diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/boot/bootp.c linux-libre-2.6.34-gnu1/arch/alpha/boot/bootp.c
--- linux-libre-2.6.33-gnu1/arch/alpha/boot/bootp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/boot/bootp.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  * based significantly on the arch/alpha/boot/main.c of Linus Torvalds
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <generated/utsrelease.h>
 #include <linux/mm.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/boot/bootpz.c linux-libre-2.6.34-gnu1/arch/alpha/boot/bootpz.c
--- linux-libre-2.6.33-gnu1/arch/alpha/boot/bootpz.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/boot/bootpz.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  * and the decompression code from MILO.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <generated/utsrelease.h>
 #include <linux/mm.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/boot/main.c linux-libre-2.6.34-gnu1/arch/alpha/boot/main.c
--- linux-libre-2.6.33-gnu1/arch/alpha/boot/main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/boot/main.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
  * This file is the bootloader for the Linux/AXP kernel
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <generated/utsrelease.h>
 #include <linux/mm.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/boot/misc.c linux-libre-2.6.34-gnu1/arch/alpha/boot/misc.c
--- linux-libre-2.6.33-gnu1/arch/alpha/boot/misc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/boot/misc.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/include/asm/core_marvel.h linux-libre-2.6.34-gnu1/arch/alpha/include/asm/core_marvel.h
--- linux-libre-2.6.33-gnu1/arch/alpha/include/asm/core_marvel.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/include/asm/core_marvel.h	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 #define __ALPHA_MARVEL__H__
 
 #include <linux/types.h>
-#include <linux/pci.h>
 #include <linux/spinlock.h>
 
 #include <asm/compiler.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/include/asm/core_mcpcia.h linux-libre-2.6.34-gnu1/arch/alpha/include/asm/core_mcpcia.h
--- linux-libre-2.6.33-gnu1/arch/alpha/include/asm/core_mcpcia.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/include/asm/core_mcpcia.h	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,6 @@
 #define MCPCIA_ONE_HAE_WINDOW 1
 
 #include <linux/types.h>
-#include <linux/pci.h>
 #include <asm/compiler.h>
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/include/asm/core_titan.h linux-libre-2.6.34-gnu1/arch/alpha/include/asm/core_titan.h
--- linux-libre-2.6.33-gnu1/arch/alpha/include/asm/core_titan.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/include/asm/core_titan.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,6 @@
 #define __ALPHA_TITAN__H__
 
 #include <linux/types.h>
-#include <linux/pci.h>
 #include <asm/compiler.h>
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/include/asm/core_tsunami.h linux-libre-2.6.34-gnu1/arch/alpha/include/asm/core_tsunami.h
--- linux-libre-2.6.33-gnu1/arch/alpha/include/asm/core_tsunami.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/include/asm/core_tsunami.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,6 @@
 #define __ALPHA_TSUNAMI__H__
 
 #include <linux/types.h>
-#include <linux/pci.h>
 #include <asm/compiler.h>
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/include/asm/dma-mapping.h linux-libre-2.6.34-gnu1/arch/alpha/include/asm/dma-mapping.h
--- linux-libre-2.6.33-gnu1/arch/alpha/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/include/asm/dma-mapping.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,71 +1,49 @@
 #ifndef _ALPHA_DMA_MAPPING_H
 #define _ALPHA_DMA_MAPPING_H
 
+#include <linux/dma-attrs.h>
 
-#ifdef CONFIG_PCI
-
-#include <linux/pci.h>
-
-#define dma_map_single(dev, va, size, dir)		\
-		pci_map_single(alpha_gendev_to_pci(dev), va, size, dir)
-#define dma_unmap_single(dev, addr, size, dir)		\
-		pci_unmap_single(alpha_gendev_to_pci(dev), addr, size, dir)
-#define dma_alloc_coherent(dev, size, addr, gfp)	\
-	      __pci_alloc_consistent(alpha_gendev_to_pci(dev), size, addr, gfp)
-#define dma_free_coherent(dev, size, va, addr)		\
-		pci_free_consistent(alpha_gendev_to_pci(dev), size, va, addr)
-#define dma_map_page(dev, page, off, size, dir)		\
-		pci_map_page(alpha_gendev_to_pci(dev), page, off, size, dir)
-#define dma_unmap_page(dev, addr, size, dir)		\
-		pci_unmap_page(alpha_gendev_to_pci(dev), addr, size, dir)
-#define dma_map_sg(dev, sg, nents, dir)			\
-		pci_map_sg(alpha_gendev_to_pci(dev), sg, nents, dir)
-#define dma_unmap_sg(dev, sg, nents, dir)		\
-		pci_unmap_sg(alpha_gendev_to_pci(dev), sg, nents, dir)
-#define dma_supported(dev, mask)			\
-		pci_dma_supported(alpha_gendev_to_pci(dev), mask)
-#define dma_mapping_error(dev, addr)				\
-		pci_dma_mapping_error(alpha_gendev_to_pci(dev), addr)
+extern struct dma_map_ops *dma_ops;
 
-#else	/* no PCI - no IOMMU. */
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+	return dma_ops;
+}
 
-#include <asm/io.h>	/* for virt_to_phys() */
+#include <asm-generic/dma-mapping-common.h>
 
-struct scatterlist;
-void *dma_alloc_coherent(struct device *dev, size_t size,
-			 dma_addr_t *dma_handle, gfp_t gfp);
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-	       enum dma_data_direction direction);
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+				       dma_addr_t *dma_handle, gfp_t gfp)
+{
+	return get_dma_ops(dev)->alloc_coherent(dev, size, dma_handle, gfp);
+}
 
-#define dma_free_coherent(dev, size, va, addr)		\
-		free_pages((unsigned long)va, get_order(size))
-#define dma_supported(dev, mask)		(mask < 0x00ffffffUL ? 0 : 1)
-#define dma_map_single(dev, va, size, dir)	virt_to_phys(va)
-#define dma_map_page(dev, page, off, size, dir)	(page_to_pa(page) + off)
+static inline void dma_free_coherent(struct device *dev, size_t size,
+				     void *vaddr, dma_addr_t dma_handle)
+{
+	get_dma_ops(dev)->free_coherent(dev, size, vaddr, dma_handle);
+}
 
-#define dma_unmap_single(dev, addr, size, dir)	((void)0)
-#define dma_unmap_page(dev, addr, size, dir)	((void)0)
-#define dma_unmap_sg(dev, sg, nents, dir)	((void)0)
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+	return get_dma_ops(dev)->mapping_error(dev, dma_addr);
+}
 
-#define dma_mapping_error(dev, addr)  (0)
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+	return get_dma_ops(dev)->dma_supported(dev, mask);
+}
 
-#endif	/* !CONFIG_PCI */
+static inline int dma_set_mask(struct device *dev, u64 mask)
+{
+	return get_dma_ops(dev)->set_dma_mask(dev, mask);
+}
 
 #define dma_alloc_noncoherent(d, s, h, f)	dma_alloc_coherent(d, s, h, f)
 #define dma_free_noncoherent(d, s, v, h)	dma_free_coherent(d, s, v, h)
 #define dma_is_consistent(d, h)			(1)
 
-int dma_set_mask(struct device *dev, u64 mask);
-
-#define dma_sync_single_for_cpu(dev, addr, size, dir)	  ((void)0)
-#define dma_sync_single_for_device(dev, addr, size, dir)  ((void)0)
-#define dma_sync_single_range(dev, addr, off, size, dir)  ((void)0)
-#define dma_sync_sg_for_cpu(dev, sg, nents, dir)	  ((void)0)
-#define dma_sync_sg_for_device(dev, sg, nents, dir)	  ((void)0)
 #define dma_cache_sync(dev, va, size, dir)		  ((void)0)
-#define dma_sync_single_range_for_cpu(dev, addr, offset, size, dir)	((void)0)
-#define dma_sync_single_range_for_device(dev, addr, offset, size, dir)	((void)0)
-
 #define dma_get_cache_alignment()			  L1_CACHE_BYTES
 
 #endif	/* _ALPHA_DMA_MAPPING_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/include/asm/local.h linux-libre-2.6.34-gnu1/arch/alpha/include/asm/local.h
--- linux-libre-2.6.33-gnu1/arch/alpha/include/asm/local.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/include/asm/local.h	2010-05-16 17:17:36.000000000 -0400
@@ -98,21 +98,4 @@ static __inline__ long local_sub_return(
 #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.
- */
-#define cpu_local_read(l)	local_read(&__get_cpu_var(l))
-#define cpu_local_set(l, i)	local_set(&__get_cpu_var(l), (i))
-
-#define cpu_local_inc(l)	local_inc(&__get_cpu_var(l))
-#define cpu_local_dec(l)	local_dec(&__get_cpu_var(l))
-#define cpu_local_add(i, l)	local_add((i), &__get_cpu_var(l))
-#define cpu_local_sub(i, l)	local_sub((i), &__get_cpu_var(l))
-
-#define __cpu_local_inc(l)	__local_inc(&__get_cpu_var(l))
-#define __cpu_local_dec(l)	__local_dec(&__get_cpu_var(l))
-#define __cpu_local_add(i, l)	__local_add((i), &__get_cpu_var(l))
-#define __cpu_local_sub(i, l)	__local_sub((i), &__get_cpu_var(l))
-
 #endif /* _ALPHA_LOCAL_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/include/asm/pci.h linux-libre-2.6.34-gnu1/arch/alpha/include/asm/pci.h
--- linux-libre-2.6.33-gnu1/arch/alpha/include/asm/pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/include/asm/pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -70,142 +70,11 @@ extern inline void pcibios_penalize_isa_
    decisions.  */
 #define PCI_DMA_BUS_IS_PHYS  0
 
-/* Allocate and map kernel buffer using consistent mode DMA for PCI
-   device.  Returns non-NULL cpu-view pointer to the buffer if
-   successful and sets *DMA_ADDRP to the pci side dma address as well,
-   else DMA_ADDRP is undefined.  */
-
-extern void *__pci_alloc_consistent(struct pci_dev *, size_t,
-				    dma_addr_t *, gfp_t);
-static inline void *
-pci_alloc_consistent(struct pci_dev *dev, size_t size, dma_addr_t *dma)
-{
-	return __pci_alloc_consistent(dev, size, dma, GFP_ATOMIC);
-}
-
-/* Free and unmap a consistent DMA buffer.  CPU_ADDR and DMA_ADDR must
-   be values that were returned from pci_alloc_consistent.  SIZE must
-   be the same as what as passed into pci_alloc_consistent.
-   References to the memory and mappings associated with CPU_ADDR or
-   DMA_ADDR past this call are illegal.  */
-
-extern void pci_free_consistent(struct pci_dev *, size_t, void *, dma_addr_t);
-
-/* Map a single buffer of the indicate size for PCI DMA in streaming mode.
-   The 32-bit PCI bus mastering 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_for_cpu is performed.  */
-
-extern dma_addr_t pci_map_single(struct pci_dev *, void *, size_t, int);
-
-/* Likewise, but for a page instead of an address.  */
-extern dma_addr_t pci_map_page(struct pci_dev *, struct page *,
-			       unsigned long, size_t, int);
-
-/* Test for pci_map_single or pci_map_page having generated an error.  */
-
-static inline int
-pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr)
-{
-	return dma_addr == 0;
-}
-
-/* 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 guaranteed to see whatever the device
-   wrote there.  */
-
-extern void pci_unmap_single(struct pci_dev *, dma_addr_t, size_t, int);
-extern void pci_unmap_page(struct pci_dev *, dma_addr_t, size_t, int);
-
-/* pci_unmap_{single,page} is not a nop, thus... */
-#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))
-
-/* Map a set of buffers described by scatterlist in streaming mode for
-   PCI DMA.  This is the scatter-gather version of the above
-   pci_map_single interface.  Here the scatter gather list elements
-   are each tagged with the appropriate PCI 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 pci_map_sg(struct pci_dev *, struct scatterlist *, int, int);
-
-/* Unmap a set of streaming mode DMA translations.  Again, cpu read
-   rules concerning calls here are the same as for pci_unmap_single()
-   above.  */
-
-extern void pci_unmap_sg(struct pci_dev *, struct scatterlist *, int, int);
-
-/* Make physical memory consistent for a single streaming mode DMA
-   translation after a transfer and device currently has ownership
-   of the buffer.
-
-   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, you must first
-   perform a pci_dma_sync_for_device, and then the device again owns
-   the buffer.  */
-
-static inline void
-pci_dma_sync_single_for_cpu(struct pci_dev *dev, dma_addr_t dma_addr,
-			    long size, int direction)
-{
-	/* Nothing to do.  */
-}
-
-static inline void
-pci_dma_sync_single_for_device(struct pci_dev *dev, dma_addr_t dma_addr,
-			       size_t size, int direction)
-{
-	/* Nothing to do.  */
-}
-
-/* Make physical memory consistent for a set of streaming mode DMA
-   translations after a transfer.  The same as pci_dma_sync_single_*
-   but for a scatter-gather list, same rules and usage.  */
-
-static inline void
-pci_dma_sync_sg_for_cpu(struct pci_dev *dev, struct scatterlist *sg,
-			int nents, int direction)
-{
-	/* Nothing to do.  */
-}
-
-static inline void
-pci_dma_sync_sg_for_device(struct pci_dev *dev, struct scatterlist *sg,
-			   int nents, int direction)
-{
-	/* Nothing to do.  */
-}
-
-/* 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.  */
+#ifdef CONFIG_PCI
 
-extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask);
+/* implement the pci_ DMA API in terms of the generic device dma_ one */
+#include <asm-generic/pci-dma-compat.h>
 
-#ifdef CONFIG_PCI
 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 					enum pci_dma_burst_strategy *strat,
 					unsigned long *strategy_parameter)
@@ -244,8 +113,6 @@ static inline int pci_proc_domain(struct
 	return hose->need_domain_info;
 }
 
-struct pci_dev *alpha_gendev_to_pci(struct device *dev);
-
 #endif /* __KERNEL__ */
 
 /* Values for the `which' argument to sys_pciconfig_iobase.  */
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/include/asm/pgtable.h linux-libre-2.6.34-gnu1/arch/alpha/include/asm/pgtable.h
--- linux-libre-2.6.33-gnu1/arch/alpha/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -329,7 +329,7 @@ extern pgd_t swapper_pg_dir[1024];
  * tables contain all the necessary information.
  */
 extern inline void update_mmu_cache(struct vm_area_struct * vma,
-	unsigned long address, pte_t pte)
+	unsigned long address, pte_t *ptep)
 {
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/alpha/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/alpha/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -68,6 +68,7 @@ struct switch_stack {
 
 #ifdef __KERNEL__
 
+#define arch_has_single_step()		(1)
 #define user_mode(regs) (((regs)->ps & 8) != 0)
 #define instruction_pointer(regs) ((regs)->pc)
 #define profile_pc(regs) instruction_pointer(regs)
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/Kconfig linux-libre-2.6.34-gnu1/arch/alpha/Kconfig
--- linux-libre-2.6.33-gnu1/arch/alpha/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@ config ALPHA
 	select HAVE_OPROFILE
 	select HAVE_SYSCALL_WRAPPERS
 	select HAVE_PERF_EVENTS
+	select HAVE_DMA_ATTRS
 	help
 	  The Alpha is a 64-bit general-purpose processor designed and
 	  marketed by the Digital Equipment Corporation of blessed memory,
@@ -58,6 +59,9 @@ config ZONE_DMA
 	bool
 	default y
 
+config NEED_DMA_MAP_STATE
+       def_bool y
+
 config GENERIC_ISA_DMA
 	bool
 	default y
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/kernel/irq.c linux-libre-2.6.34-gnu1/arch/alpha/kernel/irq.c
--- linux-libre-2.6.33-gnu1/arch/alpha/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/kernel/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/sched.h>
 #include <linux/ptrace.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/init.h>
 #include <linux/irq.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/kernel/osf_sys.c linux-libre-2.6.34-gnu1/arch/alpha/kernel/osf_sys.c
--- linux-libre-2.6.33-gnu1/arch/alpha/kernel/osf_sys.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/kernel/osf_sys.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,7 +20,6 @@
 #include <linux/syscalls.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/utsname.h>
 #include <linux/time.h>
@@ -37,6 +36,7 @@
 #include <linux/uio.h>
 #include <linux/vfs.h>
 #include <linux/rcupdate.h>
+#include <linux/slab.h>
 
 #include <asm/fpu.h>
 #include <asm/io.h>
@@ -361,7 +361,7 @@ osf_procfs_mount(char *dirname, struct p
 SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, char __user *, path,
 		int, flag, void __user *, data)
 {
-	int retval = -EINVAL;
+	int retval;
 	char *name;
 
 	name = getname(path);
@@ -379,6 +379,7 @@ SYSCALL_DEFINE4(osf_mount, unsigned long
 		retval = osf_procfs_mount(name, data, flag);
 		break;
 	default:
+		retval = -EINVAL;
 		printk("osf_mount(%ld, %x)\n", typenr, flag);
 	}
 	putname(name);
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/kernel/pci.c linux-libre-2.6.34-gnu1/arch/alpha/kernel/pci.c
--- linux-libre-2.6.33-gnu1/arch/alpha/kernel/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/kernel/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -126,8 +126,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_
 #define MB			(1024*KB)
 #define GB			(1024*MB)
 
-void
-pcibios_align_resource(void *data, struct resource *res,
+resource_size_t
+pcibios_align_resource(void *data, const struct resource *res,
 		       resource_size_t size, resource_size_t align)
 {
 	struct pci_dev *dev = data;
@@ -184,7 +184,7 @@ pcibios_align_resource(void *data, struc
 		}
 	}
 
-	res->start = start;
+	return start;
 }
 #undef KB
 #undef MB
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/kernel/pci_iommu.c linux-libre-2.6.34-gnu1/arch/alpha/kernel/pci_iommu.c
--- linux-libre-2.6.33-gnu1/arch/alpha/kernel/pci_iommu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/kernel/pci_iommu.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/bootmem.h>
 #include <linux/scatterlist.h>
 #include <linux/log2.h>
@@ -216,10 +216,30 @@ iommu_arena_free(struct pci_iommu_arena
 	for (i = 0; i < n; ++i)
 		p[i] = 0;
 }
-
-/* True if the machine supports DAC addressing, and DEV can
-   make use of it given MASK.  */
-static int pci_dac_dma_supported(struct pci_dev *hwdev, u64 mask);
+
+/*
+ * True if the machine supports DAC addressing, and DEV can
+ * make use of it given MASK.
+ */
+static int pci_dac_dma_supported(struct pci_dev *dev, u64 mask)
+{
+	dma64_addr_t dac_offset = alpha_mv.pci_dac_offset;
+	int ok = 1;
+
+	/* If this is not set, the machine doesn't support DAC at all.  */
+	if (dac_offset == 0)
+		ok = 0;
+
+	/* The device has to be able to address our DAC bit.  */
+	if ((dac_offset & dev->dma_mask) != dac_offset)
+		ok = 0;
+
+	/* If both conditions above are met, we are fine. */
+	DBGA("pci_dac_dma_supported %s from %p\n",
+	     ok ? "yes" : "no", __builtin_return_address(0));
+
+	return ok;
+}
 
 /* Map a single buffer of the indicated size for PCI DMA in streaming
    mode.  The 32-bit PCI bus mastering address to use is returned.
@@ -301,23 +321,36 @@ pci_map_single_1(struct pci_dev *pdev, v
 	return ret;
 }
 
-dma_addr_t
-pci_map_single(struct pci_dev *pdev, void *cpu_addr, size_t size, int dir)
+/* Helper for generic DMA-mapping functions. */
+static struct pci_dev *alpha_gendev_to_pci(struct device *dev)
 {
-	int dac_allowed; 
+	if (dev && dev->bus == &pci_bus_type)
+		return to_pci_dev(dev);
 
-	if (dir == PCI_DMA_NONE)
-		BUG();
+	/* Assume that non-PCI devices asking for DMA are either ISA or EISA,
+	   BUG() otherwise. */
+	BUG_ON(!isa_bridge);
 
-	dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0; 
-	return pci_map_single_1(pdev, cpu_addr, size, dac_allowed);
+	/* Assume non-busmaster ISA DMA when dma_mask is not set (the ISA
+	   bridge is bus master then). */
+	if (!dev || !dev->dma_mask || !*dev->dma_mask)
+		return isa_bridge;
+
+	/* For EISA bus masters, return isa_bridge (it might have smaller
+	   dma_mask due to wiring limitations). */
+	if (*dev->dma_mask >= isa_bridge->dma_mask)
+		return isa_bridge;
+
+	/* This assumes ISA bus master with dma_mask 0xffffff. */
+	return NULL;
 }
-EXPORT_SYMBOL(pci_map_single);
 
-dma_addr_t
-pci_map_page(struct pci_dev *pdev, struct page *page, unsigned long offset,
-	     size_t size, int dir)
+static dma_addr_t alpha_pci_map_page(struct device *dev, struct page *page,
+				     unsigned long offset, size_t size,
+				     enum dma_data_direction dir,
+				     struct dma_attrs *attrs)
 {
+	struct pci_dev *pdev = alpha_gendev_to_pci(dev);
 	int dac_allowed;
 
 	if (dir == PCI_DMA_NONE)
@@ -327,7 +360,6 @@ pci_map_page(struct pci_dev *pdev, struc
 	return pci_map_single_1(pdev, (char *)page_address(page) + offset, 
 				size, dac_allowed);
 }
-EXPORT_SYMBOL(pci_map_page);
 
 /* Unmap a single streaming mode DMA translation.  The DMA_ADDR and
    SIZE must match what was provided for in a previous pci_map_single
@@ -335,16 +367,17 @@ EXPORT_SYMBOL(pci_map_page);
    the cpu to the buffer are guaranteed to see whatever the device
    wrote there.  */
 
-void
-pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
-		 int direction)
+static void alpha_pci_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 pci_dev *pdev = alpha_gendev_to_pci(dev);
 	struct pci_controller *hose = pdev ? pdev->sysdata : pci_isa_hose;
 	struct pci_iommu_arena *arena;
 	long dma_ofs, npages;
 
-	if (direction == PCI_DMA_NONE)
+	if (dir == PCI_DMA_NONE)
 		BUG();
 
 	if (dma_addr >= __direct_map_base
@@ -393,25 +426,16 @@ pci_unmap_single(struct pci_dev *pdev, d
 	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);
-
-void
-pci_unmap_page(struct pci_dev *pdev, dma_addr_t dma_addr,
-	       size_t size, int direction)
-{
-	pci_unmap_single(pdev, dma_addr, size, direction);
-}
-EXPORT_SYMBOL(pci_unmap_page);
 
 /* Allocate and map kernel buffer using consistent mode DMA for PCI
    device.  Returns non-NULL cpu-view pointer to the buffer if
    successful and sets *DMA_ADDRP to the pci side dma address as well,
    else DMA_ADDRP is undefined.  */
 
-void *
-__pci_alloc_consistent(struct pci_dev *pdev, size_t size,
-		       dma_addr_t *dma_addrp, gfp_t gfp)
+static void *alpha_pci_alloc_coherent(struct device *dev, size_t size,
+				      dma_addr_t *dma_addrp, gfp_t gfp)
 {
+	struct pci_dev *pdev = alpha_gendev_to_pci(dev);
 	void *cpu_addr;
 	long order = get_order(size);
 
@@ -439,13 +463,12 @@ try_again:
 		gfp |= GFP_DMA;
 		goto try_again;
 	}
-		
+
 	DBGA2("pci_alloc_consistent: %zx -> [%p,%llx] from %p\n",
 	      size, cpu_addr, *dma_addrp, __builtin_return_address(0));
 
 	return cpu_addr;
 }
-EXPORT_SYMBOL(__pci_alloc_consistent);
 
 /* Free and unmap a consistent DMA buffer.  CPU_ADDR and DMA_ADDR must
    be values that were returned from pci_alloc_consistent.  SIZE must
@@ -453,17 +476,16 @@ EXPORT_SYMBOL(__pci_alloc_consistent);
    References to the memory and mappings associated with CPU_ADDR or
    DMA_ADDR past this call are illegal.  */
 
-void
-pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr,
-		    dma_addr_t dma_addr)
+static void alpha_pci_free_coherent(struct device *dev, size_t size,
+				    void *cpu_addr, dma_addr_t dma_addr)
 {
+	struct pci_dev *pdev = alpha_gendev_to_pci(dev);
 	pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL);
 	free_pages((unsigned long)cpu_addr, get_order(size));
 
 	DBGA2("pci_free_consistent: [%llx,%zx] from %p\n",
 	      dma_addr, size, __builtin_return_address(0));
 }
-EXPORT_SYMBOL(pci_free_consistent);
 
 /* Classify the elements of the scatterlist.  Write dma_address
    of each element with:
@@ -626,23 +648,21 @@ sg_fill(struct device *dev, struct scatt
 	return 1;
 }
 
-int
-pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
-	   int direction)
+static int alpha_pci_map_sg(struct device *dev, struct scatterlist *sg,
+			    int nents, enum dma_data_direction dir,
+			    struct dma_attrs *attrs)
 {
+	struct pci_dev *pdev = alpha_gendev_to_pci(dev);
 	struct scatterlist *start, *end, *out;
 	struct pci_controller *hose;
 	struct pci_iommu_arena *arena;
 	dma_addr_t max_dma;
 	int dac_allowed;
-	struct device *dev;
 
-	if (direction == PCI_DMA_NONE)
+	if (dir == PCI_DMA_NONE)
 		BUG();
 
-	dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0;
-
-	dev = pdev ? &pdev->dev : NULL;
+	dac_allowed = dev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0;
 
 	/* Fast path single entry scatterlists.  */
 	if (nents == 1) {
@@ -699,19 +719,19 @@ pci_map_sg(struct pci_dev *pdev, struct
 	/* Some allocation failed while mapping the scatterlist
 	   entries.  Unmap them now.  */
 	if (out > start)
-		pci_unmap_sg(pdev, start, out - start, direction);
+		pci_unmap_sg(pdev, start, out - start, dir);
 	return 0;
 }
-EXPORT_SYMBOL(pci_map_sg);
 
 /* Unmap a set of streaming mode DMA translations.  Again, cpu read
    rules concerning calls here are the same as for pci_unmap_single()
    above.  */
 
-void
-pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
-	     int direction)
+static void alpha_pci_unmap_sg(struct device *dev, struct scatterlist *sg,
+			       int nents, enum dma_data_direction dir,
+			       struct dma_attrs *attrs)
 {
+	struct pci_dev *pdev = alpha_gendev_to_pci(dev);
 	unsigned long flags;
 	struct pci_controller *hose;
 	struct pci_iommu_arena *arena;
@@ -719,7 +739,7 @@ pci_unmap_sg(struct pci_dev *pdev, struc
 	dma_addr_t max_dma;
 	dma_addr_t fbeg, fend;
 
-	if (direction == PCI_DMA_NONE)
+	if (dir == PCI_DMA_NONE)
 		BUG();
 
 	if (! alpha_mv.mv_pci_tbi)
@@ -783,15 +803,13 @@ pci_unmap_sg(struct pci_dev *pdev, struc
 
 	DBGA("pci_unmap_sg: %ld entries\n", nents - (end - sg));
 }
-EXPORT_SYMBOL(pci_unmap_sg);
-
 
 /* Return whether the given PCI device DMA address mask can be
    supported properly.  */
 
-int
-pci_dma_supported(struct pci_dev *pdev, u64 mask)
+static int alpha_pci_supported(struct device *dev, u64 mask)
 {
+	struct pci_dev *pdev = alpha_gendev_to_pci(dev);
 	struct pci_controller *hose;
 	struct pci_iommu_arena *arena;
 
@@ -818,7 +836,6 @@ pci_dma_supported(struct pci_dev *pdev,
 
 	return 0;
 }
-EXPORT_SYMBOL(pci_dma_supported);
 
 
 /*
@@ -918,66 +935,32 @@ iommu_unbind(struct pci_iommu_arena *are
 	return 0;
 }
 
-/* True if the machine supports DAC addressing, and DEV can
-   make use of it given MASK.  */
-
-static int
-pci_dac_dma_supported(struct pci_dev *dev, u64 mask)
-{
-	dma64_addr_t dac_offset = alpha_mv.pci_dac_offset;
-	int ok = 1;
-
-	/* If this is not set, the machine doesn't support DAC at all.  */
-	if (dac_offset == 0)
-		ok = 0;
-
-	/* The device has to be able to address our DAC bit.  */
-	if ((dac_offset & dev->dma_mask) != dac_offset)
-		ok = 0;
-
-	/* If both conditions above are met, we are fine. */
-	DBGA("pci_dac_dma_supported %s from %p\n",
-	     ok ? "yes" : "no", __builtin_return_address(0));
-
-	return ok;
-}
-
-/* Helper for generic DMA-mapping functions. */
-
-struct pci_dev *
-alpha_gendev_to_pci(struct device *dev)
+static int alpha_pci_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
-	if (dev && dev->bus == &pci_bus_type)
-		return to_pci_dev(dev);
-
-	/* Assume that non-PCI devices asking for DMA are either ISA or EISA,
-	   BUG() otherwise. */
-	BUG_ON(!isa_bridge);
-
-	/* Assume non-busmaster ISA DMA when dma_mask is not set (the ISA
-	   bridge is bus master then). */
-	if (!dev || !dev->dma_mask || !*dev->dma_mask)
-		return isa_bridge;
-
-	/* For EISA bus masters, return isa_bridge (it might have smaller
-	   dma_mask due to wiring limitations). */
-	if (*dev->dma_mask >= isa_bridge->dma_mask)
-		return isa_bridge;
-
-	/* This assumes ISA bus master with dma_mask 0xffffff. */
-	return NULL;
+	return dma_addr == 0;
 }
-EXPORT_SYMBOL(alpha_gendev_to_pci);
 
-int
-dma_set_mask(struct device *dev, u64 mask)
+static int alpha_pci_set_mask(struct device *dev, u64 mask)
 {
 	if (!dev->dma_mask ||
 	    !pci_dma_supported(alpha_gendev_to_pci(dev), mask))
 		return -EIO;
 
 	*dev->dma_mask = mask;
-
 	return 0;
 }
-EXPORT_SYMBOL(dma_set_mask);
+
+struct dma_map_ops alpha_pci_ops = {
+	.alloc_coherent		= alpha_pci_alloc_coherent,
+	.free_coherent		= alpha_pci_free_coherent,
+	.map_page		= alpha_pci_map_page,
+	.unmap_page		= alpha_pci_unmap_page,
+	.map_sg			= alpha_pci_map_sg,
+	.unmap_sg		= alpha_pci_unmap_sg,
+	.mapping_error		= alpha_pci_mapping_error,
+	.dma_supported		= alpha_pci_supported,
+	.set_dma_mask		= alpha_pci_set_mask,
+};
+
+struct dma_map_ops *dma_ops = &alpha_pci_ops;
+EXPORT_SYMBOL(dma_ops);
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/kernel/pci-noop.c linux-libre-2.6.34-gnu1/arch/alpha/kernel/pci-noop.c
--- linux-libre-2.6.33-gnu1/arch/alpha/kernel/pci-noop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/kernel/pci-noop.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 #include <linux/capability.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
@@ -106,58 +107,8 @@ sys_pciconfig_write(unsigned long bus, u
 		return -ENODEV;
 }
 
-/* Stubs for the routines in pci_iommu.c: */
-
-void *
-__pci_alloc_consistent(struct pci_dev *pdev, size_t size,
-		       dma_addr_t *dma_addrp, gfp_t gfp)
-{
-	return NULL;
-}
-
-void
-pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr,
-		    dma_addr_t dma_addr)
-{
-}
-
-dma_addr_t
-pci_map_single(struct pci_dev *pdev, void *cpu_addr, size_t size,
-	       int direction)
-{
-	return (dma_addr_t) 0;
-}
-
-void
-pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
-		 int direction)
-{
-}
-
-int
-pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
-	   int direction)
-{
-	return 0;
-}
-
-void
-pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
-	     int direction)
-{
-}
-
-int
-pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
-{
-	return 0;
-}
-
-/* Generic DMA mapping functions: */
-
-void *
-dma_alloc_coherent(struct device *dev, size_t size,
-		   dma_addr_t *dma_handle, gfp_t gfp)
+static void *alpha_noop_alloc_coherent(struct device *dev, size_t size,
+				       dma_addr_t *dma_handle, gfp_t gfp)
 {
 	void *ret;
 
@@ -171,11 +122,22 @@ dma_alloc_coherent(struct device *dev, s
 	return ret;
 }
 
-EXPORT_SYMBOL(dma_alloc_coherent);
+static void alpha_noop_free_coherent(struct device *dev, size_t size,
+				     void *cpu_addr, dma_addr_t dma_addr)
+{
+	free_pages((unsigned long)cpu_addr, get_order(size));
+}
 
-int
-dma_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
-	   enum dma_data_direction direction)
+static dma_addr_t alpha_noop_map_page(struct device *dev, struct page *page,
+				      unsigned long offset, size_t size,
+				      enum dma_data_direction dir,
+				      struct dma_attrs *attrs)
+{
+	return page_to_pa(page) + offset;
+}
+
+static int alpha_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
+			     enum dma_data_direction dir, struct dma_attrs *attrs)
 {
 	int i;
 	struct scatterlist *sg;
@@ -192,19 +154,37 @@ dma_map_sg(struct device *dev, struct sc
 	return nents;
 }
 
-EXPORT_SYMBOL(dma_map_sg);
+static int alpha_noop_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+	return 0;
+}
 
-int
-dma_set_mask(struct device *dev, u64 mask)
+static int alpha_noop_supported(struct device *dev, u64 mask)
+{
+	return mask < 0x00ffffffUL ? 0 : 1;
+}
+
+static int alpha_noop_set_mask(struct device *dev, u64 mask)
 {
 	if (!dev->dma_mask || !dma_supported(dev, mask))
 		return -EIO;
 
 	*dev->dma_mask = mask;
-
 	return 0;
 }
-EXPORT_SYMBOL(dma_set_mask);
+
+struct dma_map_ops alpha_noop_ops = {
+	.alloc_coherent		= alpha_noop_alloc_coherent,
+	.free_coherent		= alpha_noop_free_coherent,
+	.map_page		= alpha_noop_map_page,
+	.map_sg			= alpha_noop_map_sg,
+	.mapping_error		= alpha_noop_mapping_error,
+	.dma_supported		= alpha_noop_supported,
+	.set_dma_mask		= alpha_noop_set_mask,
+};
+
+struct dma_map_ops *dma_ops = &alpha_noop_ops;
+EXPORT_SYMBOL(dma_ops);
 
 void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/kernel/pci-sysfs.c linux-libre-2.6.34-gnu1/arch/alpha/kernel/pci-sysfs.c
--- linux-libre-2.6.33-gnu1/arch/alpha/kernel/pci-sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/kernel/pci-sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 
 static int hose_mmap_page_range(struct pci_controller *hose,
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/kernel/process.c linux-libre-2.6.34-gnu1/arch/alpha/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/alpha/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/time.h>
 #include <linux/major.h>
@@ -28,6 +27,7 @@
 #include <linux/reboot.h>
 #include <linux/tty.h>
 #include <linux/console.h>
+#include <linux/slab.h>
 
 #include <asm/reg.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/alpha/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/alpha/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,6 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
-#include <linux/slab.h>
 #include <linux/security.h>
 #include <linux/signal.h>
 
@@ -249,6 +248,17 @@ ptrace_cancel_bpt(struct task_struct * c
 	return (nsaved != 0);
 }
 
+void user_enable_single_step(struct task_struct *child)
+{
+	/* Mark single stepping.  */
+	task_thread_info(child)->bpt_nsaved = -1;
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+	ptrace_cancel_bpt(child);
+}
+
 /*
  * Called by kernel/ptrace.c when detaching..
  *
@@ -256,7 +266,7 @@ ptrace_cancel_bpt(struct task_struct * c
  */
 void ptrace_disable(struct task_struct *child)
 { 
-	ptrace_cancel_bpt(child);
+	user_disable_single_step(child);
 }
 
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -295,52 +305,6 @@ long arch_ptrace(struct task_struct *chi
 		DBG(DBG_MEM, ("poke $%ld<-%#lx\n", addr, data));
 		ret = put_reg(child, addr, data);
 		break;
-
-	case PTRACE_SYSCALL:
-		/* continue and stop at next (return from) syscall */
-	case PTRACE_CONT:    /* restart after signal. */
-		ret = -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;
-		/* make sure single-step breakpoint is gone. */
-		ptrace_cancel_bpt(child);
-		wake_up_process(child);
-		ret = 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:
-		ret = 0;
-		if (child->exit_state == EXIT_ZOMBIE)
-			break;
-		child->exit_code = SIGKILL;
-		/* make sure single-step breakpoint is gone. */
-		ptrace_cancel_bpt(child);
-		wake_up_process(child);
-		break;
-
-	case PTRACE_SINGLESTEP:  /* execute single instruction. */
-		ret = -EIO;
-		if (!valid_signal(data))
-			break;
-		/* Mark single stepping.  */
-		task_thread_info(child)->bpt_nsaved = -1;
-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		child->exit_code = data;
-		wake_up_process(child);
-		/* give it a chance to run. */
-		ret = 0;
-		break;
-
 	default:
 		ret = ptrace_request(child, request, addr, data);
 		break;
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/kernel/smc37c669.c linux-libre-2.6.34-gnu1/arch/alpha/kernel/smc37c669.c
--- linux-libre-2.6.33-gnu1/arch/alpha/kernel/smc37c669.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/kernel/smc37c669.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,6 @@
  */
 #include <linux/kernel.h>
 
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/kernel/smc37c93x.c linux-libre-2.6.34-gnu1/arch/alpha/kernel/smc37c93x.c
--- linux-libre-2.6.33-gnu1/arch/alpha/kernel/smc37c93x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/kernel/smc37c93x.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,6 @@
 
 #include <linux/kernel.h>
 
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/kernel/srm_env.c linux-libre-2.6.34-gnu1/arch/alpha/kernel/srm_env.c
--- linux-libre-2.6.33-gnu1/arch/alpha/kernel/srm_env.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/kernel/srm_env.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/kernel/sys_dp264.c linux-libre-2.6.34-gnu1/arch/alpha/kernel/sys_dp264.c
--- linux-libre-2.6.33-gnu1/arch/alpha/kernel/sys_dp264.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/kernel/sys_dp264.c	2010-05-16 17:17:36.000000000 -0400
@@ -224,7 +224,7 @@ static void
 dp264_device_interrupt(unsigned long vector)
 {
 #if 1
-	printk("dp264_device_interrupt: NOT IMPLEMENTED YET!! \n");
+	printk("dp264_device_interrupt: NOT IMPLEMENTED YET!!\n");
 #else
 	unsigned long pld;
 	unsigned int i;
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/kernel/sys_titan.c linux-libre-2.6.34-gnu1/arch/alpha/kernel/sys_titan.c
--- linux-libre-2.6.33-gnu1/arch/alpha/kernel/sys_titan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/kernel/sys_titan.c	2010-05-16 17:17:36.000000000 -0400
@@ -171,7 +171,7 @@ titan_set_irq_affinity(unsigned int irq,
 static void
 titan_device_interrupt(unsigned long vector)
 {
-	printk("titan_device_interrupt: NOT IMPLEMENTED YET!! \n");
+	printk("titan_device_interrupt: NOT IMPLEMENTED YET!!\n");
 }
 
 static void 
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/kernel/traps.c linux-libre-2.6.34-gnu1/arch/alpha/kernel/traps.c
--- linux-libre-2.6.33-gnu1/arch/alpha/kernel/traps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/kernel/traps.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kallsyms.h>
+#include <linux/ratelimit.h>
 
 #include <asm/gentrap.h>
 #include <asm/uaccess.h>
@@ -771,8 +772,7 @@ asmlinkage void
 do_entUnaUser(void __user * va, unsigned long opcode,
 	      unsigned long reg, struct pt_regs *regs)
 {
-	static int cnt = 0;
-	static unsigned long last_time;
+	static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5);
 
 	unsigned long tmp1, tmp2, tmp3, tmp4;
 	unsigned long fake_reg, *reg_addr = &fake_reg;
@@ -783,15 +783,11 @@ do_entUnaUser(void __user * va, unsigned
 	   with the unaliged access.  */
 
 	if (!test_thread_flag (TIF_UAC_NOPRINT)) {
-		if (cnt >= 5 && time_after(jiffies, last_time + 5 * HZ)) {
-			cnt = 0;
-		}
-		if (++cnt < 5) {
+		if (__ratelimit(&ratelimit)) {
 			printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n",
 			       current->comm, task_pid_nr(current),
 			       regs->pc - 4, va, opcode, reg);
 		}
-		last_time = jiffies;
 	}
 	if (test_thread_flag (TIF_UAC_SIGBUS))
 		goto give_sigbus;
diff -druNp linux-libre-2.6.33-gnu1/arch/alpha/mm/init.c linux-libre-2.6.34-gnu1/arch/alpha/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/alpha/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/alpha/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h> /* max_low_pfn */
 #include <linux/vmalloc.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/boot/bootp/init.S linux-libre-2.6.34-gnu1/arch/arm/boot/bootp/init.S
--- linux-libre-2.6.33-gnu1/arch/arm/boot/bootp/init.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/boot/bootp/init.S	2010-05-16 17:17:36.000000000 -0400
@@ -49,7 +49,7 @@ _start:		add	lr, pc, #-0x8		@ lr = curre
 /*
  * find the end of the tag list, and then add an INITRD tag on the end.
  * If there is already an INITRD tag, then we ignore it; the last INITRD
- * tag takes precidence.
+ * tag takes precedence.
  */
 taglist:	ldr	r10, [r9, #0]		@ tag length
 		teq	r10, #0			@ last tag (zero length)?
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/decompress.c linux-libre-2.6.34-gnu1/arch/arm/boot/compressed/decompress.c
--- linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/decompress.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/boot/compressed/decompress.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,46 @@
+#define _LINUX_STRING_H_
+
+#include <linux/compiler.h>	/* for inline */
+#include <linux/types.h>	/* for size_t */
+#include <linux/stddef.h>	/* for NULL */
+#include <linux/linkage.h>
+#include <asm/string.h>
+
+extern unsigned long free_mem_ptr;
+extern unsigned long free_mem_end_ptr;
+extern void error(char *);
+
+#define STATIC static
+#define STATIC_RW_DATA	/* non-static please */
+
+#define ARCH_HAS_DECOMP_WDOG
+
+/* 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
+
+#ifdef CONFIG_KERNEL_GZIP
+#include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZO
+#include "../../../../lib/decompress_unlzo.c"
+#endif
+
+void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
+{
+	decompress(input, len, NULL, NULL, output, NULL, error);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/head.S linux-libre-2.6.34-gnu1/arch/arm/boot/compressed/head.S
--- linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/head.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/boot/compressed/head.S	2010-05-16 17:17:36.000000000 -0400
@@ -22,13 +22,13 @@
 #if defined(CONFIG_DEBUG_ICEDCC)
 
 #ifdef CONFIG_CPU_V6
-		.macro	loadsp, rb
+		.macro	loadsp, rb, tmp
 		.endm
 		.macro	writeb, ch, rb
 		mcr	p14, 0, \ch, c0, c5, 0
 		.endm
 #elif defined(CONFIG_CPU_V7)
-		.macro	loadsp, rb
+		.macro	loadsp, rb, tmp
 		.endm
 		.macro	writeb, ch, rb
 wait:		mrc	p14, 0, pc, c0, c1, 0
@@ -36,13 +36,13 @@ wait:		mrc	p14, 0, pc, c0, c1, 0
 		mcr	p14, 0, \ch, c0, c5, 0
 		.endm
 #elif defined(CONFIG_CPU_XSCALE)
-		.macro	loadsp, rb
+		.macro	loadsp, rb, tmp
 		.endm
 		.macro	writeb, ch, rb
 		mcr	p14, 0, \ch, c8, c0, 0
 		.endm
 #else
-		.macro	loadsp, rb
+		.macro	loadsp, rb, tmp
 		.endm
 		.macro	writeb, ch, rb
 		mcr	p14, 0, \ch, c1, c0, 0
@@ -58,7 +58,7 @@ wait:		mrc	p14, 0, pc, c0, c1, 0
 		.endm
 
 #if defined(CONFIG_ARCH_SA1100)
-		.macro	loadsp, rb
+		.macro	loadsp, rb, tmp
 		mov	\rb, #0x80000000	@ physical base address
 #ifdef CONFIG_DEBUG_LL_SER3
 		add	\rb, \rb, #0x00050000	@ Ser3
@@ -67,13 +67,13 @@ wait:		mrc	p14, 0, pc, c0, c1, 0
 #endif
 		.endm
 #elif defined(CONFIG_ARCH_S3C2410)
-		.macro loadsp, rb
+		.macro loadsp, rb, tmp
 		mov	\rb, #0x50000000
 		add	\rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
 		.endm
 #else
-		.macro	loadsp,	rb
-		addruart \rb
+		.macro	loadsp,	rb, tmp
+		addruart \rb, \tmp
 		.endm
 #endif
 #endif
@@ -170,9 +170,9 @@ not_angel:
 
 		.text
 		adr	r0, LC0
- ARM(		ldmia	r0, {r1, r2, r3, r4, r5, r6, ip, sp}	)
- THUMB(		ldmia	r0, {r1, r2, r3, r4, r5, r6, ip}	)
- THUMB(		ldr	sp, [r0, #28]				)
+ ARM(		ldmia	r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp})
+ THUMB(		ldmia	r0, {r1, r2, r3, r4, r5, r6, r11, ip}	)
+ THUMB(		ldr	sp, [r0, #32]				)
 		subs	r0, r0, r1		@ calculate the delta offset
 
 						@ if delta is zero, we are
@@ -182,12 +182,13 @@ not_angel:
 		/*
 		 * We're running at a different address.  We need to fix
 		 * up various pointers:
-		 *   r5 - zImage base address
-		 *   r6 - GOT start
+		 *   r5 - zImage base address (_start)
+		 *   r6 - size of decompressed image
+		 *   r11 - GOT start
 		 *   ip - GOT end
 		 */
 		add	r5, r5, r0
-		add	r6, r6, r0
+		add	r11, r11, r0
 		add	ip, ip, r0
 
 #ifndef CONFIG_ZBOOT_ROM
@@ -205,10 +206,10 @@ not_angel:
 		/*
 		 * Relocate all entries in the GOT table.
 		 */
-1:		ldr	r1, [r6, #0]		@ relocate entries in the GOT
+1:		ldr	r1, [r11, #0]		@ relocate entries in the GOT
 		add	r1, r1, r0		@ table.  This fixes up the
-		str	r1, [r6], #4		@ C references.
-		cmp	r6, ip
+		str	r1, [r11], #4		@ C references.
+		cmp	r11, ip
 		blo	1b
 #else
 
@@ -216,12 +217,12 @@ not_angel:
 		 * Relocate entries in the GOT table.  We only relocate
 		 * the entries that are outside the (relocated) BSS region.
 		 */
-1:		ldr	r1, [r6, #0]		@ relocate entries in the GOT
+1:		ldr	r1, [r11, #0]		@ relocate entries in the GOT
 		cmp	r1, r2			@ entry < bss_start ||
 		cmphs	r3, r1			@ _end < entry
 		addlo	r1, r1, r0		@ table.  This fixes up the
-		str	r1, [r6], #4		@ C references.
-		cmp	r6, ip
+		str	r1, [r11], #4		@ C references.
+		cmp	r11, ip
 		blo	1b
 #endif
 
@@ -247,6 +248,7 @@ not_relocated:	mov	r0, #0
  * Check to see if we will overwrite ourselves.
  *   r4 = final kernel address
  *   r5 = start of this image
+ *   r6 = size of decompressed image
  *   r2 = end of malloc space (and therefore this image)
  * We basically want:
  *   r4 >= r2 -> OK
@@ -254,8 +256,7 @@ not_relocated:	mov	r0, #0
  */
 		cmp	r4, r2
 		bhs	wont_overwrite
-		sub	r3, sp, r5		@ > compressed kernel size
-		add	r0, r4, r3, lsl #2	@ allow for 4x expansion
+		add	r0, r4, r6
 		cmp	r0, r5
 		bls	wont_overwrite
 
@@ -271,7 +272,6 @@ not_relocated:	mov	r0, #0
  * r1-r3  = unused
  * r4     = kernel execution address
  * r5     = decompressed kernel start
- * r6     = processor ID
  * r7     = architecture ID
  * r8     = atags pointer
  * r9-r12,r14 = corrupted
@@ -312,7 +312,8 @@ LC0:		.word	LC0			@ r1
 		.word	_end			@ r3
 		.word	zreladdr		@ r4
 		.word	_start			@ r5
-		.word	_got_start		@ r6
+		.word	_image_size		@ r6
+		.word	_got_start		@ r11
 		.word	_got_end		@ ip
 		.word	user_stack+4096		@ sp
 LC1:		.word	reloc_end - reloc_start
@@ -336,7 +337,6 @@ params:		ldr	r0, =params_phys
  *
  * On entry,
  *  r4 = kernel execution address
- *  r6 = processor ID
  *  r7 = architecture number
  *  r8 = atags pointer
  *  r9 = run-time address of "start"  (???)
@@ -542,7 +542,6 @@ __common_mmu_cache_on:
  * r1-r3  = unused
  * r4     = kernel execution address
  * r5     = decompressed kernel start
- * r6     = processor ID
  * r7     = architecture ID
  * r8     = atags pointer
  * r9-r12,r14 = corrupted
@@ -581,19 +580,19 @@ call_kernel:	bl	cache_clean_flush
  *  r1  = corrupted
  *  r2  = corrupted
  *  r3  = block offset
- *  r6  = corrupted
+ *  r9  = corrupted
  *  r12 = corrupted
  */
 
 call_cache_fn:	adr	r12, proc_types
 #ifdef CONFIG_CPU_CP15
-		mrc	p15, 0, r6, c0, c0	@ get processor ID
+		mrc	p15, 0, r9, c0, c0	@ get processor ID
 #else
-		ldr	r6, =CONFIG_PROCESSOR_ID
+		ldr	r9, =CONFIG_PROCESSOR_ID
 #endif
 1:		ldr	r1, [r12, #0]		@ get value
 		ldr	r2, [r12, #4]		@ get mask
-		eor	r1, r1, r6		@ (real ^ match)
+		eor	r1, r1, r9		@ (real ^ match)
 		tst	r1, r2			@       & mask
  ARM(		addeq	pc, r12, r3		) @ call cache function
  THUMB(		addeq	r12, r3			)
@@ -686,8 +685,8 @@ proc_types:
 		W(b)	__armv4_mmu_cache_off
 		W(b)	__armv4_mmu_cache_flush
 
-		.word	0x56056930
-		.word	0xff0ffff0		@ PXA935
+		.word	0x56056900
+		.word	0xffffff00		@ PXA9xx
 		W(b)	__armv4_mmu_cache_on
 		W(b)	__armv4_mmu_cache_off
 		W(b)	__armv4_mmu_cache_flush
@@ -698,12 +697,6 @@ proc_types:
 		W(b)	__armv4_mmu_cache_off
 		W(b)	__armv5tej_mmu_cache_flush
 
-		.word	0x56056930
-		.word	0xff0ffff0		@ PXA935
-		W(b)	__armv4_mmu_cache_on
-		W(b)	__armv4_mmu_cache_off
-		W(b)	__armv4_mmu_cache_flush
-
 		.word	0x56050000		@ Feroceon
 		.word	0xff0f0000
 		W(b)	__armv4_mmu_cache_on
@@ -743,7 +736,7 @@ proc_types:
 		.word	0x000f0000
 		W(b)	__armv4_mmu_cache_on
 		W(b)	__armv4_mmu_cache_off
-		W(b)	__armv4_mmu_cache_flush
+		W(b)	__armv5tej_mmu_cache_flush
 
 		.word	0x0007b000		@ ARMv6
 		.word	0x000ff000
@@ -778,8 +771,7 @@ proc_types:
  * Turn off the Cache and MMU.  ARMv3 does not support
  * reading the control register, but ARMv4 does.
  *
- * On entry,  r6 = processor ID
- * On exit,   r0, r1, r2, r3, r12 corrupted
+ * On exit, r0, r1, r2, r3, r9, r12 corrupted
  * This routine must preserve: r4, r6, r7
  */
 		.align	5
@@ -852,10 +844,8 @@ __armv3_mmu_cache_off:
 /*
  * Clean and flush the cache to maintain consistency.
  *
- * On entry,
- *  r6 = processor ID
  * On exit,
- *  r1, r2, r3, r11, r12 corrupted
+ *  r1, r2, r3, r9, r11, r12 corrupted
  * This routine must preserve:
  *  r0, r4, r5, r6, r7
  */
@@ -967,7 +957,7 @@ __armv4_mmu_cache_flush:
 		mov	r2, #64*1024		@ default: 32K dcache size (*2)
 		mov	r11, #32		@ default: 32 byte line size
 		mrc	p15, 0, r3, c0, c0, 1	@ read cache type
-		teq	r3, r6			@ cache ID register present?
+		teq	r3, r9			@ cache ID register present?
 		beq	no_cache_id
 		mov	r1, r3, lsr #18
 		and	r1, r1, #7
@@ -1025,7 +1015,7 @@ phex:		adr	r3, phexbuf
 		strb	r2, [r3, r1]
 		b	1b
 
-puts:		loadsp	r3
+puts:		loadsp	r3, r1
 1:		ldrb	r2, [r0], #1
 		teq	r2, #0
 		moveq	pc, lr
@@ -1042,7 +1032,7 @@ puts:		loadsp	r3
 putc:
 		mov	r2, r0
 		mov	r0, #0
-		loadsp	r3
+		loadsp	r3, r1
 		b	2b
 
 memdump:	mov	r12, r0
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/Makefile linux-libre-2.6.34-gnu1/arch/arm/boot/compressed/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/boot/compressed/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
 #
 
 HEAD	= head.o
-OBJS	= misc.o
+OBJS	= misc.o decompress.o
 FONTC	= $(srctree)/drivers/video/console/font_acorn_8x8.c
 
 #
@@ -106,10 +106,6 @@ lib1funcs = $(obj)/lib1funcs.o
 $(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE
 	$(call cmd,shipped)
 
-# Don't allow any static data in misc.o, which
-# would otherwise mess up our GOT table
-CFLAGS_misc.o := -Dstatic=
-
 $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
 	 	$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
 	$(call if_changed,ld)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/misc.c linux-libre-2.6.34-gnu1/arch/arm/boot/compressed/misc.c
--- linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/misc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/boot/compressed/misc.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,8 +23,8 @@ unsigned int __machine_arch_type;
 #include <linux/compiler.h>	/* for inline */
 #include <linux/types.h>	/* for size_t */
 #include <linux/stddef.h>	/* for NULL */
-#include <asm/string.h>
 #include <linux/linkage.h>
+#include <asm/string.h>
 
 #include <asm/unaligned.h>
 
@@ -33,6 +33,7 @@ unsigned int __machine_arch_type;
 #else
 
 static void putstr(const char *ptr);
+extern void error(char *x);
 
 #include <mach/uncompress.h>
 
@@ -117,57 +118,7 @@ static void putstr(const char *ptr)
 
 #endif
 
-#define __ptr_t void *
-
-#define memzero(s,n) __memzero(s,n)
-
-/*
- * Optimised C version of memzero for the ARM.
- */
-void __memzero (__ptr_t s, size_t n)
-{
-	union { void *vp; unsigned long *ulp; unsigned char *ucp; } u;
-	int i;
-
-	u.vp = s;
-
-	for (i = n >> 5; i > 0; i--) {
-		*u.ulp++ = 0;
-		*u.ulp++ = 0;
-		*u.ulp++ = 0;
-		*u.ulp++ = 0;
-		*u.ulp++ = 0;
-		*u.ulp++ = 0;
-		*u.ulp++ = 0;
-		*u.ulp++ = 0;
-	}
-
-	if (n & 1 << 4) {
-		*u.ulp++ = 0;
-		*u.ulp++ = 0;
-		*u.ulp++ = 0;
-		*u.ulp++ = 0;
-	}
-
-	if (n & 1 << 3) {
-		*u.ulp++ = 0;
-		*u.ulp++ = 0;
-	}
-
-	if (n & 1 << 2)
-		*u.ulp++ = 0;
-
-	if (n & 1 << 1) {
-		*u.ucp++ = 0;
-		*u.ucp++ = 0;
-	}
-
-	if (n & 1)
-		*u.ucp++ = 0;
-}
-
-static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
-			    size_t __n)
+void *memcpy(void *__dest, __const void *__src, size_t __n)
 {
 	int i = 0;
 	unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
@@ -204,59 +155,20 @@ static inline __ptr_t memcpy(__ptr_t __d
 /*
  * gzip delarations
  */
-#define STATIC static
-
-/* 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 error(char *m);
-
 extern char input_data[];
 extern char input_data_end[];
 
-static unsigned char *output_data;
-static unsigned long output_ptr;
-
-static void error(char *m);
-
-static void putstr(const char *);
-
-static unsigned long free_mem_ptr;
-static unsigned long free_mem_end_ptr;
-
-#ifdef STANDALONE_DEBUG
-#define NO_INFLATE_MALLOC
-#endif
-
-#define ARCH_HAS_DECOMP_WDOG
-
-#ifdef CONFIG_KERNEL_GZIP
-#include "../../../../lib/decompress_inflate.c"
-#endif
+unsigned char *output_data;
+unsigned long output_ptr;
 
-#ifdef CONFIG_KERNEL_LZO
-#include "../../../../lib/decompress_unlzo.c"
-#endif
+unsigned long free_mem_ptr;
+unsigned long free_mem_end_ptr;
 
 #ifndef arch_error
 #define arch_error(x)
 #endif
 
-static void error(char *x)
+void error(char *x)
 {
 	arch_error(x);
 
@@ -272,6 +184,8 @@ asmlinkage void __div0(void)
 	error("Attempting division by 0!");
 }
 
+extern void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
+
 #ifndef STANDALONE_DEBUG
 
 unsigned long
@@ -292,8 +206,8 @@ decompress_kernel(unsigned long output_s
 	output_ptr = get_unaligned_le32(tmp);
 
 	putstr("Uncompressing Linux...");
-	decompress(input_data, input_data_end - input_data,
-			NULL, NULL, output_data, NULL, error);
+	do_decompress(input_data, input_data_end - input_data,
+			output_data, error);
 	putstr(" done, booting the kernel.\n");
 	return output_ptr;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/vmlinux.lds.in linux-libre-2.6.34-gnu1/arch/arm/boot/compressed/vmlinux.lds.in
--- linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/vmlinux.lds.in	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/boot/compressed/vmlinux.lds.in	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,13 @@ SECTIONS
   /DISCARD/ : {
     *(.ARM.exidx*)
     *(.ARM.extab*)
+    /*
+     * Discard any r/w data - this produces a link error if we have any,
+     * which is required for PIC decompression.  Local data generates
+     * GOTOFF relocations, which prevents it being relocated independently
+     * of the text/got segments.
+     */
+    *(.data)
   }
 
   . = TEXT_START;
@@ -36,11 +43,13 @@ SECTIONS
 
   _etext = .;
 
+  /* Assume size of decompressed image is 4x the compressed image */
+  _image_size = (_etext - _text) * 4;
+
   _got_start = .;
   .got			: { *(.got) }
   _got_end = .;
   .got.plt		: { *(.got.plt) }
-  .data			: { *(.data) }
   _edata = .;
 
   . = BSS_START;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/common/clkdev.c linux-libre-2.6.34-gnu1/arch/arm/common/clkdev.c
--- linux-libre-2.6.33-gnu1/arch/arm/common/clkdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/common/clkdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/mutex.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include <asm/clkdev.h>
 #include <mach/clkdev.h>
@@ -32,7 +33,7 @@ static DEFINE_MUTEX(clocks_mutex);
  *  If an entry has a device ID, it must match
  *  If an entry has a connection ID, it must match
  * Then we take the most specific entry - with the following
- * order of precidence: dev+con > dev only > con only.
+ * order of precedence: dev+con > dev only > con only.
  */
 static struct clk *clk_find(const char *dev_id, const char *con_id)
 {
@@ -99,6 +100,16 @@ void clkdev_add(struct clk_lookup *cl)
 }
 EXPORT_SYMBOL(clkdev_add);
 
+void __init clkdev_add_table(struct clk_lookup *cl, size_t num)
+{
+	mutex_lock(&clocks_mutex);
+	while (num--) {
+		list_add_tail(&cl->node, &clocks);
+		cl++;
+	}
+	mutex_unlock(&clocks_mutex);
+}
+
 #define MAX_DEV_ID	20
 #define MAX_CON_ID	16
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/common/dmabounce.c linux-libre-2.6.34-gnu1/arch/arm/common/dmabounce.c
--- linux-libre-2.6.33-gnu1/arch/arm/common/dmabounce.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/common/dmabounce.c	2010-05-16 17:17:36.000000000 -0400
@@ -277,7 +277,7 @@ static inline dma_addr_t map_single(stru
 		 * We don't need to sync the DMA buffer since
 		 * it was allocated via the coherent allocators.
 		 */
-		dma_cache_maint(ptr, size, dir);
+		__dma_single_cpu_to_dev(ptr, size, dir);
 	}
 
 	return dma_addr;
@@ -315,6 +315,8 @@ static inline void unmap_single(struct d
 			__cpuc_flush_dcache_area(ptr, size);
 		}
 		free_safe_buffer(dev->archdata.dmabounce, buf);
+	} else {
+		__dma_single_dev_to_cpu(dma_to_virt(dev, dma_addr), size, dir);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/common/it8152.c linux-libre-2.6.34-gnu1/arch/arm/common/it8152.c
--- linux-libre-2.6.33-gnu1/arch/arm/common/it8152.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/common/it8152.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@
 #include <linux/ptrace.h>
 #include <linux/interrupt.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
@@ -272,33 +271,6 @@ int dma_needs_bounce(struct device *dev,
 		((dma_addr + size - PHYS_OFFSET) >= SZ_64M);
 }
 
-/*
- * We override these so we properly do dmabounce otherwise drivers
- * are able to set the dma_mask to 0xffffffff and we can no longer
- * trap bounces. :(
- *
- * We just return true on everyhing except for < 64MB in which case
- * we will fail miseralby and die since we can't handle that case.
- */
-int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
-	dev_dbg(&dev->dev, "%s: %llx\n", __func__, mask);
-	if (mask >= PHYS_OFFSET + SZ_64M - 1)
-		return 0;
-
-	return -EIO;
-}
-
-int
-pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
-	dev_dbg(&dev->dev, "%s: %llx\n", __func__, mask);
-	if (mask >= PHYS_OFFSET + SZ_64M - 1)
-		return 0;
-
-	return -EIO;
-}
-
 int __init it8152_pci_setup(int nr, struct pci_sys_data *sys)
 {
 	it8152_io.start = IT8152_IO_BASE + 0x12000;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/common/locomo.c linux-libre-2.6.34-gnu1/arch/arm/common/locomo.c
--- linux-libre-2.6.33-gnu1/arch/arm/common/locomo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/common/locomo.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,12 @@
 
 #include <asm/hardware/locomo.h>
 
+/* LoCoMo Interrupts */
+#define IRQ_LOCOMO_KEY		(0)
+#define IRQ_LOCOMO_GPIO		(1)
+#define IRQ_LOCOMO_LT		(2)
+#define IRQ_LOCOMO_SPI		(3)
+
 /* M62332 output channel selection */
 #define M62332_EVR_CH	1	/* M62332 volume channel number  */
 				/*   0 : CH.1 , 1 : CH. 2        */
@@ -58,6 +64,7 @@ struct locomo {
 	struct device *dev;
 	unsigned long phys;
 	unsigned int irq;
+	int irq_base;
 	spinlock_t lock;
 	void __iomem *base;
 #ifdef CONFIG_PM
@@ -81,9 +88,7 @@ struct locomo_dev_info {
 static struct locomo_dev_info locomo_devices[] = {
 	{
 		.devid 		= LOCOMO_DEVID_KEYBOARD,
-		.irq = {
-			IRQ_LOCOMO_KEY,
-		},
+		.irq		= { IRQ_LOCOMO_KEY },
 		.name		= "locomo-keyboard",
 		.offset		= LOCOMO_KEYBOARD,
 		.length		= 16,
@@ -133,53 +138,20 @@ static struct locomo_dev_info locomo_dev
 	},
 };
 
-
-/** LoCoMo interrupt handling stuff.
- * NOTE: LoCoMo has a 1 to many mapping on all of its IRQs.
- * that is, there is only one real hardware interrupt
- * we determine which interrupt it is by reading some IO memory.
- * We have two levels of expansion, first in the handler for the
- * hardware interrupt we generate an interrupt
- * IRQ_LOCOMO_*_BASE and those handlers generate more interrupts
- *
- * hardware irq reads LOCOMO_ICR & 0x0f00
- *   IRQ_LOCOMO_KEY_BASE
- *   IRQ_LOCOMO_GPIO_BASE
- *   IRQ_LOCOMO_LT_BASE
- *   IRQ_LOCOMO_SPI_BASE
- * IRQ_LOCOMO_KEY_BASE reads LOCOMO_KIC & 0x0001
- *   IRQ_LOCOMO_KEY
- * IRQ_LOCOMO_GPIO_BASE reads LOCOMO_GIR & LOCOMO_GPD & 0xffff
- *   IRQ_LOCOMO_GPIO[0-15]
- * IRQ_LOCOMO_LT_BASE reads LOCOMO_LTINT & 0x0001
- *   IRQ_LOCOMO_LT
- * IRQ_LOCOMO_SPI_BASE reads LOCOMO_SPIIR & 0x000F
- *   IRQ_LOCOMO_SPI_RFR
- *   IRQ_LOCOMO_SPI_RFW
- *   IRQ_LOCOMO_SPI_OVRN
- *   IRQ_LOCOMO_SPI_TEND
- */
-
-#define LOCOMO_IRQ_START	(IRQ_LOCOMO_KEY_BASE)
-#define LOCOMO_IRQ_KEY_START	(IRQ_LOCOMO_KEY)
-#define	LOCOMO_IRQ_GPIO_START	(IRQ_LOCOMO_GPIO0)
-#define	LOCOMO_IRQ_LT_START	(IRQ_LOCOMO_LT)
-#define	LOCOMO_IRQ_SPI_START	(IRQ_LOCOMO_SPI_RFR)
-
 static void locomo_handler(unsigned int irq, struct irq_desc *desc)
 {
+	struct locomo *lchip = get_irq_chip_data(irq);
 	int req, i;
-	void __iomem *mapbase = get_irq_chip_data(irq);
 
 	/* Acknowledge the parent IRQ */
 	desc->chip->ack(irq);
 
 	/* check why this interrupt was generated */
-	req = locomo_readl(mapbase + LOCOMO_ICR) & 0x0f00;
+	req = locomo_readl(lchip->base + LOCOMO_ICR) & 0x0f00;
 
 	if (req) {
 		/* generate the next interrupt(s) */
-		irq = LOCOMO_IRQ_START;
+		irq = lchip->irq_base;
 		for (i = 0; i <= 3; i++, irq++) {
 			if (req & (0x0100 << i)) {
 				generic_handle_irq(irq);
@@ -195,20 +167,20 @@ static void locomo_ack_irq(unsigned int
 
 static void locomo_mask_irq(unsigned int irq)
 {
-	void __iomem *mapbase = get_irq_chip_data(irq);
+	struct locomo *lchip = get_irq_chip_data(irq);
 	unsigned int r;
-	r = locomo_readl(mapbase + LOCOMO_ICR);
-	r &= ~(0x0010 << (irq - LOCOMO_IRQ_START));
-	locomo_writel(r, mapbase + LOCOMO_ICR);
+	r = locomo_readl(lchip->base + LOCOMO_ICR);
+	r &= ~(0x0010 << (irq - lchip->irq_base));
+	locomo_writel(r, lchip->base + LOCOMO_ICR);
 }
 
 static void locomo_unmask_irq(unsigned int irq)
 {
-	void __iomem *mapbase = get_irq_chip_data(irq);
+	struct locomo *lchip = get_irq_chip_data(irq);
 	unsigned int r;
-	r = locomo_readl(mapbase + LOCOMO_ICR);
-	r |= (0x0010 << (irq - LOCOMO_IRQ_START));
-	locomo_writel(r, mapbase + LOCOMO_ICR);
+	r = locomo_readl(lchip->base + LOCOMO_ICR);
+	r |= (0x0010 << (irq - lchip->irq_base));
+	locomo_writel(r, lchip->base + LOCOMO_ICR);
 }
 
 static struct irq_chip locomo_chip = {
@@ -218,297 +190,22 @@ static struct irq_chip locomo_chip = {
 	.unmask	= locomo_unmask_irq,
 };
 
-static void locomo_key_handler(unsigned int irq, struct irq_desc *desc)
-{
-	void __iomem *mapbase = get_irq_chip_data(irq);
-
-	if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) {
-		generic_handle_irq(LOCOMO_IRQ_KEY_START);
-	}
-}
-
-static void locomo_key_ack_irq(unsigned int irq)
-{
-	void __iomem *mapbase = get_irq_chip_data(irq);
-	unsigned int r;
-	r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
-	r &= ~(0x0100 << (irq - LOCOMO_IRQ_KEY_START));
-	locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
-}
-
-static void locomo_key_mask_irq(unsigned int irq)
-{
-	void __iomem *mapbase = get_irq_chip_data(irq);
-	unsigned int r;
-	r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
-	r &= ~(0x0010 << (irq - LOCOMO_IRQ_KEY_START));
-	locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
-}
-
-static void locomo_key_unmask_irq(unsigned int irq)
-{
-	void __iomem *mapbase = get_irq_chip_data(irq);
-	unsigned int r;
-	r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
-	r |= (0x0010 << (irq - LOCOMO_IRQ_KEY_START));
-	locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
-}
-
-static struct irq_chip locomo_key_chip = {
-	.name	= "LOCOMO-key",
-	.ack	= locomo_key_ack_irq,
-	.mask	= locomo_key_mask_irq,
-	.unmask	= locomo_key_unmask_irq,
-};
-
-static void locomo_gpio_handler(unsigned int irq, struct irq_desc *desc)
-{
-	int req, i;
-	void __iomem *mapbase = get_irq_chip_data(irq);
-
-	req = 	locomo_readl(mapbase + LOCOMO_GIR) &
-		locomo_readl(mapbase + LOCOMO_GPD) &
-		0xffff;
-
-	if (req) {
-		irq = LOCOMO_IRQ_GPIO_START;
-		for (i = 0; i <= 15; i++, irq++) {
-			if (req & (0x0001 << i)) {
-				generic_handle_irq(irq);
-			}
-		}
-	}
-}
-
-static void locomo_gpio_ack_irq(unsigned int irq)
-{
-	void __iomem *mapbase = get_irq_chip_data(irq);
-	unsigned int r;
-	r = locomo_readl(mapbase + LOCOMO_GWE);
-	r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
-	locomo_writel(r, mapbase + LOCOMO_GWE);
-
-	r = locomo_readl(mapbase + LOCOMO_GIS);
-	r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
-	locomo_writel(r, mapbase + LOCOMO_GIS);
-
-	r = locomo_readl(mapbase + LOCOMO_GWE);
-	r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
-	locomo_writel(r, mapbase + LOCOMO_GWE);
-}
-
-static void locomo_gpio_mask_irq(unsigned int irq)
-{
-	void __iomem *mapbase = get_irq_chip_data(irq);
-	unsigned int r;
-	r = locomo_readl(mapbase + LOCOMO_GIE);
-	r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
-	locomo_writel(r, mapbase + LOCOMO_GIE);
-}
-
-static void locomo_gpio_unmask_irq(unsigned int irq)
-{
-	void __iomem *mapbase = get_irq_chip_data(irq);
-	unsigned int r;
-	r = locomo_readl(mapbase + LOCOMO_GIE);
-	r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
-	locomo_writel(r, mapbase + LOCOMO_GIE);
-}
-
-static int GPIO_IRQ_rising_edge;
-static int GPIO_IRQ_falling_edge;
-
-static int locomo_gpio_type(unsigned int irq, unsigned int type)
-{
-	unsigned int mask;
-	void __iomem *mapbase = get_irq_chip_data(irq);
-
-	mask = 1 << (irq - LOCOMO_IRQ_GPIO_START);
-
-	if (type == IRQ_TYPE_PROBE) {
-		if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
-			return 0;
-		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
-	}
-
-	if (type & IRQ_TYPE_EDGE_RISING)
-		GPIO_IRQ_rising_edge |= mask;
-	else
-		GPIO_IRQ_rising_edge &= ~mask;
-	if (type & IRQ_TYPE_EDGE_FALLING)
-		GPIO_IRQ_falling_edge |= mask;
-	else
-		GPIO_IRQ_falling_edge &= ~mask;
-	locomo_writel(GPIO_IRQ_rising_edge, mapbase + LOCOMO_GRIE);
-	locomo_writel(GPIO_IRQ_falling_edge, mapbase + LOCOMO_GFIE);
-
-	return 0;
-}
-
-static struct irq_chip locomo_gpio_chip = {
-	.name	  = "LOCOMO-gpio",
-	.ack	  = locomo_gpio_ack_irq,
-	.mask	  = locomo_gpio_mask_irq,
-	.unmask	  = locomo_gpio_unmask_irq,
-	.set_type = locomo_gpio_type,
-};
-
-static void locomo_lt_handler(unsigned int irq, struct irq_desc *desc)
-{
-	void __iomem *mapbase = get_irq_chip_data(irq);
-
-	if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) {
-		generic_handle_irq(LOCOMO_IRQ_LT_START);
-	}
-}
-
-static void locomo_lt_ack_irq(unsigned int irq)
-{
-	void __iomem *mapbase = get_irq_chip_data(irq);
-	unsigned int r;
-	r = locomo_readl(mapbase + LOCOMO_LTINT);
-	r &= ~(0x0100 << (irq - LOCOMO_IRQ_LT_START));
-	locomo_writel(r, mapbase + LOCOMO_LTINT);
-}
-
-static void locomo_lt_mask_irq(unsigned int irq)
-{
-	void __iomem *mapbase = get_irq_chip_data(irq);
-	unsigned int r;
-	r = locomo_readl(mapbase + LOCOMO_LTINT);
-	r &= ~(0x0010 << (irq - LOCOMO_IRQ_LT_START));
-	locomo_writel(r, mapbase + LOCOMO_LTINT);
-}
-
-static void locomo_lt_unmask_irq(unsigned int irq)
-{
-	void __iomem *mapbase = get_irq_chip_data(irq);
-	unsigned int r;
-	r = locomo_readl(mapbase + LOCOMO_LTINT);
-	r |= (0x0010 << (irq - LOCOMO_IRQ_LT_START));
-	locomo_writel(r, mapbase + LOCOMO_LTINT);
-}
-
-static struct irq_chip locomo_lt_chip = {
-	.name	= "LOCOMO-lt",
-	.ack	= locomo_lt_ack_irq,
-	.mask	= locomo_lt_mask_irq,
-	.unmask	= locomo_lt_unmask_irq,
-};
-
-static void locomo_spi_handler(unsigned int irq, struct irq_desc *desc)
-{
-	int req, i;
-	void __iomem *mapbase = get_irq_chip_data(irq);
-
-	req = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIR) & 0x000F;
-	if (req) {
-		irq = LOCOMO_IRQ_SPI_START;
-
-		for (i = 0; i <= 3; i++, irq++) {
-			if (req & (0x0001 << i)) {
-				generic_handle_irq(irq);
-			}
-		}
-	}
-}
-
-static void locomo_spi_ack_irq(unsigned int irq)
-{
-	void __iomem *mapbase = get_irq_chip_data(irq);
-	unsigned int r;
-	r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
-	r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START));
-	locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
-
-	r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIS);
-	r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));
-	locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIS);
-
-	r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
-	r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));
-	locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
-}
-
-static void locomo_spi_mask_irq(unsigned int irq)
-{
-	void __iomem *mapbase = get_irq_chip_data(irq);
-	unsigned int r;
-	r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
-	r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));
-	locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
-}
-
-static void locomo_spi_unmask_irq(unsigned int irq)
-{
-	void __iomem *mapbase = get_irq_chip_data(irq);
-	unsigned int r;
-	r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
-	r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START));
-	locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
-}
-
-static struct irq_chip locomo_spi_chip = {
-	.name	= "LOCOMO-spi",
-	.ack	= locomo_spi_ack_irq,
-	.mask	= locomo_spi_mask_irq,
-	.unmask	= locomo_spi_unmask_irq,
-};
-
 static void locomo_setup_irq(struct locomo *lchip)
 {
-	int irq;
-	void __iomem *irqbase = lchip->base;
+	int irq = lchip->irq_base;
 
 	/*
 	 * Install handler for IRQ_LOCOMO_HW.
 	 */
 	set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING);
-	set_irq_chip_data(lchip->irq, irqbase);
+	set_irq_chip_data(lchip->irq, lchip);
 	set_irq_chained_handler(lchip->irq, locomo_handler);
 
-	/* Install handlers for IRQ_LOCOMO_*_BASE */
-	set_irq_chip(IRQ_LOCOMO_KEY_BASE, &locomo_chip);
-	set_irq_chip_data(IRQ_LOCOMO_KEY_BASE, irqbase);
-	set_irq_chained_handler(IRQ_LOCOMO_KEY_BASE, locomo_key_handler);
-
-	set_irq_chip(IRQ_LOCOMO_GPIO_BASE, &locomo_chip);
-	set_irq_chip_data(IRQ_LOCOMO_GPIO_BASE, irqbase);
-	set_irq_chained_handler(IRQ_LOCOMO_GPIO_BASE, locomo_gpio_handler);
-
-	set_irq_chip(IRQ_LOCOMO_LT_BASE, &locomo_chip);
-	set_irq_chip_data(IRQ_LOCOMO_LT_BASE, irqbase);
-	set_irq_chained_handler(IRQ_LOCOMO_LT_BASE, locomo_lt_handler);
-
-	set_irq_chip(IRQ_LOCOMO_SPI_BASE, &locomo_chip);
-	set_irq_chip_data(IRQ_LOCOMO_SPI_BASE, irqbase);
-	set_irq_chained_handler(IRQ_LOCOMO_SPI_BASE, locomo_spi_handler);
-
-	/* install handlers for IRQ_LOCOMO_KEY_BASE generated interrupts */
-	set_irq_chip(LOCOMO_IRQ_KEY_START, &locomo_key_chip);
-	set_irq_chip_data(LOCOMO_IRQ_KEY_START, irqbase);
-	set_irq_handler(LOCOMO_IRQ_KEY_START, handle_edge_irq);
-	set_irq_flags(LOCOMO_IRQ_KEY_START, IRQF_VALID | IRQF_PROBE);
-
-	/* install handlers for IRQ_LOCOMO_GPIO_BASE generated interrupts */
-	for (irq = LOCOMO_IRQ_GPIO_START; irq < LOCOMO_IRQ_GPIO_START + 16; irq++) {
-		set_irq_chip(irq, &locomo_gpio_chip);
-		set_irq_chip_data(irq, irqbase);
-		set_irq_handler(irq, handle_edge_irq);
-		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-	}
-
-	/* install handlers for IRQ_LOCOMO_LT_BASE generated interrupts */
-	set_irq_chip(LOCOMO_IRQ_LT_START, &locomo_lt_chip);
-	set_irq_chip_data(LOCOMO_IRQ_LT_START, irqbase);
-	set_irq_handler(LOCOMO_IRQ_LT_START, handle_edge_irq);
-	set_irq_flags(LOCOMO_IRQ_LT_START, IRQF_VALID | IRQF_PROBE);
-
-	/* install handlers for IRQ_LOCOMO_SPI_BASE generated interrupts */
-	for (irq = LOCOMO_IRQ_SPI_START; irq < LOCOMO_IRQ_SPI_START + 4; irq++) {
-		set_irq_chip(irq, &locomo_spi_chip);
-		set_irq_chip_data(irq, irqbase);
-		set_irq_handler(irq, handle_edge_irq);
+	/* Install handlers for IRQ_LOCOMO_* */
+	for ( ; irq <= lchip->irq_base + 3; irq++) {
+		set_irq_chip(irq, &locomo_chip);
+		set_irq_chip_data(irq, lchip);
+		set_irq_handler(irq, handle_level_irq);
 		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 	}
 }
@@ -555,7 +252,8 @@ locomo_init_one_child(struct locomo *lch
 		dev->mapbase = 0;
 	dev->length = info->length;
 
-	memmove(dev->irq, info->irq, sizeof(dev->irq));
+	dev->irq[0] = (lchip->irq_base == NO_IRQ) ?
+			NO_IRQ : lchip->irq_base + info->irq[0];
 
 	ret = device_register(&dev->dev);
 	if (ret) {
@@ -592,7 +290,7 @@ static int locomo_suspend(struct platfor
 	save->LCM_GPO     = locomo_readl(lchip->base + LOCOMO_GPO);	/* GPIO */
 	locomo_writel(0x00, lchip->base + LOCOMO_GPO);
 	save->LCM_SPICT   = locomo_readl(lchip->base + LOCOMO_SPI + LOCOMO_SPICT);	/* SPI */
-	locomo_writel(0x40, lchip->base + LOCOMO_SPICT);
+	locomo_writel(0x40, lchip->base + LOCOMO_SPI + LOCOMO_SPICT);
 	save->LCM_GPE     = locomo_readl(lchip->base + LOCOMO_GPE);	/* GPIO */
 	locomo_writel(0x00, lchip->base + LOCOMO_GPE);
 	save->LCM_ASD     = locomo_readl(lchip->base + LOCOMO_ASD);	/* ADSTART */
@@ -672,6 +370,7 @@ static int locomo_resume(struct platform
 static int
 __locomo_probe(struct device *me, struct resource *mem, int irq)
 {
+	struct locomo_platform_data *pdata = me->platform_data;
 	struct locomo *lchip;
 	unsigned long r;
 	int i, ret = -ENODEV;
@@ -687,6 +386,7 @@ __locomo_probe(struct device *me, struct
 
 	lchip->phys = mem->start;
 	lchip->irq = irq;
+	lchip->irq_base = (pdata) ? pdata->irq_base : NO_IRQ;
 
 	/*
 	 * Map the whole region.  This also maps the
@@ -718,7 +418,7 @@ __locomo_probe(struct device *me, struct
 	/* Longtime timer */
 	locomo_writel(0, lchip->base + LOCOMO_LTINT);
 	/* SPI */
-	locomo_writel(0, lchip->base + LOCOMO_SPIIE);
+	locomo_writel(0, lchip->base + LOCOMO_SPI + LOCOMO_SPIIE);
 
 	locomo_writel(6 + 8 + 320 + 30 - 10, lchip->base + LOCOMO_ASD);
 	r = locomo_readl(lchip->base + LOCOMO_ASD);
@@ -753,7 +453,7 @@ __locomo_probe(struct device *me, struct
 	 * The interrupt controller must be initialised before any
 	 * other device to ensure that the interrupts are available.
 	 */
-	if (lchip->irq != NO_IRQ)
+	if (lchip->irq != NO_IRQ && lchip->irq_base != NO_IRQ)
 		locomo_setup_irq(lchip);
 
 	for (i = 0; i < ARRAY_SIZE(locomo_devices); i++)
@@ -1007,7 +707,7 @@ void locomo_m62332_senddata(struct locom
 	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.7 usec */
 	if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */
 		printk(KERN_WARNING "locomo: m62332_senddata Error 1\n");
-		return;
+		goto out;
 	}
 
 	/* Send Sub address (LSB is channel select) */
@@ -1035,7 +735,7 @@ void locomo_m62332_senddata(struct locom
 	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.7 usec */
 	if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */
 		printk(KERN_WARNING "locomo: m62332_senddata Error 2\n");
-		return;
+		goto out;
 	}
 
 	/* Send DAC data */
@@ -1060,9 +760,9 @@ void locomo_m62332_senddata(struct locom
 	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.7 usec */
 	if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */
 		printk(KERN_WARNING "locomo: m62332_senddata Error 3\n");
-		return;
 	}
 
+out:
 	/* stop */
 	r = locomo_readl(mapbase + LOCOMO_DAC);
 	r &=  ~(LOCOMO_DAC_SCLOEB);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/common/sa1111.c linux-libre-2.6.34-gnu1/arch/arm/common/sa1111.c
--- linux-libre-2.6.33-gnu1/arch/arm/common/sa1111.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/common/sa1111.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,58 @@
 
 #include <asm/hardware/sa1111.h>
 
+/* SA1111 IRQs */
+#define IRQ_GPAIN0		(0)
+#define IRQ_GPAIN1		(1)
+#define IRQ_GPAIN2		(2)
+#define IRQ_GPAIN3		(3)
+#define IRQ_GPBIN0		(4)
+#define IRQ_GPBIN1		(5)
+#define IRQ_GPBIN2		(6)
+#define IRQ_GPBIN3		(7)
+#define IRQ_GPBIN4		(8)
+#define IRQ_GPBIN5		(9)
+#define IRQ_GPCIN0		(10)
+#define IRQ_GPCIN1		(11)
+#define IRQ_GPCIN2		(12)
+#define IRQ_GPCIN3		(13)
+#define IRQ_GPCIN4		(14)
+#define IRQ_GPCIN5		(15)
+#define IRQ_GPCIN6		(16)
+#define IRQ_GPCIN7		(17)
+#define IRQ_MSTXINT		(18)
+#define IRQ_MSRXINT		(19)
+#define IRQ_MSSTOPERRINT	(20)
+#define IRQ_TPTXINT		(21)
+#define IRQ_TPRXINT		(22)
+#define IRQ_TPSTOPERRINT	(23)
+#define SSPXMTINT		(24)
+#define SSPRCVINT		(25)
+#define SSPROR			(26)
+#define AUDXMTDMADONEA		(32)
+#define AUDRCVDMADONEA		(33)
+#define AUDXMTDMADONEB		(34)
+#define AUDRCVDMADONEB		(35)
+#define AUDTFSR			(36)
+#define AUDRFSR			(37)
+#define AUDTUR			(38)
+#define AUDROR			(39)
+#define AUDDTS			(40)
+#define AUDRDD			(41)
+#define AUDSTO			(42)
+#define IRQ_USBPWR		(43)
+#define IRQ_HCIM		(44)
+#define IRQ_HCIBUFFACC		(45)
+#define IRQ_HCIRMTWKP		(46)
+#define IRQ_NHCIMFCIR		(47)
+#define IRQ_USB_PORT_RESUME	(48)
+#define IRQ_S0_READY_NINT	(49)
+#define IRQ_S1_READY_NINT	(50)
+#define IRQ_S0_CD_VALID		(51)
+#define IRQ_S1_CD_VALID		(52)
+#define IRQ_S0_BVD1_STSCHG	(53)
+#define IRQ_S1_BVD1_STSCHG	(54)
+
 extern void __init sa1110_mb_enable(void);
 
 /*
@@ -49,6 +101,7 @@ struct sa1111 {
 	struct clk	*clk;
 	unsigned long	phys;
 	int		irq;
+	int		irq_base;	/* base for cascaded on-chip IRQs */
 	spinlock_t	lock;
 	void __iomem	*base;
 #ifdef CONFIG_PM
@@ -152,36 +205,37 @@ static void
 sa1111_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
 	unsigned int stat0, stat1, i;
-	void __iomem *base = get_irq_data(irq);
+	struct sa1111 *sachip = get_irq_data(irq);
+	void __iomem *mapbase = sachip->base + SA1111_INTC;
 
-	stat0 = sa1111_readl(base + SA1111_INTSTATCLR0);
-	stat1 = sa1111_readl(base + SA1111_INTSTATCLR1);
+	stat0 = sa1111_readl(mapbase + SA1111_INTSTATCLR0);
+	stat1 = sa1111_readl(mapbase + SA1111_INTSTATCLR1);
 
-	sa1111_writel(stat0, base + SA1111_INTSTATCLR0);
+	sa1111_writel(stat0, mapbase + SA1111_INTSTATCLR0);
 
 	desc->chip->ack(irq);
 
-	sa1111_writel(stat1, base + SA1111_INTSTATCLR1);
+	sa1111_writel(stat1, mapbase + SA1111_INTSTATCLR1);
 
 	if (stat0 == 0 && stat1 == 0) {
 		do_bad_IRQ(irq, desc);
 		return;
 	}
 
-	for (i = IRQ_SA1111_START; stat0; i++, stat0 >>= 1)
+	for (i = 0; stat0; i++, stat0 >>= 1)
 		if (stat0 & 1)
-			handle_edge_irq(i, irq_desc + i);
+			generic_handle_irq(i + sachip->irq_base);
 
-	for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1)
+	for (i = 32; stat1; i++, stat1 >>= 1)
 		if (stat1 & 1)
-			handle_edge_irq(i, irq_desc + i);
+			generic_handle_irq(i + sachip->irq_base);
 
 	/* For level-based interrupts */
 	desc->chip->unmask(irq);
 }
 
-#define SA1111_IRQMASK_LO(x)	(1 << (x - IRQ_SA1111_START))
-#define SA1111_IRQMASK_HI(x)	(1 << (x - IRQ_SA1111_START - 32))
+#define SA1111_IRQMASK_LO(x)	(1 << (x - sachip->irq_base))
+#define SA1111_IRQMASK_HI(x)	(1 << (x - sachip->irq_base - 32))
 
 static void sa1111_ack_irq(unsigned int irq)
 {
@@ -189,7 +243,8 @@ static void sa1111_ack_irq(unsigned int
 
 static void sa1111_mask_lowirq(unsigned int irq)
 {
-	void __iomem *mapbase = get_irq_chip_data(irq);
+	struct sa1111 *sachip = get_irq_chip_data(irq);
+	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned long ie0;
 
 	ie0 = sa1111_readl(mapbase + SA1111_INTEN0);
@@ -199,7 +254,8 @@ static void sa1111_mask_lowirq(unsigned
 
 static void sa1111_unmask_lowirq(unsigned int irq)
 {
-	void __iomem *mapbase = get_irq_chip_data(irq);
+	struct sa1111 *sachip = get_irq_chip_data(irq);
+	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned long ie0;
 
 	ie0 = sa1111_readl(mapbase + SA1111_INTEN0);
@@ -216,8 +272,9 @@ static void sa1111_unmask_lowirq(unsigne
  */
 static int sa1111_retrigger_lowirq(unsigned int irq)
 {
+	struct sa1111 *sachip = get_irq_chip_data(irq);
+	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_LO(irq);
-	void __iomem *mapbase = get_irq_chip_data(irq);
 	unsigned long ip0;
 	int i;
 
@@ -237,8 +294,9 @@ static int sa1111_retrigger_lowirq(unsig
 
 static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
 {
+	struct sa1111 *sachip = get_irq_chip_data(irq);
+	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_LO(irq);
-	void __iomem *mapbase = get_irq_chip_data(irq);
 	unsigned long ip0;
 
 	if (flags == IRQ_TYPE_PROBE)
@@ -260,8 +318,9 @@ static int sa1111_type_lowirq(unsigned i
 
 static int sa1111_wake_lowirq(unsigned int irq, unsigned int on)
 {
+	struct sa1111 *sachip = get_irq_chip_data(irq);
+	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_LO(irq);
-	void __iomem *mapbase = get_irq_chip_data(irq);
 	unsigned long we0;
 
 	we0 = sa1111_readl(mapbase + SA1111_WAKEEN0);
@@ -286,7 +345,8 @@ static struct irq_chip sa1111_low_chip =
 
 static void sa1111_mask_highirq(unsigned int irq)
 {
-	void __iomem *mapbase = get_irq_chip_data(irq);
+	struct sa1111 *sachip = get_irq_chip_data(irq);
+	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned long ie1;
 
 	ie1 = sa1111_readl(mapbase + SA1111_INTEN1);
@@ -296,7 +356,8 @@ static void sa1111_mask_highirq(unsigned
 
 static void sa1111_unmask_highirq(unsigned int irq)
 {
-	void __iomem *mapbase = get_irq_chip_data(irq);
+	struct sa1111 *sachip = get_irq_chip_data(irq);
+	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned long ie1;
 
 	ie1 = sa1111_readl(mapbase + SA1111_INTEN1);
@@ -313,8 +374,9 @@ static void sa1111_unmask_highirq(unsign
  */
 static int sa1111_retrigger_highirq(unsigned int irq)
 {
+	struct sa1111 *sachip = get_irq_chip_data(irq);
+	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_HI(irq);
-	void __iomem *mapbase = get_irq_chip_data(irq);
 	unsigned long ip1;
 	int i;
 
@@ -334,8 +396,9 @@ static int sa1111_retrigger_highirq(unsi
 
 static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
 {
+	struct sa1111 *sachip = get_irq_chip_data(irq);
+	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_HI(irq);
-	void __iomem *mapbase = get_irq_chip_data(irq);
 	unsigned long ip1;
 
 	if (flags == IRQ_TYPE_PROBE)
@@ -357,8 +420,9 @@ static int sa1111_type_highirq(unsigned
 
 static int sa1111_wake_highirq(unsigned int irq, unsigned int on)
 {
+	struct sa1111 *sachip = get_irq_chip_data(irq);
+	void __iomem *mapbase = sachip->base + SA1111_INTC;
 	unsigned int mask = SA1111_IRQMASK_HI(irq);
-	void __iomem *mapbase = get_irq_chip_data(irq);
 	unsigned long we1;
 
 	we1 = sa1111_readl(mapbase + SA1111_WAKEEN1);
@@ -412,14 +476,14 @@ static void sa1111_setup_irq(struct sa11
 
 	for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) {
 		set_irq_chip(irq, &sa1111_low_chip);
-		set_irq_chip_data(irq, irqbase);
+		set_irq_chip_data(irq, sachip);
 		set_irq_handler(irq, handle_edge_irq);
 		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 	}
 
 	for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) {
 		set_irq_chip(irq, &sa1111_high_chip);
-		set_irq_chip_data(irq, irqbase);
+		set_irq_chip_data(irq, sachip);
 		set_irq_handler(irq, handle_edge_irq);
 		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 	}
@@ -428,7 +492,7 @@ static void sa1111_setup_irq(struct sa11
 	 * Register SA1111 interrupt
 	 */
 	set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING);
-	set_irq_data(sachip->irq, irqbase);
+	set_irq_data(sachip->irq, sachip);
 	set_irq_chained_handler(sachip->irq, sa1111_irq_handler);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/common/scoop.c linux-libre-2.6.34-gnu1/arch/arm/common/scoop.c
--- linux-libre-2.6.33-gnu1/arch/arm/common/scoop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/common/scoop.c	2010-05-16 17:17:36.000000000 -0400
@@ -140,6 +140,7 @@ EXPORT_SYMBOL(reset_scoop);
 EXPORT_SYMBOL(read_scoop_reg);
 EXPORT_SYMBOL(write_scoop_reg);
 
+#ifdef CONFIG_PM
 static void check_scoop_reg(struct scoop_dev *sdev)
 {
 	unsigned short mcr;
@@ -149,7 +150,6 @@ static void check_scoop_reg(struct scoop
 		iowrite16(0x0101, sdev->base + SCOOP_MCR);
 }
 
-#ifdef CONFIG_PM
 static int scoop_suspend(struct platform_device *dev, pm_message_t state)
 {
 	struct scoop_dev *sdev = platform_get_drvdata(dev);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/common/vic.c linux-libre-2.6.34-gnu1/arch/arm/common/vic.c
--- linux-libre-2.6.33-gnu1/arch/arm/common/vic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/common/vic.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
  * 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/list.h>
 #include <linux/io.h>
@@ -28,48 +29,6 @@
 #include <asm/mach/irq.h>
 #include <asm/hardware/vic.h>
 
-static void vic_ack_irq(unsigned int irq)
-{
-	void __iomem *base = get_irq_chip_data(irq);
-	irq &= 31;
-	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
-	/* moreover, clear the soft-triggered, in case it was the reason */
-	writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
-}
-
-static void vic_mask_irq(unsigned int irq)
-{
-	void __iomem *base = get_irq_chip_data(irq);
-	irq &= 31;
-	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
-}
-
-static void vic_unmask_irq(unsigned int irq)
-{
-	void __iomem *base = get_irq_chip_data(irq);
-	irq &= 31;
-	writel(1 << irq, base + VIC_INT_ENABLE);
-}
-
-/**
- * vic_init2 - common initialisation code
- * @base: Base of the VIC.
- *
- * Common initialisation code for registeration
- * and resume.
-*/
-static void vic_init2(void __iomem *base)
-{
-	int i;
-
-	for (i = 0; i < 16; i++) {
-		void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
-		writel(VIC_VECT_CNTL_ENABLE | i, reg);
-	}
-
-	writel(32, base + VIC_PL190_DEF_VECT_ADDR);
-}
-
 #if defined(CONFIG_PM)
 /**
  * struct vic_device - VIC PM device
@@ -99,13 +58,34 @@ struct vic_device {
 /* we cannot allocate memory when VICs are initially registered */
 static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
 
+static int vic_id;
+
 static inline struct vic_device *to_vic(struct sys_device *sys)
 {
 	return container_of(sys, struct vic_device, sysdev);
 }
+#endif /* CONFIG_PM */
 
-static int vic_id;
+/**
+ * vic_init2 - common initialisation code
+ * @base: Base of the VIC.
+ *
+ * Common initialisation code for registeration
+ * and resume.
+*/
+static void vic_init2(void __iomem *base)
+{
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
+		writel(VIC_VECT_CNTL_ENABLE | i, reg);
+	}
+
+	writel(32, base + VIC_PL190_DEF_VECT_ADDR);
+}
 
+#if defined(CONFIG_PM)
 static int vic_class_resume(struct sys_device *dev)
 {
 	struct vic_device *vic = to_vic(dev);
@@ -159,31 +139,6 @@ struct sysdev_class vic_class = {
 };
 
 /**
- * vic_pm_register - Register a VIC for later power management control
- * @base: The base address of the VIC.
- * @irq: The base IRQ for the VIC.
- * @resume_sources: bitmask of interrupts allowed for resume sources.
- *
- * Register the VIC with the system device tree so that it can be notified
- * of suspend and resume requests and ensure that the correct actions are
- * taken to re-instate the settings on resume.
- */
-static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
-{
-	struct vic_device *v;
-
-	if (vic_id >= ARRAY_SIZE(vic_devices))
-		printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
-	else {
-		v = &vic_devices[vic_id];
-		v->base = base;
-		v->resume_sources = resume_sources;
-		v->irq = irq;
-		vic_id++;
-	}
-}
-
-/**
  * vic_pm_init - initicall to register VIC pm
  *
  * This is called via late_initcall() to register
@@ -219,9 +174,60 @@ static int __init vic_pm_init(void)
 
 	return 0;
 }
-
 late_initcall(vic_pm_init);
 
+/**
+ * vic_pm_register - Register a VIC for later power management control
+ * @base: The base address of the VIC.
+ * @irq: The base IRQ for the VIC.
+ * @resume_sources: bitmask of interrupts allowed for resume sources.
+ *
+ * Register the VIC with the system device tree so that it can be notified
+ * of suspend and resume requests and ensure that the correct actions are
+ * taken to re-instate the settings on resume.
+ */
+static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
+{
+	struct vic_device *v;
+
+	if (vic_id >= ARRAY_SIZE(vic_devices))
+		printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
+	else {
+		v = &vic_devices[vic_id];
+		v->base = base;
+		v->resume_sources = resume_sources;
+		v->irq = irq;
+		vic_id++;
+	}
+}
+#else
+static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
+#endif /* CONFIG_PM */
+
+static void vic_ack_irq(unsigned int irq)
+{
+	void __iomem *base = get_irq_chip_data(irq);
+	irq &= 31;
+	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
+	/* moreover, clear the soft-triggered, in case it was the reason */
+	writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
+}
+
+static void vic_mask_irq(unsigned int irq)
+{
+	void __iomem *base = get_irq_chip_data(irq);
+	irq &= 31;
+	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
+}
+
+static void vic_unmask_irq(unsigned int irq)
+{
+	void __iomem *base = get_irq_chip_data(irq);
+	irq &= 31;
+	writel(1 << irq, base + VIC_INT_ENABLE);
+}
+
+#if defined(CONFIG_PM)
 static struct vic_device *vic_from_irq(unsigned int irq)
 {
         struct vic_device *v = vic_devices;
@@ -255,10 +261,7 @@ static int vic_set_wake(unsigned int irq
 
 	return 0;
 }
-
 #else
-static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
-
 #define vic_set_wake NULL
 #endif /* CONFIG_PM */
 
@@ -270,9 +273,62 @@ static struct irq_chip vic_chip = {
 	.set_wake = vic_set_wake,
 };
 
-/* The PL190 cell from ARM has been modified by ST, so handle both here */
-static void vik_init_st(void __iomem *base, unsigned int irq_start,
-			 u32 vic_sources);
+/*
+ * The PL190 cell from ARM has been modified by ST to handle 64 interrupts.
+ * The original cell has 32 interrupts, while the modified one has 64,
+ * replocating two blocks 0x00..0x1f in 0x20..0x3f. In that case
+ * the probe function is called twice, with base set to offset 000
+ *  and 020 within the page. We call this "second block".
+ */
+static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
+				u32 vic_sources)
+{
+	unsigned int i;
+	int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0;
+
+	/* Disable all interrupts initially. */
+
+	writel(0, base + VIC_INT_SELECT);
+	writel(0, base + VIC_INT_ENABLE);
+	writel(~0, base + VIC_INT_ENABLE_CLEAR);
+	writel(0, base + VIC_IRQ_STATUS);
+	writel(0, base + VIC_ITCR);
+	writel(~0, base + VIC_INT_SOFT_CLEAR);
+
+	/*
+	 * Make sure we clear all existing interrupts. The vector registers
+	 * in this cell are after the second block of general registers,
+	 * so we can address them using standard offsets, but only from
+	 * the second base address, which is 0x20 in the page
+	 */
+	if (vic_2nd_block) {
+		writel(0, base + VIC_PL190_VECT_ADDR);
+		for (i = 0; i < 19; i++) {
+			unsigned int value;
+
+			value = readl(base + VIC_PL190_VECT_ADDR);
+			writel(value, base + VIC_PL190_VECT_ADDR);
+		}
+		/* ST has 16 vectors as well, but we don't enable them by now */
+		for (i = 0; i < 16; i++) {
+			void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
+			writel(0, reg);
+		}
+
+		writel(32, base + VIC_PL190_DEF_VECT_ADDR);
+	}
+
+	for (i = 0; i < 32; i++) {
+		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);
+		}
+	}
+}
 
 /**
  * vic_init - initialise a vectored interrupt controller
@@ -299,7 +355,7 @@ void __init vic_init(void __iomem *base,
 
 	switch(vendor) {
 	case AMBA_VENDOR_ST:
-		vik_init_st(base, irq_start, vic_sources);
+		vic_init_st(base, irq_start, vic_sources);
 		return;
 	default:
 		printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
@@ -343,60 +399,3 @@ void __init vic_init(void __iomem *base,
 
 	vic_pm_register(base, irq_start, resume_sources);
 }
-
-/*
- * The PL190 cell from ARM has been modified by ST to handle 64 interrupts.
- * The original cell has 32 interrupts, while the modified one has 64,
- * replocating two blocks 0x00..0x1f in 0x20..0x3f. In that case
- * the probe function is called twice, with base set to offset 000
- *  and 020 within the page. We call this "second block".
- */
-static void __init vik_init_st(void __iomem *base, unsigned int irq_start,
-				u32 vic_sources)
-{
-	unsigned int i;
-	int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0;
-
-	/* Disable all interrupts initially. */
-
-	writel(0, base + VIC_INT_SELECT);
-	writel(0, base + VIC_INT_ENABLE);
-	writel(~0, base + VIC_INT_ENABLE_CLEAR);
-	writel(0, base + VIC_IRQ_STATUS);
-	writel(0, base + VIC_ITCR);
-	writel(~0, base + VIC_INT_SOFT_CLEAR);
-
-	/*
-	 * Make sure we clear all existing interrupts. The vector registers
-	 * in this cell are after the second block of general registers,
-	 * so we can address them using standard offsets, but only from
-	 * the second base address, which is 0x20 in the page
-	 */
-	if (vic_2nd_block) {
-		writel(0, base + VIC_PL190_VECT_ADDR);
-		for (i = 0; i < 19; i++) {
-			unsigned int value;
-
-			value = readl(base + VIC_PL190_VECT_ADDR);
-			writel(value, base + VIC_PL190_VECT_ADDR);
-		}
-		/* ST has 16 vectors as well, but we don't enable them by now */
-		for (i = 0; i < 16; i++) {
-			void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
-			writel(0, reg);
-		}
-
-		writel(32, base + VIC_PL190_DEF_VECT_ADDR);
-	}
-
-	for (i = 0; i < 32; i++) {
-		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.33-gnu1/arch/arm/configs/am3517_evm_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/am3517_evm_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/am3517_evm_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/am3517_evm_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -201,7 +201,7 @@ CONFIG_ARCH_OMAP3=y
 # CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
 # CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
 CONFIG_OMAP_RESET_CLOCKS=y
-# CONFIG_OMAP_MUX is not set
+CONFIG_OMAP_MUX=y
 # CONFIG_OMAP_MCBSP is not set
 # CONFIG_OMAP_MBOX_FWK is not set
 # CONFIG_OMAP_MPU_TIMER is not set
@@ -590,7 +590,46 @@ 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_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_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
 
 #
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/ap4evb_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/ap4evb_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/ap4evb_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/ap4evb_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,779 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc7
+# Mon Feb  8 12:25:36 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=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_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+CONFIG_ARCH_SHMOBILE=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_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+
+#
+# SH-Mobile System Type
+#
+# CONFIG_ARCH_SH7367 is not set
+# CONFIG_ARCH_SH7377 is not set
+CONFIG_ARCH_SH7372=y
+
+#
+# SH-Mobile Board Type
+#
+CONFIG_MACH_AP4EVB=y
+
+#
+# SH-Mobile System Configuration
+#
+
+#
+# Memory configuration
+#
+CONFIG_MEMORY_START=0x40000000
+CONFIG_MEMORY_SIZE=0x10000000
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TIMER_CMT=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySC0,115200 earlyprintk=sh-sci.0,115200"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL 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_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_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
+
+#
+# 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_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP 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_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=8
+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
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS 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_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_FSNOTIFY is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_INOTIFY_USER 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=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES 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_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/at572d940hfek_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/at572d940hfek_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/at572d940hfek_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/at572d940hfek_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1640 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28-rc7
+# Fri Dec  5 10:58:47 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_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="-AT572D940HF"
+# 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=y
+# CONFIG_TASK_DELAY_ACCT is not set
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_AUDIT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_NS is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+# CONFIG_USER_SCHED is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_CGROUP_CPUACCT=y
+# CONFIG_RESOURCE_COUNTERS 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_CC_OPTIMIZE_FOR_SIZE is not set
+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_AIO=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=m
+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_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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+CONFIG_BLK_DEV_IO_TRACE=y
+# 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
+# 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=y
+# 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 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_MSM is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Atmel AT91 System-on-Chip
+#
+# CONFIG_ARCH_AT91RM9200 is not set
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+# CONFIG_ARCH_AT91SAM9RL is not set
+# CONFIG_ARCH_AT91SAM9G20 is not set
+# CONFIG_ARCH_AT91CAP9 is not set
+# CONFIG_ARCH_AT91X40 is not set
+CONFIG_ARCH_AT572D940HF=y
+CONFIG_AT91_PMC_UNIT=y
+
+#
+# AT572D940HF Board Type
+#
+CONFIG_MACH_AT572D940HFEB=y
+
+#
+# AT91 Board Options
+#
+# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
+# CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16 is not set
+CONFIG_NUM_SERIAL=3
+
+#
+# AT91 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_AT91_TIMER_HZ=100
+CONFIG_AT91_EARLY_DBGU=y
+# CONFIG_AT91_EARLY_USART0 is not set
+# CONFIG_AT91_EARLY_USART1 is not set
+# CONFIG_AT91_EARLY_USART2 is not set
+# CONFIG_AT91_EARLY_USART3 is not set
+# CONFIG_AT91_EARLY_USART4 is not set
+# CONFIG_AT91_EARLY_USART5 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_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 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=y
+# 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=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="mem=48M console=ttyS0 initrd=0x21100000,3145728 root=/dev/ram0 rw ip=172.16.1.181"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=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
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+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=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
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+CONFIG_NET_TCPPROBE=m
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
+
+#
+# CAN Device Drivers
+#
+CONFIG_CAN_VCAN=m
+CONFIG_CAN_DEBUG_DEVICES=y
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_MAC80211 is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP 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=m
+CONFIG_MTD=m
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=1
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+# 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=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+CONFIG_SSFDC=m
+CONFIG_MTD_OOPS=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+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=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=m
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x4000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+CONFIG_MTD_PLATRAM=m
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=m
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+# CONFIG_MTD_DATAFLASH_OTP is not set
+CONFIG_MTD_M25P80=m
+CONFIG_M25PXX_USE_FAST_READ=y
+CONFIG_MTD_SLRAM=m
+CONFIG_MTD_PHRAM=m
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=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=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+# CONFIG_MTD_NAND_ATMEL is not set
+CONFIG_MTD_NAND_NANDSIM=m
+CONFIG_MTD_NAND_PLATFORM=m
+CONFIG_MTD_ALAUDA=m
+# CONFIG_MTD_ONENAND 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=y
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65536
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_TCB_CLKSRC=y
+CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
+CONFIG_ATMEL_SSC=m
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=m
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+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=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_MACVLAN=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=m
+CONFIG_ICPLUS_PHY=m
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=m
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_MACB=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# 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_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=y
+CONFIG_STRIP=m
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_USB=m
+CONFIG_LIBERTAS_SDIO=m
+# CONFIG_LIBERTAS_DEBUG is not set
+CONFIG_USB_ZD1201=m
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+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 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=m
+
+#
+# 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=y
+CONFIG_KEYBOARD_SUNKBD=m
+CONFIG_KEYBOARD_LKKBD=m
+CONFIG_KEYBOARD_XTKBD=m
+CONFIG_KEYBOARD_NEWTON=m
+CONFIG_KEYBOARD_STOWAWAY=m
+CONFIG_KEYBOARD_GPIO=m
+CONFIG_INPUT_MOUSE=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
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_APPLETOUCH=m
+# CONFIG_MOUSE_BCM5974 is not set
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_MOUSE_GPIO=m
+# 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=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+# 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=m
+# CONFIG_RISCOM8 is not set
+CONFIG_SPECIALIX=m
+CONFIG_RIO=m
+# CONFIG_RIO_OLDPCI is not set
+CONFIG_STALDRV=y
+
+#
+# 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_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+CONFIG_HW_RANDOM=y
+CONFIG_NVRAM=m
+CONFIG_R3964=m
+CONFIG_RAW_DRIVER=m
+CONFIG_MAX_RAW_DEVS=256
+CONFIG_TCG_TPM=m
+CONFIG_TCG_NSC=m
+CONFIG_TCG_ATMEL=m
+CONFIG_I2C=m
+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_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=m
+# CONFIG_AT24 is not set
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+CONFIG_SENSORS_TSL2550=m
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+CONFIG_SPI_BITBANG=m
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_AT25=m
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 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_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=m
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+# CONFIG_SND_PCM_OSS_PLUGINS is not set
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_DRIVERS=y
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+# 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_AT73C213 is not set
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=m
+# CONFIG_HID_DEBUG is not set
+CONFIG_HIDRAW=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
+
+#
+# USB HID Boot Protocol drivers
+#
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_BRIGHT=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DELL=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_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_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=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=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_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
+
+#
+# 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=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+CONFIG_USB_STORAGE_KARMA=y
+# 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=m
+CONFIG_USB_EZUSB=y
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_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=m
+# CONFIG_USB_SERIAL_OTI6858 is not set
+CONFIG_USB_SERIAL_SPCP8X5=m
+# 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=m
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_ADUTUX=m
+# 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_FILES=y
+CONFIG_USB_GADGET_DEBUG_FS=y
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=m
+# 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_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=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=m
+# 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
+
+#
+# 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/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_AT91=y
+CONFIG_MMC_SPI=m
+# 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_PCA955X is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+# 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=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=m
+# 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=y
+# 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_AT91SAM9 is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_JBD_DEBUG=y
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+CONFIG_REISERFS_CHECK=y
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# 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_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_JFFS2_CMODE_NONE is not set
+# CONFIG_JFFS2_CMODE_PRIORITY is not set
+# CONFIG_JFFS2_CMODE_SIZE is not set
+CONFIG_JFFS2_CMODE_FAVOURLZO=y
+# CONFIG_UBIFS_FS is not set
+CONFIG_CRAMFS=m
+# 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=y
+CONFIG_NFS_V4=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=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 is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+# 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=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_LDM_DEBUG=y
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+# 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=y
+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=m
+# CONFIG_DLM_DEBUG 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=y
+CONFIG_DEBUG_FS=y
+# 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_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG 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_SECURITYFS=y
+# 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_AEAD=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_GF128MUL=m
+# 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 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=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=m
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT 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_CRC_CCITT=m
+CONFIG_CRC16=m
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_REED_SOLOMON=m
+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.33-gnu1/arch/arm/configs/bcmring_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/bcmring_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/bcmring_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/bcmring_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,13 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc3
-# Fri Jul 17 12:07:28 2009
+# Linux kernel version: 2.6.34-rc2
+# Mon Mar 29 12:01:41 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
+CONFIG_HAVE_PROC_CPU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,6 +18,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -32,6 +33,12 @@ CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -43,21 +50,22 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG 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 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
@@ -75,19 +83,21 @@ CONFIG_FUTEX=y
 # CONFIG_EVENTFD is not set
 CONFIG_SHMEM=y
 # CONFIG_AIO is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
+CONFIG_PERF_EVENTS=y
+CONFIG_PERF_COUNTERS=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_SLUB_DEBUG is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_COMPAT_BRK is not set
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_KPROBES=y
@@ -115,24 +125,53 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
 # System Type
 #
+CONFIG_MMU=y
 # CONFIG_ARCH_AAEC2000 is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
+CONFIG_ARCH_BCMRING=y
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
@@ -149,6 +188,7 @@ CONFIG_DEFAULT_IOSCHED="noop"
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
 # CONFIG_ARCH_KIRKWOOD is not set
 # CONFIG_ARCH_LOKI is not set
 # CONFIG_ARCH_MV78XX0 is not set
@@ -157,19 +197,26 @@ CONFIG_DEFAULT_IOSCHED="noop"
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
 # CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE 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_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_S5PV210 is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-CONFIG_ARCH_BCMRING=y
 # CONFIG_ARCH_FPGA11107 is not set
 CONFIG_ARCH_BCM11107=y
 
@@ -185,7 +232,7 @@ CONFIG_CPU_V6=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_32v6=y
 CONFIG_CPU_ABRT_EV6=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_V6=y
 CONFIG_CPU_CACHE_V6=y
 CONFIG_CPU_CACHE_VIPT=y
 CONFIG_CPU_COPY_V6=y
@@ -201,6 +248,8 @@ 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_ARM_L1_CACHE_SHIFT=5
+CONFIG_CPU_HAS_PMU=y
 # CONFIG_ARM_ERRATA_411920 is not set
 CONFIG_COMMON_CLKDEV=y
 
@@ -222,6 +271,8 @@ CONFIG_VMSPLIT_3G=y
 # CONFIG_VMSPLIT_2G is not set
 # CONFIG_VMSPLIT_1G is not set
 CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_HZ=100
 CONFIG_AEABI=y
@@ -229,6 +280,7 @@ CONFIG_AEABI=y
 # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
 # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 # CONFIG_HIGHMEM is not set
+CONFIG_HW_PERF_EVENTS=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -240,8 +292,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ALIGNMENT_TRAP=y
 CONFIG_UACCESS_WITH_MEMCPY=y
@@ -335,9 +386,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 CONFIG_MTD_CONCAT=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
@@ -433,6 +484,10 @@ CONFIG_MTD_NAND_BCM_UMI_HWCS=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
@@ -444,6 +499,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -452,6 +508,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_MD is not set
 # CONFIG_NETDEVICES is not set
 # CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
 
 #
 # Input device support
@@ -459,6 +516,7 @@ CONFIG_HAVE_IDE=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -508,6 +566,7 @@ CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -519,13 +578,17 @@ CONFIG_LEGACY_PTY_COUNT=64
 # CONFIG_TCG_TPM is not set
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -541,6 +604,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
 #
@@ -566,14 +630,17 @@ CONFIG_DUMMY_CONSOLE=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
-# CONFIG_REGULATOR is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -589,9 +656,12 @@ CONFIG_FS_POSIX_ACL=y
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 # CONFIG_FILE_LOCKING is not set
 # CONFIG_FSNOTIFY is not set
+# CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
@@ -647,6 +717,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -657,7 +728,6 @@ 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
 
 #
@@ -675,11 +745,12 @@ CONFIG_MSDOS_PARTITION=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 CONFIG_HEADERS_CHECK=y
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -693,6 +764,7 @@ CONFIG_TRACING_SUPPORT=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_ARM_UNWIND is not set
 # CONFIG_DEBUG_USER is not set
+# CONFIG_OC_ETM is not set
 
 #
 # Security options
@@ -700,7 +772,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_BINARY_PRINTF is not set
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/cm_t35_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/cm_t35_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/cm_t35_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/cm_t35_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -358,7 +358,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
-# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/devkit8000_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/devkit8000_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/devkit8000_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/devkit8000_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1889 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc6
+# Thu Feb  4 15:42:56 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+# CONFIG_RD_LZO is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+CONFIG_ARCH_OMAP2PLUS=y
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+# CONFIG_ARCH_OMAP4 is not set
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_RESET_CLOCKS is not set
+# CONFIG_OMAP_MUX is not set
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MBOX_FWK is not set
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+CONFIG_MACH_DEVKIT8000=y
+# CONFIG_MACH_OMAP_LDP is not set
+# CONFIG_MACH_OVERO is not set
+# CONFIG_MACH_OMAP3EVM is not set
+# CONFIG_MACH_OMAP3517EVM is not set
+# CONFIG_MACH_OMAP3_PANDORA is not set
+# CONFIG_MACH_OMAP3_TOUCHBOOK is not set
+# CONFIG_MACH_OMAP_3430SDP is not set
+# CONFIG_MACH_NOKIA_RX51 is not set
+# CONFIG_MACH_OMAP_ZOOM2 is not set
+# CONFIG_MACH_OMAP_ZOOM3 is not set
+# CONFIG_MACH_CM_T35 is not set
+# CONFIG_MACH_IGEP0020 is not set
+# CONFIG_MACH_OMAP_3630SDP is not set
+# CONFIG_OMAP3_EMU is not set
+# CONFIG_OMAP3_SDRC_AC_TIMING is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=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_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS2,115200n8 root=/dev/nfs nfsroot=192.168.1.1:home/nfsroot/current,home/nfsroot/current ip=dhcp rw noinitrd root  delay=3"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC 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=y
+# CONFIG_NET_KEY_MIGRATE 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=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+CONFIG_IRDA=y
+
+#
+# IrDA protocols
+#
+# CONFIG_IRLAN is not set
+# CONFIG_IRCOMM is not set
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+
+#
+# Dongle support
+#
+# 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_MCS_FIR is not set
+CONFIG_BT=y
+# CONFIG_BT_L2CAP is not set
+# CONFIG_BT_SCO is not set
+
+#
+# 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_BT_MRVL is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS 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=y
+CONFIG_MTD_ROM=y
+# 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_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_OMAP2=y
+CONFIG_MTD_NAND_OMAP_PREFETCH=y
+# CONFIG_MTD_NAND_OMAP_PREFETCH_DMA is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=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
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=40960
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=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=4
+CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN 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
+# CONFIG_INPUT_SPARSEKMAP 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_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_KEYBOARD_MATRIX=y
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_TWL4030=y
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=y
+# CONFIG_SERIO_ALTERA_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
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=256
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_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
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# 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
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+CONFIG_TWL4030_CORE=y
+CONFIG_TWL4030_POWER=y
+CONFIG_TWL4030_CODEC=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_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_MAX8660 is not set
+CONFIG_REGULATOR_TWL4030=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=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_TMIO is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_FB_OMAP_BOOTLOADER_INIT=y
+CONFIG_OMAP2_VRAM=y
+CONFIG_OMAP2_VRFB=y
+CONFIG_OMAP2_DSS=y
+CONFIG_OMAP2_VRAM_SIZE=0
+CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y
+# CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS is not set
+# CONFIG_OMAP2_DSS_RFBI is not set
+CONFIG_OMAP2_DSS_VENC=y
+# CONFIG_OMAP2_DSS_SDI is not set
+# CONFIG_OMAP2_DSS_DSI is not set
+# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
+CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
+CONFIG_FB_OMAP2=y
+CONFIG_FB_OMAP2_DEBUG_SUPPORT=y
+# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set
+CONFIG_FB_OMAP2_NUM_FBS=3
+
+#
+# OMAP2/3 Display Device Drivers
+#
+CONFIG_PANEL_GENERIC=y
+# CONFIG_PANEL_SHARP_LS037V7DW01 is not set
+CONFIG_PANEL_INNOLUX_AT070TN83=y
+# 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_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+# 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_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+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
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_OMAP_SOC=y
+CONFIG_SND_OMAP_SOC_MCBSP=y
+CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE=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_HIDRAW=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+# CONFIG_HID_DRAGONRISE is not set
+CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
+CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+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_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=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_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# OMAP 343x high speed USB support
+#
+CONFIG_USB_MUSB_HOST=y
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+# CONFIG_USB_MUSB_OTG is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+CONFIG_USB_MUSB_HDRC_HCD=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+CONFIG_USB_GADGET_OMAP=y
+CONFIG_USB_OMAP=y
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_AUDIO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_ETH_EEM=y
+CONFIG_USB_GADGETFS=m
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+CONFIG_USB_G_PRINTER=m
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_MULTI 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_USB_ULPI is not set
+CONFIG_TWL4030_USB=y
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=m
+# CONFIG_MMC_OMAP is not set
+CONFIG_MMC_OMAP_HS=y
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+CONFIG_MMC_SPI=m
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_REGULATOR is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+CONFIG_RTC_DRV_TWL4030=y
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# CBUS support
+#
+# CONFIG_CBUS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+CONFIG_QUOTA_TREE=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+CONFIG_CRAMFS=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=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=m
+CONFIG_CRC_ITU_T=m
+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_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.33-gnu1/arch/arm/configs/g3evm_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/g3evm_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/g3evm_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/g3evm_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,774 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc7
+# Mon Feb  8 12:20:01 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=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_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+CONFIG_ARCH_SHMOBILE=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_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+
+#
+# SH-Mobile System Type
+#
+CONFIG_ARCH_SH7367=y
+# CONFIG_ARCH_SH7377 is not set
+# CONFIG_ARCH_SH7372 is not set
+
+#
+# SH-Mobile Board Type
+#
+CONFIG_MACH_G3EVM=y
+
+#
+# SH-Mobile System Configuration
+#
+
+#
+# Memory configuration
+#
+CONFIG_MEMORY_START=0x50000000
+CONFIG_MEMORY_SIZE=0x08000000
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TIMER_CMT=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+# CONFIG_CPU_32v6K is not set
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_V6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+# CONFIG_ARM_ERRATA_411920 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_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySC1,115200 earlyprintk=sh-sci.1,115200"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL 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_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_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
+
+#
+# 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_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP 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_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=8
+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
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS 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_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_FSNOTIFY is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_INOTIFY_USER 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=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES 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_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/g4evm_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/g4evm_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/g4evm_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/g4evm_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,779 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc7
+# Mon Feb  8 12:21:35 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=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_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+CONFIG_ARCH_SHMOBILE=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_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+
+#
+# SH-Mobile System Type
+#
+# CONFIG_ARCH_SH7367 is not set
+CONFIG_ARCH_SH7377=y
+# CONFIG_ARCH_SH7372 is not set
+
+#
+# SH-Mobile Board Type
+#
+CONFIG_MACH_G4EVM=y
+
+#
+# SH-Mobile System Configuration
+#
+
+#
+# Memory configuration
+#
+CONFIG_MEMORY_START=0x40000000
+CONFIG_MEMORY_SIZE=0x08000000
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TIMER_CMT=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySC4,115200 earlyprintk=sh-sci.4,115200"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL 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_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_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
+
+#
+# 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_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP 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_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=8
+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
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS 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_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_FSNOTIFY is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_INOTIFY_USER 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=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES 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_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/igep0020_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/igep0020_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/igep0020_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/igep0020_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc6
-# Fri Nov 13 12:01:17 2009
+# Linux kernel version: 2.6.33-rc3
+# Thu Jan  7 16:14:55 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -46,6 +46,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -126,14 +127,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -162,6 +190,7 @@ CONFIG_MMU=y
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
 # CONFIG_ARCH_KIRKWOOD is not set
 # CONFIG_ARCH_LOKI is not set
 # CONFIG_ARCH_MV78XX0 is not set
@@ -184,6 +213,7 @@ CONFIG_MMU=y
 # CONFIG_ARCH_DAVINCI is not set
 CONFIG_ARCH_OMAP=y
 # CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
 
 #
 # TI OMAP Implementations
@@ -197,12 +227,8 @@ 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_RESET_CLOCKS=y
+# CONFIG_OMAP_MUX is not set
 CONFIG_OMAP_MCBSP=y
 # CONFIG_OMAP_MBOX_FWK is not set
 # CONFIG_OMAP_MPU_TIMER is not set
@@ -217,6 +243,7 @@ CONFIG_OMAP_LL_DEBUG_UART3=y
 CONFIG_OMAP_PM_NOOP=y
 CONFIG_ARCH_OMAP34XX=y
 CONFIG_ARCH_OMAP3430=y
+CONFIG_OMAP_PACKAGE_CBB=y
 
 #
 # OMAP Board Type
@@ -227,13 +254,16 @@ CONFIG_ARCH_OMAP3430=y
 # CONFIG_MACH_OMAP3EVM is not set
 # CONFIG_MACH_OMAP3517EVM is not set
 # CONFIG_MACH_OMAP3_PANDORA is not set
+# CONFIG_MACH_OMAP3_TOUCHBOOK is not set
 # CONFIG_MACH_OMAP_3430SDP is not set
 # CONFIG_MACH_NOKIA_RX51 is not set
 # CONFIG_MACH_OMAP_ZOOM2 is not set
-# CONFIG_MACH_CM_T35 is not set
 # CONFIG_MACH_OMAP_ZOOM3 is not set
-# CONFIG_MACH_OMAP_3630SDP is not set
+# CONFIG_MACH_CM_T35 is not set
 CONFIG_MACH_IGEP0020=y
+# CONFIG_MACH_OMAP_3630SDP is not set
+# CONFIG_OMAP3_EMU is not set
+# CONFIG_OMAP3_SDRC_AC_TIMING is not set
 
 #
 # Processor Type
@@ -305,8 +335,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 # CONFIG_LEDS is not set
@@ -440,35 +468,35 @@ CONFIG_BT_HIDP=m
 #
 # Bluetooth device drivers
 #
-CONFIG_BT_HCIBTUSB=m
+# CONFIG_BT_HCIBTUSB is not set
 # CONFIG_BT_HCIBTSDIO is not set
 CONFIG_BT_HCIUART=m
 CONFIG_BT_HCIUART_H4=y
 CONFIG_BT_HCIUART_BCSP=y
 CONFIG_BT_HCIUART_LL=y
-CONFIG_BT_HCIBCM203X=m
-CONFIG_BT_HCIBPA10X=m
-CONFIG_BT_HCIBFUSB=m
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
 CONFIG_BT_HCIVHCI=m
 CONFIG_BT_MRVL=m
 CONFIG_BT_MRVL_SDIO=m
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
-CONFIG_CFG80211=m
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_WEXT_SPY=y
+CONFIG_CFG80211=y
 # CONFIG_NL80211_TESTMODE is not set
 # CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
 # CONFIG_CFG80211_REG_DEBUG is not set
 CONFIG_CFG80211_DEFAULT_PS=y
-CONFIG_CFG80211_DEFAULT_PS_VALUE=1
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
+CONFIG_CFG80211_WEXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
-CONFIG_LIB80211=m
-CONFIG_LIB80211_CRYPT_WEP=m
-CONFIG_LIB80211_CRYPT_CCMP=m
-CONFIG_LIB80211_CRYPT_TKIP=m
+CONFIG_LIB80211=y
 # CONFIG_LIB80211_DEBUG is not set
-CONFIG_MAC80211=m
+CONFIG_MAC80211=y
 # CONFIG_MAC80211_RC_PID is not set
 CONFIG_MAC80211_RC_MINSTREL=y
 # CONFIG_MAC80211_RC_DEFAULT_PID is not set
@@ -500,12 +528,95 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND 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=y
+# 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 is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
@@ -516,7 +627,6 @@ CONFIG_BLK_DEV_RAM_SIZE=16384
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_MG_DISK is not set
 # CONFIG_MISC_DEVICES is not set
-CONFIG_EEPROM_93CX6=m
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -613,56 +723,26 @@ CONFIG_SMSC911X=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-CONFIG_WLAN_80211=y
-CONFIG_LIBERTAS=m
-CONFIG_LIBERTAS_USB=m
-CONFIG_LIBERTAS_SDIO=m
-# CONFIG_LIBERTAS_SPI is not set
-# CONFIG_LIBERTAS_DEBUG is not set
 # CONFIG_LIBERTAS_THINFIRM is not set
-CONFIG_AT76C50X_USB=m
-CONFIG_USB_ZD1201=m
-CONFIG_USB_NET_RNDIS_WLAN=m
-CONFIG_RTL8187=m
+# CONFIG_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=m
-CONFIG_P54_USB=m
-CONFIG_P54_SPI=m
-CONFIG_ATH_COMMON=m
-CONFIG_AR9170_USB=m
-CONFIG_HOSTAP=m
-CONFIG_HOSTAP_FIRMWARE=y
-CONFIG_HOSTAP_FIRMWARE_NVRAM=y
-CONFIG_B43=m
-# CONFIG_B43_SDIO is not set
-# CONFIG_B43_PHY_LP is not set
-CONFIG_B43_HWRNG=y
-# CONFIG_B43_DEBUG is not set
-CONFIG_B43LEGACY=m
-CONFIG_B43LEGACY_HWRNG=y
-# CONFIG_B43LEGACY_DEBUG is not set
-CONFIG_B43LEGACY_DMA=y
-CONFIG_B43LEGACY_PIO=y
-CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
-# CONFIG_B43LEGACY_DMA_MODE is not set
-# CONFIG_B43LEGACY_PIO_MODE is not set
-CONFIG_ZD1211RW=m
-# CONFIG_ZD1211RW_DEBUG is not set
-CONFIG_RT2X00=m
-CONFIG_RT2500USB=m
-CONFIG_RT73USB=m
-CONFIG_RT2800USB=m
-CONFIG_RT2X00_LIB_USB=m
-CONFIG_RT2X00_LIB=m
-CONFIG_RT2X00_LIB_HT=y
-CONFIG_RT2X00_LIB_FIRMWARE=y
-CONFIG_RT2X00_LIB_CRYPTO=y
-# CONFIG_RT2X00_DEBUG is not set
-CONFIG_WL12XX=m
-# CONFIG_WL1251 is not set
-# CONFIG_WL1271 is not set
+# CONFIG_ATH_COMMON is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_HOSTAP is not set
 # CONFIG_IWM is not set
+CONFIG_LIBERTAS=y
+# CONFIG_LIBERTAS_USB is not set
+CONFIG_LIBERTAS_SDIO=y
+# CONFIG_LIBERTAS_SPI is not set
+# CONFIG_LIBERTAS_DEBUG is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_WL12XX is not set
+# CONFIG_ZD1211RW is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -672,29 +752,10 @@ CONFIG_WL12XX=m
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
-CONFIG_USB_KAWETH=m
-CONFIG_USB_PEGASUS=m
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
-CONFIG_USB_USBNET=m
-CONFIG_USB_NET_AX8817X=m
-CONFIG_USB_NET_CDCETHER=m
-CONFIG_USB_NET_CDC_EEM=m
-CONFIG_USB_NET_DM9601=m
-CONFIG_USB_NET_SMSC95XX=m
-CONFIG_USB_NET_GL620A=m
-CONFIG_USB_NET_NET1080=m
-CONFIG_USB_NET_PLUSB=m
-CONFIG_USB_NET_MCS7830=m
-CONFIG_USB_NET_RNDIS_HOST=m
-CONFIG_USB_NET_CDC_SUBSET=m
-# CONFIG_USB_ALI_M5632 is not set
-# CONFIG_USB_AN2720 is not set
-CONFIG_USB_BELKIN=y
-CONFIG_USB_ARMLINUX=y
-# CONFIG_USB_EPSON2888 is not set
-# CONFIG_USB_KC2190 is not set
-CONFIG_USB_NET_ZAURUS=m
-# CONFIG_USB_NET_INT51X1 is not set
+# CONFIG_USB_USBNET is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -710,6 +771,7 @@ CONFIG_USB_NET_ZAURUS=m
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -809,7 +871,6 @@ CONFIG_I2C_OMAP=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -825,6 +886,8 @@ CONFIG_SPI_MASTER=y
 # CONFIG_SPI_BITBANG is not set
 # CONFIG_SPI_GPIO is not set
 CONFIG_SPI_OMAP24XX=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -892,7 +955,7 @@ CONFIG_SSB_SDIOHOST_POSSIBLE=y
 #
 # Multifunction device drivers
 #
-# CONFIG_MFD_CORE is not set
+CONFIG_MFD_CORE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_ASIC3 is not set
 # CONFIG_HTC_EGPIO is not set
@@ -900,11 +963,13 @@ CONFIG_SSB_SDIOHOST_POSSIBLE=y
 # CONFIG_TPS65010 is not set
 CONFIG_TWL4030_CORE=y
 # CONFIG_TWL4030_POWER is not set
+CONFIG_TWL4030_CODEC=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_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
@@ -912,6 +977,8 @@ CONFIG_TWL4030_CORE=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
 CONFIG_REGULATOR=y
 # CONFIG_REGULATOR_DEBUG is not set
 # CONFIG_REGULATOR_FIXED_VOLTAGE is not set
@@ -919,6 +986,7 @@ CONFIG_REGULATOR=y
 # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
 # CONFIG_REGULATOR_BQ24022 is not set
 # CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_MAX8660 is not set
 CONFIG_REGULATOR_TWL4030=y
 # CONFIG_REGULATOR_LP3971 is not set
 # CONFIG_REGULATOR_TPS65023 is not set
@@ -930,65 +998,129 @@ CONFIG_REGULATOR_TWL4030=y
 #
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT 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=y
+# CONFIG_FB_TILEBLITTING is not set
 
 #
-# Display device support
+# Frame buffer hardware drivers
 #
-# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_TMIO is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
+CONFIG_OMAP2_VRAM=y
+CONFIG_OMAP2_VRFB=y
+CONFIG_OMAP2_DSS=y
+CONFIG_OMAP2_VRAM_SIZE=14
+# CONFIG_OMAP2_DSS_DEBUG_SUPPORT is not set
+# CONFIG_OMAP2_DSS_RFBI is not set
+# CONFIG_OMAP2_DSS_VENC is not set
+# CONFIG_OMAP2_DSS_SDI is not set
+CONFIG_OMAP2_DSS_DSI=y
+CONFIG_OMAP2_DSS_USE_DSI_PLL=y
+# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
+CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
+CONFIG_FB_OMAP2=y
+# CONFIG_FB_OMAP2_DEBUG_SUPPORT is not set
+# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set
+CONFIG_FB_OMAP2_NUM_FBS=3
 
 #
-# Console display driver support
+# OMAP2/3 Display Device Drivers
 #
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_SOUND is not set
-CONFIG_HID_SUPPORT=y
-CONFIG_HID=y
-# CONFIG_HIDRAW is not set
+CONFIG_PANEL_GENERIC=y
+# CONFIG_PANEL_SHARP_LS037V7DW01 is not set
+# CONFIG_PANEL_TAAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# USB Input Devices
+# Display device support
 #
-CONFIG_USB_HID=y
-# CONFIG_HID_PID is not set
-# CONFIG_USB_HIDDEV is not set
+CONFIG_DISPLAY_SUPPORT=y
 
 #
-# Special HID drivers
+# Display hardware drivers
 #
-# CONFIG_HID_A4TECH is not set
-# CONFIG_HID_APPLE is not set
-# CONFIG_HID_BELKIN is not set
-# CONFIG_HID_CHERRY is not set
-# CONFIG_HID_CHICONY is not set
-# CONFIG_HID_CYPRESS is not set
-# CONFIG_HID_DRAGONRISE is not set
-# CONFIG_HID_EZKEY is not set
-# CONFIG_HID_KYE is not set
-# CONFIG_HID_GYRATION is not set
-# CONFIG_HID_TWINHAN is not set
-# CONFIG_HID_KENSINGTON is not set
-# CONFIG_HID_LOGITECH is not set
-# CONFIG_HID_MICROSOFT is not set
-# CONFIG_HID_MONTEREY is not set
-# CONFIG_HID_NTRIG is not set
-# CONFIG_HID_PANTHERLORD is not set
-# CONFIG_HID_PETALYNX is not set
-# CONFIG_HID_SAMSUNG is not set
-# CONFIG_HID_SONY is not set
-# CONFIG_HID_SUNPLUS is not set
-# CONFIG_HID_GREENASIA is not set
-# CONFIG_HID_SMARTJOYPLUS is not set
-# CONFIG_HID_TOPSEED is not set
-# CONFIG_HID_THRUSTMASTER is not set
-# CONFIG_HID_WACOM is not set
-# CONFIG_HID_ZEROPLUS is not set
+
+#
+# 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
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+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
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_OMAP_SOC=y
+CONFIG_SND_OMAP_SOC_MCBSP=y
+CONFIG_SND_OMAP_SOC_IGEP0020=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 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_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
@@ -997,12 +1129,12 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 # Miscellaneous USB options
 #
 # CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_DEVICE_CLASS 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=m
+# CONFIG_USB_MON is not set
 # CONFIG_USB_WUSB is not set
 # CONFIG_USB_WUSB_CBAF is not set
 
@@ -1010,29 +1142,21 @@ CONFIG_USB_MON=m
 # 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_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
 # CONFIG_USB_ISP1362_HCD is not set
-# CONFIG_USB_OHCI_HCD is not set
+CONFIG_USB_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=y
-CONFIG_USB_MUSB_SOC=y
-
-#
-# OMAP 343x high speed USB support
-#
-CONFIG_USB_MUSB_HOST=y
-# CONFIG_USB_MUSB_PERIPHERAL is not set
-# CONFIG_USB_MUSB_OTG is not set
-# CONFIG_USB_GADGET_MUSB_HDRC is not set
-CONFIG_USB_MUSB_HDRC_HCD=y
-# CONFIG_MUSB_PIO_ONLY is not set
-CONFIG_USB_INVENTRA_DMA=y
-# CONFIG_USB_TI_CPPI_DMA is not set
-# CONFIG_USB_MUSB_DEBUG is not set
+# CONFIG_USB_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
@@ -1049,19 +1173,7 @@ CONFIG_USB_INVENTRA_DMA=y
 #
 # 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_STORAGE is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
@@ -1099,41 +1211,7 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
-CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_DEBUG=y
-CONFIG_USB_GADGET_DEBUG_FILES=y
-CONFIG_USB_GADGET_VBUS_DRAW=2
-CONFIG_USB_GADGET_SELECTED=y
-# CONFIG_USB_GADGET_AT91 is not set
-# CONFIG_USB_GADGET_ATMEL_USBA is not set
-# CONFIG_USB_GADGET_FSL_USB2 is not set
-# CONFIG_USB_GADGET_LH7A40X is not set
-CONFIG_USB_GADGET_OMAP=y
-CONFIG_USB_OMAP=y
-# CONFIG_USB_GADGET_PXA25X is not set
-# CONFIG_USB_GADGET_R8A66597 is not set
-# CONFIG_USB_GADGET_PXA27X is not set
-# CONFIG_USB_GADGET_S3C_HSOTG is not set
-# CONFIG_USB_GADGET_IMX is not set
-# CONFIG_USB_GADGET_S3C2410 is not set
-# CONFIG_USB_GADGET_M66592 is not set
-# CONFIG_USB_GADGET_AMD5536UDC is not set
-# CONFIG_USB_GADGET_FSL_QE is not set
-# CONFIG_USB_GADGET_CI13XXX is not set
-# CONFIG_USB_GADGET_NET2280 is not set
-# CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_LANGWELL is not set
-# CONFIG_USB_GADGET_DUMMY_HCD is not set
-# CONFIG_USB_GADGET_DUALSPEED is not set
-CONFIG_USB_ZERO=m
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_ETH is not set
-# CONFIG_USB_GADGETFS is not set
-# CONFIG_USB_FILE_STORAGE is not set
-# CONFIG_USB_G_SERIAL is not set
-# CONFIG_USB_MIDI_GADGET is not set
-# CONFIG_USB_G_PRINTER is not set
-# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_GADGET is not set
 
 #
 # OTG and related infrastructure
@@ -1141,10 +1219,11 @@ CONFIG_USB_ZERO=m
 CONFIG_USB_OTG_UTILS=y
 # CONFIG_USB_GPIO_VBUS is not set
 # CONFIG_ISP1301_OMAP is not set
-CONFIG_TWL4030_USB=y
+# CONFIG_USB_ULPI is not set
+# CONFIG_TWL4030_USB is not set
 # CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
-# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_DEBUG=y
 # CONFIG_MMC_UNSAFE_RESUME is not set
 
 #
@@ -1158,7 +1237,8 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 #
 # MMC/SD/SDIO Host Controller Drivers
 #
-# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_PLTFM is not set
 # CONFIG_MMC_OMAP is not set
 CONFIG_MMC_OMAP_HS=y
 # CONFIG_MMC_AT91 is not set
@@ -1179,6 +1259,11 @@ CONFIG_RTC_LIB=y
 # CONFIG_STAGING is not set
 
 #
+# CBUS support
+#
+# CONFIG_CBUS is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1253,6 +1338,7 @@ 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_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1401,6 +1487,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_TRACING_SUPPORT=y
@@ -1425,7 +1512,9 @@ CONFIG_ARM_UNWIND=y
 # CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_LL=y
+# CONFIG_EARLY_PRINTK is not set
 # CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
 
 #
 # Security options
@@ -1433,7 +1522,11 @@ 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_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/imote2_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/imote2_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/imote2_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/imote2_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,2039 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.34-rc2
+# Thu Apr  8 14:49:08 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_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=y
+CONFIG_RD_LZMA=y
+# CONFIG_RD_LZO 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_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_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+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_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_SLOW_WORK_DEBUG is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF 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_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE 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_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+
+#
+# Intel/Marvell Dev Platforms (sorted by hardware release time)
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_MACH_ZYLONITE300 is not set
+# CONFIG_MACH_ZYLONITE320 is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
+
+#
+# Third Party Dev Platforms (sorted by vendor name)
+#
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_ARCH_VIPER is not set
+# CONFIG_MACH_ARCOM_ZEUS is not set
+# CONFIG_MACH_BALLOON3 is not set
+# CONFIG_MACH_CSB726 is not set
+# CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_EXEDA is not set
+# CONFIG_MACH_CM_X300 is not set
+# CONFIG_MACH_CAPC7117 is not set
+# CONFIG_ARCH_GUMSTIX is not set
+CONFIG_MACH_INTELMOTE2=y
+# CONFIG_MACH_STARGATE2 is not set
+# CONFIG_MACH_XCEP is not set
+# CONFIG_TRIZEPS_PXA is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_MACH_COLIBRI is not set
+# CONFIG_MACH_COLIBRI300 is not set
+# CONFIG_MACH_COLIBRI320 is not set
+
+#
+# End-user Products (sorted by vendor name)
+#
+# CONFIG_MACH_H4700 is not set
+# CONFIG_MACH_H5000 is not set
+# CONFIG_MACH_HIMALAYA is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_PXA_EZX is not set
+# CONFIG_MACH_MP900C is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_MACH_RAUMFELD_RC is not set
+# CONFIG_MACH_RAUMFELD_CONNECTOR is not set
+# CONFIG_MACH_RAUMFELD_SPEAKER is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_MACH_ICONTROL is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+CONFIG_PXA27x=y
+CONFIG_PXA_SSP=y
+CONFIG_PXA_HAVE_BOARD_IRQS=y
+CONFIG_PLAT_PXA=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_IWMMXT=y
+CONFIG_XSCALE_PMU=y
+CONFIG_CPU_HAS_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=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=jffs2 console=ttyS2,115200 mem=32M"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_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=m
+CONFIG_BINFMT_MISC=m
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_APM_EMULATION=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
+# CONFIG_NET_KEY 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=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+# CONFIG_INET_XFRM_MODE_TRANSPORT 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=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+CONFIG_BRIDGE_NETFILTER=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 is not set
+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 is not set
+# CONFIG_NETFILTER_XT_TARGET_CT is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_HL=m
+CONFIG_NETFILTER_XT_TARGET_LED=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+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 is not set
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_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_GRE=m
+CONFIG_NF_NAT_PROTO_UDPLITE=m
+CONFIG_NF_NAT_PROTO_SCTP=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_NF_NAT_SIP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+# CONFIG_BRIDGE_NF_EBTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_STP=m
+CONFIG_BRIDGE=m
+# CONFIG_BRIDGE_IGMP_SNOOPING is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+CONFIG_IEEE802154=y
+# 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_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_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=m
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_AFS_PARTS=y
+CONFIG_MTD_AR7_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_HAVE_MTD_OTP=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# 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=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
+# 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_PXA2XX=y
+# 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_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# CONFIG_BLK_DEV_DRBD is not set
+CONFIG_BLK_DEV_NBD=m
+# 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_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# 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=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_NET_ETHERNET is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# 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_IEEE802154_DRIVERS=y
+# CONFIG_IEEE802154_FAKEHARD 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 is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP 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
+# CONFIG_INPUT_APMPOWER is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+CONFIG_KEYBOARD_PXA27x=y
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+CONFIG_TOUCHSCREEN_DA9034=y
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=y
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER 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_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=8
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PXA=y
+# CONFIG_I2C_PXA_SLAVE is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX 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
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS 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
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_APM_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_DA9030 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_HTC_I2CPLD 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_AB4500_CORE is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+# CONFIG_REGULATOR_DUMMY is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
+CONFIG_REGULATOR_USERSPACE_CONSUMER=y
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_MAX8649 is not set
+# CONFIG_REGULATOR_MAX8660 is not set
+CONFIG_REGULATOR_DA903X=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# 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_IR_CORE=y
+CONFIG_VIDEO_IR=y
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+CONFIG_MEDIA_TUNER_CUSTOMISE=y
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_MC44S803 is not set
+CONFIG_MEDIA_TUNER_MAX2165=m
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_SG=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+CONFIG_VIDEO_IR_I2C=y
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TDA9875 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_M52790 is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+
+#
+# RDS decoders
+#
+# CONFIG_VIDEO_SAA6588 is not set
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_ADV7180 is not set
+# CONFIG_VIDEO_BT819 is not set
+# CONFIG_VIDEO_BT856 is not set
+# CONFIG_VIDEO_BT866 is not set
+# CONFIG_VIDEO_KS0127 is not set
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_MT9V011 is not set
+# CONFIG_VIDEO_TCM825X is not set
+# CONFIG_VIDEO_SAA7110 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_SAA7191 is not set
+# CONFIG_VIDEO_TVP514X is not set
+# CONFIG_VIDEO_TVP5150 is not set
+# CONFIG_VIDEO_TVP7002 is not set
+# CONFIG_VIDEO_VPX3220 is not set
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_CX25840 is not set
+
+#
+# MPEG video encoders
+#
+# CONFIG_VIDEO_CX2341X is not set
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_SAA7185 is not set
+# CONFIG_VIDEO_ADV7170 is not set
+# CONFIG_VIDEO_ADV7175 is not set
+# CONFIG_VIDEO_THS7303 is not set
+# CONFIG_VIDEO_ADV7343 is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+CONFIG_SOC_CAMERA=y
+# CONFIG_SOC_CAMERA_MT9M001 is not set
+CONFIG_SOC_CAMERA_MT9M111=y
+# CONFIG_SOC_CAMERA_MT9T031 is not set
+# CONFIG_SOC_CAMERA_MT9T112 is not set
+# CONFIG_SOC_CAMERA_MT9V022 is not set
+# CONFIG_SOC_CAMERA_RJ54N1 is not set
+# CONFIG_SOC_CAMERA_TW9910 is not set
+# CONFIG_SOC_CAMERA_PLATFORM is not set
+# CONFIG_SOC_CAMERA_OV772X is not set
+# CONFIG_SOC_CAMERA_OV9640 is not set
+CONFIG_VIDEO_PXA27x=y
+# 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_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_PXA=y
+CONFIG_FB_PXA_OVERLAY=y
+# CONFIG_FB_PXA_SMARTPANEL is not set
+CONFIG_FB_PXA_PARAMETERS=y
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_W100 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+# CONFIG_BACKLIGHT_DA903X 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 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+CONFIG_FONT_MINI_4x6=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+CONFIG_SND_PXA2XX_LIB=y
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_PXA2XX_SOC=y
+# CONFIG_SND_PXA2XX_SOC_IMOTE2 is not set
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID 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_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 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_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+# 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_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_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=y
+# CONFIG_USB_ETH_RNDIS is not set
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
+# CONFIG_USB_G_MULTI is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_SDIO_UART=m
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_PXA=y
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_SPI=y
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+CONFIG_LEDS_LP3944=y
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DA903X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_REGULATOR is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+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_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_SA1100 is not set
+CONFIG_RTC_DRV_PXA=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=m
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=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=y
+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_LOGFS is not set
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=m
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+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=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+# CONFIG_CIFS_STATS2 is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+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
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_LOCK_ALLOC=y
+CONFIG_PROVE_LOCKING=y
+# CONFIG_PROVE_RCU is not set
+CONFIG_LOCKDEP=y
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_LOCKDEP is not set
+CONFIG_TRACE_IRQFLAGS=y
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_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
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_PCOMP=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_WORKQUEUE=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# 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=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_GHASH=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+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=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+# CONFIG_CRYPTO_SALSA20 is not set
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/kirkwood_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/kirkwood_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/kirkwood_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/kirkwood_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc6
-# Sat Nov  7 20:31:18 2009
+# Linux kernel version: 2.6.33-rc6
+# Thu Feb  4 23:08:54 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -32,6 +32,12 @@ CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -45,6 +51,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -127,14 +134,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -163,6 +197,7 @@ CONFIG_MMU=y
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
 CONFIG_ARCH_KIRKWOOD=y
 # CONFIG_ARCH_LOKI is not set
 # CONFIG_ARCH_MV78XX0 is not set
@@ -185,6 +220,7 @@ CONFIG_ARCH_KIRKWOOD=y
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
 # CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
 
 #
 # Marvell Kirkwood Implementations
@@ -195,7 +231,11 @@ CONFIG_MACH_RD88F6281=y
 CONFIG_MACH_MV88F6281GTW_GE=y
 CONFIG_MACH_SHEEVAPLUG=y
 CONFIG_MACH_TS219=y
+CONFIG_MACH_TS41X=y
+CONFIG_MACH_OPENRD=y
 CONFIG_MACH_OPENRD_BASE=y
+CONFIG_MACH_OPENRD_CLIENT=y
+CONFIG_MACH_NETSPACE_V2=y
 CONFIG_PLAT_ORION=y
 
 #
@@ -262,12 +302,10 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ALIGNMENT_TRAP=y
@@ -398,15 +436,18 @@ CONFIG_NET_PKTGEN=m
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_WEXT_SPY=y
 CONFIG_CFG80211=y
 # CONFIG_NL80211_TESTMODE is not set
 # CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
 # CONFIG_CFG80211_REG_DEBUG is not set
 CONFIG_CFG80211_DEFAULT_PS=y
-CONFIG_CFG80211_DEFAULT_PS_VALUE=1
 # CONFIG_CFG80211_DEBUGFS is not set
 CONFIG_WIRELESS_OLD_REGULATORY=y
-CONFIG_WIRELESS_EXT=y
+CONFIG_CFG80211_WEXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 CONFIG_LIB80211=y
 # CONFIG_LIB80211_DEBUG is not set
@@ -556,6 +597,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -606,7 +651,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -642,6 +689,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -696,15 +744,16 @@ CONFIG_SATA_MV=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_SCH is not set
@@ -720,7 +769,7 @@ CONFIG_SATA_MV=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -828,13 +877,6 @@ CONFIG_MV643XX_ETH=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-CONFIG_WLAN_80211=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
@@ -846,19 +888,24 @@ CONFIG_LIBERTAS_SDIO=y
 # CONFIG_ADM8211 is not set
 # CONFIG_MAC80211_HWSIM is not set
 # CONFIG_MWL8K is not set
-# CONFIG_P54_COMMON is not set
 # CONFIG_ATH_COMMON is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_HOSTAP is not set
 # CONFIG_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_IWM is not set
+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_HERMES is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_RT2X00 is not set
 # CONFIG_WL12XX is not set
-# CONFIG_IWM is not set
+# CONFIG_ZD1211RW is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -881,6 +928,7 @@ CONFIG_LIBERTAS_SDIO=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -890,6 +938,7 @@ CONFIG_LIBERTAS_SDIO=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -933,6 +982,7 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_PCIPS2 is not set
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -1019,11 +1069,6 @@ CONFIG_I2C_MV64XXX=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -1032,7 +1077,6 @@ CONFIG_I2C_MV64XXX=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1048,6 +1092,8 @@ CONFIG_SPI_MASTER=y
 # CONFIG_SPI_BITBANG is not set
 # CONFIG_SPI_GPIO is not set
 CONFIG_SPI_ORION=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -1074,10 +1120,12 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1116,6 +1164,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_TC6393XB is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
@@ -1123,6 +1172,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1305,6 +1356,7 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
 # OTG and related infrastructure
 #
 # CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
 # CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_UWB is not set
 CONFIG_MMC=y
@@ -1344,6 +1396,7 @@ CONFIG_LEDS_GPIO_PLATFORM=y
 # CONFIG_LEDS_PCA955X is not set
 # CONFIG_LEDS_DAC124S085 is not set
 # CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
 
 #
 # LED Triggers
@@ -1388,6 +1441,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 CONFIG_RTC_DRV_S35390A=y
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1417,7 +1471,9 @@ CONFIG_RTC_DRV_S35390A=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1684,7 +1740,9 @@ CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_LL=y
+# CONFIG_EARLY_PRINTK is not set
 # CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
 
 #
 # Security options
@@ -1692,7 +1750,11 @@ 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_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/mini2440_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/mini2440_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/mini2440_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/mini2440_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -184,7 +184,7 @@ CONFIG_S3C24XX_PWM=y
 CONFIG_S3C24XX_GPIO_EXTRA=0
 CONFIG_S3C2410_DMA=y
 # CONFIG_S3C2410_DMA_DEBUG is not set
-CONFIG_S3C24XX_ADC=y
+CONFIG_S3C_ADC=y
 CONFIG_PLAT_S3C=y
 CONFIG_CPU_LLSERIAL_S3C2440_ONLY=y
 CONFIG_CPU_LLSERIAL_S3C2440=y
@@ -199,8 +199,8 @@ CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
 #
 # Power management
 #
-# CONFIG_S3C2410_PM_DEBUG is not set
-# CONFIG_S3C2410_PM_CHECK is not set
+# CONFIG_SAMSUNG_PM_DEBUG is not set
+# CONFIG_SAMSUNG_PM_CHECK is not set
 CONFIG_S3C_LOWLEVEL_UART_PORT=0
 CONFIG_S3C_GPIO_SPACE=0
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/mmp2_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/mmp2_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/mmp2_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/mmp2_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1194 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc2
+# Tue Jan  5 13:55:22 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# 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 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+CONFIG_ARCH_MMP=y
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_MACH_TAVOREVB is not set
+
+#
+# Marvell PXA168/910/MMP2 Implmentations
+#
+# CONFIG_MACH_ASPENITE is not set
+# CONFIG_MACH_ZYLONITE2 is not set
+# CONFIG_MACH_TTC_DKB is not set
+CONFIG_MACH_FLINT=y
+CONFIG_CPU_MMP2=y
+CONFIG_PLAT_PXA=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_V6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+# CONFIG_ARM_ERRATA_411920 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 is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on console=ttyS0,115200 mem=128M user_debug=255"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP 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_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+# CONFIG_DEVTMPFS is not set
+# 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=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+# CONFIG_MTD_CHAR is not set
+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_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_PXA3xx is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+CONFIG_MTD_ONENAND=y
+# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
+CONFIG_MTD_ONENAND_GENERIC=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 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_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_HOSTAP 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
+# CONFIG_INPUT_SPARSEKMAP 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=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PXA=y
+# CONFIG_I2C_PXA_SLAVE is not set
+# CONFIG_I2C_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_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+CONFIG_MFD_CORE=y
+# 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+CONFIG_MFD_88PM8607=y
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+CONFIG_REGULATOR_MAX8660=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+CONFIG_REGULATOR_88PM8607=y
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=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_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
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# 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_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=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_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED 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_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_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_EARLY_PRINTK is not set
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=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
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C 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.33-gnu1/arch/arm/configs/mv78xx0_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/mv78xx0_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/mv78xx0_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/mv78xx0_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -176,6 +176,7 @@ CONFIG_ARCH_MV78XX0=y
 #
 CONFIG_MACH_DB78X00_BP=y
 CONFIG_MACH_RD78X00_MASA=y
+CONFIG_MACH_TERASTATION_WXL=y
 CONFIG_PLAT_ORION=y
 
 #
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/mx1ads_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/mx1ads_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/mx1ads_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/mx1ads_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,742 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 02:15:46 2005
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=y
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_EMBEDDED=y
-# CONFIG_KALLSYMS is not set
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# 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_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_L7200 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_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-CONFIG_ARCH_IMX=y
-# CONFIG_ARCH_H720X is not set
-
-#
-# IMX Implementations
-#
-CONFIG_ARCH_MX1ADS=y
-
-#
-# Processor Type
-#
-CONFIG_CPU_ARM920T=y
-CONFIG_CPU_32v4=y
-CONFIG_CPU_ABRT_EV4T=y
-CONFIG_CPU_CACHE_V4WT=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_TLB_V4WBI=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
-
-#
-# Bus support
-#
-CONFIG_ISA=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-CONFIG_PREEMPT=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=ttySMX0,57600n8 ip=bootp root=/dev/nfs"
-# CONFIG_XIP_KERNEL 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=y
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_ARTHUR is not set
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL 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=y
-# CONFIG_MTD_ABSENT is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS 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_BLKMTD is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV 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=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_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_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# 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_NET_VENDOR_RACAL 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_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-CONFIG_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=y
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=y
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ISDN subsystem
-#
-# 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
-CONFIG_SOUND_GAMEPORT=y
-
-#
-# Character devices
-#
-# CONFIG_VT is not set
-# 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
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-CONFIG_RTC=m
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_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 is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=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=y
-# CONFIG_TMPFS_XATTR is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# 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_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-CONFIG_CRAMFS=y
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_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_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
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_DEBUG_FS is not set
-CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-CONFIG_CRC_CCITT=y
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/mx27_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/mx27_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/mx27_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/mx27_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -200,7 +200,7 @@ CONFIG_MACH_MX27ADS=y
 CONFIG_MACH_PCM038=y
 CONFIG_MACH_PCM970_BASEBOARD=y
 CONFIG_MACH_MX27_3DS=y
-CONFIG_MACH_MX27LITE=y
+CONFIG_MACH_IMX27LITE=y
 CONFIG_MXC_IRQ_PRIOR=y
 CONFIG_MXC_PWM=y
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/mx51_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/mx51_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/mx51_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/mx51_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1286 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc6
+# Tue Feb  2 15:20:48 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=18
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB_DEBUG 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_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+# CONFIG_LBDAF 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_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+CONFIG_ARCH_MXC=y
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+# CONFIG_ARCH_MX2 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MXC91231 is not set
+CONFIG_ARCH_MX5=y
+CONFIG_ARCH_MX51=y
+
+#
+# MX5 platforms:
+#
+CONFIG_MACH_MX51_BABBAGE=y
+# CONFIG_MXC_IRQ_PRIOR is not set
+CONFIG_MXC_TZIC=y
+# CONFIG_MXC_PWM is not set
+CONFIG_ARCH_MXC_IOMUX_V3=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.0.101:/shared/nfs ip=dhcp"
+# 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=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=m
+
+#
+# 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=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+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=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD 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=65536
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+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 is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_SATA_PMP=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_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=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_FIXED_PHY=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_GPIO=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# 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_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+CONFIG_FEC=y
+# CONFIG_FEC2 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+CONFIG_MOUSE_PS2_ELANTECH=y
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK 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=m
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_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=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_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=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=m
+# CONFIG_I2C_HELPER_AUTO is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_IMX is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=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_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_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=y
+# 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=m
+# CONFIG_MMC_SDHCI_PLTFM is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_MXC is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS 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=y
+# 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_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_MXC is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTACTL=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=m
+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 is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+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=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=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_DETECT_SOFTLOCKUP 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
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
+# CONFIG_SECURITY is not set
+CONFIG_SECURITYFS=y
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# 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_RATIONAL=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/n770_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/n770_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/n770_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/n770_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -308,6 +308,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND_UP_POSSIBLE=y
 CONFIG_SUSPEND=y
 # CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 
 #
 # Networking
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/n8x0_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/n8x0_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/n8x0_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/n8x0_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -191,6 +191,7 @@ CONFIG_ARCH_OMAP=y
 #
 CONFIG_ARCH_OMAP_OTG=y
 # CONFIG_ARCH_OMAP1 is not set
+CONFIG_ARCH_OMAP2PLUS=y
 CONFIG_ARCH_OMAP2=y
 # CONFIG_ARCH_OMAP3 is not set
 # CONFIG_ARCH_OMAP4 is not set
@@ -198,8 +199,6 @@ CONFIG_ARCH_OMAP2=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 is not set
 # CONFIG_OMAP_MCBSP is not set
@@ -208,15 +207,13 @@ CONFIG_OMAP_MBOX_FWK=y
 CONFIG_OMAP_32K_TIMER=y
 CONFIG_OMAP_32K_TIMER_HZ=128
 CONFIG_OMAP_DM_TIMER=y
-# CONFIG_OMAP_LL_DEBUG_UART1 is not set
-# CONFIG_OMAP_LL_DEBUG_UART2 is not set
-CONFIG_OMAP_LL_DEBUG_UART3=y
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
 # CONFIG_MACH_OMAP_GENERIC is not set
 
 #
 # OMAP Core Type
 #
-CONFIG_ARCH_OMAP24XX=y
 CONFIG_ARCH_OMAP2420=y
 # CONFIG_ARCH_OMAP2430 is not set
 
@@ -227,6 +224,9 @@ CONFIG_MACH_OMAP2_TUSB6010=y
 # CONFIG_MACH_OMAP_H4 is not set
 # CONFIG_MACH_OMAP_APOLLON is not set
 # CONFIG_MACH_OMAP_2430SDP is not set
+CONFIG_MACH_NOKIA_N800=y
+CONFIG_MACH_NOKIA_N810=y
+CONFIG_MACH_NOKIA_N810_WIMAX=y
 CONFIG_MACH_NOKIA_N8X0=y
 
 #
@@ -303,7 +303,7 @@ CONFIG_ALIGNMENT_TRAP=y
 CONFIG_ZBOOT_ROM_TEXT=0x10C08000
 CONFIG_ZBOOT_ROM_BSS=0x10200000
 # CONFIG_ZBOOT_ROM is not set
-CONFIG_CMDLINE="root=1f03 rootfstype=jffs2 console=ttyS2,115200n8"
+CONFIG_CMDLINE="root=/dev/mmcblk0p2 console=ttyS2,115200n8 debug earlyprintk rootwait"
 # CONFIG_XIP_KERNEL is not set
 # CONFIG_KEXEC is not set
 
@@ -337,7 +337,14 @@ CONFIG_HAVE_AOUT=y
 #
 # Power management options
 #
-# CONFIG_PM is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -617,7 +624,55 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+# CONFIG_I2C_CHARDEV is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+# 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_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX 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_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
@@ -673,15 +728,44 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_HTC_I2CPLD is not set
+# CONFIG_TPS65010 is not set
+CONFIG_MENELAUS=y
+# CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_T7L66XB is not set
 # CONFIG_MFD_TC6387XB is not set
 # CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_AB4500_CORE is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_DUMMY is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_MAX8649 is not set
+# CONFIG_REGULATOR_MAX8660 is not set
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
 #
@@ -718,7 +802,10 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_DEVICEFS=y
 CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_OTG is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
 # CONFIG_USB_MON is not set
 # CONFIG_USB_WUSB is not set
 # CONFIG_USB_WUSB_CBAF is not set
@@ -737,9 +824,10 @@ CONFIG_USB_DEVICE_CLASS=y
 CONFIG_USB_MUSB_HDRC=y
 CONFIG_USB_TUSB6010=y
 # CONFIG_USB_MUSB_HOST is not set
-CONFIG_USB_MUSB_PERIPHERAL=y
-# CONFIG_USB_MUSB_OTG 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 is not set
 # CONFIG_USB_TI_CPPI_DMA is not set
@@ -824,44 +912,77 @@ CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_ZERO is not set
 # CONFIG_USB_AUDIO is not set
 CONFIG_USB_ETH=y
-# CONFIG_USB_ETH_RNDIS is not set
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_ETH_EEM=y
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
 # CONFIG_USB_G_SERIAL is not set
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
+# CONFIG_USB_G_MULTI 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_USB_ULPI is not set
 CONFIG_NOP_USB_XCEIV=y
-# 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_MMC_OMAP=y
+# CONFIG_MMC_SPI is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
-# CONFIG_REGULATOR is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
-# CONFIG_EXT3_FS is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
@@ -886,8 +1007,11 @@ CONFIG_INOTIFY_USER=y
 #
 # DOS/FAT/NT Filesystems
 #
+CONFIG_FAT_FS=y
 # CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
@@ -934,7 +1058,6 @@ CONFIG_JFFS2_CMODE_PRIORITY=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/nuc950_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/nuc950_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/nuc950_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/nuc950_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -590,8 +590,40 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT 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_NUC900=y
+CONFIG_GPM1040A0_320X240=y
+CONFIG_FB_NUC900_DEBUG=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
@@ -603,6 +635,25 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+# 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=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
 # CONFIG_SOUND is not set
 # CONFIG_HID_SUPPORT is not set
 CONFIG_USB_SUPPORT=y
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/omap_3430sdp_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/omap_3430sdp_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/omap_3430sdp_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/omap_3430sdp_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -363,6 +363,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/omap_3630sdp_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/omap_3630sdp_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/omap_3630sdp_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/omap_3630sdp_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -361,7 +361,7 @@ CONFIG_SUSPEND=y
 # CONFIG_PM_TEST_SUSPEND is not set
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
-# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_beagle_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/omap3_beagle_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_beagle_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/omap3_beagle_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -324,6 +324,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/omap3_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/omap3_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc8
-# Tue Dec  1 14:04:02 2009
+# Linux kernel version: 2.6.33-rc5
+# Tue Jan 26 11:05:31 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -20,6 +20,8 @@ CONFIG_ARCH_HAS_CPUFREQ=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_OPROFILE_ARMV6=y
+CONFIG_OPROFILE_ARM11_CORE=y
 CONFIG_OPROFILE_ARMV7=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -33,6 +35,12 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -48,6 +56,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -69,6 +78,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -133,14 +143,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -169,6 +206,7 @@ CONFIG_MMU=y
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
 # CONFIG_ARCH_KIRKWOOD is not set
 # CONFIG_ARCH_LOKI is not set
 # CONFIG_ARCH_MV78XX0 is not set
@@ -191,21 +229,23 @@ CONFIG_MMU=y
 # CONFIG_ARCH_DAVINCI is not set
 CONFIG_ARCH_OMAP=y
 # CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 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_OMAP2PLUS=y
+CONFIG_ARCH_OMAP2=y
 CONFIG_ARCH_OMAP3=y
-# CONFIG_ARCH_OMAP4 is not set
+CONFIG_ARCH_OMAP4=y
 
 #
 # OMAP Feature Selections
 #
-# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
-# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+CONFIG_OMAP_DEBUG_DEVICES=y
+CONFIG_OMAP_DEBUG_LEDS=y
 CONFIG_OMAP_RESET_CLOCKS=y
 CONFIG_OMAP_MUX=y
 CONFIG_OMAP_MUX_DEBUG=y
@@ -216,43 +256,66 @@ CONFIG_OMAP_MCBSP=y
 CONFIG_OMAP_32K_TIMER=y
 CONFIG_OMAP_32K_TIMER_HZ=128
 CONFIG_OMAP_DM_TIMER=y
-# CONFIG_OMAP_LL_DEBUG_UART1 is not set
-# CONFIG_OMAP_LL_DEBUG_UART2 is not set
-# CONFIG_OMAP_LL_DEBUG_UART3 is not set
-CONFIG_OMAP_LL_DEBUG_NONE=y
 # CONFIG_OMAP_PM_NONE is not set
 CONFIG_OMAP_PM_NOOP=y
-CONFIG_ARCH_OMAP34XX=y
+CONFIG_MACH_OMAP_GENERIC=y
+
+#
+# OMAP Core Type
+#
+CONFIG_ARCH_OMAP2420=y
+# CONFIG_ARCH_OMAP2430 is not set
 CONFIG_ARCH_OMAP3430=y
+CONFIG_OMAP_PACKAGE_CBB=y
+CONFIG_OMAP_PACKAGE_CUS=y
+CONFIG_OMAP_PACKAGE_CBP=y
 
 #
 # OMAP Board Type
 #
+CONFIG_MACH_OMAP2_TUSB6010=y
+CONFIG_MACH_OMAP_H4=y
+CONFIG_MACH_OMAP_APOLLON=y
+# CONFIG_MACH_OMAP_2430SDP is not set
 CONFIG_MACH_OMAP3_BEAGLE=y
 CONFIG_MACH_OMAP_LDP=y
 CONFIG_MACH_OVERO=y
 CONFIG_MACH_OMAP3EVM=y
 CONFIG_MACH_OMAP3517EVM=y
 CONFIG_MACH_OMAP3_PANDORA=y
+CONFIG_MACH_OMAP3_TOUCHBOOK=y
 CONFIG_MACH_OMAP_3430SDP=y
+CONFIG_MACH_NOKIA_N800=y
+CONFIG_MACH_NOKIA_N810=y
+CONFIG_MACH_NOKIA_N810_WIMAX=y
+CONFIG_MACH_NOKIA_N8X0=y
 CONFIG_MACH_NOKIA_RX51=y
 CONFIG_MACH_OMAP_ZOOM2=y
 CONFIG_MACH_OMAP_ZOOM3=y
 CONFIG_MACH_CM_T35=y
 CONFIG_MACH_IGEP0020=y
 CONFIG_MACH_OMAP_3630SDP=y
+CONFIG_MACH_OMAP_4430SDP=y
+# CONFIG_OMAP3_EMU is not set
+# CONFIG_OMAP3_SDRC_AC_TIMING is not set
 
 #
 # Processor Type
 #
-CONFIG_CPU_32v6K=y
+CONFIG_CPU_V6=y
+# CONFIG_CPU_32v6K is not set
 CONFIG_CPU_V7=y
+CONFIG_CPU_32v6=y
 CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV6=y
 CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V6=y
 CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V6=y
 CONFIG_CPU_CACHE_V7=y
 CONFIG_CPU_CACHE_VIPT=y
 CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
 CONFIG_CPU_TLB_V7=y
 CONFIG_CPU_HAS_ASID=y
 CONFIG_CPU_CP15=y
@@ -268,9 +331,11 @@ CONFIG_ARM_THUMBEE=y
 # CONFIG_CPU_BPREDICT_DISABLE is not set
 CONFIG_HAS_TLS_REG=y
 CONFIG_ARM_L1_CACHE_SHIFT=6
+# CONFIG_ARM_ERRATA_411920 is not set
 # CONFIG_ARM_ERRATA_430973 is not set
 # CONFIG_ARM_ERRATA_458693 is not set
 # CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_ARM_GIC=y
 CONFIG_COMMON_CLKDEV=y
 
 #
@@ -287,6 +352,7 @@ CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_SMP is not set
 CONFIG_VMSPLIT_3G=y
 # CONFIG_VMSPLIT_2G is not set
 # CONFIG_VMSPLIT_1G is not set
@@ -298,6 +364,7 @@ CONFIG_HZ=128
 # CONFIG_THUMB2_KERNEL is not set
 CONFIG_AEABI=y
 CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y
 # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
 # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 # CONFIG_HIGHMEM is not set
@@ -308,12 +375,10 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_LEDS=y
@@ -385,7 +450,7 @@ CONFIG_SUSPEND=y
 # CONFIG_PM_TEST_SUSPEND is not set
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
-# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -509,15 +574,18 @@ CONFIG_BT_HCIBPA10X=y
 # CONFIG_BT_MRVL is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_WEXT_SPY=y
 CONFIG_CFG80211=y
 # CONFIG_NL80211_TESTMODE is not set
 # CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
 # CONFIG_CFG80211_REG_DEBUG is not set
 CONFIG_CFG80211_DEFAULT_PS=y
-CONFIG_CFG80211_DEFAULT_PS_VALUE=1
 # CONFIG_CFG80211_DEBUGFS is not set
 CONFIG_WIRELESS_OLD_REGULATORY=y
-CONFIG_WIRELESS_EXT=y
+CONFIG_CFG80211_WEXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 CONFIG_LIB80211=y
 # CONFIG_LIB80211_DEBUG is not set
@@ -671,6 +739,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
@@ -681,9 +750,12 @@ CONFIG_BLK_DEV_RAM_SIZE=16384
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_MG_DISK is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -694,6 +766,7 @@ CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_LEGACY=y
 # CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -792,28 +865,26 @@ CONFIG_SMSC911X=y
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-CONFIG_WLAN_80211=y
-CONFIG_LIBERTAS=y
-CONFIG_LIBERTAS_USB=y
-CONFIG_LIBERTAS_SDIO=y
-# CONFIG_LIBERTAS_SPI is not set
-CONFIG_LIBERTAS_DEBUG=y
 # CONFIG_LIBERTAS_THINFIRM is not set
 # CONFIG_AT76C50X_USB is not set
 # CONFIG_USB_ZD1201 is not set
 # CONFIG_USB_NET_RNDIS_WLAN is not set
 # CONFIG_RTL8187 is not set
 # CONFIG_MAC80211_HWSIM is not set
-# CONFIG_P54_COMMON is not set
 # CONFIG_ATH_COMMON is not set
-# CONFIG_HOSTAP is not set
 # CONFIG_B43 is not set
 # CONFIG_B43LEGACY is not set
-# CONFIG_ZD1211RW is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_IWM is not set
+CONFIG_LIBERTAS=y
+CONFIG_LIBERTAS_USB=y
+CONFIG_LIBERTAS_SDIO=y
+# CONFIG_LIBERTAS_SPI is not set
+CONFIG_LIBERTAS_DEBUG=y
+# CONFIG_P54_COMMON is not set
 # CONFIG_RT2X00 is not set
 # CONFIG_WL12XX is not set
-# CONFIG_IWM is not set
+# CONFIG_ZD1211RW is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -861,6 +932,7 @@ CONFIG_USB_NET_ZAURUS=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -889,6 +961,7 @@ CONFIG_KEYBOARD_GPIO=y
 # CONFIG_KEYBOARD_OPENCORES is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
 # CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_OMAP is not set
 CONFIG_KEYBOARD_TWL4030=y
 # CONFIG_KEYBOARD_XTKBD is not set
 CONFIG_INPUT_MOUSE=y
@@ -914,6 +987,7 @@ CONFIG_TOUCHSCREEN_ADS7846=y
 # CONFIG_TOUCHSCREEN_AD7879_I2C is not set
 # CONFIG_TOUCHSCREEN_AD7879_SPI is not set
 # CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
 # CONFIG_TOUCHSCREEN_EETI is not set
 # CONFIG_TOUCHSCREEN_FUJITSU is not set
 # CONFIG_TOUCHSCREEN_GUNZE is not set
@@ -948,6 +1022,7 @@ CONFIG_SERIO=y
 CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -986,6 +1061,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
 # CONFIG_HW_RANDOM_TIMERIOMEM is not set
+CONFIG_HW_RANDOM_OMAP=y
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -1024,7 +1100,6 @@ CONFIG_I2C_OMAP=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1040,6 +1115,8 @@ CONFIG_SPI_MASTER=y
 # CONFIG_SPI_BITBANG is not set
 # CONFIG_SPI_GPIO is not set
 CONFIG_SPI_OMAP24XX=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -1067,6 +1144,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
 CONFIG_GPIO_TWL4030=y
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1141,6 +1219,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1166,6 +1245,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1179,6 +1259,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 CONFIG_WATCHDOG_NOWAYOUT=y
@@ -1204,20 +1285,22 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
-# CONFIG_MFD_CORE is not set
+CONFIG_MFD_CORE=y
 # 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_MENELAUS is not set
 CONFIG_TWL4030_CORE=y
 # CONFIG_TWL4030_POWER is not set
-# CONFIG_TWL4030_CODEC is not set
+CONFIG_TWL4030_CODEC=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_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
@@ -1225,6 +1308,8 @@ CONFIG_TWL4030_CORE=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
 CONFIG_REGULATOR=y
 # CONFIG_REGULATOR_DEBUG is not set
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
@@ -1232,6 +1317,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
 # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
 # CONFIG_REGULATOR_BQ24022 is not set
 # CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_MAX8660 is not set
 CONFIG_REGULATOR_TWL4030=y
 # CONFIG_REGULATOR_LP3971 is not set
 # CONFIG_REGULATOR_TPS65023 is not set
@@ -1267,6 +1353,7 @@ CONFIG_FB_TILEBLITTING=y
 #
 # CONFIG_FB_UVESA is not set
 # CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_TMIO is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
@@ -1281,6 +1368,7 @@ CONFIG_FB_OMAP_079M3R=y
 # CONFIG_FB_OMAP_LCD_MIPID is not set
 # CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
 CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2
+# CONFIG_OMAP2_DSS is not set
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 # CONFIG_LCD_LMS283GF05 is not set
@@ -1364,12 +1452,15 @@ CONFIG_SND_USB_AUDIO=y
 CONFIG_SND_SOC=y
 CONFIG_SND_OMAP_SOC=y
 CONFIG_SND_OMAP_SOC_MCBSP=y
+# CONFIG_SND_OMAP_SOC_N810 is not set
 # CONFIG_SND_OMAP_SOC_OVERO is not set
 # CONFIG_SND_OMAP_SOC_OMAP3EVM is not set
+# CONFIG_SND_OMAP_SOC_AM3517EVM is not set
 # CONFIG_SND_OMAP_SOC_SDP3430 is not set
 CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=y
 # CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE is not set
 # CONFIG_SND_OMAP_SOC_ZOOM2 is not set
+# CONFIG_SND_OMAP_SOC_IGEP0020 is not set
 CONFIG_SND_SOC_I2C_AND_SPI=y
 # CONFIG_SND_SOC_ALL_CODECS is not set
 CONFIG_SND_SOC_TWL4030=y
@@ -1418,7 +1509,7 @@ CONFIG_USB_HID=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
-# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 CONFIG_USB_DEBUG=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
@@ -1441,6 +1532,7 @@ CONFIG_USB_MON=y
 # 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
@@ -1556,16 +1648,18 @@ CONFIG_USB_GADGET_SELECTED=y
 # CONFIG_USB_GADGET_LANGWELL is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 CONFIG_USB_GADGET_DUALSPEED=y
-CONFIG_USB_ZERO=y
+CONFIG_USB_ZERO=m
 # CONFIG_USB_ZERO_HNPTEST is not set
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_ETH is not set
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
 # CONFIG_USB_G_SERIAL is not set
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_MULTI is not set
 
 #
 # OTG and related infrastructure
@@ -1573,6 +1667,7 @@ CONFIG_USB_ZERO=y
 CONFIG_USB_OTG_UTILS=y
 # CONFIG_USB_GPIO_VBUS is not set
 # CONFIG_ISP1301_OMAP is not set
+# CONFIG_USB_ULPI is not set
 CONFIG_TWL4030_USB=y
 CONFIG_NOP_USB_XCEIV=y
 CONFIG_MMC=y
@@ -1609,7 +1704,9 @@ CONFIG_LEDS_GPIO_PLATFORM=y
 # CONFIG_LEDS_LP3944 is not set
 # CONFIG_LEDS_PCA955X is not set
 # CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_REGULATOR is not set
 # CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
 
 #
 # LED Triggers
@@ -1653,6 +1750,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 CONFIG_RTC_DRV_TWL4030=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
@@ -1683,7 +1781,9 @@ CONFIG_RTC_DRV_TWL4030=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1951,6 +2051,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
@@ -1983,7 +2084,9 @@ CONFIG_ARM_UNWIND=y
 # CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_LL=y
+# CONFIG_EARLY_PRINTK is not set
 # CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
 
 #
 # Security options
@@ -1993,9 +2096,12 @@ CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
 # CONFIG_SECURITY_PATH is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_SECURITY_ROOTPLUG is not set
 # CONFIG_SECURITY_TOMOYO is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_evm_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/omap3_evm_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_evm_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/omap3_evm_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -187,6 +187,8 @@ CONFIG_ARCH_OMAP3=y
 #
 # OMAP Feature Selections
 #
+CONFIG_OMAP_SMARTREFLEX=y
+# CONFIG_OMAP_SMARTREFLEX_TESTING is not set
 # CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
 # CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
 CONFIG_OMAP_RESET_CLOCKS=y
@@ -333,11 +335,12 @@ CONFIG_BINFMT_MISC=y
 # Power management options
 #
 CONFIG_PM=y
-# CONFIG_PM_DEBUG is not set
+CONFIG_PM_DEBUG=y
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -1339,7 +1342,7 @@ 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
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_pandora_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/omap3_pandora_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_pandora_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/omap3_pandora_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,15 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Fri Dec  5 11:54:09 2008
+# Linux kernel version: 2.6.33-rc6
+# Sat Feb  6 20:25:41 2010
 #
 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_HAVE_PROC_CPU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,13 +17,13 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_HAS_CPUFREQ=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -32,8 +31,15 @@ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNA
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -42,24 +48,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_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=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 is not set
-# CONFIG_SYSFS_DEPRECATED_V2=y is not set
-
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO 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,31 +85,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_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_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
+
+#
+# GCOV-based kernel profiling
+#
+CONFIG_SLOW_WORK=y
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -102,11 +127,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -114,33 +136,62 @@ CONFIG_BLOCK=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
 # System Type
 #
+CONFIG_MMU=y
 # CONFIG_ARCH_AAEC2000 is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -148,49 +199,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_DOVE is not set
 # CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
 # CONFIG_ARCH_LOKI is not set
 # CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
 # CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5PC1XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
 # CONFIG_ARCH_DAVINCI is not set
 CONFIG_ARCH_OMAP=y
-# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
 
 #
 # TI OMAP Implementations
 #
 CONFIG_ARCH_OMAP_OTG=y
 # CONFIG_ARCH_OMAP1 is not set
+CONFIG_ARCH_OMAP2PLUS=y
 # CONFIG_ARCH_OMAP2 is not set
 CONFIG_ARCH_OMAP3=y
+# CONFIG_ARCH_OMAP4 is not set
 
 #
 # OMAP Feature Selections
 #
-# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
-# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
 # CONFIG_OMAP_RESET_CLOCKS is not set
 # CONFIG_OMAP_MUX is not set
 CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MBOX_FWK is not set
 # CONFIG_OMAP_MPU_TIMER is not set
 CONFIG_OMAP_32K_TIMER=y
 CONFIG_OMAP_32K_TIMER_HZ=128
 CONFIG_OMAP_DM_TIMER=y
-# CONFIG_OMAP_LL_DEBUG_UART1 is not set
-# CONFIG_OMAP_LL_DEBUG_UART2 is not set
-CONFIG_OMAP_LL_DEBUG_UART3=y
-CONFIG_ARCH_OMAP34XX=y
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
 CONFIG_ARCH_OMAP3430=y
+CONFIG_OMAP_PACKAGE_CBB=y
 
 #
 # OMAP Board Type
@@ -198,15 +258,19 @@ CONFIG_ARCH_OMAP3430=y
 # CONFIG_MACH_OMAP3_BEAGLE is not set
 # CONFIG_MACH_OMAP_LDP is not set
 # CONFIG_MACH_OVERO is not set
+# CONFIG_MACH_OMAP3EVM is not set
+# CONFIG_MACH_OMAP3517EVM is not set
 CONFIG_MACH_OMAP3_PANDORA=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
+# CONFIG_MACH_OMAP3_TOUCHBOOK is not set
+# CONFIG_MACH_OMAP_3430SDP is not set
+# CONFIG_MACH_NOKIA_RX51 is not set
+# CONFIG_MACH_OMAP_ZOOM2 is not set
+# CONFIG_MACH_OMAP_ZOOM3 is not set
+# CONFIG_MACH_CM_T35 is not set
+# CONFIG_MACH_IGEP0020 is not set
+# CONFIG_MACH_OMAP_3630SDP is not set
+# CONFIG_OMAP3_EMU is not set
+# CONFIG_OMAP3_SDRC_AC_TIMING is not set
 
 #
 # Processor Type
@@ -215,7 +279,7 @@ CONFIG_CPU_32v6K=y
 CONFIG_CPU_V7=y
 CONFIG_CPU_32v7=y
 CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_PABRT_IFAR=y
+CONFIG_CPU_PABRT_V7=y
 CONFIG_CPU_CACHE_V7=y
 CONFIG_CPU_CACHE_VIPT=y
 CONFIG_CPU_COPY_V6=y
@@ -233,7 +297,12 @@ CONFIG_ARM_THUMBEE=y
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_BPREDICT_DISABLE is not set
 CONFIG_HAS_TLS_REG=y
-# CONFIG_OUTER_CACHE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_CPU_HAS_PMU=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
 
 #
 # Bus support
@@ -253,13 +322,16 @@ CONFIG_VMSPLIT_3G=y
 # CONFIG_VMSPLIT_2G is not set
 # CONFIG_VMSPLIT_1G is not set
 CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
 CONFIG_HZ=128
+# CONFIG_THUMB2_KERNEL is not set
 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
@@ -268,13 +340,14 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 # CONFIG_LEDS is not set
 CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
 
 #
 # Boot options
@@ -366,6 +439,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -379,7 +453,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -390,8 +467,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 is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -403,6 +486,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -412,6 +497,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
@@ -462,6 +548,7 @@ CONFIG_MTD_CFI_I2=y
 #
 # CONFIG_MTD_DATAFLASH is not set
 # CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -478,6 +565,9 @@ CONFIG_MTD_NAND=y
 # CONFIG_MTD_NAND_ECC_SMC is not set
 # CONFIG_MTD_NAND_MUSEUM_IDS is not set
 # CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_OMAP2=y
+CONFIG_MTD_NAND_OMAP_PREFETCH=y
+# CONFIG_MTD_NAND_OMAP_PREFETCH_DMA is not set
 CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
@@ -486,6 +576,11 @@ CONFIG_MTD_NAND_IDS=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
@@ -494,6 +589,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
@@ -502,7 +601,25 @@ CONFIG_BLK_DEV_RAM_SIZE=16384
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-# CONFIG_MISC_DEVICES is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -525,10 +642,6 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_BLK_DEV_SR is not set
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -545,8 +658,11 @@ CONFIG_SCSI_WAIT_SCAN=m
 # 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
@@ -559,13 +675,13 @@ CONFIG_NETDEVICES=y
 # CONFIG_NET_ETHERNET is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # USB Network Adapters
@@ -582,6 +698,7 @@ CONFIG_NETDEVICES=y
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
 # CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
 
 #
 # Input device support
@@ -589,6 +706,7 @@ CONFIG_NETDEVICES=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -605,13 +723,20 @@ CONFIG_INPUT_EVDEV=y
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
 # CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_QT2160 is not set
 # CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
-CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_TWL4030=y
+# CONFIG_KEYBOARD_XTKBD is not set
 CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_MOUSE_SERIAL is not set
@@ -619,13 +744,22 @@ CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_BCM5974 is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
 # CONFIG_TOUCHSCREEN_FUJITSU is not set
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
 # CONFIG_TOUCHSCREEN_MTOUCH is not set
 # CONFIG_TOUCHSCREEN_INEXIO is not set
 # CONFIG_TOUCHSCREEN_MK712 is not set
@@ -634,8 +768,18 @@ CONFIG_TOUCHSCREEN_ADS7846=y
 # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
 # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
 # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
 CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
 CONFIG_INPUT_TWL4030_PWRBUTTON=y
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
 
 #
 # Hardware I/O ports
@@ -670,18 +814,21 @@ CONFIG_SERIAL_8250_RSA=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
-# CONFIG_NVRAM is not set
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -692,10 +839,12 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_DESIGNWARE is not set
 # CONFIG_I2C_GPIO is not set
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_OMAP=y
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -709,21 +858,6 @@ CONFIG_I2C_OMAP=y
 #
 # 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_ISP1301_OMAP 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
@@ -736,14 +870,21 @@ CONFIG_SPI_MASTER=y
 # SPI Master Controller Drivers
 #
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 CONFIG_SPI_OMAP24XX=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -760,6 +901,7 @@ CONFIG_GPIOLIB=y
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
 CONFIG_GPIO_TWL4030=y
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -770,11 +912,16 @@ CONFIG_GPIO_TWL4030=y
 #
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
+# CONFIG_ALS is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -786,44 +933,111 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
-# CONFIG_MFD_CORE is not set
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_88PM860X 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_HTC_I2CPLD is not set
+# CONFIG_TPS65010 is not set
 CONFIG_TWL4030_CORE=y
+CONFIG_TWL4030_POWER=y
+CONFIG_TWL4030_CODEC=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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_AB4500_CORE is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_MAX8649 is not set
+# CONFIG_REGULATOR_MAX8660 is not set
+CONFIG_REGULATOR_TWL4030=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
-# Multimedia devices
-#
-
-#
-# Multimedia core support
+# Graphics support
 #
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
+# 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
 
 #
-# Multimedia drivers
+# Frame buffer hardware drivers
 #
-CONFIG_DAB=y
-# CONFIG_USB_DABUSB is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_TMIO is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
+CONFIG_OMAP2_VRAM=y
+CONFIG_OMAP2_VRFB=y
+CONFIG_OMAP2_DSS=y
+CONFIG_OMAP2_VRAM_SIZE=0
+CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y
+# CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS is not set
+# CONFIG_OMAP2_DSS_RFBI is not set
+CONFIG_OMAP2_DSS_VENC=y
+# CONFIG_OMAP2_DSS_SDI is not set
+# CONFIG_OMAP2_DSS_DSI is not set
+# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
+CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
+CONFIG_FB_OMAP2=y
+CONFIG_FB_OMAP2_DEBUG_SUPPORT=y
+# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set
+CONFIG_FB_OMAP2_NUM_FBS=3
 
 #
-# Graphics support
+# OMAP2/3 Display Device Drivers
 #
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_PANEL_GENERIC is not set
+# CONFIG_PANEL_SHARP_LS037V7DW01 is not set
+# CONFIG_PANEL_SHARP_LQ043T1DG01 is not set
+# CONFIG_PANEL_TOPPOLY_TDO35S is not set
+CONFIG_PANEL_TPO_TD043MTEA1=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
 
 #
 # Display device support
@@ -835,6 +1049,16 @@ CONFIG_DAB=y
 #
 # 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=y
 CONFIG_SOUND_OSS_CORE=y
 CONFIG_SOUND_OSS_CORE_PRECLAIM=y
@@ -842,25 +1066,43 @@ CONFIG_SND=y
 CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=y
 CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
 CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
 CONFIG_SND_VERBOSE_PRINTK=y
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
 CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
 CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_CAIAQ is not set
 CONFIG_SND_SOC=y
 CONFIG_SND_OMAP_SOC=y
 CONFIG_SND_OMAP_SOC_MCBSP=y
 CONFIG_SND_OMAP_SOC_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 is not set
 # CONFIG_HIDRAW is not set
 
 #
@@ -873,31 +1115,40 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
-# CONFIG_HID_COMPAT is not set
+# CONFIG_HID_3M_PCT is not set
 # CONFIG_HID_A4TECH is not set
 # CONFIG_HID_APPLE is not set
 # CONFIG_HID_BELKIN is not set
-# CONFIG_HID_BRIGHT is not set
 # CONFIG_HID_CHERRY is not set
 # CONFIG_HID_CHICONY is not set
 # CONFIG_HID_CYPRESS is not set
-# CONFIG_HID_DELL is not set
+# CONFIG_HID_DRAGONRISE is not set
 # CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
 # CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
 # CONFIG_HID_LOGITECH is not set
 # CONFIG_HID_MICROSOFT is not set
 # CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_QUANTA is not set
 # CONFIG_HID_SAMSUNG is not set
 # CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
 # CONFIG_HID_SUNPLUS is not set
-# CONFIG_THRUSTMASTER_FF is not set
-# CONFIG_ZEROPLUS_FF is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
-# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
@@ -911,7 +1162,7 @@ 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=y
+# CONFIG_USB_MON is not set
 # CONFIG_USB_WUSB is not set
 # CONFIG_USB_WUSB_CBAF is not set
 
@@ -919,7 +1170,13 @@ CONFIG_USB_MON=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 # CONFIG_USB_OHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
@@ -930,11 +1187,10 @@ CONFIG_USB_MUSB_SOC=y
 #
 # OMAP 343x high speed USB support
 #
-CONFIG_USB_MUSB_HOST=y
-# CONFIG_USB_MUSB_PERIPHERAL is not set
+# CONFIG_USB_MUSB_HOST is not set
+CONFIG_USB_MUSB_PERIPHERAL=y
 # CONFIG_USB_MUSB_OTG is not set
-# CONFIG_USB_GADGET_MUSB_HDRC is not set
-CONFIG_USB_MUSB_HDRC_HCD=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
 # CONFIG_MUSB_PIO_ONLY is not set
 CONFIG_USB_INVENTRA_DMA=y
 # CONFIG_USB_TI_CPPI_DMA is not set
@@ -949,11 +1205,11 @@ CONFIG_USB_INVENTRA_DMA=y
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_LIBUSUAL is not set
@@ -979,14 +1235,13 @@ CONFIG_USB_INVENTRA_DMA=y
 # 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
@@ -1002,27 +1257,46 @@ CONFIG_USB_GADGET_SELECTED=y
 # CONFIG_USB_GADGET_ATMEL_USBA is not set
 # CONFIG_USB_GADGET_FSL_USB2 is not set
 # CONFIG_USB_GADGET_LH7A40X is not set
-CONFIG_USB_GADGET_OMAP=y
-CONFIG_USB_OMAP=y
+# CONFIG_USB_GADGET_OMAP is not set
 # CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
 # CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
 # CONFIG_USB_GADGET_S3C2410 is not set
 # CONFIG_USB_GADGET_M66592 is not set
 # CONFIG_USB_GADGET_AMD5536UDC is not set
 # CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
 # CONFIG_USB_GADGET_NET2280 is not set
 # CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
-# CONFIG_USB_GADGET_DUALSPEED is not set
+CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
 CONFIG_USB_ETH=y
 CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
 # CONFIG_USB_G_SERIAL is not set
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
+# CONFIG_USB_G_MULTI 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_USB_ULPI is not set
+CONFIG_TWL4030_USB=y
+# CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
@@ -1040,16 +1314,41 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 #
 # CONFIG_MMC_SDHCI is not set
 # CONFIG_MMC_OMAP is not set
+CONFIG_MMC_OMAP_HS=y
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
 # CONFIG_MMC_SPI is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_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_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_REGULATOR is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+
+#
+# LED Triggers
+#
 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_GPIO is not set
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
 
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
@@ -1078,10 +1377,12 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 CONFIG_RTC_DRV_TWL4030=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -1093,6 +1394,7 @@ CONFIG_RTC_DRV_TWL4030=y
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
 # CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -1106,18 +1408,22 @@ CONFIG_RTC_DRV_TWL4030=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
 # on-CPU RTC drivers
 #
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_TWL4030=y
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -1126,21 +1432,27 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
 # CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
-CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
+CONFIG_FANOTIFY=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
@@ -1149,6 +1461,11 @@ CONFIG_QUOTACTL=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -1175,10 +1492,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
@@ -1187,7 +1501,9 @@ CONFIG_TMPFS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS 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
@@ -1196,7 +1512,20 @@ CONFIG_TMPFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=y
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
 
 #
 # Partition Types
@@ -1269,6 +1598,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -1277,11 +1607,15 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1299,33 +1633,42 @@ CONFIG_DEBUG_INFO=y
 # 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_DEBUG_CREDENTIALS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
 # CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
 
 #
 # Security options
@@ -1333,19 +1676,22 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=y
-CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HASH2=y
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_CRYPTD is not set
@@ -1362,12 +1708,12 @@ CONFIG_CRYPTO_MANAGER=y
 #
 # Block modes
 #
-CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CBC is not set
 # CONFIG_CRYPTO_CTR is not set
 # CONFIG_CRYPTO_CTS is not set
-CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_ECB is not set
 # CONFIG_CRYPTO_LRW is not set
-CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_PCBC is not set
 # CONFIG_CRYPTO_XTS is not set
 
 #
@@ -1375,13 +1721,15 @@ CONFIG_CRYPTO_PCBC=m
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
+# 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
@@ -1403,7 +1751,7 @@ CONFIG_CRYPTO_MD5=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_DES is not set
 # CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_SALSA20 is not set
@@ -1416,33 +1764,33 @@ CONFIG_CRYPTO_DES=y
 # 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_HW 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 is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
-CONFIG_LIBCRC32C=y
-CONFIG_PLIST=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
-
-# added by hand for now
-CONFIG_KEYBOARD_TWL4030=y
-CONFIG_USB_OTG_UTILS=y
-CONFIG_TWL4030_USB=y
-CONFIG_MMC_OMAP_HS=y
-
+CONFIG_NLATTR=y
+# CONFIG_SHM_SIGNAL is not set
+# CONFIG_IOQ is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_touchbook_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/omap3_touchbook_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_touchbook_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/omap3_touchbook_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -368,7 +368,7 @@ CONFIG_SUSPEND=y
 # CONFIG_PM_TEST_SUSPEND is not set
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
-# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/omap_4430sdp_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/omap_4430sdp_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/omap_4430sdp_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/omap_4430sdp_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -199,7 +199,7 @@ CONFIG_ARCH_OMAP4=y
 #
 # CONFIG_OMAP_RESET_CLOCKS is not set
 # CONFIG_OMAP_MUX is not set
-# CONFIG_OMAP_MCBSP is not set
+CONFIG_OMAP_MCBSP=y
 # CONFIG_OMAP_MBOX_FWK is not set
 # CONFIG_OMAP_MPU_TIMER is not set
 CONFIG_OMAP_32K_TIMER=y
@@ -242,10 +242,13 @@ CONFIG_CPU_CP15_MMU=y
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_BPREDICT_DISABLE is not set
 CONFIG_HAS_TLS_REG=y
+CONFIG_OUTER_CACHE=y
+CONFIG_CACHE_L2X0=y
 CONFIG_ARM_L1_CACHE_SHIFT=5
 # CONFIG_ARM_ERRATA_430973 is not set
 # CONFIG_ARM_ERRATA_458693 is not set
 # CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_PL310_ERRATA_588369=y
 CONFIG_ARM_GIC=y
 
 #
@@ -304,7 +307,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=/dev/ram0 rw mem=128M console=ttyS0,115200n8 initrd=0x81600000,20M ramdisk_size=20480"
+CONFIG_CMDLINE="root=/dev/ram0 rw mem=128M console=ttyS2,115200n8 initrd=0x81600000,20M ramdisk_size=20480"
 # CONFIG_XIP_KERNEL is not set
 # CONFIG_KEXEC is not set
 
@@ -488,7 +491,8 @@ CONFIG_GPIOLIB=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_WATCHDOG is not set
+CONFIG_WATCHDOG=y
+CONFIG_OMAP_WATCHDOG=y
 CONFIG_SSB_POSSIBLE=y
 
 #
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/omap_h2_1610_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/omap_h2_1610_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/omap_h2_1610_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/omap_h2_1610_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -331,6 +331,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 
 #
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/omap_zoom2_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/omap_zoom2_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/omap_zoom2_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/omap_zoom2_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -343,6 +343,7 @@ CONFIG_SUSPEND=y
 # CONFIG_PM_TEST_SUSPEND is not set
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -660,7 +661,7 @@ CONFIG_DEVKMEM=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/omap_zoom3_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/omap_zoom3_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/omap_zoom3_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/omap_zoom3_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -361,7 +361,7 @@ CONFIG_SUSPEND=y
 # CONFIG_PM_TEST_SUSPEND is not set
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
-# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -680,7 +680,7 @@ CONFIG_DEVKMEM=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -1136,7 +1136,7 @@ CONFIG_TWL4030_USB=y
 # CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
-# CONFIG_MMC_UNSAFE_RESUME is not set
+CONFIG_MMC_UNSAFE_RESUME=y
 
 #
 # MMC/SD/SDIO Card Drivers
@@ -1186,7 +1186,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_TWL4030 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
@@ -1416,7 +1416,7 @@ CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/orion5x_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/orion5x_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/orion5x_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/orion5x_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc6
-# Sat Nov  7 20:52:21 2009
+# Linux kernel version: 2.6.33-rc6
+# Thu Feb  4 23:30:00 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -32,6 +32,12 @@ CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -45,6 +51,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -122,14 +129,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -158,6 +192,7 @@ CONFIG_MMU=y
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
 # CONFIG_ARCH_KIRKWOOD is not set
 # CONFIG_ARCH_LOKI is not set
 # CONFIG_ARCH_MV78XX0 is not set
@@ -180,6 +215,7 @@ CONFIG_ARCH_ORION5X=y
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
 # CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
 
 #
 # Orion Implementations
@@ -192,6 +228,7 @@ CONFIG_MACH_TS209=y
 CONFIG_MACH_TERASTATION_PRO2=y
 CONFIG_MACH_LINKSTATION_PRO=y
 CONFIG_MACH_LINKSTATION_MINI=y
+CONFIG_MACH_LINKSTATION_LS_HGL=y
 CONFIG_MACH_TS409=y
 CONFIG_MACH_WRT350N_V2=y
 CONFIG_MACH_TS78XX=y
@@ -268,12 +305,10 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_LEDS=y
@@ -412,10 +447,6 @@ CONFIG_NET_PKTGEN=m
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 
 #
@@ -554,6 +585,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -562,6 +597,7 @@ CONFIG_BLK_DEV_LOOP=y
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_MG_DISK is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -569,6 +605,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -621,7 +658,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -657,6 +696,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -711,15 +751,16 @@ CONFIG_SATA_MV=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -736,7 +777,7 @@ CONFIG_SATA_MV=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -842,8 +883,10 @@ CONFIG_MV643XX_ETH=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -866,6 +909,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -875,6 +919,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -993,11 +1038,6 @@ CONFIG_I2C_MV64XXX=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -1006,7 +1046,6 @@ CONFIG_I2C_MV64XXX=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1033,10 +1072,12 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1079,6 +1120,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1104,6 +1146,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1118,6 +1161,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
@@ -1140,11 +1184,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_TC6393XB is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1316,6 +1362,7 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
 # OTG and related infrastructure
 #
 # CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
 # CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
@@ -1332,6 +1379,7 @@ CONFIG_LEDS_GPIO_PLATFORM=y
 # CONFIG_LEDS_LP3944 is not set
 # CONFIG_LEDS_PCA955X is not set
 # CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
 
 #
 # LED Triggers
@@ -1377,6 +1425,7 @@ CONFIG_RTC_DRV_PCF8563=y
 # CONFIG_RTC_DRV_PCF8583 is not set
 CONFIG_RTC_DRV_M41T80=y
 # CONFIG_RTC_DRV_M41T80_WDT is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 CONFIG_RTC_DRV_S35390A=y
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1398,7 +1447,9 @@ CONFIG_RTC_DRV_S35390A=y
 CONFIG_RTC_DRV_M48T86=y
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1686,7 +1737,9 @@ CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_LL=y
+# CONFIG_EARLY_PRINTK is not set
 # CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
 
 #
 # Security options
@@ -1694,7 +1747,11 @@ 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_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/pxa168_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/pxa168_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/pxa168_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/pxa168_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,15 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc3
-# Fri Mar 20 13:43:13 2009
+# Linux kernel version: 2.6.33-rc3
+# Tue Jan 12 08:57:10 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,13 +16,12 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -35,6 +32,12 @@ CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -46,11 +49,13 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_GROUP_SCHED is not set
@@ -64,10 +69,10 @@ CONFIG_NAMESPACES=y
 # 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_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
@@ -78,17 +83,20 @@ 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
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -98,6 +106,11 @@ CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -109,8 +122,7 @@ 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_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -118,31 +130,62 @@ CONFIG_BLOCK=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
 # System Type
 #
+CONFIG_MMU=y
 # CONFIG_ARCH_AAEC2000 is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
 # CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -150,26 +193,30 @@ CONFIG_DEFAULT_IOSCHED="cfq"
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
 # CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
 # CONFIG_ARCH_LOKI is not set
 # CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
 # CONFIG_ARCH_ORION5X is not set
+CONFIG_ARCH_MMP=y
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
-CONFIG_ARCH_MMP=y
+# CONFIG_ARCH_MSM is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
 # CONFIG_MACH_TAVOREVB is not set
 
 #
@@ -177,6 +224,7 @@ CONFIG_ARCH_MMP=y
 #
 CONFIG_MACH_ASPENITE=y
 CONFIG_MACH_ZYLONITE2=y
+CONFIG_MACH_AVENGERS_LITE=y
 # CONFIG_MACH_TTC_DKB is not set
 CONFIG_CPU_PXA168=y
 CONFIG_PLAT_PXA=y
@@ -187,7 +235,7 @@ CONFIG_PLAT_PXA=y
 CONFIG_CPU_MOHAWK=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_LEGACY=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_COPY_V4WB=y
 CONFIG_CPU_TLB_V4WBI=y
@@ -201,7 +249,7 @@ 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_ARM_L1_CACHE_SHIFT=5
 CONFIG_IWMMXT=y
 CONFIG_COMMON_CLKDEV=y
 
@@ -223,13 +271,15 @@ CONFIG_VMSPLIT_3G=y
 # CONFIG_VMSPLIT_2G is not set
 # CONFIG_VMSPLIT_1G is not set
 CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_HZ=100
 CONFIG_AEABI=y
 CONFIG_OABI_COMPAT=y
-CONFIG_ARCH_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
@@ -237,12 +287,14 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
 
 #
 # Boot options
@@ -288,7 +340,6 @@ 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 +381,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -343,6 +395,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -355,13 +409,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
-# CONFIG_MAC80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -374,6 +428,7 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_FW_LOADER=y
@@ -412,8 +467,10 @@ CONFIG_MII=y
 # CONFIG_AX88796 is not set
 CONFIG_SMC91X=y
 # CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -422,15 +479,12 @@ CONFIG_SMC91X=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN=y
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -442,6 +496,7 @@ CONFIG_SMC91X=y
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
 # CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
 
 #
 # Input device support
@@ -449,6 +504,7 @@ CONFIG_SMC91X=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -510,6 +566,11 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_TCG_TPM is not set
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -530,11 +591,14 @@ CONFIG_GPIOLIB=y
 #
 # SPI GPIO expanders:
 #
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -555,22 +619,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_T7L66XB is not set
 # CONFIG_MFD_TC6387XB is not set
 # CONFIG_MFD_TC6393XB is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -595,13 +645,17 @@ CONFIG_DUMMY_CONSOLE=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
-# CONFIG_REGULATOR is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -613,10 +667,13 @@ CONFIG_RTC_LIB=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -627,6 +684,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
@@ -673,6 +735,7 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=y
@@ -681,7 +744,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
@@ -706,6 +768,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -714,11 +777,15 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_PREEMPT is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -738,28 +805,33 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
 # CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_PREEMPT_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -768,7 +840,9 @@ CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_LL=y
+# CONFIG_EARLY_PRINTK is not set
 # CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
 
 #
 # Security options
@@ -776,13 +850,16 @@ 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_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -791,10 +868,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
@@ -822,11 +901,13 @@ CONFIG_CRYPTO_CBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -863,6 +944,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -870,6 +952,7 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -884,7 +967,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.33-gnu1/arch/arm/configs/raumfeld_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/raumfeld_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/raumfeld_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/raumfeld_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1898 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc5
+# Sun Nov  1 21:57:32 2009
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+# 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_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_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
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+CONFIG_SLOW_WORK=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_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+
+#
+# Supported PXA3xx Processor Variants
+#
+CONFIG_CPU_PXA300=y
+# CONFIG_CPU_PXA310 is not set
+CONFIG_CPU_PXA320=y
+# CONFIG_CPU_PXA930 is not set
+# CONFIG_CPU_PXA935 is not set
+# CONFIG_CPU_PXA950 is not set
+
+#
+# Intel/Marvell Dev Platforms (sorted by hardware release time)
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_MAINSTONE 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
+
+#
+# Third Party Dev Platforms (sorted by vendor name)
+#
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_ARCH_VIPER is not set
+# CONFIG_MACH_BALLOON3 is not set
+# CONFIG_MACH_CSB726 is not set
+# CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_EXEDA is not set
+# CONFIG_MACH_CM_X300 is not set
+# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_MACH_INTELMOTE2 is not set
+# CONFIG_MACH_STARGATE2 is not set
+# CONFIG_MACH_XCEP is not set
+# CONFIG_TRIZEPS_PXA is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_MACH_COLIBRI is not set
+# CONFIG_MACH_COLIBRI300 is not set
+# CONFIG_MACH_COLIBRI320 is not set
+
+#
+# End-user Products (sorted by vendor name)
+#
+# CONFIG_MACH_H4700 is not set
+# CONFIG_MACH_H5000 is not set
+# CONFIG_MACH_HIMALAYA is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_PXA_EZX is not set
+# CONFIG_MACH_MP900C is not set
+# CONFIG_ARCH_PXA_PALM is not set
+CONFIG_MACH_RAUMFELD_RC=y
+CONFIG_MACH_RAUMFELD_CONNECTOR=y
+CONFIG_MACH_RAUMFELD_PROTO=y
+CONFIG_MACH_RAUMFELD_SPEAKER=y
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+CONFIG_PXA3xx=y
+CONFIG_PXA_SSP=y
+CONFIG_PLAT_PXA=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSC3=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_LEGACY=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_ARM_L1_CACHE_SHIFT=5
+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 is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="console=ttyS0,115200 rw"
+# 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 is not set
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_APM_EMULATION=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=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 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_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_CFG80211=y
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+CONFIG_CFG80211_REG_DEBUG=y
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEFAULT_PS_VALUE=1
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=y
+# CONFIG_LIB80211_DEBUG is not set
+CONFIG_MAC80211=y
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_LEDS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_CONCAT=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=y
+CONFIG_NFTL_RW=y
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+CONFIG_MTD_BLOCK2MTD=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 is not set
+# CONFIG_MTD_NAND_SHARPSL is not set
+CONFIG_MTD_NAND_PXA3xx=y
+# CONFIG_MTD_NAND_PXA3xx_BUILTIN 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=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 is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_ISL29003=y
+CONFIG_TI_DAC7512=y
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=y
+# CONFIG_LIBERTAS_USB is not set
+CONFIG_LIBERTAS_SDIO=m
+# CONFIG_LIBERTAS_SPI is not set
+# CONFIG_LIBERTAS_DEBUG is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_ATH_COMMON is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_ZD1211RW is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_WL12XX is not set
+# CONFIG_IWM is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+CONFIG_USB_USBNET=y
+# CONFIG_USB_NET_AX8817X is not set
+CONFIG_USB_NET_CDCETHER=y
+# CONFIG_USB_NET_CDC_EEM is not set
+# CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_SMSC95XX is not set
+# CONFIG_USB_NET_GL620A is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_PLUSB is not set
+CONFIG_USB_NET_MCS7830=y
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+# CONFIG_USB_NET_INT51X1 is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_POLLDEV=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_PXA27x is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+CONFIG_TOUCHSCREEN_EETI=m
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+# CONFIG_INPUT_UINPUT is not set
+CONFIG_INPUT_GPIO_ROTARY_ENCODER=y
+
+#
+# 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_MAX3100 is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=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_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PXA=y
+# CONFIG_I2C_PXA_SLAVE is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_DEBUG=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_GPIO=y
+# CONFIG_SPI_PXA2XX is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_DEBUG_GPIO=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_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+CONFIG_W1=m
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2490 is not set
+# CONFIG_W1_MASTER_DS2482 is not set
+# CONFIG_W1_MASTER_DS1WM is not set
+CONFIG_W1_MASTER_GPIO=m
+
+#
+# 1-wire Slaves
+#
+# CONFIG_W1_SLAVE_THERM is not set
+# CONFIG_W1_SLAVE_SMEM is not set
+# CONFIG_W1_SLAVE_DS2431 is not set
+# CONFIG_W1_SLAVE_DS2433 is not set
+CONFIG_W1_SLAVE_DS2760=m
+# 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=m
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_SENSORS_LIS3_SPI=y
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+CONFIG_REGULATOR_MAX8660=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=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_PXA3XX_GCU=y
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_W100 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=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 is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_LOGO_RAUMFELD_CLUT224=y
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+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
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_PXA2XX_LIB=y
+# CONFIG_SND_PXA2XX_AC97 is not set
+CONFIG_SND_SPI=y
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_PXA2XX_SOC=y
+CONFIG_SND_PXA_SOC_SSP=y
+CONFIG_SND_SOC_RAUMFELD=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_AK4104=y
+CONFIG_SND_SOC_CS4270=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+# CONFIG_DRAGONRISE_FF is not set
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# 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_HID_GREENASIA=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_SMARTJOYPLUS=y
+# CONFIG_SMARTJOYPLUS_FF is not set
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+# CONFIG_THRUSTMASTER_FF is not set
+CONFIG_HID_ZEROPLUS=y
+# 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 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_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=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 info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+# 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=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=m
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_PWM is not set
+# CONFIG_LEDS_BD2802 is not set
+CONFIG_LEDS_LT3593=y
+
+#
+# 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_GPIO is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_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=y
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+# CONFIG_AUXDISPLAY 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
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT2_FS_XIP=y
+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_FS_XIP=y
+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_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+CONFIG_FSCACHE=y
+CONFIG_FSCACHE_STATS=y
+# CONFIG_FSCACHE_HISTOGRAM is not set
+# CONFIG_FSCACHE_DEBUG is not set
+CONFIG_CACHEFILES=y
+# CONFIG_CACHEFILES_DEBUG is not set
+# CONFIG_CACHEFILES_HISTOGRAM 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 is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFS_FSCACHE=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=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_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=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_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/rx51_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/rx51_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/rx51_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/rx51_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -59,8 +59,6 @@ CONFIG_FAIR_GROUP_SCHED=y
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -322,6 +320,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -445,6 +444,8 @@ CONFIG_IP_NF_FILTER=m
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+CONFIG_PHONET=y
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -477,7 +478,6 @@ CONFIG_BT_HIDP=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=y
 # CONFIG_CFG80211_REG_DEBUG is not set
@@ -1325,27 +1325,34 @@ CONFIG_USB_GADGET_SELECTED=y
 # CONFIG_USB_GADGET_LH7A40X is not set
 # CONFIG_USB_GADGET_OMAP is not set
 # CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
 # CONFIG_USB_GADGET_PXA27X is not set
-# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
 # CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
 # CONFIG_USB_GADGET_M66592 is not set
 # CONFIG_USB_GADGET_AMD5536UDC is not set
 # CONFIG_USB_GADGET_FSL_QE is not set
 # CONFIG_USB_GADGET_CI13XXX is not set
 # CONFIG_USB_GADGET_NET2280 is not set
 # CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 CONFIG_USB_GADGET_DUALSPEED=y
 CONFIG_USB_ZERO=m
 # CONFIG_USB_ZERO_HNPTEST is not set
+# CONFIG_USB_AUDIO is not set
 # CONFIG_USB_ETH is not set
 # CONFIG_USB_GADGETFS is not set
 CONFIG_USB_FILE_STORAGE=m
 # CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_MASS_STORAGE is not set
 # CONFIG_USB_G_SERIAL is not set
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+CONFIG_USB_G_NOKIA=m
+# CONFIG_USB_G_MULTI is not set
 
 #
 # OTG and related infrastructure
@@ -1354,7 +1361,7 @@ 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=m
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
 
@@ -1362,7 +1369,7 @@ CONFIG_MMC=y
 # MMC/SD/SDIO Card Drivers
 #
 CONFIG_MMC_BLOCK=m
-CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
 # CONFIG_SDIO_UART is not set
 # CONFIG_MMC_TEST is not set
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/s3c2410_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/s3c2410_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/s3c2410_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/s3c2410_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -187,7 +187,7 @@ 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_S3C_ADC=y
 CONFIG_MACH_SMDK=y
 CONFIG_PLAT_S3C=y
 CONFIG_CPU_LLSERIAL_S3C2410=y
@@ -203,8 +203,8 @@ CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
 #
 # Power management
 #
-# CONFIG_S3C2410_PM_DEBUG is not set
-# CONFIG_S3C2410_PM_CHECK is not set
+# CONFIG_SAMSUNG_PM_DEBUG is not set
+# CONFIG_SAMSUNG_PM_CHECK is not set
 CONFIG_S3C_LOWLEVEL_UART_PORT=0
 CONFIG_S3C_GPIO_SPACE=0
 CONFIG_S3C_DEV_HSMMC=y
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/s3c6400_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/s3c6400_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/s3c6400_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/s3c6400_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,14 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc3
-# Mon Nov  3 10:10:30 2008
+# Linux kernel version: 2.6.33-rc4
+# Tue Jan 19 13:12:40 2010
 #
 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=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -18,13 +15,13 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_HAS_CPUFREQ=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -34,13 +31,30 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=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
@@ -50,8 +64,13 @@ CONFIG_NAMESPACES=y
 # CONFIG_PID_NS is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=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
@@ -62,32 +81,38 @@ 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
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_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
+
+#
+# GCOV-based kernel profiling
+#
+# 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
@@ -95,11 +120,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=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
-CONFIG_LSF=y
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -107,33 +129,62 @@ CONFIG_LSF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
 # System Type
 #
+CONFIG_MMU=y
 # CONFIG_ARCH_AAEC2000 is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -141,35 +192,62 @@ CONFIG_CLASSIC_RCU=y
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
 # CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
 # CONFIG_ARCH_LOKI is not set
 # CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
 # CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 CONFIG_ARCH_S3C64XX=y
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5PC1XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_PLAT_SAMSUNG=y
+CONFIG_SAMSUNG_CLKSRC=y
+CONFIG_SAMSUNG_IRQ_VIC_TIMER=y
+CONFIG_SAMSUNG_IRQ_UART=y
+CONFIG_S3C_GPIO_CFG_S3C24XX=y
+CONFIG_S3C_GPIO_CFG_S3C64XX=y
+CONFIG_S3C_GPIO_PULL_UPDOWN=y
+CONFIG_SAMSUNG_GPIO_EXTRA=0
+# CONFIG_S3C_ADC is not set
+CONFIG_S3C_DEV_HSMMC=y
+CONFIG_S3C_DEV_HSMMC1=y
+CONFIG_S3C_DEV_I2C1=y
+CONFIG_S3C_DEV_FB=y
+CONFIG_S3C_DEV_USB_HOST=y
+CONFIG_S3C_DEV_USB_HSOTG=y
+CONFIG_S3C_DEV_NAND=y
 CONFIG_PLAT_S3C64XX=y
 CONFIG_CPU_S3C6400_INIT=y
 CONFIG_CPU_S3C6400_CLOCK=y
+# CONFIG_S3C64XX_DMA is not set
 CONFIG_S3C64XX_SETUP_I2C0=y
 CONFIG_S3C64XX_SETUP_I2C1=y
+CONFIG_S3C64XX_SETUP_FB_24BPP=y
+CONFIG_S3C64XX_SETUP_SDHCI_GPIO=y
 CONFIG_PLAT_S3C=y
 
 #
 # Boot options
 #
 CONFIG_S3C_BOOT_ERROR_RESET=y
+CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
 
 #
 # Power management
@@ -177,17 +255,16 @@ CONFIG_S3C_BOOT_ERROR_RESET=y
 CONFIG_S3C_LOWLEVEL_UART_PORT=0
 CONFIG_S3C_GPIO_SPACE=0
 CONFIG_S3C_GPIO_TRACK=y
-CONFIG_S3C_GPIO_PULL_UPDOWN=y
-CONFIG_S3C_GPIO_CFG_S3C24XX=y
-CONFIG_S3C_GPIO_CFG_S3C64XX=y
-CONFIG_S3C_DEV_HSMMC=y
-CONFIG_S3C_DEV_HSMMC1=y
-CONFIG_S3C_DEV_I2C1=y
+# CONFIG_MACH_SMDK6400 is not set
 CONFIG_CPU_S3C6410=y
 CONFIG_S3C6410_SETUP_SDHCI=y
+# CONFIG_MACH_ANW6410 is not set
 CONFIG_MACH_SMDK6410=y
 CONFIG_SMDK6410_SD_CH0=y
 # CONFIG_SMDK6410_SD_CH1 is not set
+# CONFIG_SMDK6410_WM1190_EV1 is not set
+# CONFIG_MACH_NCP is not set
+# CONFIG_MACH_HMT is not set
 
 #
 # Processor Type
@@ -196,7 +273,7 @@ CONFIG_CPU_V6=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_32v6=y
 CONFIG_CPU_ABRT_EV6=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_V6=y
 CONFIG_CPU_CACHE_V6=y
 CONFIG_CPU_CACHE_VIPT=y
 CONFIG_CPU_COPY_V6=y
@@ -212,8 +289,10 @@ 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_ARM_L1_CACHE_SHIFT=5
+# CONFIG_ARM_ERRATA_411920 is not set
 CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
 
 #
 # Bus support
@@ -229,13 +308,15 @@ CONFIG_VMSPLIT_3G=y
 # CONFIG_VMSPLIT_2G is not set
 # CONFIG_VMSPLIT_1G is not set
 CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_HZ=100
 CONFIG_AEABI=y
 CONFIG_OABI_COMPAT=y
-CONFIG_ARCH_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
@@ -243,26 +324,28 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
 
 #
 # Boot options
 #
 CONFIG_ZBOOT_ROM_TEXT=0
 CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_CMDLINE="console=ttySAC0,115200 root=/dev/ram init=/bin/bash initrd=0x51000000,4M"
+CONFIG_CMDLINE="console=ttySAC0,115200 root=/dev/ram init=/linuxrc initrd=0x51000000,6M ramdisk_size=6144"
 # 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
 
 #
@@ -300,6 +383,7 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -314,14 +398,32 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_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_MG_DISK is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -334,6 +436,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_SCSI_NETLINK is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
+# CONFIG_PHONE is not set
 
 #
 # Input device support
@@ -341,6 +444,7 @@ CONFIG_HAVE_IDE=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -357,27 +461,33 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
 CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_QT2160 is not set
 # CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
-# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 CONFIG_MOUSE_PS2_ALPS=y
 CONFIG_MOUSE_PS2_LOGIPS2PP=y
 CONFIG_MOUSE_PS2_SYNAPTICS=y
-CONFIG_MOUSE_PS2_LIFEBOOK=y
 CONFIG_MOUSE_PS2_TRACKPOINT=y
 # CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
 # CONFIG_MOUSE_PS2_TOUCHKIT is not set
 # CONFIG_MOUSE_SERIAL is not set
 # CONFIG_MOUSE_APPLETOUCH is not set
 # CONFIG_MOUSE_BCM5974 is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
@@ -390,6 +500,7 @@ CONFIG_SERIO=y
 CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -423,16 +534,18 @@ CONFIG_SERIAL_S3C6400=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_NVRAM is not set
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -443,6 +556,7 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_DESIGNWARE is not set
 # CONFIG_I2C_GPIO is not set
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_S3C2410=y
@@ -463,32 +577,33 @@ CONFIG_I2C_S3C2410=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
-CONFIG_EEPROM_AT24=y
-# 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
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
 # CONFIG_GPIO_SYSFS is not set
 
 #
+# Memory mapped GPIO expanders:
+#
+
+#
 # I2C GPIO expanders:
 #
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -497,10 +612,19 @@ CONFIG_GPIOLIB=y
 #
 # SPI GPIO expanders:
 #
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
 # CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
@@ -509,17 +633,21 @@ 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_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_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -530,16 +658,24 @@ 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_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_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
@@ -549,15 +685,14 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
@@ -568,28 +703,22 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_ASIC3 is not set
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_T7L66XB is not set
 # CONFIG_MFD_TC6387XB is not set
 # CONFIG_MFD_TC6393XB is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -612,17 +741,15 @@ 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_HID_PID is not set
 
 #
 # Special HID drivers
 #
-# CONFIG_HID_COMPAT 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_OHCI=y
 # CONFIG_USB_ARCH_HAS_EHCI is not set
 # CONFIG_USB is not set
 
@@ -631,9 +758,13 @@ 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
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 CONFIG_MMC=y
 CONFIG_MMC_DEBUG=y
 CONFIG_MMC_UNSAFE_RESUME=y
@@ -650,22 +781,24 @@ CONFIG_SDIO_UART=y
 # MMC/SD/SDIO Host Controller Drivers
 #
 CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_PLTFM is not set
 CONFIG_MMC_SDHCI_S3C=y
+# CONFIG_MMC_SDHCI_S3C_DMA is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
 
 #
-# Voltage and Current regulators
+# TI VLYNQ
 #
-# 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
@@ -674,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=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
@@ -683,9 +817,12 @@ 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_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -696,6 +833,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
@@ -719,10 +861,7 @@ CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
 # 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
@@ -731,12 +870,17 @@ CONFIG_TMPFS_POSIX_ACL=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
 # 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
 
@@ -755,6 +899,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -763,12 +908,16 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 CONFIG_DEBUG_RT_MUTEXES=y
 CONFIG_DEBUG_PI_LIST=y
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -787,34 +936,43 @@ 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_DEBUG_CREDENTIALS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_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_EARLY_PRINTK is not set
 # CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
 CONFIG_DEBUG_S3C_UART=0
 
 #
@@ -823,13 +981,19 @@ 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_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # 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
@@ -838,6 +1002,10 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/s5p6440_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/s5p6440_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/s5p6440_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/s5p6440_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,969 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc2
+# Sat Jan  9 16:33:55 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=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
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=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=y
+# CONFIG_UTS_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+CONFIG_ARCH_S5P6440=y
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_PLAT_SAMSUNG=y
+CONFIG_SAMSUNG_CLKSRC=y
+CONFIG_SAMSUNG_IRQ_VIC_TIMER=y
+CONFIG_SAMSUNG_IRQ_UART=y
+CONFIG_SAMSUNG_GPIO_EXTRA=0
+CONFIG_PLAT_S3C=y
+
+#
+# Boot options
+#
+CONFIG_S3C_BOOT_ERROR_RESET=y
+CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
+
+#
+# Power management
+#
+CONFIG_S3C_LOWLEVEL_UART_PORT=1
+CONFIG_S3C_GPIO_SPACE=0
+CONFIG_S3C_GPIO_TRACK=y
+CONFIG_PLAT_S5P=y
+CONFIG_CPU_S5P6440_INIT=y
+CONFIG_CPU_S5P6440_CLOCK=y
+CONFIG_CPU_S5P6440=y
+CONFIG_MACH_SMDK6440=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_V6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+# CONFIG_ARM_ERRATA_411920 is not set
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=200
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
+# 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
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+# 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_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
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=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
+# 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_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# 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_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_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_AD7879 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# 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_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_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
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+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_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_UARTS=4
+# CONFIG_SERIAL_SAMSUNG_DEBUG is not set
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_SERIAL_S5P6440=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
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR 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=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_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=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=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_RT_MUTEXES=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 is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_EARLY_PRINTK is not set
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
+CONFIG_DEBUG_S3C_UART=1
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/s5p6442_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/s5p6442_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/s5p6442_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/s5p6442_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,883 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc4
+# Mon Jan 25 08:50:28 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=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
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=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=y
+# CONFIG_UTS_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+CONFIG_ARCH_S5P6442=y
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_PLAT_SAMSUNG=y
+CONFIG_SAMSUNG_CLKSRC=y
+CONFIG_SAMSUNG_IRQ_VIC_TIMER=y
+CONFIG_SAMSUNG_IRQ_UART=y
+CONFIG_SAMSUNG_GPIOLIB_4BIT=y
+CONFIG_S3C_GPIO_CFG_S3C24XX=y
+CONFIG_S3C_GPIO_CFG_S3C64XX=y
+CONFIG_S3C_GPIO_PULL_UPDOWN=y
+CONFIG_SAMSUNG_GPIO_EXTRA=0
+# CONFIG_S3C_ADC is not set
+
+#
+# Power management
+#
+CONFIG_PLAT_S3C=y
+
+#
+# Boot options
+#
+# CONFIG_S3C_BOOT_ERROR_RESET is not set
+CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
+CONFIG_S3C_LOWLEVEL_UART_PORT=1
+CONFIG_S3C_GPIO_SPACE=0
+CONFIG_S3C_GPIO_TRACK=y
+CONFIG_PLAT_S5P=y
+CONFIG_CPU_S5P6442=y
+CONFIG_MACH_SMDK6442=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_V6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+# CONFIG_ARM_ERRATA_411920 is not set
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=200
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
+# 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
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+# 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_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=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
+# 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_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# 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_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP 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=y
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# 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_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_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
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+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_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_UARTS=3
+# CONFIG_SERIAL_SAMSUNG_DEBUG is not set
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_SERIAL_S5PV210=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
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_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=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=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+# CONFIG_MINIX_SUBPARTITION is not set
+CONFIG_SOLARIS_X86_PARTITION=y
+# 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=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_RT_MUTEXES=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 is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_EARLY_PRINTK is not set
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
+CONFIG_DEBUG_S3C_UART=1
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO 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 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/s5pc110_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/s5pc110_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/s5pc110_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/s5pc110_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,894 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc4
+# Wed Feb 24 15:36:54 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=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
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=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=y
+# CONFIG_UTS_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC1XX is not set
+CONFIG_ARCH_S5PV210=y
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_PLAT_SAMSUNG=y
+
+#
+# Boot options
+#
+# CONFIG_S3C_BOOT_ERROR_RESET is not set
+CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
+CONFIG_S3C_LOWLEVEL_UART_PORT=1
+CONFIG_SAMSUNG_CLKSRC=y
+CONFIG_SAMSUNG_IRQ_VIC_TIMER=y
+CONFIG_SAMSUNG_IRQ_UART=y
+CONFIG_SAMSUNG_GPIOLIB_4BIT=y
+CONFIG_S3C_GPIO_CFG_S3C24XX=y
+CONFIG_S3C_GPIO_CFG_S3C64XX=y
+CONFIG_S3C_GPIO_PULL_UPDOWN=y
+CONFIG_SAMSUNG_GPIO_EXTRA=0
+CONFIG_S3C_GPIO_SPACE=0
+CONFIG_S3C_GPIO_TRACK=y
+# CONFIG_S3C_ADC is not set
+
+#
+# Power management
+#
+CONFIG_PLAT_S5P=y
+CONFIG_CPU_S5PV210=y
+# CONFIG_MACH_SMDKV210 is not set
+CONFIG_MACH_SMDKC110=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=200
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=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
+# 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_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# 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_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP 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=y
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# 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_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_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
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+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_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_UARTS_4=y
+CONFIG_SERIAL_SAMSUNG_UARTS=4
+# CONFIG_SERIAL_SAMSUNG_DEBUG is not set
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_SERIAL_S5PV210=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
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_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=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=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+# CONFIG_MINIX_SUBPARTITION is not set
+CONFIG_SOLARIS_X86_PARTITION=y
+# 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=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_PREEMPT is not set
+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 is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
+CONFIG_DEBUG_S3C_UART=1
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO 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 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/configs/s5pv210_defconfig linux-libre-2.6.34-gnu1/arch/arm/configs/s5pv210_defconfig
--- linux-libre-2.6.33-gnu1/arch/arm/configs/s5pv210_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/configs/s5pv210_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,894 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc4
+# Wed Feb 24 15:36:16 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=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
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=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=y
+# CONFIG_UTS_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC1XX is not set
+CONFIG_ARCH_S5PV210=y
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_PLAT_SAMSUNG=y
+
+#
+# Boot options
+#
+# CONFIG_S3C_BOOT_ERROR_RESET is not set
+CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
+CONFIG_S3C_LOWLEVEL_UART_PORT=1
+CONFIG_SAMSUNG_CLKSRC=y
+CONFIG_SAMSUNG_IRQ_VIC_TIMER=y
+CONFIG_SAMSUNG_IRQ_UART=y
+CONFIG_SAMSUNG_GPIOLIB_4BIT=y
+CONFIG_S3C_GPIO_CFG_S3C24XX=y
+CONFIG_S3C_GPIO_CFG_S3C64XX=y
+CONFIG_S3C_GPIO_PULL_UPDOWN=y
+CONFIG_SAMSUNG_GPIO_EXTRA=0
+CONFIG_S3C_GPIO_SPACE=0
+CONFIG_S3C_GPIO_TRACK=y
+# CONFIG_S3C_ADC is not set
+
+#
+# Power management
+#
+CONFIG_PLAT_S5P=y
+CONFIG_CPU_S5PV210=y
+CONFIG_MACH_SMDKV210=y
+# CONFIG_MACH_SMDKC110 is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=200
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=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
+# 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_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# 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_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP 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=y
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# 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_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_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
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+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_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_UARTS_4=y
+CONFIG_SERIAL_SAMSUNG_UARTS=4
+# CONFIG_SERIAL_SAMSUNG_DEBUG is not set
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_SERIAL_S5PV210=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
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_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=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=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+# CONFIG_MINIX_SUBPARTITION is not set
+CONFIG_SOLARIS_X86_PARTITION=y
+# 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=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_PREEMPT is not set
+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 is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
+CONFIG_DEBUG_S3C_UART=1
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO 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 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/assembler.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/assembler.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/assembler.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/assembler.h	2010-05-16 17:17:36.000000000 -0400
@@ -149,10 +149,10 @@
 
 #define USER(x...)				\
 9999:	x;					\
-	.section __ex_table,"a";		\
+	.pushsection __ex_table,"a";		\
 	.align	3;				\
 	.long	9999b,9001f;			\
-	.previous
+	.popsection
 
 /*
  * SMP data memory barrier
@@ -193,10 +193,10 @@
 	.error	"Unsupported inc macro argument"
 	.endif
 
-	.section __ex_table,"a"
+	.pushsection __ex_table,"a"
 	.align	3
 	.long	9999b, \abort
-	.previous
+	.popsection
 	.endm
 
 	.macro	usracc, instr, reg, ptr, inc, cond, rept, abort
@@ -234,10 +234,10 @@
 	.error	"Unsupported inc macro argument"
 	.endif
 
-	.section __ex_table,"a"
+	.pushsection __ex_table,"a"
 	.align	3
 	.long	9999b, \abort
-	.previous
+	.popsection
 	.endr
 	.endm
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/atomic.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/atomic.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/atomic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/atomic.h	2010-05-16 17:17:36.000000000 -0400
@@ -235,6 +235,234 @@ static inline int atomic_add_unless(atom
 #define smp_mb__before_atomic_inc()	smp_mb()
 #define smp_mb__after_atomic_inc()	smp_mb()
 
+#ifndef CONFIG_GENERIC_ATOMIC64
+typedef struct {
+	u64 __aligned(8) counter;
+} atomic64_t;
+
+#define ATOMIC64_INIT(i) { (i) }
+
+static inline u64 atomic64_read(atomic64_t *v)
+{
+	u64 result;
+
+	__asm__ __volatile__("@ atomic64_read\n"
+"	ldrexd	%0, %H0, [%1]"
+	: "=&r" (result)
+	: "r" (&v->counter)
+	);
+
+	return result;
+}
+
+static inline void atomic64_set(atomic64_t *v, u64 i)
+{
+	u64 tmp;
+
+	__asm__ __volatile__("@ atomic64_set\n"
+"1:	ldrexd	%0, %H0, [%1]\n"
+"	strexd	%0, %2, %H2, [%1]\n"
+"	teq	%0, #0\n"
+"	bne	1b"
+	: "=&r" (tmp)
+	: "r" (&v->counter), "r" (i)
+	: "cc");
+}
+
+static inline void atomic64_add(u64 i, atomic64_t *v)
+{
+	u64 result;
+	unsigned long tmp;
+
+	__asm__ __volatile__("@ atomic64_add\n"
+"1:	ldrexd	%0, %H0, [%2]\n"
+"	adds	%0, %0, %3\n"
+"	adc	%H0, %H0, %H3\n"
+"	strexd	%1, %0, %H0, [%2]\n"
+"	teq	%1, #0\n"
+"	bne	1b"
+	: "=&r" (result), "=&r" (tmp)
+	: "r" (&v->counter), "r" (i)
+	: "cc");
+}
+
+static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
+{
+	u64 result;
+	unsigned long tmp;
+
+	smp_mb();
+
+	__asm__ __volatile__("@ atomic64_add_return\n"
+"1:	ldrexd	%0, %H0, [%2]\n"
+"	adds	%0, %0, %3\n"
+"	adc	%H0, %H0, %H3\n"
+"	strexd	%1, %0, %H0, [%2]\n"
+"	teq	%1, #0\n"
+"	bne	1b"
+	: "=&r" (result), "=&r" (tmp)
+	: "r" (&v->counter), "r" (i)
+	: "cc");
+
+	smp_mb();
+
+	return result;
+}
+
+static inline void atomic64_sub(u64 i, atomic64_t *v)
+{
+	u64 result;
+	unsigned long tmp;
+
+	__asm__ __volatile__("@ atomic64_sub\n"
+"1:	ldrexd	%0, %H0, [%2]\n"
+"	subs	%0, %0, %3\n"
+"	sbc	%H0, %H0, %H3\n"
+"	strexd	%1, %0, %H0, [%2]\n"
+"	teq	%1, #0\n"
+"	bne	1b"
+	: "=&r" (result), "=&r" (tmp)
+	: "r" (&v->counter), "r" (i)
+	: "cc");
+}
+
+static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
+{
+	u64 result;
+	unsigned long tmp;
+
+	smp_mb();
+
+	__asm__ __volatile__("@ atomic64_sub_return\n"
+"1:	ldrexd	%0, %H0, [%2]\n"
+"	subs	%0, %0, %3\n"
+"	sbc	%H0, %H0, %H3\n"
+"	strexd	%1, %0, %H0, [%2]\n"
+"	teq	%1, #0\n"
+"	bne	1b"
+	: "=&r" (result), "=&r" (tmp)
+	: "r" (&v->counter), "r" (i)
+	: "cc");
+
+	smp_mb();
+
+	return result;
+}
+
+static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new)
+{
+	u64 oldval;
+	unsigned long res;
+
+	smp_mb();
+
+	do {
+		__asm__ __volatile__("@ atomic64_cmpxchg\n"
+		"ldrexd		%1, %H1, [%2]\n"
+		"mov		%0, #0\n"
+		"teq		%1, %3\n"
+		"teqeq		%H1, %H3\n"
+		"strexdeq	%0, %4, %H4, [%2]"
+		: "=&r" (res), "=&r" (oldval)
+		: "r" (&ptr->counter), "r" (old), "r" (new)
+		: "cc");
+	} while (res);
+
+	smp_mb();
+
+	return oldval;
+}
+
+static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new)
+{
+	u64 result;
+	unsigned long tmp;
+
+	smp_mb();
+
+	__asm__ __volatile__("@ atomic64_xchg\n"
+"1:	ldrexd	%0, %H0, [%2]\n"
+"	strexd	%1, %3, %H3, [%2]\n"
+"	teq	%1, #0\n"
+"	bne	1b"
+	: "=&r" (result), "=&r" (tmp)
+	: "r" (&ptr->counter), "r" (new)
+	: "cc");
+
+	smp_mb();
+
+	return result;
+}
+
+static inline u64 atomic64_dec_if_positive(atomic64_t *v)
+{
+	u64 result;
+	unsigned long tmp;
+
+	smp_mb();
+
+	__asm__ __volatile__("@ atomic64_dec_if_positive\n"
+"1:	ldrexd	%0, %H0, [%2]\n"
+"	subs	%0, %0, #1\n"
+"	sbc	%H0, %H0, #0\n"
+"	teq	%H0, #0\n"
+"	bmi	2f\n"
+"	strexd	%1, %0, %H0, [%2]\n"
+"	teq	%1, #0\n"
+"	bne	1b\n"
+"2:"
+	: "=&r" (result), "=&r" (tmp)
+	: "r" (&v->counter)
+	: "cc");
+
+	smp_mb();
+
+	return result;
+}
+
+static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
+{
+	u64 val;
+	unsigned long tmp;
+	int ret = 1;
+
+	smp_mb();
+
+	__asm__ __volatile__("@ atomic64_add_unless\n"
+"1:	ldrexd	%0, %H0, [%3]\n"
+"	teq	%0, %4\n"
+"	teqeq	%H0, %H4\n"
+"	moveq	%1, #0\n"
+"	beq	2f\n"
+"	adds	%0, %0, %5\n"
+"	adc	%H0, %H0, %H5\n"
+"	strexd	%2, %0, %H0, [%3]\n"
+"	teq	%2, #0\n"
+"	bne	1b\n"
+"2:"
+	: "=&r" (val), "=&r" (ret), "=&r" (tmp)
+	: "r" (&v->counter), "r" (u), "r" (a)
+	: "cc");
+
+	if (ret)
+		smp_mb();
+
+	return ret;
+}
+
+#define atomic64_add_negative(a, v)	(atomic64_add_return((a), (v)) < 0)
+#define atomic64_inc(v)			atomic64_add(1LL, (v))
+#define atomic64_inc_return(v)		atomic64_add_return(1LL, (v))
+#define atomic64_inc_and_test(v)	(atomic64_inc_return(v) == 0)
+#define atomic64_sub_and_test(a, v)	(atomic64_sub_return((a), (v)) == 0)
+#define atomic64_dec(v)			atomic64_sub(1LL, (v))
+#define atomic64_dec_return(v)		atomic64_sub_return(1LL, (v))
+#define atomic64_dec_and_test(v)	(atomic64_dec_return((v)) == 0)
+#define atomic64_inc_not_zero(v)	atomic64_add_unless((v), 1LL, 0LL)
+
+#else /* !CONFIG_GENERIC_ATOMIC64 */
+#include <asm-generic/atomic64.h>
+#endif
 #include <asm-generic/atomic-long.h>
 #endif
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/cacheflush.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/cacheflush.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/cacheflush.h	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <asm/glue.h>
 #include <asm/shmparam.h>
 #include <asm/cachetype.h>
+#include <asm/outercache.h>
 
 #define CACHE_COLOUR(vaddr)	((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
 
@@ -197,21 +198,6 @@
  *	DMA Cache Coherency
  *	===================
  *
- *	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
- *
- *	dma_clean_range(start, end)
- *
- *		Clean (write back) the specified virtual address range.
- *		- start  - virtual start address
- *		- end    - virtual end address
- *
  *	dma_flush_range(start, end)
  *
  *		Clean and invalidate the specified virtual address range.
@@ -228,15 +214,10 @@ struct cpu_cache_fns {
 	void (*coherent_user_range)(unsigned long, unsigned long);
 	void (*flush_kern_dcache_area)(void *, size_t);
 
-	void (*dma_inv_range)(const void *, const void *);
-	void (*dma_clean_range)(const void *, const void *);
-	void (*dma_flush_range)(const void *, const void *);
-};
+	void (*dma_map_area)(const void *, size_t, int);
+	void (*dma_unmap_area)(const void *, size_t, int);
 
-struct outer_cache_fns {
-	void (*inv_range)(unsigned long, unsigned long);
-	void (*clean_range)(unsigned long, unsigned long);
-	void (*flush_range)(unsigned long, unsigned long);
+	void (*dma_flush_range)(const void *, const void *);
 };
 
 /*
@@ -259,8 +240,8 @@ extern struct cpu_cache_fns cpu_cache;
  * is visible to DMA, or data written by DMA to system memory is
  * visible to the CPU.
  */
-#define dmac_inv_range			cpu_cache.dma_inv_range
-#define dmac_clean_range		cpu_cache.dma_clean_range
+#define dmac_map_area			cpu_cache.dma_map_area
+#define dmac_unmap_area		cpu_cache.dma_unmap_area
 #define dmac_flush_range		cpu_cache.dma_flush_range
 
 #else
@@ -285,58 +266,23 @@ extern void __cpuc_flush_dcache_area(voi
  * is visible to DMA, or data written by DMA to system memory is
  * visible to the CPU.
  */
-#define dmac_inv_range			__glue(_CACHE,_dma_inv_range)
-#define dmac_clean_range		__glue(_CACHE,_dma_clean_range)
+#define dmac_map_area			__glue(_CACHE,_dma_map_area)
+#define dmac_unmap_area		__glue(_CACHE,_dma_unmap_area)
 #define dmac_flush_range		__glue(_CACHE,_dma_flush_range)
 
-extern void dmac_inv_range(const void *, const void *);
-extern void dmac_clean_range(const void *, const void *);
+extern void dmac_map_area(const void *, size_t, int);
+extern void dmac_unmap_area(const void *, size_t, int);
 extern void dmac_flush_range(const void *, const void *);
 
 #endif
 
-#ifdef CONFIG_OUTER_CACHE
-
-extern struct outer_cache_fns outer_cache;
-
-static inline void outer_inv_range(unsigned long start, unsigned long end)
-{
-	if (outer_cache.inv_range)
-		outer_cache.inv_range(start, end);
-}
-static inline void outer_clean_range(unsigned long start, unsigned long end)
-{
-	if (outer_cache.clean_range)
-		outer_cache.clean_range(start, end);
-}
-static inline void outer_flush_range(unsigned long start, unsigned long end)
-{
-	if (outer_cache.flush_range)
-		outer_cache.flush_range(start, end);
-}
-
-#else
-
-static inline void outer_inv_range(unsigned long start, unsigned long end)
-{ }
-static inline void outer_clean_range(unsigned long start, unsigned long end)
-{ }
-static inline void outer_flush_range(unsigned long start, unsigned long end)
-{ }
-
-#endif
-
 /*
  * Copy user data from/to a page which is mapped into a different
  * processes address space.  Really, we want to allow our "user
  * space" model to handle this.
  */
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-	do {							\
-		memcpy(dst, src, len);				\
-		flush_ptrace_access(vma, page, vaddr, dst, len, 1);\
-	} while (0)
-
+extern void copy_to_user_page(struct vm_area_struct *, struct page *,
+	unsigned long, void *, const void *, unsigned long);
 #define copy_from_user_page(vma, page, vaddr, dst, src, len) \
 	do {							\
 		memcpy(dst, src, len);				\
@@ -370,17 +316,6 @@ vivt_flush_cache_page(struct vm_area_str
 	}
 }
 
-static inline void
-vivt_flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
-			 unsigned long uaddr, void *kaddr,
-			 unsigned long len, int write)
-{
-	if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
-		unsigned long addr = (unsigned long)kaddr;
-		__cpuc_coherent_kern_range(addr, addr + len);
-	}
-}
-
 #ifndef CONFIG_CPU_CACHE_VIPT
 #define flush_cache_mm(mm) \
 		vivt_flush_cache_mm(mm)
@@ -388,15 +323,10 @@ vivt_flush_ptrace_access(struct vm_area_
 		vivt_flush_cache_range(vma,start,end)
 #define flush_cache_page(vma,addr,pfn) \
 		vivt_flush_cache_page(vma,addr,pfn)
-#define flush_ptrace_access(vma,page,ua,ka,len,write) \
-		vivt_flush_ptrace_access(vma,page,ua,ka,len,write)
 #else
 extern void flush_cache_mm(struct mm_struct *mm);
 extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
 extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn);
-extern void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
-				unsigned long uaddr, void *kaddr,
-				unsigned long len, int write);
 #endif
 
 #define flush_cache_dup_mm(mm) flush_cache_mm(mm)
@@ -441,12 +371,26 @@ static inline void __flush_icache_all(vo
 #ifdef CONFIG_ARM_ERRATA_411920
 	extern void v6_icache_inval_all(void);
 	v6_icache_inval_all();
+#elif defined(CONFIG_SMP) && __LINUX_ARM_ARCH__ >= 7
+	asm("mcr	p15, 0, %0, c7, c1, 0	@ invalidate I-cache inner shareable\n"
+	    :
+	    : "r" (0));
 #else
 	asm("mcr	p15, 0, %0, c7, c5, 0	@ invalidate I-cache\n"
 	    :
 	    : "r" (0));
 #endif
 }
+static inline void flush_kernel_vmap_range(void *addr, int size)
+{
+	if ((cache_is_vivt() || cache_is_vipt_aliasing()))
+	  __cpuc_flush_dcache_area(addr, (size_t)size);
+}
+static inline void invalidate_kernel_vmap_range(void *addr, int size)
+{
+	if ((cache_is_vivt() || cache_is_vipt_aliasing()))
+	  __cpuc_flush_dcache_area(addr, (size_t)size);
+}
 
 #define ARCH_HAS_FLUSH_ANON_PAGE
 static inline void flush_anon_page(struct vm_area_struct *vma,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/clkdev.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/clkdev.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/clkdev.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/clkdev.h	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #define __ASM_CLKDEV_H
 
 struct clk;
+struct device;
 
 struct clk_lookup {
 	struct list_head	node;
@@ -27,4 +28,7 @@ struct clk_lookup *clkdev_alloc(struct c
 void clkdev_add(struct clk_lookup *cl);
 void clkdev_drop(struct clk_lookup *cl);
 
+void clkdev_add_table(struct clk_lookup *, size_t);
+int clk_add_alias(const char *, const char *, char *, struct device *);
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/dma-mapping.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/dma-mapping.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/dma-mapping.h	2010-05-16 17:17:36.000000000 -0400
@@ -57,18 +57,58 @@ static inline dma_addr_t virt_to_dma(str
 #endif
 
 /*
- * DMA-consistent mapping functions.  These allocate/free a region of
- * uncached, unwrite-buffered mapped memory space for use with DMA
- * devices.  This is the "generic" version.  The PCI specific version
- * is in pci.h
+ * The DMA API is built upon the notion of "buffer ownership".  A buffer
+ * is either exclusively owned by the CPU (and therefore may be accessed
+ * by it) or exclusively owned by the DMA device.  These helper functions
+ * represent the transitions between these two ownership states.
  *
- * Note: Drivers should NOT use this function directly, as it will break
- * platforms with CONFIG_DMABOUNCE.
- * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
+ * Note, however, that on later ARMs, this notion does not work due to
+ * speculative prefetches.  We model our approach on the assumption that
+ * the CPU does do speculative prefetches, which means we clean caches
+ * before transfers and delay cache invalidation until transfer completion.
+ *
+ * Private support functions: these are not part of the API and are
+ * liable to change.  Drivers must not use these.
  */
-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);
+static inline void __dma_single_cpu_to_dev(const void *kaddr, size_t size,
+	enum dma_data_direction dir)
+{
+	extern void ___dma_single_cpu_to_dev(const void *, size_t,
+		enum dma_data_direction);
+
+	if (!arch_is_coherent())
+		___dma_single_cpu_to_dev(kaddr, size, dir);
+}
+
+static inline void __dma_single_dev_to_cpu(const void *kaddr, size_t size,
+	enum dma_data_direction dir)
+{
+	extern void ___dma_single_dev_to_cpu(const void *, size_t,
+		enum dma_data_direction);
+
+	if (!arch_is_coherent())
+		___dma_single_dev_to_cpu(kaddr, size, dir);
+}
+
+static inline void __dma_page_cpu_to_dev(struct page *page, unsigned long off,
+	size_t size, enum dma_data_direction dir)
+{
+	extern void ___dma_page_cpu_to_dev(struct page *, unsigned long,
+		size_t, enum dma_data_direction);
+
+	if (!arch_is_coherent())
+		___dma_page_cpu_to_dev(page, off, size, dir);
+}
+
+static inline void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
+	size_t size, enum dma_data_direction dir)
+{
+	extern void ___dma_page_dev_to_cpu(struct page *, unsigned long,
+		size_t, enum dma_data_direction);
+
+	if (!arch_is_coherent())
+		___dma_page_dev_to_cpu(page, off, size, dir);
+}
 
 /*
  * Return whether the given device DMA address mask can be supported
@@ -88,6 +128,14 @@ static inline int dma_supported(struct d
 
 static inline int dma_set_mask(struct device *dev, u64 dma_mask)
 {
+#ifdef CONFIG_DMABOUNCE
+	if (dev->archdata.dmabounce) {
+		if (dma_mask >= ISA_DMA_THRESHOLD)
+			return 0;
+		else
+			return -EIO;
+	}
+#endif
 	if (!dev->dma_mask || !dma_supported(dev, dma_mask))
 		return -EIO;
 
@@ -304,8 +352,7 @@ static inline dma_addr_t dma_map_single(
 {
 	BUG_ON(!valid_dma_direction(dir));
 
-	if (!arch_is_coherent())
-		dma_cache_maint(cpu_addr, size, dir);
+	__dma_single_cpu_to_dev(cpu_addr, size, dir);
 
 	return virt_to_dma(dev, cpu_addr);
 }
@@ -329,8 +376,7 @@ static inline dma_addr_t dma_map_page(st
 {
 	BUG_ON(!valid_dma_direction(dir));
 
-	if (!arch_is_coherent())
-		dma_cache_maint_page(page, offset, size, dir);
+	__dma_page_cpu_to_dev(page, offset, size, dir);
 
 	return page_to_dma(dev, page) + offset;
 }
@@ -352,7 +398,7 @@ static inline dma_addr_t dma_map_page(st
 static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
 		size_t size, enum dma_data_direction dir)
 {
-	/* nothing to do */
+	__dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir);
 }
 
 /**
@@ -372,7 +418,8 @@ static inline void dma_unmap_single(stru
 static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
 		size_t size, enum dma_data_direction dir)
 {
-	/* nothing to do */
+	__dma_page_dev_to_cpu(dma_to_page(dev, handle), handle & ~PAGE_MASK,
+		size, dir);
 }
 #endif /* CONFIG_DMABOUNCE */
 
@@ -400,7 +447,10 @@ static inline void dma_sync_single_range
 {
 	BUG_ON(!valid_dma_direction(dir));
 
-	dmabounce_sync_for_cpu(dev, handle, offset, size, dir);
+	if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir))
+		return;
+
+	__dma_single_dev_to_cpu(dma_to_virt(dev, handle) + offset, size, dir);
 }
 
 static inline void dma_sync_single_range_for_device(struct device *dev,
@@ -412,8 +462,7 @@ static inline void dma_sync_single_range
 	if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
 		return;
 
-	if (!arch_is_coherent())
-		dma_cache_maint(dma_to_virt(dev, handle) + offset, size, dir);
+	__dma_single_cpu_to_dev(dma_to_virt(dev, handle) + offset, size, dir);
 }
 
 static inline void dma_sync_single_for_cpu(struct device *dev,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/elf.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/elf.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/elf.h	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,8 @@
 #include <asm/ptrace.h>
 #include <asm/user.h>
 
+struct task_struct;
+
 typedef unsigned long elf_greg_t;
 typedef unsigned long elf_freg_t[3];
 
@@ -98,6 +100,7 @@ extern int elf_check_arch(const struct e
 extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int);
 #define elf_read_implies_exec(ex,stk) arm_elf_read_implies_exec(&(ex), stk)
 
+struct task_struct;
 int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
 #define ELF_CORE_COPY_TASK_REGS dump_task_regs
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/entry-macro-vic2.S linux-libre-2.6.34-gnu1/arch/arm/include/asm/entry-macro-vic2.S
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/entry-macro-vic2.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/entry-macro-vic2.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,57 @@
+/* arch/arm/include/asm/entry-macro-vic2.S
+ *
+ * Originally arch/arm/mach-s3c6400/include/mach/entry-macro.S
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Low-level IRQ helper macros for a device with two VICs
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+*/
+
+/* This should be included from <mach/entry-macro.S> with the necessary
+ * defines for virtual addresses and IRQ bases for the two vics.
+ *
+ * The code needs the following defined:
+ *	IRQ_VIC0_BASE	IRQ number of VIC0's first IRQ
+ *	IRQ_VIC1_BASE	IRQ number of VIC1's first IRQ
+ *	VA_VIC0		Virtual address of VIC0
+ *	VA_VIC1		Virtual address of VIC1
+ *
+ * Note, code assumes VIC0's virtual address is an ARM immediate constant
+ * away from VIC1.
+*/
+
+#include <asm/hardware/vic.h>
+
+	.macro	disable_fiq
+	.endm
+
+	.macro	get_irqnr_preamble, base, tmp
+	ldr	\base, =VA_VIC0
+	.endm
+
+	.macro	arch_ret_to_user, tmp1, tmp2
+	.endm
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+	@ check the vic0
+	mov	\irqnr, #IRQ_VIC0_BASE + 31
+	ldr	\irqstat, [ \base, # VIC_IRQ_STATUS ]
+	teq	\irqstat, #0
+
+	@ otherwise try vic1
+	addeq	\tmp, \base, #(VA_VIC1 - VA_VIC0)
+	addeq	\irqnr, \irqnr, #(IRQ_VIC1_BASE - IRQ_VIC0_BASE)
+	ldreq	\irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+	teqeq	\irqstat, #0
+
+	clzne	\irqstat, \irqstat
+	subne	\irqnr, \irqnr, \irqstat
+	.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/futex.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/futex.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/futex.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/futex.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,14 +21,14 @@
 	"2:	strt	%0, [%2]\n"				\
 	"	mov	%0, #0\n"				\
 	"3:\n"							\
-	"	.section __ex_table,\"a\"\n"			\
+	"	.pushsection __ex_table,\"a\"\n"		\
 	"	.align	3\n"					\
 	"	.long	1b, 4f, 2b, 4f\n"			\
-	"	.previous\n"					\
-	"	.section .fixup,\"ax\"\n"			\
+	"	.popsection\n"					\
+	"	.pushsection .fixup,\"ax\"\n"			\
 	"4:	mov	%0, %4\n"				\
 	"	b	3b\n"					\
-	"	.previous"					\
+	"	.popsection"					\
 	: "=&r" (ret), "=&r" (oldval)				\
 	: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT)		\
 	: "cc", "memory")
@@ -102,14 +102,14 @@ futex_atomic_cmpxchg_inatomic(int __user
 	"	it	eq	@ explicit IT needed for the 2b label\n"
 	"2:	streqt	%2, [%3]\n"
 	"3:\n"
-	"	.section __ex_table,\"a\"\n"
+	"	.pushsection __ex_table,\"a\"\n"
 	"	.align	3\n"
 	"	.long	1b, 4f, 2b, 4f\n"
-	"	.previous\n"
-	"	.section .fixup,\"ax\"\n"
+	"	.popsection\n"
+	"	.pushsection .fixup,\"ax\"\n"
 	"4:	mov	%0, %4\n"
 	"	b	3b\n"
-	"	.previous"
+	"	.popsection"
 	: "=&r" (val)
 	: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
 	: "cc", "memory");
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/hardware/iop3xx-adma.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/hardware/iop3xx-adma.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/hardware/iop3xx-adma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/hardware/iop3xx-adma.h	2010-05-16 17:17:36.000000000 -0400
@@ -366,8 +366,7 @@ static inline int iop_chan_xor_slot_coun
 		slot_cnt += *slots_per_op;
 	}
 
-	if (len)
-		slot_cnt += *slots_per_op;
+	slot_cnt += *slots_per_op;
 
 	return slot_cnt;
 }
@@ -389,8 +388,7 @@ static inline int iop_chan_zero_sum_slot
 		slot_cnt += *slots_per_op;
 	}
 
-	if (len)
-		slot_cnt += *slots_per_op;
+	slot_cnt += *slots_per_op;
 
 	return slot_cnt;
 }
@@ -737,10 +735,8 @@ iop_desc_set_zero_sum_byte_count(struct
 			i += slots_per_op;
 		} while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT);
 
-		if (len) {
-			iter = iop_hw_desc_slot_idx(hw_desc, i);
-			iter->byte_count = len;
-		}
+		iter = iop_hw_desc_slot_idx(hw_desc, i);
+		iter->byte_count = len;
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/hardware/it8152.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/hardware/it8152.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/hardware/it8152.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/hardware/it8152.h	2010-05-16 17:17:36.000000000 -0400
@@ -75,6 +75,18 @@ extern unsigned long it8152_base_address
   IT8152_PD_IRQ(1)  USB (USBR)
   IT8152_PD_IRQ(0)  Audio controller (ACR)
  */
+#define IT8152_IRQ(x)   (IRQ_BOARD_END + (x))
+
+/* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */
+#define IT8152_LD_IRQ_COUNT     9
+#define IT8152_LP_IRQ_COUNT     16
+#define IT8152_PD_IRQ_COUNT     15
+
+/* Priorities: */
+#define IT8152_PD_IRQ(i)        IT8152_IRQ(i)
+#define IT8152_LP_IRQ(i)        (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT)
+#define IT8152_LD_IRQ(i)        (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT + IT8152_LP_IRQ_COUNT)
+
 /* frequently used interrupts */
 #define IT8152_PCISERR		IT8152_PD_IRQ(14)
 #define IT8152_H2PTADR		IT8152_PD_IRQ(13)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/hardware/locomo.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/hardware/locomo.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/hardware/locomo.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/hardware/locomo.h	2010-05-16 17:17:36.000000000 -0400
@@ -214,4 +214,8 @@ void locomo_m62332_senddata(struct locom
 /* Frontlight control */
 void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf);
 
+struct locomo_platform_data {
+	int	irq_base;	/* IRQ base for cascaded on-chip IRQs */
+};
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/hardware/sa1111.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/hardware/sa1111.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/hardware/sa1111.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/hardware/sa1111.h	2010-05-16 17:17:36.000000000 -0400
@@ -578,4 +578,8 @@ void sa1111_set_io_dir(struct sa1111_dev
 void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
 void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
 
+struct sa1111_platform_data {
+	int	irq_base;	/* base for cascaded on-chip IRQs */
+};
+
 #endif  /* _ASM_ARCH_SA1111 */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/highmem.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/highmem.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/highmem.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/highmem.h	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,11 @@
 
 #define kmap_prot		PAGE_KERNEL
 
-#define flush_cache_kmaps()	flush_cache_all()
+#define flush_cache_kmaps() \
+	do { \
+		if (cache_is_vivt()) \
+			flush_cache_all(); \
+	} while (0)
 
 extern pte_t *pkmap_page_table;
 
@@ -21,11 +25,20 @@ 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_high_l1_vipt(struct page *page, pte_t *saved_pte);
+extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte);
+
+/*
+ * The following functions are already defined by <linux/highmem.h>
+ * when CONFIG_HIGHMEM is not set.
+ */
+#ifdef CONFIG_HIGHMEM
 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
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/io.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/io.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/io.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/io.h	2010-05-16 17:17:36.000000000 -0400
@@ -69,9 +69,16 @@ extern void __raw_readsl(const void __io
 /*
  * __arm_ioremap takes CPU physical address.
  * __arm_ioremap_pfn takes a Page Frame Number and an offset into that page
+ * The _caller variety takes a __builtin_return_address(0) value for
+ * /proc/vmalloc to use - and should only be used in non-inline functions.
  */
-extern void __iomem * __arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int);
-extern void __iomem * __arm_ioremap(unsigned long, size_t, unsigned int);
+extern void __iomem *__arm_ioremap_pfn_caller(unsigned long, unsigned long,
+	size_t, unsigned int, void *);
+extern void __iomem *__arm_ioremap_caller(unsigned long, size_t, unsigned int,
+	void *);
+
+extern void __iomem *__arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int);
+extern void __iomem *__arm_ioremap(unsigned long, size_t, unsigned int);
 extern void __iounmap(volatile void __iomem *addr);
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/irq.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/irq.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/irq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 
 #ifndef __ASSEMBLY__
 struct irqaction;
+struct pt_regs;
 extern void migrate_irqs(void);
 
 extern void asm_do_IRQ(unsigned int, struct pt_regs *);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/kmap_types.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/kmap_types.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/kmap_types.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/kmap_types.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@ enum km_type {
 	KM_IRQ1,
 	KM_SOFTIRQ0,
 	KM_SOFTIRQ1,
+	KM_L1_CACHE,
 	KM_L2_CACHE,
 	KM_TYPE_NR
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/mach/time.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/mach/time.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/mach/time.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/mach/time.h	2010-05-16 17:17:36.000000000 -0400
@@ -46,12 +46,4 @@ struct sys_timer {
 extern struct sys_timer *system_timer;
 extern void timer_tick(void);
 
-/*
- * Kernel time keeping support.
- */
-struct timespec;
-extern int (*set_rtc)(void);
-extern void save_time_delta(struct timespec *delta, struct timespec *rtc);
-extern void restore_time_delta(struct timespec *delta, struct timespec *rtc);
-
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/memory.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/memory.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/memory.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/memory.h	2010-05-16 17:17:36.000000000 -0400
@@ -76,6 +76,17 @@
  */
 #define IOREMAP_MAX_ORDER	24
 
+/*
+ * Size of DMA-consistent memory region.  Must be multiple of 2M,
+ * between 2MB and 14MB inclusive.
+ */
+#ifndef CONSISTENT_DMA_SIZE
+#define CONSISTENT_DMA_SIZE 	SZ_2M
+#endif
+
+#define CONSISTENT_END		(0xffe00000UL)
+#define CONSISTENT_BASE		(CONSISTENT_END - CONSISTENT_DMA_SIZE)
+
 #else /* CONFIG_MMU */
 
 /*
@@ -93,11 +104,11 @@
 #endif
 
 #ifndef PHYS_OFFSET
-#define PHYS_OFFSET 		(CONFIG_DRAM_BASE)
+#define PHYS_OFFSET 		UL(CONFIG_DRAM_BASE)
 #endif
 
 #ifndef END_MEM
-#define END_MEM     		(CONFIG_DRAM_BASE + CONFIG_DRAM_SIZE)
+#define END_MEM     		(UL(CONFIG_DRAM_BASE) + CONFIG_DRAM_SIZE)
 #endif
 
 #ifndef PAGE_OFFSET
@@ -113,14 +124,6 @@
 #endif /* !CONFIG_MMU */
 
 /*
- * Size of DMA-consistent memory region.  Must be multiple of 2M,
- * between 2MB and 14MB inclusive.
- */
-#ifndef CONSISTENT_DMA_SIZE
-#define CONSISTENT_DMA_SIZE SZ_2M
-#endif
-
-/*
  * Physical vs virtual RAM address space conversion.  These are
  * private definitions which should NOT be used outside memory.h
  * files.  Use virt_to_phys/phys_to_virt/__pa/__va instead.
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/mmu_context.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/mmu_context.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/mmu_context.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/mmu_context.h	2010-05-16 17:17:36.000000000 -0400
@@ -43,12 +43,23 @@ void __check_kvm_seq(struct mm_struct *m
 #define ASID_FIRST_VERSION	(1 << ASID_BITS)
 
 extern unsigned int cpu_last_asid;
+#ifdef CONFIG_SMP
+DECLARE_PER_CPU(struct mm_struct *, current_mm);
+#endif
 
 void __init_new_context(struct task_struct *tsk, struct mm_struct *mm);
 void __new_context(struct mm_struct *mm);
 
 static inline void check_context(struct mm_struct *mm)
 {
+	/*
+	 * This code is executed with interrupts enabled. Therefore,
+	 * mm->context.id cannot be updated to the latest ASID version
+	 * on a different CPU (and condition below not triggered)
+	 * without first getting an IPI to reset the context. The
+	 * alternative is to take a read_lock on mm->context.id_lock
+	 * (after changing its type to rwlock_t).
+	 */
 	if (unlikely((mm->context.id ^ cpu_last_asid) >> ASID_BITS))
 		__new_context(mm);
 
@@ -108,6 +119,10 @@ switch_mm(struct mm_struct *prev, struct
 		__flush_icache_all();
 #endif
 	if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) {
+#ifdef CONFIG_SMP
+		struct mm_struct **crt_mm = &per_cpu(current_mm, cpu);
+		*crt_mm = next;
+#endif
 		check_context(next);
 		cpu_switch_mm(next->pgd, next);
 		if (cache_is_vivt())
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/mmu.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/mmu.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/mmu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/mmu.h	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
 typedef struct {
 #ifdef CONFIG_CPU_HAS_ASID
 	unsigned int id;
+	spinlock_t id_lock;
 #endif
 	unsigned int kvm_seq;
 } mm_context_t;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/outercache.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/outercache.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/outercache.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/outercache.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,75 @@
+/*
+ * arch/arm/include/asm/outercache.h
+ *
+ * Copyright (C) 2010 ARM Ltd.
+ * Written by Catalin Marinas <catalin.marinas@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_OUTERCACHE_H
+#define __ASM_OUTERCACHE_H
+
+struct outer_cache_fns {
+	void (*inv_range)(unsigned long, unsigned long);
+	void (*clean_range)(unsigned long, unsigned long);
+	void (*flush_range)(unsigned long, unsigned long);
+#ifdef CONFIG_OUTER_CACHE_SYNC
+	void (*sync)(void);
+#endif
+};
+
+#ifdef CONFIG_OUTER_CACHE
+
+extern struct outer_cache_fns outer_cache;
+
+static inline void outer_inv_range(unsigned long start, unsigned long end)
+{
+	if (outer_cache.inv_range)
+		outer_cache.inv_range(start, end);
+}
+static inline void outer_clean_range(unsigned long start, unsigned long end)
+{
+	if (outer_cache.clean_range)
+		outer_cache.clean_range(start, end);
+}
+static inline void outer_flush_range(unsigned long start, unsigned long end)
+{
+	if (outer_cache.flush_range)
+		outer_cache.flush_range(start, end);
+}
+
+#else
+
+static inline void outer_inv_range(unsigned long start, unsigned long end)
+{ }
+static inline void outer_clean_range(unsigned long start, unsigned long end)
+{ }
+static inline void outer_flush_range(unsigned long start, unsigned long end)
+{ }
+
+#endif
+
+#ifdef CONFIG_OUTER_CACHE_SYNC
+static inline void outer_sync(void)
+{
+	if (outer_cache.sync)
+		outer_cache.sync();
+}
+#else
+static inline void outer_sync(void)
+{ }
+#endif
+
+#endif	/* __ASM_OUTERCACHE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/page.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/page.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/page.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/page.h	2010-05-16 17:17:36.000000000 -0400
@@ -117,11 +117,12 @@
 #endif
 
 struct page;
+struct vm_area_struct;
 
 struct cpu_user_fns {
 	void (*cpu_clear_user_highpage)(struct page *page, unsigned long vaddr);
 	void (*cpu_copy_user_highpage)(struct page *to, struct page *from,
-			unsigned long vaddr);
+			unsigned long vaddr, struct vm_area_struct *vma);
 };
 
 #ifdef MULTI_USER
@@ -137,7 +138,7 @@ extern struct cpu_user_fns cpu_user;
 
 extern void __cpu_clear_user_highpage(struct page *page, unsigned long vaddr);
 extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
-			unsigned long vaddr);
+			unsigned long vaddr, struct vm_area_struct *vma);
 #endif
 
 #define clear_user_highpage(page,vaddr)		\
@@ -145,7 +146,7 @@ extern void __cpu_copy_user_highpage(str
 
 #define __HAVE_ARCH_COPY_USER_HIGHPAGE
 #define copy_user_highpage(to,from,vaddr,vma)	\
-	__cpu_copy_user_highpage(to, from, vaddr)
+	__cpu_copy_user_highpage(to, from, vaddr, vma)
 
 #define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
 extern void copy_page(void *to, const void *from);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/pci.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/pci.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,17 +30,6 @@ static inline void pcibios_penalize_isa_
  */
 #define PCI_DMA_BUS_IS_PHYS     (1)
 
-/*
- * Whether pci_unmap_{single,page} is a nop depends upon the
- * configuration.
- */
-#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_PCI
 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 					enum pci_dma_burst_strategy *strat,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/perf_event.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/perf_event.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/perf_event.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/perf_event.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,31 @@
+/*
+ *  linux/arch/arm/include/asm/perf_event.h
+ *
+ *  Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ARM_PERF_EVENT_H__
+#define __ARM_PERF_EVENT_H__
+
+/*
+ * NOP: on *most* (read: all supported) ARM platforms, the performance
+ * counter interrupts are regular interrupts and not an NMI. This
+ * means that when we receive the interrupt we can call
+ * perf_event_do_pending() that handles all of the work with
+ * interrupts enabled.
+ */
+static inline void
+set_perf_event_pending(void)
+{
+}
+
+/* ARM performance counters start from 1 (in the cp15 accesses) so use the
+ * same indexes here for consistency. */
+#define PERF_EVENT_INDEX_OFFSET 1
+
+#endif /* __ARM_PERF_EVENT_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/pgtable-nommu.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/pgtable-nommu.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/pgtable-nommu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/pgtable-nommu.h	2010-05-16 17:17:36.000000000 -0400
@@ -67,6 +67,7 @@ static inline int pte_file(pte_t pte) {
  */
 #define pgprot_noncached(prot)	__pgprot(0)
 #define pgprot_writecombine(prot) __pgprot(0)
+#define pgprot_dmacoherent(prot) __pgprot(0)
 
 
 /*
@@ -86,8 +87,8 @@ extern unsigned int kobjsize(const void
  * All 32bit addresses are effectively valid for vmalloc...
  * Sort of meaningless for non-VM targets.
  */
-#define	VMALLOC_START	0
-#define	VMALLOC_END	0xffffffff
+#define	VMALLOC_START	0UL
+#define	VMALLOC_END	0xffffffffUL
 
 #define FIRST_USER_ADDRESS      (0)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/pmu.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/pmu.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/pmu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/pmu.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,75 @@
+/*
+ *  linux/arch/arm/include/asm/pmu.h
+ *
+ *  Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ARM_PMU_H__
+#define __ARM_PMU_H__
+
+#ifdef CONFIG_CPU_HAS_PMU
+
+struct pmu_irqs {
+	const int   *irqs;
+	int	    num_irqs;
+};
+
+/**
+ * reserve_pmu() - reserve the hardware performance counters
+ *
+ * Reserve the hardware performance counters in the system for exclusive use.
+ * The 'struct pmu_irqs' for the system is returned on success, ERR_PTR()
+ * encoded error on failure.
+ */
+extern const struct pmu_irqs *
+reserve_pmu(void);
+
+/**
+ * release_pmu() - Relinquish control of the performance counters
+ *
+ * Release the performance counters and allow someone else to use them.
+ * Callers must have disabled the counters and released IRQs before calling
+ * this. The 'struct pmu_irqs' returned from reserve_pmu() must be passed as
+ * a cookie.
+ */
+extern int
+release_pmu(const struct pmu_irqs *irqs);
+
+/**
+ * init_pmu() - Initialise the PMU.
+ *
+ * Initialise the system ready for PMU enabling. This should typically set the
+ * IRQ affinity and nothing else. The users (oprofile/perf events etc) will do
+ * the actual hardware initialisation.
+ */
+extern int
+init_pmu(void);
+
+#else /* CONFIG_CPU_HAS_PMU */
+
+static inline const struct pmu_irqs *
+reserve_pmu(void)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline int
+release_pmu(const struct pmu_irqs *irqs)
+{
+	return -ENODEV;
+}
+
+static inline int
+init_pmu(void)
+{
+	return -ENODEV;
+}
+
+#endif /* CONFIG_CPU_HAS_PMU */
+
+#endif /* __ARM_PMU_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -128,6 +128,8 @@ struct pt_regs {
 
 #ifdef __KERNEL__
 
+#define arch_has_single_step()	(1)
+
 #define user_mode(regs)	\
 	(((regs)->ARM_cpsr & 0xf) == 0)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/setup.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/setup.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/setup.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/setup.h	2010-05-16 17:17:36.000000000 -0400
@@ -223,18 +223,6 @@ extern struct meminfo meminfo;
 #define bank_phys_end(bank)	((bank)->start + (bank)->size)
 #define bank_phys_size(bank)	(bank)->size
 
-/*
- * Early command line parameters.
- */
-struct early_params {
-	const char *arg;
-	void (*fn)(char **p);
-};
-
-#define __early_param(name,fn)					\
-static struct early_params __early_##fn __used			\
-__attribute__((__section__(".early_param.init"))) = { name, fn }
-
 #endif  /*  __KERNEL__  */
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/smp_plat.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/smp_plat.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/smp_plat.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/smp_plat.h	2010-05-16 17:17:36.000000000 -0400
@@ -13,4 +13,9 @@ static inline int tlb_ops_need_broadcast
 	return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
 }
 
+static inline int cache_ops_need_broadcast(void)
+{
+	return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1;
+}
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/smp_twd.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/smp_twd.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/smp_twd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/smp_twd.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,23 @@
 #ifndef __ASMARM_SMP_TWD_H
 #define __ASMARM_SMP_TWD_H
 
+#define TWD_TIMER_LOAD			0x00
+#define TWD_TIMER_COUNTER		0x04
+#define TWD_TIMER_CONTROL		0x08
+#define TWD_TIMER_INTSTAT		0x0C
+
+#define TWD_WDOG_LOAD			0x20
+#define TWD_WDOG_COUNTER		0x24
+#define TWD_WDOG_CONTROL		0x28
+#define TWD_WDOG_INTSTAT		0x2C
+#define TWD_WDOG_RESETSTAT		0x30
+#define TWD_WDOG_DISABLE		0x34
+
+#define TWD_TIMER_CONTROL_ENABLE	(1 << 0)
+#define TWD_TIMER_CONTROL_ONESHOT	(0 << 1)
+#define TWD_TIMER_CONTROL_PERIODIC	(1 << 1)
+#define TWD_TIMER_CONTROL_IT_ENABLE	(1 << 2)
+
 struct clock_event_device;
 
 extern void __iomem *twd_base;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/spinlock.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/spinlock.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/spinlock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/spinlock.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,22 @@
 #error SMP not supported on pre-ARMv6 CPUs
 #endif
 
+static inline void dsb_sev(void)
+{
+#if __LINUX_ARM_ARCH__ >= 7
+	__asm__ __volatile__ (
+		"dsb\n"
+		"sev"
+	);
+#elif defined(CONFIG_CPU_32v6K)
+	__asm__ __volatile__ (
+		"mcr p15, 0, %0, c7, c10, 4\n"
+		"sev"
+		: : "r" (0)
+	);
+#endif
+}
+
 /*
  * ARMv6 Spin-locking.
  *
@@ -69,13 +85,11 @@ static inline void arch_spin_unlock(arch
 
 	__asm__ __volatile__(
 "	str	%1, [%0]\n"
-#ifdef CONFIG_CPU_32v6K
-"	mcr	p15, 0, %1, c7, c10, 4\n" /* DSB */
-"	sev"
-#endif
 	:
 	: "r" (&lock->lock), "r" (0)
 	: "cc");
+
+	dsb_sev();
 }
 
 /*
@@ -132,13 +146,11 @@ static inline void arch_write_unlock(arc
 
 	__asm__ __volatile__(
 	"str	%1, [%0]\n"
-#ifdef CONFIG_CPU_32v6K
-"	mcr	p15, 0, %1, c7, c10, 4\n" /* DSB */
-"	sev\n"
-#endif
 	:
 	: "r" (&rw->lock), "r" (0)
 	: "cc");
+
+	dsb_sev();
 }
 
 /* write_can_lock - would write_trylock() succeed? */
@@ -188,14 +200,12 @@ static inline void arch_read_unlock(arch
 "	strex	%1, %0, [%2]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
-#ifdef CONFIG_CPU_32v6K
-"\n	cmp	%0, #0\n"
-"	mcreq   p15, 0, %0, c7, c10, 4\n"
-"	seveq"
-#endif
 	: "=&r" (tmp), "=&r" (tmp2)
 	: "r" (&rw->lock)
 	: "cc");
+
+	if (tmp == 0)
+		dsb_sev();
 }
 
 static inline int arch_read_trylock(arch_rwlock_t *rw)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/system.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/system.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/system.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -60,6 +60,8 @@
 #include <linux/linkage.h>
 #include <linux/irqflags.h>
 
+#include <asm/outercache.h>
+
 #define __exception	__attribute__((section(".exception.text")))
 
 struct thread_info;
@@ -73,8 +75,7 @@ extern unsigned int mem_fclk_21285;
 
 struct pt_regs;
 
-void die(const char *msg, struct pt_regs *regs, int err)
-		__attribute__((noreturn));
+void die(const char *msg, struct pt_regs *regs, int err);
 
 struct siginfo;
 void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
@@ -138,10 +139,12 @@ extern unsigned int user_debug;
 #define dmb() __asm__ __volatile__ ("" : : : "memory")
 #endif
 
-#if __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP)
-#define mb()		dmb()
+#ifdef CONFIG_ARCH_HAS_BARRIERS
+#include <mach/barriers.h>
+#elif __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP)
+#define mb()		do { dsb(); outer_sync(); } while (0)
 #define rmb()		dmb()
-#define wmb()		dmb()
+#define wmb()		mb()
 #else
 #define mb()	do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
 #define rmb()	do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
@@ -153,9 +156,9 @@ extern unsigned int user_debug;
 #define smp_rmb()	barrier()
 #define smp_wmb()	barrier()
 #else
-#define smp_mb()	mb()
-#define smp_rmb()	rmb()
-#define smp_wmb()	wmb()
+#define smp_mb()	dmb()
+#define smp_rmb()	dmb()
+#define smp_wmb()	dmb()
 #endif
 
 #define read_barrier_depends()		do { } while(0)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/thread_info.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/thread_info.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/thread_info.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/thread_info.h	2010-05-16 17:17:36.000000000 -0400
@@ -115,7 +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);
+extern void vfp_sync_hwstate(struct thread_info *);
+extern void vfp_flush_hwstate(struct thread_info *);
 
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/tlbflush.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/tlbflush.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/tlbflush.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/tlbflush.h	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,9 @@
 #define TLB_V7_UIS_FULL (1 << 20)
 #define TLB_V7_UIS_ASID (1 << 21)
 
+/* Inner Shareable BTB operation (ARMv7 MP extensions) */
+#define TLB_V7_IS_BTB	(1 << 22)
+
 #define TLB_L2CLEAN_FR	(1 << 29)		/* Feroceon */
 #define TLB_DCLEAN	(1 << 30)
 #define TLB_WB		(1 << 31)
@@ -183,7 +186,7 @@
 #endif
 
 #ifdef CONFIG_SMP
-#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
+#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \
 			 TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID)
 #else
 #define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
@@ -339,6 +342,12 @@ static inline void local_flush_tlb_all(v
 		dsb();
 		isb();
 	}
+	if (tlb_flag(TLB_V7_IS_BTB)) {
+		/* flush the branch target cache */
+		asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+		dsb();
+		isb();
+	}
 }
 
 static inline void local_flush_tlb_mm(struct mm_struct *mm)
@@ -376,6 +385,12 @@ static inline void local_flush_tlb_mm(st
 		asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
 		dsb();
 	}
+	if (tlb_flag(TLB_V7_IS_BTB)) {
+		/* flush the branch target cache */
+		asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+		dsb();
+		isb();
+	}
 }
 
 static inline void
@@ -416,6 +431,12 @@ local_flush_tlb_page(struct vm_area_stru
 		asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
 		dsb();
 	}
+	if (tlb_flag(TLB_V7_IS_BTB)) {
+		/* flush the branch target cache */
+		asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+		dsb();
+		isb();
+	}
 }
 
 static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
@@ -454,6 +475,12 @@ static inline void local_flush_tlb_kerne
 		dsb();
 		isb();
 	}
+	if (tlb_flag(TLB_V7_IS_BTB)) {
+		/* flush the branch target cache */
+		asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+		dsb();
+		isb();
+	}
 }
 
 /*
@@ -529,7 +556,8 @@ extern void flush_tlb_kernel_range(unsig
  * cache entries for the kernels virtual memory range are written
  * back to the page.
  */
-extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte);
+extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
+	pte_t *ptep);
 
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/uaccess.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/uaccess.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/uaccess.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/uaccess.h	2010-05-16 17:17:36.000000000 -0400
@@ -229,16 +229,16 @@ do {									\
 	__asm__ __volatile__(					\
 	"1:	ldrbt	%1,[%2]\n"				\
 	"2:\n"							\
-	"	.section .fixup,\"ax\"\n"			\
+	"	.pushsection .fixup,\"ax\"\n"			\
 	"	.align	2\n"					\
 	"3:	mov	%0, %3\n"				\
 	"	mov	%1, #0\n"				\
 	"	b	2b\n"					\
-	"	.previous\n"					\
-	"	.section __ex_table,\"a\"\n"			\
+	"	.popsection\n"					\
+	"	.pushsection __ex_table,\"a\"\n"		\
 	"	.align	3\n"					\
 	"	.long	1b, 3b\n"				\
-	"	.previous"					\
+	"	.popsection"					\
 	: "+r" (err), "=&r" (x)					\
 	: "r" (addr), "i" (-EFAULT)				\
 	: "cc")
@@ -265,16 +265,16 @@ do {									\
 	__asm__ __volatile__(					\
 	"1:	ldrt	%1,[%2]\n"				\
 	"2:\n"							\
-	"	.section .fixup,\"ax\"\n"			\
+	"	.pushsection .fixup,\"ax\"\n"			\
 	"	.align	2\n"					\
 	"3:	mov	%0, %3\n"				\
 	"	mov	%1, #0\n"				\
 	"	b	2b\n"					\
-	"	.previous\n"					\
-	"	.section __ex_table,\"a\"\n"			\
+	"	.popsection\n"					\
+	"	.pushsection __ex_table,\"a\"\n"		\
 	"	.align	3\n"					\
 	"	.long	1b, 3b\n"				\
-	"	.previous"					\
+	"	.popsection"					\
 	: "+r" (err), "=&r" (x)					\
 	: "r" (addr), "i" (-EFAULT)				\
 	: "cc")
@@ -310,15 +310,15 @@ do {									\
 	__asm__ __volatile__(					\
 	"1:	strbt	%1,[%2]\n"				\
 	"2:\n"							\
-	"	.section .fixup,\"ax\"\n"			\
+	"	.pushsection .fixup,\"ax\"\n"			\
 	"	.align	2\n"					\
 	"3:	mov	%0, %3\n"				\
 	"	b	2b\n"					\
-	"	.previous\n"					\
-	"	.section __ex_table,\"a\"\n"			\
+	"	.popsection\n"					\
+	"	.pushsection __ex_table,\"a\"\n"		\
 	"	.align	3\n"					\
 	"	.long	1b, 3b\n"				\
-	"	.previous"					\
+	"	.popsection"					\
 	: "+r" (err)						\
 	: "r" (x), "r" (__pu_addr), "i" (-EFAULT)		\
 	: "cc")
@@ -343,15 +343,15 @@ do {									\
 	__asm__ __volatile__(					\
 	"1:	strt	%1,[%2]\n"				\
 	"2:\n"							\
-	"	.section .fixup,\"ax\"\n"			\
+	"	.pushsection .fixup,\"ax\"\n"			\
 	"	.align	2\n"					\
 	"3:	mov	%0, %3\n"				\
 	"	b	2b\n"					\
-	"	.previous\n"					\
-	"	.section __ex_table,\"a\"\n"			\
+	"	.popsection\n"					\
+	"	.pushsection __ex_table,\"a\"\n"		\
 	"	.align	3\n"					\
 	"	.long	1b, 3b\n"				\
-	"	.previous"					\
+	"	.popsection"					\
 	: "+r" (err)						\
 	: "r" (x), "r" (__pu_addr), "i" (-EFAULT)		\
 	: "cc")
@@ -371,16 +371,16 @@ do {									\
  THUMB(	"1:	strt	" __reg_oper1 ", [%1]\n"	)	\
  THUMB(	"2:	strt	" __reg_oper0 ", [%1, #4]\n"	)	\
 	"3:\n"							\
-	"	.section .fixup,\"ax\"\n"			\
+	"	.pushsection .fixup,\"ax\"\n"			\
 	"	.align	2\n"					\
 	"4:	mov	%0, %3\n"				\
 	"	b	3b\n"					\
-	"	.previous\n"					\
-	"	.section __ex_table,\"a\"\n"			\
+	"	.popsection\n"					\
+	"	.pushsection __ex_table,\"a\"\n"		\
 	"	.align	3\n"					\
 	"	.long	1b, 4b\n"				\
 	"	.long	2b, 4b\n"				\
-	"	.previous"					\
+	"	.popsection"					\
 	: "+r" (err), "+r" (__pu_addr)				\
 	: "r" (x), "i" (-EFAULT)				\
 	: "cc")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/ucontext.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/ucontext.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/ucontext.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/ucontext.h	2010-05-16 17:17:36.000000000 -0400
@@ -59,23 +59,22 @@ struct iwmmxt_sigframe {
 #endif /* CONFIG_IWMMXT */
 
 #ifdef CONFIG_VFP
-#if __LINUX_ARM_ARCH__ < 6
-/* For ARM pre-v6, we use fstmiax and fldmiax.  This adds one extra
- * word after the registers, and a word of padding at the end for
- * alignment.  */
 #define VFP_MAGIC		0x56465001
-#define VFP_STORAGE_SIZE	152
-#else
-#define VFP_MAGIC		0x56465002
-#define VFP_STORAGE_SIZE	144
-#endif
 
 struct vfp_sigframe
 {
 	unsigned long		magic;
 	unsigned long		size;
-	union vfp_state		storage;
-};
+	struct user_vfp		ufp;
+	struct user_vfp_exc	ufp_exc;
+} __attribute__((__aligned__(8)));
+
+/*
+ *  8 byte for magic and size, 264 byte for ufp, 12 bytes for ufp_exc,
+ *  4 bytes padding.
+ */
+#define VFP_STORAGE_SIZE	sizeof(struct vfp_sigframe)
+
 #endif /* CONFIG_VFP */
 
 /*
@@ -91,7 +90,7 @@ struct aux_sigframe {
 #ifdef CONFIG_IWMMXT
 	struct iwmmxt_sigframe	iwmmxt;
 #endif
-#if 0 && defined CONFIG_VFP /* Not yet saved.  */
+#ifdef CONFIG_VFP
 	struct vfp_sigframe	vfp;
 #endif
 	/* Something that isn't a valid magic number for any coprocessor.  */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/unistd.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/unistd.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/unistd.h	2010-05-16 17:17:36.000000000 -0400
@@ -443,9 +443,12 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_OLD_MMAP
+#define __ARCH_WANT_SYS_OLD_SELECT
 
 #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
 #define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_UTIME
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/include/asm/user.h linux-libre-2.6.34-gnu1/arch/arm/include/asm/user.h
--- linux-libre-2.6.33-gnu1/arch/arm/include/asm/user.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/include/asm/user.h	2010-05-16 17:17:36.000000000 -0400
@@ -83,11 +83,21 @@ struct user{
 
 /*
  * User specific VFP registers. If only VFPv2 is present, registers 16 to 31
- * are ignored by the ptrace system call.
+ * are ignored by the ptrace system call and the signal handler.
  */
 struct user_vfp {
 	unsigned long long fpregs[32];
 	unsigned long fpscr;
 };
 
+/*
+ * VFP exception registers exposed to user space during signal delivery.
+ * Fields not relavant to the current VFP architecture are ignored.
+ */
+struct user_vfp_exc {
+	unsigned long	fpexc;
+	unsigned long	fpinst;
+	unsigned long	fpinst2;
+};
+
 #endif /* _ARM_USER_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/Kconfig linux-libre-2.6.34-gnu1/arch/arm/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@ config ARM
 	select HAVE_IDE
 	select RTC_LIB
 	select SYS_SUPPORTS_APM_EMULATION
+	select GENERIC_ATOMIC64 if (!CPU_32v6K)
 	select HAVE_OPROFILE
 	select HAVE_ARCH_KGDB
 	select HAVE_KPROBES if (!XIP_KERNEL)
@@ -20,6 +21,8 @@ config ARM
 	select HAVE_GENERIC_DMA_COHERENT
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_LZO
+	select HAVE_PERF_EVENTS
+	select PERF_USE_VMALLOC
 	help
 	  The ARM series is a line of low-power-consumption RISC chip designs
 	  licensed by ARM Ltd and targeted at embedded applications and
@@ -52,6 +55,9 @@ config HAVE_TCM
 	bool
 	select GENERIC_ALLOCATOR
 
+config HAVE_PROC_CPU
+	bool
+
 config NO_IOPORT
 	bool
 
@@ -149,6 +155,9 @@ config ARCH_MAY_HAVE_PC_FDC
 config ZONE_DMA
 	bool
 
+config NEED_DMA_MAP_STATE
+       def_bool y
+
 config GENERIC_ISA_DMA
 	bool
 
@@ -161,6 +170,11 @@ config ARCH_MTD_XIP
 config GENERIC_HARDIRQS_NO__DO_IRQ
 	def_bool y
 
+config ARM_L1_CACHE_SHIFT_6
+	bool
+	help
+	  Setting ARM L1 cache line size to 64 Bytes.
+
 if OPROFILE
 
 config OPROFILE_ARMV6
@@ -204,6 +218,10 @@ config MMU
 	  Select if you want MMU-based virtualised addressing space
 	  support by paged memory management. If unsure, say 'Y'.
 
+#
+# The "ARM system type" choice list is ordered alphabetically by option
+# text.  Please add new entries in the option alphabetic order.
+#
 choice
 	prompt "ARM system type"
 	default ARCH_VERSATILE
@@ -235,6 +253,7 @@ config ARCH_REALVIEW
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select GPIO_PL061 if GPIOLIB
 	help
 	  This enables support for ARM Ltd RealView boards.
 
@@ -260,6 +279,18 @@ config ARCH_AT91
 	  This enables support for systems based on the Atmel AT91RM9200,
 	  AT91SAM9 and AT91CAP9 processors.
 
+config ARCH_BCMRING
+	bool "Broadcom BCMRING"
+	depends on MMU
+	select CPU_V6
+	select ARM_AMBA
+	select COMMON_CLKDEV
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+	select ARCH_WANT_OPTIONAL_GPIOLIB
+	help
+	  Support for Broadcom's BCMRing platform.
+
 config ARCH_CLPS711X
 	bool "Cirrus Logic CLPS711x/EP721x-based"
 	select CPU_ARM720T
@@ -310,10 +341,9 @@ config ARCH_MXC
 	bool "Freescale MXC/iMX-based"
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
-	select ARCH_MTD_XIP
-	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
 	select HAVE_CLK
+	select COMMON_CLKDEV
 	help
 	  Support for Freescale MXC/iMX-based family of processors
 
@@ -346,20 +376,6 @@ config ARCH_H720X
 	help
 	  This enables support for systems based on the Hynix HMS720x
 
-config ARCH_NOMADIK
-	bool "STMicroelectronics Nomadik"
-	select ARM_AMBA
-	select ARM_VIC
-	select CPU_ARM926T
-	select HAVE_CLK
-	select COMMON_CLKDEV
-	select GENERIC_TIME
-	select GENERIC_CLOCKEVENTS
-	select GENERIC_GPIO
-	select ARCH_REQUIRE_GPIOLIB
-	help
-	  Support for the Nomadik platform by ST-Ericsson
-
 config ARCH_IOP13XX
 	bool "IOP13xx-based"
 	depends on MMU
@@ -497,7 +513,7 @@ config ARCH_ORION5X
 	  Orion-2 (5281), Orion-1-90 (6183).
 
 config ARCH_MMP
-	bool "Marvell PXA168/910"
+	bool "Marvell PXA168/910/MMP2"
 	depends on MMU
 	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
@@ -508,7 +524,7 @@ config ARCH_MMP
 	select TICK_ONESHOT
 	select PLAT_PXA
 	help
-	  Support for Marvell's PXA168/910 processor line.
+	  Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
 
 config ARCH_KS8695
 	bool "Micrel/Kendin KS8695"
@@ -550,10 +566,20 @@ config ARCH_W90X900
 	  <http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/
 		ConsumerElectronicsIC/ARMMicrocontroller/ARMMicrocontroller>
 
+config ARCH_NUC93X
+	bool "Nuvoton NUC93X CPU"
+	select CPU_ARM926T
+	select HAVE_CLK
+	select COMMON_CLKDEV
+	help
+	  Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a
+	  low-power and high performance MPEG-4/JPEG multimedia controller chip.
+
 config ARCH_PNX4008
 	bool "Philips Nexperia PNX4008 Mobile"
 	select CPU_ARM926T
 	select HAVE_CLK
+	select COMMON_CLKDEV
 	help
 	  This enables support for Philips PNX4008 mobile platform.
 
@@ -584,6 +610,11 @@ config ARCH_MSM
 	  interface to the ARM9 modem processor which runs the baseband stack
 	  and controls some vital subsystems (clock and power control, etc).
 
+config ARCH_SHMOBILE
+	bool "Renesas SH-Mobile"
+	help
+	  Support for Renesas's SH-Mobile ARM platforms
+
 config ARCH_RPC
 	bool "RiscPC"
 	select ARCH_ACORN
@@ -627,20 +658,61 @@ config ARCH_S3C2410
 
 config ARCH_S3C64XX
 	bool "Samsung S3C64XX"
+	select PLAT_SAMSUNG
+	select CPU_V6
 	select GENERIC_GPIO
+	select ARM_VIC
 	select HAVE_CLK
+	select NO_IOPORT
 	select ARCH_HAS_CPUFREQ
+	select ARCH_REQUIRE_GPIOLIB
+	select SAMSUNG_CLKSRC
+	select SAMSUNG_IRQ_VIC_TIMER
+	select SAMSUNG_IRQ_UART
+	select S3C_GPIO_TRACK
+	select S3C_GPIO_PULL_UPDOWN
+	select S3C_GPIO_CFG_S3C24XX
+	select S3C_GPIO_CFG_S3C64XX
+	select S3C_DEV_NAND
+	select USB_ARCH_HAS_OHCI
+	select SAMSUNG_GPIOLIB_4BIT
 	help
 	  Samsung S3C64XX series based systems
 
+config ARCH_S5P6440
+	bool "Samsung S5P6440"
+	select CPU_V6
+	select GENERIC_GPIO
+	select HAVE_CLK
+	help
+	  Samsung S5P6440 CPU based systems
+
+config ARCH_S5P6442
+	bool "Samsung S5P6442"
+	select CPU_V6
+	select GENERIC_GPIO
+	select HAVE_CLK
+	help
+	  Samsung S5P6442 CPU based systems
+
 config ARCH_S5PC1XX
 	bool "Samsung S5PC1XX"
 	select GENERIC_GPIO
 	select HAVE_CLK
 	select CPU_V7
+	select ARM_L1_CACHE_SHIFT_6
 	help
 	  Samsung S5PC1XX series based systems
 
+config ARCH_S5PV210
+	bool "Samsung S5PV210/S5PC110"
+	select CPU_V7
+	select GENERIC_GPIO
+	select HAVE_CLK
+	select ARM_L1_CACHE_SHIFT_6
+	help
+	  Samsung S5PV210/S5PC110 series based systems
+
 config ARCH_SHARK
 	bool "Shark"
 	select CPU_SA110
@@ -678,6 +750,30 @@ config ARCH_U300
 	help
 	  Support for ST-Ericsson U300 series mobile platforms.
 
+config ARCH_U8500
+	bool "ST-Ericsson U8500 Series"
+	select CPU_V7
+	select ARM_AMBA
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+	select COMMON_CLKDEV
+	help
+	  Support for ST-Ericsson's Ux500 architecture
+
+config ARCH_NOMADIK
+	bool "STMicroelectronics Nomadik"
+	select ARM_AMBA
+	select ARM_VIC
+	select CPU_ARM926T
+	select HAVE_CLK
+	select COMMON_CLKDEV
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
+	help
+	  Support for the Nomadik platform by ST-Ericsson
+
 config ARCH_DAVINCI
 	bool "TI DaVinci"
 	select CPU_ARM926T
@@ -706,30 +802,13 @@ config ARCH_OMAP
 	help
 	  Support for TI's OMAP platform (OMAP1 and OMAP2).
 
-config ARCH_BCMRING
-	bool "Broadcom BCMRING"
-	depends on MMU
-	select CPU_V6
-	select ARM_AMBA
-	select COMMON_CLKDEV
-	select GENERIC_TIME
-	select GENERIC_CLOCKEVENTS
-	select ARCH_WANT_OPTIONAL_GPIOLIB
-	help
-	  Support for Broadcom's BCMRing platform.
-
-config ARCH_U8500
-	bool "ST-Ericsson U8500 Series"
-	select CPU_V7
-	select ARM_AMBA
-	select GENERIC_TIME
-	select GENERIC_CLOCKEVENTS
-	select COMMON_CLKDEV
-	help
-	  Support for ST-Ericsson's Ux500 architecture
-
 endchoice
 
+#
+# This is sorted alphabetically by mach-* pathname.  However, plat-*
+# Kconfigs may be included either alphabetically (according to the
+# plat- suffix) or along side the corresponding mach-* source.
+#
 source "arch/arm/mach-aaec2000/Kconfig"
 
 source "arch/arm/mach-at91/Kconfig"
@@ -785,6 +864,8 @@ source "arch/arm/plat-nomadik/Kconfig"
 
 source "arch/arm/mach-ns9xxx/Kconfig"
 
+source "arch/arm/mach-nuc93x/Kconfig"
+
 source "arch/arm/plat-omap/Kconfig"
 
 source "arch/arm/mach-omap1/Kconfig"
@@ -804,8 +885,7 @@ source "arch/arm/mach-sa1100/Kconfig"
 
 source "arch/arm/plat-samsung/Kconfig"
 source "arch/arm/plat-s3c24xx/Kconfig"
-source "arch/arm/plat-s3c64xx/Kconfig"
-source "arch/arm/plat-s3c/Kconfig"
+source "arch/arm/plat-s5p/Kconfig"
 source "arch/arm/plat-s5pc1xx/Kconfig"
 
 if ARCH_S3C2410
@@ -813,21 +893,27 @@ source "arch/arm/mach-s3c2400/Kconfig"
 source "arch/arm/mach-s3c2410/Kconfig"
 source "arch/arm/mach-s3c2412/Kconfig"
 source "arch/arm/mach-s3c2440/Kconfig"
-source "arch/arm/mach-s3c2442/Kconfig"
 source "arch/arm/mach-s3c2443/Kconfig"
 endif
 
 if ARCH_S3C64XX
-source "arch/arm/mach-s3c6400/Kconfig"
-source "arch/arm/mach-s3c6410/Kconfig"
+source "arch/arm/mach-s3c64xx/Kconfig"
 endif
 
-source "arch/arm/plat-stmp3xxx/Kconfig"
+source "arch/arm/mach-s5p6440/Kconfig"
+
+source "arch/arm/mach-s5p6442/Kconfig"
 
 if ARCH_S5PC1XX
 source "arch/arm/mach-s5pc100/Kconfig"
 endif
 
+source "arch/arm/mach-s5pv210/Kconfig"
+
+source "arch/arm/mach-shmobile/Kconfig"
+
+source "arch/arm/plat-stmp3xxx/Kconfig"
+
 source "arch/arm/mach-u300/Kconfig"
 
 source "arch/arm/mach-ux500/Kconfig"
@@ -867,6 +953,11 @@ config XSCALE_PMU
 	depends on CPU_XSCALE && !XSCALE_PMU_TIMER
 	default y
 
+config CPU_HAS_PMU
+	depends on CPU_V6 || CPU_V7 || XSCALE_PMU
+	default y
+	bool
+
 if !MMU
 source "arch/arm/Kconfig-nommu"
 endif
@@ -921,6 +1012,19 @@ config ARM_ERRATA_460075
 	  ACTLR register. Note that setting specific bits in the ACTLR register
 	  may not be available in non-secure mode.
 
+config PL310_ERRATA_588369
+	bool "Clean & Invalidate maintenance operations do not invalidate clean lines"
+	depends on CACHE_L2X0 && ARCH_OMAP4
+	help
+	   The PL310 L2 cache controller implements three types of Clean &
+	   Invalidate maintenance operations: by Physical Address
+	   (offset 0x7F0), by Index/Way (0x7F8) and by Way (0x7FC).
+	   They are architecturally defined to behave as the execution of a
+	   clean operation followed immediately by an invalidate operation,
+	   both performing to the same memory location. This functionality
+	   is not correctly implemented in PL310 as clean lines are not
+	   invalidated as a result of these operations. Note that this errata
+	   uses Texas Instrument's secure monitor api.
 endmenu
 
 source "arch/arm/common/Kconfig"
@@ -1075,7 +1179,7 @@ source kernel/Kconfig.preempt
 config HZ
 	int
 	default 128 if ARCH_L7200
-	default 200 if ARCH_EBSA110 || ARCH_S3C2410
+	default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P6440 || ARCH_S5P6442 || ARCH_S5PV210
 	default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
 	default AT91_TIMER_HZ if ARCH_AT91
 	default 100
@@ -1171,6 +1275,14 @@ config HIGHPTE
 	depends on HIGHMEM
 	depends on !OUTER_CACHE
 
+config HW_PERF_EVENTS
+	bool "Enable hardware performance counter support for perf events"
+	depends on PERF_EVENTS && CPU_HAS_PMU && (CPU_V6 || CPU_V7)
+	default y
+	help
+	  Enable hardware performance counter support for perf events. If
+	  disabled, perf events will use software events only.
+
 source "mm/Kconfig"
 
 config LEDS
@@ -1230,6 +1342,7 @@ config ALIGNMENT_TRAP
 	bool
 	depends on CPU_CP15_MMU
 	default y if !ARCH_EBSA110
+	select HAVE_PROC_CPU if PROC_FS
 	help
 	  ARM processors cannot fetch/store information which is not
 	  naturally aligned on the bus, i.e., a 4 byte fetch must start at an
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/Kconfig.debug linux-libre-2.6.34-gnu1/arch/arm/Kconfig.debug
--- linux-libre-2.6.33-gnu1/arch/arm/Kconfig.debug	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/Kconfig.debug	2010-05-16 17:17:36.000000000 -0400
@@ -117,7 +117,7 @@ config DEBUG_CLPS711X_UART2
 	  cause the debug messages to appear on the first serial port.
 
 config DEBUG_S3C_UART
-	depends on PLAT_S3C
+	depends on PLAT_SAMSUNG
 	int "S3C UART to use for low-level debug"
 	default "0"
 	help
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/asm-offsets.c linux-libre-2.6.34-gnu1/arch/arm/kernel/asm-offsets.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/asm-offsets.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/asm-offsets.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
  */
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/dma-mapping.h>
 #include <asm/mach/arch.h>
 #include <asm/thread_info.h>
 #include <asm/memory.h>
@@ -112,5 +113,9 @@ int main(void)
 #ifdef MULTI_PABORT
   DEFINE(PROCESSOR_PABT_FUNC,	offsetof(struct processor, _prefetch_abort));
 #endif
+  BLANK();
+  DEFINE(DMA_BIDIRECTIONAL,	DMA_BIDIRECTIONAL);
+  DEFINE(DMA_TO_DEVICE,		DMA_TO_DEVICE);
+  DEFINE(DMA_FROM_DEVICE,	DMA_FROM_DEVICE);
   return 0; 
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/bios32.c linux-libre-2.6.34-gnu1/arch/arm/kernel/bios32.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/bios32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/bios32.c	2010-05-16 17:17:36.000000000 -0400
@@ -616,15 +616,17 @@ char * __init pcibios_setup(char *str)
  * but we want to try to avoid allocating at 0x2900-0x2bff
  * which might be mirrored at 0x0100-0x03ff..
  */
-void pcibios_align_resource(void *data, struct resource *res,
-			    resource_size_t size, resource_size_t align)
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+				resource_size_t size, resource_size_t align)
 {
 	resource_size_t start = res->start;
 
 	if (res->flags & IORESOURCE_IO && start & 0x300)
 		start = (start + 0x3ff) & ~0x3ff;
 
-	res->start = (start + align - 1) & ~(align - 1);
+	start = (start + align - 1) & ~(align - 1);
+
+	return start;
 }
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/calls.S linux-libre-2.6.34-gnu1/arch/arm/kernel/calls.S
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/calls.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/calls.S	2010-05-16 17:17:36.000000000 -0400
@@ -91,7 +91,7 @@
 		CALL(sys_settimeofday)
 /* 80 */	CALL(sys_getgroups16)
 		CALL(sys_setgroups16)
-		CALL(OBSOLETE(old_select))	/* used by libc4 */
+		CALL(OBSOLETE(sys_old_select))	/* used by libc4 */
 		CALL(sys_symlink)
 		CALL(sys_ni_syscall)		/* was sys_lstat */
 /* 85 */	CALL(sys_readlink)
@@ -99,7 +99,7 @@
 		CALL(sys_swapon)
 		CALL(sys_reboot)
 		CALL(OBSOLETE(sys_old_readdir))	/* used by libc4 */
-/* 90 */	CALL(OBSOLETE(old_mmap))	/* used by libc4 */
+/* 90 */	CALL(OBSOLETE(sys_old_mmap))	/* used by libc4 */
 		CALL(sys_munmap)
 		CALL(sys_truncate)
 		CALL(sys_ftruncate)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/debug.S linux-libre-2.6.34-gnu1/arch/arm/kernel/debug.S
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/debug.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/debug.S	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,7 @@
 
 #if defined(CONFIG_CPU_V6)
 
-		.macro	addruart, rx
+		.macro	addruart, rx, tmp
 		.endm
 
 		.macro	senduart, rd, rx
@@ -51,7 +51,7 @@
 
 #elif defined(CONFIG_CPU_V7)
 
-		.macro	addruart, rx
+		.macro	addruart, rx, tmp
 		.endm
 
 		.macro	senduart, rd, rx
@@ -71,7 +71,7 @@ wait:		mrc	p14, 0, pc, c0, c1, 0
 
 #elif defined(CONFIG_CPU_XSCALE)
 
-		.macro	addruart, rx
+		.macro	addruart, rx, tmp
 		.endm
 
 		.macro	senduart, rd, rx
@@ -98,7 +98,7 @@ wait:		mrc	p14, 0, pc, c0, c1, 0
 
 #else
 
-		.macro	addruart, rx
+		.macro	addruart, rx, tmp
 		.endm
 
 		.macro	senduart, rd, rx
@@ -164,7 +164,7 @@ ENDPROC(printhex2)
 		.ltorg
 
 ENTRY(printascii)
-		addruart r3
+		addruart r3, r1
 		b	2f
 1:		waituart r2, r3
 		senduart r1, r3
@@ -180,7 +180,7 @@ ENTRY(printascii)
 ENDPROC(printascii)
 
 ENTRY(printch)
-		addruart r3
+		addruart r3, r1
 		mov	r1, r0
 		mov	r0, #0
 		b	1b
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/entry-armv.S linux-libre-2.6.34-gnu1/arch/arm/kernel/entry-armv.S
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/entry-armv.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/entry-armv.S	2010-05-16 17:17:36.000000000 -0400
@@ -523,16 +523,16 @@ ENDPROC(__und_usr)
 /*
  * The out of line fixup for the ldrt above.
  */
-	.section .fixup, "ax"
+	.pushsection .fixup, "ax"
 4:	mov	pc, r9
-	.previous
-	.section __ex_table,"a"
+	.popsection
+	.pushsection __ex_table,"a"
 	.long	1b, 4b
 #if __LINUX_ARM_ARCH__ >= 7
 	.long	2b, 4b
 	.long	3b, 4b
 #endif
-	.previous
+	.popsection
 
 /*
  * Check whether the instruction is a co-processor instruction.
@@ -676,10 +676,10 @@ do_fpe:
  *  lr  = unrecognised FP instruction return address
  */
 
-	.data
+	.pushsection .data
 ENTRY(fp_enter)
 	.word	no_fp
-	.previous
+	.popsection
 
 ENTRY(no_fp)
 	mov	pc, lr
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/entry-header.S linux-libre-2.6.34-gnu1/arch/arm/kernel/entry-header.S
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/entry-header.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/entry-header.S	2010-05-16 17:17:36.000000000 -0400
@@ -102,6 +102,8 @@
 	.else
 	ldmdb	sp, {r0 - lr}^			@ get calling r0 - lr
 	.endif
+	mov	r0, r0				@ ARMv5T and earlier require a nop
+						@ after ldm {}^
 	add	sp, sp, #S_FRAME_SIZE - S_PC
 	movs	pc, lr				@ return & move spsr_svc into cpsr
 	.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/ftrace.c linux-libre-2.6.34-gnu1/arch/arm/kernel/ftrace.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/ftrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/ftrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -62,15 +62,15 @@ int ftrace_modify_code(unsigned long pc,
 		"    movne  %0, #2    \n"
 		"3:\n"
 
-		".section .fixup, \"ax\"\n"
+		".pushsection .fixup, \"ax\"\n"
 		"4:  mov  %0, #1  \n"
 		"    b    3b      \n"
-		".previous\n"
+		".popsection\n"
 
-		".section __ex_table, \"a\"\n"
+		".pushsection __ex_table, \"a\"\n"
 		"    .long 1b, 4b \n"
 		"    .long 2b, 4b \n"
-		".previous\n"
+		".popsection\n"
 
 		: "=r"(err), "=r"(replaced)
 		: "r"(pc), "r"(new), "r"(old), "0"(err), "1"(replaced)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/irq.c linux-libre-2.6.34-gnu1/arch/arm/kernel/irq.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/smp.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/kgdb.c linux-libre-2.6.34-gnu1/arch/arm/kernel/kgdb.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/kgdb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/kgdb.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  * Authors:  George Davis <davis_g@mvista.com>
  *           Deepak Saxena <dsaxena@plexity.net>
  */
+#include <linux/irq.h>
 #include <linux/kgdb.h>
 #include <asm/traps.h>
 
@@ -158,6 +159,18 @@ static struct undef_hook kgdb_compiled_b
 	.fn			= kgdb_compiled_brk_fn
 };
 
+static void kgdb_call_nmi_hook(void *ignored)
+{
+       kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
+}
+
+void kgdb_roundup_cpus(unsigned long flags)
+{
+       local_irq_enable();
+       smp_call_function(kgdb_call_nmi_hook, NULL, 0);
+       local_irq_disable();
+}
+
 /**
  *	kgdb_arch_init - Perform any architecture specific initalization.
  *
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/kprobes.c linux-libre-2.6.34-gnu1/arch/arm/kernel/kprobes.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/kprobes.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/kprobes.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/stop_machine.h>
 #include <linux/stringify.h>
 #include <asm/traps.h>
@@ -393,6 +394,14 @@ void __kprobes jprobe_return(void)
 		/*
 		 * Setup an empty pt_regs. Fill SP and PC fields as
 		 * they're needed by longjmp_break_handler.
+		 *
+		 * We allocate some slack between the original SP and start of
+		 * our fabricated regs. To be precise we want to have worst case
+		 * covered which is STMFD with all 16 regs so we allocate 2 *
+		 * sizeof(struct_pt_regs)).
+		 *
+		 * This is to prevent any simulated instruction from writing
+		 * over the regs when they are accessing the stack.
 		 */
 		"sub    sp, %0, %1		\n\t"
 		"ldr    r0, ="__stringify(JPROBE_MAGIC_ADDR)"\n\t"
@@ -410,7 +419,7 @@ void __kprobes jprobe_return(void)
 		"ldmia	sp, {r0 - pc}		\n\t"
 		:
 		: "r" (kcb->jprobe_saved_regs.ARM_sp),
-		  "I" (sizeof(struct pt_regs)),
+		  "I" (sizeof(struct pt_regs) * 2),
 		  "J" (offsetof(struct pt_regs, ARM_sp)),
 		  "J" (offsetof(struct pt_regs, ARM_pc)),
 		  "J" (offsetof(struct pt_regs, ARM_cpsr))
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/leds.c linux-libre-2.6.34-gnu1/arch/arm/kernel/leds.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/leds.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/leds.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,115 @@
+/*
+ * LED support code, ripped out of arch/arm/kernel/time.c
+ *
+ *  Copyright (C) 1994-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+
+#include <asm/leds.h>
+
+static void dummy_leds_event(led_event_t evt)
+{
+}
+
+void (*leds_event)(led_event_t) = dummy_leds_event;
+
+struct leds_evt_name {
+	const char	name[8];
+	int		on;
+	int		off;
+};
+
+static const struct leds_evt_name evt_names[] = {
+	{ "amber", led_amber_on, led_amber_off },
+	{ "blue",  led_blue_on,  led_blue_off  },
+	{ "green", led_green_on, led_green_off },
+	{ "red",   led_red_on,   led_red_off   },
+};
+
+static ssize_t leds_store(struct sys_device *dev,
+			struct sysdev_attribute *attr,
+			const char *buf, size_t size)
+{
+	int ret = -EINVAL, len = strcspn(buf, " ");
+
+	if (len > 0 && buf[len] == '\0')
+		len--;
+
+	if (strncmp(buf, "claim", len) == 0) {
+		leds_event(led_claim);
+		ret = size;
+	} else if (strncmp(buf, "release", len) == 0) {
+		leds_event(led_release);
+		ret = size;
+	} else {
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(evt_names); i++) {
+			if (strlen(evt_names[i].name) != len ||
+			    strncmp(buf, evt_names[i].name, len) != 0)
+				continue;
+			if (strncmp(buf+len, " on", 3) == 0) {
+				leds_event(evt_names[i].on);
+				ret = size;
+			} else if (strncmp(buf+len, " off", 4) == 0) {
+				leds_event(evt_names[i].off);
+				ret = size;
+			}
+			break;
+		}
+	}
+	return ret;
+}
+
+static SYSDEV_ATTR(event, 0200, NULL, leds_store);
+
+static int leds_suspend(struct sys_device *dev, pm_message_t state)
+{
+	leds_event(led_stop);
+	return 0;
+}
+
+static int leds_resume(struct sys_device *dev)
+{
+	leds_event(led_start);
+	return 0;
+}
+
+static int leds_shutdown(struct sys_device *dev)
+{
+	leds_event(led_halted);
+	return 0;
+}
+
+static struct sysdev_class leds_sysclass = {
+	.name		= "leds",
+	.shutdown	= leds_shutdown,
+	.suspend	= leds_suspend,
+	.resume		= leds_resume,
+};
+
+static struct sys_device leds_device = {
+	.id		= 0,
+	.cls		= &leds_sysclass,
+};
+
+static int __init leds_init(void)
+{
+	int ret;
+	ret = sysdev_class_register(&leds_sysclass);
+	if (ret == 0)
+		ret = sysdev_register(&leds_device);
+	if (ret == 0)
+		ret = sysdev_create_file(&leds_device, &attr_event);
+	return ret;
+}
+
+device_initcall(leds_init);
+
+EXPORT_SYMBOL(leds_event);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/Makefile linux-libre-2.6.34-gnu1/arch/arm/kernel/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@ obj-y		:= compat.o elf.o entry-armv.o en
 		   process.o ptrace.o return_address.o setup.o signal.o \
 		   sys_arm.o stacktrace.o time.o traps.o
 
+obj-$(CONFIG_LEDS)		+= leds.o
 obj-$(CONFIG_OC_ETM)		+= etm.o
 
 obj-$(CONFIG_ISA_DMA_API)	+= dma.o
@@ -46,6 +47,8 @@ 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
+obj-$(CONFIG_CPU_HAS_PMU)	+= pmu.o
+obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
 AFLAGS_iwmmxt.o			:= -Wa,-mcpu=iwmmxt
 
 ifneq ($(CONFIG_ARCH_EBSA110),y)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/module.c linux-libre-2.6.34-gnu1/arch/arm/kernel/module.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/module.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/module.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,9 +16,9 @@
 #include <linux/mm.h>
 #include <linux/elf.h>
 #include <linux/vmalloc.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/string.h>
+#include <linux/gfp.h>
 
 #include <asm/pgtable.h>
 #include <asm/sections.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/perf_event.c linux-libre-2.6.34-gnu1/arch/arm/kernel/perf_event.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/perf_event.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/perf_event.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,2277 @@
+#undef DEBUG
+
+/*
+ * ARM performance counter support.
+ *
+ * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles
+ *
+ * ARMv7 support: Jean Pihet <jpihet@mvista.com>
+ * 2010 (c) MontaVista Software, LLC.
+ *
+ * This code is based on the sparc64 perf event code, which is in turn based
+ * on the x86 code. Callchain code is based on the ARM OProfile backtrace
+ * code.
+ */
+#define pr_fmt(fmt) "hw perfevents: " fmt
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+
+#include <asm/cputype.h>
+#include <asm/irq.h>
+#include <asm/irq_regs.h>
+#include <asm/pmu.h>
+#include <asm/stacktrace.h>
+
+static const struct pmu_irqs *pmu_irqs;
+
+/*
+ * Hardware lock to serialize accesses to PMU registers. Needed for the
+ * read/modify/write sequences.
+ */
+DEFINE_SPINLOCK(pmu_lock);
+
+/*
+ * ARMv6 supports a maximum of 3 events, starting from index 1. If we add
+ * another platform that supports more, we need to increase this to be the
+ * largest of all platforms.
+ *
+ * ARMv7 supports up to 32 events:
+ *  cycle counter CCNT + 31 events counters CNT0..30.
+ *  Cortex-A8 has 1+4 counters, Cortex-A9 has 1+6 counters.
+ */
+#define ARMPMU_MAX_HWEVENTS		33
+
+/* The events for a given CPU. */
+struct cpu_hw_events {
+	/*
+	 * The events that are active on the CPU for the given index. Index 0
+	 * is reserved.
+	 */
+	struct perf_event	*events[ARMPMU_MAX_HWEVENTS];
+
+	/*
+	 * A 1 bit for an index indicates that the counter is being used for
+	 * an event. A 0 means that the counter can be used.
+	 */
+	unsigned long		used_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)];
+
+	/*
+	 * A 1 bit for an index indicates that the counter is actively being
+	 * used.
+	 */
+	unsigned long		active_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)];
+};
+DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
+
+struct arm_pmu {
+	char		*name;
+	irqreturn_t	(*handle_irq)(int irq_num, void *dev);
+	void		(*enable)(struct hw_perf_event *evt, int idx);
+	void		(*disable)(struct hw_perf_event *evt, int idx);
+	int		(*event_map)(int evt);
+	u64		(*raw_event)(u64);
+	int		(*get_event_idx)(struct cpu_hw_events *cpuc,
+					 struct hw_perf_event *hwc);
+	u32		(*read_counter)(int idx);
+	void		(*write_counter)(int idx, u32 val);
+	void		(*start)(void);
+	void		(*stop)(void);
+	int		num_events;
+	u64		max_period;
+};
+
+/* Set at runtime when we know what CPU type we are. */
+static const struct arm_pmu *armpmu;
+
+#define HW_OP_UNSUPPORTED		0xFFFF
+
+#define C(_x) \
+	PERF_COUNT_HW_CACHE_##_x
+
+#define CACHE_OP_UNSUPPORTED		0xFFFF
+
+static unsigned armpmu_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+				     [PERF_COUNT_HW_CACHE_OP_MAX]
+				     [PERF_COUNT_HW_CACHE_RESULT_MAX];
+
+static int
+armpmu_map_cache_event(u64 config)
+{
+	unsigned int cache_type, cache_op, cache_result, ret;
+
+	cache_type = (config >>  0) & 0xff;
+	if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
+		return -EINVAL;
+
+	cache_op = (config >>  8) & 0xff;
+	if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
+		return -EINVAL;
+
+	cache_result = (config >> 16) & 0xff;
+	if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+		return -EINVAL;
+
+	ret = (int)armpmu_perf_cache_map[cache_type][cache_op][cache_result];
+
+	if (ret == CACHE_OP_UNSUPPORTED)
+		return -ENOENT;
+
+	return ret;
+}
+
+static int
+armpmu_event_set_period(struct perf_event *event,
+			struct hw_perf_event *hwc,
+			int idx)
+{
+	s64 left = atomic64_read(&hwc->period_left);
+	s64 period = hwc->sample_period;
+	int ret = 0;
+
+	if (unlikely(left <= -period)) {
+		left = period;
+		atomic64_set(&hwc->period_left, left);
+		hwc->last_period = period;
+		ret = 1;
+	}
+
+	if (unlikely(left <= 0)) {
+		left += period;
+		atomic64_set(&hwc->period_left, left);
+		hwc->last_period = period;
+		ret = 1;
+	}
+
+	if (left > (s64)armpmu->max_period)
+		left = armpmu->max_period;
+
+	atomic64_set(&hwc->prev_count, (u64)-left);
+
+	armpmu->write_counter(idx, (u64)(-left) & 0xffffffff);
+
+	perf_event_update_userpage(event);
+
+	return ret;
+}
+
+static u64
+armpmu_event_update(struct perf_event *event,
+		    struct hw_perf_event *hwc,
+		    int idx)
+{
+	int shift = 64 - 32;
+	s64 prev_raw_count, new_raw_count;
+	s64 delta;
+
+again:
+	prev_raw_count = atomic64_read(&hwc->prev_count);
+	new_raw_count = armpmu->read_counter(idx);
+
+	if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
+			     new_raw_count) != prev_raw_count)
+		goto again;
+
+	delta = (new_raw_count << shift) - (prev_raw_count << shift);
+	delta >>= shift;
+
+	atomic64_add(delta, &event->count);
+	atomic64_sub(delta, &hwc->period_left);
+
+	return new_raw_count;
+}
+
+static void
+armpmu_disable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	WARN_ON(idx < 0);
+
+	clear_bit(idx, cpuc->active_mask);
+	armpmu->disable(hwc, idx);
+
+	barrier();
+
+	armpmu_event_update(event, hwc, idx);
+	cpuc->events[idx] = NULL;
+	clear_bit(idx, cpuc->used_mask);
+
+	perf_event_update_userpage(event);
+}
+
+static void
+armpmu_read(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	/* Don't read disabled counters! */
+	if (hwc->idx < 0)
+		return;
+
+	armpmu_event_update(event, hwc, hwc->idx);
+}
+
+static void
+armpmu_unthrottle(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	/*
+	 * Set the period again. Some counters can't be stopped, so when we
+	 * were throttled we simply disabled the IRQ source and the counter
+	 * may have been left counting. If we don't do this step then we may
+	 * get an interrupt too soon or *way* too late if the overflow has
+	 * happened since disabling.
+	 */
+	armpmu_event_set_period(event, hwc, hwc->idx);
+	armpmu->enable(hwc, hwc->idx);
+}
+
+static int
+armpmu_enable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx;
+	int err = 0;
+
+	/* If we don't have a space for the counter then finish early. */
+	idx = armpmu->get_event_idx(cpuc, hwc);
+	if (idx < 0) {
+		err = idx;
+		goto out;
+	}
+
+	/*
+	 * If there is an event in the counter we are going to use then make
+	 * sure it is disabled.
+	 */
+	event->hw.idx = idx;
+	armpmu->disable(hwc, idx);
+	cpuc->events[idx] = event;
+	set_bit(idx, cpuc->active_mask);
+
+	/* Set the period for the event. */
+	armpmu_event_set_period(event, hwc, idx);
+
+	/* Enable the event. */
+	armpmu->enable(hwc, idx);
+
+	/* Propagate our changes to the userspace mapping. */
+	perf_event_update_userpage(event);
+
+out:
+	return err;
+}
+
+static struct pmu pmu = {
+	.enable	    = armpmu_enable,
+	.disable    = armpmu_disable,
+	.unthrottle = armpmu_unthrottle,
+	.read	    = armpmu_read,
+};
+
+static int
+validate_event(struct cpu_hw_events *cpuc,
+	       struct perf_event *event)
+{
+	struct hw_perf_event fake_event = event->hw;
+
+	if (event->pmu && event->pmu != &pmu)
+		return 0;
+
+	return armpmu->get_event_idx(cpuc, &fake_event) >= 0;
+}
+
+static int
+validate_group(struct perf_event *event)
+{
+	struct perf_event *sibling, *leader = event->group_leader;
+	struct cpu_hw_events fake_pmu;
+
+	memset(&fake_pmu, 0, sizeof(fake_pmu));
+
+	if (!validate_event(&fake_pmu, leader))
+		return -ENOSPC;
+
+	list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
+		if (!validate_event(&fake_pmu, sibling))
+			return -ENOSPC;
+	}
+
+	if (!validate_event(&fake_pmu, event))
+		return -ENOSPC;
+
+	return 0;
+}
+
+static int
+armpmu_reserve_hardware(void)
+{
+	int i;
+	int err;
+
+	pmu_irqs = reserve_pmu();
+	if (IS_ERR(pmu_irqs)) {
+		pr_warning("unable to reserve pmu\n");
+		return PTR_ERR(pmu_irqs);
+	}
+
+	init_pmu();
+
+	if (pmu_irqs->num_irqs < 1) {
+		pr_err("no irqs for PMUs defined\n");
+		return -ENODEV;
+	}
+
+	for (i = 0; i < pmu_irqs->num_irqs; ++i) {
+		err = request_irq(pmu_irqs->irqs[i], armpmu->handle_irq,
+				  IRQF_DISABLED | IRQF_NOBALANCING,
+				  "armpmu", NULL);
+		if (err) {
+			pr_warning("unable to request IRQ%d for ARM "
+				   "perf counters\n", pmu_irqs->irqs[i]);
+			break;
+		}
+	}
+
+	if (err) {
+		for (i = i - 1; i >= 0; --i)
+			free_irq(pmu_irqs->irqs[i], NULL);
+		release_pmu(pmu_irqs);
+		pmu_irqs = NULL;
+	}
+
+	return err;
+}
+
+static void
+armpmu_release_hardware(void)
+{
+	int i;
+
+	for (i = pmu_irqs->num_irqs - 1; i >= 0; --i)
+		free_irq(pmu_irqs->irqs[i], NULL);
+	armpmu->stop();
+
+	release_pmu(pmu_irqs);
+	pmu_irqs = NULL;
+}
+
+static atomic_t active_events = ATOMIC_INIT(0);
+static DEFINE_MUTEX(pmu_reserve_mutex);
+
+static void
+hw_perf_event_destroy(struct perf_event *event)
+{
+	if (atomic_dec_and_mutex_lock(&active_events, &pmu_reserve_mutex)) {
+		armpmu_release_hardware();
+		mutex_unlock(&pmu_reserve_mutex);
+	}
+}
+
+static int
+__hw_perf_event_init(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	int mapping, err;
+
+	/* Decode the generic type into an ARM event identifier. */
+	if (PERF_TYPE_HARDWARE == event->attr.type) {
+		mapping = armpmu->event_map(event->attr.config);
+	} else if (PERF_TYPE_HW_CACHE == event->attr.type) {
+		mapping = armpmu_map_cache_event(event->attr.config);
+	} else if (PERF_TYPE_RAW == event->attr.type) {
+		mapping = armpmu->raw_event(event->attr.config);
+	} else {
+		pr_debug("event type %x not supported\n", event->attr.type);
+		return -EOPNOTSUPP;
+	}
+
+	if (mapping < 0) {
+		pr_debug("event %x:%llx not supported\n", event->attr.type,
+			 event->attr.config);
+		return mapping;
+	}
+
+	/*
+	 * Check whether we need to exclude the counter from certain modes.
+	 * The ARM performance counters are on all of the time so if someone
+	 * has asked us for some excludes then we have to fail.
+	 */
+	if (event->attr.exclude_kernel || event->attr.exclude_user ||
+	    event->attr.exclude_hv || event->attr.exclude_idle) {
+		pr_debug("ARM performance counters do not support "
+			 "mode exclusion\n");
+		return -EPERM;
+	}
+
+	/*
+	 * We don't assign an index until we actually place the event onto
+	 * hardware. Use -1 to signify that we haven't decided where to put it
+	 * yet. For SMP systems, each core has it's own PMU so we can't do any
+	 * clever allocation or constraints checking at this point.
+	 */
+	hwc->idx = -1;
+
+	/*
+	 * Store the event encoding into the config_base field. config and
+	 * event_base are unused as the only 2 things we need to know are
+	 * the event mapping and the counter to use. The counter to use is
+	 * also the indx and the config_base is the event type.
+	 */
+	hwc->config_base	    = (unsigned long)mapping;
+	hwc->config		    = 0;
+	hwc->event_base		    = 0;
+
+	if (!hwc->sample_period) {
+		hwc->sample_period  = armpmu->max_period;
+		hwc->last_period    = hwc->sample_period;
+		atomic64_set(&hwc->period_left, hwc->sample_period);
+	}
+
+	err = 0;
+	if (event->group_leader != event) {
+		err = validate_group(event);
+		if (err)
+			return -EINVAL;
+	}
+
+	return err;
+}
+
+const struct pmu *
+hw_perf_event_init(struct perf_event *event)
+{
+	int err = 0;
+
+	if (!armpmu)
+		return ERR_PTR(-ENODEV);
+
+	event->destroy = hw_perf_event_destroy;
+
+	if (!atomic_inc_not_zero(&active_events)) {
+		if (atomic_read(&active_events) > perf_max_events) {
+			atomic_dec(&active_events);
+			return ERR_PTR(-ENOSPC);
+		}
+
+		mutex_lock(&pmu_reserve_mutex);
+		if (atomic_read(&active_events) == 0) {
+			err = armpmu_reserve_hardware();
+		}
+
+		if (!err)
+			atomic_inc(&active_events);
+		mutex_unlock(&pmu_reserve_mutex);
+	}
+
+	if (err)
+		return ERR_PTR(err);
+
+	err = __hw_perf_event_init(event);
+	if (err)
+		hw_perf_event_destroy(event);
+
+	return err ? ERR_PTR(err) : &pmu;
+}
+
+void
+hw_perf_enable(void)
+{
+	/* Enable all of the perf events on hardware. */
+	int idx;
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+	if (!armpmu)
+		return;
+
+	for (idx = 0; idx <= armpmu->num_events; ++idx) {
+		struct perf_event *event = cpuc->events[idx];
+
+		if (!event)
+			continue;
+
+		armpmu->enable(&event->hw, idx);
+	}
+
+	armpmu->start();
+}
+
+void
+hw_perf_disable(void)
+{
+	if (armpmu)
+		armpmu->stop();
+}
+
+/*
+ * ARMv6 Performance counter handling code.
+ *
+ * ARMv6 has 2 configurable performance counters and a single cycle counter.
+ * They all share a single reset bit but can be written to zero so we can use
+ * that for a reset.
+ *
+ * The counters can't be individually enabled or disabled so when we remove
+ * one event and replace it with another we could get spurious counts from the
+ * wrong event. However, we can take advantage of the fact that the
+ * performance counters can export events to the event bus, and the event bus
+ * itself can be monitored. This requires that we *don't* export the events to
+ * the event bus. The procedure for disabling a configurable counter is:
+ *	- change the counter to count the ETMEXTOUT[0] signal (0x20). This
+ *	  effectively stops the counter from counting.
+ *	- disable the counter's interrupt generation (each counter has it's
+ *	  own interrupt enable bit).
+ * Once stopped, the counter value can be written as 0 to reset.
+ *
+ * To enable a counter:
+ *	- enable the counter's interrupt generation.
+ *	- set the new event type.
+ *
+ * Note: the dedicated cycle counter only counts cycles and can't be
+ * enabled/disabled independently of the others. When we want to disable the
+ * cycle counter, we have to just disable the interrupt reporting and start
+ * ignoring that counter. When re-enabling, we have to reset the value and
+ * enable the interrupt.
+ */
+
+enum armv6_perf_types {
+	ARMV6_PERFCTR_ICACHE_MISS	    = 0x0,
+	ARMV6_PERFCTR_IBUF_STALL	    = 0x1,
+	ARMV6_PERFCTR_DDEP_STALL	    = 0x2,
+	ARMV6_PERFCTR_ITLB_MISS		    = 0x3,
+	ARMV6_PERFCTR_DTLB_MISS		    = 0x4,
+	ARMV6_PERFCTR_BR_EXEC		    = 0x5,
+	ARMV6_PERFCTR_BR_MISPREDICT	    = 0x6,
+	ARMV6_PERFCTR_INSTR_EXEC	    = 0x7,
+	ARMV6_PERFCTR_DCACHE_HIT	    = 0x9,
+	ARMV6_PERFCTR_DCACHE_ACCESS	    = 0xA,
+	ARMV6_PERFCTR_DCACHE_MISS	    = 0xB,
+	ARMV6_PERFCTR_DCACHE_WBACK	    = 0xC,
+	ARMV6_PERFCTR_SW_PC_CHANGE	    = 0xD,
+	ARMV6_PERFCTR_MAIN_TLB_MISS	    = 0xF,
+	ARMV6_PERFCTR_EXPL_D_ACCESS	    = 0x10,
+	ARMV6_PERFCTR_LSU_FULL_STALL	    = 0x11,
+	ARMV6_PERFCTR_WBUF_DRAINED	    = 0x12,
+	ARMV6_PERFCTR_CPU_CYCLES	    = 0xFF,
+	ARMV6_PERFCTR_NOP		    = 0x20,
+};
+
+enum armv6_counters {
+	ARMV6_CYCLE_COUNTER = 1,
+	ARMV6_COUNTER0,
+	ARMV6_COUNTER1,
+};
+
+/*
+ * The hardware events that we support. We do support cache operations but
+ * we have harvard caches and no way to combine instruction and data
+ * accesses/misses in hardware.
+ */
+static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = {
+	[PERF_COUNT_HW_CPU_CYCLES]	    = ARMV6_PERFCTR_CPU_CYCLES,
+	[PERF_COUNT_HW_INSTRUCTIONS]	    = ARMV6_PERFCTR_INSTR_EXEC,
+	[PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
+	[PERF_COUNT_HW_CACHE_MISSES]	    = HW_OP_UNSUPPORTED,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC,
+	[PERF_COUNT_HW_BRANCH_MISSES]	    = ARMV6_PERFCTR_BR_MISPREDICT,
+	[PERF_COUNT_HW_BUS_CYCLES]	    = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+					  [PERF_COUNT_HW_CACHE_OP_MAX]
+					  [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+	[C(L1D)] = {
+		/*
+		 * The performance counters don't differentiate between read
+		 * and write accesses/misses so this isn't strictly correct,
+		 * but it's the best we can do. Writes and reads get
+		 * combined.
+		 */
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= ARMV6_PERFCTR_DCACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV6_PERFCTR_DCACHE_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= ARMV6_PERFCTR_DCACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV6_PERFCTR_DCACHE_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(L1I)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV6_PERFCTR_ICACHE_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV6_PERFCTR_ICACHE_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(LL)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(DTLB)] = {
+		/*
+		 * The ARM performance counters can count micro DTLB misses,
+		 * micro ITLB misses and main TLB misses. There isn't an event
+		 * for TLB misses, so use the micro misses here and if users
+		 * want the main TLB misses they can use a raw counter.
+		 */
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV6_PERFCTR_DTLB_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV6_PERFCTR_DTLB_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(ITLB)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV6_PERFCTR_ITLB_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV6_PERFCTR_ITLB_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(BPU)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+};
+
+enum armv6mpcore_perf_types {
+	ARMV6MPCORE_PERFCTR_ICACHE_MISS	    = 0x0,
+	ARMV6MPCORE_PERFCTR_IBUF_STALL	    = 0x1,
+	ARMV6MPCORE_PERFCTR_DDEP_STALL	    = 0x2,
+	ARMV6MPCORE_PERFCTR_ITLB_MISS	    = 0x3,
+	ARMV6MPCORE_PERFCTR_DTLB_MISS	    = 0x4,
+	ARMV6MPCORE_PERFCTR_BR_EXEC	    = 0x5,
+	ARMV6MPCORE_PERFCTR_BR_NOTPREDICT   = 0x6,
+	ARMV6MPCORE_PERFCTR_BR_MISPREDICT   = 0x7,
+	ARMV6MPCORE_PERFCTR_INSTR_EXEC	    = 0x8,
+	ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS = 0xA,
+	ARMV6MPCORE_PERFCTR_DCACHE_RDMISS   = 0xB,
+	ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS = 0xC,
+	ARMV6MPCORE_PERFCTR_DCACHE_WRMISS   = 0xD,
+	ARMV6MPCORE_PERFCTR_DCACHE_EVICTION = 0xE,
+	ARMV6MPCORE_PERFCTR_SW_PC_CHANGE    = 0xF,
+	ARMV6MPCORE_PERFCTR_MAIN_TLB_MISS   = 0x10,
+	ARMV6MPCORE_PERFCTR_EXPL_MEM_ACCESS = 0x11,
+	ARMV6MPCORE_PERFCTR_LSU_FULL_STALL  = 0x12,
+	ARMV6MPCORE_PERFCTR_WBUF_DRAINED    = 0x13,
+	ARMV6MPCORE_PERFCTR_CPU_CYCLES	    = 0xFF,
+};
+
+/*
+ * The hardware events that we support. We do support cache operations but
+ * we have harvard caches and no way to combine instruction and data
+ * accesses/misses in hardware.
+ */
+static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = {
+	[PERF_COUNT_HW_CPU_CYCLES]	    = ARMV6MPCORE_PERFCTR_CPU_CYCLES,
+	[PERF_COUNT_HW_INSTRUCTIONS]	    = ARMV6MPCORE_PERFCTR_INSTR_EXEC,
+	[PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
+	[PERF_COUNT_HW_CACHE_MISSES]	    = HW_OP_UNSUPPORTED,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC,
+	[PERF_COUNT_HW_BRANCH_MISSES]	    = ARMV6MPCORE_PERFCTR_BR_MISPREDICT,
+	[PERF_COUNT_HW_BUS_CYCLES]	    = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+					[PERF_COUNT_HW_CACHE_OP_MAX]
+					[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+	[C(L1D)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]  =
+				ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS,
+			[C(RESULT_MISS)]    =
+				ARMV6MPCORE_PERFCTR_DCACHE_RDMISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]  =
+				ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS,
+			[C(RESULT_MISS)]    =
+				ARMV6MPCORE_PERFCTR_DCACHE_WRMISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(L1I)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(LL)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(DTLB)] = {
+		/*
+		 * The ARM performance counters can count micro DTLB misses,
+		 * micro ITLB misses and main TLB misses. There isn't an event
+		 * for TLB misses, so use the micro misses here and if users
+		 * want the main TLB misses they can use a raw counter.
+		 */
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_DTLB_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_DTLB_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(ITLB)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ITLB_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ITLB_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(BPU)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+		},
+	},
+};
+
+static inline unsigned long
+armv6_pmcr_read(void)
+{
+	u32 val;
+	asm volatile("mrc   p15, 0, %0, c15, c12, 0" : "=r"(val));
+	return val;
+}
+
+static inline void
+armv6_pmcr_write(unsigned long val)
+{
+	asm volatile("mcr   p15, 0, %0, c15, c12, 0" : : "r"(val));
+}
+
+#define ARMV6_PMCR_ENABLE		(1 << 0)
+#define ARMV6_PMCR_CTR01_RESET		(1 << 1)
+#define ARMV6_PMCR_CCOUNT_RESET		(1 << 2)
+#define ARMV6_PMCR_CCOUNT_DIV		(1 << 3)
+#define ARMV6_PMCR_COUNT0_IEN		(1 << 4)
+#define ARMV6_PMCR_COUNT1_IEN		(1 << 5)
+#define ARMV6_PMCR_CCOUNT_IEN		(1 << 6)
+#define ARMV6_PMCR_COUNT0_OVERFLOW	(1 << 8)
+#define ARMV6_PMCR_COUNT1_OVERFLOW	(1 << 9)
+#define ARMV6_PMCR_CCOUNT_OVERFLOW	(1 << 10)
+#define ARMV6_PMCR_EVT_COUNT0_SHIFT	20
+#define ARMV6_PMCR_EVT_COUNT0_MASK	(0xFF << ARMV6_PMCR_EVT_COUNT0_SHIFT)
+#define ARMV6_PMCR_EVT_COUNT1_SHIFT	12
+#define ARMV6_PMCR_EVT_COUNT1_MASK	(0xFF << ARMV6_PMCR_EVT_COUNT1_SHIFT)
+
+#define ARMV6_PMCR_OVERFLOWED_MASK \
+	(ARMV6_PMCR_COUNT0_OVERFLOW | ARMV6_PMCR_COUNT1_OVERFLOW | \
+	 ARMV6_PMCR_CCOUNT_OVERFLOW)
+
+static inline int
+armv6_pmcr_has_overflowed(unsigned long pmcr)
+{
+	return (pmcr & ARMV6_PMCR_OVERFLOWED_MASK);
+}
+
+static inline int
+armv6_pmcr_counter_has_overflowed(unsigned long pmcr,
+				  enum armv6_counters counter)
+{
+	int ret = 0;
+
+	if (ARMV6_CYCLE_COUNTER == counter)
+		ret = pmcr & ARMV6_PMCR_CCOUNT_OVERFLOW;
+	else if (ARMV6_COUNTER0 == counter)
+		ret = pmcr & ARMV6_PMCR_COUNT0_OVERFLOW;
+	else if (ARMV6_COUNTER1 == counter)
+		ret = pmcr & ARMV6_PMCR_COUNT1_OVERFLOW;
+	else
+		WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+
+	return ret;
+}
+
+static inline u32
+armv6pmu_read_counter(int counter)
+{
+	unsigned long value = 0;
+
+	if (ARMV6_CYCLE_COUNTER == counter)
+		asm volatile("mrc   p15, 0, %0, c15, c12, 1" : "=r"(value));
+	else if (ARMV6_COUNTER0 == counter)
+		asm volatile("mrc   p15, 0, %0, c15, c12, 2" : "=r"(value));
+	else if (ARMV6_COUNTER1 == counter)
+		asm volatile("mrc   p15, 0, %0, c15, c12, 3" : "=r"(value));
+	else
+		WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+
+	return value;
+}
+
+static inline void
+armv6pmu_write_counter(int counter,
+		       u32 value)
+{
+	if (ARMV6_CYCLE_COUNTER == counter)
+		asm volatile("mcr   p15, 0, %0, c15, c12, 1" : : "r"(value));
+	else if (ARMV6_COUNTER0 == counter)
+		asm volatile("mcr   p15, 0, %0, c15, c12, 2" : : "r"(value));
+	else if (ARMV6_COUNTER1 == counter)
+		asm volatile("mcr   p15, 0, %0, c15, c12, 3" : : "r"(value));
+	else
+		WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+}
+
+void
+armv6pmu_enable_event(struct hw_perf_event *hwc,
+		      int idx)
+{
+	unsigned long val, mask, evt, flags;
+
+	if (ARMV6_CYCLE_COUNTER == idx) {
+		mask	= 0;
+		evt	= ARMV6_PMCR_CCOUNT_IEN;
+	} else if (ARMV6_COUNTER0 == idx) {
+		mask	= ARMV6_PMCR_EVT_COUNT0_MASK;
+		evt	= (hwc->config_base << ARMV6_PMCR_EVT_COUNT0_SHIFT) |
+			  ARMV6_PMCR_COUNT0_IEN;
+	} else if (ARMV6_COUNTER1 == idx) {
+		mask	= ARMV6_PMCR_EVT_COUNT1_MASK;
+		evt	= (hwc->config_base << ARMV6_PMCR_EVT_COUNT1_SHIFT) |
+			  ARMV6_PMCR_COUNT1_IEN;
+	} else {
+		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+		return;
+	}
+
+	/*
+	 * Mask out the current event and set the counter to count the event
+	 * that we're interested in.
+	 */
+	spin_lock_irqsave(&pmu_lock, flags);
+	val = armv6_pmcr_read();
+	val &= ~mask;
+	val |= evt;
+	armv6_pmcr_write(val);
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static irqreturn_t
+armv6pmu_handle_irq(int irq_num,
+		    void *dev)
+{
+	unsigned long pmcr = armv6_pmcr_read();
+	struct perf_sample_data data;
+	struct cpu_hw_events *cpuc;
+	struct pt_regs *regs;
+	int idx;
+
+	if (!armv6_pmcr_has_overflowed(pmcr))
+		return IRQ_NONE;
+
+	regs = get_irq_regs();
+
+	/*
+	 * The interrupts are cleared by writing the overflow flags back to
+	 * the control register. All of the other bits don't have any effect
+	 * if they are rewritten, so write the whole value back.
+	 */
+	armv6_pmcr_write(pmcr);
+
+	perf_sample_data_init(&data, 0);
+
+	cpuc = &__get_cpu_var(cpu_hw_events);
+	for (idx = 0; idx <= armpmu->num_events; ++idx) {
+		struct perf_event *event = cpuc->events[idx];
+		struct hw_perf_event *hwc;
+
+		if (!test_bit(idx, cpuc->active_mask))
+			continue;
+
+		/*
+		 * We have a single interrupt for all counters. Check that
+		 * each counter has overflowed before we process it.
+		 */
+		if (!armv6_pmcr_counter_has_overflowed(pmcr, idx))
+			continue;
+
+		hwc = &event->hw;
+		armpmu_event_update(event, hwc, idx);
+		data.period = event->hw.last_period;
+		if (!armpmu_event_set_period(event, hwc, idx))
+			continue;
+
+		if (perf_event_overflow(event, 0, &data, regs))
+			armpmu->disable(hwc, idx);
+	}
+
+	/*
+	 * Handle the pending perf events.
+	 *
+	 * Note: this call *must* be run with interrupts enabled. For
+	 * platforms that can have the PMU interrupts raised as a PMI, this
+	 * will not work.
+	 */
+	perf_event_do_pending();
+
+	return IRQ_HANDLED;
+}
+
+static void
+armv6pmu_start(void)
+{
+	unsigned long flags, val;
+
+	spin_lock_irqsave(&pmu_lock, flags);
+	val = armv6_pmcr_read();
+	val |= ARMV6_PMCR_ENABLE;
+	armv6_pmcr_write(val);
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+void
+armv6pmu_stop(void)
+{
+	unsigned long flags, val;
+
+	spin_lock_irqsave(&pmu_lock, flags);
+	val = armv6_pmcr_read();
+	val &= ~ARMV6_PMCR_ENABLE;
+	armv6_pmcr_write(val);
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static inline int
+armv6pmu_event_map(int config)
+{
+	int mapping = armv6_perf_map[config];
+	if (HW_OP_UNSUPPORTED == mapping)
+		mapping = -EOPNOTSUPP;
+	return mapping;
+}
+
+static inline int
+armv6mpcore_pmu_event_map(int config)
+{
+	int mapping = armv6mpcore_perf_map[config];
+	if (HW_OP_UNSUPPORTED == mapping)
+		mapping = -EOPNOTSUPP;
+	return mapping;
+}
+
+static u64
+armv6pmu_raw_event(u64 config)
+{
+	return config & 0xff;
+}
+
+static int
+armv6pmu_get_event_idx(struct cpu_hw_events *cpuc,
+		       struct hw_perf_event *event)
+{
+	/* Always place a cycle counter into the cycle counter. */
+	if (ARMV6_PERFCTR_CPU_CYCLES == event->config_base) {
+		if (test_and_set_bit(ARMV6_CYCLE_COUNTER, cpuc->used_mask))
+			return -EAGAIN;
+
+		return ARMV6_CYCLE_COUNTER;
+	} else {
+		/*
+		 * For anything other than a cycle counter, try and use
+		 * counter0 and counter1.
+		 */
+		if (!test_and_set_bit(ARMV6_COUNTER1, cpuc->used_mask)) {
+			return ARMV6_COUNTER1;
+		}
+
+		if (!test_and_set_bit(ARMV6_COUNTER0, cpuc->used_mask)) {
+			return ARMV6_COUNTER0;
+		}
+
+		/* The counters are all in use. */
+		return -EAGAIN;
+	}
+}
+
+static void
+armv6pmu_disable_event(struct hw_perf_event *hwc,
+		       int idx)
+{
+	unsigned long val, mask, evt, flags;
+
+	if (ARMV6_CYCLE_COUNTER == idx) {
+		mask	= ARMV6_PMCR_CCOUNT_IEN;
+		evt	= 0;
+	} else if (ARMV6_COUNTER0 == idx) {
+		mask	= ARMV6_PMCR_COUNT0_IEN | ARMV6_PMCR_EVT_COUNT0_MASK;
+		evt	= ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT0_SHIFT;
+	} else if (ARMV6_COUNTER1 == idx) {
+		mask	= ARMV6_PMCR_COUNT1_IEN | ARMV6_PMCR_EVT_COUNT1_MASK;
+		evt	= ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT1_SHIFT;
+	} else {
+		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+		return;
+	}
+
+	/*
+	 * Mask out the current event and set the counter to count the number
+	 * of ETM bus signal assertion cycles. The external reporting should
+	 * be disabled and so this should never increment.
+	 */
+	spin_lock_irqsave(&pmu_lock, flags);
+	val = armv6_pmcr_read();
+	val &= ~mask;
+	val |= evt;
+	armv6_pmcr_write(val);
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,
+			      int idx)
+{
+	unsigned long val, mask, flags, evt = 0;
+
+	if (ARMV6_CYCLE_COUNTER == idx) {
+		mask	= ARMV6_PMCR_CCOUNT_IEN;
+	} else if (ARMV6_COUNTER0 == idx) {
+		mask	= ARMV6_PMCR_COUNT0_IEN;
+	} else if (ARMV6_COUNTER1 == idx) {
+		mask	= ARMV6_PMCR_COUNT1_IEN;
+	} else {
+		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+		return;
+	}
+
+	/*
+	 * Unlike UP ARMv6, we don't have a way of stopping the counters. We
+	 * simply disable the interrupt reporting.
+	 */
+	spin_lock_irqsave(&pmu_lock, flags);
+	val = armv6_pmcr_read();
+	val &= ~mask;
+	val |= evt;
+	armv6_pmcr_write(val);
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static const struct arm_pmu armv6pmu = {
+	.name			= "v6",
+	.handle_irq		= armv6pmu_handle_irq,
+	.enable			= armv6pmu_enable_event,
+	.disable		= armv6pmu_disable_event,
+	.event_map		= armv6pmu_event_map,
+	.raw_event		= armv6pmu_raw_event,
+	.read_counter		= armv6pmu_read_counter,
+	.write_counter		= armv6pmu_write_counter,
+	.get_event_idx		= armv6pmu_get_event_idx,
+	.start			= armv6pmu_start,
+	.stop			= armv6pmu_stop,
+	.num_events		= 3,
+	.max_period		= (1LLU << 32) - 1,
+};
+
+/*
+ * ARMv6mpcore is almost identical to single core ARMv6 with the exception
+ * that some of the events have different enumerations and that there is no
+ * *hack* to stop the programmable counters. To stop the counters we simply
+ * disable the interrupt reporting and update the event. When unthrottling we
+ * reset the period and enable the interrupt reporting.
+ */
+static const struct arm_pmu armv6mpcore_pmu = {
+	.name			= "v6mpcore",
+	.handle_irq		= armv6pmu_handle_irq,
+	.enable			= armv6pmu_enable_event,
+	.disable		= armv6mpcore_pmu_disable_event,
+	.event_map		= armv6mpcore_pmu_event_map,
+	.raw_event		= armv6pmu_raw_event,
+	.read_counter		= armv6pmu_read_counter,
+	.write_counter		= armv6pmu_write_counter,
+	.get_event_idx		= armv6pmu_get_event_idx,
+	.start			= armv6pmu_start,
+	.stop			= armv6pmu_stop,
+	.num_events		= 3,
+	.max_period		= (1LLU << 32) - 1,
+};
+
+/*
+ * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code.
+ *
+ * Copied from ARMv6 code, with the low level code inspired
+ *  by the ARMv7 Oprofile code.
+ *
+ * Cortex-A8 has up to 4 configurable performance counters and
+ *  a single cycle counter.
+ * Cortex-A9 has up to 31 configurable performance counters and
+ *  a single cycle counter.
+ *
+ * All counters can be enabled/disabled and IRQ masked separately. The cycle
+ *  counter and all 4 performance counters together can be reset separately.
+ */
+
+#define ARMV7_PMU_CORTEX_A8_NAME		"ARMv7 Cortex-A8"
+
+#define ARMV7_PMU_CORTEX_A9_NAME		"ARMv7 Cortex-A9"
+
+/* Common ARMv7 event types */
+enum armv7_perf_types {
+	ARMV7_PERFCTR_PMNC_SW_INCR		= 0x00,
+	ARMV7_PERFCTR_IFETCH_MISS		= 0x01,
+	ARMV7_PERFCTR_ITLB_MISS			= 0x02,
+	ARMV7_PERFCTR_DCACHE_REFILL		= 0x03,
+	ARMV7_PERFCTR_DCACHE_ACCESS		= 0x04,
+	ARMV7_PERFCTR_DTLB_REFILL		= 0x05,
+	ARMV7_PERFCTR_DREAD			= 0x06,
+	ARMV7_PERFCTR_DWRITE			= 0x07,
+
+	ARMV7_PERFCTR_EXC_TAKEN			= 0x09,
+	ARMV7_PERFCTR_EXC_EXECUTED		= 0x0A,
+	ARMV7_PERFCTR_CID_WRITE			= 0x0B,
+	/* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
+	 * It counts:
+	 *  - all branch instructions,
+	 *  - instructions that explicitly write the PC,
+	 *  - exception generating instructions.
+	 */
+	ARMV7_PERFCTR_PC_WRITE			= 0x0C,
+	ARMV7_PERFCTR_PC_IMM_BRANCH		= 0x0D,
+	ARMV7_PERFCTR_UNALIGNED_ACCESS		= 0x0F,
+	ARMV7_PERFCTR_PC_BRANCH_MIS_PRED	= 0x10,
+	ARMV7_PERFCTR_CLOCK_CYCLES		= 0x11,
+
+	ARMV7_PERFCTR_PC_BRANCH_MIS_USED	= 0x12,
+
+	ARMV7_PERFCTR_CPU_CYCLES		= 0xFF
+};
+
+/* ARMv7 Cortex-A8 specific event types */
+enum armv7_a8_perf_types {
+	ARMV7_PERFCTR_INSTR_EXECUTED		= 0x08,
+
+	ARMV7_PERFCTR_PC_PROC_RETURN		= 0x0E,
+
+	ARMV7_PERFCTR_WRITE_BUFFER_FULL		= 0x40,
+	ARMV7_PERFCTR_L2_STORE_MERGED		= 0x41,
+	ARMV7_PERFCTR_L2_STORE_BUFF		= 0x42,
+	ARMV7_PERFCTR_L2_ACCESS			= 0x43,
+	ARMV7_PERFCTR_L2_CACH_MISS		= 0x44,
+	ARMV7_PERFCTR_AXI_READ_CYCLES		= 0x45,
+	ARMV7_PERFCTR_AXI_WRITE_CYCLES		= 0x46,
+	ARMV7_PERFCTR_MEMORY_REPLAY		= 0x47,
+	ARMV7_PERFCTR_UNALIGNED_ACCESS_REPLAY	= 0x48,
+	ARMV7_PERFCTR_L1_DATA_MISS		= 0x49,
+	ARMV7_PERFCTR_L1_INST_MISS		= 0x4A,
+	ARMV7_PERFCTR_L1_DATA_COLORING		= 0x4B,
+	ARMV7_PERFCTR_L1_NEON_DATA		= 0x4C,
+	ARMV7_PERFCTR_L1_NEON_CACH_DATA		= 0x4D,
+	ARMV7_PERFCTR_L2_NEON			= 0x4E,
+	ARMV7_PERFCTR_L2_NEON_HIT		= 0x4F,
+	ARMV7_PERFCTR_L1_INST			= 0x50,
+	ARMV7_PERFCTR_PC_RETURN_MIS_PRED	= 0x51,
+	ARMV7_PERFCTR_PC_BRANCH_FAILED		= 0x52,
+	ARMV7_PERFCTR_PC_BRANCH_TAKEN		= 0x53,
+	ARMV7_PERFCTR_PC_BRANCH_EXECUTED	= 0x54,
+	ARMV7_PERFCTR_OP_EXECUTED		= 0x55,
+	ARMV7_PERFCTR_CYCLES_INST_STALL		= 0x56,
+	ARMV7_PERFCTR_CYCLES_INST		= 0x57,
+	ARMV7_PERFCTR_CYCLES_NEON_DATA_STALL	= 0x58,
+	ARMV7_PERFCTR_CYCLES_NEON_INST_STALL	= 0x59,
+	ARMV7_PERFCTR_NEON_CYCLES		= 0x5A,
+
+	ARMV7_PERFCTR_PMU0_EVENTS		= 0x70,
+	ARMV7_PERFCTR_PMU1_EVENTS		= 0x71,
+	ARMV7_PERFCTR_PMU_EVENTS		= 0x72,
+};
+
+/* ARMv7 Cortex-A9 specific event types */
+enum armv7_a9_perf_types {
+	ARMV7_PERFCTR_JAVA_HW_BYTECODE_EXEC	= 0x40,
+	ARMV7_PERFCTR_JAVA_SW_BYTECODE_EXEC	= 0x41,
+	ARMV7_PERFCTR_JAZELLE_BRANCH_EXEC	= 0x42,
+
+	ARMV7_PERFCTR_COHERENT_LINE_MISS	= 0x50,
+	ARMV7_PERFCTR_COHERENT_LINE_HIT		= 0x51,
+
+	ARMV7_PERFCTR_ICACHE_DEP_STALL_CYCLES	= 0x60,
+	ARMV7_PERFCTR_DCACHE_DEP_STALL_CYCLES	= 0x61,
+	ARMV7_PERFCTR_TLB_MISS_DEP_STALL_CYCLES	= 0x62,
+	ARMV7_PERFCTR_STREX_EXECUTED_PASSED	= 0x63,
+	ARMV7_PERFCTR_STREX_EXECUTED_FAILED	= 0x64,
+	ARMV7_PERFCTR_DATA_EVICTION		= 0x65,
+	ARMV7_PERFCTR_ISSUE_STAGE_NO_INST	= 0x66,
+	ARMV7_PERFCTR_ISSUE_STAGE_EMPTY		= 0x67,
+	ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE	= 0x68,
+
+	ARMV7_PERFCTR_PREDICTABLE_FUNCT_RETURNS	= 0x6E,
+
+	ARMV7_PERFCTR_MAIN_UNIT_EXECUTED_INST	= 0x70,
+	ARMV7_PERFCTR_SECOND_UNIT_EXECUTED_INST	= 0x71,
+	ARMV7_PERFCTR_LD_ST_UNIT_EXECUTED_INST	= 0x72,
+	ARMV7_PERFCTR_FP_EXECUTED_INST		= 0x73,
+	ARMV7_PERFCTR_NEON_EXECUTED_INST	= 0x74,
+
+	ARMV7_PERFCTR_PLD_FULL_DEP_STALL_CYCLES	= 0x80,
+	ARMV7_PERFCTR_DATA_WR_DEP_STALL_CYCLES	= 0x81,
+	ARMV7_PERFCTR_ITLB_MISS_DEP_STALL_CYCLES	= 0x82,
+	ARMV7_PERFCTR_DTLB_MISS_DEP_STALL_CYCLES	= 0x83,
+	ARMV7_PERFCTR_MICRO_ITLB_MISS_DEP_STALL_CYCLES	= 0x84,
+	ARMV7_PERFCTR_MICRO_DTLB_MISS_DEP_STALL_CYCLES 	= 0x85,
+	ARMV7_PERFCTR_DMB_DEP_STALL_CYCLES	= 0x86,
+
+	ARMV7_PERFCTR_INTGR_CLK_ENABLED_CYCLES	= 0x8A,
+	ARMV7_PERFCTR_DATA_ENGINE_CLK_EN_CYCLES	= 0x8B,
+
+	ARMV7_PERFCTR_ISB_INST			= 0x90,
+	ARMV7_PERFCTR_DSB_INST			= 0x91,
+	ARMV7_PERFCTR_DMB_INST			= 0x92,
+	ARMV7_PERFCTR_EXT_INTERRUPTS		= 0x93,
+
+	ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_COMPLETED	= 0xA0,
+	ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_SKIPPED	= 0xA1,
+	ARMV7_PERFCTR_PLE_FIFO_FLUSH		= 0xA2,
+	ARMV7_PERFCTR_PLE_RQST_COMPLETED	= 0xA3,
+	ARMV7_PERFCTR_PLE_FIFO_OVERFLOW		= 0xA4,
+	ARMV7_PERFCTR_PLE_RQST_PROG		= 0xA5
+};
+
+/*
+ * Cortex-A8 HW events mapping
+ *
+ * The hardware events that we support. We do support cache operations but
+ * we have harvard caches and no way to combine instruction and data
+ * accesses/misses in hardware.
+ */
+static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = {
+	[PERF_COUNT_HW_CPU_CYCLES]	    = ARMV7_PERFCTR_CPU_CYCLES,
+	[PERF_COUNT_HW_INSTRUCTIONS]	    = ARMV7_PERFCTR_INSTR_EXECUTED,
+	[PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
+	[PERF_COUNT_HW_CACHE_MISSES]	    = HW_OP_UNSUPPORTED,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
+	[PERF_COUNT_HW_BRANCH_MISSES]	    = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+	[PERF_COUNT_HW_BUS_CYCLES]	    = ARMV7_PERFCTR_CLOCK_CYCLES,
+};
+
+static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+					  [PERF_COUNT_HW_CACHE_OP_MAX]
+					  [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+	[C(L1D)] = {
+		/*
+		 * The performance counters don't differentiate between read
+		 * and write accesses/misses so this isn't strictly correct,
+		 * but it's the best we can do. Writes and reads get
+		 * combined.
+		 */
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_DCACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DCACHE_REFILL,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_DCACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DCACHE_REFILL,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(L1I)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_INST,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L1_INST_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_INST,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L1_INST_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(LL)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L2_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L2_CACH_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L2_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L2_CACH_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(DTLB)] = {
+		/*
+		 * Only ITLB misses and DTLB refills are supported.
+		 * If users want the DTLB refills misses a raw counter
+		 * must be used.
+		 */
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(ITLB)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(BPU)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_WRITE,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_WRITE,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+};
+
+/*
+ * Cortex-A9 HW events mapping
+ */
+static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
+	[PERF_COUNT_HW_CPU_CYCLES]	    = ARMV7_PERFCTR_CPU_CYCLES,
+	[PERF_COUNT_HW_INSTRUCTIONS]	    =
+					ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE,
+	[PERF_COUNT_HW_CACHE_REFERENCES]    = ARMV7_PERFCTR_COHERENT_LINE_HIT,
+	[PERF_COUNT_HW_CACHE_MISSES]	    = ARMV7_PERFCTR_COHERENT_LINE_MISS,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
+	[PERF_COUNT_HW_BRANCH_MISSES]	    = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+	[PERF_COUNT_HW_BUS_CYCLES]	    = ARMV7_PERFCTR_CLOCK_CYCLES,
+};
+
+static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+					  [PERF_COUNT_HW_CACHE_OP_MAX]
+					  [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+	[C(L1D)] = {
+		/*
+		 * The performance counters don't differentiate between read
+		 * and write accesses/misses so this isn't strictly correct,
+		 * but it's the best we can do. Writes and reads get
+		 * combined.
+		 */
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_DCACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DCACHE_REFILL,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_DCACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DCACHE_REFILL,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(L1I)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_IFETCH_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_IFETCH_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(LL)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(DTLB)] = {
+		/*
+		 * Only ITLB misses and DTLB refills are supported.
+		 * If users want the DTLB refills misses a raw counter
+		 * must be used.
+		 */
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(ITLB)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(BPU)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_WRITE,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_WRITE,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+};
+
+/*
+ * Perf Events counters
+ */
+enum armv7_counters {
+	ARMV7_CYCLE_COUNTER 		= 1,	/* Cycle counter */
+	ARMV7_COUNTER0			= 2,	/* First event counter */
+};
+
+/*
+ * The cycle counter is ARMV7_CYCLE_COUNTER.
+ * The first event counter is ARMV7_COUNTER0.
+ * The last event counter is (ARMV7_COUNTER0 + armpmu->num_events - 1).
+ */
+#define	ARMV7_COUNTER_LAST	(ARMV7_COUNTER0 + armpmu->num_events - 1)
+
+/*
+ * ARMv7 low level PMNC access
+ */
+
+/*
+ * Per-CPU PMNC: config reg
+ */
+#define ARMV7_PMNC_E		(1 << 0) /* Enable all counters */
+#define ARMV7_PMNC_P		(1 << 1) /* Reset all counters */
+#define ARMV7_PMNC_C		(1 << 2) /* Cycle counter reset */
+#define ARMV7_PMNC_D		(1 << 3) /* CCNT counts every 64th cpu cycle */
+#define ARMV7_PMNC_X		(1 << 4) /* Export to ETM */
+#define ARMV7_PMNC_DP		(1 << 5) /* Disable CCNT if non-invasive debug*/
+#define	ARMV7_PMNC_N_SHIFT	11	 /* Number of counters supported */
+#define	ARMV7_PMNC_N_MASK	0x1f
+#define	ARMV7_PMNC_MASK		0x3f	 /* Mask for writable bits */
+
+/*
+ * Available counters
+ */
+#define ARMV7_CNT0 		0	/* First event counter */
+#define ARMV7_CCNT 		31	/* Cycle counter */
+
+/* Perf Event to low level counters mapping */
+#define ARMV7_EVENT_CNT_TO_CNTx	(ARMV7_COUNTER0 - ARMV7_CNT0)
+
+/*
+ * CNTENS: counters enable reg
+ */
+#define ARMV7_CNTENS_P(idx)	(1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_CNTENS_C		(1 << ARMV7_CCNT)
+
+/*
+ * CNTENC: counters disable reg
+ */
+#define ARMV7_CNTENC_P(idx)	(1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_CNTENC_C		(1 << ARMV7_CCNT)
+
+/*
+ * INTENS: counters overflow interrupt enable reg
+ */
+#define ARMV7_INTENS_P(idx)	(1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_INTENS_C		(1 << ARMV7_CCNT)
+
+/*
+ * INTENC: counters overflow interrupt disable reg
+ */
+#define ARMV7_INTENC_P(idx)	(1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_INTENC_C		(1 << ARMV7_CCNT)
+
+/*
+ * EVTSEL: Event selection reg
+ */
+#define	ARMV7_EVTSEL_MASK	0xff		/* Mask for writable bits */
+
+/*
+ * SELECT: Counter selection reg
+ */
+#define	ARMV7_SELECT_MASK	0x1f		/* Mask for writable bits */
+
+/*
+ * FLAG: counters overflow flag status reg
+ */
+#define ARMV7_FLAG_P(idx)	(1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_FLAG_C		(1 << ARMV7_CCNT)
+#define	ARMV7_FLAG_MASK		0xffffffff	/* Mask for writable bits */
+#define	ARMV7_OVERFLOWED_MASK	ARMV7_FLAG_MASK
+
+static inline unsigned long armv7_pmnc_read(void)
+{
+	u32 val;
+	asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
+	return val;
+}
+
+static inline void armv7_pmnc_write(unsigned long val)
+{
+	val &= ARMV7_PMNC_MASK;
+	asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
+}
+
+static inline int armv7_pmnc_has_overflowed(unsigned long pmnc)
+{
+	return pmnc & ARMV7_OVERFLOWED_MASK;
+}
+
+static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc,
+					enum armv7_counters counter)
+{
+	int ret;
+
+	if (counter == ARMV7_CYCLE_COUNTER)
+		ret = pmnc & ARMV7_FLAG_C;
+	else if ((counter >= ARMV7_COUNTER0) && (counter <= ARMV7_COUNTER_LAST))
+		ret = pmnc & ARMV7_FLAG_P(counter);
+	else
+		pr_err("CPU%u checking wrong counter %d overflow status\n",
+			smp_processor_id(), counter);
+
+	return ret;
+}
+
+static inline int armv7_pmnc_select_counter(unsigned int idx)
+{
+	u32 val;
+
+	if ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST)) {
+		pr_err("CPU%u selecting wrong PMNC counter"
+			" %d\n", smp_processor_id(), idx);
+		return -1;
+	}
+
+	val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK;
+	asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
+
+	return idx;
+}
+
+static inline u32 armv7pmu_read_counter(int idx)
+{
+	unsigned long value = 0;
+
+	if (idx == ARMV7_CYCLE_COUNTER)
+		asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
+	else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
+		if (armv7_pmnc_select_counter(idx) == idx)
+			asm volatile("mrc p15, 0, %0, c9, c13, 2"
+				     : "=r" (value));
+	} else
+		pr_err("CPU%u reading wrong counter %d\n",
+			smp_processor_id(), idx);
+
+	return value;
+}
+
+static inline void armv7pmu_write_counter(int idx, u32 value)
+{
+	if (idx == ARMV7_CYCLE_COUNTER)
+		asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
+	else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
+		if (armv7_pmnc_select_counter(idx) == idx)
+			asm volatile("mcr p15, 0, %0, c9, c13, 2"
+				     : : "r" (value));
+	} else
+		pr_err("CPU%u writing wrong counter %d\n",
+			smp_processor_id(), idx);
+}
+
+static inline void armv7_pmnc_write_evtsel(unsigned int idx, u32 val)
+{
+	if (armv7_pmnc_select_counter(idx) == idx) {
+		val &= ARMV7_EVTSEL_MASK;
+		asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
+	}
+}
+
+static inline u32 armv7_pmnc_enable_counter(unsigned int idx)
+{
+	u32 val;
+
+	if ((idx != ARMV7_CYCLE_COUNTER) &&
+	    ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+		pr_err("CPU%u enabling wrong PMNC counter"
+			" %d\n", smp_processor_id(), idx);
+		return -1;
+	}
+
+	if (idx == ARMV7_CYCLE_COUNTER)
+		val = ARMV7_CNTENS_C;
+	else
+		val = ARMV7_CNTENS_P(idx);
+
+	asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val));
+
+	return idx;
+}
+
+static inline u32 armv7_pmnc_disable_counter(unsigned int idx)
+{
+	u32 val;
+
+
+	if ((idx != ARMV7_CYCLE_COUNTER) &&
+	    ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+		pr_err("CPU%u disabling wrong PMNC counter"
+			" %d\n", smp_processor_id(), idx);
+		return -1;
+	}
+
+	if (idx == ARMV7_CYCLE_COUNTER)
+		val = ARMV7_CNTENC_C;
+	else
+		val = ARMV7_CNTENC_P(idx);
+
+	asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val));
+
+	return idx;
+}
+
+static inline u32 armv7_pmnc_enable_intens(unsigned int idx)
+{
+	u32 val;
+
+	if ((idx != ARMV7_CYCLE_COUNTER) &&
+	    ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+		pr_err("CPU%u enabling wrong PMNC counter"
+			" interrupt enable %d\n", smp_processor_id(), idx);
+		return -1;
+	}
+
+	if (idx == ARMV7_CYCLE_COUNTER)
+		val = ARMV7_INTENS_C;
+	else
+		val = ARMV7_INTENS_P(idx);
+
+	asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val));
+
+	return idx;
+}
+
+static inline u32 armv7_pmnc_disable_intens(unsigned int idx)
+{
+	u32 val;
+
+	if ((idx != ARMV7_CYCLE_COUNTER) &&
+	    ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+		pr_err("CPU%u disabling wrong PMNC counter"
+			" interrupt enable %d\n", smp_processor_id(), idx);
+		return -1;
+	}
+
+	if (idx == ARMV7_CYCLE_COUNTER)
+		val = ARMV7_INTENC_C;
+	else
+		val = ARMV7_INTENC_P(idx);
+
+	asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (val));
+
+	return idx;
+}
+
+static inline u32 armv7_pmnc_getreset_flags(void)
+{
+	u32 val;
+
+	/* Read */
+	asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
+
+	/* Write to clear flags */
+	val &= ARMV7_FLAG_MASK;
+	asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
+
+	return val;
+}
+
+#ifdef DEBUG
+static void armv7_pmnc_dump_regs(void)
+{
+	u32 val;
+	unsigned int cnt;
+
+	printk(KERN_INFO "PMNC registers dump:\n");
+
+	asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
+	printk(KERN_INFO "PMNC  =0x%08x\n", val);
+
+	asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
+	printk(KERN_INFO "CNTENS=0x%08x\n", val);
+
+	asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
+	printk(KERN_INFO "INTENS=0x%08x\n", val);
+
+	asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
+	printk(KERN_INFO "FLAGS =0x%08x\n", val);
+
+	asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
+	printk(KERN_INFO "SELECT=0x%08x\n", val);
+
+	asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
+	printk(KERN_INFO "CCNT  =0x%08x\n", val);
+
+	for (cnt = ARMV7_COUNTER0; cnt < ARMV7_COUNTER_LAST; cnt++) {
+		armv7_pmnc_select_counter(cnt);
+		asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
+		printk(KERN_INFO "CNT[%d] count =0x%08x\n",
+			cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
+		asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
+		printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n",
+			cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
+	}
+}
+#endif
+
+void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+	unsigned long flags;
+
+	/*
+	 * Enable counter and interrupt, and set the counter to count
+	 * the event that we're interested in.
+	 */
+	spin_lock_irqsave(&pmu_lock, flags);
+
+	/*
+	 * Disable counter
+	 */
+	armv7_pmnc_disable_counter(idx);
+
+	/*
+	 * Set event (if destined for PMNx counters)
+	 * We don't need to set the event if it's a cycle count
+	 */
+	if (idx != ARMV7_CYCLE_COUNTER)
+		armv7_pmnc_write_evtsel(idx, hwc->config_base);
+
+	/*
+	 * Enable interrupt for this counter
+	 */
+	armv7_pmnc_enable_intens(idx);
+
+	/*
+	 * Enable counter
+	 */
+	armv7_pmnc_enable_counter(idx);
+
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+	unsigned long flags;
+
+	/*
+	 * Disable counter and interrupt
+	 */
+	spin_lock_irqsave(&pmu_lock, flags);
+
+	/*
+	 * Disable counter
+	 */
+	armv7_pmnc_disable_counter(idx);
+
+	/*
+	 * Disable interrupt for this counter
+	 */
+	armv7_pmnc_disable_intens(idx);
+
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
+{
+	unsigned long pmnc;
+	struct perf_sample_data data;
+	struct cpu_hw_events *cpuc;
+	struct pt_regs *regs;
+	int idx;
+
+	/*
+	 * Get and reset the IRQ flags
+	 */
+	pmnc = armv7_pmnc_getreset_flags();
+
+	/*
+	 * Did an overflow occur?
+	 */
+	if (!armv7_pmnc_has_overflowed(pmnc))
+		return IRQ_NONE;
+
+	/*
+	 * Handle the counter(s) overflow(s)
+	 */
+	regs = get_irq_regs();
+
+	perf_sample_data_init(&data, 0);
+
+	cpuc = &__get_cpu_var(cpu_hw_events);
+	for (idx = 0; idx <= armpmu->num_events; ++idx) {
+		struct perf_event *event = cpuc->events[idx];
+		struct hw_perf_event *hwc;
+
+		if (!test_bit(idx, cpuc->active_mask))
+			continue;
+
+		/*
+		 * We have a single interrupt for all counters. Check that
+		 * each counter has overflowed before we process it.
+		 */
+		if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
+			continue;
+
+		hwc = &event->hw;
+		armpmu_event_update(event, hwc, idx);
+		data.period = event->hw.last_period;
+		if (!armpmu_event_set_period(event, hwc, idx))
+			continue;
+
+		if (perf_event_overflow(event, 0, &data, regs))
+			armpmu->disable(hwc, idx);
+	}
+
+	/*
+	 * Handle the pending perf events.
+	 *
+	 * Note: this call *must* be run with interrupts enabled. For
+	 * platforms that can have the PMU interrupts raised as a PMI, this
+	 * will not work.
+	 */
+	perf_event_do_pending();
+
+	return IRQ_HANDLED;
+}
+
+static void armv7pmu_start(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pmu_lock, flags);
+	/* Enable all counters */
+	armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void armv7pmu_stop(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pmu_lock, flags);
+	/* Disable all counters */
+	armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static inline int armv7_a8_pmu_event_map(int config)
+{
+	int mapping = armv7_a8_perf_map[config];
+	if (HW_OP_UNSUPPORTED == mapping)
+		mapping = -EOPNOTSUPP;
+	return mapping;
+}
+
+static inline int armv7_a9_pmu_event_map(int config)
+{
+	int mapping = armv7_a9_perf_map[config];
+	if (HW_OP_UNSUPPORTED == mapping)
+		mapping = -EOPNOTSUPP;
+	return mapping;
+}
+
+static u64 armv7pmu_raw_event(u64 config)
+{
+	return config & 0xff;
+}
+
+static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc,
+				  struct hw_perf_event *event)
+{
+	int idx;
+
+	/* Always place a cycle counter into the cycle counter. */
+	if (event->config_base == ARMV7_PERFCTR_CPU_CYCLES) {
+		if (test_and_set_bit(ARMV7_CYCLE_COUNTER, cpuc->used_mask))
+			return -EAGAIN;
+
+		return ARMV7_CYCLE_COUNTER;
+	} else {
+		/*
+		 * For anything other than a cycle counter, try and use
+		 * the events counters
+		 */
+		for (idx = ARMV7_COUNTER0; idx <= armpmu->num_events; ++idx) {
+			if (!test_and_set_bit(idx, cpuc->used_mask))
+				return idx;
+		}
+
+		/* The counters are all in use. */
+		return -EAGAIN;
+	}
+}
+
+static struct arm_pmu armv7pmu = {
+	.handle_irq		= armv7pmu_handle_irq,
+	.enable			= armv7pmu_enable_event,
+	.disable		= armv7pmu_disable_event,
+	.raw_event		= armv7pmu_raw_event,
+	.read_counter		= armv7pmu_read_counter,
+	.write_counter		= armv7pmu_write_counter,
+	.get_event_idx		= armv7pmu_get_event_idx,
+	.start			= armv7pmu_start,
+	.stop			= armv7pmu_stop,
+	.max_period		= (1LLU << 32) - 1,
+};
+
+static u32 __init armv7_reset_read_pmnc(void)
+{
+	u32 nb_cnt;
+
+	/* Initialize & Reset PMNC: C and P bits */
+	armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
+
+	/* Read the nb of CNTx counters supported from PMNC */
+	nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
+
+	/* Add the CPU cycles counter and return */
+	return nb_cnt + 1;
+}
+
+static int __init
+init_hw_perf_events(void)
+{
+	unsigned long cpuid = read_cpuid_id();
+	unsigned long implementor = (cpuid & 0xFF000000) >> 24;
+	unsigned long part_number = (cpuid & 0xFFF0);
+
+	/* We only support ARM CPUs implemented by ARM at the moment. */
+	if (0x41 == implementor) {
+		switch (part_number) {
+		case 0xB360:	/* ARM1136 */
+		case 0xB560:	/* ARM1156 */
+		case 0xB760:	/* ARM1176 */
+			armpmu = &armv6pmu;
+			memcpy(armpmu_perf_cache_map, armv6_perf_cache_map,
+					sizeof(armv6_perf_cache_map));
+			perf_max_events	= armv6pmu.num_events;
+			break;
+		case 0xB020:	/* ARM11mpcore */
+			armpmu = &armv6mpcore_pmu;
+			memcpy(armpmu_perf_cache_map,
+			       armv6mpcore_perf_cache_map,
+			       sizeof(armv6mpcore_perf_cache_map));
+			perf_max_events = armv6mpcore_pmu.num_events;
+			break;
+		case 0xC080:	/* Cortex-A8 */
+			armv7pmu.name = ARMV7_PMU_CORTEX_A8_NAME;
+			memcpy(armpmu_perf_cache_map, armv7_a8_perf_cache_map,
+				sizeof(armv7_a8_perf_cache_map));
+			armv7pmu.event_map = armv7_a8_pmu_event_map;
+			armpmu = &armv7pmu;
+
+			/* Reset PMNC and read the nb of CNTx counters
+			    supported */
+			armv7pmu.num_events = armv7_reset_read_pmnc();
+			perf_max_events = armv7pmu.num_events;
+			break;
+		case 0xC090:	/* Cortex-A9 */
+			armv7pmu.name = ARMV7_PMU_CORTEX_A9_NAME;
+			memcpy(armpmu_perf_cache_map, armv7_a9_perf_cache_map,
+				sizeof(armv7_a9_perf_cache_map));
+			armv7pmu.event_map = armv7_a9_pmu_event_map;
+			armpmu = &armv7pmu;
+
+			/* Reset PMNC and read the nb of CNTx counters
+			    supported */
+			armv7pmu.num_events = armv7_reset_read_pmnc();
+			perf_max_events = armv7pmu.num_events;
+			break;
+		default:
+			pr_info("no hardware support available\n");
+			perf_max_events = -1;
+		}
+	}
+
+	if (armpmu)
+		pr_info("enabled with %s PMU driver, %d counters available\n",
+			armpmu->name, armpmu->num_events);
+
+	return 0;
+}
+arch_initcall(init_hw_perf_events);
+
+/*
+ * Callchain handling code.
+ */
+static inline void
+callchain_store(struct perf_callchain_entry *entry,
+		u64 ip)
+{
+	if (entry->nr < PERF_MAX_STACK_DEPTH)
+		entry->ip[entry->nr++] = ip;
+}
+
+/*
+ * The registers we're interested in are at the end of the variable
+ * length saved register structure. The fp points at the end of this
+ * structure so the address of this struct is:
+ * (struct frame_tail *)(xxx->fp)-1
+ *
+ * This code has been adapted from the ARM OProfile support.
+ */
+struct frame_tail {
+	struct frame_tail   *fp;
+	unsigned long	    sp;
+	unsigned long	    lr;
+} __attribute__((packed));
+
+/*
+ * Get the return address for a single stackframe and return a pointer to the
+ * next frame tail.
+ */
+static struct frame_tail *
+user_backtrace(struct frame_tail *tail,
+	       struct perf_callchain_entry *entry)
+{
+	struct frame_tail buftail;
+
+	/* Also check accessibility of one struct frame_tail beyond */
+	if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
+		return NULL;
+	if (__copy_from_user_inatomic(&buftail, tail, sizeof(buftail)))
+		return NULL;
+
+	callchain_store(entry, buftail.lr);
+
+	/*
+	 * Frame pointers should strictly progress back up the stack
+	 * (towards higher addresses).
+	 */
+	if (tail >= buftail.fp)
+		return NULL;
+
+	return buftail.fp - 1;
+}
+
+static void
+perf_callchain_user(struct pt_regs *regs,
+		    struct perf_callchain_entry *entry)
+{
+	struct frame_tail *tail;
+
+	callchain_store(entry, PERF_CONTEXT_USER);
+
+	if (!user_mode(regs))
+		regs = task_pt_regs(current);
+
+	tail = (struct frame_tail *)regs->ARM_fp - 1;
+
+	while (tail && !((unsigned long)tail & 0x3))
+		tail = user_backtrace(tail, entry);
+}
+
+/*
+ * Gets called by walk_stackframe() for every stackframe. This will be called
+ * whist unwinding the stackframe and is like a subroutine return so we use
+ * the PC.
+ */
+static int
+callchain_trace(struct stackframe *fr,
+		void *data)
+{
+	struct perf_callchain_entry *entry = data;
+	callchain_store(entry, fr->pc);
+	return 0;
+}
+
+static void
+perf_callchain_kernel(struct pt_regs *regs,
+		      struct perf_callchain_entry *entry)
+{
+	struct stackframe fr;
+
+	callchain_store(entry, PERF_CONTEXT_KERNEL);
+	fr.fp = regs->ARM_fp;
+	fr.sp = regs->ARM_sp;
+	fr.lr = regs->ARM_lr;
+	fr.pc = regs->ARM_pc;
+	walk_stackframe(&fr, callchain_trace, entry);
+}
+
+static void
+perf_do_callchain(struct pt_regs *regs,
+		  struct perf_callchain_entry *entry)
+{
+	int is_user;
+
+	if (!regs)
+		return;
+
+	is_user = user_mode(regs);
+
+	if (!current || !current->pid)
+		return;
+
+	if (is_user && current->state != TASK_RUNNING)
+		return;
+
+	if (!is_user)
+		perf_callchain_kernel(regs, entry);
+
+	if (current->mm)
+		perf_callchain_user(regs, entry);
+}
+
+static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry);
+
+struct perf_callchain_entry *
+perf_callchain(struct pt_regs *regs)
+{
+	struct perf_callchain_entry *entry = &__get_cpu_var(pmc_irq_entry);
+
+	entry->nr = 0;
+	perf_do_callchain(regs, entry);
+	return entry;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/pmu.c linux-libre-2.6.34-gnu1/arch/arm/kernel/pmu.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/pmu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/pmu.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,103 @@
+/*
+ *  linux/arch/arm/kernel/pmu.c
+ *
+ *  Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/cpumask.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/pmu.h>
+
+/*
+ * Define the IRQs for the system. We could use something like a platform
+ * device but that seems fairly heavyweight for this. Also, the performance
+ * counters can't be removed or hotplugged.
+ *
+ * Ordering is important: init_pmu() will use the ordering to set the affinity
+ * to the corresponding core. e.g. the first interrupt will go to cpu 0, the
+ * second goes to cpu 1 etc.
+ */
+static const int irqs[] = {
+#if defined(CONFIG_ARCH_OMAP2)
+	3,
+#elif defined(CONFIG_ARCH_BCMRING)
+	IRQ_PMUIRQ,
+#elif defined(CONFIG_MACH_REALVIEW_EB)
+	IRQ_EB11MP_PMU_CPU0,
+	IRQ_EB11MP_PMU_CPU1,
+	IRQ_EB11MP_PMU_CPU2,
+	IRQ_EB11MP_PMU_CPU3,
+#elif defined(CONFIG_ARCH_OMAP3)
+	INT_34XX_BENCH_MPU_EMUL,
+#elif defined(CONFIG_ARCH_IOP32X)
+	IRQ_IOP32X_CORE_PMU,
+#elif defined(CONFIG_ARCH_IOP33X)
+	IRQ_IOP33X_CORE_PMU,
+#elif defined(CONFIG_ARCH_PXA)
+	IRQ_PMU,
+#endif
+};
+
+static const struct pmu_irqs pmu_irqs = {
+	.irqs	    = irqs,
+	.num_irqs   = ARRAY_SIZE(irqs),
+};
+
+static volatile long pmu_lock;
+
+const struct pmu_irqs *
+reserve_pmu(void)
+{
+	return test_and_set_bit_lock(0, &pmu_lock) ? ERR_PTR(-EBUSY) :
+		&pmu_irqs;
+}
+EXPORT_SYMBOL_GPL(reserve_pmu);
+
+int
+release_pmu(const struct pmu_irqs *irqs)
+{
+	if (WARN_ON(irqs != &pmu_irqs))
+		return -EINVAL;
+	clear_bit_unlock(0, &pmu_lock);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(release_pmu);
+
+static int
+set_irq_affinity(int irq,
+		 unsigned int cpu)
+{
+#ifdef CONFIG_SMP
+	int err = irq_set_affinity(irq, cpumask_of(cpu));
+	if (err)
+		pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
+			   irq, cpu);
+	return err;
+#else
+	return 0;
+#endif
+}
+
+int
+init_pmu(void)
+{
+	int i, err = 0;
+
+	for (i = 0; i < pmu_irqs.num_irqs; ++i) {
+		err = set_irq_affinity(pmu_irqs.irqs[i], i);
+		if (err)
+			break;
+	}
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(init_pmu);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/process.c linux-libre-2.6.34-gnu1/arch/arm/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/mm.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/delay.h>
 #include <linux/reboot.h>
@@ -356,7 +355,7 @@ EXPORT_SYMBOL(dump_fpu);
  * the thread function, and r3 points to the exit function.
  */
 extern void kernel_thread_helper(void);
-asm(	".section .text\n"
+asm(	".pushsection .text\n"
 "	.align\n"
 "	.type	kernel_thread_helper, #function\n"
 "kernel_thread_helper:\n"
@@ -364,11 +363,11 @@ asm(	".section .text\n"
 "	mov	lr, r3\n"
 "	mov	pc, r2\n"
 "	.size	kernel_thread_helper, . - kernel_thread_helper\n"
-"	.previous");
+"	.popsection");
 
 #ifdef CONFIG_ARM_UNWIND
 extern void kernel_thread_exit(long code);
-asm(	".section .text\n"
+asm(	".pushsection .text\n"
 "	.align\n"
 "	.type	kernel_thread_exit, #function\n"
 "kernel_thread_exit:\n"
@@ -378,7 +377,7 @@ asm(	".section .text\n"
 "	nop\n"
 "	.fnend\n"
 "	.size	kernel_thread_exit, . - kernel_thread_exit\n"
-"	.previous");
+"	.popsection");
 #else
 #define kernel_thread_exit	do_exit
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/arm/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -452,12 +452,23 @@ void ptrace_cancel_bpt(struct task_struc
 		clear_breakpoint(child, &child->thread.debug.bp[i]);
 }
 
+void user_disable_single_step(struct task_struct *task)
+{
+	task->ptrace &= ~PT_SINGLESTEP;
+	ptrace_cancel_bpt(task);
+}
+
+void user_enable_single_step(struct task_struct *task)
+{
+	task->ptrace |= PT_SINGLESTEP;
+}
+
 /*
  * Called by kernel/ptrace.c when detaching..
  */
 void ptrace_disable(struct task_struct *child)
 {
-	single_step_disable(child);
+	user_disable_single_step(child);
 }
 
 /*
@@ -499,10 +510,41 @@ static struct undef_hook thumb_break_hoo
 	.fn		= break_trap,
 };
 
+static int thumb2_break_trap(struct pt_regs *regs, unsigned int instr)
+{
+	unsigned int instr2;
+	void __user *pc;
+
+	/* Check the second half of the instruction.  */
+	pc = (void __user *)(instruction_pointer(regs) + 2);
+
+	if (processor_mode(regs) == SVC_MODE) {
+		instr2 = *(u16 *) pc;
+	} else {
+		get_user(instr2, (u16 __user *)pc);
+	}
+
+	if (instr2 == 0xa000) {
+		ptrace_break(current, regs);
+		return 0;
+	} else {
+		return 1;
+	}
+}
+
+static struct undef_hook thumb2_break_hook = {
+	.instr_mask	= 0xffff,
+	.instr_val	= 0xf7f0,
+	.cpsr_mask	= PSR_T_BIT,
+	.cpsr_val	= PSR_T_BIT,
+	.fn		= thumb2_break_trap,
+};
+
 static int __init ptrace_break_init(void)
 {
 	register_undef_hook(&arm_break_hook);
 	register_undef_hook(&thumb_break_hook);
+	register_undef_hook(&thumb2_break_hook);
 	return 0;
 }
 
@@ -669,7 +711,7 @@ static int ptrace_getvfpregs(struct task
 	union vfp_state *vfp = &thread->vfpstate;
 	struct user_vfp __user *ufp = data;
 
-	vfp_sync_state(thread);
+	vfp_sync_hwstate(thread);
 
 	/* copy the floating point registers */
 	if (copy_to_user(&ufp->fpregs, &vfp->hard.fpregs,
@@ -692,7 +734,7 @@ static int ptrace_setvfpregs(struct task
 	union vfp_state *vfp = &thread->vfpstate;
 	struct user_vfp __user *ufp = data;
 
-	vfp_sync_state(thread);
+	vfp_sync_hwstate(thread);
 
 	/* copy the floating point registers */
 	if (copy_from_user(&vfp->hard.fpregs, &ufp->fpregs,
@@ -703,6 +745,8 @@ static int ptrace_setvfpregs(struct task
 	if (get_user(vfp->hard.fpscr, &ufp->fpscr))
 		return -EFAULT;
 
+	vfp_flush_hwstate(thread);
+
 	return 0;
 }
 #endif
@@ -712,77 +756,14 @@ long arch_ptrace(struct task_struct *chi
 	int ret;
 
 	switch (request) {
-		/*
-		 * read word at location "addr" in the child process.
-		 */
-		case PTRACE_PEEKTEXT:
-		case PTRACE_PEEKDATA:
-			ret = generic_ptrace_peekdata(child, addr, data);
-			break;
-
 		case PTRACE_PEEKUSR:
 			ret = ptrace_read_user(child, addr, (unsigned long __user *)data);
 			break;
 
-		/*
-		 * write the word at location addr.
-		 */
-		case PTRACE_POKETEXT:
-		case PTRACE_POKEDATA:
-			ret = generic_ptrace_pokedata(child, addr, data);
-			break;
-
 		case PTRACE_POKEUSR:
 			ret = ptrace_write_user(child, addr, data);
 			break;
 
-		/*
-		 * continue/restart and stop at next (return from) syscall
-		 */
-		case PTRACE_SYSCALL:
-		case PTRACE_CONT:
-			ret = -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;
-			single_step_disable(child);
-			wake_up_process(child);
-			ret = 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:
-			single_step_disable(child);
-			if (child->exit_state != EXIT_ZOMBIE) {
-				child->exit_code = SIGKILL;
-				wake_up_process(child);
-			}
-			ret = 0;
-			break;
-
-		/*
-		 * execute single instruction.
-		 */
-		case PTRACE_SINGLESTEP:
-			ret = -EIO;
-			if (!valid_signal(data))
-				break;
-			single_step_enable(child);
-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-			child->exit_code = data;
-			/* give it a chance to run. */
-			wake_up_process(child);
-			ret = 0;
-			break;
-
 		case PTRACE_GETREGS:
 			ret = ptrace_getregs(child, (void __user *)data);
 			break;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/ptrace.h linux-libre-2.6.34-gnu1/arch/arm/kernel/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,20 +14,6 @@ extern void ptrace_set_bpt(struct task_s
 extern void ptrace_break(struct task_struct *, struct pt_regs *);
 
 /*
- * make sure single-step breakpoint is gone.
- */
-static inline void single_step_disable(struct task_struct *task)
-{
-	task->ptrace &= ~PT_SINGLESTEP;
-	ptrace_cancel_bpt(task);
-}
-
-static inline void single_step_enable(struct task_struct *task)
-{
-	task->ptrace |= PT_SINGLESTEP;
-}
-
-/*
  * Send SIGTRAP if we're single-stepping
  */
 static inline void single_step_trap(struct task_struct *task)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/setup.c linux-libre-2.6.34-gnu1/arch/arm/kernel/setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/smp.h>
 #include <linux/fs.h>
+#include <linux/proc_fs.h>
 
 #include <asm/unified.h>
 #include <asm/cpu.h>
@@ -118,7 +119,7 @@ EXPORT_SYMBOL(elf_platform);
 
 static const char *cpu_name;
 static const char *machine_name;
-static char __initdata command_line[COMMAND_LINE_SIZE];
+static char __initdata cmd_line[COMMAND_LINE_SIZE];
 
 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
 static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
@@ -418,10 +419,11 @@ static int __init arm_add_memory(unsigne
  * Pick out the memory size.  We look for mem=size@start,
  * where start and size are "size[KkMm]"
  */
-static void __init early_mem(char **p)
+static int __init early_mem(char *p)
 {
 	static int usermem __initdata = 0;
 	unsigned long size, start;
+	char *endp;
 
 	/*
 	 * If the user specifies memory size, we
@@ -434,52 +436,15 @@ static void __init early_mem(char **p)
 	}
 
 	start = PHYS_OFFSET;
-	size  = memparse(*p, p);
-	if (**p == '@')
-		start = memparse(*p + 1, p);
+	size  = memparse(p, &endp);
+	if (*endp == '@')
+		start = memparse(endp + 1, NULL);
 
 	arm_add_memory(start, size);
-}
-__early_param("mem=", early_mem);
-
-/*
- * Initial parsing of the command line.
- */
-static void __init parse_cmdline(char **cmdline_p, char *from)
-{
-	char c = ' ', *to = command_line;
-	int len = 0;
-
-	for (;;) {
-		if (c == ' ') {
-			extern struct early_params __early_begin, __early_end;
-			struct early_params *p;
-
-			for (p = &__early_begin; p < &__early_end; p++) {
-				int arglen = strlen(p->arg);
 
-				if (memcmp(from, p->arg, arglen) == 0) {
-					if (to != command_line)
-						to -= 1;
-					from += arglen;
-					p->fn(&from);
-
-					while (*from != ' ' && *from != '\0')
-						from++;
-					break;
-				}
-			}
-		}
-		c = *from++;
-		if (!c)
-			break;
-		if (COMMAND_LINE_SIZE <= ++len)
-			break;
-		*to++ = c;
-	}
-	*to = '\0';
-	*cmdline_p = command_line;
+	return 0;
 }
+early_param("mem", early_mem);
 
 static void __init
 setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
@@ -740,9 +705,15 @@ void __init setup_arch(char **cmdline_p)
 	init_mm.end_data   = (unsigned long) _edata;
 	init_mm.brk	   = (unsigned long) _end;
 
-	memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
-	boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
-	parse_cmdline(cmdline_p, from);
+	/* parse_early_param needs a boot_command_line */
+	strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
+
+	/* populate cmd_line too for later use, preserving boot_command_line */
+	strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
+	*cmdline_p = cmd_line;
+
+	parse_early_param();
+
 	paging_init(mdesc);
 	request_standard_resources(&meminfo, mdesc);
 
@@ -783,9 +754,21 @@ static int __init topology_init(void)
 
 	return 0;
 }
-
 subsys_initcall(topology_init);
 
+#ifdef CONFIG_HAVE_PROC_CPU
+static int __init proc_cpu_init(void)
+{
+	struct proc_dir_entry *res;
+
+	res = proc_mkdir("cpu", NULL);
+	if (!res)
+		return -ENOMEM;
+	return 0;
+}
+fs_initcall(proc_cpu_init);
+#endif
+
 static const char *hwcap_str[] = {
 	"swp",
 	"half",
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/signal.c linux-libre-2.6.34-gnu1/arch/arm/kernel/signal.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/signal.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/signal.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <asm/cacheflush.h>
 #include <asm/ucontext.h>
 #include <asm/unistd.h>
+#include <asm/vfp.h>
 
 #include "ptrace.h"
 #include "signal.h"
@@ -175,6 +176,90 @@ static int restore_iwmmxt_context(struct
 
 #endif
 
+#ifdef CONFIG_VFP
+
+static int preserve_vfp_context(struct vfp_sigframe __user *frame)
+{
+	struct thread_info *thread = current_thread_info();
+	struct vfp_hard_struct *h = &thread->vfpstate.hard;
+	const unsigned long magic = VFP_MAGIC;
+	const unsigned long size = VFP_STORAGE_SIZE;
+	int err = 0;
+
+	vfp_sync_hwstate(thread);
+	__put_user_error(magic, &frame->magic, err);
+	__put_user_error(size, &frame->size, err);
+
+	/*
+	 * Copy the floating point registers. There can be unused
+	 * registers see asm/hwcap.h for details.
+	 */
+	err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs,
+			      sizeof(h->fpregs));
+	/*
+	 * Copy the status and control register.
+	 */
+	__put_user_error(h->fpscr, &frame->ufp.fpscr, err);
+
+	/*
+	 * Copy the exception registers.
+	 */
+	__put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err);
+	__put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
+	__put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
+
+	return err ? -EFAULT : 0;
+}
+
+static int restore_vfp_context(struct vfp_sigframe __user *frame)
+{
+	struct thread_info *thread = current_thread_info();
+	struct vfp_hard_struct *h = &thread->vfpstate.hard;
+	unsigned long magic;
+	unsigned long size;
+	unsigned long fpexc;
+	int err = 0;
+
+	__get_user_error(magic, &frame->magic, err);
+	__get_user_error(size, &frame->size, err);
+
+	if (err)
+		return -EFAULT;
+	if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
+		return -EINVAL;
+
+	/*
+	 * Copy the floating point registers. There can be unused
+	 * registers see asm/hwcap.h for details.
+	 */
+	err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs,
+				sizeof(h->fpregs));
+	/*
+	 * Copy the status and control register.
+	 */
+	__get_user_error(h->fpscr, &frame->ufp.fpscr, err);
+
+	/*
+	 * Sanitise and restore the exception registers.
+	 */
+	__get_user_error(fpexc, &frame->ufp_exc.fpexc, err);
+	/* Ensure the VFP is enabled. */
+	fpexc |= FPEXC_EN;
+	/* Ensure FPINST2 is invalid and the exception flag is cleared. */
+	fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
+	h->fpexc = fpexc;
+
+	__get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
+	__get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
+
+	if (!err)
+		vfp_flush_hwstate(thread);
+
+	return err ? -EFAULT : 0;
+}
+
+#endif
+
 /*
  * Do a signal return; undo the signal stack.  These are aligned to 64-bit.
  */
@@ -233,8 +318,8 @@ static int restore_sigframe(struct pt_re
 		err |= restore_iwmmxt_context(&aux->iwmmxt);
 #endif
 #ifdef CONFIG_VFP
-//	if (err == 0)
-//		err |= vfp_restore_state(&sf->aux.vfp);
+	if (err == 0)
+		err |= restore_vfp_context(&aux->vfp);
 #endif
 
 	return err;
@@ -348,8 +433,8 @@ setup_sigframe(struct sigframe __user *s
 		err |= preserve_iwmmxt_context(&aux->iwmmxt);
 #endif
 #ifdef CONFIG_VFP
-//	if (err == 0)
-//		err |= vfp_save_state(&sf->aux.vfp);
+	if (err == 0)
+		err |= preserve_vfp_context(&aux->vfp);
 #endif
 	__put_user_error(0, &aux->end_magic, err);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/smp.c linux-libre-2.6.34-gnu1/arch/arm/kernel/smp.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/smp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -86,6 +86,12 @@ int __cpuinit __cpu_up(unsigned int cpu)
 			return PTR_ERR(idle);
 		}
 		ci->idle = idle;
+	} else {
+		/*
+		 * Since this idle thread is being re-used, call
+		 * init_idle() to reinitialize the thread structure.
+		 */
+		init_idle(idle, cpu);
 	}
 
 	/*
@@ -99,6 +105,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
 	*pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) |
 		     PMD_TYPE_SECT | PMD_SECT_AP_WRITE);
 	flush_pmd_entry(pmd);
+	outer_clean_range(__pa(pmd), __pa(pmd + 1));
 
 	/*
 	 * We need to tell the secondary core where to find
@@ -106,7 +113,8 @@ int __cpuinit __cpu_up(unsigned int cpu)
 	 */
 	secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
 	secondary_data.pgdir = virt_to_phys(pgd);
-	wmb();
+	__cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data));
+	outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1));
 
 	/*
 	 * Now bring the CPU into our world.
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/smp_twd.c linux-libre-2.6.34-gnu1/arch/arm/kernel/smp_twd.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/smp_twd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/smp_twd.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,23 +21,6 @@
 #include <asm/smp_twd.h>
 #include <asm/hardware/gic.h>
 
-#define TWD_TIMER_LOAD 			0x00
-#define TWD_TIMER_COUNTER		0x04
-#define TWD_TIMER_CONTROL		0x08
-#define TWD_TIMER_INTSTAT		0x0C
-
-#define TWD_WDOG_LOAD			0x20
-#define TWD_WDOG_COUNTER		0x24
-#define TWD_WDOG_CONTROL		0x28
-#define TWD_WDOG_INTSTAT		0x2C
-#define TWD_WDOG_RESETSTAT		0x30
-#define TWD_WDOG_DISABLE		0x34
-
-#define TWD_TIMER_CONTROL_ENABLE	(1 << 0)
-#define TWD_TIMER_CONTROL_ONESHOT	(0 << 1)
-#define TWD_TIMER_CONTROL_PERIODIC	(1 << 1)
-#define TWD_TIMER_CONTROL_IT_ENABLE	(1 << 2)
-
 /* set up by the platform code */
 void __iomem *twd_base;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/sys_arm.c linux-libre-2.6.34-gnu1/arch/arm/kernel/sys_arm.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/sys_arm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/sys_arm.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
@@ -27,135 +26,7 @@
 #include <linux/file.h>
 #include <linux/ipc.h>
 #include <linux/uaccess.h>
-
-struct mmap_arg_struct {
-	unsigned long addr;
-	unsigned long len;
-	unsigned long prot;
-	unsigned long flags;
-	unsigned long fd;
-	unsigned long offset;
-};
-
-asmlinkage int old_mmap(struct mmap_arg_struct __user *arg)
-{
-	int error = -EFAULT;
-	struct mmap_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		goto out;
-
-	error = -EINVAL;
-	if (a.offset & ~PAGE_MASK)
-		goto out;
-
-	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-out:
-	return error;
-}
-
-/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls.
- */
-
-struct sel_arg_struct {
-	unsigned long n;
-	fd_set __user *inp, *outp, *exp;
-	struct timeval __user *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct __user *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	/* sys_select() does the appropriate kernel locking */
-	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
-#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage int sys_ipc(uint call, int first, int second, int third,
-		       void __user *ptr, long fifth)
-{
-	int version, ret;
-
-	version = call >> 16; /* hack for backward compatibility */
-	call &= 0xffff;
-
-	switch (call) {
-	case SEMOP:
-		return sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL);
-	case SEMTIMEDOP:
-		return sys_semtimedop(first, (struct sembuf __user *)ptr, second,
-					(const struct timespec __user *)fifth);
-
-	case SEMGET:
-		return sys_semget (first, second, third);
-	case SEMCTL: {
-		union semun fourth;
-		if (!ptr)
-			return -EINVAL;
-		if (get_user(fourth.__pad, (void __user * __user *) ptr))
-			return -EFAULT;
-		return sys_semctl (first, second, third, fourth);
-	}
-
-	case MSGSND:
-		return sys_msgsnd(first, (struct msgbuf __user *) ptr, 
-				  second, third);
-	case MSGRCV:
-		switch (version) {
-		case 0: {
-			struct ipc_kludge tmp;
-			if (!ptr)
-				return -EINVAL;
-			if (copy_from_user(&tmp,(struct ipc_kludge __user *)ptr,
-					   sizeof (tmp)))
-				return -EFAULT;
-			return sys_msgrcv (first, tmp.msgp, second,
-					   tmp.msgtyp, third);
-		}
-		default:
-			return sys_msgrcv (first,
-					   (struct msgbuf __user *) ptr,
-					   second, fifth, third);
-		}
-	case MSGGET:
-		return sys_msgget ((key_t) first, second);
-	case MSGCTL:
-		return sys_msgctl(first, second, (struct msqid_ds __user *)ptr);
-
-	case SHMAT:
-		switch (version) {
-		default: {
-			ulong raddr;
-			ret = do_shmat(first, (char __user *)ptr, second, &raddr);
-			if (ret)
-				return ret;
-			return put_user(raddr, (ulong __user *)third);
-		}
-		case 1: /* Of course, we don't support iBCS2! */
-			return -EINVAL;
-		}
-	case SHMDT: 
-		return sys_shmdt ((char __user *)ptr);
-	case SHMGET:
-		return sys_shmget (first, second, third);
-	case SHMCTL:
-		return sys_shmctl (first, second,
-				   (struct shmid_ds __user *) ptr);
-	default:
-		return -ENOSYS;
-	}
-}
-#endif
+#include <linux/slab.h>
 
 /* Fork a new task - this creates a new program thread.
  * This is called indirectly via a small wrapper
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/sys_oabi-compat.c linux-libre-2.6.34-gnu1/arch/arm/kernel/sys_oabi-compat.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/sys_oabi-compat.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/sys_oabi-compat.c	2010-05-16 17:17:36.000000000 -0400
@@ -346,9 +346,6 @@ asmlinkage long sys_oabi_semop(int semid
 	return sys_oabi_semtimedop(semid, tsops, nsops, NULL);
 }
 
-extern asmlinkage int sys_ipc(uint call, int first, int second, int third,
-			      void __user *ptr, long fifth);
-
 asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third,
 			    void __user *ptr, long fifth)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/time.c linux-libre-2.6.34-gnu1/arch/arm/kernel/time.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,11 +10,6 @@
  *
  *  This file contains the ARM-specific time handling details:
  *  reading the RTC at bootup, etc...
- *
- *  1994-07-02  Alan Modra
- *              fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
- *  1998-12-20  Updated NTP code according to technical memorandum Jan '96
- *              "A Kernel Model for Precision Timekeeping" by Dave Mills
  */
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -77,11 +72,6 @@ unsigned long profile_pc(struct pt_regs
 EXPORT_SYMBOL(profile_pc);
 #endif
 
-/*
- * hook for setting the RTC's idea of the current time.
- */
-int (*set_rtc)(void);
-
 #ifndef CONFIG_GENERIC_TIME
 static unsigned long dummy_gettimeoffset(void)
 {
@@ -89,140 +79,6 @@ static unsigned long dummy_gettimeoffset
 }
 #endif
 
-static unsigned long next_rtc_update;
-
-/*
- * If we have an externally synchronized linux clock, then update
- * CMOS clock accordingly every ~11 minutes.  set_rtc() has to be
- * called as close as possible to 500 ms before the new second
- * starts.
- */
-static inline void do_set_rtc(void)
-{
-	if (!ntp_synced() || set_rtc == NULL)
-		return;
-
-	if (next_rtc_update &&
-	    time_before((unsigned long)xtime.tv_sec, next_rtc_update))
-		return;
-
-	if (xtime.tv_nsec < 500000000 - ((unsigned) tick_nsec >> 1) &&
-	    xtime.tv_nsec >= 500000000 + ((unsigned) tick_nsec >> 1))
-		return;
-
-	if (set_rtc())
-		/*
-		 * rtc update failed.  Try again in 60s
-		 */
-		next_rtc_update = xtime.tv_sec + 60;
-	else
-		next_rtc_update = xtime.tv_sec + 660;
-}
-
-#ifdef CONFIG_LEDS
-
-static void dummy_leds_event(led_event_t evt)
-{
-}
-
-void (*leds_event)(led_event_t) = dummy_leds_event;
-
-struct leds_evt_name {
-	const char	name[8];
-	int		on;
-	int		off;
-};
-
-static const struct leds_evt_name evt_names[] = {
-	{ "amber", led_amber_on, led_amber_off },
-	{ "blue",  led_blue_on,  led_blue_off  },
-	{ "green", led_green_on, led_green_off },
-	{ "red",   led_red_on,   led_red_off   },
-};
-
-static ssize_t leds_store(struct sys_device *dev,
-			struct sysdev_attribute *attr,
-			const char *buf, size_t size)
-{
-	int ret = -EINVAL, len = strcspn(buf, " ");
-
-	if (len > 0 && buf[len] == '\0')
-		len--;
-
-	if (strncmp(buf, "claim", len) == 0) {
-		leds_event(led_claim);
-		ret = size;
-	} else if (strncmp(buf, "release", len) == 0) {
-		leds_event(led_release);
-		ret = size;
-	} else {
-		int i;
-
-		for (i = 0; i < ARRAY_SIZE(evt_names); i++) {
-			if (strlen(evt_names[i].name) != len ||
-			    strncmp(buf, evt_names[i].name, len) != 0)
-				continue;
-			if (strncmp(buf+len, " on", 3) == 0) {
-				leds_event(evt_names[i].on);
-				ret = size;
-			} else if (strncmp(buf+len, " off", 4) == 0) {
-				leds_event(evt_names[i].off);
-				ret = size;
-			}
-			break;
-		}
-	}
-	return ret;
-}
-
-static SYSDEV_ATTR(event, 0200, NULL, leds_store);
-
-static int leds_suspend(struct sys_device *dev, pm_message_t state)
-{
-	leds_event(led_stop);
-	return 0;
-}
-
-static int leds_resume(struct sys_device *dev)
-{
-	leds_event(led_start);
-	return 0;
-}
-
-static int leds_shutdown(struct sys_device *dev)
-{
-	leds_event(led_halted);
-	return 0;
-}
-
-static struct sysdev_class leds_sysclass = {
-	.name		= "leds",
-	.shutdown	= leds_shutdown,
-	.suspend	= leds_suspend,
-	.resume		= leds_resume,
-};
-
-static struct sys_device leds_device = {
-	.id		= 0,
-	.cls		= &leds_sysclass,
-};
-
-static int __init leds_init(void)
-{
-	int ret;
-	ret = sysdev_class_register(&leds_sysclass);
-	if (ret == 0)
-		ret = sysdev_register(&leds_device);
-	if (ret == 0)
-		ret = sysdev_create_file(&leds_device, &attr_event);
-	return ret;
-}
-
-device_initcall(leds_init);
-
-EXPORT_SYMBOL(leds_event);
-#endif
-
 #ifdef CONFIG_LEDS_TIMER
 static inline void do_leds(void)
 {
@@ -295,39 +151,6 @@ int do_settimeofday(struct timespec *tv)
 EXPORT_SYMBOL(do_settimeofday);
 #endif /* !CONFIG_GENERIC_TIME */
 
-/**
- * save_time_delta - Save the offset between system time and RTC time
- * @delta: pointer to timespec to store delta
- * @rtc: pointer to timespec for current RTC time
- *
- * Return a delta between the system time and the RTC time, such
- * that system time can be restored later with restore_time_delta()
- */
-void save_time_delta(struct timespec *delta, struct timespec *rtc)
-{
-	set_normalized_timespec(delta,
-				xtime.tv_sec - rtc->tv_sec,
-				xtime.tv_nsec - rtc->tv_nsec);
-}
-EXPORT_SYMBOL(save_time_delta);
-
-/**
- * restore_time_delta - Restore the current system time
- * @delta: delta returned by save_time_delta()
- * @rtc: pointer to timespec for current RTC time
- */
-void restore_time_delta(struct timespec *delta, struct timespec *rtc)
-{
-	struct timespec ts;
-
-	set_normalized_timespec(&ts,
-				delta->tv_sec + rtc->tv_sec,
-				delta->tv_nsec + rtc->tv_nsec);
-
-	do_settimeofday(&ts);
-}
-EXPORT_SYMBOL(restore_time_delta);
-
 #ifndef CONFIG_GENERIC_CLOCKEVENTS
 /*
  * Kernel system timer support.
@@ -336,7 +159,6 @@ void timer_tick(void)
 {
 	profile_tick(CPU_PROFILING);
 	do_leds();
-	do_set_rtc();
 	write_seqlock(&xtime_lock);
 	do_timer(1);
 	write_sequnlock(&xtime_lock);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/traps.c linux-libre-2.6.34-gnu1/arch/arm/kernel/traps.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/traps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/traps.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,15 +12,17 @@
  *  'linux/arch/arm/lib/traps.S'.  Mostly a debugging aid, but will probably
  *  kill the offending process.
  */
-#include <linux/module.h>
 #include <linux/signal.h>
-#include <linux/spinlock.h>
 #include <linux/personality.h>
 #include <linux/kallsyms.h>
-#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
 #include <linux/hardirq.h>
+#include <linux/kdebug.h>
+#include <linux/module.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
 #include <linux/init.h>
-#include <linux/uaccess.h>
 
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
@@ -224,14 +226,21 @@ void show_stack(struct task_struct *tsk,
 #define S_SMP ""
 #endif
 
-static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
+static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
 {
 	struct task_struct *tsk = thread->task;
 	static int die_counter;
+	int ret;
 
 	printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
 	       str, err, ++die_counter);
 	sysfs_printk_last_file();
+
+	/* trap and error numbers are mostly meaningless on ARM */
+	ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
+	if (ret == NOTIFY_STOP)
+		return ret;
+
 	print_modules();
 	__show_regs(regs);
 	printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
@@ -243,6 +252,8 @@ static void __die(const char *str, int e
 		dump_backtrace(regs, tsk);
 		dump_instr(KERN_EMERG, regs);
 	}
+
+	return ret;
 }
 
 DEFINE_SPINLOCK(die_lock);
@@ -250,16 +261,21 @@ DEFINE_SPINLOCK(die_lock);
 /*
  * This function is protected against re-entrancy.
  */
-NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
+void die(const char *str, struct pt_regs *regs, int err)
 {
 	struct thread_info *thread = current_thread_info();
+	int ret;
 
 	oops_enter();
 
 	spin_lock_irq(&die_lock);
 	console_verbose();
 	bust_spinlocks(1);
-	__die(str, err, thread, regs);
+	ret = __die(str, err, thread, regs);
+
+	if (regs && kexec_should_crash(thread->task))
+		crash_kexec(regs);
+
 	bust_spinlocks(0);
 	add_taint(TAINT_DIE);
 	spin_unlock_irq(&die_lock);
@@ -267,11 +283,10 @@ NORET_TYPE void die(const char *str, str
 
 	if (in_interrupt())
 		panic("Fatal exception in interrupt");
-
 	if (panic_on_oops)
 		panic("Fatal exception");
-
-	do_exit(SIGSEGV);
+	if (ret != NOTIFY_STOP)
+		do_exit(SIGSEGV);
 }
 
 void arm_notify_die(const char *str, struct pt_regs *regs,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/unwind.c linux-libre-2.6.34-gnu1/arch/arm/kernel/unwind.c
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/unwind.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/unwind.c	2010-05-16 17:17:36.000000000 -0400
@@ -359,7 +359,9 @@ void unwind_backtrace(struct pt_regs *re
 		frame.fp = regs->ARM_fp;
 		frame.sp = regs->ARM_sp;
 		frame.lr = regs->ARM_lr;
-		frame.pc = regs->ARM_pc;
+		/* PC might be corrupted, use LR in that case. */
+		frame.pc = kernel_text_address(regs->ARM_pc)
+			 ? regs->ARM_pc : regs->ARM_lr;
 	} else if (tsk == current) {
 		frame.fp = (unsigned long)__builtin_frame_address(0);
 		frame.sp = current_sp;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/kernel/vmlinux.lds.S linux-libre-2.6.34-gnu1/arch/arm/kernel/vmlinux.lds.S
--- linux-libre-2.6.33-gnu1/arch/arm/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/kernel/vmlinux.lds.S	2010-05-16 17:17:36.000000000 -0400
@@ -43,10 +43,6 @@ SECTIONS
 
 		INIT_SETUP(16)
 
-		__early_begin = .;
-			*(.early_param.init)
-		__early_end = .;
-
 		INIT_CALLS
 		CON_INITCALL
 		SECURITY_INITCALL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/lib/backtrace.S linux-libre-2.6.34-gnu1/arch/arm/lib/backtrace.S
--- linux-libre-2.6.33-gnu1/arch/arm/lib/backtrace.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/lib/backtrace.S	2010-05-16 17:17:36.000000000 -0400
@@ -110,13 +110,13 @@ no_frame:	ldmfd	sp!, {r4 - r8, pc}
 ENDPROC(__backtrace)
 ENDPROC(c_backtrace)
 		
-		.section __ex_table,"a"
+		.pushsection __ex_table,"a"
 		.align	3
 		.long	1001b, 1006b
 		.long	1002b, 1006b
 		.long	1003b, 1006b
 		.long	1004b, 1006b
-		.previous
+		.popsection
 
 #define instr r4
 #define reg   r5
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/lib/clear_user.S linux-libre-2.6.34-gnu1/arch/arm/lib/clear_user.S
--- linux-libre-2.6.33-gnu1/arch/arm/lib/clear_user.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/lib/clear_user.S	2010-05-16 17:17:36.000000000 -0400
@@ -45,9 +45,10 @@ USER(		strnebt	r2, [r0])
 		mov	r0, #0
 		ldmfd	sp!, {r1, pc}
 ENDPROC(__clear_user)
+ENDPROC(__clear_user_std)
 
-		.section .fixup,"ax"
+		.pushsection .fixup,"ax"
 		.align	0
 9001:		ldmfd	sp!, {r0, pc}
-		.previous
+		.popsection
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/lib/copy_from_user.S linux-libre-2.6.34-gnu1/arch/arm/lib/copy_from_user.S
--- linux-libre-2.6.33-gnu1/arch/arm/lib/copy_from_user.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/lib/copy_from_user.S	2010-05-16 17:17:36.000000000 -0400
@@ -90,7 +90,7 @@ ENTRY(__copy_from_user)
 
 ENDPROC(__copy_from_user)
 
-	.section .fixup,"ax"
+	.pushsection .fixup,"ax"
 	.align 0
 	copy_abort_preamble
 	ldmfd	sp!, {r1, r2}
@@ -100,5 +100,5 @@ ENDPROC(__copy_from_user)
 	bl	__memzero
 	ldr	r0, [sp], #4
 	copy_abort_end
-	.previous
+	.popsection
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/lib/copy_to_user.S linux-libre-2.6.34-gnu1/arch/arm/lib/copy_to_user.S
--- linux-libre-2.6.33-gnu1/arch/arm/lib/copy_to_user.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/lib/copy_to_user.S	2010-05-16 17:17:36.000000000 -0400
@@ -93,13 +93,14 @@ WEAK(__copy_to_user)
 #include "copy_template.S"
 
 ENDPROC(__copy_to_user)
+ENDPROC(__copy_to_user_std)
 
-	.section .fixup,"ax"
+	.pushsection .fixup,"ax"
 	.align 0
 	copy_abort_preamble
 	ldmfd	sp!, {r1, r2, r3}
 	sub	r0, r0, r1
 	rsb	r0, r0, r2
 	copy_abort_end
-	.previous
+	.popsection
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/lib/csumpartialcopyuser.S linux-libre-2.6.34-gnu1/arch/arm/lib/csumpartialcopyuser.S
--- linux-libre-2.6.33-gnu1/arch/arm/lib/csumpartialcopyuser.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/lib/csumpartialcopyuser.S	2010-05-16 17:17:36.000000000 -0400
@@ -68,7 +68,7 @@
  * so properly, we would have to add in whatever registers were loaded before
  * the fault, which, with the current asm above is not predictable.
  */
-		.section .fixup,"ax"
+		.pushsection .fixup,"ax"
 		.align	4
 9001:		mov	r4, #-EFAULT
 		ldr	r5, [fp, #4]		@ *err_ptr
@@ -80,4 +80,4 @@
 		strneb	r0, [r1], #1
 		bne	9002b
 		load_regs
-		.previous
+		.popsection
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/lib/getuser.S linux-libre-2.6.34-gnu1/arch/arm/lib/getuser.S
--- linux-libre-2.6.33-gnu1/arch/arm/lib/getuser.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/lib/getuser.S	2010-05-16 17:17:36.000000000 -0400
@@ -64,9 +64,9 @@ __get_user_bad:
 	mov	pc, lr
 ENDPROC(__get_user_bad)
 
-.section __ex_table, "a"
+.pushsection __ex_table, "a"
 	.long	1b, __get_user_bad
 	.long	2b, __get_user_bad
 	.long	3b, __get_user_bad
 	.long	4b, __get_user_bad
-.previous
+.popsection
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/lib/memmove.S linux-libre-2.6.34-gnu1/arch/arm/lib/memmove.S
--- linux-libre-2.6.33-gnu1/arch/arm/lib/memmove.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/lib/memmove.S	2010-05-16 17:17:36.000000000 -0400
@@ -74,7 +74,7 @@ ENTRY(memmove)
 		rsb	ip, ip, #32
 		addne	pc, pc, ip		@ C is always clear here
 		b	7f
-6:		nop
+6:		W(nop)
 		W(ldr)	r3, [r1, #-4]!
 		W(ldr)	r4, [r1, #-4]!
 		W(ldr)	r5, [r1, #-4]!
@@ -85,7 +85,7 @@ ENTRY(memmove)
 
 		add	pc, pc, ip
 		nop
-		nop
+		W(nop)
 		W(str)	r3, [r0, #-4]!
 		W(str)	r4, [r0, #-4]!
 		W(str)	r5, [r0, #-4]!
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/lib/putuser.S linux-libre-2.6.34-gnu1/arch/arm/lib/putuser.S
--- linux-libre-2.6.33-gnu1/arch/arm/lib/putuser.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/lib/putuser.S	2010-05-16 17:17:36.000000000 -0400
@@ -81,11 +81,11 @@ __put_user_bad:
 	mov	pc, lr
 ENDPROC(__put_user_bad)
 
-.section __ex_table, "a"
+.pushsection __ex_table, "a"
 	.long	1b, __put_user_bad
 	.long	2b, __put_user_bad
 	.long	3b, __put_user_bad
 	.long	4b, __put_user_bad
 	.long	5b, __put_user_bad
 	.long	6b, __put_user_bad
-.previous
+.popsection
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/lib/strncpy_from_user.S linux-libre-2.6.34-gnu1/arch/arm/lib/strncpy_from_user.S
--- linux-libre-2.6.33-gnu1/arch/arm/lib/strncpy_from_user.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/lib/strncpy_from_user.S	2010-05-16 17:17:36.000000000 -0400
@@ -33,11 +33,11 @@ ENTRY(__strncpy_from_user)
 	mov	pc, lr
 ENDPROC(__strncpy_from_user)
 
-	.section .fixup,"ax"
+	.pushsection .fixup,"ax"
 	.align	0
 9001:	mov	r3, #0
 	strb	r3, [r0, #0]	@ null terminate
 	mov	r0, #-EFAULT
 	mov	pc, lr
-	.previous
+	.popsection
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/lib/strnlen_user.S linux-libre-2.6.34-gnu1/arch/arm/lib/strnlen_user.S
--- linux-libre-2.6.33-gnu1/arch/arm/lib/strnlen_user.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/lib/strnlen_user.S	2010-05-16 17:17:36.000000000 -0400
@@ -33,8 +33,8 @@ ENTRY(__strnlen_user)
 	mov	pc, lr
 ENDPROC(__strnlen_user)
 
-	.section .fixup,"ax"
+	.pushsection .fixup,"ax"
 	.align	0
 9001:	mov	r0, #0
 	mov	pc, lr
-	.previous
+	.popsection
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/lib/uaccess.S linux-libre-2.6.34-gnu1/arch/arm/lib/uaccess.S
--- linux-libre-2.6.33-gnu1/arch/arm/lib/uaccess.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/lib/uaccess.S	2010-05-16 17:17:36.000000000 -0400
@@ -279,10 +279,10 @@ USER(		strgtbt	r3, [r0], #1)			@ May fau
 		b	.Lc2u_finished
 ENDPROC(__copy_to_user)
 
-		.section .fixup,"ax"
+		.pushsection .fixup,"ax"
 		.align	0
 9001:		ldmfd	sp!, {r0, r4 - r7, pc}
-		.previous
+		.popsection
 
 /* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n);
  * Purpose  : copy a block from user memory to kernel memory
@@ -545,7 +545,7 @@ USER(		ldrgtbt	r3, [r1], #1)			@ May fau
 		b	.Lcfu_finished
 ENDPROC(__copy_from_user)
 
-		.section .fixup,"ax"
+		.pushsection .fixup,"ax"
 		.align	0
 		/*
 		 * We took an exception.  r0 contains a pointer to
@@ -559,5 +559,5 @@ ENDPROC(__copy_from_user)
 		blne	__memzero
 		mov	r0, r4
 		ldmfd	sp!, {r4 - r7, pc}
-		.previous
+		.popsection
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/lib/uaccess_with_memcpy.c linux-libre-2.6.34-gnu1/arch/arm/lib/uaccess_with_memcpy.c
--- linux-libre-2.6.33-gnu1/arch/arm/lib/uaccess_with_memcpy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/lib/uaccess_with_memcpy.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/hardirq.h> /* for in_atomic() */
+#include <linux/gfp.h>
 #include <asm/current.h>
 #include <asm/page.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-aaec2000/core.c linux-libre-2.6.34-gnu1/arch/arm/mach-aaec2000/core.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-aaec2000/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-aaec2000/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/timex.h>
 #include <linux/signal.h>
 #include <linux/clk.h>
+#include <linux/gfp.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-aaec2000/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-aaec2000/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-aaec2000/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-aaec2000/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,7 @@
  */
 
 #include "hardware.h"
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #0x80000000		@ physical
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/at572d940hf.c linux-libre-2.6.34-gnu1/arch/arm/mach-at91/at572d940hf.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/at572d940hf.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/at572d940hf.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,377 @@
+/*
+ * arch/arm/mach-at91/at572d940hf.c
+ *
+ * Antonio R. Costa <costa.antonior@gmail.com>
+ * Copyright (C) 2008 Atmel
+ *
+ * Copyright (C) 2005 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/at572d940hf.h>
+#include <mach/at91_pmc.h>
+#include <mach/at91_rstc.h>
+
+#include "generic.h"
+#include "clock.h"
+
+static struct map_desc at572d940hf_io_desc[] __initdata = {
+	{
+		.virtual	= AT91_VA_BASE_SYS,
+		.pfn		= __phys_to_pfn(AT91_BASE_SYS),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_IO_VIRT_BASE - AT572D940HF_SRAM_SIZE,
+		.pfn		= __phys_to_pfn(AT572D940HF_SRAM_BASE),
+		.length		= AT572D940HF_SRAM_SIZE,
+		.type		= MT_DEVICE,
+	},
+};
+
+/* --------------------------------------------------------------------
+ *  Clocks
+ * -------------------------------------------------------------------- */
+
+/*
+ * The peripheral clocks.
+ */
+static struct clk pioA_clk = {
+	.name		= "pioA_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_PIOA,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioB_clk = {
+	.name		= "pioB_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_PIOB,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioC_clk = {
+	.name		= "pioC_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_PIOC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk macb_clk = {
+	.name		= "macb_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_EMAC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart0_clk = {
+	.name		= "usart0_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_US0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart1_clk = {
+	.name		= "usart1_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_US1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart2_clk = {
+	.name		= "usart2_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_US2,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc_clk = {
+	.name		= "mci_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_MCI,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk udc_clk = {
+	.name		= "udc_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_UDP,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi0_clk = {
+	.name		= "twi0_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_TWI0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi0_clk = {
+	.name		= "spi0_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_SPI0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi1_clk = {
+	.name		= "spi1_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_SPI1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc0_clk = {
+	.name		= "ssc0_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_SSC0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+	.name		= "ssc1_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_SSC1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc2_clk = {
+	.name		= "ssc2_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_SSC2,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc0_clk = {
+	.name		= "tc0_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_TC0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc1_clk = {
+	.name		= "tc1_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_TC1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc2_clk = {
+	.name		= "tc2_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_TC2,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ohci_clk = {
+	.name		= "ohci_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_UHP,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc3_clk = {
+	.name		= "ssc3_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_SSC3,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi1_clk = {
+	.name		= "twi1_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_TWI1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk can0_clk = {
+	.name		= "can0_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_CAN0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk can1_clk = {
+	.name		= "can1_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_CAN1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk mAgicV_clk = {
+	.name		= "mAgicV_clk",
+	.pmc_mask	= 1 << AT572D940HF_ID_MSIRQ0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+
+
+static struct clk *periph_clocks[] __initdata = {
+	&pioA_clk,
+	&pioB_clk,
+	&pioC_clk,
+	&macb_clk,
+	&usart0_clk,
+	&usart1_clk,
+	&usart2_clk,
+	&mmc_clk,
+	&udc_clk,
+	&twi0_clk,
+	&spi0_clk,
+	&spi1_clk,
+	&ssc0_clk,
+	&ssc1_clk,
+	&ssc2_clk,
+	&tc0_clk,
+	&tc1_clk,
+	&tc2_clk,
+	&ohci_clk,
+	&ssc3_clk,
+	&twi1_clk,
+	&can0_clk,
+	&can1_clk,
+	&mAgicV_clk,
+	/* irq0 .. irq2 */
+};
+
+/*
+ * The five programmable clocks.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+	.name		= "pck0",
+	.pmc_mask	= AT91_PMC_PCK0,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 0,
+};
+static struct clk pck1 = {
+	.name		= "pck1",
+	.pmc_mask	= AT91_PMC_PCK1,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 1,
+};
+static struct clk pck2 = {
+	.name		= "pck2",
+	.pmc_mask	= AT91_PMC_PCK2,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 2,
+};
+static struct clk pck3 = {
+	.name		= "pck3",
+	.pmc_mask	= AT91_PMC_PCK3,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 3,
+};
+
+static struct clk mAgicV_mem_clk = {
+	.name		= "mAgicV_mem_clk",
+	.pmc_mask	= AT91_PMC_PCK4,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 4,
+};
+
+/* HClocks */
+static struct clk hck0 = {
+	.name		= "hck0",
+	.pmc_mask	= AT91_PMC_HCK0,
+	.type		= CLK_TYPE_SYSTEM,
+	.id		= 0,
+};
+static struct clk hck1 = {
+	.name		= "hck1",
+	.pmc_mask	= AT91_PMC_HCK1,
+	.type		= CLK_TYPE_SYSTEM,
+	.id		= 1,
+};
+
+static void __init at572d940hf_register_clocks(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
+		clk_register(periph_clocks[i]);
+
+	clk_register(&pck0);
+	clk_register(&pck1);
+	clk_register(&pck2);
+	clk_register(&pck3);
+	clk_register(&mAgicV_mem_clk);
+
+	clk_register(&hck0);
+	clk_register(&hck1);
+}
+
+/* --------------------------------------------------------------------
+ *  GPIO
+ * -------------------------------------------------------------------- */
+
+static struct at91_gpio_bank at572d940hf_gpio[] = {
+	{
+		.id		= AT572D940HF_ID_PIOA,
+		.offset		= AT91_PIOA,
+		.clock		= &pioA_clk,
+	}, {
+		.id		= AT572D940HF_ID_PIOB,
+		.offset		= AT91_PIOB,
+		.clock		= &pioB_clk,
+	}, {
+		.id		= AT572D940HF_ID_PIOC,
+		.offset		= AT91_PIOC,
+		.clock		= &pioC_clk,
+	}
+};
+
+static void at572d940hf_reset(void)
+{
+	at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
+}
+
+
+/* --------------------------------------------------------------------
+ *  AT572D940HF processor initialization
+ * -------------------------------------------------------------------- */
+
+void __init at572d940hf_initialize(unsigned long main_clock)
+{
+	/* Map peripherals */
+	iotable_init(at572d940hf_io_desc, ARRAY_SIZE(at572d940hf_io_desc));
+
+	at91_arch_reset = at572d940hf_reset;
+	at91_extern_irq = (1 << AT572D940HF_ID_IRQ0) | (1 << AT572D940HF_ID_IRQ1)
+			| (1 << AT572D940HF_ID_IRQ2);
+
+	/* Init clock subsystem */
+	at91_clock_init(main_clock);
+
+	/* Register the processor-specific clocks */
+	at572d940hf_register_clocks();
+
+	/* Register GPIO subsystem */
+	at91_gpio_init(at572d940hf_gpio, 3);
+}
+
+/* --------------------------------------------------------------------
+ *  Interrupt initialization
+ * -------------------------------------------------------------------- */
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at572d940hf_default_irq_priority[NR_AIC_IRQS] __initdata = {
+	7,	/* Advanced Interrupt Controller */
+	7,	/* System Peripherals */
+	0,	/* Parallel IO Controller A */
+	0,	/* Parallel IO Controller B */
+	0,	/* Parallel IO Controller C */
+	3,	/* Ethernet */
+	6,	/* USART 0 */
+	6,	/* USART 1 */
+	6,	/* USART 2 */
+	0,	/* Multimedia Card Interface */
+	4,	/* USB Device Port */
+	0,	/* Two-Wire Interface 0 */
+	6,	/* Serial Peripheral Interface 0 */
+	6,	/* Serial Peripheral Interface 1 */
+	5,	/* Serial Synchronous Controller 0 */
+	5,	/* Serial Synchronous Controller 1 */
+	5,	/* Serial Synchronous Controller 2 */
+	0,	/* Timer Counter 0 */
+	0,	/* Timer Counter 1 */
+	0,	/* Timer Counter 2 */
+	3,	/* USB Host port */
+	3,	/* Serial Synchronous Controller 3 */
+	0,	/* Two-Wire Interface 1 */
+	0,	/* CAN Controller 0 */
+	0,	/* CAN Controller 1 */
+	0,	/* mAgicV HALT line */
+	0,	/* mAgicV SIRQ0 line */
+	0,	/* mAgicV exception line */
+	0,	/* mAgicV end of DMA line */
+	0,	/* Advanced Interrupt Controller */
+	0,	/* Advanced Interrupt Controller */
+	0,	/* Advanced Interrupt Controller */
+};
+
+void __init at572d940hf_init_interrupts(unsigned int priority[NR_AIC_IRQS])
+{
+	if (!priority)
+		priority = at572d940hf_default_irq_priority;
+
+	/* Initialize the AIC interrupt controller */
+	at91_aic_init(priority);
+
+	/* Enable GPIO interrupts */
+	at91_gpio_irq_setup();
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/at572d940hf_devices.c linux-libre-2.6.34-gnu1/arch/arm/mach-at91/at572d940hf_devices.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/at572d940hf_devices.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/at572d940hf_devices.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,970 @@
+/*
+ * arch/arm/mach-at91/at572d940hf_devices.c
+ *
+ * Copyright (C) 2008 Atmel Antonio R. Costa <costa.antonior@gmail.com>
+ * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
+ * Copyright (C) 2005 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at572d940hf.h>
+#include <mach/at572d940hf_matrix.h>
+#include <mach/at91sam9_smc.h>
+
+#include "generic.h"
+#include "sam9_smc.h"
+
+
+/* --------------------------------------------------------------------
+ *  USB Host
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
+static struct at91_usbh_data usbh_data;
+
+static struct resource usbh_resources[] = {
+	[0] = {
+		.start	= AT572D940HF_UHP_BASE,
+		.end	= AT572D940HF_UHP_BASE + SZ_1M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT572D940HF_ID_UHP,
+		.end	= AT572D940HF_ID_UHP,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at572d940hf_usbh_device = {
+	.name		= "at91_ohci",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &ohci_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &usbh_data,
+	},
+	.resource	= usbh_resources,
+	.num_resources	= ARRAY_SIZE(usbh_resources),
+};
+
+void __init at91_add_device_usbh(struct at91_usbh_data *data)
+{
+	if (!data)
+		return;
+
+	usbh_data = *data;
+	platform_device_register(&at572d940hf_usbh_device);
+
+}
+#else
+void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  USB Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_USB_GADGET_AT91
+static struct at91_udc_data udc_data;
+
+static struct resource udc_resources[] = {
+	[0] = {
+		.start	= AT572D940HF_BASE_UDP,
+		.end	= AT572D940HF_BASE_UDP + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT572D940HF_ID_UDP,
+		.end	= AT572D940HF_ID_UDP,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at572d940hf_udc_device = {
+	.name		= "at91_udc",
+	.id		= -1,
+	.dev		= {
+				.platform_data		= &udc_data,
+	},
+	.resource	= udc_resources,
+	.num_resources	= ARRAY_SIZE(udc_resources),
+};
+
+void __init at91_add_device_udc(struct at91_udc_data *data)
+{
+	if (!data)
+		return;
+
+	if (data->vbus_pin) {
+		at91_set_gpio_input(data->vbus_pin, 0);
+		at91_set_deglitch(data->vbus_pin, 1);
+	}
+
+	/* Pullup pin is handled internally */
+
+	udc_data = *data;
+	platform_device_register(&at572d940hf_udc_device);
+}
+#else
+void __init at91_add_device_udc(struct at91_udc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  Ethernet
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
+static u64 eth_dmamask = DMA_BIT_MASK(32);
+static struct at91_eth_data eth_data;
+
+static struct resource eth_resources[] = {
+	[0] = {
+		.start	= AT572D940HF_BASE_EMAC,
+		.end	= AT572D940HF_BASE_EMAC + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT572D940HF_ID_EMAC,
+		.end	= AT572D940HF_ID_EMAC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at572d940hf_eth_device = {
+	.name		= "macb",
+	.id		= -1,
+	.dev		= {
+			.dma_mask		= &eth_dmamask,
+			.coherent_dma_mask	= DMA_BIT_MASK(32),
+			.platform_data		= &eth_data,
+	},
+	.resource	= eth_resources,
+	.num_resources	= ARRAY_SIZE(eth_resources),
+};
+
+void __init at91_add_device_eth(struct at91_eth_data *data)
+{
+	if (!data)
+		return;
+
+	if (data->phy_irq_pin) {
+		at91_set_gpio_input(data->phy_irq_pin, 0);
+		at91_set_deglitch(data->phy_irq_pin, 1);
+	}
+
+	/* Only RMII is supported */
+	data->is_rmii = 1;
+
+	/* Pins used for RMII */
+	at91_set_A_periph(AT91_PIN_PA16, 0);	/* ETXCK_EREFCK */
+	at91_set_A_periph(AT91_PIN_PA17, 0);	/* ERXDV */
+	at91_set_A_periph(AT91_PIN_PA18, 0);	/* ERX0 */
+	at91_set_A_periph(AT91_PIN_PA19, 0);	/* ERX1 */
+	at91_set_A_periph(AT91_PIN_PA20, 0);	/* ERXER */
+	at91_set_A_periph(AT91_PIN_PA23, 0);	/* ETXEN */
+	at91_set_A_periph(AT91_PIN_PA21, 0);	/* ETX0 */
+	at91_set_A_periph(AT91_PIN_PA22, 0);	/* ETX1 */
+	at91_set_A_periph(AT91_PIN_PA13, 0);	/* EMDIO */
+	at91_set_A_periph(AT91_PIN_PA14, 0);	/* EMDC */
+
+	eth_data = *data;
+	platform_device_register(&at572d940hf_eth_device);
+}
+#else
+void __init at91_add_device_eth(struct at91_eth_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  MMC / SD
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
+static struct at91_mmc_data mmc_data;
+
+static struct resource mmc_resources[] = {
+	[0] = {
+		.start	= AT572D940HF_BASE_MCI,
+		.end	= AT572D940HF_BASE_MCI + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT572D940HF_ID_MCI,
+		.end	= AT572D940HF_ID_MCI,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at572d940hf_mmc_device = {
+	.name		= "at91_mci",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &mmc_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &mmc_data,
+	},
+	.resource	= mmc_resources,
+	.num_resources	= ARRAY_SIZE(mmc_resources),
+};
+
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
+{
+	if (!data)
+		return;
+
+	/* input/irq */
+	if (data->det_pin) {
+		at91_set_gpio_input(data->det_pin, 1);
+		at91_set_deglitch(data->det_pin, 1);
+	}
+	if (data->wp_pin)
+		at91_set_gpio_input(data->wp_pin, 1);
+	if (data->vcc_pin)
+		at91_set_gpio_output(data->vcc_pin, 0);
+
+	/* CLK */
+	at91_set_A_periph(AT91_PIN_PC22, 0);
+
+	/* CMD */
+	at91_set_A_periph(AT91_PIN_PC23, 1);
+
+	/* DAT0, maybe DAT1..DAT3 */
+	at91_set_A_periph(AT91_PIN_PC24, 1);
+	if (data->wire4) {
+		at91_set_A_periph(AT91_PIN_PC25, 1);
+		at91_set_A_periph(AT91_PIN_PC26, 1);
+		at91_set_A_periph(AT91_PIN_PC27, 1);
+	}
+
+	mmc_data = *data;
+	platform_device_register(&at572d940hf_mmc_device);
+}
+#else
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  NAND / SmartMedia
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
+static struct atmel_nand_data nand_data;
+
+#define NAND_BASE	AT91_CHIPSELECT_3
+
+static struct resource nand_resources[] = {
+	{
+		.start	= NAND_BASE,
+		.end	= NAND_BASE + SZ_256M - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device at572d940hf_nand_device = {
+	.name		= "atmel_nand",
+	.id		= -1,
+	.dev		= {
+				.platform_data	= &nand_data,
+	},
+	.resource	= nand_resources,
+	.num_resources	= ARRAY_SIZE(nand_resources),
+};
+
+void __init at91_add_device_nand(struct atmel_nand_data *data)
+{
+	unsigned long csa;
+
+	if (!data)
+		return;
+
+	csa = at91_sys_read(AT91_MATRIX_EBICSA);
+	at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
+
+	/* enable pin */
+	if (data->enable_pin)
+		at91_set_gpio_output(data->enable_pin, 1);
+
+	/* ready/busy pin */
+	if (data->rdy_pin)
+		at91_set_gpio_input(data->rdy_pin, 1);
+
+	/* card detect pin */
+	if (data->det_pin)
+		at91_set_gpio_input(data->det_pin, 1);
+
+	at91_set_A_periph(AT91_PIN_PB28, 0);		/* A[22] */
+	at91_set_B_periph(AT91_PIN_PA28, 0);		/* NANDOE */
+	at91_set_B_periph(AT91_PIN_PA29, 0);		/* NANDWE */
+
+	nand_data = *data;
+	platform_device_register(&at572d940hf_nand_device);
+}
+
+#else
+void __init at91_add_device_nand(struct atmel_nand_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  TWI (i2c)
+ * -------------------------------------------------------------------- */
+
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+	.sda_pin		= AT91_PIN_PC7,
+	.sda_is_open_drain	= 1,
+	.scl_pin		= AT91_PIN_PC8,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,		/* ~100 kHz */
+};
+
+static struct platform_device at572d940hf_twi_device {
+	.name			= "i2c-gpio",
+	.id			= -1,
+	.dev.platform_data	= &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+	at91_set_GPIO_periph(AT91_PIN_PC7, 1);		/* TWD (SDA) */
+	at91_set_multi_drive(AT91_PIN_PC7, 1);
+
+	at91_set_GPIO_periph(AT91_PIN_PA8, 1);		/* TWCK (SCL) */
+	at91_set_multi_drive(AT91_PIN_PC8, 1);
+
+	i2c_register_board_info(0, devices, nr_devices);
+	platform_device_register(&at572d940hf_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+
+static struct resource twi0_resources[] = {
+	[0] = {
+		.start	= AT572D940HF_BASE_TWI0,
+		.end	= AT572D940HF_BASE_TWI0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT572D940HF_ID_TWI0,
+		.end	= AT572D940HF_ID_TWI0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at572d940hf_twi0_device = {
+	.name		= "at91_i2c",
+	.id		= 0,
+	.resource	= twi0_resources,
+	.num_resources	= ARRAY_SIZE(twi0_resources),
+};
+
+static struct resource twi1_resources[] = {
+	[0] = {
+		.start	= AT572D940HF_BASE_TWI1,
+		.end	= AT572D940HF_BASE_TWI1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT572D940HF_ID_TWI1,
+		.end	= AT572D940HF_ID_TWI1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at572d940hf_twi1_device = {
+	.name		= "at91_i2c",
+	.id		= 1,
+	.resource	= twi1_resources,
+	.num_resources	= ARRAY_SIZE(twi1_resources),
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+	/* pins used for TWI0 interface */
+	at91_set_A_periph(AT91_PIN_PC7, 0);		/* TWD */
+	at91_set_multi_drive(AT91_PIN_PC7, 1);
+
+	at91_set_A_periph(AT91_PIN_PC8, 0);		/* TWCK */
+	at91_set_multi_drive(AT91_PIN_PC8, 1);
+
+	/* pins used for TWI1 interface */
+	at91_set_A_periph(AT91_PIN_PC20, 0);		/* TWD */
+	at91_set_multi_drive(AT91_PIN_PC20, 1);
+
+	at91_set_A_periph(AT91_PIN_PC21, 0);		/* TWCK */
+	at91_set_multi_drive(AT91_PIN_PC21, 1);
+
+	i2c_register_board_info(0, devices, nr_devices);
+	platform_device_register(&at572d940hf_twi0_device);
+	platform_device_register(&at572d940hf_twi1_device);
+}
+#else
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  SPI
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+static struct resource spi0_resources[] = {
+	[0] = {
+		.start	= AT572D940HF_BASE_SPI0,
+		.end	= AT572D940HF_BASE_SPI0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT572D940HF_ID_SPI0,
+		.end	= AT572D940HF_ID_SPI0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at572d940hf_spi0_device = {
+	.name		= "atmel_spi",
+	.id		= 0,
+	.dev		= {
+				.dma_mask		= &spi_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= spi0_resources,
+	.num_resources	= ARRAY_SIZE(spi0_resources),
+};
+
+static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 };
+
+static struct resource spi1_resources[] = {
+	[0] = {
+		.start	= AT572D940HF_BASE_SPI1,
+		.end	= AT572D940HF_BASE_SPI1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT572D940HF_ID_SPI1,
+		.end	= AT572D940HF_ID_SPI1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at572d940hf_spi1_device = {
+	.name		= "atmel_spi",
+	.id		= 1,
+	.dev		= {
+				.dma_mask		= &spi_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= spi1_resources,
+	.num_resources	= ARRAY_SIZE(spi1_resources),
+};
+
+static const unsigned spi1_standard_cs[4] = { AT91_PIN_PC3, AT91_PIN_PC4, AT91_PIN_PC5, AT91_PIN_PC6 };
+
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
+{
+	int i;
+	unsigned long cs_pin;
+	short enable_spi0 = 0;
+	short enable_spi1 = 0;
+
+	/* Choose SPI chip-selects */
+	for (i = 0; i < nr_devices; i++) {
+		if (devices[i].controller_data)
+			cs_pin = (unsigned long) devices[i].controller_data;
+		else if (devices[i].bus_num == 0)
+			cs_pin = spi0_standard_cs[devices[i].chip_select];
+		else
+			cs_pin = spi1_standard_cs[devices[i].chip_select];
+
+		if (devices[i].bus_num == 0)
+			enable_spi0 = 1;
+		else
+			enable_spi1 = 1;
+
+		/* enable chip-select pin */
+		at91_set_gpio_output(cs_pin, 1);
+
+		/* pass chip-select pin to driver */
+		devices[i].controller_data = (void *) cs_pin;
+	}
+
+	spi_register_board_info(devices, nr_devices);
+
+	/* Configure SPI bus(es) */
+	if (enable_spi0) {
+		at91_set_A_periph(AT91_PIN_PA0, 0);	/* SPI0_MISO */
+		at91_set_A_periph(AT91_PIN_PA1, 0);	/* SPI0_MOSI */
+		at91_set_A_periph(AT91_PIN_PA2, 0);	/* SPI0_SPCK */
+
+		at91_clock_associate("spi0_clk", &at572d940hf_spi0_device.dev, "spi_clk");
+		platform_device_register(&at572d940hf_spi0_device);
+	}
+	if (enable_spi1) {
+		at91_set_A_periph(AT91_PIN_PC0, 0);	/* SPI1_MISO */
+		at91_set_A_periph(AT91_PIN_PC1, 0);	/* SPI1_MOSI */
+		at91_set_A_periph(AT91_PIN_PC2, 0);	/* SPI1_SPCK */
+
+		at91_clock_associate("spi1_clk", &at572d940hf_spi1_device.dev, "spi_clk");
+		platform_device_register(&at572d940hf_spi1_device);
+	}
+}
+#else
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  Timer/Counter blocks
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+
+static struct resource tcb_resources[] = {
+	[0] = {
+		.start	= AT572D940HF_BASE_TCB,
+		.end	= AT572D940HF_BASE_TCB + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT572D940HF_ID_TC0,
+		.end	= AT572D940HF_ID_TC0,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= AT572D940HF_ID_TC1,
+		.end	= AT572D940HF_ID_TC1,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start	= AT572D940HF_ID_TC2,
+		.end	= AT572D940HF_ID_TC2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at572d940hf_tcb_device = {
+	.name		= "atmel_tcb",
+	.id		= 0,
+	.resource	= tcb_resources,
+	.num_resources	= ARRAY_SIZE(tcb_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+	/* this chip has a separate clock and irq for each TC channel */
+	at91_clock_associate("tc0_clk", &at572d940hf_tcb_device.dev, "t0_clk");
+	at91_clock_associate("tc1_clk", &at572d940hf_tcb_device.dev, "t1_clk");
+	at91_clock_associate("tc2_clk", &at572d940hf_tcb_device.dev, "t2_clk");
+	platform_device_register(&at572d940hf_tcb_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  RTT
+ * -------------------------------------------------------------------- */
+
+static struct resource rtt_resources[] = {
+	{
+		.start	= AT91_BASE_SYS + AT91_RTT,
+		.end	= AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device at572d940hf_rtt_device = {
+	.name		= "at91_rtt",
+	.id		= 0,
+	.resource	= rtt_resources,
+	.num_resources	= ARRAY_SIZE(rtt_resources),
+};
+
+static void __init at91_add_device_rtt(void)
+{
+	platform_device_register(&at572d940hf_rtt_device);
+}
+
+
+/* --------------------------------------------------------------------
+ *  Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
+static struct platform_device at572d940hf_wdt_device = {
+	.name		= "at91_wdt",
+	.id		= -1,
+	.num_resources	= 0,
+};
+
+static void __init at91_add_device_watchdog(void)
+{
+	platform_device_register(&at572d940hf_wdt_device);
+}
+#else
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  UART
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SERIAL_ATMEL)
+static struct resource dbgu_resources[] = {
+	[0] = {
+		.start	= AT91_VA_BASE_SYS + AT91_DBGU,
+		.end	= AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91_ID_SYS,
+		.end	= AT91_ID_SYS,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data dbgu_data = {
+	.use_dma_tx	= 0,
+	.use_dma_rx	= 0,		/* DBGU not capable of receive DMA */
+	.regs		= (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
+};
+
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at572d940hf_dbgu_device = {
+	.name		= "atmel_usart",
+	.id		= 0,
+	.dev		= {
+				.dma_mask		= &dbgu_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &dbgu_data,
+	},
+	.resource	= dbgu_resources,
+	.num_resources	= ARRAY_SIZE(dbgu_resources),
+};
+
+static inline void configure_dbgu_pins(void)
+{
+	at91_set_A_periph(AT91_PIN_PC31, 1);		/* DTXD */
+	at91_set_A_periph(AT91_PIN_PC30, 0);		/* DRXD */
+}
+
+static struct resource uart0_resources[] = {
+	[0] = {
+		.start	= AT572D940HF_BASE_US0,
+		.end	= AT572D940HF_BASE_US0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT572D940HF_ID_US0,
+		.end	= AT572D940HF_ID_US0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data uart0_data = {
+	.use_dma_tx	= 1,
+	.use_dma_rx	= 1,
+};
+
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at572d940hf_uart0_device = {
+	.name		= "atmel_usart",
+	.id		= 1,
+	.dev		= {
+				.dma_mask		= &uart0_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart0_data,
+	},
+	.resource	= uart0_resources,
+	.num_resources	= ARRAY_SIZE(uart0_resources),
+};
+
+static inline void configure_usart0_pins(unsigned pins)
+{
+	at91_set_A_periph(AT91_PIN_PA8, 1);		/* TXD0 */
+	at91_set_A_periph(AT91_PIN_PA7, 0);		/* RXD0 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_A_periph(AT91_PIN_PA10, 0);	/* RTS0 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_A_periph(AT91_PIN_PA9, 0);	/* CTS0 */
+}
+
+static struct resource uart1_resources[] = {
+	[0] = {
+		.start	= AT572D940HF_BASE_US1,
+		.end	= AT572D940HF_BASE_US1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT572D940HF_ID_US1,
+		.end	= AT572D940HF_ID_US1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data uart1_data = {
+	.use_dma_tx	= 1,
+	.use_dma_rx	= 1,
+};
+
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at572d940hf_uart1_device = {
+	.name		= "atmel_usart",
+	.id		= 2,
+	.dev		= {
+				.dma_mask		= &uart1_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart1_data,
+	},
+	.resource	= uart1_resources,
+	.num_resources	= ARRAY_SIZE(uart1_resources),
+};
+
+static inline void configure_usart1_pins(unsigned pins)
+{
+	at91_set_A_periph(AT91_PIN_PC10, 1);		/* TXD1 */
+	at91_set_A_periph(AT91_PIN_PC9 , 0);		/* RXD1 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_A_periph(AT91_PIN_PC12, 0);	/* RTS1 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_A_periph(AT91_PIN_PC11, 0);	/* CTS1 */
+}
+
+static struct resource uart2_resources[] = {
+	[0] = {
+		.start	= AT572D940HF_BASE_US2,
+		.end	= AT572D940HF_BASE_US2 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT572D940HF_ID_US2,
+		.end	= AT572D940HF_ID_US2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data uart2_data = {
+	.use_dma_tx	= 1,
+	.use_dma_rx	= 1,
+};
+
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at572d940hf_uart2_device = {
+	.name		= "atmel_usart",
+	.id		= 3,
+	.dev		= {
+				.dma_mask		= &uart2_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart2_data,
+	},
+	.resource	= uart2_resources,
+	.num_resources	= ARRAY_SIZE(uart2_resources),
+};
+
+static inline void configure_usart2_pins(unsigned pins)
+{
+	at91_set_A_periph(AT91_PIN_PC15, 1);		/* TXD2 */
+	at91_set_A_periph(AT91_PIN_PC14, 0);		/* RXD2 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_A_periph(AT91_PIN_PC17, 0);	/* RTS2 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_A_periph(AT91_PIN_PC16, 0);	/* CTS2 */
+}
+
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
+struct platform_device *atmel_default_console_device;	/* the serial console device */
+
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+	struct platform_device *pdev;
+
+	switch (id) {
+		case 0:		/* DBGU */
+			pdev = &at572d940hf_dbgu_device;
+			configure_dbgu_pins();
+			at91_clock_associate("mck", &pdev->dev, "usart");
+			break;
+		case AT572D940HF_ID_US0:
+			pdev = &at572d940hf_uart0_device;
+			configure_usart0_pins(pins);
+			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
+			break;
+		case AT572D940HF_ID_US1:
+			pdev = &at572d940hf_uart1_device;
+			configure_usart1_pins(pins);
+			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
+			break;
+		case AT572D940HF_ID_US2:
+			pdev = &at572d940hf_uart2_device;
+			configure_usart2_pins(pins);
+			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
+			break;
+		default:
+			return;
+	}
+	pdev->id = portnr;		/* update to mapped ID */
+
+	if (portnr < ATMEL_MAX_UART)
+		at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+	if (portnr < ATMEL_MAX_UART)
+		atmel_default_console_device = at91_uarts[portnr];
+}
+
+void __init at91_add_device_serial(void)
+{
+	int i;
+
+	for (i = 0; i < ATMEL_MAX_UART; i++) {
+		if (at91_uarts[i])
+			platform_device_register(at91_uarts[i]);
+	}
+
+	if (!atmel_default_console_device)
+		printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+
+#else
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
+void __init at91_add_device_serial(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  mAgic
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_MAGICV
+static struct resource mAgic_resources[] = {
+	{
+		.start = AT91_MAGIC_PM_BASE,
+		.end   = AT91_MAGIC_PM_BASE + AT91_MAGIC_PM_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = AT91_MAGIC_DM_I_BASE,
+		.end   = AT91_MAGIC_DM_I_BASE + AT91_MAGIC_DM_I_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = AT91_MAGIC_DM_F_BASE,
+		.end   = AT91_MAGIC_DM_F_BASE + AT91_MAGIC_DM_F_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = AT91_MAGIC_DM_DB_BASE,
+		.end   = AT91_MAGIC_DM_DB_BASE + AT91_MAGIC_DM_DB_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = AT91_MAGIC_REGS_BASE,
+		.end   = AT91_MAGIC_REGS_BASE + AT91_MAGIC_REGS_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = AT91_MAGIC_EXTPAGE_BASE,
+		.end   = AT91_MAGIC_EXTPAGE_BASE + AT91_MAGIC_EXTPAGE_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start  = AT572D940HF_ID_MSIRQ0,
+		.end    = AT572D940HF_ID_MSIRQ0,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.start  = AT572D940HF_ID_MHALT,
+		.end    = AT572D940HF_ID_MHALT,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.start  = AT572D940HF_ID_MEXC,
+		.end    = AT572D940HF_ID_MEXC,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.start  = AT572D940HF_ID_MEDMA,
+		.end    = AT572D940HF_ID_MEDMA,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device mAgic_device = {
+	.name           = "mAgic",
+	.id             = -1,
+	.num_resources  = ARRAY_SIZE(mAgic_resources),
+	.resource       = mAgic_resources,
+};
+
+void __init at91_add_device_mAgic(void)
+{
+	platform_device_register(&mAgic_device);
+}
+#else
+void __init at91_add_device_mAgic(void) {}
+#endif
+
+
+/* -------------------------------------------------------------------- */
+
+/*
+ * These devices are always present and don't need any board-specific
+ * setup.
+ */
+static int __init at91_add_standard_devices(void)
+{
+	at91_add_device_rtt();
+	at91_add_device_watchdog();
+	at91_add_device_tc();
+	return 0;
+}
+
+arch_initcall(at91_add_standard_devices);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/at91rm9200_time.c linux-libre-2.6.34-gnu1/arch/arm/mach-at91/at91rm9200_time.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/at91rm9200_time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/at91rm9200_time.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,6 +58,12 @@ static irqreturn_t at91rm9200_timer_inte
 {
 	u32	sr = at91_sys_read(AT91_ST_SR) & irqmask;
 
+	/*
+	 * irqs should be disabled here, but as the irq is shared they are only
+	 * guaranteed to be off if the timer irq is registered first.
+	 */
+	WARN_ON_ONCE(!irqs_disabled());
+
 	/* simulate "oneshot" timer with alarm */
 	if (sr & AT91_ST_ALMS) {
 		clkevt.event_handler(&clkevt);
@@ -132,24 +138,11 @@ clkevt32k_mode(enum clock_event_mode mod
 static int
 clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
 {
-	unsigned long	flags;
 	u32		alm;
 	int		status = 0;
 
 	BUG_ON(delta < 2);
 
-	/* Use "raw" primitives so we behave correctly on RT kernels. */
-	raw_local_irq_save(flags);
-
-	/*
-	 * According to Thomas Gleixner irqs are already disabled here.  Simply
-	 * removing raw_local_irq_save above (and the matching
-	 * raw_local_irq_restore) was not accepted.  See
-	 * http://thread.gmane.org/gmane.linux.ports.arm.kernel/41174
-	 * So for now (2008-11-20) just warn once if irqs were not disabled ...
-	 */
-	WARN_ON_ONCE(!raw_irqs_disabled_flags(flags));
-
 	/* The alarm IRQ uses absolute time (now+delta), not the relative
 	 * time (delta) in our calling convention.  Like all clockevents
 	 * using such "match" hardware, we have a race to defend against.
@@ -169,7 +162,6 @@ clkevt32k_next_event(unsigned long delta
 	alm += delta;
 	at91_sys_write(AT91_ST_RTAR, alm);
 
-	raw_local_irq_restore(flags);
 	return status;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/at91sam926x_time.c linux-libre-2.6.34-gnu1/arch/arm/mach-at91/at91sam926x_time.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/at91sam926x_time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/at91sam926x_time.c	2010-05-16 17:17:36.000000000 -0400
@@ -62,16 +62,12 @@ static struct clocksource pit_clk = {
 static void
 pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
 {
-	unsigned long	flags;
-
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
-		/* update clocksource counter, then enable the IRQ */
-		raw_local_irq_save(flags);
+		/* update clocksource counter */
 		pit_cnt += pit_cycle * PIT_PICNT(at91_sys_read(AT91_PIT_PIVR));
 		at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN
 				| AT91_PIT_PITIEN);
-		raw_local_irq_restore(flags);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 		BUG();
@@ -100,6 +96,11 @@ static struct clock_event_device pit_clk
  */
 static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id)
 {
+	/*
+	 * irqs should be disabled here, but as the irq is shared they are only
+	 * guaranteed to be off if the timer irq is registered first.
+	 */
+	WARN_ON_ONCE(!irqs_disabled());
 
 	/* The PIT interrupt may be disabled, and is shared */
 	if ((pit_clkevt.mode == CLOCK_EVT_MODE_PERIODIC)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/board-at572d940hf_ek.c linux-libre-2.6.34-gnu1/arch/arm/mach-at91/board-at572d940hf_ek.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/board-at572d940hf_ek.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/board-at572d940hf_ek.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,328 @@
+/*
+ * linux/arch/arm/mach-at91/board-at572d940hf_ek.c
+ *
+ * Copyright (C) 2008 Atmel Antonio R. Costa <costa.antonior@gmail.com>
+ * Copyright (C) 2005 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ds1305.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init eb_map_io(void)
+{
+	/* Initialize processor: 12.500 MHz crystal */
+	at572d940hf_initialize(12000000);
+
+	/* DBGU on ttyS0. (Rx & Tx only) */
+	at91_register_uart(0, 0, 0);
+
+	/* USART0 on ttyS1. (Rx & Tx only) */
+	at91_register_uart(AT572D940HF_ID_US0, 1, 0);
+
+	/* USART1 on ttyS2. (Rx & Tx only) */
+	at91_register_uart(AT572D940HF_ID_US1, 2, 0);
+
+	/* USART2 on ttyS3. (Tx & Rx only */
+	at91_register_uart(AT572D940HF_ID_US2, 3, 0);
+
+	/* set serial console to ttyS0 (ie, DBGU) */
+	at91_set_serial_console(0);
+}
+
+static void __init eb_init_irq(void)
+{
+	at572d940hf_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host Port
+ */
+static struct at91_usbh_data __initdata eb_usbh_data = {
+	.ports		= 2,
+};
+
+
+/*
+ * USB Device Port
+ */
+static struct at91_udc_data __initdata eb_udc_data = {
+	.vbus_pin	= 0,		/* no VBUS detection,UDC always on */
+	.pullup_pin	= 0,		/* pull-up driven by UDC */
+};
+
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata eb_mmc_data = {
+	.wire4		= 1,
+/*	.det_pin	= ... not connected */
+/*	.wp_pin		= ... not connected */
+/*	.vcc_pin	= ... not connected */
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata eb_eth_data = {
+	.phy_irq_pin	= AT91_PIN_PB25,
+	.is_rmii	= 1,
+};
+
+/*
+ * NOR flash
+ */
+
+static struct mtd_partition eb_nor_partitions[] = {
+	{
+		.name		= "Raw Environment",
+		.offset		= 0,
+		.size		= SZ_4M,
+		.mask_flags	= 0,
+	},
+	{
+		.name		= "OS FS",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 3 * SZ_1M,
+		.mask_flags	= 0,
+	},
+	{
+		.name		= "APP FS",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0,
+	},
+};
+
+static void nor_flash_set_vpp(struct map_info* mi, int i) {
+};
+
+static struct physmap_flash_data nor_flash_data = {
+	.width		= 4,
+	.parts		= eb_nor_partitions,
+	.nr_parts	= ARRAY_SIZE(eb_nor_partitions),
+	.set_vpp	= nor_flash_set_vpp,
+};
+
+static struct resource nor_flash_resources[] = {
+	{
+		.start	= AT91_CHIPSELECT_0,
+		.end	= AT91_CHIPSELECT_0 + SZ_16M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device nor_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+				.platform_data = &nor_flash_data,
+			},
+	.resource	= nor_flash_resources,
+	.num_resources	= ARRAY_SIZE(nor_flash_resources),
+};
+
+static struct sam9_smc_config __initdata eb_nor_smc_config = {
+	.ncs_read_setup		= 1,
+	.nrd_setup		= 1,
+	.ncs_write_setup	= 1,
+	.nwe_setup		= 1,
+
+	.ncs_read_pulse		= 7,
+	.nrd_pulse		= 7,
+	.ncs_write_pulse	= 7,
+	.nwe_pulse		= 7,
+
+	.read_cycle		= 9,
+	.write_cycle		= 9,
+
+	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_32,
+	.tdf_cycles		= 1,
+};
+
+static void __init eb_add_device_nor(void)
+{
+	/* configure chip-select 0 (NOR) */
+	sam9_smc_configure(0, &eb_nor_smc_config);
+	platform_device_register(&nor_flash);
+}
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata eb_nand_partition[] = {
+	{
+		.name	= "Partition 1",
+		.offset	= 0,
+		.size	= SZ_16M,
+	},
+	{
+		.name	= "Partition 2",
+		.offset = MTDPART_OFS_NXTBLK,
+		.size	= MTDPART_SIZ_FULL,
+	}
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+	*num_partitions = ARRAY_SIZE(eb_nand_partition);
+	return eb_nand_partition;
+}
+
+static struct atmel_nand_data __initdata eb_nand_data = {
+	.ale		= 22,
+	.cle		= 21,
+/*	.det_pin	= ... not connected */
+/*	.rdy_pin	= AT91_PIN_PC16, */
+	.enable_pin	= AT91_PIN_PA15,
+	.partition_info	= nand_partitions,
+#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
+	.bus_width_16	= 1,
+#else
+	.bus_width_16	= 0,
+#endif
+};
+
+static struct sam9_smc_config __initdata eb_nand_smc_config = {
+	.ncs_read_setup		= 0,
+	.nrd_setup		= 0,
+	.ncs_write_setup	= 1,
+	.nwe_setup		= 1,
+
+	.ncs_read_pulse		= 3,
+	.nrd_pulse		= 3,
+	.ncs_write_pulse	= 3,
+	.nwe_pulse		= 3,
+
+	.read_cycle		= 5,
+	.write_cycle		= 5,
+
+	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
+	.tdf_cycles		= 12,
+};
+
+static void __init eb_add_device_nand(void)
+{
+	/* setup bus-width (8 or 16) */
+	if (eb_nand_data.bus_width_16)
+		eb_nand_smc_config.mode |= AT91_SMC_DBW_16;
+	else
+		eb_nand_smc_config.mode |= AT91_SMC_DBW_8;
+
+	/* configure chip-select 3 (NAND) */
+	sam9_smc_configure(3, &eb_nand_smc_config);
+
+	at91_add_device_nand(&eb_nand_data);
+}
+
+
+/*
+ * SPI devices
+ */
+static struct resource rtc_resources[] = {
+	[0] = {
+		.start	= AT572D940HF_ID_IRQ1,
+		.end	= AT572D940HF_ID_IRQ1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct ds1305_platform_data ds1306_data = {
+	.is_ds1306	= true,
+	.en_1hz		= false,
+};
+
+static struct spi_board_info eb_spi_devices[] = {
+	{	/* RTC Dallas DS1306 */
+		.modalias	= "rtc-ds1305",
+		.chip_select	= 3,
+		.mode		= SPI_CS_HIGH | SPI_CPOL | SPI_CPHA,
+		.max_speed_hz	= 500000,
+		.bus_num	= 0,
+		.irq		= AT572D940HF_ID_IRQ1,
+		.platform_data	= (void *) &ds1306_data,
+	},
+#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
+	{	/* Dataflash card */
+		.modalias	= "mtd_dataflash",
+		.chip_select	= 0,
+		.max_speed_hz	= 15 * 1000 * 1000,
+		.bus_num	= 0,
+	},
+#endif
+};
+
+static void __init eb_board_init(void)
+{
+	/* Serial */
+	at91_add_device_serial();
+	/* USB Host */
+	at91_add_device_usbh(&eb_usbh_data);
+	/* USB Device */
+	at91_add_device_udc(&eb_udc_data);
+	/* I2C */
+	at91_add_device_i2c(NULL, 0);
+	/* NOR */
+	eb_add_device_nor();
+	/* NAND */
+	eb_add_device_nand();
+	/* SPI */
+	at91_add_device_spi(eb_spi_devices, ARRAY_SIZE(eb_spi_devices));
+	/* MMC */
+	at91_add_device_mmc(0, &eb_mmc_data);
+	/* Ethernet */
+	at91_add_device_eth(&eb_eth_data);
+	/* mAgic */
+	at91_add_device_mAgic();
+}
+
+MACHINE_START(AT572D940HFEB, "Atmel AT91D940HF-EB")
+	/* Maintainer: Atmel <costa.antonior@gmail.com> */
+	.phys_io	= AT91_BASE_SYS,
+	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+	.boot_params	= AT91_SDRAM_BASE + 0x100,
+	.timer		= &at91sam926x_timer,
+	.map_io		= eb_map_io,
+	.init_irq	= eb_init_irq,
+	.init_machine	= eb_board_init,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/board-sam9g20ek.c linux-libre-2.6.34-gnu1/arch/arm/mach-at91/board-sam9g20ek.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/board-sam9g20ek.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/board-sam9g20ek.c	2010-05-16 17:17:36.000000000 -0400
@@ -271,10 +271,12 @@ static void __init ek_add_device_buttons
 
 
 static struct i2c_board_info __initdata ek_i2c_devices[] = {
-	{
-		I2C_BOARD_INFO("24c512", 0x50),
-		I2C_BOARD_INFO("wm8731", 0x1b),
-	},
+        {
+                I2C_BOARD_INFO("24c512", 0x50)
+        },
+        {
+                I2C_BOARD_INFO("wm8731", 0x1b)
+        },
 };
 
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-at91/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <mach/cpu.h>
 
 #include "clock.h"
+#include "generic.h"
 
 
 /*
@@ -628,7 +629,7 @@ static void __init at91_pllb_usbfs_clock
 		at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
 	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() ||
 		   cpu_is_at91sam9263() || cpu_is_at91sam9g20() ||
-		   cpu_is_at91sam9g10()) {
+		   cpu_is_at91sam9g10() || cpu_is_at572d940hf()) {
 		uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
 		udpck.pmc_mask = AT91SAM926x_PMC_UDP;
 	} else if (cpu_is_at91cap9()) {
@@ -711,12 +712,13 @@ int __init at91_clock_init(unsigned long
 	/*
 	 * USB HS clock init
 	 */
-	if (cpu_has_utmi())
+	if (cpu_has_utmi()) {
 		/*
 		 * multiplier is hard-wired to 40
 		 * (obtain the USB High Speed 480 MHz when input is 12 MHz)
 		 */
 		utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz;
+	}
 
 	/*
 	 * USB FS clock init
@@ -746,7 +748,7 @@ int __init at91_clock_init(unsigned long
 		mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ?
 			freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));	/* mdiv */
 	} else {
-		mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));      /* mdiv */
+		mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));		/* mdiv */
 	}
 
 	/* Register the PMC's standard clocks */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-at91/clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,7 @@ struct clk {
 	struct clk	*parent;
 	u32		pmc_mask;
 	void		(*mode)(struct clk *, int);
-	unsigned	id:2;		/* PCK0..3, or 32k/main/a/b */
+	unsigned	id:3;		/* PCK0..4, or 32k/main/a/b */
 	unsigned	type;		/* clock type */
 	u16		users;
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/generic.h linux-libre-2.6.34-gnu1/arch/arm/mach-at91/generic.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/generic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/generic.h	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@ extern void __init at91sam9rl_initialize
 extern void __init at91sam9g45_initialize(unsigned long main_clock);
 extern void __init at91x40_initialize(unsigned long main_clock);
 extern void __init at91cap9_initialize(unsigned long main_clock);
+extern void __init at572d940hf_initialize(unsigned long main_clock);
 
  /* Interrupts */
 extern void __init at91rm9200_init_interrupts(unsigned int priority[]);
@@ -27,6 +28,7 @@ extern void __init at91sam9rl_init_inter
 extern void __init at91sam9g45_init_interrupts(unsigned int priority[]);
 extern void __init at91x40_init_interrupts(unsigned int priority[]);
 extern void __init at91cap9_init_interrupts(unsigned int priority[]);
+extern void __init at572d940hf_init_interrupts(unsigned int priority[]);
 extern void __init at91_aic_init(unsigned int priority[]);
 
  /* Timer */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/at572d940hf.h linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/at572d940hf.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/at572d940hf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/at572d940hf.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,123 @@
+/*
+ * include/mach/at572d940hf.h
+ *
+ * Antonio R. Costa <costa.antonior@gmail.com>
+ * Copyright (C) 2008 Atmel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 AT572D940HF_H
+#define AT572D940HF_H
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91_ID_FIQ		0	/* Advanced Interrupt Controller (FIQ) */
+#define AT91_ID_SYS		1	/* System Peripherals */
+#define AT572D940HF_ID_PIOA	2	/* Parallel IO Controller A */
+#define AT572D940HF_ID_PIOB	3	/* Parallel IO Controller B */
+#define AT572D940HF_ID_PIOC	4	/* Parallel IO Controller C */
+#define AT572D940HF_ID_EMAC	5	/* MACB ethernet controller */
+#define AT572D940HF_ID_US0	6	/* USART 0 */
+#define AT572D940HF_ID_US1	7	/* USART 1 */
+#define AT572D940HF_ID_US2	8	/* USART 2 */
+#define AT572D940HF_ID_MCI	9	/* Multimedia Card Interface */
+#define AT572D940HF_ID_UDP	10	/* USB Device Port */
+#define AT572D940HF_ID_TWI0	11	/* Two-Wire Interface 0 */
+#define AT572D940HF_ID_SPI0	12	/* Serial Peripheral Interface 0 */
+#define AT572D940HF_ID_SPI1	13	/* Serial Peripheral Interface 1 */
+#define AT572D940HF_ID_SSC0	14	/* Serial Synchronous Controller 0 */
+#define AT572D940HF_ID_SSC1	15	/* Serial Synchronous Controller 1 */
+#define AT572D940HF_ID_SSC2	16	/* Serial Synchronous Controller 2 */
+#define AT572D940HF_ID_TC0	17	/* Timer Counter 0 */
+#define AT572D940HF_ID_TC1	18	/* Timer Counter 1 */
+#define AT572D940HF_ID_TC2	19	/* Timer Counter 2 */
+#define AT572D940HF_ID_UHP	20	/* USB Host port */
+#define AT572D940HF_ID_SSC3	21	/* Serial Synchronous Controller 3 */
+#define AT572D940HF_ID_TWI1	22	/* Two-Wire Interface 1 */
+#define AT572D940HF_ID_CAN0	23	/* CAN Controller 0 */
+#define AT572D940HF_ID_CAN1	24	/* CAN Controller 1 */
+#define AT572D940HF_ID_MHALT	25	/* mAgicV HALT line */
+#define AT572D940HF_ID_MSIRQ0	26	/* mAgicV SIRQ0 line */
+#define AT572D940HF_ID_MEXC	27	/* mAgicV exception line */
+#define AT572D940HF_ID_MEDMA	28	/* mAgicV end of DMA line */
+#define AT572D940HF_ID_IRQ0	29	/* External Interrupt Source (IRQ0) */
+#define AT572D940HF_ID_IRQ1	30	/* External Interrupt Source (IRQ1) */
+#define AT572D940HF_ID_IRQ2	31	/* External Interrupt Source (IRQ2) */
+
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define AT572D940HF_BASE_TCB	0xfffa0000
+#define AT572D940HF_BASE_TC0	0xfffa0000
+#define AT572D940HF_BASE_TC1	0xfffa0040
+#define AT572D940HF_BASE_TC2	0xfffa0080
+#define AT572D940HF_BASE_UDP	0xfffa4000
+#define AT572D940HF_BASE_MCI	0xfffa8000
+#define AT572D940HF_BASE_TWI0	0xfffac000
+#define AT572D940HF_BASE_US0	0xfffb0000
+#define AT572D940HF_BASE_US1	0xfffb4000
+#define AT572D940HF_BASE_US2	0xfffb8000
+#define AT572D940HF_BASE_SSC0	0xfffbc000
+#define AT572D940HF_BASE_SSC1	0xfffc0000
+#define AT572D940HF_BASE_SSC2	0xfffc4000
+#define AT572D940HF_BASE_SPI0	0xfffc8000
+#define AT572D940HF_BASE_SPI1	0xfffcc000
+#define AT572D940HF_BASE_SSC3	0xfffd0000
+#define AT572D940HF_BASE_TWI1	0xfffd4000
+#define AT572D940HF_BASE_EMAC	0xfffd8000
+#define AT572D940HF_BASE_CAN0	0xfffdc000
+#define AT572D940HF_BASE_CAN1	0xfffe0000
+#define AT91_BASE_SYS		0xffffea00
+
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_SDRAMC	(0xffffea00 - AT91_BASE_SYS)
+#define AT91_SMC	(0xffffec00 - AT91_BASE_SYS)
+#define AT91_MATRIX	(0xffffee00 - AT91_BASE_SYS)
+#define AT91_AIC	(0xfffff000 - AT91_BASE_SYS)
+#define AT91_DBGU	(0xfffff200 - AT91_BASE_SYS)
+#define AT91_PIOA	(0xfffff400 - AT91_BASE_SYS)
+#define AT91_PIOB	(0xfffff600 - AT91_BASE_SYS)
+#define AT91_PIOC	(0xfffff800 - AT91_BASE_SYS)
+#define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)
+#define AT91_RSTC	(0xfffffd00 - AT91_BASE_SYS)
+#define AT91_RTT	(0xfffffd20 - AT91_BASE_SYS)
+#define AT91_PIT	(0xfffffd30 - AT91_BASE_SYS)
+#define AT91_WDT	(0xfffffd40 - AT91_BASE_SYS)
+
+#define AT91_USART0	AT572D940HF_ID_US0
+#define AT91_USART1	AT572D940HF_ID_US1
+#define AT91_USART2	AT572D940HF_ID_US2
+
+
+/*
+ * Internal Memory.
+ */
+#define AT572D940HF_SRAM_BASE	0x00300000	/* Internal SRAM base address */
+#define AT572D940HF_SRAM_SIZE	(48 * SZ_1K)	/* Internal SRAM size (48Kb) */
+
+#define AT572D940HF_ROM_BASE	0x00400000	/* Internal ROM base address */
+#define AT572D940HF_ROM_SIZE	SZ_32K		/* Internal ROM size (32Kb) */
+
+#define AT572D940HF_UHP_BASE	0x00500000	/* USB Host controller */
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/at572d940hf_matrix.h linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/at572d940hf_matrix.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/at572d940hf_matrix.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/at572d940hf_matrix.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,123 @@
+/*
+ * include/mach//at572d940hf_matrix.h
+ *
+ * Antonio R. Costa <costa.antonior@gmail.com>
+ * Copyright (C) 2008 Atmel
+ *
+ * Copyright (C) 2005 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 AT572D940HF_MATRIX_H
+#define AT572D940HF_MATRIX_H
+
+#define AT91_MATRIX_MCFG0	(AT91_MATRIX + 0x00)	/* Master Configuration Register 0 */
+#define AT91_MATRIX_MCFG1	(AT91_MATRIX + 0x04)	/* Master Configuration Register 1 */
+#define AT91_MATRIX_MCFG2	(AT91_MATRIX + 0x08)	/* Master Configuration Register 2 */
+#define AT91_MATRIX_MCFG3	(AT91_MATRIX + 0x0C)	/* Master Configuration Register 3 */
+#define AT91_MATRIX_MCFG4	(AT91_MATRIX + 0x10)	/* Master Configuration Register 4 */
+#define AT91_MATRIX_MCFG5	(AT91_MATRIX + 0x14)	/* Master Configuration Register 5 */
+
+#define		AT91_MATRIX_ULBT	(7 << 0)	/* Undefined Length Burst Type */
+#define			AT91_MATRIX_ULBT_INFINITE	(0 << 0)
+#define			AT91_MATRIX_ULBT_SINGLE		(1 << 0)
+#define			AT91_MATRIX_ULBT_FOUR		(2 << 0)
+#define			AT91_MATRIX_ULBT_EIGHT		(3 << 0)
+#define			AT91_MATRIX_ULBT_SIXTEEN	(4 << 0)
+
+#define AT91_MATRIX_SCFG0	(AT91_MATRIX + 0x40)	/* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1	(AT91_MATRIX + 0x44)	/* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2	(AT91_MATRIX + 0x48)	/* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3	(AT91_MATRIX + 0x4C)	/* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4	(AT91_MATRIX + 0x50)	/* Slave Configuration Register 4 */
+#define		AT91_MATRIX_SLOT_CYCLE		(0xff << 0)	/* Maximum Number of Allowed Cycles for a Burst */
+#define		AT91_MATRIX_DEFMSTR_TYPE	(3    << 16)	/* Default Master Type */
+#define			AT91_MATRIX_DEFMSTR_TYPE_NONE	(0 << 16)
+#define			AT91_MATRIX_DEFMSTR_TYPE_LAST	(1 << 16)
+#define			AT91_MATRIX_DEFMSTR_TYPE_FIXED	(2 << 16)
+#define		AT91_MATRIX_FIXED_DEFMSTR	(0x7  << 18)	/* Fixed Index of Default Master */
+#define		AT91_MATRIX_ARBT		(3    << 24)	/* Arbitration Type */
+#define			AT91_MATRIX_ARBT_ROUND_ROBIN	(0 << 24)
+#define			AT91_MATRIX_ARBT_FIXED_PRIORITY	(1 << 24)
+
+#define AT91_MATRIX_PRAS0	(AT91_MATRIX + 0x80)	/* Priority Register A for Slave 0 */
+#define AT91_MATRIX_PRAS1	(AT91_MATRIX + 0x88)	/* Priority Register A for Slave 1 */
+#define AT91_MATRIX_PRAS2	(AT91_MATRIX + 0x90)	/* Priority Register A for Slave 2 */
+#define AT91_MATRIX_PRAS3	(AT91_MATRIX + 0x98)	/* Priority Register A for Slave 3 */
+#define AT91_MATRIX_PRAS4	(AT91_MATRIX + 0xA0)	/* Priority Register A for Slave 4 */
+
+#define		AT91_MATRIX_M0PR		(3 << 0)	/* Master 0 Priority */
+#define		AT91_MATRIX_M1PR		(3 << 4)	/* Master 1 Priority */
+#define		AT91_MATRIX_M2PR		(3 << 8)	/* Master 2 Priority */
+#define		AT91_MATRIX_M3PR		(3 << 12)	/* Master 3 Priority */
+#define		AT91_MATRIX_M4PR		(3 << 16)	/* Master 4 Priority */
+#define		AT91_MATRIX_M5PR		(3 << 20)	/* Master 5 Priority */
+#define		AT91_MATRIX_M6PR		(3 << 24)	/* Master 6 Priority */
+
+#define AT91_MATRIX_MRCR	(AT91_MATRIX + 0x100)	/* Master Remap Control Register */
+#define		AT91_MATRIX_RCB0		(1 << 0)	/* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
+#define		AT91_MATRIX_RCB1		(1 << 1)	/* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
+
+#define AT91_MATRIX_SFR0	(AT91_MATRIX + 0x110)	/* Special Function Register 0 */
+#define AT91_MATRIX_SFR1	(AT91_MATRIX + 0x114)	/* Special Function Register 1 */
+#define AT91_MATRIX_SFR2	(AT91_MATRIX + 0x118)	/* Special Function Register 2 */
+#define AT91_MATRIX_SFR3	(AT91_MATRIX + 0x11C)	/* Special Function Register 3 */
+#define AT91_MATRIX_SFR4	(AT91_MATRIX + 0x120)	/* Special Function Register 4 */
+#define AT91_MATRIX_SFR5	(AT91_MATRIX + 0x124)	/* Special Function Register 5 */
+#define AT91_MATRIX_SFR6	(AT91_MATRIX + 0x128)	/* Special Function Register 6 */
+#define AT91_MATRIX_SFR7	(AT91_MATRIX + 0x12C)	/* Special Function Register 7 */
+#define AT91_MATRIX_SFR8	(AT91_MATRIX + 0x130)	/* Special Function Register 8 */
+#define AT91_MATRIX_SFR9	(AT91_MATRIX + 0x134)	/* Special Function Register 9 */
+#define AT91_MATRIX_SFR10	(AT91_MATRIX + 0x138)	/* Special Function Register 10 */
+#define AT91_MATRIX_SFR11	(AT91_MATRIX + 0x13C)	/* Special Function Register 11 */
+#define AT91_MATRIX_SFR12	(AT91_MATRIX + 0x140)	/* Special Function Register 12 */
+#define AT91_MATRIX_SFR13	(AT91_MATRIX + 0x144)	/* Special Function Register 13 */
+#define AT91_MATRIX_SFR14	(AT91_MATRIX + 0x148)	/* Special Function Register 14 */
+#define AT91_MATRIX_SFR15	(AT91_MATRIX + 0x14C)	/* Special Function Register 15 */
+
+
+/*
+ * The following registers / bits are not defined in the Datasheet (Revision A)
+ */
+
+#define AT91_MATRIX_TCR		(AT91_MATRIX + 0x100)	/* TCM Configuration Register */
+#define		AT91_MATRIX_ITCM_SIZE		(0xf << 0)	/* Size of ITCM enabled memory block */
+#define			AT91_MATRIX_ITCM_0		(0 << 0)
+#define			AT91_MATRIX_ITCM_16		(5 << 0)
+#define			AT91_MATRIX_ITCM_32		(6 << 0)
+#define			AT91_MATRIX_ITCM_64		(7 << 0)
+#define		AT91_MATRIX_DTCM_SIZE		(0xf << 4)	/* Size of DTCM enabled memory block */
+#define			AT91_MATRIX_DTCM_0		(0 << 4)
+#define			AT91_MATRIX_DTCM_16		(5 << 4)
+#define			AT91_MATRIX_DTCM_32		(6 << 4)
+#define			AT91_MATRIX_DTCM_64		(7 << 4)
+
+#define AT91_MATRIX_EBICSA	(AT91_MATRIX + 0x11C)	/* EBI Chip Select Assignment Register */
+#define		AT91_MATRIX_CS1A		(1 << 1)	/* Chip Select 1 Assignment */
+#define			AT91_MATRIX_CS1A_SMC		(0 << 1)
+#define			AT91_MATRIX_CS1A_SDRAMC		(1 << 1)
+#define		AT91_MATRIX_CS3A		(1 << 3)	/* Chip Select 3 Assignment */
+#define			AT91_MATRIX_CS3A_SMC		(0 << 3)
+#define			AT91_MATRIX_CS3A_SMC_SMARTMEDIA	(1 << 3)
+#define		AT91_MATRIX_CS4A		(1 << 4)	/* Chip Select 4 Assignment */
+#define			AT91_MATRIX_CS4A_SMC		(0 << 4)
+#define			AT91_MATRIX_CS4A_SMC_CF1	(1 << 4)
+#define		AT91_MATRIX_CS5A		(1 << 5)	/* Chip Select 5 Assignment */
+#define			AT91_MATRIX_CS5A_SMC		(0 << 5)
+#define			AT91_MATRIX_CS5A_SMC_CF2	(1 << 5)
+#define		AT91_MATRIX_DBPUC		(1 << 8)	/* Data Bus Pull-up Configuration */
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/at91_mci.h linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/at91_mci.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/at91_mci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/at91_mci.h	2010-05-16 17:17:36.000000000 -0400
@@ -77,7 +77,7 @@
 
 #define AT91_MCI_BLKR		0x18		/* Block Register */
 #define		AT91_MCI_BLKR_BCNT(n)	((0xffff & (n)) << 0)	/* Block count */
-#define		AT91_MCI_BLKR_BLKLEN(n)	((0xffff & (n)) << 16)	/* Block lenght */
+#define		AT91_MCI_BLKR_BLKLEN(n)	((0xffff & (n)) << 16)	/* Block length */
 
 #define AT91_MCI_RSPR(n)	(0x20 + ((n) * 4))	/* Response Registers 0-3 */
 #define AT91_MCR_RDR		0x30		/* Receive Data Register */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/at91_pmc.h linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/at91_pmc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/at91_pmc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/at91_pmc.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #define		AT91_PMC_PCK1		(1 <<  9)		/* Programmable Clock 1 */
 #define		AT91_PMC_PCK2		(1 << 10)		/* Programmable Clock 2 */
 #define		AT91_PMC_PCK3		(1 << 11)		/* Programmable Clock 3 */
+#define		AT91_PMC_PCK4		(1 << 12)		/* Programmable Clock 4 [AT572D940HF only] */
 #define		AT91_PMC_HCK0		(1 << 16)		/* AHB Clock (USB host) [AT91SAM9261 only] */
 #define		AT91_PMC_HCK1		(1 << 17)		/* AHB Clock (LCD) [AT91SAM9261 only] */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/board.h linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/board.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/board.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/board.h	2010-05-16 17:17:36.000000000 -0400
@@ -87,7 +87,7 @@ struct at91_eth_data {
 extern void __init at91_add_device_eth(struct at91_eth_data *data);
 
 #if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \
-	|| defined(CONFIG_ARCH_AT91SAM9G45)
+	|| defined(CONFIG_ARCH_AT91SAM9G45) || defined(CONFIG_ARCH_AT572D940HF)
 #define eth_platform_data	at91_eth_data
 #endif
 
@@ -205,6 +205,9 @@ extern void __init at91_init_leds(u8 cpu
 extern void __init at91_gpio_leds(struct gpio_led *leds, int nr);
 extern void __init at91_pwm_leds(struct gpio_led *leds, int nr);
 
+ /* AT572D940HF DSP */
+extern void __init at91_add_device_mAgic(void);
+
 /* FIXME: this needs a better location, but gets stuff building again */
 extern int at91_suspend_entering_slow_clock(void);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/cpu.h linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/cpu.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/cpu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/cpu.h	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,8 @@
 #define ARCH_ID_AT91SAM9XE256	0x329a93a0
 #define ARCH_ID_AT91SAM9XE512	0x329aa3a0
 
+#define ARCH_ID_AT572D940HF	0x0e0303e0
+
 #define ARCH_ID_AT91M40800	0x14080044
 #define ARCH_ID_AT91R40807	0x44080746
 #define ARCH_ID_AT91M40807	0x14080745
@@ -141,6 +143,12 @@ static inline unsigned long at91cap9_rev
 #define cpu_is_at91cap9_revC()	(0)
 #endif
 
+#ifdef CONFIG_ARCH_AT572D940HF
+#define cpu_is_at572d940hf() (at91_cpu_identify() == ARCH_ID_AT572D940HF)
+#else
+#define cpu_is_at572d940hf() (0)
+#endif
+
 /*
  * Since this is ARM, we will never run on any AVR32 CPU. But these
  * definitions may reduce clutter in common drivers.
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,7 @@
 #include <mach/hardware.h>
 #include <mach/at91_dbgu.h>
 
-	.macro	addruart,rx
+	.macro	addruart, rx, tmp
 	mrc	p15, 0, \rx, c1, c0
 	tst	\rx, #1						@ MMU enabled?
 	ldreq	\rx, =(AT91_BASE_SYS + AT91_DBGU)		@ System peripherals (phys address)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/hardware.h linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/hardware.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/hardware.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/hardware.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,8 @@
 #include <mach/at91cap9.h>
 #elif defined(CONFIG_ARCH_AT91X40)
 #include <mach/at91x40.h>
+#elif defined(CONFIG_ARCH_AT572D940HF)
+#include <mach/at572d940hf.h>
 #else
 #error "Unsupported AT91 processor"
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/timex.h linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/timex.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/timex.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/include/mach/timex.h	2010-05-16 17:17:36.000000000 -0400
@@ -82,6 +82,11 @@
 #define AT91X40_MASTER_CLOCK	40000000
 #define CLOCK_TICK_RATE		(AT91X40_MASTER_CLOCK)
 
+#elif defined(CONFIG_ARCH_AT572D940HF)
+
+#define AT572D940HF_MASTER_CLOCK	80000000
+#define CLOCK_TICK_RATE		(AT572D940HF_MASTER_CLOCK/16)
+
 #endif
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-at91/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -89,6 +89,12 @@ config ARCH_AT91CAP9
 	select GENERIC_CLOCKEVENTS
 	select HAVE_FB_ATMEL
 
+config ARCH_AT572D940HF
+	bool "AT572D940HF"
+	select CPU_ARM926T
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+
 config ARCH_AT91X40
 	bool "AT91x40"
 
@@ -388,6 +394,23 @@ config MACH_AT91CAP9ADK
 
 endif
 
+# ----------------------------------------------------------
+
+if ARCH_AT572D940HF
+
+comment "AT572D940HF Board Type"
+
+config MACH_AT572D940HFEB
+	bool "AT572D940HF-EK"
+	depends on ARCH_AT572D940HF
+	select HAVE_AT91_DATAFLASH_CARD
+	select HAVE_NAND_ATMEL_BUSWIDTH_16
+	help
+	  Select this if you are using Atmel's AT572D940HF-EK evaluation kit.
+	  <http://www.atmel.com/products/diopsis/default.asp>
+
+endif
+
 # ----------------------------------------------------------
 
 if ARCH_AT91X40
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-at91/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -16,9 +16,10 @@ obj-$(CONFIG_ARCH_AT91SAM9261)	+= at91sa
 obj-$(CONFIG_ARCH_AT91SAM9G10)	+= at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9263)	+= at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9RL)	+= at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
-obj-$(CONFIG_ARCH_AT91SAM9G20)	+= at91sam9260.o at91sam926x_time.o at91sam9260_devices.o  sam9_smc.o
- obj-$(CONFIG_ARCH_AT91SAM9G45)	+= at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G20)	+= at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G45)	+= at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91CAP9)	+= at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT572D940HF)  += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91X40)	+= at91x40.o at91x40_time.o
 
 # AT91RM9200 board-specific support
@@ -69,6 +70,9 @@ obj-$(CONFIG_MACH_AT91SAM9G45EKES) += bo
 # AT91CAP9 board-specific support
 obj-$(CONFIG_MACH_AT91CAP9ADK)	+= board-cap9adk.o
 
+# AT572D940HF board-specific support
+obj-$(CONFIG_MACH_AT572D940HFEB) += board-at572d940hf_ek.o
+
 # AT91X40 board-specific support
 obj-$(CONFIG_MACH_AT91EB01)	+= board-eb01.o
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-at91/pm_slowclock.S linux-libre-2.6.34-gnu1/arch/arm/mach-at91/pm_slowclock.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-at91/pm_slowclock.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-at91/pm_slowclock.S	2010-05-16 17:17:36.000000000 -0400
@@ -175,8 +175,6 @@ ENTRY(at91_slow_clock)
 	orr	r3, r3, #(1 << 29)		/* bit 29 always set */
 	str	r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
 
-	wait_pllalock
-
 	/* Save PLLB setting and disable it */
 	ldr	r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
 	str	r3, .saved_pllbr
@@ -184,8 +182,6 @@ ENTRY(at91_slow_clock)
 	mov	r3, #AT91_PMC_PLLCOUNT
 	str	r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
 
-	wait_pllblock
-
 	/* Turn off the main oscillator */
 	ldr	r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
 	bic	r3, r3, #AT91_PMC_MOSCEN
@@ -205,13 +201,25 @@ ENTRY(at91_slow_clock)
 	ldr	r3, .saved_pllbr
 	str	r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
 
+	tst	r3, #(AT91_PMC_MUL &  0xff0000)
+	bne	1f
+	tst	r3, #(AT91_PMC_MUL & ~0xff0000)
+	beq	2f
+1:
 	wait_pllblock
+2:
 
 	/* Restore PLLA setting */
 	ldr	r3, .saved_pllar
 	str	r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
 
+	tst	r3, #(AT91_PMC_MUL &  0xff0000)
+	bne	3f
+	tst	r3, #(AT91_PMC_MUL & ~0xff0000)
+	beq	4f
+3:
 	wait_pllalock
+4:
 
 #ifdef SLOWDOWN_MASTER_CLOCK
 	/*
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/core.c linux-libre-2.6.34-gnu1/arch/arm/mach-bcmring/core.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-bcmring/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -142,8 +142,7 @@ void __init bcmring_amba_init(void)
 
 	chipcHw_busInterfaceClockEnable(bus_clock);
 
-	for (i = 0; i < ARRAY_SIZE(lookups); i++)
-		clkdev_add(&lookups[i]);
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 		struct amba_device *d = amba_devs[i];
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/dma.c linux-libre-2.6.34-gnu1/arch/arm/mach-bcmring/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-bcmring/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/interrupt.h>
 #include <linux/irqreturn.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 
 #include <mach/timer.h>
 
@@ -2220,11 +2221,15 @@ EXPORT_SYMBOL(dma_map_create_descriptor_
 int dma_unmap(DMA_MemMap_t *memMap,	/* Stores state information about the map */
 	      int dirtied	/* non-zero if any of the pages were modified */
     ) {
+
+	int rc = 0;
 	int regionIdx;
 	int segmentIdx;
 	DMA_Region_t *region;
 	DMA_Segment_t *segment;
 
+	down(&memMap->lock);
+
 	for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
 		region = &memMap->region[regionIdx];
 
@@ -2238,7 +2243,8 @@ int dma_unmap(DMA_MemMap_t *memMap,	/* S
 					printk(KERN_ERR
 					       "%s: vmalloc'd pages are not yet supported\n",
 					       __func__);
-					return -EINVAL;
+					rc = -EINVAL;
+					goto out;
 				}
 
 			case DMA_MEM_TYPE_KMALLOC:
@@ -2275,7 +2281,8 @@ int dma_unmap(DMA_MemMap_t *memMap,	/* S
 					printk(KERN_ERR
 					       "%s: Unsupported memory type: %d\n",
 					       __func__, region->memType);
-					return -EINVAL;
+					rc = -EINVAL;
+					goto out;
 				}
 			}
 
@@ -2313,9 +2320,10 @@ int dma_unmap(DMA_MemMap_t *memMap,	/* S
 	memMap->numRegionsUsed = 0;
 	memMap->inUse = 0;
 
+out:
 	up(&memMap->lock);
 
-	return 0;
+	return rc;
 }
 
 EXPORT_SYMBOL(dma_unmap);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-clps711x/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-clps711x/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-clps711x/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-clps711x/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,7 @@
 
 #include <asm/hardware/clps7111.h>
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #CLPS7111_PHYS_BASE
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-da830-evm.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-da830-evm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-da830-evm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-da830-evm.c	2010-05-16 17:17:36.000000000 -0400
@@ -112,7 +112,7 @@ static __init void da830_evm_usb_init(vo
 	 * Set up USB clock/mode in the CFGCHIP2 register.
 	 * FYI:  CFGCHIP2 is 0x0000ef00 initially.
 	 */
-	cfgchip2 = __raw_readl(DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP2_REG));
+	cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
 
 	/* USB2.0 PHY reference clock is 24 MHz */
 	cfgchip2 &= ~CFGCHIP2_REFFREQ;
@@ -139,7 +139,7 @@ static __init void da830_evm_usb_init(vo
 	cfgchip2 |=  CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN;
 #endif
 
-	__raw_writel(cfgchip2, DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP2_REG));
+	__raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
 
 	/* USB_REFCLKIN is not used. */
 	ret = davinci_cfg_reg(DA830_USB0_DRVVBUS);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-da850-evm.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-da850-evm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-da850-evm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-da850-evm.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,8 +46,20 @@
 
 static struct mtd_partition da850_evm_norflash_partition[] = {
 	{
-		.name           = "NOR filesystem",
+		.name           = "bootloaders + env",
 		.offset         = 0,
+		.size           = SZ_512K,
+		.mask_flags     = MTD_WRITEABLE,
+	},
+	{
+		.name           = "kernel",
+		.offset         = MTDPART_OFS_APPEND,
+		.size           = SZ_2M,
+		.mask_flags     = 0,
+	},
+	{
+		.name           = "filesystem",
+		.offset         = MTDPART_OFS_APPEND,
 		.size           = MTDPART_SIZ_FULL,
 		.mask_flags     = 0,
 	},
@@ -77,6 +89,18 @@ static struct platform_device da850_evm_
 	.resource	= da850_evm_norflash_resource,
 };
 
+static struct davinci_pm_config da850_pm_pdata = {
+	.sleepcount = 128,
+};
+
+static struct platform_device da850_pm_device = {
+	.name           = "pm-davinci",
+	.dev = {
+		.platform_data	= &da850_pm_pdata,
+	},
+	.id             = -1,
+};
+
 /* DA850/OMAP-L138 EVM includes a 512 MByte large-page NAND flash
  * (128K blocks). It may be used instead of the (default) SPI flash
  * to boot, using TI's tools to install the secondary boot loader
@@ -119,6 +143,7 @@ static struct davinci_nand_pdata da850_e
 	.parts		= da850_evm_nandflash_partition,
 	.nr_parts	= ARRAY_SIZE(da850_evm_nandflash_partition),
 	.ecc_mode	= NAND_ECC_HW,
+	.ecc_bits	= 4,
 	.options	= NAND_USE_FLASH_BBT,
 };
 
@@ -537,7 +562,7 @@ static int __init da850_evm_config_emac(
 	if (!machine_is_davinci_da850_evm())
 		return 0;
 
-	cfg_chip3_base = DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP3_REG);
+	cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
 
 	val = __raw_readl(cfg_chip3_base);
 
@@ -696,6 +721,11 @@ static __init void da850_evm_init(void)
 	if (ret)
 		pr_warning("da850_evm_init: cpuidle registration failed: %d\n",
 				ret);
+
+	ret = da850_register_pm(&da850_pm_device);
+	if (ret)
+		pr_warning("da850_evm_init: suspend registration failed: %d\n",
+				ret);
 }
 
 #ifdef CONFIG_SERIAL_8250_CONSOLE
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm355-evm.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-dm355-evm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm355-evm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-dm355-evm.c	2010-05-16 17:17:36.000000000 -0400
@@ -111,6 +111,8 @@ static struct platform_device davinci_na
 static struct davinci_i2c_platform_data i2c_pdata = {
 	.bus_freq	= 400	/* kHz */,
 	.bus_delay	= 0	/* usec */,
+	.sda_pin        = 15,
+	.scl_pin        = 14,
 };
 
 static struct snd_platform_data dm355_evm_snd_data;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm365-evm.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-dm365-evm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm365-evm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-dm365-evm.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,8 +22,11 @@
 #include <linux/leds.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/slab.h>
 #include <linux/mtd/nand.h>
 #include <linux/input.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -37,6 +40,8 @@
 #include <mach/nand.h>
 #include <mach/keyscan.h>
 
+#include <media/tvp514x.h>
+
 static inline int have_imager(void)
 {
 	/* REVISIT when it's supported, trigger via Kconfig */
@@ -306,6 +311,73 @@ static void dm365evm_mmc_configure(void)
 	davinci_cfg_reg(DM365_SD1_DATA0);
 }
 
+static struct tvp514x_platform_data tvp5146_pdata = {
+	.clk_polarity = 0,
+	.hs_polarity = 1,
+	.vs_polarity = 1
+};
+
+#define TVP514X_STD_ALL        (V4L2_STD_NTSC | V4L2_STD_PAL)
+/* Inputs available at the TVP5146 */
+static struct v4l2_input tvp5146_inputs[] = {
+	{
+		.index = 0,
+		.name = "Composite",
+		.type = V4L2_INPUT_TYPE_CAMERA,
+		.std = TVP514X_STD_ALL,
+	},
+	{
+		.index = 1,
+		.name = "S-Video",
+		.type = V4L2_INPUT_TYPE_CAMERA,
+		.std = TVP514X_STD_ALL,
+	},
+};
+
+/*
+ * this is the route info for connecting each input to decoder
+ * ouput that goes to vpfe. There is a one to one correspondence
+ * with tvp5146_inputs
+ */
+static struct vpfe_route tvp5146_routes[] = {
+	{
+		.input = INPUT_CVBS_VI2B,
+		.output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+	},
+{
+		.input = INPUT_SVIDEO_VI2C_VI1C,
+		.output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+	},
+};
+
+static struct vpfe_subdev_info vpfe_sub_devs[] = {
+	{
+		.name = "tvp5146",
+		.grp_id = 0,
+		.num_inputs = ARRAY_SIZE(tvp5146_inputs),
+		.inputs = tvp5146_inputs,
+		.routes = tvp5146_routes,
+		.can_route = 1,
+		.ccdc_if_params = {
+			.if_type = VPFE_BT656,
+			.hdpol = VPFE_PINPOL_POSITIVE,
+			.vdpol = VPFE_PINPOL_POSITIVE,
+		},
+		.board_info = {
+			I2C_BOARD_INFO("tvp5146", 0x5d),
+			.platform_data = &tvp5146_pdata,
+		},
+	},
+};
+
+static struct vpfe_config vpfe_cfg = {
+	.num_subdevs = ARRAY_SIZE(vpfe_sub_devs),
+	.sub_devs = vpfe_sub_devs,
+	.i2c_adapter_id = 1,
+	.card_name = "DM365 EVM",
+	.ccdc = "ISIF",
+};
+
 static void __init evm_init_i2c(void)
 {
 	davinci_init_i2c(&i2c_pdata);
@@ -497,9 +569,29 @@ static struct davinci_uart_config uart_c
 
 static void __init dm365_evm_map_io(void)
 {
+	/* setup input configuration for VPFE input devices */
+	dm365_set_vpfe_config(&vpfe_cfg);
 	dm365_init();
 }
 
+static struct spi_eeprom at25640 = {
+	.byte_len	= SZ_64K / 8,
+	.name		= "at25640",
+	.page_size	= 32,
+	.flags		= EE_ADDR2,
+};
+
+static struct spi_board_info dm365_evm_spi_info[] __initconst = {
+	{
+		.modalias	= "at25",
+		.platform_data	= &at25640,
+		.max_speed_hz	= 10 * 1000 * 1000,
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.mode		= SPI_MODE_0,
+	},
+};
+
 static __init void dm365_evm_init(void)
 {
 	evm_init_i2c();
@@ -516,6 +608,9 @@ static __init void dm365_evm_init(void)
 	dm365_init_asp(&dm365_evm_snd_data);
 	dm365_init_rtc();
 	dm365_init_ks(&dm365evm_ks_data);
+
+	dm365_init_spi0(BIT(0), dm365_evm_spi_info,
+			ARRAY_SIZE(dm365_evm_spi_info));
 }
 
 static __init void dm365_evm_irq_init(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm644x-evm.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-dm644x-evm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm644x-evm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-dm644x-evm.c	2010-05-16 17:17:36.000000000 -0400
@@ -629,6 +629,8 @@ static struct i2c_board_info __initdata
 static struct davinci_i2c_platform_data i2c_pdata = {
 	.bus_freq	= 20 /* kHz */,
 	.bus_delay	= 100 /* usec */,
+	.sda_pin        = 44,
+	.scl_pin        = 43,
 };
 
 static void __init evm_init_i2c(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm646x-evm.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-dm646x-evm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm646x-evm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-dm646x-evm.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/clk.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -39,54 +40,13 @@
 #include <mach/serial.h>
 #include <mach/i2c.h>
 #include <mach/nand.h>
+#include <mach/clock.h>
+#include <mach/cdce949.h>
 
-#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
-    defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
-#define HAS_ATA 1
-#else
-#define HAS_ATA 0
-#endif
-
-#define DAVINCI_ASYNC_EMIF_CONTROL_BASE		0x20008000
-#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE	0x42000000
+#include "clock.h"
 
 #define NAND_BLOCK_SIZE		SZ_128K
 
-/* CPLD Register 0 bits to control ATA */
-#define DM646X_EVM_ATA_RST		BIT(0)
-#define DM646X_EVM_ATA_PWD		BIT(1)
-
-#define DM646X_EVM_PHY_MASK		(0x2)
-#define DM646X_EVM_MDIO_FREQUENCY	(2200000) /* PHY bus frequency */
-
-#define VIDCLKCTL_OFFSET	(DAVINCI_SYSTEM_MODULE_BASE + 0x38)
-#define VSCLKDIS_OFFSET		(DAVINCI_SYSTEM_MODULE_BASE + 0x6c)
-#define VCH2CLK_MASK		(BIT_MASK(10) | BIT_MASK(9) | BIT_MASK(8))
-#define VCH2CLK_SYSCLK8		(BIT(9))
-#define VCH2CLK_AUXCLK		(BIT(9) | BIT(8))
-#define VCH3CLK_MASK		(BIT_MASK(14) | BIT_MASK(13) | BIT_MASK(12))
-#define VCH3CLK_SYSCLK8		(BIT(13))
-#define VCH3CLK_AUXCLK		(BIT(14) | BIT(13))
-
-#define VIDCH2CLK		(BIT(10))
-#define VIDCH3CLK		(BIT(11))
-#define VIDCH1CLK		(BIT(4))
-#define TVP7002_INPUT		(BIT(4))
-#define TVP5147_INPUT		(~BIT(4))
-#define VPIF_INPUT_ONE_CHANNEL	(BIT(5))
-#define VPIF_INPUT_TWO_CHANNEL	(~BIT(5))
-#define TVP5147_CH0		"tvp514x-0"
-#define TVP5147_CH1		"tvp514x-1"
-
-static void __iomem *vpif_vidclkctl_reg;
-static void __iomem *vpif_vsclkdis_reg;
-/* spin lock for updating above registers */
-static spinlock_t vpif_reg_lock;
-
-static struct davinci_uart_config uart_config __initdata = {
-	.enabled_uarts = (1 << 0),
-};
-
 /* Note: We are setting first partition as 'bootloader' constituting UBL, U-Boot
  * and U-Boot environment this avoids dependency on any particular combination
  * of UBL, U-Boot or flashing tools etc.
@@ -120,6 +80,9 @@ static struct davinci_nand_pdata davinci
 	.options		= 0,
 };
 
+#define DAVINCI_ASYNC_EMIF_CONTROL_BASE		0x20008000
+#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE	0x42000000
+
 static struct resource davinci_nand_resources[] = {
 	{
 		.start		= DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
@@ -144,6 +107,17 @@ static struct platform_device davinci_na
 	},
 };
 
+#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+    defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+#define HAS_ATA 1
+#else
+#define HAS_ATA 0
+#endif
+
+/* CPLD Register 0 bits to control ATA */
+#define DM646X_EVM_ATA_RST		BIT(0)
+#define DM646X_EVM_ATA_PWD		BIT(1)
+
 /* CPLD Register 0 Client: used for I/O Control */
 static int cpld_reg0_probe(struct i2c_client *client,
 			   const struct i2c_device_id *id)
@@ -417,6 +391,9 @@ static struct i2c_board_info __initdata
 	{
 		I2C_BOARD_INFO("cpld_video", 0x3b),
 	},
+	{
+		I2C_BOARD_INFO("cdce949", 0x6c),
+	},
 };
 
 static struct davinci_i2c_platform_data i2c_pdata = {
@@ -424,6 +401,30 @@ static struct davinci_i2c_platform_data
 	.bus_delay      = 0 /* usec */,
 };
 
+#define VIDCLKCTL_OFFSET	(DAVINCI_SYSTEM_MODULE_BASE + 0x38)
+#define VSCLKDIS_OFFSET		(DAVINCI_SYSTEM_MODULE_BASE + 0x6c)
+#define VCH2CLK_MASK		(BIT_MASK(10) | BIT_MASK(9) | BIT_MASK(8))
+#define VCH2CLK_SYSCLK8		(BIT(9))
+#define VCH2CLK_AUXCLK		(BIT(9) | BIT(8))
+#define VCH3CLK_MASK		(BIT_MASK(14) | BIT_MASK(13) | BIT_MASK(12))
+#define VCH3CLK_SYSCLK8		(BIT(13))
+#define VCH3CLK_AUXCLK		(BIT(14) | BIT(13))
+
+#define VIDCH2CLK		(BIT(10))
+#define VIDCH3CLK		(BIT(11))
+#define VIDCH1CLK		(BIT(4))
+#define TVP7002_INPUT		(BIT(4))
+#define TVP5147_INPUT		(~BIT(4))
+#define VPIF_INPUT_ONE_CHANNEL	(BIT(5))
+#define VPIF_INPUT_TWO_CHANNEL	(~BIT(5))
+#define TVP5147_CH0		"tvp514x-0"
+#define TVP5147_CH1		"tvp514x-1"
+
+static void __iomem *vpif_vidclkctl_reg;
+static void __iomem *vpif_vsclkdis_reg;
+/* spin lock for updating above registers */
+static spinlock_t vpif_reg_lock;
+
 static int set_vpif_clock(int mux_mode, int hd)
 {
 	unsigned long flags;
@@ -685,11 +686,44 @@ static void __init evm_init_i2c(void)
 	evm_init_video();
 }
 
+#define CDCE949_XIN_RATE	27000000
+
+/* CDCE949 support - "lpsc" field is overridden to work as clock number */
+static struct clk cdce_clk_in = {
+	.name	= "cdce_xin",
+	.rate	= CDCE949_XIN_RATE,
+};
+
+static struct clk_lookup cdce_clks[] = {
+	CLK(NULL, "xin", &cdce_clk_in),
+	CLK(NULL, NULL, NULL),
+};
+
+static void __init cdce_clk_init(void)
+{
+	struct clk_lookup *c;
+	struct clk *clk;
+
+	for (c = cdce_clks; c->clk; c++) {
+		clk = c->clk;
+		clkdev_add(c);
+		clk_register(clk);
+	}
+}
+
 static void __init davinci_map_io(void)
 {
 	dm646x_init();
+	cdce_clk_init();
 }
 
+static struct davinci_uart_config uart_config __initdata = {
+	.enabled_uarts = (1 << 0),
+};
+
+#define DM646X_EVM_PHY_MASK		(0x2)
+#define DM646X_EVM_MDIO_FREQUENCY	(2200000) /* PHY bus frequency */
+
 static __init void evm_init(void)
 {
 	struct davinci_soc_info *soc_info = &davinci_soc_info;
@@ -713,10 +747,31 @@ static __init void davinci_dm646x_evm_ir
 	davinci_irq_init();
 }
 
+#define DM646X_EVM_REF_FREQ		27000000
+#define DM6467T_EVM_REF_FREQ		33000000
+
+void __init dm646x_board_setup_refclk(struct clk *clk)
+{
+	if (machine_is_davinci_dm6467tevm())
+		clk->rate = DM6467T_EVM_REF_FREQ;
+	else
+		clk->rate = DM646X_EVM_REF_FREQ;
+}
+
 MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
 	.phys_io      = IO_PHYS,
 	.io_pg_offst  = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
 	.boot_params  = (0x80000100),
+	.map_io       = davinci_map_io,
+	.init_irq     = davinci_dm646x_evm_irq_init,
+	.timer        = &davinci_timer,
+	.init_machine = evm_init,
+MACHINE_END
+
+MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
+	.phys_io      = IO_PHYS,
+	.io_pg_offst  = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
+	.boot_params  = (0x80000100),
 	.map_io       = davinci_map_io,
 	.init_irq     = davinci_dm646x_evm_irq_init,
 	.timer        = &davinci_timer,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/cdce949.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/cdce949.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/cdce949.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/cdce949.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,293 @@
+/*
+ * TI CDCE949 clock synthesizer driver
+ *
+ * Note: This implementation assumes an input of 27MHz to the CDCE.
+ * This is by no means constrained by CDCE hardware although the datasheet
+ * does use this as an example for all illustrations and more importantly:
+ * that is the crystal input on boards it is currently used on.
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated. http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+
+#include <mach/clock.h>
+
+#include "clock.h"
+
+static struct i2c_client *cdce_i2c_client;
+static DEFINE_MUTEX(cdce_mutex);
+
+/* CDCE register descriptor */
+struct cdce_reg {
+	u8	addr;
+	u8	val;
+};
+
+/* Per-Output (Y1, Y2 etc.) frequency descriptor */
+struct cdce_freq {
+	/* Frequency in KHz */
+	unsigned long frequency;
+	/*
+	 * List of registers to program to obtain a particular frequency.
+	 * 0x0 in register address and value is the end of list marker.
+	 */
+	struct cdce_reg *reglist;
+};
+
+#define CDCE_FREQ_TABLE_ENTRY(line, out)		\
+{							\
+	.reglist	= cdce_y ##line## _ ##out,		\
+	.frequency	= out,				\
+}
+
+/* List of CDCE outputs  */
+struct cdce_output {
+	/* List of frequencies on this output */
+	struct cdce_freq *freq_table;
+	/* Number of possible frequencies */
+	int size;
+};
+
+/*
+ * Finding out the values to program into CDCE949 registers for a particular
+ * frequency output is not a simple calculation. Have a look at the datasheet
+ * for the details. There is desktop software available to help users with
+ * the calculations. Here, we just depend on the output of that software
+ * (or hand calculations) instead trying to runtime calculate the register
+ * values and inflicting misery on ourselves.
+ */
+static struct cdce_reg cdce_y1_148500[] = {
+	{ 0x13, 0x00 },
+	/* program PLL1_0 multiplier */
+	{ 0x18, 0xaf },
+	{ 0x19, 0x50 },
+	{ 0x1a, 0x02 },
+	{ 0x1b, 0xc9 },
+	/* program PLL1_11 multiplier */
+	{ 0x1c, 0x00 },
+	{ 0x1d, 0x40 },
+	{ 0x1e, 0x02 },
+	{ 0x1f, 0xc9 },
+	/* output state selection */
+	{ 0x15, 0x00 },
+	{ 0x14, 0xef },
+	/* switch MUX to PLL1 output */
+	{ 0x14, 0x6f },
+	{ 0x16, 0x06 },
+	/* set P2DIV divider, P3DIV and input crystal */
+	{ 0x17, 0x06 },
+	{ 0x01, 0x00 },
+	{ 0x05, 0x48 },
+	{ 0x02, 0x80 },
+	/* enable and disable PLL */
+	{ 0x02, 0xbc },
+	{ 0x03, 0x01 },
+	{ },
+};
+
+static struct cdce_reg cdce_y1_74250[] = {
+	{ 0x13, 0x00 },
+	{ 0x18, 0xaf },
+	{ 0x19, 0x50 },
+	{ 0x1a, 0x02 },
+	{ 0x1b, 0xc9 },
+	{ 0x1c, 0x00 },
+	{ 0x1d, 0x40 },
+	{ 0x1e, 0x02 },
+	{ 0x1f, 0xc9 },
+	/* output state selection */
+	{ 0x15, 0x00 },
+	{ 0x14, 0xef },
+	/* switch MUX to PLL1 output */
+	{ 0x14, 0x6f },
+	{ 0x16, 0x06 },
+	/* set P2DIV divider, P3DIV and input crystal */
+	{ 0x17, 0x06 },
+	{ 0x01, 0x00 },
+	{ 0x05, 0x48 },
+	{ 0x02, 0x80 },
+	/* enable and disable PLL */
+	{ 0x02, 0xbc },
+	{ 0x03, 0x02 },
+	{ },
+};
+
+static struct cdce_reg cdce_y1_27000[] = {
+	{ 0x13, 0x00 },
+	{ 0x18, 0x00 },
+	{ 0x19, 0x40 },
+	{ 0x1a, 0x02 },
+	{ 0x1b, 0x08 },
+	{ 0x1c, 0x00 },
+	{ 0x1d, 0x40 },
+	{ 0x1e, 0x02 },
+	{ 0x1f, 0x08 },
+	{ 0x15, 0x02 },
+	{ 0x14, 0xed },
+	{ 0x16, 0x01 },
+	{ 0x17, 0x01 },
+	{ 0x01, 0x00 },
+	{ 0x05, 0x50 },
+	{ 0x02, 0xb4 },
+	{ 0x03, 0x01 },
+	{ },
+};
+
+static struct cdce_freq cdce_y1_freqs[] = {
+	CDCE_FREQ_TABLE_ENTRY(1, 148500),
+	CDCE_FREQ_TABLE_ENTRY(1, 74250),
+	CDCE_FREQ_TABLE_ENTRY(1, 27000),
+};
+
+static struct cdce_reg cdce_y5_13500[] = {
+	{ 0x27, 0x08 },
+	{ 0x28, 0x00 },
+	{ 0x29, 0x40 },
+	{ 0x2a, 0x02 },
+	{ 0x2b, 0x08 },
+	{ 0x24, 0x6f },
+	{ },
+};
+
+static struct cdce_reg cdce_y5_16875[] = {
+	{ 0x27, 0x08 },
+	{ 0x28, 0x9f },
+	{ 0x29, 0xb0 },
+	{ 0x2a, 0x02 },
+	{ 0x2b, 0x89 },
+	{ 0x24, 0x6f },
+	{ },
+};
+
+static struct cdce_reg cdce_y5_27000[] = {
+	{ 0x27, 0x04 },
+	{ 0x28, 0x00 },
+	{ 0x29, 0x40 },
+	{ 0x2a, 0x02 },
+	{ 0x2b, 0x08 },
+	{ 0x24, 0x6f },
+	{ },
+};
+static struct cdce_reg cdce_y5_54000[] = {
+	{ 0x27, 0x04 },
+	{ 0x28, 0xff },
+	{ 0x29, 0x80 },
+	{ 0x2a, 0x02 },
+	{ 0x2b, 0x07 },
+	{ 0x24, 0x6f },
+	{ },
+};
+
+static struct cdce_reg cdce_y5_81000[] = {
+	{ 0x27, 0x02 },
+	{ 0x28, 0xbf },
+	{ 0x29, 0xa0 },
+	{ 0x2a, 0x03 },
+	{ 0x2b, 0x0a },
+	{ 0x24, 0x6f },
+	{ },
+};
+
+static struct cdce_freq cdce_y5_freqs[] = {
+	CDCE_FREQ_TABLE_ENTRY(5, 13500),
+	CDCE_FREQ_TABLE_ENTRY(5, 16875),
+	CDCE_FREQ_TABLE_ENTRY(5, 27000),
+	CDCE_FREQ_TABLE_ENTRY(5, 54000),
+	CDCE_FREQ_TABLE_ENTRY(5, 81000),
+};
+
+
+static struct cdce_output output_list[] = {
+	[1]	= { cdce_y1_freqs, ARRAY_SIZE(cdce_y1_freqs) },
+	[5]	= { cdce_y5_freqs, ARRAY_SIZE(cdce_y5_freqs) },
+};
+
+int cdce_set_rate(struct clk *clk, unsigned long rate)
+{
+	int i, ret = 0;
+	struct cdce_freq *freq_table = output_list[clk->lpsc].freq_table;
+	struct cdce_reg  *regs = NULL;
+
+	if (!cdce_i2c_client)
+		return -ENODEV;
+
+	if (!freq_table)
+		return -EINVAL;
+
+	for (i = 0; i < output_list[clk->lpsc].size; i++) {
+		if (freq_table[i].frequency == rate / 1000) {
+			regs = freq_table[i].reglist;
+			break;
+		}
+	}
+
+	if (!regs)
+		return -EINVAL;
+
+	mutex_lock(&cdce_mutex);
+	for (i = 0; regs[i].addr; i++) {
+		ret = i2c_smbus_write_byte_data(cdce_i2c_client,
+					regs[i].addr | 0x80, regs[i].val);
+		if (ret)
+			break;
+	}
+	mutex_unlock(&cdce_mutex);
+
+	if (!ret)
+		clk->rate = rate;
+
+	return ret;
+}
+
+static int cdce_probe(struct i2c_client *client,
+					const struct i2c_device_id *id)
+{
+	cdce_i2c_client = client;
+	return 0;
+}
+
+static int __devexit cdce_remove(struct i2c_client *client)
+{
+	cdce_i2c_client = NULL;
+	return 0;
+}
+
+static const struct i2c_device_id cdce_id[] = {
+	{"cdce949", 0},
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, cdce_id);
+
+static struct i2c_driver cdce_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "cdce949",
+	},
+	.probe		= cdce_probe,
+	.remove		= __devexit_p(cdce_remove),
+	.id_table	= cdce_id,
+};
+
+static int __init cdce_init(void)
+{
+	return i2c_add_driver(&cdce_driver);
+}
+subsys_initcall(cdce_init);
+
+static void __exit cdce_exit(void)
+{
+	i2c_del_driver(&cdce_driver);
+}
+module_exit(cdce_exit);
+
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("CDCE949 clock synthesizer driver");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,7 +49,8 @@ static void __clk_disable(struct clk *cl
 {
 	if (WARN_ON(clk->usecount == 0))
 		return;
-	if (--clk->usecount == 0 && !(clk->flags & CLK_PLL))
+	if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) &&
+	    (clk->flags & CLK_PSC))
 		davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 0);
 	if (clk->parent)
 		__clk_disable(clk->parent);
@@ -124,9 +125,10 @@ int clk_set_rate(struct clk *clk, unsign
 	if (clk == NULL || IS_ERR(clk))
 		return ret;
 
-	spin_lock_irqsave(&clockfw_lock, flags);
 	if (clk->set_rate)
 		ret = clk->set_rate(clk, rate);
+
+	spin_lock_irqsave(&clockfw_lock, flags);
 	if (ret == 0) {
 		if (clk->recalc)
 			clk->rate = clk->recalc(clk);
@@ -363,6 +365,7 @@ int davinci_set_pllrate(struct pll_data
 {
 	u32 ctrl;
 	unsigned int locktime;
+	unsigned long flags;
 
 	if (pll->base == NULL)
 		return -EINVAL;
@@ -376,25 +379,23 @@ int davinci_set_pllrate(struct pll_data
 		locktime = ((2000 * prediv) / 100);
 		prediv = (prediv - 1) | PLLDIV_EN;
 	} else {
-		locktime = 20;
+		locktime = PLL_LOCK_TIME;
 	}
 	if (postdiv)
 		postdiv = (postdiv - 1) | PLLDIV_EN;
 	if (mult)
 		mult = mult - 1;
 
+	/* Protect against simultaneous calls to PLL setting seqeunce */
+	spin_lock_irqsave(&clockfw_lock, flags);
+
 	ctrl = __raw_readl(pll->base + PLLCTL);
 
 	/* Switch the PLL to bypass mode */
 	ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
 	__raw_writel(ctrl, pll->base + PLLCTL);
 
-	/*
-	 * Wait for 4 OSCIN/CLKIN cycles to ensure that the PLLC has switched
-	 * to bypass mode. Delay of 1us ensures we are good for all > 4MHz
-	 * OSCIN/CLKIN inputs. Typically the input is ~25MHz.
-	 */
-	udelay(1);
+	udelay(PLL_BYPASS_TIME);
 
 	/* Reset and enable PLL */
 	ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
@@ -408,11 +409,7 @@ int davinci_set_pllrate(struct pll_data
 	if (pll->flags & PLL_HAS_POSTDIV)
 		__raw_writel(postdiv, pll->base + POSTDIV);
 
-	/*
-	 * Wait for PLL to reset properly, OMAP-L138 datasheet says
-	 * 'min' time = 125ns
-	 */
-	udelay(1);
+	udelay(PLL_RESET_TIME);
 
 	/* Bring PLL out of reset */
 	ctrl |= PLLCTL_PLLRST;
@@ -424,17 +421,20 @@ int davinci_set_pllrate(struct pll_data
 	ctrl |= PLLCTL_PLLEN;
 	__raw_writel(ctrl, pll->base + PLLCTL);
 
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+
 	return 0;
 }
 EXPORT_SYMBOL(davinci_set_pllrate);
 
-int __init davinci_clk_init(struct davinci_clk *clocks)
+int __init davinci_clk_init(struct clk_lookup *clocks)
   {
-	struct davinci_clk *c;
+	struct clk_lookup *c;
 	struct clk *clk;
+	size_t num_clocks = 0;
 
-	for (c = clocks; c->lk.clk; c++) {
-		clk = c->lk.clk;
+	for (c = clocks; c->clk; c++) {
+		clk = c->clk;
 
 		if (!clk->recalc) {
 
@@ -457,35 +457,23 @@ int __init davinci_clk_init(struct davin
 		if (clk->lpsc)
 			clk->flags |= CLK_PSC;
 
-		clkdev_add(&c->lk);
 		clk_register(clk);
+		num_clocks++;
 
 		/* Turn on clocks that Linux doesn't otherwise manage */
 		if (clk->flags & ALWAYS_ENABLED)
 			clk_enable(clk);
 	}
 
-	return 0;
-}
-
-#ifdef CONFIG_PROC_FS
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
+	clkdev_add_table(clocks, num_clocks);
 
-static void *davinci_ck_start(struct seq_file *m, loff_t *pos)
-{
-	return *pos < 1 ? (void *)1 : NULL;
+	return 0;
 }
 
-static void *davinci_ck_next(struct seq_file *m, void *v, loff_t *pos)
-{
-	++*pos;
-	return NULL;
-}
+#ifdef CONFIG_DEBUG_FS
 
-static void davinci_ck_stop(struct seq_file *m, void *v)
-{
-}
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 
 #define CLKNAME_MAX	10		/* longest clock name */
 #define NEST_DELTA	2
@@ -525,41 +513,38 @@ dump_clock(struct seq_file *s, unsigned
 
 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...
+	struct clk *clk;
+
+	/*
+	 * Show clock tree; 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));
+	list_for_each_entry(clk, &clocks, node)
+		if (!clk->parent)
+			dump_clock(m, 0, clk);
 	mutex_unlock(&clocks_mutex);
 
 	return 0;
 }
 
-static const struct seq_operations davinci_ck_op = {
-	.start	= davinci_ck_start,
-	.next	= davinci_ck_next,
-	.stop	= davinci_ck_stop,
-	.show	= davinci_ck_show
-};
-
 static int davinci_ck_open(struct inode *inode, struct file *file)
 {
-	return seq_open(file, &davinci_ck_op);
+	return single_open(file, davinci_ck_show, NULL);
 }
 
-static const struct file_operations proc_davinci_ck_operations = {
+static const struct file_operations davinci_ck_operations = {
 	.open		= davinci_ck_open,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
-	.release	= seq_release,
+	.release	= single_release,
 };
 
-static int __init davinci_ck_proc_init(void)
+static int __init davinci_clk_debugfs_init(void)
 {
-	proc_create("davinci_clocks", 0, NULL, &proc_davinci_ck_operations);
+	debugfs_create_file("davinci_clocks", S_IFREG | S_IRUGO, NULL, NULL,
+						&davinci_ck_operations);
 	return 0;
 
 }
-__initcall(davinci_ck_proc_init);
-#endif /* CONFIG_DEBUG_PROC_FS */
+device_initcall(davinci_clk_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -12,9 +12,6 @@
 #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
@@ -53,6 +50,26 @@
 #define PLLDIV_EN       BIT(15)
 #define PLLDIV_RATIO_MASK 0x1f
 
+/*
+ * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN
+ * cycles to ensure that the PLLC has switched to bypass mode. Delay of 1us
+ * ensures we are good for all > 4MHz OSCIN/CLKIN inputs. Typically the input
+ * is ~25MHz. Units are micro seconds.
+ */
+#define PLL_BYPASS_TIME		1
+/* From OMAP-L138 datasheet table 6-4. Units are micro seconds */
+#define PLL_RESET_TIME		1
+/*
+ * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4
+ * Units are micro seconds.
+ */
+#define PLL_LOCK_TIME		20
+
+#ifndef __ASSEMBLER__
+
+#include <linux/list.h>
+#include <asm/clkdev.h>
+
 struct pll_data {
 	u32 phys_base;
 	void __iomem *base;
@@ -89,23 +106,19 @@ struct clk {
 #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,	\
-		},			\
-	}
+#define CLK(dev, con, ck) 	\
+	{			\
+		.dev_id = dev,	\
+		.con_id = con,	\
+		.clk = ck,	\
+	}			\
 
-int davinci_clk_init(struct davinci_clk *clocks);
+int davinci_clk_init(struct clk_lookup *clocks);
 int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
 				unsigned int mult, unsigned int postdiv);
 
 extern struct platform_device davinci_wdt_device;
 
 #endif
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/common.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/common.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/common.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,13 +11,13 @@
 #include <linux/module.h>
 #include <linux/io.h>
 #include <linux/etherdevice.h>
+#include <linux/davinci_emac.h>
 
 #include <asm/tlb.h>
 #include <asm/mach/map.h>
 
 #include <mach/common.h>
 #include <mach/cputype.h>
-#include <mach/emac.h>
 
 #include "clock.h"
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/cpuidle.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/cpuidle.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/cpuidle.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/cpuidle.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <asm/proc-fns.h>
 
 #include <mach/cpuidle.h>
+#include <mach/memory.h>
 
 #define DAVINCI_CPUIDLE_MAX_STATES	2
 
@@ -39,10 +40,6 @@ static struct cpuidle_driver davinci_idl
 static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device);
 static void __iomem *ddr2_reg_base;
 
-#define DDR2_SDRCR_OFFSET	0xc
-#define DDR2_SRPD_BIT		BIT(23)
-#define DDR2_LPMODEN_BIT	BIT(31)
-
 static void davinci_save_ddr_power(int enter, bool pdown)
 {
 	u32 val;
@@ -109,8 +106,6 @@ static int __init davinci_cpuidle_probe(
 	int ret;
 	struct cpuidle_device *device;
 	struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;
-	struct resource *ddr2_regs;
-	resource_size_t len;
 
 	device = &per_cpu(davinci_cpuidle_device, smp_processor_id());
 
@@ -119,28 +114,12 @@ static int __init davinci_cpuidle_probe(
 		return -ENOENT;
 	}
 
-	ddr2_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!ddr2_regs) {
-		dev_err(&pdev->dev, "cannot get DDR2 controller register base");
-		return -ENODEV;
-	}
-
-	len = resource_size(ddr2_regs);
-
-	ddr2_regs = request_mem_region(ddr2_regs->start, len, ddr2_regs->name);
-	if (!ddr2_regs)
-		return -EBUSY;
-
-	ddr2_reg_base = ioremap(ddr2_regs->start, len);
-	if (!ddr2_reg_base) {
-		ret = -ENOMEM;
-		goto ioremap_fail;
-	}
+	ddr2_reg_base = pdata->ddr2_ctlr_base;
 
 	ret = cpuidle_register_driver(&davinci_idle_driver);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register driver\n");
-		goto driver_register_fail;
+		return ret;
 	}
 
 	/* Wait for interrupt state */
@@ -167,18 +146,11 @@ static int __init davinci_cpuidle_probe(
 	ret = cpuidle_register_device(device);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register device\n");
-		goto device_register_fail;
+		cpuidle_unregister_driver(&davinci_idle_driver);
+		return ret;
 	}
 
 	return 0;
-
-device_register_fail:
-	cpuidle_unregister_driver(&davinci_idle_driver);
-driver_register_fail:
-	iounmap(ddr2_reg_base);
-ioremap_fail:
-	release_mem_region(ddr2_regs->start, len);
-	return ret;
 }
 
 static struct platform_driver davinci_cpuidle_driver = {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/da830.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/da830.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/da830.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/da830.c	2010-05-16 17:17:36.000000000 -0400
@@ -371,7 +371,7 @@ static struct clk rmii_clk = {
 	.parent		= &pll0_sysclk7,
 };
 
-static struct davinci_clk da830_clks[] = {
+static struct clk_lookup da830_clks[] = {
 	CLK(NULL,		"ref",		&ref_clk),
 	CLK(NULL,		"pll0",		&pll0_clk),
 	CLK(NULL,		"pll0_aux",	&pll0_aux_clk),
@@ -410,7 +410,7 @@ static struct davinci_clk da830_clks[] =
 	CLK("davinci-mcasp.0",	NULL,		&mcasp0_clk),
 	CLK("davinci-mcasp.1",	NULL,		&mcasp1_clk),
 	CLK("davinci-mcasp.2",	NULL,		&mcasp2_clk),
-	CLK("musb_hdrc",	NULL,		&usb20_clk),
+	CLK(NULL,		"usb20",	&usb20_clk),
 	CLK(NULL,		"aemif",	&aemif_clk),
 	CLK(NULL,		"aintc",	&aintc_clk),
 	CLK(NULL,		"secu_mgr",	&secu_mgr_clk),
@@ -1208,13 +1208,13 @@ static struct davinci_soc_info davinci_s
 
 void __init da830_init(void)
 {
-	da8xx_syscfg_base = ioremap(DA8XX_SYSCFG_BASE, SZ_4K);
-	if (WARN(!da8xx_syscfg_base, "Unable to map syscfg module"))
+	da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
+	if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"))
 		return;
 
 	davinci_soc_info_da830.jtag_id_base =
-					DA8XX_SYSCFG_VIRT(DA8XX_JTAG_ID_REG);
-	davinci_soc_info_da830.pinmux_base = DA8XX_SYSCFG_VIRT(0x120);
+					DA8XX_SYSCFG0_VIRT(DA8XX_JTAG_ID_REG);
+	davinci_soc_info_da830.pinmux_base = DA8XX_SYSCFG0_VIRT(0x120);
 
 	davinci_common_init(&davinci_soc_info_da830);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/da850.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/da850.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/da850.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/da850.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <mach/time.h>
 #include <mach/da8xx.h>
 #include <mach/cpufreq.h>
+#include <mach/pm.h>
 
 #include "clock.h"
 #include "mux.h"
@@ -40,6 +41,7 @@
 #define DA850_REF_FREQ		24000000
 
 #define CFGCHIP3_ASYNC3_CLKSRC	BIT(4)
+#define CFGCHIP3_PLL1_MASTER_LOCK	BIT(5)
 #define CFGCHIP0_PLL_MASTER_LOCK	BIT(4)
 
 static int da850_set_armrate(struct clk *clk, unsigned long rate);
@@ -333,7 +335,7 @@ static struct clk aemif_clk = {
 	.flags		= ALWAYS_ENABLED,
 };
 
-static struct davinci_clk da850_clks[] = {
+static struct clk_lookup da850_clks[] = {
 	CLK(NULL,		"ref",		&ref_clk),
 	CLK(NULL,		"pll0",		&pll0_clk),
 	CLK(NULL,		"pll0_aux",	&pll0_aux_clk),
@@ -535,6 +537,7 @@ static const struct mux_config da850_pin
 	MUX_CFG(DA850, GPIO2_15,	5,	0,	15,	8,	false)
 	MUX_CFG(DA850, GPIO4_0,		10,	28,	15,	8,	false)
 	MUX_CFG(DA850, GPIO4_1,		10,	24,	15,	8,	false)
+	MUX_CFG(DA850, RTC_ALARM,	0,	28,	15,	2,	false)
 #endif
 };
 
@@ -770,6 +773,12 @@ static struct map_desc da850_io_desc[] =
 		.length		= DA8XX_CP_INTC_SIZE,
 		.type		= MT_DEVICE
 	},
+	{
+		.virtual	= SRAM_VIRT,
+		.pfn		= __phys_to_pfn(DA8XX_ARM_RAM_BASE),
+		.length		= SZ_8K,
+		.type		= MT_DEVICE
+	},
 };
 
 static void __iomem *da850_psc_bases[] = {
@@ -825,12 +834,12 @@ static struct davinci_timer_info da850_t
 static void da850_set_async3_src(int pllnum)
 {
 	struct clk *clk, *newparent = pllnum ? &pll1_sysclk2 : &pll0_sysclk2;
-	struct davinci_clk *c;
+	struct clk_lookup *c;
 	unsigned int v;
 	int ret;
 
-	for (c = da850_clks; c->lk.clk; c++) {
-		clk = c->lk.clk;
+	for (c = da850_clks; c->clk; c++) {
+		clk = c->clk;
 		if (clk->flags & DA850_CLK_ASYNC3) {
 			ret = clk_set_parent(clk, newparent);
 			WARN(ret, "DA850: unable to re-parent clock %s",
@@ -838,12 +847,12 @@ static void da850_set_async3_src(int pll
 		}
        }
 
-	v = __raw_readl(DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP3_REG));
+	v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
 	if (pllnum)
 		v |= CFGCHIP3_ASYNC3_CLKSRC;
 	else
 		v &= ~CFGCHIP3_ASYNC3_CLKSRC;
-	__raw_writel(v, DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP3_REG));
+	__raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
 }
 
 #ifdef CONFIG_CPU_FREQ
@@ -987,7 +996,6 @@ static int da850_set_pll0rate(struct clk
 	unsigned int prediv, mult, postdiv;
 	struct da850_opp *opp;
 	struct pll_data *pll = clk->pll_data;
-	unsigned int v;
 	int ret;
 
 	opp = (struct da850_opp *) da850_freq_table[index].index;
@@ -995,11 +1003,6 @@ static int da850_set_pll0rate(struct clk
 	mult = opp->mult;
 	postdiv = opp->postdiv;
 
-	/* Unlock writing to PLL registers */
-	v = __raw_readl(DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP0_REG));
-	v &= ~CFGCHIP0_PLL_MASTER_LOCK;
-	__raw_writel(v, DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP0_REG));
-
 	ret = davinci_set_pllrate(pll, prediv, mult, postdiv);
 	if (WARN_ON(ret))
 		return ret;
@@ -1028,6 +1031,43 @@ static int da850_round_armrate(struct cl
 }
 #endif
 
+int da850_register_pm(struct platform_device *pdev)
+{
+	int ret;
+	struct davinci_pm_config *pdata = pdev->dev.platform_data;
+
+	ret = davinci_cfg_reg(DA850_RTC_ALARM);
+	if (ret)
+		return ret;
+
+	pdata->ddr2_ctlr_base = da8xx_get_mem_ctlr();
+	pdata->deepsleep_reg = DA8XX_SYSCFG1_VIRT(DA8XX_DEEPSLEEP_REG);
+	pdata->ddrpsc_num = DA8XX_LPSC1_EMIF3C;
+
+	pdata->cpupll_reg_base = ioremap(DA8XX_PLL0_BASE, SZ_4K);
+	if (!pdata->cpupll_reg_base)
+		return -ENOMEM;
+
+	pdata->ddrpll_reg_base = ioremap(DA8XX_PLL1_BASE, SZ_4K);
+	if (!pdata->ddrpll_reg_base) {
+		ret = -ENOMEM;
+		goto no_ddrpll_mem;
+	}
+
+	pdata->ddrpsc_reg_base = ioremap(DA8XX_PSC1_BASE, SZ_4K);
+	if (!pdata->ddrpsc_reg_base) {
+		ret = -ENOMEM;
+		goto no_ddrpsc_mem;
+	}
+
+	return platform_device_register(pdev);
+
+no_ddrpsc_mem:
+	iounmap(pdata->ddrpll_reg_base);
+no_ddrpll_mem:
+	iounmap(pdata->cpupll_reg_base);
+	return ret;
+}
 
 static struct davinci_soc_info davinci_soc_info_da850 = {
 	.io_desc		= da850_io_desc,
@@ -1049,17 +1089,25 @@ static struct davinci_soc_info davinci_s
 	.gpio_irq		= IRQ_DA8XX_GPIO0,
 	.serial_dev		= &da8xx_serial_device,
 	.emac_pdata		= &da8xx_emac_pdata,
+	.sram_dma		= DA8XX_ARM_RAM_BASE,
+	.sram_len		= SZ_8K,
 };
 
 void __init da850_init(void)
 {
-	da8xx_syscfg_base = ioremap(DA8XX_SYSCFG_BASE, SZ_4K);
-	if (WARN(!da8xx_syscfg_base, "Unable to map syscfg module"))
+	unsigned int v;
+
+	da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
+	if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"))
+		return;
+
+	da8xx_syscfg1_base = ioremap(DA8XX_SYSCFG1_BASE, SZ_4K);
+	if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module"))
 		return;
 
 	davinci_soc_info_da850.jtag_id_base =
-					DA8XX_SYSCFG_VIRT(DA8XX_JTAG_ID_REG);
-	davinci_soc_info_da850.pinmux_base = DA8XX_SYSCFG_VIRT(0x120);
+					DA8XX_SYSCFG0_VIRT(DA8XX_JTAG_ID_REG);
+	davinci_soc_info_da850.pinmux_base = DA8XX_SYSCFG0_VIRT(0x120);
 
 	davinci_common_init(&davinci_soc_info_da850);
 
@@ -1071,4 +1119,14 @@ void __init da850_init(void)
 	 * be any noticible change even in non-DVFS use cases.
 	 */
 	da850_set_async3_src(1);
+
+	/* Unlock writing to PLL0 registers */
+	v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG));
+	v &= ~CFGCHIP0_PLL_MASTER_LOCK;
+	__raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG));
+
+	/* Unlock writing to PLL1 registers */
+	v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
+	v &= ~CFGCHIP3_PLL1_MASTER_LOCK;
+	__raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/devices-da8xx.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/devices-da8xx.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/devices-da8xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/devices-da8xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,8 +24,10 @@
 #include "clock.h"
 
 #define DA8XX_TPCC_BASE			0x01c00000
+#define DA850_TPCC1_BASE		0x01e30000
 #define DA8XX_TPTC0_BASE		0x01c08000
 #define DA8XX_TPTC1_BASE		0x01c08400
+#define DA850_TPTC2_BASE		0x01e38000
 #define DA8XX_WDOG_BASE			0x01c21000 /* DA8XX_TIMER64P1_BASE */
 #define DA8XX_I2C0_BASE			0x01c22000
 #define DA8XX_RTC_BASE			0x01C23000
@@ -42,7 +44,8 @@
 #define DA8XX_MDIO_REG_OFFSET		0x4000
 #define DA8XX_EMAC_CTRL_RAM_SIZE	SZ_8K
 
-void __iomem *da8xx_syscfg_base;
+void __iomem *da8xx_syscfg0_base;
+void __iomem *da8xx_syscfg1_base;
 
 static struct plat_serial8250_port da8xx_serial_pdata[] = {
 	{
@@ -82,11 +85,6 @@ struct platform_device da8xx_serial_devi
 	},
 };
 
-static const s8 da8xx_dma_chan_no_event[] = {
-	20, 21,
-	-1
-};
-
 static const s8 da8xx_queue_tc_mapping[][2] = {
 	/* {event queue no, TC no} */
 	{0, 0},
@@ -101,20 +99,52 @@ static const s8 da8xx_queue_priority_map
 	{-1, -1}
 };
 
-static struct edma_soc_info da8xx_edma_info[] = {
+static const s8 da850_queue_tc_mapping[][2] = {
+	/* {event queue no, TC no} */
+	{0, 0},
+	{-1, -1}
+};
+
+static const s8 da850_queue_priority_mapping[][2] = {
+	/* {event queue no, Priority} */
+	{0, 3},
+	{-1, -1}
+};
+
+static struct edma_soc_info da830_edma_info[] = {
 	{
 		.n_channel		= 32,
 		.n_region		= 4,
 		.n_slot			= 128,
 		.n_tc			= 2,
 		.n_cc			= 1,
-		.noevent		= da8xx_dma_chan_no_event,
 		.queue_tc_mapping	= da8xx_queue_tc_mapping,
 		.queue_priority_mapping	= da8xx_queue_priority_mapping,
 	},
 };
 
-static struct resource da8xx_edma_resources[] = {
+static struct edma_soc_info da850_edma_info[] = {
+	{
+		.n_channel		= 32,
+		.n_region		= 4,
+		.n_slot			= 128,
+		.n_tc			= 2,
+		.n_cc			= 1,
+		.queue_tc_mapping	= da8xx_queue_tc_mapping,
+		.queue_priority_mapping	= da8xx_queue_priority_mapping,
+	},
+	{
+		.n_channel		= 32,
+		.n_region		= 4,
+		.n_slot			= 128,
+		.n_tc			= 1,
+		.n_cc			= 1,
+		.queue_tc_mapping	= da850_queue_tc_mapping,
+		.queue_priority_mapping	= da850_queue_priority_mapping,
+	},
+};
+
+static struct resource da830_edma_resources[] = {
 	{
 		.name	= "edma_cc0",
 		.start	= DA8XX_TPCC_BASE,
@@ -145,19 +175,91 @@ static struct resource da8xx_edma_resour
 	},
 };
 
-static struct platform_device da8xx_edma_device = {
+static struct resource da850_edma_resources[] = {
+	{
+		.name	= "edma_cc0",
+		.start	= DA8XX_TPCC_BASE,
+		.end	= DA8XX_TPCC_BASE + SZ_32K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "edma_tc0",
+		.start	= DA8XX_TPTC0_BASE,
+		.end	= DA8XX_TPTC0_BASE + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "edma_tc1",
+		.start	= DA8XX_TPTC1_BASE,
+		.end	= DA8XX_TPTC1_BASE + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "edma_cc1",
+		.start	= DA850_TPCC1_BASE,
+		.end	= DA850_TPCC1_BASE + SZ_32K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "edma_tc2",
+		.start	= DA850_TPTC2_BASE,
+		.end	= DA850_TPTC2_BASE + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "edma0",
+		.start	= IRQ_DA8XX_CCINT0,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.name	= "edma0_err",
+		.start	= IRQ_DA8XX_CCERRINT,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.name	= "edma1",
+		.start	= IRQ_DA850_CCINT1,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.name	= "edma1_err",
+		.start	= IRQ_DA850_CCERRINT1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device da830_edma_device = {
 	.name		= "edma",
 	.id		= -1,
 	.dev = {
-		.platform_data	= da8xx_edma_info,
+		.platform_data = da830_edma_info,
 	},
-	.num_resources	= ARRAY_SIZE(da8xx_edma_resources),
-	.resource	= da8xx_edma_resources,
+	.num_resources	= ARRAY_SIZE(da830_edma_resources),
+	.resource	= da830_edma_resources,
+};
+
+static struct platform_device da850_edma_device = {
+	.name		= "edma",
+	.id		= -1,
+	.dev = {
+		.platform_data = da850_edma_info,
+	},
+	.num_resources	= ARRAY_SIZE(da850_edma_resources),
+	.resource	= da850_edma_resources,
 };
 
 int __init da8xx_register_edma(void)
 {
-	return platform_device_register(&da8xx_edma_device);
+	struct platform_device *pdev;
+
+	if (cpu_is_davinci_da830())
+		pdev = &da830_edma_device;
+	else if (cpu_is_davinci_da850())
+		pdev = &da850_edma_device;
+	else
+		return -ENODEV;
+
+	return platform_device_register(pdev);
 }
 
 static struct resource da8xx_i2c_resources0[] = {
@@ -495,6 +597,19 @@ int da8xx_register_rtc(void)
 	return ret;
 }
 
+static void __iomem *da8xx_ddr2_ctlr_base;
+void __iomem * __init da8xx_get_mem_ctlr(void)
+{
+	if (da8xx_ddr2_ctlr_base)
+		return da8xx_ddr2_ctlr_base;
+
+	da8xx_ddr2_ctlr_base = ioremap(DA8XX_DDR2_CTL_BASE, SZ_32K);
+	if (!da8xx_ddr2_ctlr_base)
+		pr_warning("%s: Unable to map DDR2 controller",	__func__);
+
+	return da8xx_ddr2_ctlr_base;
+}
+
 static struct resource da8xx_cpuidle_resources[] = {
 	{
 		.start		= DA8XX_DDR2_CTL_BASE,
@@ -520,6 +635,7 @@ static struct platform_device da8xx_cpui
 
 int __init da8xx_register_cpuidle(void)
 {
+	da8xx_cpuidle_pdata.ddr2_ctlr_base = da8xx_get_mem_ctlr();
+
 	return platform_device_register(&da8xx_cpuidle_device);
 }
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm355.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/dm355.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm355.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/dm355.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <mach/serial.h>
 #include <mach/common.h>
 #include <mach/asp.h>
+#include <mach/spi.h>
 
 #include "clock.h"
 #include "mux.h"
@@ -125,7 +126,6 @@ static struct clk vpss_slave_clk = {
 	.lpsc = DAVINCI_LPSC_VPSSSLV,
 };
 
-
 static struct clk clkout1_clk = {
 	.name = "clkout1",
 	.parent = &pll1_aux_clk,
@@ -335,7 +335,7 @@ static struct clk usb_clk = {
 	.lpsc = DAVINCI_LPSC_USB,
 };
 
-static struct davinci_clk dm355_clks[] = {
+static struct clk_lookup dm355_clks[] = {
 	CLK(NULL, "ref", &ref_clk),
 	CLK(NULL, "pll1", &pll1_clk),
 	CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
@@ -363,9 +363,9 @@ static struct davinci_clk dm355_clks[] =
 	CLK("davinci-asp.1", NULL, &asp1_clk),
 	CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
 	CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
-	CLK(NULL, "spi0", &spi0_clk),
-	CLK(NULL, "spi1", &spi1_clk),
-	CLK(NULL, "spi2", &spi2_clk),
+	CLK("spi_davinci.0", NULL, &spi0_clk),
+	CLK("spi_davinci.1", NULL, &spi1_clk),
+	CLK("spi_davinci.2", NULL, &spi2_clk),
 	CLK(NULL, "gpio", &gpio_clk),
 	CLK(NULL, "aemif", &aemif_clk),
 	CLK(NULL, "pwm0", &pwm0_clk),
@@ -392,24 +392,40 @@ static struct resource dm355_spi0_resour
 		.flags = IORESOURCE_MEM,
 	},
 	{
-		.start = IRQ_DM355_SPINT0_1,
+		.start = IRQ_DM355_SPINT0_0,
 		.flags = IORESOURCE_IRQ,
 	},
-	/* Not yet used, so not included:
-	 * IORESOURCE_IRQ:
-	 *  - IRQ_DM355_SPINT0_0
-	 * IORESOURCE_DMA:
-	 *  - DAVINCI_DMA_SPI_SPIX
-	 *  - DAVINCI_DMA_SPI_SPIR
-	 */
+	{
+		.start = 17,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = 16,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = EVENTQ_1,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
+static struct davinci_spi_platform_data dm355_spi0_pdata = {
+	.version 	= SPI_VERSION_1,
+	.num_chipselect = 2,
+	.clk_internal	= 1,
+	.cs_hold	= 1,
+	.intr_level	= 0,
+	.poll_mode	= 1,	/* 0 -> interrupt mode 1-> polling mode */
+	.c2tdelay	= 0,
+	.t2cdelay	= 0,
+};
 static struct platform_device dm355_spi0_device = {
 	.name = "spi_davinci",
 	.id = 0,
 	.dev = {
 		.dma_mask = &dm355_spi0_dma_mask,
 		.coherent_dma_mask = DMA_BIT_MASK(32),
+		.platform_data = &dm355_spi0_pdata,
 	},
 	.num_resources = ARRAY_SIZE(dm355_spi0_resources),
 	.resource = dm355_spi0_resources,
@@ -564,13 +580,6 @@ static u8 dm355_default_priorities[DAVIN
 
 /*----------------------------------------------------------------------*/
 
-static const s8 dma_chan_dm355_no_event[] = {
-	12, 13, 24, 56, 57,
-	58, 59, 60, 61, 62,
-	63,
-	-1
-};
-
 static const s8
 queue_tc_mapping[][2] = {
 	/* {event queue no, TC no} */
@@ -594,7 +603,6 @@ static struct edma_soc_info dm355_edma_i
 		.n_slot			= 128,
 		.n_tc			= 2,
 		.n_cc			= 1,
-		.noevent		= dma_chan_dm355_no_event,
 		.queue_tc_mapping	= queue_tc_mapping,
 		.queue_priority_mapping	= queue_priority_mapping,
 	},
@@ -665,6 +673,17 @@ static struct platform_device dm355_asp1
 	.resource	= dm355_asp1_resources,
 };
 
+static void dm355_ccdc_setup_pinmux(void)
+{
+	davinci_cfg_reg(DM355_VIN_PCLK);
+	davinci_cfg_reg(DM355_VIN_CAM_WEN);
+	davinci_cfg_reg(DM355_VIN_CAM_VD);
+	davinci_cfg_reg(DM355_VIN_CAM_HD);
+	davinci_cfg_reg(DM355_VIN_YIN_EN);
+	davinci_cfg_reg(DM355_VIN_CINL_EN);
+	davinci_cfg_reg(DM355_VIN_CINH_EN);
+}
+
 static struct resource dm355_vpss_resources[] = {
 	{
 		/* VPSS BL Base address */
@@ -701,6 +720,10 @@ static struct resource vpfe_resources[]
 		.end            = IRQ_VDINT1,
 		.flags          = IORESOURCE_IRQ,
 	},
+};
+
+static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
+static struct resource dm355_ccdc_resource[] = {
 	/* CCDC Base address */
 	{
 		.flags          = IORESOURCE_MEM,
@@ -708,8 +731,18 @@ static struct resource vpfe_resources[]
 		.end            = 0x01c70600 + 0x1ff,
 	},
 };
+static struct platform_device dm355_ccdc_dev = {
+	.name           = "dm355_ccdc",
+	.id             = -1,
+	.num_resources  = ARRAY_SIZE(dm355_ccdc_resource),
+	.resource       = dm355_ccdc_resource,
+	.dev = {
+		.dma_mask               = &vpfe_capture_dma_mask,
+		.coherent_dma_mask      = DMA_BIT_MASK(32),
+		.platform_data		= dm355_ccdc_setup_pinmux,
+	},
+};
 
-static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
 static struct platform_device vpfe_capture_dev = {
 	.name		= CAPTURE_DRV_NAME,
 	.id		= -1,
@@ -857,20 +890,13 @@ static int __init dm355_init_devices(voi
 	if (!cpu_is_davinci_dm355())
 		return 0;
 
+	/* Add ccdc clock aliases */
+	clk_add_alias("master", dm355_ccdc_dev.name, "vpss_master", NULL);
+	clk_add_alias("slave", dm355_ccdc_dev.name, "vpss_master", NULL);
 	davinci_cfg_reg(DM355_INT_EDMA_CC);
 	platform_device_register(&dm355_edma_device);
 	platform_device_register(&dm355_vpss_device);
-	/*
-	 * setup Mux configuration for vpfe input and register
-	 * vpfe capture platform device
-	 */
-	davinci_cfg_reg(DM355_VIN_PCLK);
-	davinci_cfg_reg(DM355_VIN_CAM_WEN);
-	davinci_cfg_reg(DM355_VIN_CAM_VD);
-	davinci_cfg_reg(DM355_VIN_CAM_HD);
-	davinci_cfg_reg(DM355_VIN_YIN_EN);
-	davinci_cfg_reg(DM355_VIN_CINL_EN);
-	davinci_cfg_reg(DM355_VIN_CINH_EN);
+	platform_device_register(&dm355_ccdc_dev);
 	platform_device_register(&vpfe_capture_dev);
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm365.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/dm365.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm365.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/dm365.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/gpio.h>
+#include <linux/spi/spi.h>
 
 #include <asm/mach/map.h>
 
@@ -32,6 +33,8 @@
 #include <mach/common.h>
 #include <mach/asp.h>
 #include <mach/keyscan.h>
+#include <mach/spi.h>
+
 
 #include "clock.h"
 #include "mux.h"
@@ -403,7 +406,7 @@ static struct clk mjcp_clk = {
 	.lpsc		= DM365_LPSC_MJCP,
 };
 
-static struct davinci_clk dm365_clks[] = {
+static struct clk_lookup dm365_clks[] = {
 	CLK(NULL, "ref", &ref_clk),
 	CLK(NULL, "pll1", &pll1_clk),
 	CLK(NULL, "pll1_aux", &pll1_aux_clk),
@@ -455,7 +458,7 @@ static struct davinci_clk dm365_clks[] =
 	CLK(NULL, "timer3", &timer3_clk),
 	CLK(NULL, "usb", &usb_clk),
 	CLK("davinci_emac.1", NULL, &emac_clk),
-	CLK("voice_codec", NULL, &voicecodec_clk),
+	CLK("davinci_voicecodec", NULL, &voicecodec_clk),
 	CLK("davinci-asp.0", NULL, &asp0_clk),
 	CLK(NULL, "rto", &rto_clk),
 	CLK(NULL, "mjcp", &mjcp_clk),
@@ -606,9 +609,78 @@ INT_CFG(DM365,  INT_NSF_DISABLE,     25,
 
 EVT_CFG(DM365,	EVT2_ASP_TX,         0,     1,    0,     false)
 EVT_CFG(DM365,	EVT3_ASP_RX,         1,     1,    0,     false)
+EVT_CFG(DM365,	EVT2_VC_TX,          0,     1,    1,     false)
+EVT_CFG(DM365,	EVT3_VC_RX,          1,     1,    1,     false)
 #endif
 };
 
+static u64 dm365_spi0_dma_mask = DMA_BIT_MASK(32);
+
+static struct davinci_spi_platform_data dm365_spi0_pdata = {
+	.version 	= SPI_VERSION_1,
+	.num_chipselect = 2,
+	.clk_internal	= 1,
+	.cs_hold	= 1,
+	.intr_level	= 0,
+	.poll_mode	= 1,	/* 0 -> interrupt mode 1-> polling mode */
+	.c2tdelay	= 0,
+	.t2cdelay	= 0,
+};
+
+static struct resource dm365_spi0_resources[] = {
+	{
+		.start = 0x01c66000,
+		.end   = 0x01c667ff,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_DM365_SPIINT0_0,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = 17,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = 16,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = EVENTQ_3,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device dm365_spi0_device = {
+	.name = "spi_davinci",
+	.id = 0,
+	.dev = {
+		.dma_mask = &dm365_spi0_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+		.platform_data = &dm365_spi0_pdata,
+	},
+	.num_resources = ARRAY_SIZE(dm365_spi0_resources),
+	.resource = dm365_spi0_resources,
+};
+
+void __init dm365_init_spi0(unsigned chipselect_mask,
+		struct spi_board_info *info, unsigned len)
+{
+	davinci_cfg_reg(DM365_SPI0_SCLK);
+	davinci_cfg_reg(DM365_SPI0_SDI);
+	davinci_cfg_reg(DM365_SPI0_SDO);
+
+	/* not all slaves will be wired up */
+	if (chipselect_mask & BIT(0))
+		davinci_cfg_reg(DM365_SPI0_SDENA0);
+	if (chipselect_mask & BIT(1))
+		davinci_cfg_reg(DM365_SPI0_SDENA1);
+
+	spi_register_board_info(info, len);
+
+	platform_device_register(&dm365_spi0_device);
+}
+
 static struct emac_platform_data dm365_emac_pdata = {
 	.ctrl_reg_offset	= DM365_EMAC_CNTRL_OFFSET,
 	.ctrl_mod_reg_offset	= DM365_EMAC_CNTRL_MOD_OFFSET,
@@ -686,7 +758,6 @@ static u8 dm365_default_priorities[DAVIN
 	[IRQ_MMCINT]			= 7,
 	[IRQ_DM365_MMCINT1]		= 7,
 	[IRQ_DM365_PWMINT3]		= 7,
-	[IRQ_DDRINT]			= 4,
 	[IRQ_AEMIFINT]			= 2,
 	[IRQ_DM365_SDIOINT1]		= 2,
 	[IRQ_TINT0_TINT12]		= 7,
@@ -754,7 +825,7 @@ static struct edma_soc_info dm365_edma_i
 		.n_cc			= 1,
 		.queue_tc_mapping	= dm365_queue_tc_mapping,
 		.queue_priority_mapping	= dm365_queue_priority_mapping,
-		.default_queue		= EVENTQ_2,
+		.default_queue		= EVENTQ_3,
 	},
 };
 
@@ -835,6 +906,31 @@ static struct platform_device dm365_asp_
 	.resource	= dm365_asp_resources,
 };
 
+static struct resource dm365_vc_resources[] = {
+	{
+		.start	= DAVINCI_DM365_VC_BASE,
+		.end	= DAVINCI_DM365_VC_BASE + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= DAVINCI_DMA_VC_TX,
+		.end	= DAVINCI_DMA_VC_TX,
+		.flags	= IORESOURCE_DMA,
+	},
+	{
+		.start	= DAVINCI_DMA_VC_RX,
+		.end	= DAVINCI_DMA_VC_RX,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device dm365_vc_device = {
+	.name		= "davinci_voicecodec",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(dm365_vc_resources),
+	.resource	= dm365_vc_resources,
+};
+
 static struct resource dm365_rtc_resources[] = {
 	{
 		.start = DM365_RTC_BASE,
@@ -991,6 +1087,14 @@ void __init dm365_init_asp(struct snd_pl
 	platform_device_register(&dm365_asp_device);
 }
 
+void __init dm365_init_vc(struct snd_platform_data *pdata)
+{
+	davinci_cfg_reg(DM365_EVT2_VC_TX);
+	davinci_cfg_reg(DM365_EVT3_VC_RX);
+	dm365_vc_device.dev.platform_data = pdata;
+	platform_device_register(&dm365_vc_device);
+}
+
 void __init dm365_init_ks(struct davinci_ks_platform_data *pdata)
 {
 	dm365_ks_device.dev.platform_data = pdata;
@@ -1008,6 +1112,97 @@ void __init dm365_init(void)
 	davinci_common_init(&davinci_soc_info_dm365);
 }
 
+static struct resource dm365_vpss_resources[] = {
+	{
+		/* VPSS ISP5 Base address */
+		.name           = "isp5",
+		.start          = 0x01c70000,
+		.end            = 0x01c70000 + 0xff,
+		.flags          = IORESOURCE_MEM,
+	},
+	{
+		/* VPSS CLK Base address */
+		.name           = "vpss",
+		.start          = 0x01c70200,
+		.end            = 0x01c70200 + 0xff,
+		.flags          = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device dm365_vpss_device = {
+       .name                   = "vpss",
+       .id                     = -1,
+       .dev.platform_data      = "dm365_vpss",
+       .num_resources          = ARRAY_SIZE(dm365_vpss_resources),
+       .resource               = dm365_vpss_resources,
+};
+
+static struct resource vpfe_resources[] = {
+	{
+		.start          = IRQ_VDINT0,
+		.end            = IRQ_VDINT0,
+		.flags          = IORESOURCE_IRQ,
+	},
+	{
+		.start          = IRQ_VDINT1,
+		.end            = IRQ_VDINT1,
+		.flags          = IORESOURCE_IRQ,
+	},
+};
+
+static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
+static struct platform_device vpfe_capture_dev = {
+	.name           = CAPTURE_DRV_NAME,
+	.id             = -1,
+	.num_resources  = ARRAY_SIZE(vpfe_resources),
+	.resource       = vpfe_resources,
+	.dev = {
+		.dma_mask               = &vpfe_capture_dma_mask,
+		.coherent_dma_mask      = DMA_BIT_MASK(32),
+	},
+};
+
+static void dm365_isif_setup_pinmux(void)
+{
+	davinci_cfg_reg(DM365_VIN_CAM_WEN);
+	davinci_cfg_reg(DM365_VIN_CAM_VD);
+	davinci_cfg_reg(DM365_VIN_CAM_HD);
+	davinci_cfg_reg(DM365_VIN_YIN4_7_EN);
+	davinci_cfg_reg(DM365_VIN_YIN0_3_EN);
+}
+
+static struct resource isif_resource[] = {
+	/* ISIF Base address */
+	{
+		.start          = 0x01c71000,
+		.end            = 0x01c71000 + 0x1ff,
+		.flags          = IORESOURCE_MEM,
+	},
+	/* ISIF Linearization table 0 */
+	{
+		.start          = 0x1C7C000,
+		.end            = 0x1C7C000 + 0x2ff,
+		.flags          = IORESOURCE_MEM,
+	},
+	/* ISIF Linearization table 1 */
+	{
+		.start          = 0x1C7C400,
+		.end            = 0x1C7C400 + 0x2ff,
+		.flags          = IORESOURCE_MEM,
+	},
+};
+static struct platform_device dm365_isif_dev = {
+	.name           = "isif",
+	.id             = -1,
+	.num_resources  = ARRAY_SIZE(isif_resource),
+	.resource       = isif_resource,
+	.dev = {
+		.dma_mask               = &vpfe_capture_dma_mask,
+		.coherent_dma_mask      = DMA_BIT_MASK(32),
+		.platform_data		= dm365_isif_setup_pinmux,
+	},
+};
+
 static int __init dm365_init_devices(void)
 {
 	if (!cpu_is_davinci_dm365())
@@ -1016,7 +1211,16 @@ static int __init dm365_init_devices(voi
 	davinci_cfg_reg(DM365_INT_EDMA_CC);
 	platform_device_register(&dm365_edma_device);
 	platform_device_register(&dm365_emac_device);
-
+	/* Add isif clock alias */
+	clk_add_alias("master", dm365_isif_dev.name, "vpss_master", NULL);
+	platform_device_register(&dm365_vpss_device);
+	platform_device_register(&dm365_isif_dev);
+	platform_device_register(&vpfe_capture_dev);
 	return 0;
 }
 postcore_initcall(dm365_init_devices);
+
+void dm365_set_vpfe_config(struct vpfe_config *cfg)
+{
+       vpfe_capture_dev.dev.platform_data = cfg;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm644x.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/dm644x.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm644x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/dm644x.c	2010-05-16 17:17:36.000000000 -0400
@@ -277,7 +277,7 @@ static struct clk timer2_clk = {
 	.usecount = 1,              /* REVISIT: why cant' this be disabled? */
 };
 
-struct davinci_clk dm644x_clks[] = {
+struct clk_lookup dm644x_clks[] = {
 	CLK(NULL, "ref", &ref_clk),
 	CLK(NULL, "pll1", &pll1_clk),
 	CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
@@ -479,15 +479,6 @@ static u8 dm644x_default_priorities[DAVI
 
 /*----------------------------------------------------------------------*/
 
-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 const s8
 queue_tc_mapping[][2] = {
 	/* {event queue no, TC no} */
@@ -511,7 +502,6 @@ static struct edma_soc_info dm644x_edma_
 		.n_slot			= 128,
 		.n_tc			= 2,
 		.n_cc			= 1,
-		.noevent		= dma_chan_dm644x_no_event,
 		.queue_tc_mapping	= queue_tc_mapping,
 		.queue_priority_mapping	= queue_priority_mapping,
 	},
@@ -612,6 +602,11 @@ static struct resource vpfe_resources[]
 		.end            = IRQ_VDINT1,
 		.flags          = IORESOURCE_IRQ,
 	},
+};
+
+static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
+static struct resource dm644x_ccdc_resource[] = {
+	/* CCDC Base address */
 	{
 		.start          = 0x01c70400,
 		.end            = 0x01c70400 + 0xff,
@@ -619,7 +614,17 @@ static struct resource vpfe_resources[]
 	},
 };
 
-static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
+static struct platform_device dm644x_ccdc_dev = {
+	.name           = "dm644x_ccdc",
+	.id             = -1,
+	.num_resources  = ARRAY_SIZE(dm644x_ccdc_resource),
+	.resource       = dm644x_ccdc_resource,
+	.dev = {
+		.dma_mask               = &vpfe_capture_dma_mask,
+		.coherent_dma_mask      = DMA_BIT_MASK(32),
+	},
+};
+
 static struct platform_device vpfe_capture_dev = {
 	.name		= CAPTURE_DRV_NAME,
 	.id		= -1,
@@ -769,9 +774,13 @@ static int __init dm644x_init_devices(vo
 	if (!cpu_is_davinci_dm644x())
 		return 0;
 
+	/* Add ccdc clock aliases */
+	clk_add_alias("master", dm644x_ccdc_dev.name, "vpss_master", NULL);
+	clk_add_alias("slave", dm644x_ccdc_dev.name, "vpss_slave", NULL);
 	platform_device_register(&dm644x_edma_device);
 	platform_device_register(&dm644x_emac_device);
 	platform_device_register(&dm644x_vpss_device);
+	platform_device_register(&dm644x_ccdc_dev);
 	platform_device_register(&vpfe_capture_dev);
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm646x.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/dm646x.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm646x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/dm646x.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,7 +42,6 @@
 /*
  * Device specific clocks
  */
-#define DM646X_REF_FREQ		27000000
 #define DM646X_AUX_FREQ		24000000
 
 static struct pll_data pll1_data = {
@@ -57,7 +56,6 @@ static struct pll_data pll2_data = {
 
 static struct clk ref_clk = {
 	.name = "ref_clk",
-	.rate = DM646X_REF_FREQ,
 };
 
 static struct clk aux_clkin = {
@@ -313,7 +311,7 @@ static struct clk vpif1_clk = {
 	.flags = ALWAYS_ENABLED,
 };
 
-struct davinci_clk dm646x_clks[] = {
+struct clk_lookup dm646x_clks[] = {
 	CLK(NULL, "ref", &ref_clk),
 	CLK(NULL, "aux", &aux_clkin),
 	CLK(NULL, "pll1", &pll1_clk),
@@ -513,14 +511,6 @@ static u8 dm646x_default_priorities[DAVI
 
 /*----------------------------------------------------------------------*/
 
-static const s8 dma_chan_dm646x_no_event[] = {
-	 0,  1,  2,  3, 13,
-	14, 15, 24, 25, 26,
-	27, 30, 31, 54, 55,
-	56,
-	-1
-};
-
 /* Four Transfer Controllers on DM646x */
 static const s8
 dm646x_queue_tc_mapping[][2] = {
@@ -549,7 +539,6 @@ static struct edma_soc_info dm646x_edma_
 		.n_slot			= 512,
 		.n_tc			= 4,
 		.n_cc			= 1,
-		.noevent		= dma_chan_dm646x_no_event,
 		.queue_tc_mapping	= dm646x_queue_tc_mapping,
 		.queue_priority_mapping	= dm646x_queue_priority_mapping,
 	},
@@ -925,6 +914,7 @@ void dm646x_setup_vpif(struct vpif_displ
 
 void __init dm646x_init(void)
 {
+	dm646x_board_setup_refclk(&ref_clk);
 	davinci_common_init(&davinci_soc_info_dm646x);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dma.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/edma.h>
 
@@ -226,11 +227,11 @@ struct edma {
 	 */
 	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.
+	/* The edma_unused bit for each channel is clear unless
+	 * it is not being used on this platform. It uses a bit
+	 * of SOC-specific initialization code.
 	 */
-	DECLARE_BITMAP(edma_noevent, EDMA_MAX_DMACH);
+	DECLARE_BITMAP(edma_unused, EDMA_MAX_DMACH);
 
 	unsigned	irq_res_start;
 	unsigned	irq_res_end;
@@ -243,6 +244,7 @@ struct edma {
 };
 
 static struct edma *edma_info[EDMA_MAX_CC];
+static int arch_num_cc;
 
 /* dummy param set used to (re)initialize parameter RAM slots */
 static const struct edmacc_param dummy_paramset = {
@@ -555,8 +557,27 @@ static int reserve_contiguous_slots(int
 	return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1);
 }
 
+static int prepare_unused_channel_list(struct device *dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	int i, ctlr;
+
+	for (i = 0; i < pdev->num_resources; i++) {
+		if ((pdev->resource[i].flags & IORESOURCE_DMA) &&
+				(int)pdev->resource[i].start >= 0) {
+			ctlr = EDMA_CTLR(pdev->resource[i].start);
+			clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start),
+					edma_info[ctlr]->edma_unused);
+		}
+	}
+
+	return 0;
+}
+
 /*-----------------------------------------------------------------------*/
 
+static bool unused_chan_list_done;
+
 /* Resource alloc/free:  dma channels, parameter RAM slots */
 
 /**
@@ -594,7 +615,22 @@ int edma_alloc_channel(int channel,
 		void *data,
 		enum dma_event_q eventq_no)
 {
-	unsigned i, done, ctlr = 0;
+	unsigned i, done = 0, ctlr = 0;
+	int ret = 0;
+
+	if (!unused_chan_list_done) {
+		/*
+		 * Scan all the platform devices to find out the EDMA channels
+		 * used and clear them in the unused list, making the rest
+		 * available for ARM usage.
+		 */
+		ret = bus_for_each_dev(&platform_bus_type, NULL, NULL,
+				prepare_unused_channel_list);
+		if (ret < 0)
+			return ret;
+
+		unused_chan_list_done = true;
+	}
 
 	if (channel >= 0) {
 		ctlr = EDMA_CTLR(channel);
@@ -602,15 +638,15 @@ int edma_alloc_channel(int channel,
 	}
 
 	if (channel < 0) {
-		for (i = 0; i < EDMA_MAX_CC; i++) {
+		for (i = 0; i < arch_num_cc; i++) {
 			channel = 0;
 			for (;;) {
 				channel = find_next_bit(edma_info[i]->
-						edma_noevent,
+						edma_unused,
 						edma_info[i]->num_channels,
 						channel);
 				if (channel == edma_info[i]->num_channels)
-					return -ENOMEM;
+					break;
 				if (!test_and_set_bit(channel,
 						edma_info[i]->edma_inuse)) {
 					done = 1;
@@ -622,6 +658,8 @@ int edma_alloc_channel(int channel,
 			if (done)
 				break;
 		}
+		if (!done)
+			return -ENOMEM;
 	} else if (channel >= edma_info[ctlr]->num_channels) {
 		return -EINVAL;
 	} else if (test_and_set_bit(channel, edma_info[ctlr]->edma_inuse)) {
@@ -642,7 +680,7 @@ int edma_alloc_channel(int channel,
 
 	map_dmach_queue(ctlr, channel, eventq_no);
 
-	return channel;
+	return EDMA_CTLR_CHAN(ctlr, channel);
 }
 EXPORT_SYMBOL(edma_alloc_channel);
 
@@ -1219,7 +1257,7 @@ int edma_start(unsigned channel)
 		unsigned int mask = (1 << (channel & 0x1f));
 
 		/* EDMA channels without event association */
-		if (test_bit(channel, edma_info[ctlr]->edma_noevent)) {
+		if (test_bit(channel, edma_info[ctlr]->edma_unused)) {
 			pr_debug("EDMA: ESR%d %08x\n", j,
 				edma_shadow0_read_array(ctlr, SH_ESR, j));
 			edma_shadow0_write_array(ctlr, SH_ESR, j, mask);
@@ -1229,7 +1267,8 @@ int edma_start(unsigned channel)
 		/* EDMA channel with event association */
 		pr_debug("EDMA: ER%d %08x\n", j,
 			edma_shadow0_read_array(ctlr, SH_ER, j));
-		/* Clear any pending error */
+		/* Clear any pending event or error */
+		edma_write_array(ctlr, EDMA_ECR, j, mask);
 		edma_write_array(ctlr, EDMA_EMCR, j, mask);
 		/* Clear any SER */
 		edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
@@ -1344,7 +1383,6 @@ static int __init edma_probe(struct plat
 	const s8		(*queue_tc_mapping)[2];
 	int			i, j, found = 0;
 	int			status = -1;
-	const s8		*noevent;
 	int			irq[EDMA_MAX_CC] = {0, 0};
 	int			err_irq[EDMA_MAX_CC] = {0, 0};
 	struct resource		*r[EDMA_MAX_CC] = {NULL};
@@ -1407,11 +1445,9 @@ static int __init edma_probe(struct plat
 			memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i),
 					&dummy_paramset, PARM_SIZE);
 
-		noevent = info[j].noevent;
-		if (noevent) {
-			while (*noevent != -1)
-				set_bit(*noevent++, edma_info[j]->edma_noevent);
-		}
+		/* Mark all channels as unused */
+		memset(edma_info[j]->edma_unused, 0xff,
+			sizeof(edma_info[j]->edma_unused));
 
 		sprintf(irq_name, "edma%d", j);
 		irq[j] = platform_get_irq_byname(pdev, irq_name);
@@ -1467,6 +1503,7 @@ static int __init edma_probe(struct plat
 			edma_write_array2(j, EDMA_DRAE, i, 1, 0x0);
 			edma_write_array(j, EDMA_QRAE, i, 0x0);
 		}
+		arch_num_cc++;
 	}
 
 	if (tc_errs_handled) {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/cdce949.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/cdce949.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/cdce949.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/cdce949.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,19 @@
+/*
+ * TI CDCE949 off-chip clock synthesizer support
+ *
+ * 2009 (C) Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+#ifndef _MACH_DAVINCI_CDCE949_H
+#define _MACH_DAVINCI_CDCE949_H
+
+#include <linux/clk.h>
+
+#include <mach/clock.h>
+
+int cdce_set_rate(struct clk *clk, unsigned long rate);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/common.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/common.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/common.h	2010-05-16 17:17:36.000000000 -0400
@@ -43,7 +43,7 @@ struct davinci_soc_info {
 	void __iomem			*jtag_id_base;
 	struct davinci_id		*ids;
 	unsigned long			ids_num;
-	struct davinci_clk		*cpu_clks;
+	struct clk_lookup		*cpu_clks;
 	void __iomem			**psc_bases;
 	unsigned long			psc_bases_num;
 	void __iomem			*pinmux_base;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/cpuidle.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/cpuidle.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/cpuidle.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/cpuidle.h	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 
 struct davinci_cpuidle_config {
 	u32 ddr2_pdown;
+	void __iomem *ddr2_ctlr_base;
 };
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/da8xx.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/da8xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/da8xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/da8xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,7 @@
  *
  * Author: Mark A. Greer <mgreer@mvista.com>
  *
- * 2007, 2009 (c) MontaVista Software, Inc. This file is licensed under
+ * 2007, 2009-2010 (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.
@@ -13,15 +13,19 @@
 
 #include <video/da8xx-fb.h>
 
+#include <linux/platform_device.h>
+#include <linux/davinci_emac.h>
+
 #include <mach/serial.h>
 #include <mach/edma.h>
 #include <mach/i2c.h>
-#include <mach/emac.h>
 #include <mach/asp.h>
 #include <mach/mmc.h>
 #include <mach/usb.h>
+#include <mach/pm.h>
 
-extern void __iomem *da8xx_syscfg_base;
+extern void __iomem *da8xx_syscfg0_base;
+extern void __iomem *da8xx_syscfg1_base;
 
 /*
  * The cp_intc interrupt controller for the da8xx isn't in the same
@@ -34,13 +38,17 @@ extern void __iomem *da8xx_syscfg_base;
 #define DA8XX_CP_INTC_SIZE	SZ_8K
 #define DA8XX_CP_INTC_VIRT	(IO_VIRT - DA8XX_CP_INTC_SIZE - SZ_4K)
 
-#define DA8XX_SYSCFG_BASE	(IO_PHYS + 0x14000)
-#define DA8XX_SYSCFG_VIRT(x)	(da8xx_syscfg_base + (x))
+#define DA8XX_SYSCFG0_BASE	(IO_PHYS + 0x14000)
+#define DA8XX_SYSCFG0_VIRT(x)	(da8xx_syscfg0_base + (x))
 #define DA8XX_JTAG_ID_REG	0x18
 #define DA8XX_CFGCHIP0_REG	0x17c
 #define DA8XX_CFGCHIP2_REG	0x184
 #define DA8XX_CFGCHIP3_REG	0x188
 
+#define DA8XX_SYSCFG1_BASE	(IO_PHYS + 0x22C000)
+#define DA8XX_SYSCFG1_VIRT(x)	(da8xx_syscfg1_base + (x))
+#define DA8XX_DEEPSLEEP_REG	0x8
+
 #define DA8XX_PSC0_BASE		0x01c10000
 #define DA8XX_PLL0_BASE		0x01c11000
 #define DA8XX_TIMER64P0_BASE	0x01c20000
@@ -48,11 +56,13 @@ extern void __iomem *da8xx_syscfg_base;
 #define DA8XX_GPIO_BASE		0x01e26000
 #define DA8XX_PSC1_BASE		0x01e27000
 #define DA8XX_LCD_CNTRL_BASE	0x01e13000
+#define DA8XX_PLL1_BASE		0x01e1a000
 #define DA8XX_MMCSD0_BASE	0x01c40000
 #define DA8XX_AEMIF_CS2_BASE	0x60000000
 #define DA8XX_AEMIF_CS3_BASE	0x62000000
 #define DA8XX_AEMIF_CTL_BASE	0x68000000
 #define DA8XX_DDR2_CTL_BASE	0xb0000000
+#define DA8XX_ARM_RAM_BASE	0xffff0000
 
 #define PINMUX0			0x00
 #define PINMUX1			0x04
@@ -90,6 +100,8 @@ void __init da8xx_register_mcasp(int id,
 int da8xx_register_rtc(void);
 int da850_register_cpufreq(void);
 int da8xx_register_cpuidle(void);
+void __iomem * __init da8xx_get_mem_ctlr(void);
+int da850_register_pm(struct platform_device *pdev);
 
 extern struct platform_device da8xx_serial_device;
 extern struct emac_platform_data da8xx_emac_pdata;
@@ -134,6 +146,10 @@ extern const short da850_mmcsd0_pins[];
 extern const short da850_nand_pins[];
 extern const short da850_nor_pins[];
 
+#ifdef CONFIG_DAVINCI_MUX
 int da8xx_pinmux_setup(const short pins[]);
+#else
+static inline int da8xx_pinmux_setup(const short pins[]) { return 0; }
+#endif
 
 #endif /* __ASM_ARCH_DAVINCI_DA8XX_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,7 @@
 #include <linux/serial_reg.h>
 #define UART_SHIFT	2
 
-		.macro addruart, rx
+		.macro addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #0x01000000	@ physical base address
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/dm365.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/dm365.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/dm365.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/dm365.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,10 +14,11 @@
 #define __ASM_ARCH_DM665_H
 
 #include <linux/platform_device.h>
+#include <linux/davinci_emac.h>
 #include <mach/hardware.h>
-#include <mach/emac.h>
 #include <mach/asp.h>
 #include <mach/keyscan.h>
+#include <media/davinci/vpfe_capture.h>
 
 #define DM365_EMAC_BASE			(0x01D07000)
 #define DM365_EMAC_CNTRL_OFFSET		(0x0000)
@@ -31,9 +32,17 @@
 
 #define DM365_RTC_BASE			(0x01C69000)
 
+#define DAVINCI_DM365_VC_BASE		(0x01D0C000)
+#define DAVINCI_DMA_VC_TX		2
+#define DAVINCI_DMA_VC_RX		3
+
 void __init dm365_init(void);
 void __init dm365_init_asp(struct snd_platform_data *pdata);
+void __init dm365_init_vc(struct snd_platform_data *pdata);
 void __init dm365_init_ks(struct davinci_ks_platform_data *pdata);
 void __init dm365_init_rtc(void);
+void dm365_init_spi0(unsigned chipselect_mask,
+			struct spi_board_info *info, unsigned len);
 
+void dm365_set_vpfe_config(struct vpfe_config *cfg);
 #endif /* __ASM_ARCH_DM365_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/dm644x.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/dm644x.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/dm644x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/dm644x.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,8 +22,8 @@
 #ifndef __ASM_ARCH_DM644X_H
 #define __ASM_ARCH_DM644X_H
 
+#include <linux/davinci_emac.h>
 #include <mach/hardware.h>
-#include <mach/emac.h>
 #include <mach/asp.h>
 #include <media/davinci/vpfe_capture.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/dm646x.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/dm646x.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/dm646x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/dm646x.h	2010-05-16 17:17:36.000000000 -0400
@@ -12,10 +12,11 @@
 #define __ASM_ARCH_DM646X_H
 
 #include <mach/hardware.h>
-#include <mach/emac.h>
 #include <mach/asp.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <linux/clk.h>
+#include <linux/davinci_emac.h>
 
 #define DM646X_EMAC_BASE		(0x01C80000)
 #define DM646X_EMAC_CNTRL_OFFSET	(0x0000)
@@ -30,6 +31,7 @@ void __init dm646x_init(void);
 void __init dm646x_init_ide(void);
 void __init dm646x_init_mcasp0(struct snd_platform_data *pdata);
 void __init dm646x_init_mcasp1(struct snd_platform_data *pdata);
+void __init dm646x_board_setup_refclk(struct clk *clk);
 
 void dm646x_video_init(void);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/edma.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/edma.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/edma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/edma.h	2010-05-16 17:17:36.000000000 -0400
@@ -280,8 +280,6 @@ struct edma_soc_info {
 	unsigned	n_cc;
 	enum dma_event_q	default_queue;
 
-	/* list of channels with no even trigger; terminated by "-1" */
-	const s8	*noevent;
 	const s8	(*queue_tc_mapping)[2];
 	const s8	(*queue_priority_mapping)[2];
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/emac.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/emac.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/emac.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/emac.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,36 +0,0 @@
-/*
- * TI DaVinci EMAC platform support
- *
- * 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.
- */
-#ifndef _MACH_DAVINCI_EMAC_H
-#define _MACH_DAVINCI_EMAC_H
-
-#include <linux/if_ether.h>
-#include <linux/memory.h>
-
-struct emac_platform_data {
-	char mac_addr[ETH_ALEN];
-	u32 ctrl_reg_offset;
-	u32 ctrl_mod_reg_offset;
-	u32 ctrl_ram_offset;
-	u32 mdio_reg_offset;
-	u32 ctrl_ram_size;
-	u32 phy_mask;
-	u32 mdio_max_freq;
-	u8 rmii_en;
-	u8 version;
-};
-
-enum {
-	EMAC_VERSION_1,	/* DM644x */
-	EMAC_VERSION_2,	/* DM646x */
-};
-
-void davinci_get_mac_addr(struct memory_accessor *mem_acc, void *context);
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/hardware.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/hardware.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/hardware.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/hardware.h	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,7 @@
 /*
  * I/O mapping
  */
-#define IO_PHYS				0x01c00000
+#define IO_PHYS				0x01c00000UL
 #define IO_OFFSET			0xfd000000 /* Virtual IO = 0xfec00000 */
 #define IO_SIZE				0x00400000
 #define IO_VIRT				(IO_PHYS + IO_OFFSET)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/i2c.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/i2c.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/i2c.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/i2c.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * DaVinci I2C controller platfrom_device info
+ * DaVinci I2C controller platform_device info
  *
  * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
  *
@@ -16,6 +16,8 @@
 struct davinci_i2c_platform_data {
 	unsigned int	bus_freq;	/* standard bus frequency (kHz) */
 	unsigned int	bus_delay;	/* post-transaction delay (usec) */
+	unsigned int    sda_pin;        /* GPIO pin ID to use for SDA */
+	unsigned int    scl_pin;        /* GPIO pin ID to use for SCL */
 };
 
 /* for board setup code */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/memory.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/memory.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/memory.h	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,11 @@
 #define PHYS_OFFSET DAVINCI_DDR_BASE
 #endif
 
+#define DDR2_SDRCR_OFFSET	0xc
+#define DDR2_SRPD_BIT		BIT(23)
+#define DDR2_MCLKSTOPEN_BIT	BIT(30)
+#define DDR2_LPMODEN_BIT	BIT(31)
+
 /*
  * Increase size of DMA-consistent memory region
  */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/mux.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/mux.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/mux.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/mux.h	2010-05-16 17:17:36.000000000 -0400
@@ -327,6 +327,8 @@ enum davinci_dm365_index {
 	/* EDMA event muxing */
 	DM365_EVT2_ASP_TX,
 	DM365_EVT3_ASP_RX,
+	DM365_EVT2_VC_TX,
+	DM365_EVT3_VC_RX,
 	DM365_EVT26_MMC0_RX,
 };
 
@@ -899,6 +901,7 @@ enum davinci_da850_index {
 	DA850_GPIO2_15,
 	DA850_GPIO4_0,
 	DA850_GPIO4_1,
+	DA850_RTC_ALARM,
 };
 
 #ifdef CONFIG_DAVINCI_MUX
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/pm.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/pm.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/pm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/pm.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,54 @@
+/*
+ * TI DaVinci platform support for power management.
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef _MACH_DAVINCI_PM_H
+#define _MACH_DAVINCI_PM_H
+
+/*
+ * Caution: Assembly code in sleep.S makes assumtion on the order
+ * of the members of this structure.
+ */
+struct davinci_pm_config {
+	void __iomem *ddr2_ctlr_base;
+	void __iomem *ddrpsc_reg_base;
+	int ddrpsc_num;
+	void __iomem *ddrpll_reg_base;
+	void __iomem *deepsleep_reg;
+	void __iomem *cpupll_reg_base;
+	/*
+	 * Note on SLEEPCOUNT:
+	 * The SLEEPCOUNT feature is mainly intended for cases in which
+	 * the internal oscillator is used. The internal oscillator is
+	 * fully disabled in deep sleep mode.  When you exist deep sleep
+	 * mode, the oscillator will be turned on and will generate very
+	 * small oscillations which will not be detected by the deep sleep
+	 * counter.  Eventually those oscillations will grow to an amplitude
+	 * large enough to start incrementing the deep sleep counter.
+	 * In this case recommendation from hardware engineers is that the
+	 * SLEEPCOUNT be set to 4096.  This means that 4096 valid clock cycles
+	 * must be detected before the clock is passed to the rest of the
+	 * system.
+	 * In the case that the internal oscillator is not used and the
+	 * clock is generated externally, the SLEEPCOUNT value can be very
+	 * small since the clock input is assumed to be stable before SoC
+	 * is taken out of deepsleep mode.  A value of 128 would be more than
+	 * adequate.
+	 */
+	int sleepcount;
+};
+
+extern unsigned int davinci_cpu_suspend_sz;
+extern void davinci_cpu_suspend(struct davinci_pm_config *);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/psc.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/psc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/psc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/psc.h	2010-05-16 17:17:36.000000000 -0400
@@ -180,8 +180,23 @@
 #define DA8XX_LPSC1_CR_P3_SS		26
 #define DA8XX_LPSC1_L3_CBA_RAM		31
 
+/* PSC register offsets */
+#define EPCPR		0x070
+#define PTCMD		0x120
+#define PTSTAT		0x128
+#define PDSTAT		0x200
+#define PDCTL1		0x304
+#define MDSTAT		0x800
+#define MDCTL		0xA00
+
+#define MDSTAT_STATE_MASK 0x1f
+
+#ifndef __ASSEMBLER__
+
 extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
 extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
 		unsigned int id, char enable);
 
+#endif
+
 #endif /* __ASM_ARCH_PSC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/spi.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/spi.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/spi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/spi.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,44 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef __ARCH_ARM_DAVINCI_SPI_H
+#define __ARCH_ARM_DAVINCI_SPI_H
+
+enum {
+	SPI_VERSION_1, /* For DM355/DM365/DM6467 */
+	SPI_VERSION_2, /* For DA8xx */
+};
+
+struct davinci_spi_platform_data {
+	u8	version;
+	u8	num_chipselect;
+	u8	wdelay;
+	u8	odd_parity;
+	u8	parity_enable;
+	u8	wait_enable;
+	u8	timer_disable;
+	u8	clk_internal;
+	u8	cs_hold;
+	u8	intr_level;
+	u8	poll_mode;
+	u8	use_dma;
+	u8	c2tdelay;
+	u8	t2cdelay;
+};
+
+#endif	/* __ARCH_ARM_DAVINCI_SPI_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/timex.h linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/timex.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/timex.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/include/mach/timex.h	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,12 @@
 #ifndef __ASM_ARCH_TIMEX_H
 #define __ASM_ARCH_TIMEX_H
 
-/* The source frequency for the timers is the 27MHz clock */
+/*
+ * Alert: Not all timers of the DaVinci family run at a frequency of 27MHz,
+ * but we should be fine as long as CLOCK_TICK_RATE or LATCH (see include/
+ * linux/jiffies.h) are not used directly in code. Currently none of the
+ * code relevant to DaVinci platform depends on these values directly.
+ */
 #define CLOCK_TICK_RATE 27000000
 
 #endif /* __ASM_ARCH_TIMEX_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/io.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/io.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/io.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,7 @@ void __iomem *davinci_ioremap(unsigned l
 	if (BETWEEN(p, IO_PHYS, IO_SIZE))
 		return XLATE(p, IO_PHYS, IO_VIRT);
 
-	return __arm_ioremap(p, size, type);
+	return __arm_ioremap_caller(p, size, type, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(davinci_ioremap);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -91,10 +91,14 @@ config MACH_DAVINCI_DM6467_EVM
 	bool "TI DM6467 EVM"
 	default ARCH_DAVINCI_DM646x
 	depends on ARCH_DAVINCI_DM646x
+	select MACH_DAVINCI_DM6467TEVM
 	help
 	  Configure this option to specify the whether the board used
 	  for development is a DM6467 EVM
 
+config MACH_DAVINCI_DM6467TEVM
+	bool
+
 config MACH_DAVINCI_DM365_EVM
 	bool "TI DM365 EVM"
 	default ARCH_DAVINCI_DM365
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,7 @@ obj-$(CONFIG_MACH_SFFSDR)		+= board-sffs
 obj-$(CONFIG_MACH_NEUROS_OSD2)		+= board-neuros-osd2.o
 obj-$(CONFIG_MACH_DAVINCI_DM355_EVM)	+= board-dm355-evm.o
 obj-$(CONFIG_MACH_DM355_LEOPARD)	+= board-dm355-leopard.o
-obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM)	+= board-dm646x-evm.o
+obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM)	+= board-dm646x-evm.o cdce949.o
 obj-$(CONFIG_MACH_DAVINCI_DM365_EVM)	+= board-dm365-evm.o
 obj-$(CONFIG_MACH_DAVINCI_DA830_EVM)	+= board-da830-evm.o
 obj-$(CONFIG_MACH_DAVINCI_DA850_EVM)	+= board-da850-evm.o
@@ -34,3 +34,4 @@ obj-$(CONFIG_MACH_DAVINCI_DA850_EVM)	+=
 # Power Management
 obj-$(CONFIG_CPU_FREQ)			+= cpufreq.o
 obj-$(CONFIG_CPU_IDLE)			+= cpuidle.o
+obj-$(CONFIG_SUSPEND)			+= pm.o sleep.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/pm.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/pm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/pm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,158 @@
+/*
+ * DaVinci Power Management Routines
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/pm.h>
+#include <linux/suspend.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+
+#include <asm/cacheflush.h>
+#include <asm/delay.h>
+
+#include <mach/da8xx.h>
+#include <mach/sram.h>
+#include <mach/pm.h>
+
+#include "clock.h"
+
+#define DEEPSLEEP_SLEEPCOUNT_MASK	0xFFFF
+
+static void (*davinci_sram_suspend) (struct davinci_pm_config *);
+static struct davinci_pm_config *pdata;
+
+static void davinci_sram_push(void *dest, void *src, unsigned int size)
+{
+	memcpy(dest, src, size);
+	flush_icache_range((unsigned long)dest, (unsigned long)(dest + size));
+}
+
+static void davinci_pm_suspend(void)
+{
+	unsigned val;
+
+	if (pdata->cpupll_reg_base != pdata->ddrpll_reg_base) {
+
+		/* Switch CPU PLL to bypass mode */
+		val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+		val &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
+		__raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+
+		udelay(PLL_BYPASS_TIME);
+
+		/* Powerdown CPU PLL */
+		val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+		val |= PLLCTL_PLLPWRDN;
+		__raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+	}
+
+	/* Configure sleep count in deep sleep register */
+	val = __raw_readl(pdata->deepsleep_reg);
+	val &= ~DEEPSLEEP_SLEEPCOUNT_MASK,
+	val |= pdata->sleepcount;
+	__raw_writel(val, pdata->deepsleep_reg);
+
+	/* System goes to sleep in this call */
+	davinci_sram_suspend(pdata);
+
+	if (pdata->cpupll_reg_base != pdata->ddrpll_reg_base) {
+
+		/* put CPU PLL in reset */
+		val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+		val &= ~PLLCTL_PLLRST;
+		__raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+
+		/* put CPU PLL in power down */
+		val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+		val &= ~PLLCTL_PLLPWRDN;
+		__raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+
+		/* wait for CPU PLL reset */
+		udelay(PLL_RESET_TIME);
+
+		/* bring CPU PLL out of reset */
+		val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+		val |= PLLCTL_PLLRST;
+		__raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+
+		/* Wait for CPU PLL to lock */
+		udelay(PLL_LOCK_TIME);
+
+		/* Remove CPU PLL from bypass mode */
+		val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+		val &= ~PLLCTL_PLLENSRC;
+		val |= PLLCTL_PLLEN;
+		__raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+	}
+}
+
+static int davinci_pm_enter(suspend_state_t state)
+{
+	int ret = 0;
+
+	switch (state) {
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		davinci_pm_suspend();
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static struct platform_suspend_ops davinci_pm_ops = {
+	.enter		= davinci_pm_enter,
+	.valid		= suspend_valid_only_mem,
+};
+
+static int __init davinci_pm_probe(struct platform_device *pdev)
+{
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_err(&pdev->dev, "cannot get platform data\n");
+		return -ENOENT;
+	}
+
+	davinci_sram_suspend = sram_alloc(davinci_cpu_suspend_sz, NULL);
+	if (!davinci_sram_suspend) {
+		dev_err(&pdev->dev, "cannot allocate SRAM memory\n");
+		return -ENOMEM;
+	}
+
+	davinci_sram_push(davinci_sram_suspend, davinci_cpu_suspend,
+						davinci_cpu_suspend_sz);
+
+	suspend_set_ops(&davinci_pm_ops);
+
+	return 0;
+}
+
+static int __exit davinci_pm_remove(struct platform_device *pdev)
+{
+	sram_free(davinci_sram_suspend, davinci_cpu_suspend_sz);
+	return 0;
+}
+
+static struct platform_driver davinci_pm_driver = {
+	.driver = {
+		.name	 = "pm-davinci",
+		.owner	 = THIS_MODULE,
+	},
+	.remove = __exit_p(davinci_pm_remove),
+};
+
+static int __init davinci_pm_init(void)
+{
+	return platform_driver_probe(&davinci_pm_driver, davinci_pm_probe);
+}
+late_initcall(davinci_pm_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/psc.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/psc.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/psc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/psc.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,17 +25,6 @@
 #include <mach/cputype.h>
 #include <mach/psc.h>
 
-/* PSC register offsets */
-#define EPCPR		0x070
-#define PTCMD		0x120
-#define PTSTAT		0x128
-#define PDSTAT		0x200
-#define PDCTL1		0x304
-#define MDSTAT		0x800
-#define MDCTL		0xA00
-
-#define MDSTAT_STATE_MASK 0x1f
-
 /* Return nonzero iff the domain's clock is active */
 int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/sleep.S linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/sleep.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/sleep.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/sleep.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,224 @@
+/*
+ * (C) Copyright 2009, Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * 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
+ */
+
+/* replicated define because linux/bitops.h cannot be included in assembly */
+#define BIT(nr)			(1 << (nr))
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/psc.h>
+#include <mach/memory.h>
+
+#include "clock.h"
+
+/* Arbitrary, hardware currently does not update PHYRDY correctly */
+#define PHYRDY_CYCLES		0x1000
+
+/* Assume 25 MHz speed for the cycle conversions since PLLs are bypassed */
+#define PLL_BYPASS_CYCLES	(PLL_BYPASS_TIME * 25)
+#define PLL_RESET_CYCLES	(PLL_RESET_TIME	* 25)
+#define PLL_LOCK_CYCLES		(PLL_LOCK_TIME * 25)
+
+#define DEEPSLEEP_SLEEPENABLE_BIT	BIT(31)
+
+	.text
+/*
+ * Move DaVinci into deep sleep state
+ *
+ * Note: This code is copied to internal SRAM by PM code. When the DaVinci
+ *	 wakes up it continues execution at the point it went to sleep.
+ * Register Usage:
+ * 	r0: contains virtual base for DDR2 controller
+ * 	r1: contains virtual base for DDR2 Power and Sleep controller (PSC)
+ * 	r2: contains PSC number for DDR2
+ * 	r3: contains virtual base DDR2 PLL controller
+ * 	r4: contains virtual address of the DEEPSLEEP register
+ */
+ENTRY(davinci_cpu_suspend)
+	stmfd	sp!, {r0-r12, lr}		@ save registers on stack
+
+	ldr 	ip, CACHE_FLUSH
+	blx	ip
+
+	ldmia	r0, {r0-r4}
+
+	/*
+	 * Switch DDR to self-refresh mode.
+	 */
+
+	/* calculate SDRCR address */
+	ldr	ip, [r0, #DDR2_SDRCR_OFFSET]
+	bic	ip, ip, #DDR2_SRPD_BIT
+	orr	ip, ip, #DDR2_LPMODEN_BIT
+	str	ip, [r0, #DDR2_SDRCR_OFFSET]
+
+	ldr	ip, [r0, #DDR2_SDRCR_OFFSET]
+	orr	ip, ip, #DDR2_MCLKSTOPEN_BIT
+	str	ip, [r0, #DDR2_SDRCR_OFFSET]
+
+       mov	ip, #PHYRDY_CYCLES
+1:     subs	ip, ip, #0x1
+       bne	1b
+
+       /* Disable DDR2 LPSC */
+	mov	r7, r0
+	mov	r0, #0x2
+	bl davinci_ddr_psc_config
+	mov	r0, r7
+
+	/* Disable clock to DDR PHY */
+	ldr	ip, [r3, #PLLDIV1]
+	bic	ip, ip, #PLLDIV_EN
+	str	ip, [r3, #PLLDIV1]
+
+	/* Put the DDR PLL in bypass and power down */
+	ldr	ip, [r3, #PLLCTL]
+	bic	ip, ip, #PLLCTL_PLLENSRC
+	bic	ip, ip, #PLLCTL_PLLEN
+	str	ip, [r3, #PLLCTL]
+
+	/* Wait for PLL to switch to bypass */
+       mov	ip, #PLL_BYPASS_CYCLES
+2:     subs	ip, ip, #0x1
+       bne	2b
+
+       /* Power down the PLL */
+	ldr	ip, [r3, #PLLCTL]
+	orr	ip, ip, #PLLCTL_PLLPWRDN
+	str	ip, [r3, #PLLCTL]
+
+	/* Go to deep sleep */
+	ldr	ip, [r4]
+	orr	ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
+	/* System goes to sleep beyond after this instruction */
+	str	ip, [r4]
+
+	/* Wake up from sleep */
+
+	/* Clear sleep enable */
+	ldr	ip, [r4]
+	bic	ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
+	str	ip, [r4]
+
+	/* initialize the DDR PLL controller */
+
+	/* Put PLL in reset */
+	ldr	ip, [r3, #PLLCTL]
+	bic	ip, ip, #PLLCTL_PLLRST
+	str	ip, [r3, #PLLCTL]
+
+	/* Clear PLL power down */
+	ldr	ip, [r3, #PLLCTL]
+	bic	ip, ip, #PLLCTL_PLLPWRDN
+	str	ip, [r3, #PLLCTL]
+
+       mov	ip, #PLL_RESET_CYCLES
+3:     subs	ip, ip, #0x1
+       bne	3b
+
+       /* Bring PLL out of reset */
+	ldr	ip, [r3, #PLLCTL]
+	orr	ip, ip, #PLLCTL_PLLRST
+	str	ip, [r3, #PLLCTL]
+
+	/* Wait for PLL to lock (assume prediv = 1, 25MHz OSCIN) */
+       mov	ip, #PLL_LOCK_CYCLES
+4:     subs	ip, ip, #0x1
+       bne	4b
+
+       /* Remove PLL from bypass mode */
+	ldr	ip, [r3, #PLLCTL]
+	bic	ip, ip, #PLLCTL_PLLENSRC
+	orr	ip, ip, #PLLCTL_PLLEN
+	str	ip, [r3, #PLLCTL]
+
+	/* Start 2x clock to DDR2 */
+
+	ldr	ip, [r3, #PLLDIV1]
+	orr	ip, ip, #PLLDIV_EN
+	str	ip, [r3, #PLLDIV1]
+
+	/* Enable VCLK */
+
+       /* Enable DDR2 LPSC */
+	mov	r7, r0
+	mov	r0, #0x3
+	bl davinci_ddr_psc_config
+	mov	r0, r7
+
+	/* clear  MCLKSTOPEN */
+
+	ldr	ip, [r0, #DDR2_SDRCR_OFFSET]
+	bic	ip, ip, #DDR2_MCLKSTOPEN_BIT
+	str	ip, [r0, #DDR2_SDRCR_OFFSET]
+
+	ldr	ip, [r0, #DDR2_SDRCR_OFFSET]
+	bic	ip, ip, #DDR2_LPMODEN_BIT
+	str	ip, [r0, #DDR2_SDRCR_OFFSET]
+
+	/* Restore registers and return */
+	ldmfd   sp!, {r0-r12, pc}
+
+ENDPROC(davinci_cpu_suspend)
+
+/*
+ * Disables or Enables DDR2 LPSC
+ * Register Usage:
+ * 	r0: Enable or Disable LPSC r0 = 0x3 => Enable, r0 = 0x2 => Disable LPSC
+ * 	r1: contains virtual base for DDR2 Power and Sleep controller (PSC)
+ * 	r2: contains PSC number for DDR2
+ */
+ENTRY(davinci_ddr_psc_config)
+	/* Set next state in mdctl for DDR2 */
+	mov	r6, #MDCTL
+	add	r6, r6, r2, lsl #2
+	ldr	ip, [r1, r6]
+	bic	ip, ip, #MDSTAT_STATE_MASK
+	orr	ip, ip, r0
+	str	ip, [r1, r6]
+
+	/* Enable the Power Domain Transition Command */
+	ldr	ip, [r1, #PTCMD]
+	orr	ip, ip, #0x1
+	str	ip, [r1, #PTCMD]
+
+	/* Check for Transition Complete (PTSTAT) */
+ptstat_done:
+	ldr	ip, [r1, #PTSTAT]
+	and	ip, ip, #0x1
+	cmp 	ip, #0x0
+	bne	ptstat_done
+
+	/* Check for DDR2 clock disable completion; */
+	mov	r6, #MDSTAT
+	add	r6, r6, r2, lsl #2
+ddr2clk_stop_done:
+	ldr	ip, [r1, r6]
+	and	ip, ip, #MDSTAT_STATE_MASK
+	cmp	ip, r0
+	bne	ddr2clk_stop_done
+
+	mov	pc, lr
+ENDPROC(davinci_ddr_psc_config)
+
+CACHE_FLUSH:
+	.word	arm926_flush_kern_cache_all
+
+ENTRY(davinci_cpu_suspend_sz)
+	.word	. - davinci_cpu_suspend
+ENDPROC(davinci_cpu_suspend_sz)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/time.c linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/time.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -253,8 +253,6 @@ static void __init timer_init(void)
 			irq = USING_COMPARE(t) ? dtip[i].cmp_irq : irq;
 			setup_irq(irq, &t->irqaction);
 		}
-
-		timer32_config(&timers[i]);
 	}
 }
 
@@ -331,6 +329,7 @@ static void __init davinci_timer_init(vo
 	unsigned int clocksource_id;
 	static char err[] __initdata = KERN_ERR
 		"%s: can't register clocksource!\n";
+	int i;
 
 	clockevent_id = soc_info->timer_info->clockevent_id;
 	clocksource_id = soc_info->timer_info->clocksource_id;
@@ -389,6 +388,9 @@ static void __init davinci_timer_init(vo
 
 	clockevent_davinci.cpumask = cpumask_of(0);
 	clockevents_register_device(&clockevent_davinci);
+
+	for (i=0; i< ARRAY_SIZE(timers); i++)
+		timer32_config(&timers[i]);
 }
 
 struct sys_timer davinci_timer = {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-dove/common.c linux-libre-2.6.34-gnu1/arch/arm/mach-dove/common.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-dove/common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-dove/common.c	2010-05-16 17:17:36.000000000 -0400
@@ -605,7 +605,7 @@ static struct platform_device dove_xor00
 	.dev		= {
 		.dma_mask		= &dove_xor0_dmamask,
 		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= (void *)&dove_xor00_data,
+		.platform_data		= &dove_xor00_data,
 	},
 };
 
@@ -631,7 +631,7 @@ static struct platform_device dove_xor01
 	.dev		= {
 		.dma_mask		= &dove_xor0_dmamask,
 		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= (void *)&dove_xor01_data,
+		.platform_data		= &dove_xor01_data,
 	},
 };
 
@@ -704,7 +704,7 @@ static struct platform_device dove_xor10
 	.dev		= {
 		.dma_mask		= &dove_xor1_dmamask,
 		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= (void *)&dove_xor10_data,
+		.platform_data		= &dove_xor10_data,
 	},
 };
 
@@ -730,7 +730,7 @@ static struct platform_device dove_xor11
 	.dev		= {
 		.dma_mask		= &dove_xor1_dmamask,
 		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= (void *)&dove_xor11_data,
+		.platform_data		= &dove_xor11_data,
 	},
 };
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-dove/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-dove/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,7 @@
 
 #include <mach/bridge-regs.h>
 
-	.macro	addruart,rx
+	.macro	addruart, rx, tmp
 	mrc	p15, 0, \rx, c1, c0
 	tst	\rx, #1					@ MMU enabled?
 	ldreq	\rx, =DOVE_SB_REGS_PHYS_BASE
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-dove/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-dove/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,4 +2,4 @@
  * arch/arm/mach-dove/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END	0xfd800000
+#define VMALLOC_END	0xfd800000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ebsa110/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-ebsa110/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ebsa110/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ebsa110/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
  *
 **/
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mov	\rx, #0xf0000000
 		orr	\rx, \rx, #0x00000be0
 		.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,8 @@
  * your option) any later version.
  */
 
+#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/err.h>
@@ -445,37 +447,39 @@ static void __init ep93xx_dma_clock_init
 static int __init ep93xx_clock_init(void)
 {
 	u32 value;
-	int i;
 
-	value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1);
-	if (!(value & 0x00800000)) {			/* PLL1 bypassed?  */
+	/* Determine the bootloader configured pll1 rate */
+	value = __raw_readl(EP93XX_SYSCON_CLKSET1);
+	if (!(value & EP93XX_SYSCON_CLKSET1_NBYP1))
 		clk_pll1.rate = clk_xtali.rate;
-	} else {
+	else
 		clk_pll1.rate = calc_pll_rate(value);
-	}
+
+	/* Initialize the pll1 derived clocks */
 	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?  */
+	/* Determine the bootloader configured pll2 rate */
+	value = __raw_readl(EP93XX_SYSCON_CLKSET2);
+	if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
 		clk_pll2.rate = clk_xtali.rate;
-	} else if (value & 0x00040000) {		/* PLL2 enabled?  */
+	else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
 		clk_pll2.rate = calc_pll_rate(value);
-	} else {
+	else
 		clk_pll2.rate = 0;
-	}
+
+	/* Initialize the pll2 derived clocks */
 	clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
 
-	printk(KERN_INFO "ep93xx: PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
+	pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
 		clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
-	printk(KERN_INFO "ep93xx: FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
+	pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
 		clk_f.rate / 1000000, clk_h.rate / 1000000,
 		clk_p.rate / 1000000);
 
-	for (i = 0; i < ARRAY_SIZE(clocks); i++)
-		clkdev_add(&clocks[i]);
+	clkdev_add_table(clocks, ARRAY_SIZE(clocks));
 	return 0;
 }
 arch_initcall(ep93xx_clock_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/core.c linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/core.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,12 +14,15 @@
  * your option) any later version.
  */
 
+#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
 #include <linux/timex.h>
+#include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/leds.h>
@@ -35,7 +38,6 @@
 
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
-#include <asm/mach/irq.h>
 
 #include <asm/hardware/vic.h>
 
@@ -82,13 +84,40 @@ void __init ep93xx_map_io(void)
  * to use this timer for something else.  We also use timer 4 for keeping
  * track of lost jiffies.
  */
-static unsigned int last_jiffy_time;
+#define EP93XX_TIMER_REG(x)		(EP93XX_TIMER_BASE + (x))
+#define EP93XX_TIMER1_LOAD		EP93XX_TIMER_REG(0x00)
+#define EP93XX_TIMER1_VALUE		EP93XX_TIMER_REG(0x04)
+#define EP93XX_TIMER1_CONTROL		EP93XX_TIMER_REG(0x08)
+#define EP93XX_TIMER123_CONTROL_ENABLE	(1 << 7)
+#define EP93XX_TIMER123_CONTROL_MODE	(1 << 6)
+#define EP93XX_TIMER123_CONTROL_CLKSEL	(1 << 3)
+#define EP93XX_TIMER1_CLEAR		EP93XX_TIMER_REG(0x0c)
+#define EP93XX_TIMER2_LOAD		EP93XX_TIMER_REG(0x20)
+#define EP93XX_TIMER2_VALUE		EP93XX_TIMER_REG(0x24)
+#define EP93XX_TIMER2_CONTROL		EP93XX_TIMER_REG(0x28)
+#define EP93XX_TIMER2_CLEAR		EP93XX_TIMER_REG(0x2c)
+#define EP93XX_TIMER4_VALUE_LOW		EP93XX_TIMER_REG(0x60)
+#define EP93XX_TIMER4_VALUE_HIGH	EP93XX_TIMER_REG(0x64)
+#define EP93XX_TIMER4_VALUE_HIGH_ENABLE	(1 << 8)
+#define EP93XX_TIMER3_LOAD		EP93XX_TIMER_REG(0x80)
+#define EP93XX_TIMER3_VALUE		EP93XX_TIMER_REG(0x84)
+#define EP93XX_TIMER3_CONTROL		EP93XX_TIMER_REG(0x88)
+#define EP93XX_TIMER3_CLEAR		EP93XX_TIMER_REG(0x8c)
+
+#define EP93XX_TIMER123_CLOCK		508469
+#define EP93XX_TIMER4_CLOCK		983040
 
+#define TIMER1_RELOAD			((EP93XX_TIMER123_CLOCK / HZ) - 1)
 #define TIMER4_TICKS_PER_JIFFY		DIV_ROUND_CLOSEST(CLOCK_TICK_RATE, HZ)
 
+static unsigned int last_jiffy_time;
+
 static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
 {
+	/* Writing any value clears the timer interrupt */
 	__raw_writel(1, EP93XX_TIMER1_CLEAR);
+
+	/* Recover lost jiffies */
 	while ((signed long)
 		(__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time)
 						>= TIMER4_TICKS_PER_JIFFY) {
@@ -107,13 +136,18 @@ static struct irqaction ep93xx_timer_irq
 
 static void __init ep93xx_timer_init(void)
 {
+	u32 tmode = EP93XX_TIMER123_CONTROL_MODE |
+		    EP93XX_TIMER123_CONTROL_CLKSEL;
+
 	/* Enable periodic HZ timer.  */
-	__raw_writel(0x48, EP93XX_TIMER1_CONTROL);
-	__raw_writel((508469 / HZ) - 1, EP93XX_TIMER1_LOAD);
-	__raw_writel(0xc8, EP93XX_TIMER1_CONTROL);
+	__raw_writel(tmode, EP93XX_TIMER1_CONTROL);
+	__raw_writel(TIMER1_RELOAD, EP93XX_TIMER1_LOAD);
+	__raw_writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE,
+			EP93XX_TIMER1_CONTROL);
 
 	/* Enable lost jiffy timer.  */
-	__raw_writel(0x100, EP93XX_TIMER4_VALUE_HIGH);
+	__raw_writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE,
+			EP93XX_TIMER4_VALUE_HIGH);
 
 	setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq);
 }
@@ -135,237 +169,16 @@ struct sys_timer ep93xx_timer = {
 
 
 /*************************************************************************
- * GPIO handling for EP93xx
- *************************************************************************/
-static unsigned char gpio_int_unmasked[3];
-static unsigned char gpio_int_enabled[3];
-static unsigned char gpio_int_type1[3];
-static unsigned char gpio_int_type2[3];
-static unsigned char gpio_int_debounce[3];
-
-/* Port ordering is: A B F */
-static const u8 int_type1_register_offset[3]	= { 0x90, 0xac, 0x4c };
-static const u8 int_type2_register_offset[3]	= { 0x94, 0xb0, 0x50 };
-static const u8 eoi_register_offset[3]		= { 0x98, 0xb4, 0x54 };
-static const u8 int_en_register_offset[3]	= { 0x9c, 0xb8, 0x58 };
-static const u8 int_debounce_register_offset[3]	= { 0xa8, 0xc4, 0x64 };
-
-void ep93xx_gpio_update_int_params(unsigned port)
-{
-	BUG_ON(port > 2);
-
-	__raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port]));
-
-	__raw_writeb(gpio_int_type2[port],
-		EP93XX_GPIO_REG(int_type2_register_offset[port]));
-
-	__raw_writeb(gpio_int_type1[port],
-		EP93XX_GPIO_REG(int_type1_register_offset[port]));
-
-	__raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
-		EP93XX_GPIO_REG(int_en_register_offset[port]));
-}
-
-void ep93xx_gpio_int_mask(unsigned line)
-{
-	gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
-}
-
-void ep93xx_gpio_int_debounce(unsigned int irq, int enable)
-{
-	int line = irq_to_gpio(irq);
-	int port = line >> 3;
-	int port_mask = 1 << (line & 7);
-
-	if (enable)
-		gpio_int_debounce[port] |= port_mask;
-	else
-		gpio_int_debounce[port] &= ~port_mask;
-
-	__raw_writeb(gpio_int_debounce[port],
-		EP93XX_GPIO_REG(int_debounce_register_offset[port]));
-}
-EXPORT_SYMBOL(ep93xx_gpio_int_debounce);
-
-/*************************************************************************
  * EP93xx IRQ handling
  *************************************************************************/
-static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-	unsigned char status;
-	int i;
-
-	status = __raw_readb(EP93XX_GPIO_A_INT_STATUS);
-	for (i = 0; i < 8; i++) {
-		if (status & (1 << i)) {
-			int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
-			generic_handle_irq(gpio_irq);
-		}
-	}
-
-	status = __raw_readb(EP93XX_GPIO_B_INT_STATUS);
-	for (i = 0; i < 8; i++) {
-		if (status & (1 << i)) {
-			int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
-			generic_handle_irq(gpio_irq);
-		}
-	}
-}
-
-static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-	/*
-	 * map discontiguous hw irq range to continous sw irq range:
-	 *
-	 *  IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
-	 */
-	int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
-	int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
-
-	generic_handle_irq(gpio_irq);
-}
-
-static void ep93xx_gpio_irq_ack(unsigned int irq)
-{
-	int line = irq_to_gpio(irq);
-	int port = line >> 3;
-	int port_mask = 1 << (line & 7);
-
-	if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
-		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
-		ep93xx_gpio_update_int_params(port);
-	}
-
-	__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
-}
-
-static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
-{
-	int line = irq_to_gpio(irq);
-	int port = line >> 3;
-	int port_mask = 1 << (line & 7);
-
-	if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
-		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
-
-	gpio_int_unmasked[port] &= ~port_mask;
-	ep93xx_gpio_update_int_params(port);
-
-	__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
-}
-
-static void ep93xx_gpio_irq_mask(unsigned int irq)
-{
-	int line = irq_to_gpio(irq);
-	int port = line >> 3;
-
-	gpio_int_unmasked[port] &= ~(1 << (line & 7));
-	ep93xx_gpio_update_int_params(port);
-}
-
-static void ep93xx_gpio_irq_unmask(unsigned int irq)
-{
-	int line = irq_to_gpio(irq);
-	int port = line >> 3;
-
-	gpio_int_unmasked[port] |= 1 << (line & 7);
-	ep93xx_gpio_update_int_params(port);
-}
-
-
-/*
- * gpio_int_type1 controls whether the interrupt is level (0) or
- * edge (1) triggered, while gpio_int_type2 controls whether it
- * triggers on low/falling (0) or high/rising (1).
- */
-static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
-{
-	struct irq_desc *desc = irq_desc + irq;
-	const int gpio = irq_to_gpio(irq);
-	const int port = gpio >> 3;
-	const int port_mask = 1 << (gpio & 7);
-
-	gpio_direction_input(gpio);
-
-	switch (type) {
-	case IRQ_TYPE_EDGE_RISING:
-		gpio_int_type1[port] |= port_mask;
-		gpio_int_type2[port] |= port_mask;
-		desc->handle_irq = handle_edge_irq;
-		break;
-	case IRQ_TYPE_EDGE_FALLING:
-		gpio_int_type1[port] |= port_mask;
-		gpio_int_type2[port] &= ~port_mask;
-		desc->handle_irq = handle_edge_irq;
-		break;
-	case IRQ_TYPE_LEVEL_HIGH:
-		gpio_int_type1[port] &= ~port_mask;
-		gpio_int_type2[port] |= port_mask;
-		desc->handle_irq = handle_level_irq;
-		break;
-	case IRQ_TYPE_LEVEL_LOW:
-		gpio_int_type1[port] &= ~port_mask;
-		gpio_int_type2[port] &= ~port_mask;
-		desc->handle_irq = handle_level_irq;
-		break;
-	case IRQ_TYPE_EDGE_BOTH:
-		gpio_int_type1[port] |= port_mask;
-		/* set initial polarity based on current input level */
-		if (gpio_get_value(gpio))
-			gpio_int_type2[port] &= ~port_mask; /* falling */
-		else
-			gpio_int_type2[port] |= port_mask; /* rising */
-		desc->handle_irq = handle_edge_irq;
-		break;
-	default:
-		pr_err("ep93xx: failed to set irq type %d for gpio %d\n",
-		       type, gpio);
-		return -EINVAL;
-	}
-
-	gpio_int_enabled[port] |= port_mask;
-
-	desc->status &= ~IRQ_TYPE_SENSE_MASK;
-	desc->status |= type & IRQ_TYPE_SENSE_MASK;
-
-	ep93xx_gpio_update_int_params(port);
-
-	return 0;
-}
-
-static struct irq_chip ep93xx_gpio_irq_chip = {
-	.name		= "GPIO",
-	.ack		= ep93xx_gpio_irq_ack,
-	.mask_ack	= ep93xx_gpio_irq_mask_ack,
-	.mask		= ep93xx_gpio_irq_mask,
-	.unmask		= ep93xx_gpio_irq_unmask,
-	.set_type	= ep93xx_gpio_irq_type,
-};
-
+extern void ep93xx_gpio_init_irq(void);
 
 void __init ep93xx_init_irq(void)
 {
-	int gpio_irq;
-
 	vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0);
 	vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0);
 
-	for (gpio_irq = gpio_to_irq(0);
-	     gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
-		set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip);
-		set_irq_handler(gpio_irq, handle_level_irq);
-		set_irq_flags(gpio_irq, IRQF_VALID);
-	}
-
-	set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
-	set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler);
-	set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler);
-	set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler);
-	set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler);
-	set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler);
-	set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler);
-	set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler);
-	set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler);
+	ep93xx_gpio_init_irq();
 }
 
 
@@ -572,9 +385,9 @@ void __init ep93xx_register_i2c(struct i
 	 * CMOS driver.
 	 */
 	if (data->sda_is_open_drain && data->sda_pin != EP93XX_GPIO_LINE_EEDAT)
-		pr_warning("ep93xx: sda != EEDAT, open drain has no effect\n");
+		pr_warning("sda != EEDAT, open drain has no effect\n");
 	if (data->scl_is_open_drain && data->scl_pin != EP93XX_GPIO_LINE_EECLK)
-		pr_warning("ep93xx: scl != EECLK, open drain has no effect\n");
+		pr_warning("scl != EECLK, open drain has no effect\n");
 
 	__raw_writel((data->sda_is_open_drain << 1) |
 		     (data->scl_is_open_drain << 0),
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/dma-m2p.c linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/dma-m2p.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/dma-m2p.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/dma-m2p.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,8 @@
  * with this implementation.
  */
 
+#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/err.h>
@@ -173,7 +175,7 @@ static irqreturn_t m2p_irq(int irq, void
 
 	switch (m2p_channel_state(ch)) {
 	case STATE_IDLE:
-		pr_crit("m2p_irq: dma interrupt without a dma buffer\n");
+		pr_crit("dma interrupt without a dma buffer\n");
 		BUG();
 		break;
 
@@ -197,7 +199,7 @@ static irqreturn_t m2p_irq(int irq, void
 		break;
 
 	case STATE_NEXT:
-		pr_crit("m2p_irq: dma interrupt while next\n");
+		pr_crit("dma interrupt while next\n");
 		BUG();
 		break;
 	}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/edb93xx.c linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/edb93xx.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/edb93xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/edb93xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -118,12 +118,33 @@ static void __init edb93xx_register_i2c(
 	}
 }
 
+
+/*************************************************************************
+ * EDB93xx pwm
+ *************************************************************************/
+static void __init edb93xx_register_pwm(void)
+{
+	if (machine_is_edb9301() ||
+	    machine_is_edb9302() || machine_is_edb9302a()) {
+		/* EP9301 and EP9302 only have pwm.1 (EGPIO14) */
+		ep93xx_register_pwm(0, 1);
+	} else if (machine_is_edb9307() || machine_is_edb9307a()) {
+		/* EP9307 only has pwm.0 (PWMOUT) */
+		ep93xx_register_pwm(1, 0);
+	} else {
+		/* EP9312 and EP9315 have both */
+		ep93xx_register_pwm(1, 1);
+	}
+}
+
+
 static void __init edb93xx_init_machine(void)
 {
 	ep93xx_init_devices();
 	edb93xx_register_flash();
 	ep93xx_register_eth(&edb93xx_eth_data, 1);
 	edb93xx_register_i2c();
+	edb93xx_register_pwm();
 }
 
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/gpio.c linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/gpio.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,8 @@
  *  published by the Free Software Foundation.
  */
 
+#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/seq_file.h>
@@ -22,6 +24,235 @@
 
 #include <mach/hardware.h>
 
+/*************************************************************************
+ * Interrupt handling for EP93xx on-chip GPIOs
+ *************************************************************************/
+static unsigned char gpio_int_unmasked[3];
+static unsigned char gpio_int_enabled[3];
+static unsigned char gpio_int_type1[3];
+static unsigned char gpio_int_type2[3];
+static unsigned char gpio_int_debounce[3];
+
+/* Port ordering is: A B F */
+static const u8 int_type1_register_offset[3]	= { 0x90, 0xac, 0x4c };
+static const u8 int_type2_register_offset[3]	= { 0x94, 0xb0, 0x50 };
+static const u8 eoi_register_offset[3]		= { 0x98, 0xb4, 0x54 };
+static const u8 int_en_register_offset[3]	= { 0x9c, 0xb8, 0x58 };
+static const u8 int_debounce_register_offset[3]	= { 0xa8, 0xc4, 0x64 };
+
+static void ep93xx_gpio_update_int_params(unsigned port)
+{
+	BUG_ON(port > 2);
+
+	__raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port]));
+
+	__raw_writeb(gpio_int_type2[port],
+		EP93XX_GPIO_REG(int_type2_register_offset[port]));
+
+	__raw_writeb(gpio_int_type1[port],
+		EP93XX_GPIO_REG(int_type1_register_offset[port]));
+
+	__raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
+		EP93XX_GPIO_REG(int_en_register_offset[port]));
+}
+
+static inline void ep93xx_gpio_int_mask(unsigned line)
+{
+	gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
+}
+
+void ep93xx_gpio_int_debounce(unsigned int irq, int enable)
+{
+	int line = irq_to_gpio(irq);
+	int port = line >> 3;
+	int port_mask = 1 << (line & 7);
+
+	if (enable)
+		gpio_int_debounce[port] |= port_mask;
+	else
+		gpio_int_debounce[port] &= ~port_mask;
+
+	__raw_writeb(gpio_int_debounce[port],
+		EP93XX_GPIO_REG(int_debounce_register_offset[port]));
+}
+EXPORT_SYMBOL(ep93xx_gpio_int_debounce);
+
+static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	unsigned char status;
+	int i;
+
+	status = __raw_readb(EP93XX_GPIO_A_INT_STATUS);
+	for (i = 0; i < 8; i++) {
+		if (status & (1 << i)) {
+			int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
+			generic_handle_irq(gpio_irq);
+		}
+	}
+
+	status = __raw_readb(EP93XX_GPIO_B_INT_STATUS);
+	for (i = 0; i < 8; i++) {
+		if (status & (1 << i)) {
+			int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
+			generic_handle_irq(gpio_irq);
+		}
+	}
+}
+
+static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	/*
+	 * map discontiguous hw irq range to continous sw irq range:
+	 *
+	 *  IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
+	 */
+	int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
+	int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
+
+	generic_handle_irq(gpio_irq);
+}
+
+static void ep93xx_gpio_irq_ack(unsigned int irq)
+{
+	int line = irq_to_gpio(irq);
+	int port = line >> 3;
+	int port_mask = 1 << (line & 7);
+
+	if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
+		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
+		ep93xx_gpio_update_int_params(port);
+	}
+
+	__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
+}
+
+static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
+{
+	int line = irq_to_gpio(irq);
+	int port = line >> 3;
+	int port_mask = 1 << (line & 7);
+
+	if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
+		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
+
+	gpio_int_unmasked[port] &= ~port_mask;
+	ep93xx_gpio_update_int_params(port);
+
+	__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
+}
+
+static void ep93xx_gpio_irq_mask(unsigned int irq)
+{
+	int line = irq_to_gpio(irq);
+	int port = line >> 3;
+
+	gpio_int_unmasked[port] &= ~(1 << (line & 7));
+	ep93xx_gpio_update_int_params(port);
+}
+
+static void ep93xx_gpio_irq_unmask(unsigned int irq)
+{
+	int line = irq_to_gpio(irq);
+	int port = line >> 3;
+
+	gpio_int_unmasked[port] |= 1 << (line & 7);
+	ep93xx_gpio_update_int_params(port);
+}
+
+/*
+ * gpio_int_type1 controls whether the interrupt is level (0) or
+ * edge (1) triggered, while gpio_int_type2 controls whether it
+ * triggers on low/falling (0) or high/rising (1).
+ */
+static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
+{
+	struct irq_desc *desc = irq_desc + irq;
+	const int gpio = irq_to_gpio(irq);
+	const int port = gpio >> 3;
+	const int port_mask = 1 << (gpio & 7);
+
+	gpio_direction_input(gpio);
+
+	switch (type) {
+	case IRQ_TYPE_EDGE_RISING:
+		gpio_int_type1[port] |= port_mask;
+		gpio_int_type2[port] |= port_mask;
+		desc->handle_irq = handle_edge_irq;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		gpio_int_type1[port] |= port_mask;
+		gpio_int_type2[port] &= ~port_mask;
+		desc->handle_irq = handle_edge_irq;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		gpio_int_type1[port] &= ~port_mask;
+		gpio_int_type2[port] |= port_mask;
+		desc->handle_irq = handle_level_irq;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		gpio_int_type1[port] &= ~port_mask;
+		gpio_int_type2[port] &= ~port_mask;
+		desc->handle_irq = handle_level_irq;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		gpio_int_type1[port] |= port_mask;
+		/* set initial polarity based on current input level */
+		if (gpio_get_value(gpio))
+			gpio_int_type2[port] &= ~port_mask; /* falling */
+		else
+			gpio_int_type2[port] |= port_mask; /* rising */
+		desc->handle_irq = handle_edge_irq;
+		break;
+	default:
+		pr_err("failed to set irq type %d for gpio %d\n", type, gpio);
+		return -EINVAL;
+	}
+
+	gpio_int_enabled[port] |= port_mask;
+
+	desc->status &= ~IRQ_TYPE_SENSE_MASK;
+	desc->status |= type & IRQ_TYPE_SENSE_MASK;
+
+	ep93xx_gpio_update_int_params(port);
+
+	return 0;
+}
+
+static struct irq_chip ep93xx_gpio_irq_chip = {
+	.name		= "GPIO",
+	.ack		= ep93xx_gpio_irq_ack,
+	.mask_ack	= ep93xx_gpio_irq_mask_ack,
+	.mask		= ep93xx_gpio_irq_mask,
+	.unmask		= ep93xx_gpio_irq_unmask,
+	.set_type	= ep93xx_gpio_irq_type,
+};
+
+void __init ep93xx_gpio_init_irq(void)
+{
+	int gpio_irq;
+
+	for (gpio_irq = gpio_to_irq(0);
+	     gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
+		set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip);
+		set_irq_handler(gpio_irq, handle_level_irq);
+		set_irq_flags(gpio_irq, IRQF_VALID);
+	}
+
+	set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler);
+}
+
+
+/*************************************************************************
+ * gpiolib interface for EP93xx on-chip GPIOs
+ *************************************************************************/
 struct ep93xx_gpio_chip {
 	struct gpio_chip	chip;
 
@@ -31,10 +262,6 @@ struct ep93xx_gpio_chip {
 
 #define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip)
 
-/* From core.c */
-extern void ep93xx_gpio_int_mask(unsigned line);
-extern void ep93xx_gpio_update_int_params(unsigned port);
-
 static int ep93xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 {
 	struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
  */
 #include <mach/ep93xx-regs.h>
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1				@ MMU enabled?
 		ldreq	\rx, =EP93XX_APB_PHYS_BASE	@ Physical base
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,8 @@
 #ifndef __ASM_ARCH_EP93XX_KEYPAD_H
 #define __ASM_ARCH_EP93XX_KEYPAD_H
 
+struct matrix_keymap_data;
+
 /* flags for the ep93xx_keypad driver */
 #define EP93XX_KEYPAD_DISABLE_3_KEY	(1<<0)	/* disable 3-key reset */
 #define EP93XX_KEYPAD_DIAG_MODE		(1<<1)	/* diagnostic mode */
@@ -15,15 +17,13 @@
 
 /**
  * struct ep93xx_keypad_platform_data - platform specific device structure
- * @matrix_key_map:		array of keycodes defining the keypad matrix
- * @matrix_key_map_size:	ARRAY_SIZE(matrix_key_map)
- * @debounce:			debounce start count; terminal count is 0xff
- * @prescale:			row/column counter pre-scaler load value
- * @flags:			see above
+ * @keymap_data:	pointer to &matrix_keymap_data
+ * @debounce:		debounce start count; terminal count is 0xff
+ * @prescale:		row/column counter pre-scaler load value
+ * @flags:		see above
  */
 struct ep93xx_keypad_platform_data {
-	unsigned int	*matrix_key_map;
-	int		matrix_key_map_size;
+	struct matrix_keymap_data *keymap_data;
 	unsigned int	debounce;
 	unsigned int	prescale;
 	unsigned int	flags;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h	2010-05-16 17:17:36.000000000 -0400
@@ -92,21 +92,6 @@
 
 /* APB peripherals */
 #define EP93XX_TIMER_BASE		EP93XX_APB_IOMEM(0x00010000)
-#define EP93XX_TIMER_REG(x)		(EP93XX_TIMER_BASE + (x))
-#define EP93XX_TIMER1_LOAD		EP93XX_TIMER_REG(0x00)
-#define EP93XX_TIMER1_VALUE		EP93XX_TIMER_REG(0x04)
-#define EP93XX_TIMER1_CONTROL		EP93XX_TIMER_REG(0x08)
-#define EP93XX_TIMER1_CLEAR		EP93XX_TIMER_REG(0x0c)
-#define EP93XX_TIMER2_LOAD		EP93XX_TIMER_REG(0x20)
-#define EP93XX_TIMER2_VALUE		EP93XX_TIMER_REG(0x24)
-#define EP93XX_TIMER2_CONTROL		EP93XX_TIMER_REG(0x28)
-#define EP93XX_TIMER2_CLEAR		EP93XX_TIMER_REG(0x2c)
-#define EP93XX_TIMER4_VALUE_LOW		EP93XX_TIMER_REG(0x60)
-#define EP93XX_TIMER4_VALUE_HIGH	EP93XX_TIMER_REG(0x64)
-#define EP93XX_TIMER3_LOAD		EP93XX_TIMER_REG(0x80)
-#define EP93XX_TIMER3_VALUE		EP93XX_TIMER_REG(0x84)
-#define EP93XX_TIMER3_CONTROL		EP93XX_TIMER_REG(0x88)
-#define EP93XX_TIMER3_CLEAR		EP93XX_TIMER_REG(0x8c)
 
 #define EP93XX_I2S_BASE			EP93XX_APB_IOMEM(0x00020000)
 
@@ -167,8 +152,11 @@
 #define EP93XX_SYSCON_PWRCNT_DMA_M2P1	(1<<16)
 #define EP93XX_SYSCON_HALT		EP93XX_SYSCON_REG(0x08)
 #define EP93XX_SYSCON_STANDBY		EP93XX_SYSCON_REG(0x0c)
-#define EP93XX_SYSCON_CLOCK_SET1	EP93XX_SYSCON_REG(0x20)
-#define EP93XX_SYSCON_CLOCK_SET2	EP93XX_SYSCON_REG(0x24)
+#define EP93XX_SYSCON_CLKSET1		EP93XX_SYSCON_REG(0x20)
+#define EP93XX_SYSCON_CLKSET1_NBYP1	(1<<23)
+#define EP93XX_SYSCON_CLKSET2		EP93XX_SYSCON_REG(0x24)
+#define EP93XX_SYSCON_CLKSET2_NBYP2	(1<<19)
+#define EP93XX_SYSCON_CLKSET2_PLL2_EN	(1<<18)
 #define EP93XX_SYSCON_DEVCFG		EP93XX_SYSCON_REG(0x80)
 #define EP93XX_SYSCON_DEVCFG_SWRST	(1<<31)
 #define EP93XX_SYSCON_DEVCFG_D1ONG	(1<<30)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/ts72xx.h linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/include/mach/ts72xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/ts72xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/include/mach/ts72xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -65,6 +65,8 @@
 #define TS72XX_RTC_DATA_PHYS_BASE	0x11700000
 #define TS72XX_RTC_DATA_SIZE		0x00001000
 
+#define TS72XX_WDT_CONTROL_PHYS_BASE	0x23800000
+#define TS72XX_WDT_FEED_PHYS_BASE	0x23c00000
 
 #ifndef __ASSEMBLY__
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,4 +2,4 @@
  * arch/arm/mach-ep93xx/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END	0xfe800000
+#define VMALLOC_END	0xfe800000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -161,6 +161,20 @@ config MACH_MICRO9S
 	  Say 'Y' here if you want your kernel to support the
 	  Contec Micro9-Slim board.
 
+config MACH_SIM_ONE
+        bool "Support Simplemachines Sim.One board"
+        depends on EP93XX_SDCE0_PHYS_OFFSET
+        help
+          Say 'Y' here if you want your kernel to support the
+          Simplemachines Sim.One board.
+
+config MACH_SNAPPER_CL15
+	bool "Support Bluewater Systems Snapper CL15 Module"
+	depends on EP93XX_SDCE0_PHYS_OFFSET
+	help
+	  Say 'Y' here if you want your kernel to support the Bluewater
+	  Systems Snapper CL15 Module.
+
 config MACH_TS72XX
 	bool "Support Technologic Systems TS-72xx SBC"
 	depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -10,4 +10,6 @@ obj-$(CONFIG_MACH_ADSSPHERE)	+= adsspher
 obj-$(CONFIG_MACH_EDB93XX)	+= edb93xx.o
 obj-$(CONFIG_MACH_GESBC9312)	+= gesbc9312.o
 obj-$(CONFIG_MACH_MICRO9)	+= micro9.o
+obj-$(CONFIG_MACH_SIM_ONE)	+= simone.o
+obj-$(CONFIG_MACH_SNAPPER_CL15)	+= snappercl15.o
 obj-$(CONFIG_MACH_TS72XX)	+= ts72xx.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/micro9.c linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/micro9.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/micro9.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/micro9.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,7 @@
  *
  * Micro9-High has up to 64MB of 32-bit flash on CS1
  * Micro9-Mid has up to 64MB of either 32-bit or 16-bit flash on CS1
- * Micro9-Lite uses a seperate MTD map driver for flash support
+ * Micro9-Lite uses a separate MTD map driver for flash support
  * Micro9-Slim has up to 64MB of either 32-bit or 16-bit flash on CS1
  *************************************************************************/
 static struct physmap_flash_data micro9_flash_data;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/simone.c linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/simone.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/simone.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/simone.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,97 @@
+/*
+ * arch/arm/mach-ep93xx/simone.c
+ * Simplemachines Sim.One support.
+ *
+ * Copyright (C) 2010 Ryan Mallon <ryan@bluewatersys.com>
+ *
+ * Based on the 2.6.24.7 support:
+ *   Copyright (C) 2009 Simplemachines
+ *   MMC support by Peter Ivanov <ivanovp@gmail.com>, 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/fb.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct physmap_flash_data simone_flash_data = {
+	.width		= 2,
+};
+
+static struct resource simone_flash_resource = {
+	.start		= EP93XX_CS6_PHYS_BASE,
+	.end		= EP93XX_CS6_PHYS_BASE + SZ_8M - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device simone_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= &simone_flash_resource,
+	.dev = {
+		.platform_data	= &simone_flash_data,
+	},
+};
+
+static struct ep93xx_eth_data simone_eth_data = {
+	.phy_id		= 1,
+};
+
+static struct ep93xxfb_mach_info simone_fb_info = {
+	.num_modes	= EP93XXFB_USE_MODEDB,
+	.bpp		= 16,
+	.flags		= EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
+};
+
+static struct i2c_gpio_platform_data simone_i2c_gpio_data = {
+	.sda_pin		= EP93XX_GPIO_LINE_EEDAT,
+	.sda_is_open_drain	= 0,
+	.scl_pin		= EP93XX_GPIO_LINE_EECLK,
+	.scl_is_open_drain	= 0,
+	.udelay			= 0,
+	.timeout		= 0,
+};
+
+static struct i2c_board_info __initdata simone_i2c_board_info[] = {
+	{
+		I2C_BOARD_INFO("ds1337", 0x68),
+	},
+};
+
+static void __init simone_init_machine(void)
+{
+	ep93xx_init_devices();
+
+	platform_device_register(&simone_flash);
+	ep93xx_register_eth(&simone_eth_data, 1);
+	ep93xx_register_fb(&simone_fb_info);
+	ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
+			    ARRAY_SIZE(simone_i2c_board_info));
+}
+
+MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board")
+/* Maintainer: Ryan Mallon <ryan@bluewatersys.com> */
+	.phys_io	= EP93XX_APB_PHYS_BASE,
+	.io_pg_offst	= ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= EP93XX_SDCE0_PHYS_BASE + 0x100,
+	.map_io		= ep93xx_map_io,
+	.init_irq	= ep93xx_init_irq,
+	.timer		= &ep93xx_timer,
+	.init_machine	= simone_init_machine,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/snappercl15.c linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/snappercl15.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/snappercl15.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/snappercl15.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,172 @@
+/*
+ * arch/arm/mach-ep93xx/snappercl15.c
+ * Bluewater Systems Snapper CL15 system module
+ *
+ * Copyright (C) 2009 Bluewater Systems Ltd
+ * Author: Ryan Mallon <ryan@bluewatersys.com>
+ *
+ * NAND code adapted from driver by:
+ *   Andre Renaud <andre@bluewatersys.com>
+ *   James R. McKaskill
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/fb.h>
+
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+
+#include <mach/hardware.h>
+#include <mach/fb.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#define SNAPPERCL15_NAND_BASE	(EP93XX_CS7_PHYS_BASE + SZ_16M)
+
+#define SNAPPERCL15_NAND_WPN	(1 << 8)  /* Write protect (active low) */
+#define SNAPPERCL15_NAND_ALE	(1 << 9)  /* Address latch */
+#define SNAPPERCL15_NAND_CLE	(1 << 10) /* Command latch */
+#define SNAPPERCL15_NAND_CEN	(1 << 11) /* Chip enable (active low) */
+#define SNAPPERCL15_NAND_RDY	(1 << 14) /* Device ready */
+
+#define NAND_CTRL_ADDR(chip) 	(chip->IO_ADDR_W + 0x40)
+
+static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+				      unsigned int ctrl)
+{
+	struct nand_chip *chip = mtd->priv;
+	static u16 nand_state = SNAPPERCL15_NAND_WPN;
+	u16 set;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		set = SNAPPERCL15_NAND_CEN | SNAPPERCL15_NAND_WPN;
+
+		if (ctrl & NAND_NCE)
+			set &= ~SNAPPERCL15_NAND_CEN;
+		if (ctrl & NAND_CLE)
+			set |= SNAPPERCL15_NAND_CLE;
+		if (ctrl & NAND_ALE)
+			set |= SNAPPERCL15_NAND_ALE;
+
+		nand_state &= ~(SNAPPERCL15_NAND_CEN |
+				SNAPPERCL15_NAND_CLE |
+				SNAPPERCL15_NAND_ALE);
+		nand_state |= set;
+		__raw_writew(nand_state, NAND_CTRL_ADDR(chip));
+	}
+
+	if (cmd != NAND_CMD_NONE)
+		__raw_writew((cmd & 0xff) | nand_state, chip->IO_ADDR_W);
+}
+
+static int snappercl15_nand_dev_ready(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	return !!(__raw_readw(NAND_CTRL_ADDR(chip)) & SNAPPERCL15_NAND_RDY);
+}
+
+static const char *snappercl15_nand_part_probes[] = {"cmdlinepart", NULL};
+
+static struct mtd_partition snappercl15_nand_parts[] = {
+	{
+		.name		= "Kernel",
+		.offset		= 0,
+		.size		= SZ_2M,
+	},
+	{
+		.name		= "Filesystem",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct platform_nand_data snappercl15_nand_data = {
+	.chip = {
+		.nr_chips		= 1,
+		.part_probe_types	= snappercl15_nand_part_probes,
+		.partitions		= snappercl15_nand_parts,
+		.nr_partitions		= ARRAY_SIZE(snappercl15_nand_parts),
+		.options		= NAND_NO_AUTOINCR,
+		.chip_delay		= 25,
+	},
+	.ctrl = {
+		.dev_ready		= snappercl15_nand_dev_ready,
+		.cmd_ctrl		= snappercl15_nand_cmd_ctrl,
+	},
+};
+
+static struct resource snappercl15_nand_resource[] = {
+	{
+		.start		= SNAPPERCL15_NAND_BASE,
+		.end		= SNAPPERCL15_NAND_BASE + SZ_4K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device snappercl15_nand_device = {
+	.name			= "gen_nand",
+	.id			= -1,
+	.dev.platform_data	= &snappercl15_nand_data,
+	.resource		= snappercl15_nand_resource,
+	.num_resources		= ARRAY_SIZE(snappercl15_nand_resource),
+};
+
+static struct ep93xx_eth_data snappercl15_eth_data = {
+	.phy_id			= 1,
+};
+
+static struct i2c_gpio_platform_data snappercl15_i2c_gpio_data = {
+	.sda_pin		= EP93XX_GPIO_LINE_EEDAT,
+	.sda_is_open_drain	= 0,
+	.scl_pin		= EP93XX_GPIO_LINE_EECLK,
+	.scl_is_open_drain	= 0,
+	.udelay			= 0,
+	.timeout		= 0,
+};
+
+static struct i2c_board_info __initdata snappercl15_i2c_data[] = {
+	{
+		/* Audio codec */
+		I2C_BOARD_INFO("tlv320aic23", 0x1a),
+	},
+};
+
+static struct ep93xxfb_mach_info snappercl15_fb_info = {
+	.num_modes		= EP93XXFB_USE_MODEDB,
+	.bpp			= 16,
+};
+
+static void __init snappercl15_init_machine(void)
+{
+	ep93xx_init_devices();
+	ep93xx_register_eth(&snappercl15_eth_data, 1);
+	ep93xx_register_i2c(&snappercl15_i2c_gpio_data, snappercl15_i2c_data,
+			    ARRAY_SIZE(snappercl15_i2c_data));
+	ep93xx_register_fb(&snappercl15_fb_info);
+	platform_device_register(&snappercl15_nand_device);
+}
+
+MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15")
+	/* Maintainer: Ryan Mallon <ryan@bluewatersys.com> */
+	.phys_io	= EP93XX_APB_PHYS_BASE,
+	.io_pg_offst	= ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= EP93XX_SDCE0_PHYS_BASE + 0x100,
+	.map_io		= ep93xx_map_io,
+	.init_irq	= ep93xx_init_irq,
+	.timer 		= &ep93xx_timer,
+	.init_machine	= snappercl15_init_machine,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/ts72xx.c linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/ts72xx.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/ts72xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ep93xx/ts72xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -166,6 +166,26 @@ static struct platform_device ts72xx_rtc
 	.num_resources	= 0,
 };
 
+static struct resource ts72xx_wdt_resources[] = {
+	{
+		.start	= TS72XX_WDT_CONTROL_PHYS_BASE,
+		.end	= TS72XX_WDT_CONTROL_PHYS_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= TS72XX_WDT_FEED_PHYS_BASE,
+		.end	= TS72XX_WDT_FEED_PHYS_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ts72xx_wdt_device = {
+	.name		= "ts72xx-wdt",
+	.id		= -1,
+	.num_resources 	= ARRAY_SIZE(ts72xx_wdt_resources),
+	.resource	= ts72xx_wdt_resources,
+};
+
 static struct ep93xx_eth_data ts72xx_eth_data = {
 	.phy_id		= 1,
 };
@@ -175,6 +195,7 @@ static void __init ts72xx_init_machine(v
 	ep93xx_init_devices();
 	ts72xx_register_flash();
 	platform_device_register(&ts72xx_rtc_device);
+	platform_device_register(&ts72xx_wdt_device);
 
 	ep93xx_register_eth(&ts72xx_eth_data, 1);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/common.c linux-libre-2.6.34-gnu1/arch/arm/mach-footbridge/common.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-footbridge/common.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,12 +32,13 @@ unsigned int mem_fclk_21285 = 50000000;
 
 EXPORT_SYMBOL(mem_fclk_21285);
 
-static void __init early_fclk(char **arg)
+static int __init early_fclk(char *arg)
 {
-	mem_fclk_21285 = simple_strtoul(*arg, arg, 0);
+	mem_fclk_21285 = simple_strtoul(arg, NULL, 0);
+	return 0;
 }
 
-__early_param("mem_fclk_21285=", early_fclk);
+early_param("mem_fclk_21285", early_fclk);
 
 static int __init parse_tag_memclk(const struct tag *tag)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-footbridge/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-footbridge/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,7 @@
 
 #ifndef CONFIG_DEBUG_DC21285_PORT
 	/* For NetWinder debugging */
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #0x7c000000	@ physical
@@ -32,7 +32,7 @@
 		.equ	dc21285_high, ARMCSR_BASE & 0xff000000
 		.equ	dc21285_low,  ARMCSR_BASE & 0x00ffffff
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #0x42000000
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-gemini/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-gemini/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-gemini/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-gemini/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
  */
 #include <mach/hardware.h>
 
-	.macro	addruart,rx
+	.macro	addruart, rx, tmp
 	mrc	p15, 0, \rx, c1, c0
 	tst	\rx, #1					@ MMU enabled?
 	ldreq	\rx, =GEMINI_UART_BASE			@ physical
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-gemini/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-gemini/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-gemini/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-gemini/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,4 +7,4 @@
  * (at your option) any later version.
  */
 
-#define VMALLOC_END	0xF0000000
+#define VMALLOC_END	0xf0000000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-h720x/common.c linux-libre-2.6.34-gnu1/arch/arm/mach-h720x/common.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-h720x/common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-h720x/common.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
  */
 
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/mman.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-h720x/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-h720x/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-h720x/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-h720x/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,7 @@
 		.equ    io_virt, IO_BASE
 		.equ    io_phys, IO_START
 
-		.macro  addruart,rx
+		.macro  addruart, rx, tmp
 		mrc     p15, 0, \rx, c1, c0
 		tst     \rx, #1  	       @ MMU enabled?
 		moveq   \rx, #io_phys	       @ physical base address
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-integrator/core.c linux-libre-2.6.34-gnu1/arch/arm/mach-integrator/core.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-integrator/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-integrator/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -144,8 +144,7 @@ static int __init integrator_init(void)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(lookups); i++)
-		clkdev_add(&lookups[i]);
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 		struct amba_device *d = amba_devs[i];
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-integrator/cpu.c linux-libre-2.6.34-gnu1/arch/arm/mach-integrator/cpu.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-integrator/cpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-integrator/cpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/cpufreq.h>
-#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-integrator/impd1.c linux-libre-2.6.34-gnu1/arch/arm/mach-integrator/impd1.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-integrator/impd1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-integrator/impd1.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/clkdev.h>
 #include <mach/clkdev.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-integrator/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-integrator/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-integrator/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-integrator/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
  *
 */
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #0x16000000	@ physical base address
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-integrator/integrator_cp.c linux-libre-2.6.34-gnu1/arch/arm/mach-integrator/integrator_cp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-integrator/integrator_cp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-integrator/integrator_cp.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/list.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
@@ -21,6 +20,7 @@
 #include <linux/amba/clcd.h>
 #include <linux/amba/mmci.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 
 #include <asm/clkdev.h>
 #include <mach/clkdev.h>
@@ -558,9 +558,7 @@ static void __init intcp_init(void)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(cp_lookups); i++)
-		clkdev_add(&cp_lookups[i]);
-
+	clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups));
 	platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
 
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-integrator/pci_v3.c linux-libre-2.6.34-gnu1/arch/arm/mach-integrator/pci_v3.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-integrator/pci_v3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-integrator/pci_v3.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,6 @@
  */
 #include <linux/kernel.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-iop13xx/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-iop13xx/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-iop13xx/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-iop13xx/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
  * published by the Free Software Foundation.
  */
 
-	.macro	addruart, rx
+	.macro	addruart, rx, tmp
 	mrc	p15, 0, \rx, c1, c0
 	tst	\rx, #1			@ mmu enabled?
 	moveq	\rx, #0xff000000	@ physical
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-iop13xx/io.c linux-libre-2.6.34-gnu1/arch/arm/mach-iop13xx/io.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-iop13xx/io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-iop13xx/io.c	2010-05-16 17:17:36.000000000 -0400
@@ -61,9 +61,9 @@ void * __iomem __iop13xx_ioremap(unsigne
 			         (cookie - IOP13XX_PCIE_LOWER_MEM_RA));
 		break;
 	case IOP13XX_PBI_LOWER_MEM_RA ... IOP13XX_PBI_UPPER_MEM_RA:
-		retval = __arm_ioremap(IOP13XX_PBI_LOWER_MEM_PA +
+		retval = __arm_ioremap_caller(IOP13XX_PBI_LOWER_MEM_PA +
 				       (cookie - IOP13XX_PBI_LOWER_MEM_RA),
-				       size, mtype);
+				       size, mtype, __builtin_return_address(0));
 		break;
 	case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA:
 		retval = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(cookie);
@@ -75,7 +75,8 @@ void * __iomem __iop13xx_ioremap(unsigne
 		retval = (void *) IOP13XX_PMMR_PHYS_TO_VIRT(cookie);
 		break;
 	default:
-		retval = __arm_ioremap(cookie, size, mtype);
+		retval = __arm_ioremap_caller(cookie, size, mtype,
+				__builtin_return_address(0));
 	}
 
 	return retval;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-iop13xx/pci.c linux-libre-2.6.34-gnu1/arch/arm/mach-iop13xx/pci.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-iop13xx/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-iop13xx/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <asm/irq.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/glantank.c linux-libre-2.6.34-gnu1/arch/arm/mach-iop32x/glantank.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/glantank.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-iop32x/glantank.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/pci.h>
 #include <linux/pm.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-iop32x/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-iop32x/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
  * published by the Free Software Foundation.
  */
 
-		.macro	addruart, rx
+		.macro	addruart, rx, tmp
 		mov	\rx, #0xfe000000	@ physical as well as virtual
 		orr	\rx, \rx, #0x00800000	@ location of the UART
 		.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-iop32x/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-iop32x/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,4 +2,4 @@
  * arch/arm/mach-iop32x/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END	0xfe000000
+#define VMALLOC_END	0xfe000000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/iq31244.c linux-libre-2.6.34-gnu1/arch/arm/mach-iop32x/iq31244.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/iq31244.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-iop32x/iq31244.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@
 #include <linux/pci.h>
 #include <linux/pm.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/iq80321.c linux-libre-2.6.34-gnu1/arch/arm/mach-iop32x/iq80321.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/iq80321.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-iop32x/iq80321.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/n2100.c linux-libre-2.6.34-gnu1/arch/arm/mach-iop32x/n2100.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/n2100.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-iop32x/n2100.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/pci.h>
 #include <linux/pm.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-iop33x/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-iop33x/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-iop33x/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-iop33x/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
  * published by the Free Software Foundation.
  */
 
-		.macro	addruart, rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ mmu enabled?
 		moveq	\rx, #0xff000000	@ physical
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-iop33x/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-iop33x/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-iop33x/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-iop33x/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,4 +2,4 @@
  * arch/arm/mach-iop33x/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END	0xfe000000
+#define VMALLOC_END	0xfe000000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-iop33x/iq80331.c linux-libre-2.6.34-gnu1/arch/arm/mach-iop33x/iq80331.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-iop33x/iq80331.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-iop33x/iq80331.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-iop33x/iq80332.c linux-libre-2.6.34-gnu1/arch/arm/mach-iop33x/iq80332.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-iop33x/iq80332.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-iop33x/iq80332.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/enp2611.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/enp2611.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/enp2611.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/enp2611.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 #include <linux/bitops.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/serial.h>
 #include <linux/tty.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
  *
 */
 
-		.macro  addruart,rx
+		.macro  addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #0xc0000000	@ Physical base
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -17,4 +17,4 @@
  * The vmalloc() routines leaves a hole of 4kB between each vmalloced
  * area for the same reason. ;)
  */
-#define VMALLOC_END	    0xfb000000
+#define VMALLOC_END	    0xfb000000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/ixdp2400.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/ixdp2400.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/ixdp2400.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/ixdp2400.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/bitops.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/ixdp2800.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/ixdp2800.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/ixdp2800.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/ixdp2800.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/bitops.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/ixdp2x00.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/ixdp2x00.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/ixdp2x00.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/ixdp2x00.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/bitops.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/ixdp2x01.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/ixdp2x01.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/ixdp2x01.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/ixdp2x01.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/bitops.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/serial.h>
 #include <linux/tty.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/pci.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/pci.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp2000/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp23xx/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-ixp23xx/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp23xx/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp23xx/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,7 @@
  */
 #include <mach/ixp23xx.h>
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1				@ mmu enabled?
 		ldreq	\rx, =IXP23XX_PERIPHERAL_PHYS 	@ physical
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp23xx/include/mach/memory.h linux-libre-2.6.34-gnu1/arch/arm/mach-ixp23xx/include/mach/memory.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp23xx/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp23xx/include/mach/memory.h	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,7 @@
  */
 #define PHYS_OFFSET		(0x00000000)
 
-#define IXP23XX_PCI_SDRAM_OFFSET (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0))
+#define IXP23XX_PCI_SDRAM_OFFSET (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0)
 
 #define __phys_to_bus(x)	((x) + (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET))
 #define __bus_to_phys(x)	((x) - (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET))
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp23xx/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-ixp23xx/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp23xx/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp23xx/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,4 +7,4 @@
  * specific static I/O.
  */
 
-#define VMALLOC_END	(0xec000000)
+#define VMALLOC_END	(0xec000000UL)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp23xx/pci.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp23xx/pci.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp23xx/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp23xx/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/avila-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/avila-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/avila-setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/avila-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
-#include <linux/slab.h>
 #include <linux/i2c-gpio.h>
 #include <asm/types.h>
 #include <asm/setup.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/common.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/common.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/common.c	2010-05-16 17:17:36.000000000 -0400
@@ -427,6 +427,17 @@ static void __init ixp4xx_clocksource_in
 }
 
 /*
+ * sched_clock()
+ */
+unsigned long long sched_clock(void)
+{
+	cycle_t cyc = ixp4xx_get_cycles(NULL);
+	struct clocksource *cs = &clocksource_ixp4xx;
+
+	return clocksource_cyc2ns(cyc, cs->mult, cs->shift);
+}
+
+/*
  * clockevents
  */
 static int ixp4xx_set_next_event(unsigned long evt,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/common-pci.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/common-pci.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/common-pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/common-pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -502,32 +502,6 @@ struct pci_bus * __devinit ixp4xx_scan_b
 	return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys);
 }
 
-/*
- * We override these so we properly do dmabounce otherwise drivers
- * are able to set the dma_mask to 0xffffffff and we can no longer
- * trap bounces. :(
- *
- * We just return true on everyhing except for < 64MB in which case 
- * we will fail miseralby and die since we can't handle that case.
- */
-int
-pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
-	if (mask >= SZ_64M - 1 )
-		return 0;
-
-	return -EIO;
-}
-    
-int
-pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
-	if (mask >= SZ_64M - 1 )
-		return 0;
-
-	return -EIO;
-}
-
 EXPORT_SYMBOL(ixp4xx_pci_read);
 EXPORT_SYMBOL(ixp4xx_pci_write);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/coyote-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/coyote-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/coyote-setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/coyote-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
-#include <linux/slab.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/gateway7001-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/gateway7001-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/gateway7001-setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/gateway7001-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
-#include <linux/slab.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/gtwx5715-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/gtwx5715-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/gtwx5715-setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/gtwx5715-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
-#include <linux/slab.h>
 #include <asm/types.h>
 #include <asm/setup.h>
 #include <asm/memory.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,7 @@
  * published by the Free Software Foundation.
 */
 
-                .macro  addruart,rx
+                .macro  addruart, rx, tmp
                 mrc     p15, 0, \rx, c1, c0
                 tst     \rx, #1                 @ MMU enabled?
                 moveq   \rx, #0xc8000000
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/hardware.h linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/include/mach/hardware.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/hardware.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/include/mach/hardware.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,11 +26,6 @@
 #define PCIBIOS_MAX_MEM		0x4BFFFFFF
 #endif
 
-/*
- * We override the standard dma-mask routines for bouncing.
- */
-#define	HAVE_ARCH_PCI_SET_DMA_MASK
-
 #define pcibios_assign_all_busses()	1
 
 /* Register locations and bits */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
  * arch/arm/mach-ixp4xx/include/mach/vmalloc.h
  */
-#define VMALLOC_END       (0xFF000000)
+#define VMALLOC_END       (0xff000000UL)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/ixdp425-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/ixdp425-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/ixdp425-setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/ixdp425-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
-#include <linux/slab.h>
 #include <linux/i2c-gpio.h>
 #include <linux/io.h>
 #include <linux/mtd/mtd.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/ixp4xx_npe.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/ixp4xx_npe.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/ixp4xx_npe.c	2013-05-03 12:02:43.000000000 -0400
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/ixp4xx_npe.c	2013-05-03 09:43:46.000000000 -0400
@@ -20,7 +20,6 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <mach/npe.h>
 
 #define DEBUG_MSG			0
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/wg302v2-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/wg302v2-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/wg302v2-setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/wg302v2-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
-#include <linux/slab.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/common.c linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/common.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/common.c	2010-05-16 17:17:36.000000000 -0400
@@ -656,7 +656,7 @@ static struct platform_device kirkwood_x
 	.dev		= {
 		.dma_mask		= &kirkwood_xor_dmamask,
 		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= (void *)&kirkwood_xor00_data,
+		.platform_data		= &kirkwood_xor00_data,
 	},
 };
 
@@ -682,7 +682,7 @@ static struct platform_device kirkwood_x
 	.dev		= {
 		.dma_mask		= &kirkwood_xor_dmamask,
 		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= (void *)&kirkwood_xor01_data,
+		.platform_data		= &kirkwood_xor01_data,
 	},
 };
 
@@ -755,7 +755,7 @@ static struct platform_device kirkwood_x
 	.dev		= {
 		.dma_mask		= &kirkwood_xor_dmamask,
 		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= (void *)&kirkwood_xor10_data,
+		.platform_data		= &kirkwood_xor10_data,
 	},
 };
 
@@ -781,7 +781,7 @@ static struct platform_device kirkwood_x
 	.dev		= {
 		.dma_mask		= &kirkwood_xor_dmamask,
 		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= (void *)&kirkwood_xor11_data,
+		.platform_data		= &kirkwood_xor11_data,
 	},
 };
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,7 @@
 
 #include <mach/bridge-regs.h>
 
-	.macro	addruart,rx
+	.macro	addruart, rx, tmp
 	mrc	p15, 0, \rx, c1, c0
 	tst	\rx, #1					@ MMU enabled?
 	ldreq	\rx, =KIRKWOOD_REGS_PHYS_BASE
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,4 +2,4 @@
  * arch/arm/mach-kirkwood/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END	0xfe800000
+#define VMALLOC_END	0xfe800000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,12 @@ config MACH_SHEEVAPLUG
 	  Say 'Y' here if you want your kernel to support the
 	  Marvell SheevaPlug Reference Board.
 
+config MACH_ESATA_SHEEVAPLUG
+	bool "Marvell eSATA SheevaPlug Reference Board"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Marvell eSATA SheevaPlug Reference Board.
+
 config MACH_TS219
 	bool "QNAP TS-110, TS-119, TS-210, TS-219 and TS-219P Turbo NAS"
 	help
@@ -46,18 +52,35 @@ config MACH_TS41X
 	  QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS
 	  devices.
 
+config MACH_OPENRD
+        bool
+
 config MACH_OPENRD_BASE
 	bool "Marvell OpenRD Base Board"
+	select MACH_OPENRD
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  Marvell OpenRD Base Board.
 
+config MACH_OPENRD_CLIENT
+	bool "Marvell OpenRD Client Board"
+	select MACH_OPENRD
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Marvell OpenRD Client Board.
+
 config MACH_NETSPACE_V2
 	bool "LaCie Network Space v2 NAS Board"
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  LaCie Network Space v2 NAS.
 
+config MACH_INETSPACE_V2
+	bool "LaCie Internet Space v2 NAS Board"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  LaCie Internet Space v2 NAS.
+
 endmenu
 
 endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,9 +5,11 @@ obj-$(CONFIG_MACH_RD88F6192_NAS)	+= rd88
 obj-$(CONFIG_MACH_RD88F6281)		+= rd88f6281-setup.o
 obj-$(CONFIG_MACH_MV88F6281GTW_GE)	+= mv88f6281gtw_ge-setup.o
 obj-$(CONFIG_MACH_SHEEVAPLUG)		+= sheevaplug-setup.o
+obj-$(CONFIG_MACH_ESATA_SHEEVAPLUG)	+= sheevaplug-setup.o
 obj-$(CONFIG_MACH_TS219)		+= ts219-setup.o tsx1x-common.o
 obj-$(CONFIG_MACH_TS41X)		+= ts41x-setup.o tsx1x-common.o
-obj-$(CONFIG_MACH_OPENRD_BASE)		+= openrd_base-setup.o
+obj-$(CONFIG_MACH_OPENRD)		+= openrd-setup.o
 obj-$(CONFIG_MACH_NETSPACE_V2)		+= netspace_v2-setup.o
+obj-$(CONFIG_MACH_INETSPACE_V2)		+= netspace_v2-setup.o
 
 obj-$(CONFIG_CPU_IDLE)			+= cpuidle.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -74,9 +74,9 @@ static struct gpio_keys_button mv88f6281
 		.desc		= "SWR Button",
 		.active_low	= 1,
 	}, {
-		.code		= KEY_F1,
+		.code		= KEY_WPS_BUTTON,
 		.gpio		= 46,
-		.desc		= "WPS Button(F1)",
+		.desc		= "WPS Button",
 		.active_low	= 1,
 	},
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/netspace_v2-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/netspace_v2-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/netspace_v2-setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/netspace_v2-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -182,8 +182,14 @@ static struct platform_device netspace_v
 
 static struct gpio_led netspace_v2_gpio_led_pins[] = {
 	{
-		.name	= "ns_v2:red:fail",
-		.gpio	= NETSPACE_V2_GPIO_RED_LED,
+		.name			= "ns_v2:blue:sata",
+		.default_trigger	= "default-on",
+		.gpio			= NETSPACE_V2_GPIO_BLUE_LED_CMD,
+		.active_low		= 1,
+	},
+	{
+		.name			= "ns_v2:red:fail",
+		.gpio			= NETSPACE_V2_GPIO_RED_LED,
 	},
 };
 
@@ -202,30 +208,19 @@ static struct platform_device netspace_v
 
 static void __init netspace_v2_gpio_leds_init(void)
 {
-	platform_device_register(&netspace_v2_gpio_leds);
-
-	/*
-	 * Configure the front blue LED to blink in relation with the SATA
-	 * activity.
-	 */
-	if (gpio_request(NETSPACE_V2_GPIO_BLUE_LED_SLOW,
-			 "SATA blue LED slow") != 0)
-		return;
-	if (gpio_direction_output(NETSPACE_V2_GPIO_BLUE_LED_SLOW, 0) != 0)
-		goto err_free_1;
-	if (gpio_request(NETSPACE_V2_GPIO_BLUE_LED_CMD,
-			 "SATA blue LED command") != 0)
-		goto err_free_1;
-	if (gpio_direction_output(NETSPACE_V2_GPIO_BLUE_LED_CMD, 0) != 0)
-		goto err_free_2;
+	int err;
 
-	return;
+	/* Configure register slow_led to allow SATA activity LED blinking */
+	err = gpio_request(NETSPACE_V2_GPIO_BLUE_LED_SLOW, "blue LED slow");
+	if (err == 0) {
+		err = gpio_direction_output(NETSPACE_V2_GPIO_BLUE_LED_SLOW, 0);
+		if (err)
+			gpio_free(NETSPACE_V2_GPIO_BLUE_LED_SLOW);
+	}
+	if (err)
+		pr_err("netspace_v2: failed to configure blue LED slow GPIO\n");
 
-err_free_2:
-	gpio_free(NETSPACE_V2_GPIO_BLUE_LED_CMD);
-err_free_1:
-	gpio_free(NETSPACE_V2_GPIO_BLUE_LED_SLOW);
-	pr_err("netspace_v2: failed to configure SATA blue LED\n");
+	platform_device_register(&netspace_v2_gpio_leds);
 }
 
 /*****************************************************************************
@@ -314,6 +309,7 @@ static void __init netspace_v2_init(void
 		pr_err("netspace_v2: failed to configure power-off GPIO\n");
 }
 
+#ifdef CONFIG_MACH_NETSPACE_V2
 MACHINE_START(NETSPACE_V2, "LaCie Network Space v2")
 	.phys_io	= KIRKWOOD_REGS_PHYS_BASE,
 	.io_pg_offst	= ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
@@ -323,3 +319,16 @@ MACHINE_START(NETSPACE_V2, "LaCie Networ
 	.init_irq	= kirkwood_init_irq,
 	.timer		= &netspace_v2_timer,
 MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_INETSPACE_V2
+MACHINE_START(INETSPACE_V2, "LaCie Internet Space v2")
+	.phys_io	= KIRKWOOD_REGS_PHYS_BASE,
+	.io_pg_offst	= ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= netspace_v2_init,
+	.map_io		= kirkwood_map_io,
+	.init_irq	= kirkwood_init_irq,
+	.timer		= &netspace_v2_timer,
+MACHINE_END
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/openrd_base-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/openrd_base-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/openrd_base-setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/openrd_base-setup.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,96 +0,0 @@
-/*
- * arch/arm/mach-kirkwood/openrd_base-setup.c
- *
- * Marvell OpenRD Base 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/partitions.h>
-#include <linux/ata_platform.h>
-#include <linux/mv643xx_eth.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <mach/kirkwood.h>
-#include <plat/mvsdio.h>
-#include "common.h"
-#include "mpp.h"
-
-static struct mtd_partition openrd_base_nand_parts[] = {
-	{
-		.name = "u-boot",
-		.offset = 0,
-		.size = SZ_1M
-	}, {
-		.name = "uImage",
-		.offset = MTDPART_OFS_NXTBLK,
-		.size = SZ_4M
-	}, {
-		.name = "root",
-		.offset = MTDPART_OFS_NXTBLK,
-		.size = MTDPART_SIZ_FULL
-	},
-};
-
-static struct mv643xx_eth_platform_data openrd_base_ge00_data = {
-	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
-};
-
-static struct mv_sata_platform_data openrd_base_sata_data = {
-	.n_ports	= 2,
-};
-
-static struct mvsdio_platform_data openrd_base_mvsdio_data = {
-	.gpio_card_detect = 29,	/* MPP29 used as SD card detect */
-};
-
-static unsigned int openrd_base_mpp_config[] __initdata = {
-	MPP29_GPIO,
-	0
-};
-
-static void __init openrd_base_init(void)
-{
-	/*
-	 * Basic setup. Needs to be called early.
-	 */
-	kirkwood_init();
-	kirkwood_mpp_conf(openrd_base_mpp_config);
-
-	kirkwood_uart0_init();
-	kirkwood_nand_init(ARRAY_AND_SIZE(openrd_base_nand_parts), 25);
-
-	kirkwood_ehci_init();
-
-	kirkwood_ge00_init(&openrd_base_ge00_data);
-	kirkwood_sata_init(&openrd_base_sata_data);
-	kirkwood_sdio_init(&openrd_base_mvsdio_data);
-
-	kirkwood_i2c_init();
-}
-
-static int __init openrd_base_pci_init(void)
-{
-	if (machine_is_openrd_base())
-		kirkwood_pcie_init();
-
-	return 0;
- }
-subsys_initcall(openrd_base_pci_init);
-
-
-MACHINE_START(OPENRD_BASE, "Marvell OpenRD Base Board")
-	/* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
-	.phys_io	= KIRKWOOD_REGS_PHYS_BASE,
-	.io_pg_offst	= ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
-	.boot_params	= 0x00000100,
-	.init_machine	= openrd_base_init,
-	.map_io		= kirkwood_map_io,
-	.init_irq	= kirkwood_init_irq,
-	.timer		= &kirkwood_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/openrd-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/openrd-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/openrd-setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/openrd-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,118 @@
+/*
+ * arch/arm/mach-kirkwood/openrd-setup.c
+ *
+ * Marvell OpenRD (Base|Client) 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/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition openrd_nand_parts[] = {
+	{
+		.name		= "u-boot",
+		.offset		= 0,
+		.size		= SZ_1M,
+		.mask_flags	= MTD_WRITEABLE
+	}, {
+		.name		= "uImage",
+		.offset		= MTDPART_OFS_NXTBLK,
+		.size		= SZ_4M
+	}, {
+		.name		= "root",
+		.offset		= MTDPART_OFS_NXTBLK,
+		.size		= MTDPART_SIZ_FULL
+	},
+};
+
+static struct mv643xx_eth_platform_data openrd_ge00_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv643xx_eth_platform_data openrd_ge01_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(24),
+};
+
+static struct mv_sata_platform_data openrd_sata_data = {
+	.n_ports	= 2,
+};
+
+static struct mvsdio_platform_data openrd_mvsdio_data = {
+	.gpio_card_detect = 29,	/* MPP29 used as SD card detect */
+};
+
+static unsigned int openrd_mpp_config[] __initdata = {
+	MPP29_GPIO,
+	0
+};
+
+static void __init openrd_init(void)
+{
+	/*
+	 * Basic setup. Needs to be called early.
+	 */
+	kirkwood_init();
+	kirkwood_mpp_conf(openrd_mpp_config);
+
+	kirkwood_uart0_init();
+	kirkwood_nand_init(ARRAY_AND_SIZE(openrd_nand_parts), 25);
+
+	kirkwood_ehci_init();
+
+	kirkwood_ge00_init(&openrd_ge00_data);
+	if (machine_is_openrd_client())
+		kirkwood_ge01_init(&openrd_ge01_data);
+	kirkwood_sata_init(&openrd_sata_data);
+	kirkwood_sdio_init(&openrd_mvsdio_data);
+
+	kirkwood_i2c_init();
+}
+
+static int __init openrd_pci_init(void)
+{
+	if (machine_is_openrd_base() || machine_is_openrd_client())
+		kirkwood_pcie_init();
+
+	return 0;
+}
+subsys_initcall(openrd_pci_init);
+
+#ifdef CONFIG_MACH_OPENRD_BASE
+MACHINE_START(OPENRD_BASE, "Marvell OpenRD Base Board")
+	/* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
+	.phys_io	= KIRKWOOD_REGS_PHYS_BASE,
+	.io_pg_offst	= ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= openrd_init,
+	.map_io		= kirkwood_map_io,
+	.init_irq	= kirkwood_init_irq,
+	.timer		= &kirkwood_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_OPENRD_CLIENT
+MACHINE_START(OPENRD_CLIENT, "Marvell OpenRD Client Board")
+	/* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
+	.phys_io	= KIRKWOOD_REGS_PHYS_BASE,
+	.io_pg_offst	= ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= openrd_init,
+	.map_io		= kirkwood_map_io,
+	.init_irq	= kirkwood_init_irq,
+	.timer		= &kirkwood_timer,
+MACHINE_END
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/pcie.c linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/pcie.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/pcie.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/pcie.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/mbus.h>
 #include <asm/irq.h>
 #include <asm/mach/pci.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/sheevaplug-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/sheevaplug-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/sheevaplug-setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-kirkwood/sheevaplug-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/ata_platform.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/gpio.h>
@@ -42,10 +43,19 @@ static struct mv643xx_eth_platform_data
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
 };
 
+static struct mv_sata_platform_data sheeva_esata_sata_data = {
+	.n_ports	= 2,
+};
+
 static struct mvsdio_platform_data sheevaplug_mvsdio_data = {
 	/* unfortunately the CD signal has not been connected */
 };
 
+static struct mvsdio_platform_data sheeva_esata_mvsdio_data = {
+	.gpio_write_protect = 44, /* MPP44 used as SD write protect */
+	.gpio_card_detect = 47,	  /* MPP47 used as SD card detect */
+};
+
 static struct gpio_led sheevaplug_led_pins[] = {
 	{
 		.name			= "plug:green:health",
@@ -74,13 +84,26 @@ static unsigned int sheevaplug_mpp_confi
 	0
 };
 
+static unsigned int sheeva_esata_mpp_config[] __initdata = {
+	MPP29_GPIO,	/* USB Power Enable */
+	MPP44_GPIO,	/* SD Write Protect */
+	MPP47_GPIO,	/* SD Card Detect */
+	MPP49_GPIO,	/* LED Green */
+	0
+};
+
 static void __init sheevaplug_init(void)
 {
 	/*
 	 * Basic setup. Needs to be called early.
 	 */
 	kirkwood_init();
-	kirkwood_mpp_conf(sheevaplug_mpp_config);
+
+	/* setup gpio pin select */
+	if (machine_is_sheeva_esata())
+		kirkwood_mpp_conf(sheeva_esata_mpp_config);
+	else
+		kirkwood_mpp_conf(sheevaplug_mpp_config);
 
 	kirkwood_uart0_init();
 	kirkwood_nand_init(ARRAY_AND_SIZE(sheevaplug_nand_parts), 25);
@@ -91,11 +114,21 @@ static void __init sheevaplug_init(void)
 	kirkwood_ehci_init();
 
 	kirkwood_ge00_init(&sheevaplug_ge00_data);
-	kirkwood_sdio_init(&sheevaplug_mvsdio_data);
+
+	/* honor lower power consumption for plugs with out eSATA */
+	if (machine_is_sheeva_esata())
+		kirkwood_sata_init(&sheeva_esata_sata_data);
+
+	/* enable sd wp and sd cd on plugs with esata */
+	if (machine_is_sheeva_esata())
+		kirkwood_sdio_init(&sheeva_esata_mvsdio_data);
+	else
+		kirkwood_sdio_init(&sheevaplug_mvsdio_data);
 
 	platform_device_register(&sheevaplug_leds);
 }
 
+#ifdef CONFIG_MACH_SHEEVAPLUG
 MACHINE_START(SHEEVAPLUG, "Marvell SheevaPlug Reference Board")
 	/* Maintainer: shadi Ammouri <shadi@marvell.com> */
 	.phys_io	= KIRKWOOD_REGS_PHYS_BASE,
@@ -106,3 +139,16 @@ MACHINE_START(SHEEVAPLUG, "Marvell Sheev
 	.init_irq	= kirkwood_init_irq,
 	.timer		= &kirkwood_timer,
 MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_ESATA_SHEEVAPLUG
+MACHINE_START(ESATA_SHEEVAPLUG, "Marvell eSATA SheevaPlug Reference Board")
+	.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
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ks8695/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-ks8695/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ks8695/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ks8695/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,7 @@
 #include <mach/hardware.h>
 #include <mach/regs-uart.h>
 
-	.macro	addruart, rx
+	.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1				@ MMU enabled?
 		ldreq	\rx, =KS8695_UART_PA		@ physical base address
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-l7200/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-l7200/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-l7200/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-l7200/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,7 @@
 		.equ	io_virt, IO_BASE
 		.equ	io_phys, IO_START
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #io_phys		@ physical base address
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-lh7a40x/clcd.c linux-libre-2.6.34-gnu1/arch/arm/mach-lh7a40x/clcd.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-lh7a40x/clcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-lh7a40x/clcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/sysdev.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-lh7a40x/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-lh7a40x/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-lh7a40x/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-lh7a40x/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,7 @@
 	@ It is not known if this will be appropriate for every 40x
 	@ board.
 
-		.macro  addruart,rx
+		.macro  addruart, rx, tmp
 		mrc     p15, 0, \rx, c1, c0
 		tst     \rx, #1                 @ MMU enabled?
 		mov     \rx, #0x00000700        @ offset from base
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-lh7a40x/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-lh7a40x/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-lh7a40x/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-lh7a40x/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,4 +7,4 @@
  *  version 2 as published by the Free Software Foundation.
  *
  */
-#define VMALLOC_END       (0xe8000000)
+#define VMALLOC_END       (0xe8000000UL)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-loki/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-loki/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-loki/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-loki/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,7 @@
 
 #include <mach/loki.h>
 
-	.macro	addruart,rx
+	.macro	addruart, rx, tmp
 	mrc	p15, 0, \rx, c1, c0
 	tst	\rx, #1					@ MMU enabled?
 	ldreq	\rx, =LOKI_REGS_PHYS_BASE
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-loki/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-loki/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-loki/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-loki/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,4 +2,4 @@
  * arch/arm/mach-loki/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END	0xfe800000
+#define VMALLOC_END	0xfe800000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/avengers_lite.c linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/avengers_lite.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/avengers_lite.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/avengers_lite.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,51 @@
+/*
+ *  linux/arch/arm/mach-mmp/avengers_lite.c
+ *
+ *  Support for the Marvell PXA168-based Avengers lite Development Platform.
+ *
+ *  Copyright (C) 2009-2010 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
+ *  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-pxa168.h>
+#include <mach/pxa168.h>
+#include <mach/irqs.h>
+
+
+#include "common.h"
+#include <linux/delay.h>
+
+/* Avengers lite MFP configurations */
+static unsigned long avengers_lite_pin_config_V16F[] __initdata = {
+	/* DEBUG_UART */
+	GPIO88_UART2_TXD,
+	GPIO89_UART2_RXD,
+};
+
+static void __init avengers_lite_init(void)
+{
+	mfp_config(ARRAY_AND_SIZE(avengers_lite_pin_config_V16F));
+
+	/* on-chip devices */
+	pxa168_add_uart(2);
+}
+
+MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite 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   = avengers_lite_init,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -88,11 +88,3 @@ unsigned long clk_get_rate(struct clk *c
 	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.33-gnu1/arch/arm/mach-mmp/clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -68,5 +68,3 @@ struct clk clk_##_name = {					\
 
 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.33-gnu1/arch/arm/mach-mmp/common.h linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/common.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/common.h	2010-05-16 17:17:36.000000000 -0400
@@ -3,11 +3,15 @@
 struct sys_timer;
 
 extern void timer_init(int irq);
+extern void mmp2_clear_pmic_int(void);
 
 extern struct sys_timer pxa168_timer;
 extern struct sys_timer pxa910_timer;
+extern struct sys_timer mmp2_timer;
 extern void __init pxa168_init_irq(void);
 extern void __init pxa910_init_irq(void);
+extern void __init mmp2_init_icu(void);
+extern void __init mmp2_init_irq(void);
 
 extern void __init icu_init_irq(void);
 extern void __init pxa_map_io(void);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/flint.c linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/flint.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/flint.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/flint.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,123 @@
+/*
+ *  linux/arch/arm/mach-mmp/flint.c
+ *
+ *  Support for the Marvell Flint Development Platform.
+ *
+ *  Copyright (C) 2009 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
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/smc91x.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-mmp2.h>
+#include <mach/mmp2.h>
+
+#include "common.h"
+
+static unsigned long flint_pin_config[] __initdata = {
+	/* UART1 */
+	GPIO45_UART1_RXD,
+	GPIO46_UART1_TXD,
+
+	/* UART2 */
+	GPIO47_UART2_RXD,
+	GPIO48_UART2_TXD,
+
+	/* SMC */
+	GPIO151_SMC_SCLK,
+	GPIO145_SMC_nCS0,
+	GPIO146_SMC_nCS1,
+	GPIO152_SMC_BE0,
+	GPIO153_SMC_BE1,
+	GPIO154_SMC_IRQ,
+	GPIO113_SMC_RDY,
+
+	/*Ethernet*/
+	GPIO155_GPIO155,
+
+	/* DFI */
+	GPIO168_DFI_D0,
+	GPIO167_DFI_D1,
+	GPIO166_DFI_D2,
+	GPIO165_DFI_D3,
+	GPIO107_DFI_D4,
+	GPIO106_DFI_D5,
+	GPIO105_DFI_D6,
+	GPIO104_DFI_D7,
+	GPIO111_DFI_D8,
+	GPIO164_DFI_D9,
+	GPIO163_DFI_D10,
+	GPIO162_DFI_D11,
+	GPIO161_DFI_D12,
+	GPIO110_DFI_D13,
+	GPIO109_DFI_D14,
+	GPIO108_DFI_D15,
+	GPIO143_ND_nCS0,
+	GPIO144_ND_nCS1,
+	GPIO147_ND_nWE,
+	GPIO148_ND_nRE,
+	GPIO150_ND_ALE,
+	GPIO149_ND_CLE,
+	GPIO112_ND_RDY0,
+	GPIO160_ND_RDY1,
+};
+
+static struct smc91x_platdata flint_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(155),
+		.end    = gpio_to_irq(155),
+		.flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+	}
+};
+
+static struct platform_device smc91x_device = {
+	.name           = "smc91x",
+	.id             = 0,
+	.dev            = {
+		.platform_data = &flint_smc91x_info,
+	},
+	.num_resources  = ARRAY_SIZE(smc91x_resources),
+	.resource       = smc91x_resources,
+};
+
+static void __init flint_init(void)
+{
+	mfp_config(ARRAY_AND_SIZE(flint_pin_config));
+
+	/* on-chip devices */
+	mmp2_add_uart(1);
+	mmp2_add_uart(2);
+
+	/* off-chip devices */
+	platform_device_register(&smc91x_device);
+}
+
+MACHINE_START(FLINT, "Flint 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       = mmp2_init_irq,
+	.timer          = &mmp2_timer,
+	.init_machine   = flint_init,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/cputype.h linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/cputype.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/cputype.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/cputype.h	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  *
  * PXA168    A0    0x41159263   0x56158400   0x00A0A333
  * PXA910    Y0    0x41159262   0x56158000   0x00F0C910
+ * MMP2	     Z0			0x560f5811
  */
 
 #ifdef CONFIG_CPU_PXA168
@@ -24,7 +25,15 @@
 #  define __cpu_is_pxa910(id)	(0)
 #endif
 
+#ifdef CONFIG_CPU_MMP2
+#  define __cpu_is_mmp2(id)	\
+	({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x58; })
+#else
+#  define __cpu_is_mmp2(id)	(0)
+#endif
+
 #define cpu_is_pxa168()		({ __cpu_is_pxa168(read_cpuid_id()); })
 #define cpu_is_pxa910()		({ __cpu_is_pxa910(read_cpuid_id()); })
+#define cpu_is_mmp2()		({ __cpu_is_mmp2(read_cpuid_id()); })
 
 #endif /* __ASM_MACH_CPUTYPE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
 
 #include <mach/addr-map.h>
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1				@ MMU enabled?
 		ldreq	\rx, =APB_PHYS_BASE		@ physical
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/devices.h linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/devices.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/devices.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/devices.h	2010-05-16 17:17:36.000000000 -0400
@@ -34,4 +34,16 @@ struct pxa_device_desc pxa910_device_##_
 	.size		= _size,					\
 	.dma		= { _dma },					\
 };
+
+#define MMP2_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...)	\
+struct pxa_device_desc mmp2_device_##_name __initdata = {		\
+	.dev_name	= "mmp2-" #_name,				\
+	.drv_name	= _drv,						\
+	.id		= _id,						\
+	.irq		= IRQ_MMP2_##_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.33-gnu1/arch/arm/mach-mmp/include/mach/entry-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/entry-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/entry-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/entry-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,12 @@
 	.endm
 
 	.macro	get_irqnr_preamble, base, tmp
-	ldr	\base, =ICU_AP_IRQ_SEL_INT_NUM
+	mrc	p15, 0, \tmp, c0, c0, 0		@ CPUID
+	and	\tmp, \tmp, #0xff00
+	cmp	\tmp, #0x5800
+	ldr	\base, =ICU_VIRT_BASE
+	addne	\base, \base, #0x10c		@ PJ1 AP INT SEL register
+	addeq	\base, \base, #0x104		@ PJ4 IRQ SEL register
 	.endm
 
 	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/irqs.h linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/irqs.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/irqs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/irqs.h	2010-05-16 17:17:36.000000000 -0400
@@ -113,10 +113,119 @@
 #define IRQ_PXA910_AP_PMU		60
 #define IRQ_PXA910_SM_INT		63	/* from PinMux */
 
-#define IRQ_GPIO_START			64
-#define IRQ_GPIO_NUM			128
+/*
+ * Interrupt numbers for MMP2
+ */
+#define IRQ_MMP2_NONE			(-1)
+#define IRQ_MMP2_SSP1			0
+#define IRQ_MMP2_SSP2			1
+#define IRQ_MMP2_SSPA1			2
+#define IRQ_MMP2_SSPA2			3
+#define IRQ_MMP2_PMIC_MUX		4	/* PMIC & Charger */
+#define IRQ_MMP2_RTC_MUX		5
+#define IRQ_MMP2_TWSI1			7
+#define IRQ_MMP2_GPU			8
+#define IRQ_MMP2_KEYPAD			9
+#define IRQ_MMP2_ROTARY			10
+#define IRQ_MMP2_TRACKBALL		11
+#define IRQ_MMP2_ONEWIRE		12
+#define IRQ_MMP2_TIMER1			13
+#define IRQ_MMP2_TIMER2			14
+#define IRQ_MMP2_TIMER3			15
+#define IRQ_MMP2_RIPC			16
+#define IRQ_MMP2_TWSI_MUX		17	/* TWSI2 ~ TWSI6 */
+#define IRQ_MMP2_HDMI			19
+#define IRQ_MMP2_SSP3			20
+#define IRQ_MMP2_SSP4			21
+#define IRQ_MMP2_USB_HS1		22
+#define IRQ_MMP2_USB_HS2		23
+#define IRQ_MMP2_UART3			24
+#define IRQ_MMP2_UART1			27
+#define IRQ_MMP2_UART2			28
+#define IRQ_MMP2_MIPI_DSI		29
+#define IRQ_MMP2_CI2			30
+#define IRQ_MMP2_PMU_TIMER1		31
+#define IRQ_MMP2_PMU_TIMER2		32
+#define IRQ_MMP2_PMU_TIMER3		33
+#define IRQ_MMP2_USB_FS			34
+#define IRQ_MMP2_MISC_MUX		35
+#define IRQ_MMP2_WDT1			36
+#define IRQ_MMP2_NAND_DMA		37
+#define IRQ_MMP2_USIM			38
+#define IRQ_MMP2_MMC			39
+#define IRQ_MMP2_WTM			40
+#define IRQ_MMP2_LCD			41
+#define IRQ_MMP2_CI			42
+#define IRQ_MMP2_IRE			43
+#define IRQ_MMP2_USB_OTG		44
+#define IRQ_MMP2_NAND			45
+#define IRQ_MMP2_UART4			46
+#define IRQ_MMP2_DMA_FIQ		47
+#define IRQ_MMP2_DMA_RIQ		48
+#define IRQ_MMP2_GPIO			49
+#define IRQ_MMP2_SSP_MUX		51
+#define IRQ_MMP2_MMC2			52
+#define IRQ_MMP2_MMC3			53
+#define IRQ_MMP2_MMC4			54
+#define IRQ_MMP2_MIPI_HSI		55
+#define IRQ_MMP2_MSP			58
+#define IRQ_MMP2_MIPI_SLIM_DMA		59
+#define IRQ_MMP2_PJ4_FREQ_CHG		60
+#define IRQ_MMP2_MIPI_SLIM		62
+#define IRQ_MMP2_SM			63
+
+#define IRQ_MMP2_MUX_BASE		64
+
+/* secondary interrupt of INT #4 */
+#define IRQ_MMP2_PMIC_BASE		(IRQ_MMP2_MUX_BASE)
+#define IRQ_MMP2_CHARGER		(IRQ_MMP2_PMIC_BASE + 0)
+#define IRQ_MMP2_PMIC			(IRQ_MMP2_PMIC_BASE + 1)
+
+/* secondary interrupt of INT #5 */
+#define IRQ_MMP2_RTC_BASE		(IRQ_MMP2_PMIC_BASE + 2)
+#define IRQ_MMP2_RTC_ALARM		(IRQ_MMP2_RTC_BASE + 0)
+#define IRQ_MMP2_RTC			(IRQ_MMP2_RTC_BASE + 1)
+
+/* secondary interrupt of INT #17 */
+#define IRQ_MMP2_TWSI_BASE		(IRQ_MMP2_RTC_BASE + 2)
+#define IRQ_MMP2_TWSI2			(IRQ_MMP2_TWSI_BASE + 0)
+#define IRQ_MMP2_TWSI3			(IRQ_MMP2_TWSI_BASE + 1)
+#define IRQ_MMP2_TWSI4			(IRQ_MMP2_TWSI_BASE + 2)
+#define IRQ_MMP2_TWSI5			(IRQ_MMP2_TWSI_BASE + 3)
+#define IRQ_MMP2_TWSI6			(IRQ_MMP2_TWSI_BASE + 4)
+
+/* secondary interrupt of INT #35 */
+#define IRQ_MMP2_MISC_BASE		(IRQ_MMP2_TWSI_BASE + 5)
+#define IRQ_MMP2_PERF			(IRQ_MMP2_MISC_BASE + 0)
+#define IRQ_MMP2_L2_PA_ECC		(IRQ_MMP2_MISC_BASE + 1)
+#define IRQ_MMP2_L2_ECC			(IRQ_MMP2_MISC_BASE + 2)
+#define IRQ_MMP2_L2_UECC		(IRQ_MMP2_MISC_BASE + 3)
+#define IRQ_MMP2_DDR			(IRQ_MMP2_MISC_BASE + 4)
+#define IRQ_MMP2_FAB0_TIMEOUT		(IRQ_MMP2_MISC_BASE + 5)
+#define IRQ_MMP2_FAB1_TIMEOUT		(IRQ_MMP2_MISC_BASE + 6)
+#define IRQ_MMP2_FAB2_TIMEOUT		(IRQ_MMP2_MISC_BASE + 7)
+#define IRQ_MMP2_THERMAL		(IRQ_MMP2_MISC_BASE + 9)
+#define IRQ_MMP2_MAIN_PMU		(IRQ_MMP2_MISC_BASE + 10)
+#define IRQ_MMP2_WDT2			(IRQ_MMP2_MISC_BASE + 11)
+#define IRQ_MMP2_CORESIGHT		(IRQ_MMP2_MISC_BASE + 12)
+#define IRQ_MMP2_COMMTX			(IRQ_MMP2_MISC_BASE + 13)
+#define IRQ_MMP2_COMMRX			(IRQ_MMP2_MISC_BASE + 14)
+
+/* secondary interrupt of INT #51 */
+#define IRQ_MMP2_SSP_BASE		(IRQ_MMP2_MISC_BASE + 15)
+#define IRQ_MMP2_SSP1_SRDY		(IRQ_MMP2_SSP_BASE + 0)
+#define IRQ_MMP2_SSP3_SRDY		(IRQ_MMP2_SSP_BASE + 1)
+
+#define IRQ_MMP2_MUX_END		(IRQ_MMP2_SSP_BASE + 2)
+
+#define IRQ_GPIO_START			128
+#define IRQ_GPIO_NUM			192
 #define IRQ_GPIO(x)			(IRQ_GPIO_START + (x))
 
-#define NR_IRQS		(IRQ_GPIO_START + IRQ_GPIO_NUM)
+/* Board IRQ - 64 by default, increase if not enough */
+#define IRQ_BOARD_START			(IRQ_GPIO_START + IRQ_GPIO_NUM)
+#define IRQ_BOARD_END			(IRQ_BOARD_START + 64)
+
+#define NR_IRQS				(IRQ_BOARD_END)
 
 #endif /* __ASM_MACH_IRQS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/mfp-mmp2.h linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/mfp-mmp2.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/mfp-mmp2.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/mfp-mmp2.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,240 @@
+#ifndef __ASM_MACH_MFP_MMP2_H
+#define __ASM_MACH_MFP_MMP2_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)
+
+/* GPIO */
+
+/* DFI */
+#define GPIO108_DFI_D15		MFP_CFG(GPIO108, AF0)
+#define GPIO109_DFI_D14		MFP_CFG(GPIO109, AF0)
+#define GPIO110_DFI_D13		MFP_CFG(GPIO110, AF0)
+#define GPIO161_DFI_D12		MFP_CFG(GPIO161, AF0)
+#define GPIO162_DFI_D11		MFP_CFG(GPIO162, AF0)
+#define GPIO163_DFI_D10		MFP_CFG(GPIO163, AF0)
+#define GPIO164_DFI_D9		MFP_CFG(GPIO164, AF0)
+#define GPIO111_DFI_D8		MFP_CFG(GPIO111, AF0)
+#define GPIO104_DFI_D7		MFP_CFG(GPIO104, AF0)
+#define GPIO105_DFI_D6		MFP_CFG(GPIO105, AF0)
+#define GPIO106_DFI_D5		MFP_CFG(GPIO106, AF0)
+#define GPIO107_DFI_D4		MFP_CFG(GPIO107, AF0)
+#define GPIO165_DFI_D3		MFP_CFG(GPIO165, AF0)
+#define GPIO166_DFI_D2		MFP_CFG(GPIO166, AF0)
+#define GPIO167_DFI_D1		MFP_CFG(GPIO167, AF0)
+#define GPIO168_DFI_D0		MFP_CFG(GPIO168, AF0)
+#define GPIO143_ND_nCS0		MFP_CFG(GPIO143, AF0)
+#define GPIO144_ND_nCS1		MFP_CFG(GPIO144, AF0)
+#define GPIO147_ND_nWE		MFP_CFG(GPIO147, AF0)
+#define GPIO148_ND_nRE		MFP_CFG(GPIO148, AF0)
+#define GPIO150_ND_ALE		MFP_CFG(GPIO150, AF0)
+#define GPIO149_ND_CLE		MFP_CFG(GPIO149, AF0)
+#define GPIO112_ND_RDY0		MFP_CFG(GPIO112, AF0)
+#define GPIO160_ND_RDY1		MFP_CFG(GPIO160, AF0)
+
+/* Static Memory Controller */
+#define GPIO145_SMC_nCS0	MFP_CFG(GPIO145, AF0)
+#define GPIO146_SMC_nCS1	MFP_CFG(GPIO146, AF0)
+#define GPIO152_SMC_BE0		MFP_CFG(GPIO152, AF0)
+#define GPIO153_SMC_BE1		MFP_CFG(GPIO153, AF0)
+#define GPIO154_SMC_IRQ		MFP_CFG(GPIO154, AF0)
+#define GPIO113_SMC_RDY		MFP_CFG(GPIO113, AF0)
+#define GPIO151_SMC_SCLK	MFP_CFG(GPIO151, AF0)
+
+/* Ethernet */
+#define GPIO155_SM_ADVMUX	MFP_CFG(GPIO155, AF2)
+#define GPIO155_GPIO155		MFP_CFG(GPIO155, AF1)
+
+/* UART1 */
+#define GPIO45_UART1_RXD	MFP_CFG(GPIO45, AF1)
+#define GPIO46_UART1_TXD	MFP_CFG(GPIO46, AF1)
+#define GPIO29_UART1_RXD	MFP_CFG(GPIO29, AF1)
+#define GPIO30_UART1_TXD	MFP_CFG(GPIO30, AF1)
+#define GPIO31_UART1_CTS	MFP_CFG(GPIO31, AF1)
+#define GPIO32_UART1_RTS	MFP_CFG(GPIO32, AF1)
+
+/* UART2 */
+#define GPIO47_UART2_RXD	MFP_CFG(GPIO47, AF1)
+#define GPIO48_UART2_TXD	MFP_CFG(GPIO48, AF1)
+#define GPIO49_UART2_CTS	MFP_CFG(GPIO49, AF1)
+#define GPIO50_UART2_RTS	MFP_CFG(GPIO50, AF1)
+
+/* UART3 */
+#define GPIO51_UART3_RXD	MFP_CFG(GPIO51, AF1)
+#define GPIO52_UART3_TXD	MFP_CFG(GPIO52, AF1)
+#define GPIO53_UART3_CTS	MFP_CFG(GPIO53, AF1)
+#define GPIO54_UART3_RTS	MFP_CFG(GPIO54, AF1)
+
+/* MMC1 */
+#define GPIO124_MMC1_DAT7	MFP_CFG_DRV(GPIO124, AF1, FAST)
+#define GPIO125_MMC1_DAT6	MFP_CFG_DRV(GPIO125, AF1, FAST)
+#define GPIO129_MMC1_DAT5	MFP_CFG_DRV(GPIO129, AF1, FAST)
+#define GPIO130_MMC1_DAT4	MFP_CFG_DRV(GPIO130, AF1, FAST)
+#define GPIO131_MMC1_DAT3	MFP_CFG_DRV(GPIO131, AF1, FAST)
+#define GPIO132_MMC1_DAT2	MFP_CFG_DRV(GPIO132, AF1, FAST)
+#define GPIO133_MMC1_DAT1	MFP_CFG_DRV(GPIO133, AF1, FAST)
+#define GPIO134_MMC1_DAT0	MFP_CFG_DRV(GPIO134, AF1, FAST)
+#define GPIO136_MMC1_CMD	MFP_CFG_DRV(GPIO136, AF1, FAST)
+#define GPIO139_MMC1_CLK	MFP_CFG_DRV(GPIO139, AF1, FAST)
+#define GPIO140_MMC1_CD		MFP_CFG_DRV(GPIO140, AF1, FAST)
+#define GPIO141_MMC1_WP		MFP_CFG_DRV(GPIO141, AF1, FAST)
+
+/*MMC2*/
+#define GPIO37_MMC2_DAT3	MFP_CFG_DRV(GPIO37, AF1, FAST)
+#define GPIO38_MMC2_DAT2	MFP_CFG_DRV(GPIO38, AF1, FAST)
+#define GPIO39_MMC2_DAT1	MFP_CFG_DRV(GPIO39, AF1, FAST)
+#define GPIO40_MMC2_DAT0	MFP_CFG_DRV(GPIO40, AF1, FAST)
+#define GPIO41_MMC2_CMD		MFP_CFG_DRV(GPIO41, AF1, FAST)
+#define GPIO42_MMC2_CLK		MFP_CFG_DRV(GPIO42, AF1, FAST)
+
+/*MMC3*/
+#define GPIO165_MMC3_DAT7	MFP_CFG_DRV(GPIO165, AF2, FAST)
+#define GPIO162_MMC3_DAT6	MFP_CFG_DRV(GPIO162, AF2, FAST)
+#define GPIO166_MMC3_DAT5	MFP_CFG_DRV(GPIO166, AF2, FAST)
+#define GPIO163_MMC3_DAT4	MFP_CFG_DRV(GPIO163, AF2, FAST)
+#define GPIO167_MMC3_DAT3	MFP_CFG_DRV(GPIO167, AF2, FAST)
+#define GPIO164_MMC3_DAT2	MFP_CFG_DRV(GPIO164, AF2, FAST)
+#define GPIO168_MMC3_DAT1	MFP_CFG_DRV(GPIO168, AF2, FAST)
+#define GPIO111_MMC3_DAT0	MFP_CFG_DRV(GPIO111, AF2, FAST)
+#define GPIO112_MMC3_CMD	MFP_CFG_DRV(GPIO112, AF2, FAST)
+#define GPIO151_MMC3_CLK	MFP_CFG_DRV(GPIO151, AF2, FAST)
+
+/* LCD */
+#define GPIO74_LCD_FCLK		MFP_CFG_DRV(GPIO74, AF1, FAST)
+#define GPIO75_LCD_LCLK		MFP_CFG_DRV(GPIO75, AF1, FAST)
+#define GPIO76_LCD_PCLK		MFP_CFG_DRV(GPIO76, AF1, FAST)
+#define GPIO77_LCD_DENA		MFP_CFG_DRV(GPIO77, AF1, FAST)
+#define GPIO78_LCD_DD0		MFP_CFG_DRV(GPIO78, AF1, FAST)
+#define GPIO79_LCD_DD1		MFP_CFG_DRV(GPIO79, AF1, FAST)
+#define GPIO80_LCD_DD2		MFP_CFG_DRV(GPIO80, AF1, FAST)
+#define GPIO81_LCD_DD3		MFP_CFG_DRV(GPIO81, AF1, FAST)
+#define GPIO82_LCD_DD4		MFP_CFG_DRV(GPIO82, AF1, FAST)
+#define GPIO83_LCD_DD5		MFP_CFG_DRV(GPIO83, AF1, FAST)
+#define GPIO84_LCD_DD6		MFP_CFG_DRV(GPIO84, AF1, FAST)
+#define GPIO85_LCD_DD7		MFP_CFG_DRV(GPIO85, AF1, FAST)
+#define GPIO86_LCD_DD8		MFP_CFG_DRV(GPIO86, AF1, FAST)
+#define GPIO87_LCD_DD9		MFP_CFG_DRV(GPIO87, AF1, FAST)
+#define GPIO88_LCD_DD10		MFP_CFG_DRV(GPIO88, AF1, FAST)
+#define GPIO89_LCD_DD11		MFP_CFG_DRV(GPIO89, AF1, FAST)
+#define GPIO90_LCD_DD12		MFP_CFG_DRV(GPIO90, AF1, FAST)
+#define GPIO91_LCD_DD13		MFP_CFG_DRV(GPIO91, AF1, FAST)
+#define GPIO92_LCD_DD14		MFP_CFG_DRV(GPIO92, AF1, FAST)
+#define GPIO93_LCD_DD15		MFP_CFG_DRV(GPIO93, AF1, FAST)
+#define GPIO94_LCD_DD16		MFP_CFG_DRV(GPIO94, AF1, FAST)
+#define GPIO95_LCD_DD17		MFP_CFG_DRV(GPIO95, AF1, FAST)
+#define GPIO96_LCD_DD18		MFP_CFG_DRV(GPIO96, AF1, FAST)
+#define GPIO97_LCD_DD19		MFP_CFG_DRV(GPIO97, AF1, FAST)
+#define GPIO98_LCD_DD20		MFP_CFG_DRV(GPIO98, AF1, FAST)
+#define GPIO99_LCD_DD21		MFP_CFG_DRV(GPIO99, AF1, FAST)
+#define GPIO100_LCD_DD22	MFP_CFG_DRV(GPIO100, AF1, FAST)
+#define GPIO101_LCD_DD23	MFP_CFG_DRV(GPIO101, AF1, FAST)
+#define GPIO94_SPI_DCLK		MFP_CFG_DRV(GPIO94, AF3, FAST)
+#define GPIO95_SPI_CS0		MFP_CFG_DRV(GPIO95, AF3, FAST)
+#define GPIO96_SPI_DIN		MFP_CFG_DRV(GPIO96, AF3, FAST)
+#define GPIO97_SPI_DOUT		MFP_CFG_DRV(GPIO97, AF3, FAST)
+#define GPIO98_LCD_RST		MFP_CFG_DRV(GPIO98, AF0, FAST)
+
+#define GPIO114_MN_CLK_OUT	MFP_CFG_DRV(GPIO114, AF1, FAST)
+
+/*LCD TV path*/
+#define GPIO124_LCD_DD24	MFP_CFG_DRV(GPIO124, AF2, FAST)
+#define GPIO125_LCD_DD25	MFP_CFG_DRV(GPIO125, AF2, FAST)
+#define GPIO126_LCD_DD33	MFP_CFG_DRV(GPIO126, AF2, FAST)
+#define GPIO127_LCD_DD26	MFP_CFG_DRV(GPIO127, AF2, FAST)
+#define GPIO128_LCD_DD27	MFP_CFG_DRV(GPIO128, AF2, FAST)
+#define GPIO129_LCD_DD28	MFP_CFG_DRV(GPIO129, AF2, FAST)
+#define GPIO130_LCD_DD29	MFP_CFG_DRV(GPIO130, AF2, FAST)
+#define GPIO135_LCD_DD30	MFP_CFG_DRV(GPIO135, AF2, FAST)
+#define GPIO137_LCD_DD31	MFP_CFG_DRV(GPIO137, AF2, FAST)
+#define GPIO138_LCD_DD32	MFP_CFG_DRV(GPIO138, AF2, FAST)
+#define GPIO140_LCD_DD34	MFP_CFG_DRV(GPIO140, AF2, FAST)
+#define GPIO141_LCD_DD35	MFP_CFG_DRV(GPIO141, AF2, FAST)
+
+/* I2C */
+#define GPIO43_TWSI2_SCL	MFP_CFG_DRV(GPIO43, AF1, SLOW)
+#define GPIO44_TWSI2_SDA	MFP_CFG_DRV(GPIO44, AF1, SLOW)
+#define GPIO71_TWSI3_SCL	MFP_CFG_DRV(GPIO71, AF1, SLOW)
+#define GPIO72_TWSI3_SDA	MFP_CFG_DRV(GPIO72, AF1, SLOW)
+#define GPIO99_TWSI5_SCL	MFP_CFG_DRV(GPIO99, AF4, SLOW)
+#define GPIO100_TWSI5_SDA	MFP_CFG_DRV(GPIO100, AF4, SLOW)
+#define GPIO97_TWSI6_SCL	MFP_CFG_DRV(GPIO97, AF2, SLOW)
+#define GPIO98_TWSI6_SDA	MFP_CFG_DRV(GPIO98, AF2, SLOW)
+
+/* SSPA1 */
+#define GPIO24_I2S_SYSCLK	MFP_CFG(GPIO24, AF1)
+#define GPIO25_I2S_BITCLK	MFP_CFG(GPIO25, AF1)
+#define GPIO26_I2S_SYNC		MFP_CFG(GPIO26, AF1)
+#define GPIO27_I2S_DATA_OUT	MFP_CFG(GPIO27, AF1)
+#define GPIO28_I2S_SDATA_IN	MFP_CFG(GPIO28, AF1)
+#define GPIO114_I2S_MCLK	MFP_CFG(GPIO114, AF1)
+
+/* SSPA2 */
+#define GPIO33_SSPA2_CLK	MFP_CFG(GPIO33, AF1)
+#define GPIO34_SSPA2_FRM	MFP_CFG(GPIO34, AF1)
+#define GPIO35_SSPA2_TXD	MFP_CFG(GPIO35, AF1)
+#define GPIO36_SSPA2_RXD	MFP_CFG(GPIO36, AF1)
+
+/* 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)
+#define GPIO20_KP_DKIN4		MFP_CFG(GPIO20, AF1)
+#define GPIO21_KP_DKIN5		MFP_CFG(GPIO21, AF1)
+#define GPIO22_KP_DKIN6		MFP_CFG(GPIO22, AF1)
+#define GPIO23_KP_DKIN7		MFP_CFG(GPIO23, AF1)
+
+/* CAMERA */
+#define GPIO59_CCIC_IN7		MFP_CFG_DRV(GPIO59, AF1, FAST)
+#define GPIO60_CCIC_IN6		MFP_CFG_DRV(GPIO60, AF1, FAST)
+#define GPIO61_CCIC_IN5		MFP_CFG_DRV(GPIO61, AF1, FAST)
+#define GPIO62_CCIC_IN4		MFP_CFG_DRV(GPIO62, AF1, FAST)
+#define GPIO63_CCIC_IN3		MFP_CFG_DRV(GPIO63, AF1, FAST)
+#define GPIO64_CCIC_IN2		MFP_CFG_DRV(GPIO64, AF1, FAST)
+#define GPIO65_CCIC_IN1		MFP_CFG_DRV(GPIO65, AF1, FAST)
+#define GPIO66_CCIC_IN0		MFP_CFG_DRV(GPIO66, AF1, FAST)
+#define GPIO67_CAM_HSYNC	MFP_CFG_DRV(GPIO67, AF1, FAST)
+#define GPIO68_CAM_VSYNC	MFP_CFG_DRV(GPIO68, AF1, FAST)
+#define GPIO69_CAM_MCLK		MFP_CFG_DRV(GPIO69, AF1, FAST)
+#define GPIO70_CAM_PCLK		MFP_CFG_DRV(GPIO70, AF1, FAST)
+
+/* Wifi */
+#define GPIO45_GPIO45		MFP_CFG(GPIO45, AF0)
+#define GPIO46_GPIO46		MFP_CFG(GPIO46, AF0)
+#define GPIO21_GPIO21		MFP_CFG(GPIO21, AF0)
+#define GPIO22_GPIO22		MFP_CFG(GPIO22, AF0)
+#define GPIO55_GPIO55		MFP_CFG(GPIO55, AF0)
+#define GPIO56_GPIO56		MFP_CFG(GPIO56, AF0)
+#define GPIO57_GPIO57		MFP_CFG(GPIO57, AF0)
+#define GPIO58_GPIO58		MFP_CFG(GPIO58, AF0)
+
+/* Codec*/
+#define GPIO23_GPIO23		MFP_CFG(GPIO23, AF0)
+
+#define GPIO101_GPIO101		MFP_CFG(GPIO101, AF0)
+
+/* PMIC */
+#define PMIC_PMIC_INT		MFP_CFG(PMIC_INT, AF0)
+
+#endif /* __ASM_MACH_MFP_MMP2_H */
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/mfp-pxa168.h linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/mfp-pxa168.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/mfp-pxa168.h	2010-05-16 17:17:36.000000000 -0400
@@ -193,7 +193,9 @@
 #define GPIO32_CF_nCD1		MFP_CFG(GPIO32, AF3)
 #define GPIO33_CF_nCD2		MFP_CFG(GPIO33, AF3)
 
-/* UART1 */
+/* UART */
+#define GPIO88_UART2_TXD	MFP_CFG(GPIO88, AF2)
+#define GPIO89_UART2_RXD	MFP_CFG(GPIO89, AF2)
 #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)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/mmp2.h linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/mmp2.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/mmp2.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/mmp2.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,60 @@
+#ifndef __ASM_MACH_MMP2_H
+#define __ASM_MACH_MMP2_H
+
+#include <linux/i2c.h>
+#include <mach/devices.h>
+#include <plat/i2c.h>
+
+extern struct pxa_device_desc mmp2_device_uart1;
+extern struct pxa_device_desc mmp2_device_uart2;
+extern struct pxa_device_desc mmp2_device_uart3;
+extern struct pxa_device_desc mmp2_device_uart4;
+extern struct pxa_device_desc mmp2_device_twsi1;
+extern struct pxa_device_desc mmp2_device_twsi2;
+extern struct pxa_device_desc mmp2_device_twsi3;
+extern struct pxa_device_desc mmp2_device_twsi4;
+extern struct pxa_device_desc mmp2_device_twsi5;
+extern struct pxa_device_desc mmp2_device_twsi6;
+
+static inline int mmp2_add_uart(int id)
+{
+	struct pxa_device_desc *d = NULL;
+
+	switch (id) {
+	case 1: d = &mmp2_device_uart1; break;
+	case 2: d = &mmp2_device_uart2; break;
+	case 3: d = &mmp2_device_uart3; break;
+	case 4: d = &mmp2_device_uart4; break;
+	default:
+		return -EINVAL;
+	}
+
+	return pxa_register_device(d, NULL, 0);
+}
+
+static inline int mmp2_add_twsi(int id, struct i2c_pxa_platform_data *data,
+				  struct i2c_board_info *info, unsigned size)
+{
+	struct pxa_device_desc *d = NULL;
+	int ret;
+
+	switch (id) {
+	case 0: d = &mmp2_device_twsi1; break;
+	case 1: d = &mmp2_device_twsi2; break;
+	case 2: d = &mmp2_device_twsi3; break;
+	case 3: d = &mmp2_device_twsi4; break;
+	case 4: d = &mmp2_device_twsi5; break;
+	case 5: d = &mmp2_device_twsi6; break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = i2c_register_board_info(id, info, size);
+	if (ret)
+		return ret;
+
+	return pxa_register_device(d, data, sizeof(*data));
+}
+
+#endif /* __ASM_MACH_MMP2_H */
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/regs-apbc.h linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/regs-apbc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/regs-apbc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/regs-apbc.h	2010-05-16 17:17:36.000000000 -0400
@@ -69,6 +69,47 @@
 #define APBC_PXA910_ASFAR	APBC_REG(0x050)
 #define APBC_PXA910_ASSAR	APBC_REG(0x054)
 
+/*
+ * APB Clock register offsets for MMP2
+ */
+#define APBC_MMP2_RTC		APBC_REG(0x000)
+#define APBC_MMP2_TWSI1		APBC_REG(0x004)
+#define APBC_MMP2_TWSI2		APBC_REG(0x008)
+#define APBC_MMP2_TWSI3		APBC_REG(0x00c)
+#define APBC_MMP2_TWSI4		APBC_REG(0x010)
+#define APBC_MMP2_ONEWIRE	APBC_REG(0x014)
+#define APBC_MMP2_KPC		APBC_REG(0x018)
+#define APBC_MMP2_TB_ROTARY	APBC_REG(0x01c)
+#define APBC_MMP2_SW_JTAG	APBC_REG(0x020)
+#define APBC_MMP2_TIMERS	APBC_REG(0x024)
+#define APBC_MMP2_UART1		APBC_REG(0x02c)
+#define APBC_MMP2_UART2		APBC_REG(0x030)
+#define APBC_MMP2_UART3		APBC_REG(0x034)
+#define APBC_MMP2_GPIO		APBC_REG(0x038)
+#define APBC_MMP2_PWM0		APBC_REG(0x03c)
+#define APBC_MMP2_PWM1		APBC_REG(0x040)
+#define APBC_MMP2_PWM2		APBC_REG(0x044)
+#define APBC_MMP2_PWM3		APBC_REG(0x048)
+#define APBC_MMP2_SSP0		APBC_REG(0x04c)
+#define APBC_MMP2_SSP1		APBC_REG(0x050)
+#define APBC_MMP2_SSP2		APBC_REG(0x054)
+#define APBC_MMP2_SSP3		APBC_REG(0x058)
+#define APBC_MMP2_SSP4		APBC_REG(0x05c)
+#define APBC_MMP2_SSP5		APBC_REG(0x060)
+#define APBC_MMP2_AIB		APBC_REG(0x064)
+#define APBC_MMP2_ASFAR		APBC_REG(0x068)
+#define APBC_MMP2_ASSAR		APBC_REG(0x06c)
+#define APBC_MMP2_USIM		APBC_REG(0x070)
+#define APBC_MMP2_MPMU		APBC_REG(0x074)
+#define APBC_MMP2_IPC		APBC_REG(0x078)
+#define APBC_MMP2_TWSI5		APBC_REG(0x07c)
+#define APBC_MMP2_TWSI6		APBC_REG(0x080)
+#define APBC_MMP2_TWSI_INTSTS	APBC_REG(0x084)
+#define APBC_MMP2_UART4		APBC_REG(0x088)
+#define APBC_MMP2_RIPC		APBC_REG(0x08c)
+#define APBC_MMP2_THSENS1	APBC_REG(0x090)	/* Thermal Sensor */
+#define APBC_MMP2_THSENS_INTSTS	APBC_REG(0x0a4)
+
 /* Common APB clock register bit definitions */
 #define APBC_APBCLK	(1 << 0)  /* APB Bus Clock Enable */
 #define APBC_FNCLK	(1 << 1)  /* Functional Clock Enable */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/regs-icu.h linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/regs-icu.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/regs-icu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/regs-icu.h	2010-05-16 17:17:36.000000000 -0400
@@ -17,10 +17,12 @@
 #define ICU_REG(x)	(ICU_VIRT_BASE + (x))
 
 #define ICU_INT_CONF(n)		ICU_REG((n) << 2)
+#define ICU_INT_CONF_MASK	(0xf)
+
+/************ PXA168/PXA910 (MMP) *********************/
 #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 */
@@ -28,4 +30,42 @@
 #define ICU_INT_STATUS_0	ICU_REG(0x128)	/* Interrupt Stuats 0 */
 #define ICU_INT_STATUS_1	ICU_REG(0x12C)	/* Interrupt Status 1 */
 
+/************************** MMP2 ***********************/
+
+/*
+ * IRQ0/FIQ0 is routed to SP IRQ/FIQ.
+ * IRQ1 is routed to PJ4 IRQ, and IRQ2 is routes to PJ4 FIQ.
+ */
+#define ICU_INT_ROUTE_SP_IRQ		(1 << 4)
+#define ICU_INT_ROUTE_PJ4_IRQ		(1 << 5)
+#define ICU_INT_ROUTE_PJ4_FIQ		(1 << 6)
+
+#define MMP2_ICU_PJ4_IRQ_STATUS0	ICU_REG(0x138)
+#define MMP2_ICU_PJ4_IRQ_STATUS1	ICU_REG(0x13c)
+#define MMP2_ICU_PJ4_FIQ_STATUS0	ICU_REG(0x140)
+#define MMP2_ICU_PJ4_FIQ_STATUS1	ICU_REG(0x144)
+
+#define MMP2_ICU_INT4_STATUS		ICU_REG(0x150)
+#define MMP2_ICU_INT5_STATUS		ICU_REG(0x154)
+#define MMP2_ICU_INT17_STATUS		ICU_REG(0x158)
+#define MMP2_ICU_INT35_STATUS		ICU_REG(0x15c)
+#define MMP2_ICU_INT51_STATUS		ICU_REG(0x160)
+
+#define MMP2_ICU_INT4_MASK		ICU_REG(0x168)
+#define MMP2_ICU_INT5_MASK		ICU_REG(0x16C)
+#define MMP2_ICU_INT17_MASK		ICU_REG(0x170)
+#define MMP2_ICU_INT35_MASK		ICU_REG(0x174)
+#define MMP2_ICU_INT51_MASK		ICU_REG(0x178)
+
+#define MMP2_ICU_SP_IRQ_SEL		ICU_REG(0x100)
+#define MMP2_ICU_PJ4_IRQ_SEL		ICU_REG(0x104)
+#define MMP2_ICU_PJ4_FIQ_SEL		ICU_REG(0x108)
+
+#define MMP2_ICU_INVERT			ICU_REG(0x164)
+
+#define MMP2_ICU_INV_PMIC		(1 << 0)
+#define MMP2_ICU_INV_PERF		(1 << 1)
+#define MMP2_ICU_INV_COMMTX		(1 << 2)
+#define MMP2_ICU_INV_COMMRX		(1 << 3)
+
 #endif /* __ASM_MACH_ICU_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/uncompress.h linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/uncompress.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/uncompress.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/uncompress.h	2010-05-16 17:17:36.000000000 -0400
@@ -8,15 +8,16 @@
 
 #include <linux/serial_reg.h>
 #include <mach/addr-map.h>
+#include <asm/mach-types.h>
 
 #define UART1_BASE	(APB_PHYS_BASE + 0x36000)
 #define UART2_BASE	(APB_PHYS_BASE + 0x17000)
 #define UART3_BASE	(APB_PHYS_BASE + 0x18000)
 
+static volatile unsigned long *UART;
+
 static inline void putc(char c)
 {
-	volatile unsigned long *UART = (unsigned long *)UART2_BASE;
-
 	/* UART enabled? */
 	if (!(UART[UART_IER] & UART_IER_UUE))
 		return;
@@ -34,8 +35,17 @@ static inline void flush(void)
 {
 }
 
+static inline void arch_decomp_setup(void)
+{
+	/* default to UART2 */
+	UART = (unsigned long *)UART2_BASE;
+
+	if (machine_is_avengers_lite())
+		UART = (unsigned long *)UART3_BASE;
+}
+
 /*
  * nothing to do
  */
-#define arch_decomp_setup()
+
 #define arch_decomp_wdog()
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,4 +2,4 @@
  * linux/arch/arm/mach-mmp/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END	0xfe000000
+#define VMALLOC_END	0xfe000000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/irq.c linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/irq.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/irq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,55 +0,0 @@
-/*
- *  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.33-gnu1/arch/arm/mach-mmp/irq-mmp2.c linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/irq-mmp2.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/irq-mmp2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/irq-mmp2.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,154 @@
+/*
+ *  linux/arch/arm/mach-mmp/irq-mmp2.c
+ *
+ *  Generic IRQ handling, GPIO IRQ demultiplexing, etc.
+ *
+ *  Author:	Haojian Zhuang <haojian.zhuang@marvell.com>
+ *  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"
+
+static void icu_mask_irq(unsigned int irq)
+{
+	uint32_t r = __raw_readl(ICU_INT_CONF(irq));
+
+	r &= ~ICU_INT_ROUTE_PJ4_IRQ;
+	__raw_writel(r, ICU_INT_CONF(irq));
+}
+
+static void icu_unmask_irq(unsigned int irq)
+{
+	uint32_t r = __raw_readl(ICU_INT_CONF(irq));
+
+	r |= ICU_INT_ROUTE_PJ4_IRQ;
+	__raw_writel(r, ICU_INT_CONF(irq));
+}
+
+static struct irq_chip icu_irq_chip = {
+	.name		= "icu_irq",
+	.mask		= icu_mask_irq,
+	.mask_ack	= icu_mask_irq,
+	.unmask		= icu_unmask_irq,
+};
+
+static void pmic_irq_ack(unsigned int irq)
+{
+	if (irq == IRQ_MMP2_PMIC)
+		mmp2_clear_pmic_int();
+}
+
+#define SECOND_IRQ_MASK(_name_, irq_base, prefix)			\
+static void _name_##_mask_irq(unsigned int irq)				\
+{									\
+	uint32_t r;							\
+	r = __raw_readl(prefix##_MASK) | (1 << (irq - irq_base));	\
+	__raw_writel(r, prefix##_MASK);					\
+}
+
+#define SECOND_IRQ_UNMASK(_name_, irq_base, prefix)			\
+static void _name_##_unmask_irq(unsigned int irq)			\
+{									\
+	uint32_t r;							\
+	r = __raw_readl(prefix##_MASK) & ~(1 << (irq - irq_base));	\
+	__raw_writel(r, prefix##_MASK);					\
+}
+
+#define SECOND_IRQ_DEMUX(_name_, irq_base, prefix)			\
+static void _name_##_irq_demux(unsigned int irq, struct irq_desc *desc)	\
+{									\
+	unsigned long status, mask, n;					\
+	mask = __raw_readl(prefix##_MASK);				\
+	while (1) {							\
+		status = __raw_readl(prefix##_STATUS) & ~mask;		\
+		if (status == 0)					\
+			break;						\
+		n = find_first_bit(&status, BITS_PER_LONG);		\
+		while (n < BITS_PER_LONG) {				\
+			generic_handle_irq(irq_base + n);		\
+			n = find_next_bit(&status, BITS_PER_LONG, n+1);	\
+		}							\
+	}								\
+}
+
+#define SECOND_IRQ_CHIP(_name_, irq_base, prefix)			\
+SECOND_IRQ_MASK(_name_, irq_base, prefix)				\
+SECOND_IRQ_UNMASK(_name_, irq_base, prefix)				\
+SECOND_IRQ_DEMUX(_name_, irq_base, prefix)				\
+static struct irq_chip _name_##_irq_chip = {				\
+	.name		= #_name_,					\
+	.mask		= _name_##_mask_irq,				\
+	.unmask		= _name_##_unmask_irq,				\
+}
+
+SECOND_IRQ_CHIP(pmic, IRQ_MMP2_PMIC_BASE, MMP2_ICU_INT4);
+SECOND_IRQ_CHIP(rtc,  IRQ_MMP2_RTC_BASE,  MMP2_ICU_INT5);
+SECOND_IRQ_CHIP(twsi, IRQ_MMP2_TWSI_BASE, MMP2_ICU_INT17);
+SECOND_IRQ_CHIP(misc, IRQ_MMP2_MISC_BASE, MMP2_ICU_INT35);
+SECOND_IRQ_CHIP(ssp,  IRQ_MMP2_SSP_BASE,  MMP2_ICU_INT51);
+
+static void init_mux_irq(struct irq_chip *chip, int start, int num)
+{
+	int irq;
+
+	for (irq = start; num > 0; irq++, num--) {
+		/* mask and clear the IRQ */
+		chip->mask(irq);
+		if (chip->ack)
+			chip->ack(irq);
+
+		set_irq_chip(irq, chip);
+		set_irq_flags(irq, IRQF_VALID);
+		set_irq_handler(irq, handle_level_irq);
+	}
+}
+
+void __init mmp2_init_icu(void)
+{
+	int irq;
+
+	for (irq = 0; irq < IRQ_MMP2_MUX_BASE; irq++) {
+		icu_mask_irq(irq);
+		set_irq_chip(irq, &icu_irq_chip);
+		set_irq_flags(irq, IRQF_VALID);
+
+		switch (irq) {
+		case IRQ_MMP2_PMIC_MUX:
+		case IRQ_MMP2_RTC_MUX:
+		case IRQ_MMP2_TWSI_MUX:
+		case IRQ_MMP2_MISC_MUX:
+		case IRQ_MMP2_SSP_MUX:
+			break;
+		default:
+			set_irq_handler(irq, handle_level_irq);
+			break;
+		}
+	}
+
+	/* NOTE: IRQ_MMP2_PMIC requires the PMIC MFPR register
+	 * to be written to clear the interrupt
+	 */
+	pmic_irq_chip.ack = pmic_irq_ack;
+
+	init_mux_irq(&pmic_irq_chip, IRQ_MMP2_PMIC_BASE, 2);
+	init_mux_irq(&rtc_irq_chip, IRQ_MMP2_RTC_BASE, 2);
+	init_mux_irq(&twsi_irq_chip, IRQ_MMP2_TWSI_BASE, 5);
+	init_mux_irq(&misc_irq_chip, IRQ_MMP2_MISC_BASE, 15);
+	init_mux_irq(&ssp_irq_chip, IRQ_MMP2_SSP_BASE, 2);
+
+	set_irq_chained_handler(IRQ_MMP2_PMIC_MUX, pmic_irq_demux);
+	set_irq_chained_handler(IRQ_MMP2_RTC_MUX, rtc_irq_demux);
+	set_irq_chained_handler(IRQ_MMP2_TWSI_MUX, twsi_irq_demux);
+	set_irq_chained_handler(IRQ_MMP2_MISC_MUX, misc_irq_demux);
+	set_irq_chained_handler(IRQ_MMP2_SSP_MUX, ssp_irq_demux);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/irq-pxa168.c linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/irq-pxa168.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/irq-pxa168.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/irq-pxa168.c	2010-05-16 17:17:36.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.33-gnu1/arch/arm/mach-mmp/jasper.c linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/jasper.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/jasper.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/jasper.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,80 @@
+/*
+ *  linux/arch/arm/mach-mmp/jasper.c
+ *
+ *  Support for the Marvell Jasper Development Platform.
+ *
+ *  Copyright (C) 2009-2010 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
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-mmp2.h>
+#include <mach/mmp2.h>
+
+#include "common.h"
+
+static unsigned long jasper_pin_config[] __initdata = {
+	/* UART1 */
+	GPIO29_UART1_RXD,
+	GPIO30_UART1_TXD,
+
+	/* UART3 */
+	GPIO51_UART3_RXD,
+	GPIO52_UART3_TXD,
+
+	/* DFI */
+	GPIO168_DFI_D0,
+	GPIO167_DFI_D1,
+	GPIO166_DFI_D2,
+	GPIO165_DFI_D3,
+	GPIO107_DFI_D4,
+	GPIO106_DFI_D5,
+	GPIO105_DFI_D6,
+	GPIO104_DFI_D7,
+	GPIO111_DFI_D8,
+	GPIO164_DFI_D9,
+	GPIO163_DFI_D10,
+	GPIO162_DFI_D11,
+	GPIO161_DFI_D12,
+	GPIO110_DFI_D13,
+	GPIO109_DFI_D14,
+	GPIO108_DFI_D15,
+	GPIO143_ND_nCS0,
+	GPIO144_ND_nCS1,
+	GPIO147_ND_nWE,
+	GPIO148_ND_nRE,
+	GPIO150_ND_ALE,
+	GPIO149_ND_CLE,
+	GPIO112_ND_RDY0,
+	GPIO160_ND_RDY1,
+};
+
+static void __init jasper_init(void)
+{
+	mfp_config(ARRAY_AND_SIZE(jasper_pin_config));
+
+	/* on-chip devices */
+	mmp2_add_uart(1);
+	mmp2_add_uart(3);
+}
+
+MACHINE_START(MARVELL_JASPER, "Jasper 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       = mmp2_init_irq,
+	.timer          = &mmp2_timer,
+	.init_machine   = jasper_init,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 if ARCH_MMP
 
-menu "Marvell PXA168/910 Implmentations"
+menu "Marvell PXA168/910/MMP2 Implmentations"
 
 config MACH_ASPENITE
 	bool "Marvell's PXA168 Aspenite Development Board"
@@ -16,6 +16,13 @@ config MACH_ZYLONITE2
 	  Say 'Y' here if you want to support the Marvell PXA168-based
 	  Zylonite2 Development Board.
 
+config MACH_AVENGERS_LITE
+	bool "Marvell's PXA168 Avengers Lite Development Board"
+	select CPU_PXA168
+	help
+	  Say 'Y' here if you want to support the Marvell PXA168-based
+	  Avengers Lite Development Board.
+
 config MACH_TAVOREVB
 	bool "Marvell's PXA910 TavorEVB Development Board"
 	select CPU_PXA910
@@ -30,6 +37,26 @@ config MACH_TTC_DKB
 	  Say 'Y' here if you want to support the Marvell PXA910-based
 	  TTC_DKB Development Board.
 
+config MACH_FLINT
+	bool "Marvell's Flint Development Platform"
+	select CPU_MMP2
+	help
+	  Say 'Y' here if you want to support the Marvell MMP2-based
+	  Flint Development Platform.
+	  MMP2-based board can't be co-existed with PXA168-based &
+	  PXA910-based development board. Since MMP2 is compatible to
+	  ARMv6 architecture.
+
+config MACH_MARVELL_JASPER
+	bool "Marvell's Jasper Development Platform"
+	select CPU_MMP2
+	help
+	  Say 'Y' here if you want to support the Marvell MMP2-base
+	  Jasper Development Platform.
+	  MMP2-based board can't be co-existed with PXA168-based &
+	  PXA910-based development board. Since MMP2 is compatible to
+	  ARMv6 architecture.
+
 endmenu
 
 config CPU_PXA168
@@ -44,4 +71,10 @@ config CPU_PXA910
 	help
 	  Select code specific to PXA910
 
+config CPU_MMP2
+	bool
+	select CPU_V6
+	select CPU_32v6K
+	help
+	  Select code specific to MMP2. MMP2 is ARMv6 compatible.
 endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -2,14 +2,18 @@
 # Makefile for Marvell's PXA168 processors line
 #
 
-obj-y				+= common.o clock.o devices.o irq.o time.o
+obj-y				+= common.o clock.o devices.o time.o
 
 # SoC support
-obj-$(CONFIG_CPU_PXA168)	+= pxa168.o
-obj-$(CONFIG_CPU_PXA910)	+= pxa910.o
+obj-$(CONFIG_CPU_PXA168)	+= pxa168.o irq-pxa168.o
+obj-$(CONFIG_CPU_PXA910)	+= pxa910.o irq-pxa168.o
+obj-$(CONFIG_CPU_MMP2)		+= mmp2.o irq-mmp2.o
 
 # board support
 obj-$(CONFIG_MACH_ASPENITE)	+= aspenite.o
 obj-$(CONFIG_MACH_ZYLONITE2)	+= aspenite.o
+obj-$(CONFIG_MACH_AVENGERS_LITE)+= avengers_lite.o
 obj-$(CONFIG_MACH_TAVOREVB)	+= tavorevb.o
 obj-$(CONFIG_MACH_TTC_DKB)	+= ttc_dkb.o
+obj-$(CONFIG_MACH_FLINT)	+= flint.o
+obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/mmp2.c linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/mmp2.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/mmp2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/mmp2.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,123 @@
+/*
+ * linux/arch/arm/mach-mmp/mmp2.c
+ *
+ * code name MMP2
+ *
+ * Copyright (C) 2009 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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.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/mfp.h>
+#include <mach/gpio.h>
+#include <mach/devices.h>
+
+#include "common.h"
+#include "clock.h"
+
+#define MFPR_VIRT_BASE	(APB_VIRT_BASE + 0x1e000)
+
+#define APMASK(i)	(GPIO_REGS_VIRT + BANK_OFF(i) + 0x9c)
+
+static struct mfp_addr_map mmp2_addr_map[] __initdata = {
+	MFP_ADDR(PMIC_INT, 0x2c4),
+
+	MFP_ADDR_END,
+};
+
+void mmp2_clear_pmic_int(void)
+{
+	unsigned long mfpr_pmic, data;
+
+	mfpr_pmic = APB_VIRT_BASE + 0x1e000 + 0x2c4;
+	data = __raw_readl(mfpr_pmic);
+	__raw_writel(data | (1 << 6), mfpr_pmic);
+	__raw_writel(data, mfpr_pmic);
+}
+
+static void __init mmp2_init_gpio(void)
+{
+	int i;
+
+	/* enable GPIO clock */
+	__raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_MMP2_GPIO);
+
+	/* unmask GPIO edge detection for all 6 banks -- APMASKx */
+	for (i = 0; i < 6; i++)
+		__raw_writel(0xffffffff, APMASK(i));
+
+	pxa_init_gpio(IRQ_MMP2_GPIO, 0, 167, NULL);
+}
+
+void __init mmp2_init_irq(void)
+{
+	mmp2_init_icu();
+	mmp2_init_gpio();
+}
+
+/* APB peripheral clocks */
+static APBC_CLK(uart1, MMP2_UART1, 1, 26000000);
+static APBC_CLK(uart2, MMP2_UART2, 1, 26000000);
+static APBC_CLK(uart3, MMP2_UART3, 1, 26000000);
+static APBC_CLK(uart4, MMP2_UART4, 1, 26000000);
+static APBC_CLK(twsi1, MMP2_TWSI1, 0, 26000000);
+static APBC_CLK(twsi2, MMP2_TWSI2, 0, 26000000);
+static APBC_CLK(twsi3, MMP2_TWSI3, 0, 26000000);
+static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000);
+static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000);
+static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000);
+static APBC_CLK(rtc, MMP2_RTC, 0, 32768);
+
+static APMU_CLK(nand, NAND, 0xbf, 100000000);
+
+static struct clk_lookup mmp2_clkregs[] = {
+	INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
+	INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
+	INIT_CLKREG(&clk_uart3, "pxa2xx-uart.2", NULL),
+	INIT_CLKREG(&clk_uart4, "pxa2xx-uart.3", NULL),
+	INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.0", NULL),
+	INIT_CLKREG(&clk_twsi2, "pxa2xx-i2c.1", NULL),
+	INIT_CLKREG(&clk_twsi3, "pxa2xx-i2c.2", NULL),
+	INIT_CLKREG(&clk_twsi4, "pxa2xx-i2c.3", NULL),
+	INIT_CLKREG(&clk_twsi5, "pxa2xx-i2c.4", NULL),
+	INIT_CLKREG(&clk_twsi6, "pxa2xx-i2c.5", NULL),
+	INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
+};
+
+static int __init mmp2_init(void)
+{
+	if (cpu_is_mmp2()) {
+		mfp_init_base(MFPR_VIRT_BASE);
+		mfp_init_addr(mmp2_addr_map);
+		clks_register(ARRAY_AND_SIZE(mmp2_clkregs));
+	}
+
+	return 0;
+}
+postcore_initcall(mmp2_init);
+
+/* on-chip devices */
+MMP2_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4030000, 0x30, 4, 5);
+MMP2_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4017000, 0x30, 20, 21);
+MMP2_DEVICE(uart3, "pxa2xx-uart", 2, UART3, 0xd4018000, 0x30, 22, 23);
+MMP2_DEVICE(uart4, "pxa2xx-uart", 3, UART4, 0xd4016000, 0x30, 18, 19);
+MMP2_DEVICE(twsi1, "pxa2xx-i2c", 0, TWSI1, 0xd4011000, 0x70);
+MMP2_DEVICE(twsi2, "pxa2xx-i2c", 1, TWSI2, 0xd4031000, 0x70);
+MMP2_DEVICE(twsi3, "pxa2xx-i2c", 2, TWSI3, 0xd4032000, 0x70);
+MMP2_DEVICE(twsi4, "pxa2xx-i2c", 3, TWSI4, 0xd4033000, 0x70);
+MMP2_DEVICE(twsi5, "pxa2xx-i2c", 4, TWSI5, 0xd4033800, 0x70);
+MMP2_DEVICE(twsi6, "pxa2xx-i2c", 5, TWSI6, 0xd4034000, 0x70);
+MMP2_DEVICE(nand, "pxa3xx-nand", -1, NAND, 0xd4283000, 0x100, 28, 29);
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/pxa168.c linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/pxa168.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/pxa168.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/pxa168.c	2010-05-16 17:17:36.000000000 -0400
@@ -94,7 +94,7 @@ static int __init pxa168_init(void)
 		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));
+		clkdev_add_table(ARRAY_AND_SIZE(pxa168_clkregs));
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/pxa910.c linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/pxa910.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/pxa910.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/pxa910.c	2010-05-16 17:17:36.000000000 -0400
@@ -131,7 +131,7 @@ static int __init pxa910_init(void)
 		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));
+		clkdev_add_table(ARRAY_AND_SIZE(pxa910_clkregs));
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/time.c linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/time.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mmp/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,10 @@
 
 #include <mach/addr-map.h>
 #include <mach/regs-timers.h>
+#include <mach/regs-apbc.h>
 #include <mach/irqs.h>
+#include <mach/cputype.h>
+#include <asm/mach/time.h>
 
 #include "clock.h"
 
@@ -158,7 +161,7 @@ static void __init timer_config(void)
 
 	__raw_writel(cer & ~0x1, TIMERS_VIRT_BASE + TMR_CER); /* disable */
 
-	ccr &= TMR_CCR_CS_0(0x3);
+	ccr &= (cpu_is_mmp2()) ? TMR_CCR_CS_0(0) : TMR_CCR_CS_0(3);
 	__raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR);
 
 	/* free-running mode */
@@ -197,3 +200,24 @@ void __init timer_init(int irq)
 	clocksource_register(&cksrc);
 	clockevents_register_device(&ckevt);
 }
+
+static void __init mmp2_timer_init(void)
+{
+	unsigned long clk_rst;
+
+	__raw_writel(APBC_APBCLK | APBC_RST, APBC_MMP2_TIMERS);
+
+	/*
+	 * enable bus/functional clock, enable 6.5MHz (divider 4),
+	 * release reset
+	 */
+	clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1);
+	__raw_writel(clk_rst, APBC_MMP2_TIMERS);
+
+	timer_init(IRQ_MMP2_TIMER1);
+}
+
+struct sys_timer mmp2_timer = {
+	.init	= mmp2_timer_init,
+};
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-msm/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-msm/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-msm/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-msm/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -20,7 +20,7 @@
 #include <mach/msm_iomap.h>
 
 #ifdef CONFIG_MSM_DEBUG_UART
-	.macro	addruart,rx
+	.macro	addruart, rx, tmp
 	@ see if the MMU is enabled and select appropriate base address
 	mrc	p15, 0, \rx, c1, c0
 	tst	\rx, #1
@@ -40,7 +40,7 @@
 	beq	1001b
 	.endm
 #else
-	.macro	addruart,rx
+	.macro	addruart, rx, tmp
 	.endm
 
 	.macro	senduart,rd,rx
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-msm/io.c linux-libre-2.6.34-gnu1/arch/arm/mach-msm/io.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-msm/io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-msm/io.c	2010-05-16 17:17:36.000000000 -0400
@@ -76,5 +76,6 @@ __msm_ioremap(unsigned long phys_addr, s
 			mtype = MT_DEVICE_NONSHARED;
 	}
 
-	return __arm_ioremap(phys_addr, size, mtype);
+	return __arm_ioremap_caller(phys_addr, size, mtype,
+		__builtin_return_address(0));
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,155 @@
+/*
+ * arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
+ *
+ * Buffalo WXL (Terastation Duo) Setup routines
+ *
+ * sebastien requiem <sebastien@requiem.fr>
+ *
+ * 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 <linux/i2c.h>
+#include <mach/mv78xx0.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include "common.h"
+#include "mpp.h"
+
+
+/* This arch has 2 Giga Ethernet */
+
+static struct mv643xx_eth_platform_data db78x00_ge00_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct mv643xx_eth_platform_data db78x00_ge01_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
+};
+
+
+/* 2 SATA controller supporting HotPlug */
+
+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 unsigned int wxl_mpp_config[] __initdata = {
+	MPP0_GE1_TXCLK,
+	MPP1_GE1_TXCTL,
+	MPP2_GE1_RXCTL,
+	MPP3_GE1_RXCLK,
+	MPP4_GE1_TXD0,
+	MPP5_GE1_TXD1,
+	MPP6_GE1_TXD2,
+	MPP7_GE1_TXD3,
+	MPP8_GE1_RXD0,
+	MPP9_GE1_RXD1,
+	MPP10_GE1_RXD2,
+	MPP11_GE1_RXD3,
+	MPP12_GPIO,
+	MPP13_SYSRST_OUTn,
+	MPP14_SATA1_ACTn,
+	MPP15_SATA0_ACTn,
+	MPP16_GPIO,
+	MPP17_GPIO,
+	MPP18_GPIO,
+	MPP19_GPIO,
+	MPP20_GPIO,
+	MPP21_GPIO,
+	MPP22_GPIO,
+	MPP23_GPIO,
+	MPP24_UA2_TXD,
+	MPP25_UA2_RXD,
+	MPP26_UA2_CTSn,
+	MPP27_UA2_RTSn,
+	MPP28_GPIO,
+	MPP29_SYSRST_OUTn,
+	MPP30_GPIO,
+	MPP31_GPIO,
+	MPP32_GPIO,
+	MPP33_GPIO,
+	MPP34_GPIO,
+	MPP35_GPIO,
+	MPP36_GPIO,
+	MPP37_GPIO,
+	MPP38_GPIO,
+	MPP39_GPIO,
+	MPP40_UNUSED,
+	MPP41_UNUSED,
+	MPP42_UNUSED,
+	MPP43_UNUSED,
+	MPP44_UNUSED,
+	MPP45_UNUSED,
+	MPP46_UNUSED,
+	MPP47_UNUSED,
+	MPP48_SATA1_ACTn,
+	MPP49_SATA0_ACTn,
+	0
+};
+
+
+static void __init wxl_init(void)
+{
+	/*
+	 * Basic MV78xx0 setup. Needs to be called early.
+	 */
+	mv78xx0_init();
+	mv78xx0_mpp_conf(wxl_mpp_config);
+
+	/*
+	 * Partition on-chip peripherals between the two CPU cores.
+	 */
+	mv78xx0_ehci0_init();
+	mv78xx0_ehci1_init();
+	mv78xx0_ehci2_init();
+	mv78xx0_ge00_init(&db78x00_ge00_data);
+	mv78xx0_ge01_init(&db78x00_ge01_data);
+	mv78xx0_sata_init(&db78x00_sata_data);
+	mv78xx0_uart0_init();
+	mv78xx0_uart1_init();
+	mv78xx0_uart2_init();
+	mv78xx0_uart3_init();
+	mv78xx0_i2c_init();
+	i2c_register_board_info(0, &db78x00_i2c_rtc, 1);
+}
+
+static int __init wxl_pci_init(void)
+{
+	if (machine_is_terastation_wxl()) {
+		/*
+		 * Assign the x16 PCIe slot on the board to CPU core
+		 * #0, and let CPU core #1 have the four x1 slots.
+		 */
+		if (mv78xx0_core_index() == 0)
+			mv78xx0_pcie_init(0, 1);
+		else
+			mv78xx0_pcie_init(1, 0);
+	}
+
+	return 0;
+}
+subsys_initcall(wxl_pci_init);
+
+MACHINE_START(TERASTATION_WXL, "Buffalo Nas WXL")
+	/* Maintainer: Sebastien Requiem <sebastien@requiem.fr> */
+	.phys_io	= MV78XX0_REGS_PHYS_BASE,
+	.io_pg_offst	= ((MV78XX0_REGS_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= wxl_init,
+	.map_io		= mv78xx0_map_io,
+	.init_irq	= mv78xx0_init_irq,
+	.timer		= &mv78xx0_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mv78xx0/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-mv78xx0/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mv78xx0/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mv78xx0/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,7 @@
 
 #include <mach/mv78xx0.h>
 
-	.macro	addruart,rx
+	.macro	addruart, rx, tmp
 	mrc	p15, 0, \rx, c1, c0
 	tst	\rx, #1					@ MMU enabled?
 	ldreq	\rx, =MV78XX0_REGS_PHYS_BASE
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mv78xx0/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-mv78xx0/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mv78xx0/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mv78xx0/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,4 +2,4 @@
  * arch/arm/mach-mv78xx0/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END	0xfe000000
+#define VMALLOC_END	0xfe000000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mv78xx0/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-mv78xx0/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mv78xx0/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mv78xx0/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,12 @@ config MACH_RD78X00_MASA
 	  Say 'Y' here if you want your kernel to support the
 	  Marvell RD-78x00-mASA Reference Design.
 
+config MACH_TERASTATION_WXL
+	bool "Buffalo WLX (Terastation Duo) NAS"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Buffalo WXL Nas.
+
 endmenu
 
 endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mv78xx0/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-mv78xx0/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mv78xx0/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mv78xx0/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,3 +1,4 @@
-obj-y				+= common.o addr-map.o irq.o pcie.o
+obj-y				+= common.o addr-map.o mpp.o irq.o pcie.o
 obj-$(CONFIG_MACH_DB78X00_BP)	+= db78x00-bp-setup.o
 obj-$(CONFIG_MACH_RD78X00_MASA)	+= rd78x00-masa-setup.o
+obj-$(CONFIG_MACH_TERASTATION_WXL) += buffalo-wxl-setup.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mv78xx0/mpp.c linux-libre-2.6.34-gnu1/arch/arm/mach-mv78xx0/mpp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mv78xx0/mpp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mv78xx0/mpp.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,96 @@
+/*
+ * arch/arm/mach-mv78x00/mpp.c
+ *
+ * MPP functions for Marvell MV78x00 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 mv78xx0_variant(void)
+{
+	u32 dev, rev;
+
+	mv78xx0_pcie_id(&dev, &rev);
+
+	if (dev == MV78100_DEV_ID && rev >= MV78100_REV_A0)
+		return MPP_78100_A0_MASK;
+
+	printk(KERN_ERR "MPP setup: unknown mv78x00 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 mv78xx0_mpp_conf(unsigned int *mpp_list)
+{
+	u32 mpp_ctrl[MPP_NR_REGS];
+	unsigned int variant_mask;
+	int i;
+
+	variant_mask = mv78xx0_variant();
+	if (!variant_mask)
+		return;
+
+	/* Initialize gpiolib. */
+	orion_gpio_init();
+
+	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 "mv78xx0_mpp_conf: invalid MPP "
+					"number (%u)\n", num);
+			continue;
+		}
+		if (!(*mpp_list & variant_mask)) {
+			printk(KERN_WARNING
+					"mv78xx0_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.33-gnu1/arch/arm/mach-mv78xx0/mpp.h linux-libre-2.6.34-gnu1/arch/arm/mach-mv78xx0/mpp.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mv78xx0/mpp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mv78xx0/mpp.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,347 @@
+/*
+ * linux/arch/arm/mach-mv78xx0/mpp.h -- Multi Purpose Pins
+ *
+ *
+ * sebastien requiem <sebastien@requiem.fr>
+ *
+ * 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 __MV78X00_MPP_H
+#define __MV78X00_MPP_H
+
+#define MPP(_num, _sel, _in, _out, _78100_A0) (\
+    /* MPP number */        ((_num) & 0xff) | \
+    /* MPP select value */        (((_sel) & 0xf) << 8) | \
+    /* may be input signal */    ((!!(_in)) << 12) | \
+    /* may be output signal */    ((!!(_out)) << 13) | \
+    /* available on A0 */    ((!!(_78100_A0)) << 14))
+
+#define MPP_NUM(x)    ((x) & 0xff)
+#define MPP_SEL(x)    (((x) >> 8) & 0xf)
+
+                /*   num sel  i  o  78100_A0  */
+
+#define MPP_INPUT_MASK        MPP(0, 0x0, 1, 0, 0)
+#define MPP_OUTPUT_MASK        MPP(0, 0x0, 0, 1, 0)
+
+#define MPP_78100_A0_MASK    MPP(0, 0x0, 0, 0, 1)
+
+#define MPP0_GPIO        MPP(0, 0x0, 1, 1, 1)
+#define MPP0_GE0_COL        MPP(0, 0x1, 1, 0, 1)
+#define MPP0_GE1_TXCLK        MPP(0, 0x2, 0, 1, 1)
+#define MPP0_UNUSED        MPP(0, 0x3, 0, 0, 1)
+
+#define MPP1_GPIO        MPP(1, 0x0, 1, 1, 1)
+#define MPP1_GE0_RXERR        MPP(1, 0x1, 1, 0, 1)
+#define MPP1_GE1_TXCTL        MPP(1, 0x2, 0, 1, 1)
+#define MPP1_UNUSED        MPP(1, 0x3, 0, 0, 1)
+
+#define MPP2_GPIO        MPP(2, 0x0, 1, 1, 1)
+#define MPP2_GE0_CRS        MPP(2, 0x1, 1, 0, 1)
+#define MPP2_GE1_RXCTL        MPP(2, 0x2, 1, 0, 1)
+#define MPP2_UNUSED        MPP(2, 0x3, 0, 0, 1)
+
+#define MPP3_GPIO        MPP(3, 0x0, 1, 1, 1)
+#define MPP3_GE0_TXERR        MPP(3, 0x1, 0, 1, 1)
+#define MPP3_GE1_RXCLK        MPP(3, 0x2, 1, 0, 1)
+#define MPP3_UNUSED        MPP(3, 0x3, 0, 0, 1)
+
+#define MPP4_GPIO        MPP(4, 0x0, 1, 1, 1)
+#define MPP4_GE0_TXD4        MPP(4, 0x1, 0, 1, 1)
+#define MPP4_GE1_TXD0        MPP(4, 0x2, 0, 1, 1)
+#define MPP4_UNUSED        MPP(4, 0x3, 0, 0, 1)
+
+#define MPP5_GPIO        MPP(5, 0x0, 1, 1, 1)
+#define MPP5_GE0_TXD5        MPP(5, 0x1, 0, 1, 1)
+#define MPP5_GE1_TXD1        MPP(5, 0x2, 0, 1, 1)
+#define MPP5_UNUSED        MPP(5, 0x3, 0, 0, 1)
+
+#define MPP6_GPIO        MPP(6, 0x0, 1, 1, 1)
+#define MPP6_GE0_TXD6        MPP(6, 0x1, 0, 1, 1)
+#define MPP6_GE1_TXD2        MPP(6, 0x2, 0, 1, 1)
+#define MPP6_UNUSED        MPP(6, 0x3, 0, 0, 1)
+
+#define MPP7_GPIO        MPP(7, 0x0, 1, 1, 1)
+#define MPP7_GE0_TXD7        MPP(7, 0x1, 0, 1, 1)
+#define MPP7_GE1_TXD3        MPP(7, 0x2, 0, 1, 1)
+#define MPP7_UNUSED        MPP(7, 0x3, 0, 0, 1)
+
+#define MPP8_GPIO        MPP(8, 0x0, 1, 1, 1)
+#define MPP8_GE0_RXD4        MPP(8, 0x1, 1, 0, 1)
+#define MPP8_GE1_RXD0        MPP(8, 0x2, 1, 0, 1)
+#define MPP8_UNUSED        MPP(8, 0x3, 0, 0, 1)
+
+#define MPP9_GPIO        MPP(9, 0x0, 1, 1, 1)
+#define MPP9_GE0_RXD5        MPP(9, 0x1, 1, 0, 1)
+#define MPP9_GE1_RXD1        MPP(9, 0x2, 1, 0, 1)
+#define MPP9_UNUSED        MPP(9, 0x3, 0, 0, 1)
+
+#define MPP10_GPIO        MPP(10, 0x0, 1, 1, 1)
+#define MPP10_GE0_RXD6        MPP(10, 0x1, 1, 0, 1)
+#define MPP10_GE1_RXD2        MPP(10, 0x2, 1, 0, 1)
+#define MPP10_UNUSED        MPP(10, 0x3, 0, 0, 1)
+
+#define MPP11_GPIO        MPP(11, 0x0, 1, 1, 1)
+#define MPP11_GE0_RXD7        MPP(11, 0x1, 1, 0, 1)
+#define MPP11_GE1_RXD3        MPP(11, 0x2, 1, 0, 1)
+#define MPP11_UNUSED        MPP(11, 0x3, 0, 0, 1)
+
+#define MPP12_GPIO        MPP(12, 0x0, 1, 1, 1)
+#define MPP12_M_BB        MPP(12, 0x3, 1, 0, 1)
+#define MPP12_UA0_CTSn        MPP(12, 0x4, 1, 0, 1)
+#define MPP12_NAND_FLASH_REn0    MPP(12, 0x5, 0, 1, 1)
+#define MPP12_TDM0_SCSn        MPP(12, 0X6, 0, 1, 1)
+#define MPP12_UNUSED        MPP(12, 0x1, 0, 0, 1)
+
+#define MPP13_GPIO        MPP(13, 0x0, 1, 1, 1)
+#define MPP13_SYSRST_OUTn    MPP(13, 0x3, 0, 1, 1)
+#define MPP13_UA0_RTSn        MPP(13, 0x4, 0, 1, 1)
+#define MPP13_NAN_FLASH_WEn0    MPP(13, 0x5, 0, 1, 1)
+#define MPP13_TDM_SCLK        MPP(13, 0x6, 0, 1, 1)
+#define MPP13_UNUSED        MPP(13, 0x1, 0, 0, 1)
+
+#define MPP14_GPIO        MPP(14, 0x0, 1, 1, 1)
+#define MPP14_SATA1_ACTn    MPP(14, 0x3, 0, 1, 1)
+#define MPP14_UA1_CTSn        MPP(14, 0x4, 1, 0, 1)
+#define MPP14_NAND_FLASH_REn1    MPP(14, 0x5, 0, 1, 1)
+#define MPP14_TDM_SMOSI        MPP(14, 0x6, 0, 1, 1)
+#define MPP14_UNUSED        MPP(14, 0x1, 0, 0, 1)
+
+#define MPP15_GPIO        MPP(15, 0x0, 1, 1, 1)
+#define MPP15_SATA0_ACTn    MPP(15, 0x3, 0, 1, 1)
+#define MPP15_UA1_RTSn        MPP(15, 0x4, 0, 1, 1)
+#define MPP15_NAND_FLASH_WEn1    MPP(15, 0x5, 0, 1, 1)
+#define MPP15_TDM_SMISO        MPP(15, 0x6, 1, 0, 1)
+#define MPP15_UNUSED        MPP(15, 0x1, 0, 0, 1)
+
+#define MPP16_GPIO        MPP(16, 0x0, 1, 1, 1)
+#define MPP16_SATA1_PRESENTn    MPP(16, 0x3, 0, 1, 1)
+#define MPP16_UA2_TXD        MPP(16, 0x4, 0, 1, 1)
+#define MPP16_NAND_FLASH_REn3    MPP(16, 0x5, 0, 1, 1)
+#define MPP16_TDM_INTn        MPP(16, 0x6, 1, 0, 1)
+#define MPP16_UNUSED        MPP(16, 0x1, 0, 0, 1)
+
+
+#define MPP17_GPIO        MPP(17, 0x0, 1, 1, 1)
+#define MPP17_SATA0_PRESENTn    MPP(17, 0x3, 0, 1, 1)
+#define MPP17_UA2_RXD        MPP(17, 0x4, 1, 0, 1)
+#define MPP17_NAND_FLASH_WEn3    MPP(17, 0x5, 0, 1, 1)
+#define MPP17_TDM_RSTn        MPP(17, 0x6, 0, 1, 1)
+#define MPP17_UNUSED        MPP(17, 0x1, 0, 0, 1)
+
+
+#define MPP18_GPIO        MPP(18, 0x0, 1, 1, 1)
+#define MPP18_UA0_CTSn        MPP(18, 0x4, 1, 0, 1)
+#define MPP18_BOOT_FLASH_REn    MPP(18, 0x5, 0, 1, 1)
+#define MPP18_UNUSED        MPP(18, 0x1, 0, 0, 1)
+
+
+
+#define MPP19_GPIO        MPP(19, 0x0, 1, 1, 1)
+#define MPP19_UA0_CTSn        MPP(19, 0x4, 0, 1, 1)
+#define MPP19_BOOT_FLASH_WEn    MPP(19, 0x5, 0, 1, 1)
+#define MPP19_UNUSED        MPP(19, 0x1, 0, 0, 1)
+
+
+#define MPP20_GPIO        MPP(20, 0x0, 1, 1, 1)
+#define MPP20_UA1_CTSs        MPP(20, 0x4, 1, 0, 1)
+#define MPP20_TDM_PCLK        MPP(20, 0x6, 1, 1, 0)
+#define MPP20_UNUSED        MPP(20, 0x1, 0, 0, 1)
+
+
+
+#define MPP21_GPIO        MPP(21, 0x0, 1, 1, 1)
+#define MPP21_UA1_CTSs        MPP(21, 0x4, 0, 1, 1)
+#define MPP21_TDM_FSYNC        MPP(21, 0x6, 1, 1, 0)
+#define MPP21_UNUSED        MPP(21, 0x1, 0, 0, 1)
+
+
+
+#define MPP22_GPIO        MPP(22, 0x0, 1, 1, 1)
+#define MPP22_UA3_TDX        MPP(22, 0x4, 0, 1, 1)
+#define MPP22_NAND_FLASH_REn2    MPP(22, 0x5, 0, 1, 1)
+#define MPP22_TDM_DRX        MPP(22, 0x6, 1, 0, 1)
+#define MPP22_UNUSED        MPP(22, 0x1, 0, 0, 1)
+
+
+
+#define MPP23_GPIO        MPP(23, 0x0, 1, 1, 1)
+#define MPP23_UA3_RDX        MPP(23, 0x4, 1, 0, 1)
+#define MPP23_NAND_FLASH_WEn2    MPP(23, 0x5, 0, 1, 1)
+#define MPP23_TDM_DTX        MPP(23, 0x6, 0, 1, 1)
+#define MPP23_UNUSED        MPP(23, 0x1, 0, 0, 1)
+
+
+#define MPP24_GPIO        MPP(24, 0x0, 1, 1, 1)
+#define MPP24_UA2_TXD        MPP(24, 0x4, 0, 1, 1)
+#define MPP24_TDM_INTn        MPP(24, 0x6, 1, 0, 1)
+#define MPP24_UNUSED        MPP(24, 0x1, 0, 0, 1)
+
+
+#define MPP25_GPIO        MPP(25, 0x0, 1, 1, 1)
+#define MPP25_UA2_RXD        MPP(25, 0x4, 1, 0, 1)
+#define MPP25_TDM_RSTn        MPP(25, 0x6, 0, 1, 1)
+#define MPP25_UNUSED        MPP(25, 0x1, 0, 0, 1)
+
+
+#define MPP26_GPIO        MPP(26, 0x0, 1, 1, 1)
+#define MPP26_UA2_CTSn        MPP(26, 0x4, 1, 0, 1)
+#define MPP26_TDM_PCLK        MPP(26, 0x6, 1, 1, 1)
+#define MPP26_UNUSED        MPP(26, 0x1, 0, 0, 1)
+
+
+#define MPP27_GPIO        MPP(27, 0x0, 1, 1, 1)
+#define MPP27_UA2_RTSn        MPP(27, 0x4, 0, 1, 1)
+#define MPP27_TDM_FSYNC        MPP(27, 0x6, 1, 1, 1)
+#define MPP27_UNUSED        MPP(27, 0x1, 0, 0, 1)
+
+
+#define MPP28_GPIO        MPP(28, 0x0, 1, 1, 1)
+#define MPP28_UA3_TXD        MPP(28, 0x4, 0, 1, 1)
+#define MPP28_TDM_DRX        MPP(28, 0x6, 1, 0, 1)
+#define MPP28_UNUSED        MPP(28, 0x1, 0, 0, 1)
+
+#define MPP29_GPIO        MPP(29, 0x0, 1, 1, 1)
+#define MPP29_UA3_RXD        MPP(29, 0x4, 1, 0, 1)
+#define MPP29_SYSRST_OUTn    MPP(29, 0x5, 0, 1, 1)
+#define MPP29_TDM_DTX        MPP(29, 0x6, 0, 1, 1)
+#define MPP29_UNUSED        MPP(29, 0x1, 0, 0, 1)
+
+#define MPP30_GPIO        MPP(30, 0x0, 1, 1, 1)
+#define MPP30_UA3_CTSn        MPP(30, 0x4, 1, 0, 1)
+#define MPP30_UNUSED        MPP(30, 0x1, 0, 0, 1)
+
+#define MPP31_GPIO        MPP(31, 0x0, 1, 1, 1)
+#define MPP31_UA3_RTSn        MPP(31, 0x4, 0, 1, 1)
+#define MPP31_TDM1_SCSn        MPP(31, 0x6, 0, 1, 1)
+#define MPP31_UNUSED        MPP(31, 0x1, 0, 0, 1)
+
+
+#define MPP32_GPIO        MPP(32, 0x1, 1, 1, 1)
+#define MPP32_UA3_TDX        MPP(32, 0x4, 0, 1, 1)
+#define MPP32_SYSRST_OUTn    MPP(32, 0x5, 0, 1, 1)
+#define MPP32_TDM0_RXQ        MPP(32, 0x6, 0, 1, 1)
+#define MPP32_UNUSED        MPP(32, 0x3, 0, 0, 1)
+
+
+#define MPP33_GPIO        MPP(33, 0x1, 1, 1, 1)
+#define MPP33_UA3_RDX        MPP(33, 0x4, 1, 0, 1)
+#define MPP33_TDM0_TXQ        MPP(33, 0x6, 0, 1, 1)
+#define MPP33_UNUSED        MPP(33, 0x3, 0, 0, 1)
+
+
+
+#define MPP34_GPIO        MPP(34, 0x1, 1, 1, 1)
+#define MPP34_UA2_TDX        MPP(34, 0x4, 0, 1, 1)
+#define MPP34_TDM1_RXQ        MPP(34, 0x6, 0, 1, 1)
+#define MPP34_UNUSED        MPP(34, 0x3, 0, 0, 1)
+
+
+
+#define MPP35_GPIO        MPP(35, 0x1, 1, 1, 1)
+#define MPP35_UA2_RDX        MPP(35, 0x4, 1, 0, 1)
+#define MPP35_TDM1_TXQ        MPP(35, 0x6, 0, 1, 1)
+#define MPP35_UNUSED        MPP(35, 0x3, 0, 0, 1)
+
+#define MPP36_GPIO        MPP(36, 0x1, 1, 1, 1)
+#define MPP36_UA0_CTSn        MPP(36, 0x2, 1, 0, 1)
+#define MPP36_UA2_TDX        MPP(36, 0x4, 0, 1, 1)
+#define MPP36_TDM0_SCSn        MPP(36, 0x6, 0, 1, 1)
+#define MPP36_UNUSED        MPP(36, 0x3, 0, 0, 1)
+
+
+#define MPP37_GPIO        MPP(37, 0x1, 1, 1, 1)
+#define MPP37_UA0_RTSn        MPP(37, 0x2, 0, 1, 1)
+#define MPP37_UA2_RXD        MPP(37, 0x4, 1, 0, 1)
+#define MPP37_SYSRST_OUTn    MPP(37, 0x5, 0, 1, 1)
+#define MPP37_TDM_SCLK        MPP(37, 0x6, 0, 1, 1)
+#define MPP37_UNUSED        MPP(37, 0x3, 0, 0, 1)
+
+
+
+
+#define MPP38_GPIO        MPP(38, 0x1, 1, 1, 1)
+#define MPP38_UA1_CTSn        MPP(38, 0x2, 1, 0, 1)
+#define MPP38_UA3_TXD        MPP(38, 0x4, 0, 1, 1)
+#define MPP38_SYSRST_OUTn    MPP(38, 0x5, 0, 1, 1)
+#define MPP38_TDM_SMOSI        MPP(38, 0x6, 0, 1, 1)
+#define MPP38_UNUSED        MPP(38, 0x3, 0, 0, 1)
+
+
+
+
+#define MPP39_GPIO        MPP(39, 0x1, 1, 1, 1)
+#define MPP39_UA1_RTSn        MPP(39, 0x2, 0, 1, 1)
+#define MPP39_UA3_RXD        MPP(39, 0x4, 1, 0, 1)
+#define MPP39_SYSRST_OUTn    MPP(39, 0x5, 0, 1, 1)
+#define MPP39_TDM_SMISO        MPP(39, 0x6, 1, 0, 1)
+#define MPP39_UNUSED        MPP(39, 0x3, 0, 0, 1)
+
+
+
+#define MPP40_GPIO        MPP(40, 0x1, 1, 1, 1)
+#define MPP40_TDM_INTn        MPP(40, 0x6, 1, 0, 1)
+#define MPP40_UNUSED        MPP(40, 0x0, 0, 0, 1)
+
+
+
+#define MPP41_GPIO        MPP(41, 0x1, 1, 1, 1)
+#define MPP41_TDM_RSTn        MPP(41, 0x6, 0, 1, 1)
+#define MPP41_UNUSED        MPP(41, 0x0, 0, 0, 1)
+
+
+
+#define MPP42_GPIO        MPP(42, 0x1, 1, 1, 1)
+#define MPP42_TDM_PCLK        MPP(42, 0x6, 1, 1, 1)
+#define MPP42_UNUSED        MPP(42, 0x0, 0, 0, 1)
+
+
+
+#define MPP43_GPIO        MPP(43, 0x1, 1, 1, 1)
+#define MPP43_TDM_FSYNC        MPP(43, 0x6, 1, 1, 1)
+#define MPP43_UNUSED        MPP(43, 0x0, 0, 0, 1)
+
+
+
+#define MPP44_GPIO        MPP(44, 0x1, 1, 1, 1)
+#define MPP44_TDM_DRX        MPP(44, 0x6, 1, 0, 1)
+#define MPP44_UNUSED        MPP(44, 0x0, 0, 0, 1)
+
+
+
+#define MPP45_GPIO        MPP(45, 0x1, 1, 1, 1)
+#define MPP45_SATA0_ACTn    MPP(45, 0x3, 0, 1, 1)
+#define MPP45_TDM_DRX        MPP(45, 0x6, 0, 1, 1)
+#define MPP45_UNUSED        MPP(45, 0x0, 0, 0, 1)
+
+
+#define MPP46_GPIO        MPP(46, 0x1, 1, 1, 1)
+#define MPP46_TDM_SCSn        MPP(46, 0x6, 0, 1, 1)
+#define MPP46_UNUSED        MPP(46, 0x0, 0, 0, 1)
+
+
+#define MPP47_GPIO        MPP(47, 0x1, 1, 1, 1)
+#define MPP47_UNUSED        MPP(47, 0x0, 0, 0, 1)
+
+
+
+#define MPP48_GPIO        MPP(48, 0x1, 1, 1, 1)
+#define MPP48_SATA1_ACTn    MPP(48, 0x3, 0, 1, 1)
+#define MPP48_UNUSED        MPP(48, 0x2, 0, 0, 1)
+
+
+
+#define MPP49_GPIO        MPP(49, 0x1, 1, 1, 1)
+#define MPP49_SATA0_ACTn    MPP(49, 0x3, 0, 1, 1)
+#define MPP49_M_BB        MPP(49, 0x4, 1, 0, 1)
+#define MPP49_UNUSED        MPP(49, 0x2, 0, 0, 1)
+
+
+#define MPP_MAX            49
+
+void mv78xx0_mpp_conf(unsigned int *mpp_list);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx1/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx1/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx1/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx1/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -570,7 +570,6 @@ static struct clk_lookup lookups[] __ini
 int __init mx1_clocks_init(unsigned long fref)
 {
 	unsigned int reg;
-	int i;
 
 	/* disable clocks we are able to */
 	__raw_writel(0, SCM_GCCR);
@@ -592,8 +591,7 @@ int __init mx1_clocks_init(unsigned long
 	reg = (reg & CCM_CSCR_CLKO_MASK) >> CCM_CSCR_CLKO_OFFSET;
 	clko_clk.parent = (struct clk *)clko_clocks[reg];
 
-	for (i = 0; i < ARRAY_SIZE(lookups); i++)
-		clkdev_add(&lookups[i]);
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	clk_enable(&hclk);
 	clk_enable(&fclk);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx1/mach-mx1ads.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx1/mach-mx1ads.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx1/mach-mx1ads.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx1/mach-mx1ads.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,165 @@
+/*
+ * arch/arm/mach-imx/mach-mx1ads.c
+ *
+ * Initially based on:
+ *	linux-2.6.7-imx/arch/arm/mach-imx/scb9328.c
+ *	Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
+ *
+ * 2004 (c) MontaVista Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.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/i2c.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx1.h>
+#include <mach/irqs.h>
+
+#include "devices.h"
+
+static int mx1ads_pins[] = {
+	/* UART1 */
+	PC9_PF_UART1_CTS,
+	PC10_PF_UART1_RTS,
+	PC11_PF_UART1_TXD,
+	PC12_PF_UART1_RXD,
+	/* UART2 */
+	PB28_PF_UART2_CTS,
+	PB29_PF_UART2_RTS,
+	PB30_PF_UART2_TXD,
+	PB31_PF_UART2_RXD,
+	/* I2C */
+	PA15_PF_I2C_SDA,
+	PA16_PF_I2C_SCL,
+	/* SPI */
+	PC13_PF_SPI1_SPI_RDY,
+	PC14_PF_SPI1_SCLK,
+	PC15_PF_SPI1_SS,
+	PC16_PF_SPI1_MISO,
+	PC17_PF_SPI1_MOSI,
+};
+
+/*
+ * UARTs platform data
+ */
+
+static struct imxuart_platform_data uart_pdata[] = {
+	{
+		.flags = IMXUART_HAVE_RTSCTS,
+	}, {
+		.flags = IMXUART_HAVE_RTSCTS,
+	},
+};
+
+/*
+ * Physmap flash
+ */
+
+static struct physmap_flash_data mx1ads_flash_data = {
+	.width		= 4,		/* bankwidth in bytes */
+};
+
+static struct resource flash_resource = {
+	.start	= IMX_CS0_PHYS,
+	.end	= IMX_CS0_PHYS + SZ_32M - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device = {
+	.name	= "physmap-flash",
+	.id	= 0,
+	.resource = &flash_resource,
+	.num_resources = 1,
+};
+
+/*
+ * I2C
+ */
+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,
+};
+
+static struct i2c_board_info mx1ads_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("pcf8575", 0x22),
+		.platform_data = &pcf857x_data[0],
+	}, {
+		I2C_BOARD_INFO("pcf8575", 0x24),
+		.platform_data = &pcf857x_data[1],
+	},
+};
+
+/*
+ * Board init
+ */
+static void __init mx1ads_init(void)
+{
+	mxc_gpio_setup_multiple_pins(mx1ads_pins,
+		ARRAY_SIZE(mx1ads_pins), "mx1ads");
+
+	/* UART */
+	mxc_register_device(&imx_uart1_device, &uart_pdata[0]);
+	mxc_register_device(&imx_uart2_device, &uart_pdata[1]);
+
+	/* 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)
+{
+	mx1_clocks_init(32000);
+}
+
+struct sys_timer mx1ads_timer = {
+	.init	= mx1ads_timer_init,
+};
+
+MACHINE_START(MX1ADS, "Freescale MX1ADS")
+	/* Maintainer: Sascha Hauer, Pengutronix */
+	.phys_io	= IMX_IO_PHYS,
+	.io_pg_offst	= (IMX_IO_BASE >> 18) & 0xfffc,
+	.boot_params	= MX1_PHYS_OFFSET + 0x100,
+	.map_io		= mx1_map_io,
+	.init_irq	= mx1_init_irq,
+	.timer		= &mx1ads_timer,
+	.init_machine	= mx1ads_init,
+MACHINE_END
+
+MACHINE_START(MXLADS, "Freescale MXLADS")
+	.phys_io	= IMX_IO_PHYS,
+	.io_pg_offst	= (IMX_IO_BASE >> 18) & 0xfffc,
+	.boot_params	= MX1_PHYS_OFFSET + 0x100,
+	.map_io		= mx1_map_io,
+	.init_irq	= mx1_init_irq,
+	.timer		= &mx1ads_timer,
+	.init_machine	= mx1ads_init,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx1/mach-scb9328.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx1/mach-scb9328.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx1/mach-scb9328.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx1/mach-scb9328.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,158 @@
+/*
+ * linux/arch/arm/mach-mx1/mach-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-mx1.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[] = {
+	{
+		.name	= "address area",
+		.start	= IMX_CS5_PHYS,
+		.end	= IMX_CS5_PHYS + 1,
+		.flags	= IORESOURCE_MEM,	/* address access */
+	}, {
+		.name	= "data area",
+		.start	= IMX_CS5_PHYS + 4,
+		.end	= IMX_CS5_PHYS + 5,
+		.flags	= IORESOURCE_MEM,	/* data access */
+	}, {
+		.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		= mx1_map_io,
+	.init_irq	= mx1_init_irq,
+	.timer		= &scb9328_timer,
+	.init_machine	= scb9328_init,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx1/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-mx1/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx1/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx1/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -4,11 +4,12 @@
 
 # Object file lists.
 
+EXTRA_CFLAGS += -DIMX_NEEDS_DEPRECATED_SYMBOLS
 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
+obj-$(CONFIG_ARCH_MX1ADS) += mach-mx1ads.o
+obj-$(CONFIG_MACH_SCB9328) += mach-scb9328.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx1/mx1ads.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx1/mx1ads.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx1/mx1ads.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx1/mx1ads.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,165 +0,0 @@
-/*
- * arch/arm/mach-imx/mx1ads.c
- *
- * Initially based on:
- *	linux-2.6.7-imx/arch/arm/mach-imx/scb9328.c
- *	Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
- *
- * 2004 (c) MontaVista Software, Inc.
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/i2c.h>
-#include <linux/i2c/pcf857x.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/physmap.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/i2c.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux.h>
-#include <mach/irqs.h>
-
-#include "devices.h"
-
-static int mx1ads_pins[] = {
-	/* UART1 */
-	PC9_PF_UART1_CTS,
-	PC10_PF_UART1_RTS,
-	PC11_PF_UART1_TXD,
-	PC12_PF_UART1_RXD,
-	/* UART2 */
-	PB28_PF_UART2_CTS,
-	PB29_PF_UART2_RTS,
-	PB30_PF_UART2_TXD,
-	PB31_PF_UART2_RXD,
-	/* I2C */
-	PA15_PF_I2C_SDA,
-	PA16_PF_I2C_SCL,
-	/* SPI */
-	PC13_PF_SPI1_SPI_RDY,
-	PC14_PF_SPI1_SCLK,
-	PC15_PF_SPI1_SS,
-	PC16_PF_SPI1_MISO,
-	PC17_PF_SPI1_MOSI,
-};
-
-/*
- * UARTs platform data
- */
-
-static struct imxuart_platform_data uart_pdata[] = {
-	{
-		.flags = IMXUART_HAVE_RTSCTS,
-	}, {
-		.flags = IMXUART_HAVE_RTSCTS,
-	},
-};
-
-/*
- * Physmap flash
- */
-
-static struct physmap_flash_data mx1ads_flash_data = {
-	.width		= 4,		/* bankwidth in bytes */
-};
-
-static struct resource flash_resource = {
-	.start	= IMX_CS0_PHYS,
-	.end	= IMX_CS0_PHYS + SZ_32M - 1,
-	.flags	= IORESOURCE_MEM,
-};
-
-static struct platform_device flash_device = {
-	.name	= "physmap-flash",
-	.id	= 0,
-	.resource = &flash_resource,
-	.num_resources = 1,
-};
-
-/*
- * I2C
- */
-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,
-};
-
-static struct i2c_board_info mx1ads_i2c_devices[] = {
-	{
-		I2C_BOARD_INFO("pcf8575", 0x22),
-		.platform_data = &pcf857x_data[0],
-	}, {
-		I2C_BOARD_INFO("pcf8575", 0x24),
-		.platform_data = &pcf857x_data[1],
-	},
-};
-
-/*
- * Board init
- */
-static void __init mx1ads_init(void)
-{
-	mxc_gpio_setup_multiple_pins(mx1ads_pins,
-		ARRAY_SIZE(mx1ads_pins), "mx1ads");
-
-	/* UART */
-	mxc_register_device(&imx_uart1_device, &uart_pdata[0]);
-	mxc_register_device(&imx_uart2_device, &uart_pdata[1]);
-
-	/* 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)
-{
-	mx1_clocks_init(32000);
-}
-
-struct sys_timer mx1ads_timer = {
-	.init	= mx1ads_timer_init,
-};
-
-MACHINE_START(MX1ADS, "Freescale MX1ADS")
-	/* Maintainer: Sascha Hauer, Pengutronix */
-	.phys_io	= IMX_IO_PHYS,
-	.io_pg_offst	= (IMX_IO_BASE >> 18) & 0xfffc,
-	.boot_params	= PHYS_OFFSET + 0x100,
-	.map_io		= mx1_map_io,
-	.init_irq	= mx1_init_irq,
-	.timer		= &mx1ads_timer,
-	.init_machine	= mx1ads_init,
-MACHINE_END
-
-MACHINE_START(MXLADS, "Freescale MXLADS")
-	.phys_io	= IMX_IO_PHYS,
-	.io_pg_offst	= (IMX_IO_BASE >> 18) & 0xfffc,
-	.boot_params	= PHYS_OFFSET + 0x100,
-	.map_io		= mx1_map_io,
-	.init_irq	= mx1_init_irq,
-	.timer		= &mx1ads_timer,
-	.init_machine	= mx1ads_init,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx1/scb9328.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx1/scb9328.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx1/scb9328.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx1/scb9328.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,158 +0,0 @@
-/*
- * 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[] = {
-	{
-		.name	= "address area",
-		.start	= IMX_CS5_PHYS,
-		.end	= IMX_CS5_PHYS + 1,
-		.flags	= IORESOURCE_MEM,	/* address access */
-	}, {
-		.name	= "data area",
-		.start	= IMX_CS5_PHYS + 4,
-		.end	= IMX_CS5_PHYS + 5,
-		.flags	= IORESOURCE_MEM,	/* data access */
-	}, {
-		.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		= mx1_map_io,
-	.init_irq	= mx1_init_irq,
-	.timer		= &scb9328_timer,
-	.init_machine	= scb9328_init,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/clock_imx21.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/clock_imx21.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/clock_imx21.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/clock_imx21.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,11 +23,242 @@
 #include <linux/module.h>
 
 #include <mach/clock.h>
+#include <mach/hardware.h>
 #include <mach/common.h>
 #include <asm/clkdev.h>
 #include <asm/div64.h>
 
-#include "crm_regs.h"
+#define IO_ADDR_CCM(off)	(MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
+
+/* Register offsets */
+#define CCM_CSCR		IO_ADDR_CCM(0x0)
+#define CCM_MPCTL0		IO_ADDR_CCM(0x4)
+#define CCM_MPCTL1		IO_ADDR_CCM(0x8)
+#define CCM_SPCTL0		IO_ADDR_CCM(0xc)
+#define CCM_SPCTL1		IO_ADDR_CCM(0x10)
+#define CCM_OSC26MCTL		IO_ADDR_CCM(0x14)
+#define CCM_PCDR0		IO_ADDR_CCM(0x18)
+#define CCM_PCDR1		IO_ADDR_CCM(0x1c)
+#define CCM_PCCR0		IO_ADDR_CCM(0x20)
+#define CCM_PCCR1		IO_ADDR_CCM(0x24)
+#define CCM_CCSR		IO_ADDR_CCM(0x28)
+#define CCM_PMCTL		IO_ADDR_CCM(0x2c)
+#define CCM_PMCOUNT		IO_ADDR_CCM(0x30)
+#define CCM_WKGDCTL		IO_ADDR_CCM(0x34)
+
+#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 << 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)
+#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)
+#define CCM_MPCTL0_MFD_OFFSET	16
+#define CCM_MPCTL0_MFD_MASK	(0x3ff << 16)
+#define CCM_MPCTL0_MFI_OFFSET	10
+#define CCM_MPCTL0_MFI_MASK	(0xf << 10)
+#define CCM_MPCTL0_MFN_OFFSET	0
+#define CCM_MPCTL0_MFN_MASK	0x3ff
+
+#define CCM_MPCTL1_LF		(1 << 15)
+#define CCM_MPCTL1_BRMO		(1 << 6)
+
+#define CCM_SPCTL0_CPLM		(1 << 31)
+#define CCM_SPCTL0_PD_OFFSET	26
+#define CCM_SPCTL0_PD_MASK	(0xf << 26)
+#define CCM_SPCTL0_MFD_OFFSET	16
+#define CCM_SPCTL0_MFD_MASK	(0x3ff << 16)
+#define CCM_SPCTL0_MFI_OFFSET	10
+#define CCM_SPCTL0_MFI_MASK	(0xf << 10)
+#define CCM_SPCTL0_MFN_OFFSET	0
+#define CCM_SPCTL0_MFN_MASK	0x3ff
+
+#define CCM_SPCTL1_LF		(1 << 15)
+#define CCM_SPCTL1_BRMO		(1 << 6)
+
+#define CCM_OSC26MCTL_PEAK_OFFSET	16
+#define CCM_OSC26MCTL_PEAK_MASK		(0x3 << 16)
+#define CCM_OSC26MCTL_AGC_OFFSET	8
+#define CCM_OSC26MCTL_AGC_MASK		(0x3f << 8)
+#define CCM_OSC26MCTL_ANATEST_OFFSET	0
+#define CCM_OSC26MCTL_ANATEST_MASK	0x3f
+
+#define CCM_PCDR0_SSI2BAUDDIV_OFFSET	26
+#define CCM_PCDR0_SSI2BAUDDIV_MASK	(0x3f << 26)
+#define CCM_PCDR0_SSI1BAUDDIV_OFFSET	16
+#define CCM_PCDR0_SSI1BAUDDIV_MASK	(0x3f << 16)
+#define CCM_PCDR0_NFCDIV_OFFSET		12
+#define CCM_PCDR0_NFCDIV_MASK		(0xf << 12)
+#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
+#define CCM_PCDR1_PERDIV3_MASK		(0x3f << 16)
+#define CCM_PCDR1_PERDIV2_OFFSET	8
+#define CCM_PCDR1_PERDIV2_MASK		(0x3f << 8)
+#define CCM_PCDR1_PERDIV1_OFFSET	0
+#define CCM_PCDR1_PERDIV1_MASK		0x3f
+
+#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_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
+
+#define SYS_FMCR		0x14	/* Functional Muxing Control Reg */
+#define SYS_CHIP_ID		0x00	/* The offset of CHIP ID register */
 
 static int _clk_enable(struct clk *clk)
 {
@@ -968,7 +1199,6 @@ static struct clk_lookup lookups[] = {
  */
 int __init mx21_clocks_init(unsigned long lref, unsigned long href)
 {
-	int i;
 	u32 cscr;
 
 	external_low_reference = lref;
@@ -986,8 +1216,7 @@ int __init mx21_clocks_init(unsigned lon
 	else
 		spll_clk.parent = &fpm_clk;
 
-	for (i = 0; i < ARRAY_SIZE(lookups); i++)
-		clkdev_add(&lookups[i]);
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	/* Turn off all clock gates */
 	__raw_writel(0, CCM_PCCR0);
@@ -1004,6 +1233,7 @@ int __init mx21_clocks_init(unsigned lon
 	clk_enable(&uart_clk[0]);
 #endif
 
-	mxc_timer_init(&gpt_clk[0], IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT1);
+	mxc_timer_init(&gpt_clk[0], MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR),
+			MX21_INT_GPT1);
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/clock_imx27.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/clock_imx27.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/clock_imx27.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/clock_imx27.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,21 +29,23 @@
 #include <mach/common.h>
 #include <mach/hardware.h>
 
+#define IO_ADDR_CCM(off)	(MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off)))
+
 /* 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)
+#define CCM_CSCR		IO_ADDR_CCM(0x0)
+#define CCM_MPCTL0		IO_ADDR_CCM(0x4)
+#define CCM_MPCTL1		IO_ADDR_CCM(0x8)
+#define CCM_SPCTL0		IO_ADDR_CCM(0xc)
+#define CCM_SPCTL1		IO_ADDR_CCM(0x10)
+#define CCM_OSC26MCTL		IO_ADDR_CCM(0x14)
+#define CCM_PCDR0		IO_ADDR_CCM(0x18)
+#define CCM_PCDR1		IO_ADDR_CCM(0x1c)
+#define CCM_PCCR0		IO_ADDR_CCM(0x20)
+#define CCM_PCCR1		IO_ADDR_CCM(0x24)
+#define CCM_CCSR		IO_ADDR_CCM(0x28)
+#define CCM_PMCTL		IO_ADDR_CCM(0x2c)
+#define CCM_PMCOUNT		IO_ADDR_CCM(0x30)
+#define CCM_WKGDCTL		IO_ADDR_CCM(0x34)
 
 #define CCM_CSCR_UPDATE_DIS	(1 << 31)
 #define CCM_CSCR_SSI2		(1 << 23)
@@ -719,7 +721,6 @@ static void __init to2_adjust_clocks(voi
 int __init mx27_clocks_init(unsigned long fref)
 {
 	u32 cscr = __raw_readl(CCM_CSCR);
-	int i;
 
 	external_high_reference = fref;
 
@@ -736,8 +737,7 @@ int __init mx27_clocks_init(unsigned lon
 
 	to2_adjust_clocks();
 
-	for (i = 0; i < ARRAY_SIZE(lookups); i++)
-		clkdev_add(&lookups[i]);
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	/* Turn off all clocks we do not need */
 	__raw_writel(0, CCM_PCCR0);
@@ -755,7 +755,8 @@ int __init mx27_clocks_init(unsigned lon
 	clk_enable(&uart1_clk);
 #endif
 
-	mxc_timer_init(&gpt1_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT1);
+	mxc_timer_init(&gpt1_clk, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR),
+			MX27_INT_GPT1);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/cpu_imx27.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/cpu_imx27.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/cpu_imx27.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/cpu_imx27.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,8 @@ static void query_silicon_parameter(void
 	 * the silicon revision very early we read it here to
 	 * avoid any further hooks
 	*/
-	val = __raw_readl(IO_ADDRESS(SYSCTRL_BASE_ADDR) + SYS_CHIP_ID);
+	val = __raw_readl(MX27_IO_ADDRESS(MX27_SYSCTRL_BASE_ADDR
+				+ SYS_CHIP_ID));
 
 	cpu_silicon_rev = (int)(val >> 28);
 	cpu_partnumber = (int)((val >> 12) & 0xFFFF);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/crm_regs.h linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/crm_regs.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/crm_regs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/crm_regs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,258 +0,0 @@
-/*
- * Copyright 2004-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., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef __ARCH_ARM_MACH_MX2_CRM_REGS_H__
-#define __ARCH_ARM_MACH_MX2_CRM_REGS_H__
-
-#include <mach/hardware.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)
-
-#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 << 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)
-#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)
-#define CCM_MPCTL0_MFD_OFFSET   16
-#define CCM_MPCTL0_MFD_MASK     (0x3ff << 16)
-#define CCM_MPCTL0_MFI_OFFSET   10
-#define CCM_MPCTL0_MFI_MASK     (0xf << 10)
-#define CCM_MPCTL0_MFN_OFFSET   0
-#define CCM_MPCTL0_MFN_MASK     0x3ff
-
-#define CCM_MPCTL1_LF           (1 << 15)
-#define CCM_MPCTL1_BRMO         (1 << 6)
-
-#define CCM_SPCTL0_CPLM         (1 << 31)
-#define CCM_SPCTL0_PD_OFFSET    26
-#define CCM_SPCTL0_PD_MASK      (0xf << 26)
-#define CCM_SPCTL0_MFD_OFFSET   16
-#define CCM_SPCTL0_MFD_MASK     (0x3ff << 16)
-#define CCM_SPCTL0_MFI_OFFSET   10
-#define CCM_SPCTL0_MFI_MASK     (0xf << 10)
-#define CCM_SPCTL0_MFN_OFFSET   0
-#define CCM_SPCTL0_MFN_MASK     0x3ff
-
-#define CCM_SPCTL1_LF           (1 << 15)
-#define CCM_SPCTL1_BRMO         (1 << 6)
-
-#define CCM_OSC26MCTL_PEAK_OFFSET       16
-#define CCM_OSC26MCTL_PEAK_MASK         (0x3 << 16)
-#define CCM_OSC26MCTL_AGC_OFFSET        8
-#define CCM_OSC26MCTL_AGC_MASK          (0x3f << 8)
-#define CCM_OSC26MCTL_ANATEST_OFFSET    0
-#define CCM_OSC26MCTL_ANATEST_MASK      0x3f
-
-#define CCM_PCDR0_SSI2BAUDDIV_OFFSET    26
-#define CCM_PCDR0_SSI2BAUDDIV_MASK      (0x3f << 26)
-#define CCM_PCDR0_SSI1BAUDDIV_OFFSET    16
-#define CCM_PCDR0_SSI1BAUDDIV_MASK      (0x3f << 16)
-#define CCM_PCDR0_NFCDIV_OFFSET         12
-#define CCM_PCDR0_NFCDIV_MASK           (0xf << 12)
-#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
-#define CCM_PCDR1_PERDIV3_MASK          (0x3f << 16)
-#define CCM_PCDR1_PERDIV2_OFFSET        8
-#define CCM_PCDR1_PERDIV2_MASK          (0x3f << 8)
-#define CCM_PCDR1_PERDIV1_OFFSET        0
-#define CCM_PCDR1_PERDIV1_MASK          0x3f
-
-#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_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
-
-#define SYS_FMCR                0x14	/*  Functional Muxing Control Reg */
-#define SYS_CHIP_ID             0x00	/* The offset of CHIP ID register */
-
-#endif /* __ARCH_ARM_MACH_MX2_CRM_REGS_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/devices.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/devices.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/devices.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/devices.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/dma-mapping.h>
 
 #include <mach/irqs.h>
 #include <mach/hardware.h>
@@ -46,65 +47,31 @@
  * - i.MX21: 2 channel
  * - i.MX27: 3 channel
  */
-static struct resource mxc_spi_resources0[] = {
-	{
-	       .start = CSPI1_BASE_ADDR,
-	       .end = CSPI1_BASE_ADDR + SZ_4K - 1,
-	       .flags = IORESOURCE_MEM,
-	}, {
-	       .start = MXC_INT_CSPI1,
-	       .end = MXC_INT_CSPI1,
-	       .flags = IORESOURCE_IRQ,
-	},
-};
-
-static struct resource mxc_spi_resources1[] = {
-	{
-		.start = CSPI2_BASE_ADDR,
-		.end = CSPI2_BASE_ADDR + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = MXC_INT_CSPI2,
-		.end = MXC_INT_CSPI2,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-#ifdef CONFIG_MACH_MX27
-static struct resource mxc_spi_resources2[] = {
-	{
-		.start = CSPI3_BASE_ADDR,
-		.end = CSPI3_BASE_ADDR + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = MXC_INT_CSPI3,
-		.end = MXC_INT_CSPI3,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-#endif
-
-struct platform_device mxc_spi_device0 = {
-	.name = "spi_imx",
-	.id = 0,
-	.num_resources = ARRAY_SIZE(mxc_spi_resources0),
-	.resource = mxc_spi_resources0,
-};
+#define DEFINE_IMX_SPI_DEVICE(n, baseaddr, irq)					\
+	static struct resource mxc_spi_resources ## n[] = {			\
+		{								\
+			.start = baseaddr,					\
+			.end = baseaddr + SZ_4K - 1,				\
+			.flags = IORESOURCE_MEM,				\
+		}, {								\
+			.start = irq,						\
+			.end = irq,						\
+			.flags = IORESOURCE_IRQ,				\
+		},								\
+	};									\
+										\
+	struct platform_device mxc_spi_device ## n = {				\
+		.name = "spi_imx",						\
+		.id = n,							\
+		.num_resources = ARRAY_SIZE(mxc_spi_resources ## n),		\
+		.resource = mxc_spi_resources ## n,				\
+	}
 
-struct platform_device mxc_spi_device1 = {
-	.name = "spi_imx",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(mxc_spi_resources1),
-	.resource = mxc_spi_resources1,
-};
+DEFINE_IMX_SPI_DEVICE(0, MX2x_CSPI1_BASE_ADDR, MX2x_INT_CSPI1);
+DEFINE_IMX_SPI_DEVICE(1, MX2x_CSPI2_BASE_ADDR, MX2x_INT_CSPI2);
 
 #ifdef CONFIG_MACH_MX27
-struct platform_device mxc_spi_device2 = {
-	.name = "spi_imx",
-	.id = 2,
-	.num_resources = ARRAY_SIZE(mxc_spi_resources2),
-	.resource = mxc_spi_resources2,
-};
+DEFINE_IMX_SPI_DEVICE(2, MX27_CSPI3_BASE_ADDR, MX27_INT_CSPI3);
 #endif
 
 /*
@@ -112,104 +79,34 @@ struct platform_device mxc_spi_device2 =
  * - i.MX21: 3 timers
  * - i.MX27: 6 timers
  */
-
-/* We use gpt0 as system timer, so do not add a device for this one */
-
-static struct resource timer1_resources[] = {
-	{
-		.start	= GPT2_BASE_ADDR,
-		.end	= GPT2_BASE_ADDR + 0x17,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start   = MXC_INT_GPT2,
-		.end     = MXC_INT_GPT2,
-		.flags   = IORESOURCE_IRQ,
-	}
-};
-
-struct platform_device mxc_gpt1 = {
-	.name = "imx_gpt",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(timer1_resources),
-	.resource = timer1_resources,
-};
-
-static struct resource timer2_resources[] = {
-	{
-		.start	= GPT3_BASE_ADDR,
-		.end	= GPT3_BASE_ADDR + 0x17,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start   = MXC_INT_GPT3,
-		.end     = MXC_INT_GPT3,
-		.flags   = IORESOURCE_IRQ,
+#define DEFINE_IMX_GPT_DEVICE(n, baseaddr, irq)				\
+	static struct resource timer ## n ##_resources[] = {		\
+		{							\
+			.start = baseaddr,				\
+			.end = baseaddr + SZ_4K - 1,			\
+			.flags = IORESOURCE_MEM,			\
+		}, {							\
+			.start = irq,					\
+			.end = irq,					\
+			.flags = IORESOURCE_IRQ,			\
+		}							\
+	};								\
+									\
+	struct platform_device mxc_gpt ## n = {				\
+		.name = "imx_gpt",					\
+		.id = n,						\
+		.num_resources = ARRAY_SIZE(timer ## n ## _resources),	\
+		.resource = timer ## n ## _resources,			\
 	}
-};
 
-struct platform_device mxc_gpt2 = {
-	.name = "imx_gpt",
-	.id = 2,
-	.num_resources = ARRAY_SIZE(timer2_resources),
-	.resource = timer2_resources,
-};
+/* We use gpt1 as system timer, so do not add a device for this one */
+DEFINE_IMX_GPT_DEVICE(1, MX2x_GPT2_BASE_ADDR, MX2x_INT_GPT2);
+DEFINE_IMX_GPT_DEVICE(2, MX2x_GPT3_BASE_ADDR, MX2x_INT_GPT3);
 
 #ifdef CONFIG_MACH_MX27
-static struct resource timer3_resources[] = {
-	{
-		.start	= GPT4_BASE_ADDR,
-		.end	= GPT4_BASE_ADDR + 0x17,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start   = MXC_INT_GPT4,
-		.end     = MXC_INT_GPT4,
-		.flags   = IORESOURCE_IRQ,
-	}
-};
-
-struct platform_device mxc_gpt3 = {
-	.name = "imx_gpt",
-	.id = 3,
-	.num_resources = ARRAY_SIZE(timer3_resources),
-	.resource = timer3_resources,
-};
-
-static struct resource timer4_resources[] = {
-	{
-		.start	= GPT5_BASE_ADDR,
-		.end	= GPT5_BASE_ADDR + 0x17,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start   = MXC_INT_GPT5,
-		.end     = MXC_INT_GPT5,
-		.flags   = IORESOURCE_IRQ,
-	}
-};
-
-struct platform_device mxc_gpt4 = {
-	.name = "imx_gpt",
-	.id = 4,
-	.num_resources = ARRAY_SIZE(timer4_resources),
-	.resource = timer4_resources,
-};
-
-static struct resource timer5_resources[] = {
-	{
-		.start	= GPT6_BASE_ADDR,
-		.end	= GPT6_BASE_ADDR + 0x17,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start   = MXC_INT_GPT6,
-		.end     = MXC_INT_GPT6,
-		.flags   = IORESOURCE_IRQ,
-	}
-};
-
-struct platform_device mxc_gpt5 = {
-	.name = "imx_gpt",
-	.id = 5,
-	.num_resources = ARRAY_SIZE(timer5_resources),
-	.resource = timer5_resources,
-};
+DEFINE_IMX_GPT_DEVICE(3, MX27_GPT4_BASE_ADDR, MX27_INT_GPT4);
+DEFINE_IMX_GPT_DEVICE(4, MX27_GPT5_BASE_ADDR, MX27_INT_GPT5);
+DEFINE_IMX_GPT_DEVICE(5, MX27_GPT6_BASE_ADDR, MX27_INT_GPT6);
 #endif
 
 /*
@@ -220,9 +117,9 @@ struct platform_device mxc_gpt5 = {
  */
 static struct resource mxc_wdt_resources[] = {
 	{
-		.start	= WDOG_BASE_ADDR,
-		.end	= WDOG_BASE_ADDR + 0x30,
-		.flags	= IORESOURCE_MEM,
+		.start = MX2x_WDOG_BASE_ADDR,
+		.end = MX2x_WDOG_BASE_ADDR + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
 	},
 };
 
@@ -235,8 +132,8 @@ struct platform_device mxc_wdt = {
 
 static struct resource mxc_w1_master_resources[] = {
 	{
-		.start = OWIRE_BASE_ADDR,
-		.end   = OWIRE_BASE_ADDR + SZ_4K - 1,
+		.start = MX2x_OWIRE_BASE_ADDR,
+		.end = MX2x_OWIRE_BASE_ADDR + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
 };
@@ -248,24 +145,33 @@ struct platform_device mxc_w1_master_dev
 	.resource = mxc_w1_master_resources,
 };
 
-static struct resource mxc_nand_resources[] = {
-	{
-		.start	= NFC_BASE_ADDR,
-		.end	= NFC_BASE_ADDR + 0xfff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= MXC_INT_NANDFC,
-		.end	= MXC_INT_NANDFC,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
+#define DEFINE_MXC_NAND_DEVICE(pfx, baseaddr, irq)			\
+	static struct resource pfx ## _nand_resources[] = {		\
+		{							\
+			.start = baseaddr,				\
+			.end = baseaddr + SZ_4K - 1,			\
+			.flags = IORESOURCE_MEM,			\
+		}, {							\
+			.start = irq,					\
+			.end = irq,					\
+			.flags = IORESOURCE_IRQ,			\
+		},							\
+	};								\
+									\
+	struct platform_device pfx ## _nand_device = {			\
+		.name = "mxc_nand",					\
+		.id = 0,						\
+		.num_resources = ARRAY_SIZE(pfx ## _nand_resources),	\
+		.resource = pfx ## _nand_resources,			\
+	}
 
-struct platform_device mxc_nand_device = {
-	.name = "mxc_nand",
-	.id = 0,
-	.num_resources = ARRAY_SIZE(mxc_nand_resources),
-	.resource = mxc_nand_resources,
-};
+#ifdef CONFIG_MACH_MX21
+DEFINE_MXC_NAND_DEVICE(imx21, MX21_NFC_BASE_ADDR, MX21_INT_NANDFC);
+#endif
+
+#ifdef CONFIG_MACH_MX27
+DEFINE_MXC_NAND_DEVICE(imx27, MX27_NFC_BASE_ADDR, MX27_INT_NANDFC);
+#endif
 
 /*
  * lcdc:
@@ -275,12 +181,12 @@ struct platform_device mxc_nand_device =
  */
 static struct resource mxc_fb[] = {
 	{
-		.start = LCDC_BASE_ADDR,
-		.end   = LCDC_BASE_ADDR + 0xFFF,
+		.start = MX2x_LCDC_BASE_ADDR,
+		.end = MX2x_LCDC_BASE_ADDR + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = MXC_INT_LCDC,
-		.end   = MXC_INT_LCDC,
+		.start = MX2x_INT_LCDC,
+		.end = MX2x_INT_LCDC,
 		.flags = IORESOURCE_IRQ,
 	}
 };
@@ -292,20 +198,20 @@ struct platform_device mxc_fb_device = {
 	.num_resources = ARRAY_SIZE(mxc_fb),
 	.resource = mxc_fb,
 	.dev = {
-		.coherent_dma_mask = 0xFFFFFFFF,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
 	},
 };
 
 #ifdef CONFIG_MACH_MX27
 static struct resource mxc_fec_resources[] = {
 	{
-		.start	= FEC_BASE_ADDR,
-		.end	= FEC_BASE_ADDR + 0xfff,
-		.flags	= IORESOURCE_MEM,
+		.start = MX27_FEC_BASE_ADDR,
+		.end = MX27_FEC_BASE_ADDR + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
 	}, {
-		.start	= MXC_INT_FEC,
-		.end	= MXC_INT_FEC,
-		.flags	= IORESOURCE_IRQ,
+		.start = MX27_INT_FEC,
+		.end = MX27_INT_FEC,
+		.flags = IORESOURCE_IRQ,
 	},
 };
 
@@ -317,55 +223,41 @@ struct platform_device mxc_fec_device =
 };
 #endif
 
-static struct resource mxc_i2c_1_resources[] = {
-	{
-		.start	= I2C_BASE_ADDR,
-		.end	= I2C_BASE_ADDR + 0x0fff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= MXC_INT_I2C,
-		.end	= MXC_INT_I2C,
-		.flags	= IORESOURCE_IRQ,
+#define DEFINE_IMX_I2C_DEVICE(n, baseaddr, irq)				\
+	static struct resource mxc_i2c_resources ## n[] = {		\
+		{							\
+			.start = baseaddr,				\
+			.end = baseaddr + SZ_4K - 1,			\
+			.flags = IORESOURCE_MEM,			\
+		}, {							\
+			.start = irq,					\
+			.end = irq,					\
+			.flags = IORESOURCE_IRQ,			\
+		}							\
+	};								\
+									\
+	struct platform_device mxc_i2c_device ## n = {			\
+		.name = "imx-i2c",					\
+		.id = n,						\
+		.num_resources = ARRAY_SIZE(mxc_i2c_resources ## n),	\
+		.resource = mxc_i2c_resources ## n,			\
 	}
-};
 
-struct platform_device mxc_i2c_device0 = {
-	.name = "imx-i2c",
-	.id = 0,
-	.num_resources = ARRAY_SIZE(mxc_i2c_1_resources),
-	.resource = mxc_i2c_1_resources,
-};
+DEFINE_IMX_I2C_DEVICE(0, MX2x_I2C_BASE_ADDR, MX2x_INT_I2C);
 
 #ifdef CONFIG_MACH_MX27
-static struct resource mxc_i2c_2_resources[] = {
-	{
-		.start	= I2C2_BASE_ADDR,
-		.end	= I2C2_BASE_ADDR + 0x0fff,
-		.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_i2c_2_resources),
-	.resource = mxc_i2c_2_resources,
-};
+DEFINE_IMX_I2C_DEVICE(1, MX27_I2C2_BASE_ADDR, MX27_INT_I2C2);
 #endif
 
 static struct resource mxc_pwm_resources[] = {
 	{
-		.start	= PWM_BASE_ADDR,
-		.end	= PWM_BASE_ADDR + 0x0fff,
-		.flags	= IORESOURCE_MEM,
+		.start = MX2x_PWM_BASE_ADDR,
+		.end = MX2x_PWM_BASE_ADDR + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
 	}, {
-		.start   = MXC_INT_PWM,
-		.end     = MXC_INT_PWM,
-		.flags   = IORESOURCE_IRQ,
+		.start = MX2x_INT_PWM,
+		.end = MX2x_INT_PWM,
+		.flags = IORESOURCE_IRQ,
 	}
 };
 
@@ -376,81 +268,53 @@ struct platform_device mxc_pwm_device =
 	.resource = mxc_pwm_resources,
 };
 
-/*
- * Resource definition for the MXC SDHC
- */
-static struct resource mxc_sdhc1_resources[] = {
-	{
-		.start = SDHC1_BASE_ADDR,
-		.end   = SDHC1_BASE_ADDR + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = MXC_INT_SDHC1,
-		.end   = MXC_INT_SDHC1,
-		.flags = IORESOURCE_IRQ,
-	}, {
-		.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[] = {
-	{
-		.start = SDHC2_BASE_ADDR,
-		.end   = SDHC2_BASE_ADDR + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = MXC_INT_SDHC2,
-		.end   = MXC_INT_SDHC2,
-		.flags = IORESOURCE_IRQ,
-	}, {
-		.start  = DMA_REQ_SDHC2,
-		.end    = DMA_REQ_SDHC2,
-		.flags  = IORESOURCE_DMA,
-	},
-};
-
-static u64 mxc_sdhc2_dmamask = 0xffffffffUL;
+#define DEFINE_MXC_MMC_DEVICE(n, baseaddr, irq, dmareq)			\
+	static struct resource mxc_sdhc_resources ## n[] = {		\
+		{							\
+			.start = baseaddr,				\
+			.end = baseaddr + SZ_4K - 1,			\
+			.flags = IORESOURCE_MEM,			\
+		}, {							\
+			.start = irq,					\
+			.end = irq,					\
+			.flags = IORESOURCE_IRQ,			\
+		}, {							\
+			.start = dmareq,				\
+			.end = dmareq,					\
+			.flags = IORESOURCE_DMA,			\
+		},							\
+	};								\
+									\
+	static u64 mxc_sdhc ## n ## _dmamask = DMA_BIT_MASK(32);	\
+									\
+	struct platform_device mxc_sdhc_device ## n = {			\
+		.name = "mxc-mmc",					\
+		.id = n,						\
+		.dev = {						\
+			.dma_mask = &mxc_sdhc ## n ## _dmamask,		\
+			.coherent_dma_mask = DMA_BIT_MASK(32),		\
+		},							\
+		.num_resources = ARRAY_SIZE(mxc_sdhc_resources ## n),	\
+		.resource = mxc_sdhc_resources ## n,		\
+	}
 
-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,
-};
+DEFINE_MXC_MMC_DEVICE(0, MX2x_SDHC1_BASE_ADDR, MX2x_INT_SDHC1, MX2x_DMA_REQ_SDHC1);
+DEFINE_MXC_MMC_DEVICE(1, MX2x_SDHC2_BASE_ADDR, MX2x_INT_SDHC2, MX2x_DMA_REQ_SDHC2);
 
 #ifdef CONFIG_MACH_MX27
 static struct resource otg_resources[] = {
 	{
-		.start	= OTG_BASE_ADDR,
-		.end	= OTG_BASE_ADDR + 0x1ff,
-		.flags	= IORESOURCE_MEM,
+		.start = MX27_USBOTG_BASE_ADDR,
+		.end = MX27_USBOTG_BASE_ADDR + 0x1ff,
+		.flags = IORESOURCE_MEM,
 	}, {
-		.start	= MXC_INT_USB3,
-		.end	= MXC_INT_USB3,
-		.flags	= IORESOURCE_IRQ,
+		.start = MX27_INT_USB3,
+		.end = MX27_INT_USB3,
+		.flags = IORESOURCE_IRQ,
 	},
 };
 
-static u64 otg_dmamask = 0xffffffffUL;
+static u64 otg_dmamask = DMA_BIT_MASK(32);
 
 /* OTG gadget device */
 struct platform_device mxc_otg_udc_device = {
@@ -458,7 +322,7 @@ struct platform_device mxc_otg_udc_devic
 	.id		= -1,
 	.dev		= {
 		.dma_mask		= &otg_dmamask,
-		.coherent_dma_mask	= 0xffffffffUL,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.resource	= otg_resources,
 	.num_resources	= ARRAY_SIZE(otg_resources),
@@ -469,7 +333,7 @@ struct platform_device mxc_otg_host = {
 	.name = "mxc-ehci",
 	.id = 0,
 	.dev = {
-		.coherent_dma_mask = 0xffffffff,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
 		.dma_mask = &otg_dmamask,
 	},
 	.resource = otg_resources,
@@ -478,16 +342,16 @@ struct platform_device mxc_otg_host = {
 
 /* USB host 1 */
 
-static u64 usbh1_dmamask = 0xffffffffUL;
+static u64 usbh1_dmamask = DMA_BIT_MASK(32);
 
 static struct resource mxc_usbh1_resources[] = {
 	{
-		.start = OTG_BASE_ADDR + 0x200,
-		.end = OTG_BASE_ADDR + 0x3ff,
+		.start = MX27_USBOTG_BASE_ADDR + 0x200,
+		.end = MX27_USBOTG_BASE_ADDR + 0x3ff,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = MXC_INT_USB1,
-		.end = MXC_INT_USB1,
+		.start = MX27_INT_USB1,
+		.end = MX27_INT_USB1,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -496,7 +360,7 @@ struct platform_device mxc_usbh1 = {
 	.name = "mxc-ehci",
 	.id = 1,
 	.dev = {
-		.coherent_dma_mask = 0xffffffff,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
 		.dma_mask = &usbh1_dmamask,
 	},
 	.resource = mxc_usbh1_resources,
@@ -504,16 +368,16 @@ struct platform_device mxc_usbh1 = {
 };
 
 /* USB host 2 */
-static u64 usbh2_dmamask = 0xffffffffUL;
+static u64 usbh2_dmamask = DMA_BIT_MASK(32);
 
 static struct resource mxc_usbh2_resources[] = {
 	{
-		.start = OTG_BASE_ADDR + 0x400,
-		.end = OTG_BASE_ADDR + 0x5ff,
+		.start = MX27_USBOTG_BASE_ADDR + 0x400,
+		.end = MX27_USBOTG_BASE_ADDR + 0x5ff,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = MXC_INT_USB2,
-		.end = MXC_INT_USB2,
+		.start = MX27_INT_USB2,
+		.end = MX27_INT_USB2,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -522,7 +386,7 @@ struct platform_device mxc_usbh2 = {
 	.name = "mxc-ehci",
 	.id = 2,
 	.dev = {
-		.coherent_dma_mask = 0xffffffff,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
 		.dma_mask = &usbh2_dmamask,
 	},
 	.resource = mxc_usbh2_resources,
@@ -530,115 +394,115 @@ struct platform_device mxc_usbh2 = {
 };
 #endif
 
-static struct resource imx_ssi_resources0[] = {
-	{
-		.start	= SSI1_BASE_ADDR,
-		.end	= SSI1_BASE_ADDR + 0x6F,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= MXC_INT_SSI1,
-		.end	= MXC_INT_SSI1,
-		.flags	= IORESOURCE_IRQ,
-	}, {
-		.name	= "tx0",
-		.start	= DMA_REQ_SSI1_TX0,
-		.end	= DMA_REQ_SSI1_TX0,
-		.flags	= IORESOURCE_DMA,
-	}, {
-		.name	= "rx0",
-		.start	= DMA_REQ_SSI1_RX0,
-		.end	= DMA_REQ_SSI1_RX0,
-		.flags	= IORESOURCE_DMA,
-	}, {
-		.name	= "tx1",
-		.start	= DMA_REQ_SSI1_TX1,
-		.end	= DMA_REQ_SSI1_TX1,
-		.flags	= IORESOURCE_DMA,
-	}, {
-		.name	= "rx1",
-		.start	= DMA_REQ_SSI1_RX1,
-		.end	= DMA_REQ_SSI1_RX1,
-		.flags	= IORESOURCE_DMA,
-	},
-};
-
-static struct resource imx_ssi_resources1[] = {
-	{
-		.start	= SSI2_BASE_ADDR,
-		.end	= SSI2_BASE_ADDR + 0x6F,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= MXC_INT_SSI2,
-		.end	= MXC_INT_SSI2,
-		.flags	= IORESOURCE_IRQ,
-	}, {
-		.name	= "tx0",
-		.start	= DMA_REQ_SSI2_TX0,
-		.end	= DMA_REQ_SSI2_TX0,
-		.flags	= IORESOURCE_DMA,
-	}, {
-		.name	= "rx0",
-		.start	= DMA_REQ_SSI2_RX0,
-		.end	= DMA_REQ_SSI2_RX0,
-		.flags	= IORESOURCE_DMA,
-	}, {
-		.name	= "tx1",
-		.start	= DMA_REQ_SSI2_TX1,
-		.end	= DMA_REQ_SSI2_TX1,
-		.flags	= IORESOURCE_DMA,
-	}, {
-		.name	= "rx1",
-		.start	= DMA_REQ_SSI2_RX1,
-		.end	= DMA_REQ_SSI2_RX1,
-		.flags	= IORESOURCE_DMA,
-	},
-};
+#define DEFINE_IMX_SSI_DMARES(_name, ssin, suffix)			\
+	{								\
+		.name = _name,						\
+		.start = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix,	\
+		.end = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix,		\
+		.flags = IORESOURCE_DMA,				\
+	}
 
-struct platform_device imx_ssi_device0 = {
-	.name = "imx-ssi",
-	.id = 0,
-	.num_resources = ARRAY_SIZE(imx_ssi_resources0),
-	.resource = imx_ssi_resources0,
-};
+#define DEFINE_IMX_SSI_DEVICE(n, ssin, baseaddr, irq)			\
+	static struct resource imx_ssi_resources ## n[] = {		\
+		{							\
+			.start = MX2x_SSI ## ssin ## _BASE_ADDR,	\
+			.end = MX2x_SSI ## ssin ## _BASE_ADDR + 0x6f,	\
+			.flags = IORESOURCE_MEM,			\
+		}, {							\
+			.start = MX2x_INT_SSI1,				\
+			.end = MX2x_INT_SSI1,				\
+			.flags = IORESOURCE_IRQ,			\
+		},							\
+		DEFINE_IMX_SSI_DMARES("tx0", ssin, TX0),		\
+		DEFINE_IMX_SSI_DMARES("rx0", ssin, RX0),		\
+		DEFINE_IMX_SSI_DMARES("tx1", ssin, TX1),		\
+		DEFINE_IMX_SSI_DMARES("rx1", ssin, RX1),		\
+	};								\
+									\
+	struct platform_device imx_ssi_device ## n = {			\
+		.name = "imx-ssi",					\
+		.id = n,						\
+		.num_resources = ARRAY_SIZE(imx_ssi_resources ## n),	\
+		.resource = imx_ssi_resources ## n,			\
+	}
 
-struct platform_device imx_ssi_device1 = {
-	.name = "imx-ssi",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(imx_ssi_resources1),
-	.resource = imx_ssi_resources1,
-};
+DEFINE_IMX_SSI_DEVICE(0, 1, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1);
+DEFINE_IMX_SSI_DEVICE(1, 2, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1);
 
 /* GPIO port description */
-static struct mxc_gpio_port imx_gpio_ports[] = {
-	{
-		.chip.label = "gpio-0",
-		.irq = MXC_INT_GPIO,
-		.base = IO_ADDRESS(GPIO_BASE_ADDR),
-		.virtual_irq_start = MXC_GPIO_IRQ_START,
-	}, {
-		.chip.label = "gpio-1",
-		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x100),
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 32,
-	}, {
-		.chip.label = "gpio-2",
-		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x200),
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 64,
-	}, {
-		.chip.label = "gpio-3",
-		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x300),
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 96,
-	}, {
-		.chip.label = "gpio-4",
-		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x400),
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 128,
-	}, {
-		.chip.label = "gpio-5",
-		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x500),
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 160,
+#define DEFINE_MXC_GPIO_PORT_IRQ(SOC, n, _irq)				\
+	{								\
+		.chip.label = "gpio-" #n,				\
+		.irq = _irq,						\
+		.base = SOC ## _IO_ADDRESS(MX2x_GPIO_BASE_ADDR +	\
+				n * 0x100),				\
+		.virtual_irq_start = MXC_GPIO_IRQ_START + n * 32,	\
 	}
-};
+
+#define DEFINE_MXC_GPIO_PORT(SOC, n)					\
+	{								\
+		.chip.label = "gpio-" #n,				\
+		.base = SOC ## _IO_ADDRESS(MX2x_GPIO_BASE_ADDR +	\
+				n * 0x100),				\
+		.virtual_irq_start = MXC_GPIO_IRQ_START + n * 32,	\
+	}
+
+#define DEFINE_MXC_GPIO_PORTS(SOC, pfx)					\
+	static struct mxc_gpio_port pfx ## _gpio_ports[] = {		\
+		DEFINE_MXC_GPIO_PORT_IRQ(SOC, 0, SOC ## _INT_GPIO),	\
+		DEFINE_MXC_GPIO_PORT(SOC, 1),				\
+		DEFINE_MXC_GPIO_PORT(SOC, 2),				\
+		DEFINE_MXC_GPIO_PORT(SOC, 3),				\
+		DEFINE_MXC_GPIO_PORT(SOC, 4),				\
+		DEFINE_MXC_GPIO_PORT(SOC, 5),				\
+	}
+
+#ifdef CONFIG_MACH_MX21
+DEFINE_MXC_GPIO_PORTS(MX21, imx21);
+#endif
+
+#ifdef CONFIG_MACH_MX27
+DEFINE_MXC_GPIO_PORTS(MX27, imx27);
+#endif
 
 int __init mxc_register_gpios(void)
 {
-	return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
+#ifdef CONFIG_MACH_MX21
+	if (cpu_is_mx21())
+		return mxc_gpio_init(imx21_gpio_ports, ARRAY_SIZE(imx21_gpio_ports));
+	else
+#endif
+#ifdef CONFIG_MACH_MX27
+	if (cpu_is_mx27())
+		return mxc_gpio_init(imx27_gpio_ports, ARRAY_SIZE(imx27_gpio_ports));
+	else
+#endif
+		return 0;
 }
+
+#ifdef CONFIG_MACH_MX21
+static struct resource mx21_usbhc_resources[] = {
+	{
+		.start	= MX21_BASE_ADDR,
+		.end	= MX21_BASE_ADDR + 0x1FFF,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start		= MX21_INT_USBHOST,
+		.end		= MX21_INT_USBHOST,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mx21_usbhc_device = {
+	.name		= "imx21-hcd",
+	.id		= 0,
+	.dev		= {
+		.dma_mask = &mx21_usbhc_device.dev.coherent_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.num_resources	= ARRAY_SIZE(mx21_usbhc_resources),
+	.resource	= mx21_usbhc_resources,
+};
+#endif
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/devices.h linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/devices.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/devices.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/devices.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,8 +1,10 @@
 extern struct platform_device mxc_gpt1;
 extern struct platform_device mxc_gpt2;
+#ifdef CONFIG_MACH_MX27
 extern struct platform_device mxc_gpt3;
 extern struct platform_device mxc_gpt4;
 extern struct platform_device mxc_gpt5;
+#endif
 extern struct platform_device mxc_wdt;
 extern struct platform_device mxc_uart_device0;
 extern struct platform_device mxc_uart_device1;
@@ -11,12 +13,19 @@ extern struct platform_device mxc_uart_d
 extern struct platform_device mxc_uart_device4;
 extern struct platform_device mxc_uart_device5;
 extern struct platform_device mxc_w1_master_device;
-extern struct platform_device mxc_nand_device;
+#ifdef CONFIG_MACH_MX21
+extern struct platform_device imx21_nand_device;
+#endif
+#ifdef CONFIG_MACH_MX27
+extern struct platform_device imx27_nand_device;
+#endif
 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;
+#ifdef CONFIG_MACH_MX27
 extern struct platform_device mxc_i2c_device1;
+#endif
 extern struct platform_device mxc_sdhc_device0;
 extern struct platform_device mxc_sdhc_device1;
 extern struct platform_device mxc_otg_udc_device;
@@ -25,6 +34,9 @@ extern struct platform_device mxc_usbh1;
 extern struct platform_device mxc_usbh2;
 extern struct platform_device mxc_spi_device0;
 extern struct platform_device mxc_spi_device1;
+#ifdef CONFIG_MACH_MX27
 extern struct platform_device mxc_spi_device2;
+#endif
+extern struct platform_device mx21_usbhc_device;
 extern struct platform_device imx_ssi_device0;
 extern struct platform_device imx_ssi_device1;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/eukrea_cpuimx27.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/eukrea_cpuimx27.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/eukrea_cpuimx27.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/eukrea_cpuimx27.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2009 Eric Benard - eric@eukrea.com
- *
- * Based on pcm038.c which is :
- * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
- * Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/i2c.h>
-#include <linux/io.h>
-#include <linux/mtd/plat-ram.h>
-#include <linux/mtd/physmap.h>
-#include <linux/platform_device.h>
-#include <linux/serial_8250.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-
-#include <mach/board-eukrea_cpuimx27.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/i2c.h>
-#include <mach/iomux.h>
-#include <mach/imx-uart.h>
-#include <mach/mxc_nand.h>
-
-#include "devices.h"
-
-static int eukrea_cpuimx27_pins[] = {
-	/* UART1 */
-	PE12_PF_UART1_TXD,
-	PE13_PF_UART1_RXD,
-	PE14_PF_UART1_CTS,
-	PE15_PF_UART1_RTS,
-	/* UART4 */
-	PB26_AF_UART4_RTS,
-	PB28_AF_UART4_TXD,
-	PB29_AF_UART4_CTS,
-	PB31_AF_UART4_RXD,
-	/* FEC */
-	PD0_AIN_FEC_TXD0,
-	PD1_AIN_FEC_TXD1,
-	PD2_AIN_FEC_TXD2,
-	PD3_AIN_FEC_TXD3,
-	PD4_AOUT_FEC_RX_ER,
-	PD5_AOUT_FEC_RXD1,
-	PD6_AOUT_FEC_RXD2,
-	PD7_AOUT_FEC_RXD3,
-	PD8_AF_FEC_MDIO,
-	PD9_AIN_FEC_MDC,
-	PD10_AOUT_FEC_CRS,
-	PD11_AOUT_FEC_TX_CLK,
-	PD12_AOUT_FEC_RXD0,
-	PD13_AOUT_FEC_RX_DV,
-	PD14_AOUT_FEC_RX_CLK,
-	PD15_AOUT_FEC_COL,
-	PD16_AIN_FEC_TX_ER,
-	PF23_AIN_FEC_TX_EN,
-	/* I2C1 */
-	PD17_PF_I2C_DATA,
-	PD18_PF_I2C_CLK,
-	/* SDHC2 */
-	PB4_PF_SD2_D0,
-	PB5_PF_SD2_D1,
-	PB6_PF_SD2_D2,
-	PB7_PF_SD2_D3,
-	PB8_PF_SD2_CMD,
-	PB9_PF_SD2_CLK,
-#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
-	/* Quad UART's IRQ */
-	GPIO_PORTD | 22 | GPIO_GPIO | GPIO_IN,
-	GPIO_PORTD | 23 | GPIO_GPIO | GPIO_IN,
-	GPIO_PORTD | 27 | GPIO_GPIO | GPIO_IN,
-	GPIO_PORTD | 30 | GPIO_GPIO | GPIO_IN,
-#endif
-};
-
-static struct physmap_flash_data eukrea_cpuimx27_flash_data = {
-	.width = 2,
-};
-
-static struct resource eukrea_cpuimx27_flash_resource = {
-	.start = 0xc0000000,
-	.end   = 0xc3ffffff,
-	.flags = IORESOURCE_MEM,
-};
-
-static struct platform_device eukrea_cpuimx27_nor_mtd_device = {
-	.name = "physmap-flash",
-	.id = 0,
-	.dev = {
-		.platform_data = &eukrea_cpuimx27_flash_data,
-	},
-	.num_resources = 1,
-	.resource = &eukrea_cpuimx27_flash_resource,
-};
-
-static struct imxuart_platform_data uart_pdata[] = {
-	{
-		.flags = IMXUART_HAVE_RTSCTS,
-	}, {
-		.flags = IMXUART_HAVE_RTSCTS,
-	},
-};
-
-static struct mxc_nand_platform_data eukrea_cpuimx27_nand_board_info = {
-	.width = 1,
-	.hw_ecc = 1,
-};
-
-static struct platform_device *platform_devices[] __initdata = {
-	&eukrea_cpuimx27_nor_mtd_device,
-	&mxc_fec_device,
-};
-
-static struct imxi2c_platform_data eukrea_cpuimx27_i2c_1_data = {
-	.bitrate = 100000,
-};
-
-static struct i2c_board_info eukrea_cpuimx27_i2c_devices[] = {
-	{
-		I2C_BOARD_INFO("pcf8563", 0x51),
-	},
-};
-
-#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
-static struct plat_serial8250_port serial_platform_data[] = {
-	{
-		.mapbase = (unsigned long)(CS3_BASE_ADDR + 0x200000),
-		.irq = IRQ_GPIOB(23),
-		.uartclk = 14745600,
-		.regshift = 1,
-		.iotype = UPIO_MEM,
-		.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
-	}, {
-		.mapbase = (unsigned long)(CS3_BASE_ADDR + 0x400000),
-		.irq = IRQ_GPIOB(22),
-		.uartclk = 14745600,
-		.regshift = 1,
-		.iotype = UPIO_MEM,
-		.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
-	}, {
-		.mapbase = (unsigned long)(CS3_BASE_ADDR + 0x800000),
-		.irq = IRQ_GPIOB(27),
-		.uartclk = 14745600,
-		.regshift = 1,
-		.iotype = UPIO_MEM,
-		.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
-	}, {
-		.mapbase = (unsigned long)(CS3_BASE_ADDR + 0x1000000),
-		.irq = IRQ_GPIOB(30),
-		.uartclk = 14745600,
-		.regshift = 1,
-		.iotype = UPIO_MEM,
-		.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
-	}, {
-	}
-};
-
-static struct platform_device serial_device = {
-	.name = "serial8250",
-	.id = 0,
-	.dev = {
-		.platform_data = serial_platform_data,
-	},
-};
-#endif
-
-static void __init eukrea_cpuimx27_init(void)
-{
-	mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins,
-		ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27");
-
-	mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
-
-	mxc_register_device(&mxc_nand_device, &eukrea_cpuimx27_nand_board_info);
-
-	i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices,
-				ARRAY_SIZE(eukrea_cpuimx27_i2c_devices));
-
-	mxc_register_device(&mxc_i2c_device0, &eukrea_cpuimx27_i2c_1_data);
-
-	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-
-#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2)
-	/* SDHC2 can be used for Wifi */
-	mxc_register_device(&mxc_sdhc_device1, NULL);
-	/* in which case UART4 is also used for Bluetooth */
-	mxc_register_device(&mxc_uart_device3, &uart_pdata[1]);
-#endif
-
-#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
-	platform_device_register(&serial_device);
-#endif
-
-#ifdef CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD
-	eukrea_mbimx27_baseboard_init();
-#endif
-}
-
-static void __init eukrea_cpuimx27_timer_init(void)
-{
-	mx27_clocks_init(26000000);
-}
-
-static struct sys_timer eukrea_cpuimx27_timer = {
-	.init = eukrea_cpuimx27_timer_init,
-};
-
-MACHINE_START(CPUIMX27, "EUKREA CPUIMX27")
-	.phys_io        = AIPI_BASE_ADDR,
-	.io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx27_map_io,
-	.init_irq       = mx27_init_irq,
-	.init_machine   = eukrea_cpuimx27_init,
-	.timer          = &eukrea_cpuimx27_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,7 @@
 #include <asm/mach/arch.h>
 
 #include <mach/common.h>
-#include <mach/iomux.h>
+#include <mach/iomux-mx27.h>
 #include <mach/imxfb.h>
 #include <mach/hardware.h>
 #include <mach/mmc.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/generic.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/generic.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/generic.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,97 +0,0 @@
-/*
- * generic.c
- *
- * Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#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>
-
-/* MX27 memory map definition */
-static struct map_desc mxc_io_desc[] __initdata = {
-	/*
-	 * this fixed mapping covers:
-	 * - AIPI1
-	 * - AIPI2
-	 * - AITC
-	 * - ROM Patch
-	 * - and some reserved space
-	 */
-	{
-		.virtual = AIPI_BASE_ADDR_VIRT,
-		.pfn = __phys_to_pfn(AIPI_BASE_ADDR),
-		.length = AIPI_SIZE,
-		.type = MT_DEVICE
-	},
-	/*
-	 * this fixed mapping covers:
-	 * - CSI
-	 * - ATA
-	 */
-	{
-		.virtual = SAHB1_BASE_ADDR_VIRT,
-		.pfn = __phys_to_pfn(SAHB1_BASE_ADDR),
-		.length = SAHB1_SIZE,
-		.type = MT_DEVICE
-	},
-	/*
-	 * this fixed mapping covers:
-	 * - EMI
-	 */
-	{
-		.virtual = X_MEMC_BASE_ADDR_VIRT,
-		.pfn = __phys_to_pfn(X_MEMC_BASE_ADDR),
-		.length = X_MEMC_SIZE,
-		.type = MT_DEVICE
-	}
-};
-
-/*
- * Initialize the memory map. It is called during the
- * system startup to create static physical to virtual
- * memory map for the IO modules.
- */
-void __init mx21_map_io(void)
-{
-	mxc_set_cpu_type(MXC_CPU_MX21);
-	mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR));
-
-	iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
-}
-
-void __init mx27_map_io(void)
-{
-	mxc_set_cpu_type(MXC_CPU_MX27);
-	mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR));
-
-	iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
-}
-
-void __init mx27_init_irq(void)
-{
-	mxc_init_irq(IO_ADDRESS(AVIC_BASE_ADDR));
-}
-
-void __init mx21_init_irq(void)
-{
-	mx27_init_irq();
-}
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@ config MACH_MX27ADS
 config MACH_PCM038
 	bool "Phytec phyCORE-i.MX27 CPU module (pcm038)"
 	depends on MACH_MX27
+	select MXC_ULPI if USB_ULPI
 	help
 	  Include support for phyCORE-i.MX27 (aka pcm038) platform. This
 	  includes specific configurations for the module and its peripherals.
@@ -55,7 +56,7 @@ config MACH_PCM970_BASEBOARD
 
 endchoice
 
-config MACH_EUKREA_CPUIMX27
+config MACH_CPUIMX27
 	bool "Eukrea CPUIMX27 module"
 	depends on MACH_MX27
 	help
@@ -64,14 +65,14 @@ config MACH_EUKREA_CPUIMX27
 
 config MACH_EUKREA_CPUIMX27_USESDHC2
 	bool "CPUIMX27 integrates SDHC2 module"
-	depends on MACH_EUKREA_CPUIMX27
+	depends on MACH_CPUIMX27
 	help
 	  This adds support for the internal SDHC2 used on CPUIMX27 used
 	  for wifi or eMMC.
 
 choice
 	prompt "Baseboard"
-	depends on MACH_EUKREA_CPUIMX27
+	depends on MACH_CPUIMX27
 	default MACH_EUKREA_MBIMX27_BASEBOARD
 
 config MACH_EUKREA_MBIMX27_BASEBOARD
@@ -90,7 +91,7 @@ config MACH_MX27_3DS
 	  Include support for MX27PDK platform. This includes specific
 	  configurations for the board and its peripherals.
 
-config MACH_MX27LITE
+config MACH_IMX27LITE
 	bool "LogicPD MX27 LITEKIT platform"
 	depends on MACH_MX27
 	help
@@ -100,6 +101,7 @@ config MACH_MX27LITE
 config MACH_PCA100
 	bool "Phytec phyCARD-s (pca100)"
 	depends on MACH_MX27
+	select MXC_ULPI if USB_ULPI
 	help
 	  Include support for phyCARD-s (aka pca100) platform. This
 	  includes specific configurations for the module and its peripherals.
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-cpuimx27.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-cpuimx27.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-cpuimx27.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-cpuimx27.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2009 Eric Benard - eric@eukrea.com
+ *
+ * Based on pcm038.c which is :
+ * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/board-eukrea_cpuimx27.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/i2c.h>
+#include <mach/iomux-mx27.h>
+#include <mach/imx-uart.h>
+#include <mach/mxc_nand.h>
+
+#include "devices.h"
+
+static int eukrea_cpuimx27_pins[] = {
+	/* UART1 */
+	PE12_PF_UART1_TXD,
+	PE13_PF_UART1_RXD,
+	PE14_PF_UART1_CTS,
+	PE15_PF_UART1_RTS,
+	/* UART4 */
+	PB26_AF_UART4_RTS,
+	PB28_AF_UART4_TXD,
+	PB29_AF_UART4_CTS,
+	PB31_AF_UART4_RXD,
+	/* FEC */
+	PD0_AIN_FEC_TXD0,
+	PD1_AIN_FEC_TXD1,
+	PD2_AIN_FEC_TXD2,
+	PD3_AIN_FEC_TXD3,
+	PD4_AOUT_FEC_RX_ER,
+	PD5_AOUT_FEC_RXD1,
+	PD6_AOUT_FEC_RXD2,
+	PD7_AOUT_FEC_RXD3,
+	PD8_AF_FEC_MDIO,
+	PD9_AIN_FEC_MDC,
+	PD10_AOUT_FEC_CRS,
+	PD11_AOUT_FEC_TX_CLK,
+	PD12_AOUT_FEC_RXD0,
+	PD13_AOUT_FEC_RX_DV,
+	PD14_AOUT_FEC_RX_CLK,
+	PD15_AOUT_FEC_COL,
+	PD16_AIN_FEC_TX_ER,
+	PF23_AIN_FEC_TX_EN,
+	/* I2C1 */
+	PD17_PF_I2C_DATA,
+	PD18_PF_I2C_CLK,
+	/* SDHC2 */
+	PB4_PF_SD2_D0,
+	PB5_PF_SD2_D1,
+	PB6_PF_SD2_D2,
+	PB7_PF_SD2_D3,
+	PB8_PF_SD2_CMD,
+	PB9_PF_SD2_CLK,
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+	/* Quad UART's IRQ */
+	GPIO_PORTD | 22 | GPIO_GPIO | GPIO_IN,
+	GPIO_PORTD | 23 | GPIO_GPIO | GPIO_IN,
+	GPIO_PORTD | 27 | GPIO_GPIO | GPIO_IN,
+	GPIO_PORTD | 30 | GPIO_GPIO | GPIO_IN,
+#endif
+};
+
+static struct physmap_flash_data eukrea_cpuimx27_flash_data = {
+	.width = 2,
+};
+
+static struct resource eukrea_cpuimx27_flash_resource = {
+	.start = 0xc0000000,
+	.end   = 0xc3ffffff,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device eukrea_cpuimx27_nor_mtd_device = {
+	.name = "physmap-flash",
+	.id = 0,
+	.dev = {
+		.platform_data = &eukrea_cpuimx27_flash_data,
+	},
+	.num_resources = 1,
+	.resource = &eukrea_cpuimx27_flash_resource,
+};
+
+static struct imxuart_platform_data uart_pdata[] = {
+	{
+		.flags = IMXUART_HAVE_RTSCTS,
+	}, {
+		.flags = IMXUART_HAVE_RTSCTS,
+	},
+};
+
+static struct mxc_nand_platform_data eukrea_cpuimx27_nand_board_info = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+	&eukrea_cpuimx27_nor_mtd_device,
+	&mxc_fec_device,
+};
+
+static struct imxi2c_platform_data eukrea_cpuimx27_i2c_1_data = {
+	.bitrate = 100000,
+};
+
+static struct i2c_board_info eukrea_cpuimx27_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("pcf8563", 0x51),
+	},
+};
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+static struct plat_serial8250_port serial_platform_data[] = {
+	{
+		.mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x200000),
+		.irq = IRQ_GPIOB(23),
+		.uartclk = 14745600,
+		.regshift = 1,
+		.iotype = UPIO_MEM,
+		.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+	}, {
+		.mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x400000),
+		.irq = IRQ_GPIOB(22),
+		.uartclk = 14745600,
+		.regshift = 1,
+		.iotype = UPIO_MEM,
+		.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+	}, {
+		.mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x800000),
+		.irq = IRQ_GPIOB(27),
+		.uartclk = 14745600,
+		.regshift = 1,
+		.iotype = UPIO_MEM,
+		.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+	}, {
+		.mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x1000000),
+		.irq = IRQ_GPIOB(30),
+		.uartclk = 14745600,
+		.regshift = 1,
+		.iotype = UPIO_MEM,
+		.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+	}, {
+	}
+};
+
+static struct platform_device serial_device = {
+	.name = "serial8250",
+	.id = 0,
+	.dev = {
+		.platform_data = serial_platform_data,
+	},
+};
+#endif
+
+static void __init eukrea_cpuimx27_init(void)
+{
+	mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins,
+		ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27");
+
+	mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
+
+	mxc_register_device(&imx27_nand_device,
+			&eukrea_cpuimx27_nand_board_info);
+
+	i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices,
+				ARRAY_SIZE(eukrea_cpuimx27_i2c_devices));
+
+	mxc_register_device(&mxc_i2c_device0, &eukrea_cpuimx27_i2c_1_data);
+
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2)
+	/* SDHC2 can be used for Wifi */
+	mxc_register_device(&mxc_sdhc_device1, NULL);
+	/* in which case UART4 is also used for Bluetooth */
+	mxc_register_device(&mxc_uart_device3, &uart_pdata[1]);
+#endif
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+	platform_device_register(&serial_device);
+#endif
+
+#ifdef CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD
+	eukrea_mbimx27_baseboard_init();
+#endif
+}
+
+static void __init eukrea_cpuimx27_timer_init(void)
+{
+	mx27_clocks_init(26000000);
+}
+
+static struct sys_timer eukrea_cpuimx27_timer = {
+	.init = eukrea_cpuimx27_timer_init,
+};
+
+MACHINE_START(CPUIMX27, "EUKREA CPUIMX27")
+	.phys_io        = MX27_AIPI_BASE_ADDR,
+	.io_pg_offst    = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = MX27_PHYS_OFFSET + 0x100,
+	.map_io         = mx27_map_io,
+	.init_irq       = mx27_init_irq,
+	.init_machine   = eukrea_cpuimx27_init,
+	.timer          = &eukrea_cpuimx27_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-imx27lite.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-imx27lite.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-imx27lite.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-imx27lite.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ * Copyright 2009 Daniel Schaeffer (daniel.schaeffer@timesys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx27.h>
+#include <mach/board-mx27lite.h>
+
+#include "devices.h"
+
+static unsigned int mx27lite_pins[] = {
+	/* UART1 */
+	PE12_PF_UART1_TXD,
+	PE13_PF_UART1_RXD,
+	PE14_PF_UART1_CTS,
+	PE15_PF_UART1_RTS,
+	/* FEC */
+	PD0_AIN_FEC_TXD0,
+	PD1_AIN_FEC_TXD1,
+	PD2_AIN_FEC_TXD2,
+	PD3_AIN_FEC_TXD3,
+	PD4_AOUT_FEC_RX_ER,
+	PD5_AOUT_FEC_RXD1,
+	PD6_AOUT_FEC_RXD2,
+	PD7_AOUT_FEC_RXD3,
+	PD8_AF_FEC_MDIO,
+	PD9_AIN_FEC_MDC,
+	PD10_AOUT_FEC_CRS,
+	PD11_AOUT_FEC_TX_CLK,
+	PD12_AOUT_FEC_RXD0,
+	PD13_AOUT_FEC_RX_DV,
+	PD14_AOUT_FEC_RX_CLK,
+	PD15_AOUT_FEC_COL,
+	PD16_AIN_FEC_TX_ER,
+	PF23_AIN_FEC_TX_EN,
+};
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+	&mxc_fec_device,
+};
+
+static void __init mx27lite_init(void)
+{
+	mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins),
+		"imx27lite");
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init mx27lite_timer_init(void)
+{
+	mx27_clocks_init(26000000);
+}
+
+static struct sys_timer mx27lite_timer = {
+	.init	= mx27lite_timer_init,
+};
+
+MACHINE_START(IMX27LITE, "LogicPD i.MX27LITE")
+	.phys_io        = MX27_AIPI_BASE_ADDR,
+	.io_pg_offst    = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = MX27_PHYS_OFFSET + 0x100,
+	.map_io         = mx27_map_io,
+	.init_irq       = mx27_init_irq,
+	.init_machine   = mx27lite_init,
+	.timer          = &mx27lite_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-mx21ads.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-mx21ads.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-mx21ads.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-mx21ads.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,294 @@
+/*
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <mach/imx-uart.h>
+#include <mach/imxfb.h>
+#include <mach/iomux-mx21.h>
+#include <mach/mxc_nand.h>
+#include <mach/mmc.h>
+#include <mach/board-mx21ads.h>
+
+#include "devices.h"
+
+static unsigned int mx21ads_pins[] = {
+
+	/* CS8900A */
+	(GPIO_PORTE | GPIO_GPIO | GPIO_IN | 11),
+
+	/* UART1 */
+	PE12_PF_UART1_TXD,
+	PE13_PF_UART1_RXD,
+	PE14_PF_UART1_CTS,
+	PE15_PF_UART1_RTS,
+
+	/* UART3 (IrDA) - only TXD and RXD */
+	PE8_PF_UART3_TXD,
+	PE9_PF_UART3_RXD,
+
+	/* UART4 */
+	PB26_AF_UART4_RTS,
+	PB28_AF_UART4_TXD,
+	PB29_AF_UART4_CTS,
+	PB31_AF_UART4_RXD,
+
+	/* LCDC */
+	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,
+	PA24_PF_REV,     /* Sharp panel dedicated signal */
+	PA25_PF_CLS,     /* Sharp panel dedicated signal */
+	PA26_PF_PS,      /* Sharp panel dedicated signal */
+	PA27_PF_SPL_SPR, /* Sharp panel dedicated signal */
+	PA28_PF_HSYNC,
+	PA29_PF_VSYNC,
+	PA30_PF_CONTRAST,
+	PA31_PF_OE_ACD,
+
+	/* MMC/SDHC */
+	PE18_PF_SD1_D0,
+	PE19_PF_SD1_D1,
+	PE20_PF_SD1_D2,
+	PE21_PF_SD1_D3,
+	PE22_PF_SD1_CMD,
+	PE23_PF_SD1_CLK,
+
+	/* NFC */
+	PF0_PF_NRFB,
+	PF1_PF_NFCE,
+	PF2_PF_NFWP,
+	PF3_PF_NFCLE,
+	PF4_PF_NFALE,
+	PF5_PF_NFRE,
+	PF6_PF_NFWE,
+	PF7_PF_NFIO0,
+	PF8_PF_NFIO1,
+	PF9_PF_NFIO2,
+	PF10_PF_NFIO3,
+	PF11_PF_NFIO4,
+	PF12_PF_NFIO5,
+	PF13_PF_NFIO6,
+	PF14_PF_NFIO7,
+};
+
+/* ADS's NOR flash: 2x AM29BDS128HE9VKI on 32-bit bus */
+static struct physmap_flash_data mx21ads_flash_data = {
+	.width = 4,
+};
+
+static struct resource mx21ads_flash_resource = {
+	.start = MX21_CS0_BASE_ADDR,
+	.end = MX21_CS0_BASE_ADDR + 0x02000000 - 1,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device mx21ads_nor_mtd_device = {
+	.name = "physmap-flash",
+	.id = 0,
+	.dev = {
+		.platform_data = &mx21ads_flash_data,
+	},
+	.num_resources = 1,
+	.resource = &mx21ads_flash_resource,
+};
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct imxuart_platform_data uart_norts_pdata = {
+};
+
+
+static int mx21ads_fb_init(struct platform_device *pdev)
+{
+	u16 tmp;
+
+	tmp = __raw_readw(MX21ADS_IO_REG);
+	tmp |= MX21ADS_IO_LCDON;
+	__raw_writew(tmp, MX21ADS_IO_REG);
+	return 0;
+}
+
+static void mx21ads_fb_exit(struct platform_device *pdev)
+{
+	u16 tmp;
+
+	tmp = __raw_readw(MX21ADS_IO_REG);
+	tmp &= ~MX21ADS_IO_LCDON;
+	__raw_writew(tmp, MX21ADS_IO_REG);
+}
+
+/*
+ * Connected is a portrait Sharp-QVGA display
+ * of type: LQ035Q7DB02
+ */
+static struct imx_fb_videomode mx21ads_modes[] = {
+	{
+		.mode = {
+			.name		= "Sharp-LQ035Q7",
+			.refresh	= 60,
+			.xres		= 240,
+			.yres		= 320,
+			.pixclock	= 188679, /* in ps (5.3MHz) */
+			.hsync_len	= 2,
+			.left_margin	= 6,
+			.right_margin	= 16,
+			.vsync_len	= 1,
+			.upper_margin	= 8,
+			.lower_margin	= 10,
+		},
+		.pcr		= 0xfb108bc7,
+		.bpp		= 16,
+	},
+};
+
+static struct imx_fb_platform_data mx21ads_fb_data = {
+	.mode = mx21ads_modes,
+	.num_modes = ARRAY_SIZE(mx21ads_modes),
+
+	.pwmr		= 0x00a903ff,
+	.lscr1		= 0x00120300,
+	.dmacr		= 0x00020008,
+
+	.init = mx21ads_fb_init,
+	.exit = mx21ads_fb_exit,
+};
+
+static int mx21ads_sdhc_get_ro(struct device *dev)
+{
+	return (__raw_readw(MX21ADS_IO_REG) & MX21ADS_IO_SD_WP) ? 1 : 0;
+}
+
+static int mx21ads_sdhc_init(struct device *dev, irq_handler_t detect_irq,
+	void *data)
+{
+	int ret;
+
+	ret = request_irq(IRQ_GPIOD(25), detect_irq,
+		IRQF_TRIGGER_FALLING, "mmc-detect", data);
+	if (ret)
+		goto out;
+	return 0;
+out:
+	return ret;
+}
+
+static void mx21ads_sdhc_exit(struct device *dev, void *data)
+{
+	free_irq(IRQ_GPIOD(25), data);
+}
+
+static struct imxmmc_platform_data mx21ads_sdhc_pdata = {
+	.ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31, /* 3.0V */
+	.get_ro = mx21ads_sdhc_get_ro,
+	.init = mx21ads_sdhc_init,
+	.exit = mx21ads_sdhc_exit,
+};
+
+static struct mxc_nand_platform_data mx21ads_nand_board_info = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
+static struct map_desc mx21ads_io_desc[] __initdata = {
+	/*
+	 * Memory-mapped I/O on MX21ADS Base board:
+	 *   - CS8900A Ethernet controller
+	 *   - ST16C2552CJ UART
+	 *   - CPU and Base board version
+	 *   - Base board I/O register
+	 */
+	{
+		.virtual = MX21ADS_MMIO_BASE_ADDR,
+		.pfn = __phys_to_pfn(MX21_CS1_BASE_ADDR),
+		.length = MX21ADS_MMIO_SIZE,
+		.type = MT_DEVICE,
+	},
+};
+
+static void __init mx21ads_map_io(void)
+{
+	mx21_map_io();
+	iotable_init(mx21ads_io_desc, ARRAY_SIZE(mx21ads_io_desc));
+}
+
+static struct platform_device *platform_devices[] __initdata = {
+	&mx21ads_nor_mtd_device,
+};
+
+static void __init mx21ads_board_init(void)
+{
+	mxc_gpio_setup_multiple_pins(mx21ads_pins, ARRAY_SIZE(mx21ads_pins),
+			"mx21ads");
+
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+	mxc_register_device(&mxc_uart_device2, &uart_norts_pdata);
+	mxc_register_device(&mxc_uart_device3, &uart_pdata);
+	mxc_register_device(&mxc_fb_device, &mx21ads_fb_data);
+	mxc_register_device(&mxc_sdhc_device0, &mx21ads_sdhc_pdata);
+	mxc_register_device(&imx21_nand_device, &mx21ads_nand_board_info);
+
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init mx21ads_timer_init(void)
+{
+	mx21_clocks_init(32768, 26000000);
+}
+
+static struct sys_timer mx21ads_timer = {
+	.init	= mx21ads_timer_init,
+};
+
+MACHINE_START(MX21ADS, "Freescale i.MX21ADS")
+	/* maintainer: Freescale Semiconductor, Inc. */
+	.phys_io        = MX21_AIPI_BASE_ADDR,
+	.io_pg_offst    = ((MX21_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = MX21_PHYS_OFFSET + 0x100,
+	.map_io         = mx21ads_map_io,
+	.init_irq       = mx21_init_irq,
+	.init_machine   = mx21ads_board_init,
+	.timer          = &mx21ads_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-mx27_3ds.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-mx27_3ds.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-mx27_3ds.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-mx27_3ds.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Author: Fabio Estevam <fabio.estevam@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx27.h>
+#include <mach/board-mx27pdk.h>
+
+#include "devices.h"
+
+static unsigned int mx27pdk_pins[] = {
+	/* UART1 */
+	PE12_PF_UART1_TXD,
+	PE13_PF_UART1_RXD,
+	PE14_PF_UART1_CTS,
+	PE15_PF_UART1_RTS,
+	/* FEC */
+	PD0_AIN_FEC_TXD0,
+	PD1_AIN_FEC_TXD1,
+	PD2_AIN_FEC_TXD2,
+	PD3_AIN_FEC_TXD3,
+	PD4_AOUT_FEC_RX_ER,
+	PD5_AOUT_FEC_RXD1,
+	PD6_AOUT_FEC_RXD2,
+	PD7_AOUT_FEC_RXD3,
+	PD8_AF_FEC_MDIO,
+	PD9_AIN_FEC_MDC,
+	PD10_AOUT_FEC_CRS,
+	PD11_AOUT_FEC_TX_CLK,
+	PD12_AOUT_FEC_RXD0,
+	PD13_AOUT_FEC_RX_DV,
+	PD14_AOUT_FEC_RX_CLK,
+	PD15_AOUT_FEC_COL,
+	PD16_AIN_FEC_TX_ER,
+	PF23_AIN_FEC_TX_EN,
+};
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+	&mxc_fec_device,
+};
+
+static void __init mx27pdk_init(void)
+{
+	mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
+		"mx27pdk");
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init mx27pdk_timer_init(void)
+{
+	mx27_clocks_init(26000000);
+}
+
+static struct sys_timer mx27pdk_timer = {
+	.init	= mx27pdk_timer_init,
+};
+
+MACHINE_START(MX27_3DS, "Freescale MX27PDK")
+	/* maintainer: Freescale Semiconductor, Inc. */
+	.phys_io        = MX27_AIPI_BASE_ADDR,
+	.io_pg_offst    = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = MX27_PHYS_OFFSET + 0x100,
+	.map_io         = mx27_map_io,
+	.init_irq       = mx27_init_irq,
+	.init_machine   = mx27pdk_init,
+	.timer          = &mx27pdk_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-mx27ads.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-mx27ads.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-mx27ads.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-mx27ads.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,345 @@
+/*
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <mach/gpio.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx27.h>
+#include <mach/board-mx27ads.h>
+#include <mach/mxc_nand.h>
+#include <mach/i2c.h>
+#include <mach/imxfb.h>
+#include <mach/mmc.h>
+
+#include "devices.h"
+
+static unsigned int mx27ads_pins[] = {
+	/* UART0 */
+	PE12_PF_UART1_TXD,
+	PE13_PF_UART1_RXD,
+	PE14_PF_UART1_CTS,
+	PE15_PF_UART1_RTS,
+	/* UART1 */
+	PE3_PF_UART2_CTS,
+	PE4_PF_UART2_RTS,
+	PE6_PF_UART2_TXD,
+	PE7_PF_UART2_RXD,
+	/* UART2 */
+	PE8_PF_UART3_TXD,
+	PE9_PF_UART3_RXD,
+	PE10_PF_UART3_CTS,
+	PE11_PF_UART3_RTS,
+	/* UART3 */
+	PB26_AF_UART4_RTS,
+	PB28_AF_UART4_TXD,
+	PB29_AF_UART4_CTS,
+	PB31_AF_UART4_RXD,
+	/* UART4 */
+	PB18_AF_UART5_TXD,
+	PB19_AF_UART5_RXD,
+	PB20_AF_UART5_CTS,
+	PB21_AF_UART5_RTS,
+	/* UART5 */
+	PB10_AF_UART6_TXD,
+	PB12_AF_UART6_CTS,
+	PB11_AF_UART6_RXD,
+	PB13_AF_UART6_RTS,
+	/* FEC */
+	PD0_AIN_FEC_TXD0,
+	PD1_AIN_FEC_TXD1,
+	PD2_AIN_FEC_TXD2,
+	PD3_AIN_FEC_TXD3,
+	PD4_AOUT_FEC_RX_ER,
+	PD5_AOUT_FEC_RXD1,
+	PD6_AOUT_FEC_RXD2,
+	PD7_AOUT_FEC_RXD3,
+	PD8_AF_FEC_MDIO,
+	PD9_AIN_FEC_MDC,
+	PD10_AOUT_FEC_CRS,
+	PD11_AOUT_FEC_TX_CLK,
+	PD12_AOUT_FEC_RXD0,
+	PD13_AOUT_FEC_RX_DV,
+	PD14_AOUT_FEC_RX_CLK,
+	PD15_AOUT_FEC_COL,
+	PD16_AIN_FEC_TX_ER,
+	PF23_AIN_FEC_TX_EN,
+	/* I2C2 */
+	PC5_PF_I2C2_SDA,
+	PC6_PF_I2C2_SCL,
+	/* FB */
+	PA5_PF_LSCLK,
+	PA6_PF_LD0,
+	PA7_PF_LD1,
+	PA8_PF_LD2,
+	PA9_PF_LD3,
+	PA10_PF_LD4,
+	PA11_PF_LD5,
+	PA12_PF_LD6,
+	PA13_PF_LD7,
+	PA14_PF_LD8,
+	PA15_PF_LD9,
+	PA16_PF_LD10,
+	PA17_PF_LD11,
+	PA18_PF_LD12,
+	PA19_PF_LD13,
+	PA20_PF_LD14,
+	PA21_PF_LD15,
+	PA22_PF_LD16,
+	PA23_PF_LD17,
+	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,
+	/* OWIRE */
+	PE16_AF_OWIRE,
+	/* SDHC1*/
+	PE18_PF_SD1_D0,
+	PE19_PF_SD1_D1,
+	PE20_PF_SD1_D2,
+	PE21_PF_SD1_D3,
+	PE22_PF_SD1_CMD,
+	PE23_PF_SD1_CLK,
+	/* SDHC2*/
+	PB4_PF_SD2_D0,
+	PB5_PF_SD2_D1,
+	PB6_PF_SD2_D2,
+	PB7_PF_SD2_D3,
+	PB8_PF_SD2_CMD,
+	PB9_PF_SD2_CLK,
+};
+
+static struct mxc_nand_platform_data mx27ads_nand_board_info = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
+/* ADS's NOR flash */
+static struct physmap_flash_data mx27ads_flash_data = {
+	.width = 2,
+};
+
+static struct resource mx27ads_flash_resource = {
+	.start = 0xc0000000,
+	.end = 0xc0000000 + 0x02000000 - 1,
+	.flags = IORESOURCE_MEM,
+
+};
+
+static struct platform_device mx27ads_nor_mtd_device = {
+	.name = "physmap-flash",
+	.id = 0,
+	.dev = {
+		.platform_data = &mx27ads_flash_data,
+	},
+	.num_resources = 1,
+	.resource = &mx27ads_flash_resource,
+};
+
+static struct imxi2c_platform_data mx27ads_i2c_data = {
+	.bitrate = 100000,
+};
+
+static struct i2c_board_info mx27ads_i2c_devices[] = {
+};
+
+void lcd_power(int on)
+{
+	if (on)
+		__raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG);
+	else
+		__raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG);
+}
+
+static struct imx_fb_videomode mx27ads_modes[] = {
+	{
+		.mode = {
+			.name		= "Sharp-LQ035Q7",
+			.refresh	= 60,
+			.xres		= 240,
+			.yres		= 320,
+			.pixclock	= 188679, /* in ps (5.3MHz) */
+			.hsync_len	= 1,
+			.left_margin	= 9,
+			.right_margin	= 16,
+			.vsync_len	= 1,
+			.upper_margin	= 7,
+			.lower_margin	= 9,
+		},
+		.bpp		= 16,
+		.pcr		= 0xFB008BC0,
+	},
+};
+
+static struct imx_fb_platform_data mx27ads_fb_data = {
+	.mode = mx27ads_modes,
+	.num_modes = ARRAY_SIZE(mx27ads_modes),
+
+	/*
+	 * - HSYNC active high
+	 * - VSYNC active high
+	 * - clk notenabled while idle
+	 * - clock inverted
+	 * - data not inverted
+	 * - data enable low active
+	 * - enable sharp mode
+	 */
+	.pwmr		= 0x00A903FF,
+	.lscr1		= 0x00120300,
+	.dmacr		= 0x00020010,
+
+	.lcd_power	= lcd_power,
+};
+
+static int mx27ads_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+			      void *data)
+{
+	return request_irq(IRQ_GPIOE(21), detect_irq, IRQF_TRIGGER_RISING,
+			   "sdhc1-card-detect", data);
+}
+
+static int mx27ads_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
+			      void *data)
+{
+	return request_irq(IRQ_GPIOB(7), detect_irq, IRQF_TRIGGER_RISING,
+			   "sdhc2-card-detect", data);
+}
+
+static void mx27ads_sdhc1_exit(struct device *dev, void *data)
+{
+	free_irq(IRQ_GPIOE(21), data);
+}
+
+static void mx27ads_sdhc2_exit(struct device *dev, void *data)
+{
+	free_irq(IRQ_GPIOB(7), data);
+}
+
+static struct imxmmc_platform_data sdhc1_pdata = {
+	.init = mx27ads_sdhc1_init,
+	.exit = mx27ads_sdhc1_exit,
+};
+
+static struct imxmmc_platform_data sdhc2_pdata = {
+	.init = mx27ads_sdhc2_init,
+	.exit = mx27ads_sdhc2_exit,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+	&mx27ads_nor_mtd_device,
+	&mxc_fec_device,
+	&mxc_w1_master_device,
+};
+
+static struct imxuart_platform_data uart_pdata[] = {
+	{
+		.flags = IMXUART_HAVE_RTSCTS,
+	}, {
+		.flags = IMXUART_HAVE_RTSCTS,
+	}, {
+		.flags = IMXUART_HAVE_RTSCTS,
+	}, {
+		.flags = IMXUART_HAVE_RTSCTS,
+	}, {
+		.flags = IMXUART_HAVE_RTSCTS,
+	}, {
+		.flags = IMXUART_HAVE_RTSCTS,
+	},
+};
+
+static void __init mx27ads_board_init(void)
+{
+	mxc_gpio_setup_multiple_pins(mx27ads_pins, ARRAY_SIZE(mx27ads_pins),
+			"mx27ads");
+
+	mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
+	mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
+	mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
+	mxc_register_device(&mxc_uart_device3, &uart_pdata[3]);
+	mxc_register_device(&mxc_uart_device4, &uart_pdata[4]);
+	mxc_register_device(&mxc_uart_device5, &uart_pdata[5]);
+	mxc_register_device(&imx27_nand_device, &mx27ads_nand_board_info);
+
+	/* only the i2c master 1 is used on this CPU card */
+	i2c_register_board_info(1, mx27ads_i2c_devices,
+				ARRAY_SIZE(mx27ads_i2c_devices));
+	mxc_register_device(&mxc_i2c_device1, &mx27ads_i2c_data);
+	mxc_register_device(&mxc_fb_device, &mx27ads_fb_data);
+	mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
+	mxc_register_device(&mxc_sdhc_device1, &sdhc2_pdata);
+
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init mx27ads_timer_init(void)
+{
+	unsigned long fref = 26000000;
+
+	if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0)
+		fref = 27000000;
+
+	mx27_clocks_init(fref);
+}
+
+static struct sys_timer mx27ads_timer = {
+	.init	= mx27ads_timer_init,
+};
+
+static struct map_desc mx27ads_io_desc[] __initdata = {
+	{
+		.virtual = PBC_BASE_ADDRESS,
+		.pfn = __phys_to_pfn(MX27_CS4_BASE_ADDR),
+		.length = SZ_1M,
+		.type = MT_DEVICE,
+	},
+};
+
+static void __init mx27ads_map_io(void)
+{
+	mx27_map_io();
+	iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc));
+}
+
+MACHINE_START(MX27ADS, "Freescale i.MX27ADS")
+	/* maintainer: Freescale Semiconductor, Inc. */
+	.phys_io        = MX27_AIPI_BASE_ADDR,
+	.io_pg_offst    = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = MX27_PHYS_OFFSET + 0x100,
+	.map_io         = mx27ads_map_io,
+	.init_irq       = mx27_init_irq,
+	.init_machine   = mx27ads_board_init,
+	.timer          = &mx27ads_timer,
+MACHINE_END
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-mxt_td60.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-mxt_td60.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-mxt_td60.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-mxt_td60.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,295 @@
+/*
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <linux/gpio.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx27.h>
+#include <mach/mxc_nand.h>
+#include <mach/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <mach/imxfb.h>
+#include <mach/mmc.h>
+
+#include "devices.h"
+
+static unsigned int mxt_td60_pins[] __initdata = {
+	/* UART0 */
+	PE12_PF_UART1_TXD,
+	PE13_PF_UART1_RXD,
+	PE14_PF_UART1_CTS,
+	PE15_PF_UART1_RTS,
+	/* UART1 */
+	PE3_PF_UART2_CTS,
+	PE4_PF_UART2_RTS,
+	PE6_PF_UART2_TXD,
+	PE7_PF_UART2_RXD,
+	/* UART2 */
+	PE8_PF_UART3_TXD,
+	PE9_PF_UART3_RXD,
+	PE10_PF_UART3_CTS,
+	PE11_PF_UART3_RTS,
+	/* FEC */
+	PD0_AIN_FEC_TXD0,
+	PD1_AIN_FEC_TXD1,
+	PD2_AIN_FEC_TXD2,
+	PD3_AIN_FEC_TXD3,
+	PD4_AOUT_FEC_RX_ER,
+	PD5_AOUT_FEC_RXD1,
+	PD6_AOUT_FEC_RXD2,
+	PD7_AOUT_FEC_RXD3,
+	PD8_AF_FEC_MDIO,
+	PD9_AIN_FEC_MDC,
+	PD10_AOUT_FEC_CRS,
+	PD11_AOUT_FEC_TX_CLK,
+	PD12_AOUT_FEC_RXD0,
+	PD13_AOUT_FEC_RX_DV,
+	PD14_AOUT_FEC_RX_CLK,
+	PD15_AOUT_FEC_COL,
+	PD16_AIN_FEC_TX_ER,
+	PF23_AIN_FEC_TX_EN,
+	/* I2C1 */
+	PD17_PF_I2C_DATA,
+	PD18_PF_I2C_CLK,
+	/* I2C2 */
+	PC5_PF_I2C2_SDA,
+	PC6_PF_I2C2_SCL,
+	/* FB */
+	PA5_PF_LSCLK,
+	PA6_PF_LD0,
+	PA7_PF_LD1,
+	PA8_PF_LD2,
+	PA9_PF_LD3,
+	PA10_PF_LD4,
+	PA11_PF_LD5,
+	PA12_PF_LD6,
+	PA13_PF_LD7,
+	PA14_PF_LD8,
+	PA15_PF_LD9,
+	PA16_PF_LD10,
+	PA17_PF_LD11,
+	PA18_PF_LD12,
+	PA19_PF_LD13,
+	PA20_PF_LD14,
+	PA21_PF_LD15,
+	PA22_PF_LD16,
+	PA23_PF_LD17,
+	PA25_PF_CLS,
+	PA27_PF_SPL_SPR,
+	PA28_PF_HSYNC,
+	PA29_PF_VSYNC,
+	PA30_PF_CONTRAST,
+	PA31_PF_OE_ACD,
+	/* OWIRE */
+	PE16_AF_OWIRE,
+	/* SDHC1*/
+	PE18_PF_SD1_D0,
+	PE19_PF_SD1_D1,
+	PE20_PF_SD1_D2,
+	PE21_PF_SD1_D3,
+	PE22_PF_SD1_CMD,
+	PE23_PF_SD1_CLK,
+	PF8_AF_ATA_IORDY,
+	/* SDHC2*/
+	PB4_PF_SD2_D0,
+	PB5_PF_SD2_D1,
+	PB6_PF_SD2_D2,
+	PB7_PF_SD2_D3,
+	PB8_PF_SD2_CMD,
+	PB9_PF_SD2_CLK,
+};
+
+static struct mxc_nand_platform_data mxt_td60_nand_board_info = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
+static struct imxi2c_platform_data mxt_td60_i2c_data = {
+	.bitrate = 100000,
+};
+
+/* PCA9557 */
+static int mxt_td60_pca9557_setup(struct i2c_client *client,
+				unsigned gpio_base, unsigned ngpio,
+				void *context)
+{
+	static int mxt_td60_gpio_value[] = {
+		-1, -1, -1, -1, -1, -1, -1, 1
+	};
+	int n;
+
+	for (n = 0; n < ARRAY_SIZE(mxt_td60_gpio_value); ++n) {
+		gpio_request(gpio_base + n, "MXT_TD60 GPIO Exp");
+		if (mxt_td60_gpio_value[n] < 0)
+			gpio_direction_input(gpio_base + n);
+		else
+			gpio_direction_output(gpio_base + n,
+						mxt_td60_gpio_value[n]);
+		gpio_export(gpio_base + n, 0);
+	}
+
+	return 0;
+}
+
+static struct pca953x_platform_data mxt_td60_pca9557_pdata = {
+	.gpio_base	= 240, /* place PCA9557 after all MX27 gpio pins */
+	.invert		= 0, /* Do not invert */
+	.setup		= mxt_td60_pca9557_setup,
+};
+
+static struct i2c_board_info mxt_td60_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("pca9557", 0x18),
+		.platform_data = &mxt_td60_pca9557_pdata,
+	},
+};
+
+static struct imxi2c_platform_data mxt_td60_i2c2_data = {
+	.bitrate = 100000,
+};
+
+static struct i2c_board_info mxt_td60_i2c2_devices[] = {
+};
+
+static struct imx_fb_videomode mxt_td60_modes[] = {
+	{
+		.mode = {
+			.name		= "Chimei LW700AT9003",
+			.refresh	= 60,
+			.xres		= 800,
+			.yres		= 480,
+			.pixclock	= 30303,
+			.hsync_len	= 64,
+			.left_margin	= 0x67,
+			.right_margin	= 0x68,
+			.vsync_len	= 16,
+			.upper_margin	= 0x0f,
+			.lower_margin	= 0x0f,
+		},
+		.bpp		= 16,
+		.pcr		= 0xFA208B83,
+	},
+};
+
+static struct imx_fb_platform_data mxt_td60_fb_data = {
+	.mode = mxt_td60_modes,
+	.num_modes = ARRAY_SIZE(mxt_td60_modes),
+
+	/*
+	 * - HSYNC active high
+	 * - VSYNC active high
+	 * - clk notenabled while idle
+	 * - clock inverted
+	 * - data not inverted
+	 * - data enable low active
+	 * - enable sharp mode
+	 */
+	.pwmr		= 0x00A903FF,
+	.lscr1		= 0x00120300,
+	.dmacr		= 0x00020010,
+};
+
+static int mxt_td60_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+				void *data)
+{
+	return request_irq(IRQ_GPIOF(8), detect_irq, IRQF_TRIGGER_FALLING,
+				"sdhc1-card-detect", data);
+}
+
+static void mxt_td60_sdhc1_exit(struct device *dev, void *data)
+{
+	free_irq(IRQ_GPIOF(8), data);
+}
+
+static struct imxmmc_platform_data sdhc1_pdata = {
+	.init = mxt_td60_sdhc1_init,
+	.exit = mxt_td60_sdhc1_exit,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+	&mxc_fec_device,
+};
+
+static struct imxuart_platform_data uart_pdata[] = {
+	{
+		.flags = IMXUART_HAVE_RTSCTS,
+	}, {
+		.flags = IMXUART_HAVE_RTSCTS,
+	}, {
+		.flags = IMXUART_HAVE_RTSCTS,
+	},
+};
+
+static void __init mxt_td60_board_init(void)
+{
+	mxc_gpio_setup_multiple_pins(mxt_td60_pins, ARRAY_SIZE(mxt_td60_pins),
+			"MXT_TD60");
+
+	mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
+	mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
+	mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
+	mxc_register_device(&imx27_nand_device, &mxt_td60_nand_board_info);
+
+	i2c_register_board_info(0, mxt_td60_i2c_devices,
+				ARRAY_SIZE(mxt_td60_i2c_devices));
+
+	i2c_register_board_info(1, mxt_td60_i2c2_devices,
+				ARRAY_SIZE(mxt_td60_i2c2_devices));
+
+	mxc_register_device(&mxc_i2c_device0, &mxt_td60_i2c_data);
+	mxc_register_device(&mxc_i2c_device1, &mxt_td60_i2c2_data);
+	mxc_register_device(&mxc_fb_device, &mxt_td60_fb_data);
+	mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
+
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init mxt_td60_timer_init(void)
+{
+	mx27_clocks_init(26000000);
+}
+
+static struct sys_timer mxt_td60_timer = {
+	.init	= mxt_td60_timer_init,
+};
+
+MACHINE_START(MXT_TD60, "Maxtrack i-MXT TD60")
+	/* maintainer: Maxtrack Industrial */
+	.phys_io	= MX27_AIPI_BASE_ADDR,
+	.io_pg_offst	= ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params	= MX27_PHYS_OFFSET + 0x100,
+	.map_io		= mx27_map_io,
+	.init_irq	= mx27_init_irq,
+	.init_machine	= mxt_td60_board_init,
+	.timer		= &mxt_td60_timer,
+MACHINE_END
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-pca100.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-pca100.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-pca100.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-pca100.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,395 @@
+/*
+ * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * Copyright (C) 2009 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/dma-mapping.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/fsl_devices.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx27.h>
+#include <mach/i2c.h>
+#include <asm/mach/time.h>
+#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
+#include <mach/spi.h>
+#endif
+#include <mach/imx-uart.h>
+#include <mach/audmux.h>
+#include <mach/ssi.h>
+#include <mach/mxc_nand.h>
+#include <mach/irqs.h>
+#include <mach/mmc.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
+
+#include "devices.h"
+
+#define OTG_PHY_CS_GPIO (GPIO_PORTB + 23)
+#define USBH2_PHY_CS_GPIO (GPIO_PORTB + 24)
+
+static int pca100_pins[] = {
+	/* UART1 */
+	PE12_PF_UART1_TXD,
+	PE13_PF_UART1_RXD,
+	PE14_PF_UART1_CTS,
+	PE15_PF_UART1_RTS,
+	/* SDHC */
+	PB4_PF_SD2_D0,
+	PB5_PF_SD2_D1,
+	PB6_PF_SD2_D2,
+	PB7_PF_SD2_D3,
+	PB8_PF_SD2_CMD,
+	PB9_PF_SD2_CLK,
+	/* FEC */
+	PD0_AIN_FEC_TXD0,
+	PD1_AIN_FEC_TXD1,
+	PD2_AIN_FEC_TXD2,
+	PD3_AIN_FEC_TXD3,
+	PD4_AOUT_FEC_RX_ER,
+	PD5_AOUT_FEC_RXD1,
+	PD6_AOUT_FEC_RXD2,
+	PD7_AOUT_FEC_RXD3,
+	PD8_AF_FEC_MDIO,
+	PD9_AIN_FEC_MDC,
+	PD10_AOUT_FEC_CRS,
+	PD11_AOUT_FEC_TX_CLK,
+	PD12_AOUT_FEC_RXD0,
+	PD13_AOUT_FEC_RX_DV,
+	PD14_AOUT_FEC_RX_CLK,
+	PD15_AOUT_FEC_COL,
+	PD16_AIN_FEC_TX_ER,
+	PF23_AIN_FEC_TX_EN,
+	/* SSI1 */
+	PC20_PF_SSI1_FS,
+	PC21_PF_SSI1_RXD,
+	PC22_PF_SSI1_TXD,
+	PC23_PF_SSI1_CLK,
+	/* onboard I2C */
+	PC5_PF_I2C2_SDA,
+	PC6_PF_I2C2_SCL,
+	/* external I2C */
+	PD17_PF_I2C_DATA,
+	PD18_PF_I2C_CLK,
+	/* SPI1 */
+	PD25_PF_CSPI1_RDY,
+	PD29_PF_CSPI1_SCLK,
+	PD30_PF_CSPI1_MISO,
+	PD31_PF_CSPI1_MOSI,
+	/* OTG */
+	OTG_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT,
+	PC7_PF_USBOTG_DATA5,
+	PC8_PF_USBOTG_DATA6,
+	PC9_PF_USBOTG_DATA0,
+	PC10_PF_USBOTG_DATA2,
+	PC11_PF_USBOTG_DATA1,
+	PC12_PF_USBOTG_DATA4,
+	PC13_PF_USBOTG_DATA3,
+	PE0_PF_USBOTG_NXT,
+	PE1_PF_USBOTG_STP,
+	PE2_PF_USBOTG_DIR,
+	PE24_PF_USBOTG_CLK,
+	PE25_PF_USBOTG_DATA7,
+	/* USBH2 */
+	USBH2_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT,
+	PA0_PF_USBH2_CLK,
+	PA1_PF_USBH2_DIR,
+	PA2_PF_USBH2_DATA7,
+	PA3_PF_USBH2_NXT,
+	PA4_PF_USBH2_STP,
+	PD19_AF_USBH2_DATA4,
+	PD20_AF_USBH2_DATA3,
+	PD21_AF_USBH2_DATA6,
+	PD22_AF_USBH2_DATA0,
+	PD23_AF_USBH2_DATA2,
+	PD24_AF_USBH2_DATA1,
+	PD26_AF_USBH2_DATA5,
+};
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct mxc_nand_platform_data pca100_nand_board_info = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+	&mxc_w1_master_device,
+	&mxc_fec_device,
+};
+
+static struct imxi2c_platform_data pca100_i2c_1_data = {
+	.bitrate = 100000,
+};
+
+static struct at24_platform_data board_eeprom = {
+	.byte_len = 4096,
+	.page_size = 32,
+	.flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info pca100_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"
+	}, {
+		I2C_BOARD_INFO("lm75", 0x4a),
+		.type = "lm75"
+	}
+};
+
+#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
+static struct spi_eeprom at25320 = {
+	.name		= "at25320an",
+	.byte_len	= 4096,
+	.page_size	= 32,
+	.flags		= EE_ADDR2,
+};
+
+static struct spi_board_info pca100_spi_board_info[] __initdata = {
+	{
+		.modalias = "at25",
+		.max_speed_hz = 30000,
+		.bus_num = 0,
+		.chip_select = 1,
+		.platform_data = &at25320,
+	},
+};
+
+static int pca100_spi_cs[] = {GPIO_PORTD + 28, GPIO_PORTD + 27};
+
+static struct spi_imx_master pca100_spi_0_data = {
+	.chipselect	= pca100_spi_cs,
+	.num_chipselect = ARRAY_SIZE(pca100_spi_cs),
+};
+#endif
+
+static void pca100_ac97_warm_reset(struct snd_ac97 *ac97)
+{
+	mxc_gpio_mode(GPIO_PORTC | 20 | GPIO_GPIO | GPIO_OUT);
+	gpio_set_value(GPIO_PORTC + 20, 1);
+	udelay(2);
+	gpio_set_value(GPIO_PORTC + 20, 0);
+	mxc_gpio_mode(PC20_PF_SSI1_FS);
+	msleep(2);
+}
+
+static void pca100_ac97_cold_reset(struct snd_ac97 *ac97)
+{
+	mxc_gpio_mode(GPIO_PORTC | 20 | GPIO_GPIO | GPIO_OUT);  /* FS */
+	gpio_set_value(GPIO_PORTC + 20, 0);
+	mxc_gpio_mode(GPIO_PORTC | 22 | GPIO_GPIO | GPIO_OUT);  /* TX */
+	gpio_set_value(GPIO_PORTC + 22, 0);
+	mxc_gpio_mode(GPIO_PORTC | 28 | GPIO_GPIO | GPIO_OUT);  /* reset */
+	gpio_set_value(GPIO_PORTC + 28, 0);
+	udelay(10);
+	gpio_set_value(GPIO_PORTC + 28, 1);
+	mxc_gpio_mode(PC20_PF_SSI1_FS);
+	mxc_gpio_mode(PC22_PF_SSI1_TXD);
+	msleep(2);
+}
+
+static struct imx_ssi_platform_data pca100_ssi_pdata = {
+	.ac97_reset		= pca100_ac97_cold_reset,
+	.ac97_warm_reset	= pca100_ac97_warm_reset,
+	.flags			= IMX_SSI_USE_AC97,
+};
+
+static int pca100_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
+		void *data)
+{
+	int ret;
+
+	ret = request_irq(IRQ_GPIOC(29), detect_irq,
+			  IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+			  "imx-mmc-detect", data);
+	if (ret)
+		printk(KERN_ERR
+			"pca100: Failed to reuest irq for sd/mmc detection\n");
+
+	return ret;
+}
+
+static void pca100_sdhc2_exit(struct device *dev, void *data)
+{
+	free_irq(IRQ_GPIOC(29), data);
+}
+
+static struct imxmmc_platform_data sdhc_pdata = {
+	.init = pca100_sdhc2_init,
+	.exit = pca100_sdhc2_exit,
+};
+
+static int otg_phy_init(struct platform_device *pdev)
+{
+	gpio_set_value(OTG_PHY_CS_GPIO, 0);
+	return 0;
+}
+
+static struct mxc_usbh_platform_data otg_pdata = {
+	.init	= otg_phy_init,
+	.portsc	= MXC_EHCI_MODE_ULPI,
+	.flags	= MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static int usbh2_phy_init(struct platform_device *pdev)
+{
+	gpio_set_value(USBH2_PHY_CS_GPIO, 0);
+	return 0;
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+	.init	= usbh2_phy_init,
+	.portsc	= MXC_EHCI_MODE_ULPI,
+	.flags	= MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static struct fsl_usb2_platform_data otg_device_pdata = {
+	.operating_mode = FSL_USB2_DR_DEVICE,
+	.phy_mode       = FSL_USB2_PHY_ULPI,
+};
+
+static int otg_mode_host;
+
+static int __init pca100_otg_mode(char *options)
+{
+	if (!strcmp(options, "host"))
+		otg_mode_host = 1;
+	else if (!strcmp(options, "device"))
+		otg_mode_host = 0;
+	else
+		pr_info("otg_mode neither \"host\" nor \"device\". "
+			"Defaulting to device\n");
+	return 0;
+}
+__setup("otg_mode=", pca100_otg_mode);
+
+static void __init pca100_init(void)
+{
+	int ret;
+
+	/* SSI unit */
+	mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
+				  MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
+				  MXC_AUDMUX_V1_PCR_TFCSEL(3) |
+				  MXC_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
+				  MXC_AUDMUX_V1_PCR_RXDSEL(3));
+	mxc_audmux_v1_configure_port(3,
+				  MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
+				  MXC_AUDMUX_V1_PCR_TFCSEL(0) |
+				  MXC_AUDMUX_V1_PCR_TFSDIR |
+				  MXC_AUDMUX_V1_PCR_RXDSEL(0));
+
+	ret = mxc_gpio_setup_multiple_pins(pca100_pins,
+			ARRAY_SIZE(pca100_pins), "PCA100");
+	if (ret)
+		printk(KERN_ERR "pca100: Failed to setup pins (%d)\n", ret);
+
+	mxc_register_device(&imx_ssi_device0, &pca100_ssi_pdata);
+
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+
+	mxc_gpio_mode(GPIO_PORTC | 29 | GPIO_GPIO | GPIO_IN);
+	mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
+
+	mxc_register_device(&imx27_nand_device, &pca100_nand_board_info);
+
+	/* only the i2c master 1 is used on this CPU card */
+	i2c_register_board_info(1, pca100_i2c_devices,
+				ARRAY_SIZE(pca100_i2c_devices));
+
+	mxc_register_device(&mxc_i2c_device1, &pca100_i2c_1_data);
+
+	mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
+	mxc_gpio_mode(GPIO_PORTD | 27 | GPIO_GPIO | GPIO_OUT);
+
+	/* GPIO0_IRQ */
+	mxc_gpio_mode(GPIO_PORTC | 31 | GPIO_GPIO | GPIO_IN);
+	/* GPIO1_IRQ */
+	mxc_gpio_mode(GPIO_PORTC | 25 | GPIO_GPIO | GPIO_IN);
+	/* GPIO2_IRQ */
+	mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_IN);
+
+#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
+	spi_register_board_info(pca100_spi_board_info,
+				ARRAY_SIZE(pca100_spi_board_info));
+	mxc_register_device(&mxc_spi_device0, &pca100_spi_0_data);
+#endif
+
+	gpio_request(OTG_PHY_CS_GPIO, "usb-otg-cs");
+	gpio_direction_output(OTG_PHY_CS_GPIO, 1);
+	gpio_request(USBH2_PHY_CS_GPIO, "usb-host2-cs");
+	gpio_direction_output(USBH2_PHY_CS_GPIO, 1);
+
+#if defined(CONFIG_USB_ULPI)
+	if (otg_mode_host) {
+		otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+				USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+		mxc_register_device(&mxc_otg_host, &otg_pdata);
+	}
+
+	usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+				USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+	mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+#endif
+	if (!otg_mode_host) {
+		gpio_set_value(OTG_PHY_CS_GPIO, 0);
+		mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
+	}
+
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init pca100_timer_init(void)
+{
+	mx27_clocks_init(26000000);
+}
+
+static struct sys_timer pca100_timer = {
+	.init = pca100_timer_init,
+};
+
+MACHINE_START(PCA100, "phyCARD-i.MX27")
+	.phys_io        = MX27_AIPI_BASE_ADDR,
+	.io_pg_offst    = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = MX27_PHYS_OFFSET + 0x100,
+	.map_io         = mx27_map_io,
+	.init_irq       = mx27_init_irq,
+	.init_machine   = pca100_init,
+	.timer          = &pca100_timer,
+MACHINE_END
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-pcm038.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-pcm038.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mach-pcm038.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mach-pcm038.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,358 @@
+/*
+ * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/io.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/board-pcm038.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/i2c.h>
+#include <mach/iomux-mx27.h>
+#include <mach/imx-uart.h>
+#include <mach/mxc_nand.h>
+#include <mach/spi.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
+
+#include "devices.h"
+
+static int pcm038_pins[] = {
+	/* UART1 */
+	PE12_PF_UART1_TXD,
+	PE13_PF_UART1_RXD,
+	PE14_PF_UART1_CTS,
+	PE15_PF_UART1_RTS,
+	/* UART2 */
+	PE3_PF_UART2_CTS,
+	PE4_PF_UART2_RTS,
+	PE6_PF_UART2_TXD,
+	PE7_PF_UART2_RXD,
+	/* UART3 */
+	PE8_PF_UART3_TXD,
+	PE9_PF_UART3_RXD,
+	PE10_PF_UART3_CTS,
+	PE11_PF_UART3_RTS,
+	/* FEC */
+	PD0_AIN_FEC_TXD0,
+	PD1_AIN_FEC_TXD1,
+	PD2_AIN_FEC_TXD2,
+	PD3_AIN_FEC_TXD3,
+	PD4_AOUT_FEC_RX_ER,
+	PD5_AOUT_FEC_RXD1,
+	PD6_AOUT_FEC_RXD2,
+	PD7_AOUT_FEC_RXD3,
+	PD8_AF_FEC_MDIO,
+	PD9_AIN_FEC_MDC,
+	PD10_AOUT_FEC_CRS,
+	PD11_AOUT_FEC_TX_CLK,
+	PD12_AOUT_FEC_RXD0,
+	PD13_AOUT_FEC_RX_DV,
+	PD14_AOUT_FEC_RX_CLK,
+	PD15_AOUT_FEC_COL,
+	PD16_AIN_FEC_TX_ER,
+	PF23_AIN_FEC_TX_EN,
+	/* I2C2 */
+	PC5_PF_I2C2_SDA,
+	PC6_PF_I2C2_SCL,
+	/* SPI1 */
+	PD25_PF_CSPI1_RDY,
+	PD29_PF_CSPI1_SCLK,
+	PD30_PF_CSPI1_MISO,
+	PD31_PF_CSPI1_MOSI,
+	/* SSI1 */
+	PC20_PF_SSI1_FS,
+	PC21_PF_SSI1_RXD,
+	PC22_PF_SSI1_TXD,
+	PC23_PF_SSI1_CLK,
+	/* SSI4 */
+	PC16_PF_SSI4_FS,
+	PC17_PF_SSI4_RXD,
+	PC18_PF_SSI4_TXD,
+	PC19_PF_SSI4_CLK,
+	/* USB host */
+	PA0_PF_USBH2_CLK,
+	PA1_PF_USBH2_DIR,
+	PA2_PF_USBH2_DATA7,
+	PA3_PF_USBH2_NXT,
+	PA4_PF_USBH2_STP,
+	PD19_AF_USBH2_DATA4,
+	PD20_AF_USBH2_DATA3,
+	PD21_AF_USBH2_DATA6,
+	PD22_AF_USBH2_DATA0,
+	PD23_AF_USBH2_DATA2,
+	PD24_AF_USBH2_DATA1,
+	PD26_AF_USBH2_DATA5,
+};
+
+/*
+ * Phytec's PCM038 comes with 2MiB battery buffered SRAM,
+ * 16 bit width
+ */
+
+static struct platdata_mtd_ram pcm038_sram_data = {
+	.bankwidth = 2,
+};
+
+static struct resource pcm038_sram_resource = {
+	.start = MX27_CS1_BASE_ADDR,
+	.end   = MX27_CS1_BASE_ADDR + 512 * 1024 - 1,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pcm038_sram_mtd_device = {
+	.name = "mtd-ram",
+	.id = 0,
+	.dev = {
+		.platform_data = &pcm038_sram_data,
+	},
+	.num_resources = 1,
+	.resource = &pcm038_sram_resource,
+};
+
+/*
+ * Phytec's phyCORE-i.MX27 comes with 32MiB flash,
+ * 16 bit width
+ */
+static struct physmap_flash_data pcm038_flash_data = {
+	.width = 2,
+};
+
+static struct resource pcm038_flash_resource = {
+	.start = 0xc0000000,
+	.end   = 0xc1ffffff,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pcm038_nor_mtd_device = {
+	.name = "physmap-flash",
+	.id = 0,
+	.dev = {
+		.platform_data = &pcm038_flash_data,
+	},
+	.num_resources = 1,
+	.resource = &pcm038_flash_resource,
+};
+
+static struct imxuart_platform_data uart_pdata[] = {
+	{
+		.flags = IMXUART_HAVE_RTSCTS,
+	}, {
+		.flags = IMXUART_HAVE_RTSCTS,
+	}, {
+		.flags = IMXUART_HAVE_RTSCTS,
+	},
+};
+
+static struct mxc_nand_platform_data pcm038_nand_board_info = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+	&pcm038_nor_mtd_device,
+	&mxc_w1_master_device,
+	&mxc_fec_device,
+	&pcm038_sram_mtd_device,
+};
+
+/* On pcm038 there's a sram attached to CS1, we enable the chipselect here and
+ * setup other stuffs to access the sram. */
+static void __init pcm038_init_sram(void)
+{
+	mx27_setup_weimcs(1, 0x0000d843, 0x22252521, 0x22220a00);
+}
+
+static struct imxi2c_platform_data pcm038_i2c_1_data = {
+	.bitrate = 100000,
+};
+
+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[] = {
+	{
+		I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+		.platform_data = &board_eeprom,
+	}, {
+		I2C_BOARD_INFO("pcf8563", 0x51),
+	}, {
+		I2C_BOARD_INFO("lm75", 0x4a),
+	}
+};
+
+static int pcm038_spi_cs[] = {GPIO_PORTD + 28};
+
+static struct spi_imx_master pcm038_spi_0_data = {
+	.chipselect = pcm038_spi_cs,
+	.num_chipselect = ARRAY_SIZE(pcm038_spi_cs),
+};
+
+static struct regulator_consumer_supply sdhc1_consumers[] = {
+	{
+		.dev	= &mxc_sdhc_device1.dev,
+		.supply	= "sdhc_vcc",
+	},
+};
+
+static struct regulator_init_data sdhc1_data = {
+	.constraints = {
+		.min_uV = 3000000,
+		.max_uV = 3400000,
+		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+			REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL |
+			REGULATOR_MODE_FAST,
+		.always_on = 0,
+		.boot_on = 0,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(sdhc1_consumers),
+	.consumer_supplies = sdhc1_consumers,
+};
+
+static struct regulator_consumer_supply cam_consumers[] = {
+	{
+		.dev	= NULL,
+		.supply	= "imx_cam_vcc",
+	},
+};
+
+static struct regulator_init_data cam_data = {
+	.constraints = {
+		.min_uV = 3000000,
+		.max_uV = 3400000,
+		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+			REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL |
+			REGULATOR_MODE_FAST,
+		.always_on = 0,
+		.boot_on = 0,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(cam_consumers),
+	.consumer_supplies = cam_consumers,
+};
+
+struct mc13783_regulator_init_data pcm038_regulators[] = {
+	{
+		.id = MC13783_REGU_VCAM,
+		.init_data = &cam_data,
+	}, {
+		.id = MC13783_REGU_VMMC1,
+		.init_data = &sdhc1_data,
+	},
+};
+
+static struct mc13783_platform_data pcm038_pmic = {
+	.regulators = pcm038_regulators,
+	.num_regulators = ARRAY_SIZE(pcm038_regulators),
+	.flags = MC13783_USE_ADC | MC13783_USE_REGULATOR |
+		 MC13783_USE_TOUCHSCREEN,
+};
+
+static struct spi_board_info pcm038_spi_board_info[] __initdata = {
+	{
+		.modalias = "mc13783",
+		.irq = IRQ_GPIOB(23),
+		.max_speed_hz = 300000,
+		.bus_num = 0,
+		.chip_select = 0,
+		.platform_data = &pcm038_pmic,
+		.mode = SPI_CS_HIGH,
+	}
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+	.portsc	= MXC_EHCI_MODE_ULPI,
+	.flags	= MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static void __init pcm038_init(void)
+{
+	mxc_gpio_setup_multiple_pins(pcm038_pins, ARRAY_SIZE(pcm038_pins),
+			"PCM038");
+
+	pcm038_init_sram();
+
+	mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
+	mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
+	mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
+
+	mxc_gpio_mode(PE16_AF_OWIRE);
+	mxc_register_device(&imx27_nand_device, &pcm038_nand_board_info);
+
+	/* 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);
+
+	/* PE18 for user-LED D40 */
+	mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT);
+
+	mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
+
+	/* MC13783 IRQ */
+	mxc_gpio_mode(GPIO_PORTB | 23 | GPIO_GPIO | GPIO_IN);
+
+	mxc_register_device(&mxc_spi_device0, &pcm038_spi_0_data);
+	spi_register_board_info(pcm038_spi_board_info,
+				ARRAY_SIZE(pcm038_spi_board_info));
+
+	mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+#ifdef CONFIG_MACH_PCM970_BASEBOARD
+	pcm970_baseboard_init();
+#endif
+}
+
+static void __init pcm038_timer_init(void)
+{
+	mx27_clocks_init(26000000);
+}
+
+static struct sys_timer pcm038_timer = {
+	.init = pcm038_timer_init,
+};
+
+MACHINE_START(PCM038, "phyCORE-i.MX27")
+	.phys_io        = MX27_AIPI_BASE_ADDR,
+	.io_pg_offst    = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = MX27_PHYS_OFFSET + 0x100,
+	.map_io         = mx27_map_io,
+	.init_irq       = mx27_init_irq,
+	.init_machine   = pcm038_init,
+	.timer          = &pcm038_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -4,21 +4,20 @@
 
 # Object file lists.
 
-obj-y	:=  generic.o devices.o serial.o
+obj-y	:=  devices.o serial.o
 
-obj-$(CONFIG_MACH_MX21) += clock_imx21.o
+obj-$(CONFIG_MACH_MX21) += clock_imx21.o mm-imx21.o
 
 obj-$(CONFIG_MACH_MX27) += cpu_imx27.o
-obj-$(CONFIG_MACH_MX27) += clock_imx27.o
+obj-$(CONFIG_MACH_MX27) += clock_imx27.o mm-imx27.o
 
-obj-$(CONFIG_MACH_MX21ADS) += mx21ads.o
-obj-$(CONFIG_MACH_MX27ADS) += mx27ads.o
-obj-$(CONFIG_MACH_PCM038) += pcm038.o
+obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o
+obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o
+obj-$(CONFIG_MACH_PCM038) += mach-pcm038.o
 obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o
-obj-$(CONFIG_MACH_MX27_3DS) += mx27pdk.o
-obj-$(CONFIG_MACH_MX27LITE) += mx27lite.o
-obj-$(CONFIG_MACH_EUKREA_CPUIMX27) += eukrea_cpuimx27.o
+obj-$(CONFIG_MACH_MX27_3DS) += mach-mx27_3ds.o
+obj-$(CONFIG_MACH_IMX27LITE) += mach-imx27lite.o
+obj-$(CONFIG_MACH_CPUIMX27) += mach-cpuimx27.o
 obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o
-obj-$(CONFIG_MACH_PCA100) += pca100.o
-obj-$(CONFIG_MACH_MXT_TD60) += mxt_td60.o
-
+obj-$(CONFIG_MACH_PCA100) += mach-pca100.o
+obj-$(CONFIG_MACH_MXT_TD60) += mach-mxt_td60.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mm-imx21.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mm-imx21.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mm-imx21.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mm-imx21.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,83 @@
+/*
+ * arch/arm/mach-mx2/mm-imx21.c
+ *
+ * Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#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>
+
+/* MX21 memory map definition */
+static struct map_desc imx21_io_desc[] __initdata = {
+	/*
+	 * this fixed mapping covers:
+	 * - AIPI1
+	 * - AIPI2
+	 * - AITC
+	 * - ROM Patch
+	 * - and some reserved space
+	 */
+	{
+		.virtual = MX21_AIPI_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(MX21_AIPI_BASE_ADDR),
+		.length = MX21_AIPI_SIZE,
+		.type = MT_DEVICE
+	},
+	/*
+	 * this fixed mapping covers:
+	 * - CSI
+	 * - ATA
+	 */
+	{
+		.virtual = MX21_SAHB1_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(MX21_SAHB1_BASE_ADDR),
+		.length = MX21_SAHB1_SIZE,
+		.type = MT_DEVICE
+	},
+	/*
+	 * this fixed mapping covers:
+	 * - EMI
+	 */
+	{
+		.virtual = MX21_X_MEMC_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(MX21_X_MEMC_BASE_ADDR),
+		.length = MX21_X_MEMC_SIZE,
+		.type = MT_DEVICE
+	},
+};
+
+/*
+ * Initialize the memory map. It is called during the
+ * system startup to create static physical to virtual
+ * memory map for the IO modules.
+ */
+void __init mx21_map_io(void)
+{
+	mxc_set_cpu_type(MXC_CPU_MX21);
+	mxc_arch_reset_init(MX21_IO_ADDRESS(MX21_WDOG_BASE_ADDR));
+
+	iotable_init(imx21_io_desc, ARRAY_SIZE(imx21_io_desc));
+}
+
+void __init mx21_init_irq(void)
+{
+	mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mm-imx27.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mm-imx27.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mm-imx27.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mm-imx27.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,83 @@
+/*
+ * arch/arm/mach-mx2/mm-imx27.c
+ *
+ * Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#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>
+
+/* MX27 memory map definition */
+static struct map_desc imx27_io_desc[] __initdata = {
+	/*
+	 * this fixed mapping covers:
+	 * - AIPI1
+	 * - AIPI2
+	 * - AITC
+	 * - ROM Patch
+	 * - and some reserved space
+	 */
+	{
+		.virtual = MX27_AIPI_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(MX27_AIPI_BASE_ADDR),
+		.length = MX27_AIPI_SIZE,
+		.type = MT_DEVICE
+	},
+	/*
+	 * this fixed mapping covers:
+	 * - CSI
+	 * - ATA
+	 */
+	{
+		.virtual = MX27_SAHB1_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(MX27_SAHB1_BASE_ADDR),
+		.length = MX27_SAHB1_SIZE,
+		.type = MT_DEVICE
+	},
+	/*
+	 * this fixed mapping covers:
+	 * - EMI
+	 */
+	{
+		.virtual = MX27_X_MEMC_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(MX27_X_MEMC_BASE_ADDR),
+		.length = MX27_X_MEMC_SIZE,
+		.type = MT_DEVICE
+	},
+};
+
+/*
+ * Initialize the memory map. It is called during the
+ * system startup to create static physical to virtual
+ * memory map for the IO modules.
+ */
+void __init mx27_map_io(void)
+{
+	mxc_set_cpu_type(MXC_CPU_MX27);
+	mxc_arch_reset_init(MX27_IO_ADDRESS(MX27_WDOG_BASE_ADDR));
+
+	iotable_init(imx27_io_desc, ARRAY_SIZE(imx27_io_desc));
+}
+
+void __init mx27_init_irq(void)
+{
+	mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mx21ads.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mx21ads.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mx21ads.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mx21ads.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,294 +0,0 @@
-/*
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
- *  Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/physmap.h>
-#include <linux/gpio.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-#include <mach/imx-uart.h>
-#include <mach/imxfb.h>
-#include <mach/iomux.h>
-#include <mach/mxc_nand.h>
-#include <mach/mmc.h>
-#include <mach/board-mx21ads.h>
-
-#include "devices.h"
-
-static unsigned int mx21ads_pins[] = {
-
-	/* CS8900A */
-	(GPIO_PORTE | GPIO_GPIO | GPIO_IN | 11),
-
-	/* UART1 */
-	PE12_PF_UART1_TXD,
-	PE13_PF_UART1_RXD,
-	PE14_PF_UART1_CTS,
-	PE15_PF_UART1_RTS,
-
-	/* UART3 (IrDA) - only TXD and RXD */
-	PE8_PF_UART3_TXD,
-	PE9_PF_UART3_RXD,
-
-	/* UART4 */
-	PB26_AF_UART4_RTS,
-	PB28_AF_UART4_TXD,
-	PB29_AF_UART4_CTS,
-	PB31_AF_UART4_RXD,
-
-	/* LCDC */
-	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,
-	PA24_PF_REV,     /* Sharp panel dedicated signal */
-	PA25_PF_CLS,     /* Sharp panel dedicated signal */
-	PA26_PF_PS,      /* Sharp panel dedicated signal */
-	PA27_PF_SPL_SPR, /* Sharp panel dedicated signal */
-	PA28_PF_HSYNC,
-	PA29_PF_VSYNC,
-	PA30_PF_CONTRAST,
-	PA31_PF_OE_ACD,
-
-	/* MMC/SDHC */
-	PE18_PF_SD1_D0,
-	PE19_PF_SD1_D1,
-	PE20_PF_SD1_D2,
-	PE21_PF_SD1_D3,
-	PE22_PF_SD1_CMD,
-	PE23_PF_SD1_CLK,
-
-	/* NFC */
-	PF0_PF_NRFB,
-	PF1_PF_NFCE,
-	PF2_PF_NFWP,
-	PF3_PF_NFCLE,
-	PF4_PF_NFALE,
-	PF5_PF_NFRE,
-	PF6_PF_NFWE,
-	PF7_PF_NFIO0,
-	PF8_PF_NFIO1,
-	PF9_PF_NFIO2,
-	PF10_PF_NFIO3,
-	PF11_PF_NFIO4,
-	PF12_PF_NFIO5,
-	PF13_PF_NFIO6,
-	PF14_PF_NFIO7,
-};
-
-/* ADS's NOR flash: 2x AM29BDS128HE9VKI on 32-bit bus */
-static struct physmap_flash_data mx21ads_flash_data = {
-	.width = 4,
-};
-
-static struct resource mx21ads_flash_resource = {
-	.start = CS0_BASE_ADDR,
-	.end = CS0_BASE_ADDR + 0x02000000 - 1,
-	.flags = IORESOURCE_MEM,
-};
-
-static struct platform_device mx21ads_nor_mtd_device = {
-	.name = "physmap-flash",
-	.id = 0,
-	.dev = {
-		.platform_data = &mx21ads_flash_data,
-	},
-	.num_resources = 1,
-	.resource = &mx21ads_flash_resource,
-};
-
-static struct imxuart_platform_data uart_pdata = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct imxuart_platform_data uart_norts_pdata = {
-};
-
-
-static int mx21ads_fb_init(struct platform_device *pdev)
-{
-	u16 tmp;
-
-	tmp = __raw_readw(MX21ADS_IO_REG);
-	tmp |= MX21ADS_IO_LCDON;
-	__raw_writew(tmp, MX21ADS_IO_REG);
-	return 0;
-}
-
-static void mx21ads_fb_exit(struct platform_device *pdev)
-{
-	u16 tmp;
-
-	tmp = __raw_readw(MX21ADS_IO_REG);
-	tmp &= ~MX21ADS_IO_LCDON;
-	__raw_writew(tmp, MX21ADS_IO_REG);
-}
-
-/*
- * Connected is a portrait Sharp-QVGA display
- * of type: LQ035Q7DB02
- */
-static struct imx_fb_videomode mx21ads_modes[] = {
-	{
-		.mode = {
-			.name		= "Sharp-LQ035Q7",
-			.refresh	= 60,
-			.xres		= 240,
-			.yres		= 320,
-			.pixclock	= 188679, /* in ps (5.3MHz) */
-			.hsync_len	= 2,
-			.left_margin	= 6,
-			.right_margin	= 16,
-			.vsync_len	= 1,
-			.upper_margin	= 8,
-			.lower_margin	= 10,
-		},
-		.pcr		= 0xfb108bc7,
-		.bpp		= 16,
-	},
-};
-
-static struct imx_fb_platform_data mx21ads_fb_data = {
-	.mode = mx21ads_modes,
-	.num_modes = ARRAY_SIZE(mx21ads_modes),
-
-	.pwmr		= 0x00a903ff,
-	.lscr1		= 0x00120300,
-	.dmacr		= 0x00020008,
-
-	.init = mx21ads_fb_init,
-	.exit = mx21ads_fb_exit,
-};
-
-static int mx21ads_sdhc_get_ro(struct device *dev)
-{
-	return (__raw_readw(MX21ADS_IO_REG) & MX21ADS_IO_SD_WP) ? 1 : 0;
-}
-
-static int mx21ads_sdhc_init(struct device *dev, irq_handler_t detect_irq,
-	void *data)
-{
-	int ret;
-
-	ret = request_irq(IRQ_GPIOD(25), detect_irq,
-		IRQF_TRIGGER_FALLING, "mmc-detect", data);
-	if (ret)
-		goto out;
-	return 0;
-out:
-	return ret;
-}
-
-static void mx21ads_sdhc_exit(struct device *dev, void *data)
-{
-	free_irq(IRQ_GPIOD(25), data);
-}
-
-static struct imxmmc_platform_data mx21ads_sdhc_pdata = {
-	.ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31, /* 3.0V */
-	.get_ro = mx21ads_sdhc_get_ro,
-	.init = mx21ads_sdhc_init,
-	.exit = mx21ads_sdhc_exit,
-};
-
-static struct mxc_nand_platform_data mx21ads_nand_board_info = {
-	.width = 1,
-	.hw_ecc = 1,
-};
-
-static struct map_desc mx21ads_io_desc[] __initdata = {
-	/*
-	 * Memory-mapped I/O on MX21ADS Base board:
-	 *   - CS8900A Ethernet controller
-	 *   - ST16C2552CJ UART
-	 *   - CPU and Base board version
-	 *   - Base board I/O register
-	 */
-	{
-		.virtual = MX21ADS_MMIO_BASE_ADDR,
-		.pfn = __phys_to_pfn(CS1_BASE_ADDR),
-		.length = MX21ADS_MMIO_SIZE,
-		.type = MT_DEVICE,
-	},
-};
-
-static void __init mx21ads_map_io(void)
-{
-	mx21_map_io();
-	iotable_init(mx21ads_io_desc, ARRAY_SIZE(mx21ads_io_desc));
-}
-
-static struct platform_device *platform_devices[] __initdata = {
-	&mx21ads_nor_mtd_device,
-};
-
-static void __init mx21ads_board_init(void)
-{
-	mxc_gpio_setup_multiple_pins(mx21ads_pins, ARRAY_SIZE(mx21ads_pins),
-			"mx21ads");
-
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-	mxc_register_device(&mxc_uart_device2, &uart_norts_pdata);
-	mxc_register_device(&mxc_uart_device3, &uart_pdata);
-	mxc_register_device(&mxc_fb_device, &mx21ads_fb_data);
-	mxc_register_device(&mxc_sdhc_device0, &mx21ads_sdhc_pdata);
-	mxc_register_device(&mxc_nand_device, &mx21ads_nand_board_info);
-
-	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-}
-
-static void __init mx21ads_timer_init(void)
-{
-	mx21_clocks_init(32768, 26000000);
-}
-
-static struct sys_timer mx21ads_timer = {
-	.init	= mx21ads_timer_init,
-};
-
-MACHINE_START(MX21ADS, "Freescale i.MX21ADS")
-	/* maintainer: Freescale Semiconductor, Inc. */
-	.phys_io        = AIPI_BASE_ADDR,
-	.io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx21ads_map_io,
-	.init_irq       = mx21_init_irq,
-	.init_machine   = mx21ads_board_init,
-	.timer          = &mx21ads_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mx27ads.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mx27ads.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mx27ads.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mx27ads.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,345 +0,0 @@
-/*
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
- *  Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <linux/i2c.h>
-#include <linux/irq.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-#include <mach/gpio.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux.h>
-#include <mach/board-mx27ads.h>
-#include <mach/mxc_nand.h>
-#include <mach/i2c.h>
-#include <mach/imxfb.h>
-#include <mach/mmc.h>
-
-#include "devices.h"
-
-static unsigned int mx27ads_pins[] = {
-	/* UART0 */
-	PE12_PF_UART1_TXD,
-	PE13_PF_UART1_RXD,
-	PE14_PF_UART1_CTS,
-	PE15_PF_UART1_RTS,
-	/* UART1 */
-	PE3_PF_UART2_CTS,
-	PE4_PF_UART2_RTS,
-	PE6_PF_UART2_TXD,
-	PE7_PF_UART2_RXD,
-	/* UART2 */
-	PE8_PF_UART3_TXD,
-	PE9_PF_UART3_RXD,
-	PE10_PF_UART3_CTS,
-	PE11_PF_UART3_RTS,
-	/* UART3 */
-	PB26_AF_UART4_RTS,
-	PB28_AF_UART4_TXD,
-	PB29_AF_UART4_CTS,
-	PB31_AF_UART4_RXD,
-	/* UART4 */
-	PB18_AF_UART5_TXD,
-	PB19_AF_UART5_RXD,
-	PB20_AF_UART5_CTS,
-	PB21_AF_UART5_RTS,
-	/* UART5 */
-	PB10_AF_UART6_TXD,
-	PB12_AF_UART6_CTS,
-	PB11_AF_UART6_RXD,
-	PB13_AF_UART6_RTS,
-	/* FEC */
-	PD0_AIN_FEC_TXD0,
-	PD1_AIN_FEC_TXD1,
-	PD2_AIN_FEC_TXD2,
-	PD3_AIN_FEC_TXD3,
-	PD4_AOUT_FEC_RX_ER,
-	PD5_AOUT_FEC_RXD1,
-	PD6_AOUT_FEC_RXD2,
-	PD7_AOUT_FEC_RXD3,
-	PD8_AF_FEC_MDIO,
-	PD9_AIN_FEC_MDC,
-	PD10_AOUT_FEC_CRS,
-	PD11_AOUT_FEC_TX_CLK,
-	PD12_AOUT_FEC_RXD0,
-	PD13_AOUT_FEC_RX_DV,
-	PD14_AOUT_FEC_RX_CLK,
-	PD15_AOUT_FEC_COL,
-	PD16_AIN_FEC_TX_ER,
-	PF23_AIN_FEC_TX_EN,
-	/* I2C2 */
-	PC5_PF_I2C2_SDA,
-	PC6_PF_I2C2_SCL,
-	/* FB */
-	PA5_PF_LSCLK,
-	PA6_PF_LD0,
-	PA7_PF_LD1,
-	PA8_PF_LD2,
-	PA9_PF_LD3,
-	PA10_PF_LD4,
-	PA11_PF_LD5,
-	PA12_PF_LD6,
-	PA13_PF_LD7,
-	PA14_PF_LD8,
-	PA15_PF_LD9,
-	PA16_PF_LD10,
-	PA17_PF_LD11,
-	PA18_PF_LD12,
-	PA19_PF_LD13,
-	PA20_PF_LD14,
-	PA21_PF_LD15,
-	PA22_PF_LD16,
-	PA23_PF_LD17,
-	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,
-	/* OWIRE */
-	PE16_AF_OWIRE,
-	/* SDHC1*/
-	PE18_PF_SD1_D0,
-	PE19_PF_SD1_D1,
-	PE20_PF_SD1_D2,
-	PE21_PF_SD1_D3,
-	PE22_PF_SD1_CMD,
-	PE23_PF_SD1_CLK,
-	/* SDHC2*/
-	PB4_PF_SD2_D0,
-	PB5_PF_SD2_D1,
-	PB6_PF_SD2_D2,
-	PB7_PF_SD2_D3,
-	PB8_PF_SD2_CMD,
-	PB9_PF_SD2_CLK,
-};
-
-static struct mxc_nand_platform_data mx27ads_nand_board_info = {
-	.width = 1,
-	.hw_ecc = 1,
-};
-
-/* ADS's NOR flash */
-static struct physmap_flash_data mx27ads_flash_data = {
-	.width = 2,
-};
-
-static struct resource mx27ads_flash_resource = {
-	.start = 0xc0000000,
-	.end = 0xc0000000 + 0x02000000 - 1,
-	.flags = IORESOURCE_MEM,
-
-};
-
-static struct platform_device mx27ads_nor_mtd_device = {
-	.name = "physmap-flash",
-	.id = 0,
-	.dev = {
-		.platform_data = &mx27ads_flash_data,
-	},
-	.num_resources = 1,
-	.resource = &mx27ads_flash_resource,
-};
-
-static struct imxi2c_platform_data mx27ads_i2c_data = {
-	.bitrate = 100000,
-};
-
-static struct i2c_board_info mx27ads_i2c_devices[] = {
-};
-
-void lcd_power(int on)
-{
-	if (on)
-		__raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG);
-	else
-		__raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG);
-}
-
-static struct imx_fb_videomode mx27ads_modes[] = {
-	{
-		.mode = {
-			.name		= "Sharp-LQ035Q7",
-			.refresh	= 60,
-			.xres		= 240,
-			.yres		= 320,
-			.pixclock	= 188679, /* in ps (5.3MHz) */
-			.hsync_len	= 1,
-			.left_margin	= 9,
-			.right_margin	= 16,
-			.vsync_len	= 1,
-			.upper_margin	= 7,
-			.lower_margin	= 9,
-		},
-		.bpp		= 16,
-		.pcr		= 0xFB008BC0,
-	},
-};
-
-static struct imx_fb_platform_data mx27ads_fb_data = {
-	.mode = mx27ads_modes,
-	.num_modes = ARRAY_SIZE(mx27ads_modes),
-
-	/*
-	 * - HSYNC active high
-	 * - VSYNC active high
-	 * - clk notenabled while idle
-	 * - clock inverted
-	 * - data not inverted
-	 * - data enable low active
-	 * - enable sharp mode
-	 */
-	.pwmr		= 0x00A903FF,
-	.lscr1		= 0x00120300,
-	.dmacr		= 0x00020010,
-
-	.lcd_power	= lcd_power,
-};
-
-static int mx27ads_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
-			      void *data)
-{
-	return request_irq(IRQ_GPIOE(21), detect_irq, IRQF_TRIGGER_RISING,
-			   "sdhc1-card-detect", data);
-}
-
-static int mx27ads_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
-			      void *data)
-{
-	return request_irq(IRQ_GPIOB(7), detect_irq, IRQF_TRIGGER_RISING,
-			   "sdhc2-card-detect", data);
-}
-
-static void mx27ads_sdhc1_exit(struct device *dev, void *data)
-{
-	free_irq(IRQ_GPIOE(21), data);
-}
-
-static void mx27ads_sdhc2_exit(struct device *dev, void *data)
-{
-	free_irq(IRQ_GPIOB(7), data);
-}
-
-static struct imxmmc_platform_data sdhc1_pdata = {
-	.init = mx27ads_sdhc1_init,
-	.exit = mx27ads_sdhc1_exit,
-};
-
-static struct imxmmc_platform_data sdhc2_pdata = {
-	.init = mx27ads_sdhc2_init,
-	.exit = mx27ads_sdhc2_exit,
-};
-
-static struct platform_device *platform_devices[] __initdata = {
-	&mx27ads_nor_mtd_device,
-	&mxc_fec_device,
-	&mxc_w1_master_device,
-};
-
-static struct imxuart_platform_data uart_pdata[] = {
-	{
-		.flags = IMXUART_HAVE_RTSCTS,
-	}, {
-		.flags = IMXUART_HAVE_RTSCTS,
-	}, {
-		.flags = IMXUART_HAVE_RTSCTS,
-	}, {
-		.flags = IMXUART_HAVE_RTSCTS,
-	}, {
-		.flags = IMXUART_HAVE_RTSCTS,
-	}, {
-		.flags = IMXUART_HAVE_RTSCTS,
-	},
-};
-
-static void __init mx27ads_board_init(void)
-{
-	mxc_gpio_setup_multiple_pins(mx27ads_pins, ARRAY_SIZE(mx27ads_pins),
-			"mx27ads");
-
-	mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
-	mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
-	mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
-	mxc_register_device(&mxc_uart_device3, &uart_pdata[3]);
-	mxc_register_device(&mxc_uart_device4, &uart_pdata[4]);
-	mxc_register_device(&mxc_uart_device5, &uart_pdata[5]);
-	mxc_register_device(&mxc_nand_device, &mx27ads_nand_board_info);
-
-	/* only the i2c master 1 is used on this CPU card */
-	i2c_register_board_info(1, mx27ads_i2c_devices,
-				ARRAY_SIZE(mx27ads_i2c_devices));
-	mxc_register_device(&mxc_i2c_device1, &mx27ads_i2c_data);
-	mxc_register_device(&mxc_fb_device, &mx27ads_fb_data);
-	mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
-	mxc_register_device(&mxc_sdhc_device1, &sdhc2_pdata);
-
-	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-}
-
-static void __init mx27ads_timer_init(void)
-{
-	unsigned long fref = 26000000;
-
-	if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0)
-		fref = 27000000;
-
-	mx27_clocks_init(fref);
-}
-
-static struct sys_timer mx27ads_timer = {
-	.init	= mx27ads_timer_init,
-};
-
-static struct map_desc mx27ads_io_desc[] __initdata = {
-	{
-		.virtual = PBC_BASE_ADDRESS,
-		.pfn = __phys_to_pfn(CS4_BASE_ADDR),
-		.length = SZ_1M,
-		.type = MT_DEVICE,
-	},
-};
-
-static void __init mx27ads_map_io(void)
-{
-	mx27_map_io();
-	iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc));
-}
-
-MACHINE_START(MX27ADS, "Freescale i.MX27ADS")
-	/* maintainer: Freescale Semiconductor, Inc. */
-	.phys_io        = AIPI_BASE_ADDR,
-	.io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx27ads_map_io,
-	.init_irq       = mx27_init_irq,
-	.init_machine   = mx27ads_board_init,
-	.timer          = &mx27ads_timer,
-MACHINE_END
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mx27lite.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mx27lite.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mx27lite.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mx27lite.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,95 +0,0 @@
-/*
- * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
- * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
- * Copyright 2009 Daniel Schaeffer (daniel.schaeffer@timesys.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux.h>
-#include <mach/board-mx27lite.h>
-
-#include "devices.h"
-
-static unsigned int mx27lite_pins[] = {
-	/* UART1 */
-	PE12_PF_UART1_TXD,
-	PE13_PF_UART1_RXD,
-	PE14_PF_UART1_CTS,
-	PE15_PF_UART1_RTS,
-	/* FEC */
-	PD0_AIN_FEC_TXD0,
-	PD1_AIN_FEC_TXD1,
-	PD2_AIN_FEC_TXD2,
-	PD3_AIN_FEC_TXD3,
-	PD4_AOUT_FEC_RX_ER,
-	PD5_AOUT_FEC_RXD1,
-	PD6_AOUT_FEC_RXD2,
-	PD7_AOUT_FEC_RXD3,
-	PD8_AF_FEC_MDIO,
-	PD9_AIN_FEC_MDC,
-	PD10_AOUT_FEC_CRS,
-	PD11_AOUT_FEC_TX_CLK,
-	PD12_AOUT_FEC_RXD0,
-	PD13_AOUT_FEC_RX_DV,
-	PD14_AOUT_FEC_RX_CLK,
-	PD15_AOUT_FEC_COL,
-	PD16_AIN_FEC_TX_ER,
-	PF23_AIN_FEC_TX_EN,
-};
-
-static struct imxuart_platform_data uart_pdata = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct platform_device *platform_devices[] __initdata = {
-	&mxc_fec_device,
-};
-
-static void __init mx27lite_init(void)
-{
-	mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins),
-		"imx27lite");
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-}
-
-static void __init mx27lite_timer_init(void)
-{
-	mx27_clocks_init(26000000);
-}
-
-static struct sys_timer mx27lite_timer = {
-	.init	= mx27lite_timer_init,
-};
-
-MACHINE_START(IMX27LITE, "LogicPD i.MX27LITE")
-	.phys_io        = AIPI_BASE_ADDR,
-	.io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx27_map_io,
-	.init_irq       = mx27_init_irq,
-	.init_machine   = mx27lite_init,
-	.timer          = &mx27lite_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mx27pdk.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mx27pdk.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mx27pdk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mx27pdk.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,95 +0,0 @@
-/*
- * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * Author: Fabio Estevam <fabio.estevam@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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux.h>
-#include <mach/board-mx27pdk.h>
-
-#include "devices.h"
-
-static unsigned int mx27pdk_pins[] = {
-	/* UART1 */
-	PE12_PF_UART1_TXD,
-	PE13_PF_UART1_RXD,
-	PE14_PF_UART1_CTS,
-	PE15_PF_UART1_RTS,
-	/* FEC */
-	PD0_AIN_FEC_TXD0,
-	PD1_AIN_FEC_TXD1,
-	PD2_AIN_FEC_TXD2,
-	PD3_AIN_FEC_TXD3,
-	PD4_AOUT_FEC_RX_ER,
-	PD5_AOUT_FEC_RXD1,
-	PD6_AOUT_FEC_RXD2,
-	PD7_AOUT_FEC_RXD3,
-	PD8_AF_FEC_MDIO,
-	PD9_AIN_FEC_MDC,
-	PD10_AOUT_FEC_CRS,
-	PD11_AOUT_FEC_TX_CLK,
-	PD12_AOUT_FEC_RXD0,
-	PD13_AOUT_FEC_RX_DV,
-	PD14_AOUT_FEC_RX_CLK,
-	PD15_AOUT_FEC_COL,
-	PD16_AIN_FEC_TX_ER,
-	PF23_AIN_FEC_TX_EN,
-};
-
-static struct imxuart_platform_data uart_pdata = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct platform_device *platform_devices[] __initdata = {
-	&mxc_fec_device,
-};
-
-static void __init mx27pdk_init(void)
-{
-	mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
-		"mx27pdk");
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-}
-
-static void __init mx27pdk_timer_init(void)
-{
-	mx27_clocks_init(26000000);
-}
-
-static struct sys_timer mx27pdk_timer = {
-	.init	= mx27pdk_timer_init,
-};
-
-MACHINE_START(MX27_3DS, "Freescale MX27PDK")
-	/* maintainer: Freescale Semiconductor, Inc. */
-	.phys_io        = AIPI_BASE_ADDR,
-	.io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx27_map_io,
-	.init_irq       = mx27_init_irq,
-	.init_machine   = mx27pdk_init,
-	.timer          = &mx27pdk_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mxt_td60.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mxt_td60.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mxt_td60.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/mxt_td60.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,295 +0,0 @@
-/*
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
- *  Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <linux/i2c.h>
-#include <linux/irq.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-#include <linux/gpio.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux.h>
-#include <mach/mxc_nand.h>
-#include <mach/i2c.h>
-#include <linux/i2c/pca953x.h>
-#include <mach/imxfb.h>
-#include <mach/mmc.h>
-
-#include "devices.h"
-
-static unsigned int mxt_td60_pins[] __initdata = {
-	/* UART0 */
-	PE12_PF_UART1_TXD,
-	PE13_PF_UART1_RXD,
-	PE14_PF_UART1_CTS,
-	PE15_PF_UART1_RTS,
-	/* UART1 */
-	PE3_PF_UART2_CTS,
-	PE4_PF_UART2_RTS,
-	PE6_PF_UART2_TXD,
-	PE7_PF_UART2_RXD,
-	/* UART2 */
-	PE8_PF_UART3_TXD,
-	PE9_PF_UART3_RXD,
-	PE10_PF_UART3_CTS,
-	PE11_PF_UART3_RTS,
-	/* FEC */
-	PD0_AIN_FEC_TXD0,
-	PD1_AIN_FEC_TXD1,
-	PD2_AIN_FEC_TXD2,
-	PD3_AIN_FEC_TXD3,
-	PD4_AOUT_FEC_RX_ER,
-	PD5_AOUT_FEC_RXD1,
-	PD6_AOUT_FEC_RXD2,
-	PD7_AOUT_FEC_RXD3,
-	PD8_AF_FEC_MDIO,
-	PD9_AIN_FEC_MDC,
-	PD10_AOUT_FEC_CRS,
-	PD11_AOUT_FEC_TX_CLK,
-	PD12_AOUT_FEC_RXD0,
-	PD13_AOUT_FEC_RX_DV,
-	PD14_AOUT_FEC_RX_CLK,
-	PD15_AOUT_FEC_COL,
-	PD16_AIN_FEC_TX_ER,
-	PF23_AIN_FEC_TX_EN,
-	/* I2C1 */
-	PD17_PF_I2C_DATA,
-	PD18_PF_I2C_CLK,
-	/* I2C2 */
-	PC5_PF_I2C2_SDA,
-	PC6_PF_I2C2_SCL,
-	/* FB */
-	PA5_PF_LSCLK,
-	PA6_PF_LD0,
-	PA7_PF_LD1,
-	PA8_PF_LD2,
-	PA9_PF_LD3,
-	PA10_PF_LD4,
-	PA11_PF_LD5,
-	PA12_PF_LD6,
-	PA13_PF_LD7,
-	PA14_PF_LD8,
-	PA15_PF_LD9,
-	PA16_PF_LD10,
-	PA17_PF_LD11,
-	PA18_PF_LD12,
-	PA19_PF_LD13,
-	PA20_PF_LD14,
-	PA21_PF_LD15,
-	PA22_PF_LD16,
-	PA23_PF_LD17,
-	PA25_PF_CLS,
-	PA27_PF_SPL_SPR,
-	PA28_PF_HSYNC,
-	PA29_PF_VSYNC,
-	PA30_PF_CONTRAST,
-	PA31_PF_OE_ACD,
-	/* OWIRE */
-	PE16_AF_OWIRE,
-	/* SDHC1*/
-	PE18_PF_SD1_D0,
-	PE19_PF_SD1_D1,
-	PE20_PF_SD1_D2,
-	PE21_PF_SD1_D3,
-	PE22_PF_SD1_CMD,
-	PE23_PF_SD1_CLK,
-	PF8_AF_ATA_IORDY,
-	/* SDHC2*/
-	PB4_PF_SD2_D0,
-	PB5_PF_SD2_D1,
-	PB6_PF_SD2_D2,
-	PB7_PF_SD2_D3,
-	PB8_PF_SD2_CMD,
-	PB9_PF_SD2_CLK,
-};
-
-static struct mxc_nand_platform_data mxt_td60_nand_board_info = {
-	.width = 1,
-	.hw_ecc = 1,
-};
-
-static struct imxi2c_platform_data mxt_td60_i2c_data = {
-	.bitrate = 100000,
-};
-
-/* PCA9557 */
-static int mxt_td60_pca9557_setup(struct i2c_client *client,
-				unsigned gpio_base, unsigned ngpio,
-				void *context)
-{
-	static int mxt_td60_gpio_value[] = {
-		-1, -1, -1, -1, -1, -1, -1, 1
-	};
-	int n;
-
-	for (n = 0; n < ARRAY_SIZE(mxt_td60_gpio_value); ++n) {
-		gpio_request(gpio_base + n, "MXT_TD60 GPIO Exp");
-		if (mxt_td60_gpio_value[n] < 0)
-			gpio_direction_input(gpio_base + n);
-		else
-			gpio_direction_output(gpio_base + n,
-						mxt_td60_gpio_value[n]);
-		gpio_export(gpio_base + n, 0);
-	}
-
-	return 0;
-}
-
-static struct pca953x_platform_data mxt_td60_pca9557_pdata = {
-	.gpio_base	= 240, /* place PCA9557 after all MX27 gpio pins */
-	.invert		= 0, /* Do not invert */
-	.setup		= mxt_td60_pca9557_setup,
-};
-
-static struct i2c_board_info mxt_td60_i2c_devices[] = {
-	{
-		I2C_BOARD_INFO("pca9557", 0x18),
-		.platform_data = &mxt_td60_pca9557_pdata,
-	},
-};
-
-static struct imxi2c_platform_data mxt_td60_i2c2_data = {
-	.bitrate = 100000,
-};
-
-static struct i2c_board_info mxt_td60_i2c2_devices[] = {
-};
-
-static struct imx_fb_videomode mxt_td60_modes[] = {
-	{
-		.mode = {
-			.name		= "Chimei LW700AT9003",
-			.refresh	= 60,
-			.xres		= 800,
-			.yres		= 480,
-			.pixclock	= 30303,
-			.hsync_len	= 64,
-			.left_margin	= 0x67,
-			.right_margin	= 0x68,
-			.vsync_len	= 16,
-			.upper_margin	= 0x0f,
-			.lower_margin	= 0x0f,
-		},
-		.bpp		= 16,
-		.pcr		= 0xFA208B83,
-	},
-};
-
-static struct imx_fb_platform_data mxt_td60_fb_data = {
-	.mode = mxt_td60_modes,
-	.num_modes = ARRAY_SIZE(mxt_td60_modes),
-
-	/*
-	 * - HSYNC active high
-	 * - VSYNC active high
-	 * - clk notenabled while idle
-	 * - clock inverted
-	 * - data not inverted
-	 * - data enable low active
-	 * - enable sharp mode
-	 */
-	.pwmr		= 0x00A903FF,
-	.lscr1		= 0x00120300,
-	.dmacr		= 0x00020010,
-};
-
-static int mxt_td60_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
-				void *data)
-{
-	return request_irq(IRQ_GPIOF(8), detect_irq, IRQF_TRIGGER_FALLING,
-				"sdhc1-card-detect", data);
-}
-
-static void mxt_td60_sdhc1_exit(struct device *dev, void *data)
-{
-	free_irq(IRQ_GPIOF(8), data);
-}
-
-static struct imxmmc_platform_data sdhc1_pdata = {
-	.init = mxt_td60_sdhc1_init,
-	.exit = mxt_td60_sdhc1_exit,
-};
-
-static struct platform_device *platform_devices[] __initdata = {
-	&mxc_fec_device,
-};
-
-static struct imxuart_platform_data uart_pdata[] = {
-	{
-		.flags = IMXUART_HAVE_RTSCTS,
-	}, {
-		.flags = IMXUART_HAVE_RTSCTS,
-	}, {
-		.flags = IMXUART_HAVE_RTSCTS,
-	},
-};
-
-static void __init mxt_td60_board_init(void)
-{
-	mxc_gpio_setup_multiple_pins(mxt_td60_pins, ARRAY_SIZE(mxt_td60_pins),
-			"MXT_TD60");
-
-	mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
-	mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
-	mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
-	mxc_register_device(&mxc_nand_device, &mxt_td60_nand_board_info);
-
-	i2c_register_board_info(0, mxt_td60_i2c_devices,
-				ARRAY_SIZE(mxt_td60_i2c_devices));
-
-	i2c_register_board_info(1, mxt_td60_i2c2_devices,
-				ARRAY_SIZE(mxt_td60_i2c2_devices));
-
-	mxc_register_device(&mxc_i2c_device0, &mxt_td60_i2c_data);
-	mxc_register_device(&mxc_i2c_device1, &mxt_td60_i2c2_data);
-	mxc_register_device(&mxc_fb_device, &mxt_td60_fb_data);
-	mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
-
-	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-}
-
-static void __init mxt_td60_timer_init(void)
-{
-	mx27_clocks_init(26000000);
-}
-
-static struct sys_timer mxt_td60_timer = {
-	.init	= mxt_td60_timer_init,
-};
-
-MACHINE_START(MXT_TD60, "Maxtrack i-MXT TD60")
-	/* maintainer: Maxtrack Industrial */
-	.phys_io	= AIPI_BASE_ADDR,
-	.io_pg_offst	= ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params	= PHYS_OFFSET + 0x100,
-	.map_io		= mx27_map_io,
-	.init_irq	= mx27_init_irq,
-	.init_machine	= mxt_td60_board_init,
-	.timer		= &mxt_td60_timer,
-MACHINE_END
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/pca100.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/pca100.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/pca100.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/pca100.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,244 +0,0 @@
-/*
- * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
- * Copyright (C) 2009 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.
- */
-
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
-#include <linux/dma-mapping.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/eeprom.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux.h>
-#include <mach/i2c.h>
-#include <asm/mach/time.h>
-#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
-#include <mach/spi.h>
-#endif
-#include <mach/imx-uart.h>
-#include <mach/mxc_nand.h>
-#include <mach/irqs.h>
-#include <mach/mmc.h>
-
-#include "devices.h"
-
-static int pca100_pins[] = {
-	/* UART1 */
-	PE12_PF_UART1_TXD,
-	PE13_PF_UART1_RXD,
-	PE14_PF_UART1_CTS,
-	PE15_PF_UART1_RTS,
-	/* SDHC */
-	PB4_PF_SD2_D0,
-	PB5_PF_SD2_D1,
-	PB6_PF_SD2_D2,
-	PB7_PF_SD2_D3,
-	PB8_PF_SD2_CMD,
-	PB9_PF_SD2_CLK,
-	/* FEC */
-	PD0_AIN_FEC_TXD0,
-	PD1_AIN_FEC_TXD1,
-	PD2_AIN_FEC_TXD2,
-	PD3_AIN_FEC_TXD3,
-	PD4_AOUT_FEC_RX_ER,
-	PD5_AOUT_FEC_RXD1,
-	PD6_AOUT_FEC_RXD2,
-	PD7_AOUT_FEC_RXD3,
-	PD8_AF_FEC_MDIO,
-	PD9_AIN_FEC_MDC,
-	PD10_AOUT_FEC_CRS,
-	PD11_AOUT_FEC_TX_CLK,
-	PD12_AOUT_FEC_RXD0,
-	PD13_AOUT_FEC_RX_DV,
-	PD14_AOUT_FEC_RX_CLK,
-	PD15_AOUT_FEC_COL,
-	PD16_AIN_FEC_TX_ER,
-	PF23_AIN_FEC_TX_EN,
-	/* SSI1 */
-	PC20_PF_SSI1_FS,
-	PC21_PF_SSI1_RXD,
-	PC22_PF_SSI1_TXD,
-	PC23_PF_SSI1_CLK,
-	/* onboard I2C */
-	PC5_PF_I2C2_SDA,
-	PC6_PF_I2C2_SCL,
-	/* external I2C */
-	PD17_PF_I2C_DATA,
-	PD18_PF_I2C_CLK,
-	/* SPI1 */
-	PD25_PF_CSPI1_RDY,
-	PD29_PF_CSPI1_SCLK,
-	PD30_PF_CSPI1_MISO,
-	PD31_PF_CSPI1_MOSI,
-};
-
-static struct imxuart_platform_data uart_pdata = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct mxc_nand_platform_data pca100_nand_board_info = {
-	.width = 1,
-	.hw_ecc = 1,
-};
-
-static struct platform_device *platform_devices[] __initdata = {
-	&mxc_w1_master_device,
-	&mxc_fec_device,
-};
-
-static struct imxi2c_platform_data pca100_i2c_1_data = {
-	.bitrate = 100000,
-};
-
-static struct at24_platform_data board_eeprom = {
-	.byte_len = 4096,
-	.page_size = 32,
-	.flags = AT24_FLAG_ADDR16,
-};
-
-static struct i2c_board_info pca100_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"
-	}, {
-		I2C_BOARD_INFO("lm75", 0x4a),
-		.type = "lm75"
-	}
-};
-
-#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
-static struct spi_eeprom at25320 = {
-	.name		= "at25320an",
-	.byte_len	= 4096,
-	.page_size	= 32,
-	.flags		= EE_ADDR2,
-};
-
-static struct spi_board_info pca100_spi_board_info[] __initdata = {
-	{
-		.modalias = "at25",
-		.max_speed_hz = 30000,
-		.bus_num = 0,
-		.chip_select = 1,
-		.platform_data = &at25320,
-	},
-};
-
-static int pca100_spi_cs[] = {GPIO_PORTD + 28, GPIO_PORTD + 27};
-
-static struct spi_imx_master pca100_spi_0_data = {
-	.chipselect	= pca100_spi_cs,
-	.num_chipselect = ARRAY_SIZE(pca100_spi_cs),
-};
-#endif
-
-static int pca100_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
-		void *data)
-{
-	int ret;
-
-	ret = request_irq(IRQ_GPIOC(29), detect_irq,
-			  IRQF_DISABLED | IRQF_TRIGGER_FALLING,
-			  "imx-mmc-detect", data);
-	if (ret)
-		printk(KERN_ERR
-			"pca100: Failed to reuest irq for sd/mmc detection\n");
-
-	return ret;
-}
-
-static void pca100_sdhc2_exit(struct device *dev, void *data)
-{
-	free_irq(IRQ_GPIOC(29), data);
-}
-
-static struct imxmmc_platform_data sdhc_pdata = {
-	.init = pca100_sdhc2_init,
-	.exit = pca100_sdhc2_exit,
-};
-
-static void __init pca100_init(void)
-{
-	int ret;
-
-	ret = mxc_gpio_setup_multiple_pins(pca100_pins,
-			ARRAY_SIZE(pca100_pins), "PCA100");
-	if (ret)
-		printk(KERN_ERR "pca100: Failed to setup pins (%d)\n", ret);
-
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-
-	mxc_gpio_mode(GPIO_PORTC | 29 | GPIO_GPIO | GPIO_IN);
-	mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
-
-	mxc_register_device(&mxc_nand_device, &pca100_nand_board_info);
-
-	/* only the i2c master 1 is used on this CPU card */
-	i2c_register_board_info(1, pca100_i2c_devices,
-				ARRAY_SIZE(pca100_i2c_devices));
-
-	mxc_register_device(&mxc_i2c_device1, &pca100_i2c_1_data);
-
-	mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
-	mxc_gpio_mode(GPIO_PORTD | 27 | GPIO_GPIO | GPIO_OUT);
-
-	/* GPIO0_IRQ */
-	mxc_gpio_mode(GPIO_PORTC | 31 | GPIO_GPIO | GPIO_IN);
-	/* GPIO1_IRQ */
-	mxc_gpio_mode(GPIO_PORTC | 25 | GPIO_GPIO | GPIO_IN);
-	/* GPIO2_IRQ */
-	mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_IN);
-
-#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
-	spi_register_board_info(pca100_spi_board_info,
-				ARRAY_SIZE(pca100_spi_board_info));
-	mxc_register_device(&mxc_spi_device0, &pca100_spi_0_data);
-#endif
-
-	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-}
-
-static void __init pca100_timer_init(void)
-{
-	mx27_clocks_init(26000000);
-}
-
-static struct sys_timer pca100_timer = {
-	.init = pca100_timer_init,
-};
-
-MACHINE_START(PCA100, "phyCARD-i.MX27")
-	.phys_io        = AIPI_BASE_ADDR,
-	.io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx27_map_io,
-	.init_irq       = mx27_init_irq,
-	.init_machine   = pca100_init,
-	.timer          = &pca100_timer,
-MACHINE_END
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/pcm038.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/pcm038.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/pcm038.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/pcm038.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,338 +0,0 @@
-/*
- * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
- * Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
-#include <linux/io.h>
-#include <linux/mtd/plat-ram.h>
-#include <linux/mtd/physmap.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/machine.h>
-#include <linux/mfd/mc13783.h>
-#include <linux/spi/spi.h>
-#include <linux/irq.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-
-#include <mach/board-pcm038.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/i2c.h>
-#include <mach/iomux.h>
-#include <mach/imx-uart.h>
-#include <mach/mxc_nand.h>
-#include <mach/spi.h>
-
-#include "devices.h"
-
-static int pcm038_pins[] = {
-	/* UART1 */
-	PE12_PF_UART1_TXD,
-	PE13_PF_UART1_RXD,
-	PE14_PF_UART1_CTS,
-	PE15_PF_UART1_RTS,
-	/* UART2 */
-	PE3_PF_UART2_CTS,
-	PE4_PF_UART2_RTS,
-	PE6_PF_UART2_TXD,
-	PE7_PF_UART2_RXD,
-	/* UART3 */
-	PE8_PF_UART3_TXD,
-	PE9_PF_UART3_RXD,
-	PE10_PF_UART3_CTS,
-	PE11_PF_UART3_RTS,
-	/* FEC */
-	PD0_AIN_FEC_TXD0,
-	PD1_AIN_FEC_TXD1,
-	PD2_AIN_FEC_TXD2,
-	PD3_AIN_FEC_TXD3,
-	PD4_AOUT_FEC_RX_ER,
-	PD5_AOUT_FEC_RXD1,
-	PD6_AOUT_FEC_RXD2,
-	PD7_AOUT_FEC_RXD3,
-	PD8_AF_FEC_MDIO,
-	PD9_AIN_FEC_MDC,
-	PD10_AOUT_FEC_CRS,
-	PD11_AOUT_FEC_TX_CLK,
-	PD12_AOUT_FEC_RXD0,
-	PD13_AOUT_FEC_RX_DV,
-	PD14_AOUT_FEC_RX_CLK,
-	PD15_AOUT_FEC_COL,
-	PD16_AIN_FEC_TX_ER,
-	PF23_AIN_FEC_TX_EN,
-	/* I2C2 */
-	PC5_PF_I2C2_SDA,
-	PC6_PF_I2C2_SCL,
-	/* SPI1 */
-	PD25_PF_CSPI1_RDY,
-	PD29_PF_CSPI1_SCLK,
-	PD30_PF_CSPI1_MISO,
-	PD31_PF_CSPI1_MOSI,
-	/* SSI1 */
-	PC20_PF_SSI1_FS,
-	PC21_PF_SSI1_RXD,
-	PC22_PF_SSI1_TXD,
-	PC23_PF_SSI1_CLK,
-	/* SSI4 */
-	PC16_PF_SSI4_FS,
-	PC17_PF_SSI4_RXD,
-	PC18_PF_SSI4_TXD,
-	PC19_PF_SSI4_CLK,
-};
-
-/*
- * Phytec's PCM038 comes with 2MiB battery buffered SRAM,
- * 16 bit width
- */
-
-static struct platdata_mtd_ram pcm038_sram_data = {
-	.bankwidth = 2,
-};
-
-static struct resource pcm038_sram_resource = {
-	.start = CS1_BASE_ADDR,
-	.end   = CS1_BASE_ADDR + 512 * 1024 - 1,
-	.flags = IORESOURCE_MEM,
-};
-
-static struct platform_device pcm038_sram_mtd_device = {
-	.name = "mtd-ram",
-	.id = 0,
-	.dev = {
-		.platform_data = &pcm038_sram_data,
-	},
-	.num_resources = 1,
-	.resource = &pcm038_sram_resource,
-};
-
-/*
- * Phytec's phyCORE-i.MX27 comes with 32MiB flash,
- * 16 bit width
- */
-static struct physmap_flash_data pcm038_flash_data = {
-	.width = 2,
-};
-
-static struct resource pcm038_flash_resource = {
-	.start = 0xc0000000,
-	.end   = 0xc1ffffff,
-	.flags = IORESOURCE_MEM,
-};
-
-static struct platform_device pcm038_nor_mtd_device = {
-	.name = "physmap-flash",
-	.id = 0,
-	.dev = {
-		.platform_data = &pcm038_flash_data,
-	},
-	.num_resources = 1,
-	.resource = &pcm038_flash_resource,
-};
-
-static struct imxuart_platform_data uart_pdata[] = {
-	{
-		.flags = IMXUART_HAVE_RTSCTS,
-	}, {
-		.flags = IMXUART_HAVE_RTSCTS,
-	}, {
-		.flags = IMXUART_HAVE_RTSCTS,
-	},
-};
-
-static struct mxc_nand_platform_data pcm038_nand_board_info = {
-	.width = 1,
-	.hw_ecc = 1,
-};
-
-static struct platform_device *platform_devices[] __initdata = {
-	&pcm038_nor_mtd_device,
-	&mxc_w1_master_device,
-	&mxc_fec_device,
-	&pcm038_sram_mtd_device,
-};
-
-/* On pcm038 there's a sram attached to CS1, we enable the chipselect here and
- * setup other stuffs to access the sram. */
-static void __init pcm038_init_sram(void)
-{
-	__raw_writel(0x0000d843, CSCR_U(1));
-	__raw_writel(0x22252521, CSCR_L(1));
-	__raw_writel(0x22220a00, CSCR_A(1));
-}
-
-static struct imxi2c_platform_data pcm038_i2c_1_data = {
-	.bitrate = 100000,
-};
-
-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[] = {
-	{
-		I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
-		.platform_data = &board_eeprom,
-	}, {
-		I2C_BOARD_INFO("pcf8563", 0x51),
-	}, {
-		I2C_BOARD_INFO("lm75", 0x4a),
-	}
-};
-
-static int pcm038_spi_cs[] = {GPIO_PORTD + 28};
-
-static struct spi_imx_master pcm038_spi_0_data = {
-	.chipselect = pcm038_spi_cs,
-	.num_chipselect = ARRAY_SIZE(pcm038_spi_cs),
-};
-
-static struct regulator_consumer_supply sdhc1_consumers[] = {
-	{
-		.dev	= &mxc_sdhc_device1.dev,
-		.supply	= "sdhc_vcc",
-	},
-};
-
-static struct regulator_init_data sdhc1_data = {
-	.constraints = {
-		.min_uV = 3000000,
-		.max_uV = 3400000,
-		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
-			REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
-		.valid_modes_mask = REGULATOR_MODE_NORMAL |
-			REGULATOR_MODE_FAST,
-		.always_on = 0,
-		.boot_on = 0,
-	},
-	.num_consumer_supplies = ARRAY_SIZE(sdhc1_consumers),
-	.consumer_supplies = sdhc1_consumers,
-};
-
-static struct regulator_consumer_supply cam_consumers[] = {
-	{
-		.dev	= NULL,
-		.supply	= "imx_cam_vcc",
-	},
-};
-
-static struct regulator_init_data cam_data = {
-	.constraints = {
-		.min_uV = 3000000,
-		.max_uV = 3400000,
-		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
-			REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
-		.valid_modes_mask = REGULATOR_MODE_NORMAL |
-			REGULATOR_MODE_FAST,
-		.always_on = 0,
-		.boot_on = 0,
-	},
-	.num_consumer_supplies = ARRAY_SIZE(cam_consumers),
-	.consumer_supplies = cam_consumers,
-};
-
-struct mc13783_regulator_init_data pcm038_regulators[] = {
-	{
-		.id = MC13783_REGU_VCAM,
-		.init_data = &cam_data,
-	}, {
-		.id = MC13783_REGU_VMMC1,
-		.init_data = &sdhc1_data,
-	},
-};
-
-static struct mc13783_platform_data pcm038_pmic = {
-	.regulators = pcm038_regulators,
-	.num_regulators = ARRAY_SIZE(pcm038_regulators),
-	.flags = MC13783_USE_ADC | MC13783_USE_REGULATOR |
-		 MC13783_USE_TOUCHSCREEN,
-};
-
-static struct spi_board_info pcm038_spi_board_info[] __initdata = {
-	{
-		.modalias = "mc13783",
-		.irq = IRQ_GPIOB(23),
-		.max_speed_hz = 300000,
-		.bus_num = 0,
-		.chip_select = 0,
-		.platform_data = &pcm038_pmic,
-		.mode = SPI_CS_HIGH,
-	}
-};
-
-static void __init pcm038_init(void)
-{
-	mxc_gpio_setup_multiple_pins(pcm038_pins, ARRAY_SIZE(pcm038_pins),
-			"PCM038");
-
-	pcm038_init_sram();
-
-	mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
-	mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
-	mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
-
-	mxc_gpio_mode(PE16_AF_OWIRE);
-	mxc_register_device(&mxc_nand_device, &pcm038_nand_board_info);
-
-	/* 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);
-
-	/* PE18 for user-LED D40 */
-	mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT);
-
-	mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
-
-	/* MC13783 IRQ */
-	mxc_gpio_mode(GPIO_PORTB | 23 | GPIO_GPIO | GPIO_IN);
-
-	mxc_register_device(&mxc_spi_device0, &pcm038_spi_0_data);
-	spi_register_board_info(pcm038_spi_board_info,
-				ARRAY_SIZE(pcm038_spi_board_info));
-
-	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-
-#ifdef CONFIG_MACH_PCM970_BASEBOARD
-	pcm970_baseboard_init();
-#endif
-}
-
-static void __init pcm038_timer_init(void)
-{
-	mx27_clocks_init(26000000);
-}
-
-static struct sys_timer pcm038_timer = {
-	.init = pcm038_timer_init,
-};
-
-MACHINE_START(PCM038, "phyCORE-i.MX27")
-	.phys_io        = AIPI_BASE_ADDR,
-	.io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx27_map_io,
-	.init_irq       = mx27_init_irq,
-	.init_machine   = pcm038_init,
-	.timer          = &pcm038_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/pcm970-baseboard.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/pcm970-baseboard.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/pcm970-baseboard.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/pcm970-baseboard.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,7 @@
 #include <asm/mach/arch.h>
 
 #include <mach/common.h>
-#include <mach/iomux.h>
+#include <mach/iomux-mx27.h>
 #include <mach/imxfb.h>
 #include <mach/hardware.h>
 #include <mach/mmc.h>
@@ -190,8 +190,8 @@ static struct imx_fb_platform_data pcm03
 
 static struct resource pcm970_sja1000_resources[] = {
 	{
-		.start   = CS4_BASE_ADDR,
-		.end     = CS4_BASE_ADDR + 0x100 - 1,
+		.start   = MX27_CS4_BASE_ADDR,
+		.end     = MX27_CS4_BASE_ADDR + 0x100 - 1,
 		.flags   = IORESOURCE_MEM,
 	}, {
 		.start   = IRQ_GPIOE(19),
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/serial.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/serial.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,12 +26,12 @@
 
 static struct resource uart0[] = {
 	{
-		.start = UART1_BASE_ADDR,
-		.end = UART1_BASE_ADDR + 0x0B5,
+		.start = MX2x_UART1_BASE_ADDR,
+		.end = MX2x_UART1_BASE_ADDR + 0x0B5,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = MXC_INT_UART1,
-		.end = MXC_INT_UART1,
+		.start = MX2x_INT_UART1,
+		.end = MX2x_INT_UART1,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -45,12 +45,12 @@ struct platform_device mxc_uart_device0
 
 static struct resource uart1[] = {
 	{
-		.start = UART2_BASE_ADDR,
-		.end = UART2_BASE_ADDR + 0x0B5,
+		.start = MX2x_UART2_BASE_ADDR,
+		.end = MX2x_UART2_BASE_ADDR + 0x0B5,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = MXC_INT_UART2,
-		.end = MXC_INT_UART2,
+		.start = MX2x_INT_UART2,
+		.end = MX2x_INT_UART2,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -64,12 +64,12 @@ struct platform_device mxc_uart_device1
 
 static struct resource uart2[] = {
 	{
-		.start = UART3_BASE_ADDR,
-		.end = UART3_BASE_ADDR + 0x0B5,
+		.start = MX2x_UART3_BASE_ADDR,
+		.end = MX2x_UART3_BASE_ADDR + 0x0B5,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = MXC_INT_UART3,
-		.end = MXC_INT_UART3,
+		.start = MX2x_INT_UART3,
+		.end = MX2x_INT_UART3,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -83,12 +83,12 @@ struct platform_device mxc_uart_device2
 
 static struct resource uart3[] = {
 	{
-		.start = UART4_BASE_ADDR,
-		.end = UART4_BASE_ADDR + 0x0B5,
+		.start = MX2x_UART4_BASE_ADDR,
+		.end = MX2x_UART4_BASE_ADDR + 0x0B5,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = MXC_INT_UART4,
-		.end = MXC_INT_UART4,
+		.start = MX2x_INT_UART4,
+		.end = MX2x_INT_UART4,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -103,12 +103,12 @@ struct platform_device mxc_uart_device3
 #ifdef CONFIG_MACH_MX27
 static struct resource uart4[] = {
 	{
-		.start = UART5_BASE_ADDR,
-		.end = UART5_BASE_ADDR + 0x0B5,
+		.start = MX27_UART5_BASE_ADDR,
+		.end = MX27_UART5_BASE_ADDR + 0x0B5,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = MXC_INT_UART5,
-		.end = MXC_INT_UART5,
+		.start = MX27_INT_UART5,
+		.end = MX27_INT_UART5,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -122,12 +122,12 @@ struct platform_device mxc_uart_device4
 
 static struct resource uart5[] = {
 	{
-		.start = UART6_BASE_ADDR,
-		.end = UART6_BASE_ADDR + 0x0B5,
+		.start = MX27_UART6_BASE_ADDR,
+		.end = MX27_UART6_BASE_ADDR + 0x0B5,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = MXC_INT_UART6,
-		.end = MXC_INT_UART6,
+		.start = MX27_INT_UART6,
+		.end = MX27_INT_UART6,
 		.flags = IORESOURCE_IRQ,
 	},
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx25/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx25/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -124,6 +124,11 @@ static unsigned long get_rate_gpt(struct
 	return get_rate_per(5);
 }
 
+static unsigned long get_rate_lcdc(struct clk *clk)
+{
+	return get_rate_per(7);
+}
+
 static unsigned long get_rate_otg(struct clk *clk)
 {
 	return 48000000; /* FIXME */
@@ -167,6 +172,8 @@ DEFINE_CLOCK(cspi1_clk,  0, CCM_CGCR1,
 DEFINE_CLOCK(cspi2_clk,  0, CCM_CGCR1,  6, get_rate_ipg, NULL, NULL);
 DEFINE_CLOCK(cspi3_clk,  0, CCM_CGCR1,  7, get_rate_ipg, NULL, NULL);
 DEFINE_CLOCK(fec_ahb_clk, 0, CCM_CGCR0, 23, NULL,	 NULL, NULL);
+DEFINE_CLOCK(lcdc_ahb_clk, 0, CCM_CGCR0, 24, NULL,	 NULL, NULL);
+DEFINE_CLOCK(lcdc_per_clk, 0, CCM_CGCR0,  7, NULL,	 NULL, &lcdc_ahb_clk);
 DEFINE_CLOCK(uart1_clk,  0, CCM_CGCR2, 14, get_rate_uart, NULL, &uart_per_clk);
 DEFINE_CLOCK(uart2_clk,  0, CCM_CGCR2, 15, get_rate_uart, NULL, &uart_per_clk);
 DEFINE_CLOCK(uart3_clk,  0, CCM_CGCR2, 16, get_rate_uart, NULL, &uart_per_clk);
@@ -182,6 +189,8 @@ DEFINE_CLOCK(kpp_clk,	 0, CCM_CGCR1, 28,
 DEFINE_CLOCK(tsc_clk,	 0, CCM_CGCR2, 13, get_rate_ipg, NULL, NULL);
 DEFINE_CLOCK(i2c_clk,	 0, CCM_CGCR0,  6, get_rate_i2c, NULL, NULL);
 DEFINE_CLOCK(fec_clk,	 0, CCM_CGCR1, 15, get_rate_ipg, NULL, &fec_ahb_clk);
+DEFINE_CLOCK(dryice_clk, 0, CCM_CGCR1,  8, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(lcdc_clk,	 0, CCM_CGCR1, 29, get_rate_lcdc, NULL, &lcdc_per_clk);
 
 #define _REGISTER_CLOCK(d, n, c)	\
 	{				\
@@ -214,14 +223,13 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
 	_REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
 	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+	_REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk)
+	_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
 };
 
 int __init mx25_clocks_init(void)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(lookups); i++)
-		clkdev_add(&lookups[i]);
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	/* Turn off all clocks except the ones we need to survive, namely:
 	 * EMI, GPIO1-3 (CCM_CGCR1[18:16]), GPT1, IOMUXC (CCM_CGCR1[27]), IIM,
@@ -231,6 +239,9 @@ int __init mx25_clocks_init(void)
 	__raw_writel((0xf << 16) | (3 << 26), CRM_BASE + CCM_CGCR1);
 	__raw_writel((1 << 5), CRM_BASE + CCM_CGCR2);
 
+	/* Clock source for lcdc is upll */
+	__raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7), CRM_BASE + 0x64);
+
 	mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/devices.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx25/devices.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/devices.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx25/devices.c	2010-05-16 17:17:36.000000000 -0400
@@ -438,3 +438,65 @@ struct platform_device mx25_fec_device =
 	.num_resources	= ARRAY_SIZE(mx25_fec_resources),
 	.resource	= mx25_fec_resources,
 };
+
+static struct resource mxc_nand_resources[] = {
+	{
+		.start	= MX25_NFC_BASE_ADDR,
+		.end	= MX25_NFC_BASE_ADDR + 0x1fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= MX25_INT_NANDFC,
+		.end	= MX25_INT_NANDFC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_nand_device = {
+	.name		= "mxc_nand",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(mxc_nand_resources),
+	.resource	= mxc_nand_resources,
+};
+
+static struct resource mx25_rtc_resources[] = {
+	{
+		.start	= MX25_DRYICE_BASE_ADDR,
+		.end	= MX25_DRYICE_BASE_ADDR + 0x40,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= MX25_INT_DRYICE,
+		.flags	= IORESOURCE_IRQ
+	},
+};
+
+struct platform_device mx25_rtc_device = {
+	.name	= "imxdi_rtc",
+	.id	= 0,
+	.num_resources	= ARRAY_SIZE(mx25_rtc_resources),
+	.resource	= mx25_rtc_resources,
+};
+
+static struct resource mx25_fb_resources[] = {
+	{
+		.start	= MX25_LCDC_BASE_ADDR,
+		.end	= MX25_LCDC_BASE_ADDR + 0xfff,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= MX25_INT_LCDC,
+		.end	= MX25_INT_LCDC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mx25_fb_device = {
+	.name		= "imx-fb",
+	.id		= 0,
+	.resource	= mx25_fb_resources,
+	.num_resources	= ARRAY_SIZE(mx25_fb_resources),
+	.dev		= {
+		.coherent_dma_mask = 0xFFFFFFFF,
+	},
+};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/devices.h linux-libre-2.6.34-gnu1/arch/arm/mach-mx25/devices.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/devices.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx25/devices.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,3 +18,6 @@ extern struct platform_device mxc_i2c_de
 extern struct platform_device mxc_i2c_device1;
 extern struct platform_device mxc_i2c_device2;
 extern struct platform_device mx25_fec_device;
+extern struct platform_device mxc_nand_device;
+extern struct platform_device mx25_rtc_device;
+extern struct platform_device mx25_fb_device;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-mx25/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx25/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,6 @@ if ARCH_MX25
 comment "MX25 platforms:"
 
 config MACH_MX25_3DS
-	select ARCH_MXC_IOMUX_V3
 	bool "Support MX25PDK (3DS) Platform"
 
 endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/mach-mx25pdk.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx25/mach-mx25pdk.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/mach-mx25pdk.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx25/mach-mx25pdk.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2009 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.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/fec.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/memory.h>
+#include <asm/mach/map.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/mx25.h>
+#include <mach/mxc_nand.h>
+#include <mach/imxfb.h>
+#include "devices.h"
+#include <mach/iomux-mx25.h>
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct pad_desc mx25pdk_pads[] = {
+	MX25_PAD_FEC_MDC__FEC_MDC,
+	MX25_PAD_FEC_MDIO__FEC_MDIO,
+	MX25_PAD_FEC_TDATA0__FEC_TDATA0,
+	MX25_PAD_FEC_TDATA1__FEC_TDATA1,
+	MX25_PAD_FEC_TX_EN__FEC_TX_EN,
+	MX25_PAD_FEC_RDATA0__FEC_RDATA0,
+	MX25_PAD_FEC_RDATA1__FEC_RDATA1,
+	MX25_PAD_FEC_RX_DV__FEC_RX_DV,
+	MX25_PAD_FEC_TX_CLK__FEC_TX_CLK,
+	MX25_PAD_A17__GPIO_2_3, /* FEC_EN, GPIO 35 */
+	MX25_PAD_D12__GPIO_4_8, /* FEC_RESET_B, GPIO 104 */
+
+	/* LCD */
+	MX25_PAD_LD0__LD0,
+	MX25_PAD_LD1__LD1,
+	MX25_PAD_LD2__LD2,
+	MX25_PAD_LD3__LD3,
+	MX25_PAD_LD4__LD4,
+	MX25_PAD_LD5__LD5,
+	MX25_PAD_LD6__LD6,
+	MX25_PAD_LD7__LD7,
+	MX25_PAD_LD8__LD8,
+	MX25_PAD_LD9__LD9,
+	MX25_PAD_LD10__LD10,
+	MX25_PAD_LD11__LD11,
+	MX25_PAD_LD12__LD12,
+	MX25_PAD_LD13__LD13,
+	MX25_PAD_LD14__LD14,
+	MX25_PAD_LD15__LD15,
+	MX25_PAD_GPIO_E__LD16,
+	MX25_PAD_GPIO_F__LD17,
+	MX25_PAD_HSYNC__HSYNC,
+	MX25_PAD_VSYNC__VSYNC,
+	MX25_PAD_LSCLK__LSCLK,
+	MX25_PAD_OE_ACD__OE_ACD,
+	MX25_PAD_CONTRAST__CONTRAST,
+};
+
+static struct fec_platform_data mx25_fec_pdata = {
+        .phy    = PHY_INTERFACE_MODE_RMII,
+};
+
+#define FEC_ENABLE_GPIO		35
+#define FEC_RESET_B_GPIO	104
+
+static void __init mx25pdk_fec_reset(void)
+{
+	gpio_request(FEC_ENABLE_GPIO, "FEC PHY enable");
+	gpio_request(FEC_RESET_B_GPIO, "FEC PHY reset");
+
+	gpio_direction_output(FEC_ENABLE_GPIO, 0);  /* drop PHY power */
+	gpio_direction_output(FEC_RESET_B_GPIO, 0); /* assert reset */
+	udelay(2);
+
+	/* turn on PHY power and lift reset */
+	gpio_set_value(FEC_ENABLE_GPIO, 1);
+	gpio_set_value(FEC_RESET_B_GPIO, 1);
+}
+
+static struct mxc_nand_platform_data mx25pdk_nand_board_info = {
+	.width		= 1,
+	.hw_ecc		= 1,
+	.flash_bbt	= 1,
+};
+
+static struct imx_fb_videomode mx25pdk_modes[] = {
+	{
+		.mode	= {
+			.name		= "CRT-VGA",
+			.refresh	= 60,
+			.xres		= 640,
+			.yres		= 480,
+			.pixclock	= 39683,
+			.left_margin	= 45,
+			.right_margin	= 114,
+			.upper_margin	= 33,
+			.lower_margin	= 11,
+			.hsync_len	= 1,
+			.vsync_len	= 1,
+		},
+		.bpp	= 16,
+		.pcr	= 0xFA208B80,
+	},
+};
+
+static struct imx_fb_platform_data mx25pdk_fb_pdata = {
+	.mode		= mx25pdk_modes,
+	.num_modes	= ARRAY_SIZE(mx25pdk_modes),
+	.pwmr		= 0x00A903FF,
+	.lscr1		= 0x00120300,
+	.dmacr		= 0x00020010,
+};
+
+static void __init mx25pdk_init(void)
+{
+	mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads,
+			ARRAY_SIZE(mx25pdk_pads));
+
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+	mxc_register_device(&mxc_usbh2, NULL);
+	mxc_register_device(&mxc_nand_device, &mx25pdk_nand_board_info);
+	mxc_register_device(&mx25_rtc_device, NULL);
+	mxc_register_device(&mx25_fb_device, &mx25pdk_fb_pdata);
+
+	mx25pdk_fec_reset();
+	mxc_register_device(&mx25_fec_device, &mx25_fec_pdata);
+}
+
+static void __init mx25pdk_timer_init(void)
+{
+	mx25_clocks_init();
+}
+
+static struct sys_timer mx25pdk_timer = {
+	.init   = mx25pdk_timer_init,
+};
+
+MACHINE_START(MX25_3DS, "Freescale MX25PDK (3DS)")
+	/* Maintainer: Freescale Semiconductor, Inc. */
+	.phys_io	= MX25_AIPS1_BASE_ADDR,
+	.io_pg_offst	= ((MX25_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = MX25_PHYS_OFFSET + 0x100,
+	.map_io         = mx25_map_io,
+	.init_irq       = mx25_init_irq,
+	.init_machine   = mx25pdk_init,
+	.timer          = &mx25pdk_timer,
+MACHINE_END
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-mx25/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx25/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,3 +1,3 @@
 obj-y				:= mm.o devices.o
 obj-$(CONFIG_ARCH_MX25)		+= clock.o
-obj-$(CONFIG_MACH_MX25_3DS)	+= mx25pdk.o
+obj-$(CONFIG_MACH_MX25_3DS)	+= mach-mx25pdk.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/mx25pdk.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx25/mx25pdk.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/mx25pdk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx25/mx25pdk.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,111 +0,0 @@
-/*
- * Copyright 2009 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.
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/fec.h>
-#include <linux/platform_device.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/memory.h>
-#include <asm/mach/map.h>
-#include <mach/common.h>
-#include <mach/imx-uart.h>
-#include <mach/mx25.h>
-#include <mach/mxc_nand.h>
-#include "devices.h"
-#include <mach/iomux.h>
-
-static struct imxuart_platform_data uart_pdata = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct pad_desc mx25pdk_pads[] = {
-	MX25_PAD_FEC_MDC__FEC_MDC,
-	MX25_PAD_FEC_MDIO__FEC_MDIO,
-	MX25_PAD_FEC_TDATA0__FEC_TDATA0,
-	MX25_PAD_FEC_TDATA1__FEC_TDATA1,
-	MX25_PAD_FEC_TX_EN__FEC_TX_EN,
-	MX25_PAD_FEC_RDATA0__FEC_RDATA0,
-	MX25_PAD_FEC_RDATA1__FEC_RDATA1,
-	MX25_PAD_FEC_RX_DV__FEC_RX_DV,
-	MX25_PAD_FEC_TX_CLK__FEC_TX_CLK,
-	MX25_PAD_A17__GPIO_2_3, /* FEC_EN, GPIO 35 */
-	MX25_PAD_D12__GPIO_4_8, /* FEC_RESET_B, GPIO 104 */
-};
-
-static struct fec_platform_data mx25_fec_pdata = {
-        .phy    = PHY_INTERFACE_MODE_RMII,
-};
-
-#define FEC_ENABLE_GPIO		35
-#define FEC_RESET_B_GPIO	104
-
-static void __init mx25pdk_fec_reset(void)
-{
-	gpio_request(FEC_ENABLE_GPIO, "FEC PHY enable");
-	gpio_request(FEC_RESET_B_GPIO, "FEC PHY reset");
-
-	gpio_direction_output(FEC_ENABLE_GPIO, 0);  /* drop PHY power */
-	gpio_direction_output(FEC_RESET_B_GPIO, 0); /* assert reset */
-	udelay(2);
-
-	/* turn on PHY power and lift reset */
-	gpio_set_value(FEC_ENABLE_GPIO, 1);
-	gpio_set_value(FEC_RESET_B_GPIO, 1);
-}
-
-static void __init mx25pdk_init(void)
-{
-	mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads,
-			ARRAY_SIZE(mx25pdk_pads));
-
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-	mxc_register_device(&mxc_usbh2, NULL);
-
-	mx25pdk_fec_reset();
-	mxc_register_device(&mx25_fec_device, &mx25_fec_pdata);
-}
-
-static void __init mx25pdk_timer_init(void)
-{
-	mx25_clocks_init();
-}
-
-static struct sys_timer mx25pdk_timer = {
-	.init   = mx25pdk_timer_init,
-};
-
-MACHINE_START(MX25_3DS, "Freescale MX25PDK (3DS)")
-	/* Maintainer: Freescale Semiconductor, Inc. */
-	.phys_io	= MX25_AIPS1_BASE_ADDR,
-	.io_pg_offst	= ((MX25_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx25_map_io,
-	.init_irq       = mx25_init_irq,
-	.init_machine   = mx25pdk_init,
-	.timer          = &mx25pdk_timer,
-MACHINE_END
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/armadillo5x0.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/armadillo5x0.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/armadillo5x0.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/armadillo5x0.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,416 +0,0 @@
-/*
- * armadillo5x0.c
- *
- * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
- * updates in http://alberdroid.blogspot.com/
- *
- * Based on Atmark Techno, Inc. armadillo 500 BSP 2008
- * Based on mx31ads.c and pcm037.c Great Work!
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You 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/types.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/smsc911x.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mtd/physmap.h>
-#include <linux/io.h>
-#include <linux/input.h>
-#include <linux/gpio_keys.h>
-#include <linux/i2c.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/memory.h>
-#include <asm/mach/map.h>
-
-#include <mach/common.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux-mx3.h>
-#include <mach/board-armadillo5x0.h>
-#include <mach/mmc.h>
-#include <mach/ipu.h>
-#include <mach/mx3fb.h>
-#include <mach/mxc_nand.h>
-
-#include "devices.h"
-#include "crm_regs.h"
-
-static int armadillo5x0_pins[] = {
-	/* UART1 */
-	MX31_PIN_CTS1__CTS1,
-	MX31_PIN_RTS1__RTS1,
-	MX31_PIN_TXD1__TXD1,
-	MX31_PIN_RXD1__RXD1,
-	/* UART2 */
-	MX31_PIN_CTS2__CTS2,
-	MX31_PIN_RTS2__RTS2,
-	MX31_PIN_TXD2__TXD2,
-	MX31_PIN_RXD2__RXD2,
-	/* LAN9118_IRQ */
-	IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO),
-	/* SDHC1 */
-	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,
-	/* Framebuffer */
-	MX31_PIN_LD0__LD0,
-	MX31_PIN_LD1__LD1,
-	MX31_PIN_LD2__LD2,
-	MX31_PIN_LD3__LD3,
-	MX31_PIN_LD4__LD4,
-	MX31_PIN_LD5__LD5,
-	MX31_PIN_LD6__LD6,
-	MX31_PIN_LD7__LD7,
-	MX31_PIN_LD8__LD8,
-	MX31_PIN_LD9__LD9,
-	MX31_PIN_LD10__LD10,
-	MX31_PIN_LD11__LD11,
-	MX31_PIN_LD12__LD12,
-	MX31_PIN_LD13__LD13,
-	MX31_PIN_LD14__LD14,
-	MX31_PIN_LD15__LD15,
-	MX31_PIN_LD16__LD16,
-	MX31_PIN_LD17__LD17,
-	MX31_PIN_VSYNC3__VSYNC3,
-	MX31_PIN_HSYNC__HSYNC,
-	MX31_PIN_FPSHIFT__FPSHIFT,
-	MX31_PIN_DRDY0__DRDY0,
-	IOMUX_MODE(MX31_PIN_LCS1, IOMUX_CONFIG_GPIO), /*ADV7125_PSAVE*/
-	/* I2C2 */
-	MX31_PIN_CSPI2_MOSI__SCL,
-	MX31_PIN_CSPI2_MISO__SDA,
-};
-
-/* RTC over I2C*/
-#define ARMADILLO5X0_RTC_GPIO	IOMUX_TO_GPIO(MX31_PIN_SRXD4)
-
-static struct i2c_board_info armadillo5x0_i2c_rtc = {
-	I2C_BOARD_INFO("s35390a", 0x30),
-};
-
-/* GPIO BUTTONS */
-static struct gpio_keys_button armadillo5x0_buttons[] = {
-	{
-		.code		= KEY_ENTER, /*28*/
-		.gpio		= IOMUX_TO_GPIO(MX31_PIN_SCLK0),
-		.active_low	= 1,
-		.desc		= "menu",
-		.wakeup		= 1,
-	}, {
-		.code		= KEY_BACK, /*158*/
-		.gpio		= IOMUX_TO_GPIO(MX31_PIN_SRST0),
-		.active_low	= 1,
-		.desc		= "back",
-		.wakeup		= 1,
-	}
-};
-
-static struct gpio_keys_platform_data armadillo5x0_button_data = {
-	.buttons	= armadillo5x0_buttons,
-	.nbuttons	= ARRAY_SIZE(armadillo5x0_buttons),
-};
-
-static struct platform_device armadillo5x0_button_device = {
-	.name		= "gpio-keys",
-	.id		= -1,
-	.num_resources	= 0,
-	.dev		= {
-		.platform_data	= &armadillo5x0_button_data,
-	}
-};
-
-/*
- * NAND Flash
- */
-static struct mxc_nand_platform_data armadillo5x0_nand_flash_pdata = {
-	.width		= 1,
-	.hw_ecc		= 1,
-};
-
-/*
- * MTD NOR Flash
- */
-static struct mtd_partition armadillo5x0_nor_flash_partitions[] = {
-	{
-		.name		= "nor.bootloader",
-		.offset		= 0x00000000,
-		.size		= 4*32*1024,
-	}, {
-		.name		= "nor.kernel",
-		.offset		= MTDPART_OFS_APPEND,
-		.size		= 16*128*1024,
-	}, {
-		.name		= "nor.userland",
-		.offset		= MTDPART_OFS_APPEND,
-		.size		= 110*128*1024,
-	}, {
-		.name		= "nor.config",
-		.offset		= MTDPART_OFS_APPEND,
-		.size		= 1*128*1024,
-	},
-};
-
-static struct physmap_flash_data armadillo5x0_nor_flash_pdata = {
-	.width		= 2,
-	.parts		= armadillo5x0_nor_flash_partitions,
-	.nr_parts	= ARRAY_SIZE(armadillo5x0_nor_flash_partitions),
-};
-
-static struct resource armadillo5x0_nor_flash_resource = {
-	.flags		= IORESOURCE_MEM,
-	.start		= CS0_BASE_ADDR,
-	.end		= CS0_BASE_ADDR + SZ_64M - 1,
-};
-
-static struct platform_device armadillo5x0_nor_flash = {
-	.name			= "physmap-flash",
-	.id			= -1,
-	.num_resources		= 1,
-	.resource		= &armadillo5x0_nor_flash_resource,
-};
-
-/*
- * FB support
- */
-static const struct fb_videomode fb_modedb[] = {
-	{	/* 640x480 @ 60 Hz */
-		.name		= "CRT-VGA",
-		.refresh	= 60,
-		.xres		= 640,
-		.yres		= 480,
-		.pixclock	= 39721,
-		.left_margin	= 35,
-		.right_margin	= 115,
-		.upper_margin	= 43,
-		.lower_margin	= 1,
-		.hsync_len	= 10,
-		.vsync_len	= 1,
-		.sync		= FB_SYNC_OE_ACT_HIGH,
-		.vmode		= FB_VMODE_NONINTERLACED,
-		.flag		= 0,
-	}, {/* 800x600 @ 56 Hz */
-		.name		= "CRT-SVGA",
-		.refresh	= 56,
-		.xres		= 800,
-		.yres		= 600,
-		.pixclock	= 30000,
-		.left_margin	= 30,
-		.right_margin	= 108,
-		.upper_margin	= 13,
-		.lower_margin	= 10,
-		.hsync_len	= 10,
-		.vsync_len	= 1,
-		.sync		= FB_SYNC_OE_ACT_HIGH | FB_SYNC_HOR_HIGH_ACT |
-				  FB_SYNC_VERT_HIGH_ACT,
-		.vmode		= FB_VMODE_NONINTERLACED,
-		.flag		= 0,
-	},
-};
-
-static struct ipu_platform_data mx3_ipu_data = {
-	.irq_base = MXC_IPU_IRQ_START,
-};
-
-static struct mx3fb_platform_data mx3fb_pdata = {
-	.dma_dev	= &mx3_ipu.dev,
-	.name		= "CRT-VGA",
-	.mode		= fb_modedb,
-	.num_modes	= ARRAY_SIZE(fb_modedb),
-};
-
-/*
- * SDHC 1
- * MMC support
- */
-static int armadillo5x0_sdhc1_get_ro(struct device *dev)
-{
-	return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B));
-}
-
-static int armadillo5x0_sdhc1_init(struct device *dev,
-				   irq_handler_t detect_irq, void *data)
-{
-	int ret;
-	int gpio_det, gpio_wp;
-
-	gpio_det = IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK);
-	gpio_wp = IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B);
-
-	ret = gpio_request(gpio_det, "sdhc-card-detect");
-	if (ret)
-		return ret;
-
-	gpio_direction_input(gpio_det);
-
-	ret = gpio_request(gpio_wp, "sdhc-write-protect");
-	if (ret)
-		goto err_gpio_free;
-
-	gpio_direction_input(gpio_wp);
-
-	/* When supported the trigger type have to be BOTH */
-	ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), detect_irq,
-			  IRQF_DISABLED | IRQF_TRIGGER_FALLING,
-			  "sdhc-detect", data);
-
-	if (ret)
-		goto err_gpio_free_2;
-
-	return 0;
-
-err_gpio_free_2:
-	gpio_free(gpio_wp);
-
-err_gpio_free:
-	gpio_free(gpio_det);
-
-	return ret;
-
-}
-
-static void armadillo5x0_sdhc1_exit(struct device *dev, void *data)
-{
-	free_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), data);
-	gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK));
-	gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B));
-}
-
-static struct imxmmc_platform_data sdhc_pdata = {
-	.get_ro = armadillo5x0_sdhc1_get_ro,
-	.init = armadillo5x0_sdhc1_init,
-	.exit = armadillo5x0_sdhc1_exit,
-};
-
-/*
- * SMSC 9118
- * Network support
- */
-static struct resource armadillo5x0_smc911x_resources[] = {
-	{
-		.start	= CS3_BASE_ADDR,
-		.end	= CS3_BASE_ADDR + SZ_32M - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
-		.end	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
-		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-	},
-};
-
-static struct smsc911x_platform_config smsc911x_info = {
-	.flags		= SMSC911X_USE_16BIT,
-	.irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
-};
-
-static struct platform_device armadillo5x0_smc911x_device = {
-	.name           = "smsc911x",
-	.id             = -1,
-	.num_resources  = ARRAY_SIZE(armadillo5x0_smc911x_resources),
-	.resource       = armadillo5x0_smc911x_resources,
-	.dev            = {
-		.platform_data = &smsc911x_info,
-	},
-};
-
-/* UART device data */
-static struct imxuart_platform_data uart_pdata = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct platform_device *devices[] __initdata = {
-	&armadillo5x0_smc911x_device,
-	&mxc_i2c_device1,
-	&armadillo5x0_button_device,
-};
-
-/*
- * Perform board specific initializations
- */
-static void __init armadillo5x0_init(void)
-{
-	mxc_iomux_setup_multiple_pins(armadillo5x0_pins,
-			ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0");
-
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-
-	/* Register UART */
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-	mxc_register_device(&mxc_uart_device1, &uart_pdata);
-
-	/* SMSC9118 IRQ pin */
-	gpio_direction_input(MX31_PIN_GPIO1_0);
-
-	/* Register SDHC */
-	mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
-
-	/* Register FB */
-	mxc_register_device(&mx3_ipu, &mx3_ipu_data);
-	mxc_register_device(&mx3_fb, &mx3fb_pdata);
-
-	/* Register NOR Flash */
-	mxc_register_device(&armadillo5x0_nor_flash,
-			    &armadillo5x0_nor_flash_pdata);
-
-	/* Register NAND Flash */
-	mxc_register_device(&mxc_nand_device, &armadillo5x0_nand_flash_pdata);
-
-	/* set NAND page size to 2k if not configured via boot mode pins */
-	__raw_writel(__raw_readl(MXC_CCM_RCSR) | (1 << 30), MXC_CCM_RCSR);
-
-	/* RTC */
-	/* Get RTC IRQ and register the chip */
-	if (gpio_request(ARMADILLO5X0_RTC_GPIO, "rtc") == 0) {
-		if (gpio_direction_input(ARMADILLO5X0_RTC_GPIO) == 0)
-			armadillo5x0_i2c_rtc.irq = gpio_to_irq(ARMADILLO5X0_RTC_GPIO);
-		else
-			gpio_free(ARMADILLO5X0_RTC_GPIO);
-	}
-	if (armadillo5x0_i2c_rtc.irq == 0)
-		pr_warning("armadillo5x0_init: failed to get RTC IRQ\n");
-	i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1);
-}
-
-static void __init armadillo5x0_timer_init(void)
-{
-	mx31_clocks_init(26000000);
-}
-
-static struct sys_timer armadillo5x0_timer = {
-	.init	= armadillo5x0_timer_init,
-};
-
-MACHINE_START(ARMADILLO5X0, "Armadillo-500")
-	/* Maintainer: Alberto Panizzo  */
-	.phys_io	= AIPS1_BASE_ADDR,
-	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params	= PHYS_OFFSET + 0x00000100,
-	.map_io		= mx31_map_io,
-	.init_irq	= mx31_init_irq,
-	.timer		= &armadillo5x0_timer,
-	.init_machine	= armadillo5x0_init,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/clock.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,632 +0,0 @@
-/*
- * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * 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.
- */
-
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#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 <mach/mx31.h>
-#include <mach/common.h>
-
-#include "crm_regs.h"
-
-#define PRE_DIV_MIN_FREQ    10000000 /* Minimum Frequency after Predivider */
-
-static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
-{
-	u32 min_pre, temp_pre, old_err, err;
-
-	if (div >= 512) {
-		*pre = 8;
-		*post = 64;
-	} else if (div >= 64) {
-		min_pre = (div - 1) / 64 + 1;
-		old_err = 8;
-		for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
-			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;
-	} else if (div <= 8) {
-		*pre = div;
-		*post = 1;
-	} else {
-		*pre = 1;
-		*post = div;
-	}
-}
-
-static struct clk mcu_pll_clk;
-static struct clk serial_pll_clk;
-static struct clk ipg_clk;
-static struct clk ckih_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);
-
-	return 0;
-}
-
-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);
-
-	/* special case for EMI clock */
-	if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8)
-		reg |= (1 << clk->enable_shift);
-
-	__raw_writel(reg, clk->enable_reg);
-}
-
-static unsigned long pll_ref_get_rate(void)
-{
-	unsigned long ccmr;
-	unsigned int prcs;
-
-	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);
-}
-
-static unsigned long usb_pll_get_rate(struct clk *clk)
-{
-	unsigned long reg;
-
-	reg = __raw_readl(MXC_CCM_UPCTL);
-
-	return mxc_decode_pll(reg, pll_ref_get_rate());
-}
-
-static unsigned long serial_pll_get_rate(struct clk *clk)
-{
-	unsigned long reg;
-
-	reg = __raw_readl(MXC_CCM_SRPCTL);
-
-	return mxc_decode_pll(reg, pll_ref_get_rate());
-}
-
-static unsigned long mcu_pll_get_rate(struct clk *clk)
-{
-	unsigned long reg, ccmr;
-
-	ccmr = __raw_readl(MXC_CCM_CCMR);
-
-	if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS))
-		return clk_get_rate(&ckih_clk);
-
-	reg = __raw_readl(MXC_CCM_MPCTL);
-
-	return mxc_decode_pll(reg, pll_ref_get_rate());
-}
-
-static int usb_pll_enable(struct clk *clk)
-{
-	u32 reg;
-
-	reg = __raw_readl(MXC_CCM_CCMR);
-	reg |= MXC_CCM_CCMR_UPE;
-	__raw_writel(reg, MXC_CCM_CCMR);
-
-	/* No lock bit on MX31, so using max time from spec */
-	udelay(80);
-
-	return 0;
-}
-
-static void usb_pll_disable(struct clk *clk)
-{
-	u32 reg;
-
-	reg = __raw_readl(MXC_CCM_CCMR);
-	reg &= ~MXC_CCM_CCMR_UPE;
-	__raw_writel(reg, MXC_CCM_CCMR);
-}
-
-static int serial_pll_enable(struct clk *clk)
-{
-	u32 reg;
-
-	reg = __raw_readl(MXC_CCM_CCMR);
-	reg |= MXC_CCM_CCMR_SPE;
-	__raw_writel(reg, MXC_CCM_CCMR);
-
-	/* No lock bit on MX31, so using max time from spec */
-	udelay(80);
-
-	return 0;
-}
-
-static void serial_pll_disable(struct clk *clk)
-{
-	u32 reg;
-
-	reg = __raw_readl(MXC_CCM_CCMR);
-	reg &= ~MXC_CCM_CCMR_SPE;
-	__raw_writel(reg, MXC_CCM_CCMR);
-}
-
-#define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off)
-#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 mcu_main_get_rate(struct clk *clk)
-{
-	u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0);
-
-	if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL)
-		return clk_get_rate(&serial_pll_clk);
-	else
-		return clk_get_rate(&mcu_pll_clk);
-}
-
-static unsigned long ahb_get_rate(struct clk *clk)
-{
-	unsigned long max_pdf;
-
-	max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK,
-		       MXC_CCM_PDR0_MAX_PODF_OFFSET);
-	return clk_get_rate(clk->parent) / (max_pdf + 1);
-}
-
-static unsigned long ipg_get_rate(struct clk *clk)
-{
-	unsigned long ipg_pdf;
-
-	ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK,
-		       MXC_CCM_PDR0_IPG_PODF_OFFSET);
-	return clk_get_rate(clk->parent) / (ipg_pdf + 1);
-}
-
-static unsigned long nfc_get_rate(struct clk *clk)
-{
-	unsigned long nfc_pdf;
-
-	nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK,
-		       MXC_CCM_PDR0_NFC_PODF_OFFSET);
-	return clk_get_rate(clk->parent) / (nfc_pdf + 1);
-}
-
-static unsigned long hsp_get_rate(struct clk *clk)
-{
-	unsigned long hsp_pdf;
-
-	hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK,
-		       MXC_CCM_PDR0_HSP_PODF_OFFSET);
-	return clk_get_rate(clk->parent) / (hsp_pdf + 1);
-}
-
-static unsigned long usb_get_rate(struct clk *clk)
-{
-	unsigned long usb_pdf, usb_prepdf;
-
-	usb_pdf = PDR1(MXC_CCM_PDR1_USB_PODF_MASK,
-		       MXC_CCM_PDR1_USB_PODF_OFFSET);
-	usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK,
-			  MXC_CCM_PDR1_USB_PRDF_OFFSET);
-	return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1);
-}
-
-static unsigned long csi_get_rate(struct clk *clk)
-{
-	u32 reg, pre, post;
-
-	reg = __raw_readl(MXC_CCM_PDR0);
-	pre = (reg & MXC_CCM_PDR0_CSI_PRDF_MASK) >>
-	    MXC_CCM_PDR0_CSI_PRDF_OFFSET;
-	pre++;
-	post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >>
-	    MXC_CCM_PDR0_CSI_PODF_OFFSET;
-	post++;
-	return clk_get_rate(clk->parent) / (pre * post);
-}
-
-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;
-
-	if (parent % rate)
-		div++;
-
-	__calc_pre_post_dividers(div, &pre, &post);
-
-	return parent / (pre * post);
-}
-
-static int csi_set_rate(struct clk *clk, unsigned long rate)
-{
-	u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
-
-	div = parent / rate;
-
-	if ((parent / div) != rate)
-		return -EINVAL;
-
-	__calc_pre_post_dividers(div, &pre, &post);
-
-	/* Set CSI clock divider */
-	reg = __raw_readl(MXC_CCM_PDR0) &
-	    ~(MXC_CCM_PDR0_CSI_PODF_MASK | MXC_CCM_PDR0_CSI_PRDF_MASK);
-	reg |= (post - 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET;
-	reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET;
-	__raw_writel(reg, MXC_CCM_PDR0);
-
-	return 0;
-}
-
-static unsigned long ssi1_get_rate(struct clk *clk)
-{
-	unsigned long ssi1_pdf, ssi1_prepdf;
-
-	ssi1_pdf = PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK,
-			MXC_CCM_PDR1_SSI1_PODF_OFFSET);
-	ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK,
-			   MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET);
-	return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1);
-}
-
-static unsigned long ssi2_get_rate(struct clk *clk)
-{
-	unsigned long ssi2_pdf, ssi2_prepdf;
-
-	ssi2_pdf = PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK,
-			MXC_CCM_PDR1_SSI2_PODF_OFFSET);
-	ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK,
-			   MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET);
-	return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1);
-}
-
-static unsigned long firi_get_rate(struct clk *clk)
-{
-	unsigned long firi_pdf, firi_prepdf;
-
-	firi_pdf = PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK,
-			MXC_CCM_PDR1_FIRI_PODF_OFFSET);
-	firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK,
-			   MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET);
-	return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1);
-}
-
-static unsigned long firi_round_rate(struct clk *clk, unsigned long rate)
-{
-	u32 pre, post;
-	u32 parent = clk_get_rate(clk->parent);
-	u32 div = parent / rate;
-
-	if (parent % rate)
-		div++;
-
-	__calc_pre_post_dividers(div, &pre, &post);
-
-	return parent / (pre * post);
-
-}
-
-static int firi_set_rate(struct clk *clk, unsigned long rate)
-{
-	u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
-
-	div = parent / rate;
-
-	if ((parent / div) != rate)
-		return -EINVAL;
-
-	__calc_pre_post_dividers(div, &pre, &post);
-
-	/* Set FIRI clock divider */
-	reg = __raw_readl(MXC_CCM_PDR1) &
-	    ~(MXC_CCM_PDR1_FIRI_PODF_MASK | MXC_CCM_PDR1_FIRI_PRE_PODF_MASK);
-	reg |= (pre - 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET;
-	reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET;
-	__raw_writel(reg, MXC_CCM_PDR1);
-
-	return 0;
-}
-
-static unsigned long mbx_get_rate(struct clk *clk)
-{
-	return clk_get_rate(clk->parent) / 2;
-}
-
-static unsigned long mstick1_get_rate(struct clk *clk)
-{
-	unsigned long msti_pdf;
-
-	msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK,
-			MXC_CCM_PDR2_MST1_PDF_OFFSET);
-	return clk_get_rate(clk->parent) / (msti_pdf + 1);
-}
-
-static unsigned long mstick2_get_rate(struct clk *clk)
-{
-	unsigned long msti_pdf;
-
-	msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK,
-			MXC_CCM_PDR2_MST2_PDF_OFFSET);
-	return clk_get_rate(clk->parent) / (msti_pdf + 1);
-}
-
-static unsigned long ckih_rate;
-
-static unsigned long clk_ckih_get_rate(struct clk *clk)
-{
-	return ckih_rate;
-}
-
-static unsigned long clk_ckil_get_rate(struct clk *clk)
-{
-	return CKIL_CLK_FREQ;
-}
-
-static struct clk ckih_clk = {
-	.get_rate = clk_ckih_get_rate,
-};
-
-static struct clk mcu_pll_clk = {
-	.parent = &ckih_clk,
-	.get_rate = mcu_pll_get_rate,
-};
-
-static struct clk mcu_main_clk = {
-	.parent = &mcu_pll_clk,
-	.get_rate = mcu_main_get_rate,
-};
-
-static struct clk serial_pll_clk = {
-	.parent = &ckih_clk,
-	.get_rate = serial_pll_get_rate,
-	.enable = serial_pll_enable,
-	.disable = serial_pll_disable,
-};
-
-static struct clk usb_pll_clk = {
-	.parent = &ckih_clk,
-	.get_rate = usb_pll_get_rate,
-	.enable = usb_pll_enable,
-	.disable = usb_pll_disable,
-};
-
-static struct clk ahb_clk = {
-	.parent = &mcu_main_clk,
-	.get_rate = ahb_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,			\
-	}
-
-#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,				\
-	}
-
-DEFINE_CLOCK(perclk_clk,  0, NULL,          0, NULL, NULL, &ipg_clk);
-
-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);
-
-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, &serial_pll_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);
-
-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);
-
-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);
-DEFINE_CLOCK(ckil_clk,    0, NULL,          0, clk_ckil_get_rate, NULL, NULL);
-
-#define _REGISTER_CLOCK(d, n, c) \
-	{ \
-		.dev_id = d, \
-		.con_id = n, \
-		.clk = &c, \
-	},
-
-static struct clk_lookup lookups[] = {
-	_REGISTER_CLOCK(NULL, "emi", emi_clk)
-	_REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
-	_REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
-	_REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
-	_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
-	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
-	_REGISTER_CLOCK("imx-wdt.0", NULL, 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("mxc-ehci.0", "usb", usb_clk1)
-	_REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk2)
-	_REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk1)
-	_REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk2)
-	_REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk1)
-	_REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk2)
-	_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("imx-ssi.0", NULL, ssi1_clk)
-	_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
-	_REGISTER_CLOCK(NULL, "firi", firi_clk)
-	_REGISTER_CLOCK(NULL, "ata", ata_clk)
-	_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
-	_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)
-	_REGISTER_CLOCK("mxc_rtc", NULL, ckil_clk)
-};
-
-int __init mx31_clocks_init(unsigned long fref)
-{
-	u32 reg;
-	int i;
-
-	ckih_rate = fref;
-
-	for (i = 0; i < ARRAY_SIZE(lookups); i++)
-		clkdev_add(&lookups[i]);
-
-	/* change the csi_clk parent if necessary */
-	reg = __raw_readl(MXC_CCM_CCMR);
-	if (!(reg & MXC_CCM_CCMR_CSCS))
-		if (clk_set_parent(&csi_clk, &usb_pll_clk))
-			pr_err("%s: error changing csi_clk parent\n", __func__);
-
-
-	/* Turn off all possible clocks */
-	__raw_writel((3 << 4), MXC_CCM_CGR0);
-	__raw_writel(0, MXC_CCM_CGR1);
-	__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);
-
-	/*
-	 * Before turning off usb_pll make sure ipg_per_clk is generated
-	 * by ipg_clk and not usb_pll.
-	 */
-	__raw_writel(__raw_readl(MXC_CCM_CCMR) | (1 << 24), MXC_CCM_CCMR);
-
-	usb_pll_disable(&usb_pll_clk);
-
-	pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk));
-
-	clk_enable(&gpt_clk);
-	clk_enable(&emi_clk);
-	clk_enable(&iim_clk);
-
-	clk_enable(&serial_pll_clk);
-
-	mx31_read_cpu_rev();
-
-	if (mx31_revision() >= CHIP_REV_2_0) {
-		reg = __raw_readl(MXC_CCM_PMCR1);
-		/* No PLL restart on DVFS switch; enable auto EMI handshake */
-		reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN;
-		__raw_writel(reg, MXC_CCM_PMCR1);
-	}
-
-	mxc_timer_init(&ipg_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT);
-
-	return 0;
-}
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/clock-imx31.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/clock-imx31.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/clock-imx31.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/clock-imx31.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,630 @@
+/*
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#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 <mach/mx31.h>
+#include <mach/common.h>
+
+#include "crm_regs.h"
+
+#define PRE_DIV_MIN_FREQ    10000000 /* Minimum Frequency after Predivider */
+
+static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
+{
+	u32 min_pre, temp_pre, old_err, err;
+
+	if (div >= 512) {
+		*pre = 8;
+		*post = 64;
+	} else if (div >= 64) {
+		min_pre = (div - 1) / 64 + 1;
+		old_err = 8;
+		for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
+			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;
+	} else if (div <= 8) {
+		*pre = div;
+		*post = 1;
+	} else {
+		*pre = 1;
+		*post = div;
+	}
+}
+
+static struct clk mcu_pll_clk;
+static struct clk serial_pll_clk;
+static struct clk ipg_clk;
+static struct clk ckih_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);
+
+	return 0;
+}
+
+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);
+
+	/* special case for EMI clock */
+	if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8)
+		reg |= (1 << clk->enable_shift);
+
+	__raw_writel(reg, clk->enable_reg);
+}
+
+static unsigned long pll_ref_get_rate(void)
+{
+	unsigned long ccmr;
+	unsigned int prcs;
+
+	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);
+}
+
+static unsigned long usb_pll_get_rate(struct clk *clk)
+{
+	unsigned long reg;
+
+	reg = __raw_readl(MXC_CCM_UPCTL);
+
+	return mxc_decode_pll(reg, pll_ref_get_rate());
+}
+
+static unsigned long serial_pll_get_rate(struct clk *clk)
+{
+	unsigned long reg;
+
+	reg = __raw_readl(MXC_CCM_SRPCTL);
+
+	return mxc_decode_pll(reg, pll_ref_get_rate());
+}
+
+static unsigned long mcu_pll_get_rate(struct clk *clk)
+{
+	unsigned long reg, ccmr;
+
+	ccmr = __raw_readl(MXC_CCM_CCMR);
+
+	if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS))
+		return clk_get_rate(&ckih_clk);
+
+	reg = __raw_readl(MXC_CCM_MPCTL);
+
+	return mxc_decode_pll(reg, pll_ref_get_rate());
+}
+
+static int usb_pll_enable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(MXC_CCM_CCMR);
+	reg |= MXC_CCM_CCMR_UPE;
+	__raw_writel(reg, MXC_CCM_CCMR);
+
+	/* No lock bit on MX31, so using max time from spec */
+	udelay(80);
+
+	return 0;
+}
+
+static void usb_pll_disable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(MXC_CCM_CCMR);
+	reg &= ~MXC_CCM_CCMR_UPE;
+	__raw_writel(reg, MXC_CCM_CCMR);
+}
+
+static int serial_pll_enable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(MXC_CCM_CCMR);
+	reg |= MXC_CCM_CCMR_SPE;
+	__raw_writel(reg, MXC_CCM_CCMR);
+
+	/* No lock bit on MX31, so using max time from spec */
+	udelay(80);
+
+	return 0;
+}
+
+static void serial_pll_disable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(MXC_CCM_CCMR);
+	reg &= ~MXC_CCM_CCMR_SPE;
+	__raw_writel(reg, MXC_CCM_CCMR);
+}
+
+#define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off)
+#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 mcu_main_get_rate(struct clk *clk)
+{
+	u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0);
+
+	if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL)
+		return clk_get_rate(&serial_pll_clk);
+	else
+		return clk_get_rate(&mcu_pll_clk);
+}
+
+static unsigned long ahb_get_rate(struct clk *clk)
+{
+	unsigned long max_pdf;
+
+	max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK,
+		       MXC_CCM_PDR0_MAX_PODF_OFFSET);
+	return clk_get_rate(clk->parent) / (max_pdf + 1);
+}
+
+static unsigned long ipg_get_rate(struct clk *clk)
+{
+	unsigned long ipg_pdf;
+
+	ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK,
+		       MXC_CCM_PDR0_IPG_PODF_OFFSET);
+	return clk_get_rate(clk->parent) / (ipg_pdf + 1);
+}
+
+static unsigned long nfc_get_rate(struct clk *clk)
+{
+	unsigned long nfc_pdf;
+
+	nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK,
+		       MXC_CCM_PDR0_NFC_PODF_OFFSET);
+	return clk_get_rate(clk->parent) / (nfc_pdf + 1);
+}
+
+static unsigned long hsp_get_rate(struct clk *clk)
+{
+	unsigned long hsp_pdf;
+
+	hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK,
+		       MXC_CCM_PDR0_HSP_PODF_OFFSET);
+	return clk_get_rate(clk->parent) / (hsp_pdf + 1);
+}
+
+static unsigned long usb_get_rate(struct clk *clk)
+{
+	unsigned long usb_pdf, usb_prepdf;
+
+	usb_pdf = PDR1(MXC_CCM_PDR1_USB_PODF_MASK,
+		       MXC_CCM_PDR1_USB_PODF_OFFSET);
+	usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK,
+			  MXC_CCM_PDR1_USB_PRDF_OFFSET);
+	return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1);
+}
+
+static unsigned long csi_get_rate(struct clk *clk)
+{
+	u32 reg, pre, post;
+
+	reg = __raw_readl(MXC_CCM_PDR0);
+	pre = (reg & MXC_CCM_PDR0_CSI_PRDF_MASK) >>
+	    MXC_CCM_PDR0_CSI_PRDF_OFFSET;
+	pre++;
+	post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >>
+	    MXC_CCM_PDR0_CSI_PODF_OFFSET;
+	post++;
+	return clk_get_rate(clk->parent) / (pre * post);
+}
+
+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;
+
+	if (parent % rate)
+		div++;
+
+	__calc_pre_post_dividers(div, &pre, &post);
+
+	return parent / (pre * post);
+}
+
+static int csi_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
+
+	div = parent / rate;
+
+	if ((parent / div) != rate)
+		return -EINVAL;
+
+	__calc_pre_post_dividers(div, &pre, &post);
+
+	/* Set CSI clock divider */
+	reg = __raw_readl(MXC_CCM_PDR0) &
+	    ~(MXC_CCM_PDR0_CSI_PODF_MASK | MXC_CCM_PDR0_CSI_PRDF_MASK);
+	reg |= (post - 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET;
+	reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET;
+	__raw_writel(reg, MXC_CCM_PDR0);
+
+	return 0;
+}
+
+static unsigned long ssi1_get_rate(struct clk *clk)
+{
+	unsigned long ssi1_pdf, ssi1_prepdf;
+
+	ssi1_pdf = PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK,
+			MXC_CCM_PDR1_SSI1_PODF_OFFSET);
+	ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK,
+			   MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET);
+	return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1);
+}
+
+static unsigned long ssi2_get_rate(struct clk *clk)
+{
+	unsigned long ssi2_pdf, ssi2_prepdf;
+
+	ssi2_pdf = PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK,
+			MXC_CCM_PDR1_SSI2_PODF_OFFSET);
+	ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK,
+			   MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET);
+	return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1);
+}
+
+static unsigned long firi_get_rate(struct clk *clk)
+{
+	unsigned long firi_pdf, firi_prepdf;
+
+	firi_pdf = PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK,
+			MXC_CCM_PDR1_FIRI_PODF_OFFSET);
+	firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK,
+			   MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET);
+	return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1);
+}
+
+static unsigned long firi_round_rate(struct clk *clk, unsigned long rate)
+{
+	u32 pre, post;
+	u32 parent = clk_get_rate(clk->parent);
+	u32 div = parent / rate;
+
+	if (parent % rate)
+		div++;
+
+	__calc_pre_post_dividers(div, &pre, &post);
+
+	return parent / (pre * post);
+
+}
+
+static int firi_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
+
+	div = parent / rate;
+
+	if ((parent / div) != rate)
+		return -EINVAL;
+
+	__calc_pre_post_dividers(div, &pre, &post);
+
+	/* Set FIRI clock divider */
+	reg = __raw_readl(MXC_CCM_PDR1) &
+	    ~(MXC_CCM_PDR1_FIRI_PODF_MASK | MXC_CCM_PDR1_FIRI_PRE_PODF_MASK);
+	reg |= (pre - 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET;
+	reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET;
+	__raw_writel(reg, MXC_CCM_PDR1);
+
+	return 0;
+}
+
+static unsigned long mbx_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) / 2;
+}
+
+static unsigned long mstick1_get_rate(struct clk *clk)
+{
+	unsigned long msti_pdf;
+
+	msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK,
+			MXC_CCM_PDR2_MST1_PDF_OFFSET);
+	return clk_get_rate(clk->parent) / (msti_pdf + 1);
+}
+
+static unsigned long mstick2_get_rate(struct clk *clk)
+{
+	unsigned long msti_pdf;
+
+	msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK,
+			MXC_CCM_PDR2_MST2_PDF_OFFSET);
+	return clk_get_rate(clk->parent) / (msti_pdf + 1);
+}
+
+static unsigned long ckih_rate;
+
+static unsigned long clk_ckih_get_rate(struct clk *clk)
+{
+	return ckih_rate;
+}
+
+static unsigned long clk_ckil_get_rate(struct clk *clk)
+{
+	return CKIL_CLK_FREQ;
+}
+
+static struct clk ckih_clk = {
+	.get_rate = clk_ckih_get_rate,
+};
+
+static struct clk mcu_pll_clk = {
+	.parent = &ckih_clk,
+	.get_rate = mcu_pll_get_rate,
+};
+
+static struct clk mcu_main_clk = {
+	.parent = &mcu_pll_clk,
+	.get_rate = mcu_main_get_rate,
+};
+
+static struct clk serial_pll_clk = {
+	.parent = &ckih_clk,
+	.get_rate = serial_pll_get_rate,
+	.enable = serial_pll_enable,
+	.disable = serial_pll_disable,
+};
+
+static struct clk usb_pll_clk = {
+	.parent = &ckih_clk,
+	.get_rate = usb_pll_get_rate,
+	.enable = usb_pll_enable,
+	.disable = usb_pll_disable,
+};
+
+static struct clk ahb_clk = {
+	.parent = &mcu_main_clk,
+	.get_rate = ahb_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,			\
+	}
+
+#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,				\
+	}
+
+DEFINE_CLOCK(perclk_clk,  0, NULL,          0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ckil_clk,    0, NULL,          0, clk_ckil_get_rate, NULL, NULL);
+
+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);
+
+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, &serial_pll_clk);
+DEFINE_CLOCK(rtc_clk,     0, MXC_CCM_CGR1,  8, NULL, NULL, &ckil_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);
+
+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);
+
+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);
+
+#define _REGISTER_CLOCK(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c, \
+	},
+
+static struct clk_lookup lookups[] = {
+	_REGISTER_CLOCK(NULL, "emi", emi_clk)
+	_REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
+	_REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
+	_REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
+	_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
+	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+	_REGISTER_CLOCK("imx-wdt.0", NULL, 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("mxc-ehci.0", "usb", usb_clk1)
+	_REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk2)
+	_REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk1)
+	_REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk2)
+	_REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk1)
+	_REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk2)
+	_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("imx-ssi.0", NULL, ssi1_clk)
+	_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+	_REGISTER_CLOCK(NULL, "firi", firi_clk)
+	_REGISTER_CLOCK(NULL, "ata", ata_clk)
+	_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
+	_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)
+};
+
+int __init mx31_clocks_init(unsigned long fref)
+{
+	u32 reg;
+
+	ckih_rate = fref;
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	/* change the csi_clk parent if necessary */
+	reg = __raw_readl(MXC_CCM_CCMR);
+	if (!(reg & MXC_CCM_CCMR_CSCS))
+		if (clk_set_parent(&csi_clk, &usb_pll_clk))
+			pr_err("%s: error changing csi_clk parent\n", __func__);
+
+
+	/* Turn off all possible clocks */
+	__raw_writel((3 << 4), MXC_CCM_CGR0);
+	__raw_writel(0, MXC_CCM_CGR1);
+	__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);
+
+	/*
+	 * Before turning off usb_pll make sure ipg_per_clk is generated
+	 * by ipg_clk and not usb_pll.
+	 */
+	__raw_writel(__raw_readl(MXC_CCM_CCMR) | (1 << 24), MXC_CCM_CCMR);
+
+	usb_pll_disable(&usb_pll_clk);
+
+	pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk));
+
+	clk_enable(&gpt_clk);
+	clk_enable(&emi_clk);
+	clk_enable(&iim_clk);
+
+	clk_enable(&serial_pll_clk);
+
+	mx31_read_cpu_rev();
+
+	if (mx31_revision() >= MX31_CHIP_REV_2_0) {
+		reg = __raw_readl(MXC_CCM_PMCR1);
+		/* No PLL restart on DVFS switch; enable auto EMI handshake */
+		reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN;
+		__raw_writel(reg, MXC_CCM_PMCR1);
+	}
+
+	mxc_timer_init(&ipg_clk, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR),
+			MX31_INT_GPT);
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/clock-imx35.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/clock-imx35.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/clock-imx35.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/clock-imx35.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,7 @@
 #include <mach/hardware.h>
 #include <mach/common.h>
 
-#define CCM_BASE	IO_ADDRESS(CCM_BASE_ADDR)
+#define CCM_BASE	MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR)
 
 #define CCM_CCMR        0x00
 #define CCM_PDR0        0x04
@@ -485,15 +485,13 @@ static struct clk_lookup lookups[] = {
 
 int __init mx35_clocks_init()
 {
-	int i;
 	unsigned int ll = 0;
 
 #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
 	ll = (3 << 16);
 #endif
 
-	for (i = 0; i < ARRAY_SIZE(lookups); i++)
-		clkdev_add(&lookups[i]);
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	/* Turn off all clocks except the ones we need to survive, namely:
 	 * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart
@@ -504,7 +502,8 @@ int __init mx35_clocks_init()
 	__raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2);
 	__raw_writel(0, CCM_BASE + CCM_CGR3);
 
-	mxc_timer_init(&gpt_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT);
+	mxc_timer_init(&gpt_clk,
+			MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/cpu.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/cpu.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/cpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/cpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,7 @@ void __init mx31_read_cpu_rev(void)
 	u32 i, srev;
 
 	/* read SREV register from IIM module */
-	srev = __raw_readl(IO_ADDRESS(IIM_BASE_ADDR) + MXC_IIMSREV);
+	srev = __raw_readl(IO_ADDRESS(IIM_BASE_ADDR + MXC_IIMSREV));
 
 	for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++)
 		if (srev == mx31_cpu_type[i].srev) {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/crm_regs.h linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/crm_regs.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/crm_regs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/crm_regs.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,7 @@
 #define CKIH_CLK_FREQ_27MHZ     27000000
 #define CKIL_CLK_FREQ           32768
 
-#define MXC_CCM_BASE		IO_ADDRESS(CCM_BASE_ADDR)
+#define MXC_CCM_BASE		MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR)
 
 /* Register addresses */
 #define MXC_CCM_CCMR		(MXC_CCM_BASE + 0x00)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/devices.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/devices.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/devices.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/devices.c	2010-05-16 17:17:36.000000000 -0400
@@ -575,11 +575,26 @@ struct platform_device imx_ssi_device1 =
 	.resource = imx_ssi_resources1,
 };
 
-static int mx3_devices_init(void)
+static struct resource imx_wdt_resources[] = {
+	{
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device imx_wdt_device0 = {
+	.name           = "imx-wdt",
+	.id             = 0,
+	.num_resources  = ARRAY_SIZE(imx_wdt_resources),
+	.resource       = imx_wdt_resources,
+};
+
+static int __init 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;
+		imx_wdt_resources[0].start = MX31_WDOG_BASE_ADDR;
+		imx_wdt_resources[0].end = MX31_WDOG_BASE_ADDR + 0x3fff;
 		mxc_register_device(&mxc_rnga_device, NULL);
 	}
 	if (cpu_is_mx35()) {
@@ -597,6 +612,8 @@ static int mx3_devices_init(void)
 		imx_ssi_resources0[1].end = MX35_INT_SSI1;
 		imx_ssi_resources1[1].start = MX35_INT_SSI2;
 		imx_ssi_resources1[1].end = MX35_INT_SSI2;
+		imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR;
+		imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff;
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/devices.h linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/devices.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/devices.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/devices.h	2010-05-16 17:17:36.000000000 -0400
@@ -25,4 +25,5 @@ extern struct platform_device mxc_spi_de
 extern struct platform_device mxc_spi_device2;
 extern struct platform_device imx_ssi_device0;
 extern struct platform_device imx_ssi_device1;
-
+extern struct platform_device imx_ssi_device1;
+extern struct platform_device imx_wdt_device0;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/iomux.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/iomux.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/iomux.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/iomux.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,181 +0,0 @@
-/*
- * 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
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <mach/iomux-mx3.h>
-
-/*
- * IOMUX register (base) addresses
- */
-#define IOMUX_BASE	IO_ADDRESS(IOMUXC_BASE_ADDR)
-#define IOMUXINT_OBS1	(IOMUX_BASE + 0x000)
-#define IOMUXINT_OBS2	(IOMUX_BASE + 0x004)
-#define IOMUXGPR	(IOMUX_BASE + 0x008)
-#define IOMUXSW_MUX_CTL	(IOMUX_BASE + 0x00C)
-#define IOMUXSW_PAD_CTL	(IOMUX_BASE + 0x154)
-
-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.
- */
-int mxc_iomux_mode(unsigned int pin_mode)
-{
-	u32 field, l, mode, ret = 0;
-	void __iomem *reg;
-
-	reg = IOMUXSW_MUX_CTL + (pin_mode & IOMUX_REG_MASK);
-	field = pin_mode & 0x3;
-	mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT;
-
-	spin_lock(&gpio_mux_lock);
-
-	l = __raw_readl(reg);
-	l &= ~(0xff << (field * 8));
-	l |= mode << (field * 8);
-	__raw_writel(l, reg);
-
-	spin_unlock(&gpio_mux_lock);
-
-	return ret;
-}
-EXPORT_SYMBOL(mxc_iomux_mode);
-
-/*
- * This function configures the pad value for a IOMUX pin.
- */
-void mxc_iomux_set_pad(enum iomux_pins pin, u32 config)
-{
-	u32 field, l;
-	void __iomem *reg;
-
-	pin &= IOMUX_PADNUM_MASK;
-	reg = IOMUXSW_PAD_CTL + (pin + 2) / 3 * 4;
-	field = (pin + 2) % 3;
-
-	pr_debug("%s: reg offset = 0x%x, field = %d\n",
-			__func__, (pin + 2) / 3, field);
-
-	spin_lock(&gpio_mux_lock);
-
-	l = __raw_readl(reg);
-	l &= ~(0x1ff << (field * 10));
-	l |= config << (field * 10);
-	__raw_writel(l, reg);
-
-	spin_unlock(&gpio_mux_lock);
-}
-EXPORT_SYMBOL(mxc_iomux_set_pad);
-
-/*
- * allocs a single pin:
- * 	- reserves the pin so that it is not claimed by another driver
- * 	- setups the iomux according to the configuration
- */
-int mxc_iomux_alloc_pin(const unsigned int pin, const char *label)
-{
-	unsigned pad = pin & IOMUX_PADNUM_MASK;
-
-	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 -EBUSY;
-	}
-	mxc_iomux_mode(pin);
-
-	return 0;
-}
-EXPORT_SYMBOL(mxc_iomux_alloc_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++) {
-		ret = mxc_iomux_alloc_pin(*p, label);
-		if (ret)
-			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;
-
-	if (pad < (PIN_MAX + 1))
-		clear_bit(pad, mxc_pin_alloc_map);
-}
-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.
- */
-void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en)
-{
-	u32 l;
-
-	spin_lock(&gpio_mux_lock);
-	l = __raw_readl(IOMUXGPR);
-	if (en)
-		l |= gp;
-	else
-		l &= ~gp;
-
-	__raw_writel(l, IOMUXGPR);
-	spin_unlock(&gpio_mux_lock);
-}
-EXPORT_SYMBOL(mxc_iomux_set_gpr);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/iomux-imx31.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/iomux-imx31.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/iomux-imx31.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/iomux-imx31.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,181 @@
+/*
+ * 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
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/iomux-mx3.h>
+
+/*
+ * IOMUX register (base) addresses
+ */
+#define IOMUX_BASE	MX31_IO_ADDRESS(MX31_IOMUXC_BASE_ADDR)
+#define IOMUXINT_OBS1	(IOMUX_BASE + 0x000)
+#define IOMUXINT_OBS2	(IOMUX_BASE + 0x004)
+#define IOMUXGPR	(IOMUX_BASE + 0x008)
+#define IOMUXSW_MUX_CTL	(IOMUX_BASE + 0x00C)
+#define IOMUXSW_PAD_CTL	(IOMUX_BASE + 0x154)
+
+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.
+ */
+int mxc_iomux_mode(unsigned int pin_mode)
+{
+	u32 field, l, mode, ret = 0;
+	void __iomem *reg;
+
+	reg = IOMUXSW_MUX_CTL + (pin_mode & IOMUX_REG_MASK);
+	field = pin_mode & 0x3;
+	mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT;
+
+	spin_lock(&gpio_mux_lock);
+
+	l = __raw_readl(reg);
+	l &= ~(0xff << (field * 8));
+	l |= mode << (field * 8);
+	__raw_writel(l, reg);
+
+	spin_unlock(&gpio_mux_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(mxc_iomux_mode);
+
+/*
+ * This function configures the pad value for a IOMUX pin.
+ */
+void mxc_iomux_set_pad(enum iomux_pins pin, u32 config)
+{
+	u32 field, l;
+	void __iomem *reg;
+
+	pin &= IOMUX_PADNUM_MASK;
+	reg = IOMUXSW_PAD_CTL + (pin + 2) / 3 * 4;
+	field = (pin + 2) % 3;
+
+	pr_debug("%s: reg offset = 0x%x, field = %d\n",
+			__func__, (pin + 2) / 3, field);
+
+	spin_lock(&gpio_mux_lock);
+
+	l = __raw_readl(reg);
+	l &= ~(0x1ff << (field * 10));
+	l |= config << (field * 10);
+	__raw_writel(l, reg);
+
+	spin_unlock(&gpio_mux_lock);
+}
+EXPORT_SYMBOL(mxc_iomux_set_pad);
+
+/*
+ * allocs a single pin:
+ * 	- reserves the pin so that it is not claimed by another driver
+ * 	- setups the iomux according to the configuration
+ */
+int mxc_iomux_alloc_pin(const unsigned int pin, const char *label)
+{
+	unsigned pad = pin & IOMUX_PADNUM_MASK;
+
+	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 -EBUSY;
+	}
+	mxc_iomux_mode(pin);
+
+	return 0;
+}
+EXPORT_SYMBOL(mxc_iomux_alloc_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++) {
+		ret = mxc_iomux_alloc_pin(*p, label);
+		if (ret)
+			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;
+
+	if (pad < (PIN_MAX + 1))
+		clear_bit(pad, mxc_pin_alloc_map);
+}
+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.
+ */
+void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en)
+{
+	u32 l;
+
+	spin_lock(&gpio_mux_lock);
+	l = __raw_readl(IOMUXGPR);
+	if (en)
+		l |= gp;
+	else
+		l &= ~gp;
+
+	__raw_writel(l, IOMUXGPR);
+	spin_unlock(&gpio_mux_lock);
+}
+EXPORT_SYMBOL(mxc_iomux_set_gpr);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@ config MACH_MX31ADS_WM1133_EV1
 config MACH_PCM037
 	bool "Support Phytec pcm037 (i.MX31) platforms"
 	select ARCH_MX31
+	select MXC_ULPI if USB_ULPI
 	help
 	  Include support for Phytec pcm037 platform. This includes
 	  specific configurations for the board and its peripherals.
@@ -61,6 +62,15 @@ config MACH_MX31_3DS
 	  Include support for MX31PDK (3DS) platform. This includes specific
 	  configurations for the board and its peripherals.
 
+config MACH_MX31_3DS_MXC_NAND_USE_BBT
+	bool "Make the MXC NAND driver use the in flash Bad Block Table"
+	depends on MACH_MX31_3DS
+	depends on MTD_NAND_MXC
+	help
+	  Enable this if you want that the MXC NAND driver uses the in flash
+	  Bad Block Table to know what blocks are bad instead of scanning the
+	  entire flash looking for bad block markers.
+
 config MACH_MX31MOBOARD
 	bool "Support mx31moboard platforms (EPFL Mobots group)"
 	select ARCH_MX31
@@ -86,6 +96,7 @@ config MACH_QONG
 config MACH_PCM043
 	bool "Support Phytec pcm043 (i.MX35) platforms"
 	select ARCH_MX35
+	select MXC_ULPI if USB_ULPI
 	help
 	  Include support for Phytec pcm043 platform. This includes
 	  specific configurations for the board and its peripherals.
@@ -93,6 +104,7 @@ config MACH_PCM043
 config MACH_ARMADILLO5X0
 	bool "Support Atmark Armadillo-500 Development Base Board"
 	select ARCH_MX31
+	select MXC_ULPI if USB_ULPI
 	help
 	  Include support for Atmark Armadillo-500 platform. This includes
 	  specific configurations for the board and its peripherals.
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/kzmarm11.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/kzmarm11.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/kzmarm11.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/kzmarm11.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,268 +0,0 @@
-/*
- * KZM-ARM11-01 support
- *  Copyright (C) 2009  Yoichi Yuasa <yuasa@linux-mips.org>
- *
- * based on code for MX31ADS,
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
- *  Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/serial_8250.h>
-#include <linux/smsc911x.h>
-#include <linux/types.h>
-
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-#include <asm/setup.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/map.h>
-#include <asm/mach/time.h>
-
-#include <mach/board-kzmarm11.h>
-#include <mach/clock.h>
-#include <mach/common.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux-mx3.h>
-#include <mach/memory.h>
-
-#include "devices.h"
-
-#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
-/*
- * KZM-ARM11-01 has an external UART on FPGA
- */
-static struct plat_serial8250_port serial_platform_data[] = {
-	{
-		.membase	= IO_ADDRESS(KZM_ARM11_16550),
-		.mapbase	= KZM_ARM11_16550,
-		.irq		= IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
-		.irqflags	= IRQ_TYPE_EDGE_RISING,
-		.uartclk	= 14745600,
-		.regshift	= 0,
-		.iotype		= UPIO_MEM,
-		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
-				  UPF_BUGGY_UART,
-	},
-	{},
-};
-
-static struct resource serial8250_resources[] = {
-	{
-		.start	= KZM_ARM11_16550,
-		.end	= KZM_ARM11_16550 + 0x10,
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.start	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
-		.end	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device serial_device = {
-	.name		= "serial8250",
-	.id		= PLAT8250_DEV_PLATFORM,
-	.dev		= {
-				.platform_data = serial_platform_data,
-			  },
-	.num_resources	= ARRAY_SIZE(serial8250_resources),
-	.resource	= serial8250_resources,
-};
-
-static int __init kzm_init_ext_uart(void)
-{
-	u8 tmp;
-
-	/*
-	 * GPIO 1-1: external UART interrupt line
-	 */
-	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO));
-	gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1), "ext-uart-int");
-	gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1));
-
-	/*
-	 * Unmask UART interrupt
-	 */
-	tmp = __raw_readb(IO_ADDRESS(KZM_ARM11_CTL1));
-	tmp |= 0x2;
-	__raw_writeb(tmp, IO_ADDRESS(KZM_ARM11_CTL1));
-
-	return platform_device_register(&serial_device);
-}
-#else
-static inline int kzm_init_ext_uart(void)
-{
-	return 0;
-}
-#endif
-
-/*
- * SMSC LAN9118
- */
-#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
-static struct smsc911x_platform_config kzm_smsc9118_config = {
-	.phy_interface	= PHY_INTERFACE_MODE_MII,
-	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
-	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
-	.flags		= SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
-};
-
-static struct resource kzm_smsc9118_resources[] = {
-	{
-		.start	= CS5_BASE_ADDR,
-		.end	= CS5_BASE_ADDR + SZ_128K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.start	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_2),
-		.end	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_2),
-		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
-	},
-};
-
-static struct platform_device kzm_smsc9118_device = {
-	.name		= "smsc911x",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(kzm_smsc9118_resources),
-	.resource	= kzm_smsc9118_resources,
-	.dev		= {
-				.platform_data = &kzm_smsc9118_config,
-			  },
-};
-
-static int __init kzm_init_smsc9118(void)
-{
-	/*
-	 * GPIO 1-2: SMSC9118 interrupt line
-	 */
-	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_2, IOMUX_CONFIG_GPIO));
-	gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2), "smsc9118-int");
-	gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2));
-
-	return platform_device_register(&kzm_smsc9118_device);
-}
-#else
-static inline int kzm_init_smsc9118(void)
-{
-	return 0;
-}
-#endif
-
-#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
-static struct imxuart_platform_data uart_pdata = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static void __init kzm_init_imx_uart(void)
-{
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-
-	mxc_register_device(&mxc_uart_device1, &uart_pdata);
-}
-#else
-static inline void kzm_init_imx_uart(void)
-{
-}
-#endif
-
-static int kzm_pins[] __initdata = {
-	MX31_PIN_CTS1__CTS1,
-	MX31_PIN_RTS1__RTS1,
-	MX31_PIN_TXD1__TXD1,
-	MX31_PIN_RXD1__RXD1,
-	MX31_PIN_DCD_DCE1__DCD_DCE1,
-	MX31_PIN_RI_DCE1__RI_DCE1,
-	MX31_PIN_DSR_DCE1__DSR_DCE1,
-	MX31_PIN_DTR_DCE1__DTR_DCE1,
-	MX31_PIN_CTS2__CTS2,
-	MX31_PIN_RTS2__RTS2,
-	MX31_PIN_TXD2__TXD2,
-	MX31_PIN_RXD2__RXD2,
-	MX31_PIN_DCD_DTE1__DCD_DTE2,
-	MX31_PIN_RI_DTE1__RI_DTE2,
-	MX31_PIN_DSR_DTE1__DSR_DTE2,
-	MX31_PIN_DTR_DTE1__DTR_DTE2,
-};
-
-/*
- * Board specific initialization.
- */
-static void __init kzm_board_init(void)
-{
-	mxc_iomux_setup_multiple_pins(kzm_pins,
-				      ARRAY_SIZE(kzm_pins), "kzm");
-	kzm_init_ext_uart();
-	kzm_init_smsc9118();
-	kzm_init_imx_uart();
-
-	pr_info("Clock input source is 26MHz\n");
-}
-
-/*
- * This structure defines static mappings for the kzm-arm11-01 board.
- */
-static struct map_desc kzm_io_desc[] __initdata = {
-	{
-		.virtual	= CS4_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(CS4_BASE_ADDR),
-		.length		= CS4_SIZE,
-		.type		= MT_DEVICE
-	},
-	{
-		.virtual	= CS5_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(CS5_BASE_ADDR),
-		.length		= CS5_SIZE,
-		.type		= MT_DEVICE
-	},
-};
-
-/*
- * Set up static virtual mappings.
- */
-static void __init kzm_map_io(void)
-{
-	mx31_map_io();
-	iotable_init(kzm_io_desc, ARRAY_SIZE(kzm_io_desc));
-}
-
-static void __init kzm_timer_init(void)
-{
-	mx31_clocks_init(26000000);
-}
-
-static struct sys_timer kzm_timer = {
-	.init   = kzm_timer_init,
-};
-
-/*
- * The following uses standard kernel macros define in arch.h in order to
- * initialize __mach_desc_KZM_ARM11_01 data structure.
- */
-MACHINE_START(KZM_ARM11_01, "Kyoto Microcomputer Co., Ltd. KZM-ARM11-01")
-	.phys_io        = AIPS1_BASE_ADDR,
-	.io_pg_offst    = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = kzm_map_io,
-	.init_irq       = mx31_init_irq,
-	.init_machine   = kzm_board_init,
-	.timer          = &kzm_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-armadillo5x0.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-armadillo5x0.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-armadillo5x0.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-armadillo5x0.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,582 @@
+/*
+ * armadillo5x0.c
+ *
+ * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * updates in http://alberdroid.blogspot.com/
+ *
+ * Based on Atmark Techno, Inc. armadillo 500 BSP 2008
+ * Based on mx31ads.c and pcm037.c Great Work!
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/types.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/i2c.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/memory.h>
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+#include <mach/board-armadillo5x0.h>
+#include <mach/mmc.h>
+#include <mach/ipu.h>
+#include <mach/mx3fb.h>
+#include <mach/mxc_nand.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
+
+#include "devices.h"
+#include "crm_regs.h"
+
+static int armadillo5x0_pins[] = {
+	/* UART1 */
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1,
+	/* UART2 */
+	MX31_PIN_CTS2__CTS2,
+	MX31_PIN_RTS2__RTS2,
+	MX31_PIN_TXD2__TXD2,
+	MX31_PIN_RXD2__RXD2,
+	/* LAN9118_IRQ */
+	IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO),
+	/* SDHC1 */
+	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,
+	/* Framebuffer */
+	MX31_PIN_LD0__LD0,
+	MX31_PIN_LD1__LD1,
+	MX31_PIN_LD2__LD2,
+	MX31_PIN_LD3__LD3,
+	MX31_PIN_LD4__LD4,
+	MX31_PIN_LD5__LD5,
+	MX31_PIN_LD6__LD6,
+	MX31_PIN_LD7__LD7,
+	MX31_PIN_LD8__LD8,
+	MX31_PIN_LD9__LD9,
+	MX31_PIN_LD10__LD10,
+	MX31_PIN_LD11__LD11,
+	MX31_PIN_LD12__LD12,
+	MX31_PIN_LD13__LD13,
+	MX31_PIN_LD14__LD14,
+	MX31_PIN_LD15__LD15,
+	MX31_PIN_LD16__LD16,
+	MX31_PIN_LD17__LD17,
+	MX31_PIN_VSYNC3__VSYNC3,
+	MX31_PIN_HSYNC__HSYNC,
+	MX31_PIN_FPSHIFT__FPSHIFT,
+	MX31_PIN_DRDY0__DRDY0,
+	IOMUX_MODE(MX31_PIN_LCS1, IOMUX_CONFIG_GPIO), /*ADV7125_PSAVE*/
+	/* I2C2 */
+	MX31_PIN_CSPI2_MOSI__SCL,
+	MX31_PIN_CSPI2_MISO__SDA,
+	/* OTG */
+	MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+	MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+	MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+	MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+	MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+	MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+	MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+	MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+	MX31_PIN_USBOTG_CLK__USBOTG_CLK,
+	MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+	MX31_PIN_USBOTG_NXT__USBOTG_NXT,
+	MX31_PIN_USBOTG_STP__USBOTG_STP,
+	/* USB host 2 */
+	IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC),
+};
+
+/* USB */
+#if defined(CONFIG_USB_ULPI)
+
+#define OTG_RESET IOMUX_TO_GPIO(MX31_PIN_STXD4)
+#define USBH2_RESET IOMUX_TO_GPIO(MX31_PIN_SCK6)
+#define USBH2_CS IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int usbotg_init(struct platform_device *pdev)
+{
+	int err;
+
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
+
+	/* Chip already enabled by hardware */
+	/* OTG phy reset*/
+	err = gpio_request(OTG_RESET, "USB-OTG-RESET");
+	if (err) {
+		pr_err("Failed to request the usb otg reset gpio\n");
+		return err;
+	}
+
+	err = gpio_direction_output(OTG_RESET, 1/*HIGH*/);
+	if (err) {
+		pr_err("Failed to reset the usb otg phy\n");
+		goto otg_free_reset;
+	}
+
+	gpio_set_value(OTG_RESET, 0/*LOW*/);
+	mdelay(5);
+	gpio_set_value(OTG_RESET, 1/*HIGH*/);
+
+	return 0;
+
+otg_free_reset:
+	gpio_free(OTG_RESET);
+	return err;
+}
+
+static int usbh2_init(struct platform_device *pdev)
+{
+	int err;
+
+	mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+	mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+
+	/* Enable the chip */
+	err = gpio_request(USBH2_CS, "USB-H2-CS");
+	if (err) {
+		pr_err("Failed to request the usb host 2 CS gpio\n");
+		return err;
+	}
+
+	err = gpio_direction_output(USBH2_CS, 0/*Enabled*/);
+	if (err) {
+		pr_err("Failed to drive the usb host 2 CS gpio\n");
+		goto h2_free_cs;
+	}
+
+	/* H2 phy reset*/
+	err = gpio_request(USBH2_RESET, "USB-H2-RESET");
+	if (err) {
+		pr_err("Failed to request the usb host 2 reset gpio\n");
+		goto h2_free_cs;
+	}
+
+	err = gpio_direction_output(USBH2_RESET, 1/*HIGH*/);
+	if (err) {
+		pr_err("Failed to reset the usb host 2 phy\n");
+		goto h2_free_reset;
+	}
+
+	gpio_set_value(USBH2_RESET, 0/*LOW*/);
+	mdelay(5);
+	gpio_set_value(USBH2_RESET, 1/*HIGH*/);
+
+	return 0;
+
+h2_free_reset:
+	gpio_free(USBH2_RESET);
+h2_free_cs:
+	gpio_free(USBH2_CS);
+	return err;
+}
+
+static struct mxc_usbh_platform_data usbotg_pdata = {
+	.init	= usbotg_init,
+	.portsc	= MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+	.flags	= MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+	.init	= usbh2_init,
+	.portsc	= MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+	.flags	= MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+#endif /* CONFIG_USB_ULPI */
+
+/* RTC over I2C*/
+#define ARMADILLO5X0_RTC_GPIO	IOMUX_TO_GPIO(MX31_PIN_SRXD4)
+
+static struct i2c_board_info armadillo5x0_i2c_rtc = {
+	I2C_BOARD_INFO("s35390a", 0x30),
+};
+
+/* GPIO BUTTONS */
+static struct gpio_keys_button armadillo5x0_buttons[] = {
+	{
+		.code		= KEY_ENTER, /*28*/
+		.gpio		= IOMUX_TO_GPIO(MX31_PIN_SCLK0),
+		.active_low	= 1,
+		.desc		= "menu",
+		.wakeup		= 1,
+	}, {
+		.code		= KEY_BACK, /*158*/
+		.gpio		= IOMUX_TO_GPIO(MX31_PIN_SRST0),
+		.active_low	= 1,
+		.desc		= "back",
+		.wakeup		= 1,
+	}
+};
+
+static struct gpio_keys_platform_data armadillo5x0_button_data = {
+	.buttons	= armadillo5x0_buttons,
+	.nbuttons	= ARRAY_SIZE(armadillo5x0_buttons),
+};
+
+static struct platform_device armadillo5x0_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= {
+		.platform_data	= &armadillo5x0_button_data,
+	}
+};
+
+/*
+ * NAND Flash
+ */
+static struct mxc_nand_platform_data armadillo5x0_nand_flash_pdata = {
+	.width		= 1,
+	.hw_ecc		= 1,
+};
+
+/*
+ * MTD NOR Flash
+ */
+static struct mtd_partition armadillo5x0_nor_flash_partitions[] = {
+	{
+		.name		= "nor.bootloader",
+		.offset		= 0x00000000,
+		.size		= 4*32*1024,
+	}, {
+		.name		= "nor.kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 16*128*1024,
+	}, {
+		.name		= "nor.userland",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 110*128*1024,
+	}, {
+		.name		= "nor.config",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 1*128*1024,
+	},
+};
+
+static struct physmap_flash_data armadillo5x0_nor_flash_pdata = {
+	.width		= 2,
+	.parts		= armadillo5x0_nor_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(armadillo5x0_nor_flash_partitions),
+};
+
+static struct resource armadillo5x0_nor_flash_resource = {
+	.flags		= IORESOURCE_MEM,
+	.start		= MX31_CS0_BASE_ADDR,
+	.end		= MX31_CS0_BASE_ADDR + SZ_64M - 1,
+};
+
+static struct platform_device armadillo5x0_nor_flash = {
+	.name			= "physmap-flash",
+	.id			= -1,
+	.num_resources		= 1,
+	.resource		= &armadillo5x0_nor_flash_resource,
+};
+
+/*
+ * FB support
+ */
+static const struct fb_videomode fb_modedb[] = {
+	{	/* 640x480 @ 60 Hz */
+		.name		= "CRT-VGA",
+		.refresh	= 60,
+		.xres		= 640,
+		.yres		= 480,
+		.pixclock	= 39721,
+		.left_margin	= 35,
+		.right_margin	= 115,
+		.upper_margin	= 43,
+		.lower_margin	= 1,
+		.hsync_len	= 10,
+		.vsync_len	= 1,
+		.sync		= FB_SYNC_OE_ACT_HIGH,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.flag		= 0,
+	}, {/* 800x600 @ 56 Hz */
+		.name		= "CRT-SVGA",
+		.refresh	= 56,
+		.xres		= 800,
+		.yres		= 600,
+		.pixclock	= 30000,
+		.left_margin	= 30,
+		.right_margin	= 108,
+		.upper_margin	= 13,
+		.lower_margin	= 10,
+		.hsync_len	= 10,
+		.vsync_len	= 1,
+		.sync		= FB_SYNC_OE_ACT_HIGH | FB_SYNC_HOR_HIGH_ACT |
+				  FB_SYNC_VERT_HIGH_ACT,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.flag		= 0,
+	},
+};
+
+static struct ipu_platform_data mx3_ipu_data = {
+	.irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct mx3fb_platform_data mx3fb_pdata = {
+	.dma_dev	= &mx3_ipu.dev,
+	.name		= "CRT-VGA",
+	.mode		= fb_modedb,
+	.num_modes	= ARRAY_SIZE(fb_modedb),
+};
+
+/*
+ * SDHC 1
+ * MMC support
+ */
+static int armadillo5x0_sdhc1_get_ro(struct device *dev)
+{
+	return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B));
+}
+
+static int armadillo5x0_sdhc1_init(struct device *dev,
+				   irq_handler_t detect_irq, void *data)
+{
+	int ret;
+	int gpio_det, gpio_wp;
+
+	gpio_det = IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK);
+	gpio_wp = IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B);
+
+	ret = gpio_request(gpio_det, "sdhc-card-detect");
+	if (ret)
+		return ret;
+
+	gpio_direction_input(gpio_det);
+
+	ret = gpio_request(gpio_wp, "sdhc-write-protect");
+	if (ret)
+		goto err_gpio_free;
+
+	gpio_direction_input(gpio_wp);
+
+	/* When supported the trigger type have to be BOTH */
+	ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), detect_irq,
+			  IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+			  "sdhc-detect", data);
+
+	if (ret)
+		goto err_gpio_free_2;
+
+	return 0;
+
+err_gpio_free_2:
+	gpio_free(gpio_wp);
+
+err_gpio_free:
+	gpio_free(gpio_det);
+
+	return ret;
+
+}
+
+static void armadillo5x0_sdhc1_exit(struct device *dev, void *data)
+{
+	free_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), data);
+	gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK));
+	gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B));
+}
+
+static struct imxmmc_platform_data sdhc_pdata = {
+	.get_ro = armadillo5x0_sdhc1_get_ro,
+	.init = armadillo5x0_sdhc1_init,
+	.exit = armadillo5x0_sdhc1_exit,
+};
+
+/*
+ * SMSC 9118
+ * Network support
+ */
+static struct resource armadillo5x0_smc911x_resources[] = {
+	{
+		.start	= MX31_CS3_BASE_ADDR,
+		.end	= MX31_CS3_BASE_ADDR + SZ_32M - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+		.end	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+	},
+};
+
+static struct smsc911x_platform_config smsc911x_info = {
+	.flags		= SMSC911X_USE_16BIT,
+	.irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device armadillo5x0_smc911x_device = {
+	.name           = "smsc911x",
+	.id             = -1,
+	.num_resources  = ARRAY_SIZE(armadillo5x0_smc911x_resources),
+	.resource       = armadillo5x0_smc911x_resources,
+	.dev            = {
+		.platform_data = &smsc911x_info,
+	},
+};
+
+/* UART device data */
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&armadillo5x0_smc911x_device,
+	&mxc_i2c_device1,
+	&armadillo5x0_button_device,
+};
+
+/*
+ * Perform board specific initializations
+ */
+static void __init armadillo5x0_init(void)
+{
+	mxc_iomux_setup_multiple_pins(armadillo5x0_pins,
+			ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0");
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	/* Register UART */
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+	mxc_register_device(&mxc_uart_device1, &uart_pdata);
+
+	/* SMSC9118 IRQ pin */
+	gpio_direction_input(MX31_PIN_GPIO1_0);
+
+	/* Register SDHC */
+	mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
+
+	/* Register FB */
+	mxc_register_device(&mx3_ipu, &mx3_ipu_data);
+	mxc_register_device(&mx3_fb, &mx3fb_pdata);
+
+	/* Register NOR Flash */
+	mxc_register_device(&armadillo5x0_nor_flash,
+			    &armadillo5x0_nor_flash_pdata);
+
+	/* Register NAND Flash */
+	mxc_register_device(&mxc_nand_device, &armadillo5x0_nand_flash_pdata);
+
+	/* set NAND page size to 2k if not configured via boot mode pins */
+	__raw_writel(__raw_readl(MXC_CCM_RCSR) | (1 << 30), MXC_CCM_RCSR);
+
+	/* RTC */
+	/* Get RTC IRQ and register the chip */
+	if (gpio_request(ARMADILLO5X0_RTC_GPIO, "rtc") == 0) {
+		if (gpio_direction_input(ARMADILLO5X0_RTC_GPIO) == 0)
+			armadillo5x0_i2c_rtc.irq = gpio_to_irq(ARMADILLO5X0_RTC_GPIO);
+		else
+			gpio_free(ARMADILLO5X0_RTC_GPIO);
+	}
+	if (armadillo5x0_i2c_rtc.irq == 0)
+		pr_warning("armadillo5x0_init: failed to get RTC IRQ\n");
+	i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1);
+
+	/* USB */
+#if defined(CONFIG_USB_ULPI)
+	usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+			USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+	usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+			USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+	mxc_register_device(&mxc_otg_host, &usbotg_pdata);
+	mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+#endif
+}
+
+static void __init armadillo5x0_timer_init(void)
+{
+	mx31_clocks_init(26000000);
+}
+
+static struct sys_timer armadillo5x0_timer = {
+	.init	= armadillo5x0_timer_init,
+};
+
+MACHINE_START(ARMADILLO5X0, "Armadillo-500")
+	/* Maintainer: Alberto Panizzo  */
+	.phys_io	= MX31_AIPS1_BASE_ADDR,
+	.io_pg_offst	= (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+	.boot_params	= MX3x_PHYS_OFFSET + 0x100,
+	.map_io		= mx31_map_io,
+	.init_irq	= mx31_init_irq,
+	.timer		= &armadillo5x0_timer,
+	.init_machine	= armadillo5x0_init,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-kzm_arm11_01.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-kzm_arm11_01.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-kzm_arm11_01.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-kzm_arm11_01.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,273 @@
+/*
+ * KZM-ARM11-01 support
+ *  Copyright (C) 2009  Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * based on code for MX31ADS,
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/smsc911x.h>
+#include <linux/types.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <mach/board-kzmarm11.h>
+#include <mach/clock.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+#include <mach/memory.h>
+
+#include "devices.h"
+
+#define KZM_ARM11_IO_ADDRESS(x) (					\
+	IMX_IO_ADDRESS(x, MX31_CS4) ?:					\
+	IMX_IO_ADDRESS(x, MX31_CS5) ?:					\
+	MX31_IO_ADDRESS(x))
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+/*
+ * KZM-ARM11-01 has an external UART on FPGA
+ */
+static struct plat_serial8250_port serial_platform_data[] = {
+	{
+		.membase	= KZM_ARM11_IO_ADDRESS(KZM_ARM11_16550),
+		.mapbase	= KZM_ARM11_16550,
+		.irq		= IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
+		.irqflags	= IRQ_TYPE_EDGE_RISING,
+		.uartclk	= 14745600,
+		.regshift	= 0,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+				  UPF_BUGGY_UART,
+	},
+	{},
+};
+
+static struct resource serial8250_resources[] = {
+	{
+		.start	= KZM_ARM11_16550,
+		.end	= KZM_ARM11_16550 + 0x10,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
+		.end	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device serial_device = {
+	.name		= "serial8250",
+	.id		= PLAT8250_DEV_PLATFORM,
+	.dev		= {
+				.platform_data = serial_platform_data,
+			  },
+	.num_resources	= ARRAY_SIZE(serial8250_resources),
+	.resource	= serial8250_resources,
+};
+
+static int __init kzm_init_ext_uart(void)
+{
+	u8 tmp;
+
+	/*
+	 * GPIO 1-1: external UART interrupt line
+	 */
+	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO));
+	gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1), "ext-uart-int");
+	gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1));
+
+	/*
+	 * Unmask UART interrupt
+	 */
+	tmp = __raw_readb(KZM_ARM11_IO_ADDRESS(KZM_ARM11_CTL1));
+	tmp |= 0x2;
+	__raw_writeb(tmp, KZM_ARM11_IO_ADDRESS(KZM_ARM11_CTL1));
+
+	return platform_device_register(&serial_device);
+}
+#else
+static inline int kzm_init_ext_uart(void)
+{
+	return 0;
+}
+#endif
+
+/*
+ * SMSC LAN9118
+ */
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+static struct smsc911x_platform_config kzm_smsc9118_config = {
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
+	.flags		= SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+};
+
+static struct resource kzm_smsc9118_resources[] = {
+	{
+		.start	= MX31_CS5_BASE_ADDR,
+		.end	= MX31_CS5_BASE_ADDR + SZ_128K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_2),
+		.end	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_2),
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+	},
+};
+
+static struct platform_device kzm_smsc9118_device = {
+	.name		= "smsc911x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(kzm_smsc9118_resources),
+	.resource	= kzm_smsc9118_resources,
+	.dev		= {
+				.platform_data = &kzm_smsc9118_config,
+			  },
+};
+
+static int __init kzm_init_smsc9118(void)
+{
+	/*
+	 * GPIO 1-2: SMSC9118 interrupt line
+	 */
+	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_2, IOMUX_CONFIG_GPIO));
+	gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2), "smsc9118-int");
+	gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2));
+
+	return platform_device_register(&kzm_smsc9118_device);
+}
+#else
+static inline int kzm_init_smsc9118(void)
+{
+	return 0;
+}
+#endif
+
+#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static void __init kzm_init_imx_uart(void)
+{
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+
+	mxc_register_device(&mxc_uart_device1, &uart_pdata);
+}
+#else
+static inline void kzm_init_imx_uart(void)
+{
+}
+#endif
+
+static int kzm_pins[] __initdata = {
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1,
+	MX31_PIN_DCD_DCE1__DCD_DCE1,
+	MX31_PIN_RI_DCE1__RI_DCE1,
+	MX31_PIN_DSR_DCE1__DSR_DCE1,
+	MX31_PIN_DTR_DCE1__DTR_DCE1,
+	MX31_PIN_CTS2__CTS2,
+	MX31_PIN_RTS2__RTS2,
+	MX31_PIN_TXD2__TXD2,
+	MX31_PIN_RXD2__RXD2,
+	MX31_PIN_DCD_DTE1__DCD_DTE2,
+	MX31_PIN_RI_DTE1__RI_DTE2,
+	MX31_PIN_DSR_DTE1__DSR_DTE2,
+	MX31_PIN_DTR_DTE1__DTR_DTE2,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init kzm_board_init(void)
+{
+	mxc_iomux_setup_multiple_pins(kzm_pins,
+				      ARRAY_SIZE(kzm_pins), "kzm");
+	kzm_init_ext_uart();
+	kzm_init_smsc9118();
+	kzm_init_imx_uart();
+
+	pr_info("Clock input source is 26MHz\n");
+}
+
+/*
+ * This structure defines static mappings for the kzm-arm11-01 board.
+ */
+static struct map_desc kzm_io_desc[] __initdata = {
+	{
+		.virtual	= MX31_CS4_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(MX31_CS4_BASE_ADDR),
+		.length		= MX31_CS4_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	= MX31_CS5_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(MX31_CS5_BASE_ADDR),
+		.length		= MX31_CS5_SIZE,
+		.type		= MT_DEVICE
+	},
+};
+
+/*
+ * Set up static virtual mappings.
+ */
+static void __init kzm_map_io(void)
+{
+	mx31_map_io();
+	iotable_init(kzm_io_desc, ARRAY_SIZE(kzm_io_desc));
+}
+
+static void __init kzm_timer_init(void)
+{
+	mx31_clocks_init(26000000);
+}
+
+static struct sys_timer kzm_timer = {
+	.init   = kzm_timer_init,
+};
+
+/*
+ * The following uses standard kernel macros define in arch.h in order to
+ * initialize __mach_desc_KZM_ARM11_01 data structure.
+ */
+MACHINE_START(KZM_ARM11_01, "Kyoto Microcomputer Co., Ltd. KZM-ARM11-01")
+	.phys_io        = MX31_AIPS1_BASE_ADDR,
+	.io_pg_offst    = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+	.boot_params    = MX3x_PHYS_OFFSET + 0x100,
+	.map_io         = kzm_map_io,
+	.init_irq       = mx31_init_irq,
+	.init_machine   = kzm_board_init,
+	.timer          = &kzm_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-mx31_3ds.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-mx31_3ds.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-mx31_3ds.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-mx31_3ds.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,344 @@
+/*
+ *  Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/machine.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/memory.h>
+#include <asm/mach/map.h>
+#include <mach/common.h>
+#include <mach/board-mx31_3ds.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+#include <mach/mxc_nand.h>
+#include <mach/spi.h>
+#include "devices.h"
+
+/*!
+ * @file mx31_3ds.c
+ *
+ * @brief This file contains the board-specific initialization routines.
+ *
+ * @ingroup System
+ */
+
+static int mx31_3ds_pins[] = {
+	/* UART1 */
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1,
+	IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO),
+	/* SPI 1 */
+	MX31_PIN_CSPI2_SCLK__SCLK,
+	MX31_PIN_CSPI2_MOSI__MOSI,
+	MX31_PIN_CSPI2_MISO__MISO,
+	MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
+	MX31_PIN_CSPI2_SS0__SS0,
+	MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */
+	/* MC13783 IRQ */
+	IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO),
+};
+
+/* Regulators */
+static struct regulator_init_data pwgtx_init = {
+	.constraints = {
+		.boot_on	= 1,
+		.always_on	= 1,
+	},
+};
+
+static struct mc13783_regulator_init_data mx31_3ds_regulators[] = {
+	{
+		.id = MC13783_REGU_PWGT1SPI, /* Power Gate for ARM core. */
+		.init_data = &pwgtx_init,
+	}, {
+		.id = MC13783_REGU_PWGT2SPI, /* Power Gate for L2 Cache. */
+		.init_data = &pwgtx_init,
+	},
+};
+
+/* MC13783 */
+static struct mc13783_platform_data mc13783_pdata __initdata = {
+	.regulators = mx31_3ds_regulators,
+	.num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
+	.flags  = MC13783_USE_REGULATOR,
+};
+
+/* SPI */
+static int spi1_internal_chipselect[] = {
+	MXC_SPI_CS(0),
+	MXC_SPI_CS(2),
+};
+
+static struct spi_imx_master spi1_pdata = {
+	.chipselect	= spi1_internal_chipselect,
+	.num_chipselect	= ARRAY_SIZE(spi1_internal_chipselect),
+};
+
+static struct spi_board_info mx31_3ds_spi_devs[] __initdata = {
+	{
+		.modalias	= "mc13783",
+		.max_speed_hz	= 1000000,
+		.bus_num	= 1,
+		.chip_select	= 1, /* SS2 */
+		.platform_data	= &mc13783_pdata,
+		.irq		= IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+		.mode = SPI_CS_HIGH,
+	},
+};
+
+/*
+ * NAND Flash
+ */
+static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = {
+	.width		= 1,
+	.hw_ecc		= 1,
+#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT
+	.flash_bbt	= 1,
+#endif
+};
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+/*
+ * Support for the SMSC9217 on the Debug board.
+ */
+
+static struct smsc911x_platform_config smsc911x_config = {
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
+	.flags		= SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
+};
+
+static struct resource smsc911x_resources[] = {
+	{
+		.start		= LAN9217_BASE_ADDR,
+		.end		= LAN9217_BASE_ADDR + 0xff,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= EXPIO_INT_ENET,
+		.end		= EXPIO_INT_ENET,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device smsc911x_device = {
+	.name		= "smsc911x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(smsc911x_resources),
+	.resource	= smsc911x_resources,
+	.dev		= {
+		.platform_data = &smsc911x_config,
+	},
+};
+
+/*
+ * Routines for the CPLD on the debug board. It contains a CPLD handling
+ * LEDs, switches, interrupts for Ethernet.
+ */
+
+static void mx31_3ds_expio_irq_handler(uint32_t irq, struct irq_desc *desc)
+{
+	uint32_t imr_val;
+	uint32_t int_valid;
+	uint32_t expio_irq;
+
+	imr_val = __raw_readw(CPLD_INT_MASK_REG);
+	int_valid = __raw_readw(CPLD_INT_STATUS_REG) & ~imr_val;
+
+	expio_irq = MXC_EXP_IO_BASE;
+	for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
+		if ((int_valid & 1) == 0)
+			continue;
+		generic_handle_irq(expio_irq);
+	}
+}
+
+/*
+ * Disable an expio pin's interrupt by setting the bit in the imr.
+ * @param irq           an expio virtual irq number
+ */
+static void expio_mask_irq(uint32_t irq)
+{
+	uint16_t reg;
+	uint32_t expio = MXC_IRQ_TO_EXPIO(irq);
+
+	/* mask the interrupt */
+	reg = __raw_readw(CPLD_INT_MASK_REG);
+	reg |= 1 << expio;
+	__raw_writew(reg, CPLD_INT_MASK_REG);
+}
+
+/*
+ * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
+ * @param irq           an expanded io virtual irq number
+ */
+static void expio_ack_irq(uint32_t irq)
+{
+	uint32_t expio = MXC_IRQ_TO_EXPIO(irq);
+
+	/* clear the interrupt status */
+	__raw_writew(1 << expio, CPLD_INT_RESET_REG);
+	__raw_writew(0, CPLD_INT_RESET_REG);
+	/* mask the interrupt */
+	expio_mask_irq(irq);
+}
+
+/*
+ * Enable a expio pin's interrupt by clearing the bit in the imr.
+ * @param irq           a expio virtual irq number
+ */
+static void expio_unmask_irq(uint32_t irq)
+{
+	uint16_t reg;
+	uint32_t expio = MXC_IRQ_TO_EXPIO(irq);
+
+	/* unmask the interrupt */
+	reg = __raw_readw(CPLD_INT_MASK_REG);
+	reg &= ~(1 << expio);
+	__raw_writew(reg, CPLD_INT_MASK_REG);
+}
+
+static struct irq_chip expio_irq_chip = {
+	.ack = expio_ack_irq,
+	.mask = expio_mask_irq,
+	.unmask = expio_unmask_irq,
+};
+
+static int __init mx31_3ds_init_expio(void)
+{
+	int i;
+	int ret;
+
+	/* Check if there's a debug board connected */
+	if ((__raw_readw(CPLD_MAGIC_NUMBER1_REG) != 0xAAAA) ||
+	    (__raw_readw(CPLD_MAGIC_NUMBER2_REG) != 0x5555) ||
+	    (__raw_readw(CPLD_MAGIC_NUMBER3_REG) != 0xCAFE)) {
+		/* No Debug board found */
+		return -ENODEV;
+	}
+
+	pr_info("i.MX31 3DS Debug board detected, rev = 0x%04X\n",
+		__raw_readw(CPLD_CODE_VER_REG));
+
+	/*
+	 * Configure INT line as GPIO input
+	 */
+	ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1), "sms9217-irq");
+	if (ret)
+		pr_warning("could not get LAN irq gpio\n");
+	else
+		gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1));
+
+	/* Disable the interrupts and clear the status */
+	__raw_writew(0, CPLD_INT_MASK_REG);
+	__raw_writew(0xFFFF, CPLD_INT_RESET_REG);
+	__raw_writew(0, CPLD_INT_RESET_REG);
+	__raw_writew(0x1F, CPLD_INT_MASK_REG);
+	for (i = MXC_EXP_IO_BASE;
+	     i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
+	     i++) {
+		set_irq_chip(i, &expio_irq_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+	set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW);
+	set_irq_chained_handler(EXPIO_PARENT_INT, mx31_3ds_expio_irq_handler);
+
+	return 0;
+}
+
+/*
+ * This structure defines the MX31 memory map.
+ */
+static struct map_desc mx31_3ds_io_desc[] __initdata = {
+	{
+		.virtual = MX31_CS5_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR),
+		.length = MX31_CS5_SIZE,
+		.type = MT_DEVICE,
+	},
+};
+
+/*
+ * Set up static virtual mappings.
+ */
+static void __init mx31_3ds_map_io(void)
+{
+	mx31_map_io();
+	iotable_init(mx31_3ds_io_desc, ARRAY_SIZE(mx31_3ds_io_desc));
+}
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+	mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins),
+				      "mx31_3ds");
+
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+	mxc_register_device(&mxc_nand_device, &imx31_3ds_nand_flash_pdata);
+
+	mxc_register_device(&mxc_spi_device1, &spi1_pdata);
+	spi_register_board_info(mx31_3ds_spi_devs,
+						ARRAY_SIZE(mx31_3ds_spi_devs));
+
+	if (!mx31_3ds_init_expio())
+		platform_device_register(&smsc911x_device);
+}
+
+static void __init mx31_3ds_timer_init(void)
+{
+	mx31_clocks_init(26000000);
+}
+
+static struct sys_timer mx31_3ds_timer = {
+	.init	= mx31_3ds_timer_init,
+};
+
+/*
+ * The following uses standard kernel macros defined in arch.h in order to
+ * initialize __mach_desc_MX31_3DS data structure.
+ */
+MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
+	/* Maintainer: Freescale Semiconductor, Inc. */
+	.phys_io	= MX31_AIPS1_BASE_ADDR,
+	.io_pg_offst	= (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+	.boot_params    = MX3x_PHYS_OFFSET + 0x100,
+	.map_io         = mx31_3ds_map_io,
+	.init_irq       = mx31_init_irq,
+	.init_machine   = mxc_board_init,
+	.timer          = &mx31_3ds_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-mx31ads.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-mx31ads.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-mx31ads.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-mx31ads.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,559 @@
+/*
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#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>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/memory.h>
+#include <asm/mach/map.h>
+#include <mach/common.h>
+#include <mach/board-mx31ads.h>
+#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"
+
+/*!
+ * @file mx31ads.c
+ *
+ * @brief This file contains the board-specific initialization routines.
+ *
+ * @ingroup System
+ */
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+/*!
+ * The serial port definition structure.
+ */
+static struct plat_serial8250_port serial_platform_data[] = {
+	{
+		.membase  = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA),
+		.mapbase  = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTA),
+		.irq      = EXPIO_INT_XUART_INTA,
+		.uartclk  = 14745600,
+		.regshift = 0,
+		.iotype   = UPIO_MEM,
+		.flags    = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
+	}, {
+		.membase  = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB),
+		.mapbase  = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTB),
+		.irq      = EXPIO_INT_XUART_INTB,
+		.uartclk  = 14745600,
+		.regshift = 0,
+		.iotype   = UPIO_MEM,
+		.flags    = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
+	},
+	{},
+};
+
+static struct platform_device serial_device = {
+	.name	= "serial8250",
+	.id	= 0,
+	.dev	= {
+		.platform_data = serial_platform_data,
+	},
+};
+
+static int __init mxc_init_extuart(void)
+{
+	return platform_device_register(&serial_device);
+}
+#else
+static inline int mxc_init_extuart(void)
+{
+	return 0;
+}
+#endif
+
+#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static 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_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0");
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+}
+#else /* !SERIAL_IMX */
+static inline void mxc_init_imx_uart(void)
+{
+}
+#endif /* !SERIAL_IMX */
+
+static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+	u32 imr_val;
+	u32 int_valid;
+	u32 expio_irq;
+
+	imr_val = __raw_readw(PBC_INTMASK_SET_REG);
+	int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val;
+
+	expio_irq = MXC_EXP_IO_BASE;
+	for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
+		if ((int_valid & 1) == 0)
+			continue;
+
+		generic_handle_irq(expio_irq);
+	}
+}
+
+/*
+ * Disable an expio pin's interrupt by setting the bit in the imr.
+ * @param irq           an expio virtual irq number
+ */
+static void expio_mask_irq(u32 irq)
+{
+	u32 expio = MXC_IRQ_TO_EXPIO(irq);
+	/* mask the interrupt */
+	__raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG);
+	__raw_readw(PBC_INTMASK_CLEAR_REG);
+}
+
+/*
+ * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
+ * @param irq           an expanded io virtual irq number
+ */
+static void expio_ack_irq(u32 irq)
+{
+	u32 expio = MXC_IRQ_TO_EXPIO(irq);
+	/* clear the interrupt status */
+	__raw_writew(1 << expio, PBC_INTSTATUS_REG);
+}
+
+/*
+ * Enable a expio pin's interrupt by clearing the bit in the imr.
+ * @param irq           a expio virtual irq number
+ */
+static void expio_unmask_irq(u32 irq)
+{
+	u32 expio = MXC_IRQ_TO_EXPIO(irq);
+	/* unmask the interrupt */
+	__raw_writew(1 << expio, PBC_INTMASK_SET_REG);
+}
+
+static struct irq_chip expio_irq_chip = {
+	.name = "EXPIO(CPLD)",
+	.ack = expio_ack_irq,
+	.mask = expio_mask_irq,
+	.unmask = expio_unmask_irq,
+};
+
+static void __init mx31ads_init_expio(void)
+{
+	int i;
+
+	printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n");
+
+	/*
+	 * Configure INT line as GPIO input
+	 */
+	mxc_iomux_alloc_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);
+	__raw_writew(0xFFFF, PBC_INTSTATUS_REG);
+	for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
+	     i++) {
+		set_irq_chip(i, &expio_irq_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+	set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH);
+	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,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		.apply_uV = 1,
+	},
+};
+
+static struct regulator_consumer_supply ldo2_consumers[] = {
+	{ .supply = "AVDD", .dev_name = "1-001a" },
+	{ .supply = "HPVDD", .dev_name = "1-001a" },
+};
+
+/* 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,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		.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)
+{
+	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);
+
+	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,
+	.irq_base = MXC_BOARD_IRQ_START + MXC_MAX_EXP_IO_LINES,
+};
+#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
+
+static unsigned int ssi_pins[] = {
+	MX31_PIN_SFS5__SFS5,
+	MX31_PIN_SCK5__SCK5,
+	MX31_PIN_SRXD5__SRXD5,
+	MX31_PIN_STXD5__STXD5,
+};
+
+static void mxc_init_audio(void)
+{
+	mxc_register_device(&imx_ssi_device0, NULL);
+	mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi");
+}
+
+/*!
+ * This structure defines static mappings for the i.MX31ADS board.
+ */
+static struct map_desc mx31ads_io_desc[] __initdata = {
+	{
+		.virtual	= MX31_CS4_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(MX31_CS4_BASE_ADDR),
+		.length		= MX31_CS4_SIZE / 2,
+		.type		= MT_DEVICE
+	},
+};
+
+/*!
+ * Set up static virtual mappings.
+ */
+static void __init mx31ads_map_io(void)
+{
+	mx31_map_io();
+	iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc));
+}
+
+static void __init mx31ads_init_irq(void)
+{
+	mx31_init_irq();
+	mx31ads_init_expio();
+}
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+	mxc_init_extuart();
+	mxc_init_imx_uart();
+	mxc_init_i2c();
+	mxc_init_audio();
+}
+
+static void __init mx31ads_timer_init(void)
+{
+	mx31_clocks_init(26000000);
+}
+
+static struct sys_timer mx31ads_timer = {
+	.init	= mx31ads_timer_init,
+};
+
+/*
+ * The following uses standard kernel macros defined in arch.h in order to
+ * initialize __mach_desc_MX31ADS data structure.
+ */
+MACHINE_START(MX31ADS, "Freescale MX31ADS")
+	/* Maintainer: Freescale Semiconductor, Inc. */
+	.phys_io	= MX31_AIPS1_BASE_ADDR,
+	.io_pg_offst	= (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+	.boot_params    = MX3x_PHYS_OFFSET + 0x100,
+	.map_io         = mx31ads_map_io,
+	.init_irq       = mx31ads_init_irq,
+	.init_machine   = mxc_board_init,
+	.timer          = &mx31ads_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-mx31lilly.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-mx31lilly.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-mx31lilly.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-mx31lilly.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,206 @@
+/*
+ *  LILLY-1131 module support
+ *
+ *    Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ *  based on code for other MX31 boards,
+ *
+ *    Copyright 2005-2007 Freescale Semiconductor
+ *    Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ *    Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/smsc911x.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/mfd/mc13783.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+#include <mach/board-mx31lilly.h>
+#include <mach/spi.h>
+
+#include "devices.h"
+
+/*
+ * This file contains module-specific initialization routines for LILLY-1131.
+ * Initialization of peripherals found on the baseboard is implemented in the
+ * appropriate baseboard support code.
+ */
+
+/* SMSC ethernet support */
+
+static struct resource smsc91x_resources[] = {
+	{
+		.start	= MX31_CS4_BASE_ADDR,
+		.end	= MX31_CS4_BASE_ADDR + 0xffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+		.end	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
+	}
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.flags		= SMSC911X_USE_32BIT |
+			  SMSC911X_SAVE_MAC_ADDRESS |
+			  SMSC911X_FORCE_INTERNAL_PHY,
+};
+
+static struct platform_device smsc91x_device = {
+	.name		= "smsc911x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(smsc91x_resources),
+	.resource	= smsc91x_resources,
+	.dev		= {
+		.platform_data = &smsc911x_config,
+	}
+};
+
+/* NOR flash */
+static struct physmap_flash_data nor_flash_data = {
+	.width  = 2,
+};
+
+static struct resource nor_flash_resource = {
+	.start	= 0xa0000000,
+	.end	= 0xa1ffffff,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device physmap_flash_device = {
+	.name	= "physmap-flash",
+	.id	= 0,
+	.dev	= {
+		.platform_data  = &nor_flash_data,
+	},
+	.resource = &nor_flash_resource,
+	.num_resources = 1,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&smsc91x_device,
+	&physmap_flash_device,
+};
+
+/* SPI */
+
+static int spi_internal_chipselect[] = {
+	MXC_SPI_CS(0),
+	MXC_SPI_CS(1),
+	MXC_SPI_CS(2),
+};
+
+static struct spi_imx_master spi0_pdata = {
+	.chipselect = spi_internal_chipselect,
+	.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
+};
+
+static struct spi_imx_master spi1_pdata = {
+	.chipselect = spi_internal_chipselect,
+	.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
+};
+
+static struct mc13783_platform_data mc13783_pdata __initdata = {
+	.flags = MC13783_USE_RTC | MC13783_USE_TOUCHSCREEN,
+};
+
+static struct spi_board_info mc13783_dev __initdata = {
+	.modalias	= "mc13783",
+	.max_speed_hz	= 1000000,
+	.bus_num	= 1,
+	.chip_select	= 0,
+	.platform_data	= &mc13783_pdata,
+};
+
+static int mx31lilly_baseboard;
+core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444);
+
+static void __init mx31lilly_board_init(void)
+{
+	switch (mx31lilly_baseboard) {
+	case MX31LILLY_NOBOARD:
+		break;
+	case MX31LILLY_DB:
+		mx31lilly_db_init();
+		break;
+	default:
+		printk(KERN_ERR "Illegal mx31lilly_baseboard type %d\n",
+			mx31lilly_baseboard);
+	}
+
+	mxc_iomux_alloc_pin(MX31_PIN_CS4__CS4, "Ethernet CS");
+
+	/* SPI */
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SCLK__SCLK, "SPI1_CLK");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MOSI__MOSI, "SPI1_TX");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MISO__MISO, "SPI1_RX");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, "SPI1_RDY");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS0__SS0, "SPI1_SS0");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS1__SS1, "SPI1_SS1");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS2__SS2, "SPI1_SS2");
+
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SCLK__SCLK, "SPI2_CLK");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MOSI__MOSI, "SPI2_TX");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MISO__MISO, "SPI2_RX");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, "SPI2_RDY");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS0__SS0, "SPI2_SS0");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS1__SS1, "SPI2_SS1");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS2__SS2, "SPI2_SS2");
+
+	mxc_register_device(&mxc_spi_device0, &spi0_pdata);
+	mxc_register_device(&mxc_spi_device1, &spi1_pdata);
+	spi_register_board_info(&mc13783_dev, 1);
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init mx31lilly_timer_init(void)
+{
+	mx31_clocks_init(26000000);
+}
+
+static struct sys_timer mx31lilly_timer = {
+	.init	= mx31lilly_timer_init,
+};
+
+MACHINE_START(LILLY1131, "INCO startec LILLY-1131")
+	.phys_io	= MX31_AIPS1_BASE_ADDR,
+	.io_pg_offst	= (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+	.boot_params	= MX3x_PHYS_OFFSET + 0x100,
+	.map_io		= mx31_map_io,
+	.init_irq	= mx31_init_irq,
+	.init_machine	= mx31lilly_board_init,
+	.timer		= &mx31lilly_timer,
+MACHINE_END
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-mx31lite.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-mx31lite.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-mx31lite.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-mx31lite.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,297 @@
+/*
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *  Copyright (C) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/board-mx31lite.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+#include <mach/irqs.h>
+#include <mach/mxc_nand.h>
+#include <mach/spi.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
+
+#include "devices.h"
+
+/*
+ * This file contains the module-specific initialization routines.
+ */
+
+static unsigned int mx31lite_pins[] = {
+	/* LAN9117 IRQ pin */
+	IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO),
+	/* SPI 1 */
+	MX31_PIN_CSPI2_SCLK__SCLK,
+	MX31_PIN_CSPI2_MOSI__MOSI,
+	MX31_PIN_CSPI2_MISO__MISO,
+	MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
+	MX31_PIN_CSPI2_SS0__SS0,
+	MX31_PIN_CSPI2_SS1__SS1,
+	MX31_PIN_CSPI2_SS2__SS2,
+};
+
+static struct mxc_nand_platform_data mx31lite_nand_board_info = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
+	.flags		= SMSC911X_USE_16BIT,
+};
+
+static struct resource smsc911x_resources[] = {
+	{
+		.start		= MX31_CS4_BASE_ADDR,
+		.end		= MX31_CS4_BASE_ADDR + 0x100,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= IOMUX_TO_IRQ(MX31_PIN_SFS6),
+		.end		= IOMUX_TO_IRQ(MX31_PIN_SFS6),
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device smsc911x_device = {
+	.name		= "smsc911x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(smsc911x_resources),
+	.resource	= smsc911x_resources,
+	.dev		= {
+		.platform_data = &smsc911x_config,
+	},
+};
+
+/*
+ * SPI
+ *
+ * The MC13783 is the only hard-wired SPI device on the module.
+ */
+
+static int spi_internal_chipselect[] = {
+	MXC_SPI_CS(0),
+};
+
+static struct spi_imx_master spi1_pdata = {
+	.chipselect	= spi_internal_chipselect,
+	.num_chipselect	= ARRAY_SIZE(spi_internal_chipselect),
+};
+
+static struct mc13783_platform_data mc13783_pdata __initdata = {
+	.flags  = MC13783_USE_RTC |
+		  MC13783_USE_REGULATOR,
+};
+
+static struct spi_board_info mc13783_spi_dev __initdata = {
+	.modalias       = "mc13783",
+	.max_speed_hz   = 1000000,
+	.bus_num	= 1,
+	.chip_select    = 0,
+	.platform_data  = &mc13783_pdata,
+	.irq		= IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+};
+
+/*
+ * USB
+ */
+
+#if defined(CONFIG_USB_ULPI)
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int usbh2_init(struct platform_device *pdev)
+{
+	int pins[] = {
+		MX31_PIN_USBH2_DATA0__USBH2_DATA0,
+		MX31_PIN_USBH2_DATA1__USBH2_DATA1,
+		MX31_PIN_USBH2_CLK__USBH2_CLK,
+		MX31_PIN_USBH2_DIR__USBH2_DIR,
+		MX31_PIN_USBH2_NXT__USBH2_NXT,
+		MX31_PIN_USBH2_STP__USBH2_STP,
+	};
+
+	mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H2");
+
+	mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+	mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+	/* chip select */
+	mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO),
+				"USBH2_CS");
+	gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), "USBH2 CS");
+	gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), 0);
+
+	return 0;
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+	.init   = usbh2_init,
+	.portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+	.flags  = MXC_EHCI_POWER_PINS_ENABLED,
+};
+#endif
+
+/*
+ * NOR flash
+ */
+
+static struct physmap_flash_data nor_flash_data = {
+	.width  = 2,
+};
+
+static struct resource nor_flash_resource = {
+	.start  = 0xa0000000,
+	.end    = 0xa1ffffff,
+	.flags  = IORESOURCE_MEM,
+};
+
+static struct platform_device physmap_flash_device = {
+	.name   = "physmap-flash",
+	.id     = 0,
+	.dev    = {
+		.platform_data  = &nor_flash_data,
+	},
+	.resource = &nor_flash_resource,
+	.num_resources = 1,
+};
+
+
+
+/*
+ * This structure defines the MX31 memory map.
+ */
+static struct map_desc mx31lite_io_desc[] __initdata = {
+	{
+		.virtual = MX31_CS4_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR),
+		.length = MX31_CS4_SIZE,
+		.type = MT_DEVICE
+	}
+};
+
+/*
+ * Set up static virtual mappings.
+ */
+void __init mx31lite_map_io(void)
+{
+	mx31_map_io();
+	iotable_init(mx31lite_io_desc, ARRAY_SIZE(mx31lite_io_desc));
+}
+
+static int mx31lite_baseboard;
+core_param(mx31lite_baseboard, mx31lite_baseboard, int, 0444);
+
+static void __init mxc_board_init(void)
+{
+	int ret;
+
+	switch (mx31lite_baseboard) {
+	case MX31LITE_NOBOARD:
+		break;
+	case MX31LITE_DB:
+		mx31lite_db_init();
+		break;
+	default:
+		printk(KERN_ERR "Illegal mx31lite_baseboard type %d\n",
+				mx31lite_baseboard);
+	}
+
+	mxc_iomux_setup_multiple_pins(mx31lite_pins, ARRAY_SIZE(mx31lite_pins),
+				      "mx31lite");
+
+	/* NOR and NAND flash */
+	platform_device_register(&physmap_flash_device);
+	mxc_register_device(&mxc_nand_device, &mx31lite_nand_board_info);
+
+	mxc_register_device(&mxc_spi_device1, &spi1_pdata);
+	spi_register_board_info(&mc13783_spi_dev, 1);
+
+#if defined(CONFIG_USB_ULPI)
+	/* USB */
+	usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+				USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+	mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+#endif
+
+	/* SMSC9117 IRQ pin */
+	ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_SFS6), "sms9117-irq");
+	if (ret)
+		pr_warning("could not get LAN irq gpio\n");
+	else {
+		gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_SFS6));
+		platform_device_register(&smsc911x_device);
+	}
+}
+
+static void __init mx31lite_timer_init(void)
+{
+	mx31_clocks_init(26000000);
+}
+
+struct sys_timer mx31lite_timer = {
+	.init	= mx31lite_timer_init,
+};
+
+MACHINE_START(MX31LITE, "LogicPD i.MX31 SOM")
+	/* Maintainer: Freescale Semiconductor, Inc. */
+	.phys_io        = MX31_AIPS1_BASE_ADDR,
+	.io_pg_offst    = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+	.boot_params    = MX3x_PHYS_OFFSET + 0x100,
+	.map_io         = mx31lite_map_io,
+	.init_irq       = mx31_init_irq,
+	.init_machine   = mxc_board_init,
+	.timer          = &mx31lite_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-mx31moboard.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-mx31moboard.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-mx31moboard.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-mx31moboard.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,552 @@
+/*
+ *  Copyright (C) 2008 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/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/fsl_devices.h>
+#include <linux/gfp.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/leds.h>
+#include <linux/memory.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/types.h>
+
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <mach/board-mx31moboard.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+#include <mach/ipu.h>
+#include <mach/i2c.h>
+#include <mach/mmc.h>
+#include <mach/mxc_ehci.h>
+#include <mach/mx3_camera.h>
+#include <mach/spi.h>
+#include <mach/ulpi.h>
+
+#include "devices.h"
+
+static unsigned int moboard_pins[] = {
+	/* UART0 */
+	MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1,
+	MX31_PIN_CTS1__GPIO2_7,
+	/* UART4 */
+	MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5,
+	MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5,
+	/* I2C0 */
+	MX31_PIN_I2C_DAT__I2C1_SDA, MX31_PIN_I2C_CLK__I2C1_SCL,
+	/* I2C1 */
+	MX31_PIN_DCD_DTE1__I2C2_SDA, MX31_PIN_RI_DTE1__I2C2_SCL,
+	/* SDHC1 */
+	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,
+	MX31_PIN_ATA_CS0__GPIO3_26, MX31_PIN_ATA_CS1__GPIO3_27,
+	/* USB reset */
+	MX31_PIN_GPIO1_0__GPIO1_0,
+	/* USB OTG */
+	MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+	MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+	MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+	MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+	MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+	MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+	MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+	MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+	MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+	MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP,
+	MX31_PIN_USB_OC__GPIO1_30,
+	/* USB H2 */
+	MX31_PIN_USBH2_DATA0__USBH2_DATA0,
+	MX31_PIN_USBH2_DATA1__USBH2_DATA1,
+	MX31_PIN_STXD3__USBH2_DATA2, MX31_PIN_SRXD3__USBH2_DATA3,
+	MX31_PIN_SCK3__USBH2_DATA4, MX31_PIN_SFS3__USBH2_DATA5,
+	MX31_PIN_STXD6__USBH2_DATA6, MX31_PIN_SRXD6__USBH2_DATA7,
+	MX31_PIN_USBH2_CLK__USBH2_CLK, MX31_PIN_USBH2_DIR__USBH2_DIR,
+	MX31_PIN_USBH2_NXT__USBH2_NXT, MX31_PIN_USBH2_STP__USBH2_STP,
+	MX31_PIN_SCK6__GPIO1_25,
+	/* LEDs */
+	MX31_PIN_SVEN0__GPIO2_0, MX31_PIN_STX0__GPIO2_1,
+	MX31_PIN_SRX0__GPIO2_2, MX31_PIN_SIMPD0__GPIO2_3,
+	/* SPI1 */
+	MX31_PIN_CSPI2_MOSI__MOSI, MX31_PIN_CSPI2_MISO__MISO,
+	MX31_PIN_CSPI2_SCLK__SCLK, MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
+	MX31_PIN_CSPI2_SS0__SS0, MX31_PIN_CSPI2_SS2__SS2,
+	/* Atlas IRQ */
+	MX31_PIN_GPIO1_3__GPIO1_3,
+	/* SPI2 */
+	MX31_PIN_CSPI3_MOSI__MOSI, MX31_PIN_CSPI3_MISO__MISO,
+	MX31_PIN_CSPI3_SCLK__SCLK, MX31_PIN_CSPI3_SPI_RDY__SPI_RDY,
+	MX31_PIN_CSPI2_SS1__CSPI3_SS1,
+};
+
+static struct physmap_flash_data mx31moboard_flash_data = {
+	.width  	= 2,
+};
+
+static struct resource mx31moboard_flash_resource = {
+	.start	= 0xa0000000,
+	.end	= 0xa1ffffff,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device mx31moboard_flash = {
+	.name	= "physmap-flash",
+	.id	= 0,
+	.dev	= {
+		.platform_data  = &mx31moboard_flash_data,
+	},
+	.resource = &mx31moboard_flash_resource,
+	.num_resources = 1,
+};
+
+static int moboard_uart0_init(struct platform_device *pdev)
+{
+	gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack");
+	gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0);
+	return 0;
+}
+
+static struct imxuart_platform_data uart0_pdata = {
+	.init = moboard_uart0_init,
+};
+
+static struct imxuart_platform_data uart4_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct imxi2c_platform_data moboard_i2c0_pdata = {
+	.bitrate = 400000,
+};
+
+static struct imxi2c_platform_data moboard_i2c1_pdata = {
+	.bitrate = 100000,
+};
+
+static int moboard_spi1_cs[] = {
+	MXC_SPI_CS(0),
+	MXC_SPI_CS(2),
+};
+
+static struct spi_imx_master moboard_spi1_master = {
+	.chipselect	= moboard_spi1_cs,
+	.num_chipselect	= ARRAY_SIZE(moboard_spi1_cs),
+};
+
+static struct regulator_consumer_supply sdhc_consumers[] = {
+	{
+		.dev	= &mxcsdhc_device0.dev,
+		.supply	= "sdhc0_vcc",
+	},
+	{
+		.dev	= &mxcsdhc_device1.dev,
+		.supply	= "sdhc1_vcc",
+	},
+};
+
+static struct regulator_init_data sdhc_vreg_data = {
+	.constraints = {
+		.min_uV = 2700000,
+		.max_uV = 3000000,
+		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+			REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL |
+			REGULATOR_MODE_FAST,
+		.always_on = 0,
+		.boot_on = 1,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(sdhc_consumers),
+	.consumer_supplies = sdhc_consumers,
+};
+
+static struct regulator_consumer_supply cam_consumers[] = {
+	{
+		.dev	= &mx3_camera.dev,
+		.supply	= "cam_vcc",
+	},
+};
+
+static struct regulator_init_data cam_vreg_data = {
+	.constraints = {
+		.min_uV = 2700000,
+		.max_uV = 3000000,
+		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+			REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL |
+			REGULATOR_MODE_FAST,
+		.always_on = 0,
+		.boot_on = 1,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(cam_consumers),
+	.consumer_supplies = cam_consumers,
+};
+
+static struct mc13783_regulator_init_data moboard_regulators[] = {
+	{
+		.id = MC13783_REGU_VMMC1,
+		.init_data = &sdhc_vreg_data,
+	},
+	{
+		.id = MC13783_REGU_VCAM,
+		.init_data = &cam_vreg_data,
+	},
+};
+
+static struct mc13783_platform_data moboard_pmic = {
+	.regulators = moboard_regulators,
+	.num_regulators = ARRAY_SIZE(moboard_regulators),
+	.flags = MC13783_USE_REGULATOR | MC13783_USE_RTC |
+		MC13783_USE_ADC,
+};
+
+static struct spi_board_info moboard_spi_board_info[] __initdata = {
+	{
+		.modalias = "mc13783",
+		.irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+		.max_speed_hz = 300000,
+		.bus_num = 1,
+		.chip_select = 0,
+		.platform_data = &moboard_pmic,
+		.mode = SPI_CS_HIGH,
+	},
+};
+
+static int moboard_spi2_cs[] = {
+	MXC_SPI_CS(1),
+};
+
+static struct spi_imx_master moboard_spi2_master = {
+	.chipselect	= moboard_spi2_cs,
+	.num_chipselect	= ARRAY_SIZE(moboard_spi2_cs),
+};
+
+#define SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_ATA_CS0)
+#define SDHC1_WP IOMUX_TO_GPIO(MX31_PIN_ATA_CS1)
+
+static int moboard_sdhc1_get_ro(struct device *dev)
+{
+	return !gpio_get_value(SDHC1_WP);
+}
+
+static int moboard_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+		void *data)
+{
+	int ret;
+
+	ret = gpio_request(SDHC1_CD, "sdhc-detect");
+	if (ret)
+		return ret;
+
+	gpio_direction_input(SDHC1_CD);
+
+	ret = gpio_request(SDHC1_WP, "sdhc-wp");
+	if (ret)
+		goto err_gpio_free;
+	gpio_direction_input(SDHC1_WP);
+
+	ret = request_irq(gpio_to_irq(SDHC1_CD), detect_irq,
+		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+		"sdhc1-card-detect", data);
+	if (ret)
+		goto err_gpio_free_2;
+
+	return 0;
+
+err_gpio_free_2:
+	gpio_free(SDHC1_WP);
+err_gpio_free:
+	gpio_free(SDHC1_CD);
+
+	return ret;
+}
+
+static void moboard_sdhc1_exit(struct device *dev, void *data)
+{
+	free_irq(gpio_to_irq(SDHC1_CD), data);
+	gpio_free(SDHC1_WP);
+	gpio_free(SDHC1_CD);
+}
+
+static struct imxmmc_platform_data sdhc1_pdata = {
+	.get_ro	= moboard_sdhc1_get_ro,
+	.init	= moboard_sdhc1_init,
+	.exit	= moboard_sdhc1_exit,
+};
+
+/*
+ * this pin is dedicated for all mx31moboard systems, so we do it here
+ */
+#define USB_RESET_B	IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)
+
+static void usb_xcvr_reset(void)
+{
+	gpio_request(USB_RESET_B, "usb-reset");
+	gpio_direction_output(USB_RESET_B, 0);
+	mdelay(1);
+	gpio_set_value(USB_RESET_B, 1);
+}
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+#define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC)
+
+static void moboard_usbotg_init(void)
+{
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
+
+	gpio_request(OTG_EN_B, "usb-udc-en");
+	gpio_direction_output(OTG_EN_B, 0);
+}
+
+static struct fsl_usb2_platform_data usb_pdata = {
+	.operating_mode	= FSL_USB2_DR_DEVICE,
+	.phy_mode	= FSL_USB2_PHY_ULPI,
+};
+
+#if defined(CONFIG_USB_ULPI)
+
+#define USBH2_EN_B IOMUX_TO_GPIO(MX31_PIN_SCK6)
+
+static int moboard_usbh2_hw_init(struct platform_device *pdev)
+{
+	int ret;
+
+	mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+	mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+	ret = gpio_request(USBH2_EN_B, "usbh2-en");
+	if (ret)
+		return ret;
+	gpio_direction_output(USBH2_EN_B, 0);
+
+	return 0;
+}
+
+static int moboard_usbh2_hw_exit(struct platform_device *pdev)
+{
+	gpio_free(USBH2_EN_B);
+	return 0;
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+	.init	= moboard_usbh2_hw_init,
+	.exit	= moboard_usbh2_hw_exit,
+	.portsc	= MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+	.flags	= MXC_EHCI_POWER_PINS_ENABLED,
+};
+
+static int __init moboard_usbh2_init(void)
+{
+	usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+			USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+	return mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+}
+#else
+static inline int moboard_usbh2_init(void) { return 0; }
+#endif
+
+
+static struct gpio_led mx31moboard_leds[] = {
+	{
+		.name 	= "coreboard-led-0:red:running",
+		.default_trigger = "heartbeat",
+		.gpio 	= IOMUX_TO_GPIO(MX31_PIN_SVEN0),
+	}, {
+		.name	= "coreboard-led-1:red",
+		.gpio	= IOMUX_TO_GPIO(MX31_PIN_STX0),
+	}, {
+		.name	= "coreboard-led-2:red",
+		.gpio	= IOMUX_TO_GPIO(MX31_PIN_SRX0),
+	}, {
+		.name	= "coreboard-led-3:red",
+		.gpio	= IOMUX_TO_GPIO(MX31_PIN_SIMPD0),
+	},
+};
+
+static struct gpio_led_platform_data mx31moboard_led_pdata = {
+	.num_leds 	= ARRAY_SIZE(mx31moboard_leds),
+	.leds		= mx31moboard_leds,
+};
+
+static struct platform_device mx31moboard_leds_device = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &mx31moboard_led_pdata,
+	},
+};
+
+static struct ipu_platform_data mx3_ipu_data = {
+	.irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&mx31moboard_flash,
+	&mx31moboard_leds_device,
+};
+
+static struct mx3_camera_pdata camera_pdata = {
+	.dma_dev	= &mx3_ipu.dev,
+	.flags		= MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10,
+	.mclk_10khz	= 4800,
+};
+
+#define CAMERA_BUF_SIZE	(4*1024*1024)
+
+static int __init mx31moboard_cam_alloc_dma(const size_t buf_size)
+{
+	dma_addr_t dma_handle;
+	void *buf;
+	int dma;
+
+	if (buf_size < 2 * 1024 * 1024)
+		return -EINVAL;
+
+	buf = dma_alloc_coherent(NULL, buf_size, &dma_handle, GFP_KERNEL);
+	if (!buf) {
+		pr_err("%s: cannot allocate camera buffer-memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	memset(buf, 0, buf_size);
+
+	dma = dma_declare_coherent_memory(&mx3_camera.dev,
+					dma_handle, dma_handle, buf_size,
+					DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+
+	/* The way we call dma_declare_coherent_memory only a malloc can fail */
+	return dma & DMA_MEMORY_MAP ? 0 : -ENOMEM;
+}
+
+static int mx31moboard_baseboard;
+core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+	mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins),
+		"moboard");
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	mxc_register_device(&mxc_uart_device0, &uart0_pdata);
+
+	mxc_register_device(&mxc_uart_device4, &uart4_pdata);
+
+	mxc_register_device(&mxc_i2c_device0, &moboard_i2c0_pdata);
+	mxc_register_device(&mxc_i2c_device1, &moboard_i2c1_pdata);
+
+	mxc_register_device(&mxc_spi_device1, &moboard_spi1_master);
+	mxc_register_device(&mxc_spi_device2, &moboard_spi2_master);
+
+	gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3), "pmic-irq");
+	gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3));
+	spi_register_board_info(moboard_spi_board_info,
+		ARRAY_SIZE(moboard_spi_board_info));
+
+	mxc_register_device(&mxcsdhc_device0, &sdhc1_pdata);
+
+	mxc_register_device(&mx3_ipu, &mx3_ipu_data);
+	if (!mx31moboard_cam_alloc_dma(CAMERA_BUF_SIZE))
+		mxc_register_device(&mx3_camera, &camera_pdata);
+
+	usb_xcvr_reset();
+
+	moboard_usbotg_init();
+	mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
+	moboard_usbh2_init();
+
+	switch (mx31moboard_baseboard) {
+	case MX31NOBOARD:
+		break;
+	case MX31DEVBOARD:
+		mx31moboard_devboard_init();
+		break;
+	case MX31MARXBOT:
+		mx31moboard_marxbot_init();
+		break;
+	case MX31SMARTBOT:
+		mx31moboard_smartbot_init();
+		break;
+	default:
+		printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n",
+			mx31moboard_baseboard);
+	}
+}
+
+static void __init mx31moboard_timer_init(void)
+{
+	mx31_clocks_init(26000000);
+}
+
+struct sys_timer mx31moboard_timer = {
+	.init	= mx31moboard_timer_init,
+};
+
+MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
+	/* Maintainer: Valentin Longchamp, EPFL Mobots group */
+	.phys_io	= MX31_AIPS1_BASE_ADDR,
+	.io_pg_offst	= (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+	.boot_params    = MX3x_PHYS_OFFSET + 0x100,
+	.map_io         = mx31_map_io,
+	.init_irq       = mx31_init_irq,
+	.init_machine   = mxc_board_init,
+	.timer          = &mx31moboard_timer,
+MACHINE_END
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-mx35pdk.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-mx35pdk.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-mx35pdk.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-mx35pdk.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Author: Fabio Estevam <fabio.estevam@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 <linux/memory.h>
+#include <linux/gpio.h>
+#include <linux/fsl_devices.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx35.h>
+
+#include "devices.h"
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&mxc_fec_device,
+};
+
+static struct pad_desc mx35pdk_pads[] = {
+	/* UART1 */
+	MX35_PAD_CTS1__UART1_CTS,
+	MX35_PAD_RTS1__UART1_RTS,
+	MX35_PAD_TXD1__UART1_TXD_MUX,
+	MX35_PAD_RXD1__UART1_RXD_MUX,
+	/* FEC */
+	MX35_PAD_FEC_TX_CLK__FEC_TX_CLK,
+	MX35_PAD_FEC_RX_CLK__FEC_RX_CLK,
+	MX35_PAD_FEC_RX_DV__FEC_RX_DV,
+	MX35_PAD_FEC_COL__FEC_COL,
+	MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
+	MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
+	MX35_PAD_FEC_TX_EN__FEC_TX_EN,
+	MX35_PAD_FEC_MDC__FEC_MDC,
+	MX35_PAD_FEC_MDIO__FEC_MDIO,
+	MX35_PAD_FEC_TX_ERR__FEC_TX_ERR,
+	MX35_PAD_FEC_RX_ERR__FEC_RX_ERR,
+	MX35_PAD_FEC_CRS__FEC_CRS,
+	MX35_PAD_FEC_RDATA1__FEC_RDATA_1,
+	MX35_PAD_FEC_TDATA1__FEC_TDATA_1,
+	MX35_PAD_FEC_RDATA2__FEC_RDATA_2,
+	MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
+	MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
+	MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
+	/* USBOTG */
+	MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,
+	MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC,
+};
+
+/* OTG config */
+static struct fsl_usb2_platform_data usb_pdata = {
+	.operating_mode	= FSL_USB2_DR_DEVICE,
+	.phy_mode	= FSL_USB2_PHY_UTMI_WIDE,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+	mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+
+	mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
+}
+
+static void __init mx35pdk_timer_init(void)
+{
+	mx35_clocks_init();
+}
+
+struct sys_timer mx35pdk_timer = {
+	.init	= mx35pdk_timer_init,
+};
+
+MACHINE_START(MX35_3DS, "Freescale MX35PDK")
+	/* Maintainer: Freescale Semiconductor, Inc */
+	.phys_io	= MX35_AIPS1_BASE_ADDR,
+	.io_pg_offst	= ((MX35_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = MX3x_PHYS_OFFSET + 0x100,
+	.map_io         = mx35_map_io,
+	.init_irq       = mx35_init_irq,
+	.init_machine   = mxc_board_init,
+	.timer          = &mx35pdk_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-pcm037.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-pcm037.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-pcm037.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-pcm037.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,693 @@
+/*
+ *  Copyright (C) 2008 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/memory.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+#include <linux/irq.h>
+#include <linux/fsl_devices.h>
+#include <linux/can/platform/sja1000.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/gfp.h>
+
+#include <media/soc_camera.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <mach/board-pcm037.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/i2c.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+#include <mach/ipu.h>
+#include <mach/mmc.h>
+#include <mach/mx3_camera.h>
+#include <mach/mx3fb.h>
+#include <mach/mxc_nand.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
+
+#include "devices.h"
+#include "pcm037.h"
+
+static enum pcm037_board_variant pcm037_instance = PCM037_PCM970;
+
+static int __init pcm037_variant_setup(char *str)
+{
+	if (!strcmp("eet", str))
+		pcm037_instance = PCM037_EET;
+	else if (strcmp("pcm970", str))
+		pr_warning("Unknown pcm037 baseboard variant %s\n", str);
+
+	return 1;
+}
+
+/* Supported values: "pcm970" (default) and "eet" */
+__setup("pcm037_variant=", pcm037_variant_setup);
+
+enum pcm037_board_variant pcm037_variant(void)
+{
+	return pcm037_instance;
+}
+
+/* UART1 with RTS/CTS handshake signals */
+static unsigned int pcm037_uart1_handshake_pins[] = {
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1,
+};
+
+/* UART1 without RTS/CTS handshake signals */
+static unsigned int pcm037_uart1_pins[] = {
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1,
+};
+
+static unsigned int pcm037_pins[] = {
+	/* I2C */
+	MX31_PIN_CSPI2_MOSI__SCL,
+	MX31_PIN_CSPI2_MISO__SDA,
+	MX31_PIN_CSPI2_SS2__I2C3_SDA,
+	MX31_PIN_CSPI2_SCLK__I2C3_SCL,
+	/* SDHC1 */
+	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,
+	IOMUX_MODE(MX31_PIN_SCK6, IOMUX_CONFIG_GPIO), /* card detect */
+	IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO), /* write protect */
+	/* SPI1 */
+	MX31_PIN_CSPI1_MOSI__MOSI,
+	MX31_PIN_CSPI1_MISO__MISO,
+	MX31_PIN_CSPI1_SCLK__SCLK,
+	MX31_PIN_CSPI1_SPI_RDY__SPI_RDY,
+	MX31_PIN_CSPI1_SS0__SS0,
+	MX31_PIN_CSPI1_SS1__SS1,
+	MX31_PIN_CSPI1_SS2__SS2,
+	/* UART2 */
+	MX31_PIN_TXD2__TXD2,
+	MX31_PIN_RXD2__RXD2,
+	MX31_PIN_CTS2__CTS2,
+	MX31_PIN_RTS2__RTS2,
+	/* UART3 */
+	MX31_PIN_CSPI3_MOSI__RXD3,
+	MX31_PIN_CSPI3_MISO__TXD3,
+	MX31_PIN_CSPI3_SCLK__RTS3,
+	MX31_PIN_CSPI3_SPI_RDY__CTS3,
+	/* LAN9217 irq pin */
+	IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO),
+	/* Onewire */
+	MX31_PIN_BATT_LINE__OWIRE,
+	/* Framebuffer */
+	MX31_PIN_LD0__LD0,
+	MX31_PIN_LD1__LD1,
+	MX31_PIN_LD2__LD2,
+	MX31_PIN_LD3__LD3,
+	MX31_PIN_LD4__LD4,
+	MX31_PIN_LD5__LD5,
+	MX31_PIN_LD6__LD6,
+	MX31_PIN_LD7__LD7,
+	MX31_PIN_LD8__LD8,
+	MX31_PIN_LD9__LD9,
+	MX31_PIN_LD10__LD10,
+	MX31_PIN_LD11__LD11,
+	MX31_PIN_LD12__LD12,
+	MX31_PIN_LD13__LD13,
+	MX31_PIN_LD14__LD14,
+	MX31_PIN_LD15__LD15,
+	MX31_PIN_LD16__LD16,
+	MX31_PIN_LD17__LD17,
+	MX31_PIN_VSYNC3__VSYNC3,
+	MX31_PIN_HSYNC__HSYNC,
+	MX31_PIN_FPSHIFT__FPSHIFT,
+	MX31_PIN_DRDY0__DRDY0,
+	MX31_PIN_D3_REV__D3_REV,
+	MX31_PIN_CONTRAST__CONTRAST,
+	MX31_PIN_D3_SPL__D3_SPL,
+	MX31_PIN_D3_CLS__D3_CLS,
+	MX31_PIN_LCS0__GPI03_23,
+	/* CSI */
+	IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_GPIO),
+	MX31_PIN_CSI_D6__CSI_D6,
+	MX31_PIN_CSI_D7__CSI_D7,
+	MX31_PIN_CSI_D8__CSI_D8,
+	MX31_PIN_CSI_D9__CSI_D9,
+	MX31_PIN_CSI_D10__CSI_D10,
+	MX31_PIN_CSI_D11__CSI_D11,
+	MX31_PIN_CSI_D12__CSI_D12,
+	MX31_PIN_CSI_D13__CSI_D13,
+	MX31_PIN_CSI_D14__CSI_D14,
+	MX31_PIN_CSI_D15__CSI_D15,
+	MX31_PIN_CSI_HSYNC__CSI_HSYNC,
+	MX31_PIN_CSI_MCLK__CSI_MCLK,
+	MX31_PIN_CSI_PIXCLK__CSI_PIXCLK,
+	MX31_PIN_CSI_VSYNC__CSI_VSYNC,
+	/* GPIO */
+	IOMUX_MODE(MX31_PIN_ATA_DMACK, IOMUX_CONFIG_GPIO),
+	/* OTG */
+	MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+	MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+	MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+	MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+	MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+	MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+	MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+	MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+	MX31_PIN_USBOTG_CLK__USBOTG_CLK,
+	MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+	MX31_PIN_USBOTG_NXT__USBOTG_NXT,
+	MX31_PIN_USBOTG_STP__USBOTG_STP,
+	/* USB host 2 */
+	IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC),
+};
+
+static struct physmap_flash_data pcm037_flash_data = {
+	.width  = 2,
+};
+
+static struct resource pcm037_flash_resource = {
+	.start	= 0xa0000000,
+	.end	= 0xa1ffffff,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device pcm037_flash = {
+	.name	= "physmap-flash",
+	.id	= 0,
+	.dev	= {
+		.platform_data  = &pcm037_flash_data,
+	},
+	.resource = &pcm037_flash_resource,
+	.num_resources = 1,
+};
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct resource smsc911x_resources[] = {
+	{
+		.start		= MX31_CS1_BASE_ADDR + 0x300,
+		.end		= MX31_CS1_BASE_ADDR + 0x300 + SZ_64K - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
+		.end		= IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
+		.flags		= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+	},
+};
+
+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		= "smsc911x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(smsc911x_resources),
+	.resource	= smsc911x_resources,
+	.dev		= {
+		.platform_data = &smsc911x_info,
+	},
+};
+
+static struct platdata_mtd_ram pcm038_sram_data = {
+	.bankwidth = 2,
+};
+
+static struct resource pcm038_sram_resource = {
+	.start = MX31_CS4_BASE_ADDR,
+	.end   = MX31_CS4_BASE_ADDR + 512 * 1024 - 1,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pcm037_sram_device = {
+	.name = "mtd-ram",
+	.id = 0,
+	.dev = {
+		.platform_data = &pcm038_sram_data,
+	},
+	.num_resources = 1,
+	.resource = &pcm038_sram_resource,
+};
+
+static struct mxc_nand_platform_data pcm037_nand_board_info = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
+static struct imxi2c_platform_data pcm037_i2c_1_data = {
+	.bitrate = 100000,
+};
+
+static struct imxi2c_platform_data pcm037_i2c_2_data = {
+	.bitrate = 20000,
+};
+
+static struct at24_platform_data board_eeprom = {
+	.byte_len = 4096,
+	.page_size = 32,
+	.flags = AT24_FLAG_ADDR16,
+};
+
+static int pcm037_camera_power(struct device *dev, int on)
+{
+	/* disable or enable the camera in X7 or X8 PCM970 connector */
+	gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), !on);
+	return 0;
+}
+
+static struct i2c_board_info pcm037_i2c_camera[] = {
+	{
+		I2C_BOARD_INFO("mt9t031", 0x5d),
+	}, {
+		I2C_BOARD_INFO("mt9v022", 0x48),
+	},
+};
+
+static struct soc_camera_link iclink_mt9v022 = {
+	.bus_id		= 0,		/* Must match with the camera ID */
+	.board_info	= &pcm037_i2c_camera[1],
+	.i2c_adapter_id	= 2,
+	.module_name	= "mt9v022",
+};
+
+static struct soc_camera_link iclink_mt9t031 = {
+	.bus_id		= 0,		/* Must match with the camera ID */
+	.power		= pcm037_camera_power,
+	.board_info	= &pcm037_i2c_camera[0],
+	.i2c_adapter_id	= 2,
+	.module_name	= "mt9t031",
+};
+
+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("pcf8563", 0x51),
+	}
+};
+
+static struct platform_device pcm037_mt9t031 = {
+	.name	= "soc-camera-pdrv",
+	.id	= 0,
+	.dev	= {
+		.platform_data = &iclink_mt9t031,
+	},
+};
+
+static struct platform_device pcm037_mt9v022 = {
+	.name	= "soc-camera-pdrv",
+	.id	= 1,
+	.dev	= {
+		.platform_data = &iclink_mt9v022,
+	},
+};
+
+/* Not connected by default */
+#ifdef PCM970_SDHC_RW_SWITCH
+static int pcm970_sdhc1_get_ro(struct device *dev)
+{
+	return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_SFS6));
+}
+#endif
+
+#define SDHC1_GPIO_WP	IOMUX_TO_GPIO(MX31_PIN_SFS6)
+#define SDHC1_GPIO_DET	IOMUX_TO_GPIO(MX31_PIN_SCK6)
+
+static int pcm970_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+		void *data)
+{
+	int ret;
+
+	ret = gpio_request(SDHC1_GPIO_DET, "sdhc-detect");
+	if (ret)
+		return ret;
+
+	gpio_direction_input(SDHC1_GPIO_DET);
+
+#ifdef PCM970_SDHC_RW_SWITCH
+	ret = gpio_request(SDHC1_GPIO_WP, "sdhc-wp");
+	if (ret)
+		goto err_gpio_free;
+	gpio_direction_input(SDHC1_GPIO_WP);
+#endif
+
+	ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_SCK6), detect_irq,
+			IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+				"sdhc-detect", data);
+	if (ret)
+		goto err_gpio_free_2;
+
+	return 0;
+
+err_gpio_free_2:
+#ifdef PCM970_SDHC_RW_SWITCH
+	gpio_free(SDHC1_GPIO_WP);
+err_gpio_free:
+#endif
+	gpio_free(SDHC1_GPIO_DET);
+
+	return ret;
+}
+
+static void pcm970_sdhc1_exit(struct device *dev, void *data)
+{
+	free_irq(IOMUX_TO_IRQ(MX31_PIN_SCK6), data);
+	gpio_free(SDHC1_GPIO_DET);
+	gpio_free(SDHC1_GPIO_WP);
+}
+
+static struct imxmmc_platform_data sdhc_pdata = {
+#ifdef PCM970_SDHC_RW_SWITCH
+	.get_ro = pcm970_sdhc1_get_ro,
+#endif
+	.init = pcm970_sdhc1_init,
+	.exit = pcm970_sdhc1_exit,
+};
+
+struct mx3_camera_pdata camera_pdata = {
+	.dma_dev	= &mx3_ipu.dev,
+	.flags		= MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10,
+	.mclk_10khz	= 2000,
+};
+
+static int __init pcm037_camera_alloc_dma(const size_t buf_size)
+{
+	dma_addr_t dma_handle;
+	void *buf;
+	int dma;
+
+	if (buf_size < 2 * 1024 * 1024)
+		return -EINVAL;
+
+	buf = dma_alloc_coherent(NULL, buf_size, &dma_handle, GFP_KERNEL);
+	if (!buf) {
+		pr_err("%s: cannot allocate camera buffer-memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	memset(buf, 0, buf_size);
+
+	dma = dma_declare_coherent_memory(&mx3_camera.dev,
+					dma_handle, dma_handle, buf_size,
+					DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+
+	/* The way we call dma_declare_coherent_memory only a malloc can fail */
+	return dma & DMA_MEMORY_MAP ? 0 : -ENOMEM;
+}
+
+static struct platform_device *devices[] __initdata = {
+	&pcm037_flash,
+	&pcm037_sram_device,
+	&pcm037_mt9t031,
+	&pcm037_mt9v022,
+};
+
+static struct ipu_platform_data mx3_ipu_data = {
+	.irq_base = MXC_IPU_IRQ_START,
+};
+
+static const struct fb_videomode fb_modedb[] = {
+	{
+		/* 240x320 @ 60 Hz Sharp */
+		.name		= "Sharp-LQ035Q7DH06-QVGA",
+		.refresh	= 60,
+		.xres		= 240,
+		.yres		= 320,
+		.pixclock	= 185925,
+		.left_margin	= 9,
+		.right_margin	= 16,
+		.upper_margin	= 7,
+		.lower_margin	= 9,
+		.hsync_len	= 1,
+		.vsync_len	= 1,
+		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
+				  FB_SYNC_CLK_INVERT | FB_SYNC_CLK_IDLE_EN,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.flag		= 0,
+	}, {
+		/* 240x320 @ 60 Hz */
+		.name		= "TX090",
+		.refresh	= 60,
+		.xres		= 240,
+		.yres		= 320,
+		.pixclock	= 38255,
+		.left_margin	= 144,
+		.right_margin	= 0,
+		.upper_margin	= 7,
+		.lower_margin	= 40,
+		.hsync_len	= 96,
+		.vsync_len	= 1,
+		.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.flag		= 0,
+	}, {
+		/* 240x320 @ 60 Hz */
+		.name		= "CMEL-OLED",
+		.refresh	= 60,
+		.xres		= 240,
+		.yres		= 320,
+		.pixclock	= 185925,
+		.left_margin	= 9,
+		.right_margin	= 16,
+		.upper_margin	= 7,
+		.lower_margin	= 9,
+		.hsync_len	= 1,
+		.vsync_len	= 1,
+		.sync		= FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.flag		= 0,
+	},
+};
+
+static struct mx3fb_platform_data mx3fb_pdata = {
+	.dma_dev	= &mx3_ipu.dev,
+	.name		= "Sharp-LQ035Q7DH06-QVGA",
+	.mode		= fb_modedb,
+	.num_modes	= ARRAY_SIZE(fb_modedb),
+};
+
+static struct resource pcm970_sja1000_resources[] = {
+	{
+		.start   = MX31_CS5_BASE_ADDR,
+		.end     = MX31_CS5_BASE_ADDR + 0x100 - 1,
+		.flags   = IORESOURCE_MEM,
+	}, {
+		.start   = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)),
+		.end     = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)),
+		.flags   = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+	},
+};
+
+struct sja1000_platform_data pcm970_sja1000_platform_data = {
+	.clock		= 16000000 / 2,
+	.ocr		= 0x40 | 0x18,
+	.cdr		= 0x40,
+};
+
+static struct platform_device pcm970_sja1000 = {
+	.name = "sja1000_platform",
+	.dev = {
+		.platform_data = &pcm970_sja1000_platform_data,
+	},
+	.resource = pcm970_sja1000_resources,
+	.num_resources = ARRAY_SIZE(pcm970_sja1000_resources),
+};
+
+static struct mxc_usbh_platform_data otg_pdata = {
+	.portsc	= MXC_EHCI_MODE_ULPI,
+	.flags	= MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+	.portsc	= MXC_EHCI_MODE_ULPI,
+	.flags	= MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static struct fsl_usb2_platform_data otg_device_pdata = {
+	.operating_mode = FSL_USB2_DR_DEVICE,
+	.phy_mode       = FSL_USB2_PHY_ULPI,
+};
+
+static int otg_mode_host;
+
+static int __init pcm037_otg_mode(char *options)
+{
+	if (!strcmp(options, "host"))
+		otg_mode_host = 1;
+	else if (!strcmp(options, "device"))
+		otg_mode_host = 0;
+	else
+		pr_info("otg_mode neither \"host\" nor \"device\". "
+			"Defaulting to device\n");
+	return 0;
+}
+__setup("otg_mode=", pcm037_otg_mode);
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+	int ret;
+	u32 tmp;
+
+	mxc_iomux_set_gpr(MUX_PGP_UH2, 1);
+
+	mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins),
+			"pcm037");
+
+#define H2_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS \
+		| PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+	mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, H2_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, H2_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, H2_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_STP, H2_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, H2_PAD_CFG); /* USBH2_DATA0 */
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, H2_PAD_CFG); /* USBH2_DATA1 */
+	mxc_iomux_set_pad(MX31_PIN_SRXD6, H2_PAD_CFG);	/* USBH2_DATA2 */
+	mxc_iomux_set_pad(MX31_PIN_STXD6, H2_PAD_CFG);	/* USBH2_DATA3 */
+	mxc_iomux_set_pad(MX31_PIN_SFS3, H2_PAD_CFG);	/* USBH2_DATA4 */
+	mxc_iomux_set_pad(MX31_PIN_SCK3, H2_PAD_CFG);	/* USBH2_DATA5 */
+	mxc_iomux_set_pad(MX31_PIN_SRXD3, H2_PAD_CFG);	/* USBH2_DATA6 */
+	mxc_iomux_set_pad(MX31_PIN_STXD3, H2_PAD_CFG);	/* USBH2_DATA7 */
+
+	if (pcm037_variant() == PCM037_EET)
+		mxc_iomux_setup_multiple_pins(pcm037_uart1_pins,
+			ARRAY_SIZE(pcm037_uart1_pins), "pcm037_uart1");
+	else
+		mxc_iomux_setup_multiple_pins(pcm037_uart1_handshake_pins,
+			ARRAY_SIZE(pcm037_uart1_handshake_pins),
+			"pcm037_uart1");
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+	mxc_register_device(&mxc_uart_device1, &uart_pdata);
+	mxc_register_device(&mxc_uart_device2, &uart_pdata);
+
+	mxc_register_device(&mxc_w1_master_device, NULL);
+
+	/* LAN9217 IRQ pin */
+	ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1), "lan9217-irq");
+	if (ret)
+		pr_warning("could not get LAN irq gpio\n");
+	else {
+		gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1));
+		platform_device_register(&pcm037_eth);
+	}
+
+
+	/* I2C adapters and devices */
+	i2c_register_board_info(1, pcm037_i2c_devices,
+			ARRAY_SIZE(pcm037_i2c_devices));
+
+	mxc_register_device(&mxc_i2c_device1, &pcm037_i2c_1_data);
+	mxc_register_device(&mxc_i2c_device2, &pcm037_i2c_2_data);
+
+	mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
+	mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
+	mxc_register_device(&mx3_ipu, &mx3_ipu_data);
+	mxc_register_device(&mx3_fb, &mx3fb_pdata);
+
+	/* CSI */
+	/* Camera power: default - off */
+	ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), "mt9t031-power");
+	if (!ret)
+		gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), 1);
+	else
+		iclink_mt9t031.power = NULL;
+
+	if (!pcm037_camera_alloc_dma(4 * 1024 * 1024))
+		mxc_register_device(&mx3_camera, &camera_pdata);
+
+	platform_device_register(&pcm970_sja1000);
+
+#if defined(CONFIG_USB_ULPI)
+	if (otg_mode_host) {
+		otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+				USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+		mxc_register_device(&mxc_otg_host, &otg_pdata);
+	}
+
+	usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+				USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+	mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+#endif
+	if (!otg_mode_host)
+		mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
+
+}
+
+static void __init pcm037_timer_init(void)
+{
+	mx31_clocks_init(26000000);
+}
+
+struct sys_timer pcm037_timer = {
+	.init	= pcm037_timer_init,
+};
+
+MACHINE_START(PCM037, "Phytec Phycore pcm037")
+	/* Maintainer: Pengutronix */
+	.phys_io	= MX31_AIPS1_BASE_ADDR,
+	.io_pg_offst	= (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+	.boot_params    = MX3x_PHYS_OFFSET + 0x100,
+	.map_io         = mx31_map_io,
+	.init_irq       = mx31_init_irq,
+	.init_machine   = mxc_board_init,
+	.timer          = &pcm037_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-pcm037_eet.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-pcm037_eet.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-pcm037_eet.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-pcm037_eet.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2009
+ * 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/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+
+#include <mach/common.h>
+#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
+#include <mach/spi.h>
+#endif
+#include <mach/iomux-mx3.h>
+
+#include <asm/mach-types.h>
+
+#include "pcm037.h"
+#include "devices.h"
+
+static unsigned int pcm037_eet_pins[] = {
+	/* Reserve and hardwire GPIO 57 high - S6E63D6 chipselect */
+	IOMUX_MODE(MX31_PIN_KEY_COL7, IOMUX_CONFIG_GPIO),
+	/* GPIO keys */
+	IOMUX_MODE(MX31_PIN_GPIO1_0,	IOMUX_CONFIG_GPIO), /* 0 */
+	IOMUX_MODE(MX31_PIN_GPIO1_1,	IOMUX_CONFIG_GPIO), /* 1 */
+	IOMUX_MODE(MX31_PIN_GPIO1_2,	IOMUX_CONFIG_GPIO), /* 2 */
+	IOMUX_MODE(MX31_PIN_GPIO1_3,	IOMUX_CONFIG_GPIO), /* 3 */
+	IOMUX_MODE(MX31_PIN_SVEN0,	IOMUX_CONFIG_GPIO), /* 32 */
+	IOMUX_MODE(MX31_PIN_STX0,	IOMUX_CONFIG_GPIO), /* 33 */
+	IOMUX_MODE(MX31_PIN_SRX0,	IOMUX_CONFIG_GPIO), /* 34 */
+	IOMUX_MODE(MX31_PIN_SIMPD0,	IOMUX_CONFIG_GPIO), /* 35 */
+	IOMUX_MODE(MX31_PIN_RTS1,	IOMUX_CONFIG_GPIO), /* 38 */
+	IOMUX_MODE(MX31_PIN_CTS1,	IOMUX_CONFIG_GPIO), /* 39 */
+	IOMUX_MODE(MX31_PIN_KEY_ROW4,	IOMUX_CONFIG_GPIO), /* 50 */
+	IOMUX_MODE(MX31_PIN_KEY_ROW5,	IOMUX_CONFIG_GPIO), /* 51 */
+	IOMUX_MODE(MX31_PIN_KEY_ROW6,	IOMUX_CONFIG_GPIO), /* 52 */
+	IOMUX_MODE(MX31_PIN_KEY_ROW7,	IOMUX_CONFIG_GPIO), /* 53 */
+
+	/* LEDs */
+	IOMUX_MODE(MX31_PIN_DTR_DTE1,	IOMUX_CONFIG_GPIO), /* 44 */
+	IOMUX_MODE(MX31_PIN_DSR_DTE1,	IOMUX_CONFIG_GPIO), /* 45 */
+	IOMUX_MODE(MX31_PIN_KEY_COL5,	IOMUX_CONFIG_GPIO), /* 55 */
+	IOMUX_MODE(MX31_PIN_KEY_COL6,	IOMUX_CONFIG_GPIO), /* 56 */
+};
+
+/* SPI */
+static struct spi_board_info pcm037_spi_dev[] = {
+	{
+		.modalias	= "dac124s085",
+		.max_speed_hz	= 400000,
+		.bus_num	= 0,
+		.chip_select	= 0,		/* Index in pcm037_spi1_cs[] */
+		.mode		= SPI_CPHA,
+	},
+};
+
+/* Platform Data for MXC CSPI */
+#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
+static int pcm037_spi1_cs[] = {MXC_SPI_CS(1), IOMUX_TO_GPIO(MX31_PIN_KEY_COL7)};
+
+struct spi_imx_master pcm037_spi1_master = {
+	.chipselect = pcm037_spi1_cs,
+	.num_chipselect = ARRAY_SIZE(pcm037_spi1_cs),
+};
+#endif
+
+/* GPIO-keys input device */
+static struct gpio_keys_button pcm037_gpio_keys[] = {
+	{
+		.type	= EV_KEY,
+		.code	= KEY_L,
+		.gpio	= 0,
+		.desc	= "Wheel Manual",
+		.wakeup	= 0,
+	}, {
+		.type	= EV_KEY,
+		.code	= KEY_A,
+		.gpio	= 1,
+		.desc	= "Wheel AF",
+		.wakeup	= 0,
+	}, {
+		.type	= EV_KEY,
+		.code	= KEY_V,
+		.gpio	= 2,
+		.desc	= "Wheel View",
+		.wakeup	= 0,
+	}, {
+		.type	= EV_KEY,
+		.code	= KEY_M,
+		.gpio	= 3,
+		.desc	= "Wheel Menu",
+		.wakeup	= 0,
+	}, {
+		.type	= EV_KEY,
+		.code	= KEY_UP,
+		.gpio	= 32,
+		.desc	= "Nav Pad Up",
+		.wakeup	= 0,
+	}, {
+		.type	= EV_KEY,
+		.code	= KEY_RIGHT,
+		.gpio	= 33,
+		.desc	= "Nav Pad Right",
+		.wakeup	= 0,
+	}, {
+		.type	= EV_KEY,
+		.code	= KEY_DOWN,
+		.gpio	= 34,
+		.desc	= "Nav Pad Down",
+		.wakeup	= 0,
+	}, {
+		.type	= EV_KEY,
+		.code	= KEY_LEFT,
+		.gpio	= 35,
+		.desc	= "Nav Pad Left",
+		.wakeup	= 0,
+	}, {
+		.type	= EV_KEY,
+		.code	= KEY_ENTER,
+		.gpio	= 38,
+		.desc	= "Nav Pad Ok",
+		.wakeup	= 0,
+	}, {
+		.type	= EV_KEY,
+		.code	= KEY_O,
+		.gpio	= 39,
+		.desc	= "Wheel Off",
+		.wakeup	= 0,
+	}, {
+		.type	= EV_KEY,
+		.code	= BTN_FORWARD,
+		.gpio	= 50,
+		.desc	= "Focus Forward",
+		.wakeup	= 0,
+	}, {
+		.type	= EV_KEY,
+		.code	= BTN_BACK,
+		.gpio	= 51,
+		.desc	= "Focus Backward",
+		.wakeup	= 0,
+	}, {
+		.type	= EV_KEY,
+		.code	= BTN_MIDDLE,
+		.gpio	= 52,
+		.desc	= "Release Half",
+		.wakeup	= 0,
+	}, {
+		.type	= EV_KEY,
+		.code	= BTN_EXTRA,
+		.gpio	= 53,
+		.desc	= "Release Full",
+		.wakeup	= 0,
+	},
+};
+
+static struct gpio_keys_platform_data pcm037_gpio_keys_platform_data = {
+	.buttons	= pcm037_gpio_keys,
+	.nbuttons	= ARRAY_SIZE(pcm037_gpio_keys),
+	.rep		= 0, /* No auto-repeat */
+};
+
+static struct platform_device pcm037_gpio_keys_device = {
+	.name	= "gpio-keys",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &pcm037_gpio_keys_platform_data,
+	},
+};
+
+static int eet_init_devices(void)
+{
+	if (!machine_is_pcm037() || pcm037_variant() != PCM037_EET)
+		return 0;
+
+	mxc_iomux_setup_multiple_pins(pcm037_eet_pins,
+				ARRAY_SIZE(pcm037_eet_pins), "pcm037_eet");
+
+	/* SPI */
+	spi_register_board_info(pcm037_spi_dev, ARRAY_SIZE(pcm037_spi_dev));
+#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
+	mxc_register_device(&mxc_spi_device0, &pcm037_spi1_master);
+#endif
+
+	platform_device_register(&pcm037_gpio_keys_device);
+
+	return 0;
+}
+
+late_initcall(eet_init_devices);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-pcm043.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-pcm043.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-pcm043.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-pcm043.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,413 @@
+/*
+ *  Copyright (C) 2009 Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/memory.h>
+#include <linux/gpio.h>
+#include <linux/smc911x.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/fsl_devices.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#if defined CONFIG_I2C_IMX || defined CONFIG_I2C_IMX_MODULE
+#include <mach/i2c.h>
+#endif
+#include <mach/iomux-mx35.h>
+#include <mach/ipu.h>
+#include <mach/mx3fb.h>
+#include <mach/mxc_nand.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
+#include <mach/audmux.h>
+#include <mach/ssi.h>
+
+#include "devices.h"
+
+static const struct fb_videomode fb_modedb[] = {
+	{
+		/* 240x320 @ 60 Hz */
+		.name		= "Sharp-LQ035Q7",
+		.refresh	= 60,
+		.xres		= 240,
+		.yres		= 320,
+		.pixclock	= 185925,
+		.left_margin	= 9,
+		.right_margin	= 16,
+		.upper_margin	= 7,
+		.lower_margin	= 9,
+		.hsync_len	= 1,
+		.vsync_len	= 1,
+		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | FB_SYNC_CLK_INVERT | FB_SYNC_CLK_IDLE_EN,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.flag		= 0,
+	}, {
+		/* 240x320 @ 60 Hz */
+		.name		= "TX090",
+		.refresh	= 60,
+		.xres		= 240,
+		.yres		= 320,
+		.pixclock	= 38255,
+		.left_margin	= 144,
+		.right_margin	= 0,
+		.upper_margin	= 7,
+		.lower_margin	= 40,
+		.hsync_len	= 96,
+		.vsync_len	= 1,
+		.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.flag		= 0,
+	},
+};
+
+static struct ipu_platform_data mx3_ipu_data = {
+	.irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct mx3fb_platform_data mx3fb_pdata = {
+	.dma_dev	= &mx3_ipu.dev,
+	.name		= "Sharp-LQ035Q7",
+	.mode		= fb_modedb,
+	.num_modes	= ARRAY_SIZE(fb_modedb),
+};
+
+static struct physmap_flash_data pcm043_flash_data = {
+	.width  = 2,
+};
+
+static struct resource pcm043_flash_resource = {
+	.start	= 0xa0000000,
+	.end	= 0xa1ffffff,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device pcm043_flash = {
+	.name	= "physmap-flash",
+	.id	= 0,
+	.dev	= {
+		.platform_data  = &pcm043_flash_data,
+	},
+	.resource = &pcm043_flash_resource,
+	.num_resources = 1,
+};
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+#if defined CONFIG_I2C_IMX || defined CONFIG_I2C_IMX_MODULE
+static struct imxi2c_platform_data pcm043_i2c_1_data = {
+	.bitrate = 50000,
+};
+
+static struct at24_platform_data board_eeprom = {
+	.byte_len = 4096,
+	.page_size = 32,
+	.flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info pcm043_i2c_devices[] = {
+       {
+		I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+		.platform_data = &board_eeprom,
+	}, {
+		I2C_BOARD_INFO("pcf8563", 0x51),
+	}
+};
+#endif
+
+static struct platform_device *devices[] __initdata = {
+	&pcm043_flash,
+	&mxc_fec_device,
+};
+
+static struct pad_desc pcm043_pads[] = {
+	/* UART1 */
+	MX35_PAD_CTS1__UART1_CTS,
+	MX35_PAD_RTS1__UART1_RTS,
+	MX35_PAD_TXD1__UART1_TXD_MUX,
+	MX35_PAD_RXD1__UART1_RXD_MUX,
+	/* UART2 */
+	MX35_PAD_CTS2__UART2_CTS,
+	MX35_PAD_RTS2__UART2_RTS,
+	MX35_PAD_TXD2__UART2_TXD_MUX,
+	MX35_PAD_RXD2__UART2_RXD_MUX,
+	/* FEC */
+	MX35_PAD_FEC_TX_CLK__FEC_TX_CLK,
+	MX35_PAD_FEC_RX_CLK__FEC_RX_CLK,
+	MX35_PAD_FEC_RX_DV__FEC_RX_DV,
+	MX35_PAD_FEC_COL__FEC_COL,
+	MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
+	MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
+	MX35_PAD_FEC_TX_EN__FEC_TX_EN,
+	MX35_PAD_FEC_MDC__FEC_MDC,
+	MX35_PAD_FEC_MDIO__FEC_MDIO,
+	MX35_PAD_FEC_TX_ERR__FEC_TX_ERR,
+	MX35_PAD_FEC_RX_ERR__FEC_RX_ERR,
+	MX35_PAD_FEC_CRS__FEC_CRS,
+	MX35_PAD_FEC_RDATA1__FEC_RDATA_1,
+	MX35_PAD_FEC_TDATA1__FEC_TDATA_1,
+	MX35_PAD_FEC_RDATA2__FEC_RDATA_2,
+	MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
+	MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
+	MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
+	/* I2C1 */
+	MX35_PAD_I2C1_CLK__I2C1_SCL,
+	MX35_PAD_I2C1_DAT__I2C1_SDA,
+	/* Display */
+	MX35_PAD_LD0__IPU_DISPB_DAT_0,
+	MX35_PAD_LD1__IPU_DISPB_DAT_1,
+	MX35_PAD_LD2__IPU_DISPB_DAT_2,
+	MX35_PAD_LD3__IPU_DISPB_DAT_3,
+	MX35_PAD_LD4__IPU_DISPB_DAT_4,
+	MX35_PAD_LD5__IPU_DISPB_DAT_5,
+	MX35_PAD_LD6__IPU_DISPB_DAT_6,
+	MX35_PAD_LD7__IPU_DISPB_DAT_7,
+	MX35_PAD_LD8__IPU_DISPB_DAT_8,
+	MX35_PAD_LD9__IPU_DISPB_DAT_9,
+	MX35_PAD_LD10__IPU_DISPB_DAT_10,
+	MX35_PAD_LD11__IPU_DISPB_DAT_11,
+	MX35_PAD_LD12__IPU_DISPB_DAT_12,
+	MX35_PAD_LD13__IPU_DISPB_DAT_13,
+	MX35_PAD_LD14__IPU_DISPB_DAT_14,
+	MX35_PAD_LD15__IPU_DISPB_DAT_15,
+	MX35_PAD_LD16__IPU_DISPB_DAT_16,
+	MX35_PAD_LD17__IPU_DISPB_DAT_17,
+	MX35_PAD_D3_HSYNC__IPU_DISPB_D3_HSYNC,
+	MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK,
+	MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY,
+	MX35_PAD_CONTRAST__IPU_DISPB_CONTR,
+	MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC,
+	MX35_PAD_D3_REV__IPU_DISPB_D3_REV,
+	MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS,
+	/* gpio */
+	MX35_PAD_ATA_CS0__GPIO2_6,
+	/* USB host */
+	MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR,
+	MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC,
+	/* SSI */
+	MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS,
+	MX35_PAD_STXD4__AUDMUX_AUD4_TXD,
+	MX35_PAD_SRXD4__AUDMUX_AUD4_RXD,
+	MX35_PAD_SCK4__AUDMUX_AUD4_TXC,
+};
+
+#define AC97_GPIO_TXFS	(1 * 32 + 31)
+#define AC97_GPIO_TXD	(1 * 32 + 28)
+#define AC97_GPIO_RESET	(1 * 32 + 0)
+
+static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
+{
+	struct pad_desc txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
+	struct pad_desc txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS;
+	int ret;
+
+	ret = gpio_request(AC97_GPIO_TXFS, "SSI");
+	if (ret) {
+		printk("failed to get GPIO_TXFS: %d\n", ret);
+		return;
+	}
+
+	mxc_iomux_v3_setup_pad(&txfs_gpio);
+
+	/* warm reset */
+	gpio_direction_output(AC97_GPIO_TXFS, 1);
+	udelay(2);
+	gpio_set_value(AC97_GPIO_TXFS, 0);
+
+	gpio_free(AC97_GPIO_TXFS);
+	mxc_iomux_v3_setup_pad(&txfs);
+}
+
+static void pcm043_ac97_cold_reset(struct snd_ac97 *ac97)
+{
+	struct pad_desc txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
+	struct pad_desc txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS;
+	struct pad_desc txd_gpio = MX35_PAD_STXD4__GPIO2_28;
+	struct pad_desc txd = MX35_PAD_STXD4__AUDMUX_AUD4_TXD;
+	struct pad_desc reset_gpio = MX35_PAD_SD2_CMD__GPIO2_0;
+	int ret;
+
+	ret = gpio_request(AC97_GPIO_TXFS, "SSI");
+	if (ret)
+		goto err1;
+
+	ret = gpio_request(AC97_GPIO_TXD, "SSI");
+	if (ret)
+		goto err2;
+
+	ret = gpio_request(AC97_GPIO_RESET, "SSI");
+	if (ret)
+		goto err3;
+
+	mxc_iomux_v3_setup_pad(&txfs_gpio);
+	mxc_iomux_v3_setup_pad(&txd_gpio);
+	mxc_iomux_v3_setup_pad(&reset_gpio);
+
+	gpio_direction_output(AC97_GPIO_TXFS, 0);
+	gpio_direction_output(AC97_GPIO_TXD, 0);
+
+	/* cold reset */
+	gpio_direction_output(AC97_GPIO_RESET, 0);
+	udelay(10);
+	gpio_direction_output(AC97_GPIO_RESET, 1);
+
+	mxc_iomux_v3_setup_pad(&txd);
+	mxc_iomux_v3_setup_pad(&txfs);
+
+	gpio_free(AC97_GPIO_RESET);
+err3:
+	gpio_free(AC97_GPIO_TXD);
+err2:
+	gpio_free(AC97_GPIO_TXFS);
+err1:
+	if (ret)
+		printk("%s failed with %d\n", __func__, ret);
+	mdelay(1);
+}
+
+static struct imx_ssi_platform_data pcm043_ssi_pdata = {
+	.ac97_reset = pcm043_ac97_cold_reset,
+	.ac97_warm_reset = pcm043_ac97_warm_reset,
+	.flags = IMX_SSI_USE_AC97,
+};
+
+static struct mxc_nand_platform_data pcm037_nand_board_info = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
+static struct mxc_usbh_platform_data otg_pdata = {
+	.portsc	= MXC_EHCI_MODE_UTMI,
+	.flags	= MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static struct mxc_usbh_platform_data usbh1_pdata = {
+	.portsc	= MXC_EHCI_MODE_SERIAL,
+	.flags	= MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY |
+		  MXC_EHCI_IPPUE_DOWN,
+};
+
+static struct fsl_usb2_platform_data otg_device_pdata = {
+	.operating_mode = FSL_USB2_DR_DEVICE,
+	.phy_mode       = FSL_USB2_PHY_UTMI,
+};
+
+static int otg_mode_host;
+
+static int __init pcm043_otg_mode(char *options)
+{
+	if (!strcmp(options, "host"))
+		otg_mode_host = 1;
+	else if (!strcmp(options, "device"))
+		otg_mode_host = 0;
+	else
+		pr_info("otg_mode neither \"host\" nor \"device\". "
+			"Defaulting to device\n");
+	return 0;
+}
+__setup("otg_mode=", pcm043_otg_mode);
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+	mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads));
+
+	mxc_audmux_v2_configure_port(3,
+			MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
+			MXC_AUDMUX_V2_PTCR_TFSEL(0) |
+			MXC_AUDMUX_V2_PTCR_TFSDIR,
+			MXC_AUDMUX_V2_PDCR_RXDSEL(0));
+
+	mxc_audmux_v2_configure_port(0,
+			MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
+			MXC_AUDMUX_V2_PTCR_TCSEL(3) |
+			MXC_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
+			MXC_AUDMUX_V2_PDCR_RXDSEL(3));
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+	mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
+	mxc_register_device(&imx_ssi_device0, &pcm043_ssi_pdata);
+
+	mxc_register_device(&mxc_uart_device1, &uart_pdata);
+
+#if defined CONFIG_I2C_IMX || defined CONFIG_I2C_IMX_MODULE
+	i2c_register_board_info(0, pcm043_i2c_devices,
+			ARRAY_SIZE(pcm043_i2c_devices));
+
+	mxc_register_device(&mxc_i2c_device0, &pcm043_i2c_1_data);
+#endif
+
+	mxc_register_device(&mx3_ipu, &mx3_ipu_data);
+	mxc_register_device(&mx3_fb, &mx3fb_pdata);
+
+#if defined(CONFIG_USB_ULPI)
+	if (otg_mode_host) {
+		otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+				USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+		mxc_register_device(&mxc_otg_host, &otg_pdata);
+	}
+
+	mxc_register_device(&mxc_usbh1, &usbh1_pdata);
+#endif
+	if (!otg_mode_host)
+		mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
+
+}
+
+static void __init pcm043_timer_init(void)
+{
+	mx35_clocks_init();
+}
+
+struct sys_timer pcm043_timer = {
+	.init	= pcm043_timer_init,
+};
+
+MACHINE_START(PCM043, "Phytec Phycore pcm043")
+	/* Maintainer: Pengutronix */
+	.phys_io	= MX35_AIPS1_BASE_ADDR,
+	.io_pg_offst	= ((MX35_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = MX3x_PHYS_OFFSET + 0x100,
+	.map_io         = mx35_map_io,
+	.init_irq       = mx35_init_irq,
+	.init_machine   = mxc_board_init,
+	.timer          = &pcm043_timer,
+MACHINE_END
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-qong.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-qong.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mach-qong.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-qong.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,283 @@
+/*
+ *  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 		MX31_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[] = {
+	{
+		.name	= "dnet-memory",
+		.start	= QONG_DNET_BASEADDR,
+		.end	= QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.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 = MX31_CS0_BASE_ADDR,
+	.end = MX31_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  	= MX31_CS3_BASE_ADDR,
+	.end    	= MX31_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 */
+	mx31_setup_weimcs(3, 0x00004f00, 0x20013b31, 0x00020800);
+	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        = MX31_AIPS1_BASE_ADDR,
+	.io_pg_offst    = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+	.boot_params    = MX3x_PHYS_OFFSET + 0x100,
+	.map_io         = mx31_map_io,
+	.init_irq       = mx31_init_irq,
+	.init_machine   = mxc_board_init,
+	.timer          = &qong_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,18 +5,22 @@
 # Object file lists.
 
 obj-y				:= mm.o devices.o cpu.o
-obj-$(CONFIG_ARCH_MX31)		+= clock.o iomux.o
+CFLAGS_mm.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
+CFLAGS_devices.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
+CFLAGS_cpu.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
+obj-$(CONFIG_ARCH_MX31)		+= clock-imx31.o iomux-imx31.o
 obj-$(CONFIG_ARCH_MX35)		+= clock-imx35.o
-obj-$(CONFIG_MACH_MX31ADS)	+= mx31ads.o
-obj-$(CONFIG_MACH_MX31LILLY)	+= mx31lilly.o mx31lilly-db.o
-obj-$(CONFIG_MACH_MX31LITE)	+= mx31lite.o mx31lite-db.o
-obj-$(CONFIG_MACH_PCM037)	+= pcm037.o
-obj-$(CONFIG_MACH_PCM037_EET)	+= pcm037_eet.o
-obj-$(CONFIG_MACH_MX31_3DS)	+= mx31pdk.o
-obj-$(CONFIG_MACH_MX31MOBOARD)	+= mx31moboard.o mx31moboard-devboard.o \
-				   mx31moboard-marxbot.o
-obj-$(CONFIG_MACH_QONG)		+= qong.o
-obj-$(CONFIG_MACH_PCM043)	+= pcm043.o
-obj-$(CONFIG_MACH_ARMADILLO5X0) += armadillo5x0.o
-obj-$(CONFIG_MACH_MX35_3DS)	+= mx35pdk.o
-obj-$(CONFIG_MACH_KZM_ARM11_01)	+= kzmarm11.o
+obj-$(CONFIG_MACH_MX31ADS)	+= mach-mx31ads.o
+obj-$(CONFIG_MACH_MX31LILLY)	+= mach-mx31lilly.o mx31lilly-db.o
+obj-$(CONFIG_MACH_MX31LITE)	+= mach-mx31lite.o mx31lite-db.o
+obj-$(CONFIG_MACH_PCM037)	+= mach-pcm037.o
+obj-$(CONFIG_MACH_PCM037_EET)	+= mach-pcm037_eet.o
+obj-$(CONFIG_MACH_MX31_3DS)	+= mach-mx31_3ds.o
+CFLAGS_mach-mx31_3ds.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
+obj-$(CONFIG_MACH_MX31MOBOARD)	+= mach-mx31moboard.o mx31moboard-devboard.o \
+				   mx31moboard-marxbot.o mx31moboard-smartbot.o
+obj-$(CONFIG_MACH_QONG)		+= mach-qong.o
+obj-$(CONFIG_MACH_PCM043)	+= mach-pcm043.o
+obj-$(CONFIG_MACH_ARMADILLO5X0) += mach-armadillo5x0.o
+obj-$(CONFIG_MACH_MX35_3DS)	+= mach-mx35pdk.o
+obj-$(CONFIG_MACH_KZM_ARM11_01)	+= mach-kzm_arm11_01.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31ads.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31ads.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31ads.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31ads.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,555 +0,0 @@
-/*
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
- *  Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/types.h>
-#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>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/memory.h>
-#include <asm/mach/map.h>
-#include <mach/common.h>
-#include <mach/board-mx31ads.h>
-#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"
-
-/*!
- * @file mx31ads.c
- *
- * @brief This file contains the board-specific initialization routines.
- *
- * @ingroup System
- */
-
-#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
-/*!
- * The serial port definition structure.
- */
-static struct plat_serial8250_port serial_platform_data[] = {
-	{
-		.membase  = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA),
-		.mapbase  = (unsigned long)(CS4_BASE_ADDR + PBC_SC16C652_UARTA),
-		.irq      = EXPIO_INT_XUART_INTA,
-		.uartclk  = 14745600,
-		.regshift = 0,
-		.iotype   = UPIO_MEM,
-		.flags    = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
-	}, {
-		.membase  = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB),
-		.mapbase  = (unsigned long)(CS4_BASE_ADDR + PBC_SC16C652_UARTB),
-		.irq      = EXPIO_INT_XUART_INTB,
-		.uartclk  = 14745600,
-		.regshift = 0,
-		.iotype   = UPIO_MEM,
-		.flags    = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
-	},
-	{},
-};
-
-static struct platform_device serial_device = {
-	.name	= "serial8250",
-	.id	= 0,
-	.dev	= {
-		.platform_data = serial_platform_data,
-	},
-};
-
-static int __init mxc_init_extuart(void)
-{
-	return platform_device_register(&serial_device);
-}
-#else
-static inline int mxc_init_extuart(void)
-{
-	return 0;
-}
-#endif
-
-#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
-static struct imxuart_platform_data uart_pdata = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static 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_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0");
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-}
-#else /* !SERIAL_IMX */
-static inline void mxc_init_imx_uart(void)
-{
-}
-#endif /* !SERIAL_IMX */
-
-static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc)
-{
-	u32 imr_val;
-	u32 int_valid;
-	u32 expio_irq;
-
-	imr_val = __raw_readw(PBC_INTMASK_SET_REG);
-	int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val;
-
-	expio_irq = MXC_EXP_IO_BASE;
-	for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
-		if ((int_valid & 1) == 0)
-			continue;
-
-		generic_handle_irq(expio_irq);
-	}
-}
-
-/*
- * Disable an expio pin's interrupt by setting the bit in the imr.
- * @param irq           an expio virtual irq number
- */
-static void expio_mask_irq(u32 irq)
-{
-	u32 expio = MXC_IRQ_TO_EXPIO(irq);
-	/* mask the interrupt */
-	__raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG);
-	__raw_readw(PBC_INTMASK_CLEAR_REG);
-}
-
-/*
- * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
- * @param irq           an expanded io virtual irq number
- */
-static void expio_ack_irq(u32 irq)
-{
-	u32 expio = MXC_IRQ_TO_EXPIO(irq);
-	/* clear the interrupt status */
-	__raw_writew(1 << expio, PBC_INTSTATUS_REG);
-}
-
-/*
- * Enable a expio pin's interrupt by clearing the bit in the imr.
- * @param irq           a expio virtual irq number
- */
-static void expio_unmask_irq(u32 irq)
-{
-	u32 expio = MXC_IRQ_TO_EXPIO(irq);
-	/* unmask the interrupt */
-	__raw_writew(1 << expio, PBC_INTMASK_SET_REG);
-}
-
-static struct irq_chip expio_irq_chip = {
-	.name = "EXPIO(CPLD)",
-	.ack = expio_ack_irq,
-	.mask = expio_mask_irq,
-	.unmask = expio_unmask_irq,
-};
-
-static void __init mx31ads_init_expio(void)
-{
-	int i;
-
-	printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n");
-
-	/*
-	 * Configure INT line as GPIO input
-	 */
-	mxc_iomux_alloc_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);
-	__raw_writew(0xFFFF, PBC_INTSTATUS_REG);
-	for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
-	     i++) {
-		set_irq_chip(i, &expio_irq_chip);
-		set_irq_handler(i, handle_level_irq);
-		set_irq_flags(i, IRQF_VALID);
-	}
-	set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH);
-	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,
-		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
-		.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,
-		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
-		.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,
-	.irq_base = MXC_BOARD_IRQ_START + MXC_MAX_EXP_IO_LINES,
-};
-#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	= CS4_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(CS4_BASE_ADDR),
-		.length		= CS4_SIZE / 2,
-		.type		= MT_DEVICE
-	},
-};
-
-/*!
- * Set up static virtual mappings.
- */
-static void __init mx31ads_map_io(void)
-{
-	mx31_map_io();
-	iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc));
-}
-
-static void __init mx31ads_init_irq(void)
-{
-	mx31_init_irq();
-	mx31ads_init_expio();
-}
-
-/*!
- * Board specific initialization.
- */
-static void __init mxc_board_init(void)
-{
-	mxc_init_extuart();
-	mxc_init_imx_uart();
-	mxc_init_i2c();
-}
-
-static void __init mx31ads_timer_init(void)
-{
-	mx31_clocks_init(26000000);
-}
-
-static struct sys_timer mx31ads_timer = {
-	.init	= mx31ads_timer_init,
-};
-
-/*
- * The following uses standard kernel macros defined in arch.h in order to
- * initialize __mach_desc_MX31ADS data structure.
- */
-MACHINE_START(MX31ADS, "Freescale MX31ADS")
-	/* Maintainer: Freescale Semiconductor, Inc. */
-	.phys_io	= AIPS1_BASE_ADDR,
-	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx31ads_map_io,
-	.init_irq       = mx31ads_init_irq,
-	.init_machine   = mxc_board_init,
-	.timer          = &mx31ads_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31lilly.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31lilly.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31lilly.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31lilly.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,206 +0,0 @@
-/*
- *  LILLY-1131 module support
- *
- *    Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
- *
- *  based on code for other MX31 boards,
- *
- *    Copyright 2005-2007 Freescale Semiconductor
- *    Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
- *    Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/smsc911x.h>
-#include <linux/mtd/physmap.h>
-#include <linux/spi/spi.h>
-#include <linux/mfd/mc13783.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx3.h>
-#include <mach/board-mx31lilly.h>
-#include <mach/spi.h>
-
-#include "devices.h"
-
-/*
- * This file contains module-specific initialization routines for LILLY-1131.
- * Initialization of peripherals found on the baseboard is implemented in the
- * appropriate baseboard support code.
- */
-
-/* SMSC ethernet support */
-
-static struct resource smsc91x_resources[] = {
-	{
-		.start	= CS4_BASE_ADDR,
-		.end	= CS4_BASE_ADDR + 0xffff,
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.start	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
-		.end	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
-		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
-	}
-};
-
-static struct smsc911x_platform_config smsc911x_config = {
-	.phy_interface	= PHY_INTERFACE_MODE_MII,
-	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
-	.flags		= SMSC911X_USE_32BIT |
-			  SMSC911X_SAVE_MAC_ADDRESS |
-			  SMSC911X_FORCE_INTERNAL_PHY,
-};
-
-static struct platform_device smsc91x_device = {
-	.name		= "smsc911x",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(smsc91x_resources),
-	.resource	= smsc91x_resources,
-	.dev		= {
-		.platform_data = &smsc911x_config,
-	}
-};
-
-/* NOR flash */
-static struct physmap_flash_data nor_flash_data = {
-	.width  = 2,
-};
-
-static struct resource nor_flash_resource = {
-	.start	= 0xa0000000,
-	.end	= 0xa1ffffff,
-	.flags	= IORESOURCE_MEM,
-};
-
-static struct platform_device physmap_flash_device = {
-	.name	= "physmap-flash",
-	.id	= 0,
-	.dev	= {
-		.platform_data  = &nor_flash_data,
-	},
-	.resource = &nor_flash_resource,
-	.num_resources = 1,
-};
-
-static struct platform_device *devices[] __initdata = {
-	&smsc91x_device,
-	&physmap_flash_device,
-};
-
-/* SPI */
-
-static int spi_internal_chipselect[] = {
-	MXC_SPI_CS(0),
-	MXC_SPI_CS(1),
-	MXC_SPI_CS(2),
-};
-
-static struct spi_imx_master spi0_pdata = {
-	.chipselect = spi_internal_chipselect,
-	.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
-};
-
-static struct spi_imx_master spi1_pdata = {
-	.chipselect = spi_internal_chipselect,
-	.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
-};
-
-static struct mc13783_platform_data mc13783_pdata __initdata = {
-	.flags = MC13783_USE_RTC | MC13783_USE_TOUCHSCREEN,
-};
-
-static struct spi_board_info mc13783_dev __initdata = {
-	.modalias	= "mc13783",
-	.max_speed_hz	= 1000000,
-	.bus_num	= 1,
-	.chip_select	= 0,
-	.platform_data	= &mc13783_pdata,
-};
-
-static int mx31lilly_baseboard;
-core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444);
-
-static void __init mx31lilly_board_init(void)
-{
-	switch (mx31lilly_baseboard) {
-	case MX31LILLY_NOBOARD:
-		break;
-	case MX31LILLY_DB:
-		mx31lilly_db_init();
-		break;
-	default:
-		printk(KERN_ERR "Illegal mx31lilly_baseboard type %d\n",
-			mx31lilly_baseboard);
-	}
-
-	mxc_iomux_alloc_pin(MX31_PIN_CS4__CS4, "Ethernet CS");
-
-	/* SPI */
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SCLK__SCLK, "SPI1_CLK");
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MOSI__MOSI, "SPI1_TX");
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MISO__MISO, "SPI1_RX");
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, "SPI1_RDY");
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS0__SS0, "SPI1_SS0");
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS1__SS1, "SPI1_SS1");
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS2__SS2, "SPI1_SS2");
-
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SCLK__SCLK, "SPI2_CLK");
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MOSI__MOSI, "SPI2_TX");
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MISO__MISO, "SPI2_RX");
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, "SPI2_RDY");
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS0__SS0, "SPI2_SS0");
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS1__SS1, "SPI2_SS1");
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS2__SS2, "SPI2_SS2");
-
-	mxc_register_device(&mxc_spi_device0, &spi0_pdata);
-	mxc_register_device(&mxc_spi_device1, &spi1_pdata);
-	spi_register_board_info(&mc13783_dev, 1);
-
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-}
-
-static void __init mx31lilly_timer_init(void)
-{
-	mx31_clocks_init(26000000);
-}
-
-static struct sys_timer mx31lilly_timer = {
-	.init	= mx31lilly_timer_init,
-};
-
-MACHINE_START(LILLY1131, "INCO startec LILLY-1131")
-	.phys_io	= AIPS1_BASE_ADDR,
-	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params	= PHYS_OFFSET + 0x100,
-	.map_io		= mx31_map_io,
-	.init_irq	= mx31_init_irq,
-	.init_machine	= mx31lilly_board_init,
-	.timer		= &mx31lilly_timer,
-MACHINE_END
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31lite.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31lite.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31lite.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31lite.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,297 +0,0 @@
-/*
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
- *  Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- *  Copyright (C) 2009 Daniel Mack <daniel@caiaq.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You 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/gpio.h>
-#include <linux/smsc911x.h>
-#include <linux/mfd/mc13783.h>
-#include <linux/spi/spi.h>
-#include <linux/usb/otg.h>
-#include <linux/usb/ulpi.h>
-#include <linux/mtd/physmap.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/board-mx31lite.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux-mx3.h>
-#include <mach/irqs.h>
-#include <mach/mxc_nand.h>
-#include <mach/spi.h>
-#include <mach/mxc_ehci.h>
-#include <mach/ulpi.h>
-
-#include "devices.h"
-
-/*
- * This file contains the module-specific initialization routines.
- */
-
-static unsigned int mx31lite_pins[] = {
-	/* LAN9117 IRQ pin */
-	IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO),
-	/* SPI 1 */
-	MX31_PIN_CSPI2_SCLK__SCLK,
-	MX31_PIN_CSPI2_MOSI__MOSI,
-	MX31_PIN_CSPI2_MISO__MISO,
-	MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
-	MX31_PIN_CSPI2_SS0__SS0,
-	MX31_PIN_CSPI2_SS1__SS1,
-	MX31_PIN_CSPI2_SS2__SS2,
-};
-
-static struct mxc_nand_platform_data mx31lite_nand_board_info = {
-	.width = 1,
-	.hw_ecc = 1,
-};
-
-static struct smsc911x_platform_config smsc911x_config = {
-	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
-	.flags		= SMSC911X_USE_16BIT,
-};
-
-static struct resource smsc911x_resources[] = {
-	{
-		.start		= CS4_BASE_ADDR,
-		.end		= CS4_BASE_ADDR + 0x100,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IOMUX_TO_IRQ(MX31_PIN_SFS6),
-		.end		= IOMUX_TO_IRQ(MX31_PIN_SFS6),
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device smsc911x_device = {
-	.name		= "smsc911x",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(smsc911x_resources),
-	.resource	= smsc911x_resources,
-	.dev		= {
-		.platform_data = &smsc911x_config,
-	},
-};
-
-/*
- * SPI
- *
- * The MC13783 is the only hard-wired SPI device on the module.
- */
-
-static int spi_internal_chipselect[] = {
-	MXC_SPI_CS(0),
-};
-
-static struct spi_imx_master spi1_pdata = {
-	.chipselect	= spi_internal_chipselect,
-	.num_chipselect	= ARRAY_SIZE(spi_internal_chipselect),
-};
-
-static struct mc13783_platform_data mc13783_pdata __initdata = {
-	.flags  = MC13783_USE_RTC |
-		  MC13783_USE_REGULATOR,
-};
-
-static struct spi_board_info mc13783_spi_dev __initdata = {
-	.modalias       = "mc13783",
-	.max_speed_hz   = 1000000,
-	.bus_num	= 1,
-	.chip_select    = 0,
-	.platform_data  = &mc13783_pdata,
-	.irq		= IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
-};
-
-/*
- * USB
- */
-
-#if defined(CONFIG_USB_ULPI)
-#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
-			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
-
-static int usbh2_init(struct platform_device *pdev)
-{
-	int pins[] = {
-		MX31_PIN_USBH2_DATA0__USBH2_DATA0,
-		MX31_PIN_USBH2_DATA1__USBH2_DATA1,
-		MX31_PIN_USBH2_CLK__USBH2_CLK,
-		MX31_PIN_USBH2_DIR__USBH2_DIR,
-		MX31_PIN_USBH2_NXT__USBH2_NXT,
-		MX31_PIN_USBH2_STP__USBH2_STP,
-	};
-
-	mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H2");
-
-	mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
-
-	mxc_iomux_set_gpr(MUX_PGP_UH2, true);
-
-	/* chip select */
-	mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO),
-				"USBH2_CS");
-	gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), "USBH2 CS");
-	gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), 0);
-
-	return 0;
-}
-
-static struct mxc_usbh_platform_data usbh2_pdata = {
-	.init   = usbh2_init,
-	.portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
-	.flags  = MXC_EHCI_POWER_PINS_ENABLED,
-};
-#endif
-
-/*
- * NOR flash
- */
-
-static struct physmap_flash_data nor_flash_data = {
-	.width  = 2,
-};
-
-static struct resource nor_flash_resource = {
-	.start  = 0xa0000000,
-	.end    = 0xa1ffffff,
-	.flags  = IORESOURCE_MEM,
-};
-
-static struct platform_device physmap_flash_device = {
-	.name   = "physmap-flash",
-	.id     = 0,
-	.dev    = {
-		.platform_data  = &nor_flash_data,
-	},
-	.resource = &nor_flash_resource,
-	.num_resources = 1,
-};
-
-
-
-/*
- * This structure defines the MX31 memory map.
- */
-static struct map_desc mx31lite_io_desc[] __initdata = {
-	{
-		.virtual = CS4_BASE_ADDR_VIRT,
-		.pfn = __phys_to_pfn(CS4_BASE_ADDR),
-		.length = CS4_SIZE,
-		.type = MT_DEVICE
-	}
-};
-
-/*
- * Set up static virtual mappings.
- */
-void __init mx31lite_map_io(void)
-{
-	mx31_map_io();
-	iotable_init(mx31lite_io_desc, ARRAY_SIZE(mx31lite_io_desc));
-}
-
-static int mx31lite_baseboard;
-core_param(mx31lite_baseboard, mx31lite_baseboard, int, 0444);
-
-static void __init mxc_board_init(void)
-{
-	int ret;
-
-	switch (mx31lite_baseboard) {
-	case MX31LITE_NOBOARD:
-		break;
-	case MX31LITE_DB:
-		mx31lite_db_init();
-		break;
-	default:
-		printk(KERN_ERR "Illegal mx31lite_baseboard type %d\n",
-				mx31lite_baseboard);
-	}
-
-	mxc_iomux_setup_multiple_pins(mx31lite_pins, ARRAY_SIZE(mx31lite_pins),
-				      "mx31lite");
-
-	/* NOR and NAND flash */
-	platform_device_register(&physmap_flash_device);
-	mxc_register_device(&mxc_nand_device, &mx31lite_nand_board_info);
-
-	mxc_register_device(&mxc_spi_device1, &spi1_pdata);
-	spi_register_board_info(&mc13783_spi_dev, 1);
-
-#if defined(CONFIG_USB_ULPI)
-	/* USB */
-	usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
-				USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
-
-	mxc_register_device(&mxc_usbh2, &usbh2_pdata);
-#endif
-
-	/* SMSC9117 IRQ pin */
-	ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_SFS6), "sms9117-irq");
-	if (ret)
-		pr_warning("could not get LAN irq gpio\n");
-	else {
-		gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_SFS6));
-		platform_device_register(&smsc911x_device);
-	}
-}
-
-static void __init mx31lite_timer_init(void)
-{
-	mx31_clocks_init(26000000);
-}
-
-struct sys_timer mx31lite_timer = {
-	.init	= mx31lite_timer_init,
-};
-
-MACHINE_START(MX31LITE, "LogicPD i.MX31 SOM")
-	/* Maintainer: Freescale Semiconductor, Inc. */
-	.phys_io        = AIPS1_BASE_ADDR,
-	.io_pg_offst    = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx31lite_map_io,
-	.init_irq       = mx31_init_irq,
-	.init_machine   = mxc_board_init,
-	.timer          = &mx31lite_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31lite-db.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31lite-db.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31lite-db.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31lite-db.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,6 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
-#include <linux/platform_device.h>
 #include <linux/leds.h>
 #include <linux/platform_device.h>
 
@@ -67,6 +66,13 @@ static unsigned int litekit_db_board_pin
 	MX31_PIN_CSPI1_SS0__SS0,
 	MX31_PIN_CSPI1_SS1__SS1,
 	MX31_PIN_CSPI1_SS2__SS2,
+	/* SDHC1 */
+	MX31_PIN_SD1_DATA0__SD1_DATA0,
+	MX31_PIN_SD1_DATA1__SD1_DATA1,
+	MX31_PIN_SD1_DATA2__SD1_DATA2,
+	MX31_PIN_SD1_DATA3__SD1_DATA3,
+	MX31_PIN_SD1_CLK__SD1_CLK,
+	MX31_PIN_SD1_CMD__SD1_CMD,
 };
 
 /* UART */
@@ -79,11 +85,11 @@ static struct imxuart_platform_data uart
 static int gpio_det, gpio_wp;
 
 #define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
-			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+		     PAD_CTL_ODE_CMOS)
 
 static int mxc_mmc1_get_ro(struct device *dev)
 {
-	return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_LCS0));
+	return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_GPIO1_6));
 }
 
 static int mxc_mmc1_init(struct device *dev,
@@ -94,12 +100,17 @@ static int mxc_mmc1_init(struct device *
 	gpio_det = IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1);
 	gpio_wp = IOMUX_TO_GPIO(MX31_PIN_GPIO1_6);
 
-	mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, MMC_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, MMC_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, MMC_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA0,
+			  MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA1,
+			  MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA2,
+			  MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA3,
+			  MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+	mxc_iomux_set_pad(MX31_PIN_SD1_CMD,
+			  MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
 	mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SD1_CMD, MMC_PAD_CFG);
 
 	ret = gpio_request(gpio_det, "MMC detect");
 	if (ret)
@@ -113,7 +124,7 @@ static int mxc_mmc1_init(struct device *
 	gpio_direction_input(gpio_wp);
 
 	ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), detect_irq,
-			  IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+			  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 			  "MMC detect", data);
 	if (ret)
 		goto exit_free_wp;
@@ -133,7 +144,7 @@ static void mxc_mmc1_exit(struct device
 {
 	gpio_free(gpio_det);
 	gpio_free(gpio_wp);
-	free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), data);
+	free_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), data);
 }
 
 static struct imxmmc_platform_data mmc_pdata = {
@@ -194,5 +205,6 @@ void __init mx31lite_db_init(void)
 	mxc_register_device(&mxcsdhc_device0, &mmc_pdata);
 	mxc_register_device(&mxc_spi_device0, &spi0_pdata);
 	platform_device_register(&litekit_led_device);
+	mxc_register_device(&imx_wdt_device0, NULL);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31moboard.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31moboard.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31moboard.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31moboard.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,580 +0,0 @@
-/*
- *  Copyright (C) 2008 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/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/fsl_devices.h>
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/leds.h>
-#include <linux/memory.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mtd/partitions.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/machine.h>
-#include <linux/mfd/mc13783.h>
-#include <linux/spi/spi.h>
-#include <linux/types.h>
-
-#include <linux/usb/otg.h>
-#include <linux/usb/ulpi.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-#include <mach/board-mx31moboard.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux-mx3.h>
-#include <mach/ipu.h>
-#include <mach/i2c.h>
-#include <mach/mmc.h>
-#include <mach/mxc_ehci.h>
-#include <mach/mx3_camera.h>
-#include <mach/spi.h>
-#include <mach/ulpi.h>
-
-#include "devices.h"
-
-static unsigned int moboard_pins[] = {
-	/* UART0 */
-	MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1,
-	MX31_PIN_CTS1__GPIO2_7,
-	/* UART4 */
-	MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5,
-	MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5,
-	/* I2C0 */
-	MX31_PIN_I2C_DAT__I2C1_SDA, MX31_PIN_I2C_CLK__I2C1_SCL,
-	/* I2C1 */
-	MX31_PIN_DCD_DTE1__I2C2_SDA, MX31_PIN_RI_DTE1__I2C2_SCL,
-	/* SDHC1 */
-	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,
-	MX31_PIN_ATA_CS0__GPIO3_26, MX31_PIN_ATA_CS1__GPIO3_27,
-	/* USB reset */
-	MX31_PIN_GPIO1_0__GPIO1_0,
-	/* USB OTG */
-	MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
-	MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
-	MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
-	MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
-	MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
-	MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
-	MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
-	MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
-	MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR,
-	MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP,
-	MX31_PIN_USB_OC__GPIO1_30,
-	/* USB H2 */
-	MX31_PIN_USBH2_DATA0__USBH2_DATA0,
-	MX31_PIN_USBH2_DATA1__USBH2_DATA1,
-	MX31_PIN_STXD3__USBH2_DATA2, MX31_PIN_SRXD3__USBH2_DATA3,
-	MX31_PIN_SCK3__USBH2_DATA4, MX31_PIN_SFS3__USBH2_DATA5,
-	MX31_PIN_STXD6__USBH2_DATA6, MX31_PIN_SRXD6__USBH2_DATA7,
-	MX31_PIN_USBH2_CLK__USBH2_CLK, MX31_PIN_USBH2_DIR__USBH2_DIR,
-	MX31_PIN_USBH2_NXT__USBH2_NXT, MX31_PIN_USBH2_STP__USBH2_STP,
-	MX31_PIN_SCK6__GPIO1_25,
-	/* LEDs */
-	MX31_PIN_SVEN0__GPIO2_0, MX31_PIN_STX0__GPIO2_1,
-	MX31_PIN_SRX0__GPIO2_2, MX31_PIN_SIMPD0__GPIO2_3,
-	/* SEL */
-	MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9,
-	MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
-	/* SPI1 */
-	MX31_PIN_CSPI2_MOSI__MOSI, MX31_PIN_CSPI2_MISO__MISO,
-	MX31_PIN_CSPI2_SCLK__SCLK, MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
-	MX31_PIN_CSPI2_SS0__SS0, MX31_PIN_CSPI2_SS2__SS2,
-	/* Atlas IRQ */
-	MX31_PIN_GPIO1_3__GPIO1_3,
-	/* SPI2 */
-	MX31_PIN_CSPI3_MOSI__MOSI, MX31_PIN_CSPI3_MISO__MISO,
-	MX31_PIN_CSPI3_SCLK__SCLK, MX31_PIN_CSPI3_SPI_RDY__SPI_RDY,
-	MX31_PIN_CSPI2_SS1__CSPI3_SS1,
-};
-
-static struct physmap_flash_data mx31moboard_flash_data = {
-	.width  	= 2,
-};
-
-static struct resource mx31moboard_flash_resource = {
-	.start	= 0xa0000000,
-	.end	= 0xa1ffffff,
-	.flags	= IORESOURCE_MEM,
-};
-
-static struct platform_device mx31moboard_flash = {
-	.name	= "physmap-flash",
-	.id	= 0,
-	.dev	= {
-		.platform_data  = &mx31moboard_flash_data,
-	},
-	.resource = &mx31moboard_flash_resource,
-	.num_resources = 1,
-};
-
-static int moboard_uart0_init(struct platform_device *pdev)
-{
-	gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack");
-	gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0);
-	return 0;
-}
-
-static struct imxuart_platform_data uart0_pdata = {
-	.init = moboard_uart0_init,
-};
-
-static struct imxuart_platform_data uart4_pdata = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct imxi2c_platform_data moboard_i2c0_pdata = {
-	.bitrate = 400000,
-};
-
-static struct imxi2c_platform_data moboard_i2c1_pdata = {
-	.bitrate = 100000,
-};
-
-static int moboard_spi1_cs[] = {
-	MXC_SPI_CS(0),
-	MXC_SPI_CS(2),
-};
-
-static struct spi_imx_master moboard_spi1_master = {
-	.chipselect	= moboard_spi1_cs,
-	.num_chipselect	= ARRAY_SIZE(moboard_spi1_cs),
-};
-
-static struct regulator_consumer_supply sdhc_consumers[] = {
-	{
-		.dev	= &mxcsdhc_device0.dev,
-		.supply	= "sdhc0_vcc",
-	},
-	{
-		.dev	= &mxcsdhc_device1.dev,
-		.supply	= "sdhc1_vcc",
-	},
-};
-
-static struct regulator_init_data sdhc_vreg_data = {
-	.constraints = {
-		.min_uV = 2700000,
-		.max_uV = 3000000,
-		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
-			REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
-		.valid_modes_mask = REGULATOR_MODE_NORMAL |
-			REGULATOR_MODE_FAST,
-		.always_on = 0,
-		.boot_on = 1,
-	},
-	.num_consumer_supplies = ARRAY_SIZE(sdhc_consumers),
-	.consumer_supplies = sdhc_consumers,
-};
-
-static struct regulator_consumer_supply cam_consumers[] = {
-	{
-		.dev	= &mx3_camera.dev,
-		.supply	= "cam_vcc",
-	},
-};
-
-static struct regulator_init_data cam_vreg_data = {
-	.constraints = {
-		.min_uV = 2700000,
-		.max_uV = 3000000,
-		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
-			REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
-		.valid_modes_mask = REGULATOR_MODE_NORMAL |
-			REGULATOR_MODE_FAST,
-		.always_on = 0,
-		.boot_on = 1,
-	},
-	.num_consumer_supplies = ARRAY_SIZE(cam_consumers),
-	.consumer_supplies = cam_consumers,
-};
-
-static struct mc13783_regulator_init_data moboard_regulators[] = {
-	{
-		.id = MC13783_REGU_VMMC1,
-		.init_data = &sdhc_vreg_data,
-	},
-	{
-		.id = MC13783_REGU_VCAM,
-		.init_data = &cam_vreg_data,
-	},
-};
-
-static struct mc13783_platform_data moboard_pmic = {
-	.regulators = moboard_regulators,
-	.num_regulators = ARRAY_SIZE(moboard_regulators),
-	.flags = MC13783_USE_REGULATOR | MC13783_USE_RTC |
-		MC13783_USE_ADC,
-};
-
-static struct spi_board_info moboard_spi_board_info[] __initdata = {
-	{
-		.modalias = "mc13783",
-		.irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
-		.max_speed_hz = 300000,
-		.bus_num = 1,
-		.chip_select = 0,
-		.platform_data = &moboard_pmic,
-		.mode = SPI_CS_HIGH,
-	},
-};
-
-static int moboard_spi2_cs[] = {
-	MXC_SPI_CS(1),
-};
-
-static struct spi_imx_master moboard_spi2_master = {
-	.chipselect	= moboard_spi2_cs,
-	.num_chipselect	= ARRAY_SIZE(moboard_spi2_cs),
-};
-
-#define SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_ATA_CS0)
-#define SDHC1_WP IOMUX_TO_GPIO(MX31_PIN_ATA_CS1)
-
-static int moboard_sdhc1_get_ro(struct device *dev)
-{
-	return !gpio_get_value(SDHC1_WP);
-}
-
-static int moboard_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
-		void *data)
-{
-	int ret;
-
-	ret = gpio_request(SDHC1_CD, "sdhc-detect");
-	if (ret)
-		return ret;
-
-	gpio_direction_input(SDHC1_CD);
-
-	ret = gpio_request(SDHC1_WP, "sdhc-wp");
-	if (ret)
-		goto err_gpio_free;
-	gpio_direction_input(SDHC1_WP);
-
-	ret = request_irq(gpio_to_irq(SDHC1_CD), detect_irq,
-		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-		"sdhc1-card-detect", data);
-	if (ret)
-		goto err_gpio_free_2;
-
-	return 0;
-
-err_gpio_free_2:
-	gpio_free(SDHC1_WP);
-err_gpio_free:
-	gpio_free(SDHC1_CD);
-
-	return ret;
-}
-
-static void moboard_sdhc1_exit(struct device *dev, void *data)
-{
-	free_irq(gpio_to_irq(SDHC1_CD), data);
-	gpio_free(SDHC1_WP);
-	gpio_free(SDHC1_CD);
-}
-
-static struct imxmmc_platform_data sdhc1_pdata = {
-	.get_ro	= moboard_sdhc1_get_ro,
-	.init	= moboard_sdhc1_init,
-	.exit	= moboard_sdhc1_exit,
-};
-
-/*
- * this pin is dedicated for all mx31moboard systems, so we do it here
- */
-#define USB_RESET_B	IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)
-
-static void usb_xcvr_reset(void)
-{
-	gpio_request(USB_RESET_B, "usb-reset");
-	gpio_direction_output(USB_RESET_B, 0);
-	mdelay(1);
-	gpio_set_value(USB_RESET_B, 1);
-}
-
-#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
-			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
-
-#define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC)
-
-static void moboard_usbotg_init(void)
-{
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
-
-	gpio_request(OTG_EN_B, "usb-udc-en");
-	gpio_direction_output(OTG_EN_B, 0);
-}
-
-static struct fsl_usb2_platform_data usb_pdata = {
-	.operating_mode	= FSL_USB2_DR_DEVICE,
-	.phy_mode	= FSL_USB2_PHY_ULPI,
-};
-
-#if defined(CONFIG_USB_ULPI)
-
-#define USBH2_EN_B IOMUX_TO_GPIO(MX31_PIN_SCK6)
-
-static int moboard_usbh2_hw_init(struct platform_device *pdev)
-{
-	int ret = gpio_request(USBH2_EN_B, "usbh2-en");
-	if (ret)
-		return ret;
-
-	mxc_iomux_set_gpr(MUX_PGP_UH2, true);
-
-	mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
-
-	gpio_direction_output(USBH2_EN_B, 0);
-
-	return 0;
-}
-
-static int moboard_usbh2_hw_exit(struct platform_device *pdev)
-{
-	gpio_free(USBH2_EN_B);
-	return 0;
-}
-
-static struct mxc_usbh_platform_data usbh2_pdata = {
-	.init	= moboard_usbh2_hw_init,
-	.exit	= moboard_usbh2_hw_exit,
-	.portsc	= MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
-	.flags	= MXC_EHCI_POWER_PINS_ENABLED,
-};
-
-static int __init moboard_usbh2_init(void)
-{
-	usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
-			USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
-
-	return mxc_register_device(&mxc_usbh2, &usbh2_pdata);
-}
-#else
-static inline int moboard_usbh2_init(void) { return 0; }
-#endif
-
-
-static struct gpio_led mx31moboard_leds[] = {
-	{
-		.name 	= "coreboard-led-0:red:running",
-		.default_trigger = "heartbeat",
-		.gpio 	= IOMUX_TO_GPIO(MX31_PIN_SVEN0),
-	}, {
-		.name	= "coreboard-led-1:red",
-		.gpio	= IOMUX_TO_GPIO(MX31_PIN_STX0),
-	}, {
-		.name	= "coreboard-led-2:red",
-		.gpio	= IOMUX_TO_GPIO(MX31_PIN_SRX0),
-	}, {
-		.name	= "coreboard-led-3:red",
-		.gpio	= IOMUX_TO_GPIO(MX31_PIN_SIMPD0),
-	},
-};
-
-static struct gpio_led_platform_data mx31moboard_led_pdata = {
-	.num_leds 	= ARRAY_SIZE(mx31moboard_leds),
-	.leds		= mx31moboard_leds,
-};
-
-static struct platform_device mx31moboard_leds_device = {
-	.name	= "leds-gpio",
-	.id	= -1,
-	.dev	= {
-		.platform_data = &mx31moboard_led_pdata,
-	},
-};
-
-#define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
-#define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
-#define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1)
-#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
-
-static void mx31moboard_init_sel_gpios(void)
-{
-	if (!gpio_request(SEL0, "sel0")) {
-		gpio_direction_input(SEL0);
-		gpio_export(SEL0, true);
-	}
-
-	if (!gpio_request(SEL1, "sel1")) {
-		gpio_direction_input(SEL1);
-		gpio_export(SEL1, true);
-	}
-
-	if (!gpio_request(SEL2, "sel2")) {
-		gpio_direction_input(SEL2);
-		gpio_export(SEL2, true);
-	}
-
-	if (!gpio_request(SEL3, "sel3")) {
-		gpio_direction_input(SEL3);
-		gpio_export(SEL3, true);
-	}
-}
-
-static struct ipu_platform_data mx3_ipu_data = {
-	.irq_base = MXC_IPU_IRQ_START,
-};
-
-static struct platform_device *devices[] __initdata = {
-	&mx31moboard_flash,
-	&mx31moboard_leds_device,
-};
-
-static struct mx3_camera_pdata camera_pdata = {
-	.dma_dev	= &mx3_ipu.dev,
-	.flags		= MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10,
-	.mclk_10khz	= 4800,
-};
-
-#define CAMERA_BUF_SIZE	(4*1024*1024)
-
-static int __init mx31moboard_cam_alloc_dma(const size_t buf_size)
-{
-	dma_addr_t dma_handle;
-	void *buf;
-	int dma;
-
-	if (buf_size < 2 * 1024 * 1024)
-		return -EINVAL;
-
-	buf = dma_alloc_coherent(NULL, buf_size, &dma_handle, GFP_KERNEL);
-	if (!buf) {
-		pr_err("%s: cannot allocate camera buffer-memory\n", __func__);
-		return -ENOMEM;
-	}
-
-	memset(buf, 0, buf_size);
-
-	dma = dma_declare_coherent_memory(&mx3_camera.dev,
-					dma_handle, dma_handle, buf_size,
-					DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
-
-	/* The way we call dma_declare_coherent_memory only a malloc can fail */
-	return dma & DMA_MEMORY_MAP ? 0 : -ENOMEM;
-}
-
-static int mx31moboard_baseboard;
-core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
-
-/*
- * Board specific initialization.
- */
-static void __init mxc_board_init(void)
-{
-	mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins),
-		"moboard");
-
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-
-	mxc_register_device(&mxc_uart_device0, &uart0_pdata);
-
-	mxc_register_device(&mxc_uart_device4, &uart4_pdata);
-
-	mx31moboard_init_sel_gpios();
-
-	mxc_register_device(&mxc_i2c_device0, &moboard_i2c0_pdata);
-	mxc_register_device(&mxc_i2c_device1, &moboard_i2c1_pdata);
-
-	mxc_register_device(&mxc_spi_device1, &moboard_spi1_master);
-	mxc_register_device(&mxc_spi_device2, &moboard_spi2_master);
-
-	gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3), "pmic-irq");
-	gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3));
-	spi_register_board_info(moboard_spi_board_info,
-		ARRAY_SIZE(moboard_spi_board_info));
-
-	mxc_register_device(&mxcsdhc_device0, &sdhc1_pdata);
-
-	mxc_register_device(&mx3_ipu, &mx3_ipu_data);
-	if (!mx31moboard_cam_alloc_dma(CAMERA_BUF_SIZE))
-		mxc_register_device(&mx3_camera, &camera_pdata);
-
-	usb_xcvr_reset();
-
-	moboard_usbotg_init();
-	mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
-	moboard_usbh2_init();
-
-	switch (mx31moboard_baseboard) {
-	case MX31NOBOARD:
-		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)
-{
-	mx31_clocks_init(26000000);
-}
-
-struct sys_timer mx31moboard_timer = {
-	.init	= mx31moboard_timer_init,
-};
-
-MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
-	/* Maintainer: Valentin Longchamp, EPFL Mobots group */
-	.phys_io	= AIPS1_BASE_ADDR,
-	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx31_map_io,
-	.init_irq       = mx31_init_irq,
-	.init_machine   = mxc_board_init,
-	.timer          = &mx31moboard_timer,
-MACHINE_END
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31moboard-devboard.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31moboard-devboard.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31moboard-devboard.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31moboard-devboard.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include <linux/usb/otg.h>
@@ -49,6 +50,9 @@ static unsigned int devboard_pins[] = {
 	MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB,
 	MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND,
 	MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12,
+	/* SEL */
+	MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9,
+	MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
 };
 
 static struct imxuart_platform_data uart_pdata = {
@@ -108,6 +112,33 @@ static struct imxmmc_platform_data sdhc2
 	.exit	= devboard_sdhc2_exit,
 };
 
+#define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
+#define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
+#define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1)
+#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
+
+static void devboard_init_sel_gpios(void)
+{
+	if (!gpio_request(SEL0, "sel0")) {
+		gpio_direction_input(SEL0);
+		gpio_export(SEL0, true);
+	}
+
+	if (!gpio_request(SEL1, "sel1")) {
+		gpio_direction_input(SEL1);
+		gpio_export(SEL1, true);
+	}
+
+	if (!gpio_request(SEL2, "sel2")) {
+		gpio_direction_input(SEL2);
+		gpio_export(SEL2, true);
+	}
+
+	if (!gpio_request(SEL3, "sel3")) {
+		gpio_direction_input(SEL3);
+		gpio_export(SEL3, true);
+	}
+}
 #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
 			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
 
@@ -196,5 +227,7 @@ void __init mx31moboard_devboard_init(vo
 
 	mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata);
 
+	devboard_init_sel_gpios();
+
 	devboard_usbh1_init();
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31moboard-marxbot.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31moboard-marxbot.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31moboard-marxbot.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31moboard-marxbot.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/types.h>
 
@@ -66,6 +67,9 @@ static unsigned int marxbot_pins[] = {
 	MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB,
 	MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND,
 	MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12,
+	/* SEL */
+	MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9,
+	MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
 };
 
 #define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR)
@@ -127,12 +131,12 @@ static struct imxmmc_platform_data sdhc2
 static void dspics_resets_init(void)
 {
 	if (!gpio_request(TRSLAT_RST_B, "translator-rst")) {
-		gpio_direction_output(TRSLAT_RST_B, 1);
+		gpio_direction_output(TRSLAT_RST_B, 0);
 		gpio_export(TRSLAT_RST_B, false);
 	}
 
 	if (!gpio_request(DSPICS_RST_B, "dspics-rst")) {
-		gpio_direction_output(DSPICS_RST_B, 1);
+		gpio_direction_output(DSPICS_RST_B, 0);
 		gpio_export(DSPICS_RST_B, false);
 	}
 }
@@ -200,7 +204,7 @@ static int __init marxbot_cam_init(void)
 	int ret = gpio_request(CAM_CHOICE, "cam-choice");
 	if (ret)
 		return ret;
-	gpio_direction_output(CAM_CHOICE, 1);
+	gpio_direction_output(CAM_CHOICE, 0);
 
 	ret = gpio_request(BASECAM_RST_B, "basecam-reset");
 	if (ret)
@@ -223,6 +227,34 @@ static int __init marxbot_cam_init(void)
 	return 0;
 }
 
+#define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
+#define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
+#define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1)
+#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
+
+static void marxbot_init_sel_gpios(void)
+{
+	if (!gpio_request(SEL0, "sel0")) {
+		gpio_direction_input(SEL0);
+		gpio_export(SEL0, true);
+	}
+
+	if (!gpio_request(SEL1, "sel1")) {
+		gpio_direction_input(SEL1);
+		gpio_export(SEL1, true);
+	}
+
+	if (!gpio_request(SEL2, "sel2")) {
+		gpio_direction_input(SEL2);
+		gpio_export(SEL2, true);
+	}
+
+	if (!gpio_request(SEL3, "sel3")) {
+		gpio_direction_input(SEL3);
+		gpio_export(SEL3, true);
+	}
+}
+
 #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
 			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
 
@@ -307,6 +339,8 @@ void __init mx31moboard_marxbot_init(voi
 	mxc_iomux_setup_multiple_pins(marxbot_pins, ARRAY_SIZE(marxbot_pins),
 		"marxbot");
 
+	marxbot_init_sel_gpios();
+
 	dspics_resets_init();
 
 	mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31moboard-smartbot.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31moboard-smartbot.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31moboard-smartbot.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31moboard-smartbot.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,162 @@
+/*
+ * 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/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+
+#include <media/soc_camera.h>
+
+#include "devices.h"
+
+static unsigned int smartbot_pins[] = {
+	/* UART1 */
+	MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2,
+	MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2,
+	/* CSI */
+	MX31_PIN_CSI_D4__CSI_D4, MX31_PIN_CSI_D5__CSI_D5,
+	MX31_PIN_CSI_D6__CSI_D6, MX31_PIN_CSI_D7__CSI_D7,
+	MX31_PIN_CSI_D8__CSI_D8, MX31_PIN_CSI_D9__CSI_D9,
+	MX31_PIN_CSI_D10__CSI_D10, MX31_PIN_CSI_D11__CSI_D11,
+	MX31_PIN_CSI_D12__CSI_D12, MX31_PIN_CSI_D13__CSI_D13,
+	MX31_PIN_CSI_D14__CSI_D14, MX31_PIN_CSI_D15__CSI_D15,
+	MX31_PIN_CSI_HSYNC__CSI_HSYNC, MX31_PIN_CSI_MCLK__CSI_MCLK,
+	MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, MX31_PIN_CSI_VSYNC__CSI_VSYNC,
+	MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1,
+	/* ENABLES */
+	MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9,
+	MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
+};
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+#define CAM_POWER	IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)
+#define CAM_RST_B	IOMUX_TO_GPIO(MX31_PIN_GPIO3_0)
+
+static int smartbot_cam_power(struct device *dev, int on)
+{
+	gpio_set_value(CAM_POWER, !on);
+	return 0;
+}
+
+static int smartbot_cam_reset(struct device *dev)
+{
+	gpio_set_value(CAM_RST_B, 0);
+	udelay(100);
+	gpio_set_value(CAM_RST_B, 1);
+	return 0;
+}
+
+static struct i2c_board_info smartbot_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("mt9t031", 0x5d),
+	},
+};
+
+static struct soc_camera_link base_iclink = {
+	.bus_id		= 0,		/* Must match with the camera ID */
+	.power		= smartbot_cam_power,
+	.reset		= smartbot_cam_reset,
+	.board_info	= &smartbot_i2c_devices[0],
+	.i2c_adapter_id	= 0,
+	.module_name	= "mt9t031",
+};
+
+static struct platform_device smartbot_camera[] = {
+	{
+		.name	= "soc-camera-pdrv",
+		.id	= 0,
+		.dev	= {
+			.platform_data = &base_iclink,
+		},
+	},
+};
+
+static struct platform_device *smartbot_cameras[] __initdata = {
+	&smartbot_camera[0],
+};
+
+static int __init smartbot_cam_init(void)
+{
+	int ret = gpio_request(CAM_RST_B, "cam-reset");
+	if (ret)
+		return ret;
+	gpio_direction_output(CAM_RST_B, 1);
+	ret = gpio_request(CAM_POWER, "cam-standby");
+	if (ret)
+		return ret;
+	gpio_direction_output(CAM_POWER, 0);
+
+	return 0;
+}
+
+#define POWER_EN IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
+#define DSPIC_RST_B IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
+#define TRSLAT_RST_B IOMUX_TO_GPIO(MX31_PIN_RI_DCE1)
+#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
+
+static void smartbot_resets_init(void)
+{
+	if (!gpio_request(POWER_EN, "power-enable")) {
+		gpio_direction_output(POWER_EN, 0);
+		gpio_export(POWER_EN, false);
+	}
+
+	if (!gpio_request(DSPIC_RST_B, "dspic-rst")) {
+		gpio_direction_output(DSPIC_RST_B, 0);
+		gpio_export(DSPIC_RST_B, false);
+	}
+
+	if (!gpio_request(TRSLAT_RST_B, "translator-rst")) {
+		gpio_direction_output(TRSLAT_RST_B, 0);
+		gpio_export(TRSLAT_RST_B, false);
+	}
+
+	if (!gpio_request(SEL3, "sel3")) {
+		gpio_direction_input(SEL3);
+		gpio_export(SEL3, true);
+	}
+}
+/*
+ * system init for baseboard usage. Will be called by mx31moboard init.
+ */
+void __init mx31moboard_smartbot_init(void)
+{
+	printk(KERN_INFO "Initializing mx31smartbot peripherals\n");
+
+	mxc_iomux_setup_multiple_pins(smartbot_pins, ARRAY_SIZE(smartbot_pins),
+		"smartbot");
+
+	mxc_register_device(&mxc_uart_device1, &uart_pdata);
+
+	smartbot_resets_init();
+
+	smartbot_cam_init();
+	platform_add_devices(smartbot_cameras, ARRAY_SIZE(smartbot_cameras));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31pdk.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31pdk.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31pdk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx31pdk.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,266 +0,0 @@
-/*
- *  Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/smsc911x.h>
-#include <linux/platform_device.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/memory.h>
-#include <asm/mach/map.h>
-#include <mach/common.h>
-#include <mach/board-mx31pdk.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux-mx3.h>
-#include "devices.h"
-
-/*!
- * @file mx31pdk.c
- *
- * @brief This file contains the board-specific initialization routines.
- *
- * @ingroup System
- */
-
-static int mx31pdk_pins[] = {
-	/* UART1 */
-	MX31_PIN_CTS1__CTS1,
-	MX31_PIN_RTS1__RTS1,
-	MX31_PIN_TXD1__TXD1,
-	MX31_PIN_RXD1__RXD1,
-	IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO),
-};
-
-static struct imxuart_platform_data uart_pdata = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-/*
- * Support for the SMSC9217 on the Debug board.
- */
-
-static struct smsc911x_platform_config smsc911x_config = {
-	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
-	.flags		= SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
-	.phy_interface	= PHY_INTERFACE_MODE_MII,
-};
-
-static struct resource smsc911x_resources[] = {
-	{
-		.start		= LAN9217_BASE_ADDR,
-		.end		= LAN9217_BASE_ADDR + 0xff,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= EXPIO_INT_ENET,
-		.end		= EXPIO_INT_ENET,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device smsc911x_device = {
-	.name		= "smsc911x",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(smsc911x_resources),
-	.resource	= smsc911x_resources,
-	.dev		= {
-		.platform_data = &smsc911x_config,
-	},
-};
-
-/*
- * Routines for the CPLD on the debug board. It contains a CPLD handling
- * LEDs, switches, interrupts for Ethernet.
- */
-
-static void mx31pdk_expio_irq_handler(uint32_t irq, struct irq_desc *desc)
-{
-	uint32_t imr_val;
-	uint32_t int_valid;
-	uint32_t expio_irq;
-
-	imr_val = __raw_readw(CPLD_INT_MASK_REG);
-	int_valid = __raw_readw(CPLD_INT_STATUS_REG) & ~imr_val;
-
-	expio_irq = MXC_EXP_IO_BASE;
-	for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
-		if ((int_valid & 1) == 0)
-			continue;
-		generic_handle_irq(expio_irq);
-	}
-}
-
-/*
- * Disable an expio pin's interrupt by setting the bit in the imr.
- * @param irq           an expio virtual irq number
- */
-static void expio_mask_irq(uint32_t irq)
-{
-	uint16_t reg;
-	uint32_t expio = MXC_IRQ_TO_EXPIO(irq);
-
-	/* mask the interrupt */
-	reg = __raw_readw(CPLD_INT_MASK_REG);
-	reg |= 1 << expio;
-	__raw_writew(reg, CPLD_INT_MASK_REG);
-}
-
-/*
- * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
- * @param irq           an expanded io virtual irq number
- */
-static void expio_ack_irq(uint32_t irq)
-{
-	uint32_t expio = MXC_IRQ_TO_EXPIO(irq);
-
-	/* clear the interrupt status */
-	__raw_writew(1 << expio, CPLD_INT_RESET_REG);
-	__raw_writew(0, CPLD_INT_RESET_REG);
-	/* mask the interrupt */
-	expio_mask_irq(irq);
-}
-
-/*
- * Enable a expio pin's interrupt by clearing the bit in the imr.
- * @param irq           a expio virtual irq number
- */
-static void expio_unmask_irq(uint32_t irq)
-{
-	uint16_t reg;
-	uint32_t expio = MXC_IRQ_TO_EXPIO(irq);
-
-	/* unmask the interrupt */
-	reg = __raw_readw(CPLD_INT_MASK_REG);
-	reg &= ~(1 << expio);
-	__raw_writew(reg, CPLD_INT_MASK_REG);
-}
-
-static struct irq_chip expio_irq_chip = {
-	.ack = expio_ack_irq,
-	.mask = expio_mask_irq,
-	.unmask = expio_unmask_irq,
-};
-
-static int __init mx31pdk_init_expio(void)
-{
-	int i;
-	int ret;
-
-	/* Check if there's a debug board connected */
-	if ((__raw_readw(CPLD_MAGIC_NUMBER1_REG) != 0xAAAA) ||
-	    (__raw_readw(CPLD_MAGIC_NUMBER2_REG) != 0x5555) ||
-	    (__raw_readw(CPLD_MAGIC_NUMBER3_REG) != 0xCAFE)) {
-		/* No Debug board found */
-		return -ENODEV;
-	}
-
-	pr_info("i.MX31PDK Debug board detected, rev = 0x%04X\n",
-		__raw_readw(CPLD_CODE_VER_REG));
-
-	/*
-	 * Configure INT line as GPIO input
-	 */
-	ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1), "sms9217-irq");
-	if (ret)
-		pr_warning("could not get LAN irq gpio\n");
-	else
-		gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1));
-
-	/* Disable the interrupts and clear the status */
-	__raw_writew(0, CPLD_INT_MASK_REG);
-	__raw_writew(0xFFFF, CPLD_INT_RESET_REG);
-	__raw_writew(0, CPLD_INT_RESET_REG);
-	__raw_writew(0x1F, CPLD_INT_MASK_REG);
-	for (i = MXC_EXP_IO_BASE;
-	     i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
-	     i++) {
-		set_irq_chip(i, &expio_irq_chip);
-		set_irq_handler(i, handle_level_irq);
-		set_irq_flags(i, IRQF_VALID);
-	}
-	set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW);
-	set_irq_chained_handler(EXPIO_PARENT_INT, mx31pdk_expio_irq_handler);
-
-	return 0;
-}
-
-/*
- * This structure defines the MX31 memory map.
- */
-static struct map_desc mx31pdk_io_desc[] __initdata = {
-	{
-		.virtual = CS5_BASE_ADDR_VIRT,
-		.pfn = __phys_to_pfn(CS5_BASE_ADDR),
-		.length = CS5_SIZE,
-		.type = MT_DEVICE,
-	},
-};
-
-/*
- * Set up static virtual mappings.
- */
-static void __init mx31pdk_map_io(void)
-{
-	mx31_map_io();
-	iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc));
-}
-
-/*!
- * Board specific initialization.
- */
-static void __init mxc_board_init(void)
-{
-	mxc_iomux_setup_multiple_pins(mx31pdk_pins, ARRAY_SIZE(mx31pdk_pins),
-				      "mx31pdk");
-
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-
-	if (!mx31pdk_init_expio())
-		platform_device_register(&smsc911x_device);
-}
-
-static void __init mx31pdk_timer_init(void)
-{
-	mx31_clocks_init(26000000);
-}
-
-static struct sys_timer mx31pdk_timer = {
-	.init	= mx31pdk_timer_init,
-};
-
-/*
- * The following uses standard kernel macros defined in arch.h in order to
- * initialize __mach_desc_MX31PDK data structure.
- */
-MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
-	/* Maintainer: Freescale Semiconductor, Inc. */
-	.phys_io	= AIPS1_BASE_ADDR,
-	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx31pdk_map_io,
-	.init_irq       = mx31_init_irq,
-	.init_machine   = mxc_board_init,
-	.timer          = &mx31pdk_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx35pdk.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx35pdk.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx35pdk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mx35pdk.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,116 +0,0 @@
-/*
- * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * Author: Fabio Estevam <fabio.estevam@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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You 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 <linux/memory.h>
-#include <linux/gpio.h>
-#include <linux/fsl_devices.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux-mx35.h>
-
-#include "devices.h"
-
-static struct imxuart_platform_data uart_pdata = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct platform_device *devices[] __initdata = {
-	&mxc_fec_device,
-};
-
-static struct pad_desc mx35pdk_pads[] = {
-	/* UART1 */
-	MX35_PAD_CTS1__UART1_CTS,
-	MX35_PAD_RTS1__UART1_RTS,
-	MX35_PAD_TXD1__UART1_TXD_MUX,
-	MX35_PAD_RXD1__UART1_RXD_MUX,
-	/* FEC */
-	MX35_PAD_FEC_TX_CLK__FEC_TX_CLK,
-	MX35_PAD_FEC_RX_CLK__FEC_RX_CLK,
-	MX35_PAD_FEC_RX_DV__FEC_RX_DV,
-	MX35_PAD_FEC_COL__FEC_COL,
-	MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
-	MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
-	MX35_PAD_FEC_TX_EN__FEC_TX_EN,
-	MX35_PAD_FEC_MDC__FEC_MDC,
-	MX35_PAD_FEC_MDIO__FEC_MDIO,
-	MX35_PAD_FEC_TX_ERR__FEC_TX_ERR,
-	MX35_PAD_FEC_RX_ERR__FEC_RX_ERR,
-	MX35_PAD_FEC_CRS__FEC_CRS,
-	MX35_PAD_FEC_RDATA1__FEC_RDATA_1,
-	MX35_PAD_FEC_TDATA1__FEC_TDATA_1,
-	MX35_PAD_FEC_RDATA2__FEC_RDATA_2,
-	MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
-	MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
-	MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
-	/* USBOTG */
-	MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,
-	MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC,
-};
-
-/* OTG config */
-static struct fsl_usb2_platform_data usb_pdata = {
-	.operating_mode	= FSL_USB2_DR_DEVICE,
-	.phy_mode	= FSL_USB2_PHY_UTMI_WIDE,
-};
-
-/*
- * Board specific initialization.
- */
-static void __init mxc_board_init(void)
-{
-	mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
-
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-
-	mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
-}
-
-static void __init mx35pdk_timer_init(void)
-{
-	mx35_clocks_init();
-}
-
-struct sys_timer mx35pdk_timer = {
-	.init	= mx35pdk_timer_init,
-};
-
-MACHINE_START(MX35_3DS, "Freescale MX35PDK")
-	/* Maintainer: Freescale Semiconductor, Inc */
-	.phys_io	= AIPS1_BASE_ADDR,
-	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx35_map_io,
-	.init_irq       = mx35_init_irq,
-	.init_machine   = mxc_board_init,
-	.timer          = &mx35pdk_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/pcm037.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/pcm037.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/pcm037.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/pcm037.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,646 +0,0 @@
-/*
- *  Copyright (C) 2008 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mtd/plat-ram.h>
-#include <linux/memory.h>
-#include <linux/gpio.h>
-#include <linux/smsc911x.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
-#include <linux/delay.h>
-#include <linux/spi/spi.h>
-#include <linux/irq.h>
-#include <linux/fsl_devices.h>
-#include <linux/can/platform/sja1000.h>
-
-#include <media/soc_camera.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-#include <mach/board-pcm037.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/i2c.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux-mx3.h>
-#include <mach/ipu.h>
-#include <mach/mmc.h>
-#include <mach/mx3_camera.h>
-#include <mach/mx3fb.h>
-#include <mach/mxc_nand.h>
-
-#include "devices.h"
-#include "pcm037.h"
-
-static enum pcm037_board_variant pcm037_instance = PCM037_PCM970;
-
-static int __init pcm037_variant_setup(char *str)
-{
-	if (!strcmp("eet", str))
-		pcm037_instance = PCM037_EET;
-	else if (strcmp("pcm970", str))
-		pr_warning("Unknown pcm037 baseboard variant %s\n", str);
-
-	return 1;
-}
-
-/* Supported values: "pcm970" (default) and "eet" */
-__setup("pcm037_variant=", pcm037_variant_setup);
-
-enum pcm037_board_variant pcm037_variant(void)
-{
-	return pcm037_instance;
-}
-
-/* UART1 with RTS/CTS handshake signals */
-static unsigned int pcm037_uart1_handshake_pins[] = {
-	MX31_PIN_CTS1__CTS1,
-	MX31_PIN_RTS1__RTS1,
-	MX31_PIN_TXD1__TXD1,
-	MX31_PIN_RXD1__RXD1,
-};
-
-/* UART1 without RTS/CTS handshake signals */
-static unsigned int pcm037_uart1_pins[] = {
-	MX31_PIN_TXD1__TXD1,
-	MX31_PIN_RXD1__RXD1,
-};
-
-static unsigned int pcm037_pins[] = {
-	/* I2C */
-	MX31_PIN_CSPI2_MOSI__SCL,
-	MX31_PIN_CSPI2_MISO__SDA,
-	MX31_PIN_CSPI2_SS2__I2C3_SDA,
-	MX31_PIN_CSPI2_SCLK__I2C3_SCL,
-	/* SDHC1 */
-	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,
-	IOMUX_MODE(MX31_PIN_SCK6, IOMUX_CONFIG_GPIO), /* card detect */
-	IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO), /* write protect */
-	/* SPI1 */
-	MX31_PIN_CSPI1_MOSI__MOSI,
-	MX31_PIN_CSPI1_MISO__MISO,
-	MX31_PIN_CSPI1_SCLK__SCLK,
-	MX31_PIN_CSPI1_SPI_RDY__SPI_RDY,
-	MX31_PIN_CSPI1_SS0__SS0,
-	MX31_PIN_CSPI1_SS1__SS1,
-	MX31_PIN_CSPI1_SS2__SS2,
-	/* UART2 */
-	MX31_PIN_TXD2__TXD2,
-	MX31_PIN_RXD2__RXD2,
-	MX31_PIN_CTS2__CTS2,
-	MX31_PIN_RTS2__RTS2,
-	/* UART3 */
-	MX31_PIN_CSPI3_MOSI__RXD3,
-	MX31_PIN_CSPI3_MISO__TXD3,
-	MX31_PIN_CSPI3_SCLK__RTS3,
-	MX31_PIN_CSPI3_SPI_RDY__CTS3,
-	/* LAN9217 irq pin */
-	IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO),
-	/* Onewire */
-	MX31_PIN_BATT_LINE__OWIRE,
-	/* Framebuffer */
-	MX31_PIN_LD0__LD0,
-	MX31_PIN_LD1__LD1,
-	MX31_PIN_LD2__LD2,
-	MX31_PIN_LD3__LD3,
-	MX31_PIN_LD4__LD4,
-	MX31_PIN_LD5__LD5,
-	MX31_PIN_LD6__LD6,
-	MX31_PIN_LD7__LD7,
-	MX31_PIN_LD8__LD8,
-	MX31_PIN_LD9__LD9,
-	MX31_PIN_LD10__LD10,
-	MX31_PIN_LD11__LD11,
-	MX31_PIN_LD12__LD12,
-	MX31_PIN_LD13__LD13,
-	MX31_PIN_LD14__LD14,
-	MX31_PIN_LD15__LD15,
-	MX31_PIN_LD16__LD16,
-	MX31_PIN_LD17__LD17,
-	MX31_PIN_VSYNC3__VSYNC3,
-	MX31_PIN_HSYNC__HSYNC,
-	MX31_PIN_FPSHIFT__FPSHIFT,
-	MX31_PIN_DRDY0__DRDY0,
-	MX31_PIN_D3_REV__D3_REV,
-	MX31_PIN_CONTRAST__CONTRAST,
-	MX31_PIN_D3_SPL__D3_SPL,
-	MX31_PIN_D3_CLS__D3_CLS,
-	MX31_PIN_LCS0__GPI03_23,
-	/* CSI */
-	IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_GPIO),
-	MX31_PIN_CSI_D6__CSI_D6,
-	MX31_PIN_CSI_D7__CSI_D7,
-	MX31_PIN_CSI_D8__CSI_D8,
-	MX31_PIN_CSI_D9__CSI_D9,
-	MX31_PIN_CSI_D10__CSI_D10,
-	MX31_PIN_CSI_D11__CSI_D11,
-	MX31_PIN_CSI_D12__CSI_D12,
-	MX31_PIN_CSI_D13__CSI_D13,
-	MX31_PIN_CSI_D14__CSI_D14,
-	MX31_PIN_CSI_D15__CSI_D15,
-	MX31_PIN_CSI_HSYNC__CSI_HSYNC,
-	MX31_PIN_CSI_MCLK__CSI_MCLK,
-	MX31_PIN_CSI_PIXCLK__CSI_PIXCLK,
-	MX31_PIN_CSI_VSYNC__CSI_VSYNC,
-	/* GPIO */
-	IOMUX_MODE(MX31_PIN_ATA_DMACK, IOMUX_CONFIG_GPIO),
-};
-
-static struct physmap_flash_data pcm037_flash_data = {
-	.width  = 2,
-};
-
-static struct resource pcm037_flash_resource = {
-	.start	= 0xa0000000,
-	.end	= 0xa1ffffff,
-	.flags	= IORESOURCE_MEM,
-};
-
-static int usbotg_pins[] = {
-	MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
-	MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
-	MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
-	MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
-	MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
-	MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
-	MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
-	MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
-	MX31_PIN_USBOTG_CLK__USBOTG_CLK,
-	MX31_PIN_USBOTG_DIR__USBOTG_DIR,
-	MX31_PIN_USBOTG_NXT__USBOTG_NXT,
-	MX31_PIN_USBOTG_STP__USBOTG_STP,
-};
-
-/* USB OTG HS port */
-static int __init gpio_usbotg_hs_activate(void)
-{
-	int ret = mxc_iomux_setup_multiple_pins(usbotg_pins,
-					ARRAY_SIZE(usbotg_pins), "usbotg");
-
-	if (ret < 0) {
-		printk(KERN_ERR "Cannot set up OTG pins\n");
-		return ret;
-	}
-
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK,   PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR,   PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT,   PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_STP,   PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
-
-	return 0;
-}
-
-/* OTG config */
-static struct fsl_usb2_platform_data usb_pdata = {
-	.operating_mode	= FSL_USB2_DR_DEVICE,
-	.phy_mode	= FSL_USB2_PHY_ULPI,
-};
-
-static struct platform_device pcm037_flash = {
-	.name	= "physmap-flash",
-	.id	= 0,
-	.dev	= {
-		.platform_data  = &pcm037_flash_data,
-	},
-	.resource = &pcm037_flash_resource,
-	.num_resources = 1,
-};
-
-static struct imxuart_platform_data uart_pdata = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct resource smsc911x_resources[] = {
-	{
-		.start		= CS1_BASE_ADDR + 0x300,
-		.end		= CS1_BASE_ADDR + 0x300 + SZ_64K - 1,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
-		.end		= IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
-		.flags		= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-	},
-};
-
-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		= "smsc911x",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(smsc911x_resources),
-	.resource	= smsc911x_resources,
-	.dev		= {
-		.platform_data = &smsc911x_info,
-	},
-};
-
-static struct platdata_mtd_ram pcm038_sram_data = {
-	.bankwidth = 2,
-};
-
-static struct resource pcm038_sram_resource = {
-	.start = CS4_BASE_ADDR,
-	.end   = CS4_BASE_ADDR + 512 * 1024 - 1,
-	.flags = IORESOURCE_MEM,
-};
-
-static struct platform_device pcm037_sram_device = {
-	.name = "mtd-ram",
-	.id = 0,
-	.dev = {
-		.platform_data = &pcm038_sram_data,
-	},
-	.num_resources = 1,
-	.resource = &pcm038_sram_resource,
-};
-
-static struct mxc_nand_platform_data pcm037_nand_board_info = {
-	.width = 1,
-	.hw_ecc = 1,
-};
-
-static struct imxi2c_platform_data pcm037_i2c_1_data = {
-	.bitrate = 100000,
-};
-
-static struct imxi2c_platform_data pcm037_i2c_2_data = {
-	.bitrate = 20000,
-};
-
-static struct at24_platform_data board_eeprom = {
-	.byte_len = 4096,
-	.page_size = 32,
-	.flags = AT24_FLAG_ADDR16,
-};
-
-static int pcm037_camera_power(struct device *dev, int on)
-{
-	/* disable or enable the camera in X7 or X8 PCM970 connector */
-	gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), !on);
-	return 0;
-}
-
-static struct i2c_board_info pcm037_i2c_camera[] = {
-	{
-		I2C_BOARD_INFO("mt9t031", 0x5d),
-	}, {
-		I2C_BOARD_INFO("mt9v022", 0x48),
-	},
-};
-
-static struct soc_camera_link iclink_mt9v022 = {
-	.bus_id		= 0,		/* Must match with the camera ID */
-	.board_info	= &pcm037_i2c_camera[1],
-	.i2c_adapter_id	= 2,
-	.module_name	= "mt9v022",
-};
-
-static struct soc_camera_link iclink_mt9t031 = {
-	.bus_id		= 0,		/* Must match with the camera ID */
-	.power		= pcm037_camera_power,
-	.board_info	= &pcm037_i2c_camera[0],
-	.i2c_adapter_id	= 2,
-	.module_name	= "mt9t031",
-};
-
-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("pcf8563", 0x51),
-	}
-};
-
-static struct platform_device pcm037_mt9t031 = {
-	.name	= "soc-camera-pdrv",
-	.id	= 0,
-	.dev	= {
-		.platform_data = &iclink_mt9t031,
-	},
-};
-
-static struct platform_device pcm037_mt9v022 = {
-	.name	= "soc-camera-pdrv",
-	.id	= 1,
-	.dev	= {
-		.platform_data = &iclink_mt9v022,
-	},
-};
-
-/* Not connected by default */
-#ifdef PCM970_SDHC_RW_SWITCH
-static int pcm970_sdhc1_get_ro(struct device *dev)
-{
-	return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_SFS6));
-}
-#endif
-
-#define SDHC1_GPIO_WP	IOMUX_TO_GPIO(MX31_PIN_SFS6)
-#define SDHC1_GPIO_DET	IOMUX_TO_GPIO(MX31_PIN_SCK6)
-
-static int pcm970_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
-		void *data)
-{
-	int ret;
-
-	ret = gpio_request(SDHC1_GPIO_DET, "sdhc-detect");
-	if (ret)
-		return ret;
-
-	gpio_direction_input(SDHC1_GPIO_DET);
-
-#ifdef PCM970_SDHC_RW_SWITCH
-	ret = gpio_request(SDHC1_GPIO_WP, "sdhc-wp");
-	if (ret)
-		goto err_gpio_free;
-	gpio_direction_input(SDHC1_GPIO_WP);
-#endif
-
-	ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_SCK6), detect_irq,
-			IRQF_DISABLED | IRQF_TRIGGER_FALLING,
-				"sdhc-detect", data);
-	if (ret)
-		goto err_gpio_free_2;
-
-	return 0;
-
-err_gpio_free_2:
-#ifdef PCM970_SDHC_RW_SWITCH
-	gpio_free(SDHC1_GPIO_WP);
-err_gpio_free:
-#endif
-	gpio_free(SDHC1_GPIO_DET);
-
-	return ret;
-}
-
-static void pcm970_sdhc1_exit(struct device *dev, void *data)
-{
-	free_irq(IOMUX_TO_IRQ(MX31_PIN_SCK6), data);
-	gpio_free(SDHC1_GPIO_DET);
-	gpio_free(SDHC1_GPIO_WP);
-}
-
-static struct imxmmc_platform_data sdhc_pdata = {
-#ifdef PCM970_SDHC_RW_SWITCH
-	.get_ro = pcm970_sdhc1_get_ro,
-#endif
-	.init = pcm970_sdhc1_init,
-	.exit = pcm970_sdhc1_exit,
-};
-
-struct mx3_camera_pdata camera_pdata = {
-	.dma_dev	= &mx3_ipu.dev,
-	.flags		= MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10,
-	.mclk_10khz	= 2000,
-};
-
-static int __init pcm037_camera_alloc_dma(const size_t buf_size)
-{
-	dma_addr_t dma_handle;
-	void *buf;
-	int dma;
-
-	if (buf_size < 2 * 1024 * 1024)
-		return -EINVAL;
-
-	buf = dma_alloc_coherent(NULL, buf_size, &dma_handle, GFP_KERNEL);
-	if (!buf) {
-		pr_err("%s: cannot allocate camera buffer-memory\n", __func__);
-		return -ENOMEM;
-	}
-
-	memset(buf, 0, buf_size);
-
-	dma = dma_declare_coherent_memory(&mx3_camera.dev,
-					dma_handle, dma_handle, buf_size,
-					DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
-
-	/* The way we call dma_declare_coherent_memory only a malloc can fail */
-	return dma & DMA_MEMORY_MAP ? 0 : -ENOMEM;
-}
-
-static struct platform_device *devices[] __initdata = {
-	&pcm037_flash,
-	&pcm037_sram_device,
-	&pcm037_mt9t031,
-	&pcm037_mt9v022,
-};
-
-static struct ipu_platform_data mx3_ipu_data = {
-	.irq_base = MXC_IPU_IRQ_START,
-};
-
-static const struct fb_videomode fb_modedb[] = {
-	{
-		/* 240x320 @ 60 Hz Sharp */
-		.name		= "Sharp-LQ035Q7DH06-QVGA",
-		.refresh	= 60,
-		.xres		= 240,
-		.yres		= 320,
-		.pixclock	= 185925,
-		.left_margin	= 9,
-		.right_margin	= 16,
-		.upper_margin	= 7,
-		.lower_margin	= 9,
-		.hsync_len	= 1,
-		.vsync_len	= 1,
-		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
-				  FB_SYNC_CLK_INVERT | FB_SYNC_CLK_IDLE_EN,
-		.vmode		= FB_VMODE_NONINTERLACED,
-		.flag		= 0,
-	}, {
-		/* 240x320 @ 60 Hz */
-		.name		= "TX090",
-		.refresh	= 60,
-		.xres		= 240,
-		.yres		= 320,
-		.pixclock	= 38255,
-		.left_margin	= 144,
-		.right_margin	= 0,
-		.upper_margin	= 7,
-		.lower_margin	= 40,
-		.hsync_len	= 96,
-		.vsync_len	= 1,
-		.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
-		.vmode		= FB_VMODE_NONINTERLACED,
-		.flag		= 0,
-	}, {
-		/* 240x320 @ 60 Hz */
-		.name		= "CMEL-OLED",
-		.refresh	= 60,
-		.xres		= 240,
-		.yres		= 320,
-		.pixclock	= 185925,
-		.left_margin	= 9,
-		.right_margin	= 16,
-		.upper_margin	= 7,
-		.lower_margin	= 9,
-		.hsync_len	= 1,
-		.vsync_len	= 1,
-		.sync		= FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
-		.vmode		= FB_VMODE_NONINTERLACED,
-		.flag		= 0,
-	},
-};
-
-static struct mx3fb_platform_data mx3fb_pdata = {
-	.dma_dev	= &mx3_ipu.dev,
-	.name		= "Sharp-LQ035Q7DH06-QVGA",
-	.mode		= fb_modedb,
-	.num_modes	= ARRAY_SIZE(fb_modedb),
-};
-
-static struct resource pcm970_sja1000_resources[] = {
-	{
-		.start   = CS5_BASE_ADDR,
-		.end     = CS5_BASE_ADDR + 0x100 - 1,
-		.flags   = IORESOURCE_MEM,
-	}, {
-		.start   = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)),
-		.end     = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)),
-		.flags   = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
-	},
-};
-
-struct sja1000_platform_data pcm970_sja1000_platform_data = {
-	.clock		= 16000000 / 2,
-	.ocr		= 0x40 | 0x18,
-	.cdr		= 0x40,
-};
-
-static struct platform_device pcm970_sja1000 = {
-	.name = "sja1000_platform",
-	.dev = {
-		.platform_data = &pcm970_sja1000_platform_data,
-	},
-	.resource = pcm970_sja1000_resources,
-	.num_resources = ARRAY_SIZE(pcm970_sja1000_resources),
-};
-
-/*
- * Board specific initialization.
- */
-static void __init mxc_board_init(void)
-{
-	int ret;
-
-	mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins),
-			"pcm037");
-
-	if (pcm037_variant() == PCM037_EET)
-		mxc_iomux_setup_multiple_pins(pcm037_uart1_pins,
-			ARRAY_SIZE(pcm037_uart1_pins), "pcm037_uart1");
-	else
-		mxc_iomux_setup_multiple_pins(pcm037_uart1_handshake_pins,
-			ARRAY_SIZE(pcm037_uart1_handshake_pins),
-			"pcm037_uart1");
-
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-	mxc_register_device(&mxc_uart_device1, &uart_pdata);
-	mxc_register_device(&mxc_uart_device2, &uart_pdata);
-
-	mxc_register_device(&mxc_w1_master_device, NULL);
-
-	/* LAN9217 IRQ pin */
-	ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1), "lan9217-irq");
-	if (ret)
-		pr_warning("could not get LAN irq gpio\n");
-	else {
-		gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1));
-		platform_device_register(&pcm037_eth);
-	}
-
-
-	/* I2C adapters and devices */
-	i2c_register_board_info(1, pcm037_i2c_devices,
-			ARRAY_SIZE(pcm037_i2c_devices));
-
-	mxc_register_device(&mxc_i2c_device1, &pcm037_i2c_1_data);
-	mxc_register_device(&mxc_i2c_device2, &pcm037_i2c_2_data);
-
-	mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
-	mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
-	mxc_register_device(&mx3_ipu, &mx3_ipu_data);
-	mxc_register_device(&mx3_fb, &mx3fb_pdata);
-	if (!gpio_usbotg_hs_activate())
-		mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
-
-	/* CSI */
-	/* Camera power: default - off */
-	ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), "mt9t031-power");
-	if (!ret)
-		gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), 1);
-	else
-		iclink_mt9t031.power = NULL;
-
-	if (!pcm037_camera_alloc_dma(4 * 1024 * 1024))
-		mxc_register_device(&mx3_camera, &camera_pdata);
-
-	platform_device_register(&pcm970_sja1000);
-}
-
-static void __init pcm037_timer_init(void)
-{
-	mx31_clocks_init(26000000);
-}
-
-struct sys_timer pcm037_timer = {
-	.init	= pcm037_timer_init,
-};
-
-MACHINE_START(PCM037, "Phytec Phycore pcm037")
-	/* Maintainer: Pengutronix */
-	.phys_io	= AIPS1_BASE_ADDR,
-	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx31_map_io,
-	.init_irq       = mx31_init_irq,
-	.init_machine   = mxc_board_init,
-	.timer          = &pcm037_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/pcm037_eet.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/pcm037_eet.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/pcm037_eet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/pcm037_eet.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2009
- * 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/gpio.h>
-#include <linux/gpio_keys.h>
-#include <linux/input.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-
-#include <mach/common.h>
-#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
-#include <mach/spi.h>
-#endif
-#include <mach/iomux-mx3.h>
-
-#include <asm/mach-types.h>
-
-#include "pcm037.h"
-#include "devices.h"
-
-static unsigned int pcm037_eet_pins[] = {
-	/* Reserve and hardwire GPIO 57 high - S6E63D6 chipselect */
-	IOMUX_MODE(MX31_PIN_KEY_COL7, IOMUX_CONFIG_GPIO),
-	/* GPIO keys */
-	IOMUX_MODE(MX31_PIN_GPIO1_0,	IOMUX_CONFIG_GPIO), /* 0 */
-	IOMUX_MODE(MX31_PIN_GPIO1_1,	IOMUX_CONFIG_GPIO), /* 1 */
-	IOMUX_MODE(MX31_PIN_GPIO1_2,	IOMUX_CONFIG_GPIO), /* 2 */
-	IOMUX_MODE(MX31_PIN_GPIO1_3,	IOMUX_CONFIG_GPIO), /* 3 */
-	IOMUX_MODE(MX31_PIN_SVEN0,	IOMUX_CONFIG_GPIO), /* 32 */
-	IOMUX_MODE(MX31_PIN_STX0,	IOMUX_CONFIG_GPIO), /* 33 */
-	IOMUX_MODE(MX31_PIN_SRX0,	IOMUX_CONFIG_GPIO), /* 34 */
-	IOMUX_MODE(MX31_PIN_SIMPD0,	IOMUX_CONFIG_GPIO), /* 35 */
-	IOMUX_MODE(MX31_PIN_RTS1,	IOMUX_CONFIG_GPIO), /* 38 */
-	IOMUX_MODE(MX31_PIN_CTS1,	IOMUX_CONFIG_GPIO), /* 39 */
-	IOMUX_MODE(MX31_PIN_KEY_ROW4,	IOMUX_CONFIG_GPIO), /* 50 */
-	IOMUX_MODE(MX31_PIN_KEY_ROW5,	IOMUX_CONFIG_GPIO), /* 51 */
-	IOMUX_MODE(MX31_PIN_KEY_ROW6,	IOMUX_CONFIG_GPIO), /* 52 */
-	IOMUX_MODE(MX31_PIN_KEY_ROW7,	IOMUX_CONFIG_GPIO), /* 53 */
-
-	/* LEDs */
-	IOMUX_MODE(MX31_PIN_DTR_DTE1,	IOMUX_CONFIG_GPIO), /* 44 */
-	IOMUX_MODE(MX31_PIN_DSR_DTE1,	IOMUX_CONFIG_GPIO), /* 45 */
-	IOMUX_MODE(MX31_PIN_KEY_COL5,	IOMUX_CONFIG_GPIO), /* 55 */
-	IOMUX_MODE(MX31_PIN_KEY_COL6,	IOMUX_CONFIG_GPIO), /* 56 */
-};
-
-/* SPI */
-static struct spi_board_info pcm037_spi_dev[] = {
-	{
-		.modalias	= "dac124s085",
-		.max_speed_hz	= 400000,
-		.bus_num	= 0,
-		.chip_select	= 0,		/* Index in pcm037_spi1_cs[] */
-		.mode		= SPI_CPHA,
-	},
-};
-
-/* Platform Data for MXC CSPI */
-#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
-static int pcm037_spi1_cs[] = {MXC_SPI_CS(1), IOMUX_TO_GPIO(MX31_PIN_KEY_COL7)};
-
-struct spi_imx_master pcm037_spi1_master = {
-	.chipselect = pcm037_spi1_cs,
-	.num_chipselect = ARRAY_SIZE(pcm037_spi1_cs),
-};
-#endif
-
-/* GPIO-keys input device */
-static struct gpio_keys_button pcm037_gpio_keys[] = {
-	{
-		.type	= EV_KEY,
-		.code	= KEY_L,
-		.gpio	= 0,
-		.desc	= "Wheel Manual",
-		.wakeup	= 0,
-	}, {
-		.type	= EV_KEY,
-		.code	= KEY_A,
-		.gpio	= 1,
-		.desc	= "Wheel AF",
-		.wakeup	= 0,
-	}, {
-		.type	= EV_KEY,
-		.code	= KEY_V,
-		.gpio	= 2,
-		.desc	= "Wheel View",
-		.wakeup	= 0,
-	}, {
-		.type	= EV_KEY,
-		.code	= KEY_M,
-		.gpio	= 3,
-		.desc	= "Wheel Menu",
-		.wakeup	= 0,
-	}, {
-		.type	= EV_KEY,
-		.code	= KEY_UP,
-		.gpio	= 32,
-		.desc	= "Nav Pad Up",
-		.wakeup	= 0,
-	}, {
-		.type	= EV_KEY,
-		.code	= KEY_RIGHT,
-		.gpio	= 33,
-		.desc	= "Nav Pad Right",
-		.wakeup	= 0,
-	}, {
-		.type	= EV_KEY,
-		.code	= KEY_DOWN,
-		.gpio	= 34,
-		.desc	= "Nav Pad Down",
-		.wakeup	= 0,
-	}, {
-		.type	= EV_KEY,
-		.code	= KEY_LEFT,
-		.gpio	= 35,
-		.desc	= "Nav Pad Left",
-		.wakeup	= 0,
-	}, {
-		.type	= EV_KEY,
-		.code	= KEY_ENTER,
-		.gpio	= 38,
-		.desc	= "Nav Pad Ok",
-		.wakeup	= 0,
-	}, {
-		.type	= EV_KEY,
-		.code	= KEY_O,
-		.gpio	= 39,
-		.desc	= "Wheel Off",
-		.wakeup	= 0,
-	}, {
-		.type	= EV_KEY,
-		.code	= BTN_FORWARD,
-		.gpio	= 50,
-		.desc	= "Focus Forward",
-		.wakeup	= 0,
-	}, {
-		.type	= EV_KEY,
-		.code	= BTN_BACK,
-		.gpio	= 51,
-		.desc	= "Focus Backward",
-		.wakeup	= 0,
-	}, {
-		.type	= EV_KEY,
-		.code	= BTN_MIDDLE,
-		.gpio	= 52,
-		.desc	= "Release Half",
-		.wakeup	= 0,
-	}, {
-		.type	= EV_KEY,
-		.code	= BTN_EXTRA,
-		.gpio	= 53,
-		.desc	= "Release Full",
-		.wakeup	= 0,
-	},
-};
-
-static struct gpio_keys_platform_data pcm037_gpio_keys_platform_data = {
-	.buttons	= pcm037_gpio_keys,
-	.nbuttons	= ARRAY_SIZE(pcm037_gpio_keys),
-	.rep		= 0, /* No auto-repeat */
-};
-
-static struct platform_device pcm037_gpio_keys_device = {
-	.name	= "gpio-keys",
-	.id	= -1,
-	.dev	= {
-		.platform_data	= &pcm037_gpio_keys_platform_data,
-	},
-};
-
-static int eet_init_devices(void)
-{
-	if (!machine_is_pcm037() || pcm037_variant() != PCM037_EET)
-		return 0;
-
-	mxc_iomux_setup_multiple_pins(pcm037_eet_pins,
-				ARRAY_SIZE(pcm037_eet_pins), "pcm037_eet");
-
-	/* SPI */
-	spi_register_board_info(pcm037_spi_dev, ARRAY_SIZE(pcm037_spi_dev));
-#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
-	mxc_register_device(&mxc_spi_device0, &pcm037_spi1_master);
-#endif
-
-	platform_device_register(&pcm037_gpio_keys_device);
-
-	return 0;
-}
-
-late_initcall(eet_init_devices);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/pcm043.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/pcm043.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/pcm043.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/pcm043.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,259 +0,0 @@
-/*
- *  Copyright (C) 2009 Sascha Hauer, Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-
-#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mtd/plat-ram.h>
-#include <linux/memory.h>
-#include <linux/gpio.h>
-#include <linux/smc911x.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/imx-uart.h>
-#if defined CONFIG_I2C_IMX || defined CONFIG_I2C_IMX_MODULE
-#include <mach/i2c.h>
-#endif
-#include <mach/iomux-mx35.h>
-#include <mach/ipu.h>
-#include <mach/mx3fb.h>
-#include <mach/mxc_nand.h>
-
-#include "devices.h"
-
-static const struct fb_videomode fb_modedb[] = {
-	{
-		/* 240x320 @ 60 Hz */
-		.name		= "Sharp-LQ035Q7",
-		.refresh	= 60,
-		.xres		= 240,
-		.yres		= 320,
-		.pixclock	= 185925,
-		.left_margin	= 9,
-		.right_margin	= 16,
-		.upper_margin	= 7,
-		.lower_margin	= 9,
-		.hsync_len	= 1,
-		.vsync_len	= 1,
-		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | FB_SYNC_CLK_INVERT | FB_SYNC_CLK_IDLE_EN,
-		.vmode		= FB_VMODE_NONINTERLACED,
-		.flag		= 0,
-	}, {
-		/* 240x320 @ 60 Hz */
-		.name		= "TX090",
-		.refresh	= 60,
-		.xres		= 240,
-		.yres		= 320,
-		.pixclock	= 38255,
-		.left_margin	= 144,
-		.right_margin	= 0,
-		.upper_margin	= 7,
-		.lower_margin	= 40,
-		.hsync_len	= 96,
-		.vsync_len	= 1,
-		.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
-		.vmode		= FB_VMODE_NONINTERLACED,
-		.flag		= 0,
-	},
-};
-
-static struct ipu_platform_data mx3_ipu_data = {
-	.irq_base = MXC_IPU_IRQ_START,
-};
-
-static struct mx3fb_platform_data mx3fb_pdata = {
-	.dma_dev	= &mx3_ipu.dev,
-	.name		= "Sharp-LQ035Q7",
-	.mode		= fb_modedb,
-	.num_modes	= ARRAY_SIZE(fb_modedb),
-};
-
-static struct physmap_flash_data pcm043_flash_data = {
-	.width  = 2,
-};
-
-static struct resource pcm043_flash_resource = {
-	.start	= 0xa0000000,
-	.end	= 0xa1ffffff,
-	.flags	= IORESOURCE_MEM,
-};
-
-static struct platform_device pcm043_flash = {
-	.name	= "physmap-flash",
-	.id	= 0,
-	.dev	= {
-		.platform_data  = &pcm043_flash_data,
-	},
-	.resource = &pcm043_flash_resource,
-	.num_resources = 1,
-};
-
-static struct imxuart_platform_data uart_pdata = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-#if defined CONFIG_I2C_IMX || defined CONFIG_I2C_IMX_MODULE
-static struct imxi2c_platform_data pcm043_i2c_1_data = {
-	.bitrate = 50000,
-};
-
-static struct at24_platform_data board_eeprom = {
-	.byte_len = 4096,
-	.page_size = 32,
-	.flags = AT24_FLAG_ADDR16,
-};
-
-static struct i2c_board_info pcm043_i2c_devices[] = {
-       {
-		I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
-		.platform_data = &board_eeprom,
-	}, {
-		I2C_BOARD_INFO("pcf8563", 0x51),
-	}
-};
-#endif
-
-static struct platform_device *devices[] __initdata = {
-	&pcm043_flash,
-	&mxc_fec_device,
-};
-
-static struct pad_desc pcm043_pads[] = {
-	/* UART1 */
-	MX35_PAD_CTS1__UART1_CTS,
-	MX35_PAD_RTS1__UART1_RTS,
-	MX35_PAD_TXD1__UART1_TXD_MUX,
-	MX35_PAD_RXD1__UART1_RXD_MUX,
-	/* UART2 */
-	MX35_PAD_CTS2__UART2_CTS,
-	MX35_PAD_RTS2__UART2_RTS,
-	MX35_PAD_TXD2__UART2_TXD_MUX,
-	MX35_PAD_RXD2__UART2_RXD_MUX,
-	/* FEC */
-	MX35_PAD_FEC_TX_CLK__FEC_TX_CLK,
-	MX35_PAD_FEC_RX_CLK__FEC_RX_CLK,
-	MX35_PAD_FEC_RX_DV__FEC_RX_DV,
-	MX35_PAD_FEC_COL__FEC_COL,
-	MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
-	MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
-	MX35_PAD_FEC_TX_EN__FEC_TX_EN,
-	MX35_PAD_FEC_MDC__FEC_MDC,
-	MX35_PAD_FEC_MDIO__FEC_MDIO,
-	MX35_PAD_FEC_TX_ERR__FEC_TX_ERR,
-	MX35_PAD_FEC_RX_ERR__FEC_RX_ERR,
-	MX35_PAD_FEC_CRS__FEC_CRS,
-	MX35_PAD_FEC_RDATA1__FEC_RDATA_1,
-	MX35_PAD_FEC_TDATA1__FEC_TDATA_1,
-	MX35_PAD_FEC_RDATA2__FEC_RDATA_2,
-	MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
-	MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
-	MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
-	/* I2C1 */
-	MX35_PAD_I2C1_CLK__I2C1_SCL,
-	MX35_PAD_I2C1_DAT__I2C1_SDA,
-	/* Display */
-	MX35_PAD_LD0__IPU_DISPB_DAT_0,
-	MX35_PAD_LD1__IPU_DISPB_DAT_1,
-	MX35_PAD_LD2__IPU_DISPB_DAT_2,
-	MX35_PAD_LD3__IPU_DISPB_DAT_3,
-	MX35_PAD_LD4__IPU_DISPB_DAT_4,
-	MX35_PAD_LD5__IPU_DISPB_DAT_5,
-	MX35_PAD_LD6__IPU_DISPB_DAT_6,
-	MX35_PAD_LD7__IPU_DISPB_DAT_7,
-	MX35_PAD_LD8__IPU_DISPB_DAT_8,
-	MX35_PAD_LD9__IPU_DISPB_DAT_9,
-	MX35_PAD_LD10__IPU_DISPB_DAT_10,
-	MX35_PAD_LD11__IPU_DISPB_DAT_11,
-	MX35_PAD_LD12__IPU_DISPB_DAT_12,
-	MX35_PAD_LD13__IPU_DISPB_DAT_13,
-	MX35_PAD_LD14__IPU_DISPB_DAT_14,
-	MX35_PAD_LD15__IPU_DISPB_DAT_15,
-	MX35_PAD_LD16__IPU_DISPB_DAT_16,
-	MX35_PAD_LD17__IPU_DISPB_DAT_17,
-	MX35_PAD_D3_HSYNC__IPU_DISPB_D3_HSYNC,
-	MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK,
-	MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY,
-	MX35_PAD_CONTRAST__IPU_DISPB_CONTR,
-	MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC,
-	MX35_PAD_D3_REV__IPU_DISPB_D3_REV,
-	MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS,
-	/* gpio */
-	MX35_PAD_ATA_CS0__GPIO2_6,
-};
-
-static struct mxc_nand_platform_data pcm037_nand_board_info = {
-	.width = 1,
-	.hw_ecc = 1,
-};
-
-/*
- * Board specific initialization.
- */
-static void __init mxc_board_init(void)
-{
-	mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads));
-
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-	mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
-
-	mxc_register_device(&mxc_uart_device1, &uart_pdata);
-
-#if defined CONFIG_I2C_IMX || defined CONFIG_I2C_IMX_MODULE
-	i2c_register_board_info(0, pcm043_i2c_devices,
-			ARRAY_SIZE(pcm043_i2c_devices));
-
-	mxc_register_device(&mxc_i2c_device0, &pcm043_i2c_1_data);
-#endif
-
-	mxc_register_device(&mx3_ipu, &mx3_ipu_data);
-	mxc_register_device(&mx3_fb, &mx3fb_pdata);
-}
-
-static void __init pcm043_timer_init(void)
-{
-	mx35_clocks_init();
-}
-
-struct sys_timer pcm043_timer = {
-	.init	= pcm043_timer_init,
-};
-
-MACHINE_START(PCM043, "Phytec Phycore pcm043")
-	/* Maintainer: Pengutronix */
-	.phys_io	= AIPS1_BASE_ADDR,
-	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx35_map_io,
-	.init_irq       = mx35_init_irq,
-	.init_machine   = mxc_board_init,
-	.timer          = &pcm043_timer,
-MACHINE_END
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/qong.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/qong.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/qong.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/qong.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,285 +0,0 @@
-/*
- *  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[] = {
-	{
-		.name	= "dnet-memory",
-		.start	= QONG_DNET_BASEADDR,
-		.end	= QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.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         = mx31_map_io,
-	.init_irq       = mx31_init_irq,
-	.init_machine   = mxc_board_init,
-	.timer          = &qong_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/board-mx51_babbage.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/board-mx51_babbage.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/board-mx51_babbage.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/board-mx51_babbage.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx51.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "devices.h"
+
+static struct platform_device *devices[] __initdata = {
+	&mxc_fec_device,
+};
+
+static struct pad_desc mx51babbage_pads[] = {
+	/* UART1 */
+	MX51_PAD_UART1_RXD__UART1_RXD,
+	MX51_PAD_UART1_TXD__UART1_TXD,
+	MX51_PAD_UART1_RTS__UART1_RTS,
+	MX51_PAD_UART1_CTS__UART1_CTS,
+
+	/* UART2 */
+	MX51_PAD_UART2_RXD__UART2_RXD,
+	MX51_PAD_UART2_TXD__UART2_TXD,
+
+	/* UART3 */
+	MX51_PAD_EIM_D25__UART3_RXD,
+	MX51_PAD_EIM_D26__UART3_TXD,
+	MX51_PAD_EIM_D27__UART3_RTS,
+	MX51_PAD_EIM_D24__UART3_CTS,
+};
+
+/* Serial ports */
+#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static inline void mxc_init_imx_uart(void)
+{
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+	mxc_register_device(&mxc_uart_device1, &uart_pdata);
+	mxc_register_device(&mxc_uart_device2, &uart_pdata);
+}
+#else /* !SERIAL_IMX */
+static inline void mxc_init_imx_uart(void)
+{
+}
+#endif /* SERIAL_IMX */
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+	mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads,
+					ARRAY_SIZE(mx51babbage_pads));
+	mxc_init_imx_uart();
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init mx51_babbage_timer_init(void)
+{
+	mx51_clocks_init(32768, 24000000, 22579200, 0);
+}
+
+static struct sys_timer mxc_timer = {
+	.init	= mx51_babbage_timer_init,
+};
+
+MACHINE_START(MX51_BABBAGE, "Freescale MX51 Babbage Board")
+	/* Maintainer: Amit Kucheria <amit.kucheria@canonical.com> */
+	.phys_io = MX51_AIPS1_BASE_ADDR,
+	.io_pg_offst = ((MX51_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params = PHYS_OFFSET + 0x100,
+	.map_io = mx51_map_io,
+	.init_irq = mx51_init_irq,
+	.init_machine = mxc_board_init,
+	.timer = &mxc_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/clock-mx51.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/clock-mx51.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/clock-mx51.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/clock-mx51.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,826 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "crm_regs.h"
+
+/* External clock values passed-in by the board code */
+static unsigned long external_high_reference, external_low_reference;
+static unsigned long oscillator_reference, ckih2_reference;
+
+static struct clk osc_clk;
+static struct clk pll1_main_clk;
+static struct clk pll1_sw_clk;
+static struct clk pll2_sw_clk;
+static struct clk pll3_sw_clk;
+static struct clk lp_apm_clk;
+static struct clk periph_apm_clk;
+static struct clk ahb_clk;
+static struct clk ipg_clk;
+
+#define MAX_DPLL_WAIT_TRIES	1000 /* 1000 * udelay(1) = 1ms */
+
+static int _clk_ccgr_enable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg |= MXC_CCM_CCGRx_MOD_ON << clk->enable_shift;
+	__raw_writel(reg, clk->enable_reg);
+
+	return 0;
+}
+
+static void _clk_ccgr_disable(struct clk *clk)
+{
+	u32 reg;
+	reg = __raw_readl(clk->enable_reg);
+	reg &= ~(MXC_CCM_CCGRx_MOD_OFF << clk->enable_shift);
+	__raw_writel(reg, clk->enable_reg);
+
+}
+
+static void _clk_ccgr_disable_inwait(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+	reg |= MXC_CCM_CCGRx_MOD_IDLE << clk->enable_shift;
+	__raw_writel(reg, clk->enable_reg);
+}
+
+/*
+ * For the 4-to-1 muxed input clock
+ */
+static inline u32 _get_mux(struct clk *parent, struct clk *m0,
+			   struct clk *m1, struct clk *m2, struct clk *m3)
+{
+	if (parent == m0)
+		return 0;
+	else if (parent == m1)
+		return 1;
+	else if (parent == m2)
+		return 2;
+	else if (parent == m3)
+		return 3;
+	else
+		BUG();
+
+	return -EINVAL;
+}
+
+static inline void __iomem *_get_pll_base(struct clk *pll)
+{
+	if (pll == &pll1_main_clk)
+		return MX51_DPLL1_BASE;
+	else if (pll == &pll2_sw_clk)
+		return MX51_DPLL2_BASE;
+	else if (pll == &pll3_sw_clk)
+		return MX51_DPLL3_BASE;
+	else
+		BUG();
+
+	return NULL;
+}
+
+static unsigned long clk_pll_get_rate(struct clk *clk)
+{
+	long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+	unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
+	void __iomem *pllbase;
+	s64 temp;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	pllbase = _get_pll_base(clk);
+
+	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+	pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+	dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
+
+	if (pll_hfsm == 0) {
+		dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
+		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
+		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
+	} else {
+		dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
+		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
+		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
+	}
+	pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
+	mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
+	mfi = (mfi <= 5) ? 5 : mfi;
+	mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
+	mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
+	/* Sign extend to 32-bits */
+	if (mfn >= 0x04000000) {
+		mfn |= 0xFC000000;
+		mfn_abs = -mfn;
+	}
+
+	ref_clk = 2 * parent_rate;
+	if (dbl != 0)
+		ref_clk *= 2;
+
+	ref_clk /= (pdf + 1);
+	temp = (u64) ref_clk * mfn_abs;
+	do_div(temp, mfd + 1);
+	if (mfn < 0)
+		temp = -temp;
+	temp = (ref_clk * mfi) + temp;
+
+	return temp;
+}
+
+static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 reg;
+	void __iomem *pllbase;
+
+	long mfi, pdf, mfn, mfd = 999999;
+	s64 temp64;
+	unsigned long quad_parent_rate;
+	unsigned long pll_hfsm, dp_ctl;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	pllbase = _get_pll_base(clk);
+
+	quad_parent_rate = 4 * parent_rate;
+	pdf = mfi = -1;
+	while (++pdf < 16 && mfi < 5)
+		mfi = rate * (pdf+1) / quad_parent_rate;
+	if (mfi > 15)
+		return -EINVAL;
+	pdf--;
+
+	temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
+	do_div(temp64, quad_parent_rate/1000000);
+	mfn = (long)temp64;
+
+	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+	/* use dpdck0_2 */
+	__raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
+	pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+	if (pll_hfsm == 0) {
+		reg = mfi << 4 | pdf;
+		__raw_writel(reg, pllbase + MXC_PLL_DP_OP);
+		__raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
+		__raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
+	} else {
+		reg = mfi << 4 | pdf;
+		__raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
+		__raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
+		__raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
+	}
+
+	return 0;
+}
+
+static int _clk_pll_enable(struct clk *clk)
+{
+	u32 reg;
+	void __iomem *pllbase;
+	int i = 0;
+
+	pllbase = _get_pll_base(clk);
+	reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
+	__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+
+	/* Wait for lock */
+	do {
+		reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+		if (reg & MXC_PLL_DP_CTL_LRF)
+			break;
+
+		udelay(1);
+	} while (++i < MAX_DPLL_WAIT_TRIES);
+
+	if (i == MAX_DPLL_WAIT_TRIES) {
+		pr_err("MX5: pll locking failed\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void _clk_pll_disable(struct clk *clk)
+{
+	u32 reg;
+	void __iomem *pllbase;
+
+	pllbase = _get_pll_base(clk);
+	reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
+	__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+}
+
+static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg, step;
+
+	reg = __raw_readl(MXC_CCM_CCSR);
+
+	/* When switching from pll_main_clk to a bypass clock, first select a
+	 * multiplexed clock in 'step_sel', then shift the glitchless mux
+	 * 'pll1_sw_clk_sel'.
+	 *
+	 * When switching back, do it in reverse order
+	 */
+	if (parent == &pll1_main_clk) {
+		/* Switch to pll1_main_clk */
+		reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+		__raw_writel(reg, MXC_CCM_CCSR);
+		/* step_clk mux switched to lp_apm, to save power. */
+		reg = __raw_readl(MXC_CCM_CCSR);
+		reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
+		reg |= (MXC_CCM_CCSR_STEP_SEL_LP_APM <<
+				MXC_CCM_CCSR_STEP_SEL_OFFSET);
+	} else {
+		if (parent == &lp_apm_clk) {
+			step = MXC_CCM_CCSR_STEP_SEL_LP_APM;
+		} else  if (parent == &pll2_sw_clk) {
+			step = MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED;
+		} else  if (parent == &pll3_sw_clk) {
+			step = MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED;
+		} else
+			return -EINVAL;
+
+		reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
+		reg |= (step << MXC_CCM_CCSR_STEP_SEL_OFFSET);
+
+		__raw_writel(reg, MXC_CCM_CCSR);
+		/* Switch to step_clk */
+		reg = __raw_readl(MXC_CCM_CCSR);
+		reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+	}
+	__raw_writel(reg, MXC_CCM_CCSR);
+	return 0;
+}
+
+static unsigned long clk_pll1_sw_get_rate(struct clk *clk)
+{
+	u32 reg, div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	reg = __raw_readl(MXC_CCM_CCSR);
+
+	if (clk->parent == &pll2_sw_clk) {
+		div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
+		       MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
+	} else if (clk->parent == &pll3_sw_clk) {
+		div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
+		       MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
+	} else
+		div = 1;
+	return parent_rate / div;
+}
+
+static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg;
+
+	reg = __raw_readl(MXC_CCM_CCSR);
+
+	if (parent == &pll2_sw_clk)
+		reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
+	else
+		reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
+
+	__raw_writel(reg, MXC_CCM_CCSR);
+	return 0;
+}
+
+static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg;
+
+	if (parent == &osc_clk)
+		reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
+	else
+		return -EINVAL;
+
+	__raw_writel(reg, MXC_CCM_CCSR);
+
+	return 0;
+}
+
+static unsigned long clk_arm_get_rate(struct clk *clk)
+{
+	u32 cacrr, div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+	cacrr = __raw_readl(MXC_CCM_CACRR);
+	div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
+
+	return parent_rate / div;
+}
+
+static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg, mux;
+	int i = 0;
+
+	mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL);
+
+	reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK;
+	reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET;
+	__raw_writel(reg, MXC_CCM_CBCMR);
+
+	/* Wait for lock */
+	do {
+		reg = __raw_readl(MXC_CCM_CDHIPR);
+		if (!(reg &  MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY))
+			break;
+
+		udelay(1);
+	} while (++i < MAX_DPLL_WAIT_TRIES);
+
+	if (i == MAX_DPLL_WAIT_TRIES) {
+		pr_err("MX5: Set parent for periph_apm clock failed\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg;
+
+	reg = __raw_readl(MXC_CCM_CBCDR);
+
+	if (parent == &pll2_sw_clk)
+		reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+	else if (parent == &periph_apm_clk)
+		reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+	else
+		return -EINVAL;
+
+	__raw_writel(reg, MXC_CCM_CBCDR);
+
+	return 0;
+}
+
+static struct clk main_bus_clk = {
+	.parent = &pll2_sw_clk,
+	.set_parent = _clk_main_bus_set_parent,
+};
+
+static unsigned long clk_ahb_get_rate(struct clk *clk)
+{
+	u32 reg, div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	reg = __raw_readl(MXC_CCM_CBCDR);
+	div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
+	       MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
+	return parent_rate / div;
+}
+
+
+static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 reg, div;
+	unsigned long parent_rate;
+	int i = 0;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	div = parent_rate / rate;
+	if (div > 8 || div < 1 || ((parent_rate / div) != rate))
+		return -EINVAL;
+
+	reg = __raw_readl(MXC_CCM_CBCDR);
+	reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
+	reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET;
+	__raw_writel(reg, MXC_CCM_CBCDR);
+
+	/* Wait for lock */
+	do {
+		reg = __raw_readl(MXC_CCM_CDHIPR);
+		if (!(reg & MXC_CCM_CDHIPR_AHB_PODF_BUSY))
+			break;
+
+		udelay(1);
+	} while (++i < MAX_DPLL_WAIT_TRIES);
+
+	if (i == MAX_DPLL_WAIT_TRIES) {
+		pr_err("MX5: clk_ahb_set_rate failed\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static unsigned long _clk_ahb_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 (div > 8)
+		div = 8;
+	else if (div == 0)
+		div++;
+	return parent_rate / div;
+}
+
+
+static int _clk_max_enable(struct clk *clk)
+{
+	u32 reg;
+
+	_clk_ccgr_enable(clk);
+
+	/* Handshake with MAX when LPM is entered. */
+	reg = __raw_readl(MXC_CCM_CLPCR);
+	reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+	__raw_writel(reg, MXC_CCM_CLPCR);
+
+	return 0;
+}
+
+static void _clk_max_disable(struct clk *clk)
+{
+	u32 reg;
+
+	_clk_ccgr_disable_inwait(clk);
+
+	/* No Handshake with MAX when LPM is entered as its disabled. */
+	reg = __raw_readl(MXC_CCM_CLPCR);
+	reg |= MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+	__raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+static unsigned long clk_ipg_get_rate(struct clk *clk)
+{
+	u32 reg, div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	reg = __raw_readl(MXC_CCM_CBCDR);
+	div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
+	       MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
+
+	return parent_rate / div;
+}
+
+static unsigned long clk_ipg_per_get_rate(struct clk *clk)
+{
+	u32 reg, prediv1, prediv2, podf;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) {
+		/* the main_bus_clk is the one before the DVFS engine */
+		reg = __raw_readl(MXC_CCM_CBCDR);
+		prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
+			   MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1;
+		prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
+			   MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1;
+		podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
+			MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1;
+		return parent_rate / (prediv1 * prediv2 * podf);
+	} else if (clk->parent == &ipg_clk)
+		return parent_rate;
+	else
+		BUG();
+}
+
+static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg;
+
+	reg = __raw_readl(MXC_CCM_CBCMR);
+
+	reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+	reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+
+	if (parent == &ipg_clk)
+		reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+	else if (parent == &lp_apm_clk)
+		reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+	else if (parent != &main_bus_clk)
+		return -EINVAL;
+
+	__raw_writel(reg, MXC_CCM_CBCMR);
+
+	return 0;
+}
+
+static unsigned long clk_uart_get_rate(struct clk *clk)
+{
+	u32 reg, prediv, podf;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	reg = __raw_readl(MXC_CCM_CSCDR1);
+	prediv = ((reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >>
+		  MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1;
+	podf = ((reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
+		MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
+
+	return parent_rate / (prediv * podf);
+}
+
+static int _clk_uart_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg, mux;
+
+	mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+		       &lp_apm_clk);
+	reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_UART_CLK_SEL_MASK;
+	reg |= mux << MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET;
+	__raw_writel(reg, MXC_CCM_CSCMR1);
+
+	return 0;
+}
+
+static unsigned long get_high_reference_clock_rate(struct clk *clk)
+{
+	return external_high_reference;
+}
+
+static unsigned long get_low_reference_clock_rate(struct clk *clk)
+{
+	return external_low_reference;
+}
+
+static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
+{
+	return oscillator_reference;
+}
+
+static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
+{
+	return ckih2_reference;
+}
+
+/* External high frequency clock */
+static struct clk ckih_clk = {
+	.get_rate = get_high_reference_clock_rate,
+};
+
+static struct clk ckih2_clk = {
+	.get_rate = get_ckih2_reference_clock_rate,
+};
+
+static struct clk osc_clk = {
+	.get_rate = get_oscillator_reference_clock_rate,
+};
+
+/* External low frequency (32kHz) clock */
+static struct clk ckil_clk = {
+	.get_rate = get_low_reference_clock_rate,
+};
+
+static struct clk pll1_main_clk = {
+	.parent = &osc_clk,
+	.get_rate = clk_pll_get_rate,
+	.enable = _clk_pll_enable,
+	.disable = _clk_pll_disable,
+};
+
+/* Clock tree block diagram (WIP):
+ * 	CCM: Clock Controller Module
+ *
+ * PLL output -> |
+ *               | CCM Switcher -> CCM_CLK_ROOT_GEN ->
+ * PLL bypass -> |
+ *
+ */
+
+/* PLL1 SW supplies to ARM core */
+static struct clk pll1_sw_clk = {
+	.parent = &pll1_main_clk,
+	.set_parent = _clk_pll1_sw_set_parent,
+	.get_rate = clk_pll1_sw_get_rate,
+};
+
+/* PLL2 SW supplies to AXI/AHB/IP buses */
+static struct clk pll2_sw_clk = {
+	.parent = &osc_clk,
+	.get_rate = clk_pll_get_rate,
+	.set_rate = _clk_pll_set_rate,
+	.set_parent = _clk_pll2_sw_set_parent,
+	.enable = _clk_pll_enable,
+	.disable = _clk_pll_disable,
+};
+
+/* PLL3 SW supplies to serial clocks like USB, SSI, etc. */
+static struct clk pll3_sw_clk = {
+	.parent = &osc_clk,
+	.set_rate = _clk_pll_set_rate,
+	.get_rate = clk_pll_get_rate,
+	.enable = _clk_pll_enable,
+	.disable = _clk_pll_disable,
+};
+
+/* Low-power Audio Playback Mode clock */
+static struct clk lp_apm_clk = {
+	.parent = &osc_clk,
+	.set_parent = _clk_lp_apm_set_parent,
+};
+
+static struct clk periph_apm_clk = {
+	.parent = &pll1_sw_clk,
+	.set_parent = _clk_periph_apm_set_parent,
+};
+
+static struct clk cpu_clk = {
+	.parent = &pll1_sw_clk,
+	.get_rate = clk_arm_get_rate,
+};
+
+static struct clk ahb_clk = {
+	.parent = &main_bus_clk,
+	.get_rate = clk_ahb_get_rate,
+	.set_rate = _clk_ahb_set_rate,
+	.round_rate = _clk_ahb_round_rate,
+};
+
+/* Main IP interface clock for access to registers */
+static struct clk ipg_clk = {
+	.parent = &ahb_clk,
+	.get_rate = clk_ipg_get_rate,
+};
+
+static struct clk ipg_perclk = {
+	.parent = &lp_apm_clk,
+	.get_rate = clk_ipg_per_get_rate,
+	.set_parent = _clk_ipg_per_set_parent,
+};
+
+static struct clk uart_root_clk = {
+	.parent = &pll2_sw_clk,
+	.get_rate = clk_uart_get_rate,
+	.set_parent = _clk_uart_set_parent,
+};
+
+static struct clk ahb_max_clk = {
+	.parent = &ahb_clk,
+	.enable_reg = MXC_CCM_CCGR0,
+	.enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+	.enable = _clk_max_enable,
+	.disable = _clk_max_disable,
+};
+
+static struct clk aips_tz1_clk = {
+	.parent = &ahb_clk,
+	.secondary = &ahb_max_clk,
+	.enable_reg = MXC_CCM_CCGR0,
+	.enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+	.enable = _clk_ccgr_enable,
+	.disable = _clk_ccgr_disable_inwait,
+};
+
+static struct clk aips_tz2_clk = {
+	.parent = &ahb_clk,
+	.secondary = &ahb_max_clk,
+	.enable_reg = MXC_CCM_CCGR0,
+	.enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+	.enable = _clk_ccgr_enable,
+	.disable = _clk_ccgr_disable_inwait,
+};
+
+static struct clk gpt_32k_clk = {
+	.id = 0,
+	.parent = &ckil_clk,
+};
+
+#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s)	\
+	static struct clk name = {			\
+		.id		= i,			\
+		.enable_reg	= er,			\
+		.enable_shift	= es,			\
+		.get_rate	= gr,			\
+		.set_rate	= sr,			\
+		.enable		= _clk_ccgr_enable,	\
+		.disable	= _clk_ccgr_disable,	\
+		.parent		= p,			\
+		.secondary	= s,			\
+	}
+
+/* DEFINE_CLOCK(name, id, enable_reg, enable_shift,
+   get_rate, set_rate, parent, secondary); */
+
+/* Shared peripheral bus arbiter */
+DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET,
+	NULL,  NULL, &ipg_clk, NULL);
+
+/* UART */
+DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET,
+	NULL,  NULL, &uart_root_clk, NULL);
+DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET,
+	NULL,  NULL, &uart_root_clk, NULL);
+DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET,
+	NULL,  NULL, &uart_root_clk, NULL);
+DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET,
+	NULL,  NULL, &ipg_clk, &aips_tz1_clk);
+DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET,
+	NULL,  NULL, &ipg_clk, &aips_tz1_clk);
+DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
+	NULL,  NULL, &ipg_clk, &spba_clk);
+
+/* GPT */
+DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
+	NULL,  NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
+	NULL,  NULL, &ipg_clk, NULL);
+
+/* FEC */
+DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
+	NULL,  NULL, &ipg_clk, NULL);
+
+#define _REGISTER_CLOCK(d, n, c) \
+       { \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c,   \
+       },
+
+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(NULL, "gpt", gpt_clk)
+	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+};
+
+static void clk_tree_init(void)
+{
+	u32 reg;
+
+	ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);
+
+	/*
+	 * Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
+	 * 8MHz, its derived from lp_apm.
+	 *
+	 * FIXME: Verify if true for all boards
+	 */
+	reg = __raw_readl(MXC_CCM_CBCDR);
+	reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK;
+	reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK;
+	reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK;
+	reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET);
+	__raw_writel(reg, MXC_CCM_CBCDR);
+}
+
+int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
+			unsigned long ckih1, unsigned long ckih2)
+{
+	int i;
+
+	external_low_reference = ckil;
+	external_high_reference = ckih1;
+	ckih2_reference = ckih2;
+	oscillator_reference = osc;
+
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
+
+	clk_tree_init();
+
+	clk_enable(&cpu_clk);
+	clk_enable(&main_bus_clk);
+
+	/* System timer */
+	mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
+		MX51_MXC_INT_GPT);
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/cpu.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/cpu.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/cpu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/cpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * This file contains the CPU initialization code.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <mach/hardware.h>
+#include <asm/io.h>
+
+static int cpu_silicon_rev = -1;
+
+#define SI_REV 0x48
+
+static void query_silicon_parameter(void)
+{
+	void __iomem *rom = ioremap(MX51_IROM_BASE_ADDR, MX51_IROM_SIZE);
+	u32 rev;
+
+	if (!rom) {
+		cpu_silicon_rev = -EINVAL;
+		return;
+	}
+
+	rev = readl(rom + SI_REV);
+	switch (rev) {
+	case 0x1:
+		cpu_silicon_rev = MX51_CHIP_REV_1_0;
+		break;
+	case 0x2:
+		cpu_silicon_rev = MX51_CHIP_REV_1_1;
+		break;
+	case 0x10:
+		cpu_silicon_rev = MX51_CHIP_REV_2_0;
+		break;
+	case 0x20:
+		cpu_silicon_rev = MX51_CHIP_REV_3_0;
+		break;
+	default:
+		cpu_silicon_rev = 0;
+	}
+
+	iounmap(rom);
+}
+
+/*
+ * Returns:
+ *	the silicon revision of the cpu
+ *	-EINVAL - not a mx51
+ */
+int mx51_revision(void)
+{
+	if (!cpu_is_mx51())
+		return -EINVAL;
+
+	if (cpu_silicon_rev == -1)
+		query_silicon_parameter();
+
+	return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx51_revision);
+
+static int __init post_cpu_init(void)
+{
+	unsigned int reg;
+	void __iomem *base;
+
+	if (!cpu_is_mx51())
+		return 0;
+
+	base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR);
+	__raw_writel(0x0, base + 0x40);
+	__raw_writel(0x0, base + 0x44);
+	__raw_writel(0x0, base + 0x48);
+	__raw_writel(0x0, base + 0x4C);
+	reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
+	__raw_writel(reg, base + 0x50);
+
+	base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR);
+	__raw_writel(0x0, base + 0x40);
+	__raw_writel(0x0, base + 0x44);
+	__raw_writel(0x0, base + 0x48);
+	__raw_writel(0x0, base + 0x4C);
+	reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
+	__raw_writel(reg, base + 0x50);
+
+	return 0;
+}
+
+postcore_initcall(post_cpu_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/crm_regs.h linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/crm_regs.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/crm_regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/crm_regs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,583 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ARCH_ARM_MACH_MX51_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX51_CRM_REGS_H__
+
+#define MX51_CCM_BASE		MX51_IO_ADDRESS(MX51_CCM_BASE_ADDR)
+#define MX51_DPLL1_BASE		MX51_IO_ADDRESS(MX51_PLL1_BASE_ADDR)
+#define MX51_DPLL2_BASE		MX51_IO_ADDRESS(MX51_PLL2_BASE_ADDR)
+#define MX51_DPLL3_BASE		MX51_IO_ADDRESS(MX51_PLL3_BASE_ADDR)
+#define MX51_CORTEXA8_BASE	MX51_IO_ADDRESS(MX51_ARM_BASE_ADDR)
+#define MX51_GPC_BASE		MX51_IO_ADDRESS(MX51_GPC_BASE_ADDR)
+
+/* PLL Register Offsets */
+#define MXC_PLL_DP_CTL			0x00
+#define MXC_PLL_DP_CONFIG		0x04
+#define MXC_PLL_DP_OP			0x08
+#define MXC_PLL_DP_MFD			0x0C
+#define MXC_PLL_DP_MFN			0x10
+#define MXC_PLL_DP_MFNMINUS		0x14
+#define MXC_PLL_DP_MFNPLUS		0x18
+#define MXC_PLL_DP_HFS_OP		0x1C
+#define MXC_PLL_DP_HFS_MFD		0x20
+#define MXC_PLL_DP_HFS_MFN		0x24
+#define MXC_PLL_DP_MFN_TOGC		0x28
+#define MXC_PLL_DP_DESTAT		0x2c
+
+/* PLL Register Bit definitions */
+#define MXC_PLL_DP_CTL_MUL_CTRL		0x2000
+#define MXC_PLL_DP_CTL_DPDCK0_2_EN	0x1000
+#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET	12
+#define MXC_PLL_DP_CTL_ADE		0x800
+#define MXC_PLL_DP_CTL_REF_CLK_DIV	0x400
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK	(3 << 8)
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET	8
+#define MXC_PLL_DP_CTL_HFSM		0x80
+#define MXC_PLL_DP_CTL_PRE		0x40
+#define MXC_PLL_DP_CTL_UPEN		0x20
+#define MXC_PLL_DP_CTL_RST		0x10
+#define MXC_PLL_DP_CTL_RCP		0x8
+#define MXC_PLL_DP_CTL_PLM		0x4
+#define MXC_PLL_DP_CTL_BRM0		0x2
+#define MXC_PLL_DP_CTL_LRF		0x1
+
+#define MXC_PLL_DP_CONFIG_BIST		0x8
+#define MXC_PLL_DP_CONFIG_SJC_CE	0x4
+#define MXC_PLL_DP_CONFIG_AREN		0x2
+#define MXC_PLL_DP_CONFIG_LDREQ		0x1
+
+#define MXC_PLL_DP_OP_MFI_OFFSET	4
+#define MXC_PLL_DP_OP_MFI_MASK		(0xF << 4)
+#define MXC_PLL_DP_OP_PDF_OFFSET	0
+#define MXC_PLL_DP_OP_PDF_MASK		0xF
+
+#define MXC_PLL_DP_MFD_OFFSET		0
+#define MXC_PLL_DP_MFD_MASK		0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_OFFSET		0x0
+#define MXC_PLL_DP_MFN_MASK		0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_TOGC_TOG_DIS	(1 << 17)
+#define MXC_PLL_DP_MFN_TOGC_TOG_EN	(1 << 16)
+#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET	0x0
+#define MXC_PLL_DP_MFN_TOGC_CNT_MASK	0xFFFF
+
+#define MXC_PLL_DP_DESTAT_TOG_SEL	(1 << 31)
+#define MXC_PLL_DP_DESTAT_MFN		0x07FFFFFF
+
+/* Register addresses of CCM*/
+#define MXC_CCM_CCR		(MX51_CCM_BASE + 0x00)
+#define MXC_CCM_CCDR		(MX51_CCM_BASE + 0x04)
+#define MXC_CCM_CSR		(MX51_CCM_BASE + 0x08)
+#define MXC_CCM_CCSR		(MX51_CCM_BASE + 0x0C)
+#define MXC_CCM_CACRR		(MX51_CCM_BASE + 0x10)
+#define MXC_CCM_CBCDR		(MX51_CCM_BASE + 0x14)
+#define MXC_CCM_CBCMR		(MX51_CCM_BASE + 0x18)
+#define MXC_CCM_CSCMR1		(MX51_CCM_BASE + 0x1C)
+#define MXC_CCM_CSCMR2		(MX51_CCM_BASE + 0x20)
+#define MXC_CCM_CSCDR1		(MX51_CCM_BASE + 0x24)
+#define MXC_CCM_CS1CDR		(MX51_CCM_BASE + 0x28)
+#define MXC_CCM_CS2CDR		(MX51_CCM_BASE + 0x2C)
+#define MXC_CCM_CDCDR		(MX51_CCM_BASE + 0x30)
+#define MXC_CCM_CHSCDR		(MX51_CCM_BASE + 0x34)
+#define MXC_CCM_CSCDR2		(MX51_CCM_BASE + 0x38)
+#define MXC_CCM_CSCDR3		(MX51_CCM_BASE + 0x3C)
+#define MXC_CCM_CSCDR4		(MX51_CCM_BASE + 0x40)
+#define MXC_CCM_CWDR		(MX51_CCM_BASE + 0x44)
+#define MXC_CCM_CDHIPR		(MX51_CCM_BASE + 0x48)
+#define MXC_CCM_CDCR		(MX51_CCM_BASE + 0x4C)
+#define MXC_CCM_CTOR		(MX51_CCM_BASE + 0x50)
+#define MXC_CCM_CLPCR		(MX51_CCM_BASE + 0x54)
+#define MXC_CCM_CISR		(MX51_CCM_BASE + 0x58)
+#define MXC_CCM_CIMR		(MX51_CCM_BASE + 0x5C)
+#define MXC_CCM_CCOSR		(MX51_CCM_BASE + 0x60)
+#define MXC_CCM_CGPR		(MX51_CCM_BASE + 0x64)
+#define MXC_CCM_CCGR0		(MX51_CCM_BASE + 0x68)
+#define MXC_CCM_CCGR1		(MX51_CCM_BASE + 0x6C)
+#define MXC_CCM_CCGR2		(MX51_CCM_BASE + 0x70)
+#define MXC_CCM_CCGR3		(MX51_CCM_BASE + 0x74)
+#define MXC_CCM_CCGR4		(MX51_CCM_BASE + 0x78)
+#define MXC_CCM_CCGR5		(MX51_CCM_BASE + 0x7C)
+#define MXC_CCM_CCGR6		(MX51_CCM_BASE + 0x80)
+#define MXC_CCM_CMEOR		(MX51_CCM_BASE + 0x84)
+
+/* Define the bits in register CCR */
+#define MXC_CCM_CCR_COSC_EN		(1 << 12)
+#define MXC_CCM_CCR_FPM_MULT_MASK	(1 << 11)
+#define MXC_CCM_CCR_CAMP2_EN		(1 << 10)
+#define MXC_CCM_CCR_CAMP1_EN		(1 << 9)
+#define MXC_CCM_CCR_FPM_EN		(1 << 8)
+#define MXC_CCM_CCR_OSCNT_OFFSET	(0)
+#define MXC_CCM_CCR_OSCNT_MASK	(0xFF)
+
+/* Define the bits in register CCDR */
+#define MXC_CCM_CCDR_HSC_HS_MASK	(0x1 << 18)
+#define MXC_CCM_CCDR_IPU_HS_MASK	(0x1 << 17)
+#define MXC_CCM_CCDR_EMI_HS_MASK	(0x1 << 16)
+
+/* Define the bits in register CSR */
+#define MXC_CCM_CSR_COSR_READY	(1 << 5)
+#define MXC_CCM_CSR_LVS_VALUE	(1 << 4)
+#define MXC_CCM_CSR_CAMP2_READY	(1 << 3)
+#define MXC_CCM_CSR_CAMP1_READY	(1 << 2)
+#define MXC_CCM_CSR_FPM_READY	(1 << 1)
+#define MXC_CCM_CSR_REF_EN_B	(1 << 0)
+
+/* Define the bits in register CCSR */
+#define MXC_CCM_CCSR_LP_APM_SEL		(0x1 << 9)
+#define MXC_CCM_CCSR_STEP_SEL_OFFSET	(7)
+#define MXC_CCM_CCSR_STEP_SEL_MASK	(0x3 << 7)
+#define MXC_CCM_CCSR_STEP_SEL_LP_APM	   0
+#define MXC_CCM_CCSR_STEP_SEL_PLL1_BYPASS  1 /* Only when JTAG connected? */
+#define MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED 2
+#define MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED 3
+#define MXC_CCM_CCSR_PLL2_PODF_OFFSET	(5)
+#define MXC_CCM_CCSR_PLL2_PODF_MASK	(0x3 << 5)
+#define MXC_CCM_CCSR_PLL3_PODF_OFFSET	(3)
+#define MXC_CCM_CCSR_PLL3_PODF_MASK	(0x3 << 3)
+#define MXC_CCM_CCSR_PLL1_SW_CLK_SEL	(1 << 2) /* 0: pll1_main_clk,
+						    1: step_clk */
+#define MXC_CCM_CCSR_PLL2_SW_CLK_SEL	(1 << 1)
+#define MXC_CCM_CCSR_PLL3_SW_CLK_SEL	(1 << 0)
+
+/* Define the bits in register CACRR */
+#define MXC_CCM_CACRR_ARM_PODF_OFFSET	(0)
+#define MXC_CCM_CACRR_ARM_PODF_MASK	(0x7)
+
+/* Define the bits in register CBCDR */
+#define MXC_CCM_CBCDR_EMI_CLK_SEL		(0x1 << 26)
+#define MXC_CCM_CBCDR_PERIPH_CLK_SEL		(0x1 << 25)
+#define MXC_CCM_CBCDR_DDR_HF_SEL_OFFSET		(30)
+#define MXC_CCM_CBCDR_DDR_HF_SEL		(0x1 << 30)
+#define MXC_CCM_CBCDR_DDR_PODF_OFFSET		(27)
+#define MXC_CCM_CBCDR_DDR_PODF_MASK		(0x7 << 27)
+#define MXC_CCM_CBCDR_EMI_PODF_OFFSET		(22)
+#define MXC_CCM_CBCDR_EMI_PODF_MASK		(0x7 << 22)
+#define MXC_CCM_CBCDR_AXI_B_PODF_OFFSET		(19)
+#define MXC_CCM_CBCDR_AXI_B_PODF_MASK		(0x7 << 19)
+#define MXC_CCM_CBCDR_AXI_A_PODF_OFFSET		(16)
+#define MXC_CCM_CBCDR_AXI_A_PODF_MASK		(0x7 << 16)
+#define MXC_CCM_CBCDR_NFC_PODF_OFFSET		(13)
+#define MXC_CCM_CBCDR_NFC_PODF_MASK		(0x7 << 13)
+#define MXC_CCM_CBCDR_AHB_PODF_OFFSET		(10)
+#define MXC_CCM_CBCDR_AHB_PODF_MASK		(0x7 << 10)
+#define MXC_CCM_CBCDR_IPG_PODF_OFFSET		(8)
+#define MXC_CCM_CBCDR_IPG_PODF_MASK		(0x3 << 8)
+#define MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET	(6)
+#define MXC_CCM_CBCDR_PERCLK_PRED1_MASK		(0x3 << 6)
+#define MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET	(3)
+#define MXC_CCM_CBCDR_PERCLK_PRED2_MASK		(0x7 << 3)
+#define MXC_CCM_CBCDR_PERCLK_PODF_OFFSET	(0)
+#define MXC_CCM_CBCDR_PERCLK_PODF_MASK		(0x7)
+
+/* Define the bits in register CBCMR */
+#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET	(14)
+#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK	(0x3 << 14)
+#define MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET	(12)
+#define MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK	(0x3 << 12)
+#define MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET	(10)
+#define MXC_CCM_CBCMR_DDR_CLK_SEL_MASK		(0x3 << 10)
+#define MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_OFFSET	(8)
+#define MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_MASK	(0x3 << 8)
+#define MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_OFFSET	(6)
+#define MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_MASK	(0x3 << 6)
+#define MXC_CCM_CBCMR_GPU_CLK_SEL_OFFSET	(4)
+#define MXC_CCM_CBCMR_GPU_CLK_SEL_MASK		(0x3 << 4)
+#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET	(14)
+#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK	(0x3 << 14)
+#define MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL	(0x1 << 1)
+#define MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL	(0x1 << 0)
+
+/* Define the bits in register CSCMR1 */
+#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET		(30)
+#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK		(0x3 << 30)
+#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET		(28)
+#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK		(0x3 << 28)
+#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET		(26)
+#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL			(0x1 << 26)
+#define MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET		(24)
+#define MXC_CCM_CSCMR1_UART_CLK_SEL_MASK		(0x3 << 24)
+#define MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET		(22)
+#define MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK		(0x3 << 22)
+#define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET	(20)
+#define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK	(0x3 << 20)
+#define MXC_CCM_CSCMR1_ESDHC3_CLK_SEL			(0x1 << 19)
+#define MXC_CCM_CSCMR1_ESDHC4_CLK_SEL			(0x1 << 18)
+#define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_OFFSET	(16)
+#define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_MASK	(0x3 << 16)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET		(14)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK		(0x3 << 14)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET		(12)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK		(0x3 << 12)
+#define MXC_CCM_CSCMR1_SSI3_CLK_SEL			(0x1 << 11)
+#define MXC_CCM_CSCMR1_VPU_RCLK_SEL			(0x1 << 10)
+#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_OFFSET		(8)
+#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_MASK		(0x3 << 8)
+#define MXC_CCM_CSCMR1_TVE_CLK_SEL			(0x1 << 7)
+#define MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL			(0x1 << 6)
+#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET		(4)
+#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK		(0x3 << 4)
+#define MXC_CCM_CSCMR1_SPDIF_CLK_SEL_OFFSET		(2)
+#define MXC_CCM_CSCMR1_SPDIF_CLK_SEL_MASK		(0x3 << 2)
+#define MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL		(0x1 << 1)
+#define MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL		(0x1)
+
+/* Define the bits in register CSCMR2 */
+#define MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET(n)		(26+n*3)
+#define MXC_CCM_CSCMR2_DI_CLK_SEL_MASK(n)		(0x7 << (26+n*3))
+#define MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_OFFSET		(24)
+#define MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_MASK		(0x3 << 24)
+#define MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_OFFSET		(22)
+#define MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_MASK		(0x3 << 22)
+#define MXC_CCM_CSCMR2_ESC_CLK_SEL_OFFSET		(20)
+#define MXC_CCM_CSCMR2_ESC_CLK_SEL_MASK			(0x3 << 20)
+#define MXC_CCM_CSCMR2_HSC2_CLK_SEL_OFFSET		(18)
+#define MXC_CCM_CSCMR2_HSC2_CLK_SEL_MASK		(0x3 << 18)
+#define MXC_CCM_CSCMR2_HSC1_CLK_SEL_OFFSET		(16)
+#define MXC_CCM_CSCMR2_HSC1_CLK_SEL_MASK		(0x3 << 16)
+#define MXC_CCM_CSCMR2_HSI2C_CLK_SEL_OFFSET		(14)
+#define MXC_CCM_CSCMR2_HSI2C_CLK_SEL_MASK		(0x3 << 14)
+#define MXC_CCM_CSCMR2_FIRI_CLK_SEL_OFFSET		(12)
+#define MXC_CCM_CSCMR2_FIRI_CLK_SEL_MASK		(0x3 << 12)
+#define MXC_CCM_CSCMR2_SIM_CLK_SEL_OFFSET		(10)
+#define MXC_CCM_CSCMR2_SIM_CLK_SEL_MASK			(0x3 << 10)
+#define MXC_CCM_CSCMR2_SLIMBUS_COM			(0x1 << 9)
+#define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_OFFSET		(6)
+#define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_MASK		(0x7 << 6)
+#define MXC_CCM_CSCMR2_SPDIF1_COM			(1 << 5)
+#define MXC_CCM_CSCMR2_SPDIF0_COM			(1 << 4)
+#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_OFFSET		(2)
+#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_MASK		(0x3 << 2)
+#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_OFFSET		(0)
+#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK		(0x3)
+
+/* Define the bits in register CSCDR1 */
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET	(22)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK	(0x7 << 22)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET	(19)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK	(0x7 << 19)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET	(16)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK	(0x7 << 16)
+#define MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET		(14)
+#define MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK		(0x3 << 14)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET	(11)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK	(0x7 << 11)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET		(8)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK		(0x7 << 8)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET		(6)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK		(0x3 << 6)
+#define MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET		(3)
+#define MXC_CCM_CSCDR1_UART_CLK_PRED_MASK		(0x7 << 3)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET		(0)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK		(0x7)
+
+/* Define the bits in register CS1CDR and CS2CDR */
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET		(22)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK		(0x7 << 22)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET		(16)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK		(0x3F << 16)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET		(6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK		(0x7 << 6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET		(0)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK		(0x3F)
+
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_OFFSET		(22)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_MASK		(0x7 << 22)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_OFFSET		(16)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_MASK		(0x3F << 16)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET		(6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK		(0x7 << 6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET		(0)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK		(0x3F)
+
+/* Define the bits in register CDCDR */
+#define MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET		(28)
+#define MXC_CCM_CDCDR_TVE_CLK_PRED_MASK			(0x7 << 28)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET		(25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK		(0x7 << 25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET		(19)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK		(0x3F << 19)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET		(16)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK		(0x7 << 16)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET		(9)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK		(0x3F << 9)
+#define MXC_CCM_CDCDR_DI_CLK_PRED_OFFSET		(6)
+#define MXC_CCM_CDCDR_DI_CLK_PRED_MASK			(0x7 << 6)
+#define MXC_CCM_CDCDR_USB_PHY_PRED_OFFSET		(3)
+#define MXC_CCM_CDCDR_USB_PHY_PRED_MASK			(0x7 << 3)
+#define MXC_CCM_CDCDR_USB_PHY_PODF_OFFSET		(0)
+#define MXC_CCM_CDCDR_USB_PHY_PODF_MASK			(0x7)
+
+/* Define the bits in register CHSCCDR */
+#define MXC_CCM_CHSCCDR_ESC_CLK_PRED_OFFSET		(12)
+#define MXC_CCM_CHSCCDR_ESC_CLK_PRED_MASK		(0x7 << 12)
+#define MXC_CCM_CHSCCDR_ESC_CLK_PODF_OFFSET		(6)
+#define MXC_CCM_CHSCCDR_ESC_CLK_PODF_MASK		(0x3F << 6)
+#define MXC_CCM_CHSCCDR_HSC2_CLK_PODF_OFFSET		(3)
+#define MXC_CCM_CHSCCDR_HSC2_CLK_PODF_MASK		(0x7 << 3)
+#define MXC_CCM_CHSCCDR_HSC1_CLK_PODF_OFFSET		(0)
+#define MXC_CCM_CHSCCDR_HSC1_CLK_PODF_MASK		(0x7)
+
+/* Define the bits in register CSCDR2 */
+#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET		(25)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK		(0x7 << 25)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET		(19)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK		(0x3F << 19)
+#define MXC_CCM_CSCDR2_SIM_CLK_PRED_OFFSET		(16)
+#define MXC_CCM_CSCDR2_SIM_CLK_PRED_MASK		(0x7 << 16)
+#define MXC_CCM_CSCDR2_SIM_CLK_PODF_OFFSET		(9)
+#define MXC_CCM_CSCDR2_SIM_CLK_PODF_MASK		(0x3F << 9)
+#define MXC_CCM_CSCDR2_SLIMBUS_CLK_PRED_OFFSET		(6)
+#define MXC_CCM_CSCDR2_SLIMBUS_PRED_MASK		(0x7 << 6)
+#define MXC_CCM_CSCDR2_SLIMBUS_PODF_OFFSET		(0)
+#define MXC_CCM_CSCDR2_SLIMBUS_PODF_MASK		(0x3F)
+
+/* Define the bits in register CSCDR3 */
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PRED_OFFSET		(16)
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PRED_MASK		(0x7 << 16)
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PODF_OFFSET		(9)
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PODF_MASK		(0x3F << 9)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PRED_OFFSET		(6)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PRED_MASK		(0x7 << 6)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PODF_OFFSET		(0)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PODF_MASK		(0x3F)
+
+/* Define the bits in register CSCDR4 */
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_OFFSET	(16)
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_MASK		(0x7 << 16)
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_OFFSET	(9)
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_MASK		(0x3F << 9)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_OFFSET	(6)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_MASK		(0x7 << 6)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_OFFSET	(0)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_MASK		(0x3F)
+
+/* Define the bits in register CDHIPR */
+#define MXC_CCM_CDHIPR_ARM_PODF_BUSY			(1 << 16)
+#define MXC_CCM_CDHIPR_DDR_HF_CLK_SEL_BUSY		(1 << 8)
+#define MXC_CCM_CDHIPR_DDR_PODF_BUSY			(1 << 7)
+#define MXC_CCM_CDHIPR_EMI_CLK_SEL_BUSY			(1 << 6)
+#define MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY		(1 << 5)
+#define MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY	(1 << 4)
+#define MXC_CCM_CDHIPR_AHB_PODF_BUSY			(1 << 3)
+#define MXC_CCM_CDHIPR_EMI_PODF_BUSY			(1 << 2)
+#define MXC_CCM_CDHIPR_AXI_B_PODF_BUSY			(1 << 1)
+#define MXC_CCM_CDHIPR_AXI_A_PODF_BUSY			(1 << 0)
+
+/* Define the bits in register CDCR */
+#define MXC_CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER		(0x1 << 2)
+#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_OFFSET	(0)
+#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK		(0x3)
+
+/* Define the bits in register CLPCR */
+#define MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS		(0x1 << 23)
+#define MXC_CCM_CLPCR_BYPASS_SCC_LPM_HS		(0x1 << 22)
+#define MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS		(0x1 << 21)
+#define MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS	(0x1 << 20)
+#define MXC_CCM_CLPCR_BYPASS_EMI_LPM_HS		(0x1 << 19)
+#define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS		(0x1 << 18)
+#define MXC_CCM_CLPCR_BYPASS_RTIC_LPM_HS	(0x1 << 17)
+#define MXC_CCM_CLPCR_BYPASS_RNGC_LPM_HS	(0x1 << 16)
+#define MXC_CCM_CLPCR_COSC_PWRDOWN		(0x1 << 11)
+#define MXC_CCM_CLPCR_STBY_COUNT_OFFSET		(9)
+#define MXC_CCM_CLPCR_STBY_COUNT_MASK		(0x3 << 9)
+#define MXC_CCM_CLPCR_VSTBY			(0x1 << 8)
+#define MXC_CCM_CLPCR_DIS_REF_OSC		(0x1 << 7)
+#define MXC_CCM_CLPCR_SBYOS			(0x1 << 6)
+#define MXC_CCM_CLPCR_ARM_CLK_DIS_ON_LPM	(0x1 << 5)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET	(3)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK		(0x3 << 3)
+#define MXC_CCM_CLPCR_LPM_OFFSET		(0)
+#define MXC_CCM_CLPCR_LPM_MASK			(0x3)
+
+/* Define the bits in register CISR */
+#define MXC_CCM_CISR_ARM_PODF_LOADED			(0x1 << 25)
+#define MXC_CCM_CISR_NFC_IPG_INT_MEM_PODF_LOADED	(0x1 << 21)
+#define MXC_CCM_CISR_AHB_PODF_LOADED			(0x1 << 20)
+#define MXC_CCM_CISR_EMI_PODF_LOADED			(0x1 << 19)
+#define MXC_CCM_CISR_AXI_B_PODF_LOADED			(0x1 << 18)
+#define MXC_CCM_CISR_AXI_A_PODF_LOADED			(0x1 << 17)
+#define MXC_CCM_CISR_DIVIDER_LOADED			(0x1 << 16)
+#define MXC_CCM_CISR_COSC_READY				(0x1 << 6)
+#define MXC_CCM_CISR_CKIH2_READY			(0x1 << 5)
+#define MXC_CCM_CISR_CKIH_READY				(0x1 << 4)
+#define MXC_CCM_CISR_FPM_READY				(0x1 << 3)
+#define MXC_CCM_CISR_LRF_PLL3				(0x1 << 2)
+#define MXC_CCM_CISR_LRF_PLL2				(0x1 << 1)
+#define MXC_CCM_CISR_LRF_PLL1				(0x1)
+
+/* Define the bits in register CIMR */
+#define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED		(0x1 << 25)
+#define MXC_CCM_CIMR_MASK_NFC_IPG_INT_MEM_PODF_LOADED	(0x1 << 21)
+#define MXC_CCM_CIMR_MASK_EMI_PODF_LOADED		(0x1 << 20)
+#define MXC_CCM_CIMR_MASK_AXI_C_PODF_LOADED		(0x1 << 19)
+#define MXC_CCM_CIMR_MASK_AXI_B_PODF_LOADED		(0x1 << 18)
+#define MXC_CCM_CIMR_MASK_AXI_A_PODF_LOADED		(0x1 << 17)
+#define MXC_CCM_CIMR_MASK_DIVIDER_LOADED		(0x1 << 16)
+#define MXC_CCM_CIMR_MASK_COSC_READY			(0x1 << 5)
+#define MXC_CCM_CIMR_MASK_CKIH_READY			(0x1 << 4)
+#define MXC_CCM_CIMR_MASK_FPM_READY			(0x1 << 3)
+#define MXC_CCM_CIMR_MASK_LRF_PLL3			(0x1 << 2)
+#define MXC_CCM_CIMR_MASK_LRF_PLL2			(0x1 << 1)
+#define MXC_CCM_CIMR_MASK_LRF_PLL1			(0x1)
+
+/* Define the bits in register CCOSR */
+#define MXC_CCM_CCOSR_CKO2_EN_OFFSET			(0x1 << 24)
+#define MXC_CCM_CCOSR_CKO2_DIV_OFFSET			(21)
+#define MXC_CCM_CCOSR_CKO2_DIV_MASK			(0x7 << 21)
+#define MXC_CCM_CCOSR_CKO2_SEL_OFFSET			(16)
+#define MXC_CCM_CCOSR_CKO2_SEL_MASK			(0x1F << 16)
+#define MXC_CCM_CCOSR_CKOL_EN				(0x1 << 7)
+#define MXC_CCM_CCOSR_CKOL_DIV_OFFSET			(4)
+#define MXC_CCM_CCOSR_CKOL_DIV_MASK			(0x7 << 4)
+#define MXC_CCM_CCOSR_CKOL_SEL_OFFSET			(0)
+#define MXC_CCM_CCOSR_CKOL_SEL_MASK			(0xF)
+
+/* Define the bits in registers CGPR */
+#define MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE		(0x1 << 4)
+#define MXC_CCM_CGPR_FPM_SEL				(0x1 << 3)
+#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_OFFSET		(0)
+#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_MASK		(0x7)
+
+/* Define the bits in registers CCGRx */
+#define MXC_CCM_CCGRx_CG_MASK				0x3
+#define MXC_CCM_CCGRx_MOD_OFF				0x0
+#define MXC_CCM_CCGRx_MOD_ON				0x3
+#define MXC_CCM_CCGRx_MOD_IDLE				0x1
+
+#define MXC_CCM_CCGRx_CG15_MASK				(0x3 << 30)
+#define MXC_CCM_CCGRx_CG14_MASK				(0x3 << 28)
+#define MXC_CCM_CCGRx_CG13_MASK				(0x3 << 26)
+#define MXC_CCM_CCGRx_CG12_MASK				(0x3 << 24)
+#define MXC_CCM_CCGRx_CG11_MASK				(0x3 << 22)
+#define MXC_CCM_CCGRx_CG10_MASK				(0x3 << 20)
+#define MXC_CCM_CCGRx_CG9_MASK				(0x3 << 18)
+#define MXC_CCM_CCGRx_CG8_MASK				(0x3 << 16)
+#define MXC_CCM_CCGRx_CG5_MASK				(0x3 << 10)
+#define MXC_CCM_CCGRx_CG4_MASK				(0x3 << 8)
+#define MXC_CCM_CCGRx_CG3_MASK				(0x3 << 6)
+#define MXC_CCM_CCGRx_CG2_MASK				(0x3 << 4)
+#define MXC_CCM_CCGRx_CG1_MASK				(0x3 << 2)
+#define MXC_CCM_CCGRx_CG0_MASK				(0x3 << 0)
+
+#define MXC_CCM_CCGRx_CG15_OFFSET			30
+#define MXC_CCM_CCGRx_CG14_OFFSET			28
+#define MXC_CCM_CCGRx_CG13_OFFSET			26
+#define MXC_CCM_CCGRx_CG12_OFFSET			24
+#define MXC_CCM_CCGRx_CG11_OFFSET			22
+#define MXC_CCM_CCGRx_CG10_OFFSET			20
+#define MXC_CCM_CCGRx_CG9_OFFSET			18
+#define MXC_CCM_CCGRx_CG8_OFFSET			16
+#define MXC_CCM_CCGRx_CG7_OFFSET			14
+#define MXC_CCM_CCGRx_CG6_OFFSET			12
+#define MXC_CCM_CCGRx_CG5_OFFSET			10
+#define MXC_CCM_CCGRx_CG4_OFFSET			8
+#define MXC_CCM_CCGRx_CG3_OFFSET			6
+#define MXC_CCM_CCGRx_CG2_OFFSET			4
+#define MXC_CCM_CCGRx_CG1_OFFSET			2
+#define MXC_CCM_CCGRx_CG0_OFFSET			0
+
+#define MXC_DPTC_LP_BASE	(MX51_GPC_BASE + 0x80)
+#define MXC_DPTC_GP_BASE	(MX51_GPC_BASE + 0x100)
+#define MXC_DVFS_CORE_BASE	(MX51_GPC_BASE + 0x180)
+#define MXC_DPTC_PER_BASE	(MX51_GPC_BASE + 0x1C0)
+#define MXC_PGC_IPU_BASE	(MX51_GPC_BASE + 0x220)
+#define MXC_PGC_VPU_BASE	(MX51_GPC_BASE + 0x240)
+#define MXC_PGC_GPU_BASE	(MX51_GPC_BASE + 0x260)
+#define MXC_SRPG_NEON_BASE	(MX51_GPC_BASE + 0x280)
+#define MXC_SRPG_ARM_BASE	(MX51_GPC_BASE + 0x2A0)
+#define MXC_SRPG_EMPGC0_BASE	(MX51_GPC_BASE + 0x2C0)
+#define MXC_SRPG_EMPGC1_BASE	(MX51_GPC_BASE + 0x2D0)
+#define MXC_SRPG_MEGAMIX_BASE	(MX51_GPC_BASE + 0x2E0)
+#define MXC_SRPG_EMI_BASE	(MX51_GPC_BASE + 0x300)
+
+/* CORTEXA8 platform */
+#define MXC_CORTEXA8_PLAT_PVID		(MX51_CORTEXA8_BASE + 0x0)
+#define MXC_CORTEXA8_PLAT_GPC		(MX51_CORTEXA8_BASE + 0x4)
+#define MXC_CORTEXA8_PLAT_PIC		(MX51_CORTEXA8_BASE + 0x8)
+#define MXC_CORTEXA8_PLAT_LPC		(MX51_CORTEXA8_BASE + 0xC)
+#define MXC_CORTEXA8_PLAT_NEON_LPC	(MX51_CORTEXA8_BASE + 0x10)
+#define MXC_CORTEXA8_PLAT_ICGC		(MX51_CORTEXA8_BASE + 0x14)
+#define MXC_CORTEXA8_PLAT_AMC		(MX51_CORTEXA8_BASE + 0x18)
+#define MXC_CORTEXA8_PLAT_NMC		(MX51_CORTEXA8_BASE + 0x20)
+#define MXC_CORTEXA8_PLAT_NMS		(MX51_CORTEXA8_BASE + 0x24)
+
+/* DVFS CORE */
+#define MXC_DVFSTHRS		(MXC_DVFS_CORE_BASE + 0x00)
+#define MXC_DVFSCOUN		(MXC_DVFS_CORE_BASE + 0x04)
+#define MXC_DVFSSIG1		(MXC_DVFS_CORE_BASE + 0x08)
+#define MXC_DVFSSIG0		(MXC_DVFS_CORE_BASE + 0x0C)
+#define MXC_DVFSGPC0		(MXC_DVFS_CORE_BASE + 0x10)
+#define MXC_DVFSGPC1		(MXC_DVFS_CORE_BASE + 0x14)
+#define MXC_DVFSGPBT		(MXC_DVFS_CORE_BASE + 0x18)
+#define MXC_DVFSEMAC		(MXC_DVFS_CORE_BASE + 0x1C)
+#define MXC_DVFSCNTR		(MXC_DVFS_CORE_BASE + 0x20)
+#define MXC_DVFSLTR0_0		(MXC_DVFS_CORE_BASE + 0x24)
+#define MXC_DVFSLTR0_1		(MXC_DVFS_CORE_BASE + 0x28)
+#define MXC_DVFSLTR1_0		(MXC_DVFS_CORE_BASE + 0x2C)
+#define MXC_DVFSLTR1_1		(MXC_DVFS_CORE_BASE + 0x30)
+#define MXC_DVFSPT0 		(MXC_DVFS_CORE_BASE + 0x34)
+#define MXC_DVFSPT1 		(MXC_DVFS_CORE_BASE + 0x38)
+#define MXC_DVFSPT2 		(MXC_DVFS_CORE_BASE + 0x3C)
+#define MXC_DVFSPT3 		(MXC_DVFS_CORE_BASE + 0x40)
+
+/* GPC */
+#define MXC_GPC_CNTR		(MX51_GPC_BASE + 0x0)
+#define MXC_GPC_PGR		(MX51_GPC_BASE + 0x4)
+#define MXC_GPC_VCR		(MX51_GPC_BASE + 0x8)
+#define MXC_GPC_ALL_PU		(MX51_GPC_BASE + 0xC)
+#define MXC_GPC_NEON		(MX51_GPC_BASE + 0x10)
+#define MXC_GPC_PGR_ARMPG_OFFSET	8
+#define MXC_GPC_PGR_ARMPG_MASK		(3 << 8)
+
+/* PGC */
+#define MXC_PGC_IPU_PGCR	(MXC_PGC_IPU_BASE + 0x0)
+#define MXC_PGC_IPU_PGSR	(MXC_PGC_IPU_BASE + 0xC)
+#define MXC_PGC_VPU_PGCR	(MXC_PGC_VPU_BASE + 0x0)
+#define MXC_PGC_VPU_PGSR	(MXC_PGC_VPU_BASE + 0xC)
+#define MXC_PGC_GPU_PGCR	(MXC_PGC_GPU_BASE + 0x0)
+#define MXC_PGC_GPU_PGSR	(MXC_PGC_GPU_BASE + 0xC)
+
+#define MXC_PGCR_PCR		1
+#define MXC_SRPGCR_PCR		1
+#define MXC_EMPGCR_PCR		1
+#define MXC_PGSR_PSR		1
+
+
+#define MXC_CORTEXA8_PLAT_LPC_DSM	(1 << 0)
+#define MXC_CORTEXA8_PLAT_LPC_DBG_DSM	(1 << 1)
+
+/* SRPG */
+#define MXC_SRPG_NEON_SRPGCR	(MXC_SRPG_NEON_BASE + 0x0)
+#define MXC_SRPG_NEON_PUPSCR	(MXC_SRPG_NEON_BASE + 0x4)
+#define MXC_SRPG_NEON_PDNSCR	(MXC_SRPG_NEON_BASE + 0x8)
+
+#define MXC_SRPG_ARM_SRPGCR	(MXC_SRPG_ARM_BASE + 0x0)
+#define MXC_SRPG_ARM_PUPSCR	(MXC_SRPG_ARM_BASE + 0x4)
+#define MXC_SRPG_ARM_PDNSCR	(MXC_SRPG_ARM_BASE + 0x8)
+
+#define MXC_SRPG_EMPGC0_SRPGCR	(MXC_SRPG_EMPGC0_BASE + 0x0)
+#define MXC_SRPG_EMPGC0_PUPSCR	(MXC_SRPG_EMPGC0_BASE + 0x4)
+#define MXC_SRPG_EMPGC0_PDNSCR	(MXC_SRPG_EMPGC0_BASE + 0x8)
+
+#define MXC_SRPG_EMPGC1_SRPGCR	(MXC_SRPG_EMPGC1_BASE + 0x0)
+#define MXC_SRPG_EMPGC1_PUPSCR	(MXC_SRPG_EMPGC1_BASE + 0x4)
+#define MXC_SRPG_EMPGC1_PDNSCR	(MXC_SRPG_EMPGC1_BASE + 0x8)
+
+#define MXC_SRPG_MEGAMIX_SRPGCR		(MXC_SRPG_MEGAMIX_BASE + 0x0)
+#define MXC_SRPG_MEGAMIX_PUPSCR		(MXC_SRPG_MEGAMIX_BASE + 0x4)
+#define MXC_SRPG_MEGAMIX_PDNSCR		(MXC_SRPG_MEGAMIX_BASE + 0x8)
+
+#define MXC_SRPGC_EMI_SRPGCR	(MXC_SRPGC_EMI_BASE + 0x0)
+#define MXC_SRPGC_EMI_PUPSCR	(MXC_SRPGC_EMI_BASE + 0x4)
+#define MXC_SRPGC_EMI_PDNSCR	(MXC_SRPGC_EMI_BASE + 0x8)
+
+#endif				/* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/devices.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/devices.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/devices.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/devices.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2009 Amit Kucheria <amit.kucheria@canonical.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/platform_device.h>
+#include <mach/hardware.h>
+#include <mach/imx-uart.h>
+
+static struct resource uart0[] = {
+	{
+		.start = MX51_UART1_BASE_ADDR,
+		.end = MX51_UART1_BASE_ADDR + 0xfff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MX51_MXC_INT_UART1,
+		.end = MX51_MXC_INT_UART1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_uart_device0 = {
+	.name = "imx-uart",
+	.id = 0,
+	.resource = uart0,
+	.num_resources = ARRAY_SIZE(uart0),
+};
+
+static struct resource uart1[] = {
+	{
+		.start = MX51_UART2_BASE_ADDR,
+		.end = MX51_UART2_BASE_ADDR + 0xfff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MX51_MXC_INT_UART2,
+		.end = MX51_MXC_INT_UART2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_uart_device1 = {
+	.name = "imx-uart",
+	.id = 1,
+	.resource = uart1,
+	.num_resources = ARRAY_SIZE(uart1),
+};
+
+static struct resource uart2[] = {
+	{
+		.start = MX51_UART3_BASE_ADDR,
+		.end = MX51_UART3_BASE_ADDR + 0xfff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MX51_MXC_INT_UART3,
+		.end = MX51_MXC_INT_UART3,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_uart_device2 = {
+	.name = "imx-uart",
+	.id = 2,
+	.resource = uart2,
+	.num_resources = ARRAY_SIZE(uart2),
+};
+
+static struct resource mxc_fec_resources[] = {
+	{
+		.start	= MX51_MXC_FEC_BASE_ADDR,
+		.end	= MX51_MXC_FEC_BASE_ADDR + 0xfff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= MX51_MXC_INT_FEC,
+		.end	= MX51_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,
+};
+
+/* Dummy definition to allow compiling in AVIC and TZIC simultaneously */
+int __init mxc_register_gpios(void)
+{
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/devices.h linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/devices.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/devices.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/devices.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,4 @@
+extern struct platform_device mxc_uart_device0;
+extern struct platform_device mxc_uart_device1;
+extern struct platform_device mxc_uart_device2;
+extern struct platform_device mxc_fec_device;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,18 @@
+if ARCH_MX5
+
+config ARCH_MX51
+	bool
+	default y
+	select MXC_TZIC
+	select ARCH_MXC_IOMUX_V3
+
+comment "MX5 platforms:"
+
+config MACH_MX51_BABBAGE
+	bool "Support MX51 BABBAGE platforms"
+	help
+	  Include support for MX51 Babbage platform, also known as MX51EVK in
+	  u-boot. This includes specific configurations for the board and its
+	  peripherals.
+
+endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,9 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+obj-y   := cpu.o mm.o clock-mx51.o devices.o
+
+obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/Makefile.boot linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/Makefile.boot
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/Makefile.boot	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,3 @@
+   zreladdr-y	:= 0x90008000
+params_phys-y	:= 0x90000100
+initrd_phys-y	:= 0x90800000
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/mm.c linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/mm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mx5/mm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mx5/mm.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License.  You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Create static mapping between physical to virtual memory.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-v3.h>
+
+/*
+ * Define the MX51 memory map.
+ */
+static struct map_desc mxc_io_desc[] __initdata = {
+	{
+		.virtual = MX51_IRAM_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(MX51_IRAM_BASE_ADDR),
+		.length = MX51_IRAM_SIZE,
+		.type = MT_DEVICE
+	}, {
+		.virtual = MX51_DEBUG_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(MX51_DEBUG_BASE_ADDR),
+		.length = MX51_DEBUG_SIZE,
+		.type = MT_DEVICE
+	}, {
+		.virtual = MX51_AIPS1_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR),
+		.length = MX51_AIPS1_SIZE,
+		.type = MT_DEVICE
+	}, {
+		.virtual = MX51_SPBA0_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(MX51_SPBA0_BASE_ADDR),
+		.length = MX51_SPBA0_SIZE,
+		.type = MT_DEVICE
+	}, {
+		.virtual = MX51_AIPS2_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR),
+		.length = MX51_AIPS2_SIZE,
+		.type = MT_DEVICE
+	},
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx51_map_io(void)
+{
+	mxc_set_cpu_type(MXC_CPU_MX51);
+	mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
+	mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR));
+	iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
+}
+
+void __init mx51_init_irq(void)
+{
+	unsigned long tzic_addr;
+	void __iomem *tzic_virt;
+
+	if (mx51_revision() < MX51_CHIP_REV_2_0)
+		tzic_addr = MX51_TZIC_BASE_ADDR_TO1;
+	else
+		tzic_addr = MX51_TZIC_BASE_ADDR;
+
+	tzic_virt = ioremap(tzic_addr, SZ_16K);
+	if (!tzic_virt)
+		panic("unable to map TZIC interrupt controller\n");
+
+	tzic_init_irq(tzic_virt);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mxc91231/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-mxc91231/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mxc91231/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mxc91231/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -624,7 +624,6 @@ static struct clk_lookup lookups[] = {
 int __init mxc91231_clocks_init(unsigned long fref)
 {
 	void __iomem *gpt_base;
-	int i;
 
 	ckih_rate = fref;
 
@@ -632,8 +631,7 @@ int __init mxc91231_clocks_init(unsigned
 	sdhc_clk[0].parent = clk_sdhc_parent(&sdhc_clk[0]);
 	sdhc_clk[1].parent = clk_sdhc_parent(&sdhc_clk[1]);
 
-	for (i = 0; i < ARRAY_SIZE(lookups); i++)
-		clkdev_add(&lookups[i]);
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	gpt_base = MXC91231_IO_ADDRESS(MXC91231_GPT1_BASE_ADDR);
 	mxc_timer_init(&gpt_clk, gpt_base, MXC91231_INT_GPT);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-mxc91231/magx-zn5.c linux-libre-2.6.34-gnu1/arch/arm/mach-mxc91231/magx-zn5.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-mxc91231/magx-zn5.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-mxc91231/magx-zn5.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,7 +55,7 @@ struct sys_timer zn5_timer = {
 MACHINE_START(MAGX_ZN5, "Motorola Zn5")
 	.phys_io	= MXC91231_AIPS1_BASE_ADDR,
 	.io_pg_offst	= ((MXC91231_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
-	.boot_params	= PHYS_OFFSET + 0x100,
+	.boot_params	= MXC91231_PHYS_OFFSET + 0x100,
 	.map_io		= mxc91231_map_io,
 	.init_irq	= mxc91231_init_irq,
 	.timer		= &zn5_timer,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-netx/fb.c linux-libre-2.6.34-gnu1/arch/arm/mach-netx/fb.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-netx/fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-netx/fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
 #include <linux/err.h>
+#include <linux/gfp.h>
 
 #include <asm/irq.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-netx/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-netx/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-netx/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-netx/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,7 @@
 
 #include "hardware.h"
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #0x00100000		@ physical
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-netx/xc.c linux-libre-2.6.34-gnu1/arch/arm/mach-netx/xc.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-netx/xc.c	2013-05-03 12:02:46.000000000 -0400
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-netx/xc.c	2013-05-03 09:43:50.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/board-nhk8815.c linux-libre-2.6.34-gnu1/arch/arm/mach-nomadik/board-nhk8815.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/board-nhk8815.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nomadik/board-nhk8815.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,7 +38,7 @@
 #define SRC_CR_INIT_MASK	0x00007fff
 #define SRC_CR_INIT_VAL		0x2aaa8000
 
-/* These adresses span 16MB, so use three individual pages */
+/* These addresses span 16MB, so use three individual pages */
 static struct resource nhk8815_nand_resources[] = {
 	{
 		.name = "nand_addr",
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/cpu-8815.c linux-libre-2.6.34-gnu1/arch/arm/mach-nomadik/cpu-8815.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/cpu-8815.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nomadik/cpu-8815.c	2010-05-16 17:17:36.000000000 -0400
@@ -86,11 +86,19 @@ static struct amba_device cpu8815_amba_g
 	},
 };
 
+static struct amba_device cpu8815_amba_rng = {
+	.dev = {
+		.init_name = "rng",
+	},
+	__MEM_4K_RESOURCE(NOMADIK_RNG_BASE),
+};
+
 static struct amba_device *amba_devs[] __initdata = {
 	cpu8815_amba_gpio + 0,
 	cpu8815_amba_gpio + 1,
 	cpu8815_amba_gpio + 2,
 	cpu8815_amba_gpio + 3,
+	&cpu8815_amba_rng
 };
 
 static int __init cpu8815_init(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/gpio.c linux-libre-2.6.34-gnu1/arch/arm/mach-nomadik/gpio.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nomadik/gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <mach/gpio.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-nomadik/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nomadik/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,7 @@
  *
 */
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #0x10000000	@ physical base address
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-nomadik/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nomadik/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,2 +1,2 @@
 
-#define VMALLOC_END       0xe8000000
+#define VMALLOC_END       0xe8000000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ns9xxx/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-ns9xxx/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ns9xxx/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ns9xxx/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
 
 #include <mach/regs-board-a9m9750dev.h>
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1
 		ldreq	\rx, =NS9XXX_CSxSTAT_PHYS(0)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ns9xxx/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-ns9xxx/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ns9xxx/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ns9xxx/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
-#define VMALLOC_END     (0xf0000000)
+#define VMALLOC_END     (0xf0000000UL)
 
 #endif /* ifndef __ASM_ARCH_VMALLOC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ns9xxx/plat-serial8250.c linux-libre-2.6.34-gnu1/arch/arm/mach-ns9xxx/plat-serial8250.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ns9xxx/plat-serial8250.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ns9xxx/plat-serial8250.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 #include <linux/platform_device.h>
 #include <linux/serial_8250.h>
+#include <linux/slab.h>
 
 #include <mach/regs-board-a9m9750dev.h>
 #include <mach/board.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ns9xxx/processor-ns9360.c linux-libre-2.6.34-gnu1/arch/arm/mach-ns9xxx/processor-ns9360.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ns9xxx/processor-ns9360.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ns9xxx/processor-ns9360.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
  */
 #include <linux/io.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 
 #include <asm/page.h>
 #include <asm/mach/map.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/clock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,83 @@
+/*
+ * linux/arch/arm/mach-nuc93x/clock.c
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#include "clock.h"
+
+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->enable)(clk, 1);
+	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->enable)(clk, 0);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return 27000000;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void nuc93x_clk_enable(struct clk *clk, int enable)
+{
+	unsigned int clocks = clk->cken;
+	unsigned long clken;
+
+	clken = __raw_readl(NUC93X_VA_CLKPWR);
+
+	if (enable)
+		clken |= clocks;
+	else
+		clken &= ~clocks;
+
+	__raw_writel(clken, NUC93X_VA_CLKPWR);
+}
+
+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.33-gnu1/arch/arm/mach-nuc93x/clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/arm/mach-nuc93x/clock.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+
+#include <asm/clkdev.h>
+
+void nuc93x_clk_enable(struct clk *clk, int enable);
+void clks_register(struct clk_lookup *clks, size_t num);
+
+struct clk {
+	unsigned long		cken;
+	unsigned int		enabled;
+	void			(*enable)(struct clk *, int enable);
+};
+
+#define DEFINE_CLK(_name, _ctrlbit)			\
+struct clk clk_##_name = {				\
+		.enable	= nuc93x_clk_enable,		\
+		.cken	= (1 << _ctrlbit),		\
+	}
+
+#define DEF_CLKLOOK(_clk, _devname, _conname)		\
+	{						\
+		.clk		= _clk,			\
+		.dev_id		= _devname,		\
+		.con_id		= _conname,		\
+	}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/cpu.c linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/cpu.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/cpu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/cpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,135 @@
+/*
+ * linux/arch/arm/mach-nuc93x/cpu.c
+ *
+ * Copyright (c) 2009 Nuvoton corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * NUC93x series cpu common support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/serial_8250.h>
+#include <linux/delay.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-serial.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-ebi.h>
+
+#include "cpu.h"
+#include "clock.h"
+
+/* Initial IO mappings */
+
+static struct map_desc nuc93x_iodesc[] __initdata = {
+	IODESC_ENT(IRQ),
+	IODESC_ENT(GCR),
+	IODESC_ENT(UART),
+	IODESC_ENT(TIMER),
+	IODESC_ENT(EBI),
+};
+
+/* Initial nuc932 clock declarations. */
+static DEFINE_CLK(audio, 2);
+static DEFINE_CLK(sd, 3);
+static DEFINE_CLK(jpg, 4);
+static DEFINE_CLK(video, 5);
+static DEFINE_CLK(vpost, 6);
+static DEFINE_CLK(2d, 7);
+static DEFINE_CLK(gpu, 8);
+static DEFINE_CLK(gdma, 9);
+static DEFINE_CLK(adc, 10);
+static DEFINE_CLK(uart, 11);
+static DEFINE_CLK(spi, 12);
+static DEFINE_CLK(pwm, 13);
+static DEFINE_CLK(timer, 14);
+static DEFINE_CLK(wdt, 15);
+static DEFINE_CLK(ac97, 16);
+static DEFINE_CLK(i2s, 16);
+static DEFINE_CLK(usbck, 17);
+static DEFINE_CLK(usb48, 18);
+static DEFINE_CLK(usbh, 19);
+static DEFINE_CLK(i2c, 20);
+static DEFINE_CLK(ext, 0);
+
+static struct clk_lookup nuc932_clkregs[] = {
+       DEF_CLKLOOK(&clk_audio, "nuc932-audio", NULL),
+       DEF_CLKLOOK(&clk_sd, "nuc932-sd", NULL),
+       DEF_CLKLOOK(&clk_jpg, "nuc932-jpg", "NULL"),
+       DEF_CLKLOOK(&clk_video, "nuc932-video", "NULL"),
+       DEF_CLKLOOK(&clk_vpost, "nuc932-vpost", NULL),
+       DEF_CLKLOOK(&clk_2d, "nuc932-2d", NULL),
+       DEF_CLKLOOK(&clk_gpu, "nuc932-gpu", NULL),
+       DEF_CLKLOOK(&clk_gdma, "nuc932-gdma", "NULL"),
+       DEF_CLKLOOK(&clk_adc, "nuc932-adc", NULL),
+       DEF_CLKLOOK(&clk_uart, NULL, "uart"),
+       DEF_CLKLOOK(&clk_spi, "nuc932-spi", NULL),
+       DEF_CLKLOOK(&clk_pwm, "nuc932-pwm", NULL),
+       DEF_CLKLOOK(&clk_timer, NULL, "timer"),
+       DEF_CLKLOOK(&clk_wdt, "nuc932-wdt", NULL),
+       DEF_CLKLOOK(&clk_ac97, "nuc932-ac97", NULL),
+       DEF_CLKLOOK(&clk_i2s, "nuc932-i2s", NULL),
+       DEF_CLKLOOK(&clk_usbck, "nuc932-usbck", NULL),
+       DEF_CLKLOOK(&clk_usb48, "nuc932-usb48", NULL),
+       DEF_CLKLOOK(&clk_usbh, "nuc932-usbh", NULL),
+       DEF_CLKLOOK(&clk_i2c, "nuc932-i2c", NULL),
+       DEF_CLKLOOK(&clk_ext, NULL, "ext"),
+};
+
+/* Initial serial platform data */
+
+struct plat_serial8250_port nuc93x_uart_data[] = {
+	NUC93X_8250PORT(UART0),
+	{},
+};
+
+struct platform_device nuc93x_serial_device = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= nuc93x_uart_data,
+	},
+};
+
+/*Init NUC93x evb io*/
+
+void __init nuc93x_map_io(struct map_desc *mach_desc, int mach_size)
+{
+	unsigned long idcode = 0x0;
+
+	iotable_init(mach_desc, mach_size);
+	iotable_init(nuc93x_iodesc, ARRAY_SIZE(nuc93x_iodesc));
+
+	idcode = __raw_readl(NUC93XPDID);
+	if (idcode == NUC932_CPUID)
+		printk(KERN_INFO "CPU type 0x%08lx is NUC910\n", idcode);
+	else
+		printk(KERN_ERR "CPU type detect error!\n");
+
+}
+
+/*Init NUC93x clock*/
+
+void __init nuc93x_init_clocks(void)
+{
+	clks_register(nuc932_clkregs, ARRAY_SIZE(nuc932_clkregs));
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/cpu.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/cpu.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/cpu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/cpu.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ * arch/arm/mach-nuc93x/cpu.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Header file for NUC93X CPU support
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define IODESC_ENT(y)					\
+{							\
+	.virtual = (unsigned long)NUC93X_VA_##y,	\
+	.pfn     = __phys_to_pfn(NUC93X_PA_##y),	\
+	.length  = NUC93X_SZ_##y,			\
+	.type    = MT_DEVICE,				\
+}
+
+#define NUC93X_8250PORT(name)					\
+{								\
+	.membase	= name##_BA,				\
+	.mapbase	= name##_PA,				\
+	.irq		= IRQ_##name,				\
+	.uartclk	= 57139200,				\
+	.regshift	= 2,					\
+	.iotype		= UPIO_MEM,				\
+	.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,	\
+}
+
+/*Cpu identifier register*/
+
+#define NUC93XPDID	NUC93X_VA_GCR
+#define NUC932_CPUID	0x29550091
+
+/* extern file from cpu.c */
+
+extern void nuc93x_clock_source(struct device *dev, unsigned char *src);
+extern void nuc93x_init_clocks(void);
+extern void nuc93x_map_io(struct map_desc *mach_desc, int mach_size);
+extern void nuc93x_board_init(struct platform_device **device, int size);
+extern struct platform_device nuc93x_serial_device;
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/dev.c linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/dev.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/dev.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,42 @@
+/*
+ * linux/arch/arm/mach-nuc93x/dev.c
+ *
+ * Copyright (C) 2009 Nuvoton corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+
+#include "cpu.h"
+
+/*Here should be your evb resourse,such as LCD*/
+
+static struct platform_device *nuc93x_public_dev[] __initdata = {
+	&nuc93x_serial_device,
+};
+
+/* Provide adding specific CPU platform devices API */
+
+void __init nuc93x_board_init(struct platform_device **device, int size)
+{
+	platform_add_devices(device, size);
+	platform_add_devices(nuc93x_public_dev, ARRAY_SIZE(nuc93x_public_dev));
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/clkdev.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/clkdev.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/clkdev.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/clkdev.h	2010-05-16 17:17:36.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.33-gnu1/arch/arm/mach-nuc93x/include/mach/entry-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/entry-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/entry-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/entry-macro.S
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ */
+
+#include <mach/hardware.h>
+#include <mach/regs-irq.h>
+
+	.macro  get_irqnr_preamble, base, tmp
+	.endm
+
+	.macro  arch_ret_to_user, tmp1, tmp2
+	.endm
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+		mov	\base, #AIC_BA
+
+		ldr	\irqnr, [ \base, #AIC_IPER]
+		ldr	\irqnr, [ \base, #AIC_ISNR]
+		cmp	\irqnr, #0
+
+	.endm
+
+	/* currently don't need an disable_fiq macro */
+
+	.macro	disable_fiq
+	.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/hardware.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/hardware.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/hardware.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/hardware.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/io.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/io.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/io.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/io.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT	0xffffffff
+
+/*
+ * 1:1 mapping for ioremapped regions.
+ */
+
+#define __mem_pci(a)	(a)
+#define __io(a)		__typesafe_io(a)
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/irqs.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/irqs.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/irqs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,59 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/irqs.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define NUC93X_IRQ(x)	(x)
+
+/* Main cpu interrupts */
+
+#define IRQ_WDT		NUC93X_IRQ(1)
+#define IRQ_IRQ0	NUC93X_IRQ(2)
+#define IRQ_IRQ1	NUC93X_IRQ(3)
+#define IRQ_IRQ2	NUC93X_IRQ(4)
+#define IRQ_IRQ3	NUC93X_IRQ(5)
+#define IRQ_USBH	NUC93X_IRQ(6)
+#define IRQ_APU		NUC93X_IRQ(7)
+#define IRQ_VPOST	NUC93X_IRQ(8)
+#define IRQ_ADC		NUC93X_IRQ(9)
+#define IRQ_UART0	NUC93X_IRQ(10)
+#define IRQ_TIMER0	NUC93X_IRQ(11)
+#define IRQ_GPU0	NUC93X_IRQ(12)
+#define IRQ_GPU1	NUC93X_IRQ(13)
+#define IRQ_GPU2	NUC93X_IRQ(14)
+#define IRQ_GPU3	NUC93X_IRQ(15)
+#define IRQ_GPU4	NUC93X_IRQ(16)
+#define IRQ_VIN		NUC93X_IRQ(17)
+#define IRQ_USBD	NUC93X_IRQ(18)
+#define IRQ_VRAMLD	NUC93X_IRQ(19)
+#define IRQ_GDMA0	NUC93X_IRQ(20)
+#define IRQ_GDMA1	NUC93X_IRQ(21)
+#define IRQ_SDIO	NUC93X_IRQ(22)
+#define IRQ_FMI		NUC93X_IRQ(22)
+#define IRQ_JPEG	NUC93X_IRQ(23)
+#define IRQ_SPI0	NUC93X_IRQ(24)
+#define IRQ_SPI1	NUC93X_IRQ(25)
+#define IRQ_RTC		NUC93X_IRQ(26)
+#define IRQ_PWM0	NUC93X_IRQ(27)
+#define IRQ_PWM1	NUC93X_IRQ(28)
+#define IRQ_PWM2	NUC93X_IRQ(29)
+#define IRQ_PWM3	NUC93X_IRQ(30)
+#define IRQ_I2SAC97	NUC93X_IRQ(31)
+#define IRQ_CAP0	IRQ_PWM0
+#define IRQ_CAP1	IRQ_PWM1
+#define IRQ_CAP2	IRQ_PWM2
+#define IRQ_CAP3	IRQ_PWM3
+#define NR_IRQS		(IRQ_I2SAC97 + 1)
+
+#endif /* __ASM_ARCH_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/map.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/map.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/map.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/map.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,139 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/map.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H
+
+#define MAP_OFFSET	(0xfff00000)
+#define CLK_OFFSET	(0x10)
+
+#ifndef __ASSEMBLY__
+#define NUC93X_ADDR(x)	((void __iomem *)(0xF0000000 + ((x)&(~MAP_OFFSET))))
+#else
+#define NUC93X_ADDR(x)	(0xF0000000 + ((x)&(~MAP_OFFSET)))
+#endif
+
+ /*
+  * nuc932 hardware register definition
+  */
+
+#define NUC93X_PA_IRQ		(0xFFF83000)
+#define NUC93X_PA_GCR		(0xFFF00000)
+#define NUC93X_PA_EBI		(0xFFF01000)
+#define NUC93X_PA_UART		(0xFFF80000)
+#define NUC93X_PA_TIMER		(0xFFF81000)
+#define NUC93X_PA_GPIO		(0xFFF84000)
+#define NUC93X_PA_GDMA		(0xFFF03000)
+#define NUC93X_PA_USBHOST	(0xFFF0d000)
+#define NUC93X_PA_I2C		(0xFFF89000)
+#define NUC93X_PA_LCD		(0xFFF06000)
+#define NUC93X_PA_GE		(0xFFF05000)
+#define NUC93X_PA_ADC		(0xFFF85000)
+#define NUC93X_PA_RTC		(0xFFF87000)
+#define NUC93X_PA_PWM		(0xFFF82000)
+#define NUC93X_PA_ACTL		(0xFFF0a000)
+#define NUC93X_PA_USBDEV	(0xFFF0C000)
+#define NUC93X_PA_JEPEG		(0xFFF0e000)
+#define NUC93X_PA_CACHE_T	(0xFFF60000)
+#define NUC93X_PA_VRAM		(0xFFF0b000)
+#define NUC93X_PA_DMAC		(0xFFF09000)
+#define NUC93X_PA_I2SM		(0xFFF08000)
+#define NUC93X_PA_CACHE		(0xFFF02000)
+#define NUC93X_PA_GPU		(0xFFF04000)
+#define NUC93X_PA_VIDEOIN	(0xFFF07000)
+#define NUC93X_PA_SPI0		(0xFFF86000)
+#define NUC93X_PA_SPI1		(0xFFF88000)
+
+ /*
+  * nuc932 virtual address mapping.
+  * interrupt controller is the first thing we put in, to make
+  * the assembly code for the irq detection easier
+  */
+
+#define NUC93X_VA_IRQ		NUC93X_ADDR(0x00000000)
+#define NUC93X_SZ_IRQ		SZ_4K
+
+#define NUC93X_VA_GCR		NUC93X_ADDR(NUC93X_PA_IRQ)
+#define NUC93X_VA_CLKPWR	(NUC93X_VA_GCR+CLK_OFFSET)
+#define NUC93X_SZ_GCR		SZ_4K
+
+/* EBI management */
+
+#define NUC93X_VA_EBI		NUC93X_ADDR(NUC93X_PA_EBI)
+#define NUC93X_SZ_EBI		SZ_4K
+
+/* UARTs */
+
+#define NUC93X_VA_UART		NUC93X_ADDR(NUC93X_PA_UART)
+#define NUC93X_SZ_UART		SZ_4K
+
+/* Timers */
+
+#define NUC93X_VA_TIMER	NUC93X_ADDR(NUC93X_PA_TIMER)
+#define NUC93X_SZ_TIMER	SZ_4K
+
+/* GPIO ports */
+
+#define NUC93X_VA_GPIO		NUC93X_ADDR(NUC93X_PA_GPIO)
+#define NUC93X_SZ_GPIO		SZ_4K
+
+/* GDMA control */
+
+#define NUC93X_VA_GDMA		NUC93X_ADDR(NUC93X_PA_GDMA)
+#define NUC93X_SZ_GDMA		SZ_4K
+
+/* I2C hardware controller */
+
+#define NUC93X_VA_I2C		NUC93X_ADDR(NUC93X_PA_I2C)
+#define NUC93X_SZ_I2C		SZ_4K
+
+/* LCD controller*/
+
+#define NUC93X_VA_LCD		NUC93X_ADDR(NUC93X_PA_LCD)
+#define NUC93X_SZ_LCD		SZ_4K
+
+/* 2D controller*/
+
+#define NUC93X_VA_GE		NUC93X_ADDR(NUC93X_PA_GE)
+#define NUC93X_SZ_GE		SZ_4K
+
+/* ADC */
+
+#define NUC93X_VA_ADC		NUC93X_ADDR(NUC93X_PA_ADC)
+#define NUC93X_SZ_ADC		SZ_4K
+
+/* RTC */
+
+#define NUC93X_VA_RTC		NUC93X_ADDR(NUC93X_PA_RTC)
+#define NUC93X_SZ_RTC		SZ_4K
+
+/* Pulse Width Modulation(PWM) Registers */
+
+#define NUC93X_VA_PWM		NUC93X_ADDR(NUC93X_PA_PWM)
+#define NUC93X_SZ_PWM		SZ_4K
+
+/* Audio Controller controller */
+
+#define NUC93X_VA_ACTL		NUC93X_ADDR(NUC93X_PA_ACTL)
+#define NUC93X_SZ_ACTL		SZ_4K
+
+/* USB Device port */
+
+#define NUC93X_VA_USBDEV	NUC93X_ADDR(NUC93X_PA_USBDEV)
+#define NUC93X_SZ_USBDEV	SZ_4K
+
+/* USB host controller*/
+#define NUC93X_VA_USBHOST	NUC93X_ADDR(NUC93X_PA_USBHOST)
+#define NUC93X_SZ_USBHOST	SZ_4K
+
+#endif /* __ASM_ARCH_MAP_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/memory.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/memory.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/memory.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/memory.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET	UL(0x00000000)
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/regs-clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/regs-clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/regs-clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/regs-clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H
+
+/* Clock Control Registers  */
+#define CLK_BA		NUC93X_VA_CLKPWR
+#define REG_CLKEN	(CLK_BA + 0x00)
+#define REG_CLKSEL	(CLK_BA + 0x04)
+#define REG_CLKDIV	(CLK_BA + 0x08)
+#define REG_PLLCON0	(CLK_BA + 0x0C)
+#define REG_PLLCON1	(CLK_BA + 0x10)
+#define REG_PMCON	(CLK_BA + 0x14)
+#define REG_IRQWAKECON	(CLK_BA + 0x18)
+#define REG_IRQWAKEFLAG	(CLK_BA + 0x1C)
+#define REG_IPSRST	(CLK_BA + 0x20)
+#define REG_CLKEN1	(CLK_BA + 0x24)
+#define REG_CLKDIV1	(CLK_BA + 0x28)
+
+/* Define PLL freq setting */
+#define PLL_DISABLE		0x12B63
+#define	PLL_66MHZ		0x2B63
+#define	PLL_100MHZ		0x4F64
+#define PLL_120MHZ		0x4F63
+#define	PLL_166MHZ		0x4124
+#define	PLL_200MHZ		0x4F24
+
+/* Define AHB:CPUFREQ ratio */
+#define	AHB_CPUCLK_1_1		0x00
+#define	AHB_CPUCLK_1_2		0x01
+#define	AHB_CPUCLK_1_4		0x02
+#define	AHB_CPUCLK_1_8		0x03
+
+/* Define APB:AHB ratio */
+#define APB_AHB_1_2		0x01
+#define APB_AHB_1_4		0x02
+#define APB_AHB_1_8		0x03
+
+/* Define clock skew */
+#define DEFAULTSKEW		0x48
+
+#endif /*  __ASM_ARCH_REGS_CLOCK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/regs-ebi.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/regs-ebi.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/regs-ebi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/regs-ebi.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/regs-ebi.h
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_EBI_H
+#define __ASM_ARCH_REGS_EBI_H
+
+/* EBI Control Registers */
+
+#define EBI_BA		NUC93X_VA_EBI
+#define REG_EBICON	(EBI_BA + 0x00)
+#define REG_ROMCON	(EBI_BA + 0x04)
+#define REG_SDCONF0	(EBI_BA + 0x08)
+#define REG_SDCONF1	(EBI_BA + 0x0C)
+#define REG_SDTIME0	(EBI_BA + 0x10)
+#define REG_SDTIME1	(EBI_BA + 0x14)
+#define REG_EXT0CON	(EBI_BA + 0x18)
+#define REG_EXT1CON	(EBI_BA + 0x1C)
+#define REG_EXT2CON	(EBI_BA + 0x20)
+#define REG_EXT3CON	(EBI_BA + 0x24)
+#define REG_EXT4CON	(EBI_BA + 0x28)
+#define REG_CKSKEW	(EBI_BA + 0x2C)
+
+#endif /*  __ASM_ARCH_REGS_EBI_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/regs-irq.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/regs-irq.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/regs-irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/regs-irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef ___ASM_ARCH_REGS_IRQ_H
+#define ___ASM_ARCH_REGS_IRQ_H
+
+/* Advance Interrupt Controller (AIC) Registers */
+
+#define AIC_BA    		NUC93X_VA_IRQ
+
+#define REG_AIC_IRQSC		(AIC_BA+0x80)
+#define REG_AIC_GEN		(AIC_BA+0x84)
+#define REG_AIC_GASR		(AIC_BA+0x88)
+#define REG_AIC_GSCR		(AIC_BA+0x8C)
+#define REG_AIC_IRSR		(AIC_BA+0x100)
+#define REG_AIC_IASR		(AIC_BA+0x104)
+#define REG_AIC_ISR		(AIC_BA+0x108)
+#define REG_AIC_IPER		(AIC_BA+0x10C)
+#define REG_AIC_ISNR		(AIC_BA+0x110)
+#define REG_AIC_IMR		(AIC_BA+0x114)
+#define REG_AIC_OISR		(AIC_BA+0x118)
+#define REG_AIC_MECR		(AIC_BA+0x120)
+#define REG_AIC_MDCR		(AIC_BA+0x124)
+#define REG_AIC_SSCR		(AIC_BA+0x128)
+#define REG_AIC_SCCR		(AIC_BA+0x12C)
+#define REG_AIC_EOSCR		(AIC_BA+0x130)
+#define AIC_IPER		(0x10C)
+#define AIC_ISNR		(0x110)
+
+#endif /* ___ASM_ARCH_REGS_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/regs-serial.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/regs-serial.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/regs-serial.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/regs-serial.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,52 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/regs-serial.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARM_REGS_SERIAL_H
+#define __ASM_ARM_REGS_SERIAL_H
+
+#define UART0_BA	NUC93X_VA_UART
+#define UART1_BA	(NUC93X_VA_UART+0x100)
+
+#define UART0_PA	NUC93X_PA_UART
+#define UART1_PA	(NUC93X_PA_UART+0x100)
+
+
+#ifndef __ASSEMBLY__
+
+struct nuc93x_uart_clksrc {
+	const char	*name;
+	unsigned int	divisor;
+	unsigned int	min_baud;
+	unsigned int	max_baud;
+};
+
+struct nuc93x_uartcfg {
+	unsigned char	hwport;
+	unsigned char	unused;
+	unsigned short	flags;
+	unsigned long	uart_flags;
+
+	unsigned long	ucon;
+	unsigned long	ulcon;
+	unsigned long	ufcon;
+
+	struct nuc93x_uart_clksrc *clocks;
+	unsigned int	clocks_size;
+};
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_ARM_REGS_SERIAL_H */
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/regs-timer.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/regs-timer.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/regs-timer.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/regs-timer.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/regs-timer.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_TIMER_H
+#define __ASM_ARCH_REGS_TIMER_H
+
+/* Timer Registers */
+
+#define TMR_BA			NUC93X_VA_TIMER
+#define REG_TCSR0		(TMR_BA+0x00)
+#define REG_TICR0		(TMR_BA+0x08)
+#define REG_TDR0		(TMR_BA+0x10)
+#define REG_TISR		(TMR_BA+0x18)
+#define REG_WTCR		(TMR_BA+0x1C)
+
+#endif /*  __ASM_ARCH_REGS_TIMER_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/system.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/system.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/machnuc93x/include/mach/system.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <asm/proc-fns.h>
+
+static void arch_idle(void)
+{
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+	cpu_reset(0);
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/timex.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/timex.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/timex.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/timex.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE Now, I don't use it. */
+
+#define CLOCK_TICK_RATE 27000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/uncompress.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/uncompress.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/uncompress.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,50 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/uncompress.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+/* Defines for UART registers */
+
+#include <mach/regs-serial.h>
+#include <mach/map.h>
+#include <linux/serial_reg.h>
+
+#define arch_decomp_wdog()
+
+#define TX_DONE	(UART_LSR_TEMT | UART_LSR_THRE)
+static u32 * uart_base = (u32 *)UART0_PA;
+
+static void putc(int ch)
+{
+	/* Check THRE and TEMT bits before we transmit the character.
+	 */
+	while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
+		barrier();
+
+	*uart_base = ch;
+}
+
+static inline void flush(void)
+{
+}
+
+static void arch_decomp_setup(void)
+{
+}
+
+#endif/* __ASM_NUC93X_UNCOMPRESS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/vmalloc.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_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END	  (0xE0000000)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/irq.c linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/irq.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,66 @@
+/*
+ * linux/arch/arm/mach-nuc93x/irq.c
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/ptrace.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-irq.h>
+
+static void nuc93x_irq_mask(unsigned int irq)
+{
+	__raw_writel(1 << irq, REG_AIC_MDCR);
+}
+
+/*
+ * By the w90p910 spec,any irq,only write 1
+ * to REG_AIC_EOSCR for ACK
+ */
+
+static void nuc93x_irq_ack(unsigned int irq)
+{
+	__raw_writel(0x01, REG_AIC_EOSCR);
+}
+
+static void nuc93x_irq_unmask(unsigned int irq)
+{
+	__raw_writel(1 << irq, REG_AIC_MECR);
+
+}
+
+static struct irq_chip nuc93x_irq_chip = {
+	.ack	   = nuc93x_irq_ack,
+	.mask	   = nuc93x_irq_mask,
+	.unmask	   = nuc93x_irq_unmask,
+};
+
+void __init nuc93x_init_irq(void)
+{
+	int irqno;
+
+	__raw_writel(0xFFFFFFFE, REG_AIC_MDCR);
+
+	for (irqno = IRQ_WDT; irqno <= NR_IRQS; irqno++) {
+		set_irq_chip(irqno, &nuc93x_irq_chip);
+		set_irq_handler(irqno, handle_level_irq);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,19 @@
+if ARCH_NUC93X
+
+config CPU_NUC932
+	bool
+	help
+	  Support for NUC932 of Nuvoton NUC93X CPUs.
+
+menu "NUC932 Machines"
+
+config MACH_NUC932EVB
+	bool "Nuvoton NUC932 Evaluation Board"
+	default y
+	select CPU_NUC932
+	help
+	   Say Y here if you are using the Nuvoton NUC932EVB
+
+endmenu
+
+endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/mach-nuc932evb.c linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/mach-nuc932evb.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/mach-nuc932evb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/mach-nuc932evb.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,45 @@
+/*
+ * linux/arch/arm/mach-w90x900/mach-nuc910evb.c
+ *
+ * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
+ *
+ * Copyright (C) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <mach/map.h>
+
+#include "nuc932.h"
+
+static void __init nuc932evb_map_io(void)
+{
+	nuc932_map_io();
+	nuc932_init_clocks();
+	nuc932_init_uartclk();
+}
+
+static void __init nuc932evb_init(void)
+{
+	nuc932_board_init();
+}
+
+MACHINE_START(NUC932EVB, "NUC932EVB")
+	/* Maintainer: Wan ZongShun */
+	.phys_io	= NUC93X_PA_UART,
+	.io_pg_offst	= (((u32)NUC93X_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= 0,
+	.map_io		= nuc932evb_map_io,
+	.init_irq	= nuc93x_init_irq,
+	.init_machine	= nuc932evb_init,
+	.timer		= &nuc93x_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,14 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y				:= irq.o time.o dev.o cpu.o clock.o
+# NUC932 CPU support files
+
+obj-$(CONFIG_CPU_NUC932)	+= nuc932.o
+
+# machine support
+
+obj-$(CONFIG_MACH_NUC932EVB)	+= mach-nuc932evb.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/Makefile.boot linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/Makefile.boot
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/Makefile.boot	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,3 @@
+zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/nuc932.c linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/nuc932.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/nuc932.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/nuc932.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,65 @@
+/*
+ * linux/arch/arm/mach-nuc93x/nuc932.c
+ *
+ * Copyright (c) 2009 Nuvoton corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * NUC932 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+
+#include "cpu.h"
+#include "clock.h"
+
+/* define specific CPU platform device */
+
+static struct platform_device *nuc932_dev[] __initdata = {
+};
+
+/* define specific CPU platform io map */
+
+static struct map_desc nuc932evb_iodesc[] __initdata = {
+};
+
+/*Init NUC932 evb io*/
+
+void __init nuc932_map_io(void)
+{
+	nuc93x_map_io(nuc932evb_iodesc, ARRAY_SIZE(nuc932evb_iodesc));
+}
+
+/*Init NUC932 clock*/
+
+void __init nuc932_init_clocks(void)
+{
+	nuc93x_init_clocks();
+}
+
+/*enable NUC932 uart clock*/
+
+void __init nuc932_init_uartclk(void)
+{
+	struct clk *ck_uart = clk_get(NULL, "uart");
+	BUG_ON(IS_ERR(ck_uart));
+
+	clk_enable(ck_uart);
+}
+
+/*Init NUC932 board info*/
+
+void __init nuc932_board_init(void)
+{
+	nuc93x_board_init(nuc932_dev, ARRAY_SIZE(nuc932_dev));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/nuc932.h linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/nuc932.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/nuc932.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/nuc932.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-nuc93x/nuc932.h
+ *
+ * Copyright (c) 2008 Nuvoton corporation
+ *
+ * Header file for NUC93x CPU support
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+struct map_desc;
+struct sys_timer;
+
+/* core initialisation functions */
+
+extern void nuc93x_init_irq(void);
+extern struct sys_timer nuc93x_timer;
+
+/* extern file from nuc932.c */
+
+extern void nuc932_board_init(void);
+extern void nuc932_init_clocks(void);
+extern void nuc932_map_io(void);
+extern void nuc932_init_uartclk(void);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/time.c linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/time.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-nuc93x/time.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-nuc93x/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,100 @@
+/*
+ * linux/arch/arm/mach-nuc93x/time.c
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+#include <mach/system.h>
+#include <mach/map.h>
+#include <mach/regs-timer.h>
+
+#define RESETINT	0x01
+#define PERIOD		(0x01 << 27)
+#define ONESHOT		(0x00 << 27)
+#define COUNTEN		(0x01 << 30)
+#define INTEN		(0x01 << 29)
+
+#define TICKS_PER_SEC	100
+#define PRESCALE	0x63 /* Divider = prescale + 1 */
+
+unsigned int timer0_load;
+
+static unsigned long nuc93x_gettimeoffset(void)
+{
+	return 0;
+}
+
+/*IRQ handler for the timer*/
+
+static irqreturn_t nuc93x_timer_interrupt(int irq, void *dev_id)
+{
+	timer_tick();
+	__raw_writel(0x01, REG_TISR); /* clear TIF0 */
+	return IRQ_HANDLED;
+}
+
+static struct irqaction nuc93x_timer_irq = {
+	.name		= "nuc93x Timer Tick",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= nuc93x_timer_interrupt,
+};
+
+/*Set up timer reg.*/
+
+static void nuc93x_timer_setup(void)
+{
+	struct clk *ck_ext = clk_get(NULL, "ext");
+	struct clk *ck_timer = clk_get(NULL, "timer");
+	unsigned int rate, val = 0;
+
+	BUG_ON(IS_ERR(ck_ext) || IS_ERR(ck_timer));
+
+	clk_enable(ck_timer);
+	rate = clk_get_rate(ck_ext);
+	clk_put(ck_ext);
+	rate = rate / (PRESCALE + 0x01);
+
+	 /* set a known state */
+	__raw_writel(0x00, REG_TCSR0);
+	__raw_writel(RESETINT, REG_TISR);
+
+	timer0_load = (rate / TICKS_PER_SEC);
+	__raw_writel(timer0_load, REG_TICR0);
+
+	val |= (PERIOD | COUNTEN | INTEN | PRESCALE);;
+	__raw_writel(val, REG_TCSR0);
+
+}
+
+static void __init nuc93x_timer_init(void)
+{
+	nuc93x_timer_setup();
+	setup_irq(IRQ_TIMER0, &nuc93x_timer_irq);
+}
+
+struct sys_timer nuc93x_timer = {
+	.init		= nuc93x_timer_init,
+	.offset		= nuc93x_gettimeoffset,
+	.resume		= nuc93x_timer_setup
+};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-fsample.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-fsample.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-fsample.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-fsample.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,18 +18,19 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 #include <linux/input.h>
 #include <linux/smc91x.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
 #include <plat/tc.h>
 #include <mach/gpio.h>
 #include <plat/mux.h>
+#include <plat/flash.h>
 #include <plat/fpga.h>
 #include <plat/keypad.h>
 #include <plat/common.h>
@@ -150,9 +151,9 @@ static struct mtd_partition nor_partitio
 	},
 };
 
-static struct flash_platform_data nor_data = {
-	.map_name	= "cfi_probe",
+static struct physmap_flash_data nor_data = {
 	.width		= 2,
+	.set_vpp	= omap1_set_vpp,
 	.parts		= nor_partitions,
 	.nr_parts	= ARRAY_SIZE(nor_partitions),
 };
@@ -164,7 +165,7 @@ static struct resource nor_resource = {
 };
 
 static struct platform_device nor_device = {
-	.name		= "omapflash",
+	.name		= "physmap-flash",
 	.id		= 0,
 	.dev		= {
 		.platform_data	= &nor_data,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-h2.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-h2.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-h2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-h2.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 #include <linux/input.h>
 #include <linux/i2c/tps65010.h>
 #include <linux/smc91x.h>
@@ -35,7 +36,6 @@
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
 #include <plat/mux.h>
@@ -45,6 +45,7 @@
 #include <plat/usb.h>
 #include <plat/keypad.h>
 #include <plat/common.h>
+#include <plat/flash.h>
 
 #include "board-h2.h"
 
@@ -121,9 +122,9 @@ static struct mtd_partition h2_nor_parti
 	}
 };
 
-static struct flash_platform_data h2_nor_data = {
-	.map_name	= "cfi_probe",
+static struct physmap_flash_data h2_nor_data = {
 	.width		= 2,
+	.set_vpp	= omap1_set_vpp,
 	.parts		= h2_nor_partitions,
 	.nr_parts	= ARRAY_SIZE(h2_nor_partitions),
 };
@@ -134,7 +135,7 @@ static struct resource h2_nor_resource =
 };
 
 static struct platform_device h2_nor_device = {
-	.name		= "omapflash",
+	.name		= "physmap-flash",
 	.id		= 0,
 	.dev		= {
 		.platform_data	= &h2_nor_data,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-h3.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-h3.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-h3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-h3.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 #include <linux/input.h>
 #include <linux/spi/spi.h>
 #include <linux/i2c/tps65010.h>
@@ -37,7 +38,6 @@
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
 #include <mach/irqs.h>
@@ -47,6 +47,7 @@
 #include <plat/keypad.h>
 #include <plat/dma.h>
 #include <plat/common.h>
+#include <plat/flash.h>
 
 #include "board-h3.h"
 
@@ -126,9 +127,9 @@ static struct mtd_partition nor_partitio
 	}
 };
 
-static struct flash_platform_data nor_data = {
-	.map_name	= "cfi_probe",
+static struct physmap_flash_data nor_data = {
 	.width		= 2,
+	.set_vpp	= omap1_set_vpp,
 	.parts		= nor_partitions,
 	.nr_parts	= ARRAY_SIZE(nor_partitions),
 };
@@ -139,7 +140,7 @@ static struct resource nor_resource = {
 };
 
 static struct platform_device nor_device = {
-	.name		= "omapflash",
+	.name		= "physmap-flash",
 	.id		= 0,
 	.dev		= {
 		.platform_data	= &nor_data,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-innovator.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-innovator.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-innovator.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-innovator.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,16 +22,17 @@
 #include <linux/delay.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 #include <linux/input.h>
 #include <linux/smc91x.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
 #include <plat/mux.h>
+#include <plat/flash.h>
 #include <plat/fpga.h>
 #include <mach/gpio.h>
 #include <plat/tc.h>
@@ -94,9 +95,9 @@ static struct mtd_partition innovator_pa
 	}
 };
 
-static struct flash_platform_data innovator_flash_data = {
-	.map_name	= "cfi_probe",
+static struct physmap_flash_data innovator_flash_data = {
 	.width		= 2,
+	.set_vpp	= omap1_set_vpp,
 	.parts		= innovator_partitions,
 	.nr_parts	= ARRAY_SIZE(innovator_partitions),
 };
@@ -108,7 +109,7 @@ static struct resource innovator_flash_r
 };
 
 static struct platform_device innovator_flash_device = {
-	.name		= "omapflash",
+	.name		= "physmap-flash",
 	.id		= 0,
 	.dev		= {
 		.platform_data	= &innovator_flash_data,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-osk.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-osk.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-osk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-osk.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 
 #include <linux/i2c/tps65010.h>
 
@@ -46,8 +47,8 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <asm/mach/flash.h>
 
+#include <plat/flash.h>
 #include <plat/usb.h>
 #include <plat/mux.h>
 #include <plat/tc.h>
@@ -94,9 +95,9 @@ static struct mtd_partition osk_partitio
 	}
 };
 
-static struct flash_platform_data osk_flash_data = {
-	.map_name	= "cfi_probe",
+static struct physmap_flash_data osk_flash_data = {
 	.width		= 2,
+	.set_vpp	= omap1_set_vpp,
 	.parts		= osk_partitions,
 	.nr_parts	= ARRAY_SIZE(osk_partitions),
 };
@@ -107,7 +108,7 @@ static struct resource osk_flash_resourc
 };
 
 static struct platform_device osk5912_flash_device = {
-	.name		= "omapflash",
+	.name		= "physmap-flash",
 	.id		= 0,
 	.dev		= {
 		.platform_data	= &osk_flash_data,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-palmte.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-palmte.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-palmte.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-palmte.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 #include <linux/spi/spi.h>
 #include <linux/interrupt.h>
 #include <linux/apm-emulation.h>
@@ -31,9 +32,9 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <asm/mach/flash.h>
 
 #include <mach/gpio.h>
+#include <plat/flash.h>
 #include <plat/mux.h>
 #include <plat/usb.h>
 #include <plat/tc.h>
@@ -126,9 +127,9 @@ static struct mtd_partition palmte_rom_p
 	},
 };
 
-static struct flash_platform_data palmte_rom_data = {
-	.map_name	= "map_rom",
+static struct physmap_flash_data palmte_rom_data = {
 	.width		= 2,
+	.set_vpp	= omap1_set_vpp,
 	.parts		= palmte_rom_partitions,
 	.nr_parts	= ARRAY_SIZE(palmte_rom_partitions),
 };
@@ -140,7 +141,7 @@ static struct resource palmte_rom_resour
 };
 
 static struct platform_device palmte_rom_device = {
-	.name		= "omapflash",
+	.name		= "physmap-flash",
 	.id		= -1,
 	.dev		= {
 		.platform_data	= &palmte_rom_data,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-palmtt.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-palmtt.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-palmtt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-palmtt.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,16 +21,17 @@
 #include <linux/interrupt.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 #include <linux/leds.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <asm/mach/flash.h>
 
 #include <plat/led.h>
 #include <mach/gpio.h>
+#include <plat/flash.h>
 #include <plat/mux.h>
 #include <plat/usb.h>
 #include <plat/dma.h>
@@ -104,9 +105,9 @@ static struct mtd_partition palmtt_parti
 	}
 };
 
-static struct flash_platform_data palmtt_flash_data = {
-	.map_name	= "cfi_probe",
+static struct physmap_flash_data palmtt_flash_data = {
 	.width		= 2,
+	.set_vpp	= omap1_set_vpp,
 	.parts		= palmtt_partitions,
 	.nr_parts	= ARRAY_SIZE(palmtt_partitions),
 };
@@ -118,7 +119,7 @@ static struct resource palmtt_flash_reso
 };
 
 static struct platform_device palmtt_flash_device = {
-	.name		= "omapflash",
+	.name		= "physmap-flash",
 	.id		= 0,
 	.dev		= {
 		.platform_data	= &palmtt_flash_data,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-palmz71.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-palmz71.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-palmz71.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-palmz71.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,14 +25,15 @@
 #include <linux/interrupt.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <asm/mach/flash.h>
 
 #include <mach/gpio.h>
+#include <plat/flash.h>
 #include <plat/mux.h>
 #include <plat/usb.h>
 #include <plat/dma.h>
@@ -126,10 +127,9 @@ static struct mtd_partition palmz71_rom_
 	},
 };
 
-static struct flash_platform_data palmz71_rom_data = {
-	.map_name	= "map_rom",
-	.name		= "onboardrom",
+static struct physmap_flash_data palmz71_rom_data = {
 	.width		= 2,
+	.set_vpp	= omap1_set_vpp,
 	.parts		= palmz71_rom_partitions,
 	.nr_parts	= ARRAY_SIZE(palmz71_rom_partitions),
 };
@@ -141,7 +141,7 @@ static struct resource palmz71_rom_resou
 };
 
 static struct platform_device palmz71_rom_device = {
-	.name	= "omapflash",
+	.name	= "physmap-flash",
 	.id	= -1,
 	.dev = {
 		.platform_data = &palmz71_rom_data,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-perseus2.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-perseus2.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-perseus2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-perseus2.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,19 +18,20 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 #include <linux/input.h>
 #include <linux/smc91x.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
 #include <plat/tc.h>
 #include <mach/gpio.h>
 #include <plat/mux.h>
 #include <plat/fpga.h>
+#include <plat/flash.h>
 #include <plat/keypad.h>
 #include <plat/common.h>
 #include <plat/board.h>
@@ -117,9 +118,9 @@ static struct mtd_partition nor_partitio
 	},
 };
 
-static struct flash_platform_data nor_data = {
-	.map_name	= "cfi_probe",
+static struct physmap_flash_data nor_data = {
 	.width		= 2,
+	.set_vpp	= omap1_set_vpp,
 	.parts		= nor_partitions,
 	.nr_parts	= ARRAY_SIZE(nor_partitions),
 };
@@ -131,7 +132,7 @@ static struct resource nor_resource = {
 };
 
 static struct platform_device nor_device = {
-	.name		= "omapflash",
+	.name		= "physmap-flash",
 	.id		= 0,
 	.dev		= {
 		.platform_data	= &nor_data,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-sx1.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-sx1.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-sx1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-sx1.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/notifier.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 #include <linux/types.h>
 #include <linux/i2c.h>
 #include <linux/errno.h>
@@ -29,10 +30,10 @@
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
 #include <mach/gpio.h>
+#include <plat/flash.h>
 #include <plat/mux.h>
 #include <plat/dma.h>
 #include <plat/irda.h>
@@ -287,9 +288,9 @@ static struct mtd_partition sx1_partitio
 	}
 };
 
-static struct flash_platform_data sx1_flash_data = {
-	.map_name	= "cfi_probe",
+static struct physmap_flash_data sx1_flash_data = {
 	.width		= 2,
+	.set_vpp	= omap1_set_vpp,
 	.parts		= sx1_partitions,
 	.nr_parts	= ARRAY_SIZE(sx1_partitions),
 };
@@ -310,7 +311,7 @@ static struct resource sx1_old_flash_res
 };
 
 static struct platform_device sx1_flash_device = {
-	.name		= "omapflash",
+	.name		= "physmap-flash",
 	.id		= 0,
 	.dev		= {
 		.platform_data	= &sx1_flash_data,
@@ -327,7 +328,7 @@ static struct resource sx1_new_flash_res
 };
 
 static struct platform_device sx1_flash_device = {
-	.name		= "omapflash",
+	.name		= "physmap-flash",
 	.id		= 0,
 	.dev		= {
 		.platform_data	= &sx1_flash_data,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-voiceblue.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-voiceblue.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-voiceblue.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/board-voiceblue.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/irq.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/mtd/physmap.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/serial_8250.h>
@@ -27,11 +28,11 @@
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
 #include <plat/common.h>
 #include <mach/gpio.h>
+#include <plat/flash.h>
 #include <plat/mux.h>
 #include <plat/tc.h>
 #include <plat/usb.h>
@@ -86,9 +87,9 @@ static int __init ext_uart_init(void)
 }
 arch_initcall(ext_uart_init);
 
-static struct flash_platform_data voiceblue_flash_data = {
-	.map_name	= "cfi_probe",
+static struct physmap_flash_data voiceblue_flash_data = {
 	.width		= 2,
+	.set_vpp	= omap1_set_vpp,
 };
 
 static struct resource voiceblue_flash_resource = {
@@ -98,7 +99,7 @@ static struct resource voiceblue_flash_r
 };
 
 static struct platform_device voiceblue_flash_device = {
-	.name		= "omapflash",
+	.name		= "physmap-flash",
 	.id		= 0,
 	.dev		= {
 		.platform_data	= &voiceblue_flash_data,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/mach-omap1/clock.c
  *
- *  Copyright (C) 2004 - 2005, 2009 Nokia corporation
+ *  Copyright (C) 2004 - 2005, 2009-2010 Nokia Corporation
  *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
  *
  *  Modified to use omap shared clock framework by
@@ -38,26 +38,6 @@ struct clk *api_ck_p, *ck_dpll1_p, *ck_r
  * Omap1 specific clock functions
  *-------------------------------------------------------------------------*/
 
-static int clk_omap1_dummy_enable(struct clk *clk)
-{
-	return 0;
-}
-
-static void clk_omap1_dummy_disable(struct clk *clk)
-{
-}
-
-const struct clkops clkops_dummy = {
-	.enable		= clk_omap1_dummy_enable,
-	.disable	= clk_omap1_dummy_disable,
-};
-
-/* XXX can be replaced with a fixed_divisor_recalc */
-unsigned long omap1_watchdog_recalc(struct clk *clk)
-{
-	return clk->parent->rate / 14;
-}
-
 unsigned long omap1_uart_recalc(struct clk *clk)
 {
 	unsigned int val = __raw_readl(clk->enable_reg);
@@ -577,9 +557,6 @@ const struct clkops clkops_uart = {
 
 long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
 {
-	if (clk->flags & RATE_FIXED)
-		return clk->rate;
-
 	if (clk->round_rate != NULL)
 		return clk->round_rate(clk, rate);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/clock_data.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/clock_data.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/clock_data.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/clock_data.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/mach-omap1/clock_data.c
  *
- *  Copyright (C) 2004 - 2005, 2009 Nokia corporation
+ *  Copyright (C) 2004 - 2005, 2009-2010 Nokia Corporation
  *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
  *  Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
  *
@@ -27,13 +27,6 @@
  * Omap1 clocks
  *-------------------------------------------------------------------------*/
 
-/* XXX is this necessary? */
-static struct clk dummy_ck = {
-	.name	= "dummy",
-	.ops	= &clkops_dummy,
-	.flags	= RATE_FIXED,
-};
-
 static struct clk ck_ref = {
 	.name		= "ck_ref",
 	.ops		= &clkops_null,
@@ -149,7 +142,8 @@ static struct arm_idlect1_clk armwdt_ck
 		.flags		= CLOCK_IDLE_CONTROL,
 		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
 		.enable_bit	= EN_WDTCK,
-		.recalc		= &omap1_watchdog_recalc,
+		.fixed_div	= 14,
+		.recalc		= &omap_fixed_divisor_recalc,
 	},
 	.idlect_shift	= 0,
 };
@@ -388,8 +382,7 @@ static struct uart_clk uart1_16xx = {
 		/* Direct from ULPD, no real parent */
 		.parent		= &armper_ck.clk,
 		.rate		= 48000000,
-		.flags		= RATE_FIXED | ENABLE_REG_32BIT |
-				  CLOCK_NO_IDLE_PARENT,
+		.flags		= ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
 		.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
 		.enable_bit	= 29,
 	},
@@ -429,8 +422,7 @@ static struct uart_clk uart3_16xx = {
 		/* Direct from ULPD, no real parent */
 		.parent		= &armper_ck.clk,
 		.rate		= 48000000,
-		.flags		= RATE_FIXED | ENABLE_REG_32BIT |
-				  CLOCK_NO_IDLE_PARENT,
+		.flags		= ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
 		.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
 		.enable_bit	= 31,
 	},
@@ -442,7 +434,7 @@ static struct clk usb_clko = {	/* 6 MHz
 	.ops		= &clkops_generic,
 	/* Direct from ULPD, no parent */
 	.rate		= 6000000,
-	.flags		= RATE_FIXED | ENABLE_REG_32BIT,
+	.flags		= ENABLE_REG_32BIT,
 	.enable_reg	= OMAP1_IO_ADDRESS(ULPD_CLOCK_CTRL),
 	.enable_bit	= USB_MCLK_EN_BIT,
 };
@@ -452,7 +444,7 @@ static struct clk usb_hhc_ck1510 = {
 	.ops		= &clkops_generic,
 	/* Direct from ULPD, no parent */
 	.rate		= 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
-	.flags		= RATE_FIXED | ENABLE_REG_32BIT,
+	.flags		= ENABLE_REG_32BIT,
 	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
 	.enable_bit	= USB_HOST_HHC_UHOST_EN,
 };
@@ -463,7 +455,7 @@ static struct clk usb_hhc_ck16xx = {
 	/* Direct from ULPD, no parent */
 	.rate		= 48000000,
 	/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
-	.flags		= RATE_FIXED | ENABLE_REG_32BIT,
+	.flags		= ENABLE_REG_32BIT,
 	.enable_reg	= OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */
 	.enable_bit	= 8 /* UHOST_EN */,
 };
@@ -473,7 +465,6 @@ static struct clk usb_dc_ck = {
 	.ops		= &clkops_generic,
 	/* Direct from ULPD, no parent */
 	.rate		= 48000000,
-	.flags		= RATE_FIXED,
 	.enable_reg	= OMAP1_IO_ADDRESS(SOFT_REQ_REG),
 	.enable_bit	= 4,
 };
@@ -483,7 +474,6 @@ static struct clk usb_dc_ck7xx = {
 	.ops		= &clkops_generic,
 	/* Direct from ULPD, no parent */
 	.rate		= 48000000,
-	.flags		= RATE_FIXED,
 	.enable_reg	= OMAP1_IO_ADDRESS(SOFT_REQ_REG),
 	.enable_bit	= 8,
 };
@@ -493,7 +483,6 @@ static struct clk mclk_1510 = {
 	.ops		= &clkops_generic,
 	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
 	.rate		= 12000000,
-	.flags		= RATE_FIXED,
 	.enable_reg	= OMAP1_IO_ADDRESS(SOFT_REQ_REG),
 	.enable_bit	= 6,
 };
@@ -514,7 +503,6 @@ static struct clk bclk_1510 = {
 	.ops		= &clkops_generic,
 	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
 	.rate		= 12000000,
-	.flags		= RATE_FIXED,
 };
 
 static struct clk bclk_16xx = {
@@ -529,36 +517,34 @@ static struct clk bclk_16xx = {
 };
 
 static struct clk mmc1_ck = {
-	.name		= "mmc_ck",
+	.name		= "mmc1_ck",
 	.ops		= &clkops_generic,
 	/* Functional clock is direct from ULPD, interface clock is ARMPER */
 	.parent		= &armper_ck.clk,
 	.rate		= 48000000,
-	.flags		= RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+	.flags		= ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
 	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
 	.enable_bit	= 23,
 };
 
 static struct clk mmc2_ck = {
-	.name		= "mmc_ck",
-	.id		= 1,
+	.name		= "mmc2_ck",
 	.ops		= &clkops_generic,
 	/* Functional clock is direct from ULPD, interface clock is ARMPER */
 	.parent		= &armper_ck.clk,
 	.rate		= 48000000,
-	.flags		= RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+	.flags		= ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
 	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
 	.enable_bit	= 20,
 };
 
 static struct clk mmc3_ck = {
-	.name		= "mmc_ck",
-	.id		= 2,
+	.name		= "mmc3_ck",
 	.ops		= &clkops_generic,
 	/* Functional clock is direct from ULPD, interface clock is ARMPER */
 	.parent		= &armper_ck.clk,
 	.rate		= 48000000,
-	.flags		= RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+	.flags		= ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
 	.enable_reg	= OMAP1_IO_ADDRESS(SOFT_REQ_REG),
 	.enable_bit	= 12,
 };
@@ -576,7 +562,6 @@ static struct clk virtual_ck_mpu = {
 remains active during MPU idle whenever this is enabled */
 static struct clk i2c_fck = {
 	.name		= "i2c_fck",
-	.id		= 1,
 	.ops		= &clkops_null,
 	.flags		= CLOCK_NO_IDLE_PARENT,
 	.parent		= &armxor_ck.clk,
@@ -585,7 +570,6 @@ static struct clk i2c_fck = {
 
 static struct clk i2c_ick = {
 	.name		= "i2c_ick",
-	.id		= 1,
 	.ops		= &clkops_null,
 	.flags		= CLOCK_NO_IDLE_PARENT,
 	.parent		= &armper_ck.clk,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/devices.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/devices.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/devices.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/devices.c	2010-05-16 17:17:36.000000000 -0400
@@ -73,7 +73,7 @@ static inline void omap_init_rtc(void) {
 #  define INT_DSP_MAILBOX1	INT_1610_DSP_MAILBOX1
 #endif
 
-#define OMAP1_MBOX_BASE		OMAP1_IO_ADDRESS(OMAP16XX_MAILBOX_BASE)
+#define OMAP1_MBOX_BASE		OMAP16XX_MAILBOX_BASE
 
 static struct resource mbox_resources[] = {
 	{
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/flash.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/flash.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/flash.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/flash.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,33 @@
+/*
+ * Flash support for OMAP1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+
+#include <plat/io.h>
+#include <plat/tc.h>
+
+void omap1_set_vpp(struct map_info *map, int enable)
+{
+	static int count;
+	u32 l;
+
+	if (enable) {
+		if (count++ == 0) {
+			l = omap_readl(EMIFS_CONFIG);
+			l |= OMAP_EMIFS_CONFIG_WP;
+			omap_writel(l, EMIFS_CONFIG);
+		}
+	} else {
+		if (count && (--count == 0)) {
+			l = omap_readl(EMIFS_CONFIG);
+			l &= ~OMAP_EMIFS_CONFIG_WP;
+			omap_writel(l, EMIFS_CONFIG);
+		}
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/i2c.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/i2c.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,9 +23,7 @@
 #include <plat/mux.h>
 #include <plat/cpu.h>
 
-int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
-			  struct i2c_board_info const *info,
-			  unsigned len)
+void __init omap1_i2c_mux_pins(int bus_id)
 {
 	if (cpu_is_omap7xx()) {
 		omap_cfg_reg(I2C_7XX_SDA);
@@ -34,6 +32,4 @@ int __init omap_register_i2c_bus(int bus
 		omap_cfg_reg(I2C_SDA);
 		omap_cfg_reg(I2C_SCL);
 	}
-
-	return omap_plat_register_i2c_bus(bus_id, clkrate, info, len);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,18 +11,80 @@
  *
 */
 
-		.macro	addruart,rx
+#include <linux/serial_reg.h>
+
+#include <plat/serial.h>
+
+		.pushsection .data
+omap_uart_phys:	.word	0x0
+omap_uart_virt:	.word	0x0
+		.popsection
+
+		/*
+		 * Note that this code won't work if the bootloader passes
+		 * a wrong machine ID number in r1. To debug, just hardcode
+		 * the desired UART phys and virt addresses temporarily into
+		 * the omap_uart_phys and omap_uart_virt above.
+		 */
+		.macro	addruart, rx, tmp
+
+		/* Use omap_uart_phys/virt if already configured */
+9:		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		ldreq	\rx, =omap_uart_phys	@ physical base address
+		ldrne	\rx, =omap_uart_virt	@ virtual base
+		ldr	\rx, [\rx, #0]
+		cmp	\rx, #0			@ is port configured?
+		bne	99f			@ already configured
+
+		/* Check 7XX UART1 scratchpad register for uart to use */
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #0xff000000	@ physical base address
 		movne	\rx, #0xfe000000	@ virtual base
-		orr	\rx, \rx, #0x00fb0000
-#ifdef CONFIG_OMAP_LL_DEBUG_UART3
-		orr	\rx, \rx, #0x00009000	@ UART 3
-#endif
-#if defined(CONFIG_OMAP_LL_DEBUG_UART2) || defined(CONFIG_OMAP_LL_DEBUG_UART3)
-		orr	\rx, \rx, #0x00000800	@ UART 2 & 3
-#endif
+		orr	\rx, \rx, #0x00fb0000	@ OMAP1UART1
+		ldrb	\rx, [\rx, #(UART_SCR << OMAP7XX_PORT_SHIFT)]
+		cmp	\rx, #0			@ anything in 7XX scratchpad?
+		bne	10f			@ found 7XX uart
+
+		/* Check 15xx/16xx UART1 scratchpad register for uart to use */
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0xff000000	@ physical base address
+		movne	\rx, #0xfe000000	@ virtual base
+		orr	\rx, \rx, #0x00fb0000	@ OMAP1UART1
+		ldrb	\rx, [\rx, #(UART_SCR << OMAP_PORT_SHIFT)]
+
+		/* Select the UART to use based on the UART1 scratchpad value */
+10:		cmp	\rx, #0			@ no port configured?
+		beq	11f			@ if none, try to use UART1
+		cmp	\rx, #OMAP1UART1
+		beq	11f			@ configure OMAP1UART1
+		cmp	\rx, #OMAP1UART2
+		beq	12f			@ configure OMAP1UART2
+		cmp	\rx, #OMAP1UART3
+		beq	13f			@ configure OMAP2UART3
+
+		/* Configure the UART offset from the phys/virt base */
+11:		mov	\rx, #0x00fb0000	@ OMAP1UART1
+		b	98f
+12:		mov	\rx, #0x00fb0000	@ OMAP1UART1
+		orr	\rx, \rx, #0x00000800	@ OMAP1UART2
+		b	98f
+13:		mov	\rx, #0x00fb0000	@ OMAP1UART1
+		orr	\rx, \rx, #0x00000800	@ OMAP1UART2
+		orr	\rx, \rx, #0x00009000	@ OMAP1UART3
+
+		/* Store both phys and virt address for the uart */
+98:		add	\rx, \rx, #0xff000000	@ phys base
+		ldr	\tmp, =omap_uart_phys
+		str	\rx, [\tmp, #0]
+		sub	\rx, \rx, #0xff000000	@ phys base
+		add	\rx, \rx, #0xfe000000	@ virt base
+		ldr	\tmp, =omap_uart_virt
+		str	\rx, [\tmp, #0]
+		b	9b
+99:
 		.endm
 
 		.macro	senduart,rd,rx
@@ -30,13 +92,13 @@
 		.endm
 
 		.macro	busyuart,rd,rx
-1001:		ldrb	\rd, [\rx, #(0x5 << 2)]	@ OMAP-1510 and friends
-		and	\rd, \rd, #0x60
-		teq	\rd, #0x60
+1001:		ldrb	\rd, [\rx, #(UART_LSR << OMAP_PORT_SHIFT)]
+		and	\rd, \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
+		teq	\rd, #(UART_LSR_TEMT | UART_LSR_THRE)
 		beq	1002f
-		ldrb	\rd, [\rx, #(0x5 << 0)]	@ OMAP-730 only
-		and	\rd, \rd, #0x60
-		teq	\rd, #0x60
+		ldrb	\rd, [\rx, #(UART_LSR << OMAP7XX_PORT_SHIFT)]
+		and	\rd, \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
+		teq	\rd, #(UART_LSR_TEMT | UART_LSR_THRE)
 		bne	1001b
 1002:
 		.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/mailbox.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/mailbox.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/mailbox.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/mailbox.c	2010-05-16 17:17:36.000000000 -0400
@@ -146,7 +146,6 @@ EXPORT_SYMBOL(mbox_dsp_info);
 static int __devinit omap1_mbox_probe(struct platform_device *pdev)
 {
 	struct resource *res;
-	int ret = 0;
 
 	if (pdev->num_resources != 2) {
 		dev_err(&pdev->dev, "invalid number of resources: %d\n",
@@ -160,12 +159,18 @@ static int __devinit omap1_mbox_probe(st
 		dev_err(&pdev->dev, "invalid mem resource\n");
 		return -ENODEV;
 	}
-	mbox_base = res->start;
+
+	mbox_base = ioremap(res->start, resource_size(res));
+	if (!mbox_base) {
+		dev_err(&pdev->dev, "ioremap failed\n");
+		return -ENODEV;
+	}
 
 	/* DSP IRQ */
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (unlikely(!res)) {
 		dev_err(&pdev->dev, "invalid irq resource\n");
+		iounmap(mbox_base);
 		return -ENODEV;
 	}
 	mbox_dsp_info.irq = res->start;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y := io.o id.o sram.o irq.o mux.o serial.o devices.o
+obj-y := io.o id.o sram.o irq.o mux.o flash.o serial.o devices.o
 obj-y += clock.o clock_data.o opp_data.o
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/mcbsp.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/mcbsp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/mcbsp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/mcbsp.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <mach/irqs.h>
 #include <plat/dma.h>
@@ -99,9 +100,11 @@ static struct omap_mcbsp_platform_data o
 	},
 };
 #define OMAP7XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap7xx_mcbsp_pdata)
+#define OMAP7XX_MCBSP_REG_NUM		(OMAP_MCBSP_REG_XCERH / sizeof(u16) + 1)
 #else
 #define omap7xx_mcbsp_pdata		NULL
 #define OMAP7XX_MCBSP_PDATA_SZ		0
+#define OMAP7XX_MCBSP_REG_NUM		0
 #endif
 
 #ifdef CONFIG_ARCH_OMAP15XX
@@ -132,9 +135,11 @@ static struct omap_mcbsp_platform_data o
 	},
 };
 #define OMAP15XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap15xx_mcbsp_pdata)
+#define OMAP15XX_MCBSP_REG_NUM		(OMAP_MCBSP_REG_XCERH / sizeof(u16) + 1)
 #else
 #define omap15xx_mcbsp_pdata		NULL
 #define OMAP15XX_MCBSP_PDATA_SZ		0
+#define OMAP15XX_MCBSP_REG_NUM		0
 #endif
 
 #ifdef CONFIG_ARCH_OMAP16XX
@@ -165,19 +170,25 @@ static struct omap_mcbsp_platform_data o
 	},
 };
 #define OMAP16XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap16xx_mcbsp_pdata)
+#define OMAP16XX_MCBSP_REG_NUM		(OMAP_MCBSP_REG_XCERH / sizeof(u16) + 1)
 #else
 #define omap16xx_mcbsp_pdata		NULL
 #define OMAP16XX_MCBSP_PDATA_SZ		0
+#define OMAP16XX_MCBSP_REG_NUM		0
 #endif
 
 int __init omap1_mcbsp_init(void)
 {
-	if (cpu_is_omap7xx())
+	if (cpu_is_omap7xx()) {
 		omap_mcbsp_count = OMAP7XX_MCBSP_PDATA_SZ;
-	if (cpu_is_omap15xx())
+		omap_mcbsp_cache_size = OMAP7XX_MCBSP_REG_NUM * sizeof(u16);
+	} else if (cpu_is_omap15xx()) {
 		omap_mcbsp_count = OMAP15XX_MCBSP_PDATA_SZ;
-	if (cpu_is_omap16xx())
+		omap_mcbsp_cache_size = OMAP15XX_MCBSP_REG_NUM * sizeof(u16);
+	} else if (cpu_is_omap16xx()) {
 		omap_mcbsp_count = OMAP16XX_MCBSP_PDATA_SZ;
+		omap_mcbsp_cache_size = OMAP16XX_MCBSP_REG_NUM * sizeof(u16);
+	}
 
 	mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
 								GFP_KERNEL);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/serial.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/serial.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,7 +64,7 @@ static void __init omap_serial_reset(str
 
 static struct plat_serial8250_port serial_platform_data[] = {
 	{
-		.mapbase	= OMAP_UART1_BASE,
+		.mapbase	= OMAP1_UART1_BASE,
 		.irq		= INT_UART1,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.iotype		= UPIO_MEM,
@@ -72,7 +72,7 @@ static struct plat_serial8250_port seria
 		.uartclk	= OMAP16XX_BASE_BAUD * 16,
 	},
 	{
-		.mapbase	= OMAP_UART2_BASE,
+		.mapbase	= OMAP1_UART2_BASE,
 		.irq		= INT_UART2,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.iotype		= UPIO_MEM,
@@ -80,7 +80,7 @@ static struct plat_serial8250_port seria
 		.uartclk	= OMAP16XX_BASE_BAUD * 16,
 	},
 	{
-		.mapbase	= OMAP_UART3_BASE,
+		.mapbase	= OMAP1_UART3_BASE,
 		.irq		= INT_UART3,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.iotype		= UPIO_MEM,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/timer32k.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/timer32k.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/timer32k.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap1/timer32k.c	2010-05-16 17:17:36.000000000 -0400
@@ -68,12 +68,6 @@ struct sys_timer omap_timer;
  * ---------------------------------------------------------------------------
  */
 
-#if defined(CONFIG_ARCH_OMAP16XX)
-#define TIMER_32K_SYNCHRONIZED		0xfffbc410
-#else
-#error OMAP 32KHz timer does not currently work on 15XX!
-#endif
-
 /* 16xx specific defines */
 #define OMAP1_32K_TIMER_BASE		0xfffb9000
 #define OMAP1_32K_TIMER_CR		0x08
@@ -150,15 +144,6 @@ static struct clock_event_device clockev
 	.set_mode	= omap_32k_timer_set_mode,
 };
 
-/*
- * The 32KHz synchronized timer is an additional timer on 16xx.
- * It is always running.
- */
-static inline unsigned long omap_32k_sync_timer_read(void)
-{
-	return omap_readl(TIMER_32K_SYNCHRONIZED);
-}
-
 static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
 {
 	struct clock_event_device *evt = &clockevent_32k_timer;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-2430sdp.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-2430sdp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-2430sdp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-2430sdp.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 #include <linux/delay.h>
 #include <linux/i2c/twl.h>
 #include <linux/err.h>
@@ -28,7 +29,6 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <asm/mach/flash.h>
 
 #include <mach/gpio.h>
 #include <plat/mux.h>
@@ -38,7 +38,7 @@
 #include <plat/usb.h>
 #include <plat/gpmc-smc91x.h>
 
-#include "mmc-twl4030.h"
+#include "hsmmc.h"
 
 #define SDP2430_CS0_BASE	0x04000000
 #define SECONDARY_LCD_GPIO		147
@@ -74,8 +74,7 @@ static struct mtd_partition sdp2430_part
 	}
 };
 
-static struct flash_platform_data sdp2430_flash_data = {
-	.map_name	= "cfi_probe",
+static struct physmap_flash_data sdp2430_flash_data = {
 	.width		= 2,
 	.parts		= sdp2430_partitions,
 	.nr_parts	= ARRAY_SIZE(sdp2430_partitions),
@@ -88,7 +87,7 @@ static struct resource sdp2430_flash_res
 };
 
 static struct platform_device sdp2430_flash_device = {
-	.name		= "omapflash",
+	.name		= "physmap-flash",
 	.id		= 0,
 	.dev = {
 		.platform_data	= &sdp2430_flash_data,
@@ -183,7 +182,7 @@ static int __init omap2430_i2c_init(void
 	return 0;
 }
 
-static struct twl4030_hsmmc_info mmc[] __initdata = {
+static struct omap2_hsmmc_info mmc[] __initdata = {
 	{
 		.mmc		= 1,
 		.wires		= 4,
@@ -194,6 +193,12 @@ static struct twl4030_hsmmc_info mmc[] _
 	{}	/* Terminator */
 };
 
+static struct omap_musb_board_data musb_board_data = {
+	.interface_type		= MUSB_INTERFACE_ULPI,
+	.mode			= MUSB_OTG,
+	.power			= 100,
+};
+
 static void __init omap_2430sdp_init(void)
 {
 	int ret;
@@ -202,8 +207,8 @@ static void __init omap_2430sdp_init(voi
 
 	platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
 	omap_serial_init();
-	twl4030_mmc_init(mmc);
-	usb_musb_init();
+	omap2_hsmmc_init(mmc);
+	usb_musb_init(&musb_board_data);
 	board_smc91x_init();
 
 	/* Turn off secondary LCD backlight */
@@ -215,7 +220,7 @@ static void __init omap_2430sdp_init(voi
 static void __init omap_2430sdp_map_io(void)
 {
 	omap2_set_globals_243x();
-	omap2_map_common_io();
+	omap243x_map_common_io();
 }
 
 MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-3430sdp.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-3430sdp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-3430sdp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-3430sdp.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,9 +41,12 @@
 #include <plat/control.h>
 #include <plat/gpmc-smc91x.h>
 
+#include <mach/board-sdp.h>
+
 #include "mux.h"
 #include "sdram-qimonda-hyb18m512160af-6.h"
-#include "mmc-twl4030.h"
+#include "hsmmc.h"
+#include "pm.h"
 
 #define CONFIG_DISABLE_HFCLK 1
 
@@ -55,6 +58,24 @@
 
 #define TWL4030_MSECURE_GPIO 22
 
+/* FIXME: These values need to be updated based on more profiling on 3430sdp*/
+static struct cpuidle_params omap3_cpuidle_params_table[] = {
+	/* C1 */
+	{1, 2, 2, 5},
+	/* C2 */
+	{1, 10, 10, 30},
+	/* C3 */
+	{1, 50, 50, 300},
+	/* C4 */
+	{1, 1500, 1800, 4000},
+	/* C5 */
+	{1, 2500, 7500, 12000},
+	/* C6 */
+	{1, 3000, 8500, 15000},
+	/* C7 */
+	{1, 10000, 30000, 300000},
+};
+
 static int board_keymap[] = {
 	KEY(0, 0, KEY_LEFT),
 	KEY(0, 1, KEY_RIGHT),
@@ -305,6 +326,7 @@ static void __init omap_3430sdp_init_irq
 {
 	omap_board_config = sdp3430_config;
 	omap_board_config_size = ARRAY_SIZE(sdp3430_config);
+	omap3_pm_init_cpuidle(omap3_cpuidle_params_table);
 	omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL);
 	omap_init_irq();
 	omap_gpio_init();
@@ -326,7 +348,7 @@ static struct twl4030_bci_platform_data
 	.tblsize		= ARRAY_SIZE(sdp3430_batt_table),
 };
 
-static struct twl4030_hsmmc_info mmc[] = {
+static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		/* 8 bits (default) requires S6.3 == ON,
@@ -363,7 +385,7 @@ static int sdp3430_twl_gpio_setup(struct
 	 */
 	mmc[0].gpio_cd = gpio + 0;
 	mmc[1].gpio_cd = gpio + 1;
-	twl4030_mmc_init(mmc);
+	omap2_hsmmc_init(mmc);
 
 	/* link regulators to MMC adapters ... we "know" the
 	 * regulators will be set up only *after* we return.
@@ -520,10 +542,6 @@ static struct regulator_init_data sdp343
 /* VPLL2 for digital video outputs */
 static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
 	{
-		.supply		= "vdvi",
-		.dev		= &sdp3430_lcd_device.dev,
-	},
-	{
 		.supply		= "vdds_dsi",
 		.dev		= &sdp3430_dss_device.dev,
 	}
@@ -630,7 +648,7 @@ static void enable_board_wakeup_source(v
 		OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
 }
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 
 	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
 	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
@@ -650,6 +668,120 @@ static struct omap_board_mux board_mux[]
 #define board_mux	NULL
 #endif
 
+static struct mtd_partition sdp_nor_partitions[] = {
+	/* bootloader (U-Boot, etc) in first sector */
+	{
+		.name		= "Bootloader-NOR",
+		.offset		= 0,
+		.size		= SZ_256K,
+		.mask_flags	= MTD_WRITEABLE, /* force read-only */
+	},
+	/* bootloader params in the next sector */
+	{
+		.name		= "Params-NOR",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_256K,
+		.mask_flags	= 0,
+	},
+	/* kernel */
+	{
+		.name		= "Kernel-NOR",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_2M,
+		.mask_flags	= 0
+	},
+	/* file system */
+	{
+		.name		= "Filesystem-NOR",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0
+	}
+};
+
+static struct mtd_partition sdp_onenand_partitions[] = {
+	{
+		.name		= "X-Loader-OneNAND",
+		.offset		= 0,
+		.size		= 4 * (64 * 2048),
+		.mask_flags	= MTD_WRITEABLE  /* force read-only */
+	},
+	{
+		.name		= "U-Boot-OneNAND",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 2 * (64 * 2048),
+		.mask_flags	= MTD_WRITEABLE  /* force read-only */
+	},
+	{
+		.name		= "U-Boot Environment-OneNAND",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 1 * (64 * 2048),
+	},
+	{
+		.name		= "Kernel-OneNAND",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 16 * (64 * 2048),
+	},
+	{
+		.name		= "File System-OneNAND",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct mtd_partition sdp_nand_partitions[] = {
+	/* All the partition sizes are listed in terms of NAND block size */
+	{
+		.name		= "X-Loader-NAND",
+		.offset		= 0,
+		.size		= 4 * (64 * 2048),
+		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
+	},
+	{
+		.name		= "U-Boot-NAND",
+		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x80000 */
+		.size		= 10 * (64 * 2048),
+		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
+	},
+	{
+		.name		= "Boot Env-NAND",
+
+		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x1c0000 */
+		.size		= 6 * (64 * 2048),
+	},
+	{
+		.name		= "Kernel-NAND",
+		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x280000 */
+		.size		= 40 * (64 * 2048),
+	},
+	{
+		.name		= "File System - NAND",
+		.size		= MTDPART_SIZ_FULL,
+		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x780000 */
+	},
+};
+
+static struct flash_partitions sdp_flash_partitions[] = {
+	{
+		.parts = sdp_nor_partitions,
+		.nr_parts = ARRAY_SIZE(sdp_nor_partitions),
+	},
+	{
+		.parts = sdp_onenand_partitions,
+		.nr_parts = ARRAY_SIZE(sdp_onenand_partitions),
+	},
+	{
+		.parts = sdp_nand_partitions,
+		.nr_parts = ARRAY_SIZE(sdp_nand_partitions),
+	},
+};
+
+static struct omap_musb_board_data musb_board_data = {
+	.interface_type		= MUSB_INTERFACE_ULPI,
+	.mode			= MUSB_OTG,
+	.power			= 100,
+};
+
 static void __init omap_3430sdp_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
@@ -664,8 +796,9 @@ static void __init omap_3430sdp_init(voi
 				ARRAY_SIZE(sdp3430_spi_board_info));
 	ads7846_dev_init();
 	omap_serial_init();
-	usb_musb_init();
+	usb_musb_init(&musb_board_data);
 	board_smc91x_init();
+	sdp_flash_init(sdp_flash_partitions);
 	sdp3430_display_init();
 	enable_board_wakeup_source();
 	usb_ehci_init(&ehci_pdata);
@@ -674,7 +807,7 @@ static void __init omap_3430sdp_init(voi
 static void __init omap_3430sdp_map_io(void)
 {
 	omap2_set_globals_343x();
-	omap2_map_common_io();
+	omap34xx_map_common_io();
 }
 
 MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-3630sdp.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-3630sdp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-3630sdp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-3630sdp.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,7 +54,7 @@ static void enable_board_wakeup_source(v
 		OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
 }
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 
 	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
 	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
@@ -68,8 +68,8 @@ static struct ehci_hcd_omap_platform_dat
 
 static void __init omap_sdp_map_io(void)
 {
-	omap2_set_globals_343x();
-	omap2_map_common_io();
+	omap2_set_globals_36xx();
+	omap34xx_map_common_io();
 }
 
 static struct omap_board_config_kernel sdp_config[] __initdata = {
@@ -96,6 +96,7 @@ static struct omap_board_mux board_mux[]
 static void __init omap_sdp_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
+	omap_serial_init();
 	zoom_peripherals_init();
 	board_smc91x_init();
 	enable_board_wakeup_source();
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-4430sdp.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-4430sdp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-4430sdp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-4430sdp.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/usb/otg.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -27,7 +28,9 @@
 #include <plat/common.h>
 #include <plat/control.h>
 #include <plat/timer-gp.h>
+#include <plat/usb.h>
 #include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
 
 static struct platform_device sdp4430_lcd_device = {
 	.name		= "sdp4430_lcd",
@@ -38,10 +41,6 @@ static struct platform_device *sdp4430_d
 	&sdp4430_lcd_device,
 };
 
-static struct omap_uart_config sdp4430_uart_config __initdata = {
-	.enabled_uarts	= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3),
-};
-
 static struct omap_lcd_config sdp4430_lcd_config __initdata = {
 	.ctrl_name	= "internal",
 };
@@ -50,6 +49,35 @@ static struct omap_board_config_kernel s
 	{ OMAP_TAG_LCD,		&sdp4430_lcd_config },
 };
 
+#ifdef CONFIG_CACHE_L2X0
+static int __init omap_l2_cache_init(void)
+{
+	extern void omap_smc1(u32 fn, u32 arg);
+	void __iomem *l2cache_base;
+
+	/* To avoid code running on other OMAPs in
+	 * multi-omap builds
+	 */
+	if (!cpu_is_omap44xx())
+		return -ENODEV;
+
+	/* Static mapping, never released */
+	l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
+	BUG_ON(!l2cache_base);
+
+	/* Enable PL310 L2 Cache controller */
+	omap_smc1(0x102, 0x1);
+
+	/* 32KB way size, 16-way associativity,
+	* parity disabled
+	*/
+	l2x0_init(l2cache_base, 0x0e050000, 0xc0000fff);
+
+	return 0;
+}
+early_initcall(omap_l2_cache_init);
+#endif
+
 static void __init gic_init_irq(void)
 {
 	void __iomem *base;
@@ -77,17 +105,27 @@ static void __init omap_4430sdp_init_irq
 	omap_gpio_init();
 }
 
+static struct omap_musb_board_data musb_board_data = {
+	.interface_type		= MUSB_INTERFACE_UTMI,
+	.mode			= MUSB_PERIPHERAL,
+	.power			= 100,
+};
 
 static void __init omap_4430sdp_init(void)
 {
 	platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
 	omap_serial_init();
+	/* OMAP4 SDP uses internal transceiver so register nop transceiver */
+	usb_nop_xceiv_register();
+	/* FIXME: allow multi-omap to boot until musb is updated for omap4 */
+	if (!cpu_is_omap44xx())
+		usb_musb_init(&musb_board_data);
 }
 
 static void __init omap_4430sdp_map_io(void)
 {
 	omap2_set_globals_443x();
-	omap2_map_common_io();
+	omap44xx_map_common_io();
 }
 
 MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-am3517evm.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-am3517evm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-am3517evm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-am3517evm.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,8 +20,10 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/i2c/pca953x.h>
 
 #include <mach/hardware.h>
+#include <mach/am35xx.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -29,9 +31,228 @@
 #include <plat/board.h>
 #include <plat/common.h>
 #include <plat/usb.h>
+#include <plat/display.h>
 
 #include "mux.h"
 
+#define LCD_PANEL_PWR		176
+#define LCD_PANEL_BKLIGHT_PWR	182
+#define LCD_PANEL_PWM		181
+
+static struct i2c_board_info __initdata am3517evm_i2c_boardinfo[] = {
+	{
+		I2C_BOARD_INFO("s35390a", 0x30),
+		.type		= "s35390a",
+	},
+};
+
+/*
+ * RTC - S35390A
+ */
+#define GPIO_RTCS35390A_IRQ	55
+
+static void __init am3517_evm_rtc_init(void)
+{
+	int r;
+
+	omap_mux_init_gpio(GPIO_RTCS35390A_IRQ, OMAP_PIN_INPUT_PULLUP);
+	r = gpio_request(GPIO_RTCS35390A_IRQ, "rtcs35390a-irq");
+	if (r < 0) {
+		printk(KERN_WARNING "failed to request GPIO#%d\n",
+				GPIO_RTCS35390A_IRQ);
+		return;
+	}
+	r = gpio_direction_input(GPIO_RTCS35390A_IRQ);
+	if (r < 0) {
+		printk(KERN_WARNING "GPIO#%d cannot be configured as input\n",
+				GPIO_RTCS35390A_IRQ);
+		gpio_free(GPIO_RTCS35390A_IRQ);
+		return;
+	}
+	am3517evm_i2c_boardinfo[0].irq = gpio_to_irq(GPIO_RTCS35390A_IRQ);
+}
+
+/*
+ * I2C GPIO Expander - TCA6416
+ */
+
+/* Mounted on Base-Board */
+static struct pca953x_platform_data am3517evm_gpio_expander_info_0 = {
+	.gpio_base	= OMAP_MAX_GPIO_LINES,
+};
+static struct i2c_board_info __initdata am3517evm_tca6416_info_0[] = {
+	{
+		I2C_BOARD_INFO("tca6416", 0x21),
+		.platform_data = &am3517evm_gpio_expander_info_0,
+	},
+};
+
+/* Mounted on UI Card */
+static struct pca953x_platform_data am3517evm_ui_gpio_expander_info_1 = {
+	.gpio_base	= OMAP_MAX_GPIO_LINES + 16,
+};
+static struct pca953x_platform_data am3517evm_ui_gpio_expander_info_2 = {
+	.gpio_base	= OMAP_MAX_GPIO_LINES + 32,
+};
+static struct i2c_board_info __initdata am3517evm_ui_tca6416_info[] = {
+	{
+		I2C_BOARD_INFO("tca6416", 0x20),
+		.platform_data = &am3517evm_ui_gpio_expander_info_1,
+	},
+	{
+		I2C_BOARD_INFO("tca6416", 0x21),
+		.platform_data = &am3517evm_ui_gpio_expander_info_2,
+	},
+};
+
+static int __init am3517_evm_i2c_init(void)
+{
+	omap_register_i2c_bus(1, 400, NULL, 0);
+	omap_register_i2c_bus(2, 400, am3517evm_tca6416_info_0,
+			ARRAY_SIZE(am3517evm_tca6416_info_0));
+	omap_register_i2c_bus(3, 400, am3517evm_ui_tca6416_info,
+			ARRAY_SIZE(am3517evm_ui_tca6416_info));
+
+	return 0;
+}
+
+static int lcd_enabled;
+static int dvi_enabled;
+
+static void __init am3517_evm_display_init(void)
+{
+	int r;
+
+	omap_mux_init_gpio(LCD_PANEL_PWR, OMAP_PIN_INPUT_PULLUP);
+	omap_mux_init_gpio(LCD_PANEL_BKLIGHT_PWR, OMAP_PIN_INPUT_PULLDOWN);
+	omap_mux_init_gpio(LCD_PANEL_PWM, OMAP_PIN_INPUT_PULLDOWN);
+	/*
+	 * Enable GPIO 182 = LCD Backlight Power
+	 */
+	r = gpio_request(LCD_PANEL_BKLIGHT_PWR, "lcd_backlight_pwr");
+	if (r) {
+		printk(KERN_ERR "failed to get lcd_backlight_pwr\n");
+		return;
+	}
+	gpio_direction_output(LCD_PANEL_BKLIGHT_PWR, 1);
+	/*
+	 * Enable GPIO 181 = LCD Panel PWM
+	 */
+	r = gpio_request(LCD_PANEL_PWM, "lcd_pwm");
+	if (r) {
+		printk(KERN_ERR "failed to get lcd_pwm\n");
+		goto err_1;
+	}
+	gpio_direction_output(LCD_PANEL_PWM, 1);
+	/*
+	 * Enable GPIO 176 = LCD Panel Power enable pin
+	 */
+	r = gpio_request(LCD_PANEL_PWR, "lcd_panel_pwr");
+	if (r) {
+		printk(KERN_ERR "failed to get lcd_panel_pwr\n");
+		goto err_2;
+	}
+	gpio_direction_output(LCD_PANEL_PWR, 1);
+
+	printk(KERN_INFO "Display initialized successfully\n");
+	return;
+
+err_2:
+	gpio_free(LCD_PANEL_PWM);
+err_1:
+	gpio_free(LCD_PANEL_BKLIGHT_PWR);
+}
+
+static int am3517_evm_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+	if (dvi_enabled) {
+		printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+		return -EINVAL;
+	}
+	gpio_set_value(LCD_PANEL_PWR, 1);
+	lcd_enabled = 1;
+
+	return 0;
+}
+
+static void am3517_evm_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+	gpio_set_value(LCD_PANEL_PWR, 0);
+	lcd_enabled = 0;
+}
+
+static struct omap_dss_device am3517_evm_lcd_device = {
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.name			= "lcd",
+	.driver_name		= "sharp_lq_panel",
+	.phy.dpi.data_lines 	= 16,
+	.platform_enable	= am3517_evm_panel_enable_lcd,
+	.platform_disable	= am3517_evm_panel_disable_lcd,
+};
+
+static int am3517_evm_panel_enable_tv(struct omap_dss_device *dssdev)
+{
+	return 0;
+}
+
+static void am3517_evm_panel_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+static struct omap_dss_device am3517_evm_tv_device = {
+	.type 			= OMAP_DISPLAY_TYPE_VENC,
+	.name 			= "tv",
+	.driver_name		= "venc",
+	.phy.venc.type		= OMAP_DSS_VENC_TYPE_SVIDEO,
+	.platform_enable	= am3517_evm_panel_enable_tv,
+	.platform_disable	= am3517_evm_panel_disable_tv,
+};
+
+static int am3517_evm_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+	if (lcd_enabled) {
+		printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+		return -EINVAL;
+	}
+	dvi_enabled = 1;
+
+	return 0;
+}
+
+static void am3517_evm_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+	dvi_enabled = 0;
+}
+
+static struct omap_dss_device am3517_evm_dvi_device = {
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.name			= "dvi",
+	.driver_name		= "generic_panel",
+	.phy.dpi.data_lines	= 24,
+	.platform_enable	= am3517_evm_panel_enable_dvi,
+	.platform_disable	= am3517_evm_panel_disable_dvi,
+};
+
+static struct omap_dss_device *am3517_evm_dss_devices[] = {
+	&am3517_evm_lcd_device,
+	&am3517_evm_tv_device,
+	&am3517_evm_dvi_device,
+};
+
+static struct omap_dss_board_info am3517_evm_dss_data = {
+	.num_devices	= ARRAY_SIZE(am3517_evm_dss_devices),
+	.devices	= am3517_evm_dss_devices,
+	.default_device	= &am3517_evm_lcd_device,
+};
+
+struct platform_device am3517_evm_dss_device = {
+	.name		= "omapdss",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &am3517_evm_dss_data,
+	},
+};
+
 /*
  * Board initialization
  */
@@ -39,6 +260,7 @@ static struct omap_board_config_kernel a
 };
 
 static struct platform_device *am3517_evm_devices[] __initdata = {
+	&am3517_evm_dss_device,
 };
 
 static void __init am3517_evm_init_irq(void)
@@ -51,7 +273,7 @@ static void __init am3517_evm_init_irq(v
 	omap_gpio_init();
 }
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
 	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
 	.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
@@ -73,17 +295,30 @@ static struct omap_board_mux board_mux[]
 static void __init am3517_evm_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+
+	am3517_evm_i2c_init();
 	platform_add_devices(am3517_evm_devices,
 				ARRAY_SIZE(am3517_evm_devices));
 
 	omap_serial_init();
+
+	/* Configure GPIO for EHCI port */
+	omap_mux_init_gpio(57, OMAP_PIN_OUTPUT);
 	usb_ehci_init(&ehci_pdata);
+	/* DSS */
+	am3517_evm_display_init();
+
+	/* RTC - S35390A */
+	am3517_evm_rtc_init();
+
+	i2c_register_board_info(1, am3517evm_i2c_boardinfo,
+				ARRAY_SIZE(am3517evm_i2c_boardinfo));
 }
 
 static void __init am3517_evm_map_io(void)
 {
 	omap2_set_globals_343x();
-	omap2_map_common_io();
+	omap34xx_map_common_io();
 }
 
 MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-apollon.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-apollon.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-apollon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-apollon.c	2010-05-16 17:17:36.000000000 -0400
@@ -337,7 +337,7 @@ static void __init omap_apollon_init(voi
 static void __init omap_apollon_map_io(void)
 {
 	omap2_set_globals_242x();
-	omap2_map_common_io();
+	omap242x_map_common_io();
 }
 
 MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-cm-t35.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-cm-t35.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-cm-t35.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-cm-t35.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,9 @@
 #include <linux/i2c/twl.h>
 #include <linux/regulator/machine.h>
 
+#include <linux/spi/spi.h>
+#include <linux/spi/tdo24m.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -41,12 +44,13 @@
 #include <plat/nand.h>
 #include <plat/gpmc.h>
 #include <plat/usb.h>
+#include <plat/display.h>
 
 #include <mach/hardware.h>
 
 #include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
-#include "mmc-twl4030.h"
+#include "hsmmc.h"
 
 #define CM_T35_GPIO_PENDOWN	57
 
@@ -248,7 +252,6 @@ static inline void cm_t35_init_nand(void
 
 #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
 	defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
-#include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 
 #include <plat/mcspi.h>
@@ -304,6 +307,193 @@ static void __init cm_t35_init_ads7846(v
 static inline void cm_t35_init_ads7846(void) {}
 #endif
 
+#define CM_T35_LCD_EN_GPIO 157
+#define CM_T35_LCD_BL_GPIO 58
+#define CM_T35_DVI_EN_GPIO 54
+
+static int lcd_bl_gpio;
+static int lcd_en_gpio;
+static int dvi_en_gpio;
+
+static int lcd_enabled;
+static int dvi_enabled;
+
+static int cm_t35_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+	if (dvi_enabled) {
+		printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+		return -EINVAL;
+	}
+
+	gpio_set_value(lcd_en_gpio, 1);
+	gpio_set_value(lcd_bl_gpio, 1);
+
+	lcd_enabled = 1;
+
+	return 0;
+}
+
+static void cm_t35_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+	lcd_enabled = 0;
+
+	gpio_set_value(lcd_bl_gpio, 0);
+	gpio_set_value(lcd_en_gpio, 0);
+}
+
+static int cm_t35_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+	if (lcd_enabled) {
+		printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+		return -EINVAL;
+	}
+
+	gpio_set_value(dvi_en_gpio, 0);
+	dvi_enabled = 1;
+
+	return 0;
+}
+
+static void cm_t35_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+	gpio_set_value(dvi_en_gpio, 1);
+	dvi_enabled = 0;
+}
+
+static int cm_t35_panel_enable_tv(struct omap_dss_device *dssdev)
+{
+	return 0;
+}
+
+static void cm_t35_panel_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+static struct omap_dss_device cm_t35_lcd_device = {
+	.name			= "lcd",
+	.driver_name		= "toppoly_tdo35s_panel",
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.phy.dpi.data_lines	= 18,
+	.platform_enable	= cm_t35_panel_enable_lcd,
+	.platform_disable	= cm_t35_panel_disable_lcd,
+};
+
+static struct omap_dss_device cm_t35_dvi_device = {
+	.name			= "dvi",
+	.driver_name		= "generic_panel",
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.phy.dpi.data_lines	= 24,
+	.platform_enable	= cm_t35_panel_enable_dvi,
+	.platform_disable	= cm_t35_panel_disable_dvi,
+};
+
+static struct omap_dss_device cm_t35_tv_device = {
+	.name			= "tv",
+	.driver_name		= "venc",
+	.type			= OMAP_DISPLAY_TYPE_VENC,
+	.phy.venc.type		= OMAP_DSS_VENC_TYPE_SVIDEO,
+	.platform_enable	= cm_t35_panel_enable_tv,
+	.platform_disable	= cm_t35_panel_disable_tv,
+};
+
+static struct omap_dss_device *cm_t35_dss_devices[] = {
+	&cm_t35_lcd_device,
+	&cm_t35_dvi_device,
+	&cm_t35_tv_device,
+};
+
+static struct omap_dss_board_info cm_t35_dss_data = {
+	.num_devices	= ARRAY_SIZE(cm_t35_dss_devices),
+	.devices	= cm_t35_dss_devices,
+	.default_device	= &cm_t35_dvi_device,
+};
+
+static struct platform_device cm_t35_dss_device = {
+	.name		= "omapdss",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &cm_t35_dss_data,
+	},
+};
+
+static struct omap2_mcspi_device_config tdo24m_mcspi_config = {
+	.turbo_mode	= 0,
+	.single_channel	= 1,	/* 0: slave, 1: master */
+};
+
+static struct tdo24m_platform_data tdo24m_config = {
+	.model = TDO35S,
+};
+
+static struct spi_board_info cm_t35_lcd_spi_board_info[] __initdata = {
+	{
+		.modalias		= "tdo24m",
+		.bus_num		= 4,
+		.chip_select		= 0,
+		.max_speed_hz		= 1000000,
+		.controller_data	= &tdo24m_mcspi_config,
+		.platform_data		= &tdo24m_config,
+	},
+};
+
+static void __init cm_t35_init_display(void)
+{
+	int err;
+
+	lcd_en_gpio = CM_T35_LCD_EN_GPIO;
+	lcd_bl_gpio = CM_T35_LCD_BL_GPIO;
+	dvi_en_gpio = CM_T35_DVI_EN_GPIO;
+
+	spi_register_board_info(cm_t35_lcd_spi_board_info,
+				ARRAY_SIZE(cm_t35_lcd_spi_board_info));
+
+	err = gpio_request(lcd_en_gpio, "LCD RST");
+	if (err) {
+		pr_err("CM-T35: failed to get LCD reset GPIO\n");
+		goto out;
+	}
+
+	err = gpio_request(lcd_bl_gpio, "LCD BL");
+	if (err) {
+		pr_err("CM-T35: failed to get LCD backlight control GPIO\n");
+		goto err_lcd_bl;
+	}
+
+	err = gpio_request(dvi_en_gpio, "DVI EN");
+	if (err) {
+		pr_err("CM-T35: failed to get DVI reset GPIO\n");
+		goto err_dvi_en;
+	}
+
+	gpio_export(lcd_en_gpio, 0);
+	gpio_export(lcd_bl_gpio, 0);
+	gpio_export(dvi_en_gpio, 0);
+	gpio_direction_output(lcd_en_gpio, 0);
+	gpio_direction_output(lcd_bl_gpio, 0);
+	gpio_direction_output(dvi_en_gpio, 1);
+
+	msleep(50);
+	gpio_set_value(lcd_en_gpio, 1);
+
+	err = platform_device_register(&cm_t35_dss_device);
+	if (err) {
+		pr_err("CM-T35: failed to register DSS device\n");
+		goto err_dev_reg;
+	}
+
+	return;
+
+err_dev_reg:
+	gpio_free(dvi_en_gpio);
+err_dvi_en:
+	gpio_free(lcd_bl_gpio);
+err_lcd_bl:
+	gpio_free(lcd_en_gpio);
+out:
+
+	return;
+}
+
 static struct regulator_consumer_supply cm_t35_vmmc1_supply = {
 	.supply			= "vmmc",
 };
@@ -312,6 +502,16 @@ static struct regulator_consumer_supply
 	.supply			= "vmmc_aux",
 };
 
+static struct regulator_consumer_supply cm_t35_vdac_supply = {
+	.supply		= "vdda_dac",
+	.dev		= &cm_t35_dss_device.dev,
+};
+
+static struct regulator_consumer_supply cm_t35_vdvi_supply = {
+	.supply		= "vdvi",
+	.dev		= &cm_t35_dss_device.dev,
+};
+
 /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
 static struct regulator_init_data cm_t35_vmmc1 = {
 	.constraints = {
@@ -342,6 +542,35 @@ static struct regulator_init_data cm_t35
 	.consumer_supplies	= &cm_t35_vsim_supply,
 };
 
+/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
+static struct regulator_init_data cm_t35_vdac = {
+	.constraints = {
+		.min_uV			= 1800000,
+		.max_uV			= 1800000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &cm_t35_vdac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_init_data cm_t35_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	= &cm_t35_vdvi_supply,
+};
+
 static struct twl4030_usb_data cm_t35_usb_data = {
 	.usb_mode	= T2_USB_MODE_ULPI,
 };
@@ -364,7 +593,7 @@ static struct twl4030_keypad_data cm_t35
 	.rep		= 1,
 };
 
-static struct twl4030_hsmmc_info mmc[] = {
+static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.wires		= 4,
@@ -383,7 +612,7 @@ static struct twl4030_hsmmc_info mmc[] =
 	{}	/* Terminator */
 };
 
-static struct ehci_hcd_omap_platform_data ehci_pdata = {
+static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = {
 	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
 	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
 	.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
@@ -413,7 +642,7 @@ static int cm_t35_twl_gpio_setup(struct
 
 	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
 	mmc[0].gpio_cd = gpio + 0;
-	twl4030_mmc_init(mmc);
+	omap2_hsmmc_init(mmc);
 
 	/* link regulators to MMC adapters */
 	cm_t35_vmmc1_supply.dev = mmc[0].dev;
@@ -445,6 +674,8 @@ static struct twl4030_platform_data cm_t
 	.gpio		= &cm_t35_gpio_data,
 	.vmmc1		= &cm_t35_vmmc1,
 	.vsim		= &cm_t35_vsim,
+	.vdac		= &cm_t35_vdac,
+	.vpll2		= &cm_t35_vpll2,
 };
 
 static struct i2c_board_info __initdata cm_t35_i2c_boardinfo[] = {
@@ -479,7 +710,7 @@ static void __init cm_t35_init_irq(void)
 static void __init cm_t35_map_io(void)
 {
 	omap2_set_globals_343x();
-	omap2_map_common_io();
+	omap34xx_map_common_io();
 }
 
 static struct omap_board_mux board_mux[] __initdata = {
@@ -568,6 +799,11 @@ static struct omap_board_mux board_mux[]
 	OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 	OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 
+	/* display controls */
+	OMAP3_MUX(MCBSP1_FSR, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(GPMC_NCS7, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(GPMC_NCS3, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
 	/* TPS IRQ */
 	OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_WAKEUP_EN | \
 		  OMAP_PIN_INPUT_PULLUP),
@@ -575,6 +811,12 @@ static struct omap_board_mux board_mux[]
 	{ .reg_offset = OMAP_MUX_TERMINATOR },
 };
 
+static struct omap_musb_board_data musb_board_data = {
+	.interface_type		= MUSB_INTERFACE_ULPI,
+	.mode			= MUSB_OTG,
+	.power			= 100,
+};
+
 static void __init cm_t35_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
@@ -584,8 +826,9 @@ static void __init cm_t35_init(void)
 	cm_t35_init_ads7846();
 	cm_t35_init_ethernet();
 	cm_t35_init_led();
+	cm_t35_init_display();
 
-	usb_musb_init();
+	usb_musb_init(&musb_board_data);
 }
 
 MACHINE_START(CM_T35, "Compulab CM-T35")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-devkit8000.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-devkit8000.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-devkit8000.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-devkit8000.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,676 @@
+/*
+ * board-devkit8000.c - TimLL Devkit8000
+ *
+ * Copyright (C) 2009 Kim Botherway
+ * Copyright (C) 2010 Thomas Weber
+ *
+ * Modified from mach-omap2/board-omap3beagle.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/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc.h>
+#include <plat/nand.h>
+#include <plat/usb.h>
+#include <plat/timer-gp.h>
+#include <plat/display.h>
+
+#include <plat/mcspi.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/dm9000.h>
+#include <linux/interrupt.h>
+
+#include "sdram-micron-mt46h32m32lf-6.h"
+
+#include "mux.h"
+#include "hsmmc.h"
+
+#define GPMC_CS0_BASE  0x60
+#define GPMC_CS_SIZE   0x30
+
+#define NAND_BLOCK_SIZE		SZ_128K
+
+#define OMAP_DM9000_GPIO_IRQ	25
+#define OMAP3_DEVKIT_TS_GPIO	27
+
+static struct mtd_partition devkit8000_nand_partitions[] = {
+	/* All the partition sizes are listed in terms of NAND block size */
+	{
+		.name		= "X-Loader",
+		.offset		= 0,
+		.size		= 4 * NAND_BLOCK_SIZE,
+		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
+	},
+	{
+		.name		= "U-Boot",
+		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x80000 */
+		.size		= 15 * NAND_BLOCK_SIZE,
+		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
+	},
+	{
+		.name		= "U-Boot Env",
+		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x260000 */
+		.size		= 1 * NAND_BLOCK_SIZE,
+	},
+	{
+		.name		= "Kernel",
+		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x280000 */
+		.size		= 32 * NAND_BLOCK_SIZE,
+	},
+	{
+		.name		= "File System",
+		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x680000 */
+		.size		= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct omap_nand_platform_data devkit8000_nand_data = {
+	.options	= NAND_BUSWIDTH_16,
+	.parts		= devkit8000_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(devkit8000_nand_partitions),
+	.dma_channel	= -1,		/* disable DMA in OMAP NAND driver */
+};
+
+static struct resource devkit8000_nand_resource = {
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device devkit8000_nand_device = {
+	.name		= "omap2-nand",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &devkit8000_nand_data,
+	},
+	.num_resources	= 1,
+	.resource	= &devkit8000_nand_resource,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+	{
+		.mmc		= 1,
+		.wires		= 8,
+		.gpio_wp	= 29,
+	},
+	{}	/* Terminator */
+};
+static struct omap_board_config_kernel devkit8000_config[] __initdata = {
+};
+
+static int devkit8000_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+	twl_i2c_write_u8(TWL4030_MODULE_GPIO, 0x80, REG_GPIODATADIR1);
+	twl_i2c_write_u8(TWL4030_MODULE_LED, 0x0, 0x0);
+
+	return 0;
+}
+
+static void devkit8000_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+}
+static int devkit8000_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+	return 0;
+}
+
+static void devkit8000_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+}
+
+static int devkit8000_panel_enable_tv(struct omap_dss_device *dssdev)
+{
+
+	return 0;
+}
+
+static void devkit8000_panel_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+
+static struct regulator_consumer_supply devkit8000_vmmc1_supply = {
+	.supply			= "vmmc",
+};
+
+static struct regulator_consumer_supply devkit8000_vsim_supply = {
+	.supply			= "vmmc_aux",
+};
+
+
+static struct omap_dss_device devkit8000_lcd_device = {
+	.name                   = "lcd",
+	.driver_name            = "innolux_at_panel",
+	.type                   = OMAP_DISPLAY_TYPE_DPI,
+	.phy.dpi.data_lines     = 24,
+	.platform_enable        = devkit8000_panel_enable_lcd,
+	.platform_disable       = devkit8000_panel_disable_lcd,
+};
+static struct omap_dss_device devkit8000_dvi_device = {
+	.name                   = "dvi",
+	.driver_name            = "generic_panel",
+	.type                   = OMAP_DISPLAY_TYPE_DPI,
+	.phy.dpi.data_lines     = 24,
+	.platform_enable        = devkit8000_panel_enable_dvi,
+	.platform_disable       = devkit8000_panel_disable_dvi,
+};
+
+static struct omap_dss_device devkit8000_tv_device = {
+	.name                   = "tv",
+	.driver_name            = "venc",
+	.type                   = OMAP_DISPLAY_TYPE_VENC,
+	.phy.venc.type          = OMAP_DSS_VENC_TYPE_SVIDEO,
+	.platform_enable        = devkit8000_panel_enable_tv,
+	.platform_disable       = devkit8000_panel_disable_tv,
+};
+
+
+static struct omap_dss_device *devkit8000_dss_devices[] = {
+	&devkit8000_lcd_device,
+	&devkit8000_dvi_device,
+	&devkit8000_tv_device,
+};
+
+static struct omap_dss_board_info devkit8000_dss_data = {
+	.num_devices = ARRAY_SIZE(devkit8000_dss_devices),
+	.devices = devkit8000_dss_devices,
+	.default_device = &devkit8000_lcd_device,
+};
+
+static struct platform_device devkit8000_dss_device = {
+	.name		= "omapdss",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &devkit8000_dss_data,
+	},
+};
+
+static struct regulator_consumer_supply devkit8000_vdda_dac_supply = {
+	.supply = "vdda_dac",
+	.dev	= &devkit8000_dss_device.dev,
+};
+
+static int board_keymap[] = {
+	KEY(0, 0, KEY_1),
+	KEY(1, 0, KEY_2),
+	KEY(2, 0, KEY_3),
+	KEY(0, 1, KEY_4),
+	KEY(1, 1, KEY_5),
+	KEY(2, 1, KEY_6),
+	KEY(3, 1, KEY_F5),
+	KEY(0, 2, KEY_7),
+	KEY(1, 2, KEY_8),
+	KEY(2, 2, KEY_9),
+	KEY(3, 2, KEY_F6),
+	KEY(0, 3, KEY_F7),
+	KEY(1, 3, KEY_0),
+	KEY(2, 3, KEY_F8),
+	PERSISTENT_KEY(4, 5),
+	KEY(4, 4, KEY_VOLUMEUP),
+	KEY(5, 5, KEY_VOLUMEDOWN),
+	0
+};
+
+static struct matrix_keymap_data board_map_data = {
+	.keymap			= board_keymap,
+	.keymap_size		= ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data devkit8000_kp_data = {
+	.keymap_data	= &board_map_data,
+	.rows		= 6,
+	.cols		= 6,
+	.rep		= 1,
+};
+
+static struct gpio_led gpio_leds[];
+
+static int devkit8000_twl_gpio_setup(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_mux_init_gpio(29, OMAP_PIN_INPUT);
+	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
+	mmc[0].gpio_cd = gpio + 0;
+	omap2_hsmmc_init(mmc);
+
+	/* link regulators to MMC adapters */
+	devkit8000_vmmc1_supply.dev = mmc[0].dev;
+	devkit8000_vsim_supply.dev = mmc[0].dev;
+
+	return 0;
+}
+
+static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
+	.gpio_base	= OMAP_MAX_GPIO_LINES,
+	.irq_base	= TWL4030_GPIO_IRQ_BASE,
+	.irq_end	= TWL4030_GPIO_IRQ_END,
+	.use_leds	= true,
+	.pullups	= BIT(1),
+	.pulldowns	= BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
+				| BIT(15) | BIT(16) | BIT(17),
+	.setup		= devkit8000_twl_gpio_setup,
+};
+
+static struct regulator_consumer_supply devkit8000_vpll2_supplies[] = {
+	{
+	.supply		= "vdvi",
+	.dev		= &devkit8000_lcd_device.dev,
+	},
+	{
+	.supply		= "vdds_dsi",
+	.dev		= &devkit8000_dss_device.dev,
+	}
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data devkit8000_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	= &devkit8000_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data devkit8000_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	= &devkit8000_vsim_supply,
+};
+
+/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
+static struct regulator_init_data devkit8000_vdac = {
+	.constraints = {
+		.min_uV			= 1800000,
+		.max_uV			= 1800000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &devkit8000_vdda_dac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_init_data devkit8000_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	= ARRAY_SIZE(devkit8000_vpll2_supplies),
+	.consumer_supplies	= devkit8000_vpll2_supplies,
+};
+
+static struct twl4030_usb_data devkit8000_usb_data = {
+	.usb_mode	= T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_codec_audio_data devkit8000_audio_data = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data devkit8000_codec_data = {
+	.audio_mclk = 26000000,
+	.audio = &devkit8000_audio_data,
+};
+
+static struct twl4030_platform_data devkit8000_twldata = {
+	.irq_base	= TWL4030_IRQ_BASE,
+	.irq_end	= TWL4030_IRQ_END,
+
+	/* platform_data for children goes here */
+	.usb		= &devkit8000_usb_data,
+	.gpio		= &devkit8000_gpio_data,
+	.codec		= &devkit8000_codec_data,
+	.vmmc1		= &devkit8000_vmmc1,
+	.vsim		= &devkit8000_vsim,
+	.vdac		= &devkit8000_vdac,
+	.vpll2		= &devkit8000_vpll2,
+	.keypad		= &devkit8000_kp_data,
+};
+
+static struct i2c_board_info __initdata devkit8000_i2c_boardinfo[] = {
+	{
+		I2C_BOARD_INFO("twl4030", 0x48),
+		.flags = I2C_CLIENT_WAKE,
+		.irq = INT_34XX_SYS_NIRQ,
+		.platform_data = &devkit8000_twldata,
+	},
+};
+
+static int __init devkit8000_i2c_init(void)
+{
+	omap_register_i2c_bus(1, 2600, devkit8000_i2c_boardinfo,
+			ARRAY_SIZE(devkit8000_i2c_boardinfo));
+	/* Bus 3 is attached to the DVI port where devices like the pico DLP
+	 * projector don't work reliably with 400kHz */
+	omap_register_i2c_bus(3, 400, NULL, 0);
+	return 0;
+}
+
+static struct gpio_led gpio_leds[] = {
+	{
+		.name			= "led1",
+		.default_trigger	= "heartbeat",
+		.gpio			= 186,
+		.active_low		= true,
+	},
+	{
+		.name			= "led2",
+		.default_trigger	= "mmc0",
+		.gpio			= 163,
+		.active_low		= true,
+	},
+	{
+		.name			= "ledB",
+		.default_trigger	= "none",
+		.gpio			= 153,
+		.active_low             = true,
+	},
+	{
+		.name			= "led3",
+		.default_trigger	= "none",
+		.gpio			= 164,
+		.active_low             = true,
+	},
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+	.leds		= gpio_leds,
+	.num_leds	= ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &gpio_led_info,
+	},
+};
+
+static struct gpio_keys_button gpio_buttons[] = {
+	{
+		.code			= BTN_EXTRA,
+		.gpio			= 26,
+		.desc			= "user",
+		.wakeup			= 1,
+	},
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+	.buttons	= gpio_buttons,
+	.nbuttons	= ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device keys_gpio = {
+	.name	= "gpio-keys",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &gpio_key_info,
+	},
+};
+
+
+static void __init devkit8000_init_irq(void)
+{
+	omap_board_config = devkit8000_config;
+	omap_board_config_size = ARRAY_SIZE(devkit8000_config);
+	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
+			     mt46h32m32lf6_sdrc_params);
+	omap_init_irq();
+#ifdef CONFIG_OMAP_32K_TIMER
+	omap2_gp_clockevent_set_gptimer(12);
+#endif
+	omap_gpio_init();
+}
+
+static void __init devkit8000_ads7846_init(void)
+{
+	int gpio = OMAP3_DEVKIT_TS_GPIO;
+	int ret;
+
+	ret = gpio_request(gpio, "ads7846_pen_down");
+	if (ret < 0) {
+		printk(KERN_ERR "Failed to request GPIO %d for "
+				"ads7846 pen down IRQ\n", gpio);
+		return;
+	}
+
+	gpio_direction_input(gpio);
+}
+
+static int ads7846_get_pendown_state(void)
+{
+	return !gpio_get_value(OMAP3_DEVKIT_TS_GPIO);
+}
+
+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           = 5,
+	.debounce_rep           = 1,
+	.get_pendown_state	= ads7846_get_pendown_state,
+	.keep_vref_on		= 1,
+	.settle_delay_usecs     = 150,
+};
+
+static struct omap2_mcspi_device_config ads7846_mcspi_config = {
+	.turbo_mode	= 0,
+	.single_channel	= 1,	/* 0: slave, 1: master */
+};
+
+static struct spi_board_info devkit8000_spi_board_info[] __initdata = {
+	{
+		.modalias		= "ads7846",
+		.bus_num		= 2,
+		.chip_select		= 0,
+		.max_speed_hz		= 1500000,
+		.controller_data	= &ads7846_mcspi_config,
+		.irq			= OMAP_GPIO_IRQ(OMAP3_DEVKIT_TS_GPIO),
+		.platform_data		= &ads7846_config,
+	}
+};
+
+#define OMAP_DM9000_BASE	0x2c000000
+
+static struct resource omap_dm9000_resources[] = {
+	[0] = {
+		.start		= OMAP_DM9000_BASE,
+		.end		= (OMAP_DM9000_BASE + 0x4 - 1),
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= (OMAP_DM9000_BASE + 0x400),
+		.end		= (OMAP_DM9000_BASE + 0x400 + 0x4 - 1),
+		.flags		= IORESOURCE_MEM,
+	},
+	[2] = {
+		.start		= OMAP_GPIO_IRQ(OMAP_DM9000_GPIO_IRQ),
+		.flags		= IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+	},
+};
+
+static struct dm9000_plat_data omap_dm9000_platdata = {
+	.flags = DM9000_PLATF_16BITONLY,
+};
+
+static struct platform_device omap_dm9000_dev = {
+	.name = "dm9000",
+	.id = -1,
+	.num_resources	= ARRAY_SIZE(omap_dm9000_resources),
+	.resource	= omap_dm9000_resources,
+	.dev = {
+		.platform_data = &omap_dm9000_platdata,
+	},
+};
+
+static void __init omap_dm9000_init(void)
+{
+	if (gpio_request(OMAP_DM9000_GPIO_IRQ, "dm9000 irq") < 0) {
+		printk(KERN_ERR "Failed to request GPIO%d for dm9000 IRQ\n",
+			OMAP_DM9000_GPIO_IRQ);
+		return;
+		}
+
+	gpio_direction_input(OMAP_DM9000_GPIO_IRQ);
+}
+
+static struct platform_device *devkit8000_devices[] __initdata = {
+	&devkit8000_dss_device,
+	&leds_gpio,
+	&keys_gpio,
+	&omap_dm9000_dev,
+};
+
+static void __init devkit8000_flash_init(void)
+{
+	u8 cs = 0;
+	u8 nandcs = GPMC_CS_NUM + 1;
+
+	u32 gpmc_base_add = OMAP34XX_GPMC_VIRT;
+
+	/* find out the chip-select on which NAND exists */
+	while (cs < GPMC_CS_NUM) {
+		u32 ret = 0;
+		ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+		if ((ret & 0xC00) == 0x800) {
+			printk(KERN_INFO "Found NAND on CS%d\n", cs);
+			if (nandcs > GPMC_CS_NUM)
+				nandcs = cs;
+		}
+		cs++;
+	}
+
+	if (nandcs > GPMC_CS_NUM) {
+		printk(KERN_INFO "NAND: Unable to find configuration "
+				 "in GPMC\n ");
+		return;
+	}
+
+	if (nandcs < GPMC_CS_NUM) {
+		devkit8000_nand_data.cs = nandcs;
+		devkit8000_nand_data.gpmc_cs_baseaddr = (void *)
+			(gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE);
+		devkit8000_nand_data.gpmc_baseaddr = (void *)
+			(gpmc_base_add);
+
+		printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
+		if (platform_device_register(&devkit8000_nand_device) < 0)
+			printk(KERN_ERR "Unable to register NAND device\n");
+	}
+}
+
+static struct omap_musb_board_data musb_board_data = {
+	.interface_type		= MUSB_INTERFACE_ULPI,
+	.mode			= MUSB_OTG,
+	.power			= 100,
+};
+
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+
+	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+	.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+	.phy_reset  = true,
+	.reset_gpio_port[0]  = -EINVAL,
+	.reset_gpio_port[1]  = -EINVAL,
+	.reset_gpio_port[2]  = -EINVAL
+};
+
+static void __init devkit8000_init(void)
+{
+	omap_serial_init();
+
+	omap_dm9000_init();
+
+	devkit8000_i2c_init();
+	platform_add_devices(devkit8000_devices,
+			ARRAY_SIZE(devkit8000_devices));
+	omap_board_config = devkit8000_config;
+	omap_board_config_size = ARRAY_SIZE(devkit8000_config);
+
+	spi_register_board_info(devkit8000_spi_board_info,
+	ARRAY_SIZE(devkit8000_spi_board_info));
+
+	devkit8000_ads7846_init();
+
+	usb_musb_init(&musb_board_data);
+	usb_ehci_init(&ehci_pdata);
+	devkit8000_flash_init();
+
+	/* Ensure SDRC pins are mux'd for self-refresh */
+	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+	omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+}
+
+static void __init devkit8000_map_io(void)
+{
+	omap2_set_globals_343x();
+	omap34xx_map_common_io();
+}
+
+MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000")
+	.phys_io	= 0x48000000,
+	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= devkit8000_map_io,
+	.init_irq	= devkit8000_init_irq,
+	.init_machine	= devkit8000_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-generic.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-generic.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,7 +50,7 @@ static void __init omap_generic_init(voi
 static void __init omap_generic_map_io(void)
 {
 	omap2_set_globals_242x(); /* should be 242x, 243x, or 343x */
-	omap2_map_common_io();
+	omap242x_map_common_io();
 }
 
 MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-h4.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-h4.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-h4.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-h4.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
 #include <linux/i2c.h>
@@ -29,7 +30,6 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <asm/mach/flash.h>
 
 #include <plat/control.h>
 #include <mach/gpio.h>
@@ -115,8 +115,7 @@ static struct mtd_partition h4_partition
 	}
 };
 
-static struct flash_platform_data h4_flash_data = {
-	.map_name	= "cfi_probe",
+static struct physmap_flash_data h4_flash_data = {
 	.width		= 2,
 	.parts		= h4_partitions,
 	.nr_parts	= ARRAY_SIZE(h4_partitions),
@@ -127,7 +126,7 @@ static struct resource h4_flash_resource
 };
 
 static struct platform_device h4_flash_device = {
-	.name		= "omapflash",
+	.name		= "physmap-flash",
 	.id		= 0,
 	.dev		= {
 		.platform_data	= &h4_flash_data,
@@ -370,7 +369,7 @@ static void __init omap_h4_init(void)
 static void __init omap_h4_map_io(void)
 {
 	omap2_set_globals_242x();
-	omap2_map_common_io();
+	omap242x_map_common_io();
 }
 
 MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-igep0020.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-igep0020.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-igep0020.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-igep0020.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,16 +28,121 @@
 #include <plat/common.h>
 #include <plat/gpmc.h>
 #include <plat/usb.h>
+#include <plat/display.h>
+#include <plat/onenand.h>
 
 #include "mux.h"
-#include "mmc-twl4030.h"
+#include "hsmmc.h"
+#include "sdram-numonyx-m65kxxxxam.h"
 
 #define IGEP2_SMSC911X_CS       5
 #define IGEP2_SMSC911X_GPIO     176
 #define IGEP2_GPIO_USBH_NRESET  24
-#define IGEP2_GPIO_LED0_RED 	26
-#define IGEP2_GPIO_LED0_GREEN 	27
+#define IGEP2_GPIO_LED0_GREEN 	26
+#define IGEP2_GPIO_LED0_RED 	27
 #define IGEP2_GPIO_LED1_RED   	28
+#define IGEP2_GPIO_DVI_PUP	170
+#define IGEP2_GPIO_WIFI_NPD 	94
+#define IGEP2_GPIO_WIFI_NRESET 	95
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+	defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+
+#define ONENAND_MAP             0x20000000
+
+/* NAND04GR4E1A ( x2 Flash built-in COMBO POP MEMORY )
+ * Since the device is equipped with two DataRAMs, and two-plane NAND
+ * Flash memory array, these two component enables simultaneous program
+ * of 4KiB. Plane1 has only even blocks such as block0, block2, block4
+ * while Plane2 has only odd blocks such as block1, block3, block5.
+ * So MTD regards it as 4KiB page size and 256KiB block size 64*(2*2048)
+ */
+
+static struct mtd_partition igep2_onenand_partitions[] = {
+	{
+		.name           = "X-Loader",
+		.offset         = 0,
+		.size           = 2 * (64*(2*2048))
+	},
+	{
+		.name           = "U-Boot",
+		.offset         = MTDPART_OFS_APPEND,
+		.size           = 6 * (64*(2*2048)),
+	},
+	{
+		.name           = "Environment",
+		.offset         = MTDPART_OFS_APPEND,
+		.size           = 2 * (64*(2*2048)),
+	},
+	{
+		.name           = "Kernel",
+		.offset         = MTDPART_OFS_APPEND,
+		.size           = 12 * (64*(2*2048)),
+	},
+	{
+		.name           = "File System",
+		.offset         = MTDPART_OFS_APPEND,
+		.size           = MTDPART_SIZ_FULL,
+	},
+};
+
+static int igep2_onenand_setup(void __iomem *onenand_base, int freq)
+{
+       /* nothing is required to be setup for onenand as of now */
+       return 0;
+}
+
+static struct omap_onenand_platform_data igep2_onenand_data = {
+	.parts = igep2_onenand_partitions,
+	.nr_parts = ARRAY_SIZE(igep2_onenand_partitions),
+	.onenand_setup = igep2_onenand_setup,
+	.dma_channel	= -1,	/* disable DMA in OMAP OneNAND driver */
+};
+
+static struct platform_device igep2_onenand_device = {
+	.name		= "omap2-onenand",
+	.id		= -1,
+	.dev = {
+		.platform_data = &igep2_onenand_data,
+	},
+};
+
+void __init igep2_flash_init(void)
+{
+	u8		cs = 0;
+	u8		onenandcs = GPMC_CS_NUM + 1;
+
+	while (cs < GPMC_CS_NUM) {
+		u32 ret = 0;
+		ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+		/* Check if NAND/oneNAND is configured */
+		if ((ret & 0xC00) == 0x800)
+			/* NAND found */
+			pr_err("IGEP v2: Unsupported NAND found\n");
+		else {
+			ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+			if ((ret & 0x3F) == (ONENAND_MAP >> 24))
+				/* ONENAND found */
+				onenandcs = cs;
+		}
+		cs++;
+	}
+	if (onenandcs > GPMC_CS_NUM) {
+		pr_err("IGEP v2: Unable to find configuration in GPMC\n");
+		return;
+	}
+
+	if (onenandcs < GPMC_CS_NUM) {
+		igep2_onenand_data.cs = onenandcs;
+		if (platform_device_register(&igep2_onenand_device) < 0)
+			pr_err("IGEP v2: Unable to register OneNAND device\n");
+	}
+}
+
+#else
+void __init igep2_flash_init(void) {}
+#endif
 
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 
@@ -106,6 +211,10 @@ static struct regulator_consumer_supply
 	.supply		= "vmmc",
 };
 
+static struct regulator_consumer_supply igep2_vmmc2_supply = {
+	.supply		= "vmmc",
+};
+
 /* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
 static struct regulator_init_data igep2_vmmc1 = {
 	.constraints = {
@@ -121,7 +230,22 @@ static struct regulator_init_data igep2_
 	.consumer_supplies      = &igep2_vmmc1_supply,
 };
 
-static struct twl4030_hsmmc_info mmc[] = {
+/* VMMC2 for OMAP VDD_MMC2 (i/o) and MMC2 WIFI */
+static struct regulator_init_data igep2_vmmc2 = {
+	.constraints = {
+		.min_uV			= 1850000,
+		.max_uV			= 3150000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
+					| REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies  = 1,
+	.consumer_supplies      = &igep2_vmmc2_supply,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.wires		= 4,
@@ -142,12 +266,13 @@ static int igep2_twl_gpio_setup(struct d
 {
 	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
 	mmc[0].gpio_cd = gpio + 0;
-	twl4030_mmc_init(mmc);
+	omap2_hsmmc_init(mmc);
 
 	/* link regulators to MMC adapters ... we "know" the
 	 * regulators will be set up only *after* we return.
 	*/
 	igep2_vmmc1_supply.dev = mmc[0].dev;
+	igep2_vmmc2_supply.dev = mmc[1].dev;
 
 	return 0;
 };
@@ -164,23 +289,146 @@ static struct twl4030_usb_data igep2_usb
 	.usb_mode	= T2_USB_MODE_ULPI,
 };
 
+static int igep2_enable_dvi(struct omap_dss_device *dssdev)
+{
+	gpio_direction_output(IGEP2_GPIO_DVI_PUP, 1);
+
+	return 0;
+}
+
+static void igep2_disable_dvi(struct omap_dss_device *dssdev)
+{
+	gpio_direction_output(IGEP2_GPIO_DVI_PUP, 0);
+}
+
+static struct omap_dss_device igep2_dvi_device = {
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.name			= "dvi",
+	.driver_name		= "generic_panel",
+	.phy.dpi.data_lines	= 24,
+	.platform_enable	= igep2_enable_dvi,
+	.platform_disable	= igep2_disable_dvi,
+};
+
+static struct omap_dss_device *igep2_dss_devices[] = {
+	&igep2_dvi_device
+};
+
+static struct omap_dss_board_info igep2_dss_data = {
+	.num_devices	= ARRAY_SIZE(igep2_dss_devices),
+	.devices	= igep2_dss_devices,
+	.default_device	= &igep2_dvi_device,
+};
+
+static struct platform_device igep2_dss_device = {
+	.name	= "omapdss",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &igep2_dss_data,
+	},
+};
+
+static struct regulator_consumer_supply igep2_vpll2_supply = {
+	.supply	= "vdds_dsi",
+	.dev	= &igep2_dss_device.dev,
+};
+
+static struct regulator_init_data igep2_vpll2 = {
+	.constraints = {
+		.name			= "VDVI",
+		.min_uV			= 1800000,
+		.max_uV			= 1800000,
+		.apply_uV		= true,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &igep2_vpll2_supply,
+};
+
+static void __init igep2_display_init(void)
+{
+	if (gpio_request(IGEP2_GPIO_DVI_PUP, "GPIO_DVI_PUP") &&
+	    gpio_direction_output(IGEP2_GPIO_DVI_PUP, 1))
+		pr_err("IGEP v2: Could not obtain gpio GPIO_DVI_PUP\n");
+}
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#include <linux/leds.h>
+
+static struct gpio_led igep2_gpio_leds[] = {
+	{
+		.name = "led0:red",
+		.gpio = IGEP2_GPIO_LED0_RED,
+	},
+	{
+		.name = "led0:green",
+		.default_trigger = "heartbeat",
+		.gpio = IGEP2_GPIO_LED0_GREEN,
+	},
+	{
+		.name = "led1:red",
+		.gpio = IGEP2_GPIO_LED1_RED,
+	},
+};
+
+static struct gpio_led_platform_data igep2_led_pdata = {
+	.leds           = igep2_gpio_leds,
+	.num_leds       = ARRAY_SIZE(igep2_gpio_leds),
+};
+
+static struct platform_device igep2_led_device = {
+	 .name   = "leds-gpio",
+	 .id     = -1,
+	 .dev    = {
+		 .platform_data  =  &igep2_led_pdata,
+	},
+};
+
+static void __init igep2_init_led(void)
+{
+	platform_device_register(&igep2_led_device);
+}
+
+#else
+static inline void igep2_init_led(void) {}
+#endif
+
+static struct platform_device *igep2_devices[] __initdata = {
+	&igep2_dss_device,
+};
+
 static void __init igep2_init_irq(void)
 {
 	omap_board_config = igep2_config;
 	omap_board_config_size = ARRAY_SIZE(igep2_config);
-	omap2_init_common_hw(NULL, NULL);
+	omap2_init_common_hw(m65kxxxxam_sdrc_params, m65kxxxxam_sdrc_params);
 	omap_init_irq();
 	omap_gpio_init();
 }
 
+static struct twl4030_codec_audio_data igep2_audio_data = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data igep2_codec_data = {
+	.audio_mclk = 26000000,
+	.audio = &igep2_audio_data,
+};
+
 static struct twl4030_platform_data igep2_twldata = {
 	.irq_base	= TWL4030_IRQ_BASE,
 	.irq_end	= TWL4030_IRQ_END,
 
 	/* platform_data for children goes here */
 	.usb		= &igep2_usb_data,
+	.codec		= &igep2_codec_data,
 	.gpio		= &igep2_gpio_data,
 	.vmmc1          = &igep2_vmmc1,
+	.vmmc2		= &igep2_vmmc2,
+	.vpll2		= &igep2_vpll2,
 
 };
 
@@ -203,6 +451,23 @@ static int __init igep2_i2c_init(void)
 	return 0;
 }
 
+static struct omap_musb_board_data musb_board_data = {
+	.interface_type		= MUSB_INTERFACE_ULPI,
+	.mode			= MUSB_OTG,
+	.power			= 100,
+};
+
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+	.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+	.phy_reset = true,
+	.reset_gpio_port[0] = IGEP2_GPIO_USBH_NRESET,
+	.reset_gpio_port[1] = -EINVAL,
+	.reset_gpio_port[2] = -EINVAL,
+};
+
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux board_mux[] __initdata = {
 	{ .reg_offset = OMAP_MUX_TERMINATOR },
@@ -215,38 +480,62 @@ static void __init igep2_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	igep2_i2c_init();
+	platform_add_devices(igep2_devices, ARRAY_SIZE(igep2_devices));
 	omap_serial_init();
-	usb_musb_init();
+	usb_musb_init(&musb_board_data);
+	usb_ehci_init(&ehci_pdata);
 
+	igep2_flash_init();
+	igep2_init_led();
+	igep2_display_init();
 	igep2_init_smsc911x();
 
 	/* GPIO userspace leds */
-	if ((gpio_request(IGEP2_GPIO_LED0_RED, "GPIO_LED0_RED") == 0) &&
+#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
+	if ((gpio_request(IGEP2_GPIO_LED0_RED, "led0:red") == 0) &&
 	    (gpio_direction_output(IGEP2_GPIO_LED0_RED, 1) == 0)) {
 		gpio_export(IGEP2_GPIO_LED0_RED, 0);
 		gpio_set_value(IGEP2_GPIO_LED0_RED, 0);
 	} else
 		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n");
 
-	if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "GPIO_LED0_GREEN") == 0) &&
+	if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "led0:green") == 0) &&
 	    (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 1) == 0)) {
 		gpio_export(IGEP2_GPIO_LED0_GREEN, 0);
 		gpio_set_value(IGEP2_GPIO_LED0_GREEN, 0);
 	} else
 		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n");
 
-	if ((gpio_request(IGEP2_GPIO_LED1_RED, "GPIO_LED1_RED") == 0) &&
+	if ((gpio_request(IGEP2_GPIO_LED1_RED, "led1:red") == 0) &&
 	    (gpio_direction_output(IGEP2_GPIO_LED1_RED, 1) == 0)) {
 		gpio_export(IGEP2_GPIO_LED1_RED, 0);
 		gpio_set_value(IGEP2_GPIO_LED1_RED, 0);
 	} else
 		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n");
+#endif
+
+	/* GPIO W-LAN + Bluetooth combo module */
+	if ((gpio_request(IGEP2_GPIO_WIFI_NPD, "GPIO_WIFI_NPD") == 0) &&
+	    (gpio_direction_output(IGEP2_GPIO_WIFI_NPD, 1) == 0)) {
+		gpio_export(IGEP2_GPIO_WIFI_NPD, 0);
+/* 		gpio_set_value(IGEP2_GPIO_WIFI_NPD, 0); */
+	} else
+		pr_warning("IGEP v2: Could not obtain gpio GPIO_WIFI_NPD\n");
+
+	if ((gpio_request(IGEP2_GPIO_WIFI_NRESET, "GPIO_WIFI_NRESET") == 0) &&
+	    (gpio_direction_output(IGEP2_GPIO_WIFI_NRESET, 1) == 0)) {
+		gpio_export(IGEP2_GPIO_WIFI_NRESET, 0);
+		gpio_set_value(IGEP2_GPIO_WIFI_NRESET, 0);
+		udelay(10);
+		gpio_set_value(IGEP2_GPIO_WIFI_NRESET, 1);
+	} else
+		pr_warning("IGEP v2: Could not obtain gpio GPIO_WIFI_NRESET\n");
 }
 
 static void __init igep2_map_io(void)
 {
 	omap2_set_globals_343x();
-	omap2_map_common_io();
+	omap34xx_map_common_io();
 }
 
 MACHINE_START(IGEP0020, "IGEP v2 board")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-ldp.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-ldp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-ldp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-ldp.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,7 +44,7 @@
 #include <plat/usb.h>
 
 #include "mux.h"
-#include "mmc-twl4030.h"
+#include "hsmmc.h"
 
 #define LDP_SMSC911X_CS		1
 #define LDP_SMSC911X_GPIO	152
@@ -359,7 +359,7 @@ static int __init omap_i2c_init(void)
 	return 0;
 }
 
-static struct twl4030_hsmmc_info mmc[] __initdata = {
+static struct omap2_hsmmc_info mmc[] __initdata = {
 	{
 		.mmc		= 1,
 		.wires		= 4,
@@ -383,6 +383,12 @@ static struct omap_board_mux board_mux[]
 #define board_mux	NULL
 #endif
 
+static struct omap_musb_board_data musb_board_data = {
+	.interface_type		= MUSB_INTERFACE_ULPI,
+	.mode			= MUSB_OTG,
+	.power			= 100,
+};
+
 static void __init omap_ldp_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
@@ -394,9 +400,9 @@ static void __init omap_ldp_init(void)
 				ARRAY_SIZE(ldp_spi_board_info));
 	ads7846_dev_init();
 	omap_serial_init();
-	usb_musb_init();
+	usb_musb_init(&musb_board_data);
 
-	twl4030_mmc_init(mmc);
+	omap2_hsmmc_init(mmc);
 	/* link regulators to MMC adapters */
 	ldp_vmmc1_supply.dev = mmc[0].dev;
 }
@@ -404,7 +410,7 @@ static void __init omap_ldp_init(void)
 static void __init omap_ldp_map_io(void)
 {
 	omap2_set_globals_343x();
-	omap2_map_common_io();
+	omap34xx_map_common_io();
 }
 
 MACHINE_START(OMAP_LDP, "OMAP LDP board")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-n8x0.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-n8x0.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-n8x0.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-n8x0.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/stddef.h>
+#include <linux/i2c.h>
 #include <linux/spi/spi.h>
 #include <linux/usb/musb.h>
 
@@ -25,11 +26,114 @@
 
 #include <plat/board.h>
 #include <plat/common.h>
+#include <plat/menelaus.h>
 #include <mach/irqs.h>
 #include <plat/mcspi.h>
 #include <plat/onenand.h>
+#include <plat/mmc.h>
 #include <plat/serial.h>
 
+static int slot1_cover_open;
+static int slot2_cover_open;
+static struct device *mmc_device;
+
+#define TUSB6010_ASYNC_CS	1
+#define TUSB6010_SYNC_CS	4
+#define TUSB6010_GPIO_INT	58
+#define TUSB6010_GPIO_ENABLE	0
+#define TUSB6010_DMACHAN	0x3f
+
+#if defined(CONFIG_USB_TUSB6010) || \
+	defined(CONFIG_USB_TUSB6010_MODULE)
+/*
+ * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
+ * 1.5 V voltage regulators of PM companion chip. Companion chip will then
+ * provide then PGOOD signal to TUSB6010 which will release it from reset.
+ */
+static int tusb_set_power(int state)
+{
+	int i, retval = 0;
+
+	if (state) {
+		gpio_set_value(TUSB6010_GPIO_ENABLE, 1);
+		msleep(1);
+
+		/* Wait until TUSB6010 pulls INT pin down */
+		i = 100;
+		while (i && gpio_get_value(TUSB6010_GPIO_INT)) {
+			msleep(1);
+			i--;
+		}
+
+		if (!i) {
+			printk(KERN_ERR "tusb: powerup failed\n");
+			retval = -ENODEV;
+		}
+	} else {
+		gpio_set_value(TUSB6010_GPIO_ENABLE, 0);
+		msleep(10);
+	}
+
+	return retval;
+}
+
+static struct musb_hdrc_config musb_config = {
+	.multipoint	= 1,
+	.dyn_fifo	= 1,
+	.num_eps	= 16,
+	.ram_bits	= 12,
+};
+
+static struct musb_hdrc_platform_data tusb_data = {
+#if defined(CONFIG_USB_MUSB_OTG)
+	.mode		= MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
+	.mode		= MUSB_PERIPHERAL,
+#else /* defined(CONFIG_USB_MUSB_HOST) */
+	.mode		= MUSB_HOST,
+#endif
+	.set_power	= tusb_set_power,
+	.min_power	= 25,	/* x2 = 50 mA drawn from VBUS as peripheral */
+	.power		= 100,	/* Max 100 mA VBUS for host mode */
+	.config		= &musb_config,
+};
+
+static void __init n8x0_usb_init(void)
+{
+	int ret = 0;
+	static char	announce[] __initdata = KERN_INFO "TUSB 6010\n";
+
+	/* PM companion chip power control pin */
+	ret = gpio_request(TUSB6010_GPIO_ENABLE, "TUSB6010 enable");
+	if (ret != 0) {
+		printk(KERN_ERR "Could not get TUSB power GPIO%i\n",
+		       TUSB6010_GPIO_ENABLE);
+		return;
+	}
+	gpio_direction_output(TUSB6010_GPIO_ENABLE, 0);
+
+	tusb_set_power(0);
+
+	ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2,
+					TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS,
+					TUSB6010_GPIO_INT, TUSB6010_DMACHAN);
+	if (ret != 0)
+		goto err;
+
+	printk(announce);
+
+	return;
+
+err:
+	gpio_free(TUSB6010_GPIO_ENABLE);
+}
+#else
+
+static void __init n8x0_usb_init(void) {}
+
+#endif /*CONFIG_USB_TUSB6010 */
+
+
 static struct omap2_mcspi_device_config p54spi_mcspi_config = {
 	.turbo_mode	= 0,
 	.single_channel = 1,
@@ -96,10 +200,446 @@ static void __init n8x0_onenand_init(voi
 
 #endif
 
+#if defined(CONFIG_MENELAUS) &&						\
+	(defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE))
+
+/*
+ * On both N800 and N810, only the first of the two MMC controllers is in use.
+ * The two MMC slots are multiplexed via Menelaus companion chip over I2C.
+ * On N800, both slots are powered via Menelaus. On N810, only one of the
+ * slots is powered via Menelaus. The N810 EMMC is powered via GPIO.
+ *
+ * VMMC				slot 1 on both N800 and N810
+ * VDCDC3_APE and VMCS2_APE	slot 2 on N800
+ * GPIO23 and GPIO9		slot 2 EMMC on N810
+ *
+ */
+#define N8X0_SLOT_SWITCH_GPIO	96
+#define N810_EMMC_VSD_GPIO	23
+#define N810_EMMC_VIO_GPIO	9
+
+static int n8x0_mmc_switch_slot(struct device *dev, int slot)
+{
+#ifdef CONFIG_MMC_DEBUG
+	dev_dbg(dev, "Choose slot %d\n", slot + 1);
+#endif
+	gpio_set_value(N8X0_SLOT_SWITCH_GPIO, slot);
+	return 0;
+}
+
+static int n8x0_mmc_set_power_menelaus(struct device *dev, int slot,
+					int power_on, int vdd)
+{
+	int mV;
+
+#ifdef CONFIG_MMC_DEBUG
+	dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
+		power_on ? "on" : "off", vdd);
+#endif
+	if (slot == 0) {
+		if (!power_on)
+			return menelaus_set_vmmc(0);
+		switch (1 << vdd) {
+		case MMC_VDD_33_34:
+		case MMC_VDD_32_33:
+		case MMC_VDD_31_32:
+			mV = 3100;
+			break;
+		case MMC_VDD_30_31:
+			mV = 3000;
+			break;
+		case MMC_VDD_28_29:
+			mV = 2800;
+			break;
+		case MMC_VDD_165_195:
+			mV = 1850;
+			break;
+		default:
+			BUG();
+		}
+		return menelaus_set_vmmc(mV);
+	} else {
+		if (!power_on)
+			return menelaus_set_vdcdc(3, 0);
+		switch (1 << vdd) {
+		case MMC_VDD_33_34:
+		case MMC_VDD_32_33:
+			mV = 3300;
+			break;
+		case MMC_VDD_30_31:
+		case MMC_VDD_29_30:
+			mV = 3000;
+			break;
+		case MMC_VDD_28_29:
+		case MMC_VDD_27_28:
+			mV = 2800;
+			break;
+		case MMC_VDD_24_25:
+		case MMC_VDD_23_24:
+			mV = 2400;
+			break;
+		case MMC_VDD_22_23:
+		case MMC_VDD_21_22:
+			mV = 2200;
+			break;
+		case MMC_VDD_20_21:
+			mV = 2000;
+			break;
+		case MMC_VDD_165_195:
+			mV = 1800;
+			break;
+		default:
+			BUG();
+		}
+		return menelaus_set_vdcdc(3, mV);
+	}
+	return 0;
+}
+
+static void n810_set_power_emmc(struct device *dev,
+					 int power_on)
+{
+	dev_dbg(dev, "Set EMMC power %s\n", power_on ? "on" : "off");
+
+	if (power_on) {
+		gpio_set_value(N810_EMMC_VSD_GPIO, 1);
+		msleep(1);
+		gpio_set_value(N810_EMMC_VIO_GPIO, 1);
+		msleep(1);
+	} else {
+		gpio_set_value(N810_EMMC_VIO_GPIO, 0);
+		msleep(50);
+		gpio_set_value(N810_EMMC_VSD_GPIO, 0);
+		msleep(50);
+	}
+}
+
+static int n8x0_mmc_set_power(struct device *dev, int slot, int power_on,
+			      int vdd)
+{
+	if (machine_is_nokia_n800() || slot == 0)
+		return n8x0_mmc_set_power_menelaus(dev, slot, power_on, vdd);
+
+	n810_set_power_emmc(dev, power_on);
+
+	return 0;
+}
+
+static int n8x0_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
+{
+	int r;
+
+	dev_dbg(dev, "Set slot %d bus mode %s\n", slot + 1,
+		bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
+	BUG_ON(slot != 0 && slot != 1);
+	slot++;
+	switch (bus_mode) {
+	case MMC_BUSMODE_OPENDRAIN:
+		r = menelaus_set_mmc_opendrain(slot, 1);
+		break;
+	case MMC_BUSMODE_PUSHPULL:
+		r = menelaus_set_mmc_opendrain(slot, 0);
+		break;
+	default:
+		BUG();
+	}
+	if (r != 0 && printk_ratelimit())
+		dev_err(dev, "MMC: unable to set bus mode for slot %d\n",
+			slot);
+	return r;
+}
+
+static int n8x0_mmc_get_cover_state(struct device *dev, int slot)
+{
+	slot++;
+	BUG_ON(slot != 1 && slot != 2);
+	if (slot == 1)
+		return slot1_cover_open;
+	else
+		return slot2_cover_open;
+}
+
+static void n8x0_mmc_callback(void *data, u8 card_mask)
+{
+	int bit, *openp, index;
+
+	if (machine_is_nokia_n800()) {
+		bit = 1 << 1;
+		openp = &slot2_cover_open;
+		index = 1;
+	} else {
+		bit = 1;
+		openp = &slot1_cover_open;
+		index = 0;
+	}
+
+	if (card_mask & bit)
+		*openp = 1;
+	else
+		*openp = 0;
+
+	omap_mmc_notify_cover_event(mmc_device, index, *openp);
+}
+
+void n8x0_mmc_slot1_cover_handler(void *arg, int closed_state)
+{
+	if (mmc_device == NULL)
+		return;
+
+	slot1_cover_open = !closed_state;
+	omap_mmc_notify_cover_event(mmc_device, 0, closed_state);
+}
+
+static int n8x0_mmc_late_init(struct device *dev)
+{
+	int r, bit, *openp;
+	int vs2sel;
+
+	mmc_device = dev;
+
+	r = menelaus_set_slot_sel(1);
+	if (r < 0)
+		return r;
+
+	if (machine_is_nokia_n800())
+		vs2sel = 0;
+	else
+		vs2sel = 2;
+
+	r = menelaus_set_mmc_slot(2, 0, vs2sel, 1);
+	if (r < 0)
+		return r;
+
+	n8x0_mmc_set_power(dev, 0, MMC_POWER_ON, 16); /* MMC_VDD_28_29 */
+	n8x0_mmc_set_power(dev, 1, MMC_POWER_ON, 16);
+
+	r = menelaus_set_mmc_slot(1, 1, 0, 1);
+	if (r < 0)
+		return r;
+	r = menelaus_set_mmc_slot(2, 1, vs2sel, 1);
+	if (r < 0)
+		return r;
+
+	r = menelaus_get_slot_pin_states();
+	if (r < 0)
+		return r;
+
+	if (machine_is_nokia_n800()) {
+		bit = 1 << 1;
+		openp = &slot2_cover_open;
+	} else {
+		bit = 1;
+		openp = &slot1_cover_open;
+		slot2_cover_open = 0;
+	}
+
+	/* All slot pin bits seem to be inversed until first switch change */
+	if (r == 0xf || r == (0xf & ~bit))
+		r = ~r;
+
+	if (r & bit)
+		*openp = 1;
+	else
+		*openp = 0;
+
+	r = menelaus_register_mmc_callback(n8x0_mmc_callback, NULL);
+
+	return r;
+}
+
+static void n8x0_mmc_shutdown(struct device *dev)
+{
+	int vs2sel;
+
+	if (machine_is_nokia_n800())
+		vs2sel = 0;
+	else
+		vs2sel = 2;
+
+	menelaus_set_mmc_slot(1, 0, 0, 0);
+	menelaus_set_mmc_slot(2, 0, vs2sel, 0);
+}
+
+static void n8x0_mmc_cleanup(struct device *dev)
+{
+	menelaus_unregister_mmc_callback();
+
+	gpio_free(N8X0_SLOT_SWITCH_GPIO);
+
+	if (machine_is_nokia_n810()) {
+		gpio_free(N810_EMMC_VSD_GPIO);
+		gpio_free(N810_EMMC_VIO_GPIO);
+	}
+}
+
+/*
+ * MMC controller1 has two slots that are multiplexed via I2C.
+ * MMC controller2 is not in use.
+ */
+static struct omap_mmc_platform_data mmc1_data = {
+	.nr_slots			= 2,
+	.switch_slot			= n8x0_mmc_switch_slot,
+	.init				= n8x0_mmc_late_init,
+	.cleanup			= n8x0_mmc_cleanup,
+	.shutdown			= n8x0_mmc_shutdown,
+	.max_freq			= 24000000,
+	.dma_mask			= 0xffffffff,
+	.slots[0] = {
+		.wires			= 4,
+		.set_power		= n8x0_mmc_set_power,
+		.set_bus_mode		= n8x0_mmc_set_bus_mode,
+		.get_cover_state	= n8x0_mmc_get_cover_state,
+		.ocr_mask		= MMC_VDD_165_195 | MMC_VDD_30_31 |
+						MMC_VDD_32_33   | MMC_VDD_33_34,
+		.name			= "internal",
+	},
+	.slots[1] = {
+		.set_power		= n8x0_mmc_set_power,
+		.set_bus_mode		= n8x0_mmc_set_bus_mode,
+		.get_cover_state	= n8x0_mmc_get_cover_state,
+		.ocr_mask		= MMC_VDD_165_195 | MMC_VDD_20_21 |
+						MMC_VDD_21_22 | MMC_VDD_22_23 |
+						MMC_VDD_23_24 | MMC_VDD_24_25 |
+						MMC_VDD_27_28 | MMC_VDD_28_29 |
+						MMC_VDD_29_30 | MMC_VDD_30_31 |
+						MMC_VDD_32_33 | MMC_VDD_33_34,
+		.name			= "external",
+	},
+};
+
+static struct omap_mmc_platform_data *mmc_data[OMAP24XX_NR_MMC];
+
+void __init n8x0_mmc_init(void)
+
+{
+	int err;
+
+	if (machine_is_nokia_n810()) {
+		mmc1_data.slots[0].name = "external";
+
+		/*
+		 * Some Samsung Movinand chips do not like open-ended
+		 * multi-block reads and fall to braind-dead state
+		 * while doing so. Reducing the number of blocks in
+		 * the transfer or delays in clock disable do not help
+		 */
+		mmc1_data.slots[1].name = "internal";
+		mmc1_data.slots[1].ban_openended = 1;
+	}
+
+	err = gpio_request(N8X0_SLOT_SWITCH_GPIO, "MMC slot switch");
+	if (err)
+		return;
+
+	gpio_direction_output(N8X0_SLOT_SWITCH_GPIO, 0);
+
+	if (machine_is_nokia_n810()) {
+		err = gpio_request(N810_EMMC_VSD_GPIO, "MMC slot 2 Vddf");
+		if (err) {
+			gpio_free(N8X0_SLOT_SWITCH_GPIO);
+			return;
+		}
+		gpio_direction_output(N810_EMMC_VSD_GPIO, 0);
+
+		err = gpio_request(N810_EMMC_VIO_GPIO, "MMC slot 2 Vdd");
+		if (err) {
+			gpio_free(N8X0_SLOT_SWITCH_GPIO);
+			gpio_free(N810_EMMC_VSD_GPIO);
+			return;
+		}
+		gpio_direction_output(N810_EMMC_VIO_GPIO, 0);
+	}
+
+	mmc_data[0] = &mmc1_data;
+	omap2_init_mmc(mmc_data, OMAP24XX_NR_MMC);
+}
+#else
+
+void __init n8x0_mmc_init(void)
+{
+}
+
+void n8x0_mmc_slot1_cover_handler(void *arg, int state)
+{
+}
+
+#endif	/* CONFIG_MMC_OMAP */
+
+#ifdef CONFIG_MENELAUS
+
+static int n8x0_auto_sleep_regulators(void)
+{
+	u32 val;
+	int ret;
+
+	val = EN_VPLL_SLEEP | EN_VMMC_SLEEP    \
+		| EN_VAUX_SLEEP | EN_VIO_SLEEP \
+		| EN_VMEM_SLEEP | EN_DC3_SLEEP \
+		| EN_VC_SLEEP | EN_DC2_SLEEP;
+
+	ret = menelaus_set_regulator_sleep(1, val);
+	if (ret < 0) {
+		printk(KERN_ERR "Could not set regulators to sleep on "
+			"menelaus: %u\n", ret);
+		return ret;
+	}
+	return 0;
+}
+
+static int n8x0_auto_voltage_scale(void)
+{
+	int ret;
+
+	ret = menelaus_set_vcore_hw(1400, 1050);
+	if (ret < 0) {
+		printk(KERN_ERR "Could not set VCORE voltage on "
+			"menelaus: %u\n", ret);
+		return ret;
+	}
+	return 0;
+}
+
+static int n8x0_menelaus_late_init(struct device *dev)
+{
+	int ret;
+
+	ret = n8x0_auto_voltage_scale();
+	if (ret < 0)
+		return ret;
+	ret = n8x0_auto_sleep_regulators();
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static struct i2c_board_info __initdata n8x0_i2c_board_info_1[] = {
+	{
+		I2C_BOARD_INFO("menelaus", 0x72),
+		.irq = INT_24XX_SYS_NIRQ,
+	},
+};
+
+static struct menelaus_platform_data n8x0_menelaus_platform_data = {
+	.late_init = n8x0_menelaus_late_init,
+};
+
+static void __init n8x0_menelaus_init(void)
+{
+	n8x0_i2c_board_info_1[0].platform_data = &n8x0_menelaus_platform_data;
+	omap_register_i2c_bus(1, 400, n8x0_i2c_board_info_1,
+			      ARRAY_SIZE(n8x0_i2c_board_info_1));
+}
+
+#else
+static inline void __init n8x0_menelaus_init(void)
+{
+}
+#endif
+
 static void __init n8x0_map_io(void)
 {
 	omap2_set_globals_242x();
-	omap2_map_common_io();
+	omap242x_map_common_io();
 }
 
 static void __init n8x0_init_irq(void)
@@ -116,7 +656,10 @@ static void __init n8x0_init_machine(voi
 				ARRAY_SIZE(n800_spi_board_info));
 
 	omap_serial_init();
+	n8x0_menelaus_init();
 	n8x0_onenand_init();
+	n8x0_mmc_init();
+	n8x0_usb_init();
 }
 
 MACHINE_START(NOKIA_N800, "Nokia N800")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3beagle.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-omap3beagle.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3beagle.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-omap3beagle.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,7 +45,7 @@
 #include <plat/timer-gp.h>
 
 #include "mux.h"
-#include "mmc-twl4030.h"
+#include "hsmmc.h"
 
 #define GPMC_CS0_BASE  0x60
 #define GPMC_CS_SIZE   0x30
@@ -108,7 +108,7 @@ static struct platform_device omap3beagl
 
 #include "sdram-micron-mt46h32m32lf-6.h"
 
-static struct twl4030_hsmmc_info mmc[] = {
+static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.wires		= 8,
@@ -147,7 +147,7 @@ static int beagle_twl_gpio_setup(struct
 	}
 	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
 	mmc[0].gpio_cd = gpio + 0;
-	twl4030_mmc_init(mmc);
+	omap2_hsmmc_init(mmc);
 
 	/* link regulators to MMC adapters */
 	beagle_vmmc1_supply.dev = mmc[0].dev;
@@ -410,7 +410,7 @@ static void __init omap3beagle_flash_ini
 	}
 }
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 
 	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
 	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
@@ -430,6 +430,12 @@ static struct omap_board_mux board_mux[]
 #define board_mux	NULL
 #endif
 
+static struct omap_musb_board_data musb_board_data = {
+	.interface_type		= MUSB_INTERFACE_ULPI,
+	.mode			= MUSB_OTG,
+	.power			= 100,
+};
+
 static void __init omap3_beagle_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
@@ -443,7 +449,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();
+	usb_musb_init(&musb_board_data);
 	usb_ehci_init(&ehci_pdata);
 	omap3beagle_flash_init();
 
@@ -455,7 +461,7 @@ static void __init omap3_beagle_init(voi
 static void __init omap3_beagle_map_io(void)
 {
 	omap2_set_globals_343x();
-	omap2_map_common_io();
+	omap34xx_map_common_io();
 }
 
 MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3evm.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-omap3evm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3evm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-omap3evm.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,10 +41,11 @@
 #include <plat/usb.h>
 #include <plat/common.h>
 #include <plat/mcspi.h>
+#include <plat/display.h>
 
 #include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
-#include "mmc-twl4030.h"
+#include "hsmmc.h"
 
 #define OMAP3_EVM_TS_GPIO	175
 #define OMAP3_EVM_EHCI_VBUS	22
@@ -147,6 +148,187 @@ static inline void __init omap3evm_init_
 static inline void __init omap3evm_init_smsc911x(void) { return; }
 #endif
 
+/*
+ * OMAP3EVM LCD Panel control signals
+ */
+#define OMAP3EVM_LCD_PANEL_LR		2
+#define OMAP3EVM_LCD_PANEL_UD		3
+#define OMAP3EVM_LCD_PANEL_INI		152
+#define OMAP3EVM_LCD_PANEL_ENVDD	153
+#define OMAP3EVM_LCD_PANEL_QVGA		154
+#define OMAP3EVM_LCD_PANEL_RESB		155
+#define OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO	210
+#define OMAP3EVM_DVI_PANEL_EN_GPIO	199
+
+static int lcd_enabled;
+static int dvi_enabled;
+
+static void __init omap3_evm_display_init(void)
+{
+	int r;
+
+	r = gpio_request(OMAP3EVM_LCD_PANEL_RESB, "lcd_panel_resb");
+	if (r) {
+		printk(KERN_ERR "failed to get lcd_panel_resb\n");
+		return;
+	}
+	gpio_direction_output(OMAP3EVM_LCD_PANEL_RESB, 1);
+
+	r = gpio_request(OMAP3EVM_LCD_PANEL_INI, "lcd_panel_ini");
+	if (r) {
+		printk(KERN_ERR "failed to get lcd_panel_ini\n");
+		goto err_1;
+	}
+	gpio_direction_output(OMAP3EVM_LCD_PANEL_INI, 1);
+
+	r = gpio_request(OMAP3EVM_LCD_PANEL_QVGA, "lcd_panel_qvga");
+	if (r) {
+		printk(KERN_ERR "failed to get lcd_panel_qvga\n");
+		goto err_2;
+	}
+	gpio_direction_output(OMAP3EVM_LCD_PANEL_QVGA, 0);
+
+	r = gpio_request(OMAP3EVM_LCD_PANEL_LR, "lcd_panel_lr");
+	if (r) {
+		printk(KERN_ERR "failed to get lcd_panel_lr\n");
+		goto err_3;
+	}
+	gpio_direction_output(OMAP3EVM_LCD_PANEL_LR, 1);
+
+	r = gpio_request(OMAP3EVM_LCD_PANEL_UD, "lcd_panel_ud");
+	if (r) {
+		printk(KERN_ERR "failed to get lcd_panel_ud\n");
+		goto err_4;
+	}
+	gpio_direction_output(OMAP3EVM_LCD_PANEL_UD, 1);
+
+	r = gpio_request(OMAP3EVM_LCD_PANEL_ENVDD, "lcd_panel_envdd");
+	if (r) {
+		printk(KERN_ERR "failed to get lcd_panel_envdd\n");
+		goto err_5;
+	}
+	gpio_direction_output(OMAP3EVM_LCD_PANEL_ENVDD, 0);
+
+	return;
+
+err_5:
+	gpio_free(OMAP3EVM_LCD_PANEL_UD);
+err_4:
+	gpio_free(OMAP3EVM_LCD_PANEL_LR);
+err_3:
+	gpio_free(OMAP3EVM_LCD_PANEL_QVGA);
+err_2:
+	gpio_free(OMAP3EVM_LCD_PANEL_INI);
+err_1:
+	gpio_free(OMAP3EVM_LCD_PANEL_RESB);
+
+}
+
+static int omap3_evm_enable_lcd(struct omap_dss_device *dssdev)
+{
+	if (dvi_enabled) {
+		printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+		return -EINVAL;
+	}
+	gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 0);
+
+	if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2)
+		gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0);
+	else
+		gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1);
+
+	lcd_enabled = 1;
+	return 0;
+}
+
+static void omap3_evm_disable_lcd(struct omap_dss_device *dssdev)
+{
+	gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 1);
+
+	if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2)
+		gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1);
+	else
+		gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0);
+
+	lcd_enabled = 0;
+}
+
+static struct omap_dss_device omap3_evm_lcd_device = {
+	.name			= "lcd",
+	.driver_name		= "sharp_ls_panel",
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.phy.dpi.data_lines	= 18,
+	.platform_enable	= omap3_evm_enable_lcd,
+	.platform_disable	= omap3_evm_disable_lcd,
+};
+
+static int omap3_evm_enable_tv(struct omap_dss_device *dssdev)
+{
+	return 0;
+}
+
+static void omap3_evm_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+static struct omap_dss_device omap3_evm_tv_device = {
+	.name			= "tv",
+	.driver_name		= "venc",
+	.type			= OMAP_DISPLAY_TYPE_VENC,
+	.phy.venc.type		= OMAP_DSS_VENC_TYPE_SVIDEO,
+	.platform_enable	= omap3_evm_enable_tv,
+	.platform_disable	= omap3_evm_disable_tv,
+};
+
+static int omap3_evm_enable_dvi(struct omap_dss_device *dssdev)
+{
+	if (lcd_enabled) {
+		printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+		return -EINVAL;
+	}
+
+	gpio_set_value(OMAP3EVM_DVI_PANEL_EN_GPIO, 1);
+
+	dvi_enabled = 1;
+	return 0;
+}
+
+static void omap3_evm_disable_dvi(struct omap_dss_device *dssdev)
+{
+	gpio_set_value(OMAP3EVM_DVI_PANEL_EN_GPIO, 0);
+
+	dvi_enabled = 0;
+}
+
+static struct omap_dss_device omap3_evm_dvi_device = {
+	.name			= "dvi",
+	.driver_name		= "generic_panel",
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.phy.dpi.data_lines	= 24,
+	.platform_enable	= omap3_evm_enable_dvi,
+	.platform_disable	= omap3_evm_disable_dvi,
+};
+
+static struct omap_dss_device *omap3_evm_dss_devices[] = {
+	&omap3_evm_lcd_device,
+	&omap3_evm_tv_device,
+	&omap3_evm_dvi_device,
+};
+
+static struct omap_dss_board_info omap3_evm_dss_data = {
+	.num_devices	= ARRAY_SIZE(omap3_evm_dss_devices),
+	.devices	= omap3_evm_dss_devices,
+	.default_device	= &omap3_evm_lcd_device,
+};
+
+static struct platform_device omap3_evm_dss_device = {
+	.name		= "omapdss",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &omap3_evm_dss_data,
+	},
+};
+
 static struct regulator_consumer_supply omap3evm_vmmc1_supply = {
 	.supply			= "vmmc",
 };
@@ -185,7 +367,7 @@ static struct regulator_init_data omap3e
 	.consumer_supplies	= &omap3evm_vsim_supply,
 };
 
-static struct twl4030_hsmmc_info mmc[] = {
+static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.wires		= 4,
@@ -225,7 +407,7 @@ static int omap3evm_twl_gpio_setup(struc
 	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
 	omap_mux_init_gpio(63, OMAP_PIN_INPUT);
 	mmc[0].gpio_cd = gpio + 0;
-	twl4030_mmc_init(mmc);
+	omap2_hsmmc_init(mmc);
 
 	/* link regulators to MMC adapters */
 	omap3evm_vmmc1_supply.dev = mmc[0].dev;
@@ -236,6 +418,14 @@ static int omap3evm_twl_gpio_setup(struc
 	 * the P2 connector; notably LEDA for the LCD backlight.
 	 */
 
+	/* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */
+	gpio_request(gpio + TWL4030_GPIO_MAX, "EN_LCD_BKL");
+	gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
+
+	/* gpio + 7 == DVI Enable */
+	gpio_request(gpio + 7, "EN_DVI");
+	gpio_direction_output(gpio + 7, 0);
+
 	/* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
 	gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
 
@@ -258,20 +448,23 @@ static struct twl4030_usb_data omap3evm_
 
 static int board_keymap[] = {
 	KEY(0, 0, KEY_LEFT),
-	KEY(0, 1, KEY_RIGHT),
-	KEY(0, 2, KEY_A),
-	KEY(0, 3, KEY_B),
-	KEY(1, 0, KEY_DOWN),
+	KEY(0, 1, KEY_DOWN),
+	KEY(0, 2, KEY_ENTER),
+	KEY(0, 3, KEY_M),
+
+	KEY(1, 0, KEY_RIGHT),
 	KEY(1, 1, KEY_UP),
-	KEY(1, 2, KEY_E),
-	KEY(1, 3, KEY_F),
-	KEY(2, 0, KEY_ENTER),
-	KEY(2, 1, KEY_I),
+	KEY(1, 2, KEY_I),
+	KEY(1, 3, KEY_N),
+
+	KEY(2, 0, KEY_A),
+	KEY(2, 1, KEY_E),
 	KEY(2, 2, KEY_J),
-	KEY(2, 3, KEY_K),
-	KEY(3, 0, KEY_M),
-	KEY(3, 1, KEY_N),
-	KEY(3, 2, KEY_O),
+	KEY(2, 3, KEY_O),
+
+	KEY(3, 0, KEY_B),
+	KEY(3, 1, KEY_F),
+	KEY(3, 2, KEY_K),
 	KEY(3, 3, KEY_P)
 };
 
@@ -300,6 +493,47 @@ static struct twl4030_codec_data omap3ev
 	.audio = &omap3evm_audio_data,
 };
 
+static struct regulator_consumer_supply omap3_evm_vdda_dac_supply = {
+	.supply		= "vdda_dac",
+	.dev		= &omap3_evm_dss_device.dev,
+};
+
+/* VDAC for DSS driving S-Video */
+static struct regulator_init_data omap3_evm_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	= &omap3_evm_vdda_dac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_consumer_supply omap3_evm_vpll2_supply = {
+	.supply		= "vdvi",
+	.dev		= &omap3_evm_lcd_device.dev,
+};
+
+static struct regulator_init_data omap3_evm_vpll2 = {
+	.constraints = {
+		.name			= "VDVI",
+		.min_uV			= 1800000,
+		.max_uV			= 1800000,
+		.apply_uV		= true,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &omap3_evm_vpll2_supply,
+};
+
 static struct twl4030_platform_data omap3evm_twldata = {
 	.irq_base	= TWL4030_IRQ_BASE,
 	.irq_end	= TWL4030_IRQ_END,
@@ -310,6 +544,8 @@ static struct twl4030_platform_data omap
 	.usb		= &omap3evm_usb_data,
 	.gpio		= &omap3evm_gpio_data,
 	.codec		= &omap3evm_codec_data,
+	.vdac		= &omap3_evm_vdac,
+	.vpll2		= &omap3_evm_vpll2,
 };
 
 static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = {
@@ -337,15 +573,6 @@ static int __init omap3_evm_i2c_init(voi
 	return 0;
 }
 
-static struct platform_device omap3_evm_lcd_device = {
-	.name		= "omap3evm_lcd",
-	.id		= -1,
-};
-
-static struct omap_lcd_config omap3_evm_lcd_config __initdata = {
-	.ctrl_name	= "internal",
-};
-
 static void ads7846_dev_init(void)
 {
 	if (gpio_request(OMAP3_EVM_TS_GPIO, "ADS7846 pendown") < 0)
@@ -393,7 +620,6 @@ struct spi_board_info omap3evm_spi_board
 };
 
 static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
-	{ OMAP_TAG_LCD,		&omap3_evm_lcd_config },
 };
 
 static void __init omap3_evm_init_irq(void)
@@ -406,10 +632,10 @@ static void __init omap3_evm_init_irq(vo
 }
 
 static struct platform_device *omap3_evm_devices[] __initdata = {
-	&omap3_evm_lcd_device,
+	&omap3_evm_dss_device,
 };
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = {
 
 	.port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
 	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
@@ -424,12 +650,24 @@ static struct ehci_hcd_omap_platform_dat
 
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux board_mux[] __initdata = {
+	OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
+				OMAP_PIN_OFF_INPUT_PULLUP |
+				OMAP_PIN_OFF_WAKEUPENABLE),
+	OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
+				OMAP_PIN_OFF_INPUT_PULLUP |
+				OMAP_PIN_OFF_WAKEUPENABLE),
 	{ .reg_offset = OMAP_MUX_TERMINATOR },
 };
 #else
 #define board_mux	NULL
 #endif
 
+static struct omap_musb_board_data musb_board_data = {
+	.interface_type		= MUSB_INTERFACE_ULPI,
+	.mode			= MUSB_OTG,
+	.power			= 100,
+};
+
 static void __init omap3_evm_init(void)
 {
 	omap3_evm_get_revision();
@@ -443,10 +681,10 @@ static void __init omap3_evm_init(void)
 				ARRAY_SIZE(omap3evm_spi_board_info));
 
 	omap_serial_init();
-#ifdef CONFIG_NOP_USB_XCEIV
+
 	/* OMAP3EVM uses ISP1504 phy and so register nop transceiver */
 	usb_nop_xceiv_register();
-#endif
+
 	if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) {
 		/* enable EHCI VBUS using GPIO22 */
 		omap_mux_init_gpio(22, OMAP_PIN_INPUT_PULLUP);
@@ -469,16 +707,17 @@ static void __init omap3_evm_init(void)
 		omap_mux_init_gpio(135, OMAP_PIN_OUTPUT);
 		ehci_pdata.reset_gpio_port[1] = 135;
 	}
-	usb_musb_init();
+	usb_musb_init(&musb_board_data);
 	usb_ehci_init(&ehci_pdata);
 	ads7846_dev_init();
 	omap3evm_init_smsc911x();
+	omap3_evm_display_init();
 }
 
 static void __init omap3_evm_map_io(void)
 {
 	omap2_set_globals_343x();
-	omap2_map_common_io();
+	omap34xx_map_common_io();
 }
 
 MACHINE_START(OMAP3EVM, "OMAP3 EVM")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3pandora.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-omap3pandora.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3pandora.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-omap3pandora.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,10 +40,11 @@
 #include <mach/hardware.h>
 #include <plat/mcspi.h>
 #include <plat/usb.h>
+#include <plat/display.h>
 
 #include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
-#include "mmc-twl4030.h"
+#include "hsmmc.h"
 
 #define OMAP3_PANDORA_TS_GPIO		94
 
@@ -192,7 +193,41 @@ static struct twl4030_keypad_data pandor
 	.rep		= 1,
 };
 
-static struct twl4030_hsmmc_info omap3pandora_mmc[] = {
+static struct omap_dss_device pandora_lcd_device = {
+	.name			= "lcd",
+	.driver_name		= "tpo_td043mtea1_panel",
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.phy.dpi.data_lines	= 24,
+	.reset_gpio		= 157,
+};
+
+static struct omap_dss_device pandora_tv_device = {
+	.name			= "tv",
+	.driver_name		= "venc",
+	.type			= OMAP_DISPLAY_TYPE_VENC,
+	.phy.venc.type		= OMAP_DSS_VENC_TYPE_SVIDEO,
+};
+
+static struct omap_dss_device *pandora_dss_devices[] = {
+	&pandora_lcd_device,
+	&pandora_tv_device,
+};
+
+static struct omap_dss_board_info pandora_dss_data = {
+	.num_devices	= ARRAY_SIZE(pandora_dss_devices),
+	.devices	= pandora_dss_devices,
+	.default_device	= &pandora_lcd_device,
+};
+
+static struct platform_device pandora_dss_device = {
+	.name		= "omapdss",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &pandora_dss_data,
+	},
+};
+
+static struct omap2_hsmmc_info omap3pandora_mmc[] = {
 	{
 		.mmc		= 1,
 		.wires		= 4,
@@ -217,25 +252,13 @@ static struct twl4030_hsmmc_info omap3pa
 	{}	/* Terminator */
 };
 
-static struct regulator_consumer_supply pandora_vmmc1_supply = {
-	.supply			= "vmmc",
-};
-
-static struct regulator_consumer_supply pandora_vmmc2_supply = {
-	.supply			= "vmmc",
-};
-
 static int omap3pandora_twl_gpio_setup(struct device *dev,
 		unsigned gpio, unsigned ngpio)
 {
 	/* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */
 	omap3pandora_mmc[0].gpio_cd = gpio + 0;
 	omap3pandora_mmc[1].gpio_cd = gpio + 1;
-	twl4030_mmc_init(omap3pandora_mmc);
-
-	/* link regulators to MMC adapters */
-	pandora_vmmc1_supply.dev = omap3pandora_mmc[0].dev;
-	pandora_vmmc2_supply.dev = omap3pandora_mmc[1].dev;
+	omap2_hsmmc_init(omap3pandora_mmc);
 
 	return 0;
 }
@@ -247,6 +270,36 @@ static struct twl4030_gpio_platform_data
 	.setup		= omap3pandora_twl_gpio_setup,
 };
 
+static struct regulator_consumer_supply pandora_vmmc1_supply =
+	REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.0");
+
+static struct regulator_consumer_supply pandora_vmmc2_supply =
+	REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1");
+
+static struct regulator_consumer_supply pandora_vdda_dac_supply =
+	REGULATOR_SUPPLY("vdda_dac", "omapdss");
+
+static struct regulator_consumer_supply pandora_vdds_supplies[] = {
+	REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+};
+
+static struct regulator_consumer_supply pandora_vcc_lcd_supply =
+	REGULATOR_SUPPLY("vcc", "display0");
+
+static struct regulator_consumer_supply pandora_usb_phy_supply =
+	REGULATOR_SUPPLY("hsusb0", "ehci-omap.0");
+
+/* ads7846 on SPI and 2 nub controllers on I2C */
+static struct regulator_consumer_supply pandora_vaux4_supplies[] = {
+	REGULATOR_SUPPLY("vcc", "spi1.0"),
+	REGULATOR_SUPPLY("vcc", "3-0066"),
+	REGULATOR_SUPPLY("vcc", "3-0067"),
+};
+
+static struct regulator_consumer_supply pandora_adac_supply =
+	REGULATOR_SUPPLY("vcc", "soc-audio");
+
 /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
 static struct regulator_init_data pandora_vmmc1 = {
 	.constraints = {
@@ -277,6 +330,96 @@ static struct regulator_init_data pandor
 	.consumer_supplies	= &pandora_vmmc2_supply,
 };
 
+/* VDAC for DSS driving S-Video */
+static struct regulator_init_data pandora_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	= &pandora_vdda_dac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_init_data pandora_vpll2 = {
+	.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	= ARRAY_SIZE(pandora_vdds_supplies),
+	.consumer_supplies	= pandora_vdds_supplies,
+};
+
+/* VAUX1 for LCD */
+static struct regulator_init_data pandora_vaux1 = {
+	.constraints = {
+		.min_uV			= 3000000,
+		.max_uV			= 3000000,
+		.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	= &pandora_vcc_lcd_supply,
+};
+
+/* VAUX2 for USB host PHY */
+static struct regulator_init_data pandora_vaux2 = {
+	.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	= &pandora_usb_phy_supply,
+};
+
+/* VAUX4 for ads7846 and nubs */
+static struct regulator_init_data pandora_vaux4 = {
+	.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,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(pandora_vaux4_supplies),
+	.consumer_supplies	= pandora_vaux4_supplies,
+};
+
+/* VSIM for audio DAC */
+static struct regulator_init_data pandora_vsim = {
+	.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,
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &pandora_adac_supply,
+};
+
 static struct twl4030_usb_data omap3pandora_usb_data = {
 	.usb_mode	= T2_USB_MODE_ULPI,
 };
@@ -298,6 +441,12 @@ static struct twl4030_platform_data omap
 	.codec		= &omap3pandora_codec_data,
 	.vmmc1		= &pandora_vmmc1,
 	.vmmc2		= &pandora_vmmc2,
+	.vdac		= &pandora_vdac,
+	.vpll2		= &pandora_vpll2,
+	.vaux1		= &pandora_vaux1,
+	.vaux2		= &pandora_vaux2,
+	.vaux4		= &pandora_vaux4,
+	.vsim		= &pandora_vsim,
 	.keypad		= &pandora_kp_data,
 };
 
@@ -310,12 +459,20 @@ static struct i2c_board_info __initdata
 	},
 };
 
+static struct i2c_board_info __initdata omap3pandora_i2c3_boardinfo[] = {
+	{
+		I2C_BOARD_INFO("bq27500", 0x55),
+		.flags = I2C_CLIENT_WAKE,
+	},
+};
+
 static int __init omap3pandora_i2c_init(void)
 {
 	omap_register_i2c_bus(1, 2600, omap3pandora_i2c_boardinfo,
 			ARRAY_SIZE(omap3pandora_i2c_boardinfo));
 	/* i2c2 pins are not connected */
-	omap_register_i2c_bus(3, 100, NULL, 0);
+	omap_register_i2c_bus(3, 100, omap3pandora_i2c3_boardinfo,
+			ARRAY_SIZE(omap3pandora_i2c3_boardinfo));
 	return 0;
 }
 
@@ -365,6 +522,12 @@ static struct spi_board_info omap3pandor
 		.controller_data	= &ads7846_mcspi_config,
 		.irq			= OMAP_GPIO_IRQ(OMAP3_PANDORA_TS_GPIO),
 		.platform_data		= &ads7846_config,
+	}, {
+		.modalias		= "tpo_td043mtea1_panel_spi",
+		.bus_num		= 1,
+		.chip_select		= 1,
+		.max_speed_hz		= 375000,
+		.platform_data		= &pandora_lcd_device,
 	}
 };
 
@@ -379,9 +542,10 @@ static void __init omap3pandora_init_irq
 static struct platform_device *omap3pandora_devices[] __initdata = {
 	&pandora_leds_gpio,
 	&pandora_keys_gpio,
+	&pandora_dss_device,
 };
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 
 	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
 	.port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
@@ -401,6 +565,12 @@ static struct omap_board_mux board_mux[]
 #define board_mux	NULL
 #endif
 
+static struct omap_musb_board_data musb_board_data = {
+	.interface_type		= MUSB_INTERFACE_ULPI,
+	.mode			= MUSB_OTG,
+	.power			= 100,
+};
+
 static void __init omap3pandora_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
@@ -413,7 +583,7 @@ static void __init omap3pandora_init(voi
 	omap3pandora_ads7846_init();
 	usb_ehci_init(&ehci_pdata);
 	pandora_keys_gpio_init();
-	usb_musb_init();
+	usb_musb_init(&musb_board_data);
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
@@ -423,7 +593,7 @@ static void __init omap3pandora_init(voi
 static void __init omap3pandora_map_io(void)
 {
 	omap2_set_globals_343x();
-	omap2_map_common_io();
+	omap34xx_map_common_io();
 }
 
 MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3touchbook.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-omap3touchbook.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3touchbook.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-omap3touchbook.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,7 +50,7 @@
 #include <plat/timer-gp.h>
 
 #include "mux.h"
-#include "mmc-twl4030.h"
+#include "hsmmc.h"
 
 #include <asm/setup.h>
 
@@ -122,7 +122,7 @@ static struct platform_device omap3touch
 
 #include "sdram-micron-mt46h32m32lf-6.h"
 
-static struct twl4030_hsmmc_info mmc[] = {
+static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.wires		= 8,
@@ -161,7 +161,7 @@ static int touchbook_twl_gpio_setup(stru
 	}
 	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
 	mmc[0].gpio_cd = gpio + 0;
-	twl4030_mmc_init(mmc);
+	omap2_hsmmc_init(mmc);
 
 	/* link regulators to MMC adapters */
 	touchbook_vmmc1_supply.dev = mmc[0].dev;
@@ -493,7 +493,7 @@ static void __init omap3touchbook_flash_
 	}
 }
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 
 	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
 	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
@@ -518,14 +518,20 @@ static void omap3_touchbook_poweroff(voi
 	gpio_direction_output(TB_KILL_POWER_GPIO, 0);
 }
 
-static void __init early_touchbook_revision(char **p)
+static int __init early_touchbook_revision(char *p)
 {
-	if (!*p)
-		return;
+	if (!p)
+		return 0;
 
-	strict_strtoul(*p, 10, &touchbook_revision);
+	return strict_strtoul(p, 10, &touchbook_revision);
 }
-__early_param("tbr=", early_touchbook_revision);
+early_param("tbr", early_touchbook_revision);
+
+static struct omap_musb_board_data musb_board_data = {
+	.interface_type		= MUSB_INTERFACE_ULPI,
+	.mode			= MUSB_OTG,
+	.power			= 100,
+};
 
 static void __init omap3_touchbook_init(void)
 {
@@ -545,7 +551,7 @@ static void __init omap3_touchbook_init(
 	spi_register_board_info(omap3_ads7846_spi_board_info,
 				ARRAY_SIZE(omap3_ads7846_spi_board_info));
 	omap3_ads7846_init();
-	usb_musb_init();
+	usb_musb_init(&musb_board_data);
 	usb_ehci_init(&ehci_pdata);
 	omap3touchbook_flash_init();
 
@@ -557,7 +563,7 @@ static void __init omap3_touchbook_init(
 static void __init omap3_touchbook_map_io(void)
 {
 	omap2_set_globals_343x();
-	omap2_map_common_io();
+	omap34xx_map_common_io();
 }
 
 MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-overo.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-overo.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-overo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-overo.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,7 +48,7 @@
 
 #include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
-#include "mmc-twl4030.h"
+#include "hsmmc.h"
 
 #define OVERO_GPIO_BT_XGATE	15
 #define OVERO_GPIO_W2W_NRESET	16
@@ -272,7 +272,7 @@ static void __init overo_flash_init(void
 	}
 }
 
-static struct twl4030_hsmmc_info mmc[] = {
+static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.wires		= 4,
@@ -297,7 +297,7 @@ static struct regulator_consumer_supply
 static int overo_twl_gpio_setup(struct device *dev,
 		unsigned gpio, unsigned ngpio)
 {
-	twl4030_mmc_init(mmc);
+	omap2_hsmmc_init(mmc);
 
 	overo_vmmc1_supply.dev = mmc[0].dev;
 
@@ -394,7 +394,7 @@ static struct platform_device *overo_dev
 	&overo_lcd_device,
 };
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 	.port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
 	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
 	.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
@@ -413,6 +413,12 @@ static struct omap_board_mux board_mux[]
 #define board_mux	NULL
 #endif
 
+static struct omap_musb_board_data musb_board_data = {
+	.interface_type		= MUSB_INTERFACE_ULPI,
+	.mode			= MUSB_OTG,
+	.power			= 100,
+};
+
 static void __init overo_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
@@ -420,7 +426,7 @@ static void __init overo_init(void)
 	platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices));
 	omap_serial_init();
 	overo_flash_init();
-	usb_musb_init();
+	usb_musb_init(&musb_board_data);
 	usb_ehci_init(&ehci_pdata);
 	overo_ads7846_init();
 	overo_init_smsc911x();
@@ -469,7 +475,7 @@ static void __init overo_init(void)
 static void __init overo_map_io(void)
 {
 	omap2_set_globals_343x();
-	omap2_map_common_io();
+	omap34xx_map_common_io();
 }
 
 MACHINE_START(OVERO, "Gumstix Overo")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-rx51.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-rx51.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-rx51.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-rx51.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/leds.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -30,9 +31,49 @@
 #include <plat/usb.h>
 
 #include "mux.h"
+#include "pm.h"
+
+#define RX51_GPIO_SLEEP_IND 162
 
 struct omap_sdrc_params *rx51_get_sdram_timings(void);
 
+static struct gpio_led gpio_leds[] = {
+	{
+		.name	= "sleep_ind",
+		.gpio	= RX51_GPIO_SLEEP_IND,
+	},
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+	.leds		= gpio_leds,
+	.num_leds	= ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &gpio_led_info,
+	},
+};
+
+static struct cpuidle_params rx51_cpuidle_params[] = {
+	/* C1 */
+	{1, 110, 162, 5},
+	/* C2 */
+	{1, 106, 180, 309},
+	/* C3 */
+	{0, 107, 410, 46057},
+	/* C4 */
+	{0, 121, 3374, 46057},
+	/* C5 */
+	{1, 855, 1146, 46057},
+	/* C6 */
+	{0, 7580, 4134, 484329},
+	/* C7 */
+	{1, 7505, 15274, 484329},
+};
+
 static struct omap_lcd_config rx51_lcd_config = {
 	.ctrl_name	= "internal",
 };
@@ -62,6 +103,7 @@ static void __init rx51_init_irq(void)
 
 	omap_board_config = rx51_config;
 	omap_board_config_size = ARRAY_SIZE(rx51_config);
+	omap3_pm_init_cpuidle(rx51_cpuidle_params);
 	sdrc_params = rx51_get_sdram_timings();
 	omap2_init_common_hw(sdrc_params, sdrc_params);
 	omap_init_irq();
@@ -78,22 +120,30 @@ static struct omap_board_mux board_mux[]
 #define board_mux	NULL
 #endif
 
+static struct omap_musb_board_data musb_board_data = {
+	.interface_type		= MUSB_INTERFACE_ULPI,
+	.mode			= MUSB_PERIPHERAL,
+	.power			= 0,
+};
+
 static void __init rx51_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap_serial_init();
-	usb_musb_init();
+	usb_musb_init(&musb_board_data);
 	rx51_peripherals_init();
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
 	omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+
+	platform_device_register(&leds_gpio);
 }
 
 static void __init rx51_map_io(void)
 {
 	omap2_set_globals_343x();
-	omap2_map_common_io();
+	omap34xx_map_common_io();
 }
 
 MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,7 @@
 #include <plat/gpmc-smc91x.h>
 
 #include "mux.h"
-#include "mmc-twl4030.h"
+#include "hsmmc.h"
 
 #define SYSTEM_REV_B_USES_VAUX3	0x1699
 #define SYSTEM_REV_S_USES_VAUX3 0x8
@@ -209,7 +209,47 @@ static struct twl4030_madc_platform_data
 	.irq_line		= 1,
 };
 
-static struct twl4030_hsmmc_info mmc[] = {
+/* Enable input logic and pull all lines up when eMMC is on. */
+static struct omap_board_mux rx51_mmc2_on_mux[] = {
+	OMAP3_MUX(SDMMC2_CMD, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT0, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT1, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT2, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT3, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT4, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT5, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT6, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT7, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/* Disable input logic and pull all lines down when eMMC is off. */
+static struct omap_board_mux rx51_mmc2_off_mux[] = {
+	OMAP3_MUX(SDMMC2_CMD, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT0, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT1, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT2, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT3, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT4, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT5, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT6, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+	OMAP3_MUX(SDMMC2_DAT7, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/*
+ * Current flows to eMMC when eMMC is off and the data lines are pulled up,
+ * so pull them down. N.B. we pull 8 lines because we are using 8 lines.
+ */
+static void rx51_mmc2_remux(struct device *dev, int slot, int power_on)
+{
+	if (power_on)
+		omap_mux_write_array(rx51_mmc2_on_mux);
+	else
+		omap_mux_write_array(rx51_mmc2_off_mux);
+}
+
+static struct omap2_hsmmc_info mmc[] __initdata = {
 	{
 		.name		= "external",
 		.mmc		= 1,
@@ -222,25 +262,29 @@ static struct twl4030_hsmmc_info mmc[] =
 	{
 		.name		= "internal",
 		.mmc		= 2,
-		.wires		= 8,
+		.wires		= 8, /* See also rx51_mmc2_remux */
 		.gpio_cd	= -EINVAL,
 		.gpio_wp	= -EINVAL,
 		.nonremovable	= true,
 		.power_saving	= true,
+		.remux		= rx51_mmc2_remux,
 	},
 	{}	/* Terminator */
 };
 
 static struct regulator_consumer_supply rx51_vmmc1_supply = {
-	.supply			= "vmmc",
+	.supply   = "vmmc",
+	.dev_name = "mmci-omap-hs.0",
 };
 
 static struct regulator_consumer_supply rx51_vmmc2_supply = {
-	.supply			= "vmmc",
+	.supply   = "vmmc",
+	.dev_name = "mmci-omap-hs.1",
 };
 
 static struct regulator_consumer_supply rx51_vsim_supply = {
-	.supply			= "vmmc_aux",
+	.supply   = "vmmc_aux",
+	.dev_name = "mmci-omap-hs.1",
 };
 
 static struct regulator_init_data rx51_vaux1 = {
@@ -375,12 +419,6 @@ static int rx51_twlgpio_setup(struct dev
 	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;
 }
 
@@ -751,5 +789,6 @@ void __init rx51_peripherals_init(void)
 	rx51_init_wl1251();
 	spi_register_board_info(rx51_peripherals_spi_board_info,
 				ARRAY_SIZE(rx51_peripherals_spi_board_info));
+	omap2_hsmmc_init(mmc);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-sdp-flash.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-sdp-flash.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-sdp-flash.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-sdp-flash.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,272 @@
+/*
+ * board-sdp-flash.c
+ * Modified from mach-omap2/board-3430sdp-flash.c
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * Vimal Singh <vimalsingh@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+
+#include <plat/gpmc.h>
+#include <plat/nand.h>
+#include <plat/onenand.h>
+#include <plat/tc.h>
+#include <mach/board-sdp.h>
+
+#define REG_FPGA_REV			0x10
+#define REG_FPGA_DIP_SWITCH_INPUT2	0x60
+#define MAX_SUPPORTED_GPMC_CONFIG	3
+
+#define DEBUG_BASE		0x08000000 /* debug board */
+
+#define PDC_NOR		1
+#define PDC_NAND	2
+#define PDC_ONENAND	3
+#define DBG_MPDB	4
+
+/* various memory sizes */
+#define FLASH_SIZE_SDPV1	SZ_64M	/* NOR flash (64 Meg aligned) */
+#define FLASH_SIZE_SDPV2	SZ_128M	/* NOR flash (256 Meg aligned) */
+
+/*
+ * SDP3430 V2 Board CS organization
+ * Different from SDP3430 V1. Now 4 switches used to specify CS
+ *
+ * See also the Switch S8 settings in the comments.
+ *
+ * REVISIT: Add support for 2430 SDP
+ */
+static const unsigned char chip_sel_sdp[][GPMC_CS_NUM] = {
+	{PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0}, /* S8:1111 */
+	{PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1110 */
+	{PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1101 */
+};
+
+static struct physmap_flash_data sdp_nor_data = {
+	.width		= 2,
+};
+
+static struct resource sdp_nor_resource = {
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device sdp_nor_device = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+			.platform_data = &sdp_nor_data,
+	},
+	.num_resources	= 1,
+	.resource	= &sdp_nor_resource,
+};
+
+static void
+__init board_nor_init(struct flash_partitions sdp_nor_parts, u8 cs)
+{
+	int err;
+
+	sdp_nor_data.parts	= sdp_nor_parts.parts;
+	sdp_nor_data.nr_parts	= sdp_nor_parts.nr_parts;
+
+	/* Configure start address and size of NOR device */
+	if (omap_rev() >= OMAP3430_REV_ES1_0) {
+		err = gpmc_cs_request(cs, FLASH_SIZE_SDPV2 - 1,
+				(unsigned long *)&sdp_nor_resource.start);
+		sdp_nor_resource.end = sdp_nor_resource.start
+					+ FLASH_SIZE_SDPV2 - 1;
+	} else {
+		err = gpmc_cs_request(cs, FLASH_SIZE_SDPV1 - 1,
+				(unsigned long *)&sdp_nor_resource.start);
+		sdp_nor_resource.end = sdp_nor_resource.start
+					+ FLASH_SIZE_SDPV1 - 1;
+	}
+	if (err < 0) {
+		printk(KERN_ERR "NOR: Can't request GPMC CS\n");
+		return;
+	}
+	if (platform_device_register(&sdp_nor_device) < 0)
+		printk(KERN_ERR	"Unable to register NOR device\n");
+}
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+		defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+static struct omap_onenand_platform_data board_onenand_data = {
+	.dma_channel	= -1,   /* disable DMA in OMAP OneNAND driver */
+};
+
+static void
+__init board_onenand_init(struct flash_partitions sdp_onenand_parts, u8 cs)
+{
+	board_onenand_data.cs		= cs;
+	board_onenand_data.parts	= sdp_onenand_parts.parts;
+	board_onenand_data.nr_parts	= sdp_onenand_parts.nr_parts;
+
+	gpmc_onenand_init(&board_onenand_data);
+}
+#else
+static void
+__init board_onenand_init(struct flash_partitions sdp_onenand_parts, u8 cs)
+{
+}
+#endif /* CONFIG_MTD_ONENAND_OMAP2 || CONFIG_MTD_ONENAND_OMAP2_MODULE */
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || \
+		defined(CONFIG_MTD_NAND_OMAP2_MODULE)
+
+/* Note that all values in this struct are in nanoseconds */
+static struct gpmc_timings nand_timings = {
+
+	.sync_clk = 0,
+
+	.cs_on = 0,
+	.cs_rd_off = 36,
+	.cs_wr_off = 36,
+
+	.adv_on = 6,
+	.adv_rd_off = 24,
+	.adv_wr_off = 36,
+
+	.we_off = 30,
+	.oe_off = 48,
+
+	.access = 54,
+	.rd_cycle = 72,
+	.wr_cycle = 72,
+
+	.wr_access = 30,
+	.wr_data_mux_bus = 0,
+};
+
+static struct omap_nand_platform_data sdp_nand_data = {
+	.nand_setup	= NULL,
+	.gpmc_t		= &nand_timings,
+	.dma_channel	= -1,		/* disable DMA in OMAP NAND driver */
+	.dev_ready	= NULL,
+	.devsize	= 0,	/* '0' for 8-bit, '1' for 16-bit device */
+};
+
+static void
+__init board_nand_init(struct flash_partitions sdp_nand_parts, u8 cs)
+{
+	sdp_nand_data.cs		= cs;
+	sdp_nand_data.parts		= sdp_nand_parts.parts;
+	sdp_nand_data.nr_parts		= sdp_nand_parts.nr_parts;
+
+	sdp_nand_data.gpmc_cs_baseaddr	= (void *)(OMAP34XX_GPMC_VIRT +
+							GPMC_CS0_BASE +
+							cs * GPMC_CS_SIZE);
+	sdp_nand_data.gpmc_baseaddr	 = (void *) (OMAP34XX_GPMC_VIRT);
+
+	gpmc_nand_init(&sdp_nand_data);
+}
+#else
+static void
+__init board_nand_init(struct flash_partitions sdp_nand_parts, u8 cs)
+{
+}
+#endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */
+
+/**
+ * get_gpmc0_type - Reads the FPGA DIP_SWITCH_INPUT_REGISTER2 to get
+ * the various cs values.
+ */
+static u8 get_gpmc0_type(void)
+{
+	u8 cs = 0;
+	void __iomem *fpga_map_addr;
+
+	fpga_map_addr = ioremap(DEBUG_BASE, 4096);
+	if (!fpga_map_addr)
+		return -ENOMEM;
+
+	if (!(__raw_readw(fpga_map_addr + REG_FPGA_REV)))
+		/* we dont have an DEBUG FPGA??? */
+		/* Depend on #defines!! default to strata boot return param */
+		goto unmap;
+
+	/* S8-DIP-OFF = 1, S8-DIP-ON = 0 */
+	cs = __raw_readw(fpga_map_addr + REG_FPGA_DIP_SWITCH_INPUT2) & 0xf;
+
+	/* ES2.0 SDP's onwards 4 dip switches are provided for CS */
+	if (omap_rev() >= OMAP3430_REV_ES1_0)
+		/* change (S8-1:4=DS-2:0) to (S8-4:1=DS-2:0) */
+		cs = ((cs & 8) >> 3) | ((cs & 4) >> 1) |
+			((cs & 2) << 1) | ((cs & 1) << 3);
+	else
+		/* change (S8-1:3=DS-2:0) to (S8-3:1=DS-2:0) */
+		cs = ((cs & 4) >> 2) | (cs & 2) | ((cs & 1) << 2);
+unmap:
+	iounmap(fpga_map_addr);
+	return cs;
+}
+
+/**
+ * sdp3430_flash_init - Identify devices connected to GPMC and register.
+ *
+ * @return - void.
+ */
+void __init sdp_flash_init(struct flash_partitions sdp_partition_info[])
+{
+	u8		cs = 0;
+	u8		norcs = GPMC_CS_NUM + 1;
+	u8		nandcs = GPMC_CS_NUM + 1;
+	u8		onenandcs = GPMC_CS_NUM + 1;
+	u8		idx;
+	unsigned char	*config_sel = NULL;
+
+	/* REVISIT: Is this return correct idx for 2430 SDP?
+	 * for which cs configuration matches for 2430 SDP?
+	 */
+	idx = get_gpmc0_type();
+	if (idx >= MAX_SUPPORTED_GPMC_CONFIG) {
+		printk(KERN_ERR "%s: Invalid chip select: %d\n", __func__, cs);
+		return;
+	}
+	config_sel = (unsigned char *)(chip_sel_sdp[idx]);
+
+	while (cs < GPMC_CS_NUM) {
+		switch (config_sel[cs]) {
+		case PDC_NOR:
+			if (norcs > GPMC_CS_NUM)
+				norcs = cs;
+			break;
+		case PDC_NAND:
+			if (nandcs > GPMC_CS_NUM)
+				nandcs = cs;
+			break;
+		case PDC_ONENAND:
+			if (onenandcs > GPMC_CS_NUM)
+				onenandcs = cs;
+			break;
+		};
+		cs++;
+	}
+
+	if (norcs > GPMC_CS_NUM)
+		printk(KERN_INFO "NOR: Unable to find configuration "
+				"in GPMC\n");
+	else
+		board_nor_init(sdp_partition_info[0], norcs);
+
+	if (onenandcs > GPMC_CS_NUM)
+		printk(KERN_INFO "OneNAND: Unable to find configuration "
+				"in GPMC\n");
+	else
+		board_onenand_init(sdp_partition_info[1], onenandcs);
+
+	if (nandcs > GPMC_CS_NUM)
+		printk(KERN_INFO "NAND: Unable to find configuration "
+				"in GPMC\n");
+	else
+		board_nand_init(sdp_partition_info[2], nandcs);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom2.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-zoom2.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-zoom2.c	2010-05-16 17:17:36.000000000 -0400
@@ -87,7 +87,7 @@ static void __init omap_zoom2_init(void)
 static void __init omap_zoom2_map_io(void)
 {
 	omap2_set_globals_343x();
-	omap2_map_common_io();
+	omap34xx_map_common_io();
 }
 
 MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom3.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-zoom3.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-zoom3.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,14 +20,15 @@
 
 #include <plat/common.h>
 #include <plat/board.h>
+#include <plat/usb.h>
 
 #include "mux.h"
 #include "sdram-hynix-h8mbx00u0mer-0em.h"
 
 static void __init omap_zoom_map_io(void)
 {
-	omap2_set_globals_343x();
-	omap2_map_common_io();
+	omap2_set_globals_36xx();
+	omap34xx_map_common_io();
 }
 
 static struct omap_board_config_kernel zoom_config[] __initdata = {
@@ -51,11 +52,24 @@ static struct omap_board_mux board_mux[]
 #define board_mux	NULL
 #endif
 
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+	.port_mode[0]		= EHCI_HCD_OMAP_MODE_UNKNOWN,
+	.port_mode[1]		= EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[2]		= EHCI_HCD_OMAP_MODE_UNKNOWN,
+	.phy_reset		= true,
+	.reset_gpio_port[0]	= -EINVAL,
+	.reset_gpio_port[1]	= 64,
+	.reset_gpio_port[2]	= -EINVAL,
+};
+
 static void __init omap_zoom_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
 	zoom_peripherals_init();
 	zoom_debugboard_init();
+
+	omap_mux_init_gpio(64, OMAP_PIN_OUTPUT);
+	usb_ehci_init(&ehci_pdata);
 }
 
 MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom-debugboard.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-zoom-debugboard.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom-debugboard.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-zoom-debugboard.c	2010-05-16 17:17:36.000000000 -0400
@@ -96,7 +96,7 @@ static struct plat_serial8250_port seria
 
 static struct platform_device zoom_debugboard_serial_device = {
 	.name			= "serial8250",
-	.id			= 3,
+	.id			= PLAT8250_DEV_PLATFORM,
 	.dev			= {
 		.platform_data	= serial_platform_data,
 	},
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom-peripherals.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-zoom-peripherals.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom-peripherals.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-zoom-peripherals.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,8 @@
 #include <plat/common.h>
 #include <plat/usb.h>
 
-#include "mmc-twl4030.h"
+#include "mux.h"
+#include "hsmmc.h"
 
 /* Zoom2 has Qwerty keyboard*/
 static int board_keymap[] = {
@@ -150,7 +151,7 @@ static struct regulator_init_data zoom_v
 	.consumer_supplies      = &zoom_vsim_supply,
 };
 
-static struct twl4030_hsmmc_info mmc[] __initdata = {
+static struct omap2_hsmmc_info mmc[] __initdata = {
 	{
 		.name		= "external",
 		.mmc		= 1,
@@ -175,7 +176,7 @@ static int zoom_twl_gpio_setup(struct de
 {
 	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
 	mmc[0].gpio_cd = gpio + 0;
-	twl4030_mmc_init(mmc);
+	omap2_hsmmc_init(mmc);
 
 	/* link regulators to MMC adapters ... we "know" the
 	 * regulators will be set up only *after* we return.
@@ -263,9 +264,22 @@ static int __init omap_i2c_init(void)
 	return 0;
 }
 
+static struct omap_musb_board_data musb_board_data = {
+	.interface_type		= MUSB_INTERFACE_ULPI,
+	.mode			= MUSB_OTG,
+	.power			= 100,
+};
+
+static void enable_board_wakeup_source(void)
+{
+	/* T2 interrupt line (keypad) */
+	omap_mux_init_signal("sys_nirq",
+		OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
+}
+
 void __init zoom_peripherals_init(void)
 {
 	omap_i2c_init();
-	omap_serial_init();
-	usb_musb_init();
+	usb_musb_init(&musb_board_data);
+	enable_board_wakeup_source();
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt2xxx_apll.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt2xxx_apll.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt2xxx_apll.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt2xxx_apll.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,122 @@
+/*
+ * OMAP2xxx APLL clock control functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/prcm.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+
+/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
+#define EN_APLL_STOPPED			0
+#define EN_APLL_LOCKED			3
+
+/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
+#define APLLS_CLKIN_19_2MHZ		0
+#define APLLS_CLKIN_13MHZ		2
+#define APLLS_CLKIN_12MHZ		3
+
+void __iomem *cm_idlest_pll;
+
+/* Private functions */
+
+/* Enable an APLL if off */
+static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
+{
+	u32 cval, apll_mask;
+
+	apll_mask = EN_APLL_LOCKED << clk->enable_bit;
+
+	cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+
+	if ((cval & apll_mask) == apll_mask)
+		return 0;   /* apll already enabled */
+
+	cval &= ~apll_mask;
+	cval |= apll_mask;
+	cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
+
+	omap2_cm_wait_idlest(cm_idlest_pll, status_mask,
+			     OMAP24XX_CM_IDLEST_VAL, clk->name);
+
+	/*
+	 * REVISIT: Should we return an error code if omap2_wait_clock_ready()
+	 * fails?
+	 */
+	return 0;
+}
+
+static int omap2_clk_apll96_enable(struct clk *clk)
+{
+	return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL);
+}
+
+static int omap2_clk_apll54_enable(struct clk *clk)
+{
+	return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL);
+}
+
+/* Stop APLL */
+static void omap2_clk_apll_disable(struct clk *clk)
+{
+	u32 cval;
+
+	cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+	cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
+	cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
+}
+
+/* Public data */
+
+const struct clkops clkops_apll96 = {
+	.enable		= omap2_clk_apll96_enable,
+	.disable	= omap2_clk_apll_disable,
+};
+
+const struct clkops clkops_apll54 = {
+	.enable		= omap2_clk_apll54_enable,
+	.disable	= omap2_clk_apll_disable,
+};
+
+/* Public functions */
+
+u32 omap2xxx_get_apll_clkin(void)
+{
+	u32 aplls, srate = 0;
+
+	aplls = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
+	aplls &= OMAP24XX_APLLS_CLKIN_MASK;
+	aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
+
+	if (aplls == APLLS_CLKIN_19_2MHZ)
+		srate = 19200000;
+	else if (aplls == APLLS_CLKIN_13MHZ)
+		srate = 13000000;
+	else if (aplls == APLLS_CLKIN_12MHZ)
+		srate = 12000000;
+
+	return srate;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt2xxx_dpllcore.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt2xxx_dpllcore.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt2xxx_dpllcore.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,173 @@
+/*
+ * DPLL + CORE_CLK composite clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX The DPLL and CORE clocks should be split into two separate clock
+ * types.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/sdrc.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+
+/* #define DOWN_VARIABLE_DPLL 1 */		/* Experimental */
+
+/**
+ * omap2xxx_clk_get_core_rate - return the CORE_CLK rate
+ * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
+ *
+ * Returns the CORE_CLK rate.  CORE_CLK can have one of three rate
+ * sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
+ * (the latter is unusual).  This currently should be called with
+ * struct clk *dpll_ck, which is a composite clock of dpll_ck and
+ * core_ck.
+ */
+unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
+{
+	long long core_clk;
+	u32 v;
+
+	core_clk = omap2_get_dpll_rate(clk);
+
+	v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+	v &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+	if (v == CORE_CLK_SRC_32K)
+		core_clk = 32768;
+	else
+		core_clk *= v;
+
+	return core_clk;
+}
+
+/*
+ * Uses the current prcm set to tell if a rate is valid.
+ * You can go slower, but not faster within a given rate set.
+ */
+static long omap2_dpllcore_round_rate(unsigned long target_rate)
+{
+	u32 high, low, core_clk_src;
+
+	core_clk_src = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+	core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+	if (core_clk_src == CORE_CLK_SRC_DPLL) {	/* DPLL clockout */
+		high = curr_prcm_set->dpll_speed * 2;
+		low = curr_prcm_set->dpll_speed;
+	} else {				/* DPLL clockout x 2 */
+		high = curr_prcm_set->dpll_speed;
+		low = curr_prcm_set->dpll_speed / 2;
+	}
+
+#ifdef DOWN_VARIABLE_DPLL
+	if (target_rate > high)
+		return high;
+	else
+		return target_rate;
+#else
+	if (target_rate > low)
+		return high;
+	else
+		return low;
+#endif
+
+}
+
+unsigned long omap2_dpllcore_recalc(struct clk *clk)
+{
+	return omap2xxx_clk_get_core_rate(clk);
+}
+
+int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
+{
+	u32 cur_rate, low, mult, div, valid_rate, done_rate;
+	u32 bypass = 0;
+	struct prcm_config tmpset;
+	const struct dpll_data *dd;
+
+	cur_rate = omap2xxx_clk_get_core_rate(dclk);
+	mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+	mult &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+	if ((rate == (cur_rate / 2)) && (mult == 2)) {
+		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
+	} else if ((rate == (cur_rate * 2)) && (mult == 1)) {
+		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+	} else if (rate != cur_rate) {
+		valid_rate = omap2_dpllcore_round_rate(rate);
+		if (valid_rate != rate)
+			return -EINVAL;
+
+		if (mult == 1)
+			low = curr_prcm_set->dpll_speed;
+		else
+			low = curr_prcm_set->dpll_speed / 2;
+
+		dd = clk->dpll_data;
+		if (!dd)
+			return -EINVAL;
+
+		tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg);
+		tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
+					   dd->div1_mask);
+		div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
+		tmpset.cm_clksel2_pll = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+		tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
+		if (rate > low) {
+			tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
+			mult = ((rate / 2) / 1000000);
+			done_rate = CORE_CLK_SRC_DPLL_X2;
+		} else {
+			tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL;
+			mult = (rate / 1000000);
+			done_rate = CORE_CLK_SRC_DPLL;
+		}
+		tmpset.cm_clksel1_pll |= (div << __ffs(dd->mult_mask));
+		tmpset.cm_clksel1_pll |= (mult << __ffs(dd->div1_mask));
+
+		/* Worst case */
+		tmpset.base_sdrc_rfr = SDRC_RFR_CTRL_BYPASS;
+
+		if (rate == curr_prcm_set->xtal_speed)	/* If asking for 1-1 */
+			bypass = 1;
+
+		/* For omap2xxx_sdrc_init_params() */
+		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+
+		/* Force dll lock mode */
+		omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
+			       bypass);
+
+		/* Errata: ret dll entry state */
+		omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
+		omap2xxx_sdrc_reprogram(done_rate, 0);
+	}
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt2xxx_osc.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt2xxx_osc.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt2xxx_osc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt2xxx_osc.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,62 @@
+/*
+ * OMAP2xxx osc_clk-specific clock code
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "prm.h"
+#include "prm-regbits-24xx.h"
+
+static int omap2_enable_osc_ck(struct clk *clk)
+{
+	u32 pcc;
+
+	pcc = __raw_readl(prcm_clksrc_ctrl);
+
+	__raw_writel(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
+
+	return 0;
+}
+
+static void omap2_disable_osc_ck(struct clk *clk)
+{
+	u32 pcc;
+
+	pcc = __raw_readl(prcm_clksrc_ctrl);
+
+	__raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
+}
+
+const struct clkops clkops_oscck = {
+	.enable		= omap2_enable_osc_ck,
+	.disable	= omap2_disable_osc_ck,
+};
+
+unsigned long omap2_osc_clk_recalc(struct clk *clk)
+{
+	return omap2xxx_get_apll_clkin() * omap2xxx_get_sysclkdiv();
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt2xxx_sys.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt2xxx_sys.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt2xxx_sys.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt2xxx_sys.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,50 @@
+/*
+ * OMAP2xxx sys_clk-specific clock code
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "prm.h"
+#include "prm-regbits-24xx.h"
+
+void __iomem *prcm_clksrc_ctrl;
+
+u32 omap2xxx_get_sysclkdiv(void)
+{
+	u32 div;
+
+	div = __raw_readl(prcm_clksrc_ctrl);
+	div &= OMAP_SYSCLKDIV_MASK;
+	div >>= OMAP_SYSCLKDIV_SHIFT;
+
+	return div;
+}
+
+unsigned long omap2xxx_sys_clk_recalc(struct clk *clk)
+{
+	return clk->parent->rate / omap2xxx_get_sysclkdiv();
+}
+
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,255 @@
+/*
+ * OMAP2xxx DVFS virtual clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX Some of this code should be replaceable by the upcoming OPP layer
+ * code.  However, some notion of "rate set" is probably still necessary
+ * for OMAP2xxx at least.  Rate sets should be generalized so they can be
+ * used for any OMAP chip, not just OMAP2xxx.  In particular, Richard Woodruff
+ * has in the past expressed a preference to use rate sets for OPP changes,
+ * rather than dynamically recalculating the clock tree, so if someone wants
+ * this badly enough to write the code to handle it, we should support it
+ * as an option.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/cpufreq.h>
+#include <linux/slab.h>
+
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/sdrc.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+
+const struct prcm_config *curr_prcm_set;
+const struct prcm_config *rate_table;
+
+/**
+ * omap2_table_mpu_recalc - just return the MPU speed
+ * @clk: virt_prcm_set struct clk
+ *
+ * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
+ */
+unsigned long omap2_table_mpu_recalc(struct clk *clk)
+{
+	return curr_prcm_set->mpu_speed;
+}
+
+/*
+ * Look for a rate equal or less than the target rate given a configuration set.
+ *
+ * What's not entirely clear is "which" field represents the key field.
+ * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
+ * just uses the ARM rates.
+ */
+long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
+{
+	const struct prcm_config *ptr;
+	long highest_rate;
+	long sys_ck_rate;
+
+	sys_ck_rate = clk_get_rate(sclk);
+
+	highest_rate = -EINVAL;
+
+	for (ptr = rate_table; ptr->mpu_speed; ptr++) {
+		if (!(ptr->flags & cpu_mask))
+			continue;
+		if (ptr->xtal_speed != sys_ck_rate)
+			continue;
+
+		highest_rate = ptr->mpu_speed;
+
+		/* Can check only after xtal frequency check */
+		if (ptr->mpu_speed <= rate)
+			break;
+	}
+	return highest_rate;
+}
+
+/* Sets basic clocks based on the specified rate */
+int omap2_select_table_rate(struct clk *clk, unsigned long rate)
+{
+	u32 cur_rate, done_rate, bypass = 0, tmp;
+	const struct prcm_config *prcm;
+	unsigned long found_speed = 0;
+	unsigned long flags;
+	long sys_ck_rate;
+
+	sys_ck_rate = clk_get_rate(sclk);
+
+	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+		if (!(prcm->flags & cpu_mask))
+			continue;
+
+		if (prcm->xtal_speed != sys_ck_rate)
+			continue;
+
+		if (prcm->mpu_speed <= rate) {
+			found_speed = prcm->mpu_speed;
+			break;
+		}
+	}
+
+	if (!found_speed) {
+		printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
+		       rate / 1000000);
+		return -EINVAL;
+	}
+
+	curr_prcm_set = prcm;
+	cur_rate = omap2xxx_clk_get_core_rate(dclk);
+
+	if (prcm->dpll_speed == cur_rate / 2) {
+		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
+	} else if (prcm->dpll_speed == cur_rate * 2) {
+		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+	} else if (prcm->dpll_speed != cur_rate) {
+		local_irq_save(flags);
+
+		if (prcm->dpll_speed == prcm->xtal_speed)
+			bypass = 1;
+
+		if ((prcm->cm_clksel2_pll & OMAP24XX_CORE_CLK_SRC_MASK) ==
+		    CORE_CLK_SRC_DPLL_X2)
+			done_rate = CORE_CLK_SRC_DPLL_X2;
+		else
+			done_rate = CORE_CLK_SRC_DPLL;
+
+		/* MPU divider */
+		cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);
+
+		/* dsp + iva1 div(2420), iva2.1(2430) */
+		cm_write_mod_reg(prcm->cm_clksel_dsp,
+				 OMAP24XX_DSP_MOD, CM_CLKSEL);
+
+		cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);
+
+		/* Major subsystem dividers */
+		tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
+		cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
+				 CM_CLKSEL1);
+
+		if (cpu_is_omap2430())
+			cm_write_mod_reg(prcm->cm_clksel_mdm,
+					 OMAP2430_MDM_MOD, CM_CLKSEL);
+
+		/* x2 to enter omap2xxx_sdrc_init_params() */
+		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+
+		omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
+			       bypass);
+
+		omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
+		omap2xxx_sdrc_reprogram(done_rate, 0);
+
+		local_irq_restore(flags);
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_CPU_FREQ
+/*
+ * Walk PRCM rate table and fillout cpufreq freq_table
+ * XXX This should be replaced by an OPP layer in the near future
+ */
+static struct cpufreq_frequency_table *freq_table;
+
+void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
+{
+	const struct prcm_config *prcm;
+	long sys_ck_rate;
+	int i = 0;
+	int tbl_sz = 0;
+
+	if (!cpu_is_omap24xx())
+		return;
+
+	sys_ck_rate = clk_get_rate(sclk);
+
+	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+		if (!(prcm->flags & cpu_mask))
+			continue;
+		if (prcm->xtal_speed != sys_ck_rate)
+			continue;
+
+		/* don't put bypass rates in table */
+		if (prcm->dpll_speed == prcm->xtal_speed)
+			continue;
+
+		tbl_sz++;
+	}
+
+	/*
+	 * XXX Ensure that we're doing what CPUFreq expects for this error
+	 * case and the following one
+	 */
+	if (tbl_sz == 0) {
+		pr_warning("%s: no matching entries in rate_table\n",
+			   __func__);
+		return;
+	}
+
+	/* Include the CPUFREQ_TABLE_END terminator entry */
+	tbl_sz++;
+
+	freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz,
+			     GFP_ATOMIC);
+	if (!freq_table) {
+		pr_err("%s: could not kzalloc frequency table\n", __func__);
+		return;
+	}
+
+	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+		if (!(prcm->flags & cpu_mask))
+			continue;
+		if (prcm->xtal_speed != sys_ck_rate)
+			continue;
+
+		/* don't put bypass rates in table */
+		if (prcm->dpll_speed == prcm->xtal_speed)
+			continue;
+
+		freq_table[i].index = i;
+		freq_table[i].frequency = prcm->mpu_speed / 1000;
+		i++;
+	}
+
+	freq_table[i].index = i;
+	freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+	*table = &freq_table[0];
+}
+
+void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
+{
+	if (!cpu_is_omap24xx())
+		return;
+
+	kfree(freq_table);
+}
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt34xx_dpll3m2.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt34xx_dpll3m2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt34xx_dpll3m2.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,121 @@
+/*
+ * OMAP34xx M2 divider clock code
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ *
+ * Paul Walmsley
+ * Jouni HÃ¶gander
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/sdrc.h>
+
+#include "clock.h"
+#include "clock3xxx.h"
+#include "clock34xx.h"
+#include "sdrc.h"
+
+#define CYCLES_PER_MHZ			1000000
+
+/*
+ * CORE DPLL (DPLL3) M2 divider 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.
+ */
+int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 new_div = 0;
+	u32 unlock_dll = 0;
+	u32 c;
+	unsigned long validrate, sdrcrate, _mpurate;
+	struct omap_sdrc_params *sdrc_cs0;
+	struct omap_sdrc_params *sdrc_cs1;
+	int ret;
+
+	if (!clk || !rate)
+		return -EINVAL;
+
+	validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
+	if (validrate != rate)
+		return -EINVAL;
+
+	sdrcrate = sdrc_ick_p->rate;
+	if (rate > clk->rate)
+		sdrcrate <<= ((rate / clk->rate) >> 1);
+	else
+		sdrcrate >>= ((clk->rate / rate) >> 1);
+
+	ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1);
+	if (ret)
+		return -EINVAL;
+
+	if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
+		pr_debug("clock: will unlock SDRC DLL\n");
+		unlock_dll = 1;
+	}
+
+	/*
+	 * XXX This only needs to be done when the CPU frequency changes
+	 */
+	_mpurate = arm_fck_p->rate / CYCLES_PER_MHZ;
+	c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
+	c += 1;  /* for safety */
+	c *= SDRC_MPURATE_LOOPS;
+	c >>= SDRC_MPURATE_SCALE;
+	if (c == 0)
+		c = 1;
+
+	pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
+		 validrate);
+	pr_debug("clock: SDRC CS0 timing params used:"
+		 " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
+		 sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+		 sdrc_cs0->actim_ctrlb, sdrc_cs0->mr);
+	if (sdrc_cs1)
+		pr_debug("clock: SDRC CS1 timing params used: "
+		 " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
+		 sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
+		 sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
+
+	if (sdrc_cs1)
+		omap3_configure_core_dpll(
+				  new_div, unlock_dll, c, rate > clk->rate,
+				  sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+				  sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
+				  sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
+				  sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
+	else
+		omap3_configure_core_dpll(
+				  new_div, unlock_dll, c, rate > clk->rate,
+				  sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+				  sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
+				  0, 0, 0, 0);
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt_clksel.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt_clksel.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt_clksel.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt_clksel.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,409 @@
+/*
+ * clkt_clksel.c - OMAP2/3/4 clksel clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX At some point these clksel clocks should be split into
+ * "divider" clocks and "mux" clocks to better match the hardware.
+ *
+ * XXX Currently these clocks are only used in the OMAP2/3/4 code, but
+ * many of the OMAP1 clocks should be convertible to use this
+ * mechanism.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+
+/* Private functions */
+
+/**
+ * _omap2_get_clksel_by_parent - return clksel struct for a given clk & parent
+ * @clk: OMAP struct clk ptr to inspect
+ * @src_clk: OMAP struct clk ptr of the parent clk to search for
+ *
+ * Scan the struct clksel array associated with the clock to find
+ * the element associated with the supplied parent clock address.
+ * Returns a pointer to the struct clksel on success or NULL on error.
+ */
+static const struct clksel *_omap2_get_clksel_by_parent(struct clk *clk,
+							struct clk *src_clk)
+{
+	const struct clksel *clks;
+
+	if (!clk->clksel)
+		return NULL;
+
+	for (clks = clk->clksel; clks->parent; clks++) {
+		if (clks->parent == src_clk)
+			break; /* Found the requested parent */
+	}
+
+	if (!clks->parent) {
+		printk(KERN_ERR "clock: Could not find parent clock %s in "
+		       "clksel array of clock %s\n", src_clk->name,
+		       clk->name);
+		return NULL;
+	}
+
+	return clks;
+}
+
+/*
+ * Converts encoded control register address into a full address
+ * On error, the return value (parent_div) will be 0.
+ */
+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;
+
+	clks = _omap2_get_clksel_by_parent(clk, src_clk);
+	if (!clks)
+		return 0;
+
+	for (clkr = clks->rates; clkr->div; clkr++) {
+		if (clkr->flags & cpu_mask && clkr->flags & DEFAULT_RATE)
+			break; /* Found the default rate for this platform */
+	}
+
+	if (!clkr->div) {
+		printk(KERN_ERR "clock: Could not find default rate for "
+		       "clock %s parent %s\n", clk->name,
+		       src_clk->parent->name);
+		return 0;
+	}
+
+	/* Should never happen.  Add a clksel mask to the struct clk. */
+	WARN_ON(clk->clksel_mask == 0);
+
+	*field_val = clkr->val;
+
+	return clkr->div;
+}
+
+
+/* Public functions */
+
+/**
+ * omap2_init_clksel_parent - set a clksel clk's parent field from the hardware
+ * @clk: OMAP clock struct ptr to use
+ *
+ * Given a pointer to a source-selectable struct clk, read the hardware
+ * register and determine what its parent is currently set to.  Update the
+ * clk->parent field with the appropriate clk ptr.
+ */
+void omap2_init_clksel_parent(struct clk *clk)
+{
+	const struct clksel *clks;
+	const struct clksel_rate *clkr;
+	u32 r, found = 0;
+
+	if (!clk->clksel)
+		return;
+
+	r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
+	r >>= __ffs(clk->clksel_mask);
+
+	for (clks = clk->clksel; clks->parent && !found; clks++) {
+		for (clkr = clks->rates; clkr->div && !found; clkr++) {
+			if ((clkr->flags & cpu_mask) && (clkr->val == r)) {
+				if (clk->parent != clks->parent) {
+					pr_debug("clock: inited %s parent "
+						 "to %s (was %s)\n",
+						 clk->name, clks->parent->name,
+						 ((clk->parent) ?
+						  clk->parent->name : "NULL"));
+					clk_reparent(clk, clks->parent);
+				};
+				found = 1;
+			}
+		}
+	}
+
+	if (!found)
+		printk(KERN_ERR "clock: init parent: could not find "
+		       "regval %0x for clock %s\n", r,  clk->name);
+
+	return;
+}
+
+/*
+ * Used for clocks that are part of CLKSEL_xyz governed clocks.
+ * REVISIT: Maybe change to use clk->enable() functions like on omap1?
+ */
+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 clk->rate;
+
+	rate = clk->parent->rate / div;
+
+	pr_debug("clock: new clock rate is %ld (div %d)\n", rate, div);
+
+	return rate;
+}
+
+/**
+ * omap2_clksel_round_rate_div - find divisor for the given clock and rate
+ * @clk: OMAP struct clk to use
+ * @target_rate: desired clock rate
+ * @new_div: ptr to where we should store the divisor
+ *
+ * Finds 'best' divider value in an array based on the source and target
+ * rates.  The divider array must be sorted with smallest divider first.
+ * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
+ * they are only settable as part of virtual_prcm set.
+ *
+ * Returns the rounded clock rate or returns 0xffffffff on error.
+ */
+u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
+				u32 *new_div)
+{
+	unsigned long test_rate;
+	const struct clksel *clks;
+	const struct clksel_rate *clkr;
+	u32 last_div = 0;
+
+	pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n",
+		 clk->name, target_rate);
+
+	*new_div = 1;
+
+	clks = _omap2_get_clksel_by_parent(clk, clk->parent);
+	if (!clks)
+		return ~0;
+
+	for (clkr = clks->rates; clkr->div; clkr++) {
+		if (!(clkr->flags & cpu_mask))
+			continue;
+
+		/* Sanity check */
+		if (clkr->div <= last_div)
+			pr_err("clock: clksel_rate table not sorted "
+			       "for clock %s", clk->name);
+
+		last_div = clkr->div;
+
+		test_rate = clk->parent->rate / clkr->div;
+
+		if (test_rate <= target_rate)
+			break; /* found it */
+	}
+
+	if (!clkr->div) {
+		pr_err("clock: Could not find divisor for target "
+		       "rate %ld for clock %s parent %s\n", target_rate,
+		       clk->name, clk->parent->name);
+		return ~0;
+	}
+
+	*new_div = clkr->div;
+
+	pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div,
+		 (clk->parent->rate / clkr->div));
+
+	return clk->parent->rate / clkr->div;
+}
+
+/**
+ * omap2_clksel_round_rate - find rounded rate for the given clock and rate
+ * @clk: OMAP struct clk to use
+ * @target_rate: desired clock rate
+ *
+ * Compatibility wrapper for OMAP clock framework
+ * Finds best target rate based on the source clock and possible dividers.
+ * rates. The divider array must be sorted with smallest divider first.
+ * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
+ * they are only settable as part of virtual_prcm set.
+ *
+ * Returns the rounded clock rate or returns 0xffffffff on error.
+ */
+long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
+{
+	u32 new_div;
+
+	return omap2_clksel_round_rate_div(clk, target_rate, &new_div);
+}
+
+
+/* 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)
+		return clk->round_rate(clk, rate);
+
+	return clk->rate;
+}
+
+/**
+ * omap2_clksel_to_divisor() - turn clksel field value into integer divider
+ * @clk: OMAP struct clk to use
+ * @field_val: register field value to find
+ *
+ * Given a struct clk of a rate-selectable clksel clock, and a register field
+ * value to search for, find the corresponding clock divisor.  The register
+ * field value should be pre-masked and shifted down so the LSB is at bit 0
+ * before calling.  Returns 0 on error
+ */
+u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val)
+{
+	const struct clksel *clks;
+	const struct clksel_rate *clkr;
+
+	clks = _omap2_get_clksel_by_parent(clk, clk->parent);
+	if (!clks)
+		return 0;
+
+	for (clkr = clks->rates; clkr->div; clkr++) {
+		if ((clkr->flags & cpu_mask) && (clkr->val == field_val))
+			break;
+	}
+
+	if (!clkr->div) {
+		printk(KERN_ERR "clock: Could not find fieldval %d for "
+		       "clock %s parent %s\n", field_val, clk->name,
+		       clk->parent->name);
+		return 0;
+	}
+
+	return clkr->div;
+}
+
+/**
+ * omap2_divisor_to_clksel() - turn clksel integer divisor into a field value
+ * @clk: OMAP struct clk to use
+ * @div: integer divisor to search for
+ *
+ * Given a struct clk of a rate-selectable clksel clock, and a clock divisor,
+ * find the corresponding register field value.  The return register value is
+ * the value before left-shifting.  Returns ~0 on error
+ */
+u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
+{
+	const struct clksel *clks;
+	const struct clksel_rate *clkr;
+
+	/* should never happen */
+	WARN_ON(div == 0);
+
+	clks = _omap2_get_clksel_by_parent(clk, clk->parent);
+	if (!clks)
+		return ~0;
+
+	for (clkr = clks->rates; clkr->div; clkr++) {
+		if ((clkr->flags & cpu_mask) && (clkr->div == div))
+			break;
+	}
+
+	if (!clkr->div) {
+		printk(KERN_ERR "clock: Could not find divisor %d for "
+		       "clock %s parent %s\n", div, clk->name,
+		       clk->parent->name);
+		return ~0;
+	}
+
+	return clkr->val;
+}
+
+/**
+ * omap2_clksel_get_divisor - get current divider applied to parent clock.
+ * @clk: OMAP struct clk to use.
+ *
+ * Returns the integer divisor upon success or 0 on error.
+ */
+u32 omap2_clksel_get_divisor(struct clk *clk)
+{
+	u32 v;
+
+	if (!clk->clksel_mask)
+		return 0;
+
+	v = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
+	v >>= __ffs(clk->clksel_mask);
+
+	return omap2_clksel_to_divisor(clk, v);
+}
+
+int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 v, field_val, validrate, new_div = 0;
+
+	if (!clk->clksel_mask)
+		return -EINVAL;
+
+	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;
+
+	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;
+
+	return 0;
+}
+
+int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent)
+{
+	u32 field_val, v, parent_div;
+
+	if (!clk->clksel)
+		return -EINVAL;
+
+	parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val);
+	if (!parent_div)
+		return -EINVAL;
+
+	/* Set new source value (previous dividers if any in effect) */
+	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_reparent(clk, new_parent);
+
+	/* CLKSEL clocks follow their parents' rates, divided by a divisor */
+	clk->rate = new_parent->rate;
+
+	if (parent_div > 0)
+		clk->rate /= parent_div;
+
+	pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
+		 clk->name, clk->parent->name, clk->rate);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt_dpll.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt_dpll.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clkt_dpll.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clkt_dpll.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,386 @@
+/*
+ * OMAP2/3/4 DPLL clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/div64.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+
+/* DPLL rate rounding: minimum DPLL multiplier, divider values */
+#define DPLL_MIN_MULTIPLIER		2
+#define DPLL_MIN_DIVIDER		1
+
+/* Possible error results from _dpll_test_mult */
+#define DPLL_MULT_UNDERFLOW		-1
+
+/*
+ * Scale factor to mitigate roundoff errors in DPLL rate rounding.
+ * The higher the scale factor, the greater the risk of arithmetic overflow,
+ * but the closer the rounded rate to the target rate.  DPLL_SCALE_FACTOR
+ * must be a power of DPLL_SCALE_BASE.
+ */
+#define DPLL_SCALE_FACTOR		64
+#define DPLL_SCALE_BASE			2
+#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
+
+/* Private functions */
+
+/*
+ * _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;
+}
+
+static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
+					    unsigned int m, unsigned int n)
+{
+	unsigned long long num;
+
+	num = (unsigned long long)parent_rate * m;
+	do_div(num, n);
+	return num;
+}
+
+/*
+ * _dpll_test_mult - test a DPLL multiplier value
+ * @m: pointer to the DPLL m (multiplier) value under test
+ * @n: current DPLL n (divider) value under test
+ * @new_rate: pointer to storage for the resulting rounded rate
+ * @target_rate: the desired DPLL rate
+ * @parent_rate: the DPLL's parent clock rate
+ *
+ * This code tests a DPLL multiplier value, ensuring that the
+ * resulting rate will not be higher than the target_rate, and that
+ * the multiplier value itself is valid for the DPLL.  Initially, the
+ * integer pointed to by the m argument should be prescaled by
+ * multiplying by DPLL_SCALE_FACTOR.  The code will replace this with
+ * a non-scaled m upon return.  This non-scaled m will result in a
+ * new_rate as close as possible to target_rate (but not greater than
+ * target_rate) given the current (parent_rate, n, prescaled m)
+ * triple. Returns DPLL_MULT_UNDERFLOW in the event that the
+ * non-scaled m attempted to underflow, which can allow the calling
+ * function to bail out early; or 0 upon success.
+ */
+static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
+			   unsigned long target_rate,
+			   unsigned long parent_rate)
+{
+	int r = 0, carry = 0;
+
+	/* Unscale m and round if necessary */
+	if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
+		carry = 1;
+	*m = (*m / DPLL_SCALE_FACTOR) + carry;
+
+	/*
+	 * The new rate must be <= the target rate to avoid programming
+	 * a rate that is impossible for the hardware to handle
+	 */
+	*new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
+	if (*new_rate > target_rate) {
+		(*m)--;
+		*new_rate = 0;
+	}
+
+	/* Guard against m underflow */
+	if (*m < DPLL_MIN_MULTIPLIER) {
+		*m = DPLL_MIN_MULTIPLIER;
+		*new_rate = 0;
+		r = DPLL_MULT_UNDERFLOW;
+	}
+
+	if (*new_rate == 0)
+		*new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
+
+	return r;
+}
+
+/* Public functions */
+
+void omap2_init_dpll_parent(struct clk *clk)
+{
+	u32 v;
+	struct dpll_data *dd;
+
+	dd = clk->dpll_data;
+	if (!dd)
+		return;
+
+	/* Return bypass rate if DPLL is bypassed */
+	v = __raw_readl(dd->control_reg);
+	v &= dd->enable_mask;
+	v >>= __ffs(dd->enable_mask);
+
+	/* Reparent in case the dpll is in bypass */
+	if (cpu_is_omap24xx()) {
+		if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
+		    v == OMAP2XXX_EN_DPLL_FRBYPASS)
+			clk_reparent(clk, dd->clk_bypass);
+	} else if (cpu_is_omap34xx()) {
+		if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
+		    v == OMAP3XXX_EN_DPLL_FRBYPASS)
+			clk_reparent(clk, dd->clk_bypass);
+	} else if (cpu_is_omap44xx()) {
+		if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
+		    v == OMAP4XXX_EN_DPLL_FRBYPASS ||
+		    v == OMAP4XXX_EN_DPLL_MNBYPASS)
+			clk_reparent(clk, dd->clk_bypass);
+	}
+	return;
+}
+
+/**
+ * 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, v;
+	struct dpll_data *dd;
+
+	dd = clk->dpll_data;
+	if (!dd)
+		return 0;
+
+	/* 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;
+	} else if (cpu_is_omap44xx()) {
+		if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
+		    v == OMAP4XXX_EN_DPLL_FRBYPASS ||
+		    v == OMAP4XXX_EN_DPLL_MNBYPASS)
+			return dd->clk_bypass->rate;
+	}
+
+	v = __raw_readl(dd->mult_div1_reg);
+	dpll_mult = v & dd->mult_mask;
+	dpll_mult >>= __ffs(dd->mult_mask);
+	dpll_div = v & dd->div1_mask;
+	dpll_div >>= __ffs(dd->div1_mask);
+
+	dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;
+	do_div(dpll_clk, dpll_div + 1);
+
+	return dpll_clk;
+}
+
+/* DPLL rate rounding code */
+
+/**
+ * omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding
+ * @clk: struct clk * of the DPLL
+ * @tolerance: maximum rate error tolerance
+ *
+ * Set the maximum DPLL rate error tolerance for the rate rounding
+ * algorithm.  The rate tolerance is an attempt to balance DPLL power
+ * saving (the least divider value "n") vs. rate fidelity (the least
+ * difference between the desired DPLL target rate and the rounded
+ * rate out of the algorithm).  So, increasing the tolerance is likely
+ * to decrease DPLL power consumption and increase DPLL rate error.
+ * Returns -EINVAL if provided a null clock ptr or a clk that is not a
+ * DPLL; or 0 upon success.
+ */
+int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
+{
+	if (!clk || !clk->dpll_data)
+		return -EINVAL;
+
+	clk->dpll_data->rate_tolerance = tolerance;
+
+	return 0;
+}
+
+/**
+ * omap2_dpll_round_rate - round a target rate for an OMAP DPLL
+ * @clk: struct clk * for a DPLL
+ * @target_rate: desired DPLL clock rate
+ *
+ * Given a DPLL, a desired target rate, and a rate tolerance, round
+ * the target rate to a possible, programmable rate for this DPLL.
+ * Rate tolerance is assumed to be set by the caller before this
+ * function is called.  Attempts to select the minimum possible n
+ * within the tolerance to reduce power consumption.  Stores the
+ * computed (m, n) in the DPLL's dpll_data structure so set_rate()
+ * will not need to call this (expensive) function again.  Returns ~0
+ * if the target rate cannot be rounded, either because the rate is
+ * too low or because the rate tolerance is set too tightly; or the
+ * rounded rate upon success.
+ */
+long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
+{
+	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 / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
+	scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
+
+	dd->last_rounded_rate = 0;
+
+	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 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)
+			break;
+
+		r = _dpll_test_mult(&m, n, &new_rate, target_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) - 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);
+
+			/* We found good settings -- bail out now */
+			if (min_e <= dd->rate_tolerance)
+				break;
+		}
+	}
+
+	if (min_e < 0) {
+		pr_debug("clock: error: target rate or tolerance too low\n");
+		return ~0;
+	}
+
+	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",
+		 dd->last_rounded_rate, target_rate);
+
+	return dd->last_rounded_rate;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2420_data.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock2420_data.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2420_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock2420_data.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1911 @@
+/*
+ *  linux/arch/arm/mach-omap2/clock2420_data.c
+ *
+ *  Copyright (C) 2005-2009 Texas Instruments, Inc.
+ *  Copyright (C) 2004-2010 Nokia Corporation
+ *
+ *  Contacts:
+ *  Richard Woodruff <r-woodruff2@ti.com>
+ *  Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/list.h>
+
+#include <plat/clkdev_omap.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "prm.h"
+#include "cm.h"
+#include "prm-regbits-24xx.h"
+#include "cm-regbits-24xx.h"
+#include "sdrc.h"
+
+#define OMAP_CM_REGADDR                 OMAP2420_CM_REGADDR
+
+/*
+ * 2420 clock tree.
+ *
+ * NOTE:In many cases here we are assigning a 'default' parent.	In many
+ *	cases the parent is selectable.	The get/set parent calls will also
+ *	switch sources.
+ *
+ *	Many some clocks say always_enabled, but they can be auto idled for
+ *	power savings. They will always be available upon clock request.
+ *
+ *	Several sources are given initial rates which may be wrong, this will
+ *	be fixed up in the init func.
+ *
+ *	Things are broadly separated below by clock domains. It is
+ *	noteworthy that most periferals have dependencies on multiple clock
+ *	domains. Many get their interface clocks from the L4 domain, but get
+ *	functional clocks from fixed sources or other core domain derived
+ *	clocks.
+ */
+
+/* Base external input clocks */
+static struct clk func_32k_ck = {
+	.name		= "func_32k_ck",
+	.ops		= &clkops_null,
+	.rate		= 32000,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+static struct clk secure_32k_ck = {
+	.name		= "secure_32k_ck",
+	.ops		= &clkops_null,
+	.rate		= 32768,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
+static struct clk osc_ck = {		/* (*12, *13, 19.2, *26, 38.4)MHz */
+	.name		= "osc_ck",
+	.ops		= &clkops_oscck,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &omap2_osc_clk_recalc,
+};
+
+/* Without modem likely 12MHz, with modem likely 13MHz */
+static struct clk sys_ck = {		/* (*12, *13, 19.2, 26, 38.4)MHz */
+	.name		= "sys_ck",		/* ~ ref_clk also */
+	.ops		= &clkops_null,
+	.parent		= &osc_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &omap2xxx_sys_clk_recalc,
+};
+
+static struct clk alt_ck = {		/* Typical 54M or 48M, may not exist */
+	.name		= "alt_ck",
+	.ops		= &clkops_null,
+	.rate		= 54000000,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+/*
+ * Analog domain root source clocks
+ */
+
+/* dpll_ck, is broken out in to special cases through clksel */
+/* REVISIT: Rate changes on dpll_ck trigger a full set change.	...
+ * deal with this
+ */
+
+static struct dpll_data dpll_dd = {
+	.mult_div1_reg		= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.mult_mask		= OMAP24XX_DPLL_MULT_MASK,
+	.div1_mask		= OMAP24XX_DPLL_DIV_MASK,
+	.clk_bypass		= &sys_ck,
+	.clk_ref		= &sys_ck,
+	.control_reg		= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_mask		= OMAP24XX_EN_DPLL_MASK,
+	.max_multiplier		= 1023,
+	.min_divider		= 1,
+	.max_divider		= 16,
+	.rate_tolerance		= DEFAULT_DPLL_RATE_TOLERANCE
+};
+
+/*
+ * XXX Cannot add round_rate here yet, as this is still a composite clock,
+ * not just a DPLL
+ */
+static struct clk dpll_ck = {
+	.name		= "dpll_ck",
+	.ops		= &clkops_null,
+	.parent		= &sys_ck,		/* Can be func_32k also */
+	.dpll_data	= &dpll_dd,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &omap2_dpllcore_recalc,
+	.set_rate	= &omap2_reprogram_dpllcore,
+};
+
+static struct clk apll96_ck = {
+	.name		= "apll96_ck",
+	.ops		= &clkops_apll96,
+	.parent		= &sys_ck,
+	.rate		= 96000000,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP24XX_EN_96M_PLL_SHIFT,
+};
+
+static struct clk apll54_ck = {
+	.name		= "apll54_ck",
+	.ops		= &clkops_apll54,
+	.parent		= &sys_ck,
+	.rate		= 54000000,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP24XX_EN_54M_PLL_SHIFT,
+};
+
+/*
+ * PRCM digital base sources
+ */
+
+/* func_54m_ck */
+
+static const struct clksel_rate func_54m_apll54_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate func_54m_alt_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel func_54m_clksel[] = {
+	{ .parent = &apll54_ck, .rates = func_54m_apll54_rates, },
+	{ .parent = &alt_ck,	.rates = func_54m_alt_rates, },
+	{ .parent = NULL },
+};
+
+static struct clk func_54m_ck = {
+	.name		= "func_54m_ck",
+	.ops		= &clkops_null,
+	.parent		= &apll54_ck,	/* can also be alt_clk */
+	.clkdm_name	= "wkup_clkdm",
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_54M_SOURCE,
+	.clksel		= func_54m_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk core_ck = {
+	.name		= "core_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll_ck,		/* can also be 32k */
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk func_96m_ck = {
+	.name		= "func_96m_ck",
+	.ops		= &clkops_null,
+	.parent		= &apll96_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* func_48m_ck */
+
+static const struct clksel_rate func_48m_apll96_rates[] = {
+	{ .div = 2, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate func_48m_alt_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel func_48m_clksel[] = {
+	{ .parent = &apll96_ck,	.rates = func_48m_apll96_rates },
+	{ .parent = &alt_ck, .rates = func_48m_alt_rates },
+	{ .parent = NULL }
+};
+
+static struct clk func_48m_ck = {
+	.name		= "func_48m_ck",
+	.ops		= &clkops_null,
+	.parent		= &apll96_ck,	 /* 96M or Alt */
+	.clkdm_name	= "wkup_clkdm",
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_48M_SOURCE,
+	.clksel		= func_48m_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static struct clk func_12m_ck = {
+	.name		= "func_12m_ck",
+	.ops		= &clkops_null,
+	.parent		= &func_48m_ck,
+	.fixed_div	= 4,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &omap_fixed_divisor_recalc,
+};
+
+/* Secure timer, only available in secure mode */
+static struct clk wdt1_osc_ck = {
+	.name		= "ck_wdt1_osc",
+	.ops		= &clkops_null, /* RMK: missing? */
+	.parent		= &osc_ck,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * The common_clkout* clksel_rate structs are common to
+ * sys_clkout, sys_clkout_src, sys_clkout2, and sys_clkout2_src.
+ * sys_clkout2_* are 2420-only, so the
+ * clksel_rate flags fields are inaccurate for those clocks. This is
+ * harmless since access to those clocks are gated by the struct clk
+ * flags fields, which mark them as 2420-only.
+ */
+static const struct clksel_rate common_clkout_src_core_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_sys_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_96m_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_54m_rates[] = {
+	{ .div = 1, .val = 3, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel common_clkout_src_clksel[] = {
+	{ .parent = &core_ck,	  .rates = common_clkout_src_core_rates },
+	{ .parent = &sys_ck,	  .rates = common_clkout_src_sys_rates },
+	{ .parent = &func_96m_ck, .rates = common_clkout_src_96m_rates },
+	{ .parent = &func_54m_ck, .rates = common_clkout_src_54m_rates },
+	{ .parent = NULL }
+};
+
+static struct clk sys_clkout_src = {
+	.name		= "sys_clkout_src",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &func_54m_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP2420_PRCM_CLKOUT_CTRL,
+	.enable_bit	= OMAP24XX_CLKOUT_EN_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP2420_PRCM_CLKOUT_CTRL,
+	.clksel_mask	= OMAP24XX_CLKOUT_SOURCE_MASK,
+	.clksel		= common_clkout_src_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static const struct clksel_rate common_clkout_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 2, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 8, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 16, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 0 },
+};
+
+static const struct clksel sys_clkout_clksel[] = {
+	{ .parent = &sys_clkout_src, .rates = common_clkout_rates },
+	{ .parent = NULL }
+};
+
+static struct clk sys_clkout = {
+	.name		= "sys_clkout",
+	.ops		= &clkops_null,
+	.parent		= &sys_clkout_src,
+	.clkdm_name	= "wkup_clkdm",
+	.clksel_reg	= OMAP2420_PRCM_CLKOUT_CTRL,
+	.clksel_mask	= OMAP24XX_CLKOUT_DIV_MASK,
+	.clksel		= sys_clkout_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+/* In 2430, new in 2420 ES2 */
+static struct clk sys_clkout2_src = {
+	.name		= "sys_clkout2_src",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &func_54m_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP2420_PRCM_CLKOUT_CTRL,
+	.enable_bit	= OMAP2420_CLKOUT2_EN_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP2420_PRCM_CLKOUT_CTRL,
+	.clksel_mask	= OMAP2420_CLKOUT2_SOURCE_MASK,
+	.clksel		= common_clkout_src_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static const struct clksel sys_clkout2_clksel[] = {
+	{ .parent = &sys_clkout2_src, .rates = common_clkout_rates },
+	{ .parent = NULL }
+};
+
+/* In 2430, new in 2420 ES2 */
+static struct clk sys_clkout2 = {
+	.name		= "sys_clkout2",
+	.ops		= &clkops_null,
+	.parent		= &sys_clkout2_src,
+	.clkdm_name	= "wkup_clkdm",
+	.clksel_reg	= OMAP2420_PRCM_CLKOUT_CTRL,
+	.clksel_mask	= OMAP2420_CLKOUT2_DIV_MASK,
+	.clksel		= sys_clkout2_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static struct clk emul_ck = {
+	.name		= "emul_ck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &func_54m_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP2420_PRCM_CLKEMUL_CTRL,
+	.enable_bit	= OMAP24XX_EMULATION_EN_SHIFT,
+	.recalc		= &followparent_recalc,
+
+};
+
+/*
+ * MPU clock domain
+ *	Clocks:
+ *		MPU_FCLK, MPU_ICLK
+ *		INT_M_FCLK, INT_M_I_CLK
+ *
+ * - Individual clocks are hardware managed.
+ * - Base divider comes from: CM_CLKSEL_MPU
+ *
+ */
+static const struct clksel_rate mpu_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_242X },
+	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
+	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
+	{ .div = 0 },
+};
+
+static const struct clksel mpu_clksel[] = {
+	{ .parent = &core_ck, .rates = mpu_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk mpu_ck = {	/* Control cpu */
+	.name		= "mpu_ck",
+	.ops		= &clkops_null,
+	.parent		= &core_ck,
+	.clkdm_name	= "mpu_clkdm",
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP24XX_CLKSEL_MPU_MASK,
+	.clksel		= mpu_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * DSP (2420-UMA+IVA1) clock domain
+ * Clocks:
+ *	2420: UMA_FCLK, UMA_ICLK, IVA_MPU, IVA_COP
+ *
+ * Won't be too specific here. The core clock comes into this block
+ * it is divided then tee'ed. One branch goes directly to xyz enable
+ * controls. The other branch gets further divided by 2 then possibly
+ * routed into a synchronizer and out of clocks abc.
+ */
+static const struct clksel_rate dsp_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
+	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
+	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
+	{ .div = 0 },
+};
+
+static const struct clksel dsp_fck_clksel[] = {
+	{ .parent = &core_ck, .rates = dsp_fck_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk dsp_fck = {
+	.name		= "dsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_ck,
+	.clkdm_name	= "dsp_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP24XX_CLKSEL_DSP_MASK,
+	.clksel		= dsp_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* DSP interface clock */
+static const struct clksel_rate dsp_irate_ick_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 0 },
+};
+
+static const struct clksel dsp_irate_ick_clksel[] = {
+	{ .parent = &dsp_fck, .rates = dsp_irate_ick_rates },
+	{ .parent = NULL }
+};
+
+/* This clock does not exist as such in the TRM. */
+static struct clk dsp_irate_ick = {
+	.name		= "dsp_irate_ick",
+	.ops		= &clkops_null,
+	.parent		= &dsp_fck,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP24XX_CLKSEL_DSP_IF_MASK,
+	.clksel		= dsp_irate_ick_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* 2420 only */
+static struct clk dsp_ick = {
+	.name		= "dsp_ick",	 /* apparently ipi and isp */
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dsp_irate_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP2420_EN_DSP_IPI_SHIFT,	      /* for ipi */
+};
+
+/*
+ * The IVA1 is an ARM7 core on the 2420 that has nothing to do with
+ * the C54x, but which is contained in the DSP powerdomain.  Does not
+ * exist on later OMAPs.
+ */
+static struct clk iva1_ifck = {
+	.name		= "iva1_ifck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_ck,
+	.clkdm_name	= "iva1_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP2420_EN_IVA_COP_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP2420_CLKSEL_IVA_MASK,
+	.clksel		= dsp_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* IVA1 mpu/int/i/f clocks are /2 of parent */
+static struct clk iva1_mpu_int_ifck = {
+	.name		= "iva1_mpu_int_ifck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &iva1_ifck,
+	.clkdm_name	= "iva1_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP2420_EN_IVA_MPU_SHIFT,
+	.fixed_div	= 2,
+	.recalc		= &omap_fixed_divisor_recalc,
+};
+
+/*
+ * L3 clock domain
+ * L3 clocks are used for both interface and functional clocks to
+ * multiple entities. Some of these clocks are completely managed
+ * by hardware, and some others allow software control. Hardware
+ * managed ones general are based on directly CLK_REQ signals and
+ * various auto idle settings. The functional spec sets many of these
+ * as 'tie-high' for their enables.
+ *
+ * I-CLOCKS:
+ *	L3-Interconnect, SMS, GPMC, SDRC, OCM_RAM, OCM_ROM, SDMA
+ *	CAM, HS-USB.
+ * F-CLOCK
+ *	SSI.
+ *
+ * GPMC memories and SDRC have timing and clock sensitive registers which
+ * may very well need notification when the clock changes. Currently for low
+ * operating points, these are taken care of in sleep.S.
+ */
+static const struct clksel_rate core_l3_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_242X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
+	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
+	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
+	{ .div = 16, .val = 16, .flags = RATE_IN_242X },
+	{ .div = 0 }
+};
+
+static const struct clksel core_l3_clksel[] = {
+	{ .parent = &core_ck, .rates = core_l3_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk core_l3_ck = {	/* Used for ick and fck, interconnect */
+	.name		= "core_l3_ck",
+	.ops		= &clkops_null,
+	.parent		= &core_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_L3_MASK,
+	.clksel		= core_l3_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* usb_l4_ick */
+static const struct clksel_rate usb_l4_ick_core_l3_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel usb_l4_ick_clksel[] = {
+	{ .parent = &core_l3_ck, .rates = usb_l4_ick_core_l3_rates },
+	{ .parent = NULL },
+};
+
+/* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */
+static struct clk usb_l4_ick = {	/* FS-USB interface clock */
+	.name		= "usb_l4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_USB_MASK,
+	.clksel		= usb_l4_ick_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * L4 clock management domain
+ *
+ * This domain contains lots of interface clocks from the L4 interface, some
+ * functional clocks.	Fixed APLL functional source clocks are managed in
+ * this domain.
+ */
+static const struct clksel_rate l4_core_l3_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel l4_clksel[] = {
+	{ .parent = &core_l3_ck, .rates = l4_core_l3_rates },
+	{ .parent = NULL }
+};
+
+static struct clk l4_ck = {		/* used both as an ick and fck */
+	.name		= "l4_ck",
+	.ops		= &clkops_null,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_L4_MASK,
+	.clksel		= l4_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * SSI is in L3 management domain, its direct parent is core not l3,
+ * many core power domain entities are grouped into the L3 clock
+ * domain.
+ * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_ICLK
+ *
+ * ssr = core/1/2/3/4/5, sst = 1/2 ssr.
+ */
+static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
+	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
+	{ .div = 0 }
+};
+
+static const struct clksel ssi_ssr_sst_fck_clksel[] = {
+	{ .parent = &core_ck, .rates = ssi_ssr_sst_fck_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk ssi_ssr_sst_fck = {
+	.name		= "ssi_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_SSI_MASK,
+	.clksel		= ssi_ssr_sst_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * Presumably this is the same as SSI_ICLK.
+ * TRM contradicts itself on what clockdomain SSI_ICLK is in
+ */
+static struct clk ssi_l4_ick = {
+	.name		= "ssi_l4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+
+/*
+ * GFX clock domain
+ *	Clocks:
+ * GFX_FCLK, GFX_ICLK
+ * GFX_CG1(2d), GFX_CG2(3d)
+ *
+ * GFX_FCLK runs from L3, and is divided by (1,2,3,4)
+ * The 2d and 3d clocks run at a hardware determined
+ * divided value of fclk.
+ *
+ */
+
+/* This clksel struct is shared between gfx_3d_fck and gfx_2d_fck */
+static const struct clksel gfx_fck_clksel[] = {
+	{ .parent = &core_l3_ck, .rates = gfx_l3_rates },
+	{ .parent = NULL },
+};
+
+static struct clk gfx_3d_fck = {
+	.name		= "gfx_3d_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "gfx_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_3D_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
+	.clksel		= gfx_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static struct clk gfx_2d_fck = {
+	.name		= "gfx_2d_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "gfx_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_2D_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
+	.clksel		= gfx_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gfx_ick = {
+	.name		= "gfx_ick",		/* From l3 */
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "gfx_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP_EN_GFX_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * DSS clock domain
+ * CLOCKs:
+ * DSS_L4_ICLK, DSS_L3_ICLK,
+ * DSS_CLK1, DSS_CLK2, DSS_54MHz_CLK
+ *
+ * DSS is both initiator and target.
+ */
+/* XXX Add RATE_NOT_VALIDATED */
+
+static const struct clksel_rate dss1_fck_sys_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate dss1_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 5, .val = 5, .flags = RATE_IN_24XX },
+	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
+	{ .div = 8, .val = 8, .flags = RATE_IN_24XX },
+	{ .div = 9, .val = 9, .flags = RATE_IN_24XX },
+	{ .div = 12, .val = 12, .flags = RATE_IN_24XX },
+	{ .div = 16, .val = 16, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel dss1_fck_clksel[] = {
+	{ .parent = &sys_ck,  .rates = dss1_fck_sys_rates },
+	{ .parent = &core_ck, .rates = dss1_fck_core_rates },
+	{ .parent = NULL },
+};
+
+static struct clk dss_ick = {		/* Enables both L3,L4 ICLK's */
+	.name		= "dss_ick",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &l4_ck,	/* really both l3 and l4 */
+	.clkdm_name	= "dss_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss1_fck = {
+	.name		= "dss1_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &core_ck,		/* Core or sys */
+	.clkdm_name	= "dss_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_DSS1_MASK,
+	.clksel		= dss1_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate dss2_fck_sys_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate dss2_fck_48m_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel dss2_fck_clksel[] = {
+	{ .parent = &sys_ck,	  .rates = dss2_fck_sys_rates },
+	{ .parent = &func_48m_ck, .rates = dss2_fck_48m_rates },
+	{ .parent = NULL }
+};
+
+static struct clk dss2_fck = {		/* Alt clk used in power management */
+	.name		= "dss2_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &sys_ck,		/* fixed at sys_ck or 48MHz */
+	.clkdm_name	= "dss_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_DSS2_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_DSS2_MASK,
+	.clksel		= dss2_fck_clksel,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss_54m_fck = {	/* Alt clk used in power management */
+	.name		= "dss_54m_fck",	/* 54m tv clk */
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_54m_ck,
+	.clkdm_name	= "dss_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_TV_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * CORE power domain ICLK & FCLK defines.
+ * Many of the these can have more than one possible parent. Entries
+ * here will likely have an L4 interface parent, and may have multiple
+ * functional clock parents.
+ */
+static const struct clksel_rate gpt_alt_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel omap24xx_gpt_clksel[] = {
+	{ .parent = &func_32k_ck, .rates = gpt_32k_rates },
+	{ .parent = &sys_ck,	  .rates = gpt_sys_rates },
+	{ .parent = &alt_ck,	  .rates = gpt_alt_rates },
+	{ .parent = NULL },
+};
+
+static struct clk gpt1_ick = {
+	.name		= "gpt1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt1_fck = {
+	.name		= "gpt1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT1_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static struct clk gpt2_ick = {
+	.name		= "gpt2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt2_fck = {
+	.name		= "gpt2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT2_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt3_ick = {
+	.name		= "gpt3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt3_fck = {
+	.name		= "gpt3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT3_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt4_ick = {
+	.name		= "gpt4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt4_fck = {
+	.name		= "gpt4_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT4_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt5_ick = {
+	.name		= "gpt5_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt5_fck = {
+	.name		= "gpt5_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT5_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt6_ick = {
+	.name		= "gpt6_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt6_fck = {
+	.name		= "gpt6_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT6_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt7_ick = {
+	.name		= "gpt7_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt7_fck = {
+	.name		= "gpt7_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT7_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt8_ick = {
+	.name		= "gpt8_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt8_fck = {
+	.name		= "gpt8_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT8_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt9_ick = {
+	.name		= "gpt9_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt9_fck = {
+	.name		= "gpt9_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT9_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt10_ick = {
+	.name		= "gpt10_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt10_fck = {
+	.name		= "gpt10_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT10_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt11_ick = {
+	.name		= "gpt11_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt11_fck = {
+	.name		= "gpt11_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT11_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt12_ick = {
+	.name		= "gpt12_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt12_fck = {
+	.name		= "gpt12_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &secure_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT12_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp1_ick = {
+	.name		= "mcbsp1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp1_fck = {
+	.name		= "mcbsp1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp2_ick = {
+	.name		= "mcbsp2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp2_fck = {
+	.name		= "mcbsp2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi1_ick = {
+	.name		= "mcspi1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi1_fck = {
+	.name		= "mcspi1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi2_ick = {
+	.name		= "mcspi2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi2_fck = {
+	.name		= "mcspi2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart1_ick = {
+	.name		= "uart1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart1_fck = {
+	.name		= "uart1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart2_ick = {
+	.name		= "uart2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart2_fck = {
+	.name		= "uart2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart3_ick = {
+	.name		= "uart3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart3_fck = {
+	.name		= "uart3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpios_ick = {
+	.name		= "gpios_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpios_fck = {
+	.name		= "gpios_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mpu_wdt_ick = {
+	.name		= "mpu_wdt_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mpu_wdt_fck = {
+	.name		= "mpu_wdt_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sync_32k_ick = {
+	.name		= "sync_32k_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_32KSYNC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt1_ick = {
+	.name		= "wdt1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_WDT1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk omapctrl_ick = {
+	.name		= "omapctrl_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_OMAPCTRL_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk cam_ick = {
+	.name		= "cam_ick",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * cam_fck controls both CAM_MCLK and CAM_FCLK.  It should probably be
+ * split into two separate clocks, since the parent clocks are different
+ * and the clockdomains are also different.
+ */
+static struct clk cam_fck = {
+	.name		= "cam_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mailboxes_ick = {
+	.name		= "mailboxes_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MAILBOXES_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt4_ick = {
+	.name		= "wdt4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt4_fck = {
+	.name		= "wdt4_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt3_ick = {
+	.name		= "wdt3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_WDT3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt3_fck = {
+	.name		= "wdt3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_WDT3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mspro_ick = {
+	.name		= "mspro_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mspro_fck = {
+	.name		= "mspro_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmc_ick = {
+	.name		= "mmc_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_MMC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmc_fck = {
+	.name		= "mmc_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_MMC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk fac_ick = {
+	.name		= "fac_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk fac_fck = {
+	.name		= "fac_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_12m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk eac_ick = {
+	.name		= "eac_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_EAC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk eac_fck = {
+	.name		= "eac_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_EAC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hdq_ick = {
+	.name		= "hdq_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hdq_fck = {
+	.name		= "hdq_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_12m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c2_ick = {
+	.name		= "i2c2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c2_fck = {
+	.name		= "i2c2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_12m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c1_ick = {
+	.name		= "i2c1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c1_fck = {
+	.name		= "i2c1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_12m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpmc_fck = {
+	.name		= "gpmc_fck",
+	.ops		= &clkops_null, /* RMK: missing? */
+	.parent		= &core_l3_ck,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sdma_fck = {
+	.name		= "sdma_fck",
+	.ops		= &clkops_null, /* RMK: missing? */
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sdma_ick = {
+	.name		= "sdma_ick",
+	.ops		= &clkops_null, /* RMK: missing? */
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk vlynq_ick = {
+	.name		= "vlynq_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_VLYNQ_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static const struct clksel_rate vlynq_fck_96m_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_242X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate vlynq_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_242X },
+	{ .div = 2, .val = 2, .flags = RATE_IN_242X },
+	{ .div = 3, .val = 3, .flags = RATE_IN_242X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_242X },
+	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
+	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
+	{ .div = 9, .val = 9, .flags = RATE_IN_242X },
+	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
+	{ .div = 16, .val = 16, .flags = RATE_IN_242X | DEFAULT_RATE },
+	{ .div = 18, .val = 18, .flags = RATE_IN_242X },
+	{ .div = 0 }
+};
+
+static const struct clksel vlynq_fck_clksel[] = {
+	{ .parent = &func_96m_ck, .rates = vlynq_fck_96m_rates },
+	{ .parent = &core_ck,	  .rates = vlynq_fck_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk vlynq_fck = {
+	.name		= "vlynq_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_VLYNQ_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP2420_CLKSEL_VLYNQ_MASK,
+	.clksel		= vlynq_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk des_ick = {
+	.name		= "des_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_DES_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sha_ick = {
+	.name		= "sha_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_SHA_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk rng_ick = {
+	.name		= "rng_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_RNG_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk aes_ick = {
+	.name		= "aes_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_AES_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk pka_ick = {
+	.name		= "pka_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_PKA_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usb_fck = {
+	.name		= "usb_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * This clock is a composite clock which does entire set changes then
+ * forces a rebalance. It keys on the MPU speed, but it really could
+ * be any key speed part of a set in the rate table.
+ *
+ * to really change a set, you need memory table sets which get changed
+ * in sram, pre-notifiers & post notifiers, changing the top set, without
+ * having low level display recalc's won't work... this is why dpm notifiers
+ * work, isr's off, walk a list of clocks already _off_ and not messing with
+ * the bus.
+ *
+ * This clock should have no parent. It embodies the entire upper level
+ * active set. A parent will mess up some of the init also.
+ */
+static struct clk virt_prcm_set = {
+	.name		= "virt_prcm_set",
+	.ops		= &clkops_null,
+	.parent		= &mpu_ck,	/* Indexed by mpu speed, no parent */
+	.recalc		= &omap2_table_mpu_recalc,	/* sets are keyed on mpu rate */
+	.set_rate	= &omap2_select_table_rate,
+	.round_rate	= &omap2_round_to_table_rate,
+};
+
+
+/*
+ * clkdev integration
+ */
+
+static struct omap_clk omap2420_clks[] = {
+	/* external root sources */
+	CLK(NULL,	"func_32k_ck",	&func_32k_ck,	CK_242X),
+	CLK(NULL,	"secure_32k_ck", &secure_32k_ck, CK_242X),
+	CLK(NULL,	"osc_ck",	&osc_ck,	CK_242X),
+	CLK(NULL,	"sys_ck",	&sys_ck,	CK_242X),
+	CLK(NULL,	"alt_ck",	&alt_ck,	CK_242X),
+	/* internal analog sources */
+	CLK(NULL,	"dpll_ck",	&dpll_ck,	CK_242X),
+	CLK(NULL,	"apll96_ck",	&apll96_ck,	CK_242X),
+	CLK(NULL,	"apll54_ck",	&apll54_ck,	CK_242X),
+	/* internal prcm root sources */
+	CLK(NULL,	"func_54m_ck",	&func_54m_ck,	CK_242X),
+	CLK(NULL,	"core_ck",	&core_ck,	CK_242X),
+	CLK(NULL,	"func_96m_ck",	&func_96m_ck,	CK_242X),
+	CLK(NULL,	"func_48m_ck",	&func_48m_ck,	CK_242X),
+	CLK(NULL,	"func_12m_ck",	&func_12m_ck,	CK_242X),
+	CLK(NULL,	"ck_wdt1_osc",	&wdt1_osc_ck,	CK_242X),
+	CLK(NULL,	"sys_clkout_src", &sys_clkout_src, CK_242X),
+	CLK(NULL,	"sys_clkout",	&sys_clkout,	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_242X),
+	/* dsp domain clocks */
+	CLK(NULL,	"dsp_fck",	&dsp_fck,	CK_242X),
+	CLK(NULL,	"dsp_irate_ick", &dsp_irate_ick, CK_242X),
+	CLK(NULL,	"dsp_ick",	&dsp_ick,	CK_242X),
+	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_242X),
+	CLK(NULL,	"gfx_2d_fck",	&gfx_2d_fck,	CK_242X),
+	CLK(NULL,	"gfx_ick",	&gfx_ick,	CK_242X),
+	/* DSS domain clocks */
+	CLK("omapdss",	"ick",		&dss_ick,	CK_242X),
+	CLK("omapdss",	"dss1_fck",	&dss1_fck,	CK_242X),
+	CLK("omapdss",	"dss2_fck",	&dss2_fck,	CK_242X),
+	CLK("omapdss",	"tv_fck",	&dss_54m_fck,	CK_242X),
+	/* L3 domain clocks */
+	CLK(NULL,	"core_l3_ck",	&core_l3_ck,	CK_242X),
+	CLK(NULL,	"ssi_fck",	&ssi_ssr_sst_fck, CK_242X),
+	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick,	CK_242X),
+	/* L4 domain clocks */
+	CLK(NULL,	"l4_ck",	&l4_ck,		CK_242X),
+	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_242X),
+	/* virtual meta-group clock */
+	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_242X),
+	/* general l4 interface ck, multi-parent functional clk */
+	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_242X),
+	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_242X),
+	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_242X),
+	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_242X),
+	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_242X),
+	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_242X),
+	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_242X),
+	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_242X),
+	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_242X),
+	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_242X),
+	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_242X),
+	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_242X),
+	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_242X),
+	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_242X),
+	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_242X),
+	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_242X),
+	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_242X),
+	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_242X),
+	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_242X),
+	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_242X),
+	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_242X),
+	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_242X),
+	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_242X),
+	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_242X),
+	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_242X),
+	CLK("omap-mcbsp.1", "fck",	&mcbsp1_fck,	CK_242X),
+	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_242X),
+	CLK("omap-mcbsp.2", "fck",	&mcbsp2_fck,	CK_242X),
+	CLK("omap2_mcspi.1", "ick",	&mcspi1_ick,	CK_242X),
+	CLK("omap2_mcspi.1", "fck",	&mcspi1_fck,	CK_242X),
+	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick,	CK_242X),
+	CLK("omap2_mcspi.2", "fck",	&mcspi2_fck,	CK_242X),
+	CLK(NULL,	"uart1_ick",	&uart1_ick,	CK_242X),
+	CLK(NULL,	"uart1_fck",	&uart1_fck,	CK_242X),
+	CLK(NULL,	"uart2_ick",	&uart2_ick,	CK_242X),
+	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_242X),
+	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_242X),
+	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_242X),
+	CLK(NULL,	"gpios_ick",	&gpios_ick,	CK_242X),
+	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_242X),
+	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_242X),
+	CLK("omap_wdt",	"fck",		&mpu_wdt_fck,	CK_242X),
+	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_242X),
+	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_242X),
+	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_242X),
+	CLK("omap24xxcam", "fck",	&cam_fck,	CK_242X),
+	CLK("omap24xxcam", "ick",	&cam_ick,	CK_242X),
+	CLK(NULL,	"mailboxes_ick", &mailboxes_ick,	CK_242X),
+	CLK(NULL,	"wdt4_ick",	&wdt4_ick,	CK_242X),
+	CLK(NULL,	"wdt4_fck",	&wdt4_fck,	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_242X),
+	CLK(NULL,	"mspro_fck",	&mspro_fck,	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_242X),
+	CLK(NULL,	"fac_fck",	&fac_fck,	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_242X),
+	CLK("omap_hdq.1", "fck",	&hdq_fck,	CK_242X),
+	CLK("i2c_omap.1", "ick",	&i2c1_ick,	CK_242X),
+	CLK("i2c_omap.1", "fck",	&i2c1_fck,	CK_242X),
+	CLK("i2c_omap.2", "ick",	&i2c2_ick,	CK_242X),
+	CLK("i2c_omap.2", "fck",	&i2c2_fck,	CK_242X),
+	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_242X),
+	CLK(NULL,	"sdma_fck",	&sdma_fck,	CK_242X),
+	CLK(NULL,	"sdma_ick",	&sdma_ick,	CK_242X),
+	CLK(NULL,	"vlynq_ick",	&vlynq_ick,	CK_242X),
+	CLK(NULL,	"vlynq_fck",	&vlynq_fck,	CK_242X),
+	CLK(NULL,	"des_ick",	&des_ick,	CK_242X),
+	CLK(NULL,	"sha_ick",	&sha_ick,	CK_242X),
+	CLK("omap_rng",	"ick",		&rng_ick,	CK_242X),
+	CLK(NULL,	"aes_ick",	&aes_ick,	CK_242X),
+	CLK(NULL,	"pka_ick",	&pka_ick,	CK_242X),
+	CLK(NULL,	"usb_fck",	&usb_fck,	CK_242X),
+	CLK("musb_hdrc",	"fck",	&osc_ck,	CK_242X),
+};
+
+/*
+ * init code
+ */
+
+int __init omap2420_clk_init(void)
+{
+	const struct prcm_config *prcm;
+	struct omap_clk *c;
+	u32 clkrate;
+
+	prcm_clksrc_ctrl = OMAP2420_PRCM_CLKSRC_CTRL;
+	cm_idlest_pll = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST);
+	cpu_mask = RATE_IN_242X;
+	rate_table = omap2420_rate_table;
+
+	clk_init(&omap2_clk_functions);
+
+	for (c = omap2420_clks; c < omap2420_clks + ARRAY_SIZE(omap2420_clks);
+	     c++)
+		clk_preinit(c->lk.clk);
+
+	osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
+	propagate_rate(&osc_ck);
+	sys_ck.rate = omap2xxx_sys_clk_recalc(&sys_ck);
+	propagate_rate(&sys_ck);
+
+	for (c = omap2420_clks; c < omap2420_clks + ARRAY_SIZE(omap2420_clks);
+	     c++) {
+		clkdev_add(&c->lk);
+		clk_register(c->lk.clk);
+		omap2_init_clk_clkdm(c->lk.clk);
+	}
+
+	/* Check the MPU rate set by bootloader */
+	clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
+	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+		if (!(prcm->flags & cpu_mask))
+			continue;
+		if (prcm->xtal_speed != sys_ck.rate)
+			continue;
+		if (prcm->dpll_speed <= clkrate)
+			break;
+	}
+	curr_prcm_set = prcm;
+
+	recalculate_root_clocks();
+
+	pr_info("Clocking rate (Crystal/DPLL/MPU): %ld.%01ld/%ld/%ld MHz\n",
+		(sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
+		(dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
+
+	/*
+	 * Only enable those clocks we will need, let the drivers
+	 * enable other clocks as necessary
+	 */
+	clk_enable_init_clocks();
+
+	/* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */
+	vclk = clk_get(NULL, "virt_prcm_set");
+	sclk = clk_get(NULL, "sys_ck");
+	dclk = clk_get(NULL, "dpll_ck");
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2430.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock2430.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2430.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock2430.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,59 @@
+/*
+ * clock2430.c - OMAP2430-specific clock integration code
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+
+/**
+ * omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
+ *
+ * OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the
+ * CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE.  This custom function
+ * passes back the correct CM_IDLEST register address for I2CHS
+ * modules.  No return value.
+ */
+static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
+					   void __iomem **idlest_reg,
+					   u8 *idlest_bit,
+					   u8 *idlest_val)
+{
+	*idlest_reg = OMAP2430_CM_REGADDR(CORE_MOD, CM_IDLEST);
+	*idlest_bit = clk->enable_bit;
+	*idlest_val = OMAP24XX_CM_IDLEST_VAL;
+}
+
+/* 2430 I2CHS has non-standard IDLEST register */
+const struct clkops clkops_omap2430_i2chs_wait = {
+	.enable		= omap2_dflt_clk_enable,
+	.disable	= omap2_dflt_clk_disable,
+	.find_idlest	= omap2430_clk_i2chs_find_idlest,
+	.find_companion = omap2_clk_dflt_find_companion,
+};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2430_data.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock2430_data.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2430_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock2430_data.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,2008 @@
+/*
+ *  linux/arch/arm/mach-omap2/clock2430_data.c
+ *
+ *  Copyright (C) 2005-2009 Texas Instruments, Inc.
+ *  Copyright (C) 2004-2010 Nokia Corporation
+ *
+ *  Contacts:
+ *  Richard Woodruff <r-woodruff2@ti.com>
+ *  Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/list.h>
+
+#include <plat/clkdev_omap.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "prm.h"
+#include "cm.h"
+#include "prm-regbits-24xx.h"
+#include "cm-regbits-24xx.h"
+#include "sdrc.h"
+
+#define OMAP_CM_REGADDR			OMAP2430_CM_REGADDR
+
+/*
+ * 2430 clock tree.
+ *
+ * NOTE:In many cases here we are assigning a 'default' parent.	In many
+ *	cases the parent is selectable.	The get/set parent calls will also
+ *	switch sources.
+ *
+ *	Many some clocks say always_enabled, but they can be auto idled for
+ *	power savings. They will always be available upon clock request.
+ *
+ *	Several sources are given initial rates which may be wrong, this will
+ *	be fixed up in the init func.
+ *
+ *	Things are broadly separated below by clock domains. It is
+ *	noteworthy that most periferals have dependencies on multiple clock
+ *	domains. Many get their interface clocks from the L4 domain, but get
+ *	functional clocks from fixed sources or other core domain derived
+ *	clocks.
+ */
+
+/* Base external input clocks */
+static struct clk func_32k_ck = {
+	.name		= "func_32k_ck",
+	.ops		= &clkops_null,
+	.rate		= 32000,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+static struct clk secure_32k_ck = {
+	.name		= "secure_32k_ck",
+	.ops		= &clkops_null,
+	.rate		= 32768,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
+static struct clk osc_ck = {		/* (*12, *13, 19.2, *26, 38.4)MHz */
+	.name		= "osc_ck",
+	.ops		= &clkops_oscck,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &omap2_osc_clk_recalc,
+};
+
+/* Without modem likely 12MHz, with modem likely 13MHz */
+static struct clk sys_ck = {		/* (*12, *13, 19.2, 26, 38.4)MHz */
+	.name		= "sys_ck",		/* ~ ref_clk also */
+	.ops		= &clkops_null,
+	.parent		= &osc_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &omap2xxx_sys_clk_recalc,
+};
+
+static struct clk alt_ck = {		/* Typical 54M or 48M, may not exist */
+	.name		= "alt_ck",
+	.ops		= &clkops_null,
+	.rate		= 54000000,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+/*
+ * Analog domain root source clocks
+ */
+
+/* dpll_ck, is broken out in to special cases through clksel */
+/* REVISIT: Rate changes on dpll_ck trigger a full set change.	...
+ * deal with this
+ */
+
+static struct dpll_data dpll_dd = {
+	.mult_div1_reg		= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.mult_mask		= OMAP24XX_DPLL_MULT_MASK,
+	.div1_mask		= OMAP24XX_DPLL_DIV_MASK,
+	.clk_bypass		= &sys_ck,
+	.clk_ref		= &sys_ck,
+	.control_reg		= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_mask		= OMAP24XX_EN_DPLL_MASK,
+	.max_multiplier		= 1023,
+	.min_divider		= 1,
+	.max_divider		= 16,
+	.rate_tolerance		= DEFAULT_DPLL_RATE_TOLERANCE
+};
+
+/*
+ * XXX Cannot add round_rate here yet, as this is still a composite clock,
+ * not just a DPLL
+ */
+static struct clk dpll_ck = {
+	.name		= "dpll_ck",
+	.ops		= &clkops_null,
+	.parent		= &sys_ck,		/* Can be func_32k also */
+	.dpll_data	= &dpll_dd,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &omap2_dpllcore_recalc,
+	.set_rate	= &omap2_reprogram_dpllcore,
+};
+
+static struct clk apll96_ck = {
+	.name		= "apll96_ck",
+	.ops		= &clkops_apll96,
+	.parent		= &sys_ck,
+	.rate		= 96000000,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP24XX_EN_96M_PLL_SHIFT,
+};
+
+static struct clk apll54_ck = {
+	.name		= "apll54_ck",
+	.ops		= &clkops_apll54,
+	.parent		= &sys_ck,
+	.rate		= 54000000,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP24XX_EN_54M_PLL_SHIFT,
+};
+
+/*
+ * PRCM digital base sources
+ */
+
+/* func_54m_ck */
+
+static const struct clksel_rate func_54m_apll54_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate func_54m_alt_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel func_54m_clksel[] = {
+	{ .parent = &apll54_ck, .rates = func_54m_apll54_rates, },
+	{ .parent = &alt_ck,	.rates = func_54m_alt_rates, },
+	{ .parent = NULL },
+};
+
+static struct clk func_54m_ck = {
+	.name		= "func_54m_ck",
+	.ops		= &clkops_null,
+	.parent		= &apll54_ck,	/* can also be alt_clk */
+	.clkdm_name	= "wkup_clkdm",
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_54M_SOURCE,
+	.clksel		= func_54m_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk core_ck = {
+	.name		= "core_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll_ck,		/* can also be 32k */
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* func_96m_ck */
+static const struct clksel_rate func_96m_apll96_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate func_96m_alt_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_243X | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel func_96m_clksel[] = {
+	{ .parent = &apll96_ck,	.rates = func_96m_apll96_rates },
+	{ .parent = &alt_ck,	.rates = func_96m_alt_rates },
+	{ .parent = NULL }
+};
+
+static struct clk func_96m_ck = {
+	.name		= "func_96m_ck",
+	.ops		= &clkops_null,
+	.parent		= &apll96_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP2430_96M_SOURCE,
+	.clksel		= func_96m_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* func_48m_ck */
+
+static const struct clksel_rate func_48m_apll96_rates[] = {
+	{ .div = 2, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate func_48m_alt_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel func_48m_clksel[] = {
+	{ .parent = &apll96_ck,	.rates = func_48m_apll96_rates },
+	{ .parent = &alt_ck, .rates = func_48m_alt_rates },
+	{ .parent = NULL }
+};
+
+static struct clk func_48m_ck = {
+	.name		= "func_48m_ck",
+	.ops		= &clkops_null,
+	.parent		= &apll96_ck,	 /* 96M or Alt */
+	.clkdm_name	= "wkup_clkdm",
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_48M_SOURCE,
+	.clksel		= func_48m_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static struct clk func_12m_ck = {
+	.name		= "func_12m_ck",
+	.ops		= &clkops_null,
+	.parent		= &func_48m_ck,
+	.fixed_div	= 4,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &omap_fixed_divisor_recalc,
+};
+
+/* Secure timer, only available in secure mode */
+static struct clk wdt1_osc_ck = {
+	.name		= "ck_wdt1_osc",
+	.ops		= &clkops_null, /* RMK: missing? */
+	.parent		= &osc_ck,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * The common_clkout* clksel_rate structs are common to
+ * sys_clkout, sys_clkout_src, sys_clkout2, and sys_clkout2_src.
+ * sys_clkout2_* are 2420-only, so the
+ * clksel_rate flags fields are inaccurate for those clocks. This is
+ * harmless since access to those clocks are gated by the struct clk
+ * flags fields, which mark them as 2420-only.
+ */
+static const struct clksel_rate common_clkout_src_core_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_sys_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_96m_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_54m_rates[] = {
+	{ .div = 1, .val = 3, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel common_clkout_src_clksel[] = {
+	{ .parent = &core_ck,	  .rates = common_clkout_src_core_rates },
+	{ .parent = &sys_ck,	  .rates = common_clkout_src_sys_rates },
+	{ .parent = &func_96m_ck, .rates = common_clkout_src_96m_rates },
+	{ .parent = &func_54m_ck, .rates = common_clkout_src_54m_rates },
+	{ .parent = NULL }
+};
+
+static struct clk sys_clkout_src = {
+	.name		= "sys_clkout_src",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &func_54m_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP2430_PRCM_CLKOUT_CTRL,
+	.enable_bit	= OMAP24XX_CLKOUT_EN_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP2430_PRCM_CLKOUT_CTRL,
+	.clksel_mask	= OMAP24XX_CLKOUT_SOURCE_MASK,
+	.clksel		= common_clkout_src_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static const struct clksel_rate common_clkout_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 2, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 8, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 16, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 0 },
+};
+
+static const struct clksel sys_clkout_clksel[] = {
+	{ .parent = &sys_clkout_src, .rates = common_clkout_rates },
+	{ .parent = NULL }
+};
+
+static struct clk sys_clkout = {
+	.name		= "sys_clkout",
+	.ops		= &clkops_null,
+	.parent		= &sys_clkout_src,
+	.clkdm_name	= "wkup_clkdm",
+	.clksel_reg	= OMAP2430_PRCM_CLKOUT_CTRL,
+	.clksel_mask	= OMAP24XX_CLKOUT_DIV_MASK,
+	.clksel		= sys_clkout_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static struct clk emul_ck = {
+	.name		= "emul_ck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &func_54m_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP2430_PRCM_CLKEMUL_CTRL,
+	.enable_bit	= OMAP24XX_EMULATION_EN_SHIFT,
+	.recalc		= &followparent_recalc,
+
+};
+
+/*
+ * MPU clock domain
+ *	Clocks:
+ *		MPU_FCLK, MPU_ICLK
+ *		INT_M_FCLK, INT_M_I_CLK
+ *
+ * - Individual clocks are hardware managed.
+ * - Base divider comes from: CM_CLKSEL_MPU
+ *
+ */
+static const struct clksel_rate mpu_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 0 },
+};
+
+static const struct clksel mpu_clksel[] = {
+	{ .parent = &core_ck, .rates = mpu_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk mpu_ck = {	/* Control cpu */
+	.name		= "mpu_ck",
+	.ops		= &clkops_null,
+	.parent		= &core_ck,
+	.clkdm_name	= "mpu_clkdm",
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP24XX_CLKSEL_MPU_MASK,
+	.clksel		= mpu_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * DSP (2430-IVA2.1) clock domain
+ * Clocks:
+ *	2430: IVA2.1_FCLK (really just DSP_FCLK), IVA2.1_ICLK
+ *
+ * Won't be too specific here. The core clock comes into this block
+ * it is divided then tee'ed. One branch goes directly to xyz enable
+ * controls. The other branch gets further divided by 2 then possibly
+ * routed into a synchronizer and out of clocks abc.
+ */
+static const struct clksel_rate dsp_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 0 },
+};
+
+static const struct clksel dsp_fck_clksel[] = {
+	{ .parent = &core_ck, .rates = dsp_fck_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk dsp_fck = {
+	.name		= "dsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_ck,
+	.clkdm_name	= "dsp_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP24XX_CLKSEL_DSP_MASK,
+	.clksel		= dsp_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* DSP interface clock */
+static const struct clksel_rate dsp_irate_ick_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_243X },
+	{ .div = 0 },
+};
+
+static const struct clksel dsp_irate_ick_clksel[] = {
+	{ .parent = &dsp_fck, .rates = dsp_irate_ick_rates },
+	{ .parent = NULL }
+};
+
+/* This clock does not exist as such in the TRM. */
+static struct clk dsp_irate_ick = {
+	.name		= "dsp_irate_ick",
+	.ops		= &clkops_null,
+	.parent		= &dsp_fck,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP24XX_CLKSEL_DSP_IF_MASK,
+	.clksel		= dsp_irate_ick_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* 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,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
+};
+
+/*
+ * L3 clock domain
+ * L3 clocks are used for both interface and functional clocks to
+ * multiple entities. Some of these clocks are completely managed
+ * by hardware, and some others allow software control. Hardware
+ * managed ones general are based on directly CLK_REQ signals and
+ * various auto idle settings. The functional spec sets many of these
+ * as 'tie-high' for their enables.
+ *
+ * I-CLOCKS:
+ *	L3-Interconnect, SMS, GPMC, SDRC, OCM_RAM, OCM_ROM, SDMA
+ *	CAM, HS-USB.
+ * F-CLOCK
+ *	SSI.
+ *
+ * GPMC memories and SDRC have timing and clock sensitive registers which
+ * may very well need notification when the clock changes. Currently for low
+ * operating points, these are taken care of in sleep.S.
+ */
+static const struct clksel_rate core_l3_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel core_l3_clksel[] = {
+	{ .parent = &core_ck, .rates = core_l3_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk core_l3_ck = {	/* Used for ick and fck, interconnect */
+	.name		= "core_l3_ck",
+	.ops		= &clkops_null,
+	.parent		= &core_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_L3_MASK,
+	.clksel		= core_l3_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* usb_l4_ick */
+static const struct clksel_rate usb_l4_ick_core_l3_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel usb_l4_ick_clksel[] = {
+	{ .parent = &core_l3_ck, .rates = usb_l4_ick_core_l3_rates },
+	{ .parent = NULL },
+};
+
+/* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */
+static struct clk usb_l4_ick = {	/* FS-USB interface clock */
+	.name		= "usb_l4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_USB_MASK,
+	.clksel		= usb_l4_ick_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * L4 clock management domain
+ *
+ * This domain contains lots of interface clocks from the L4 interface, some
+ * functional clocks.	Fixed APLL functional source clocks are managed in
+ * this domain.
+ */
+static const struct clksel_rate l4_core_l3_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel l4_clksel[] = {
+	{ .parent = &core_l3_ck, .rates = l4_core_l3_rates },
+	{ .parent = NULL }
+};
+
+static struct clk l4_ck = {		/* used both as an ick and fck */
+	.name		= "l4_ck",
+	.ops		= &clkops_null,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_L4_MASK,
+	.clksel		= l4_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * SSI is in L3 management domain, its direct parent is core not l3,
+ * many core power domain entities are grouped into the L3 clock
+ * domain.
+ * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_ICLK
+ *
+ * ssr = core/1/2/3/4/5, sst = 1/2 ssr.
+ */
+static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 5, .val = 5, .flags = RATE_IN_243X },
+	{ .div = 0 }
+};
+
+static const struct clksel ssi_ssr_sst_fck_clksel[] = {
+	{ .parent = &core_ck, .rates = ssi_ssr_sst_fck_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk ssi_ssr_sst_fck = {
+	.name		= "ssi_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_SSI_MASK,
+	.clksel		= ssi_ssr_sst_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * Presumably this is the same as SSI_ICLK.
+ * TRM contradicts itself on what clockdomain SSI_ICLK is in
+ */
+static struct clk ssi_l4_ick = {
+	.name		= "ssi_l4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+
+/*
+ * GFX clock domain
+ *	Clocks:
+ * GFX_FCLK, GFX_ICLK
+ * GFX_CG1(2d), GFX_CG2(3d)
+ *
+ * GFX_FCLK runs from L3, and is divided by (1,2,3,4)
+ * The 2d and 3d clocks run at a hardware determined
+ * divided value of fclk.
+ *
+ */
+
+/* This clksel struct is shared between gfx_3d_fck and gfx_2d_fck */
+static const struct clksel gfx_fck_clksel[] = {
+	{ .parent = &core_l3_ck, .rates = gfx_l3_rates },
+	{ .parent = NULL },
+};
+
+static struct clk gfx_3d_fck = {
+	.name		= "gfx_3d_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "gfx_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_3D_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
+	.clksel		= gfx_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static struct clk gfx_2d_fck = {
+	.name		= "gfx_2d_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "gfx_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_2D_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
+	.clksel		= gfx_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gfx_ick = {
+	.name		= "gfx_ick",		/* From l3 */
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "gfx_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP_EN_GFX_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * Modem clock domain (2430)
+ *	CLOCKS:
+ *		MDM_OSC_CLK
+ *		MDM_ICLK
+ * These clocks are usable in chassis mode only.
+ */
+static const struct clksel_rate mdm_ick_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_243X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_243X | DEFAULT_RATE },
+	{ .div = 6, .val = 6, .flags = RATE_IN_243X },
+	{ .div = 9, .val = 9, .flags = RATE_IN_243X },
+	{ .div = 0 }
+};
+
+static const struct clksel mdm_ick_clksel[] = {
+	{ .parent = &core_ck, .rates = mdm_ick_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk mdm_ick = {		/* used both as a ick and fck */
+	.name		= "mdm_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_ck,
+	.clkdm_name	= "mdm_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP2430_CLKSEL_MDM_MASK,
+	.clksel		= mdm_ick_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk mdm_osc_ck = {
+	.name		= "mdm_osc_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &osc_ck,
+	.clkdm_name	= "mdm_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP2430_EN_OSC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * DSS clock domain
+ * CLOCKs:
+ * DSS_L4_ICLK, DSS_L3_ICLK,
+ * DSS_CLK1, DSS_CLK2, DSS_54MHz_CLK
+ *
+ * DSS is both initiator and target.
+ */
+/* XXX Add RATE_NOT_VALIDATED */
+
+static const struct clksel_rate dss1_fck_sys_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate dss1_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 5, .val = 5, .flags = RATE_IN_24XX },
+	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
+	{ .div = 8, .val = 8, .flags = RATE_IN_24XX },
+	{ .div = 9, .val = 9, .flags = RATE_IN_24XX },
+	{ .div = 12, .val = 12, .flags = RATE_IN_24XX },
+	{ .div = 16, .val = 16, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel dss1_fck_clksel[] = {
+	{ .parent = &sys_ck,  .rates = dss1_fck_sys_rates },
+	{ .parent = &core_ck, .rates = dss1_fck_core_rates },
+	{ .parent = NULL },
+};
+
+static struct clk dss_ick = {		/* Enables both L3,L4 ICLK's */
+	.name		= "dss_ick",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &l4_ck,	/* really both l3 and l4 */
+	.clkdm_name	= "dss_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss1_fck = {
+	.name		= "dss1_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &core_ck,		/* Core or sys */
+	.clkdm_name	= "dss_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_DSS1_MASK,
+	.clksel		= dss1_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate dss2_fck_sys_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate dss2_fck_48m_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel dss2_fck_clksel[] = {
+	{ .parent = &sys_ck,	  .rates = dss2_fck_sys_rates },
+	{ .parent = &func_48m_ck, .rates = dss2_fck_48m_rates },
+	{ .parent = NULL }
+};
+
+static struct clk dss2_fck = {		/* Alt clk used in power management */
+	.name		= "dss2_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &sys_ck,		/* fixed at sys_ck or 48MHz */
+	.clkdm_name	= "dss_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_DSS2_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_DSS2_MASK,
+	.clksel		= dss2_fck_clksel,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss_54m_fck = {	/* Alt clk used in power management */
+	.name		= "dss_54m_fck",	/* 54m tv clk */
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_54m_ck,
+	.clkdm_name	= "dss_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_TV_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * CORE power domain ICLK & FCLK defines.
+ * Many of the these can have more than one possible parent. Entries
+ * here will likely have an L4 interface parent, and may have multiple
+ * functional clock parents.
+ */
+static const struct clksel_rate gpt_alt_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel omap24xx_gpt_clksel[] = {
+	{ .parent = &func_32k_ck, .rates = gpt_32k_rates },
+	{ .parent = &sys_ck,	  .rates = gpt_sys_rates },
+	{ .parent = &alt_ck,	  .rates = gpt_alt_rates },
+	{ .parent = NULL },
+};
+
+static struct clk gpt1_ick = {
+	.name		= "gpt1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt1_fck = {
+	.name		= "gpt1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT1_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static struct clk gpt2_ick = {
+	.name		= "gpt2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt2_fck = {
+	.name		= "gpt2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT2_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt3_ick = {
+	.name		= "gpt3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt3_fck = {
+	.name		= "gpt3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT3_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt4_ick = {
+	.name		= "gpt4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt4_fck = {
+	.name		= "gpt4_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT4_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt5_ick = {
+	.name		= "gpt5_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt5_fck = {
+	.name		= "gpt5_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT5_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt6_ick = {
+	.name		= "gpt6_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt6_fck = {
+	.name		= "gpt6_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT6_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt7_ick = {
+	.name		= "gpt7_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt7_fck = {
+	.name		= "gpt7_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT7_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt8_ick = {
+	.name		= "gpt8_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt8_fck = {
+	.name		= "gpt8_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT8_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt9_ick = {
+	.name		= "gpt9_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt9_fck = {
+	.name		= "gpt9_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT9_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt10_ick = {
+	.name		= "gpt10_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt10_fck = {
+	.name		= "gpt10_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT10_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt11_ick = {
+	.name		= "gpt11_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt11_fck = {
+	.name		= "gpt11_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT11_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt12_ick = {
+	.name		= "gpt12_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt12_fck = {
+	.name		= "gpt12_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &secure_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT12_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp1_ick = {
+	.name		= "mcbsp1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp1_fck = {
+	.name		= "mcbsp1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp2_ick = {
+	.name		= "mcbsp2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp2_fck = {
+	.name		= "mcbsp2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp3_ick = {
+	.name		= "mcbsp3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MCBSP3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp3_fck = {
+	.name		= "mcbsp3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MCBSP3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp4_ick = {
+	.name		= "mcbsp4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MCBSP4_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp4_fck = {
+	.name		= "mcbsp4_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MCBSP4_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp5_ick = {
+	.name		= "mcbsp5_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MCBSP5_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp5_fck = {
+	.name		= "mcbsp5_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MCBSP5_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi1_ick = {
+	.name		= "mcspi1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi1_fck = {
+	.name		= "mcspi1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi2_ick = {
+	.name		= "mcspi2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi2_fck = {
+	.name		= "mcspi2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi3_ick = {
+	.name		= "mcspi3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MCSPI3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi3_fck = {
+	.name		= "mcspi3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MCSPI3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart1_ick = {
+	.name		= "uart1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart1_fck = {
+	.name		= "uart1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart2_ick = {
+	.name		= "uart2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart2_fck = {
+	.name		= "uart2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart3_ick = {
+	.name		= "uart3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart3_fck = {
+	.name		= "uart3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpios_ick = {
+	.name		= "gpios_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpios_fck = {
+	.name		= "gpios_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mpu_wdt_ick = {
+	.name		= "mpu_wdt_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mpu_wdt_fck = {
+	.name		= "mpu_wdt_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sync_32k_ick = {
+	.name		= "sync_32k_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_32KSYNC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt1_ick = {
+	.name		= "wdt1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_WDT1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk omapctrl_ick = {
+	.name		= "omapctrl_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_OMAPCTRL_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk icr_ick = {
+	.name		= "icr_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP2430_EN_ICR_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk cam_ick = {
+	.name		= "cam_ick",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * cam_fck controls both CAM_MCLK and CAM_FCLK.  It should probably be
+ * split into two separate clocks, since the parent clocks are different
+ * and the clockdomains are also different.
+ */
+static struct clk cam_fck = {
+	.name		= "cam_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mailboxes_ick = {
+	.name		= "mailboxes_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MAILBOXES_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt4_ick = {
+	.name		= "wdt4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt4_fck = {
+	.name		= "wdt4_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mspro_ick = {
+	.name		= "mspro_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mspro_fck = {
+	.name		= "mspro_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk fac_ick = {
+	.name		= "fac_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk fac_fck = {
+	.name		= "fac_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_12m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hdq_ick = {
+	.name		= "hdq_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hdq_fck = {
+	.name		= "hdq_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_12m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * XXX This is marked as a 2420-only define, but it claims to be present
+ * on 2430 also.  Double-check.
+ */
+static struct clk i2c2_ick = {
+	.name		= "i2c2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2chs2_fck = {
+	.name		= "i2chs2_fck",
+	.ops		= &clkops_omap2430_i2chs_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_I2CHS2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * XXX This is marked as a 2420-only define, but it claims to be present
+ * on 2430 also.  Double-check.
+ */
+static struct clk i2c1_ick = {
+	.name		= "i2c1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2chs1_fck = {
+	.name		= "i2chs1_fck",
+	.ops		= &clkops_omap2430_i2chs_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_I2CHS1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpmc_fck = {
+	.name		= "gpmc_fck",
+	.ops		= &clkops_null, /* RMK: missing? */
+	.parent		= &core_l3_ck,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sdma_fck = {
+	.name		= "sdma_fck",
+	.ops		= &clkops_null, /* RMK: missing? */
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sdma_ick = {
+	.name		= "sdma_ick",
+	.ops		= &clkops_null, /* RMK: missing? */
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sdrc_ick = {
+	.name		= "sdrc_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP2430_EN_SDRC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk des_ick = {
+	.name		= "des_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_DES_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sha_ick = {
+	.name		= "sha_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_SHA_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk rng_ick = {
+	.name		= "rng_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_RNG_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk aes_ick = {
+	.name		= "aes_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_AES_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk pka_ick = {
+	.name		= "pka_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_PKA_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usb_fck = {
+	.name		= "usb_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usbhs_ick = {
+	.name		= "usbhs_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_USBHS_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs1_ick = {
+	.name		= "mmchs1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHS1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs1_fck = {
+	.name		= "mmchs1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHS1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs2_ick = {
+	.name		= "mmchs2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHS2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs2_fck = {
+	.name		= "mmchs2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHS2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio5_ick = {
+	.name		= "gpio5_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_GPIO5_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio5_fck = {
+	.name		= "gpio5_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_GPIO5_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mdm_intc_ick = {
+	.name		= "mdm_intc_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MDM_INTC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchsdb1_fck = {
+	.name		= "mmchsdb1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHSDB1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchsdb2_fck = {
+	.name		= "mmchsdb2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHSDB2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * This clock is a composite clock which does entire set changes then
+ * forces a rebalance. It keys on the MPU speed, but it really could
+ * be any key speed part of a set in the rate table.
+ *
+ * to really change a set, you need memory table sets which get changed
+ * in sram, pre-notifiers & post notifiers, changing the top set, without
+ * having low level display recalc's won't work... this is why dpm notifiers
+ * work, isr's off, walk a list of clocks already _off_ and not messing with
+ * the bus.
+ *
+ * This clock should have no parent. It embodies the entire upper level
+ * active set. A parent will mess up some of the init also.
+ */
+static struct clk virt_prcm_set = {
+	.name		= "virt_prcm_set",
+	.ops		= &clkops_null,
+	.parent		= &mpu_ck,	/* Indexed by mpu speed, no parent */
+	.recalc		= &omap2_table_mpu_recalc,	/* sets are keyed on mpu rate */
+	.set_rate	= &omap2_select_table_rate,
+	.round_rate	= &omap2_round_to_table_rate,
+};
+
+
+/*
+ * clkdev integration
+ */
+
+static struct omap_clk omap2430_clks[] = {
+	/* external root sources */
+	CLK(NULL,	"func_32k_ck",	&func_32k_ck,	CK_243X),
+	CLK(NULL,	"secure_32k_ck", &secure_32k_ck, CK_243X),
+	CLK(NULL,	"osc_ck",	&osc_ck,	CK_243X),
+	CLK(NULL,	"sys_ck",	&sys_ck,	CK_243X),
+	CLK(NULL,	"alt_ck",	&alt_ck,	CK_243X),
+	/* internal analog sources */
+	CLK(NULL,	"dpll_ck",	&dpll_ck,	CK_243X),
+	CLK(NULL,	"apll96_ck",	&apll96_ck,	CK_243X),
+	CLK(NULL,	"apll54_ck",	&apll54_ck,	CK_243X),
+	/* internal prcm root sources */
+	CLK(NULL,	"func_54m_ck",	&func_54m_ck,	CK_243X),
+	CLK(NULL,	"core_ck",	&core_ck,	CK_243X),
+	CLK(NULL,	"func_96m_ck",	&func_96m_ck,	CK_243X),
+	CLK(NULL,	"func_48m_ck",	&func_48m_ck,	CK_243X),
+	CLK(NULL,	"func_12m_ck",	&func_12m_ck,	CK_243X),
+	CLK(NULL,	"ck_wdt1_osc",	&wdt1_osc_ck,	CK_243X),
+	CLK(NULL,	"sys_clkout_src", &sys_clkout_src, CK_243X),
+	CLK(NULL,	"sys_clkout",	&sys_clkout,	CK_243X),
+	CLK(NULL,	"emul_ck",	&emul_ck,	CK_243X),
+	/* mpu domain clocks */
+	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_243X),
+	/* dsp domain clocks */
+	CLK(NULL,	"dsp_fck",	&dsp_fck,	CK_243X),
+	CLK(NULL,	"dsp_irate_ick", &dsp_irate_ick, CK_243X),
+	CLK(NULL,	"iva2_1_ick",	&iva2_1_ick,	CK_243X),
+	/* GFX domain clocks */
+	CLK(NULL,	"gfx_3d_fck",	&gfx_3d_fck,	CK_243X),
+	CLK(NULL,	"gfx_2d_fck",	&gfx_2d_fck,	CK_243X),
+	CLK(NULL,	"gfx_ick",	&gfx_ick,	CK_243X),
+	/* Modem domain clocks */
+	CLK(NULL,	"mdm_ick",	&mdm_ick,	CK_243X),
+	CLK(NULL,	"mdm_osc_ck",	&mdm_osc_ck,	CK_243X),
+	/* DSS domain clocks */
+	CLK("omapdss",	"ick",		&dss_ick,	CK_243X),
+	CLK("omapdss",	"dss1_fck",	&dss1_fck,	CK_243X),
+	CLK("omapdss",	"dss2_fck",	&dss2_fck,	CK_243X),
+	CLK("omapdss",	"tv_fck",	&dss_54m_fck,	CK_243X),
+	/* L3 domain clocks */
+	CLK(NULL,	"core_l3_ck",	&core_l3_ck,	CK_243X),
+	CLK(NULL,	"ssi_fck",	&ssi_ssr_sst_fck, CK_243X),
+	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick,	CK_243X),
+	/* L4 domain clocks */
+	CLK(NULL,	"l4_ck",	&l4_ck,		CK_243X),
+	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_243X),
+	/* virtual meta-group clock */
+	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_243X),
+	/* general l4 interface ck, multi-parent functional clk */
+	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_243X),
+	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_243X),
+	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_243X),
+	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_243X),
+	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_243X),
+	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_243X),
+	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_243X),
+	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_243X),
+	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_243X),
+	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_243X),
+	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_243X),
+	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_243X),
+	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_243X),
+	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_243X),
+	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_243X),
+	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_243X),
+	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_243X),
+	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_243X),
+	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_243X),
+	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_243X),
+	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_243X),
+	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_243X),
+	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_243X),
+	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_243X),
+	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_243X),
+	CLK("omap-mcbsp.1", "fck",	&mcbsp1_fck,	CK_243X),
+	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_243X),
+	CLK("omap-mcbsp.2", "fck",	&mcbsp2_fck,	CK_243X),
+	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),
+	CLK("omap2_mcspi.1", "fck",	&mcspi1_fck,	CK_243X),
+	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick,	CK_243X),
+	CLK("omap2_mcspi.2", "fck",	&mcspi2_fck,	CK_243X),
+	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),
+	CLK(NULL,	"uart1_fck",	&uart1_fck,	CK_243X),
+	CLK(NULL,	"uart2_ick",	&uart2_ick,	CK_243X),
+	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_243X),
+	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_243X),
+	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_243X),
+	CLK(NULL,	"gpios_ick",	&gpios_ick,	CK_243X),
+	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_243X),
+	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_243X),
+	CLK("omap_wdt",	"fck",		&mpu_wdt_fck,	CK_243X),
+	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_243X),
+	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_243X),
+	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_243X),
+	CLK(NULL,	"icr_ick",	&icr_ick,	CK_243X),
+	CLK("omap24xxcam", "fck",	&cam_fck,	CK_243X),
+	CLK("omap24xxcam", "ick",	&cam_ick,	CK_243X),
+	CLK(NULL,	"mailboxes_ick", &mailboxes_ick,	CK_243X),
+	CLK(NULL,	"wdt4_ick",	&wdt4_ick,	CK_243X),
+	CLK(NULL,	"wdt4_fck",	&wdt4_fck,	CK_243X),
+	CLK(NULL,	"mspro_ick",	&mspro_ick,	CK_243X),
+	CLK(NULL,	"mspro_fck",	&mspro_fck,	CK_243X),
+	CLK(NULL,	"fac_ick",	&fac_ick,	CK_243X),
+	CLK(NULL,	"fac_fck",	&fac_fck,	CK_243X),
+	CLK("omap_hdq.0", "ick",	&hdq_ick,	CK_243X),
+	CLK("omap_hdq.1", "fck",	&hdq_fck,	CK_243X),
+	CLK("i2c_omap.1", "ick",	&i2c1_ick,	CK_243X),
+	CLK("i2c_omap.1", "fck",	&i2chs1_fck,	CK_243X),
+	CLK("i2c_omap.2", "ick",	&i2c2_ick,	CK_243X),
+	CLK("i2c_omap.2", "fck",	&i2chs2_fck,	CK_243X),
+	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_243X),
+	CLK(NULL,	"sdma_fck",	&sdma_fck,	CK_243X),
+	CLK(NULL,	"sdma_ick",	&sdma_ick,	CK_243X),
+	CLK(NULL,	"sdrc_ick",	&sdrc_ick,	CK_243X),
+	CLK(NULL,	"des_ick",	&des_ick,	CK_243X),
+	CLK(NULL,	"sha_ick",	&sha_ick,	CK_243X),
+	CLK("omap_rng",	"ick",		&rng_ick,	CK_243X),
+	CLK(NULL,	"aes_ick",	&aes_ick,	CK_243X),
+	CLK(NULL,	"pka_ick",	&pka_ick,	CK_243X),
+	CLK(NULL,	"usb_fck",	&usb_fck,	CK_243X),
+	CLK("musb_hdrc",	"ick",	&usbhs_ick,	CK_243X),
+	CLK("mmci-omap-hs.0", "ick",	&mmchs1_ick,	CK_243X),
+	CLK("mmci-omap-hs.0", "fck",	&mmchs1_fck,	CK_243X),
+	CLK("mmci-omap-hs.1", "ick",	&mmchs2_ick,	CK_243X),
+	CLK("mmci-omap-hs.1", "fck",	&mmchs2_fck,	CK_243X),
+	CLK(NULL,	"gpio5_ick",	&gpio5_ick,	CK_243X),
+	CLK(NULL,	"gpio5_fck",	&gpio5_fck,	CK_243X),
+	CLK(NULL,	"mdm_intc_ick",	&mdm_intc_ick,	CK_243X),
+	CLK("mmci-omap-hs.0", "mmchsdb_fck",	&mmchsdb1_fck,	CK_243X),
+	CLK("mmci-omap-hs.1", "mmchsdb_fck", 	&mmchsdb2_fck,	CK_243X),
+};
+
+/*
+ * init code
+ */
+
+int __init omap2430_clk_init(void)
+{
+	const struct prcm_config *prcm;
+	struct omap_clk *c;
+	u32 clkrate;
+
+	prcm_clksrc_ctrl = OMAP2430_PRCM_CLKSRC_CTRL;
+	cm_idlest_pll = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST);
+	cpu_mask = RATE_IN_243X;
+	rate_table = omap2430_rate_table;
+
+	clk_init(&omap2_clk_functions);
+
+	for (c = omap2430_clks; c < omap2430_clks + ARRAY_SIZE(omap2430_clks);
+	     c++)
+		clk_preinit(c->lk.clk);
+
+	osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
+	propagate_rate(&osc_ck);
+	sys_ck.rate = omap2xxx_sys_clk_recalc(&sys_ck);
+	propagate_rate(&sys_ck);
+
+	for (c = omap2430_clks; c < omap2430_clks + ARRAY_SIZE(omap2430_clks);
+	     c++) {
+		clkdev_add(&c->lk);
+		clk_register(c->lk.clk);
+		omap2_init_clk_clkdm(c->lk.clk);
+	}
+
+	/* Check the MPU rate set by bootloader */
+	clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
+	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+		if (!(prcm->flags & cpu_mask))
+			continue;
+		if (prcm->xtal_speed != sys_ck.rate)
+			continue;
+		if (prcm->dpll_speed <= clkrate)
+			break;
+	}
+	curr_prcm_set = prcm;
+
+	recalculate_root_clocks();
+
+	pr_info("Clocking rate (Crystal/DPLL/MPU): %ld.%01ld/%ld/%ld MHz\n",
+		(sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
+		(dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
+
+	/*
+	 * Only enable those clocks we will need, let the drivers
+	 * enable other clocks as necessary
+	 */
+	clk_enable_init_clocks();
+
+	/* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */
+	vclk = clk_get(NULL, "virt_prcm_set");
+	sclk = clk_get(NULL, "sys_ck");
+	dclk = clk_get(NULL, "dpll_ck");
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2xxx.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock2xxx.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2xxx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock2xxx.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,15 +1,15 @@
 /*
- *  linux/arch/arm/mach-omap2/clock.c
+ * clock2xxx.c - OMAP2xxx-specific clock integration code
  *
- *  Copyright (C) 2005-2008 Texas Instruments, Inc.
- *  Copyright (C) 2004-2008 Nokia Corporation
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
  *
- *  Contacts:
- *  Richard Woodruff <r-woodruff2@ti.com>
- *  Paul Walmsley
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
  *
- *  Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
- *  Gordon McNutt and RidgeRun, Inc.
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -17,568 +17,28 @@
  */
 #undef DEBUG
 
-#include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/list.h>
 #include <linux/errno.h>
-#include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/io.h>
-#include <linux/cpufreq.h>
-#include <linux/bitops.h>
 
 #include <plat/clock.h>
-#include <plat/sram.h>
-#include <plat/prcm.h>
-#include <plat/clkdev_omap.h>
-#include <asm/div64.h>
-#include <asm/clkdev.h>
 
-#include <plat/sdrc.h>
 #include "clock.h"
 #include "clock2xxx.h"
-#include "opp2xxx.h"
-#include "prm.h"
-#include "prm-regbits-24xx.h"
 #include "cm.h"
 #include "cm-regbits-24xx.h"
 
-
-/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
-#define EN_APLL_STOPPED			0
-#define EN_APLL_LOCKED			3
-
-/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
-#define APLLS_CLKIN_19_2MHZ		0
-#define APLLS_CLKIN_13MHZ		2
-#define APLLS_CLKIN_12MHZ		3
-
-/* #define DOWN_VARIABLE_DPLL 1 */		/* Experimental */
-
-const struct prcm_config *curr_prcm_set;
-const struct prcm_config *rate_table;
-
 struct clk *vclk, *sclk, *dclk;
 
-void __iomem *prcm_clksrc_ctrl;
-
-/*-------------------------------------------------------------------------
- * Omap24xx specific clock functions
- *-------------------------------------------------------------------------*/
-
-/**
- * omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS
- * @clk: struct clk * being enabled
- * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
- * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
- *
- * OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the
- * CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE.  This custom function
- * passes back the correct CM_IDLEST register address for I2CHS
- * modules.  No return value.
- */
-static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
-					   void __iomem **idlest_reg,
-					   u8 *idlest_bit)
-{
-	*idlest_reg = OMAP_CM_REGADDR(CORE_MOD, CM_IDLEST);
-	*idlest_bit = clk->enable_bit;
-}
-
-/* 2430 I2CHS has non-standard IDLEST register */
-const struct clkops clkops_omap2430_i2chs_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
-	.find_idlest	= omap2430_clk_i2chs_find_idlest,
-	.find_companion = omap2_clk_dflt_find_companion,
-};
-
-/**
- * omap2xxx_clk_get_core_rate - return the CORE_CLK rate
- * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
- *
- * Returns the CORE_CLK rate.  CORE_CLK can have one of three rate
- * sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
- * (the latter is unusual).  This currently should be called with
- * struct clk *dpll_ck, which is a composite clock of dpll_ck and
- * core_ck.
- */
-unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
-{
-	long long core_clk;
-	u32 v;
-
-	core_clk = omap2_get_dpll_rate(clk);
-
-	v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
-	v &= OMAP24XX_CORE_CLK_SRC_MASK;
-
-	if (v == CORE_CLK_SRC_32K)
-		core_clk = 32768;
-	else
-		core_clk *= v;
-
-	return core_clk;
-}
-
-static int omap2_enable_osc_ck(struct clk *clk)
-{
-	u32 pcc;
-
-	pcc = __raw_readl(prcm_clksrc_ctrl);
-
-	__raw_writel(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
-
-	return 0;
-}
-
-static void omap2_disable_osc_ck(struct clk *clk)
-{
-	u32 pcc;
-
-	pcc = __raw_readl(prcm_clksrc_ctrl);
-
-	__raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
-}
-
-const struct clkops clkops_oscck = {
-	.enable		= omap2_enable_osc_ck,
-	.disable	= omap2_disable_osc_ck,
-};
-
-#ifdef OLD_CK
-/* Recalculate SYST_CLK */
-static void omap2_sys_clk_recalc(struct clk *clk)
-{
-	u32 div = PRCM_CLKSRC_CTRL;
-	div &= (1 << 7) | (1 << 6);	/* Test if ext clk divided by 1 or 2 */
-	div >>= clk->rate_offset;
-	clk->rate = (clk->parent->rate / div);
-	propagate_rate(clk);
-}
-#endif	/* OLD_CK */
-
-/* Enable an APLL if off */
-static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
-{
-	u32 cval, apll_mask;
-
-	apll_mask = EN_APLL_LOCKED << clk->enable_bit;
-
-	cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
-
-	if ((cval & apll_mask) == apll_mask)
-		return 0;   /* apll already enabled */
-
-	cval &= ~apll_mask;
-	cval |= apll_mask;
-	cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
-
-	omap2_cm_wait_idlest(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), status_mask,
-			     clk->name);
-
-	/*
-	 * REVISIT: Should we return an error code if omap2_wait_clock_ready()
-	 * fails?
-	 */
-	return 0;
-}
-
-static int omap2_clk_apll96_enable(struct clk *clk)
-{
-	return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL);
-}
-
-static int omap2_clk_apll54_enable(struct clk *clk)
-{
-	return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL);
-}
-
-/* Stop APLL */
-static void omap2_clk_apll_disable(struct clk *clk)
-{
-	u32 cval;
-
-	cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
-	cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
-	cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
-}
-
-const struct clkops clkops_apll96 = {
-	.enable		= omap2_clk_apll96_enable,
-	.disable	= omap2_clk_apll_disable,
-};
-
-const struct clkops clkops_apll54 = {
-	.enable		= omap2_clk_apll54_enable,
-	.disable	= omap2_clk_apll_disable,
-};
-
 /*
- * Uses the current prcm set to tell if a rate is valid.
- * You can go slower, but not faster within a given rate set.
- */
-long omap2_dpllcore_round_rate(unsigned long target_rate)
-{
-	u32 high, low, core_clk_src;
-
-	core_clk_src = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
-	core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
-
-	if (core_clk_src == CORE_CLK_SRC_DPLL) {	/* DPLL clockout */
-		high = curr_prcm_set->dpll_speed * 2;
-		low = curr_prcm_set->dpll_speed;
-	} else {				/* DPLL clockout x 2 */
-		high = curr_prcm_set->dpll_speed;
-		low = curr_prcm_set->dpll_speed / 2;
-	}
-
-#ifdef DOWN_VARIABLE_DPLL
-	if (target_rate > high)
-		return high;
-	else
-		return target_rate;
-#else
-	if (target_rate > low)
-		return high;
-	else
-		return low;
-#endif
-
-}
-
-unsigned long omap2_dpllcore_recalc(struct clk *clk)
-{
-	return omap2xxx_clk_get_core_rate(clk);
-}
-
-int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
-{
-	u32 cur_rate, low, mult, div, valid_rate, done_rate;
-	u32 bypass = 0;
-	struct prcm_config tmpset;
-	const struct dpll_data *dd;
-
-	cur_rate = omap2xxx_clk_get_core_rate(dclk);
-	mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
-	mult &= OMAP24XX_CORE_CLK_SRC_MASK;
-
-	if ((rate == (cur_rate / 2)) && (mult == 2)) {
-		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
-	} else if ((rate == (cur_rate * 2)) && (mult == 1)) {
-		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
-	} else if (rate != cur_rate) {
-		valid_rate = omap2_dpllcore_round_rate(rate);
-		if (valid_rate != rate)
-			return -EINVAL;
-
-		if (mult == 1)
-			low = curr_prcm_set->dpll_speed;
-		else
-			low = curr_prcm_set->dpll_speed / 2;
-
-		dd = clk->dpll_data;
-		if (!dd)
-			return -EINVAL;
-
-		tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg);
-		tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
-					   dd->div1_mask);
-		div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
-		tmpset.cm_clksel2_pll = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
-		tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
-		if (rate > low) {
-			tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
-			mult = ((rate / 2) / 1000000);
-			done_rate = CORE_CLK_SRC_DPLL_X2;
-		} else {
-			tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL;
-			mult = (rate / 1000000);
-			done_rate = CORE_CLK_SRC_DPLL;
-		}
-		tmpset.cm_clksel1_pll |= (div << __ffs(dd->mult_mask));
-		tmpset.cm_clksel1_pll |= (mult << __ffs(dd->div1_mask));
-
-		/* Worst case */
-		tmpset.base_sdrc_rfr = SDRC_RFR_CTRL_BYPASS;
-
-		if (rate == curr_prcm_set->xtal_speed)	/* If asking for 1-1 */
-			bypass = 1;
-
-		/* For omap2xxx_sdrc_init_params() */
-		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
-
-		/* Force dll lock mode */
-		omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
-			       bypass);
-
-		/* Errata: ret dll entry state */
-		omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
-		omap2xxx_sdrc_reprogram(done_rate, 0);
-	}
-
-	return 0;
-}
-
-/**
- * omap2_table_mpu_recalc - just return the MPU speed
- * @clk: virt_prcm_set struct clk
- *
- * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
- */
-unsigned long omap2_table_mpu_recalc(struct clk *clk)
-{
-	return curr_prcm_set->mpu_speed;
-}
-
-/*
- * Look for a rate equal or less than the target rate given a configuration set.
- *
- * What's not entirely clear is "which" field represents the key field.
- * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
- * just uses the ARM rates.
+ * Omap24xx specific clock functions
  */
-long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
-{
-	const struct prcm_config *ptr;
-	long highest_rate;
-	long sys_ck_rate;
-
-	sys_ck_rate = clk_get_rate(sclk);
-
-	highest_rate = -EINVAL;
-
-	for (ptr = rate_table; ptr->mpu_speed; ptr++) {
-		if (!(ptr->flags & cpu_mask))
-			continue;
-		if (ptr->xtal_speed != sys_ck_rate)
-			continue;
-
-		highest_rate = ptr->mpu_speed;
-
-		/* Can check only after xtal frequency check */
-		if (ptr->mpu_speed <= rate)
-			break;
-	}
-	return highest_rate;
-}
-
-/* Sets basic clocks based on the specified rate */
-int omap2_select_table_rate(struct clk *clk, unsigned long rate)
-{
-	u32 cur_rate, done_rate, bypass = 0, tmp;
-	const struct prcm_config *prcm;
-	unsigned long found_speed = 0;
-	unsigned long flags;
-	long sys_ck_rate;
-
-	sys_ck_rate = clk_get_rate(sclk);
-
-	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
-		if (!(prcm->flags & cpu_mask))
-			continue;
-
-		if (prcm->xtal_speed != sys_ck_rate)
-			continue;
-
-		if (prcm->mpu_speed <= rate) {
-			found_speed = prcm->mpu_speed;
-			break;
-		}
-	}
-
-	if (!found_speed) {
-		printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
-		       rate / 1000000);
-		return -EINVAL;
-	}
-
-	curr_prcm_set = prcm;
-	cur_rate = omap2xxx_clk_get_core_rate(dclk);
-
-	if (prcm->dpll_speed == cur_rate / 2) {
-		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
-	} else if (prcm->dpll_speed == cur_rate * 2) {
-		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
-	} else if (prcm->dpll_speed != cur_rate) {
-		local_irq_save(flags);
-
-		if (prcm->dpll_speed == prcm->xtal_speed)
-			bypass = 1;
-
-		if ((prcm->cm_clksel2_pll & OMAP24XX_CORE_CLK_SRC_MASK) ==
-		    CORE_CLK_SRC_DPLL_X2)
-			done_rate = CORE_CLK_SRC_DPLL_X2;
-		else
-			done_rate = CORE_CLK_SRC_DPLL;
-
-		/* MPU divider */
-		cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);
-
-		/* dsp + iva1 div(2420), iva2.1(2430) */
-		cm_write_mod_reg(prcm->cm_clksel_dsp,
-				 OMAP24XX_DSP_MOD, CM_CLKSEL);
-
-		cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);
-
-		/* Major subsystem dividers */
-		tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
-		cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
-				 CM_CLKSEL1);
-
-		if (cpu_is_omap2430())
-			cm_write_mod_reg(prcm->cm_clksel_mdm,
-					 OMAP2430_MDM_MOD, CM_CLKSEL);
-
-		/* x2 to enter omap2xxx_sdrc_init_params() */
-		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
-
-		omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
-			       bypass);
-
-		omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
-		omap2xxx_sdrc_reprogram(done_rate, 0);
-
-		local_irq_restore(flags);
-	}
-
-	return 0;
-}
-
-#ifdef CONFIG_CPU_FREQ
-/*
- * Walk PRCM rate table and fillout cpufreq freq_table
- * XXX This should be replaced by an OPP layer in the near future
- */
-static struct cpufreq_frequency_table *freq_table;
-
-void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
-{
-	const struct prcm_config *prcm;
-	long sys_ck_rate;
-	int i = 0;
-	int tbl_sz = 0;
-
-	sys_ck_rate = clk_get_rate(sclk);
-
-	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
-		if (!(prcm->flags & cpu_mask))
-			continue;
-		if (prcm->xtal_speed != sys_ck_rate)
-			continue;
-
-		/* don't put bypass rates in table */
-		if (prcm->dpll_speed == prcm->xtal_speed)
-			continue;
-
-		tbl_sz++;
-	}
-
-	/*
-	 * XXX Ensure that we're doing what CPUFreq expects for this error
-	 * case and the following one
-	 */
-	if (tbl_sz == 0) {
-		pr_warning("%s: no matching entries in rate_table\n",
-			   __func__);
-		return;
-	}
-
-	/* Include the CPUFREQ_TABLE_END terminator entry */
-	tbl_sz++;
-
-	freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz,
-			     GFP_ATOMIC);
-	if (!freq_table) {
-		pr_err("%s: could not kzalloc frequency table\n", __func__);
-		return;
-	}
-
-	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
-		if (!(prcm->flags & cpu_mask))
-			continue;
-		if (prcm->xtal_speed != sys_ck_rate)
-			continue;
-
-		/* don't put bypass rates in table */
-		if (prcm->dpll_speed == prcm->xtal_speed)
-			continue;
-
-		freq_table[i].index = i;
-		freq_table[i].frequency = prcm->mpu_speed / 1000;
-		i++;
-	}
-
-	freq_table[i].index = i;
-	freq_table[i].frequency = CPUFREQ_TABLE_END;
-
-	*table = &freq_table[0];
-}
-
-void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
-{
-	kfree(freq_table);
-}
-
-#endif
-
-struct clk_functions omap2_clk_functions = {
-	.clk_enable		= omap2_clk_enable,
-	.clk_disable		= omap2_clk_disable,
-	.clk_round_rate		= omap2_clk_round_rate,
-	.clk_set_rate		= omap2_clk_set_rate,
-	.clk_set_parent		= omap2_clk_set_parent,
-	.clk_disable_unused	= omap2_clk_disable_unused,
-#ifdef	CONFIG_CPU_FREQ
-	.clk_init_cpufreq_table	= omap2_clk_init_cpufreq_table,
-	.clk_exit_cpufreq_table	= omap2_clk_exit_cpufreq_table,
-#endif
-};
-
-static u32 omap2_get_apll_clkin(void)
-{
-	u32 aplls, srate = 0;
-
-	aplls = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
-	aplls &= OMAP24XX_APLLS_CLKIN_MASK;
-	aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
-
-	if (aplls == APLLS_CLKIN_19_2MHZ)
-		srate = 19200000;
-	else if (aplls == APLLS_CLKIN_13MHZ)
-		srate = 13000000;
-	else if (aplls == APLLS_CLKIN_12MHZ)
-		srate = 12000000;
-
-	return srate;
-}
-
-static u32 omap2_get_sysclkdiv(void)
-{
-	u32 div;
-
-	div = __raw_readl(prcm_clksrc_ctrl);
-	div &= OMAP_SYSCLKDIV_MASK;
-	div >>= OMAP_SYSCLKDIV_SHIFT;
-
-	return div;
-}
-
-unsigned long omap2_osc_clk_recalc(struct clk *clk)
-{
-	return omap2_get_apll_clkin() * omap2_get_sysclkdiv();
-}
-
-unsigned long omap2_sys_clk_recalc(struct clk *clk)
-{
-	return clk->parent->rate / omap2_get_sysclkdiv();
-}
 
 /*
  * Set clocks for bypass mode for reboot to work.
  */
-void omap2_clk_prepare_for_reboot(void)
+void omap2xxx_clk_prepare_for_reboot(void)
 {
 	u32 rate;
 
@@ -590,37 +50,24 @@ void omap2_clk_prepare_for_reboot(void)
 }
 
 /*
- * Switch the MPU rate if specified on cmdline.
- * We cannot do this early until cmdline is parsed.
+ * Switch the MPU rate if specified on cmdline.  We cannot do this
+ * early until cmdline is parsed.  XXX This should be removed from the
+ * clock code and handled by the OPP layer code in the near future.
  */
-static int __init omap2_clk_arch_init(void)
+static int __init omap2xxx_clk_arch_init(void)
 {
-	struct clk *virt_prcm_set, *sys_ck, *dpll_ck, *mpu_ck;
-	unsigned long sys_ck_rate;
-
-	if (!mpurate)
-		return -EINVAL;
-
-	virt_prcm_set = clk_get(NULL, "virt_prcm_set");
-	sys_ck = clk_get(NULL, "sys_ck");
-	dpll_ck = clk_get(NULL, "dpll_ck");
-	mpu_ck = clk_get(NULL, "mpu_ck");
-
-	if (clk_set_rate(virt_prcm_set, mpurate))
-		printk(KERN_ERR "Could not find matching MPU rate\n");
-
-	recalculate_root_clocks();
+	int ret;
 
-	sys_ck_rate = clk_get_rate(sys_ck);
+	if (!cpu_is_omap24xx())
+		return 0;
 
-	pr_info("Switched to new clocking rate (Crystal/DPLL/MPU): "
-		"%ld.%01ld/%ld/%ld MHz\n",
-		(sys_ck_rate / 1000000), (sys_ck_rate / 100000) % 10,
-		(clk_get_rate(dpll_ck) / 1000000),
-		(clk_get_rate(mpu_ck) / 1000000));
+	ret = omap2_clk_switch_mpurate_at_boot("virt_prcm_set");
+	if (!ret)
+		omap2_clk_print_new_rates("sys_ck", "dpll_ck", "mpu_ck");
 
-	return 0;
+	return ret;
 }
-arch_initcall(omap2_clk_arch_init);
+
+arch_initcall(omap2xxx_clk_arch_init);
 
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2xxx_data.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock2xxx_data.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2xxx_data.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock2xxx_data.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2309 +0,0 @@
-/*
- *  linux/arch/arm/mach-omap2/clock2xxx_data.c
- *
- *  Copyright (C) 2005-2009 Texas Instruments, Inc.
- *  Copyright (C) 2004-2009 Nokia Corporation
- *
- *  Contacts:
- *  Richard Woodruff <r-woodruff2@ti.com>
- *  Paul Walmsley
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/clk.h>
-
-#include <plat/clkdev_omap.h>
-
-#include "clock.h"
-#include "clock2xxx.h"
-#include "opp2xxx.h"
-#include "prm.h"
-#include "cm.h"
-#include "prm-regbits-24xx.h"
-#include "cm-regbits-24xx.h"
-#include "sdrc.h"
-
-/*-------------------------------------------------------------------------
- * 24xx clock tree.
- *
- * NOTE:In many cases here we are assigning a 'default' parent.	In many
- *	cases the parent is selectable.	The get/set parent calls will also
- *	switch sources.
- *
- *	Many some clocks say always_enabled, but they can be auto idled for
- *	power savings. They will always be available upon clock request.
- *
- *	Several sources are given initial rates which may be wrong, this will
- *	be fixed up in the init func.
- *
- *	Things are broadly separated below by clock domains. It is
- *	noteworthy that most periferals have dependencies on multiple clock
- *	domains. Many get their interface clocks from the L4 domain, but get
- *	functional clocks from fixed sources or other core domain derived
- *	clocks.
- *-------------------------------------------------------------------------*/
-
-/* Base external input clocks */
-static struct clk func_32k_ck = {
-	.name		= "func_32k_ck",
-	.ops		= &clkops_null,
-	.rate		= 32000,
-	.flags		= RATE_FIXED,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-static struct clk secure_32k_ck = {
-	.name		= "secure_32k_ck",
-	.ops		= &clkops_null,
-	.rate		= 32768,
-	.flags		= RATE_FIXED,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
-static struct clk osc_ck = {		/* (*12, *13, 19.2, *26, 38.4)MHz */
-	.name		= "osc_ck",
-	.ops		= &clkops_oscck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2_osc_clk_recalc,
-};
-
-/* Without modem likely 12MHz, with modem likely 13MHz */
-static struct clk sys_ck = {		/* (*12, *13, 19.2, 26, 38.4)MHz */
-	.name		= "sys_ck",		/* ~ ref_clk also */
-	.ops		= &clkops_null,
-	.parent		= &osc_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2_sys_clk_recalc,
-};
-
-static struct clk alt_ck = {		/* Typical 54M or 48M, may not exist */
-	.name		= "alt_ck",
-	.ops		= &clkops_null,
-	.rate		= 54000000,
-	.flags		= RATE_FIXED,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-/*
- * Analog domain root source clocks
- */
-
-/* dpll_ck, is broken out in to special cases through clksel */
-/* REVISIT: Rate changes on dpll_ck trigger a full set change.	...
- * deal with this
- */
-
-static struct dpll_data dpll_dd = {
-	.mult_div1_reg		= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.mult_mask		= OMAP24XX_DPLL_MULT_MASK,
-	.div1_mask		= OMAP24XX_DPLL_DIV_MASK,
-	.clk_bypass		= &sys_ck,
-	.clk_ref		= &sys_ck,
-	.control_reg		= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_mask		= OMAP24XX_EN_DPLL_MASK,
-	.max_multiplier		= 1024,
-	.min_divider		= 1,
-	.max_divider		= 16,
-	.rate_tolerance		= DEFAULT_DPLL_RATE_TOLERANCE
-};
-
-/*
- * XXX Cannot add round_rate here yet, as this is still a composite clock,
- * not just a DPLL
- */
-static struct clk dpll_ck = {
-	.name		= "dpll_ck",
-	.ops		= &clkops_null,
-	.parent		= &sys_ck,		/* Can be func_32k also */
-	.dpll_data	= &dpll_dd,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2_dpllcore_recalc,
-	.set_rate	= &omap2_reprogram_dpllcore,
-};
-
-static struct clk apll96_ck = {
-	.name		= "apll96_ck",
-	.ops		= &clkops_apll96,
-	.parent		= &sys_ck,
-	.rate		= 96000000,
-	.flags		= RATE_FIXED | ENABLE_ON_INIT,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP24XX_EN_96M_PLL_SHIFT,
-};
-
-static struct clk apll54_ck = {
-	.name		= "apll54_ck",
-	.ops		= &clkops_apll54,
-	.parent		= &sys_ck,
-	.rate		= 54000000,
-	.flags		= RATE_FIXED | ENABLE_ON_INIT,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP24XX_EN_54M_PLL_SHIFT,
-};
-
-/*
- * PRCM digital base sources
- */
-
-/* func_54m_ck */
-
-static const struct clksel_rate func_54m_apll54_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate func_54m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel func_54m_clksel[] = {
-	{ .parent = &apll54_ck, .rates = func_54m_apll54_rates, },
-	{ .parent = &alt_ck,	.rates = func_54m_alt_rates, },
-	{ .parent = NULL },
-};
-
-static struct clk func_54m_ck = {
-	.name		= "func_54m_ck",
-	.ops		= &clkops_null,
-	.parent		= &apll54_ck,	/* can also be alt_clk */
-	.clkdm_name	= "wkup_clkdm",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_54M_SOURCE,
-	.clksel		= func_54m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk core_ck = {
-	.name		= "core_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll_ck,		/* can also be 32k */
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* func_96m_ck */
-static const struct clksel_rate func_96m_apll96_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate func_96m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_243X | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel func_96m_clksel[] = {
-	{ .parent = &apll96_ck,	.rates = func_96m_apll96_rates },
-	{ .parent = &alt_ck,	.rates = func_96m_alt_rates },
-	{ .parent = NULL }
-};
-
-/* The parent of this clock is not selectable on 2420. */
-static struct clk func_96m_ck = {
-	.name		= "func_96m_ck",
-	.ops		= &clkops_null,
-	.parent		= &apll96_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP2430_96M_SOURCE,
-	.clksel		= func_96m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/* func_48m_ck */
-
-static const struct clksel_rate func_48m_apll96_rates[] = {
-	{ .div = 2, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate func_48m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel func_48m_clksel[] = {
-	{ .parent = &apll96_ck,	.rates = func_48m_apll96_rates },
-	{ .parent = &alt_ck, .rates = func_48m_alt_rates },
-	{ .parent = NULL }
-};
-
-static struct clk func_48m_ck = {
-	.name		= "func_48m_ck",
-	.ops		= &clkops_null,
-	.parent		= &apll96_ck,	 /* 96M or Alt */
-	.clkdm_name	= "wkup_clkdm",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_48M_SOURCE,
-	.clksel		= func_48m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk func_12m_ck = {
-	.name		= "func_12m_ck",
-	.ops		= &clkops_null,
-	.parent		= &func_48m_ck,
-	.fixed_div	= 4,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2_fixed_divisor_recalc,
-};
-
-/* Secure timer, only available in secure mode */
-static struct clk wdt1_osc_ck = {
-	.name		= "ck_wdt1_osc",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &osc_ck,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * The common_clkout* clksel_rate structs are common to
- * sys_clkout, sys_clkout_src, sys_clkout2, and sys_clkout2_src.
- * sys_clkout2_* are 2420-only, so the
- * clksel_rate flags fields are inaccurate for those clocks. This is
- * harmless since access to those clocks are gated by the struct clk
- * flags fields, which mark them as 2420-only.
- */
-static const struct clksel_rate common_clkout_src_core_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_clkout_src_sys_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_clkout_src_96m_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_clkout_src_54m_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel common_clkout_src_clksel[] = {
-	{ .parent = &core_ck,	  .rates = common_clkout_src_core_rates },
-	{ .parent = &sys_ck,	  .rates = common_clkout_src_sys_rates },
-	{ .parent = &func_96m_ck, .rates = common_clkout_src_96m_rates },
-	{ .parent = &func_54m_ck, .rates = common_clkout_src_54m_rates },
-	{ .parent = NULL }
-};
-
-static struct clk sys_clkout_src = {
-	.name		= "sys_clkout_src",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &func_54m_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
-	.enable_bit	= OMAP24XX_CLKOUT_EN_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP24XX_CLKOUT_SOURCE_MASK,
-	.clksel		= common_clkout_src_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static const struct clksel_rate common_clkout_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 2, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 8, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 16, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel sys_clkout_clksel[] = {
-	{ .parent = &sys_clkout_src, .rates = common_clkout_rates },
-	{ .parent = NULL }
-};
-
-static struct clk sys_clkout = {
-	.name		= "sys_clkout",
-	.ops		= &clkops_null,
-	.parent		= &sys_clkout_src,
-	.clkdm_name	= "wkup_clkdm",
-	.clksel_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP24XX_CLKOUT_DIV_MASK,
-	.clksel		= sys_clkout_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/* In 2430, new in 2420 ES2 */
-static struct clk sys_clkout2_src = {
-	.name		= "sys_clkout2_src",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &func_54m_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
-	.enable_bit	= OMAP2420_CLKOUT2_EN_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP2420_CLKOUT2_SOURCE_MASK,
-	.clksel		= common_clkout_src_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static const struct clksel sys_clkout2_clksel[] = {
-	{ .parent = &sys_clkout2_src, .rates = common_clkout_rates },
-	{ .parent = NULL }
-};
-
-/* In 2430, new in 2420 ES2 */
-static struct clk sys_clkout2 = {
-	.name		= "sys_clkout2",
-	.ops		= &clkops_null,
-	.parent		= &sys_clkout2_src,
-	.clkdm_name	= "wkup_clkdm",
-	.clksel_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP2420_CLKOUT2_DIV_MASK,
-	.clksel		= sys_clkout2_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk emul_ck = {
-	.name		= "emul_ck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &func_54m_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP24XX_PRCM_CLKEMUL_CTRL,
-	.enable_bit	= OMAP24XX_EMULATION_EN_SHIFT,
-	.recalc		= &followparent_recalc,
-
-};
-
-/*
- * MPU clock domain
- *	Clocks:
- *		MPU_FCLK, MPU_ICLK
- *		INT_M_FCLK, INT_M_I_CLK
- *
- * - Individual clocks are hardware managed.
- * - Base divider comes from: CM_CLKSEL_MPU
- *
- */
-static const struct clksel_rate mpu_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_242X },
-	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
-	{ .div = 0 },
-};
-
-static const struct clksel mpu_clksel[] = {
-	{ .parent = &core_ck, .rates = mpu_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk mpu_ck = {	/* Control cpu */
-	.name		= "mpu_ck",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.clkdm_name	= "mpu_clkdm",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP24XX_CLKSEL_MPU_MASK,
-	.clksel		= mpu_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/*
- * DSP (2430-IVA2.1) (2420-UMA+IVA1) clock domain
- * Clocks:
- *	2430: IVA2.1_FCLK (really just DSP_FCLK), IVA2.1_ICLK
- *	2420: UMA_FCLK, UMA_ICLK, IVA_MPU, IVA_COP
- *
- * Won't be too specific here. The core clock comes into this block
- * it is divided then tee'ed. One branch goes directly to xyz enable
- * controls. The other branch gets further divided by 2 then possibly
- * routed into a synchronizer and out of clocks abc.
- */
-static const struct clksel_rate dsp_fck_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
-	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
-	{ .div = 0 },
-};
-
-static const struct clksel dsp_fck_clksel[] = {
-	{ .parent = &core_ck, .rates = dsp_fck_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk dsp_fck = {
-	.name		= "dsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_ck,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.clkdm_name	= "dsp_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSP_MASK,
-	.clksel		= dsp_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/* DSP interface clock */
-static const struct clksel_rate dsp_irate_ick_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_243X },
-	{ .div = 0 },
-};
-
-static const struct clksel dsp_irate_ick_clksel[] = {
-	{ .parent = &dsp_fck, .rates = dsp_irate_ick_rates },
-	{ .parent = NULL }
-};
-
-/* This clock does not exist as such in the TRM. */
-static struct clk dsp_irate_ick = {
-	.name		= "dsp_irate_ick",
-	.ops		= &clkops_null,
-	.parent		= &dsp_fck,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSP_IF_MASK,
-	.clksel		= dsp_irate_ick_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	      = &omap2_clksel_set_rate
-};
-
-/* 2420 only */
-static struct clk dsp_ick = {
-	.name		= "dsp_ick",	 /* apparently ipi and isp */
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dsp_irate_ick,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP2420_EN_DSP_IPI_SHIFT,	      /* for ipi */
-};
-
-/* 2430 only - EN_DSP controls both dsp fclk and iclk on 2430 */
-static struct clk iva2_1_ick = {
-	.name		= "iva2_1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dsp_irate_ick,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
-};
-
-/*
- * The IVA1 is an ARM7 core on the 2420 that has nothing to do with
- * the C54x, but which is contained in the DSP powerdomain.  Does not
- * exist on later OMAPs.
- */
-static struct clk iva1_ifck = {
-	.name		= "iva1_ifck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_ck,
-	.flags		= CONFIG_PARTICIPANT | DELAYED_APP,
-	.clkdm_name	= "iva1_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP2420_EN_IVA_COP_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP2420_CLKSEL_IVA_MASK,
-	.clksel		= dsp_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/* IVA1 mpu/int/i/f clocks are /2 of parent */
-static struct clk iva1_mpu_int_ifck = {
-	.name		= "iva1_mpu_int_ifck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &iva1_ifck,
-	.clkdm_name	= "iva1_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP2420_EN_IVA_MPU_SHIFT,
-	.fixed_div	= 2,
-	.recalc		= &omap2_fixed_divisor_recalc,
-};
-
-/*
- * L3 clock domain
- * L3 clocks are used for both interface and functional clocks to
- * multiple entities. Some of these clocks are completely managed
- * by hardware, and some others allow software control. Hardware
- * managed ones general are based on directly CLK_REQ signals and
- * various auto idle settings. The functional spec sets many of these
- * as 'tie-high' for their enables.
- *
- * I-CLOCKS:
- *	L3-Interconnect, SMS, GPMC, SDRC, OCM_RAM, OCM_ROM, SDMA
- *	CAM, HS-USB.
- * F-CLOCK
- *	SSI.
- *
- * GPMC memories and SDRC have timing and clock sensitive registers which
- * may very well need notification when the clock changes. Currently for low
- * operating points, these are taken care of in sleep.S.
- */
-static const struct clksel_rate core_l3_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_242X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
-	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
-	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
-	{ .div = 16, .val = 16, .flags = RATE_IN_242X },
-	{ .div = 0 }
-};
-
-static const struct clksel core_l3_clksel[] = {
-	{ .parent = &core_ck, .rates = core_l3_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk core_l3_ck = {	/* Used for ick and fck, interconnect */
-	.name		= "core_l3_ck",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.clkdm_name	= "core_l3_clkdm",
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_L3_MASK,
-	.clksel		= core_l3_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/* usb_l4_ick */
-static const struct clksel_rate usb_l4_ick_core_l3_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel usb_l4_ick_clksel[] = {
-	{ .parent = &core_l3_ck, .rates = usb_l4_ick_core_l3_rates },
-	{ .parent = NULL },
-};
-
-/* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */
-static struct clk usb_l4_ick = {	/* FS-USB interface clock */
-	.name		= "usb_l4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_USB_MASK,
-	.clksel		= usb_l4_ick_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/*
- * L4 clock management domain
- *
- * This domain contains lots of interface clocks from the L4 interface, some
- * functional clocks.	Fixed APLL functional source clocks are managed in
- * this domain.
- */
-static const struct clksel_rate l4_core_l3_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel l4_clksel[] = {
-	{ .parent = &core_l3_ck, .rates = l4_core_l3_rates },
-	{ .parent = NULL }
-};
-
-static struct clk l4_ck = {		/* used both as an ick and fck */
-	.name		= "l4_ck",
-	.ops		= &clkops_null,
-	.parent		= &core_l3_ck,
-	.flags		= DELAYED_APP,
-	.clkdm_name	= "core_l4_clkdm",
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_L4_MASK,
-	.clksel		= l4_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/*
- * SSI is in L3 management domain, its direct parent is core not l3,
- * many core power domain entities are grouped into the L3 clock
- * domain.
- * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_ICLK
- *
- * ssr = core/1/2/3/4/5, sst = 1/2 ssr.
- */
-static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 5, .val = 5, .flags = RATE_IN_243X },
-	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
-	{ .div = 0 }
-};
-
-static const struct clksel ssi_ssr_sst_fck_clksel[] = {
-	{ .parent = &core_ck, .rates = ssi_ssr_sst_fck_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk ssi_ssr_sst_fck = {
-	.name		= "ssi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_ck,
-	.flags		= DELAYED_APP,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_SSI_MASK,
-	.clksel		= ssi_ssr_sst_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/*
- * Presumably this is the same as SSI_ICLK.
- * TRM contradicts itself on what clockdomain SSI_ICLK is in
- */
-static struct clk ssi_l4_ick = {
-	.name		= "ssi_l4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-
-/*
- * GFX clock domain
- *	Clocks:
- * GFX_FCLK, GFX_ICLK
- * GFX_CG1(2d), GFX_CG2(3d)
- *
- * GFX_FCLK runs from L3, and is divided by (1,2,3,4)
- * The 2d and 3d clocks run at a hardware determined
- * divided value of fclk.
- *
- */
-/* XXX REVISIT: GFX clock is part of CONFIG_PARTICIPANT, no? doublecheck. */
-
-/* This clksel struct is shared between gfx_3d_fck and gfx_2d_fck */
-static const struct clksel gfx_fck_clksel[] = {
-	{ .parent = &core_l3_ck, .rates = gfx_l3_rates },
-	{ .parent = NULL },
-};
-
-static struct clk gfx_3d_fck = {
-	.name		= "gfx_3d_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "gfx_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_3D_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
-	.clksel		= gfx_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk gfx_2d_fck = {
-	.name		= "gfx_2d_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "gfx_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_2D_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
-	.clksel		= gfx_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk gfx_ick = {
-	.name		= "gfx_ick",		/* From l3 */
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "gfx_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP_EN_GFX_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * Modem clock domain (2430)
- *	CLOCKS:
- *		MDM_OSC_CLK
- *		MDM_ICLK
- * These clocks are usable in chassis mode only.
- */
-static const struct clksel_rate mdm_ick_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_243X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_243X | DEFAULT_RATE },
-	{ .div = 6, .val = 6, .flags = RATE_IN_243X },
-	{ .div = 9, .val = 9, .flags = RATE_IN_243X },
-	{ .div = 0 }
-};
-
-static const struct clksel mdm_ick_clksel[] = {
-	{ .parent = &core_ck, .rates = mdm_ick_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk mdm_ick = {		/* used both as a ick and fck */
-	.name		= "mdm_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_ck,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.clkdm_name	= "mdm_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP2430_CLKSEL_MDM_MASK,
-	.clksel		= mdm_ick_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk mdm_osc_ck = {
-	.name		= "mdm_osc_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &osc_ck,
-	.clkdm_name	= "mdm_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP2430_EN_OSC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * DSS clock domain
- * CLOCKs:
- * DSS_L4_ICLK, DSS_L3_ICLK,
- * DSS_CLK1, DSS_CLK2, DSS_54MHz_CLK
- *
- * DSS is both initiator and target.
- */
-/* XXX Add RATE_NOT_VALIDATED */
-
-static const struct clksel_rate dss1_fck_sys_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate dss1_fck_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 5, .val = 5, .flags = RATE_IN_24XX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
-	{ .div = 8, .val = 8, .flags = RATE_IN_24XX },
-	{ .div = 9, .val = 9, .flags = RATE_IN_24XX },
-	{ .div = 12, .val = 12, .flags = RATE_IN_24XX },
-	{ .div = 16, .val = 16, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel dss1_fck_clksel[] = {
-	{ .parent = &sys_ck,  .rates = dss1_fck_sys_rates },
-	{ .parent = &core_ck, .rates = dss1_fck_core_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dss_ick = {		/* Enables both L3,L4 ICLK's */
-	.name		= "dss_ick",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &l4_ck,	/* really both l3 and l4 */
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss1_fck = {
-	.name		= "dss1_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &core_ck,		/* Core or sys */
-	.flags		= DELAYED_APP,
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSS1_MASK,
-	.clksel		= dss1_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static const struct clksel_rate dss2_fck_sys_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate dss2_fck_48m_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel dss2_fck_clksel[] = {
-	{ .parent = &sys_ck,	  .rates = dss2_fck_sys_rates },
-	{ .parent = &func_48m_ck, .rates = dss2_fck_48m_rates },
-	{ .parent = NULL }
-};
-
-static struct clk dss2_fck = {		/* Alt clk used in power management */
-	.name		= "dss2_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &sys_ck,		/* fixed at sys_ck or 48MHz */
-	.flags		= DELAYED_APP,
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_DSS2_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSS2_MASK,
-	.clksel		= dss2_fck_clksel,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_54m_fck = {	/* Alt clk used in power management */
-	.name		= "dss_54m_fck",	/* 54m tv clk */
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_54m_ck,
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_TV_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * CORE power domain ICLK & FCLK defines.
- * Many of the these can have more than one possible parent. Entries
- * here will likely have an L4 interface parent, and may have multiple
- * functional clock parents.
- */
-static const struct clksel_rate gpt_alt_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel omap24xx_gpt_clksel[] = {
-	{ .parent = &func_32k_ck, .rates = gpt_32k_rates },
-	{ .parent = &sys_ck,	  .rates = gpt_sys_rates },
-	{ .parent = &alt_ck,	  .rates = gpt_alt_rates },
-	{ .parent = NULL },
-};
-
-static struct clk gpt1_ick = {
-	.name		= "gpt1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt1_fck = {
-	.name		= "gpt1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT1_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk gpt2_ick = {
-	.name		= "gpt2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt2_fck = {
-	.name		= "gpt2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT2_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt3_ick = {
-	.name		= "gpt3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt3_fck = {
-	.name		= "gpt3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT3_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt4_ick = {
-	.name		= "gpt4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt4_fck = {
-	.name		= "gpt4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT4_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt5_ick = {
-	.name		= "gpt5_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt5_fck = {
-	.name		= "gpt5_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT5_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt6_ick = {
-	.name		= "gpt6_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt6_fck = {
-	.name		= "gpt6_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT6_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt7_ick = {
-	.name		= "gpt7_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt7_fck = {
-	.name		= "gpt7_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT7_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt8_ick = {
-	.name		= "gpt8_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt8_fck = {
-	.name		= "gpt8_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT8_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt9_ick = {
-	.name		= "gpt9_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt9_fck = {
-	.name		= "gpt9_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT9_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt10_ick = {
-	.name		= "gpt10_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt10_fck = {
-	.name		= "gpt10_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT10_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt11_ick = {
-	.name		= "gpt11_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt11_fck = {
-	.name		= "gpt11_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT11_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt12_ick = {
-	.name		= "gpt12_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt12_fck = {
-	.name		= "gpt12_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &secure_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT12_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp1_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp1_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp2_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp2_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp3_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp3_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp4_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 4,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp4_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 4,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp5_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 5,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP5_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp5_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 5,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP5_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi1_ick = {
-	.name		= "mcspi_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi1_fck = {
-	.name		= "mcspi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi2_ick = {
-	.name		= "mcspi_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi2_fck = {
-	.name		= "mcspi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi3_ick = {
-	.name		= "mcspi_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MCSPI3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi3_fck = {
-	.name		= "mcspi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MCSPI3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart1_ick = {
-	.name		= "uart1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart1_fck = {
-	.name		= "uart1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart2_ick = {
-	.name		= "uart2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart2_fck = {
-	.name		= "uart2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart3_ick = {
-	.name		= "uart3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart3_fck = {
-	.name		= "uart3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpios_ick = {
-	.name		= "gpios_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpios_fck = {
-	.name		= "gpios_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mpu_wdt_ick = {
-	.name		= "mpu_wdt_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mpu_wdt_fck = {
-	.name		= "mpu_wdt_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sync_32k_ick = {
-	.name		= "sync_32k_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_32KSYNC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt1_ick = {
-	.name		= "wdt1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_WDT1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk omapctrl_ick = {
-	.name		= "omapctrl_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_OMAPCTRL_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk icr_ick = {
-	.name		= "icr_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP2430_EN_ICR_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk cam_ick = {
-	.name		= "cam_ick",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * cam_fck controls both CAM_MCLK and CAM_FCLK.  It should probably be
- * split into two separate clocks, since the parent clocks are different
- * and the clockdomains are also different.
- */
-static struct clk cam_fck = {
-	.name		= "cam_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mailboxes_ick = {
-	.name		= "mailboxes_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MAILBOXES_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt4_ick = {
-	.name		= "wdt4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt4_fck = {
-	.name		= "wdt4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt3_ick = {
-	.name		= "wdt3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_WDT3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt3_fck = {
-	.name		= "wdt3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_WDT3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mspro_ick = {
-	.name		= "mspro_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mspro_fck = {
-	.name		= "mspro_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmc_ick = {
-	.name		= "mmc_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_MMC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmc_fck = {
-	.name		= "mmc_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_MMC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk fac_ick = {
-	.name		= "fac_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk fac_fck = {
-	.name		= "fac_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_12m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk eac_ick = {
-	.name		= "eac_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_EAC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk eac_fck = {
-	.name		= "eac_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_EAC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hdq_ick = {
-	.name		= "hdq_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hdq_fck = {
-	.name		= "hdq_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_12m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c2_ick = {
-	.name		= "i2c_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c2_fck = {
-	.name		= "i2c_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &func_12m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2chs2_fck = {
-	.name		= "i2c_fck",
-	.ops		= &clkops_omap2430_i2chs_wait,
-	.id		= 2,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_I2CHS2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c1_ick = {
-	.name		= "i2c_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c1_fck = {
-	.name		= "i2c_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &func_12m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2chs1_fck = {
-	.name		= "i2c_fck",
-	.ops		= &clkops_omap2430_i2chs_wait,
-	.id		= 1,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_I2CHS1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpmc_fck = {
-	.name		= "gpmc_fck",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &core_l3_ck,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sdma_fck = {
-	.name		= "sdma_fck",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sdma_ick = {
-	.name		= "sdma_ick",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk vlynq_ick = {
-	.name		= "vlynq_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_VLYNQ_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel_rate vlynq_fck_96m_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_242X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate vlynq_fck_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_242X },
-	{ .div = 2, .val = 2, .flags = RATE_IN_242X },
-	{ .div = 3, .val = 3, .flags = RATE_IN_242X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_242X },
-	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
-	{ .div = 9, .val = 9, .flags = RATE_IN_242X },
-	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
-	{ .div = 16, .val = 16, .flags = RATE_IN_242X | DEFAULT_RATE },
-	{ .div = 18, .val = 18, .flags = RATE_IN_242X },
-	{ .div = 0 }
-};
-
-static const struct clksel vlynq_fck_clksel[] = {
-	{ .parent = &func_96m_ck, .rates = vlynq_fck_96m_rates },
-	{ .parent = &core_ck,	  .rates = vlynq_fck_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk vlynq_fck = {
-	.name		= "vlynq_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.flags		= DELAYED_APP,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_VLYNQ_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP2420_CLKSEL_VLYNQ_MASK,
-	.clksel		= vlynq_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk sdrc_ick = {
-	.name		= "sdrc_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP2430_EN_SDRC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk des_ick = {
-	.name		= "des_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_DES_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sha_ick = {
-	.name		= "sha_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_SHA_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk rng_ick = {
-	.name		= "rng_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_RNG_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk aes_ick = {
-	.name		= "aes_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_AES_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk pka_ick = {
-	.name		= "pka_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_PKA_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_fck = {
-	.name		= "usb_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbhs_ick = {
-	.name		= "usbhs_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_USBHS_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs1_ick = {
-	.name		= "mmchs_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHS1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs1_fck = {
-	.name		= "mmchs_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHS1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs2_ick = {
-	.name		= "mmchs_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHS2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs2_fck = {
-	.name		= "mmchs_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &func_96m_ck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHS2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio5_ick = {
-	.name		= "gpio5_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_GPIO5_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio5_fck = {
-	.name		= "gpio5_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_GPIO5_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mdm_intc_ick = {
-	.name		= "mdm_intc_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MDM_INTC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchsdb1_fck = {
-	.name		= "mmchsdb_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHSDB1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchsdb2_fck = {
-	.name		= "mmchsdb_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHSDB2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * This clock is a composite clock which does entire set changes then
- * forces a rebalance. It keys on the MPU speed, but it really could
- * be any key speed part of a set in the rate table.
- *
- * to really change a set, you need memory table sets which get changed
- * in sram, pre-notifiers & post notifiers, changing the top set, without
- * having low level display recalc's won't work... this is why dpm notifiers
- * work, isr's off, walk a list of clocks already _off_ and not messing with
- * the bus.
- *
- * This clock should have no parent. It embodies the entire upper level
- * active set. A parent will mess up some of the init also.
- */
-static struct clk virt_prcm_set = {
-	.name		= "virt_prcm_set",
-	.ops		= &clkops_null,
-	.flags		= DELAYED_APP,
-	.parent		= &mpu_ck,	/* Indexed by mpu speed, no parent */
-	.recalc		= &omap2_table_mpu_recalc,	/* sets are keyed on mpu rate */
-	.set_rate	= &omap2_select_table_rate,
-	.round_rate	= &omap2_round_to_table_rate,
-};
-
-
-/*
- * clkdev integration
- */
-
-static struct omap_clk omap24xx_clks[] = {
-	/* external root sources */
-	CLK(NULL,	"func_32k_ck",	&func_32k_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"secure_32k_ck", &secure_32k_ck, CK_243X | CK_242X),
-	CLK(NULL,	"osc_ck",	&osc_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"sys_ck",	&sys_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"alt_ck",	&alt_ck,	CK_243X | CK_242X),
-	/* internal analog sources */
-	CLK(NULL,	"dpll_ck",	&dpll_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"apll96_ck",	&apll96_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"apll54_ck",	&apll54_ck,	CK_243X | CK_242X),
-	/* internal prcm root sources */
-	CLK(NULL,	"func_54m_ck",	&func_54m_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"core_ck",	&core_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"func_96m_ck",	&func_96m_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"func_48m_ck",	&func_48m_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"func_12m_ck",	&func_12m_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"ck_wdt1_osc",	&wdt1_osc_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"sys_clkout_src", &sys_clkout_src, CK_243X | CK_242X),
-	CLK(NULL,	"sys_clkout",	&sys_clkout,	CK_243X | CK_242X),
-	CLK(NULL,	"sys_clkout2_src", &sys_clkout2_src, CK_242X),
-	CLK(NULL,	"sys_clkout2",	&sys_clkout2,	CK_242X),
-	CLK(NULL,	"emul_ck",	&emul_ck,	CK_242X),
-	/* mpu domain clocks */
-	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_243X | CK_242X),
-	/* dsp domain clocks */
-	CLK(NULL,	"dsp_fck",	&dsp_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"dsp_irate_ick", &dsp_irate_ick, CK_243X | CK_242X),
-	CLK(NULL,	"dsp_ick",	&dsp_ick,	CK_242X),
-	CLK(NULL,	"iva2_1_ick",	&iva2_1_ick,	CK_243X),
-	CLK(NULL,	"iva1_ifck",	&iva1_ifck,	CK_242X),
-	CLK(NULL,	"iva1_mpu_int_ifck", &iva1_mpu_int_ifck, CK_242X),
-	/* GFX domain clocks */
-	CLK(NULL,	"gfx_3d_fck",	&gfx_3d_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gfx_2d_fck",	&gfx_2d_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gfx_ick",	&gfx_ick,	CK_243X | CK_242X),
-	/* Modem domain clocks */
-	CLK(NULL,	"mdm_ick",	&mdm_ick,	CK_243X),
-	CLK(NULL,	"mdm_osc_ck",	&mdm_osc_ck,	CK_243X),
-	/* DSS domain clocks */
-	CLK("omapdss",	"ick",		&dss_ick,	CK_243X | CK_242X),
-	CLK("omapdss",	"dss1_fck",	&dss1_fck,	CK_243X | CK_242X),
-	CLK("omapdss",	"dss2_fck",	&dss2_fck,	CK_243X | CK_242X),
-	CLK("omapdss",	"tv_fck",	&dss_54m_fck,	CK_243X | CK_242X),
-	/* L3 domain clocks */
-	CLK(NULL,	"core_l3_ck",	&core_l3_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"ssi_fck",	&ssi_ssr_sst_fck, CK_243X | CK_242X),
-	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick,	CK_243X | CK_242X),
-	/* L4 domain clocks */
-	CLK(NULL,	"l4_ck",	&l4_ck,		CK_243X | CK_242X),
-	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_243X | CK_242X),
-	/* virtual meta-group clock */
-	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_243X | CK_242X),
-	/* general l4 interface ck, multi-parent functional clk */
-	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_243X | CK_242X),
-	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_243X | CK_242X),
-	CLK("omap-mcbsp.1", "fck",	&mcbsp1_fck,	CK_243X | CK_242X),
-	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_243X | CK_242X),
-	CLK("omap-mcbsp.2", "fck",	&mcbsp2_fck,	CK_243X | CK_242X),
-	CLK("omap-mcbsp.3", "ick",	&mcbsp3_ick,	CK_243X),
-	CLK("omap-mcbsp.3", "fck",	&mcbsp3_fck,	CK_243X),
-	CLK("omap-mcbsp.4", "ick",	&mcbsp4_ick,	CK_243X),
-	CLK("omap-mcbsp.4", "fck",	&mcbsp4_fck,	CK_243X),
-	CLK("omap-mcbsp.5", "ick",	&mcbsp5_ick,	CK_243X),
-	CLK("omap-mcbsp.5", "fck",	&mcbsp5_fck,	CK_243X),
-	CLK("omap2_mcspi.1", "ick",	&mcspi1_ick,	CK_243X | CK_242X),
-	CLK("omap2_mcspi.1", "fck",	&mcspi1_fck,	CK_243X | CK_242X),
-	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick,	CK_243X | CK_242X),
-	CLK("omap2_mcspi.2", "fck",	&mcspi2_fck,	CK_243X | CK_242X),
-	CLK("omap2_mcspi.3", "ick",	&mcspi3_ick,	CK_243X),
-	CLK("omap2_mcspi.3", "fck",	&mcspi3_fck,	CK_243X),
-	CLK(NULL,	"uart1_ick",	&uart1_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"uart1_fck",	&uart1_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"uart2_ick",	&uart2_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpios_ick",	&gpios_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_243X | CK_242X),
-	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_243X | CK_242X),
-	CLK("omap_wdt",	"fck",		&mpu_wdt_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"icr_ick",	&icr_ick,	CK_243X),
-	CLK("omap24xxcam", "fck",	&cam_fck,	CK_243X | CK_242X),
-	CLK("omap24xxcam", "ick",	&cam_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"mailboxes_ick", &mailboxes_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"wdt4_ick",	&wdt4_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"wdt4_fck",	&wdt4_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"wdt3_ick",	&wdt3_ick,	CK_242X),
-	CLK(NULL,	"wdt3_fck",	&wdt3_fck,	CK_242X),
-	CLK(NULL,	"mspro_ick",	&mspro_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"mspro_fck",	&mspro_fck,	CK_243X | CK_242X),
-	CLK("mmci-omap.0", "ick",	&mmc_ick,	CK_242X),
-	CLK("mmci-omap.0", "fck",	&mmc_fck,	CK_242X),
-	CLK(NULL,	"fac_ick",	&fac_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"fac_fck",	&fac_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"eac_ick",	&eac_ick,	CK_242X),
-	CLK(NULL,	"eac_fck",	&eac_fck,	CK_242X),
-	CLK("omap_hdq.0", "ick",	&hdq_ick,	CK_243X | CK_242X),
-	CLK("omap_hdq.1", "fck",	&hdq_fck,	CK_243X | CK_242X),
-	CLK("i2c_omap.1", "ick",	&i2c1_ick,	CK_243X | CK_242X),
-	CLK("i2c_omap.1", "fck",	&i2c1_fck,	CK_242X),
-	CLK("i2c_omap.1", "fck",	&i2chs1_fck,	CK_243X),
-	CLK("i2c_omap.2", "ick",	&i2c2_ick,	CK_243X | CK_242X),
-	CLK("i2c_omap.2", "fck",	&i2c2_fck,	CK_242X),
-	CLK("i2c_omap.2", "fck",	&i2chs2_fck,	CK_243X),
-	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"sdma_fck",	&sdma_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"sdma_ick",	&sdma_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"vlynq_ick",	&vlynq_ick,	CK_242X),
-	CLK(NULL,	"vlynq_fck",	&vlynq_fck,	CK_242X),
-	CLK(NULL,	"sdrc_ick",	&sdrc_ick,	CK_243X),
-	CLK(NULL,	"des_ick",	&des_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"sha_ick",	&sha_ick,	CK_243X | CK_242X),
-	CLK("omap_rng",	"ick",		&rng_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"aes_ick",	&aes_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"pka_ick",	&pka_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"usb_fck",	&usb_fck,	CK_243X | CK_242X),
-	CLK("musb_hdrc",	"ick",	&usbhs_ick,	CK_243X),
-	CLK("mmci-omap-hs.0", "ick",	&mmchs1_ick,	CK_243X),
-	CLK("mmci-omap-hs.0", "fck",	&mmchs1_fck,	CK_243X),
-	CLK("mmci-omap-hs.1", "ick",	&mmchs2_ick,	CK_243X),
-	CLK("mmci-omap-hs.1", "fck",	&mmchs2_fck,	CK_243X),
-	CLK(NULL,	"gpio5_ick",	&gpio5_ick,	CK_243X),
-	CLK(NULL,	"gpio5_fck",	&gpio5_fck,	CK_243X),
-	CLK(NULL,	"mdm_intc_ick",	&mdm_intc_ick,	CK_243X),
-	CLK("mmci-omap-hs.0", "mmchsdb_fck",	&mmchsdb1_fck,	CK_243X),
-	CLK("mmci-omap-hs.1", "mmchsdb_fck", 	&mmchsdb2_fck,	CK_243X),
-};
-
-/*
- * init code
- */
-
-int __init omap2_clk_init(void)
-{
-	const struct prcm_config *prcm;
-	struct omap_clk *c;
-	u32 clkrate;
-	u16 cpu_clkflg;
-
-	if (cpu_is_omap242x()) {
-		prcm_clksrc_ctrl = OMAP2420_PRCM_CLKSRC_CTRL;
-		cpu_mask = RATE_IN_242X;
-		cpu_clkflg = CK_242X;
-		rate_table = omap2420_rate_table;
-	} else if (cpu_is_omap2430()) {
-		prcm_clksrc_ctrl = OMAP2430_PRCM_CLKSRC_CTRL;
-		cpu_mask = RATE_IN_243X;
-		cpu_clkflg = CK_243X;
-		rate_table = omap2430_rate_table;
-	}
-
-	clk_init(&omap2_clk_functions);
-
-	for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
-		clk_preinit(c->lk.clk);
-
-	osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
-	propagate_rate(&osc_ck);
-	sys_ck.rate = omap2_sys_clk_recalc(&sys_ck);
-	propagate_rate(&sys_ck);
-
-	for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
-		if (c->cpu & cpu_clkflg) {
-			clkdev_add(&c->lk);
-			clk_register(c->lk.clk);
-			omap2_init_clk_clkdm(c->lk.clk);
-		}
-
-	/* Check the MPU rate set by bootloader */
-	clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
-	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
-		if (!(prcm->flags & cpu_mask))
-			continue;
-		if (prcm->xtal_speed != sys_ck.rate)
-			continue;
-		if (prcm->dpll_speed <= clkrate)
-			break;
-	}
-	curr_prcm_set = prcm;
-
-	recalculate_root_clocks();
-
-	printk(KERN_INFO "Clocking rate (Crystal/DPLL/MPU): "
-	       "%ld.%01ld/%ld/%ld MHz\n",
-	       (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
-	       (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
-
-	/*
-	 * Only enable those clocks we will need, let the drivers
-	 * enable other clocks as necessary
-	 */
-	clk_enable_init_clocks();
-
-	/* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */
-	vclk = clk_get(NULL, "virt_prcm_set");
-	sclk = clk_get(NULL, "sys_ck");
-	dclk = clk_get(NULL, "dpll_ck");
-
-	return 0;
-}
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2xxx.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock2xxx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2xxx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock2xxx.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,35 +1,38 @@
 /*
  * OMAP2 clock function prototypes and macros
  *
- * Copyright (C) 2005-2009 Texas Instruments, Inc.
- * Copyright (C) 2004-2009 Nokia Corporation
+ * Copyright (C) 2005-2010 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
  */
 
-#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_24XX_H
-#define __ARCH_ARM_MACH_OMAP2_CLOCK_24XX_H
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK2XXX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK2XXX_H
 
 unsigned long omap2_table_mpu_recalc(struct clk *clk);
 int omap2_select_table_rate(struct clk *clk, unsigned long rate);
 long omap2_round_to_table_rate(struct clk *clk, unsigned long rate);
-unsigned long omap2_sys_clk_recalc(struct clk *clk);
+unsigned long omap2xxx_sys_clk_recalc(struct clk *clk);
 unsigned long omap2_osc_clk_recalc(struct clk *clk);
-unsigned long omap2_sys_clk_recalc(struct clk *clk);
 unsigned long omap2_dpllcore_recalc(struct clk *clk);
 int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate);
 unsigned long omap2xxx_clk_get_core_rate(struct clk *clk);
+u32 omap2xxx_get_apll_clkin(void);
+u32 omap2xxx_get_sysclkdiv(void);
+void omap2xxx_clk_prepare_for_reboot(void);
 
-/* REVISIT: These should be set dynamically for CONFIG_MULTI_OMAP2 */
 #ifdef CONFIG_ARCH_OMAP2420
-#define OMAP_CM_REGADDR			OMAP2420_CM_REGADDR
-#define OMAP24XX_PRCM_CLKOUT_CTRL	OMAP2420_PRCM_CLKOUT_CTRL
-#define OMAP24XX_PRCM_CLKEMUL_CTRL	OMAP2420_PRCM_CLKEMUL_CTRL
+int omap2420_clk_init(void);
 #else
-#define OMAP_CM_REGADDR			OMAP2430_CM_REGADDR
-#define OMAP24XX_PRCM_CLKOUT_CTRL	OMAP2430_PRCM_CLKOUT_CTRL
-#define OMAP24XX_PRCM_CLKEMUL_CTRL	OMAP2430_PRCM_CLKEMUL_CTRL
+#define omap2420_clk_init()	0
 #endif
 
-extern void __iomem *prcm_clksrc_ctrl;
+#ifdef CONFIG_ARCH_OMAP2430
+int omap2430_clk_init(void);
+#else
+#define omap2430_clk_init()	0
+#endif
+
+extern void __iomem *prcm_clksrc_ctrl, *cm_idlest_pll;
 
 extern struct clk *dclk;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock34xx.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock34xx.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock34xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock34xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,13 +2,14 @@
  * OMAP3-specific clock framework functions
  *
  * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2009 Nokia Corporation
+ * Copyright (C) 2007-2010 Nokia Corporation
  *
- * Written by Paul Walmsley
- * Testing and integration fixes by Jouni HÃ¶gander
+ * Paul Walmsley
+ * Jouni HÃ¶gander
  *
  * Parts of this code are based on code written by
- * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu,
+ * 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
@@ -16,49 +17,23 @@
  */
 #undef DEBUG
 
-#include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/io.h>
-#include <linux/limits.h>
-#include <linux/bitops.h>
 
-#include <plat/cpu.h>
 #include <plat/clock.h>
-#include <plat/sram.h>
-#include <plat/sdrc.h>
-#include <asm/div64.h>
-#include <asm/clkdev.h>
 
 #include "clock.h"
 #include "clock34xx.h"
-#include "sdrc.h"
-#include "prm.h"
-#include "prm-regbits-34xx.h"
 #include "cm.h"
 #include "cm-regbits-34xx.h"
 
-#define CYCLES_PER_MHZ			1000000
-
-/*
- * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
- * that are sourced by DPLL5, and both of these require this clock
- * to be at 120 MHz for proper operation.
- */
-#define DPLL5_FREQ_FOR_USBHOST		120000000
-
-/* needed by omap3_core_dpll_m2_set_rate() */
-struct clk *sdrc_ick_p, *arm_fck_p;
-
 /**
  * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI
  * @clk: struct clk * being enabled
  * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
  * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
  *
  * The OMAP3430ES2 SSI target CM_IDLEST bit is at a different shift
  * from the CM_{I,F}CLKEN bit.  Pass back the correct info via
@@ -66,13 +41,15 @@ struct clk *sdrc_ick_p, *arm_fck_p;
  */
 static void omap3430es2_clk_ssi_find_idlest(struct clk *clk,
 					    void __iomem **idlest_reg,
-					    u8 *idlest_bit)
+					    u8 *idlest_bit,
+					    u8 *idlest_val)
 {
 	u32 r;
 
 	r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
 	*idlest_reg = (__force void __iomem *)r;
 	*idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT;
+	*idlest_val = OMAP34XX_CM_IDLEST_VAL;
 }
 
 const struct clkops clkops_omap3430es2_ssi_wait = {
@@ -87,6 +64,7 @@ const struct clkops clkops_omap3430es2_s
  * @clk: struct clk * being enabled
  * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
  * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
  *
  * Some OMAP modules on OMAP3 ES2+ chips have both initiator and
  * target IDLEST bits.  For our purposes, we are concerned with the
@@ -97,7 +75,8 @@ const struct clkops clkops_omap3430es2_s
  */
 static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk,
 						    void __iomem **idlest_reg,
-						    u8 *idlest_bit)
+						    u8 *idlest_bit,
+						    u8 *idlest_val)
 {
 	u32 r;
 
@@ -105,6 +84,7 @@ static void omap3430es2_clk_dss_usbhost_
 	*idlest_reg = (__force void __iomem *)r;
 	/* USBHOST_IDLE has same shift */
 	*idlest_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT;
+	*idlest_val = OMAP34XX_CM_IDLEST_VAL;
 }
 
 const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
@@ -119,6 +99,7 @@ const struct clkops clkops_omap3430es2_d
  * @clk: struct clk * being enabled
  * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
  * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
  *
  * The OMAP3430ES2 HSOTGUSB target CM_IDLEST bit is at a different
  * shift from the CM_{I,F}CLKEN bit.  Pass back the correct info via
@@ -126,13 +107,15 @@ const struct clkops clkops_omap3430es2_d
  */
 static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk,
 						 void __iomem **idlest_reg,
-						 u8 *idlest_bit)
+						 u8 *idlest_bit,
+						 u8 *idlest_val)
 {
 	u32 r;
 
 	r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
 	*idlest_reg = (__force void __iomem *)r;
 	*idlest_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT;
+	*idlest_val = OMAP34XX_CM_IDLEST_VAL;
 }
 
 const struct clkops clkops_omap3430es2_hsotgusb_wait = {
@@ -141,213 +124,3 @@ const struct clkops clkops_omap3430es2_h
 	.find_idlest	= omap3430es2_clk_hsotgusb_find_idlest,
 	.find_companion = omap2_clk_dflt_find_companion,
 };
-
-const struct clkops clkops_noncore_dpll_ops = {
-	.enable		= omap3_noncore_dpll_enable,
-	.disable	= omap3_noncore_dpll_disable,
-};
-
-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.
- */
-int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
-{
-	u32 new_div = 0;
-	u32 unlock_dll = 0;
-	u32 c;
-	unsigned long validrate, sdrcrate, _mpurate;
-	struct omap_sdrc_params *sdrc_cs0;
-	struct omap_sdrc_params *sdrc_cs1;
-	int ret;
-
-	if (!clk || !rate)
-		return -EINVAL;
-
-	validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
-	if (validrate != rate)
-		return -EINVAL;
-
-	sdrcrate = sdrc_ick_p->rate;
-	if (rate > clk->rate)
-		sdrcrate <<= ((rate / clk->rate) >> 1);
-	else
-		sdrcrate >>= ((clk->rate / rate) >> 1);
-
-	ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1);
-	if (ret)
-		return -EINVAL;
-
-	if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
-		pr_debug("clock: will unlock SDRC DLL\n");
-		unlock_dll = 1;
-	}
-
-	/*
-	 * XXX This only needs to be done when the CPU frequency changes
-	 */
-	_mpurate = arm_fck_p->rate / CYCLES_PER_MHZ;
-	c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
-	c += 1;  /* for safety */
-	c *= SDRC_MPURATE_LOOPS;
-	c >>= SDRC_MPURATE_SCALE;
-	if (c == 0)
-		c = 1;
-
-	pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
-		 validrate);
-	pr_debug("clock: SDRC CS0 timing params used:"
-		 " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
-		 sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
-		 sdrc_cs0->actim_ctrlb, sdrc_cs0->mr);
-	if (sdrc_cs1)
-		pr_debug("clock: SDRC CS1 timing params used: "
-		 " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
-		 sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
-		 sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
-
-	if (sdrc_cs1)
-		omap3_configure_core_dpll(
-				  new_div, unlock_dll, c, rate > clk->rate,
-				  sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
-				  sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
-				  sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
-				  sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
-	else
-		omap3_configure_core_dpll(
-				  new_div, unlock_dll, c, rate > clk->rate,
-				  sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
-				  sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
-				  0, 0, 0, 0);
-
-	return 0;
-}
-
-/* Common clock code */
-
-/*
- * As it is structured now, this will prevent an OMAP2/3 multiboot
- * kernel from compiling.  This will need further attention.
- */
-#if defined(CONFIG_ARCH_OMAP3)
-
-struct clk_functions omap2_clk_functions = {
-	.clk_enable		= omap2_clk_enable,
-	.clk_disable		= omap2_clk_disable,
-	.clk_round_rate		= omap2_clk_round_rate,
-	.clk_set_rate		= omap2_clk_set_rate,
-	.clk_set_parent		= omap2_clk_set_parent,
-	.clk_disable_unused	= omap2_clk_disable_unused,
-};
-
-/*
- * Set clocks for bypass mode for reboot to work.
- */
-void omap2_clk_prepare_for_reboot(void)
-{
-	/* REVISIT: Not ready for 343x */
-#if 0
-	u32 rate;
-
-	if (vclk == NULL || sclk == NULL)
-		return;
-
-	rate = clk_get_rate(sclk);
-	clk_set_rate(vclk, rate);
-#endif
-}
-
-void omap3_clk_lock_dpll5(void)
-{
-	struct clk *dpll5_clk;
-	struct clk *dpll5_m2_clk;
-
-	dpll5_clk = clk_get(NULL, "dpll5_ck");
-	clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
-	clk_enable(dpll5_clk);
-
-	/* Enable autoidle to allow it to enter low power bypass */
-	omap3_dpll_allow_idle(dpll5_clk);
-
-	/* Program dpll5_m2_clk divider for no division */
-	dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
-	clk_enable(dpll5_m2_clk);
-	clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
-
-	clk_disable(dpll5_m2_clk);
-	clk_disable(dpll5_clk);
-	return;
-}
-
-/* REVISIT: Move this init stuff out into clock.c */
-
-/*
- * Switch the MPU rate if specified on cmdline.
- * We cannot do this early until cmdline is parsed.
- */
-static int __init omap2_clk_arch_init(void)
-{
-	struct clk *osc_sys_ck, *dpll1_ck, *arm_fck, *core_ck;
-	unsigned long osc_sys_rate;
-
-	if (!mpurate)
-		return -EINVAL;
-
-	/* XXX test these for success */
-	dpll1_ck = clk_get(NULL, "dpll1_ck");
-	arm_fck = clk_get(NULL, "arm_fck");
-	core_ck = clk_get(NULL, "core_ck");
-	osc_sys_ck = clk_get(NULL, "osc_sys_ck");
-
-	/* REVISIT: not yet ready for 343x */
-	if (clk_set_rate(dpll1_ck, mpurate))
-		printk(KERN_ERR "*** Unable to set MPU rate\n");
-
-	recalculate_root_clocks();
-
-	osc_sys_rate = clk_get_rate(osc_sys_ck);
-
-	pr_info("Switched to new clocking rate (Crystal/Core/MPU): "
-		"%ld.%01ld/%ld/%ld MHz\n",
-		(osc_sys_rate / 1000000),
-		((osc_sys_rate / 100000) % 10),
-		(clk_get_rate(core_ck) / 1000000),
-		(clk_get_rate(arm_fck) / 1000000));
-
-	calibrate_delay();
-
-	return 0;
-}
-arch_initcall(omap2_clk_arch_init);
-
-
-#endif
-
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock34xx_data.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock34xx_data.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock34xx_data.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock34xx_data.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,3289 +0,0 @@
-/*
- * OMAP3 clock data
- *
- * Copyright (C) 2007-2009 Texas Instruments, Inc.
- * Copyright (C) 2007-2009 Nokia Corporation
- *
- * Written by Paul Walmsley
- * With many device clock fixes by Kevin Hilman and Jouni HÃ¶gander
- * DPLL bypass clock support added by Roman Tereshonkov
- *
- */
-
-/*
- * Virtual clocks are introduced as convenient tools.
- * They are sources for other clocks and not supposed
- * to be requested from drivers directly.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/clk.h>
-
-#include <plat/control.h>
-#include <plat/clkdev_omap.h>
-
-#include "clock.h"
-#include "clock34xx.h"
-#include "cm.h"
-#include "cm-regbits-34xx.h"
-#include "prm.h"
-#include "prm-regbits-34xx.h"
-
-/*
- * clocks
- */
-
-#define OMAP_CM_REGADDR		OMAP34XX_CM_REGADDR
-
-/* Maximum DPLL multiplier, divider values for OMAP3 */
-#define OMAP3_MAX_DPLL_MULT		2048
-#define OMAP3_MAX_DPLL_DIV		128
-
-/*
- * DPLL1 supplies clock to the MPU.
- * DPLL2 supplies clock to the IVA2.
- * DPLL3 supplies CORE domain clocks.
- * DPLL4 supplies peripheral clocks.
- * DPLL5 supplies other peripheral clocks (USBHOST, USIM).
- */
-
-/* Forward declarations for DPLL bypass clocks */
-static struct clk dpll1_fck;
-static struct clk dpll2_fck;
-
-/* PRM CLOCKS */
-
-/* According to timer32k.c, this is a 32768Hz clock, not a 32000Hz clock. */
-static struct clk omap_32k_fck = {
-	.name		= "omap_32k_fck",
-	.ops		= &clkops_null,
-	.rate		= 32768,
-	.flags		= RATE_FIXED,
-};
-
-static struct clk secure_32k_fck = {
-	.name		= "secure_32k_fck",
-	.ops		= &clkops_null,
-	.rate		= 32768,
-	.flags		= RATE_FIXED,
-};
-
-/* Virtual source clocks for osc_sys_ck */
-static struct clk virt_12m_ck = {
-	.name		= "virt_12m_ck",
-	.ops		= &clkops_null,
-	.rate		= 12000000,
-	.flags		= RATE_FIXED,
-};
-
-static struct clk virt_13m_ck = {
-	.name		= "virt_13m_ck",
-	.ops		= &clkops_null,
-	.rate		= 13000000,
-	.flags		= RATE_FIXED,
-};
-
-static struct clk virt_16_8m_ck = {
-	.name		= "virt_16_8m_ck",
-	.ops		= &clkops_null,
-	.rate		= 16800000,
-	.flags		= RATE_FIXED,
-};
-
-static struct clk virt_19_2m_ck = {
-	.name		= "virt_19_2m_ck",
-	.ops		= &clkops_null,
-	.rate		= 19200000,
-	.flags		= RATE_FIXED,
-};
-
-static struct clk virt_26m_ck = {
-	.name		= "virt_26m_ck",
-	.ops		= &clkops_null,
-	.rate		= 26000000,
-	.flags		= RATE_FIXED,
-};
-
-static struct clk virt_38_4m_ck = {
-	.name		= "virt_38_4m_ck",
-	.ops		= &clkops_null,
-	.rate		= 38400000,
-	.flags		= RATE_FIXED,
-};
-
-static const struct clksel_rate osc_sys_12m_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate osc_sys_13m_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate osc_sys_16_8m_rates[] = {
-	{ .div = 1, .val = 5, .flags = RATE_IN_3430ES2 | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate osc_sys_19_2m_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate osc_sys_26m_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate osc_sys_38_4m_rates[] = {
-	{ .div = 1, .val = 4, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel osc_sys_clksel[] = {
-	{ .parent = &virt_12m_ck,   .rates = osc_sys_12m_rates },
-	{ .parent = &virt_13m_ck,   .rates = osc_sys_13m_rates },
-	{ .parent = &virt_16_8m_ck, .rates = osc_sys_16_8m_rates },
-	{ .parent = &virt_19_2m_ck, .rates = osc_sys_19_2m_rates },
-	{ .parent = &virt_26m_ck,   .rates = osc_sys_26m_rates },
-	{ .parent = &virt_38_4m_ck, .rates = osc_sys_38_4m_rates },
-	{ .parent = NULL },
-};
-
-/* Oscillator clock */
-/* 12, 13, 16.8, 19.2, 26, or 38.4 MHz */
-static struct clk osc_sys_ck = {
-	.name		= "osc_sys_ck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP3430_PRM_CLKSEL,
-	.clksel_mask	= OMAP3430_SYS_CLKIN_SEL_MASK,
-	.clksel		= osc_sys_clksel,
-	/* REVISIT: deal with autoextclkmode? */
-	.flags		= RATE_FIXED,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate div2_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 0 }
-};
-
-static const struct clksel sys_clksel[] = {
-	{ .parent = &osc_sys_ck, .rates = div2_rates },
-	{ .parent = NULL }
-};
-
-/* Latency: this clock is only enabled after PRM_CLKSETUP.SETUP_TIME */
-/* Feeds DPLLs - divided first by PRM_CLKSRC_CTRL.SYSCLKDIV? */
-static struct clk sys_ck = {
-	.name		= "sys_ck",
-	.ops		= &clkops_null,
-	.parent		= &osc_sys_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP3430_PRM_CLKSRC_CTRL,
-	.clksel_mask	= OMAP_SYSCLKDIV_MASK,
-	.clksel		= sys_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk sys_altclk = {
-	.name		= "sys_altclk",
-	.ops		= &clkops_null,
-};
-
-/* Optional external clock input for some McBSPs */
-static struct clk mcbsp_clks = {
-	.name		= "mcbsp_clks",
-	.ops		= &clkops_null,
-};
-
-/* PRM EXTERNAL CLOCK OUTPUT */
-
-static struct clk sys_clkout1 = {
-	.name		= "sys_clkout1",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &osc_sys_ck,
-	.enable_reg	= OMAP3430_PRM_CLKOUT_CTRL,
-	.enable_bit	= OMAP3430_CLKOUT_EN_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* DPLLS */
-
-/* CM CLOCKS */
-
-static const struct clksel_rate div16_dpll_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
-	{ .div = 5, .val = 5, .flags = RATE_IN_343X },
-	{ .div = 6, .val = 6, .flags = RATE_IN_343X },
-	{ .div = 7, .val = 7, .flags = RATE_IN_343X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_343X },
-	{ .div = 9, .val = 9, .flags = RATE_IN_343X },
-	{ .div = 10, .val = 10, .flags = RATE_IN_343X },
-	{ .div = 11, .val = 11, .flags = RATE_IN_343X },
-	{ .div = 12, .val = 12, .flags = RATE_IN_343X },
-	{ .div = 13, .val = 13, .flags = RATE_IN_343X },
-	{ .div = 14, .val = 14, .flags = RATE_IN_343X },
-	{ .div = 15, .val = 15, .flags = RATE_IN_343X },
-	{ .div = 16, .val = 16, .flags = RATE_IN_343X },
-	{ .div = 0 }
-};
-
-/* DPLL1 */
-/* MPU clock source */
-/* Type: DPLL */
-static struct dpll_data dpll1_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
-	.mult_mask	= OMAP3430_MPU_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_MPU_DPLL_DIV_MASK,
-	.clk_bypass	= &dpll1_fck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_MPU_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL),
-	.enable_mask	= OMAP3430_EN_MPU_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
-	.auto_recal_bit	= OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_MPU_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_MPU_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL),
-	.autoidle_mask	= OMAP3430_AUTO_MPU_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
-	.idlest_mask	= OMAP3430_ST_MPU_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
-};
-
-static struct clk dpll1_ck = {
-	.name		= "dpll1_ck",
-	.ops		= &clkops_null,
-	.parent		= &sys_ck,
-	.dpll_data	= &dpll1_dd,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.clkdm_name	= "dpll1_clkdm",
-	.recalc		= &omap3_dpll_recalc,
-};
-
-/*
- * This virtual clock provides the CLKOUTX2 output from the DPLL if the
- * DPLL isn't bypassed.
- */
-static struct clk dpll1_x2_ck = {
-	.name		= "dpll1_x2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll1_ck,
-	.clkdm_name	= "dpll1_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-/* On DPLL1, unlike other DPLLs, the divider is downstream from CLKOUTX2 */
-static const struct clksel div16_dpll1_x2m2_clksel[] = {
-	{ .parent = &dpll1_x2_ck, .rates = div16_dpll_rates },
-	{ .parent = NULL }
-};
-
-/*
- * Does not exist in the TRM - needed to separate the M2 divider from
- * bypass selection in mpu_ck
- */
-static struct clk dpll1_x2m2_ck = {
-	.name		= "dpll1_x2m2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll1_x2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL),
-	.clksel_mask	= OMAP3430_MPU_DPLL_CLKOUT_DIV_MASK,
-	.clksel		= div16_dpll1_x2m2_clksel,
-	.clkdm_name	= "dpll1_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* DPLL2 */
-/* IVA2 clock source */
-/* Type: DPLL */
-
-static struct dpll_data dpll2_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
-	.mult_mask	= OMAP3430_IVA2_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_IVA2_DPLL_DIV_MASK,
-	.clk_bypass	= &dpll2_fck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_IVA2_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL),
-	.enable_mask	= OMAP3430_EN_IVA2_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) |
-				(1 << DPLL_LOW_POWER_BYPASS),
-	.auto_recal_bit	= OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL),
-	.autoidle_mask	= OMAP3430_AUTO_IVA2_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL),
-	.idlest_mask	= OMAP3430_ST_IVA2_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
-};
-
-static struct clk dpll2_ck = {
-	.name		= "dpll2_ck",
-	.ops		= &clkops_noncore_dpll_ops,
-	.parent		= &sys_ck,
-	.dpll_data	= &dpll2_dd,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.clkdm_name	= "dpll2_clkdm",
-	.recalc		= &omap3_dpll_recalc,
-};
-
-static const struct clksel div16_dpll2_m2x2_clksel[] = {
-	{ .parent = &dpll2_ck, .rates = div16_dpll_rates },
-	{ .parent = NULL }
-};
-
-/*
- * The TRM is conflicted on whether IVA2 clock comes from DPLL2 CLKOUT
- * or CLKOUTX2. CLKOUT seems most plausible.
- */
-static struct clk dpll2_m2_ck = {
-	.name		= "dpll2_m2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD,
-					  OMAP3430_CM_CLKSEL2_PLL),
-	.clksel_mask	= OMAP3430_IVA2_DPLL_CLKOUT_DIV_MASK,
-	.clksel		= div16_dpll2_m2x2_clksel,
-	.clkdm_name	= "dpll2_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/*
- * DPLL3
- * Source clock for all interfaces and for some device fclks
- * REVISIT: Also supports fast relock bypass - not included below
- */
-static struct dpll_data dpll3_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.mult_mask	= OMAP3430_CORE_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_CORE_DPLL_DIV_MASK,
-	.clk_bypass	= &sys_ck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_CORE_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_mask	= OMAP3430_EN_CORE_DPLL_MASK,
-	.auto_recal_bit	= OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_CORE_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_CORE_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
-	.autoidle_mask	= OMAP3430_AUTO_CORE_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.idlest_mask	= OMAP3430_ST_CORE_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
-};
-
-static struct clk dpll3_ck = {
-	.name		= "dpll3_ck",
-	.ops		= &clkops_null,
-	.parent		= &sys_ck,
-	.dpll_data	= &dpll3_dd,
-	.round_rate	= &omap2_dpll_round_rate,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &omap3_dpll_recalc,
-};
-
-/*
- * This virtual clock provides the CLKOUTX2 output from the DPLL if the
- * DPLL isn't bypassed
- */
-static struct clk dpll3_x2_ck = {
-	.name		= "dpll3_x2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_ck,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static const struct clksel_rate div31_dpll3_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 3, .val = 3, .flags = RATE_IN_3430ES2 },
-	{ .div = 4, .val = 4, .flags = RATE_IN_3430ES2 },
-	{ .div = 5, .val = 5, .flags = RATE_IN_3430ES2 },
-	{ .div = 6, .val = 6, .flags = RATE_IN_3430ES2 },
-	{ .div = 7, .val = 7, .flags = RATE_IN_3430ES2 },
-	{ .div = 8, .val = 8, .flags = RATE_IN_3430ES2 },
-	{ .div = 9, .val = 9, .flags = RATE_IN_3430ES2 },
-	{ .div = 10, .val = 10, .flags = RATE_IN_3430ES2 },
-	{ .div = 11, .val = 11, .flags = RATE_IN_3430ES2 },
-	{ .div = 12, .val = 12, .flags = RATE_IN_3430ES2 },
-	{ .div = 13, .val = 13, .flags = RATE_IN_3430ES2 },
-	{ .div = 14, .val = 14, .flags = RATE_IN_3430ES2 },
-	{ .div = 15, .val = 15, .flags = RATE_IN_3430ES2 },
-	{ .div = 16, .val = 16, .flags = RATE_IN_3430ES2 },
-	{ .div = 17, .val = 17, .flags = RATE_IN_3430ES2 },
-	{ .div = 18, .val = 18, .flags = RATE_IN_3430ES2 },
-	{ .div = 19, .val = 19, .flags = RATE_IN_3430ES2 },
-	{ .div = 20, .val = 20, .flags = RATE_IN_3430ES2 },
-	{ .div = 21, .val = 21, .flags = RATE_IN_3430ES2 },
-	{ .div = 22, .val = 22, .flags = RATE_IN_3430ES2 },
-	{ .div = 23, .val = 23, .flags = RATE_IN_3430ES2 },
-	{ .div = 24, .val = 24, .flags = RATE_IN_3430ES2 },
-	{ .div = 25, .val = 25, .flags = RATE_IN_3430ES2 },
-	{ .div = 26, .val = 26, .flags = RATE_IN_3430ES2 },
-	{ .div = 27, .val = 27, .flags = RATE_IN_3430ES2 },
-	{ .div = 28, .val = 28, .flags = RATE_IN_3430ES2 },
-	{ .div = 29, .val = 29, .flags = RATE_IN_3430ES2 },
-	{ .div = 30, .val = 30, .flags = RATE_IN_3430ES2 },
-	{ .div = 31, .val = 31, .flags = RATE_IN_3430ES2 },
-	{ .div = 0 },
-};
-
-static const struct clksel div31_dpll3m2_clksel[] = {
-	{ .parent = &dpll3_ck, .rates = div31_dpll3_rates },
-	{ .parent = NULL }
-};
-
-/* DPLL3 output M2 - primary control point for CORE speed */
-static struct clk dpll3_m2_ck = {
-	.name		= "dpll3_m2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK,
-	.clksel		= div31_dpll3m2_clksel,
-	.clkdm_name	= "dpll3_clkdm",
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap3_core_dpll_m2_set_rate,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk core_ck = {
-	.name		= "core_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_m2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dpll3_m2x2_ck = {
-	.name		= "dpll3_m2x2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_m2_ck,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static const struct clksel div16_dpll3_clksel[] = {
-	{ .parent = &dpll3_ck, .rates = div16_dpll_rates },
-	{ .parent = NULL }
-};
-
-/* This virtual clock is the source for dpll3_m3x2_ck */
-static struct clk dpll3_m3_ck = {
-	.name		= "dpll3_m3_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_DIV_DPLL3_MASK,
-	.clksel		= div16_dpll3_clksel,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll3_m3x2_ck = {
-	.name		= "dpll3_m3x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll3_m3_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_EMU_CORE_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static struct clk emu_core_alwon_ck = {
-	.name		= "emu_core_alwon_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_m3x2_ck,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* DPLL4 */
-/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */
-/* Type: DPLL */
-static struct dpll_data dpll4_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
-	.mult_mask	= OMAP3430_PERIPH_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_PERIPH_DPLL_DIV_MASK,
-	.clk_bypass	= &sys_ck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_PERIPH_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_mask	= OMAP3430_EN_PERIPH_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
-	.auto_recal_bit	= OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_PERIPH_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
-	.autoidle_mask	= OMAP3430_AUTO_PERIPH_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.idlest_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
-};
-
-static struct clk dpll4_ck = {
-	.name		= "dpll4_ck",
-	.ops		= &clkops_noncore_dpll_ops,
-	.parent		= &sys_ck,
-	.dpll_data	= &dpll4_dd,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_dpll4_set_rate,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_dpll_recalc,
-};
-
-/*
- * This virtual clock provides the CLKOUTX2 output from the DPLL if the
- * DPLL isn't bypassed --
- * XXX does this serve any downstream clocks?
- */
-static struct clk dpll4_x2_ck = {
-	.name		= "dpll4_x2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static const struct clksel div16_dpll4_clksel[] = {
-	{ .parent = &dpll4_ck, .rates = div16_dpll_rates },
-	{ .parent = NULL }
-};
-
-/* This virtual clock is the source for dpll4_m2x2_ck */
-static struct clk dpll4_m2_ck = {
-	.name		= "dpll4_m2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430_CM_CLKSEL3),
-	.clksel_mask	= OMAP3430_DIV_96M_MASK,
-	.clksel		= div16_dpll4_clksel,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll4_m2x2_ck = {
-	.name		= "dpll4_m2x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll4_m2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_96M_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-/*
- * DPLL4 generates DPLL4_M2X2_CLK which is then routed into the PRM as
- * PRM_96M_ALWON_(F)CLK.  Two clocks then emerge from the PRM:
- * 96M_ALWON_FCLK (called "omap_96m_alwon_fck" below) and
- * CM_96K_(F)CLK.
- */
-static struct clk omap_96m_alwon_fck = {
-	.name		= "omap_96m_alwon_fck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_m2x2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk cm_96m_fck = {
-	.name		= "cm_96m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_96m_alwon_fck,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel_rate omap_96m_dpll_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate omap_96m_sys_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel omap_96m_fck_clksel[] = {
-	{ .parent = &cm_96m_fck, .rates = omap_96m_dpll_rates },
-	{ .parent = &sys_ck,	 .rates = omap_96m_sys_rates },
-	{ .parent = NULL }
-};
-
-static struct clk omap_96m_fck = {
-	.name		= "omap_96m_fck",
-	.ops		= &clkops_null,
-	.parent		= &sys_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_SOURCE_96M_MASK,
-	.clksel		= omap_96m_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* This virtual clock is the source for dpll4_m3x2_ck */
-static struct clk dpll4_m3_ck = {
-	.name		= "dpll4_m3_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_TV_MASK,
-	.clksel		= div16_dpll4_clksel,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll4_m3x2_ck = {
-	.name		= "dpll4_m3x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll4_m3_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_TV_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static const struct clksel_rate omap_54m_d4m3x2_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate omap_54m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel omap_54m_clksel[] = {
-	{ .parent = &dpll4_m3x2_ck, .rates = omap_54m_d4m3x2_rates },
-	{ .parent = &sys_altclk,    .rates = omap_54m_alt_rates },
-	{ .parent = NULL }
-};
-
-static struct clk omap_54m_fck = {
-	.name		= "omap_54m_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_SOURCE_54M_MASK,
-	.clksel		= omap_54m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate omap_48m_cm96m_rates[] = {
-	{ .div = 2, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate omap_48m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel omap_48m_clksel[] = {
-	{ .parent = &cm_96m_fck, .rates = omap_48m_cm96m_rates },
-	{ .parent = &sys_altclk, .rates = omap_48m_alt_rates },
-	{ .parent = NULL }
-};
-
-static struct clk omap_48m_fck = {
-	.name		= "omap_48m_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_SOURCE_48M_MASK,
-	.clksel		= omap_48m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk omap_12m_fck = {
-	.name		= "omap_12m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_48m_fck,
-	.fixed_div	= 4,
-	.recalc		= &omap2_fixed_divisor_recalc,
-};
-
-/* This virstual clock is the source for dpll4_m4x2_ck */
-static struct clk dpll4_m4_ck = {
-	.name		= "dpll4_m4_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_DSS1_MASK,
-	.clksel		= div16_dpll4_clksel,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-	.set_rate	= &omap2_clksel_set_rate,
-	.round_rate	= &omap2_clksel_round_rate,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll4_m4x2_ck = {
-	.name		= "dpll4_m4x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll4_m4_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_CAM_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-/* This virtual clock is the source for dpll4_m5x2_ck */
-static struct clk dpll4_m5_ck = {
-	.name		= "dpll4_m5_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_CAM_MASK,
-	.clksel		= div16_dpll4_clksel,
-	.clkdm_name	= "dpll4_clkdm",
-	.set_rate	= &omap2_clksel_set_rate,
-	.round_rate	= &omap2_clksel_round_rate,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll4_m5x2_ck = {
-	.name		= "dpll4_m5x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll4_m5_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_CAM_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-/* This virtual clock is the source for dpll4_m6x2_ck */
-static struct clk dpll4_m6_ck = {
-	.name		= "dpll4_m6_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_DIV_DPLL4_MASK,
-	.clksel		= div16_dpll4_clksel,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll4_m6x2_ck = {
-	.name		= "dpll4_m6x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll4_m6_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_EMU_PERIPH_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static struct clk emu_per_alwon_ck = {
-	.name		= "emu_per_alwon_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_m6x2_ck,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* DPLL5 */
-/* Supplies 120MHz clock, USIM source clock */
-/* Type: DPLL */
-/* 3430ES2 only */
-static struct dpll_data dpll5_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4),
-	.mult_mask	= OMAP3430ES2_PERIPH2_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430ES2_PERIPH2_DPLL_DIV_MASK,
-	.clk_bypass	= &sys_ck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430ES2_PERIPH2_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2),
-	.enable_mask	= OMAP3430ES2_EN_PERIPH2_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
-	.auto_recal_bit	= OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL),
-	.autoidle_mask	= OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
-	.idlest_mask	= OMAP3430ES2_ST_PERIPH2_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
-};
-
-static struct clk dpll5_ck = {
-	.name		= "dpll5_ck",
-	.ops		= &clkops_noncore_dpll_ops,
-	.parent		= &sys_ck,
-	.dpll_data	= &dpll5_dd,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.clkdm_name	= "dpll5_clkdm",
-	.recalc		= &omap3_dpll_recalc,
-};
-
-static const struct clksel div16_dpll5_clksel[] = {
-	{ .parent = &dpll5_ck, .rates = div16_dpll_rates },
-	{ .parent = NULL }
-};
-
-static struct clk dpll5_m2_ck = {
-	.name		= "dpll5_m2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll5_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL5),
-	.clksel_mask	= OMAP3430ES2_DIV_120M_MASK,
-	.clksel		= div16_dpll5_clksel,
-	.clkdm_name	= "dpll5_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* CM EXTERNAL CLOCK OUTPUTS */
-
-static const struct clksel_rate clkout2_src_core_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate clkout2_src_sys_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate clkout2_src_96m_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate clkout2_src_54m_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel clkout2_src_clksel[] = {
-	{ .parent = &core_ck,		.rates = clkout2_src_core_rates },
-	{ .parent = &sys_ck,		.rates = clkout2_src_sys_rates },
-	{ .parent = &cm_96m_fck,	.rates = clkout2_src_96m_rates },
-	{ .parent = &omap_54m_fck,	.rates = clkout2_src_54m_rates },
-	{ .parent = NULL }
-};
-
-static struct clk clkout2_src_ck = {
-	.name		= "clkout2_src_ck",
-	.ops		= &clkops_omap2_dflt,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP3430_CM_CLKOUT_CTRL,
-	.enable_bit	= OMAP3430_CLKOUT2_EN_SHIFT,
-	.clksel_reg	= OMAP3430_CM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP3430_CLKOUT2SOURCE_MASK,
-	.clksel		= clkout2_src_clksel,
-	.clkdm_name	= "core_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate sys_clkout2_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 1, .flags = RATE_IN_343X },
-	{ .div = 4, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 8, .val = 3, .flags = RATE_IN_343X },
-	{ .div = 16, .val = 4, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel sys_clkout2_clksel[] = {
-	{ .parent = &clkout2_src_ck, .rates = sys_clkout2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk sys_clkout2 = {
-	.name		= "sys_clkout2",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP3430_CM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP3430_CLKOUT2_DIV_MASK,
-	.clksel		= sys_clkout2_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* CM OUTPUT CLOCKS */
-
-static struct clk corex2_fck = {
-	.name		= "corex2_fck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_m2x2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-/* DPLL power domain clock controls */
-
-static const struct clksel_rate div4_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
-	{ .div = 0 }
-};
-
-static const struct clksel div4_core_clksel[] = {
-	{ .parent = &core_ck, .rates = div4_rates },
-	{ .parent = NULL }
-};
-
-/*
- * REVISIT: Are these in DPLL power domain or CM power domain? docs
- * may be inconsistent here?
- */
-static struct clk dpll1_fck = {
-	.name		= "dpll1_fck",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
-	.clksel_mask	= OMAP3430_MPU_CLK_SRC_MASK,
-	.clksel		= div4_core_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mpu_ck = {
-	.name		= "mpu_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll1_x2m2_ck,
-	.clkdm_name	= "mpu_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* arm_fck is divided by two when DPLL1 locked; otherwise, passthrough mpu_ck */
-static const struct clksel_rate arm_fck_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 1, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel arm_fck_clksel[] = {
-	{ .parent = &mpu_ck, .rates = arm_fck_rates },
-	{ .parent = NULL }
-};
-
-static struct clk arm_fck = {
-	.name		= "arm_fck",
-	.ops		= &clkops_null,
-	.parent		= &mpu_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
-	.clksel_mask	= OMAP3430_ST_MPU_CLK_MASK,
-	.clksel		= arm_fck_clksel,
-	.clkdm_name	= "mpu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* XXX What about neon_clkdm ? */
-
-/*
- * REVISIT: This clock is never specifically defined in the 3430 TRM,
- * although it is referenced - so this is a guess
- */
-static struct clk emu_mpu_alwon_ck = {
-	.name		= "emu_mpu_alwon_ck",
-	.ops		= &clkops_null,
-	.parent		= &mpu_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dpll2_fck = {
-	.name		= "dpll2_fck",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
-	.clksel_mask	= OMAP3430_IVA2_CLK_SRC_MASK,
-	.clksel		= div4_core_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk iva2_ck = {
-	.name		= "iva2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll2_m2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
-	.clkdm_name	= "iva2_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* Common interface clocks */
-
-static const struct clksel div2_core_clksel[] = {
-	{ .parent = &core_ck, .rates = div2_rates },
-	{ .parent = NULL }
-};
-
-static struct clk l3_ick = {
-	.name		= "l3_ick",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_L3_MASK,
-	.clksel		= div2_core_clksel,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel div2_l3_clksel[] = {
-	{ .parent = &l3_ick, .rates = div2_rates },
-	{ .parent = NULL }
-};
-
-static struct clk l4_ick = {
-	.name		= "l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &l3_ick,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_L4_MASK,
-	.clksel		= div2_l3_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-
-};
-
-static const struct clksel div2_l4_clksel[] = {
-	{ .parent = &l4_ick, .rates = div2_rates },
-	{ .parent = NULL }
-};
-
-static struct clk rm_ick = {
-	.name		= "rm_ick",
-	.ops		= &clkops_null,
-	.parent		= &l4_ick,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_RM_MASK,
-	.clksel		= div2_l4_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* GFX power domain */
-
-/* GFX clocks are in 3430ES1 only. 3430ES2 and later uses the SGX instead */
-
-static const struct clksel gfx_l3_clksel[] = {
-	{ .parent = &l3_ick, .rates = gfx_l3_rates },
-	{ .parent = NULL }
-};
-
-/* Virtual parent clock for gfx_l3_ick and gfx_l3_fck */
-static struct clk gfx_l3_ck = {
-	.name		= "gfx_l3_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP_EN_GFX_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gfx_l3_fck = {
-	.name		= "gfx_l3_fck",
-	.ops		= &clkops_null,
-	.parent		= &gfx_l3_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
-	.clksel		= gfx_l3_clksel,
-	.clkdm_name	= "gfx_3430es1_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gfx_l3_ick = {
-	.name		= "gfx_l3_ick",
-	.ops		= &clkops_null,
-	.parent		= &gfx_l3_ck,
-	.clkdm_name	= "gfx_3430es1_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gfx_cg1_ck = {
-	.name		= "gfx_cg1_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &gfx_l3_fck, /* REVISIT: correct? */
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES1_EN_2D_SHIFT,
-	.clkdm_name	= "gfx_3430es1_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gfx_cg2_ck = {
-	.name		= "gfx_cg2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &gfx_l3_fck, /* REVISIT: correct? */
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES1_EN_3D_SHIFT,
-	.clkdm_name	= "gfx_3430es1_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* SGX power domain - 3430ES2 only */
-
-static const struct clksel_rate sgx_core_rates[] = {
-	{ .div = 3, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 4, .val = 1, .flags = RATE_IN_343X },
-	{ .div = 6, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate sgx_96m_rates[] = {
-	{ .div = 1,  .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel sgx_clksel[] = {
-	{ .parent = &core_ck,	 .rates = sgx_core_rates },
-	{ .parent = &cm_96m_fck, .rates = sgx_96m_rates },
-	{ .parent = NULL },
-};
-
-static struct clk sgx_fck = {
-	.name		= "sgx_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430ES2_CLKSEL_SGX_MASK,
-	.clksel		= sgx_clksel,
-	.clkdm_name	= "sgx_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk sgx_ick = {
-	.name		= "sgx_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT,
-	.clkdm_name	= "sgx_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* CORE power domain */
-
-static struct clk d2d_26m_fck = {
-	.name		= "d2d_26m_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430ES1_EN_D2D_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk modem_fck = {
-	.name		= "modem_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MODEM_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sad2d_ick = {
-	.name		= "sad2d_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SAD2D_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mad2d_ick = {
-	.name		= "mad2d_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP3430_EN_MAD2D_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel omap343x_gpt_clksel[] = {
-	{ .parent = &omap_32k_fck, .rates = gpt_32k_rates },
-	{ .parent = &sys_ck,	   .rates = gpt_sys_rates },
-	{ .parent = NULL}
-};
-
-static struct clk gpt10_fck = {
-	.name		= "gpt10_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_GPT10_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT10_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt11_fck = {
-	.name		= "gpt11_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_GPT11_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT11_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk cpefuse_fck = {
-	.name		= "cpefuse_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_CPEFUSE_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk ts_fck = {
-	.name		= "ts_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &omap_32k_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_TS_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbtll_fck = {
-	.name		= "usbtll_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &dpll5_m2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* CORE 96M FCLK-derived clocks */
-
-static struct clk core_96m_fck = {
-	.name		= "core_96m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_96m_fck,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs3_fck = {
-	.name		= "mmchs_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430ES2_EN_MMC3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs2_fck = {
-	.name		= "mmchs_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mspro_fck = {
-	.name		= "mspro_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MSPRO_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs1_fck = {
-	.name		= "mmchs_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c3_fck = {
-	.name		= "i2c_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c2_fck = {
-	.name		= "i2c_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c1_fck = {
-	.name		= "i2c_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * MCBSP 1 & 5 get their 96MHz clock from core_96m_fck;
- * MCBSP 2, 3, 4 get their 96MHz clock from per_96m_fck.
- */
-static const struct clksel_rate common_mcbsp_96m_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel mcbsp_15_clksel[] = {
-	{ .parent = &core_96m_fck, .rates = common_mcbsp_96m_rates },
-	{ .parent = &mcbsp_clks,   .rates = common_mcbsp_mcbsp_rates },
-	{ .parent = NULL }
-};
-
-static struct clk mcbsp5_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 5,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCBSP5_SHIFT,
-	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
-	.clksel_mask	= OMAP2_MCBSP5_CLKS_MASK,
-	.clksel		= mcbsp_15_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp1_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCBSP1_SHIFT,
-	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
-	.clksel_mask	= OMAP2_MCBSP1_CLKS_MASK,
-	.clksel		= mcbsp_15_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* CORE_48M_FCK-derived clocks */
-
-static struct clk core_48m_fck = {
-	.name		= "core_48m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_48m_fck,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi4_fck = {
-	.name		= "mcspi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 4,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi3_fck = {
-	.name		= "mcspi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi2_fck = {
-	.name		= "mcspi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi1_fck = {
-	.name		= "mcspi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart2_fck = {
-	.name		= "uart2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_UART2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart1_fck = {
-	.name		= "uart1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_UART1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk fshostusb_fck = {
-	.name		= "fshostusb_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* CORE_12M_FCK based clocks */
-
-static struct clk core_12m_fck = {
-	.name		= "core_12m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_12m_fck,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hdq_fck = {
-	.name		= "hdq_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_12m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_HDQ_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* DPLL3-derived clock */
-
-static const struct clksel_rate ssi_ssr_corex2_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
-	{ .div = 6, .val = 6, .flags = RATE_IN_343X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_343X },
-	{ .div = 0 }
-};
-
-static const struct clksel ssi_ssr_clksel[] = {
-	{ .parent = &corex2_fck, .rates = ssi_ssr_corex2_rates },
-	{ .parent = NULL }
-};
-
-static struct clk ssi_ssr_fck_3430es1 = {
-	.name		= "ssi_ssr_fck",
-	.ops		= &clkops_omap2_dflt,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_SSI_MASK,
-	.clksel		= ssi_ssr_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk ssi_ssr_fck_3430es2 = {
-	.name		= "ssi_ssr_fck",
-	.ops		= &clkops_omap3430es2_ssi_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_SSI_MASK,
-	.clksel		= ssi_ssr_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk ssi_sst_fck_3430es1 = {
-	.name		= "ssi_sst_fck",
-	.ops		= &clkops_null,
-	.parent		= &ssi_ssr_fck_3430es1,
-	.fixed_div	= 2,
-	.recalc		= &omap2_fixed_divisor_recalc,
-};
-
-static struct clk ssi_sst_fck_3430es2 = {
-	.name		= "ssi_sst_fck",
-	.ops		= &clkops_null,
-	.parent		= &ssi_ssr_fck_3430es2,
-	.fixed_div	= 2,
-	.recalc		= &omap2_fixed_divisor_recalc,
-};
-
-
-
-/* CORE_L3_ICK based clocks */
-
-/*
- * XXX must add clk_enable/clk_disable for these if standard code won't
- * handle it
- */
-static struct clk core_l3_ick = {
-	.name		= "core_l3_ick",
-	.ops		= &clkops_null,
-	.parent		= &l3_ick,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hsotgusb_ick_3430es1 = {
-	.name		= "hsotgusb_ick",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &core_l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hsotgusb_ick_3430es2 = {
-	.name		= "hsotgusb_ick",
-	.ops		= &clkops_omap3430es2_hsotgusb_wait,
-	.parent		= &core_l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sdrc_ick = {
-	.name		= "sdrc_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SDRC_SHIFT,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpmc_fck = {
-	.name		= "gpmc_fck",
-	.ops		= &clkops_null,
-	.parent		= &core_l3_ick,
-	.flags		= ENABLE_ON_INIT, /* huh? */
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* SECURITY_L3_ICK based clocks */
-
-static struct clk security_l3_ick = {
-	.name		= "security_l3_ick",
-	.ops		= &clkops_null,
-	.parent		= &l3_ick,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk pka_ick = {
-	.name		= "pka_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &security_l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_PKA_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* CORE_L4_ICK based clocks */
-
-static struct clk core_l4_ick = {
-	.name		= "core_l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &l4_ick,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbtll_ick = {
-	.name		= "usbtll_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs3_ick = {
-	.name		= "mmchs_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430ES2_EN_MMC3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* Intersystem Communication Registers - chassis mode only */
-static struct clk icr_ick = {
-	.name		= "icr_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_ICR_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk aes2_ick = {
-	.name		= "aes2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_AES2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sha12_ick = {
-	.name		= "sha12_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SHA12_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk des2_ick = {
-	.name		= "des2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_DES2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs2_ick = {
-	.name		= "mmchs_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs1_ick = {
-	.name		= "mmchs_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mspro_ick = {
-	.name		= "mspro_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MSPRO_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hdq_ick = {
-	.name		= "hdq_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_HDQ_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi4_ick = {
-	.name		= "mcspi_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 4,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI4_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi3_ick = {
-	.name		= "mcspi_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi2_ick = {
-	.name		= "mcspi_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi1_ick = {
-	.name		= "mcspi_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c3_ick = {
-	.name		= "i2c_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c2_ick = {
-	.name		= "i2c_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c1_ick = {
-	.name		= "i2c_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart2_ick = {
-	.name		= "uart2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_UART2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart1_ick = {
-	.name		= "uart1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_UART1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt11_ick = {
-	.name		= "gpt11_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_GPT11_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt10_ick = {
-	.name		= "gpt10_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_GPT10_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp5_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 5,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCBSP5_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp1_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCBSP1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk fac_ick = {
-	.name		= "fac_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430ES1_EN_FAC_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mailboxes_ick = {
-	.name		= "mailboxes_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MAILBOXES_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk omapctrl_ick = {
-	.name		= "omapctrl_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_OMAPCTRL_SHIFT,
-	.flags		= ENABLE_ON_INIT,
-	.recalc		= &followparent_recalc,
-};
-
-/* SSI_L4_ICK based clocks */
-
-static struct clk ssi_l4_ick = {
-	.name		= "ssi_l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &l4_ick,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk ssi_ick_3430es1 = {
-	.name		= "ssi_ick",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &ssi_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk ssi_ick_3430es2 = {
-	.name		= "ssi_ick",
-	.ops		= &clkops_omap3430es2_ssi_wait,
-	.parent		= &ssi_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* REVISIT: Technically the TRM claims that this is CORE_CLK based,
- * but l4_ick makes more sense to me */
-
-static const struct clksel usb_l4_clksel[] = {
-	{ .parent = &l4_ick, .rates = div2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk usb_l4_ick = {
-	.name		= "usb_l4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ick,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK,
-	.clksel		= usb_l4_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* SECURITY_L4_ICK2 based clocks */
-
-static struct clk security_l4_ick2 = {
-	.name		= "security_l4_ick2",
-	.ops		= &clkops_null,
-	.parent		= &l4_ick,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk aes1_ick = {
-	.name		= "aes1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &security_l4_ick2,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_AES1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk rng_ick = {
-	.name		= "rng_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &security_l4_ick2,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_RNG_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sha11_ick = {
-	.name		= "sha11_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &security_l4_ick2,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_SHA11_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk des1_ick = {
-	.name		= "des1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &security_l4_ick2,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_DES1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* DSS */
-static struct clk dss1_alwon_fck_3430es1 = {
-	.name		= "dss1_alwon_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &dpll4_m4x2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss1_alwon_fck_3430es2 = {
-	.name		= "dss1_alwon_fck",
-	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
-	.parent		= &dpll4_m4x2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_tv_fck = {
-	.name		= "dss_tv_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &omap_54m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_TV_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_96m_fck = {
-	.name		= "dss_96m_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &omap_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_TV_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss2_alwon_fck = {
-	.name		= "dss2_alwon_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_DSS2_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_ick_3430es1 = {
-	/* Handles both L3 and L4 clocks */
-	.name		= "dss_ick",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_ick_3430es2 = {
-	/* Handles both L3 and L4 clocks */
-	.name		= "dss_ick",
-	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
-	.parent		= &l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* CAM */
-
-static struct clk cam_mclk = {
-	.name		= "cam_mclk",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &dpll4_m5x2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
-	.clkdm_name	= "cam_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk cam_ick = {
-	/* Handles both L3 and L4 clocks */
-	.name		= "cam_ick",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
-	.clkdm_name	= "cam_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk csi2_96m_fck = {
-	.name		= "csi2_96m_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_CSI2_SHIFT,
-	.clkdm_name	= "cam_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* USBHOST - 3430ES2 only */
-
-static struct clk usbhost_120m_fck = {
-	.name		= "usbhost_120m_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &dpll5_m2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USBHOST2_SHIFT,
-	.clkdm_name	= "usbhost_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbhost_48m_fck = {
-	.name		= "usbhost_48m_fck",
-	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
-	.parent		= &omap_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USBHOST1_SHIFT,
-	.clkdm_name	= "usbhost_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbhost_ick = {
-	/* Handles both L3 and L4 clocks */
-	.name		= "usbhost_ick",
-	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
-	.parent		= &l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USBHOST_SHIFT,
-	.clkdm_name	= "usbhost_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* WKUP */
-
-static const struct clksel_rate usim_96m_rates[] = {
-	{ .div = 2,  .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 4,  .val = 4, .flags = RATE_IN_343X },
-	{ .div = 8,  .val = 5, .flags = RATE_IN_343X },
-	{ .div = 10, .val = 6, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate usim_120m_rates[] = {
-	{ .div = 4,  .val = 7,	.flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 8,  .val = 8,	.flags = RATE_IN_343X },
-	{ .div = 16, .val = 9,	.flags = RATE_IN_343X },
-	{ .div = 20, .val = 10, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel usim_clksel[] = {
-	{ .parent = &omap_96m_fck,	.rates = usim_96m_rates },
-	{ .parent = &dpll5_m2_ck,	.rates = usim_120m_rates },
-	{ .parent = &sys_ck,		.rates = div2_rates },
-	{ .parent = NULL },
-};
-
-/* 3430ES2 only */
-static struct clk usim_fck = {
-	.name		= "usim_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USIMOCP_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430ES2_CLKSEL_USIMOCP_MASK,
-	.clksel		= usim_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* XXX should gpt1's clksel have wkup_32k_fck as the 32k opt? */
-static struct clk gpt1_fck = {
-	.name		= "gpt1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT1_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT1_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk wkup_32k_fck = {
-	.name		= "wkup_32k_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_32k_fck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio1_dbck = {
-	.name		= "gpio1_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &wkup_32k_fck,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt2_fck = {
-	.name		= "wdt2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_32k_fck,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_WDT2_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wkup_l4_ick = {
-	.name		= "wkup_l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &sys_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* 3430ES2 only */
-/* Never specifically named in the TRM, so we have to infer a likely name */
-static struct clk usim_ick = {
-	.name		= "usim_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USIMOCP_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt2_ick = {
-	.name		= "wdt2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_WDT2_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt1_ick = {
-	.name		= "wdt1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_WDT1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio1_ick = {
-	.name		= "gpio1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk omap_32ksync_ick = {
-	.name		= "omap_32ksync_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_32KSYNC_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* XXX This clock no longer exists in 3430 TRM rev F */
-static struct clk gpt12_ick = {
-	.name		= "gpt12_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT12_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt1_ick = {
-	.name		= "gpt1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-
-
-/* PER clock domain */
-
-static struct clk per_96m_fck = {
-	.name		= "per_96m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_96m_alwon_fck,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk per_48m_fck = {
-	.name		= "per_48m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_48m_fck,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart3_fck = {
-	.name		= "uart3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_UART3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt2_fck = {
-	.name		= "gpt2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT2_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT2_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt3_fck = {
-	.name		= "gpt3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT3_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT3_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt4_fck = {
-	.name		= "gpt4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT4_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT4_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt5_fck = {
-	.name		= "gpt5_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT5_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT5_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt6_fck = {
-	.name		= "gpt6_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT6_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT6_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt7_fck = {
-	.name		= "gpt7_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT7_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT7_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt8_fck = {
-	.name		= "gpt8_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT8_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT8_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt9_fck = {
-	.name		= "gpt9_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT9_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT9_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk per_32k_alwon_fck = {
-	.name		= "per_32k_alwon_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_32k_fck,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio6_dbck = {
-	.name		= "gpio6_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO6_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio5_dbck = {
-	.name		= "gpio5_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO5_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio4_dbck = {
-	.name		= "gpio4_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio3_dbck = {
-	.name		= "gpio3_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio2_dbck = {
-	.name		= "gpio2_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt3_fck = {
-	.name		= "wdt3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_WDT3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk per_l4_ick = {
-	.name		= "per_l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &l4_ick,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio6_ick = {
-	.name		= "gpio6_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO6_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio5_ick = {
-	.name		= "gpio5_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO5_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio4_ick = {
-	.name		= "gpio4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio3_ick = {
-	.name		= "gpio3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio2_ick = {
-	.name		= "gpio2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt3_ick = {
-	.name		= "wdt3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_WDT3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart3_ick = {
-	.name		= "uart3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_UART3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt9_ick = {
-	.name		= "gpt9_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT9_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt8_ick = {
-	.name		= "gpt8_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT8_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt7_ick = {
-	.name		= "gpt7_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT7_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt6_ick = {
-	.name		= "gpt6_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT6_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt5_ick = {
-	.name		= "gpt5_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT5_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt4_ick = {
-	.name		= "gpt4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt3_ick = {
-	.name		= "gpt3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt2_ick = {
-	.name		= "gpt2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp2_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp3_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp4_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 4,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel mcbsp_234_clksel[] = {
-	{ .parent = &per_96m_fck,  .rates = common_mcbsp_96m_rates },
-	{ .parent = &mcbsp_clks,   .rates = common_mcbsp_mcbsp_rates },
-	{ .parent = NULL }
-};
-
-static struct clk mcbsp2_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP2_SHIFT,
-	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
-	.clksel_mask	= OMAP2_MCBSP2_CLKS_MASK,
-	.clksel		= mcbsp_234_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp3_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP3_SHIFT,
-	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
-	.clksel_mask	= OMAP2_MCBSP3_CLKS_MASK,
-	.clksel		= mcbsp_234_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp4_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 4,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP4_SHIFT,
-	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
-	.clksel_mask	= OMAP2_MCBSP4_CLKS_MASK,
-	.clksel		= mcbsp_234_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* EMU clocks */
-
-/* More information: ARM Cortex-A8 Technical Reference Manual, sect 10.1 */
-
-static const struct clksel_rate emu_src_sys_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate emu_src_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate emu_src_per_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate emu_src_mpu_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel emu_src_clksel[] = {
-	{ .parent = &sys_ck,		.rates = emu_src_sys_rates },
-	{ .parent = &emu_core_alwon_ck, .rates = emu_src_core_rates },
-	{ .parent = &emu_per_alwon_ck,	.rates = emu_src_per_rates },
-	{ .parent = &emu_mpu_alwon_ck,	.rates = emu_src_mpu_rates },
-	{ .parent = NULL },
-};
-
-/*
- * Like the clkout_src clocks, emu_src_clk is a virtual clock, existing only
- * to switch the source of some of the EMU clocks.
- * XXX Are there CLKEN bits for these EMU clks?
- */
-static struct clk emu_src_ck = {
-	.name		= "emu_src_ck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_MUX_CTRL_MASK,
-	.clksel		= emu_src_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate pclk_emu_rates[] = {
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
-	{ .div = 6, .val = 6, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel pclk_emu_clksel[] = {
-	{ .parent = &emu_src_ck, .rates = pclk_emu_rates },
-	{ .parent = NULL },
-};
-
-static struct clk pclk_fck = {
-	.name		= "pclk_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_CLKSEL_PCLK_MASK,
-	.clksel		= pclk_emu_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate pclkx2_emu_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel pclkx2_emu_clksel[] = {
-	{ .parent = &emu_src_ck, .rates = pclkx2_emu_rates },
-	{ .parent = NULL },
-};
-
-static struct clk pclkx2_fck = {
-	.name		= "pclkx2_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_CLKSEL_PCLKX2_MASK,
-	.clksel		= pclkx2_emu_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel atclk_emu_clksel[] = {
-	{ .parent = &emu_src_ck, .rates = div2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk atclk_fck = {
-	.name		= "atclk_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_CLKSEL_ATCLK_MASK,
-	.clksel		= atclk_emu_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk traceclk_src_fck = {
-	.name		= "traceclk_src_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_TRACE_MUX_CTRL_MASK,
-	.clksel		= emu_src_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate traceclk_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel traceclk_clksel[] = {
-	{ .parent = &traceclk_src_fck, .rates = traceclk_rates },
-	{ .parent = NULL },
-};
-
-static struct clk traceclk_fck = {
-	.name		= "traceclk_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_CLKSEL_TRACECLK_MASK,
-	.clksel		= traceclk_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* SR clocks */
-
-/* SmartReflex fclk (VDD1) */
-static struct clk sr1_fck = {
-	.name		= "sr1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_SR1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* SmartReflex fclk (VDD2) */
-static struct clk sr2_fck = {
-	.name		= "sr2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_SR2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sr_l4_ick = {
-	.name		= "sr_l4_ick",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &l4_ick,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* SECURE_32K_FCK clocks */
-
-static struct clk gpt12_fck = {
-	.name		= "gpt12_fck",
-	.ops		= &clkops_null,
-	.parent		= &secure_32k_fck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt1_fck = {
-	.name		= "wdt1_fck",
-	.ops		= &clkops_null,
-	.parent		= &secure_32k_fck,
-	.recalc		= &followparent_recalc,
-};
-
-
-/*
- * clkdev
- */
-
-static struct omap_clk omap34xx_clks[] = {
-	CLK(NULL,	"omap_32k_fck",	&omap_32k_fck,	CK_343X),
-	CLK(NULL,	"virt_12m_ck",	&virt_12m_ck,	CK_343X),
-	CLK(NULL,	"virt_13m_ck",	&virt_13m_ck,	CK_343X),
-	CLK(NULL,	"virt_16_8m_ck", &virt_16_8m_ck, CK_3430ES2),
-	CLK(NULL,	"virt_19_2m_ck", &virt_19_2m_ck, CK_343X),
-	CLK(NULL,	"virt_26m_ck",	&virt_26m_ck,	CK_343X),
-	CLK(NULL,	"virt_38_4m_ck", &virt_38_4m_ck, CK_343X),
-	CLK(NULL,	"osc_sys_ck",	&osc_sys_ck,	CK_343X),
-	CLK(NULL,	"sys_ck",	&sys_ck,	CK_343X),
-	CLK(NULL,	"sys_altclk",	&sys_altclk,	CK_343X),
-	CLK(NULL,	"mcbsp_clks",	&mcbsp_clks,	CK_343X),
-	CLK(NULL,	"sys_clkout1",	&sys_clkout1,	CK_343X),
-	CLK(NULL,	"dpll1_ck",	&dpll1_ck,	CK_343X),
-	CLK(NULL,	"dpll1_x2_ck",	&dpll1_x2_ck,	CK_343X),
-	CLK(NULL,	"dpll1_x2m2_ck", &dpll1_x2m2_ck, CK_343X),
-	CLK(NULL,	"dpll2_ck",	&dpll2_ck,	CK_343X),
-	CLK(NULL,	"dpll2_m2_ck",	&dpll2_m2_ck,	CK_343X),
-	CLK(NULL,	"dpll3_ck",	&dpll3_ck,	CK_343X),
-	CLK(NULL,	"core_ck",	&core_ck,	CK_343X),
-	CLK(NULL,	"dpll3_x2_ck",	&dpll3_x2_ck,	CK_343X),
-	CLK(NULL,	"dpll3_m2_ck",	&dpll3_m2_ck,	CK_343X),
-	CLK(NULL,	"dpll3_m2x2_ck", &dpll3_m2x2_ck, CK_343X),
-	CLK(NULL,	"dpll3_m3_ck",	&dpll3_m3_ck,	CK_343X),
-	CLK(NULL,	"dpll3_m3x2_ck", &dpll3_m3x2_ck, CK_343X),
-	CLK("etb",	"emu_core_alwon_ck", &emu_core_alwon_ck, CK_343X),
-	CLK(NULL,	"dpll4_ck",	&dpll4_ck,	CK_343X),
-	CLK(NULL,	"dpll4_x2_ck",	&dpll4_x2_ck,	CK_343X),
-	CLK(NULL,	"omap_96m_alwon_fck", &omap_96m_alwon_fck, CK_343X),
-	CLK(NULL,	"omap_96m_fck",	&omap_96m_fck,	CK_343X),
-	CLK(NULL,	"cm_96m_fck",	&cm_96m_fck,	CK_343X),
-	CLK(NULL,	"omap_54m_fck",	&omap_54m_fck,	CK_343X),
-	CLK(NULL,	"omap_48m_fck",	&omap_48m_fck,	CK_343X),
-	CLK(NULL,	"omap_12m_fck",	&omap_12m_fck,	CK_343X),
-	CLK(NULL,	"dpll4_m2_ck",	&dpll4_m2_ck,	CK_343X),
-	CLK(NULL,	"dpll4_m2x2_ck", &dpll4_m2x2_ck, CK_343X),
-	CLK(NULL,	"dpll4_m3_ck",	&dpll4_m3_ck,	CK_343X),
-	CLK(NULL,	"dpll4_m3x2_ck", &dpll4_m3x2_ck, CK_343X),
-	CLK(NULL,	"dpll4_m4_ck",	&dpll4_m4_ck,	CK_343X),
-	CLK(NULL,	"dpll4_m4x2_ck", &dpll4_m4x2_ck, CK_343X),
-	CLK(NULL,	"dpll4_m5_ck",	&dpll4_m5_ck,	CK_343X),
-	CLK(NULL,	"dpll4_m5x2_ck", &dpll4_m5x2_ck, CK_343X),
-	CLK(NULL,	"dpll4_m6_ck",	&dpll4_m6_ck,	CK_343X),
-	CLK(NULL,	"dpll4_m6x2_ck", &dpll4_m6x2_ck, CK_343X),
-	CLK("etb",	"emu_per_alwon_ck", &emu_per_alwon_ck, CK_343X),
-	CLK(NULL,	"dpll5_ck",	&dpll5_ck,	CK_3430ES2),
-	CLK(NULL,	"dpll5_m2_ck",	&dpll5_m2_ck,	CK_3430ES2),
-	CLK(NULL,	"clkout2_src_ck", &clkout2_src_ck, CK_343X),
-	CLK(NULL,	"sys_clkout2",	&sys_clkout2,	CK_343X),
-	CLK(NULL,	"corex2_fck",	&corex2_fck,	CK_343X),
-	CLK(NULL,	"dpll1_fck",	&dpll1_fck,	CK_343X),
-	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_343X),
-	CLK(NULL,	"arm_fck",	&arm_fck,	CK_343X),
-	CLK("etb",	"emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_343X),
-	CLK(NULL,	"dpll2_fck",	&dpll2_fck,	CK_343X),
-	CLK(NULL,	"iva2_ck",	&iva2_ck,	CK_343X),
-	CLK(NULL,	"l3_ick",	&l3_ick,	CK_343X),
-	CLK(NULL,	"l4_ick",	&l4_ick,	CK_343X),
-	CLK(NULL,	"rm_ick",	&rm_ick,	CK_343X),
-	CLK(NULL,	"gfx_l3_ck",	&gfx_l3_ck,	CK_3430ES1),
-	CLK(NULL,	"gfx_l3_fck",	&gfx_l3_fck,	CK_3430ES1),
-	CLK(NULL,	"gfx_l3_ick",	&gfx_l3_ick,	CK_3430ES1),
-	CLK(NULL,	"gfx_cg1_ck",	&gfx_cg1_ck,	CK_3430ES1),
-	CLK(NULL,	"gfx_cg2_ck",	&gfx_cg2_ck,	CK_3430ES1),
-	CLK(NULL,	"sgx_fck",	&sgx_fck,	CK_3430ES2),
-	CLK(NULL,	"sgx_ick",	&sgx_ick,	CK_3430ES2),
-	CLK(NULL,	"d2d_26m_fck",	&d2d_26m_fck,	CK_3430ES1),
-	CLK(NULL,	"modem_fck",	&modem_fck,	CK_343X),
-	CLK(NULL,	"sad2d_ick",	&sad2d_ick,	CK_343X),
-	CLK(NULL,	"mad2d_ick",	&mad2d_ick,	CK_343X),
-	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_343X),
-	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_343X),
-	CLK(NULL,	"cpefuse_fck",	&cpefuse_fck,	CK_3430ES2),
-	CLK(NULL,	"ts_fck",	&ts_fck,	CK_3430ES2),
-	CLK(NULL,	"usbtll_fck",	&usbtll_fck,	CK_3430ES2),
-	CLK(NULL,	"core_96m_fck",	&core_96m_fck,	CK_343X),
-	CLK("mmci-omap-hs.2",	"fck",	&mmchs3_fck,	CK_3430ES2),
-	CLK("mmci-omap-hs.1",	"fck",	&mmchs2_fck,	CK_343X),
-	CLK(NULL,	"mspro_fck",	&mspro_fck,	CK_343X),
-	CLK("mmci-omap-hs.0",	"fck",	&mmchs1_fck,	CK_343X),
-	CLK("i2c_omap.3", "fck",	&i2c3_fck,	CK_343X),
-	CLK("i2c_omap.2", "fck",	&i2c2_fck,	CK_343X),
-	CLK("i2c_omap.1", "fck",	&i2c1_fck,	CK_343X),
-	CLK("omap-mcbsp.5", "fck",	&mcbsp5_fck,	CK_343X),
-	CLK("omap-mcbsp.1", "fck",	&mcbsp1_fck,	CK_343X),
-	CLK(NULL,	"core_48m_fck",	&core_48m_fck,	CK_343X),
-	CLK("omap2_mcspi.4", "fck",	&mcspi4_fck,	CK_343X),
-	CLK("omap2_mcspi.3", "fck",	&mcspi3_fck,	CK_343X),
-	CLK("omap2_mcspi.2", "fck",	&mcspi2_fck,	CK_343X),
-	CLK("omap2_mcspi.1", "fck",	&mcspi1_fck,	CK_343X),
-	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_343X),
-	CLK(NULL,	"uart1_fck",	&uart1_fck,	CK_343X),
-	CLK(NULL,	"fshostusb_fck", &fshostusb_fck, CK_3430ES1),
-	CLK(NULL,	"core_12m_fck",	&core_12m_fck,	CK_343X),
-	CLK("omap_hdq.0", "fck",	&hdq_fck,	CK_343X),
-	CLK(NULL,	"ssi_ssr_fck",	&ssi_ssr_fck_3430es1,	CK_3430ES1),
-	CLK(NULL,	"ssi_ssr_fck",	&ssi_ssr_fck_3430es2,	CK_3430ES2),
-	CLK(NULL,	"ssi_sst_fck",	&ssi_sst_fck_3430es1,	CK_3430ES1),
-	CLK(NULL,	"ssi_sst_fck",	&ssi_sst_fck_3430es2,	CK_3430ES2),
-	CLK(NULL,	"core_l3_ick",	&core_l3_ick,	CK_343X),
-	CLK("musb_hdrc",	"ick",	&hsotgusb_ick_3430es1,	CK_3430ES1),
-	CLK("musb_hdrc",	"ick",	&hsotgusb_ick_3430es2,	CK_3430ES2),
-	CLK(NULL,	"sdrc_ick",	&sdrc_ick,	CK_343X),
-	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_343X),
-	CLK(NULL,	"security_l3_ick", &security_l3_ick, CK_343X),
-	CLK(NULL,	"pka_ick",	&pka_ick,	CK_343X),
-	CLK(NULL,	"core_l4_ick",	&core_l4_ick,	CK_343X),
-	CLK(NULL,	"usbtll_ick",	&usbtll_ick,	CK_3430ES2),
-	CLK("mmci-omap-hs.2",	"ick",	&mmchs3_ick,	CK_3430ES2),
-	CLK(NULL,	"icr_ick",	&icr_ick,	CK_343X),
-	CLK(NULL,	"aes2_ick",	&aes2_ick,	CK_343X),
-	CLK(NULL,	"sha12_ick",	&sha12_ick,	CK_343X),
-	CLK(NULL,	"des2_ick",	&des2_ick,	CK_343X),
-	CLK("mmci-omap-hs.1",	"ick",	&mmchs2_ick,	CK_343X),
-	CLK("mmci-omap-hs.0",	"ick",	&mmchs1_ick,	CK_343X),
-	CLK(NULL,	"mspro_ick",	&mspro_ick,	CK_343X),
-	CLK("omap_hdq.0", "ick",	&hdq_ick,	CK_343X),
-	CLK("omap2_mcspi.4", "ick",	&mcspi4_ick,	CK_343X),
-	CLK("omap2_mcspi.3", "ick",	&mcspi3_ick,	CK_343X),
-	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick,	CK_343X),
-	CLK("omap2_mcspi.1", "ick",	&mcspi1_ick,	CK_343X),
-	CLK("i2c_omap.3", "ick",	&i2c3_ick,	CK_343X),
-	CLK("i2c_omap.2", "ick",	&i2c2_ick,	CK_343X),
-	CLK("i2c_omap.1", "ick",	&i2c1_ick,	CK_343X),
-	CLK(NULL,	"uart2_ick",	&uart2_ick,	CK_343X),
-	CLK(NULL,	"uart1_ick",	&uart1_ick,	CK_343X),
-	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_343X),
-	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_343X),
-	CLK("omap-mcbsp.5", "ick",	&mcbsp5_ick,	CK_343X),
-	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_343X),
-	CLK(NULL,	"fac_ick",	&fac_ick,	CK_3430ES1),
-	CLK(NULL,	"mailboxes_ick", &mailboxes_ick, CK_343X),
-	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_343X),
-	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_343X),
-	CLK(NULL,	"ssi_ick",	&ssi_ick_3430es1,	CK_3430ES1),
-	CLK(NULL,	"ssi_ick",	&ssi_ick_3430es2,	CK_3430ES2),
-	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick,	CK_3430ES1),
-	CLK(NULL,	"security_l4_ick2", &security_l4_ick2, CK_343X),
-	CLK(NULL,	"aes1_ick",	&aes1_ick,	CK_343X),
-	CLK("omap_rng",	"ick",		&rng_ick,	CK_343X),
-	CLK(NULL,	"sha11_ick",	&sha11_ick,	CK_343X),
-	CLK(NULL,	"des1_ick",	&des1_ick,	CK_343X),
-	CLK("omapdss",	"dss1_fck",	&dss1_alwon_fck_3430es1, CK_3430ES1),
-	CLK("omapdss",	"dss1_fck",	&dss1_alwon_fck_3430es2, CK_3430ES2),
-	CLK("omapdss",	"tv_fck",	&dss_tv_fck,	CK_343X),
-	CLK("omapdss",	"video_fck",	&dss_96m_fck,	CK_343X),
-	CLK("omapdss",	"dss2_fck",	&dss2_alwon_fck, CK_343X),
-	CLK("omapdss",	"ick",		&dss_ick_3430es1,	CK_3430ES1),
-	CLK("omapdss",	"ick",		&dss_ick_3430es2,	CK_3430ES2),
-	CLK(NULL,	"cam_mclk",	&cam_mclk,	CK_343X),
-	CLK(NULL,	"cam_ick",	&cam_ick,	CK_343X),
-	CLK(NULL,	"csi2_96m_fck",	&csi2_96m_fck,	CK_343X),
-	CLK(NULL,	"usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2),
-	CLK(NULL,	"usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2),
-	CLK(NULL,	"usbhost_ick",	&usbhost_ick,	CK_3430ES2),
-	CLK(NULL,	"usim_fck",	&usim_fck,	CK_3430ES2),
-	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_343X),
-	CLK(NULL,	"wkup_32k_fck",	&wkup_32k_fck,	CK_343X),
-	CLK(NULL,	"gpio1_dbck",	&gpio1_dbck,	CK_343X),
-	CLK("omap_wdt",	"fck",		&wdt2_fck,	CK_343X),
-	CLK(NULL,	"wkup_l4_ick",	&wkup_l4_ick,	CK_343X),
-	CLK(NULL,	"usim_ick",	&usim_ick,	CK_3430ES2),
-	CLK("omap_wdt",	"ick",		&wdt2_ick,	CK_343X),
-	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_343X),
-	CLK(NULL,	"gpio1_ick",	&gpio1_ick,	CK_343X),
-	CLK(NULL,	"omap_32ksync_ick", &omap_32ksync_ick, CK_343X),
-	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_343X),
-	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_343X),
-	CLK(NULL,	"per_96m_fck",	&per_96m_fck,	CK_343X),
-	CLK(NULL,	"per_48m_fck",	&per_48m_fck,	CK_343X),
-	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_343X),
-	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_343X),
-	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_343X),
-	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_343X),
-	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_343X),
-	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_343X),
-	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_343X),
-	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_343X),
-	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_343X),
-	CLK(NULL,	"per_32k_alwon_fck", &per_32k_alwon_fck, CK_343X),
-	CLK(NULL,	"gpio6_dbck",	&gpio6_dbck,	CK_343X),
-	CLK(NULL,	"gpio5_dbck",	&gpio5_dbck,	CK_343X),
-	CLK(NULL,	"gpio4_dbck",	&gpio4_dbck,	CK_343X),
-	CLK(NULL,	"gpio3_dbck",	&gpio3_dbck,	CK_343X),
-	CLK(NULL,	"gpio2_dbck",	&gpio2_dbck,	CK_343X),
-	CLK(NULL,	"wdt3_fck",	&wdt3_fck,	CK_343X),
-	CLK(NULL,	"per_l4_ick",	&per_l4_ick,	CK_343X),
-	CLK(NULL,	"gpio6_ick",	&gpio6_ick,	CK_343X),
-	CLK(NULL,	"gpio5_ick",	&gpio5_ick,	CK_343X),
-	CLK(NULL,	"gpio4_ick",	&gpio4_ick,	CK_343X),
-	CLK(NULL,	"gpio3_ick",	&gpio3_ick,	CK_343X),
-	CLK(NULL,	"gpio2_ick",	&gpio2_ick,	CK_343X),
-	CLK(NULL,	"wdt3_ick",	&wdt3_ick,	CK_343X),
-	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_343X),
-	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_343X),
-	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_343X),
-	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_343X),
-	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_343X),
-	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_343X),
-	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_343X),
-	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_343X),
-	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_343X),
-	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_343X),
-	CLK("omap-mcbsp.3", "ick",	&mcbsp3_ick,	CK_343X),
-	CLK("omap-mcbsp.4", "ick",	&mcbsp4_ick,	CK_343X),
-	CLK("omap-mcbsp.2", "fck",	&mcbsp2_fck,	CK_343X),
-	CLK("omap-mcbsp.3", "fck",	&mcbsp3_fck,	CK_343X),
-	CLK("omap-mcbsp.4", "fck",	&mcbsp4_fck,	CK_343X),
-	CLK("etb",	"emu_src_ck",	&emu_src_ck,	CK_343X),
-	CLK(NULL,	"pclk_fck",	&pclk_fck,	CK_343X),
-	CLK(NULL,	"pclkx2_fck",	&pclkx2_fck,	CK_343X),
-	CLK(NULL,	"atclk_fck",	&atclk_fck,	CK_343X),
-	CLK(NULL,	"traceclk_src_fck", &traceclk_src_fck, CK_343X),
-	CLK(NULL,	"traceclk_fck",	&traceclk_fck,	CK_343X),
-	CLK(NULL,	"sr1_fck",	&sr1_fck,	CK_343X),
-	CLK(NULL,	"sr2_fck",	&sr2_fck,	CK_343X),
-	CLK(NULL,	"sr_l4_ick",	&sr_l4_ick,	CK_343X),
-	CLK(NULL,	"secure_32k_fck", &secure_32k_fck, CK_343X),
-	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_343X),
-	CLK(NULL,	"wdt1_fck",	&wdt1_fck,	CK_343X),
-};
-
-
-int __init omap2_clk_init(void)
-{
-	/* struct prcm_config *prcm; */
-	struct omap_clk *c;
-	/* u32 clkrate; */
-	u32 cpu_clkflg;
-
-	if (cpu_is_omap34xx()) {
-		cpu_mask = RATE_IN_343X;
-		cpu_clkflg = CK_343X;
-
-		/*
-		 * Update this if there are further clock changes between ES2
-		 * and production parts
-		 */
-		if (omap_rev() == OMAP3430_REV_ES1_0) {
-			/* No 3430ES1-only rates exist, so no RATE_IN_3430ES1 */
-			cpu_clkflg |= CK_3430ES1;
-		} else {
-			cpu_mask |= RATE_IN_3430ES2;
-			cpu_clkflg |= CK_3430ES2;
-		}
-	}
-
-	clk_init(&omap2_clk_functions);
-
-	for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
-		clk_preinit(c->lk.clk);
-
-	for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
-		if (c->cpu & cpu_clkflg) {
-			clkdev_add(&c->lk);
-			clk_register(c->lk.clk);
-			omap2_init_clk_clkdm(c->lk.clk);
-		}
-
-	/* REVISIT: Not yet ready for OMAP3 */
-#if 0
-	/* Check the MPU rate set by bootloader */
-	clkrate = omap2_get_dpll_rate_24xx(&dpll_ck);
-	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
-		if (!(prcm->flags & cpu_mask))
-			continue;
-		if (prcm->xtal_speed != sys_ck.rate)
-			continue;
-		if (prcm->dpll_speed <= clkrate)
-			break;
-	}
-	curr_prcm_set = prcm;
-#endif
-
-	recalculate_root_clocks();
-
-	printk(KERN_INFO "Clocking rate (Crystal/Core/MPU): "
-	       "%ld.%01ld/%ld/%ld MHz\n",
-	       (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10,
-	       (core_ck.rate / 1000000), (arm_fck.rate / 1000000));
-
-	/*
-	 * Only enable those clocks we will need, let the drivers
-	 * enable other clocks as necessary
-	 */
-	clk_enable_init_clocks();
-
-	/*
-	 * Lock DPLL5 and put it in autoidle.
-	 */
-	if (omap_rev() >= OMAP3430_REV_ES2_0)
-		omap3_clk_lock_dpll5();
-
-	/* Avoid sleeping during omap3_core_dpll_m2_set_rate() */
-	sdrc_ick_p = clk_get(NULL, "sdrc_ick");
-	arm_fck_p = clk_get(NULL, "arm_fck");
-
-	return 0;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock34xx.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock34xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock34xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock34xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,24 +1,15 @@
 /*
- * OMAP3 clock function prototypes and macros
+ * OMAP34xx clock function prototypes and macros
  *
- * Copyright (C) 2007-2009 Texas Instruments, Inc.
- * Copyright (C) 2007-2009 Nokia Corporation
+ * Copyright (C) 2007-2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
  */
 
-#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_34XX_H
-#define __ARCH_ARM_MACH_OMAP2_CLOCK_34XX_H
-
-int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
-int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
-void omap3_clk_lock_dpll5(void);
-
-extern struct clk *sdrc_ick_p;
-extern struct clk *arm_fck_p;
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H
 
-/* OMAP34xx-specific clkops */
 extern const struct clkops clkops_omap3430es2_ssi_wait;
 extern const struct clkops clkops_omap3430es2_hsotgusb_wait;
 extern const struct clkops clkops_omap3430es2_dss_usbhost_wait;
-extern const struct clkops clkops_noncore_dpll_ops;
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock3517.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock3517.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock3517.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock3517.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,124 @@
+/*
+ * OMAP3517/3505-specific clock framework functions
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Ranjith Lohithakshan
+ * Paul Walmsley
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu,
+ * 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.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock3517.h"
+#include "cm.h"
+#include "cm-regbits-34xx.h"
+
+/*
+ * In AM35xx IPSS, the {ICK,FCK} enable bits for modules are exported
+ * in the same register at a bit offset of 0x8. The EN_ACK for ICK is
+ * at an offset of 4 from ICK enable bit.
+ */
+#define AM35XX_IPSS_ICK_MASK			0xF
+#define AM35XX_IPSS_ICK_EN_ACK_OFFSET 		0x4
+#define AM35XX_IPSS_ICK_FCK_OFFSET		0x8
+#define AM35XX_IPSS_CLK_IDLEST_VAL		0
+
+/**
+ * am35xx_clk_find_idlest - return clock ACK info for AM35XX IPSS
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
+ *
+ * The interface clocks on AM35xx IPSS reflects the clock idle status
+ * in the enable register itsel at a bit offset of 4 from the enable
+ * bit. A value of 1 indicates that clock is enabled.
+ */
+static void am35xx_clk_find_idlest(struct clk *clk,
+					    void __iomem **idlest_reg,
+					    u8 *idlest_bit,
+					    u8 *idlest_val)
+{
+	*idlest_reg = (__force void __iomem *)(clk->enable_reg);
+	*idlest_bit = clk->enable_bit + AM35XX_IPSS_ICK_EN_ACK_OFFSET;
+	*idlest_val = AM35XX_IPSS_CLK_IDLEST_VAL;
+}
+
+/**
+ * am35xx_clk_find_companion - find companion clock to @clk
+ * @clk: struct clk * to find the companion clock of
+ * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in
+ * @other_bit: u8 ** to return the companion clock bit shift in
+ *
+ * Some clocks don't have companion clocks.  For example, modules with
+ * only an interface clock (such as HECC) don't have a companion
+ * clock.  Right now, this code relies on the hardware exporting a bit
+ * in the correct companion register that indicates that the
+ * nonexistent 'companion clock' is active.  Future patches will
+ * associate this type of code with per-module data structures to
+ * avoid this issue, and remove the casts.  No return value.
+ */
+static void am35xx_clk_find_companion(struct clk *clk, void __iomem **other_reg,
+					    u8 *other_bit)
+{
+	*other_reg = (__force void __iomem *)(clk->enable_reg);
+	if (clk->enable_bit & AM35XX_IPSS_ICK_MASK)
+		*other_bit = clk->enable_bit + AM35XX_IPSS_ICK_FCK_OFFSET;
+	else
+		*other_bit = clk->enable_bit - AM35XX_IPSS_ICK_FCK_OFFSET;
+}
+
+const struct clkops clkops_am35xx_ipss_module_wait = {
+	.enable		= omap2_dflt_clk_enable,
+	.disable	= omap2_dflt_clk_disable,
+	.find_idlest	= am35xx_clk_find_idlest,
+	.find_companion	= am35xx_clk_find_companion,
+};
+
+/**
+ * am35xx_clk_ipss_find_idlest - return CM_IDLEST info for IPSS
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
+ *
+ * The IPSS target CM_IDLEST bit is at a different shift from the
+ * CM_{I,F}CLKEN bit.  Pass back the correct info via @idlest_reg
+ * and @idlest_bit.  No return value.
+ */
+static void am35xx_clk_ipss_find_idlest(struct clk *clk,
+					    void __iomem **idlest_reg,
+					    u8 *idlest_bit,
+					    u8 *idlest_val)
+{
+	u32 r;
+
+	r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
+	*idlest_reg = (__force void __iomem *)r;
+	*idlest_bit = AM35XX_ST_IPSS_SHIFT;
+	*idlest_val = OMAP34XX_CM_IDLEST_VAL;
+}
+
+const struct clkops clkops_am35xx_ipss_wait = {
+	.enable		= omap2_dflt_clk_enable,
+	.disable	= omap2_dflt_clk_disable,
+	.find_idlest	= am35xx_clk_ipss_find_idlest,
+	.find_companion	= omap2_clk_dflt_find_companion,
+};
+
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock3517.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock3517.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock3517.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock3517.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,14 @@
+/*
+ * OMAP3517/3505 clock function prototypes and macros
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK3517_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK3517_H
+
+extern const struct clkops clkops_am35xx_ipss_module_wait;
+extern const struct clkops clkops_am35xx_ipss_wait;
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock36xx.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock36xx.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock36xx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock36xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,72 @@
+/*
+ * OMAP36xx-specific clkops
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Mike Turquette
+ * Vijaykumar GN
+ * Paul Walmsley
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu,
+ * 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.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock36xx.h"
+
+
+/**
+ * omap36xx_pwrdn_clk_enable_with_hsdiv_restore - enable clocks suffering
+ *         from HSDivider PWRDN problem Implements Errata ID: i556.
+ * @clk: DPLL output struct clk
+ *
+ * 3630 only: dpll3_m3_ck, dpll4_m2_ck, dpll4_m3_ck, dpll4_m4_ck,
+ * dpll4_m5_ck & dpll4_m6_ck dividers gets loaded with reset
+ * valueafter their respective PWRDN bits are set.  Any dummy write
+ * (Any other value different from the Read value) to the
+ * corresponding CM_CLKSEL register will refresh the dividers.
+ */
+static int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk *clk)
+{
+	u32 dummy_v, orig_v, clksel_shift;
+	int ret;
+
+	/* Clear PWRDN bit of HSDIVIDER */
+	ret = omap2_dflt_clk_enable(clk);
+
+	/* Restore the dividers */
+	if (!ret) {
+		clksel_shift = __ffs(clk->parent->clksel_mask);
+		orig_v = __raw_readl(clk->parent->clksel_reg);
+		dummy_v = orig_v;
+
+		/* Write any other value different from the Read value */
+		dummy_v ^= (1 << clksel_shift);
+		__raw_writel(dummy_v, clk->parent->clksel_reg);
+
+		/* Write the original divider */
+		__raw_writel(orig_v, clk->parent->clksel_reg);
+	}
+
+	return ret;
+}
+
+const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore = {
+	.enable		= omap36xx_pwrdn_clk_enable_with_hsdiv_restore,
+	.disable	= omap2_dflt_clk_disable,
+	.find_companion	= omap2_clk_dflt_find_companion,
+	.find_idlest	= omap2_clk_dflt_find_idlest,
+};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock36xx.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock36xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock36xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock36xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,13 @@
+/*
+ * OMAP36xx clock function prototypes and macros
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H
+
+extern const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock3xxx.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock3xxx.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock3xxx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock3xxx.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,104 @@
+/*
+ * OMAP3-specific clock framework functions
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ *
+ * Paul Walmsley
+ * Jouni HÃ¶gander
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock3xxx.h"
+#include "prm.h"
+#include "prm-regbits-34xx.h"
+#include "cm.h"
+#include "cm-regbits-34xx.h"
+
+/*
+ * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
+ * that are sourced by DPLL5, and both of these require this clock
+ * to be at 120 MHz for proper operation.
+ */
+#define DPLL5_FREQ_FOR_USBHOST		120000000
+
+/* needed by omap3_core_dpll_m2_set_rate() */
+struct clk *sdrc_ick_p, *arm_fck_p;
+
+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) {
+		pr_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);
+}
+
+void __init omap3_clk_lock_dpll5(void)
+{
+	struct clk *dpll5_clk;
+	struct clk *dpll5_m2_clk;
+
+	dpll5_clk = clk_get(NULL, "dpll5_ck");
+	clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
+	clk_enable(dpll5_clk);
+
+	/* Enable autoidle to allow it to enter low power bypass */
+	omap3_dpll_allow_idle(dpll5_clk);
+
+	/* Program dpll5_m2_clk divider for no division */
+	dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
+	clk_enable(dpll5_m2_clk);
+	clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
+
+	clk_disable(dpll5_m2_clk);
+	clk_disable(dpll5_clk);
+	return;
+}
+
+/* Common clock code */
+
+/*
+ * Switch the MPU rate if specified on cmdline.  We cannot do this
+ * early until cmdline is parsed.  XXX This should be removed from the
+ * clock code and handled by the OPP layer code in the near future.
+ */
+static int __init omap3xxx_clk_arch_init(void)
+{
+	int ret;
+
+	if (!cpu_is_omap34xx())
+		return 0;
+
+	ret = omap2_clk_switch_mpurate_at_boot("dpll1_ck");
+	if (!ret)
+		omap2_clk_print_new_rates("osc_sys_ck", "arm_fck", "core_ck");
+
+	return ret;
+}
+
+arch_initcall(omap3xxx_clk_arch_init);
+
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock3xxx_data.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock3xxx_data.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock3xxx_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock3xxx_data.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,3601 @@
+/*
+ * OMAP3 clock data
+ *
+ * Copyright (C) 2007-2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ * With many device clock fixes by Kevin Hilman and Jouni HÃ¶gander
+ * DPLL bypass clock support added by Roman Tereshonkov
+ *
+ */
+
+/*
+ * Virtual clocks are introduced as convenient tools.
+ * They are sources for other clocks and not supposed
+ * to be requested from drivers directly.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/list.h>
+
+#include <plat/control.h>
+#include <plat/clkdev_omap.h>
+
+#include "clock.h"
+#include "clock3xxx.h"
+#include "clock34xx.h"
+#include "clock36xx.h"
+#include "clock3517.h"
+
+#include "cm.h"
+#include "cm-regbits-34xx.h"
+#include "prm.h"
+#include "prm-regbits-34xx.h"
+
+/*
+ * clocks
+ */
+
+#define OMAP_CM_REGADDR		OMAP34XX_CM_REGADDR
+
+/* Maximum DPLL multiplier, divider values for OMAP3 */
+#define OMAP3_MAX_DPLL_MULT		2047
+#define OMAP3630_MAX_JTYPE_DPLL_MULT	4095
+#define OMAP3_MAX_DPLL_DIV		128
+
+/*
+ * DPLL1 supplies clock to the MPU.
+ * DPLL2 supplies clock to the IVA2.
+ * DPLL3 supplies CORE domain clocks.
+ * DPLL4 supplies peripheral clocks.
+ * DPLL5 supplies other peripheral clocks (USBHOST, USIM).
+ */
+
+/* Forward declarations for DPLL bypass clocks */
+static struct clk dpll1_fck;
+static struct clk dpll2_fck;
+
+/* PRM CLOCKS */
+
+/* According to timer32k.c, this is a 32768Hz clock, not a 32000Hz clock. */
+static struct clk omap_32k_fck = {
+	.name		= "omap_32k_fck",
+	.ops		= &clkops_null,
+	.rate		= 32768,
+};
+
+static struct clk secure_32k_fck = {
+	.name		= "secure_32k_fck",
+	.ops		= &clkops_null,
+	.rate		= 32768,
+};
+
+/* Virtual source clocks for osc_sys_ck */
+static struct clk virt_12m_ck = {
+	.name		= "virt_12m_ck",
+	.ops		= &clkops_null,
+	.rate		= 12000000,
+};
+
+static struct clk virt_13m_ck = {
+	.name		= "virt_13m_ck",
+	.ops		= &clkops_null,
+	.rate		= 13000000,
+};
+
+static struct clk virt_16_8m_ck = {
+	.name		= "virt_16_8m_ck",
+	.ops		= &clkops_null,
+	.rate		= 16800000,
+};
+
+static struct clk virt_19_2m_ck = {
+	.name		= "virt_19_2m_ck",
+	.ops		= &clkops_null,
+	.rate		= 19200000,
+};
+
+static struct clk virt_26m_ck = {
+	.name		= "virt_26m_ck",
+	.ops		= &clkops_null,
+	.rate		= 26000000,
+};
+
+static struct clk virt_38_4m_ck = {
+	.name		= "virt_38_4m_ck",
+	.ops		= &clkops_null,
+	.rate		= 38400000,
+};
+
+static const struct clksel_rate osc_sys_12m_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate osc_sys_13m_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate osc_sys_16_8m_rates[] = {
+	{ .div = 1, .val = 5, .flags = RATE_IN_3430ES2 | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate osc_sys_19_2m_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate osc_sys_26m_rates[] = {
+	{ .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate osc_sys_38_4m_rates[] = {
+	{ .div = 1, .val = 4, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel osc_sys_clksel[] = {
+	{ .parent = &virt_12m_ck,   .rates = osc_sys_12m_rates },
+	{ .parent = &virt_13m_ck,   .rates = osc_sys_13m_rates },
+	{ .parent = &virt_16_8m_ck, .rates = osc_sys_16_8m_rates },
+	{ .parent = &virt_19_2m_ck, .rates = osc_sys_19_2m_rates },
+	{ .parent = &virt_26m_ck,   .rates = osc_sys_26m_rates },
+	{ .parent = &virt_38_4m_ck, .rates = osc_sys_38_4m_rates },
+	{ .parent = NULL },
+};
+
+/* Oscillator clock */
+/* 12, 13, 16.8, 19.2, 26, or 38.4 MHz */
+static struct clk osc_sys_ck = {
+	.name		= "osc_sys_ck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP3430_PRM_CLKSEL,
+	.clksel_mask	= OMAP3430_SYS_CLKIN_SEL_MASK,
+	.clksel		= osc_sys_clksel,
+	/* REVISIT: deal with autoextclkmode? */
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate div2_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 0 }
+};
+
+static const struct clksel sys_clksel[] = {
+	{ .parent = &osc_sys_ck, .rates = div2_rates },
+	{ .parent = NULL }
+};
+
+/* Latency: this clock is only enabled after PRM_CLKSETUP.SETUP_TIME */
+/* Feeds DPLLs - divided first by PRM_CLKSRC_CTRL.SYSCLKDIV? */
+static struct clk sys_ck = {
+	.name		= "sys_ck",
+	.ops		= &clkops_null,
+	.parent		= &osc_sys_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP3430_PRM_CLKSRC_CTRL,
+	.clksel_mask	= OMAP_SYSCLKDIV_MASK,
+	.clksel		= sys_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk sys_altclk = {
+	.name		= "sys_altclk",
+	.ops		= &clkops_null,
+};
+
+/* Optional external clock input for some McBSPs */
+static struct clk mcbsp_clks = {
+	.name		= "mcbsp_clks",
+	.ops		= &clkops_null,
+};
+
+/* PRM EXTERNAL CLOCK OUTPUT */
+
+static struct clk sys_clkout1 = {
+	.name		= "sys_clkout1",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &osc_sys_ck,
+	.enable_reg	= OMAP3430_PRM_CLKOUT_CTRL,
+	.enable_bit	= OMAP3430_CLKOUT_EN_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/* DPLLS */
+
+/* CM CLOCKS */
+
+static const struct clksel_rate div16_dpll_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
+	{ .div = 5, .val = 5, .flags = RATE_IN_343X },
+	{ .div = 6, .val = 6, .flags = RATE_IN_343X },
+	{ .div = 7, .val = 7, .flags = RATE_IN_343X },
+	{ .div = 8, .val = 8, .flags = RATE_IN_343X },
+	{ .div = 9, .val = 9, .flags = RATE_IN_343X },
+	{ .div = 10, .val = 10, .flags = RATE_IN_343X },
+	{ .div = 11, .val = 11, .flags = RATE_IN_343X },
+	{ .div = 12, .val = 12, .flags = RATE_IN_343X },
+	{ .div = 13, .val = 13, .flags = RATE_IN_343X },
+	{ .div = 14, .val = 14, .flags = RATE_IN_343X },
+	{ .div = 15, .val = 15, .flags = RATE_IN_343X },
+	{ .div = 16, .val = 16, .flags = RATE_IN_343X },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate div32_dpll4_rates_3630[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_36XX | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_36XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_36XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_36XX },
+	{ .div = 5, .val = 5, .flags = RATE_IN_36XX },
+	{ .div = 6, .val = 6, .flags = RATE_IN_36XX },
+	{ .div = 7, .val = 7, .flags = RATE_IN_36XX },
+	{ .div = 8, .val = 8, .flags = RATE_IN_36XX },
+	{ .div = 9, .val = 9, .flags = RATE_IN_36XX },
+	{ .div = 10, .val = 10, .flags = RATE_IN_36XX },
+	{ .div = 11, .val = 11, .flags = RATE_IN_36XX },
+	{ .div = 12, .val = 12, .flags = RATE_IN_36XX },
+	{ .div = 13, .val = 13, .flags = RATE_IN_36XX },
+	{ .div = 14, .val = 14, .flags = RATE_IN_36XX },
+	{ .div = 15, .val = 15, .flags = RATE_IN_36XX },
+	{ .div = 16, .val = 16, .flags = RATE_IN_36XX },
+	{ .div = 17, .val = 17, .flags = RATE_IN_36XX },
+	{ .div = 18, .val = 18, .flags = RATE_IN_36XX },
+	{ .div = 19, .val = 19, .flags = RATE_IN_36XX },
+	{ .div = 20, .val = 20, .flags = RATE_IN_36XX },
+	{ .div = 21, .val = 21, .flags = RATE_IN_36XX },
+	{ .div = 22, .val = 22, .flags = RATE_IN_36XX },
+	{ .div = 23, .val = 23, .flags = RATE_IN_36XX },
+	{ .div = 24, .val = 24, .flags = RATE_IN_36XX },
+	{ .div = 25, .val = 25, .flags = RATE_IN_36XX },
+	{ .div = 26, .val = 26, .flags = RATE_IN_36XX },
+	{ .div = 27, .val = 27, .flags = RATE_IN_36XX },
+	{ .div = 28, .val = 28, .flags = RATE_IN_36XX },
+	{ .div = 29, .val = 29, .flags = RATE_IN_36XX },
+	{ .div = 30, .val = 30, .flags = RATE_IN_36XX },
+	{ .div = 31, .val = 31, .flags = RATE_IN_36XX },
+	{ .div = 32, .val = 32, .flags = RATE_IN_36XX },
+	{ .div = 0 }
+};
+
+/* DPLL1 */
+/* MPU clock source */
+/* Type: DPLL */
+static struct dpll_data dpll1_dd = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
+	.mult_mask	= OMAP3430_MPU_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430_MPU_DPLL_DIV_MASK,
+	.clk_bypass	= &dpll1_fck,
+	.clk_ref	= &sys_ck,
+	.freqsel_mask	= OMAP3430_MPU_DPLL_FREQSEL_MASK,
+	.control_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL),
+	.enable_mask	= OMAP3430_EN_MPU_DPLL_MASK,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.auto_recal_bit	= OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430_MPU_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430_MPU_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL),
+	.autoidle_mask	= OMAP3430_AUTO_MPU_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
+	.idlest_mask	= OMAP3430_ST_MPU_CLK_MASK,
+	.max_multiplier = OMAP3_MAX_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
+};
+
+static struct clk dpll1_ck = {
+	.name		= "dpll1_ck",
+	.ops		= &clkops_null,
+	.parent		= &sys_ck,
+	.dpll_data	= &dpll1_dd,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.clkdm_name	= "dpll1_clkdm",
+	.recalc		= &omap3_dpll_recalc,
+};
+
+/*
+ * This virtual clock provides the CLKOUTX2 output from the DPLL if the
+ * DPLL isn't bypassed.
+ */
+static struct clk dpll1_x2_ck = {
+	.name		= "dpll1_x2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll1_ck,
+	.clkdm_name	= "dpll1_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+/* On DPLL1, unlike other DPLLs, the divider is downstream from CLKOUTX2 */
+static const struct clksel div16_dpll1_x2m2_clksel[] = {
+	{ .parent = &dpll1_x2_ck, .rates = div16_dpll_rates },
+	{ .parent = NULL }
+};
+
+/*
+ * Does not exist in the TRM - needed to separate the M2 divider from
+ * bypass selection in mpu_ck
+ */
+static struct clk dpll1_x2m2_ck = {
+	.name		= "dpll1_x2m2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll1_x2_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL),
+	.clksel_mask	= OMAP3430_MPU_DPLL_CLKOUT_DIV_MASK,
+	.clksel		= div16_dpll1_x2m2_clksel,
+	.clkdm_name	= "dpll1_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* DPLL2 */
+/* IVA2 clock source */
+/* Type: DPLL */
+
+static struct dpll_data dpll2_dd = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
+	.mult_mask	= OMAP3430_IVA2_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430_IVA2_DPLL_DIV_MASK,
+	.clk_bypass	= &dpll2_fck,
+	.clk_ref	= &sys_ck,
+	.freqsel_mask	= OMAP3430_IVA2_DPLL_FREQSEL_MASK,
+	.control_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL),
+	.enable_mask	= OMAP3430_EN_IVA2_DPLL_MASK,
+	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) |
+				(1 << DPLL_LOW_POWER_BYPASS),
+	.auto_recal_bit	= OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL),
+	.autoidle_mask	= OMAP3430_AUTO_IVA2_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL),
+	.idlest_mask	= OMAP3430_ST_IVA2_CLK_MASK,
+	.max_multiplier = OMAP3_MAX_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
+};
+
+static struct clk dpll2_ck = {
+	.name		= "dpll2_ck",
+	.ops		= &clkops_omap3_noncore_dpll_ops,
+	.parent		= &sys_ck,
+	.dpll_data	= &dpll2_dd,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.clkdm_name	= "dpll2_clkdm",
+	.recalc		= &omap3_dpll_recalc,
+};
+
+static const struct clksel div16_dpll2_m2x2_clksel[] = {
+	{ .parent = &dpll2_ck, .rates = div16_dpll_rates },
+	{ .parent = NULL }
+};
+
+/*
+ * The TRM is conflicted on whether IVA2 clock comes from DPLL2 CLKOUT
+ * or CLKOUTX2. CLKOUT seems most plausible.
+ */
+static struct clk dpll2_m2_ck = {
+	.name		= "dpll2_m2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll2_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD,
+					  OMAP3430_CM_CLKSEL2_PLL),
+	.clksel_mask	= OMAP3430_IVA2_DPLL_CLKOUT_DIV_MASK,
+	.clksel		= div16_dpll2_m2x2_clksel,
+	.clkdm_name	= "dpll2_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * DPLL3
+ * Source clock for all interfaces and for some device fclks
+ * REVISIT: Also supports fast relock bypass - not included below
+ */
+static struct dpll_data dpll3_dd = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.mult_mask	= OMAP3430_CORE_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430_CORE_DPLL_DIV_MASK,
+	.clk_bypass	= &sys_ck,
+	.clk_ref	= &sys_ck,
+	.freqsel_mask	= OMAP3430_CORE_DPLL_FREQSEL_MASK,
+	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_mask	= OMAP3430_EN_CORE_DPLL_MASK,
+	.auto_recal_bit	= OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430_CORE_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430_CORE_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
+	.autoidle_mask	= OMAP3430_AUTO_CORE_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
+	.idlest_mask	= OMAP3430_ST_CORE_CLK_MASK,
+	.max_multiplier = OMAP3_MAX_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
+};
+
+static struct clk dpll3_ck = {
+	.name		= "dpll3_ck",
+	.ops		= &clkops_null,
+	.parent		= &sys_ck,
+	.dpll_data	= &dpll3_dd,
+	.round_rate	= &omap2_dpll_round_rate,
+	.clkdm_name	= "dpll3_clkdm",
+	.recalc		= &omap3_dpll_recalc,
+};
+
+/*
+ * This virtual clock provides the CLKOUTX2 output from the DPLL if the
+ * DPLL isn't bypassed
+ */
+static struct clk dpll3_x2_ck = {
+	.name		= "dpll3_x2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll3_ck,
+	.clkdm_name	= "dpll3_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel_rate div31_dpll3_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 3, .val = 3, .flags = RATE_IN_3430ES2 },
+	{ .div = 4, .val = 4, .flags = RATE_IN_3430ES2 },
+	{ .div = 5, .val = 5, .flags = RATE_IN_3430ES2 },
+	{ .div = 6, .val = 6, .flags = RATE_IN_3430ES2 },
+	{ .div = 7, .val = 7, .flags = RATE_IN_3430ES2 },
+	{ .div = 8, .val = 8, .flags = RATE_IN_3430ES2 },
+	{ .div = 9, .val = 9, .flags = RATE_IN_3430ES2 },
+	{ .div = 10, .val = 10, .flags = RATE_IN_3430ES2 },
+	{ .div = 11, .val = 11, .flags = RATE_IN_3430ES2 },
+	{ .div = 12, .val = 12, .flags = RATE_IN_3430ES2 },
+	{ .div = 13, .val = 13, .flags = RATE_IN_3430ES2 },
+	{ .div = 14, .val = 14, .flags = RATE_IN_3430ES2 },
+	{ .div = 15, .val = 15, .flags = RATE_IN_3430ES2 },
+	{ .div = 16, .val = 16, .flags = RATE_IN_3430ES2 },
+	{ .div = 17, .val = 17, .flags = RATE_IN_3430ES2 },
+	{ .div = 18, .val = 18, .flags = RATE_IN_3430ES2 },
+	{ .div = 19, .val = 19, .flags = RATE_IN_3430ES2 },
+	{ .div = 20, .val = 20, .flags = RATE_IN_3430ES2 },
+	{ .div = 21, .val = 21, .flags = RATE_IN_3430ES2 },
+	{ .div = 22, .val = 22, .flags = RATE_IN_3430ES2 },
+	{ .div = 23, .val = 23, .flags = RATE_IN_3430ES2 },
+	{ .div = 24, .val = 24, .flags = RATE_IN_3430ES2 },
+	{ .div = 25, .val = 25, .flags = RATE_IN_3430ES2 },
+	{ .div = 26, .val = 26, .flags = RATE_IN_3430ES2 },
+	{ .div = 27, .val = 27, .flags = RATE_IN_3430ES2 },
+	{ .div = 28, .val = 28, .flags = RATE_IN_3430ES2 },
+	{ .div = 29, .val = 29, .flags = RATE_IN_3430ES2 },
+	{ .div = 30, .val = 30, .flags = RATE_IN_3430ES2 },
+	{ .div = 31, .val = 31, .flags = RATE_IN_3430ES2 },
+	{ .div = 0 },
+};
+
+static const struct clksel div31_dpll3m2_clksel[] = {
+	{ .parent = &dpll3_ck, .rates = div31_dpll3_rates },
+	{ .parent = NULL }
+};
+
+/* DPLL3 output M2 - primary control point for CORE speed */
+static struct clk dpll3_m2_ck = {
+	.name		= "dpll3_m2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll3_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK,
+	.clksel		= div31_dpll3m2_clksel,
+	.clkdm_name	= "dpll3_clkdm",
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap3_core_dpll_m2_set_rate,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk core_ck = {
+	.name		= "core_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll3_m2_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dpll3_m2x2_ck = {
+	.name		= "dpll3_m2x2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll3_m2_ck,
+	.clkdm_name	= "dpll3_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static const struct clksel div16_dpll3_clksel[] = {
+	{ .parent = &dpll3_ck, .rates = div16_dpll_rates },
+	{ .parent = NULL }
+};
+
+/* This virtual clock is the source for dpll3_m3x2_ck */
+static struct clk dpll3_m3_ck = {
+	.name		= "dpll3_m3_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll3_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_DIV_DPLL3_MASK,
+	.clksel		= div16_dpll3_clksel,
+	.clkdm_name	= "dpll3_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll3_m3x2_ck = {
+	.name		= "dpll3_m3x2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dpll3_m3_ck,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_EMU_CORE_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll3_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+static struct clk emu_core_alwon_ck = {
+	.name		= "emu_core_alwon_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll3_m3x2_ck,
+	.clkdm_name	= "dpll3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* DPLL4 */
+/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */
+/* Type: DPLL */
+static struct dpll_data dpll4_dd;
+static struct dpll_data dpll4_dd_34xx __initdata = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
+	.mult_mask	= OMAP3430_PERIPH_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430_PERIPH_DPLL_DIV_MASK,
+	.clk_bypass	= &sys_ck,
+	.clk_ref	= &sys_ck,
+	.freqsel_mask	= OMAP3430_PERIPH_DPLL_FREQSEL_MASK,
+	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_mask	= OMAP3430_EN_PERIPH_DPLL_MASK,
+	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
+	.auto_recal_bit	= OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430_PERIPH_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
+	.autoidle_mask	= OMAP3430_AUTO_PERIPH_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
+	.idlest_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
+	.max_multiplier = OMAP3_MAX_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
+};
+
+static struct dpll_data dpll4_dd_3630 __initdata = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
+	.mult_mask	= OMAP3630_PERIPH_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430_PERIPH_DPLL_DIV_MASK,
+	.clk_bypass	= &sys_ck,
+	.clk_ref	= &sys_ck,
+	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_mask	= OMAP3430_EN_PERIPH_DPLL_MASK,
+	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
+	.auto_recal_bit	= OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430_PERIPH_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
+	.autoidle_mask	= OMAP3430_AUTO_PERIPH_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
+	.idlest_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
+	.max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE,
+	.flags		= DPLL_J_TYPE
+};
+
+static struct clk dpll4_ck = {
+	.name		= "dpll4_ck",
+	.ops		= &clkops_omap3_noncore_dpll_ops,
+	.parent		= &sys_ck,
+	.dpll_data	= &dpll4_dd,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_dpll4_set_rate,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap3_dpll_recalc,
+};
+
+/*
+ * This virtual clock provides the CLKOUTX2 output from the DPLL if the
+ * DPLL isn't bypassed --
+ * XXX does this serve any downstream clocks?
+ */
+static struct clk dpll4_x2_ck = {
+	.name		= "dpll4_x2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_ck,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel div16_dpll4_clksel[] = {
+	{ .parent = &dpll4_ck, .rates = div16_dpll_rates },
+	{ .parent = NULL }
+};
+
+static const struct clksel div32_dpll4_clksel[] = {
+	{ .parent = &dpll4_ck, .rates = div32_dpll4_rates_3630 },
+	{ .parent = NULL }
+};
+
+/* This virtual clock is the source for dpll4_m2x2_ck */
+static struct clk dpll4_m2_ck;
+
+static struct clk dpll4_m2_ck_34xx __initdata = {
+	.name		= "dpll4_m2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430_CM_CLKSEL3),
+	.clksel_mask	= OMAP3430_DIV_96M_MASK,
+	.clksel		= div16_dpll4_clksel,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk dpll4_m2_ck_3630 __initdata  = {
+	.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	= OMAP3630_DIV_96M_MASK,
+	.clksel		= div32_dpll4_clksel,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll4_m2x2_ck = {
+	.name		= "dpll4_m2x2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dpll4_m2_ck,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_96M_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+/*
+ * DPLL4 generates DPLL4_M2X2_CLK which is then routed into the PRM as
+ * PRM_96M_ALWON_(F)CLK.  Two clocks then emerge from the PRM:
+ * 96M_ALWON_FCLK (called "omap_96m_alwon_fck" below) and
+ * CM_96K_(F)CLK.
+ */
+
+/* Adding 192MHz Clock node needed by SGX */
+static struct clk omap_192m_alwon_fck = {
+	.name		= "omap_192m_alwon_fck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_m2x2_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static const struct clksel_rate omap_96m_alwon_fck_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_36XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_36XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel omap_96m_alwon_fck_clksel[] = {
+	{ .parent = &omap_192m_alwon_fck, .rates = omap_96m_alwon_fck_rates },
+	{ .parent = NULL }
+};
+
+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 struct clk omap_96m_alwon_fck = {
+	.name		= "omap_96m_alwon_fck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_m2x2_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk omap_96m_alwon_fck_3630 = {
+	.name		= "omap_96m_alwon_fck",
+	.parent		= &omap_192m_alwon_fck,
+	.init		= &omap2_init_clksel_parent,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3630_CLKSEL_96M_MASK,
+	.clksel		= omap_96m_alwon_fck_clksel
+};
+
+static struct clk cm_96m_fck = {
+	.name		= "cm_96m_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_96m_alwon_fck,
+	.recalc		= &followparent_recalc,
+};
+
+static const struct clksel omap_96m_fck_clksel[] = {
+	{ .parent = &cm_96m_fck, .rates = omap_96m_dpll_rates },
+	{ .parent = &sys_ck,	 .rates = omap_96m_sys_rates },
+	{ .parent = NULL }
+};
+
+static struct clk omap_96m_fck = {
+	.name		= "omap_96m_fck",
+	.ops		= &clkops_null,
+	.parent		= &sys_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_SOURCE_96M_MASK,
+	.clksel		= omap_96m_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* This virtual clock is the source for dpll4_m3x2_ck */
+static struct clk dpll4_m3_ck;
+
+static struct clk dpll4_m3_ck_34xx __initdata = {
+	.name		= "dpll4_m3_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_TV_MASK,
+	.clksel		= div16_dpll4_clksel,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk dpll4_m3_ck_3630 __initdata = {
+	.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	= OMAP3630_CLKSEL_TV_MASK,
+	.clksel		= div32_dpll4_clksel,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll4_m3x2_ck = {
+	.name		= "dpll4_m3x2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dpll4_m3_ck,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_TV_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel_rate omap_54m_d4m3x2_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate omap_54m_alt_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel omap_54m_clksel[] = {
+	{ .parent = &dpll4_m3x2_ck, .rates = omap_54m_d4m3x2_rates },
+	{ .parent = &sys_altclk,    .rates = omap_54m_alt_rates },
+	{ .parent = NULL }
+};
+
+static struct clk omap_54m_fck = {
+	.name		= "omap_54m_fck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_SOURCE_54M_MASK,
+	.clksel		= omap_54m_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate omap_48m_cm96m_rates[] = {
+	{ .div = 2, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate omap_48m_alt_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel omap_48m_clksel[] = {
+	{ .parent = &cm_96m_fck, .rates = omap_48m_cm96m_rates },
+	{ .parent = &sys_altclk, .rates = omap_48m_alt_rates },
+	{ .parent = NULL }
+};
+
+static struct clk omap_48m_fck = {
+	.name		= "omap_48m_fck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_SOURCE_48M_MASK,
+	.clksel		= omap_48m_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk omap_12m_fck = {
+	.name		= "omap_12m_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_48m_fck,
+	.fixed_div	= 4,
+	.recalc		= &omap_fixed_divisor_recalc,
+};
+
+/* This virstual clock is the source for dpll4_m4x2_ck */
+static struct clk dpll4_m4_ck;
+
+static struct clk dpll4_m4_ck_34xx __initdata = {
+	.name		= "dpll4_m4_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_DSS1_MASK,
+	.clksel		= div16_dpll4_clksel,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate,
+};
+
+static struct clk dpll4_m4_ck_3630 __initdata = {
+	.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	= OMAP3630_CLKSEL_DSS1_MASK,
+	.clksel		= div32_dpll4_clksel,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll4_m4x2_ck = {
+	.name		= "dpll4_m4x2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dpll4_m4_ck,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_DSS1_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+/* This virtual clock is the source for dpll4_m5x2_ck */
+static struct clk dpll4_m5_ck;
+
+static struct clk dpll4_m5_ck_34xx __initdata = {
+	.name		= "dpll4_m5_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_CAM_MASK,
+	.clksel		= div16_dpll4_clksel,
+	.clkdm_name	= "dpll4_clkdm",
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk dpll4_m5_ck_3630 __initdata = {
+	.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	= OMAP3630_CLKSEL_CAM_MASK,
+	.clksel		= div32_dpll4_clksel,
+	.clkdm_name	= "dpll4_clkdm",
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll4_m5x2_ck = {
+	.name		= "dpll4_m5x2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dpll4_m5_ck,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_CAM_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+/* This virtual clock is the source for dpll4_m6x2_ck */
+static struct clk dpll4_m6_ck;
+
+static struct clk dpll4_m6_ck_34xx __initdata = {
+	.name		= "dpll4_m6_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_DIV_DPLL4_MASK,
+	.clksel		= div16_dpll4_clksel,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk dpll4_m6_ck_3630 __initdata = {
+	.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	= OMAP3630_DIV_DPLL4_MASK,
+	.clksel		= div32_dpll4_clksel,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll4_m6x2_ck = {
+	.name		= "dpll4_m6x2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dpll4_m6_ck,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_EMU_PERIPH_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+static struct clk emu_per_alwon_ck = {
+	.name		= "emu_per_alwon_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_m6x2_ck,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* DPLL5 */
+/* Supplies 120MHz clock, USIM source clock */
+/* Type: DPLL */
+/* 3430ES2 only */
+static struct dpll_data dpll5_dd = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4),
+	.mult_mask	= OMAP3430ES2_PERIPH2_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430ES2_PERIPH2_DPLL_DIV_MASK,
+	.clk_bypass	= &sys_ck,
+	.clk_ref	= &sys_ck,
+	.freqsel_mask	= OMAP3430ES2_PERIPH2_DPLL_FREQSEL_MASK,
+	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2),
+	.enable_mask	= OMAP3430ES2_EN_PERIPH2_DPLL_MASK,
+	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
+	.auto_recal_bit	= OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL),
+	.autoidle_mask	= OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
+	.idlest_mask	= OMAP3430ES2_ST_PERIPH2_CLK_MASK,
+	.max_multiplier = OMAP3_MAX_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
+};
+
+static struct clk dpll5_ck = {
+	.name		= "dpll5_ck",
+	.ops		= &clkops_omap3_noncore_dpll_ops,
+	.parent		= &sys_ck,
+	.dpll_data	= &dpll5_dd,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.clkdm_name	= "dpll5_clkdm",
+	.recalc		= &omap3_dpll_recalc,
+};
+
+static const struct clksel div16_dpll5_clksel[] = {
+	{ .parent = &dpll5_ck, .rates = div16_dpll_rates },
+	{ .parent = NULL }
+};
+
+static struct clk dpll5_m2_ck = {
+	.name		= "dpll5_m2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll5_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL5),
+	.clksel_mask	= OMAP3430ES2_DIV_120M_MASK,
+	.clksel		= div16_dpll5_clksel,
+	.clkdm_name	= "dpll5_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* CM EXTERNAL CLOCK OUTPUTS */
+
+static const struct clksel_rate clkout2_src_core_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate clkout2_src_sys_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate clkout2_src_96m_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate clkout2_src_54m_rates[] = {
+	{ .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel clkout2_src_clksel[] = {
+	{ .parent = &core_ck,		.rates = clkout2_src_core_rates },
+	{ .parent = &sys_ck,		.rates = clkout2_src_sys_rates },
+	{ .parent = &cm_96m_fck,	.rates = clkout2_src_96m_rates },
+	{ .parent = &omap_54m_fck,	.rates = clkout2_src_54m_rates },
+	{ .parent = NULL }
+};
+
+static struct clk clkout2_src_ck = {
+	.name		= "clkout2_src_ck",
+	.ops		= &clkops_omap2_dflt,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP3430_CM_CLKOUT_CTRL,
+	.enable_bit	= OMAP3430_CLKOUT2_EN_SHIFT,
+	.clksel_reg	= OMAP3430_CM_CLKOUT_CTRL,
+	.clksel_mask	= OMAP3430_CLKOUT2SOURCE_MASK,
+	.clksel		= clkout2_src_clksel,
+	.clkdm_name	= "core_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate sys_clkout2_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 1, .flags = RATE_IN_343X },
+	{ .div = 4, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 8, .val = 3, .flags = RATE_IN_343X },
+	{ .div = 16, .val = 4, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel sys_clkout2_clksel[] = {
+	{ .parent = &clkout2_src_ck, .rates = sys_clkout2_rates },
+	{ .parent = NULL },
+};
+
+static struct clk sys_clkout2 = {
+	.name		= "sys_clkout2",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP3430_CM_CLKOUT_CTRL,
+	.clksel_mask	= OMAP3430_CLKOUT2_DIV_MASK,
+	.clksel		= sys_clkout2_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* CM OUTPUT CLOCKS */
+
+static struct clk corex2_fck = {
+	.name		= "corex2_fck",
+	.ops		= &clkops_null,
+	.parent		= &dpll3_m2x2_ck,
+	.recalc		= &followparent_recalc,
+};
+
+/* DPLL power domain clock controls */
+
+static const struct clksel_rate div4_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
+	{ .div = 0 }
+};
+
+static const struct clksel div4_core_clksel[] = {
+	{ .parent = &core_ck, .rates = div4_rates },
+	{ .parent = NULL }
+};
+
+/*
+ * REVISIT: Are these in DPLL power domain or CM power domain? docs
+ * may be inconsistent here?
+ */
+static struct clk dpll1_fck = {
+	.name		= "dpll1_fck",
+	.ops		= &clkops_null,
+	.parent		= &core_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
+	.clksel_mask	= OMAP3430_MPU_CLK_SRC_MASK,
+	.clksel		= div4_core_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk mpu_ck = {
+	.name		= "mpu_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll1_x2m2_ck,
+	.clkdm_name	= "mpu_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* arm_fck is divided by two when DPLL1 locked; otherwise, passthrough mpu_ck */
+static const struct clksel_rate arm_fck_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 1, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel arm_fck_clksel[] = {
+	{ .parent = &mpu_ck, .rates = arm_fck_rates },
+	{ .parent = NULL }
+};
+
+static struct clk arm_fck = {
+	.name		= "arm_fck",
+	.ops		= &clkops_null,
+	.parent		= &mpu_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
+	.clksel_mask	= OMAP3430_ST_MPU_CLK_MASK,
+	.clksel		= arm_fck_clksel,
+	.clkdm_name	= "mpu_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* XXX What about neon_clkdm ? */
+
+/*
+ * REVISIT: This clock is never specifically defined in the 3430 TRM,
+ * although it is referenced - so this is a guess
+ */
+static struct clk emu_mpu_alwon_ck = {
+	.name		= "emu_mpu_alwon_ck",
+	.ops		= &clkops_null,
+	.parent		= &mpu_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dpll2_fck = {
+	.name		= "dpll2_fck",
+	.ops		= &clkops_null,
+	.parent		= &core_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
+	.clksel_mask	= OMAP3430_IVA2_CLK_SRC_MASK,
+	.clksel		= div4_core_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk iva2_ck = {
+	.name		= "iva2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dpll2_m2_ck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
+	.clkdm_name	= "iva2_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* Common interface clocks */
+
+static const struct clksel div2_core_clksel[] = {
+	{ .parent = &core_ck, .rates = div2_rates },
+	{ .parent = NULL }
+};
+
+static struct clk l3_ick = {
+	.name		= "l3_ick",
+	.ops		= &clkops_null,
+	.parent		= &core_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_L3_MASK,
+	.clksel		= div2_core_clksel,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel div2_l3_clksel[] = {
+	{ .parent = &l3_ick, .rates = div2_rates },
+	{ .parent = NULL }
+};
+
+static struct clk l4_ick = {
+	.name		= "l4_ick",
+	.ops		= &clkops_null,
+	.parent		= &l3_ick,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_L4_MASK,
+	.clksel		= div2_l3_clksel,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+
+};
+
+static const struct clksel div2_l4_clksel[] = {
+	{ .parent = &l4_ick, .rates = div2_rates },
+	{ .parent = NULL }
+};
+
+static struct clk rm_ick = {
+	.name		= "rm_ick",
+	.ops		= &clkops_null,
+	.parent		= &l4_ick,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_RM_MASK,
+	.clksel		= div2_l4_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* GFX power domain */
+
+/* GFX clocks are in 3430ES1 only. 3430ES2 and later uses the SGX instead */
+
+static const struct clksel gfx_l3_clksel[] = {
+	{ .parent = &l3_ick, .rates = gfx_l3_rates },
+	{ .parent = NULL }
+};
+
+/* Virtual parent clock for gfx_l3_ick and gfx_l3_fck */
+static struct clk gfx_l3_ck = {
+	.name		= "gfx_l3_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP_EN_GFX_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gfx_l3_fck = {
+	.name		= "gfx_l3_fck",
+	.ops		= &clkops_null,
+	.parent		= &gfx_l3_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
+	.clksel		= gfx_l3_clksel,
+	.clkdm_name	= "gfx_3430es1_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gfx_l3_ick = {
+	.name		= "gfx_l3_ick",
+	.ops		= &clkops_null,
+	.parent		= &gfx_l3_ck,
+	.clkdm_name	= "gfx_3430es1_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gfx_cg1_ck = {
+	.name		= "gfx_cg1_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &gfx_l3_fck, /* REVISIT: correct? */
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES1_EN_2D_SHIFT,
+	.clkdm_name	= "gfx_3430es1_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gfx_cg2_ck = {
+	.name		= "gfx_cg2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &gfx_l3_fck, /* REVISIT: correct? */
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES1_EN_3D_SHIFT,
+	.clkdm_name	= "gfx_3430es1_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* SGX power domain - 3430ES2 only */
+
+static const struct clksel_rate sgx_core_rates[] = {
+	{ .div = 2, .val = 5, .flags = RATE_IN_36XX },
+	{ .div = 3, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 4, .val = 1, .flags = RATE_IN_343X },
+	{ .div = 6, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate sgx_192m_rates[] = {
+	{ .div = 1,  .val = 4, .flags = RATE_IN_36XX | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate sgx_corex2_rates[] = {
+	{ .div = 3, .val = 6, .flags = RATE_IN_36XX | DEFAULT_RATE },
+	{ .div = 5, .val = 7, .flags = RATE_IN_36XX },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate sgx_96m_rates[] = {
+	{ .div = 1,  .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel sgx_clksel[] = {
+	{ .parent = &core_ck,	 .rates = sgx_core_rates },
+	{ .parent = &cm_96m_fck, .rates = sgx_96m_rates },
+	{ .parent = &omap_192m_alwon_fck, .rates = sgx_192m_rates },
+	{ .parent = &corex2_fck, .rates = sgx_corex2_rates },
+	{ .parent = NULL }
+};
+
+static struct clk sgx_fck = {
+	.name		= "sgx_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430ES2_CLKSEL_SGX_MASK,
+	.clksel		= sgx_clksel,
+	.clkdm_name	= "sgx_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate
+};
+
+static struct clk sgx_ick = {
+	.name		= "sgx_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT,
+	.clkdm_name	= "sgx_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* CORE power domain */
+
+static struct clk d2d_26m_fck = {
+	.name		= "d2d_26m_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &sys_ck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430ES1_EN_D2D_SHIFT,
+	.clkdm_name	= "d2d_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk modem_fck = {
+	.name		= "modem_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &sys_ck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MODEM_SHIFT,
+	.clkdm_name	= "d2d_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sad2d_ick = {
+	.name		= "sad2d_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_SAD2D_SHIFT,
+	.clkdm_name	= "d2d_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mad2d_ick = {
+	.name		= "mad2d_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP3430_EN_MAD2D_SHIFT,
+	.clkdm_name	= "d2d_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static const struct clksel omap343x_gpt_clksel[] = {
+	{ .parent = &omap_32k_fck, .rates = gpt_32k_rates },
+	{ .parent = &sys_ck,	   .rates = gpt_sys_rates },
+	{ .parent = NULL}
+};
+
+static struct clk gpt10_fck = {
+	.name		= "gpt10_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &sys_ck,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_GPT10_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT10_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt11_fck = {
+	.name		= "gpt11_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &sys_ck,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_GPT11_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT11_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk cpefuse_fck = {
+	.name		= "cpefuse_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &sys_ck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
+	.enable_bit	= OMAP3430ES2_EN_CPEFUSE_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk ts_fck = {
+	.name		= "ts_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &omap_32k_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
+	.enable_bit	= OMAP3430ES2_EN_TS_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usbtll_fck = {
+	.name		= "usbtll_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &dpll5_m2_ck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
+	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/* CORE 96M FCLK-derived clocks */
+
+static struct clk core_96m_fck = {
+	.name		= "core_96m_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_96m_fck,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs3_fck = {
+	.name		= "mmchs3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430ES2_EN_MMC3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs2_fck = {
+	.name		= "mmchs2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MMC2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mspro_fck = {
+	.name		= "mspro_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MSPRO_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs1_fck = {
+	.name		= "mmchs1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MMC1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c3_fck = {
+	.name		= "i2c3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c2_fck = {
+	.name		= "i2c2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c1_fck = {
+	.name		= "i2c1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * MCBSP 1 & 5 get their 96MHz clock from core_96m_fck;
+ * MCBSP 2, 3, 4 get their 96MHz clock from per_96m_fck.
+ */
+static const struct clksel_rate common_mcbsp_96m_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel mcbsp_15_clksel[] = {
+	{ .parent = &core_96m_fck, .rates = common_mcbsp_96m_rates },
+	{ .parent = &mcbsp_clks,   .rates = common_mcbsp_mcbsp_rates },
+	{ .parent = NULL }
+};
+
+static struct clk mcbsp5_fck = {
+	.name		= "mcbsp5_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCBSP5_SHIFT,
+	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
+	.clksel_mask	= OMAP2_MCBSP5_CLKS_MASK,
+	.clksel		= mcbsp_15_clksel,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp1_fck = {
+	.name		= "mcbsp1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCBSP1_SHIFT,
+	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+	.clksel_mask	= OMAP2_MCBSP1_CLKS_MASK,
+	.clksel		= mcbsp_15_clksel,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* CORE_48M_FCK-derived clocks */
+
+static struct clk core_48m_fck = {
+	.name		= "core_48m_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_48m_fck,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi4_fck = {
+	.name		= "mcspi4_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI4_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi3_fck = {
+	.name		= "mcspi3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi2_fck = {
+	.name		= "mcspi2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi1_fck = {
+	.name		= "mcspi1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart2_fck = {
+	.name		= "uart2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_UART2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart1_fck = {
+	.name		= "uart1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_UART1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk fshostusb_fck = {
+	.name		= "fshostusb_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/* CORE_12M_FCK based clocks */
+
+static struct clk core_12m_fck = {
+	.name		= "core_12m_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_12m_fck,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hdq_fck = {
+	.name		= "hdq_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_12m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_HDQ_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/* DPLL3-derived clock */
+
+static const struct clksel_rate ssi_ssr_corex2_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
+	{ .div = 6, .val = 6, .flags = RATE_IN_343X },
+	{ .div = 8, .val = 8, .flags = RATE_IN_343X },
+	{ .div = 0 }
+};
+
+static const struct clksel ssi_ssr_clksel[] = {
+	{ .parent = &corex2_fck, .rates = ssi_ssr_corex2_rates },
+	{ .parent = NULL }
+};
+
+static struct clk ssi_ssr_fck_3430es1 = {
+	.name		= "ssi_ssr_fck",
+	.ops		= &clkops_omap2_dflt,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_SSI_MASK,
+	.clksel		= ssi_ssr_clksel,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk ssi_ssr_fck_3430es2 = {
+	.name		= "ssi_ssr_fck",
+	.ops		= &clkops_omap3430es2_ssi_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_SSI_MASK,
+	.clksel		= ssi_ssr_clksel,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk ssi_sst_fck_3430es1 = {
+	.name		= "ssi_sst_fck",
+	.ops		= &clkops_null,
+	.parent		= &ssi_ssr_fck_3430es1,
+	.fixed_div	= 2,
+	.recalc		= &omap_fixed_divisor_recalc,
+};
+
+static struct clk ssi_sst_fck_3430es2 = {
+	.name		= "ssi_sst_fck",
+	.ops		= &clkops_null,
+	.parent		= &ssi_ssr_fck_3430es2,
+	.fixed_div	= 2,
+	.recalc		= &omap_fixed_divisor_recalc,
+};
+
+
+
+/* CORE_L3_ICK based clocks */
+
+/*
+ * XXX must add clk_enable/clk_disable for these if standard code won't
+ * handle it
+ */
+static struct clk core_l3_ick = {
+	.name		= "core_l3_ick",
+	.ops		= &clkops_null,
+	.parent		= &l3_ick,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hsotgusb_ick_3430es1 = {
+	.name		= "hsotgusb_ick",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &core_l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hsotgusb_ick_3430es2 = {
+	.name		= "hsotgusb_ick",
+	.ops		= &clkops_omap3430es2_hsotgusb_wait,
+	.parent		= &core_l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sdrc_ick = {
+	.name		= "sdrc_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_SDRC_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpmc_fck = {
+	.name		= "gpmc_fck",
+	.ops		= &clkops_null,
+	.parent		= &core_l3_ick,
+	.flags		= ENABLE_ON_INIT, /* huh? */
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* SECURITY_L3_ICK based clocks */
+
+static struct clk security_l3_ick = {
+	.name		= "security_l3_ick",
+	.ops		= &clkops_null,
+	.parent		= &l3_ick,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk pka_ick = {
+	.name		= "pka_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &security_l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP3430_EN_PKA_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/* CORE_L4_ICK based clocks */
+
+static struct clk core_l4_ick = {
+	.name		= "core_l4_ick",
+	.ops		= &clkops_null,
+	.parent		= &l4_ick,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usbtll_ick = {
+	.name		= "usbtll_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs3_ick = {
+	.name		= "mmchs3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430ES2_EN_MMC3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* Intersystem Communication Registers - chassis mode only */
+static struct clk icr_ick = {
+	.name		= "icr_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_ICR_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk aes2_ick = {
+	.name		= "aes2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_AES2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sha12_ick = {
+	.name		= "sha12_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_SHA12_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk des2_ick = {
+	.name		= "des2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_DES2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs2_ick = {
+	.name		= "mmchs2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MMC2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs1_ick = {
+	.name		= "mmchs1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MMC1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mspro_ick = {
+	.name		= "mspro_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MSPRO_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hdq_ick = {
+	.name		= "hdq_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_HDQ_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi4_ick = {
+	.name		= "mcspi4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI4_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi3_ick = {
+	.name		= "mcspi3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi2_ick = {
+	.name		= "mcspi2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi1_ick = {
+	.name		= "mcspi1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c3_ick = {
+	.name		= "i2c3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c2_ick = {
+	.name		= "i2c2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c1_ick = {
+	.name		= "i2c1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart2_ick = {
+	.name		= "uart2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_UART2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart1_ick = {
+	.name		= "uart1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_UART1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt11_ick = {
+	.name		= "gpt11_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_GPT11_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt10_ick = {
+	.name		= "gpt10_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_GPT10_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp5_ick = {
+	.name		= "mcbsp5_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCBSP5_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp1_ick = {
+	.name		= "mcbsp1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCBSP1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk fac_ick = {
+	.name		= "fac_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430ES1_EN_FAC_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mailboxes_ick = {
+	.name		= "mailboxes_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MAILBOXES_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk omapctrl_ick = {
+	.name		= "omapctrl_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_OMAPCTRL_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.recalc		= &followparent_recalc,
+};
+
+/* SSI_L4_ICK based clocks */
+
+static struct clk ssi_l4_ick = {
+	.name		= "ssi_l4_ick",
+	.ops		= &clkops_null,
+	.parent		= &l4_ick,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk ssi_ick_3430es1 = {
+	.name		= "ssi_ick",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &ssi_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk ssi_ick_3430es2 = {
+	.name		= "ssi_ick",
+	.ops		= &clkops_omap3430es2_ssi_wait,
+	.parent		= &ssi_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* REVISIT: Technically the TRM claims that this is CORE_CLK based,
+ * but l4_ick makes more sense to me */
+
+static const struct clksel usb_l4_clksel[] = {
+	{ .parent = &l4_ick, .rates = div2_rates },
+	{ .parent = NULL },
+};
+
+static struct clk usb_l4_ick = {
+	.name		= "usb_l4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ick,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK,
+	.clksel		= usb_l4_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* SECURITY_L4_ICK2 based clocks */
+
+static struct clk security_l4_ick2 = {
+	.name		= "security_l4_ick2",
+	.ops		= &clkops_null,
+	.parent		= &l4_ick,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk aes1_ick = {
+	.name		= "aes1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &security_l4_ick2,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP3430_EN_AES1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk rng_ick = {
+	.name		= "rng_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &security_l4_ick2,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP3430_EN_RNG_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sha11_ick = {
+	.name		= "sha11_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &security_l4_ick2,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP3430_EN_SHA11_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk des1_ick = {
+	.name		= "des1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &security_l4_ick2,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP3430_EN_DES1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/* DSS */
+static struct clk dss1_alwon_fck_3430es1 = {
+	.name		= "dss1_alwon_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &dpll4_m4x2_ck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss1_alwon_fck_3430es2 = {
+	.name		= "dss1_alwon_fck",
+	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
+	.parent		= &dpll4_m4x2_ck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss_tv_fck = {
+	.name		= "dss_tv_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &omap_54m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_TV_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss_96m_fck = {
+	.name		= "dss_96m_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &omap_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_TV_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss2_alwon_fck = {
+	.name		= "dss2_alwon_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &sys_ck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_DSS2_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss_ick_3430es1 = {
+	/* Handles both L3 and L4 clocks */
+	.name		= "dss_ick",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss_ick_3430es2 = {
+	/* Handles both L3 and L4 clocks */
+	.name		= "dss_ick",
+	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
+	.parent		= &l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* CAM */
+
+static struct clk cam_mclk = {
+	.name		= "cam_mclk",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &dpll4_m5x2_ck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
+	.clkdm_name	= "cam_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk cam_ick = {
+	/* Handles both L3 and L4 clocks */
+	.name		= "cam_ick",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
+	.clkdm_name	= "cam_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk csi2_96m_fck = {
+	.name		= "csi2_96m_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_CSI2_SHIFT,
+	.clkdm_name	= "cam_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* USBHOST - 3430ES2 only */
+
+static struct clk usbhost_120m_fck = {
+	.name		= "usbhost_120m_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &dpll5_m2_ck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES2_EN_USBHOST2_SHIFT,
+	.clkdm_name	= "usbhost_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usbhost_48m_fck = {
+	.name		= "usbhost_48m_fck",
+	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
+	.parent		= &omap_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES2_EN_USBHOST1_SHIFT,
+	.clkdm_name	= "usbhost_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usbhost_ick = {
+	/* Handles both L3 and L4 clocks */
+	.name		= "usbhost_ick",
+	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
+	.parent		= &l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430ES2_EN_USBHOST_SHIFT,
+	.clkdm_name	= "usbhost_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* WKUP */
+
+static const struct clksel_rate usim_96m_rates[] = {
+	{ .div = 2,  .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 4,  .val = 4, .flags = RATE_IN_343X },
+	{ .div = 8,  .val = 5, .flags = RATE_IN_343X },
+	{ .div = 10, .val = 6, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate usim_120m_rates[] = {
+	{ .div = 4,  .val = 7,	.flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 8,  .val = 8,	.flags = RATE_IN_343X },
+	{ .div = 16, .val = 9,	.flags = RATE_IN_343X },
+	{ .div = 20, .val = 10, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel usim_clksel[] = {
+	{ .parent = &omap_96m_fck,	.rates = usim_96m_rates },
+	{ .parent = &dpll5_m2_ck,	.rates = usim_120m_rates },
+	{ .parent = &sys_ck,		.rates = div2_rates },
+	{ .parent = NULL },
+};
+
+/* 3430ES2 only */
+static struct clk usim_fck = {
+	.name		= "usim_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES2_EN_USIMOCP_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430ES2_CLKSEL_USIMOCP_MASK,
+	.clksel		= usim_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* XXX should gpt1's clksel have wkup_32k_fck as the 32k opt? */
+static struct clk gpt1_fck = {
+	.name		= "gpt1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT1_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT1_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk wkup_32k_fck = {
+	.name		= "wkup_32k_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_32k_fck,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio1_dbck = {
+	.name		= "gpio1_dbck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &wkup_32k_fck,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt2_fck = {
+	.name		= "wdt2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_32k_fck,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_WDT2_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wkup_l4_ick = {
+	.name		= "wkup_l4_ick",
+	.ops		= &clkops_null,
+	.parent		= &sys_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* 3430ES2 only */
+/* Never specifically named in the TRM, so we have to infer a likely name */
+static struct clk usim_ick = {
+	.name		= "usim_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430ES2_EN_USIMOCP_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt2_ick = {
+	.name		= "wdt2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_WDT2_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt1_ick = {
+	.name		= "wdt1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_WDT1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio1_ick = {
+	.name		= "gpio1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk omap_32ksync_ick = {
+	.name		= "omap_32ksync_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_32KSYNC_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* XXX This clock no longer exists in 3430 TRM rev F */
+static struct clk gpt12_ick = {
+	.name		= "gpt12_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT12_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt1_ick = {
+	.name		= "gpt1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+
+
+/* PER clock domain */
+
+static struct clk per_96m_fck = {
+	.name		= "per_96m_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_96m_alwon_fck,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk per_48m_fck = {
+	.name		= "per_48m_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_48m_fck,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart3_fck = {
+	.name		= "uart3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_UART3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt2_fck = {
+	.name		= "gpt2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT2_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT2_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt3_fck = {
+	.name		= "gpt3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT3_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT3_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt4_fck = {
+	.name		= "gpt4_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT4_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT4_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt5_fck = {
+	.name		= "gpt5_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT5_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT5_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt6_fck = {
+	.name		= "gpt6_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT6_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT6_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt7_fck = {
+	.name		= "gpt7_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT7_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT7_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt8_fck = {
+	.name		= "gpt8_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT8_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT8_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt9_fck = {
+	.name		= "gpt9_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT9_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT9_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk per_32k_alwon_fck = {
+	.name		= "per_32k_alwon_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_32k_fck,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio6_dbck = {
+	.name		= "gpio6_dbck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &per_32k_alwon_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO6_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio5_dbck = {
+	.name		= "gpio5_dbck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &per_32k_alwon_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO5_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio4_dbck = {
+	.name		= "gpio4_dbck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &per_32k_alwon_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO4_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio3_dbck = {
+	.name		= "gpio3_dbck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &per_32k_alwon_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio2_dbck = {
+	.name		= "gpio2_dbck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &per_32k_alwon_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO2_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt3_fck = {
+	.name		= "wdt3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_32k_alwon_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_WDT3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk per_l4_ick = {
+	.name		= "per_l4_ick",
+	.ops		= &clkops_null,
+	.parent		= &l4_ick,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio6_ick = {
+	.name		= "gpio6_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO6_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio5_ick = {
+	.name		= "gpio5_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO5_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio4_ick = {
+	.name		= "gpio4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO4_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio3_ick = {
+	.name		= "gpio3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio2_ick = {
+	.name		= "gpio2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO2_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt3_ick = {
+	.name		= "wdt3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_WDT3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart3_ick = {
+	.name		= "uart3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_UART3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt9_ick = {
+	.name		= "gpt9_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT9_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt8_ick = {
+	.name		= "gpt8_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT8_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt7_ick = {
+	.name		= "gpt7_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT7_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt6_ick = {
+	.name		= "gpt6_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT6_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt5_ick = {
+	.name		= "gpt5_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT5_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt4_ick = {
+	.name		= "gpt4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT4_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt3_ick = {
+	.name		= "gpt3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt2_ick = {
+	.name		= "gpt2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT2_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp2_ick = {
+	.name		= "mcbsp2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_MCBSP2_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp3_ick = {
+	.name		= "mcbsp3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_MCBSP3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp4_ick = {
+	.name		= "mcbsp4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_MCBSP4_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static const struct clksel mcbsp_234_clksel[] = {
+	{ .parent = &per_96m_fck,  .rates = common_mcbsp_96m_rates },
+	{ .parent = &mcbsp_clks,   .rates = common_mcbsp_mcbsp_rates },
+	{ .parent = NULL }
+};
+
+static struct clk mcbsp2_fck = {
+	.name		= "mcbsp2_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_MCBSP2_SHIFT,
+	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+	.clksel_mask	= OMAP2_MCBSP2_CLKS_MASK,
+	.clksel		= mcbsp_234_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp3_fck = {
+	.name		= "mcbsp3_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_MCBSP3_SHIFT,
+	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
+	.clksel_mask	= OMAP2_MCBSP3_CLKS_MASK,
+	.clksel		= mcbsp_234_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp4_fck = {
+	.name		= "mcbsp4_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_MCBSP4_SHIFT,
+	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
+	.clksel_mask	= OMAP2_MCBSP4_CLKS_MASK,
+	.clksel		= mcbsp_234_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* EMU clocks */
+
+/* More information: ARM Cortex-A8 Technical Reference Manual, sect 10.1 */
+
+static const struct clksel_rate emu_src_sys_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate emu_src_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate emu_src_per_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate emu_src_mpu_rates[] = {
+	{ .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel emu_src_clksel[] = {
+	{ .parent = &sys_ck,		.rates = emu_src_sys_rates },
+	{ .parent = &emu_core_alwon_ck, .rates = emu_src_core_rates },
+	{ .parent = &emu_per_alwon_ck,	.rates = emu_src_per_rates },
+	{ .parent = &emu_mpu_alwon_ck,	.rates = emu_src_mpu_rates },
+	{ .parent = NULL },
+};
+
+/*
+ * Like the clkout_src clocks, emu_src_clk is a virtual clock, existing only
+ * to switch the source of some of the EMU clocks.
+ * XXX Are there CLKEN bits for these EMU clks?
+ */
+static struct clk emu_src_ck = {
+	.name		= "emu_src_ck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_MUX_CTRL_MASK,
+	.clksel		= emu_src_clksel,
+	.clkdm_name	= "emu_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate pclk_emu_rates[] = {
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
+	{ .div = 6, .val = 6, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel pclk_emu_clksel[] = {
+	{ .parent = &emu_src_ck, .rates = pclk_emu_rates },
+	{ .parent = NULL },
+};
+
+static struct clk pclk_fck = {
+	.name		= "pclk_fck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_CLKSEL_PCLK_MASK,
+	.clksel		= pclk_emu_clksel,
+	.clkdm_name	= "emu_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate pclkx2_emu_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel pclkx2_emu_clksel[] = {
+	{ .parent = &emu_src_ck, .rates = pclkx2_emu_rates },
+	{ .parent = NULL },
+};
+
+static struct clk pclkx2_fck = {
+	.name		= "pclkx2_fck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_CLKSEL_PCLKX2_MASK,
+	.clksel		= pclkx2_emu_clksel,
+	.clkdm_name	= "emu_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel atclk_emu_clksel[] = {
+	{ .parent = &emu_src_ck, .rates = div2_rates },
+	{ .parent = NULL },
+};
+
+static struct clk atclk_fck = {
+	.name		= "atclk_fck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_CLKSEL_ATCLK_MASK,
+	.clksel		= atclk_emu_clksel,
+	.clkdm_name	= "emu_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk traceclk_src_fck = {
+	.name		= "traceclk_src_fck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_TRACE_MUX_CTRL_MASK,
+	.clksel		= emu_src_clksel,
+	.clkdm_name	= "emu_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate traceclk_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel traceclk_clksel[] = {
+	{ .parent = &traceclk_src_fck, .rates = traceclk_rates },
+	{ .parent = NULL },
+};
+
+static struct clk traceclk_fck = {
+	.name		= "traceclk_fck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_CLKSEL_TRACECLK_MASK,
+	.clksel		= traceclk_clksel,
+	.clkdm_name	= "emu_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* SR clocks */
+
+/* SmartReflex fclk (VDD1) */
+static struct clk sr1_fck = {
+	.name		= "sr1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &sys_ck,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_SR1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/* SmartReflex fclk (VDD2) */
+static struct clk sr2_fck = {
+	.name		= "sr2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &sys_ck,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_SR2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sr_l4_ick = {
+	.name		= "sr_l4_ick",
+	.ops		= &clkops_null, /* RMK: missing? */
+	.parent		= &l4_ick,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* SECURE_32K_FCK clocks */
+
+static struct clk gpt12_fck = {
+	.name		= "gpt12_fck",
+	.ops		= &clkops_null,
+	.parent		= &secure_32k_fck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt1_fck = {
+	.name		= "wdt1_fck",
+	.ops		= &clkops_null,
+	.parent		= &secure_32k_fck,
+	.recalc		= &followparent_recalc,
+};
+
+/* Clocks for AM35XX */
+static struct clk ipss_ick = {
+	.name		= "ipss_ick",
+	.ops		= &clkops_am35xx_ipss_wait,
+	.parent		= &core_l3_ick,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= AM35XX_EN_IPSS_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk emac_ick = {
+	.name		= "emac_ick",
+	.ops		= &clkops_am35xx_ipss_module_wait,
+	.parent		= &ipss_ick,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+	.enable_bit	= AM35XX_CPGMAC_VBUSP_CLK_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk rmii_ck = {
+	.name		= "rmii_ck",
+	.ops		= &clkops_null,
+	.rate		= 50000000,
+};
+
+static struct clk emac_fck = {
+	.name		= "emac_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &rmii_ck,
+	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+	.enable_bit	= AM35XX_CPGMAC_FCLK_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hsotgusb_ick_am35xx = {
+	.name		= "hsotgusb_ick",
+	.ops		= &clkops_am35xx_ipss_module_wait,
+	.parent		= &ipss_ick,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+	.enable_bit	= AM35XX_USBOTG_VBUSP_CLK_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hsotgusb_fck_am35xx = {
+	.name		= "hsotgusb_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &sys_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+	.enable_bit	= AM35XX_USBOTG_FCLK_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hecc_ck = {
+	.name		= "hecc_ck",
+	.ops		= &clkops_am35xx_ipss_module_wait,
+	.parent		= &sys_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+	.enable_bit	= AM35XX_HECC_VBUSP_CLK_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk vpfe_ick = {
+	.name		= "vpfe_ick",
+	.ops		= &clkops_am35xx_ipss_module_wait,
+	.parent		= &ipss_ick,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+	.enable_bit	= AM35XX_VPFE_VBUSP_CLK_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk pclk_ck = {
+	.name		= "pclk_ck",
+	.ops		= &clkops_null,
+	.rate		= 27000000,
+};
+
+static struct clk vpfe_fck = {
+	.name		= "vpfe_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &pclk_ck,
+	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+	.enable_bit	= AM35XX_VPFE_FCLK_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * The UART1/2 functional clock acts as the functional
+ * clock for UART4. No separate fclk control available.
+ */
+static struct clk uart4_ick_am35xx = {
+	.name		= "uart4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= AM35XX_EN_UART4_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+
+/*
+ * clkdev
+ */
+
+/* XXX At some point we should rename this file to clock3xxx_data.c */
+static struct omap_clk omap3xxx_clks[] = {
+	CLK(NULL,	"omap_32k_fck",	&omap_32k_fck,	CK_3XXX),
+	CLK(NULL,	"virt_12m_ck",	&virt_12m_ck,	CK_3XXX),
+	CLK(NULL,	"virt_13m_ck",	&virt_13m_ck,	CK_3XXX),
+	CLK(NULL,	"virt_16_8m_ck", &virt_16_8m_ck, CK_3430ES2 | CK_AM35XX),
+	CLK(NULL,	"virt_19_2m_ck", &virt_19_2m_ck, CK_3XXX),
+	CLK(NULL,	"virt_26m_ck",	&virt_26m_ck,	CK_3XXX),
+	CLK(NULL,	"virt_38_4m_ck", &virt_38_4m_ck, CK_3XXX),
+	CLK(NULL,	"osc_sys_ck",	&osc_sys_ck,	CK_3XXX),
+	CLK(NULL,	"sys_ck",	&sys_ck,	CK_3XXX),
+	CLK(NULL,	"sys_altclk",	&sys_altclk,	CK_3XXX),
+	CLK(NULL,	"mcbsp_clks",	&mcbsp_clks,	CK_3XXX),
+	CLK(NULL,	"sys_clkout1",	&sys_clkout1,	CK_3XXX),
+	CLK(NULL,	"dpll1_ck",	&dpll1_ck,	CK_3XXX),
+	CLK(NULL,	"dpll1_x2_ck",	&dpll1_x2_ck,	CK_3XXX),
+	CLK(NULL,	"dpll1_x2m2_ck", &dpll1_x2m2_ck, CK_3XXX),
+	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_3XXX),
+	CLK(NULL,	"core_ck",	&core_ck,	CK_3XXX),
+	CLK(NULL,	"dpll3_x2_ck",	&dpll3_x2_ck,	CK_3XXX),
+	CLK(NULL,	"dpll3_m2_ck",	&dpll3_m2_ck,	CK_3XXX),
+	CLK(NULL,	"dpll3_m2x2_ck", &dpll3_m2x2_ck, CK_3XXX),
+	CLK(NULL,	"dpll3_m3_ck",	&dpll3_m3_ck,	CK_3XXX),
+	CLK(NULL,	"dpll3_m3x2_ck", &dpll3_m3x2_ck, CK_3XXX),
+	CLK("etb",	"emu_core_alwon_ck", &emu_core_alwon_ck, CK_3XXX),
+	CLK(NULL,	"dpll4_ck",	&dpll4_ck,	CK_3XXX),
+	CLK(NULL,	"dpll4_x2_ck",	&dpll4_x2_ck,	CK_3XXX),
+	CLK(NULL,	"omap_192m_alwon_fck", &omap_192m_alwon_fck, CK_36XX),
+	CLK(NULL,	"omap_96m_alwon_fck", &omap_96m_alwon_fck, CK_3XXX),
+	CLK(NULL,	"omap_96m_fck",	&omap_96m_fck,	CK_3XXX),
+	CLK(NULL,	"cm_96m_fck",	&cm_96m_fck,	CK_3XXX),
+	CLK(NULL,	"omap_54m_fck",	&omap_54m_fck,	CK_3XXX),
+	CLK(NULL,	"omap_48m_fck",	&omap_48m_fck,	CK_3XXX),
+	CLK(NULL,	"omap_12m_fck",	&omap_12m_fck,	CK_3XXX),
+	CLK(NULL,	"dpll4_m2_ck",	&dpll4_m2_ck,	CK_3XXX),
+	CLK(NULL,	"dpll4_m2x2_ck", &dpll4_m2x2_ck, CK_3XXX),
+	CLK(NULL,	"dpll4_m3_ck",	&dpll4_m3_ck,	CK_3XXX),
+	CLK(NULL,	"dpll4_m3x2_ck", &dpll4_m3x2_ck, CK_3XXX),
+	CLK(NULL,	"dpll4_m4_ck",	&dpll4_m4_ck,	CK_3XXX),
+	CLK(NULL,	"dpll4_m4x2_ck", &dpll4_m4x2_ck, CK_3XXX),
+	CLK(NULL,	"dpll4_m5_ck",	&dpll4_m5_ck,	CK_3XXX),
+	CLK(NULL,	"dpll4_m5x2_ck", &dpll4_m5x2_ck, CK_3XXX),
+	CLK(NULL,	"dpll4_m6_ck",	&dpll4_m6_ck,	CK_3XXX),
+	CLK(NULL,	"dpll4_m6x2_ck", &dpll4_m6x2_ck, CK_3XXX),
+	CLK("etb",	"emu_per_alwon_ck", &emu_per_alwon_ck, CK_3XXX),
+	CLK(NULL,	"dpll5_ck",	&dpll5_ck,	CK_3430ES2 | CK_AM35XX),
+	CLK(NULL,	"dpll5_m2_ck",	&dpll5_m2_ck,	CK_3430ES2 | CK_AM35XX),
+	CLK(NULL,	"clkout2_src_ck", &clkout2_src_ck, CK_3XXX),
+	CLK(NULL,	"sys_clkout2",	&sys_clkout2,	CK_3XXX),
+	CLK(NULL,	"corex2_fck",	&corex2_fck,	CK_3XXX),
+	CLK(NULL,	"dpll1_fck",	&dpll1_fck,	CK_3XXX),
+	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_3XXX),
+	CLK(NULL,	"arm_fck",	&arm_fck,	CK_3XXX),
+	CLK("etb",	"emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_3XXX),
+	CLK(NULL,	"dpll2_fck",	&dpll2_fck,	CK_343X),
+	CLK(NULL,	"iva2_ck",	&iva2_ck,	CK_343X),
+	CLK(NULL,	"l3_ick",	&l3_ick,	CK_3XXX),
+	CLK(NULL,	"l4_ick",	&l4_ick,	CK_3XXX),
+	CLK(NULL,	"rm_ick",	&rm_ick,	CK_3XXX),
+	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 | CK_3517),
+	CLK(NULL,	"sgx_ick",	&sgx_ick,	CK_3430ES2 | CK_3517),
+	CLK(NULL,	"d2d_26m_fck",	&d2d_26m_fck,	CK_3430ES1),
+	CLK(NULL,	"modem_fck",	&modem_fck,	CK_343X),
+	CLK(NULL,	"sad2d_ick",	&sad2d_ick,	CK_343X),
+	CLK(NULL,	"mad2d_ick",	&mad2d_ick,	CK_343X),
+	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_3XXX),
+	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_3XXX),
+	CLK(NULL,	"cpefuse_fck",	&cpefuse_fck,	CK_3430ES2 | CK_AM35XX),
+	CLK(NULL,	"ts_fck",	&ts_fck,	CK_3430ES2 | CK_AM35XX),
+	CLK(NULL,	"usbtll_fck",	&usbtll_fck,	CK_3430ES2 | CK_AM35XX),
+	CLK(NULL,	"core_96m_fck",	&core_96m_fck,	CK_3XXX),
+	CLK("mmci-omap-hs.2",	"fck",	&mmchs3_fck,	CK_3430ES2 | CK_AM35XX),
+	CLK("mmci-omap-hs.1",	"fck",	&mmchs2_fck,	CK_3XXX),
+	CLK(NULL,	"mspro_fck",	&mspro_fck,	CK_343X),
+	CLK("mmci-omap-hs.0",	"fck",	&mmchs1_fck,	CK_3XXX),
+	CLK("i2c_omap.3", "fck",	&i2c3_fck,	CK_3XXX),
+	CLK("i2c_omap.2", "fck",	&i2c2_fck,	CK_3XXX),
+	CLK("i2c_omap.1", "fck",	&i2c1_fck,	CK_3XXX),
+	CLK("omap-mcbsp.5", "fck",	&mcbsp5_fck,	CK_3XXX),
+	CLK("omap-mcbsp.1", "fck",	&mcbsp1_fck,	CK_3XXX),
+	CLK(NULL,	"core_48m_fck",	&core_48m_fck,	CK_3XXX),
+	CLK("omap2_mcspi.4", "fck",	&mcspi4_fck,	CK_3XXX),
+	CLK("omap2_mcspi.3", "fck",	&mcspi3_fck,	CK_3XXX),
+	CLK("omap2_mcspi.2", "fck",	&mcspi2_fck,	CK_3XXX),
+	CLK("omap2_mcspi.1", "fck",	&mcspi1_fck,	CK_3XXX),
+	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_3XXX),
+	CLK(NULL,	"uart1_fck",	&uart1_fck,	CK_3XXX),
+	CLK(NULL,	"fshostusb_fck", &fshostusb_fck, CK_3430ES1),
+	CLK(NULL,	"core_12m_fck",	&core_12m_fck,	CK_3XXX),
+	CLK("omap_hdq.0", "fck",	&hdq_fck,	CK_3XXX),
+	CLK(NULL,	"ssi_ssr_fck",	&ssi_ssr_fck_3430es1,	CK_3430ES1),
+	CLK(NULL,	"ssi_ssr_fck",	&ssi_ssr_fck_3430es2,	CK_3430ES2),
+	CLK(NULL,	"ssi_sst_fck",	&ssi_sst_fck_3430es1,	CK_3430ES1),
+	CLK(NULL,	"ssi_sst_fck",	&ssi_sst_fck_3430es2,	CK_3430ES2),
+	CLK(NULL,	"core_l3_ick",	&core_l3_ick,	CK_3XXX),
+	CLK("musb_hdrc",	"ick",	&hsotgusb_ick_3430es1,	CK_3430ES1),
+	CLK("musb_hdrc",	"ick",	&hsotgusb_ick_3430es2,	CK_3430ES2),
+	CLK(NULL,	"sdrc_ick",	&sdrc_ick,	CK_3XXX),
+	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_3XXX),
+	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_3XXX),
+	CLK(NULL,	"usbtll_ick",	&usbtll_ick,	CK_3430ES2 | CK_AM35XX),
+	CLK("mmci-omap-hs.2",	"ick",	&mmchs3_ick,	CK_3430ES2 | CK_AM35XX),
+	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_3XXX),
+	CLK("mmci-omap-hs.0",	"ick",	&mmchs1_ick,	CK_3XXX),
+	CLK(NULL,	"mspro_ick",	&mspro_ick,	CK_343X),
+	CLK("omap_hdq.0", "ick",	&hdq_ick,	CK_3XXX),
+	CLK("omap2_mcspi.4", "ick",	&mcspi4_ick,	CK_3XXX),
+	CLK("omap2_mcspi.3", "ick",	&mcspi3_ick,	CK_3XXX),
+	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick,	CK_3XXX),
+	CLK("omap2_mcspi.1", "ick",	&mcspi1_ick,	CK_3XXX),
+	CLK("i2c_omap.3", "ick",	&i2c3_ick,	CK_3XXX),
+	CLK("i2c_omap.2", "ick",	&i2c2_ick,	CK_3XXX),
+	CLK("i2c_omap.1", "ick",	&i2c1_ick,	CK_3XXX),
+	CLK(NULL,	"uart2_ick",	&uart2_ick,	CK_3XXX),
+	CLK(NULL,	"uart1_ick",	&uart1_ick,	CK_3XXX),
+	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_3XXX),
+	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_3XXX),
+	CLK("omap-mcbsp.5", "ick",	&mcbsp5_ick,	CK_3XXX),
+	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_3XXX),
+	CLK(NULL,	"fac_ick",	&fac_ick,	CK_3430ES1),
+	CLK(NULL,	"mailboxes_ick", &mailboxes_ick, CK_343X),
+	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_3XXX),
+	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_343X),
+	CLK(NULL,	"ssi_ick",	&ssi_ick_3430es1,	CK_3430ES1),
+	CLK(NULL,	"ssi_ick",	&ssi_ick_3430es2,	CK_3430ES2),
+	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick,	CK_3430ES1),
+	CLK(NULL,	"security_l4_ick2", &security_l4_ick2, CK_343X),
+	CLK(NULL,	"aes1_ick",	&aes1_ick,	CK_343X),
+	CLK("omap_rng",	"ick",		&rng_ick,	CK_343X),
+	CLK(NULL,	"sha11_ick",	&sha11_ick,	CK_343X),
+	CLK(NULL,	"des1_ick",	&des1_ick,	CK_343X),
+	CLK("omapdss",	"dss1_fck",	&dss1_alwon_fck_3430es1, CK_3430ES1),
+	CLK("omapdss",	"dss1_fck",	&dss1_alwon_fck_3430es2, CK_3430ES2 | CK_AM35XX),
+	CLK("omapdss",	"tv_fck",	&dss_tv_fck,	CK_3XXX),
+	CLK("omapdss",	"video_fck",	&dss_96m_fck,	CK_3XXX),
+	CLK("omapdss",	"dss2_fck",	&dss2_alwon_fck, CK_3XXX),
+	CLK("omapdss",	"ick",		&dss_ick_3430es1,	CK_3430ES1),
+	CLK("omapdss",	"ick",		&dss_ick_3430es2,	CK_3430ES2 | CK_AM35XX),
+	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 | CK_AM35XX),
+	CLK(NULL,	"usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2 | CK_AM35XX),
+	CLK(NULL,	"usbhost_ick",	&usbhost_ick,	CK_3430ES2 | CK_AM35XX),
+	CLK(NULL,	"usim_fck",	&usim_fck,	CK_3430ES2),
+	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_3XXX),
+	CLK(NULL,	"wkup_32k_fck",	&wkup_32k_fck,	CK_3XXX),
+	CLK(NULL,	"gpio1_dbck",	&gpio1_dbck,	CK_3XXX),
+	CLK("omap_wdt",	"fck",		&wdt2_fck,	CK_3XXX),
+	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_3XXX),
+	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_3XXX),
+	CLK(NULL,	"gpio1_ick",	&gpio1_ick,	CK_3XXX),
+	CLK(NULL,	"omap_32ksync_ick", &omap_32ksync_ick, CK_3XXX),
+	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_3XXX),
+	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_3XXX),
+	CLK(NULL,	"per_96m_fck",	&per_96m_fck,	CK_3XXX),
+	CLK(NULL,	"per_48m_fck",	&per_48m_fck,	CK_3XXX),
+	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_3XXX),
+	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_3XXX),
+	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_3XXX),
+	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_3XXX),
+	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_3XXX),
+	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_3XXX),
+	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_3XXX),
+	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_3XXX),
+	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_3XXX),
+	CLK(NULL,	"per_32k_alwon_fck", &per_32k_alwon_fck, CK_3XXX),
+	CLK(NULL,	"gpio6_dbck",	&gpio6_dbck,	CK_3XXX),
+	CLK(NULL,	"gpio5_dbck",	&gpio5_dbck,	CK_3XXX),
+	CLK(NULL,	"gpio4_dbck",	&gpio4_dbck,	CK_3XXX),
+	CLK(NULL,	"gpio3_dbck",	&gpio3_dbck,	CK_3XXX),
+	CLK(NULL,	"gpio2_dbck",	&gpio2_dbck,	CK_3XXX),
+	CLK(NULL,	"wdt3_fck",	&wdt3_fck,	CK_3XXX),
+	CLK(NULL,	"per_l4_ick",	&per_l4_ick,	CK_3XXX),
+	CLK(NULL,	"gpio6_ick",	&gpio6_ick,	CK_3XXX),
+	CLK(NULL,	"gpio5_ick",	&gpio5_ick,	CK_3XXX),
+	CLK(NULL,	"gpio4_ick",	&gpio4_ick,	CK_3XXX),
+	CLK(NULL,	"gpio3_ick",	&gpio3_ick,	CK_3XXX),
+	CLK(NULL,	"gpio2_ick",	&gpio2_ick,	CK_3XXX),
+	CLK(NULL,	"wdt3_ick",	&wdt3_ick,	CK_3XXX),
+	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_3XXX),
+	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_3XXX),
+	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_3XXX),
+	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_3XXX),
+	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_3XXX),
+	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_3XXX),
+	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_3XXX),
+	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_3XXX),
+	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_3XXX),
+	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_3XXX),
+	CLK("omap-mcbsp.3", "ick",	&mcbsp3_ick,	CK_3XXX),
+	CLK("omap-mcbsp.4", "ick",	&mcbsp4_ick,	CK_3XXX),
+	CLK("omap-mcbsp.2", "fck",	&mcbsp2_fck,	CK_3XXX),
+	CLK("omap-mcbsp.3", "fck",	&mcbsp3_fck,	CK_3XXX),
+	CLK("omap-mcbsp.4", "fck",	&mcbsp4_fck,	CK_3XXX),
+	CLK("etb",	"emu_src_ck",	&emu_src_ck,	CK_3XXX),
+	CLK(NULL,	"pclk_fck",	&pclk_fck,	CK_3XXX),
+	CLK(NULL,	"pclkx2_fck",	&pclkx2_fck,	CK_3XXX),
+	CLK(NULL,	"atclk_fck",	&atclk_fck,	CK_3XXX),
+	CLK(NULL,	"traceclk_src_fck", &traceclk_src_fck, CK_3XXX),
+	CLK(NULL,	"traceclk_fck",	&traceclk_fck,	CK_3XXX),
+	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_3XXX),
+	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_3XXX),
+	CLK(NULL,	"wdt1_fck",	&wdt1_fck,	CK_3XXX),
+	CLK(NULL,	"ipss_ick",	&ipss_ick,	CK_AM35XX),
+	CLK(NULL,	"rmii_ck",	&rmii_ck,	CK_AM35XX),
+	CLK(NULL,	"pclk_ck",	&pclk_ck,	CK_AM35XX),
+	CLK("davinci_emac",	"ick",		&emac_ick,	CK_AM35XX),
+	CLK("davinci_emac",	"fck",		&emac_fck,	CK_AM35XX),
+	CLK("vpfe-capture",	"master",	&vpfe_ick,	CK_AM35XX),
+	CLK("vpfe-capture",	"slave",	&vpfe_fck,	CK_AM35XX),
+	CLK("musb_hdrc",	"ick",		&hsotgusb_ick_am35xx,	CK_AM35XX),
+	CLK("musb_hdrc",	"fck",		&hsotgusb_fck_am35xx,	CK_AM35XX),
+	CLK(NULL,	"hecc_ck",	&hecc_ck,	CK_AM35XX),
+	CLK(NULL,	"uart4_ick",	&uart4_ick_am35xx,	CK_AM35XX),
+};
+
+
+int __init omap3xxx_clk_init(void)
+{
+	struct omap_clk *c;
+	u32 cpu_clkflg = CK_3XXX;
+
+	if (cpu_is_omap3517()) {
+		cpu_mask = RATE_IN_343X | RATE_IN_3430ES2;
+		cpu_clkflg |= CK_3517;
+	} else if (cpu_is_omap3505()) {
+		cpu_mask = RATE_IN_343X | RATE_IN_3430ES2;
+		cpu_clkflg |= CK_3505;
+	} else if (cpu_is_omap34xx()) {
+		cpu_mask = RATE_IN_343X;
+		cpu_clkflg |= CK_343X;
+
+		/*
+		 * Update this if there are further clock changes between ES2
+		 * and production parts
+		 */
+		if (omap_rev() == OMAP3430_REV_ES1_0) {
+			/* No 3430ES1-only rates exist, so no RATE_IN_3430ES1 */
+			cpu_clkflg |= CK_3430ES1;
+		} else {
+			cpu_mask |= RATE_IN_3430ES2;
+			cpu_clkflg |= CK_3430ES2;
+		}
+	}
+	if (omap3_has_192mhz_clk())
+		omap_96m_alwon_fck = omap_96m_alwon_fck_3630;
+
+	if (cpu_is_omap3630()) {
+		cpu_mask |= RATE_IN_36XX;
+		cpu_clkflg |= CK_36XX;
+
+		/*
+		 * XXX This type of dynamic rewriting of the clock tree is
+		 * deprecated and should be revised soon.
+		 */
+		dpll4_m2_ck = dpll4_m2_ck_3630;
+		dpll4_m3_ck = dpll4_m3_ck_3630;
+		dpll4_m4_ck = dpll4_m4_ck_3630;
+		dpll4_m5_ck = dpll4_m5_ck_3630;
+		dpll4_m6_ck = dpll4_m6_ck_3630;
+
+		/*
+		 * For 3630: override clkops_omap2_dflt_wait for the
+		 * clocks affected from PWRDN reset Limitation
+		 */
+		dpll3_m3x2_ck.ops =
+				&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+		dpll4_m2x2_ck.ops =
+				&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+		dpll4_m3x2_ck.ops =
+				&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+		dpll4_m4x2_ck.ops =
+				&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+		dpll4_m5x2_ck.ops =
+				&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+		dpll4_m6x2_ck.ops =
+				&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+	} else {
+		/*
+		 * XXX This type of dynamic rewriting of the clock tree is
+		 * deprecated and should be revised soon.
+		 */
+		dpll4_m2_ck = dpll4_m2_ck_34xx;
+		dpll4_m3_ck = dpll4_m3_ck_34xx;
+		dpll4_m4_ck = dpll4_m4_ck_34xx;
+		dpll4_m5_ck = dpll4_m5_ck_34xx;
+		dpll4_m6_ck = dpll4_m6_ck_34xx;
+	}
+
+	if (cpu_is_omap3630())
+		dpll4_dd = dpll4_dd_3630;
+	else
+		dpll4_dd = dpll4_dd_34xx;
+
+	clk_init(&omap2_clk_functions);
+
+	for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks);
+	     c++)
+		clk_preinit(c->lk.clk);
+
+	for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks);
+	     c++)
+		if (c->cpu & cpu_clkflg) {
+			clkdev_add(&c->lk);
+			clk_register(c->lk.clk);
+			omap2_init_clk_clkdm(c->lk.clk);
+		}
+
+	recalculate_root_clocks();
+
+	printk(KERN_INFO "Clocking rate (Crystal/Core/MPU): "
+	       "%ld.%01ld/%ld/%ld MHz\n",
+	       (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10,
+	       (core_ck.rate / 1000000), (arm_fck.rate / 1000000));
+
+	/*
+	 * Only enable those clocks we will need, let the drivers
+	 * enable other clocks as necessary
+	 */
+	clk_enable_init_clocks();
+
+	/*
+	 * Lock DPLL5 and put it in autoidle.
+	 */
+	if (omap_rev() >= OMAP3430_REV_ES2_0)
+		omap3_clk_lock_dpll5();
+
+	/* Avoid sleeping during omap3_core_dpll_m2_set_rate() */
+	sdrc_ick_p = clk_get(NULL, "sdrc_ick");
+	arm_fck_p = clk_get(NULL, "arm_fck");
+
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock3xxx.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock3xxx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock3xxx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock3xxx.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ * OMAP3-common clock function prototypes and macros
+ *
+ * Copyright (C) 2007-2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H
+
+int omap3xxx_clk_init(void);
+int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
+int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
+void omap3_clk_lock_dpll5(void);
+
+extern struct clk *sdrc_ick_p;
+extern struct clk *arm_fck_p;
+
+extern const struct clkops clkops_noncore_dpll_ops;
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock44xx.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock44xx.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock44xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock44xx.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,33 +0,0 @@
-/*
- * OMAP4-specific clock framework functions
- *
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Rajendra Nayak (rnayak@ti.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/errno.h>
-#include "clock.h"
-
-struct clk_functions omap2_clk_functions = {
-	.clk_enable		= omap2_clk_enable,
-	.clk_disable		= omap2_clk_disable,
-	.clk_round_rate		= omap2_clk_round_rate,
-	.clk_set_rate		= omap2_clk_set_rate,
-	.clk_set_parent		= omap2_clk_set_parent,
-	.clk_disable_unused	= omap2_clk_disable_unused,
-};
-
-const struct clkops clkops_noncore_dpll_ops = {
-	.enable		= &omap3_noncore_dpll_enable,
-	.disable	= &omap3_noncore_dpll_disable,
-};
-
-void omap2_clk_prepare_for_reboot(void)
-{
-	return;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock44xx_data.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock44xx_data.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock44xx_data.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock44xx_data.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,8 +1,8 @@
 /*
  * OMAP4 Clock data
  *
- * Copyright (C) 2009 Texas Instruments, Inc.
- * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
  *
  * Paul Walmsley (paul@pwsan.com)
  * Rajendra Nayak (rnayak@ti.com)
@@ -20,7 +20,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/list.h>
 #include <linux/clk.h>
 
 #include <plat/control.h>
@@ -39,42 +39,36 @@ static struct clk extalt_clkin_ck = {
 	.name		= "extalt_clkin_ck",
 	.rate		= 59000000,
 	.ops		= &clkops_null,
-	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
 };
 
 static struct clk pad_clks_ck = {
 	.name		= "pad_clks_ck",
 	.rate		= 12000000,
 	.ops		= &clkops_null,
-	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
 };
 
 static struct clk pad_slimbus_core_clks_ck = {
 	.name		= "pad_slimbus_core_clks_ck",
 	.rate		= 12000000,
 	.ops		= &clkops_null,
-	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
 };
 
 static struct clk secure_32k_clk_src_ck = {
 	.name		= "secure_32k_clk_src_ck",
 	.rate		= 32768,
 	.ops		= &clkops_null,
-	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
 };
 
 static struct clk slimbus_clk = {
 	.name		= "slimbus_clk",
 	.rate		= 12000000,
 	.ops		= &clkops_null,
-	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
 };
 
 static struct clk sys_32k_ck = {
 	.name		= "sys_32k_ck",
 	.rate		= 32768,
 	.ops		= &clkops_null,
-	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
 };
 
 static struct clk virt_12000000_ck = {
@@ -179,35 +173,30 @@ static struct clk sys_clkin_ck = {
 	.clksel_mask	= OMAP4430_SYS_CLKSEL_MASK,
 	.ops		= &clkops_null,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
 };
 
 static struct clk utmi_phy_clkout_ck = {
 	.name		= "utmi_phy_clkout_ck",
 	.rate		= 12000000,
 	.ops		= &clkops_null,
-	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
 };
 
 static struct clk xclk60mhsp1_ck = {
 	.name		= "xclk60mhsp1_ck",
 	.rate		= 12000000,
 	.ops		= &clkops_null,
-	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
 };
 
 static struct clk xclk60mhsp2_ck = {
 	.name		= "xclk60mhsp2_ck",
 	.rate		= 12000000,
 	.ops		= &clkops_null,
-	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
 };
 
 static struct clk xclk60motg_ck = {
 	.name		= "xclk60motg_ck",
 	.rate		= 60000000,
 	.ops		= &clkops_null,
-	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
 };
 
 /* Module clocks and DPLL outputs */
@@ -233,7 +222,6 @@ static struct clk dpll_sys_ref_clk = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel abe_dpll_refclk_mux_sel[] = {
@@ -251,7 +239,6 @@ static struct clk abe_dpll_refclk_mux_ck
 	.clksel_mask	= OMAP4430_CLKSEL_0_0_MASK,
 	.ops		= &clkops_null,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 /* DPLL_ABE */
@@ -279,11 +266,10 @@ static struct clk dpll_abe_ck = {
 	.parent		= &abe_dpll_refclk_mux_ck,
 	.dpll_data	= &dpll_abe_dd,
 	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_noncore_dpll_ops,
+	.ops		= &clkops_omap3_noncore_dpll_ops,
 	.recalc		= &omap3_dpll_recalc,
 	.round_rate	= &omap2_dpll_round_rate,
 	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dpll_abe_m2x2_ck = {
@@ -291,7 +277,6 @@ static struct clk dpll_abe_m2x2_ck = {
 	.parent		= &dpll_abe_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk abe_24m_fclk = {
@@ -299,7 +284,6 @@ static struct clk abe_24m_fclk = {
 	.parent		= &dpll_abe_m2x2_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel_rate div3_1to4_rates[] = {
@@ -324,7 +308,6 @@ static struct clk abe_clk = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel aess_fclk_div[] = {
@@ -342,7 +325,6 @@ static struct clk aess_fclk = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel_rate div31_1to31_rates[] = {
@@ -395,7 +377,6 @@ static struct clk dpll_abe_m3_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel core_hsd_byp_clk_mux_sel[] = {
@@ -413,7 +394,6 @@ static struct clk core_hsd_byp_clk_mux_c
 	.clksel_mask	= OMAP4430_DPLL_BYP_CLKSEL_MASK,
 	.ops		= &clkops_null,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 /* DPLL_CORE */
@@ -443,7 +423,6 @@ static struct clk dpll_core_ck = {
 	.init		= &omap2_init_dpll_parent,
 	.ops		= &clkops_null,
 	.recalc		= &omap3_dpll_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel dpll_core_m6_div[] = {
@@ -461,7 +440,6 @@ static struct clk dpll_core_m6_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel dbgclk_mux_sel[] = {
@@ -475,7 +453,6 @@ static struct clk dbgclk_mux_ck = {
 	.parent		= &sys_clkin_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dpll_core_m2_ck = {
@@ -488,7 +465,6 @@ static struct clk dpll_core_m2_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk ddrphy_ck = {
@@ -496,7 +472,6 @@ static struct clk ddrphy_ck = {
 	.parent		= &dpll_core_m2_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dpll_core_m5_ck = {
@@ -509,7 +484,6 @@ static struct clk dpll_core_m5_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel div_core_div[] = {
@@ -527,7 +501,6 @@ static struct clk div_core_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel_rate div4_1to8_rates[] = {
@@ -553,7 +526,6 @@ static struct clk div_iva_hs_clk = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk div_mpu_hs_clk = {
@@ -566,7 +538,6 @@ static struct clk div_mpu_hs_clk = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dpll_core_m4_ck = {
@@ -579,7 +550,6 @@ static struct clk dpll_core_m4_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dll_clk_div_ck = {
@@ -587,7 +557,6 @@ static struct clk dll_clk_div_ck = {
 	.parent		= &dpll_core_m4_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dpll_abe_m2_ck = {
@@ -600,7 +569,6 @@ static struct clk dpll_abe_m2_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dpll_core_m3_ck = {
@@ -613,7 +581,6 @@ static struct clk dpll_core_m3_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dpll_core_m7_ck = {
@@ -626,7 +593,6 @@ static struct clk dpll_core_m7_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel iva_hsd_byp_clk_mux_sel[] = {
@@ -640,7 +606,6 @@ static struct clk iva_hsd_byp_clk_mux_ck
 	.parent		= &dpll_sys_ref_clk,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 /* DPLL_IVA */
@@ -668,11 +633,10 @@ static struct clk dpll_iva_ck = {
 	.parent		= &dpll_sys_ref_clk,
 	.dpll_data	= &dpll_iva_dd,
 	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_noncore_dpll_ops,
+	.ops		= &clkops_omap3_noncore_dpll_ops,
 	.recalc		= &omap3_dpll_recalc,
 	.round_rate	= &omap2_dpll_round_rate,
 	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel dpll_iva_m4_div[] = {
@@ -690,7 +654,6 @@ static struct clk dpll_iva_m4_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dpll_iva_m5_ck = {
@@ -703,7 +666,6 @@ static struct clk dpll_iva_m5_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 /* DPLL_MPU */
@@ -731,11 +693,10 @@ static struct clk dpll_mpu_ck = {
 	.parent		= &dpll_sys_ref_clk,
 	.dpll_data	= &dpll_mpu_dd,
 	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_noncore_dpll_ops,
+	.ops		= &clkops_omap3_noncore_dpll_ops,
 	.recalc		= &omap3_dpll_recalc,
 	.round_rate	= &omap2_dpll_round_rate,
 	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel dpll_mpu_m2_div[] = {
@@ -753,7 +714,6 @@ static struct clk dpll_mpu_m2_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk per_hs_clk_div_ck = {
@@ -761,7 +721,6 @@ static struct clk per_hs_clk_div_ck = {
 	.parent		= &dpll_abe_m3_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel per_hsd_byp_clk_mux_sel[] = {
@@ -779,7 +738,6 @@ static struct clk per_hsd_byp_clk_mux_ck
 	.clksel_mask	= OMAP4430_DPLL_BYP_CLKSEL_MASK,
 	.ops		= &clkops_null,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 /* DPLL_PER */
@@ -807,11 +765,10 @@ static struct clk dpll_per_ck = {
 	.parent		= &dpll_sys_ref_clk,
 	.dpll_data	= &dpll_per_dd,
 	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_noncore_dpll_ops,
+	.ops		= &clkops_omap3_noncore_dpll_ops,
 	.recalc		= &omap3_dpll_recalc,
 	.round_rate	= &omap2_dpll_round_rate,
 	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel dpll_per_m2_div[] = {
@@ -829,7 +786,6 @@ static struct clk dpll_per_m2_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dpll_per_m2x2_ck = {
@@ -837,7 +793,6 @@ static struct clk dpll_per_m2x2_ck = {
 	.parent		= &dpll_per_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dpll_per_m3_ck = {
@@ -850,7 +805,6 @@ static struct clk dpll_per_m3_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dpll_per_m4_ck = {
@@ -863,7 +817,6 @@ static struct clk dpll_per_m4_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dpll_per_m5_ck = {
@@ -876,7 +829,6 @@ static struct clk dpll_per_m5_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dpll_per_m6_ck = {
@@ -889,7 +841,6 @@ static struct clk dpll_per_m6_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dpll_per_m7_ck = {
@@ -902,7 +853,6 @@ static struct clk dpll_per_m7_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 /* DPLL_UNIPRO */
@@ -930,11 +880,10 @@ static struct clk dpll_unipro_ck = {
 	.parent		= &dpll_sys_ref_clk,
 	.dpll_data	= &dpll_unipro_dd,
 	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_noncore_dpll_ops,
+	.ops		= &clkops_omap3_noncore_dpll_ops,
 	.recalc		= &omap3_dpll_recalc,
 	.round_rate	= &omap2_dpll_round_rate,
 	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel dpll_unipro_m2x2_div[] = {
@@ -952,7 +901,6 @@ static struct clk dpll_unipro_m2x2_ck =
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk usb_hs_clk_div_ck = {
@@ -960,7 +908,6 @@ static struct clk usb_hs_clk_div_ck = {
 	.parent		= &dpll_abe_m3_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 /* DPLL_USB */
@@ -980,6 +927,7 @@ static struct dpll_data dpll_usb_dd = {
 	.max_multiplier	= OMAP4430_MAX_DPLL_MULT,
 	.max_divider	= OMAP4430_MAX_DPLL_DIV,
 	.min_divider	= 1,
+	.flags		= DPLL_J_TYPE | DPLL_NO_DCO_SEL
 };
 
 
@@ -988,11 +936,10 @@ static struct clk dpll_usb_ck = {
 	.parent		= &dpll_sys_ref_clk,
 	.dpll_data	= &dpll_usb_dd,
 	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_noncore_dpll_ops,
+	.ops		= &clkops_omap3_noncore_dpll_ops,
 	.recalc		= &omap3_dpll_recalc,
 	.round_rate	= &omap2_dpll_round_rate,
 	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk dpll_usb_clkdcoldo_ck = {
@@ -1000,7 +947,6 @@ static struct clk dpll_usb_clkdcoldo_ck
 	.parent		= &dpll_usb_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel dpll_usb_m2_div[] = {
@@ -1018,7 +964,6 @@ static struct clk dpll_usb_m2_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel ducati_clk_mux_sel[] = {
@@ -1036,7 +981,6 @@ static struct clk ducati_clk_mux_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_0_0_MASK,
 	.ops		= &clkops_null,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk func_12m_fclk = {
@@ -1044,7 +988,6 @@ static struct clk func_12m_fclk = {
 	.parent		= &dpll_per_m2x2_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk func_24m_clk = {
@@ -1052,7 +995,6 @@ static struct clk func_24m_clk = {
 	.parent		= &dpll_per_m2_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk func_24mc_fclk = {
@@ -1060,7 +1002,6 @@ static struct clk func_24mc_fclk = {
 	.parent		= &dpll_per_m2x2_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel_rate div2_4to8_rates[] = {
@@ -1084,7 +1025,6 @@ static struct clk func_48m_fclk = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk func_48mc_fclk = {
@@ -1092,7 +1032,6 @@ static struct clk func_48mc_fclk = {
 	.parent		= &dpll_per_m2x2_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel_rate div2_2to4_rates[] = {
@@ -1116,7 +1055,6 @@ static struct clk func_64m_fclk = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel func_96m_fclk_div[] = {
@@ -1134,7 +1072,6 @@ static struct clk func_96m_fclk = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel hsmmc6_fclk_sel[] = {
@@ -1148,7 +1085,6 @@ static struct clk hsmmc6_fclk = {
 	.parent		= &func_64m_fclk,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel_rate div2_1to8_rates[] = {
@@ -1172,7 +1108,6 @@ static struct clk init_60m_fclk = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel l3_div_div[] = {
@@ -1190,7 +1125,6 @@ static struct clk l3_div_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel l4_div_div[] = {
@@ -1208,7 +1142,6 @@ static struct clk l4_div_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk lp_clk_div_ck = {
@@ -1216,7 +1149,6 @@ static struct clk lp_clk_div_ck = {
 	.parent		= &dpll_abe_m2x2_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel l4_wkup_clk_mux_sel[] = {
@@ -1234,7 +1166,6 @@ static struct clk l4_wkup_clk_mux_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_0_0_MASK,
 	.ops		= &clkops_null,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel per_abe_nc_fclk_div[] = {
@@ -1252,7 +1183,6 @@ static struct clk per_abe_nc_fclk = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel mcasp2_fclk_sel[] = {
@@ -1266,7 +1196,6 @@ static struct clk mcasp2_fclk = {
 	.parent		= &func_96m_fclk,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk mcasp3_fclk = {
@@ -1274,7 +1203,6 @@ static struct clk mcasp3_fclk = {
 	.parent		= &func_96m_fclk,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk ocp_abe_iclk = {
@@ -1282,7 +1210,6 @@ static struct clk ocp_abe_iclk = {
 	.parent		= &aess_fclk,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk per_abe_24m_fclk = {
@@ -1290,7 +1217,6 @@ static struct clk per_abe_24m_fclk = {
 	.parent		= &dpll_abe_m2_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel pmd_stm_clock_mux_sel[] = {
@@ -1305,7 +1231,6 @@ static struct clk pmd_stm_clock_mux_ck =
 	.parent		= &sys_clkin_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk pmd_trace_clk_mux_ck = {
@@ -1313,7 +1238,6 @@ static struct clk pmd_trace_clk_mux_ck =
 	.parent		= &sys_clkin_ck,
 	.ops		= &clkops_null,
 	.recalc		= &followparent_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static struct clk syc_clk_div_ck = {
@@ -1326,13 +1250,12 @@ static struct clk syc_clk_div_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 /* Leaf clocks controlled by modules */
 
-static struct clk aes1_ck = {
-	.name		= "aes1_ck",
+static struct clk aes1_fck = {
+	.name		= "aes1_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4SEC_AES1_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -1341,8 +1264,8 @@ static struct clk aes1_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk aes2_ck = {
-	.name		= "aes2_ck",
+static struct clk aes2_fck = {
+	.name		= "aes2_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4SEC_AES2_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -1351,8 +1274,8 @@ static struct clk aes2_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk aess_ck = {
-	.name		= "aess_ck",
+static struct clk aess_fck = {
+	.name		= "aess_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM1_ABE_AESS_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -1361,8 +1284,8 @@ static struct clk aess_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk cust_efuse_ck = {
-	.name		= "cust_efuse_ck",
+static struct clk cust_efuse_fck = {
+	.name		= "cust_efuse_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -1371,8 +1294,8 @@ static struct clk cust_efuse_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk des3des_ck = {
-	.name		= "des3des_ck",
+static struct clk des3des_fck = {
+	.name		= "des3des_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4SEC_DES3DES_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -1397,7 +1320,6 @@ static struct clk dmic_sync_mux_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
 	.ops		= &clkops_null,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel func_dmic_abe_gfclk_sel[] = {
@@ -1407,9 +1329,9 @@ static const struct clksel func_dmic_abe
 	{ .parent = NULL },
 };
 
-/* Merged func_dmic_abe_gfclk into dmic_ck */
-static struct clk dmic_ck = {
-	.name		= "dmic_ck",
+/* Merged func_dmic_abe_gfclk into dmic */
+static struct clk dmic_fck = {
+	.name		= "dmic_fck",
 	.parent		= &dmic_sync_mux_ck,
 	.clksel		= func_dmic_abe_gfclk_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1417,14 +1339,13 @@ static struct clk dmic_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM1_ABE_DMIC_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "abe_clkdm",
 };
 
-static struct clk dss_ck = {
-	.name		= "dss_ck",
+static struct clk dss_fck = {
+	.name		= "dss_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_DSS_DSS_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -1433,8 +1354,8 @@ static struct clk dss_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk ducati_ck = {
-	.name		= "ducati_ck",
+static struct clk ducati_ick = {
+	.name		= "ducati_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_DUCATI_DUCATI_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -1443,8 +1364,8 @@ static struct clk ducati_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk emif1_ck = {
-	.name		= "emif1_ck",
+static struct clk emif1_ick = {
+	.name		= "emif1_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -1453,8 +1374,8 @@ static struct clk emif1_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk emif2_ck = {
-	.name		= "emif2_ck",
+static struct clk emif2_ick = {
+	.name		= "emif2_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -1468,9 +1389,9 @@ static const struct clksel fdif_fclk_div
 	{ .parent = NULL },
 };
 
-/* Merged fdif_fclk into fdif_ck */
-static struct clk fdif_ck = {
-	.name		= "fdif_ck",
+/* Merged fdif_fclk into fdif */
+static struct clk fdif_fck = {
+	.name		= "fdif_fck",
 	.parent		= &dpll_per_m4_ck,
 	.clksel		= fdif_fclk_div,
 	.clksel_reg	= OMAP4430_CM_CAM_FDIF_CLKCTRL,
@@ -1479,7 +1400,6 @@ static struct clk fdif_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM_CAM_FDIF_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "iss_clkdm",
@@ -1500,7 +1420,6 @@ static struct clk per_sgx_fclk = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel sgx_clk_mux_sel[] = {
@@ -1509,9 +1428,9 @@ static const struct clksel sgx_clk_mux_s
 	{ .parent = NULL },
 };
 
-/* Merged sgx_clk_mux into gfx_ck */
-static struct clk gfx_ck = {
-	.name		= "gfx_ck",
+/* Merged sgx_clk_mux into gfx */
+static struct clk gfx_fck = {
+	.name		= "gfx_fck",
 	.parent		= &dpll_core_m7_ck,
 	.clksel		= sgx_clk_mux_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1519,14 +1438,13 @@ static struct clk gfx_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_SGX_FCLK_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM_GFX_GFX_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "l3_gfx_clkdm",
 };
 
-static struct clk gpio1_ck = {
-	.name		= "gpio1_ck",
+static struct clk gpio1_ick = {
+	.name		= "gpio1_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -1535,8 +1453,8 @@ static struct clk gpio1_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk gpio2_ck = {
-	.name		= "gpio2_ck",
+static struct clk gpio2_ick = {
+	.name		= "gpio2_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_GPIO2_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -1545,8 +1463,8 @@ static struct clk gpio2_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk gpio3_ck = {
-	.name		= "gpio3_ck",
+static struct clk gpio3_ick = {
+	.name		= "gpio3_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -1555,8 +1473,8 @@ static struct clk gpio3_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk gpio4_ck = {
-	.name		= "gpio4_ck",
+static struct clk gpio4_ick = {
+	.name		= "gpio4_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_GPIO4_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -1565,8 +1483,8 @@ static struct clk gpio4_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk gpio5_ck = {
-	.name		= "gpio5_ck",
+static struct clk gpio5_ick = {
+	.name		= "gpio5_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_GPIO5_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -1575,8 +1493,8 @@ static struct clk gpio5_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk gpio6_ck = {
-	.name		= "gpio6_ck",
+static struct clk gpio6_ick = {
+	.name		= "gpio6_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_GPIO6_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -1585,8 +1503,8 @@ static struct clk gpio6_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk gpmc_ck = {
-	.name		= "gpmc_ck",
+static struct clk gpmc_ick = {
+	.name		= "gpmc_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L3_2_GPMC_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -1601,9 +1519,12 @@ static const struct clksel dmt1_clk_mux_
 	{ .parent = NULL },
 };
 
-/* Merged dmt1_clk_mux into gptimer1_ck */
-static struct clk gptimer1_ck = {
-	.name		= "gptimer1_ck",
+/*
+ * Merged dmt1_clk_mux into gptimer1
+ * gptimer1 renamed temporarily into gpt1 to match OMAP3 convention
+ */
+static struct clk gpt1_fck = {
+	.name		= "gpt1_fck",
 	.parent		= &sys_clkin_ck,
 	.clksel		= dmt1_clk_mux_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1611,15 +1532,17 @@ static struct clk gptimer1_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "l4_wkup_clkdm",
 };
 
-/* Merged cm2_dm10_mux into gptimer10_ck */
-static struct clk gptimer10_ck = {
-	.name		= "gptimer10_ck",
+/*
+ * Merged cm2_dm10_mux into gptimer10
+ * gptimer10 renamed temporarily into gpt10 to match OMAP3 convention
+ */
+static struct clk gpt10_fck = {
+	.name		= "gpt10_fck",
 	.parent		= &sys_clkin_ck,
 	.clksel		= dmt1_clk_mux_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1627,15 +1550,17 @@ static struct clk gptimer10_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "l4_per_clkdm",
 };
 
-/* Merged cm2_dm11_mux into gptimer11_ck */
-static struct clk gptimer11_ck = {
-	.name		= "gptimer11_ck",
+/*
+ * Merged cm2_dm11_mux into gptimer11
+ * gptimer11 renamed temporarily into gpt11 to match OMAP3 convention
+ */
+static struct clk gpt11_fck = {
+	.name		= "gpt11_fck",
 	.parent		= &sys_clkin_ck,
 	.clksel		= dmt1_clk_mux_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1643,15 +1568,17 @@ static struct clk gptimer11_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "l4_per_clkdm",
 };
 
-/* Merged cm2_dm2_mux into gptimer2_ck */
-static struct clk gptimer2_ck = {
-	.name		= "gptimer2_ck",
+/*
+ * Merged cm2_dm2_mux into gptimer2
+ * gptimer2 renamed temporarily into gpt2 to match OMAP3 convention
+ */
+static struct clk gpt2_fck = {
+	.name		= "gpt2_fck",
 	.parent		= &sys_clkin_ck,
 	.clksel		= dmt1_clk_mux_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1659,15 +1586,17 @@ static struct clk gptimer2_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "l4_per_clkdm",
 };
 
-/* Merged cm2_dm3_mux into gptimer3_ck */
-static struct clk gptimer3_ck = {
-	.name		= "gptimer3_ck",
+/*
+ * Merged cm2_dm3_mux into gptimer3
+ * gptimer3 renamed temporarily into gpt3 to match OMAP3 convention
+ */
+static struct clk gpt3_fck = {
+	.name		= "gpt3_fck",
 	.parent		= &sys_clkin_ck,
 	.clksel		= dmt1_clk_mux_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1675,15 +1604,17 @@ static struct clk gptimer3_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "l4_per_clkdm",
 };
 
-/* Merged cm2_dm4_mux into gptimer4_ck */
-static struct clk gptimer4_ck = {
-	.name		= "gptimer4_ck",
+/*
+ * Merged cm2_dm4_mux into gptimer4
+ * gptimer4 renamed temporarily into gpt4 to match OMAP3 convention
+ */
+static struct clk gpt4_fck = {
+	.name		= "gpt4_fck",
 	.parent		= &sys_clkin_ck,
 	.clksel		= dmt1_clk_mux_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1691,7 +1622,6 @@ static struct clk gptimer4_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "l4_per_clkdm",
@@ -1703,9 +1633,12 @@ static const struct clksel timer5_sync_m
 	{ .parent = NULL },
 };
 
-/* Merged timer5_sync_mux into gptimer5_ck */
-static struct clk gptimer5_ck = {
-	.name		= "gptimer5_ck",
+/*
+ * Merged timer5_sync_mux into gptimer5
+ * gptimer5 renamed temporarily into gpt5 to match OMAP3 convention
+ */
+static struct clk gpt5_fck = {
+	.name		= "gpt5_fck",
 	.parent		= &syc_clk_div_ck,
 	.clksel		= timer5_sync_mux_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1713,15 +1646,17 @@ static struct clk gptimer5_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "abe_clkdm",
 };
 
-/* Merged timer6_sync_mux into gptimer6_ck */
-static struct clk gptimer6_ck = {
-	.name		= "gptimer6_ck",
+/*
+ * Merged timer6_sync_mux into gptimer6
+ * gptimer6 renamed temporarily into gpt6 to match OMAP3 convention
+ */
+static struct clk gpt6_fck = {
+	.name		= "gpt6_fck",
 	.parent		= &syc_clk_div_ck,
 	.clksel		= timer5_sync_mux_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1729,15 +1664,17 @@ static struct clk gptimer6_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "abe_clkdm",
 };
 
-/* Merged timer7_sync_mux into gptimer7_ck */
-static struct clk gptimer7_ck = {
-	.name		= "gptimer7_ck",
+/*
+ * Merged timer7_sync_mux into gptimer7
+ * gptimer7 renamed temporarily into gpt7 to match OMAP3 convention
+ */
+static struct clk gpt7_fck = {
+	.name		= "gpt7_fck",
 	.parent		= &syc_clk_div_ck,
 	.clksel		= timer5_sync_mux_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1745,15 +1682,17 @@ static struct clk gptimer7_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "abe_clkdm",
 };
 
-/* Merged timer8_sync_mux into gptimer8_ck */
-static struct clk gptimer8_ck = {
-	.name		= "gptimer8_ck",
+/*
+ * Merged timer8_sync_mux into gptimer8
+ * gptimer8 renamed temporarily into gpt8 to match OMAP3 convention
+ */
+static struct clk gpt8_fck = {
+	.name		= "gpt8_fck",
 	.parent		= &syc_clk_div_ck,
 	.clksel		= timer5_sync_mux_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1761,15 +1700,17 @@ static struct clk gptimer8_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "abe_clkdm",
 };
 
-/* Merged cm2_dm9_mux into gptimer9_ck */
-static struct clk gptimer9_ck = {
-	.name		= "gptimer9_ck",
+/*
+ * Merged cm2_dm9_mux into gptimer9
+ * gptimer9 renamed temporarily into gpt9 to match OMAP3 convention
+ */
+static struct clk gpt9_fck = {
+	.name		= "gpt9_fck",
 	.parent		= &sys_clkin_ck,
 	.clksel		= dmt1_clk_mux_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1777,14 +1718,13 @@ static struct clk gptimer9_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "l4_per_clkdm",
 };
 
-static struct clk hdq1w_ck = {
-	.name		= "hdq1w_ck",
+static struct clk hdq1w_fck = {
+	.name		= "hdq1w_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_HDQ1W_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -1793,9 +1733,9 @@ static struct clk hdq1w_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-/* Merged hsi_fclk into hsi_ck */
-static struct clk hsi_ck = {
-	.name		= "hsi_ck",
+/* Merged hsi_fclk into hsi */
+static struct clk hsi_ick = {
+	.name		= "hsi_ick",
 	.parent		= &dpll_per_m2x2_ck,
 	.clksel		= per_sgx_fclk_div,
 	.clksel_reg	= OMAP4430_CM_L3INIT_HSI_CLKCTRL,
@@ -1804,14 +1744,13 @@ static struct clk hsi_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM_L3INIT_HSI_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
 	.clkdm_name	= "l3_init_clkdm",
 };
 
-static struct clk i2c1_ck = {
-	.name		= "i2c1_ck",
+static struct clk i2c1_fck = {
+	.name		= "i2c1_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_I2C1_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -1820,8 +1759,8 @@ static struct clk i2c1_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk i2c2_ck = {
-	.name		= "i2c2_ck",
+static struct clk i2c2_fck = {
+	.name		= "i2c2_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_I2C2_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -1830,8 +1769,8 @@ static struct clk i2c2_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk i2c3_ck = {
-	.name		= "i2c3_ck",
+static struct clk i2c3_fck = {
+	.name		= "i2c3_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_I2C3_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -1840,8 +1779,8 @@ static struct clk i2c3_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk i2c4_ck = {
-	.name		= "i2c4_ck",
+static struct clk i2c4_fck = {
+	.name		= "i2c4_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_I2C4_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -1850,8 +1789,8 @@ static struct clk i2c4_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk iss_ck = {
-	.name		= "iss_ck",
+static struct clk iss_fck = {
+	.name		= "iss_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_CAM_ISS_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -1860,8 +1799,8 @@ static struct clk iss_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk ivahd_ck = {
-	.name		= "ivahd_ck",
+static struct clk ivahd_ick = {
+	.name		= "ivahd_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_IVAHD_IVAHD_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -1870,8 +1809,8 @@ static struct clk ivahd_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk keyboard_ck = {
-	.name		= "keyboard_ck",
+static struct clk keyboard_fck = {
+	.name		= "keyboard_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -1880,8 +1819,8 @@ static struct clk keyboard_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk l3_instr_interconnect_ck = {
-	.name		= "l3_instr_interconnect_ck",
+static struct clk l3_instr_interconnect_ick = {
+	.name		= "l3_instr_interconnect_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -1890,8 +1829,8 @@ static struct clk l3_instr_interconnect_
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk l3_interconnect_3_ck = {
-	.name		= "l3_interconnect_3_ck",
+static struct clk l3_interconnect_3_ick = {
+	.name		= "l3_interconnect_3_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L3INSTR_L3_3_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -1909,7 +1848,6 @@ static struct clk mcasp_sync_mux_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
 	.ops		= &clkops_null,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel func_mcasp_abe_gfclk_sel[] = {
@@ -1919,9 +1857,9 @@ static const struct clksel func_mcasp_ab
 	{ .parent = NULL },
 };
 
-/* Merged func_mcasp_abe_gfclk into mcasp_ck */
-static struct clk mcasp_ck = {
-	.name		= "mcasp_ck",
+/* Merged func_mcasp_abe_gfclk into mcasp */
+static struct clk mcasp_fck = {
+	.name		= "mcasp_fck",
 	.parent		= &mcasp_sync_mux_ck,
 	.clksel		= func_mcasp_abe_gfclk_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1929,7 +1867,6 @@ static struct clk mcasp_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM1_ABE_MCASP_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "abe_clkdm",
@@ -1944,7 +1881,6 @@ static struct clk mcbsp1_sync_mux_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
 	.ops		= &clkops_null,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel func_mcbsp1_gfclk_sel[] = {
@@ -1954,9 +1890,9 @@ static const struct clksel func_mcbsp1_g
 	{ .parent = NULL },
 };
 
-/* Merged func_mcbsp1_gfclk into mcbsp1_ck */
-static struct clk mcbsp1_ck = {
-	.name		= "mcbsp1_ck",
+/* Merged func_mcbsp1_gfclk into mcbsp1 */
+static struct clk mcbsp1_fck = {
+	.name		= "mcbsp1_fck",
 	.parent		= &mcbsp1_sync_mux_ck,
 	.clksel		= func_mcbsp1_gfclk_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1964,7 +1900,6 @@ static struct clk mcbsp1_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "abe_clkdm",
@@ -1979,7 +1914,6 @@ static struct clk mcbsp2_sync_mux_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
 	.ops		= &clkops_null,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel func_mcbsp2_gfclk_sel[] = {
@@ -1989,9 +1923,9 @@ static const struct clksel func_mcbsp2_g
 	{ .parent = NULL },
 };
 
-/* Merged func_mcbsp2_gfclk into mcbsp2_ck */
-static struct clk mcbsp2_ck = {
-	.name		= "mcbsp2_ck",
+/* Merged func_mcbsp2_gfclk into mcbsp2 */
+static struct clk mcbsp2_fck = {
+	.name		= "mcbsp2_fck",
 	.parent		= &mcbsp2_sync_mux_ck,
 	.clksel		= func_mcbsp2_gfclk_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -1999,7 +1933,6 @@ static struct clk mcbsp2_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "abe_clkdm",
@@ -2014,7 +1947,6 @@ static struct clk mcbsp3_sync_mux_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
 	.ops		= &clkops_null,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel func_mcbsp3_gfclk_sel[] = {
@@ -2024,9 +1956,9 @@ static const struct clksel func_mcbsp3_g
 	{ .parent = NULL },
 };
 
-/* Merged func_mcbsp3_gfclk into mcbsp3_ck */
-static struct clk mcbsp3_ck = {
-	.name		= "mcbsp3_ck",
+/* Merged func_mcbsp3_gfclk into mcbsp3 */
+static struct clk mcbsp3_fck = {
+	.name		= "mcbsp3_fck",
 	.parent		= &mcbsp3_sync_mux_ck,
 	.clksel		= func_mcbsp3_gfclk_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -2034,7 +1966,6 @@ static struct clk mcbsp3_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "abe_clkdm",
@@ -2049,7 +1980,6 @@ static struct clk mcbsp4_sync_mux_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
 	.ops		= &clkops_null,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel per_mcbsp4_gfclk_sel[] = {
@@ -2058,9 +1988,9 @@ static const struct clksel per_mcbsp4_gf
 	{ .parent = NULL },
 };
 
-/* Merged per_mcbsp4_gfclk into mcbsp4_ck */
-static struct clk mcbsp4_ck = {
-	.name		= "mcbsp4_ck",
+/* Merged per_mcbsp4_gfclk into mcbsp4 */
+static struct clk mcbsp4_fck = {
+	.name		= "mcbsp4_fck",
 	.parent		= &mcbsp4_sync_mux_ck,
 	.clksel		= per_mcbsp4_gfclk_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -2068,14 +1998,13 @@ static struct clk mcbsp4_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_24_24_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "l4_per_clkdm",
 };
 
-static struct clk mcspi1_ck = {
-	.name		= "mcspi1_ck",
+static struct clk mcspi1_fck = {
+	.name		= "mcspi1_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_MCSPI1_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2084,8 +2013,8 @@ static struct clk mcspi1_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk mcspi2_ck = {
-	.name		= "mcspi2_ck",
+static struct clk mcspi2_fck = {
+	.name		= "mcspi2_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_MCSPI2_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2094,8 +2023,8 @@ static struct clk mcspi2_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk mcspi3_ck = {
-	.name		= "mcspi3_ck",
+static struct clk mcspi3_fck = {
+	.name		= "mcspi3_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_MCSPI3_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2104,8 +2033,8 @@ static struct clk mcspi3_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk mcspi4_ck = {
-	.name		= "mcspi4_ck",
+static struct clk mcspi4_fck = {
+	.name		= "mcspi4_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_MCSPI4_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2114,9 +2043,9 @@ static struct clk mcspi4_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-/* Merged hsmmc1_fclk into mmc1_ck */
-static struct clk mmc1_ck = {
-	.name		= "mmc1_ck",
+/* Merged hsmmc1_fclk into mmc1 */
+static struct clk mmc1_fck = {
+	.name		= "mmc1_fck",
 	.parent		= &func_64m_fclk,
 	.clksel		= hsmmc6_fclk_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -2124,15 +2053,14 @@ static struct clk mmc1_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM_L3INIT_MMC1_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "l3_init_clkdm",
 };
 
-/* Merged hsmmc2_fclk into mmc2_ck */
-static struct clk mmc2_ck = {
-	.name		= "mmc2_ck",
+/* Merged hsmmc2_fclk into mmc2 */
+static struct clk mmc2_fck = {
+	.name		= "mmc2_fck",
 	.parent		= &func_64m_fclk,
 	.clksel		= hsmmc6_fclk_sel,
 	.init		= &omap2_init_clksel_parent,
@@ -2140,14 +2068,13 @@ static struct clk mmc2_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_MASK,
 	.ops		= &clkops_omap2_dflt,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 	.enable_reg	= OMAP4430_CM_L3INIT_MMC2_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
 	.clkdm_name	= "l3_init_clkdm",
 };
 
-static struct clk mmc3_ck = {
-	.name		= "mmc3_ck",
+static struct clk mmc3_fck = {
+	.name		= "mmc3_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_MMCSD3_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2156,8 +2083,8 @@ static struct clk mmc3_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk mmc4_ck = {
-	.name		= "mmc4_ck",
+static struct clk mmc4_fck = {
+	.name		= "mmc4_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_MMCSD4_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2166,8 +2093,8 @@ static struct clk mmc4_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk mmc5_ck = {
-	.name		= "mmc5_ck",
+static struct clk mmc5_fck = {
+	.name		= "mmc5_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_MMCSD5_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2176,8 +2103,8 @@ static struct clk mmc5_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk ocp_wp1_ck = {
-	.name		= "ocp_wp1_ck",
+static struct clk ocp_wp1_ick = {
+	.name		= "ocp_wp1_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -2186,8 +2113,8 @@ static struct clk ocp_wp1_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk pdm_ck = {
-	.name		= "pdm_ck",
+static struct clk pdm_fck = {
+	.name		= "pdm_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM1_ABE_PDM_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2196,8 +2123,8 @@ static struct clk pdm_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk pkaeip29_ck = {
-	.name		= "pkaeip29_ck",
+static struct clk pkaeip29_fck = {
+	.name		= "pkaeip29_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2206,8 +2133,8 @@ static struct clk pkaeip29_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk rng_ck = {
-	.name		= "rng_ck",
+static struct clk rng_ick = {
+	.name		= "rng_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4SEC_RNG_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -2216,8 +2143,8 @@ static struct clk rng_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk sha2md51_ck = {
-	.name		= "sha2md51_ck",
+static struct clk sha2md51_fck = {
+	.name		= "sha2md51_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2226,8 +2153,8 @@ static struct clk sha2md51_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk sl2_ck = {
-	.name		= "sl2_ck",
+static struct clk sl2_ick = {
+	.name		= "sl2_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_IVAHD_SL2_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -2236,8 +2163,8 @@ static struct clk sl2_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk slimbus1_ck = {
-	.name		= "slimbus1_ck",
+static struct clk slimbus1_fck = {
+	.name		= "slimbus1_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2246,8 +2173,8 @@ static struct clk slimbus1_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk slimbus2_ck = {
-	.name		= "slimbus2_ck",
+static struct clk slimbus2_fck = {
+	.name		= "slimbus2_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2256,8 +2183,8 @@ static struct clk slimbus2_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk sr_core_ck = {
-	.name		= "sr_core_ck",
+static struct clk sr_core_fck = {
+	.name		= "sr_core_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2266,8 +2193,8 @@ static struct clk sr_core_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk sr_iva_ck = {
-	.name		= "sr_iva_ck",
+static struct clk sr_iva_fck = {
+	.name		= "sr_iva_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_ALWON_SR_IVA_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2276,8 +2203,8 @@ static struct clk sr_iva_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk sr_mpu_ck = {
-	.name		= "sr_mpu_ck",
+static struct clk sr_mpu_fck = {
+	.name		= "sr_mpu_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_ALWON_SR_MPU_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2286,8 +2213,8 @@ static struct clk sr_mpu_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk tesla_ck = {
-	.name		= "tesla_ck",
+static struct clk tesla_ick = {
+	.name		= "tesla_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_TESLA_TESLA_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -2296,8 +2223,8 @@ static struct clk tesla_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk uart1_ck = {
-	.name		= "uart1_ck",
+static struct clk uart1_fck = {
+	.name		= "uart1_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_UART1_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2306,8 +2233,8 @@ static struct clk uart1_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk uart2_ck = {
-	.name		= "uart2_ck",
+static struct clk uart2_fck = {
+	.name		= "uart2_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_UART2_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2316,8 +2243,8 @@ static struct clk uart2_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk uart3_ck = {
-	.name		= "uart3_ck",
+static struct clk uart3_fck = {
+	.name		= "uart3_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_UART3_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2326,8 +2253,8 @@ static struct clk uart3_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk uart4_ck = {
-	.name		= "uart4_ck",
+static struct clk uart4_fck = {
+	.name		= "uart4_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L4PER_UART4_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2336,8 +2263,8 @@ static struct clk uart4_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk unipro1_ck = {
-	.name		= "unipro1_ck",
+static struct clk unipro1_fck = {
+	.name		= "unipro1_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L3INIT_UNIPRO1_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2346,8 +2273,8 @@ static struct clk unipro1_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk usb_host_ck = {
-	.name		= "usb_host_ck",
+static struct clk usb_host_fck = {
+	.name		= "usb_host_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2356,8 +2283,8 @@ static struct clk usb_host_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk usb_host_fs_ck = {
-	.name		= "usb_host_fs_ck",
+static struct clk usb_host_fs_fck = {
+	.name		= "usb_host_fs_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L3INIT_USB_HOST_FS_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2366,8 +2293,8 @@ static struct clk usb_host_fs_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk usb_otg_ck = {
-	.name		= "usb_otg_ck",
+static struct clk usb_otg_ick = {
+	.name		= "usb_otg_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -2376,8 +2303,8 @@ static struct clk usb_otg_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk usb_tll_ck = {
-	.name		= "usb_tll_ck",
+static struct clk usb_tll_ick = {
+	.name		= "usb_tll_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -2386,8 +2313,8 @@ static struct clk usb_tll_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk usbphyocp2scp_ck = {
-	.name		= "usbphyocp2scp_ck",
+static struct clk usbphyocp2scp_ick = {
+	.name		= "usbphyocp2scp_ick",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
@@ -2396,8 +2323,8 @@ static struct clk usbphyocp2scp_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk usim_ck = {
-	.name		= "usim_ck",
+static struct clk usim_fck = {
+	.name		= "usim_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_WKUP_USIM_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2406,8 +2333,8 @@ static struct clk usim_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk wdt2_ck = {
-	.name		= "wdt2_ck",
+static struct clk wdt2_fck = {
+	.name		= "wdt2_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM_WKUP_WDT2_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2416,8 +2343,8 @@ static struct clk wdt2_ck = {
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk wdt3_ck = {
-	.name		= "wdt3_ck",
+static struct clk wdt3_fck = {
+	.name		= "wdt3_fck",
 	.ops		= &clkops_omap2_dflt,
 	.enable_reg	= OMAP4430_CM1_ABE_WDT3_CLKCTRL,
 	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
@@ -2442,7 +2369,6 @@ static struct clk otg_60m_gfclk_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_60M_MASK,
 	.ops		= &clkops_null,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel stm_clk_div_div[] = {
@@ -2460,7 +2386,6 @@ static struct clk stm_clk_div_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel trace_clk_div_div[] = {
@@ -2478,7 +2403,6 @@ static struct clk trace_clk_div_ck = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel_rate div2_14to18_rates[] = {
@@ -2502,7 +2426,6 @@ static struct clk usim_fclk = {
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel utmi_p1_gfclk_sel[] = {
@@ -2520,7 +2443,6 @@ static struct clk utmi_p1_gfclk_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_UTMI_P1_MASK,
 	.ops		= &clkops_null,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 static const struct clksel utmi_p2_gfclk_sel[] = {
@@ -2538,7 +2460,6 @@ static struct clk utmi_p2_gfclk_ck = {
 	.clksel_mask	= OMAP4430_CLKSEL_UTMI_P2_MASK,
 	.ops		= &clkops_null,
 	.recalc		= &omap2_clksel_recalc,
-	.flags		= CLOCK_IN_OMAP4430,
 };
 
 /*
@@ -2631,106 +2552,139 @@ static struct omap_clk omap44xx_clks[] =
 	CLK(NULL,	"pmd_stm_clock_mux_ck",		&pmd_stm_clock_mux_ck,	CK_443X),
 	CLK(NULL,	"pmd_trace_clk_mux_ck",		&pmd_trace_clk_mux_ck,	CK_443X),
 	CLK(NULL,	"syc_clk_div_ck",		&syc_clk_div_ck,	CK_443X),
-	CLK(NULL,	"aes1_ck",			&aes1_ck,	CK_443X),
-	CLK(NULL,	"aes2_ck",			&aes2_ck,	CK_443X),
-	CLK(NULL,	"aess_ck",			&aess_ck,	CK_443X),
-	CLK(NULL,	"cust_efuse_ck",		&cust_efuse_ck,	CK_443X),
-	CLK(NULL,	"des3des_ck",			&des3des_ck,	CK_443X),
+	CLK(NULL,	"aes1_fck",			&aes1_fck,	CK_443X),
+	CLK(NULL,	"aes2_fck",			&aes2_fck,	CK_443X),
+	CLK(NULL,	"aess_fck",			&aess_fck,	CK_443X),
+	CLK(NULL,	"cust_efuse_fck",		&cust_efuse_fck,	CK_443X),
+	CLK(NULL,	"des3des_fck",			&des3des_fck,	CK_443X),
 	CLK(NULL,	"dmic_sync_mux_ck",		&dmic_sync_mux_ck,	CK_443X),
-	CLK(NULL,	"dmic_ck",			&dmic_ck,	CK_443X),
-	CLK(NULL,	"dss_ck",			&dss_ck,	CK_443X),
-	CLK(NULL,	"ducati_ck",			&ducati_ck,	CK_443X),
-	CLK(NULL,	"emif1_ck",			&emif1_ck,	CK_443X),
-	CLK(NULL,	"emif2_ck",			&emif2_ck,	CK_443X),
-	CLK(NULL,	"fdif_ck",			&fdif_ck,	CK_443X),
+	CLK(NULL,	"dmic_fck",			&dmic_fck,	CK_443X),
+	CLK(NULL,	"dss_fck",			&dss_fck,	CK_443X),
+	CLK(NULL,	"ducati_ick",			&ducati_ick,	CK_443X),
+	CLK(NULL,	"emif1_ick",			&emif1_ick,	CK_443X),
+	CLK(NULL,	"emif2_ick",			&emif2_ick,	CK_443X),
+	CLK(NULL,	"fdif_fck",			&fdif_fck,	CK_443X),
 	CLK(NULL,	"per_sgx_fclk",			&per_sgx_fclk,	CK_443X),
-	CLK(NULL,	"gfx_ck",			&gfx_ck,	CK_443X),
-	CLK(NULL,	"gpio1_ck",			&gpio1_ck,	CK_443X),
-	CLK(NULL,	"gpio2_ck",			&gpio2_ck,	CK_443X),
-	CLK(NULL,	"gpio3_ck",			&gpio3_ck,	CK_443X),
-	CLK(NULL,	"gpio4_ck",			&gpio4_ck,	CK_443X),
-	CLK(NULL,	"gpio5_ck",			&gpio5_ck,	CK_443X),
-	CLK(NULL,	"gpio6_ck",			&gpio6_ck,	CK_443X),
-	CLK(NULL,	"gpmc_ck",			&gpmc_ck,	CK_443X),
-	CLK(NULL,	"gptimer1_ck",			&gptimer1_ck,	CK_443X),
-	CLK(NULL,	"gptimer10_ck",			&gptimer10_ck,	CK_443X),
-	CLK(NULL,	"gptimer11_ck",			&gptimer11_ck,	CK_443X),
-	CLK(NULL,	"gptimer2_ck",			&gptimer2_ck,	CK_443X),
-	CLK(NULL,	"gptimer3_ck",			&gptimer3_ck,	CK_443X),
-	CLK(NULL,	"gptimer4_ck",			&gptimer4_ck,	CK_443X),
-	CLK(NULL,	"gptimer5_ck",			&gptimer5_ck,	CK_443X),
-	CLK(NULL,	"gptimer6_ck",			&gptimer6_ck,	CK_443X),
-	CLK(NULL,	"gptimer7_ck",			&gptimer7_ck,	CK_443X),
-	CLK(NULL,	"gptimer8_ck",			&gptimer8_ck,	CK_443X),
-	CLK(NULL,	"gptimer9_ck",			&gptimer9_ck,	CK_443X),
-	CLK("omap2_hdq.0",	"ick",				&hdq1w_ck,	CK_443X),
-	CLK(NULL,	"hsi_ck",			&hsi_ck,	CK_443X),
-	CLK("i2c_omap.1",	"ick",				&i2c1_ck,	CK_443X),
-	CLK("i2c_omap.2",	"ick",				&i2c2_ck,	CK_443X),
-	CLK("i2c_omap.3",	"ick",				&i2c3_ck,	CK_443X),
-	CLK("i2c_omap.4",	"ick",				&i2c4_ck,	CK_443X),
-	CLK(NULL,	"iss_ck",			&iss_ck,	CK_443X),
-	CLK(NULL,	"ivahd_ck",			&ivahd_ck,	CK_443X),
-	CLK(NULL,	"keyboard_ck",			&keyboard_ck,	CK_443X),
-	CLK(NULL,	"l3_instr_interconnect_ck",	&l3_instr_interconnect_ck,	CK_443X),
-	CLK(NULL,	"l3_interconnect_3_ck",		&l3_interconnect_3_ck,	CK_443X),
+	CLK(NULL,	"gfx_fck",			&gfx_fck,	CK_443X),
+	CLK(NULL,	"gpio1_ick",			&gpio1_ick,	CK_443X),
+	CLK(NULL,	"gpio2_ick",			&gpio2_ick,	CK_443X),
+	CLK(NULL,	"gpio3_ick",			&gpio3_ick,	CK_443X),
+	CLK(NULL,	"gpio4_ick",			&gpio4_ick,	CK_443X),
+	CLK(NULL,	"gpio5_ick",			&gpio5_ick,	CK_443X),
+	CLK(NULL,	"gpio6_ick",			&gpio6_ick,	CK_443X),
+	CLK(NULL,	"gpmc_ick",			&gpmc_ick,	CK_443X),
+	CLK(NULL,	"gpt1_fck",			&gpt1_fck,	CK_443X),
+	CLK(NULL,	"gpt10_fck",			&gpt10_fck,	CK_443X),
+	CLK(NULL,	"gpt11_fck",			&gpt11_fck,	CK_443X),
+	CLK(NULL,	"gpt2_fck",			&gpt2_fck,	CK_443X),
+	CLK(NULL,	"gpt3_fck",			&gpt3_fck,	CK_443X),
+	CLK(NULL,	"gpt4_fck",			&gpt4_fck,	CK_443X),
+	CLK(NULL,	"gpt5_fck",			&gpt5_fck,	CK_443X),
+	CLK(NULL,	"gpt6_fck",			&gpt6_fck,	CK_443X),
+	CLK(NULL,	"gpt7_fck",			&gpt7_fck,	CK_443X),
+	CLK(NULL,	"gpt8_fck",			&gpt8_fck,	CK_443X),
+	CLK(NULL,	"gpt9_fck",			&gpt9_fck,	CK_443X),
+	CLK("omap2_hdq.0",	"fck",				&hdq1w_fck,	CK_443X),
+	CLK(NULL,	"hsi_ick",			&hsi_ick,	CK_443X),
+	CLK("i2c_omap.1",	"fck",				&i2c1_fck,	CK_443X),
+	CLK("i2c_omap.2",	"fck",				&i2c2_fck,	CK_443X),
+	CLK("i2c_omap.3",	"fck",				&i2c3_fck,	CK_443X),
+	CLK("i2c_omap.4",	"fck",				&i2c4_fck,	CK_443X),
+	CLK(NULL,	"iss_fck",			&iss_fck,	CK_443X),
+	CLK(NULL,	"ivahd_ick",			&ivahd_ick,	CK_443X),
+	CLK(NULL,	"keyboard_fck",			&keyboard_fck,	CK_443X),
+	CLK(NULL,	"l3_instr_interconnect_ick",	&l3_instr_interconnect_ick,	CK_443X),
+	CLK(NULL,	"l3_interconnect_3_ick",	&l3_interconnect_3_ick,	CK_443X),
 	CLK(NULL,	"mcasp_sync_mux_ck",		&mcasp_sync_mux_ck,	CK_443X),
-	CLK(NULL,	"mcasp_ck",			&mcasp_ck,	CK_443X),
+	CLK(NULL,	"mcasp_fck",			&mcasp_fck,	CK_443X),
 	CLK(NULL,	"mcbsp1_sync_mux_ck",		&mcbsp1_sync_mux_ck,	CK_443X),
-	CLK("omap-mcbsp.1",	"fck",				&mcbsp1_ck,	CK_443X),
+	CLK("omap-mcbsp.1",	"fck",				&mcbsp1_fck,	CK_443X),
 	CLK(NULL,	"mcbsp2_sync_mux_ck",		&mcbsp2_sync_mux_ck,	CK_443X),
-	CLK("omap-mcbsp.2",	"fck",				&mcbsp2_ck,	CK_443X),
+	CLK("omap-mcbsp.2",	"fck",				&mcbsp2_fck,	CK_443X),
 	CLK(NULL,	"mcbsp3_sync_mux_ck",		&mcbsp3_sync_mux_ck,	CK_443X),
-	CLK("omap-mcbsp.3",	"fck",				&mcbsp3_ck,	CK_443X),
+	CLK("omap-mcbsp.3",	"fck",				&mcbsp3_fck,	CK_443X),
 	CLK(NULL,	"mcbsp4_sync_mux_ck",		&mcbsp4_sync_mux_ck,	CK_443X),
-	CLK("omap-mcbsp.4",	"fck",				&mcbsp4_ck,	CK_443X),
-	CLK("omap2_mcspi.1",	"fck",				&mcspi1_ck,	CK_443X),
-	CLK("omap2_mcspi.2",	"fck",				&mcspi2_ck,	CK_443X),
-	CLK("omap2_mcspi.3",	"fck",				&mcspi3_ck,	CK_443X),
-	CLK("omap2_mcspi.4",	"fck",				&mcspi4_ck,	CK_443X),
-	CLK("mmci-omap-hs.0",	"fck",				&mmc1_ck,	CK_443X),
-	CLK("mmci-omap-hs.1",	"fck",				&mmc2_ck,	CK_443X),
-	CLK("mmci-omap-hs.2",	"fck",				&mmc3_ck,	CK_443X),
-	CLK("mmci-omap-hs.3",	"fck",				&mmc4_ck,	CK_443X),
-	CLK("mmci-omap-hs.4",	"fck",				&mmc5_ck,	CK_443X),
-	CLK(NULL,	"ocp_wp1_ck",			&ocp_wp1_ck,	CK_443X),
-	CLK(NULL,	"pdm_ck",			&pdm_ck,	CK_443X),
-	CLK(NULL,	"pkaeip29_ck",			&pkaeip29_ck,	CK_443X),
-	CLK("omap_rng",	"ick",				&rng_ck,	CK_443X),
-	CLK(NULL,	"sha2md51_ck",			&sha2md51_ck,	CK_443X),
-	CLK(NULL,	"sl2_ck",			&sl2_ck,	CK_443X),
-	CLK(NULL,	"slimbus1_ck",			&slimbus1_ck,	CK_443X),
-	CLK(NULL,	"slimbus2_ck",			&slimbus2_ck,	CK_443X),
-	CLK(NULL,	"sr_core_ck",			&sr_core_ck,	CK_443X),
-	CLK(NULL,	"sr_iva_ck",			&sr_iva_ck,	CK_443X),
-	CLK(NULL,	"sr_mpu_ck",			&sr_mpu_ck,	CK_443X),
-	CLK(NULL,	"tesla_ck",			&tesla_ck,	CK_443X),
-	CLK(NULL,	"uart1_ck",			&uart1_ck,	CK_443X),
-	CLK(NULL,	"uart2_ck",			&uart2_ck,	CK_443X),
-	CLK(NULL,	"uart3_ck",			&uart3_ck,	CK_443X),
-	CLK(NULL,	"uart4_ck",			&uart4_ck,	CK_443X),
-	CLK(NULL,	"unipro1_ck",			&unipro1_ck,	CK_443X),
-	CLK(NULL,	"usb_host_ck",			&usb_host_ck,	CK_443X),
-	CLK(NULL,	"usb_host_fs_ck",		&usb_host_fs_ck,	CK_443X),
-	CLK("musb_hdrc",	"ick",				&usb_otg_ck,	CK_443X),
-	CLK(NULL,	"usb_tll_ck",			&usb_tll_ck,	CK_443X),
-	CLK(NULL,	"usbphyocp2scp_ck",		&usbphyocp2scp_ck,	CK_443X),
-	CLK(NULL,	"usim_ck",			&usim_ck,	CK_443X),
-	CLK("omap_wdt",	"fck",				&wdt2_ck,	CK_443X),
-	CLK(NULL,	"wdt3_ck",			&wdt3_ck,	CK_443X),
+	CLK("omap-mcbsp.4",	"fck",				&mcbsp4_fck,	CK_443X),
+	CLK("omap2_mcspi.1",	"fck",				&mcspi1_fck,	CK_443X),
+	CLK("omap2_mcspi.2",	"fck",				&mcspi2_fck,	CK_443X),
+	CLK("omap2_mcspi.3",	"fck",				&mcspi3_fck,	CK_443X),
+	CLK("omap2_mcspi.4",	"fck",				&mcspi4_fck,	CK_443X),
+	CLK("mmci-omap-hs.0",	"fck",				&mmc1_fck,	CK_443X),
+	CLK("mmci-omap-hs.1",	"fck",				&mmc2_fck,	CK_443X),
+	CLK("mmci-omap-hs.2",	"fck",				&mmc3_fck,	CK_443X),
+	CLK("mmci-omap-hs.3",	"fck",				&mmc4_fck,	CK_443X),
+	CLK("mmci-omap-hs.4",	"fck",				&mmc5_fck,	CK_443X),
+	CLK(NULL,	"ocp_wp1_ick",			&ocp_wp1_ick,	CK_443X),
+	CLK(NULL,	"pdm_fck",			&pdm_fck,	CK_443X),
+	CLK(NULL,	"pkaeip29_fck",			&pkaeip29_fck,	CK_443X),
+	CLK("omap_rng",	"ick",				&rng_ick,	CK_443X),
+	CLK(NULL,	"sha2md51_fck",			&sha2md51_fck,	CK_443X),
+	CLK(NULL,	"sl2_ick",			&sl2_ick,	CK_443X),
+	CLK(NULL,	"slimbus1_fck",			&slimbus1_fck,	CK_443X),
+	CLK(NULL,	"slimbus2_fck",			&slimbus2_fck,	CK_443X),
+	CLK(NULL,	"sr_core_fck",			&sr_core_fck,	CK_443X),
+	CLK(NULL,	"sr_iva_fck",			&sr_iva_fck,	CK_443X),
+	CLK(NULL,	"sr_mpu_fck",			&sr_mpu_fck,	CK_443X),
+	CLK(NULL,	"tesla_ick",			&tesla_ick,	CK_443X),
+	CLK(NULL,	"uart1_fck",			&uart1_fck,	CK_443X),
+	CLK(NULL,	"uart2_fck",			&uart2_fck,	CK_443X),
+	CLK(NULL,	"uart3_fck",			&uart3_fck,	CK_443X),
+	CLK(NULL,	"uart4_fck",			&uart4_fck,	CK_443X),
+	CLK(NULL,	"unipro1_fck",			&unipro1_fck,	CK_443X),
+	CLK(NULL,	"usb_host_fck",			&usb_host_fck,	CK_443X),
+	CLK(NULL,	"usb_host_fs_fck",		&usb_host_fs_fck,	CK_443X),
+	CLK("musb_hdrc",	"ick",				&usb_otg_ick,	CK_443X),
+	CLK(NULL,	"usb_tll_ick",			&usb_tll_ick,	CK_443X),
+	CLK(NULL,	"usbphyocp2scp_ick",		&usbphyocp2scp_ick,	CK_443X),
+	CLK(NULL,	"usim_fck",			&usim_fck,	CK_443X),
+	CLK("omap_wdt",	"fck",				&wdt2_fck,	CK_443X),
+	CLK(NULL,	"wdt3_fck",			&wdt3_fck,	CK_443X),
 	CLK(NULL,	"otg_60m_gfclk_ck",		&otg_60m_gfclk_ck,	CK_443X),
 	CLK(NULL,	"stm_clk_div_ck",		&stm_clk_div_ck,	CK_443X),
 	CLK(NULL,	"trace_clk_div_ck",		&trace_clk_div_ck,	CK_443X),
 	CLK(NULL,	"usim_fclk",			&usim_fclk,	CK_443X),
 	CLK(NULL,	"utmi_p1_gfclk_ck",		&utmi_p1_gfclk_ck,	CK_443X),
 	CLK(NULL,	"utmi_p2_gfclk_ck",		&utmi_p2_gfclk_ck,	CK_443X),
+	CLK(NULL,	"gpio1_dbck",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpio2_dbck",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpio3_dbck",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpio4_dbck",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpio5_dbck",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpio6_dbck",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpmc_ck",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpt1_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpt2_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpt3_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpt4_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpt5_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpt6_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpt7_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpt8_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpt9_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpt10_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"gpt11_ick",			&dummy_ck,	CK_443X),
+	CLK("i2c_omap.1",	"ick",				&dummy_ck,	CK_443X),
+	CLK("i2c_omap.2",	"ick",				&dummy_ck,	CK_443X),
+	CLK("i2c_omap.3",	"ick",				&dummy_ck,	CK_443X),
+	CLK("i2c_omap.4",	"ick",				&dummy_ck,	CK_443X),
+	CLK("omap-mcbsp.1",	"ick",				&dummy_ck,	CK_443X),
+	CLK("omap-mcbsp.2",	"ick",				&dummy_ck,	CK_443X),
+	CLK("omap-mcbsp.3",	"ick",				&dummy_ck,	CK_443X),
+	CLK("omap-mcbsp.4",	"ick",				&dummy_ck,	CK_443X),
+	CLK("omap2_mcspi.1",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap2_mcspi.2",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap2_mcspi.3",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap2_mcspi.4",	"ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"uart1_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"uart2_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"uart3_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"uart4_ick",			&dummy_ck,	CK_443X),
+	CLK("omap_wdt",	"ick",				&dummy_ck,	CK_443X),
 };
 
-int __init omap2_clk_init(void)
+int __init omap4xxx_clk_init(void)
 {
-	/* struct prcm_config *prcm; */
 	struct omap_clk *c;
-	/* u32 clkrate; */
 	u32 cpu_clkflg;
 
 	if (cpu_is_omap44xx()) {
@@ -2749,9 +2703,7 @@ int __init omap2_clk_init(void)
 		if (c->cpu & cpu_clkflg) {
 			clkdev_add(&c->lk);
 			clk_register(c->lk.clk);
-			/* TODO
 			omap2_init_clk_clkdm(c->lk.clk);
-			*/
 		}
 
 	recalculate_root_clocks();
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock44xx.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock44xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock44xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock44xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,14 +2,19 @@
  * OMAP4 clock function prototypes and macros
  *
  * Copyright (C) 2009 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
  */
 
-#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_44XX_H
-#define __ARCH_ARM_MACH_OMAP2_CLOCK_44XX_H
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H
 
-#define OMAP4430_MAX_DPLL_MULT	2048
+/*
+ * XXX Missing values for the OMAP4 DPLL_USB
+ * XXX Missing min_multiplier values for all OMAP4 DPLLs
+ */
+#define OMAP4430_MAX_DPLL_MULT	2047
 #define OMAP4430_MAX_DPLL_DIV	128
 
-extern const struct clkops clkops_noncore_dpll_ops;
+int omap4xxx_clk_init(void);
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  *  linux/arch/arm/mach-omap2/clock.c
  *
  *  Copyright (C) 2005-2008 Texas Instruments, Inc.
- *  Copyright (C) 2004-2008 Nokia Corporation
+ *  Copyright (C) 2004-2010 Nokia Corporation
  *
  *  Contacts:
  *  Richard Woodruff <r-woodruff2@ti.com>
@@ -14,11 +14,10 @@
  */
 #undef DEBUG
 
-#include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/device.h>
 #include <linux/list.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/io.h>
@@ -28,10 +27,7 @@
 #include <plat/clockdomain.h>
 #include <plat/cpu.h>
 #include <plat/prcm.h>
-#include <asm/div64.h>
 
-#include <plat/sdrc.h>
-#include "sdrc.h"
 #include "clock.h"
 #include "prm.h"
 #include "prm-regbits-24xx.h"
@@ -39,140 +35,44 @@
 #include "cm-regbits-24xx.h"
 #include "cm-regbits-34xx.h"
 
-/* DPLL rate rounding: minimum DPLL multiplier, divider values */
-#define DPLL_MIN_MULTIPLIER		1
-#define DPLL_MIN_DIVIDER		1
-
-/* Possible error results from _dpll_test_mult */
-#define DPLL_MULT_UNDERFLOW		-1
+u8 cpu_mask;
 
 /*
- * Scale factor to mitigate roundoff errors in DPLL rate rounding.
- * The higher the scale factor, the greater the risk of arithmetic overflow,
- * but the closer the rounded rate to the target rate.  DPLL_SCALE_FACTOR
- * must be a power of DPLL_SCALE_BASE.
+ * OMAP2+ specific clock functions
  */
-#define DPLL_SCALE_FACTOR		64
-#define DPLL_SCALE_BASE			2
-#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;
-
-/*-------------------------------------------------------------------------
- * OMAP2/3/4 specific clock functions
- *-------------------------------------------------------------------------*/
-
-void omap2_init_dpll_parent(struct clk *clk)
-{
-	u32 v;
-	struct dpll_data *dd;
-
-	dd = clk->dpll_data;
-	if (!dd)
-		return;
-
-	/* Return bypass rate if DPLL is bypassed */
-	v = __raw_readl(dd->control_reg);
-	v &= dd->enable_mask;
-	v >>= __ffs(dd->enable_mask);
-
-	/* Reparent in case the dpll is in bypass */
-	if (cpu_is_omap24xx()) {
-		if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
-		    v == OMAP2XXX_EN_DPLL_FRBYPASS)
-			clk_reparent(clk, dd->clk_bypass);
-	} else if (cpu_is_omap34xx()) {
-		if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
-		    v == OMAP3XXX_EN_DPLL_FRBYPASS)
-			clk_reparent(clk, dd->clk_bypass);
-	} else if (cpu_is_omap44xx()) {
-		if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
-		    v == OMAP4XXX_EN_DPLL_FRBYPASS ||
-		    v == OMAP4XXX_EN_DPLL_MNBYPASS)
-			clk_reparent(clk, dd->clk_bypass);
-	}
-	return;
-}
+/* Private functions */
 
 /**
- * _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,
-		OMAP2_PRCM_CLKCFG_CTRL_OFFSET);
-	/* OCP barrier */
-	prm_read_mod_reg(OMAP24XX_GR_MOD, OMAP2_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
+ * _omap2_module_wait_ready - wait for an OMAP module to leave IDLE
+ * @clk: struct clk * belonging to the module
  *
- * 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).
+ * If the necessary clocks for the OMAP hardware IP block that
+ * corresponds to clock @clk are enabled, then wait for the module to
+ * indicate readiness (i.e., to leave IDLE).  This code does not
+ * belong in the clock code and will be moved in the medium term to
+ * module-dependent code.  No return value.
  */
-static int _dpll_test_fint(struct clk *clk, u8 n)
+static void _omap2_module_wait_ready(struct clk *clk)
 {
-	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;
+	void __iomem *companion_reg, *idlest_reg;
+	u8 other_bit, idlest_bit, idlest_val;
 
+	/* Not all modules have multiple clocks that their IDLEST depends on */
+	if (clk->ops->find_companion) {
+		clk->ops->find_companion(clk, &companion_reg, &other_bit);
+		if (!(__raw_readl(companion_reg) & (1 << other_bit)))
+			return;
 	}
 
-	return ret;
+	clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val);
+
+	omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), idlest_val,
+			     clk->name);
 }
 
+/* Public functions */
+
 /**
  * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
  * @clk: OMAP clock struct ptr to use
@@ -181,7 +81,6 @@ static int _dpll_test_fint(struct clk *c
  * clockdomain pointer, and save it into the struct clk.  Intended to be
  * called during clk_register().  No return value.
  */
-#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
 void omap2_init_clk_clkdm(struct clk *clk)
 {
 	struct clockdomain *clkdm;
@@ -199,117 +98,6 @@ void omap2_init_clk_clkdm(struct clk *cl
 			 "clkdm %s\n", clk->name, clk->clkdm_name);
 	}
 }
-#endif
-
-/**
- * omap2_init_clksel_parent - set a clksel clk's parent field from the hardware
- * @clk: OMAP clock struct ptr to use
- *
- * Given a pointer to a source-selectable struct clk, read the hardware
- * register and determine what its parent is currently set to.  Update the
- * clk->parent field with the appropriate clk ptr.
- */
-void omap2_init_clksel_parent(struct clk *clk)
-{
-	const struct clksel *clks;
-	const struct clksel_rate *clkr;
-	u32 r, found = 0;
-
-	if (!clk->clksel)
-		return;
-
-	r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
-	r >>= __ffs(clk->clksel_mask);
-
-	for (clks = clk->clksel; clks->parent && !found; clks++) {
-		for (clkr = clks->rates; clkr->div && !found; clkr++) {
-			if ((clkr->flags & cpu_mask) && (clkr->val == r)) {
-				if (clk->parent != clks->parent) {
-					pr_debug("clock: inited %s parent "
-						 "to %s (was %s)\n",
-						 clk->name, clks->parent->name,
-						 ((clk->parent) ?
-						  clk->parent->name : "NULL"));
-					clk_reparent(clk, clks->parent);
-				};
-				found = 1;
-			}
-		}
-	}
-
-	if (!found)
-		printk(KERN_ERR "clock: init parent: could not find "
-		       "regval %0x for clock %s\n", r,  clk->name);
-
-	return;
-}
-
-/**
- * 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, v;
-	struct dpll_data *dd;
-
-	dd = clk->dpll_data;
-	if (!dd)
-		return 0;
-
-	/* 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;
-	} else if (cpu_is_omap44xx()) {
-		if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
-		    v == OMAP4XXX_EN_DPLL_FRBYPASS ||
-		    v == OMAP4XXX_EN_DPLL_MNBYPASS)
-			return dd->clk_bypass->rate;
-	}
-
-	v = __raw_readl(dd->mult_div1_reg);
-	dpll_mult = v & dd->mult_mask;
-	dpll_mult >>= __ffs(dd->mult_mask);
-	dpll_div = v & dd->div1_mask;
-	dpll_div >>= __ffs(dd->div1_mask);
-
-	dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;
-	do_div(dpll_clk, dpll_div + 1);
-
-	return dpll_clk;
-}
-
-/*
- * Used for clocks that have the same value as the parent clock,
- * divided by some factor
- */
-unsigned long omap2_fixed_divisor_recalc(struct clk *clk)
-{
-	WARN_ON(!clk->fixed_div);
-
-	return clk->parent->rate / clk->fixed_div;
-}
 
 /**
  * omap2_clk_dflt_find_companion - find companion clock to @clk
@@ -351,7 +139,8 @@ void omap2_clk_dflt_find_companion(struc
  * omap2_clk_dflt_find_idlest - find CM_IDLEST reg va, bit shift for @clk
  * @clk: struct clk * to find IDLEST info for
  * @idlest_reg: void __iomem ** to return the CM_IDLEST va in
- * @idlest_bit: u8 ** to return the CM_IDLEST bit shift in
+ * @idlest_bit: u8 * to return the CM_IDLEST bit shift in
+ * @idlest_val: u8 * to return the idle status indicator
  *
  * Return the CM_IDLEST register address and bit shift corresponding
  * to the module that "owns" this clock.  This default code assumes
@@ -361,40 +150,26 @@ void omap2_clk_dflt_find_companion(struc
  * CM_IDLEST2).  This is not true for all modules.  No return value.
  */
 void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
-				u8 *idlest_bit)
+				u8 *idlest_bit, u8 *idlest_val)
 {
 	u32 r;
 
 	r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
 	*idlest_reg = (__force void __iomem *)r;
 	*idlest_bit = clk->enable_bit;
-}
-
-/**
- * omap2_module_wait_ready - wait for an OMAP module to leave IDLE
- * @clk: struct clk * belonging to the module
- *
- * If the necessary clocks for the OMAP hardware IP block that
- * corresponds to clock @clk are enabled, then wait for the module to
- * indicate readiness (i.e., to leave IDLE).  This code does not
- * belong in the clock code and will be moved in the medium term to
- * module-dependent code.  No return value.
- */
-static void omap2_module_wait_ready(struct clk *clk)
-{
-	void __iomem *companion_reg, *idlest_reg;
-	u8 other_bit, idlest_bit;
-
-	/* Not all modules have multiple clocks that their IDLEST depends on */
-	if (clk->ops->find_companion) {
-		clk->ops->find_companion(clk, &companion_reg, &other_bit);
-		if (!(__raw_readl(companion_reg) & (1 << other_bit)))
-			return;
-	}
 
-	clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit);
+	/*
+	 * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
+	 * 34xx reverses this, just to keep us on our toes
+	 * AM35xx uses both, depending on the module.
+	 */
+	if (cpu_is_omap24xx())
+		*idlest_val = OMAP24XX_CM_IDLEST_VAL;
+	else if (cpu_is_omap34xx())
+		*idlest_val = OMAP34XX_CM_IDLEST_VAL;
+	else
+		BUG();
 
-	omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), clk->name);
 }
 
 int omap2_dflt_clk_enable(struct clk *clk)
@@ -416,7 +191,7 @@ int omap2_dflt_clk_enable(struct clk *cl
 	v = __raw_readl(clk->enable_reg); /* OCP barrier */
 
 	if (clk->ops->find_idlest)
-		omap2_module_wait_ready(clk);
+		_omap2_module_wait_ready(clk);
 
 	return 0;
 }
@@ -456,337 +231,109 @@ const struct clkops clkops_omap2_dflt =
 	.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?
+/**
+ * omap2_clk_disable - disable a clock, if the system is not using it
+ * @clk: struct clk * to disable
+ *
+ * Decrements the usecount on struct clk @clk.  If there are no users
+ * left, call the clkops-specific clock disable function to disable it
+ * in hardware.  If the clock is part of a clockdomain (which they all
+ * should be), request that the clockdomain be disabled.  (It too has
+ * a usecount, and so will not be disabled in the hardware until it no
+ * longer has any users.)  If the clock has a parent clock (most of
+ * them do), then call ourselves, recursing on the parent clock.  This
+ * can cause an entire branch of the clock tree to be powered off by
+ * simply disabling one clock.  Intended to be called with the clockfw_lock
+ * spinlock held.  No return value.
  */
-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 (clk->parent)
-			omap2_clk_disable(clk->parent);
-#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
-		if (clk->clkdm)
-			omap2_clkdm_clk_disable(clk->clkdm, clk);
-#endif
-
+	if (clk->usecount == 0) {
+		WARN(1, "clock: %s: omap2_clk_disable() called, but usecount "
+		     "already 0?", clk->name);
+		return;
 	}
-}
 
-int omap2_clk_enable(struct clk *clk)
-{
-	int ret = 0;
+	pr_debug("clock: %s: decrementing usecount\n", clk->name);
 
-	if (clk->usecount++ == 0) {
-#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
-		if (clk->clkdm)
-			omap2_clkdm_clk_enable(clk->clkdm, clk);
-#endif
+	clk->usecount--;
 
-		if (clk->parent) {
-			ret = omap2_clk_enable(clk->parent);
-			if (ret)
-				goto err;
-		}
+	if (clk->usecount > 0)
+		return;
 
-		ret = _omap2_clk_enable(clk);
-		if (ret) {
-			if (clk->parent)
-				omap2_clk_disable(clk->parent);
+	pr_debug("clock: %s: disabling in hardware\n", clk->name);
 
-			goto err;
-		}
-	}
-	return ret;
+	clk->ops->disable(clk);
 
-err:
-#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
 	if (clk->clkdm)
 		omap2_clkdm_clk_disable(clk->clkdm, clk);
-#endif
-	clk->usecount--;
-	return ret;
-}
-
-/*
- * Used for clocks that are part of CLKSEL_xyz governed clocks.
- * REVISIT: Maybe change to use clk->enable() functions like on omap1?
- */
-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 clk->rate;
-
-	rate = clk->parent->rate / div;
-
-	pr_debug("clock: new clock rate is %ld (div %d)\n", rate, div);
-
-	return rate;
-}
-
-/**
- * omap2_get_clksel_by_parent - return clksel struct for a given clk & parent
- * @clk: OMAP struct clk ptr to inspect
- * @src_clk: OMAP struct clk ptr of the parent clk to search for
- *
- * Scan the struct clksel array associated with the clock to find
- * the element associated with the supplied parent clock address.
- * Returns a pointer to the struct clksel on success or NULL on error.
- */
-static const struct clksel *omap2_get_clksel_by_parent(struct clk *clk,
-						       struct clk *src_clk)
-{
-	const struct clksel *clks;
-
-	if (!clk->clksel)
-		return NULL;
-
-	for (clks = clk->clksel; clks->parent; clks++) {
-		if (clks->parent == src_clk)
-			break; /* Found the requested parent */
-	}
-
-	if (!clks->parent) {
-		printk(KERN_ERR "clock: Could not find parent clock %s in "
-		       "clksel array of clock %s\n", src_clk->name,
-		       clk->name);
-		return NULL;
-	}
-
-	return clks;
-}
-
-/**
- * omap2_clksel_round_rate_div - find divisor for the given clock and rate
- * @clk: OMAP struct clk to use
- * @target_rate: desired clock rate
- * @new_div: ptr to where we should store the divisor
- *
- * Finds 'best' divider value in an array based on the source and target
- * rates.  The divider array must be sorted with smallest divider first.
- * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
- * they are only settable as part of virtual_prcm set.
- *
- * Returns the rounded clock rate or returns 0xffffffff on error.
- */
-u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
-				u32 *new_div)
-{
-	unsigned long test_rate;
-	const struct clksel *clks;
-	const struct clksel_rate *clkr;
-	u32 last_div = 0;
-
-	pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n",
-		 clk->name, target_rate);
-
-	*new_div = 1;
-
-	clks = omap2_get_clksel_by_parent(clk, clk->parent);
-	if (!clks)
-		return ~0;
-
-	for (clkr = clks->rates; clkr->div; clkr++) {
-		if (!(clkr->flags & cpu_mask))
-		    continue;
-
-		/* Sanity check */
-		if (clkr->div <= last_div)
-			pr_err("clock: clksel_rate table not sorted "
-			       "for clock %s", clk->name);
-
-		last_div = clkr->div;
-
-		test_rate = clk->parent->rate / clkr->div;
-
-		if (test_rate <= target_rate)
-			break; /* found it */
-	}
-
-	if (!clkr->div) {
-		pr_err("clock: Could not find divisor for target "
-		       "rate %ld for clock %s parent %s\n", target_rate,
-		       clk->name, clk->parent->name);
-		return ~0;
-	}
 
-	*new_div = clkr->div;
-
-	pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div,
-		 (clk->parent->rate / clkr->div));
-
-	return (clk->parent->rate / clkr->div);
+	if (clk->parent)
+		omap2_clk_disable(clk->parent);
 }
 
 /**
- * omap2_clksel_round_rate - find rounded rate for the given clock and rate
- * @clk: OMAP struct clk to use
- * @target_rate: desired clock rate
- *
- * Compatibility wrapper for OMAP clock framework
- * Finds best target rate based on the source clock and possible dividers.
- * rates. The divider array must be sorted with smallest divider first.
- * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
- * they are only settable as part of virtual_prcm set.
+ * omap2_clk_enable - request that the system enable a clock
+ * @clk: struct clk * to enable
  *
- * Returns the rounded clock rate or returns 0xffffffff on error.
+ * Increments the usecount on struct clk @clk.  If there were no users
+ * previously, then recurse up the clock tree, enabling all of the
+ * clock's parents and all of the parent clockdomains, and finally,
+ * enabling @clk's clockdomain, and @clk itself.  Intended to be
+ * called with the clockfw_lock spinlock held.  Returns 0 upon success
+ * or a negative error code upon failure.
  */
-long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
-{
-	u32 new_div;
-
-	return omap2_clksel_round_rate_div(clk, target_rate, &new_div);
-}
-
-
-/* Given a clock and a rate apply a clock specific rounding function */
-long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
+int omap2_clk_enable(struct clk *clk)
 {
-	if (clk->round_rate)
-		return clk->round_rate(clk, rate);
-
-	if (clk->flags & RATE_FIXED)
-		printk(KERN_ERR "clock: generic omap2_clk_round_rate called "
-		       "on fixed-rate clock %s\n", clk->name);
+	int ret;
 
-	return clk->rate;
-}
+	pr_debug("clock: %s: incrementing usecount\n", clk->name);
 
-/**
- * omap2_clksel_to_divisor() - turn clksel field value into integer divider
- * @clk: OMAP struct clk to use
- * @field_val: register field value to find
- *
- * Given a struct clk of a rate-selectable clksel clock, and a register field
- * value to search for, find the corresponding clock divisor.  The register
- * field value should be pre-masked and shifted down so the LSB is at bit 0
- * before calling.  Returns 0 on error
- */
-u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val)
-{
-	const struct clksel *clks;
-	const struct clksel_rate *clkr;
+	clk->usecount++;
 
-	clks = omap2_get_clksel_by_parent(clk, clk->parent);
-	if (!clks)
+	if (clk->usecount > 1)
 		return 0;
 
-	for (clkr = clks->rates; clkr->div; clkr++) {
-		if ((clkr->flags & cpu_mask) && (clkr->val == field_val))
-			break;
-	}
+	pr_debug("clock: %s: enabling in hardware\n", clk->name);
 
-	if (!clkr->div) {
-		printk(KERN_ERR "clock: Could not find fieldval %d for "
-		       "clock %s parent %s\n", field_val, clk->name,
-		       clk->parent->name);
-		return 0;
+	if (clk->parent) {
+		ret = omap2_clk_enable(clk->parent);
+		if (ret) {
+			WARN(1, "clock: %s: could not enable parent %s: %d\n",
+			     clk->name, clk->parent->name, ret);
+			goto oce_err1;
+		}
 	}
 
-	return clkr->div;
-}
-
-/**
- * omap2_divisor_to_clksel() - turn clksel integer divisor into a field value
- * @clk: OMAP struct clk to use
- * @div: integer divisor to search for
- *
- * Given a struct clk of a rate-selectable clksel clock, and a clock divisor,
- * find the corresponding register field value.  The return register value is
- * the value before left-shifting.  Returns ~0 on error
- */
-u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
-{
-	const struct clksel *clks;
-	const struct clksel_rate *clkr;
-
-	/* should never happen */
-	WARN_ON(div == 0);
-
-	clks = omap2_get_clksel_by_parent(clk, clk->parent);
-	if (!clks)
-		return ~0;
-
-	for (clkr = clks->rates; clkr->div; clkr++) {
-		if ((clkr->flags & cpu_mask) && (clkr->div == div))
-			break;
+	if (clk->clkdm) {
+		ret = omap2_clkdm_clk_enable(clk->clkdm, clk);
+		if (ret) {
+			WARN(1, "clock: %s: could not enable clockdomain %s: "
+			     "%d\n", clk->name, clk->clkdm->name, ret);
+			goto oce_err2;
+		}
 	}
 
-	if (!clkr->div) {
-		printk(KERN_ERR "clock: Could not find divisor %d for "
-		       "clock %s parent %s\n", div, clk->name,
-		       clk->parent->name);
-		return ~0;
+	ret = clk->ops->enable(clk);
+	if (ret) {
+		WARN(1, "clock: %s: could not enable: %d\n", clk->name, ret);
+		goto oce_err3;
 	}
 
-	return clkr->val;
-}
-
-/**
- * omap2_clksel_get_divisor - get current divider applied to parent clock.
- * @clk: OMAP struct clk to use.
- *
- * Returns the integer divisor upon success or 0 on error.
- */
-u32 omap2_clksel_get_divisor(struct clk *clk)
-{
-	u32 v;
-
-	if (!clk->clksel_mask)
-		return 0;
-
-	v = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
-	v >>= __ffs(clk->clksel_mask);
-
-	return omap2_clksel_to_divisor(clk, v);
-}
-
-int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
-{
-	u32 v, field_val, validrate, new_div = 0;
-
-	if (!clk->clksel_mask)
-		return -EINVAL;
-
-	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;
-
-	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;
+	return 0;
 
-	_omap2xxx_clk_commit(clk);
+oce_err3:
+	if (clk->clkdm)
+		omap2_clkdm_clk_disable(clk->clkdm, clk);
+oce_err2:
+	if (clk->parent)
+		omap2_clk_disable(clk->parent);
+oce_err1:
+	clk->usecount--;
 
-	return 0;
+	return ret;
 }
 
-
 /* Set the clock rate for a clock source */
 int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
 {
@@ -794,11 +341,6 @@ int omap2_clk_set_rate(struct clk *clk,
 
 	pr_debug("clock: set_rate for clock %s to rate %ld\n", clk->name, rate);
 
-	/* CONFIG_PARTICIPANT clocks are changed only in sets via the
-	   rate table mechanism, driven by mpu_speed  */
-	if (clk->flags & CONFIG_PARTICIPANT)
-		return -EINVAL;
-
 	/* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */
 	if (clk->set_rate)
 		ret = clk->set_rate(clk, rate);
@@ -806,289 +348,152 @@ int omap2_clk_set_rate(struct clk *clk,
 	return ret;
 }
 
-/*
- * Converts encoded control register address into a full address
- * On error, the return value (parent_div) will be 0.
- */
-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;
-
-	clks = omap2_get_clksel_by_parent(clk, src_clk);
-	if (!clks)
-		return 0;
-
-	for (clkr = clks->rates; clkr->div; clkr++) {
-		if (clkr->flags & cpu_mask && clkr->flags & DEFAULT_RATE)
-			break; /* Found the default rate for this platform */
-	}
-
-	if (!clkr->div) {
-		printk(KERN_ERR "clock: Could not find default rate for "
-		       "clock %s parent %s\n", clk->name,
-		       src_clk->parent->name);
-		return 0;
-	}
-
-	/* Should never happen.  Add a clksel mask to the struct clk. */
-	WARN_ON(clk->clksel_mask == 0);
-
-	*field_val = clkr->val;
-
-	return clkr->div;
-}
-
 int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
 {
-	u32 field_val, v, parent_div;
-
-	if (clk->flags & CONFIG_PARTICIPANT)
-		return -EINVAL;
-
 	if (!clk->clksel)
 		return -EINVAL;
 
-	parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val);
-	if (!parent_div)
-		return -EINVAL;
-
-	/* Set new source value (previous dividers if any in effect) */
-	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 */
-
-	_omap2xxx_clk_commit(clk);
+	if (clk->parent == new_parent)
+		return 0;
 
-	clk_reparent(clk, new_parent);
+	return omap2_clksel_set_parent(clk, new_parent);
+}
 
-	/* CLKSEL clocks follow their parents' rates, divided by a divisor */
-	clk->rate = new_parent->rate;
+/* OMAP3/4 non-CORE DPLL clkops */
 
-	if (parent_div > 0)
-		clk->rate /= parent_div;
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
 
-	pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
-		 clk->name, clk->parent->name, clk->rate);
+const struct clkops clkops_omap3_noncore_dpll_ops = {
+	.enable		= omap3_noncore_dpll_enable,
+	.disable	= omap3_noncore_dpll_disable,
+};
 
-	return 0;
-}
+#endif
 
-/* DPLL rate rounding code */
 
-/**
- * omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding
- * @clk: struct clk * of the DPLL
- * @tolerance: maximum rate error tolerance
- *
- * Set the maximum DPLL rate error tolerance for the rate rounding
- * algorithm.  The rate tolerance is an attempt to balance DPLL power
- * saving (the least divider value "n") vs. rate fidelity (the least
- * difference between the desired DPLL target rate and the rounded
- * rate out of the algorithm).  So, increasing the tolerance is likely
- * to decrease DPLL power consumption and increase DPLL rate error.
- * Returns -EINVAL if provided a null clock ptr or a clk that is not a
- * DPLL; or 0 upon success.
+/*
+ * OMAP2+ clock reset and init functions
  */
-int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
-{
-	if (!clk || !clk->dpll_data)
-		return -EINVAL;
 
-	clk->dpll_data->rate_tolerance = tolerance;
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+void omap2_clk_disable_unused(struct clk *clk)
+{
+	u32 regval32, v;
 
-	return 0;
-}
+	v = (clk->flags & INVERT_ENABLE) ? (1 << clk->enable_bit) : 0;
 
-static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
-					    unsigned int m, unsigned int n)
-{
-	unsigned long long num;
+	regval32 = __raw_readl(clk->enable_reg);
+	if ((regval32 & (1 << clk->enable_bit)) == v)
+		return;
 
-	num = (unsigned long long)parent_rate * m;
-	do_div(num, n);
-	return num;
+	printk(KERN_DEBUG "Disabling unused clock \"%s\"\n", clk->name);
+	if (cpu_is_omap34xx()) {
+		omap2_clk_enable(clk);
+		omap2_clk_disable(clk);
+	} else {
+		clk->ops->disable(clk);
+	}
+	if (clk->clkdm != NULL)
+		pwrdm_clkdm_state_switch(clk->clkdm);
 }
+#endif
 
-/*
- * _dpll_test_mult - test a DPLL multiplier value
- * @m: pointer to the DPLL m (multiplier) value under test
- * @n: current DPLL n (divider) value under test
- * @new_rate: pointer to storage for the resulting rounded rate
- * @target_rate: the desired DPLL rate
- * @parent_rate: the DPLL's parent clock rate
+/**
+ * omap2_clk_switch_mpurate_at_boot - switch ARM MPU rate by boot-time argument
+ * @mpurate_ck_name: clk name of the clock to change rate
  *
- * This code tests a DPLL multiplier value, ensuring that the
- * resulting rate will not be higher than the target_rate, and that
- * the multiplier value itself is valid for the DPLL.  Initially, the
- * integer pointed to by the m argument should be prescaled by
- * multiplying by DPLL_SCALE_FACTOR.  The code will replace this with
- * a non-scaled m upon return.  This non-scaled m will result in a
- * new_rate as close as possible to target_rate (but not greater than
- * target_rate) given the current (parent_rate, n, prescaled m)
- * triple. Returns DPLL_MULT_UNDERFLOW in the event that the
- * non-scaled m attempted to underflow, which can allow the calling
- * function to bail out early; or 0 upon success.
+ * Change the ARM MPU clock rate to the rate specified on the command
+ * line, if one was specified.  @mpurate_ck_name should be
+ * "virt_prcm_set" on OMAP2xxx and "dpll1_ck" on OMAP34xx/OMAP36xx.
+ * XXX Does not handle voltage scaling - on OMAP2xxx this is currently
+ * handled by the virt_prcm_set clock, but this should be handled by
+ * the OPP layer.  XXX This is intended to be handled by the OPP layer
+ * code in the near future and should be removed from the clock code.
+ * Returns -EINVAL if 'mpurate' is zero or if clk_set_rate() rejects
+ * the rate, -ENOENT if the struct clk referred to by @mpurate_ck_name
+ * cannot be found, or 0 upon success.
  */
-static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
-			   unsigned long target_rate,
-			   unsigned long parent_rate)
+int __init omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name)
 {
-	int r = 0, carry = 0;
+	struct clk *mpurate_ck;
+	int r;
 
-	/* Unscale m and round if necessary */
-	if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
-		carry = 1;
-	*m = (*m / DPLL_SCALE_FACTOR) + carry;
+	if (!mpurate)
+		return -EINVAL;
 
-	/*
-	 * The new rate must be <= the target rate to avoid programming
-	 * a rate that is impossible for the hardware to handle
-	 */
-	*new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
-	if (*new_rate > target_rate) {
-		(*m)--;
-		*new_rate = 0;
-	}
+	mpurate_ck = clk_get(NULL, mpurate_ck_name);
+	if (WARN(IS_ERR(mpurate_ck), "Failed to get %s.\n", mpurate_ck_name))
+		return -ENOENT;
 
-	/* Guard against m underflow */
-	if (*m < DPLL_MIN_MULTIPLIER) {
-		*m = DPLL_MIN_MULTIPLIER;
-		*new_rate = 0;
-		r = DPLL_MULT_UNDERFLOW;
+	r = clk_set_rate(mpurate_ck, mpurate);
+	if (IS_ERR_VALUE(r)) {
+		WARN(1, "clock: %s: unable to set MPU rate to %d: %d\n",
+		     mpurate_ck->name, mpurate, r);
+		return -EINVAL;
 	}
 
-	if (*new_rate == 0)
-		*new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
+	calibrate_delay();
+	recalculate_root_clocks();
 
-	return r;
+	clk_put(mpurate_ck);
+
+	return 0;
 }
 
 /**
- * omap2_dpll_round_rate - round a target rate for an OMAP DPLL
- * @clk: struct clk * for a DPLL
- * @target_rate: desired DPLL clock rate
+ * omap2_clk_print_new_rates - print summary of current clock tree rates
+ * @hfclkin_ck_name: clk name for the off-chip HF oscillator
+ * @core_ck_name: clk name for the on-chip CORE_CLK
+ * @mpu_ck_name: clk name for the ARM MPU clock
  *
- * Given a DPLL, a desired target rate, and a rate tolerance, round
- * the target rate to a possible, programmable rate for this DPLL.
- * Rate tolerance is assumed to be set by the caller before this
- * function is called.  Attempts to select the minimum possible n
- * within the tolerance to reduce power consumption.  Stores the
- * computed (m, n) in the DPLL's dpll_data structure so set_rate()
- * will not need to call this (expensive) function again.  Returns ~0
- * if the target rate cannot be rounded, either because the rate is
- * too low or because the rate tolerance is set too tightly; or the
- * rounded rate upon success.
+ * Prints a short message to the console with the HFCLKIN oscillator
+ * rate, the rate of the CORE clock, and the rate of the ARM MPU clock.
+ * Called by the boot-time MPU rate switching code.   XXX This is intended
+ * to be handled by the OPP layer code in the near future and should be
+ * removed from the clock code.  No return value.
  */
-long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
+void __init omap2_clk_print_new_rates(const char *hfclkin_ck_name,
+				      const char *core_ck_name,
+				      const char *mpu_ck_name)
 {
-	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 / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
-	scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
-
-	dd->last_rounded_rate = 0;
-
-	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 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)
-			break;
-
-		r = _dpll_test_mult(&m, n, &new_rate, target_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) - 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);
+	struct clk *hfclkin_ck, *core_ck, *mpu_ck;
+	unsigned long hfclkin_rate;
 
-			/* We found good settings -- bail out now */
-			if (min_e <= dd->rate_tolerance)
-				break;
-		}
-	}
+	mpu_ck = clk_get(NULL, mpu_ck_name);
+	if (WARN(IS_ERR(mpu_ck), "clock: failed to get %s.\n", mpu_ck_name))
+		return;
 
-	if (min_e < 0) {
-		pr_debug("clock: error: target rate or tolerance too low\n");
-		return ~0;
-	}
+	core_ck = clk_get(NULL, core_ck_name);
+	if (WARN(IS_ERR(core_ck), "clock: failed to get %s.\n", core_ck_name))
+		return;
 
-	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);
+	hfclkin_ck = clk_get(NULL, hfclkin_ck_name);
+	if (WARN(IS_ERR(hfclkin_ck), "Failed to get %s.\n", hfclkin_ck_name))
+		return;
 
-	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",
-		 dd->last_rounded_rate, target_rate);
+	hfclkin_rate = clk_get_rate(hfclkin_ck);
 
-	return dd->last_rounded_rate;
+	pr_info("Switched to new clocking rate (Crystal/Core/MPU): "
+		"%ld.%01ld/%ld/%ld MHz\n",
+		(hfclkin_rate / 1000000),
+		((hfclkin_rate / 100000) % 10),
+		(clk_get_rate(core_ck) / 1000000),
+		(clk_get_rate(mpu_ck) / 1000000));
 }
 
-/*-------------------------------------------------------------------------
- * Omap2 clock reset and init functions
- *-------------------------------------------------------------------------*/
-
-#ifdef CONFIG_OMAP_RESET_CLOCKS
-void omap2_clk_disable_unused(struct clk *clk)
-{
-	u32 regval32, v;
-
-	v = (clk->flags & INVERT_ENABLE) ? (1 << clk->enable_bit) : 0;
-
-	regval32 = __raw_readl(clk->enable_reg);
-	if ((regval32 & (1 << clk->enable_bit)) == v)
-		return;
+/* Common data */
 
-	printk(KERN_DEBUG "Disabling unused clock \"%s\"\n", clk->name);
-	if (cpu_is_omap34xx()) {
-		omap2_clk_enable(clk);
-		omap2_clk_disable(clk);
-	} else
-		_omap2_clk_disable(clk);
-	if (clk->clkdm != NULL)
-		pwrdm_clkdm_state_switch(clk->clkdm);
-}
+struct clk_functions omap2_clk_functions = {
+	.clk_enable		= omap2_clk_enable,
+	.clk_disable		= omap2_clk_disable,
+	.clk_round_rate		= omap2_clk_round_rate,
+	.clk_set_rate		= omap2_clk_set_rate,
+	.clk_set_parent		= omap2_clk_set_parent,
+	.clk_disable_unused	= omap2_clk_disable_unused,
+#ifdef CONFIG_CPU_FREQ
+	/* These will be removed when the OPP code is integrated */
+	.clk_init_cpufreq_table	= omap2_clk_init_cpufreq_table,
+	.clk_exit_cpufreq_table	= omap2_clk_exit_cpufreq_table,
 #endif
+};
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clockdomain.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clockdomain.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clockdomain.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clockdomain.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,10 +1,11 @@
 /*
- * OMAP2/3 clockdomain framework functions
+ * OMAP2/3/4 clockdomain framework functions
  *
- * Copyright (C) 2008 Texas Instruments, Inc.
- * Copyright (C) 2008-2009 Nokia Corporation
+ * Copyright (C) 2008-2010 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
  *
  * Written by Paul Walmsley and Jouni HÃ¶gander
+ * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@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
@@ -26,43 +27,124 @@
 
 #include <linux/bitops.h>
 
-#include <plat/clock.h>
-
 #include "prm.h"
 #include "prm-regbits-24xx.h"
 #include "cm.h"
 
+#include <plat/clock.h>
 #include <plat/powerdomain.h>
 #include <plat/clockdomain.h>
+#include <plat/prcm.h>
 
 /* clkdm_list contains all registered struct clockdomains */
 static LIST_HEAD(clkdm_list);
 
-/* clkdm_mutex protects clkdm_list add and del ops */
-static DEFINE_MUTEX(clkdm_mutex);
-
-/* array of powerdomain deps to be added/removed when clkdm in hwsup mode */
-static struct clkdm_pwrdm_autodep *autodeps;
+/* array of clockdomain deps to be added/removed when clkdm in hwsup mode */
+static struct clkdm_autodep *autodeps;
 
 
 /* Private functions */
 
+static struct clockdomain *_clkdm_lookup(const char *name)
+{
+	struct clockdomain *clkdm, *temp_clkdm;
+
+	if (!name)
+		return NULL;
+
+	clkdm = NULL;
+
+	list_for_each_entry(temp_clkdm, &clkdm_list, node) {
+		if (!strcmp(name, temp_clkdm->name)) {
+			clkdm = temp_clkdm;
+			break;
+		}
+	}
+
+	return clkdm;
+}
+
+/**
+ * _clkdm_register - register a clockdomain
+ * @clkdm: struct clockdomain * to register
+ *
+ * Adds a clockdomain to the internal clockdomain list.
+ * Returns -EINVAL if given a null pointer, -EEXIST if a clockdomain is
+ * already registered by the provided name, or 0 upon success.
+ */
+static int _clkdm_register(struct clockdomain *clkdm)
+{
+	struct powerdomain *pwrdm;
+
+	if (!clkdm || !clkdm->name)
+		return -EINVAL;
+
+	if (!omap_chip_is(clkdm->omap_chip))
+		return -EINVAL;
+
+	pwrdm = pwrdm_lookup(clkdm->pwrdm.name);
+	if (!pwrdm) {
+		pr_err("clockdomain: %s: powerdomain %s does not exist\n",
+			clkdm->name, clkdm->pwrdm.name);
+		return -EINVAL;
+	}
+	clkdm->pwrdm.ptr = pwrdm;
+
+	/* Verify that the clockdomain is not already registered */
+	if (_clkdm_lookup(clkdm->name))
+		return -EEXIST;
+
+	list_add(&clkdm->node, &clkdm_list);
+
+	pwrdm_add_clkdm(pwrdm, clkdm);
+
+	pr_debug("clockdomain: registered %s\n", clkdm->name);
+
+	return 0;
+}
+
+/* _clkdm_deps_lookup - look up the specified clockdomain in a clkdm list */
+static struct clkdm_dep *_clkdm_deps_lookup(struct clockdomain *clkdm,
+					    struct clkdm_dep *deps)
+{
+	struct clkdm_dep *cd;
+
+	if (!clkdm || !deps || !omap_chip_is(clkdm->omap_chip))
+		return ERR_PTR(-EINVAL);
+
+	for (cd = deps; cd->clkdm_name; cd++) {
+		if (!omap_chip_is(cd->omap_chip))
+			continue;
+
+		if (!cd->clkdm && cd->clkdm_name)
+			cd->clkdm = _clkdm_lookup(cd->clkdm_name);
+
+		if (cd->clkdm == clkdm)
+			break;
+	}
+
+	if (!cd->clkdm_name)
+		return ERR_PTR(-ENOENT);
+
+	return cd;
+}
+
 /*
- * _autodep_lookup - resolve autodep pwrdm names to pwrdm pointers; store
- * @autodep: struct clkdm_pwrdm_autodep * to resolve
+ * _autodep_lookup - resolve autodep clkdm names to clkdm pointers; store
+ * @autodep: struct clkdm_autodep * to resolve
  *
- * Resolve autodep powerdomain names to powerdomain pointers via
- * pwrdm_lookup() and store the pointers in the autodep structure.  An
- * "autodep" is a powerdomain sleep/wakeup dependency that is
+ * Resolve autodep clockdomain names to clockdomain pointers via
+ * clkdm_lookup() and store the pointers in the autodep structure.  An
+ * "autodep" is a clockdomain sleep/wakeup dependency that is
  * automatically added and removed whenever clocks in the associated
  * clockdomain are enabled or disabled (respectively) when the
  * clockdomain is in hardware-supervised mode.	Meant to be called
  * once at clockdomain layer initialization, since these should remain
  * fixed for a particular architecture.  No return value.
  */
-static void _autodep_lookup(struct clkdm_pwrdm_autodep *autodep)
+static void _autodep_lookup(struct clkdm_autodep *autodep)
 {
-	struct powerdomain *pwrdm;
+	struct clockdomain *clkdm;
 
 	if (!autodep)
 		return;
@@ -70,13 +152,13 @@ static void _autodep_lookup(struct clkdm
 	if (!omap_chip_is(autodep->omap_chip))
 		return;
 
-	pwrdm = pwrdm_lookup(autodep->pwrdm.name);
-	if (!pwrdm) {
-		pr_err("clockdomain: autodeps: powerdomain %s does not exist\n",
-			 autodep->pwrdm.name);
-		pwrdm = ERR_PTR(-ENOENT);
+	clkdm = clkdm_lookup(autodep->clkdm.name);
+	if (!clkdm) {
+		pr_err("clockdomain: autodeps: clockdomain %s does not exist\n",
+			 autodep->clkdm.name);
+		clkdm = ERR_PTR(-ENOENT);
 	}
-	autodep->pwrdm.ptr = pwrdm;
+	autodep->clkdm.ptr = clkdm;
 }
 
 /*
@@ -89,21 +171,24 @@ static void _autodep_lookup(struct clkdm
  */
 static void _clkdm_add_autodeps(struct clockdomain *clkdm)
 {
-	struct clkdm_pwrdm_autodep *autodep;
+	struct clkdm_autodep *autodep;
 
-	for (autodep = autodeps; autodep->pwrdm.ptr; autodep++) {
-		if (IS_ERR(autodep->pwrdm.ptr))
+	if (!autodeps)
+		return;
+
+	for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
+		if (IS_ERR(autodep->clkdm.ptr))
 			continue;
 
 		if (!omap_chip_is(autodep->omap_chip))
 			continue;
 
 		pr_debug("clockdomain: adding %s sleepdep/wkdep for "
-			 "pwrdm %s\n", autodep->pwrdm.ptr->name,
-			 clkdm->pwrdm.ptr->name);
+			 "clkdm %s\n", autodep->clkdm.ptr->name,
+			 clkdm->name);
 
-		pwrdm_add_sleepdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
-		pwrdm_add_wkdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
+		clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr);
+		clkdm_add_wkdep(clkdm, autodep->clkdm.ptr);
 	}
 }
 
@@ -117,21 +202,24 @@ static void _clkdm_add_autodeps(struct c
  */
 static void _clkdm_del_autodeps(struct clockdomain *clkdm)
 {
-	struct clkdm_pwrdm_autodep *autodep;
+	struct clkdm_autodep *autodep;
 
-	for (autodep = autodeps; autodep->pwrdm.ptr; autodep++) {
-		if (IS_ERR(autodep->pwrdm.ptr))
+	if (!autodeps)
+		return;
+
+	for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
+		if (IS_ERR(autodep->clkdm.ptr))
 			continue;
 
 		if (!omap_chip_is(autodep->omap_chip))
 			continue;
 
 		pr_debug("clockdomain: removing %s sleepdep/wkdep for "
-			 "pwrdm %s\n", autodep->pwrdm.ptr->name,
-			 clkdm->pwrdm.ptr->name);
+			 "clkdm %s\n", autodep->clkdm.ptr->name,
+			 clkdm->name);
 
-		pwrdm_del_sleepdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
-		pwrdm_del_wkdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
+		clkdm_del_sleepdep(clkdm, autodep->clkdm.ptr);
+		clkdm_del_wkdep(clkdm, autodep->clkdm.ptr);
 	}
 }
 
@@ -145,152 +233,167 @@ static void _clkdm_del_autodeps(struct c
  */
 static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable)
 {
-	u32 v;
+	u32 bits, v;
 
 	if (cpu_is_omap24xx()) {
 		if (enable)
-			v = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
+			bits = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
 		else
-			v = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
-	} else if (cpu_is_omap34xx()) {
+			bits = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
+	} else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
 		if (enable)
-			v = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
+			bits = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
 		else
-			v = OMAP34XX_CLKSTCTRL_DISABLE_AUTO;
+			bits = OMAP34XX_CLKSTCTRL_DISABLE_AUTO;
 	} else {
 		BUG();
 	}
 
-	cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
-			    v << __ffs(clkdm->clktrctrl_mask),
-			    clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
-}
-
-static struct clockdomain *_clkdm_lookup(const char *name)
-{
-	struct clockdomain *clkdm, *temp_clkdm;
-
-	if (!name)
-		return NULL;
-
-	clkdm = NULL;
+	bits = bits << __ffs(clkdm->clktrctrl_mask);
 
-	list_for_each_entry(temp_clkdm, &clkdm_list, node) {
-		if (!strcmp(name, temp_clkdm->name)) {
-			clkdm = temp_clkdm;
-			break;
-		}
-	}
+	v = __raw_readl(clkdm->clkstctrl_reg);
+	v &= ~(clkdm->clktrctrl_mask);
+	v |= bits;
+	__raw_writel(v, clkdm->clkstctrl_reg);
 
-	return clkdm;
 }
 
-
-/* Public functions */
-
 /**
- * clkdm_init - set up the clockdomain layer
- * @clkdms: optional pointer to an array of clockdomains to register
- * @init_autodeps: optional pointer to an array of autodeps to register
+ * _init_wkdep_usecount - initialize wkdep usecounts to match hardware
+ * @clkdm: clockdomain to initialize wkdep usecounts
  *
- * Set up internal state.  If a pointer to an array of clockdomains
- * was supplied, loop through the list of clockdomains, register all
- * that are available on the current platform.	Similarly, if a
- * pointer to an array of clockdomain-powerdomain autodependencies was
- * provided, register those.  No return value.
+ * Initialize the wakeup dependency usecount variables for clockdomain @clkdm.
+ * If a wakeup dependency is present in the hardware, the usecount will be
+ * set to 1; otherwise, it will be set to 0.  Software should clear all
+ * software wakeup dependencies prior to calling this function if it wishes
+ * to ensure that all usecounts start at 0.  No return value.
  */
-void clkdm_init(struct clockdomain **clkdms,
-		struct clkdm_pwrdm_autodep *init_autodeps)
+static void _init_wkdep_usecount(struct clockdomain *clkdm)
 {
-	struct clockdomain **c = NULL;
-	struct clkdm_pwrdm_autodep *autodep = NULL;
+	u32 v;
+	struct clkdm_dep *cd;
 
-	if (clkdms)
-		for (c = clkdms; *c; c++)
-			clkdm_register(*c);
+	if (!clkdm->wkdep_srcs)
+		return;
 
-	autodeps = init_autodeps;
-	if (autodeps)
-		for (autodep = autodeps; autodep->pwrdm.ptr; autodep++)
-			_autodep_lookup(autodep);
+	for (cd = clkdm->wkdep_srcs; cd->clkdm_name; cd++) {
+		if (!omap_chip_is(cd->omap_chip))
+			continue;
+
+		if (!cd->clkdm && cd->clkdm_name)
+			cd->clkdm = _clkdm_lookup(cd->clkdm_name);
+
+		if (!cd->clkdm) {
+			WARN(!cd->clkdm, "clockdomain: %s: wkdep clkdm %s not "
+			     "found\n", clkdm->name, cd->clkdm_name);
+			continue;
+		}
+
+		v = prm_read_mod_bits_shift(clkdm->pwrdm.ptr->prcm_offs,
+					    PM_WKDEP,
+					    (1 << cd->clkdm->dep_bit));
+
+		if (v)
+			pr_debug("clockdomain: %s: wakeup dependency already "
+				 "set to wake up when %s wakes\n",
+				 clkdm->name, cd->clkdm->name);
+
+		atomic_set(&cd->wkdep_usecount, (v) ? 1 : 0);
+	}
 }
 
 /**
- * clkdm_register - register a clockdomain
- * @clkdm: struct clockdomain * to register
+ * _init_sleepdep_usecount - initialize sleepdep usecounts to match hardware
+ * @clkdm: clockdomain to initialize sleepdep usecounts
  *
- * Adds a clockdomain to the internal clockdomain list.
- * Returns -EINVAL if given a null pointer, -EEXIST if a clockdomain is
- * already registered by the provided name, or 0 upon success.
+ * Initialize the sleep dependency usecount variables for clockdomain @clkdm.
+ * If a sleep dependency is present in the hardware, the usecount will be
+ * set to 1; otherwise, it will be set to 0.  Software should clear all
+ * software sleep dependencies prior to calling this function if it wishes
+ * to ensure that all usecounts start at 0.  No return value.
  */
-int clkdm_register(struct clockdomain *clkdm)
+static void _init_sleepdep_usecount(struct clockdomain *clkdm)
 {
-	int ret = -EINVAL;
-	struct powerdomain *pwrdm;
+	u32 v;
+	struct clkdm_dep *cd;
 
-	if (!clkdm || !clkdm->name)
-		return -EINVAL;
+	if (!cpu_is_omap34xx())
+		return;
 
-	if (!omap_chip_is(clkdm->omap_chip))
-		return -EINVAL;
+	if (!clkdm->sleepdep_srcs)
+		return;
 
-	pwrdm = pwrdm_lookup(clkdm->pwrdm.name);
-	if (!pwrdm) {
-		pr_err("clockdomain: %s: powerdomain %s does not exist\n",
-			clkdm->name, clkdm->pwrdm.name);
-		return -EINVAL;
-	}
-	clkdm->pwrdm.ptr = pwrdm;
+	for (cd = clkdm->sleepdep_srcs; cd->clkdm_name; cd++) {
+		if (!omap_chip_is(cd->omap_chip))
+			continue;
 
-	mutex_lock(&clkdm_mutex);
-	/* Verify that the clockdomain is not already registered */
-	if (_clkdm_lookup(clkdm->name)) {
-		ret = -EEXIST;
-		goto cr_unlock;
-	}
+		if (!cd->clkdm && cd->clkdm_name)
+			cd->clkdm = _clkdm_lookup(cd->clkdm_name);
 
-	list_add(&clkdm->node, &clkdm_list);
+		if (!cd->clkdm) {
+			WARN(!cd->clkdm, "clockdomain: %s: sleepdep clkdm %s "
+			     "not found\n", clkdm->name, cd->clkdm_name);
+			continue;
+		}
 
-	pwrdm_add_clkdm(pwrdm, clkdm);
+		v = prm_read_mod_bits_shift(clkdm->pwrdm.ptr->prcm_offs,
+					    OMAP3430_CM_SLEEPDEP,
+					    (1 << cd->clkdm->dep_bit));
 
-	pr_debug("clockdomain: registered %s\n", clkdm->name);
-	ret = 0;
+		if (v)
+			pr_debug("clockdomain: %s: sleep dependency already "
+				 "set to prevent from idling until %s "
+				 "idles\n", clkdm->name, cd->clkdm->name);
 
-cr_unlock:
-	mutex_unlock(&clkdm_mutex);
+		atomic_set(&cd->sleepdep_usecount, (v) ? 1 : 0);
+	}
+};
 
-	return ret;
-}
+/* Public functions */
 
 /**
- * clkdm_unregister - unregister a clockdomain
- * @clkdm: struct clockdomain * to unregister
+ * clkdm_init - set up the clockdomain layer
+ * @clkdms: optional pointer to an array of clockdomains to register
+ * @init_autodeps: optional pointer to an array of autodeps to register
  *
- * Removes a clockdomain from the internal clockdomain list.  Returns
- * -EINVAL if clkdm argument is NULL.
+ * Set up internal state.  If a pointer to an array of clockdomains
+ * @clkdms was supplied, loop through the list of clockdomains,
+ * register all that are available on the current platform. Similarly,
+ * if a pointer to an array of clockdomain autodependencies
+ * @init_autodeps was provided, register those.  No return value.
  */
-int clkdm_unregister(struct clockdomain *clkdm)
+void clkdm_init(struct clockdomain **clkdms,
+		struct clkdm_autodep *init_autodeps)
 {
-	if (!clkdm)
-		return -EINVAL;
-
-	pwrdm_del_clkdm(clkdm->pwrdm.ptr, clkdm);
+	struct clockdomain **c = NULL;
+	struct clockdomain *clkdm;
+	struct clkdm_autodep *autodep = NULL;
 
-	mutex_lock(&clkdm_mutex);
-	list_del(&clkdm->node);
-	mutex_unlock(&clkdm_mutex);
+	if (clkdms)
+		for (c = clkdms; *c; c++)
+			_clkdm_register(*c);
 
-	pr_debug("clockdomain: unregistered %s\n", clkdm->name);
+	autodeps = init_autodeps;
+	if (autodeps)
+		for (autodep = autodeps; autodep->clkdm.ptr; autodep++)
+			_autodep_lookup(autodep);
 
-	return 0;
+	/*
+	 * Ensure that the *dep_usecount registers reflect the current
+	 * state of the PRCM.
+	 */
+	list_for_each_entry(clkdm, &clkdm_list, node) {
+		_init_wkdep_usecount(clkdm);
+		_init_sleepdep_usecount(clkdm);
+	}
 }
 
 /**
  * clkdm_lookup - look up a clockdomain by name, return a pointer
  * @name: name of clockdomain
  *
- * Find a registered clockdomain by its name.  Returns a pointer to the
- * struct clockdomain if found, or NULL otherwise.
+ * Find a registered clockdomain by its name @name.  Returns a pointer
+ * to the struct clockdomain if found, or NULL otherwise.
  */
 struct clockdomain *clkdm_lookup(const char *name)
 {
@@ -301,14 +404,12 @@ struct clockdomain *clkdm_lookup(const c
 
 	clkdm = NULL;
 
-	mutex_lock(&clkdm_mutex);
 	list_for_each_entry(temp_clkdm, &clkdm_list, node) {
 		if (!strcmp(name, temp_clkdm->name)) {
 			clkdm = temp_clkdm;
 			break;
 		}
 	}
-	mutex_unlock(&clkdm_mutex);
 
 	return clkdm;
 }
@@ -317,8 +418,8 @@ struct clockdomain *clkdm_lookup(const c
  * clkdm_for_each - call function on each registered clockdomain
  * @fn: callback function *
  *
- * Call the supplied function for each registered clockdomain.
- * The callback function can return anything but 0 to bail
+ * Call the supplied function @fn for each registered clockdomain.
+ * The callback function @fn can return anything but 0 to bail
  * out early from the iterator.  The callback function is called with
  * the clkdm_mutex held, so no clockdomain structure manipulation
  * functions should be called from the callback, although hardware
@@ -336,13 +437,11 @@ int clkdm_for_each(int (*fn)(struct cloc
 	if (!fn)
 		return -EINVAL;
 
-	mutex_lock(&clkdm_mutex);
 	list_for_each_entry(clkdm, &clkdm_list, node) {
 		ret = (*fn)(clkdm, user);
 		if (ret)
 			break;
 	}
-	mutex_unlock(&clkdm_mutex);
 
 	return ret;
 }
@@ -353,7 +452,7 @@ int clkdm_for_each(int (*fn)(struct cloc
  * @clkdm: struct clockdomain *
  *
  * Return a pointer to the struct powerdomain that the specified clockdomain
- * 'clkdm' exists in, or returns NULL if clkdm argument is NULL.
+ * @clkdm exists in, or returns NULL if @clkdm is NULL.
  */
 struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)
 {
@@ -367,11 +466,309 @@ struct powerdomain *clkdm_get_pwrdm(stru
 /* Hardware clockdomain control */
 
 /**
+ * clkdm_add_wkdep - add a wakeup dependency from clkdm2 to clkdm1
+ * @clkdm1: wake this struct clockdomain * up (dependent)
+ * @clkdm2: when this struct clockdomain * wakes up (source)
+ *
+ * When the clockdomain represented by @clkdm2 wakes up, wake up
+ * @clkdm1. Implemented in hardware on the OMAP, this feature is
+ * designed to reduce wakeup latency of the dependent clockdomain @clkdm1.
+ * Returns -EINVAL if presented with invalid clockdomain pointers,
+ * -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or 0 upon
+ * success.
+ */
+int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
+{
+	struct clkdm_dep *cd;
+
+	if (!clkdm1 || !clkdm2)
+		return -EINVAL;
+
+	cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
+	if (IS_ERR(cd)) {
+		pr_debug("clockdomain: hardware cannot set/clear wake up of "
+			 "%s when %s wakes up\n", clkdm1->name, clkdm2->name);
+		return PTR_ERR(cd);
+	}
+
+	if (atomic_inc_return(&cd->wkdep_usecount) == 1) {
+		pr_debug("clockdomain: hardware will wake up %s when %s wakes "
+			 "up\n", clkdm1->name, clkdm2->name);
+
+		prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
+				     clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+	}
+
+	return 0;
+}
+
+/**
+ * clkdm_del_wkdep - remove a wakeup dependency from clkdm2 to clkdm1
+ * @clkdm1: wake this struct clockdomain * up (dependent)
+ * @clkdm2: when this struct clockdomain * wakes up (source)
+ *
+ * Remove a wakeup dependency causing @clkdm1 to wake up when @clkdm2
+ * wakes up.  Returns -EINVAL if presented with invalid clockdomain
+ * pointers, -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or
+ * 0 upon success.
+ */
+int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
+{
+	struct clkdm_dep *cd;
+
+	if (!clkdm1 || !clkdm2)
+		return -EINVAL;
+
+	cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
+	if (IS_ERR(cd)) {
+		pr_debug("clockdomain: hardware cannot set/clear wake up of "
+			 "%s when %s wakes up\n", clkdm1->name, clkdm2->name);
+		return PTR_ERR(cd);
+	}
+
+	if (atomic_dec_return(&cd->wkdep_usecount) == 0) {
+		pr_debug("clockdomain: hardware will no longer wake up %s "
+			 "after %s wakes up\n", clkdm1->name, clkdm2->name);
+
+		prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
+				       clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+	}
+
+	return 0;
+}
+
+/**
+ * clkdm_read_wkdep - read wakeup dependency state from clkdm2 to clkdm1
+ * @clkdm1: wake this struct clockdomain * up (dependent)
+ * @clkdm2: when this struct clockdomain * wakes up (source)
+ *
+ * Return 1 if a hardware wakeup dependency exists wherein @clkdm1 will be
+ * awoken when @clkdm2 wakes up; 0 if dependency is not set; -EINVAL
+ * if either clockdomain pointer is invalid; or -ENOENT if the hardware
+ * is incapable.
+ *
+ * REVISIT: Currently this function only represents software-controllable
+ * wakeup dependencies.  Wakeup dependencies fixed in hardware are not
+ * yet handled here.
+ */
+int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
+{
+	struct clkdm_dep *cd;
+
+	if (!clkdm1 || !clkdm2)
+		return -EINVAL;
+
+	cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
+	if (IS_ERR(cd)) {
+		pr_debug("clockdomain: hardware cannot set/clear wake up of "
+			 "%s when %s wakes up\n", clkdm1->name, clkdm2->name);
+		return PTR_ERR(cd);
+	}
+
+	/* XXX It's faster to return the atomic wkdep_usecount */
+	return prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP,
+				       (1 << clkdm2->dep_bit));
+}
+
+/**
+ * clkdm_clear_all_wkdeps - remove all wakeup dependencies from target clkdm
+ * @clkdm: struct clockdomain * to remove all wakeup dependencies from
+ *
+ * Remove all inter-clockdomain wakeup dependencies that could cause
+ * @clkdm to wake.  Intended to be used during boot to initialize the
+ * PRCM to a known state, after all clockdomains are put into swsup idle
+ * and woken up.  Returns -EINVAL if @clkdm pointer is invalid, or
+ * 0 upon success.
+ */
+int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
+{
+	struct clkdm_dep *cd;
+	u32 mask = 0;
+
+	if (!clkdm)
+		return -EINVAL;
+
+	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
+		if (!omap_chip_is(cd->omap_chip))
+			continue;
+
+		/* PRM accesses are slow, so minimize them */
+		mask |= 1 << cd->clkdm->dep_bit;
+		atomic_set(&cd->wkdep_usecount, 0);
+	}
+
+	prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, PM_WKDEP);
+
+	return 0;
+}
+
+/**
+ * clkdm_add_sleepdep - add a sleep dependency from clkdm2 to clkdm1
+ * @clkdm1: prevent this struct clockdomain * from sleeping (dependent)
+ * @clkdm2: when this struct clockdomain * is active (source)
+ *
+ * Prevent @clkdm1 from automatically going inactive (and then to
+ * retention or off) if @clkdm2 is active.  Returns -EINVAL if
+ * presented with invalid clockdomain pointers or called on a machine
+ * that does not support software-configurable hardware sleep
+ * dependencies, -ENOENT if the specified dependency cannot be set in
+ * hardware, or 0 upon success.
+ */
+int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
+{
+	struct clkdm_dep *cd;
+
+	if (!cpu_is_omap34xx())
+		return -EINVAL;
+
+	if (!clkdm1 || !clkdm2)
+		return -EINVAL;
+
+	cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
+	if (IS_ERR(cd)) {
+		pr_debug("clockdomain: hardware cannot set/clear sleep "
+			 "dependency affecting %s from %s\n", clkdm1->name,
+			 clkdm2->name);
+		return PTR_ERR(cd);
+	}
+
+	if (atomic_inc_return(&cd->sleepdep_usecount) == 1) {
+		pr_debug("clockdomain: will prevent %s from sleeping if %s "
+			 "is active\n", clkdm1->name, clkdm2->name);
+
+		cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
+				    clkdm1->pwrdm.ptr->prcm_offs,
+				    OMAP3430_CM_SLEEPDEP);
+	}
+
+	return 0;
+}
+
+/**
+ * clkdm_del_sleepdep - remove a sleep dependency from clkdm2 to clkdm1
+ * @clkdm1: prevent this struct clockdomain * from sleeping (dependent)
+ * @clkdm2: when this struct clockdomain * is active (source)
+ *
+ * Allow @clkdm1 to automatically go inactive (and then to retention or
+ * off), independent of the activity state of @clkdm2.  Returns -EINVAL
+ * if presented with invalid clockdomain pointers or called on a machine
+ * that does not support software-configurable hardware sleep dependencies,
+ * -ENOENT if the specified dependency cannot be cleared in hardware, or
+ * 0 upon success.
+ */
+int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
+{
+	struct clkdm_dep *cd;
+
+	if (!cpu_is_omap34xx())
+		return -EINVAL;
+
+	if (!clkdm1 || !clkdm2)
+		return -EINVAL;
+
+	cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
+	if (IS_ERR(cd)) {
+		pr_debug("clockdomain: hardware cannot set/clear sleep "
+			 "dependency affecting %s from %s\n", clkdm1->name,
+			 clkdm2->name);
+		return PTR_ERR(cd);
+	}
+
+	if (atomic_dec_return(&cd->sleepdep_usecount) == 0) {
+		pr_debug("clockdomain: will no longer prevent %s from "
+			 "sleeping if %s is active\n", clkdm1->name,
+			 clkdm2->name);
+
+		cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
+				      clkdm1->pwrdm.ptr->prcm_offs,
+				      OMAP3430_CM_SLEEPDEP);
+	}
+
+	return 0;
+}
+
+/**
+ * clkdm_read_sleepdep - read sleep dependency state from clkdm2 to clkdm1
+ * @clkdm1: prevent this struct clockdomain * from sleeping (dependent)
+ * @clkdm2: when this struct clockdomain * is active (source)
+ *
+ * Return 1 if a hardware sleep dependency exists wherein @clkdm1 will
+ * not be allowed to automatically go inactive if @clkdm2 is active;
+ * 0 if @clkdm1's automatic power state inactivity transition is independent
+ * of @clkdm2's; -EINVAL if either clockdomain pointer is invalid or called
+ * on a machine that does not support software-configurable hardware sleep
+ * dependencies; or -ENOENT if the hardware is incapable.
+ *
+ * REVISIT: Currently this function only represents software-controllable
+ * sleep dependencies.	Sleep dependencies fixed in hardware are not
+ * yet handled here.
+ */
+int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
+{
+	struct clkdm_dep *cd;
+
+	if (!cpu_is_omap34xx())
+		return -EINVAL;
+
+	if (!clkdm1 || !clkdm2)
+		return -EINVAL;
+
+	cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
+	if (IS_ERR(cd)) {
+		pr_debug("clockdomain: hardware cannot set/clear sleep "
+			 "dependency affecting %s from %s\n", clkdm1->name,
+			 clkdm2->name);
+		return PTR_ERR(cd);
+	}
+
+	/* XXX It's faster to return the atomic sleepdep_usecount */
+	return prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
+				       OMAP3430_CM_SLEEPDEP,
+				       (1 << clkdm2->dep_bit));
+}
+
+/**
+ * clkdm_clear_all_sleepdeps - remove all sleep dependencies from target clkdm
+ * @clkdm: struct clockdomain * to remove all sleep dependencies from
+ *
+ * Remove all inter-clockdomain sleep dependencies that could prevent
+ * @clkdm from idling.  Intended to be used during boot to initialize the
+ * PRCM to a known state, after all clockdomains are put into swsup idle
+ * and woken up.  Returns -EINVAL if @clkdm pointer is invalid, or
+ * 0 upon success.
+ */
+int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
+{
+	struct clkdm_dep *cd;
+	u32 mask = 0;
+
+	if (!cpu_is_omap34xx())
+		return -EINVAL;
+
+	if (!clkdm)
+		return -EINVAL;
+
+	for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
+		if (!omap_chip_is(cd->omap_chip))
+			continue;
+
+		/* PRM accesses are slow, so minimize them */
+		mask |= 1 << cd->clkdm->dep_bit;
+		atomic_set(&cd->sleepdep_usecount, 0);
+	}
+
+	prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
+			       OMAP3430_CM_SLEEPDEP);
+
+	return 0;
+}
+
+/**
  * omap2_clkdm_clktrctrl_read - read the clkdm's current state transition mode
- * @clk: struct clk * of a clockdomain
+ * @clkdm: struct clkdm * of a clockdomain
  *
- * Return the clockdomain's current state transition mode from the
- * corresponding domain CM_CLKSTCTRL register.	Returns -EINVAL if clk
+ * Return the clockdomain @clkdm current state transition mode from the
+ * corresponding domain CM_CLKSTCTRL register.	Returns -EINVAL if @clkdm
  * is NULL or the current mode upon success.
  */
 static int omap2_clkdm_clktrctrl_read(struct clockdomain *clkdm)
@@ -381,7 +778,7 @@ static int omap2_clkdm_clktrctrl_read(st
 	if (!clkdm)
 		return -EINVAL;
 
-	v = cm_read_mod_reg(clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
+	v = __raw_readl(clkdm->clkstctrl_reg);
 	v &= clkdm->clktrctrl_mask;
 	v >>= __ffs(clkdm->clktrctrl_mask);
 
@@ -393,7 +790,7 @@ static int omap2_clkdm_clktrctrl_read(st
  * @clkdm: struct clockdomain *
  *
  * Instruct the CM to force a sleep transition on the specified
- * clockdomain 'clkdm'.  Returns -EINVAL if clk is NULL or if
+ * clockdomain @clkdm.  Returns -EINVAL if @clkdm is NULL or if
  * clockdomain does not support software-initiated sleep; 0 upon
  * success.
  */
@@ -413,15 +810,17 @@ int omap2_clkdm_sleep(struct clockdomain
 	if (cpu_is_omap24xx()) {
 
 		cm_set_mod_reg_bits(OMAP24XX_FORCESTATE,
-				    clkdm->pwrdm.ptr->prcm_offs, PM_PWSTCTRL);
+			    clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
 
-	} else if (cpu_is_omap34xx()) {
+	} else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
 
-		u32 v = (OMAP34XX_CLKSTCTRL_FORCE_SLEEP <<
+		u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_SLEEP <<
 			 __ffs(clkdm->clktrctrl_mask));
 
-		cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v,
-				    clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
+		u32 v = __raw_readl(clkdm->clkstctrl_reg);
+		v &= ~(clkdm->clktrctrl_mask);
+		v |= bits;
+		__raw_writel(v, clkdm->clkstctrl_reg);
 
 	} else {
 		BUG();
@@ -435,7 +834,7 @@ int omap2_clkdm_sleep(struct clockdomain
  * @clkdm: struct clockdomain *
  *
  * Instruct the CM to force a wakeup transition on the specified
- * clockdomain 'clkdm'.  Returns -EINVAL if clkdm is NULL or if the
+ * clockdomain @clkdm.  Returns -EINVAL if @clkdm is NULL or if the
  * clockdomain does not support software-controlled wakeup; 0 upon
  * success.
  */
@@ -455,15 +854,17 @@ int omap2_clkdm_wakeup(struct clockdomai
 	if (cpu_is_omap24xx()) {
 
 		cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE,
-				      clkdm->pwrdm.ptr->prcm_offs, PM_PWSTCTRL);
+			      clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
 
-	} else if (cpu_is_omap34xx()) {
+	} else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
 
-		u32 v = (OMAP34XX_CLKSTCTRL_FORCE_WAKEUP <<
+		u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_WAKEUP <<
 			 __ffs(clkdm->clktrctrl_mask));
 
-		cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v,
-				    clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
+		u32 v = __raw_readl(clkdm->clkstctrl_reg);
+		v &= ~(clkdm->clktrctrl_mask);
+		v |= bits;
+		__raw_writel(v, clkdm->clkstctrl_reg);
 
 	} else {
 		BUG();
@@ -476,7 +877,7 @@ int omap2_clkdm_wakeup(struct clockdomai
  * omap2_clkdm_allow_idle - enable hwsup idle transitions for clkdm
  * @clkdm: struct clockdomain *
  *
- * Allow the hardware to automatically switch the clockdomain into
+ * Allow the hardware to automatically switch the clockdomain @clkdm into
  * active or idle states, as needed by downstream clocks.  If the
  * clockdomain has any downstream clocks enabled in the clock
  * framework, wkdep/sleepdep autodependencies are added; this is so
@@ -496,8 +897,17 @@ void omap2_clkdm_allow_idle(struct clock
 	pr_debug("clockdomain: enabling automatic idle transitions for %s\n",
 		 clkdm->name);
 
-	if (atomic_read(&clkdm->usecount) > 0)
-		_clkdm_add_autodeps(clkdm);
+	/*
+	 * XXX This should be removed once TI adds wakeup/sleep
+	 * dependency code and data for OMAP4.
+	 */
+	if (cpu_is_omap44xx()) {
+		WARN_ONCE(1, "clockdomain: OMAP4 wakeup/sleep dependency "
+			  "support is not yet implemented\n");
+	} else {
+		if (atomic_read(&clkdm->usecount) > 0)
+			_clkdm_add_autodeps(clkdm);
+	}
 
 	_omap2_clkdm_set_hwsup(clkdm, 1);
 
@@ -509,8 +919,8 @@ void omap2_clkdm_allow_idle(struct clock
  * @clkdm: struct clockdomain *
  *
  * Prevent the hardware from automatically switching the clockdomain
- * into inactive or idle states.  If the clockdomain has downstream
- * clocks enabled in the clock framework, wkdep/sleepdep
+ * @clkdm into inactive or idle states.  If the clockdomain has
+ * downstream clocks enabled in the clock framework, wkdep/sleepdep
  * autodependencies are removed.  No return value.
  */
 void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
@@ -529,8 +939,17 @@ void omap2_clkdm_deny_idle(struct clockd
 
 	_omap2_clkdm_set_hwsup(clkdm, 0);
 
-	if (atomic_read(&clkdm->usecount) > 0)
-		_clkdm_del_autodeps(clkdm);
+	/*
+	 * XXX This should be removed once TI adds wakeup/sleep
+	 * dependency code and data for OMAP4.
+	 */
+	if (cpu_is_omap44xx()) {
+		WARN_ONCE(1, "clockdomain: OMAP4 wakeup/sleep dependency "
+			  "support is not yet implemented\n");
+	} else {
+		if (atomic_read(&clkdm->usecount) > 0)
+			_clkdm_del_autodeps(clkdm);
+	}
 }
 
 
@@ -541,14 +960,14 @@ void omap2_clkdm_deny_idle(struct clockd
  * @clkdm: struct clockdomain *
  * @clk: struct clk * of the enabled downstream clock
  *
- * Increment the usecount of this clockdomain 'clkdm' and ensure that
- * it is awake.  Intended to be called by clk_enable() code.  If the
- * clockdomain is in software-supervised idle mode, force the
- * clockdomain to wake.  If the clockdomain is in hardware-supervised
- * idle mode, add clkdm-pwrdm autodependencies, to ensure that devices
- * in the clockdomain can be read from/written to by on-chip processors.
- * Returns -EINVAL if passed null pointers; returns 0 upon success or
- * if the clockdomain is in hwsup idle mode.
+ * Increment the usecount of the clockdomain @clkdm and ensure that it
+ * is awake before @clk is enabled.  Intended to be called by
+ * clk_enable() code.  If the clockdomain is in software-supervised
+ * idle mode, force the clockdomain to wake.  If the clockdomain is in
+ * hardware-supervised idle mode, add clkdm-pwrdm autodependencies, to
+ * ensure that devices in the clockdomain can be read from/written to
+ * by on-chip processors.  Returns -EINVAL if passed null pointers;
+ * returns 0 upon success or if the clockdomain is in hwsup idle mode.
  */
 int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
 {
@@ -559,7 +978,7 @@ int omap2_clkdm_clk_enable(struct clockd
 	 * downstream clocks for debugging purposes?
 	 */
 
-	if (!clkdm || !clk || !clkdm->clktrctrl_mask)
+	if (!clkdm || !clk)
 		return -EINVAL;
 
 	if (atomic_inc_return(&clkdm->usecount) > 1)
@@ -570,6 +989,9 @@ int omap2_clkdm_clk_enable(struct clockd
 	pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name,
 		 clk->name);
 
+	if (!clkdm->clkstctrl_reg)
+		return 0;
+
 	v = omap2_clkdm_clktrctrl_read(clkdm);
 
 	if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
@@ -593,13 +1015,14 @@ int omap2_clkdm_clk_enable(struct clockd
  * @clkdm: struct clockdomain *
  * @clk: struct clk * of the disabled downstream clock
  *
- * Decrement the usecount of this clockdomain 'clkdm'. Intended to be
- * called by clk_disable() code.  If the usecount goes to 0, put the
- * clockdomain to sleep (software-supervised mode) or remove the
- * clkdm-pwrdm autodependencies (hardware-supervised mode).  Returns
- * -EINVAL if passed null pointers; -ERANGE if the clkdm usecount
- * underflows and debugging is enabled; or returns 0 upon success or
- * if the clockdomain is in hwsup idle mode.
+ * Decrement the usecount of this clockdomain @clkdm when @clk is
+ * disabled.  Intended to be called by clk_disable() code.  If the
+ * clockdomain usecount goes to 0, put the clockdomain to sleep
+ * (software-supervised mode) or remove the clkdm autodependencies
+ * (hardware-supervised mode).  Returns -EINVAL if passed null
+ * pointers; -ERANGE if the @clkdm usecount underflows and debugging
+ * is enabled; or returns 0 upon success or if the clockdomain is in
+ * hwsup idle mode.
  */
 int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
 {
@@ -610,7 +1033,7 @@ int omap2_clkdm_clk_disable(struct clock
 	 * downstream clocks for debugging purposes?
 	 */
 
-	if (!clkdm || !clk || !clkdm->clktrctrl_mask)
+	if (!clkdm || !clk)
 		return -EINVAL;
 
 #ifdef DEBUG
@@ -628,6 +1051,9 @@ int omap2_clkdm_clk_disable(struct clock
 	pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name,
 		 clk->name);
 
+	if (!clkdm->clkstctrl_reg)
+		return 0;
+
 	v = omap2_clkdm_clktrctrl_read(clkdm);
 
 	if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clockdomains44xx.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clockdomains44xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clockdomains44xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clockdomains44xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,250 @@
+/*
+ * OMAP4 Clock domains framework
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Abhijit Pagare (abhijitpagare@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * To-Do List
+ * -> Populate the Sleep/Wakeup dependencies for the domains
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS44XX_H
+
+#include <plat/clockdomain.h>
+
+#if defined(CONFIG_ARCH_OMAP4)
+
+static struct clockdomain l4_cefuse_44xx_clkdm = {
+	.name		  = "l4_cefuse_clkdm",
+	.pwrdm		  = { .name = "cefuse_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_CEFUSE_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l4_cfg_44xx_clkdm = {
+	.name		  = "l4_cfg_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_L4CFG_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_HWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain tesla_44xx_clkdm = {
+	.name		  = "tesla_clkdm",
+	.pwrdm		  = { .name = "tesla_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_TESLA_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_gfx_44xx_clkdm = {
+	.name		  = "l3_gfx_clkdm",
+	.pwrdm		  = { .name = "gfx_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_GFX_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain ivahd_44xx_clkdm = {
+	.name		  = "ivahd_clkdm",
+	.pwrdm		  = { .name = "ivahd_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_IVAHD_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l4_secure_44xx_clkdm = {
+	.name		  = "l4_secure_clkdm",
+	.pwrdm		  = { .name = "l4per_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_L4SEC_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l4_per_44xx_clkdm = {
+	.name		  = "l4_per_clkdm",
+	.pwrdm		  = { .name = "l4per_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_L4PER_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain abe_44xx_clkdm = {
+	.name		  = "abe_clkdm",
+	.pwrdm		  = { .name = "abe_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM1_ABE_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_instr_44xx_clkdm = {
+	.name		  = "l3_instr_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_L3INSTR_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_init_44xx_clkdm = {
+	.name		  = "l3_init_clkdm",
+	.pwrdm		  = { .name = "l3init_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_L3INIT_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain mpuss_44xx_clkdm = {
+	.name		  = "mpuss_clkdm",
+	.pwrdm		  = { .name = "mpu_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_MPU_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain mpu0_44xx_clkdm = {
+	.name		  = "mpu0_clkdm",
+	.pwrdm		  = { .name = "cpu0_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_PDA_CPU0_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain mpu1_44xx_clkdm = {
+	.name		  = "mpu1_clkdm",
+	.pwrdm		  = { .name = "cpu1_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_PDA_CPU1_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_emif_44xx_clkdm = {
+	.name		  = "l3_emif_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_MEMIF_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l4_ao_44xx_clkdm = {
+	.name		  = "l4_ao_clkdm",
+	.pwrdm		  = { .name = "always_on_core_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_ALWON_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain ducati_44xx_clkdm = {
+	.name		  = "ducati_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_DUCATI_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_2_44xx_clkdm = {
+	.name		  = "l3_2_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_L3_2_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_HWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_1_44xx_clkdm = {
+	.name		  = "l3_1_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_L3_1_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_HWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_d2d_44xx_clkdm = {
+	.name		  = "l3_d2d_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_D2D_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain iss_44xx_clkdm = {
+	.name		  = "iss_clkdm",
+	.pwrdm		  = { .name = "cam_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_CAM_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_dss_44xx_clkdm = {
+	.name		  = "l3_dss_clkdm",
+	.pwrdm		  = { .name = "dss_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_DSS_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l4_wkup_44xx_clkdm = {
+	.name		  = "l4_wkup_clkdm",
+	.pwrdm		  = { .name = "wkup_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_WKUP_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_HWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain emu_sys_44xx_clkdm = {
+	.name		  = "emu_sys_clkdm",
+	.pwrdm		  = { .name = "emu_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_EMU_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_HWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_dma_44xx_clkdm = {
+	.name		  = "l3_dma_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.clkstctrl_reg	  = OMAP4430_CM_SDMA_CLKSTCTRL,
+	.clktrctrl_mask	  = OMAP4430_CLKTRCTRL_MASK,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+#endif
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clockdomains.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clockdomains.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clockdomains.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clockdomains.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,16 +1,420 @@
 /*
  * OMAP2/3 clockdomains
  *
- * Copyright (C) 2008 Texas Instruments, Inc.
- * Copyright (C) 2008 Nokia Corporation
+ * Copyright (C) 2008-2009 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
  *
- * Written by Paul Walmsley
+ * Written by Paul Walmsley and Jouni HÃ¶gander
+ *
+ * This file contains clockdomains and clockdomain wakeup/sleep
+ * dependencies for the OMAP2/3 chips.  Some notes:
+ *
+ * A useful validation rule for struct clockdomain: Any clockdomain
+ * referenced by a wkdep_srcs or sleepdep_srcs array must have a
+ * dep_bit assigned.  So wkdep_srcs/sleepdep_srcs are really just
+ * software-controllable dependencies.  Non-software-controllable
+ * dependencies do exist, but they are not encoded below (yet).
+ *
+ * 24xx does not support programmable sleep dependencies (SLEEPDEP)
+ *
+ * The overly-specific dep_bit names are due to a bit name collision
+ * with CM_FCLKEN_{DSP,IVA2}.  The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift
+ * value are the same for all powerdomains: 2
+ *
+ * XXX should dep_bit be a mask, so we can test to see if it is 0 as a
+ * sanity check?
+ * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
+ */
+
+/*
+ * To-Do List
+ * -> Port the Sleep/Wakeup dependencies for the domains
+ *    from the Power domain framework
  */
 
 #ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H
 #define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H
 
 #include <plat/clockdomain.h>
+#include "cm.h"
+#include "prm.h"
+
+/*
+ * Clockdomain dependencies for wkdeps/sleepdeps
+ *
+ * XXX Hardware dependencies (e.g., dependencies that cannot be
+ * changed in software) are not included here yet, but should be.
+ */
+
+/* OMAP2/3-common wakeup dependencies */
+
+/*
+ * 2420/2430 PM_WKDEP_GFX: CORE, MPU, WKUP
+ * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
+ * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
+ * These can share data since they will never be present simultaneously
+ * on the same device.
+ */
+static struct clkdm_dep gfx_sgx_wkdeps[] = {
+	{
+		.clkdm_name = "core_l3_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "core_l4_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "iva2_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "mpu_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
+					    CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "wkup_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
+					    CHIP_IS_OMAP3430)
+	},
+	{ NULL },
+};
+
+
+/* 24XX-specific possible dependencies */
+
+#ifdef CONFIG_ARCH_OMAP2
+
+/* Wakeup dependency source arrays */
+
+/* 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP */
+static struct clkdm_dep dsp_24xx_wkdeps[] = {
+	{
+		.clkdm_name = "core_l3_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "core_l4_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "mpu_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "wkup_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{ NULL },
+};
+
+/*
+ * 2420 PM_WKDEP_MPU: CORE, DSP, WKUP
+ * 2430 adds MDM
+ */
+static struct clkdm_dep mpu_24xx_wkdeps[] = {
+	{
+		.clkdm_name = "core_l3_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "core_l4_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "dsp_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "wkup_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "mdm_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+	},
+	{ NULL },
+};
+
+/*
+ * 2420 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP
+ * 2430 adds MDM
+ */
+static struct clkdm_dep core_24xx_wkdeps[] = {
+	{
+		.clkdm_name = "dsp_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "gfx_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "mpu_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "wkup_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "mdm_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+	},
+	{ NULL },
+};
+
+#endif
+
+
+/* 2430-specific possible wakeup dependencies */
+
+#ifdef CONFIG_ARCH_OMAP2430
+
+/* 2430 PM_WKDEP_MDM: CORE, MPU, WKUP */
+static struct clkdm_dep mdm_2430_wkdeps[] = {
+	{
+		.clkdm_name = "core_l3_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "core_l4_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "mpu_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{
+		.clkdm_name = "wkup_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+	},
+	{ NULL },
+};
+
+#endif /* CONFIG_ARCH_OMAP2430 */
+
+
+/* OMAP3-specific possible dependencies */
+
+#ifdef CONFIG_ARCH_OMAP3
+
+/* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */
+static struct clkdm_dep per_wkdeps[] = {
+	{
+		.clkdm_name = "core_l3_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "core_l4_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "iva2_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "mpu_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "wkup_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{ NULL },
+};
+
+/* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */
+static struct clkdm_dep usbhost_wkdeps[] = {
+	{
+		.clkdm_name = "core_l3_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "core_l4_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "iva2_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "mpu_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "wkup_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{ NULL },
+};
+
+/* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */
+static struct clkdm_dep mpu_3xxx_wkdeps[] = {
+	{
+		.clkdm_name = "core_l3_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "core_l4_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "iva2_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "dss_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "per_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{ NULL },
+};
+
+/* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */
+static struct clkdm_dep iva2_wkdeps[] = {
+	{
+		.clkdm_name = "core_l3_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "core_l4_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "mpu_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "wkup_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "dss_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "per_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{ NULL },
+};
+
+
+/* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */
+static struct clkdm_dep cam_wkdeps[] = {
+	{
+		.clkdm_name = "iva2_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "mpu_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "wkup_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{ NULL },
+};
+
+/* 3430 PM_WKDEP_DSS: IVA2, MPU, WKUP */
+static struct clkdm_dep dss_wkdeps[] = {
+	{
+		.clkdm_name = "iva2_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "mpu_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "wkup_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{ NULL },
+};
+
+/* 3430: PM_WKDEP_NEON: MPU */
+static struct clkdm_dep neon_wkdeps[] = {
+	{
+		.clkdm_name = "mpu_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{ NULL },
+};
+
+
+/* Sleep dependency source arrays for OMAP3-specific clkdms */
+
+/* 3430: CM_SLEEPDEP_DSS: MPU, IVA */
+static struct clkdm_dep dss_sleepdeps[] = {
+	{
+		.clkdm_name = "mpu_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "iva2_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{ NULL },
+};
+
+/* 3430: CM_SLEEPDEP_PER: MPU, IVA */
+static struct clkdm_dep per_sleepdeps[] = {
+	{
+		.clkdm_name = "mpu_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "iva2_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{ NULL },
+};
+
+/* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
+static struct clkdm_dep usbhost_sleepdeps[] = {
+	{
+		.clkdm_name = "mpu_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{
+		.clkdm_name = "iva2_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{ NULL },
+};
+
+/* 3430: CM_SLEEPDEP_CAM: MPU */
+static struct clkdm_dep cam_sleepdeps[] = {
+	{
+		.clkdm_name = "mpu_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{ NULL },
+};
+
+/*
+ * 3430ES1: CM_SLEEPDEP_GFX: MPU
+ * 3430ES2: CM_SLEEPDEP_SGX: MPU
+ * These can share data since they will never be present simultaneously
+ * on the same device.
+ */
+static struct clkdm_dep gfx_sgx_sleepdeps[] = {
+	{
+		.clkdm_name = "mpu_clkdm",
+		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+	},
+	{ NULL },
+};
+
+#endif /* CONFIG_ARCH_OMAP3 */
+
 
 /*
  * OMAP2/3-common clockdomains
@@ -21,10 +425,13 @@
  * sys_clkout/sys_clkout2.
  */
 
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+
 /* 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" },
+	.dep_bit	= OMAP_EN_WKUP_SHIFT,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
 };
 
@@ -40,6 +447,8 @@ static struct clockdomain cm_clkdm = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
 };
 
+#endif
+
 /*
  * 2420-only clockdomains
  */
@@ -50,6 +459,8 @@ static struct clockdomain mpu_2420_clkdm
 	.name		= "mpu_clkdm",
 	.pwrdm		= { .name = "mpu_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP,
+	.clkstctrl_reg  = OMAP2420_CM_REGADDR(MPU_MOD, OMAP2_CM_CLKSTCTRL),
+	.wkdep_srcs	= mpu_24xx_wkdeps,
 	.clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
 };
@@ -58,11 +469,64 @@ static struct clockdomain iva1_2420_clkd
 	.name		= "iva1_clkdm",
 	.pwrdm		= { .name = "dsp_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg  = OMAP2420_CM_REGADDR(OMAP24XX_DSP_MOD,
+						 OMAP2_CM_CLKSTCTRL),
+	.dep_bit	= OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
+	.wkdep_srcs	= dsp_24xx_wkdeps,
 	.clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
 };
 
-#endif  /* CONFIG_ARCH_OMAP2420 */
+static struct clockdomain dsp_2420_clkdm = {
+	.name		= "dsp_clkdm",
+	.pwrdm		= { .name = "dsp_pwrdm" },
+	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg  = OMAP2420_CM_REGADDR(OMAP24XX_DSP_MOD,
+						 OMAP2_CM_CLKSTCTRL),
+	.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+static struct clockdomain gfx_2420_clkdm = {
+	.name		= "gfx_clkdm",
+	.pwrdm		= { .name = "gfx_pwrdm" },
+	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg  = OMAP2420_CM_REGADDR(GFX_MOD, OMAP2_CM_CLKSTCTRL),
+	.wkdep_srcs	= gfx_sgx_wkdeps,
+	.clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+static struct clockdomain core_l3_2420_clkdm = {
+	.name		= "core_l3_clkdm",
+	.pwrdm		= { .name = "core_pwrdm" },
+	.flags		= CLKDM_CAN_HWSUP,
+	.clkstctrl_reg  = OMAP2420_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
+	.wkdep_srcs	= core_24xx_wkdeps,
+	.clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+static struct clockdomain core_l4_2420_clkdm = {
+	.name		= "core_l4_clkdm",
+	.pwrdm		= { .name = "core_pwrdm" },
+	.flags		= CLKDM_CAN_HWSUP,
+	.clkstctrl_reg  = OMAP2420_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
+	.wkdep_srcs	= core_24xx_wkdeps,
+	.clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+static struct clockdomain dss_2420_clkdm = {
+	.name		= "dss_clkdm",
+	.pwrdm		= { .name = "core_pwrdm" },
+	.flags		= CLKDM_CAN_HWSUP,
+	.clkstctrl_reg  = OMAP2420_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
+	.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+#endif   /* CONFIG_ARCH_OMAP2420 */
 
 
 /*
@@ -75,80 +539,105 @@ static struct clockdomain mpu_2430_clkdm
 	.name		= "mpu_clkdm",
 	.pwrdm		= { .name = "mpu_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg  = OMAP2430_CM_REGADDR(MPU_MOD,
+						 OMAP2_CM_CLKSTCTRL),
+	.wkdep_srcs	= mpu_24xx_wkdeps,
 	.clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
 };
 
+/* Another case of bit name collisions between several registers: EN_MDM */
 static struct clockdomain mdm_clkdm = {
 	.name		= "mdm_clkdm",
 	.pwrdm		= { .name = "mdm_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg  = OMAP2430_CM_REGADDR(OMAP2430_MDM_MOD,
+						 OMAP2_CM_CLKSTCTRL),
+	.dep_bit	= OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT,
+	.wkdep_srcs	= mdm_2430_wkdeps,
 	.clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
 };
 
-#endif    /* CONFIG_ARCH_OMAP2430 */
-
-
-/*
- * 24XX-only clockdomains
- */
-
-#if defined(CONFIG_ARCH_OMAP24XX)
-
-static struct clockdomain dsp_clkdm = {
+static struct clockdomain dsp_2430_clkdm = {
 	.name		= "dsp_clkdm",
 	.pwrdm		= { .name = "dsp_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg  = OMAP2430_CM_REGADDR(OMAP24XX_DSP_MOD,
+						 OMAP2_CM_CLKSTCTRL),
+	.dep_bit	= OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
+	.wkdep_srcs	= dsp_24xx_wkdeps,
 	.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
 };
 
-static struct clockdomain gfx_24xx_clkdm = {
+static struct clockdomain gfx_2430_clkdm = {
 	.name		= "gfx_clkdm",
 	.pwrdm		= { .name = "gfx_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg  = OMAP2430_CM_REGADDR(GFX_MOD, OMAP2_CM_CLKSTCTRL),
+	.wkdep_srcs	= gfx_sgx_wkdeps,
 	.clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
 };
 
-static struct clockdomain core_l3_24xx_clkdm = {
+/*
+ * XXX add usecounting for clkdm dependencies, otherwise the presence
+ * of a single dep bit for core_l3_24xx_clkdm and core_l4_24xx_clkdm
+ * could cause trouble
+ */
+static struct clockdomain core_l3_2430_clkdm = {
 	.name		= "core_l3_clkdm",
 	.pwrdm		= { .name = "core_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP,
+	.clkstctrl_reg  = OMAP2430_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
+	.dep_bit	= OMAP24XX_EN_CORE_SHIFT,
+	.wkdep_srcs	= core_24xx_wkdeps,
 	.clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
 };
 
-static struct clockdomain core_l4_24xx_clkdm = {
+/*
+ * XXX add usecounting for clkdm dependencies, otherwise the presence
+ * of a single dep bit for core_l3_24xx_clkdm and core_l4_24xx_clkdm
+ * could cause trouble
+ */
+static struct clockdomain core_l4_2430_clkdm = {
 	.name		= "core_l4_clkdm",
 	.pwrdm		= { .name = "core_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP,
+	.clkstctrl_reg  = OMAP2430_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
+	.dep_bit	= OMAP24XX_EN_CORE_SHIFT,
+	.wkdep_srcs	= core_24xx_wkdeps,
 	.clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
 };
 
-static struct clockdomain dss_24xx_clkdm = {
+static struct clockdomain dss_2430_clkdm = {
 	.name		= "dss_clkdm",
 	.pwrdm		= { .name = "core_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP,
+	.clkstctrl_reg  = OMAP2430_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
 	.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
 };
 
-#endif   /* CONFIG_ARCH_OMAP24XX */
+#endif    /* CONFIG_ARCH_OMAP2430 */
 
 
 /*
- * 34xx clockdomains
+ * OMAP3 clockdomains
  */
 
-#if defined(CONFIG_ARCH_OMAP34XX)
+#if defined(CONFIG_ARCH_OMAP3)
 
-static struct clockdomain mpu_34xx_clkdm = {
+static struct clockdomain mpu_3xxx_clkdm = {
 	.name		= "mpu_clkdm",
 	.pwrdm		= { .name = "mpu_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
+	.clkstctrl_reg	= OMAP34XX_CM_REGADDR(MPU_MOD, OMAP2_CM_CLKSTCTRL),
+	.dep_bit	= OMAP3430_EN_MPU_SHIFT,
+	.wkdep_srcs	= mpu_3xxx_wkdeps,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
@@ -157,6 +646,9 @@ static struct clockdomain neon_clkdm = {
 	.name		= "neon_clkdm",
 	.pwrdm		= { .name = "neon_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg	= OMAP34XX_CM_REGADDR(OMAP3430_NEON_MOD,
+						 OMAP2_CM_CLKSTCTRL),
+	.wkdep_srcs	= neon_wkdeps,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
@@ -165,6 +657,10 @@ static struct clockdomain iva2_clkdm = {
 	.name		= "iva2_clkdm",
 	.pwrdm		= { .name = "iva2_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg	= OMAP34XX_CM_REGADDR(OMAP3430_IVA2_MOD,
+						 OMAP2_CM_CLKSTCTRL),
+	.dep_bit	= OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
+	.wkdep_srcs	= iva2_wkdeps,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
@@ -173,6 +669,9 @@ static struct clockdomain gfx_3430es1_cl
 	.name		= "gfx_clkdm",
 	.pwrdm		= { .name = "gfx_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg	= OMAP34XX_CM_REGADDR(GFX_MOD, OMAP2_CM_CLKSTCTRL),
+	.wkdep_srcs	= gfx_sgx_wkdeps,
+	.sleepdep_srcs	= gfx_sgx_sleepdeps,
 	.clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1),
 };
@@ -181,6 +680,10 @@ static struct clockdomain sgx_clkdm = {
 	.name		= "sgx_clkdm",
 	.pwrdm		= { .name = "sgx_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg	= OMAP34XX_CM_REGADDR(OMAP3430ES2_SGX_MOD,
+						 OMAP2_CM_CLKSTCTRL),
+	.wkdep_srcs	= gfx_sgx_wkdeps,
+	.sleepdep_srcs	= gfx_sgx_sleepdeps,
 	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
 };
@@ -196,30 +699,51 @@ static struct clockdomain d2d_clkdm = {
 	.name		= "d2d_clkdm",
 	.pwrdm		= { .name = "core_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg	= OMAP34XX_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
 	.clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
 
-static struct clockdomain core_l3_34xx_clkdm = {
+/*
+ * XXX add usecounting for clkdm dependencies, otherwise the presence
+ * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
+ * could cause trouble
+ */
+static struct clockdomain core_l3_3xxx_clkdm = {
 	.name		= "core_l3_clkdm",
 	.pwrdm		= { .name = "core_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP,
+	.clkstctrl_reg	= OMAP34XX_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
+	.dep_bit	= OMAP3430_EN_CORE_SHIFT,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
 
-static struct clockdomain core_l4_34xx_clkdm = {
+/*
+ * XXX add usecounting for clkdm dependencies, otherwise the presence
+ * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
+ * could cause trouble
+ */
+static struct clockdomain core_l4_3xxx_clkdm = {
 	.name		= "core_l4_clkdm",
 	.pwrdm		= { .name = "core_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP,
+	.clkstctrl_reg	= OMAP34XX_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
+	.dep_bit	= OMAP3430_EN_CORE_SHIFT,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
 
-static struct clockdomain dss_34xx_clkdm = {
+/* Another case of bit name collisions between several registers: EN_DSS */
+static struct clockdomain dss_3xxx_clkdm = {
 	.name		= "dss_clkdm",
 	.pwrdm		= { .name = "dss_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg	= OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD,
+						 OMAP2_CM_CLKSTCTRL),
+	.dep_bit	= OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
+	.wkdep_srcs	= dss_wkdeps,
+	.sleepdep_srcs	= dss_sleepdeps,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
@@ -228,6 +752,10 @@ static struct clockdomain cam_clkdm = {
 	.name		= "cam_clkdm",
 	.pwrdm		= { .name = "cam_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg	= OMAP34XX_CM_REGADDR(OMAP3430_CAM_MOD,
+						 OMAP2_CM_CLKSTCTRL),
+	.wkdep_srcs	= cam_wkdeps,
+	.sleepdep_srcs	= cam_sleepdeps,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
@@ -236,6 +764,10 @@ static struct clockdomain usbhost_clkdm
 	.name		= "usbhost_clkdm",
 	.pwrdm		= { .name = "usbhost_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg	= OMAP34XX_CM_REGADDR(OMAP3430ES2_USBHOST_MOD,
+						 OMAP2_CM_CLKSTCTRL),
+	.wkdep_srcs	= usbhost_wkdeps,
+	.sleepdep_srcs	= usbhost_sleepdeps,
 	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
 };
@@ -244,6 +776,11 @@ static struct clockdomain per_clkdm = {
 	.name		= "per_clkdm",
 	.pwrdm		= { .name = "per_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.clkstctrl_reg	= OMAP34XX_CM_REGADDR(OMAP3430_PER_MOD,
+						 OMAP2_CM_CLKSTCTRL),
+	.dep_bit	= OMAP3430_EN_PER_SHIFT,
+	.wkdep_srcs	= per_wkdeps,
+	.sleepdep_srcs	= per_sleepdeps,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
@@ -256,6 +793,8 @@ static struct clockdomain emu_clkdm = {
 	.name		= "emu_clkdm",
 	.pwrdm		= { .name = "emu_pwrdm" },
 	.flags		= /* CLKDM_CAN_ENABLE_AUTO |  */CLKDM_CAN_SWSUP,
+	.clkstctrl_reg	= OMAP34XX_CM_REGADDR(OMAP3430_EMU_MOD,
+						 OMAP2_CM_CLKSTCTRL),
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
@@ -290,64 +829,70 @@ static struct clockdomain dpll5_clkdm =
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
 };
 
-#endif   /* CONFIG_ARCH_OMAP34XX */
+#endif   /* CONFIG_ARCH_OMAP3 */
+
+#include "clockdomains44xx.h"
 
 /*
- * Clockdomain-powerdomain hwsup dependencies (34XX only)
+ * Clockdomain hwsup dependencies (OMAP3 only)
  */
 
-static struct clkdm_pwrdm_autodep clkdm_pwrdm_autodeps[] = {
+static struct clkdm_autodep clkdm_autodeps[] = {
 	{
-		.pwrdm	   = { .name = "mpu_pwrdm" },
+		.clkdm	   = { .name = "mpu_clkdm" },
 		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
 	},
 	{
-		.pwrdm	   = { .name = "iva2_pwrdm" },
+		.clkdm	   = { .name = "iva2_clkdm" },
 		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
 	},
 	{
-		.pwrdm	   = { .name = NULL },
+		.clkdm	   = { .name = NULL },
 	}
 };
 
 /*
- *
+ * List of clockdomain pointers per platform
  */
 
 static struct clockdomain *clockdomains_omap[] = {
 
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 	&wkup_clkdm,
 	&cm_clkdm,
 	&prm_clkdm,
+#endif
 
 #ifdef CONFIG_ARCH_OMAP2420
 	&mpu_2420_clkdm,
 	&iva1_2420_clkdm,
+	&dsp_2420_clkdm,
+	&gfx_2420_clkdm,
+	&core_l3_2420_clkdm,
+	&core_l4_2420_clkdm,
+	&dss_2420_clkdm,
 #endif
 
 #ifdef CONFIG_ARCH_OMAP2430
 	&mpu_2430_clkdm,
 	&mdm_clkdm,
+	&dsp_2430_clkdm,
+	&gfx_2430_clkdm,
+	&core_l3_2430_clkdm,
+	&core_l4_2430_clkdm,
+	&dss_2430_clkdm,
 #endif
 
-#ifdef CONFIG_ARCH_OMAP24XX
-	&dsp_clkdm,
-	&gfx_24xx_clkdm,
-	&core_l3_24xx_clkdm,
-	&core_l4_24xx_clkdm,
-	&dss_24xx_clkdm,
-#endif
-
-#ifdef CONFIG_ARCH_OMAP34XX
-	&mpu_34xx_clkdm,
+#ifdef CONFIG_ARCH_OMAP3
+	&mpu_3xxx_clkdm,
 	&neon_clkdm,
 	&iva2_clkdm,
 	&gfx_3430es1_clkdm,
 	&sgx_clkdm,
 	&d2d_clkdm,
-	&core_l3_34xx_clkdm,
-	&core_l4_34xx_clkdm,
-	&dss_34xx_clkdm,
+	&core_l3_3xxx_clkdm,
+	&core_l4_3xxx_clkdm,
+	&dss_3xxx_clkdm,
 	&cam_clkdm,
 	&usbhost_clkdm,
 	&per_clkdm,
@@ -359,6 +904,33 @@ static struct clockdomain *clockdomains_
 	&dpll5_clkdm,
 #endif
 
+#ifdef CONFIG_ARCH_OMAP4
+	&l4_cefuse_44xx_clkdm,
+	&l4_cfg_44xx_clkdm,
+	&tesla_44xx_clkdm,
+	&l3_gfx_44xx_clkdm,
+	&ivahd_44xx_clkdm,
+	&l4_secure_44xx_clkdm,
+	&l4_per_44xx_clkdm,
+	&abe_44xx_clkdm,
+	&l3_instr_44xx_clkdm,
+	&l3_init_44xx_clkdm,
+	&mpuss_44xx_clkdm,
+	&mpu0_44xx_clkdm,
+	&mpu1_44xx_clkdm,
+	&l3_emif_44xx_clkdm,
+	&l4_ao_44xx_clkdm,
+	&ducati_44xx_clkdm,
+	&l3_2_44xx_clkdm,
+	&l3_1_44xx_clkdm,
+	&l3_d2d_44xx_clkdm,
+	&iss_44xx_clkdm,
+	&l3_dss_44xx_clkdm,
+	&l4_wkup_44xx_clkdm,
+	&emu_sys_44xx_clkdm,
+	&l3_dma_44xx_clkdm,
+#endif
+
 	NULL,
 };
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -47,7 +47,10 @@
 #define DPLL_LOW_POWER_BYPASS	0x5
 #define DPLL_LOCKED		0x7
 
-int omap2_clk_init(void);
+/* DPLL Type and DCO Selection Flags */
+#define DPLL_J_TYPE		0x1
+#define DPLL_NO_DCO_SEL		0x2
+
 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);
@@ -78,23 +81,53 @@ 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);
-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);
+int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent);
 u32 omap2_get_dpll_rate(struct clk *clk);
 void omap2_init_dpll_parent(struct clk *clk);
 int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name);
-void omap2_clk_prepare_for_reboot(void);
+
+
+#ifdef CONFIG_ARCH_OMAP2
+void omap2xxx_clk_prepare_for_reboot(void);
+#else
+static inline void omap2xxx_clk_prepare_for_reboot(void)
+{
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+void omap3_clk_prepare_for_reboot(void);
+#else
+static inline void omap3_clk_prepare_for_reboot(void)
+{
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+void omap4_clk_prepare_for_reboot(void);
+#else
+static inline void omap4_clk_prepare_for_reboot(void)
+{
+}
+#endif
+
 int omap2_dflt_clk_enable(struct clk *clk);
 void omap2_dflt_clk_disable(struct clk *clk);
 void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
 				   u8 *other_bit);
 void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
-				u8 *idlest_bit);
+				u8 *idlest_bit, u8 *idlest_val);
+int omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name);
+void omap2_clk_print_new_rates(const char *hfclkin_ck_name,
+			       const char *core_ck_name,
+			       const char *mpu_ck_name);
 
 extern u8 cpu_mask;
 
 extern const struct clkops clkops_omap2_dflt_wait;
+extern const struct clkops clkops_dummy;
 extern const struct clkops clkops_omap2_dflt;
 
 extern struct clk_functions omap2_clk_functions;
@@ -104,5 +137,14 @@ extern const struct clksel_rate gpt_32k_
 extern const struct clksel_rate gpt_sys_rates[];
 extern const struct clksel_rate gfx_l3_rates[];
 
+#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ)
+extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
+extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
+#else
+#define omap2_clk_init_cpufreq_table	0
+#define omap2_clk_exit_cpufreq_table	0
+#endif
+
+extern const struct clkops clkops_omap3_noncore_dpll_ops;
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cm.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/cm.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/cm.h	2010-05-16 17:17:36.000000000 -0400
@@ -67,7 +67,8 @@
 #define CM_CLKSEL					0x0040
 #define CM_CLKSEL1					CM_CLKSEL
 #define CM_CLKSEL2					0x0044
-#define CM_CLKSTCTRL					0x0048
+#define OMAP2_CM_CLKSTCTRL				0x0048
+#define OMAP4_CM_CLKSTCTRL				0x0000
 
 
 /* Architecture-specific registers */
@@ -88,7 +89,7 @@
 #define OMAP3430_CM_CLKSEL1_PLL				CM_CLKSEL
 #define OMAP3430_CM_CLKSEL2_PLL				CM_CLKSEL2
 #define OMAP3430_CM_SLEEPDEP				CM_CLKSEL2
-#define OMAP3430_CM_CLKSEL3				CM_CLKSTCTRL
+#define OMAP3430_CM_CLKSEL3				OMAP2_CM_CLKSTCTRL
 #define OMAP3430_CM_CLKSTST				0x004c
 #define OMAP3430ES2_CM_CLKSEL4				0x004c
 #define OMAP3430ES2_CM_CLKSEL5				0x0050
@@ -138,5 +139,8 @@ static inline u32 cm_clear_mod_reg_bits(
 /* CM_IDLEST_GFX */
 #define OMAP_ST_GFX					(1 << 0)
 
+/* CM_IDLEST indicator */
+#define OMAP24XX_CM_IDLEST_VAL		0
+#define OMAP34XX_CM_IDLEST_VAL		1
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cm-regbits-34xx.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/cm-regbits-34xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cm-regbits-34xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/cm-regbits-34xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -55,7 +55,7 @@
 /* Bits specific to each register */
 
 /* CM_FCLKEN_IVA2 */
-#define OMAP3430_CM_FCLKEN_IVA2_EN_IVA2			(1 << 0)
+#define OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK		(1 << 0)
 #define OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT		0
 
 /* CM_CLKEN_PLL_IVA2 */
@@ -168,6 +168,12 @@
 #define OMAP3430_EN_SDRC				(1 << 1)
 #define OMAP3430_EN_SDRC_SHIFT				1
 
+/* AM35XX specific CM_ICLKEN1_CORE bits */
+#define AM35XX_EN_IPSS_MASK				(1 << 4)
+#define AM35XX_EN_IPSS_SHIFT				4
+#define AM35XX_EN_UART4_MASK			(1 << 23)
+#define AM35XX_EN_UART4_SHIFT				23
+
 /* CM_ICLKEN2_CORE */
 #define OMAP3430_EN_PKA					(1 << 4)
 #define OMAP3430_EN_PKA_SHIFT				4
@@ -220,6 +226,10 @@
 #define OMAP3430_ST_SSI_STDBY_SHIFT			0
 #define OMAP3430_ST_SSI_STDBY_MASK			(1 << 0)
 
+/* AM35xx specific CM_IDLEST1_CORE bits */
+#define AM35XX_ST_IPSS_SHIFT				5
+#define AM35XX_ST_IPSS_MASK 				(1 << 5)
+
 /* CM_IDLEST2_CORE */
 #define OMAP3430_ST_PKA_SHIFT				4
 #define OMAP3430_ST_PKA_MASK				(1 << 4)
@@ -336,6 +346,8 @@
 #define OMAP3430_CLKSEL_L4_MASK				(0x3 << 2)
 #define OMAP3430_CLKSEL_L3_SHIFT			0
 #define OMAP3430_CLKSEL_L3_MASK				(0x3 << 0)
+#define OMAP3630_CLKSEL_96M_SHIFT			12
+#define OMAP3630_CLKSEL_96M_MASK			(0x3 << 12)
 
 /* CM_CLKSTCTRL_CORE */
 #define OMAP3430ES1_CLKTRCTRL_D2D_SHIFT			4
@@ -379,6 +391,10 @@
 #define OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT		1
 #define OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_MASK		(1 << 1)
 
+/* CM_IDLEST_SGX */
+#define OMAP3430ES2_ST_SGX_SHIFT			1
+#define OMAP3430ES2_ST_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)
@@ -517,12 +533,18 @@
 /* CM_CLKSEL2_PLL */
 #define OMAP3430_PERIPH_DPLL_MULT_SHIFT			8
 #define OMAP3430_PERIPH_DPLL_MULT_MASK			(0x7ff << 8)
+#define OMAP3630_PERIPH_DPLL_MULT_MASK			(0xfff << 8)
 #define OMAP3430_PERIPH_DPLL_DIV_SHIFT			0
 #define OMAP3430_PERIPH_DPLL_DIV_MASK			(0x7f << 0)
+#define OMAP3630_PERIPH_DPLL_DCO_SEL_SHIFT		21
+#define OMAP3630_PERIPH_DPLL_DCO_SEL_MASK		(0x7 << 21)
+#define OMAP3630_PERIPH_DPLL_SD_DIV_SHIFT		24
+#define OMAP3630_PERIPH_DPLL_SD_DIV_MASK		(0xff << 24)
 
 /* CM_CLKSEL3_PLL */
 #define OMAP3430_DIV_96M_SHIFT				0
 #define OMAP3430_DIV_96M_MASK				(0x1f << 0)
+#define OMAP3630_DIV_96M_MASK				(0x3f << 0)
 
 /* CM_CLKSEL4_PLL */
 #define OMAP3430ES2_PERIPH2_DPLL_MULT_SHIFT		8
@@ -569,8 +591,10 @@
 /* CM_CLKSEL_DSS */
 #define OMAP3430_CLKSEL_TV_SHIFT			8
 #define OMAP3430_CLKSEL_TV_MASK				(0x1f << 8)
+#define OMAP3630_CLKSEL_TV_MASK				(0x3f << 8)
 #define OMAP3430_CLKSEL_DSS1_SHIFT			0
 #define OMAP3430_CLKSEL_DSS1_MASK			(0x1f << 0)
+#define OMAP3630_CLKSEL_DSS1_MASK			(0x3f << 0)
 
 /* CM_SLEEPDEP_DSS specific bits */
 
@@ -598,6 +622,7 @@
 /* CM_CLKSEL_CAM */
 #define OMAP3430_CLKSEL_CAM_SHIFT			0
 #define OMAP3430_CLKSEL_CAM_MASK			(0x1f << 0)
+#define OMAP3630_CLKSEL_CAM_MASK			(0x3f << 0)
 
 /* CM_SLEEPDEP_CAM specific bits */
 
@@ -693,6 +718,7 @@
 /* CM_CLKSEL1_EMU */
 #define OMAP3430_DIV_DPLL4_SHIFT			24
 #define OMAP3430_DIV_DPLL4_MASK				(0x1f << 24)
+#define OMAP3630_DIV_DPLL4_MASK				(0x3f << 24)
 #define OMAP3430_DIV_DPLL3_SHIFT			16
 #define OMAP3430_DIV_DPLL3_MASK				(0x1f << 16)
 #define OMAP3430_CLKSEL_TRACECLK_SHIFT			11
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cm-regbits-44xx.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/cm-regbits-44xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cm-regbits-44xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/cm-regbits-44xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,7 @@
 
 
 /* Used by CM_L3_1_DYNAMICDEP, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP */
-#define OMAP4430_ABE_DYNDEP_SHIFT				(1 << 3)
+#define OMAP4430_ABE_DYNDEP_SHIFT				3
 #define OMAP4430_ABE_DYNDEP_MASK				BITFIELD(3, 3)
 
 /*
@@ -34,15 +34,15 @@
  * CM_L3INIT_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP,
  * CM_TESLA_STATICDEP
  */
-#define OMAP4430_ABE_STATDEP_SHIFT				(1 << 3)
+#define OMAP4430_ABE_STATDEP_SHIFT				3
 #define OMAP4430_ABE_STATDEP_MASK				BITFIELD(3, 3)
 
 /* Used by CM_L4CFG_DYNAMICDEP */
-#define OMAP4430_ALWONCORE_DYNDEP_SHIFT				(1 << 16)
+#define OMAP4430_ALWONCORE_DYNDEP_SHIFT				16
 #define OMAP4430_ALWONCORE_DYNDEP_MASK				BITFIELD(16, 16)
 
 /* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP, CM_TESLA_STATICDEP */
-#define OMAP4430_ALWONCORE_STATDEP_SHIFT			(1 << 16)
+#define OMAP4430_ALWONCORE_STATDEP_SHIFT			16
 #define OMAP4430_ALWONCORE_STATDEP_MASK				BITFIELD(16, 16)
 
 /*
@@ -50,371 +50,371 @@
  * CM_AUTOIDLE_DPLL_CORE_RESTORE, CM_AUTOIDLE_DPLL_ABE, CM_AUTOIDLE_DPLL_CORE,
  * CM_AUTOIDLE_DPLL_DDRPHY, CM_AUTOIDLE_DPLL_IVA, CM_AUTOIDLE_DPLL_MPU
  */
-#define OMAP4430_AUTO_DPLL_MODE_SHIFT				(1 << 0)
+#define OMAP4430_AUTO_DPLL_MODE_SHIFT				0
 #define OMAP4430_AUTO_DPLL_MODE_MASK				BITFIELD(0, 2)
 
 /* Used by CM_L4CFG_DYNAMICDEP */
-#define OMAP4430_CEFUSE_DYNDEP_SHIFT				(1 << 17)
+#define OMAP4430_CEFUSE_DYNDEP_SHIFT				17
 #define OMAP4430_CEFUSE_DYNDEP_MASK				BITFIELD(17, 17)
 
 /* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP, CM_TESLA_STATICDEP */
-#define OMAP4430_CEFUSE_STATDEP_SHIFT				(1 << 17)
+#define OMAP4430_CEFUSE_STATDEP_SHIFT				17
 #define OMAP4430_CEFUSE_STATDEP_MASK				BITFIELD(17, 17)
 
 /* Used by CM1_ABE_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_ABE_24M_GFCLK_SHIFT		(1 << 13)
+#define OMAP4430_CLKACTIVITY_ABE_24M_GFCLK_SHIFT		13
 #define OMAP4430_CLKACTIVITY_ABE_24M_GFCLK_MASK			BITFIELD(13, 13)
 
 /* Used by CM1_ABE_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_ABE_ALWON_32K_CLK_SHIFT		(1 << 12)
+#define OMAP4430_CLKACTIVITY_ABE_ALWON_32K_CLK_SHIFT		12
 #define OMAP4430_CLKACTIVITY_ABE_ALWON_32K_CLK_MASK		BITFIELD(12, 12)
 
 /* Used by CM_WKUP_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_ABE_LP_CLK_SHIFT			(1 << 9)
+#define OMAP4430_CLKACTIVITY_ABE_LP_CLK_SHIFT			9
 #define OMAP4430_CLKACTIVITY_ABE_LP_CLK_MASK			BITFIELD(9, 9)
 
 /* Used by CM1_ABE_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_ABE_SYSCLK_SHIFT			(1 << 11)
+#define OMAP4430_CLKACTIVITY_ABE_SYSCLK_SHIFT			11
 #define OMAP4430_CLKACTIVITY_ABE_SYSCLK_MASK			BITFIELD(11, 11)
 
 /* Used by CM1_ABE_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_ABE_X2_CLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_ABE_X2_CLK_SHIFT			8
 #define OMAP4430_CLKACTIVITY_ABE_X2_CLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_ASYNC_DLL_CLK_SHIFT		(1 << 11)
+#define OMAP4430_CLKACTIVITY_ASYNC_DLL_CLK_SHIFT		11
 #define OMAP4430_CLKACTIVITY_ASYNC_DLL_CLK_MASK			BITFIELD(11, 11)
 
 /* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_ASYNC_PHY1_CLK_SHIFT		(1 << 12)
+#define OMAP4430_CLKACTIVITY_ASYNC_PHY1_CLK_SHIFT		12
 #define OMAP4430_CLKACTIVITY_ASYNC_PHY1_CLK_MASK		BITFIELD(12, 12)
 
 /* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_ASYNC_PHY2_CLK_SHIFT		(1 << 13)
+#define OMAP4430_CLKACTIVITY_ASYNC_PHY2_CLK_SHIFT		13
 #define OMAP4430_CLKACTIVITY_ASYNC_PHY2_CLK_MASK		BITFIELD(13, 13)
 
 /* Used by CM_CAM_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_CAM_PHY_CTRL_GCLK_SHIFT		(1 << 9)
+#define OMAP4430_CLKACTIVITY_CAM_PHY_CTRL_GCLK_SHIFT		9
 #define OMAP4430_CLKACTIVITY_CAM_PHY_CTRL_GCLK_MASK		BITFIELD(9, 9)
 
 /* Used by CM_EMU_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_SHIFT		(1 << 9)
+#define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_SHIFT		9
 #define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_MASK		BITFIELD(9, 9)
 
 /* Used by CM_CEFUSE_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_SHIFT		(1 << 9)
+#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_SHIFT		9
 #define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_MASK		BITFIELD(9, 9)
 
 /* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_DLL_CLK_SHIFT			(1 << 9)
+#define OMAP4430_CLKACTIVITY_DLL_CLK_SHIFT			9
 #define OMAP4430_CLKACTIVITY_DLL_CLK_MASK			BITFIELD(9, 9)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_DMT10_GFCLK_SHIFT			(1 << 9)
+#define OMAP4430_CLKACTIVITY_DMT10_GFCLK_SHIFT			9
 #define OMAP4430_CLKACTIVITY_DMT10_GFCLK_MASK			BITFIELD(9, 9)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_DMT11_GFCLK_SHIFT			(1 << 10)
+#define OMAP4430_CLKACTIVITY_DMT11_GFCLK_SHIFT			10
 #define OMAP4430_CLKACTIVITY_DMT11_GFCLK_MASK			BITFIELD(10, 10)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_DMT2_GFCLK_SHIFT			(1 << 11)
+#define OMAP4430_CLKACTIVITY_DMT2_GFCLK_SHIFT			11
 #define OMAP4430_CLKACTIVITY_DMT2_GFCLK_MASK			BITFIELD(11, 11)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_DMT3_GFCLK_SHIFT			(1 << 12)
+#define OMAP4430_CLKACTIVITY_DMT3_GFCLK_SHIFT			12
 #define OMAP4430_CLKACTIVITY_DMT3_GFCLK_MASK			BITFIELD(12, 12)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_DMT4_GFCLK_SHIFT			(1 << 13)
+#define OMAP4430_CLKACTIVITY_DMT4_GFCLK_SHIFT			13
 #define OMAP4430_CLKACTIVITY_DMT4_GFCLK_MASK			BITFIELD(13, 13)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_DMT9_GFCLK_SHIFT			(1 << 14)
+#define OMAP4430_CLKACTIVITY_DMT9_GFCLK_SHIFT			14
 #define OMAP4430_CLKACTIVITY_DMT9_GFCLK_MASK			BITFIELD(14, 14)
 
 /* Used by CM_DSS_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_DSS_ALWON_SYS_CLK_SHIFT		(1 << 10)
+#define OMAP4430_CLKACTIVITY_DSS_ALWON_SYS_CLK_SHIFT		10
 #define OMAP4430_CLKACTIVITY_DSS_ALWON_SYS_CLK_MASK		BITFIELD(10, 10)
 
 /* Used by CM_DSS_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_DSS_FCLK_SHIFT			(1 << 9)
+#define OMAP4430_CLKACTIVITY_DSS_FCLK_SHIFT			9
 #define OMAP4430_CLKACTIVITY_DSS_FCLK_MASK			BITFIELD(9, 9)
 
 /* Used by CM_DUCATI_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_DUCATI_GCLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_DUCATI_GCLK_SHIFT			8
 #define OMAP4430_CLKACTIVITY_DUCATI_GCLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_EMAC_50MHZ_CLK_SHIFT		(1 << 10)
+#define OMAP4430_CLKACTIVITY_EMAC_50MHZ_CLK_SHIFT		10
 #define OMAP4430_CLKACTIVITY_EMAC_50MHZ_CLK_MASK		BITFIELD(10, 10)
 
 /* Used by CM_EMU_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_EMU_SYS_CLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_EMU_SYS_CLK_SHIFT			8
 #define OMAP4430_CLKACTIVITY_EMU_SYS_CLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_CAM_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_FDIF_GFCLK_SHIFT			(1 << 10)
+#define OMAP4430_CLKACTIVITY_FDIF_GFCLK_SHIFT			10
 #define OMAP4430_CLKACTIVITY_FDIF_GFCLK_MASK			BITFIELD(10, 10)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_FUNC_12M_GFCLK_SHIFT		(1 << 15)
+#define OMAP4430_CLKACTIVITY_FUNC_12M_GFCLK_SHIFT		15
 #define OMAP4430_CLKACTIVITY_FUNC_12M_GFCLK_MASK		BITFIELD(15, 15)
 
 /* Used by CM1_ABE_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_FUNC_24M_GFCLK_SHIFT		(1 << 10)
+#define OMAP4430_CLKACTIVITY_FUNC_24M_GFCLK_SHIFT		10
 #define OMAP4430_CLKACTIVITY_FUNC_24M_GFCLK_MASK		BITFIELD(10, 10)
 
 /* Used by CM_DSS_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_HDMI_PHY_48MHZ_GFCLK_SHIFT		(1 << 11)
+#define OMAP4430_CLKACTIVITY_HDMI_PHY_48MHZ_GFCLK_SHIFT		11
 #define OMAP4430_CLKACTIVITY_HDMI_PHY_48MHZ_GFCLK_MASK		BITFIELD(11, 11)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_HSIC_P1_480M_GFCLK_SHIFT		(1 << 20)
+#define OMAP4430_CLKACTIVITY_HSIC_P1_480M_GFCLK_SHIFT		20
 #define OMAP4430_CLKACTIVITY_HSIC_P1_480M_GFCLK_MASK		BITFIELD(20, 20)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_HSIC_P1_GFCLK_SHIFT		(1 << 26)
+#define OMAP4430_CLKACTIVITY_HSIC_P1_GFCLK_SHIFT		26
 #define OMAP4430_CLKACTIVITY_HSIC_P1_GFCLK_MASK			BITFIELD(26, 26)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_HSIC_P2_480M_GFCLK_SHIFT		(1 << 21)
+#define OMAP4430_CLKACTIVITY_HSIC_P2_480M_GFCLK_SHIFT		21
 #define OMAP4430_CLKACTIVITY_HSIC_P2_480M_GFCLK_MASK		BITFIELD(21, 21)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_HSIC_P2_GFCLK_SHIFT		(1 << 27)
+#define OMAP4430_CLKACTIVITY_HSIC_P2_GFCLK_SHIFT		27
 #define OMAP4430_CLKACTIVITY_HSIC_P2_GFCLK_MASK			BITFIELD(27, 27)
 
 /* Used by CM_L3INIT_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_INIT_32K_GFCLK_SHIFT		(1 << 31)
+#define OMAP4430_CLKACTIVITY_INIT_32K_GFCLK_SHIFT		31
 #define OMAP4430_CLKACTIVITY_INIT_32K_GFCLK_MASK		BITFIELD(31, 31)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_INIT_48MC_GFCLK_SHIFT		(1 << 13)
+#define OMAP4430_CLKACTIVITY_INIT_48MC_GFCLK_SHIFT		13
 #define OMAP4430_CLKACTIVITY_INIT_48MC_GFCLK_MASK		BITFIELD(13, 13)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_INIT_48M_GFCLK_SHIFT		(1 << 12)
+#define OMAP4430_CLKACTIVITY_INIT_48M_GFCLK_SHIFT		12
 #define OMAP4430_CLKACTIVITY_INIT_48M_GFCLK_MASK		BITFIELD(12, 12)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_INIT_60M_P1_GFCLK_SHIFT		(1 << 28)
+#define OMAP4430_CLKACTIVITY_INIT_60M_P1_GFCLK_SHIFT		28
 #define OMAP4430_CLKACTIVITY_INIT_60M_P1_GFCLK_MASK		BITFIELD(28, 28)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_INIT_60M_P2_GFCLK_SHIFT		(1 << 29)
+#define OMAP4430_CLKACTIVITY_INIT_60M_P2_GFCLK_SHIFT		29
 #define OMAP4430_CLKACTIVITY_INIT_60M_P2_GFCLK_MASK		BITFIELD(29, 29)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_INIT_96M_GFCLK_SHIFT		(1 << 11)
+#define OMAP4430_CLKACTIVITY_INIT_96M_GFCLK_SHIFT		11
 #define OMAP4430_CLKACTIVITY_INIT_96M_GFCLK_MASK		BITFIELD(11, 11)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_INIT_HSI_GFCLK_SHIFT		(1 << 16)
+#define OMAP4430_CLKACTIVITY_INIT_HSI_GFCLK_SHIFT		16
 #define OMAP4430_CLKACTIVITY_INIT_HSI_GFCLK_MASK		BITFIELD(16, 16)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_INIT_HSMMC1_GFCLK_SHIFT		(1 << 17)
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC1_GFCLK_SHIFT		17
 #define OMAP4430_CLKACTIVITY_INIT_HSMMC1_GFCLK_MASK		BITFIELD(17, 17)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_INIT_HSMMC2_GFCLK_SHIFT		(1 << 18)
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC2_GFCLK_SHIFT		18
 #define OMAP4430_CLKACTIVITY_INIT_HSMMC2_GFCLK_MASK		BITFIELD(18, 18)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_INIT_HSMMC6_GFCLK_SHIFT		(1 << 19)
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC6_GFCLK_SHIFT		19
 #define OMAP4430_CLKACTIVITY_INIT_HSMMC6_GFCLK_MASK		BITFIELD(19, 19)
 
 /* Used by CM_CAM_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_ISS_GCLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_ISS_GCLK_SHIFT			8
 #define OMAP4430_CLKACTIVITY_ISS_GCLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_IVAHD_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_IVAHD_ROOT_CLK_SHIFT		(1 << 8)
+#define OMAP4430_CLKACTIVITY_IVAHD_ROOT_CLK_SHIFT		8
 #define OMAP4430_CLKACTIVITY_IVAHD_ROOT_CLK_MASK		BITFIELD(8, 8)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_L3INIT_DPLL_ALWON_CLK_SHIFT	(1 << 14)
+#define OMAP4430_CLKACTIVITY_L3INIT_DPLL_ALWON_CLK_SHIFT	14
 #define OMAP4430_CLKACTIVITY_L3INIT_DPLL_ALWON_CLK_MASK		BITFIELD(14, 14)
 
 /* Used by CM_L3_1_CLKSTCTRL, CM_L3_1_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_L3_1_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_1_GICLK_SHIFT			8
 #define OMAP4430_CLKACTIVITY_L3_1_GICLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_L3_2_CLKSTCTRL, CM_L3_2_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_L3_2_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_2_GICLK_SHIFT			8
 #define OMAP4430_CLKACTIVITY_L3_2_GICLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_D2D_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_L3_D2D_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_D2D_GICLK_SHIFT			8
 #define OMAP4430_CLKACTIVITY_L3_D2D_GICLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_SDMA_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_L3_DMA_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_DMA_GICLK_SHIFT			8
 #define OMAP4430_CLKACTIVITY_L3_DMA_GICLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_DSS_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_L3_DSS_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_DSS_GICLK_SHIFT			8
 #define OMAP4430_CLKACTIVITY_L3_DSS_GICLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_L3_EMIF_GICLK_SHIFT		(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_EMIF_GICLK_SHIFT		8
 #define OMAP4430_CLKACTIVITY_L3_EMIF_GICLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_GFX_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_L3_GFX_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_GFX_GICLK_SHIFT			8
 #define OMAP4430_CLKACTIVITY_L3_GFX_GICLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_L3_INIT_GICLK_SHIFT		(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_INIT_GICLK_SHIFT		8
 #define OMAP4430_CLKACTIVITY_L3_INIT_GICLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_L3INSTR_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_L3_INSTR_GICLK_SHIFT		(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_INSTR_GICLK_SHIFT		8
 #define OMAP4430_CLKACTIVITY_L3_INSTR_GICLK_MASK		BITFIELD(8, 8)
 
 /* Used by CM_L4SEC_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_L3_SECURE_GICLK_SHIFT		(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_SECURE_GICLK_SHIFT		8
 #define OMAP4430_CLKACTIVITY_L3_SECURE_GICLK_MASK		BITFIELD(8, 8)
 
 /* Used by CM_ALWON_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_L4_AO_ICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L4_AO_ICLK_SHIFT			8
 #define OMAP4430_CLKACTIVITY_L4_AO_ICLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_CEFUSE_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_L4_CEFUSE_GICLK_SHIFT		(1 << 8)
+#define OMAP4430_CLKACTIVITY_L4_CEFUSE_GICLK_SHIFT		8
 #define OMAP4430_CLKACTIVITY_L4_CEFUSE_GICLK_MASK		BITFIELD(8, 8)
 
 /* Used by CM_L4CFG_CLKSTCTRL, CM_L4CFG_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_L4_CFG_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L4_CFG_GICLK_SHIFT			8
 #define OMAP4430_CLKACTIVITY_L4_CFG_GICLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_D2D_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_L4_D2D_GICLK_SHIFT			(1 << 9)
+#define OMAP4430_CLKACTIVITY_L4_D2D_GICLK_SHIFT			9
 #define OMAP4430_CLKACTIVITY_L4_D2D_GICLK_MASK			BITFIELD(9, 9)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_L4_INIT_GICLK_SHIFT		(1 << 9)
+#define OMAP4430_CLKACTIVITY_L4_INIT_GICLK_SHIFT		9
 #define OMAP4430_CLKACTIVITY_L4_INIT_GICLK_MASK			BITFIELD(9, 9)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_L4_PER_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L4_PER_GICLK_SHIFT			8
 #define OMAP4430_CLKACTIVITY_L4_PER_GICLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_L4SEC_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_L4_SECURE_GICLK_SHIFT		(1 << 9)
+#define OMAP4430_CLKACTIVITY_L4_SECURE_GICLK_SHIFT		9
 #define OMAP4430_CLKACTIVITY_L4_SECURE_GICLK_MASK		BITFIELD(9, 9)
 
 /* Used by CM_WKUP_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_L4_WKUP_GICLK_SHIFT		(1 << 12)
+#define OMAP4430_CLKACTIVITY_L4_WKUP_GICLK_SHIFT		12
 #define OMAP4430_CLKACTIVITY_L4_WKUP_GICLK_MASK			BITFIELD(12, 12)
 
 /* Used by CM_MPU_CLKSTCTRL, CM_MPU_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_MPU_DPLL_CLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_MPU_DPLL_CLK_SHIFT			8
 #define OMAP4430_CLKACTIVITY_MPU_DPLL_CLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM1_ABE_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_OCP_ABE_GICLK_SHIFT		(1 << 9)
+#define OMAP4430_CLKACTIVITY_OCP_ABE_GICLK_SHIFT		9
 #define OMAP4430_CLKACTIVITY_OCP_ABE_GICLK_MASK			BITFIELD(9, 9)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_PER_24MC_GFCLK_SHIFT		(1 << 16)
+#define OMAP4430_CLKACTIVITY_PER_24MC_GFCLK_SHIFT		16
 #define OMAP4430_CLKACTIVITY_PER_24MC_GFCLK_MASK		BITFIELD(16, 16)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_PER_32K_GFCLK_SHIFT		(1 << 17)
+#define OMAP4430_CLKACTIVITY_PER_32K_GFCLK_SHIFT		17
 #define OMAP4430_CLKACTIVITY_PER_32K_GFCLK_MASK			BITFIELD(17, 17)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_PER_48M_GFCLK_SHIFT		(1 << 18)
+#define OMAP4430_CLKACTIVITY_PER_48M_GFCLK_SHIFT		18
 #define OMAP4430_CLKACTIVITY_PER_48M_GFCLK_MASK			BITFIELD(18, 18)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_PER_96M_GFCLK_SHIFT		(1 << 19)
+#define OMAP4430_CLKACTIVITY_PER_96M_GFCLK_SHIFT		19
 #define OMAP4430_CLKACTIVITY_PER_96M_GFCLK_MASK			BITFIELD(19, 19)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_PER_ABE_24M_GFCLK_SHIFT		(1 << 25)
+#define OMAP4430_CLKACTIVITY_PER_ABE_24M_GFCLK_SHIFT		25
 #define OMAP4430_CLKACTIVITY_PER_ABE_24M_GFCLK_MASK		BITFIELD(25, 25)
 
 /* Used by CM_EMU_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_PER_DPLL_EMU_CLK_SHIFT		(1 << 10)
+#define OMAP4430_CLKACTIVITY_PER_DPLL_EMU_CLK_SHIFT		10
 #define OMAP4430_CLKACTIVITY_PER_DPLL_EMU_CLK_MASK		BITFIELD(10, 10)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_PER_MCASP2_GFCLK_SHIFT		(1 << 20)
+#define OMAP4430_CLKACTIVITY_PER_MCASP2_GFCLK_SHIFT		20
 #define OMAP4430_CLKACTIVITY_PER_MCASP2_GFCLK_MASK		BITFIELD(20, 20)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_PER_MCASP3_GFCLK_SHIFT		(1 << 21)
+#define OMAP4430_CLKACTIVITY_PER_MCASP3_GFCLK_SHIFT		21
 #define OMAP4430_CLKACTIVITY_PER_MCASP3_GFCLK_MASK		BITFIELD(21, 21)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_PER_MCBSP4_GFCLK_SHIFT		(1 << 22)
+#define OMAP4430_CLKACTIVITY_PER_MCBSP4_GFCLK_SHIFT		22
 #define OMAP4430_CLKACTIVITY_PER_MCBSP4_GFCLK_MASK		BITFIELD(22, 22)
 
 /* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_PER_SYS_GFCLK_SHIFT		(1 << 24)
+#define OMAP4430_CLKACTIVITY_PER_SYS_GFCLK_SHIFT		24
 #define OMAP4430_CLKACTIVITY_PER_SYS_GFCLK_MASK			BITFIELD(24, 24)
 
 /* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_PHY_ROOT_CLK_SHIFT			(1 << 10)
+#define OMAP4430_CLKACTIVITY_PHY_ROOT_CLK_SHIFT			10
 #define OMAP4430_CLKACTIVITY_PHY_ROOT_CLK_MASK			BITFIELD(10, 10)
 
 /* Used by CM_GFX_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_SGX_GFCLK_SHIFT			(1 << 9)
+#define OMAP4430_CLKACTIVITY_SGX_GFCLK_SHIFT			9
 #define OMAP4430_CLKACTIVITY_SGX_GFCLK_MASK			BITFIELD(9, 9)
 
 /* Used by CM_ALWON_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK_SHIFT		(1 << 11)
+#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK_SHIFT		11
 #define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK_MASK		BITFIELD(11, 11)
 
 /* Used by CM_ALWON_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK_SHIFT		(1 << 10)
+#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK_SHIFT		10
 #define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK_MASK			BITFIELD(10, 10)
 
 /* Used by CM_ALWON_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK_SHIFT		(1 << 9)
+#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK_SHIFT		9
 #define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK_MASK			BITFIELD(9, 9)
 
 /* Used by CM_WKUP_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_SYS_CLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_SYS_CLK_SHIFT			8
 #define OMAP4430_CLKACTIVITY_SYS_CLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_TESLA_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_TESLA_ROOT_CLK_SHIFT		(1 << 8)
+#define OMAP4430_CLKACTIVITY_TESLA_ROOT_CLK_SHIFT		8
 #define OMAP4430_CLKACTIVITY_TESLA_ROOT_CLK_MASK		BITFIELD(8, 8)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_TLL_CH0_GFCLK_SHIFT		(1 << 22)
+#define OMAP4430_CLKACTIVITY_TLL_CH0_GFCLK_SHIFT		22
 #define OMAP4430_CLKACTIVITY_TLL_CH0_GFCLK_MASK			BITFIELD(22, 22)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_TLL_CH1_GFCLK_SHIFT		(1 << 23)
+#define OMAP4430_CLKACTIVITY_TLL_CH1_GFCLK_SHIFT		23
 #define OMAP4430_CLKACTIVITY_TLL_CH1_GFCLK_MASK			BITFIELD(23, 23)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_TLL_CH2_GFCLK_SHIFT		(1 << 24)
+#define OMAP4430_CLKACTIVITY_TLL_CH2_GFCLK_SHIFT		24
 #define OMAP4430_CLKACTIVITY_TLL_CH2_GFCLK_MASK			BITFIELD(24, 24)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_USB_DPLL_HS_CLK_SHIFT		(1 << 15)
+#define OMAP4430_CLKACTIVITY_USB_DPLL_HS_CLK_SHIFT		15
 #define OMAP4430_CLKACTIVITY_USB_DPLL_HS_CLK_MASK		BITFIELD(15, 15)
 
 /* Used by CM_WKUP_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_USIM_GFCLK_SHIFT			(1 << 10)
+#define OMAP4430_CLKACTIVITY_USIM_GFCLK_SHIFT			10
 #define OMAP4430_CLKACTIVITY_USIM_GFCLK_MASK			BITFIELD(10, 10)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_UTMI_P3_GFCLK_SHIFT		(1 << 30)
+#define OMAP4430_CLKACTIVITY_UTMI_P3_GFCLK_SHIFT		30
 #define OMAP4430_CLKACTIVITY_UTMI_P3_GFCLK_MASK			BITFIELD(30, 30)
 
 /* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
-#define OMAP4430_CLKACTIVITY_UTMI_ROOT_GFCLK_SHIFT		(1 << 25)
+#define OMAP4430_CLKACTIVITY_UTMI_ROOT_GFCLK_SHIFT		25
 #define OMAP4430_CLKACTIVITY_UTMI_ROOT_GFCLK_MASK		BITFIELD(25, 25)
 
 /* Used by CM_WKUP_CLKSTCTRL */
-#define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_SHIFT		(1 << 11)
+#define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_SHIFT		11
 #define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_MASK		BITFIELD(11, 11)
 
 /*
@@ -426,7 +426,7 @@
  * CM1_ABE_TIMER5_CLKCTRL, CM1_ABE_TIMER6_CLKCTRL, CM1_ABE_TIMER7_CLKCTRL,
  * CM1_ABE_TIMER8_CLKCTRL
  */
-#define OMAP4430_CLKSEL_SHIFT					(1 << 24)
+#define OMAP4430_CLKSEL_SHIFT					24
 #define OMAP4430_CLKSEL_MASK					BITFIELD(24, 24)
 
 /*
@@ -434,43 +434,43 @@
  * CM_DPLL_SYS_REF_CLKSEL, CM_L4_WKUP_CLKSEL, CM_CLKSEL_DUCATI_ISS_ROOT,
  * CM_CLKSEL_USB_60MHZ
  */
-#define OMAP4430_CLKSEL_0_0_SHIFT				(1 << 0)
+#define OMAP4430_CLKSEL_0_0_SHIFT				0
 #define OMAP4430_CLKSEL_0_0_MASK				BITFIELD(0, 0)
 
 /* Renamed from CLKSEL Used by CM_BYPCLK_DPLL_IVA, CM_BYPCLK_DPLL_MPU */
-#define OMAP4430_CLKSEL_0_1_SHIFT				(1 << 0)
+#define OMAP4430_CLKSEL_0_1_SHIFT				0
 #define OMAP4430_CLKSEL_0_1_MASK				BITFIELD(0, 1)
 
 /* Renamed from CLKSEL Used by CM_L3INIT_HSI_CLKCTRL */
-#define OMAP4430_CLKSEL_24_25_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_24_25_SHIFT				24
 #define OMAP4430_CLKSEL_24_25_MASK				BITFIELD(24, 25)
 
 /* Used by CM_L3INIT_USB_OTG_CLKCTRL */
-#define OMAP4430_CLKSEL_60M_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_60M_SHIFT				24
 #define OMAP4430_CLKSEL_60M_MASK				BITFIELD(24, 24)
 
 /* Used by CM1_ABE_AESS_CLKCTRL */
-#define OMAP4430_CLKSEL_AESS_FCLK_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_AESS_FCLK_SHIFT				24
 #define OMAP4430_CLKSEL_AESS_FCLK_MASK				BITFIELD(24, 24)
 
 /* Used by CM_CLKSEL_CORE_RESTORE, CM_CLKSEL_CORE */
-#define OMAP4430_CLKSEL_CORE_SHIFT				(1 << 0)
+#define OMAP4430_CLKSEL_CORE_SHIFT				0
 #define OMAP4430_CLKSEL_CORE_MASK				BITFIELD(0, 0)
 
 /* Renamed from CLKSEL_CORE Used by CM_SHADOW_FREQ_CONFIG2 */
-#define OMAP4430_CLKSEL_CORE_1_1_SHIFT				(1 << 1)
+#define OMAP4430_CLKSEL_CORE_1_1_SHIFT				1
 #define OMAP4430_CLKSEL_CORE_1_1_MASK				BITFIELD(1, 1)
 
 /* Used by CM_WKUP_USIM_CLKCTRL */
-#define OMAP4430_CLKSEL_DIV_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_DIV_SHIFT				24
 #define OMAP4430_CLKSEL_DIV_MASK				BITFIELD(24, 24)
 
 /* Used by CM_CAM_FDIF_CLKCTRL */
-#define OMAP4430_CLKSEL_FCLK_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_FCLK_SHIFT				24
 #define OMAP4430_CLKSEL_FCLK_MASK				BITFIELD(24, 25)
 
 /* Used by CM_L4PER_MCBSP4_CLKCTRL */
-#define OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT			(1 << 25)
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT			25
 #define OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK			BITFIELD(25, 25)
 
 /*
@@ -478,58 +478,58 @@
  * CM1_ABE_MCASP_CLKCTRL, CM1_ABE_MCBSP1_CLKCTRL, CM1_ABE_MCBSP2_CLKCTRL,
  * CM1_ABE_MCBSP3_CLKCTRL
  */
-#define OMAP4430_CLKSEL_INTERNAL_SOURCE_CM1_ABE_DMIC_SHIFT	(1 << 26)
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_CM1_ABE_DMIC_SHIFT	26
 #define OMAP4430_CLKSEL_INTERNAL_SOURCE_CM1_ABE_DMIC_MASK	BITFIELD(26, 27)
 
 /* Used by CM_CLKSEL_CORE_RESTORE, CM_CLKSEL_CORE */
-#define OMAP4430_CLKSEL_L3_SHIFT				(1 << 4)
+#define OMAP4430_CLKSEL_L3_SHIFT				4
 #define OMAP4430_CLKSEL_L3_MASK					BITFIELD(4, 4)
 
 /* Renamed from CLKSEL_L3 Used by CM_SHADOW_FREQ_CONFIG2 */
-#define OMAP4430_CLKSEL_L3_SHADOW_SHIFT				(1 << 2)
+#define OMAP4430_CLKSEL_L3_SHADOW_SHIFT				2
 #define OMAP4430_CLKSEL_L3_SHADOW_MASK				BITFIELD(2, 2)
 
 /* Used by CM_CLKSEL_CORE_RESTORE, CM_CLKSEL_CORE */
-#define OMAP4430_CLKSEL_L4_SHIFT				(1 << 8)
+#define OMAP4430_CLKSEL_L4_SHIFT				8
 #define OMAP4430_CLKSEL_L4_MASK					BITFIELD(8, 8)
 
 /* Used by CM_CLKSEL_ABE */
-#define OMAP4430_CLKSEL_OPP_SHIFT				(1 << 0)
+#define OMAP4430_CLKSEL_OPP_SHIFT				0
 #define OMAP4430_CLKSEL_OPP_MASK				BITFIELD(0, 1)
 
 /* Used by CM_GFX_GFX_CLKCTRL */
-#define OMAP4430_CLKSEL_PER_192M_SHIFT				(1 << 25)
+#define OMAP4430_CLKSEL_PER_192M_SHIFT				25
 #define OMAP4430_CLKSEL_PER_192M_MASK				BITFIELD(25, 26)
 
 /* Used by CM_EMU_DEBUGSS_CLKCTRL */
-#define OMAP4430_CLKSEL_PMD_STM_CLK_SHIFT			(1 << 27)
+#define OMAP4430_CLKSEL_PMD_STM_CLK_SHIFT			27
 #define OMAP4430_CLKSEL_PMD_STM_CLK_MASK			BITFIELD(27, 29)
 
 /* Used by CM_EMU_DEBUGSS_CLKCTRL */
-#define OMAP4430_CLKSEL_PMD_TRACE_CLK_SHIFT			(1 << 24)
+#define OMAP4430_CLKSEL_PMD_TRACE_CLK_SHIFT			24
 #define OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK			BITFIELD(24, 26)
 
 /* Used by CM_GFX_GFX_CLKCTRL */
-#define OMAP4430_CLKSEL_SGX_FCLK_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_SGX_FCLK_SHIFT				24
 #define OMAP4430_CLKSEL_SGX_FCLK_MASK				BITFIELD(24, 24)
 
 /*
  * Used by CM1_ABE_DMIC_CLKCTRL, CM1_ABE_MCASP_CLKCTRL, CM1_ABE_MCBSP1_CLKCTRL,
  * CM1_ABE_MCBSP2_CLKCTRL, CM1_ABE_MCBSP3_CLKCTRL
  */
-#define OMAP4430_CLKSEL_SOURCE_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_SOURCE_SHIFT				24
 #define OMAP4430_CLKSEL_SOURCE_MASK				BITFIELD(24, 25)
 
 /* Renamed from CLKSEL_SOURCE Used by CM_L4PER_MCBSP4_CLKCTRL */
-#define OMAP4430_CLKSEL_SOURCE_24_24_SHIFT			(1 << 24)
+#define OMAP4430_CLKSEL_SOURCE_24_24_SHIFT			24
 #define OMAP4430_CLKSEL_SOURCE_24_24_MASK			BITFIELD(24, 24)
 
 /* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
-#define OMAP4430_CLKSEL_UTMI_P1_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_UTMI_P1_SHIFT				24
 #define OMAP4430_CLKSEL_UTMI_P1_MASK				BITFIELD(24, 24)
 
 /* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
-#define OMAP4430_CLKSEL_UTMI_P2_SHIFT				(1 << 25)
+#define OMAP4430_CLKSEL_UTMI_P2_SHIFT				25
 #define OMAP4430_CLKSEL_UTMI_P2_MASK				BITFIELD(25, 25)
 
 /*
@@ -544,23 +544,23 @@
  * CM_IVAHD_CLKSTCTRL, CM_DSS_CLKSTCTRL, CM_MPU_CLKSTCTRL, CM_TESLA_CLKSTCTRL,
  * CM1_ABE_CLKSTCTRL, CM_MPU_CLKSTCTRL_RESTORE
  */
-#define OMAP4430_CLKTRCTRL_SHIFT				(1 << 0)
+#define OMAP4430_CLKTRCTRL_SHIFT				0
 #define OMAP4430_CLKTRCTRL_MASK					BITFIELD(0, 1)
 
 /* Used by CM_EMU_OVERRIDE_DPLL_CORE */
-#define OMAP4430_CORE_DPLL_EMU_DIV_SHIFT			(1 << 0)
+#define OMAP4430_CORE_DPLL_EMU_DIV_SHIFT			0
 #define OMAP4430_CORE_DPLL_EMU_DIV_MASK				BITFIELD(0, 6)
 
 /* Used by CM_EMU_OVERRIDE_DPLL_CORE */
-#define OMAP4430_CORE_DPLL_EMU_MULT_SHIFT			(1 << 8)
+#define OMAP4430_CORE_DPLL_EMU_MULT_SHIFT			8
 #define OMAP4430_CORE_DPLL_EMU_MULT_MASK			BITFIELD(8, 18)
 
 /* Used by CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP */
-#define OMAP4430_D2D_DYNDEP_SHIFT				(1 << 18)
+#define OMAP4430_D2D_DYNDEP_SHIFT				18
 #define OMAP4430_D2D_DYNDEP_MASK				BITFIELD(18, 18)
 
 /* Used by CM_MPU_STATICDEP */
-#define OMAP4430_D2D_STATDEP_SHIFT				(1 << 18)
+#define OMAP4430_D2D_STATDEP_SHIFT				18
 #define OMAP4430_D2D_STATDEP_MASK				BITFIELD(18, 18)
 
 /*
@@ -570,19 +570,19 @@
  * CM_SSC_DELTAMSTEP_DPLL_DDRPHY, CM_SSC_DELTAMSTEP_DPLL_IVA,
  * CM_SSC_DELTAMSTEP_DPLL_MPU
  */
-#define OMAP4430_DELTAMSTEP_SHIFT				(1 << 0)
+#define OMAP4430_DELTAMSTEP_SHIFT				0
 #define OMAP4430_DELTAMSTEP_MASK				BITFIELD(0, 19)
 
 /* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
-#define OMAP4430_DLL_OVERRIDE_SHIFT				(1 << 2)
+#define OMAP4430_DLL_OVERRIDE_SHIFT				2
 #define OMAP4430_DLL_OVERRIDE_MASK				BITFIELD(2, 2)
 
 /* Renamed from DLL_OVERRIDE Used by CM_DLL_CTRL */
-#define OMAP4430_DLL_OVERRIDE_0_0_SHIFT				(1 << 0)
+#define OMAP4430_DLL_OVERRIDE_0_0_SHIFT				0
 #define OMAP4430_DLL_OVERRIDE_0_0_MASK				BITFIELD(0, 0)
 
 /* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
-#define OMAP4430_DLL_RESET_SHIFT				(1 << 3)
+#define OMAP4430_DLL_RESET_SHIFT				3
 #define OMAP4430_DLL_RESET_MASK					BITFIELD(3, 3)
 
 /*
@@ -590,40 +590,40 @@
  * CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE,
  * CM_CLKSEL_DPLL_DDRPHY, CM_CLKSEL_DPLL_IVA, CM_CLKSEL_DPLL_MPU
  */
-#define OMAP4430_DPLL_BYP_CLKSEL_SHIFT				(1 << 23)
+#define OMAP4430_DPLL_BYP_CLKSEL_SHIFT				23
 #define OMAP4430_DPLL_BYP_CLKSEL_MASK				BITFIELD(23, 23)
 
 /* Used by CM_CLKDCOLDO_DPLL_USB */
-#define OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_SHIFT			(1 << 8)
+#define OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_SHIFT			8
 #define OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_MASK			BITFIELD(8, 8)
 
 /* Used by CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_CORE */
-#define OMAP4430_DPLL_CLKOUTHIF_CLKSEL_SHIFT			(1 << 20)
+#define OMAP4430_DPLL_CLKOUTHIF_CLKSEL_SHIFT			20
 #define OMAP4430_DPLL_CLKOUTHIF_CLKSEL_MASK			BITFIELD(20, 20)
 
 /*
  * Used by CM_DIV_M3_DPLL_PER, CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_ABE,
  * CM_DIV_M3_DPLL_CORE
  */
-#define OMAP4430_DPLL_CLKOUTHIF_DIV_SHIFT			(1 << 0)
+#define OMAP4430_DPLL_CLKOUTHIF_DIV_SHIFT			0
 #define OMAP4430_DPLL_CLKOUTHIF_DIV_MASK			BITFIELD(0, 4)
 
 /*
  * Used by CM_DIV_M3_DPLL_PER, CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_ABE,
  * CM_DIV_M3_DPLL_CORE
  */
-#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK_SHIFT			(1 << 5)
+#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK_SHIFT			5
 #define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK_MASK			BITFIELD(5, 5)
 
 /*
  * Used by CM_DIV_M3_DPLL_PER, CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_ABE,
  * CM_DIV_M3_DPLL_CORE
  */
-#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT			(1 << 8)
+#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT			8
 #define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_MASK			BITFIELD(8, 8)
 
 /* Used by CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO, CM_DIV_M2_DPLL_ABE */
-#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_SHIFT			(1 << 10)
+#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_SHIFT			10
 #define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK			BITFIELD(10, 10)
 
 /*
@@ -631,11 +631,11 @@
  * CM_DIV_M2_DPLL_CORE_RESTORE, CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE,
  * CM_DIV_M2_DPLL_DDRPHY, CM_DIV_M2_DPLL_MPU
  */
-#define OMAP4430_DPLL_CLKOUT_DIV_SHIFT				(1 << 0)
+#define OMAP4430_DPLL_CLKOUT_DIV_SHIFT				0
 #define OMAP4430_DPLL_CLKOUT_DIV_MASK				BITFIELD(0, 4)
 
 /* Renamed from DPLL_CLKOUT_DIV Used by CM_DIV_M2_DPLL_USB */
-#define OMAP4430_DPLL_CLKOUT_DIV_0_6_SHIFT			(1 << 0)
+#define OMAP4430_DPLL_CLKOUT_DIV_0_6_SHIFT			0
 #define OMAP4430_DPLL_CLKOUT_DIV_0_6_MASK			BITFIELD(0, 6)
 
 /*
@@ -643,11 +643,11 @@
  * CM_DIV_M2_DPLL_CORE_RESTORE, CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE,
  * CM_DIV_M2_DPLL_DDRPHY, CM_DIV_M2_DPLL_MPU
  */
-#define OMAP4430_DPLL_CLKOUT_DIVCHACK_SHIFT			(1 << 5)
+#define OMAP4430_DPLL_CLKOUT_DIVCHACK_SHIFT			5
 #define OMAP4430_DPLL_CLKOUT_DIVCHACK_MASK			BITFIELD(5, 5)
 
 /* Renamed from DPLL_CLKOUT_DIVCHACK Used by CM_DIV_M2_DPLL_USB */
-#define OMAP4430_DPLL_CLKOUT_DIVCHACK_M2_USB_SHIFT		(1 << 7)
+#define OMAP4430_DPLL_CLKOUT_DIVCHACK_M2_USB_SHIFT		7
 #define OMAP4430_DPLL_CLKOUT_DIVCHACK_M2_USB_MASK		BITFIELD(7, 7)
 
 /*
@@ -655,23 +655,23 @@
  * CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE, CM_DIV_M2_DPLL_DDRPHY,
  * CM_DIV_M2_DPLL_MPU
  */
-#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_SHIFT			(1 << 8)
+#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_SHIFT			8
 #define OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK			BITFIELD(8, 8)
 
 /* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
-#define OMAP4430_DPLL_CORE_DPLL_EN_SHIFT			(1 << 8)
+#define OMAP4430_DPLL_CORE_DPLL_EN_SHIFT			8
 #define OMAP4430_DPLL_CORE_DPLL_EN_MASK				BITFIELD(8, 10)
 
 /* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
-#define OMAP4430_DPLL_CORE_M2_DIV_SHIFT				(1 << 11)
+#define OMAP4430_DPLL_CORE_M2_DIV_SHIFT				11
 #define OMAP4430_DPLL_CORE_M2_DIV_MASK				BITFIELD(11, 15)
 
 /* Used by CM_SHADOW_FREQ_CONFIG2 */
-#define OMAP4430_DPLL_CORE_M5_DIV_SHIFT				(1 << 3)
+#define OMAP4430_DPLL_CORE_M5_DIV_SHIFT				3
 #define OMAP4430_DPLL_CORE_M5_DIV_MASK				BITFIELD(3, 7)
 
 /* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
-#define OMAP4430_DPLL_CORE_SYS_REF_CLKSEL_SHIFT			(1 << 1)
+#define OMAP4430_DPLL_CORE_SYS_REF_CLKSEL_SHIFT			1
 #define OMAP4430_DPLL_CORE_SYS_REF_CLKSEL_MASK			BITFIELD(1, 1)
 
 /*
@@ -679,11 +679,11 @@
  * CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE,
  * CM_CLKSEL_DPLL_DDRPHY, CM_CLKSEL_DPLL_IVA, CM_CLKSEL_DPLL_MPU
  */
-#define OMAP4430_DPLL_DIV_SHIFT					(1 << 0)
+#define OMAP4430_DPLL_DIV_SHIFT					0
 #define OMAP4430_DPLL_DIV_MASK					BITFIELD(0, 6)
 
 /* Renamed from DPLL_DIV Used by CM_CLKSEL_DPLL_USB */
-#define OMAP4430_DPLL_DIV_0_7_SHIFT				(1 << 0)
+#define OMAP4430_DPLL_DIV_0_7_SHIFT				0
 #define OMAP4430_DPLL_DIV_0_7_MASK				BITFIELD(0, 7)
 
 /*
@@ -691,11 +691,11 @@
  * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
  * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
  */
-#define OMAP4430_DPLL_DRIFTGUARD_EN_SHIFT			(1 << 8)
+#define OMAP4430_DPLL_DRIFTGUARD_EN_SHIFT			8
 #define OMAP4430_DPLL_DRIFTGUARD_EN_MASK			BITFIELD(8, 8)
 
 /* Renamed from DPLL_DRIFTGUARD_EN Used by CM_CLKMODE_DPLL_UNIPRO */
-#define OMAP4430_DPLL_DRIFTGUARD_EN_3_3_SHIFT			(1 << 3)
+#define OMAP4430_DPLL_DRIFTGUARD_EN_3_3_SHIFT			3
 #define OMAP4430_DPLL_DRIFTGUARD_EN_3_3_MASK			BITFIELD(3, 3)
 
 /*
@@ -703,7 +703,7 @@
  * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
  * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
  */
-#define OMAP4430_DPLL_EN_SHIFT					(1 << 0)
+#define OMAP4430_DPLL_EN_SHIFT					0
 #define OMAP4430_DPLL_EN_MASK					BITFIELD(0, 2)
 
 /*
@@ -711,7 +711,7 @@
  * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
  * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
  */
-#define OMAP4430_DPLL_LPMODE_EN_SHIFT				(1 << 10)
+#define OMAP4430_DPLL_LPMODE_EN_SHIFT				10
 #define OMAP4430_DPLL_LPMODE_EN_MASK				BITFIELD(10, 10)
 
 /*
@@ -719,11 +719,11 @@
  * CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE,
  * CM_CLKSEL_DPLL_DDRPHY, CM_CLKSEL_DPLL_IVA, CM_CLKSEL_DPLL_MPU
  */
-#define OMAP4430_DPLL_MULT_SHIFT				(1 << 8)
+#define OMAP4430_DPLL_MULT_SHIFT				8
 #define OMAP4430_DPLL_MULT_MASK					BITFIELD(8, 18)
 
 /* Renamed from DPLL_MULT Used by CM_CLKSEL_DPLL_USB */
-#define OMAP4430_DPLL_MULT_USB_SHIFT				(1 << 8)
+#define OMAP4430_DPLL_MULT_USB_SHIFT				8
 #define OMAP4430_DPLL_MULT_USB_MASK				BITFIELD(8, 19)
 
 /*
@@ -731,11 +731,11 @@
  * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
  * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
  */
-#define OMAP4430_DPLL_REGM4XEN_SHIFT				(1 << 11)
+#define OMAP4430_DPLL_REGM4XEN_SHIFT				11
 #define OMAP4430_DPLL_REGM4XEN_MASK				BITFIELD(11, 11)
 
 /* Used by CM_CLKSEL_DPLL_USB */
-#define OMAP4430_DPLL_SD_DIV_SHIFT				(1 << 24)
+#define OMAP4430_DPLL_SD_DIV_SHIFT				24
 #define OMAP4430_DPLL_SD_DIV_MASK				BITFIELD(24, 31)
 
 /*
@@ -743,7 +743,7 @@
  * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
  * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
  */
-#define OMAP4430_DPLL_SSC_ACK_SHIFT				(1 << 13)
+#define OMAP4430_DPLL_SSC_ACK_SHIFT				13
 #define OMAP4430_DPLL_SSC_ACK_MASK				BITFIELD(13, 13)
 
 /*
@@ -751,7 +751,7 @@
  * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
  * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
  */
-#define OMAP4430_DPLL_SSC_DOWNSPREAD_SHIFT			(1 << 14)
+#define OMAP4430_DPLL_SSC_DOWNSPREAD_SHIFT			14
 #define OMAP4430_DPLL_SSC_DOWNSPREAD_MASK			BITFIELD(14, 14)
 
 /*
@@ -759,154 +759,154 @@
  * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
  * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
  */
-#define OMAP4430_DPLL_SSC_EN_SHIFT				(1 << 12)
+#define OMAP4430_DPLL_SSC_EN_SHIFT				12
 #define OMAP4430_DPLL_SSC_EN_MASK				BITFIELD(12, 12)
 
 /* Used by CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP, CM_L4PER_DYNAMICDEP */
-#define OMAP4430_DSS_DYNDEP_SHIFT				(1 << 8)
+#define OMAP4430_DSS_DYNDEP_SHIFT				8
 #define OMAP4430_DSS_DYNDEP_MASK				BITFIELD(8, 8)
 
 /*
  * Used by CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE,
  * CM_MPU_STATICDEP
  */
-#define OMAP4430_DSS_STATDEP_SHIFT				(1 << 8)
+#define OMAP4430_DSS_STATDEP_SHIFT				8
 #define OMAP4430_DSS_STATDEP_MASK				BITFIELD(8, 8)
 
 /* Used by CM_L3_2_DYNAMICDEP */
-#define OMAP4430_DUCATI_DYNDEP_SHIFT				(1 << 0)
+#define OMAP4430_DUCATI_DYNDEP_SHIFT				0
 #define OMAP4430_DUCATI_DYNDEP_MASK				BITFIELD(0, 0)
 
 /* Used by CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP */
-#define OMAP4430_DUCATI_STATDEP_SHIFT				(1 << 0)
+#define OMAP4430_DUCATI_STATDEP_SHIFT				0
 #define OMAP4430_DUCATI_STATDEP_MASK				BITFIELD(0, 0)
 
 /* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
-#define OMAP4430_FREQ_UPDATE_SHIFT				(1 << 0)
+#define OMAP4430_FREQ_UPDATE_SHIFT				0
 #define OMAP4430_FREQ_UPDATE_MASK				BITFIELD(0, 0)
 
 /* Used by CM_L3_2_DYNAMICDEP */
-#define OMAP4430_GFX_DYNDEP_SHIFT				(1 << 10)
+#define OMAP4430_GFX_DYNDEP_SHIFT				10
 #define OMAP4430_GFX_DYNDEP_MASK				BITFIELD(10, 10)
 
 /* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP */
-#define OMAP4430_GFX_STATDEP_SHIFT				(1 << 10)
+#define OMAP4430_GFX_STATDEP_SHIFT				10
 #define OMAP4430_GFX_STATDEP_MASK				BITFIELD(10, 10)
 
 /* Used by CM_SHADOW_FREQ_CONFIG2 */
-#define OMAP4430_GPMC_FREQ_UPDATE_SHIFT				(1 << 0)
+#define OMAP4430_GPMC_FREQ_UPDATE_SHIFT				0
 #define OMAP4430_GPMC_FREQ_UPDATE_MASK				BITFIELD(0, 0)
 
 /*
  * Used by CM_DIV_M4_DPLL_PER, CM_DIV_M4_DPLL_CORE_RESTORE,
  * CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA
  */
-#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_SHIFT			(1 << 0)
+#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_SHIFT			0
 #define OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK			BITFIELD(0, 4)
 
 /*
  * Used by CM_DIV_M4_DPLL_PER, CM_DIV_M4_DPLL_CORE_RESTORE,
  * CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA
  */
-#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK_SHIFT		(1 << 5)
+#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK_SHIFT		5
 #define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK_MASK		BITFIELD(5, 5)
 
 /*
  * Used by CM_DIV_M4_DPLL_PER, CM_DIV_M4_DPLL_CORE_RESTORE,
  * CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA
  */
-#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_SHIFT		(1 << 8)
+#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_SHIFT		8
 #define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_MASK		BITFIELD(8, 8)
 
 /*
  * Used by CM_DIV_M4_DPLL_PER, CM_DIV_M4_DPLL_CORE_RESTORE,
  * CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA
  */
-#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN_SHIFT			(1 << 12)
+#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN_SHIFT			12
 #define OMAP4430_HSDIVIDER_CLKOUT1_PWDN_MASK			BITFIELD(12, 12)
 
 /*
  * Used by CM_DIV_M5_DPLL_PER, CM_DIV_M5_DPLL_CORE_RESTORE,
  * CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA
  */
-#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_SHIFT			(1 << 0)
+#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_SHIFT			0
 #define OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK			BITFIELD(0, 4)
 
 /*
  * Used by CM_DIV_M5_DPLL_PER, CM_DIV_M5_DPLL_CORE_RESTORE,
  * CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA
  */
-#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK_SHIFT		(1 << 5)
+#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK_SHIFT		5
 #define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK_MASK		BITFIELD(5, 5)
 
 /*
  * Used by CM_DIV_M5_DPLL_PER, CM_DIV_M5_DPLL_CORE_RESTORE,
  * CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA
  */
-#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_SHIFT		(1 << 8)
+#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_SHIFT		8
 #define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_MASK		BITFIELD(8, 8)
 
 /*
  * Used by CM_DIV_M5_DPLL_PER, CM_DIV_M5_DPLL_CORE_RESTORE,
  * CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA
  */
-#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN_SHIFT			(1 << 12)
+#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN_SHIFT			12
 #define OMAP4430_HSDIVIDER_CLKOUT2_PWDN_MASK			BITFIELD(12, 12)
 
 /*
  * Used by CM_DIV_M6_DPLL_PER, CM_DIV_M6_DPLL_CORE_RESTORE,
  * CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY
  */
-#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_SHIFT			(1 << 0)
+#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_SHIFT			0
 #define OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK			BITFIELD(0, 4)
 
 /*
  * Used by CM_DIV_M6_DPLL_PER, CM_DIV_M6_DPLL_CORE_RESTORE,
  * CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY
  */
-#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK_SHIFT		(1 << 5)
+#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK_SHIFT		5
 #define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK_MASK		BITFIELD(5, 5)
 
 /*
  * Used by CM_DIV_M6_DPLL_PER, CM_DIV_M6_DPLL_CORE_RESTORE,
  * CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY
  */
-#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_SHIFT		(1 << 8)
+#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_SHIFT		8
 #define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_MASK		BITFIELD(8, 8)
 
 /*
  * Used by CM_DIV_M6_DPLL_PER, CM_DIV_M6_DPLL_CORE_RESTORE,
  * CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY
  */
-#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN_SHIFT			(1 << 12)
+#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN_SHIFT			12
 #define OMAP4430_HSDIVIDER_CLKOUT3_PWDN_MASK			BITFIELD(12, 12)
 
 /*
  * Used by CM_DIV_M7_DPLL_PER, CM_DIV_M7_DPLL_CORE_RESTORE,
  * CM_DIV_M7_DPLL_CORE
  */
-#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_SHIFT			(1 << 0)
+#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_SHIFT			0
 #define OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK			BITFIELD(0, 4)
 
 /*
  * Used by CM_DIV_M7_DPLL_PER, CM_DIV_M7_DPLL_CORE_RESTORE,
  * CM_DIV_M7_DPLL_CORE
  */
-#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK_SHIFT		(1 << 5)
+#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK_SHIFT		5
 #define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK_MASK		BITFIELD(5, 5)
 
 /*
  * Used by CM_DIV_M7_DPLL_PER, CM_DIV_M7_DPLL_CORE_RESTORE,
  * CM_DIV_M7_DPLL_CORE
  */
-#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_SHIFT		(1 << 8)
+#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_SHIFT		8
 #define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_MASK		BITFIELD(8, 8)
 
 /*
  * Used by CM_DIV_M7_DPLL_PER, CM_DIV_M7_DPLL_CORE_RESTORE,
  * CM_DIV_M7_DPLL_CORE
  */
-#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN_SHIFT			(1 << 12)
+#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN_SHIFT			12
 #define OMAP4430_HSDIVIDER_CLKOUT4_PWDN_MASK			BITFIELD(12, 12)
 
 /*
@@ -962,22 +962,22 @@
  * CM1_ABE_TIMER6_CLKCTRL, CM1_ABE_TIMER7_CLKCTRL, CM1_ABE_TIMER8_CLKCTRL,
  * CM1_ABE_WDT3_CLKCTRL, CM_CM1_PROFILING_CLKCTRL
  */
-#define OMAP4430_IDLEST_SHIFT					(1 << 16)
+#define OMAP4430_IDLEST_SHIFT					16
 #define OMAP4430_IDLEST_MASK					BITFIELD(16, 17)
 
 /* Used by CM_DUCATI_DYNAMICDEP, CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP */
-#define OMAP4430_ISS_DYNDEP_SHIFT				(1 << 9)
+#define OMAP4430_ISS_DYNDEP_SHIFT				9
 #define OMAP4430_ISS_DYNDEP_MASK				BITFIELD(9, 9)
 
 /*
  * Used by CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE,
  * CM_MPU_STATICDEP, CM_TESLA_STATICDEP
  */
-#define OMAP4430_ISS_STATDEP_SHIFT				(1 << 9)
+#define OMAP4430_ISS_STATDEP_SHIFT				9
 #define OMAP4430_ISS_STATDEP_MASK				BITFIELD(9, 9)
 
 /* Used by CM_L3_2_DYNAMICDEP, CM_TESLA_DYNAMICDEP */
-#define OMAP4430_IVAHD_DYNDEP_SHIFT				(1 << 2)
+#define OMAP4430_IVAHD_DYNDEP_SHIFT				2
 #define OMAP4430_IVAHD_DYNDEP_MASK				BITFIELD(2, 2)
 
 /*
@@ -986,25 +986,25 @@
  * CM_SDMA_STATICDEP_RESTORE, CM_DSS_STATICDEP, CM_MPU_STATICDEP,
  * CM_TESLA_STATICDEP
  */
-#define OMAP4430_IVAHD_STATDEP_SHIFT				(1 << 2)
+#define OMAP4430_IVAHD_STATDEP_SHIFT				2
 #define OMAP4430_IVAHD_STATDEP_MASK				BITFIELD(2, 2)
 
 /* Used by CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP, CM_L4PER_DYNAMICDEP */
-#define OMAP4430_L3INIT_DYNDEP_SHIFT				(1 << 7)
+#define OMAP4430_L3INIT_DYNDEP_SHIFT				7
 #define OMAP4430_L3INIT_DYNDEP_MASK				BITFIELD(7, 7)
 
 /*
  * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
  * CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP, CM_TESLA_STATICDEP
  */
-#define OMAP4430_L3INIT_STATDEP_SHIFT				(1 << 7)
+#define OMAP4430_L3INIT_STATDEP_SHIFT				7
 #define OMAP4430_L3INIT_STATDEP_MASK				BITFIELD(7, 7)
 
 /*
  * Used by CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP, CM_L3INIT_DYNAMICDEP,
  * CM_DSS_DYNAMICDEP, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP
  */
-#define OMAP4430_L3_1_DYNDEP_SHIFT				(1 << 5)
+#define OMAP4430_L3_1_DYNDEP_SHIFT				5
 #define OMAP4430_L3_1_DYNDEP_MASK				BITFIELD(5, 5)
 
 /*
@@ -1013,7 +1013,7 @@
  * CM_SDMA_STATICDEP_RESTORE, CM_IVAHD_STATICDEP, CM_DSS_STATICDEP,
  * CM_MPU_STATICDEP, CM_TESLA_STATICDEP
  */
-#define OMAP4430_L3_1_STATDEP_SHIFT				(1 << 5)
+#define OMAP4430_L3_1_STATDEP_SHIFT				5
 #define OMAP4430_L3_1_STATDEP_MASK				BITFIELD(5, 5)
 
 /*
@@ -1022,7 +1022,7 @@
  * CM_GFX_DYNAMICDEP, CM_L4SEC_DYNAMICDEP, CM_L3INIT_DYNAMICDEP,
  * CM_CAM_DYNAMICDEP, CM_IVAHD_DYNAMICDEP
  */
-#define OMAP4430_L3_2_DYNDEP_SHIFT				(1 << 6)
+#define OMAP4430_L3_2_DYNDEP_SHIFT				6
 #define OMAP4430_L3_2_DYNDEP_MASK				BITFIELD(6, 6)
 
 /*
@@ -1031,11 +1031,11 @@
  * CM_SDMA_STATICDEP_RESTORE, CM_IVAHD_STATICDEP, CM_DSS_STATICDEP,
  * CM_MPU_STATICDEP, CM_TESLA_STATICDEP
  */
-#define OMAP4430_L3_2_STATDEP_SHIFT				(1 << 6)
+#define OMAP4430_L3_2_STATDEP_SHIFT				6
 #define OMAP4430_L3_2_STATDEP_MASK				BITFIELD(6, 6)
 
 /* Used by CM_L3_1_DYNAMICDEP */
-#define OMAP4430_L4CFG_DYNDEP_SHIFT				(1 << 12)
+#define OMAP4430_L4CFG_DYNDEP_SHIFT				12
 #define OMAP4430_L4CFG_DYNDEP_MASK				BITFIELD(12, 12)
 
 /*
@@ -1043,11 +1043,11 @@
  * CM_L3INIT_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP,
  * CM_TESLA_STATICDEP
  */
-#define OMAP4430_L4CFG_STATDEP_SHIFT				(1 << 12)
+#define OMAP4430_L4CFG_STATDEP_SHIFT				12
 #define OMAP4430_L4CFG_STATDEP_MASK				BITFIELD(12, 12)
 
 /* Used by CM_L3_2_DYNAMICDEP */
-#define OMAP4430_L4PER_DYNDEP_SHIFT				(1 << 13)
+#define OMAP4430_L4PER_DYNDEP_SHIFT				13
 #define OMAP4430_L4PER_DYNDEP_MASK				BITFIELD(13, 13)
 
 /*
@@ -1055,36 +1055,36 @@
  * CM_L4SEC_STATICDEP, CM_L3INIT_STATICDEP, CM_SDMA_STATICDEP_RESTORE,
  * CM_MPU_STATICDEP, CM_TESLA_STATICDEP
  */
-#define OMAP4430_L4PER_STATDEP_SHIFT				(1 << 13)
+#define OMAP4430_L4PER_STATDEP_SHIFT				13
 #define OMAP4430_L4PER_STATDEP_MASK				BITFIELD(13, 13)
 
 /* Used by CM_L3_2_DYNAMICDEP, CM_L4PER_DYNAMICDEP */
-#define OMAP4430_L4SEC_DYNDEP_SHIFT				(1 << 14)
+#define OMAP4430_L4SEC_DYNDEP_SHIFT				14
 #define OMAP4430_L4SEC_DYNDEP_MASK				BITFIELD(14, 14)
 
 /*
  * Used by CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP, CM_L3INIT_STATICDEP,
  * CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP
  */
-#define OMAP4430_L4SEC_STATDEP_SHIFT				(1 << 14)
+#define OMAP4430_L4SEC_STATDEP_SHIFT				14
 #define OMAP4430_L4SEC_STATDEP_MASK				BITFIELD(14, 14)
 
 /* Used by CM_L4CFG_DYNAMICDEP */
-#define OMAP4430_L4WKUP_DYNDEP_SHIFT				(1 << 15)
+#define OMAP4430_L4WKUP_DYNDEP_SHIFT				15
 #define OMAP4430_L4WKUP_DYNDEP_MASK				BITFIELD(15, 15)
 
 /*
  * Used by CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP, CM_L3INIT_STATICDEP,
  * CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP, CM_TESLA_STATICDEP
  */
-#define OMAP4430_L4WKUP_STATDEP_SHIFT				(1 << 15)
+#define OMAP4430_L4WKUP_STATDEP_SHIFT				15
 #define OMAP4430_L4WKUP_STATDEP_MASK				BITFIELD(15, 15)
 
 /*
  * Used by CM_D2D_DYNAMICDEP, CM_L3_1_DYNAMICDEP, CM_L4CFG_DYNAMICDEP,
  * CM_MPU_DYNAMICDEP
  */
-#define OMAP4430_MEMIF_DYNDEP_SHIFT				(1 << 4)
+#define OMAP4430_MEMIF_DYNDEP_SHIFT				4
 #define OMAP4430_MEMIF_DYNDEP_MASK				BITFIELD(4, 4)
 
 /*
@@ -1093,7 +1093,7 @@
  * CM_SDMA_STATICDEP_RESTORE, CM_IVAHD_STATICDEP, CM_DSS_STATICDEP,
  * CM_MPU_STATICDEP, CM_TESLA_STATICDEP
  */
-#define OMAP4430_MEMIF_STATDEP_SHIFT				(1 << 4)
+#define OMAP4430_MEMIF_STATDEP_SHIFT				4
 #define OMAP4430_MEMIF_STATDEP_MASK				BITFIELD(4, 4)
 
 /*
@@ -1103,7 +1103,7 @@
  * CM_SSC_MODFREQDIV_DPLL_DDRPHY, CM_SSC_MODFREQDIV_DPLL_IVA,
  * CM_SSC_MODFREQDIV_DPLL_MPU
  */
-#define OMAP4430_MODFREQDIV_EXPONENT_SHIFT			(1 << 8)
+#define OMAP4430_MODFREQDIV_EXPONENT_SHIFT			8
 #define OMAP4430_MODFREQDIV_EXPONENT_MASK			BITFIELD(8, 10)
 
 /*
@@ -1113,7 +1113,7 @@
  * CM_SSC_MODFREQDIV_DPLL_DDRPHY, CM_SSC_MODFREQDIV_DPLL_IVA,
  * CM_SSC_MODFREQDIV_DPLL_MPU
  */
-#define OMAP4430_MODFREQDIV_MANTISSA_SHIFT			(1 << 0)
+#define OMAP4430_MODFREQDIV_MANTISSA_SHIFT			0
 #define OMAP4430_MODFREQDIV_MANTISSA_MASK			BITFIELD(0, 6)
 
 /*
@@ -1169,23 +1169,23 @@
  * CM1_ABE_TIMER6_CLKCTRL, CM1_ABE_TIMER7_CLKCTRL, CM1_ABE_TIMER8_CLKCTRL,
  * CM1_ABE_WDT3_CLKCTRL, CM_CM1_PROFILING_CLKCTRL
  */
-#define OMAP4430_MODULEMODE_SHIFT				(1 << 0)
+#define OMAP4430_MODULEMODE_SHIFT				0
 #define OMAP4430_MODULEMODE_MASK				BITFIELD(0, 1)
 
 /* Used by CM_DSS_DSS_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT			(1 << 9)
+#define OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT			9
 #define OMAP4430_OPTFCLKEN_48MHZ_CLK_MASK			BITFIELD(9, 9)
 
 /* Used by CM_WKUP_BANDGAP_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT			8
 #define OMAP4430_OPTFCLKEN_BGAP_32K_MASK			BITFIELD(8, 8)
 
 /* Used by CM_L3INIT_USBPHYOCP2SCP_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_CLK32K_SHIFT				(1 << 9)
+#define OMAP4430_OPTFCLKEN_CLK32K_SHIFT				9
 #define OMAP4430_OPTFCLKEN_CLK32K_MASK				BITFIELD(9, 9)
 
 /* Used by CM_CAM_ISS_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT			8
 #define OMAP4430_OPTFCLKEN_CTRLCLK_MASK				BITFIELD(8, 8)
 
 /*
@@ -1195,119 +1195,119 @@
  * CM_L4PER_GPIO3_CLKCTRL_RESTORE, CM_L4PER_GPIO4_CLKCTRL_RESTORE,
  * CM_L4PER_GPIO5_CLKCTRL_RESTORE, CM_L4PER_GPIO6_CLKCTRL_RESTORE
  */
-#define OMAP4430_OPTFCLKEN_DBCLK_SHIFT				(1 << 8)
+#define OMAP4430_OPTFCLKEN_DBCLK_SHIFT				8
 #define OMAP4430_OPTFCLKEN_DBCLK_MASK				BITFIELD(8, 8)
 
 /* Used by CM_MEMIF_DLL_CLKCTRL, CM_MEMIF_DLL_H_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_DLL_CLK_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_DLL_CLK_SHIFT			8
 #define OMAP4430_OPTFCLKEN_DLL_CLK_MASK				BITFIELD(8, 8)
 
 /* Used by CM_DSS_DSS_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_DSSCLK_SHIFT				(1 << 8)
+#define OMAP4430_OPTFCLKEN_DSSCLK_SHIFT				8
 #define OMAP4430_OPTFCLKEN_DSSCLK_MASK				BITFIELD(8, 8)
 
 /* Used by CM1_ABE_SLIMBUS_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_FCLK0_SHIFT				(1 << 8)
+#define OMAP4430_OPTFCLKEN_FCLK0_SHIFT				8
 #define OMAP4430_OPTFCLKEN_FCLK0_MASK				BITFIELD(8, 8)
 
 /* Used by CM1_ABE_SLIMBUS_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_FCLK1_SHIFT				(1 << 9)
+#define OMAP4430_OPTFCLKEN_FCLK1_SHIFT				9
 #define OMAP4430_OPTFCLKEN_FCLK1_MASK				BITFIELD(9, 9)
 
 /* Used by CM1_ABE_SLIMBUS_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_FCLK2_SHIFT				(1 << 10)
+#define OMAP4430_OPTFCLKEN_FCLK2_SHIFT				10
 #define OMAP4430_OPTFCLKEN_FCLK2_MASK				BITFIELD(10, 10)
 
 /* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
-#define OMAP4430_OPTFCLKEN_FUNC48MCLK_SHIFT			(1 << 15)
+#define OMAP4430_OPTFCLKEN_FUNC48MCLK_SHIFT			15
 #define OMAP4430_OPTFCLKEN_FUNC48MCLK_MASK			BITFIELD(15, 15)
 
 /* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
-#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT		(1 << 13)
+#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT		13
 #define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_MASK			BITFIELD(13, 13)
 
 /* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
-#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT		(1 << 14)
+#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT		14
 #define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_MASK			BITFIELD(14, 14)
 
 /* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
-#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT			(1 << 11)
+#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT			11
 #define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_MASK			BITFIELD(11, 11)
 
 /* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
-#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT			(1 << 12)
+#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT			12
 #define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_MASK			BITFIELD(12, 12)
 
 /* Used by CM_L4PER_SLIMBUS2_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_SHIFT			8
 #define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_L4PER_SLIMBUS2_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT		(1 << 9)
+#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT		9
 #define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_MASK			BITFIELD(9, 9)
 
 /* Used by CM_L3INIT_USBPHYOCP2SCP_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_PHY_48M_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_PHY_48M_SHIFT			8
 #define OMAP4430_OPTFCLKEN_PHY_48M_MASK				BITFIELD(8, 8)
 
 /* Used by CM_L4PER_SLIMBUS2_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT			(1 << 10)
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT			10
 #define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_MASK			BITFIELD(10, 10)
 
 /* Renamed from OPTFCLKEN_SLIMBUS_CLK Used by CM1_ABE_SLIMBUS_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT		(1 << 11)
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT		11
 #define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_MASK		BITFIELD(11, 11)
 
 /* Used by CM_DSS_DSS_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT			(1 << 10)
+#define OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT			10
 #define OMAP4430_OPTFCLKEN_SYS_CLK_MASK				BITFIELD(10, 10)
 
 /* Used by CM_DSS_DSS_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_TV_CLK_SHIFT				(1 << 11)
+#define OMAP4430_OPTFCLKEN_TV_CLK_SHIFT				11
 #define OMAP4430_OPTFCLKEN_TV_CLK_MASK				BITFIELD(11, 11)
 
 /* Used by CM_L3INIT_UNIPRO1_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_TXPHYCLK_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_TXPHYCLK_SHIFT			8
 #define OMAP4430_OPTFCLKEN_TXPHYCLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE */
-#define OMAP4430_OPTFCLKEN_USB_CH0_CLK_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_USB_CH0_CLK_SHIFT			8
 #define OMAP4430_OPTFCLKEN_USB_CH0_CLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE */
-#define OMAP4430_OPTFCLKEN_USB_CH1_CLK_SHIFT			(1 << 9)
+#define OMAP4430_OPTFCLKEN_USB_CH1_CLK_SHIFT			9
 #define OMAP4430_OPTFCLKEN_USB_CH1_CLK_MASK			BITFIELD(9, 9)
 
 /* Used by CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE */
-#define OMAP4430_OPTFCLKEN_USB_CH2_CLK_SHIFT			(1 << 10)
+#define OMAP4430_OPTFCLKEN_USB_CH2_CLK_SHIFT			10
 #define OMAP4430_OPTFCLKEN_USB_CH2_CLK_MASK			BITFIELD(10, 10)
 
 /* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
-#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_SHIFT			8
 #define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_MASK			BITFIELD(8, 8)
 
 /* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
-#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_SHIFT			(1 << 9)
+#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_SHIFT			9
 #define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_MASK			BITFIELD(9, 9)
 
 /* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
-#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_SHIFT			(1 << 10)
+#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_SHIFT			10
 #define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_MASK			BITFIELD(10, 10)
 
 /* Used by CM_L3INIT_USB_OTG_CLKCTRL */
-#define OMAP4430_OPTFCLKEN_XCLK_SHIFT				(1 << 8)
+#define OMAP4430_OPTFCLKEN_XCLK_SHIFT				8
 #define OMAP4430_OPTFCLKEN_XCLK_MASK				BITFIELD(8, 8)
 
 /* Used by CM_EMU_OVERRIDE_DPLL_PER, CM_EMU_OVERRIDE_DPLL_CORE */
-#define OMAP4430_OVERRIDE_ENABLE_SHIFT				(1 << 19)
+#define OMAP4430_OVERRIDE_ENABLE_SHIFT				19
 #define OMAP4430_OVERRIDE_ENABLE_MASK				BITFIELD(19, 19)
 
 /* Used by CM_CLKSEL_ABE */
-#define OMAP4430_PAD_CLKS_GATE_SHIFT				(1 << 8)
+#define OMAP4430_PAD_CLKS_GATE_SHIFT				8
 #define OMAP4430_PAD_CLKS_GATE_MASK				BITFIELD(8, 8)
 
 /* Used by CM_CORE_DVFS_CURRENT, CM_IVA_DVFS_CURRENT */
-#define OMAP4430_PERF_CURRENT_SHIFT				(1 << 0)
+#define OMAP4430_PERF_CURRENT_SHIFT				0
 #define OMAP4430_PERF_CURRENT_MASK				BITFIELD(0, 7)
 
 /*
@@ -1315,66 +1315,66 @@
  * CM_CORE_DVFS_PERF4, CM_IVA_DVFS_PERF_ABE, CM_IVA_DVFS_PERF_IVAHD,
  * CM_IVA_DVFS_PERF_TESLA
  */
-#define OMAP4430_PERF_REQ_SHIFT					(1 << 0)
+#define OMAP4430_PERF_REQ_SHIFT					0
 #define OMAP4430_PERF_REQ_MASK					BITFIELD(0, 7)
 
 /* Used by CM_EMU_OVERRIDE_DPLL_PER */
-#define OMAP4430_PER_DPLL_EMU_DIV_SHIFT				(1 << 0)
+#define OMAP4430_PER_DPLL_EMU_DIV_SHIFT				0
 #define OMAP4430_PER_DPLL_EMU_DIV_MASK				BITFIELD(0, 6)
 
 /* Used by CM_EMU_OVERRIDE_DPLL_PER */
-#define OMAP4430_PER_DPLL_EMU_MULT_SHIFT			(1 << 8)
+#define OMAP4430_PER_DPLL_EMU_MULT_SHIFT			8
 #define OMAP4430_PER_DPLL_EMU_MULT_MASK				BITFIELD(8, 18)
 
 /* Used by CM_RESTORE_ST */
-#define OMAP4430_PHASE1_COMPLETED_SHIFT				(1 << 0)
+#define OMAP4430_PHASE1_COMPLETED_SHIFT				0
 #define OMAP4430_PHASE1_COMPLETED_MASK				BITFIELD(0, 0)
 
 /* Used by CM_RESTORE_ST */
-#define OMAP4430_PHASE2A_COMPLETED_SHIFT			(1 << 1)
+#define OMAP4430_PHASE2A_COMPLETED_SHIFT			1
 #define OMAP4430_PHASE2A_COMPLETED_MASK				BITFIELD(1, 1)
 
 /* Used by CM_RESTORE_ST */
-#define OMAP4430_PHASE2B_COMPLETED_SHIFT			(1 << 2)
+#define OMAP4430_PHASE2B_COMPLETED_SHIFT			2
 #define OMAP4430_PHASE2B_COMPLETED_MASK				BITFIELD(2, 2)
 
 /* Used by CM_EMU_DEBUGSS_CLKCTRL */
-#define OMAP4430_PMD_STM_MUX_CTRL_SHIFT				(1 << 20)
+#define OMAP4430_PMD_STM_MUX_CTRL_SHIFT				20
 #define OMAP4430_PMD_STM_MUX_CTRL_MASK				BITFIELD(20, 21)
 
 /* Used by CM_EMU_DEBUGSS_CLKCTRL */
-#define OMAP4430_PMD_TRACE_MUX_CTRL_SHIFT			(1 << 22)
+#define OMAP4430_PMD_TRACE_MUX_CTRL_SHIFT			22
 #define OMAP4430_PMD_TRACE_MUX_CTRL_MASK			BITFIELD(22, 23)
 
 /* Used by CM_DYN_DEP_PRESCAL */
-#define OMAP4430_PRESCAL_SHIFT					(1 << 0)
+#define OMAP4430_PRESCAL_SHIFT					0
 #define OMAP4430_PRESCAL_MASK					BITFIELD(0, 5)
 
 /* Used by REVISION_CM2, REVISION_CM1 */
-#define OMAP4430_REV_SHIFT					(1 << 0)
+#define OMAP4430_REV_SHIFT					0
 #define OMAP4430_REV_MASK					BITFIELD(0, 7)
 
 /*
  * Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL,
  * CM_L3INIT_USB_HOST_CLKCTRL_RESTORE, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE
  */
-#define OMAP4430_SAR_MODE_SHIFT					(1 << 4)
+#define OMAP4430_SAR_MODE_SHIFT					4
 #define OMAP4430_SAR_MODE_MASK					BITFIELD(4, 4)
 
 /* Used by CM_SCALE_FCLK */
-#define OMAP4430_SCALE_FCLK_SHIFT				(1 << 0)
+#define OMAP4430_SCALE_FCLK_SHIFT				0
 #define OMAP4430_SCALE_FCLK_MASK				BITFIELD(0, 0)
 
 /* Used by CM_L4CFG_DYNAMICDEP */
-#define OMAP4430_SDMA_DYNDEP_SHIFT				(1 << 11)
+#define OMAP4430_SDMA_DYNDEP_SHIFT				11
 #define OMAP4430_SDMA_DYNDEP_MASK				BITFIELD(11, 11)
 
 /* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP */
-#define OMAP4430_SDMA_STATDEP_SHIFT				(1 << 11)
+#define OMAP4430_SDMA_STATDEP_SHIFT				11
 #define OMAP4430_SDMA_STATDEP_MASK				BITFIELD(11, 11)
 
 /* Used by CM_CLKSEL_ABE */
-#define OMAP4430_SLIMBUS_CLK_GATE_SHIFT				(1 << 10)
+#define OMAP4430_SLIMBUS_CLK_GATE_SHIFT				10
 #define OMAP4430_SLIMBUS_CLK_GATE_MASK				BITFIELD(10, 10)
 
 /*
@@ -1390,7 +1390,7 @@
  * CM_IVAHD_IVAHD_CLKCTRL, CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL,
  * CM_MPU_MPU_CLKCTRL, CM_TESLA_TESLA_CLKCTRL, CM1_ABE_AESS_CLKCTRL
  */
-#define OMAP4430_STBYST_SHIFT					(1 << 18)
+#define OMAP4430_STBYST_SHIFT					18
 #define OMAP4430_STBYST_MASK					BITFIELD(18, 18)
 
 /*
@@ -1398,11 +1398,11 @@
  * CM_IDLEST_DPLL_ABE, CM_IDLEST_DPLL_CORE, CM_IDLEST_DPLL_DDRPHY,
  * CM_IDLEST_DPLL_IVA, CM_IDLEST_DPLL_MPU
  */
-#define OMAP4430_ST_DPLL_CLK_SHIFT				(1 << 0)
+#define OMAP4430_ST_DPLL_CLK_SHIFT				0
 #define OMAP4430_ST_DPLL_CLK_MASK				BITFIELD(0, 0)
 
 /* Used by CM_CLKDCOLDO_DPLL_USB */
-#define OMAP4430_ST_DPLL_CLKDCOLDO_SHIFT			(1 << 9)
+#define OMAP4430_ST_DPLL_CLKDCOLDO_SHIFT			9
 #define OMAP4430_ST_DPLL_CLKDCOLDO_MASK				BITFIELD(9, 9)
 
 /*
@@ -1410,58 +1410,58 @@
  * CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE, CM_DIV_M2_DPLL_DDRPHY,
  * CM_DIV_M2_DPLL_MPU
  */
-#define OMAP4430_ST_DPLL_CLKOUT_SHIFT				(1 << 9)
+#define OMAP4430_ST_DPLL_CLKOUT_SHIFT				9
 #define OMAP4430_ST_DPLL_CLKOUT_MASK				BITFIELD(9, 9)
 
 /*
  * Used by CM_DIV_M3_DPLL_PER, CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_ABE,
  * CM_DIV_M3_DPLL_CORE
  */
-#define OMAP4430_ST_DPLL_CLKOUTHIF_SHIFT			(1 << 9)
+#define OMAP4430_ST_DPLL_CLKOUTHIF_SHIFT			9
 #define OMAP4430_ST_DPLL_CLKOUTHIF_MASK				BITFIELD(9, 9)
 
 /* Used by CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO, CM_DIV_M2_DPLL_ABE */
-#define OMAP4430_ST_DPLL_CLKOUTX2_SHIFT				(1 << 11)
+#define OMAP4430_ST_DPLL_CLKOUTX2_SHIFT				11
 #define OMAP4430_ST_DPLL_CLKOUTX2_MASK				BITFIELD(11, 11)
 
 /*
  * Used by CM_DIV_M4_DPLL_PER, CM_DIV_M4_DPLL_CORE_RESTORE,
  * CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA
  */
-#define OMAP4430_ST_HSDIVIDER_CLKOUT1_SHIFT			(1 << 9)
+#define OMAP4430_ST_HSDIVIDER_CLKOUT1_SHIFT			9
 #define OMAP4430_ST_HSDIVIDER_CLKOUT1_MASK			BITFIELD(9, 9)
 
 /*
  * Used by CM_DIV_M5_DPLL_PER, CM_DIV_M5_DPLL_CORE_RESTORE,
  * CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA
  */
-#define OMAP4430_ST_HSDIVIDER_CLKOUT2_SHIFT			(1 << 9)
+#define OMAP4430_ST_HSDIVIDER_CLKOUT2_SHIFT			9
 #define OMAP4430_ST_HSDIVIDER_CLKOUT2_MASK			BITFIELD(9, 9)
 
 /*
  * Used by CM_DIV_M6_DPLL_PER, CM_DIV_M6_DPLL_CORE_RESTORE,
  * CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY
  */
-#define OMAP4430_ST_HSDIVIDER_CLKOUT3_SHIFT			(1 << 9)
+#define OMAP4430_ST_HSDIVIDER_CLKOUT3_SHIFT			9
 #define OMAP4430_ST_HSDIVIDER_CLKOUT3_MASK			BITFIELD(9, 9)
 
 /*
  * Used by CM_DIV_M7_DPLL_PER, CM_DIV_M7_DPLL_CORE_RESTORE,
  * CM_DIV_M7_DPLL_CORE
  */
-#define OMAP4430_ST_HSDIVIDER_CLKOUT4_SHIFT			(1 << 9)
+#define OMAP4430_ST_HSDIVIDER_CLKOUT4_SHIFT			9
 #define OMAP4430_ST_HSDIVIDER_CLKOUT4_MASK			BITFIELD(9, 9)
 
 /* Used by CM_SYS_CLKSEL */
-#define OMAP4430_SYS_CLKSEL_SHIFT				(1 << 0)
+#define OMAP4430_SYS_CLKSEL_SHIFT				0
 #define OMAP4430_SYS_CLKSEL_MASK				BITFIELD(0, 2)
 
 /* Used by CM_L4CFG_DYNAMICDEP */
-#define OMAP4430_TESLA_DYNDEP_SHIFT				(1 << 1)
+#define OMAP4430_TESLA_DYNDEP_SHIFT				1
 #define OMAP4430_TESLA_DYNDEP_MASK				BITFIELD(1, 1)
 
 /* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP */
-#define OMAP4430_TESLA_STATDEP_SHIFT				(1 << 1)
+#define OMAP4430_TESLA_STATDEP_SHIFT				1
 #define OMAP4430_TESLA_STATDEP_MASK				BITFIELD(1, 1)
 
 /*
@@ -1469,6 +1469,6 @@
  * CM_L3_1_DYNAMICDEP, CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP,
  * CM_L4PER_DYNAMICDEP, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP
  */
-#define OMAP4430_WINDOWSIZE_SHIFT				(1 << 24)
+#define OMAP4430_WINDOWSIZE_SHIFT				24
 #define OMAP4430_WINDOWSIZE_MASK				BITFIELD(24, 27)
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/control.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/control.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/control.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/control.c	2010-05-16 17:17:36.000000000 -0400
@@ -140,7 +140,11 @@ static struct omap3_control_regs control
 
 void __init omap2_set_globals_control(struct omap_globals *omap2_globals)
 {
-	omap2_ctrl_base = omap2_globals->ctrl;
+	/* Static mapping, never released */
+	if (omap2_globals->ctrl) {
+		omap2_ctrl_base = ioremap(omap2_globals->ctrl, SZ_4K);
+		WARN_ON(!omap2_ctrl_base);
+	}
 }
 
 void __iomem *omap_ctrl_base_get(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cpuidle34xx.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/cpuidle34xx.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cpuidle34xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/cpuidle34xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,6 +45,8 @@
 #define OMAP3_STATE_C6 5 /* C6 - MPU OFF + Core RET */
 #define OMAP3_STATE_C7 6 /* C7 - MPU OFF + Core OFF */
 
+#define OMAP3_STATE_MAX OMAP3_STATE_C7
+
 struct omap3_processor_cx {
 	u8 valid;
 	u8 type;
@@ -60,6 +62,30 @@ struct omap3_processor_cx omap3_power_st
 struct omap3_processor_cx current_cx_state;
 struct powerdomain *mpu_pd, *core_pd;
 
+/*
+ * The latencies/thresholds for various C states have
+ * to be configured from the respective board files.
+ * These are some default values (which might not provide
+ * the best power savings) used on boards which do not
+ * pass these details from the board file.
+ */
+static struct cpuidle_params cpuidle_params_table[] = {
+	/* C1 */
+	{1, 2, 2, 5},
+	/* C2 */
+	{1, 10, 10, 30},
+	/* C3 */
+	{1, 50, 50, 300},
+	/* C4 */
+	{1, 1500, 1800, 4000},
+	/* C5 */
+	{1, 2500, 7500, 12000},
+	/* C6 */
+	{1, 3000, 8500, 15000},
+	/* C7 */
+	{1, 10000, 30000, 300000},
+};
+
 static int omap3_idle_bm_check(void)
 {
 	if (!omap3_can_sleep())
@@ -104,13 +130,6 @@ static int omap3_enter_idle(struct cpuid
 	local_irq_disable();
 	local_fiq_disable();
 
-	if (!enable_off_mode) {
-		if (mpu_state < PWRDM_POWER_RET)
-			mpu_state = PWRDM_POWER_RET;
-		if (core_state < PWRDM_POWER_RET)
-			core_state = PWRDM_POWER_RET;
-	}
-
 	pwrdm_set_next_pwrst(mpu_pd, mpu_state);
 	pwrdm_set_next_pwrst(core_pd, core_state);
 
@@ -141,6 +160,67 @@ return_sleep_time:
 }
 
 /**
+ * next_valid_state - Find next valid c-state
+ * @dev: cpuidle device
+ * @state: Currently selected c-state
+ *
+ * If the current state is valid, it is returned back to the caller.
+ * Else, this function searches for a lower c-state which is still
+ * valid (as defined in omap3_power_states[]).
+ */
+static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
+						struct cpuidle_state *curr)
+{
+	struct cpuidle_state *next = NULL;
+	struct omap3_processor_cx *cx;
+
+	cx = (struct omap3_processor_cx *)cpuidle_get_statedata(curr);
+
+	/* Check if current state is valid */
+	if (cx->valid) {
+		return curr;
+	} else {
+		u8 idx = OMAP3_STATE_MAX;
+
+		/*
+		 * Reach the current state starting at highest C-state
+		 */
+		for (; idx >= OMAP3_STATE_C1; idx--) {
+			if (&dev->states[idx] == curr) {
+				next = &dev->states[idx];
+				break;
+			}
+		}
+
+		/*
+		 * Should never hit this condition.
+		 */
+		WARN_ON(next == NULL);
+
+		/*
+		 * Drop to next valid state.
+		 * Start search from the next (lower) state.
+		 */
+		idx--;
+		for (; idx >= OMAP3_STATE_C1; idx--) {
+			struct omap3_processor_cx *cx;
+
+			cx = cpuidle_get_statedata(&dev->states[idx]);
+			if (cx->valid) {
+				next = &dev->states[idx];
+				break;
+			}
+		}
+		/*
+		 * C1 and C2 are always valid.
+		 * So, no need to check for 'next==NULL' outside this loop.
+		 */
+	}
+
+	return next;
+}
+
+/**
  * omap3_enter_idle_bm - Checks for any bus activity
  * @dev: cpuidle device
  * @state: The target state to be programmed
@@ -152,7 +232,7 @@ return_sleep_time:
 static int omap3_enter_idle_bm(struct cpuidle_device *dev,
 			       struct cpuidle_state *state)
 {
-	struct cpuidle_state *new_state = state;
+	struct cpuidle_state *new_state = next_valid_state(dev, state);
 
 	if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
 		BUG_ON(!dev->safe_state);
@@ -165,6 +245,50 @@ static int omap3_enter_idle_bm(struct cp
 
 DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
 
+/**
+ * omap3_cpuidle_update_states - Update the cpuidle states.
+ *
+ * Currently, this function toggles the validity of idle states based upon
+ * the flag 'enable_off_mode'. When the flag is set all states are valid.
+ * Else, states leading to OFF state set to be invalid.
+ */
+void omap3_cpuidle_update_states(void)
+{
+	int i;
+
+	for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) {
+		struct omap3_processor_cx *cx = &omap3_power_states[i];
+
+		if (enable_off_mode) {
+			cx->valid = 1;
+		} else {
+			if ((cx->mpu_state == PWRDM_POWER_OFF) ||
+				(cx->core_state	== PWRDM_POWER_OFF))
+				cx->valid = 0;
+		}
+	}
+}
+
+void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
+{
+	int i;
+
+	if (!cpuidle_board_params)
+		return;
+
+	for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) {
+		cpuidle_params_table[i].valid =
+			cpuidle_board_params[i].valid;
+		cpuidle_params_table[i].sleep_latency =
+			cpuidle_board_params[i].sleep_latency;
+		cpuidle_params_table[i].wake_latency =
+			cpuidle_board_params[i].wake_latency;
+		cpuidle_params_table[i].threshold =
+			cpuidle_board_params[i].threshold;
+	}
+	return;
+}
+
 /* omap3_init_power_states - Initialises the OMAP3 specific C states.
  *
  * Below is the desciption of each C state.
@@ -179,75 +303,103 @@ DEFINE_PER_CPU(struct cpuidle_device, om
 void omap_init_power_states(void)
 {
 	/* C1 . MPU WFI + Core active */
-	omap3_power_states[OMAP3_STATE_C1].valid = 1;
+	omap3_power_states[OMAP3_STATE_C1].valid =
+			cpuidle_params_table[OMAP3_STATE_C1].valid;
 	omap3_power_states[OMAP3_STATE_C1].type = OMAP3_STATE_C1;
-	omap3_power_states[OMAP3_STATE_C1].sleep_latency = 2;
-	omap3_power_states[OMAP3_STATE_C1].wakeup_latency = 2;
-	omap3_power_states[OMAP3_STATE_C1].threshold = 5;
+	omap3_power_states[OMAP3_STATE_C1].sleep_latency =
+			cpuidle_params_table[OMAP3_STATE_C1].sleep_latency;
+	omap3_power_states[OMAP3_STATE_C1].wakeup_latency =
+			cpuidle_params_table[OMAP3_STATE_C1].wake_latency;
+	omap3_power_states[OMAP3_STATE_C1].threshold =
+			cpuidle_params_table[OMAP3_STATE_C1].threshold;
 	omap3_power_states[OMAP3_STATE_C1].mpu_state = PWRDM_POWER_ON;
 	omap3_power_states[OMAP3_STATE_C1].core_state = PWRDM_POWER_ON;
 	omap3_power_states[OMAP3_STATE_C1].flags = CPUIDLE_FLAG_TIME_VALID;
 
 	/* C2 . MPU WFI + Core inactive */
-	omap3_power_states[OMAP3_STATE_C2].valid = 1;
+	omap3_power_states[OMAP3_STATE_C2].valid =
+			cpuidle_params_table[OMAP3_STATE_C2].valid;
 	omap3_power_states[OMAP3_STATE_C2].type = OMAP3_STATE_C2;
-	omap3_power_states[OMAP3_STATE_C2].sleep_latency = 10;
-	omap3_power_states[OMAP3_STATE_C2].wakeup_latency = 10;
-	omap3_power_states[OMAP3_STATE_C2].threshold = 30;
+	omap3_power_states[OMAP3_STATE_C2].sleep_latency =
+			cpuidle_params_table[OMAP3_STATE_C2].sleep_latency;
+	omap3_power_states[OMAP3_STATE_C2].wakeup_latency =
+			cpuidle_params_table[OMAP3_STATE_C2].wake_latency;
+	omap3_power_states[OMAP3_STATE_C2].threshold =
+			cpuidle_params_table[OMAP3_STATE_C2].threshold;
 	omap3_power_states[OMAP3_STATE_C2].mpu_state = PWRDM_POWER_ON;
 	omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON;
 	omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID;
 
 	/* C3 . MPU CSWR + Core inactive */
-	omap3_power_states[OMAP3_STATE_C3].valid = 1;
+	omap3_power_states[OMAP3_STATE_C3].valid =
+			cpuidle_params_table[OMAP3_STATE_C3].valid;
 	omap3_power_states[OMAP3_STATE_C3].type = OMAP3_STATE_C3;
-	omap3_power_states[OMAP3_STATE_C3].sleep_latency = 50;
-	omap3_power_states[OMAP3_STATE_C3].wakeup_latency = 50;
-	omap3_power_states[OMAP3_STATE_C3].threshold = 300;
+	omap3_power_states[OMAP3_STATE_C3].sleep_latency =
+			cpuidle_params_table[OMAP3_STATE_C3].sleep_latency;
+	omap3_power_states[OMAP3_STATE_C3].wakeup_latency =
+			cpuidle_params_table[OMAP3_STATE_C3].wake_latency;
+	omap3_power_states[OMAP3_STATE_C3].threshold =
+			cpuidle_params_table[OMAP3_STATE_C3].threshold;
 	omap3_power_states[OMAP3_STATE_C3].mpu_state = PWRDM_POWER_RET;
 	omap3_power_states[OMAP3_STATE_C3].core_state = PWRDM_POWER_ON;
 	omap3_power_states[OMAP3_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID |
 				CPUIDLE_FLAG_CHECK_BM;
 
 	/* C4 . MPU OFF + Core inactive */
-	omap3_power_states[OMAP3_STATE_C4].valid = 1;
+	omap3_power_states[OMAP3_STATE_C4].valid =
+			cpuidle_params_table[OMAP3_STATE_C4].valid;
 	omap3_power_states[OMAP3_STATE_C4].type = OMAP3_STATE_C4;
-	omap3_power_states[OMAP3_STATE_C4].sleep_latency = 1500;
-	omap3_power_states[OMAP3_STATE_C4].wakeup_latency = 1800;
-	omap3_power_states[OMAP3_STATE_C4].threshold = 4000;
+	omap3_power_states[OMAP3_STATE_C4].sleep_latency =
+			cpuidle_params_table[OMAP3_STATE_C4].sleep_latency;
+	omap3_power_states[OMAP3_STATE_C4].wakeup_latency =
+			cpuidle_params_table[OMAP3_STATE_C4].wake_latency;
+	omap3_power_states[OMAP3_STATE_C4].threshold =
+			cpuidle_params_table[OMAP3_STATE_C4].threshold;
 	omap3_power_states[OMAP3_STATE_C4].mpu_state = PWRDM_POWER_OFF;
 	omap3_power_states[OMAP3_STATE_C4].core_state = PWRDM_POWER_ON;
 	omap3_power_states[OMAP3_STATE_C4].flags = CPUIDLE_FLAG_TIME_VALID |
 				CPUIDLE_FLAG_CHECK_BM;
 
 	/* C5 . MPU CSWR + Core CSWR*/
-	omap3_power_states[OMAP3_STATE_C5].valid = 1;
+	omap3_power_states[OMAP3_STATE_C5].valid =
+			cpuidle_params_table[OMAP3_STATE_C5].valid;
 	omap3_power_states[OMAP3_STATE_C5].type = OMAP3_STATE_C5;
-	omap3_power_states[OMAP3_STATE_C5].sleep_latency = 2500;
-	omap3_power_states[OMAP3_STATE_C5].wakeup_latency = 7500;
-	omap3_power_states[OMAP3_STATE_C5].threshold = 12000;
+	omap3_power_states[OMAP3_STATE_C5].sleep_latency =
+			cpuidle_params_table[OMAP3_STATE_C5].sleep_latency;
+	omap3_power_states[OMAP3_STATE_C5].wakeup_latency =
+			cpuidle_params_table[OMAP3_STATE_C5].wake_latency;
+	omap3_power_states[OMAP3_STATE_C5].threshold =
+			cpuidle_params_table[OMAP3_STATE_C5].threshold;
 	omap3_power_states[OMAP3_STATE_C5].mpu_state = PWRDM_POWER_RET;
 	omap3_power_states[OMAP3_STATE_C5].core_state = PWRDM_POWER_RET;
 	omap3_power_states[OMAP3_STATE_C5].flags = CPUIDLE_FLAG_TIME_VALID |
 				CPUIDLE_FLAG_CHECK_BM;
 
 	/* C6 . MPU OFF + Core CSWR */
-	omap3_power_states[OMAP3_STATE_C6].valid = 1;
+	omap3_power_states[OMAP3_STATE_C6].valid =
+			cpuidle_params_table[OMAP3_STATE_C6].valid;
 	omap3_power_states[OMAP3_STATE_C6].type = OMAP3_STATE_C6;
-	omap3_power_states[OMAP3_STATE_C6].sleep_latency = 3000;
-	omap3_power_states[OMAP3_STATE_C6].wakeup_latency = 8500;
-	omap3_power_states[OMAP3_STATE_C6].threshold = 15000;
+	omap3_power_states[OMAP3_STATE_C6].sleep_latency =
+			cpuidle_params_table[OMAP3_STATE_C6].sleep_latency;
+	omap3_power_states[OMAP3_STATE_C6].wakeup_latency =
+			cpuidle_params_table[OMAP3_STATE_C6].wake_latency;
+	omap3_power_states[OMAP3_STATE_C6].threshold =
+			cpuidle_params_table[OMAP3_STATE_C6].threshold;
 	omap3_power_states[OMAP3_STATE_C6].mpu_state = PWRDM_POWER_OFF;
 	omap3_power_states[OMAP3_STATE_C6].core_state = PWRDM_POWER_RET;
 	omap3_power_states[OMAP3_STATE_C6].flags = CPUIDLE_FLAG_TIME_VALID |
 				CPUIDLE_FLAG_CHECK_BM;
 
 	/* C7 . MPU OFF + Core OFF */
-	omap3_power_states[OMAP3_STATE_C7].valid = 1;
+	omap3_power_states[OMAP3_STATE_C7].valid =
+			cpuidle_params_table[OMAP3_STATE_C7].valid;
 	omap3_power_states[OMAP3_STATE_C7].type = OMAP3_STATE_C7;
-	omap3_power_states[OMAP3_STATE_C7].sleep_latency = 10000;
-	omap3_power_states[OMAP3_STATE_C7].wakeup_latency = 30000;
-	omap3_power_states[OMAP3_STATE_C7].threshold = 300000;
+	omap3_power_states[OMAP3_STATE_C7].sleep_latency =
+			cpuidle_params_table[OMAP3_STATE_C7].sleep_latency;
+	omap3_power_states[OMAP3_STATE_C7].wakeup_latency =
+			cpuidle_params_table[OMAP3_STATE_C7].wake_latency;
+	omap3_power_states[OMAP3_STATE_C7].threshold =
+			cpuidle_params_table[OMAP3_STATE_C7].threshold;
 	omap3_power_states[OMAP3_STATE_C7].mpu_state = PWRDM_POWER_OFF;
 	omap3_power_states[OMAP3_STATE_C7].core_state = PWRDM_POWER_OFF;
 	omap3_power_states[OMAP3_STATE_C7].flags = CPUIDLE_FLAG_TIME_VALID |
@@ -302,6 +454,8 @@ int __init omap3_idle_init(void)
 		return -EINVAL;
 	dev->state_count = count;
 
+	omap3_cpuidle_update_states();
+
 	if (cpuidle_register_device(dev)) {
 		printk(KERN_ERR "%s: CPUidle register device failed\n",
 		       __func__);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/devices.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/devices.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/devices.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/devices.c	2010-05-16 17:17:36.000000000 -0400
@@ -141,7 +141,7 @@ static inline void omap_init_camera(void
 #define MBOX_REG_SIZE   0x120
 
 #ifdef CONFIG_ARCH_OMAP2
-static struct resource omap_mbox_resources[] = {
+static struct resource omap2_mbox_resources[] = {
 	{
 		.start		= OMAP24XX_MAILBOX_BASE,
 		.end		= OMAP24XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
@@ -156,10 +156,14 @@ static struct resource omap_mbox_resourc
 		.flags		= IORESOURCE_IRQ,
 	},
 };
+static int omap2_mbox_resources_sz = ARRAY_SIZE(omap2_mbox_resources);
+#else
+#define omap2_mbox_resources		NULL
+#define omap2_mbox_resources_sz		0
 #endif
 
 #ifdef CONFIG_ARCH_OMAP3
-static struct resource omap_mbox_resources[] = {
+static struct resource omap3_mbox_resources[] = {
 	{
 		.start		= OMAP34XX_MAILBOX_BASE,
 		.end		= OMAP34XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
@@ -170,12 +174,16 @@ static struct resource omap_mbox_resourc
 		.flags		= IORESOURCE_IRQ,
 	},
 };
+static int omap3_mbox_resources_sz = ARRAY_SIZE(omap3_mbox_resources);
+#else
+#define omap3_mbox_resources		NULL
+#define omap3_mbox_resources_sz		0
 #endif
 
 #ifdef CONFIG_ARCH_OMAP4
 
 #define OMAP4_MBOX_REG_SIZE	0x130
-static struct resource omap_mbox_resources[] = {
+static struct resource omap4_mbox_resources[] = {
 	{
 		.start          = OMAP44XX_MAILBOX_BASE,
 		.end            = OMAP44XX_MAILBOX_BASE +
@@ -183,10 +191,14 @@ static struct resource omap_mbox_resourc
 		.flags          = IORESOURCE_MEM,
 	},
 	{
-		.start          = INT_44XX_MAIL_U0_MPU,
+		.start          = OMAP44XX_IRQ_MAIL_U0,
 		.flags          = IORESOURCE_IRQ,
 	},
 };
+static int omap4_mbox_resources_sz = ARRAY_SIZE(omap4_mbox_resources);
+#else
+#define omap4_mbox_resources		NULL
+#define omap4_mbox_resources_sz		0
 #endif
 
 static struct platform_device mbox_device = {
@@ -196,9 +208,15 @@ static struct platform_device mbox_devic
 
 static inline void omap_init_mbox(void)
 {
-	if (cpu_is_omap2420() || cpu_is_omap3430() || cpu_is_omap44xx()) {
-		mbox_device.num_resources = ARRAY_SIZE(omap_mbox_resources);
-		mbox_device.resource = omap_mbox_resources;
+	if (cpu_is_omap24xx()) {
+		mbox_device.resource = omap2_mbox_resources;
+		mbox_device.num_resources = omap2_mbox_resources_sz;
+	} else if (cpu_is_omap34xx()) {
+		mbox_device.resource = omap3_mbox_resources;
+		mbox_device.num_resources = omap3_mbox_resources_sz;
+	} else if (cpu_is_omap44xx()) {
+		mbox_device.resource = omap4_mbox_resources;
+		mbox_device.num_resources = omap4_mbox_resources_sz;
 	} else {
 		pr_err("%s: platform not supported\n", __func__);
 		return;
@@ -492,7 +510,12 @@ static struct platform_device dummy_pdev
  **/
 static void __init omap_hsmmc_reset(void)
 {
-	u32 i, nr_controllers = cpu_is_omap44xx() ? OMAP44XX_NR_MMC :
+	u32 i, nr_controllers;
+
+	if (cpu_is_omap242x())
+		return;
+
+	nr_controllers = cpu_is_omap44xx() ? OMAP44XX_NR_MMC :
 		(cpu_is_omap34xx() ? OMAP34XX_NR_MMC : OMAP24XX_NR_MMC);
 
 	for (i = 0; i < nr_controllers; i++) {
@@ -697,13 +720,13 @@ void __init omap2_init_mmc(struct omap_m
 			if (!cpu_is_omap44xx())
 				return;
 			base = OMAP4_MMC4_BASE + OMAP4_MMC_REG_OFFSET;
-			irq = INT_44XX_MMC4_IRQ;
+			irq = OMAP44XX_IRQ_MMC4;
 			break;
 		case 4:
 			if (!cpu_is_omap44xx())
 				return;
 			base = OMAP4_MMC5_BASE + OMAP4_MMC_REG_OFFSET;
-			irq = INT_44XX_MMC5_IRQ;
+			irq = OMAP44XX_IRQ_MMC5;
 			break;
 		default:
 			continue;
@@ -715,7 +738,7 @@ void __init omap2_init_mmc(struct omap_m
 		} else if (cpu_is_omap44xx()) {
 			if (i < 3) {
 				base += OMAP4_MMC_REG_OFFSET;
-				irq += IRQ_GIC_START;
+				irq += OMAP44XX_IRQ_GIC_START;
 			}
 			size = OMAP4_HSMMC_SIZE;
 			name = "mmci-omap-hs";
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/dpll3xxx.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/dpll3xxx.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/dpll3xxx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/dpll3xxx.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,599 @@
+/*
+ * OMAP3/4 - specific DPLL control functions
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ * Testing and integration fixes by Jouni HÃ¶gander
+ *
+ * 36xx support added by Vishwanath BS, Richard Woodruff, and Nishanth
+ * Menon
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <asm/clkdev.h>
+
+#include "clock.h"
+#include "prm.h"
+#include "prm-regbits-34xx.h"
+#include "cm.h"
+#include "cm-regbits-34xx.h"
+
+/* CM_AUTOIDLE_PLL*.AUTO_* bit values */
+#define DPLL_AUTOIDLE_DISABLE			0x0
+#define DPLL_AUTOIDLE_LOW_POWER_STOP		0x1
+
+#define MAX_DPLL_WAIT_TRIES		1000000
+
+/* Private functions */
+
+/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
+static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
+{
+	const struct dpll_data *dd;
+	u32 v;
+
+	dd = clk->dpll_data;
+
+	v = __raw_readl(dd->control_reg);
+	v &= ~dd->enable_mask;
+	v |= clken_bits << __ffs(dd->enable_mask);
+	__raw_writel(v, dd->control_reg);
+}
+
+/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */
+static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
+{
+	const struct dpll_data *dd;
+	int i = 0;
+	int ret = -EINVAL;
+
+	dd = clk->dpll_data;
+
+	state <<= __ffs(dd->idlest_mask);
+
+	while (((__raw_readl(dd->idlest_reg) & dd->idlest_mask) != state) &&
+	       i < MAX_DPLL_WAIT_TRIES) {
+		i++;
+		udelay(1);
+	}
+
+	if (i == MAX_DPLL_WAIT_TRIES) {
+		printk(KERN_ERR "clock: %s failed transition to '%s'\n",
+		       clk->name, (state) ? "locked" : "bypassed");
+	} else {
+		pr_debug("clock: %s transition to '%s' in %d loops\n",
+			 clk->name, (state) ? "locked" : "bypassed", i);
+
+		ret = 0;
+	}
+
+	return ret;
+}
+
+/* From 3430 TRM ES2 4.7.6.2 */
+static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
+{
+	unsigned long fint;
+	u16 f = 0;
+
+	fint = clk->dpll_data->clk_ref->rate / n;
+
+	pr_debug("clock: fint is %lu\n", fint);
+
+	if (fint >= 750000 && fint <= 1000000)
+		f = 0x3;
+	else if (fint > 1000000 && fint <= 1250000)
+		f = 0x4;
+	else if (fint > 1250000 && fint <= 1500000)
+		f = 0x5;
+	else if (fint > 1500000 && fint <= 1750000)
+		f = 0x6;
+	else if (fint > 1750000 && fint <= 2100000)
+		f = 0x7;
+	else if (fint > 7500000 && fint <= 10000000)
+		f = 0xB;
+	else if (fint > 10000000 && fint <= 12500000)
+		f = 0xC;
+	else if (fint > 12500000 && fint <= 15000000)
+		f = 0xD;
+	else if (fint > 15000000 && fint <= 17500000)
+		f = 0xE;
+	else if (fint > 17500000 && fint <= 21000000)
+		f = 0xF;
+	else
+		pr_debug("clock: unknown freqsel setting for %d\n", n);
+
+	return f;
+}
+
+/*
+ * _omap3_noncore_dpll_lock - instruct a DPLL to lock and wait for readiness
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to lock.  Waits for the DPLL to report
+ * readiness before returning.  Will save and restore the DPLL's
+ * autoidle state across the enable, per the CDP code.  If the DPLL
+ * locked successfully, return 0; if the DPLL did not lock in the time
+ * allotted, or DPLL3 was passed in, return -EINVAL.
+ */
+static int _omap3_noncore_dpll_lock(struct clk *clk)
+{
+	u8 ai;
+	int r;
+
+	pr_debug("clock: locking DPLL %s\n", clk->name);
+
+	ai = omap3_dpll_autoidle_read(clk);
+
+	omap3_dpll_deny_idle(clk);
+
+	_omap3_dpll_write_clken(clk, DPLL_LOCKED);
+
+	r = _omap3_wait_dpll_status(clk, 1);
+
+	if (ai)
+		omap3_dpll_allow_idle(clk);
+
+	return r;
+}
+
+/*
+ * _omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enter low-power bypass mode.  In
+ * bypass mode, the DPLL's rate is set equal to its parent clock's
+ * rate.  Waits for the DPLL to report readiness before returning.
+ * Will save and restore the DPLL's autoidle state across the enable,
+ * per the CDP code.  If the DPLL entered bypass mode successfully,
+ * return 0; if the DPLL did not enter bypass in the time allotted, or
+ * DPLL3 was passed in, or the DPLL does not support low-power bypass,
+ * return -EINVAL.
+ */
+static int _omap3_noncore_dpll_bypass(struct clk *clk)
+{
+	int r;
+	u8 ai;
+
+	if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS)))
+		return -EINVAL;
+
+	pr_debug("clock: configuring DPLL %s for low-power bypass\n",
+		 clk->name);
+
+	ai = omap3_dpll_autoidle_read(clk);
+
+	_omap3_dpll_write_clken(clk, DPLL_LOW_POWER_BYPASS);
+
+	r = _omap3_wait_dpll_status(clk, 0);
+
+	if (ai)
+		omap3_dpll_allow_idle(clk);
+	else
+		omap3_dpll_deny_idle(clk);
+
+	return r;
+}
+
+/*
+ * _omap3_noncore_dpll_stop - instruct a DPLL to stop
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enter low-power stop. Will save and
+ * restore the DPLL's autoidle state across the stop, per the CDP
+ * code.  If DPLL3 was passed in, or the DPLL does not support
+ * low-power stop, return -EINVAL; otherwise, return 0.
+ */
+static int _omap3_noncore_dpll_stop(struct clk *clk)
+{
+	u8 ai;
+
+	if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP)))
+		return -EINVAL;
+
+	pr_debug("clock: stopping DPLL %s\n", clk->name);
+
+	ai = omap3_dpll_autoidle_read(clk);
+
+	_omap3_dpll_write_clken(clk, DPLL_LOW_POWER_STOP);
+
+	if (ai)
+		omap3_dpll_allow_idle(clk);
+	else
+		omap3_dpll_deny_idle(clk);
+
+	return 0;
+}
+
+/**
+ * lookup_dco_sddiv -  Set j-type DPLL4 compensation variables
+ * @clk: pointer to a DPLL struct clk
+ * @dco: digital control oscillator selector
+ * @sd_div: target sigma-delta divider
+ * @m: DPLL multiplier to set
+ * @n: DPLL divider to set
+ *
+ * See 36xx TRM section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)"
+ *
+ * XXX This code is not needed for 3430/AM35xx; can it be optimized
+ * out in non-multi-OMAP builds for those chips?
+ */
+static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 m,
+			     u8 n)
+{
+	unsigned long fint, clkinp, sd; /* watch out for overflow */
+	int mod1, mod2;
+
+	clkinp = clk->parent->rate;
+	fint = (clkinp / n) * m;
+
+	if (fint < 1000000000)
+		*dco = 2;
+	else
+		*dco = 4;
+	/*
+	 * target sigma-delta to near 250MHz
+	 * sd = ceil[(m/(n+1)) * (clkinp_MHz / 250)]
+	 */
+	clkinp /= 100000; /* shift from MHz to 10*Hz for 38.4 and 19.2 */
+	mod1 = (clkinp * m) % (250 * n);
+	sd = (clkinp * m) / (250 * n);
+	mod2 = sd % 10;
+	sd /= 10;
+
+	if (mod1 || mod2)
+		sd++;
+	*sd_div = sd;
+}
+
+/*
+ * _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. No jitter correction for OMAP4 and 3630
+	 * since freqsel field is no longer present
+	 */
+	if (!cpu_is_omap44xx() && !cpu_is_omap3630()) {
+		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);
+
+	/*
+	 * XXX This code is not needed for 3430/AM35XX; can it be optimized
+	 * out in non-multi-OMAP builds for those chips?
+	 */
+	if ((dd->flags & DPLL_J_TYPE) && !(dd->flags & DPLL_NO_DCO_SEL)) {
+		u8 dco, sd_div;
+		lookup_dco_sddiv(clk, &dco, &sd_div, m, n);
+		/* XXX This probably will need revision for OMAP4 */
+		v &= ~(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK
+			| OMAP3630_PERIPH_DPLL_SD_DIV_MASK);
+		v |= dco << __ffs(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK);
+		v |= sd_div << __ffs(OMAP3630_PERIPH_DPLL_SD_DIV_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;
+}
+
+/* Public functions */
+
+/**
+ * omap3_dpll_recalc - recalculate DPLL rate
+ * @clk: DPLL struct clk
+ *
+ * Recalculate and propagate the DPLL rate.
+ */
+unsigned long omap3_dpll_recalc(struct clk *clk)
+{
+	return omap2_get_dpll_rate(clk);
+}
+
+/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */
+
+/**
+ * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock.
+ * The choice of modes depends on the DPLL's programmed rate: if it is
+ * the same as the DPLL's parent clock, it will enter bypass;
+ * otherwise, it will enter lock.  This code will wait for the DPLL to
+ * indicate readiness before returning, unless the DPLL takes too long
+ * to enter the target state.  Intended to be used as the struct clk's
+ * enable function.  If DPLL3 was passed in, or the DPLL does not
+ * support low-power stop, or if the DPLL took too long to enter
+ * bypass or lock, return -EINVAL; otherwise, return 0.
+ */
+int omap3_noncore_dpll_enable(struct clk *clk)
+{
+	int r;
+	struct dpll_data *dd;
+
+	dd = clk->dpll_data;
+	if (!dd)
+		return -EINVAL;
+
+	if (clk->rate == dd->clk_bypass->rate) {
+		WARN_ON(clk->parent != dd->clk_bypass);
+		r = _omap3_noncore_dpll_bypass(clk);
+	} else {
+		WARN_ON(clk->parent != dd->clk_ref);
+		r = _omap3_noncore_dpll_lock(clk);
+	}
+	/*
+	 *FIXME: this is dubious - if clk->rate has changed, what about
+	 * propagating?
+	 */
+	if (!r)
+		clk->rate = omap2_get_dpll_rate(clk);
+
+	return r;
+}
+
+/**
+ * omap3_noncore_dpll_disable - instruct a DPLL to enter low-power stop
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enter low-power stop.  This function is
+ * intended for use in struct clkops.  No return value.
+ */
+void omap3_noncore_dpll_disable(struct clk *clk)
+{
+	_omap3_noncore_dpll_stop(clk);
+}
+
+
+/* Non-CORE DPLL rate set code */
+
+/**
+ * omap3_noncore_dpll_set_rate - set non-core DPLL rate
+ * @clk: struct clk * of DPLL to set
+ * @rate: rounded target rate
+ *
+ * Set the DPLL CLKOUT to the target rate.  If the DPLL can enter
+ * low-power bypass, and the target rate is the bypass source clock
+ * rate, then configure the DPLL for bypass.  Otherwise, round the
+ * target rate if it hasn't been done already, then program and lock
+ * the DPLL.  Returns -EINVAL upon error, or 0 upon success.
+ */
+int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
+{
+	struct clk *new_parent = NULL;
+	u16 freqsel = 0;
+	struct dpll_data *dd;
+	int ret;
+
+	if (!clk || !rate)
+		return -EINVAL;
+
+	dd = clk->dpll_data;
+	if (!dd)
+		return -EINVAL;
+
+	if (rate == omap2_get_dpll_rate(clk))
+		return 0;
+
+	/*
+	 * Ensure both the bypass and ref clocks are enabled prior to
+	 * doing anything; we need the bypass clock running to reprogram
+	 * the DPLL.
+	 */
+	omap2_clk_enable(dd->clk_bypass);
+	omap2_clk_enable(dd->clk_ref);
+
+	if (dd->clk_bypass->rate == rate &&
+	    (clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
+		pr_debug("clock: %s: set rate: entering bypass.\n", clk->name);
+
+		ret = _omap3_noncore_dpll_bypass(clk);
+		if (!ret)
+			new_parent = dd->clk_bypass;
+	} else {
+		if (dd->last_rounded_rate != rate)
+			omap2_dpll_round_rate(clk, rate);
+
+		if (dd->last_rounded_rate == 0)
+			return -EINVAL;
+
+		/* No freqsel on OMAP4 and OMAP3630 */
+		if (!cpu_is_omap44xx() && !cpu_is_omap3630()) {
+			freqsel = _omap3_dpll_compute_freqsel(clk,
+						dd->last_rounded_n);
+			if (!freqsel)
+				WARN_ON(1);
+		}
+
+		pr_debug("clock: %s: set rate: locking rate to %lu.\n",
+			 clk->name, rate);
+
+		ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m,
+						 dd->last_rounded_n, freqsel);
+		if (!ret)
+			new_parent = dd->clk_ref;
+	}
+	if (!ret) {
+		/*
+		 * Switch the parent clock in the heirarchy, and make sure
+		 * that the new parent's usecount is correct.  Note: we
+		 * enable the new parent before disabling the old to avoid
+		 * any unnecessary hardware disable->enable transitions.
+		 */
+		if (clk->usecount) {
+			omap2_clk_enable(new_parent);
+			omap2_clk_disable(clk->parent);
+		}
+		clk_reparent(clk, new_parent);
+		clk->rate = rate;
+	}
+	omap2_clk_disable(dd->clk_ref);
+	omap2_clk_disable(dd->clk_bypass);
+
+	return 0;
+}
+
+/* DPLL autoidle read/set code */
+
+/**
+ * omap3_dpll_autoidle_read - read a DPLL's autoidle bits
+ * @clk: struct clk * of the DPLL to read
+ *
+ * Return the DPLL's autoidle bits, shifted down to bit 0.  Returns
+ * -EINVAL if passed a null pointer or if the struct clk does not
+ * appear to refer to a DPLL.
+ */
+u32 omap3_dpll_autoidle_read(struct clk *clk)
+{
+	const struct dpll_data *dd;
+	u32 v;
+
+	if (!clk || !clk->dpll_data)
+		return -EINVAL;
+
+	dd = clk->dpll_data;
+
+	v = __raw_readl(dd->autoidle_reg);
+	v &= dd->autoidle_mask;
+	v >>= __ffs(dd->autoidle_mask);
+
+	return v;
+}
+
+/**
+ * omap3_dpll_allow_idle - enable DPLL autoidle bits
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Enable DPLL automatic idle control.  This automatic idle mode
+ * switching takes effect only when the DPLL is locked, at least on
+ * OMAP3430.  The DPLL will enter low-power stop when its downstream
+ * clocks are gated.  No return value.
+ */
+void omap3_dpll_allow_idle(struct clk *clk)
+{
+	const struct dpll_data *dd;
+	u32 v;
+
+	if (!clk || !clk->dpll_data)
+		return;
+
+	dd = clk->dpll_data;
+
+	/*
+	 * REVISIT: CORE DPLL can optionally enter low-power bypass
+	 * by writing 0x5 instead of 0x1.  Add some mechanism to
+	 * optionally enter this mode.
+	 */
+	v = __raw_readl(dd->autoidle_reg);
+	v &= ~dd->autoidle_mask;
+	v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask);
+	__raw_writel(v, dd->autoidle_reg);
+}
+
+/**
+ * omap3_dpll_deny_idle - prevent DPLL from automatically idling
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Disable DPLL automatic idle control.  No return value.
+ */
+void omap3_dpll_deny_idle(struct clk *clk)
+{
+	const struct dpll_data *dd;
+	u32 v;
+
+	if (!clk || !clk->dpll_data)
+		return;
+
+	dd = clk->dpll_data;
+
+	v = __raw_readl(dd->autoidle_reg);
+	v &= ~dd->autoidle_mask;
+	v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask);
+	__raw_writel(v, dd->autoidle_reg);
+
+}
+
+/* Clock control for DPLL outputs */
+
+/**
+ * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate
+ * @clk: DPLL output struct clk
+ *
+ * Using parent clock DPLL data, look up DPLL state.  If locked, set our
+ * rate to the dpll_clk * 2; otherwise, just use dpll_clk.
+ */
+unsigned long omap3_clkoutx2_recalc(struct clk *clk)
+{
+	const struct dpll_data *dd;
+	unsigned long rate;
+	u32 v;
+	struct clk *pclk;
+
+	/* Walk up the parents of clk, looking for a DPLL */
+	pclk = clk->parent;
+	while (pclk && !pclk->dpll_data)
+		pclk = pclk->parent;
+
+	/* clk does not have a DPLL as a parent? */
+	WARN_ON(!pclk);
+
+	dd = pclk->dpll_data;
+
+	WARN_ON(!dd->enable_mask);
+
+	v = __raw_readl(dd->control_reg) & dd->enable_mask;
+	v >>= __ffs(dd->enable_mask);
+	if ((v != OMAP3XXX_EN_DPLL_LOCKED) || (dd->flags & DPLL_J_TYPE))
+		rate = clk->parent->rate;
+	else
+		rate = clk->parent->rate * 2;
+	return rate;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/dpll.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/dpll.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/dpll.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/dpll.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,538 +0,0 @@
-/*
- * OMAP3/4 - specific DPLL control functions
- *
- * Copyright (C) 2009 Texas Instruments, Inc.
- * Copyright (C) 2009 Nokia Corporation
- *
- * Written by Paul Walmsley
- * Testing and integration fixes by Jouni HÃƒÂ¶gander
- *
- * Parts of this code are based on code written by
- * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/limits.h>
-#include <linux/bitops.h>
-
-#include <plat/cpu.h>
-#include <plat/clock.h>
-#include <plat/sram.h>
-#include <asm/div64.h>
-#include <asm/clkdev.h>
-
-#include "clock.h"
-#include "prm.h"
-#include "prm-regbits-34xx.h"
-#include "cm.h"
-#include "cm-regbits-34xx.h"
-
-/* CM_AUTOIDLE_PLL*.AUTO_* bit values */
-#define DPLL_AUTOIDLE_DISABLE			0x0
-#define DPLL_AUTOIDLE_LOW_POWER_STOP		0x1
-
-#define MAX_DPLL_WAIT_TRIES		1000000
-
-
-/**
- * omap3_dpll_recalc - recalculate DPLL rate
- * @clk: DPLL struct clk
- *
- * Recalculate and propagate the DPLL rate.
- */
-unsigned long omap3_dpll_recalc(struct clk *clk)
-{
-	return omap2_get_dpll_rate(clk);
-}
-
-/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
-static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
-{
-	const struct dpll_data *dd;
-	u32 v;
-
-	dd = clk->dpll_data;
-
-	v = __raw_readl(dd->control_reg);
-	v &= ~dd->enable_mask;
-	v |= clken_bits << __ffs(dd->enable_mask);
-	__raw_writel(v, dd->control_reg);
-}
-
-/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */
-static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
-{
-	const struct dpll_data *dd;
-	int i = 0;
-	int ret = -EINVAL;
-
-	dd = clk->dpll_data;
-
-	state <<= __ffs(dd->idlest_mask);
-
-	while (((__raw_readl(dd->idlest_reg) & dd->idlest_mask) != state) &&
-	       i < MAX_DPLL_WAIT_TRIES) {
-		i++;
-		udelay(1);
-	}
-
-	if (i == MAX_DPLL_WAIT_TRIES) {
-		printk(KERN_ERR "clock: %s failed transition to '%s'\n",
-		       clk->name, (state) ? "locked" : "bypassed");
-	} else {
-		pr_debug("clock: %s transition to '%s' in %d loops\n",
-			 clk->name, (state) ? "locked" : "bypassed", i);
-
-		ret = 0;
-	}
-
-	return ret;
-}
-
-/* From 3430 TRM ES2 4.7.6.2 */
-static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
-{
-	unsigned long fint;
-	u16 f = 0;
-
-	fint = clk->dpll_data->clk_ref->rate / n;
-
-	pr_debug("clock: fint is %lu\n", fint);
-
-	if (fint >= 750000 && fint <= 1000000)
-		f = 0x3;
-	else if (fint > 1000000 && fint <= 1250000)
-		f = 0x4;
-	else if (fint > 1250000 && fint <= 1500000)
-		f = 0x5;
-	else if (fint > 1500000 && fint <= 1750000)
-		f = 0x6;
-	else if (fint > 1750000 && fint <= 2100000)
-		f = 0x7;
-	else if (fint > 7500000 && fint <= 10000000)
-		f = 0xB;
-	else if (fint > 10000000 && fint <= 12500000)
-		f = 0xC;
-	else if (fint > 12500000 && fint <= 15000000)
-		f = 0xD;
-	else if (fint > 15000000 && fint <= 17500000)
-		f = 0xE;
-	else if (fint > 17500000 && fint <= 21000000)
-		f = 0xF;
-	else
-		pr_debug("clock: unknown freqsel setting for %d\n", n);
-
-	return f;
-}
-
-/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */
-
-/*
- * _omap3_noncore_dpll_lock - instruct a DPLL to lock and wait for readiness
- * @clk: pointer to a DPLL struct clk
- *
- * Instructs a non-CORE DPLL to lock.  Waits for the DPLL to report
- * readiness before returning.  Will save and restore the DPLL's
- * autoidle state across the enable, per the CDP code.  If the DPLL
- * locked successfully, return 0; if the DPLL did not lock in the time
- * allotted, or DPLL3 was passed in, return -EINVAL.
- */
-static int _omap3_noncore_dpll_lock(struct clk *clk)
-{
-	u8 ai;
-	int r;
-
-	pr_debug("clock: locking DPLL %s\n", clk->name);
-
-	ai = omap3_dpll_autoidle_read(clk);
-
-	omap3_dpll_deny_idle(clk);
-
-	_omap3_dpll_write_clken(clk, DPLL_LOCKED);
-
-	r = _omap3_wait_dpll_status(clk, 1);
-
-	if (ai)
-		omap3_dpll_allow_idle(clk);
-
-	return r;
-}
-
-/*
- * _omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness
- * @clk: pointer to a DPLL struct clk
- *
- * Instructs a non-CORE DPLL to enter low-power bypass mode.  In
- * bypass mode, the DPLL's rate is set equal to its parent clock's
- * rate.  Waits for the DPLL to report readiness before returning.
- * Will save and restore the DPLL's autoidle state across the enable,
- * per the CDP code.  If the DPLL entered bypass mode successfully,
- * return 0; if the DPLL did not enter bypass in the time allotted, or
- * DPLL3 was passed in, or the DPLL does not support low-power bypass,
- * return -EINVAL.
- */
-static int _omap3_noncore_dpll_bypass(struct clk *clk)
-{
-	int r;
-	u8 ai;
-
-	if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS)))
-		return -EINVAL;
-
-	pr_debug("clock: configuring DPLL %s for low-power bypass\n",
-		 clk->name);
-
-	ai = omap3_dpll_autoidle_read(clk);
-
-	_omap3_dpll_write_clken(clk, DPLL_LOW_POWER_BYPASS);
-
-	r = _omap3_wait_dpll_status(clk, 0);
-
-	if (ai)
-		omap3_dpll_allow_idle(clk);
-	else
-		omap3_dpll_deny_idle(clk);
-
-	return r;
-}
-
-/*
- * _omap3_noncore_dpll_stop - instruct a DPLL to stop
- * @clk: pointer to a DPLL struct clk
- *
- * Instructs a non-CORE DPLL to enter low-power stop. Will save and
- * restore the DPLL's autoidle state across the stop, per the CDP
- * code.  If DPLL3 was passed in, or the DPLL does not support
- * low-power stop, return -EINVAL; otherwise, return 0.
- */
-static int _omap3_noncore_dpll_stop(struct clk *clk)
-{
-	u8 ai;
-
-	if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP)))
-		return -EINVAL;
-
-	pr_debug("clock: stopping DPLL %s\n", clk->name);
-
-	ai = omap3_dpll_autoidle_read(clk);
-
-	_omap3_dpll_write_clken(clk, DPLL_LOW_POWER_STOP);
-
-	if (ai)
-		omap3_dpll_allow_idle(clk);
-	else
-		omap3_dpll_deny_idle(clk);
-
-	return 0;
-}
-
-/**
- * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode
- * @clk: pointer to a DPLL struct clk
- *
- * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock.
- * The choice of modes depends on the DPLL's programmed rate: if it is
- * the same as the DPLL's parent clock, it will enter bypass;
- * otherwise, it will enter lock.  This code will wait for the DPLL to
- * indicate readiness before returning, unless the DPLL takes too long
- * to enter the target state.  Intended to be used as the struct clk's
- * enable function.  If DPLL3 was passed in, or the DPLL does not
- * support low-power stop, or if the DPLL took too long to enter
- * bypass or lock, return -EINVAL; otherwise, return 0.
- */
-int omap3_noncore_dpll_enable(struct clk *clk)
-{
-	int r;
-	struct dpll_data *dd;
-
-	dd = clk->dpll_data;
-	if (!dd)
-		return -EINVAL;
-
-	if (clk->rate == dd->clk_bypass->rate) {
-		WARN_ON(clk->parent != dd->clk_bypass);
-		r = _omap3_noncore_dpll_bypass(clk);
-	} else {
-		WARN_ON(clk->parent != dd->clk_ref);
-		r = _omap3_noncore_dpll_lock(clk);
-	}
-	/*
-	 *FIXME: this is dubious - if clk->rate has changed, what about
-	 * propagating?
-	 */
-	if (!r)
-		clk->rate = omap2_get_dpll_rate(clk);
-
-	return r;
-}
-
-/**
- * omap3_noncore_dpll_disable - instruct a DPLL to enter low-power stop
- * @clk: pointer to a DPLL struct clk
- *
- * Instructs a non-CORE DPLL to enter low-power stop.  This function is
- * intended for use in struct clkops.  No return value.
- */
-void omap3_noncore_dpll_disable(struct clk *clk)
-{
-	_omap3_noncore_dpll_stop(clk);
-}
-
-
-/* Non-CORE DPLL rate set code */
-
-/*
- * omap3_noncore_dpll_program - set non-core DPLL M,N values directly
- * @clk: struct clk * of DPLL to set
- * @m: DPLL multiplier to set
- * @n: DPLL divider to set
- * @freqsel: FREQSEL value to set
- *
- * Program the DPLL with the supplied M, N values, and wait for the DPLL to
- * lock..  Returns -EINVAL upon error, or 0 upon success.
- */
-int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
-{
-	struct dpll_data *dd = clk->dpll_data;
-	u32 v;
-
-	/* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
-	_omap3_noncore_dpll_bypass(clk);
-
-	/* Set jitter correction */
-	if (!cpu_is_omap44xx()) {
-		v = __raw_readl(dd->control_reg);
-		v &= ~dd->freqsel_mask;
-		v |= freqsel << __ffs(dd->freqsel_mask);
-		__raw_writel(v, dd->control_reg);
-	}
-
-	/* Set DPLL multiplier, divider */
-	v = __raw_readl(dd->mult_div1_reg);
-	v &= ~(dd->mult_mask | dd->div1_mask);
-	v |= m << __ffs(dd->mult_mask);
-	v |= (n - 1) << __ffs(dd->div1_mask);
-	__raw_writel(v, dd->mult_div1_reg);
-
-	/* We let the clock framework set the other output dividers later */
-
-	/* REVISIT: Set ramp-up delay? */
-
-	_omap3_noncore_dpll_lock(clk);
-
-	return 0;
-}
-
-/**
- * omap3_noncore_dpll_set_rate - set non-core DPLL rate
- * @clk: struct clk * of DPLL to set
- * @rate: rounded target rate
- *
- * Set the DPLL CLKOUT to the target rate.  If the DPLL can enter
- * low-power bypass, and the target rate is the bypass source clock
- * rate, then configure the DPLL for bypass.  Otherwise, round the
- * target rate if it hasn't been done already, then program and lock
- * the DPLL.  Returns -EINVAL upon error, or 0 upon success.
- */
-int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
-{
-	struct clk *new_parent = NULL;
-	u16 freqsel = 0;
-	struct dpll_data *dd;
-	int ret;
-
-	if (!clk || !rate)
-		return -EINVAL;
-
-	dd = clk->dpll_data;
-	if (!dd)
-		return -EINVAL;
-
-	if (rate == omap2_get_dpll_rate(clk))
-		return 0;
-
-	/*
-	 * Ensure both the bypass and ref clocks are enabled prior to
-	 * doing anything; we need the bypass clock running to reprogram
-	 * the DPLL.
-	 */
-	omap2_clk_enable(dd->clk_bypass);
-	omap2_clk_enable(dd->clk_ref);
-
-	if (dd->clk_bypass->rate == rate &&
-	    (clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
-		pr_debug("clock: %s: set rate: entering bypass.\n", clk->name);
-
-		ret = _omap3_noncore_dpll_bypass(clk);
-		if (!ret)
-			new_parent = dd->clk_bypass;
-	} else {
-		if (dd->last_rounded_rate != rate)
-			omap2_dpll_round_rate(clk, rate);
-
-		if (dd->last_rounded_rate == 0)
-			return -EINVAL;
-
-		/* No freqsel on OMAP4 */
-		if (!cpu_is_omap44xx()) {
-			freqsel = _omap3_dpll_compute_freqsel(clk,
-						dd->last_rounded_n);
-			if (!freqsel)
-				WARN_ON(1);
-		}
-
-		pr_debug("clock: %s: set rate: locking rate to %lu.\n",
-			 clk->name, rate);
-
-		ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m,
-						 dd->last_rounded_n, freqsel);
-		if (!ret)
-			new_parent = dd->clk_ref;
-	}
-	if (!ret) {
-		/*
-		 * Switch the parent clock in the heirarchy, and make sure
-		 * that the new parent's usecount is correct.  Note: we
-		 * enable the new parent before disabling the old to avoid
-		 * any unnecessary hardware disable->enable transitions.
-		 */
-		if (clk->usecount) {
-			omap2_clk_enable(new_parent);
-			omap2_clk_disable(clk->parent);
-		}
-		clk_reparent(clk, new_parent);
-		clk->rate = rate;
-	}
-	omap2_clk_disable(dd->clk_ref);
-	omap2_clk_disable(dd->clk_bypass);
-
-	return 0;
-}
-
-/* DPLL autoidle read/set code */
-
-/**
- * omap3_dpll_autoidle_read - read a DPLL's autoidle bits
- * @clk: struct clk * of the DPLL to read
- *
- * Return the DPLL's autoidle bits, shifted down to bit 0.  Returns
- * -EINVAL if passed a null pointer or if the struct clk does not
- * appear to refer to a DPLL.
- */
-u32 omap3_dpll_autoidle_read(struct clk *clk)
-{
-	const struct dpll_data *dd;
-	u32 v;
-
-	if (!clk || !clk->dpll_data)
-		return -EINVAL;
-
-	dd = clk->dpll_data;
-
-	v = __raw_readl(dd->autoidle_reg);
-	v &= dd->autoidle_mask;
-	v >>= __ffs(dd->autoidle_mask);
-
-	return v;
-}
-
-/**
- * omap3_dpll_allow_idle - enable DPLL autoidle bits
- * @clk: struct clk * of the DPLL to operate on
- *
- * Enable DPLL automatic idle control.  This automatic idle mode
- * switching takes effect only when the DPLL is locked, at least on
- * OMAP3430.  The DPLL will enter low-power stop when its downstream
- * clocks are gated.  No return value.
- */
-void omap3_dpll_allow_idle(struct clk *clk)
-{
-	const struct dpll_data *dd;
-	u32 v;
-
-	if (!clk || !clk->dpll_data)
-		return;
-
-	dd = clk->dpll_data;
-
-	/*
-	 * REVISIT: CORE DPLL can optionally enter low-power bypass
-	 * by writing 0x5 instead of 0x1.  Add some mechanism to
-	 * optionally enter this mode.
-	 */
-	v = __raw_readl(dd->autoidle_reg);
-	v &= ~dd->autoidle_mask;
-	v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask);
-	__raw_writel(v, dd->autoidle_reg);
-}
-
-/**
- * omap3_dpll_deny_idle - prevent DPLL from automatically idling
- * @clk: struct clk * of the DPLL to operate on
- *
- * Disable DPLL automatic idle control.  No return value.
- */
-void omap3_dpll_deny_idle(struct clk *clk)
-{
-	const struct dpll_data *dd;
-	u32 v;
-
-	if (!clk || !clk->dpll_data)
-		return;
-
-	dd = clk->dpll_data;
-
-	v = __raw_readl(dd->autoidle_reg);
-	v &= ~dd->autoidle_mask;
-	v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask);
-	__raw_writel(v, dd->autoidle_reg);
-
-}
-
-/* Clock control for DPLL outputs */
-
-/**
- * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate
- * @clk: DPLL output struct clk
- *
- * Using parent clock DPLL data, look up DPLL state.  If locked, set our
- * rate to the dpll_clk * 2; otherwise, just use dpll_clk.
- */
-unsigned long omap3_clkoutx2_recalc(struct clk *clk)
-{
-	const struct dpll_data *dd;
-	unsigned long rate;
-	u32 v;
-	struct clk *pclk;
-
-	/* Walk up the parents of clk, looking for a DPLL */
-	pclk = clk->parent;
-	while (pclk && !pclk->dpll_data)
-		pclk = pclk->parent;
-
-	/* clk does not have a DPLL as a parent? */
-	WARN_ON(!pclk);
-
-	dd = pclk->dpll_data;
-
-	WARN_ON(!dd->enable_mask);
-
-	v = __raw_readl(dd->control_reg) & dd->enable_mask;
-	v >>= __ffs(dd->enable_mask);
-	if (v != OMAP3XXX_EN_DPLL_LOCKED)
-		rate = clk->parent->rate;
-	else
-		rate = clk->parent->rate * 2;
-	return rate;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/emu.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/emu.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/emu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/emu.c	2010-05-16 17:17:36.000000000 -0400
@@ -56,6 +56,9 @@ static struct amba_device omap3_etm_devi
 
 static int __init emu_init(void)
 {
+	if (!cpu_is_omap34xx())
+		return -ENODEV;
+
 	amba_device_register(&omap3_etb_device, &iomem_resource);
 	amba_device_register(&omap3_etm_device, &iomem_resource);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/gpmc.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/gpmc.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/gpmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/gpmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -552,9 +552,10 @@ void __init gpmc_init(void)
 #ifdef CONFIG_ARCH_OMAP3
 static struct omap3_gpmc_regs gpmc_context;
 
-void omap3_gpmc_save_context()
+void omap3_gpmc_save_context(void)
 {
 	int i;
+
 	gpmc_context.sysconfig = gpmc_read_reg(GPMC_SYSCONFIG);
 	gpmc_context.irqenable = gpmc_read_reg(GPMC_IRQENABLE);
 	gpmc_context.timeout_ctrl = gpmc_read_reg(GPMC_TIMEOUT_CONTROL);
@@ -583,9 +584,10 @@ void omap3_gpmc_save_context()
 	}
 }
 
-void omap3_gpmc_restore_context()
+void omap3_gpmc_restore_context(void)
 {
 	int i;
+
 	gpmc_write_reg(GPMC_SYSCONFIG, gpmc_context.sysconfig);
 	gpmc_write_reg(GPMC_IRQENABLE, gpmc_context.irqenable);
 	gpmc_write_reg(GPMC_TIMEOUT_CONTROL, gpmc_context.timeout_ctrl);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/gpmc-nand.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/gpmc-nand.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/gpmc-nand.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/gpmc-nand.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,142 @@
+/*
+ * gpmc-nand.c
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Vimal Singh <vimalsingh@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/flash.h>
+
+#include <plat/nand.h>
+#include <plat/board.h>
+#include <plat/gpmc.h>
+
+#define WR_RD_PIN_MONITORING	0x00600000
+
+static struct omap_nand_platform_data *gpmc_nand_data;
+
+static struct resource gpmc_nand_resource = {
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device gpmc_nand_device = {
+	.name		= "omap2-nand",
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= &gpmc_nand_resource,
+};
+
+static int omap2_nand_gpmc_retime(void)
+{
+	struct gpmc_timings t;
+	int err;
+
+	if (!gpmc_nand_data->gpmc_t)
+		return 0;
+
+	memset(&t, 0, sizeof(t));
+	t.sync_clk = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->sync_clk);
+	t.cs_on = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->cs_on);
+	t.adv_on = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->adv_on);
+
+	/* Read */
+	t.adv_rd_off = gpmc_round_ns_to_ticks(
+				gpmc_nand_data->gpmc_t->adv_rd_off);
+	t.oe_on  = t.adv_on;
+	t.access = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->access);
+	t.oe_off = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->oe_off);
+	t.cs_rd_off = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->cs_rd_off);
+	t.rd_cycle  = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->rd_cycle);
+
+	/* Write */
+	t.adv_wr_off = gpmc_round_ns_to_ticks(
+				gpmc_nand_data->gpmc_t->adv_wr_off);
+	t.we_on  = t.oe_on;
+	if (cpu_is_omap34xx()) {
+	    t.wr_data_mux_bus =	gpmc_round_ns_to_ticks(
+				gpmc_nand_data->gpmc_t->wr_data_mux_bus);
+	    t.wr_access = gpmc_round_ns_to_ticks(
+				gpmc_nand_data->gpmc_t->wr_access);
+	}
+	t.we_off = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->we_off);
+	t.cs_wr_off = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->cs_wr_off);
+	t.wr_cycle  = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->wr_cycle);
+
+	/* Configure GPMC */
+	gpmc_cs_write_reg(gpmc_nand_data->cs, GPMC_CS_CONFIG1,
+			GPMC_CONFIG1_DEVICESIZE(gpmc_nand_data->devsize) |
+			GPMC_CONFIG1_DEVICETYPE_NAND);
+
+	err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int gpmc_nand_setup(void)
+{
+	struct device *dev = &gpmc_nand_device.dev;
+
+	/* Set timings in GPMC */
+	if (omap2_nand_gpmc_retime() < 0) {
+		dev_err(dev, "Unable to set gpmc timings\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int __init gpmc_nand_init(struct omap_nand_platform_data *_nand_data)
+{
+	unsigned int val;
+	int err	= 0;
+	struct device *dev = &gpmc_nand_device.dev;
+
+	gpmc_nand_data = _nand_data;
+	gpmc_nand_data->nand_setup = gpmc_nand_setup;
+	gpmc_nand_device.dev.platform_data = gpmc_nand_data;
+
+	err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE,
+				&gpmc_nand_data->phys_base);
+	if (err < 0) {
+		dev_err(dev, "Cannot request GPMC CS\n");
+		return err;
+	}
+
+	err = gpmc_nand_setup();
+	if (err < 0) {
+		dev_err(dev, "NAND platform setup failed: %d\n", err);
+		return err;
+	}
+
+	/* Enable RD PIN Monitoring Reg */
+	if (gpmc_nand_data->dev_ready) {
+		val  = gpmc_cs_read_reg(gpmc_nand_data->cs,
+						 GPMC_CS_CONFIG1);
+		val |= WR_RD_PIN_MONITORING;
+		gpmc_cs_write_reg(gpmc_nand_data->cs,
+						GPMC_CS_CONFIG1, val);
+	}
+
+	err = platform_device_register(&gpmc_nand_device);
+	if (err < 0) {
+		dev_err(dev, "Unable to register NAND device\n");
+		goto out_free_cs;
+	}
+
+	return 0;
+
+out_free_cs:
+	gpmc_cs_free(gpmc_nand_data->cs);
+
+	return err;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/hsmmc.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/hsmmc.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/hsmmc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/hsmmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,266 @@
+/*
+ * linux/arch/arm/mach-omap2/hsmmc.c
+ *
+ * Copyright (C) 2007-2008 Texas Instruments
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <mach/hardware.h>
+#include <plat/control.h>
+#include <plat/mmc.h>
+#include <plat/omap-pm.h>
+
+#include "hsmmc.h"
+
+#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+
+static u16 control_pbias_offset;
+static u16 control_devconf1_offset;
+
+#define HSMMC_NAME_LEN	9
+
+static struct hsmmc_controller {
+	char				name[HSMMC_NAME_LEN + 1];
+} hsmmc[OMAP34XX_NR_MMC];
+
+#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
+
+static int hsmmc_get_context_loss(struct device *dev)
+{
+	return omap_pm_get_dev_context_loss_count(dev);
+}
+
+#else
+#define hsmmc_get_context_loss NULL
+#endif
+
+static void hsmmc1_before_set_reg(struct device *dev, int slot,
+				  int power_on, int vdd)
+{
+	u32 reg, prog_io;
+	struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+	if (mmc->slots[0].remux)
+		mmc->slots[0].remux(dev, slot, power_on);
+
+	/*
+	 * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
+	 * card with Vcc regulator (from twl4030 or whatever).  OMAP has both
+	 * 1.8V and 3.0V modes, controlled by the PBIAS register.
+	 *
+	 * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
+	 * is most naturally TWL VSIM; those pins also use PBIAS.
+	 *
+	 * FIXME handle VMMC1A as needed ...
+	 */
+	if (power_on) {
+		if (cpu_is_omap2430()) {
+			reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1);
+			if ((1 << vdd) >= MMC_VDD_30_31)
+				reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE;
+			else
+				reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE;
+			omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1);
+		}
+
+		if (mmc->slots[0].internal_clock) {
+			reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+			reg |= OMAP2_MMCSDIO1ADPCLKISEL;
+			omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0);
+		}
+
+		reg = omap_ctrl_readl(control_pbias_offset);
+		if (cpu_is_omap3630()) {
+			/* Set MMC I/O to 52Mhz */
+			prog_io = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1);
+			prog_io |= OMAP3630_PRG_SDMMC1_SPEEDCTRL;
+			omap_ctrl_writel(prog_io, OMAP343X_CONTROL_PROG_IO1);
+		} else {
+			reg |= OMAP2_PBIASSPEEDCTRL0;
+		}
+		reg &= ~OMAP2_PBIASLITEPWRDNZ0;
+		omap_ctrl_writel(reg, control_pbias_offset);
+	} else {
+		reg = omap_ctrl_readl(control_pbias_offset);
+		reg &= ~OMAP2_PBIASLITEPWRDNZ0;
+		omap_ctrl_writel(reg, control_pbias_offset);
+	}
+}
+
+static void hsmmc1_after_set_reg(struct device *dev, int slot,
+				 int power_on, int vdd)
+{
+	u32 reg;
+
+	/* 100ms delay required for PBIAS configuration */
+	msleep(100);
+
+	if (power_on) {
+		reg = omap_ctrl_readl(control_pbias_offset);
+		reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0);
+		if ((1 << vdd) <= MMC_VDD_165_195)
+			reg &= ~OMAP2_PBIASLITEVMODE0;
+		else
+			reg |= OMAP2_PBIASLITEVMODE0;
+		omap_ctrl_writel(reg, control_pbias_offset);
+	} else {
+		reg = omap_ctrl_readl(control_pbias_offset);
+		reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 |
+			OMAP2_PBIASLITEVMODE0);
+		omap_ctrl_writel(reg, control_pbias_offset);
+	}
+}
+
+static void hsmmc23_before_set_reg(struct device *dev, int slot,
+				   int power_on, int vdd)
+{
+	struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+	if (mmc->slots[0].remux)
+		mmc->slots[0].remux(dev, slot, power_on);
+
+	if (power_on) {
+		/* Only MMC2 supports a CLKIN */
+		if (mmc->slots[0].internal_clock) {
+			u32 reg;
+
+			reg = omap_ctrl_readl(control_devconf1_offset);
+			reg |= OMAP2_MMCSDIO2ADPCLKISEL;
+			omap_ctrl_writel(reg, control_devconf1_offset);
+		}
+	}
+}
+
+static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
+
+void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
+{
+	struct omap2_hsmmc_info *c;
+	int nr_hsmmc = ARRAY_SIZE(hsmmc_data);
+	int i;
+
+	if (cpu_is_omap2430()) {
+		control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
+		control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1;
+	} else {
+		control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE;
+		control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1;
+	}
+
+	for (c = controllers; c->mmc; c++) {
+		struct hsmmc_controller *hc = hsmmc + c->mmc - 1;
+		struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1];
+
+		if (!c->mmc || c->mmc > nr_hsmmc) {
+			pr_debug("MMC%d: no such controller\n", c->mmc);
+			continue;
+		}
+		if (mmc) {
+			pr_debug("MMC%d: already configured\n", c->mmc);
+			continue;
+		}
+
+		mmc = kzalloc(sizeof(struct omap_mmc_platform_data),
+			      GFP_KERNEL);
+		if (!mmc) {
+			pr_err("Cannot allocate memory for mmc device!\n");
+			goto done;
+		}
+
+		if (c->name)
+			strncpy(hc->name, c->name, HSMMC_NAME_LEN);
+		else
+			snprintf(hc->name, ARRAY_SIZE(hc->name),
+				"mmc%islot%i", c->mmc, 1);
+		mmc->slots[0].name = hc->name;
+		mmc->nr_slots = 1;
+		mmc->slots[0].wires = c->wires;
+		mmc->slots[0].internal_clock = !c->ext_clock;
+		mmc->dma_mask = 0xffffffff;
+
+		mmc->get_context_loss_count = hsmmc_get_context_loss;
+
+		mmc->slots[0].switch_pin = c->gpio_cd;
+		mmc->slots[0].gpio_wp = c->gpio_wp;
+
+		mmc->slots[0].remux = c->remux;
+
+		if (c->cover_only)
+			mmc->slots[0].cover = 1;
+
+		if (c->nonremovable)
+			mmc->slots[0].nonremovable = 1;
+
+		if (c->power_saving)
+			mmc->slots[0].power_saving = 1;
+
+		if (c->no_off)
+			mmc->slots[0].no_off = 1;
+
+		if (c->vcc_aux_disable_is_sleep)
+			mmc->slots[0].vcc_aux_disable_is_sleep = 1;
+
+		/* NOTE:  MMC slots should have a Vcc regulator set up.
+		 * This may be from a TWL4030-family chip, another
+		 * controllable regulator, or a fixed supply.
+		 *
+		 * temporary HACK: ocr_mask instead of fixed supply
+		 */
+		mmc->slots[0].ocr_mask = c->ocr_mask;
+
+		switch (c->mmc) {
+		case 1:
+			/* on-chip level shifting via PBIAS0/PBIAS1 */
+			mmc->slots[0].before_set_reg = hsmmc1_before_set_reg;
+			mmc->slots[0].after_set_reg = hsmmc1_after_set_reg;
+
+			/* Omap3630 HSMMC1 supports only 4-bit */
+			if (cpu_is_omap3630() && c->wires > 4) {
+				c->wires = 4;
+				mmc->slots[0].wires = c->wires;
+			}
+			break;
+		case 2:
+			if (c->ext_clock)
+				c->transceiver = 1;
+			if (c->transceiver && c->wires > 4)
+				c->wires = 4;
+			/* FALLTHROUGH */
+		case 3:
+			/* off-chip level shifting, or none */
+			mmc->slots[0].before_set_reg = hsmmc23_before_set_reg;
+			mmc->slots[0].after_set_reg = NULL;
+			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;
+	}
+
+done:
+	for (i = 0; i < nr_hsmmc; i++)
+		kfree(hsmmc_data[i]);
+}
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/hsmmc.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/hsmmc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/hsmmc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/hsmmc.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,38 @@
+/*
+ * MMC definitions for OMAP2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+struct omap2_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 */
+	bool	nonremovable;	/* Nonremovable e.g. eMMC */
+	bool	power_saving;	/* Try to sleep or power off when possible */
+	bool	no_off;		/* power_saving and power is not to go off */
+	bool	vcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */
+	int	gpio_cd;	/* or -EINVAL */
+	int	gpio_wp;	/* or -EINVAL */
+	char	*name;		/* or NULL for default */
+	struct device *dev;	/* returned: pointer to mmc adapter */
+	int	ocr_mask;	/* temporary HACK */
+	/* Remux (pad configuation) when powering on/off */
+	void (*remux)(struct device *dev, int slot, int power_on);
+};
+
+#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+
+void omap2_hsmmc_init(struct omap2_hsmmc_info *);
+
+#else
+
+static inline void omap2_hsmmc_init(struct omap2_hsmmc_info *info)
+{
+}
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/i2c.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/i2c.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,9 +25,7 @@
 
 #include "mux.h"
 
-int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
-			  struct i2c_board_info const *info,
-			  unsigned len)
+void __init omap2_i2c_mux_pins(int bus_id)
 {
 	if (cpu_is_omap24xx()) {
 		const int omap24xx_pins[][2] = {
@@ -51,6 +49,4 @@ int __init omap_register_i2c_bus(int bus
 		sprintf(mux_name, "i2c%i_sda.i2c%i_sda", bus_id, bus_id);
 		omap_mux_init_signal(mux_name, OMAP_PIN_INPUT);
 	}
-
-	return omap_plat_register_i2c_bus(bus_id, clkrate, info, len);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/id.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/id.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/id.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/id.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,6 +57,8 @@ int omap_type(void)
 		val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
 	} else if (cpu_is_omap34xx()) {
 		val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
+	} else if (cpu_is_omap44xx()) {
+		val = omap_ctrl_readl(OMAP44XX_CONTROL_STATUS);
 	} else {
 		pr_err("Cannot detect omap type!\n");
 		goto out;
@@ -175,6 +177,8 @@ void __init omap3_check_features(void)
 	OMAP3_CHECK_FEATURE(status, SGX);
 	OMAP3_CHECK_FEATURE(status, NEON);
 	OMAP3_CHECK_FEATURE(status, ISP);
+	if (cpu_is_omap3630())
+		omap3_features |= OMAP3_HAS_192MHZ_CLK;
 
 	/*
 	 * TODO: Get additional info (where applicable)
@@ -281,6 +285,7 @@ void __init omap4_check_revision(void)
 
 	if ((hawkeye == 0xb852) && (rev == 0x0)) {
 		omap_revision = OMAP4430_REV_ES1_0;
+		omap_chip.oc |= CHIP_IS_OMAP4430ES1;
 		pr_info("OMAP%04x %s\n", omap_rev() >> 16, rev_name);
 		return;
 	}
@@ -358,6 +363,7 @@ void __init omap3_cpuinfo(void)
 	OMAP3_SHOW_FEATURE(sgx);
 	OMAP3_SHOW_FEATURE(neon);
 	OMAP3_SHOW_FEATURE(isp);
+	OMAP3_SHOW_FEATURE(192mhz_clk);
 
 	printk(")\n");
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/am35xx.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/include/mach/am35xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/am35xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/include/mach/am35xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,26 @@
+/*:
+ * Address mappings and base address for AM35XX specific interconnects
+ * and peripherals.
+ *
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * Author: Sriramakrishnan <srk@ti.com>
+ *	   Vaibhav Hiremath <hvaibhav@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_AM35XX_H
+#define __ASM_ARCH_AM35XX_H
+
+/*
+ * Base addresses
+ *	Note: OMAP3430 IVA2 memory space is being used for AM35xx IPSS modules
+ */
+#define AM35XX_IPSS_EMAC_BASE		0x5C000000
+#define AM35XX_IPSS_USBOTGSS_BASE	0x5C040000
+#define AM35XX_IPSS_HECC_BASE		0x5C050000
+#define AM35XX_IPSS_VPFE_BASE		0x5C060000
+
+#endif /*  __ASM_ARCH_AM35XX_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/board-sdp.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/include/mach/board-sdp.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/board-sdp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/include/mach/board-sdp.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ *  board-sdp.h
+ *
+ *  Information structures for SDP-specific board config data
+ *
+ *  Copyright (C) 2009 Nokia Corporation
+ *  Copyright (C) 2009 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+struct flash_partitions {
+	struct mtd_partition *parts;
+	int nr_parts;
+};
+
+extern void sdp_flash_init(struct flash_partitions []);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,32 +11,107 @@
  *
 */
 
-		.macro	addruart,rx
+#include <linux/serial_reg.h>
+
+#include <plat/serial.h>
+
+#define UART_OFFSET(addr)	((addr) & 0x00ffffff)
+
+		.pushsection .data
+omap_uart_phys:	.word	0
+omap_uart_virt:	.word	0
+omap_uart_lsr:	.word	0
+		.popsection
+
+		/*
+		 * Note that this code won't work if the bootloader passes
+		 * a wrong machine ID number in r1. To debug, just hardcode
+		 * the desired UART phys and virt addresses temporarily into
+		 * the omap_uart_phys and omap_uart_virt above.
+		 */
+		.macro	addruart, rx, tmp
+
+		/* Use omap_uart_phys/virt if already configured */
+10:		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		ldreq	\rx, =omap_uart_phys	@ physical base address
+		ldrne	\rx, =omap_uart_virt	@ virtual base address
+		ldr	\rx, [\rx, #0]
+		cmp	\rx, #0			@ is port configured?
+		bne	99f			@ already configured
+
+		/* Check UART1 scratchpad register for uart to use */
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
-#ifdef  CONFIG_ARCH_OMAP2
 		moveq	\rx, #0x48000000	@ physical base address
 		movne	\rx, #0xfa000000	@ virtual base
-		orr	\rx, \rx, #0x0006a000
-#ifdef CONFIG_OMAP_LL_DEBUG_UART2
-		add	\rx, \rx, #0x00002000	@ UART 2
-#endif
-#ifdef CONFIG_OMAP_LL_DEBUG_UART3
-		add	\rx, \rx, #0x00004000	@ UART 3
-#endif
+		orr	\rx, \rx, #0x0006a000	@ uart1 on omap2/3/4
+		ldrb	\rx, [\rx, #(UART_SCR << OMAP_PORT_SHIFT)] @ scratchpad
 
-#elif defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
-		moveq	\rx, #0x48000000	@ physical base address
-		movne	\rx, #0xfa000000	@ virtual base
-		orr	\rx, \rx, #0x0006a000
-#ifdef CONFIG_OMAP_LL_DEBUG_UART2
-		add	\rx, \rx, #0x00002000	@ UART 2
-#endif
-#ifdef CONFIG_OMAP_LL_DEBUG_UART3
-		add	\rx, \rx, #0x00fb0000	@ UART 3
-		add	\rx, \rx, #0x00006000
-#endif
-#endif
+		/* Select the UART to use based on the UART1 scratchpad value */
+		cmp	\rx, #0			@ no port configured?
+		beq	21f			@ if none, try to use UART1
+		cmp	\rx, #OMAP2UART1	@ OMAP2/3/4UART1
+		beq	21f			@ configure OMAP2/3/4UART1
+		cmp	\rx, #OMAP2UART2	@ OMAP2/3/4UART2
+		beq	22f			@ configure OMAP2/3/4UART2
+		cmp	\rx, #OMAP2UART3	@ only on 24xx
+		beq	23f			@ configure OMAP2UART3
+		cmp	\rx, #OMAP3UART3	@ only on 34xx
+		beq	33f			@ configure OMAP3UART3
+		cmp	\rx, #OMAP4UART3	@ only on 44xx
+		beq	43f			@ configure OMAP4UART3
+		cmp	\rx, #OMAP3UART4	@ only on 36xx
+		beq	34f			@ configure OMAP3UART4
+		cmp	\rx, #OMAP4UART4	@ only on 44xx
+		beq	44f			@ configure OMAP4UART4
+		cmp	\rx, #ZOOM_UART		@ only on zoom2/3
+		beq	95f			@ configure ZOOM_UART
+
+		/* Configure the UART offset from the phys/virt base */
+21:		mov	\rx, #UART_OFFSET(OMAP2_UART1_BASE)	@ omap2/3/4
+		b	98f
+22:		mov	\rx, #UART_OFFSET(OMAP2_UART2_BASE)	@ omap2/3/4
+		b	98f
+23:		mov	\rx, #UART_OFFSET(OMAP2_UART3_BASE)
+		b	98f
+33:		mov	\rx, #UART_OFFSET(OMAP3_UART1_BASE)
+		add	\rx, \rx, #0x00fb0000
+		add	\rx, \rx, #0x00006000		@ OMAP3_UART3_BASE
+		b	98f
+34:		mov	\rx, #UART_OFFSET(OMAP3_UART1_BASE)
+		add	\rx, \rx, #0x00fb0000
+		add	\rx, \rx, #0x00028000		@ OMAP3_UART4_BASE
+		b	98f
+43:		mov	\rx, #UART_OFFSET(OMAP4_UART3_BASE)
+		b	98f
+44:		mov	\rx, #UART_OFFSET(OMAP4_UART4_BASE)
+		b	98f
+95:		mov	\rx, #ZOOM_UART_BASE
+		ldr	\tmp, =omap_uart_phys
+		str	\rx, [\tmp, #0]
+		mov	\rx, #ZOOM_UART_VIRT
+		ldr	\tmp, =omap_uart_virt
+		str	\rx, [\tmp, #0]
+		mov	\rx, #(UART_LSR << ZOOM_PORT_SHIFT)
+		ldr	\tmp, =omap_uart_lsr
+		str	\rx, [\tmp, #0]
+		b	10b
+
+		/* Store both phys and virt address for the uart */
+98:		add	\rx, \rx, #0x48000000	@ phys base
+		ldr	\tmp, =omap_uart_phys
+		str	\rx, [\tmp, #0]
+		sub	\rx, \rx, #0x48000000	@ phys base
+		add	\rx, \rx, #0xfa000000	@ virt base
+		ldr	\tmp, =omap_uart_virt
+		str	\rx, [\tmp, #0]
+		mov	\rx, #(UART_LSR << OMAP_PORT_SHIFT)
+		ldr	\tmp, =omap_uart_lsr
+		str	\rx, [\tmp, #0]
+
+		b	10b
+99:
 		.endm
 
 		.macro	senduart,rd,rx
@@ -44,15 +119,12 @@
 		.endm
 
 		.macro	busyuart,rd,rx
-1001:		ldrb	\rd, [\rx, #(0x5 << 2)]	@ OMAP-1510 and friends
-		and	\rd, \rd, #0x60
-		teq	\rd, #0x60
-		beq	1002f
-		ldrb	\rd, [\rx, #(0x5 << 0)]	@ OMAP-730 only
-		and	\rd, \rd, #0x60
-		teq	\rd, #0x60
+1001:		ldr	\rd, =omap_uart_lsr
+		ldr	\rd, [\rd, #0]
+		ldrb	\rd, [\rx, \rd]
+		and	\rd, \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
+		teq	\rd, #(UART_LSR_TEMT | UART_LSR_THRE)
 		bne	1001b
-1002:
 		.endm
 
 		.macro	waituart,rd,rx
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/entry-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/include/mach/entry-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/entry-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/include/mach/entry-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -17,46 +17,134 @@
 
 #include <plat/omap24xx.h>
 #include <plat/omap34xx.h>
-
-/* REVISIT: This should be set dynamically if CONFIG_MULTI_OMAP2 is selected */
-#if defined(CONFIG_ARCH_OMAP2420) || defined(CONFIG_ARCH_OMAP2430)
-#define OMAP2_VA_IC_BASE		OMAP2_L4_IO_ADDRESS(OMAP24XX_IC_BASE)
-#elif defined(CONFIG_ARCH_OMAP34XX)
-#define OMAP2_VA_IC_BASE		OMAP2_L4_IO_ADDRESS(OMAP34XX_IC_BASE)
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
 #include <plat/omap44xx.h>
-#endif
-#define INTCPS_SIR_IRQ_OFFSET	0x0040		/* Active interrupt offset */
-#define	ACTIVEIRQ_MASK		0x7f		/* Active interrupt bits */
+
+#include <plat/multi.h>
+
+#define OMAP2_IRQ_BASE		OMAP2_L4_IO_ADDRESS(OMAP24XX_IC_BASE)
+#define OMAP3_IRQ_BASE		OMAP2_L4_IO_ADDRESS(OMAP34XX_IC_BASE)
+#define OMAP4_IRQ_BASE		OMAP2_L4_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE)
+#define INTCPS_SIR_IRQ_OFFSET	0x0040	/* omap2/3 active interrupt offset */
+#define	ACTIVEIRQ_MASK		0x7f	/* omap2/3 active interrupt bits */
 
 		.macro	disable_fiq
 		.endm
 
-		.macro  get_irqnr_preamble, base, tmp
+		.macro  arch_ret_to_user, tmp1, tmp2
 		.endm
 
-		.macro  arch_ret_to_user, tmp1, tmp2
+/*
+ * Unoptimized irq functions for multi-omap2, 3 and 4
+ */
+
+#ifdef MULTI_OMAP2
+		.pushsection .data
+omap_irq_base:	.word	0
+		.popsection
+
+		/* Configure the interrupt base on the first interrupt */
+		.macro  get_irqnr_preamble, base, tmp
+9:
+		ldr	\base, =omap_irq_base	@ irq base address
+		ldr	\base, [\base, #0]	@ irq base value
+		cmp	\base, #0		@ already configured?
+		bne	9997f			@ nothing to do
+
+		mrc	p15, 0, \tmp, c0, c0, 0	@ get processor revision
+		and	\tmp, \tmp, #0x000f0000	@ only check architecture
+		cmp	\tmp, #0x00070000	@ is v6?
+		beq	2400f			@ found v6 so it's omap24xx
+		mrc	p15, 0, \tmp, c0, c0, 0	@ get processor revision
+		and	\tmp, \tmp, #0x000000f0	@ check cortex 8 or 9
+		cmp	\tmp, #0x00000080	@ cortex A-8?
+		beq	3400f			@ found A-8 so it's omap34xx
+		cmp	\tmp, #0x00000090	@ cortex A-9?
+		beq	4400f			@ found A-9 so it's omap44xx
+2400:		ldr	\base, =OMAP2_IRQ_BASE
+		ldr	\tmp, =omap_irq_base
+		str	\base, [\tmp, #0]
+		b	9b
+3400:		ldr	\base, =OMAP3_IRQ_BASE
+		ldr	\tmp, =omap_irq_base
+		str	\base, [\tmp, #0]
+		b	9b
+4400:		ldr	\base, =OMAP4_IRQ_BASE
+		ldr	\tmp, =omap_irq_base
+		str	\base, [\tmp, #0]
+		b	9b
+9997:
 		.endm
 
-#ifndef CONFIG_ARCH_OMAP4
+		/* Check the pending interrupts. Note that base already set */
 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\base, =OMAP2_VA_IC_BASE
+		tst	\base, #0x100		@ gic address?
+		bne	4401f			@ found gic
+
+		/* Handle omap2 and omap3 */
 		ldr	\irqnr, [\base, #0x98] /* IRQ pending reg 1 */
 		cmp	\irqnr, #0x0
-		bne	2222f
+		bne	9998f
 		ldr	\irqnr, [\base, #0xb8] /* IRQ pending reg 2 */
 		cmp	\irqnr, #0x0
-		bne	2222f
+		bne	9998f
 		ldr	\irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
 		cmp	\irqnr, #0x0
-2222:
+9998:
 		ldrne	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
 		and	\irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */
+		b	9999f
 
+		/* Handle omap4 */
+4401:		ldr     \irqstat, [\base, #GIC_CPU_INTACK]
+		ldr     \tmp, =1021
+		bic     \irqnr, \irqstat, #0x1c00
+		cmp     \irqnr, #29
+		cmpcc   \irqnr, \irqnr
+		cmpne   \irqnr, \tmp
+		cmpcs   \irqnr, \irqnr
+9999:
 		.endm
+
+
+#else	/* MULTI_OMAP2 */
+
+
+/*
+ * Optimized irq functions for omap2, 3 and 4
+ */
+
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+		.macro  get_irqnr_preamble, base, tmp
+#ifdef CONFIG_ARCH_OMAP2
+		ldr	\base, =OMAP2_IRQ_BASE
 #else
-#define OMAP44XX_VA_GIC_CPU_BASE	OMAP2_L4_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE)
+		ldr	\base, =OMAP3_IRQ_BASE
+#endif
+		.endm
+
+		/* Check the pending interrupts. Note that base already set */
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\irqnr, [\base, #0x98] /* IRQ pending reg 1 */
+		cmp	\irqnr, #0x0
+		bne	9999f
+		ldr	\irqnr, [\base, #0xb8] /* IRQ pending reg 2 */
+		cmp	\irqnr, #0x0
+		bne	9999f
+		ldr	\irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
+		cmp	\irqnr, #0x0
+9999:
+		ldrne	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
+		and	\irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */
+
+		.endm
+#endif
+
+
+#ifdef CONFIG_ARCH_OMAP4
+
+		.macro  get_irqnr_preamble, base, tmp
+		ldr     \base, =OMAP4_IRQ_BASE
+		.endm
 
 		/*
 		 * The interrupt numbering scheme is defined in the
@@ -78,7 +166,6 @@
 		 * valid range for an IRQ (30-1020 inclusive).
 		 */
 		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr     \base, =OMAP44XX_VA_GIC_CPU_BASE
 		ldr     \irqstat, [\base, #GIC_CPU_INTACK]
 
 		ldr     \tmp, =1021
@@ -119,6 +206,7 @@
 		cmp	\tmp, #0
 		.endm
 #endif
+#endif	/* MULTI_OMAP2 */
 
 		.macro	irq_prio_table
 		.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/io.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/io.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/io.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,7 +35,9 @@
 #include <plat/serial.h>
 #include <plat/vram.h>
 
-#include "clock.h"
+#include "clock2xxx.h"
+#include "clock3xxx.h"
+#include "clock44xx.h"
 
 #include <plat/omap-pm.h>
 #include <plat/powerdomain.h>
@@ -44,16 +46,13 @@
 #include <plat/clockdomain.h>
 #include "clockdomains.h"
 #include <plat/omap_hwmod.h>
-#include "omap_hwmod_2420.h"
-#include "omap_hwmod_2430.h"
-#include "omap_hwmod_34xx.h"
 
 /*
  * The machine specific code may provide the extra mapping besides the
  * default mapping provided here.
  */
 
-#ifdef CONFIG_ARCH_OMAP24XX
+#ifdef CONFIG_ARCH_OMAP2
 static struct map_desc omap24xx_io_desc[] __initdata = {
 	{
 		.virtual	= L3_24XX_VIRT,
@@ -123,7 +122,7 @@ static struct map_desc omap243x_io_desc[
 #endif
 #endif
 
-#ifdef	CONFIG_ARCH_OMAP34XX
+#ifdef	CONFIG_ARCH_OMAP3
 static struct map_desc omap34xx_io_desc[] __initdata = {
 	{
 		.virtual	= L3_34XX_VIRT,
@@ -138,12 +137,6 @@ static struct map_desc omap34xx_io_desc[
 		.type		= MT_DEVICE
 	},
 	{
-		.virtual	= L4_WK_34XX_VIRT,
-		.pfn		= __phys_to_pfn(L4_WK_34XX_PHYS),
-		.length		= L4_WK_34XX_SIZE,
-		.type		= MT_DEVICE
-	},
-	{
 		.virtual	= OMAP34XX_GPMC_VIRT,
 		.pfn		= __phys_to_pfn(OMAP34XX_GPMC_PHYS),
 		.length		= OMAP34XX_GPMC_SIZE,
@@ -190,12 +183,6 @@ static struct map_desc omap44xx_io_desc[
 		.type		= MT_DEVICE,
 	},
 	{
-		.virtual	= L4_WK_44XX_VIRT,
-		.pfn		= __phys_to_pfn(L4_WK_44XX_PHYS),
-		.length		= L4_WK_44XX_SIZE,
-		.type		= MT_DEVICE,
-	},
-	{
 		.virtual	= OMAP44XX_GPMC_VIRT,
 		.pfn		= __phys_to_pfn(OMAP44XX_GPMC_PHYS),
 		.length		= OMAP44XX_GPMC_SIZE,
@@ -234,37 +221,54 @@ static struct map_desc omap44xx_io_desc[
 };
 #endif
 
-void __init omap2_map_common_io(void)
+static void __init _omap2_map_common_io(void)
+{
+	/* Normally devicemaps_init() would flush caches and tlb after
+	 * mdesc->map_io(), but we must also do it here because of the CPU
+	 * revision check below.
+	 */
+	local_flush_tlb_all();
+	flush_cache_all();
+
+	omap2_check_revision();
+	omap_sram_init();
+	omapfb_reserve_sdram();
+	omap_vram_reserve_sdram();
+}
+
+#ifdef CONFIG_ARCH_OMAP2420
+void __init omap242x_map_common_io(void)
 {
-#if defined(CONFIG_ARCH_OMAP2420)
 	iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
 	iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc));
+	_omap2_map_common_io();
+}
 #endif
 
-#if defined(CONFIG_ARCH_OMAP2430)
+#ifdef CONFIG_ARCH_OMAP2430
+void __init omap243x_map_common_io(void)
+{
 	iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
 	iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc));
+	_omap2_map_common_io();
+}
 #endif
 
-#if defined(CONFIG_ARCH_OMAP34XX)
+#ifdef CONFIG_ARCH_OMAP3
+void __init omap34xx_map_common_io(void)
+{
 	iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc));
+	_omap2_map_common_io();
+}
 #endif
 
-#if defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP4
+void __init omap44xx_map_common_io(void)
+{
 	iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc));
-#endif
-	/* Normally devicemaps_init() would flush caches and tlb after
-	 * mdesc->map_io(), but we must also do it here because of the CPU
-	 * revision check below.
-	 */
-	local_flush_tlb_all();
-	flush_cache_all();
-
-	omap2_check_revision();
-	omap_sram_init();
-	omapfb_reserve_sdram();
-	omap_vram_reserve_sdram();
+	_omap2_map_common_io();
 }
+#endif
 
 /*
  * omap2_init_reprogram_sdrc - reprogram SDRC timing parameters
@@ -303,30 +307,36 @@ static int __init _omap2_init_reprogram_
 void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
 				 struct omap_sdrc_params *sdrc_cs1)
 {
-	struct omap_hwmod **hwmods = NULL;
+	pwrdm_init(powerdomains_omap);
+	clkdm_init(clockdomains_omap, clkdm_autodeps);
+	if (cpu_is_omap242x())
+		omap2420_hwmod_init();
+	else if (cpu_is_omap243x())
+		omap2430_hwmod_init();
+	else if (cpu_is_omap34xx())
+		omap3xxx_hwmod_init();
+	omap2_mux_init();
+	/* The OPP tables have to be registered before a clk init */
+	omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps);
 
 	if (cpu_is_omap2420())
-		hwmods = omap2420_hwmods;
+		omap2420_clk_init();
 	else if (cpu_is_omap2430())
-		hwmods = omap2430_hwmods;
+		omap2430_clk_init();
 	else if (cpu_is_omap34xx())
-		hwmods = omap34xx_hwmods;
+		omap3xxx_clk_init();
+	else if (cpu_is_omap44xx())
+		omap4xxx_clk_init();
+	else
+		pr_err("Could not init clock framework - unknown CPU\n");
 
-#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */
-	/* The OPP tables have to be registered before a clk init */
-	omap_hwmod_init(hwmods);
-	omap2_mux_init();
-	omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps);
-	pwrdm_init(powerdomains_omap);
-	clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
-#endif
-	omap2_clk_init();
 	omap_serial_early_init();
-#ifndef CONFIG_ARCH_OMAP4
-	omap_hwmod_late_init();
+	if (cpu_is_omap24xx() || cpu_is_omap34xx())   /* FIXME: OMAP4 */
+		omap_hwmod_late_init();
 	omap_pm_if_init();
-	omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
-	_omap2_init_reprogram_sdrc();
-#endif
+	if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+		omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
+		_omap2_init_reprogram_sdrc();
+	}
 	gpmc_init();
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/iommu2.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/iommu2.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/iommu2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/iommu2.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/device.h>
 #include <linux/jiffies.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/stringify.h>
 
 #include <plat/iommu.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,28 +1,19 @@
 comment "OMAP Core Type"
 	depends on ARCH_OMAP2
 
-config ARCH_OMAP24XX
-	bool "OMAP24xx Based System"
-	depends on ARCH_OMAP2
-
 config ARCH_OMAP2420
 	bool "OMAP2420 support"
-	depends on ARCH_OMAP24XX
+	depends on ARCH_OMAP2
 	select OMAP_DM_TIMER
 	select ARCH_OMAP_OTG
 
 config ARCH_OMAP2430
 	bool "OMAP2430 support"
-	depends on ARCH_OMAP24XX
-
-config ARCH_OMAP34XX
-	bool "OMAP34xx Based System"
-	depends on ARCH_OMAP3
-	select USB_ARCH_HAS_EHCI
+	depends on ARCH_OMAP2
 
 config ARCH_OMAP3430
 	bool "OMAP3430 support"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	depends on ARCH_OMAP3
 	select ARCH_OMAP_OTG
 
 config OMAP_PACKAGE_CBC
@@ -38,11 +29,11 @@ config OMAP_PACKAGE_CBP
        bool
 
 comment "OMAP Board Type"
-	depends on ARCH_OMAP2 || ARCH_OMAP3 || ARCH_OMAP4
+	depends on ARCH_OMAP2PLUS
 
 config MACH_OMAP_GENERIC
 	bool "Generic OMAP board"
-	depends on ARCH_OMAP2 && ARCH_OMAP24XX
+	depends on ARCH_OMAP2
 
 config MACH_OMAP2_TUSB6010
 	bool
@@ -51,55 +42,61 @@ config MACH_OMAP2_TUSB6010
 
 config MACH_OMAP_H4
 	bool "OMAP 2420 H4 board"
-	depends on ARCH_OMAP2 && ARCH_OMAP24XX
+	depends on ARCH_OMAP2
 	select OMAP_DEBUG_DEVICES
 
 config MACH_OMAP_APOLLON
 	bool "OMAP 2420 Apollon board"
-	depends on ARCH_OMAP2 && ARCH_OMAP24XX
+	depends on ARCH_OMAP2
 
 config MACH_OMAP_2430SDP
 	bool "OMAP 2430 SDP board"
-	depends on ARCH_OMAP2 && ARCH_OMAP24XX
+	depends on ARCH_OMAP2
 
 config MACH_OMAP3_BEAGLE
 	bool "OMAP3 BEAGLE board"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	depends on ARCH_OMAP3
 	select OMAP_PACKAGE_CBB
 
+config MACH_DEVKIT8000
+	bool "DEVKIT8000 board"
+	depends on ARCH_OMAP3
+	select OMAP_PACKAGE_CUS
+	select OMAP_MUX
+
 config MACH_OMAP_LDP
 	bool "OMAP3 LDP board"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	depends on ARCH_OMAP3
 	select OMAP_PACKAGE_CBB
 
 config MACH_OVERO
 	bool "Gumstix Overo board"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	depends on ARCH_OMAP3
 	select OMAP_PACKAGE_CBB
 
 config MACH_OMAP3EVM
 	bool "OMAP 3530 EVM board"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	depends on ARCH_OMAP3
 	select OMAP_PACKAGE_CBB
 
 config MACH_OMAP3517EVM
 	bool "OMAP3517/ AM3517 EVM board"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	depends on ARCH_OMAP3
 	select OMAP_PACKAGE_CBB
 
 config MACH_OMAP3_PANDORA
 	bool "OMAP3 Pandora"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	depends on ARCH_OMAP3
 	select OMAP_PACKAGE_CBB
 
 config MACH_OMAP3_TOUCHBOOK
 	bool "OMAP3 Touch Book"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	depends on ARCH_OMAP3
 	select BACKLIGHT_CLASS_DEVICE
 
 config MACH_OMAP_3430SDP
 	bool "OMAP 3430 SDP board"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	depends on ARCH_OMAP3
 	select OMAP_PACKAGE_CBB
 
 config MACH_NOKIA_N800
@@ -120,33 +117,33 @@ config MACH_NOKIA_N8X0
 
 config MACH_NOKIA_RX51
 	bool "Nokia RX-51 board"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	depends on ARCH_OMAP3
 	select OMAP_PACKAGE_CBB
 
 config MACH_OMAP_ZOOM2
 	bool "OMAP3 Zoom2 board"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	depends on ARCH_OMAP3
 	select OMAP_PACKAGE_CBB
 
 config MACH_OMAP_ZOOM3
 	bool "OMAP3630 Zoom3 board"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	depends on ARCH_OMAP3
 	select OMAP_PACKAGE_CBP
 
 config MACH_CM_T35
 	bool "CompuLab CM-T35 module"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	depends on ARCH_OMAP3
 	select OMAP_PACKAGE_CUS
 	select OMAP_MUX
 
 config MACH_IGEP0020
-	bool "IGEP0020"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	bool "IGEP v2 board"
+	depends on ARCH_OMAP3
 	select OMAP_PACKAGE_CBB
 
 config MACH_OMAP_3630SDP
 	bool "OMAP3630 SDP board"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	depends on ARCH_OMAP3
 	select OMAP_PACKAGE_CBP
 
 config MACH_OMAP_4430SDP
@@ -162,7 +159,7 @@ config OMAP3_EMU
 
 config OMAP3_SDRC_AC_TIMING
 	bool "Enable SDRC AC timing register changes"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	depends on ARCH_OMAP3
 	default n
 	help
 	  If you know that none of your system initiators will attempt to
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mailbox.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/mailbox.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mailbox.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/mailbox.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,9 @@
 #define AUTOIDLE	(1 << 0)
 #define SOFTRESET	(1 << 1)
 #define SMARTIDLE	(2 << 3)
+#define OMAP4_SOFTRESET	(1 << 0)
+#define OMAP4_NOIDLE	(1 << 2)
+#define OMAP4_SMARTIDLE	(2 << 2)
 
 /* SYSSTATUS: register bit definition */
 #define RESETDONE	(1 << 0)
@@ -93,29 +96,47 @@ static int omap2_mbox_startup(struct oma
 
 	mbox_ick_handle = clk_get(NULL, "mailboxes_ick");
 	if (IS_ERR(mbox_ick_handle)) {
-		printk(KERN_ERR "Could not get mailboxes_ick: %d\n",
+		printk(KERN_ERR "Could not get mailboxes_ick: %ld\n",
 			PTR_ERR(mbox_ick_handle));
 		return PTR_ERR(mbox_ick_handle);
 	}
 	clk_enable(mbox_ick_handle);
 
-	mbox_write_reg(SOFTRESET, MAILBOX_SYSCONFIG);
-	timeout = jiffies + msecs_to_jiffies(20);
-	do {
-		l = mbox_read_reg(MAILBOX_SYSSTATUS);
-		if (l & RESETDONE)
-			break;
-	} while (!time_after(jiffies, timeout));
+	if (cpu_is_omap44xx()) {
+		mbox_write_reg(OMAP4_SOFTRESET, MAILBOX_SYSCONFIG);
+		timeout = jiffies + msecs_to_jiffies(20);
+		do {
+			l = mbox_read_reg(MAILBOX_SYSCONFIG);
+			if (!(l & OMAP4_SOFTRESET))
+				break;
+		} while (!time_after(jiffies, timeout));
 
-	if (!(l & RESETDONE)) {
-		pr_err("Can't take mmu out of reset\n");
-		return -ENODEV;
+		if (l & OMAP4_SOFTRESET) {
+			pr_err("Can't take mailbox out of reset\n");
+			return -ENODEV;
+		}
+	} else {
+		mbox_write_reg(SOFTRESET, MAILBOX_SYSCONFIG);
+		timeout = jiffies + msecs_to_jiffies(20);
+		do {
+			l = mbox_read_reg(MAILBOX_SYSSTATUS);
+			if (l & RESETDONE)
+				break;
+		} while (!time_after(jiffies, timeout));
+
+		if (!(l & RESETDONE)) {
+			pr_err("Can't take mailbox out of reset\n");
+			return -ENODEV;
+		}
 	}
 
 	l = mbox_read_reg(MAILBOX_REVISION);
 	pr_info("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f));
 
-	l = SMARTIDLE | AUTOIDLE;
+	if (cpu_is_omap44xx())
+		l = OMAP4_SMARTIDLE;
+	else
+		l = SMARTIDLE | AUTOIDLE;
 	mbox_write_reg(l, MAILBOX_SYSCONFIG);
 
 	omap2_mbox_enable_irq(mbox, IRQ_RX);
@@ -409,19 +430,19 @@ static int __devinit omap2_mbox_probe(st
 		if (unlikely(!res)) {
 			dev_err(&pdev->dev, "invalid irq resource\n");
 			ret = -ENODEV;
-			goto err_iva1;
+			omap_mbox_unregister(&mbox_dsp_info);
+			goto err_dsp;
 		}
 		mbox_iva_info.irq = res->start;
 		ret = omap_mbox_register(&pdev->dev, &mbox_iva_info);
-		if (ret)
-			goto err_iva1;
+		if (ret) {
+			omap_mbox_unregister(&mbox_dsp_info);
+			goto err_dsp;
+		}
 	}
 #endif
 	return 0;
 
-err_iva1:
-	omap_mbox_unregister(&mbox_dsp_info);
-
 err_dsp:
 	iounmap(mbox_base);
 	return ret;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,27 +5,36 @@
 # Common support
 obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o
 
-omap-2-3-common				= irq.o sdrc.o omap_hwmod.o
-omap-3-4-common				= dpll.o
+omap-2-3-common				= irq.o sdrc.o
+hwmod-common				= omap_hwmod.o \
+					  omap_hwmod_common_data.o
 prcm-common				= prcm.o powerdomain.o
-clock-common				= clock.o clock_common_data.o clockdomain.o
+clock-common				= clock.o clock_common_data.o \
+					  clockdomain.o clkt_dpll.o \
+					  clkt_clksel.o
 
-obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common)
-obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
-			    $(omap-3-4-common)
-obj-$(CONFIG_ARCH_OMAP4) += $(omap-3-4-common) prcm.o clock.o
+obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
+obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
+obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common)
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
 # SMP support ONLY available for OMAP4
 obj-$(CONFIG_SMP)			+= omap-smp.o omap-headsmp.o
 obj-$(CONFIG_LOCAL_TIMERS)		+= timer-mpu.o
+obj-$(CONFIG_ARCH_OMAP4)		+= omap44xx-smc.o
+
+AFLAGS_omap44xx-smc.o			:=-Wa,-march=armv7-a
 
 # Functions loaded to SRAM
 obj-$(CONFIG_ARCH_OMAP2420)		+= sram242x.o
 obj-$(CONFIG_ARCH_OMAP2430)		+= sram243x.o
 obj-$(CONFIG_ARCH_OMAP3)		+= sram34xx.o
 
+AFLAGS_sram242x.o			:=-Wa,-march=armv6
+AFLAGS_sram243x.o			:=-Wa,-march=armv6
+AFLAGS_sram34xx.o			:=-Wa,-march=armv7-a
+
 # Pin multiplexing
 obj-$(CONFIG_ARCH_OMAP3)		+= mux34xx.o
 
@@ -36,9 +45,13 @@ obj-$(CONFIG_ARCH_OMAP2)		+= sdrc2xxx.o
 # Power Management
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o
-obj-$(CONFIG_ARCH_OMAP24XX)		+= sleep24xx.o
+obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o cpuidle34xx.o
 obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
+
+AFLAGS_sleep24xx.o			:=-Wa,-march=armv6
+AFLAGS_sleep34xx.o			:=-Wa,-march=armv7-a
+
 endif
 
 # PRCM
@@ -47,14 +60,31 @@ obj-$(CONFIG_ARCH_OMAP3)		+= cm.o
 obj-$(CONFIG_ARCH_OMAP4)		+= cm4xxx.o
 
 # Clock framework
-obj-$(CONFIG_ARCH_OMAP2)		+= clock2xxx.o clock2xxx_data.o
+obj-$(CONFIG_ARCH_OMAP2)		+= $(clock-common) clock2xxx.o \
+					   clkt2xxx_sys.o \
+					   clkt2xxx_dpllcore.o \
+					   clkt2xxx_virt_prcm_set.o \
+					   clkt2xxx_apll.o clkt2xxx_osc.o
+obj-$(CONFIG_ARCH_OMAP2420)		+= clock2420_data.o
+obj-$(CONFIG_ARCH_OMAP2430)		+= clock2430.o clock2430_data.o
+obj-$(CONFIG_ARCH_OMAP3)		+= $(clock-common) clock3xxx.o \
+					   clock34xx.o clkt34xx_dpll3m2.o \
+					   clock3517.o clock36xx.o \
+					   dpll3xxx.o clock3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4)		+= $(clock-common) clock44xx_data.o \
+					   dpll3xxx.o
+
+# OMAP2 clock rate set data (old "OPP" data)
 obj-$(CONFIG_ARCH_OMAP2420)		+= opp2420_data.o
-obj-$(CONFIG_ARCH_OMAP3)		+= clock34xx.o clock34xx_data.o
 obj-$(CONFIG_ARCH_OMAP2430)		+= opp2430_data.o
-obj-$(CONFIG_ARCH_OMAP4)		+= clock44xx.o clock44xx_data.o
+
+# hwmod data
+obj-$(CONFIG_ARCH_OMAP2420)		+= omap_hwmod_2420_data.o
+obj-$(CONFIG_ARCH_OMAP2430)		+= omap_hwmod_2430_data.o
+obj-$(CONFIG_ARCH_OMAP3)		+= omap_hwmod_3xxx_data.o
 
 # EMU peripherals
-obj-$(CONFIG_OMAP3_EMU)		+= emu.o
+obj-$(CONFIG_OMAP3_EMU)			+= emu.o
 
 obj-$(CONFIG_OMAP_MBOX_FWK)		+= mailbox_mach.o
 mailbox_mach-objs			:= mailbox.o
@@ -71,45 +101,48 @@ obj-y					+= $(i2c-omap-m) $(i2c-omap-y)
 obj-$(CONFIG_MACH_OMAP_GENERIC)		+= board-generic.o
 obj-$(CONFIG_MACH_OMAP_H4)		+= board-h4.o
 obj-$(CONFIG_MACH_OMAP_2430SDP)		+= board-2430sdp.o \
-					   mmc-twl4030.o
+					   hsmmc.o
 obj-$(CONFIG_MACH_OMAP_APOLLON)		+= board-apollon.o
 obj-$(CONFIG_MACH_OMAP3_BEAGLE)		+= board-omap3beagle.o \
-					   mmc-twl4030.o
+					   hsmmc.o
+obj-$(CONFIG_MACH_DEVKIT8000)     	+= board-devkit8000.o \
+                                           hsmmc.o
 obj-$(CONFIG_MACH_OMAP_LDP)		+= board-ldp.o \
-					   mmc-twl4030.o
+					   hsmmc.o
 obj-$(CONFIG_MACH_OVERO)		+= board-overo.o \
-					   mmc-twl4030.o
+					   hsmmc.o
 obj-$(CONFIG_MACH_OMAP3EVM)		+= board-omap3evm.o \
-					   mmc-twl4030.o
+					   hsmmc.o
 obj-$(CONFIG_MACH_OMAP3_PANDORA)	+= board-omap3pandora.o \
-					   mmc-twl4030.o
+					   hsmmc.o
 obj-$(CONFIG_MACH_OMAP_3430SDP)		+= board-3430sdp.o \
-					   mmc-twl4030.o
+					   hsmmc.o \
+					   board-sdp-flash.o
 obj-$(CONFIG_MACH_NOKIA_N8X0)		+= board-n8x0.o
 obj-$(CONFIG_MACH_NOKIA_RX51)		+= board-rx51.o \
 					   board-rx51-sdram.o \
 					   board-rx51-peripherals.o \
-					   mmc-twl4030.o
+					   hsmmc.o
 obj-$(CONFIG_MACH_OMAP_ZOOM2)		+= board-zoom2.o \
 					   board-zoom-peripherals.o \
-					   mmc-twl4030.o \
+					   hsmmc.o \
 					   board-zoom-debugboard.o
 obj-$(CONFIG_MACH_OMAP_ZOOM3)		+= board-zoom3.o \
 					   board-zoom-peripherals.o \
-					   mmc-twl4030.o \
+					   hsmmc.o \
 					   board-zoom-debugboard.o
 obj-$(CONFIG_MACH_OMAP_3630SDP)		+= board-3630sdp.o \
 					   board-zoom-peripherals.o \
-					   mmc-twl4030.o
+					   hsmmc.o
 obj-$(CONFIG_MACH_CM_T35)		+= board-cm-t35.o \
-					   mmc-twl4030.o
+					   hsmmc.o
 obj-$(CONFIG_MACH_IGEP0020)		+= board-igep0020.o \
-					   mmc-twl4030.o
+					   hsmmc.o
 obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK)	+= board-omap3touchbook.o \
-					   mmc-twl4030.o
+					   hsmmc.o
 obj-$(CONFIG_MACH_OMAP_4430SDP)		+= board-4430sdp.o
 
-obj-$(CONFIG_MACH_OMAP3517EVM)     += board-am3517evm.o
+obj-$(CONFIG_MACH_OMAP3517EVM)		+= board-am3517evm.o
 
 # Platform specific device init code
 obj-y					+= usb-musb.o
@@ -119,5 +152,8 @@ obj-y					+= usb-ehci.o
 onenand-$(CONFIG_MTD_ONENAND_OMAP2)	:= gpmc-onenand.o
 obj-y					+= $(onenand-m) $(onenand-y)
 
+nand-$(CONFIG_MTD_NAND_OMAP2)		:= gpmc-nand.o
+obj-y					+= $(nand-m) $(nand-y)
+
 smc91x-$(CONFIG_SMC91X)			:= gpmc-smc91x.o
 obj-y					+= $(smc91x-m) $(smc91x-y)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mcbsp.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/mcbsp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mcbsp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/mcbsp.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <mach/irqs.h>
 #include <plat/dma.h>
@@ -65,9 +66,11 @@ static struct omap_mcbsp_platform_data o
 	},
 };
 #define OMAP2420_MCBSP_PDATA_SZ		ARRAY_SIZE(omap2420_mcbsp_pdata)
+#define OMAP2420_MCBSP_REG_NUM		(OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
 #else
 #define omap2420_mcbsp_pdata		NULL
 #define OMAP2420_MCBSP_PDATA_SZ		0
+#define OMAP2420_MCBSP_REG_NUM		0
 #endif
 
 #ifdef CONFIG_ARCH_OMAP2430
@@ -114,12 +117,14 @@ static struct omap_mcbsp_platform_data o
 	},
 };
 #define OMAP2430_MCBSP_PDATA_SZ		ARRAY_SIZE(omap2430_mcbsp_pdata)
+#define OMAP2430_MCBSP_REG_NUM		(OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
 #else
 #define omap2430_mcbsp_pdata		NULL
 #define OMAP2430_MCBSP_PDATA_SZ		0
+#define OMAP2430_MCBSP_REG_NUM		0
 #endif
 
-#ifdef CONFIG_ARCH_OMAP34XX
+#ifdef CONFIG_ARCH_OMAP3
 static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
 	{
 		.phys_base	= OMAP34XX_MCBSP1_BASE,
@@ -132,6 +137,7 @@ static struct omap_mcbsp_platform_data o
 	},
 	{
 		.phys_base	= OMAP34XX_MCBSP2_BASE,
+		.phys_base_st	= OMAP34XX_MCBSP2_ST_BASE,
 		.dma_rx_sync	= OMAP24XX_DMA_MCBSP2_RX,
 		.dma_tx_sync	= OMAP24XX_DMA_MCBSP2_TX,
 		.rx_irq		= INT_24XX_MCBSP2_IRQ_RX,
@@ -141,6 +147,7 @@ static struct omap_mcbsp_platform_data o
 	},
 	{
 		.phys_base	= OMAP34XX_MCBSP3_BASE,
+		.phys_base_st	= OMAP34XX_MCBSP3_ST_BASE,
 		.dma_rx_sync	= OMAP24XX_DMA_MCBSP3_RX,
 		.dma_tx_sync	= OMAP24XX_DMA_MCBSP3_TX,
 		.rx_irq		= INT_24XX_MCBSP3_IRQ_RX,
@@ -168,9 +175,11 @@ static struct omap_mcbsp_platform_data o
 	},
 };
 #define OMAP34XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap34xx_mcbsp_pdata)
+#define OMAP34XX_MCBSP_REG_NUM		(OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
 #else
 #define omap34xx_mcbsp_pdata		NULL
 #define OMAP34XX_MCBSP_PDATA_SZ		0
+#define OMAP34XX_MCBSP_REG_NUM		0
 #endif
 
 static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
@@ -208,17 +217,23 @@ static struct omap_mcbsp_platform_data o
 	},
 };
 #define OMAP44XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap44xx_mcbsp_pdata)
+#define OMAP44XX_MCBSP_REG_NUM		(OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
 
 static int __init omap2_mcbsp_init(void)
 {
-	if (cpu_is_omap2420())
+	if (cpu_is_omap2420()) {
 		omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ;
-	if (cpu_is_omap2430())
+		omap_mcbsp_cache_size = OMAP2420_MCBSP_REG_NUM * sizeof(u16);
+	} else if (cpu_is_omap2430()) {
 		omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ;
-	if (cpu_is_omap34xx())
+		omap_mcbsp_cache_size = OMAP2430_MCBSP_REG_NUM * sizeof(u32);
+	} else if (cpu_is_omap34xx()) {
 		omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ;
-	if (cpu_is_omap44xx())
+		omap_mcbsp_cache_size = OMAP34XX_MCBSP_REG_NUM * sizeof(u32);
+	} else if (cpu_is_omap44xx()) {
 		omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ;
+		omap_mcbsp_cache_size = OMAP44XX_MCBSP_REG_NUM * sizeof(u32);
+	}
 
 	mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
 								GFP_KERNEL);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mmc-twl4030.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/mmc-twl4030.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mmc-twl4030.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/mmc-twl4030.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,542 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/mmc-twl4030.c
- *
- * Copyright (C) 2007-2008 Texas Instruments
- * Copyright (C) 2008 Nokia Corporation
- * Author: Texas Instruments
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/mmc/host.h>
-#include <linux/regulator/consumer.h>
-
-#include <mach/hardware.h>
-#include <plat/control.h>
-#include <plat/mmc.h>
-#include <plat/board.h>
-
-#include "mmc-twl4030.h"
-
-
-#if defined(CONFIG_REGULATOR) && \
-	(defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
-
-static u16 control_pbias_offset;
-static u16 control_devconf1_offset;
-
-#define HSMMC_NAME_LEN	9
-
-static struct twl_mmc_controller {
-	struct omap_mmc_platform_data	*mmc;
-	/* Vcc == configured supply
-	 * Vcc_alt == optional
-	 *   -	MMC1, supply for DAT4..DAT7
-	 *   -	MMC2/MMC2, external level shifter voltage supply, for
-	 *	chip (SDIO, eMMC, etc) or transceiver (MMC2 only)
-	 */
-	struct regulator		*vcc;
-	struct regulator		*vcc_aux;
-	char				name[HSMMC_NAME_LEN + 1];
-} hsmmc[OMAP34XX_NR_MMC];
-
-static int twl_mmc_card_detect(int irq)
-{
-	unsigned i;
-
-	for (i = 0; i < ARRAY_SIZE(hsmmc); i++) {
-		struct omap_mmc_platform_data *mmc;
-
-		mmc = hsmmc[i].mmc;
-		if (!mmc)
-			continue;
-		if (irq != mmc->slots[0].card_detect_irq)
-			continue;
-
-		/* NOTE: assumes card detect signal is active-low */
-		return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
-	}
-	return -ENOSYS;
-}
-
-static int twl_mmc_get_ro(struct device *dev, int slot)
-{
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
-
-	/* NOTE: assumes write protect signal is active-high */
-	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.
- */
-static int twl_mmc_late_init(struct device *dev)
-{
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
-	int ret = 0;
-	int i;
-
-	/* MMC/SD/SDIO doesn't require a card detect switch */
-	if (gpio_is_valid(mmc->slots[0].switch_pin)) {
-		ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd");
-		if (ret)
-			goto done;
-		ret = gpio_direction_input(mmc->slots[0].switch_pin);
-		if (ret)
-			goto err;
-	}
-
-	/* require at least main regulator */
-	for (i = 0; i < ARRAY_SIZE(hsmmc); i++) {
-		if (hsmmc[i].name == mmc->slots[0].name) {
-			struct regulator *reg;
-
-			hsmmc[i].mmc = mmc;
-
-			reg = regulator_get(dev, "vmmc");
-			if (IS_ERR(reg)) {
-				dev_dbg(dev, "vmmc regulator missing\n");
-				/* HACK: until fixed.c regulator is usable,
-				 * we don't require a main regulator
-				 * for MMC2 or MMC3
-				 */
-				if (i != 0)
-					break;
-				ret = PTR_ERR(reg);
-				hsmmc[i].vcc = NULL;
-				goto err;
-			}
-			hsmmc[i].vcc = reg;
-			mmc->slots[0].ocr_mask = mmc_regulator_get_ocrmask(reg);
-
-			/* allow an aux regulator */
-			reg = regulator_get(dev, "vmmc_aux");
-			hsmmc[i].vcc_aux = IS_ERR(reg) ? NULL : reg;
-
-			/* UGLY HACK:  workaround regulator framework bugs.
-			 * When the bootloader leaves a supply active, it's
-			 * initialized with zero usecount ... and we can't
-			 * disable it without first enabling it.  Until the
-			 * framework is fixed, we need a workaround like this
-			 * (which is safe for MMC, but not in general).
-			 */
-			if (regulator_is_enabled(hsmmc[i].vcc) > 0) {
-				regulator_enable(hsmmc[i].vcc);
-				regulator_disable(hsmmc[i].vcc);
-			}
-			if (hsmmc[i].vcc_aux) {
-				if (regulator_is_enabled(reg) > 0) {
-					regulator_enable(reg);
-					regulator_disable(reg);
-				}
-			}
-
-			break;
-		}
-	}
-
-	return 0;
-
-err:
-	gpio_free(mmc->slots[0].switch_pin);
-done:
-	mmc->slots[0].card_detect_irq = 0;
-	mmc->slots[0].card_detect = NULL;
-
-	dev_err(dev, "err %d configuring card detect\n", ret);
-	return ret;
-}
-
-static void twl_mmc_cleanup(struct device *dev)
-{
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
-	int i;
-
-	gpio_free(mmc->slots[0].switch_pin);
-	for(i = 0; i < ARRAY_SIZE(hsmmc); i++) {
-		regulator_put(hsmmc[i].vcc);
-		regulator_put(hsmmc[i].vcc_aux);
-	}
-}
-
-#ifdef CONFIG_PM
-
-static int twl_mmc_suspend(struct device *dev, int slot)
-{
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
-
-	disable_irq(mmc->slots[0].card_detect_irq);
-	return 0;
-}
-
-static int twl_mmc_resume(struct device *dev, int slot)
-{
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
-
-	enable_irq(mmc->slots[0].card_detect_irq);
-	return 0;
-}
-
-#else
-#define twl_mmc_suspend	NULL
-#define twl_mmc_resume	NULL
-#endif
-
-#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
-
-static int twl4030_mmc_get_context_loss(struct device *dev)
-{
-	/* FIXME: PM DPS not implemented yet */
-	return 0;
-}
-
-#else
-#define twl4030_mmc_get_context_loss NULL
-#endif
-
-static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
-				int vdd)
-{
-	u32 reg, prog_io;
-	int ret = 0;
-	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 with Vcc regulator (from twl4030 or whatever).  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.
-	 *
-	 * FIXME handle VMMC1A as needed ...
-	 */
-	if (power_on) {
-		if (cpu_is_omap2430()) {
-			reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1);
-			if ((1 << vdd) >= MMC_VDD_30_31)
-				reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE;
-			else
-				reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE;
-			omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1);
-		}
-
-		if (mmc->slots[0].internal_clock) {
-			reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
-			reg |= OMAP2_MMCSDIO1ADPCLKISEL;
-			omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0);
-		}
-
-		reg = omap_ctrl_readl(control_pbias_offset);
-		if (cpu_is_omap3630()) {
-			/* Set MMC I/O to 52Mhz */
-			prog_io = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1);
-			prog_io |= OMAP3630_PRG_SDMMC1_SPEEDCTRL;
-			omap_ctrl_writel(prog_io, OMAP343X_CONTROL_PROG_IO1);
-		} else {
-			reg |= OMAP2_PBIASSPEEDCTRL0;
-		}
-		reg &= ~OMAP2_PBIASLITEPWRDNZ0;
-		omap_ctrl_writel(reg, control_pbias_offset);
-
-		ret = mmc_regulator_set_ocr(c->vcc, vdd);
-
-		/* 100ms delay required for PBIAS configuration */
-		msleep(100);
-		reg = omap_ctrl_readl(control_pbias_offset);
-		reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0);
-		if ((1 << vdd) <= MMC_VDD_165_195)
-			reg &= ~OMAP2_PBIASLITEVMODE0;
-		else
-			reg |= OMAP2_PBIASLITEVMODE0;
-		omap_ctrl_writel(reg, control_pbias_offset);
-	} else {
-		reg = omap_ctrl_readl(control_pbias_offset);
-		reg &= ~OMAP2_PBIASLITEPWRDNZ0;
-		omap_ctrl_writel(reg, control_pbias_offset);
-
-		ret = mmc_regulator_set_ocr(c->vcc, 0);
-
-		/* 100ms delay required for PBIAS configuration */
-		msleep(100);
-		reg = omap_ctrl_readl(control_pbias_offset);
-		reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 |
-			OMAP2_PBIASLITEVMODE0);
-		omap_ctrl_writel(reg, control_pbias_offset);
-	}
-
-	return ret;
-}
-
-static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int vdd)
-{
-	int ret = 0;
-	struct twl_mmc_controller *c = NULL;
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
-	int i;
-
-	for (i = 1; i < ARRAY_SIZE(hsmmc); i++) {
-		if (mmc == hsmmc[i].mmc) {
-			c = &hsmmc[i];
-			break;
-		}
-	}
-
-	if (c == NULL)
-		return -ENODEV;
-
-	/* If we don't see a Vcc regulator, assume it's a fixed
-	 * voltage always-on regulator.
-	 */
-	if (!c->vcc)
-		return 0;
-
-	/*
-	 * Assume Vcc regulator 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.
-	 *
-	 * In some cases this regulator won't support enable/disable;
-	 * e.g. it's a fixed rail for a WLAN chip.
-	 *
-	 * In other cases vcc_aux switches interface power.  Example, for
-	 * eMMC cards it represents VccQ.  Sometimes transceivers or SDIO
-	 * chips/cards need an interface voltage rail too.
-	 */
-	if (power_on) {
-		/* only MMC2 supports a CLKIN */
-		if (mmc->slots[0].internal_clock) {
-			u32 reg;
-
-			reg = omap_ctrl_readl(control_devconf1_offset);
-			reg |= OMAP2_MMCSDIO2ADPCLKISEL;
-			omap_ctrl_writel(reg, control_devconf1_offset);
-		}
-		ret = mmc_regulator_set_ocr(c->vcc, vdd);
-		/* enable interface voltage rail, if needed */
-		if (ret == 0 && c->vcc_aux) {
-			ret = regulator_enable(c->vcc_aux);
-			if (ret < 0)
-				ret = mmc_regulator_set_ocr(c->vcc, 0);
-		}
-	} else {
-		if (c->vcc_aux && (ret = regulator_is_enabled(c->vcc_aux)) > 0)
-			ret = regulator_disable(c->vcc_aux);
-		if (ret == 0)
-			ret = mmc_regulator_set_ocr(c->vcc, 0);
-	}
-
-	return ret;
-}
-
-static int twl_mmc1_set_sleep(struct device *dev, int slot, int sleep, int vdd,
-			      int cardsleep)
-{
-	struct twl_mmc_controller *c = &hsmmc[0];
-	int mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL;
-
-	return regulator_set_mode(c->vcc, mode);
-}
-
-static int twl_mmc23_set_sleep(struct device *dev, int slot, int sleep, int vdd,
-			       int cardsleep)
-{
-	struct twl_mmc_controller *c = NULL;
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
-	int i, err, mode;
-
-	for (i = 1; i < ARRAY_SIZE(hsmmc); i++) {
-		if (mmc == hsmmc[i].mmc) {
-			c = &hsmmc[i];
-			break;
-		}
-	}
-
-	if (c == NULL)
-		return -ENODEV;
-
-	/*
-	 * If we don't see a Vcc regulator, assume it's a fixed
-	 * voltage always-on regulator.
-	 */
-	if (!c->vcc)
-		return 0;
-
-	mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL;
-
-	if (!c->vcc_aux)
-		return regulator_set_mode(c->vcc, mode);
-
-	if (cardsleep) {
-		/* VCC can be turned off if card is asleep */
-		struct regulator *vcc_aux = c->vcc_aux;
-
-		c->vcc_aux = NULL;
-		if (sleep)
-			err = twl_mmc23_set_power(dev, slot, 0, 0);
-		else
-			err = twl_mmc23_set_power(dev, slot, 1, vdd);
-		c->vcc_aux = vcc_aux;
-	} else
-		err = regulator_set_mode(c->vcc, mode);
-	if (err)
-		return err;
-	return regulator_set_mode(c->vcc_aux, mode);
-}
-
-static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
-
-void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
-{
-	struct twl4030_hsmmc_info *c;
-	int nr_hsmmc = ARRAY_SIZE(hsmmc_data);
-	int i;
-
-	if (cpu_is_omap2430()) {
-		control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
-		control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1;
-		nr_hsmmc = 2;
-	} else {
-		control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE;
-		control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1;
-	}
-
-	for (c = controllers; c->mmc; c++) {
-		struct twl_mmc_controller *twl = hsmmc + c->mmc - 1;
-		struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1];
-
-		if (!c->mmc || c->mmc > nr_hsmmc) {
-			pr_debug("MMC%d: no such controller\n", c->mmc);
-			continue;
-		}
-		if (mmc) {
-			pr_debug("MMC%d: already configured\n", c->mmc);
-			continue;
-		}
-
-		mmc = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
-		if (!mmc) {
-			pr_err("Cannot allocate memory for mmc device!\n");
-			goto done;
-		}
-
-		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].wires = c->wires;
-		mmc->slots[0].internal_clock = !c->ext_clock;
-		mmc->dma_mask = 0xffffffff;
-		mmc->init = twl_mmc_late_init;
-
-		/* note: twl4030 card detect GPIOs can disable VMMCx ... */
-		if (gpio_is_valid(c->gpio_cd)) {
-			mmc->cleanup = twl_mmc_cleanup;
-			mmc->suspend = twl_mmc_suspend;
-			mmc->resume = twl_mmc_resume;
-
-			mmc->slots[0].switch_pin = c->gpio_cd;
-			mmc->slots[0].card_detect_irq = gpio_to_irq(c->gpio_cd);
-			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;
-
-		mmc->get_context_loss_count =
-				twl4030_mmc_get_context_loss;
-
-		/* write protect normally uses an OMAP gpio */
-		if (gpio_is_valid(c->gpio_wp)) {
-			gpio_request(c->gpio_wp, "mmc_wp");
-			gpio_direction_input(c->gpio_wp);
-
-			mmc->slots[0].gpio_wp = c->gpio_wp;
-			mmc->slots[0].get_ro = twl_mmc_get_ro;
-		} else
-			mmc->slots[0].gpio_wp = -EINVAL;
-
-		if (c->nonremovable)
-			mmc->slots[0].nonremovable = 1;
-
-		if (c->power_saving)
-			mmc->slots[0].power_saving = 1;
-
-		/* NOTE:  MMC slots should have a Vcc regulator set up.
-		 * This may be from a TWL4030-family chip, another
-		 * controllable regulator, or a fixed supply.
-		 *
-		 * temporary HACK: ocr_mask instead of fixed supply
-		 */
-		mmc->slots[0].ocr_mask = c->ocr_mask;
-
-		switch (c->mmc) {
-		case 1:
-			/* on-chip level shifting via PBIAS0/PBIAS1 */
-			mmc->slots[0].set_power = twl_mmc1_set_power;
-			mmc->slots[0].set_sleep = twl_mmc1_set_sleep;
-
-			/* Omap3630 HSMMC1 supports only 4-bit */
-			if (cpu_is_omap3630() && c->wires > 4) {
-				c->wires = 4;
-				mmc->slots[0].wires = c->wires;
-			}
-			break;
-		case 2:
-			if (c->ext_clock)
-				c->transceiver = 1;
-			if (c->transceiver && c->wires > 4)
-				c->wires = 4;
-			/* FALLTHROUGH */
-		case 3:
-			/* off-chip level shifting, or none */
-			mmc->slots[0].set_power = twl_mmc23_set_power;
-			mmc->slots[0].set_sleep = twl_mmc23_set_sleep;
-			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;
-	}
-
-done:
-	for (i = 0; i < nr_hsmmc; i++)
-		kfree(hsmmc_data[i]);
-}
-
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mmc-twl4030.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/mmc-twl4030.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mmc-twl4030.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/mmc-twl4030.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,36 +0,0 @@
-/*
- * MMC definitions for OMAP2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-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 */
-	bool	nonremovable;	/* Nonremovable e.g. eMMC */
-	bool	power_saving;	/* Try to sleep or power off when possible */
-	int	gpio_cd;	/* or -EINVAL */
-	int	gpio_wp;	/* or -EINVAL */
-	char	*name;		/* or NULL for default */
-	struct device *dev;	/* returned: pointer to mmc adapter */
-	int	ocr_mask;	/* temporary HACK */
-};
-
-#if defined(CONFIG_REGULATOR) && \
-	(defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
-	 defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
-
-void twl4030_mmc_init(struct twl4030_hsmmc_info *);
-
-#else
-
-static inline void twl4030_mmc_init(struct twl4030_hsmmc_info *info)
-{
-}
-
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mux.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/mux.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mux.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/mux.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
 #include <linux/ctype.h>
@@ -75,7 +76,7 @@ void omap_mux_write_array(struct omap_bo
 	}
 }
 
-#if defined(CONFIG_ARCH_OMAP24XX) && defined(CONFIG_OMAP_MUX)
+#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_OMAP_MUX)
 
 static struct omap_mux_cfg arch_mux_cfg;
 
@@ -369,7 +370,7 @@ int __init omap2_mux_init(void)
 
 /*----------------------------------------------------------------------------*/
 
-#ifdef CONFIG_ARCH_OMAP34XX
+#ifdef CONFIG_ARCH_OMAP3
 static LIST_HEAD(muxmodes);
 static DEFINE_MUTEX(muxmode_mutex);
 
@@ -983,6 +984,38 @@ static void __init omap_mux_init_list(st
 	}
 }
 
+#ifdef CONFIG_OMAP_MUX
+
+static void omap_mux_init_package(struct omap_mux *superset,
+				  struct omap_mux *package_subset,
+				  struct omap_ball *package_balls)
+{
+	if (package_subset)
+		omap_mux_package_fixup(package_subset, superset);
+	if (package_balls)
+		omap_mux_package_init_balls(package_balls, superset);
+}
+
+static void omap_mux_init_signals(struct omap_board_mux *board_mux)
+{
+	omap_mux_set_cmdline_signals();
+	omap_mux_write_array(board_mux);
+}
+
+#else
+
+static void omap_mux_init_package(struct omap_mux *superset,
+				  struct omap_mux *package_subset,
+				  struct omap_ball *package_balls)
+{
+}
+
+static void omap_mux_init_signals(struct omap_board_mux *board_mux)
+{
+}
+
+#endif
+
 int __init omap_mux_init(u32 mux_pbase, u32 mux_size,
 				struct omap_mux *superset,
 				struct omap_mux *package_subset,
@@ -999,22 +1032,12 @@ int __init omap_mux_init(u32 mux_pbase,
 		return -ENODEV;
 	}
 
-#ifdef CONFIG_OMAP_MUX
-	if (package_subset)
-		omap_mux_package_fixup(package_subset, superset);
-	if (package_balls)
-		omap_mux_package_init_balls(package_balls, superset);
-#endif
-
+	omap_mux_init_package(superset, package_subset, package_balls);
 	omap_mux_init_list(superset);
-
-#ifdef CONFIG_OMAP_MUX
-	omap_mux_set_cmdline_signals();
-	omap_mux_write_array(board_mux);
-#endif
+	omap_mux_init_signals(board_mux);
 
 	return 0;
 }
 
-#endif	/* CONFIG_ARCH_OMAP34XX */
+#endif	/* CONFIG_ARCH_OMAP3 */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mux.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/mux.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mux.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/mux.h	2010-05-16 17:17:36.000000000 -0400
@@ -102,7 +102,7 @@ struct omap_board_mux {
 	u16	value;
 };
 
-#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_ARCH_OMAP34XX)
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_ARCH_OMAP3)
 
 /**
  * omap_mux_init_gpio - initialize a signal based on the GPIO number
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap44xx-smc.S linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap44xx-smc.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap44xx-smc.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap44xx-smc.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,32 @@
+/*
+ * OMAP44xx secure APIs file.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Written by Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ *
+ * This program is free software,you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+
+/*
+ * This is common routine to manage secure monitor API
+ * used to modify the PL310 secure registers.
+ * 'r0' contains the value to be modified and 'r12' contains
+ * the monitor API number. It uses few CPU registers
+ * internally and hence they need be backed up including
+ * link register "lr".
+ * Function signature : void omap_smc1(u32 fn, u32 arg)
+ */
+
+ENTRY(omap_smc1)
+	stmfd   sp!, {r2-r12, lr}
+	mov	r12, r0
+	mov 	r0, r1
+	dsb
+	smc	#0
+	ldmfd   sp!, {r2-r12, pc}
+END(omap_smc1)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap-headsmp.S linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap-headsmp.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap-headsmp.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap-headsmp.S	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,7 @@
 ENTRY(omap_secondary_startup)
 hold:	ldr	r12,=0x103
 	dsb
-	smc				@ read from AuxCoreBoot0
+	smc	#0			@ read from AuxCoreBoot0
 	mov	r0, r0, lsr #9
 	mrc	p15, 0, r4, c0, c0, 5
 	and	r4, r4, #0x0f
@@ -52,7 +52,7 @@ ENTRY(omap_modify_auxcoreboot0)
 	stmfd   sp!, {r1-r12, lr}
 	ldr	r12, =0x104
 	dsb
-	smc
+	smc	#0
 	ldmfd   sp!, {r1-r12, pc}
 END(omap_modify_auxcoreboot0)
 
@@ -60,6 +60,6 @@ ENTRY(omap_auxcoreboot_addr)
 	stmfd   sp!, {r2-r12, lr}
 	ldr	r12, =0x105
 	dsb
-	smc
+	smc	#0
 	ldmfd   sp!, {r2-r12, pc}
 END(omap_auxcoreboot_addr)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_2420_data.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_2420_data.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_2420_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_2420_data.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,149 @@
+/*
+ * omap_hwmod_2420_data.c - hardware modules present on the OMAP2420 chips
+ *
+ * Copyright (C) 2009-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX handle crossbar/shared link difference for L3?
+ * XXX these should be marked initdata for multi-OMAP kernels
+ */
+#include <plat/omap_hwmod.h>
+#include <mach/irqs.h>
+#include <plat/cpu.h>
+#include <plat/dma.h>
+
+#include "omap_hwmod_common_data.h"
+
+#include "prm-regbits-24xx.h"
+
+/*
+ * OMAP2420 hardware module integration data
+ *
+ * ALl of the data in this section should be autogeneratable from the
+ * TI hardware database or other technical documentation.  Data that
+ * is driver-specific or driver-kernel integration-specific belongs
+ * elsewhere.
+ */
+
+static struct omap_hwmod omap2420_mpu_hwmod;
+static struct omap_hwmod omap2420_l3_hwmod;
+static struct omap_hwmod omap2420_l4_core_hwmod;
+
+/* L3 -> L4_CORE interface */
+static struct omap_hwmod_ocp_if omap2420_l3__l4_core = {
+	.master	= &omap2420_l3_hwmod,
+	.slave	= &omap2420_l4_core_hwmod,
+	.user	= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* MPU -> L3 interface */
+static struct omap_hwmod_ocp_if omap2420_mpu__l3 = {
+	.master = &omap2420_mpu_hwmod,
+	.slave	= &omap2420_l3_hwmod,
+	.user	= OCP_USER_MPU,
+};
+
+/* Slave interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l3_slaves[] = {
+	&omap2420_mpu__l3,
+};
+
+/* Master interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l3_masters[] = {
+	&omap2420_l3__l4_core,
+};
+
+/* L3 */
+static struct omap_hwmod omap2420_l3_hwmod = {
+	.name		= "l3_hwmod",
+	.class		= &l3_hwmod_class,
+	.masters	= omap2420_l3_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2420_l3_masters),
+	.slaves		= omap2420_l3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_l3_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+static struct omap_hwmod omap2420_l4_wkup_hwmod;
+
+/* L4_CORE -> L4_WKUP interface */
+static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = {
+	.master	= &omap2420_l4_core_hwmod,
+	.slave	= &omap2420_l4_wkup_hwmod,
+	.user	= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* Slave interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = {
+	&omap2420_l3__l4_core,
+};
+
+/* Master interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = {
+	&omap2420_l4_core__l4_wkup,
+};
+
+/* L4 CORE */
+static struct omap_hwmod omap2420_l4_core_hwmod = {
+	.name		= "l4_core_hwmod",
+	.class		= &l4_hwmod_class,
+	.masters	= omap2420_l4_core_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2420_l4_core_masters),
+	.slaves		= omap2420_l4_core_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_l4_core_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* Slave interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l4_wkup_slaves[] = {
+	&omap2420_l4_core__l4_wkup,
+};
+
+/* Master interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l4_wkup_masters[] = {
+};
+
+/* L4 WKUP */
+static struct omap_hwmod omap2420_l4_wkup_hwmod = {
+	.name		= "l4_wkup_hwmod",
+	.class		= &l4_hwmod_class,
+	.masters	= omap2420_l4_wkup_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2420_l4_wkup_masters),
+	.slaves		= omap2420_l4_wkup_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_l4_wkup_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* Master interfaces on the MPU device */
+static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = {
+	&omap2420_mpu__l3,
+};
+
+/* MPU */
+static struct omap_hwmod omap2420_mpu_hwmod = {
+	.name		= "mpu_hwmod",
+	.class		= &mpu_hwmod_class,
+	.main_clk	= "mpu_ck",
+	.masters	= omap2420_mpu_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2420_mpu_masters),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+static __initdata struct omap_hwmod *omap2420_hwmods[] = {
+	&omap2420_l3_hwmod,
+	&omap2420_l4_core_hwmod,
+	&omap2420_l4_wkup_hwmod,
+	&omap2420_mpu_hwmod,
+	NULL,
+};
+
+int __init omap2420_hwmod_init(void)
+{
+	return omap_hwmod_init(omap2420_hwmods);
+}
+
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_2420.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_2420.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_2420.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_2420.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,141 +0,0 @@
-/*
- * omap_hwmod_2420.h - hardware modules present on the OMAP2420 chips
- *
- * Copyright (C) 2009 Nokia Corporation
- * Paul Walmsley
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * XXX handle crossbar/shared link difference for L3?
- *
- */
-#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2420_H
-#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2420_H
-
-#ifdef CONFIG_ARCH_OMAP2420
-
-#include <plat/omap_hwmod.h>
-#include <mach/irqs.h>
-#include <plat/cpu.h>
-#include <plat/dma.h>
-
-#include "prm-regbits-24xx.h"
-
-static struct omap_hwmod omap2420_mpu_hwmod;
-static struct omap_hwmod omap2420_l3_hwmod;
-static struct omap_hwmod omap2420_l4_core_hwmod;
-
-/* L3 -> L4_CORE interface */
-static struct omap_hwmod_ocp_if omap2420_l3__l4_core = {
-	.master	= &omap2420_l3_hwmod,
-	.slave	= &omap2420_l4_core_hwmod,
-	.user	= OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* MPU -> L3 interface */
-static struct omap_hwmod_ocp_if omap2420_mpu__l3 = {
-	.master = &omap2420_mpu_hwmod,
-	.slave	= &omap2420_l3_hwmod,
-	.user	= OCP_USER_MPU,
-};
-
-/* Slave interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap2420_l3_slaves[] = {
-	&omap2420_mpu__l3,
-};
-
-/* Master interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap2420_l3_masters[] = {
-	&omap2420_l3__l4_core,
-};
-
-/* L3 */
-static struct omap_hwmod omap2420_l3_hwmod = {
-	.name		= "l3_hwmod",
-	.masters	= omap2420_l3_masters,
-	.masters_cnt	= ARRAY_SIZE(omap2420_l3_masters),
-	.slaves		= omap2420_l3_slaves,
-	.slaves_cnt	= ARRAY_SIZE(omap2420_l3_slaves),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
-};
-
-static struct omap_hwmod omap2420_l4_wkup_hwmod;
-
-/* L4_CORE -> L4_WKUP interface */
-static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = {
-	.master	= &omap2420_l4_core_hwmod,
-	.slave	= &omap2420_l4_wkup_hwmod,
-	.user	= OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* Slave interfaces on the L4_CORE interconnect */
-static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = {
-	&omap2420_l3__l4_core,
-};
-
-/* Master interfaces on the L4_CORE interconnect */
-static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = {
-	&omap2420_l4_core__l4_wkup,
-};
-
-/* L4 CORE */
-static struct omap_hwmod omap2420_l4_core_hwmod = {
-	.name		= "l4_core_hwmod",
-	.masters	= omap2420_l4_core_masters,
-	.masters_cnt	= ARRAY_SIZE(omap2420_l4_core_masters),
-	.slaves		= omap2420_l4_core_slaves,
-	.slaves_cnt	= ARRAY_SIZE(omap2420_l4_core_slaves),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
-};
-
-/* Slave interfaces on the L4_WKUP interconnect */
-static struct omap_hwmod_ocp_if *omap2420_l4_wkup_slaves[] = {
-	&omap2420_l4_core__l4_wkup,
-};
-
-/* Master interfaces on the L4_WKUP interconnect */
-static struct omap_hwmod_ocp_if *omap2420_l4_wkup_masters[] = {
-};
-
-/* L4 WKUP */
-static struct omap_hwmod omap2420_l4_wkup_hwmod = {
-	.name		= "l4_wkup_hwmod",
-	.masters	= omap2420_l4_wkup_masters,
-	.masters_cnt	= ARRAY_SIZE(omap2420_l4_wkup_masters),
-	.slaves		= omap2420_l4_wkup_slaves,
-	.slaves_cnt	= ARRAY_SIZE(omap2420_l4_wkup_slaves),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
-};
-
-/* Master interfaces on the MPU device */
-static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = {
-	&omap2420_mpu__l3,
-};
-
-/* MPU */
-static struct omap_hwmod omap2420_mpu_hwmod = {
-	.name		= "mpu_hwmod",
-	.clkdev_dev_id	= NULL,
-	.clkdev_con_id	= "mpu_ck",
-	.masters	= omap2420_mpu_masters,
-	.masters_cnt	= ARRAY_SIZE(omap2420_mpu_masters),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
-};
-
-static __initdata struct omap_hwmod *omap2420_hwmods[] = {
-	&omap2420_l3_hwmod,
-	&omap2420_l4_core_hwmod,
-	&omap2420_l4_wkup_hwmod,
-	&omap2420_mpu_hwmod,
-	NULL,
-};
-
-#else
-# define omap2420_hwmods		0
-#endif
-
-#endif
-
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_2430_data.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_2430_data.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_2430_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_2430_data.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,151 @@
+/*
+ * omap_hwmod_2430_data.c - hardware modules present on the OMAP2430 chips
+ *
+ * Copyright (C) 2009-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX handle crossbar/shared link difference for L3?
+ * XXX these should be marked initdata for multi-OMAP kernels
+ */
+#include <plat/omap_hwmod.h>
+#include <mach/irqs.h>
+#include <plat/cpu.h>
+#include <plat/dma.h>
+
+#include "omap_hwmod_common_data.h"
+
+#include "prm-regbits-24xx.h"
+
+/*
+ * OMAP2430 hardware module integration data
+ *
+ * ALl of the data in this section should be autogeneratable from the
+ * TI hardware database or other technical documentation.  Data that
+ * is driver-specific or driver-kernel integration-specific belongs
+ * elsewhere.
+ */
+
+static struct omap_hwmod omap2430_mpu_hwmod;
+static struct omap_hwmod omap2430_l3_hwmod;
+static struct omap_hwmod omap2430_l4_core_hwmod;
+
+/* L3 -> L4_CORE interface */
+static struct omap_hwmod_ocp_if omap2430_l3__l4_core = {
+	.master	= &omap2430_l3_hwmod,
+	.slave	= &omap2430_l4_core_hwmod,
+	.user	= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* MPU -> L3 interface */
+static struct omap_hwmod_ocp_if omap2430_mpu__l3 = {
+	.master = &omap2430_mpu_hwmod,
+	.slave	= &omap2430_l3_hwmod,
+	.user	= OCP_USER_MPU,
+};
+
+/* Slave interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l3_slaves[] = {
+	&omap2430_mpu__l3,
+};
+
+/* Master interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l3_masters[] = {
+	&omap2430_l3__l4_core,
+};
+
+/* L3 */
+static struct omap_hwmod omap2430_l3_hwmod = {
+	.name		= "l3_hwmod",
+	.class		= &l3_hwmod_class,
+	.masters	= omap2430_l3_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2430_l3_masters),
+	.slaves		= omap2430_l3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_l3_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+static struct omap_hwmod omap2430_l4_wkup_hwmod;
+static struct omap_hwmod omap2430_mmc1_hwmod;
+static struct omap_hwmod omap2430_mmc2_hwmod;
+
+/* L4_CORE -> L4_WKUP interface */
+static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
+	.master	= &omap2430_l4_core_hwmod,
+	.slave	= &omap2430_l4_wkup_hwmod,
+	.user	= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* Slave interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = {
+	&omap2430_l3__l4_core,
+};
+
+/* Master interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = {
+	&omap2430_l4_core__l4_wkup,
+};
+
+/* L4 CORE */
+static struct omap_hwmod omap2430_l4_core_hwmod = {
+	.name		= "l4_core_hwmod",
+	.class		= &l4_hwmod_class,
+	.masters	= omap2430_l4_core_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2430_l4_core_masters),
+	.slaves		= omap2430_l4_core_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_l4_core_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* Slave interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l4_wkup_slaves[] = {
+	&omap2430_l4_core__l4_wkup,
+};
+
+/* Master interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = {
+};
+
+/* L4 WKUP */
+static struct omap_hwmod omap2430_l4_wkup_hwmod = {
+	.name		= "l4_wkup_hwmod",
+	.class		= &l4_hwmod_class,
+	.masters	= omap2430_l4_wkup_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2430_l4_wkup_masters),
+	.slaves		= omap2430_l4_wkup_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_l4_wkup_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* Master interfaces on the MPU device */
+static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = {
+	&omap2430_mpu__l3,
+};
+
+/* MPU */
+static struct omap_hwmod omap2430_mpu_hwmod = {
+	.name		= "mpu_hwmod",
+	.class		= &mpu_hwmod_class,
+	.main_clk	= "mpu_ck",
+	.masters	= omap2430_mpu_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2430_mpu_masters),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+static __initdata struct omap_hwmod *omap2430_hwmods[] = {
+	&omap2430_l3_hwmod,
+	&omap2430_l4_core_hwmod,
+	&omap2430_l4_wkup_hwmod,
+	&omap2430_mpu_hwmod,
+	NULL,
+};
+
+int __init omap2430_hwmod_init(void)
+{
+	return omap_hwmod_init(omap2430_hwmods);
+}
+
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_2430.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_2430.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_2430.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_2430.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,143 +0,0 @@
-/*
- * omap_hwmod_2430.h - hardware modules present on the OMAP2430 chips
- *
- * Copyright (C) 2009 Nokia Corporation
- * Paul Walmsley
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * XXX handle crossbar/shared link difference for L3?
- *
- */
-#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2430_H
-#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2430_H
-
-#ifdef CONFIG_ARCH_OMAP2430
-
-#include <plat/omap_hwmod.h>
-#include <mach/irqs.h>
-#include <plat/cpu.h>
-#include <plat/dma.h>
-
-#include "prm-regbits-24xx.h"
-
-static struct omap_hwmod omap2430_mpu_hwmod;
-static struct omap_hwmod omap2430_l3_hwmod;
-static struct omap_hwmod omap2430_l4_core_hwmod;
-
-/* L3 -> L4_CORE interface */
-static struct omap_hwmod_ocp_if omap2430_l3__l4_core = {
-	.master	= &omap2430_l3_hwmod,
-	.slave	= &omap2430_l4_core_hwmod,
-	.user	= OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* MPU -> L3 interface */
-static struct omap_hwmod_ocp_if omap2430_mpu__l3 = {
-	.master = &omap2430_mpu_hwmod,
-	.slave	= &omap2430_l3_hwmod,
-	.user	= OCP_USER_MPU,
-};
-
-/* Slave interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap2430_l3_slaves[] = {
-	&omap2430_mpu__l3,
-};
-
-/* Master interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap2430_l3_masters[] = {
-	&omap2430_l3__l4_core,
-};
-
-/* L3 */
-static struct omap_hwmod omap2430_l3_hwmod = {
-	.name		= "l3_hwmod",
-	.masters	= omap2430_l3_masters,
-	.masters_cnt	= ARRAY_SIZE(omap2430_l3_masters),
-	.slaves		= omap2430_l3_slaves,
-	.slaves_cnt	= ARRAY_SIZE(omap2430_l3_slaves),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
-};
-
-static struct omap_hwmod omap2430_l4_wkup_hwmod;
-static struct omap_hwmod omap2430_mmc1_hwmod;
-static struct omap_hwmod omap2430_mmc2_hwmod;
-
-/* L4_CORE -> L4_WKUP interface */
-static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
-	.master	= &omap2430_l4_core_hwmod,
-	.slave	= &omap2430_l4_wkup_hwmod,
-	.user	= OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* Slave interfaces on the L4_CORE interconnect */
-static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = {
-	&omap2430_l3__l4_core,
-};
-
-/* Master interfaces on the L4_CORE interconnect */
-static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = {
-	&omap2430_l4_core__l4_wkup,
-};
-
-/* L4 CORE */
-static struct omap_hwmod omap2430_l4_core_hwmod = {
-	.name		= "l4_core_hwmod",
-	.masters	= omap2430_l4_core_masters,
-	.masters_cnt	= ARRAY_SIZE(omap2430_l4_core_masters),
-	.slaves		= omap2430_l4_core_slaves,
-	.slaves_cnt	= ARRAY_SIZE(omap2430_l4_core_slaves),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
-};
-
-/* Slave interfaces on the L4_WKUP interconnect */
-static struct omap_hwmod_ocp_if *omap2430_l4_wkup_slaves[] = {
-	&omap2430_l4_core__l4_wkup,
-};
-
-/* Master interfaces on the L4_WKUP interconnect */
-static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = {
-};
-
-/* L4 WKUP */
-static struct omap_hwmod omap2430_l4_wkup_hwmod = {
-	.name		= "l4_wkup_hwmod",
-	.masters	= omap2430_l4_wkup_masters,
-	.masters_cnt	= ARRAY_SIZE(omap2430_l4_wkup_masters),
-	.slaves		= omap2430_l4_wkup_slaves,
-	.slaves_cnt	= ARRAY_SIZE(omap2430_l4_wkup_slaves),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
-};
-
-/* Master interfaces on the MPU device */
-static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = {
-	&omap2430_mpu__l3,
-};
-
-/* MPU */
-static struct omap_hwmod omap2430_mpu_hwmod = {
-	.name		= "mpu_hwmod",
-	.clkdev_dev_id	= NULL,
-	.clkdev_con_id	= "mpu_ck",
-	.masters	= omap2430_mpu_masters,
-	.masters_cnt	= ARRAY_SIZE(omap2430_mpu_masters),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
-};
-
-static __initdata struct omap_hwmod *omap2430_hwmods[] = {
-	&omap2430_l3_hwmod,
-	&omap2430_l4_core_hwmod,
-	&omap2430_l4_wkup_hwmod,
-	&omap2430_mpu_hwmod,
-	NULL,
-};
-
-#else
-# define omap2430_hwmods		0
-#endif
-
-#endif
-
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_34xx.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_34xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_34xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_34xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,168 +0,0 @@
-/*
- * omap_hwmod_34xx.h - hardware modules present on the OMAP34xx chips
- *
- * Copyright (C) 2009 Nokia Corporation
- * Paul Walmsley
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD34XX_H
-#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD34XX_H
-
-#ifdef CONFIG_ARCH_OMAP34XX
-
-#include <plat/omap_hwmod.h>
-#include <mach/irqs.h>
-#include <plat/cpu.h>
-#include <plat/dma.h>
-
-#include "prm-regbits-34xx.h"
-
-static struct omap_hwmod omap34xx_mpu_hwmod;
-static struct omap_hwmod omap34xx_l3_hwmod;
-static struct omap_hwmod omap34xx_l4_core_hwmod;
-static struct omap_hwmod omap34xx_l4_per_hwmod;
-
-/* L3 -> L4_CORE interface */
-static struct omap_hwmod_ocp_if omap34xx_l3__l4_core = {
-	.master	= &omap34xx_l3_hwmod,
-	.slave	= &omap34xx_l4_core_hwmod,
-	.user	= OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* L3 -> L4_PER interface */
-static struct omap_hwmod_ocp_if omap34xx_l3__l4_per = {
-	.master = &omap34xx_l3_hwmod,
-	.slave	= &omap34xx_l4_per_hwmod,
-	.user	= OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* MPU -> L3 interface */
-static struct omap_hwmod_ocp_if omap34xx_mpu__l3 = {
-	.master = &omap34xx_mpu_hwmod,
-	.slave	= &omap34xx_l3_hwmod,
-	.user	= OCP_USER_MPU,
-};
-
-/* Slave interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap34xx_l3_slaves[] = {
-	&omap34xx_mpu__l3,
-};
-
-/* Master interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap34xx_l3_masters[] = {
-	&omap34xx_l3__l4_core,
-	&omap34xx_l3__l4_per,
-};
-
-/* L3 */
-static struct omap_hwmod omap34xx_l3_hwmod = {
-	.name		= "l3_hwmod",
-	.masters	= omap34xx_l3_masters,
-	.masters_cnt	= ARRAY_SIZE(omap34xx_l3_masters),
-	.slaves		= omap34xx_l3_slaves,
-	.slaves_cnt	= ARRAY_SIZE(omap34xx_l3_slaves),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-};
-
-static struct omap_hwmod omap34xx_l4_wkup_hwmod;
-
-/* L4_CORE -> L4_WKUP interface */
-static struct omap_hwmod_ocp_if omap34xx_l4_core__l4_wkup = {
-	.master	= &omap34xx_l4_core_hwmod,
-	.slave	= &omap34xx_l4_wkup_hwmod,
-	.user	= OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* Slave interfaces on the L4_CORE interconnect */
-static struct omap_hwmod_ocp_if *omap34xx_l4_core_slaves[] = {
-	&omap34xx_l3__l4_core,
-};
-
-/* Master interfaces on the L4_CORE interconnect */
-static struct omap_hwmod_ocp_if *omap34xx_l4_core_masters[] = {
-	&omap34xx_l4_core__l4_wkup,
-};
-
-/* L4 CORE */
-static struct omap_hwmod omap34xx_l4_core_hwmod = {
-	.name		= "l4_core_hwmod",
-	.masters	= omap34xx_l4_core_masters,
-	.masters_cnt	= ARRAY_SIZE(omap34xx_l4_core_masters),
-	.slaves		= omap34xx_l4_core_slaves,
-	.slaves_cnt	= ARRAY_SIZE(omap34xx_l4_core_slaves),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-};
-
-/* Slave interfaces on the L4_PER interconnect */
-static struct omap_hwmod_ocp_if *omap34xx_l4_per_slaves[] = {
-	&omap34xx_l3__l4_per,
-};
-
-/* Master interfaces on the L4_PER interconnect */
-static struct omap_hwmod_ocp_if *omap34xx_l4_per_masters[] = {
-};
-
-/* L4 PER */
-static struct omap_hwmod omap34xx_l4_per_hwmod = {
-	.name		= "l4_per_hwmod",
-	.masters	= omap34xx_l4_per_masters,
-	.masters_cnt	= ARRAY_SIZE(omap34xx_l4_per_masters),
-	.slaves		= omap34xx_l4_per_slaves,
-	.slaves_cnt	= ARRAY_SIZE(omap34xx_l4_per_slaves),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-};
-
-/* Slave interfaces on the L4_WKUP interconnect */
-static struct omap_hwmod_ocp_if *omap34xx_l4_wkup_slaves[] = {
-	&omap34xx_l4_core__l4_wkup,
-};
-
-/* Master interfaces on the L4_WKUP interconnect */
-static struct omap_hwmod_ocp_if *omap34xx_l4_wkup_masters[] = {
-};
-
-/* L4 WKUP */
-static struct omap_hwmod omap34xx_l4_wkup_hwmod = {
-	.name		= "l4_wkup_hwmod",
-	.masters	= omap34xx_l4_wkup_masters,
-	.masters_cnt	= ARRAY_SIZE(omap34xx_l4_wkup_masters),
-	.slaves		= omap34xx_l4_wkup_slaves,
-	.slaves_cnt	= ARRAY_SIZE(omap34xx_l4_wkup_slaves),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-};
-
-/* Master interfaces on the MPU device */
-static struct omap_hwmod_ocp_if *omap34xx_mpu_masters[] = {
-	&omap34xx_mpu__l3,
-};
-
-/* MPU */
-static struct omap_hwmod omap34xx_mpu_hwmod = {
-	.name		= "mpu_hwmod",
-	.clkdev_dev_id	= NULL,
-	.clkdev_con_id	= "arm_fck",
-	.masters	= omap34xx_mpu_masters,
-	.masters_cnt	= ARRAY_SIZE(omap34xx_mpu_masters),
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-};
-
-static __initdata struct omap_hwmod *omap34xx_hwmods[] = {
-	&omap34xx_l3_hwmod,
-	&omap34xx_l4_core_hwmod,
-	&omap34xx_l4_per_hwmod,
-	&omap34xx_l4_wkup_hwmod,
-	&omap34xx_mpu_hwmod,
-	NULL,
-};
-
-#else
-# define omap34xx_hwmods		0
-#endif
-
-#endif
-
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,181 @@
+/*
+ * omap_hwmod_3xxx_data.c - hardware modules present on the OMAP3xxx chips
+ *
+ * Copyright (C) 2009-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The data in this file should be completely autogeneratable from
+ * the TI hardware database or other technical documentation.
+ *
+ * XXX these should be marked initdata for multi-OMAP kernels
+ */
+#include <plat/omap_hwmod.h>
+#include <mach/irqs.h>
+#include <plat/cpu.h>
+#include <plat/dma.h>
+
+#include "omap_hwmod_common_data.h"
+
+#include "prm-regbits-34xx.h"
+
+/*
+ * OMAP3xxx hardware module integration data
+ *
+ * ALl of the data in this section should be autogeneratable from the
+ * TI hardware database or other technical documentation.  Data that
+ * is driver-specific or driver-kernel integration-specific belongs
+ * elsewhere.
+ */
+
+static struct omap_hwmod omap3xxx_mpu_hwmod;
+static struct omap_hwmod omap3xxx_l3_hwmod;
+static struct omap_hwmod omap3xxx_l4_core_hwmod;
+static struct omap_hwmod omap3xxx_l4_per_hwmod;
+
+/* L3 -> L4_CORE interface */
+static struct omap_hwmod_ocp_if omap3xxx_l3__l4_core = {
+	.master	= &omap3xxx_l3_hwmod,
+	.slave	= &omap3xxx_l4_core_hwmod,
+	.user	= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L3 -> L4_PER interface */
+static struct omap_hwmod_ocp_if omap3xxx_l3__l4_per = {
+	.master = &omap3xxx_l3_hwmod,
+	.slave	= &omap3xxx_l4_per_hwmod,
+	.user	= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* MPU -> L3 interface */
+static struct omap_hwmod_ocp_if omap3xxx_mpu__l3 = {
+	.master = &omap3xxx_mpu_hwmod,
+	.slave	= &omap3xxx_l3_hwmod,
+	.user	= OCP_USER_MPU,
+};
+
+/* Slave interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap3xxx_l3_slaves[] = {
+	&omap3xxx_mpu__l3,
+};
+
+/* Master interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap3xxx_l3_masters[] = {
+	&omap3xxx_l3__l4_core,
+	&omap3xxx_l3__l4_per,
+};
+
+/* L3 */
+static struct omap_hwmod omap3xxx_l3_hwmod = {
+	.name		= "l3_hwmod",
+	.class		= &l3_hwmod_class,
+	.masters	= omap3xxx_l3_masters,
+	.masters_cnt	= ARRAY_SIZE(omap3xxx_l3_masters),
+	.slaves		= omap3xxx_l3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_l3_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+static struct omap_hwmod omap3xxx_l4_wkup_hwmod;
+
+/* L4_CORE -> L4_WKUP interface */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = {
+	.master	= &omap3xxx_l4_core_hwmod,
+	.slave	= &omap3xxx_l4_wkup_hwmod,
+	.user	= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* Slave interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = {
+	&omap3xxx_l3__l4_core,
+};
+
+/* Master interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap3xxx_l4_core_masters[] = {
+	&omap3xxx_l4_core__l4_wkup,
+};
+
+/* L4 CORE */
+static struct omap_hwmod omap3xxx_l4_core_hwmod = {
+	.name		= "l4_core_hwmod",
+	.class		= &l4_hwmod_class,
+	.masters	= omap3xxx_l4_core_masters,
+	.masters_cnt	= ARRAY_SIZE(omap3xxx_l4_core_masters),
+	.slaves		= omap3xxx_l4_core_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_l4_core_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* Slave interfaces on the L4_PER interconnect */
+static struct omap_hwmod_ocp_if *omap3xxx_l4_per_slaves[] = {
+	&omap3xxx_l3__l4_per,
+};
+
+/* Master interfaces on the L4_PER interconnect */
+static struct omap_hwmod_ocp_if *omap3xxx_l4_per_masters[] = {
+};
+
+/* L4 PER */
+static struct omap_hwmod omap3xxx_l4_per_hwmod = {
+	.name		= "l4_per_hwmod",
+	.class		= &l4_hwmod_class,
+	.masters	= omap3xxx_l4_per_masters,
+	.masters_cnt	= ARRAY_SIZE(omap3xxx_l4_per_masters),
+	.slaves		= omap3xxx_l4_per_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_l4_per_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* Slave interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap3xxx_l4_wkup_slaves[] = {
+	&omap3xxx_l4_core__l4_wkup,
+};
+
+/* Master interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap3xxx_l4_wkup_masters[] = {
+};
+
+/* L4 WKUP */
+static struct omap_hwmod omap3xxx_l4_wkup_hwmod = {
+	.name		= "l4_wkup_hwmod",
+	.class		= &l4_hwmod_class,
+	.masters	= omap3xxx_l4_wkup_masters,
+	.masters_cnt	= ARRAY_SIZE(omap3xxx_l4_wkup_masters),
+	.slaves		= omap3xxx_l4_wkup_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_l4_wkup_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* Master interfaces on the MPU device */
+static struct omap_hwmod_ocp_if *omap3xxx_mpu_masters[] = {
+	&omap3xxx_mpu__l3,
+};
+
+/* MPU */
+static struct omap_hwmod omap3xxx_mpu_hwmod = {
+	.name		= "mpu_hwmod",
+	.class		= &mpu_hwmod_class,
+	.main_clk	= "arm_fck",
+	.masters	= omap3xxx_mpu_masters,
+	.masters_cnt	= ARRAY_SIZE(omap3xxx_mpu_masters),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
+	&omap3xxx_l3_hwmod,
+	&omap3xxx_l4_core_hwmod,
+	&omap3xxx_l4_per_hwmod,
+	&omap3xxx_l4_wkup_hwmod,
+	&omap3xxx_mpu_hwmod,
+	NULL,
+};
+
+int __init omap3xxx_hwmod_init(void)
+{
+	return omap_hwmod_init(omap3xxx_hwmods);
+}
+
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod.c	2010-05-16 17:17:36.000000000 -0400
@@ -84,17 +84,16 @@ static u8 inited;
  */
 static int _update_sysc_cache(struct omap_hwmod *oh)
 {
-	if (!oh->sysconfig) {
-		WARN(!oh->sysconfig, "omap_hwmod: %s: cannot read "
-		     "OCP_SYSCONFIG: not defined on hwmod\n", oh->name);
+	if (!oh->class->sysc) {
+		WARN(1, "omap_hwmod: %s: cannot read OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name);
 		return -EINVAL;
 	}
 
 	/* XXX ensure module interface clock is up */
 
-	oh->_sysc_cache = omap_hwmod_readl(oh, oh->sysconfig->sysc_offs);
+	oh->_sysc_cache = omap_hwmod_readl(oh, oh->class->sysc->sysc_offs);
 
-	if (!(oh->sysconfig->sysc_flags & SYSC_NO_CACHE))
+	if (!(oh->class->sysc->sysc_flags & SYSC_NO_CACHE))
 		oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED;
 
 	return 0;
@@ -105,14 +104,13 @@ static int _update_sysc_cache(struct oma
  * @v: OCP_SYSCONFIG value to write
  * @oh: struct omap_hwmod *
  *
- * Write @v into the module OCP_SYSCONFIG register, if it has one.  No
- * return value.
+ * Write @v into the module class' OCP_SYSCONFIG register, if it has
+ * one.  No return value.
  */
 static void _write_sysconfig(u32 v, struct omap_hwmod *oh)
 {
-	if (!oh->sysconfig) {
-		WARN(!oh->sysconfig, "omap_hwmod: %s: cannot write "
-		     "OCP_SYSCONFIG: not defined on hwmod\n", oh->name);
+	if (!oh->class->sysc) {
+		WARN(1, "omap_hwmod: %s: cannot write OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name);
 		return;
 	}
 
@@ -120,7 +118,7 @@ static void _write_sysconfig(u32 v, stru
 
 	if (oh->_sysc_cache != v) {
 		oh->_sysc_cache = v;
-		omap_hwmod_writel(v, oh, oh->sysconfig->sysc_offs);
+		omap_hwmod_writel(v, oh, oh->class->sysc->sysc_offs);
 	}
 }
 
@@ -137,12 +135,23 @@ static void _write_sysconfig(u32 v, stru
 static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode,
 				   u32 *v)
 {
-	if (!oh->sysconfig ||
-	    !(oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE))
+	u32 mstandby_mask;
+	u8 mstandby_shift;
+
+	if (!oh->class->sysc ||
+	    !(oh->class->sysc->sysc_flags & SYSC_HAS_MIDLEMODE))
 		return -EINVAL;
 
-	*v &= ~SYSC_MIDLEMODE_MASK;
-	*v |= __ffs(standbymode) << SYSC_MIDLEMODE_SHIFT;
+	if (!oh->class->sysc->sysc_fields) {
+		WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
+		return -EINVAL;
+	}
+
+	mstandby_shift = oh->class->sysc->sysc_fields->midle_shift;
+	mstandby_mask = (0x3 << mstandby_shift);
+
+	*v &= ~mstandby_mask;
+	*v |= __ffs(standbymode) << mstandby_shift;
 
 	return 0;
 }
@@ -159,12 +168,23 @@ static int _set_master_standbymode(struc
  */
 static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v)
 {
-	if (!oh->sysconfig ||
-	    !(oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE))
+	u32 sidle_mask;
+	u8 sidle_shift;
+
+	if (!oh->class->sysc ||
+	    !(oh->class->sysc->sysc_flags & SYSC_HAS_SIDLEMODE))
 		return -EINVAL;
 
-	*v &= ~SYSC_SIDLEMODE_MASK;
-	*v |= __ffs(idlemode) << SYSC_SIDLEMODE_SHIFT;
+	if (!oh->class->sysc->sysc_fields) {
+		WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
+		return -EINVAL;
+	}
+
+	sidle_shift = oh->class->sysc->sysc_fields->sidle_shift;
+	sidle_mask = (0x3 << sidle_shift);
+
+	*v &= ~sidle_mask;
+	*v |= __ffs(idlemode) << sidle_shift;
 
 	return 0;
 }
@@ -182,12 +202,23 @@ static int _set_slave_idlemode(struct om
  */
 static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v)
 {
-	if (!oh->sysconfig ||
-	    !(oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY))
+	u32 clkact_mask;
+	u8  clkact_shift;
+
+	if (!oh->class->sysc ||
+	    !(oh->class->sysc->sysc_flags & SYSC_HAS_CLOCKACTIVITY))
 		return -EINVAL;
 
-	*v &= ~SYSC_CLOCKACTIVITY_MASK;
-	*v |= clockact << SYSC_CLOCKACTIVITY_SHIFT;
+	if (!oh->class->sysc->sysc_fields) {
+		WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
+		return -EINVAL;
+	}
+
+	clkact_shift = oh->class->sysc->sysc_fields->clkact_shift;
+	clkact_mask = (0x3 << clkact_shift);
+
+	*v &= ~clkact_mask;
+	*v |= clockact << clkact_shift;
 
 	return 0;
 }
@@ -202,11 +233,20 @@ static int _set_clockactivity(struct oma
  */
 static int _set_softreset(struct omap_hwmod *oh, u32 *v)
 {
-	if (!oh->sysconfig ||
-	    !(oh->sysconfig->sysc_flags & SYSC_HAS_SOFTRESET))
+	u32 softrst_mask;
+
+	if (!oh->class->sysc ||
+	    !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
 		return -EINVAL;
 
-	*v |= SYSC_SOFTRESET_MASK;
+	if (!oh->class->sysc->sysc_fields) {
+		WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
+		return -EINVAL;
+	}
+
+	softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
+
+	*v |= softrst_mask;
 
 	return 0;
 }
@@ -227,12 +267,23 @@ static int _set_softreset(struct omap_hw
 static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
 				u32 *v)
 {
-	if (!oh->sysconfig ||
-	    !(oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE))
+	u32 autoidle_mask;
+	u8 autoidle_shift;
+
+	if (!oh->class->sysc ||
+	    !(oh->class->sysc->sysc_flags & SYSC_HAS_AUTOIDLE))
 		return -EINVAL;
 
-	*v &= ~SYSC_AUTOIDLE_MASK;
-	*v |= autoidle << SYSC_AUTOIDLE_SHIFT;
+	if (!oh->class->sysc->sysc_fields) {
+		WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
+		return -EINVAL;
+	}
+
+	autoidle_shift = oh->class->sysc->sysc_fields->autoidle_shift;
+	autoidle_mask = (0x3 << autoidle_shift);
+
+	*v &= ~autoidle_mask;
+	*v |= autoidle << autoidle_shift;
 
 	return 0;
 }
@@ -246,14 +297,21 @@ static int _set_module_autoidle(struct o
  */
 static int _enable_wakeup(struct omap_hwmod *oh)
 {
-	u32 v;
+	u32 v, wakeup_mask;
 
-	if (!oh->sysconfig ||
-	    !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
+	if (!oh->class->sysc ||
+	    !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
 		return -EINVAL;
 
+	if (!oh->class->sysc->sysc_fields) {
+		WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
+		return -EINVAL;
+	}
+
+	wakeup_mask = (0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
+
 	v = oh->_sysc_cache;
-	v |= SYSC_ENAWAKEUP_MASK;
+	v |= wakeup_mask;
 	_write_sysconfig(v, oh);
 
 	/* XXX test pwrdm_get_wken for this hwmod's subsystem */
@@ -272,14 +330,21 @@ static int _enable_wakeup(struct omap_hw
  */
 static int _disable_wakeup(struct omap_hwmod *oh)
 {
-	u32 v;
+	u32 v, wakeup_mask;
 
-	if (!oh->sysconfig ||
-	    !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
+	if (!oh->class->sysc ||
+	    !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
+		return -EINVAL;
+
+	if (!oh->class->sysc->sysc_fields) {
+		WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
 		return -EINVAL;
+	}
+
+	wakeup_mask = (0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
 
 	v = oh->_sysc_cache;
-	v &= ~SYSC_ENAWAKEUP_MASK;
+	v &= ~wakeup_mask;
 	_write_sysconfig(v, oh);
 
 	/* XXX test pwrdm_get_wken for this hwmod's subsystem */
@@ -299,15 +364,14 @@ static int _disable_wakeup(struct omap_h
  * be accessed by the IVA, there should be a sleepdep between the IVA
  * initiator and the module).  Only applies to modules in smart-idle
  * mode.  Returns -EINVAL upon error or passes along
- * pwrdm_add_sleepdep() value upon success.
+ * clkdm_add_sleepdep() value upon success.
  */
 static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
 {
 	if (!oh->_clk)
 		return -EINVAL;
 
-	return pwrdm_add_sleepdep(oh->_clk->clkdm->pwrdm.ptr,
-				  init_oh->_clk->clkdm->pwrdm.ptr);
+	return clkdm_add_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
 }
 
 /**
@@ -320,15 +384,14 @@ static int _add_initiator_dep(struct oma
  * be accessed by the IVA, there should be no sleepdep between the IVA
  * initiator and the module).  Only applies to modules in smart-idle
  * mode.  Returns -EINVAL upon error or passes along
- * pwrdm_add_sleepdep() value upon success.
+ * clkdm_del_sleepdep() value upon success.
  */
 static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
 {
 	if (!oh->_clk)
 		return -EINVAL;
 
-	return pwrdm_del_sleepdep(oh->_clk->clkdm->pwrdm.ptr,
-				  init_oh->_clk->clkdm->pwrdm.ptr);
+	return clkdm_del_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
 }
 
 /**
@@ -344,18 +407,18 @@ static int _init_main_clk(struct omap_hw
 	struct clk *c;
 	int ret = 0;
 
-	if (!oh->clkdev_con_id)
+	if (!oh->main_clk)
 		return 0;
 
-	c = clk_get_sys(oh->clkdev_dev_id, oh->clkdev_con_id);
-	WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get main_clk %s.%s\n",
-	     oh->name, oh->clkdev_dev_id, oh->clkdev_con_id);
+	c = omap_clk_get_by_name(oh->main_clk);
+	WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get main_clk %s\n",
+	     oh->name, oh->main_clk);
 	if (IS_ERR(c))
 		ret = -EINVAL;
 	oh->_clk = c;
 
 	WARN(!c->clkdm, "omap_hwmod: %s: missing clockdomain for %s.\n",
-	     oh->clkdev_con_id, c->name);
+	     oh->main_clk, c->name);
 
 	return ret;
 }
@@ -378,13 +441,12 @@ static int _init_interface_clks(struct o
 		return 0;
 
 	for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) {
-		if (!os->clkdev_con_id)
+		if (!os->clk)
 			continue;
 
-		c = clk_get_sys(os->clkdev_dev_id, os->clkdev_con_id);
+		c = omap_clk_get_by_name(os->clk);
 		WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get "
-		     "interface_clk %s.%s\n", oh->name,
-		     os->clkdev_dev_id, os->clkdev_con_id);
+		     "interface_clk %s\n", oh->name, os->clk);
 		if (IS_ERR(c))
 			ret = -EINVAL;
 		os->_clk = c;
@@ -408,10 +470,9 @@ static int _init_opt_clks(struct omap_hw
 	int ret = 0;
 
 	for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) {
-		c = clk_get_sys(oc->clkdev_dev_id, oc->clkdev_con_id);
+		c = omap_clk_get_by_name(oc->clk);
 		WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get opt_clk "
-		     "%s.%s\n", oh->name, oc->clkdev_dev_id,
-		     oc->clkdev_con_id);
+		     "%s\n", oh->name, oc->clk);
 		if (IS_ERR(c))
 			ret = -EINVAL;
 		oc->_clk = c;
@@ -568,27 +629,28 @@ static void __iomem *_find_mpu_rt_base(s
  */
 static void _sysc_enable(struct omap_hwmod *oh)
 {
-	u8 idlemode;
+	u8 idlemode, sf;
 	u32 v;
 
-	if (!oh->sysconfig)
+	if (!oh->class->sysc)
 		return;
 
 	v = oh->_sysc_cache;
+	sf = oh->class->sysc->sysc_flags;
 
-	if (oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE) {
+	if (sf & SYSC_HAS_SIDLEMODE) {
 		idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
 			HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
 		_set_slave_idlemode(oh, idlemode, &v);
 	}
 
-	if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE) {
+	if (sf & SYSC_HAS_MIDLEMODE) {
 		idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ?
 			HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
 		_set_master_standbymode(oh, idlemode, &v);
 	}
 
-	if (oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE) {
+	if (sf & SYSC_HAS_AUTOIDLE) {
 		idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ?
 			0 : 1;
 		_set_module_autoidle(oh, idlemode, &v);
@@ -601,9 +663,9 @@ static void _sysc_enable(struct omap_hwm
 	 * calling into this code.  But this must wait until the
 	 * clock structures are tagged with omap_hwmod entries
 	 */
-	if (oh->flags & HWMOD_SET_DEFAULT_CLOCKACT &&
-	    oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY)
-		_set_clockactivity(oh, oh->sysconfig->clockact, &v);
+	if ((oh->flags & HWMOD_SET_DEFAULT_CLOCKACT) &&
+	    (sf & SYSC_HAS_CLOCKACTIVITY))
+		_set_clockactivity(oh, oh->class->sysc->clockact, &v);
 
 	_write_sysconfig(v, oh);
 }
@@ -619,21 +681,22 @@ static void _sysc_enable(struct omap_hwm
  */
 static void _sysc_idle(struct omap_hwmod *oh)
 {
-	u8 idlemode;
+	u8 idlemode, sf;
 	u32 v;
 
-	if (!oh->sysconfig)
+	if (!oh->class->sysc)
 		return;
 
 	v = oh->_sysc_cache;
+	sf = oh->class->sysc->sysc_flags;
 
-	if (oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE) {
+	if (sf & SYSC_HAS_SIDLEMODE) {
 		idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
 			HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART;
 		_set_slave_idlemode(oh, idlemode, &v);
 	}
 
-	if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE) {
+	if (sf & SYSC_HAS_MIDLEMODE) {
 		idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ?
 			HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART;
 		_set_master_standbymode(oh, idlemode, &v);
@@ -652,19 +715,21 @@ static void _sysc_idle(struct omap_hwmod
 static void _sysc_shutdown(struct omap_hwmod *oh)
 {
 	u32 v;
+	u8 sf;
 
-	if (!oh->sysconfig)
+	if (!oh->class->sysc)
 		return;
 
 	v = oh->_sysc_cache;
+	sf = oh->class->sysc->sysc_flags;
 
-	if (oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE)
+	if (sf & SYSC_HAS_SIDLEMODE)
 		_set_slave_idlemode(oh, HWMOD_IDLEMODE_FORCE, &v);
 
-	if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE)
+	if (sf & SYSC_HAS_MIDLEMODE)
 		_set_master_standbymode(oh, HWMOD_IDLEMODE_FORCE, &v);
 
-	if (oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE)
+	if (sf & SYSC_HAS_AUTOIDLE)
 		_set_module_autoidle(oh, 1, &v);
 
 	_write_sysconfig(v, oh);
@@ -781,9 +846,9 @@ static int _reset(struct omap_hwmod *oh)
 	u32 r, v;
 	int c = 0;
 
-	if (!oh->sysconfig ||
-	    !(oh->sysconfig->sysc_flags & SYSC_HAS_SOFTRESET) ||
-	    (oh->sysconfig->sysc_flags & SYSS_MISSING))
+	if (!oh->class->sysc ||
+	    !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET) ||
+	    (oh->class->sysc->sysc_flags & SYSS_MISSING))
 		return -EINVAL;
 
 	/* clocks must be on for this operation */
@@ -801,7 +866,7 @@ static int _reset(struct omap_hwmod *oh)
 		return r;
 	_write_sysconfig(v, oh);
 
-	omap_test_timeout((omap_hwmod_readl(oh, oh->sysconfig->syss_offs) &
+	omap_test_timeout((omap_hwmod_readl(oh, oh->class->sysc->syss_offs) &
 			   SYSS_RESETDONE_MASK),
 			  MAX_MODULE_RESET_WAIT, c);
 
@@ -847,7 +912,7 @@ static int _enable(struct omap_hwmod *oh
 	_add_initiator_dep(oh, mpu_oh);
 	_enable_clocks(oh);
 
-	if (oh->sysconfig) {
+	if (oh->class->sysc) {
 		if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED))
 			_update_sysc_cache(oh);
 		_sysc_enable(oh);
@@ -878,7 +943,7 @@ static int _idle(struct omap_hwmod *oh)
 
 	pr_debug("omap_hwmod: %s: idling\n", oh->name);
 
-	if (oh->sysconfig)
+	if (oh->class->sysc)
 		_sysc_idle(oh);
 	_del_initiator_dep(oh, mpu_oh);
 	_disable_clocks(oh);
@@ -908,7 +973,7 @@ static int _shutdown(struct omap_hwmod *
 
 	pr_debug("omap_hwmod: %s: disabling\n", oh->name);
 
-	if (oh->sysconfig)
+	if (oh->class->sysc)
 		_sysc_shutdown(oh);
 	_del_initiator_dep(oh, mpu_oh);
 	/* XXX what about the other system initiators here? DMA, tesla, d2d */
@@ -968,7 +1033,7 @@ static int _setup(struct omap_hwmod *oh)
 		 * _enable() function should be split to avoid the
 		 * rewrite of the OCP_SYSCONFIG register.
 		 */
-		if (oh->sysconfig) {
+		if (oh->class->sysc) {
 			_update_sysc_cache(oh);
 			_sysc_enable(oh);
 		}
@@ -994,13 +1059,33 @@ void omap_hwmod_writel(u32 v, struct oma
 	__raw_writel(v, oh->_rt_va + reg_offs);
 }
 
+int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
+{
+	u32 v;
+	int retval = 0;
+
+	if (!oh)
+		return -EINVAL;
+
+	v = oh->_sysc_cache;
+
+	retval = _set_slave_idlemode(oh, idlemode, &v);
+	if (!retval)
+		_write_sysconfig(v, oh);
+
+	return retval;
+}
+
 /**
  * omap_hwmod_register - register a struct omap_hwmod
  * @oh: struct omap_hwmod *
  *
- * Registers the omap_hwmod @oh.  Returns -EEXIST if an omap_hwmod already
- * has been registered by the same name; -EINVAL if the omap_hwmod is in the
- * wrong state, or 0 on success.
+ * Registers the omap_hwmod @oh.  Returns -EEXIST if an omap_hwmod
+ * already has been registered by the same name; -EINVAL if the
+ * omap_hwmod is in the wrong state, if @oh is NULL, if the
+ * omap_hwmod's class field is NULL; if the omap_hwmod is missing a
+ * name, or if the omap_hwmod's class is missing a name; or 0 upon
+ * success.
  *
  * XXX The data should be copied into bootmem, so the original data
  * should be marked __initdata and freed after init.  This would allow
@@ -1012,7 +1097,8 @@ int omap_hwmod_register(struct omap_hwmo
 {
 	int ret, ms_id;
 
-	if (!oh || (oh->_state != _HWMOD_STATE_UNKNOWN))
+	if (!oh || !oh->name || !oh->class || !oh->class->name ||
+	    (oh->_state != _HWMOD_STATE_UNKNOWN))
 		return -EINVAL;
 
 	mutex_lock(&omap_hwmod_mutex);
@@ -1285,7 +1371,7 @@ void omap_hwmod_ocp_barrier(struct omap_
 {
 	BUG_ON(!oh);
 
-	if (!oh->sysconfig || !oh->sysconfig->sysc_flags) {
+	if (!oh->class->sysc || !oh->class->sysc->sysc_flags) {
 		WARN(1, "omap_device: %s: OCP barrier impossible due to "
 		      "device configuration\n", oh->name);
 		return;
@@ -1295,7 +1381,7 @@ void omap_hwmod_ocp_barrier(struct omap_
 	 * Forces posted writes to complete on the OCP thread handling
 	 * register writes
 	 */
-	omap_hwmod_readl(oh, oh->sysconfig->sysc_offs);
+	omap_hwmod_readl(oh, oh->class->sysc->sysc_offs);
 }
 
 /**
@@ -1425,6 +1511,9 @@ struct powerdomain *omap_hwmod_get_pwrdm
 		c = oh->slaves[oh->_mpu_port_index]->_clk;
 	}
 
+	if (!c->clkdm)
+		return NULL;
+
 	return c->clkdm->pwrdm.ptr;
 
 }
@@ -1488,8 +1577,8 @@ int omap_hwmod_del_initiator_dep(struct
  */
 int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
 {
-	if (!oh->sysconfig ||
-	    !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
+	if (!oh->class->sysc ||
+	    !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
 		return -EINVAL;
 
 	mutex_lock(&omap_hwmod_mutex);
@@ -1513,8 +1602,8 @@ int omap_hwmod_enable_wakeup(struct omap
  */
 int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
 {
-	if (!oh->sysconfig ||
-	    !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
+	if (!oh->class->sysc ||
+	    !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
 		return -EINVAL;
 
 	mutex_lock(&omap_hwmod_mutex);
@@ -1523,3 +1612,52 @@ int omap_hwmod_disable_wakeup(struct oma
 
 	return 0;
 }
+
+/**
+ * omap_hwmod_for_each_by_class - call @fn for each hwmod of class @classname
+ * @classname: struct omap_hwmod_class name to search for
+ * @fn: callback function pointer to call for each hwmod in class @classname
+ * @user: arbitrary context data to pass to the callback function
+ *
+ * For each omap_hwmod of class @classname, call @fn.  Takes
+ * omap_hwmod_mutex to prevent the hwmod list from changing during the
+ * iteration.  If the callback function returns something other than
+ * zero, the iterator is terminated, and the callback function's return
+ * value is passed back to the caller.  Returns 0 upon success, -EINVAL
+ * if @classname or @fn are NULL, or passes back the error code from @fn.
+ */
+int omap_hwmod_for_each_by_class(const char *classname,
+				 int (*fn)(struct omap_hwmod *oh,
+					   void *user),
+				 void *user)
+{
+	struct omap_hwmod *temp_oh;
+	int ret = 0;
+
+	if (!classname || !fn)
+		return -EINVAL;
+
+	pr_debug("omap_hwmod: %s: looking for modules of class %s\n",
+		 __func__, classname);
+
+	mutex_lock(&omap_hwmod_mutex);
+
+	list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
+		if (!strcmp(temp_oh->class->name, classname)) {
+			pr_debug("omap_hwmod: %s: %s: calling callback fn\n",
+				 __func__, temp_oh->name);
+			ret = (*fn)(temp_oh, user);
+			if (ret)
+				break;
+		}
+	}
+
+	mutex_unlock(&omap_hwmod_mutex);
+
+	if (ret)
+		pr_debug("omap_hwmod: %s: iterator terminated early: %d\n",
+			 __func__, ret);
+
+	return ret;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_common_data.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_common_data.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_common_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_common_data.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,68 @@
+/*
+ * omap_hwmod common data structures
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ * BenoÃ®t Cousson
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This data/structures are to be used while defining OMAP on-chip module
+ * data and their integration with other OMAP modules and Linux.
+ */
+
+#include <plat/omap_hwmod.h>
+
+#include "omap_hwmod_common_data.h"
+
+/**
+ * struct omap_hwmod_sysc_type1 - TYPE1 sysconfig scheme.
+ *
+ * To be used by hwmod structure to specify the sysconfig offsets
+ * if the device ip is compliant with the original PRCM protocol
+ * defined for OMAP2420.
+ */
+struct omap_hwmod_sysc_fields omap_hwmod_sysc_type1 = {
+	.midle_shift	= SYSC_TYPE1_MIDLEMODE_SHIFT,
+	.clkact_shift	= SYSC_TYPE1_CLOCKACTIVITY_SHIFT,
+	.sidle_shift	= SYSC_TYPE1_SIDLEMODE_SHIFT,
+	.enwkup_shift	= SYSC_TYPE1_ENAWAKEUP_SHIFT,
+	.srst_shift	= SYSC_TYPE1_SOFTRESET_SHIFT,
+	.autoidle_shift	= SYSC_TYPE1_AUTOIDLE_SHIFT,
+};
+
+/**
+ * struct omap_hwmod_sysc_type2 - TYPE2 sysconfig scheme.
+ *
+ * To be used by hwmod structure to specify the sysconfig offsets if the
+ * device ip is compliant with the new PRCM protocol defined for new
+ * OMAP4 IPs.
+ */
+struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2 = {
+	.midle_shift	= SYSC_TYPE2_MIDLEMODE_SHIFT,
+	.sidle_shift	= SYSC_TYPE2_SIDLEMODE_SHIFT,
+	.srst_shift	= SYSC_TYPE2_SOFTRESET_SHIFT,
+};
+
+
+/*
+ * omap_hwmod class data
+ */
+
+struct omap_hwmod_class l3_hwmod_class = {
+	.name = "l3"
+};
+
+struct omap_hwmod_class l4_hwmod_class = {
+	.name = "l4"
+};
+
+struct omap_hwmod_class mpu_hwmod_class = {
+	.name = "mpu"
+};
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_common_data.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_common_data.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_common_data.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/omap_hwmod_common_data.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,24 @@
+/*
+ * omap_hwmod_common_data.h - OMAP hwmod common macros and declarations
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * BenoÃ®t Cousson
+ *
+ * This program is free software; you can 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_OMAP_HWMOD_COMMON_DATA_H
+#define __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_COMMON_DATA_H
+
+#include <plat/omap_hwmod.h>
+
+/* OMAP hwmod classes - forward declarations */
+extern struct omap_hwmod_class l3_hwmod_class;
+extern struct omap_hwmod_class l4_hwmod_class;
+extern struct omap_hwmod_class mpu_hwmod_class;
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/opp2xxx.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/opp2xxx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/opp2xxx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/opp2xxx.h	2010-05-16 17:17:36.000000000 -0400
@@ -417,7 +417,12 @@ struct prcm_config {
 
 
 extern const struct prcm_config omap2420_rate_table[];
+
+#ifdef CONFIG_ARCH_OMAP2430
 extern const struct prcm_config omap2430_rate_table[];
+#else
+#define omap2430_rate_table	NULL
+#endif
 extern const struct prcm_config *rate_table;
 extern const struct prcm_config *curr_prcm_set;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm24xx.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/pm24xx.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm24xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/pm24xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,11 +57,8 @@ static void (*omap2_sram_idle)(void);
 static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl,
 				  void __iomem *sdrc_power);
 
-static struct powerdomain *mpu_pwrdm;
-static struct powerdomain *core_pwrdm;
-
-static struct clockdomain *dsp_clkdm;
-static struct clockdomain *gfx_clkdm;
+static struct powerdomain *mpu_pwrdm, *core_pwrdm;
+static struct clockdomain *dsp_clkdm, *mpu_clkdm, *wkup_clkdm, *gfx_clkdm;
 
 static struct clk *osc_ck, *emul_ck;
 
@@ -219,11 +216,12 @@ static void omap2_enter_mpu_retention(vo
 		/* Try to enter MPU retention */
 		prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) |
 				  OMAP_LOGICRETSTATE,
-				  MPU_MOD, PM_PWSTCTRL);
+				  MPU_MOD, OMAP2_PM_PWSTCTRL);
 	} else {
 		/* Block MPU retention */
 
-		prm_write_mod_reg(OMAP_LOGICRETSTATE, MPU_MOD, PM_PWSTCTRL);
+		prm_write_mod_reg(OMAP_LOGICRETSTATE, MPU_MOD,
+						 OMAP2_PM_PWSTCTRL);
 		only_idle = 1;
 	}
 
@@ -333,9 +331,17 @@ static struct platform_suspend_ops omap_
 	.valid		= suspend_valid_only_mem,
 };
 
-static int _pm_clkdm_enable_hwsup(struct clockdomain *clkdm, void *unused)
+/* XXX This function should be shareable between OMAP2xxx and OMAP3 */
+static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
 {
-	omap2_clkdm_allow_idle(clkdm);
+	clkdm_clear_all_wkdeps(clkdm);
+	clkdm_clear_all_sleepdeps(clkdm);
+
+	if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
+		omap2_clkdm_allow_idle(clkdm);
+	else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
+		 atomic_read(&clkdm->usecount) == 0)
+		omap2_clkdm_sleep(clkdm);
 	return 0;
 }
 
@@ -348,14 +354,6 @@ static void __init prcm_setup_regs(void)
 	prm_write_mod_reg(OMAP24XX_AUTOIDLE, OCP_MOD,
 			  OMAP2_PRCM_SYSCONFIG_OFFSET);
 
-	/* Set all domain wakeup dependencies */
-	prm_write_mod_reg(OMAP_EN_WKUP_MASK, MPU_MOD, PM_WKDEP);
-	prm_write_mod_reg(0, OMAP24XX_DSP_MOD, PM_WKDEP);
-	prm_write_mod_reg(0, GFX_MOD, PM_WKDEP);
-	prm_write_mod_reg(0, CORE_MOD, PM_WKDEP);
-	if (cpu_is_omap2430())
-		prm_write_mod_reg(0, OMAP2430_MDM_MOD, PM_WKDEP);
-
 	/*
 	 * Set CORE powerdomain memory banks to retain their contents
 	 * during RETENTION
@@ -384,8 +382,12 @@ static void __init prcm_setup_regs(void)
 	pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
 	omap2_clkdm_sleep(gfx_clkdm);
 
-	/* Enable clockdomain hardware-supervised control for all clkdms */
-	clkdm_for_each(_pm_clkdm_enable_hwsup, NULL);
+	/*
+	 * Clear clockdomain wakeup dependencies and enable
+	 * hardware-supervised idle for all clkdms
+	 */
+	clkdm_for_each(clkdms_setup, NULL);
+	clkdm_add_wkdep(mpu_clkdm, wkup_clkdm);
 
 	/* Enable clock autoidle for all domains */
 	cm_write_mod_reg(OMAP24XX_AUTO_CAM |
@@ -481,7 +483,7 @@ static int __init omap2_pm_init(void)
 	l = prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_REVISION_OFFSET);
 	printk(KERN_INFO "PRCM revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
 
-	/* Look up important powerdomains, clockdomains */
+	/* Look up important powerdomains */
 
 	mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
 	if (!mpu_pwrdm)
@@ -491,9 +493,19 @@ static int __init omap2_pm_init(void)
 	if (!core_pwrdm)
 		pr_err("PM: core_pwrdm not found\n");
 
+	/* Look up important clockdomains */
+
+	mpu_clkdm = clkdm_lookup("mpu_clkdm");
+	if (!mpu_clkdm)
+		pr_err("PM: mpu_clkdm not found\n");
+
+	wkup_clkdm = clkdm_lookup("wkup_clkdm");
+	if (!wkup_clkdm)
+		pr_err("PM: wkup_clkdm not found\n");
+
 	dsp_clkdm = clkdm_lookup("dsp_clkdm");
 	if (!dsp_clkdm)
-		pr_err("PM: mpu_clkdm not found\n");
+		pr_err("PM: dsp_clkdm not found\n");
 
 	gfx_clkdm = clkdm_lookup("gfx_clkdm");
 	if (!gfx_clkdm)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm34xx.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/pm34xx.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm34xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/pm34xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <plat/sram.h>
 #include <plat/clockdomain.h>
@@ -685,10 +686,10 @@ static void __init omap3_iva_idle(void)
 	prm_write_mod_reg(OMAP3430_RST1_IVA2 |
 			  OMAP3430_RST2_IVA2 |
 			  OMAP3430_RST3_IVA2,
-			  OMAP3430_IVA2_MOD, RM_RSTCTRL);
+			  OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
 
 	/* Enable IVA2 clock */
-	cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2,
+	cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK,
 			 OMAP3430_IVA2_MOD, CM_FCLKEN);
 
 	/* Set IVA2 boot mode to 'idle' */
@@ -696,7 +697,7 @@ static void __init omap3_iva_idle(void)
 			 OMAP343X_CONTROL_IVA2_BOOTMOD);
 
 	/* Un-reset IVA2 */
-	prm_write_mod_reg(0, OMAP3430_IVA2_MOD, RM_RSTCTRL);
+	prm_write_mod_reg(0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
 
 	/* Disable IVA2 clock */
 	cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
@@ -705,7 +706,7 @@ static void __init omap3_iva_idle(void)
 	prm_write_mod_reg(OMAP3430_RST1_IVA2 |
 			  OMAP3430_RST2_IVA2 |
 			  OMAP3430_RST3_IVA2,
-			  OMAP3430_IVA2_MOD, RM_RSTCTRL);
+			  OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
 }
 
 static void __init omap3_d2d_idle(void)
@@ -728,8 +729,8 @@ static void __init omap3_d2d_idle(void)
 	/* reset modem */
 	prm_write_mod_reg(OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON |
 			  OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST,
-			  CORE_MOD, RM_RSTCTRL);
-	prm_write_mod_reg(0, CORE_MOD, RM_RSTCTRL);
+			  CORE_MOD, OMAP2_RM_RSTCTRL);
+	prm_write_mod_reg(0, CORE_MOD, OMAP2_RM_RSTCTRL);
 }
 
 static void __init prcm_setup_regs(void)
@@ -916,13 +917,13 @@ static void __init prcm_setup_regs(void)
 	prm_write_mod_reg(0, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
 
 	/* Clear any pending 'reset' flags */
-	prm_write_mod_reg(0xffffffff, MPU_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, CORE_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, RM_RSTST);
+	prm_write_mod_reg(0xffffffff, MPU_MOD, OMAP2_RM_RSTST);
+	prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP2_RM_RSTST);
+	prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, OMAP2_RM_RSTST);
+	prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, OMAP2_RM_RSTST);
+	prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, OMAP2_RM_RSTST);
+	prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, OMAP2_RM_RSTST);
+	prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, OMAP2_RM_RSTST);
 
 	/* Clear any pending PRCM interrupts */
 	prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
@@ -941,6 +942,10 @@ void omap3_pm_off_mode_enable(int enable
 	else
 		state = PWRDM_POWER_RET;
 
+#ifdef CONFIG_CPU_IDLE
+	omap3_cpuidle_update_states();
+#endif
+
 	list_for_each_entry(pwrst, &pwrst_list, node) {
 		pwrst->next_state = state;
 		set_pwrdm_state(pwrst->pwrdm, state);
@@ -998,6 +1003,9 @@ static int __init pwrdms_setup(struct po
  */
 static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
 {
+	clkdm_clear_all_wkdeps(clkdm);
+	clkdm_clear_all_sleepdeps(clkdm);
+
 	if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
 		omap2_clkdm_allow_idle(clkdm);
 	else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
@@ -1018,6 +1026,7 @@ void omap_push_sram_idle(void)
 static int __init omap3_pm_init(void)
 {
 	struct power_state *pwrst, *tmp;
+	struct clockdomain *neon_clkdm, *per_clkdm, *mpu_clkdm, *core_clkdm;
 	int ret;
 
 	if (!cpu_is_omap34xx())
@@ -1057,6 +1066,11 @@ static int __init omap3_pm_init(void)
 	core_pwrdm = pwrdm_lookup("core_pwrdm");
 	cam_pwrdm = pwrdm_lookup("cam_pwrdm");
 
+	neon_clkdm = clkdm_lookup("neon_clkdm");
+	mpu_clkdm = clkdm_lookup("mpu_clkdm");
+	per_clkdm = clkdm_lookup("per_clkdm");
+	core_clkdm = clkdm_lookup("core_clkdm");
+
 	omap_push_sram_idle();
 #ifdef CONFIG_SUSPEND
 	suspend_set_ops(&omap_pm_ops);
@@ -1065,14 +1079,14 @@ static int __init omap3_pm_init(void)
 	pm_idle = omap3_pm_idle;
 	omap3_idle_init();
 
-	pwrdm_add_wkdep(neon_pwrdm, mpu_pwrdm);
+	clkdm_add_wkdep(neon_clkdm, mpu_clkdm);
 	/*
 	 * REVISIT: This wkdep is only necessary when GPIO2-6 are enabled for
 	 * IO-pad wakeup.  Otherwise it will unnecessarily waste power
 	 * waking up PER with every CORE wakeup - see
 	 * http://marc.info/?l=linux-omap&m=121852150710062&w=2
 	*/
-	pwrdm_add_wkdep(per_pwrdm, core_pwrdm);
+	clkdm_add_wkdep(per_clkdm, core_clkdm);
 
 	if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
 		omap3_secure_ram_storage =
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm-debug.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/pm-debug.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm-debug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/pm-debug.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <plat/clock.h>
 #include <plat/board.h>
@@ -67,9 +68,9 @@ void omap2_pm_dump(int mode, int resume,
 #if 0
 		/* MPU */
 		DUMP_PRM_MOD_REG(OCP_MOD, OMAP2_PRM_IRQENABLE_MPU_OFFSET);
-		DUMP_CM_MOD_REG(MPU_MOD, CM_CLKSTCTRL);
-		DUMP_PRM_MOD_REG(MPU_MOD, PM_PWSTCTRL);
-		DUMP_PRM_MOD_REG(MPU_MOD, PM_PWSTST);
+		DUMP_CM_MOD_REG(MPU_MOD, OMAP2_CM_CLKSTCTRL);
+		DUMP_PRM_MOD_REG(MPU_MOD, OMAP2_PM_PWSTCTRL);
+		DUMP_PRM_MOD_REG(MPU_MOD, OMAP2_PM_PWSTST);
 		DUMP_PRM_MOD_REG(MPU_MOD, PM_WKDEP);
 #endif
 #if 0
@@ -93,7 +94,7 @@ void omap2_pm_dump(int mode, int resume,
 		DUMP_CM_MOD_REG(WKUP_MOD, CM_ICLKEN);
 		DUMP_CM_MOD_REG(PLL_MOD, CM_CLKEN);
 		DUMP_CM_MOD_REG(PLL_MOD, CM_AUTOIDLE);
-		DUMP_PRM_MOD_REG(CORE_MOD, PM_PWSTST);
+		DUMP_PRM_MOD_REG(CORE_MOD, OMAP2_PM_PWSTST);
 #endif
 #if 0
 		/* DSP */
@@ -103,11 +104,11 @@ void omap2_pm_dump(int mode, int resume,
 			DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_IDLEST);
 			DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_AUTOIDLE);
 			DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_CLKSEL);
-			DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_CLKSTCTRL);
-			DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, RM_RSTCTRL);
-			DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, RM_RSTST);
-			DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, PM_PWSTCTRL);
-			DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, PM_PWSTST);
+			DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_CM_CLKSTCTRL);
+			DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_RM_RSTCTRL);
+			DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_RM_RSTST);
+			DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_PM_PWSTCTRL);
+			DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_PM_PWSTST);
 		}
 #endif
 	} else {
@@ -385,6 +386,11 @@ static int pwrdm_dbg_show_counter(struct
 		seq_printf(s, ",%s:%d", pwrdm_state_names[i],
 			pwrdm->state_counter[i]);
 
+	seq_printf(s, ",RET-LOGIC-OFF:%d", pwrdm->ret_logic_off_counter);
+	for (i = 0; i < pwrdm->banks; i++)
+		seq_printf(s, ",RET-MEMBANK%d-OFF:%d", i + 1,
+				pwrdm->ret_mem_off_counter[i]);
+
 	seq_printf(s, "\n");
 
 	return 0;
@@ -577,7 +583,7 @@ static int __init pm_dbg_init(void)
 	(void) debugfs_create_file("time", S_IRUGO,
 		d, (void *)DEBUG_FILE_TIMERS, &debug_fops);
 
-	pwrdm_for_each_nolock(pwrdms_setup, (void *)d);
+	pwrdm_for_each(pwrdms_setup, (void *)d);
 
 	pm_dbg_dir = debugfs_create_dir("registers", d);
 	if (IS_ERR(pm_dbg_dir))
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/pm.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/pm.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,22 @@ extern int omap3_can_sleep(void);
 extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
 extern int omap3_idle_init(void);
 
+struct cpuidle_params {
+	u8  valid;
+	u32 sleep_latency;
+	u32 wake_latency;
+	u32 threshold;
+};
+
+#if defined(CONFIG_PM) && defined(CONFIG_CPU_IDLE)
+extern void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params);
+#else
+static
+inline void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
+{
+}
+#endif
+
 extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm);
 extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
 
@@ -37,6 +53,10 @@ extern int omap2_pm_debug;
 #define omap2_pm_debug				0
 #endif
 
+#if defined(CONFIG_CPU_IDLE)
+extern void omap3_cpuidle_update_states(void);
+#endif
+
 #if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
 extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev);
 extern int pm_dbg_regset_save(int reg_set);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomain.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/powerdomain.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomain.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/powerdomain.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,10 +2,12 @@
  * OMAP powerdomain control
  *
  * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2008 Nokia Corporation
+ * Copyright (C) 2007-2009 Nokia Corporation
  *
  * Written by Paul Walmsley
  *
+ * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@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.
@@ -26,12 +28,15 @@
 
 #include "cm.h"
 #include "cm-regbits-34xx.h"
+#include "cm-regbits-44xx.h"
 #include "prm.h"
 #include "prm-regbits-34xx.h"
+#include "prm-regbits-44xx.h"
 
 #include <plat/cpu.h>
 #include <plat/powerdomain.h>
 #include <plat/clockdomain.h>
+#include <plat/prcm.h>
 
 #include "pm.h"
 
@@ -40,28 +45,42 @@ enum {
 	PWRDM_STATE_PREV,
 };
 
-/* pwrdm_list contains all registered struct powerdomains */
-static LIST_HEAD(pwrdm_list);
+/* Variable holding value of the CPU dependent PWRSTCTRL Register Offset */
+static u16 pwrstctrl_reg_offs;
 
-/*
- * pwrdm_rwlock protects pwrdm_list add and del ops - also reused to
- * protect pwrdm_clkdms[] during clkdm add/del ops
+/* Variable holding value of the CPU dependent PWRSTST Register Offset */
+static u16 pwrstst_reg_offs;
+
+/* OMAP3 and OMAP4 specific register bit initialisations
+ * Notice that the names here are not according to each power
+ * domain but the bit mapping used applies to all of them
  */
-static DEFINE_RWLOCK(pwrdm_rwlock);
 
+/* OMAP3 and OMAP4 Memory Onstate Masks (common across all power domains) */
+#define OMAP_MEM0_ONSTATE_MASK OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK
+#define OMAP_MEM1_ONSTATE_MASK OMAP3430_L1FLATMEMONSTATE_MASK
+#define OMAP_MEM2_ONSTATE_MASK OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK
+#define OMAP_MEM3_ONSTATE_MASK OMAP3430_L2FLATMEMONSTATE_MASK
+#define OMAP_MEM4_ONSTATE_MASK OMAP4430_OCP_NRET_BANK_ONSTATE_MASK
 
-/* Private functions */
+/* OMAP3 and OMAP4 Memory Retstate Masks (common across all power domains) */
+#define OMAP_MEM0_RETSTATE_MASK OMAP3430_SHAREDL1CACHEFLATRETSTATE
+#define OMAP_MEM1_RETSTATE_MASK OMAP3430_L1FLATMEMRETSTATE
+#define OMAP_MEM2_RETSTATE_MASK OMAP3430_SHAREDL2CACHEFLATRETSTATE
+#define OMAP_MEM3_RETSTATE_MASK OMAP3430_L2FLATMEMRETSTATE
+#define OMAP_MEM4_RETSTATE_MASK OMAP4430_OCP_NRET_BANK_RETSTATE_MASK
 
-static u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
-{
-	u32 v;
+/* OMAP3 and OMAP4 Memory Status bits */
+#define OMAP_MEM0_STATEST_MASK OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK
+#define OMAP_MEM1_STATEST_MASK OMAP3430_L1FLATMEMSTATEST_MASK
+#define OMAP_MEM2_STATEST_MASK OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK
+#define OMAP_MEM3_STATEST_MASK OMAP3430_L2FLATMEMSTATEST_MASK
+#define OMAP_MEM4_STATEST_MASK OMAP4430_OCP_NRET_BANK_STATEST_MASK
 
-	v = prm_read_mod_reg(domain, idx);
-	v &= mask;
-	v >>= __ffs(mask);
+/* pwrdm_list contains all registered struct powerdomains */
+static LIST_HEAD(pwrdm_list);
 
-	return v;
-}
+/* Private functions */
 
 static struct powerdomain *_pwrdm_lookup(const char *name)
 {
@@ -79,32 +98,63 @@ static struct powerdomain *_pwrdm_lookup
 	return pwrdm;
 }
 
-/* _pwrdm_deps_lookup - look up the specified powerdomain in a pwrdm list */
-static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm,
-					      struct pwrdm_dep *deps)
+/**
+ * _pwrdm_register - register a powerdomain
+ * @pwrdm: struct powerdomain * to register
+ *
+ * Adds a powerdomain to the internal powerdomain list.  Returns
+ * -EINVAL if given a null pointer, -EEXIST if a powerdomain is
+ * already registered by the provided name, or 0 upon success.
+ */
+static int _pwrdm_register(struct powerdomain *pwrdm)
 {
-	struct pwrdm_dep *pd;
+	int i;
 
-	if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip))
-		return ERR_PTR(-EINVAL);
+	if (!pwrdm)
+		return -EINVAL;
 
-	for (pd = deps; pd->pwrdm_name; pd++) {
+	if (!omap_chip_is(pwrdm->omap_chip))
+		return -EINVAL;
 
-		if (!omap_chip_is(pd->omap_chip))
-			continue;
+	if (_pwrdm_lookup(pwrdm->name))
+		return -EEXIST;
 
-		if (!pd->pwrdm && pd->pwrdm_name)
-			pd->pwrdm = pwrdm_lookup(pd->pwrdm_name);
+	list_add(&pwrdm->node, &pwrdm_list);
 
-		if (pd->pwrdm == pwrdm)
-			break;
+	/* Initialize the powerdomain's state counter */
+	for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
+		pwrdm->state_counter[i] = 0;
 
-	}
+	pwrdm->ret_logic_off_counter = 0;
+	for (i = 0; i < pwrdm->banks; i++)
+		pwrdm->ret_mem_off_counter[i] = 0;
 
-	if (!pd->pwrdm_name)
-		return ERR_PTR(-ENOENT);
+	pwrdm_wait_transition(pwrdm);
+	pwrdm->state = pwrdm_read_pwrst(pwrdm);
+	pwrdm->state_counter[pwrdm->state] = 1;
 
-	return pd->pwrdm;
+	pr_debug("powerdomain: registered %s\n", pwrdm->name);
+
+	return 0;
+}
+
+static void _update_logic_membank_counters(struct powerdomain *pwrdm)
+{
+	int i;
+	u8 prev_logic_pwrst, prev_mem_pwrst;
+
+	prev_logic_pwrst = pwrdm_read_prev_logic_pwrst(pwrdm);
+	if ((pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET) &&
+	    (prev_logic_pwrst == PWRDM_POWER_OFF))
+		pwrdm->ret_logic_off_counter++;
+
+	for (i = 0; i < pwrdm->banks; i++) {
+		prev_mem_pwrst = pwrdm_read_prev_mem_pwrst(pwrdm, i);
+
+		if ((pwrdm->pwrsts_mem_ret[i] == PWRSTS_OFF_RET) &&
+		    (prev_mem_pwrst == PWRDM_POWER_OFF))
+			pwrdm->ret_mem_off_counter[i]++;
+	}
 }
 
 static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
@@ -126,6 +176,8 @@ static int _pwrdm_state_switch(struct po
 		prev = pwrdm_read_prev_pwrst(pwrdm);
 		if (pwrdm->state != prev)
 			pwrdm->state_counter[prev]++;
+		if (prev == PWRDM_POWER_RET)
+			_update_logic_membank_counters(pwrdm);
 		break;
 	default:
 		return -EINVAL;
@@ -154,134 +206,71 @@ static int _pwrdm_post_transition_cb(str
 	return 0;
 }
 
-static __init void _pwrdm_setup(struct powerdomain *pwrdm)
-{
-	int i;
-
-	for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
-		pwrdm->state_counter[i] = 0;
-
-	pwrdm_wait_transition(pwrdm);
-	pwrdm->state = pwrdm_read_pwrst(pwrdm);
-	pwrdm->state_counter[pwrdm->state] = 1;
-
-}
-
 /* Public functions */
 
 /**
  * pwrdm_init - set up the powerdomain layer
+ * @pwrdm_list: array of struct powerdomain pointers to register
  *
- * Loop through the list of powerdomains, registering all that are
- * available on the current CPU. If pwrdm_list is supplied and not
- * null, all of the referenced powerdomains will be registered.  No
- * return value.
+ * Loop through the array of powerdomains @pwrdm_list, registering all
+ * that are available on the current CPU. If pwrdm_list is supplied
+ * and not null, all of the referenced powerdomains will be
+ * registered.  No return value.  XXX pwrdm_list is not really a
+ * "list"; it is an array.  Rename appropriately.
  */
 void pwrdm_init(struct powerdomain **pwrdm_list)
 {
 	struct powerdomain **p = NULL;
 
-	if (pwrdm_list) {
-		for (p = pwrdm_list; *p; p++) {
-			pwrdm_register(*p);
-			_pwrdm_setup(*p);
-		}
+	if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+		pwrstctrl_reg_offs = OMAP2_PM_PWSTCTRL;
+		pwrstst_reg_offs = OMAP2_PM_PWSTST;
+	} else if (cpu_is_omap44xx()) {
+		pwrstctrl_reg_offs = OMAP4_PM_PWSTCTRL;
+		pwrstst_reg_offs = OMAP4_PM_PWSTST;
+	} else {
+		printk(KERN_ERR "Power Domain struct not supported for " \
+							"this CPU\n");
+		return;
 	}
-}
-
-/**
- * pwrdm_register - register a powerdomain
- * @pwrdm: struct powerdomain * to register
- *
- * Adds a powerdomain to the internal powerdomain list.  Returns
- * -EINVAL if given a null pointer, -EEXIST if a powerdomain is
- * already registered by the provided name, or 0 upon success.
- */
-int pwrdm_register(struct powerdomain *pwrdm)
-{
-	unsigned long flags;
-	int ret = -EINVAL;
-
-	if (!pwrdm)
-		return -EINVAL;
-
-	if (!omap_chip_is(pwrdm->omap_chip))
-		return -EINVAL;
 
-	write_lock_irqsave(&pwrdm_rwlock, flags);
-	if (_pwrdm_lookup(pwrdm->name)) {
-		ret = -EEXIST;
-		goto pr_unlock;
+	if (pwrdm_list) {
+		for (p = pwrdm_list; *p; p++)
+			_pwrdm_register(*p);
 	}
-
-	list_add(&pwrdm->node, &pwrdm_list);
-
-	pr_debug("powerdomain: registered %s\n", pwrdm->name);
-	ret = 0;
-
-pr_unlock:
-	write_unlock_irqrestore(&pwrdm_rwlock, flags);
-
-	return ret;
-}
-
-/**
- * pwrdm_unregister - unregister a powerdomain
- * @pwrdm: struct powerdomain * to unregister
- *
- * Removes a powerdomain from the internal powerdomain list.  Returns
- * -EINVAL if pwrdm argument is NULL.
- */
-int pwrdm_unregister(struct powerdomain *pwrdm)
-{
-	unsigned long flags;
-
-	if (!pwrdm)
-		return -EINVAL;
-
-	write_lock_irqsave(&pwrdm_rwlock, flags);
-	list_del(&pwrdm->node);
-	write_unlock_irqrestore(&pwrdm_rwlock, flags);
-
-	pr_debug("powerdomain: unregistered %s\n", pwrdm->name);
-
-	return 0;
 }
 
 /**
  * pwrdm_lookup - look up a powerdomain by name, return a pointer
  * @name: name of powerdomain
  *
- * Find a registered powerdomain by its name.  Returns a pointer to the
- * struct powerdomain if found, or NULL otherwise.
+ * Find a registered powerdomain by its name @name.  Returns a pointer
+ * to the struct powerdomain if found, or NULL otherwise.
  */
 struct powerdomain *pwrdm_lookup(const char *name)
 {
 	struct powerdomain *pwrdm;
-	unsigned long flags;
 
 	if (!name)
 		return NULL;
 
-	read_lock_irqsave(&pwrdm_rwlock, flags);
 	pwrdm = _pwrdm_lookup(name);
-	read_unlock_irqrestore(&pwrdm_rwlock, flags);
 
 	return pwrdm;
 }
 
 /**
- * pwrdm_for_each_nolock - call function on each registered clockdomain
+ * pwrdm_for_each - call function on each registered clockdomain
  * @fn: callback function *
  *
- * Call the supplied function for each registered powerdomain.  The
- * callback function can return anything but 0 to bail out early from
- * the iterator.  Returns the last return value of the callback function, which
- * should be 0 for success or anything else to indicate failure; or -EINVAL if
- * the function pointer is null.
+ * Call the supplied function @fn for each registered powerdomain.
+ * The callback function @fn can return anything but 0 to bail out
+ * early from the iterator.  Returns the last return value of the
+ * callback function, which should be 0 for success or anything else
+ * to indicate failure; or -EINVAL if the function pointer is null.
  */
-int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
-				void *user)
+int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
+		   void *user)
 {
 	struct powerdomain *temp_pwrdm;
 	int ret = 0;
@@ -299,40 +288,17 @@ int pwrdm_for_each_nolock(int (*fn)(stru
 }
 
 /**
- * pwrdm_for_each - call function on each registered clockdomain
- * @fn: callback function *
- *
- * This function is the same as 'pwrdm_for_each_nolock()', but keeps the
- * &pwrdm_rwlock locked for reading, so no powerdomain structure manipulation
- * functions should be called from the callback, although hardware powerdomain
- * control functions are fine.
- */
-int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
-			void *user)
-{
-	unsigned long flags;
-	int ret;
-
-	read_lock_irqsave(&pwrdm_rwlock, flags);
-	ret = pwrdm_for_each_nolock(fn, user);
-	read_unlock_irqrestore(&pwrdm_rwlock, flags);
-
-	return ret;
-}
-
-/**
  * pwrdm_add_clkdm - add a clockdomain to a powerdomain
  * @pwrdm: struct powerdomain * to add the clockdomain to
  * @clkdm: struct clockdomain * to associate with a powerdomain
  *
- * Associate the clockdomain 'clkdm' with a powerdomain 'pwrdm'.  This
+ * Associate the clockdomain @clkdm with a powerdomain @pwrdm.  This
  * enables the use of pwrdm_for_each_clkdm().  Returns -EINVAL if
  * presented with invalid pointers; -ENOMEM if memory could not be allocated;
  * or 0 upon success.
  */
 int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
 {
-	unsigned long flags;
 	int i;
 	int ret = -EINVAL;
 
@@ -342,8 +308,6 @@ int pwrdm_add_clkdm(struct powerdomain *
 	pr_debug("powerdomain: associating clockdomain %s with powerdomain "
 		 "%s\n", clkdm->name, pwrdm->name);
 
-	write_lock_irqsave(&pwrdm_rwlock, flags);
-
 	for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
 		if (!pwrdm->pwrdm_clkdms[i])
 			break;
@@ -368,8 +332,6 @@ int pwrdm_add_clkdm(struct powerdomain *
 	ret = 0;
 
 pac_exit:
-	write_unlock_irqrestore(&pwrdm_rwlock, flags);
-
 	return ret;
 }
 
@@ -378,14 +340,13 @@ pac_exit:
  * @pwrdm: struct powerdomain * to add the clockdomain to
  * @clkdm: struct clockdomain * to associate with a powerdomain
  *
- * Dissociate the clockdomain 'clkdm' from the powerdomain
- * 'pwrdm'. Returns -EINVAL if presented with invalid pointers;
- * -ENOENT if the clkdm was not associated with the powerdomain, or 0
- * upon success.
+ * Dissociate the clockdomain @clkdm from the powerdomain
+ * @pwrdm. Returns -EINVAL if presented with invalid pointers; -ENOENT
+ * if @clkdm was not associated with the powerdomain, or 0 upon
+ * success.
  */
 int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
 {
-	unsigned long flags;
 	int ret = -EINVAL;
 	int i;
 
@@ -395,8 +356,6 @@ int pwrdm_del_clkdm(struct powerdomain *
 	pr_debug("powerdomain: dissociating clockdomain %s from powerdomain "
 		 "%s\n", clkdm->name, pwrdm->name);
 
-	write_lock_irqsave(&pwrdm_rwlock, flags);
-
 	for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
 		if (pwrdm->pwrdm_clkdms[i] == clkdm)
 			break;
@@ -413,8 +372,6 @@ int pwrdm_del_clkdm(struct powerdomain *
 	ret = 0;
 
 pdc_exit:
-	write_unlock_irqrestore(&pwrdm_rwlock, flags);
-
 	return ret;
 }
 
@@ -423,259 +380,34 @@ pdc_exit:
  * @pwrdm: struct powerdomain * to iterate over
  * @fn: callback function *
  *
- * Call the supplied function for each clockdomain in the powerdomain
- * 'pwrdm'.  The callback function can return anything but 0 to bail
- * out early from the iterator.  The callback function is called with
- * the pwrdm_rwlock held for reading, so no powerdomain structure
- * manipulation functions should be called from the callback, although
- * hardware powerdomain control functions are fine.  Returns -EINVAL
- * if presented with invalid pointers; or passes along the last return
- * value of the callback function, which should be 0 for success or
- * anything else to indicate failure.
+ * Call the supplied function @fn for each clockdomain in the powerdomain
+ * @pwrdm.  The callback function can return anything but 0 to bail
+ * out early from the iterator.  Returns -EINVAL if presented with
+ * invalid pointers; or passes along the last return value of the
+ * callback function, which should be 0 for success or anything else
+ * to indicate failure.
  */
 int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
 			 int (*fn)(struct powerdomain *pwrdm,
 				   struct clockdomain *clkdm))
 {
-	unsigned long flags;
 	int ret = 0;
 	int i;
 
 	if (!fn)
 		return -EINVAL;
 
-	read_lock_irqsave(&pwrdm_rwlock, flags);
-
 	for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
 		ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
 
-	read_unlock_irqrestore(&pwrdm_rwlock, flags);
-
 	return ret;
 }
 
-
-/**
- * pwrdm_add_wkdep - add a wakeup dependency from pwrdm2 to pwrdm1
- * @pwrdm1: wake this struct powerdomain * up (dependent)
- * @pwrdm2: when this struct powerdomain * wakes up (source)
- *
- * When the powerdomain represented by pwrdm2 wakes up (due to an
- * interrupt), wake up pwrdm1.	Implemented in hardware on the OMAP,
- * this feature is designed to reduce wakeup latency of the dependent
- * powerdomain.  Returns -EINVAL if presented with invalid powerdomain
- * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
- * 0 upon success.
- */
-int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
-{
-	struct powerdomain *p;
-
-	if (!pwrdm1)
-		return -EINVAL;
-
-	p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
-	if (IS_ERR(p)) {
-		pr_debug("powerdomain: hardware cannot set/clear wake up of "
-			 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
-		return PTR_ERR(p);
-	}
-
-	pr_debug("powerdomain: hardware will wake up %s when %s wakes up\n",
-		 pwrdm1->name, pwrdm2->name);
-
-	prm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
-			     pwrdm1->prcm_offs, PM_WKDEP);
-
-	return 0;
-}
-
-/**
- * pwrdm_del_wkdep - remove a wakeup dependency from pwrdm2 to pwrdm1
- * @pwrdm1: wake this struct powerdomain * up (dependent)
- * @pwrdm2: when this struct powerdomain * wakes up (source)
- *
- * Remove a wakeup dependency that causes pwrdm1 to wake up when pwrdm2
- * wakes up.  Returns -EINVAL if presented with invalid powerdomain
- * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
- * 0 upon success.
- */
-int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
-{
-	struct powerdomain *p;
-
-	if (!pwrdm1)
-		return -EINVAL;
-
-	p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
-	if (IS_ERR(p)) {
-		pr_debug("powerdomain: hardware cannot set/clear wake up of "
-			 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
-		return PTR_ERR(p);
-	}
-
-	pr_debug("powerdomain: hardware will no longer wake up %s after %s "
-		 "wakes up\n", pwrdm1->name, pwrdm2->name);
-
-	prm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
-			       pwrdm1->prcm_offs, PM_WKDEP);
-
-	return 0;
-}
-
-/**
- * pwrdm_read_wkdep - read wakeup dependency state from pwrdm2 to pwrdm1
- * @pwrdm1: wake this struct powerdomain * up (dependent)
- * @pwrdm2: when this struct powerdomain * wakes up (source)
- *
- * Return 1 if a hardware wakeup dependency exists wherein pwrdm1 will be
- * awoken when pwrdm2 wakes up; 0 if dependency is not set; -EINVAL
- * if either powerdomain pointer is invalid; or -ENOENT if the hardware
- * is incapable.
- *
- * REVISIT: Currently this function only represents software-controllable
- * wakeup dependencies.  Wakeup dependencies fixed in hardware are not
- * yet handled here.
- */
-int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
-{
-	struct powerdomain *p;
-
-	if (!pwrdm1)
-		return -EINVAL;
-
-	p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
-	if (IS_ERR(p)) {
-		pr_debug("powerdomain: hardware cannot set/clear wake up of "
-			 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
-		return PTR_ERR(p);
-	}
-
-	return prm_read_mod_bits_shift(pwrdm1->prcm_offs, PM_WKDEP,
-					(1 << pwrdm2->dep_bit));
-}
-
-/**
- * pwrdm_add_sleepdep - add a sleep dependency from pwrdm2 to pwrdm1
- * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
- * @pwrdm2: when this struct powerdomain * is active (source)
- *
- * Prevent pwrdm1 from automatically going inactive (and then to
- * retention or off) if pwrdm2 is still active.	 Returns -EINVAL if
- * presented with invalid powerdomain pointers or called on a machine
- * that does not support software-configurable hardware sleep dependencies,
- * -ENOENT if the specified dependency cannot be set in hardware, or
- * 0 upon success.
- */
-int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
-{
-	struct powerdomain *p;
-
-	if (!cpu_is_omap34xx())
-		return -EINVAL;
-
-	if (!pwrdm1)
-		return -EINVAL;
-
-	p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
-	if (IS_ERR(p)) {
-		pr_debug("powerdomain: hardware cannot set/clear sleep "
-			 "dependency affecting %s from %s\n", pwrdm1->name,
-			 pwrdm2->name);
-		return PTR_ERR(p);
-	}
-
-	pr_debug("powerdomain: will prevent %s from sleeping if %s is active\n",
-		 pwrdm1->name, pwrdm2->name);
-
-	cm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
-			    pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
-
-	return 0;
-}
-
-/**
- * pwrdm_del_sleepdep - remove a sleep dependency from pwrdm2 to pwrdm1
- * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
- * @pwrdm2: when this struct powerdomain * is active (source)
- *
- * Allow pwrdm1 to automatically go inactive (and then to retention or
- * off), independent of the activity state of pwrdm2.  Returns -EINVAL
- * if presented with invalid powerdomain pointers or called on a machine
- * that does not support software-configurable hardware sleep dependencies,
- * -ENOENT if the specified dependency cannot be cleared in hardware, or
- * 0 upon success.
- */
-int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
-{
-	struct powerdomain *p;
-
-	if (!cpu_is_omap34xx())
-		return -EINVAL;
-
-	if (!pwrdm1)
-		return -EINVAL;
-
-	p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
-	if (IS_ERR(p)) {
-		pr_debug("powerdomain: hardware cannot set/clear sleep "
-			 "dependency affecting %s from %s\n", pwrdm1->name,
-			 pwrdm2->name);
-		return PTR_ERR(p);
-	}
-
-	pr_debug("powerdomain: will no longer prevent %s from sleeping if "
-		 "%s is active\n", pwrdm1->name, pwrdm2->name);
-
-	cm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
-			      pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
-
-	return 0;
-}
-
-/**
- * pwrdm_read_sleepdep - read sleep dependency state from pwrdm2 to pwrdm1
- * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
- * @pwrdm2: when this struct powerdomain * is active (source)
- *
- * Return 1 if a hardware sleep dependency exists wherein pwrdm1 will
- * not be allowed to automatically go inactive if pwrdm2 is active;
- * 0 if pwrdm1's automatic power state inactivity transition is independent
- * of pwrdm2's; -EINVAL if either powerdomain pointer is invalid or called
- * on a machine that does not support software-configurable hardware sleep
- * dependencies; or -ENOENT if the hardware is incapable.
- *
- * REVISIT: Currently this function only represents software-controllable
- * sleep dependencies.	Sleep dependencies fixed in hardware are not
- * yet handled here.
- */
-int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
-{
-	struct powerdomain *p;
-
-	if (!cpu_is_omap34xx())
-		return -EINVAL;
-
-	if (!pwrdm1)
-		return -EINVAL;
-
-	p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
-	if (IS_ERR(p)) {
-		pr_debug("powerdomain: hardware cannot set/clear sleep "
-			 "dependency affecting %s from %s\n", pwrdm1->name,
-			 pwrdm2->name);
-		return PTR_ERR(p);
-	}
-
-	return prm_read_mod_bits_shift(pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP,
-					(1 << pwrdm2->dep_bit));
-}
-
 /**
  * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
  * @pwrdm: struct powerdomain *
  *
- * Return the number of controllable memory banks in powerdomain pwrdm,
+ * Return the number of controllable memory banks in powerdomain @pwrdm,
  * starting with 1.  Returns -EINVAL if the powerdomain pointer is null.
  */
 int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
@@ -691,7 +423,7 @@ int pwrdm_get_mem_bank_count(struct powe
  * @pwrdm: struct powerdomain * to set
  * @pwrst: one of the PWRDM_POWER_* macros
  *
- * Set the powerdomain pwrdm's next power state to pwrst.  The powerdomain
+ * Set the powerdomain @pwrdm's next power state to @pwrst.  The powerdomain
  * may not enter this state immediately if the preconditions for this state
  * have not been satisfied.  Returns -EINVAL if the powerdomain pointer is
  * null or if the power state is invalid for the powerdomin, or returns 0
@@ -710,7 +442,7 @@ int pwrdm_set_next_pwrst(struct powerdom
 
 	prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
 			     (pwrst << OMAP_POWERSTATE_SHIFT),
-			     pwrdm->prcm_offs, PM_PWSTCTRL);
+			     pwrdm->prcm_offs, pwrstctrl_reg_offs);
 
 	return 0;
 }
@@ -719,7 +451,7 @@ int pwrdm_set_next_pwrst(struct powerdom
  * pwrdm_read_next_pwrst - get next powerdomain power state
  * @pwrdm: struct powerdomain * to get power state
  *
- * Return the powerdomain pwrdm's next power state.  Returns -EINVAL
+ * Return the powerdomain @pwrdm's next power state.  Returns -EINVAL
  * if the powerdomain pointer is null or returns the next power state
  * upon success.
  */
@@ -728,15 +460,15 @@ int pwrdm_read_next_pwrst(struct powerdo
 	if (!pwrdm)
 		return -EINVAL;
 
-	return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL,
-					OMAP_POWERSTATE_MASK);
+	return prm_read_mod_bits_shift(pwrdm->prcm_offs,
+				 pwrstctrl_reg_offs, OMAP_POWERSTATE_MASK);
 }
 
 /**
  * pwrdm_read_pwrst - get current powerdomain power state
  * @pwrdm: struct powerdomain * to get power state
  *
- * Return the powerdomain pwrdm's current power state.	Returns -EINVAL
+ * Return the powerdomain @pwrdm's current power state.	Returns -EINVAL
  * if the powerdomain pointer is null or returns the current power state
  * upon success.
  */
@@ -745,15 +477,15 @@ int pwrdm_read_pwrst(struct powerdomain
 	if (!pwrdm)
 		return -EINVAL;
 
-	return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST,
-					OMAP_POWERSTATEST_MASK);
+	return prm_read_mod_bits_shift(pwrdm->prcm_offs,
+				 pwrstst_reg_offs, OMAP_POWERSTATEST_MASK);
 }
 
 /**
  * pwrdm_read_prev_pwrst - get previous powerdomain power state
  * @pwrdm: struct powerdomain * to get previous power state
  *
- * Return the powerdomain pwrdm's previous power state.  Returns -EINVAL
+ * Return the powerdomain @pwrdm's previous power state.  Returns -EINVAL
  * if the powerdomain pointer is null or returns the previous power state
  * upon success.
  */
@@ -771,11 +503,11 @@ int pwrdm_read_prev_pwrst(struct powerdo
  * @pwrdm: struct powerdomain * to set
  * @pwrst: one of the PWRDM_POWER_* macros
  *
- * Set the next power state that the logic portion of the powerdomain
- * pwrdm will enter when the powerdomain enters retention.  This will
- * be either RETENTION or OFF, if supported.  Returns -EINVAL if the
- * powerdomain pointer is null or the target power state is not not
- * supported, or returns 0 upon success.
+ * Set the next power state @pwrst that the logic portion of the
+ * powerdomain @pwrdm will enter when the powerdomain enters retention.
+ * This will be either RETENTION or OFF, if supported.  Returns
+ * -EINVAL if the powerdomain pointer is null or the target power
+ * state is not not supported, or returns 0 upon success.
  */
 int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
 {
@@ -796,7 +528,7 @@ int pwrdm_set_logic_retst(struct powerdo
 	 */
 	prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE,
 			     (pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE)),
-			     pwrdm->prcm_offs, PM_PWSTCTRL);
+				 pwrdm->prcm_offs, pwrstctrl_reg_offs);
 
 	return 0;
 }
@@ -807,13 +539,14 @@ int pwrdm_set_logic_retst(struct powerdo
  * @bank: memory bank number to set (0-3)
  * @pwrst: one of the PWRDM_POWER_* macros
  *
- * Set the next power state that memory bank x of the powerdomain
- * pwrdm will enter when the powerdomain enters the ON state.  Bank
- * will be a number from 0 to 3, and represents different types of
- * memory, depending on the powerdomain.  Returns -EINVAL if the
- * powerdomain pointer is null or the target power state is not not
- * supported for this memory bank, -EEXIST if the target memory bank
- * does not exist or is not controllable, or returns 0 upon success.
+ * Set the next power state @pwrst that memory bank @bank of the
+ * powerdomain @pwrdm will enter when the powerdomain enters the ON
+ * state.  @bank will be a number from 0 to 3, and represents different
+ * types of memory, depending on the powerdomain.  Returns -EINVAL if
+ * the powerdomain pointer is null or the target power state is not
+ * not supported for this memory bank, -EEXIST if the target memory
+ * bank does not exist or is not controllable, or returns 0 upon
+ * success.
  */
 int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
 {
@@ -839,16 +572,19 @@ int pwrdm_set_mem_onst(struct powerdomai
 	 */
 	switch (bank) {
 	case 0:
-		m = OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK;
+		m = OMAP_MEM0_ONSTATE_MASK;
 		break;
 	case 1:
-		m = OMAP3430_L1FLATMEMONSTATE_MASK;
+		m = OMAP_MEM1_ONSTATE_MASK;
 		break;
 	case 2:
-		m = OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK;
+		m = OMAP_MEM2_ONSTATE_MASK;
 		break;
 	case 3:
-		m = OMAP3430_L2FLATMEMONSTATE_MASK;
+		m = OMAP_MEM3_ONSTATE_MASK;
+		break;
+	case 4:
+		m = OMAP_MEM4_ONSTATE_MASK;
 		break;
 	default:
 		WARN_ON(1); /* should never happen */
@@ -856,7 +592,7 @@ int pwrdm_set_mem_onst(struct powerdomai
 	}
 
 	prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)),
-			     pwrdm->prcm_offs, PM_PWSTCTRL);
+			     pwrdm->prcm_offs, pwrstctrl_reg_offs);
 
 	return 0;
 }
@@ -867,14 +603,15 @@ int pwrdm_set_mem_onst(struct powerdomai
  * @bank: memory bank number to set (0-3)
  * @pwrst: one of the PWRDM_POWER_* macros
  *
- * Set the next power state that memory bank x of the powerdomain
- * pwrdm will enter when the powerdomain enters the RETENTION state.
- * Bank will be a number from 0 to 3, and represents different types
- * of memory, depending on the powerdomain.  pwrst will be either
- * RETENTION or OFF, if supported. Returns -EINVAL if the powerdomain
- * pointer is null or the target power state is not not supported for
- * this memory bank, -EEXIST if the target memory bank does not exist
- * or is not controllable, or returns 0 upon success.
+ * Set the next power state @pwrst that memory bank @bank of the
+ * powerdomain @pwrdm will enter when the powerdomain enters the
+ * RETENTION state.  Bank will be a number from 0 to 3, and represents
+ * different types of memory, depending on the powerdomain.  @pwrst
+ * will be either RETENTION or OFF, if supported.  Returns -EINVAL if
+ * the powerdomain pointer is null or the target power state is not
+ * not supported for this memory bank, -EEXIST if the target memory
+ * bank does not exist or is not controllable, or returns 0 upon
+ * success.
  */
 int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
 {
@@ -900,16 +637,19 @@ int pwrdm_set_mem_retst(struct powerdoma
 	 */
 	switch (bank) {
 	case 0:
-		m = OMAP3430_SHAREDL1CACHEFLATRETSTATE;
+		m = OMAP_MEM0_RETSTATE_MASK;
 		break;
 	case 1:
-		m = OMAP3430_L1FLATMEMRETSTATE;
+		m = OMAP_MEM1_RETSTATE_MASK;
 		break;
 	case 2:
-		m = OMAP3430_SHAREDL2CACHEFLATRETSTATE;
+		m = OMAP_MEM2_RETSTATE_MASK;
 		break;
 	case 3:
-		m = OMAP3430_L2FLATMEMRETSTATE;
+		m = OMAP_MEM3_RETSTATE_MASK;
+		break;
+	case 4:
+		m = OMAP_MEM4_RETSTATE_MASK;
 		break;
 	default:
 		WARN_ON(1); /* should never happen */
@@ -917,7 +657,7 @@ int pwrdm_set_mem_retst(struct powerdoma
 	}
 
 	prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
-			     PM_PWSTCTRL);
+			     pwrstctrl_reg_offs);
 
 	return 0;
 }
@@ -926,27 +666,27 @@ int pwrdm_set_mem_retst(struct powerdoma
  * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state
  * @pwrdm: struct powerdomain * to get current logic retention power state
  *
- * Return the current power state that the logic portion of
- * powerdomain pwrdm will enter
- * Returns -EINVAL if the powerdomain pointer is null or returns the
- * current logic retention power state upon success.
+ * Return the power state that the logic portion of powerdomain @pwrdm
+ * will enter when the powerdomain enters retention.  Returns -EINVAL
+ * if the powerdomain pointer is null or returns the logic retention
+ * power state upon success.
  */
 int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
 {
 	if (!pwrdm)
 		return -EINVAL;
 
-	return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST,
-					OMAP3430_LOGICSTATEST);
+	return prm_read_mod_bits_shift(pwrdm->prcm_offs,
+				 pwrstst_reg_offs, OMAP3430_LOGICSTATEST);
 }
 
 /**
  * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state
  * @pwrdm: struct powerdomain * to get previous logic power state
  *
- * Return the powerdomain pwrdm's logic power state.  Returns -EINVAL
- * if the powerdomain pointer is null or returns the previous logic
- * power state upon success.
+ * Return the powerdomain @pwrdm's previous logic power state.  Returns
+ * -EINVAL if the powerdomain pointer is null or returns the previous
+ * logic power state upon success.
  */
 int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
 {
@@ -964,12 +704,35 @@ int pwrdm_read_prev_logic_pwrst(struct p
 }
 
 /**
+ * pwrdm_read_logic_retst - get next powerdomain logic power state
+ * @pwrdm: struct powerdomain * to get next logic power state
+ *
+ * Return the powerdomain pwrdm's logic power state.  Returns -EINVAL
+ * if the powerdomain pointer is null or returns the next logic
+ * power state upon success.
+ */
+int pwrdm_read_logic_retst(struct powerdomain *pwrdm)
+{
+	if (!pwrdm)
+		return -EINVAL;
+
+	/*
+	 * The register bit names below may not correspond to the
+	 * actual names of the bits in each powerdomain's register,
+	 * but the type of value returned is the same for each
+	 * powerdomain.
+	 */
+	return prm_read_mod_bits_shift(pwrdm->prcm_offs, pwrstctrl_reg_offs,
+					OMAP3430_LOGICSTATEST);
+}
+
+/**
  * pwrdm_read_mem_pwrst - get current memory bank power state
  * @pwrdm: struct powerdomain * to get current memory bank power state
  * @bank: memory bank number (0-3)
  *
- * Return the powerdomain pwrdm's current memory power state for bank
- * x.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
+ * Return the powerdomain @pwrdm's current memory power state for bank
+ * @bank.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
  * the target memory bank does not exist or is not controllable, or
  * returns the current memory power state upon success.
  */
@@ -994,23 +757,27 @@ int pwrdm_read_mem_pwrst(struct powerdom
 	 */
 	switch (bank) {
 	case 0:
-		m = OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK;
+		m = OMAP_MEM0_STATEST_MASK;
 		break;
 	case 1:
-		m = OMAP3430_L1FLATMEMSTATEST_MASK;
+		m = OMAP_MEM1_STATEST_MASK;
 		break;
 	case 2:
-		m = OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK;
+		m = OMAP_MEM2_STATEST_MASK;
 		break;
 	case 3:
-		m = OMAP3430_L2FLATMEMSTATEST_MASK;
+		m = OMAP_MEM3_STATEST_MASK;
+		break;
+	case 4:
+		m = OMAP_MEM4_STATEST_MASK;
 		break;
 	default:
 		WARN_ON(1); /* should never happen */
 		return -EEXIST;
 	}
 
-	return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, m);
+	return prm_read_mod_bits_shift(pwrdm->prcm_offs,
+					 pwrstst_reg_offs, m);
 }
 
 /**
@@ -1018,10 +785,11 @@ int pwrdm_read_mem_pwrst(struct powerdom
  * @pwrdm: struct powerdomain * to get previous memory bank power state
  * @bank: memory bank number (0-3)
  *
- * Return the powerdomain pwrdm's previous memory power state for bank
- * x.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
- * the target memory bank does not exist or is not controllable, or
- * returns the previous memory power state upon success.
+ * Return the powerdomain @pwrdm's previous memory power state for
+ * bank @bank.  Returns -EINVAL if the powerdomain pointer is null,
+ * -EEXIST if the target memory bank does not exist or is not
+ * controllable, or returns the previous memory power state upon
+ * success.
  */
 int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
 {
@@ -1065,13 +833,63 @@ int pwrdm_read_prev_mem_pwrst(struct pow
 }
 
 /**
+ * pwrdm_read_mem_retst - get next memory bank power state
+ * @pwrdm: struct powerdomain * to get mext memory bank power state
+ * @bank: memory bank number (0-3)
+ *
+ * Return the powerdomain pwrdm's next memory power state for bank
+ * x.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
+ * the target memory bank does not exist or is not controllable, or
+ * returns the next memory power state upon success.
+ */
+int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
+{
+	u32 m;
+
+	if (!pwrdm)
+		return -EINVAL;
+
+	if (pwrdm->banks < (bank + 1))
+		return -EEXIST;
+
+	/*
+	 * The register bit names below may not correspond to the
+	 * actual names of the bits in each powerdomain's register,
+	 * but the type of value returned is the same for each
+	 * powerdomain.
+	 */
+	switch (bank) {
+	case 0:
+		m = OMAP_MEM0_RETSTATE_MASK;
+		break;
+	case 1:
+		m = OMAP_MEM1_RETSTATE_MASK;
+		break;
+	case 2:
+		m = OMAP_MEM2_RETSTATE_MASK;
+		break;
+	case 3:
+		m = OMAP_MEM3_RETSTATE_MASK;
+		break;
+	case 4:
+		m = OMAP_MEM4_RETSTATE_MASK;
+	default:
+		WARN_ON(1); /* should never happen */
+		return -EEXIST;
+	}
+
+	return prm_read_mod_bits_shift(pwrdm->prcm_offs,
+					pwrstctrl_reg_offs, m);
+}
+
+/**
  * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
  * @pwrdm: struct powerdomain * to clear
  *
- * Clear the powerdomain's previous power state register.  Clears the
- * entire register, including logic and memory bank previous power states.
- * Returns -EINVAL if the powerdomain pointer is null, or returns 0 upon
- * success.
+ * Clear the powerdomain's previous power state register @pwrdm.
+ * Clears the entire register, including logic and memory bank
+ * previous power states.  Returns -EINVAL if the powerdomain pointer
+ * is null, or returns 0 upon success.
  */
 int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
 {
@@ -1096,11 +914,11 @@ int pwrdm_clear_all_prev_pwrst(struct po
  * @pwrdm: struct powerdomain *
  *
  * Enable automatic context save-and-restore upon power state change
- * for some devices in a powerdomain.  Warning: this only affects a
- * subset of devices in a powerdomain; check the TRM closely.  Returns
- * -EINVAL if the powerdomain pointer is null or if the powerdomain
- * does not support automatic save-and-restore, or returns 0 upon
- * success.
+ * for some devices in the powerdomain @pwrdm.  Warning: this only
+ * affects a subset of devices in a powerdomain; check the TRM
+ * closely.  Returns -EINVAL if the powerdomain pointer is null or if
+ * the powerdomain does not support automatic save-and-restore, or
+ * returns 0 upon success.
  */
 int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
 {
@@ -1114,7 +932,7 @@ int pwrdm_enable_hdwr_sar(struct powerdo
 		 pwrdm->name);
 
 	prm_rmw_mod_reg_bits(0, 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
-			     pwrdm->prcm_offs, PM_PWSTCTRL);
+			     pwrdm->prcm_offs, pwrstctrl_reg_offs);
 
 	return 0;
 }
@@ -1124,11 +942,11 @@ int pwrdm_enable_hdwr_sar(struct powerdo
  * @pwrdm: struct powerdomain *
  *
  * Disable automatic context save-and-restore upon power state change
- * for some devices in a powerdomain.  Warning: this only affects a
- * subset of devices in a powerdomain; check the TRM closely.  Returns
- * -EINVAL if the powerdomain pointer is null or if the powerdomain
- * does not support automatic save-and-restore, or returns 0 upon
- * success.
+ * for some devices in the powerdomain @pwrdm.  Warning: this only
+ * affects a subset of devices in a powerdomain; check the TRM
+ * closely.  Returns -EINVAL if the powerdomain pointer is null or if
+ * the powerdomain does not support automatic save-and-restore, or
+ * returns 0 upon success.
  */
 int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
 {
@@ -1142,7 +960,7 @@ int pwrdm_disable_hdwr_sar(struct powerd
 		 pwrdm->name);
 
 	prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 0,
-			     pwrdm->prcm_offs, PM_PWSTCTRL);
+			     pwrdm->prcm_offs, pwrstctrl_reg_offs);
 
 	return 0;
 }
@@ -1151,7 +969,7 @@ int pwrdm_disable_hdwr_sar(struct powerd
  * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR
  * @pwrdm: struct powerdomain *
  *
- * Returns 1 if powerdomain 'pwrdm' supports hardware save-and-restore
+ * Returns 1 if powerdomain @pwrdm supports hardware save-and-restore
  * for some devices, or 0 if it does not.
  */
 bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
@@ -1163,7 +981,7 @@ bool pwrdm_has_hdwr_sar(struct powerdoma
  * pwrdm_wait_transition - wait for powerdomain power transition to finish
  * @pwrdm: struct powerdomain * to wait for
  *
- * If the powerdomain pwrdm is in the process of a state transition,
+ * If the powerdomain @pwrdm is in the process of a state transition,
  * spin until it completes the power transition, or until an iteration
  * bailout value is reached. Returns -EINVAL if the powerdomain
  * pointer is null, -EAGAIN if the bailout value was reached, or
@@ -1183,10 +1001,10 @@ int pwrdm_wait_transition(struct powerdo
 	 */
 
 	/* XXX Is this udelay() value meaningful? */
-	while ((prm_read_mod_reg(pwrdm->prcm_offs, PM_PWSTST) &
+	while ((prm_read_mod_reg(pwrdm->prcm_offs, pwrstst_reg_offs) &
 		OMAP_INTRANSITION) &&
 	       (c++ < PWRDM_TRANSITION_BAILOUT))
-		udelay(1);
+			udelay(1);
 
 	if (c > PWRDM_TRANSITION_BAILOUT) {
 		printk(KERN_ERR "powerdomain: waited too long for "
@@ -1213,12 +1031,6 @@ int pwrdm_clkdm_state_switch(struct cloc
 
 	return -EINVAL;
 }
-int pwrdm_clk_state_switch(struct clk *clk)
-{
-	if (clk != NULL && clk->clkdm != NULL)
-		return pwrdm_clkdm_state_switch(clk->clkdm);
-	return -EINVAL;
-}
 
 int pwrdm_pre_transition(void)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomains24xx.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/powerdomains24xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomains24xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/powerdomains24xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  * OMAP24XX powerdomain definitions
  *
  * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2008 Nokia Corporation
+ * Copyright (C) 2007-2009 Nokia Corporation
  *
  * Written by Paul Walmsley
  * Debugging and integration fixes by Jouni HÃ¶gander
@@ -30,83 +30,7 @@
 
 /* 24XX powerdomains and dependencies */
 
-#ifdef CONFIG_ARCH_OMAP24XX
-
-
-/* Wakeup dependency source arrays */
-
-/*
- * 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP
- * 2430 PM_WKDEP_MDM: same as above
- */
-static struct pwrdm_dep dsp_mdm_24xx_wkdeps[] = {
-	{
-		.pwrdm_name = "core_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
-	},
-	{
-		.pwrdm_name = "mpu_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
-	},
-	{
-		.pwrdm_name = "wkup_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
-	},
-	{ NULL },
-};
-
-/*
- * 2420 PM_WKDEP_MPU: CORE, DSP, WKUP
- * 2430 adds MDM
- */
-static struct pwrdm_dep mpu_24xx_wkdeps[] = {
-	{
-		.pwrdm_name = "core_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
-	},
-	{
-		.pwrdm_name = "dsp_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
-	},
-	{
-		.pwrdm_name = "wkup_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
-	},
-	{
-		.pwrdm_name = "mdm_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
-	},
-	{ NULL },
-};
-
-/*
- * 2420 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP
- * 2430 adds MDM
- */
-static struct pwrdm_dep core_24xx_wkdeps[] = {
-	{
-		.pwrdm_name = "dsp_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
-	},
-	{
-		.pwrdm_name = "gfx_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
-	},
-	{
-		.pwrdm_name = "mpu_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
-	},
-	{
-		.pwrdm_name = "wkup_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
-	},
-	{
-		.pwrdm_name = "mdm_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
-	},
-	{ NULL },
-};
-
+#ifdef CONFIG_ARCH_OMAP2
 
 /* Powerdomains */
 
@@ -114,8 +38,6 @@ static struct powerdomain dsp_pwrdm = {
 	.name		  = "dsp_pwrdm",
 	.prcm_offs	  = OMAP24XX_DSP_MOD,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
-	.dep_bit	  = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
-	.wkdep_srcs	  = dsp_mdm_24xx_wkdeps,
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
 	.pwrsts_logic_ret = PWRDM_POWER_RET,
 	.banks		  = 1,
@@ -131,8 +53,6 @@ static struct powerdomain mpu_24xx_pwrdm
 	.name		  = "mpu_pwrdm",
 	.prcm_offs	  = MPU_MOD,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
-	.dep_bit	  = OMAP24XX_EN_MPU_SHIFT,
-	.wkdep_srcs	  = mpu_24xx_wkdeps,
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.banks		  = 1,
@@ -148,9 +68,7 @@ static struct powerdomain core_24xx_pwrd
 	.name		  = "core_pwrdm",
 	.prcm_offs	  = CORE_MOD,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
-	.wkdep_srcs	  = core_24xx_wkdeps,
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
-	.dep_bit	  = OMAP24XX_EN_CORE_SHIFT,
 	.banks		  = 3,
 	.pwrsts_mem_ret	  = {
 		[0] = PWRSTS_OFF_RET,	 /* MEM1RETSTATE */
@@ -164,7 +82,7 @@ static struct powerdomain core_24xx_pwrd
 	},
 };
 
-#endif	   /* CONFIG_ARCH_OMAP24XX */
+#endif	   /* CONFIG_ARCH_OMAP2 */
 
 
 
@@ -176,13 +94,10 @@ static struct powerdomain core_24xx_pwrd
 
 /* XXX 2430 KILLDOMAINWKUP bit?  No current users apparently */
 
-/* Another case of bit name collisions between several registers: EN_MDM */
 static struct powerdomain mdm_pwrdm = {
 	.name		  = "mdm_pwrdm",
 	.prcm_offs	  = OMAP2430_MDM_MOD,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
-	.dep_bit	  = OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT,
-	.wkdep_srcs	  = dsp_mdm_24xx_wkdeps,
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
 	.pwrsts_logic_ret = PWRDM_POWER_RET,
 	.banks		  = 1,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomains34xx.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/powerdomains34xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomains34xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/powerdomains34xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,8 +1,8 @@
 /*
- * OMAP34XX powerdomain definitions
+ * OMAP3 powerdomain definitions
  *
  * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2008 Nokia Corporation
+ * Copyright (C) 2007-2010 Nokia Corporation
  *
  * Written by Paul Walmsley
  * Debugging and integration fixes by Jouni HÃ¶gander
@@ -32,128 +32,7 @@
  * 34XX-specific powerdomains, dependencies
  */
 
-#ifdef CONFIG_ARCH_OMAP34XX
-
-/*
- * 3430: PM_WKDEP_{PER,USBHOST}: CORE, IVA2, MPU, WKUP
- * (USBHOST is ES2 only)
- */
-static struct pwrdm_dep per_usbhost_wkdeps[] = {
-	{
-		.pwrdm_name = "core_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{
-		.pwrdm_name = "iva2_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{
-		.pwrdm_name = "mpu_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{
-		.pwrdm_name = "wkup_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{ NULL },
-};
-
-/*
- * 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER
- */
-static struct pwrdm_dep mpu_34xx_wkdeps[] = {
-	{
-		.pwrdm_name = "core_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{
-		.pwrdm_name = "iva2_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{
-		.pwrdm_name = "dss_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{
-		.pwrdm_name = "per_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{ NULL },
-};
-
-/*
- * 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER
- */
-static struct pwrdm_dep iva2_wkdeps[] = {
-	{
-		.pwrdm_name = "core_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{
-		.pwrdm_name = "mpu_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{
-		.pwrdm_name = "wkup_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{
-		.pwrdm_name = "dss_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{
-		.pwrdm_name = "per_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{ NULL },
-};
-
-
-/* 3430 PM_WKDEP_{CAM,DSS}: IVA2, MPU, WKUP */
-static struct pwrdm_dep cam_dss_wkdeps[] = {
-	{
-		.pwrdm_name = "iva2_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{
-		.pwrdm_name = "mpu_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{
-		.pwrdm_name = "wkup_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{ NULL },
-};
-
-/* 3430: PM_WKDEP_NEON: MPU */
-static struct pwrdm_dep neon_wkdeps[] = {
-	{
-		.pwrdm_name = "mpu_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{ NULL },
-};
-
-
-/* Sleep dependency source arrays for 34xx-specific pwrdms - 34XX only */
-
-/*
- * 3430: CM_SLEEPDEP_{DSS,PER}: MPU, IVA
- * 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA
- */
-static struct pwrdm_dep dss_per_usbhost_sleepdeps[] = {
-	{
-		.pwrdm_name = "mpu_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{
-		.pwrdm_name = "iva2_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{ NULL },
-};
-
+#ifdef CONFIG_ARCH_OMAP3
 
 /*
  * Powerdomains
@@ -163,8 +42,6 @@ static struct powerdomain iva2_pwrdm = {
 	.name		  = "iva2_pwrdm",
 	.prcm_offs	  = OMAP3430_IVA2_MOD,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-	.dep_bit	  = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
-	.wkdep_srcs	  = iva2_wkdeps,
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.banks		  = 4,
@@ -182,12 +59,10 @@ static struct powerdomain iva2_pwrdm = {
 	},
 };
 
-static struct powerdomain mpu_34xx_pwrdm = {
+static struct powerdomain mpu_3xxx_pwrdm = {
 	.name		  = "mpu_pwrdm",
 	.prcm_offs	  = MPU_MOD,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-	.dep_bit	  = OMAP3430_EN_MPU_SHIFT,
-	.wkdep_srcs	  = mpu_34xx_wkdeps,
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.flags		  = PWRDM_HAS_MPU_QUIRK,
@@ -200,15 +75,14 @@ static struct powerdomain mpu_34xx_pwrdm
 	},
 };
 
-/* No wkdeps or sleepdeps for 34xx core apparently */
-static struct powerdomain core_34xx_pre_es3_1_pwrdm = {
+static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
 	.name		  = "core_pwrdm",
 	.prcm_offs	  = CORE_MOD,
 	.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,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.banks		  = 2,
 	.pwrsts_mem_ret	  = {
 		[0] = PWRSTS_OFF_RET,	 /* MEM1RETSTATE */
@@ -220,13 +94,12 @@ static struct powerdomain core_34xx_pre_
 	},
 };
 
-/* No wkdeps or sleepdeps for 34xx core apparently */
-static struct powerdomain core_34xx_es3_1_pwrdm = {
+static struct powerdomain core_3xxx_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,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.flags		  = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
 	.banks		  = 2,
 	.pwrsts_mem_ret	  = {
@@ -239,14 +112,10 @@ static struct powerdomain core_34xx_es3_
 	},
 };
 
-/* Another case of bit name collisions between several registers: EN_DSS */
 static struct powerdomain dss_pwrdm = {
 	.name		  = "dss_pwrdm",
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 	.prcm_offs	  = OMAP3430_DSS_MOD,
-	.dep_bit	  = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
-	.wkdep_srcs	  = cam_dss_wkdeps,
-	.sleepdep_srcs	  = dss_per_usbhost_sleepdeps,
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
 	.pwrsts_logic_ret = PWRDM_POWER_RET,
 	.banks		  = 1,
@@ -267,8 +136,6 @@ static struct powerdomain sgx_pwrdm = {
 	.name		  = "sgx_pwrdm",
 	.prcm_offs	  = OMAP3430ES2_SGX_MOD,
 	.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_ON,
 	.pwrsts_logic_ret = PWRDM_POWER_RET,
@@ -285,8 +152,6 @@ static struct powerdomain cam_pwrdm = {
 	.name		  = "cam_pwrdm",
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 	.prcm_offs	  = OMAP3430_CAM_MOD,
-	.wkdep_srcs	  = cam_dss_wkdeps,
-	.sleepdep_srcs	  = cam_gfx_sleepdeps,
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
 	.pwrsts_logic_ret = PWRDM_POWER_RET,
 	.banks		  = 1,
@@ -302,9 +167,6 @@ static struct powerdomain per_pwrdm = {
 	.name		  = "per_pwrdm",
 	.prcm_offs	  = OMAP3430_PER_MOD,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-	.dep_bit	  = OMAP3430_EN_PER_SHIFT,
-	.wkdep_srcs	  = per_usbhost_wkdeps,
-	.sleepdep_srcs	  = dss_per_usbhost_sleepdeps,
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.banks		  = 1,
@@ -326,7 +188,6 @@ static struct powerdomain neon_pwrdm = {
 	.name		  = "neon_pwrdm",
 	.prcm_offs	  = OMAP3430_NEON_MOD,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-	.wkdep_srcs	  = neon_wkdeps,
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
 	.pwrsts_logic_ret = PWRDM_POWER_RET,
 };
@@ -335,8 +196,6 @@ static struct powerdomain usbhost_pwrdm
 	.name		  = "usbhost_pwrdm",
 	.prcm_offs	  = OMAP3430ES2_USBHOST_MOD,
 	.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,
 	/*
@@ -386,7 +245,7 @@ static struct powerdomain dpll5_pwrdm =
 };
 
 
-#endif    /* CONFIG_ARCH_OMAP34XX */
+#endif    /* CONFIG_ARCH_OMAP3 */
 
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomains44xx.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/powerdomains44xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomains44xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/powerdomains44xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,310 @@
+/*
+ * OMAP4 Power domains framework
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Abhijit Pagare (abhijitpagare@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ * Paul Walmsley
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_POWERDOMAINS44XX_H
+#define __ARCH_ARM_MACH_OMAP2_POWERDOMAINS44XX_H
+
+#include <plat/powerdomain.h>
+
+#include "prcm-common.h"
+#include "cm.h"
+#include "cm-regbits-44xx.h"
+#include "prm.h"
+#include "prm-regbits-44xx.h"
+
+#if defined(CONFIG_ARCH_OMAP4)
+
+/* core_44xx_pwrdm: CORE power domain */
+static struct powerdomain core_44xx_pwrdm = {
+	.name		  = "core_pwrdm",
+	.prcm_offs	  = OMAP4430_PRM_CORE_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRSTS_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
+	.banks		  = 5,
+	.pwrsts_mem_ret	= {
+		[0] = PWRDM_POWER_OFF,	/* core_nret_bank */
+		[1] = PWRSTS_OFF_RET,	/* core_ocmram */
+		[2] = PWRDM_POWER_RET,	/* core_other_bank */
+		[3] = PWRSTS_OFF_RET,	/* ducati_l2ram */
+		[4] = PWRSTS_OFF_RET,	/* ducati_unicache */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRDM_POWER_ON,	/* core_nret_bank */
+		[1] = PWRSTS_OFF_RET,	/* core_ocmram */
+		[2] = PWRDM_POWER_ON,	/* core_other_bank */
+		[3] = PWRDM_POWER_ON,	/* ducati_l2ram */
+		[4] = PWRDM_POWER_ON,	/* ducati_unicache */
+	},
+};
+
+/* gfx_44xx_pwrdm: 3D accelerator power domain */
+static struct powerdomain gfx_44xx_pwrdm = {
+	.name		  = "gfx_pwrdm",
+	.prcm_offs	  = OMAP4430_PRM_GFX_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRSTS_OFF_ON,
+	.banks		  = 1,
+	.pwrsts_mem_ret	= {
+		[0] = PWRDM_POWER_OFF,	/* gfx_mem */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRDM_POWER_ON,	/* gfx_mem */
+	},
+};
+
+/* abe_44xx_pwrdm: Audio back end power domain */
+static struct powerdomain abe_44xx_pwrdm = {
+	.name		  = "abe_pwrdm",
+	.prcm_offs	  = OMAP4430_PRM_ABE_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts_logic_ret = PWRDM_POWER_OFF,
+	.banks		  = 2,
+	.pwrsts_mem_ret	= {
+		[0] = PWRDM_POWER_RET,	/* aessmem */
+		[1] = PWRDM_POWER_OFF,	/* periphmem */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRDM_POWER_ON,	/* aessmem */
+		[1] = PWRDM_POWER_ON,	/* periphmem */
+	},
+};
+
+/* dss_44xx_pwrdm: Display subsystem power domain */
+static struct powerdomain dss_44xx_pwrdm = {
+	.name		  = "dss_pwrdm",
+	.prcm_offs	  = OMAP4430_PRM_DSS_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
+	.banks		  = 1,
+	.pwrsts_mem_ret	= {
+		[0] = PWRDM_POWER_OFF,	/* dss_mem */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRDM_POWER_ON,	/* dss_mem */
+	},
+};
+
+/* tesla_44xx_pwrdm: Tesla processor power domain */
+static struct powerdomain tesla_44xx_pwrdm = {
+	.name		  = "tesla_pwrdm",
+	.prcm_offs	  = OMAP4430_PRM_TESLA_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
+	.banks		  = 3,
+	.pwrsts_mem_ret	= {
+		[0] = PWRDM_POWER_RET,	/* tesla_edma */
+		[1] = PWRSTS_OFF_RET,	/* tesla_l1 */
+		[2] = PWRSTS_OFF_RET,	/* tesla_l2 */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRDM_POWER_ON,	/* tesla_edma */
+		[1] = PWRDM_POWER_ON,	/* tesla_l1 */
+		[2] = PWRDM_POWER_ON,	/* tesla_l2 */
+	},
+};
+
+/* wkup_44xx_pwrdm: Wake-up power domain */
+static struct powerdomain wkup_44xx_pwrdm = {
+	.name		  = "wkup_pwrdm",
+	.prcm_offs	  = OMAP4430_PRM_WKUP_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRDM_POWER_ON,
+	.banks		  = 1,
+	.pwrsts_mem_ret	= {
+		[0] = PWRDM_POWER_OFF,	/* wkup_bank */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRDM_POWER_ON,	/* wkup_bank */
+	},
+};
+
+/* cpu0_44xx_pwrdm: MPU0 processor and Neon coprocessor power domain */
+static struct powerdomain cpu0_44xx_pwrdm = {
+	.name		  = "cpu0_pwrdm",
+	.prcm_offs	  = OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
+	.banks		  = 1,
+	.pwrsts_mem_ret	= {
+		[0] = PWRSTS_OFF_RET,	/* cpu0_l1 */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRDM_POWER_ON,	/* cpu0_l1 */
+	},
+};
+
+/* cpu1_44xx_pwrdm: MPU1 processor and Neon coprocessor power domain */
+static struct powerdomain cpu1_44xx_pwrdm = {
+	.name		  = "cpu1_pwrdm",
+	.prcm_offs	  = OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
+	.banks		  = 1,
+	.pwrsts_mem_ret	= {
+		[0] = PWRSTS_OFF_RET,	/* cpu1_l1 */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRDM_POWER_ON,	/* cpu1_l1 */
+	},
+};
+
+/* emu_44xx_pwrdm: Emulation power domain */
+static struct powerdomain emu_44xx_pwrdm = {
+	.name		  = "emu_pwrdm",
+	.prcm_offs	  = OMAP4430_PRM_EMU_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRSTS_OFF_ON,
+	.banks		  = 1,
+	.pwrsts_mem_ret	= {
+		[0] = PWRDM_POWER_OFF,	/* emu_bank */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRDM_POWER_ON,	/* emu_bank */
+	},
+};
+
+/* mpu_44xx_pwrdm: Modena processor and the Neon coprocessor power domain */
+static struct powerdomain mpu_44xx_pwrdm = {
+	.name		  = "mpu_pwrdm",
+	.prcm_offs	  = OMAP4430_PRM_MPU_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
+	.banks		  = 3,
+	.pwrsts_mem_ret	= {
+		[0] = PWRSTS_OFF_RET,	/* mpu_l1 */
+		[1] = PWRSTS_OFF_RET,	/* mpu_l2 */
+		[2] = PWRDM_POWER_RET,	/* mpu_ram */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRDM_POWER_ON,	/* mpu_l1 */
+		[1] = PWRDM_POWER_ON,	/* mpu_l2 */
+		[2] = PWRDM_POWER_ON,	/* mpu_ram */
+	},
+};
+
+/* ivahd_44xx_pwrdm: IVA-HD power domain */
+static struct powerdomain ivahd_44xx_pwrdm = {
+	.name		  = "ivahd_pwrdm",
+	.prcm_offs	  = OMAP4430_PRM_IVAHD_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts_logic_ret = PWRDM_POWER_OFF,
+	.banks		  = 4,
+	.pwrsts_mem_ret	= {
+		[0] = PWRDM_POWER_OFF,	/* hwa_mem */
+		[1] = PWRSTS_OFF_RET,	/* sl2_mem */
+		[2] = PWRSTS_OFF_RET,	/* tcm1_mem */
+		[3] = PWRSTS_OFF_RET,	/* tcm2_mem */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRDM_POWER_ON,	/* hwa_mem */
+		[1] = PWRDM_POWER_ON,	/* sl2_mem */
+		[2] = PWRDM_POWER_ON,	/* tcm1_mem */
+		[3] = PWRDM_POWER_ON,	/* tcm2_mem */
+	},
+};
+
+/* cam_44xx_pwrdm: Camera subsystem power domain */
+static struct powerdomain cam_44xx_pwrdm = {
+	.name		  = "cam_pwrdm",
+	.prcm_offs	  = OMAP4430_PRM_CAM_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRSTS_OFF_ON,
+	.banks		  = 1,
+	.pwrsts_mem_ret	= {
+		[0] = PWRDM_POWER_OFF,	/* cam_mem */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRDM_POWER_ON,	/* cam_mem */
+	},
+};
+
+/* l3init_44xx_pwrdm: L3 initators pheripherals power domain  */
+static struct powerdomain l3init_44xx_pwrdm = {
+	.name		  = "l3init_pwrdm",
+	.prcm_offs	  = OMAP4430_PRM_L3INIT_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
+	.banks		  = 1,
+	.pwrsts_mem_ret	= {
+		[0] = PWRDM_POWER_OFF,	/* l3init_bank1 */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRDM_POWER_ON,	/* l3init_bank1 */
+	},
+};
+
+/* l4per_44xx_pwrdm: Target peripherals power domain */
+static struct powerdomain l4per_44xx_pwrdm = {
+	.name		  = "l4per_pwrdm",
+	.prcm_offs	  = OMAP4430_PRM_L4PER_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
+	.banks		  = 2,
+	.pwrsts_mem_ret	= {
+		[0] = PWRDM_POWER_OFF,	/* nonretained_bank */
+		[1] = PWRDM_POWER_RET,	/* retained_bank */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRDM_POWER_ON,	/* nonretained_bank */
+		[1] = PWRDM_POWER_ON,	/* retained_bank */
+	},
+};
+
+/*
+ * always_on_core_44xx_pwrdm: Always ON logic that sits in VDD_CORE voltage
+ * domain
+ */
+static struct powerdomain always_on_core_44xx_pwrdm = {
+	.name		  = "always_on_core_pwrdm",
+	.prcm_offs	  = OMAP4430_PRM_ALWAYS_ON_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRDM_POWER_ON,
+};
+
+/* cefuse_44xx_pwrdm: Customer efuse controller power domain */
+static struct powerdomain cefuse_44xx_pwrdm = {
+	.name		  = "cefuse_pwrdm",
+	.prcm_offs	  = OMAP4430_PRM_CEFUSE_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.pwrsts		  = PWRSTS_OFF_ON,
+};
+
+/*
+ * The following power domains are not under SW control
+ *
+ * always_on_iva
+ * always_on_mpu
+ * stdefuse
+ */
+
+#endif
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomains.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/powerdomains.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomains.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/powerdomains.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,8 +1,8 @@
 /*
  * OMAP2/3 common powerdomain definitions
  *
- * Copyright (C) 2007-8 Texas Instruments, Inc.
- * Copyright (C) 2007-8 Nokia Corporation
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009 Nokia Corporation
  *
  * Written by Paul Walmsley
  * Debugging and integration fixes by Jouni HÃ¶gander
@@ -12,26 +12,21 @@
  * published by the Free Software Foundation.
  */
 
+/*
+ * To Do List
+ * -> Move the Sleep/Wakeup dependencies from Power Domain framework to
+ *    Clock Domain Framework
+ */
+
 #ifndef ARCH_ARM_MACH_OMAP2_POWERDOMAINS
 #define ARCH_ARM_MACH_OMAP2_POWERDOMAINS
 
 /*
  * This file contains all of the powerdomains that have some element
- * of software control for the OMAP24xx and OMAP34XX chips.
- *
- * A few notes:
+ * of software control for the OMAP24xx and OMAP34xx chips.
  *
  * This is not an exhaustive listing of powerdomains on the chips; only
  * powerdomains that can be controlled in software.
- *
- * A useful validation rule for struct powerdomain:
- * Any powerdomain referenced by a wkdep_srcs or sleepdep_srcs array
- * must have a dep_bit assigned.  So wkdep_srcs/sleepdep_srcs are really
- * just software-controllable dependencies.  Non-software-controllable
- * dependencies do exist, but they are not encoded below (yet).
- *
- * 24xx does not support programmable sleep dependencies (SLEEPDEP)
- *
  */
 
 /*
@@ -41,26 +36,17 @@
  *
  * On the 2420, this is a 'C55 DSP called, simply, the DSP.  Its
  * powerdomain is called the "DSP power domain."  On the 2430, the
- * on-board DSP is a 'C64 DSP, now called the IVA2 or IVA2.1.  Its
- * powerdomain is still called the "DSP power domain."	On the 3430,
- * the DSP is a 'C64 DSP like the 2430, also known as the IVA2; but
- * its powerdomain is now called the "IVA2 power domain."
+ * on-board DSP is a 'C64 DSP, now called (along with its hardware
+ * accelerators) the IVA2 or IVA2.1.  Its powerdomain is still called
+ * the "DSP power domain." On the 3430, the DSP is a 'C64 DSP like the
+ * 2430, also known as the IVA2; but its powerdomain is now called the
+ * "IVA2 power domain."
  *
  * The 2420 also has something called the IVA, which is a separate ARM
  * core, and has nothing to do with the DSP/IVA2.
  *
  * Ideally the DSP/IVA2 could just be the same powerdomain, but the PRCM
  * address offset is different between the C55 and C64 DSPs.
- *
- * The overly-specific dep_bit names are due to a bit name collision
- * with CM_FCLKEN_{DSP,IVA2}.  The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift
- * value are the same for all powerdomains: 2
- */
-
-/*
- * XXX should dep_bit be a mask, so we can test to see if it is 0 as a
- * sanity check?
- * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
  */
 
 #include <plat/powerdomain.h>
@@ -68,69 +54,23 @@
 #include "prcm-common.h"
 #include "prm.h"
 #include "cm.h"
-
-/* OMAP2/3-common powerdomains and wakeup dependencies */
-
-/*
- * 2420/2430 PM_WKDEP_GFX: CORE, MPU, WKUP
- * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
- * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
- */
-static struct pwrdm_dep gfx_sgx_wkdeps[] = {
-	{
-		.pwrdm_name = "core_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
-	},
-	{
-		.pwrdm_name = "iva2_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{
-		.pwrdm_name = "mpu_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
-					    CHIP_IS_OMAP3430)
-	},
-	{
-		.pwrdm_name = "wkup_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
-					    CHIP_IS_OMAP3430)
-	},
-	{ NULL },
-};
-
-/*
- * 3430: CM_SLEEPDEP_CAM: MPU
- * 3430ES1: CM_SLEEPDEP_GFX: MPU
- * 3430ES2: CM_SLEEPDEP_SGX: MPU
- */
-static struct pwrdm_dep cam_gfx_sleepdeps[] = {
-	{
-		.pwrdm_name = "mpu_pwrdm",
-		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
-	},
-	{ NULL },
-};
-
-
 #include "powerdomains24xx.h"
 #include "powerdomains34xx.h"
+#include "powerdomains44xx.h"
 
+/* OMAP2/3-common powerdomains */
 
-/*
- * OMAP2/3 common powerdomains
- */
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 
 /*
  * The GFX powerdomain is not present on 3430ES2, but currently we do not
  * have a macro to filter it out at compile-time.
  */
-static struct powerdomain gfx_pwrdm = {
+static struct powerdomain gfx_omap2_pwrdm = {
 	.name		  = "gfx_pwrdm",
 	.prcm_offs	  = GFX_MOD,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
 					   CHIP_IS_OMAP3430ES1),
-	.wkdep_srcs	  = gfx_sgx_wkdeps,
-	.sleepdep_srcs	  = cam_gfx_sleepdeps,
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
 	.pwrsts_logic_ret = PWRDM_POWER_RET,
 	.banks		  = 1,
@@ -142,22 +82,24 @@ static struct powerdomain gfx_pwrdm = {
 	},
 };
 
-static struct powerdomain wkup_pwrdm = {
+static struct powerdomain wkup_omap2_pwrdm = {
 	.name		= "wkup_pwrdm",
 	.prcm_offs	= WKUP_MOD,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
-	.dep_bit	= OMAP_EN_WKUP_SHIFT,
 };
 
+#endif
 
 
 /* As powerdomains are added or removed above, this list must also be changed */
 static struct powerdomain *powerdomains_omap[] __initdata = {
 
-	&gfx_pwrdm,
-	&wkup_pwrdm,
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+	&wkup_omap2_pwrdm,
+	&gfx_omap2_pwrdm,
+#endif
 
-#ifdef CONFIG_ARCH_OMAP24XX
+#ifdef CONFIG_ARCH_OMAP2
 	&dsp_pwrdm,
 	&mpu_24xx_pwrdm,
 	&core_24xx_pwrdm,
@@ -167,12 +109,12 @@ static struct powerdomain *powerdomains_
 	&mdm_pwrdm,
 #endif
 
-#ifdef CONFIG_ARCH_OMAP34XX
+#ifdef CONFIG_ARCH_OMAP3
 	&iva2_pwrdm,
-	&mpu_34xx_pwrdm,
+	&mpu_3xxx_pwrdm,
 	&neon_pwrdm,
-	&core_34xx_pre_es3_1_pwrdm,
-	&core_34xx_es3_1_pwrdm,
+	&core_3xxx_pre_es3_1_pwrdm,
+	&core_3xxx_es3_1_pwrdm,
 	&cam_pwrdm,
 	&dss_pwrdm,
 	&per_pwrdm,
@@ -186,6 +128,24 @@ static struct powerdomain *powerdomains_
 	&dpll5_pwrdm,
 #endif
 
+#ifdef CONFIG_ARCH_OMAP4
+	&core_44xx_pwrdm,
+	&gfx_44xx_pwrdm,
+	&abe_44xx_pwrdm,
+	&dss_44xx_pwrdm,
+	&tesla_44xx_pwrdm,
+	&wkup_44xx_pwrdm,
+	&cpu0_44xx_pwrdm,
+	&cpu1_44xx_pwrdm,
+	&emu_44xx_pwrdm,
+	&mpu_44xx_pwrdm,
+	&ivahd_44xx_pwrdm,
+	&cam_44xx_pwrdm,
+	&l3init_44xx_pwrdm,
+	&l4per_44xx_pwrdm,
+	&always_on_core_44xx_pwrdm,
+	&cefuse_44xx_pwrdm,
+#endif
 	NULL
 };
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prcm.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/prcm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prcm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/prcm.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
  * Rajendra Nayak <rnayak@ti.com>
  *
  * Some pieces of code Copyright (C) 2005 Texas Instruments, Inc.
+ * Upgraded with OMAP4 support by Abhijit Pagare <abhijitpagare@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
@@ -28,6 +29,7 @@
 #include <plat/control.h>
 
 #include "clock.h"
+#include "clock2xxx.h"
 #include "cm.h"
 #include "prm.h"
 #include "prm-regbits-24xx.h"
@@ -121,33 +123,46 @@ struct omap3_prcm_regs prcm_context;
 u32 omap_prcm_get_reset_sources(void)
 {
 	/* XXX This presumably needs modification for 34XX */
-	return prm_read_mod_reg(WKUP_MOD, RM_RSTST) & 0x7f;
+	if (cpu_is_omap24xx() || cpu_is_omap34xx())
+		return prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST) & 0x7f;
+	if (cpu_is_omap44xx())
+		return prm_read_mod_reg(WKUP_MOD, OMAP4_RM_RSTST) & 0x7f;
+
+	return 0;
 }
 EXPORT_SYMBOL(omap_prcm_get_reset_sources);
 
 /* Resets clock rates and reboots the system. Only called from system.h */
-void omap_prcm_arch_reset(char mode)
+void omap_prcm_arch_reset(char mode, const char *cmd)
 {
-	s16 prcm_offs;
-	omap2_clk_prepare_for_reboot();
+	s16 prcm_offs = 0;
+
+	if (cpu_is_omap24xx()) {
+		omap2xxx_clk_prepare_for_reboot();
 
-	if (cpu_is_omap24xx())
 		prcm_offs = WKUP_MOD;
-	else if (cpu_is_omap34xx()) {
+	} else if (cpu_is_omap34xx()) {
 		u32 l;
 
 		prcm_offs = OMAP3430_GR_MOD;
-		l = ('B' << 24) | ('M' << 16) | mode;
+		l = ('B' << 24) | ('M' << 16) | (cmd ? (u8)*cmd : 0);
 		/* Reserve the first word in scratchpad for communicating
 		 * with the boot ROM. A pointer to a data structure
 		 * describing the boot process can be stored there,
 		 * cf. OMAP34xx TRM, Initialization / Software Booting
 		 * Configuration. */
 		omap_writel(l, OMAP343X_SCRATCHPAD + 4);
-	} else
+	} else if (cpu_is_omap44xx())
+		prcm_offs = OMAP4430_PRM_DEVICE_MOD;
+	else
 		WARN_ON(1);
 
-	prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs, RM_RSTCTRL);
+	if (cpu_is_omap24xx() || cpu_is_omap34xx())
+		prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs,
+						 OMAP2_RM_RSTCTRL);
+	if (cpu_is_omap44xx())
+		prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs,
+						 OMAP4_RM_RSTCTRL);
 }
 
 static inline u32 __omap_prcm_read(void __iomem *base, s16 module, u16 reg)
@@ -188,6 +203,18 @@ u32 prm_rmw_mod_reg_bits(u32 mask, u32 b
 	return v;
 }
 
+/* Read a PRM register, AND it, and shift the result down to bit 0 */
+u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
+{
+	u32 v;
+
+	v = prm_read_mod_reg(domain, idx);
+	v &= mask;
+	v >>= __ffs(mask);
+
+	return v;
+}
+
 /* Read a register in a CM module */
 u32 cm_read_mod_reg(s16 module, u16 idx)
 {
@@ -217,26 +244,22 @@ u32 cm_rmw_mod_reg_bits(u32 mask, u32 bi
  * omap2_cm_wait_idlest - wait for IDLEST bit to indicate module readiness
  * @reg: physical address of module IDLEST register
  * @mask: value to mask against to determine if the module is active
+ * @idlest: idle state indicator (0 or 1) for the clock
  * @name: name of the clock (for printk)
  *
  * Returns 1 if the module indicated readiness in time, or 0 if it
  * failed to enable in roughly MAX_MODULE_ENABLE_WAIT microseconds.
  */
-int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name)
+int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest,
+				const char *name)
 {
 	int i = 0;
 	int ena = 0;
 
-	/*
-	 * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
-	 * 34xx reverses this, just to keep us on our toes
-	 */
-	if (cpu_is_omap24xx())
-		ena = mask;
-	else if (cpu_is_omap34xx())
+	if (idlest)
 		ena = 0;
 	else
-		BUG();
+		ena = mask;
 
 	/* Wait for lock */
 	omap_test_timeout(((__raw_readl(reg) & mask) == ena),
@@ -254,9 +277,19 @@ int omap2_cm_wait_idlest(void __iomem *r
 
 void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals)
 {
-	prm_base = omap2_globals->prm;
-	cm_base = omap2_globals->cm;
-	cm2_base = omap2_globals->cm2;
+	/* Static mapping, never released */
+	if (omap2_globals->prm) {
+		prm_base = ioremap(omap2_globals->prm, SZ_8K);
+		WARN_ON(!prm_base);
+	}
+	if (omap2_globals->cm) {
+		cm_base = ioremap(omap2_globals->cm, SZ_8K);
+		WARN_ON(!cm_base);
+	}
+	if (omap2_globals->cm2) {
+		cm2_base = ioremap(omap2_globals->cm2, SZ_8K);
+		WARN_ON(!cm2_base);
+	}
 }
 
 #ifdef CONFIG_ARCH_OMAP3
@@ -280,7 +313,7 @@ void omap3_prcm_save_context(void)
 	prcm_context.emu_cm_clksel =
 			 cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
 	prcm_context.emu_cm_clkstctrl =
-			 cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSTCTRL);
+			 cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL);
 	prcm_context.pll_cm_autoidle2 =
 			 cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
 	prcm_context.pll_cm_clksel4 =
@@ -333,23 +366,25 @@ void omap3_prcm_save_context(void)
 	prcm_context.mpu_cm_autoidle2 =
 			 cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2);
 	prcm_context.iva2_cm_clkstctrl =
-			 cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSTCTRL);
+			 cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
 	prcm_context.mpu_cm_clkstctrl =
-			 cm_read_mod_reg(MPU_MOD, CM_CLKSTCTRL);
+			 cm_read_mod_reg(MPU_MOD, OMAP2_CM_CLKSTCTRL);
 	prcm_context.core_cm_clkstctrl =
-			 cm_read_mod_reg(CORE_MOD, CM_CLKSTCTRL);
+			 cm_read_mod_reg(CORE_MOD, OMAP2_CM_CLKSTCTRL);
 	prcm_context.sgx_cm_clkstctrl =
-			 cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSTCTRL);
+			 cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
+						OMAP2_CM_CLKSTCTRL);
 	prcm_context.dss_cm_clkstctrl =
-			 cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSTCTRL);
+			 cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP2_CM_CLKSTCTRL);
 	prcm_context.cam_cm_clkstctrl =
-			 cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSTCTRL);
+			 cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP2_CM_CLKSTCTRL);
 	prcm_context.per_cm_clkstctrl =
-			 cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSTCTRL);
+			 cm_read_mod_reg(OMAP3430_PER_MOD, OMAP2_CM_CLKSTCTRL);
 	prcm_context.neon_cm_clkstctrl =
-			 cm_read_mod_reg(OMAP3430_NEON_MOD, CM_CLKSTCTRL);
+			 cm_read_mod_reg(OMAP3430_NEON_MOD, OMAP2_CM_CLKSTCTRL);
 	prcm_context.usbhost_cm_clkstctrl =
-			 cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_CLKSTCTRL);
+			 cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
+						OMAP2_CM_CLKSTCTRL);
 	prcm_context.core_cm_autoidle1 =
 			 cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE1);
 	prcm_context.core_cm_autoidle2 =
@@ -432,7 +467,7 @@ void omap3_prcm_restore_context(void)
 	cm_write_mod_reg(prcm_context.emu_cm_clksel, OMAP3430_EMU_MOD,
 					 CM_CLKSEL1);
 	cm_write_mod_reg(prcm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD,
-					 CM_CLKSTCTRL);
+					 OMAP2_CM_CLKSTCTRL);
 	cm_write_mod_reg(prcm_context.pll_cm_autoidle2, PLL_MOD,
 					 CM_AUTOIDLE2);
 	cm_write_mod_reg(prcm_context.pll_cm_clksel4, PLL_MOD,
@@ -478,22 +513,23 @@ void omap3_prcm_restore_context(void)
 					CM_AUTOIDLE2);
 	cm_write_mod_reg(prcm_context.mpu_cm_autoidle2, MPU_MOD, CM_AUTOIDLE2);
 	cm_write_mod_reg(prcm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD,
-					CM_CLKSTCTRL);
-	cm_write_mod_reg(prcm_context.mpu_cm_clkstctrl, MPU_MOD, CM_CLKSTCTRL);
+					OMAP2_CM_CLKSTCTRL);
+	cm_write_mod_reg(prcm_context.mpu_cm_clkstctrl, MPU_MOD,
+					OMAP2_CM_CLKSTCTRL);
 	cm_write_mod_reg(prcm_context.core_cm_clkstctrl, CORE_MOD,
-					CM_CLKSTCTRL);
+					OMAP2_CM_CLKSTCTRL);
 	cm_write_mod_reg(prcm_context.sgx_cm_clkstctrl, OMAP3430ES2_SGX_MOD,
-					CM_CLKSTCTRL);
+					OMAP2_CM_CLKSTCTRL);
 	cm_write_mod_reg(prcm_context.dss_cm_clkstctrl, OMAP3430_DSS_MOD,
-					CM_CLKSTCTRL);
+					OMAP2_CM_CLKSTCTRL);
 	cm_write_mod_reg(prcm_context.cam_cm_clkstctrl, OMAP3430_CAM_MOD,
-					CM_CLKSTCTRL);
+					OMAP2_CM_CLKSTCTRL);
 	cm_write_mod_reg(prcm_context.per_cm_clkstctrl, OMAP3430_PER_MOD,
-					CM_CLKSTCTRL);
+					OMAP2_CM_CLKSTCTRL);
 	cm_write_mod_reg(prcm_context.neon_cm_clkstctrl, OMAP3430_NEON_MOD,
-					CM_CLKSTCTRL);
+					OMAP2_CM_CLKSTCTRL);
 	cm_write_mod_reg(prcm_context.usbhost_cm_clkstctrl,
-					OMAP3430ES2_USBHOST_MOD, CM_CLKSTCTRL);
+				OMAP3430ES2_USBHOST_MOD, OMAP2_CM_CLKSTCTRL);
 	cm_write_mod_reg(prcm_context.core_cm_autoidle1, CORE_MOD,
 					CM_AUTOIDLE1);
 	cm_write_mod_reg(prcm_context.core_cm_autoidle2, CORE_MOD,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prcm-common.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/prcm-common.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prcm-common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/prcm-common.h	2010-05-16 17:17:36.000000000 -0400
@@ -119,6 +119,15 @@
 #define OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD		0x0400
 #define OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD		0x0800
 
+/* Base Addresses for the OMAP4 */
+
+#define OMAP4430_CM1_BASE		0x4a004000
+#define OMAP4430_CM2_BASE		0x4a008000
+#define OMAP4430_PRM_BASE		0x4a306000
+#define OMAP4430_SCRM_BASE		0x4a30a000
+#define OMAP4430_CHIRONSS_BASE		0x48243000
+
+
 /* 24XX register bits shared between CM & PRM registers */
 
 /* CM_FCLKEN1_CORE, CM_ICLKEN1_CORE, PM_WKEN1_CORE shared bits */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prm.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/prm.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/prm.h	2010-05-16 17:17:36.000000000 -0400
@@ -179,9 +179,11 @@
 
 /* Registers appearing on both 24xx and 34xx */
 
-#define RM_RSTCTRL					0x0050
-#define RM_RSTTIME					0x0054
-#define RM_RSTST					0x0058
+#define OMAP2_RM_RSTCTRL				0x0050
+#define OMAP2_RM_RSTTIME				0x0054
+#define OMAP2_RM_RSTST					0x0058
+#define OMAP2_PM_PWSTCTRL				0x00e0
+#define OMAP2_PM_PWSTST					0x00e4
 
 #define PM_WKEN						0x00a0
 #define PM_WKEN1					PM_WKEN
@@ -191,8 +193,6 @@
 #define PM_EVGENCTRL					0x00d4
 #define PM_EVGENONTIM					0x00d8
 #define PM_EVGENOFFTIM					0x00dc
-#define PM_PWSTCTRL					0x00e0
-#define PM_PWSTST					0x00e4
 
 /* Omap2 specific registers */
 #define OMAP24XX_PM_WKEN2				0x00a4
@@ -220,6 +220,13 @@
 #define OMAP3430_PRM_IRQSTATUS_IVA2			0x00f8
 #define OMAP3430_PRM_IRQENABLE_IVA2			0x00fc
 
+/* Omap4 specific registers */
+#define OMAP4_RM_RSTCTRL				0x0000
+#define OMAP4_RM_RSTTIME				0x0004
+#define OMAP4_RM_RSTST					0x0008
+#define OMAP4_PM_PWSTCTRL				0x0000
+#define OMAP4_PM_PWSTST					0x0004
+
 
 #ifndef __ASSEMBLER__
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prm-regbits-44xx.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/prm-regbits-44xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prm-regbits-44xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/prm-regbits-44xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -29,412 +29,412 @@
  * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
  * PRM_LDO_SRAM_MPU_SETUP
  */
-#define OMAP4430_ABBOFF_ACT_EXPORT_SHIFT				(1 << 1)
+#define OMAP4430_ABBOFF_ACT_EXPORT_SHIFT				1
 #define OMAP4430_ABBOFF_ACT_EXPORT_MASK					BITFIELD(1, 1)
 
 /*
  * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
  * PRM_LDO_SRAM_MPU_SETUP
  */
-#define OMAP4430_ABBOFF_SLEEP_EXPORT_SHIFT				(1 << 2)
+#define OMAP4430_ABBOFF_SLEEP_EXPORT_SHIFT				2
 #define OMAP4430_ABBOFF_SLEEP_EXPORT_MASK				BITFIELD(2, 2)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_ABB_IVA_DONE_EN_SHIFT					(1 << 31)
+#define OMAP4430_ABB_IVA_DONE_EN_SHIFT					31
 #define OMAP4430_ABB_IVA_DONE_EN_MASK					BITFIELD(31, 31)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_ABB_IVA_DONE_ST_SHIFT					(1 << 31)
+#define OMAP4430_ABB_IVA_DONE_ST_SHIFT					31
 #define OMAP4430_ABB_IVA_DONE_ST_MASK					BITFIELD(31, 31)
 
 /* Used by PRM_IRQENABLE_MPU_2 */
-#define OMAP4430_ABB_MPU_DONE_EN_SHIFT					(1 << 7)
+#define OMAP4430_ABB_MPU_DONE_EN_SHIFT					7
 #define OMAP4430_ABB_MPU_DONE_EN_MASK					BITFIELD(7, 7)
 
 /* Used by PRM_IRQSTATUS_MPU_2 */
-#define OMAP4430_ABB_MPU_DONE_ST_SHIFT					(1 << 7)
+#define OMAP4430_ABB_MPU_DONE_ST_SHIFT					7
 #define OMAP4430_ABB_MPU_DONE_ST_MASK					BITFIELD(7, 7)
 
 /* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
-#define OMAP4430_ACTIVE_FBB_SEL_SHIFT					(1 << 2)
+#define OMAP4430_ACTIVE_FBB_SEL_SHIFT					2
 #define OMAP4430_ACTIVE_FBB_SEL_MASK					BITFIELD(2, 2)
 
 /* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
-#define OMAP4430_ACTIVE_RBB_SEL_SHIFT					(1 << 1)
+#define OMAP4430_ACTIVE_RBB_SEL_SHIFT					1
 #define OMAP4430_ACTIVE_RBB_SEL_MASK					BITFIELD(1, 1)
 
 /* Used by PM_ABE_PWRSTCTRL */
-#define OMAP4430_AESSMEM_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_AESSMEM_ONSTATE_SHIFT					16
 #define OMAP4430_AESSMEM_ONSTATE_MASK					BITFIELD(16, 17)
 
 /* Used by PM_ABE_PWRSTCTRL */
-#define OMAP4430_AESSMEM_RETSTATE_SHIFT					(1 << 8)
+#define OMAP4430_AESSMEM_RETSTATE_SHIFT					8
 #define OMAP4430_AESSMEM_RETSTATE_MASK					BITFIELD(8, 8)
 
 /* Used by PM_ABE_PWRSTST */
-#define OMAP4430_AESSMEM_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_AESSMEM_STATEST_SHIFT					4
 #define OMAP4430_AESSMEM_STATEST_MASK					BITFIELD(4, 5)
 
 /*
  * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
  * PRM_LDO_SRAM_MPU_SETUP
  */
-#define OMAP4430_AIPOFF_SHIFT						(1 << 8)
+#define OMAP4430_AIPOFF_SHIFT						8
 #define OMAP4430_AIPOFF_MASK						BITFIELD(8, 8)
 
 /* Used by PRM_VOLTCTRL */
-#define OMAP4430_AUTO_CTRL_VDD_CORE_L_SHIFT				(1 << 0)
+#define OMAP4430_AUTO_CTRL_VDD_CORE_L_SHIFT				0
 #define OMAP4430_AUTO_CTRL_VDD_CORE_L_MASK				BITFIELD(0, 1)
 
 /* Used by PRM_VOLTCTRL */
-#define OMAP4430_AUTO_CTRL_VDD_IVA_L_SHIFT				(1 << 4)
+#define OMAP4430_AUTO_CTRL_VDD_IVA_L_SHIFT				4
 #define OMAP4430_AUTO_CTRL_VDD_IVA_L_MASK				BITFIELD(4, 5)
 
 /* Used by PRM_VOLTCTRL */
-#define OMAP4430_AUTO_CTRL_VDD_MPU_L_SHIFT				(1 << 2)
+#define OMAP4430_AUTO_CTRL_VDD_MPU_L_SHIFT				2
 #define OMAP4430_AUTO_CTRL_VDD_MPU_L_MASK				BITFIELD(2, 3)
 
 /* Used by PM_CAM_PWRSTCTRL */
-#define OMAP4430_CAM_MEM_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_CAM_MEM_ONSTATE_SHIFT					16
 #define OMAP4430_CAM_MEM_ONSTATE_MASK					BITFIELD(16, 17)
 
 /* Used by PM_CAM_PWRSTST */
-#define OMAP4430_CAM_MEM_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_CAM_MEM_STATEST_SHIFT					4
 #define OMAP4430_CAM_MEM_STATEST_MASK					BITFIELD(4, 5)
 
 /* Used by PRM_CLKREQCTRL */
-#define OMAP4430_CLKREQ_COND_SHIFT					(1 << 0)
+#define OMAP4430_CLKREQ_COND_SHIFT					0
 #define OMAP4430_CLKREQ_COND_MASK					BITFIELD(0, 2)
 
 /* Used by PRM_VC_VAL_SMPS_RA_CMD */
-#define OMAP4430_CMDRA_VDD_CORE_L_SHIFT					(1 << 0)
+#define OMAP4430_CMDRA_VDD_CORE_L_SHIFT					0
 #define OMAP4430_CMDRA_VDD_CORE_L_MASK					BITFIELD(0, 7)
 
 /* Used by PRM_VC_VAL_SMPS_RA_CMD */
-#define OMAP4430_CMDRA_VDD_IVA_L_SHIFT					(1 << 8)
+#define OMAP4430_CMDRA_VDD_IVA_L_SHIFT					8
 #define OMAP4430_CMDRA_VDD_IVA_L_MASK					BITFIELD(8, 15)
 
 /* Used by PRM_VC_VAL_SMPS_RA_CMD */
-#define OMAP4430_CMDRA_VDD_MPU_L_SHIFT					(1 << 16)
+#define OMAP4430_CMDRA_VDD_MPU_L_SHIFT					16
 #define OMAP4430_CMDRA_VDD_MPU_L_MASK					BITFIELD(16, 23)
 
 /* Used by PRM_VC_CFG_CHANNEL */
-#define OMAP4430_CMD_VDD_CORE_L_SHIFT					(1 << 4)
+#define OMAP4430_CMD_VDD_CORE_L_SHIFT					4
 #define OMAP4430_CMD_VDD_CORE_L_MASK					BITFIELD(4, 4)
 
 /* Used by PRM_VC_CFG_CHANNEL */
-#define OMAP4430_CMD_VDD_IVA_L_SHIFT					(1 << 12)
+#define OMAP4430_CMD_VDD_IVA_L_SHIFT					12
 #define OMAP4430_CMD_VDD_IVA_L_MASK					BITFIELD(12, 12)
 
 /* Used by PRM_VC_CFG_CHANNEL */
-#define OMAP4430_CMD_VDD_MPU_L_SHIFT					(1 << 17)
+#define OMAP4430_CMD_VDD_MPU_L_SHIFT					17
 #define OMAP4430_CMD_VDD_MPU_L_MASK					BITFIELD(17, 17)
 
 /* Used by PM_CORE_PWRSTCTRL */
-#define OMAP4430_CORE_OCMRAM_ONSTATE_SHIFT				(1 << 18)
+#define OMAP4430_CORE_OCMRAM_ONSTATE_SHIFT				18
 #define OMAP4430_CORE_OCMRAM_ONSTATE_MASK				BITFIELD(18, 19)
 
 /* Used by PM_CORE_PWRSTCTRL */
-#define OMAP4430_CORE_OCMRAM_RETSTATE_SHIFT				(1 << 9)
+#define OMAP4430_CORE_OCMRAM_RETSTATE_SHIFT				9
 #define OMAP4430_CORE_OCMRAM_RETSTATE_MASK				BITFIELD(9, 9)
 
 /* Used by PM_CORE_PWRSTST */
-#define OMAP4430_CORE_OCMRAM_STATEST_SHIFT				(1 << 6)
+#define OMAP4430_CORE_OCMRAM_STATEST_SHIFT				6
 #define OMAP4430_CORE_OCMRAM_STATEST_MASK				BITFIELD(6, 7)
 
 /* Used by PM_CORE_PWRSTCTRL */
-#define OMAP4430_CORE_OTHER_BANK_ONSTATE_SHIFT				(1 << 16)
+#define OMAP4430_CORE_OTHER_BANK_ONSTATE_SHIFT				16
 #define OMAP4430_CORE_OTHER_BANK_ONSTATE_MASK				BITFIELD(16, 17)
 
 /* Used by PM_CORE_PWRSTCTRL */
-#define OMAP4430_CORE_OTHER_BANK_RETSTATE_SHIFT				(1 << 8)
+#define OMAP4430_CORE_OTHER_BANK_RETSTATE_SHIFT				8
 #define OMAP4430_CORE_OTHER_BANK_RETSTATE_MASK				BITFIELD(8, 8)
 
 /* Used by PM_CORE_PWRSTST */
-#define OMAP4430_CORE_OTHER_BANK_STATEST_SHIFT				(1 << 4)
+#define OMAP4430_CORE_OTHER_BANK_STATEST_SHIFT				4
 #define OMAP4430_CORE_OTHER_BANK_STATEST_MASK				BITFIELD(4, 5)
 
 /* Used by PRM_VC_VAL_BYPASS */
-#define OMAP4430_DATA_SHIFT						(1 << 16)
+#define OMAP4430_DATA_SHIFT						16
 #define OMAP4430_DATA_MASK						BITFIELD(16, 23)
 
 /* Used by PRM_DEVICE_OFF_CTRL */
-#define OMAP4430_DEVICE_OFF_ENABLE_SHIFT				(1 << 0)
+#define OMAP4430_DEVICE_OFF_ENABLE_SHIFT				0
 #define OMAP4430_DEVICE_OFF_ENABLE_MASK					BITFIELD(0, 0)
 
 /* Used by PRM_VC_CFG_I2C_MODE */
-#define OMAP4430_DFILTEREN_SHIFT					(1 << 6)
+#define OMAP4430_DFILTEREN_SHIFT					6
 #define OMAP4430_DFILTEREN_MASK						BITFIELD(6, 6)
 
 /* Used by PRM_IRQENABLE_MPU, PRM_IRQENABLE_TESLA */
-#define OMAP4430_DPLL_ABE_RECAL_EN_SHIFT				(1 << 4)
+#define OMAP4430_DPLL_ABE_RECAL_EN_SHIFT				4
 #define OMAP4430_DPLL_ABE_RECAL_EN_MASK					BITFIELD(4, 4)
 
 /* Used by PRM_IRQSTATUS_MPU, PRM_IRQSTATUS_TESLA */
-#define OMAP4430_DPLL_ABE_RECAL_ST_SHIFT				(1 << 4)
+#define OMAP4430_DPLL_ABE_RECAL_ST_SHIFT				4
 #define OMAP4430_DPLL_ABE_RECAL_ST_MASK					BITFIELD(4, 4)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_DPLL_CORE_RECAL_EN_SHIFT				(1 << 0)
+#define OMAP4430_DPLL_CORE_RECAL_EN_SHIFT				0
 #define OMAP4430_DPLL_CORE_RECAL_EN_MASK				BITFIELD(0, 0)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_DPLL_CORE_RECAL_ST_SHIFT				(1 << 0)
+#define OMAP4430_DPLL_CORE_RECAL_ST_SHIFT				0
 #define OMAP4430_DPLL_CORE_RECAL_ST_MASK				BITFIELD(0, 0)
 
 /* Used by PRM_IRQENABLE_MPU */
-#define OMAP4430_DPLL_DDRPHY_RECAL_EN_SHIFT				(1 << 6)
+#define OMAP4430_DPLL_DDRPHY_RECAL_EN_SHIFT				6
 #define OMAP4430_DPLL_DDRPHY_RECAL_EN_MASK				BITFIELD(6, 6)
 
 /* Used by PRM_IRQSTATUS_MPU */
-#define OMAP4430_DPLL_DDRPHY_RECAL_ST_SHIFT				(1 << 6)
+#define OMAP4430_DPLL_DDRPHY_RECAL_ST_SHIFT				6
 #define OMAP4430_DPLL_DDRPHY_RECAL_ST_MASK				BITFIELD(6, 6)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU, PRM_IRQENABLE_TESLA */
-#define OMAP4430_DPLL_IVA_RECAL_EN_SHIFT				(1 << 2)
+#define OMAP4430_DPLL_IVA_RECAL_EN_SHIFT				2
 #define OMAP4430_DPLL_IVA_RECAL_EN_MASK					BITFIELD(2, 2)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU, PRM_IRQSTATUS_TESLA */
-#define OMAP4430_DPLL_IVA_RECAL_ST_SHIFT				(1 << 2)
+#define OMAP4430_DPLL_IVA_RECAL_ST_SHIFT				2
 #define OMAP4430_DPLL_IVA_RECAL_ST_MASK					BITFIELD(2, 2)
 
 /* Used by PRM_IRQENABLE_MPU */
-#define OMAP4430_DPLL_MPU_RECAL_EN_SHIFT				(1 << 1)
+#define OMAP4430_DPLL_MPU_RECAL_EN_SHIFT				1
 #define OMAP4430_DPLL_MPU_RECAL_EN_MASK					BITFIELD(1, 1)
 
 /* Used by PRM_IRQSTATUS_MPU */
-#define OMAP4430_DPLL_MPU_RECAL_ST_SHIFT				(1 << 1)
+#define OMAP4430_DPLL_MPU_RECAL_ST_SHIFT				1
 #define OMAP4430_DPLL_MPU_RECAL_ST_MASK					BITFIELD(1, 1)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_DPLL_PER_RECAL_EN_SHIFT				(1 << 3)
+#define OMAP4430_DPLL_PER_RECAL_EN_SHIFT				3
 #define OMAP4430_DPLL_PER_RECAL_EN_MASK					BITFIELD(3, 3)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_DPLL_PER_RECAL_ST_SHIFT				(1 << 3)
+#define OMAP4430_DPLL_PER_RECAL_ST_SHIFT				3
 #define OMAP4430_DPLL_PER_RECAL_ST_MASK					BITFIELD(3, 3)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_DPLL_UNIPRO_RECAL_EN_SHIFT				(1 << 7)
+#define OMAP4430_DPLL_UNIPRO_RECAL_EN_SHIFT				7
 #define OMAP4430_DPLL_UNIPRO_RECAL_EN_MASK				BITFIELD(7, 7)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_DPLL_UNIPRO_RECAL_ST_SHIFT				(1 << 7)
+#define OMAP4430_DPLL_UNIPRO_RECAL_ST_SHIFT				7
 #define OMAP4430_DPLL_UNIPRO_RECAL_ST_MASK				BITFIELD(7, 7)
 
 /* Used by PRM_IRQENABLE_MPU */
-#define OMAP4430_DPLL_USB_RECAL_EN_SHIFT				(1 << 5)
+#define OMAP4430_DPLL_USB_RECAL_EN_SHIFT				5
 #define OMAP4430_DPLL_USB_RECAL_EN_MASK					BITFIELD(5, 5)
 
 /* Used by PRM_IRQSTATUS_MPU */
-#define OMAP4430_DPLL_USB_RECAL_ST_SHIFT				(1 << 5)
+#define OMAP4430_DPLL_USB_RECAL_ST_SHIFT				5
 #define OMAP4430_DPLL_USB_RECAL_ST_MASK					BITFIELD(5, 5)
 
 /* Used by PM_DSS_PWRSTCTRL */
-#define OMAP4430_DSS_MEM_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_DSS_MEM_ONSTATE_SHIFT					16
 #define OMAP4430_DSS_MEM_ONSTATE_MASK					BITFIELD(16, 17)
 
 /* Used by PM_DSS_PWRSTCTRL */
-#define OMAP4430_DSS_MEM_RETSTATE_SHIFT					(1 << 8)
+#define OMAP4430_DSS_MEM_RETSTATE_SHIFT					8
 #define OMAP4430_DSS_MEM_RETSTATE_MASK					BITFIELD(8, 8)
 
 /* Used by PM_DSS_PWRSTST */
-#define OMAP4430_DSS_MEM_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_DSS_MEM_STATEST_SHIFT					4
 #define OMAP4430_DSS_MEM_STATEST_MASK					BITFIELD(4, 5)
 
 /* Used by PM_CORE_PWRSTCTRL */
-#define OMAP4430_DUCATI_L2RAM_ONSTATE_SHIFT				(1 << 20)
+#define OMAP4430_DUCATI_L2RAM_ONSTATE_SHIFT				20
 #define OMAP4430_DUCATI_L2RAM_ONSTATE_MASK				BITFIELD(20, 21)
 
 /* Used by PM_CORE_PWRSTCTRL */
-#define OMAP4430_DUCATI_L2RAM_RETSTATE_SHIFT				(1 << 10)
+#define OMAP4430_DUCATI_L2RAM_RETSTATE_SHIFT				10
 #define OMAP4430_DUCATI_L2RAM_RETSTATE_MASK				BITFIELD(10, 10)
 
 /* Used by PM_CORE_PWRSTST */
-#define OMAP4430_DUCATI_L2RAM_STATEST_SHIFT				(1 << 8)
+#define OMAP4430_DUCATI_L2RAM_STATEST_SHIFT				8
 #define OMAP4430_DUCATI_L2RAM_STATEST_MASK				BITFIELD(8, 9)
 
 /* Used by PM_CORE_PWRSTCTRL */
-#define OMAP4430_DUCATI_UNICACHE_ONSTATE_SHIFT				(1 << 22)
+#define OMAP4430_DUCATI_UNICACHE_ONSTATE_SHIFT				22
 #define OMAP4430_DUCATI_UNICACHE_ONSTATE_MASK				BITFIELD(22, 23)
 
 /* Used by PM_CORE_PWRSTCTRL */
-#define OMAP4430_DUCATI_UNICACHE_RETSTATE_SHIFT				(1 << 11)
+#define OMAP4430_DUCATI_UNICACHE_RETSTATE_SHIFT				11
 #define OMAP4430_DUCATI_UNICACHE_RETSTATE_MASK				BITFIELD(11, 11)
 
 /* Used by PM_CORE_PWRSTST */
-#define OMAP4430_DUCATI_UNICACHE_STATEST_SHIFT				(1 << 10)
+#define OMAP4430_DUCATI_UNICACHE_STATEST_SHIFT				10
 #define OMAP4430_DUCATI_UNICACHE_STATEST_MASK				BITFIELD(10, 11)
 
 /* Used by RM_MPU_RSTST */
-#define OMAP4430_EMULATION_RST_SHIFT					(1 << 0)
+#define OMAP4430_EMULATION_RST_SHIFT					0
 #define OMAP4430_EMULATION_RST_MASK					BITFIELD(0, 0)
 
 /* Used by RM_DUCATI_RSTST */
-#define OMAP4430_EMULATION_RST1ST_SHIFT					(1 << 3)
+#define OMAP4430_EMULATION_RST1ST_SHIFT					3
 #define OMAP4430_EMULATION_RST1ST_MASK					BITFIELD(3, 3)
 
 /* Used by RM_DUCATI_RSTST */
-#define OMAP4430_EMULATION_RST2ST_SHIFT					(1 << 4)
+#define OMAP4430_EMULATION_RST2ST_SHIFT					4
 #define OMAP4430_EMULATION_RST2ST_MASK					BITFIELD(4, 4)
 
 /* Used by RM_IVAHD_RSTST */
-#define OMAP4430_EMULATION_SEQ1_RST1ST_SHIFT				(1 << 3)
+#define OMAP4430_EMULATION_SEQ1_RST1ST_SHIFT				3
 #define OMAP4430_EMULATION_SEQ1_RST1ST_MASK				BITFIELD(3, 3)
 
 /* Used by RM_IVAHD_RSTST */
-#define OMAP4430_EMULATION_SEQ2_RST2ST_SHIFT				(1 << 4)
+#define OMAP4430_EMULATION_SEQ2_RST2ST_SHIFT				4
 #define OMAP4430_EMULATION_SEQ2_RST2ST_MASK				BITFIELD(4, 4)
 
 /* Used by PM_EMU_PWRSTCTRL */
-#define OMAP4430_EMU_BANK_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_EMU_BANK_ONSTATE_SHIFT					16
 #define OMAP4430_EMU_BANK_ONSTATE_MASK					BITFIELD(16, 17)
 
 /* Used by PM_EMU_PWRSTST */
-#define OMAP4430_EMU_BANK_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_EMU_BANK_STATEST_SHIFT					4
 #define OMAP4430_EMU_BANK_STATEST_MASK					BITFIELD(4, 5)
 
 /*
  * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
  * PRM_LDO_SRAM_MPU_SETUP, PRM_SRAM_WKUP_SETUP
  */
-#define OMAP4430_ENABLE_RTA_EXPORT_SHIFT				(1 << 0)
+#define OMAP4430_ENABLE_RTA_EXPORT_SHIFT				0
 #define OMAP4430_ENABLE_RTA_EXPORT_MASK					BITFIELD(0, 0)
 
 /*
  * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
  * PRM_LDO_SRAM_MPU_SETUP
  */
-#define OMAP4430_ENFUNC1_SHIFT						(1 << 3)
+#define OMAP4430_ENFUNC1_SHIFT						3
 #define OMAP4430_ENFUNC1_MASK						BITFIELD(3, 3)
 
 /*
  * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
  * PRM_LDO_SRAM_MPU_SETUP
  */
-#define OMAP4430_ENFUNC3_SHIFT						(1 << 5)
+#define OMAP4430_ENFUNC3_SHIFT						5
 #define OMAP4430_ENFUNC3_MASK						BITFIELD(5, 5)
 
 /*
  * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
  * PRM_LDO_SRAM_MPU_SETUP
  */
-#define OMAP4430_ENFUNC4_SHIFT						(1 << 6)
+#define OMAP4430_ENFUNC4_SHIFT						6
 #define OMAP4430_ENFUNC4_MASK						BITFIELD(6, 6)
 
 /*
  * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
  * PRM_LDO_SRAM_MPU_SETUP
  */
-#define OMAP4430_ENFUNC5_SHIFT						(1 << 7)
+#define OMAP4430_ENFUNC5_SHIFT						7
 #define OMAP4430_ENFUNC5_MASK						BITFIELD(7, 7)
 
 /* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
-#define OMAP4430_ERRORGAIN_SHIFT					(1 << 16)
+#define OMAP4430_ERRORGAIN_SHIFT					16
 #define OMAP4430_ERRORGAIN_MASK						BITFIELD(16, 23)
 
 /* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
-#define OMAP4430_ERROROFFSET_SHIFT					(1 << 24)
+#define OMAP4430_ERROROFFSET_SHIFT					24
 #define OMAP4430_ERROROFFSET_MASK					BITFIELD(24, 31)
 
 /* Used by PRM_RSTST */
-#define OMAP4430_EXTERNAL_WARM_RST_SHIFT				(1 << 5)
+#define OMAP4430_EXTERNAL_WARM_RST_SHIFT				5
 #define OMAP4430_EXTERNAL_WARM_RST_MASK					BITFIELD(5, 5)
 
 /* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
-#define OMAP4430_FORCEUPDATE_SHIFT					(1 << 1)
+#define OMAP4430_FORCEUPDATE_SHIFT					1
 #define OMAP4430_FORCEUPDATE_MASK					BITFIELD(1, 1)
 
 /* Used by PRM_VP_CORE_VOLTAGE, PRM_VP_IVA_VOLTAGE, PRM_VP_MPU_VOLTAGE */
-#define OMAP4430_FORCEUPDATEWAIT_SHIFT					(1 << 8)
+#define OMAP4430_FORCEUPDATEWAIT_SHIFT					8
 #define OMAP4430_FORCEUPDATEWAIT_MASK					BITFIELD(8, 31)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_TESLA */
-#define OMAP4430_FORCEWKUP_EN_SHIFT					(1 << 10)
+#define OMAP4430_FORCEWKUP_EN_SHIFT					10
 #define OMAP4430_FORCEWKUP_EN_MASK					BITFIELD(10, 10)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_TESLA */
-#define OMAP4430_FORCEWKUP_ST_SHIFT					(1 << 10)
+#define OMAP4430_FORCEWKUP_ST_SHIFT					10
 #define OMAP4430_FORCEWKUP_ST_MASK					BITFIELD(10, 10)
 
 /* Used by PM_GFX_PWRSTCTRL */
-#define OMAP4430_GFX_MEM_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_GFX_MEM_ONSTATE_SHIFT					16
 #define OMAP4430_GFX_MEM_ONSTATE_MASK					BITFIELD(16, 17)
 
 /* Used by PM_GFX_PWRSTST */
-#define OMAP4430_GFX_MEM_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_GFX_MEM_STATEST_SHIFT					4
 #define OMAP4430_GFX_MEM_STATEST_MASK					BITFIELD(4, 5)
 
 /* Used by PRM_RSTST */
-#define OMAP4430_GLOBAL_COLD_RST_SHIFT					(1 << 0)
+#define OMAP4430_GLOBAL_COLD_RST_SHIFT					0
 #define OMAP4430_GLOBAL_COLD_RST_MASK					BITFIELD(0, 0)
 
 /* Used by PRM_RSTST */
-#define OMAP4430_GLOBAL_WARM_SW_RST_SHIFT				(1 << 1)
+#define OMAP4430_GLOBAL_WARM_SW_RST_SHIFT				1
 #define OMAP4430_GLOBAL_WARM_SW_RST_MASK				BITFIELD(1, 1)
 
 /* Used by PRM_IO_PMCTRL */
-#define OMAP4430_GLOBAL_WUEN_SHIFT					(1 << 16)
+#define OMAP4430_GLOBAL_WUEN_SHIFT					16
 #define OMAP4430_GLOBAL_WUEN_MASK					BITFIELD(16, 16)
 
 /* Used by PRM_VC_CFG_I2C_MODE */
-#define OMAP4430_HSMCODE_SHIFT						(1 << 0)
+#define OMAP4430_HSMCODE_SHIFT						0
 #define OMAP4430_HSMCODE_MASK						BITFIELD(0, 2)
 
 /* Used by PRM_VC_CFG_I2C_MODE */
-#define OMAP4430_HSMODEEN_SHIFT						(1 << 3)
+#define OMAP4430_HSMODEEN_SHIFT						3
 #define OMAP4430_HSMODEEN_MASK						BITFIELD(3, 3)
 
 /* Used by PRM_VC_CFG_I2C_CLK */
-#define OMAP4430_HSSCLH_SHIFT						(1 << 16)
+#define OMAP4430_HSSCLH_SHIFT						16
 #define OMAP4430_HSSCLH_MASK						BITFIELD(16, 23)
 
 /* Used by PRM_VC_CFG_I2C_CLK */
-#define OMAP4430_HSSCLL_SHIFT						(1 << 24)
+#define OMAP4430_HSSCLL_SHIFT						24
 #define OMAP4430_HSSCLL_MASK						BITFIELD(24, 31)
 
 /* Used by PM_IVAHD_PWRSTCTRL */
-#define OMAP4430_HWA_MEM_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_HWA_MEM_ONSTATE_SHIFT					16
 #define OMAP4430_HWA_MEM_ONSTATE_MASK					BITFIELD(16, 17)
 
 /* Used by PM_IVAHD_PWRSTCTRL */
-#define OMAP4430_HWA_MEM_RETSTATE_SHIFT					(1 << 8)
+#define OMAP4430_HWA_MEM_RETSTATE_SHIFT					8
 #define OMAP4430_HWA_MEM_RETSTATE_MASK					BITFIELD(8, 8)
 
 /* Used by PM_IVAHD_PWRSTST */
-#define OMAP4430_HWA_MEM_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_HWA_MEM_STATEST_SHIFT					4
 #define OMAP4430_HWA_MEM_STATEST_MASK					BITFIELD(4, 5)
 
 /* Used by RM_MPU_RSTST */
-#define OMAP4430_ICECRUSHER_MPU_RST_SHIFT				(1 << 1)
+#define OMAP4430_ICECRUSHER_MPU_RST_SHIFT				1
 #define OMAP4430_ICECRUSHER_MPU_RST_MASK				BITFIELD(1, 1)
 
 /* Used by RM_DUCATI_RSTST */
-#define OMAP4430_ICECRUSHER_RST1ST_SHIFT				(1 << 5)
+#define OMAP4430_ICECRUSHER_RST1ST_SHIFT				5
 #define OMAP4430_ICECRUSHER_RST1ST_MASK					BITFIELD(5, 5)
 
 /* Used by RM_DUCATI_RSTST */
-#define OMAP4430_ICECRUSHER_RST2ST_SHIFT				(1 << 6)
+#define OMAP4430_ICECRUSHER_RST2ST_SHIFT				6
 #define OMAP4430_ICECRUSHER_RST2ST_MASK					BITFIELD(6, 6)
 
 /* Used by RM_IVAHD_RSTST */
-#define OMAP4430_ICECRUSHER_SEQ1_RST1ST_SHIFT				(1 << 5)
+#define OMAP4430_ICECRUSHER_SEQ1_RST1ST_SHIFT				5
 #define OMAP4430_ICECRUSHER_SEQ1_RST1ST_MASK				BITFIELD(5, 5)
 
 /* Used by RM_IVAHD_RSTST */
-#define OMAP4430_ICECRUSHER_SEQ2_RST2ST_SHIFT				(1 << 6)
+#define OMAP4430_ICECRUSHER_SEQ2_RST2ST_SHIFT				6
 #define OMAP4430_ICECRUSHER_SEQ2_RST2ST_MASK				BITFIELD(6, 6)
 
 /* Used by PRM_RSTST */
-#define OMAP4430_ICEPICK_RST_SHIFT					(1 << 9)
+#define OMAP4430_ICEPICK_RST_SHIFT					9
 #define OMAP4430_ICEPICK_RST_MASK					BITFIELD(9, 9)
 
 /* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
-#define OMAP4430_INITVDD_SHIFT						(1 << 2)
+#define OMAP4430_INITVDD_SHIFT						2
 #define OMAP4430_INITVDD_MASK						BITFIELD(2, 2)
 
 /* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
-#define OMAP4430_INITVOLTAGE_SHIFT					(1 << 8)
+#define OMAP4430_INITVOLTAGE_SHIFT					8
 #define OMAP4430_INITVOLTAGE_MASK					BITFIELD(8, 15)
 
 /*
@@ -442,47 +442,47 @@
  * PM_ABE_PWRSTST, PM_GFX_PWRSTST, PM_MPU_PWRSTST, PM_CEFUSE_PWRSTST,
  * PM_DSS_PWRSTST, PM_L4PER_PWRSTST, PM_TESLA_PWRSTST, PM_IVAHD_PWRSTST
  */
-#define OMAP4430_INTRANSITION_SHIFT					(1 << 20)
+#define OMAP4430_INTRANSITION_SHIFT					20
 #define OMAP4430_INTRANSITION_MASK					BITFIELD(20, 20)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_IO_EN_SHIFT						(1 << 9)
+#define OMAP4430_IO_EN_SHIFT						9
 #define OMAP4430_IO_EN_MASK						BITFIELD(9, 9)
 
 /* Used by PRM_IO_PMCTRL */
-#define OMAP4430_IO_ON_STATUS_SHIFT					(1 << 5)
+#define OMAP4430_IO_ON_STATUS_SHIFT					5
 #define OMAP4430_IO_ON_STATUS_MASK					BITFIELD(5, 5)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_IO_ST_SHIFT						(1 << 9)
+#define OMAP4430_IO_ST_SHIFT						9
 #define OMAP4430_IO_ST_MASK						BITFIELD(9, 9)
 
 /* Used by PRM_IO_PMCTRL */
-#define OMAP4430_ISOCLK_OVERRIDE_SHIFT					(1 << 0)
+#define OMAP4430_ISOCLK_OVERRIDE_SHIFT					0
 #define OMAP4430_ISOCLK_OVERRIDE_MASK					BITFIELD(0, 0)
 
 /* Used by PRM_IO_PMCTRL */
-#define OMAP4430_ISOCLK_STATUS_SHIFT					(1 << 1)
+#define OMAP4430_ISOCLK_STATUS_SHIFT					1
 #define OMAP4430_ISOCLK_STATUS_MASK					BITFIELD(1, 1)
 
 /* Used by PRM_IO_PMCTRL */
-#define OMAP4430_ISOOVR_EXTEND_SHIFT					(1 << 4)
+#define OMAP4430_ISOOVR_EXTEND_SHIFT					4
 #define OMAP4430_ISOOVR_EXTEND_MASK					BITFIELD(4, 4)
 
 /* Used by PRM_IO_COUNT */
-#define OMAP4430_ISO_2_ON_TIME_SHIFT					(1 << 0)
+#define OMAP4430_ISO_2_ON_TIME_SHIFT					0
 #define OMAP4430_ISO_2_ON_TIME_MASK					BITFIELD(0, 7)
 
 /* Used by PM_L3INIT_PWRSTCTRL */
-#define OMAP4430_L3INIT_BANK1_ONSTATE_SHIFT				(1 << 16)
+#define OMAP4430_L3INIT_BANK1_ONSTATE_SHIFT				16
 #define OMAP4430_L3INIT_BANK1_ONSTATE_MASK				BITFIELD(16, 17)
 
 /* Used by PM_L3INIT_PWRSTCTRL */
-#define OMAP4430_L3INIT_BANK1_RETSTATE_SHIFT				(1 << 8)
+#define OMAP4430_L3INIT_BANK1_RETSTATE_SHIFT				8
 #define OMAP4430_L3INIT_BANK1_RETSTATE_MASK				BITFIELD(8, 8)
 
 /* Used by PM_L3INIT_PWRSTST */
-#define OMAP4430_L3INIT_BANK1_STATEST_SHIFT				(1 << 4)
+#define OMAP4430_L3INIT_BANK1_STATEST_SHIFT				4
 #define OMAP4430_L3INIT_BANK1_STATEST_MASK				BITFIELD(4, 5)
 
 /*
@@ -490,7 +490,7 @@
  * PM_MPU_PWRSTCTRL, PM_DSS_PWRSTCTRL, PM_L4PER_PWRSTCTRL, PM_TESLA_PWRSTCTRL,
  * PM_IVAHD_PWRSTCTRL
  */
-#define OMAP4430_LOGICRETSTATE_SHIFT					(1 << 2)
+#define OMAP4430_LOGICRETSTATE_SHIFT					2
 #define OMAP4430_LOGICRETSTATE_MASK					BITFIELD(2, 2)
 
 /*
@@ -498,7 +498,7 @@
  * PM_ABE_PWRSTST, PM_GFX_PWRSTST, PM_MPU_PWRSTST, PM_CEFUSE_PWRSTST,
  * PM_DSS_PWRSTST, PM_L4PER_PWRSTST, PM_TESLA_PWRSTST, PM_IVAHD_PWRSTST
  */
-#define OMAP4430_LOGICSTATEST_SHIFT					(1 << 2)
+#define OMAP4430_LOGICSTATEST_SHIFT					2
 #define OMAP4430_LOGICSTATEST_MASK					BITFIELD(2, 2)
 
 /*
@@ -537,7 +537,7 @@
  * RM_L4PER_SLIMBUS2_CONTEXT, RM_L4SEC_PKAEIP29_CONTEXT,
  * RM_TESLA_TESLA_CONTEXT, RM_IVAHD_IVAHD_CONTEXT, RM_IVAHD_SL2_CONTEXT
  */
-#define OMAP4430_LOSTCONTEXT_DFF_SHIFT					(1 << 0)
+#define OMAP4430_LOSTCONTEXT_DFF_SHIFT					0
 #define OMAP4430_LOSTCONTEXT_DFF_MASK					BITFIELD(0, 0)
 
 /*
@@ -558,58 +558,58 @@
  * RM_L4SEC_AES2_CONTEXT, RM_L4SEC_CRYPTODMA_CONTEXT, RM_L4SEC_DES3DES_CONTEXT,
  * RM_L4SEC_RNG_CONTEXT, RM_L4SEC_SHA2MD51_CONTEXT, RM_TESLA_TESLA_CONTEXT
  */
-#define OMAP4430_LOSTCONTEXT_RFF_SHIFT					(1 << 1)
+#define OMAP4430_LOSTCONTEXT_RFF_SHIFT					1
 #define OMAP4430_LOSTCONTEXT_RFF_MASK					BITFIELD(1, 1)
 
 /* Used by RM_ABE_AESS_CONTEXT */
-#define OMAP4430_LOSTMEM_AESSMEM_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_AESSMEM_SHIFT					8
 #define OMAP4430_LOSTMEM_AESSMEM_MASK					BITFIELD(8, 8)
 
 /* Used by RM_CAM_FDIF_CONTEXT, RM_CAM_ISS_CONTEXT */
-#define OMAP4430_LOSTMEM_CAM_MEM_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_CAM_MEM_SHIFT					8
 #define OMAP4430_LOSTMEM_CAM_MEM_MASK					BITFIELD(8, 8)
 
 /* Used by RM_L3INSTR_OCP_WP1_CONTEXT */
-#define OMAP4430_LOSTMEM_CORE_NRET_BANK_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_CORE_NRET_BANK_SHIFT				8
 #define OMAP4430_LOSTMEM_CORE_NRET_BANK_MASK				BITFIELD(8, 8)
 
 /* Renamed from LOSTMEM_CORE_NRET_BANK Used by RM_MEMIF_DMM_CONTEXT */
-#define OMAP4430_LOSTMEM_CORE_NRET_BANK_9_9_SHIFT			(1 << 9)
+#define OMAP4430_LOSTMEM_CORE_NRET_BANK_9_9_SHIFT			9
 #define OMAP4430_LOSTMEM_CORE_NRET_BANK_9_9_MASK			BITFIELD(9, 9)
 
 /* Used by RM_L3_2_OCMC_RAM_CONTEXT */
-#define OMAP4430_LOSTMEM_CORE_OCMRAM_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_CORE_OCMRAM_SHIFT				8
 #define OMAP4430_LOSTMEM_CORE_OCMRAM_MASK				BITFIELD(8, 8)
 
 /*
  * Used by RM_D2D_MODEM_ICR_CONTEXT, RM_MEMIF_DMM_CONTEXT,
  * RM_SDMA_SDMA_CONTEXT
  */
-#define OMAP4430_LOSTMEM_CORE_OTHER_BANK_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_CORE_OTHER_BANK_SHIFT				8
 #define OMAP4430_LOSTMEM_CORE_OTHER_BANK_MASK				BITFIELD(8, 8)
 
 /* Used by RM_DSS_DEISS_CONTEXT, RM_DSS_DSS_CONTEXT */
-#define OMAP4430_LOSTMEM_DSS_MEM_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_DSS_MEM_SHIFT					8
 #define OMAP4430_LOSTMEM_DSS_MEM_MASK					BITFIELD(8, 8)
 
 /* Used by RM_DUCATI_DUCATI_CONTEXT */
-#define OMAP4430_LOSTMEM_DUCATI_L2RAM_SHIFT				(1 << 9)
+#define OMAP4430_LOSTMEM_DUCATI_L2RAM_SHIFT				9
 #define OMAP4430_LOSTMEM_DUCATI_L2RAM_MASK				BITFIELD(9, 9)
 
 /* Used by RM_DUCATI_DUCATI_CONTEXT */
-#define OMAP4430_LOSTMEM_DUCATI_UNICACHE_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_DUCATI_UNICACHE_SHIFT				8
 #define OMAP4430_LOSTMEM_DUCATI_UNICACHE_MASK				BITFIELD(8, 8)
 
 /* Used by RM_EMU_DEBUGSS_CONTEXT */
-#define OMAP4430_LOSTMEM_EMU_BANK_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_EMU_BANK_SHIFT					8
 #define OMAP4430_LOSTMEM_EMU_BANK_MASK					BITFIELD(8, 8)
 
 /* Used by RM_GFX_GFX_CONTEXT */
-#define OMAP4430_LOSTMEM_GFX_MEM_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_GFX_MEM_SHIFT					8
 #define OMAP4430_LOSTMEM_GFX_MEM_MASK					BITFIELD(8, 8)
 
 /* Used by RM_IVAHD_IVAHD_CONTEXT */
-#define OMAP4430_LOSTMEM_HWA_MEM_SHIFT					(1 << 10)
+#define OMAP4430_LOSTMEM_HWA_MEM_SHIFT					10
 #define OMAP4430_LOSTMEM_HWA_MEM_MASK					BITFIELD(10, 10)
 
 /*
@@ -619,19 +619,19 @@
  * RM_L3INIT_TPPSS_CONTEXT, RM_L3INIT_UNIPRO1_CONTEXT,
  * RM_L3INIT_USB_OTG_CONTEXT, RM_L3INIT_XHPI_CONTEXT
  */
-#define OMAP4430_LOSTMEM_L3INIT_BANK1_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_L3INIT_BANK1_SHIFT				8
 #define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK				BITFIELD(8, 8)
 
 /* Used by RM_MPU_MPU_CONTEXT */
-#define OMAP4430_LOSTMEM_MPU_L1_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_MPU_L1_SHIFT					8
 #define OMAP4430_LOSTMEM_MPU_L1_MASK					BITFIELD(8, 8)
 
 /* Used by RM_MPU_MPU_CONTEXT */
-#define OMAP4430_LOSTMEM_MPU_L2_SHIFT					(1 << 9)
+#define OMAP4430_LOSTMEM_MPU_L2_SHIFT					9
 #define OMAP4430_LOSTMEM_MPU_L2_MASK					BITFIELD(9, 9)
 
 /* Used by RM_MPU_MPU_CONTEXT */
-#define OMAP4430_LOSTMEM_MPU_RAM_SHIFT					(1 << 10)
+#define OMAP4430_LOSTMEM_MPU_RAM_SHIFT					10
 #define OMAP4430_LOSTMEM_MPU_RAM_MASK					BITFIELD(10, 10)
 
 /*
@@ -639,14 +639,14 @@
  * RM_L4PER_MCBSP4_CONTEXT, RM_L4PER_MMCSD3_CONTEXT, RM_L4PER_MMCSD4_CONTEXT,
  * RM_L4PER_MMCSD5_CONTEXT, RM_L4PER_SLIMBUS2_CONTEXT, RM_L4SEC_PKAEIP29_CONTEXT
  */
-#define OMAP4430_LOSTMEM_NONRETAINED_BANK_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_NONRETAINED_BANK_SHIFT				8
 #define OMAP4430_LOSTMEM_NONRETAINED_BANK_MASK				BITFIELD(8, 8)
 
 /*
  * Used by RM_ABE_DMIC_CONTEXT, RM_ABE_MCBSP1_CONTEXT, RM_ABE_MCBSP2_CONTEXT,
  * RM_ABE_MCBSP3_CONTEXT, RM_ABE_PDM_CONTEXT, RM_ABE_SLIMBUS_CONTEXT
  */
-#define OMAP4430_LOSTMEM_PERIHPMEM_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_PERIHPMEM_SHIFT				8
 #define OMAP4430_LOSTMEM_PERIHPMEM_MASK					BITFIELD(8, 8)
 
 /*
@@ -654,35 +654,35 @@
  * RM_L4PER_UART2_CONTEXT, RM_L4PER_UART3_CONTEXT, RM_L4PER_UART4_CONTEXT,
  * RM_L4SEC_CRYPTODMA_CONTEXT
  */
-#define OMAP4430_LOSTMEM_RETAINED_BANK_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_RETAINED_BANK_SHIFT				8
 #define OMAP4430_LOSTMEM_RETAINED_BANK_MASK				BITFIELD(8, 8)
 
 /* Used by RM_IVAHD_SL2_CONTEXT */
-#define OMAP4430_LOSTMEM_SL2_MEM_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_SL2_MEM_SHIFT					8
 #define OMAP4430_LOSTMEM_SL2_MEM_MASK					BITFIELD(8, 8)
 
 /* Used by RM_IVAHD_IVAHD_CONTEXT */
-#define OMAP4430_LOSTMEM_TCM1_MEM_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_TCM1_MEM_SHIFT					8
 #define OMAP4430_LOSTMEM_TCM1_MEM_MASK					BITFIELD(8, 8)
 
 /* Used by RM_IVAHD_IVAHD_CONTEXT */
-#define OMAP4430_LOSTMEM_TCM2_MEM_SHIFT					(1 << 9)
+#define OMAP4430_LOSTMEM_TCM2_MEM_SHIFT					9
 #define OMAP4430_LOSTMEM_TCM2_MEM_MASK					BITFIELD(9, 9)
 
 /* Used by RM_TESLA_TESLA_CONTEXT */
-#define OMAP4430_LOSTMEM_TESLA_EDMA_SHIFT				(1 << 10)
+#define OMAP4430_LOSTMEM_TESLA_EDMA_SHIFT				10
 #define OMAP4430_LOSTMEM_TESLA_EDMA_MASK				BITFIELD(10, 10)
 
 /* Used by RM_TESLA_TESLA_CONTEXT */
-#define OMAP4430_LOSTMEM_TESLA_L1_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_TESLA_L1_SHIFT					8
 #define OMAP4430_LOSTMEM_TESLA_L1_MASK					BITFIELD(8, 8)
 
 /* Used by RM_TESLA_TESLA_CONTEXT */
-#define OMAP4430_LOSTMEM_TESLA_L2_SHIFT					(1 << 9)
+#define OMAP4430_LOSTMEM_TESLA_L2_SHIFT					9
 #define OMAP4430_LOSTMEM_TESLA_L2_MASK					BITFIELD(9, 9)
 
 /* Used by RM_WKUP_SARRAM_CONTEXT */
-#define OMAP4430_LOSTMEM_WKUP_BANK_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_WKUP_BANK_SHIFT				8
 #define OMAP4430_LOSTMEM_WKUP_BANK_MASK					BITFIELD(8, 8)
 
 /*
@@ -690,164 +690,164 @@
  * PM_ABE_PWRSTCTRL, PM_GFX_PWRSTCTRL, PM_MPU_PWRSTCTRL, PM_CEFUSE_PWRSTCTRL,
  * PM_DSS_PWRSTCTRL, PM_L4PER_PWRSTCTRL, PM_TESLA_PWRSTCTRL, PM_IVAHD_PWRSTCTRL
  */
-#define OMAP4430_LOWPOWERSTATECHANGE_SHIFT				(1 << 4)
+#define OMAP4430_LOWPOWERSTATECHANGE_SHIFT				4
 #define OMAP4430_LOWPOWERSTATECHANGE_MASK				BITFIELD(4, 4)
 
 /* Used by PM_CORE_PWRSTCTRL */
-#define OMAP4430_MEMORYCHANGE_SHIFT					(1 << 3)
+#define OMAP4430_MEMORYCHANGE_SHIFT					3
 #define OMAP4430_MEMORYCHANGE_MASK					BITFIELD(3, 3)
 
 /* Used by PRM_MODEM_IF_CTRL */
-#define OMAP4430_MODEM_READY_SHIFT					(1 << 1)
+#define OMAP4430_MODEM_READY_SHIFT					1
 #define OMAP4430_MODEM_READY_MASK					BITFIELD(1, 1)
 
 /* Used by PRM_MODEM_IF_CTRL */
-#define OMAP4430_MODEM_SHUTDOWN_IRQ_SHIFT				(1 << 9)
+#define OMAP4430_MODEM_SHUTDOWN_IRQ_SHIFT				9
 #define OMAP4430_MODEM_SHUTDOWN_IRQ_MASK				BITFIELD(9, 9)
 
 /* Used by PRM_MODEM_IF_CTRL */
-#define OMAP4430_MODEM_SLEEP_ST_SHIFT					(1 << 16)
+#define OMAP4430_MODEM_SLEEP_ST_SHIFT					16
 #define OMAP4430_MODEM_SLEEP_ST_MASK					BITFIELD(16, 16)
 
 /* Used by PRM_MODEM_IF_CTRL */
-#define OMAP4430_MODEM_WAKE_IRQ_SHIFT					(1 << 8)
+#define OMAP4430_MODEM_WAKE_IRQ_SHIFT					8
 #define OMAP4430_MODEM_WAKE_IRQ_MASK					BITFIELD(8, 8)
 
 /* Used by PM_MPU_PWRSTCTRL */
-#define OMAP4430_MPU_L1_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_MPU_L1_ONSTATE_SHIFT					16
 #define OMAP4430_MPU_L1_ONSTATE_MASK					BITFIELD(16, 17)
 
 /* Used by PM_MPU_PWRSTCTRL */
-#define OMAP4430_MPU_L1_RETSTATE_SHIFT					(1 << 8)
+#define OMAP4430_MPU_L1_RETSTATE_SHIFT					8
 #define OMAP4430_MPU_L1_RETSTATE_MASK					BITFIELD(8, 8)
 
 /* Used by PM_MPU_PWRSTST */
-#define OMAP4430_MPU_L1_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_MPU_L1_STATEST_SHIFT					4
 #define OMAP4430_MPU_L1_STATEST_MASK					BITFIELD(4, 5)
 
 /* Used by PM_MPU_PWRSTCTRL */
-#define OMAP4430_MPU_L2_ONSTATE_SHIFT					(1 << 18)
+#define OMAP4430_MPU_L2_ONSTATE_SHIFT					18
 #define OMAP4430_MPU_L2_ONSTATE_MASK					BITFIELD(18, 19)
 
 /* Used by PM_MPU_PWRSTCTRL */
-#define OMAP4430_MPU_L2_RETSTATE_SHIFT					(1 << 9)
+#define OMAP4430_MPU_L2_RETSTATE_SHIFT					9
 #define OMAP4430_MPU_L2_RETSTATE_MASK					BITFIELD(9, 9)
 
 /* Used by PM_MPU_PWRSTST */
-#define OMAP4430_MPU_L2_STATEST_SHIFT					(1 << 6)
+#define OMAP4430_MPU_L2_STATEST_SHIFT					6
 #define OMAP4430_MPU_L2_STATEST_MASK					BITFIELD(6, 7)
 
 /* Used by PM_MPU_PWRSTCTRL */
-#define OMAP4430_MPU_RAM_ONSTATE_SHIFT					(1 << 20)
+#define OMAP4430_MPU_RAM_ONSTATE_SHIFT					20
 #define OMAP4430_MPU_RAM_ONSTATE_MASK					BITFIELD(20, 21)
 
 /* Used by PM_MPU_PWRSTCTRL */
-#define OMAP4430_MPU_RAM_RETSTATE_SHIFT					(1 << 10)
+#define OMAP4430_MPU_RAM_RETSTATE_SHIFT					10
 #define OMAP4430_MPU_RAM_RETSTATE_MASK					BITFIELD(10, 10)
 
 /* Used by PM_MPU_PWRSTST */
-#define OMAP4430_MPU_RAM_STATEST_SHIFT					(1 << 8)
+#define OMAP4430_MPU_RAM_STATEST_SHIFT					8
 #define OMAP4430_MPU_RAM_STATEST_MASK					BITFIELD(8, 9)
 
 /* Used by PRM_RSTST */
-#define OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT				(1 << 2)
+#define OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT				2
 #define OMAP4430_MPU_SECURITY_VIOL_RST_MASK				BITFIELD(2, 2)
 
 /* Used by PRM_RSTST */
-#define OMAP4430_MPU_WDT_RST_SHIFT					(1 << 3)
+#define OMAP4430_MPU_WDT_RST_SHIFT					3
 #define OMAP4430_MPU_WDT_RST_MASK					BITFIELD(3, 3)
 
 /* Used by PM_L4PER_PWRSTCTRL */
-#define OMAP4430_NONRETAINED_BANK_ONSTATE_SHIFT				(1 << 18)
+#define OMAP4430_NONRETAINED_BANK_ONSTATE_SHIFT				18
 #define OMAP4430_NONRETAINED_BANK_ONSTATE_MASK				BITFIELD(18, 19)
 
 /* Used by PM_L4PER_PWRSTCTRL */
-#define OMAP4430_NONRETAINED_BANK_RETSTATE_SHIFT			(1 << 9)
+#define OMAP4430_NONRETAINED_BANK_RETSTATE_SHIFT			9
 #define OMAP4430_NONRETAINED_BANK_RETSTATE_MASK				BITFIELD(9, 9)
 
 /* Used by PM_L4PER_PWRSTST */
-#define OMAP4430_NONRETAINED_BANK_STATEST_SHIFT				(1 << 6)
+#define OMAP4430_NONRETAINED_BANK_STATEST_SHIFT				6
 #define OMAP4430_NONRETAINED_BANK_STATEST_MASK				BITFIELD(6, 7)
 
 /* Used by PM_CORE_PWRSTCTRL */
-#define OMAP4430_OCP_NRET_BANK_ONSTATE_SHIFT				(1 << 24)
+#define OMAP4430_OCP_NRET_BANK_ONSTATE_SHIFT				24
 #define OMAP4430_OCP_NRET_BANK_ONSTATE_MASK				BITFIELD(24, 25)
 
 /* Used by PM_CORE_PWRSTCTRL */
-#define OMAP4430_OCP_NRET_BANK_RETSTATE_SHIFT				(1 << 12)
+#define OMAP4430_OCP_NRET_BANK_RETSTATE_SHIFT				12
 #define OMAP4430_OCP_NRET_BANK_RETSTATE_MASK				BITFIELD(12, 12)
 
 /* Used by PM_CORE_PWRSTST */
-#define OMAP4430_OCP_NRET_BANK_STATEST_SHIFT				(1 << 12)
+#define OMAP4430_OCP_NRET_BANK_STATEST_SHIFT				12
 #define OMAP4430_OCP_NRET_BANK_STATEST_MASK				BITFIELD(12, 13)
 
 /*
  * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
  * PRM_VC_VAL_CMD_VDD_MPU_L
  */
-#define OMAP4430_OFF_SHIFT						(1 << 0)
+#define OMAP4430_OFF_SHIFT						0
 #define OMAP4430_OFF_MASK						BITFIELD(0, 7)
 
 /* Used by PRM_LDO_BANDGAP_CTRL */
-#define OMAP4430_OFF_ENABLE_SHIFT					(1 << 0)
+#define OMAP4430_OFF_ENABLE_SHIFT					0
 #define OMAP4430_OFF_ENABLE_MASK					BITFIELD(0, 0)
 
 /*
  * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
  * PRM_VC_VAL_CMD_VDD_MPU_L
  */
-#define OMAP4430_ON_SHIFT						(1 << 24)
+#define OMAP4430_ON_SHIFT						24
 #define OMAP4430_ON_MASK						BITFIELD(24, 31)
 
 /*
  * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
  * PRM_VC_VAL_CMD_VDD_MPU_L
  */
-#define OMAP4430_ONLP_SHIFT						(1 << 16)
+#define OMAP4430_ONLP_SHIFT						16
 #define OMAP4430_ONLP_MASK						BITFIELD(16, 23)
 
 /* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
-#define OMAP4430_OPP_CHANGE_SHIFT					(1 << 2)
+#define OMAP4430_OPP_CHANGE_SHIFT					2
 #define OMAP4430_OPP_CHANGE_MASK					BITFIELD(2, 2)
 
 /* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
-#define OMAP4430_OPP_SEL_SHIFT						(1 << 0)
+#define OMAP4430_OPP_SEL_SHIFT						0
 #define OMAP4430_OPP_SEL_MASK						BITFIELD(0, 1)
 
 /* Used by PRM_SRAM_COUNT */
-#define OMAP4430_PCHARGECNT_VALUE_SHIFT					(1 << 0)
+#define OMAP4430_PCHARGECNT_VALUE_SHIFT					0
 #define OMAP4430_PCHARGECNT_VALUE_MASK					BITFIELD(0, 5)
 
 /* Used by PRM_PSCON_COUNT */
-#define OMAP4430_PCHARGE_TIME_SHIFT					(1 << 0)
+#define OMAP4430_PCHARGE_TIME_SHIFT					0
 #define OMAP4430_PCHARGE_TIME_MASK					BITFIELD(0, 7)
 
 /* Used by PM_ABE_PWRSTCTRL */
-#define OMAP4430_PERIPHMEM_ONSTATE_SHIFT				(1 << 20)
+#define OMAP4430_PERIPHMEM_ONSTATE_SHIFT				20
 #define OMAP4430_PERIPHMEM_ONSTATE_MASK					BITFIELD(20, 21)
 
 /* Used by PM_ABE_PWRSTCTRL */
-#define OMAP4430_PERIPHMEM_RETSTATE_SHIFT				(1 << 10)
+#define OMAP4430_PERIPHMEM_RETSTATE_SHIFT				10
 #define OMAP4430_PERIPHMEM_RETSTATE_MASK				BITFIELD(10, 10)
 
 /* Used by PM_ABE_PWRSTST */
-#define OMAP4430_PERIPHMEM_STATEST_SHIFT				(1 << 8)
+#define OMAP4430_PERIPHMEM_STATEST_SHIFT				8
 #define OMAP4430_PERIPHMEM_STATEST_MASK					BITFIELD(8, 9)
 
 /* Used by PRM_PHASE1_CNDP */
-#define OMAP4430_PHASE1_CNDP_SHIFT					(1 << 0)
+#define OMAP4430_PHASE1_CNDP_SHIFT					0
 #define OMAP4430_PHASE1_CNDP_MASK					BITFIELD(0, 31)
 
 /* Used by PRM_PHASE2A_CNDP */
-#define OMAP4430_PHASE2A_CNDP_SHIFT					(1 << 0)
+#define OMAP4430_PHASE2A_CNDP_SHIFT					0
 #define OMAP4430_PHASE2A_CNDP_MASK					BITFIELD(0, 31)
 
 /* Used by PRM_PHASE2B_CNDP */
-#define OMAP4430_PHASE2B_CNDP_SHIFT					(1 << 0)
+#define OMAP4430_PHASE2B_CNDP_SHIFT					0
 #define OMAP4430_PHASE2B_CNDP_MASK					BITFIELD(0, 31)
 
 /* Used by PRM_PSCON_COUNT */
-#define OMAP4430_PONOUT_2_PGOODIN_TIME_SHIFT				(1 << 8)
+#define OMAP4430_PONOUT_2_PGOODIN_TIME_SHIFT				8
 #define OMAP4430_PONOUT_2_PGOODIN_TIME_MASK				BITFIELD(8, 15)
 
 /*
@@ -856,7 +856,7 @@
  * PM_CEFUSE_PWRSTCTRL, PM_DSS_PWRSTCTRL, PM_L4PER_PWRSTCTRL,
  * PM_TESLA_PWRSTCTRL, PM_IVAHD_PWRSTCTRL
  */
-#define OMAP4430_POWERSTATE_SHIFT					(1 << 0)
+#define OMAP4430_POWERSTATE_SHIFT					0
 #define OMAP4430_POWERSTATE_MASK					BITFIELD(0, 1)
 
 /*
@@ -864,35 +864,35 @@
  * PM_ABE_PWRSTST, PM_GFX_PWRSTST, PM_MPU_PWRSTST, PM_CEFUSE_PWRSTST,
  * PM_DSS_PWRSTST, PM_L4PER_PWRSTST, PM_TESLA_PWRSTST, PM_IVAHD_PWRSTST
  */
-#define OMAP4430_POWERSTATEST_SHIFT					(1 << 0)
+#define OMAP4430_POWERSTATEST_SHIFT					0
 #define OMAP4430_POWERSTATEST_MASK					BITFIELD(0, 1)
 
 /* Used by PRM_PWRREQCTRL */
-#define OMAP4430_PWRREQ_COND_SHIFT					(1 << 0)
+#define OMAP4430_PWRREQ_COND_SHIFT					0
 #define OMAP4430_PWRREQ_COND_MASK					BITFIELD(0, 1)
 
 /* Used by PRM_VC_CFG_CHANNEL */
-#define OMAP4430_RACEN_VDD_CORE_L_SHIFT					(1 << 3)
+#define OMAP4430_RACEN_VDD_CORE_L_SHIFT					3
 #define OMAP4430_RACEN_VDD_CORE_L_MASK					BITFIELD(3, 3)
 
 /* Used by PRM_VC_CFG_CHANNEL */
-#define OMAP4430_RACEN_VDD_IVA_L_SHIFT					(1 << 11)
+#define OMAP4430_RACEN_VDD_IVA_L_SHIFT					11
 #define OMAP4430_RACEN_VDD_IVA_L_MASK					BITFIELD(11, 11)
 
 /* Used by PRM_VC_CFG_CHANNEL */
-#define OMAP4430_RACEN_VDD_MPU_L_SHIFT					(1 << 20)
+#define OMAP4430_RACEN_VDD_MPU_L_SHIFT					20
 #define OMAP4430_RACEN_VDD_MPU_L_MASK					BITFIELD(20, 20)
 
 /* Used by PRM_VC_CFG_CHANNEL */
-#define OMAP4430_RAC_VDD_CORE_L_SHIFT					(1 << 2)
+#define OMAP4430_RAC_VDD_CORE_L_SHIFT					2
 #define OMAP4430_RAC_VDD_CORE_L_MASK					BITFIELD(2, 2)
 
 /* Used by PRM_VC_CFG_CHANNEL */
-#define OMAP4430_RAC_VDD_IVA_L_SHIFT					(1 << 10)
+#define OMAP4430_RAC_VDD_IVA_L_SHIFT					10
 #define OMAP4430_RAC_VDD_IVA_L_MASK					BITFIELD(10, 10)
 
 /* Used by PRM_VC_CFG_CHANNEL */
-#define OMAP4430_RAC_VDD_MPU_L_SHIFT					(1 << 19)
+#define OMAP4430_RAC_VDD_MPU_L_SHIFT					19
 #define OMAP4430_RAC_VDD_MPU_L_MASK					BITFIELD(19, 19)
 
 /*
@@ -900,7 +900,7 @@
  * PRM_VOLTSETUP_IVA_OFF, PRM_VOLTSETUP_IVA_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
  * PRM_VOLTSETUP_MPU_RET_SLEEP
  */
-#define OMAP4430_RAMP_DOWN_COUNT_SHIFT					(1 << 16)
+#define OMAP4430_RAMP_DOWN_COUNT_SHIFT					16
 #define OMAP4430_RAMP_DOWN_COUNT_MASK					BITFIELD(16, 21)
 
 /*
@@ -908,7 +908,7 @@
  * PRM_VOLTSETUP_IVA_OFF, PRM_VOLTSETUP_IVA_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
  * PRM_VOLTSETUP_MPU_RET_SLEEP
  */
-#define OMAP4430_RAMP_DOWN_PRESCAL_SHIFT				(1 << 24)
+#define OMAP4430_RAMP_DOWN_PRESCAL_SHIFT				24
 #define OMAP4430_RAMP_DOWN_PRESCAL_MASK					BITFIELD(24, 25)
 
 /*
@@ -916,7 +916,7 @@
  * PRM_VOLTSETUP_IVA_OFF, PRM_VOLTSETUP_IVA_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
  * PRM_VOLTSETUP_MPU_RET_SLEEP
  */
-#define OMAP4430_RAMP_UP_COUNT_SHIFT					(1 << 0)
+#define OMAP4430_RAMP_UP_COUNT_SHIFT					0
 #define OMAP4430_RAMP_UP_COUNT_MASK					BITFIELD(0, 5)
 
 /*
@@ -924,1282 +924,1282 @@
  * PRM_VOLTSETUP_IVA_OFF, PRM_VOLTSETUP_IVA_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
  * PRM_VOLTSETUP_MPU_RET_SLEEP
  */
-#define OMAP4430_RAMP_UP_PRESCAL_SHIFT					(1 << 8)
+#define OMAP4430_RAMP_UP_PRESCAL_SHIFT					8
 #define OMAP4430_RAMP_UP_PRESCAL_MASK					BITFIELD(8, 9)
 
 /* Used by PRM_VC_CFG_CHANNEL */
-#define OMAP4430_RAV_VDD_CORE_L_SHIFT					(1 << 1)
+#define OMAP4430_RAV_VDD_CORE_L_SHIFT					1
 #define OMAP4430_RAV_VDD_CORE_L_MASK					BITFIELD(1, 1)
 
 /* Used by PRM_VC_CFG_CHANNEL */
-#define OMAP4430_RAV_VDD_IVA_L_SHIFT					(1 << 9)
+#define OMAP4430_RAV_VDD_IVA_L_SHIFT					9
 #define OMAP4430_RAV_VDD_IVA_L_MASK					BITFIELD(9, 9)
 
 /* Used by PRM_VC_CFG_CHANNEL */
-#define OMAP4430_RAV_VDD_MPU_L_SHIFT					(1 << 18)
+#define OMAP4430_RAV_VDD_MPU_L_SHIFT					18
 #define OMAP4430_RAV_VDD_MPU_L_MASK					BITFIELD(18, 18)
 
 /* Used by PRM_VC_VAL_BYPASS */
-#define OMAP4430_REGADDR_SHIFT						(1 << 8)
+#define OMAP4430_REGADDR_SHIFT						8
 #define OMAP4430_REGADDR_MASK						BITFIELD(8, 15)
 
 /*
  * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
  * PRM_VC_VAL_CMD_VDD_MPU_L
  */
-#define OMAP4430_RET_SHIFT						(1 << 8)
+#define OMAP4430_RET_SHIFT						8
 #define OMAP4430_RET_MASK						BITFIELD(8, 15)
 
 /* Used by PM_L4PER_PWRSTCTRL */
-#define OMAP4430_RETAINED_BANK_ONSTATE_SHIFT				(1 << 16)
+#define OMAP4430_RETAINED_BANK_ONSTATE_SHIFT				16
 #define OMAP4430_RETAINED_BANK_ONSTATE_MASK				BITFIELD(16, 17)
 
 /* Used by PM_L4PER_PWRSTCTRL */
-#define OMAP4430_RETAINED_BANK_RETSTATE_SHIFT				(1 << 8)
+#define OMAP4430_RETAINED_BANK_RETSTATE_SHIFT				8
 #define OMAP4430_RETAINED_BANK_RETSTATE_MASK				BITFIELD(8, 8)
 
 /* Used by PM_L4PER_PWRSTST */
-#define OMAP4430_RETAINED_BANK_STATEST_SHIFT				(1 << 4)
+#define OMAP4430_RETAINED_BANK_STATEST_SHIFT				4
 #define OMAP4430_RETAINED_BANK_STATEST_MASK				BITFIELD(4, 5)
 
 /*
  * Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_IVA_CTRL,
  * PRM_LDO_SRAM_MPU_CTRL
  */
-#define OMAP4430_RETMODE_ENABLE_SHIFT					(1 << 0)
+#define OMAP4430_RETMODE_ENABLE_SHIFT					0
 #define OMAP4430_RETMODE_ENABLE_MASK					BITFIELD(0, 0)
 
 /* Used by REVISION_PRM */
-#define OMAP4430_REV_SHIFT						(1 << 0)
+#define OMAP4430_REV_SHIFT						0
 #define OMAP4430_REV_MASK						BITFIELD(0, 7)
 
 /* Used by RM_DUCATI_RSTCTRL, RM_TESLA_RSTCTRL, RM_IVAHD_RSTCTRL */
-#define OMAP4430_RST1_SHIFT						(1 << 0)
+#define OMAP4430_RST1_SHIFT						0
 #define OMAP4430_RST1_MASK						BITFIELD(0, 0)
 
 /* Used by RM_DUCATI_RSTST, RM_TESLA_RSTST, RM_IVAHD_RSTST */
-#define OMAP4430_RST1ST_SHIFT						(1 << 0)
+#define OMAP4430_RST1ST_SHIFT						0
 #define OMAP4430_RST1ST_MASK						BITFIELD(0, 0)
 
 /* Used by RM_DUCATI_RSTCTRL, RM_TESLA_RSTCTRL, RM_IVAHD_RSTCTRL */
-#define OMAP4430_RST2_SHIFT						(1 << 1)
+#define OMAP4430_RST2_SHIFT						1
 #define OMAP4430_RST2_MASK						BITFIELD(1, 1)
 
 /* Used by RM_DUCATI_RSTST, RM_TESLA_RSTST, RM_IVAHD_RSTST */
-#define OMAP4430_RST2ST_SHIFT						(1 << 1)
+#define OMAP4430_RST2ST_SHIFT						1
 #define OMAP4430_RST2ST_MASK						BITFIELD(1, 1)
 
 /* Used by RM_DUCATI_RSTCTRL, RM_IVAHD_RSTCTRL */
-#define OMAP4430_RST3_SHIFT						(1 << 2)
+#define OMAP4430_RST3_SHIFT						2
 #define OMAP4430_RST3_MASK						BITFIELD(2, 2)
 
 /* Used by RM_DUCATI_RSTST, RM_IVAHD_RSTST */
-#define OMAP4430_RST3ST_SHIFT						(1 << 2)
+#define OMAP4430_RST3ST_SHIFT						2
 #define OMAP4430_RST3ST_MASK						BITFIELD(2, 2)
 
 /* Used by PRM_RSTTIME */
-#define OMAP4430_RSTTIME1_SHIFT						(1 << 0)
+#define OMAP4430_RSTTIME1_SHIFT						0
 #define OMAP4430_RSTTIME1_MASK						BITFIELD(0, 9)
 
 /* Used by PRM_RSTTIME */
-#define OMAP4430_RSTTIME2_SHIFT						(1 << 10)
+#define OMAP4430_RSTTIME2_SHIFT						10
 #define OMAP4430_RSTTIME2_MASK						BITFIELD(10, 14)
 
 /* Used by PRM_RSTCTRL */
-#define OMAP4430_RST_GLOBAL_COLD_SW_SHIFT				(1 << 1)
+#define OMAP4430_RST_GLOBAL_COLD_SW_SHIFT				1
 #define OMAP4430_RST_GLOBAL_COLD_SW_MASK				BITFIELD(1, 1)
 
 /* Used by PRM_RSTCTRL */
-#define OMAP4430_RST_GLOBAL_WARM_SW_SHIFT				(1 << 0)
+#define OMAP4430_RST_GLOBAL_WARM_SW_SHIFT				0
 #define OMAP4430_RST_GLOBAL_WARM_SW_MASK				BITFIELD(0, 0)
 
 /* Used by PRM_VC_CFG_CHANNEL */
-#define OMAP4430_SA_VDD_CORE_L_SHIFT					(1 << 0)
+#define OMAP4430_SA_VDD_CORE_L_SHIFT					0
 #define OMAP4430_SA_VDD_CORE_L_MASK					BITFIELD(0, 0)
 
 /* Renamed from SA_VDD_CORE_L Used by PRM_VC_SMPS_SA */
-#define OMAP4430_SA_VDD_CORE_L_0_6_SHIFT				(1 << 0)
+#define OMAP4430_SA_VDD_CORE_L_0_6_SHIFT				0
 #define OMAP4430_SA_VDD_CORE_L_0_6_MASK					BITFIELD(0, 6)
 
 /* Used by PRM_VC_CFG_CHANNEL */
-#define OMAP4430_SA_VDD_IVA_L_SHIFT					(1 << 8)
+#define OMAP4430_SA_VDD_IVA_L_SHIFT					8
 #define OMAP4430_SA_VDD_IVA_L_MASK					BITFIELD(8, 8)
 
 /* Renamed from SA_VDD_IVA_L Used by PRM_VC_SMPS_SA */
-#define OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT			(1 << 8)
+#define OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT			8
 #define OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK			BITFIELD(8, 14)
 
 /* Used by PRM_VC_CFG_CHANNEL */
-#define OMAP4430_SA_VDD_MPU_L_SHIFT					(1 << 16)
+#define OMAP4430_SA_VDD_MPU_L_SHIFT					16
 #define OMAP4430_SA_VDD_MPU_L_MASK					BITFIELD(16, 16)
 
 /* Renamed from SA_VDD_MPU_L Used by PRM_VC_SMPS_SA */
-#define OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT			(1 << 16)
+#define OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT			16
 #define OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK			BITFIELD(16, 22)
 
 /* Used by PRM_VC_CFG_I2C_CLK */
-#define OMAP4430_SCLH_SHIFT						(1 << 0)
+#define OMAP4430_SCLH_SHIFT						0
 #define OMAP4430_SCLH_MASK						BITFIELD(0, 7)
 
 /* Used by PRM_VC_CFG_I2C_CLK */
-#define OMAP4430_SCLL_SHIFT						(1 << 8)
+#define OMAP4430_SCLL_SHIFT						8
 #define OMAP4430_SCLL_MASK						BITFIELD(8, 15)
 
 /* Used by PRM_RSTST */
-#define OMAP4430_SECURE_WDT_RST_SHIFT					(1 << 4)
+#define OMAP4430_SECURE_WDT_RST_SHIFT					4
 #define OMAP4430_SECURE_WDT_RST_MASK					BITFIELD(4, 4)
 
 /* Used by PM_IVAHD_PWRSTCTRL */
-#define OMAP4430_SL2_MEM_ONSTATE_SHIFT					(1 << 18)
+#define OMAP4430_SL2_MEM_ONSTATE_SHIFT					18
 #define OMAP4430_SL2_MEM_ONSTATE_MASK					BITFIELD(18, 19)
 
 /* Used by PM_IVAHD_PWRSTCTRL */
-#define OMAP4430_SL2_MEM_RETSTATE_SHIFT					(1 << 9)
+#define OMAP4430_SL2_MEM_RETSTATE_SHIFT					9
 #define OMAP4430_SL2_MEM_RETSTATE_MASK					BITFIELD(9, 9)
 
 /* Used by PM_IVAHD_PWRSTST */
-#define OMAP4430_SL2_MEM_STATEST_SHIFT					(1 << 6)
+#define OMAP4430_SL2_MEM_STATEST_SHIFT					6
 #define OMAP4430_SL2_MEM_STATEST_MASK					BITFIELD(6, 7)
 
 /* Used by PRM_VC_VAL_BYPASS */
-#define OMAP4430_SLAVEADDR_SHIFT					(1 << 0)
+#define OMAP4430_SLAVEADDR_SHIFT					0
 #define OMAP4430_SLAVEADDR_MASK						BITFIELD(0, 6)
 
 /* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
-#define OMAP4430_SLEEP_RBB_SEL_SHIFT					(1 << 3)
+#define OMAP4430_SLEEP_RBB_SEL_SHIFT					3
 #define OMAP4430_SLEEP_RBB_SEL_MASK					BITFIELD(3, 3)
 
 /* Used by PRM_SRAM_COUNT */
-#define OMAP4430_SLPCNT_VALUE_SHIFT					(1 << 16)
+#define OMAP4430_SLPCNT_VALUE_SHIFT					16
 #define OMAP4430_SLPCNT_VALUE_MASK					BITFIELD(16, 23)
 
 /* Used by PRM_VP_CORE_VSTEPMAX, PRM_VP_IVA_VSTEPMAX, PRM_VP_MPU_VSTEPMAX */
-#define OMAP4430_SMPSWAITTIMEMAX_SHIFT					(1 << 8)
+#define OMAP4430_SMPSWAITTIMEMAX_SHIFT					8
 #define OMAP4430_SMPSWAITTIMEMAX_MASK					BITFIELD(8, 23)
 
 /* Used by PRM_VP_CORE_VSTEPMIN, PRM_VP_IVA_VSTEPMIN, PRM_VP_MPU_VSTEPMIN */
-#define OMAP4430_SMPSWAITTIMEMIN_SHIFT					(1 << 8)
+#define OMAP4430_SMPSWAITTIMEMIN_SHIFT					8
 #define OMAP4430_SMPSWAITTIMEMIN_MASK					BITFIELD(8, 23)
 
 /* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
-#define OMAP4430_SR2EN_SHIFT						(1 << 0)
+#define OMAP4430_SR2EN_SHIFT						0
 #define OMAP4430_SR2EN_MASK						BITFIELD(0, 0)
 
 /* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
-#define OMAP4430_SR2_IN_TRANSITION_SHIFT				(1 << 6)
+#define OMAP4430_SR2_IN_TRANSITION_SHIFT				6
 #define OMAP4430_SR2_IN_TRANSITION_MASK					BITFIELD(6, 6)
 
 /* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
-#define OMAP4430_SR2_STATUS_SHIFT					(1 << 3)
+#define OMAP4430_SR2_STATUS_SHIFT					3
 #define OMAP4430_SR2_STATUS_MASK					BITFIELD(3, 4)
 
 /* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
-#define OMAP4430_SR2_WTCNT_VALUE_SHIFT					(1 << 8)
+#define OMAP4430_SR2_WTCNT_VALUE_SHIFT					8
 #define OMAP4430_SR2_WTCNT_VALUE_MASK					BITFIELD(8, 15)
 
 /*
  * Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_IVA_CTRL,
  * PRM_LDO_SRAM_MPU_CTRL
  */
-#define OMAP4430_SRAMLDO_STATUS_SHIFT					(1 << 8)
+#define OMAP4430_SRAMLDO_STATUS_SHIFT					8
 #define OMAP4430_SRAMLDO_STATUS_MASK					BITFIELD(8, 8)
 
 /*
  * Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_IVA_CTRL,
  * PRM_LDO_SRAM_MPU_CTRL
  */
-#define OMAP4430_SRAM_IN_TRANSITION_SHIFT				(1 << 9)
+#define OMAP4430_SRAM_IN_TRANSITION_SHIFT				9
 #define OMAP4430_SRAM_IN_TRANSITION_MASK				BITFIELD(9, 9)
 
 /* Used by PRM_VC_CFG_I2C_MODE */
-#define OMAP4430_SRMODEEN_SHIFT						(1 << 4)
+#define OMAP4430_SRMODEEN_SHIFT						4
 #define OMAP4430_SRMODEEN_MASK						BITFIELD(4, 4)
 
 /* Used by PRM_VOLTSETUP_WARMRESET */
-#define OMAP4430_STABLE_COUNT_SHIFT					(1 << 0)
+#define OMAP4430_STABLE_COUNT_SHIFT					0
 #define OMAP4430_STABLE_COUNT_MASK					BITFIELD(0, 5)
 
 /* Used by PRM_VOLTSETUP_WARMRESET */
-#define OMAP4430_STABLE_PRESCAL_SHIFT					(1 << 8)
+#define OMAP4430_STABLE_PRESCAL_SHIFT					8
 #define OMAP4430_STABLE_PRESCAL_MASK					BITFIELD(8, 9)
 
 /* Used by PM_IVAHD_PWRSTCTRL */
-#define OMAP4430_TCM1_MEM_ONSTATE_SHIFT					(1 << 20)
+#define OMAP4430_TCM1_MEM_ONSTATE_SHIFT					20
 #define OMAP4430_TCM1_MEM_ONSTATE_MASK					BITFIELD(20, 21)
 
 /* Used by PM_IVAHD_PWRSTCTRL */
-#define OMAP4430_TCM1_MEM_RETSTATE_SHIFT				(1 << 10)
+#define OMAP4430_TCM1_MEM_RETSTATE_SHIFT				10
 #define OMAP4430_TCM1_MEM_RETSTATE_MASK					BITFIELD(10, 10)
 
 /* Used by PM_IVAHD_PWRSTST */
-#define OMAP4430_TCM1_MEM_STATEST_SHIFT					(1 << 8)
+#define OMAP4430_TCM1_MEM_STATEST_SHIFT					8
 #define OMAP4430_TCM1_MEM_STATEST_MASK					BITFIELD(8, 9)
 
 /* Used by PM_IVAHD_PWRSTCTRL */
-#define OMAP4430_TCM2_MEM_ONSTATE_SHIFT					(1 << 22)
+#define OMAP4430_TCM2_MEM_ONSTATE_SHIFT					22
 #define OMAP4430_TCM2_MEM_ONSTATE_MASK					BITFIELD(22, 23)
 
 /* Used by PM_IVAHD_PWRSTCTRL */
-#define OMAP4430_TCM2_MEM_RETSTATE_SHIFT				(1 << 11)
+#define OMAP4430_TCM2_MEM_RETSTATE_SHIFT				11
 #define OMAP4430_TCM2_MEM_RETSTATE_MASK					BITFIELD(11, 11)
 
 /* Used by PM_IVAHD_PWRSTST */
-#define OMAP4430_TCM2_MEM_STATEST_SHIFT					(1 << 10)
+#define OMAP4430_TCM2_MEM_STATEST_SHIFT					10
 #define OMAP4430_TCM2_MEM_STATEST_MASK					BITFIELD(10, 11)
 
 /* Used by RM_TESLA_RSTST */
-#define OMAP4430_TESLASS_EMU_RSTST_SHIFT				(1 << 2)
+#define OMAP4430_TESLASS_EMU_RSTST_SHIFT				2
 #define OMAP4430_TESLASS_EMU_RSTST_MASK					BITFIELD(2, 2)
 
 /* Used by RM_TESLA_RSTST */
-#define OMAP4430_TESLA_DSP_EMU_REQ_RSTST_SHIFT				(1 << 3)
+#define OMAP4430_TESLA_DSP_EMU_REQ_RSTST_SHIFT				3
 #define OMAP4430_TESLA_DSP_EMU_REQ_RSTST_MASK				BITFIELD(3, 3)
 
 /* Used by PM_TESLA_PWRSTCTRL */
-#define OMAP4430_TESLA_EDMA_ONSTATE_SHIFT				(1 << 20)
+#define OMAP4430_TESLA_EDMA_ONSTATE_SHIFT				20
 #define OMAP4430_TESLA_EDMA_ONSTATE_MASK				BITFIELD(20, 21)
 
 /* Used by PM_TESLA_PWRSTCTRL */
-#define OMAP4430_TESLA_EDMA_RETSTATE_SHIFT				(1 << 10)
+#define OMAP4430_TESLA_EDMA_RETSTATE_SHIFT				10
 #define OMAP4430_TESLA_EDMA_RETSTATE_MASK				BITFIELD(10, 10)
 
 /* Used by PM_TESLA_PWRSTST */
-#define OMAP4430_TESLA_EDMA_STATEST_SHIFT				(1 << 8)
+#define OMAP4430_TESLA_EDMA_STATEST_SHIFT				8
 #define OMAP4430_TESLA_EDMA_STATEST_MASK				BITFIELD(8, 9)
 
 /* Used by PM_TESLA_PWRSTCTRL */
-#define OMAP4430_TESLA_L1_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_TESLA_L1_ONSTATE_SHIFT					16
 #define OMAP4430_TESLA_L1_ONSTATE_MASK					BITFIELD(16, 17)
 
 /* Used by PM_TESLA_PWRSTCTRL */
-#define OMAP4430_TESLA_L1_RETSTATE_SHIFT				(1 << 8)
+#define OMAP4430_TESLA_L1_RETSTATE_SHIFT				8
 #define OMAP4430_TESLA_L1_RETSTATE_MASK					BITFIELD(8, 8)
 
 /* Used by PM_TESLA_PWRSTST */
-#define OMAP4430_TESLA_L1_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_TESLA_L1_STATEST_SHIFT					4
 #define OMAP4430_TESLA_L1_STATEST_MASK					BITFIELD(4, 5)
 
 /* Used by PM_TESLA_PWRSTCTRL */
-#define OMAP4430_TESLA_L2_ONSTATE_SHIFT					(1 << 18)
+#define OMAP4430_TESLA_L2_ONSTATE_SHIFT					18
 #define OMAP4430_TESLA_L2_ONSTATE_MASK					BITFIELD(18, 19)
 
 /* Used by PM_TESLA_PWRSTCTRL */
-#define OMAP4430_TESLA_L2_RETSTATE_SHIFT				(1 << 9)
+#define OMAP4430_TESLA_L2_RETSTATE_SHIFT				9
 #define OMAP4430_TESLA_L2_RETSTATE_MASK					BITFIELD(9, 9)
 
 /* Used by PM_TESLA_PWRSTST */
-#define OMAP4430_TESLA_L2_STATEST_SHIFT					(1 << 6)
+#define OMAP4430_TESLA_L2_STATEST_SHIFT					6
 #define OMAP4430_TESLA_L2_STATEST_MASK					BITFIELD(6, 7)
 
 /* Used by PRM_VP_CORE_VLIMITTO, PRM_VP_IVA_VLIMITTO, PRM_VP_MPU_VLIMITTO */
-#define OMAP4430_TIMEOUT_SHIFT						(1 << 0)
+#define OMAP4430_TIMEOUT_SHIFT						0
 #define OMAP4430_TIMEOUT_MASK						BITFIELD(0, 15)
 
 /* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
-#define OMAP4430_TIMEOUTEN_SHIFT					(1 << 3)
+#define OMAP4430_TIMEOUTEN_SHIFT					3
 #define OMAP4430_TIMEOUTEN_MASK						BITFIELD(3, 3)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_TRANSITION_EN_SHIFT					(1 << 8)
+#define OMAP4430_TRANSITION_EN_SHIFT					8
 #define OMAP4430_TRANSITION_EN_MASK					BITFIELD(8, 8)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_TRANSITION_ST_SHIFT					(1 << 8)
+#define OMAP4430_TRANSITION_ST_SHIFT					8
 #define OMAP4430_TRANSITION_ST_MASK					BITFIELD(8, 8)
 
 /* Used by PRM_VC_VAL_BYPASS */
-#define OMAP4430_VALID_SHIFT						(1 << 24)
+#define OMAP4430_VALID_SHIFT						24
 #define OMAP4430_VALID_MASK						BITFIELD(24, 24)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VC_BYPASSACK_EN_SHIFT					(1 << 14)
+#define OMAP4430_VC_BYPASSACK_EN_SHIFT					14
 #define OMAP4430_VC_BYPASSACK_EN_MASK					BITFIELD(14, 14)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VC_BYPASSACK_ST_SHIFT					(1 << 14)
+#define OMAP4430_VC_BYPASSACK_ST_SHIFT					14
 #define OMAP4430_VC_BYPASSACK_ST_MASK					BITFIELD(14, 14)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VC_IVA_VPACK_EN_SHIFT					(1 << 30)
+#define OMAP4430_VC_IVA_VPACK_EN_SHIFT					30
 #define OMAP4430_VC_IVA_VPACK_EN_MASK					BITFIELD(30, 30)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VC_IVA_VPACK_ST_SHIFT					(1 << 30)
+#define OMAP4430_VC_IVA_VPACK_ST_SHIFT					30
 #define OMAP4430_VC_IVA_VPACK_ST_MASK					BITFIELD(30, 30)
 
 /* Used by PRM_IRQENABLE_MPU_2 */
-#define OMAP4430_VC_MPU_VPACK_EN_SHIFT					(1 << 6)
+#define OMAP4430_VC_MPU_VPACK_EN_SHIFT					6
 #define OMAP4430_VC_MPU_VPACK_EN_MASK					BITFIELD(6, 6)
 
 /* Used by PRM_IRQSTATUS_MPU_2 */
-#define OMAP4430_VC_MPU_VPACK_ST_SHIFT					(1 << 6)
+#define OMAP4430_VC_MPU_VPACK_ST_SHIFT					6
 #define OMAP4430_VC_MPU_VPACK_ST_MASK					BITFIELD(6, 6)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VC_RAERR_EN_SHIFT					(1 << 12)
+#define OMAP4430_VC_RAERR_EN_SHIFT					12
 #define OMAP4430_VC_RAERR_EN_MASK					BITFIELD(12, 12)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VC_RAERR_ST_SHIFT					(1 << 12)
+#define OMAP4430_VC_RAERR_ST_SHIFT					12
 #define OMAP4430_VC_RAERR_ST_MASK					BITFIELD(12, 12)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VC_SAERR_EN_SHIFT					(1 << 11)
+#define OMAP4430_VC_SAERR_EN_SHIFT					11
 #define OMAP4430_VC_SAERR_EN_MASK					BITFIELD(11, 11)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VC_SAERR_ST_SHIFT					(1 << 11)
+#define OMAP4430_VC_SAERR_ST_SHIFT					11
 #define OMAP4430_VC_SAERR_ST_MASK					BITFIELD(11, 11)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VC_TOERR_EN_SHIFT					(1 << 13)
+#define OMAP4430_VC_TOERR_EN_SHIFT					13
 #define OMAP4430_VC_TOERR_EN_MASK					BITFIELD(13, 13)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VC_TOERR_ST_SHIFT					(1 << 13)
+#define OMAP4430_VC_TOERR_ST_SHIFT					13
 #define OMAP4430_VC_TOERR_ST_MASK					BITFIELD(13, 13)
 
 /* Used by PRM_VP_CORE_VLIMITTO, PRM_VP_IVA_VLIMITTO, PRM_VP_MPU_VLIMITTO */
-#define OMAP4430_VDDMAX_SHIFT						(1 << 24)
+#define OMAP4430_VDDMAX_SHIFT						24
 #define OMAP4430_VDDMAX_MASK						BITFIELD(24, 31)
 
 /* Used by PRM_VP_CORE_VLIMITTO, PRM_VP_IVA_VLIMITTO, PRM_VP_MPU_VLIMITTO */
-#define OMAP4430_VDDMIN_SHIFT						(1 << 16)
+#define OMAP4430_VDDMIN_SHIFT						16
 #define OMAP4430_VDDMIN_MASK						BITFIELD(16, 23)
 
 /* Used by PRM_VOLTCTRL */
-#define OMAP4430_VDD_CORE_I2C_DISABLE_SHIFT				(1 << 12)
+#define OMAP4430_VDD_CORE_I2C_DISABLE_SHIFT				12
 #define OMAP4430_VDD_CORE_I2C_DISABLE_MASK				BITFIELD(12, 12)
 
 /* Used by PRM_RSTST */
-#define OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT				(1 << 8)
+#define OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT				8
 #define OMAP4430_VDD_CORE_VOLT_MGR_RST_MASK				BITFIELD(8, 8)
 
 /* Used by PRM_VOLTCTRL */
-#define OMAP4430_VDD_IVA_I2C_DISABLE_SHIFT				(1 << 14)
+#define OMAP4430_VDD_IVA_I2C_DISABLE_SHIFT				14
 #define OMAP4430_VDD_IVA_I2C_DISABLE_MASK				BITFIELD(14, 14)
 
 /* Used by PRM_VOLTCTRL */
-#define OMAP4430_VDD_IVA_PRESENCE_SHIFT					(1 << 9)
+#define OMAP4430_VDD_IVA_PRESENCE_SHIFT					9
 #define OMAP4430_VDD_IVA_PRESENCE_MASK					BITFIELD(9, 9)
 
 /* Used by PRM_RSTST */
-#define OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT				(1 << 7)
+#define OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT				7
 #define OMAP4430_VDD_IVA_VOLT_MGR_RST_MASK				BITFIELD(7, 7)
 
 /* Used by PRM_VOLTCTRL */
-#define OMAP4430_VDD_MPU_I2C_DISABLE_SHIFT				(1 << 13)
+#define OMAP4430_VDD_MPU_I2C_DISABLE_SHIFT				13
 #define OMAP4430_VDD_MPU_I2C_DISABLE_MASK				BITFIELD(13, 13)
 
 /* Used by PRM_VOLTCTRL */
-#define OMAP4430_VDD_MPU_PRESENCE_SHIFT					(1 << 8)
+#define OMAP4430_VDD_MPU_PRESENCE_SHIFT					8
 #define OMAP4430_VDD_MPU_PRESENCE_MASK					BITFIELD(8, 8)
 
 /* Used by PRM_RSTST */
-#define OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT				(1 << 6)
+#define OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT				6
 #define OMAP4430_VDD_MPU_VOLT_MGR_RST_MASK				BITFIELD(6, 6)
 
 /* Used by PRM_VC_VAL_SMPS_RA_VOL */
-#define OMAP4430_VOLRA_VDD_CORE_L_SHIFT					(1 << 0)
+#define OMAP4430_VOLRA_VDD_CORE_L_SHIFT					0
 #define OMAP4430_VOLRA_VDD_CORE_L_MASK					BITFIELD(0, 7)
 
 /* Used by PRM_VC_VAL_SMPS_RA_VOL */
-#define OMAP4430_VOLRA_VDD_IVA_L_SHIFT					(1 << 8)
+#define OMAP4430_VOLRA_VDD_IVA_L_SHIFT					8
 #define OMAP4430_VOLRA_VDD_IVA_L_MASK					BITFIELD(8, 15)
 
 /* Used by PRM_VC_VAL_SMPS_RA_VOL */
-#define OMAP4430_VOLRA_VDD_MPU_L_SHIFT					(1 << 16)
+#define OMAP4430_VOLRA_VDD_MPU_L_SHIFT					16
 #define OMAP4430_VOLRA_VDD_MPU_L_MASK					BITFIELD(16, 23)
 
 /* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
-#define OMAP4430_VPENABLE_SHIFT						(1 << 0)
+#define OMAP4430_VPENABLE_SHIFT						0
 #define OMAP4430_VPENABLE_MASK						BITFIELD(0, 0)
 
 /* Used by PRM_VP_CORE_STATUS, PRM_VP_IVA_STATUS, PRM_VP_MPU_STATUS */
-#define OMAP4430_VPINIDLE_SHIFT						(1 << 0)
+#define OMAP4430_VPINIDLE_SHIFT						0
 #define OMAP4430_VPINIDLE_MASK						BITFIELD(0, 0)
 
 /* Used by PRM_VP_CORE_VOLTAGE, PRM_VP_IVA_VOLTAGE, PRM_VP_MPU_VOLTAGE */
-#define OMAP4430_VPVOLTAGE_SHIFT					(1 << 0)
+#define OMAP4430_VPVOLTAGE_SHIFT					0
 #define OMAP4430_VPVOLTAGE_MASK						BITFIELD(0, 7)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VP_CORE_EQVALUE_EN_SHIFT				(1 << 20)
+#define OMAP4430_VP_CORE_EQVALUE_EN_SHIFT				20
 #define OMAP4430_VP_CORE_EQVALUE_EN_MASK				BITFIELD(20, 20)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VP_CORE_EQVALUE_ST_SHIFT				(1 << 20)
+#define OMAP4430_VP_CORE_EQVALUE_ST_SHIFT				20
 #define OMAP4430_VP_CORE_EQVALUE_ST_MASK				BITFIELD(20, 20)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VP_CORE_MAXVDD_EN_SHIFT				(1 << 18)
+#define OMAP4430_VP_CORE_MAXVDD_EN_SHIFT				18
 #define OMAP4430_VP_CORE_MAXVDD_EN_MASK					BITFIELD(18, 18)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VP_CORE_MAXVDD_ST_SHIFT				(1 << 18)
+#define OMAP4430_VP_CORE_MAXVDD_ST_SHIFT				18
 #define OMAP4430_VP_CORE_MAXVDD_ST_MASK					BITFIELD(18, 18)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VP_CORE_MINVDD_EN_SHIFT				(1 << 17)
+#define OMAP4430_VP_CORE_MINVDD_EN_SHIFT				17
 #define OMAP4430_VP_CORE_MINVDD_EN_MASK					BITFIELD(17, 17)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VP_CORE_MINVDD_ST_SHIFT				(1 << 17)
+#define OMAP4430_VP_CORE_MINVDD_ST_SHIFT				17
 #define OMAP4430_VP_CORE_MINVDD_ST_MASK					BITFIELD(17, 17)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VP_CORE_NOSMPSACK_EN_SHIFT				(1 << 19)
+#define OMAP4430_VP_CORE_NOSMPSACK_EN_SHIFT				19
 #define OMAP4430_VP_CORE_NOSMPSACK_EN_MASK				BITFIELD(19, 19)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VP_CORE_NOSMPSACK_ST_SHIFT				(1 << 19)
+#define OMAP4430_VP_CORE_NOSMPSACK_ST_SHIFT				19
 #define OMAP4430_VP_CORE_NOSMPSACK_ST_MASK				BITFIELD(19, 19)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VP_CORE_OPPCHANGEDONE_EN_SHIFT				(1 << 16)
+#define OMAP4430_VP_CORE_OPPCHANGEDONE_EN_SHIFT				16
 #define OMAP4430_VP_CORE_OPPCHANGEDONE_EN_MASK				BITFIELD(16, 16)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VP_CORE_OPPCHANGEDONE_ST_SHIFT				(1 << 16)
+#define OMAP4430_VP_CORE_OPPCHANGEDONE_ST_SHIFT				16
 #define OMAP4430_VP_CORE_OPPCHANGEDONE_ST_MASK				BITFIELD(16, 16)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VP_CORE_TRANXDONE_EN_SHIFT				(1 << 21)
+#define OMAP4430_VP_CORE_TRANXDONE_EN_SHIFT				21
 #define OMAP4430_VP_CORE_TRANXDONE_EN_MASK				BITFIELD(21, 21)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VP_CORE_TRANXDONE_ST_SHIFT				(1 << 21)
+#define OMAP4430_VP_CORE_TRANXDONE_ST_SHIFT				21
 #define OMAP4430_VP_CORE_TRANXDONE_ST_MASK				BITFIELD(21, 21)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VP_IVA_EQVALUE_EN_SHIFT				(1 << 28)
+#define OMAP4430_VP_IVA_EQVALUE_EN_SHIFT				28
 #define OMAP4430_VP_IVA_EQVALUE_EN_MASK					BITFIELD(28, 28)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VP_IVA_EQVALUE_ST_SHIFT				(1 << 28)
+#define OMAP4430_VP_IVA_EQVALUE_ST_SHIFT				28
 #define OMAP4430_VP_IVA_EQVALUE_ST_MASK					BITFIELD(28, 28)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VP_IVA_MAXVDD_EN_SHIFT					(1 << 26)
+#define OMAP4430_VP_IVA_MAXVDD_EN_SHIFT					26
 #define OMAP4430_VP_IVA_MAXVDD_EN_MASK					BITFIELD(26, 26)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VP_IVA_MAXVDD_ST_SHIFT					(1 << 26)
+#define OMAP4430_VP_IVA_MAXVDD_ST_SHIFT					26
 #define OMAP4430_VP_IVA_MAXVDD_ST_MASK					BITFIELD(26, 26)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VP_IVA_MINVDD_EN_SHIFT					(1 << 25)
+#define OMAP4430_VP_IVA_MINVDD_EN_SHIFT					25
 #define OMAP4430_VP_IVA_MINVDD_EN_MASK					BITFIELD(25, 25)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VP_IVA_MINVDD_ST_SHIFT					(1 << 25)
+#define OMAP4430_VP_IVA_MINVDD_ST_SHIFT					25
 #define OMAP4430_VP_IVA_MINVDD_ST_MASK					BITFIELD(25, 25)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VP_IVA_NOSMPSACK_EN_SHIFT				(1 << 27)
+#define OMAP4430_VP_IVA_NOSMPSACK_EN_SHIFT				27
 #define OMAP4430_VP_IVA_NOSMPSACK_EN_MASK				BITFIELD(27, 27)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VP_IVA_NOSMPSACK_ST_SHIFT				(1 << 27)
+#define OMAP4430_VP_IVA_NOSMPSACK_ST_SHIFT				27
 #define OMAP4430_VP_IVA_NOSMPSACK_ST_MASK				BITFIELD(27, 27)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VP_IVA_OPPCHANGEDONE_EN_SHIFT				(1 << 24)
+#define OMAP4430_VP_IVA_OPPCHANGEDONE_EN_SHIFT				24
 #define OMAP4430_VP_IVA_OPPCHANGEDONE_EN_MASK				BITFIELD(24, 24)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VP_IVA_OPPCHANGEDONE_ST_SHIFT				(1 << 24)
+#define OMAP4430_VP_IVA_OPPCHANGEDONE_ST_SHIFT				24
 #define OMAP4430_VP_IVA_OPPCHANGEDONE_ST_MASK				BITFIELD(24, 24)
 
 /* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
-#define OMAP4430_VP_IVA_TRANXDONE_EN_SHIFT				(1 << 29)
+#define OMAP4430_VP_IVA_TRANXDONE_EN_SHIFT				29
 #define OMAP4430_VP_IVA_TRANXDONE_EN_MASK				BITFIELD(29, 29)
 
 /* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
-#define OMAP4430_VP_IVA_TRANXDONE_ST_SHIFT				(1 << 29)
+#define OMAP4430_VP_IVA_TRANXDONE_ST_SHIFT				29
 #define OMAP4430_VP_IVA_TRANXDONE_ST_MASK				BITFIELD(29, 29)
 
 /* Used by PRM_IRQENABLE_MPU_2 */
-#define OMAP4430_VP_MPU_EQVALUE_EN_SHIFT				(1 << 4)
+#define OMAP4430_VP_MPU_EQVALUE_EN_SHIFT				4
 #define OMAP4430_VP_MPU_EQVALUE_EN_MASK					BITFIELD(4, 4)
 
 /* Used by PRM_IRQSTATUS_MPU_2 */
-#define OMAP4430_VP_MPU_EQVALUE_ST_SHIFT				(1 << 4)
+#define OMAP4430_VP_MPU_EQVALUE_ST_SHIFT				4
 #define OMAP4430_VP_MPU_EQVALUE_ST_MASK					BITFIELD(4, 4)
 
 /* Used by PRM_IRQENABLE_MPU_2 */
-#define OMAP4430_VP_MPU_MAXVDD_EN_SHIFT					(1 << 2)
+#define OMAP4430_VP_MPU_MAXVDD_EN_SHIFT					2
 #define OMAP4430_VP_MPU_MAXVDD_EN_MASK					BITFIELD(2, 2)
 
 /* Used by PRM_IRQSTATUS_MPU_2 */
-#define OMAP4430_VP_MPU_MAXVDD_ST_SHIFT					(1 << 2)
+#define OMAP4430_VP_MPU_MAXVDD_ST_SHIFT					2
 #define OMAP4430_VP_MPU_MAXVDD_ST_MASK					BITFIELD(2, 2)
 
 /* Used by PRM_IRQENABLE_MPU_2 */
-#define OMAP4430_VP_MPU_MINVDD_EN_SHIFT					(1 << 1)
+#define OMAP4430_VP_MPU_MINVDD_EN_SHIFT					1
 #define OMAP4430_VP_MPU_MINVDD_EN_MASK					BITFIELD(1, 1)
 
 /* Used by PRM_IRQSTATUS_MPU_2 */
-#define OMAP4430_VP_MPU_MINVDD_ST_SHIFT					(1 << 1)
+#define OMAP4430_VP_MPU_MINVDD_ST_SHIFT					1
 #define OMAP4430_VP_MPU_MINVDD_ST_MASK					BITFIELD(1, 1)
 
 /* Used by PRM_IRQENABLE_MPU_2 */
-#define OMAP4430_VP_MPU_NOSMPSACK_EN_SHIFT				(1 << 3)
+#define OMAP4430_VP_MPU_NOSMPSACK_EN_SHIFT				3
 #define OMAP4430_VP_MPU_NOSMPSACK_EN_MASK				BITFIELD(3, 3)
 
 /* Used by PRM_IRQSTATUS_MPU_2 */
-#define OMAP4430_VP_MPU_NOSMPSACK_ST_SHIFT				(1 << 3)
+#define OMAP4430_VP_MPU_NOSMPSACK_ST_SHIFT				3
 #define OMAP4430_VP_MPU_NOSMPSACK_ST_MASK				BITFIELD(3, 3)
 
 /* Used by PRM_IRQENABLE_MPU_2 */
-#define OMAP4430_VP_MPU_OPPCHANGEDONE_EN_SHIFT				(1 << 0)
+#define OMAP4430_VP_MPU_OPPCHANGEDONE_EN_SHIFT				0
 #define OMAP4430_VP_MPU_OPPCHANGEDONE_EN_MASK				BITFIELD(0, 0)
 
 /* Used by PRM_IRQSTATUS_MPU_2 */
-#define OMAP4430_VP_MPU_OPPCHANGEDONE_ST_SHIFT				(1 << 0)
+#define OMAP4430_VP_MPU_OPPCHANGEDONE_ST_SHIFT				0
 #define OMAP4430_VP_MPU_OPPCHANGEDONE_ST_MASK				BITFIELD(0, 0)
 
 /* Used by PRM_IRQENABLE_MPU_2 */
-#define OMAP4430_VP_MPU_TRANXDONE_EN_SHIFT				(1 << 5)
+#define OMAP4430_VP_MPU_TRANXDONE_EN_SHIFT				5
 #define OMAP4430_VP_MPU_TRANXDONE_EN_MASK				BITFIELD(5, 5)
 
 /* Used by PRM_IRQSTATUS_MPU_2 */
-#define OMAP4430_VP_MPU_TRANXDONE_ST_SHIFT				(1 << 5)
+#define OMAP4430_VP_MPU_TRANXDONE_ST_SHIFT				5
 #define OMAP4430_VP_MPU_TRANXDONE_ST_MASK				BITFIELD(5, 5)
 
 /* Used by PRM_SRAM_COUNT */
-#define OMAP4430_VSETUPCNT_VALUE_SHIFT					(1 << 8)
+#define OMAP4430_VSETUPCNT_VALUE_SHIFT					8
 #define OMAP4430_VSETUPCNT_VALUE_MASK					BITFIELD(8, 15)
 
 /* Used by PRM_VP_CORE_VSTEPMAX, PRM_VP_IVA_VSTEPMAX, PRM_VP_MPU_VSTEPMAX */
-#define OMAP4430_VSTEPMAX_SHIFT						(1 << 0)
+#define OMAP4430_VSTEPMAX_SHIFT						0
 #define OMAP4430_VSTEPMAX_MASK						BITFIELD(0, 7)
 
 /* Used by PRM_VP_CORE_VSTEPMIN, PRM_VP_IVA_VSTEPMIN, PRM_VP_MPU_VSTEPMIN */
-#define OMAP4430_VSTEPMIN_SHIFT						(1 << 0)
+#define OMAP4430_VSTEPMIN_SHIFT						0
 #define OMAP4430_VSTEPMIN_MASK						BITFIELD(0, 7)
 
 /* Used by PRM_MODEM_IF_CTRL */
-#define OMAP4430_WAKE_MODEM_SHIFT					(1 << 0)
+#define OMAP4430_WAKE_MODEM_SHIFT					0
 #define OMAP4430_WAKE_MODEM_MASK					BITFIELD(0, 0)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_DISPC_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_DISPC_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_DISPC_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_DISPC_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DISPC_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_DISPC_MPU_MASK					BITFIELD(0, 0)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_DISPC_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_DISPC_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_DISPC_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_DISPC_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_DISPC_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_DISPC_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_ABE_DMIC_WKDEP */
-#define OMAP4430_WKUPDEP_DMIC_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_DMIC_DMA_SDMA_SHIFT				7
 #define OMAP4430_WKUPDEP_DMIC_DMA_SDMA_MASK				BITFIELD(7, 7)
 
 /* Used by PM_ABE_DMIC_WKDEP */
-#define OMAP4430_WKUPDEP_DMIC_DMA_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_DMIC_DMA_TESLA_SHIFT				6
 #define OMAP4430_WKUPDEP_DMIC_DMA_TESLA_MASK				BITFIELD(6, 6)
 
 /* Used by PM_ABE_DMIC_WKDEP */
-#define OMAP4430_WKUPDEP_DMIC_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DMIC_IRQ_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_DMIC_IRQ_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_ABE_DMIC_WKDEP */
-#define OMAP4430_WKUPDEP_DMIC_IRQ_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_DMIC_IRQ_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_DMIC_IRQ_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_L4PER_DMTIMER10_WKDEP */
-#define OMAP4430_WKUPDEP_DMTIMER10_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DMTIMER10_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_DMTIMER10_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_DMTIMER11_WKDEP */
-#define OMAP4430_WKUPDEP_DMTIMER11_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_DMTIMER11_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_DMTIMER11_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L4PER_DMTIMER11_WKDEP */
-#define OMAP4430_WKUPDEP_DMTIMER11_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DMTIMER11_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_DMTIMER11_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_DMTIMER2_WKDEP */
-#define OMAP4430_WKUPDEP_DMTIMER2_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DMTIMER2_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_DMTIMER2_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_DMTIMER3_WKDEP */
-#define OMAP4430_WKUPDEP_DMTIMER3_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_DMTIMER3_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_DMTIMER3_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L4PER_DMTIMER3_WKDEP */
-#define OMAP4430_WKUPDEP_DMTIMER3_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DMTIMER3_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_DMTIMER3_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_DMTIMER4_WKDEP */
-#define OMAP4430_WKUPDEP_DMTIMER4_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_DMTIMER4_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_DMTIMER4_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L4PER_DMTIMER4_WKDEP */
-#define OMAP4430_WKUPDEP_DMTIMER4_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DMTIMER4_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_DMTIMER4_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_DMTIMER9_WKDEP */
-#define OMAP4430_WKUPDEP_DMTIMER9_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_DMTIMER9_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_DMTIMER9_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L4PER_DMTIMER9_WKDEP */
-#define OMAP4430_WKUPDEP_DMTIMER9_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DMTIMER9_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_DMTIMER9_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_DSI1_DUCATI_SHIFT				(1 << 5)
+#define OMAP4430_WKUPDEP_DSI1_DUCATI_SHIFT				5
 #define OMAP4430_WKUPDEP_DSI1_DUCATI_MASK				BITFIELD(5, 5)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_DSI1_MPU_SHIFT					(1 << 4)
+#define OMAP4430_WKUPDEP_DSI1_MPU_SHIFT					4
 #define OMAP4430_WKUPDEP_DSI1_MPU_MASK					BITFIELD(4, 4)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_DSI1_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_DSI1_SDMA_SHIFT				7
 #define OMAP4430_WKUPDEP_DSI1_SDMA_MASK					BITFIELD(7, 7)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_DSI1_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_DSI1_TESLA_SHIFT				6
 #define OMAP4430_WKUPDEP_DSI1_TESLA_MASK				BITFIELD(6, 6)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_DSI2_DUCATI_SHIFT				(1 << 9)
+#define OMAP4430_WKUPDEP_DSI2_DUCATI_SHIFT				9
 #define OMAP4430_WKUPDEP_DSI2_DUCATI_MASK				BITFIELD(9, 9)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_DSI2_MPU_SHIFT					(1 << 8)
+#define OMAP4430_WKUPDEP_DSI2_MPU_SHIFT					8
 #define OMAP4430_WKUPDEP_DSI2_MPU_MASK					BITFIELD(8, 8)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_DSI2_SDMA_SHIFT				(1 << 11)
+#define OMAP4430_WKUPDEP_DSI2_SDMA_SHIFT				11
 #define OMAP4430_WKUPDEP_DSI2_SDMA_MASK					BITFIELD(11, 11)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_DSI2_TESLA_SHIFT				(1 << 10)
+#define OMAP4430_WKUPDEP_DSI2_TESLA_SHIFT				10
 #define OMAP4430_WKUPDEP_DSI2_TESLA_MASK				BITFIELD(10, 10)
 
 /* Used by PM_WKUP_GPIO1_WKDEP */
-#define OMAP4430_WKUPDEP_GPIO1_IRQ1_DUCATI_SHIFT			(1 << 1)
+#define OMAP4430_WKUPDEP_GPIO1_IRQ1_DUCATI_SHIFT			1
 #define OMAP4430_WKUPDEP_GPIO1_IRQ1_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_WKUP_GPIO1_WKDEP */
-#define OMAP4430_WKUPDEP_GPIO1_IRQ1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_GPIO1_IRQ1_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_GPIO1_IRQ1_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_WKUP_GPIO1_WKDEP */
-#define OMAP4430_WKUPDEP_GPIO1_IRQ2_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_GPIO1_IRQ2_TESLA_SHIFT				6
 #define OMAP4430_WKUPDEP_GPIO1_IRQ2_TESLA_MASK				BITFIELD(6, 6)
 
 /* Used by PM_L4PER_GPIO2_WKDEP */
-#define OMAP4430_WKUPDEP_GPIO2_IRQ1_DUCATI_SHIFT			(1 << 1)
+#define OMAP4430_WKUPDEP_GPIO2_IRQ1_DUCATI_SHIFT			1
 #define OMAP4430_WKUPDEP_GPIO2_IRQ1_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L4PER_GPIO2_WKDEP */
-#define OMAP4430_WKUPDEP_GPIO2_IRQ1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_GPIO2_IRQ1_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_GPIO2_IRQ1_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_GPIO2_WKDEP */
-#define OMAP4430_WKUPDEP_GPIO2_IRQ2_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_GPIO2_IRQ2_TESLA_SHIFT				6
 #define OMAP4430_WKUPDEP_GPIO2_IRQ2_TESLA_MASK				BITFIELD(6, 6)
 
 /* Used by PM_L4PER_GPIO3_WKDEP */
-#define OMAP4430_WKUPDEP_GPIO3_IRQ1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_GPIO3_IRQ1_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_GPIO3_IRQ1_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_GPIO3_WKDEP */
-#define OMAP4430_WKUPDEP_GPIO3_IRQ2_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_GPIO3_IRQ2_TESLA_SHIFT				6
 #define OMAP4430_WKUPDEP_GPIO3_IRQ2_TESLA_MASK				BITFIELD(6, 6)
 
 /* Used by PM_L4PER_GPIO4_WKDEP */
-#define OMAP4430_WKUPDEP_GPIO4_IRQ1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_GPIO4_IRQ1_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_GPIO4_IRQ1_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_GPIO4_WKDEP */
-#define OMAP4430_WKUPDEP_GPIO4_IRQ2_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_GPIO4_IRQ2_TESLA_SHIFT				6
 #define OMAP4430_WKUPDEP_GPIO4_IRQ2_TESLA_MASK				BITFIELD(6, 6)
 
 /* Used by PM_L4PER_GPIO5_WKDEP */
-#define OMAP4430_WKUPDEP_GPIO5_IRQ1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_GPIO5_IRQ1_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_GPIO5_IRQ1_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_GPIO5_WKDEP */
-#define OMAP4430_WKUPDEP_GPIO5_IRQ2_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_GPIO5_IRQ2_TESLA_SHIFT				6
 #define OMAP4430_WKUPDEP_GPIO5_IRQ2_TESLA_MASK				BITFIELD(6, 6)
 
 /* Used by PM_L4PER_GPIO6_WKDEP */
-#define OMAP4430_WKUPDEP_GPIO6_IRQ1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_GPIO6_IRQ1_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_GPIO6_IRQ1_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_GPIO6_WKDEP */
-#define OMAP4430_WKUPDEP_GPIO6_IRQ2_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_GPIO6_IRQ2_TESLA_SHIFT				6
 #define OMAP4430_WKUPDEP_GPIO6_IRQ2_TESLA_MASK				BITFIELD(6, 6)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_HDMIDMA_SDMA_SHIFT				(1 << 19)
+#define OMAP4430_WKUPDEP_HDMIDMA_SDMA_SHIFT				19
 #define OMAP4430_WKUPDEP_HDMIDMA_SDMA_MASK				BITFIELD(19, 19)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_HDMIIRQ_DUCATI_SHIFT				(1 << 13)
+#define OMAP4430_WKUPDEP_HDMIIRQ_DUCATI_SHIFT				13
 #define OMAP4430_WKUPDEP_HDMIIRQ_DUCATI_MASK				BITFIELD(13, 13)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_HDMIIRQ_MPU_SHIFT				(1 << 12)
+#define OMAP4430_WKUPDEP_HDMIIRQ_MPU_SHIFT				12
 #define OMAP4430_WKUPDEP_HDMIIRQ_MPU_MASK				BITFIELD(12, 12)
 
 /* Used by PM_DSS_DSS_WKDEP */
-#define OMAP4430_WKUPDEP_HDMIIRQ_TESLA_SHIFT				(1 << 14)
+#define OMAP4430_WKUPDEP_HDMIIRQ_TESLA_SHIFT				14
 #define OMAP4430_WKUPDEP_HDMIIRQ_TESLA_MASK				BITFIELD(14, 14)
 
 /* Used by PM_L4PER_HECC1_WKDEP */
-#define OMAP4430_WKUPDEP_HECC1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_HECC1_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_HECC1_MPU_MASK					BITFIELD(0, 0)
 
 /* Used by PM_L4PER_HECC2_WKDEP */
-#define OMAP4430_WKUPDEP_HECC2_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_HECC2_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_HECC2_MPU_MASK					BITFIELD(0, 0)
 
 /* Used by PM_L3INIT_HSI_WKDEP */
-#define OMAP4430_WKUPDEP_HSI_DSP_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_HSI_DSP_TESLA_SHIFT				6
 #define OMAP4430_WKUPDEP_HSI_DSP_TESLA_MASK				BITFIELD(6, 6)
 
 /* Used by PM_L3INIT_HSI_WKDEP */
-#define OMAP4430_WKUPDEP_HSI_MCU_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_HSI_MCU_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_HSI_MCU_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L3INIT_HSI_WKDEP */
-#define OMAP4430_WKUPDEP_HSI_MCU_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_HSI_MCU_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_HSI_MCU_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_I2C1_WKDEP */
-#define OMAP4430_WKUPDEP_I2C1_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_I2C1_DMA_SDMA_SHIFT				7
 #define OMAP4430_WKUPDEP_I2C1_DMA_SDMA_MASK				BITFIELD(7, 7)
 
 /* Used by PM_L4PER_I2C1_WKDEP */
-#define OMAP4430_WKUPDEP_I2C1_IRQ_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_I2C1_IRQ_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_I2C1_IRQ_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L4PER_I2C1_WKDEP */
-#define OMAP4430_WKUPDEP_I2C1_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_I2C1_IRQ_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_I2C1_IRQ_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_I2C2_WKDEP */
-#define OMAP4430_WKUPDEP_I2C2_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_I2C2_DMA_SDMA_SHIFT				7
 #define OMAP4430_WKUPDEP_I2C2_DMA_SDMA_MASK				BITFIELD(7, 7)
 
 /* Used by PM_L4PER_I2C2_WKDEP */
-#define OMAP4430_WKUPDEP_I2C2_IRQ_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_I2C2_IRQ_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_I2C2_IRQ_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L4PER_I2C2_WKDEP */
-#define OMAP4430_WKUPDEP_I2C2_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_I2C2_IRQ_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_I2C2_IRQ_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_I2C3_WKDEP */
-#define OMAP4430_WKUPDEP_I2C3_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_I2C3_DMA_SDMA_SHIFT				7
 #define OMAP4430_WKUPDEP_I2C3_DMA_SDMA_MASK				BITFIELD(7, 7)
 
 /* Used by PM_L4PER_I2C3_WKDEP */
-#define OMAP4430_WKUPDEP_I2C3_IRQ_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_I2C3_IRQ_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_I2C3_IRQ_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L4PER_I2C3_WKDEP */
-#define OMAP4430_WKUPDEP_I2C3_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_I2C3_IRQ_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_I2C3_IRQ_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_I2C4_WKDEP */
-#define OMAP4430_WKUPDEP_I2C4_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_I2C4_DMA_SDMA_SHIFT				7
 #define OMAP4430_WKUPDEP_I2C4_DMA_SDMA_MASK				BITFIELD(7, 7)
 
 /* Used by PM_L4PER_I2C4_WKDEP */
-#define OMAP4430_WKUPDEP_I2C4_IRQ_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_I2C4_IRQ_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_I2C4_IRQ_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L4PER_I2C4_WKDEP */
-#define OMAP4430_WKUPDEP_I2C4_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_I2C4_IRQ_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_I2C4_IRQ_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_I2C5_WKDEP */
-#define OMAP4430_WKUPDEP_I2C5_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_I2C5_DMA_SDMA_SHIFT				7
 #define OMAP4430_WKUPDEP_I2C5_DMA_SDMA_MASK				BITFIELD(7, 7)
 
 /* Used by PM_L4PER_I2C5_WKDEP */
-#define OMAP4430_WKUPDEP_I2C5_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_I2C5_IRQ_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_I2C5_IRQ_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_WKUP_KEYBOARD_WKDEP */
-#define OMAP4430_WKUPDEP_KEYBOARD_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_KEYBOARD_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_KEYBOARD_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_ABE_MCASP_WKDEP */
-#define OMAP4430_WKUPDEP_MCASP1_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_MCASP1_DMA_SDMA_SHIFT				7
 #define OMAP4430_WKUPDEP_MCASP1_DMA_SDMA_MASK				BITFIELD(7, 7)
 
 /* Used by PM_ABE_MCASP_WKDEP */
-#define OMAP4430_WKUPDEP_MCASP1_DMA_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_MCASP1_DMA_TESLA_SHIFT				6
 #define OMAP4430_WKUPDEP_MCASP1_DMA_TESLA_MASK				BITFIELD(6, 6)
 
 /* Used by PM_ABE_MCASP_WKDEP */
-#define OMAP4430_WKUPDEP_MCASP1_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCASP1_IRQ_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_MCASP1_IRQ_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_ABE_MCASP_WKDEP */
-#define OMAP4430_WKUPDEP_MCASP1_IRQ_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCASP1_IRQ_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_MCASP1_IRQ_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_L4PER_MCASP2_WKDEP */
-#define OMAP4430_WKUPDEP_MCASP2_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_MCASP2_DMA_SDMA_SHIFT				7
 #define OMAP4430_WKUPDEP_MCASP2_DMA_SDMA_MASK				BITFIELD(7, 7)
 
 /* Used by PM_L4PER_MCASP2_WKDEP */
-#define OMAP4430_WKUPDEP_MCASP2_DMA_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_MCASP2_DMA_TESLA_SHIFT				6
 #define OMAP4430_WKUPDEP_MCASP2_DMA_TESLA_MASK				BITFIELD(6, 6)
 
 /* Used by PM_L4PER_MCASP2_WKDEP */
-#define OMAP4430_WKUPDEP_MCASP2_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCASP2_IRQ_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_MCASP2_IRQ_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_MCASP2_WKDEP */
-#define OMAP4430_WKUPDEP_MCASP2_IRQ_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCASP2_IRQ_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_MCASP2_IRQ_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_L4PER_MCASP3_WKDEP */
-#define OMAP4430_WKUPDEP_MCASP3_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_MCASP3_DMA_SDMA_SHIFT				7
 #define OMAP4430_WKUPDEP_MCASP3_DMA_SDMA_MASK				BITFIELD(7, 7)
 
 /* Used by PM_L4PER_MCASP3_WKDEP */
-#define OMAP4430_WKUPDEP_MCASP3_DMA_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_MCASP3_DMA_TESLA_SHIFT				6
 #define OMAP4430_WKUPDEP_MCASP3_DMA_TESLA_MASK				BITFIELD(6, 6)
 
 /* Used by PM_L4PER_MCASP3_WKDEP */
-#define OMAP4430_WKUPDEP_MCASP3_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCASP3_IRQ_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_MCASP3_IRQ_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_MCASP3_WKDEP */
-#define OMAP4430_WKUPDEP_MCASP3_IRQ_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCASP3_IRQ_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_MCASP3_IRQ_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_ABE_MCBSP1_WKDEP */
-#define OMAP4430_WKUPDEP_MCBSP1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCBSP1_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_MCBSP1_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_ABE_MCBSP1_WKDEP */
-#define OMAP4430_WKUPDEP_MCBSP1_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCBSP1_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_MCBSP1_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_ABE_MCBSP1_WKDEP */
-#define OMAP4430_WKUPDEP_MCBSP1_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCBSP1_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_MCBSP1_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_ABE_MCBSP2_WKDEP */
-#define OMAP4430_WKUPDEP_MCBSP2_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCBSP2_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_MCBSP2_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_ABE_MCBSP2_WKDEP */
-#define OMAP4430_WKUPDEP_MCBSP2_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCBSP2_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_MCBSP2_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_ABE_MCBSP2_WKDEP */
-#define OMAP4430_WKUPDEP_MCBSP2_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCBSP2_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_MCBSP2_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_ABE_MCBSP3_WKDEP */
-#define OMAP4430_WKUPDEP_MCBSP3_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCBSP3_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_MCBSP3_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_ABE_MCBSP3_WKDEP */
-#define OMAP4430_WKUPDEP_MCBSP3_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCBSP3_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_MCBSP3_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_ABE_MCBSP3_WKDEP */
-#define OMAP4430_WKUPDEP_MCBSP3_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCBSP3_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_MCBSP3_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_L4PER_MCBSP4_WKDEP */
-#define OMAP4430_WKUPDEP_MCBSP4_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCBSP4_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_MCBSP4_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_MCBSP4_WKDEP */
-#define OMAP4430_WKUPDEP_MCBSP4_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCBSP4_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_MCBSP4_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_L4PER_MCBSP4_WKDEP */
-#define OMAP4430_WKUPDEP_MCBSP4_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCBSP4_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_MCBSP4_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_L4PER_MCSPI1_WKDEP */
-#define OMAP4430_WKUPDEP_MCSPI1_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MCSPI1_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_MCSPI1_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L4PER_MCSPI1_WKDEP */
-#define OMAP4430_WKUPDEP_MCSPI1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCSPI1_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_MCSPI1_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_MCSPI1_WKDEP */
-#define OMAP4430_WKUPDEP_MCSPI1_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCSPI1_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_MCSPI1_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_L4PER_MCSPI1_WKDEP */
-#define OMAP4430_WKUPDEP_MCSPI1_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCSPI1_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_MCSPI1_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_L4PER_MCSPI2_WKDEP */
-#define OMAP4430_WKUPDEP_MCSPI2_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MCSPI2_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_MCSPI2_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L4PER_MCSPI2_WKDEP */
-#define OMAP4430_WKUPDEP_MCSPI2_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCSPI2_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_MCSPI2_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_MCSPI2_WKDEP */
-#define OMAP4430_WKUPDEP_MCSPI2_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCSPI2_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_MCSPI2_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_L4PER_MCSPI3_WKDEP */
-#define OMAP4430_WKUPDEP_MCSPI3_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCSPI3_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_MCSPI3_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_MCSPI3_WKDEP */
-#define OMAP4430_WKUPDEP_MCSPI3_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCSPI3_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_MCSPI3_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_L4PER_MCSPI4_WKDEP */
-#define OMAP4430_WKUPDEP_MCSPI4_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCSPI4_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_MCSPI4_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_MCSPI4_WKDEP */
-#define OMAP4430_WKUPDEP_MCSPI4_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCSPI4_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_MCSPI4_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_L3INIT_MMC1_WKDEP */
-#define OMAP4430_WKUPDEP_MMC1_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MMC1_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_MMC1_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L3INIT_MMC1_WKDEP */
-#define OMAP4430_WKUPDEP_MMC1_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_MMC1_MPU_SHIFT					0
 #define OMAP4430_WKUPDEP_MMC1_MPU_MASK					BITFIELD(0, 0)
 
 /* Used by PM_L3INIT_MMC1_WKDEP */
-#define OMAP4430_WKUPDEP_MMC1_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MMC1_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_MMC1_SDMA_MASK					BITFIELD(3, 3)
 
 /* Used by PM_L3INIT_MMC1_WKDEP */
-#define OMAP4430_WKUPDEP_MMC1_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MMC1_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_MMC1_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_L3INIT_MMC2_WKDEP */
-#define OMAP4430_WKUPDEP_MMC2_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MMC2_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_MMC2_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L3INIT_MMC2_WKDEP */
-#define OMAP4430_WKUPDEP_MMC2_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_MMC2_MPU_SHIFT					0
 #define OMAP4430_WKUPDEP_MMC2_MPU_MASK					BITFIELD(0, 0)
 
 /* Used by PM_L3INIT_MMC2_WKDEP */
-#define OMAP4430_WKUPDEP_MMC2_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MMC2_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_MMC2_SDMA_MASK					BITFIELD(3, 3)
 
 /* Used by PM_L3INIT_MMC2_WKDEP */
-#define OMAP4430_WKUPDEP_MMC2_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MMC2_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_MMC2_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_L3INIT_MMC6_WKDEP */
-#define OMAP4430_WKUPDEP_MMC6_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MMC6_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_MMC6_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L3INIT_MMC6_WKDEP */
-#define OMAP4430_WKUPDEP_MMC6_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_MMC6_MPU_SHIFT					0
 #define OMAP4430_WKUPDEP_MMC6_MPU_MASK					BITFIELD(0, 0)
 
 /* Used by PM_L3INIT_MMC6_WKDEP */
-#define OMAP4430_WKUPDEP_MMC6_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MMC6_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_MMC6_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_L4PER_MMCSD3_WKDEP */
-#define OMAP4430_WKUPDEP_MMCSD3_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MMCSD3_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_MMCSD3_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L4PER_MMCSD3_WKDEP */
-#define OMAP4430_WKUPDEP_MMCSD3_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MMCSD3_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_MMCSD3_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_MMCSD3_WKDEP */
-#define OMAP4430_WKUPDEP_MMCSD3_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MMCSD3_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_MMCSD3_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_L4PER_MMCSD4_WKDEP */
-#define OMAP4430_WKUPDEP_MMCSD4_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MMCSD4_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_MMCSD4_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L4PER_MMCSD4_WKDEP */
-#define OMAP4430_WKUPDEP_MMCSD4_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MMCSD4_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_MMCSD4_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_MMCSD4_WKDEP */
-#define OMAP4430_WKUPDEP_MMCSD4_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MMCSD4_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_MMCSD4_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_L4PER_MMCSD5_WKDEP */
-#define OMAP4430_WKUPDEP_MMCSD5_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MMCSD5_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_MMCSD5_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L4PER_MMCSD5_WKDEP */
-#define OMAP4430_WKUPDEP_MMCSD5_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MMCSD5_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_MMCSD5_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_MMCSD5_WKDEP */
-#define OMAP4430_WKUPDEP_MMCSD5_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MMCSD5_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_MMCSD5_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_L3INIT_PCIESS_WKDEP */
-#define OMAP4430_WKUPDEP_PCIESS_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_PCIESS_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_PCIESS_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L3INIT_PCIESS_WKDEP */
-#define OMAP4430_WKUPDEP_PCIESS_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_PCIESS_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_PCIESS_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_ABE_PDM_WKDEP */
-#define OMAP4430_WKUPDEP_PDM_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_PDM_DMA_SDMA_SHIFT				7
 #define OMAP4430_WKUPDEP_PDM_DMA_SDMA_MASK				BITFIELD(7, 7)
 
 /* Used by PM_ABE_PDM_WKDEP */
-#define OMAP4430_WKUPDEP_PDM_DMA_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_PDM_DMA_TESLA_SHIFT				6
 #define OMAP4430_WKUPDEP_PDM_DMA_TESLA_MASK				BITFIELD(6, 6)
 
 /* Used by PM_ABE_PDM_WKDEP */
-#define OMAP4430_WKUPDEP_PDM_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_PDM_IRQ_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_PDM_IRQ_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_ABE_PDM_WKDEP */
-#define OMAP4430_WKUPDEP_PDM_IRQ_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_PDM_IRQ_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_PDM_IRQ_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_WKUP_RTC_WKDEP */
-#define OMAP4430_WKUPDEP_RTC_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_RTC_MPU_SHIFT					0
 #define OMAP4430_WKUPDEP_RTC_MPU_MASK					BITFIELD(0, 0)
 
 /* Used by PM_L3INIT_SATA_WKDEP */
-#define OMAP4430_WKUPDEP_SATA_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_SATA_MPU_SHIFT					0
 #define OMAP4430_WKUPDEP_SATA_MPU_MASK					BITFIELD(0, 0)
 
 /* Used by PM_L3INIT_SATA_WKDEP */
-#define OMAP4430_WKUPDEP_SATA_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_SATA_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_SATA_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_ABE_SLIMBUS_WKDEP */
-#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_SDMA_SHIFT			(1 << 7)
+#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_SDMA_SHIFT			7
 #define OMAP4430_WKUPDEP_SLIMBUS1_DMA_SDMA_MASK				BITFIELD(7, 7)
 
 /* Used by PM_ABE_SLIMBUS_WKDEP */
-#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_TESLA_SHIFT			(1 << 6)
+#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_TESLA_SHIFT			6
 #define OMAP4430_WKUPDEP_SLIMBUS1_DMA_TESLA_MASK			BITFIELD(6, 6)
 
 /* Used by PM_ABE_SLIMBUS_WKDEP */
-#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_ABE_SLIMBUS_WKDEP */
-#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_TESLA_SHIFT			(1 << 2)
+#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_TESLA_SHIFT			2
 #define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_TESLA_MASK			BITFIELD(2, 2)
 
 /* Used by PM_L4PER_SLIMBUS2_WKDEP */
-#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_SDMA_SHIFT			(1 << 7)
+#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_SDMA_SHIFT			7
 #define OMAP4430_WKUPDEP_SLIMBUS2_DMA_SDMA_MASK				BITFIELD(7, 7)
 
 /* Used by PM_L4PER_SLIMBUS2_WKDEP */
-#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_TESLA_SHIFT			(1 << 6)
+#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_TESLA_SHIFT			6
 #define OMAP4430_WKUPDEP_SLIMBUS2_DMA_TESLA_MASK			BITFIELD(6, 6)
 
 /* Used by PM_L4PER_SLIMBUS2_WKDEP */
-#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L4PER_SLIMBUS2_WKDEP */
-#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_TESLA_SHIFT			(1 << 2)
+#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_TESLA_SHIFT			2
 #define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_TESLA_MASK			BITFIELD(2, 2)
 
 /* Used by PM_ALWON_SR_CORE_WKDEP */
-#define OMAP4430_WKUPDEP_SR_CORE_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_SR_CORE_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_SR_CORE_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_ALWON_SR_CORE_WKDEP */
-#define OMAP4430_WKUPDEP_SR_CORE_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_SR_CORE_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_SR_CORE_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_ALWON_SR_IVA_WKDEP */
-#define OMAP4430_WKUPDEP_SR_IVA_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_SR_IVA_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_SR_IVA_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_ALWON_SR_IVA_WKDEP */
-#define OMAP4430_WKUPDEP_SR_IVA_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_SR_IVA_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_SR_IVA_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_ALWON_SR_MPU_WKDEP */
-#define OMAP4430_WKUPDEP_SR_MPU_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_SR_MPU_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_SR_MPU_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_WKUP_TIMER12_WKDEP */
-#define OMAP4430_WKUPDEP_TIMER12_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_TIMER12_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_TIMER12_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_WKUP_TIMER1_WKDEP */
-#define OMAP4430_WKUPDEP_TIMER1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_TIMER1_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_TIMER1_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_ABE_TIMER5_WKDEP */
-#define OMAP4430_WKUPDEP_TIMER5_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_TIMER5_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_TIMER5_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_ABE_TIMER5_WKDEP */
-#define OMAP4430_WKUPDEP_TIMER5_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_TIMER5_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_TIMER5_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_ABE_TIMER6_WKDEP */
-#define OMAP4430_WKUPDEP_TIMER6_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_TIMER6_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_TIMER6_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_ABE_TIMER6_WKDEP */
-#define OMAP4430_WKUPDEP_TIMER6_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_TIMER6_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_TIMER6_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_ABE_TIMER7_WKDEP */
-#define OMAP4430_WKUPDEP_TIMER7_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_TIMER7_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_TIMER7_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_ABE_TIMER7_WKDEP */
-#define OMAP4430_WKUPDEP_TIMER7_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_TIMER7_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_TIMER7_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_ABE_TIMER8_WKDEP */
-#define OMAP4430_WKUPDEP_TIMER8_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_TIMER8_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_TIMER8_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_ABE_TIMER8_WKDEP */
-#define OMAP4430_WKUPDEP_TIMER8_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_TIMER8_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_TIMER8_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_L4PER_UART1_WKDEP */
-#define OMAP4430_WKUPDEP_UART1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_UART1_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_UART1_MPU_MASK					BITFIELD(0, 0)
 
 /* Used by PM_L4PER_UART1_WKDEP */
-#define OMAP4430_WKUPDEP_UART1_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_UART1_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_UART1_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_L4PER_UART2_WKDEP */
-#define OMAP4430_WKUPDEP_UART2_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_UART2_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_UART2_MPU_MASK					BITFIELD(0, 0)
 
 /* Used by PM_L4PER_UART2_WKDEP */
-#define OMAP4430_WKUPDEP_UART2_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_UART2_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_UART2_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_L4PER_UART3_WKDEP */
-#define OMAP4430_WKUPDEP_UART3_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_UART3_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_UART3_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L4PER_UART3_WKDEP */
-#define OMAP4430_WKUPDEP_UART3_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_UART3_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_UART3_MPU_MASK					BITFIELD(0, 0)
 
 /* Used by PM_L4PER_UART3_WKDEP */
-#define OMAP4430_WKUPDEP_UART3_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_UART3_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_UART3_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_L4PER_UART3_WKDEP */
-#define OMAP4430_WKUPDEP_UART3_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_UART3_TESLA_SHIFT				2
 #define OMAP4430_WKUPDEP_UART3_TESLA_MASK				BITFIELD(2, 2)
 
 /* Used by PM_L4PER_UART4_WKDEP */
-#define OMAP4430_WKUPDEP_UART4_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_UART4_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_UART4_MPU_MASK					BITFIELD(0, 0)
 
 /* Used by PM_L4PER_UART4_WKDEP */
-#define OMAP4430_WKUPDEP_UART4_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_UART4_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_UART4_SDMA_MASK				BITFIELD(3, 3)
 
 /* Used by PM_L3INIT_UNIPRO1_WKDEP */
-#define OMAP4430_WKUPDEP_UNIPRO1_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_UNIPRO1_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_UNIPRO1_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L3INIT_UNIPRO1_WKDEP */
-#define OMAP4430_WKUPDEP_UNIPRO1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_UNIPRO1_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_UNIPRO1_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L3INIT_USB_HOST_WKDEP */
-#define OMAP4430_WKUPDEP_USB_HOST_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_USB_HOST_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_USB_HOST_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L3INIT_USB_HOST_FS_WKDEP */
-#define OMAP4430_WKUPDEP_USB_HOST_FS_DUCATI_SHIFT			(1 << 1)
+#define OMAP4430_WKUPDEP_USB_HOST_FS_DUCATI_SHIFT			1
 #define OMAP4430_WKUPDEP_USB_HOST_FS_DUCATI_MASK			BITFIELD(1, 1)
 
 /* Used by PM_L3INIT_USB_HOST_FS_WKDEP */
-#define OMAP4430_WKUPDEP_USB_HOST_FS_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_USB_HOST_FS_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_USB_HOST_FS_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L3INIT_USB_HOST_WKDEP */
-#define OMAP4430_WKUPDEP_USB_HOST_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_USB_HOST_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_USB_HOST_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L3INIT_USB_OTG_WKDEP */
-#define OMAP4430_WKUPDEP_USB_OTG_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_USB_OTG_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_USB_OTG_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L3INIT_USB_OTG_WKDEP */
-#define OMAP4430_WKUPDEP_USB_OTG_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_USB_OTG_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_USB_OTG_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_L3INIT_USB_TLL_WKDEP */
-#define OMAP4430_WKUPDEP_USB_TLL_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_USB_TLL_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_USB_TLL_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_L3INIT_USB_TLL_WKDEP */
-#define OMAP4430_WKUPDEP_USB_TLL_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_USB_TLL_MPU_SHIFT				0
 #define OMAP4430_WKUPDEP_USB_TLL_MPU_MASK				BITFIELD(0, 0)
 
 /* Used by PM_WKUP_USIM_WKDEP */
-#define OMAP4430_WKUPDEP_USIM_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_USIM_MPU_SHIFT					0
 #define OMAP4430_WKUPDEP_USIM_MPU_MASK					BITFIELD(0, 0)
 
 /* Used by PM_WKUP_USIM_WKDEP */
-#define OMAP4430_WKUPDEP_USIM_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_USIM_SDMA_SHIFT				3
 #define OMAP4430_WKUPDEP_USIM_SDMA_MASK					BITFIELD(3, 3)
 
 /* Used by PM_WKUP_WDT2_WKDEP */
-#define OMAP4430_WKUPDEP_WDT2_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_WDT2_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_WDT2_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PM_WKUP_WDT2_WKDEP */
-#define OMAP4430_WKUPDEP_WDT2_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_WDT2_MPU_SHIFT					0
 #define OMAP4430_WKUPDEP_WDT2_MPU_MASK					BITFIELD(0, 0)
 
 /* Used by PM_ABE_WDT3_WKDEP */
-#define OMAP4430_WKUPDEP_WDT3_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_WDT3_MPU_SHIFT					0
 #define OMAP4430_WKUPDEP_WDT3_MPU_MASK					BITFIELD(0, 0)
 
 /* Used by PM_L3INIT_HSI_WKDEP */
-#define OMAP4430_WKUPDEP_WGM_HSI_WAKE_MPU_SHIFT				(1 << 8)
+#define OMAP4430_WKUPDEP_WGM_HSI_WAKE_MPU_SHIFT				8
 #define OMAP4430_WKUPDEP_WGM_HSI_WAKE_MPU_MASK				BITFIELD(8, 8)
 
 /* Used by PM_L3INIT_XHPI_WKDEP */
-#define OMAP4430_WKUPDEP_XHPI_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_XHPI_DUCATI_SHIFT				1
 #define OMAP4430_WKUPDEP_XHPI_DUCATI_MASK				BITFIELD(1, 1)
 
 /* Used by PRM_IO_PMCTRL */
-#define OMAP4430_WUCLK_CTRL_SHIFT					(1 << 8)
+#define OMAP4430_WUCLK_CTRL_SHIFT					8
 #define OMAP4430_WUCLK_CTRL_MASK					BITFIELD(8, 8)
 
 /* Used by PRM_IO_PMCTRL */
-#define OMAP4430_WUCLK_STATUS_SHIFT					(1 << 9)
+#define OMAP4430_WUCLK_STATUS_SHIFT					9
 #define OMAP4430_WUCLK_STATUS_MASK					BITFIELD(9, 9)
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,51 @@
+/*
+ * SDRC register values for the Numonyx M65KXXXXAM
+ *
+ * Copyright (C) 2009 Integration Software and Electronic Engineering.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_SDRAM_NUMONYX_M65KXXXXAM
+#define __ARCH_ARM_MACH_OMAP2_SDRAM_NUMONYX_M65KXXXXAM
+
+#include <plat/sdrc.h>
+
+/* Numonyx  M65KXXXXAM */
+static struct omap_sdrc_params m65kxxxxam_sdrc_params[] = {
+	[0] = {
+		.rate		= 200000000,
+		.actim_ctrla	= 0xe321d4c6,
+		.actim_ctrlb	= 0x00022328,
+		.rfr_ctrl	= 0x0005e601,
+		.mr		= 0x00000032,
+	},
+	[1] = {
+		.rate		= 166000000,
+		.actim_ctrla	= 0xba9dc485,
+		.actim_ctrlb	= 0x00022321,
+		.rfr_ctrl	= 0x0004dc01,
+		.mr		= 0x00000032,
+	},
+	[2] = {
+		.rate		= 133000000,
+		.actim_ctrla	= 0x9a19b485,
+		.actim_ctrlb	= 0x0002231b,
+		.rfr_ctrl	= 0x0003de01,
+		.mr		= 0x00000032,
+	},
+	[3] = {
+		.rate		= 83000000,
+		.actim_ctrla	= 0x594ca242,
+		.actim_ctrlb	= 0x00022310,
+		.rfr_ctrl	= 0x00025501,
+		.mr		= 0x00000032,
+	},
+	[4] = {
+		.rate			= 0
+	},
+};
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdrc.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/sdrc.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdrc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/sdrc.c	2010-05-16 17:17:36.000000000 -0400
@@ -119,8 +119,15 @@ int omap2_sdrc_get_params(unsigned long
 
 void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals)
 {
-	omap2_sdrc_base = omap2_globals->sdrc;
-	omap2_sms_base = omap2_globals->sms;
+	/* Static mapping, never released */
+	if (omap2_globals->sdrc) {
+		omap2_sdrc_base = ioremap(omap2_globals->sdrc, SZ_64K);
+		WARN_ON(!omap2_sdrc_base);
+	}
+	if (omap2_globals->sms) {
+		omap2_sms_base = ioremap(omap2_globals->sms, SZ_64K);
+		WARN_ON(!omap2_sms_base);
+	}
 }
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/serial.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/serial.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/serial_reg.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/delay.h>
 
 #include <plat/common.h>
 #include <plat/board.h>
@@ -80,7 +81,6 @@ static LIST_HEAD(uart_list);
 
 static struct plat_serial8250_port serial_platform_data0[] = {
 	{
-		.mapbase	= OMAP_UART1_BASE,
 		.irq		= 72,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.iotype		= UPIO_MEM,
@@ -93,7 +93,6 @@ static struct plat_serial8250_port seria
 
 static struct plat_serial8250_port serial_platform_data1[] = {
 	{
-		.mapbase	= OMAP_UART2_BASE,
 		.irq		= 73,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.iotype		= UPIO_MEM,
@@ -106,7 +105,6 @@ static struct plat_serial8250_port seria
 
 static struct plat_serial8250_port serial_platform_data2[] = {
 	{
-		.mapbase	= OMAP_UART3_BASE,
 		.irq		= 74,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.iotype		= UPIO_MEM,
@@ -117,10 +115,8 @@ static struct plat_serial8250_port seria
 	}
 };
 
-#ifdef CONFIG_ARCH_OMAP4
 static struct plat_serial8250_port serial_platform_data3[] = {
 	{
-		.mapbase	= OMAP_UART4_BASE,
 		.irq		= 70,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.iotype		= UPIO_MEM,
@@ -130,7 +126,15 @@ static struct plat_serial8250_port seria
 		.flags		= 0
 	}
 };
-#endif
+
+void __init omap2_set_globals_uart(struct omap_globals *omap2_globals)
+{
+	serial_platform_data0[0].mapbase = omap2_globals->uart1_phys;
+	serial_platform_data1[0].mapbase = omap2_globals->uart2_phys;
+	serial_platform_data2[0].mapbase = omap2_globals->uart3_phys;
+	serial_platform_data3[0].mapbase = omap2_globals->uart4_phys;
+}
+
 static inline unsigned int __serial_read_reg(struct uart_port *up,
 					   int offset)
 {
@@ -145,6 +149,13 @@ static inline unsigned int serial_read_r
 	return (unsigned int)__raw_readb(up->membase + offset);
 }
 
+static inline void __serial_write_reg(struct uart_port *up, int offset,
+		int value)
+{
+	offset <<= up->regshift;
+	__raw_writeb(value, up->membase + offset);
+}
+
 static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
 				    int value)
 {
@@ -527,7 +538,7 @@ static ssize_t sleep_timeout_store(struc
 	unsigned int value;
 
 	if (sscanf(buf, "%u", &value) != 1) {
-		printk(KERN_ERR "sleep_timeout_store: Invalid value\n");
+		dev_err(dev, "sleep_timeout_store: Invalid value\n");
 		return -EINVAL;
 	}
 
@@ -574,7 +585,7 @@ static struct omap_uart_state omap_uart[
 			},
 		},
 	},
-#ifdef CONFIG_ARCH_OMAP4
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
 	{
 		.pdev = {
 			.name			= "serial8250",
@@ -605,44 +616,69 @@ static unsigned int serial_in_override(s
 	return __serial_read_reg(up, offset);
 }
 
+static void serial_out_override(struct uart_port *up, int offset, int value)
+{
+	unsigned int status, tmout = 10000;
+
+	status = __serial_read_reg(up, UART_LSR);
+	while (!(status & UART_LSR_THRE)) {
+		/* Wait up to 10ms for the character(s) to be sent. */
+		if (--tmout == 0)
+			break;
+		udelay(1);
+		status = __serial_read_reg(up, UART_LSR);
+	}
+	__serial_write_reg(up, offset, value);
+}
 void __init omap_serial_early_init(void)
 {
-	int i;
+	int i, nr_ports;
 	char name[16];
 
+	if (!(cpu_is_omap3630() || cpu_is_omap4430()))
+		nr_ports = 3;
+	else
+		nr_ports = ARRAY_SIZE(omap_uart);
+
 	/*
 	 * 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 < ARRAY_SIZE(omap_uart); i++) {
+	for (i = 0; i < nr_ports; i++) {
 		struct omap_uart_state *uart = &omap_uart[i];
 		struct platform_device *pdev = &uart->pdev;
 		struct device *dev = &pdev->dev;
 		struct plat_serial8250_port *p = dev->platform_data;
 
+		/* Don't map zero-based physical address */
+		if (p->mapbase == 0) {
+			dev_warn(dev, "no physical address for uart#%d,"
+				 " so skipping early_init...\n", i);
+			continue;
+		}
 		/*
 		 * Module 4KB + L4 interconnect 4KB
 		 * Static mapping, never released
 		 */
 		p->membase = ioremap(p->mapbase, SZ_8K);
 		if (!p->membase) {
-			printk(KERN_ERR "ioremap failed for uart%i\n", i + 1);
+			dev_err(dev, "ioremap failed for uart%i\n", i + 1);
 			continue;
 		}
 
-		sprintf(name, "uart%d_ick", i+1);
+		sprintf(name, "uart%d_ick", i + 1);
 		uart->ick = clk_get(NULL, name);
 		if (IS_ERR(uart->ick)) {
-			printk(KERN_ERR "Could not get uart%d_ick\n", i+1);
+			dev_err(dev, "Could not get uart%d_ick\n", i + 1);
 			uart->ick = NULL;
 		}
 
 		sprintf(name, "uart%d_fck", i+1);
 		uart->fck = clk_get(NULL, name);
 		if (IS_ERR(uart->fck)) {
-			printk(KERN_ERR "Could not get uart%d_fck\n", i+1);
+			dev_err(dev, "Could not get uart%d_fck\n", i + 1);
 			uart->fck = NULL;
 		}
 
@@ -685,6 +721,13 @@ void __init omap_serial_init_port(int po
 	pdev = &uart->pdev;
 	dev = &pdev->dev;
 
+	/* Don't proceed if there's no clocks available */
+	if (unlikely(!uart->ick || !uart->fck)) {
+		WARN(1, "%s: can't init uart%d, no clocks available\n",
+		     kobject_name(&dev->kobj), port);
+		return;
+	}
+
 	omap_uart_enable_clocks(uart);
 
 	omap_uart_reset(uart);
@@ -701,15 +744,19 @@ void __init omap_serial_init_port(int po
 		DEV_CREATE_FILE(dev, &dev_attr_sleep_timeout);
 	}
 
-		/* omap44xx: Never read empty UART fifo
-		 * omap3xxx: Never read empty UART fifo on UARTs
-		 * with IP rev >=0x52
-		 */
-		if (cpu_is_omap44xx())
-			uart->p->serial_in = serial_in_override;
-		else if ((serial_read_reg(uart->p, UART_OMAP_MVER) & 0xFF)
-				>= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV)
-			uart->p->serial_in = serial_in_override;
+	/*
+	 * omap44xx: Never read empty UART fifo
+	 * omap3xxx: Never read empty UART fifo on UARTs
+	 * with IP rev >=0x52
+	 */
+	if (cpu_is_omap44xx()) {
+		uart->p->serial_in = serial_in_override;
+		uart->p->serial_out = serial_out_override;
+	} else if ((serial_read_reg(uart->p, UART_OMAP_MVER) & 0xFF)
+			>= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV) {
+		uart->p->serial_in = serial_in_override;
+		uart->p->serial_out = serial_out_override;
+	}
 }
 
 /**
@@ -721,8 +768,13 @@ void __init omap_serial_init_port(int po
  */
 void __init omap_serial_init(void)
 {
-	int i;
+	int i, nr_ports;
 
-	for (i = 0; i < ARRAY_SIZE(omap_uart); i++)
+	if (!(cpu_is_omap3630() || cpu_is_omap4430()))
+		nr_ports = 3;
+	else
+		nr_ports = ARRAY_SIZE(omap_uart);
+
+	for (i = 0; i < nr_ports; i++)
 		omap_serial_init_port(i);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sleep34xx.S linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/sleep34xx.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sleep34xx.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/sleep34xx.S	2010-05-16 17:17:36.000000000 -0400
@@ -33,12 +33,14 @@
 #include "prm.h"
 #include "sdrc.h"
 
+#define SDRC_SCRATCHPAD_SEM_V	0xfa00291c
+
 #define PM_PREPWSTST_CORE_V	OMAP34XX_PRM_REGADDR(CORE_MOD, \
 				OMAP3430_PM_PREPWSTST)
 #define PM_PREPWSTST_CORE_P	0x48306AE8
 #define PM_PREPWSTST_MPU_V	OMAP34XX_PRM_REGADDR(MPU_MOD, \
 				OMAP3430_PM_PREPWSTST)
-#define PM_PWSTCTRL_MPU_P	OMAP3430_PRM_BASE + MPU_MOD + PM_PWSTCTRL
+#define PM_PWSTCTRL_MPU_P	OMAP3430_PRM_BASE + MPU_MOD + OMAP2_PM_PWSTCTRL
 #define CM_IDLEST1_CORE_V	OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST1)
 #define SRAM_BASE_P		0x40200000
 #define CONTROL_STAT		0x480022F0
@@ -57,6 +59,37 @@
 #define SDRC_DLLA_STATUS_V	OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
 #define SDRC_DLLA_CTRL_V	OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
 
+        .text
+/* Function to aquire the semaphore in scratchpad */
+ENTRY(lock_scratchpad_sem)
+	stmfd	sp!, {lr}	@ save registers on stack
+wait_sem:
+	mov	r0,#1
+	ldr	r1, sdrc_scratchpad_sem
+wait_loop:
+	ldr	r2, [r1]	@ load the lock value
+	cmp	r2, r0		@ is the lock free ?
+	beq	wait_loop	@ not free...
+	swp	r2, r0, [r1]	@ semaphore free so lock it and proceed
+	cmp	r2, r0		@ did we succeed ?
+	beq	wait_sem	@ no - try again
+	ldmfd	sp!, {pc}	@ restore regs and return
+sdrc_scratchpad_sem:
+        .word SDRC_SCRATCHPAD_SEM_V
+ENTRY(lock_scratchpad_sem_sz)
+        .word   . - lock_scratchpad_sem
+
+        .text
+/* Function to release the scratchpad semaphore */
+ENTRY(unlock_scratchpad_sem)
+	stmfd	sp!, {lr}	@ save registers on stack
+	ldr	r3, sdrc_scratchpad_sem
+	mov	r2,#0
+	str	r2,[r3]
+	ldmfd	sp!, {pc}	@ restore regs and return
+ENTRY(unlock_scratchpad_sem_sz)
+        .word   . - unlock_scratchpad_sem
+
 	.text
 /* Function call to get the restore pointer for resume from OFF */
 ENTRY(get_restore_pointer)
@@ -251,6 +284,21 @@ restore:
 	mcr	p15, 0, r0, c7, c10, 5	@ data memory barrier
 	.word	0xE1600071		@ call SMI monitor (smi #1)
 
+#ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE
+	/* Restore L2 aux control register */
+	@ set service ID for PPA
+	mov	r0, #CONFIG_OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
+	mov	r12, r0		@ copy service ID in r12
+	mov	r1, #0		@ set task ID for ROM code in r1
+	mov	r2, #4		@ set some flags in r2, r6
+	mov	r6, #0xff
+	ldr	r4, scratchpad_base
+	ldr	r3, [r4, #0xBC]
+	adds	r3, r3, #8	@ r3 points to parameters
+	mcr	p15, 0, r0, c7, c10, 4	@ data write barrier
+	mcr	p15, 0, r0, c7, c10, 5	@ data memory barrier
+	.word	0xE1600071		@ call SMI monitor (smi #1)
+#endif
 	b	logic_l1_restore
 l2_inv_api_params:
 	.word   0x1, 0x00
@@ -264,6 +312,11 @@ smi:    .word 0xE1600070		@ Call SMI mon
 	ldr	r0, [r3,#4]
 	mov	r12, #0x3
 	.word 0xE1600070	@ Call SMI monitor (smieq)
+	ldr	r4, scratchpad_base
+	ldr	r3, [r4,#0xBC]
+	ldr	r0, [r3,#12]
+	mov	r12, #0x2
+	.word 0xE1600070	@ Call SMI monitor (smieq)
 logic_l1_restore:
 	mov	r1, #0
 	/* Invalidate all instruction caches to PoU
@@ -272,7 +325,7 @@ logic_l1_restore:
 
 	ldr	r4, scratchpad_base
 	ldr	r3, [r4,#0xBC]
-	adds	r3, r3, #8
+	adds	r3, r3, #16
 	ldmia	r3!, {r4-r6}
 	mov	sp, r4
 	msr	spsr_cxsf, r5
@@ -391,7 +444,9 @@ save_context_wfi:
 	mov	r8, r0 /* Store SDRAM address in r8 */
 	mrc	p15, 0, r5, c1, c0, 1	@ Read Auxiliary Control Register
 	mov	r4, #0x1		@ Number of parameters for restore call
-	stmia	r8!, {r4-r5}
+	stmia	r8!, {r4-r5}		@ Push parameters for restore call
+	mrc	p15, 1, r5, c9, c0, 2	@ Read L2 AUX ctrl register
+	stmia	r8!, {r4-r5}		@ Push parameters for restore call
         /* Check what that target sleep state is:stored in r1*/
         /* 1 - Only L1 and logic lost */
         /* 2 - Only L2 lost */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/timer-gp.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/timer-gp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/timer-gp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/timer-gp.c	2010-05-16 17:17:36.000000000 -0400
@@ -85,8 +85,6 @@ static void omap2_gp_timer_set_mode(enum
 	case CLOCK_EVT_MODE_PERIODIC:
 		period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ;
 		period -= 1;
-		if (cpu_is_omap44xx())
-			period = 0xff;	/* FIXME: */
 		omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
@@ -150,9 +148,6 @@ static void __init omap2_gp_clockevent_i
 		     "timer-gp: omap_dm_timer_set_source() failed\n");
 
 	tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer));
-	if (cpu_is_omap44xx())
-		/* Assuming 32kHz clk is driving GPT1 */
-		tick_rate = 32768;	/* FIXME: */
 
 	pr_info("OMAP clockevent source: GPTIMER%d at %u Hz\n",
 		gptimer_id, tick_rate);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/timer-mpu.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/timer-mpu.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/timer-mpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/timer-mpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,7 @@
  */
 void __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
-	evt->irq = INT_44XX_LOCALTIMER_IRQ;
+	evt->irq = OMAP44XX_IRQ_LOCALTIMER;
 	twd_timer_setup(evt);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/usb-ehci.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/usb-ehci.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/usb-ehci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/usb-ehci.c	2010-05-16 17:17:36.000000000 -0400
@@ -70,7 +70,7 @@ static struct platform_device ehci_devic
 /*
  * setup_ehci_io_mux - initialize IO pad mux for USBHOST
  */
-static void setup_ehci_io_mux(enum ehci_hcd_omap_mode *port_mode)
+static void setup_ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode)
 {
 	switch (port_mode[0]) {
 	case EHCI_HCD_OMAP_MODE_PHY:
@@ -213,7 +213,7 @@ static void setup_ehci_io_mux(enum ehci_
 	return;
 }
 
-void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata)
+void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata)
 {
 	platform_device_add_data(&ehci_device, pdata, sizeof(*pdata));
 
@@ -229,7 +229,7 @@ void __init usb_ehci_init(struct ehci_hc
 
 #else
 
-void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata)
+void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata)
 
 {
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/usb-musb.c linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/usb-musb.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/usb-musb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/usb-musb.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,70 +47,11 @@ static struct resource musb_resources[]
 	},
 };
 
-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 = {
@@ -122,7 +63,6 @@ static struct musb_hdrc_platform_data mu
 	.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
@@ -146,28 +86,34 @@ static struct platform_device musb_devic
 	.resource	= musb_resources,
 };
 
-void __init usb_musb_init(void)
+void __init usb_musb_init(struct omap_musb_board_data *board_data)
 {
-	if (cpu_is_omap243x())
+	if (cpu_is_omap243x()) {
 		musb_resources[0].start = OMAP243X_HS_BASE;
-	else
+	} else if (cpu_is_omap34xx()) {
 		musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE;
-	musb_resources[0].end = musb_resources[0].start + SZ_8K - 1;
+	} else if (cpu_is_omap44xx()) {
+		musb_resources[0].start = OMAP44XX_HSUSB_OTG_BASE;
+		musb_resources[1].start = OMAP44XX_IRQ_HS_USB_MC_N;
+		musb_resources[2].start = OMAP44XX_IRQ_HS_USB_DMA_N;
+	}
+	musb_resources[0].end = musb_resources[0].start + SZ_4K - 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";
+	musb_plat.board_data = board_data;
+	musb_plat.power = board_data->power >> 1;
+	musb_plat.mode = board_data->mode;
 
-	if (platform_device_register(&musb_device) < 0) {
+	if (platform_device_register(&musb_device) < 0)
 		printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n");
-		return;
-	}
 }
 
 #else
-void __init usb_musb_init(void)
+void __init usb_musb_init(struct omap_musb_board_data *board_data)
 {
 }
 #endif /* CONFIG_USB_MUSB_SOC */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/common.c linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/common.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/common.c	2010-05-16 17:17:36.000000000 -0400
@@ -488,7 +488,7 @@ static struct platform_device orion5x_xo
 	.dev		= {
 		.dma_mask		= &orion5x_xor_dmamask,
 		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= (void *)&orion5x_xor0_data,
+		.platform_data		= &orion5x_xor0_data,
 	},
 };
 
@@ -514,7 +514,7 @@ static struct platform_device orion5x_xo
 	.dev		= {
 		.dma_mask		= &orion5x_xor_dmamask,
 		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= (void *)&orion5x_xor1_data,
+		.platform_data		= &orion5x_xor1_data,
 	},
 };
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/d2net-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/d2net-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/d2net-setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/d2net-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -149,10 +149,7 @@ static void __init d2net_sata_power_init
 
 /*
  * The blue front LED is wired to the CPLD and can blink in relation with the
- * SATA activity. This feature is disabled to make this LED compatible with
- * the leds-gpio driver: MPP14 and MPP15 are configured to act like output
- * GPIO's and have to stay in an active state. This is needed to set the blue
- * LED in a "fix on" state regardless of the SATA activity.
+ * SATA activity.
  *
  * The following array detail the different LED registers and the combination
  * of their possible values:
@@ -171,12 +168,11 @@ static void __init d2net_sata_power_init
 #define D2NET_GPIO_RED_LED		6
 #define D2NET_GPIO_BLUE_LED_BLINK_CTRL	16
 #define D2NET_GPIO_BLUE_LED_OFF		23
-#define D2NET_GPIO_SATA0_ACT		14
-#define D2NET_GPIO_SATA1_ACT		15
 
 static struct gpio_led d2net_leds[] = {
 	{
-		.name = "d2net:blue:power",
+		.name = "d2net:blue:sata",
+		.default_trigger = "default-on",
 		.gpio = D2NET_GPIO_BLUE_LED_OFF,
 		.active_low = 1,
 	},
@@ -201,25 +197,22 @@ static struct platform_device d2net_gpio
 
 static void __init d2net_gpio_leds_init(void)
 {
+	int err;
+
 	/* Configure GPIO over MPP max number. */
 	orion_gpio_set_valid(D2NET_GPIO_BLUE_LED_OFF, 1);
 
-	if (gpio_request(D2NET_GPIO_SATA0_ACT, "LED SATA0 activity") != 0)
-		return;
-	if (gpio_direction_output(D2NET_GPIO_SATA0_ACT, 1) != 0)
-		goto err_free_1;
-	if (gpio_request(D2NET_GPIO_SATA1_ACT, "LED SATA1 activity") != 0)
-		goto err_free_1;
-	if (gpio_direction_output(D2NET_GPIO_SATA1_ACT, 1) != 0)
-		goto err_free_2;
-	platform_device_register(&d2net_gpio_leds);
-	return;
+	/* Configure register blink_ctrl to allow SATA activity LED blinking. */
+	err = gpio_request(D2NET_GPIO_BLUE_LED_BLINK_CTRL, "blue LED blink");
+	if (err == 0) {
+		err = gpio_direction_output(D2NET_GPIO_BLUE_LED_BLINK_CTRL, 1);
+		if (err)
+			gpio_free(D2NET_GPIO_BLUE_LED_BLINK_CTRL);
+	}
+	if (err)
+		pr_err("d2net: failed to configure blue LED blink GPIO\n");
 
-err_free_2:
-	gpio_free(D2NET_GPIO_SATA1_ACT);
-err_free_1:
-	gpio_free(D2NET_GPIO_SATA0_ACT);
-	return;
+	platform_device_register(&d2net_gpio_leds);
 }
 
 /****************************************************************************
@@ -289,8 +282,8 @@ static struct orion5x_mpp_mode d2net_mpp
 	{ 11, MPP_UNUSED },
 	{ 12, MPP_GPIO },	/* SATA 1 power */
 	{ 13, MPP_UNUSED },
-	{ 14, MPP_GPIO },	/* SATA 0 active */
-	{ 15, MPP_GPIO },	/* SATA 1 active */
+	{ 14, MPP_SATA_LED },	/* SATA 0 active */
+	{ 15, MPP_SATA_LED },	/* SATA 1 active */
 	{ 16, MPP_GPIO },	/* Blue front LED blink control */
 	{ 17, MPP_UNUSED },
 	{ 18, MPP_GPIO },	/* Front button (0 = Released, 1 = Pushed ) */
@@ -301,6 +294,8 @@ static struct orion5x_mpp_mode d2net_mpp
 	/* 24: Inhibit board power off (0 = Disabled, 1 = Enabled) */
 };
 
+#define D2NET_GPIO_INHIBIT_POWER_OFF    24
+
 static void __init d2net_init(void)
 {
 	/*
@@ -333,6 +328,8 @@ static void __init d2net_init(void)
 
 	i2c_register_board_info(0, d2net_i2c_devices,
 				ARRAY_SIZE(d2net_i2c_devices));
+
+	orion_gpio_set_valid(D2NET_GPIO_INHIBIT_POWER_OFF, 1);
 }
 
 /* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/dns323-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/dns323-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/dns323-setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/dns323-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,8 @@
 #define DNS323_GPIO_LED_RIGHT_AMBER	1
 #define DNS323_GPIO_LED_LEFT_AMBER	2
 #define DNS323_GPIO_SYSTEM_UP		3
-#define DNS323_GPIO_LED_POWER		5
+#define DNS323_GPIO_LED_POWER1		4
+#define DNS323_GPIO_LED_POWER2		5
 #define DNS323_GPIO_OVERTEMP		6
 #define DNS323_GPIO_RTC			7
 #define DNS323_GPIO_POWER_OFF		8
@@ -237,11 +238,31 @@ error_fail:
  * GPIO LEDs (simple - doesn't use hardware blinking support)
  */
 
+#define ORION_BLINK_HALF_PERIOD 100 /* ms */
+
+static int dns323_gpio_blink_set(unsigned gpio,
+	unsigned long *delay_on, unsigned long *delay_off)
+{
+	static int value = 0;
+
+	if (!*delay_on && !*delay_off)
+		*delay_on = *delay_off = ORION_BLINK_HALF_PERIOD;
+
+	if (ORION_BLINK_HALF_PERIOD == *delay_on
+	    && ORION_BLINK_HALF_PERIOD == *delay_off) {
+		value = !value;
+		orion_gpio_set_blink(gpio, value);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 static struct gpio_led dns323_leds[] = {
 	{
 		.name = "power:blue",
-		.gpio = DNS323_GPIO_LED_POWER,
-		.default_state = LEDS_GPIO_DEFSTATE_ON,
+		.gpio = DNS323_GPIO_LED_POWER2,
+		.default_trigger = "timer",
 	}, {
 		.name = "right:amber",
 		.gpio = DNS323_GPIO_LED_RIGHT_AMBER,
@@ -256,6 +277,7 @@ static struct gpio_led dns323_leds[] = {
 static struct gpio_led_platform_data dns323_led_data = {
 	.num_leds	= ARRAY_SIZE(dns323_leds),
 	.leds		= dns323_leds,
+	.gpio_blink_set = dns323_gpio_blink_set,
 };
 
 static struct platform_device dns323_gpio_leds = {
@@ -412,6 +434,14 @@ static void __init dns323_init(void)
 	orion5x_setup_dev_boot_win(DNS323_NOR_BOOT_BASE, DNS323_NOR_BOOT_SIZE);
 	platform_device_register(&dns323_nor_flash);
 
+	/* The 5181 power LED is active low and requires
+	 * DNS323_GPIO_LED_POWER1 to also be low.
+	 */
+	if (dns323_dev_id() == MV88F5181_DEV_ID) {
+		dns323_leds[0].active_low = 1;
+		gpio_direction_output(DNS323_GPIO_LED_POWER1, 0);
+	}
+
 	platform_device_register(&dns323_gpio_leds);
 
 	platform_device_register(&dns323_button_device);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,7 @@
 
 #include <mach/orion5x.h>
 
-	.macro  addruart,rx
+	.macro  addruart, rx, tmp
 	mrc	p15, 0, \rx, c1, c0
 	tst	\rx, #1					@ MMU enabled?
 	ldreq	\rx, =ORION5X_REGS_PHYS_BASE
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,4 +2,4 @@
  * arch/arm/mach-orion5x/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END       0xfd800000
+#define VMALLOC_END       0xfd800000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -57,6 +57,13 @@ config MACH_LINKSTATION_MINI
 	  Say 'Y' here if you want your kernel to support the
 	  Buffalo Linkstation Mini platform.
 
+config MACH_LINKSTATION_LS_HGL
+	bool "Buffalo Linkstation LS-HGL"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Buffalo Linkstation LS-HGL platform.
+
 config MACH_TS409
 	bool "QNAP TS-409"
 	help
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/ls_hgl-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/ls_hgl-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/ls_hgl-setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/ls_hgl-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,276 @@
+/*
+ * arch/arm/mach-orion5x/ls_hgl-setup.c
+ *
+ * Maintainer: Zhu Qingsen <zhuqs@cn.fujitsu.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/system.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * Linkstation LS-HGL Info
+ ****************************************************************************/
+
+/*
+ * 256K NOR flash Device bus boot chip select
+ */
+
+#define LS_HGL_NOR_BOOT_BASE	0xf4000000
+#define LS_HGL_NOR_BOOT_SIZE	SZ_256K
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data ls_hgl_nor_flash_data = {
+	.width		= 1,
+};
+
+static struct resource ls_hgl_nor_flash_resource = {
+	.flags	= IORESOURCE_MEM,
+	.start	= LS_HGL_NOR_BOOT_BASE,
+	.end	= LS_HGL_NOR_BOOT_BASE + LS_HGL_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device ls_hgl_nor_flash = {
+	.name			= "physmap-flash",
+	.id			= 0,
+	.dev		= {
+		.platform_data	= &ls_hgl_nor_flash_data,
+	},
+	.num_resources		= 1,
+	.resource		= &ls_hgl_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data ls_hgl_eth_data = {
+	.phy_addr	= 8,
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+
+static struct i2c_board_info __initdata ls_hgl_i2c_rtc = {
+	I2C_BOARD_INFO("rs5c372a", 0x32),
+};
+
+/*****************************************************************************
+ * LEDs attached to GPIO
+ ****************************************************************************/
+
+#define LS_HGL_GPIO_LED_ALARM   2
+#define LS_HGL_GPIO_LED_INFO    3
+#define LS_HGL_GPIO_LED_FUNC    17
+#define LS_HGL_GPIO_LED_PWR     0
+
+
+static struct gpio_led ls_hgl_led_pins[] = {
+	{
+		.name	   = "alarm:red",
+		.gpio	   = LS_HGL_GPIO_LED_ALARM,
+		.active_low     = 1,
+	}, {
+		.name	   = "info:amber",
+		.gpio	   = LS_HGL_GPIO_LED_INFO,
+		.active_low     = 1,
+	}, {
+		.name	   = "func:blue:top",
+		.gpio	   = LS_HGL_GPIO_LED_FUNC,
+		.active_low     = 1,
+	}, {
+		.name	   = "power:blue:bottom",
+		.gpio	   = LS_HGL_GPIO_LED_PWR,
+	},
+};
+
+static struct gpio_led_platform_data ls_hgl_led_data = {
+	.leds	   = ls_hgl_led_pins,
+	.num_leds       = ARRAY_SIZE(ls_hgl_led_pins),
+};
+
+static struct platform_device ls_hgl_leds = {
+	.name   = "leds-gpio",
+	.id     = -1,
+	.dev    = {
+		.platform_data  = &ls_hgl_led_data,
+	},
+};
+
+/****************************************************************************
+ * GPIO Attached Keys
+ ****************************************************************************/
+#define LS_HGL_GPIO_KEY_FUNC       15
+#define LS_HGL_GPIO_KEY_POWER      8
+#define LS_HGL_GPIO_KEY_AUTOPOWER  10
+
+#define LS_HGL_SW_POWER     0x00
+#define LS_HGL_SW_AUTOPOWER 0x01
+
+static struct gpio_keys_button ls_hgl_buttons[] = {
+	{
+		.code	   = KEY_OPTION,
+		.gpio	   = LS_HGL_GPIO_KEY_FUNC,
+		.desc	   = "Function Button",
+		.active_low     = 1,
+	}, {
+		.type		= EV_SW,
+		.code	   = LS_HGL_SW_POWER,
+		.gpio	   = LS_HGL_GPIO_KEY_POWER,
+		.desc	   = "Power-on Switch",
+		.active_low     = 1,
+	}, {
+		.type		= EV_SW,
+		.code	   = LS_HGL_SW_AUTOPOWER,
+		.gpio	   = LS_HGL_GPIO_KEY_AUTOPOWER,
+		.desc	   = "Power-auto Switch",
+		.active_low     = 1,
+	},
+};
+
+static struct gpio_keys_platform_data ls_hgl_button_data = {
+	.buttons	= ls_hgl_buttons,
+	.nbuttons       = ARRAY_SIZE(ls_hgl_buttons),
+};
+
+static struct platform_device ls_hgl_button_device = {
+	.name	   = "gpio-keys",
+	.id	     = -1,
+	.num_resources  = 0,
+	.dev	    = {
+		.platform_data  = &ls_hgl_button_data,
+	},
+};
+
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct mv_sata_platform_data ls_hgl_sata_data = {
+	.n_ports	= 2,
+};
+
+
+/*****************************************************************************
+ * Linkstation LS-HGL specific power off method: reboot
+ ****************************************************************************/
+/*
+ * On the Linkstation LS-HGL, the shutdown process is following:
+ * - Userland monitors key events until the power switch goes to off position
+ * - The board reboots
+ * - U-boot starts and goes into an idle mode waiting for the user
+ *   to move the switch to ON position
+ */
+
+static void ls_hgl_power_off(void)
+{
+	arm_machine_restart('h', NULL);
+}
+
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+#define LS_HGL_GPIO_USB_POWER	9
+#define LS_HGL_GPIO_AUTO_POWER	10
+#define LS_HGL_GPIO_POWER	    8
+
+#define LS_HGL_GPIO_HDD_POWER	1
+
+static struct orion5x_mpp_mode ls_hgl_mpp_modes[] __initdata = {
+	{  0, MPP_GPIO }, /* LED_PWR */
+	{  1, MPP_GPIO }, /* HDD_PWR */
+	{  2, MPP_GPIO }, /* LED_ALARM */
+	{  3, MPP_GPIO }, /* LED_INFO */
+	{  4, MPP_UNUSED },
+	{  5, MPP_UNUSED },
+	{  6, MPP_GPIO }, /* FAN_LCK */
+	{  7, MPP_GPIO }, /* INIT */
+	{  8, MPP_GPIO }, /* POWER */
+	{  9, MPP_GPIO }, /* USB_PWR */
+	{ 10, MPP_GPIO }, /* AUTO_POWER */
+	{ 11, MPP_UNUSED }, /* LED_ETH (dummy) */
+	{ 12, MPP_UNUSED },
+	{ 13, MPP_UNUSED },
+	{ 14, MPP_UNUSED },
+	{ 15, MPP_GPIO }, /* FUNC */
+	{ 16, MPP_UNUSED },
+	{ 17, MPP_GPIO }, /* LED_FUNC */
+	{ 18, MPP_UNUSED },
+	{ 19, MPP_UNUSED },
+	{ -1 },
+};
+
+static void __init ls_hgl_init(void)
+{
+	/*
+	 * Setup basic Orion functions. Need to be called early.
+	 */
+	orion5x_init();
+
+	orion5x_mpp_conf(ls_hgl_mpp_modes);
+
+	/*
+	 * Configure peripherals.
+	 */
+	orion5x_ehci0_init();
+	orion5x_ehci1_init();
+	orion5x_eth_init(&ls_hgl_eth_data);
+	orion5x_i2c_init();
+	orion5x_sata_init(&ls_hgl_sata_data);
+	orion5x_uart0_init();
+	orion5x_xor_init();
+
+	orion5x_setup_dev_boot_win(LS_HGL_NOR_BOOT_BASE,
+				   LS_HGL_NOR_BOOT_SIZE);
+	platform_device_register(&ls_hgl_nor_flash);
+
+	platform_device_register(&ls_hgl_button_device);
+
+	platform_device_register(&ls_hgl_leds);
+
+	i2c_register_board_info(0, &ls_hgl_i2c_rtc, 1);
+
+	/* enable USB power */
+	gpio_set_value(LS_HGL_GPIO_USB_POWER, 1);
+
+	/* register power-off method */
+	pm_power_off = ls_hgl_power_off;
+
+	pr_info("%s: finished\n", __func__);
+}
+
+MACHINE_START(LINKSTATION_LS_HGL, "Buffalo Linkstation LS-HGL")
+	/* Maintainer: Zhu Qingsen <zhuqs@cn.fujistu.com> */
+	.phys_io	= ORION5X_REGS_PHYS_BASE,
+	.io_pg_offst	= ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= ls_hgl_init,
+	.map_io		= orion5x_map_io,
+	.init_irq	= orion5x_init_irq,
+	.timer		= &orion5x_timer,
+	.fixup		= tag_fixup_mem32,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/lsmini-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/lsmini-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/lsmini-setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/lsmini-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/pci.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/leds.h>
@@ -19,12 +18,13 @@
 #include <linux/input.h>
 #include <linux/i2c.h>
 #include <linux/ata_platform.h>
-#include <asm/mach-types.h>
 #include <linux/gpio.h>
+#include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include <asm/system.h>
+#include <mach/orion5x.h>
 #include "common.h"
 #include "mpp.h"
-#include "include/mach/system.h"
 
 /*****************************************************************************
  * Linkstation Mini Info
@@ -186,7 +186,7 @@ static struct mv_sata_platform_data lsmi
 
 static void lsmini_power_off(void)
 {
-	arch_reset(0, NULL);
+	arm_machine_restart('h', NULL);
 }
 
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@ obj-$(CONFIG_MACH_KUROBOX_PRO)	+= kurobo
 obj-$(CONFIG_MACH_TERASTATION_PRO2)	+= terastation_pro2-setup.o
 obj-$(CONFIG_MACH_LINKSTATION_PRO) += kurobox_pro-setup.o
 obj-$(CONFIG_MACH_LINKSTATION_MINI) += lsmini-setup.o
+obj-$(CONFIG_MACH_LINKSTATION_LS_HGL) += ls_hgl-setup.o
 obj-$(CONFIG_MACH_DNS323)	+= dns323-setup.o
 obj-$(CONFIG_MACH_TS209)	+= ts209-setup.o tsx09-common.o
 obj-$(CONFIG_MACH_TS409)	+= ts409-setup.o tsx09-common.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/pci.c linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/pci.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/mbus.h>
 #include <asm/irq.h>
 #include <asm/mach/pci.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/wrt350n-v2-setup.c linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/wrt350n-v2-setup.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/wrt350n-v2-setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/wrt350n-v2-setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -77,7 +77,7 @@ static struct gpio_keys_button wrt350n_v
 		.desc		= "Reset Button",
 		.active_low	= 1,
 	}, {
-		.code		= KEY_WLAN,
+		.code		= KEY_WPS_BUTTON,
 		.gpio		= 2,
 		.desc		= "WPS Button",
 		.active_low	= 1,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,8 +22,9 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 
-#include <mach/hardware.h>
+#include <asm/clkdev.h>
 
+#include <mach/hardware.h>
 #include <mach/clock.h>
 #include "clock.h"
 
@@ -56,18 +57,19 @@ static void propagate_rate(struct clk *c
 	}
 }
 
-static inline void clk_reg_disable(struct clk *clk)
+static void clk_reg_disable(struct clk *clk)
 {
 	if (clk->enable_reg)
 		__raw_writel(__raw_readl(clk->enable_reg) &
 			     ~(1 << clk->enable_shift), clk->enable_reg);
 }
 
-static inline void clk_reg_enable(struct clk *clk)
+static int clk_reg_enable(struct clk *clk)
 {
 	if (clk->enable_reg)
 		__raw_writel(__raw_readl(clk->enable_reg) |
 			     (1 << clk->enable_shift), clk->enable_reg);
+	return 0;
 }
 
 static inline void clk_reg_disable1(struct clk *clk)
@@ -636,31 +638,34 @@ static struct clk flash_ck = {
 static struct clk i2c0_ck = {
 	.name = "i2c0_ck",
 	.parent = &per_ck,
-	.flags = NEEDS_INITIALIZATION,
-	.round_rate = &on_off_round_rate,
-	.set_rate = &on_off_set_rate,
+	.flags = NEEDS_INITIALIZATION | FIXED_RATE,
 	.enable_shift = 0,
 	.enable_reg = I2CCLKCTRL_REG,
+	.rate = 13000000,
+	.enable = clk_reg_enable,
+	.disable = clk_reg_disable,
 };
 
 static struct clk i2c1_ck = {
 	.name = "i2c1_ck",
 	.parent = &per_ck,
-	.flags = NEEDS_INITIALIZATION,
-	.round_rate = &on_off_round_rate,
-	.set_rate = &on_off_set_rate,
+	.flags = NEEDS_INITIALIZATION | FIXED_RATE,
 	.enable_shift = 1,
 	.enable_reg = I2CCLKCTRL_REG,
+	.rate = 13000000,
+	.enable = clk_reg_enable,
+	.disable = clk_reg_disable,
 };
 
 static struct clk i2c2_ck = {
 	.name = "i2c2_ck",
 	.parent = &per_ck,
-	.flags = NEEDS_INITIALIZATION,
-	.round_rate = &on_off_round_rate,
-	.set_rate = &on_off_set_rate,
+	.flags = NEEDS_INITIALIZATION | FIXED_RATE,
 	.enable_shift = 2,
 	.enable_reg = USB_OTG_CLKCTRL_REG,
+	.rate = 13000000,
+	.enable = clk_reg_enable,
+	.disable = clk_reg_disable,
 };
 
 static struct clk spi0_ck = {
@@ -738,16 +743,16 @@ static struct clk wdt_ck = {
 	.name = "wdt_ck",
 	.parent = &per_ck,
 	.flags = NEEDS_INITIALIZATION,
-	.round_rate = &on_off_round_rate,
-	.set_rate = &on_off_set_rate,
 	.enable_shift = 0,
 	.enable_reg = TIMCLKCTRL_REG,
+	.enable = clk_reg_enable,
+	.disable = clk_reg_disable,
 };
 
 /* These clocks are visible outside this module
  * and can be initialized
  */
-static struct clk *onchip_clks[] = {
+static struct clk *onchip_clks[] __initdata = {
 	&ck_13MHz,
 	&ck_pll1,
 	&ck_pll4,
@@ -777,49 +782,74 @@ static struct clk *onchip_clks[] = {
 	&wdt_ck,
 };
 
-static int local_clk_enable(struct clk *clk)
-{
-	int ret = 0;
-
-	if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate
-	    && clk->user_rate)
-		ret = clk->set_rate(clk, clk->user_rate);
-	return ret;
-}
+static struct clk_lookup onchip_clkreg[] = {
+	{ .clk = &ck_13MHz,	.con_id = "ck_13MHz"	},
+	{ .clk = &ck_pll1,	.con_id = "ck_pll1"	},
+	{ .clk = &ck_pll4,	.con_id = "ck_pll4"	},
+	{ .clk = &ck_pll5,	.con_id = "ck_pll5"	},
+	{ .clk = &ck_pll3,	.con_id = "ck_pll3"	},
+	{ .clk = &vfp9_ck,	.con_id = "vfp9_ck"	},
+	{ .clk = &m2hclk_ck,	.con_id = "m2hclk_ck"	},
+	{ .clk = &hclk_ck,	.con_id = "hclk_ck"	},
+	{ .clk = &dma_ck,	.con_id = "dma_ck"	},
+	{ .clk = &flash_ck,	.con_id = "flash_ck"	},
+	{ .clk = &dum_ck,	.con_id = "dum_ck"	},
+	{ .clk = &keyscan_ck,	.con_id = "keyscan_ck"	},
+	{ .clk = &pwm1_ck,	.con_id = "pwm1_ck"	},
+	{ .clk = &pwm2_ck,	.con_id = "pwm2_ck"	},
+	{ .clk = &jpeg_ck,	.con_id = "jpeg_ck"	},
+	{ .clk = &ms_ck,	.con_id = "ms_ck"	},
+	{ .clk = &touch_ck,	.con_id = "touch_ck"	},
+	{ .clk = &i2c0_ck,	.dev_id = "pnx-i2c.0"	},
+	{ .clk = &i2c1_ck,	.dev_id = "pnx-i2c.1"	},
+	{ .clk = &i2c2_ck,	.dev_id = "pnx-i2c.2"	},
+	{ .clk = &spi0_ck,	.con_id = "spi0_ck"	},
+	{ .clk = &spi1_ck,	.con_id = "spi1_ck"	},
+	{ .clk = &uart3_ck,	.con_id = "uart3_ck"	},
+	{ .clk = &uart4_ck,	.con_id = "uart4_ck"	},
+	{ .clk = &uart5_ck,	.con_id = "uart5_ck"	},
+	{ .clk = &uart6_ck,	.con_id = "uart6_ck"	},
+	{ .clk = &wdt_ck,	.dev_id = "pnx4008-watchdog" },
+};
 
 static void local_clk_disable(struct clk *clk)
 {
-	if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate)
-		clk->set_rate(clk, 0);
-}
+	if (WARN_ON(clk->usecount == 0))
+		return;
 
-static void local_clk_unuse(struct clk *clk)
-{
-	if (clk->usecount > 0 && !(--clk->usecount)) {
-		local_clk_disable(clk);
+	if (!(--clk->usecount)) {
+		if (clk->disable)
+			clk->disable(clk);
+		else if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate)
+			clk->set_rate(clk, 0);
 		if (clk->parent)
-			local_clk_unuse(clk->parent);
+			local_clk_disable(clk->parent);
 	}
 }
 
-static int local_clk_use(struct clk *clk)
+static int local_clk_enable(struct clk *clk)
 {
 	int ret = 0;
-	if (clk->usecount++ == 0) {
-		if (clk->parent)
-			ret = local_clk_use(clk->parent);
 
-		if (ret != 0) {
-			clk->usecount--;
-			goto out;
+	if (clk->usecount == 0) {
+		if (clk->parent) {
+			ret = local_clk_enable(clk->parent);
+			if (ret != 0)
+				goto out;
 		}
 
-		ret = local_clk_enable(clk);
+		if (clk->enable)
+			ret = clk->enable(clk);
+		else if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate
+			    && clk->user_rate)
+			ret = clk->set_rate(clk, clk->user_rate);
 
 		if (ret != 0 && clk->parent) {
-			local_clk_unuse(clk->parent);
-			clk->usecount--;
+			local_clk_disable(clk->parent);
+			goto out;
 		}
+
+		clk->usecount++;
 	}
 out:
 	return ret;
@@ -866,35 +896,6 @@ out:
 
 EXPORT_SYMBOL(clk_set_rate);
 
-struct clk *clk_get(struct device *dev, const char *id)
-{
-	struct clk *clk = ERR_PTR(-ENOENT);
-	struct clk **clkp;
-
-	clock_lock();
-	for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
-	     clkp++) {
-		if (strcmp(id, (*clkp)->name) == 0
-		    && try_module_get((*clkp)->owner)) {
-			clk = (*clkp);
-			break;
-		}
-	}
-	clock_unlock();
-
-	return clk;
-}
-EXPORT_SYMBOL(clk_get);
-
-void clk_put(struct clk *clk)
-{
-	clock_lock();
-	if (clk && !IS_ERR(clk))
-		module_put(clk->owner);
-	clock_unlock();
-}
-EXPORT_SYMBOL(clk_put);
-
 unsigned long clk_get_rate(struct clk *clk)
 {
 	unsigned long ret;
@@ -907,10 +908,10 @@ EXPORT_SYMBOL(clk_get_rate);
 
 int clk_enable(struct clk *clk)
 {
-	int ret = 0;
+	int ret;
 
 	clock_lock();
-	ret = local_clk_use(clk);
+	ret = local_clk_enable(clk);
 	clock_unlock();
 	return ret;
 }
@@ -920,7 +921,7 @@ EXPORT_SYMBOL(clk_enable);
 void clk_disable(struct clk *clk)
 {
 	clock_lock();
-	local_clk_unuse(clk);
+	local_clk_disable(clk);
 	clock_unlock();
 }
 
@@ -967,18 +968,24 @@ static int __init clk_init(void)
 
 	for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
 	     clkp++) {
-		if (((*clkp)->flags & NEEDS_INITIALIZATION)
-		    && ((*clkp)->set_rate)) {
-			(*clkp)->user_rate = (*clkp)->rate;
-			local_set_rate((*clkp), (*clkp)->user_rate);
-			if ((*clkp)->set_parent)
-				(*clkp)->set_parent((*clkp), (*clkp)->parent);
+		struct clk *clk = *clkp;
+		if (clk->flags & NEEDS_INITIALIZATION) {
+			if (clk->set_rate) {
+				clk->user_rate = clk->rate;
+				local_set_rate(clk, clk->user_rate);
+				if (clk->set_parent)
+					clk->set_parent(clk, clk->parent);
+			}
+			if (clk->enable && clk->usecount)
+				clk->enable(clk);
+			if (clk->disable && !clk->usecount)
+				clk->disable(clk);
 		}
 		pr_debug("%s: clock %s, rate %ld\n",
-			__func__, (*clkp)->name, (*clkp)->rate);
+			__func__, clk->name, clk->rate);
 	}
 
-	local_clk_use(&ck_pll4);
+	local_clk_enable(&ck_pll4);
 
 	/* if ck_13MHz is not used, disable it. */
 	if (ck_13MHz.usecount == 0)
@@ -987,6 +994,8 @@ static int __init clk_init(void)
 	/* Disable autoclocking */
 	__raw_writeb(0xff, AUTOCLK_CTRL);
 
+	clkdev_add_table(onchip_clkreg, ARRAY_SIZE(onchip_clkreg));
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,8 +14,6 @@
 #define __ARCH_ARM_PNX4008_CLOCK_H__
 
 struct clk {
-	struct list_head node;
-	struct module *owner;
 	const char *name;
 	struct clk *parent;
 	struct clk *propagate_next;
@@ -29,9 +27,11 @@ struct clk {
 	u8 enable_shift1;
 	u32 enable_reg1;
 	u32 parent_switch_reg;
-	 u32(*round_rate) (struct clk *, u32);
+	u32(*round_rate) (struct clk *, u32);
 	int (*set_rate) (struct clk *, u32);
 	int (*set_parent) (struct clk * clk, struct clk * parent);
+	int (*enable)(struct clk *);
+	void (*disable)(struct clk *);
 };
 
 /* Flags */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/dma.c linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <mach/hardware.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/i2c.c linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/i2c.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,120 +18,24 @@
 #include <mach/irqs.h>
 #include <mach/i2c.h>
 
-static int set_clock_run(struct platform_device *pdev)
-{
-	struct clk *clk;
-	char name[10];
-	int retval = 0;
-
-	snprintf(name, 10, "i2c%d_ck", pdev->id);
-	clk = clk_get(&pdev->dev, name);
-	if (!IS_ERR(clk)) {
-		clk_set_rate(clk, 1);
-		clk_put(clk);
-	} else
-		retval = -ENOENT;
-
-	return retval;
-}
-
-static int set_clock_stop(struct platform_device *pdev)
-{
-	struct clk *clk;
-	char name[10];
-	int retval = 0;
-
-	snprintf(name, 10, "i2c%d_ck", pdev->id);
-	clk = clk_get(&pdev->dev, name);
-	if (!IS_ERR(clk)) {
-		clk_set_rate(clk, 0);
-		clk_put(clk);
-	} else
-		retval = -ENOENT;
-
-	return retval;
-}
-
-static int i2c_pnx_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	int retval = 0;
-#ifdef CONFIG_PM
-	retval = set_clock_run(pdev);
-#endif
-	return retval;
-}
-
-static int i2c_pnx_resume(struct platform_device *pdev)
-{
-	int retval = 0;
-#ifdef CONFIG_PM
-	retval = set_clock_run(pdev);
-#endif
-	return retval;
-}
-
-static u32 calculate_input_freq(struct platform_device *pdev)
-{
-	return HCLK_MHZ;
-}
-
-
-static struct i2c_pnx_algo_data pnx_algo_data0 = {
+static struct i2c_pnx_data i2c0_data = {
+	.name = I2C_CHIP_NAME "0",
 	.base = PNX4008_I2C1_BASE,
 	.irq = I2C_1_INT,
 };
 
-static struct i2c_pnx_algo_data pnx_algo_data1 = {
+static struct i2c_pnx_data i2c1_data = {
+	.name = I2C_CHIP_NAME "1",
 	.base = PNX4008_I2C2_BASE,
 	.irq = I2C_2_INT,
 };
 
-static struct i2c_pnx_algo_data pnx_algo_data2 = {
+static struct i2c_pnx_data i2c2_data = {
+	.name = "USB-I2C",
 	.base = (PNX4008_USB_CONFIG_BASE + 0x300),
 	.irq = USB_I2C_INT,
 };
 
-static struct i2c_adapter pnx_adapter0 = {
-	.name = I2C_CHIP_NAME "0",
-	.algo_data = &pnx_algo_data0,
-};
-static struct i2c_adapter pnx_adapter1 = {
-	.name = I2C_CHIP_NAME "1",
-	.algo_data = &pnx_algo_data1,
-};
-
-static struct i2c_adapter pnx_adapter2 = {
-	.name = "USB-I2C",
-	.algo_data = &pnx_algo_data2,
-};
-
-static struct i2c_pnx_data i2c0_data = {
-	.suspend = i2c_pnx_suspend,
-	.resume = i2c_pnx_resume,
-	.calculate_input_freq = calculate_input_freq,
-	.set_clock_run = set_clock_run,
-	.set_clock_stop = set_clock_stop,
-	.adapter = &pnx_adapter0,
-};
-
-static struct i2c_pnx_data i2c1_data = {
-	.suspend = i2c_pnx_suspend,
-	.resume = i2c_pnx_resume,
-	.calculate_input_freq = calculate_input_freq,
-	.set_clock_run = set_clock_run,
-	.set_clock_stop = set_clock_stop,
-	.adapter = &pnx_adapter1,
-};
-
-static struct i2c_pnx_data i2c2_data = {
-	.suspend = i2c_pnx_suspend,
-	.resume = i2c_pnx_resume,
-	.calculate_input_freq = calculate_input_freq,
-	.set_clock_run = set_clock_run,
-	.set_clock_stop = set_clock_stop,
-	.adapter = &pnx_adapter2,
-};
-
 static struct platform_device i2c0_device = {
 	.name = "pnx-i2c",
 	.id = 0,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/include/mach/clkdev.h linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/include/mach/clkdev.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/include/mach/clkdev.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/include/mach/clkdev.h	2010-05-16 17:17:36.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.33-gnu1/arch/arm/mach-pnx4008/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
  *
 */
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		mov	\rx, #0x00090000
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/include/mach/timex.h linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/include/mach/timex.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/include/mach/timex.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/include/mach/timex.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,60 +14,6 @@
 #ifndef __PNX4008_TIMEX_H
 #define __PNX4008_TIMEX_H
 
-#include <linux/io.h>
-#include <mach/hardware.h>
-
 #define CLOCK_TICK_RATE		1000000
 
-#define TICKS2USECS(x)	(x)
-
-/* MilliSecond Timer - Chapter 21 Page 202 */
-
-#define MSTIM_INT     IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x0))
-#define MSTIM_CTRL    IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x4))
-#define MSTIM_COUNTER IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x8))
-#define MSTIM_MCTRL   IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x14))
-#define MSTIM_MATCH0  IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x18))
-#define MSTIM_MATCH1  IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x1c))
-
-/* High Speed Timer - Chpater 22, Page 205 */
-
-#define HSTIM_INT     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x0))
-#define HSTIM_CTRL    IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x4))
-#define HSTIM_COUNTER IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x8))
-#define HSTIM_PMATCH  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0xC))
-#define HSTIM_PCOUNT  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x10))
-#define HSTIM_MCTRL   IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x14))
-#define HSTIM_MATCH0  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x18))
-#define HSTIM_MATCH1  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x1c))
-#define HSTIM_MATCH2  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x20))
-#define HSTIM_CCR     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x28))
-#define HSTIM_CR0     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x2C))
-#define HSTIM_CR1     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x30))
-
-/* IMPORTANT: both timers are UPCOUNTING */
-
-/* xSTIM_MCTRL bit definitions */
-#define MR0_INT        1
-#define RESET_COUNT0   (1<<1)
-#define STOP_COUNT0    (1<<2)
-#define MR1_INT        (1<<3)
-#define RESET_COUNT1   (1<<4)
-#define STOP_COUNT1    (1<<5)
-#define MR2_INT        (1<<6)
-#define RESET_COUNT2   (1<<7)
-#define STOP_COUNT2    (1<<8)
-
-/* xSTIM_CTRL bit definitions */
-#define COUNT_ENAB     1
-#define RESET_COUNT    (1<<1)
-#define DEBUG_EN       (1<<2)
-
-/* xSTIM_INT bit definitions */
-#define MATCH0_INT     1
-#define MATCH1_INT     (1<<1)
-#define MATCH2_INT     (1<<2)
-#define RTC_TICK0      (1<<4)
-#define RTC_TICK1      (1<<5)
-
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/pm.c linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/pm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/pm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,8 +19,11 @@
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/cacheflush.h>
+
+#include <mach/hardware.h>
 #include <mach/pm.h>
 #include <mach/clock.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/time.c linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/time.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,8 @@
 #include <asm/mach/time.h>
 #include <asm/errno.h>
 
+#include "time.h"
+
 /*! Note: all timers are UPCOUNTING */
 
 /*!
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/time.h linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/time.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pnx4008/time.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pnx4008/time.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,70 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/timex.h
+ *
+ * PNX4008 timers header file
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef PNX_TIME_H
+#define PNX_TIME_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+
+#define TICKS2USECS(x)	(x)
+
+/* MilliSecond Timer - Chapter 21 Page 202 */
+
+#define MSTIM_INT     IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x0))
+#define MSTIM_CTRL    IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x4))
+#define MSTIM_COUNTER IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x8))
+#define MSTIM_MCTRL   IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x14))
+#define MSTIM_MATCH0  IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x18))
+#define MSTIM_MATCH1  IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x1c))
+
+/* High Speed Timer - Chpater 22, Page 205 */
+
+#define HSTIM_INT     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x0))
+#define HSTIM_CTRL    IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x4))
+#define HSTIM_COUNTER IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x8))
+#define HSTIM_PMATCH  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0xC))
+#define HSTIM_PCOUNT  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x10))
+#define HSTIM_MCTRL   IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x14))
+#define HSTIM_MATCH0  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x18))
+#define HSTIM_MATCH1  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x1c))
+#define HSTIM_MATCH2  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x20))
+#define HSTIM_CCR     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x28))
+#define HSTIM_CR0     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x2C))
+#define HSTIM_CR1     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x30))
+
+/* IMPORTANT: both timers are UPCOUNTING */
+
+/* xSTIM_MCTRL bit definitions */
+#define MR0_INT        1
+#define RESET_COUNT0   (1<<1)
+#define STOP_COUNT0    (1<<2)
+#define MR1_INT        (1<<3)
+#define RESET_COUNT1   (1<<4)
+#define STOP_COUNT1    (1<<5)
+#define MR2_INT        (1<<6)
+#define RESET_COUNT2   (1<<7)
+#define STOP_COUNT2    (1<<8)
+
+/* xSTIM_CTRL bit definitions */
+#define COUNT_ENAB     1
+#define RESET_COUNT    (1<<1)
+#define DEBUG_EN       (1<<2)
+
+/* xSTIM_INT bit definitions */
+#define MATCH0_INT     1
+#define MATCH1_INT     (1<<1)
+#define MATCH2_INT     (1<<2)
+#define RTC_TICK0      (1<<4)
+#define RTC_TICK1      (1<<5)
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/am300epd.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/am300epd.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/am300epd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/am300epd.c	2010-05-16 17:17:36.000000000 -0400
@@ -288,7 +288,7 @@ int __init am300_init(void)
 }
 
 module_param(panel_type, uint, 0);
-MODULE_PARM_DESC(panel_type, "Select the panel type: 6, 8, 97");
+MODULE_PARM_DESC(panel_type, "Select the panel type: 37, 6, 97");
 
 MODULE_DESCRIPTION("board driver for am300 epd kit");
 MODULE_AUTHOR("Jaya Kumar");
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/balloon3.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/balloon3.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/balloon3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/balloon3.c	2010-05-16 17:17:36.000000000 -0400
@@ -132,6 +132,14 @@ static void __init balloon3_init_irq(voi
 		"enabled\n", __func__, BALLOON3_AUX_NIRQ);
 }
 
+static unsigned long balloon3_ac97_pin_config[] = {
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+	GPIO113_AC97_nRESET,
+};
+
 static void balloon3_backlight_power(int on)
 {
 	pr_debug("%s: power is %s\n", __func__, on ? "on" : "off");
@@ -140,26 +148,7 @@ static void balloon3_backlight_power(int
 
 static unsigned long balloon3_lcd_pin_config[] = {
 	/* LCD - 16bpp Active TFT */
-	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,
+	GPIOxx_LCD_TFT_16BPP,
 
 	GPIO99_GPIO,		/* Backlight */
 };
@@ -311,8 +300,10 @@ static void __init balloon3_init(void)
 	pxa_set_stuart_info(NULL);
 
 	pxa_set_i2c_info(NULL);
-	if (balloon3_has(BALLOON3_FEATURE_AUDIO))
+	if (balloon3_has(BALLOON3_FEATURE_AUDIO)) {
+		pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_ac97_pin_config));
 		pxa_set_ac97_info(NULL);
+	}
 
 	if (balloon3_has(BALLOON3_FEATURE_TOPPOLY)) {
 		pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_lcd_pin_config));
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/capc7117.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/capc7117.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/capc7117.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/capc7117.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,158 @@
+/*
+ * linux/arch/arm/mach-pxa/capc7117.c
+ *
+ * Support for the Embedian CAPC-7117 Evaluation Kit
+ * based on the Embedian MXM-8x10 Computer on Module
+ *
+ * Copyright (C) 2009 Embedian Inc.
+ * Copyright (C) 2009 TMT Services & Supplies (Pty) Ltd.
+ *
+ * 2007-09-04: eric miao <eric.y.miao@gmail.com>
+ *             rewrite to align with latest kernel
+ *
+ * 2010-01-09: Edwin Peer <epeer@tmtservices.co.za>
+ *             Hennie van der Merwe <hvdmerwe@tmtservices.co.za>
+ *             rework for upstream merge
+ *
+ * This program is free software; you can 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/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/serial_8250.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa320.h>
+#include <mach/mxm8x10.h>
+
+#include "generic.h"
+
+/* IDE (PATA) Support */
+static struct pata_platform_info pata_platform_data = {
+	.ioport_shift = 1
+};
+
+static struct resource capc7117_ide_resources[] = {
+	[0] = {
+	       .start = 0x11000020,
+	       .end = 0x1100003f,
+	       .flags = IORESOURCE_MEM
+	},
+	[1] = {
+	       .start = 0x1100001c,
+	       .end = 0x1100001c,
+	       .flags = IORESOURCE_MEM
+	},
+	[2] = {
+	       .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO76)),
+	       .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO76)),
+	       .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING
+	}
+};
+
+static struct platform_device capc7117_ide_device = {
+	.name = "pata_platform",
+	.num_resources = ARRAY_SIZE(capc7117_ide_resources),
+	.resource = capc7117_ide_resources,
+	.dev = {
+		.platform_data = &pata_platform_data,
+		.coherent_dma_mask = ~0		/* grumble */
+	}
+};
+
+static void __init capc7117_ide_init(void)
+{
+	platform_device_register(&capc7117_ide_device);
+}
+
+/* TI16C752 UART support */
+#define	TI16C752_FLAGS		(UPF_BOOT_AUTOCONF | \
+					UPF_IOREMAP | \
+					UPF_BUGGY_UART | \
+					UPF_SKIP_TEST)
+#define	TI16C752_UARTCLK	(22118400)
+static struct plat_serial8250_port ti16c752_platform_data[] = {
+	[0] = {
+	       .mapbase = 0x14000000,
+	       .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO78)),
+	       .irqflags = IRQF_TRIGGER_RISING,
+	       .flags = TI16C752_FLAGS,
+	       .iotype = UPIO_MEM,
+	       .regshift = 1,
+	       .uartclk = TI16C752_UARTCLK
+	},
+	[1] = {
+	       .mapbase = 0x14000040,
+	       .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO79)),
+	       .irqflags = IRQF_TRIGGER_RISING,
+	       .flags = TI16C752_FLAGS,
+	       .iotype = UPIO_MEM,
+	       .regshift = 1,
+	       .uartclk = TI16C752_UARTCLK
+	},
+	[2] = {
+	       .mapbase = 0x14000080,
+	       .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO80)),
+	       .irqflags = IRQF_TRIGGER_RISING,
+	       .flags = TI16C752_FLAGS,
+	       .iotype = UPIO_MEM,
+	       .regshift = 1,
+	       .uartclk = TI16C752_UARTCLK
+	},
+	[3] = {
+	       .mapbase = 0x140000c0,
+	       .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO81)),
+	       .irqflags = IRQF_TRIGGER_RISING,
+	       .flags = TI16C752_FLAGS,
+	       .iotype = UPIO_MEM,
+	       .regshift = 1,
+	       .uartclk = TI16C752_UARTCLK
+	},
+	[4] = {
+	       /* end of array */
+	}
+};
+
+static struct platform_device ti16c752_device = {
+	.name = "serial8250",
+	.id = PLAT8250_DEV_PLATFORM,
+	.dev = {
+		.platform_data = ti16c752_platform_data
+	}
+};
+
+static void __init capc7117_uarts_init(void)
+{
+	platform_device_register(&ti16c752_device);
+}
+
+static void __init capc7117_init(void)
+{
+	/* Init CoM */
+	mxm_8x10_barebones_init();
+
+	/* Init evaluation board peripherals */
+	mxm_8x10_ac97_init();
+	mxm_8x10_usb_host_init();
+	mxm_8x10_mmc_init();
+
+	capc7117_uarts_init();
+	capc7117_ide_init();
+}
+
+MACHINE_START(CAPC7117,
+	      "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM")
+	.phys_io = 0x40000000,
+	.boot_params = 0xa0000100,
+	.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io = pxa_map_io,
+	.init_irq = pxa3xx_init_irq,
+	.timer = &pxa_timer,
+	.init_machine = capc7117_init
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -78,11 +78,3 @@ const struct clkops clk_cken_ops = {
 	.enable		= clk_cken_enable,
 	.disable	= clk_cken_disable,
 };
-
-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.33-gnu1/arch/arm/mach-pxa/clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -67,7 +67,3 @@ extern void clk_pxa3xx_cken_enable(struc
 extern void clk_pxa3xx_cken_disable(struct clk *);
 #endif
 
-void clks_register(struct clk_lookup *clks, size_t num);
-int clk_add_alias(const char *alias, const char *alias_name, char *id,
-	struct device *dev);
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/cm-x255.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/cm-x255.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/cm-x255.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/cm-x255.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,26 +50,7 @@ static unsigned long cmx255_pin_config[]
 	GPIO47_STUART_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,
+	GPIOxx_LCD_TFT_16BPP,
 
 	/* SSP1 */
 	GPIO23_SSP1_SCLK,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/cm-x270.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/cm-x270.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/cm-x270.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/cm-x270.c	2010-05-16 17:17:36.000000000 -0400
@@ -71,26 +71,7 @@ static unsigned long cmx270_pin_config[]
 	GPIO111_MMC_DAT_3,
 
 	/* 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,
+	GPIOxx_LCD_TFT_16BPP,
 
 	/* I2C */
 	GPIO117_I2C_SCL,
@@ -195,33 +176,57 @@ static struct resource cmx270_2700G_reso
 	},
 };
 
-static unsigned long save_lcd_regs[10];
+static unsigned long cmx270_marathon_on[] = {
+	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,
+	GPIO74_GPIO,
+	GPIO75_GPIO,
+	GPIO76_GPIO,
+	GPIO77_GPIO,
+};
+
+static unsigned long cmx270_marathon_off[] = {
+	GPIOxx_LCD_TFT_16BPP,
+};
 
 static int cmx270_marathon_probe(struct fb_info *fb)
 {
-	/* save PXA-270 pin settings before enabling 2700G */
-	save_lcd_regs[0] = GPDR1;
-	save_lcd_regs[1] = GPDR2;
-	save_lcd_regs[2] = GAFR1_U;
-	save_lcd_regs[3] = GAFR2_L;
-	save_lcd_regs[4] = GAFR2_U;
+	int gpio, err;
 
-	/* Disable PXA-270 on-chip controller driving pins */
-	GPDR1 &= ~(0xfc000000);
-	GPDR2 &= ~(0x00c03fff);
-	GAFR1_U &= ~(0xfff00000);
-	GAFR2_L &= ~(0x0fffffff);
-	GAFR2_U &= ~(0x0000f000);
+	for (gpio = 58; gpio <= 77; gpio++) {
+		err = gpio_request(gpio, "LCD");
+		if (err)
+			return err;
+		gpio_direction_input(gpio);
+	}
+
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_marathon_on));
 	return 0;
 }
 
 static int cmx270_marathon_remove(struct fb_info *fb)
 {
-	GPDR1 =   save_lcd_regs[0];
-	GPDR2 =   save_lcd_regs[1];
-	GAFR1_U = save_lcd_regs[2];
-	GAFR2_L = save_lcd_regs[3];
-	GAFR2_U = save_lcd_regs[4];
+	int gpio;
+
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_marathon_off));
+
+	for (gpio = 58; gpio <= 77; gpio++)
+		gpio_free(gpio);
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/cm-x2xx-pci.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/cm-x2xx-pci.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/cm-x2xx-pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/cm-x2xx-pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -59,7 +59,7 @@ void __init cmx2xx_pci_adjust_zones(int
 static void cmx2xx_it8152_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
 	/* clear our parent irq */
-	GEDR(cmx2xx_it8152_irq_gpio) = GPIO_bit(cmx2xx_it8152_irq_gpio);
+	desc->chip->ack(irq);
 
 	it8152_irq_demux(irq, desc);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/corgi_ssp.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/corgi_ssp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/corgi_ssp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/corgi_ssp.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <mach/hardware.h>
@@ -204,7 +203,7 @@ void __init corgi_ssp_set_machinfo(struc
 	ssp_machinfo = machinfo;
 }
 
-static int __init corgi_ssp_probe(struct platform_device *dev)
+static int __devinit corgi_ssp_probe(struct platform_device *dev)
 {
 	int ret;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/cpufreq-pxa3xx.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/cpufreq-pxa3xx.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/cpufreq-pxa3xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/cpufreq-pxa3xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
+#include <linux/slab.h>
 
 #include <mach/pxa3xx-regs.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e740.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/e740.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e740.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/e740.c	2010-05-16 17:17:36.000000000 -0400
@@ -134,6 +134,12 @@ static unsigned long e740_pin_config[] _
 	/* IrDA */
 	GPIO38_GPIO | MFP_LPM_DRIVE_HIGH,
 
+	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+
 	/* Audio power control */
 	GPIO16_GPIO,  /* AC97 codec AVDD2 supply (analogue power) */
 	GPIO40_GPIO,  /* Mic amp power */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e750.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/e750.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e750.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/e750.c	2010-05-16 17:17:36.000000000 -0400
@@ -132,6 +132,12 @@ static unsigned long e750_pin_config[] _
 	/* IrDA */
 	GPIO38_GPIO | MFP_LPM_DRIVE_HIGH,
 
+	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+
 	/* Audio power control */
 	GPIO4_GPIO,  /* Headphone amp power */
 	GPIO7_GPIO,  /* Speaker amp power */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e800.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/e800.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e800.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/e800.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,14 @@
 
 /* ------------------------ e800 LCD definitions ------------------------- */
 
+static unsigned long e800_pin_config[] __initdata = {
+	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+};
+
 static struct w100_gen_regs e800_lcd_regs = {
 	.lcd_format =            0x00008003,
 	.lcdd_cntl1 =            0x02a00000,
@@ -195,6 +203,7 @@ static struct platform_device *devices[]
 
 static void __init e800_init(void)
 {
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(e800_pin_config));
 	pxa_set_ffuart_info(NULL);
 	pxa_set_btuart_info(NULL);
 	pxa_set_stuart_info(NULL);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/em-x270.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/em-x270.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/em-x270.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/em-x270.c	2010-05-16 17:17:36.000000000 -0400
@@ -109,26 +109,7 @@ static unsigned long common_pin_config[]
 	GPIO111_MMC_DAT_3,
 
 	/* 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,
+	GPIOxx_LCD_TFT_16BPP,
 
 	/* QCI */
 	GPIO84_CIF_FV,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/eseries.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/eseries.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/eseries.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/eseries.c	2010-05-16 17:17:36.000000000 -0400
@@ -128,6 +128,6 @@ static struct clk_lookup eseries_clkregs
 
 void eseries_register_clks(void)
 {
-	clks_register(eseries_clkregs, ARRAY_SIZE(eseries_clkregs));
+	clkdev_add_table(eseries_clkregs, ARRAY_SIZE(eseries_clkregs));
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/icontrol.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/icontrol.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/icontrol.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/icontrol.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,202 @@
+/*
+ * linux/arch/arm/mach-pxa/icontrol.c
+ *
+ * Support for the iControl and SafeTcam platforms from TMT Services
+ * using the Embedian MXM-8x10 Computer on Module
+ *
+ * Copyright (C) 2009 TMT Services & Supplies (Pty) Ltd.
+ *
+ * 2010-01-21 Hennie van der Merve <hvdmerwe@tmtservies.co.za>
+ *
+ * This program is free software; you can 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/platform_device.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa320.h>
+#include <mach/mxm8x10.h>
+
+#include <linux/spi/spi.h>
+#include <mach/pxa2xx_spi.h>
+#include <linux/can/platform/mcp251x.h>
+
+#include "generic.h"
+
+#define ICONTROL_MCP251x_nCS1	(15)
+#define ICONTROL_MCP251x_nCS2	(16)
+#define ICONTROL_MCP251x_nCS3	(17)
+#define ICONTROL_MCP251x_nCS4	(24)
+
+#define ICONTROL_MCP251x_nIRQ1	(74)
+#define ICONTROL_MCP251x_nIRQ2	(75)
+#define ICONTROL_MCP251x_nIRQ3	(76)
+#define ICONTROL_MCP251x_nIRQ4	(77)
+
+static struct pxa2xx_spi_chip mcp251x_chip_info1 = {
+	.tx_threshold   = 8,
+	.rx_threshold   = 128,
+	.dma_burst_size = 8,
+	.timeout        = 235,
+	.gpio_cs        = ICONTROL_MCP251x_nCS1
+};
+
+static struct pxa2xx_spi_chip mcp251x_chip_info2 = {
+	.tx_threshold   = 8,
+	.rx_threshold   = 128,
+	.dma_burst_size = 8,
+	.timeout        = 235,
+	.gpio_cs        = ICONTROL_MCP251x_nCS2
+};
+
+static struct pxa2xx_spi_chip mcp251x_chip_info3 = {
+	.tx_threshold   = 8,
+	.rx_threshold   = 128,
+	.dma_burst_size = 8,
+	.timeout        = 235,
+	.gpio_cs        = ICONTROL_MCP251x_nCS3
+};
+
+static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
+	.tx_threshold   = 8,
+	.rx_threshold   = 128,
+	.dma_burst_size = 8,
+	.timeout        = 235,
+	.gpio_cs        = ICONTROL_MCP251x_nCS4
+};
+
+static struct mcp251x_platform_data mcp251x_info = {
+	.oscillator_frequency = 16E6,
+	.model                = CAN_MCP251X_MCP2515,
+	.board_specific_setup = NULL,
+	.power_enable         = NULL,
+	.transceiver_enable   = NULL
+};
+
+static struct spi_board_info mcp251x_board_info[] = {
+	{
+		.modalias        = "mcp251x",
+		.max_speed_hz    = 6500000,
+		.bus_num         = 3,
+		.chip_select     = 0,
+		.platform_data   = &mcp251x_info,
+		.controller_data = &mcp251x_chip_info1,
+		.irq             = gpio_to_irq(ICONTROL_MCP251x_nIRQ1)
+	},
+	{
+		.modalias        = "mcp251x",
+		.max_speed_hz    = 6500000,
+		.bus_num         = 3,
+		.chip_select     = 1,
+		.platform_data   = &mcp251x_info,
+		.controller_data = &mcp251x_chip_info2,
+		.irq             = gpio_to_irq(ICONTROL_MCP251x_nIRQ2)
+	},
+	{
+		.modalias        = "mcp251x",
+		.max_speed_hz    = 6500000,
+		.bus_num         = 4,
+		.chip_select     = 0,
+		.platform_data   = &mcp251x_info,
+		.controller_data = &mcp251x_chip_info3,
+		.irq             = gpio_to_irq(ICONTROL_MCP251x_nIRQ3)
+	},
+	{
+		.modalias        = "mcp251x",
+		.max_speed_hz    = 6500000,
+		.bus_num         = 4,
+		.chip_select     = 1,
+		.platform_data   = &mcp251x_info,
+		.controller_data = &mcp251x_chip_info4,
+		.irq             = gpio_to_irq(ICONTROL_MCP251x_nIRQ4)
+	}
+};
+
+static struct pxa2xx_spi_master pxa_ssp3_spi_master_info = {
+	.clock_enable   = CKEN_SSP3,
+	.num_chipselect = 2,
+	.enable_dma     = 1
+};
+
+static struct pxa2xx_spi_master pxa_ssp4_spi_master_info = {
+	.clock_enable   = CKEN_SSP4,
+	.num_chipselect = 2,
+	.enable_dma     = 1
+};
+
+struct platform_device pxa_spi_ssp3 = {
+	.name          = "pxa2xx-spi",
+	.id            = 3,
+	.dev           = {
+		.platform_data = &pxa_ssp3_spi_master_info,
+	}
+};
+
+struct platform_device pxa_spi_ssp4 = {
+	.name          = "pxa2xx-spi",
+	.id            = 4,
+	.dev           = {
+		.platform_data = &pxa_ssp4_spi_master_info,
+	}
+};
+
+static struct platform_device *icontrol_spi_devices[] __initdata = {
+	&pxa_spi_ssp3,
+	&pxa_spi_ssp4,
+};
+
+static mfp_cfg_t mfp_can_cfg[] __initdata = {
+	/* CAN CS lines */
+	GPIO15_GPIO,
+	GPIO16_GPIO,
+	GPIO17_GPIO,
+	GPIO24_GPIO,
+
+	/* SPI (SSP3) lines */
+	GPIO89_SSP3_SCLK,
+	GPIO91_SSP3_TXD,
+	GPIO92_SSP3_RXD,
+
+	/* SPI (SSP4) lines */
+	GPIO93_SSP4_SCLK,
+	GPIO95_SSP4_TXD,
+	GPIO96_SSP4_RXD,
+
+	/* CAN nIRQ lines */
+	GPIO74_GPIO | MFP_LPM_EDGE_RISE,
+	GPIO75_GPIO | MFP_LPM_EDGE_RISE,
+	GPIO76_GPIO | MFP_LPM_EDGE_RISE,
+	GPIO77_GPIO | MFP_LPM_EDGE_RISE
+};
+
+static void __init icontrol_can_init(void)
+{
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_can_cfg));
+	platform_add_devices(ARRAY_AND_SIZE(icontrol_spi_devices));
+	spi_register_board_info(ARRAY_AND_SIZE(mcp251x_board_info));
+}
+
+static void __init icontrol_init(void)
+{
+	mxm_8x10_barebones_init();
+	mxm_8x10_usb_host_init();
+	mxm_8x10_mmc_init();
+
+	icontrol_can_init();
+}
+
+MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM")
+	.phys_io	= 0x40000000,
+	.boot_params	= 0xa0000100,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa3xx_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= icontrol_init
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/idp.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/idp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/idp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/idp.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,25 +47,7 @@
 
 static unsigned long idp_pin_config[] __initdata = {
 	/* 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,
+	GPIOxx_LCD_DSTN_16BPP,
 
 	/* BTUART */
 	GPIO42_BTUART_RXD,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/imote2.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/imote2.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/imote2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/imote2.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,7 +64,6 @@ static unsigned long imote2_pin_config[]
 	GPIO116_GPIO,			/* CC_CCA */
 	GPIO0_GPIO,			/* CC_FIFOP */
 	GPIO16_GPIO,			/* CCSFD */
-	GPIO39_GPIO,			/* CSn */
 	GPIO115_GPIO,			/* Power enable */
 
 	/* I2C */
@@ -72,7 +71,7 @@ static unsigned long imote2_pin_config[]
 	GPIO118_I2C_SDA,
 
 	/* SSP 3 - 802.15.4 radio */
-	GPIO39_GPIO, 			/* Chip Select */
+	GPIO39_GPIO,			/* Chip Select */
 	GPIO34_SSP3_SCLK,
 	GPIO35_SSP3_TXD,
 	GPIO41_SSP3_RXD,
@@ -560,10 +559,6 @@ static void __init imote2_init(void)
 	pxa_set_btuart_info(NULL);
 	pxa_set_stuart_info(NULL);
 
-	/* SPI chip select directions - all other directions should
-	 * be handled by drivers.*/
-	gpio_direction_output(37, 0);
-
 	platform_add_devices(imote2_devices, ARRAY_SIZE(imote2_devices));
 
 	pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/balloon3.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/balloon3.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/balloon3.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/balloon3.h	2010-05-16 17:17:36.000000000 -0400
@@ -129,6 +129,16 @@ enum balloon3_features {
 #define CPLD_AROUTING_LOONR2INT_BIT    6
 #define CPLD_AROUTING_LOONR2EXT_BIT    7
 
+/* Balloon3 Interrupts */
+#define BALLOON3_IRQ(x)		(IRQ_BOARD_START + (x))
+
+#define BALLOON3_BP_CF_NRDY_IRQ	BALLOON3_IRQ(0)
+#define BALLOON3_BP_NSTSCHG_IRQ	BALLOON3_IRQ(1)
+
+#define BALLOON3_AUX_NIRQ	IRQ_GPIO(BALLOON3_GPIO_AUX_NIRQ)
+#define BALLOON3_CODEC_IRQ	IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ)
+#define BALLOON3_S0_CD_IRQ	IRQ_GPIO(BALLOON3_GPIO_S0_CD)
+
 extern int balloon3_has(enum balloon3_features feature);
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/camera.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/camera.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/camera.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/camera.h	2010-05-16 17:17:36.000000000 -0400
@@ -35,8 +35,6 @@
 #define PXA_CAMERA_VSP		0x400
 
 struct pxacamera_platform_data {
-	int (*init)(struct device *);
-
 	unsigned long flags;
 	unsigned long mclk_10khz;
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/colibri.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/colibri.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/colibri.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/colibri.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
 #define _COLIBRI_H_
 
 #include <net/ax88796.h>
+#include <mach/mfp.h>
 
 /*
  * common settings for all modules
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,7 @@
 
 #include "hardware.h"
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #0x40000000		@ physical
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/hardware.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/hardware.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/hardware.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/hardware.h	2010-05-16 17:17:36.000000000 -0400
@@ -202,7 +202,7 @@
 #define __cpu_is_pxa950(id)                             \
 	({                                              \
 		unsigned int _id = (id) >> 4 & 0xfff;	\
-		id == 0x697;				\
+		_id == 0x697;				\
 	 })
 #else
 #define __cpu_is_pxa950(id)	(0)
@@ -314,7 +314,6 @@ extern unsigned long get_clock_tick_rate
 #define PCIBIOS_MIN_IO		0
 #define PCIBIOS_MIN_MEM		0
 #define pcibios_assign_all_busses()	1
-#define HAVE_ARCH_PCI_SET_DMA_MASK	1
 #endif
 
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/irqs.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/irqs.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/irqs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/irqs.h	2010-05-16 17:17:36.000000000 -0400
@@ -135,82 +135,6 @@
 #define IRQ_BOARD_END		(IRQ_BOARD_START + 16)
 #endif
 
-#define IRQ_SA1111_START	(IRQ_BOARD_END)
-#define IRQ_GPAIN0		(IRQ_BOARD_END + 0)
-#define IRQ_GPAIN1		(IRQ_BOARD_END + 1)
-#define IRQ_GPAIN2		(IRQ_BOARD_END + 2)
-#define IRQ_GPAIN3		(IRQ_BOARD_END + 3)
-#define IRQ_GPBIN0		(IRQ_BOARD_END + 4)
-#define IRQ_GPBIN1		(IRQ_BOARD_END + 5)
-#define IRQ_GPBIN2		(IRQ_BOARD_END + 6)
-#define IRQ_GPBIN3		(IRQ_BOARD_END + 7)
-#define IRQ_GPBIN4		(IRQ_BOARD_END + 8)
-#define IRQ_GPBIN5		(IRQ_BOARD_END + 9)
-#define IRQ_GPCIN0		(IRQ_BOARD_END + 10)
-#define IRQ_GPCIN1		(IRQ_BOARD_END + 11)
-#define IRQ_GPCIN2		(IRQ_BOARD_END + 12)
-#define IRQ_GPCIN3		(IRQ_BOARD_END + 13)
-#define IRQ_GPCIN4		(IRQ_BOARD_END + 14)
-#define IRQ_GPCIN5		(IRQ_BOARD_END + 15)
-#define IRQ_GPCIN6		(IRQ_BOARD_END + 16)
-#define IRQ_GPCIN7		(IRQ_BOARD_END + 17)
-#define IRQ_MSTXINT		(IRQ_BOARD_END + 18)
-#define IRQ_MSRXINT		(IRQ_BOARD_END + 19)
-#define IRQ_MSSTOPERRINT	(IRQ_BOARD_END + 20)
-#define IRQ_TPTXINT		(IRQ_BOARD_END + 21)
-#define IRQ_TPRXINT		(IRQ_BOARD_END + 22)
-#define IRQ_TPSTOPERRINT	(IRQ_BOARD_END + 23)
-#define SSPXMTINT		(IRQ_BOARD_END + 24)
-#define SSPRCVINT		(IRQ_BOARD_END + 25)
-#define SSPROR			(IRQ_BOARD_END + 26)
-#define AUDXMTDMADONEA		(IRQ_BOARD_END + 32)
-#define AUDRCVDMADONEA		(IRQ_BOARD_END + 33)
-#define AUDXMTDMADONEB		(IRQ_BOARD_END + 34)
-#define AUDRCVDMADONEB		(IRQ_BOARD_END + 35)
-#define AUDTFSR			(IRQ_BOARD_END + 36)
-#define AUDRFSR			(IRQ_BOARD_END + 37)
-#define AUDTUR			(IRQ_BOARD_END + 38)
-#define AUDROR			(IRQ_BOARD_END + 39)
-#define AUDDTS			(IRQ_BOARD_END + 40)
-#define AUDRDD			(IRQ_BOARD_END + 41)
-#define AUDSTO			(IRQ_BOARD_END + 42)
-#define IRQ_USBPWR		(IRQ_BOARD_END + 43)
-#define IRQ_HCIM		(IRQ_BOARD_END + 44)
-#define IRQ_HCIBUFFACC		(IRQ_BOARD_END + 45)
-#define IRQ_HCIRMTWKP		(IRQ_BOARD_END + 46)
-#define IRQ_NHCIMFCIR		(IRQ_BOARD_END + 47)
-#define IRQ_USB_PORT_RESUME	(IRQ_BOARD_END + 48)
-#define IRQ_S0_READY_NINT	(IRQ_BOARD_END + 49)
-#define IRQ_S1_READY_NINT	(IRQ_BOARD_END + 50)
-#define IRQ_S0_CD_VALID		(IRQ_BOARD_END + 51)
-#define IRQ_S1_CD_VALID		(IRQ_BOARD_END + 52)
-#define IRQ_S0_BVD1_STSCHG	(IRQ_BOARD_END + 53)
-#define IRQ_S1_BVD1_STSCHG	(IRQ_BOARD_END + 54)
-
-#define IRQ_LOCOMO_START	(IRQ_BOARD_END)
-#define IRQ_LOCOMO_KEY		(IRQ_BOARD_END + 0)
-#define IRQ_LOCOMO_GPIO0	(IRQ_BOARD_END + 1)
-#define IRQ_LOCOMO_GPIO1	(IRQ_BOARD_END + 2)
-#define IRQ_LOCOMO_GPIO2	(IRQ_BOARD_END + 3)
-#define IRQ_LOCOMO_GPIO3	(IRQ_BOARD_END + 4)
-#define IRQ_LOCOMO_GPIO4	(IRQ_BOARD_END + 5)
-#define IRQ_LOCOMO_GPIO5	(IRQ_BOARD_END + 6)
-#define IRQ_LOCOMO_GPIO6	(IRQ_BOARD_END + 7)
-#define IRQ_LOCOMO_GPIO7	(IRQ_BOARD_END + 8)
-#define IRQ_LOCOMO_GPIO8	(IRQ_BOARD_END + 9)
-#define IRQ_LOCOMO_GPIO9	(IRQ_BOARD_END + 10)
-#define IRQ_LOCOMO_GPIO10	(IRQ_BOARD_END + 11)
-#define IRQ_LOCOMO_GPIO11	(IRQ_BOARD_END + 12)
-#define IRQ_LOCOMO_GPIO12	(IRQ_BOARD_END + 13)
-#define IRQ_LOCOMO_GPIO13	(IRQ_BOARD_END + 14)
-#define IRQ_LOCOMO_GPIO14	(IRQ_BOARD_END + 15)
-#define IRQ_LOCOMO_GPIO15	(IRQ_BOARD_END + 16)
-#define IRQ_LOCOMO_LT		(IRQ_BOARD_END + 17)
-#define IRQ_LOCOMO_SPI_RFR	(IRQ_BOARD_END + 18)
-#define IRQ_LOCOMO_SPI_RFW	(IRQ_BOARD_END + 19)
-#define IRQ_LOCOMO_SPI_OVRN	(IRQ_BOARD_END + 20)
-#define IRQ_LOCOMO_SPI_TEND	(IRQ_BOARD_END + 21)
-
 /*
  * Figure out the MAX IRQ number.
  *
@@ -219,89 +143,16 @@
  * Otherwise, we have the standard IRQs only.
  */
 #ifdef CONFIG_SA1111
-#define NR_IRQS			(IRQ_S1_BVD1_STSCHG + 1)
-#elif defined(CONFIG_SHARP_LOCOMO)
-#define NR_IRQS			(IRQ_LOCOMO_SPI_TEND + 1)
+#define NR_IRQS			(IRQ_BOARD_END + 55)
 #elif defined(CONFIG_PXA_HAVE_BOARD_IRQS)
 #define NR_IRQS			(IRQ_BOARD_END)
 #else
 #define NR_IRQS			(IRQ_BOARD_START)
 #endif
 
-/*
- * Board specific IRQs.  Define them here.
- * Do not surround them with ifdefs.
- */
-#define LUBBOCK_IRQ(x)		(IRQ_BOARD_START + (x))
-#define LUBBOCK_SD_IRQ		LUBBOCK_IRQ(0)
-#define LUBBOCK_SA1111_IRQ	LUBBOCK_IRQ(1)
-#define LUBBOCK_USB_IRQ		LUBBOCK_IRQ(2)  /* usb connect */
-#define LUBBOCK_ETH_IRQ		LUBBOCK_IRQ(3)
-#define LUBBOCK_UCB1400_IRQ	LUBBOCK_IRQ(4)
-#define LUBBOCK_BB_IRQ		LUBBOCK_IRQ(5)
-#define LUBBOCK_USB_DISC_IRQ	LUBBOCK_IRQ(6)  /* usb disconnect */
-#define LUBBOCK_LAST_IRQ	LUBBOCK_IRQ(6)
-
-#define LPD270_IRQ(x)		(IRQ_BOARD_START + (x))
-#define LPD270_USBC_IRQ		LPD270_IRQ(2)
-#define LPD270_ETHERNET_IRQ	LPD270_IRQ(3)
-#define LPD270_AC97_IRQ		LPD270_IRQ(4)
-
-#define MAINSTONE_IRQ(x)	(IRQ_BOARD_START + (x))
-#define MAINSTONE_MMC_IRQ	MAINSTONE_IRQ(0)
-#define MAINSTONE_USIM_IRQ	MAINSTONE_IRQ(1)
-#define MAINSTONE_USBC_IRQ	MAINSTONE_IRQ(2)
-#define MAINSTONE_ETHERNET_IRQ	MAINSTONE_IRQ(3)
-#define MAINSTONE_AC97_IRQ	MAINSTONE_IRQ(4)
-#define MAINSTONE_PEN_IRQ	MAINSTONE_IRQ(5)
-#define MAINSTONE_MSINS_IRQ	MAINSTONE_IRQ(6)
-#define MAINSTONE_EXBRD_IRQ	MAINSTONE_IRQ(7)
-#define MAINSTONE_S0_CD_IRQ	MAINSTONE_IRQ(9)
-#define MAINSTONE_S0_STSCHG_IRQ	MAINSTONE_IRQ(10)
-#define MAINSTONE_S0_IRQ	MAINSTONE_IRQ(11)
-#define MAINSTONE_S1_CD_IRQ	MAINSTONE_IRQ(13)
-#define MAINSTONE_S1_STSCHG_IRQ	MAINSTONE_IRQ(14)
-#define MAINSTONE_S1_IRQ	MAINSTONE_IRQ(15)
-
-/* Balloon3 Interrupts */
-#define BALLOON3_IRQ(x)		(IRQ_BOARD_START + (x))
-
-#define BALLOON3_BP_CF_NRDY_IRQ	BALLOON3_IRQ(0)
-#define BALLOON3_BP_NSTSCHG_IRQ	BALLOON3_IRQ(1)
-
-#define BALLOON3_AUX_NIRQ	IRQ_GPIO(BALLOON3_GPIO_AUX_NIRQ)
-#define BALLOON3_CODEC_IRQ	IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ)
-#define BALLOON3_S0_CD_IRQ	IRQ_GPIO(BALLOON3_GPIO_S0_CD)
-
-/* LoCoMo Interrupts (CONFIG_SHARP_LOCOMO) */
-#define IRQ_LOCOMO_KEY_BASE	(IRQ_BOARD_START + 0)
-#define IRQ_LOCOMO_GPIO_BASE	(IRQ_BOARD_START + 1)
-#define IRQ_LOCOMO_LT_BASE	(IRQ_BOARD_START + 2)
-#define IRQ_LOCOMO_SPI_BASE	(IRQ_BOARD_START + 3)
-
-/* phyCORE-PXA270 (PCM027) Interrupts */
-#define PCM027_IRQ(x)          (IRQ_BOARD_START + (x))
-#define PCM027_BTDET_IRQ       PCM027_IRQ(0)
-#define PCM027_FF_RI_IRQ       PCM027_IRQ(1)
-#define PCM027_MMCDET_IRQ      PCM027_IRQ(2)
-#define PCM027_PM_5V_IRQ       PCM027_IRQ(3)
-
-/* ITE8152 irqs */
 /* add IT8152 IRQs beyond BOARD_END */
 #ifdef CONFIG_PCI_HOST_ITE8152
-#define IT8152_IRQ(x)   (IRQ_BOARD_END + (x))
-
-/* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */
-#define IT8152_LD_IRQ_COUNT     9
-#define IT8152_LP_IRQ_COUNT     16
-#define IT8152_PD_IRQ_COUNT     15
-
-/* Priorities: */
-#define IT8152_PD_IRQ(i)        IT8152_IRQ(i)
-#define IT8152_LP_IRQ(i)        (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT)
-#define IT8152_LD_IRQ(i)        (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT + IT8152_LP_IRQ_COUNT)
-
-#define IT8152_LAST_IRQ         IT8152_LD_IRQ(IT8152_LD_IRQ_COUNT - 1)
+#define IT8152_LAST_IRQ         (IRQ_BOARD_END + 40)
 
 #if NR_IRQS < (IT8152_LAST_IRQ+1)
 #undef NR_IRQS
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/lpd270.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/lpd270.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/lpd270.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/lpd270.h	2010-05-16 17:17:36.000000000 -0400
@@ -34,5 +34,9 @@
 #define LPD270_INT_ETHERNET	(1 << 3)  /* Ethernet controller IRQ */
 #define LPD270_INT_USBC		(1 << 2)  /* USB client cable detection IRQ */
 
+#define LPD270_IRQ(x)		(IRQ_BOARD_START + (x))
+#define LPD270_USBC_IRQ		LPD270_IRQ(2)
+#define LPD270_ETHERNET_IRQ	LPD270_IRQ(3)
+#define LPD270_AC97_IRQ		LPD270_IRQ(4)
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/lubbock.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/lubbock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/lubbock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/lubbock.h	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,17 @@
 #define LUB_IRQ_SET_CLR		__LUB_REG(LUBBOCK_FPGA_PHYS + 0x0d0)
 #define LUB_GP			__LUB_REG(LUBBOCK_FPGA_PHYS + 0x100)
 
+/* Board specific IRQs */
+#define LUBBOCK_IRQ(x)		(IRQ_BOARD_START + (x))
+#define LUBBOCK_SD_IRQ		LUBBOCK_IRQ(0)
+#define LUBBOCK_SA1111_IRQ	LUBBOCK_IRQ(1)
+#define LUBBOCK_USB_IRQ		LUBBOCK_IRQ(2)  /* usb connect */
+#define LUBBOCK_ETH_IRQ		LUBBOCK_IRQ(3)
+#define LUBBOCK_UCB1400_IRQ	LUBBOCK_IRQ(4)
+#define LUBBOCK_BB_IRQ		LUBBOCK_IRQ(5)
+#define LUBBOCK_USB_DISC_IRQ	LUBBOCK_IRQ(6)  /* usb disconnect */
+#define LUBBOCK_LAST_IRQ	LUBBOCK_IRQ(6)
+
 #ifndef __ASSEMBLY__
 extern void lubbock_set_misc_wr(unsigned int mask, unsigned int set);
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/mainstone.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/mainstone.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/mainstone.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/mainstone.h	2010-05-16 17:17:36.000000000 -0400
@@ -117,4 +117,21 @@
 #define MST_PCMCIA_PWR_VCC_33   0x8	   /* voltage VCC = 3.3V */
 #define MST_PCMCIA_PWR_VCC_50   0x4	   /* voltage VCC = 5.0V */
 
+/* board specific IRQs */
+#define MAINSTONE_IRQ(x)	(IRQ_BOARD_START + (x))
+#define MAINSTONE_MMC_IRQ	MAINSTONE_IRQ(0)
+#define MAINSTONE_USIM_IRQ	MAINSTONE_IRQ(1)
+#define MAINSTONE_USBC_IRQ	MAINSTONE_IRQ(2)
+#define MAINSTONE_ETHERNET_IRQ	MAINSTONE_IRQ(3)
+#define MAINSTONE_AC97_IRQ	MAINSTONE_IRQ(4)
+#define MAINSTONE_PEN_IRQ	MAINSTONE_IRQ(5)
+#define MAINSTONE_MSINS_IRQ	MAINSTONE_IRQ(6)
+#define MAINSTONE_EXBRD_IRQ	MAINSTONE_IRQ(7)
+#define MAINSTONE_S0_CD_IRQ	MAINSTONE_IRQ(9)
+#define MAINSTONE_S0_STSCHG_IRQ	MAINSTONE_IRQ(10)
+#define MAINSTONE_S0_IRQ	MAINSTONE_IRQ(11)
+#define MAINSTONE_S1_CD_IRQ	MAINSTONE_IRQ(13)
+#define MAINSTONE_S1_STSCHG_IRQ	MAINSTONE_IRQ(14)
+#define MAINSTONE_S1_IRQ	MAINSTONE_IRQ(15)
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h	2010-05-16 17:17:36.000000000 -0400
@@ -190,4 +190,36 @@
 #define GPIO89_AC97_nRESET	MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH)
 #endif	/* CONFIG_CPU_PXA26x */
 
+/* commonly used pin configurations */
+#define GPIOxx_LCD_16BPP	\
+	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
+
+#define GPIOxx_LCD_DSTN_16BPP	\
+	GPIOxx_LCD_16BPP,	\
+	GPIO74_LCD_FCLK,	\
+	GPIO75_LCD_LCLK,	\
+	GPIO76_LCD_PCLK
+
+#define GPIOxx_LCD_TFT_16BPP	\
+	GPIOxx_LCD_16BPP,	\
+	GPIO74_LCD_FCLK,	\
+	GPIO75_LCD_LCLK,	\
+	GPIO76_LCD_PCLK,	\
+	GPIO77_LCD_BIAS
+
 #endif /* __ASM_ARCH_MFP_PXA25X_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h	2010-05-16 17:17:36.000000000 -0400
@@ -434,5 +434,32 @@
 #define GPIO112_nMSINS		MFP_CFG_IN(GPIO112, AF2)
 #define GPIO32_MSSCLK		MFP_CFG_OUT(GPIO32, AF1, DRIVE_LOW)
 
+/* commonly used pin configurations */
+#define GPIOxx_LCD_16BPP	\
+	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
+
+#define GPIOxx_LCD_TFT_16BPP	\
+	GPIOxx_LCD_16BPP,	\
+	GPIO74_LCD_FCLK,	\
+	GPIO75_LCD_LCLK,	\
+	GPIO76_LCD_PCLK,	\
+	GPIO77_LCD_BIAS
+
+
 extern int keypad_set_wake(unsigned int on);
 #endif /* __ASM_ARCH_MFP_PXA27X_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/mxm8x10.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/mxm8x10.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/mxm8x10.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/mxm8x10.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,21 @@
+#ifndef __MACH_MXM_8X10_H
+#define __MACH_MXM_8X10_H
+
+#define MXM_8X10_ETH_PHYS	0x13000000
+
+#if defined(CONFIG_MMC)
+
+#define MXM_8X10_SD_nCD (72)
+#define MXM_8X10_SD_WP (84)
+
+extern void mxm_8x10_mmc_init(void);
+#else
+static inline void mxm_8x10_mmc_init(void) {}
+#endif
+
+extern void mxm_8x10_usb_host_init(void);
+extern void mxm_8x10_ac97_init(void);
+
+extern void mxm_8x10_barebones_init(void);
+
+#endif /* __MACH_MXM_8X10_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/pcm027.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/pcm027.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/pcm027.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/pcm027.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,13 @@
  * Definitions of CPU card resources only
  */
 
+/* phyCORE-PXA270 (PCM027) Interrupts */
+#define PCM027_IRQ(x)          (IRQ_BOARD_START + (x))
+#define PCM027_BTDET_IRQ       PCM027_IRQ(0)
+#define PCM027_FF_RI_IRQ       PCM027_IRQ(1)
+#define PCM027_MMCDET_IRQ      PCM027_IRQ(2)
+#define PCM027_PM_5V_IRQ       PCM027_IRQ(3)
+
 /* I2C RTC */
 #define PCM027_RTC_IRQ_GPIO	0
 #define PCM027_RTC_IRQ		IRQ_GPIO(PCM027_RTC_IRQ_GPIO)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/regs-u2d.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/regs-u2d.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/regs-u2d.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/regs-u2d.h	2010-05-16 17:17:36.000000000 -0400
@@ -166,7 +166,8 @@
 #define U2DMACSR_BUSERRTYPE	(7 << 10)	/* PX Bus Error Type */
 #define U2DMACSR_EORINTR	(1 << 9)	/* End Of Receive */
 #define U2DMACSR_REQPEND	(1 << 8)	/* Request Pending */
-#define U2DMACSR_RASINTR	(1 << 4)	/* Request After Channel Stopped (read / write 1 clear) */#define U2DMACSR_STOPINTR	(1 << 3)	/* Stop Interrupt (read only) */
+#define U2DMACSR_RASINTR	(1 << 4)	/* Request After Channel Stopped (read / write 1 clear) */
+#define U2DMACSR_STOPINTR	(1 << 3)	/* Stop Interrupt (read only) */
 #define U2DMACSR_ENDINTR	(1 << 2)	/* End Interrupt (read / write 1 clear) */
 #define U2DMACSR_STARTINTR	(1 << 1)	/* Start Interrupt (read / write 1 clear) */
 #define U2DMACSR_BUSERRINTR	(1 << 0)	/* Bus Error Interrupt (read / write 1 clear) */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/ssp.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/ssp.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/ssp.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/ssp.h	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,7 @@ struct ssp_device {
 	int		drcmr_tx;
 };
 
+#ifdef CONFIG_PXA_SSP_LEGACY
 /*
  * SSP initialisation flags
  */
@@ -78,6 +79,7 @@ void ssp_restore_state(struct ssp_dev *d
 int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags);
 int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed);
 void ssp_exit(struct ssp_dev *dev);
+#endif /* CONFIG_PXA_SSP_LEGACY */
 
 /**
  * ssp_write_reg - Write to a SSP register
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/uncompress.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/uncompress.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/uncompress.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/uncompress.h	2010-05-16 17:17:36.000000000 -0400
@@ -10,20 +10,41 @@
  */
 
 #include <linux/serial_reg.h>
-#include <mach/regs-uart.h>
 #include <asm/mach-types.h>
 
-#define __REG(x)       ((volatile unsigned long *)x)
+#define FFUART_BASE	(0x40100000)
+#define BTUART_BASE	(0x40200000)
+#define STUART_BASE	(0x40700000)
 
-static volatile unsigned long *UART = FFUART;
+static unsigned long uart_base;
+static unsigned int uart_shift;
+static unsigned int uart_is_pxa;
+
+static inline unsigned char uart_read(int offset)
+{
+	return *(volatile unsigned char *)(uart_base + (offset << uart_shift));
+}
+
+static inline void uart_write(unsigned char val, int offset)
+{
+	*(volatile unsigned char *)(uart_base + (offset << uart_shift)) = val;
+}
+
+static inline int uart_is_enabled(void)
+{
+	/* assume enabled by default for non-PXA uarts */
+	return uart_is_pxa ? uart_read(UART_IER) & UART_IER_UUE : 1;
+}
 
 static inline void putc(char c)
 {
-	if (!(UART[UART_IER] & IER_UUE))
+	if (!uart_is_enabled())
 		return;
-	while (!(UART[UART_LSR] & LSR_TDRQ))
+
+	while (!(uart_read(UART_LSR) & UART_LSR_THRE))
 		barrier();
-	UART[UART_TX] = c;
+
+	uart_write(c, UART_TX);
 }
 
 /*
@@ -35,10 +56,21 @@ static inline void flush(void)
 
 static inline void arch_decomp_setup(void)
 {
+	/* initialize to default */
+	uart_base = FFUART_BASE;
+	uart_shift = 2;
+	uart_is_pxa = 1;
+
 	if (machine_is_littleton() || machine_is_intelmote2()
 	    || machine_is_csb726() || machine_is_stargate2()
 	    || machine_is_cm_x300() || machine_is_balloon3())
-		UART = STUART;
+		uart_base = STUART_BASE;
+
+	if (machine_is_arcom_zeus()) {
+		uart_base = 0x10000000;	/* nCS4 */
+		uart_shift = 1;
+		uart_is_pxa = 0;
+	}
 }
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -8,4 +8,4 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#define VMALLOC_END       (0xe8000000)
+#define VMALLOC_END       (0xe8000000UL)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/zeus.h linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/zeus.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/zeus.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/include/mach/zeus.h	2010-05-16 17:17:36.000000000 -0400
@@ -58,6 +58,8 @@
 #define ZEUS_EXT1_GPIO(x)	(ZEUS_EXT1_GPIO_BASE + (x))
 #define ZEUS_USER_GPIO(x)	(ZEUS_USER_GPIO_BASE + (x))
 
+#define	ZEUS_CAN_SHDN_GPIO	ZEUS_EXT1_GPIO(2)
+
 /*
  * CPLD registers:
  * Only 4 registers, but spreaded over a 32MB address space.
@@ -68,7 +70,6 @@
 #define ZEUS_CPLD_VERSION	(ZEUS_CPLD + 0x0000)
 #define ZEUS_CPLD_ISA_IRQ	(ZEUS_CPLD + 0x1000)
 #define ZEUS_CPLD_CONTROL	(ZEUS_CPLD + 0x2000)
-#define ZEUS_CPLD_EXTWDOG	(ZEUS_CPLD + 0x3000)
 
 /* CPLD register bits */
 #define ZEUS_CPLD_CONTROL_CF_RST        0x01
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -115,6 +115,11 @@ config MACH_CM_X300
 	select CPU_PXA310
 	select HAVE_PWM
 
+config MACH_CAPC7117
+	bool "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM"
+	select CPU_PXA320
+	select PXA3xx
+
 config ARCH_GUMSTIX
 	bool "Gumstix XScale 255 boards"
 	select PXA25x
@@ -267,7 +272,6 @@ config MACH_H5000
 config MACH_HIMALAYA
 	bool "HTC Himalaya Support"
 	select CPU_PXA26x
-	select FB_W100
 
 config MACH_MAGICIAN
 	bool "Enable HTC Magician Support"
@@ -417,6 +421,24 @@ config MACH_TREO680
 	  Say Y here if you intend to run this kernel on Palm Treo 680
 	  smartphone.
 
+config MACH_RAUMFELD_RC
+	bool "Raumfeld Controller"
+	select PXA3xx
+	select CPU_PXA300
+	select HAVE_PWM
+
+config MACH_RAUMFELD_CONNECTOR
+	bool "Raumfeld Connector"
+	select PXA3xx
+	select CPU_PXA300
+	select PXA_SSP
+
+config MACH_RAUMFELD_SPEAKER
+	bool "Raumfeld Speaker"
+	select PXA3xx
+	select CPU_PXA300
+	select PXA_SSP
+
 config PXA_SHARPSL
 	bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models"
 	select SHARP_SCOOP
@@ -431,10 +453,18 @@ config PXA_SHARPSL
 config SHARPSL_PM
 	bool
 	select APM_EMULATION
+	select SHARPSL_PM_MAX1111
+
+config SHARPSL_PM_MAX1111
+	bool
+	depends on !CORGI_SSP_DEPRECATED
+	select HWMON
+	select SENSORS_MAX1111
 
 config CORGI_SSP_DEPRECATED
 	bool
 	select PXA_SSP
+	select PXA_SSP_LEGACY
 	help
 	  This option will include corgi_ssp.c and corgi_lcd.c
 	  that corgi_ts.c and other legacy drivers (corgi_bl.c
@@ -446,6 +476,7 @@ config MACH_POODLE
 	select PXA25x
 	select SHARP_LOCOMO
 	select PXA_SSP
+	select PXA_HAVE_BOARD_IRQS
 
 config MACH_CORGI
 	bool "Enable Sharp SL-C700 (Corgi) Support"
@@ -492,6 +523,11 @@ config MACH_TOSA
 	select PXA25x
 	select PXA_HAVE_BOARD_IRQS
 
+config MACH_ICONTROL
+	bool "TMT iControl/SafeTCam based on the MXM-8x10 CoM"
+	select CPU_PXA320
+	select PXA3xx
+
 config ARCH_PXA_ESERIES
 	bool "PXA based Toshiba e-series PDAs"
 	select PXA25x
@@ -517,7 +553,6 @@ config MACH_E740
 	bool "Toshiba e740"
 	default y
 	depends on ARCH_PXA_ESERIES
-	select FB_W100
 	help
 	  Say Y here if you intend to run this kernel on a Toshiba
 	  e740 family PDA.
@@ -526,7 +561,6 @@ config MACH_E750
 	bool "Toshiba e750"
 	default y
 	depends on ARCH_PXA_ESERIES
-	select FB_W100
 	help
 	  Say Y here if you intend to run this kernel on a Toshiba
 	  e750 family PDA.
@@ -543,7 +577,6 @@ config MACH_E800
 	bool "Toshiba e800"
 	default y
 	depends on ARCH_PXA_ESERIES
-	select FB_W100
 	help
 	  Say Y here if you intend to run this kernel on a Toshiba
 	  e800 family PDA.
@@ -629,6 +662,11 @@ config PXA_SSP
 	help
 	  Enable support for PXA2xx SSP ports
 
+config PXA_SSP_LEGACY
+	bool
+	help
+	  Support of legacy SSP API
+
 config TOSA_BT
 	tristate "Control the state of built-in bluetooth chip on Sharp SL-6000"
 	depends on MACH_TOSA
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/lpd270.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/lpd270.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/lpd270.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/lpd270.c	2010-05-16 17:17:36.000000000 -0400
@@ -83,6 +83,10 @@ static unsigned long lpd270_pin_config[]
 	GPIO89_USBH1_PEN,
 
 	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
 	GPIO45_AC97_SYSCLK,
 
 	GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
@@ -121,7 +125,7 @@ static void lpd270_irq_handler(unsigned
 
 	pending = __raw_readw(LPD270_INT_STATUS) & lpd270_irq_enabled;
 	do {
-		GEDR(0) = GPIO_bit(0);  /* clear useless edge notification */
+		desc->chip->ack(irq);	/* clear useless edge notification */
 		if (likely(pending)) {
 			irq = LPD270_IRQ(0) + __ffs(pending);
 			generic_handle_irq(irq);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/lubbock.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/lubbock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/lubbock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/lubbock.c	2010-05-16 17:17:36.000000000 -0400
@@ -66,26 +66,14 @@ static unsigned long lubbock_pin_config[
 	GPIO25_SSP1_TXD,
 	GPIO26_SSP1_RXD,
 
+	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+
 	/* LCD - 16bpp DSTN */
-	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,
+	GPIOxx_LCD_DSTN_16BPP,
 
 	/* BTUART */
 	GPIO42_BTUART_RXD,
@@ -158,7 +146,7 @@ static void lubbock_irq_handler(unsigned
 {
 	unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
 	do {
-		GEDR(0) = GPIO_bit(0);	/* clear our parent irq */
+		desc->chip->ack(irq);	/* clear our parent irq */
 		if (likely(pending)) {
 			irq = LUBBOCK_IRQ(0) + __ffs(pending);
 			generic_handle_irq(irq);
@@ -240,11 +228,18 @@ static struct resource sa1111_resources[
 	},
 };
 
+static struct sa1111_platform_data sa1111_info = {
+	.irq_base	= IRQ_BOARD_END,
+};
+
 static struct platform_device sa1111_device = {
 	.name		= "sa1111",
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(sa1111_resources),
 	.resource	= sa1111_resources,
+	.dev		= {
+		.platform_data	= &sa1111_info,
+	},
 };
 
 /* ADS7846 is connected through SSP ... and if your board has J5 populated,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/magician.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/magician.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/magician.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/magician.c	2010-05-16 17:17:36.000000000 -0400
@@ -88,26 +88,7 @@ static unsigned long magician_pin_config
 	GPIO112_MMC_CMD,
 
 	/* 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,
+	GPIOxx_LCD_TFT_16BPP,
 
 	/* QCI */
 	GPIO12_CIF_DD_7,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/mainstone.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/mainstone.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/mainstone.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/mainstone.c	2010-05-16 17:17:36.000000000 -0400
@@ -60,26 +60,7 @@ static unsigned long mainstone_pin_confi
 	GPIO15_nCS_1,
 
 	/* LCD - 16bpp Active TFT */
-	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,
+	GPIOxx_LCD_TFT_16BPP,
 	GPIO16_PWM0_OUT,	/* Backlight */
 
 	/* MMC */
@@ -107,6 +88,10 @@ static unsigned long mainstone_pin_confi
 	GPIO57_nIOIS16,
 
 	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
 	GPIO45_AC97_SYSCLK,
 
 	/* Keypad */
@@ -162,7 +147,7 @@ static void mainstone_irq_handler(unsign
 {
 	unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled;
 	do {
-		GEDR(0) = GPIO_bit(0);  /* clear useless edge notification */
+		desc->chip->ack(irq);	/* clear useless edge notification */
 		if (likely(pending)) {
 			irq = MAINSTONE_IRQ(0) + __ffs(pending);
 			generic_handle_irq(irq);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -48,6 +48,7 @@ obj-$(CONFIG_MACH_ARMCORE)	+= cm-x2xx-pc
 endif
 obj-$(CONFIG_MACH_EM_X270)	+= em-x270.o
 obj-$(CONFIG_MACH_CM_X300)      += cm-x300.o
+obj-$(CONFIG_MACH_CAPC7117)     += capc7117.o mxm8x10.o
 obj-$(CONFIG_ARCH_GUMSTIX)	+= gumstix.o
 obj-$(CONFIG_GUMSTIX_AM200EPD)	+= am200epd.o
 obj-$(CONFIG_GUMSTIX_AM300EPD)	+= am300epd.o
@@ -82,6 +83,7 @@ obj-$(CONFIG_PXA_SHARP_Cxx00)	+= spitz.o
 obj-$(CONFIG_CORGI_SSP_DEPRECATED)	+= corgi_ssp.o corgi_lcd.o
 obj-$(CONFIG_MACH_POODLE)	+= poodle.o
 obj-$(CONFIG_MACH_TOSA)		+= tosa.o
+obj-$(CONFIG_MACH_ICONTROL)     += icontrol.o mxm8x10.o
 obj-$(CONFIG_ARCH_PXA_ESERIES)	+= eseries.o
 obj-$(CONFIG_MACH_E330)		+= e330.o
 obj-$(CONFIG_MACH_E350)		+= e350.o
@@ -89,6 +91,9 @@ 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_RAUMFELD_RC)		+= raumfeld.o
+obj-$(CONFIG_MACH_RAUMFELD_CONNECTOR)	+= raumfeld.o
+obj-$(CONFIG_MACH_RAUMFELD_SPEAKER)	+= raumfeld.o
 
 # Support for blinky lights
 led-y := leds.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/mioa701.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/mioa701.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/mioa701.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/mioa701.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/mtd/physmap.h>
 #include <linux/usb/gpio_vbus.h>
 #include <linux/regulator/max1586.h>
+#include <linux/slab.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -86,25 +87,7 @@ static unsigned long mioa701_pin_config[
 	MIO_CFG_OUT(GPIO22_USB_ENABLE, AF0, DRIVE_LOW),
 
 	/* 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,
+	GPIOxx_LCD_TFT_16BPP,
 
 	/* QCI */
 	GPIO12_CIF_DD_7,
@@ -155,6 +138,10 @@ static unsigned long mioa701_pin_config[
 	GPIO41_FFUART_RTS,
 
 	/* Sound */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
 	GPIO89_AC97_SYSCLK,
 	MIO_CFG_IN(GPIO12_HPJACK_INSERT, AF0),
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/mxm8x10.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/mxm8x10.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/mxm8x10.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/mxm8x10.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,474 @@
+/*
+ * linux/arch/arm/mach-pxa/mxm8x10.c
+ *
+ * Support for the Embedian MXM-8x10 Computer on Module
+ *
+ * Copyright (C) 2006 Marvell International Ltd.
+ * Copyright (C) 2009 Embedian Inc.
+ * Copyright (C) 2009 TMT Services & Supplies (Pty) Ltd.
+ *
+ * 2007-09-04: eric miao <eric.y.miao@gmail.com>
+ *             rewrite to align with latest kernel
+ *
+ * 2010-01-09: Edwin Peer <epeer@tmtservices.co.za>
+ * 	       Hennie van der Merwe <hvdmerwe@tmtservices.co.za>
+ *             rework for upstream merge
+ *
+ * This program is free software; you can 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_8250.h>
+#include <linux/dm9000.h>
+#include <linux/gpio.h>
+
+#include <plat/i2c.h>
+#include <plat/pxa3xx_nand.h>
+
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <mach/ohci.h>
+#include <mach/pxa320.h>
+
+#include <mach/mxm8x10.h>
+
+#include "devices.h"
+#include "generic.h"
+
+/* GPIO pin definition
+
+External device stuff   - Leave unconfigured for now...
+---------------------
+GPIO0   -   DREQ    (External DMA Request)
+GPIO3   -   nGCS2   (External Chip Select) Where is nGCS0; nGCS1; nGCS4; nGCS5 ?
+GPIO4   -   nGCS3
+GPIO15  -   EXT_GPIO1
+GPIO16  -   EXT_GPIO2
+GPIO17  -   EXT_GPIO3
+GPIO24  -   EXT_GPIO4
+GPIO25  -   EXT_GPIO5
+GPIO26  -   EXT_GPIO6
+GPIO27  -   EXT_GPIO7
+GPIO28  -   EXT_GPIO8
+GPIO29  -   EXT_GPIO9
+GPIO30  -   EXT_GPIO10
+GPIO31  -   EXT_GPIO11
+GPIO57  -   EXT_GPIO12
+GPIO74  -   EXT_IRQ1
+GPIO75  -   EXT_IRQ2
+GPIO76  -   EXT_IRQ3
+GPIO77  -   EXT_IRQ4
+GPIO78  -   EXT_IRQ5
+GPIO79  -   EXT_IRQ6
+GPIO80  -   EXT_IRQ7
+GPIO81  -   EXT_IRQ8
+GPIO87  -   VCCIO_PWREN (External Device PWREN)
+
+Dallas 1-Wire   - Leave unconfigured for now...
+-------------
+GPIO0_2 -   DS - 1Wire
+
+Ethernet
+--------
+GPIO1   -   DM9000 PWR
+GPIO9   -   DM9K_nIRQ
+GPIO36  -   DM9K_RESET
+
+Keypad  - Leave unconfigured by for now...
+------
+GPIO1_2 -   KP_DKIN0
+GPIO5_2 -   KP_MKOUT7
+GPIO82  -   KP_DKIN1
+GPIO85  -   KP_DKIN2
+GPIO86  -   KP_DKIN3
+GPIO113 -   KP_MKIN0
+GPIO114 -   KP_MKIN1
+GPIO115 -   KP_MKIN2
+GPIO116 -   KP_MKIN3
+GPIO117 -   KP_MKIN4
+GPIO118 -   KP_MKIN5
+GPIO119 -   KP_MKIN6
+GPIO120 -   KP_MKIN7
+GPIO121 -   KP_MKOUT0
+GPIO122 -   KP_MKOUT1
+GPIO122 -   KP_MKOUT2
+GPIO123 -   KP_MKOUT3
+GPIO124 -   KP_MKOUT4
+GPIO125 -   KP_MKOUT5
+GPIO127 -   KP_MKOUT6
+
+Data Bus    - Leave unconfigured for now...
+--------
+GPIO2   -   nWait (Data Bus)
+
+USB Device
+----------
+GPIO4_2 -   USBD_PULLUP
+GPIO10  -   UTM_CLK (USB Device UTM Clk)
+GPIO49  -   USB 2.0 Device UTM_DATA0
+GPIO50  -   USB 2.0 Device UTM_DATA1
+GPIO51  -   USB 2.0 Device UTM_DATA2
+GPIO52  -   USB 2.0 Device UTM_DATA3
+GPIO53  -   USB 2.0 Device UTM_DATA4
+GPIO54  -   USB 2.0 Device UTM_DATA5
+GPIO55  -   USB 2.0 Device UTM_DATA6
+GPIO56  -   USB 2.0 Device UTM_DATA7
+GPIO58  -   UTM_RXVALID (USB 2.0 Device)
+GPIO59  -   UTM_RXACTIVE (USB 2.0 Device)
+GPIO60  -   UTM_RXERROR
+GPIO61  -   UTM_OPMODE0
+GPIO62  -   UTM_OPMODE1
+GPIO71  -   USBD_INT    (USB Device?)
+GPIO73  -   UTM_TXREADY (USB 2.0 Device)
+GPIO83  -   UTM_TXVALID (USB 2.0 Device)
+GPIO98  -   UTM_RESET   (USB 2.0 device)
+GPIO99  -   UTM_XCVR_SELECT
+GPIO100 -   UTM_TERM_SELECT
+GPIO101 -   UTM_SUSPENDM_X
+GPIO102 -   UTM_LINESTATE0
+GPIO103 -   UTM_LINESTATE1
+
+Card-Bus Interface  - Leave unconfigured for now...
+------------------
+GPIO5   -   nPIOR (I/O space output enable)
+GPIO6   -   nPIOW (I/O space write enable)
+GPIO7   -   nIOS16 (Input from I/O space telling size of data bus)
+GPIO8   -   nPWAIT (Input for inserting wait states)
+
+LCD
+---
+GPIO6_2     -   LDD0
+GPIO7_2     -   LDD1
+GPIO8_2     -   LDD2
+GPIO9_2     -   LDD3
+GPIO11_2    -   LDD5
+GPIO12_2    -   LDD6
+GPIO13_2    -   LDD7
+GPIO14_2    -   VSYNC
+GPIO15_2    -   HSYNC
+GPIO16_2    -   VCLK
+GPIO17_2    -   HCLK
+GPIO18_2    -   VDEN
+GPIO63      -   LDD8    (CPU LCD)
+GPIO64      -   LDD9    (CPU LCD)
+GPIO65      -   LDD10   (CPU LCD)
+GPIO66      -   LDD11   (CPU LCD)
+GPIO67      -   LDD12   (CPU LCD)
+GPIO68      -   LDD13   (CPU LCD)
+GPIO69      -   LDD14   (CPU LCD)
+GPIO70      -   LDD15   (CPU LCD)
+GPIO88      -   VCCLCD_PWREN (LCD Panel PWREN)
+GPIO97      -   BACKLIGHT_EN
+GPIO104     -   LCD_PWREN
+
+PWM   - Leave unconfigured for now...
+---
+GPIO11  -   PWM0
+GPIO12  -   PWM1
+GPIO13  -   PWM2
+GPIO14  -   PWM3
+
+SD-CARD
+-------
+GPIO18  -   SDDATA0
+GPIO19  -   SDDATA1
+GPIO20  -   SDDATA2
+GPIO21  -   SDDATA3
+GPIO22  -   SDCLK
+GPIO23  -   SDCMD
+GPIO72  -   SD_WP
+GPIO84  -   SD_nIRQ_CD  (SD-Card)
+
+I2C
+---
+GPIO32  -   I2CSCL
+GPIO33  -   I2CSDA
+
+AC97
+----
+GPIO35  -   AC97_SDATA_IN
+GPIO37  -   AC97_SDATA_OUT
+GPIO38  -   AC97_SYNC
+GPIO39  -   AC97_BITCLK
+GPIO40  -   AC97_nRESET
+
+UART1
+-----
+GPIO41  -   UART_RXD1
+GPIO42  -   UART_TXD1
+GPIO43  -   UART_CTS1
+GPIO44  -   UART_DCD1
+GPIO45  -   UART_DSR1
+GPIO46  -   UART_nRI1
+GPIO47  -   UART_DTR1
+GPIO48  -   UART_RTS1
+
+UART2
+-----
+GPIO109 -   RTS2
+GPIO110 -   RXD2
+GPIO111 -   TXD2
+GPIO112 -   nCTS2
+
+UART3
+-----
+GPIO105 -   nCTS3
+GPIO106 -   nRTS3
+GPIO107 -   TXD3
+GPIO108 -   RXD3
+
+SSP3    - Leave unconfigured for now...
+----
+GPIO89  -   SSP3_CLK
+GPIO90  -   SSP3_SFRM
+GPIO91  -   SSP3_TXD
+GPIO92  -   SSP3_RXD
+
+SSP4
+GPIO93  -   SSP4_CLK
+GPIO94  -   SSP4_SFRM
+GPIO95  -   SSP4_TXD
+GPIO96  -   SSP4_RXD
+*/
+
+static mfp_cfg_t mfp_cfg[] __initdata = {
+	/* USB */
+	GPIO10_UTM_CLK,
+	GPIO49_U2D_PHYDATA_0,
+	GPIO50_U2D_PHYDATA_1,
+	GPIO51_U2D_PHYDATA_2,
+	GPIO52_U2D_PHYDATA_3,
+	GPIO53_U2D_PHYDATA_4,
+	GPIO54_U2D_PHYDATA_5,
+	GPIO55_U2D_PHYDATA_6,
+	GPIO56_U2D_PHYDATA_7,
+	GPIO58_UTM_RXVALID,
+	GPIO59_UTM_RXACTIVE,
+	GPIO60_U2D_RXERROR,
+	GPIO61_U2D_OPMODE0,
+	GPIO62_U2D_OPMODE1,
+	GPIO71_GPIO, /* USBD_INT */
+	GPIO73_UTM_TXREADY,
+	GPIO83_U2D_TXVALID,
+	GPIO98_U2D_RESET,
+	GPIO99_U2D_XCVR_SEL,
+	GPIO100_U2D_TERM_SEL,
+	GPIO101_U2D_SUSPEND,
+	GPIO102_UTM_LINESTATE_0,
+	GPIO103_UTM_LINESTATE_1,
+	GPIO4_2_GPIO | MFP_PULL_HIGH, /* UTM_PULLUP */
+
+	/* DM9000 */
+	GPIO1_GPIO,
+	GPIO9_GPIO,
+	GPIO36_GPIO,
+
+	/* AC97 */
+	GPIO35_AC97_SDATA_IN_0,
+	GPIO37_AC97_SDATA_OUT,
+	GPIO38_AC97_SYNC,
+	GPIO39_AC97_BITCLK,
+	GPIO40_AC97_nACRESET,
+
+	/* UARTS */
+	GPIO41_UART1_RXD,
+	GPIO42_UART1_TXD,
+	GPIO43_UART1_CTS,
+	GPIO44_UART1_DCD,
+	GPIO45_UART1_DSR,
+	GPIO46_UART1_RI,
+	GPIO47_UART1_DTR,
+	GPIO48_UART1_RTS,
+
+	GPIO109_UART2_RTS,
+	GPIO110_UART2_RXD,
+	GPIO111_UART2_TXD,
+	GPIO112_UART2_CTS,
+
+	GPIO105_UART3_CTS,
+	GPIO106_UART3_RTS,
+	GPIO107_UART3_TXD,
+	GPIO108_UART3_RXD,
+
+	GPIO78_GPIO,
+	GPIO79_GPIO,
+	GPIO80_GPIO,
+	GPIO81_GPIO,
+
+	/* I2C */
+	GPIO32_I2C_SCL,
+	GPIO33_I2C_SDA,
+
+	/* MMC */
+	GPIO18_MMC1_DAT0,
+	GPIO19_MMC1_DAT1,
+	GPIO20_MMC1_DAT2,
+	GPIO21_MMC1_DAT3,
+	GPIO22_MMC1_CLK,
+	GPIO23_MMC1_CMD,
+	GPIO72_GPIO | MFP_PULL_HIGH, /* Card Detect */
+	GPIO84_GPIO | MFP_PULL_LOW, /* Write Protect */
+
+	/* IRQ */
+	GPIO74_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ1 */
+	GPIO75_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ2 */
+	GPIO76_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ3 */
+	GPIO77_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ4 */
+	GPIO78_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ5 */
+	GPIO79_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ6 */
+	GPIO80_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ7 */
+	GPIO81_GPIO | MFP_LPM_EDGE_RISE  /* EXT_IRQ8 */
+};
+
+/* MMC/MCI Support */
+#if defined(CONFIG_MMC)
+static struct pxamci_platform_data mxm_8x10_mci_platform_data = {
+	.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+	.detect_delay = 1,
+	.gpio_card_detect = MXM_8X10_SD_nCD,
+	.gpio_card_ro = MXM_8X10_SD_WP,
+	.gpio_power = -1
+};
+
+void __init mxm_8x10_mmc_init(void)
+{
+	pxa_set_mci_info(&mxm_8x10_mci_platform_data);
+}
+#endif
+
+/* USB Open Host Controler Interface */
+static struct pxaohci_platform_data mxm_8x10_ohci_platform_data = {
+	.port_mode = PMM_NPS_MODE,
+	.flags = ENABLE_PORT_ALL
+};
+
+void __init mxm_8x10_usb_host_init(void)
+{
+	pxa_set_ohci_info(&mxm_8x10_ohci_platform_data);
+}
+
+/* AC97 Sound Support */
+static struct platform_device mxm_8x10_ac97_device = {
+	.name = "pxa2xx-ac97"
+};
+
+void __init mxm_8x10_ac97_init(void)
+{
+	platform_device_register(&mxm_8x10_ac97_device);
+}
+
+/* NAND flash Support */
+#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+#define NAND_BLOCK_SIZE SZ_128K
+#define NB(x)           (NAND_BLOCK_SIZE * (x))
+static struct mtd_partition mxm_8x10_nand_partitions[] = {
+	[0] = {
+	       .name = "boot",
+	       .size = NB(0x002),
+	       .offset = NB(0x000),
+	       .mask_flags = MTD_WRITEABLE
+	},
+	[1] = {
+	       .name = "kernel",
+	       .size = NB(0x010),
+	       .offset = NB(0x002),
+	       .mask_flags = MTD_WRITEABLE
+	},
+	[2] = {
+	       .name = "root",
+	       .size = NB(0x36c),
+	       .offset = NB(0x012)
+	},
+	[3] = {
+	       .name = "bbt",
+	       .size = NB(0x082),
+	       .offset = NB(0x37e),
+	       .mask_flags = MTD_WRITEABLE
+	}
+};
+
+static struct pxa3xx_nand_platform_data mxm_8x10_nand_info = {
+	.enable_arbiter = 1,
+	.keep_config = 1,
+	.parts = mxm_8x10_nand_partitions,
+	.nr_parts = ARRAY_SIZE(mxm_8x10_nand_partitions)
+};
+
+static void __init mxm_8x10_nand_init(void)
+{
+	pxa3xx_set_nand_info(&mxm_8x10_nand_info);
+}
+#else
+static inline void mxm_8x10_nand_init(void) {}
+#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */
+
+/* Ethernet support: Davicom DM9000 */
+static struct resource dm9k_resources[] = {
+	[0] = {
+	       .start = MXM_8X10_ETH_PHYS + 0x300,
+	       .end = MXM_8X10_ETH_PHYS + 0x300,
+	       .flags = IORESOURCE_MEM
+	},
+	[1] = {
+	       .start = MXM_8X10_ETH_PHYS + 0x308,
+	       .end = MXM_8X10_ETH_PHYS + 0x308,
+	       .flags = IORESOURCE_MEM
+	},
+	[2] = {
+	       .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO9)),
+	       .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO9)),
+	       .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE
+	}
+};
+
+static struct dm9000_plat_data dm9k_plat_data = {
+	.flags = DM9000_PLATF_16BITONLY
+};
+
+static struct platform_device dm9k_device = {
+	.name = "dm9000",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(dm9k_resources),
+	.resource = dm9k_resources,
+	.dev = {
+		.platform_data = &dm9k_plat_data
+	}
+};
+
+static void __init mxm_8x10_ethernet_init(void)
+{
+	platform_device_register(&dm9k_device);
+}
+
+/* PXA UARTs */
+static void __init mxm_8x10_uarts_init(void)
+{
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+}
+
+/* I2C and Real Time Clock */
+static struct i2c_board_info __initdata mxm_8x10_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("ds1337", 0x68)
+	}
+};
+
+static void __init mxm_8x10_i2c_init(void)
+{
+	i2c_register_board_info(0, mxm_8x10_i2c_devices,
+				ARRAY_SIZE(mxm_8x10_i2c_devices));
+	pxa_set_i2c_info(NULL);
+}
+
+void __init mxm_8x10_barebones_init(void)
+{
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_cfg));
+
+	mxm_8x10_uarts_init();
+	mxm_8x10_nand_init();
+	mxm_8x10_i2c_init();
+	mxm_8x10_ethernet_init();
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmld.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/palmld.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmld.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/palmld.c	2010-05-16 17:17:36.000000000 -0400
@@ -83,26 +83,7 @@ static unsigned long palmld_pin_config[]
 	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,
+	GPIOxx_LCD_TFT_16BPP,
 
 	/* PWM */
 	GPIO16_PWM0_OUT,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmt5.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/palmt5.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmt5.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/palmt5.c	2010-05-16 17:17:36.000000000 -0400
@@ -87,26 +87,7 @@ static unsigned long palmt5_pin_config[]
 	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,
+	GPIOxx_LCD_TFT_16BPP,
 
 	/* PWM */
 	GPIO16_PWM0_OUT,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmtc.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/palmtc.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmtc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/palmtc.c	2010-05-16 17:17:36.000000000 -0400
@@ -84,26 +84,7 @@ static unsigned long palmtc_pin_config[]
 	GPIO36_GPIO,	/* pullup */
 
 	/* 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,
+	GPIOxx_LCD_TFT_16BPP,
 
 	/* MATRIX KEYPAD */
 	GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH,	/* in 0 */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmte2.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/palmte2.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmte2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/palmte2.c	2010-05-16 17:17:36.000000000 -0400
@@ -73,26 +73,7 @@ static unsigned long palmte2_pin_config[
 	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,
+	GPIOxx_LCD_TFT_16BPP,
 
 	/* GPIO KEYS */
 	GPIO5_GPIO,	/* notes */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmtreo.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/palmtreo.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmtreo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/palmtreo.c	2010-05-16 17:17:36.000000000 -0400
@@ -99,25 +99,7 @@ static unsigned long treo_pin_config[] _
 	GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH,	/* Hotsync button */
 
 	/* LCD */
-	GPIO58_LCD_LDD_0,
-	GPIO59_LCD_LDD_1,
-	GPIO60_LCD_LDD_2,
-	GPIO61_LCD_LDD_3,
-	GPIO62_LCD_LDD_4,
-	GPIO63_LCD_LDD_5,
-	GPIO64_LCD_LDD_6,
-	GPIO65_LCD_LDD_7,
-	GPIO66_LCD_LDD_8,
-	GPIO67_LCD_LDD_9,
-	GPIO68_LCD_LDD_10,
-	GPIO69_LCD_LDD_11,
-	GPIO70_LCD_LDD_12,
-	GPIO71_LCD_LDD_13,
-	GPIO72_LCD_LDD_14,
-	GPIO73_LCD_LDD_15,
-	GPIO74_LCD_FCLK,
-	GPIO75_LCD_LCLK,
-	GPIO76_LCD_PCLK,
+	GPIOxx_LCD_TFT_16BPP,
 
 	/* Quick Capture Interface */
 	GPIO84_CIF_FV,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmtx.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/palmtx.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmtx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/palmtx.c	2010-05-16 17:17:36.000000000 -0400
@@ -110,26 +110,7 @@ static unsigned long palmtx_pin_config[]
 	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,
+	GPIOxx_LCD_TFT_16BPP,
 
 	/* FFUART */
 	GPIO34_FFUART_RXD,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmz72.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/palmz72.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmz72.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/palmz72.c	2010-05-16 17:17:36.000000000 -0400
@@ -95,26 +95,8 @@ static unsigned long palmz72_pin_config[
 	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,
+	GPIOxx_LCD_TFT_16BPP,
+
 	GPIO20_GPIO,	/* bl power */
 	GPIO21_GPIO,	/* LCD border switch */
 	GPIO22_GPIO,	/* LCD border color */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pcm990-baseboard.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/pcm990-baseboard.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pcm990-baseboard.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/pcm990-baseboard.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,6 +58,12 @@ static unsigned long pcm990_pin_config[]
 	/* I2C */
 	GPIO117_I2C_SCL,
 	GPIO118_I2C_SDA,
+
+	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
 };
 
 /*
@@ -259,8 +265,7 @@ static void pcm990_irq_handler(unsigned
 	unsigned long pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
 
 	do {
-		GEDR(PCM990_CTRL_INT_IRQ_GPIO) =
-					GPIO_bit(PCM990_CTRL_INT_IRQ_GPIO);
+		desc->chip->ack(irq);	/* clear our parent IRQ */
 		if (likely(pending)) {
 			irq = PCM027_IRQ(0) + __ffs(pending);
 			generic_handle_irq(irq);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pm.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/pm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/suspend.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 
 #include <mach/pm.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/poodle.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/poodle.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/poodle.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/poodle.c	2010-05-16 17:17:36.000000000 -0400
@@ -91,26 +91,7 @@ static unsigned long poodle_pin_config[]
 	GPIO35_FFUART_CTS,
 
 	/* 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,
+	GPIOxx_LCD_TFT_16BPP,
 
 	/* PC Card */
 	GPIO48_nPOE,
@@ -193,11 +174,18 @@ static struct resource locomo_resources[
 	},
 };
 
+static struct locomo_platform_data locomo_info = {
+	.irq_base	= IRQ_BOARD_START,
+};
+
 struct platform_device poodle_locomo_device = {
 	.name		= "locomo",
 	.id		= 0,
 	.num_resources	= ARRAY_SIZE(locomo_resources),
 	.resource	= locomo_resources,
+	.dev		= {
+		.platform_data	= &locomo_info,
+	},
 };
 
 EXPORT_SYMBOL(poodle_locomo_device);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa25x.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/pxa25x.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa25x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/pxa25x.c	2010-05-16 17:17:36.000000000 -0400
@@ -349,7 +349,7 @@ static int __init pxa25x_init(void)
 
 		reset_status = RCSR;
 
-		clks_register(pxa25x_clkregs, ARRAY_SIZE(pxa25x_clkregs));
+		clkdev_add_table(pxa25x_clkregs, ARRAY_SIZE(pxa25x_clkregs));
 
 		if ((ret = pxa_init_dma(IRQ_DMA, 16)))
 			return ret;
@@ -370,7 +370,7 @@ static int __init pxa25x_init(void)
 
 	/* Only add HWUART for PXA255/26x; PXA210/250 do not have it. */
 	if (cpu_is_pxa255())
-		clks_register(&pxa25x_hwuart_clkreg, 1);
+		clkdev_add(&pxa25x_hwuart_clkreg);
 
 	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa27x.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/pxa27x.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa27x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/pxa27x.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,25 @@ void pxa27x_clear_otgph(void)
 }
 EXPORT_SYMBOL(pxa27x_clear_otgph);
 
+static unsigned long ac97_reset_config[] = {
+	GPIO95_AC97_nRESET,
+	GPIO95_GPIO,
+	GPIO113_AC97_nRESET,
+	GPIO113_GPIO,
+};
+
+void pxa27x_assert_ac97reset(int reset_gpio, int on)
+{
+	if (reset_gpio == 113)
+		pxa2xx_mfp_config(on ? &ac97_reset_config[0] :
+				       &ac97_reset_config[1], 1);
+
+	if (reset_gpio == 95)
+		pxa2xx_mfp_config(on ? &ac97_reset_config[2] :
+				       &ac97_reset_config[3], 1);
+}
+EXPORT_SYMBOL_GPL(pxa27x_assert_ac97reset);
+
 /* Crystal clock: 13MHz */
 #define BASE_CLK	13000000
 
@@ -392,7 +411,7 @@ static int __init pxa27x_init(void)
 
 		reset_status = RCSR;
 
-		clks_register(pxa27x_clkregs, ARRAY_SIZE(pxa27x_clkregs));
+		clkdev_add_table(pxa27x_clkregs, ARRAY_SIZE(pxa27x_clkregs));
 
 		if ((ret = pxa_init_dma(IRQ_DMA, 32)))
 			return ret;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa300.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/pxa300.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa300.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/pxa300.c	2010-05-16 17:17:36.000000000 -0400
@@ -102,12 +102,12 @@ static int __init pxa300_init(void)
 	if (cpu_is_pxa300() || cpu_is_pxa310()) {
 		mfp_init_base(io_p2v(MFPR_BASE));
 		mfp_init_addr(pxa300_mfp_addr_map);
-		clks_register(ARRAY_AND_SIZE(common_clkregs));
+		clkdev_add_table(ARRAY_AND_SIZE(common_clkregs));
 	}
 
 	if (cpu_is_pxa310()) {
 		mfp_init_addr(pxa310_mfp_addr_map);
-		clks_register(ARRAY_AND_SIZE(pxa310_clkregs));
+		clkdev_add_table(ARRAY_AND_SIZE(pxa310_clkregs));
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa320.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/pxa320.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa320.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/pxa320.c	2010-05-16 17:17:36.000000000 -0400
@@ -90,7 +90,7 @@ static int __init pxa320_init(void)
 	if (cpu_is_pxa320()) {
 		mfp_init_base(io_p2v(MFPR_BASE));
 		mfp_init_addr(pxa320_mfp_addr_map);
-		clks_register(ARRAY_AND_SIZE(pxa320_clkregs));
+		clkdev_add_table(ARRAY_AND_SIZE(pxa320_clkregs));
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa3xx.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/pxa3xx.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa3xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/pxa3xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -634,7 +634,7 @@ static int __init pxa3xx_init(void)
 		 */
 		ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
 
-		clks_register(pxa3xx_clkregs, ARRAY_SIZE(pxa3xx_clkregs));
+		clkdev_add_table(pxa3xx_clkregs, ARRAY_SIZE(pxa3xx_clkregs));
 
 		if ((ret = pxa_init_dma(IRQ_DMA, 32)))
 			return ret;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/raumfeld.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/raumfeld.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/raumfeld.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/raumfeld.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1105 @@
+/*
+ * arch/arm/mach-pxa/raumfeld.c
+ *
+ * Support for the following Raumfeld devices:
+ *
+ * 	* Controller
+ *  	* Connector
+ *  	* Speaker S/M
+ *
+ * See http://www.raumfeld.com for details.
+ *
+ * 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
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/input.h>
+#include <linux/rotary_encoder.h>
+#include <linux/gpio_keys.h>
+#include <linux/input/eeti_ts.h>
+#include <linux/leds.h>
+#include <linux/w1-gpio.h>
+#include <linux/sched.h>
+#include <linux/pwm_backlight.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/lis3lv02d.h>
+#include <linux/pda_power.h>
+#include <linux/power_supply.h>
+#include <linux/regulator/max8660.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/consumer.h>
+#include <linux/delay.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/hardware.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa3xx.h>
+#include <mach/mfp-pxa300.h>
+#include <mach/ohci.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <plat/i2c.h>
+#include <plat/pxa3xx_nand.h>
+
+#include "generic.h"
+#include "devices.h"
+#include "clock.h"
+
+/* common GPIO	definitions */
+
+/* inputs */
+#define GPIO_ON_OFF		(14)
+#define GPIO_VOLENC_A		(19)
+#define GPIO_VOLENC_B		(20)
+#define GPIO_CHARGE_DONE	(23)
+#define GPIO_CHARGE_IND		(27)
+#define GPIO_TOUCH_IRQ		(32)
+#define GPIO_ETH_IRQ		(40)
+#define GPIO_SPI_MISO		(98)
+#define GPIO_ACCEL_IRQ		(104)
+#define GPIO_RESCUE_BOOT	(115)
+#define GPIO_DOCK_DETECT	(116)
+#define GPIO_KEY1		(117)
+#define GPIO_KEY2		(118)
+#define GPIO_KEY3		(119)
+#define GPIO_CHARGE_USB_OK	(112)
+#define GPIO_CHARGE_DC_OK	(101)
+#define GPIO_CHARGE_USB_SUSP	(102)
+
+/* outputs */
+#define GPIO_SHUTDOWN_SUPPLY	(16)
+#define GPIO_SHUTDOWN_BATT	(18)
+#define GPIO_CHRG_PEN2		(31)
+#define GPIO_TFT_VA_EN		(33)
+#define GPIO_SPDIF_CS		(34)
+#define GPIO_LED2		(35)
+#define GPIO_LED1		(36)
+#define GPIO_SPDIF_RESET	(38)
+#define GPIO_SPI_CLK		(95)
+#define GPIO_MCLK_DAC_CS	(96)
+#define GPIO_SPI_MOSI		(97)
+#define GPIO_W1_PULLUP_ENABLE	(105)
+#define GPIO_DISPLAY_ENABLE	(106)
+#define GPIO_MCLK_RESET		(111)
+#define GPIO_W2W_RESET		(113)
+#define GPIO_W2W_PDN		(114)
+#define GPIO_CODEC_RESET	(120)
+#define GPIO_AUDIO_VA_ENABLE	(124)
+#define GPIO_ACCEL_CS		(125)
+#define GPIO_ONE_WIRE		(126)
+
+/*
+ * GPIO configurations
+ */
+static mfp_cfg_t raumfeld_controller_pin_config[] __initdata = {
+	/* UART1 */
+	GPIO77_UART1_RXD,
+	GPIO78_UART1_TXD,
+	GPIO79_UART1_CTS,
+	GPIO81_UART1_DSR,
+	GPIO83_UART1_DTR,
+	GPIO84_UART1_RTS,
+
+	/* UART3 */
+	GPIO110_UART3_RXD,
+
+	/* USB Host */
+	GPIO0_2_USBH_PEN,
+	GPIO1_2_USBH_PWR,
+
+	/* I2C */
+	GPIO21_I2C_SCL | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+	GPIO22_I2C_SDA | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+
+	/* SPI */
+	GPIO34_GPIO,	/* SPDIF_CS */
+	GPIO96_GPIO,	/* MCLK_CS */
+	GPIO125_GPIO,	/* ACCEL_CS */
+
+	/* MMC */
+	GPIO3_MMC1_DAT0,
+	GPIO4_MMC1_DAT1,
+	GPIO5_MMC1_DAT2,
+	GPIO6_MMC1_DAT3,
+	GPIO7_MMC1_CLK,
+	GPIO8_MMC1_CMD,
+
+	/* One-wire */
+	GPIO126_GPIO | MFP_LPM_FLOAT,
+	GPIO105_GPIO | MFP_PULL_LOW | MFP_LPM_PULL_LOW,
+
+	/* CHRG_USB_OK */
+	GPIO101_GPIO | MFP_PULL_HIGH,
+	/* CHRG_USB_OK */
+	GPIO112_GPIO | MFP_PULL_HIGH,
+	/* CHRG_USB_SUSP */
+	GPIO102_GPIO,
+	/* DISPLAY_ENABLE */
+	GPIO106_GPIO,
+	/* DOCK_DETECT */
+	GPIO116_GPIO | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+
+	/* LCD */
+	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,
+	GPIO72_LCD_FCLK,
+	GPIO73_LCD_LCLK,
+	GPIO74_LCD_PCLK,
+	GPIO75_LCD_BIAS,
+};
+
+static mfp_cfg_t raumfeld_connector_pin_config[] __initdata = {
+	/* UART1 */
+	GPIO77_UART1_RXD,
+	GPIO78_UART1_TXD,
+	GPIO79_UART1_CTS,
+	GPIO81_UART1_DSR,
+	GPIO83_UART1_DTR,
+	GPIO84_UART1_RTS,
+
+	/* UART3 */
+	GPIO110_UART3_RXD,
+
+	/* USB Host */
+	GPIO0_2_USBH_PEN,
+	GPIO1_2_USBH_PWR,
+
+	/* I2C */
+	GPIO21_I2C_SCL | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+	GPIO22_I2C_SDA | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+
+	/* SPI */
+	GPIO34_GPIO,	/* SPDIF_CS */
+	GPIO96_GPIO,	/* MCLK_CS */
+	GPIO125_GPIO,	/* ACCEL_CS */
+
+	/* MMC */
+	GPIO3_MMC1_DAT0,
+	GPIO4_MMC1_DAT1,
+	GPIO5_MMC1_DAT2,
+	GPIO6_MMC1_DAT3,
+	GPIO7_MMC1_CLK,
+	GPIO8_MMC1_CMD,
+
+	/* Ethernet */
+	GPIO1_nCS2,			/* CS */
+	GPIO40_GPIO | MFP_PULL_HIGH,	/* IRQ */
+
+	/* SSP for I2S */
+	GPIO85_SSP1_SCLK,
+	GPIO89_SSP1_EXTCLK,
+	GPIO86_SSP1_FRM,
+	GPIO87_SSP1_TXD,
+	GPIO88_SSP1_RXD,
+	GPIO90_SSP1_SYSCLK,
+
+	/* SSP2 for S/PDIF */
+	GPIO25_SSP2_SCLK,
+	GPIO26_SSP2_FRM,
+	GPIO27_SSP2_TXD,
+	GPIO29_SSP2_EXTCLK,
+
+	/* LEDs */
+	GPIO35_GPIO | MFP_LPM_PULL_LOW,
+	GPIO36_GPIO | MFP_LPM_DRIVE_HIGH,
+};
+
+static mfp_cfg_t raumfeld_speaker_pin_config[] __initdata = {
+	/* UART1 */
+	GPIO77_UART1_RXD,
+	GPIO78_UART1_TXD,
+	GPIO79_UART1_CTS,
+	GPIO81_UART1_DSR,
+	GPIO83_UART1_DTR,
+	GPIO84_UART1_RTS,
+
+	/* UART3 */
+	GPIO110_UART3_RXD,
+
+	/* USB Host */
+	GPIO0_2_USBH_PEN,
+	GPIO1_2_USBH_PWR,
+
+	/* I2C */
+	GPIO21_I2C_SCL | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+	GPIO22_I2C_SDA | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+
+	/* SPI */
+	GPIO34_GPIO,	/* SPDIF_CS */
+	GPIO96_GPIO,	/* MCLK_CS */
+	GPIO125_GPIO,	/* ACCEL_CS */
+
+	/* MMC */
+	GPIO3_MMC1_DAT0,
+	GPIO4_MMC1_DAT1,
+	GPIO5_MMC1_DAT2,
+	GPIO6_MMC1_DAT3,
+	GPIO7_MMC1_CLK,
+	GPIO8_MMC1_CMD,
+
+	/* Ethernet */
+	GPIO1_nCS2,			/* CS */
+	GPIO40_GPIO | MFP_PULL_HIGH,	/* IRQ */
+
+	/* SSP for I2S */
+	GPIO85_SSP1_SCLK,
+	GPIO89_SSP1_EXTCLK,
+	GPIO86_SSP1_FRM,
+	GPIO87_SSP1_TXD,
+	GPIO88_SSP1_RXD,
+	GPIO90_SSP1_SYSCLK,
+
+	/* LEDs */
+	GPIO35_GPIO | MFP_LPM_PULL_LOW,
+	GPIO36_GPIO | MFP_LPM_DRIVE_HIGH,
+};
+
+/*
+ * SMSC LAN9220 Ethernet
+ */
+
+static struct resource smc91x_resources[] = {
+	{
+		.start	= PXA3xx_CS2_PHYS,
+		.end	= PXA3xx_CS2_PHYS + 0xfffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= gpio_to_irq(GPIO_ETH_IRQ),
+		.end	= gpio_to_irq(GPIO_ETH_IRQ),
+		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
+	}
+};
+
+static struct smsc911x_platform_config raumfeld_smsc911x_config = {
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.flags		= SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smsc911x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+	.dev		= {
+		.platform_data = &raumfeld_smsc911x_config,
+	}
+};
+
+/**
+ * NAND
+ */
+
+static struct mtd_partition raumfeld_nand_partitions[] = {
+	{
+		.name		= "Bootloader",
+		.offset		= 0,
+		.size		= 0xa0000,
+		.mask_flags	= MTD_WRITEABLE, /* force read-only */
+	},
+	{
+		.name		= "BootloaderEnvironment",
+		.offset		= 0xa0000,
+		.size		= 0x20000,
+	},
+	{
+		.name		= "BootloaderSplashScreen",
+		.offset		= 0xc0000,
+		.size		= 0x60000,
+	},
+	{
+		.name		= "UBI",
+		.offset		= 0x120000,
+		.size		= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct pxa3xx_nand_platform_data raumfeld_nand_info = {
+	.enable_arbiter	= 1,
+	.keep_config	= 1,
+	.parts		= raumfeld_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(raumfeld_nand_partitions),
+};
+
+/**
+ * USB (OHCI) support
+ */
+
+static struct pxaohci_platform_data raumfeld_ohci_info = {
+	.port_mode      = PMM_GLOBAL_MODE,
+	.flags		= ENABLE_PORT1,
+};
+
+/**
+ * Rotary encoder input device
+ */
+
+static struct rotary_encoder_platform_data raumfeld_rotary_encoder_info = {
+	.steps		= 24,
+	.axis		= REL_X,
+	.relative_axis	= 1,
+	.gpio_a		= GPIO_VOLENC_A,
+	.gpio_b		= GPIO_VOLENC_B,
+	.inverted_a	= 1,
+	.inverted_b	= 0,
+};
+
+static struct platform_device rotary_encoder_device = {
+	.name		= "rotary-encoder",
+	.id		= 0,
+	.dev		= {
+		.platform_data = &raumfeld_rotary_encoder_info,
+	}
+};
+
+/**
+ * GPIO buttons
+ */
+
+static struct gpio_keys_button gpio_keys_button[] = {
+	{
+		.code			= KEY_F1,
+		.type			= EV_KEY,
+		.gpio			= GPIO_KEY1,
+		.active_low		= 1,
+		.wakeup			= 0,
+		.debounce_interval	= 5, /* ms */
+		.desc			= "Button 1",
+	},
+	{
+		.code			= KEY_F2,
+		.type			= EV_KEY,
+		.gpio			= GPIO_KEY2,
+		.active_low		= 1,
+		.wakeup			= 0,
+		.debounce_interval	= 5, /* ms */
+		.desc			= "Button 2",
+	},
+	{
+		.code			= KEY_F3,
+		.type			= EV_KEY,
+		.gpio			= GPIO_KEY3,
+		.active_low		= 1,
+		.wakeup			= 0,
+		.debounce_interval	= 5, /* ms */
+		.desc			= "Button 3",
+	},
+	{
+		.code			= KEY_F4,
+		.type			= EV_KEY,
+		.gpio			= GPIO_RESCUE_BOOT,
+		.active_low		= 0,
+		.wakeup			= 0,
+		.debounce_interval	= 5, /* ms */
+		.desc			= "rescue boot button",
+	},
+	{
+		.code			= KEY_F5,
+		.type			= EV_KEY,
+		.gpio			= GPIO_DOCK_DETECT,
+		.active_low		= 1,
+		.wakeup			= 0,
+		.debounce_interval	= 5, /* ms */
+		.desc			= "dock detect",
+	},
+	{
+		.code			= KEY_F6,
+		.type			= EV_KEY,
+		.gpio			= GPIO_ON_OFF,
+		.active_low		= 0,
+		.wakeup			= 0,
+		.debounce_interval	= 5, /* ms */
+		.desc			= "on_off button",
+	},
+};
+
+static struct gpio_keys_platform_data gpio_keys_platform_data = {
+	.buttons	= gpio_keys_button,
+	.nbuttons	= ARRAY_SIZE(gpio_keys_button),
+	.rep		= 0,
+};
+
+static struct platform_device raumfeld_gpio_keys_device = {
+	.name	= "gpio-keys",
+	.id	= -1,
+	.dev 	= {
+		.platform_data	= &gpio_keys_platform_data,
+	}
+};
+
+/**
+ * GPIO LEDs
+ */
+
+static struct gpio_led raumfeld_leds[] = {
+	{
+		.name		= "raumfeld:1",
+		.gpio		= GPIO_LED1,
+		.active_low	= 1,
+		.default_state	= LEDS_GPIO_DEFSTATE_ON,
+	},
+	{
+		.name		= "raumfeld:2",
+		.gpio		= GPIO_LED2,
+		.active_low	= 0,
+		.default_state	= LEDS_GPIO_DEFSTATE_OFF,
+	}
+};
+
+static struct gpio_led_platform_data raumfeld_led_platform_data = {
+	.leds		= raumfeld_leds,
+	.num_leds	= ARRAY_SIZE(raumfeld_leds),
+};
+
+static struct platform_device raumfeld_led_device = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &raumfeld_led_platform_data,
+	},
+};
+
+/**
+ * One-wire (W1 bus) support
+ */
+
+static void w1_enable_external_pullup(int enable)
+{
+	gpio_set_value(GPIO_W1_PULLUP_ENABLE, enable);
+	msleep(100);
+}
+
+static struct w1_gpio_platform_data w1_gpio_platform_data = {
+	.pin			= GPIO_ONE_WIRE,
+	.is_open_drain		= 0,
+	.enable_external_pullup	= w1_enable_external_pullup,
+};
+
+struct platform_device raumfeld_w1_gpio_device = {
+	.name	= "w1-gpio",
+	.dev	= {
+		.platform_data = &w1_gpio_platform_data
+	}
+};
+
+static void __init raumfeld_w1_init(void)
+{
+	int ret = gpio_request(GPIO_W1_PULLUP_ENABLE,
+				"W1 external pullup enable");
+
+	if (ret < 0)
+		pr_warning("Unable to request GPIO_W1_PULLUP_ENABLE\n");
+	else
+		gpio_direction_output(GPIO_W1_PULLUP_ENABLE, 0);
+
+	platform_device_register(&raumfeld_w1_gpio_device);
+}
+
+/**
+ * Framebuffer device
+ */
+
+/* PWM controlled backlight */
+static struct platform_pwm_backlight_data raumfeld_pwm_backlight_data = {
+	.pwm_id		= 0,
+	.max_brightness	= 100,
+	.dft_brightness	= 100,
+	/* 10000 ns = 10 ms ^= 100 kHz */
+	.pwm_period_ns	= 10000,
+};
+
+static struct platform_device raumfeld_pwm_backlight_device = {
+	.name	= "pwm-backlight",
+	.dev	= {
+		.parent		= &pxa27x_device_pwm0.dev,
+		.platform_data	= &raumfeld_pwm_backlight_data,
+	}
+};
+
+/* LT3593 controlled backlight */
+static struct gpio_led raumfeld_lt3593_led = {
+	.name		= "backlight",
+	.gpio		= mfp_to_gpio(MFP_PIN_GPIO17),
+	.default_state	= LEDS_GPIO_DEFSTATE_ON,
+};
+
+static struct gpio_led_platform_data raumfeld_lt3593_platform_data = {
+	.leds		= &raumfeld_lt3593_led,
+	.num_leds	= 1,
+};
+
+static struct platform_device raumfeld_lt3593_device = {
+	.name	= "leds-lt3593",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &raumfeld_lt3593_platform_data,
+	},
+};
+
+static struct pxafb_mode_info sharp_lq043t3dx02_mode = {
+	.pixclock	= 111000,
+	.xres		= 480,
+	.yres		= 272,
+	.bpp		= 16,
+	.hsync_len	= 4,
+	.left_margin	= 2,
+	.right_margin	= 1,
+	.vsync_len	= 1,
+	.upper_margin	= 3,
+	.lower_margin	= 1,
+	.sync		= 0,
+};
+
+static struct pxafb_mach_info raumfeld_sharp_lcd_info = {
+	.modes		= &sharp_lq043t3dx02_mode,
+	.num_modes	= 1,
+	.video_mem_size = 0x400000,
+	.lcd_conn	= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+static void __init raumfeld_lcd_init(void)
+{
+	int ret;
+
+	set_pxa_fb_info(&raumfeld_sharp_lcd_info);
+
+	/* Earlier devices had the backlight regulator controlled
+	 * via PWM, later versions use another controller for that */
+	if ((system_rev & 0xff) < 2) {
+		mfp_cfg_t raumfeld_pwm_pin_config = GPIO17_PWM0_OUT;
+		pxa3xx_mfp_config(&raumfeld_pwm_pin_config, 1);
+		platform_device_register(&raumfeld_pwm_backlight_device);
+	} else
+		platform_device_register(&raumfeld_lt3593_device);
+
+	ret = gpio_request(GPIO_TFT_VA_EN, "display VA enable");
+	if (ret < 0)
+		pr_warning("Unable to request GPIO_TFT_VA_EN\n");
+	else
+		gpio_direction_output(GPIO_TFT_VA_EN, 1);
+
+	ret = gpio_request(GPIO_DISPLAY_ENABLE, "display enable");
+	if (ret < 0)
+		pr_warning("Unable to request GPIO_DISPLAY_ENABLE\n");
+	else
+		gpio_direction_output(GPIO_DISPLAY_ENABLE, 1);
+}
+
+/**
+ * SPI devices
+ */
+
+struct spi_gpio_platform_data raumfeld_spi_platform_data = {
+	.sck		= GPIO_SPI_CLK,
+	.mosi		= GPIO_SPI_MOSI,
+	.miso		= GPIO_SPI_MISO,
+	.num_chipselect	= 3,
+};
+
+static struct platform_device raumfeld_spi_device = {
+	.name	= "spi_gpio",
+	.id	= 0,
+	.dev 	= {
+		.platform_data	= &raumfeld_spi_platform_data,
+	}
+};
+
+static struct lis3lv02d_platform_data lis3_pdata = {
+	.click_flags 	= LIS3_CLICK_SINGLE_X |
+			  LIS3_CLICK_SINGLE_Y |
+			  LIS3_CLICK_SINGLE_Z,
+	.irq_cfg	= LIS3_IRQ1_CLICK | LIS3_IRQ2_CLICK,
+	.wakeup_flags	= LIS3_WAKEUP_X_LO | LIS3_WAKEUP_X_HI |
+			  LIS3_WAKEUP_Y_LO | LIS3_WAKEUP_Y_HI |
+			  LIS3_WAKEUP_Z_LO | LIS3_WAKEUP_Z_HI,
+	.wakeup_thresh	= 10,
+	.click_thresh_x = 10,
+	.click_thresh_y = 10,
+	.click_thresh_z = 10,
+};
+
+#define SPI_AK4104	\
+{			\
+	.modalias	= "ak4104",	\
+	.max_speed_hz	= 10000,	\
+	.bus_num	= 0,		\
+	.chip_select	= 0,		\
+	.controller_data = (void *) GPIO_SPDIF_CS,	\
+}
+
+#define SPI_LIS3	\
+{			\
+	.modalias	= "lis3lv02d_spi",	\
+	.max_speed_hz	= 1000000,		\
+	.bus_num	= 0,			\
+	.chip_select	= 1,			\
+	.controller_data = (void *) GPIO_ACCEL_CS,	\
+	.platform_data	= &lis3_pdata,		\
+	.irq		= gpio_to_irq(GPIO_ACCEL_IRQ),	\
+}
+
+#define SPI_DAC7512	\
+{	\
+	.modalias	= "dac7512",		\
+	.max_speed_hz	= 1000000,		\
+	.bus_num	= 0,			\
+	.chip_select	= 2,			\
+	.controller_data = (void *) GPIO_MCLK_DAC_CS,	\
+}
+
+static struct spi_board_info connector_spi_devices[] __initdata = {
+	SPI_AK4104,
+	SPI_DAC7512,
+};
+
+static struct spi_board_info speaker_spi_devices[] __initdata = {
+	SPI_DAC7512,
+};
+
+static struct spi_board_info controller_spi_devices[] __initdata = {
+	SPI_LIS3,
+};
+
+/**
+ * MMC for Marvell Libertas 8688 via SDIO
+ */
+
+static int raumfeld_mci_init(struct device *dev, irq_handler_t isr, void *data)
+{
+	gpio_set_value(GPIO_W2W_RESET, 1);
+	gpio_set_value(GPIO_W2W_PDN, 1);
+
+	return 0;
+}
+
+static void raumfeld_mci_exit(struct device *dev, void *data)
+{
+	gpio_set_value(GPIO_W2W_RESET, 0);
+	gpio_set_value(GPIO_W2W_PDN, 0);
+}
+
+static struct pxamci_platform_data raumfeld_mci_platform_data = {
+	.init			= raumfeld_mci_init,
+	.exit			= raumfeld_mci_exit,
+	.detect_delay		= 20,
+	.gpio_card_detect	= -1,
+	.gpio_card_ro		= -1,
+	.gpio_power		= -1,
+};
+
+/*
+ * External power / charge logic
+ */
+
+static int power_supply_init(struct device *dev)
+{
+	return 0;
+}
+
+static void power_supply_exit(struct device *dev)
+{
+}
+
+static int raumfeld_is_ac_online(void)
+{
+	return !gpio_get_value(GPIO_CHARGE_DC_OK);
+}
+
+static int raumfeld_is_usb_online(void)
+{
+	return 0;
+}
+
+static char *raumfeld_power_supplicants[] = { "ds2760-battery.0" };
+
+static struct pda_power_pdata power_supply_info = {
+	.init			= power_supply_init,
+	.is_ac_online		= raumfeld_is_ac_online,
+	.is_usb_online		= raumfeld_is_usb_online,
+	.exit			= power_supply_exit,
+	.supplied_to		= raumfeld_power_supplicants,
+	.num_supplicants	= ARRAY_SIZE(raumfeld_power_supplicants)
+};
+
+static struct resource power_supply_resources[] = {
+	{
+		.name  = "ac",
+		.flags = IORESOURCE_IRQ |
+			 IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
+		.start = GPIO_CHARGE_DC_OK,
+		.end   = GPIO_CHARGE_DC_OK,
+	},
+};
+
+static irqreturn_t charge_done_irq(int irq, void *dev_id)
+{
+	struct power_supply *psy;
+
+	psy = power_supply_get_by_name("ds2760-battery.0");
+
+	if (psy)
+		power_supply_set_battery_charged(psy);
+
+	return IRQ_HANDLED;
+}
+
+static struct platform_device raumfeld_power_supply = {
+	.name = "pda-power",
+	.id   = -1,
+	.dev  = {
+		.platform_data = &power_supply_info,
+	},
+	.resource      = power_supply_resources,
+	.num_resources = ARRAY_SIZE(power_supply_resources),
+};
+
+static void __init raumfeld_power_init(void)
+{
+	int ret;
+
+	/* Set PEN2 high to enable maximum charge current */
+	ret = gpio_request(GPIO_CHRG_PEN2, "CHRG_PEN2");
+	if (ret < 0)
+		pr_warning("Unable to request GPIO_CHRG_PEN2\n");
+	else
+		gpio_direction_output(GPIO_CHRG_PEN2, 1);
+
+	ret = gpio_request(GPIO_CHARGE_DC_OK, "CABLE_DC_OK");
+	if (ret < 0)
+		pr_warning("Unable to request GPIO_CHARGE_DC_OK\n");
+
+	ret = gpio_request(GPIO_CHARGE_USB_SUSP, "CHARGE_USB_SUSP");
+	if (ret < 0)
+		pr_warning("Unable to request GPIO_CHARGE_USB_SUSP\n");
+	else
+		gpio_direction_output(GPIO_CHARGE_USB_SUSP, 0);
+
+	power_supply_resources[0].start = gpio_to_irq(GPIO_CHARGE_DC_OK);
+	power_supply_resources[0].end = gpio_to_irq(GPIO_CHARGE_DC_OK);
+
+	ret = request_irq(gpio_to_irq(GPIO_CHARGE_DONE),
+			&charge_done_irq, IORESOURCE_IRQ_LOWEDGE,
+			"charge_done", NULL);
+
+	if (ret < 0)
+		printk(KERN_ERR "%s: unable to register irq %d\n", __func__,
+			GPIO_CHARGE_DONE);
+	else
+		platform_device_register(&raumfeld_power_supply);
+}
+
+/* Fixed regulator for AUDIO_VA, 0-0048 maps to the cs4270 codec device */
+
+static struct regulator_consumer_supply audio_va_consumer_supply =
+	REGULATOR_SUPPLY("va", "0-0048");
+
+struct regulator_init_data audio_va_initdata = {
+	.consumer_supplies = &audio_va_consumer_supply,
+	.num_consumer_supplies = 1,
+	.constraints = {
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+};
+
+static struct fixed_voltage_config audio_va_config = {
+	.supply_name		= "audio_va",
+	.microvolts		= 5000000,
+	.gpio			= GPIO_AUDIO_VA_ENABLE,
+	.enable_high		= 1,
+	.enabled_at_boot	= 0,
+	.init_data		= &audio_va_initdata,
+};
+
+static struct platform_device audio_va_device = {
+	.name	= "reg-fixed-voltage",
+	.id	= 0,
+	.dev	= {
+		.platform_data = &audio_va_config,
+	},
+};
+
+/* Dummy supplies for Codec's VD/VLC */
+
+static struct regulator_consumer_supply audio_dummy_supplies[] = {
+	REGULATOR_SUPPLY("vd", "0-0048"),
+	REGULATOR_SUPPLY("vlc", "0-0048"),
+};
+
+struct regulator_init_data audio_dummy_initdata = {
+	.consumer_supplies = audio_dummy_supplies,
+	.num_consumer_supplies = ARRAY_SIZE(audio_dummy_supplies),
+	.constraints = {
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+};
+
+static struct fixed_voltage_config audio_dummy_config = {
+	.supply_name		= "audio_vd",
+	.microvolts		= 3300000,
+	.gpio			= -1,
+	.init_data		= &audio_dummy_initdata,
+};
+
+static struct platform_device audio_supply_dummy_device = {
+	.name	= "reg-fixed-voltage",
+	.id	= 1,
+	.dev	= {
+		.platform_data = &audio_dummy_config,
+	},
+};
+
+static struct platform_device *audio_regulator_devices[] = {
+	&audio_va_device,
+	&audio_supply_dummy_device,
+};
+
+/**
+ * Regulator support via MAX8660
+ */
+
+static struct regulator_consumer_supply vcc_mmc_supply =
+	REGULATOR_SUPPLY("vmmc", "pxa2xx-mci.0");
+
+static struct regulator_init_data vcc_mmc_init_data = {
+	.constraints = {
+		.min_uV			= 3300000,
+		.max_uV			= 3300000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL,
+		.valid_ops_mask		= REGULATOR_CHANGE_STATUS |
+					  REGULATOR_CHANGE_VOLTAGE |
+					  REGULATOR_CHANGE_MODE,
+	},
+	.consumer_supplies = &vcc_mmc_supply,
+	.num_consumer_supplies = 1,
+};
+
+struct max8660_subdev_data max8660_v6_subdev_data = {
+	.id		= MAX8660_V6,
+	.name		= "vmmc",
+	.platform_data	= &vcc_mmc_init_data,
+};
+
+static struct max8660_platform_data max8660_pdata = {
+	.subdevs = &max8660_v6_subdev_data,
+	.num_subdevs = 1,
+};
+
+/**
+ * I2C devices
+ */
+
+static struct i2c_board_info raumfeld_pwri2c_board_info = {
+	.type		= "max8660",
+	.addr		= 0x34,
+	.platform_data	= &max8660_pdata,
+};
+
+static struct i2c_board_info raumfeld_connector_i2c_board_info __initdata = {
+	.type	= "cs4270",
+	.addr	= 0x48,
+};
+
+static struct eeti_ts_platform_data eeti_ts_pdata = {
+	.irq_active_high = 1,
+};
+
+static struct i2c_board_info raumfeld_controller_i2c_board_info __initdata = {
+	.type	= "eeti_ts",
+	.addr	= 0x0a,
+	.irq	= gpio_to_irq(GPIO_TOUCH_IRQ),
+	.platform_data = &eeti_ts_pdata,
+};
+
+static struct platform_device *raumfeld_common_devices[] = {
+	&raumfeld_gpio_keys_device,
+	&raumfeld_led_device,
+	&raumfeld_spi_device,
+};
+
+static void __init raumfeld_audio_init(void)
+{
+	int ret;
+
+	ret = gpio_request(GPIO_CODEC_RESET, "cs4270 reset");
+	if (ret < 0)
+		pr_warning("unable to request GPIO_CODEC_RESET\n");
+	else
+		gpio_direction_output(GPIO_CODEC_RESET, 1);
+
+	ret = gpio_request(GPIO_SPDIF_RESET, "ak4104 s/pdif reset");
+	if (ret < 0)
+		pr_warning("unable to request GPIO_SPDIF_RESET\n");
+	else
+		gpio_direction_output(GPIO_SPDIF_RESET, 1);
+
+	ret = gpio_request(GPIO_MCLK_RESET, "MCLK reset");
+	if (ret < 0)
+		pr_warning("unable to request GPIO_MCLK_RESET\n");
+	else
+		gpio_direction_output(GPIO_MCLK_RESET, 1);
+
+	platform_add_devices(ARRAY_AND_SIZE(audio_regulator_devices));
+}
+
+static void __init raumfeld_common_init(void)
+{
+	int ret;
+
+	/* The on/off button polarity has changed after revision 1 */
+	if ((system_rev & 0xff) > 1) {
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(gpio_keys_button); i++)
+			if (!strcmp(gpio_keys_button[i].desc, "on_off button"))
+				gpio_keys_button[i].active_low = 1;
+	}
+
+	enable_irq_wake(IRQ_WAKEUP0);
+
+	pxa3xx_set_nand_info(&raumfeld_nand_info);
+	pxa3xx_set_i2c_power_info(NULL);
+	pxa_set_ohci_info(&raumfeld_ohci_info);
+	pxa_set_mci_info(&raumfeld_mci_platform_data);
+	pxa_set_i2c_info(NULL);
+	pxa_set_ffuart_info(NULL);
+
+	ret = gpio_request(GPIO_W2W_RESET, "Wi2Wi reset");
+	if (ret < 0)
+		pr_warning("Unable to request GPIO_W2W_RESET\n");
+	else
+		gpio_direction_output(GPIO_W2W_RESET, 0);
+
+	ret = gpio_request(GPIO_W2W_PDN, "Wi2Wi powerup");
+	if (ret < 0)
+		pr_warning("Unable to request GPIO_W2W_PDN\n");
+	else
+		gpio_direction_output(GPIO_W2W_PDN, 0);
+
+	/* this can be used to switch off the device */
+	ret = gpio_request(GPIO_SHUTDOWN_SUPPLY, "supply shutdown");
+	if (ret < 0)
+		pr_warning("Unable to request GPIO_SHUTDOWN_SUPPLY\n");
+	else
+		gpio_direction_output(GPIO_SHUTDOWN_SUPPLY, 0);
+
+	platform_add_devices(ARRAY_AND_SIZE(raumfeld_common_devices));
+	i2c_register_board_info(1, &raumfeld_pwri2c_board_info, 1);
+}
+
+static void __init raumfeld_controller_init(void)
+{
+	int ret;
+
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_controller_pin_config));
+	platform_device_register(&rotary_encoder_device);
+	spi_register_board_info(ARRAY_AND_SIZE(controller_spi_devices));
+	i2c_register_board_info(0, &raumfeld_controller_i2c_board_info, 1);
+
+	ret = gpio_request(GPIO_SHUTDOWN_BATT, "battery shutdown");
+	if (ret < 0)
+		pr_warning("Unable to request GPIO_SHUTDOWN_BATT\n");
+	else
+		gpio_direction_output(GPIO_SHUTDOWN_BATT, 0);
+
+	raumfeld_common_init();
+	raumfeld_power_init();
+	raumfeld_lcd_init();
+	raumfeld_w1_init();
+}
+
+static void __init raumfeld_connector_init(void)
+{
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_connector_pin_config));
+	spi_register_board_info(ARRAY_AND_SIZE(connector_spi_devices));
+	i2c_register_board_info(0, &raumfeld_connector_i2c_board_info, 1);
+
+	platform_device_register(&smc91x_device);
+
+	raumfeld_audio_init();
+	raumfeld_common_init();
+}
+
+static void __init raumfeld_speaker_init(void)
+{
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_speaker_pin_config));
+	spi_register_board_info(ARRAY_AND_SIZE(speaker_spi_devices));
+	i2c_register_board_info(0, &raumfeld_connector_i2c_board_info, 1);
+
+	platform_device_register(&smc91x_device);
+	platform_device_register(&rotary_encoder_device);
+
+	raumfeld_audio_init();
+	raumfeld_common_init();
+}
+
+/* physical memory regions */
+#define	RAUMFELD_SDRAM_BASE	0xa0000000	/* SDRAM region */
+
+#ifdef CONFIG_MACH_RAUMFELD_RC
+MACHINE_START(RAUMFELD_RC, "Raumfeld Controller")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= RAUMFELD_SDRAM_BASE + 0x100,
+	.init_machine	= raumfeld_controller_init,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa3xx_init_irq,
+	.timer		= &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_RAUMFELD_CONNECTOR
+MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= RAUMFELD_SDRAM_BASE + 0x100,
+	.init_machine	= raumfeld_connector_init,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa3xx_init_irq,
+	.timer		= &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_RAUMFELD_SPEAKER
+MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= RAUMFELD_SDRAM_BASE + 0x100,
+	.init_machine	= raumfeld_speaker_init,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa3xx_init_irq,
+	.timer		= &pxa_timer,
+MACHINE_END
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/sharpsl_pm.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/sharpsl_pm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/sharpsl_pm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/sharpsl_pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -900,7 +900,7 @@ static struct platform_suspend_ops sharp
 };
 #endif
 
-static int __init sharpsl_pm_probe(struct platform_device *pdev)
+static int __devinit sharpsl_pm_probe(struct platform_device *pdev)
 {
 	int ret;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/spitz.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/spitz.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/spitz.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/spitz.c	2010-05-16 17:17:36.000000000 -0400
@@ -56,25 +56,7 @@ static unsigned long spitz_pin_config[]
 	GPIO80_nCS_4,	/* SCOOP #1 */
 
 	/* LCD - 16bpp Active TFT */
-	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,
+	GPIOxx_LCD_TFT_16BPP,
 
 	/* PC Card */
 	GPIO48_nPOE,
@@ -381,7 +363,7 @@ static struct gpio_keys_button spitz_gpi
 		.type	= EV_PWR,
 		.code	= KEY_SUSPEND,
 		.gpio	= SPITZ_GPIO_ON_KEY,
-		.desc	= "On/Off",
+		.desc	= "On Off",
 		.wakeup	= 1,
 	},
 	/* Two buttons detecting the lid state */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/ssp.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/ssp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/ssp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/ssp.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,8 @@
 #include <mach/ssp.h>
 #include <mach/regs-ssp.h>
 
+#ifdef CONFIG_PXA_SSP_LEGACY
+
 #define TIMEOUT 100000
 
 static irqreturn_t ssp_interrupt(int irq, void *dev_id)
@@ -303,6 +305,7 @@ void ssp_exit(struct ssp_dev *dev)
 	clk_disable(ssp->clk);
 	ssp_free(ssp);
 }
+#endif /* CONFIG_PXA_SSP_LEGACY */
 
 static DEFINE_MUTEX(ssp_lock);
 static LIST_HEAD(ssp_list);
@@ -488,6 +491,7 @@ static void __exit pxa_ssp_exit(void)
 arch_initcall(pxa_ssp_init);
 module_exit(pxa_ssp_exit);
 
+#ifdef CONFIG_PXA_SSP_LEGACY
 EXPORT_SYMBOL(ssp_write_word);
 EXPORT_SYMBOL(ssp_read_word);
 EXPORT_SYMBOL(ssp_flush);
@@ -498,6 +502,7 @@ EXPORT_SYMBOL(ssp_restore_state);
 EXPORT_SYMBOL(ssp_init);
 EXPORT_SYMBOL(ssp_exit);
 EXPORT_SYMBOL(ssp_config);
+#endif
 
 MODULE_DESCRIPTION("PXA SSP driver");
 MODULE_AUTHOR("Liam Girdwood");
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/stargate2.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/stargate2.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/stargate2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/stargate2.c	2010-05-16 17:17:36.000000000 -0400
@@ -764,11 +764,6 @@ static void __init stargate2_init(void)
 	pxa_set_btuart_info(NULL);
 	pxa_set_stuart_info(NULL);
 
-	/* spi chip selects */
-	gpio_direction_output(37, 0);
-	gpio_direction_output(24, 0);
-	gpio_direction_output(39, 0);
-
 	platform_add_devices(ARRAY_AND_SIZE(stargate2_devices));
 
 	pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/time.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/time.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -76,14 +76,12 @@ pxa_ost0_interrupt(int irq, void *dev_id
 static int
 pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev)
 {
-	unsigned long flags, next, oscr;
+	unsigned long next, oscr;
 
-	raw_local_irq_save(flags);
 	OIER |= OIER_E0;
 	next = OSCR + delta;
 	OSMR0 = next;
 	oscr = OSCR;
-	raw_local_irq_restore(flags);
 
 	return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
 }
@@ -91,23 +89,17 @@ pxa_osmr0_set_next_event(unsigned long d
 static void
 pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
 {
-	unsigned long irqflags;
-
 	switch (mode) {
 	case CLOCK_EVT_MODE_ONESHOT:
-		raw_local_irq_save(irqflags);
 		OIER &= ~OIER_E0;
 		OSSR = OSSR_M0;
-		raw_local_irq_restore(irqflags);
 		break;
 
 	case CLOCK_EVT_MODE_UNUSED:
 	case CLOCK_EVT_MODE_SHUTDOWN:
 		/* initializing, released, or preparing for suspend */
-		raw_local_irq_save(irqflags);
 		OIER &= ~OIER_E0;
 		OSSR = OSSR_M0;
-		raw_local_irq_restore(irqflags);
 		break;
 
 	case CLOCK_EVT_MODE_RESUME:
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/tosa.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/tosa.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/tosa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/tosa.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/gpio.h>
 #include <linux/pda_power.h>
 #include <linux/spi/spi.h>
+#include <linux/input/matrix_keypad.h>
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -131,24 +132,24 @@ static unsigned long tosa_pin_config[] =
 	GPIO45_BTUART_RTS,
 
 	/* Keybd */
-	GPIO58_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO59_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO60_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO61_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO62_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO63_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO64_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO65_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO66_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO67_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO68_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO69_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO70_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO71_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO72_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO73_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO74_GPIO | MFP_LPM_DRIVE_LOW,
-	GPIO75_GPIO | MFP_LPM_DRIVE_LOW,
+	GPIO58_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 0 */
+	GPIO59_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 1 */
+	GPIO60_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 2 */
+	GPIO61_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 3 */
+	GPIO62_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 4 */
+	GPIO63_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 5 */
+	GPIO64_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 6 */
+	GPIO65_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 7 */
+	GPIO66_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 8 */
+	GPIO67_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 9 */
+	GPIO68_GPIO | MFP_LPM_DRIVE_LOW,	/* Column 10 */
+	GPIO69_GPIO | MFP_LPM_DRIVE_LOW,	/* Row 0 */
+	GPIO70_GPIO | MFP_LPM_DRIVE_LOW,	/* Row 1 */
+	GPIO71_GPIO | MFP_LPM_DRIVE_LOW,	/* Row 2 */
+	GPIO72_GPIO | MFP_LPM_DRIVE_LOW,	/* Row 3 */
+	GPIO73_GPIO | MFP_LPM_DRIVE_LOW,	/* Row 4 */
+	GPIO74_GPIO | MFP_LPM_DRIVE_LOW,	/* Row 5 */
+	GPIO75_GPIO | MFP_LPM_DRIVE_LOW,	/* Row 6 */
 
 	/* SPI */
 	GPIO81_SSP2_CLK_OUT,
@@ -411,9 +412,87 @@ static struct platform_device tosa_power
 /*
  * Tosa Keyboard
  */
+static const uint32_t tosakbd_keymap[] = {
+	KEY(0, 2, KEY_W),
+	KEY(0, 6, KEY_K),
+	KEY(0, 7, KEY_BACKSPACE),
+	KEY(0, 8, KEY_P),
+	KEY(1, 1, KEY_Q),
+	KEY(1, 2, KEY_E),
+	KEY(1, 3, KEY_T),
+	KEY(1, 4, KEY_Y),
+	KEY(1, 6, KEY_O),
+	KEY(1, 7, KEY_I),
+	KEY(1, 8, KEY_COMMA),
+	KEY(2, 1, KEY_A),
+	KEY(2, 2, KEY_D),
+	KEY(2, 3, KEY_G),
+	KEY(2, 4, KEY_U),
+	KEY(2, 6, KEY_L),
+	KEY(2, 7, KEY_ENTER),
+	KEY(2, 8, KEY_DOT),
+	KEY(3, 1, KEY_Z),
+	KEY(3, 2, KEY_C),
+	KEY(3, 3, KEY_V),
+	KEY(3, 4, KEY_J),
+	KEY(3, 5, TOSA_KEY_ADDRESSBOOK),
+	KEY(3, 6, TOSA_KEY_CANCEL),
+	KEY(3, 7, TOSA_KEY_CENTER),
+	KEY(3, 8, TOSA_KEY_OK),
+	KEY(3, 9, KEY_LEFTSHIFT),
+	KEY(4, 1, KEY_S),
+	KEY(4, 2, KEY_R),
+	KEY(4, 3, KEY_B),
+	KEY(4, 4, KEY_N),
+	KEY(4, 5, TOSA_KEY_CALENDAR),
+	KEY(4, 6, TOSA_KEY_HOMEPAGE),
+	KEY(4, 7, KEY_LEFTCTRL),
+	KEY(4, 8, TOSA_KEY_LIGHT),
+	KEY(4, 10, KEY_RIGHTSHIFT),
+	KEY(5, 1, KEY_TAB),
+	KEY(5, 2, KEY_SLASH),
+	KEY(5, 3, KEY_H),
+	KEY(5, 4, KEY_M),
+	KEY(5, 5, TOSA_KEY_MENU),
+	KEY(5, 7, KEY_UP),
+	KEY(5, 11, TOSA_KEY_FN),
+	KEY(6, 1, KEY_X),
+	KEY(6, 2, KEY_F),
+	KEY(6, 3, KEY_SPACE),
+	KEY(6, 4, KEY_APOSTROPHE),
+	KEY(6, 5, TOSA_KEY_MAIL),
+	KEY(6, 6, KEY_LEFT),
+	KEY(6, 7, KEY_DOWN),
+	KEY(6, 8, KEY_RIGHT),
+};
+
+static struct matrix_keymap_data tosakbd_keymap_data = {
+	.keymap		= tosakbd_keymap,
+	.keymap_size	= ARRAY_SIZE(tosakbd_keymap),
+};
+
+static const int tosakbd_col_gpios[] =
+			{ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68 };
+static const int tosakbd_row_gpios[] =
+			{ 69, 70, 71, 72, 73, 74, 75 };
+
+static struct matrix_keypad_platform_data tosakbd_pdata = {
+	.keymap_data		= &tosakbd_keymap_data,
+	.row_gpios		= tosakbd_row_gpios,
+	.col_gpios		= tosakbd_col_gpios,
+	.num_row_gpios		= ARRAY_SIZE(tosakbd_row_gpios),
+	.num_col_gpios		= ARRAY_SIZE(tosakbd_col_gpios),
+	.col_scan_delay_us	= 10,
+	.debounce_ms		= 10,
+	.wakeup			= 1,
+};
+
 static struct platform_device tosakbd_device = {
-	.name		= "tosa-keyboard",
+	.name		= "matrix-keypad",
 	.id		= -1,
+	.dev		= {
+		.platform_data = &tosakbd_pdata,
+	},
 };
 
 static struct gpio_keys_button tosa_gpio_keys[] = {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/trizeps4.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/trizeps4.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/trizeps4.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/trizeps4.c	2010-05-16 17:17:36.000000000 -0400
@@ -72,27 +72,14 @@ static unsigned long trizeps4_pin_config
 	GPIO79_nCS_3,		/* Logic CS */
 	GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,	/* Logic irq */
 
+	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+
 	/* LCD - 16bpp Active TFT */
-	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,
+	GPIOxx_LCD_TFT_16BPP,
 
 	/* UART */
 	GPIO9_FFUART_CTS,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/viper.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/viper.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/viper.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/viper.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,12 +27,14 @@
 #include <linux/delay.h>
 #include <linux/fs.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/major.h>
 #include <linux/module.h>
 #include <linux/pm.h>
 #include <linux/sched.h>
 #include <linux/gpio.h>
+#include <linux/jiffies.h>
 #include <linux/i2c-gpio.h>
 #include <linux/serial_8250.h>
 #include <linux/smc91x.h>
@@ -281,7 +283,7 @@ static void viper_irq_handler(unsigned i
 	do {
 		/* we're in a chained irq handler,
 		 * so ack the interrupt by hand */
-		GEDR(VIPER_CPLD_GPIO) = GPIO_bit(VIPER_CPLD_GPIO);
+		desc->chip->ack(irq);
 
 		if (likely(pending)) {
 			irq = viper_bit_to_irq(__ffs(pending));
@@ -453,7 +455,7 @@ static struct i2c_gpio_platform_data i2c
 	.sda_pin = VIPER_RTC_I2C_SDA_GPIO,
 	.scl_pin = VIPER_RTC_I2C_SCL_GPIO,
 	.udelay  = 10,
-	.timeout = 100,
+	.timeout = HZ,
 };
 
 static struct platform_device i2c_bus_device = {
@@ -711,6 +713,12 @@ static mfp_cfg_t viper_pin_config[] __in
 	GPIO80_nCS_4,
 	GPIO33_nCS_5,
 
+	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+
 	/* FP Backlight */
 	GPIO9_GPIO, 				/* VIPER_BCKLIGHT_EN_GPIO */
 	GPIO10_GPIO,				/* VIPER_LCD_EN_GPIO */
@@ -772,7 +780,7 @@ static void __init viper_tpm_init(void)
 		.sda_pin = VIPER_TPM_I2C_SDA_GPIO,
 		.scl_pin = VIPER_TPM_I2C_SCL_GPIO,
 		.udelay  = 10,
-		.timeout = 100,
+		.timeout = HZ,
 	};
 	char *errstr;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/zeus.c linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/zeus.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/zeus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/zeus.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c/pca953x.h>
 #include <linux/apm-emulation.h>
+#include <linux/can/platform/mcp251x.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -387,11 +388,47 @@ static struct pxa2xx_spi_master pxa2xx_s
 	.enable_dma     = 1,
 };
 
-static struct platform_device pxa2xx_spi_ssp3_device = {
-	.name = "pxa2xx-spi",
-	.id = 3,
-	.dev = {
-		.platform_data = &pxa2xx_spi_ssp3_master_info,
+/* CAN bus on SPI */
+static int zeus_mcp2515_setup(struct spi_device *sdev)
+{
+	int err;
+
+	err = gpio_request(ZEUS_CAN_SHDN_GPIO, "CAN shutdown");
+	if (err)
+		return err;
+
+	err = gpio_direction_output(ZEUS_CAN_SHDN_GPIO, 1);
+	if (err) {
+		gpio_free(ZEUS_CAN_SHDN_GPIO);
+		return err;
+	}
+
+	return 0;
+}
+
+static int zeus_mcp2515_transceiver_enable(int enable)
+{
+	gpio_set_value(ZEUS_CAN_SHDN_GPIO, !enable);
+	return 0;
+}
+
+static struct mcp251x_platform_data zeus_mcp2515_pdata = {
+	.oscillator_frequency	= 16*1000*1000,
+	.model			= CAN_MCP251X_MCP2515,
+	.board_specific_setup	= zeus_mcp2515_setup,
+	.transceiver_enable	= zeus_mcp2515_transceiver_enable,
+	.power_enable		= zeus_mcp2515_transceiver_enable,
+};
+
+static struct spi_board_info zeus_spi_board_info[] = {
+	[0] = {
+		.modalias	= "mcp251x",
+		.platform_data	= &zeus_mcp2515_pdata,
+		.irq		= gpio_to_irq(ZEUS_CAN_GPIO),
+		.max_speed_hz	= 1*1000*1000,
+		.bus_num	= 3,
+		.mode		= SPI_MODE_0,
+		.chip_select	= 0,
 	},
 };
 
@@ -457,15 +494,28 @@ static struct platform_device zeus_pcmci
 	},
 };
 
+static struct resource zeus_max6369_resource = {
+	.start		= ZEUS_CPLD_EXTWDOG_PHYS,
+	.end		= ZEUS_CPLD_EXTWDOG_PHYS,
+	.flags		= IORESOURCE_MEM,
+};
+
+struct platform_device zeus_max6369_device = {
+	.name		= "max6369_wdt",
+	.id		= -1,
+	.resource	= &zeus_max6369_resource,
+	.num_resources	= 1,
+};
+
 static struct platform_device *zeus_devices[] __initdata = {
 	&zeus_serial_device,
 	&zeus_mtd_devices[0],
 	&zeus_dm9k0_device,
 	&zeus_dm9k1_device,
 	&zeus_sram_device,
-	&pxa2xx_spi_ssp3_device,
 	&zeus_leds_device,
 	&zeus_pcmcia_device,
+	&zeus_max6369_device,
 };
 
 /* AC'97 */
@@ -509,7 +559,9 @@ static void zeus_ohci_exit(struct device
 
 static struct pxaohci_platform_data zeus_ohci_platform_data = {
 	.port_mode	= PMM_NPS_MODE,
-	.flags		= ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
+	/* Clear Power Control Polarity Low and set Power Sense
+	 * Polarity Low. Supply power to USB ports. */
+	.flags		= ENABLE_PORT_ALL | POWER_SENSE_LOW,
 	.init		= zeus_ohci_init,
 	.exit		= zeus_ohci_exit,
 };
@@ -621,11 +673,15 @@ static struct pxa2xx_udc_mach_info zeus_
 	.udc_command = zeus_udc_command,
 };
 
+#ifdef CONFIG_PM
 static void zeus_power_off(void)
 {
 	local_irq_disable();
 	pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP);
 }
+#else
+#define zeus_power_off   NULL
+#endif
 
 #ifdef CONFIG_APM_EMULATION
 static void zeus_get_power_status(struct apm_power_info *info)
@@ -706,6 +762,12 @@ static struct i2c_board_info __initdata
 };
 
 static mfp_cfg_t zeus_pin_config[] __initdata = {
+	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+
 	GPIO15_nCS_1,
 	GPIO78_nCS_2,
 	GPIO80_nCS_4,
@@ -731,6 +793,11 @@ static mfp_cfg_t zeus_pin_config[] __ini
 	GPIO104_CIF_DD_2,
 	GPIO105_CIF_DD_1,
 
+	GPIO81_SSP3_TXD,
+	GPIO82_SSP3_RXD,
+	GPIO83_SSP3_SFRM,
+	GPIO84_SSP3_SCLK,
+
 	GPIO48_nPOE,
 	GPIO49_nPWE,
 	GPIO50_nPIOR,
@@ -785,6 +852,8 @@ static void __init zeus_init(void)
 	pxa_set_ac97_info(&zeus_ac97_info);
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(zeus_i2c_devices));
+	pxa2xx_set_spi_info(3, &pxa2xx_spi_ssp3_master_info);
+	spi_register_board_info(zeus_spi_board_info, ARRAY_SIZE(zeus_spi_board_info));
 }
 
 static struct map_desc zeus_io_desc[] __initdata = {
@@ -807,12 +876,6 @@ static struct map_desc zeus_io_desc[] __
 		.type    = MT_DEVICE,
 	},
 	{
-		.virtual = ZEUS_CPLD_EXTWDOG,
-		.pfn     = __phys_to_pfn(ZEUS_CPLD_EXTWDOG_PHYS),
-		.length  = 0x1000,
-		.type    = MT_DEVICE,
-	},
-	{
 		.virtual = ZEUS_PC104IO,
 		.pfn     = __phys_to_pfn(ZEUS_PC104IO_PHYS),
 		.length  = 0x00800000,
@@ -837,7 +900,7 @@ static void __init zeus_map_io(void)
 	PCFR = PCFR_OPDE | PCFR_DC_EN | PCFR_FS | PCFR_FP;
 }
 
-MACHINE_START(ARCOM_ZEUS, "Arcom ZEUS")
+MACHINE_START(ARCOM_ZEUS, "Arcom/Eurotech ZEUS")
 	/* Maintainer: Marc Zyngier <maz@misterjones.org> */
 	.phys_io	= 0x40000000,
 	.io_pg_offst	= ((io_p2v(0x40000000) >> 18) & 0xfffc),
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-realview/core.c linux-libre-2.6.34-gnu1/arch/arm/mach-realview/core.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-realview/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-realview/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/smsc911x.h>
 #include <linux/ata_platform.h>
 #include <linux/amba/mmci.h>
+#include <linux/gfp.h>
 
 #include <asm/clkdev.h>
 #include <asm/system.h>
@@ -253,7 +254,7 @@ static unsigned int realview_mmc_status(
 	else
 		mask = 2;
 
-	return readl(REALVIEW_SYSMCI) & mask;
+	return !(readl(REALVIEW_SYSMCI) & mask);
 }
 
 struct mmci_platform_data realview_mmc0_plat_data = {
@@ -346,10 +347,7 @@ static struct clk_lookup lookups[] = {
 
 static int __init clk_init(void)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(lookups); i++)
-		clkdev_add(&lookups[i]);
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 	return 0;
 }
 arch_initcall(clk_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-realview/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-realview/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-realview/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-realview/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,7 @@
 #error "Unknown RealView platform"
 #endif
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx,      #0x10000000
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-realview/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-realview/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-realview/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-realview/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,4 +18,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#define VMALLOC_END		0xf8000000
+#define VMALLOC_END		0xf8000000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-rpc/dma.c linux-libre-2.6.34-gnu1/arch/arm/mach-rpc/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-rpc/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-rpc/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,6 @@
  *
  *  DMA functions specific to RiscPC architecture
  */
-#include <linux/slab.h>
 #include <linux/mman.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-rpc/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-rpc/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-rpc/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-rpc/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
  *
 */
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #0x03000000
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-rpc/include/mach/uncompress.h linux-libre-2.6.34-gnu1/arch/arm/mach-rpc/include/mach/uncompress.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-rpc/include/mach/uncompress.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-rpc/include/mach/uncompress.h	2010-05-16 17:17:36.000000000 -0400
@@ -109,8 +109,6 @@ static inline void flush(void)
 {
 }
 
-static void error(char *x);
-
 /*
  * Setup for decompression
  */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/dma.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,7 @@
 #include <mach/dma.h>
 
 #include <plat/cpu.h>
-#include <plat/dma-plat.h>
+#include <plat/dma-s3c24xx.h>
 
 #include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/h1940-bluetooth.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/h1940-bluetooth.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/h1940-bluetooth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/h1940-bluetooth.c	2010-05-16 17:17:36.000000000 -0400
@@ -56,7 +56,7 @@ static const struct rfkill_ops h1940bt_r
 	.set_block = h1940bt_set_block,
 };
 
-static int __init h1940bt_probe(struct platform_device *pdev)
+static int __devinit h1940bt_probe(struct platform_device *pdev)
 {
 	struct rfkill *rfk;
 	int ret = 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,7 @@
 #define S3C2410_UART1_OFF (0x4000)
 #define SHIFT_2440TXF (14-9)
 
-	.macro addruart, rx
+	.macro addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1
 		ldreq	\rx, = S3C24XX_PA_UART
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-core.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-core.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-core.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,34 +0,0 @@
-/* arch/arm/mach-s3c24100/include/mach/gpio-core.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C2410 - GPIO core support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_GPIO_CORE_H
-#define __ASM_ARCH_GPIO_CORE_H __FILE__
-
-#include <plat/gpio-core.h>
-#include <mach/regs-gpio.h>
-
-extern struct s3c_gpio_chip s3c24xx_gpios[];
-
-static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin)
-{
-	struct s3c_gpio_chip *chip;
-
-	if (pin > S3C2410_GPG(10))
-		return NULL;
-
-	chip = &s3c24xx_gpios[pin/32];
-	return (S3C2410_GPIO_OFFSET(pin) < chip->chip.ngpio) ? chip : NULL;
-}
-
-#endif /* __ASM_ARCH_GPIO_CORE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-track.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-track.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-track.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-track.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,33 @@
+/* arch/arm/mach-s3c24100/include/mach/gpio-core.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C2410 - GPIO core support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_CORE_H
+#define __ASM_ARCH_GPIO_CORE_H __FILE__
+
+#include <mach/regs-gpio.h>
+
+extern struct s3c_gpio_chip s3c24xx_gpios[];
+
+static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin)
+{
+	struct s3c_gpio_chip *chip;
+
+	if (pin > S3C2410_GPG(10))
+		return NULL;
+
+	chip = &s3c24xx_gpios[pin/32];
+	return (S3C2410_GPIO_OFFSET(pin) < chip->chip.ngpio) ? chip : NULL;
+}
+
+#endif /* __ASM_ARCH_GPIO_CORE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/pm-core.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/pm-core.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/pm-core.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/pm-core.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,64 @@
+/* linux/arch/arm/mach-s3c2410/include/pm-core.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);
+}
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+					   struct pm_uart_save *save)
+{
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/regs-gpio.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/regs-gpio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/regs-gpio.h	2010-05-16 17:17:36.000000000 -0400
@@ -406,31 +406,31 @@
 #define S3C2443_GPE5_SD1_CLK   (0x02 << 10)
 #define S3C2400_GPE5_EINT5     (0x02 << 10)
 #define S3C2400_GPE5_TCLK1     (0x03 << 10)
+#define S3C2443_GPE5_AC_BITCLK (0x03 << 10)
 
 #define S3C2410_GPE6_SDCMD     (0x02 << 12)
 #define S3C2443_GPE6_SD1_CMD   (0x02 << 12)
-#define S3C2443_GPE6_AC_BITCLK (0x03 << 12)
+#define S3C2443_GPE6_AC_SDI    (0x03 << 12)
 #define S3C2400_GPE6_EINT6     (0x02 << 12)
 
 #define S3C2410_GPE7_SDDAT0    (0x02 << 14)
 #define S3C2443_GPE5_SD1_DAT0  (0x02 << 14)
-#define S3C2443_GPE7_AC_SDI    (0x03 << 14)
+#define S3C2443_GPE7_AC_SDO    (0x03 << 14)
 #define S3C2400_GPE7_EINT7     (0x02 << 14)
 
 #define S3C2410_GPE8_SDDAT1    (0x02 << 16)
 #define S3C2443_GPE8_SD1_DAT1  (0x02 << 16)
-#define S3C2443_GPE8_AC_SDO    (0x03 << 16)
+#define S3C2443_GPE8_AC_SYNC   (0x03 << 16)
 #define S3C2400_GPE8_nXDACK0   (0x02 << 16)
 
 #define S3C2410_GPE9_SDDAT2    (0x02 << 18)
 #define S3C2443_GPE9_SD1_DAT2  (0x02 << 18)
-#define S3C2443_GPE9_AC_SYNC   (0x03 << 18)
+#define S3C2443_GPE9_AC_nRESET (0x03 << 18)
 #define S3C2400_GPE9_nXDACK1   (0x02 << 18)
 #define S3C2400_GPE9_nXBACK    (0x03 << 18)
 
 #define S3C2410_GPE10_SDDAT3   (0x02 << 20)
 #define S3C2443_GPE10_SD1_DAT3 (0x02 << 20)
-#define S3C2443_GPE10_AC_nRESET (0x03 << 20)
 #define S3C2400_GPE10_nXDREQ0  (0x02 << 20)
 
 #define S3C2410_GPE11_SPIMISO0 (0x02 << 22)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -42,23 +42,14 @@
 
 #define S3C2443_PLLCON_OFF		(1<<24)
 
-#define S3C2443_CLKSRC_I2S_EXT		(1<<14)
-#define S3C2443_CLKSRC_I2S_EPLLDIV	(0<<14)
-#define S3C2443_CLKSRC_I2S_EPLLREF	(2<<14)
-#define S3C2443_CLKSRC_I2S_EPLLREF3	(3<<14)
-#define S3C2443_CLKSRC_I2S_MASK		(3<<14)
-
 #define S3C2443_CLKSRC_EPLLREF_XTAL	(2<<7)
 #define S3C2443_CLKSRC_EPLLREF_EXTCLK	(3<<7)
 #define S3C2443_CLKSRC_EPLLREF_MPLLREF	(0<<7)
 #define S3C2443_CLKSRC_EPLLREF_MPLLREF2	(1<<7)
 #define S3C2443_CLKSRC_EPLLREF_MASK	(3<<7)
 
-#define S3C2443_CLKSRC_ESYSCLK_EPLL	(1<<6)
-#define S3C2443_CLKSRC_MSYSCLK_MPLL	(1<<4)
 #define S3C2443_CLKSRC_EXTCLK_DIV	(1<<3)
 
-#define S3C2443_CLKDIV0_DVS		(1<<13)
 #define S3C2443_CLKDIV0_HALF_HCLK	(1<<3)
 #define S3C2443_CLKDIV0_HALF_PCLK	(1<<2)
 
@@ -81,28 +72,7 @@
 #define S3C2443_CLKDIV0_ARMDIV_12	(13<<9)
 #define S3C2443_CLKDIV0_ARMDIV_16	(15<<9)
 
-/* S3C2443_CLKDIV1 */
-
-#define S3C2443_CLKDIV1_CAMDIV_MASK	(15<<26)
-#define S3C2443_CLKDIV1_CAMDIV_SHIFT	(26)
-
-#define S3C2443_CLKDIV1_HSSPIDIV_MASK	(3<<24)
-#define S3C2443_CLKDIV1_HSSPIDIV_SHIFT	(24)
-
-#define S3C2443_CLKDIV1_DISPDIV_MASK	(0xff<<16)
-#define S3C2443_CLKDIV1_DISPDIV_SHIFT	(16)
-
-#define S3C2443_CLKDIV1_I2SDIV_MASK	(15<<12)
-#define S3C2443_CLKDIV1_I2SDIV_SHIFT	(12)
-
-#define S3C2443_CLKDIV1_UARTDIV_MASK	(15<<8)
-#define S3C2443_CLKDIV1_UARTDIV_SHIFT	(8)
-
-#define S3C2443_CLKDIV1_HSMMCDIV_MASK	(3<<6)
-#define S3C2443_CLKDIV1_HSMMCDIV_SHIFT	(6)
-
-#define S3C2443_CLKDIV1_USBHOSTDIV_MASK	(3<<4)
-#define S3C2443_CLKDIV1_USBHOSTDIV_SHIFT (4)
+/* S3C2443_CLKDIV1 removed, only used in clock.c code */
 
 #define S3C2443_CLKCON_NAND
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/spi-gpio.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/spi-gpio.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/spi-gpio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/spi-gpio.h	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,7 @@
  * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
- * S3C2410 - SPI Controller platfrom_device info
+ * S3C2410 - SPI 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
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/timex.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/timex.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/timex.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c2410/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - time parameters
+ *
+ * This program is free software; you can 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_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,20 @@
+/* arch/arm/mach-s3c2410/include/mach/vmalloc.h
+ *
+ * from arch/arm/mach-iop3xx/include/mach/vmalloc.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 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END	  (0xE0000000)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-amlm5900.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-amlm5900.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-amlm5900.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-amlm5900.c	2010-05-16 17:17:36.000000000 -0400
@@ -153,7 +153,7 @@ static struct platform_device *amlm5900_
 	&s3c_device_adc,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
-	&s3c_device_usb,
+	&s3c_device_ohci,
  	&s3c_device_rtc,
 	&s3c_device_usbgadget,
         &s3c_device_sdi,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-bast.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-bast.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-bast.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-bast.c	2010-05-16 17:17:36.000000000 -0400
@@ -584,7 +584,7 @@ static struct s3c_hwmon_pdata bast_hwmon
 // cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0
 
 static struct platform_device *bast_devices[] __initdata = {
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-h1940.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-h1940.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-h1940.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-h1940.c	2010-05-16 17:17:36.000000000 -0400
@@ -196,7 +196,7 @@ static struct platform_device h1940_devi
 	.id               = -1,
 };
 
-static struct s3c24xx_mci_pdata h1940_mmc_cfg = {
+static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = {
 	.gpio_detect   = S3C2410_GPF(5),
 	.gpio_wprotect = S3C2410_GPH(8),
 	.set_power     = NULL,
@@ -272,7 +272,7 @@ static struct platform_device h1940_lcd_
 
 static struct platform_device *h1940_devices[] __initdata = {
 	&s3c_device_ts,
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
@@ -311,12 +311,11 @@ static void __init h1940_init(void)
 	u32 tmp;
 
 	s3c24xx_fb_set_platdata(&h1940_fb_info);
+	s3c24xx_mci_set_platdata(&h1940_mmc_cfg);
  	s3c24xx_udc_set_platdata(&h1940_udc_cfg);
 	s3c24xx_ts_set_platdata(&h1940_ts_cfg);
 	s3c_i2c0_set_platdata(NULL);
 
-	s3c_device_sdi.dev.platform_data = &h1940_mmc_cfg;
-
 	/* Turn off suspend on both USB ports, and switch the
 	 * selectable USB port to USB device mode. */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-n30.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-n30.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-n30.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-n30.c	2010-05-16 17:17:36.000000000 -0400
@@ -322,7 +322,7 @@ static struct platform_device *n30_devic
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
 	&s3c_device_iis,
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_usbgadget,
 	&n30_button_device,
 	&n30_blue_led,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-otom.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-otom.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-otom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-otom.c	2010-05-16 17:17:36.000000000 -0400
@@ -92,7 +92,7 @@ static struct platform_device otom_devic
 /* Standard OTOM devices */
 
 static struct platform_device *otom11_devices[] __initdata = {
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-qt2410.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-qt2410.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-qt2410.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-qt2410.c	2010-05-16 17:17:36.000000000 -0400
@@ -246,7 +246,7 @@ static struct platform_device qt2410_spi
 /* Board devices */
 
 static struct platform_device *qt2410_devices[] __initdata = {
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-smdk2410.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-smdk2410.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-smdk2410.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-smdk2410.c	2010-05-16 17:17:36.000000000 -0400
@@ -87,7 +87,7 @@ static struct s3c2410_uartcfg smdk2410_u
 };
 
 static struct platform_device *smdk2410_devices[] __initdata = {
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-tct_hammer.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-tct_hammer.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-tct_hammer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-tct_hammer.c	2010-05-16 17:17:36.000000000 -0400
@@ -129,7 +129,7 @@ static struct platform_device *tct_hamme
 	&s3c_device_adc,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_rtc,
 	&s3c_device_usbgadget,
 	&s3c_device_sdi,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-vr1000.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-vr1000.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-vr1000.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/mach-vr1000.c	2010-05-16 17:17:36.000000000 -0400
@@ -334,7 +334,7 @@ static struct i2c_board_info vr1000_i2c_
 /* devices for this board */
 
 static struct platform_device *vr1000_devices[] __initdata = {
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/usb-simtec.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/usb-simtec.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/usb-simtec.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2410/usb-simtec.c	2010-05-16 17:17:36.000000000 -0400
@@ -91,7 +91,7 @@ static void usb_simtec_enableoc(struct s
 	}
 }
 
-static struct s3c2410_hcd_info usb_simtec_info = {
+static struct s3c2410_hcd_info usb_simtec_info __initdata = {
 	.port[0]	= {
 		.flags	= S3C_HCDFLG_USED
 	},
@@ -127,6 +127,6 @@ int usb_simtec_init(void)
 	gpio_direction_output(S3C2410_GPB(4), 1);
 	gpio_direction_input(S3C2410_GPG(10));
 
-	s3c_device_usb.dev.platform_data = &usb_simtec_info;
+	s3c_ohci_set_platdata(&usb_simtec_info);
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2412/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2412/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -124,7 +124,9 @@ static struct clk clk_usysclk = {
 	.name		= "usysclk",
 	.id		= -1,
 	.parent		= &clk_xtal,
-	.set_parent	= s3c2412_setparent_usysclk,
+	.ops		= &(struct clk_ops) {
+		.set_parent	= s3c2412_setparent_usysclk,
+	},
 };
 
 static struct clk clk_mrefclk = {
@@ -199,10 +201,12 @@ static int s3c2412_setrate_usbsrc(struct
 static struct clk clk_usbsrc = {
 	.name		= "usbsrc",
 	.id		= -1,
-	.get_rate	= s3c2412_getrate_usbsrc,
-	.set_rate	= s3c2412_setrate_usbsrc,
-	.round_rate	= s3c2412_roundrate_usbsrc,
-	.set_parent	= s3c2412_setparent_usbsrc,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2412_getrate_usbsrc,
+		.set_rate	= s3c2412_setrate_usbsrc,
+		.round_rate	= s3c2412_roundrate_usbsrc,
+		.set_parent	= s3c2412_setparent_usbsrc,
+	},
 };
 
 static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent)
@@ -225,7 +229,9 @@ static int s3c2412_setparent_msysclk(str
 static struct clk clk_msysclk = {
 	.name		= "msysclk",
 	.id		= -1,
-	.set_parent	= s3c2412_setparent_msysclk,
+	.ops		= &(struct clk_ops) {
+		.set_parent	= s3c2412_setparent_msysclk,
+	},
 };
 
 static int s3c2412_setparent_armclk(struct clk *clk, struct clk *parent)
@@ -264,7 +270,9 @@ static struct clk clk_armclk = {
 	.name		= "armclk",
 	.id		= -1,
 	.parent		= &clk_msysclk,
-	.set_parent	= s3c2412_setparent_armclk,
+	.ops		= &(struct clk_ops) {
+		.set_parent	= s3c2412_setparent_armclk,
+	},
 };
 
 /* these next clocks have an divider immediately after them,
@@ -337,10 +345,12 @@ static int s3c2412_setrate_uart(struct c
 static struct clk clk_uart = {
 	.name		= "uartclk",
 	.id		= -1,
-	.get_rate	= s3c2412_getrate_uart,
-	.set_rate	= s3c2412_setrate_uart,
-	.set_parent	= s3c2412_setparent_uart,
-	.round_rate	= s3c2412_roundrate_clksrc,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2412_getrate_uart,
+		.set_rate	= s3c2412_setrate_uart,
+		.set_parent	= s3c2412_setparent_uart,
+		.round_rate	= s3c2412_roundrate_clksrc,
+	},
 };
 
 static int s3c2412_setparent_i2s(struct clk *clk, struct clk *parent)
@@ -388,10 +398,12 @@ static int s3c2412_setrate_i2s(struct cl
 static struct clk clk_i2s = {
 	.name		= "i2sclk",
 	.id		= -1,
-	.get_rate	= s3c2412_getrate_i2s,
-	.set_rate	= s3c2412_setrate_i2s,
-	.set_parent	= s3c2412_setparent_i2s,
-	.round_rate	= s3c2412_roundrate_clksrc,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2412_getrate_i2s,
+		.set_rate	= s3c2412_setrate_i2s,
+		.set_parent	= s3c2412_setparent_i2s,
+		.round_rate	= s3c2412_roundrate_clksrc,
+	},
 };
 
 static int s3c2412_setparent_cam(struct clk *clk, struct clk *parent)
@@ -438,10 +450,12 @@ static int s3c2412_setrate_cam(struct cl
 static struct clk clk_cam = {
 	.name		= "camif-upll",	/* same as 2440 name */
 	.id		= -1,
-	.get_rate	= s3c2412_getrate_cam,
-	.set_rate	= s3c2412_setrate_cam,
-	.set_parent	= s3c2412_setparent_cam,
-	.round_rate	= s3c2412_roundrate_clksrc,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2412_getrate_cam,
+		.set_rate	= s3c2412_setrate_cam,
+		.set_parent	= s3c2412_setparent_cam,
+		.round_rate	= s3c2412_roundrate_clksrc,
+	},
 };
 
 /* standard clock definitions */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/dma.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2412/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2412/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,7 +20,7 @@
 
 #include <mach/dma.h>
 
-#include <plat/dma-plat.h>
+#include <plat/dma-s3c24xx.h>
 #include <plat/cpu.h>
 
 #include <plat/regs-serial.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/mach-jive.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2412/mach-jive.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/mach-jive.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2412/mach-jive.c	2010-05-16 17:17:36.000000000 -0400
@@ -468,7 +468,7 @@ static struct i2c_board_info jive_i2c_de
 /* The platform devices being used. */
 
 static struct platform_device *jive_devices[] __initdata = {
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_rtc,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/mach-smdk2413.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2412/mach-smdk2413.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/mach-smdk2413.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2412/mach-smdk2413.c	2010-05-16 17:17:36.000000000 -0400
@@ -104,8 +104,7 @@ static struct s3c2410_udc_mach_info smdk
 
 
 static struct platform_device *smdk2413_devices[] __initdata = {
-	&s3c_device_usb,
-	//&s3c_device_lcd,
+	&s3c_device_ohci,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
 	&s3c_device_iis,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/mach-vstms.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2412/mach-vstms.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/mach-vstms.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2412/mach-vstms.c	2010-05-16 17:17:36.000000000 -0400
@@ -121,7 +121,7 @@ static struct s3c2410_platform_nand __in
 };
 
 static struct platform_device *vstms_devices[] __initdata = {
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
 	&s3c_device_iis,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -98,8 +98,10 @@ static struct clk s3c2440_clk_cam = {
 static struct clk s3c2440_clk_cam_upll = {
 	.name		= "camif-upll",
 	.id		= -1,
-	.set_rate	= s3c2440_camif_upll_setrate,
-	.round_rate	= s3c2440_camif_upll_round,
+	.ops		= &(struct clk_ops) {
+		.set_rate	= s3c2440_camif_upll_setrate,
+		.round_rate	= s3c2440_camif_upll_round,
+	},
 };
 
 static struct clk s3c2440_clk_ac97 = {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/dma.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,7 +20,7 @@
 #include <mach/map.h>
 #include <mach/dma.h>
 
-#include <plat/dma-plat.h>
+#include <plat/dma-s3c24xx.h>
 #include <plat/cpu.h>
 
 #include <plat/regs-serial.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/dsc.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/dsc.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/dsc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/dsc.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,7 @@
 #include <mach/regs-dsc.h>
 
 #include <plat/cpu.h>
-#include <plat/s3c2440.h>
+#include <plat/s3c244x.h>
 
 int s3c2440_set_dsc(unsigned int pin, unsigned int value)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/include/mach/gta02.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/include/mach/gta02.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/include/mach/gta02.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/include/mach/gta02.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,84 @@
+#ifndef _GTA02_H
+#define _GTA02_H
+
+#include <mach/regs-gpio.h>
+
+/* Different hardware revisions, passed in ATAG_REVISION by u-boot */
+#define GTA02v1_SYSTEM_REV	0x00000310
+#define GTA02v2_SYSTEM_REV	0x00000320
+#define GTA02v3_SYSTEM_REV	0x00000330
+#define GTA02v4_SYSTEM_REV	0x00000340
+#define GTA02v5_SYSTEM_REV	0x00000350
+/* since A7 is basically same as A6, we use A6 PCB ID */
+#define GTA02v6_SYSTEM_REV	0x00000360
+
+#define GTA02_GPIO_n3DL_GSM	S3C2410_GPA(13)	/* v1 + v2 + v3 only */
+
+#define GTA02_GPIO_PWR_LED1	S3C2410_GPB(0)
+#define GTA02_GPIO_PWR_LED2	S3C2410_GPB(1)
+#define GTA02_GPIO_AUX_LED	S3C2410_GPB(2)
+#define GTA02_GPIO_VIBRATOR_ON	S3C2410_GPB(3)
+#define GTA02_GPIO_MODEM_RST	S3C2410_GPB(5)
+#define GTA02_GPIO_BT_EN	S3C2410_GPB(6)
+#define GTA02_GPIO_MODEM_ON	S3C2410_GPB(7)
+#define GTA02_GPIO_EXTINT8	S3C2410_GPB(8)
+#define GTA02_GPIO_USB_PULLUP	S3C2410_GPB(9)
+
+#define GTA02_GPIO_PIO5		S3C2410_GPC(5)	/* v3 + v4 only */
+
+#define GTA02v3_GPIO_nG1_CS	S3C2410_GPD(12)	/* v3 + v4 only */
+#define GTA02v3_GPIO_nG2_CS	S3C2410_GPD(13)	/* v3 + v4 only */
+#define GTA02v5_GPIO_HDQ	S3C2410_GPD(14)   /* v5 + */
+
+#define GTA02_GPIO_nG1_INT	S3C2410_GPF(0)
+#define GTA02_GPIO_IO1		S3C2410_GPF(1)
+#define GTA02_GPIO_PIO_2	S3C2410_GPF(2)	/* v2 + v3 + v4 only */
+#define GTA02_GPIO_JACK_INSERT	S3C2410_GPF(4)
+#define GTA02_GPIO_WLAN_GPIO1	S3C2410_GPF(5)	/* v2 + v3 + v4 only */
+#define GTA02_GPIO_AUX_KEY	S3C2410_GPF(6)
+#define GTA02_GPIO_HOLD_KEY	S3C2410_GPF(7)
+
+#define GTA02_GPIO_3D_IRQ	S3C2410_GPG(4)
+#define GTA02v2_GPIO_nG2_INT	S3C2410_GPG(8)	/* v2 + v3 + v4 only */
+#define GTA02v3_GPIO_nUSB_OC	S3C2410_GPG(9)	/* v3 + v4 only */
+#define GTA02v3_GPIO_nUSB_FLT	S3C2410_GPG(10)	/* v3 + v4 only */
+#define GTA02v3_GPIO_nGSM_OC	S3C2410_GPG(11)	/* v3 + v4 only */
+
+#define GTA02_GPIO_AMP_SHUT	S3C2440_GPJ1	/* v2 + v3 + v4 only */
+#define GTA02v1_GPIO_WLAN_GPIO10	S3C2440_GPJ2
+#define GTA02_GPIO_HP_IN	S3C2440_GPJ2	/* v2 + v3 + v4 only */
+#define GTA02_GPIO_INT0		S3C2440_GPJ3	/* v2 + v3 + v4 only */
+#define GTA02_GPIO_nGSM_EN	S3C2440_GPJ4
+#define GTA02_GPIO_3D_RESET	S3C2440_GPJ5
+#define GTA02_GPIO_nDL_GSM	S3C2440_GPJ6	/* v4 + v5 only */
+#define GTA02_GPIO_WLAN_GPIO0	S3C2440_GPJ7
+#define GTA02v1_GPIO_BAT_ID	S3C2440_GPJ8
+#define GTA02_GPIO_KEEPACT	S3C2440_GPJ8
+#define GTA02v1_GPIO_HP_IN	S3C2440_GPJ10
+#define GTA02_CHIP_PWD		S3C2440_GPJ11	/* v2 + v3 + v4 only */
+#define GTA02_GPIO_nWLAN_RESET	S3C2440_GPJ12	/* v2 + v3 + v4 only */
+
+#define GTA02_IRQ_GSENSOR_1	IRQ_EINT0
+#define GTA02_IRQ_MODEM		IRQ_EINT1
+#define GTA02_IRQ_PIO_2		IRQ_EINT2	/* v2 + v3 + v4 only */
+#define GTA02_IRQ_nJACK_INSERT	IRQ_EINT4
+#define GTA02_IRQ_WLAN_GPIO1	IRQ_EINT5
+#define GTA02_IRQ_AUX		IRQ_EINT6
+#define GTA02_IRQ_nHOLD		IRQ_EINT7
+#define GTA02_IRQ_PCF50633	IRQ_EINT9
+#define GTA02_IRQ_3D		IRQ_EINT12
+#define GTA02_IRQ_GSENSOR_2	IRQ_EINT16	/* v2 + v3 + v4 only */
+#define GTA02v3_IRQ_nUSB_OC	IRQ_EINT17	/* v3 + v4 only */
+#define GTA02v3_IRQ_nUSB_FLT	IRQ_EINT18	/* v3 + v4 only */
+#define GTA02v3_IRQ_nGSM_OC	IRQ_EINT19	/* v3 + v4 only */
+
+/* returns 00 000 on GTA02 A5 and earlier, A6 returns 01 001 */
+#define GTA02_PCB_ID1_0		S3C2410_GPC(13)
+#define GTA02_PCB_ID1_1		S3C2410_GPC(15)
+#define GTA02_PCB_ID1_2		S3C2410_GPD(0)
+#define GTA02_PCB_ID2_0		S3C2410_GPD(3)
+#define GTA02_PCB_ID2_1		S3C2410_GPD(4)
+
+int gta02_get_pcb_revision(void);
+
+#endif /* _GTA02_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -15,14 +15,67 @@ config CPU_S3C2440
 	help
 	  Support for S3C2440 Samsung Mobile CPU based systems.
 
+config CPU_S3C2442
+	bool
+	depends on ARCH_S3C2410
+	select CPU_ARM920T
+	select S3C2410_CLOCK
+	select S3C2410_GPIO
+	select S3C2410_PM if PM
+	select CPU_S3C244X
+	select CPU_LLSERIAL_S3C2440
+	help
+	  Support for S3C2442 Samsung Mobile CPU based systems.
+
+config CPU_S3C244X
+	bool
+	depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
+	help
+	  Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
+
+
+
+config S3C2440_CPUFREQ
+	bool "S3C2440/S3C2442 CPU Frequency scaling support"
+	depends on CPU_FREQ_S3C24XX && (CPU_S3C2440 || CPU_S3C2442)
+	select S3C2410_CPUFREQ_UTILS
+	default y
+	help
+	  CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs.
+
+config S3C2440_XTAL_12000000
+	bool
+	help
+	  Indicate that the build needs to support 12MHz system
+	  crystal.
+
+config S3C2440_XTAL_16934400
+	bool
+	help
+	  Indicate that the build needs to support 16.9344MHz system
+	  crystal.
+
+config S3C2440_PLL_12000000
+	bool
+	depends on S3C2440_CPUFREQ && S3C2440_XTAL_12000000
+	default y if CPU_FREQ_S3C24XX_PLL
+	help
+	  PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals.
+
+config S3C2440_PLL_16934400
+	bool
+	depends on S3C2440_CPUFREQ && S3C2440_XTAL_16934400
+	default y if CPU_FREQ_S3C24XX_PLL
+	help
+	  PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals.
+
 config S3C2440_DMA
 	bool
 	depends on ARCH_S3C2410 && CPU_S3C24405B
 	help
 	  Support for S3C2440 specific DMA code5A
 
-
-menu "S3C2440 Machines"
+menu "S3C2440 and S3C2442 Machines"
 
 config MACH_ANUBIS
 	bool "Simtec Electronics ANUBIS"
@@ -37,6 +90,18 @@ config MACH_ANUBIS
 	  Say Y here if you are using the Simtec Electronics ANUBIS
 	  development system
 
+config MACH_NEO1973_GTA02
+	bool "Openmoko GTA02 / Freerunner phone"
+	select CPU_S3C2442
+	select MFD_PCF50633
+	select PCF50633_GPIO
+	select I2C
+	select POWER_SUPPLY
+	select MACH_NEO1973
+	select S3C2410_PWM
+	help
+	   Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone
+
 config MACH_OSIRIS
 	bool "Simtec IM2440D20 (OSIRIS) module"
 	select CPU_S3C2440
@@ -94,11 +159,14 @@ config MACH_NEXCODER_2440
 
 config SMDK2440_CPU2440
 	bool "SMDK2440 with S3C2440 CPU module"
-	depends on ARCH_S3C2440
 	default y if ARCH_S3C2440
 	select S3C2440_XTAL_16934400
 	select CPU_S3C2440
 
+config SMDK2440_CPU2442
+	bool "SMDM2440 with S3C2442 CPU module"
+	select CPU_S3C2442
+
 config MACH_AT2440EVB
 	bool "Avantech AT2440EVB development board"
 	select CPU_S3C2440
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-anubis.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/mach-anubis.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-anubis.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/mach-anubis.c	2010-05-16 17:17:36.000000000 -0400
@@ -409,7 +409,7 @@ static struct platform_device anubis_dev
 /* Standard Anubis devices */
 
 static struct platform_device *anubis_devices[] __initdata = {
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_wdt,
 	&s3c_device_adc,
 	&s3c_device_i2c0,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-at2440evb.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/mach-at2440evb.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-at2440evb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/mach-at2440evb.c	2010-05-16 17:17:36.000000000 -0400
@@ -165,7 +165,7 @@ static struct platform_device at2440evb_
 	},
 };
 
-static struct s3c24xx_mci_pdata at2440evb_mci_pdata = {
+static struct s3c24xx_mci_pdata at2440evb_mci_pdata __initdata = {
 	.gpio_detect	= S3C2410_GPG(10),
 };
 
@@ -203,7 +203,7 @@ static struct s3c2410fb_mach_info at2440
 };
 
 static struct platform_device *at2440evb_devices[] __initdata = {
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_wdt,
 	&s3c_device_adc,
 	&s3c_device_i2c0,
@@ -216,8 +216,6 @@ static struct platform_device *at2440evb
 
 static void __init at2440evb_map_io(void)
 {
-	s3c_device_sdi.dev.platform_data = &at2440evb_mci_pdata;
-
 	s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc));
 	s3c24xx_init_clocks(16934400);
 	s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs));
@@ -226,6 +224,7 @@ static void __init at2440evb_map_io(void
 static void __init at2440evb_init(void)
 {
 	s3c24xx_fb_set_platdata(&at2440evb_fb_info);
+	s3c24xx_mci_set_platdata(&at2440evb_mci_pdata);
 	s3c_nand_set_platdata(&at2440evb_nand_info);
 	s3c_i2c0_set_platdata(NULL);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-gta02.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/mach-gta02.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-gta02.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/mach-gta02.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,647 @@
+/*
+ * linux/arch/arm/mach-s3c2442/mach-gta02.c
+ *
+ * S3C2442 Machine Support for Openmoko GTA02 / FreeRunner.
+ *
+ * Copyright (C) 2006-2009 by Openmoko, Inc.
+ * Authors: Harald Welte <laforge@openmoko.org>
+ *          Andy Green <andy@openmoko.org>
+ *          Werner Almesberger <werner@openmoko.org>
+ * 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 <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/spi/spi.h>
+
+#include <linux/mmc/host.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/regulator/machine.h>
+
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/mbc.h>
+#include <linux/mfd/pcf50633/adc.h>
+#include <linux/mfd/pcf50633/gpio.h>
+#include <linux/mfd/pcf50633/pmic.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/fb.h>
+
+#include <mach/spi.h>
+#include <mach/spi-gpio.h>
+#include <plat/usb-control.h>
+#include <mach/regs-mem.h>
+#include <mach/hardware.h>
+
+#include <mach/gta02.h>
+
+#include <plat/regs-serial.h>
+#include <plat/nand.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/udc.h>
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+
+static struct pcf50633 *gta02_pcf;
+
+/*
+ * This gets called every 1ms when we paniced.
+ */
+
+static long gta02_panic_blink(long count)
+{
+	long delay = 0;
+	static long last_blink;
+	static char led;
+
+	/* Fast blink: 200ms period. */
+	if (count - last_blink < 100)
+		return 0;
+
+	led ^= 1;
+	gpio_direction_output(GTA02_GPIO_AUX_LED, led);
+
+	last_blink = count;
+
+	return delay;
+}
+
+
+static struct map_desc gta02_iodesc[] __initdata = {
+	{
+		.virtual	= 0xe0000000,
+		.pfn		= __phys_to_pfn(S3C2410_CS3 + 0x01000000),
+		.length		= SZ_1M,
+		.type		= MT_DEVICE
+	},
+};
+
+#define UCON (S3C2410_UCON_DEFAULT | S3C2443_UCON_RXERR_IRQEN)
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg gta02_uartcfgs[] = {
+	[0] = {
+		.hwport		= 0,
+		.flags		= 0,
+		.ucon		= UCON,
+		.ulcon		= ULCON,
+		.ufcon		= UFCON,
+	},
+	[1] = {
+		.hwport		= 1,
+		.flags		= 0,
+		.ucon		= UCON,
+		.ulcon		= ULCON,
+		.ufcon		= UFCON,
+	},
+	[2] = {
+		.hwport		= 2,
+		.flags		= 0,
+		.ucon		= UCON,
+		.ulcon		= ULCON,
+		.ufcon		= UFCON,
+	},
+};
+
+#ifdef CONFIG_CHARGER_PCF50633
+/*
+ * On GTA02 the 1A charger features a 48K resistor to 0V on the ID pin.
+ * We use this to recognize that we can pull 1A from the USB socket.
+ *
+ * These constants are the measured pcf50633 ADC levels with the 1A
+ * charger / 48K resistor, and with no pulldown resistor.
+ */
+
+#define ADC_NOM_CHG_DETECT_1A 6
+#define ADC_NOM_CHG_DETECT_USB 43
+
+static void
+gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
+{
+	int  ma;
+
+	/* Interpret charger type */
+	if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) {
+
+		/*
+		 * Sanity - stop GPO driving out now that we have a 1A charger
+		 * GPO controls USB Host power generation on GTA02
+		 */
+		pcf50633_gpio_set(pcf, PCF50633_GPO, 0);
+
+		ma = 1000;
+	} else
+		ma = 100;
+
+	pcf50633_mbc_usb_curlim_set(pcf, ma);
+}
+
+static struct delayed_work gta02_charger_work;
+static int gta02_usb_vbus_draw;
+
+static void gta02_charger_worker(struct work_struct *work)
+{
+	if (gta02_usb_vbus_draw) {
+		pcf50633_mbc_usb_curlim_set(gta02_pcf, gta02_usb_vbus_draw);
+		return;
+	}
+
+#ifdef CONFIG_PCF50633_ADC
+	pcf50633_adc_async_read(gta02_pcf,
+				PCF50633_ADCC1_MUX_ADCIN1,
+				PCF50633_ADCC1_AVERAGE_16,
+				gta02_configure_pmu_for_charger,
+				NULL);
+#else
+	/*
+	 * If the PCF50633 ADC is disabled we fallback to a
+	 * 100mA limit for safety.
+	 */
+	pcf50633_mbc_usb_curlim_set(pcf, 100);
+#endif
+}
+
+#define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000)
+
+static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq)
+{
+	if (irq == PCF50633_IRQ_USBINS) {
+		schedule_delayed_work(&gta02_charger_work,
+				      GTA02_CHARGER_CONFIGURE_TIMEOUT);
+
+		return;
+	}
+
+	if (irq == PCF50633_IRQ_USBREM) {
+		cancel_delayed_work_sync(&gta02_charger_work);
+		gta02_usb_vbus_draw = 0;
+	}
+}
+
+static void gta02_udc_vbus_draw(unsigned int ma)
+{
+	if (!gta02_pcf)
+		return;
+
+	gta02_usb_vbus_draw = ma;
+
+	schedule_delayed_work(&gta02_charger_work,
+			      GTA02_CHARGER_CONFIGURE_TIMEOUT);
+}
+#else /* !CONFIG_CHARGER_PCF50633 */
+#define gta02_pmu_event_callback	NULL
+#define gta02_udc_vbus_draw		NULL
+#endif
+
+/*
+ * This is called when pc50633 is probed, unfortunately quite late in the
+ * day since it is an I2C bus device. Here we can belatedly define some
+ * platform devices with the advantage that we can mark the pcf50633 as the
+ * parent. This makes them get suspended and resumed with their parent
+ * the pcf50633 still around.
+ */
+
+static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf);
+
+
+static char *gta02_batteries[] = {
+	"battery",
+};
+
+struct pcf50633_platform_data gta02_pcf_pdata = {
+	.resumers = {
+		[0] =	PCF50633_INT1_USBINS |
+			PCF50633_INT1_USBREM |
+			PCF50633_INT1_ALARM,
+		[1] =	PCF50633_INT2_ONKEYF,
+		[2] =	PCF50633_INT3_ONKEY1S,
+		[3] =	PCF50633_INT4_LOWSYS |
+			PCF50633_INT4_LOWBAT |
+			PCF50633_INT4_HIGHTMP,
+	},
+
+	.batteries = gta02_batteries,
+	.num_batteries = ARRAY_SIZE(gta02_batteries),
+
+	.charger_reference_current_ma = 1000,
+
+	.reg_init_data = {
+		[PCF50633_REGULATOR_AUTO] = {
+			.constraints = {
+				.min_uV = 3300000,
+				.max_uV = 3300000,
+				.valid_modes_mask = REGULATOR_MODE_NORMAL,
+				.always_on = 1,
+				.apply_uV = 1,
+				.state_mem = {
+					.enabled = 1,
+				},
+			},
+		},
+		[PCF50633_REGULATOR_DOWN1] = {
+			.constraints = {
+				.min_uV = 1300000,
+				.max_uV = 1600000,
+				.valid_modes_mask = REGULATOR_MODE_NORMAL,
+				.always_on = 1,
+				.apply_uV = 1,
+			},
+		},
+		[PCF50633_REGULATOR_DOWN2] = {
+			.constraints = {
+				.min_uV = 1800000,
+				.max_uV = 1800000,
+				.valid_modes_mask = REGULATOR_MODE_NORMAL,
+				.apply_uV = 1,
+				.always_on = 1,
+				.state_mem = {
+					.enabled = 1,
+				},
+			},
+		},
+		[PCF50633_REGULATOR_HCLDO] = {
+			.constraints = {
+				.min_uV = 2000000,
+				.max_uV = 3300000,
+				.valid_modes_mask = REGULATOR_MODE_NORMAL,
+				.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+				.always_on = 1,
+			},
+		},
+		[PCF50633_REGULATOR_LDO1] = {
+			.constraints = {
+				.min_uV = 3300000,
+				.max_uV = 3300000,
+				.valid_modes_mask = REGULATOR_MODE_NORMAL,
+				.apply_uV = 1,
+				.state_mem = {
+					.enabled = 0,
+				},
+			},
+		},
+		[PCF50633_REGULATOR_LDO2] = {
+			.constraints = {
+				.min_uV = 3300000,
+				.max_uV = 3300000,
+				.valid_modes_mask = REGULATOR_MODE_NORMAL,
+				.apply_uV = 1,
+			},
+		},
+		[PCF50633_REGULATOR_LDO3] = {
+			.constraints = {
+				.min_uV = 3000000,
+				.max_uV = 3000000,
+				.valid_modes_mask = REGULATOR_MODE_NORMAL,
+				.apply_uV = 1,
+			},
+		},
+		[PCF50633_REGULATOR_LDO4] = {
+			.constraints = {
+				.min_uV = 3200000,
+				.max_uV = 3200000,
+				.valid_modes_mask = REGULATOR_MODE_NORMAL,
+				.apply_uV = 1,
+			},
+		},
+		[PCF50633_REGULATOR_LDO5] = {
+			.constraints = {
+				.min_uV = 3000000,
+				.max_uV = 3000000,
+				.valid_modes_mask = REGULATOR_MODE_NORMAL,
+				.apply_uV = 1,
+				.state_mem = {
+					.enabled = 1,
+				},
+			},
+		},
+		[PCF50633_REGULATOR_LDO6] = {
+			.constraints = {
+				.min_uV = 3000000,
+				.max_uV = 3000000,
+				.valid_modes_mask = REGULATOR_MODE_NORMAL,
+			},
+		},
+		[PCF50633_REGULATOR_MEMLDO] = {
+			.constraints = {
+				.min_uV = 1800000,
+				.max_uV = 1800000,
+				.valid_modes_mask = REGULATOR_MODE_NORMAL,
+				.state_mem = {
+					.enabled = 1,
+				},
+			},
+		},
+
+	},
+	.probe_done = gta02_pmu_attach_child_devices,
+	.mbc_event_callback = gta02_pmu_event_callback,
+};
+
+
+/* NOR Flash. */
+
+#define GTA02_FLASH_BASE	0x18000000 /* GCS3 */
+#define GTA02_FLASH_SIZE	0x200000 /* 2MBytes */
+
+static struct physmap_flash_data gta02_nor_flash_data = {
+	.width		= 2,
+};
+
+static struct resource gta02_nor_flash_resource = {
+	.start		= GTA02_FLASH_BASE,
+	.end		= GTA02_FLASH_BASE + GTA02_FLASH_SIZE - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device gta02_nor_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &gta02_nor_flash_data,
+	},
+	.resource	= &gta02_nor_flash_resource,
+	.num_resources	= 1,
+};
+
+
+struct platform_device s3c24xx_pwm_device = {
+	.name		= "s3c24xx_pwm",
+	.num_resources	= 0,
+};
+
+static struct i2c_board_info gta02_i2c_devs[] __initdata = {
+	{
+		I2C_BOARD_INFO("pcf50633", 0x73),
+		.irq = GTA02_IRQ_PCF50633,
+		.platform_data = &gta02_pcf_pdata,
+	},
+	{
+		I2C_BOARD_INFO("wm8753", 0x1a),
+	},
+};
+
+static struct s3c2410_nand_set __initdata gta02_nand_sets[] = {
+	[0] = {
+		/*
+		 * This name is also hard-coded in the boot loaders, so
+		 * changing it would would require all users to upgrade
+		 * their boot loaders, some of which are stored in a NOR
+		 * that is considered to be immutable.
+		 */
+		.name		= "neo1973-nand",
+		.nr_chips	= 1,
+		.flash_bbt	= 1,
+	},
+};
+
+/*
+ * Choose a set of timings derived from S3C@2442B MCP54
+ * data sheet (K5D2G13ACM-D075 MCP Memory).
+ */
+
+static struct s3c2410_platform_nand __initdata gta02_nand_info = {
+	.tacls		= 0,
+	.twrph0		= 25,
+	.twrph1		= 15,
+	.nr_sets	= ARRAY_SIZE(gta02_nand_sets),
+	.sets		= gta02_nand_sets,
+};
+
+
+static void gta02_udc_command(enum s3c2410_udc_cmd_e cmd)
+{
+	switch (cmd) {
+	case S3C2410_UDC_P_ENABLE:
+		pr_debug("%s S3C2410_UDC_P_ENABLE\n", __func__);
+		gpio_direction_output(GTA02_GPIO_USB_PULLUP, 1);
+		break;
+	case S3C2410_UDC_P_DISABLE:
+		pr_debug("%s S3C2410_UDC_P_DISABLE\n", __func__);
+		gpio_direction_output(GTA02_GPIO_USB_PULLUP, 0);
+		break;
+	case S3C2410_UDC_P_RESET:
+		pr_debug("%s S3C2410_UDC_P_RESET\n", __func__);
+		/* FIXME: Do something here. */
+	}
+}
+
+/* Get PMU to set USB current limit accordingly. */
+static struct s3c2410_udc_mach_info gta02_udc_cfg = {
+	.vbus_draw	= gta02_udc_vbus_draw,
+	.udc_command	= gta02_udc_command,
+
+};
+
+
+
+static void gta02_bl_set_intensity(int intensity)
+{
+	struct pcf50633 *pcf = gta02_pcf;
+	int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
+
+	/* We map 8-bit intensity to 6-bit intensity in hardware. */
+	intensity >>= 2;
+
+	/*
+	 * This can happen during, eg, print of panic on blanked console,
+	 * but we can't service i2c without interrupts active, so abort.
+	 */
+	if (in_atomic()) {
+		printk(KERN_ERR "gta02_bl_set_intensity called while atomic\n");
+		return;
+	}
+
+	old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
+	if (intensity == old_intensity)
+		return;
+
+	/* We can't do this anywhere else. */
+	pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 5);
+
+	if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 3))
+		old_intensity = 0;
+
+	/*
+	 * The PCF50633 cannot handle LEDOUT = 0 (datasheet p60)
+	 * if seen, you have to re-enable the LED unit.
+	 */
+	if (!intensity || !old_intensity)
+		pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0);
+
+	/* Illegal to set LEDOUT to 0. */
+	if (!intensity)
+		pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, 2);
+	else
+		pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f,
+					  intensity);
+
+	if (intensity)
+		pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 2);
+
+}
+
+static struct generic_bl_info gta02_bl_info = {
+	.name			= "gta02-bl",
+	.max_intensity		= 0xff,
+	.default_intensity	= 0xff,
+	.set_bl_intensity	= gta02_bl_set_intensity,
+};
+
+static struct platform_device gta02_bl_dev = {
+	.name			= "generic-bl",
+	.id			= 1,
+	.dev = {
+		.platform_data = &gta02_bl_info,
+	},
+};
+
+
+
+/* USB */
+static struct s3c2410_hcd_info gta02_usb_info __initdata = {
+	.port[0]	= {
+		.flags	= S3C_HCDFLG_USED,
+	},
+	.port[1]	= {
+		.flags	= 0,
+	},
+};
+
+
+static void __init gta02_map_io(void)
+{
+	s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
+	s3c24xx_init_clocks(12000000);
+	s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
+}
+
+
+/* These are the guys that don't need to be children of PMU. */
+
+static struct platform_device *gta02_devices[] __initdata = {
+	&s3c_device_ohci,
+	&s3c_device_wdt,
+	&s3c_device_sdi,
+	&s3c_device_usbgadget,
+	&s3c_device_nand,
+	&gta02_nor_flash,
+	&s3c24xx_pwm_device,
+	&s3c_device_iis,
+	&s3c_device_i2c0,
+};
+
+/* These guys DO need to be children of PMU. */
+
+static struct platform_device *gta02_devices_pmu_children[] = {
+	&gta02_bl_dev,
+};
+
+
+/*
+ * This is called when pc50633 is probed, quite late in the day since it is an
+ * I2C bus device.  Here we can define platform devices with the advantage that
+ * we can mark the pcf50633 as the parent.  This makes them get suspended and
+ * resumed with their parent the pcf50633 still around.  All devices whose
+ * operation depends on something from pcf50633 must have this relationship
+ * made explicit like this, or suspend and resume will become an unreliable
+ * hellworld.
+ */
+
+static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
+{
+	int n;
+
+	/* Grab a copy of the now probed PMU pointer. */
+	gta02_pcf = pcf;
+
+	for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++)
+		gta02_devices_pmu_children[n]->dev.parent = pcf->dev;
+
+	platform_add_devices(gta02_devices_pmu_children,
+			     ARRAY_SIZE(gta02_devices_pmu_children));
+}
+
+static void gta02_poweroff(void)
+{
+	pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
+}
+
+static void __init gta02_machine_init(void)
+{
+	/* Set the panic callback to make AUX LED blink at ~5Hz. */
+	panic_blink = gta02_panic_blink;
+
+	s3c_pm_init();
+
+#ifdef CONFIG_CHARGER_PCF50633
+	INIT_DELAYED_WORK(&gta02_charger_work, gta02_charger_worker);
+#endif
+
+	s3c24xx_udc_set_platdata(&gta02_udc_cfg);
+	s3c_ohci_set_platdata(&gta02_usb_info);
+	s3c_nand_set_platdata(&gta02_nand_info);
+	s3c_i2c0_set_platdata(NULL);
+
+	i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
+
+	platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
+	pm_power_off = gta02_poweroff;
+}
+
+
+MACHINE_START(NEO1973_GTA02, "GTA02")
+	/* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+	.map_io		= gta02_map_io,
+	.init_irq	= s3c24xx_init_irq,
+	.init_machine	= gta02_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-mini2440.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/mach-mini2440.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-mini2440.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/mach-mini2440.c	2010-05-16 17:17:36.000000000 -0400
@@ -506,9 +506,8 @@ static struct i2c_board_info mini2440_i2
 };
 
 static struct platform_device *mini2440_devices[] __initdata = {
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_wdt,
-/*	&s3c_device_adc,*/ /* ADC doesn't like living with touchscreen ! */
 	&s3c_device_i2c0,
 	&s3c_device_rtc,
 	&s3c_device_usbgadget,
@@ -522,8 +521,6 @@ static struct platform_device *mini2440_
 	&s3c_device_sdi,
 	&s3c_device_iis,
 	&mini2440_audio,
-/*	&s3c_device_timer[0],*/	/* buzzer pwm, no API for it */
-	/* remaining devices are optional */
 };
 
 static void __init mini2440_map_io(void)
@@ -531,8 +528,6 @@ static void __init mini2440_map_io(void)
 	s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));
 	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));
-
-	s3c_device_sdi.dev.platform_data = &mini2440_mmc_cfg;
 }
 
 /*
@@ -678,6 +673,7 @@ static void __init mini2440_init(void)
 	}
 
 	s3c24xx_udc_set_platdata(&mini2440_udc_cfg);
+	s3c24xx_mci_set_platdata(&mini2440_mmc_cfg);
 	s3c_nand_set_platdata(&mini2440_nand_info);
 	s3c_i2c0_set_platdata(NULL);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-nexcoder.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/mach-nexcoder.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-nexcoder.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/mach-nexcoder.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,7 @@
 #include <plat/iic.h>
 
 #include <plat/s3c2410.h>
-#include <plat/s3c2440.h>
+#include <plat/s3c244x.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
@@ -106,7 +106,7 @@ static struct platform_device nexcoder_d
 /* Standard Nexcoder devices */
 
 static struct platform_device *nexcoder_devices[] __initdata = {
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-rx3715.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/mach-rx3715.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-rx3715.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/mach-rx3715.c	2010-05-16 17:17:36.000000000 -0400
@@ -176,7 +176,7 @@ static struct s3c2410_platform_nand __in
 };
 
 static struct platform_device *rx3715_devices[] __initdata = {
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-smdk2440.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/mach-smdk2440.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-smdk2440.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/mach-smdk2440.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,7 +40,7 @@
 #include <plat/iic.h>
 
 #include <plat/s3c2410.h>
-#include <plat/s3c2440.h>
+#include <plat/s3c244x.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
@@ -150,7 +150,7 @@ static struct s3c2410fb_mach_info smdk24
 };
 
 static struct platform_device *smdk2440_devices[] __initdata = {
-	&s3c_device_usb,
+	&s3c_device_ohci,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -10,10 +10,20 @@ obj-n				:=
 obj-				:=
 
 obj-$(CONFIG_CPU_S3C2440)	+= s3c2440.o dsc.o
+obj-$(CONFIG_CPU_S3C2442)	+= s3c2442.o
+
 obj-$(CONFIG_CPU_S3C2440)	+= irq.o
 obj-$(CONFIG_CPU_S3C2440)	+= clock.o
 obj-$(CONFIG_S3C2440_DMA)	+= dma.o
 
+obj-$(CONFIG_CPU_S3C244X)	+= s3c244x.o
+obj-$(CONFIG_CPU_S3C244X)	+= s3c244x-irq.o
+obj-$(CONFIG_CPU_S3C244X)	+= s3c244x-clock.o
+obj-$(CONFIG_S3C2440_CPUFREQ)	+= s3c2440-cpufreq.o
+
+obj-$(CONFIG_S3C2440_PLL_12000000) += s3c2440-pll-12000000.o
+obj-$(CONFIG_S3C2440_PLL_16934400) += s3c2440-pll-16934400.o
+
 # Machine support
 
 obj-$(CONFIG_MACH_ANUBIS)	+= mach-anubis.o
@@ -23,6 +33,7 @@ obj-$(CONFIG_ARCH_S3C2440)	+= mach-smdk2
 obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
 obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o
 obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o
+obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o
 
 # extra machine support
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c2440.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c2440.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c2440.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c2440.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,9 +29,9 @@
 #include <mach/hardware.h>
 #include <asm/irq.h>
 
-#include <plat/s3c2440.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
+#include <plat/s3c244x.h>
 
 static struct sys_device s3c2440_sysdev = {
 	.cls		= &s3c2440_sysclass,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c2440-cpufreq.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c2440-cpufreq.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c2440-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c2440-cpufreq.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,311 @@
+/* linux/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c
+ *
+ * Copyright (c) 2006-2009 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	Vincent Sanders <vince@simtec.co.uk>
+ *
+ * S3C2440/S3C2442 CPU Frequency scaling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+#include <plat/clock.h>
+
+static struct clk *xtal;
+static struct clk *fclk;
+static struct clk *hclk;
+static struct clk *armclk;
+
+/* HDIV: 1, 2, 3, 4, 6, 8 */
+
+static inline int within_khz(unsigned long a, unsigned long b)
+{
+	long diff = a - b;
+
+	return (diff >= -1000 && diff <= 1000);
+}
+
+/**
+ * s3c2440_cpufreq_calcdivs - calculate divider settings
+ * @cfg: The cpu frequency settings.
+ *
+ * Calcualte the divider values for the given frequency settings
+ * specified in @cfg. The values are stored in @cfg for later use
+ * by the relevant set routine if the request settings can be reached.
+ */
+int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
+{
+	unsigned int hdiv, pdiv;
+	unsigned long hclk, fclk, armclk;
+	unsigned long hclk_max;
+
+	fclk = cfg->freq.fclk;
+	armclk = cfg->freq.armclk;
+	hclk_max = cfg->max.hclk;
+
+	s3c_freq_dbg("%s: fclk is %lu, armclk %lu, max hclk %lu\n",
+		     __func__, fclk, armclk, hclk_max);
+
+	if (armclk > fclk) {
+		printk(KERN_WARNING "%s: armclk > fclk\n", __func__);
+		armclk = fclk;
+	}
+
+	/* if we are in DVS, we need HCLK to be <= ARMCLK */
+	if (armclk < fclk && armclk < hclk_max)
+		hclk_max = armclk;
+
+	for (hdiv = 1; hdiv < 9; hdiv++) {
+		if (hdiv == 5 || hdiv == 7)
+			hdiv++;
+
+		hclk = (fclk / hdiv);
+		if (hclk <= hclk_max || within_khz(hclk, hclk_max))
+			break;
+	}
+
+	s3c_freq_dbg("%s: hclk %lu, div %d\n", __func__, hclk, hdiv);
+
+	if (hdiv > 8)
+		goto invalid;
+
+	pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
+
+	if ((hclk / pdiv) > cfg->max.pclk)
+		pdiv++;
+
+	s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv);
+
+	if (pdiv > 2)
+		goto invalid;
+
+	pdiv *= hdiv;
+
+	/* calculate a valid armclk */
+
+	if (armclk < hclk)
+		armclk = hclk;
+
+	/* if we're running armclk lower than fclk, this really means
+	 * that the system should go into dvs mode, which means that
+	 * armclk is connected to hclk. */
+	if (armclk < fclk) {
+		cfg->divs.dvs = 1;
+		armclk = hclk;
+	} else
+		cfg->divs.dvs = 0;
+
+	cfg->freq.armclk = armclk;
+
+	/* store the result, and then return */
+
+	cfg->divs.h_divisor = hdiv;
+	cfg->divs.p_divisor = pdiv;
+
+	return 0;
+
+ invalid:
+	return -EINVAL;
+}
+
+#define CAMDIVN_HCLK_HALF (S3C2440_CAMDIVN_HCLK3_HALF | \
+			   S3C2440_CAMDIVN_HCLK4_HALF)
+
+/**
+ * s3c2440_cpufreq_setdivs - set the cpu frequency divider settings
+ * @cfg: The cpu frequency settings.
+ *
+ * Set the divisors from the settings in @cfg, which where generated
+ * during the calculation phase by s3c2440_cpufreq_calcdivs().
+ */
+static void s3c2440_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
+{
+	unsigned long clkdiv, camdiv;
+
+	s3c_freq_dbg("%s: divsiors: h=%d, p=%d\n", __func__,
+		     cfg->divs.h_divisor, cfg->divs.p_divisor);
+
+	clkdiv = __raw_readl(S3C2410_CLKDIVN);
+	camdiv = __raw_readl(S3C2440_CAMDIVN);
+
+	clkdiv &= ~(S3C2440_CLKDIVN_HDIVN_MASK | S3C2440_CLKDIVN_PDIVN);
+	camdiv &= ~CAMDIVN_HCLK_HALF;
+
+	switch (cfg->divs.h_divisor) {
+	case 1:
+		clkdiv |= S3C2440_CLKDIVN_HDIVN_1;
+		break;
+
+	case 2:
+		clkdiv |= S3C2440_CLKDIVN_HDIVN_2;
+		break;
+
+	case 6:
+		camdiv |= S3C2440_CAMDIVN_HCLK3_HALF;
+	case 3:
+		clkdiv |= S3C2440_CLKDIVN_HDIVN_3_6;
+		break;
+
+	case 8:
+		camdiv |= S3C2440_CAMDIVN_HCLK4_HALF;
+	case 4:
+		clkdiv |= S3C2440_CLKDIVN_HDIVN_4_8;
+		break;
+
+	default:
+		BUG();	/* we don't expect to get here. */
+	}
+
+	if (cfg->divs.p_divisor != cfg->divs.h_divisor)
+		clkdiv |= S3C2440_CLKDIVN_PDIVN;
+
+	/* todo - set pclk. */
+
+	/* Write the divisors first with hclk intentionally halved so that
+	 * when we write clkdiv we will under-frequency instead of over. We
+	 * then make a short delay and remove the hclk halving if necessary.
+	 */
+
+	__raw_writel(camdiv | CAMDIVN_HCLK_HALF, S3C2440_CAMDIVN);
+	__raw_writel(clkdiv, S3C2410_CLKDIVN);
+
+	ndelay(20);
+	__raw_writel(camdiv, S3C2440_CAMDIVN);
+
+	clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk);
+}
+
+static int run_freq_for(unsigned long max_hclk, unsigned long fclk,
+			int *divs,
+			struct cpufreq_frequency_table *table,
+			size_t table_size)
+{
+	unsigned long freq;
+	int index = 0;
+	int div;
+
+	for (div = *divs; div > 0; div = *divs++) {
+		freq = fclk / div;
+
+		if (freq > max_hclk && div != 1)
+			continue;
+
+		freq /= 1000; /* table is in kHz */
+		index = s3c_cpufreq_addfreq(table, index, table_size, freq);
+		if (index < 0)
+			break;
+	}
+
+	return index;
+}
+
+static int hclk_divs[] = { 1, 2, 3, 4, 6, 8, -1 };
+
+static int s3c2440_cpufreq_calctable(struct s3c_cpufreq_config *cfg,
+				     struct cpufreq_frequency_table *table,
+				     size_t table_size)
+{
+	int ret;
+
+	WARN_ON(cfg->info == NULL);
+	WARN_ON(cfg->board == NULL);
+
+	ret = run_freq_for(cfg->info->max.hclk,
+			   cfg->info->max.fclk,
+			   hclk_divs,
+			   table, table_size);
+
+	s3c_freq_dbg("%s: returning %d\n", __func__, ret);
+
+	return ret;
+}
+
+struct s3c_cpufreq_info s3c2440_cpufreq_info = {
+	.max		= {
+		.fclk	= 400000000,
+		.hclk	= 133333333,
+		.pclk	=  66666666,
+	},
+
+	.locktime_m	= 300,
+	.locktime_u	= 300,
+	.locktime_bits	= 16,
+
+	.name		= "s3c244x",
+	.calc_iotiming	= s3c2410_iotiming_calc,
+	.set_iotiming	= s3c2410_iotiming_set,
+	.get_iotiming	= s3c2410_iotiming_get,
+	.set_fvco	= s3c2410_set_fvco,
+
+	.set_refresh	= s3c2410_cpufreq_setrefresh,
+	.set_divs	= s3c2440_cpufreq_setdivs,
+	.calc_divs	= s3c2440_cpufreq_calcdivs,
+	.calc_freqtable	= s3c2440_cpufreq_calctable,
+
+	.resume_clocks	= s3c244x_setup_clocks,
+
+	.debug_io_show  = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
+};
+
+static int s3c2440_cpufreq_add(struct sys_device *sysdev)
+{
+	xtal = s3c_cpufreq_clk_get(NULL, "xtal");
+	hclk = s3c_cpufreq_clk_get(NULL, "hclk");
+	fclk = s3c_cpufreq_clk_get(NULL, "fclk");
+	armclk = s3c_cpufreq_clk_get(NULL, "armclk");
+
+	if (IS_ERR(xtal) || IS_ERR(hclk) || IS_ERR(fclk) || IS_ERR(armclk)) {
+		printk(KERN_ERR "%s: failed to get clocks\n", __func__);
+		return -ENOENT;
+	}
+
+	return s3c_cpufreq_register(&s3c2440_cpufreq_info);
+}
+
+static struct sysdev_driver s3c2440_cpufreq_driver = {
+	.add		= s3c2440_cpufreq_add,
+};
+
+static int s3c2440_cpufreq_init(void)
+{
+	return sysdev_driver_register(&s3c2440_sysclass,
+				      &s3c2440_cpufreq_driver);
+}
+
+/* arch_initcall adds the clocks we need, so use subsys_initcall. */
+subsys_initcall(s3c2440_cpufreq_init);
+
+static struct sysdev_driver s3c2442_cpufreq_driver = {
+	.add		= s3c2440_cpufreq_add,
+};
+
+static int s3c2442_cpufreq_init(void)
+{
+	return sysdev_driver_register(&s3c2442_sysclass,
+				      &s3c2442_cpufreq_driver);
+}
+
+subsys_initcall(s3c2442_cpufreq_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,97 @@
+/* arch/arm/mach-s3c2440/s3c2440-pll-12000000.c
+ *
+ * Copyright (c) 2006-2007 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	Vincent Sanders <vince@arm.linux.org.uk>
+ *
+ * S3C2440/S3C2442 CPU PLL tables (12MHz Crystal)
+ *
+ * This program is free software; you can 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/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+
+static struct cpufreq_frequency_table s3c2440_plls_12[] __initdata = {
+	{ .frequency = 75000000,	.index = PLLVAL(0x75, 3, 3),  }, 	/* FVco 600.000000 */
+	{ .frequency = 80000000,	.index = PLLVAL(0x98, 4, 3),  }, 	/* FVco 640.000000 */
+	{ .frequency = 90000000,	.index = PLLVAL(0x70, 2, 3),  }, 	/* FVco 720.000000 */
+	{ .frequency = 100000000,	.index = PLLVAL(0x5c, 1, 3),  }, 	/* FVco 800.000000 */
+	{ .frequency = 110000000,	.index = PLLVAL(0x66, 1, 3),  }, 	/* FVco 880.000000 */
+	{ .frequency = 120000000,	.index = PLLVAL(0x70, 1, 3),  }, 	/* FVco 960.000000 */
+	{ .frequency = 150000000,	.index = PLLVAL(0x75, 3, 2),  }, 	/* FVco 600.000000 */
+	{ .frequency = 160000000,	.index = PLLVAL(0x98, 4, 2),  }, 	/* FVco 640.000000 */
+	{ .frequency = 170000000,	.index = PLLVAL(0x4d, 1, 2),  }, 	/* FVco 680.000000 */
+	{ .frequency = 180000000,	.index = PLLVAL(0x70, 2, 2),  }, 	/* FVco 720.000000 */
+	{ .frequency = 190000000,	.index = PLLVAL(0x57, 1, 2),  }, 	/* FVco 760.000000 */
+	{ .frequency = 200000000,	.index = PLLVAL(0x5c, 1, 2),  }, 	/* FVco 800.000000 */
+	{ .frequency = 210000000,	.index = PLLVAL(0x84, 2, 2),  }, 	/* FVco 840.000000 */
+	{ .frequency = 220000000,	.index = PLLVAL(0x66, 1, 2),  }, 	/* FVco 880.000000 */
+	{ .frequency = 230000000,	.index = PLLVAL(0x6b, 1, 2),  }, 	/* FVco 920.000000 */
+	{ .frequency = 240000000,	.index = PLLVAL(0x70, 1, 2),  }, 	/* FVco 960.000000 */
+	{ .frequency = 300000000,	.index = PLLVAL(0x75, 3, 1),  }, 	/* FVco 600.000000 */
+	{ .frequency = 310000000,	.index = PLLVAL(0x93, 4, 1),  }, 	/* FVco 620.000000 */
+	{ .frequency = 320000000,	.index = PLLVAL(0x98, 4, 1),  }, 	/* FVco 640.000000 */
+	{ .frequency = 330000000,	.index = PLLVAL(0x66, 2, 1),  }, 	/* FVco 660.000000 */
+	{ .frequency = 340000000,	.index = PLLVAL(0x4d, 1, 1),  }, 	/* FVco 680.000000 */
+	{ .frequency = 350000000,	.index = PLLVAL(0xa7, 4, 1),  }, 	/* FVco 700.000000 */
+	{ .frequency = 360000000,	.index = PLLVAL(0x70, 2, 1),  }, 	/* FVco 720.000000 */
+	{ .frequency = 370000000,	.index = PLLVAL(0xb1, 4, 1),  }, 	/* FVco 740.000000 */
+	{ .frequency = 380000000,	.index = PLLVAL(0x57, 1, 1),  }, 	/* FVco 760.000000 */
+	{ .frequency = 390000000,	.index = PLLVAL(0x7a, 2, 1),  }, 	/* FVco 780.000000 */
+	{ .frequency = 400000000,	.index = PLLVAL(0x5c, 1, 1),  }, 	/* FVco 800.000000 */
+};
+
+static int s3c2440_plls12_add(struct sys_device *dev)
+{
+	struct clk *xtal_clk;
+	unsigned long xtal;
+
+	xtal_clk = clk_get(NULL, "xtal");
+	if (IS_ERR(xtal_clk))
+		return PTR_ERR(xtal_clk);
+
+	xtal = clk_get_rate(xtal_clk);
+	clk_put(xtal_clk);
+
+	if (xtal == 12000000) {
+		printk(KERN_INFO "Using PLL table for 12MHz crystal\n");
+		return s3c_plltab_register(s3c2440_plls_12,
+					   ARRAY_SIZE(s3c2440_plls_12));
+	}
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2440_plls12_drv = {
+	.add	= s3c2440_plls12_add,
+};
+
+static int __init s3c2440_pll_12mhz(void)
+{
+	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_plls12_drv);
+
+}
+
+arch_initcall(s3c2440_pll_12mhz);
+
+static struct sysdev_driver s3c2442_plls12_drv = {
+	.add	= s3c2440_plls12_add,
+};
+
+static int __init s3c2442_pll_12mhz(void)
+{
+	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_plls12_drv);
+
+}
+
+arch_initcall(s3c2442_pll_12mhz);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,127 @@
+/* arch/arm/mach-s3c2440/s3c2440-pll-16934400.c
+ *
+ * Copyright (c) 2006-2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	Vincent Sanders <vince@arm.linux.org.uk>
+ *
+ * S3C2440/S3C2442 CPU PLL tables (16.93444MHz Crystal)
+ *
+ * This program is free software; you can 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/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+
+static struct cpufreq_frequency_table s3c2440_plls_169344[] __initdata = {
+	{ .frequency = 78019200,	.index = PLLVAL(121, 5, 3), 	}, 	/* FVco 624.153600 */
+	{ .frequency = 84067200,	.index = PLLVAL(131, 5, 3), 	}, 	/* FVco 672.537600 */
+	{ .frequency = 90115200,	.index = PLLVAL(141, 5, 3), 	}, 	/* FVco 720.921600 */
+	{ .frequency = 96163200,	.index = PLLVAL(151, 5, 3), 	}, 	/* FVco 769.305600 */
+	{ .frequency = 102135600,	.index = PLLVAL(185, 6, 3), 	}, 	/* FVco 817.084800 */
+	{ .frequency = 108259200,	.index = PLLVAL(171, 5, 3), 	}, 	/* FVco 866.073600 */
+	{ .frequency = 114307200,	.index = PLLVAL(127, 3, 3), 	}, 	/* FVco 914.457600 */
+	{ .frequency = 120234240,	.index = PLLVAL(134, 3, 3), 	}, 	/* FVco 961.873920 */
+	{ .frequency = 126161280,	.index = PLLVAL(141, 3, 3), 	}, 	/* FVco 1009.290240 */
+	{ .frequency = 132088320,	.index = PLLVAL(148, 3, 3), 	}, 	/* FVco 1056.706560 */
+	{ .frequency = 138015360,	.index = PLLVAL(155, 3, 3), 	}, 	/* FVco 1104.122880 */
+	{ .frequency = 144789120,	.index = PLLVAL(163, 3, 3), 	}, 	/* FVco 1158.312960 */
+	{ .frequency = 150100363,	.index = PLLVAL(187, 9, 2), 	}, 	/* FVco 600.401454 */
+	{ .frequency = 156038400,	.index = PLLVAL(121, 5, 2), 	}, 	/* FVco 624.153600 */
+	{ .frequency = 162086400,	.index = PLLVAL(126, 5, 2), 	}, 	/* FVco 648.345600 */
+	{ .frequency = 168134400,	.index = PLLVAL(131, 5, 2), 	}, 	/* FVco 672.537600 */
+	{ .frequency = 174048000,	.index = PLLVAL(177, 7, 2), 	}, 	/* FVco 696.192000 */
+	{ .frequency = 180230400,	.index = PLLVAL(141, 5, 2), 	}, 	/* FVco 720.921600 */
+	{ .frequency = 186278400,	.index = PLLVAL(124, 4, 2), 	}, 	/* FVco 745.113600 */
+	{ .frequency = 192326400,	.index = PLLVAL(151, 5, 2), 	}, 	/* FVco 769.305600 */
+	{ .frequency = 198132480,	.index = PLLVAL(109, 3, 2), 	}, 	/* FVco 792.529920 */
+	{ .frequency = 204271200,	.index = PLLVAL(185, 6, 2), 	}, 	/* FVco 817.084800 */
+	{ .frequency = 210268800,	.index = PLLVAL(141, 4, 2), 	}, 	/* FVco 841.075200 */
+	{ .frequency = 216518400,	.index = PLLVAL(171, 5, 2), 	}, 	/* FVco 866.073600 */
+	{ .frequency = 222264000,	.index = PLLVAL(97, 2, 2), 	}, 	/* FVco 889.056000 */
+	{ .frequency = 228614400,	.index = PLLVAL(127, 3, 2), 	}, 	/* FVco 914.457600 */
+	{ .frequency = 234259200,	.index = PLLVAL(158, 4, 2), 	}, 	/* FVco 937.036800 */
+	{ .frequency = 240468480,	.index = PLLVAL(134, 3, 2), 	}, 	/* FVco 961.873920 */
+	{ .frequency = 246960000,	.index = PLLVAL(167, 4, 2), 	}, 	/* FVco 987.840000 */
+	{ .frequency = 252322560,	.index = PLLVAL(141, 3, 2), 	}, 	/* FVco 1009.290240 */
+	{ .frequency = 258249600,	.index = PLLVAL(114, 2, 2), 	}, 	/* FVco 1032.998400 */
+	{ .frequency = 264176640,	.index = PLLVAL(148, 3, 2), 	}, 	/* FVco 1056.706560 */
+	{ .frequency = 270950400,	.index = PLLVAL(120, 2, 2), 	}, 	/* FVco 1083.801600 */
+	{ .frequency = 276030720,	.index = PLLVAL(155, 3, 2), 	}, 	/* FVco 1104.122880 */
+	{ .frequency = 282240000,	.index = PLLVAL(92, 1, 2), 	}, 	/* FVco 1128.960000 */
+	{ .frequency = 289578240,	.index = PLLVAL(163, 3, 2), 	}, 	/* FVco 1158.312960 */
+	{ .frequency = 294235200,	.index = PLLVAL(131, 2, 2), 	}, 	/* FVco 1176.940800 */
+	{ .frequency = 300200727,	.index = PLLVAL(187, 9, 1), 	}, 	/* FVco 600.401454 */
+	{ .frequency = 306358690,	.index = PLLVAL(191, 9, 1), 	}, 	/* FVco 612.717380 */
+	{ .frequency = 312076800,	.index = PLLVAL(121, 5, 1), 	}, 	/* FVco 624.153600 */
+	{ .frequency = 318366720,	.index = PLLVAL(86, 3, 1), 	}, 	/* FVco 636.733440 */
+	{ .frequency = 324172800,	.index = PLLVAL(126, 5, 1), 	}, 	/* FVco 648.345600 */
+	{ .frequency = 330220800,	.index = PLLVAL(109, 4, 1), 	}, 	/* FVco 660.441600 */
+	{ .frequency = 336268800,	.index = PLLVAL(131, 5, 1), 	}, 	/* FVco 672.537600 */
+	{ .frequency = 342074880,	.index = PLLVAL(93, 3, 1), 	}, 	/* FVco 684.149760 */
+	{ .frequency = 348096000,	.index = PLLVAL(177, 7, 1), 	}, 	/* FVco 696.192000 */
+	{ .frequency = 355622400,	.index = PLLVAL(118, 4, 1), 	}, 	/* FVco 711.244800 */
+	{ .frequency = 360460800,	.index = PLLVAL(141, 5, 1), 	}, 	/* FVco 720.921600 */
+	{ .frequency = 366206400,	.index = PLLVAL(165, 6, 1), 	}, 	/* FVco 732.412800 */
+	{ .frequency = 372556800,	.index = PLLVAL(124, 4, 1), 	}, 	/* FVco 745.113600 */
+	{ .frequency = 378201600,	.index = PLLVAL(126, 4, 1), 	}, 	/* FVco 756.403200 */
+	{ .frequency = 384652800,	.index = PLLVAL(151, 5, 1), 	}, 	/* FVco 769.305600 */
+	{ .frequency = 391608000,	.index = PLLVAL(177, 6, 1), 	}, 	/* FVco 783.216000 */
+	{ .frequency = 396264960,	.index = PLLVAL(109, 3, 1), 	}, 	/* FVco 792.529920 */
+	{ .frequency = 402192000,	.index = PLLVAL(87, 2, 1), 	}, 	/* FVco 804.384000 */
+};
+
+static int s3c2440_plls169344_add(struct sys_device *dev)
+{
+	struct clk *xtal_clk;
+	unsigned long xtal;
+
+	xtal_clk = clk_get(NULL, "xtal");
+	if (IS_ERR(xtal_clk))
+		return PTR_ERR(xtal_clk);
+
+	xtal = clk_get_rate(xtal_clk);
+	clk_put(xtal_clk);
+
+	if (xtal == 169344000) {
+		printk(KERN_INFO "Using PLL table for 16.9344MHz crystal\n");
+		return s3c_plltab_register(s3c2440_plls_169344,
+					   ARRAY_SIZE(s3c2440_plls_169344));
+	}
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2440_plls169344_drv = {
+	.add	= s3c2440_plls169344_add,
+};
+
+static int __init s3c2440_pll_16934400(void)
+{
+	return sysdev_driver_register(&s3c2440_sysclass,
+				      &s3c2440_plls169344_drv);
+
+}
+
+arch_initcall(s3c2440_pll_16934400);
+
+static struct sysdev_driver s3c2442_plls169344_drv = {
+	.add	= s3c2440_plls169344_add,
+};
+
+static int __init s3c2442_pll_16934400(void)
+{
+	return sysdev_driver_register(&s3c2442_sysclass,
+				      &s3c2442_plls169344_drv);
+
+}
+
+arch_initcall(s3c2442_pll_16934400);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c2442.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c2442.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c2442.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c2442.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,165 @@
+/* linux/arch/arm/mach-s3c2442/s3c2442.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2442 core and lock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+/* S3C2442 extended clock support */
+
+static unsigned long s3c2442_camif_upll_round(struct clk *clk,
+					      unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	int div;
+
+	if (rate > parent_rate)
+		return parent_rate;
+
+	div = parent_rate / rate;
+
+	if (div == 3)
+		return parent_rate / 3;
+
+	/* note, we remove the +/- 1 calculations for the divisor */
+
+	div /= 2;
+
+	if (div < 1)
+		div = 1;
+	else if (div > 16)
+		div = 16;
+
+	return parent_rate / (div * 2);
+}
+
+static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
+
+	rate = s3c2442_camif_upll_round(clk, rate);
+
+	camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
+
+	if (rate == parent_rate) {
+		camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
+	} else if ((parent_rate / rate) == 3) {
+		camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+		camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
+	} else {
+		camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
+		camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+		camdivn |= (((parent_rate / rate) / 2) - 1);
+	}
+
+	__raw_writel(camdivn, S3C2440_CAMDIVN);
+
+	return 0;
+}
+
+/* Extra S3C2442 clocks */
+
+static struct clk s3c2442_clk_cam = {
+	.name		= "camif",
+	.id		= -1,
+	.enable		= s3c2410_clkcon_enable,
+	.ctrlbit	= S3C2440_CLKCON_CAMERA,
+};
+
+static struct clk s3c2442_clk_cam_upll = {
+	.name		= "camif-upll",
+	.id		= -1,
+	.ops		= &(struct clk_ops) {
+		.set_rate	= s3c2442_camif_upll_setrate,
+		.round_rate	= s3c2442_camif_upll_round,
+	},
+};
+
+static int s3c2442_clk_add(struct sys_device *sysdev)
+{
+	struct clk *clock_upll;
+	struct clk *clock_h;
+	struct clk *clock_p;
+
+	clock_p = clk_get(NULL, "pclk");
+	clock_h = clk_get(NULL, "hclk");
+	clock_upll = clk_get(NULL, "upll");
+
+	if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
+		printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
+		return -EINVAL;
+	}
+
+	s3c2442_clk_cam.parent = clock_h;
+	s3c2442_clk_cam_upll.parent = clock_upll;
+
+	s3c24xx_register_clock(&s3c2442_clk_cam);
+	s3c24xx_register_clock(&s3c2442_clk_cam_upll);
+
+	clk_disable(&s3c2442_clk_cam);
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2442_clk_driver = {
+	.add	= s3c2442_clk_add,
+};
+
+static __init int s3c2442_clk_init(void)
+{
+	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
+}
+
+arch_initcall(s3c2442_clk_init);
+
+
+static struct sys_device s3c2442_sysdev = {
+	.cls		= &s3c2442_sysclass,
+};
+
+int __init s3c2442_init(void)
+{
+	printk("S3C2442: Initialising architecture\n");
+
+	return sysdev_register(&s3c2442_sysdev);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c244x.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c244x.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c244x.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c244x.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,195 @@
+/* linux/arch/arm/plat-s3c24xx/s3c244x.c
+ *
+ * Copyright (c) 2004-2006 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2440 and S3C2442 Mobile CPU support (not S3C2443)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+
+#include <mach/regs-clock.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/regs-dsc.h>
+
+#include <plat/s3c2410.h>
+#include <plat/s3c244x.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/pll.h>
+
+static struct map_desc s3c244x_iodesc[] __initdata = {
+	IODESC_ENT(CLKPWR),
+	IODESC_ENT(TIMER),
+	IODESC_ENT(WATCHDOG),
+};
+
+/* uart initialisation */
+
+void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+	s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+}
+
+void __init s3c244x_map_io(void)
+{
+	/* register our io-tables */
+
+	iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
+
+	/* rename any peripherals used differing from the s3c2410 */
+
+	s3c_device_sdi.name  = "s3c2440-sdi";
+	s3c_device_i2c0.name  = "s3c2440-i2c";
+	s3c_device_nand.name = "s3c2440-nand";
+	s3c_device_ts.name = "s3c2440-ts";
+	s3c_device_usbgadget.name = "s3c2440-usbgadget";
+}
+
+void __init_or_cpufreq s3c244x_setup_clocks(void)
+{
+	struct clk *xtal_clk;
+	unsigned long clkdiv;
+	unsigned long camdiv;
+	unsigned long xtal;
+	unsigned long hclk, fclk, pclk;
+	int hdiv = 1;
+
+	xtal_clk = clk_get(NULL, "xtal");
+	xtal = clk_get_rate(xtal_clk);
+	clk_put(xtal_clk);
+
+	fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
+
+	clkdiv = __raw_readl(S3C2410_CLKDIVN);
+	camdiv = __raw_readl(S3C2440_CAMDIVN);
+
+	/* work out clock scalings */
+
+	switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
+	case S3C2440_CLKDIVN_HDIVN_1:
+		hdiv = 1;
+		break;
+
+	case S3C2440_CLKDIVN_HDIVN_2:
+		hdiv = 2;
+		break;
+
+	case S3C2440_CLKDIVN_HDIVN_4_8:
+		hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
+		break;
+
+	case S3C2440_CLKDIVN_HDIVN_3_6:
+		hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
+		break;
+	}
+
+	hclk = fclk / hdiv;
+	pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2 : 1);
+
+	/* print brief summary of clocks, etc */
+
+	printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
+	       print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
+
+	s3c24xx_setup_clocks(fclk, hclk, pclk);
+}
+
+void __init s3c244x_init_clocks(int xtal)
+{
+	/* initialise the clocks here, to allow other things like the
+	 * console to use them, and to add new ones after the initialisation
+	 */
+
+	s3c24xx_register_baseclocks(xtal);
+	s3c244x_setup_clocks();
+	s3c2410_baseclk_add();
+}
+
+#ifdef CONFIG_PM
+
+static struct sleep_save s3c244x_sleep[] = {
+	SAVE_ITEM(S3C2440_DSC0),
+	SAVE_ITEM(S3C2440_DSC1),
+	SAVE_ITEM(S3C2440_GPJDAT),
+	SAVE_ITEM(S3C2440_GPJCON),
+	SAVE_ITEM(S3C2440_GPJUP)
+};
+
+static int s3c244x_suspend(struct sys_device *dev, pm_message_t state)
+{
+	s3c_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+	return 0;
+}
+
+static int s3c244x_resume(struct sys_device *dev)
+{
+	s3c_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+	return 0;
+}
+
+#else
+#define s3c244x_suspend NULL
+#define s3c244x_resume  NULL
+#endif
+
+/* Since the S3C2442 and S3C2440 share  items, put both sysclasses here */
+
+struct sysdev_class s3c2440_sysclass = {
+	.name		= "s3c2440-core",
+	.suspend	= s3c244x_suspend,
+	.resume		= s3c244x_resume
+};
+
+struct sysdev_class s3c2442_sysclass = {
+	.name		= "s3c2442-core",
+	.suspend	= s3c244x_suspend,
+	.resume		= s3c244x_resume
+};
+
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2440 based system)
+ * as a driver which may support both 2410 and 2440 may try and use it.
+*/
+
+static int __init s3c2440_core_init(void)
+{
+	return sysdev_class_register(&s3c2440_sysclass);
+}
+
+core_initcall(s3c2440_core_init);
+
+static int __init s3c2442_core_init(void)
+{
+	return sysdev_class_register(&s3c2442_sysclass);
+}
+
+core_initcall(s3c2442_core_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c244x-clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c244x-clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c244x-clock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c244x-clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,138 @@
+/* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c
+ *
+ * Copyright (c) 2004-2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2440/S3C2442 Common clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent)
+{
+	unsigned long camdivn;
+	unsigned long dvs;
+
+	if (parent == &clk_f)
+		dvs = 0;
+	else if (parent == &clk_h)
+		dvs = S3C2440_CAMDIVN_DVSEN;
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	camdivn  = __raw_readl(S3C2440_CAMDIVN);
+	camdivn &= ~S3C2440_CAMDIVN_DVSEN;
+	camdivn |= dvs;
+	__raw_writel(camdivn, S3C2440_CAMDIVN);
+
+	return 0;
+}
+
+static struct clk clk_arm = {
+	.name		= "armclk",
+	.id		= -1,
+	.ops		= &(struct clk_ops) {
+		.set_parent	= s3c2440_setparent_armclk,
+	},
+};
+
+static int s3c244x_clk_add(struct sys_device *sysdev)
+{
+	unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
+	unsigned long clkdivn;
+	struct clk *clock_upll;
+	int ret;
+
+	printk("S3C244X: Clock Support, DVS %s\n",
+	       (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
+
+	clk_arm.parent = (camdivn & S3C2440_CAMDIVN_DVSEN) ? &clk_h : &clk_f;
+
+	ret = s3c24xx_register_clock(&clk_arm);
+	if (ret < 0) {
+		printk(KERN_ERR "S3C24XX: Failed to add armclk (%d)\n", ret);
+		return ret;
+	}
+
+	clock_upll = clk_get(NULL, "upll");
+	if (IS_ERR(clock_upll)) {
+		printk(KERN_ERR "S3C244X: Failed to get upll clock\n");
+		return -ENOENT;
+	}
+
+	/* check rate of UPLL, and if it is near 96MHz, then change
+	 * to using half the UPLL rate for the system */
+
+	if (clk_get_rate(clock_upll) > (94 * MHZ)) {
+		clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
+
+		spin_lock(&clocks_lock);
+
+		clkdivn = __raw_readl(S3C2410_CLKDIVN);
+		clkdivn |= S3C2440_CLKDIVN_UCLK;
+		__raw_writel(clkdivn, S3C2410_CLKDIVN);
+
+		spin_unlock(&clocks_lock);
+	}
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2440_clk_driver = {
+	.add		= s3c244x_clk_add,
+};
+
+static int s3c2440_clk_init(void)
+{
+	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver);
+}
+
+arch_initcall(s3c2440_clk_init);
+
+static struct sysdev_driver s3c2442_clk_driver = {
+	.add		= s3c244x_clk_add,
+};
+
+static int s3c2442_clk_init(void)
+{
+	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
+}
+
+arch_initcall(s3c2442_clk_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c244x-irq.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c244x-irq.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/s3c244x-irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2440/s3c244x-irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,142 @@
+/* linux/arch/arm/plat-s3c24xx/s3c244x-irq.c
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ *	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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/module.h>
+#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 <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+/* camera irq */
+
+static void s3c_irq_demux_cam(unsigned int irq,
+			      struct irq_desc *desc)
+{
+	unsigned int subsrc, submsk;
+
+	/* read the current pending interrupts, and the mask
+	 * for what it is available */
+
+	subsrc = __raw_readl(S3C2410_SUBSRCPND);
+	submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+	subsrc &= ~submsk;
+	subsrc >>= 11;
+	subsrc &= 3;
+
+	if (subsrc != 0) {
+		if (subsrc & 1) {
+			generic_handle_irq(IRQ_S3C2440_CAM_C);
+		}
+		if (subsrc & 2) {
+			generic_handle_irq(IRQ_S3C2440_CAM_P);
+		}
+	}
+}
+
+#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
+
+static void
+s3c_irq_cam_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
+}
+
+static void
+s3c_irq_cam_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_CAM);
+}
+
+static void
+s3c_irq_cam_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
+}
+
+static struct irq_chip s3c_irq_cam = {
+	.mask	    = s3c_irq_cam_mask,
+	.unmask	    = s3c_irq_cam_unmask,
+	.ack	    = s3c_irq_cam_ack,
+};
+
+static int s3c244x_irq_add(struct sys_device *sysdev)
+{
+	unsigned int irqno;
+
+	set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
+	set_irq_handler(IRQ_NFCON, handle_level_irq);
+	set_irq_flags(IRQ_NFCON, IRQF_VALID);
+
+	/* add chained handler for camera */
+
+	set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
+	set_irq_handler(IRQ_CAM, handle_level_irq);
+	set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
+
+	for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
+		set_irq_chip(irqno, &s3c_irq_cam);
+		set_irq_handler(irqno, handle_level_irq);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2440_irq_driver = {
+	.add		= s3c244x_irq_add,
+	.suspend	= s3c24xx_irq_suspend,
+	.resume		= s3c24xx_irq_resume,
+};
+
+static int s3c2440_irq_init(void)
+{
+	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
+}
+
+arch_initcall(s3c2440_irq_init);
+
+static struct sysdev_driver s3c2442_irq_driver = {
+	.add		= s3c244x_irq_add,
+	.suspend	= s3c24xx_irq_suspend,
+	.resume		= s3c24xx_irq_resume,
+};
+
+
+static int s3c2442_irq_init(void)
+{
+	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_irq_driver);
+}
+
+arch_initcall(s3c2442_irq_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2442/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2442/clock.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,151 +0,0 @@
-/* linux/arch/arm/mach-s3c2442/clock.c
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2442 Clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You 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/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/sysdev.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/mutex.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/atomic.h>
-#include <asm/irq.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-/* S3C2442 extended clock support */
-
-static unsigned long s3c2442_camif_upll_round(struct clk *clk,
-					      unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	int div;
-
-	if (rate > parent_rate)
-		return parent_rate;
-
-	div = parent_rate / rate;
-
-	if (div == 3)
-		return parent_rate / 3;
-
-	/* note, we remove the +/- 1 calculations for the divisor */
-
-	div /= 2;
-
-	if (div < 1)
-		div = 1;
-	else if (div > 16)
-		div = 16;
-
-	return parent_rate / (div * 2);
-}
-
-static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
-
-	rate = s3c2442_camif_upll_round(clk, rate);
-
-	camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
-
-	if (rate == parent_rate) {
-		camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
-	} else if ((parent_rate / rate) == 3) {
-		camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
-		camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
-	} else {
-		camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
-		camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
-		camdivn |= (((parent_rate / rate) / 2) - 1);
-	}
-
-	__raw_writel(camdivn, S3C2440_CAMDIVN);
-
-	return 0;
-}
-
-/* Extra S3C2442 clocks */
-
-static struct clk s3c2442_clk_cam = {
-	.name		= "camif",
-	.id		= -1,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2440_CLKCON_CAMERA,
-};
-
-static struct clk s3c2442_clk_cam_upll = {
-	.name		= "camif-upll",
-	.id		= -1,
-	.set_rate	= s3c2442_camif_upll_setrate,
-	.round_rate	= s3c2442_camif_upll_round,
-};
-
-static int s3c2442_clk_add(struct sys_device *sysdev)
-{
-	struct clk *clock_upll;
-	struct clk *clock_h;
-	struct clk *clock_p;
-
-	clock_p = clk_get(NULL, "pclk");
-	clock_h = clk_get(NULL, "hclk");
-	clock_upll = clk_get(NULL, "upll");
-
-	if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
-		printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
-		return -EINVAL;
-	}
-
-	s3c2442_clk_cam.parent = clock_h;
-	s3c2442_clk_cam_upll.parent = clock_upll;
-
-	s3c24xx_register_clock(&s3c2442_clk_cam);
-	s3c24xx_register_clock(&s3c2442_clk_cam_upll);
-
-	clk_disable(&s3c2442_clk_cam);
-
-	return 0;
-}
-
-static struct sysdev_driver s3c2442_clk_driver = {
-	.add	= s3c2442_clk_add,
-};
-
-static __init int s3c2442_clk_init(void)
-{
-	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
-}
-
-arch_initcall(s3c2442_clk_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/include/mach/gta02.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2442/include/mach/gta02.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/include/mach/gta02.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2442/include/mach/gta02.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,84 +0,0 @@
-#ifndef _GTA02_H
-#define _GTA02_H
-
-#include <mach/regs-gpio.h>
-
-/* Different hardware revisions, passed in ATAG_REVISION by u-boot */
-#define GTA02v1_SYSTEM_REV	0x00000310
-#define GTA02v2_SYSTEM_REV	0x00000320
-#define GTA02v3_SYSTEM_REV	0x00000330
-#define GTA02v4_SYSTEM_REV	0x00000340
-#define GTA02v5_SYSTEM_REV	0x00000350
-/* since A7 is basically same as A6, we use A6 PCB ID */
-#define GTA02v6_SYSTEM_REV	0x00000360
-
-#define GTA02_GPIO_n3DL_GSM	S3C2410_GPA(13)	/* v1 + v2 + v3 only */
-
-#define GTA02_GPIO_PWR_LED1	S3C2410_GPB(0)
-#define GTA02_GPIO_PWR_LED2	S3C2410_GPB(1)
-#define GTA02_GPIO_AUX_LED	S3C2410_GPB(2)
-#define GTA02_GPIO_VIBRATOR_ON	S3C2410_GPB(3)
-#define GTA02_GPIO_MODEM_RST	S3C2410_GPB(5)
-#define GTA02_GPIO_BT_EN	S3C2410_GPB(6)
-#define GTA02_GPIO_MODEM_ON	S3C2410_GPB(7)
-#define GTA02_GPIO_EXTINT8	S3C2410_GPB(8)
-#define GTA02_GPIO_USB_PULLUP	S3C2410_GPB(9)
-
-#define GTA02_GPIO_PIO5		S3C2410_GPC(5)	/* v3 + v4 only */
-
-#define GTA02v3_GPIO_nG1_CS	S3C2410_GPD(12)	/* v3 + v4 only */
-#define GTA02v3_GPIO_nG2_CS	S3C2410_GPD(13)	/* v3 + v4 only */
-#define GTA02v5_GPIO_HDQ	S3C2410_GPD(14)   /* v5 + */
-
-#define GTA02_GPIO_nG1_INT	S3C2410_GPF(0)
-#define GTA02_GPIO_IO1		S3C2410_GPF(1)
-#define GTA02_GPIO_PIO_2	S3C2410_GPF(2)	/* v2 + v3 + v4 only */
-#define GTA02_GPIO_JACK_INSERT	S3C2410_GPF(4)
-#define GTA02_GPIO_WLAN_GPIO1	S3C2410_GPF(5)	/* v2 + v3 + v4 only */
-#define GTA02_GPIO_AUX_KEY	S3C2410_GPF(6)
-#define GTA02_GPIO_HOLD_KEY	S3C2410_GPF(7)
-
-#define GTA02_GPIO_3D_IRQ	S3C2410_GPG(4)
-#define GTA02v2_GPIO_nG2_INT	S3C2410_GPG(8)	/* v2 + v3 + v4 only */
-#define GTA02v3_GPIO_nUSB_OC	S3C2410_GPG(9)	/* v3 + v4 only */
-#define GTA02v3_GPIO_nUSB_FLT	S3C2410_GPG(10)	/* v3 + v4 only */
-#define GTA02v3_GPIO_nGSM_OC	S3C2410_GPG(11)	/* v3 + v4 only */
-
-#define GTA02_GPIO_AMP_SHUT	S3C2440_GPJ1	/* v2 + v3 + v4 only */
-#define GTA02v1_GPIO_WLAN_GPIO10	S3C2440_GPJ2
-#define GTA02_GPIO_HP_IN	S3C2440_GPJ2	/* v2 + v3 + v4 only */
-#define GTA02_GPIO_INT0		S3C2440_GPJ3	/* v2 + v3 + v4 only */
-#define GTA02_GPIO_nGSM_EN	S3C2440_GPJ4
-#define GTA02_GPIO_3D_RESET	S3C2440_GPJ5
-#define GTA02_GPIO_nDL_GSM	S3C2440_GPJ6	/* v4 + v5 only */
-#define GTA02_GPIO_WLAN_GPIO0	S3C2440_GPJ7
-#define GTA02v1_GPIO_BAT_ID	S3C2440_GPJ8
-#define GTA02_GPIO_KEEPACT	S3C2440_GPJ8
-#define GTA02v1_GPIO_HP_IN	S3C2440_GPJ10
-#define GTA02_CHIP_PWD		S3C2440_GPJ11	/* v2 + v3 + v4 only */
-#define GTA02_GPIO_nWLAN_RESET	S3C2440_GPJ12	/* v2 + v3 + v4 only */
-
-#define GTA02_IRQ_GSENSOR_1	IRQ_EINT0
-#define GTA02_IRQ_MODEM		IRQ_EINT1
-#define GTA02_IRQ_PIO_2		IRQ_EINT2	/* v2 + v3 + v4 only */
-#define GTA02_IRQ_nJACK_INSERT	IRQ_EINT4
-#define GTA02_IRQ_WLAN_GPIO1	IRQ_EINT5
-#define GTA02_IRQ_AUX		IRQ_EINT6
-#define GTA02_IRQ_nHOLD		IRQ_EINT7
-#define GTA02_IRQ_PCF50633	IRQ_EINT9
-#define GTA02_IRQ_3D		IRQ_EINT12
-#define GTA02_IRQ_GSENSOR_2	IRQ_EINT16	/* v2 + v3 + v4 only */
-#define GTA02v3_IRQ_nUSB_OC	IRQ_EINT17	/* v3 + v4 only */
-#define GTA02v3_IRQ_nUSB_FLT	IRQ_EINT18	/* v3 + v4 only */
-#define GTA02v3_IRQ_nGSM_OC	IRQ_EINT19	/* v3 + v4 only */
-
-/* returns 00 000 on GTA02 A5 and earlier, A6 returns 01 001 */
-#define GTA02_PCB_ID1_0		S3C2410_GPC(13)
-#define GTA02_PCB_ID1_1		S3C2410_GPC(15)
-#define GTA02_PCB_ID1_2		S3C2410_GPD(0)
-#define GTA02_PCB_ID2_0		S3C2410_GPD(3)
-#define GTA02_PCB_ID2_1		S3C2410_GPD(4)
-
-int gta02_get_pcb_revision(void);
-
-#endif /* _GTA02_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2442/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2442/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-# Copyright 2007 Simtec Electronics
-#
-# Licensed under GPLv2
-
-config CPU_S3C2442
-	bool
-	depends on ARCH_S3C2410
-	select CPU_ARM920T
-	select S3C2410_CLOCK
-	select S3C2410_GPIO
-	select S3C2410_PM if PM
-	select CPU_S3C244X
-	select CPU_LLSERIAL_S3C2440
-	help
-	  Support for S3C2442 Samsung Mobile CPU based systems.
-
-
-menu "S3C2442 Machines"
-
-config SMDK2440_CPU2442
-	bool "SMDM2440 with S3C2442 CPU module"
-	depends on ARCH_S3C2440
-	select CPU_S3C2442
-
-config MACH_NEO1973_GTA02
-	bool "Openmoko GTA02 / Freerunner phone"
-	select CPU_S3C2442
-	select MFD_PCF50633
-	select PCF50633_GPIO
-	select I2C
-	select POWER_SUPPLY
-	select MACH_NEO1973
-	select S3C2410_PWM
-	help
-	   Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone
-
-endmenu
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/mach-gta02.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2442/mach-gta02.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/mach-gta02.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2442/mach-gta02.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,648 +0,0 @@
-/*
- * linux/arch/arm/mach-s3c2442/mach-gta02.c
- *
- * S3C2442 Machine Support for Openmoko GTA02 / FreeRunner.
- *
- * Copyright (C) 2006-2009 by Openmoko, Inc.
- * Authors: Harald Welte <laforge@openmoko.org>
- *          Andy Green <andy@openmoko.org>
- *          Werner Almesberger <werner@openmoko.org>
- * 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 <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/spi/spi.h>
-
-#include <linux/mmc/host.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <linux/io.h>
-
-#include <linux/i2c.h>
-#include <linux/backlight.h>
-#include <linux/regulator/machine.h>
-
-#include <linux/mfd/pcf50633/core.h>
-#include <linux/mfd/pcf50633/mbc.h>
-#include <linux/mfd/pcf50633/adc.h>
-#include <linux/mfd/pcf50633/gpio.h>
-#include <linux/mfd/pcf50633/pmic.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-gpioj.h>
-#include <mach/fb.h>
-
-#include <mach/spi.h>
-#include <mach/spi-gpio.h>
-#include <plat/usb-control.h>
-#include <mach/regs-mem.h>
-#include <mach/hardware.h>
-
-#include <mach/gta02.h>
-
-#include <plat/regs-serial.h>
-#include <plat/nand.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/udc.h>
-#include <plat/gpio-cfg.h>
-#include <plat/iic.h>
-
-static struct pcf50633 *gta02_pcf;
-
-/*
- * This gets called every 1ms when we paniced.
- */
-
-static long gta02_panic_blink(long count)
-{
-	long delay = 0;
-	static long last_blink;
-	static char led;
-
-	/* Fast blink: 200ms period. */
-	if (count - last_blink < 100)
-		return 0;
-
-	led ^= 1;
-	gpio_direction_output(GTA02_GPIO_AUX_LED, led);
-
-	last_blink = count;
-
-	return delay;
-}
-
-
-static struct map_desc gta02_iodesc[] __initdata = {
-	{
-		.virtual	= 0xe0000000,
-		.pfn		= __phys_to_pfn(S3C2410_CS3 + 0x01000000),
-		.length		= SZ_1M,
-		.type		= MT_DEVICE
-	},
-};
-
-#define UCON (S3C2410_UCON_DEFAULT | S3C2443_UCON_RXERR_IRQEN)
-#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
-#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
-
-static struct s3c2410_uartcfg gta02_uartcfgs[] = {
-	[0] = {
-		.hwport		= 0,
-		.flags		= 0,
-		.ucon		= UCON,
-		.ulcon		= ULCON,
-		.ufcon		= UFCON,
-	},
-	[1] = {
-		.hwport		= 1,
-		.flags		= 0,
-		.ucon		= UCON,
-		.ulcon		= ULCON,
-		.ufcon		= UFCON,
-	},
-	[2] = {
-		.hwport		= 2,
-		.flags		= 0,
-		.ucon		= UCON,
-		.ulcon		= ULCON,
-		.ufcon		= UFCON,
-	},
-};
-
-#ifdef CONFIG_CHARGER_PCF50633
-/*
- * On GTA02 the 1A charger features a 48K resistor to 0V on the ID pin.
- * We use this to recognize that we can pull 1A from the USB socket.
- *
- * These constants are the measured pcf50633 ADC levels with the 1A
- * charger / 48K resistor, and with no pulldown resistor.
- */
-
-#define ADC_NOM_CHG_DETECT_1A 6
-#define ADC_NOM_CHG_DETECT_USB 43
-
-static void
-gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
-{
-	int  ma;
-
-	/* Interpret charger type */
-	if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) {
-
-		/*
-		 * Sanity - stop GPO driving out now that we have a 1A charger
-		 * GPO controls USB Host power generation on GTA02
-		 */
-		pcf50633_gpio_set(pcf, PCF50633_GPO, 0);
-
-		ma = 1000;
-	} else
-		ma = 100;
-
-	pcf50633_mbc_usb_curlim_set(pcf, ma);
-}
-
-static struct delayed_work gta02_charger_work;
-static int gta02_usb_vbus_draw;
-
-static void gta02_charger_worker(struct work_struct *work)
-{
-	if (gta02_usb_vbus_draw) {
-		pcf50633_mbc_usb_curlim_set(gta02_pcf, gta02_usb_vbus_draw);
-		return;
-	}
-
-#ifdef CONFIG_PCF50633_ADC
-	pcf50633_adc_async_read(gta02_pcf,
-				PCF50633_ADCC1_MUX_ADCIN1,
-				PCF50633_ADCC1_AVERAGE_16,
-				gta02_configure_pmu_for_charger,
-				NULL);
-#else
-	/*
-	 * If the PCF50633 ADC is disabled we fallback to a
-	 * 100mA limit for safety.
-	 */
-	pcf50633_mbc_usb_curlim_set(pcf, 100);
-#endif
-}
-
-#define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000)
-
-static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq)
-{
-	if (irq == PCF50633_IRQ_USBINS) {
-		schedule_delayed_work(&gta02_charger_work,
-				      GTA02_CHARGER_CONFIGURE_TIMEOUT);
-
-		return;
-	}
-
-	if (irq == PCF50633_IRQ_USBREM) {
-		cancel_delayed_work_sync(&gta02_charger_work);
-		gta02_usb_vbus_draw = 0;
-	}
-}
-
-static void gta02_udc_vbus_draw(unsigned int ma)
-{
-	if (!gta02_pcf)
-		return;
-
-	gta02_usb_vbus_draw = ma;
-
-	schedule_delayed_work(&gta02_charger_work,
-			      GTA02_CHARGER_CONFIGURE_TIMEOUT);
-}
-#else /* !CONFIG_CHARGER_PCF50633 */
-#define gta02_pmu_event_callback	NULL
-#define gta02_udc_vbus_draw		NULL
-#endif
-
-/*
- * This is called when pc50633 is probed, unfortunately quite late in the
- * day since it is an I2C bus device. Here we can belatedly define some
- * platform devices with the advantage that we can mark the pcf50633 as the
- * parent. This makes them get suspended and resumed with their parent
- * the pcf50633 still around.
- */
-
-static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf);
-
-
-static char *gta02_batteries[] = {
-	"battery",
-};
-
-struct pcf50633_platform_data gta02_pcf_pdata = {
-	.resumers = {
-		[0] =	PCF50633_INT1_USBINS |
-			PCF50633_INT1_USBREM |
-			PCF50633_INT1_ALARM,
-		[1] =	PCF50633_INT2_ONKEYF,
-		[2] =	PCF50633_INT3_ONKEY1S,
-		[3] =	PCF50633_INT4_LOWSYS |
-			PCF50633_INT4_LOWBAT |
-			PCF50633_INT4_HIGHTMP,
-	},
-
-	.batteries = gta02_batteries,
-	.num_batteries = ARRAY_SIZE(gta02_batteries),
-
-	.charger_reference_current_ma = 1000,
-
-	.reg_init_data = {
-		[PCF50633_REGULATOR_AUTO] = {
-			.constraints = {
-				.min_uV = 3300000,
-				.max_uV = 3300000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.always_on = 1,
-				.apply_uV = 1,
-				.state_mem = {
-					.enabled = 1,
-				},
-			},
-		},
-		[PCF50633_REGULATOR_DOWN1] = {
-			.constraints = {
-				.min_uV = 1300000,
-				.max_uV = 1600000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.always_on = 1,
-				.apply_uV = 1,
-			},
-		},
-		[PCF50633_REGULATOR_DOWN2] = {
-			.constraints = {
-				.min_uV = 1800000,
-				.max_uV = 1800000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.apply_uV = 1,
-				.always_on = 1,
-				.state_mem = {
-					.enabled = 1,
-				},
-			},
-		},
-		[PCF50633_REGULATOR_HCLDO] = {
-			.constraints = {
-				.min_uV = 2000000,
-				.max_uV = 3300000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
-				.always_on = 1,
-			},
-		},
-		[PCF50633_REGULATOR_LDO1] = {
-			.constraints = {
-				.min_uV = 3300000,
-				.max_uV = 3300000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.apply_uV = 1,
-				.state_mem = {
-					.enabled = 0,
-				},
-			},
-		},
-		[PCF50633_REGULATOR_LDO2] = {
-			.constraints = {
-				.min_uV = 3300000,
-				.max_uV = 3300000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.apply_uV = 1,
-			},
-		},
-		[PCF50633_REGULATOR_LDO3] = {
-			.constraints = {
-				.min_uV = 3000000,
-				.max_uV = 3000000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.apply_uV = 1,
-			},
-		},
-		[PCF50633_REGULATOR_LDO4] = {
-			.constraints = {
-				.min_uV = 3200000,
-				.max_uV = 3200000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.apply_uV = 1,
-			},
-		},
-		[PCF50633_REGULATOR_LDO5] = {
-			.constraints = {
-				.min_uV = 3000000,
-				.max_uV = 3000000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.apply_uV = 1,
-				.state_mem = {
-					.enabled = 1,
-				},
-			},
-		},
-		[PCF50633_REGULATOR_LDO6] = {
-			.constraints = {
-				.min_uV = 3000000,
-				.max_uV = 3000000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-			},
-		},
-		[PCF50633_REGULATOR_MEMLDO] = {
-			.constraints = {
-				.min_uV = 1800000,
-				.max_uV = 1800000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.state_mem = {
-					.enabled = 1,
-				},
-			},
-		},
-
-	},
-	.probe_done = gta02_pmu_attach_child_devices,
-	.mbc_event_callback = gta02_pmu_event_callback,
-};
-
-
-/* NOR Flash. */
-
-#define GTA02_FLASH_BASE	0x18000000 /* GCS3 */
-#define GTA02_FLASH_SIZE	0x200000 /* 2MBytes */
-
-static struct physmap_flash_data gta02_nor_flash_data = {
-	.width		= 2,
-};
-
-static struct resource gta02_nor_flash_resource = {
-	.start		= GTA02_FLASH_BASE,
-	.end		= GTA02_FLASH_BASE + GTA02_FLASH_SIZE - 1,
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device gta02_nor_flash = {
-	.name		= "physmap-flash",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &gta02_nor_flash_data,
-	},
-	.resource	= &gta02_nor_flash_resource,
-	.num_resources	= 1,
-};
-
-
-struct platform_device s3c24xx_pwm_device = {
-	.name		= "s3c24xx_pwm",
-	.num_resources	= 0,
-};
-
-static struct i2c_board_info gta02_i2c_devs[] __initdata = {
-	{
-		I2C_BOARD_INFO("pcf50633", 0x73),
-		.irq = GTA02_IRQ_PCF50633,
-		.platform_data = &gta02_pcf_pdata,
-	},
-	{
-		I2C_BOARD_INFO("wm8753", 0x1a),
-	},
-};
-
-static struct s3c2410_nand_set __initdata gta02_nand_sets[] = {
-	[0] = {
-		/*
-		 * This name is also hard-coded in the boot loaders, so
-		 * changing it would would require all users to upgrade
-		 * their boot loaders, some of which are stored in a NOR
-		 * that is considered to be immutable.
-		 */
-		.name		= "neo1973-nand",
-		.nr_chips	= 1,
-		.flash_bbt	= 1,
-	},
-};
-
-/*
- * Choose a set of timings derived from S3C@2442B MCP54
- * data sheet (K5D2G13ACM-D075 MCP Memory).
- */
-
-static struct s3c2410_platform_nand __initdata gta02_nand_info = {
-	.tacls		= 0,
-	.twrph0		= 25,
-	.twrph1		= 15,
-	.nr_sets	= ARRAY_SIZE(gta02_nand_sets),
-	.sets		= gta02_nand_sets,
-};
-
-
-static void gta02_udc_command(enum s3c2410_udc_cmd_e cmd)
-{
-	switch (cmd) {
-	case S3C2410_UDC_P_ENABLE:
-		pr_debug("%s S3C2410_UDC_P_ENABLE\n", __func__);
-		gpio_direction_output(GTA02_GPIO_USB_PULLUP, 1);
-		break;
-	case S3C2410_UDC_P_DISABLE:
-		pr_debug("%s S3C2410_UDC_P_DISABLE\n", __func__);
-		gpio_direction_output(GTA02_GPIO_USB_PULLUP, 0);
-		break;
-	case S3C2410_UDC_P_RESET:
-		pr_debug("%s S3C2410_UDC_P_RESET\n", __func__);
-		/* FIXME: Do something here. */
-	}
-}
-
-/* Get PMU to set USB current limit accordingly. */
-static struct s3c2410_udc_mach_info gta02_udc_cfg = {
-	.vbus_draw	= gta02_udc_vbus_draw,
-	.udc_command	= gta02_udc_command,
-
-};
-
-
-
-static void gta02_bl_set_intensity(int intensity)
-{
-	struct pcf50633 *pcf = gta02_pcf;
-	int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
-
-	/* We map 8-bit intensity to 6-bit intensity in hardware. */
-	intensity >>= 2;
-
-	/*
-	 * This can happen during, eg, print of panic on blanked console,
-	 * but we can't service i2c without interrupts active, so abort.
-	 */
-	if (in_atomic()) {
-		printk(KERN_ERR "gta02_bl_set_intensity called while atomic\n");
-		return;
-	}
-
-	old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
-	if (intensity == old_intensity)
-		return;
-
-	/* We can't do this anywhere else. */
-	pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 5);
-
-	if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 3))
-		old_intensity = 0;
-
-	/*
-	 * The PCF50633 cannot handle LEDOUT = 0 (datasheet p60)
-	 * if seen, you have to re-enable the LED unit.
-	 */
-	if (!intensity || !old_intensity)
-		pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0);
-
-	/* Illegal to set LEDOUT to 0. */
-	if (!intensity)
-		pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, 2);
-	else
-		pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f,
-					  intensity);
-
-	if (intensity)
-		pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 2);
-
-}
-
-static struct generic_bl_info gta02_bl_info = {
-	.name			= "gta02-bl",
-	.max_intensity		= 0xff,
-	.default_intensity	= 0xff,
-	.set_bl_intensity	= gta02_bl_set_intensity,
-};
-
-static struct platform_device gta02_bl_dev = {
-	.name			= "generic-bl",
-	.id			= 1,
-	.dev = {
-		.platform_data = &gta02_bl_info,
-	},
-};
-
-
-
-/* USB */
-static struct s3c2410_hcd_info gta02_usb_info = {
-	.port[0]	= {
-		.flags	= S3C_HCDFLG_USED,
-	},
-	.port[1]	= {
-		.flags	= 0,
-	},
-};
-
-
-static void __init gta02_map_io(void)
-{
-	s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
-	s3c24xx_init_clocks(12000000);
-	s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
-}
-
-
-/* These are the guys that don't need to be children of PMU. */
-
-static struct platform_device *gta02_devices[] __initdata = {
-	&s3c_device_usb,
-	&s3c_device_wdt,
-	&s3c_device_sdi,
-	&s3c_device_usbgadget,
-	&s3c_device_nand,
-	&gta02_nor_flash,
-	&s3c24xx_pwm_device,
-	&s3c_device_iis,
-	&s3c_device_i2c0,
-};
-
-/* These guys DO need to be children of PMU. */
-
-static struct platform_device *gta02_devices_pmu_children[] = {
-	&gta02_bl_dev,
-};
-
-
-/*
- * This is called when pc50633 is probed, quite late in the day since it is an
- * I2C bus device.  Here we can define platform devices with the advantage that
- * we can mark the pcf50633 as the parent.  This makes them get suspended and
- * resumed with their parent the pcf50633 still around.  All devices whose
- * operation depends on something from pcf50633 must have this relationship
- * made explicit like this, or suspend and resume will become an unreliable
- * hellworld.
- */
-
-static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
-{
-	int n;
-
-	/* Grab a copy of the now probed PMU pointer. */
-	gta02_pcf = pcf;
-
-	for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++)
-		gta02_devices_pmu_children[n]->dev.parent = pcf->dev;
-
-	platform_add_devices(gta02_devices_pmu_children,
-			     ARRAY_SIZE(gta02_devices_pmu_children));
-}
-
-static void gta02_poweroff(void)
-{
-	pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
-}
-
-static void __init gta02_machine_init(void)
-{
-	/* Set the panic callback to make AUX LED blink at ~5Hz. */
-	panic_blink = gta02_panic_blink;
-
-	s3c_pm_init();
-
-#ifdef CONFIG_CHARGER_PCF50633
-	INIT_DELAYED_WORK(&gta02_charger_work, gta02_charger_worker);
-#endif
-
-	s3c_device_usb.dev.platform_data = &gta02_usb_info;
-
-	s3c24xx_udc_set_platdata(&gta02_udc_cfg);
-	s3c_nand_set_platdata(&gta02_nand_info);
-	s3c_i2c0_set_platdata(NULL);
-
-	i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
-
-	platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
-	pm_power_off = gta02_poweroff;
-}
-
-
-MACHINE_START(NEO1973_GTA02, "GTA02")
-	/* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
-	.phys_io	= S3C2410_PA_UART,
-	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
-	.boot_params	= S3C2410_SDRAM_PA + 0x100,
-	.map_io		= gta02_map_io,
-	.init_irq	= s3c24xx_init_irq,
-	.init_machine	= gta02_machine_init,
-	.timer		= &s3c24xx_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2442/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2442/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,18 +0,0 @@
-# arch/arm/mach-s3c2442/Makefile
-#
-# Copyright 2007 Simtec Electronics
-#
-# Licensed under GPLv2
-
-obj-y				:=
-obj-m				:=
-obj-n				:=
-obj-				:=
-
-obj-$(CONFIG_CPU_S3C2442)	+= s3c2442.o
-obj-$(CONFIG_CPU_S3C2442)	+= clock.o
-
-obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o
-
-# Machine support
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/s3c2442.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2442/s3c2442.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/s3c2442.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2442/s3c2442.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,34 +0,0 @@
-/* linux/arch/arm/mach-s3c2442/s3c2442.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C2442 Mobile CPU support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/sysdev.h>
-
-#include <plat/s3c2442.h>
-#include <plat/cpu.h>
-
-static struct sys_device s3c2442_sysdev = {
-	.cls		= &s3c2442_sysclass,
-};
-
-int __init s3c2442_init(void)
-{
-	printk("S3C2442: Initialising architecture\n");
-
-	return sysdev_register(&s3c2442_sysdev);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2443/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2443/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2443/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2443/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2443/clock.c
  *
- * Copyright (c) 2007 Simtec Electronics
+ * Copyright (c) 2007, 2010 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2443 Clock control support
@@ -42,6 +42,7 @@
 
 #include <plat/s3c2443.h>
 #include <plat/clock.h>
+#include <plat/clock-clksrc.h>
 #include <plat/cpu.h>
 
 /* We currently have to assume that the system is running
@@ -53,141 +54,69 @@
  * set the correct muxing at initialisation
 */
 
-static int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
-{
-	unsigned int clocks = clk->ctrlbit;
-	unsigned long clkcon;
-
-	clkcon = __raw_readl(S3C2443_HCLKCON);
-
-	if (enable)
-		clkcon |= clocks;
-	else
-		clkcon &= ~clocks;
-
-	__raw_writel(clkcon, S3C2443_HCLKCON);
-
-	return 0;
-}
-
-static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
-{
-	unsigned int clocks = clk->ctrlbit;
-	unsigned long clkcon;
-
-	clkcon = __raw_readl(S3C2443_PCLKCON);
-
-	if (enable)
-		clkcon |= clocks;
-	else
-		clkcon &= ~clocks;
-
-	__raw_writel(clkcon, S3C2443_PCLKCON);
-
-	return 0;
-}
-
-static int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
+static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
 {
-	unsigned int clocks = clk->ctrlbit;
-	unsigned long clkcon;
-
-	clkcon = __raw_readl(S3C2443_SCLKCON);
+	u32 ctrlbit = clk->ctrlbit;
+	u32 con = __raw_readl(reg);
 
 	if (enable)
-		clkcon |= clocks;
+		con |= ctrlbit;
 	else
-		clkcon &= ~clocks;
-
-	__raw_writel(clkcon, S3C2443_SCLKCON);
+		con &= ~ctrlbit;
 
+	__raw_writel(con, reg);
 	return 0;
 }
 
-static unsigned long s3c2443_roundrate_clksrc(struct clk *clk,
-					      unsigned long rate,
-					      unsigned int max)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	int div;
-
-	if (rate > parent_rate)
-		return parent_rate;
-
-	/* note, we remove the +/- 1 calculations as they cancel out */
-
-	div = (rate / parent_rate);
-
-	if (div < 1)
-		div = 1;
-	else if (div > max)
-		div = max;
-
-	return parent_rate / div;
-}
-
-static unsigned long s3c2443_roundrate_clksrc4(struct clk *clk,
-					       unsigned long rate)
+static int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
 {
-	return s3c2443_roundrate_clksrc(clk, rate, 4);
+	return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
 }
 
-static unsigned long s3c2443_roundrate_clksrc16(struct clk *clk,
-						unsigned long rate)
+static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
 {
-	return s3c2443_roundrate_clksrc(clk, rate, 16);
+	return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
 }
 
-static unsigned long s3c2443_roundrate_clksrc256(struct clk *clk,
-						 unsigned long rate)
+static int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
 {
-	return s3c2443_roundrate_clksrc(clk, rate, 256);
+	return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
 }
 
 /* clock selections */
 
+/* mpllref is a direct descendant of clk_xtal by default, but it is not
+ * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
+ * such directly equating the two source clocks is impossible.
+ */
 static struct clk clk_mpllref = {
 	.name		= "mpllref",
 	.parent		= &clk_xtal,
 	.id		= -1,
 };
 
-#if 0
-static struct clk clk_mpll = {
-	.name		= "mpll",
-	.parent		= &clk_mpllref,
-	.id		= -1,
-};
-#endif
-
 static struct clk clk_i2s_ext = {
 	.name		= "i2s-ext",
 	.id		= -1,
 };
 
-static int s3c2443_setparent_epllref(struct clk *clk, struct clk *parent)
-{
-	unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
-
-	clksrc &= ~S3C2443_CLKSRC_EPLLREF_MASK;
-
-	if (parent == &clk_xtal)
-		clksrc |= S3C2443_CLKSRC_EPLLREF_XTAL;
-	else if (parent == &clk_ext)
-		clksrc |= S3C2443_CLKSRC_EPLLREF_EXTCLK;
-	else if (parent != &clk_mpllref)
-		return -EINVAL;
-
-	__raw_writel(clksrc, S3C2443_CLKSRC);
-	clk->parent = parent;
-
-	return 0;
-}
+static struct clk *clk_epllref_sources[] = {
+	[0] = &clk_mpllref,
+	[1] = &clk_mpllref,
+	[2] = &clk_xtal,
+	[3] = &clk_ext,
+};
 
-static struct clk clk_epllref = {
-	.name		= "epllref",
-	.id		= -1,
-	.set_parent	= s3c2443_setparent_epllref,
+static struct clksrc_clk clk_epllref = {
+	.clk	= {
+		.name		= "epllref",
+		.id		= -1,
+	},
+	.sources = &(struct clksrc_sources) {
+		.sources = clk_epllref_sources,
+		.nr_sources = ARRAY_SIZE(clk_epllref_sources),
+	},
+	.reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
 };
 
 static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
@@ -205,34 +134,29 @@ static struct clk clk_mdivclk = {
 	.name		= "mdivclk",
 	.parent		= &clk_mpllref,
 	.id		= -1,
-	.get_rate	= s3c2443_getrate_mdivclk,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2443_getrate_mdivclk,
+	},
 };
 
-static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent)
-{
-	unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
-
-	clksrc &= ~(S3C2443_CLKSRC_MSYSCLK_MPLL |
-		    S3C2443_CLKSRC_EXTCLK_DIV);
-
-	if (parent == &clk_mpll)
-		clksrc |= S3C2443_CLKSRC_MSYSCLK_MPLL;
-	else if (parent == &clk_mdivclk)
-		clksrc |= S3C2443_CLKSRC_EXTCLK_DIV;
-	else if (parent != &clk_mpllref)
-		return -EINVAL;
-
-	__raw_writel(clksrc, S3C2443_CLKSRC);
-	clk->parent = parent;
-
-	return 0;
-}
+static struct clk *clk_msysclk_sources[] = {
+	[0] = &clk_mpllref,
+	[1] = &clk_mpll,
+	[2] = &clk_mdivclk,
+	[3] = &clk_mpllref,
+};
 
-static struct clk clk_msysclk = {
-	.name		= "msysclk",
-	.parent		= &clk_xtal,
-	.id		= -1,
-	.set_parent	= s3c2443_setparent_msysclk,
+static struct clksrc_clk clk_msysclk = {
+	.clk	= {
+		.name		= "msysclk",
+		.parent		= &clk_xtal,
+		.id		= -1,
+	},
+	.sources = &(struct clksrc_sources) {
+		.sources = clk_msysclk_sources,
+		.nr_sources = ARRAY_SIZE(clk_msysclk_sources),
+	},
+	.reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
 };
 
 /* armdiv
@@ -241,152 +165,159 @@ static struct clk clk_msysclk = {
  * divider values applied to it to then be fed into armclk.
 */
 
-static struct clk clk_armdiv = {
-	.name		= "armdiv",
-	.id		= -1,
-	.parent		= &clk_msysclk,
-};
+/* armdiv divisor table */
 
-/* armclk
- *
- * this is the clock fed into the ARM core itself, either from
- * armdiv or from hclk.
- */
+static unsigned int armdiv[16] = {
+	[S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 1,
+	[S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 2,
+	[S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 3,
+	[S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 4,
+	[S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 6,
+	[S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 8,
+	[S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 12,
+	[S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 16,
+};
 
-static int s3c2443_setparent_armclk(struct clk *clk, struct clk *parent)
+static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
 {
-	unsigned long clkdiv0;
-
-	clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
-
-	if (parent == &clk_armdiv)
-		clkdiv0 &= ~S3C2443_CLKDIV0_DVS;
-	else if (parent == &clk_h)
-		clkdiv0 |= S3C2443_CLKDIV0_DVS;
-	else
-		return -EINVAL;
+	clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
 
-	__raw_writel(clkdiv0, S3C2443_CLKDIV0);
-	return 0;
+	return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
 }
 
-static struct clk clk_arm = {
-	.name		= "armclk",
-	.id		= -1,
-	.set_parent	= s3c2443_setparent_armclk,
-};
+static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
+					      unsigned long rate)
+{
+	unsigned long parent = clk_get_rate(clk->parent);
+	unsigned long calc;
+	unsigned best = 256; /* bigger than any value */
+	unsigned div;
+	int ptr;
 
-/* esysclk
- *
- * this is sourced from either the EPLL or the EPLLref clock
-*/
+	for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) {
+		div = armdiv[ptr];
+		calc = parent / div;
+		if (calc <= rate && div < best)
+			best = div;
+	}
 
-static int s3c2443_setparent_esysclk(struct clk *clk, struct clk *parent)
+	return parent / best;
+}
+
+static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
 {
-	unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+	unsigned long parent = clk_get_rate(clk->parent);
+	unsigned long calc;
+	unsigned div;
+	unsigned best = 256; /* bigger than any value */
+	int ptr;
+	int val = -1;
 
-	if (parent == &clk_epll)
-		clksrc |= S3C2443_CLKSRC_ESYSCLK_EPLL;
-	else if (parent == &clk_epllref)
-		clksrc &= ~S3C2443_CLKSRC_ESYSCLK_EPLL;
-	else
-		return -EINVAL;
+	for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) {
+		div = armdiv[ptr];
+		calc = parent / div;
+		if (calc <= rate && div < best) {
+			best = div;
+			val = ptr;
+		}
+	}
 
-	__raw_writel(clksrc, S3C2443_CLKSRC);
-	clk->parent = parent;
+	if (val >= 0) {
+		unsigned long clkcon0;
 
-	return 0;
+		clkcon0 = __raw_readl(S3C2443_CLKDIV0);
+		clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
+		clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
+		__raw_writel(clkcon0, S3C2443_CLKDIV0);
+	}
+
+	return (val == -1) ? -EINVAL : 0;
 }
 
-static struct clk clk_esysclk = {
-	.name		= "esysclk",
-	.parent		= &clk_epll,
+static struct clk clk_armdiv = {
+	.name		= "armdiv",
 	.id		= -1,
-	.set_parent	= s3c2443_setparent_esysclk,
+	.parent		= &clk_msysclk.clk,
+	.ops		= &(struct clk_ops) {
+		.round_rate = s3c2443_armclk_roundrate,
+		.set_rate = s3c2443_armclk_setrate,
+	},
 };
 
-/* uartclk
+/* armclk
  *
- * UART baud-rate clock sourced from esysclk via a divisor
-*/
-
-static unsigned long s3c2443_getrate_uart(struct clk *clk)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
-
-	div &= S3C2443_CLKDIV1_UARTDIV_MASK;
-	div >>= S3C2443_CLKDIV1_UARTDIV_SHIFT;
+ * this is the clock fed into the ARM core itself, from armdiv or from hclk.
+ */
 
-	return parent_rate / (div + 1);
-}
+static struct clk *clk_arm_sources[] = {
+	[0] = &clk_armdiv,
+	[1] = &clk_h,
+};
 
+static struct clksrc_clk clk_arm = {
+	.clk	= {
+		.name		= "armclk",
+		.id		= -1,
+	},
+	.sources = &(struct clksrc_sources) {
+		.sources = clk_arm_sources,
+		.nr_sources = ARRAY_SIZE(clk_arm_sources),
+	},
+	.reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
+};
 
-static int s3c2443_setrate_uart(struct clk *clk, unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+/* esysclk
+ *
+ * this is sourced from either the EPLL or the EPLLref clock
+*/
 
-	rate = s3c2443_roundrate_clksrc16(clk, rate);
-	rate = parent_rate / rate;
+static struct clk *clk_sysclk_sources[] = {
+	[0] = &clk_epllref.clk,
+	[1] = &clk_epll,
+};
 
-	clkdivn &= ~S3C2443_CLKDIV1_UARTDIV_MASK;
-	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_UARTDIV_SHIFT;
+static struct clksrc_clk clk_esysclk = {
+	.clk	= {
+		.name		= "esysclk",
+		.parent		= &clk_epll,
+		.id		= -1,
+	},
+	.sources = &(struct clksrc_sources) {
+		.sources = clk_sysclk_sources,
+		.nr_sources = ARRAY_SIZE(clk_sysclk_sources),
+	},
+	.reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
+};
 
-	__raw_writel(clkdivn, S3C2443_CLKDIV1);
-	return 0;
-}
+/* uartclk
+ *
+ * UART baud-rate clock sourced from esysclk via a divisor
+*/
 
-static struct clk clk_uart = {
-	.name		= "uartclk",
-	.id		= -1,
-	.parent		= &clk_esysclk,
-	.get_rate	= s3c2443_getrate_uart,
-	.set_rate	= s3c2443_setrate_uart,
-	.round_rate	= s3c2443_roundrate_clksrc16,
+static struct clksrc_clk clk_uart = {
+	.clk	= {
+		.name		= "uartclk",
+		.id		= -1,
+		.parent		= &clk_esysclk.clk,
+	},
+	.reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
 };
 
+
 /* hsspi
  *
  * high-speed spi clock, sourced from esysclk
 */
 
-static unsigned long s3c2443_getrate_hsspi(struct clk *clk)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
-
-	div &= S3C2443_CLKDIV1_HSSPIDIV_MASK;
-	div >>= S3C2443_CLKDIV1_HSSPIDIV_SHIFT;
-
-	return parent_rate / (div + 1);
-}
-
-
-static int s3c2443_setrate_hsspi(struct clk *clk, unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
-
-	rate = s3c2443_roundrate_clksrc4(clk, rate);
-	rate = parent_rate / rate;
-
-	clkdivn &= ~S3C2443_CLKDIV1_HSSPIDIV_MASK;
-	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_HSSPIDIV_SHIFT;
-
-	__raw_writel(clkdivn, S3C2443_CLKDIV1);
-	return 0;
-}
-
-static struct clk clk_hsspi = {
-	.name		= "hsspi",
-	.id		= -1,
-	.parent		= &clk_esysclk,
-	.ctrlbit	= S3C2443_SCLKCON_HSSPICLK,
-	.enable		= s3c2443_clkcon_enable_s,
-	.get_rate	= s3c2443_getrate_hsspi,
-	.set_rate	= s3c2443_setrate_hsspi,
-	.round_rate	= s3c2443_roundrate_clksrc4,
+static struct clksrc_clk clk_hsspi = {
+	.clk	= {
+		.name		= "hsspi",
+		.id		= -1,
+		.parent		= &clk_esysclk.clk,
+		.ctrlbit	= S3C2443_SCLKCON_HSSPICLK,
+		.enable		= s3c2443_clkcon_enable_s,
+	},
+	.reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
 };
 
 /* usbhost
@@ -394,41 +325,15 @@ static struct clk clk_hsspi = {
  * usb host bus-clock, usually 48MHz to provide USB bus clock timing
 */
 
-static unsigned long s3c2443_getrate_usbhost(struct clk *clk)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
-
-	div &= S3C2443_CLKDIV1_USBHOSTDIV_MASK;
-	div >>= S3C2443_CLKDIV1_USBHOSTDIV_SHIFT;
-
-	return parent_rate / (div + 1);
-}
-
-static int s3c2443_setrate_usbhost(struct clk *clk, unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
-
-	rate = s3c2443_roundrate_clksrc4(clk, rate);
-	rate = parent_rate / rate;
-
-	clkdivn &= ~S3C2443_CLKDIV1_USBHOSTDIV_MASK;
-	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_USBHOSTDIV_SHIFT;
-
-	__raw_writel(clkdivn, S3C2443_CLKDIV1);
-	return 0;
-}
-
-static struct clk clk_usb_bus_host = {
-	.name		= "usb-bus-host-parent",
-	.id		= -1,
-	.parent		= &clk_esysclk,
-	.ctrlbit	= S3C2443_SCLKCON_USBHOST,
-	.enable		= s3c2443_clkcon_enable_s,
-	.get_rate	= s3c2443_getrate_usbhost,
-	.set_rate	= s3c2443_setrate_usbhost,
-	.round_rate	= s3c2443_roundrate_clksrc4,
+static struct clksrc_clk clk_usb_bus_host = {
+	.clk	= {
+		.name		= "usb-bus-host-parent",
+		.id		= -1,
+		.parent		= &clk_esysclk.clk,
+		.ctrlbit	= S3C2443_SCLKCON_USBHOST,
+		.enable		= s3c2443_clkcon_enable_s,
+	},
+	.reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
 };
 
 /* clk_hsmcc_div
@@ -438,39 +343,13 @@ static struct clk clk_usb_bus_host = {
  * be fed to the hsmmc block
 */
 
-static unsigned long s3c2443_getrate_hsmmc_div(struct clk *clk)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
-
-	div &= S3C2443_CLKDIV1_HSMMCDIV_MASK;
-	div >>= S3C2443_CLKDIV1_HSMMCDIV_SHIFT;
-
-	return parent_rate / (div + 1);
-}
-
-static int s3c2443_setrate_hsmmc_div(struct clk *clk, unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
-
-	rate = s3c2443_roundrate_clksrc4(clk, rate);
-	rate = parent_rate / rate;
-
-	clkdivn &= ~S3C2443_CLKDIV1_HSMMCDIV_MASK;
-	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_HSMMCDIV_SHIFT;
-
-	__raw_writel(clkdivn, S3C2443_CLKDIV1);
-	return 0;
-}
-
-static struct clk clk_hsmmc_div = {
-	.name		= "hsmmc-div",
-	.id		= -1,
-	.parent		= &clk_esysclk,
-	.get_rate	= s3c2443_getrate_hsmmc_div,
-	.set_rate	= s3c2443_setrate_hsmmc_div,
-	.round_rate	= s3c2443_roundrate_clksrc4,
+static struct clksrc_clk clk_hsmmc_div = {
+	.clk	= {
+		.name		= "hsmmc-div",
+		.id		= -1,
+		.parent		= &clk_esysclk.clk,
+	},
+	.reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
 };
 
 static int s3c2443_setparent_hsmmc(struct clk *clk, struct clk *parent)
@@ -503,82 +382,55 @@ static int s3c2443_enable_hsmmc(struct c
 static struct clk clk_hsmmc = {
 	.name		= "hsmmc-if",
 	.id		= -1,
-	.parent		= &clk_hsmmc_div,
+	.parent		= &clk_hsmmc_div.clk,
 	.enable		= s3c2443_enable_hsmmc,
-	.set_parent	= s3c2443_setparent_hsmmc,
+	.ops		= &(struct clk_ops) {
+		.set_parent	= s3c2443_setparent_hsmmc,
+	},
 };
 
 /* i2s_eplldiv
  *
- * this clock is the output from the i2s divisor of esysclk
+ * This clock is the output from the I2S divisor of ESYSCLK, and is seperate
+ * from the mux that comes after it (cannot merge into one single clock)
 */
 
-static unsigned long s3c2443_getrate_i2s_eplldiv(struct clk *clk)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
-
-	div &= S3C2443_CLKDIV1_I2SDIV_MASK;
-	div >>= S3C2443_CLKDIV1_I2SDIV_SHIFT;
-
-	return parent_rate / (div + 1);
-}
-
-static int s3c2443_setrate_i2s_eplldiv(struct clk *clk, unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
-
-	rate = s3c2443_roundrate_clksrc16(clk, rate);
-	rate = parent_rate / rate;
-
-	clkdivn &= ~S3C2443_CLKDIV1_I2SDIV_MASK;
-	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_I2SDIV_SHIFT;
-
-	__raw_writel(clkdivn, S3C2443_CLKDIV1);
-	return 0;
-}
-
-static struct clk clk_i2s_eplldiv = {
-	.name		= "i2s-eplldiv",
-	.id		= -1,
-	.parent		= &clk_esysclk,
-	.get_rate	= s3c2443_getrate_i2s_eplldiv,
-	.set_rate	= s3c2443_setrate_i2s_eplldiv,
-	.round_rate	= s3c2443_roundrate_clksrc16,
+static struct clksrc_clk clk_i2s_eplldiv = {
+	.clk	= {
+		.name		= "i2s-eplldiv",
+		.id		= -1,
+		.parent		= &clk_esysclk.clk,
+	},
+	.reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, },
 };
 
 /* i2s-ref
  *
  * i2s bus reference clock, selectable from external, esysclk or epllref
+ *
+ * Note, this used to be two clocks, but was compressed into one.
 */
 
-static int s3c2443_setparent_i2s(struct clk *clk, struct clk *parent)
-{
-	unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
-
-	clksrc &= ~S3C2443_CLKSRC_I2S_MASK;
-
-	if (parent == &clk_epllref)
-		clksrc |= S3C2443_CLKSRC_I2S_EPLLREF;
-	else if (parent == &clk_i2s_ext)
-		clksrc |= S3C2443_CLKSRC_I2S_EXT;
-	else if (parent != &clk_i2s_eplldiv)
-		return -EINVAL;
-
-	clk->parent = parent;
-	__raw_writel(clksrc, S3C2443_CLKSRC);
+struct clk *clk_i2s_srclist[] = {
+	[0] = &clk_i2s_eplldiv.clk,
+	[1] = &clk_i2s_ext,
+	[2] = &clk_epllref.clk,
+	[3] = &clk_epllref.clk,
+};
 
-	return 0;
-}
+static struct clksrc_clk clk_i2s = {
+	.clk	= {
+		.name		= "i2s-if",
+		.id		= -1,
+		.ctrlbit	= S3C2443_SCLKCON_I2SCLK,
+		.enable		= s3c2443_clkcon_enable_s,
 
-static struct clk clk_i2s = {
-	.name		= "i2s-if",
-	.id		= -1,
-	.parent		= &clk_i2s_eplldiv,
-	.ctrlbit	= S3C2443_SCLKCON_I2SCLK,
-	.enable		= s3c2443_clkcon_enable_s,
-	.set_parent	= s3c2443_setparent_i2s,
+	},
+	.sources = &(struct clksrc_sources) {
+		.sources = clk_i2s_srclist,
+		.nr_sources = ARRAY_SIZE(clk_i2s_srclist),
+	},
+	.reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
 };
 
 /* cam-if
@@ -586,41 +438,15 @@ static struct clk clk_i2s = {
  * camera interface bus-clock, divided down from esysclk
 */
 
-static unsigned long s3c2443_getrate_cam(struct clk *clk)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
-
-	div  &= S3C2443_CLKDIV1_CAMDIV_MASK;
-	div >>= S3C2443_CLKDIV1_CAMDIV_SHIFT;
-
-	return parent_rate / (div + 1);
-}
-
-static int s3c2443_setrate_cam(struct clk *clk, unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long clkdiv1 = __raw_readl(S3C2443_CLKDIV1);
-
-	rate = s3c2443_roundrate_clksrc16(clk, rate);
-	rate = parent_rate / rate;
-
-	clkdiv1 &= ~S3C2443_CLKDIV1_CAMDIV_MASK;
-	clkdiv1 |= (rate - 1) << S3C2443_CLKDIV1_CAMDIV_SHIFT;
-
-	__raw_writel(clkdiv1, S3C2443_CLKDIV1);
-	return 0;
-}
-
-static struct clk clk_cam = {
-	.name		= "camif-upll",		/* same as 2440 name */
-	.id		= -1,
-	.parent		= &clk_esysclk,
-	.ctrlbit	= S3C2443_SCLKCON_CAMCLK,
-	.enable		= s3c2443_clkcon_enable_s,
-	.get_rate	= s3c2443_getrate_cam,
-	.set_rate	= s3c2443_setrate_cam,
-	.round_rate	= s3c2443_roundrate_clksrc16,
+static struct clksrc_clk clk_cam = {
+	.clk	= {
+		.name		= "camif-upll",	/* same as 2440 name */
+		.id		= -1,
+		.parent		= &clk_esysclk.clk,
+		.ctrlbit	= S3C2443_SCLKCON_CAMCLK,
+		.enable		= s3c2443_clkcon_enable_s,
+	},
+	.reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
 };
 
 /* display-if
@@ -628,41 +454,15 @@ static struct clk clk_cam = {
  * display interface clock, divided from esysclk
 */
 
-static unsigned long s3c2443_getrate_display(struct clk *clk)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
-
-	div &= S3C2443_CLKDIV1_DISPDIV_MASK;
-	div >>= S3C2443_CLKDIV1_DISPDIV_SHIFT;
-
-	return parent_rate / (div + 1);
-}
-
-static int s3c2443_setrate_display(struct clk *clk, unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
-
-	rate = s3c2443_roundrate_clksrc256(clk, rate);
-	rate = parent_rate / rate;
-
-	clkdivn &= ~S3C2443_CLKDIV1_UARTDIV_MASK;
-	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_UARTDIV_SHIFT;
-
-	__raw_writel(clkdivn, S3C2443_CLKDIV1);
-	return 0;
-}
-
-static struct clk clk_display = {
-	.name		= "display-if",
-	.id		= -1,
-	.parent		= &clk_esysclk,
-	.ctrlbit	= S3C2443_SCLKCON_DISPCLK,
-	.enable		= s3c2443_clkcon_enable_s,
-	.get_rate	= s3c2443_getrate_display,
-	.set_rate	= s3c2443_setrate_display,
-	.round_rate	= s3c2443_roundrate_clksrc256,
+static struct clksrc_clk clk_display = {
+	.clk	= {
+		.name		= "display-if",
+		.id		= -1,
+		.parent		= &clk_esysclk.clk,
+		.ctrlbit	= S3C2443_SCLKCON_DISPCLK,
+		.enable		= s3c2443_clkcon_enable_s,
+	},
+	.reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
 };
 
 /* prediv
@@ -684,8 +484,10 @@ static unsigned long s3c2443_prediv_getr
 static struct clk clk_prediv = {
 	.name		= "prediv",
 	.id		= -1,
-	.parent		= &clk_msysclk,
-	.get_rate	= s3c2443_prediv_getrate,
+	.parent		= &clk_msysclk.clk,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2443_prediv_getrate,
+	},
 };
 
 /* standard clock definitions */
@@ -857,7 +659,7 @@ static struct clk init_clocks[] = {
 	}, {
 		.name		= "usb-bus-host",
 		.id		= -1,
-		.parent		= &clk_usb_bus_host,
+		.parent		= &clk_usb_bus_host.clk,
 	}, {
 		.name		= "ac97",
 		.id		= -1,
@@ -868,103 +670,26 @@ static struct clk init_clocks[] = {
 
 /* clocks to add where we need to check their parentage */
 
-/* s3c2443_clk_initparents
- *
- * Initialise the parents for the clocks that we get at start-time
-*/
-
-static int __init clk_init_set_parent(struct clk *clk, struct clk *parent)
-{
-	printk(KERN_DEBUG "clock %s: parent %s\n", clk->name, parent->name);
-	return clk_set_parent(clk, parent);
-}
-
-static void __init s3c2443_clk_initparents(void)
-{
-	unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
-	struct clk *parent;
-
-	switch (clksrc & S3C2443_CLKSRC_EPLLREF_MASK) {
-	case S3C2443_CLKSRC_EPLLREF_EXTCLK:
-		parent = &clk_ext;
-		break;
-
-	case S3C2443_CLKSRC_EPLLREF_XTAL:
-	default:
-		parent = &clk_xtal;
-		break;
-
-	case S3C2443_CLKSRC_EPLLREF_MPLLREF:
-	case S3C2443_CLKSRC_EPLLREF_MPLLREF2:
-		parent = &clk_mpllref;
-		break;
-	}
-
-	clk_init_set_parent(&clk_epllref, parent);
-
-	switch (clksrc & S3C2443_CLKSRC_I2S_MASK) {
-	case S3C2443_CLKSRC_I2S_EXT:
-		parent = &clk_i2s_ext;
-		break;
-
-	case S3C2443_CLKSRC_I2S_EPLLDIV:
-	default:
-		parent = &clk_i2s_eplldiv;
-		break;
-
-	case S3C2443_CLKSRC_I2S_EPLLREF:
-	case S3C2443_CLKSRC_I2S_EPLLREF3:
-		parent = &clk_epllref;
-	}
-
-	clk_init_set_parent(&clk_i2s, &clk_epllref);
-
-	/* esysclk source */
-
-	parent = (clksrc & S3C2443_CLKSRC_ESYSCLK_EPLL) ?
-		&clk_epll : &clk_epllref;
-
-	clk_init_set_parent(&clk_esysclk, parent);
-
-	/* msysclk source */
-
-	if (clksrc & S3C2443_CLKSRC_MSYSCLK_MPLL) {
-		parent = &clk_mpll;
-	} else {
-		parent = (clksrc & S3C2443_CLKSRC_EXTCLK_DIV) ?
-			&clk_mdivclk : &clk_mpllref;
-	}
-
-	clk_init_set_parent(&clk_msysclk, parent);
-
-	/* arm */
-
-	if (__raw_readl(S3C2443_CLKDIV0) & S3C2443_CLKDIV0_DVS)
-		parent = &clk_h;
-	else
-		parent = &clk_armdiv;
-
-	clk_init_set_parent(&clk_arm, parent);
-}
-
-/* armdiv divisor table */
-
-static unsigned int armdiv[16] = {
-	[S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 1,
-	[S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 2,
-	[S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 3,
-	[S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 4,
-	[S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 6,
-	[S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 8,
-	[S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 12,
-	[S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 16,
+static struct clksrc_clk __initdata *init_list[] = {
+	&clk_epllref, /* should be first */
+	&clk_esysclk,
+	&clk_msysclk,
+	&clk_arm,
+	&clk_i2s_eplldiv,
+	&clk_i2s,
+	&clk_cam,
+	&clk_uart,
+	&clk_display,
+	&clk_hsmmc_div,
+	&clk_usb_bus_host,
 };
 
-static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
+static void __init s3c2443_clk_initparents(void)
 {
-	clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
+	int ptr;
 
-	return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
+	for (ptr = 0; ptr < ARRAY_SIZE(init_list); ptr++)
+		s3c_set_clksrc(init_list[ptr], true);
 }
 
 static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
@@ -976,15 +701,12 @@ static inline unsigned long s3c2443_get_
 
 /* clocks to add straight away */
 
-static struct clk *clks[] __initdata = {
-	&clk_ext,
-	&clk_epll,
+static struct clksrc_clk *clksrcs[] __initdata = {
 	&clk_usb_bus_host,
-	&clk_usb_bus,
-	&clk_esysclk,
 	&clk_epllref,
-	&clk_mpllref,
+	&clk_esysclk,
 	&clk_msysclk,
+	&clk_arm,
 	&clk_uart,
 	&clk_display,
 	&clk_cam,
@@ -992,9 +714,15 @@ static struct clk *clks[] __initdata = {
 	&clk_i2s,
 	&clk_hsspi,
 	&clk_hsmmc_div,
+};
+
+static struct clk *clks[] __initdata = {
+	&clk_ext,
+	&clk_epll,
+	&clk_usb_bus,
+	&clk_mpllref,
 	&clk_hsmmc,
 	&clk_armdiv,
-	&clk_arm,
 	&clk_prediv,
 };
 
@@ -1014,7 +742,7 @@ void __init_or_cpufreq s3c2443_setup_clo
 	clk_put(xtal_clk);
 
 	pll = s3c2443_get_mpll(mpllcon, xtal);
-	clk_msysclk.rate = pll;
+	clk_msysclk.clk.rate = pll;
 
 	fclk = pll / s3c2443_fclk_div(clkdiv0);
 	hclk = s3c2443_prediv_getrate(&clk_prediv);
@@ -1056,15 +784,18 @@ void __init s3c2443_init_clocks(int xtal
 		}
 	}
 
+	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+		s3c_register_clksrc(clksrcs[ptr], 1);
+
 	clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
-	clk_epll.parent = &clk_epllref;
-	clk_usb_bus.parent = &clk_usb_bus_host;
+	clk_epll.parent = &clk_epllref.clk;
+	clk_usb_bus.parent = &clk_usb_bus_host.clk;
 
 	/* ensure usb bus clock is within correct rate of 48MHz */
 
-	if (clk_get_rate(&clk_usb_bus_host) != (48 * 1000 * 1000)) {
+	if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
 		printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
-		clk_set_rate(&clk_usb_bus_host, 48*1000*1000);
+		clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
 	}
 
 	printk("S3C2443: epll %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
@@ -1074,14 +805,7 @@ void __init s3c2443_init_clocks(int xtal
 
 	/* register clocks from clock array */
 
-	clkp = init_clocks;
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-	}
+	s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
 
 	/* We must be careful disabling the clocks we are not intending to
 	 * be using at boot time, as subsystems such as the LCD which do
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2443/dma.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2443/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2443/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2443/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,7 +20,7 @@
 
 #include <mach/dma.h>
 
-#include <plat/dma-plat.h>
+#include <plat/dma-s3c24xx.h>
 #include <plat/cpu.h>
 
 #include <plat/regs-serial.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2443/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2443/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2443/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2443/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@ config CPU_S3C2443
 	depends on ARCH_S3C2410
 	select S3C2443_DMA if S3C2410_DMA
 	select CPU_LLSERIAL_S3C2440
+	select SAMSUNG_CLKSRC
 	help
 	  Support for the S3C2443 SoC from the S3C24XX line
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2443/mach-smdk2443.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2443/mach-smdk2443.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2443/mach-smdk2443.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c2443/mach-smdk2443.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,7 +40,7 @@
 #include <plat/iic.h>
 
 #include <plat/s3c2410.h>
-#include <plat/s3c2440.h>
+#include <plat/s3c2443.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
@@ -106,6 +106,9 @@ static struct platform_device *smdk2443_
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
 	&s3c_device_hsmmc0,
+#ifdef CONFIG_SND_SOC_SMDK2443_WM9710
+	&s3c_device_ac97,
+#endif
 };
 
 static void __init smdk2443_map_io(void)
@@ -118,6 +121,11 @@ static void __init smdk2443_map_io(void)
 static void __init smdk2443_machine_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
+
+#ifdef CONFIG_SND_SOC_SMDK2443_WM9710
+	s3c24xx_ac97_setup_gpio(S3C24XX_AC97_GPE0);
+#endif
+
 	platform_add_devices(smdk2443_devices, ARRAY_SIZE(smdk2443_devices));
 	smdk_machine_init();
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c24a0/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-s3c24a0/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c24a0/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c24a0/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,7 @@
 #include <mach/map.h>
 #include <plat/regs-serial.h>
 
-	.macro addruart, rx
+	.macro addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1
 		ldreq	\rx, = S3C24XX_PA_UART
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c24a0/include/mach/io.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c24a0/include/mach/io.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c24a0/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c24a0/include/mach/io.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s3c24a0/include/mach/io.h
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S3C24A0
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a)		__typesafe_io(a)
+#define __mem_pci(a)	(a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c24a0/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c24a0/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c24a0/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c24a0/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
-#define VMALLOC_END	  (0xE0000000)
+#define VMALLOC_END	  (0xe0000000UL)
 
 #endif /* __ASM_ARCH_VMALLOC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-/* arch/arm/mach-s3c6400/include/mach/debug-macro.S
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	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.
-*/
-
-/* pull in the relevant register and map files. */
-
-#include <mach/map.h>
-#include <plat/regs-serial.h>
-
-	/* note, for the boot process to work we have to keep the UART
-	 * virtual address aligned to an 1MiB boundary for the L1
-	 * mapping the head code makes. We keep the UART virtual address
-	 * aligned and add in the offset when we load the value here.
-	 */
-
-	.macro addruart, rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1
-		ldreq	\rx, = S3C_PA_UART
-		ldrne	\rx, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)
-#if CONFIG_DEBUG_S3C_UART != 0
-		add	\rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
-#endif
-	.endm
-
-/* include the reset of the code which will do the work, we're only
- * compiling for a single cpu processor type so the default of s3c2440
- * will be fine with us.
- */
-
-#include <plat/debug-macro.S>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/dma.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/dma.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/dma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/dma.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,70 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/dma.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C6400 - DMA support
- */
-
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H __FILE__
-
-#define S3C_DMA_CHANNELS	(16)
-
-/* see mach-s3c2410/dma.h for notes on dma channel numbers */
-
-/* Note, for the S3C64XX architecture we keep the DMACH_
- * defines in the order they are allocated to [S]DMA0/[S]DMA1
- * so that is easy to do DHACH_ -> DMA controller conversion
- */
-enum dma_ch {
-	/* DMA0/SDMA0 */
-	DMACH_UART0 = 0,
-	DMACH_UART0_SRC2,
-	DMACH_UART1,
-	DMACH_UART1_SRC2,
-	DMACH_UART2,
-	DMACH_UART2_SRC2,
-	DMACH_UART3,
-	DMACH_UART3_SRC2,
-	DMACH_PCM0_TX,
-	DMACH_PCM0_RX,
-	DMACH_I2S0_OUT,
-	DMACH_I2S0_IN,
-	DMACH_SPI0_TX,
-	DMACH_SPI0_RX,
-	DMACH_HSI_I2SV40_TX,
-	DMACH_HSI_I2SV40_RX,
-
-	/* DMA1/SDMA1 */
-	DMACH_PCM1_TX = 16,
-	DMACH_PCM1_RX,
-	DMACH_I2S1_OUT,
-	DMACH_I2S1_IN,
-	DMACH_SPI1_TX,
-	DMACH_SPI1_RX,
-	DMACH_AC97_PCMOUT,
-	DMACH_AC97_PCMIN,
-	DMACH_AC97_MICIN,
-	DMACH_PWM,
-	DMACH_IRDA,
-	DMACH_EXTERNAL,
-	DMACH_RES1,
-	DMACH_RES2,
-	DMACH_SECURITY_RX,	/* SDMA1 only */
-	DMACH_SECURITY_TX,	/* SDMA1 only */
-	DMACH_MAX		/* the end */
-};
-
-static __inline__ bool s3c_dma_has_circular(void)
-{
-	return true;
-}
-
-#define S3C2410_DMAF_CIRCULAR		(1 << 0)
-
-#include <plat/dma.h>
-
-#endif /* __ASM_ARCH_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/entry-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/entry-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/entry-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,44 +0,0 @@
-/* arch/arm/mach-s3c6400/include/mach/entry-macro.S
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * Low-level IRQ helper macros for the Samsung S3C64XX series
- *
- * 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 <asm/hardware/vic.h>
-#include <mach/map.h>
-#include <plat/irqs.h>
-
-	.macro	disable_fiq
-	.endm
-
-	.macro	get_irqnr_preamble, base, tmp
-	ldr	\base, =S3C_VA_VIC0
-	.endm
-
-	.macro	arch_ret_to_user, tmp1, tmp2
-	.endm
-
-	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-	@ check the vic0
-	mov	\irqnr, # S3C_IRQ_OFFSET + 31
-	ldr	\irqstat, [ \base, # VIC_IRQ_STATUS ]
-	teq	\irqstat, #0
-
-	@ otherwise try vic1
-	addeq	\tmp, \base, #(S3C_VA_VIC1 - S3C_VA_VIC0)
-	addeq	\irqnr, \irqnr, #32
-	ldreq	\irqstat, [ \tmp, # VIC_IRQ_STATUS ]
-	teqeq	\irqstat, #0
-
-	clzne	\irqstat, \irqstat
-	subne	\irqnr, \irqnr, \irqstat
-	.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/gpio-core.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/gpio-core.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/gpio-core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/gpio-core.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,21 +0,0 @@
-/* arch/arm/mach-s3c6400/include/mach/gpio-core.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C64XX - GPIO core support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_GPIO_CORE_H
-#define __ASM_ARCH_GPIO_CORE_H __FILE__
-
-/* currently we just include the platform support */
-#include <plat/gpio-core.h>
-
-#endif /* __ASM_ARCH_GPIO_CORE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/gpio.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/gpio.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/gpio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,96 +0,0 @@
-/* arch/arm/mach-s3c6400/include/mach/gpio.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C6400 - GPIO lib support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define gpio_get_value	__gpio_get_value
-#define gpio_set_value	__gpio_set_value
-#define gpio_cansleep	__gpio_cansleep
-#define gpio_to_irq	__gpio_to_irq
-
-/* GPIO bank sizes */
-#define S3C64XX_GPIO_A_NR	(8)
-#define S3C64XX_GPIO_B_NR	(7)
-#define S3C64XX_GPIO_C_NR	(8)
-#define S3C64XX_GPIO_D_NR	(5)
-#define S3C64XX_GPIO_E_NR	(5)
-#define S3C64XX_GPIO_F_NR	(16)
-#define S3C64XX_GPIO_G_NR	(7)
-#define S3C64XX_GPIO_H_NR	(10)
-#define S3C64XX_GPIO_I_NR	(16)
-#define S3C64XX_GPIO_J_NR	(12)
-#define S3C64XX_GPIO_K_NR	(16)
-#define S3C64XX_GPIO_L_NR	(15)
-#define S3C64XX_GPIO_M_NR	(6)
-#define S3C64XX_GPIO_N_NR	(16)
-#define S3C64XX_GPIO_O_NR	(16)
-#define S3C64XX_GPIO_P_NR	(15)
-#define S3C64XX_GPIO_Q_NR	(9)
-
-/* GPIO bank numbes */
-
-/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
- * space for debugging purposes so that any accidental
- * change from one gpio bank to another can be caught.
-*/
-
-#define S3C64XX_GPIO_NEXT(__gpio) \
-	((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
-
-enum s3c_gpio_number {
-	S3C64XX_GPIO_A_START = 0,
-	S3C64XX_GPIO_B_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_A),
-	S3C64XX_GPIO_C_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_B),
-	S3C64XX_GPIO_D_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_C),
-	S3C64XX_GPIO_E_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_D),
-	S3C64XX_GPIO_F_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_E),
-	S3C64XX_GPIO_G_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_F),
-	S3C64XX_GPIO_H_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_G),
-	S3C64XX_GPIO_I_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_H),
-	S3C64XX_GPIO_J_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_I),
-	S3C64XX_GPIO_K_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_J),
-	S3C64XX_GPIO_L_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_K),
-	S3C64XX_GPIO_M_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_L),
-	S3C64XX_GPIO_N_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_M),
-	S3C64XX_GPIO_O_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_N),
-	S3C64XX_GPIO_P_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_O),
-	S3C64XX_GPIO_Q_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_P),
-};
-
-/* S3C64XX GPIO number definitions. */
-
-#define S3C64XX_GPA(_nr)	(S3C64XX_GPIO_A_START + (_nr))
-#define S3C64XX_GPB(_nr)	(S3C64XX_GPIO_B_START + (_nr))
-#define S3C64XX_GPC(_nr)	(S3C64XX_GPIO_C_START + (_nr))
-#define S3C64XX_GPD(_nr)	(S3C64XX_GPIO_D_START + (_nr))
-#define S3C64XX_GPE(_nr)	(S3C64XX_GPIO_E_START + (_nr))
-#define S3C64XX_GPF(_nr)	(S3C64XX_GPIO_F_START + (_nr))
-#define S3C64XX_GPG(_nr)	(S3C64XX_GPIO_G_START + (_nr))
-#define S3C64XX_GPH(_nr)	(S3C64XX_GPIO_H_START + (_nr))
-#define S3C64XX_GPI(_nr)	(S3C64XX_GPIO_I_START + (_nr))
-#define S3C64XX_GPJ(_nr)	(S3C64XX_GPIO_J_START + (_nr))
-#define S3C64XX_GPK(_nr)	(S3C64XX_GPIO_K_START + (_nr))
-#define S3C64XX_GPL(_nr)	(S3C64XX_GPIO_L_START + (_nr))
-#define S3C64XX_GPM(_nr)	(S3C64XX_GPIO_M_START + (_nr))
-#define S3C64XX_GPN(_nr)	(S3C64XX_GPIO_N_START + (_nr))
-#define S3C64XX_GPO(_nr)	(S3C64XX_GPIO_O_START + (_nr))
-#define S3C64XX_GPP(_nr)	(S3C64XX_GPIO_P_START + (_nr))
-#define S3C64XX_GPQ(_nr)	(S3C64XX_GPIO_Q_START + (_nr))
-
-/* the end of the S3C64XX specific gpios */
-#define S3C64XX_GPIO_END	(S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
-#define S3C_GPIO_END		S3C64XX_GPIO_END
-
-/* define the number of gpios we need to the one after the GPQ() range */
-#define ARCH_NR_GPIOS	(S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
-
-#include <asm-generic/gpio.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/hardware.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/hardware.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/hardware.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,16 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/hardware.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C6400 - Hardware support
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H __FILE__
-
-/* currently nothing here, placeholder */
-
-#endif /* __ASM_ARCH_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/irqs.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/irqs.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/irqs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,16 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/irqs.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C6400 - IRQ definitions
- */
-
-#ifndef __ASM_ARCH_IRQS_H
-#define __ASM_ARCH_IRQS_H __FILE__
-
-#include <plat/irqs.h>
-
-#endif /* __ASM_ARCH_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/map.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/map.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/map.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/map.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,89 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/map.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C64XX - Memory 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_ARCH_MAP_H
-#define __ASM_ARCH_MAP_H __FILE__
-
-#include <plat/map-base.h>
-
-/* HSMMC units */
-#define S3C64XX_PA_HSMMC(x)	(0x7C200000 + ((x) * 0x100000))
-#define S3C64XX_PA_HSMMC0	S3C64XX_PA_HSMMC(0)
-#define S3C64XX_PA_HSMMC1	S3C64XX_PA_HSMMC(1)
-#define S3C64XX_PA_HSMMC2	S3C64XX_PA_HSMMC(2)
-
-#define S3C_PA_UART		(0x7F005000)
-#define S3C_PA_UART0		(S3C_PA_UART + 0x00)
-#define S3C_PA_UART1		(S3C_PA_UART + 0x400)
-#define S3C_PA_UART2		(S3C_PA_UART + 0x800)
-#define S3C_PA_UART3		(S3C_PA_UART + 0xC00)
-#define S3C_UART_OFFSET		(0x400)
-
-/* See notes on UART VA mapping in debug-macro.S */
-#define S3C_VA_UARTx(x)	(S3C_VA_UART + (S3C_PA_UART & 0xfffff) + ((x) * S3C_UART_OFFSET))
-
-#define S3C_VA_UART0		S3C_VA_UARTx(0)
-#define S3C_VA_UART1		S3C_VA_UARTx(1)
-#define S3C_VA_UART2		S3C_VA_UARTx(2)
-#define S3C_VA_UART3		S3C_VA_UARTx(3)
-
-#define S3C64XX_PA_NAND		(0x70200000)
-#define S3C64XX_PA_FB		(0x77100000)
-#define S3C64XX_PA_USB_HSOTG	(0x7C000000)
-#define S3C64XX_PA_WATCHDOG	(0x7E004000)
-#define S3C64XX_PA_SYSCON	(0x7E00F000)
-#define S3C64XX_PA_AC97		(0x7F001000)
-#define S3C64XX_PA_IIS0		(0x7F002000)
-#define S3C64XX_PA_IIS1		(0x7F003000)
-#define S3C64XX_PA_TIMER	(0x7F006000)
-#define S3C64XX_PA_IIC0		(0x7F004000)
-#define S3C64XX_PA_PCM0		(0x7F009000)
-#define S3C64XX_PA_PCM1		(0x7F00A000)
-#define S3C64XX_PA_IISV4	(0x7F00D000)
-#define S3C64XX_PA_IIC1		(0x7F00F000)
-
-#define S3C64XX_PA_GPIO		(0x7F008000)
-#define S3C64XX_VA_GPIO		S3C_ADDR_CPU(0x00000000)
-#define S3C64XX_SZ_GPIO		SZ_4K
-
-#define S3C64XX_PA_SDRAM	(0x50000000)
-#define S3C64XX_PA_VIC0		(0x71200000)
-#define S3C64XX_PA_VIC1		(0x71300000)
-
-#define S3C64XX_PA_MODEM	(0x74108000)
-#define S3C64XX_VA_MODEM	S3C_ADDR_CPU(0x00100000)
-
-#define S3C64XX_PA_USBHOST	(0x74300000)
-
-#define S3C64XX_PA_USB_HSPHY	(0x7C100000)
-#define S3C64XX_VA_USB_HSPHY	S3C_ADDR_CPU(0x00200000)
-
-/* place VICs close together */
-#define S3C_VA_VIC0		(S3C_VA_IRQ + 0x00)
-#define S3C_VA_VIC1		(S3C_VA_IRQ + 0x10000)
-
-/* compatibiltiy defines. */
-#define S3C_PA_TIMER		S3C64XX_PA_TIMER
-#define S3C_PA_HSMMC0		S3C64XX_PA_HSMMC0
-#define S3C_PA_HSMMC1		S3C64XX_PA_HSMMC1
-#define S3C_PA_HSMMC2		S3C64XX_PA_HSMMC2
-#define S3C_PA_IIC		S3C64XX_PA_IIC0
-#define S3C_PA_IIC1		S3C64XX_PA_IIC1
-#define S3C_PA_NAND		S3C64XX_PA_NAND
-#define S3C_PA_FB		S3C64XX_PA_FB
-#define S3C_PA_USBHOST		S3C64XX_PA_USBHOST
-#define S3C_PA_USB_HSOTG	S3C64XX_PA_USB_HSOTG
-#define S3C_VA_USB_HSPHY	S3C64XX_VA_USB_HSPHY
-
-#endif /* __ASM_ARCH_6400_MAP_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/memory.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/memory.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,18 +0,0 @@
-/* arch/arm/mach-s3c6400/include/mach/memory.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
-
-#define PHYS_OFFSET     UL(0x50000000)
-
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/pwm-clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/pwm-clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/pwm-clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/pwm-clock.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,56 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/pwm-clock.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C64xx - pwm clock and timer support
- */
-
-/**
- * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
- * @tcfg: The timer TCFG1 register bits shifted down to 0.
- *
- * Return true if the given configuration from TCFG1 is a TCLK instead
- * any of the TDIV clocks.
- */
-static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
-{
-	return tcfg >= S3C64XX_TCFG1_MUX_TCLK;
-}
-
-/**
- * tcfg_to_divisor() - convert tcfg1 setting to a divisor
- * @tcfg1: The tcfg1 setting, shifted down.
- *
- * Get the divisor value for the given tcfg1 setting. We assume the
- * caller has already checked to see if this is not a TCLK source.
- */
-static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
-{
-	return 1 << tcfg1;
-}
-
-/**
- * pwm_tdiv_has_div1() - does the tdiv setting have a /1
- *
- * Return true if we have a /1 in the tdiv setting.
- */
-static inline unsigned int pwm_tdiv_has_div1(void)
-{
-	return 1;
-}
-
-/**
- * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
- * @div: The divisor to calculate the bit information for.
- *
- * Turn a divisor into the necessary bit field for TCFG1.
- */
-static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
-{
-	return ilog2(div);
-}
-
-#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/regs-clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/regs-clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/regs-clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/regs-clock.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,16 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/regs-clock.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C64XX - clock register compatibility with s3c24xx
- *
- * This program is free software; you can 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 <plat/regs-clock.h>
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/regs-fb.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/regs-fb.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/regs-fb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/regs-fb.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-/*
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Copyright 2009 Samsung Electronics Co.
- *
- * Pawel Osciak <p.osciak@samsung.com>
- * Based on plat-s3c/include/plat/regs-fb.h by Ben Dooks <ben@simtec.co.uk>
- *
- * Framebuffer register definitions for Samsung S3C64xx.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_MACH_REGS_FB_H
-#define __ASM_ARCH_MACH_REGS_FB_H __FILE__
-
-#include <plat/regs-fb-v4.h>
-
-/* Palette registers */
-#define WIN2_PAL(_entry)			(0x300 + ((_entry) * 2))
-#define WIN3_PAL(_entry)			(0x320 + ((_entry) * 2))
-#define WIN4_PAL(_entry)			(0x340 + ((_entry) * 2))
-#define WIN0_PAL(_entry)			(0x400 + ((_entry) * 4))
-#define WIN1_PAL(_entry)			(0x800 + ((_entry) * 4))
-
-static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg)
-{
-	switch (window) {
-	case 0: return WIN0_PAL(reg);
-	case 1: return WIN1_PAL(reg);
-	case 2: return WIN2_PAL(reg);
-	case 3: return WIN3_PAL(reg);
-	case 4: return WIN4_PAL(reg);
-	}
-
-	BUG();
-}
-
-#endif /* __ASM_ARCH_MACH_REGS_FB_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/regs-irq.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/regs-irq.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/regs-irq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/regs-irq.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,20 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/regs-irq.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C64XX - IRQ register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_IRQ_H
-#define __ASM_ARCH_REGS_IRQ_H __FILE__
-
-#include <asm/hardware/vic.h>
-
-#endif /* __ASM_ARCH_6400_REGS_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/system.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/system.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/system.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,30 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/system.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C6400 - system implementation
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H __FILE__
-
-#include <plat/watchdog-reset.h>
-
-static void arch_idle(void)
-{
-	/* nothing here yet */
-}
-
-static void arch_reset(char mode, const char *cmd)
-{
-	if (mode != 's')
-		arch_wdt_reset();
-
-	/* if all else fails, or mode was for soft, jump to 0 */
-	cpu_reset(0);
-}
-
-#endif /* __ASM_ARCH_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/tick.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/tick.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/tick.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/tick.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,29 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/tick.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C64XX - Timer tick support definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_TICK_H
-#define __ASM_ARCH_TICK_H __FILE__
-
-/* note, the timer interrutps turn up in 2 places, the vic and then
- * the timer block. We take the VIC as the base at the moment.
- */
-static inline u32 s3c24xx_ostimer_pending(void)
-{
-	u32 pend = __raw_readl(S3C_VA_VIC0 + VIC_RAW_STATUS);
-	return pend & 1 << (IRQ_TIMER4_VIC - S3C64XX_IRQ_VIC0(0));
-}
-
-#define TICK_MAX	(0xffffffff)
-
-#endif /* __ASM_ARCH_6400_TICK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/uncompress.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/uncompress.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/uncompress.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,28 +0,0 @@
-/* arch/arm/mach-s3c6400/include/mach/uncompress.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C6400 - uncompress 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.
-*/
-
-#ifndef __ASM_ARCH_UNCOMPRESS_H
-#define __ASM_ARCH_UNCOMPRESS_H
-
-#include <mach/map.h>
-#include <plat/uncompress.h>
-
-static void arch_detect_cpu(void)
-{
-	/* we do not need to do any cpu detection here at the moment. */
-	fifo_mask = S3C2440_UFSTAT_TXMASK;
-	fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
-}
-
-#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,30 +0,0 @@
-# Copyright 2008 Openmoko, Inc.
-#	Simtec Electronics, Ben Dooks <ben@simtec.co.uk>
-#
-# Licensed under GPLv2
-
-# Configuration options for the S3C6410 CPU
-
-config CPU_S3C6400
-	bool
-	select CPU_S3C6400_INIT
-	select CPU_S3C6400_CLOCK
-	help
-	  Enable S3C6400 CPU support
-
-config S3C6400_SETUP_SDHCI
-	bool
-	help
-	  Internal configuration for default SDHCI
-	  setup for S3C6400.
-
-# S36400 Macchine support
-
-config MACH_SMDK6400
-       bool "SMDK6400"
-	select CPU_S3C6400
-	select S3C_DEV_HSMMC
-	select S3C_DEV_NAND
-	select S3C6400_SETUP_SDHCI
-	help
-	  Machine support for the Samsung SMDK6400
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/mach-smdk6400.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/mach-smdk6400.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/mach-smdk6400.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/mach-smdk6400.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,96 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/mach-smdk6400.c
- *
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/io.h>
-
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <plat/regs-serial.h>
-
-#include <plat/s3c6400.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/iic.h>
-
-#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg smdk6400_uartcfgs[] __initdata = {
-	[0] = {
-		.hwport	     = 0,
-		.flags	     = 0,
-		.ucon	     = 0x3c5,
-		.ulcon	     = 0x03,
-		.ufcon	     = 0x51,
-	},
-	[1] = {
-		.hwport	     = 1,
-		.flags	     = 0,
-		.ucon	     = 0x3c5,
-		.ulcon	     = 0x03,
-		.ufcon	     = 0x51,
-	},
-};
-
-static struct map_desc smdk6400_iodesc[] = {};
-
-static void __init smdk6400_map_io(void)
-{
-	s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc));
-	s3c24xx_init_clocks(12000000);
-	s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs));
-}
-
-static struct platform_device *smdk6400_devices[] __initdata = {
-	&s3c_device_hsmmc1,
-	&s3c_device_i2c0,
-};
-
-static struct i2c_board_info i2c_devs[] __initdata = {
-	{ I2C_BOARD_INFO("wm8753", 0x1A), },
-	{ I2C_BOARD_INFO("24c08", 0x50), },
-};
-
-static void __init smdk6400_machine_init(void)
-{
-	i2c_register_board_info(0, i2c_devs, ARRAY_SIZE(i2c_devs));
-	platform_add_devices(smdk6400_devices, ARRAY_SIZE(smdk6400_devices));
-}
-
-MACHINE_START(SMDK6400, "SMDK6400")
-	/* Maintainer: Ben Dooks <ben@fluff.org> */
-	.phys_io	= S3C_PA_UART & 0xfff00000,
-	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
-	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
-
-	.init_irq	= s3c6400_init_irq,
-	.map_io		= smdk6400_map_io,
-	.init_machine	= smdk6400_machine_init,
-	.timer		= &s3c24xx_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-# arch/arm/mach-s3c6400/Makefile
-#
-# Copyright 2008 Openmoko, Inc.
-# Copyright 2008 Simtec Electronics
-#
-# Licensed under GPLv2
-
-obj-y				:=
-obj-m				:=
-obj-n				:=
-obj-				:=
-
-# Core support for S3C6400 system
-
-obj-$(CONFIG_CPU_S3C6400)	+= s3c6400.o
-
-# setup support
-
-obj-$(CONFIG_S3C6400_SETUP_SDHCI) += setup-sdhci.o
-
-# Machine support
-
-obj-$(CONFIG_MACH_SMDK6400)	+= mach-smdk6400.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/Makefile.boot linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/Makefile.boot
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/Makefile.boot	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
@@ -1,2 +0,0 @@
-   zreladdr-y	:= 0x50008000
-params_phys-y	:= 0x50000100
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/s3c6400.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/s3c6400.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/s3c6400.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/s3c6400.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,92 +0,0 @@
-/* linux/arch/arm/mach-s3c6410/cpu.c
- *
- * Copyright 2009 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/sysdev.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/regs-serial.h>
-#include <plat/regs-clock.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/clock.h>
-#include <plat/sdhci.h>
-#include <plat/iic-core.h>
-#include <plat/s3c6400.h>
-
-void __init s3c6400_map_io(void)
-{
-	/* setup SDHCI */
-
-	s3c6400_default_sdhci0();
-	s3c6400_default_sdhci1();
-	s3c6400_default_sdhci2();
-
-	/* the i2c devices are directly compatible with s3c2440 */
-	s3c_i2c0_setname("s3c2440-i2c");
-
-	s3c_device_nand.name = "s3c6400-nand";
-}
-
-void __init s3c6400_init_clocks(int xtal)
-{
-	printk(KERN_DEBUG "%s: initialising clocks\n", __func__);
-	s3c24xx_register_baseclocks(xtal);
-	s3c64xx_register_clocks();
-	s3c6400_register_clocks(S3C6400_CLKDIV0_ARM_MASK);
-	s3c6400_setup_clocks();
-}
-
-void __init s3c6400_init_irq(void)
-{
-	/* VIC0 does not have IRQS 5..7,
-	 * VIC1 is fully populated. */
-	s3c64xx_init_irq(~0 & ~(0xf << 5), ~0);
-}
-
-struct sysdev_class s3c6400_sysclass = {
-	.name	= "s3c6400-core",
-};
-
-static struct sys_device s3c6400_sysdev = {
-	.cls	= &s3c6400_sysclass,
-};
-
-static int __init s3c6400_core_init(void)
-{
-	return sysdev_class_register(&s3c6400_sysclass);
-}
-
-core_initcall(s3c6400_core_init);
-
-int __init s3c6400_init(void)
-{
-	printk("S3C6400: Initialising architecture\n");
-
-	return sysdev_register(&s3c6400_sysdev);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/setup-sdhci.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/setup-sdhci.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/setup-sdhci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6400/setup-sdhci.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,63 +0,0 @@
-/* linux/arch/arm/mach-s3c6410/setup-sdhci.c
- *
- * Copyright 2008 Simtec Electronics
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C6410 - Helper functions for settign up SDHCI device(s) (HSMMC)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
-
-#include <plat/regs-sdhci.h>
-#include <plat/sdhci.h>
-
-/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
-
-char *s3c6400_hsmmc_clksrcs[4] = {
-	[0] = "hsmmc",
-	[1] = "hsmmc",
-	[2] = "mmc_bus",
-	/* [3] = "48m", - note not successfully used yet */
-};
-
-void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
-				  void __iomem *r,
-				  struct mmc_ios *ios,
-				  struct mmc_card *card)
-{
-	u32 ctrl2, ctrl3;
-
-	ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
-	ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
-	ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
-		  S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
-		  S3C_SDHCI_CTRL2_ENFBCLKRX |
-		  S3C_SDHCI_CTRL2_DFCNT_NONE |
-		  S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
-
-	if (ios->clock < 25 * 1000000)
-		ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
-			 S3C_SDHCI_CTRL3_FCSEL2 |
-			 S3C_SDHCI_CTRL3_FCSEL1 |
-			 S3C_SDHCI_CTRL3_FCSEL0);
-	else
-		ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
-
-	printk(KERN_INFO "%s: CTRL 2=%08x, 3=%08x\n", __func__, ctrl2, ctrl3);
-	writel(ctrl2, r + S3C_SDHCI_CONTROL2);
-	writel(ctrl3, r + S3C_SDHCI_CONTROL3);
-}
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/cpu.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/cpu.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/cpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/cpu.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,105 +0,0 @@
-/* linux/arch/arm/mach-s3c6410/cpu.c
- *
- * Copyright 2008 Simtec Electronics
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/sysdev.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/regs-serial.h>
-#include <plat/regs-clock.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/clock.h>
-#include <plat/sdhci.h>
-#include <plat/iic-core.h>
-#include <plat/s3c6400.h>
-#include <plat/s3c6410.h>
-
-/* Initial IO mappings */
-
-static struct map_desc s3c6410_iodesc[] __initdata = {
-};
-
-/* s3c6410_map_io
- *
- * register the standard cpu IO areas
-*/
-
-void __init s3c6410_map_io(void)
-{
-	iotable_init(s3c6410_iodesc, ARRAY_SIZE(s3c6410_iodesc));
-
-	/* initialise device information early */
-	s3c6410_default_sdhci0();
-	s3c6410_default_sdhci1();
-	s3c6410_default_sdhci2();
-
-	/* the i2c devices are directly compatible with s3c2440 */
-	s3c_i2c0_setname("s3c2440-i2c");
-	s3c_i2c1_setname("s3c2440-i2c");
-
-	s3c_device_nand.name = "s3c6400-nand";
-}
-
-void __init s3c6410_init_clocks(int xtal)
-{
-	printk(KERN_DEBUG "%s: initialising clocks\n", __func__);
-	s3c24xx_register_baseclocks(xtal);
-	s3c64xx_register_clocks();
-	s3c6400_register_clocks(S3C6410_CLKDIV0_ARM_MASK);
-	s3c6400_setup_clocks();
-}
-
-void __init s3c6410_init_irq(void)
-{
-	/* VIC0 is missing IRQ7, VIC1 is fully populated. */
-	s3c64xx_init_irq(~0 & ~(1 << 7), ~0);
-}
-
-struct sysdev_class s3c6410_sysclass = {
-	.name	= "s3c6410-core",
-};
-
-static struct sys_device s3c6410_sysdev = {
-	.cls	= &s3c6410_sysclass,
-};
-
-static int __init s3c6410_core_init(void)
-{
-	return sysdev_class_register(&s3c6410_sysclass);
-}
-
-core_initcall(s3c6410_core_init);
-
-int __init s3c6410_init(void)
-{
-	printk("S3C6410: Initialising architecture\n");
-
-	return sysdev_register(&s3c6410_sysdev);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,109 +0,0 @@
-# Copyright 2008 Openmoko, Inc.
-# Copyright 2008 Simtec Electronics
-#
-# Licensed under GPLv2
-
-# Configuration options for the S3C6410 CPU
-
-config CPU_S3C6410
-	bool
-	select CPU_S3C6400_INIT
-	select CPU_S3C6400_CLOCK
-	help
-	  Enable S3C6410 CPU support
-
-config S3C6410_SETUP_SDHCI
-	bool
-	select S3C64XX_SETUP_SDHCI_GPIO
-	help
-	  Internal helper functions for S3C6410 based SDHCI systems
-
-config MACH_ANW6410
-	bool "A&W6410"
-	select CPU_S3C6410
-	select S3C_DEV_FB
-	select S3C64XX_SETUP_FB_24BPP
-	help
-	  Machine support for the A&W6410
-
-config MACH_SMDK6410
-	bool "SMDK6410"
-	select CPU_S3C6410
-	select S3C_DEV_HSMMC
-	select S3C_DEV_HSMMC1
-	select S3C_DEV_I2C1
-	select S3C_DEV_FB
-	select S3C_DEV_USB_HOST
-	select S3C_DEV_USB_HSOTG
-	select S3C6410_SETUP_SDHCI
-	select S3C64XX_SETUP_I2C1
-	select S3C64XX_SETUP_FB_24BPP
-	help
-	  Machine support for the Samsung SMDK6410
-
-# At least some of the SMDK6410s were shipped with the card detect
-# for the MMC/SD slots connected to the same input. This means that
-# either the boards need to be altered to have channel0 to an alternate
-# configuration or that only one slot can be used.
-
-choice
-	prompt "SMDK6410 MMC/SD slot setup"
-	depends on MACH_SMDK6410
-
-config SMDK6410_SD_CH0
-	bool "Use channel 0 only"
-	depends on MACH_SMDK6410
-	help
-          Select CON7 (channel 0) as the MMC/SD slot, as
-	  at least some SMDK6410 boards come with the
-	  resistors fitted so that the card detects for
-	  channels 0 and 1 are the same.
-       
-config SMDK6410_SD_CH1
-	bool "Use channel 1 only"
-	depends on MACH_SMDK6410
-	help
-          Select CON6 (channel 1) as the MMC/SD slot, as
-	  at least some SMDK6410 boards come with the
-	  resistors fitted so that the card detects for
-	  channels 0 and 1 are the same.
-
-endchoice
-
-config SMDK6410_WM1190_EV1
-	bool "Support Wolfson Microelectronics 1190-EV1 PMIC card"
-	depends on MACH_SMDK6410
-	select REGULATOR
-	select REGULATOR_WM8350
-	select S3C24XX_GPIO_EXTRA64
-	select MFD_WM8350_I2C
-	select MFD_WM8350_CONFIG_MODE_0
-	select MFD_WM8350_CONFIG_MODE_3
-	select MFD_WM8352_CONFIG_MODE_0
-	help
-	  The Wolfson Microelectronics 1190-EV1 is a WM835x based PMIC
-	  and audio daughtercard for the Samsung SMDK6410 reference
-	  platform.  Enabling this option will build support for this
-	  module into the kernel.  The presence of the module will be
-	  detected at runtime so the the resulting kernel can be used
-	  with or without the 1190-EV1 fitted.
-
-config MACH_NCP
-	bool "NCP"
-	select CPU_S3C6410
-	select S3C_DEV_I2C1
-	select S3C_DEV_HSMMC1
-	select S3C64XX_SETUP_I2C1
-	help
-          Machine support for the Samsung NCP
-
-config MACH_HMT
-	bool "Airgoo HMT"
-	select CPU_S3C6410
-	select S3C_DEV_FB
-	select S3C_DEV_NAND
-	select S3C_DEV_USB_HOST
-	select S3C64XX_SETUP_FB_24BPP
-	select HAVE_PWM
-	help
-	  Machine support for the Airgoo HMT
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/mach-anw6410.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/mach-anw6410.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/mach-anw6410.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/mach-anw6410.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,245 +0,0 @@
-/* linux/arch/arm/mach-s3c6410/mach-anw6410.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- * Copyright 2009 Kwangwoo Lee
- * 	Kwangwoo Lee <kwangwoo.lee@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/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/fb.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/dm9000.h>
-
-#include <video/platform_lcd.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-fb.h>
-#include <mach/map.h>
-
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <plat/iic.h>
-#include <plat/fb.h>
-
-#include <plat/s3c6410.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/regs-gpio.h>
-#include <plat/regs-modem.h>
-
-/* DM9000 */
-#define ANW6410_PA_DM9000	(0x18000000)
-
-/* A hardware buffer to control external devices is mapped at 0x30000000.
- * It can not be read. So current status must be kept in anw6410_extdev_status.
- */
-#define ANW6410_VA_EXTDEV	S3C_ADDR(0x02000000)
-#define ANW6410_PA_EXTDEV	(0x30000000)
-
-#define ANW6410_EN_DM9000	(1<<11)
-#define ANW6410_EN_LCD		(1<<14)
-
-static __u32 anw6410_extdev_status;
-
-static struct s3c2410_uartcfg anw6410_uartcfgs[] __initdata = {
-	[0] = {
-		.hwport	     = 0,
-		.flags	     = 0,
-		.ucon	     = 0x3c5,
-		.ulcon	     = 0x03,
-		.ufcon	     = 0x51,
-	},
-	[1] = {
-		.hwport	     = 1,
-		.flags	     = 0,
-		.ucon	     = 0x3c5,
-		.ulcon	     = 0x03,
-		.ufcon	     = 0x51,
-	},
-};
-
-/* framebuffer and LCD setup. */
-static void __init anw6410_lcd_mode_set(void)
-{
-	u32 tmp;
-
-	/* set the LCD type */
-	tmp = __raw_readl(S3C64XX_SPCON);
-	tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
-	tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
-	__raw_writel(tmp, S3C64XX_SPCON);
-
-	/* remove the LCD bypass */
-	tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
-	tmp &= ~MIFPCON_LCD_BYPASS;
-	__raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
-}
-
-/* GPF1 = LCD panel power
- * GPF4 = LCD backlight control
- */
-static void anw6410_lcd_power_set(struct plat_lcd_data *pd,
-				   unsigned int power)
-{
-	if (power) {
-		anw6410_extdev_status |= (ANW6410_EN_LCD << 16);
-		__raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
-
-		gpio_direction_output(S3C64XX_GPF(1), 1);
-		gpio_direction_output(S3C64XX_GPF(4), 1);
-	} else {
-		anw6410_extdev_status &= ~(ANW6410_EN_LCD << 16);
-		__raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
-
-		gpio_direction_output(S3C64XX_GPF(1), 0);
-		gpio_direction_output(S3C64XX_GPF(4), 0);
-	}
-}
-
-static struct plat_lcd_data anw6410_lcd_power_data = {
-	.set_power	= anw6410_lcd_power_set,
-};
-
-static struct platform_device anw6410_lcd_powerdev = {
-	.name			= "platform-lcd",
-	.dev.parent		= &s3c_device_fb.dev,
-	.dev.platform_data	= &anw6410_lcd_power_data,
-};
-
-static struct s3c_fb_pd_win anw6410_fb_win0 = {
-	/* this is to ensure we use win0 */
-	.win_mode	= {
-		.pixclock	= 41094,
-		.left_margin	= 8,
-		.right_margin	= 13,
-		.upper_margin	= 7,
-		.lower_margin	= 5,
-		.hsync_len	= 3,
-		.vsync_len	= 1,
-		.xres		= 800,
-		.yres		= 480,
-	},
-	.max_bpp	= 32,
-	.default_bpp	= 16,
-};
-
-/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
-static struct s3c_fb_platdata anw6410_lcd_pdata __initdata = {
-	.setup_gpio	= s3c64xx_fb_gpio_setup_24bpp,
-	.win[0]		= &anw6410_fb_win0,
-	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
-	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-};
-
-/* DM9000AEP 10/100 ethernet controller */
-static void __init anw6410_dm9000_enable(void)
-{
-	anw6410_extdev_status |= (ANW6410_EN_DM9000 << 16);
-	__raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
-}
-
-static struct resource anw6410_dm9000_resource[] = {
-	[0] = {
-		.start = ANW6410_PA_DM9000,
-		.end   = ANW6410_PA_DM9000 + 3,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = ANW6410_PA_DM9000 + 4,
-		.end   = ANW6410_PA_DM9000 + 4 + 500,
-		.flags = IORESOURCE_MEM,
-	},
-	[2] = {
-		.start = IRQ_EINT(15),
-		.end   = IRQ_EINT(15),
-		.flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
-	},
-};
-
-static struct dm9000_plat_data anw6410_dm9000_pdata = {
-	.flags	  = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
-	/* dev_addr can be set to provide hwaddr. */
-};
-
-static struct platform_device anw6410_device_eth = {
-	.name	= "dm9000",
-	.id	= -1,
-	.num_resources	= ARRAY_SIZE(anw6410_dm9000_resource),
-	.resource	= anw6410_dm9000_resource,
-	.dev	= {
-		.platform_data  = &anw6410_dm9000_pdata,
-	},
-};
-
-static struct map_desc anw6410_iodesc[] __initdata = {
-	{
-		.virtual	= (unsigned long)ANW6410_VA_EXTDEV,
-		.pfn		= __phys_to_pfn(ANW6410_PA_EXTDEV),
-		.length		= SZ_64K,
-		.type		= MT_DEVICE,
-	},
-};
-
-static struct platform_device *anw6410_devices[] __initdata = {
-	&s3c_device_fb,
-	&anw6410_lcd_powerdev,
-	&anw6410_device_eth,
-};
-
-static void __init anw6410_map_io(void)
-{
-	s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc));
-	s3c24xx_init_clocks(12000000);
-	s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs));
-
-	anw6410_lcd_mode_set();
-}
-
-static void __init anw6410_machine_init(void)
-{
-	s3c_fb_set_platdata(&anw6410_lcd_pdata);
-
-	gpio_request(S3C64XX_GPF(1), "panel power");
-	gpio_request(S3C64XX_GPF(4), "LCD backlight");
-
-	anw6410_dm9000_enable();
-
-	platform_add_devices(anw6410_devices, ARRAY_SIZE(anw6410_devices));
-}
-
-MACHINE_START(ANW6410, "A&W6410")
-	/* Maintainer: Kwangwoo Lee <kwangwoo.lee@gmail.com> */
-	.phys_io	= S3C_PA_UART & 0xfff00000,
-	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
-	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
-
-	.init_irq	= s3c6410_init_irq,
-	.map_io		= anw6410_map_io,
-	.init_machine	= anw6410_machine_init,
-	.timer		= &s3c24xx_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/mach-hmt.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/mach-hmt.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/mach-hmt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/mach-hmt.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,276 +0,0 @@
-/* mach-hmt.c - Platform code for Airgoo HMT
- *
- * Copyright 2009 Peter Korsgaard <jacmet@sunsite.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.
- *
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/fb.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/leds.h>
-#include <linux/pwm_backlight.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-fb.h>
-#include <mach/map.h>
-
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <plat/iic.h>
-#include <plat/fb.h>
-#include <plat/nand.h>
-
-#include <plat/s3c6410.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#define UCON S3C2410_UCON_DEFAULT
-#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
-#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
-
-static struct s3c2410_uartcfg hmt_uartcfgs[] __initdata = {
-	[0] = {
-		.hwport	     = 0,
-		.flags	     = 0,
-		.ucon	     = UCON,
-		.ulcon	     = ULCON,
-		.ufcon	     = UFCON,
-	},
-	[1] = {
-		.hwport	     = 1,
-		.flags	     = 0,
-		.ucon	     = UCON,
-		.ulcon	     = ULCON,
-		.ufcon	     = UFCON,
-	},
-	[2] = {
-		.hwport	     = 2,
-		.flags	     = 0,
-		.ucon	     = UCON,
-		.ulcon	     = ULCON,
-		.ufcon	     = UFCON,
-	},
-};
-
-static int hmt_bl_init(struct device *dev)
-{
-	int ret;
-
-	ret = gpio_request(S3C64XX_GPB(4), "lcd backlight enable");
-	if (!ret)
-		ret = gpio_direction_output(S3C64XX_GPB(4), 0);
-
-	return ret;
-}
-
-static int hmt_bl_notify(struct device *dev, int brightness)
-{
-	/*
-	 * translate from CIELUV/CIELAB L*->brightness, E.G. from
-	 * perceived luminance to light output. Assumes range 0..25600
-	 */
-	if (brightness < 0x800) {
-		/* Y = Yn * L / 903.3 */
-		brightness = (100*256 * brightness + 231245/2) / 231245;
-	} else {
-		/* Y = Yn * ((L + 16) / 116 )^3 */
-		int t = (brightness*4 + 16*1024 + 58)/116;
-		brightness = 25 * ((t * t * t + 0x100000/2) / 0x100000);
-	}
-
-	gpio_set_value(S3C64XX_GPB(4), brightness);
-
-	return brightness;
-}
-
-static void hmt_bl_exit(struct device *dev)
-{
-	gpio_free(S3C64XX_GPB(4));
-}
-
-static struct platform_pwm_backlight_data hmt_backlight_data = {
-	.pwm_id		= 1,
-	.max_brightness	= 100 * 256,
-	.dft_brightness	= 40 * 256,
-	.pwm_period_ns	= 1000000000 / (100 * 256 * 20),
-	.init		= hmt_bl_init,
-	.notify		= hmt_bl_notify,
-	.exit		= hmt_bl_exit,
-
-};
-
-static struct platform_device hmt_backlight_device = {
-	.name		= "pwm-backlight",
-	.dev		= {
-		.parent	= &s3c_device_timer[1].dev,
-		.platform_data = &hmt_backlight_data,
-	},
-};
-
-static struct s3c_fb_pd_win hmt_fb_win0 = {
-	.win_mode	= {
-		.pixclock	= 41094,
-		.left_margin	= 8,
-		.right_margin	= 13,
-		.upper_margin	= 7,
-		.lower_margin	= 5,
-		.hsync_len	= 3,
-		.vsync_len	= 1,
-		.xres		= 800,
-		.yres		= 480,
-	},
-	.max_bpp	= 32,
-	.default_bpp	= 16,
-};
-
-/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
-static struct s3c_fb_platdata hmt_lcd_pdata __initdata = {
-	.setup_gpio	= s3c64xx_fb_gpio_setup_24bpp,
-	.win[0]		= &hmt_fb_win0,
-	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
-	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-};
-
-static struct mtd_partition hmt_nand_part[] = {
-	[0] = {
-		.name	= "uboot",
-		.size	= SZ_512K,
-		.offset	= 0,
-	},
-	[1] = {
-		.name	= "uboot-env1",
-		.size	= SZ_256K,
-		.offset	= SZ_512K,
-	},
-	[2] = {
-		.name	= "uboot-env2",
-		.size	= SZ_256K,
-		.offset	= SZ_512K + SZ_256K,
-	},
-	[3] = {
-		.name	= "kernel",
-		.size	= SZ_2M,
-		.offset	= SZ_1M,
-	},
-	[4] = {
-		.name	= "rootfs",
-		.size	= MTDPART_SIZ_FULL,
-		.offset	= SZ_1M + SZ_2M,
-	},
-};
-
-static struct s3c2410_nand_set hmt_nand_sets[] = {
-	[0] = {
-		.name		= "nand",
-		.nr_chips	= 1,
-		.nr_partitions	= ARRAY_SIZE(hmt_nand_part),
-		.partitions	= hmt_nand_part,
-	},
-};
-
-static struct s3c2410_platform_nand hmt_nand_info = {
-	.tacls		= 25,
-	.twrph0		= 55,
-	.twrph1		= 40,
-	.nr_sets	= ARRAY_SIZE(hmt_nand_sets),
-	.sets		= hmt_nand_sets,
-};
-
-static struct gpio_led hmt_leds[] = {
-	{ /* left function keys */
-		.name			= "left:blue",
-		.gpio			= S3C64XX_GPO(12),
-		.default_trigger	= "default-on",
-	},
-	{ /* right function keys - red */
-		.name			= "right:red",
-		.gpio			= S3C64XX_GPO(13),
-	},
-	{ /* right function keys - green */
-		.name			= "right:green",
-		.gpio			= S3C64XX_GPO(14),
-	},
-	{ /* right function keys - blue */
-		.name			= "right:blue",
-		.gpio			= S3C64XX_GPO(15),
-		.default_trigger	= "default-on",
-	},
-};
-
-static struct gpio_led_platform_data hmt_led_data = {
-	.num_leds = ARRAY_SIZE(hmt_leds),
-	.leds = hmt_leds,
-};
-
-static struct platform_device hmt_leds_device = {
-	.name			= "leds-gpio",
-	.id			= -1,
-	.dev.platform_data	= &hmt_led_data,
-};
-
-static struct map_desc hmt_iodesc[] = {};
-
-static struct platform_device *hmt_devices[] __initdata = {
-	&s3c_device_i2c0,
-	&s3c_device_nand,
-	&s3c_device_fb,
-	&s3c_device_usb,
-	&s3c_device_timer[1],
-	&hmt_backlight_device,
-	&hmt_leds_device,
-};
-
-static void __init hmt_map_io(void)
-{
-	s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc));
-	s3c24xx_init_clocks(12000000);
-	s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs));
-}
-
-static void __init hmt_machine_init(void)
-{
-	s3c_i2c0_set_platdata(NULL);
-	s3c_fb_set_platdata(&hmt_lcd_pdata);
-	s3c_nand_set_platdata(&hmt_nand_info);
-
-	gpio_request(S3C64XX_GPC(7), "usb power");
-	gpio_direction_output(S3C64XX_GPC(7), 0);
-	gpio_request(S3C64XX_GPM(0), "usb power");
-	gpio_direction_output(S3C64XX_GPM(0), 1);
-	gpio_request(S3C64XX_GPK(7), "usb power");
-	gpio_direction_output(S3C64XX_GPK(7), 1);
-	gpio_request(S3C64XX_GPF(13), "usb power");
-	gpio_direction_output(S3C64XX_GPF(13), 1);
-
-	platform_add_devices(hmt_devices, ARRAY_SIZE(hmt_devices));
-}
-
-MACHINE_START(HMT, "Airgoo-HMT")
-	/* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */
-	.phys_io	= S3C_PA_UART & 0xfff00000,
-	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
-	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
-	.init_irq	= s3c6410_init_irq,
-	.map_io		= hmt_map_io,
-	.init_machine	= hmt_machine_init,
-	.timer		= &s3c24xx_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/mach-ncp.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/mach-ncp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/mach-ncp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/mach-ncp.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,107 +0,0 @@
-/*
- * linux/arch/arm/mach-s3c6410/mach-ncp.c
- *
- * Copyright (C) 2008-2009 Samsung Electronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/fb.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-
-#include <video/platform_lcd.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-fb.h>
-#include <mach/map.h>
-
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <plat/iic.h>
-#include <plat/fb.h>
-
-#include <plat/s3c6410.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#define UCON S3C2410_UCON_DEFAULT
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg ncp_uartcfgs[] __initdata = {
-	/* REVISIT: NCP uses only serial 1, 2 */
-	[0] = {
-		.hwport	     = 0,
-		.flags	     = 0,
-		.ucon	     = UCON,
-		.ulcon	     = ULCON,
-		.ufcon	     = UFCON,
-	},
-	[1] = {
-		.hwport	     = 1,
-		.flags	     = 0,
-		.ucon	     = UCON,
-		.ulcon	     = ULCON,
-		.ufcon	     = UFCON,
-	},
-	[2] = {
-		.hwport	     = 2,
-		.flags	     = 0,
-		.ucon	     = UCON,
-		.ulcon	     = ULCON,
-		.ufcon	     = UFCON,
-	},
-};
-
-static struct platform_device *ncp_devices[] __initdata = {
-	&s3c_device_hsmmc1,
-	&s3c_device_i2c0,
-};
-
-static struct map_desc ncp_iodesc[] __initdata = {};
-
-static void __init ncp_map_io(void)
-{
-	s3c64xx_init_io(ncp_iodesc, ARRAY_SIZE(ncp_iodesc));
-	s3c24xx_init_clocks(12000000);
-	s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs));
-}
-
-static void __init ncp_machine_init(void)
-{
-	s3c_i2c0_set_platdata(NULL);
-
-	platform_add_devices(ncp_devices, ARRAY_SIZE(ncp_devices));
-}
-
-MACHINE_START(NCP, "NCP")
-	/* Maintainer: Samsung Electronics */
-	.phys_io	= S3C_PA_UART & 0xfff00000,
-	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
-	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
-	.init_irq	= s3c6410_init_irq,
-	.map_io		= ncp_map_io,
-	.init_machine	= ncp_machine_init,
-	.timer		= &s3c24xx_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/mach-smdk6410.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/mach-smdk6410.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/mach-smdk6410.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/mach-smdk6410.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,457 +0,0 @@
-/* linux/arch/arm/mach-s3c6410/mach-smdk6410.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/fb.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/smsc911x.h>
-#include <linux/regulator/fixed.h>
-
-#ifdef CONFIG_SMDK6410_WM1190_EV1
-#include <linux/mfd/wm8350/core.h>
-#include <linux/mfd/wm8350/pmic.h>
-#endif
-
-#include <video/platform_lcd.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-fb.h>
-#include <mach/map.h>
-
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <plat/regs-modem.h>
-#include <plat/regs-gpio.h>
-#include <plat/regs-sys.h>
-#include <plat/iic.h>
-#include <plat/fb.h>
-#include <plat/gpio-cfg.h>
-
-#include <plat/s3c6410.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg smdk6410_uartcfgs[] __initdata = {
-	[0] = {
-		.hwport	     = 0,
-		.flags	     = 0,
-		.ucon	     = UCON,
-		.ulcon	     = ULCON,
-		.ufcon	     = UFCON,
-	},
-	[1] = {
-		.hwport	     = 1,
-		.flags	     = 0,
-		.ucon	     = UCON,
-		.ulcon	     = ULCON,
-		.ufcon	     = UFCON,
-	},
-	[2] = {
-		.hwport	     = 2,
-		.flags	     = 0,
-		.ucon	     = UCON,
-		.ulcon	     = ULCON,
-		.ufcon	     = UFCON,
-	},
-	[3] = {
-		.hwport	     = 3,
-		.flags	     = 0,
-		.ucon	     = UCON,
-		.ulcon	     = ULCON,
-		.ufcon	     = UFCON,
-	},
-};
-
-/* framebuffer and LCD setup. */
-
-/* GPF15 = LCD backlight control
- * GPF13 => Panel power
- * GPN5 = LCD nRESET signal
- * PWM_TOUT1 => backlight brightness
- */
-
-static void smdk6410_lcd_power_set(struct plat_lcd_data *pd,
-				   unsigned int power)
-{
-	if (power) {
-		gpio_direction_output(S3C64XX_GPF(13), 1);
-		gpio_direction_output(S3C64XX_GPF(15), 1);
-
-		/* fire nRESET on power up */
-		gpio_direction_output(S3C64XX_GPN(5), 0);
-		msleep(10);
-		gpio_direction_output(S3C64XX_GPN(5), 1);
-		msleep(1);
-	} else {
-		gpio_direction_output(S3C64XX_GPF(15), 0);
-		gpio_direction_output(S3C64XX_GPF(13), 0);
-	}
-}
-
-static struct plat_lcd_data smdk6410_lcd_power_data = {
-	.set_power	= smdk6410_lcd_power_set,
-};
-
-static struct platform_device smdk6410_lcd_powerdev = {
-	.name			= "platform-lcd",
-	.dev.parent		= &s3c_device_fb.dev,
-	.dev.platform_data	= &smdk6410_lcd_power_data,
-};
-
-static struct s3c_fb_pd_win smdk6410_fb_win0 = {
-	/* this is to ensure we use win0 */
-	.win_mode	= {
-		.pixclock	= 41094,
-		.left_margin	= 8,
-		.right_margin	= 13,
-		.upper_margin	= 7,
-		.lower_margin	= 5,
-		.hsync_len	= 3,
-		.vsync_len	= 1,
-		.xres		= 800,
-		.yres		= 480,
-	},
-	.max_bpp	= 32,
-	.default_bpp	= 16,
-};
-
-/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
-static struct s3c_fb_platdata smdk6410_lcd_pdata __initdata = {
-	.setup_gpio	= s3c64xx_fb_gpio_setup_24bpp,
-	.win[0]		= &smdk6410_fb_win0,
-	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
-	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-};
-
-static struct resource smdk6410_smsc911x_resources[] = {
-	[0] = {
-		.start = 0x18000000,
-		.end   = 0x18000000 + SZ_64K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = S3C_EINT(10),
-		.end   = S3C_EINT(10),
-		.flags = IORESOURCE_IRQ | IRQ_TYPE_LEVEL_LOW,
-	},
-};
-
-static struct smsc911x_platform_config smdk6410_smsc911x_pdata = {
-	.irq_polarity  = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type      = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
-	.flags         = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY,
-	.phy_interface = PHY_INTERFACE_MODE_MII,
-};
-
-
-static struct platform_device smdk6410_smsc911x = {
-	.name          = "smsc911x",
-	.id            = -1,
-	.num_resources = ARRAY_SIZE(smdk6410_smsc911x_resources),
-	.resource      = &smdk6410_smsc911x_resources[0],
-	.dev = {
-		.platform_data = &smdk6410_smsc911x_pdata,
-	},
-};
-
-#ifdef CONFIG_REGULATOR
-static struct regulator_consumer_supply smdk6410_b_pwr_5v_consumers[] = {
-	{
-		/* WM8580 */
-		.supply = "PVDD",
-		.dev_name = "0-001b",
-	},
-	{
-		/* WM8580 */
-		.supply = "AVDD",
-		.dev_name = "0-001b",
-	},
-};
-
-static struct regulator_init_data smdk6410_b_pwr_5v_data = {
-	.constraints = {
-		.always_on = 1,
-	},
-	.num_consumer_supplies = ARRAY_SIZE(smdk6410_b_pwr_5v_consumers),
-	.consumer_supplies = smdk6410_b_pwr_5v_consumers,
-};
-
-static struct fixed_voltage_config smdk6410_b_pwr_5v_pdata = {
-	.supply_name = "B_PWR_5V",
-	.microvolts = 5000000,
-	.init_data = &smdk6410_b_pwr_5v_data,
-	.gpio = -EINVAL,
-};
-
-static struct platform_device smdk6410_b_pwr_5v = {
-	.name          = "reg-fixed-voltage",
-	.id            = -1,
-	.dev = {
-		.platform_data = &smdk6410_b_pwr_5v_pdata,
-	},
-};
-#endif
-
-static struct map_desc smdk6410_iodesc[] = {};
-
-static struct platform_device *smdk6410_devices[] __initdata = {
-#ifdef CONFIG_SMDK6410_SD_CH0
-	&s3c_device_hsmmc0,
-#endif
-#ifdef CONFIG_SMDK6410_SD_CH1
-	&s3c_device_hsmmc1,
-#endif
-	&s3c_device_i2c0,
-	&s3c_device_i2c1,
-	&s3c_device_fb,
-	&s3c_device_usb,
-	&s3c_device_usb_hsotg,
-
-#ifdef CONFIG_REGULATOR
-	&smdk6410_b_pwr_5v,
-#endif
-	&smdk6410_lcd_powerdev,
-
-	&smdk6410_smsc911x,
-};
-
-#ifdef CONFIG_SMDK6410_WM1190_EV1
-/* S3C64xx internal logic & PLL */
-static struct regulator_init_data wm8350_dcdc1_data = {
-	.constraints = {
-		.name = "PVDD_INT/PVDD_PLL",
-		.min_uV = 1200000,
-		.max_uV = 1200000,
-		.always_on = 1,
-		.apply_uV = 1,
-	},
-};
-
-/* Memory */
-static struct regulator_init_data wm8350_dcdc3_data = {
-	.constraints = {
-		.name = "PVDD_MEM",
-		.min_uV = 1800000,
-		.max_uV = 1800000,
-		.always_on = 1,
-		.state_mem = {
-			 .uV = 1800000,
-			 .mode = REGULATOR_MODE_NORMAL,
-			 .enabled = 1,
-		 },
-		.initial_state = PM_SUSPEND_MEM,
-	},
-};
-
-/* USB, EXT, PCM, ADC/DAC, USB, MMC */
-static struct regulator_consumer_supply wm8350_dcdc4_consumers[] = {
-	{
-		/* WM8580 */
-		.supply = "DVDD",
-		.dev_name = "0-001b",
-	},
-};
-
-static struct regulator_init_data wm8350_dcdc4_data = {
-	.constraints = {
-		.name = "PVDD_HI/PVDD_EXT/PVDD_SYS/PVCCM2MTV",
-		.min_uV = 3000000,
-		.max_uV = 3000000,
-		.always_on = 1,
-	},
-	.num_consumer_supplies = ARRAY_SIZE(wm8350_dcdc4_consumers),
-	.consumer_supplies = wm8350_dcdc4_consumers,
-};
-
-/* ARM core */
-static struct regulator_consumer_supply dcdc6_consumers[] = {
-	{
-		.supply = "vddarm",
-	}
-};
-
-static struct regulator_init_data wm8350_dcdc6_data = {
-	.constraints = {
-		.name = "PVDD_ARM",
-		.min_uV = 1000000,
-		.max_uV = 1300000,
-		.always_on = 1,
-		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
-	},
-	.num_consumer_supplies = ARRAY_SIZE(dcdc6_consumers),
-	.consumer_supplies = dcdc6_consumers,
-};
-
-/* Alive */
-static struct regulator_init_data wm8350_ldo1_data = {
-	.constraints = {
-		.name = "PVDD_ALIVE",
-		.min_uV = 1200000,
-		.max_uV = 1200000,
-		.always_on = 1,
-		.apply_uV = 1,
-	},
-};
-
-/* OTG */
-static struct regulator_init_data wm8350_ldo2_data = {
-	.constraints = {
-		.name = "PVDD_OTG",
-		.min_uV = 3300000,
-		.max_uV = 3300000,
-		.always_on = 1,
-	},
-};
-
-/* LCD */
-static struct regulator_init_data wm8350_ldo3_data = {
-	.constraints = {
-		.name = "PVDD_LCD",
-		.min_uV = 3000000,
-		.max_uV = 3000000,
-		.always_on = 1,
-	},
-};
-
-/* OTGi/1190-EV1 HPVDD & AVDD */
-static struct regulator_init_data wm8350_ldo4_data = {
-	.constraints = {
-		.name = "PVDD_OTGI/HPVDD/AVDD",
-		.min_uV = 1200000,
-		.max_uV = 1200000,
-		.apply_uV = 1,
-		.always_on = 1,
-	},
-};
-
-static struct {
-	int regulator;
-	struct regulator_init_data *initdata;
-} wm1190_regulators[] = {
-	{ WM8350_DCDC_1, &wm8350_dcdc1_data },
-	{ WM8350_DCDC_3, &wm8350_dcdc3_data },
-	{ WM8350_DCDC_4, &wm8350_dcdc4_data },
-	{ WM8350_DCDC_6, &wm8350_dcdc6_data },
-	{ WM8350_LDO_1, &wm8350_ldo1_data },
-	{ WM8350_LDO_2, &wm8350_ldo2_data },
-	{ WM8350_LDO_3, &wm8350_ldo3_data },
-	{ WM8350_LDO_4, &wm8350_ldo4_data },
-};
-
-static int __init smdk6410_wm8350_init(struct wm8350 *wm8350)
-{
-	int i;
-
-	/* Configure the IRQ line */
-	s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_UP);
-
-	/* Instantiate the regulators */
-	for (i = 0; i < ARRAY_SIZE(wm1190_regulators); i++)
-		wm8350_register_regulator(wm8350,
-					  wm1190_regulators[i].regulator,
-					  wm1190_regulators[i].initdata);
-
-	return 0;
-}
-
-static struct wm8350_platform_data __initdata smdk6410_wm8350_pdata = {
-	.init = smdk6410_wm8350_init,
-	.irq_high = 1,
-};
-#endif
-
-static struct i2c_board_info i2c_devs0[] __initdata = {
-	{ I2C_BOARD_INFO("24c08", 0x50), },
-	{ I2C_BOARD_INFO("wm8580", 0x1b), },
-
-#ifdef CONFIG_SMDK6410_WM1190_EV1
-	{ I2C_BOARD_INFO("wm8350", 0x1a),
-	  .platform_data = &smdk6410_wm8350_pdata,
-	  .irq = S3C_EINT(12),
-	},
-#endif
-};
-
-static struct i2c_board_info i2c_devs1[] __initdata = {
-	{ I2C_BOARD_INFO("24c128", 0x57), },	/* Samsung S524AD0XD1 */
-};
-
-static void __init smdk6410_map_io(void)
-{
-	u32 tmp;
-
-	s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc));
-	s3c24xx_init_clocks(12000000);
-	s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs));
-
-	/* set the LCD type */
-
-	tmp = __raw_readl(S3C64XX_SPCON);
-	tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
-	tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
-	__raw_writel(tmp, S3C64XX_SPCON);
-
-	/* remove the lcd bypass */
-	tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
-	tmp &= ~MIFPCON_LCD_BYPASS;
-	__raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
-}
-
-static void __init smdk6410_machine_init(void)
-{
-	s3c_i2c0_set_platdata(NULL);
-	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));
-
-	platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
-}
-
-MACHINE_START(SMDK6410, "SMDK6410")
-	/* Maintainer: Ben Dooks <ben@fluff.org> */
-	.phys_io	= S3C_PA_UART & 0xfff00000,
-	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
-	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
-
-	.init_irq	= s3c6410_init_irq,
-	.map_io		= smdk6410_map_io,
-	.init_machine	= smdk6410_machine_init,
-	.timer		= &s3c24xx_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-# arch/arm/plat-s3c6410/Makefile
-#
-# Copyright 2008 Openmoko, Inc.
-# Copyright 2008 Simtec Electronics
-#
-# Licensed under GPLv2
-
-obj-y				:=
-obj-m				:=
-obj-n				:=
-obj-				:=
-
-# Core support for S3C6410 system
-
-obj-$(CONFIG_CPU_S3C6410)	+= cpu.o
-
-# Helper and device support
-
-obj-$(CONFIG_S3C6410_SETUP_SDHCI)	+= setup-sdhci.o
-
-# machine support
-
-obj-$(CONFIG_MACH_ANW6410)	+= mach-anw6410.o
-obj-$(CONFIG_MACH_SMDK6410)	+= mach-smdk6410.o
-obj-$(CONFIG_MACH_NCP)		+= mach-ncp.o
-obj-$(CONFIG_MACH_HMT)		+= mach-hmt.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/setup-sdhci.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/setup-sdhci.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/setup-sdhci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c6410/setup-sdhci.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,68 +0,0 @@
-/* linux/arch/arm/mach-s3c6410/setup-sdhci.c
- *
- * Copyright 2008 Simtec Electronics
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C6410 - Helper functions for settign up SDHCI device(s) (HSMMC)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
-
-#include <plat/regs-sdhci.h>
-#include <plat/sdhci.h>
-
-/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
-
-char *s3c6410_hsmmc_clksrcs[4] = {
-	[0] = "hsmmc",
-	[1] = "hsmmc",
-	[2] = "mmc_bus",
-	/* [3] = "48m", - note not successfully used yet */
-};
-
-
-void s3c6410_setup_sdhci0_cfg_card(struct platform_device *dev,
-				    void __iomem *r,
-				    struct mmc_ios *ios,
-				    struct mmc_card *card)
-{
-	u32 ctrl2, ctrl3;
-
-	/* don't need to alter anything acording to card-type */
-
-	writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
-
-	ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
-	ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
-	ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
-		  S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
-		  S3C_SDHCI_CTRL2_ENFBCLKRX |
-		  S3C_SDHCI_CTRL2_DFCNT_NONE |
-		  S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
-
-	if (ios->clock < 25 * 1000000)
-		ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
-			 S3C_SDHCI_CTRL3_FCSEL2 |
-			 S3C_SDHCI_CTRL3_FCSEL1 |
-			 S3C_SDHCI_CTRL3_FCSEL0);
-	else
-		ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
-
-	printk(KERN_INFO "%s: CTRL 2=%08x, 3=%08x\n", __func__, ctrl2, ctrl3);
-	writel(ctrl2, r + S3C_SDHCI_CONTROL2);
-	writel(ctrl3, r + S3C_SDHCI_CONTROL3);
-}
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/clock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,809 @@
+/* linux/arch/arm/plat-s3c64xx/clock.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX Base clock 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/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <mach/regs-sys.h>
+#include <mach/regs-clock.h>
+#include <mach/pll.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+
+/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
+ * ext_xtal_mux for want of an actual name from the manual.
+*/
+
+static struct clk clk_ext_xtal_mux = {
+	.name		= "ext_xtal",
+	.id		= -1,
+};
+
+#define clk_fin_apll clk_ext_xtal_mux
+#define clk_fin_mpll clk_ext_xtal_mux
+#define clk_fin_epll clk_ext_xtal_mux
+
+#define clk_fout_mpll	clk_mpll
+#define clk_fout_epll	clk_epll
+
+struct clk clk_h2 = {
+	.name		= "hclk2",
+	.id		= -1,
+	.rate		= 0,
+};
+
+struct clk clk_27m = {
+	.name		= "clk_27m",
+	.id		= -1,
+	.rate		= 27000000,
+};
+
+static int clk_48m_ctrl(struct clk *clk, int enable)
+{
+	unsigned long flags;
+	u32 val;
+
+	/* can't rely on clock lock, this register has other usages */
+	local_irq_save(flags);
+
+	val = __raw_readl(S3C64XX_OTHERS);
+	if (enable)
+		val |= S3C64XX_OTHERS_USBMASK;
+	else
+		val &= ~S3C64XX_OTHERS_USBMASK;
+
+	__raw_writel(val, S3C64XX_OTHERS);
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+struct clk clk_48m = {
+	.name		= "clk_48m",
+	.id		= -1,
+	.rate		= 48000000,
+	.enable		= clk_48m_ctrl,
+};
+
+static int inline s3c64xx_gate(void __iomem *reg,
+				struct clk *clk,
+				int enable)
+{
+	unsigned int ctrlbit = clk->ctrlbit;
+	u32 con;
+
+	con = __raw_readl(reg);
+
+	if (enable)
+		con |= ctrlbit;
+	else
+		con &= ~ctrlbit;
+
+	__raw_writel(con, reg);
+	return 0;
+}
+
+static int s3c64xx_pclk_ctrl(struct clk *clk, int enable)
+{
+	return s3c64xx_gate(S3C_PCLK_GATE, clk, enable);
+}
+
+static int s3c64xx_hclk_ctrl(struct clk *clk, int enable)
+{
+	return s3c64xx_gate(S3C_HCLK_GATE, clk, enable);
+}
+
+int s3c64xx_sclk_ctrl(struct clk *clk, int enable)
+{
+	return s3c64xx_gate(S3C_SCLK_GATE, clk, enable);
+}
+
+static struct clk init_clocks_disable[] = {
+	{
+		.name		= "nand",
+		.id		= -1,
+		.parent		= &clk_h,
+	}, {
+		.name		= "adc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c64xx_pclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_PCLK_TSADC,
+	}, {
+		.name		= "i2c",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c64xx_pclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_PCLK_IIC,
+	}, {
+		.name		= "iis",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s3c64xx_pclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_PCLK_IIS0,
+	}, {
+		.name		= "iis",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s3c64xx_pclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_PCLK_IIS1,
+	}, {
+#ifdef CONFIG_CPU_S3C6410
+		.name		= "iis",
+		.id		= -1,  /* There's only one IISv4 port */
+		.parent		= &clk_p,
+		.enable		= s3c64xx_pclk_ctrl,
+		.ctrlbit	= S3C6410_CLKCON_PCLK_IIS2,
+	}, {
+#endif
+		.name		= "spi",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s3c64xx_pclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_PCLK_SPI0,
+	}, {
+		.name		= "spi",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s3c64xx_pclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_PCLK_SPI1,
+	}, {
+		.name		= "spi_48m",
+		.id		= 0,
+		.parent		= &clk_48m,
+		.enable		= s3c64xx_sclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_SCLK_SPI0_48,
+	}, {
+		.name		= "spi_48m",
+		.id		= 1,
+		.parent		= &clk_48m,
+		.enable		= s3c64xx_sclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_SCLK_SPI1_48,
+	}, {
+		.name		= "48m",
+		.id		= 0,
+		.parent		= &clk_48m,
+		.enable		= s3c64xx_sclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_SCLK_MMC0_48,
+	}, {
+		.name		= "48m",
+		.id		= 1,
+		.parent		= &clk_48m,
+		.enable		= s3c64xx_sclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_SCLK_MMC1_48,
+	}, {
+		.name		= "48m",
+		.id		= 2,
+		.parent		= &clk_48m,
+		.enable		= s3c64xx_sclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_SCLK_MMC2_48,
+	}, {
+		.name		= "dma0",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_DMA0,
+	}, {
+		.name		= "dma1",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_DMA1,
+	},
+};
+
+static struct clk init_clocks[] = {
+	{
+		.name		= "lcd",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_LCD,
+	}, {
+		.name		= "gpio",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c64xx_pclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_PCLK_GPIO,
+	}, {
+		.name		= "usb-host",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_UHOST,
+	}, {
+		.name		= "hsmmc",
+		.id		= 0,
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_HSMMC0,
+	}, {
+		.name		= "hsmmc",
+		.id		= 1,
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_HSMMC1,
+	}, {
+		.name		= "hsmmc",
+		.id		= 2,
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_HSMMC2,
+	}, {
+		.name		= "timers",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c64xx_pclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_PCLK_PWM,
+	}, {
+		.name		= "uart",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s3c64xx_pclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_PCLK_UART0,
+	}, {
+		.name		= "uart",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s3c64xx_pclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_PCLK_UART1,
+	}, {
+		.name		= "uart",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s3c64xx_pclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_PCLK_UART2,
+	}, {
+		.name		= "uart",
+		.id		= 3,
+		.parent		= &clk_p,
+		.enable		= s3c64xx_pclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_PCLK_UART3,
+	}, {
+		.name		= "rtc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c64xx_pclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_PCLK_RTC,
+	}, {
+		.name		= "watchdog",
+		.id		= -1,
+		.parent		= &clk_p,
+		.ctrlbit	= S3C_CLKCON_PCLK_WDT,
+	}, {
+		.name		= "ac97",
+		.id		= -1,
+		.parent		= &clk_p,
+		.ctrlbit	= S3C_CLKCON_PCLK_AC97,
+	}
+};
+
+
+static struct clk clk_fout_apll = {
+	.name		= "fout_apll",
+	.id		= -1,
+};
+
+static struct clk *clk_src_apll_list[] = {
+	[0] = &clk_fin_apll,
+	[1] = &clk_fout_apll,
+};
+
+static struct clksrc_sources clk_src_apll = {
+	.sources	= clk_src_apll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_apll_list),
+};
+
+static struct clksrc_clk clk_mout_apll = {
+	.clk	= {
+		.name		= "mout_apll",
+		.id		= -1,
+	},
+	.reg_src	= { .reg = S3C_CLK_SRC, .shift = 0, .size = 1  },
+	.sources	= &clk_src_apll,
+};
+
+static struct clk *clk_src_epll_list[] = {
+	[0] = &clk_fin_epll,
+	[1] = &clk_fout_epll,
+};
+
+static struct clksrc_sources clk_src_epll = {
+	.sources	= clk_src_epll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_epll_list),
+};
+
+static struct clksrc_clk clk_mout_epll = {
+	.clk	= {
+		.name		= "mout_epll",
+		.id		= -1,
+	},
+	.reg_src	= { .reg = S3C_CLK_SRC, .shift = 2, .size = 1  },
+	.sources	= &clk_src_epll,
+};
+
+static struct clk *clk_src_mpll_list[] = {
+	[0] = &clk_fin_mpll,
+	[1] = &clk_fout_mpll,
+};
+
+static struct clksrc_sources clk_src_mpll = {
+	.sources	= clk_src_mpll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_mpll_list),
+};
+
+static struct clksrc_clk clk_mout_mpll = {
+	.clk = {
+		.name		= "mout_mpll",
+		.id		= -1,
+	},
+	.reg_src	= { .reg = S3C_CLK_SRC, .shift = 1, .size = 1  },
+	.sources	= &clk_src_mpll,
+};
+
+static unsigned int armclk_mask;
+
+static unsigned long s3c64xx_clk_arm_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	u32 clkdiv;
+
+	/* divisor mask starts at bit0, so no need to shift */
+	clkdiv = __raw_readl(S3C_CLK_DIV0) & armclk_mask;
+
+	return rate / (clkdiv + 1);
+}
+
+static unsigned long s3c64xx_clk_arm_round_rate(struct clk *clk,
+						unsigned long rate)
+{
+	unsigned long parent = clk_get_rate(clk->parent);
+	u32 div;
+
+	if (parent < rate)
+		return parent;
+
+	div = (parent / rate) - 1;
+	if (div > armclk_mask)
+		div = armclk_mask;
+
+	return parent / (div + 1);
+}
+
+static int s3c64xx_clk_arm_set_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent = clk_get_rate(clk->parent);
+	u32 div;
+	u32 val;
+
+	if (rate < parent / (armclk_mask + 1))
+		return -EINVAL;
+
+	rate = clk_round_rate(clk, rate);
+	div = clk_get_rate(clk->parent) / rate;
+
+	val = __raw_readl(S3C_CLK_DIV0);
+	val &= ~armclk_mask;
+	val |= (div - 1);
+	__raw_writel(val, S3C_CLK_DIV0);
+
+	return 0;
+
+}
+
+static struct clk clk_arm = {
+	.name		= "armclk",
+	.id		= -1,
+	.parent		= &clk_mout_apll.clk,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c64xx_clk_arm_get_rate,
+		.set_rate	= s3c64xx_clk_arm_set_rate,
+		.round_rate	= s3c64xx_clk_arm_round_rate,
+	},
+};
+
+static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
+
+	if (__raw_readl(S3C_CLK_DIV0) & S3C6400_CLKDIV0_MPLL_MASK)
+		rate /= 2;
+
+	return rate;
+}
+
+static struct clk_ops clk_dout_ops = {
+	.get_rate	= s3c64xx_clk_doutmpll_get_rate,
+};
+
+static struct clk clk_dout_mpll = {
+	.name		= "dout_mpll",
+	.id		= -1,
+	.parent		= &clk_mout_mpll.clk,
+	.ops		= &clk_dout_ops,
+};
+
+static struct clk *clkset_spi_mmc_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_fin_epll,
+	&clk_27m,
+};
+
+static struct clksrc_sources clkset_spi_mmc = {
+	.sources	= clkset_spi_mmc_list,
+	.nr_sources	= ARRAY_SIZE(clkset_spi_mmc_list),
+};
+
+static struct clk *clkset_irda_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	NULL,
+	&clk_27m,
+};
+
+static struct clksrc_sources clkset_irda = {
+	.sources	= clkset_irda_list,
+	.nr_sources	= ARRAY_SIZE(clkset_irda_list),
+};
+
+static struct clk *clkset_uart_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	NULL,
+	NULL
+};
+
+static struct clksrc_sources clkset_uart = {
+	.sources	= clkset_uart_list,
+	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clk *clkset_uhost_list[] = {
+	&clk_48m,
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_fin_epll,
+};
+
+static struct clksrc_sources clkset_uhost = {
+	.sources	= clkset_uhost_list,
+	.nr_sources	= ARRAY_SIZE(clkset_uhost_list),
+};
+
+/* The peripheral clocks are all controlled via clocksource followed
+ * by an optional divider and gate stage. We currently roll this into
+ * one clock which hides the intermediate clock from the mux.
+ *
+ * Note, the JPEG clock can only be an even divider...
+ *
+ * The scaler and LCD clocks depend on the S3C64XX version, and also
+ * have a common parent divisor so are not included here.
+ */
+
+/* clocks that feed other parts of the clock source tree */
+
+static struct clk clk_iis_cd0 = {
+	.name		= "iis_cdclk0",
+	.id		= -1,
+};
+
+static struct clk clk_iis_cd1 = {
+	.name		= "iis_cdclk1",
+	.id		= -1,
+};
+
+static struct clk clk_pcm_cd = {
+	.name		= "pcm_cdclk",
+	.id		= -1,
+};
+
+static struct clk *clkset_audio0_list[] = {
+	[0] = &clk_mout_epll.clk,
+	[1] = &clk_dout_mpll,
+	[2] = &clk_fin_epll,
+	[3] = &clk_iis_cd0,
+	[4] = &clk_pcm_cd,
+};
+
+static struct clksrc_sources clkset_audio0 = {
+	.sources	= clkset_audio0_list,
+	.nr_sources	= ARRAY_SIZE(clkset_audio0_list),
+};
+
+static struct clk *clkset_audio1_list[] = {
+	[0] = &clk_mout_epll.clk,
+	[1] = &clk_dout_mpll,
+	[2] = &clk_fin_epll,
+	[3] = &clk_iis_cd1,
+	[4] = &clk_pcm_cd,
+};
+
+static struct clksrc_sources clkset_audio1 = {
+	.sources	= clkset_audio1_list,
+	.nr_sources	= ARRAY_SIZE(clkset_audio1_list),
+};
+
+static struct clk *clkset_camif_list[] = {
+	&clk_h2,
+};
+
+static struct clksrc_sources clkset_camif = {
+	.sources	= clkset_camif_list,
+	.nr_sources	= ARRAY_SIZE(clkset_camif_list),
+};
+
+static struct clksrc_clk clksrcs[] = {
+	{
+		.clk	= {
+			.name		= "mmc_bus",
+			.id		= 0,
+			.ctrlbit        = S3C_CLKCON_SCLK_MMC0,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 18, .size = 2  },
+		.reg_div	= { .reg = S3C_CLK_DIV1, .shift = 0, .size = 4  },
+		.sources	= &clkset_spi_mmc,
+	}, {
+		.clk	= {
+			.name		= "mmc_bus",
+			.id		= 1,
+			.ctrlbit        = S3C_CLKCON_SCLK_MMC1,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 20, .size = 2  },
+		.reg_div	= { .reg = S3C_CLK_DIV1, .shift = 4, .size = 4  },
+		.sources	= &clkset_spi_mmc,
+	}, {
+		.clk	= {
+			.name		= "mmc_bus",
+			.id		= 2,
+			.ctrlbit        = S3C_CLKCON_SCLK_MMC2,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 22, .size = 2  },
+		.reg_div 	= { .reg = S3C_CLK_DIV1, .shift = 8, .size = 4  },
+		.sources	= &clkset_spi_mmc,
+	}, {
+		.clk	= {
+			.name		= "usb-bus-host",
+			.id		= -1,
+			.ctrlbit        = S3C_CLKCON_SCLK_UHOST,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.reg_src 	= { .reg = S3C_CLK_SRC, .shift = 5, .size = 2  },
+		.reg_div	= { .reg = S3C_CLK_DIV1, .shift = 20, .size = 4  },
+		.sources	= &clkset_uhost,
+	}, {
+		.clk	= {
+			.name		= "uclk1",
+			.id		= -1,
+			.ctrlbit        = S3C_CLKCON_SCLK_UART,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 13, .size = 1  },
+		.reg_div	= { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4  },
+		.sources	= &clkset_uart,
+	}, {
+/* Where does UCLK0 come from? */
+		.clk	= {
+			.name		= "spi-bus",
+			.id		= 0,
+			.ctrlbit        = S3C_CLKCON_SCLK_SPI0,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 14, .size = 2  },
+		.reg_div	= { .reg = S3C_CLK_DIV2, .shift = 0, .size = 4  },
+		.sources	= &clkset_spi_mmc,
+	}, {
+		.clk	= {
+			.name		= "spi-bus",
+			.id		= 1,
+			.ctrlbit        = S3C_CLKCON_SCLK_SPI1,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 16, .size = 2  },
+		.reg_div	= { .reg = S3C_CLK_DIV2, .shift = 4, .size = 4  },
+		.sources	= &clkset_spi_mmc,
+	}, {
+		.clk	= {
+			.name		= "audio-bus",
+			.id		= 0,
+			.ctrlbit        = S3C_CLKCON_SCLK_AUDIO0,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 7, .size = 3  },
+		.reg_div	= { .reg = S3C_CLK_DIV2, .shift = 8, .size = 4  },
+		.sources	= &clkset_audio0,
+	}, {
+		.clk	= {
+			.name		= "audio-bus",
+			.id		= 1,
+			.ctrlbit        = S3C_CLKCON_SCLK_AUDIO1,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 10, .size = 3  },
+		.reg_div	= { .reg = S3C_CLK_DIV2, .shift = 12, .size = 4  },
+		.sources	= &clkset_audio1,
+	}, {
+		.clk	= {
+			.name		= "irda-bus",
+			.id		= 0,
+			.ctrlbit        = S3C_CLKCON_SCLK_IRDA,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 24, .size = 2  },
+		.reg_div	= { .reg = S3C_CLK_DIV2, .shift = 20, .size = 4  },
+		.sources	= &clkset_irda,
+	}, {
+		.clk	= {
+			.name		= "camera",
+			.id		= -1,
+			.ctrlbit        = S3C_CLKCON_SCLK_CAM,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.reg_div	= { .reg = S3C_CLK_DIV0, .shift = 20, .size = 4  },
+		.reg_src	= { .reg = NULL, .shift = 0, .size = 0  },
+		.sources	= &clkset_camif,
+	},
+};
+
+/* Clock initialisation code */
+
+static struct clksrc_clk *init_parents[] = {
+	&clk_mout_apll,
+	&clk_mout_epll,
+	&clk_mout_mpll,
+};
+
+#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
+
+void __init_or_cpufreq s3c6400_setup_clocks(void)
+{
+	struct clk *xtal_clk;
+	unsigned long xtal;
+	unsigned long fclk;
+	unsigned long hclk;
+	unsigned long hclk2;
+	unsigned long pclk;
+	unsigned long epll;
+	unsigned long apll;
+	unsigned long mpll;
+	unsigned int ptr;
+	u32 clkdiv0;
+
+	printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+	clkdiv0 = __raw_readl(S3C_CLK_DIV0);
+	printk(KERN_DEBUG "%s: clkdiv0 = %08x\n", __func__, clkdiv0);
+
+	xtal_clk = clk_get(NULL, "xtal");
+	BUG_ON(IS_ERR(xtal_clk));
+
+	xtal = clk_get_rate(xtal_clk);
+	clk_put(xtal_clk);
+
+	printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+	/* For now assume the mux always selects the crystal */
+	clk_ext_xtal_mux.parent = xtal_clk;
+
+	epll = s3c6400_get_epll(xtal);
+	mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON));
+	apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON));
+
+	fclk = mpll;
+
+	printk(KERN_INFO "S3C64XX: PLL settings, A=%ld, M=%ld, E=%ld\n",
+	       apll, mpll, epll);
+
+	hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
+	hclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK);
+	pclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK);
+
+	printk(KERN_INFO "S3C64XX: HCLK2=%ld, HCLK=%ld, PCLK=%ld\n",
+	       hclk2, hclk, pclk);
+
+	clk_fout_mpll.rate = mpll;
+	clk_fout_epll.rate = epll;
+	clk_fout_apll.rate = apll;
+
+	clk_h2.rate = hclk2;
+	clk_h.rate = hclk;
+	clk_p.rate = pclk;
+	clk_f.rate = fclk;
+
+	for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
+		s3c_set_clksrc(init_parents[ptr], true);
+
+	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+		s3c_set_clksrc(&clksrcs[ptr], true);
+}
+
+static struct clk *clks1[] __initdata = {
+	&clk_ext_xtal_mux,
+	&clk_iis_cd0,
+	&clk_iis_cd1,
+	&clk_pcm_cd,
+	&clk_mout_epll.clk,
+	&clk_mout_mpll.clk,
+	&clk_dout_mpll,
+	&clk_arm,
+};
+
+static struct clk *clks[] __initdata = {
+	&clk_ext,
+	&clk_epll,
+	&clk_27m,
+	&clk_48m,
+	&clk_h2,
+};
+
+/**
+ * s3c64xx_register_clocks - register clocks for s3c6400 and s3c6410
+ * @xtal: The rate for the clock crystal feeding the PLLs.
+ * @armclk_divlimit: Divisor mask for ARMCLK.
+ *
+ * Register the clocks for the S3C6400 and S3C6410 SoC range, such
+ * as ARMCLK as well as the necessary parent clocks.
+ *
+ * This call does not setup the clocks, which is left to the
+ * s3c6400_setup_clocks() call which may be needed by the cpufreq
+ * or resume code to re-set the clocks if the bootloader has changed
+ * them.
+ */
+void __init s3c64xx_register_clocks(unsigned long xtal, 
+				    unsigned armclk_divlimit)
+{
+	struct clk *clkp;
+	int ret;
+	int ptr;
+
+	armclk_mask = armclk_divlimit;
+
+	s3c24xx_register_baseclocks(xtal);
+	s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+	s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+	clkp = init_clocks_disable;
+	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+
+		(clkp->enable)(clkp, 0);
+	}
+
+	s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1));
+	s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+	s3c_pwmclk_init();
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/cpu.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/cpu.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/cpu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/cpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,167 @@
+/* linux/arch/arm/plat-s3c64xx/cpu.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX CPU 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/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/regs-serial.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+
+#include <mach/s3c6400.h>
+#include <mach/s3c6410.h>
+
+/* table of supported CPUs */
+
+static const char name_s3c6400[] = "S3C6400";
+static const char name_s3c6410[] = "S3C6410";
+
+static struct cpu_table cpu_ids[] __initdata = {
+	{
+		.idcode		= 0x36400000,
+		.idmask		= 0xfffff000,
+		.map_io		= s3c6400_map_io,
+		.init_clocks	= s3c6400_init_clocks,
+		.init_uarts	= s3c6400_init_uarts,
+		.init		= s3c6400_init,
+		.name		= name_s3c6400,
+	}, {
+		.idcode		= 0x36410100,
+		.idmask		= 0xffffff00,
+		.map_io		= s3c6410_map_io,
+		.init_clocks	= s3c6410_init_clocks,
+		.init_uarts	= s3c6410_init_uarts,
+		.init		= s3c6410_init,
+		.name		= name_s3c6410,
+	},
+};
+
+/* minimal IO mapping */
+
+/* see notes on uart map in arch/arm/mach-s3c6400/include/mach/debug-macro.S */
+#define UART_OFFS (S3C_PA_UART & 0xfffff)
+
+static struct map_desc s3c_iodesc[] __initdata = {
+	{
+		.virtual	= (unsigned long)S3C_VA_SYS,
+		.pfn		= __phys_to_pfn(S3C64XX_PA_SYSCON),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S3C_VA_MEM,
+		.pfn		= __phys_to_pfn(S3C64XX_PA_SROM),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)(S3C_VA_UART + UART_OFFS),
+		.pfn		= __phys_to_pfn(S3C_PA_UART),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)VA_VIC0,
+		.pfn		= __phys_to_pfn(S3C64XX_PA_VIC0),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)VA_VIC1,
+		.pfn		= __phys_to_pfn(S3C64XX_PA_VIC1),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S3C_VA_TIMER,
+		.pfn		= __phys_to_pfn(S3C_PA_TIMER),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S3C64XX_VA_GPIO,
+		.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,
+	}, {
+		.virtual	= (unsigned long)S3C_VA_WATCHDOG,
+		.pfn		= __phys_to_pfn(S3C64XX_PA_WATCHDOG),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S3C_VA_USB_HSPHY,
+		.pfn		= __phys_to_pfn(S3C64XX_PA_USB_HSPHY),
+		.length		= SZ_1K,
+		.type		= MT_DEVICE,
+	},
+};
+
+
+struct sysdev_class s3c64xx_sysclass = {
+	.name	= "s3c64xx-core",
+};
+
+static struct sys_device s3c64xx_sysdev = {
+	.cls	= &s3c64xx_sysclass,
+};
+
+/* uart registration process */
+
+void __init s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+	s3c24xx_init_uartdevs("s3c6400-uart", s3c64xx_uart_resources, cfg, no);
+}
+
+/* read cpu identification code */
+
+void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
+{
+	unsigned long idcode;
+
+	/* initialise the io descriptors we need for initialisation */
+	iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
+	iotable_init(mach_desc, size);
+
+	idcode = __raw_readl(S3C_VA_SYS + 0x118);
+	if (!idcode) {
+		/* S3C6400 has the ID register in a different place,
+		 * and needs a write before it can be read. */
+
+		__raw_writel(0x0, S3C_VA_SYS + 0xA1C);
+		idcode = __raw_readl(S3C_VA_SYS + 0xA1C);
+	}
+
+	s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+}
+
+static __init int s3c64xx_sysdev_init(void)
+{
+	sysdev_class_register(&s3c64xx_sysclass);
+	return sysdev_register(&s3c64xx_sysdev);
+}
+
+core_initcall(s3c64xx_sysdev_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/cpufreq.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/cpufreq.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/cpufreq.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,270 @@
+/* linux/arch/arm/plat-s3c64xx/cpufreq.c
+ *
+ * Copyright 2009 Wolfson Microelectronics plc
+ *
+ * S3C64xx CPUfreq Support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/regulator/consumer.h>
+
+static struct clk *armclk;
+static struct regulator *vddarm;
+static unsigned long regulator_latency;
+
+#ifdef CONFIG_CPU_S3C6410
+struct s3c64xx_dvfs {
+	unsigned int vddarm_min;
+	unsigned int vddarm_max;
+};
+
+static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = {
+	[0] = { 1000000, 1150000 },
+	[1] = { 1050000, 1150000 },
+	[2] = { 1100000, 1150000 },
+	[3] = { 1200000, 1350000 },
+};
+
+static struct cpufreq_frequency_table s3c64xx_freq_table[] = {
+	{ 0,  66000 },
+	{ 0, 133000 },
+	{ 1, 222000 },
+	{ 1, 266000 },
+	{ 2, 333000 },
+	{ 2, 400000 },
+	{ 2, 532000 },
+	{ 2, 533000 },
+	{ 3, 667000 },
+	{ 0, CPUFREQ_TABLE_END },
+};
+#endif
+
+static int s3c64xx_cpufreq_verify_speed(struct cpufreq_policy *policy)
+{
+	if (policy->cpu != 0)
+		return -EINVAL;
+
+	return cpufreq_frequency_table_verify(policy, s3c64xx_freq_table);
+}
+
+static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu)
+{
+	if (cpu != 0)
+		return 0;
+
+	return clk_get_rate(armclk) / 1000;
+}
+
+static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
+				      unsigned int target_freq,
+				      unsigned int relation)
+{
+	int ret;
+	unsigned int i;
+	struct cpufreq_freqs freqs;
+	struct s3c64xx_dvfs *dvfs;
+
+	ret = cpufreq_frequency_table_target(policy, s3c64xx_freq_table,
+					     target_freq, relation, &i);
+	if (ret != 0)
+		return ret;
+
+	freqs.cpu = 0;
+	freqs.old = clk_get_rate(armclk) / 1000;
+	freqs.new = s3c64xx_freq_table[i].frequency;
+	freqs.flags = 0;
+	dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[i].index];
+
+	if (freqs.old == freqs.new)
+		return 0;
+
+	pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new);
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+#ifdef CONFIG_REGULATOR
+	if (vddarm && freqs.new > freqs.old) {
+		ret = regulator_set_voltage(vddarm,
+					    dvfs->vddarm_min,
+					    dvfs->vddarm_max);
+		if (ret != 0) {
+			pr_err("cpufreq: Failed to set VDDARM for %dkHz: %d\n",
+			       freqs.new, ret);
+			goto err;
+		}
+	}
+#endif
+
+	ret = clk_set_rate(armclk, freqs.new * 1000);
+	if (ret < 0) {
+		pr_err("cpufreq: Failed to set rate %dkHz: %d\n",
+		       freqs.new, ret);
+		goto err;
+	}
+
+#ifdef CONFIG_REGULATOR
+	if (vddarm && freqs.new < freqs.old) {
+		ret = regulator_set_voltage(vddarm,
+					    dvfs->vddarm_min,
+					    dvfs->vddarm_max);
+		if (ret != 0) {
+			pr_err("cpufreq: Failed to set VDDARM for %dkHz: %d\n",
+			       freqs.new, ret);
+			goto err_clk;
+		}
+	}
+#endif
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	pr_debug("cpufreq: Set actual frequency %lukHz\n",
+		 clk_get_rate(armclk) / 1000);
+
+	return 0;
+
+err_clk:
+	if (clk_set_rate(armclk, freqs.old * 1000) < 0)
+		pr_err("Failed to restore original clock rate\n");
+err:
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	return ret;
+}
+
+#ifdef CONFIG_REGULATOR
+static void __init s3c64xx_cpufreq_config_regulator(void)
+{
+	int count, v, i, found;
+	struct cpufreq_frequency_table *freq;
+	struct s3c64xx_dvfs *dvfs;
+
+	count = regulator_count_voltages(vddarm);
+	if (count < 0) {
+		pr_err("cpufreq: Unable to check supported voltages\n");
+	}
+
+	freq = s3c64xx_freq_table;
+	while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) {
+		if (freq->frequency == CPUFREQ_ENTRY_INVALID)
+			continue;
+
+		dvfs = &s3c64xx_dvfs_table[freq->index];
+		found = 0;
+
+		for (i = 0; i < count; i++) {
+			v = regulator_list_voltage(vddarm, i);
+			if (v >= dvfs->vddarm_min && v <= dvfs->vddarm_max)
+				found = 1;
+		}
+
+		if (!found) {
+			pr_debug("cpufreq: %dkHz unsupported by regulator\n",
+				 freq->frequency);
+			freq->frequency = CPUFREQ_ENTRY_INVALID;
+		}
+
+		freq++;
+	}
+
+	/* Guess based on having to do an I2C/SPI write; in future we
+	 * will be able to query the regulator performance here. */
+	regulator_latency = 1 * 1000 * 1000;
+}
+#endif
+
+static int __init s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
+{
+	int ret;
+	struct cpufreq_frequency_table *freq;
+
+	if (policy->cpu != 0)
+		return -EINVAL;
+
+	if (s3c64xx_freq_table == NULL) {
+		pr_err("cpufreq: No frequency information for this CPU\n");
+		return -ENODEV;
+	}
+
+	armclk = clk_get(NULL, "armclk");
+	if (IS_ERR(armclk)) {
+		pr_err("cpufreq: Unable to obtain ARMCLK: %ld\n",
+		       PTR_ERR(armclk));
+		return PTR_ERR(armclk);
+	}
+
+#ifdef CONFIG_REGULATOR
+	vddarm = regulator_get(NULL, "vddarm");
+	if (IS_ERR(vddarm)) {
+		ret = PTR_ERR(vddarm);
+		pr_err("cpufreq: Failed to obtain VDDARM: %d\n", ret);
+		pr_err("cpufreq: Only frequency scaling available\n");
+		vddarm = NULL;
+	} else {
+		s3c64xx_cpufreq_config_regulator();
+	}
+#endif
+
+	freq = s3c64xx_freq_table;
+	while (freq->frequency != CPUFREQ_TABLE_END) {
+		unsigned long r;
+
+		/* Check for frequencies we can generate */
+		r = clk_round_rate(armclk, freq->frequency * 1000);
+		r /= 1000;
+		if (r != freq->frequency) {
+			pr_debug("cpufreq: %dkHz unsupported by clock\n",
+				 freq->frequency);
+			freq->frequency = CPUFREQ_ENTRY_INVALID;
+		}
+
+		/* If we have no regulator then assume startup
+		 * frequency is the maximum we can support. */
+		if (!vddarm && freq->frequency > s3c64xx_cpufreq_get_speed(0))
+			freq->frequency = CPUFREQ_ENTRY_INVALID;
+
+		freq++;
+	}
+
+	policy->cur = clk_get_rate(armclk) / 1000;
+
+	/* Datasheet says PLL stabalisation time (if we were to use
+	 * the PLLs, which we don't currently) is ~300us worst case,
+	 * but add some fudge.
+	 */
+	policy->cpuinfo.transition_latency = (500 * 1000) + regulator_latency;
+
+	ret = cpufreq_frequency_table_cpuinfo(policy, s3c64xx_freq_table);
+	if (ret != 0) {
+		pr_err("cpufreq: Failed to configure frequency table: %d\n",
+		       ret);
+		regulator_put(vddarm);
+		clk_put(armclk);
+	}
+
+	return ret;
+}
+
+static struct cpufreq_driver s3c64xx_cpufreq_driver = {
+	.owner		= THIS_MODULE,
+	.flags          = 0,
+	.verify		= s3c64xx_cpufreq_verify_speed,
+	.target		= s3c64xx_cpufreq_set_target,
+	.get		= s3c64xx_cpufreq_get_speed,
+	.init		= s3c64xx_cpufreq_driver_init,
+	.name		= "s3c",
+};
+
+static int __init s3c64xx_cpufreq_init(void)
+{
+	return cpufreq_register_driver(&s3c64xx_cpufreq_driver);
+}
+module_init(s3c64xx_cpufreq_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/dev-adc.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/dev-adc.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/dev-adc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/dev-adc.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,46 @@
+/* linux/arch/arm/plat-s3c64xx/dev-adc.c
+ *
+ * Copyright 2010 Maurus Cuelenaere
+ *
+ * S3C64xx series device definition for ADC 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/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/adc.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_adc_resource[] = {
+	[0] = {
+		.start = S3C64XX_PA_ADC,
+		.end   = S3C64XX_PA_ADC + SZ_256 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_TC,
+		.end   = IRQ_TC,
+		.flags = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start = IRQ_ADC,
+		.end   = IRQ_ADC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device s3c_device_adc = {
+	.name		= "s3c64xx-adc",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(s3c_adc_resource),
+	.resource	= s3c_adc_resource,
+};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/dev-audio.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/dev-audio.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/dev-audio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/dev-audio.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,335 @@
+/* linux/arch/arm/plat-s3c/dev-audio.c
+ *
+ * Copyright 2009 Wolfson Microelectronics
+ *      Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/gpio.h>
+
+#include <plat/devs.h>
+#include <plat/audio.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/gpio-bank-c.h>
+#include <mach/gpio-bank-d.h>
+#include <mach/gpio-bank-e.h>
+#include <mach/gpio-bank-h.h>
+
+static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
+{
+	switch (pdev->id) {
+	case 0:
+		s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK);
+		s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK);
+		s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_I2S0_LRCLK);
+		s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_I2S0_DI);
+		s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_I2S0_D0);
+		break;
+	case 1:
+		s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_I2S1_CLK);
+		s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_I2S1_CDCLK);
+		s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_I2S1_LRCLK);
+		s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_I2S1_DI);
+		s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_I2S1_D0);
+	default:
+		printk(KERN_DEBUG "Invalid I2S Controller number!");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev)
+{
+	s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_I2S_V40_DO0);
+	s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_I2S_V40_DO1);
+	s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C64XX_GPC7_I2S_V40_DO2);
+	s3c_gpio_cfgpin(S3C64XX_GPH(6), S3C64XX_GPH6_I2S_V40_BCLK);
+	s3c_gpio_cfgpin(S3C64XX_GPH(7), S3C64XX_GPH7_I2S_V40_CDCLK);
+	s3c_gpio_cfgpin(S3C64XX_GPH(8), S3C64XX_GPH8_I2S_V40_LRCLK);
+	s3c_gpio_cfgpin(S3C64XX_GPH(9), S3C64XX_GPH9_I2S_V40_DI);
+
+	return 0;
+}
+
+static struct resource s3c64xx_iis0_resource[] = {
+	[0] = {
+		.start = S3C64XX_PA_IIS0,
+		.end   = S3C64XX_PA_IIS0 + 0x100 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = DMACH_I2S0_OUT,
+		.end   = DMACH_I2S0_OUT,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = DMACH_I2S0_IN,
+		.end   = DMACH_I2S0_IN,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+static struct s3c_audio_pdata s3c_i2s0_pdata = {
+	.cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_iis0 = {
+	.name		  = "s3c64xx-iis",
+	.id		  = 0,
+	.num_resources	  = ARRAY_SIZE(s3c64xx_iis0_resource),
+	.resource	  = s3c64xx_iis0_resource,
+	.dev = {
+		.platform_data = &s3c_i2s0_pdata,
+	},
+};
+EXPORT_SYMBOL(s3c64xx_device_iis0);
+
+static struct resource s3c64xx_iis1_resource[] = {
+	[0] = {
+		.start = S3C64XX_PA_IIS1,
+		.end   = S3C64XX_PA_IIS1 + 0x100 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = DMACH_I2S1_OUT,
+		.end   = DMACH_I2S1_OUT,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = DMACH_I2S1_IN,
+		.end   = DMACH_I2S1_IN,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+static struct s3c_audio_pdata s3c_i2s1_pdata = {
+	.cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_iis1 = {
+	.name		  = "s3c64xx-iis",
+	.id		  = 1,
+	.num_resources	  = ARRAY_SIZE(s3c64xx_iis1_resource),
+	.resource	  = s3c64xx_iis1_resource,
+	.dev = {
+		.platform_data = &s3c_i2s1_pdata,
+	},
+};
+EXPORT_SYMBOL(s3c64xx_device_iis1);
+
+static struct resource s3c64xx_iisv4_resource[] = {
+	[0] = {
+		.start = S3C64XX_PA_IISV4,
+		.end   = S3C64XX_PA_IISV4 + 0x100 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = DMACH_HSI_I2SV40_TX,
+		.end   = DMACH_HSI_I2SV40_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = DMACH_HSI_I2SV40_RX,
+		.end   = DMACH_HSI_I2SV40_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+static struct s3c_audio_pdata s3c_i2sv4_pdata = {
+	.cfg_gpio = s3c64xx_i2sv4_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_iisv4 = {
+	.name		  = "s3c64xx-iis-v4",
+	.id		  = -1,
+	.num_resources	  = ARRAY_SIZE(s3c64xx_iisv4_resource),
+	.resource	  = s3c64xx_iisv4_resource,
+	.dev = {
+		.platform_data = &s3c_i2sv4_pdata,
+	},
+};
+EXPORT_SYMBOL(s3c64xx_device_iisv4);
+
+
+/* PCM Controller platform_devices */
+
+static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
+{
+	switch (pdev->id) {
+	case 0:
+		s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_PCM0_SCLK);
+		s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_PCM0_EXTCLK);
+		s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_PCM0_FSYNC);
+		s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_PCM0_SIN);
+		s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_PCM0_SOUT);
+		break;
+	case 1:
+		s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_PCM1_SCLK);
+		s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_PCM1_EXTCLK);
+		s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_PCM1_FSYNC);
+		s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_PCM1_SIN);
+		s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_PCM1_SOUT);
+		break;
+	default:
+		printk(KERN_DEBUG "Invalid PCM Controller number!");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct resource s3c64xx_pcm0_resource[] = {
+	[0] = {
+		.start = S3C64XX_PA_PCM0,
+		.end   = S3C64XX_PA_PCM0 + 0x100 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = DMACH_PCM0_TX,
+		.end   = DMACH_PCM0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = DMACH_PCM0_RX,
+		.end   = DMACH_PCM0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+static struct s3c_audio_pdata s3c_pcm0_pdata = {
+	.cfg_gpio = s3c64xx_pcm_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_pcm0 = {
+	.name		  = "samsung-pcm",
+	.id		  = 0,
+	.num_resources	  = ARRAY_SIZE(s3c64xx_pcm0_resource),
+	.resource	  = s3c64xx_pcm0_resource,
+	.dev = {
+		.platform_data = &s3c_pcm0_pdata,
+	},
+};
+EXPORT_SYMBOL(s3c64xx_device_pcm0);
+
+static struct resource s3c64xx_pcm1_resource[] = {
+	[0] = {
+		.start = S3C64XX_PA_PCM1,
+		.end   = S3C64XX_PA_PCM1 + 0x100 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = DMACH_PCM1_TX,
+		.end   = DMACH_PCM1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = DMACH_PCM1_RX,
+		.end   = DMACH_PCM1_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+static struct s3c_audio_pdata s3c_pcm1_pdata = {
+	.cfg_gpio = s3c64xx_pcm_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_pcm1 = {
+	.name		  = "samsung-pcm",
+	.id		  = 1,
+	.num_resources	  = ARRAY_SIZE(s3c64xx_pcm1_resource),
+	.resource	  = s3c64xx_pcm1_resource,
+	.dev = {
+		.platform_data = &s3c_pcm1_pdata,
+	},
+};
+EXPORT_SYMBOL(s3c64xx_device_pcm1);
+
+/* AC97 Controller platform devices */
+
+static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev)
+{
+	s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_AC97_BITCLK);
+	s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_AC97_nRESET);
+	s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_AC97_SYNC);
+	s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_AC97_SDI);
+	s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_AC97_SDO);
+
+	return 0;
+}
+
+static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
+{
+	s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_AC97_BITCLK);
+	s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_AC97_nRESET);
+	s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_AC97_SYNC);
+	s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_AC97_SDI);
+	s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_AC97_SDO);
+
+	return 0;
+}
+
+static struct resource s3c64xx_ac97_resource[] = {
+	[0] = {
+		.start = S3C64XX_PA_AC97,
+		.end   = S3C64XX_PA_AC97 + 0x100 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = DMACH_AC97_PCMOUT,
+		.end   = DMACH_AC97_PCMOUT,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = DMACH_AC97_PCMIN,
+		.end   = DMACH_AC97_PCMIN,
+		.flags = IORESOURCE_DMA,
+	},
+	[3] = {
+		.start = DMACH_AC97_MICIN,
+		.end   = DMACH_AC97_MICIN,
+		.flags = IORESOURCE_DMA,
+	},
+	[4] = {
+		.start = IRQ_AC97,
+		.end   = IRQ_AC97,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct s3c_audio_pdata s3c_ac97_pdata;
+
+static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s3c64xx_device_ac97 = {
+	.name		  = "s3c-ac97",
+	.id		  = -1,
+	.num_resources	  = ARRAY_SIZE(s3c64xx_ac97_resource),
+	.resource	  = s3c64xx_ac97_resource,
+	.dev = {
+		.platform_data = &s3c_ac97_pdata,
+		.dma_mask = &s3c64xx_ac97_dmamask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+};
+EXPORT_SYMBOL(s3c64xx_device_ac97);
+
+void __init s3c64xx_ac97_setup_gpio(int num)
+{
+	if (num == S3C64XX_AC97_GPD)
+		s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpd;
+	else
+		s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/dev-rtc.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/dev-rtc.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/dev-rtc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/dev-rtc.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,43 @@
+/* linux/arch/arm/plat-s3c64xx/dev-rtc.c
+ *
+ * Copyright 2009 by Maurus Cuelenaere <mcuelenaere@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/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+static struct resource s3c_rtc_resource[] = {
+	[0] = {
+		.start = S3C64XX_PA_RTC,
+		.end   = S3C64XX_PA_RTC + 0xff,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_RTC_ALARM,
+		.end   = IRQ_RTC_ALARM,
+		.flags = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start = IRQ_RTC_TIC,
+		.end   = IRQ_RTC_TIC,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+struct platform_device s3c_device_rtc = {
+	.name		  = "s3c64xx-rtc",
+	.id		  = -1,
+	.num_resources	  = ARRAY_SIZE(s3c_rtc_resource),
+	.resource	  = s3c_rtc_resource,
+};
+EXPORT_SYMBOL(s3c_device_rtc);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/dev-spi.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/dev-spi.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/dev-spi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/dev-spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,182 @@
+/* linux/arch/arm/plat-s3c64xx/dev-spi.c
+ *
+ * Copyright (C) 2009 Samsung Electronics Ltd.
+ *	Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/dma.h>
+#include <mach/map.h>
+#include <mach/gpio.h>
+#include <mach/gpio-bank-c.h>
+#include <mach/spi-clocks.h>
+
+#include <plat/s3c64xx-spi.h>
+#include <plat/gpio-cfg.h>
+#include <plat/irqs.h>
+
+static char *spi_src_clks[] = {
+	[S3C64XX_SPI_SRCCLK_PCLK] = "pclk",
+	[S3C64XX_SPI_SRCCLK_SPIBUS] = "spi-bus",
+	[S3C64XX_SPI_SRCCLK_48M] = "spi_48m",
+};
+
+/* SPI Controller platform_devices */
+
+/* Since we emulate multi-cs capability, we do not touch the GPC-3,7.
+ * The emulated CS is toggled by board specific mechanism, as it can
+ * be either some immediate GPIO or some signal out of some other
+ * chip in between ... or some yet another way.
+ * We simply do not assume anything about CS.
+ */
+static int s3c64xx_spi_cfg_gpio(struct platform_device *pdev)
+{
+	switch (pdev->id) {
+	case 0:
+		s3c_gpio_cfgpin(S3C64XX_GPC(0), S3C64XX_GPC0_SPI_MISO0);
+		s3c_gpio_cfgpin(S3C64XX_GPC(1), S3C64XX_GPC1_SPI_CLKO);
+		s3c_gpio_cfgpin(S3C64XX_GPC(2), S3C64XX_GPC2_SPI_MOSIO);
+		s3c_gpio_setpull(S3C64XX_GPC(0), S3C_GPIO_PULL_UP);
+		s3c_gpio_setpull(S3C64XX_GPC(1), S3C_GPIO_PULL_UP);
+		s3c_gpio_setpull(S3C64XX_GPC(2), S3C_GPIO_PULL_UP);
+		break;
+
+	case 1:
+		s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_SPI_MISO1);
+		s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_SPI_CLK1);
+		s3c_gpio_cfgpin(S3C64XX_GPC(6), S3C64XX_GPC6_SPI_MOSI1);
+		s3c_gpio_setpull(S3C64XX_GPC(4), S3C_GPIO_PULL_UP);
+		s3c_gpio_setpull(S3C64XX_GPC(5), S3C_GPIO_PULL_UP);
+		s3c_gpio_setpull(S3C64XX_GPC(6), S3C_GPIO_PULL_UP);
+		break;
+
+	default:
+		dev_err(&pdev->dev, "Invalid SPI Controller number!");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct resource s3c64xx_spi0_resource[] = {
+	[0] = {
+		.start = S3C64XX_PA_SPI0,
+		.end   = S3C64XX_PA_SPI0 + 0x100 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = DMACH_SPI0_TX,
+		.end   = DMACH_SPI0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = DMACH_SPI0_RX,
+		.end   = DMACH_SPI0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+	[3] = {
+		.start = IRQ_SPI0,
+		.end   = IRQ_SPI0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct s3c64xx_spi_info s3c64xx_spi0_pdata = {
+	.cfg_gpio = s3c64xx_spi_cfg_gpio,
+	.fifo_lvl_mask = 0x7f,
+	.rx_lvl_offset = 13,
+};
+
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s3c64xx_device_spi0 = {
+	.name		  = "s3c64xx-spi",
+	.id		  = 0,
+	.num_resources	  = ARRAY_SIZE(s3c64xx_spi0_resource),
+	.resource	  = s3c64xx_spi0_resource,
+	.dev = {
+		.dma_mask		= &spi_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data = &s3c64xx_spi0_pdata,
+	},
+};
+EXPORT_SYMBOL(s3c64xx_device_spi0);
+
+static struct resource s3c64xx_spi1_resource[] = {
+	[0] = {
+		.start = S3C64XX_PA_SPI1,
+		.end   = S3C64XX_PA_SPI1 + 0x100 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = DMACH_SPI1_TX,
+		.end   = DMACH_SPI1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = DMACH_SPI1_RX,
+		.end   = DMACH_SPI1_RX,
+		.flags = IORESOURCE_DMA,
+	},
+	[3] = {
+		.start = IRQ_SPI1,
+		.end   = IRQ_SPI1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct s3c64xx_spi_info s3c64xx_spi1_pdata = {
+	.cfg_gpio = s3c64xx_spi_cfg_gpio,
+	.fifo_lvl_mask = 0x7f,
+	.rx_lvl_offset = 13,
+};
+
+struct platform_device s3c64xx_device_spi1 = {
+	.name		  = "s3c64xx-spi",
+	.id		  = 1,
+	.num_resources	  = ARRAY_SIZE(s3c64xx_spi1_resource),
+	.resource	  = s3c64xx_spi1_resource,
+	.dev = {
+		.dma_mask		= &spi_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data = &s3c64xx_spi1_pdata,
+	},
+};
+EXPORT_SYMBOL(s3c64xx_device_spi1);
+
+void __init s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
+{
+	struct s3c64xx_spi_info *pd;
+
+	/* Reject invalid configuration */
+	if (!num_cs || src_clk_nr < 0
+			|| src_clk_nr > S3C64XX_SPI_SRCCLK_48M) {
+		printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
+		return;
+	}
+
+	switch (cntrlr) {
+	case 0:
+		pd = &s3c64xx_spi0_pdata;
+		break;
+	case 1:
+		pd = &s3c64xx_spi1_pdata;
+		break;
+	default:
+		printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
+							__func__, cntrlr);
+		return;
+	}
+
+	pd->num_cs = num_cs;
+	pd->src_clk_nr = src_clk_nr;
+	pd->src_clk_name = spi_src_clks[src_clk_nr];
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/dev-uart.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/dev-uart.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/dev-uart.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/dev-uart.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,147 @@
+/* linux/arch/arm/plat-s3c64xx/dev-uart.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * Base S3C64XX UART resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+/* Serial port registrations */
+
+/* 64xx uarts are closer together */
+
+static struct resource s3c64xx_uart0_resource[] = {
+	[0] = {
+		.start	= S3C_PA_UART0,
+		.end	= S3C_PA_UART0 + 0x100,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_S3CUART_RX0,
+		.end	= IRQ_S3CUART_RX0,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= IRQ_S3CUART_TX0,
+		.end	= IRQ_S3CUART_TX0,
+		.flags	= IORESOURCE_IRQ,
+
+	},
+	[3] = {
+		.start	= IRQ_S3CUART_ERR0,
+		.end	= IRQ_S3CUART_ERR0,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct resource s3c64xx_uart1_resource[] = {
+	[0] = {
+		.start = S3C_PA_UART1,
+		.end   = S3C_PA_UART1 + 0x100,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_S3CUART_RX1,
+		.end	= IRQ_S3CUART_RX1,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= IRQ_S3CUART_TX1,
+		.end	= IRQ_S3CUART_TX1,
+		.flags	= IORESOURCE_IRQ,
+
+	},
+	[3] = {
+		.start	= IRQ_S3CUART_ERR1,
+		.end	= IRQ_S3CUART_ERR1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource s3c6xx_uart2_resource[] = {
+	[0] = {
+		.start = S3C_PA_UART2,
+		.end   = S3C_PA_UART2 + 0x100,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_S3CUART_RX2,
+		.end	= IRQ_S3CUART_RX2,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= IRQ_S3CUART_TX2,
+		.end	= IRQ_S3CUART_TX2,
+		.flags	= IORESOURCE_IRQ,
+
+	},
+	[3] = {
+		.start	= IRQ_S3CUART_ERR2,
+		.end	= IRQ_S3CUART_ERR2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource s3c64xx_uart3_resource[] = {
+	[0] = {
+		.start = S3C_PA_UART3,
+		.end   = S3C_PA_UART3 + 0x100,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_S3CUART_RX3,
+		.end	= IRQ_S3CUART_RX3,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= IRQ_S3CUART_TX3,
+		.end	= IRQ_S3CUART_TX3,
+		.flags	= IORESOURCE_IRQ,
+
+	},
+	[3] = {
+		.start	= IRQ_S3CUART_ERR3,
+		.end	= IRQ_S3CUART_ERR3,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+
+struct s3c24xx_uart_resources s3c64xx_uart_resources[] __initdata = {
+	[0] = {
+		.resources	= s3c64xx_uart0_resource,
+		.nr_resources	= ARRAY_SIZE(s3c64xx_uart0_resource),
+	},
+	[1] = {
+		.resources	= s3c64xx_uart1_resource,
+		.nr_resources	= ARRAY_SIZE(s3c64xx_uart1_resource),
+	},
+	[2] = {
+		.resources	= s3c6xx_uart2_resource,
+		.nr_resources	= ARRAY_SIZE(s3c6xx_uart2_resource),
+	},
+	[3] = {
+		.resources	= s3c64xx_uart3_resource,
+		.nr_resources	= ARRAY_SIZE(s3c64xx_uart3_resource),
+	},
+};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/dma.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/dma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,750 @@
+/* linux/arch/arm/plat-s3c64xx/dma.c
+ *
+ * Copyright 2009 Openmoko, Inc.
+ * Copyright 2009 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX DMA core
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/dmapool.h>
+#include <linux/sysdev.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/dma.h>
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#include <mach/regs-sys.h>
+
+#include <asm/hardware/pl080.h>
+
+/* dma channel state information */
+
+struct s3c64xx_dmac {
+	struct sys_device	 sysdev;
+	struct clk		*clk;
+	void __iomem		*regs;
+	struct s3c2410_dma_chan *channels;
+	enum dma_ch		 chanbase;
+};
+
+/* pool to provide LLI buffers */
+static struct dma_pool *dma_pool;
+
+/* Debug configuration and code */
+
+static unsigned char debug_show_buffs = 0;
+
+static void dbg_showchan(struct s3c2410_dma_chan *chan)
+{
+	pr_debug("DMA%d: %08x->%08x L %08x C %08x,%08x S %08x\n",
+		 chan->number,
+		 readl(chan->regs + PL080_CH_SRC_ADDR),
+		 readl(chan->regs + PL080_CH_DST_ADDR),
+		 readl(chan->regs + PL080_CH_LLI),
+		 readl(chan->regs + PL080_CH_CONTROL),
+		 readl(chan->regs + PL080S_CH_CONTROL2),
+		 readl(chan->regs + PL080S_CH_CONFIG));
+}
+
+static void show_lli(struct pl080s_lli *lli)
+{
+	pr_debug("LLI[%p] %08x->%08x, NL %08x C %08x,%08x\n",
+		 lli, lli->src_addr, lli->dst_addr, lli->next_lli,
+		 lli->control0, lli->control1);
+}
+
+static void dbg_showbuffs(struct s3c2410_dma_chan *chan)
+{
+	struct s3c64xx_dma_buff *ptr;
+	struct s3c64xx_dma_buff *end;
+
+	pr_debug("DMA%d: buffs next %p, curr %p, end %p\n",
+		 chan->number, chan->next, chan->curr, chan->end);
+
+	ptr = chan->next;
+	end = chan->end;
+
+	if (debug_show_buffs) {
+		for (; ptr != NULL; ptr = ptr->next) {
+			pr_debug("DMA%d: %08x ",
+				 chan->number, ptr->lli_dma);
+			show_lli(ptr->lli);
+		}
+	}
+}
+
+/* End of Debug */
+
+static struct s3c2410_dma_chan *s3c64xx_dma_map_channel(unsigned int channel)
+{
+	struct s3c2410_dma_chan *chan;
+	unsigned int start, offs;
+
+	start = 0;
+
+	if (channel >= DMACH_PCM1_TX)
+		start = 8;
+
+	for (offs = 0; offs < 8; offs++) {
+		chan = &s3c2410_chans[start + offs];
+		if (!chan->in_use)
+			goto found;
+	}
+
+	return NULL;
+
+found:
+	s3c_dma_chan_map[channel] = chan;
+	return chan;
+}
+
+int s3c2410_dma_config(unsigned int channel, int xferunit)
+{
+	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	switch (xferunit) {
+	case 1:
+		chan->hw_width = 0;
+		break;
+	case 2:
+		chan->hw_width = 1;
+		break;
+	case 4:
+		chan->hw_width = 2;
+		break;
+	default:
+		printk(KERN_ERR "%s: illegal width %d\n", __func__, xferunit);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_config);
+
+static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
+				 struct pl080s_lli *lli,
+				 dma_addr_t data, int size)
+{
+	dma_addr_t src, dst;
+	u32 control0, control1;
+
+	switch (chan->source) {
+	case S3C2410_DMASRC_HW:
+		src = chan->dev_addr;
+		dst = data;
+		control0 = PL080_CONTROL_SRC_AHB2;
+		control0 |= PL080_CONTROL_DST_INCR;
+		break;
+
+	case S3C2410_DMASRC_MEM:
+		src = data;
+		dst = chan->dev_addr;
+		control0 = PL080_CONTROL_DST_AHB2;
+		control0 |= PL080_CONTROL_SRC_INCR;
+		break;
+	default:
+		BUG();
+	}
+
+	/* note, we do not currently setup any of the burst controls */
+
+	control1 = size >> chan->hw_width;	/* size in no of xfers */
+	control0 |= PL080_CONTROL_PROT_SYS;	/* always in priv. mode */
+	control0 |= PL080_CONTROL_TC_IRQ_EN;	/* always fire IRQ */
+	control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT;
+	control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT;
+
+	lli->src_addr = src;
+	lli->dst_addr = dst;
+	lli->next_lli = 0;
+	lli->control0 = control0;
+	lli->control1 = control1;
+}
+
+static void s3c64xx_lli_to_regs(struct s3c2410_dma_chan *chan,
+				struct pl080s_lli *lli)
+{
+	void __iomem *regs = chan->regs;
+
+	pr_debug("%s: LLI %p => regs\n", __func__, lli);
+	show_lli(lli);
+
+	writel(lli->src_addr, regs + PL080_CH_SRC_ADDR);
+	writel(lli->dst_addr, regs + PL080_CH_DST_ADDR);
+	writel(lli->next_lli, regs + PL080_CH_LLI);
+	writel(lli->control0, regs + PL080_CH_CONTROL);
+	writel(lli->control1, regs + PL080S_CH_CONTROL2);
+}
+
+static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan)
+{
+	struct s3c64xx_dmac *dmac = chan->dmac;
+	u32 config;
+	u32 bit = chan->bit;
+
+	dbg_showchan(chan);
+
+	pr_debug("%s: clearing interrupts\n", __func__);
+
+	/* clear interrupts */
+	writel(bit, dmac->regs + PL080_TC_CLEAR);
+	writel(bit, dmac->regs + PL080_ERR_CLEAR);
+
+	pr_debug("%s: starting channel\n", __func__);
+
+	config = readl(chan->regs + PL080S_CH_CONFIG);
+	config |= PL080_CONFIG_ENABLE;
+
+	pr_debug("%s: writing config %08x\n", __func__, config);
+	writel(config, chan->regs + PL080S_CH_CONFIG);
+
+	return 0;
+}
+
+static int s3c64xx_dma_stop(struct s3c2410_dma_chan *chan)
+{
+	u32 config;
+	int timeout;
+
+	pr_debug("%s: stopping channel\n", __func__);
+
+	dbg_showchan(chan);
+
+	config = readl(chan->regs + PL080S_CH_CONFIG);
+	config |= PL080_CONFIG_HALT;
+	writel(config, chan->regs + PL080S_CH_CONFIG);
+
+	timeout = 1000;
+	do {
+		config = readl(chan->regs + PL080S_CH_CONFIG);
+		pr_debug("%s: %d - config %08x\n", __func__, timeout, config);
+		if (config & PL080_CONFIG_ACTIVE)
+			udelay(10);
+		else
+			break;
+		} while (--timeout > 0);
+
+	if (config & PL080_CONFIG_ACTIVE) {
+		printk(KERN_ERR "%s: channel still active\n", __func__);
+		return -EFAULT;
+	}
+
+	config = readl(chan->regs + PL080S_CH_CONFIG);
+	config &= ~PL080_CONFIG_ENABLE;
+	writel(config, chan->regs + PL080S_CH_CONFIG);
+
+	return 0;
+}
+
+static inline void s3c64xx_dma_bufffdone(struct s3c2410_dma_chan *chan,
+					 struct s3c64xx_dma_buff *buf,
+					 enum s3c2410_dma_buffresult result)
+{
+	if (chan->callback_fn != NULL)
+		(chan->callback_fn)(chan, buf->pw, 0, result);
+}
+
+static void s3c64xx_dma_freebuff(struct s3c64xx_dma_buff *buff)
+{
+	dma_pool_free(dma_pool, buff->lli, buff->lli_dma);
+	kfree(buff);
+}
+
+static int s3c64xx_dma_flush(struct s3c2410_dma_chan *chan)
+{
+	struct s3c64xx_dma_buff *buff, *next;
+	u32 config;
+
+	dbg_showchan(chan);
+
+	pr_debug("%s: flushing channel\n", __func__);
+
+	config = readl(chan->regs + PL080S_CH_CONFIG);
+	config &= ~PL080_CONFIG_ENABLE;
+	writel(config, chan->regs + PL080S_CH_CONFIG);
+
+	/* dump all the buffers associated with this channel */
+
+	for (buff = chan->curr; buff != NULL; buff = next) {
+		next = buff->next;
+		pr_debug("%s: buff %p (next %p)\n", __func__, buff, buff->next);
+
+		s3c64xx_dma_bufffdone(chan, buff, S3C2410_RES_ABORT);
+		s3c64xx_dma_freebuff(buff);
+	}
+
+	chan->curr = chan->next = chan->end = NULL;
+
+	return 0;
+}
+
+int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op)
+{
+	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+	WARN_ON(!chan);
+	if (!chan)
+		return -EINVAL;
+
+	switch (op) {
+	case S3C2410_DMAOP_START:
+		return s3c64xx_dma_start(chan);
+
+	case S3C2410_DMAOP_STOP:
+		return s3c64xx_dma_stop(chan);
+
+	case S3C2410_DMAOP_FLUSH:
+		return s3c64xx_dma_flush(chan);
+
+	/* belive PAUSE/RESUME are no-ops */
+	case S3C2410_DMAOP_PAUSE:
+	case S3C2410_DMAOP_RESUME:
+	case S3C2410_DMAOP_STARTED:
+	case S3C2410_DMAOP_TIMEOUT:
+		return 0;
+	}
+
+	return -ENOENT;
+}
+EXPORT_SYMBOL(s3c2410_dma_ctrl);
+
+/* s3c2410_dma_enque
+ *
+ */
+
+int s3c2410_dma_enqueue(unsigned int channel, void *id,
+			dma_addr_t data, int size)
+{
+	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+	struct s3c64xx_dma_buff *next;
+	struct s3c64xx_dma_buff *buff;
+	struct pl080s_lli *lli;
+	unsigned long flags;
+	int ret;
+
+	WARN_ON(!chan);
+	if (!chan)
+		return -EINVAL;
+
+	buff = kzalloc(sizeof(struct s3c64xx_dma_buff), GFP_ATOMIC);
+	if (!buff) {
+		printk(KERN_ERR "%s: no memory for buffer\n", __func__);
+		return -ENOMEM;
+	}
+
+	lli = dma_pool_alloc(dma_pool, GFP_ATOMIC, &buff->lli_dma);
+	if (!lli) {
+		printk(KERN_ERR "%s: no memory for lli\n", __func__);
+		ret = -ENOMEM;
+		goto err_buff;
+	}
+
+	pr_debug("%s: buff %p, dp %08x lli (%p, %08x) %d\n",
+		 __func__, buff, data, lli, (u32)buff->lli_dma, size);
+
+	buff->lli = lli;
+	buff->pw = id;
+
+	s3c64xx_dma_fill_lli(chan, lli, data, size);
+
+	local_irq_save(flags);
+
+	if ((next = chan->next) != NULL) {
+		struct s3c64xx_dma_buff *end = chan->end;
+		struct pl080s_lli *endlli = end->lli;
+
+		pr_debug("enquing onto channel\n");
+
+		end->next = buff;
+		endlli->next_lli = buff->lli_dma;
+
+		if (chan->flags & S3C2410_DMAF_CIRCULAR) {
+			struct s3c64xx_dma_buff *curr = chan->curr;
+			lli->next_lli = curr->lli_dma;
+		}
+
+		if (next == chan->curr) {
+			writel(buff->lli_dma, chan->regs + PL080_CH_LLI);
+			chan->next = buff;
+		}
+
+		show_lli(endlli);
+		chan->end = buff;
+	} else {
+		pr_debug("enquing onto empty channel\n");
+
+		chan->curr = buff;
+		chan->next = buff;
+		chan->end = buff;
+
+		s3c64xx_lli_to_regs(chan, lli);
+	}
+
+	local_irq_restore(flags);
+
+	show_lli(lli);
+
+	dbg_showchan(chan);
+	dbg_showbuffs(chan);
+	return 0;
+
+err_buff:
+	kfree(buff);
+	return ret;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_enqueue);
+
+
+int s3c2410_dma_devconfig(int channel,
+			  enum s3c2410_dmasrc source,
+			  unsigned long devaddr)
+{
+	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+	u32 peripheral;
+	u32 config = 0;
+
+	pr_debug("%s: channel %d, source %d, dev %08lx, chan %p\n",
+		 __func__, channel, source, devaddr, chan);
+
+	WARN_ON(!chan);
+	if (!chan)
+		return -EINVAL;
+
+	peripheral = (chan->peripheral & 0xf);
+	chan->source = source;
+	chan->dev_addr = devaddr;
+
+	pr_debug("%s: peripheral %d\n", __func__, peripheral);
+
+	switch (source) {
+	case S3C2410_DMASRC_HW:
+		config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
+		config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT;
+		break;
+	case S3C2410_DMASRC_MEM:
+		config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
+		config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT;
+		break;
+	default:
+		printk(KERN_ERR "%s: bad source\n", __func__);
+		return -EINVAL;
+	}
+
+	/* allow TC and ERR interrupts */
+	config |= PL080_CONFIG_TC_IRQ_MASK;
+	config |= PL080_CONFIG_ERR_IRQ_MASK;
+
+	pr_debug("%s: config %08x\n", __func__, config);
+
+	writel(config, chan->regs + PL080S_CH_CONFIG);
+
+	return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_devconfig);
+
+
+int s3c2410_dma_getposition(unsigned int channel,
+			    dma_addr_t *src, dma_addr_t *dst)
+{
+	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+	WARN_ON(!chan);
+	if (!chan)
+		return -EINVAL;
+
+	if (src != NULL)
+		*src = readl(chan->regs + PL080_CH_SRC_ADDR);
+
+	if (dst != NULL)
+		*dst = readl(chan->regs + PL080_CH_DST_ADDR);
+
+	return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_getposition);
+
+/* s3c2410_request_dma
+ *
+ * get control of an dma channel
+*/
+
+int s3c2410_dma_request(unsigned int channel,
+			struct s3c2410_dma_client *client,
+			void *dev)
+{
+	struct s3c2410_dma_chan *chan;
+	unsigned long flags;
+
+	pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
+		 channel, client->name, dev);
+
+	local_irq_save(flags);
+
+	chan = s3c64xx_dma_map_channel(channel);
+	if (chan == NULL) {
+		local_irq_restore(flags);
+		return -EBUSY;
+	}
+
+	dbg_showchan(chan);
+
+	chan->client = client;
+	chan->in_use = 1;
+	chan->peripheral = channel;
+
+	local_irq_restore(flags);
+
+	/* need to setup */
+
+	pr_debug("%s: channel initialised, %p\n", __func__, chan);
+
+	return chan->number | DMACH_LOW_LEVEL;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_request);
+
+/* s3c2410_dma_free
+ *
+ * release the given channel back to the system, will stop and flush
+ * any outstanding transfers, and ensure the channel is ready for the
+ * next claimant.
+ *
+ * Note, although a warning is currently printed if the freeing client
+ * info is not the same as the registrant's client info, the free is still
+ * allowed to go through.
+*/
+
+int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
+{
+	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+	unsigned long flags;
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	local_irq_save(flags);
+
+	if (chan->client != client) {
+		printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
+		       channel, chan->client, client);
+	}
+
+	/* sort out stopping and freeing the channel */
+
+
+	chan->client = NULL;
+	chan->in_use = 0;
+
+	if (!(channel & DMACH_LOW_LEVEL))
+		s3c_dma_chan_map[channel] = NULL;
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_free);
+
+static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
+{
+	struct s3c64xx_dmac *dmac = pw;
+	struct s3c2410_dma_chan *chan;
+	enum s3c2410_dma_buffresult res;
+	u32 tcstat, errstat;
+	u32 bit;
+	int offs;
+
+	tcstat = readl(dmac->regs + PL080_TC_STATUS);
+	errstat = readl(dmac->regs + PL080_ERR_STATUS);
+
+	for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) {
+		struct s3c64xx_dma_buff *buff;
+
+		if (!(errstat & bit) && !(tcstat & bit))
+			continue;
+
+		chan = dmac->channels + offs;
+		res = S3C2410_RES_ERR;
+
+		if (tcstat & bit) {
+			writel(bit, dmac->regs + PL080_TC_CLEAR);
+			res = S3C2410_RES_OK;
+		}
+
+		if (errstat & bit)
+			writel(bit, dmac->regs + PL080_ERR_CLEAR);
+
+		/* 'next' points to the buffer that is next to the
+		 * currently active buffer.
+		 * For CIRCULAR queues, 'next' will be same as 'curr'
+		 * when 'end' is the active buffer.
+		 */
+		buff = chan->curr;
+		while (buff && buff != chan->next
+				&& buff->next != chan->next)
+			buff = buff->next;
+
+		if (!buff)
+			BUG();
+
+		if (buff == chan->next)
+			buff = chan->end;
+
+		s3c64xx_dma_bufffdone(chan, buff, res);
+
+		/* Free the node and update curr, if non-circular queue */
+		if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) {
+			chan->curr = buff->next;
+			s3c64xx_dma_freebuff(buff);
+		}
+
+		/* Update 'next' */
+		buff = chan->next;
+		if (chan->next == chan->end) {
+			chan->next = chan->curr;
+			if (!(chan->flags & S3C2410_DMAF_CIRCULAR))
+				chan->end = NULL;
+		} else {
+			chan->next = buff->next;
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct sysdev_class dma_sysclass = {
+	.name		= "s3c64xx-dma",
+};
+
+static int s3c64xx_dma_init1(int chno, enum dma_ch chbase,
+			     int irq, unsigned int base)
+{
+	struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno];
+	struct s3c64xx_dmac *dmac;
+	char clkname[16];
+	void __iomem *regs;
+	void __iomem *regptr;
+	int err, ch;
+
+	dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL);
+	if (!dmac) {
+		printk(KERN_ERR "%s: failed to alloc mem\n", __func__);
+		return -ENOMEM;
+	}
+
+	dmac->sysdev.id = chno / 8;
+	dmac->sysdev.cls = &dma_sysclass;
+
+	err = sysdev_register(&dmac->sysdev);
+	if (err) {
+		printk(KERN_ERR "%s: failed to register sysdevice\n", __func__);
+		goto err_alloc;
+	}
+
+	regs = ioremap(base, 0x200);
+	if (!regs) {
+		printk(KERN_ERR "%s: failed to ioremap()\n", __func__);
+		err = -ENXIO;
+		goto err_dev;
+	}
+
+	snprintf(clkname, sizeof(clkname), "dma%d", dmac->sysdev.id);
+
+	dmac->clk = clk_get(NULL, clkname);
+	if (IS_ERR(dmac->clk)) {
+		printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname);
+		err = PTR_ERR(dmac->clk);
+		goto err_map;
+	}
+
+	clk_enable(dmac->clk);
+
+	dmac->regs = regs;
+	dmac->chanbase = chbase;
+	dmac->channels = chptr;
+
+	err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac);
+	if (err < 0) {
+		printk(KERN_ERR "%s: failed to get irq\n", __func__);
+		goto err_clk;
+	}
+
+	regptr = regs + PL080_Cx_BASE(0);
+
+	for (ch = 0; ch < 8; ch++, chno++, chptr++) {
+		printk(KERN_INFO "%s: registering DMA %d (%p)\n",
+		       __func__, chno, regptr);
+
+		chptr->bit = 1 << ch;
+		chptr->number = chno;
+		chptr->dmac = dmac;
+		chptr->regs = regptr;
+		regptr += PL008_Cx_STRIDE;
+	}
+
+	/* for the moment, permanently enable the controller */
+	writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG);
+
+	printk(KERN_INFO "PL080: IRQ %d, at %p\n", irq, regs);
+
+	return 0;
+
+err_clk:
+	clk_disable(dmac->clk);
+	clk_put(dmac->clk);
+err_map:
+	iounmap(regs);
+err_dev:
+	sysdev_unregister(&dmac->sysdev);
+err_alloc:
+	kfree(dmac);
+	return err;
+}
+
+static int __init s3c64xx_dma_init(void)
+{
+	int ret;
+
+	printk(KERN_INFO "%s: Registering DMA channels\n", __func__);
+
+	dma_pool = dma_pool_create("DMA-LLI", NULL, sizeof(struct pl080s_lli), 16, 0);
+	if (!dma_pool) {
+		printk(KERN_ERR "%s: failed to create pool\n", __func__);
+		return -ENOMEM;
+	}
+
+	ret = sysdev_class_register(&dma_sysclass);
+	if (ret) {
+		printk(KERN_ERR "%s: failed to create sysclass\n", __func__);
+		return -ENOMEM;
+	}
+
+	/* Set all DMA configuration to be DMA, not SDMA */
+	writel(0xffffff, S3C_SYSREG(0x110));
+
+	/* Register standard DMA controlers */
+	s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000);
+	s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000);
+
+	return 0;
+}
+
+arch_initcall(s3c64xx_dma_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/gpiolib.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/gpiolib.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/gpiolib.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/gpiolib.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,288 @@
+/* arch/arm/plat-s3c64xx/gpiolib.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - GPIOlib support 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/gpio.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <mach/regs-gpio.h>
+
+/* GPIO bank summary:
+ *
+ * Bank	GPIOs	Style	SlpCon	ExtInt Group
+ * A	8	4Bit	Yes	1
+ * B	7	4Bit	Yes	1
+ * C	8	4Bit	Yes	2
+ * D	5	4Bit	Yes	3
+ * E	5	4Bit	Yes	None
+ * F	16	2Bit	Yes	4 [1]
+ * G	7	4Bit	Yes	5
+ * H	10	4Bit[2]	Yes	6
+ * I	16	2Bit	Yes	None
+ * J	12	2Bit	Yes	None
+ * K	16	4Bit[2]	No	None
+ * L	15	4Bit[2] No	None
+ * M	6	4Bit	No	IRQ_EINT
+ * N	16	2Bit	No	IRQ_EINT
+ * O	16	2Bit	Yes	7
+ * P	15	2Bit	Yes	8
+ * Q	9	2Bit	Yes	9
+ *
+ * [1] BANKF pins 14,15 do not form part of the external interrupt sources
+ * [2] BANK has two control registers, GPxCON0 and GPxCON1
+ */
+
+static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
+	.cfg_eint	= 7,
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
+	.cfg_eint	= 3,
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+int s3c64xx_gpio2int_gpm(struct gpio_chip *chip, unsigned pin)
+{
+	return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
+}
+
+static struct s3c_gpio_chip gpio_4bit[] = {
+	{
+		.base	= S3C64XX_GPA_BASE,
+		.config	= &gpio_4bit_cfg_eint0111,
+		.chip	= {
+			.base	= S3C64XX_GPA(0),
+			.ngpio	= S3C64XX_GPIO_A_NR,
+			.label	= "GPA",
+		},
+	}, {
+		.base	= S3C64XX_GPB_BASE,
+		.config	= &gpio_4bit_cfg_eint0111,
+		.chip	= {
+			.base	= S3C64XX_GPB(0),
+			.ngpio	= S3C64XX_GPIO_B_NR,
+			.label	= "GPB",
+		},
+	}, {
+		.base	= S3C64XX_GPC_BASE,
+		.config	= &gpio_4bit_cfg_eint0111,
+		.chip	= {
+			.base	= S3C64XX_GPC(0),
+			.ngpio	= S3C64XX_GPIO_C_NR,
+			.label	= "GPC",
+		},
+	}, {
+		.base	= S3C64XX_GPD_BASE,
+		.config	= &gpio_4bit_cfg_eint0111,
+		.chip	= {
+			.base	= S3C64XX_GPD(0),
+			.ngpio	= S3C64XX_GPIO_D_NR,
+			.label	= "GPD",
+		},
+	}, {
+		.base	= S3C64XX_GPE_BASE,
+		.config	= &gpio_4bit_cfg_noint,
+		.chip	= {
+			.base	= S3C64XX_GPE(0),
+			.ngpio	= S3C64XX_GPIO_E_NR,
+			.label	= "GPE",
+		},
+	}, {
+		.base	= S3C64XX_GPG_BASE,
+		.config	= &gpio_4bit_cfg_eint0111,
+		.chip	= {
+			.base	= S3C64XX_GPG(0),
+			.ngpio	= S3C64XX_GPIO_G_NR,
+			.label	= "GPG",
+		},
+	}, {
+		.base	= S3C64XX_GPM_BASE,
+		.config	= &gpio_4bit_cfg_eint0011,
+		.chip	= {
+			.base	= S3C64XX_GPM(0),
+			.ngpio	= S3C64XX_GPIO_M_NR,
+			.label	= "GPM",
+			.to_irq = s3c64xx_gpio2int_gpm,
+		},
+	},
+};
+
+int s3c64xx_gpio2int_gpl(struct gpio_chip *chip, unsigned pin)
+{
+	return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
+}
+
+static struct s3c_gpio_chip gpio_4bit2[] = {
+	{
+		.base	= S3C64XX_GPH_BASE + 0x4,
+		.config	= &gpio_4bit_cfg_eint0111,
+		.chip	= {
+			.base	= S3C64XX_GPH(0),
+			.ngpio	= S3C64XX_GPIO_H_NR,
+			.label	= "GPH",
+		},
+	}, {
+		.base	= S3C64XX_GPK_BASE + 0x4,
+		.config	= &gpio_4bit_cfg_noint,
+		.chip	= {
+			.base	= S3C64XX_GPK(0),
+			.ngpio	= S3C64XX_GPIO_K_NR,
+			.label	= "GPK",
+		},
+	}, {
+		.base	= S3C64XX_GPL_BASE + 0x4,
+		.config	= &gpio_4bit_cfg_eint0011,
+		.chip	= {
+			.base	= S3C64XX_GPL(0),
+			.ngpio	= S3C64XX_GPIO_L_NR,
+			.label	= "GPL",
+			.to_irq = s3c64xx_gpio2int_gpl,
+		},
+	},
+};
+
+static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
+	.set_config	= s3c_gpio_setcfg_s3c24xx,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
+	.cfg_eint	= 2,
+	.set_config	= s3c_gpio_setcfg_s3c24xx,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
+	.cfg_eint	= 3,
+	.set_config	= s3c_gpio_setcfg_s3c24xx,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+int s3c64xx_gpio2int_gpn(struct gpio_chip *chip, unsigned pin)
+{
+	return IRQ_EINT(0) + pin;
+}
+
+static struct s3c_gpio_chip gpio_2bit[] = {
+	{
+		.base	= S3C64XX_GPF_BASE,
+		.config	= &gpio_2bit_cfg_eint11,
+		.chip	= {
+			.base	= S3C64XX_GPF(0),
+			.ngpio	= S3C64XX_GPIO_F_NR,
+			.label	= "GPF",
+		},
+	}, {
+		.base	= S3C64XX_GPI_BASE,
+		.config	= &gpio_2bit_cfg_noint,
+		.chip	= {
+			.base	= S3C64XX_GPI(0),
+			.ngpio	= S3C64XX_GPIO_I_NR,
+			.label	= "GPI",
+		},
+	}, {
+		.base	= S3C64XX_GPJ_BASE,
+		.config	= &gpio_2bit_cfg_noint,
+		.chip	= {
+			.base	= S3C64XX_GPJ(0),
+			.ngpio	= S3C64XX_GPIO_J_NR,
+			.label	= "GPJ",
+		},
+	}, {
+		.base	= S3C64XX_GPN_BASE,
+		.config	= &gpio_2bit_cfg_eint10,
+		.chip	= {
+			.base	= S3C64XX_GPN(0),
+			.ngpio	= S3C64XX_GPIO_N_NR,
+			.label	= "GPN",
+			.to_irq = s3c64xx_gpio2int_gpn,
+		},
+	}, {
+		.base	= S3C64XX_GPO_BASE,
+		.config	= &gpio_2bit_cfg_eint11,
+		.chip	= {
+			.base	= S3C64XX_GPO(0),
+			.ngpio	= S3C64XX_GPIO_O_NR,
+			.label	= "GPO",
+		},
+	}, {
+		.base	= S3C64XX_GPP_BASE,
+		.config	= &gpio_2bit_cfg_eint11,
+		.chip	= {
+			.base	= S3C64XX_GPP(0),
+			.ngpio	= S3C64XX_GPIO_P_NR,
+			.label	= "GPP",
+		},
+	}, {
+		.base	= S3C64XX_GPQ_BASE,
+		.config	= &gpio_2bit_cfg_eint11,
+		.chip	= {
+			.base	= S3C64XX_GPQ(0),
+			.ngpio	= S3C64XX_GPIO_Q_NR,
+			.label	= "GPQ",
+		},
+	},
+};
+
+static __init void s3c64xx_gpiolib_add_2bit(struct s3c_gpio_chip *chip)
+{
+	chip->pm = __gpio_pm(&s3c_gpio_pm_2bit);
+}
+
+static __init void s3c64xx_gpiolib_add(struct s3c_gpio_chip *chips,
+				       int nr_chips,
+				       void (*fn)(struct s3c_gpio_chip *))
+{
+	for (; nr_chips > 0; nr_chips--, chips++) {
+		if (fn)
+			(fn)(chips);
+		s3c_gpiolib_add(chips);
+	}
+}
+
+static __init int s3c64xx_gpiolib_init(void)
+{
+	s3c64xx_gpiolib_add(gpio_4bit, ARRAY_SIZE(gpio_4bit),
+			    samsung_gpiolib_add_4bit);
+
+	s3c64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2),
+			    samsung_gpiolib_add_4bit2);
+
+	s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit),
+			    s3c64xx_gpiolib_add_2bit);
+
+	return 0;
+}
+
+core_initcall(s3c64xx_gpiolib_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,39 @@
+/* arch/arm/mach-s3c6400/include/mach/debug-macro.S
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	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.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <mach/map.h>
+#include <plat/regs-serial.h>
+
+	/* note, for the boot process to work we have to keep the UART
+	 * virtual address aligned to an 1MiB boundary for the L1
+	 * mapping the head code makes. We keep the UART virtual address
+	 * aligned and add in the offset when we load the value here.
+	 */
+
+	.macro addruart, rx, rtmp
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1
+		ldreq	\rx, = S3C_PA_UART
+		ldrne	\rx, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)
+#if CONFIG_DEBUG_S3C_UART != 0
+		add	\rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
+#endif
+	.endm
+
+/* include the reset of the code which will do the work, we're only
+ * compiling for a single cpu processor type so the default of s3c2440
+ * will be fine with us.
+ */
+
+#include <plat/debug-macro.S>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/dma.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/dma.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/dma.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,127 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/dma.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C6400 - DMA support
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H __FILE__
+
+#define S3C_DMA_CHANNELS	(16)
+
+/* see mach-s3c2410/dma.h for notes on dma channel numbers */
+
+/* Note, for the S3C64XX architecture we keep the DMACH_
+ * defines in the order they are allocated to [S]DMA0/[S]DMA1
+ * so that is easy to do DHACH_ -> DMA controller conversion
+ */
+enum dma_ch {
+	/* DMA0/SDMA0 */
+	DMACH_UART0 = 0,
+	DMACH_UART0_SRC2,
+	DMACH_UART1,
+	DMACH_UART1_SRC2,
+	DMACH_UART2,
+	DMACH_UART2_SRC2,
+	DMACH_UART3,
+	DMACH_UART3_SRC2,
+	DMACH_PCM0_TX,
+	DMACH_PCM0_RX,
+	DMACH_I2S0_OUT,
+	DMACH_I2S0_IN,
+	DMACH_SPI0_TX,
+	DMACH_SPI0_RX,
+	DMACH_HSI_I2SV40_TX,
+	DMACH_HSI_I2SV40_RX,
+
+	/* DMA1/SDMA1 */
+	DMACH_PCM1_TX = 16,
+	DMACH_PCM1_RX,
+	DMACH_I2S1_OUT,
+	DMACH_I2S1_IN,
+	DMACH_SPI1_TX,
+	DMACH_SPI1_RX,
+	DMACH_AC97_PCMOUT,
+	DMACH_AC97_PCMIN,
+	DMACH_AC97_MICIN,
+	DMACH_PWM,
+	DMACH_IRDA,
+	DMACH_EXTERNAL,
+	DMACH_RES1,
+	DMACH_RES2,
+	DMACH_SECURITY_RX,	/* SDMA1 only */
+	DMACH_SECURITY_TX,	/* SDMA1 only */
+	DMACH_MAX		/* the end */
+};
+
+static __inline__ bool s3c_dma_has_circular(void)
+{
+	return true;
+}
+
+#define S3C2410_DMAF_CIRCULAR		(1 << 0)
+
+#include <plat/dma.h>
+
+#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
+
+struct s3c64xx_dma_buff;
+
+/** s3c64xx_dma_buff - S3C64XX DMA buffer descriptor
+ * @next: Pointer to next buffer in queue or ring.
+ * @pw: Client provided identifier
+ * @lli: Pointer to hardware descriptor this buffer is associated with.
+ * @lli_dma: Hardare address of the descriptor.
+ */
+struct s3c64xx_dma_buff {
+	struct s3c64xx_dma_buff *next;
+
+	void			*pw;
+	struct pl080s_lli	*lli;
+	dma_addr_t		 lli_dma;
+};
+
+struct s3c64xx_dmac;
+
+struct s3c2410_dma_chan {
+	unsigned char		 number;      /* number of this dma channel */
+	unsigned char		 in_use;      /* channel allocated */
+	unsigned char		 bit;	      /* bit for enable/disable/etc */
+	unsigned char		 hw_width;
+	unsigned char		 peripheral;
+
+	unsigned int		 flags;
+	enum s3c2410_dmasrc	 source;
+
+
+	dma_addr_t		dev_addr;
+
+	struct s3c2410_dma_client *client;
+	struct s3c64xx_dmac	*dmac;		/* pointer to controller */
+
+	void __iomem		*regs;
+
+	/* cdriver callbacks */
+	s3c2410_dma_cbfn_t	 callback_fn;	/* buffer done callback */
+	s3c2410_dma_opfn_t	 op_fn;		/* channel op callback */
+
+	/* buffer list and information */
+	struct s3c64xx_dma_buff	*curr;		/* current dma buffer */
+	struct s3c64xx_dma_buff	*next;		/* next buffer to load */
+	struct s3c64xx_dma_buff	*end;		/* end of queue */
+
+	/* note, when channel is running in circular mode, curr is the
+	 * first buffer enqueued, end is the last and curr is where the
+	 * last buffer-done event is set-at. The buffers are not freed
+	 * and the last buffer hardware descriptor points back to the
+	 * first.
+	 */
+};
+
+#include <plat/dma-core.h>
+
+#endif /* __ASM_ARCH_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/entry-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/entry-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/entry-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s3c6400/include/mach/entry-macro.S
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Low-level IRQ helper macros for the Samsung S3C64XX series
+ *
+ * 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/map.h>
+#include <mach/irqs.h>
+
+#include <asm/entry-macro-vic2.S>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,48 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * 	Ben Dooks <ben@simtec.co.uk>
+ * 	http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank A register and configuration definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C64XX_GPACON			(S3C64XX_GPA_BASE + 0x00)
+#define S3C64XX_GPADAT			(S3C64XX_GPA_BASE + 0x04)
+#define S3C64XX_GPAPUD			(S3C64XX_GPA_BASE + 0x08)
+#define S3C64XX_GPACONSLP		(S3C64XX_GPA_BASE + 0x0c)
+#define S3C64XX_GPAPUDSLP		(S3C64XX_GPA_BASE + 0x10)
+
+#define S3C64XX_GPA_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
+#define S3C64XX_GPA_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
+#define S3C64XX_GPA_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
+
+#define S3C64XX_GPA0_UART_RXD0		(0x02 << 0)
+#define S3C64XX_GPA0_EINT_G1_0		(0x07 << 0)
+
+#define S3C64XX_GPA1_UART_TXD0		(0x02 << 4)
+#define S3C64XX_GPA1_EINT_G1_1		(0x07 << 4)
+
+#define S3C64XX_GPA2_UART_nCTS0		(0x02 << 8)
+#define S3C64XX_GPA2_EINT_G1_2		(0x07 << 8)
+
+#define S3C64XX_GPA3_UART_nRTS0		(0x02 << 12)
+#define S3C64XX_GPA3_EINT_G1_3		(0x07 << 12)
+
+#define S3C64XX_GPA4_UART_RXD1		(0x02 << 16)
+#define S3C64XX_GPA4_EINT_G1_4		(0x07 << 16)
+
+#define S3C64XX_GPA5_UART_TXD1		(0x02 << 20)
+#define S3C64XX_GPA5_EINT_G1_5		(0x07 << 20)
+
+#define S3C64XX_GPA6_UART_nCTS1		(0x02 << 24)
+#define S3C64XX_GPA6_EINT_G1_6		(0x07 << 24)
+
+#define S3C64XX_GPA7_UART_nRTS1		(0x02 << 28)
+#define S3C64XX_GPA7_EINT_G1_7		(0x07 << 28)
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,60 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * 	Ben Dooks <ben@simtec.co.uk>
+ * 	http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank B register and configuration definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C64XX_GPBCON			(S3C64XX_GPB_BASE + 0x00)
+#define S3C64XX_GPBDAT			(S3C64XX_GPB_BASE + 0x04)
+#define S3C64XX_GPBPUD			(S3C64XX_GPB_BASE + 0x08)
+#define S3C64XX_GPBCONSLP		(S3C64XX_GPB_BASE + 0x0c)
+#define S3C64XX_GPBPUDSLP		(S3C64XX_GPB_BASE + 0x10)
+
+#define S3C64XX_GPB_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
+#define S3C64XX_GPB_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
+#define S3C64XX_GPB_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
+
+#define S3C64XX_GPB0_UART_RXD2		(0x02 << 0)
+#define S3C64XX_GPB0_EXTDMA_REQ		(0x03 << 0)
+#define S3C64XX_GPB0_IrDA_RXD		(0x04 << 0)
+#define S3C64XX_GPB0_ADDR_CF0		(0x05 << 0)
+#define S3C64XX_GPB0_EINT_G1_8		(0x07 << 0)
+
+#define S3C64XX_GPB1_UART_TXD2		(0x02 << 4)
+#define S3C64XX_GPB1_EXTDMA_ACK		(0x03 << 4)
+#define S3C64XX_GPB1_IrDA_TXD		(0x04 << 4)
+#define S3C64XX_GPB1_ADDR_CF1		(0x05 << 4)
+#define S3C64XX_GPB1_EINT_G1_9		(0x07 << 4)
+
+#define S3C64XX_GPB2_UART_RXD3		(0x02 << 8)
+#define S3C64XX_GPB2_IrDA_RXD		(0x03 << 8)
+#define S3C64XX_GPB2_EXTDMA_REQ		(0x04 << 8)
+#define S3C64XX_GPB2_ADDR_CF2		(0x05 << 8)
+#define S3C64XX_GPB2_I2C_SCL1		(0x06 << 8)
+#define S3C64XX_GPB2_EINT_G1_10		(0x07 << 8)
+
+#define S3C64XX_GPB3_UART_TXD3		(0x02 << 12)
+#define S3C64XX_GPB3_IrDA_TXD		(0x03 << 12)
+#define S3C64XX_GPB3_EXTDMA_ACK		(0x04 << 12)
+#define S3C64XX_GPB3_I2C_SDA1		(0x06 << 12)
+#define S3C64XX_GPB3_EINT_G1_11		(0x07 << 12)
+
+#define S3C64XX_GPB4_IrDA_SDBW		(0x02 << 16)
+#define S3C64XX_GPB4_CAM_FIELD		(0x03 << 16)
+#define S3C64XX_GPB4_CF_DATA_DIR	(0x04 << 16)
+#define S3C64XX_GPB4_EINT_G1_12		(0x07 << 16)
+
+#define S3C64XX_GPB5_I2C_SCL0		(0x02 << 20)
+#define S3C64XX_GPB5_EINT_G1_13		(0x07 << 20)
+
+#define S3C64XX_GPB6_I2C_SDA0		(0x02 << 24)
+#define S3C64XX_GPB6_EINT_G1_14		(0x07 << 24)
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,53 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * 	Ben Dooks <ben@simtec.co.uk>
+ * 	http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank C register and configuration definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C64XX_GPCCON			(S3C64XX_GPC_BASE + 0x00)
+#define S3C64XX_GPCDAT			(S3C64XX_GPC_BASE + 0x04)
+#define S3C64XX_GPCPUD			(S3C64XX_GPC_BASE + 0x08)
+#define S3C64XX_GPCCONSLP		(S3C64XX_GPC_BASE + 0x0c)
+#define S3C64XX_GPCPUDSLP		(S3C64XX_GPC_BASE + 0x10)
+
+#define S3C64XX_GPC_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
+#define S3C64XX_GPC_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
+#define S3C64XX_GPC_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
+
+#define S3C64XX_GPC0_SPI_MISO0		(0x02 << 0)
+#define S3C64XX_GPC0_EINT_G2_0		(0x07 << 0)
+
+#define S3C64XX_GPC1_SPI_CLKO		(0x02 << 4)
+#define S3C64XX_GPC1_EINT_G2_1		(0x07 << 4)
+
+#define S3C64XX_GPC2_SPI_MOSIO		(0x02 << 8)
+#define S3C64XX_GPC2_EINT_G2_2		(0x07 << 8)
+
+#define S3C64XX_GPC3_SPI_nCSO		(0x02 << 12)
+#define S3C64XX_GPC3_EINT_G2_3		(0x07 << 12)
+
+#define S3C64XX_GPC4_SPI_MISO1		(0x02 << 16)
+#define S3C64XX_GPC4_MMC2_CMD		(0x03 << 16)
+#define S3C64XX_GPC4_I2S_V40_DO0	(0x05 << 16)
+#define S3C64XX_GPC4_EINT_G2_4		(0x07 << 16)
+
+#define S3C64XX_GPC5_SPI_CLK1		(0x02 << 20)
+#define S3C64XX_GPC5_MMC2_CLK		(0x03 << 20)
+#define S3C64XX_GPC5_I2S_V40_DO1	(0x05 << 20)
+#define S3C64XX_GPC5_EINT_G2_5		(0x07 << 20)
+
+#define S3C64XX_GPC6_SPI_MOSI1		(0x02 << 24)
+#define S3C64XX_GPC6_EINT_G2_6		(0x07 << 24)
+
+#define S3C64XX_GPC7_SPI_nCS1		(0x02 << 28)
+#define S3C64XX_GPC7_I2S_V40_DO2	(0x05 << 28)
+#define S3C64XX_GPC7_EINT_G2_7		(0x07 << 28)
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,49 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * 	Ben Dooks <ben@simtec.co.uk>
+ * 	http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank D register and configuration definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C64XX_GPDCON			(S3C64XX_GPD_BASE + 0x00)
+#define S3C64XX_GPDDAT			(S3C64XX_GPD_BASE + 0x04)
+#define S3C64XX_GPDPUD			(S3C64XX_GPD_BASE + 0x08)
+#define S3C64XX_GPDCONSLP		(S3C64XX_GPD_BASE + 0x0c)
+#define S3C64XX_GPDPUDSLP		(S3C64XX_GPD_BASE + 0x10)
+
+#define S3C64XX_GPD_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
+#define S3C64XX_GPD_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
+#define S3C64XX_GPD_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
+
+#define S3C64XX_GPD0_PCM0_SCLK		(0x02 << 0)
+#define S3C64XX_GPD0_I2S0_CLK		(0x03 << 0)
+#define S3C64XX_GPD0_AC97_BITCLK	(0x04 << 0)
+#define S3C64XX_GPD0_EINT_G3_0		(0x07 << 0)
+
+#define S3C64XX_GPD1_PCM0_EXTCLK	(0x02 << 4)
+#define S3C64XX_GPD1_I2S0_CDCLK		(0x03 << 4)
+#define S3C64XX_GPD1_AC97_nRESET	(0x04 << 4)
+#define S3C64XX_GPD1_EINT_G3_1		(0x07 << 4)
+
+#define S3C64XX_GPD2_PCM0_FSYNC		(0x02 << 8)
+#define S3C64XX_GPD2_I2S0_LRCLK		(0x03 << 8)
+#define S3C64XX_GPD2_AC97_SYNC		(0x04 << 8)
+#define S3C64XX_GPD2_EINT_G3_2		(0x07 << 8)
+
+#define S3C64XX_GPD3_PCM0_SIN		(0x02 << 12)
+#define S3C64XX_GPD3_I2S0_DI		(0x03 << 12)
+#define S3C64XX_GPD3_AC97_SDI		(0x04 << 12)
+#define S3C64XX_GPD3_EINT_G3_3		(0x07 << 12)
+
+#define S3C64XX_GPD4_PCM0_SOUT		(0x02 << 16)
+#define S3C64XX_GPD4_I2S0_D0		(0x03 << 16)
+#define S3C64XX_GPD4_AC97_SDO		(0x04 << 16)
+#define S3C64XX_GPD4_EINT_G3_4		(0x07 << 16)
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,44 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * 	Ben Dooks <ben@simtec.co.uk>
+ * 	http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank E register and configuration definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C64XX_GPECON			(S3C64XX_GPE_BASE + 0x00)
+#define S3C64XX_GPEDAT			(S3C64XX_GPE_BASE + 0x04)
+#define S3C64XX_GPEPUD			(S3C64XX_GPE_BASE + 0x08)
+#define S3C64XX_GPECONSLP		(S3C64XX_GPE_BASE + 0x0c)
+#define S3C64XX_GPEPUDSLP		(S3C64XX_GPE_BASE + 0x10)
+
+#define S3C64XX_GPE_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
+#define S3C64XX_GPE_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
+#define S3C64XX_GPE_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
+
+#define S3C64XX_GPE0_PCM1_SCLK		(0x02 << 0)
+#define S3C64XX_GPE0_I2S1_CLK		(0x03 << 0)
+#define S3C64XX_GPE0_AC97_BITCLK	(0x04 << 0)
+
+#define S3C64XX_GPE1_PCM1_EXTCLK	(0x02 << 4)
+#define S3C64XX_GPE1_I2S1_CDCLK		(0x03 << 4)
+#define S3C64XX_GPE1_AC97_nRESET	(0x04 << 4)
+
+#define S3C64XX_GPE2_PCM1_FSYNC		(0x02 << 8)
+#define S3C64XX_GPE2_I2S1_LRCLK		(0x03 << 8)
+#define S3C64XX_GPE2_AC97_SYNC		(0x04 << 8)
+
+#define S3C64XX_GPE3_PCM1_SIN		(0x02 << 12)
+#define S3C64XX_GPE3_I2S1_DI		(0x03 << 12)
+#define S3C64XX_GPE3_AC97_SDI		(0x04 << 12)
+
+#define S3C64XX_GPE4_PCM1_SOUT		(0x02 << 16)
+#define S3C64XX_GPE4_I2S1_D0		(0x03 << 16)
+#define S3C64XX_GPE4_AC97_SDO		(0x04 << 16)
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,71 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * 	Ben Dooks <ben@simtec.co.uk>
+ * 	http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank F register and configuration definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C64XX_GPFCON			(S3C64XX_GPF_BASE + 0x00)
+#define S3C64XX_GPFDAT			(S3C64XX_GPF_BASE + 0x04)
+#define S3C64XX_GPFPUD			(S3C64XX_GPF_BASE + 0x08)
+#define S3C64XX_GPFCONSLP		(S3C64XX_GPF_BASE + 0x0c)
+#define S3C64XX_GPFPUDSLP		(S3C64XX_GPF_BASE + 0x10)
+
+#define S3C64XX_GPF_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
+#define S3C64XX_GPF_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
+#define S3C64XX_GPF_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
+
+#define S3C64XX_GPF0_CAMIF_CLK		(0x02 << 0)
+#define S3C64XX_GPF0_EINT_G4_0		(0x03 << 0)
+
+#define S3C64XX_GPF1_CAMIF_HREF		(0x02 << 2)
+#define S3C64XX_GPF1_EINT_G4_1		(0x03 << 2)
+
+#define S3C64XX_GPF2_CAMIF_PCLK		(0x02 << 4)
+#define S3C64XX_GPF2_EINT_G4_2		(0x03 << 4)
+
+#define S3C64XX_GPF3_CAMIF_nRST		(0x02 << 6)
+#define S3C64XX_GPF3_EINT_G4_3		(0x03 << 6)
+
+#define S3C64XX_GPF4_CAMIF_VSYNC	(0x02 << 8)
+#define S3C64XX_GPF4_EINT_G4_4		(0x03 << 8)
+
+#define S3C64XX_GPF5_CAMIF_YDATA0	(0x02 << 10)
+#define S3C64XX_GPF5_EINT_G4_5		(0x03 << 10)
+
+#define S3C64XX_GPF6_CAMIF_YDATA1	(0x02 << 12)
+#define S3C64XX_GPF6_EINT_G4_6		(0x03 << 12)
+
+#define S3C64XX_GPF7_CAMIF_YDATA2	(0x02 << 14)
+#define S3C64XX_GPF7_EINT_G4_7		(0x03 << 14)
+
+#define S3C64XX_GPF8_CAMIF_YDATA3	(0x02 << 16)
+#define S3C64XX_GPF8_EINT_G4_8		(0x03 << 16)
+
+#define S3C64XX_GPF9_CAMIF_YDATA4	(0x02 << 18)
+#define S3C64XX_GPF9_EINT_G4_9		(0x03 << 18)
+
+#define S3C64XX_GPF10_CAMIF_YDATA5	(0x02 << 20)
+#define S3C64XX_GPF10_EINT_G4_10	(0x03 << 20)
+
+#define S3C64XX_GPF11_CAMIF_YDATA6	(0x02 << 22)
+#define S3C64XX_GPF11_EINT_G4_11	(0x03 << 22)
+
+#define S3C64XX_GPF12_CAMIF_YDATA7	(0x02 << 24)
+#define S3C64XX_GPF12_EINT_G4_12	(0x03 << 24)
+
+#define S3C64XX_GPF13_PWM_ECLK		(0x02 << 26)
+#define S3C64XX_GPF13_EINT_G4_13	(0x03 << 26)
+
+#define S3C64XX_GPF14_PWM_TOUT0		(0x02 << 28)
+#define S3C64XX_GPF14_CLKOUT0		(0x03 << 28)
+
+#define S3C64XX_GPF15_PWM_TOUT1		(0x02 << 30)
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,42 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * 	Ben Dooks <ben@simtec.co.uk>
+ * 	http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank G register and configuration definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C64XX_GPGCON			(S3C64XX_GPG_BASE + 0x00)
+#define S3C64XX_GPGDAT			(S3C64XX_GPG_BASE + 0x04)
+#define S3C64XX_GPGPUD			(S3C64XX_GPG_BASE + 0x08)
+#define S3C64XX_GPGCONSLP		(S3C64XX_GPG_BASE + 0x0c)
+#define S3C64XX_GPGPUDSLP		(S3C64XX_GPG_BASE + 0x10)
+
+#define S3C64XX_GPG_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
+#define S3C64XX_GPG_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
+#define S3C64XX_GPG_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
+
+#define S3C64XX_GPG0_MMC0_CLK		(0x02 << 0)
+#define S3C64XX_GPG0_EINT_G5_0		(0x07 << 0)
+
+#define S3C64XX_GPG1_MMC0_CMD		(0x02 << 4)
+#define S3C64XX_GPG1_EINT_G5_1		(0x07 << 4)
+
+#define S3C64XX_GPG2_MMC0_DATA0		(0x02 << 8)
+#define S3C64XX_GPG2_EINT_G5_2		(0x07 << 8)
+
+#define S3C64XX_GPG3_MMC0_DATA1		(0x02 << 12)
+#define S3C64XX_GPG3_EINT_G5_3		(0x07 << 12)
+
+#define S3C64XX_GPG4_MMC0_DATA2		(0x02 << 16)
+#define S3C64XX_GPG4_EINT_G5_4		(0x07 << 16)
+
+#define S3C64XX_GPG5_MMC0_DATA3		(0x02 << 20)
+#define S3C64XX_GPG5_EINT_G5_5		(0x07 << 20)
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,74 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * 	Ben Dooks <ben@simtec.co.uk>
+ * 	http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank H register and configuration definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C64XX_GPHCON0			(S3C64XX_GPH_BASE + 0x00)
+#define S3C64XX_GPHCON1			(S3C64XX_GPH_BASE + 0x04)
+#define S3C64XX_GPHDAT			(S3C64XX_GPH_BASE + 0x08)
+#define S3C64XX_GPHPUD			(S3C64XX_GPH_BASE + 0x0c)
+#define S3C64XX_GPHCONSLP		(S3C64XX_GPH_BASE + 0x10)
+#define S3C64XX_GPHPUDSLP		(S3C64XX_GPH_BASE + 0x14)
+
+#define S3C64XX_GPH_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
+#define S3C64XX_GPH_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
+#define S3C64XX_GPH_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
+
+#define S3C64XX_GPH0_MMC1_CLK		(0x02 << 0)
+#define S3C64XX_GPH0_KP_COL0		(0x04 << 0)
+#define S3C64XX_GPH0_EINT_G6_0		(0x07 << 0)
+
+#define S3C64XX_GPH1_MMC1_CMD		(0x02 << 4)
+#define S3C64XX_GPH1_KP_COL1		(0x04 << 4)
+#define S3C64XX_GPH1_EINT_G6_1		(0x07 << 4)
+
+#define S3C64XX_GPH2_MMC1_DATA0		(0x02 << 8)
+#define S3C64XX_GPH2_KP_COL2		(0x04 << 8)
+#define S3C64XX_GPH2_EINT_G6_2		(0x07 << 8)
+
+#define S3C64XX_GPH3_MMC1_DATA1		(0x02 << 12)
+#define S3C64XX_GPH3_KP_COL3		(0x04 << 12)
+#define S3C64XX_GPH3_EINT_G6_3		(0x07 << 12)
+
+#define S3C64XX_GPH4_MMC1_DATA2		(0x02 << 16)
+#define S3C64XX_GPH4_KP_COL4		(0x04 << 16)
+#define S3C64XX_GPH4_EINT_G6_4		(0x07 << 16)
+
+#define S3C64XX_GPH5_MMC1_DATA3		(0x02 << 20)
+#define S3C64XX_GPH5_KP_COL5		(0x04 << 20)
+#define S3C64XX_GPH5_EINT_G6_5		(0x07 << 20)
+
+#define S3C64XX_GPH6_MMC1_DATA4		(0x02 << 24)
+#define S3C64XX_GPH6_MMC2_DATA0		(0x03 << 24)
+#define S3C64XX_GPH6_KP_COL6		(0x04 << 24)
+#define S3C64XX_GPH6_I2S_V40_BCLK	(0x05 << 24)
+#define S3C64XX_GPH6_ADDR_CF0		(0x06 << 24)
+#define S3C64XX_GPH6_EINT_G6_6		(0x07 << 24)
+
+#define S3C64XX_GPH7_MMC1_DATA5		(0x02 << 28)
+#define S3C64XX_GPH7_MMC2_DATA1		(0x03 << 28)
+#define S3C64XX_GPH7_KP_COL7		(0x04 << 28)
+#define S3C64XX_GPH7_I2S_V40_CDCLK	(0x05 << 28)
+#define S3C64XX_GPH7_ADDR_CF1		(0x06 << 28)
+#define S3C64XX_GPH7_EINT_G6_7		(0x07 << 28)
+
+#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.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,40 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * 	Ben Dooks <ben@simtec.co.uk>
+ * 	http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank I register and configuration definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C64XX_GPICON			(S3C64XX_GPI_BASE + 0x00)
+#define S3C64XX_GPIDAT			(S3C64XX_GPI_BASE + 0x04)
+#define S3C64XX_GPIPUD			(S3C64XX_GPI_BASE + 0x08)
+#define S3C64XX_GPICONSLP		(S3C64XX_GPI_BASE + 0x0c)
+#define S3C64XX_GPIPUDSLP		(S3C64XX_GPI_BASE + 0x10)
+
+#define S3C64XX_GPI_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
+#define S3C64XX_GPI_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
+#define S3C64XX_GPI_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
+
+#define S3C64XX_GPI0_VD0		(0x02 << 0)
+#define S3C64XX_GPI1_VD1		(0x02 << 2)
+#define S3C64XX_GPI2_VD2		(0x02 << 4)
+#define S3C64XX_GPI3_VD3		(0x02 << 6)
+#define S3C64XX_GPI4_VD4		(0x02 << 8)
+#define S3C64XX_GPI5_VD5		(0x02 << 10)
+#define S3C64XX_GPI6_VD6		(0x02 << 12)
+#define S3C64XX_GPI7_VD7		(0x02 << 14)
+#define S3C64XX_GPI8_VD8		(0x02 << 16)
+#define S3C64XX_GPI9_VD9		(0x02 << 18)
+#define S3C64XX_GPI10_VD10		(0x02 << 20)
+#define S3C64XX_GPI11_VD11		(0x02 << 22)
+#define S3C64XX_GPI12_VD12		(0x02 << 24)
+#define S3C64XX_GPI13_VD13		(0x02 << 26)
+#define S3C64XX_GPI14_VD14		(0x02 << 28)
+#define S3C64XX_GPI15_VD15		(0x02 << 30)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,36 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * 	Ben Dooks <ben@simtec.co.uk>
+ * 	http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank J register and configuration definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C64XX_GPJCON			(S3C64XX_GPJ_BASE + 0x00)
+#define S3C64XX_GPJDAT			(S3C64XX_GPJ_BASE + 0x04)
+#define S3C64XX_GPJPUD			(S3C64XX_GPJ_BASE + 0x08)
+#define S3C64XX_GPJCONSLP		(S3C64XX_GPJ_BASE + 0x0c)
+#define S3C64XX_GPJPUDSLP		(S3C64XX_GPJ_BASE + 0x10)
+
+#define S3C64XX_GPJ_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
+#define S3C64XX_GPJ_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
+#define S3C64XX_GPJ_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
+
+#define S3C64XX_GPJ0_VD16		(0x02 << 0)
+#define S3C64XX_GPJ1_VD17		(0x02 << 2)
+#define S3C64XX_GPJ2_VD18		(0x02 << 4)
+#define S3C64XX_GPJ3_VD19		(0x02 << 6)
+#define S3C64XX_GPJ4_VD20		(0x02 << 8)
+#define S3C64XX_GPJ5_VD21		(0x02 << 10)
+#define S3C64XX_GPJ6_VD22		(0x02 << 12)
+#define S3C64XX_GPJ7_VD23		(0x02 << 14)
+#define S3C64XX_GPJ8_LCD_HSYNC		(0x02 << 16)
+#define S3C64XX_GPJ9_LCD_VSYNC		(0x02 << 18)
+#define S3C64XX_GPJ10_LCD_VDEN		(0x02 << 20)
+#define S3C64XX_GPJ11_LCD_VCLK		(0x02 << 22)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,54 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * 	Ben Dooks <ben@simtec.co.uk>
+ * 	http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank N register and configuration definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C64XX_GPNCON			(S3C64XX_GPN_BASE + 0x00)
+#define S3C64XX_GPNDAT			(S3C64XX_GPN_BASE + 0x04)
+#define S3C64XX_GPNPUD			(S3C64XX_GPN_BASE + 0x08)
+
+#define S3C64XX_GPN_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
+#define S3C64XX_GPN_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
+#define S3C64XX_GPN_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
+
+#define S3C64XX_GPN0_EINT0		(0x02 << 0)
+#define S3C64XX_GPN0_KP_ROW0		(0x03 << 0)
+
+#define S3C64XX_GPN1_EINT1		(0x02 << 2)
+#define S3C64XX_GPN1_KP_ROW1		(0x03 << 2)
+
+#define S3C64XX_GPN2_EINT2		(0x02 << 4)
+#define S3C64XX_GPN2_KP_ROW2		(0x03 << 4)
+
+#define S3C64XX_GPN3_EINT3		(0x02 << 6)
+#define S3C64XX_GPN3_KP_ROW3		(0x03 << 6)
+
+#define S3C64XX_GPN4_EINT4		(0x02 << 8)
+#define S3C64XX_GPN4_KP_ROW4		(0x03 << 8)
+
+#define S3C64XX_GPN5_EINT5		(0x02 << 10)
+#define S3C64XX_GPN5_KP_ROW5		(0x03 << 10)
+
+#define S3C64XX_GPN6_EINT6		(0x02 << 12)
+#define S3C64XX_GPN6_KP_ROW6		(0x03 << 12)
+
+#define S3C64XX_GPN7_EINT7		(0x02 << 14)
+#define S3C64XX_GPN7_KP_ROW7		(0x03 << 14)
+
+#define S3C64XX_GPN8_EINT8		(0x02 << 16)
+#define S3C64XX_GPN9_EINT9		(0x02 << 18)
+#define S3C64XX_GPN10_EINT10		(0x02 << 20)
+#define S3C64XX_GPN11_EINT11		(0x02 << 22)
+#define S3C64XX_GPN12_EINT12		(0x02 << 24)
+#define S3C64XX_GPN13_EINT13		(0x02 << 26)
+#define S3C64XX_GPN14_EINT14		(0x02 << 28)
+#define S3C64XX_GPN15_EINT15		(0x02 << 30)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,70 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * 	Ben Dooks <ben@simtec.co.uk>
+ * 	http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank O register and configuration definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C64XX_GPOCON			(S3C64XX_GPO_BASE + 0x00)
+#define S3C64XX_GPODAT			(S3C64XX_GPO_BASE + 0x04)
+#define S3C64XX_GPOPUD			(S3C64XX_GPO_BASE + 0x08)
+#define S3C64XX_GPOCONSLP		(S3C64XX_GPO_BASE + 0x0c)
+#define S3C64XX_GPOPUDSLP		(S3C64XX_GPO_BASE + 0x10)
+
+#define S3C64XX_GPO_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
+#define S3C64XX_GPO_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
+#define S3C64XX_GPO_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
+
+#define S3C64XX_GPO0_MEM0_nCS2		(0x02 << 0)
+#define S3C64XX_GPO0_EINT_G7_0		(0x03 << 0)
+
+#define S3C64XX_GPO1_MEM0_nCS3		(0x02 << 2)
+#define S3C64XX_GPO1_EINT_G7_1		(0x03 << 2)
+
+#define S3C64XX_GPO2_MEM0_nCS4		(0x02 << 4)
+#define S3C64XX_GPO2_EINT_G7_2		(0x03 << 4)
+
+#define S3C64XX_GPO3_MEM0_nCS5		(0x02 << 6)
+#define S3C64XX_GPO3_EINT_G7_3		(0x03 << 6)
+
+#define S3C64XX_GPO4_EINT_G7_4		(0x03 << 8)
+
+#define S3C64XX_GPO5_EINT_G7_5		(0x03 << 10)
+
+#define S3C64XX_GPO6_MEM0_ADDR6		(0x02 << 12)
+#define S3C64XX_GPO6_EINT_G7_6		(0x03 << 12)
+
+#define S3C64XX_GPO7_MEM0_ADDR7		(0x02 << 14)
+#define S3C64XX_GPO7_EINT_G7_7		(0x03 << 14)
+
+#define S3C64XX_GPO8_MEM0_ADDR8		(0x02 << 16)
+#define S3C64XX_GPO8_EINT_G7_8		(0x03 << 16)
+
+#define S3C64XX_GPO9_MEM0_ADDR9		(0x02 << 18)
+#define S3C64XX_GPO9_EINT_G7_9		(0x03 << 18)
+
+#define S3C64XX_GPO10_MEM0_ADDR10	(0x02 << 20)
+#define S3C64XX_GPO10_EINT_G7_10	(0x03 << 20)
+
+#define S3C64XX_GPO11_MEM0_ADDR11	(0x02 << 22)
+#define S3C64XX_GPO11_EINT_G7_11	(0x03 << 22)
+
+#define S3C64XX_GPO12_MEM0_ADDR12	(0x02 << 24)
+#define S3C64XX_GPO12_EINT_G7_12	(0x03 << 24)
+
+#define S3C64XX_GPO13_MEM0_ADDR13	(0x02 << 26)
+#define S3C64XX_GPO13_EINT_G7_13	(0x03 << 26)
+
+#define S3C64XX_GPO14_MEM0_ADDR14	(0x02 << 28)
+#define S3C64XX_GPO14_EINT_G7_14	(0x03 << 28)
+
+#define S3C64XX_GPO15_MEM0_ADDR15	(0x02 << 30)
+#define S3C64XX_GPO15_EINT_G7_15	(0x03 << 30)
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,69 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * 	Ben Dooks <ben@simtec.co.uk>
+ * 	http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank P register and configuration definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C64XX_GPPCON			(S3C64XX_GPP_BASE + 0x00)
+#define S3C64XX_GPPDAT			(S3C64XX_GPP_BASE + 0x04)
+#define S3C64XX_GPPPUD			(S3C64XX_GPP_BASE + 0x08)
+#define S3C64XX_GPPCONSLP		(S3C64XX_GPP_BASE + 0x0c)
+#define S3C64XX_GPPPUDSLP		(S3C64XX_GPP_BASE + 0x10)
+
+#define S3C64XX_GPP_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
+#define S3C64XX_GPP_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
+#define S3C64XX_GPP_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
+
+#define S3C64XX_GPP0_MEM0_ADDRV		(0x02 << 0)
+#define S3C64XX_GPP0_EINT_G8_0		(0x03 << 0)
+
+#define S3C64XX_GPP1_MEM0_SMCLK		(0x02 << 2)
+#define S3C64XX_GPP1_EINT_G8_1		(0x03 << 2)
+
+#define S3C64XX_GPP2_MEM0_nWAIT		(0x02 << 4)
+#define S3C64XX_GPP2_EINT_G8_2		(0x03 << 4)
+
+#define S3C64XX_GPP3_MEM0_RDY0_ALE	(0x02 << 6)
+#define S3C64XX_GPP3_EINT_G8_3		(0x03 << 6)
+
+#define S3C64XX_GPP4_MEM0_RDY1_CLE	(0x02 << 8)
+#define S3C64XX_GPP4_EINT_G8_4		(0x03 << 8)
+
+#define S3C64XX_GPP5_MEM0_INTsm0_FWE	(0x02 << 10)
+#define S3C64XX_GPP5_EINT_G8_5		(0x03 << 10)
+
+#define S3C64XX_GPP6_MEM0_(null)	(0x02 << 12)
+#define S3C64XX_GPP6_EINT_G8_6		(0x03 << 12)
+
+#define S3C64XX_GPP7_MEM0_INTsm1_FRE	(0x02 << 14)
+#define S3C64XX_GPP7_EINT_G8_7		(0x03 << 14)
+
+#define S3C64XX_GPP8_MEM0_RPn_RnB	(0x02 << 16)
+#define S3C64XX_GPP8_EINT_G8_8		(0x03 << 16)
+
+#define S3C64XX_GPP9_MEM0_ATA_RESET	(0x02 << 18)
+#define S3C64XX_GPP9_EINT_G8_9		(0x03 << 18)
+
+#define S3C64XX_GPP10_MEM0_ATA_INPACK	(0x02 << 20)
+#define S3C64XX_GPP10_EINT_G8_10	(0x03 << 20)
+
+#define S3C64XX_GPP11_MEM0_ATA_REG	(0x02 << 22)
+#define S3C64XX_GPP11_EINT_G8_11	(0x03 << 22)
+
+#define S3C64XX_GPP12_MEM0_ATA_WE	(0x02 << 24)
+#define S3C64XX_GPP12_EINT_G8_12	(0x03 << 24)
+
+#define S3C64XX_GPP13_MEM0_ATA_OE	(0x02 << 26)
+#define S3C64XX_GPP13_EINT_G8_13	(0x03 << 26)
+
+#define S3C64XX_GPP14_MEM0_ATA_CD	(0x02 << 28)
+#define S3C64XX_GPP14_EINT_G8_14	(0x03 << 28)
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,46 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * 	Ben Dooks <ben@simtec.co.uk>
+ * 	http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank Q register and configuration definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C64XX_GPQCON			(S3C64XX_GPQ_BASE + 0x00)
+#define S3C64XX_GPQDAT			(S3C64XX_GPQ_BASE + 0x04)
+#define S3C64XX_GPQPUD			(S3C64XX_GPQ_BASE + 0x08)
+#define S3C64XX_GPQCONSLP		(S3C64XX_GPQ_BASE + 0x0c)
+#define S3C64XX_GPQPUDSLP		(S3C64XX_GPQ_BASE + 0x10)
+
+#define S3C64XX_GPQ_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
+#define S3C64XX_GPQ_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
+#define S3C64XX_GPQ_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
+
+#define S3C64XX_GPQ0_MEM0_ADDR18_RAS	(0x02 << 0)
+#define S3C64XX_GPQ0_EINT_G9_0		(0x03 << 0)
+
+#define S3C64XX_GPQ1_MEM0_ADDR19_CAS	(0x02 << 2)
+#define S3C64XX_GPQ1_EINT_G9_1		(0x03 << 2)
+
+#define S3C64XX_GPQ2_EINT_G9_2		(0x03 << 4)
+
+#define S3C64XX_GPQ3_EINT_G9_3		(0x03 << 6)
+
+#define S3C64XX_GPQ4_EINT_G9_4		(0x03 << 8)
+
+#define S3C64XX_GPQ5_EINT_G9_5		(0x03 << 10)
+
+#define S3C64XX_GPQ6_EINT_G9_6		(0x03 << 12)
+
+#define S3C64XX_GPQ7_MEM0_ADDR17_WENDMC	(0x02 << 14)
+#define S3C64XX_GPQ7_EINT_G9_7		(0x03 << 14)
+
+#define S3C64XX_GPQ8_MEM0_ADDR16_APDMC	(0x02 << 16)
+#define S3C64XX_GPQ8_EINT_G9_8		(0x03 << 16)
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/gpio.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,100 @@
+/* arch/arm/mach-s3c6400/include/mach/gpio.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C6400 - GPIO lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define gpio_get_value	__gpio_get_value
+#define gpio_set_value	__gpio_set_value
+#define gpio_cansleep	__gpio_cansleep
+#define gpio_to_irq	__gpio_to_irq
+
+/* GPIO bank sizes */
+#define S3C64XX_GPIO_A_NR	(8)
+#define S3C64XX_GPIO_B_NR	(7)
+#define S3C64XX_GPIO_C_NR	(8)
+#define S3C64XX_GPIO_D_NR	(5)
+#define S3C64XX_GPIO_E_NR	(5)
+#define S3C64XX_GPIO_F_NR	(16)
+#define S3C64XX_GPIO_G_NR	(7)
+#define S3C64XX_GPIO_H_NR	(10)
+#define S3C64XX_GPIO_I_NR	(16)
+#define S3C64XX_GPIO_J_NR	(12)
+#define S3C64XX_GPIO_K_NR	(16)
+#define S3C64XX_GPIO_L_NR	(15)
+#define S3C64XX_GPIO_M_NR	(6)
+#define S3C64XX_GPIO_N_NR	(16)
+#define S3C64XX_GPIO_O_NR	(16)
+#define S3C64XX_GPIO_P_NR	(15)
+#define S3C64XX_GPIO_Q_NR	(9)
+
+/* GPIO bank numbes */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+
+#define S3C64XX_GPIO_NEXT(__gpio) \
+	((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s3c_gpio_number {
+	S3C64XX_GPIO_A_START = 0,
+	S3C64XX_GPIO_B_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_A),
+	S3C64XX_GPIO_C_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_B),
+	S3C64XX_GPIO_D_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_C),
+	S3C64XX_GPIO_E_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_D),
+	S3C64XX_GPIO_F_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_E),
+	S3C64XX_GPIO_G_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_F),
+	S3C64XX_GPIO_H_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_G),
+	S3C64XX_GPIO_I_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_H),
+	S3C64XX_GPIO_J_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_I),
+	S3C64XX_GPIO_K_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_J),
+	S3C64XX_GPIO_L_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_K),
+	S3C64XX_GPIO_M_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_L),
+	S3C64XX_GPIO_N_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_M),
+	S3C64XX_GPIO_O_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_N),
+	S3C64XX_GPIO_P_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_O),
+	S3C64XX_GPIO_Q_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_P),
+};
+
+/* S3C64XX GPIO number definitions. */
+
+#define S3C64XX_GPA(_nr)	(S3C64XX_GPIO_A_START + (_nr))
+#define S3C64XX_GPB(_nr)	(S3C64XX_GPIO_B_START + (_nr))
+#define S3C64XX_GPC(_nr)	(S3C64XX_GPIO_C_START + (_nr))
+#define S3C64XX_GPD(_nr)	(S3C64XX_GPIO_D_START + (_nr))
+#define S3C64XX_GPE(_nr)	(S3C64XX_GPIO_E_START + (_nr))
+#define S3C64XX_GPF(_nr)	(S3C64XX_GPIO_F_START + (_nr))
+#define S3C64XX_GPG(_nr)	(S3C64XX_GPIO_G_START + (_nr))
+#define S3C64XX_GPH(_nr)	(S3C64XX_GPIO_H_START + (_nr))
+#define S3C64XX_GPI(_nr)	(S3C64XX_GPIO_I_START + (_nr))
+#define S3C64XX_GPJ(_nr)	(S3C64XX_GPIO_J_START + (_nr))
+#define S3C64XX_GPK(_nr)	(S3C64XX_GPIO_K_START + (_nr))
+#define S3C64XX_GPL(_nr)	(S3C64XX_GPIO_L_START + (_nr))
+#define S3C64XX_GPM(_nr)	(S3C64XX_GPIO_M_START + (_nr))
+#define S3C64XX_GPN(_nr)	(S3C64XX_GPIO_N_START + (_nr))
+#define S3C64XX_GPO(_nr)	(S3C64XX_GPIO_O_START + (_nr))
+#define S3C64XX_GPP(_nr)	(S3C64XX_GPIO_P_START + (_nr))
+#define S3C64XX_GPQ(_nr)	(S3C64XX_GPIO_Q_START + (_nr))
+
+/* the end of the S3C64XX specific gpios */
+#define S3C64XX_GPIO_END	(S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
+#define S3C_GPIO_END		S3C64XX_GPIO_END
+
+/* define the number of gpios we need to the one after the GPQ() range */
+#define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
+
+#define BOARD_NR_GPIOS 16
+
+#define ARCH_NR_GPIOS	(GPIO_BOARD_START + BOARD_NR_GPIOS)
+
+#include <asm-generic/gpio.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/hardware.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/hardware.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/hardware.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,16 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/hardware.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C6400 - Hardware support
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H __FILE__
+
+/* currently nothing here, placeholder */
+
+#endif /* __ASM_ARCH_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/io.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/io.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/io.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s3c64xxinclude/mach/io.h
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S3C64XX based
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a)		__typesafe_io(a)
+#define __mem_pci(a)	(a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/irqs.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/irqs.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/irqs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,216 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/irqs.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - IRQ support
+ */
+
+#ifndef __ASM_MACH_S3C64XX_IRQS_H
+#define __ASM_MACH_S3C64XX_IRQS_H __FILE__
+
+/* we keep the first set of CPU IRQs out of the range of
+ * the ISA space, so that the PC104 has them to itself
+ * and we don't end up having to do horrible things to the
+ * standard ISA drivers....
+ *
+ * note, since we're using the VICs, our start must be a
+ * mulitple of 32 to allow the common code to work
+ */
+
+#define S3C_IRQ_OFFSET	(32)
+
+#define S3C_IRQ(x)	((x) + S3C_IRQ_OFFSET)
+
+#define IRQ_VIC0_BASE	S3C_IRQ(0)
+#define IRQ_VIC1_BASE	S3C_IRQ(32)
+
+/* UART interrupts, each UART has 4 intterupts per channel so
+ * use the space between the ISA and S3C main interrupts. Note, these
+ * are not in the same order as the S3C24XX series! */
+
+#define IRQ_S3CUART_BASE0	(16)
+#define IRQ_S3CUART_BASE1	(20)
+#define IRQ_S3CUART_BASE2	(24)
+#define IRQ_S3CUART_BASE3	(28)
+
+#define UART_IRQ_RXD		(0)
+#define UART_IRQ_ERR		(1)
+#define UART_IRQ_TXD		(2)
+#define UART_IRQ_MODEM		(3)
+
+#define IRQ_S3CUART_RX0		(IRQ_S3CUART_BASE0 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX0		(IRQ_S3CUART_BASE0 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR0	(IRQ_S3CUART_BASE0 + UART_IRQ_ERR)
+
+#define IRQ_S3CUART_RX1		(IRQ_S3CUART_BASE1 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX1		(IRQ_S3CUART_BASE1 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR1	(IRQ_S3CUART_BASE1 + UART_IRQ_ERR)
+
+#define IRQ_S3CUART_RX2		(IRQ_S3CUART_BASE2 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX2		(IRQ_S3CUART_BASE2 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR2	(IRQ_S3CUART_BASE2 + UART_IRQ_ERR)
+
+#define IRQ_S3CUART_RX3		(IRQ_S3CUART_BASE3 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX3		(IRQ_S3CUART_BASE3 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR3	(IRQ_S3CUART_BASE3 + UART_IRQ_ERR)
+
+/* VIC based IRQs */
+
+#define S3C64XX_IRQ_VIC0(x)	(IRQ_VIC0_BASE + (x))
+#define S3C64XX_IRQ_VIC1(x)	(IRQ_VIC1_BASE + (x))
+
+/* VIC0 */
+
+#define IRQ_EINT0_3		S3C64XX_IRQ_VIC0(0)
+#define IRQ_EINT4_11		S3C64XX_IRQ_VIC0(1)
+#define IRQ_RTC_TIC		S3C64XX_IRQ_VIC0(2)
+#define IRQ_CAMIF_C		S3C64XX_IRQ_VIC0(3)
+#define IRQ_CAMIF_P		S3C64XX_IRQ_VIC0(4)
+#define IRQ_CAMIF_MC		S3C64XX_IRQ_VIC0(5)
+#define IRQ_S3C6410_IIC1	S3C64XX_IRQ_VIC0(5)
+#define IRQ_S3C6410_IIS		S3C64XX_IRQ_VIC0(6)
+#define IRQ_S3C6400_CAMIF_MP	S3C64XX_IRQ_VIC0(6)
+#define IRQ_CAMIF_WE_C		S3C64XX_IRQ_VIC0(7)
+#define IRQ_S3C6410_G3D		S3C64XX_IRQ_VIC0(8)
+#define IRQ_S3C6400_CAMIF_WE_P	S3C64XX_IRQ_VIC0(8)
+#define IRQ_POST0		S3C64XX_IRQ_VIC0(9)
+#define IRQ_ROTATOR		S3C64XX_IRQ_VIC0(10)
+#define IRQ_2D			S3C64XX_IRQ_VIC0(11)
+#define IRQ_TVENC		S3C64XX_IRQ_VIC0(12)
+#define IRQ_SCALER		S3C64XX_IRQ_VIC0(13)
+#define IRQ_BATF		S3C64XX_IRQ_VIC0(14)
+#define IRQ_JPEG		S3C64XX_IRQ_VIC0(15)
+#define IRQ_MFC			S3C64XX_IRQ_VIC0(16)
+#define IRQ_SDMA0		S3C64XX_IRQ_VIC0(17)
+#define IRQ_SDMA1		S3C64XX_IRQ_VIC0(18)
+#define IRQ_ARM_DMAERR		S3C64XX_IRQ_VIC0(19)
+#define IRQ_ARM_DMA		S3C64XX_IRQ_VIC0(20)
+#define IRQ_ARM_DMAS		S3C64XX_IRQ_VIC0(21)
+#define IRQ_KEYPAD		S3C64XX_IRQ_VIC0(22)
+#define IRQ_TIMER0_VIC		S3C64XX_IRQ_VIC0(23)
+#define IRQ_TIMER1_VIC		S3C64XX_IRQ_VIC0(24)
+#define IRQ_TIMER2_VIC		S3C64XX_IRQ_VIC0(25)
+#define IRQ_WDT			S3C64XX_IRQ_VIC0(26)
+#define IRQ_TIMER3_VIC		S3C64XX_IRQ_VIC0(27)
+#define IRQ_TIMER4_VIC		S3C64XX_IRQ_VIC0(28)
+#define IRQ_LCD_FIFO		S3C64XX_IRQ_VIC0(29)
+#define IRQ_LCD_VSYNC		S3C64XX_IRQ_VIC0(30)
+#define IRQ_LCD_SYSTEM		S3C64XX_IRQ_VIC0(31)
+
+/* VIC1 */
+
+#define IRQ_EINT12_19		S3C64XX_IRQ_VIC1(0)
+#define IRQ_EINT20_27		S3C64XX_IRQ_VIC1(1)
+#define IRQ_PCM0		S3C64XX_IRQ_VIC1(2)
+#define IRQ_PCM1		S3C64XX_IRQ_VIC1(3)
+#define IRQ_AC97		S3C64XX_IRQ_VIC1(4)
+#define IRQ_UART0		S3C64XX_IRQ_VIC1(5)
+#define IRQ_UART1		S3C64XX_IRQ_VIC1(6)
+#define IRQ_UART2		S3C64XX_IRQ_VIC1(7)
+#define IRQ_UART3		S3C64XX_IRQ_VIC1(8)
+#define IRQ_DMA0		S3C64XX_IRQ_VIC1(9)
+#define IRQ_DMA1		S3C64XX_IRQ_VIC1(10)
+#define IRQ_ONENAND0		S3C64XX_IRQ_VIC1(11)
+#define IRQ_ONENAND1		S3C64XX_IRQ_VIC1(12)
+#define IRQ_NFC			S3C64XX_IRQ_VIC1(13)
+#define IRQ_CFCON		S3C64XX_IRQ_VIC1(14)
+#define IRQ_USBH		S3C64XX_IRQ_VIC1(15)
+#define IRQ_SPI0		S3C64XX_IRQ_VIC1(16)
+#define IRQ_SPI1		S3C64XX_IRQ_VIC1(17)
+#define IRQ_IIC			S3C64XX_IRQ_VIC1(18)
+#define IRQ_HSItx		S3C64XX_IRQ_VIC1(19)
+#define IRQ_HSIrx		S3C64XX_IRQ_VIC1(20)
+#define IRQ_RESERVED		S3C64XX_IRQ_VIC1(21)
+#define IRQ_MSM			S3C64XX_IRQ_VIC1(22)
+#define IRQ_HOSTIF		S3C64XX_IRQ_VIC1(23)
+#define IRQ_HSMMC0		S3C64XX_IRQ_VIC1(24)
+#define IRQ_HSMMC1		S3C64XX_IRQ_VIC1(25)
+#define IRQ_HSMMC2		IRQ_SPI1	/* shared with SPI1 */
+#define IRQ_OTG			S3C64XX_IRQ_VIC1(26)
+#define IRQ_IRDA		S3C64XX_IRQ_VIC1(27)
+#define IRQ_RTC_ALARM		S3C64XX_IRQ_VIC1(28)
+#define IRQ_SEC			S3C64XX_IRQ_VIC1(29)
+#define IRQ_PENDN		S3C64XX_IRQ_VIC1(30)
+#define IRQ_TC			IRQ_PENDN
+#define IRQ_ADC			S3C64XX_IRQ_VIC1(31)
+
+#define S3C64XX_TIMER_IRQ(x)	S3C_IRQ(64 + (x))
+
+#define IRQ_TIMER0		S3C64XX_TIMER_IRQ(0)
+#define IRQ_TIMER1		S3C64XX_TIMER_IRQ(1)
+#define IRQ_TIMER2		S3C64XX_TIMER_IRQ(2)
+#define IRQ_TIMER3		S3C64XX_TIMER_IRQ(3)
+#define IRQ_TIMER4		S3C64XX_TIMER_IRQ(4)
+
+/* compatibility for device defines */
+
+#define IRQ_IIC1		IRQ_S3C6410_IIC1
+
+/* Since the IRQ_EINT(x) are a linear mapping on current s3c64xx series
+ * we just defined them as an IRQ_EINT(x) macro from S3C_IRQ_EINT_BASE
+ * which we place after the pair of VICs. */
+
+#define S3C_IRQ_EINT_BASE	S3C_IRQ(64+5)
+
+#define S3C_EINT(x)		((x) + S3C_IRQ_EINT_BASE)
+#define IRQ_EINT(x)		S3C_EINT(x)
+#define IRQ_EINT_BIT(x)		((x) - S3C_EINT(0))
+
+/* Next the external interrupt groups. These are similar to the IRQ_EINT(x)
+ * that they are sourced from the GPIO pins but with a different scheme for
+ * priority and source indication.
+ *
+ * The IRQ_EINT(x) can be thought of as 'group 0' of the available GPIO
+ * interrupts, but for historical reasons they are kept apart from these
+ * next interrupts.
+ *
+ * Use IRQ_EINT_GROUP(group, offset) to get the number for use in the
+ * machine specific support files.
+ */
+
+#define IRQ_EINT_GROUP1_NR	(15)
+#define IRQ_EINT_GROUP2_NR	(8)
+#define IRQ_EINT_GROUP3_NR	(5)
+#define IRQ_EINT_GROUP4_NR	(14)
+#define IRQ_EINT_GROUP5_NR	(7)
+#define IRQ_EINT_GROUP6_NR	(10)
+#define IRQ_EINT_GROUP7_NR	(16)
+#define IRQ_EINT_GROUP8_NR	(15)
+#define IRQ_EINT_GROUP9_NR	(9)
+
+#define IRQ_EINT_GROUP_BASE	S3C_EINT(28)
+#define IRQ_EINT_GROUP1_BASE	(IRQ_EINT_GROUP_BASE + 0x00)
+#define IRQ_EINT_GROUP2_BASE	(IRQ_EINT_GROUP1_BASE + IRQ_EINT_GROUP1_NR)
+#define IRQ_EINT_GROUP3_BASE	(IRQ_EINT_GROUP2_BASE + IRQ_EINT_GROUP2_NR)
+#define IRQ_EINT_GROUP4_BASE	(IRQ_EINT_GROUP3_BASE + IRQ_EINT_GROUP3_NR)
+#define IRQ_EINT_GROUP5_BASE	(IRQ_EINT_GROUP4_BASE + IRQ_EINT_GROUP4_NR)
+#define IRQ_EINT_GROUP6_BASE	(IRQ_EINT_GROUP5_BASE + IRQ_EINT_GROUP5_NR)
+#define IRQ_EINT_GROUP7_BASE	(IRQ_EINT_GROUP6_BASE + IRQ_EINT_GROUP6_NR)
+#define IRQ_EINT_GROUP8_BASE	(IRQ_EINT_GROUP7_BASE + IRQ_EINT_GROUP7_NR)
+#define IRQ_EINT_GROUP9_BASE	(IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR)
+
+#define IRQ_EINT_GROUP(group, no)	(IRQ_EINT_GROUP##group##_BASE + (no))
+
+/* Define a group of interrupts for board-specific use (eg, for MFD
+ * interrupt controllers). */
+#define IRQ_BOARD_START (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1)
+
+#ifdef CONFIG_SMDK6410_WM1190_EV1
+#define IRQ_BOARD_NR 64
+#elif defined(CONFIG_SMDK6410_WM1192_EV1)
+#define IRQ_BOARD_NR 64
+#else
+#define IRQ_BOARD_NR 16
+#endif
+
+#define IRQ_BOARD_END (IRQ_BOARD_START + IRQ_BOARD_NR)
+
+/* Set the default NR_IRQS */
+
+#define NR_IRQS	(IRQ_BOARD_END + 1)
+
+#endif /* __ASM_MACH_S3C64XX_IRQS_H */
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/map.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/map.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/map.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/map.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,107 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/map.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - Memory 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_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+
+/*
+ * Post-mux Chip Select Regions Xm0CSn_
+ * These may be used by SROM, NAND or CF depending on settings
+ */
+
+#define S3C64XX_PA_XM0CSN0 (0x10000000)
+#define S3C64XX_PA_XM0CSN1 (0x18000000)
+#define S3C64XX_PA_XM0CSN2 (0x20000000)
+#define S3C64XX_PA_XM0CSN3 (0x28000000)
+#define S3C64XX_PA_XM0CSN4 (0x30000000)
+#define S3C64XX_PA_XM0CSN5 (0x38000000)
+
+/* HSMMC units */
+#define S3C64XX_PA_HSMMC(x)	(0x7C200000 + ((x) * 0x100000))
+#define S3C64XX_PA_HSMMC0	S3C64XX_PA_HSMMC(0)
+#define S3C64XX_PA_HSMMC1	S3C64XX_PA_HSMMC(1)
+#define S3C64XX_PA_HSMMC2	S3C64XX_PA_HSMMC(2)
+
+#define S3C_PA_UART		(0x7F005000)
+#define S3C_PA_UART0		(S3C_PA_UART + 0x00)
+#define S3C_PA_UART1		(S3C_PA_UART + 0x400)
+#define S3C_PA_UART2		(S3C_PA_UART + 0x800)
+#define S3C_PA_UART3		(S3C_PA_UART + 0xC00)
+#define S3C_UART_OFFSET		(0x400)
+
+/* See notes on UART VA mapping in debug-macro.S */
+#define S3C_VA_UARTx(x)	(S3C_VA_UART + (S3C_PA_UART & 0xfffff) + ((x) * S3C_UART_OFFSET))
+
+#define S3C_VA_UART0		S3C_VA_UARTx(0)
+#define S3C_VA_UART1		S3C_VA_UARTx(1)
+#define S3C_VA_UART2		S3C_VA_UARTx(2)
+#define S3C_VA_UART3		S3C_VA_UARTx(3)
+
+#define S3C64XX_PA_SROM		(0x70000000)
+
+#define S3C64XX_PA_NAND		(0x70200000)
+#define S3C64XX_PA_FB		(0x77100000)
+#define S3C64XX_PA_USB_HSOTG	(0x7C000000)
+#define S3C64XX_PA_WATCHDOG	(0x7E004000)
+#define S3C64XX_PA_RTC		(0x7E005000)
+#define S3C64XX_PA_ADC		(0x7E00B000)
+#define S3C64XX_PA_SYSCON	(0x7E00F000)
+#define S3C64XX_PA_AC97		(0x7F001000)
+#define S3C64XX_PA_IIS0		(0x7F002000)
+#define S3C64XX_PA_IIS1		(0x7F003000)
+#define S3C64XX_PA_TIMER	(0x7F006000)
+#define S3C64XX_PA_IIC0		(0x7F004000)
+#define S3C64XX_PA_SPI0		(0x7F00B000)
+#define S3C64XX_PA_SPI1		(0x7F00C000)
+#define S3C64XX_PA_PCM0		(0x7F009000)
+#define S3C64XX_PA_PCM1		(0x7F00A000)
+#define S3C64XX_PA_IISV4	(0x7F00D000)
+#define S3C64XX_PA_IIC1		(0x7F00F000)
+
+#define S3C64XX_PA_GPIO		(0x7F008000)
+#define S3C64XX_VA_GPIO		S3C_ADDR_CPU(0x00000000)
+#define S3C64XX_SZ_GPIO		SZ_4K
+
+#define S3C64XX_PA_SDRAM	(0x50000000)
+#define S3C64XX_PA_VIC0		(0x71200000)
+#define S3C64XX_PA_VIC1		(0x71300000)
+
+#define S3C64XX_PA_MODEM	(0x74108000)
+#define S3C64XX_VA_MODEM	S3C_ADDR_CPU(0x00100000)
+
+#define S3C64XX_PA_USBHOST	(0x74300000)
+
+#define S3C64XX_PA_USB_HSPHY	(0x7C100000)
+#define S3C64XX_VA_USB_HSPHY	S3C_ADDR_CPU(0x00200000)
+
+/* place VICs close together */
+#define VA_VIC0			(S3C_VA_IRQ + 0x00)
+#define VA_VIC1			(S3C_VA_IRQ + 0x10000)
+
+/* compatibiltiy defines. */
+#define S3C_PA_TIMER		S3C64XX_PA_TIMER
+#define S3C_PA_HSMMC0		S3C64XX_PA_HSMMC0
+#define S3C_PA_HSMMC1		S3C64XX_PA_HSMMC1
+#define S3C_PA_HSMMC2		S3C64XX_PA_HSMMC2
+#define S3C_PA_IIC		S3C64XX_PA_IIC0
+#define S3C_PA_IIC1		S3C64XX_PA_IIC1
+#define S3C_PA_NAND		S3C64XX_PA_NAND
+#define S3C_PA_FB		S3C64XX_PA_FB
+#define S3C_PA_USBHOST		S3C64XX_PA_USBHOST
+#define S3C_PA_USB_HSOTG	S3C64XX_PA_USB_HSOTG
+#define S3C_VA_USB_HSPHY	S3C64XX_VA_USB_HSPHY
+
+#endif /* __ASM_ARCH_6400_MAP_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/memory.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/memory.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/memory.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s3c6400/include/mach/memory.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET     UL(0x50000000)
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/pll.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/pll.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/pll.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/pll.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,74 @@
+/* arch/arm/plat-s3c64xx/include/plat/pll.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX PLL 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.
+*/
+
+#define S3C6400_PLL_MDIV_MASK	((1 << (25-16+1)) - 1)
+#define S3C6400_PLL_PDIV_MASK	((1 << (13-8+1)) - 1)
+#define S3C6400_PLL_SDIV_MASK	((1 << (2-0+1)) - 1)
+#define S3C6400_PLL_MDIV_SHIFT	(16)
+#define S3C6400_PLL_PDIV_SHIFT	(8)
+#define S3C6400_PLL_SDIV_SHIFT	(0)
+
+#include <asm/div64.h>
+
+static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
+					    u32 pllcon)
+{
+	u32 mdiv, pdiv, sdiv;
+	u64 fvco = baseclk;
+
+	mdiv = (pllcon >> S3C6400_PLL_MDIV_SHIFT) & S3C6400_PLL_MDIV_MASK;
+	pdiv = (pllcon >> S3C6400_PLL_PDIV_SHIFT) & S3C6400_PLL_PDIV_MASK;
+	sdiv = (pllcon >> S3C6400_PLL_SDIV_SHIFT) & S3C6400_PLL_SDIV_MASK;
+
+	fvco *= mdiv;
+	do_div(fvco, (pdiv << sdiv));
+
+	return (unsigned long)fvco;
+}
+
+#define S3C6400_EPLL_MDIV_MASK	((1 << (23-16)) - 1)
+#define S3C6400_EPLL_PDIV_MASK	((1 << (13-8)) - 1)
+#define S3C6400_EPLL_SDIV_MASK	((1 << (2-0)) - 1)
+#define S3C6400_EPLL_MDIV_SHIFT	(16)
+#define S3C6400_EPLL_PDIV_SHIFT	(8)
+#define S3C6400_EPLL_SDIV_SHIFT	(0)
+#define S3C6400_EPLL_KDIV_MASK  (0xffff)
+
+static inline unsigned long s3c6400_get_epll(unsigned long baseclk)
+{
+	unsigned long result;
+	u32 epll0 = __raw_readl(S3C_EPLL_CON0);
+	u32 epll1 = __raw_readl(S3C_EPLL_CON1);
+	u32 mdiv, pdiv, sdiv, kdiv;
+	u64 tmp;
+
+	mdiv = (epll0 >> S3C6400_EPLL_MDIV_SHIFT) & S3C6400_EPLL_MDIV_MASK;
+	pdiv = (epll0 >> S3C6400_EPLL_PDIV_SHIFT) & S3C6400_EPLL_PDIV_MASK;
+	sdiv = (epll0 >> S3C6400_EPLL_SDIV_SHIFT) & S3C6400_EPLL_SDIV_MASK;
+	kdiv = epll1 & S3C6400_EPLL_KDIV_MASK;
+
+	/* We need to multiple baseclk by mdiv (the integer part) and kdiv
+	 * which is in 2^16ths, so shift mdiv up (does not overflow) and
+	 * add kdiv before multiplying. The use of tmp is to avoid any
+	 * overflows before shifting bac down into result when multipling
+	 * by the mdiv and kdiv pair.
+	 */
+
+	tmp = baseclk;
+	tmp *= (mdiv << 16) + kdiv;
+	do_div(tmp, (pdiv << sdiv));
+	result = tmp >> 16;
+
+	return result;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/pm-core.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/pm-core.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/pm-core.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/pm-core.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,98 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/pm-core.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - 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.
+ */
+
+#include <mach/regs-gpio.h>
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+	u32 tmp = __raw_readl(S3C_PCLK_GATE);
+
+	/* As a note, since the S3C64XX UARTs generally have multiple
+	 * clock sources, we simply enable PCLK at the moment and hope
+	 * that the resume settings for the UART are suitable for the
+	 * use with PCLK.
+	 */
+
+	tmp |= S3C_CLKCON_PCLK_UART0;
+	tmp |= S3C_CLKCON_PCLK_UART1;
+	tmp |= S3C_CLKCON_PCLK_UART2;
+	tmp |= S3C_CLKCON_PCLK_UART3;
+
+	__raw_writel(tmp, S3C_PCLK_GATE);
+	udelay(10);
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+	/* VIC should have already been taken care of */
+
+	/* clear any pending EINT0 interrupts */
+	__raw_writel(__raw_readl(S3C64XX_EINT0PEND), S3C64XX_EINT0PEND);
+}
+
+static inline void s3c_pm_arch_stop_clocks(void)
+{
+}
+
+static inline void s3c_pm_arch_show_resume_irqs(void)
+{
+}
+
+/* make these defines, we currently do not have any need to change
+ * the IRQ wake controls depending on the CPU we are running on */
+
+#define s3c_irqwake_eintallow	((1 << 28) - 1)
+#define s3c_irqwake_intallow	(0)
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+					   struct pm_uart_save *save)
+{
+	u32 ucon = __raw_readl(regs + S3C2410_UCON);
+	u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK;
+	u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK;
+	u32 new_ucon;
+	u32 delta;
+
+	/* S3C64XX UART blocks only support level interrupts, so ensure that
+	 * when we restore unused UART blocks we force the level interrupt
+	 * settigs. */
+	save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL;
+
+	/* We have a constraint on changing the clock type of the UART
+	 * between UCLKx and PCLK, so ensure that when we restore UCON
+	 * that the CLK field is correctly modified if the bootloader
+	 * has changed anything.
+	 */
+	if (ucon_clk != save_clk) {
+		new_ucon = save->ucon;
+		delta = ucon_clk ^ save_clk;
+
+		/* change from UCLKx => wrong PCLK,
+		 * either UCLK can be tested for by a bit-test
+		 * with UCLK0 */
+		if (ucon_clk & S3C6400_UCON_UCLK0 &&
+		    !(save_clk & S3C6400_UCON_UCLK0) &&
+		    delta & S3C6400_UCON_PCLK2) {
+			new_ucon &= ~S3C6400_UCON_UCLK0;
+		} else if (delta == S3C6400_UCON_PCLK2) {
+			/* as an precaution, don't change from
+			 * PCLK2 => PCLK or vice-versa */
+			new_ucon ^= S3C6400_UCON_PCLK2;
+		}
+
+		S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n",
+			  ucon, new_ucon, save->ucon);
+		save->ucon = new_ucon;
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/pwm-clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/pwm-clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/pwm-clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,56 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/pwm-clock.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C64xx - pwm clock and timer support
+ */
+
+/**
+ * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
+ * @tcfg: The timer TCFG1 register bits shifted down to 0.
+ *
+ * Return true if the given configuration from TCFG1 is a TCLK instead
+ * any of the TDIV clocks.
+ */
+static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
+{
+	return tcfg >= S3C64XX_TCFG1_MUX_TCLK;
+}
+
+/**
+ * tcfg_to_divisor() - convert tcfg1 setting to a divisor
+ * @tcfg1: The tcfg1 setting, shifted down.
+ *
+ * Get the divisor value for the given tcfg1 setting. We assume the
+ * caller has already checked to see if this is not a TCLK source.
+ */
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+	return 1 << tcfg1;
+}
+
+/**
+ * pwm_tdiv_has_div1() - does the tdiv setting have a /1
+ *
+ * Return true if we have a /1 in the tdiv setting.
+ */
+static inline unsigned int pwm_tdiv_has_div1(void)
+{
+	return 1;
+}
+
+/**
+ * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
+ * @div: The divisor to calculate the bit information for.
+ *
+ * Turn a divisor into the necessary bit field for TCFG1.
+ */
+static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
+{
+	return ilog2(div);
+}
+
+#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,156 @@
+/* arch/arm/plat-s3c64xx/include/plat/regs-clock.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_REGS_CLOCK_H
+#define __PLAT_REGS_CLOCK_H __FILE__
+
+#define S3C_CLKREG(x)		(S3C_VA_SYS + (x))
+
+#define S3C_APLL_LOCK		S3C_CLKREG(0x00)
+#define S3C_MPLL_LOCK		S3C_CLKREG(0x04)
+#define S3C_EPLL_LOCK		S3C_CLKREG(0x08)
+#define S3C_APLL_CON		S3C_CLKREG(0x0C)
+#define S3C_MPLL_CON		S3C_CLKREG(0x10)
+#define S3C_EPLL_CON0		S3C_CLKREG(0x14)
+#define S3C_EPLL_CON1		S3C_CLKREG(0x18)
+#define S3C_CLK_SRC		S3C_CLKREG(0x1C)
+#define S3C_CLK_DIV0		S3C_CLKREG(0x20)
+#define S3C_CLK_DIV1		S3C_CLKREG(0x24)
+#define S3C_CLK_DIV2		S3C_CLKREG(0x28)
+#define S3C_CLK_OUT		S3C_CLKREG(0x2C)
+#define S3C_HCLK_GATE		S3C_CLKREG(0x30)
+#define S3C_PCLK_GATE		S3C_CLKREG(0x34)
+#define S3C_SCLK_GATE		S3C_CLKREG(0x38)
+#define S3C_MEM0_GATE		S3C_CLKREG(0x3C)
+
+/* CLKDIV0 */
+#define S3C6400_CLKDIV0_PCLK_MASK	(0xf << 12)
+#define S3C6400_CLKDIV0_PCLK_SHIFT	(12)
+#define S3C6400_CLKDIV0_HCLK2_MASK	(0x7 << 9)
+#define S3C6400_CLKDIV0_HCLK2_SHIFT	(9)
+#define S3C6400_CLKDIV0_HCLK_MASK	(0x1 << 8)
+#define S3C6400_CLKDIV0_HCLK_SHIFT	(8)
+#define S3C6400_CLKDIV0_MPLL_MASK	(0x1 << 4)
+#define S3C6400_CLKDIV0_MPLL_SHIFT	(4)
+
+#define S3C6400_CLKDIV0_ARM_MASK	(0x7 << 0)
+#define S3C6410_CLKDIV0_ARM_MASK	(0xf << 0)
+#define S3C6400_CLKDIV0_ARM_SHIFT	(0)
+
+/* HCLK GATE Registers */
+#define S3C_CLKCON_HCLK_3DSE	(1<<31)
+#define S3C_CLKCON_HCLK_UHOST	(1<<29)
+#define S3C_CLKCON_HCLK_SECUR	(1<<28)
+#define S3C_CLKCON_HCLK_SDMA1	(1<<27)
+#define S3C_CLKCON_HCLK_SDMA0	(1<<26)
+#define S3C_CLKCON_HCLK_IROM	(1<<25)
+#define S3C_CLKCON_HCLK_DDR1	(1<<24)
+#define S3C_CLKCON_HCLK_DDR0	(1<<23)
+#define S3C_CLKCON_HCLK_MEM1	(1<<22)
+#define S3C_CLKCON_HCLK_MEM0	(1<<21)
+#define S3C_CLKCON_HCLK_USB	(1<<20)
+#define S3C_CLKCON_HCLK_HSMMC2	(1<<19)
+#define S3C_CLKCON_HCLK_HSMMC1	(1<<18)
+#define S3C_CLKCON_HCLK_HSMMC0	(1<<17)
+#define S3C_CLKCON_HCLK_MDP	(1<<16)
+#define S3C_CLKCON_HCLK_DHOST	(1<<15)
+#define S3C_CLKCON_HCLK_IHOST	(1<<14)
+#define S3C_CLKCON_HCLK_DMA1	(1<<13)
+#define S3C_CLKCON_HCLK_DMA0	(1<<12)
+#define S3C_CLKCON_HCLK_JPEG	(1<<11)
+#define S3C_CLKCON_HCLK_CAMIF	(1<<10)
+#define S3C_CLKCON_HCLK_SCALER	(1<<9)
+#define S3C_CLKCON_HCLK_2D	(1<<8)
+#define S3C_CLKCON_HCLK_TV	(1<<7)
+#define S3C_CLKCON_HCLK_POST0	(1<<5)
+#define S3C_CLKCON_HCLK_ROT	(1<<4)
+#define S3C_CLKCON_HCLK_LCD	(1<<3)
+#define S3C_CLKCON_HCLK_TZIC	(1<<2)
+#define S3C_CLKCON_HCLK_INTC	(1<<1)
+#define S3C_CLKCON_HCLK_MFC	(1<<0)
+
+/* PCLK GATE Registers */
+#define S3C6410_CLKCON_PCLK_I2C1	(1<<27)
+#define S3C6410_CLKCON_PCLK_IIS2	(1<<26)
+#define S3C_CLKCON_PCLK_SKEY		(1<<24)
+#define S3C_CLKCON_PCLK_CHIPID		(1<<23)
+#define S3C_CLKCON_PCLK_SPI1		(1<<22)
+#define S3C_CLKCON_PCLK_SPI0		(1<<21)
+#define S3C_CLKCON_PCLK_HSIRX		(1<<20)
+#define S3C_CLKCON_PCLK_HSITX		(1<<19)
+#define S3C_CLKCON_PCLK_GPIO		(1<<18)
+#define S3C_CLKCON_PCLK_IIC		(1<<17)
+#define S3C_CLKCON_PCLK_IIS1		(1<<16)
+#define S3C_CLKCON_PCLK_IIS0		(1<<15)
+#define S3C_CLKCON_PCLK_AC97		(1<<14)
+#define S3C_CLKCON_PCLK_TZPC		(1<<13)
+#define S3C_CLKCON_PCLK_TSADC		(1<<12)
+#define S3C_CLKCON_PCLK_KEYPAD		(1<<11)
+#define S3C_CLKCON_PCLK_IRDA		(1<<10)
+#define S3C_CLKCON_PCLK_PCM1		(1<<9)
+#define S3C_CLKCON_PCLK_PCM0		(1<<8)
+#define S3C_CLKCON_PCLK_PWM		(1<<7)
+#define S3C_CLKCON_PCLK_RTC		(1<<6)
+#define S3C_CLKCON_PCLK_WDT		(1<<5)
+#define S3C_CLKCON_PCLK_UART3		(1<<4)
+#define S3C_CLKCON_PCLK_UART2		(1<<3)
+#define S3C_CLKCON_PCLK_UART1		(1<<2)
+#define S3C_CLKCON_PCLK_UART0		(1<<1)
+#define S3C_CLKCON_PCLK_MFC		(1<<0)
+
+/* SCLK GATE Registers */
+#define S3C_CLKCON_SCLK_UHOST		(1<<30)
+#define S3C_CLKCON_SCLK_MMC2_48		(1<<29)
+#define S3C_CLKCON_SCLK_MMC1_48		(1<<28)
+#define S3C_CLKCON_SCLK_MMC0_48		(1<<27)
+#define S3C_CLKCON_SCLK_MMC2		(1<<26)
+#define S3C_CLKCON_SCLK_MMC1		(1<<25)
+#define S3C_CLKCON_SCLK_MMC0		(1<<24)
+#define S3C_CLKCON_SCLK_SPI1_48 	(1<<23)
+#define S3C_CLKCON_SCLK_SPI0_48 	(1<<22)
+#define S3C_CLKCON_SCLK_SPI1		(1<<21)
+#define S3C_CLKCON_SCLK_SPI0		(1<<20)
+#define S3C_CLKCON_SCLK_DAC27		(1<<19)
+#define S3C_CLKCON_SCLK_TV27		(1<<18)
+#define S3C_CLKCON_SCLK_SCALER27	(1<<17)
+#define S3C_CLKCON_SCLK_SCALER		(1<<16)
+#define S3C_CLKCON_SCLK_LCD27		(1<<15)
+#define S3C_CLKCON_SCLK_LCD		(1<<14)
+#define S3C6400_CLKCON_SCLK_POST1_27	(1<<13)
+#define S3C6410_CLKCON_FIMC		(1<<13)
+#define S3C_CLKCON_SCLK_POST0_27	(1<<12)
+#define S3C6400_CLKCON_SCLK_POST1	(1<<11)
+#define S3C6410_CLKCON_SCLK_AUDIO2	(1<<11)
+#define S3C_CLKCON_SCLK_POST0		(1<<10)
+#define S3C_CLKCON_SCLK_AUDIO1		(1<<9)
+#define S3C_CLKCON_SCLK_AUDIO0		(1<<8)
+#define S3C_CLKCON_SCLK_SECUR		(1<<7)
+#define S3C_CLKCON_SCLK_IRDA		(1<<6)
+#define S3C_CLKCON_SCLK_UART		(1<<5)
+#define S3C_CLKCON_SCLK_ONENAND 	(1<<4)
+#define S3C_CLKCON_SCLK_MFC		(1<<3)
+#define S3C_CLKCON_SCLK_CAM		(1<<2)
+#define S3C_CLKCON_SCLK_JPEG		(1<<1)
+
+/* CLKSRC */
+
+#define S3C6400_CLKSRC_APLL_MOUT	(1 << 0)
+#define S3C6400_CLKSRC_MPLL_MOUT	(1 << 1)
+#define S3C6400_CLKSRC_EPLL_MOUT	(1 << 2)
+#define S3C6400_CLKSRC_APLL_MOUT_SHIFT	(0)
+#define S3C6400_CLKSRC_MPLL_MOUT_SHIFT	(1)
+#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT	(2)
+#define S3C6400_CLKSRC_MFC		(1 << 4)
+
+#endif /* _PLAT_REGS_CLOCK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-fb.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-fb.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-fb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-fb.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Copyright 2009 Samsung Electronics Co.
+ *
+ * Pawel Osciak <p.osciak@samsung.com>
+ * Based on plat-s3c/include/plat/regs-fb.h by Ben Dooks <ben@simtec.co.uk>
+ *
+ * Framebuffer register definitions for Samsung S3C64xx.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MACH_REGS_FB_H
+#define __ASM_ARCH_MACH_REGS_FB_H __FILE__
+
+#include <plat/regs-fb-v4.h>
+
+/* Palette registers */
+#define WIN2_PAL(_entry)			(0x300 + ((_entry) * 2))
+#define WIN3_PAL(_entry)			(0x320 + ((_entry) * 2))
+#define WIN4_PAL(_entry)			(0x340 + ((_entry) * 2))
+#define WIN0_PAL(_entry)			(0x400 + ((_entry) * 4))
+#define WIN1_PAL(_entry)			(0x800 + ((_entry) * 4))
+
+static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg)
+{
+	switch (window) {
+	case 0: return WIN0_PAL(reg);
+	case 1: return WIN1_PAL(reg);
+	case 2: return WIN2_PAL(reg);
+	case 3: return WIN3_PAL(reg);
+	case 4: return WIN4_PAL(reg);
+	}
+
+	BUG();
+}
+
+#endif /* __ASM_ARCH_MACH_REGS_FB_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,187 @@
+/* linux/arch/arm/plat-s3c64xx/include/mach/regs-gpio.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - GPIO register definitions
+ */
+
+#ifndef __ASM_PLAT_S3C64XX_REGS_GPIO_H
+#define __ASM_PLAT_S3C64XX_REGS_GPIO_H __FILE__
+
+/* Base addresses for each of the banks */
+
+#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.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-gpio-memport.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-gpio-memport.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-gpio-memport.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-gpio-memport.h	2010-05-16 17:17:36.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.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-irq.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-irq.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,20 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/regs-irq.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - IRQ register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_IRQ_H
+#define __ASM_ARCH_REGS_IRQ_H __FILE__
+
+#include <asm/hardware/vic.h>
+
+#endif /* __ASM_ARCH_6400_REGS_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-modem.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-modem.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-modem.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-modem.h	2010-05-16 17:17:36.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.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-srom.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-srom.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-srom.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-srom.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,59 @@
+/* arch/arm/plat-s3c64xx/include/plat/regs-srom.h
+ *
+ * Copyright 2009 Andy Green <andy@warmcat.com>
+ *
+ * S3C64XX SROM 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 __PLAT_REGS_SROM_H
+#define __PLAT_REGS_SROM_H __FILE__
+
+#define S3C64XX_SROMREG(x)	(S3C_VA_MEM + (x))
+
+#define S3C64XX_SROM_BW		S3C64XX_SROMREG(0)
+#define S3C64XX_SROM_BC0	S3C64XX_SROMREG(4)
+#define S3C64XX_SROM_BC1	S3C64XX_SROMREG(8)
+#define S3C64XX_SROM_BC2	S3C64XX_SROMREG(0xc)
+#define S3C64XX_SROM_BC3	S3C64XX_SROMREG(0x10)
+#define S3C64XX_SROM_BC4	S3C64XX_SROMREG(0x14)
+#define S3C64XX_SROM_BC5	S3C64XX_SROMREG(0x18)
+
+/*
+ * one register BW holds 5 x 4-bit packed settings for NCS0 - NCS4
+ */
+
+#define S3C64XX_SROM_BW__DATAWIDTH__SHIFT	0
+#define S3C64XX_SROM_BW__WAITENABLE__SHIFT	2
+#define S3C64XX_SROM_BW__BYTEENABLE__SHIFT	3
+#define S3C64XX_SROM_BW__CS_MASK 0xf
+
+#define S3C64XX_SROM_BW__NCS0__SHIFT	0
+#define S3C64XX_SROM_BW__NCS1__SHIFT	4
+#define S3C64XX_SROM_BW__NCS2__SHIFT	8
+#define S3C64XX_SROM_BW__NCS3__SHIFT	0xc
+#define S3C64XX_SROM_BW__NCS4__SHIFT	0x10
+
+/*
+ * applies to same to BCS0 - BCS4
+ */
+
+#define S3C64XX_SROM_BCX__PMC__SHIFT	0
+#define S3C64XX_SROM_BCX__PMC__MASK	3
+#define S3C64XX_SROM_BCX__TACP__SHIFT	4
+#define S3C64XX_SROM_BCX__TACP__MASK	0xf
+#define S3C64XX_SROM_BCX__TCAH__SHIFT	8
+#define S3C64XX_SROM_BCX__TCAH__MASK	0xf
+#define S3C64XX_SROM_BCX__TCOH__SHIFT	12
+#define S3C64XX_SROM_BCX__TCOH__MASK	0xf
+#define S3C64XX_SROM_BCX__TACC__SHIFT	16
+#define S3C64XX_SROM_BCX__TACC__MASK	0x1f
+#define S3C64XX_SROM_BCX__TCOS__SHIFT	24
+#define S3C64XX_SROM_BCX__TCOS__MASK	0xf
+#define S3C64XX_SROM_BCX__TACS__SHIFT	28
+#define S3C64XX_SROM_BCX__TACS__MASK	0xf
+
+#endif /* _PLAT_REGS_SROM_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-syscon-power.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-syscon-power.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-syscon-power.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-syscon-power.h	2010-05-16 17:17:36.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.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-sys.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-sys.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-sys.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/regs-sys.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,28 @@
+/* arch/arm/plat-s3c64xx/include/plat/regs-sys.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX system register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_REGS_SYS_H
+#define __PLAT_REGS_SYS_H __FILE__
+
+#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)
+
+#endif /* _PLAT_REGS_SYS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/s3c6400.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/s3c6400.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/s3c6400.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/s3c6400.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,36 @@
+/* arch/arm/mach-s3c64xx/include/macht/s3c6400.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * Header file for s3c6400 cpu 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.
+*/
+
+/* Common init code for S3C6400 related SoCs */
+
+extern void s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s3c6400_setup_clocks(void);
+
+extern void s3c64xx_register_clocks(unsigned long xtal, unsigned armclk_limit);
+
+#ifdef CONFIG_CPU_S3C6400
+
+extern  int s3c6400_init(void);
+extern void s3c6400_init_irq(void);
+extern void s3c6400_map_io(void);
+extern void s3c6400_init_clocks(int xtal);
+
+#define s3c6400_init_uarts s3c6400_common_init_uarts
+
+#else
+#define s3c6400_init_clocks NULL
+#define s3c6400_init_uarts NULL
+#define s3c6400_map_io NULL
+#define s3c6400_init NULL
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/s3c6410.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/s3c6410.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/s3c6410.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/s3c6410.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,29 @@
+/* arch/arm/mach-s3c64xx/include/mach/s3c6410.h
+ *
+ * Copyright 2008 Openmoko,  Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * Header file for s3c6410 cpu 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.
+*/
+
+#ifdef CONFIG_CPU_S3C6410
+
+extern  int s3c6410_init(void);
+extern void s3c6410_init_irq(void);
+extern void s3c6410_map_io(void);
+extern void s3c6410_init_clocks(int xtal);
+
+#define s3c6410_init_uarts s3c6400_common_init_uarts
+
+#else
+#define s3c6410_init_clocks NULL
+#define s3c6410_init_uarts NULL
+#define s3c6410_map_io NULL
+#define s3c6410_init NULL
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,18 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h
+ *
+ * Copyright (C) 2009 Samsung Electronics Ltd.
+ *	Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __S3C64XX_PLAT_SPI_CLKS_H
+#define __S3C64XX_PLAT_SPI_CLKS_H __FILE__
+
+#define S3C64XX_SPI_SRCCLK_PCLK		0
+#define S3C64XX_SPI_SRCCLK_SPIBUS	1
+#define S3C64XX_SPI_SRCCLK_48M		2
+
+#endif /* __S3C64XX_PLAT_SPI_CLKS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/system.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/system.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,30 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/system.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C6400 - system implementation
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H __FILE__
+
+#include <plat/watchdog-reset.h>
+
+static void arch_idle(void)
+{
+	/* nothing here yet */
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+	if (mode != 's')
+		arch_wdt_reset();
+
+	/* if all else fails, or mode was for soft, jump to 0 */
+	cpu_reset(0);
+}
+
+#endif /* __ASM_ARCH_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/tick.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/tick.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/tick.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/tick.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,29 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/tick.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - Timer tick support definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TICK_H
+#define __ASM_ARCH_TICK_H __FILE__
+
+/* note, the timer interrutps turn up in 2 places, the vic and then
+ * the timer block. We take the VIC as the base at the moment.
+ */
+static inline u32 s3c24xx_ostimer_pending(void)
+{
+	u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
+	return pend & 1 << (IRQ_TIMER4_VIC - S3C64XX_IRQ_VIC0(0));
+}
+
+#define TICK_MAX	(0xffffffff)
+
+#endif /* __ASM_ARCH_6400_TICK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/timex.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/timex.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/timex.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c64xx/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C6400 - time parameters
+ *
+ * This program is free software; you can 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_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/uncompress.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/uncompress.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/uncompress.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,28 @@
+/* arch/arm/mach-s3c6400/include/mach/uncompress.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C6400 - uncompress 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.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/map.h>
+#include <plat/uncompress.h>
+
+static void arch_detect_cpu(void)
+{
+	/* we do not need to do any cpu detection here at the moment. */
+	fifo_mask = S3C2440_UFSTAT_TXMASK;
+	fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,20 @@
+/* arch/arm/mach-s3c64xx/include/mach/vmalloc.h
+ *
+ * from arch/arm/mach-iop3xx/include/mach/vmalloc.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.
+ *
+ * S3C6400 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END	  (0xE0000000)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/irq.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/irq.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,69 @@
+/* arch/arm/plat-s3c64xx/irq.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Interrupt handling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/serial_core.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/hardware/vic.h>
+
+#include <mach/map.h>
+#include <plat/irq-vic-timer.h>
+#include <plat/irq-uart.h>
+#include <plat/cpu.h>
+
+static struct s3c_uart_irq uart_irqs[] = {
+	[0] = {
+		.regs		= S3C_VA_UART0,
+		.base_irq	= IRQ_S3CUART_BASE0,
+		.parent_irq	= IRQ_UART0,
+	},
+	[1] = {
+		.regs		= S3C_VA_UART1,
+		.base_irq	= IRQ_S3CUART_BASE1,
+		.parent_irq	= IRQ_UART1,
+	},
+	[2] = {
+		.regs		= S3C_VA_UART2,
+		.base_irq	= IRQ_S3CUART_BASE2,
+		.parent_irq	= IRQ_UART2,
+	},
+	[3] = {
+		.regs		= S3C_VA_UART3,
+		.base_irq	= IRQ_S3CUART_BASE3,
+		.parent_irq	= IRQ_UART3,
+	},
+};
+
+
+void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
+{
+	printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
+
+	/* initialise the pair of VICs */
+	vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, 0);
+	vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, 0);
+
+	/* add the timer sub-irqs */
+
+	s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0);
+	s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1);
+	s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2);
+	s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3);
+	s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4);
+
+	s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/irq-eint.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/irq-eint.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/irq-eint.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/irq-eint.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,213 @@
+/* arch/arm/plat-s3c64xx/irq-eint.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Interrupt handling for IRQ_EINT(x)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/hardware/vic.h>
+
+#include <plat/regs-irqtype.h>
+#include <mach/regs-gpio.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/map.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#define eint_offset(irq)	((irq) - IRQ_EINT(0))
+#define eint_irq_to_bit(irq)	(1 << eint_offset(irq))
+
+static inline void s3c_irq_eint_mask(unsigned int irq)
+{
+	u32 mask;
+
+	mask = __raw_readl(S3C64XX_EINT0MASK);
+	mask |= eint_irq_to_bit(irq);
+	__raw_writel(mask, S3C64XX_EINT0MASK);
+}
+
+static void s3c_irq_eint_unmask(unsigned int irq)
+{
+	u32 mask;
+
+	mask = __raw_readl(S3C64XX_EINT0MASK);
+	mask &= ~eint_irq_to_bit(irq);
+	__raw_writel(mask, S3C64XX_EINT0MASK);
+}
+
+static inline void s3c_irq_eint_ack(unsigned int irq)
+{
+	__raw_writel(eint_irq_to_bit(irq), S3C64XX_EINT0PEND);
+}
+
+static void s3c_irq_eint_maskack(unsigned int irq)
+{
+	/* compiler should in-line these */
+	s3c_irq_eint_mask(irq);
+	s3c_irq_eint_ack(irq);
+}
+
+static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
+{
+	int offs = eint_offset(irq);
+	int pin, pin_val;
+	int shift;
+	u32 ctrl, mask;
+	u32 newvalue = 0;
+	void __iomem *reg;
+
+	if (offs > 27)
+		return -EINVAL;
+
+	if (offs <= 15)
+		reg = S3C64XX_EINT0CON0;
+	else
+		reg = S3C64XX_EINT0CON1;
+
+	switch (type) {
+	case IRQ_TYPE_NONE:
+		printk(KERN_WARNING "No edge setting!\n");
+		break;
+
+	case IRQ_TYPE_EDGE_RISING:
+		newvalue = S3C2410_EXTINT_RISEEDGE;
+		break;
+
+	case IRQ_TYPE_EDGE_FALLING:
+		newvalue = S3C2410_EXTINT_FALLEDGE;
+		break;
+
+	case IRQ_TYPE_EDGE_BOTH:
+		newvalue = S3C2410_EXTINT_BOTHEDGE;
+		break;
+
+	case IRQ_TYPE_LEVEL_LOW:
+		newvalue = S3C2410_EXTINT_LOWLEV;
+		break;
+
+	case IRQ_TYPE_LEVEL_HIGH:
+		newvalue = S3C2410_EXTINT_HILEV;
+		break;
+
+	default:
+		printk(KERN_ERR "No such irq type %d", type);
+		return -1;
+	}
+
+	if (offs <= 15)
+		shift = (offs / 2) * 4;
+	else
+		shift = ((offs - 16) / 2) * 4;
+	mask = 0x7 << shift;
+
+	ctrl = __raw_readl(reg);
+	ctrl &= ~mask;
+	ctrl |= newvalue << shift;
+	__raw_writel(ctrl, reg);
+
+	/* set the GPIO pin appropriately */
+
+	if (offs < 16) {
+		pin = S3C64XX_GPN(offs);
+		pin_val = S3C_GPIO_SFN(2);
+	} else if (offs < 23) {
+		pin = S3C64XX_GPL(offs + 8 - 16);
+		pin_val = S3C_GPIO_SFN(3);
+	} else {
+		pin = S3C64XX_GPM(offs - 23);
+		pin_val = S3C_GPIO_SFN(3);
+	}
+
+	s3c_gpio_cfgpin(pin, pin_val);
+
+	return 0;
+}
+
+static struct irq_chip s3c_irq_eint = {
+	.name		= "s3c-eint",
+	.mask		= s3c_irq_eint_mask,
+	.unmask		= s3c_irq_eint_unmask,
+	.mask_ack	= s3c_irq_eint_maskack,
+	.ack		= s3c_irq_eint_ack,
+	.set_type	= s3c_irq_eint_set_type,
+	.set_wake	= s3c_irqext_wake,
+};
+
+/* s3c_irq_demux_eint
+ *
+ * This function demuxes the IRQ from the group0 external interrupts,
+ * from IRQ_EINT(0) to IRQ_EINT(27). It is designed to be inlined into
+ * the specific handlers s3c_irq_demux_eintX_Y.
+ */
+static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end)
+{
+	u32 status = __raw_readl(S3C64XX_EINT0PEND);
+	u32 mask = __raw_readl(S3C64XX_EINT0MASK);
+	unsigned int irq;
+
+	status &= ~mask;
+	status >>= start;
+	status &= (1 << (end - start + 1)) - 1;
+
+	for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
+		if (status & 1)
+			generic_handle_irq(irq);
+
+		status >>= 1;
+	}
+}
+
+static void s3c_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
+{
+	s3c_irq_demux_eint(0, 3);
+}
+
+static void s3c_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
+{
+	s3c_irq_demux_eint(4, 11);
+}
+
+static void s3c_irq_demux_eint12_19(unsigned int irq, struct irq_desc *desc)
+{
+	s3c_irq_demux_eint(12, 19);
+}
+
+static void s3c_irq_demux_eint20_27(unsigned int irq, struct irq_desc *desc)
+{
+	s3c_irq_demux_eint(20, 27);
+}
+
+static int __init s3c64xx_init_irq_eint(void)
+{
+	int irq;
+
+	for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
+		set_irq_chip(irq, &s3c_irq_eint);
+		set_irq_handler(irq, handle_level_irq);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	set_irq_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3);
+	set_irq_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11);
+	set_irq_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19);
+	set_irq_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27);
+
+	return 0;
+}
+
+arch_initcall(s3c64xx_init_irq_eint);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/irq-pm.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/irq-pm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/irq-pm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/irq-pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,111 @@
+/* arch/arm/plat-s3c64xx/irq-pm.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Interrupt handling Power Management
+ *
+ * This program is free software; you can 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/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/serial_core.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+
+#include <plat/regs-serial.h>
+#include <plat/regs-timer.h>
+#include <mach/regs-gpio.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+/* We handled all the IRQ types in this code, to save having to make several
+ * small files to handle each different type separately. Having the EINT_GRP
+ * code here shouldn't be as much bloat as the IRQ table space needed when
+ * they are enabled. The added benefit is we ensure that these registers are
+ * in the same state as we suspended.
+ */
+
+static struct sleep_save irq_save[] = {
+	SAVE_ITEM(S3C64XX_PRIORITY),
+	SAVE_ITEM(S3C64XX_EINT0CON0),
+	SAVE_ITEM(S3C64XX_EINT0CON1),
+	SAVE_ITEM(S3C64XX_EINT0FLTCON0),
+	SAVE_ITEM(S3C64XX_EINT0FLTCON1),
+	SAVE_ITEM(S3C64XX_EINT0FLTCON2),
+	SAVE_ITEM(S3C64XX_EINT0FLTCON3),
+	SAVE_ITEM(S3C64XX_EINT0MASK),
+	SAVE_ITEM(S3C64XX_TINT_CSTAT),
+};
+
+static struct irq_grp_save {
+	u32	fltcon;
+	u32	con;
+	u32	mask;
+} eint_grp_save[5];
+
+static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS];
+
+static int s3c64xx_irq_pm_suspend(struct sys_device *dev, pm_message_t state)
+{
+	struct irq_grp_save *grp = eint_grp_save;
+	int i;
+
+	S3C_PMDBG("%s: suspending IRQs\n", __func__);
+
+	s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+
+	for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
+		irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM);
+
+	for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
+		grp->con = __raw_readl(S3C64XX_EINT12CON + (i * 4));
+		grp->mask = __raw_readl(S3C64XX_EINT12MASK + (i * 4));
+		grp->fltcon = __raw_readl(S3C64XX_EINT12FLTCON + (i * 4));
+	}
+
+	return 0;
+}
+
+static int s3c64xx_irq_pm_resume(struct sys_device *dev)
+{
+	struct irq_grp_save *grp = eint_grp_save;
+	int i;
+
+	S3C_PMDBG("%s: resuming IRQs\n", __func__);
+
+	s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+
+	for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
+		__raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM);
+
+	for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
+		__raw_writel(grp->con, S3C64XX_EINT12CON + (i * 4));
+		__raw_writel(grp->mask, S3C64XX_EINT12MASK + (i * 4));
+		__raw_writel(grp->fltcon, S3C64XX_EINT12FLTCON + (i * 4));
+	}
+
+	S3C_PMDBG("%s: IRQ configuration restored\n", __func__);
+	return 0;
+}
+
+static struct sysdev_driver s3c64xx_irq_driver = {
+	.suspend = s3c64xx_irq_pm_suspend,
+	.resume	 = s3c64xx_irq_pm_resume,
+};
+
+static int __init s3c64xx_irq_pm_init(void)
+{
+	return sysdev_driver_register(&s3c64xx_sysclass, &s3c64xx_irq_driver);
+}
+
+arch_initcall(s3c64xx_irq_pm_init);
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,180 @@
+# Copyright 2008 Openmoko, Inc.
+#	Simtec Electronics, Ben Dooks <ben@simtec.co.uk>
+#
+# Licensed under GPLv2
+
+# temporary until we can eliminate all drivers using it.
+config PLAT_S3C64XX
+	bool
+	depends on ARCH_S3C64XX
+	default y
+	help
+	  Base platform code for any Samsung S3C64XX device
+
+
+# Configuration options for the S3C6410 CPU
+
+config CPU_S3C6400
+	bool
+	help
+	  Enable S3C6400 CPU support
+
+config CPU_S3C6410
+	bool
+	help
+	  Enable S3C6410 CPU support
+
+config S3C64XX_DMA
+	bool "S3C64XX DMA"
+	select S3C_DMA
+
+config S3C64XX_SETUP_SDHCI
+	select S3C64XX_SETUP_SDHCI_GPIO
+	bool
+	help
+	  Internal configuration for default SDHCI setup for S3C6400 and
+	  S3C6410 SoCs.
+
+# platform specific device setup
+
+config S3C64XX_SETUP_I2C0
+	bool
+	default y
+	help
+	  Common setup code for i2c bus 0.
+
+	  Note, currently since i2c0 is always compiled, this setup helper
+	  is always compiled with it.
+
+config S3C64XX_SETUP_I2C1
+	bool
+	help
+	  Common setup code for i2c bus 1.
+
+config S3C64XX_SETUP_FB_24BPP
+	bool
+	help
+	  Common setup code for S3C64XX with an 24bpp RGB display helper.
+
+config S3C64XX_SETUP_SDHCI_GPIO
+	bool
+	help
+	  Common setup code for S3C64XX SDHCI GPIO configurations
+
+# S36400 Macchine support
+
+config MACH_SMDK6400
+       bool "SMDK6400"
+	select CPU_S3C6400
+	select S3C_DEV_HSMMC
+	select S3C_DEV_NAND
+	select S3C64XX_SETUP_SDHCI
+	help
+	  Machine support for the Samsung SMDK6400
+
+# S3C6410 machine support
+
+config MACH_ANW6410
+	bool "A&W6410"
+	select CPU_S3C6410
+	select S3C_DEV_FB
+	select S3C64XX_SETUP_FB_24BPP
+	help
+	  Machine support for the A&W6410
+
+config MACH_SMDK6410
+	bool "SMDK6410"
+	select CPU_S3C6410
+	select S3C_DEV_HSMMC
+	select S3C_DEV_HSMMC1
+	select S3C_DEV_I2C1
+	select S3C_DEV_FB
+	select S3C_DEV_USB_HOST
+	select S3C_DEV_USB_HSOTG
+	select S3C64XX_SETUP_SDHCI
+	select S3C64XX_SETUP_I2C1
+	select S3C64XX_SETUP_FB_24BPP
+	help
+	  Machine support for the Samsung SMDK6410
+
+# At least some of the SMDK6410s were shipped with the card detect
+# for the MMC/SD slots connected to the same input. This means that
+# either the boards need to be altered to have channel0 to an alternate
+# configuration or that only one slot can be used.
+
+choice
+	prompt "SMDK6410 MMC/SD slot setup"
+	depends on MACH_SMDK6410
+
+config SMDK6410_SD_CH0
+	bool "Use channel 0 only"
+	depends on MACH_SMDK6410
+	help
+          Select CON7 (channel 0) as the MMC/SD slot, as
+	  at least some SMDK6410 boards come with the
+	  resistors fitted so that the card detects for
+	  channels 0 and 1 are the same.
+
+config SMDK6410_SD_CH1
+	bool "Use channel 1 only"
+	depends on MACH_SMDK6410
+	help
+          Select CON6 (channel 1) as the MMC/SD slot, as
+	  at least some SMDK6410 boards come with the
+	  resistors fitted so that the card detects for
+	  channels 0 and 1 are the same.
+
+endchoice
+
+config SMDK6410_WM1190_EV1
+	bool "Support Wolfson Microelectronics 1190-EV1 PMIC card"
+	depends on MACH_SMDK6410
+	select REGULATOR
+	select REGULATOR_WM8350
+	select S3C24XX_GPIO_EXTRA64
+	select MFD_WM8350_I2C
+	select MFD_WM8350_CONFIG_MODE_0
+	select MFD_WM8350_CONFIG_MODE_3
+	select MFD_WM8352_CONFIG_MODE_0
+	help
+	  The Wolfson Microelectronics 1190-EV1 is a WM835x based PMIC
+	  and audio daughtercard for the Samsung SMDK6410 reference
+	  platform.  Enabling this option will build support for this
+	  module into the kernel.  The presence of the module will be
+	  detected at runtime so the the resulting kernel can be used
+	  with or without the 1190-EV1 fitted.
+
+config SMDK6410_WM1192_EV1
+	bool "Support Wolfson Microelectronics 1192-EV1 PMIC card"
+	depends on MACH_SMDK6410
+	select REGULATOR
+	select REGULATOR_WM831X
+	select S3C24XX_GPIO_EXTRA64
+	select MFD_WM831X
+	help
+	  The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC
+	  daughtercard for the Samsung SMDK6410 reference platform.
+	  Enabling this option will build support for this module into
+	  the kernel.  The presence of the daughtercard will be
+	  detected at runtime so the the resulting kernel can be used
+	  with or without the 1192-EV1 fitted.
+
+config MACH_NCP
+	bool "NCP"
+	select CPU_S3C6410
+	select S3C_DEV_I2C1
+	select S3C_DEV_HSMMC1
+	select S3C64XX_SETUP_I2C1
+	help
+          Machine support for the Samsung NCP
+
+config MACH_HMT
+	bool "Airgoo HMT"
+	select CPU_S3C6410
+	select S3C_DEV_FB
+	select S3C_DEV_NAND
+	select S3C_DEV_USB_HOST
+	select S3C64XX_SETUP_FB_24BPP
+	select HAVE_PWM
+	help
+	  Machine support for the Airgoo HMT
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/mach-anw6410.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/mach-anw6410.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/mach-anw6410.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/mach-anw6410.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,245 @@
+/* linux/arch/arm/mach-s3c64xx/mach-anw6410.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ * Copyright 2009 Kwangwoo Lee
+ * 	Kwangwoo Lee <kwangwoo.lee@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/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/dm9000.h>
+
+#include <video/platform_lcd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+#include <plat/fb.h>
+
+#include <mach/s3c6410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-modem.h>
+
+/* DM9000 */
+#define ANW6410_PA_DM9000	(0x18000000)
+
+/* A hardware buffer to control external devices is mapped at 0x30000000.
+ * It can not be read. So current status must be kept in anw6410_extdev_status.
+ */
+#define ANW6410_VA_EXTDEV	S3C_ADDR(0x02000000)
+#define ANW6410_PA_EXTDEV	(0x30000000)
+
+#define ANW6410_EN_DM9000	(1<<11)
+#define ANW6410_EN_LCD		(1<<14)
+
+static __u32 anw6410_extdev_status;
+
+static struct s3c2410_uartcfg anw6410_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+	[1] = {
+		.hwport	     = 1,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+};
+
+/* framebuffer and LCD setup. */
+static void __init anw6410_lcd_mode_set(void)
+{
+	u32 tmp;
+
+	/* set the LCD type */
+	tmp = __raw_readl(S3C64XX_SPCON);
+	tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+	tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+	__raw_writel(tmp, S3C64XX_SPCON);
+
+	/* remove the LCD bypass */
+	tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+	tmp &= ~MIFPCON_LCD_BYPASS;
+	__raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+/* GPF1 = LCD panel power
+ * GPF4 = LCD backlight control
+ */
+static void anw6410_lcd_power_set(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	if (power) {
+		anw6410_extdev_status |= (ANW6410_EN_LCD << 16);
+		__raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
+
+		gpio_direction_output(S3C64XX_GPF(1), 1);
+		gpio_direction_output(S3C64XX_GPF(4), 1);
+	} else {
+		anw6410_extdev_status &= ~(ANW6410_EN_LCD << 16);
+		__raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
+
+		gpio_direction_output(S3C64XX_GPF(1), 0);
+		gpio_direction_output(S3C64XX_GPF(4), 0);
+	}
+}
+
+static struct plat_lcd_data anw6410_lcd_power_data = {
+	.set_power	= anw6410_lcd_power_set,
+};
+
+static struct platform_device anw6410_lcd_powerdev = {
+	.name			= "platform-lcd",
+	.dev.parent		= &s3c_device_fb.dev,
+	.dev.platform_data	= &anw6410_lcd_power_data,
+};
+
+static struct s3c_fb_pd_win anw6410_fb_win0 = {
+	/* this is to ensure we use win0 */
+	.win_mode	= {
+		.pixclock	= 41094,
+		.left_margin	= 8,
+		.right_margin	= 13,
+		.upper_margin	= 7,
+		.lower_margin	= 5,
+		.hsync_len	= 3,
+		.vsync_len	= 1,
+		.xres		= 800,
+		.yres		= 480,
+	},
+	.max_bpp	= 32,
+	.default_bpp	= 16,
+};
+
+/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
+static struct s3c_fb_platdata anw6410_lcd_pdata __initdata = {
+	.setup_gpio	= s3c64xx_fb_gpio_setup_24bpp,
+	.win[0]		= &anw6410_fb_win0,
+	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+static void __init anw6410_dm9000_enable(void)
+{
+	anw6410_extdev_status |= (ANW6410_EN_DM9000 << 16);
+	__raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
+}
+
+static struct resource anw6410_dm9000_resource[] = {
+	[0] = {
+		.start = ANW6410_PA_DM9000,
+		.end   = ANW6410_PA_DM9000 + 3,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = ANW6410_PA_DM9000 + 4,
+		.end   = ANW6410_PA_DM9000 + 4 + 500,
+		.flags = IORESOURCE_MEM,
+	},
+	[2] = {
+		.start = IRQ_EINT(15),
+		.end   = IRQ_EINT(15),
+		.flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
+	},
+};
+
+static struct dm9000_plat_data anw6410_dm9000_pdata = {
+	.flags	  = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+	/* dev_addr can be set to provide hwaddr. */
+};
+
+static struct platform_device anw6410_device_eth = {
+	.name	= "dm9000",
+	.id	= -1,
+	.num_resources	= ARRAY_SIZE(anw6410_dm9000_resource),
+	.resource	= anw6410_dm9000_resource,
+	.dev	= {
+		.platform_data  = &anw6410_dm9000_pdata,
+	},
+};
+
+static struct map_desc anw6410_iodesc[] __initdata = {
+	{
+		.virtual	= (unsigned long)ANW6410_VA_EXTDEV,
+		.pfn		= __phys_to_pfn(ANW6410_PA_EXTDEV),
+		.length		= SZ_64K,
+		.type		= MT_DEVICE,
+	},
+};
+
+static struct platform_device *anw6410_devices[] __initdata = {
+	&s3c_device_fb,
+	&anw6410_lcd_powerdev,
+	&anw6410_device_eth,
+};
+
+static void __init anw6410_map_io(void)
+{
+	s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc));
+	s3c24xx_init_clocks(12000000);
+	s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs));
+
+	anw6410_lcd_mode_set();
+}
+
+static void __init anw6410_machine_init(void)
+{
+	s3c_fb_set_platdata(&anw6410_lcd_pdata);
+
+	gpio_request(S3C64XX_GPF(1), "panel power");
+	gpio_request(S3C64XX_GPF(4), "LCD backlight");
+
+	anw6410_dm9000_enable();
+
+	platform_add_devices(anw6410_devices, ARRAY_SIZE(anw6410_devices));
+}
+
+MACHINE_START(ANW6410, "A&W6410")
+	/* Maintainer: Kwangwoo Lee <kwangwoo.lee@gmail.com> */
+	.phys_io	= S3C_PA_UART & 0xfff00000,
+	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
+
+	.init_irq	= s3c6410_init_irq,
+	.map_io		= anw6410_map_io,
+	.init_machine	= anw6410_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/mach-hmt.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/mach-hmt.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/mach-hmt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/mach-hmt.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,276 @@
+/* mach-hmt.c - Platform code for Airgoo HMT
+ *
+ * Copyright 2009 Peter Korsgaard <jacmet@sunsite.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.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/pwm_backlight.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+#include <plat/fb.h>
+#include <plat/nand.h>
+
+#include <mach/s3c6410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg hmt_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+	[1] = {
+		.hwport	     = 1,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+	[2] = {
+		.hwport	     = 2,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+};
+
+static int hmt_bl_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(S3C64XX_GPB(4), "lcd backlight enable");
+	if (!ret)
+		ret = gpio_direction_output(S3C64XX_GPB(4), 0);
+
+	return ret;
+}
+
+static int hmt_bl_notify(struct device *dev, int brightness)
+{
+	/*
+	 * translate from CIELUV/CIELAB L*->brightness, E.G. from
+	 * perceived luminance to light output. Assumes range 0..25600
+	 */
+	if (brightness < 0x800) {
+		/* Y = Yn * L / 903.3 */
+		brightness = (100*256 * brightness + 231245/2) / 231245;
+	} else {
+		/* Y = Yn * ((L + 16) / 116 )^3 */
+		int t = (brightness*4 + 16*1024 + 58)/116;
+		brightness = 25 * ((t * t * t + 0x100000/2) / 0x100000);
+	}
+
+	gpio_set_value(S3C64XX_GPB(4), brightness);
+
+	return brightness;
+}
+
+static void hmt_bl_exit(struct device *dev)
+{
+	gpio_free(S3C64XX_GPB(4));
+}
+
+static struct platform_pwm_backlight_data hmt_backlight_data = {
+	.pwm_id		= 1,
+	.max_brightness	= 100 * 256,
+	.dft_brightness	= 40 * 256,
+	.pwm_period_ns	= 1000000000 / (100 * 256 * 20),
+	.init		= hmt_bl_init,
+	.notify		= hmt_bl_notify,
+	.exit		= hmt_bl_exit,
+
+};
+
+static struct platform_device hmt_backlight_device = {
+	.name		= "pwm-backlight",
+	.dev		= {
+		.parent	= &s3c_device_timer[1].dev,
+		.platform_data = &hmt_backlight_data,
+	},
+};
+
+static struct s3c_fb_pd_win hmt_fb_win0 = {
+	.win_mode	= {
+		.pixclock	= 41094,
+		.left_margin	= 8,
+		.right_margin	= 13,
+		.upper_margin	= 7,
+		.lower_margin	= 5,
+		.hsync_len	= 3,
+		.vsync_len	= 1,
+		.xres		= 800,
+		.yres		= 480,
+	},
+	.max_bpp	= 32,
+	.default_bpp	= 16,
+};
+
+/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
+static struct s3c_fb_platdata hmt_lcd_pdata __initdata = {
+	.setup_gpio	= s3c64xx_fb_gpio_setup_24bpp,
+	.win[0]		= &hmt_fb_win0,
+	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+static struct mtd_partition hmt_nand_part[] = {
+	[0] = {
+		.name	= "uboot",
+		.size	= SZ_512K,
+		.offset	= 0,
+	},
+	[1] = {
+		.name	= "uboot-env1",
+		.size	= SZ_256K,
+		.offset	= SZ_512K,
+	},
+	[2] = {
+		.name	= "uboot-env2",
+		.size	= SZ_256K,
+		.offset	= SZ_512K + SZ_256K,
+	},
+	[3] = {
+		.name	= "kernel",
+		.size	= SZ_2M,
+		.offset	= SZ_1M,
+	},
+	[4] = {
+		.name	= "rootfs",
+		.size	= MTDPART_SIZ_FULL,
+		.offset	= SZ_1M + SZ_2M,
+	},
+};
+
+static struct s3c2410_nand_set hmt_nand_sets[] = {
+	[0] = {
+		.name		= "nand",
+		.nr_chips	= 1,
+		.nr_partitions	= ARRAY_SIZE(hmt_nand_part),
+		.partitions	= hmt_nand_part,
+	},
+};
+
+static struct s3c2410_platform_nand hmt_nand_info = {
+	.tacls		= 25,
+	.twrph0		= 55,
+	.twrph1		= 40,
+	.nr_sets	= ARRAY_SIZE(hmt_nand_sets),
+	.sets		= hmt_nand_sets,
+};
+
+static struct gpio_led hmt_leds[] = {
+	{ /* left function keys */
+		.name			= "left:blue",
+		.gpio			= S3C64XX_GPO(12),
+		.default_trigger	= "default-on",
+	},
+	{ /* right function keys - red */
+		.name			= "right:red",
+		.gpio			= S3C64XX_GPO(13),
+	},
+	{ /* right function keys - green */
+		.name			= "right:green",
+		.gpio			= S3C64XX_GPO(14),
+	},
+	{ /* right function keys - blue */
+		.name			= "right:blue",
+		.gpio			= S3C64XX_GPO(15),
+		.default_trigger	= "default-on",
+	},
+};
+
+static struct gpio_led_platform_data hmt_led_data = {
+	.num_leds = ARRAY_SIZE(hmt_leds),
+	.leds = hmt_leds,
+};
+
+static struct platform_device hmt_leds_device = {
+	.name			= "leds-gpio",
+	.id			= -1,
+	.dev.platform_data	= &hmt_led_data,
+};
+
+static struct map_desc hmt_iodesc[] = {};
+
+static struct platform_device *hmt_devices[] __initdata = {
+	&s3c_device_i2c0,
+	&s3c_device_nand,
+	&s3c_device_fb,
+	&s3c_device_ohci,
+	&s3c_device_timer[1],
+	&hmt_backlight_device,
+	&hmt_leds_device,
+};
+
+static void __init hmt_map_io(void)
+{
+	s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc));
+	s3c24xx_init_clocks(12000000);
+	s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs));
+}
+
+static void __init hmt_machine_init(void)
+{
+	s3c_i2c0_set_platdata(NULL);
+	s3c_fb_set_platdata(&hmt_lcd_pdata);
+	s3c_nand_set_platdata(&hmt_nand_info);
+
+	gpio_request(S3C64XX_GPC(7), "usb power");
+	gpio_direction_output(S3C64XX_GPC(7), 0);
+	gpio_request(S3C64XX_GPM(0), "usb power");
+	gpio_direction_output(S3C64XX_GPM(0), 1);
+	gpio_request(S3C64XX_GPK(7), "usb power");
+	gpio_direction_output(S3C64XX_GPK(7), 1);
+	gpio_request(S3C64XX_GPF(13), "usb power");
+	gpio_direction_output(S3C64XX_GPF(13), 1);
+
+	platform_add_devices(hmt_devices, ARRAY_SIZE(hmt_devices));
+}
+
+MACHINE_START(HMT, "Airgoo-HMT")
+	/* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */
+	.phys_io	= S3C_PA_UART & 0xfff00000,
+	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
+	.init_irq	= s3c6410_init_irq,
+	.map_io		= hmt_map_io,
+	.init_machine	= hmt_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/mach-ncp.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/mach-ncp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/mach-ncp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/mach-ncp.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,107 @@
+/*
+ * linux/arch/arm/mach-s3c64xx/mach-ncp.c
+ *
+ * Copyright (C) 2008-2009 Samsung Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include <video/platform_lcd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+#include <plat/fb.h>
+
+#include <mach/s3c6410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg ncp_uartcfgs[] __initdata = {
+	/* REVISIT: NCP uses only serial 1, 2 */
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+	[1] = {
+		.hwport	     = 1,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+	[2] = {
+		.hwport	     = 2,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+};
+
+static struct platform_device *ncp_devices[] __initdata = {
+	&s3c_device_hsmmc1,
+	&s3c_device_i2c0,
+};
+
+static struct map_desc ncp_iodesc[] __initdata = {};
+
+static void __init ncp_map_io(void)
+{
+	s3c64xx_init_io(ncp_iodesc, ARRAY_SIZE(ncp_iodesc));
+	s3c24xx_init_clocks(12000000);
+	s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs));
+}
+
+static void __init ncp_machine_init(void)
+{
+	s3c_i2c0_set_platdata(NULL);
+
+	platform_add_devices(ncp_devices, ARRAY_SIZE(ncp_devices));
+}
+
+MACHINE_START(NCP, "NCP")
+	/* Maintainer: Samsung Electronics */
+	.phys_io	= S3C_PA_UART & 0xfff00000,
+	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
+	.init_irq	= s3c6410_init_irq,
+	.map_io		= ncp_map_io,
+	.init_machine	= ncp_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/mach-smdk6400.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/mach-smdk6400.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/mach-smdk6400.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/mach-smdk6400.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,96 @@
+/* linux/arch/arm/mach-s3c64xx/mach-smdk6400.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/regs-serial.h>
+
+#include <mach/s3c6400.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/iic.h>
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk6400_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+	[1] = {
+		.hwport	     = 1,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+};
+
+static struct map_desc smdk6400_iodesc[] = {};
+
+static void __init smdk6400_map_io(void)
+{
+	s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc));
+	s3c24xx_init_clocks(12000000);
+	s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs));
+}
+
+static struct platform_device *smdk6400_devices[] __initdata = {
+	&s3c_device_hsmmc1,
+	&s3c_device_i2c0,
+};
+
+static struct i2c_board_info i2c_devs[] __initdata = {
+	{ I2C_BOARD_INFO("wm8753", 0x1A), },
+	{ I2C_BOARD_INFO("24c08", 0x50), },
+};
+
+static void __init smdk6400_machine_init(void)
+{
+	i2c_register_board_info(0, i2c_devs, ARRAY_SIZE(i2c_devs));
+	platform_add_devices(smdk6400_devices, ARRAY_SIZE(smdk6400_devices));
+}
+
+MACHINE_START(SMDK6400, "SMDK6400")
+	/* Maintainer: Ben Dooks <ben@fluff.org> */
+	.phys_io	= S3C_PA_UART & 0xfff00000,
+	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
+
+	.init_irq	= s3c6400_init_irq,
+	.map_io		= smdk6400_map_io,
+	.init_machine	= smdk6400_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/mach-smdk6410.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/mach-smdk6410.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/mach-smdk6410.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/mach-smdk6410.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,668 @@
+/* linux/arch/arm/mach-s3c64xx/mach-smdk6410.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/smsc911x.h>
+#include <linux/regulator/fixed.h>
+
+#ifdef CONFIG_SMDK6410_WM1190_EV1
+#include <linux/mfd/wm8350/core.h>
+#include <linux/mfd/wm8350/pmic.h>
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1192_EV1
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/pdata.h>
+#endif
+
+#include <video/platform_lcd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-modem.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-sys.h>
+#include <mach/regs-srom.h>
+#include <plat/iic.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/s3c6410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk6410_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+	[1] = {
+		.hwport	     = 1,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+	[2] = {
+		.hwport	     = 2,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+	[3] = {
+		.hwport	     = 3,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+};
+
+/* framebuffer and LCD setup. */
+
+/* GPF15 = LCD backlight control
+ * GPF13 => Panel power
+ * GPN5 = LCD nRESET signal
+ * PWM_TOUT1 => backlight brightness
+ */
+
+static void smdk6410_lcd_power_set(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	if (power) {
+		gpio_direction_output(S3C64XX_GPF(13), 1);
+		gpio_direction_output(S3C64XX_GPF(15), 1);
+
+		/* fire nRESET on power up */
+		gpio_direction_output(S3C64XX_GPN(5), 0);
+		msleep(10);
+		gpio_direction_output(S3C64XX_GPN(5), 1);
+		msleep(1);
+	} else {
+		gpio_direction_output(S3C64XX_GPF(15), 0);
+		gpio_direction_output(S3C64XX_GPF(13), 0);
+	}
+}
+
+static struct plat_lcd_data smdk6410_lcd_power_data = {
+	.set_power	= smdk6410_lcd_power_set,
+};
+
+static struct platform_device smdk6410_lcd_powerdev = {
+	.name			= "platform-lcd",
+	.dev.parent		= &s3c_device_fb.dev,
+	.dev.platform_data	= &smdk6410_lcd_power_data,
+};
+
+static struct s3c_fb_pd_win smdk6410_fb_win0 = {
+	/* this is to ensure we use win0 */
+	.win_mode	= {
+		.pixclock	= 41094,
+		.left_margin	= 8,
+		.right_margin	= 13,
+		.upper_margin	= 7,
+		.lower_margin	= 5,
+		.hsync_len	= 3,
+		.vsync_len	= 1,
+		.xres		= 800,
+		.yres		= 480,
+	},
+	.max_bpp	= 32,
+	.default_bpp	= 16,
+};
+
+/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
+static struct s3c_fb_platdata smdk6410_lcd_pdata __initdata = {
+	.setup_gpio	= s3c64xx_fb_gpio_setup_24bpp,
+	.win[0]		= &smdk6410_fb_win0,
+	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+/*
+ * Configuring Ethernet on SMDK6410
+ *
+ * Both CS8900A and LAN9115 chips share one chip select mediated by CFG6.
+ * The constant address below corresponds to nCS1
+ *
+ *  1) Set CFGB2 p3 ON others off, no other CFGB selects "ethernet"
+ *  2) CFG6 needs to be switched to "LAN9115" side
+ */
+
+static struct resource smdk6410_smsc911x_resources[] = {
+	[0] = {
+		.start = S3C64XX_PA_XM0CSN1,
+		.end   = S3C64XX_PA_XM0CSN1 + SZ_64K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = S3C_EINT(10),
+		.end   = S3C_EINT(10),
+		.flags = IORESOURCE_IRQ | IRQ_TYPE_LEVEL_LOW,
+	},
+};
+
+static struct smsc911x_platform_config smdk6410_smsc911x_pdata = {
+	.irq_polarity  = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type      = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.flags         = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY,
+	.phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+
+static struct platform_device smdk6410_smsc911x = {
+	.name          = "smsc911x",
+	.id            = -1,
+	.num_resources = ARRAY_SIZE(smdk6410_smsc911x_resources),
+	.resource      = &smdk6410_smsc911x_resources[0],
+	.dev = {
+		.platform_data = &smdk6410_smsc911x_pdata,
+	},
+};
+
+#ifdef CONFIG_REGULATOR
+static struct regulator_consumer_supply smdk6410_b_pwr_5v_consumers[] = {
+	{
+		/* WM8580 */
+		.supply = "PVDD",
+		.dev_name = "0-001b",
+	},
+	{
+		/* WM8580 */
+		.supply = "AVDD",
+		.dev_name = "0-001b",
+	},
+};
+
+static struct regulator_init_data smdk6410_b_pwr_5v_data = {
+	.constraints = {
+		.always_on = 1,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(smdk6410_b_pwr_5v_consumers),
+	.consumer_supplies = smdk6410_b_pwr_5v_consumers,
+};
+
+static struct fixed_voltage_config smdk6410_b_pwr_5v_pdata = {
+	.supply_name = "B_PWR_5V",
+	.microvolts = 5000000,
+	.init_data = &smdk6410_b_pwr_5v_data,
+	.gpio = -EINVAL,
+};
+
+static struct platform_device smdk6410_b_pwr_5v = {
+	.name          = "reg-fixed-voltage",
+	.id            = -1,
+	.dev = {
+		.platform_data = &smdk6410_b_pwr_5v_pdata,
+	},
+};
+#endif
+
+static struct map_desc smdk6410_iodesc[] = {};
+
+static struct platform_device *smdk6410_devices[] __initdata = {
+#ifdef CONFIG_SMDK6410_SD_CH0
+	&s3c_device_hsmmc0,
+#endif
+#ifdef CONFIG_SMDK6410_SD_CH1
+	&s3c_device_hsmmc1,
+#endif
+	&s3c_device_i2c0,
+	&s3c_device_i2c1,
+	&s3c_device_fb,
+	&s3c_device_ohci,
+	&s3c_device_usb_hsotg,
+	&s3c64xx_device_iisv4,
+
+#ifdef CONFIG_REGULATOR
+	&smdk6410_b_pwr_5v,
+#endif
+	&smdk6410_lcd_powerdev,
+
+	&smdk6410_smsc911x,
+};
+
+#ifdef CONFIG_REGULATOR
+/* ARM core */
+static struct regulator_consumer_supply smdk6410_vddarm_consumers[] = {
+	{
+		.supply = "vddarm",
+	}
+};
+
+/* VDDARM, BUCK1 on J5 */
+static struct regulator_init_data smdk6410_vddarm = {
+	.constraints = {
+		.name = "PVDD_ARM",
+		.min_uV = 1000000,
+		.max_uV = 1300000,
+		.always_on = 1,
+		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(smdk6410_vddarm_consumers),
+	.consumer_supplies = smdk6410_vddarm_consumers,
+};
+
+/* VDD_INT, BUCK2 on J5 */
+static struct regulator_init_data smdk6410_vddint = {
+	.constraints = {
+		.name = "PVDD_INT",
+		.min_uV = 1000000,
+		.max_uV = 1200000,
+		.always_on = 1,
+		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+	},
+};
+
+/* VDD_HI, LDO3 on J5 */
+static struct regulator_init_data smdk6410_vddhi = {
+	.constraints = {
+		.name = "PVDD_HI",
+		.always_on = 1,
+	},
+};
+
+/* VDD_PLL, LDO2 on J5 */
+static struct regulator_init_data smdk6410_vddpll = {
+	.constraints = {
+		.name = "PVDD_PLL",
+		.always_on = 1,
+	},
+};
+
+/* VDD_UH_MMC, LDO5 on J5 */
+static struct regulator_init_data smdk6410_vdduh_mmc = {
+	.constraints = {
+		.name = "PVDD_UH/PVDD_MMC",
+		.always_on = 1,
+	},
+};
+
+/* VCCM3BT, LDO8 on J5 */
+static struct regulator_init_data smdk6410_vccmc3bt = {
+	.constraints = {
+		.name = "PVCCM3BT",
+		.always_on = 1,
+	},
+};
+
+/* VCCM2MTV, LDO11 on J5 */
+static struct regulator_init_data smdk6410_vccm2mtv = {
+	.constraints = {
+		.name = "PVCCM2MTV",
+		.always_on = 1,
+	},
+};
+
+/* VDD_LCD, LDO12 on J5 */
+static struct regulator_init_data smdk6410_vddlcd = {
+	.constraints = {
+		.name = "PVDD_LCD",
+		.always_on = 1,
+	},
+};
+
+/* VDD_OTGI, LDO9 on J5 */
+static struct regulator_init_data smdk6410_vddotgi = {
+	.constraints = {
+		.name = "PVDD_OTGI",
+		.always_on = 1,
+	},
+};
+
+/* VDD_OTG, LDO14 on J5 */
+static struct regulator_init_data smdk6410_vddotg = {
+	.constraints = {
+		.name = "PVDD_OTG",
+		.always_on = 1,
+	},
+};
+
+/* VDD_ALIVE, LDO15 on J5 */
+static struct regulator_init_data smdk6410_vddalive = {
+	.constraints = {
+		.name = "PVDD_ALIVE",
+		.always_on = 1,
+	},
+};
+
+/* VDD_AUDIO, VLDO_AUDIO on J5 */
+static struct regulator_init_data smdk6410_vddaudio = {
+	.constraints = {
+		.name = "PVDD_AUDIO",
+		.always_on = 1,
+	},
+};
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1190_EV1
+/* S3C64xx internal logic & PLL */
+static struct regulator_init_data wm8350_dcdc1_data = {
+	.constraints = {
+		.name = "PVDD_INT/PVDD_PLL",
+		.min_uV = 1200000,
+		.max_uV = 1200000,
+		.always_on = 1,
+		.apply_uV = 1,
+	},
+};
+
+/* Memory */
+static struct regulator_init_data wm8350_dcdc3_data = {
+	.constraints = {
+		.name = "PVDD_MEM",
+		.min_uV = 1800000,
+		.max_uV = 1800000,
+		.always_on = 1,
+		.state_mem = {
+			 .uV = 1800000,
+			 .mode = REGULATOR_MODE_NORMAL,
+			 .enabled = 1,
+		},
+		.initial_state = PM_SUSPEND_MEM,
+	},
+};
+
+/* USB, EXT, PCM, ADC/DAC, USB, MMC */
+static struct regulator_consumer_supply wm8350_dcdc4_consumers[] = {
+	{
+		/* WM8580 */
+		.supply = "DVDD",
+		.dev_name = "0-001b",
+	},
+};
+
+static struct regulator_init_data wm8350_dcdc4_data = {
+	.constraints = {
+		.name = "PVDD_HI/PVDD_EXT/PVDD_SYS/PVCCM2MTV",
+		.min_uV = 3000000,
+		.max_uV = 3000000,
+		.always_on = 1,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(wm8350_dcdc4_consumers),
+	.consumer_supplies = wm8350_dcdc4_consumers,
+};
+
+/* OTGi/1190-EV1 HPVDD & AVDD */
+static struct regulator_init_data wm8350_ldo4_data = {
+	.constraints = {
+		.name = "PVDD_OTGI/HPVDD/AVDD",
+		.min_uV = 1200000,
+		.max_uV = 1200000,
+		.apply_uV = 1,
+		.always_on = 1,
+	},
+};
+
+static struct {
+	int regulator;
+	struct regulator_init_data *initdata;
+} wm1190_regulators[] = {
+	{ WM8350_DCDC_1, &wm8350_dcdc1_data },
+	{ WM8350_DCDC_3, &wm8350_dcdc3_data },
+	{ WM8350_DCDC_4, &wm8350_dcdc4_data },
+	{ WM8350_DCDC_6, &smdk6410_vddarm },
+	{ WM8350_LDO_1, &smdk6410_vddalive },
+	{ WM8350_LDO_2, &smdk6410_vddotg },
+	{ WM8350_LDO_3, &smdk6410_vddlcd },
+	{ WM8350_LDO_4, &wm8350_ldo4_data },
+};
+
+static int __init smdk6410_wm8350_init(struct wm8350 *wm8350)
+{
+	int i;
+
+	/* Configure the IRQ line */
+	s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_UP);
+
+	/* Instantiate the regulators */
+	for (i = 0; i < ARRAY_SIZE(wm1190_regulators); i++)
+		wm8350_register_regulator(wm8350,
+					  wm1190_regulators[i].regulator,
+					  wm1190_regulators[i].initdata);
+
+	return 0;
+}
+
+static struct wm8350_platform_data __initdata smdk6410_wm8350_pdata = {
+	.init = smdk6410_wm8350_init,
+	.irq_high = 1,
+	.irq_base = IRQ_BOARD_START,
+};
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1192_EV1
+static struct gpio_led wm1192_pmic_leds[] = {
+	{
+		.name = "PMIC:red:power",
+		.gpio = GPIO_BOARD_START + 3,
+		.default_state = LEDS_GPIO_DEFSTATE_ON,
+	},
+};
+
+static struct gpio_led_platform_data wm1192_pmic_led = {
+	.num_leds = ARRAY_SIZE(wm1192_pmic_leds),
+	.leds = wm1192_pmic_leds,
+};
+
+static struct platform_device wm1192_pmic_led_dev = {
+	.name          = "leds-gpio",
+	.id            = -1,
+	.dev = {
+		.platform_data = &wm1192_pmic_led,
+	},
+};
+
+static int wm1192_pre_init(struct wm831x *wm831x)
+{
+	int ret;
+
+	/* Configure the IRQ line */
+	s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_UP);
+
+	ret = platform_device_register(&wm1192_pmic_led_dev);
+	if (ret != 0)
+		dev_err(wm831x->dev, "Failed to add PMIC LED: %d\n", ret);
+
+	return 0;
+}
+
+static struct wm831x_backlight_pdata wm1192_backlight_pdata = {
+	.isink = 1,
+	.max_uA = 27554,
+};
+
+static struct regulator_init_data wm1192_dcdc3 = {
+	.constraints = {
+		.name = "PVDD_MEM/PVDD_GPS",
+		.always_on = 1,
+	},
+};
+
+static struct regulator_consumer_supply wm1192_ldo1_consumers[] = {
+	{ .supply = "DVDD", .dev_name = "0-001b", },   /* WM8580 */
+};
+
+static struct regulator_init_data wm1192_ldo1 = {
+	.constraints = {
+		.name = "PVDD_LCD/PVDD_EXT",
+		.always_on = 1,
+	},
+	.consumer_supplies = wm1192_ldo1_consumers,
+	.num_consumer_supplies = ARRAY_SIZE(wm1192_ldo1_consumers),
+};
+
+static struct wm831x_status_pdata wm1192_led7_pdata = {
+	.name = "LED7:green:",
+};
+
+static struct wm831x_status_pdata wm1192_led8_pdata = {
+	.name = "LED8:green:",
+};
+
+static struct wm831x_pdata smdk6410_wm1192_pdata = {
+	.pre_init = wm1192_pre_init,
+	.irq_base = IRQ_BOARD_START,
+
+	.backlight = &wm1192_backlight_pdata,
+	.dcdc = {
+		&smdk6410_vddarm,  /* DCDC1 */
+		&smdk6410_vddint,  /* DCDC2 */
+		&wm1192_dcdc3,
+	},
+	.gpio_base = GPIO_BOARD_START,
+	.ldo = {
+		 &wm1192_ldo1,        /* LDO1 */
+		 &smdk6410_vdduh_mmc, /* LDO2 */
+		 NULL,                /* LDO3 NC */
+		 &smdk6410_vddotgi,   /* LDO4 */
+		 &smdk6410_vddotg,    /* LDO5 */
+		 &smdk6410_vddhi,     /* LDO6 */
+		 &smdk6410_vddaudio,  /* LDO7 */
+		 &smdk6410_vccm2mtv,  /* LDO8 */
+		 &smdk6410_vddpll,    /* LDO9 */
+		 &smdk6410_vccmc3bt,  /* LDO10 */
+		 &smdk6410_vddalive,  /* LDO11 */
+	},
+	.status = {
+		&wm1192_led7_pdata,
+		&wm1192_led8_pdata,
+	},
+};
+#endif
+
+static struct i2c_board_info i2c_devs0[] __initdata = {
+	{ I2C_BOARD_INFO("24c08", 0x50), },
+	{ I2C_BOARD_INFO("wm8580", 0x1b), },
+
+#ifdef CONFIG_SMDK6410_WM1192_EV1
+	{ I2C_BOARD_INFO("wm8312", 0x34),
+	  .platform_data = &smdk6410_wm1192_pdata,
+	  .irq = S3C_EINT(12),
+	},
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1190_EV1
+	{ I2C_BOARD_INFO("wm8350", 0x1a),
+	  .platform_data = &smdk6410_wm8350_pdata,
+	  .irq = S3C_EINT(12),
+	},
+#endif
+};
+
+static struct i2c_board_info i2c_devs1[] __initdata = {
+	{ I2C_BOARD_INFO("24c128", 0x57), },	/* Samsung S524AD0XD1 */
+};
+
+static void __init smdk6410_map_io(void)
+{
+	u32 tmp;
+
+	s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc));
+	s3c24xx_init_clocks(12000000);
+	s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs));
+
+	/* set the LCD type */
+
+	tmp = __raw_readl(S3C64XX_SPCON);
+	tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+	tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+	__raw_writel(tmp, S3C64XX_SPCON);
+
+	/* remove the lcd bypass */
+	tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+	tmp &= ~MIFPCON_LCD_BYPASS;
+	__raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+static void __init smdk6410_machine_init(void)
+{
+	u32 cs1;
+
+	s3c_i2c0_set_platdata(NULL);
+	s3c_i2c1_set_platdata(NULL);
+	s3c_fb_set_platdata(&smdk6410_lcd_pdata);
+
+	/* configure nCS1 width to 16 bits */
+
+	cs1 = __raw_readl(S3C64XX_SROM_BW) &
+		    ~(S3C64XX_SROM_BW__CS_MASK << S3C64XX_SROM_BW__NCS1__SHIFT);
+	cs1 |= ((1 << S3C64XX_SROM_BW__DATAWIDTH__SHIFT) |
+		(1 << S3C64XX_SROM_BW__WAITENABLE__SHIFT) |
+		(1 << S3C64XX_SROM_BW__BYTEENABLE__SHIFT)) <<
+						   S3C64XX_SROM_BW__NCS1__SHIFT;
+	__raw_writel(cs1, S3C64XX_SROM_BW);
+
+	/* set timing for nCS1 suitable for ethernet chip */
+
+	__raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) |
+		     (6 << S3C64XX_SROM_BCX__TACP__SHIFT) |
+		     (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) |
+		     (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) |
+		     (0xe << S3C64XX_SROM_BCX__TACC__SHIFT) |
+		     (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
+		     (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
+
+	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));
+
+	platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
+}
+
+MACHINE_START(SMDK6410, "SMDK6410")
+	/* Maintainer: Ben Dooks <ben@fluff.org> */
+	.phys_io	= S3C_PA_UART & 0xfff00000,
+	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
+
+	.init_irq	= s3c6410_init_irq,
+	.map_io		= smdk6410_map_io,
+	.init_machine	= smdk6410_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,62 @@
+# arch/arm/mach-s3c64xx/Makefile
+#
+# Copyright 2008 Openmoko, Inc.
+# Copyright 2008 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:=
+obj-				:=
+
+# Core files
+obj-y				+= cpu.o
+obj-y				+= clock.o
+obj-y				+= gpiolib.o
+
+# Core support for S3C6400 system
+
+obj-$(CONFIG_CPU_S3C6400)	+= s3c6400.o
+obj-$(CONFIG_CPU_S3C6410)	+= s3c6410.o
+
+obj-y				+= irq.o
+obj-y				+= irq-eint.o
+
+# CPU frequency scaling
+
+obj-$(CONFIG_CPU_FREQ_S3C64XX)  += cpufreq.o
+
+# DMA support
+
+obj-$(CONFIG_S3C64XX_DMA)	+= dma.o
+
+# Device setup
+
+obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
+obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o
+obj-$(CONFIG_S3C64XX_SETUP_SDHCI) += setup-sdhci.o
+obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
+obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
+
+# PM
+
+obj-$(CONFIG_PM)		+= pm.o
+obj-$(CONFIG_PM)		+= sleep.o
+obj-$(CONFIG_PM)		+= irq-pm.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_ANW6410)	+= mach-anw6410.o
+obj-$(CONFIG_MACH_SMDK6400)	+= mach-smdk6400.o
+obj-$(CONFIG_MACH_SMDK6410)	+= mach-smdk6410.o
+obj-$(CONFIG_MACH_NCP)		+= mach-ncp.o
+obj-$(CONFIG_MACH_HMT)		+= mach-hmt.o
+
+# device support
+
+obj-y				+= dev-uart.o
+obj-y				+= dev-rtc.o
+obj-y				+= dev-audio.o
+obj-$(CONFIG_S3C_ADC)		+= dev-adc.o
+obj-$(CONFIG_S3C64XX_DEV_SPI)	+= dev-spi.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/Makefile.boot linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/Makefile.boot
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/Makefile.boot	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,2 @@
+   zreladdr-y	:= 0x50008000
+params_phys-y	:= 0x50000100
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/pm.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/pm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/pm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,173 @@
+/* linux/arch/arm/plat-s3c64xx/pm.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX CPU PM 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/serial_core.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+
+#include <plat/pm.h>
+#include <mach/regs-sys.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-syscon-power.h>
+#include <mach/regs-gpio-memport.h>
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+#include <mach/gpio-bank-n.h>
+
+void s3c_pm_debug_smdkled(u32 set, u32 clear)
+{
+	unsigned long flags;
+	u32 reg;
+
+	local_irq_save(flags);
+	reg = __raw_readl(S3C64XX_GPNCON);
+	reg &= ~(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) |
+		 S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15));
+	reg |= S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) |
+	       S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15);
+	__raw_writel(reg, S3C64XX_GPNCON);
+
+	reg = __raw_readl(S3C64XX_GPNDAT);
+	reg &= ~(clear << 12);
+	reg |= set << 12;
+	__raw_writel(reg, S3C64XX_GPNDAT);
+
+	local_irq_restore(flags);
+}
+#endif
+
+static struct sleep_save core_save[] = {
+	SAVE_ITEM(S3C_APLL_LOCK),
+	SAVE_ITEM(S3C_MPLL_LOCK),
+	SAVE_ITEM(S3C_EPLL_LOCK),
+	SAVE_ITEM(S3C_CLK_SRC),
+	SAVE_ITEM(S3C_CLK_DIV0),
+	SAVE_ITEM(S3C_CLK_DIV1),
+	SAVE_ITEM(S3C_CLK_DIV2),
+	SAVE_ITEM(S3C_CLK_OUT),
+	SAVE_ITEM(S3C_HCLK_GATE),
+	SAVE_ITEM(S3C_PCLK_GATE),
+	SAVE_ITEM(S3C_SCLK_GATE),
+	SAVE_ITEM(S3C_MEM0_GATE),
+
+	SAVE_ITEM(S3C_EPLL_CON1),
+	SAVE_ITEM(S3C_EPLL_CON0),
+
+	SAVE_ITEM(S3C64XX_MEM0DRVCON),
+	SAVE_ITEM(S3C64XX_MEM1DRVCON),
+
+#ifndef CONFIG_CPU_FREQ
+	SAVE_ITEM(S3C_APLL_CON),
+	SAVE_ITEM(S3C_MPLL_CON),
+#endif
+};
+
+static struct sleep_save misc_save[] = {
+	SAVE_ITEM(S3C64XX_AHB_CON0),
+	SAVE_ITEM(S3C64XX_AHB_CON1),
+	SAVE_ITEM(S3C64XX_AHB_CON2),
+	
+	SAVE_ITEM(S3C64XX_SPCON),
+
+	SAVE_ITEM(S3C64XX_MEM0CONSTOP),
+	SAVE_ITEM(S3C64XX_MEM1CONSTOP),
+	SAVE_ITEM(S3C64XX_MEM0CONSLP0),
+	SAVE_ITEM(S3C64XX_MEM0CONSLP1),
+	SAVE_ITEM(S3C64XX_MEM1CONSLP),
+};
+
+void s3c_pm_configure_extint(void)
+{
+	__raw_writel(s3c_irqwake_eintmask, S3C64XX_EINT_MASK);
+}
+
+void s3c_pm_restore_core(void)
+{
+	__raw_writel(0, S3C64XX_EINT_MASK);
+
+	s3c_pm_debug_smdkled(1 << 2, 0);
+
+	s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
+	s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
+}
+
+void s3c_pm_save_core(void)
+{
+	s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
+	s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
+}
+
+/* since both s3c6400 and s3c6410 share the same sleep pm calls, we
+ * put the per-cpu code in here until any new cpu comes along and changes
+ * this.
+ */
+
+static void s3c64xx_cpu_suspend(void)
+{
+	unsigned long tmp;
+
+	/* set our standby method to sleep */
+
+	tmp = __raw_readl(S3C64XX_PWR_CFG);
+	tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
+	tmp |= S3C64XX_PWRCFG_CFG_WFI_SLEEP;
+	__raw_writel(tmp, S3C64XX_PWR_CFG);
+
+	/* clear any old wakeup */
+
+	__raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT),
+		     S3C64XX_WAKEUP_STAT);
+
+	/* set the LED state to 0110 over sleep */
+	s3c_pm_debug_smdkled(3 << 1, 0xf);
+
+	/* issue the standby signal into the pm unit. Note, we
+	 * issue a write-buffer drain just in case */
+
+	tmp = 0;
+
+	asm("b 1f\n\t"
+	    ".align 5\n\t"
+	    "1:\n\t"
+	    "mcr p15, 0, %0, c7, c10, 5\n\t"
+	    "mcr p15, 0, %0, c7, c10, 4\n\t"
+	    "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp));
+
+	/* we should never get past here */
+
+	panic("sleep resumed to originator?");
+}
+
+static void s3c64xx_pm_prepare(void)
+{
+	/* store address of resume. */
+	__raw_writel(virt_to_phys(s3c_cpu_resume), S3C64XX_INFORM0);
+
+	/* ensure previous wakeup state is cleared before sleeping */
+	__raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT), S3C64XX_WAKEUP_STAT);
+}
+
+static int s3c64xx_pm_init(void)
+{
+	pm_cpu_prep = s3c64xx_pm_prepare;
+	pm_cpu_sleep = s3c64xx_cpu_suspend;
+	pm_uart_udivslot = 1;
+	return 0;
+}
+
+arch_initcall(s3c64xx_pm_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/s3c6400.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/s3c6400.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/s3c6400.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/s3c6400.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,89 @@
+/* linux/arch/arm/mach-s3c64xx/cpu.c
+ *
+ * Copyright 2009 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/sdhci.h>
+#include <plat/iic-core.h>
+#include <mach/s3c6400.h>
+
+void __init s3c6400_map_io(void)
+{
+	/* setup SDHCI */
+
+	s3c6400_default_sdhci0();
+	s3c6400_default_sdhci1();
+	s3c6400_default_sdhci2();
+
+	/* the i2c devices are directly compatible with s3c2440 */
+	s3c_i2c0_setname("s3c2440-i2c");
+
+	s3c_device_nand.name = "s3c6400-nand";
+}
+
+void __init s3c6400_init_clocks(int xtal)
+{
+	s3c64xx_register_clocks(xtal, S3C6400_CLKDIV0_ARM_MASK);
+	s3c6400_setup_clocks();
+}
+
+void __init s3c6400_init_irq(void)
+{
+	/* VIC0 does not have IRQS 5..7,
+	 * VIC1 is fully populated. */
+	s3c64xx_init_irq(~0 & ~(0xf << 5), ~0);
+}
+
+struct sysdev_class s3c6400_sysclass = {
+	.name	= "s3c6400-core",
+};
+
+static struct sys_device s3c6400_sysdev = {
+	.cls	= &s3c6400_sysclass,
+};
+
+static int __init s3c6400_core_init(void)
+{
+	return sysdev_class_register(&s3c6400_sysclass);
+}
+
+core_initcall(s3c6400_core_init);
+
+int __init s3c6400_init(void)
+{
+	printk("S3C6400: Initialising architecture\n");
+
+	return sysdev_register(&s3c6400_sysdev);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/s3c6410.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/s3c6410.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/s3c6410.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/s3c6410.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,91 @@
+/* linux/arch/arm/mach-s3c64xx/s3c6410.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/sdhci.h>
+#include <plat/iic-core.h>
+#include <mach/s3c6400.h>
+#include <mach/s3c6410.h>
+
+void __init s3c6410_map_io(void)
+{
+	/* initialise device information early */
+	s3c6410_default_sdhci0();
+	s3c6410_default_sdhci1();
+	s3c6410_default_sdhci2();
+
+	/* the i2c devices are directly compatible with s3c2440 */
+	s3c_i2c0_setname("s3c2440-i2c");
+	s3c_i2c1_setname("s3c2440-i2c");
+
+	s3c_device_nand.name = "s3c6400-nand";
+}
+
+void __init s3c6410_init_clocks(int xtal)
+{
+	printk(KERN_DEBUG "%s: initialising clocks\n", __func__);
+	s3c64xx_register_clocks(xtal, S3C6410_CLKDIV0_ARM_MASK);
+	s3c6400_setup_clocks();
+}
+
+void __init s3c6410_init_irq(void)
+{
+	/* VIC0 is missing IRQ7, VIC1 is fully populated. */
+	s3c64xx_init_irq(~0 & ~(1 << 7), ~0);
+}
+
+struct sysdev_class s3c6410_sysclass = {
+	.name	= "s3c6410-core",
+};
+
+static struct sys_device s3c6410_sysdev = {
+	.cls	= &s3c6410_sysclass,
+};
+
+static int __init s3c6410_core_init(void)
+{
+	return sysdev_class_register(&s3c6410_sysclass);
+}
+
+core_initcall(s3c6410_core_init);
+
+int __init s3c6410_init(void)
+{
+	printk("S3C6410: Initialising architecture\n");
+
+	return sysdev_register(&s3c6410_sysdev);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/setup-fb-24bpp.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/setup-fb-24bpp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/setup-fb-24bpp.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,37 @@
+/* linux/arch/arm/plat-s3c64xx/setup-fb-24bpp.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * Base S3C64XX setup information for 24bpp LCD framebuffer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+
+#include <mach/regs-fb.h>
+#include <mach/gpio.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+extern void s3c64xx_fb_gpio_setup_24bpp(void)
+{
+	unsigned int gpio;
+
+	for (gpio = S3C64XX_GPI(0); gpio <= S3C64XX_GPI(15); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	for (gpio = S3C64XX_GPJ(0); gpio <= S3C64XX_GPJ(11); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/setup-i2c0.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/setup-i2c0.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/setup-i2c0.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/setup-i2c0.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,31 @@
+/* linux/arch/arm/plat-s3c64xx/setup-i2c0.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * Base S3C64XX I2C bus 0 gpio configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <mach/gpio.h>
+#include <mach/gpio-bank-b.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+	s3c_gpio_cfgpin(S3C64XX_GPB(5), S3C64XX_GPB5_I2C_SCL0);
+	s3c_gpio_cfgpin(S3C64XX_GPB(6), S3C64XX_GPB6_I2C_SDA0);
+	s3c_gpio_setpull(S3C64XX_GPB(5), S3C_GPIO_PULL_UP);
+	s3c_gpio_setpull(S3C64XX_GPB(6), S3C_GPIO_PULL_UP);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/setup-i2c1.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/setup-i2c1.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/setup-i2c1.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/setup-i2c1.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,31 @@
+/* linux/arch/arm/plat-s3c64xx/setup-i2c1.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * Base S3C64XX I2C bus 1 gpio configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <mach/gpio.h>
+#include <mach/gpio-bank-b.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c1_cfg_gpio(struct platform_device *dev)
+{
+	s3c_gpio_cfgpin(S3C64XX_GPB(2), S3C64XX_GPB2_I2C_SCL1);
+	s3c_gpio_cfgpin(S3C64XX_GPB(3), S3C64XX_GPB3_I2C_SDA1);
+	s3c_gpio_setpull(S3C64XX_GPB(2), S3C_GPIO_PULL_UP);
+	s3c_gpio_setpull(S3C64XX_GPB(3), S3C_GPIO_PULL_UP);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/setup-sdhci.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/setup-sdhci.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/setup-sdhci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/setup-sdhci.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,72 @@
+/* linux/arch/arm/mach-s3c64xx/setup-sdhci.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C6400/S3C6410 - Helper functions for settign up SDHCI device(s) (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include <plat/regs-sdhci.h>
+#include <plat/sdhci.h>
+
+/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
+
+char *s3c64xx_hsmmc_clksrcs[4] = {
+	[0] = "hsmmc",
+	[1] = "hsmmc",
+	[2] = "mmc_bus",
+	/* [3] = "48m", - note not successfully used yet */
+};
+
+void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
+				  void __iomem *r,
+				  struct mmc_ios *ios,
+				  struct mmc_card *card)
+{
+	u32 ctrl2, ctrl3;
+
+	ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
+	ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
+	ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
+		  S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
+		  S3C_SDHCI_CTRL2_ENFBCLKRX |
+		  S3C_SDHCI_CTRL2_DFCNT_NONE |
+		  S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
+
+	if (ios->clock < 25 * 1000000)
+		ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
+			 S3C_SDHCI_CTRL3_FCSEL2 |
+			 S3C_SDHCI_CTRL3_FCSEL1 |
+			 S3C_SDHCI_CTRL3_FCSEL0);
+	else
+		ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
+
+	printk(KERN_INFO "%s: CTRL 2=%08x, 3=%08x\n", __func__, ctrl2, ctrl3);
+	writel(ctrl2, r + S3C_SDHCI_CONTROL2);
+	writel(ctrl3, r + S3C_SDHCI_CONTROL3);
+}
+
+void s3c6410_setup_sdhci_cfg_card(struct platform_device *dev,
+				  void __iomem *r,
+				  struct mmc_ios *ios,
+				  struct mmc_card *card)
+{
+	writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
+
+	s3c6400_setup_sdhci_cfg_card(dev, r, ios, card);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,75 @@
+/* linux/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+
+void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+	unsigned int gpio;
+	unsigned int end;
+
+	end = S3C64XX_GPG(2 + width);
+
+	/* Set all the necessary GPG pins to special-function 0 */
+	for (gpio = S3C64XX_GPG(0); gpio < end; gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(2));
+}
+
+void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+	unsigned int gpio;
+	unsigned int end;
+
+	end = S3C64XX_GPH(2 + width);
+
+	/* Set all the necessary GPG pins to special-function 0 */
+	for (gpio = S3C64XX_GPH(0); gpio < end; gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(3));
+}
+
+void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+	unsigned int gpio;
+	unsigned int end;
+
+	end = S3C64XX_GPH(6 + width);
+
+	/* Set all the necessary GPH pins to special-function 1 */
+	for (gpio = S3C64XX_GPH(6); gpio < end; gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	/* Set all the necessary GPC pins to special-function 1 */
+	for (gpio = S3C64XX_GPC(4); gpio < S3C64XX_GPC(6); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/sleep.S linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/sleep.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s3c64xx/sleep.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s3c64xx/sleep.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,144 @@
+/* linux/arch/arm/plat-s3c64xx/sleep.S
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX CPU sleep 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/linkage.h>
+#include <asm/assembler.h>
+#include <mach/map.h>
+
+#undef S3C64XX_VA_GPIO
+#define S3C64XX_VA_GPIO (0x0)
+
+#include <mach/regs-gpio.h>
+#include <mach/gpio-bank-n.h>
+
+#define LL_UART (S3C_PA_UART + (0x400 * CONFIG_S3C_LOWLEVEL_UART_PORT))
+
+	.text
+
+	/* s3c_cpu_save
+	 *
+	 * Save enough processor state to allow the restart of the pm.c
+	 * code after resume.
+	 *
+	 * entry:
+	 *	r0 = pointer to the save block
+	*/
+
+ENTRY(s3c_cpu_save)
+	stmfd	sp!, { r4 - r12, lr }
+
+	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
+	mrc	p15, 0, r5, c3, c0, 0	@ Domain ID
+	mrc	p15, 0, r6, c2, c0, 0	@ Translation Table BASE0
+	mrc	p15, 0, r7, c2, c0, 1	@ Translation Table BASE1
+	mrc	p15, 0, r8, c2, c0, 2	@ Translation Table Control
+	mrc	p15, 0, r9, c1, c0, 0	@ Control register
+	mrc	p15, 0, r10, c1, c0, 1	@ Auxiliary control register
+	mrc	p15, 0, r11, c1, c0, 2	@ Co-processor access controls
+
+	stmia	r0, { r4 - r13 }	@ Save CP registers and SP
+
+	@@ save our state to ram
+	bl	s3c_pm_cb_flushcache
+
+	@@ call final suspend code
+	ldr	r0, =pm_cpu_sleep
+	ldr	pc, [r0]
+	
+	@@ return to the caller, after the MMU is turned on.
+	@@ restore the last bits of the stack and return.
+resume_with_mmu:
+	ldmfd	sp!, { r4 - r12, pc }	@ return, from sp from s3c_cpu_save
+
+	.data
+
+	/* the next bit is code, but it requires easy access to the
+	 * s3c_sleep_save_phys data before the MMU is switched on, so
+	 * we store the code that needs this variable in the .data where
+	 * the value can be written to (the .text segment is RO).
+	*/
+
+	.global	s3c_sleep_save_phys
+s3c_sleep_save_phys:
+	.word	0
+
+	/* Sleep magic, the word before the resume entry point so that the
+	 * bootloader can check for a resumeable image. */
+
+	.word	0x2bedf00d
+
+	/* s3c_cpu_reusme
+	 *
+	 * This is the entry point, stored by whatever method the bootloader
+	 * requires to get the kernel runnign again. This code expects to be
+	 * entered with no caches live and the MMU disabled. It will then
+	 * restore the MMU and other basic CP registers saved and restart
+	 * the kernel C code to finish the resume code.
+	*/
+
+ENTRY(s3c_cpu_resume)
+	msr	cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+	ldr	r2, =LL_UART		/* for debug */
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+	/* Initialise the GPIO state if we are debugging via the SMDK LEDs,
+	 * as the uboot version supplied resets these to inputs during the
+	 * resume checks.
+	*/
+
+	ldr	r3, =S3C64XX_PA_GPIO
+	ldr	r0, [ r3, #S3C64XX_GPNCON ]
+	bic	r0, r0, #(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) | \
+			  S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15))
+	orr	r0, r0, #(S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) | \
+			  S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15))
+	str	r0, [ r3, #S3C64XX_GPNCON ]
+
+	ldr	r0, [ r3, #S3C64XX_GPNDAT ]
+	bic	r0, r0, #0xf << 12			@ GPN12..15
+	orr	r0, r0, #1 << 15			@ GPN15
+	str	r0, [ r3, #S3C64XX_GPNDAT ]
+#endif
+
+	/* __v6_setup from arch/arm/mm/proc-v6.S, ensure that the caches
+	 * are thoroughly cleaned just in case the bootloader didn't do it
+	 * for us. */
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c14, 0		@ clean+invalidate D cache
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, r0, c7, c15, 0		@ clean+invalidate cache
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
+	@@mcr	p15, 0, r0, c8, c7, 0		@ invalidate I + D TLBs
+	@@mcr	p15, 0, r0, c7, c7, 0		@ Invalidate I + D caches
+
+	ldr	r0, s3c_sleep_save_phys
+	ldmia	r0, { r4 - r13 }
+
+	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
+	mcr	p15, 0, r5, c3, c0, 0	@ Domain ID
+	mcr	p15, 0, r6, c2, c0, 0	@ Translation Table BASE0
+	mcr	p15, 0, r7, c2, c0, 1	@ Translation Table BASE1
+	mcr	p15, 0, r8, c2, c0, 2	@ Translation Table Control
+	mcr	p15, 0, r10, c1, c0, 1	@ Auxiliary control register
+
+	mov	r0, #0			@ restore copro access controls
+	mcr	p15, 0, r11, c1, c0, 2	@ Co-processor access controls
+	mcr 	p15, 0, r0, c7, c5, 4
+
+	ldr	r2, =resume_with_mmu
+	mcr	p15, 0, r9, c1, c0, 0		/* turn mmu back on */
+	nop
+	mov	pc, r2				/* jump back */
+
+	.end
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/clock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,698 @@
+/* linux/arch/arm/mach-s5p6440/clock.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6440 - Clock 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/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/cpu-freq.h>
+#include <mach/regs-clock.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p-clock.h>
+#include <plat/pll.h>
+#include <plat/s5p6440.h>
+
+/* APLL Mux output clock */
+static struct clksrc_clk clk_mout_apll = {
+	.clk    = {
+		.name           = "mout_apll",
+		.id             = -1,
+	},
+	.sources        = &clk_src_apll,
+	.reg_src        = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
+};
+
+static int s5p6440_epll_enable(struct clk *clk, int enable)
+{
+	unsigned int ctrlbit = clk->ctrlbit;
+	unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
+
+	if (enable)
+		__raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
+	else
+		__raw_writel(epll_con, S5P_EPLL_CON);
+
+	return 0;
+}
+
+static unsigned long s5p6440_epll_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+
+static u32 epll_div[][5] = {
+	{ 36000000,	0,	48, 1, 4 },
+	{ 48000000,	0,	32, 1, 3 },
+	{ 60000000,	0,	40, 1, 3 },
+	{ 72000000,	0,	48, 1, 3 },
+	{ 84000000,	0,	28, 1, 2 },
+	{ 96000000,	0,	32, 1, 2 },
+	{ 32768000,	45264,	43, 1, 4 },
+	{ 45158000,	6903,	30, 1, 3 },
+	{ 49152000,	50332,	32, 1, 3 },
+	{ 67738000,	10398,	45, 1, 3 },
+	{ 73728000,	9961,	49, 1, 3 }
+};
+
+static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned int epll_con, epll_con_k;
+	unsigned int i;
+
+	if (clk->rate == rate)	/* Return if nothing changed */
+		return 0;
+
+	epll_con = __raw_readl(S5P_EPLL_CON);
+	epll_con_k = __raw_readl(S5P_EPLL_CON_K);
+
+	epll_con_k &= ~(PLL90XX_KDIV_MASK);
+	epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
+
+	for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+		 if (epll_div[i][0] == rate) {
+			epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
+			epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
+				    (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
+				    (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(epll_div)) {
+		printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
+		return -EINVAL;
+	}
+
+	__raw_writel(epll_con, S5P_EPLL_CON);
+	__raw_writel(epll_con_k, S5P_EPLL_CON_K);
+
+	clk->rate = rate;
+
+	return 0;
+}
+
+static struct clk_ops s5p6440_epll_ops = {
+	.get_rate = s5p6440_epll_get_rate,
+	.set_rate = s5p6440_epll_set_rate,
+};
+
+static struct clksrc_clk clk_mout_epll = {
+	.clk    = {
+		.name           = "mout_epll",
+		.id             = -1,
+	},
+	.sources        = &clk_src_epll,
+	.reg_src        = { .reg = S5P_CLK_SRC0, .shift = 2, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_mpll = {
+	.clk = {
+		.name           = "mout_mpll",
+		.id             = -1,
+	},
+	.sources        = &clk_src_mpll,
+	.reg_src        = { .reg = S5P_CLK_SRC0, .shift = 1, .size = 1 },
+};
+
+static struct clk clk_h_low = {
+	.name		= "hclk_low",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+	.ops		= &clk_ops_def_setrate,
+};
+
+static struct clk clk_p_low = {
+	.name		= "pclk_low",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+	.ops		= &clk_ops_def_setrate,
+};
+
+enum perf_level {
+	L0 = 532*1000,
+	L1 = 266*1000,
+	L2 = 133*1000,
+};
+
+static const u32 clock_table[][3] = {
+	/*{ARM_CLK, DIVarm, DIVhclk}*/
+	{L0 * 1000, (0 << ARM_DIV_RATIO_SHIFT), (3 << S5P_CLKDIV0_HCLK_SHIFT)},
+	{L1 * 1000, (1 << ARM_DIV_RATIO_SHIFT), (1 << S5P_CLKDIV0_HCLK_SHIFT)},
+	{L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P_CLKDIV0_HCLK_SHIFT)},
+};
+
+static unsigned long s5p6440_armclk_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	u32 clkdiv;
+
+	/* divisor mask starts at bit0, so no need to shift */
+	clkdiv = __raw_readl(ARM_CLK_DIV) & ARM_DIV_MASK;
+
+	return rate / (clkdiv + 1);
+}
+
+static unsigned long s5p6440_armclk_round_rate(struct clk *clk,
+						unsigned long rate)
+{
+	u32 iter;
+
+	for (iter = 1 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
+		if (rate > clock_table[iter][0])
+			return clock_table[iter-1][0];
+	}
+
+	return clock_table[ARRAY_SIZE(clock_table) - 1][0];
+}
+
+static int s5p6440_armclk_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 round_tmp;
+	u32 iter;
+	u32 clk_div0_tmp;
+	u32 cur_rate = clk->ops->get_rate(clk);
+	unsigned long flags;
+
+	round_tmp = clk->ops->round_rate(clk, rate);
+	if (round_tmp == cur_rate)
+		return 0;
+
+
+	for (iter = 0 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
+		if (round_tmp == clock_table[iter][0])
+			break;
+	}
+
+	if (iter >= ARRAY_SIZE(clock_table))
+		iter = ARRAY_SIZE(clock_table) - 1;
+
+	local_irq_save(flags);
+	if (cur_rate > round_tmp) {
+		/* Frequency Down */
+		clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
+		clk_div0_tmp |= clock_table[iter][1];
+		__raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+
+		clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
+				~(S5P_CLKDIV0_HCLK_MASK);
+		clk_div0_tmp |= clock_table[iter][2];
+		__raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+
+
+	} else {
+		/* Frequency Up */
+		clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
+				~(S5P_CLKDIV0_HCLK_MASK);
+		clk_div0_tmp |= clock_table[iter][2];
+		__raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+
+		clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
+		clk_div0_tmp |= clock_table[iter][1];
+		__raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+		}
+	local_irq_restore(flags);
+
+	clk->rate = clock_table[iter][0];
+
+	return 0;
+}
+
+static struct clk_ops s5p6440_clkarm_ops = {
+	.get_rate	= s5p6440_armclk_get_rate,
+	.set_rate	= s5p6440_armclk_set_rate,
+	.round_rate	= s5p6440_armclk_round_rate,
+};
+
+static unsigned long s5p6440_clk_doutmpll_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+
+	if (__raw_readl(S5P_CLK_DIV0) & S5P_CLKDIV0_MPLL_MASK)
+		rate /= 2;
+
+	return rate;
+}
+
+static struct clk clk_dout_mpll = {
+	.name		= "dout_mpll",
+	.id		= -1,
+	.parent		= &clk_mout_mpll.clk,
+	.ops            = &(struct clk_ops) {
+		.get_rate	= s5p6440_clk_doutmpll_get_rate,
+	},
+};
+
+int s5p6440_clk48m_ctrl(struct clk *clk, int enable)
+{
+	unsigned long flags;
+	u32 val;
+
+	/* can't rely on clock lock, this register has other usages */
+	local_irq_save(flags);
+
+	val = __raw_readl(S5P_OTHERS);
+	if (enable)
+		val |= S5P_OTHERS_USB_SIG_MASK;
+	else
+		val &= ~S5P_OTHERS_USB_SIG_MASK;
+
+	__raw_writel(val, S5P_OTHERS);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static int s5p6440_pclk_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLK_GATE_PCLK, clk, enable);
+}
+
+static int s5p6440_hclk0_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLK_GATE_HCLK0, clk, enable);
+}
+
+static int s5p6440_hclk1_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLK_GATE_HCLK1, clk, enable);
+}
+
+static int s5p6440_sclk_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLK_GATE_SCLK0, clk, enable);
+}
+
+static int s5p6440_mem_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLK_GATE_MEM0, clk, enable);
+}
+
+/*
+ * The following clocks will be disabled during clock initialization. It is
+ * recommended to keep the following clocks disabled until the driver requests
+ * for enabling the clock.
+ */
+static struct clk init_clocks_disable[] = {
+	{
+		.name		= "nand",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5p6440_mem_ctrl,
+		.ctrlbit	= S5P_CLKCON_MEM0_HCLK_NFCON,
+	}, {
+		.name		= "adc",
+		.id		= -1,
+		.parent		= &clk_p_low,
+		.enable		= s5p6440_pclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_PCLK_TSADC,
+	}, {
+		.name		= "i2c",
+		.id		= -1,
+		.parent		= &clk_p_low,
+		.enable		= s5p6440_pclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_PCLK_IIC0,
+	}, {
+		.name		= "i2s_v40",
+		.id		= 0,
+		.parent		= &clk_p_low,
+		.enable		= s5p6440_pclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_PCLK_IIS2,
+	}, {
+		.name		= "spi",
+		.id		= 0,
+		.parent		= &clk_p_low,
+		.enable		= s5p6440_pclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_PCLK_SPI0,
+	}, {
+		.name		= "spi",
+		.id		= 1,
+		.parent		= &clk_p_low,
+		.enable		= s5p6440_pclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_PCLK_SPI1,
+	}, {
+		.name		= "sclk_spi_48",
+		.id		= 0,
+		.parent		= &clk_48m,
+		.enable		= s5p6440_sclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_SCLK0_SPI0_48,
+	}, {
+		.name		= "sclk_spi_48",
+		.id		= 1,
+		.parent		= &clk_48m,
+		.enable		= s5p6440_sclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_SCLK0_SPI1_48,
+	}, {
+		.name		= "mmc_48m",
+		.id		= 0,
+		.parent		= &clk_48m,
+		.enable		= s5p6440_sclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_SCLK0_MMC0_48,
+	}, {
+		.name		= "mmc_48m",
+		.id		= 1,
+		.parent		= &clk_48m,
+		.enable		= s5p6440_sclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_SCLK0_MMC1_48,
+	}, {
+		.name		= "mmc_48m",
+		.id		= 2,
+		.parent		= &clk_48m,
+		.enable		= s5p6440_sclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_SCLK0_MMC2_48,
+	}, {
+		.name    	= "otg",
+		.id	   	= -1,
+		.parent  	= &clk_h_low,
+		.enable  	= s5p6440_hclk0_ctrl,
+		.ctrlbit 	= S5P_CLKCON_HCLK0_USB
+	}, {
+		.name    	= "post",
+		.id	   	= -1,
+		.parent  	= &clk_h_low,
+		.enable  	= s5p6440_hclk0_ctrl,
+		.ctrlbit 	= S5P_CLKCON_HCLK0_POST0
+	}, {
+		.name		= "lcd",
+		.id		= -1,
+		.parent		= &clk_h_low,
+		.enable		= s5p6440_hclk1_ctrl,
+		.ctrlbit	= S5P_CLKCON_HCLK1_DISPCON,
+	}, {
+		.name		= "hsmmc",
+		.id		= 0,
+		.parent		= &clk_h_low,
+		.enable		= s5p6440_hclk0_ctrl,
+		.ctrlbit	= S5P_CLKCON_HCLK0_HSMMC0,
+	}, {
+		.name		= "hsmmc",
+		.id		= 1,
+		.parent		= &clk_h_low,
+		.enable		= s5p6440_hclk0_ctrl,
+		.ctrlbit	= S5P_CLKCON_HCLK0_HSMMC1,
+	}, {
+		.name		= "hsmmc",
+		.id		= 2,
+		.parent		= &clk_h_low,
+		.enable		= s5p6440_hclk0_ctrl,
+		.ctrlbit	= S5P_CLKCON_HCLK0_HSMMC2,
+	}, {
+		.name		= "rtc",
+		.id		= -1,
+		.parent		= &clk_p_low,
+		.enable		= s5p6440_pclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_PCLK_RTC,
+	}, {
+		.name		= "watchdog",
+		.id		= -1,
+		.parent		= &clk_p_low,
+		.enable		= s5p6440_pclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_PCLK_WDT,
+	}, {
+		.name		= "timers",
+		.id		= -1,
+		.parent		= &clk_p_low,
+		.enable		= s5p6440_pclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_PCLK_PWM,
+	}
+};
+
+/*
+ * The following clocks will be enabled during clock initialization.
+ */
+static struct clk init_clocks[] = {
+	{
+		.name		= "gpio",
+		.id		= -1,
+		.parent		= &clk_p_low,
+		.enable		= s5p6440_pclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_PCLK_GPIO,
+	}, {
+		.name		= "uart",
+		.id		= 0,
+		.parent		= &clk_p_low,
+		.enable		= s5p6440_pclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_PCLK_UART0,
+	}, {
+		.name		= "uart",
+		.id		= 1,
+		.parent		= &clk_p_low,
+		.enable		= s5p6440_pclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_PCLK_UART1,
+	}, {
+		.name		= "uart",
+		.id		= 2,
+		.parent		= &clk_p_low,
+		.enable		= s5p6440_pclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_PCLK_UART2,
+	}, {
+		.name		= "uart",
+		.id		= 3,
+		.parent		= &clk_p_low,
+		.enable		= s5p6440_pclk_ctrl,
+		.ctrlbit	= S5P_CLKCON_PCLK_UART3,
+	}
+};
+
+static struct clk clk_iis_cd_v40 = {
+	.name		= "iis_cdclk_v40",
+	.id		= -1,
+};
+
+static struct clk clk_pcm_cd = {
+	.name		= "pcm_cdclk",
+	.id		= -1,
+};
+
+static struct clk *clkset_spi_mmc_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_fin_epll,
+};
+
+static struct clksrc_sources clkset_spi_mmc = {
+	.sources	= clkset_spi_mmc_list,
+	.nr_sources	= ARRAY_SIZE(clkset_spi_mmc_list),
+};
+
+static struct clk *clkset_uart_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll
+};
+
+static struct clksrc_sources clkset_uart = {
+	.sources	= clkset_uart_list,
+	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clksrc_clk clksrcs[] = {
+	{
+		.clk	= {
+			.name		= "mmc_bus",
+			.id		= 0,
+			.ctrlbit        = S5P_CLKCON_SCLK0_MMC0,
+			.enable		= s5p6440_sclk_ctrl,
+		},
+		.sources = &clkset_spi_mmc,
+		.reg_src = { .reg = S5P_CLK_SRC0, .shift = 18, .size = 2 },
+		.reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4 },
+	}, {
+		.clk	= {
+			.name		= "mmc_bus",
+			.id		= 1,
+			.ctrlbit        = S5P_CLKCON_SCLK0_MMC1,
+			.enable		= s5p6440_sclk_ctrl,
+		},
+		.sources = &clkset_spi_mmc,
+		.reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 2 },
+		.reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 4 },
+	}, {
+		.clk	= {
+			.name		= "mmc_bus",
+			.id		= 2,
+			.ctrlbit        = S5P_CLKCON_SCLK0_MMC2,
+			.enable		= s5p6440_sclk_ctrl,
+		},
+		.sources = &clkset_spi_mmc,
+		.reg_src = { .reg = S5P_CLK_SRC0, .shift = 22, .size = 2 },
+		.reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 4 },
+	}, {
+		.clk	= {
+			.name		= "uclk1",
+			.id		= -1,
+			.ctrlbit        = S5P_CLKCON_SCLK0_UART,
+			.enable		= s5p6440_sclk_ctrl,
+		},
+		.sources = &clkset_uart,
+		.reg_src = { .reg = S5P_CLK_SRC0, .shift = 13, .size = 1 },
+		.reg_div = { .reg = S5P_CLK_DIV2, .shift = 16, .size = 4 },
+	}, {
+		.clk	= {
+			.name		= "spi_epll",
+			.id		= 0,
+			.ctrlbit        = S5P_CLKCON_SCLK0_SPI0,
+			.enable		= s5p6440_sclk_ctrl,
+		},
+		.sources = &clkset_spi_mmc,
+		.reg_src = { .reg = S5P_CLK_SRC0, .shift = 14, .size = 2 },
+		.reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
+	}, {
+		.clk	= {
+			.name		= "spi_epll",
+			.id		= 1,
+			.ctrlbit        = S5P_CLKCON_SCLK0_SPI1,
+			.enable		= s5p6440_sclk_ctrl,
+		},
+		.sources = &clkset_spi_mmc,
+		.reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 2 },
+		.reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
+	}
+};
+
+/* Clock initialisation code */
+static struct clksrc_clk *init_parents[] = {
+	&clk_mout_apll,
+	&clk_mout_epll,
+	&clk_mout_mpll,
+};
+
+void __init_or_cpufreq s5p6440_setup_clocks(void)
+{
+	struct clk *xtal_clk;
+	unsigned long xtal;
+	unsigned long fclk;
+	unsigned long hclk;
+	unsigned long hclk_low;
+	unsigned long pclk;
+	unsigned long pclk_low;
+	unsigned long epll;
+	unsigned long apll;
+	unsigned long mpll;
+	unsigned int ptr;
+	u32 clkdiv0;
+	u32 clkdiv3;
+
+	/* Set S5P6440 functions for clk_fout_epll */
+	clk_fout_epll.enable = s5p6440_epll_enable;
+	clk_fout_epll.ops = &s5p6440_epll_ops;
+
+	/* Set S5P6440 functions for arm clock */
+	clk_arm.parent = &clk_mout_apll.clk;
+	clk_arm.ops = &s5p6440_clkarm_ops;
+	clk_48m.enable = s5p6440_clk48m_ctrl;
+
+	clkdiv0 = __raw_readl(S5P_CLK_DIV0);
+	clkdiv3 = __raw_readl(S5P_CLK_DIV3);
+
+	xtal_clk = clk_get(NULL, "ext_xtal");
+	BUG_ON(IS_ERR(xtal_clk));
+
+	xtal = clk_get_rate(xtal_clk);
+	clk_put(xtal_clk);
+
+	epll = s5p_get_pll90xx(xtal, __raw_readl(S5P_EPLL_CON),
+				__raw_readl(S5P_EPLL_CON_K));
+	mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
+	apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4502);
+
+	printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \
+			" E=%ld.%ldMHz\n",
+			print_mhz(apll), print_mhz(mpll), print_mhz(epll));
+
+	fclk = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_ARM);
+	hclk = fclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK);
+	pclk = hclk / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK);
+
+	if (__raw_readl(S5P_OTHERS) & S5P_OTHERS_HCLK_LOW_SEL_MPLL) {
+		/* Asynchronous mode */
+		hclk_low = mpll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW);
+	} else {
+		/* Synchronous mode */
+		hclk_low = apll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW);
+	}
+
+	pclk_low = hclk_low / GET_DIV(clkdiv3, S5P_CLKDIV3_PCLK_LOW);
+
+	printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \
+			" PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n",
+			print_mhz(hclk), print_mhz(hclk_low),
+			print_mhz(pclk), print_mhz(pclk_low));
+
+	clk_fout_mpll.rate = mpll;
+	clk_fout_epll.rate = epll;
+	clk_fout_apll.rate = apll;
+
+	clk_f.rate = fclk;
+	clk_h.rate = hclk;
+	clk_p.rate = pclk;
+	clk_h_low.rate = hclk_low;
+	clk_p_low.rate = pclk_low;
+
+	for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
+		s3c_set_clksrc(init_parents[ptr], true);
+
+	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+		s3c_set_clksrc(&clksrcs[ptr], true);
+}
+
+static struct clk *clks[] __initdata = {
+	&clk_ext,
+	&clk_mout_epll.clk,
+	&clk_mout_mpll.clk,
+	&clk_dout_mpll,
+	&clk_iis_cd_v40,
+	&clk_pcm_cd,
+	&clk_p_low,
+	&clk_h_low,
+};
+
+void __init s5p6440_register_clocks(void)
+{
+	struct clk *clkp;
+	int ret;
+	int ptr;
+
+	ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+	if (ret > 0)
+		printk(KERN_ERR "Failed to register %u clocks\n", ret);
+
+	s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+	s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+	clkp = init_clocks_disable;
+	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+		(clkp->enable)(clkp, 0);
+	}
+
+	s3c_pwmclk_init();
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/cpu.c linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/cpu.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/cpu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/cpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,114 @@
+/* linux/arch/arm/mach-s5p6440/cpu.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/proc-fns.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <asm/irq.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/s5p6440.h>
+
+static void s5p6440_idle(void)
+{
+	unsigned long val;
+
+	if (!need_resched()) {
+		val = __raw_readl(S5P_PWR_CFG);
+		val &= ~(0x3<<5);
+		val |= (0x1<<5);
+		__raw_writel(val, S5P_PWR_CFG);
+
+		cpu_do_idle();
+	}
+	local_irq_enable();
+}
+
+/* s5p6440_map_io
+ *
+ * register the standard cpu IO areas
+*/
+
+void __init s5p6440_map_io(void)
+{
+	/* initialize any device information early */
+}
+
+void __init s5p6440_init_clocks(int xtal)
+{
+	printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+	s3c24xx_register_baseclocks(xtal);
+	s5p_register_clocks(xtal);
+	s5p6440_register_clocks();
+	s5p6440_setup_clocks();
+}
+
+void __init s5p6440_init_irq(void)
+{
+	/* S5P6440 supports only 2 VIC */
+	u32 vic[2];
+
+	/*
+	 * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)]
+	 * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22]
+	 */
+	vic[0] = 0xff800ae7;
+	vic[1] = 0xffbf23e5;
+
+	s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+static struct sysdev_class s5p6440_sysclass = {
+	.name	= "s5p6440-core",
+};
+
+static struct sys_device s5p6440_sysdev = {
+	.cls	= &s5p6440_sysclass,
+};
+
+static int __init s5p6440_core_init(void)
+{
+	return sysdev_class_register(&s5p6440_sysclass);
+}
+
+core_initcall(s5p6440_core_init);
+
+int __init s5p6440_init(void)
+{
+	printk(KERN_INFO "S5P6440: Initializing architecture\n");
+
+	/* set idle function */
+	pm_idle = s5p6440_idle;
+
+	return sysdev_register(&s5p6440_sysdev);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/gpio.c linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/gpio.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,322 @@
+/* arch/arm/mach-s5p6440/gpio.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * 		http://www.samsung.com/
+ *
+ * S5P6440 - GPIOlib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/map.h>
+#include <mach/gpio.h>
+#include <mach/regs-gpio.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+/* GPIO bank summary:
+*
+* Bank	GPIOs	Style	SlpCon	ExtInt Group
+* A	6	4Bit	Yes	1
+* B	7	4Bit	Yes	1
+* C	8	4Bit	Yes	2
+* F	2	2Bit	Yes	4 [1]
+* G	7	4Bit	Yes	5
+* H	10	4Bit[2]	Yes	6
+* I	16	2Bit	Yes	None
+* J	12	2Bit	Yes	None
+* N	16	2Bit	No	IRQ_EINT
+* P	8	2Bit	Yes	8
+* R	15	4Bit[2]	Yes	8
+*
+* [1] BANKF pins 14,15 do not form part of the external interrupt sources
+* [2] BANK has two control registers, GPxCON0 and GPxCON1
+*/
+
+static int s5p6440_gpiolib_rbank_4bit2_input(struct gpio_chip *chip,
+					     unsigned int offset)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	void __iomem *regcon = base;
+	unsigned long con;
+
+	switch (offset) {
+	case 6:
+		offset += 1;
+	case 0:
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+	case 5:
+		regcon -= 4;
+		break;
+	default:
+		offset -= 7;
+		break;
+	}
+
+	con = __raw_readl(regcon);
+	con &= ~(0xf << con_4bit_shift(offset));
+	__raw_writel(con, regcon);
+
+	return 0;
+}
+
+static int s5p6440_gpiolib_rbank_4bit2_output(struct gpio_chip *chip,
+					      unsigned int offset, int value)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	void __iomem *regcon = base;
+	unsigned long con;
+	unsigned long dat;
+	unsigned con_offset  = offset;
+
+	switch (con_offset) {
+	case 6:
+		con_offset += 1;
+	case 0:
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+	case 5:
+		regcon -= 4;
+		break;
+	default:
+		con_offset -= 7;
+		break;
+	}
+
+	con = __raw_readl(regcon);
+	con &= ~(0xf << con_4bit_shift(con_offset));
+	con |= 0x1 << con_4bit_shift(con_offset);
+
+	dat = __raw_readl(base + GPIODAT_OFF);
+	if (value)
+		dat |= 1 << offset;
+	else
+		dat &= ~(1 << offset);
+
+	__raw_writel(con, regcon);
+	__raw_writel(dat, base + GPIODAT_OFF);
+
+	return 0;
+}
+
+int s5p6440_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip,
+				   unsigned int off, unsigned int cfg)
+{
+	void __iomem *reg = chip->base;
+	unsigned int shift;
+	u32 con;
+
+	switch (off) {
+	case 0:
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+	case 5:
+		shift = (off & 7) * 4;
+		reg -= 4;
+		break;
+	case 6:
+		shift = ((off + 1) & 7) * 4;
+		reg -= 4;
+	default:
+		shift = ((off + 1) & 7) * 4;
+		break;
+	}
+
+	if (s3c_gpio_is_cfg_special(cfg)) {
+		cfg &= 0xf;
+		cfg <<= shift;
+	}
+
+	con = __raw_readl(reg);
+	con &= ~(0xf << shift);
+	con |= cfg;
+	__raw_writel(con, reg);
+
+	return 0;
+}
+
+static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = {
+	{
+		.cfg_eint	= 0,
+	}, {
+		.cfg_eint	= 7,
+	}, {
+		.cfg_eint	= 3,
+		.set_config	= s5p6440_gpio_setcfg_4bit_rbank,
+	}, {
+		.cfg_eint	= 0,
+		.set_config	= s3c_gpio_setcfg_s3c24xx,
+	}, {
+		.cfg_eint	= 2,
+		.set_config	= s3c_gpio_setcfg_s3c24xx,
+	}, {
+		.cfg_eint	= 3,
+		.set_config	= s3c_gpio_setcfg_s3c24xx,
+	},
+};
+
+static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
+	{
+		.base	= S5P6440_GPA_BASE,
+		.config	= &s5p6440_gpio_cfgs[1],
+		.chip	= {
+			.base	= S5P6440_GPA(0),
+			.ngpio	= S5P6440_GPIO_A_NR,
+			.label	= "GPA",
+		},
+	}, {
+		.base	= S5P6440_GPB_BASE,
+		.config	= &s5p6440_gpio_cfgs[1],
+		.chip	= {
+			.base	= S5P6440_GPB(0),
+			.ngpio	= S5P6440_GPIO_B_NR,
+			.label	= "GPB",
+		},
+	}, {
+		.base	= S5P6440_GPC_BASE,
+		.config	= &s5p6440_gpio_cfgs[1],
+		.chip	= {
+			.base	= S5P6440_GPC(0),
+			.ngpio	= S5P6440_GPIO_C_NR,
+			.label	= "GPC",
+		},
+	}, {
+		.base	= S5P6440_GPG_BASE,
+		.config	= &s5p6440_gpio_cfgs[1],
+		.chip	= {
+			.base	= S5P6440_GPG(0),
+			.ngpio	= S5P6440_GPIO_G_NR,
+			.label	= "GPG",
+		},
+	},
+};
+
+static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = {
+	{
+		.base	= S5P6440_GPH_BASE + 0x4,
+		.config	= &s5p6440_gpio_cfgs[1],
+		.chip	= {
+			.base	= S5P6440_GPH(0),
+			.ngpio	= S5P6440_GPIO_H_NR,
+			.label	= "GPH",
+		},
+	},
+};
+
+static struct s3c_gpio_chip gpio_rbank_4bit2[] = {
+	{
+		.base	= S5P6440_GPR_BASE + 0x4,
+		.config	= &s5p6440_gpio_cfgs[2],
+		.chip	= {
+			.base	= S5P6440_GPR(0),
+			.ngpio	= S5P6440_GPIO_R_NR,
+			.label	= "GPR",
+		},
+	},
+};
+
+static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
+	{
+		.base	= S5P6440_GPF_BASE,
+		.config	= &s5p6440_gpio_cfgs[5],
+		.chip	= {
+			.base	= S5P6440_GPF(0),
+			.ngpio	= S5P6440_GPIO_F_NR,
+			.label	= "GPF",
+		},
+	}, {
+		.base	= S5P6440_GPI_BASE,
+		.config	= &s5p6440_gpio_cfgs[3],
+		.chip	= {
+			.base	= S5P6440_GPI(0),
+			.ngpio	= S5P6440_GPIO_I_NR,
+			.label	= "GPI",
+		},
+	}, {
+		.base	= S5P6440_GPJ_BASE,
+		.config	= &s5p6440_gpio_cfgs[3],
+		.chip	= {
+			.base	= S5P6440_GPJ(0),
+			.ngpio	= S5P6440_GPIO_J_NR,
+			.label	= "GPJ",
+		},
+	}, {
+		.base	= S5P6440_GPN_BASE,
+		.config	= &s5p6440_gpio_cfgs[4],
+		.chip	= {
+			.base	= S5P6440_GPN(0),
+			.ngpio	= S5P6440_GPIO_N_NR,
+			.label	= "GPN",
+		},
+	}, {
+		.base	= S5P6440_GPP_BASE,
+		.config	= &s5p6440_gpio_cfgs[5],
+		.chip	= {
+			.base	= S5P6440_GPP(0),
+			.ngpio	= S5P6440_GPIO_P_NR,
+			.label	= "GPP",
+		},
+	},
+};
+
+void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
+{
+	for (; nr_chips > 0; nr_chips--, chipcfg++) {
+		if (!chipcfg->set_config)
+			chipcfg->set_config	= s3c_gpio_setcfg_s3c64xx_4bit;
+		if (!chipcfg->set_pull)
+			chipcfg->set_pull	= s3c_gpio_setpull_updown;
+		if (!chipcfg->get_pull)
+			chipcfg->get_pull	= s3c_gpio_getpull_updown;
+	}
+}
+
+static void __init s5p6440_gpio_add_rbank_4bit2(struct s3c_gpio_chip *chip,
+						int nr_chips)
+{
+	for (; nr_chips > 0; nr_chips--, chip++) {
+		chip->chip.direction_input = s5p6440_gpiolib_rbank_4bit2_input;
+		chip->chip.direction_output =
+					s5p6440_gpiolib_rbank_4bit2_output;
+		s3c_gpiolib_add(chip);
+	}
+}
+
+static int __init s5p6440_gpiolib_init(void)
+{
+	struct s3c_gpio_chip *chips = s5p6440_gpio_2bit;
+	int nr_chips = ARRAY_SIZE(s5p6440_gpio_2bit);
+
+	s5p6440_gpiolib_set_cfg(s5p6440_gpio_cfgs,
+				ARRAY_SIZE(s5p6440_gpio_cfgs));
+
+	for (; nr_chips > 0; nr_chips--, chips++)
+		s3c_gpiolib_add(chips);
+
+	samsung_gpiolib_add_4bit_chips(s5p6440_gpio_4bit,
+				ARRAY_SIZE(s5p6440_gpio_4bit));
+
+	samsung_gpiolib_add_4bit2_chips(s5p6440_gpio_4bit2,
+				ARRAY_SIZE(s5p6440_gpio_4bit2));
+
+	s5p6440_gpio_add_rbank_4bit2(gpio_rbank_4bit2,
+				ARRAY_SIZE(gpio_rbank_4bit2));
+
+	return 0;
+}
+arch_initcall(s5p6440_gpiolib_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,37 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/debug-macro.S
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <mach/map.h>
+#include <plat/regs-serial.h>
+
+	/* note, for the boot process to work we have to keep the UART
+	 * virtual address aligned to an 1MiB boundary for the L1
+	 * mapping the head code makes. We keep the UART virtual address
+	 * aligned and add in the offset when we load the value here.
+	 */
+
+	.macro addruart, rx, rtmp
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1
+		ldreq	\rx, = S3C_PA_UART
+		ldrne	\rx, = S3C_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+		add	\rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
+#endif
+	.endm
+
+/* include the reset of the code which will do the work, we're only
+ * compiling for a single cpu processor type so the default of s3c2440
+ * will be fine with us.
+ */
+
+#include <plat/debug-macro.S>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/entry-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/entry-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/entry-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,16 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/entry-macro.S
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Low-level IRQ helper macros for the Samsung S5P6440
+ *
+ * This program is free software; you can 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/map.h>
+#include <plat/irqs.h>
+
+#include <asm/entry-macro-vic2.S>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/gpio.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/gpio.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/gpio.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,80 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/gpio.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6440 - GPIO lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H __FILE__
+
+#define gpio_get_value	__gpio_get_value
+#define gpio_set_value	__gpio_set_value
+#define gpio_cansleep	__gpio_cansleep
+#define gpio_to_irq	__gpio_to_irq
+
+/* GPIO bank sizes */
+#define S5P6440_GPIO_A_NR	(6)
+#define S5P6440_GPIO_B_NR	(7)
+#define S5P6440_GPIO_C_NR	(8)
+#define S5P6440_GPIO_F_NR	(2)
+#define S5P6440_GPIO_G_NR	(7)
+#define S5P6440_GPIO_H_NR	(10)
+#define S5P6440_GPIO_I_NR	(16)
+#define S5P6440_GPIO_J_NR	(12)
+#define S5P6440_GPIO_N_NR	(16)
+#define S5P6440_GPIO_P_NR	(8)
+#define S5P6440_GPIO_R_NR	(15)
+
+/* GPIO bank numbers */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+#define S5P6440_GPIO_NEXT(__gpio) \
+	((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s5p_gpio_number {
+	S5P6440_GPIO_A_START = 0,
+	S5P6440_GPIO_B_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_A),
+	S5P6440_GPIO_C_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_B),
+	S5P6440_GPIO_F_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_C),
+	S5P6440_GPIO_G_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_F),
+	S5P6440_GPIO_H_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_G),
+	S5P6440_GPIO_I_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_H),
+	S5P6440_GPIO_J_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_I),
+	S5P6440_GPIO_N_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_J),
+	S5P6440_GPIO_P_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_N),
+	S5P6440_GPIO_R_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_P),
+};
+
+/* S5P6440 GPIO number definitions. */
+#define S5P6440_GPA(_nr)	(S5P6440_GPIO_A_START + (_nr))
+#define S5P6440_GPB(_nr)	(S5P6440_GPIO_B_START + (_nr))
+#define S5P6440_GPC(_nr)	(S5P6440_GPIO_C_START + (_nr))
+#define S5P6440_GPF(_nr)	(S5P6440_GPIO_F_START + (_nr))
+#define S5P6440_GPG(_nr)	(S5P6440_GPIO_G_START + (_nr))
+#define S5P6440_GPH(_nr)	(S5P6440_GPIO_H_START + (_nr))
+#define S5P6440_GPI(_nr)	(S5P6440_GPIO_I_START + (_nr))
+#define S5P6440_GPJ(_nr)	(S5P6440_GPIO_J_START + (_nr))
+#define S5P6440_GPN(_nr)	(S5P6440_GPIO_N_START + (_nr))
+#define S5P6440_GPP(_nr)	(S5P6440_GPIO_P_START + (_nr))
+#define S5P6440_GPR(_nr)	(S5P6440_GPIO_R_START + (_nr))
+
+/* the end of the S5P6440 specific gpios */
+#define S5P6440_GPIO_END	(S5P6440_GPR(S5P6440_GPIO_R_NR) + 1)
+#define S3C_GPIO_END		S5P6440_GPIO_END
+
+/* define the number of gpios we need to the one after the GPR() range */
+#define ARCH_NR_GPIOS		(S5P6440_GPR(S5P6440_GPIO_R_NR) +	\
+				 CONFIG_SAMSUNG_GPIO_EXTRA + 1)
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/hardware.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/hardware.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/hardware.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,18 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/hardware.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6440 - Hardware support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H __FILE__
+
+/* currently nothing here, placeholder */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/io.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/io.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/io.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s5p6440/include/mach/io.h
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S3C64XX based
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a)		__typesafe_io(a)
+#define __mem_pci(a)	(a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/irqs.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/irqs.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/irqs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,111 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/irqs.h
+ *
+ * Copyright 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6440 - IRQ definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_S5P_IRQS_H
+#define __ASM_ARCH_S5P_IRQS_H __FILE__
+
+#include <plat/irqs.h>
+
+/* VIC0 */
+
+#define IRQ_EINT0_3		S5P_IRQ_VIC0(0)
+#define IRQ_EINT4_11		S5P_IRQ_VIC0(1)
+#define IRQ_RTC_TIC		S5P_IRQ_VIC0(2)
+#define IRQ_IIC1		S5P_IRQ_VIC0(5)
+#define IRQ_I2SV40		S5P_IRQ_VIC0(6)
+#define IRQ_GPS			S5P_IRQ_VIC0(7)
+#define IRQ_POST0		S5P_IRQ_VIC0(9)
+#define IRQ_2D			S5P_IRQ_VIC0(11)
+#define IRQ_TIMER0_VIC		S5P_IRQ_VIC0(23)
+#define IRQ_TIMER1_VIC		S5P_IRQ_VIC0(24)
+#define IRQ_TIMER2_VIC		S5P_IRQ_VIC0(25)
+#define IRQ_WDT			S5P_IRQ_VIC0(26)
+#define IRQ_TIMER3_VIC		S5P_IRQ_VIC0(27)
+#define IRQ_TIMER4_VIC		S5P_IRQ_VIC0(28)
+#define IRQ_DISPCON0		S5P_IRQ_VIC0(29)
+#define IRQ_DISPCON1		S5P_IRQ_VIC0(30)
+#define IRQ_DISPCON2		S5P_IRQ_VIC0(31)
+
+/* VIC1 */
+
+#define IRQ_EINT12_15		S5P_IRQ_VIC1(0)
+#define IRQ_PCM0		S5P_IRQ_VIC1(2)
+#define IRQ_UART0		S5P_IRQ_VIC1(5)
+#define IRQ_UART1		S5P_IRQ_VIC1(6)
+#define IRQ_UART2		S5P_IRQ_VIC1(7)
+#define IRQ_UART3		S5P_IRQ_VIC1(8)
+#define IRQ_DMA0		S5P_IRQ_VIC1(9)
+#define IRQ_NFC			S5P_IRQ_VIC1(13)
+#define IRQ_SPI0		S5P_IRQ_VIC1(16)
+#define IRQ_SPI1		S5P_IRQ_VIC1(17)
+#define IRQ_IIC			S5P_IRQ_VIC1(18)
+#define IRQ_DISPCON3		S5P_IRQ_VIC1(19)
+#define IRQ_FIMGVG		S5P_IRQ_VIC1(20)
+#define IRQ_EINT_GROUPS		S5P_IRQ_VIC1(21)
+#define IRQ_PMUIRQ		S5P_IRQ_VIC1(23)
+#define IRQ_HSMMC0		S5P_IRQ_VIC1(24)
+#define IRQ_HSMMC1		S5P_IRQ_VIC1(25)
+#define IRQ_HSMMC2		IRQ_SPI1	/* shared with SPI1 */
+#define IRQ_OTG			S5P_IRQ_VIC1(26)
+#define IRQ_DSI			S5P_IRQ_VIC1(27)
+#define IRQ_RTC_ALARM		S5P_IRQ_VIC1(28)
+#define IRQ_TSI			S5P_IRQ_VIC1(29)
+#define IRQ_PENDN		S5P_IRQ_VIC1(30)
+#define IRQ_TC			IRQ_PENDN
+#define IRQ_ADC			S5P_IRQ_VIC1(31)
+
+/*
+ * Since the IRQ_EINT(x) are a linear mapping on s5p6440 we just defined
+ * them as an IRQ_EINT(x) macro from S5P_IRQ_EINT_BASE which we place
+ * after the pair of VICs.
+ */
+
+#define S5P_IRQ_EINT_BASE	(S5P_IRQ_VIC1(31) + 6)
+
+#define S5P_EINT(x)		((x) + S5P_IRQ_EINT_BASE)
+#define IRQ_EINT(x)		S5P_EINT(x)
+
+/*
+ * Next the external interrupt groups. These are similar to the IRQ_EINT(x)
+ * that they are sourced from the GPIO pins but with a different scheme for
+ * priority and source indication.
+ *
+ * The IRQ_EINT(x) can be thought of as 'group 0' of the available GPIO
+ * interrupts, but for historical reasons they are kept apart from these
+ * next interrupts.
+ *
+ * Use IRQ_EINT_GROUP(group, offset) to get the number for use in the
+ * machine specific support files.
+ */
+
+/* Actually, #6 and #7 are missing in the EINT_GROUP1 */
+#define IRQ_EINT_GROUP1_NR	(15)
+#define IRQ_EINT_GROUP2_NR	(8)
+#define IRQ_EINT_GROUP5_NR	(7)
+#define IRQ_EINT_GROUP6_NR	(10)
+/* Actually, #0, #1 and #2 are missing in the EINT_GROUP8 */
+#define IRQ_EINT_GROUP8_NR	(11)
+
+#define IRQ_EINT_GROUP_BASE	S5P_EINT(16)
+#define IRQ_EINT_GROUP1_BASE	(IRQ_EINT_GROUP_BASE + 0)
+#define IRQ_EINT_GROUP2_BASE	(IRQ_EINT_GROUP1_BASE + IRQ_EINT_GROUP1_NR)
+#define IRQ_EINT_GROUP5_BASE	(IRQ_EINT_GROUP2_BASE + IRQ_EINT_GROUP2_NR)
+#define IRQ_EINT_GROUP6_BASE	(IRQ_EINT_GROUP5_BASE + IRQ_EINT_GROUP5_NR)
+#define IRQ_EINT_GROUP8_BASE	(IRQ_EINT_GROUP6_BASE + IRQ_EINT_GROUP6_NR)
+
+#define IRQ_EINT_GROUP(grp, x)	(IRQ_EINT_GROUP##grp##_BASE + (x))
+
+/* Set the default NR_IRQS */
+
+#define NR_IRQS			(IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1)
+
+#endif /* __ASM_ARCH_S5P_IRQS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/map.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/map.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/map.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/map.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,68 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/map.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6440 - Memory 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_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+#define S5P6440_PA_CHIPID	(0xE0000000)
+#define S5P_PA_CHIPID		S5P6440_PA_CHIPID
+
+#define S5P6440_PA_SYSCON	(0xE0100000)
+#define S5P6440_PA_CLK		(S5P6440_PA_SYSCON + 0x0)
+#define S5P_PA_SYSCON		S5P6440_PA_SYSCON
+
+#define S5P6440_PA_GPIO		(0xE0308000)
+#define S5P_PA_GPIO		S5P6440_PA_GPIO
+
+#define S5P6440_PA_VIC0		(0xE4000000)
+#define S5P_PA_VIC0		S5P6440_PA_VIC0
+
+#define S5P6440_PA_VIC1		(0xE4100000)
+#define S5P_PA_VIC1		S5P6440_PA_VIC1
+
+#define S5P6440_PA_TIMER	(0xEA000000)
+#define S5P_PA_TIMER		S5P6440_PA_TIMER
+
+#define S5P6440_PA_RTC		(0xEA100000)
+#define S5P_PA_RTC		S5P6440_PA_RTC
+
+#define S5P6440_PA_WDT		(0xEA200000)
+#define S5P_PA_WDT		S5P6440_PA_WDT
+
+#define S5P6440_PA_UART		(0xEC000000)
+
+#define S5P_PA_UART0		(S5P6440_PA_UART + 0x0)
+#define S5P_PA_UART1		(S5P6440_PA_UART + 0x400)
+#define S5P_PA_UART2		(S5P6440_PA_UART + 0x800)
+#define S5P_PA_UART3		(S5P6440_PA_UART + 0xC00)
+
+#define S5P_SZ_UART		SZ_256
+
+#define S5P6440_PA_IIC0		(0xEC104000)
+
+#define S5P6440_PA_HSOTG	(0xED100000)
+
+#define S5P6440_PA_HSMMC0	(0xED800000)
+#define S5P6440_PA_HSMMC1	(0xED900000)
+#define S5P6440_PA_HSMMC2	(0xEDA00000)
+
+#define S5P6440_PA_SDRAM	(0x20000000)
+#define S5P_PA_SDRAM		S5P6440_PA_SDRAM
+
+/* compatibiltiy defines. */
+#define S3C_PA_UART		S5P6440_PA_UART
+#define S3C_PA_IIC		S5P6440_PA_IIC0
+
+#endif /* __ASM_ARCH_MAP_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/memory.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/memory.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/memory.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/memory.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6440 - Memory definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET     	UL(0x20000000)
+#define CONSISTENT_DMA_SIZE	SZ_8M
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/pwm-clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/pwm-clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/pwm-clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/pwm-clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,62 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/pwm-clock.h
+ *
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * Copyright 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6440 - pwm clock and timer 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.
+*/
+
+/**
+ * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
+ * @cfg: The timer TCFG1 register bits shifted down to 0.
+ *
+ * Return true if the given configuration from TCFG1 is a TCLK instead
+ * any of the TDIV clocks.
+ */
+static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
+{
+	return tcfg == S3C2410_TCFG1_MUX_TCLK;
+}
+
+/**
+ * tcfg_to_divisor() - convert tcfg1 setting to a divisor
+ * @tcfg1: The tcfg1 setting, shifted down.
+ *
+ * Get the divisor value for the given tcfg1 setting. We assume the
+ * caller has already checked to see if this is not a TCLK source.
+ */
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+	return 1 << (1 + tcfg1);
+}
+
+/**
+ * pwm_tdiv_has_div1() - does the tdiv setting have a /1
+ *
+ * Return true if we have a /1 in the tdiv setting.
+ */
+static inline unsigned int pwm_tdiv_has_div1(void)
+{
+	return 0;
+}
+
+/**
+ * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
+ * @div: The divisor to calculate the bit information for.
+ *
+ * Turn a divisor into the necessary bit field for TCFG1.
+ */
+static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
+{
+	return ilog2(div) - 1;
+}
+
+#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/regs-clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/regs-clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/regs-clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/regs-clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,130 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6440 - Clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_CLKREG(x)		(S3C_VA_SYS + (x))
+
+#define S5P_APLL_LOCK		S5P_CLKREG(0x00)
+#define S5P_MPLL_LOCK		S5P_CLKREG(0x04)
+#define S5P_EPLL_LOCK		S5P_CLKREG(0x08)
+#define S5P_APLL_CON		S5P_CLKREG(0x0C)
+#define S5P_MPLL_CON		S5P_CLKREG(0x10)
+#define S5P_EPLL_CON		S5P_CLKREG(0x14)
+#define S5P_EPLL_CON_K		S5P_CLKREG(0x18)
+#define S5P_CLK_SRC0		S5P_CLKREG(0x1C)
+#define S5P_CLK_DIV0		S5P_CLKREG(0x20)
+#define S5P_CLK_DIV1		S5P_CLKREG(0x24)
+#define S5P_CLK_DIV2		S5P_CLKREG(0x28)
+#define S5P_CLK_OUT		S5P_CLKREG(0x2C)
+#define S5P_CLK_GATE_HCLK0	S5P_CLKREG(0x30)
+#define S5P_CLK_GATE_PCLK	S5P_CLKREG(0x34)
+#define S5P_CLK_GATE_SCLK0	S5P_CLKREG(0x38)
+#define S5P_CLK_GATE_MEM0	S5P_CLKREG(0x3C)
+#define S5P_CLK_DIV3		S5P_CLKREG(0x40)
+#define S5P_CLK_GATE_HCLK1	S5P_CLKREG(0x44)
+#define S5P_CLK_GATE_SCLK1	S5P_CLKREG(0x48)
+#define S5P_AHB_CON0           	S5P_CLKREG(0x100)
+#define S5P_CLK_SRC1           	S5P_CLKREG(0x10C)
+#define S5P_SWRESET		S5P_CLKREG(0x114)
+#define S5P_SYS_ID		S5P_CLKREG(0x118)
+#define S5P_SYS_OTHERS		S5P_CLKREG(0x11C)
+#define S5P_MEM_CFG_STAT	S5P_CLKREG(0x12C)
+#define S5P_PWR_CFG		S5P_CLKREG(0x804)
+#define S5P_EINT_WAKEUP_MASK	S5P_CLKREG(0x808)
+#define S5P_NORMAL_CFG		S5P_CLKREG(0x810)
+#define S5P_STOP_CFG		S5P_CLKREG(0x814)
+#define S5P_SLEEP_CFG		S5P_CLKREG(0x818)
+#define S5P_OSC_FREQ		S5P_CLKREG(0x820)
+#define S5P_OSC_STABLE		S5P_CLKREG(0x824)
+#define S5P_PWR_STABLE		S5P_CLKREG(0x828)
+#define S5P_MTC_STABLE		S5P_CLKREG(0x830)
+#define S5P_OTHERS		S5P_CLKREG(0x900)
+#define S5P_RST_STAT		S5P_CLKREG(0x904)
+#define S5P_WAKEUP_STAT		S5P_CLKREG(0x908)
+#define S5P_SLPEN		S5P_CLKREG(0x930)
+#define S5P_INFORM0		S5P_CLKREG(0xA00)
+#define S5P_INFORM1		S5P_CLKREG(0xA04)
+#define S5P_INFORM2		S5P_CLKREG(0xA08)
+#define S5P_INFORM3		S5P_CLKREG(0xA0C)
+
+/* CLKDIV0 */
+#define S5P_CLKDIV0_PCLK_MASK		(0xf << 12)
+#define S5P_CLKDIV0_PCLK_SHIFT		(12)
+#define S5P_CLKDIV0_HCLK_MASK		(0xf << 8)
+#define S5P_CLKDIV0_HCLK_SHIFT		(8)
+#define S5P_CLKDIV0_MPLL_MASK		(0x1 << 4)
+#define S5P_CLKDIV0_ARM_MASK		(0xf << 0)
+#define S5P_CLKDIV0_ARM_SHIFT		(0)
+
+/* CLKDIV3 */
+#define S5P_CLKDIV3_PCLK_LOW_MASK	(0xf << 12)
+#define S5P_CLKDIV3_PCLK_LOW_SHIFT	(12)
+#define S5P_CLKDIV3_HCLK_LOW_MASK	(0xf << 8)
+#define S5P_CLKDIV3_HCLK_LOW_SHIFT	(8)
+
+/* HCLK0 GATE Registers */
+#define S5P_CLKCON_HCLK0_USB		(1<<20)
+#define S5P_CLKCON_HCLK0_HSMMC2		(1<<19)
+#define S5P_CLKCON_HCLK0_HSMMC1		(1<<18)
+#define S5P_CLKCON_HCLK0_HSMMC0		(1<<17)
+#define S5P_CLKCON_HCLK0_POST0		(1<<5)
+
+/* HCLK1 GATE Registers */
+#define S5P_CLKCON_HCLK1_DISPCON	(1<<1)
+
+/* PCLK GATE Registers */
+#define S5P_CLKCON_PCLK_IIS2		(1<<26)
+#define S5P_CLKCON_PCLK_SPI1		(1<<22)
+#define S5P_CLKCON_PCLK_SPI0		(1<<21)
+#define S5P_CLKCON_PCLK_GPIO		(1<<18)
+#define S5P_CLKCON_PCLK_IIC0		(1<<17)
+#define S5P_CLKCON_PCLK_TSADC		(1<<12)
+#define S5P_CLKCON_PCLK_PWM		(1<<7)
+#define S5P_CLKCON_PCLK_RTC		(1<<6)
+#define S5P_CLKCON_PCLK_WDT		(1<<5)
+#define S5P_CLKCON_PCLK_UART3		(1<<4)
+#define S5P_CLKCON_PCLK_UART2		(1<<3)
+#define S5P_CLKCON_PCLK_UART1		(1<<2)
+#define S5P_CLKCON_PCLK_UART0		(1<<1)
+
+/* SCLK0 GATE Registers */
+#define S5P_CLKCON_SCLK0_MMC2_48	(1<<29)
+#define S5P_CLKCON_SCLK0_MMC1_48	(1<<28)
+#define S5P_CLKCON_SCLK0_MMC0_48	(1<<27)
+#define S5P_CLKCON_SCLK0_MMC2		(1<<26)
+#define S5P_CLKCON_SCLK0_MMC1		(1<<25)
+#define S5P_CLKCON_SCLK0_MMC0		(1<<24)
+#define S5P_CLKCON_SCLK0_SPI1_48 	(1<<23)
+#define S5P_CLKCON_SCLK0_SPI0_48 	(1<<22)
+#define S5P_CLKCON_SCLK0_SPI1		(1<<21)
+#define S5P_CLKCON_SCLK0_SPI0		(1<<20)
+#define S5P_CLKCON_SCLK0_UART		(1<<5)
+
+/* SCLK1 GATE Registers */
+
+/* MEM0 GATE Registers */
+#define S5P_CLKCON_MEM0_HCLK_NFCON	(1<<2)
+
+/*OTHERS Resgister */
+#define S5P_OTHERS_USB_SIG_MASK		(1<<16)
+#define S5P_OTHERS_HCLK_LOW_SEL_MPLL	(1<<6)
+
+/* Compatibility defines */
+#define ARM_CLK_DIV			S5P_CLK_DIV0
+#define ARM_DIV_RATIO_SHIFT		0
+#define ARM_DIV_MASK			(0xf << ARM_DIV_RATIO_SHIFT)
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/regs-gpio.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/regs-gpio.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/regs-gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/regs-gpio.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,54 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/regs-gpio.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6440 - GPIO register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_REGS_GPIO_H
+#define __ASM_ARCH_REGS_GPIO_H __FILE__
+
+#include <mach/map.h>
+
+/* Base addresses for each of the banks */
+#define S5P6440_GPA_BASE		(S5P_VA_GPIO + 0x0000)
+#define S5P6440_GPB_BASE		(S5P_VA_GPIO + 0x0020)
+#define S5P6440_GPC_BASE		(S5P_VA_GPIO + 0x0040)
+#define S5P6440_GPF_BASE		(S5P_VA_GPIO + 0x00A0)
+#define S5P6440_GPG_BASE		(S5P_VA_GPIO + 0x00C0)
+#define S5P6440_GPH_BASE		(S5P_VA_GPIO + 0x00E0)
+#define S5P6440_GPI_BASE		(S5P_VA_GPIO + 0x0100)
+#define S5P6440_GPJ_BASE		(S5P_VA_GPIO + 0x0120)
+#define S5P6440_GPN_BASE		(S5P_VA_GPIO + 0x0830)
+#define S5P6440_GPP_BASE		(S5P_VA_GPIO + 0x0160)
+#define S5P6440_GPR_BASE		(S5P_VA_GPIO + 0x0290)
+#define S5P6440_EINT0CON0		(S5P_VA_GPIO + 0x900)
+#define S5P6440_EINT0FLTCON0		(S5P_VA_GPIO + 0x910)
+#define S5P6440_EINT0FLTCON1		(S5P_VA_GPIO + 0x914)
+#define S5P6440_EINT0MASK		(S5P_VA_GPIO + 0x920)
+#define S5P6440_EINT0PEND		(S5P_VA_GPIO + 0x924)
+
+/* for LCD */
+#define S5P6440_SPCON_LCD_SEL_RGB	(1 << 0)
+#define S5P6440_SPCON_LCD_SEL_MASK	(3 << 0)
+
+/* These set of macros are not really useful for the
+ * GPF/GPI/GPJ/GPN/GPP,
+ * useful for others set of GPIO's (4 bit)
+ */
+#define S5P6440_GPIO_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
+#define S5P6440_GPIO_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
+#define S5P6440_GPIO_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
+
+/* Use these macros for GPF/GPI/GPJ/GPN/GPP set of GPIO (2 bit)
+ * */
+#define S5P6440_GPIO2_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
+#define S5P6440_GPIO2_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
+#define S5P6440_GPIO2_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
+
+#endif /* __ASM_ARCH_REGS_GPIO_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/regs-irq.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/regs-irq.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/regs-irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/regs-irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6440 - IRQ register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_IRQ_H
+#define __ASM_ARCH_REGS_IRQ_H __FILE__
+
+#include <asm/hardware/vic.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_REGS_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/system.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/system.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/system.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6440 - system support header
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H __FILE__
+
+static void arch_idle(void)
+{
+	/* nothing here yet */
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+	/* nothing here yet */
+}
+
+#endif /* __ASM_ARCH_SYSTEM_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/tick.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/tick.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/tick.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/tick.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,24 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/tick.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6440 - Timer tick support definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TICK_H
+#define __ASM_ARCH_TICK_H __FILE__
+
+static inline u32 s3c24xx_ostimer_pending(void)
+{
+	u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
+	return pend & (1 << (IRQ_TIMER4_VIC - S5P_IRQ_VIC0(0)));
+}
+
+#define TICK_MAX	(0xffffffff)
+
+#endif /* __ASM_ARCH_TICK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/timex.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/timex.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/timex.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c64xx/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C6400 - time parameters
+ *
+ * This program is free software; you can 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_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/uncompress.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/uncompress.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/uncompress.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,24 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/uncompress.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6440 - uncompress 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.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/map.h>
+#include <plat/uncompress.h>
+
+static void arch_detect_cpu(void)
+{
+	/* we do not need to do any cpu detection here at the moment. */
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,17 @@
+/* arch/arm/mach-s5p6440/include/mach/vmalloc.h
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.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.
+ *
+ * S3C6400 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END	  (0xE0000000)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/init.c linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/init.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/init.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,52 @@
+/* linux/arch/arm/mach-s5p6440/init.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6440 - Init support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/s5p6440.h>
+#include <plat/regs-serial.h>
+
+static struct s3c24xx_uart_clksrc s5p6440_serial_clocks[] = {
+	[0] = {
+		.name		= "pclk_low",
+		.divisor	= 1,
+		.min_baud	= 0,
+		.max_baud	= 0,
+	},
+	[1] = {
+		.name		= "uclk1",
+		.divisor	= 1,
+		.min_baud	= 0,
+		.max_baud	= 0,
+	},
+};
+
+/* uart registration process */
+void __init s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+	struct s3c2410_uartcfg *tcfg = cfg;
+	u32 ucnt;
+
+	for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
+		if (!tcfg->clocks) {
+			tcfg->clocks = s5p6440_serial_clocks;
+			tcfg->clocks_size = ARRAY_SIZE(s5p6440_serial_clocks);
+		}
+	}
+
+	s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,21 @@
+# arch/arm/mach-s5p6440/Kconfig
+#
+# Copyright (c) 2009 Samsung Electronics Co., Ltd.
+#		http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+if ARCH_S5P6440
+
+config CPU_S5P6440
+	bool
+	help
+	  Enable S5P6440 CPU support
+
+config MACH_SMDK6440
+	bool "SMDK6440"
+	select CPU_S5P6440
+	help
+	  Machine support for the Samsung SMDK6440
+
+endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/mach-smdk6440.c linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/mach-smdk6440.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/mach-smdk6440.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/mach-smdk6440.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,111 @@
+/* linux/arch/arm/mach-s5p6440/mach-smdk6440.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+
+#include <plat/s5p6440.h>
+#include <plat/clock.h>
+#include <mach/regs-clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+
+#define S5P6440_UCON_DEFAULT    (S3C2410_UCON_TXILEVEL |	\
+				S3C2410_UCON_RXILEVEL |		\
+				S3C2410_UCON_TXIRQMODE |	\
+				S3C2410_UCON_RXIRQMODE |	\
+				S3C2410_UCON_RXFIFO_TOI |	\
+				S3C2443_UCON_RXERR_IRQEN)
+
+#define S5P6440_ULCON_DEFAULT	S3C2410_LCON_CS8
+
+#define S5P6440_UFCON_DEFAULT   (S3C2410_UFCON_FIFOMODE |	\
+				S3C2440_UFCON_TXTRIG16 |	\
+				S3C2410_UFCON_RXTRIG8)
+
+static struct s3c2410_uartcfg smdk6440_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = S5P6440_UCON_DEFAULT,
+		.ulcon	     = S5P6440_ULCON_DEFAULT,
+		.ufcon	     = S5P6440_UFCON_DEFAULT,
+	},
+	[1] = {
+		.hwport	     = 1,
+		.flags	     = 0,
+		.ucon	     = S5P6440_UCON_DEFAULT,
+		.ulcon	     = S5P6440_ULCON_DEFAULT,
+		.ufcon	     = S5P6440_UFCON_DEFAULT,
+	},
+	[2] = {
+		.hwport	     = 2,
+		.flags	     = 0,
+		.ucon	     = S5P6440_UCON_DEFAULT,
+		.ulcon	     = S5P6440_ULCON_DEFAULT,
+		.ufcon	     = S5P6440_UFCON_DEFAULT,
+	},
+	[3] = {
+		.hwport	     = 3,
+		.flags	     = 0,
+		.ucon	     = S5P6440_UCON_DEFAULT,
+		.ulcon	     = S5P6440_ULCON_DEFAULT,
+		.ufcon	     = S5P6440_UFCON_DEFAULT,
+	},
+};
+
+static struct platform_device *smdk6440_devices[] __initdata = {
+};
+
+static void __init smdk6440_map_io(void)
+{
+	s5p_init_io(NULL, 0, S5P_SYS_ID);
+	s3c24xx_init_clocks(12000000);
+	s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs));
+}
+
+static void __init smdk6440_machine_init(void)
+{
+	platform_add_devices(smdk6440_devices, ARRAY_SIZE(smdk6440_devices));
+}
+
+MACHINE_START(SMDK6440, "SMDK6440")
+	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+	.phys_io	= S3C_PA_UART & 0xfff00000,
+	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S5P_PA_SDRAM + 0x100,
+
+	.init_irq	= s5p6440_init_irq,
+	.map_io		= smdk6440_map_io,
+	.init_machine	= smdk6440_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,19 @@
+# arch/arm/mach-s5p6440/Makefile
+#
+# Copyright (c) 2009 Samsung Electronics Co., Ltd.
+# 		http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:=
+obj-				:=
+
+# Core support for S5P6440 system
+
+obj-$(CONFIG_CPU_S5P6440)	+= cpu.o init.o clock.o gpio.o
+
+# machine support
+
+obj-$(CONFIG_MACH_SMDK6440)	+= mach-smdk6440.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/Makefile.boot linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/Makefile.boot
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6440/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6440/Makefile.boot	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,2 @@
+   zreladdr-y	:= 0x20008000
+params_phys-y	:= 0x20000100
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/clock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,396 @@
+/* linux/arch/arm/mach-s5p6442/clock.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6442 - Clock 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/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+
+#include <plat/cpu-freq.h>
+#include <mach/regs-clock.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p6442.h>
+
+static struct clksrc_clk clk_mout_apll = {
+	.clk	= {
+		.name		= "mout_apll",
+		.id		= -1,
+	},
+	.sources	= &clk_src_apll,
+	.reg_src	= { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_mpll = {
+	.clk = {
+		.name		= "mout_mpll",
+		.id		= -1,
+	},
+	.sources	= &clk_src_mpll,
+	.reg_src	= { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_epll = {
+	.clk	= {
+		.name		= "mout_epll",
+		.id		= -1,
+	},
+	.sources	= &clk_src_epll,
+	.reg_src	= { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
+};
+
+/* Possible clock sources for ARM Mux */
+static struct clk *clk_src_arm_list[] = {
+	[1] = &clk_mout_apll.clk,
+	[2] = &clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources clk_src_arm = {
+	.sources	= clk_src_arm_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_arm_list),
+};
+
+static struct clksrc_clk clk_mout_arm = {
+	.clk	= {
+		.name		= "mout_arm",
+		.id		= -1,
+	},
+	.sources	= &clk_src_arm,
+	.reg_src	= { .reg = S5P_CLK_MUX_STAT0, .shift = 16, .size = 3 },
+};
+
+static struct clk clk_dout_a2m = {
+	.name		= "dout_a2m",
+	.id		= -1,
+	.parent		= &clk_mout_apll.clk,
+};
+
+/* Possible clock sources for D0 Mux */
+static struct clk *clk_src_d0_list[] = {
+	[1] = &clk_mout_mpll.clk,
+	[2] = &clk_dout_a2m,
+};
+
+static struct clksrc_sources clk_src_d0 = {
+	.sources	= clk_src_d0_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_d0_list),
+};
+
+static struct clksrc_clk clk_mout_d0 = {
+	.clk = {
+		.name		= "mout_d0",
+		.id		= -1,
+	},
+	.sources	= &clk_src_d0,
+	.reg_src	= { .reg = S5P_CLK_MUX_STAT0, .shift = 20, .size = 3 },
+};
+
+static struct clk clk_dout_apll = {
+	.name		= "dout_apll",
+	.id		= -1,
+	.parent		= &clk_mout_arm.clk,
+};
+
+/* Possible clock sources for D0SYNC Mux */
+static struct clk *clk_src_d0sync_list[] = {
+	[1] = &clk_mout_d0.clk,
+	[2] = &clk_dout_apll,
+};
+
+static struct clksrc_sources clk_src_d0sync = {
+	.sources	= clk_src_d0sync_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_d0sync_list),
+};
+
+static struct clksrc_clk clk_mout_d0sync = {
+	.clk	= {
+		.name		= "mout_d0sync",
+		.id		= -1,
+	},
+	.sources	= &clk_src_d0sync,
+	.reg_src	= { .reg = S5P_CLK_MUX_STAT1, .shift = 28, .size = 3 },
+};
+
+/* Possible clock sources for D1 Mux */
+static struct clk *clk_src_d1_list[] = {
+	[1] = &clk_mout_mpll.clk,
+	[2] = &clk_dout_a2m,
+};
+
+static struct clksrc_sources clk_src_d1 = {
+	.sources	= clk_src_d1_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_d1_list),
+};
+
+static struct clksrc_clk clk_mout_d1 = {
+	.clk	= {
+		.name		= "mout_d1",
+		.id		= -1,
+	},
+	.sources	= &clk_src_d1,
+	.reg_src	= { .reg = S5P_CLK_MUX_STAT0, .shift = 24, .size = 3 },
+};
+
+/* Possible clock sources for D1SYNC Mux */
+static struct clk *clk_src_d1sync_list[] = {
+	[1] = &clk_mout_d1.clk,
+	[2] = &clk_dout_apll,
+};
+
+static struct clksrc_sources clk_src_d1sync = {
+	.sources	= clk_src_d1sync_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_d1sync_list),
+};
+
+static struct clksrc_clk clk_mout_d1sync = {
+	.clk	= {
+		.name		= "mout_d1sync",
+		.id		= -1,
+	},
+	.sources	= &clk_src_d1sync,
+	.reg_src	= { .reg = S5P_CLK_MUX_STAT1, .shift = 24, .size = 3 },
+};
+
+static struct clk clk_hclkd0 = {
+	.name		= "hclkd0",
+	.id		= -1,
+	.parent		= &clk_mout_d0sync.clk,
+};
+
+static struct clk clk_hclkd1 = {
+	.name		= "hclkd1",
+	.id		= -1,
+	.parent		= &clk_mout_d1sync.clk,
+};
+
+static struct clk clk_pclkd0 = {
+	.name		= "pclkd0",
+	.id		= -1,
+	.parent		= &clk_hclkd0,
+};
+
+static struct clk clk_pclkd1 = {
+	.name		= "pclkd1",
+	.id		= -1,
+	.parent		= &clk_hclkd1,
+};
+
+int s5p6442_clk_ip3_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
+}
+
+static struct clksrc_clk clksrcs[] = {
+	{
+		.clk	= {
+			.name		= "dout_a2m",
+			.id		= -1,
+			.parent		= &clk_mout_apll.clk,
+		},
+		.sources = &clk_src_apll,
+		.reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
+		.reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 },
+	}, {
+		.clk	= {
+			.name		= "dout_apll",
+			.id		= -1,
+			.parent		= &clk_mout_arm.clk,
+		},
+		.sources = &clk_src_arm,
+		.reg_src = { .reg = S5P_CLK_MUX_STAT0, .shift = 16, .size = 3 },
+		.reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 },
+	}, {
+		.clk	= {
+			.name		= "hclkd1",
+			.id		= -1,
+			.parent		= &clk_mout_d1sync.clk,
+		},
+		.sources = &clk_src_d1sync,
+		.reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 24, .size = 3 },
+		.reg_div = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 },
+	}, {
+		.clk	= {
+			.name		= "hclkd0",
+			.id		= -1,
+			.parent		= &clk_mout_d0sync.clk,
+		},
+		.sources = &clk_src_d0sync,
+		.reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 28, .size = 3 },
+		.reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 },
+	}, {
+		.clk	= {
+			.name		= "pclkd0",
+			.id		= -1,
+			.parent		= &clk_hclkd0,
+		},
+		.sources = &clk_src_d0sync,
+		.reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 28, .size = 3 },
+		.reg_div = { .reg = S5P_CLK_DIV0, .shift = 20, .size = 3 },
+	}, {
+		.clk	= {
+			.name		= "pclkd1",
+			.id		= -1,
+			.parent		= &clk_hclkd1,
+		},
+		.sources = &clk_src_d1sync,
+		.reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 24, .size = 3 },
+		.reg_div = { .reg = S5P_CLK_DIV0, .shift = 28, .size = 3 },
+	}
+};
+
+/* Clock initialisation code */
+static struct clksrc_clk *init_parents[] = {
+	&clk_mout_apll,
+	&clk_mout_mpll,
+	&clk_mout_epll,
+	&clk_mout_arm,
+	&clk_mout_d0,
+	&clk_mout_d0sync,
+	&clk_mout_d1,
+	&clk_mout_d1sync,
+};
+
+void __init_or_cpufreq s5p6442_setup_clocks(void)
+{
+	struct clk *pclkd0_clk;
+	struct clk *pclkd1_clk;
+
+	unsigned long xtal;
+	unsigned long arm;
+	unsigned long hclkd0 = 0;
+	unsigned long hclkd1 = 0;
+	unsigned long pclkd0 = 0;
+	unsigned long pclkd1 = 0;
+
+	unsigned long apll;
+	unsigned long mpll;
+	unsigned long epll;
+	unsigned int ptr;
+
+	printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+	xtal = clk_get_rate(&clk_xtal);
+
+	printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+	apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
+	mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
+	epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500);
+
+	printk(KERN_INFO "S5P6440: PLL settings, A=%ld, M=%ld, E=%ld",
+			apll, mpll, epll);
+
+	clk_fout_apll.rate = apll;
+	clk_fout_mpll.rate = mpll;
+	clk_fout_epll.rate = epll;
+
+	for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
+		s3c_set_clksrc(init_parents[ptr], true);
+
+	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+		s3c_set_clksrc(&clksrcs[ptr], true);
+
+	arm = clk_get_rate(&clk_dout_apll);
+	hclkd0 = clk_get_rate(&clk_hclkd0);
+	hclkd1 = clk_get_rate(&clk_hclkd1);
+
+	pclkd0_clk = clk_get(NULL, "pclkd0");
+	BUG_ON(IS_ERR(pclkd0_clk));
+
+	pclkd0 = clk_get_rate(pclkd0_clk);
+	clk_put(pclkd0_clk);
+
+	pclkd1_clk = clk_get(NULL, "pclkd1");
+	BUG_ON(IS_ERR(pclkd1_clk));
+
+	pclkd1 = clk_get_rate(pclkd1_clk);
+	clk_put(pclkd1_clk);
+
+	printk(KERN_INFO "S5P6442: HCLKD0=%ld, HCLKD1=%ld, PCLKD0=%ld, PCLKD1=%ld\n",
+			hclkd0, hclkd1, pclkd0, pclkd1);
+
+	/* For backward compatibility */
+	clk_f.rate = arm;
+	clk_h.rate = hclkd1;
+	clk_p.rate = pclkd1;
+
+	clk_pclkd0.rate = pclkd0;
+	clk_pclkd1.rate = pclkd1;
+}
+
+static struct clk init_clocks[] = {
+	{
+		.name		= "systimer",
+		.id		= -1,
+		.parent		= &clk_pclkd1,
+		.enable		= s5p6442_clk_ip3_ctrl,
+		.ctrlbit	= (1<<16),
+	}, {
+		.name		= "uart",
+		.id		= 0,
+		.parent		= &clk_pclkd1,
+		.enable		= s5p6442_clk_ip3_ctrl,
+		.ctrlbit	= (1<<17),
+	}, {
+		.name		= "uart",
+		.id		= 1,
+		.parent		= &clk_pclkd1,
+		.enable		= s5p6442_clk_ip3_ctrl,
+		.ctrlbit	= (1<<18),
+	}, {
+		.name		= "uart",
+		.id		= 2,
+		.parent		= &clk_pclkd1,
+		.enable		= s5p6442_clk_ip3_ctrl,
+		.ctrlbit	= (1<<19),
+	}, {
+		.name		= "timers",
+		.id		= -1,
+		.parent		= &clk_pclkd1,
+		.enable		= s5p6442_clk_ip3_ctrl,
+		.ctrlbit	= (1<<23),
+	},
+};
+
+static struct clk *clks[] __initdata = {
+	&clk_ext,
+	&clk_epll,
+	&clk_mout_apll.clk,
+	&clk_mout_mpll.clk,
+	&clk_mout_epll.clk,
+	&clk_mout_d0.clk,
+	&clk_mout_d0sync.clk,
+	&clk_mout_d1.clk,
+	&clk_mout_d1sync.clk,
+	&clk_hclkd0,
+	&clk_pclkd0,
+	&clk_hclkd1,
+	&clk_pclkd1,
+};
+
+void __init s5p6442_register_clocks(void)
+{
+	s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+	s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+	s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+	s3c_pwmclk_init();
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/cpu.c linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/cpu.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/cpu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/cpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,121 @@
+/* linux/arch/arm/mach-s5p6442/cpu.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/proc-fns.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <asm/irq.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/s5p6442.h>
+
+/* Initial IO mappings */
+
+static struct map_desc s5p6442_iodesc[] __initdata = {
+	{
+		.virtual	= (unsigned long)S5P_VA_SYSTIMER,
+		.pfn		= __phys_to_pfn(S5P6442_PA_SYSTIMER),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)VA_VIC2,
+		.pfn		= __phys_to_pfn(S5P6442_PA_VIC2),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}
+};
+
+static void s5p6442_idle(void)
+{
+	if (!need_resched())
+		cpu_do_idle();
+
+	local_irq_enable();
+}
+
+/* s5p6442_map_io
+ *
+ * register the standard cpu IO areas
+*/
+
+void __init s5p6442_map_io(void)
+{
+	iotable_init(s5p6442_iodesc, ARRAY_SIZE(s5p6442_iodesc));
+}
+
+void __init s5p6442_init_clocks(int xtal)
+{
+	printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+	s3c24xx_register_baseclocks(xtal);
+	s5p_register_clocks(xtal);
+	s5p6442_register_clocks();
+	s5p6442_setup_clocks();
+}
+
+void __init s5p6442_init_irq(void)
+{
+	/* S5P6442 supports 3 VIC */
+	u32 vic[3];
+
+	/* VIC0, VIC1, and VIC2: some interrupt reserved */
+	vic[0] = 0x7fefffff;
+	vic[1] = 0X7f389c81;
+	vic[2] = 0X1bbbcfff;
+
+	s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+static struct sysdev_class s5p6442_sysclass = {
+	.name	= "s5p6442-core",
+};
+
+static struct sys_device s5p6442_sysdev = {
+	.cls	= &s5p6442_sysclass,
+};
+
+static int __init s5p6442_core_init(void)
+{
+	return sysdev_class_register(&s5p6442_sysclass);
+}
+
+core_initcall(s5p6442_core_init);
+
+int __init s5p6442_init(void)
+{
+	printk(KERN_INFO "S5P6442: Initializing architecture\n");
+
+	/* set idle function */
+	pm_idle = s5p6442_idle;
+
+	return sysdev_register(&s5p6442_sysdev);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,36 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/debug-macro.S
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s3c6400/include/mach/debug-macro.S
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <mach/map.h>
+#include <plat/regs-serial.h>
+
+	.macro addruart, rx, rtmp
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1
+		ldreq	\rx, = S3C_PA_UART
+		ldrne	\rx, = S3C_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+		add	\rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
+#endif
+	.endm
+
+#define fifo_full fifo_full_s5pv210
+#define fifo_level fifo_level_s5pv210
+
+/* include the reset of the code which will do the work, we're only
+ * compiling for a single cpu processor type so the default of s3c2440
+ * will be fine with us.
+ */
+
+#include <plat/debug-macro.S>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/entry-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/entry-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/entry-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,48 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/entry-macro.S
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Low-level IRQ helper macros for the Samsung S5P6442
+ *
+ * This program is free software; you can 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/hardware/vic.h>
+#include <mach/map.h>
+#include <plat/irqs.h>
+
+	.macro	disable_fiq
+	.endm
+
+	.macro	get_irqnr_preamble, base, tmp
+	ldr	\base, =VA_VIC0
+	.endm
+
+	.macro	arch_ret_to_user, tmp1, tmp2
+	.endm
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+	@ check the vic0
+	mov	\irqnr, # S5P_IRQ_OFFSET + 31
+	ldr	\irqstat, [ \base, # VIC_IRQ_STATUS ]
+	teq	\irqstat, #0
+
+	@ otherwise try vic1
+	addeq	\tmp, \base, #(VA_VIC1 - VA_VIC0)
+	addeq	\irqnr, \irqnr, #32
+	ldreq	\irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+	teqeq	\irqstat, #0
+
+	@ otherwise try vic2
+	addeq	\tmp, \base, #(VA_VIC2 - VA_VIC0)
+	addeq	\irqnr, \irqnr, #32
+	ldreq	\irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+	teqeq	\irqstat, #0
+
+	clzne	\irqstat, \irqstat
+	subne	\irqnr, \irqnr, \irqstat
+	.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/gpio.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/gpio.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/gpio.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,123 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/gpio.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6442 - GPIO lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H __FILE__
+
+#define gpio_get_value	__gpio_get_value
+#define gpio_set_value	__gpio_set_value
+#define gpio_cansleep	__gpio_cansleep
+#define gpio_to_irq	__gpio_to_irq
+
+/* GPIO bank sizes */
+#define S5P6442_GPIO_A0_NR	(8)
+#define S5P6442_GPIO_A1_NR	(2)
+#define S5P6442_GPIO_B_NR	(4)
+#define S5P6442_GPIO_C0_NR	(5)
+#define S5P6442_GPIO_C1_NR	(5)
+#define S5P6442_GPIO_D0_NR	(2)
+#define S5P6442_GPIO_D1_NR	(6)
+#define S5P6442_GPIO_E0_NR	(8)
+#define S5P6442_GPIO_E1_NR	(5)
+#define S5P6442_GPIO_F0_NR	(8)
+#define S5P6442_GPIO_F1_NR	(8)
+#define S5P6442_GPIO_F2_NR	(8)
+#define S5P6442_GPIO_F3_NR	(6)
+#define S5P6442_GPIO_G0_NR	(7)
+#define S5P6442_GPIO_G1_NR	(7)
+#define S5P6442_GPIO_G2_NR	(7)
+#define S5P6442_GPIO_H0_NR	(8)
+#define S5P6442_GPIO_H1_NR	(8)
+#define S5P6442_GPIO_H2_NR	(8)
+#define S5P6442_GPIO_H3_NR	(8)
+#define S5P6442_GPIO_J0_NR	(8)
+#define S5P6442_GPIO_J1_NR	(6)
+#define S5P6442_GPIO_J2_NR	(8)
+#define S5P6442_GPIO_J3_NR	(8)
+#define S5P6442_GPIO_J4_NR	(5)
+
+/* GPIO bank numbers */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+
+#define S5P6442_GPIO_NEXT(__gpio) \
+	((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s5p_gpio_number {
+	S5P6442_GPIO_A0_START	= 0,
+	S5P6442_GPIO_A1_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_A0),
+	S5P6442_GPIO_B_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_A1),
+	S5P6442_GPIO_C0_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_B),
+	S5P6442_GPIO_C1_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_C0),
+	S5P6442_GPIO_D0_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_C1),
+	S5P6442_GPIO_D1_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_D0),
+	S5P6442_GPIO_E0_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_D1),
+	S5P6442_GPIO_E1_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_E0),
+	S5P6442_GPIO_F0_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_E1),
+	S5P6442_GPIO_F1_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_F0),
+	S5P6442_GPIO_F2_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_F1),
+	S5P6442_GPIO_F3_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_F2),
+	S5P6442_GPIO_G0_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_F3),
+	S5P6442_GPIO_G1_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_G0),
+	S5P6442_GPIO_G2_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_G1),
+	S5P6442_GPIO_H0_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_G2),
+	S5P6442_GPIO_H1_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_H0),
+	S5P6442_GPIO_H2_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_H1),
+	S5P6442_GPIO_H3_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_H2),
+	S5P6442_GPIO_J0_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_H3),
+	S5P6442_GPIO_J1_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_J0),
+	S5P6442_GPIO_J2_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_J1),
+	S5P6442_GPIO_J3_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_J2),
+	S5P6442_GPIO_J4_START	= S5P6442_GPIO_NEXT(S5P6442_GPIO_J3),
+};
+
+/* S5P6442 GPIO number definitions. */
+#define S5P6442_GPA0(_nr)	(S5P6442_GPIO_A0_START + (_nr))
+#define S5P6442_GPA1(_nr)	(S5P6442_GPIO_A1_START + (_nr))
+#define S5P6442_GPB(_nr)	(S5P6442_GPIO_B_START + (_nr))
+#define S5P6442_GPC0(_nr)	(S5P6442_GPIO_C0_START + (_nr))
+#define S5P6442_GPC1(_nr)	(S5P6442_GPIO_C1_START + (_nr))
+#define S5P6442_GPD0(_nr)	(S5P6442_GPIO_D0_START + (_nr))
+#define S5P6442_GPD1(_nr)	(S5P6442_GPIO_D1_START + (_nr))
+#define S5P6442_GPE0(_nr)	(S5P6442_GPIO_E0_START + (_nr))
+#define S5P6442_GPE1(_nr)	(S5P6442_GPIO_E1_START + (_nr))
+#define S5P6442_GPF0(_nr)	(S5P6442_GPIO_F0_START + (_nr))
+#define S5P6442_GPF1(_nr)	(S5P6442_GPIO_F1_START + (_nr))
+#define S5P6442_GPF2(_nr)	(S5P6442_GPIO_F2_START + (_nr))
+#define S5P6442_GPF3(_nr)	(S5P6442_GPIO_F3_START + (_nr))
+#define S5P6442_GPG0(_nr)	(S5P6442_GPIO_G0_START + (_nr))
+#define S5P6442_GPG1(_nr)	(S5P6442_GPIO_G1_START + (_nr))
+#define S5P6442_GPG2(_nr)	(S5P6442_GPIO_G2_START + (_nr))
+#define S5P6442_GPH0(_nr)	(S5P6442_GPIO_H0_START + (_nr))
+#define S5P6442_GPH1(_nr)	(S5P6442_GPIO_H1_START + (_nr))
+#define S5P6442_GPH2(_nr)	(S5P6442_GPIO_H2_START + (_nr))
+#define S5P6442_GPH3(_nr)	(S5P6442_GPIO_H3_START + (_nr))
+#define S5P6442_GPJ0(_nr)	(S5P6442_GPIO_J0_START + (_nr))
+#define S5P6442_GPJ1(_nr)	(S5P6442_GPIO_J1_START + (_nr))
+#define S5P6442_GPJ2(_nr)	(S5P6442_GPIO_J2_START + (_nr))
+#define S5P6442_GPJ3(_nr)	(S5P6442_GPIO_J3_START + (_nr))
+#define S5P6442_GPJ4(_nr)	(S5P6442_GPIO_J4_START + (_nr))
+
+/* the end of the S5P6442 specific gpios */
+#define S5P6442_GPIO_END	(S5P6442_GPJ4(S5P6442_GPIO_J4_NR) + 1)
+#define S3C_GPIO_END		S5P6442_GPIO_END
+
+/* define the number of gpios we need to the one after the GPJ4() range */
+#define ARCH_NR_GPIOS		(S5P6442_GPJ4(S5P6442_GPIO_J4_NR) +	\
+				 CONFIG_SAMSUNG_GPIO_EXTRA + 1)
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/hardware.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/hardware.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/hardware.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,18 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/hardware.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6442 - Hardware support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H __FILE__
+
+/* currently nothing here, placeholder */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/io.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/io.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/io.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,17 @@
+/* arch/arm/mach-s5p6442/include/mach/io.h
+ *
+ * Copyright 2008-2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S5P6442
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a)		__typesafe_io(a)
+#define __mem_pci(a)	(a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/irqs.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/irqs.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/irqs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,86 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/irqs.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6442 - IRQ definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H __FILE__
+
+#include <plat/irqs.h>
+
+/* VIC0 */
+#define IRQ_EINT16_31 		S5P_IRQ_VIC0(16)
+#define IRQ_BATF 		S5P_IRQ_VIC0(17)
+#define IRQ_MDMA 		S5P_IRQ_VIC0(18)
+#define IRQ_PDMA 		S5P_IRQ_VIC0(19)
+#define IRQ_TIMER0_VIC		S5P_IRQ_VIC0(21)
+#define IRQ_TIMER1_VIC		S5P_IRQ_VIC0(22)
+#define IRQ_TIMER2_VIC		S5P_IRQ_VIC0(23)
+#define IRQ_TIMER3_VIC		S5P_IRQ_VIC0(24)
+#define IRQ_TIMER4_VIC		S5P_IRQ_VIC0(25)
+#define IRQ_SYSTIMER		S5P_IRQ_VIC0(26)
+#define IRQ_WDT			S5P_IRQ_VIC0(27)
+#define IRQ_RTC_ALARM		S5P_IRQ_VIC0(28)
+#define IRQ_RTC_TIC		S5P_IRQ_VIC0(29)
+#define IRQ_GPIOINT		S5P_IRQ_VIC0(30)
+
+/* VIC1 */
+#define IRQ_nPMUIRQ 		S5P_IRQ_VIC1(0)
+#define IRQ_ONENAND 		S5P_IRQ_VIC1(7)
+#define IRQ_UART0 		S5P_IRQ_VIC1(10)
+#define IRQ_UART1 		S5P_IRQ_VIC1(11)
+#define IRQ_UART2 		S5P_IRQ_VIC1(12)
+#define IRQ_SPI0 		S5P_IRQ_VIC1(15)
+#define IRQ_IIC 		S5P_IRQ_VIC1(19)
+#define IRQ_IIC1 		S5P_IRQ_VIC1(20)
+#define IRQ_IIC2 		S5P_IRQ_VIC1(21)
+#define IRQ_OTG 		S5P_IRQ_VIC1(24)
+#define IRQ_MSM 		S5P_IRQ_VIC1(25)
+#define IRQ_HSMMC0 		S5P_IRQ_VIC1(26)
+#define IRQ_HSMMC1 		S5P_IRQ_VIC1(27)
+#define IRQ_HSMMC2 		S5P_IRQ_VIC1(28)
+#define IRQ_COMMRX 		S5P_IRQ_VIC1(29)
+#define IRQ_COMMTX 		S5P_IRQ_VIC1(30)
+
+/* VIC2 */
+#define IRQ_LCD0 		S5P_IRQ_VIC2(0)
+#define IRQ_LCD1 		S5P_IRQ_VIC2(1)
+#define IRQ_LCD2 		S5P_IRQ_VIC2(2)
+#define IRQ_LCD3 		S5P_IRQ_VIC2(3)
+#define IRQ_ROTATOR 		S5P_IRQ_VIC2(4)
+#define IRQ_FIMC0 		S5P_IRQ_VIC2(5)
+#define IRQ_FIMC1 		S5P_IRQ_VIC2(6)
+#define IRQ_FIMC2 		S5P_IRQ_VIC2(7)
+#define IRQ_JPEG 		S5P_IRQ_VIC2(8)
+#define IRQ_3D 			S5P_IRQ_VIC2(10)
+#define IRQ_Mixer 		S5P_IRQ_VIC2(11)
+#define IRQ_MFC 		S5P_IRQ_VIC2(14)
+#define IRQ_TVENC 		S5P_IRQ_VIC2(15)
+#define IRQ_I2S0 		S5P_IRQ_VIC2(16)
+#define IRQ_I2S1 		S5P_IRQ_VIC2(17)
+#define IRQ_RP 			S5P_IRQ_VIC2(19)
+#define IRQ_PCM0 		S5P_IRQ_VIC2(20)
+#define IRQ_PCM1 		S5P_IRQ_VIC2(21)
+#define IRQ_ADC 		S5P_IRQ_VIC2(23)
+#define IRQ_PENDN 		S5P_IRQ_VIC2(24)
+#define IRQ_KEYPAD 		S5P_IRQ_VIC2(25)
+#define IRQ_SSS_INT 		S5P_IRQ_VIC2(27)
+#define IRQ_SSS_HASH 		S5P_IRQ_VIC2(28)
+#define IRQ_VIC_END 		S5P_IRQ_VIC2(31)
+
+#define S5P_IRQ_EINT_BASE	(IRQ_VIC_END + 1)
+
+#define IRQ_EINT(x)             ((x) < 16 ? S5P_IRQ_VIC0(x) : \
+					(S5P_IRQ_EINT_BASE + (x)-16))
+/* Set the default NR_IRQS */
+
+#define NR_IRQS 		(IRQ_EINT(31) + 1)
+
+#endif /* __ASM_ARCH_IRQS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/map.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/map.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/map.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/map.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,58 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/map.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6442 - Memory 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_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+#define S5P6442_PA_CHIPID	(0xE0000000)
+#define S5P_PA_CHIPID		S5P6442_PA_CHIPID
+
+#define S5P6442_PA_SYSCON	(0xE0100000)
+#define S5P_PA_SYSCON		S5P6442_PA_SYSCON
+
+#define S5P6442_PA_GPIO		(0xE0200000)
+#define S5P_PA_GPIO		S5P6442_PA_GPIO
+
+#define S5P6442_PA_VIC0		(0xE4000000)
+#define S5P_PA_VIC0		S5P6442_PA_VIC0
+
+#define S5P6442_PA_VIC1		(0xE4100000)
+#define S5P_PA_VIC1		S5P6442_PA_VIC1
+
+#define S5P6442_PA_VIC2		(0xE4200000)
+#define S5P_PA_VIC2		S5P6442_PA_VIC2
+
+#define S5P6442_PA_TIMER	(0xEA000000)
+#define S5P_PA_TIMER		S5P6442_PA_TIMER
+
+#define S5P6442_PA_SYSTIMER   	(0xEA100000)
+
+#define S5P6442_PA_UART		(0xEC000000)
+
+#define S5P_PA_UART0		(S5P6442_PA_UART + 0x0)
+#define S5P_PA_UART1		(S5P6442_PA_UART + 0x400)
+#define S5P_PA_UART2		(S5P6442_PA_UART + 0x800)
+#define S5P_SZ_UART		SZ_256
+
+#define S5P6442_PA_IIC0		(0xEC100000)
+
+#define S5P6442_PA_SDRAM	(0x20000000)
+#define S5P_PA_SDRAM		S5P6442_PA_SDRAM
+
+/* compatibiltiy defines. */
+#define S3C_PA_UART		S5P6442_PA_UART
+#define S3C_PA_IIC		S5P6442_PA_IIC0
+
+#endif /* __ASM_ARCH_MAP_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/memory.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/memory.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/memory.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/memory.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6442 - Memory definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET		UL(0x20000000)
+#define CONSISTENT_DMA_SIZE	SZ_8M
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/pwm-clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/pwm-clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/pwm-clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/pwm-clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,69 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/pwm-clock.h
+ *
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * Copyright 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Based on arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
+ *
+ * S5P6442 - pwm clock and timer support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_PWMCLK_H
+#define __ASM_ARCH_PWMCLK_H __FILE__
+
+/**
+ * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
+ * @cfg: The timer TCFG1 register bits shifted down to 0.
+ *
+ * Return true if the given configuration from TCFG1 is a TCLK instead
+ * any of the TDIV clocks.
+ */
+static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
+{
+	return tcfg == S3C2410_TCFG1_MUX_TCLK;
+}
+
+/**
+ * tcfg_to_divisor() - convert tcfg1 setting to a divisor
+ * @tcfg1: The tcfg1 setting, shifted down.
+ *
+ * Get the divisor value for the given tcfg1 setting. We assume the
+ * caller has already checked to see if this is not a TCLK source.
+ */
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+	return 1 << (1 + tcfg1);
+}
+
+/**
+ * pwm_tdiv_has_div1() - does the tdiv setting have a /1
+ *
+ * Return true if we have a /1 in the tdiv setting.
+ */
+static inline unsigned int pwm_tdiv_has_div1(void)
+{
+	return 0;
+}
+
+/**
+ * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
+ * @div: The divisor to calculate the bit information for.
+ *
+ * Turn a divisor into the necessary bit field for TCFG1.
+ */
+static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
+{
+	return ilog2(div) - 1;
+}
+
+#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
+
+#endif /* __ASM_ARCH_PWMCLK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/regs-clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/regs-clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/regs-clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/regs-clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,103 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6442 - Clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_CLKREG(x)		(S3C_VA_SYS + (x))
+
+#define S5P_APLL_LOCK		S5P_CLKREG(0x00)
+#define S5P_MPLL_LOCK		S5P_CLKREG(0x08)
+#define S5P_EPLL_LOCK		S5P_CLKREG(0x10)
+#define S5P_VPLL_LOCK		S5P_CLKREG(0x20)
+
+#define S5P_APLL_CON		S5P_CLKREG(0x100)
+#define S5P_MPLL_CON		S5P_CLKREG(0x108)
+#define S5P_EPLL_CON		S5P_CLKREG(0x110)
+#define S5P_VPLL_CON		S5P_CLKREG(0x120)
+
+#define S5P_CLK_SRC0		S5P_CLKREG(0x200)
+#define S5P_CLK_SRC1		S5P_CLKREG(0x204)
+#define S5P_CLK_SRC2		S5P_CLKREG(0x208)
+#define S5P_CLK_SRC3		S5P_CLKREG(0x20C)
+#define S5P_CLK_SRC4		S5P_CLKREG(0x210)
+#define S5P_CLK_SRC5		S5P_CLKREG(0x214)
+#define S5P_CLK_SRC6		S5P_CLKREG(0x218)
+
+#define S5P_CLK_SRC_MASK0	S5P_CLKREG(0x280)
+#define S5P_CLK_SRC_MASK1	S5P_CLKREG(0x284)
+
+#define S5P_CLK_DIV0		S5P_CLKREG(0x300)
+#define S5P_CLK_DIV1		S5P_CLKREG(0x304)
+#define S5P_CLK_DIV2		S5P_CLKREG(0x308)
+#define S5P_CLK_DIV3		S5P_CLKREG(0x30C)
+#define S5P_CLK_DIV4		S5P_CLKREG(0x310)
+#define S5P_CLK_DIV5		S5P_CLKREG(0x314)
+#define S5P_CLK_DIV6		S5P_CLKREG(0x318)
+
+#define S5P_CLKGATE_IP3		S5P_CLKREG(0x46C)
+
+/* CLK_OUT */
+#define S5P_CLK_OUT_SHIFT	(12)
+#define S5P_CLK_OUT_MASK	(0x1F << S5P_CLK_OUT_SHIFT)
+#define S5P_CLK_OUT		S5P_CLKREG(0x500)
+
+#define S5P_CLK_DIV_STAT0	S5P_CLKREG(0x1000)
+#define S5P_CLK_DIV_STAT1	S5P_CLKREG(0x1004)
+
+#define S5P_CLK_MUX_STAT0	S5P_CLKREG(0x1100)
+#define S5P_CLK_MUX_STAT1	S5P_CLKREG(0x1104)
+
+#define S5P_MDNIE_SEL		S5P_CLKREG(0x7008)
+
+/* Register Bit definition */
+#define S5P_EPLL_EN     		(1<<31)
+#define S5P_EPLL_MASK   		0xffffffff
+#define S5P_EPLLVAL(_m, _p, _s)   	((_m) << 16 | ((_p) << 8) | ((_s)))
+
+/* CLKDIV0 */
+#define S5P_CLKDIV0_APLL_SHIFT		(0)
+#define S5P_CLKDIV0_APLL_MASK		(0x7 << S5P_CLKDIV0_APLL_SHIFT)
+#define S5P_CLKDIV0_A2M_SHIFT		(4)
+#define S5P_CLKDIV0_A2M_MASK		(0x7 << S5P_CLKDIV0_A2M_SHIFT)
+#define S5P_CLKDIV0_D0CLK_SHIFT		(16)
+#define S5P_CLKDIV0_D0CLK_MASK		(0xF << S5P_CLKDIV0_D0CLK_SHIFT)
+#define S5P_CLKDIV0_P0CLK_SHIFT		(20)
+#define S5P_CLKDIV0_P0CLK_MASK		(0x7 << S5P_CLKDIV0_P0CLK_SHIFT)
+#define S5P_CLKDIV0_D1CLK_SHIFT		(24)
+#define S5P_CLKDIV0_D1CLK_MASK		(0xF << S5P_CLKDIV0_D1CLK_SHIFT)
+#define S5P_CLKDIV0_P1CLK_SHIFT		(28)
+#define S5P_CLKDIV0_P1CLK_MASK		(0x7 << S5P_CLKDIV0_P1CLK_SHIFT)
+
+/* Clock MUX status Registers */
+#define S5P_CLK_MUX_STAT0_APLL_SHIFT	(0)
+#define S5P_CLK_MUX_STAT0_APLL_MASK	(0x7 << S5P_CLK_MUX_STAT0_APLL_SHIFT)
+#define S5P_CLK_MUX_STAT0_MPLL_SHIFT	(4)
+#define S5P_CLK_MUX_STAT0_MPLL_MASK	(0x7 << S5P_CLK_MUX_STAT0_MPLL_SHIFT)
+#define S5P_CLK_MUX_STAT0_EPLL_SHIFT	(8)
+#define S5P_CLK_MUX_STAT0_EPLL_MASK	(0x7 << S5P_CLK_MUX_STAT0_EPLL_SHIFT)
+#define S5P_CLK_MUX_STAT0_VPLL_SHIFT	(12)
+#define S5P_CLK_MUX_STAT0_VPLL_MASK	(0x7 << S5P_CLK_MUX_STAT0_VPLL_SHIFT)
+#define S5P_CLK_MUX_STAT0_MUXARM_SHIFT	(16)
+#define S5P_CLK_MUX_STAT0_MUXARM_MASK	(0x7 << S5P_CLK_MUX_STAT0_MUXARM_SHIFT)
+#define S5P_CLK_MUX_STAT0_MUXD0_SHIFT	(20)
+#define S5P_CLK_MUX_STAT0_MUXD0_MASK	(0x7 << S5P_CLK_MUX_STAT0_MUXD0_SHIFT)
+#define S5P_CLK_MUX_STAT0_MUXD1_SHIFT	(24)
+#define S5P_CLK_MUX_STAT0_MUXD1_MASK	(0x7 << S5P_CLK_MUX_STAT0_MUXD1_SHIFT)
+#define S5P_CLK_MUX_STAT1_D1SYNC_SHIFT	(24)
+#define S5P_CLK_MUX_STAT1_D1SYNC_MASK	(0x7 << S5P_CLK_MUX_STAT1_D1SYNC_SHIFT)
+#define S5P_CLK_MUX_STAT1_D0SYNC_SHIFT	(28)
+#define S5P_CLK_MUX_STAT1_D0SYNC_MASK	(0x7 << S5P_CLK_MUX_STAT1_D0SYNC_SHIFT)
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/regs-irq.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/regs-irq.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/regs-irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/regs-irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6442 - IRQ register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_IRQ_H
+#define __ASM_ARCH_REGS_IRQ_H __FILE__
+
+#include <asm/hardware/vic.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_REGS_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/system.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/system.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/system.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6442 - system support header
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H __FILE__
+
+static void arch_idle(void)
+{
+	/* nothing here yet */
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+	/* nothing here yet */
+}
+
+#endif /* __ASM_ARCH_SYSTEM_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/tick.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/tick.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/tick.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/tick.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/tick.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s3c6400/include/mach/tick.h
+ *
+ * S5P6442 - Timer tick support definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TICK_H
+#define __ASM_ARCH_TICK_H __FILE__
+
+static inline u32 s3c24xx_ostimer_pending(void)
+{
+	u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
+	return pend & (1 << (IRQ_TIMER4_VIC - S5P_IRQ_VIC0(0)));
+}
+
+#define TICK_MAX	(0xffffffff)
+
+#endif /* __ASM_ARCH_TICK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/timex.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/timex.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/timex.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s5p6442/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2010 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S5P6442 - time parameters
+ *
+ * This program is free software; you can 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_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/uncompress.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/uncompress.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/uncompress.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,24 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/uncompress.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P6442 - uncompress 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.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/map.h>
+#include <plat/uncompress.h>
+
+static void arch_detect_cpu(void)
+{
+	/* we do not need to do any cpu detection here at the moment. */
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,17 @@
+/* arch/arm/mach-s5p6442/include/mach/vmalloc.h
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.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.
+ *
+ * S5P6442 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END	  (0xE0000000)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/init.c linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/init.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/init.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,44 @@
+/* linux/arch/arm/mach-s5p6442/s5p6442-init.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/s5p6442.h>
+#include <plat/regs-serial.h>
+
+static struct s3c24xx_uart_clksrc s5p6442_serial_clocks[] = {
+	[0] = {
+		.name		= "pclk",
+		.divisor	= 1,
+		.min_baud	= 0,
+		.max_baud	= 0,
+	},
+};
+
+/* uart registration process */
+void __init s5p6442_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+	struct s3c2410_uartcfg *tcfg = cfg;
+	u32 ucnt;
+
+	for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
+		if (!tcfg->clocks) {
+			tcfg->clocks = s5p6442_serial_clocks;
+			tcfg->clocks_size = ARRAY_SIZE(s5p6442_serial_clocks);
+		}
+	}
+
+	s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,24 @@
+# arch/arm/mach-s5p6442/Kconfig
+#
+# Copyright (c) 2010 Samsung Electronics Co., Ltd.
+#		http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+# Configuration options for the S5P6442
+
+if ARCH_S5P6442
+
+config CPU_S5P6442
+	bool
+	select PLAT_S5P
+	help
+	  Enable S5P6442 CPU support
+
+config MACH_SMDK6442
+	bool "SMDK6442"
+	select CPU_S5P6442
+	help
+	  Machine support for Samsung SMDK6442
+
+endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/mach-smdk6442.c linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/mach-smdk6442.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/mach-smdk6442.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/mach-smdk6442.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,91 @@
+/* linux/arch/arm/mach-s5p6442/mach-smdk6442.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/regs-serial.h>
+#include <plat/s5p6442.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define S5P6442_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
+				 S3C2410_UCON_RXILEVEL |	\
+				 S3C2410_UCON_TXIRQMODE |	\
+				 S3C2410_UCON_RXIRQMODE |	\
+				 S3C2410_UCON_RXFIFO_TOI |	\
+				 S3C2443_UCON_RXERR_IRQEN)
+
+#define S5P6442_ULCON_DEFAULT	S3C2410_LCON_CS8
+
+#define S5P6442_UFCON_DEFAULT	(S3C2410_UFCON_FIFOMODE |	\
+				 S5PV210_UFCON_TXTRIG4 |	\
+				 S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdk6442_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport		= 0,
+		.flags		= 0,
+		.ucon		= S5P6442_UCON_DEFAULT,
+		.ulcon		= S5P6442_ULCON_DEFAULT,
+		.ufcon		= S5P6442_UFCON_DEFAULT,
+	},
+	[1] = {
+		.hwport		= 1,
+		.flags		= 0,
+		.ucon		= S5P6442_UCON_DEFAULT,
+		.ulcon		= S5P6442_ULCON_DEFAULT,
+		.ufcon		= S5P6442_UFCON_DEFAULT,
+	},
+	[2] = {
+		.hwport		= 2,
+		.flags		= 0,
+		.ucon		= S5P6442_UCON_DEFAULT,
+		.ulcon		= S5P6442_ULCON_DEFAULT,
+		.ufcon		= S5P6442_UFCON_DEFAULT,
+	},
+};
+
+static struct platform_device *smdk6442_devices[] __initdata = {
+};
+
+static void __init smdk6442_map_io(void)
+{
+	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+	s3c24xx_init_clocks(12000000);
+	s3c24xx_init_uarts(smdk6442_uartcfgs, ARRAY_SIZE(smdk6442_uartcfgs));
+}
+
+static void __init smdk6442_machine_init(void)
+{
+	platform_add_devices(smdk6442_devices, ARRAY_SIZE(smdk6442_devices));
+}
+
+MACHINE_START(SMDK6442, "SMDK6442")
+	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+	.phys_io	= S3C_PA_UART & 0xfff00000,
+	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S5P_PA_SDRAM + 0x100,
+	.init_irq	= s5p6442_init_irq,
+	.map_io		= smdk6442_map_io,
+	.init_machine	= smdk6442_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,19 @@
+# arch/arm/mach-s5p6442/Makefile
+#
+# Copyright (c) 2010 Samsung Electronics Co., Ltd.
+# 		http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:=
+obj-				:=
+
+# Core support for S5P6442 system
+
+obj-$(CONFIG_CPU_S5P6442)	+= cpu.o init.o clock.o
+
+# machine support
+
+obj-$(CONFIG_MACH_SMDK6442)	+= mach-smdk6442.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/Makefile.boot linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/Makefile.boot
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5p6442/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5p6442/Makefile.boot	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,2 @@
+   zreladdr-y	:= 0x20008000
+params_phys-y	:= 0x20000100
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-s5pc100/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pc100/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,7 @@
 	 * aligned and add in the offset when we load the value here.
 	 */
 
-	.macro addruart, rx
+	.macro addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1
 		ldreq	\rx, = S3C_PA_UART
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/gpio-core.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pc100/include/mach/gpio-core.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/gpio-core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pc100/include/mach/gpio-core.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,21 +0,0 @@
-/* arch/arm/mach-s5pc100/include/mach/gpio-core.h
- *
- * Copyright 2009 Samsung Electronics Co.
- *      Byungho Min <bhmin@samsung.com>
- *
- * S5PC100 - GPIO core support
- *
- * Based on mach-s3c6400/include/mach/gpio-core.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_ARCH_GPIO_CORE_H
-#define __ASM_ARCH_GPIO_CORE_H __FILE__
-
-/* currently we just include the platform support */
-#include <plat/gpio-core.h>
-
-#endif /* __ASM_ARCH_GPIO_CORE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/io.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pc100/include/mach/io.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pc100/include/mach/io.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s5pc100/include/mach/io.h
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S5PC100 systems
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a)		__typesafe_io(a)
+#define __mem_pci(a)	(a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/tick.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pc100/include/mach/tick.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/tick.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pc100/include/mach/tick.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,7 @@
 static inline u32 s3c24xx_ostimer_pending(void)
 {
 	u32 pend = __raw_readl(S3C_VA_VIC0 + VIC_RAW_STATUS);
-	return pend & 1 << (IRQ_TIMER4 - S5PC1XX_IRQ_VIC0(0));
+	return pend & 1 << (IRQ_TIMER4_VIC - S5PC1XX_IRQ_VIC0(0));
 }
 
 #define TICK_MAX	(0xffffffff)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/timex.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pc100/include/mach/timex.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pc100/include/mach/timex.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s5pc100/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C6400 - time parameters
+ *
+ * This program is free software; you can 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_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pc100/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pc100/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,17 @@
+/* arch/arm/mach-s5pc100/include/mach/vmalloc.h
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.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.
+ *
+ * S3C6400 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END	  (0xe0000000UL)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/setup-sdhci.c linux-libre-2.6.34-gnu1/arch/arm/mach-s5pc100/setup-sdhci.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/setup-sdhci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pc100/setup-sdhci.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,8 +28,8 @@
 char *s5pc100_hsmmc_clksrcs[4] = {
 	[0] = "hsmmc",
 	[1] = "hsmmc",
-	/* [2] = "mmc_bus", not yet succesfuuly used yet */
-	/* [3] = "48m", - note not succesfully used yet */
+	/* [2] = "mmc_bus", not yet successfully used yet */
+	/* [3] = "48m", - note not successfully used yet */
 };
 
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/clock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,454 @@
+/* linux/arch/arm/mach-s5pv210/clock.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5PV210 - Clock 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/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+
+#include <plat/cpu-freq.h>
+#include <mach/regs-clock.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5pv210.h>
+
+static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
+}
+
+static int s5pv210_clk_ip1_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLKGATE_IP1, clk, enable);
+}
+
+static int s5pv210_clk_ip2_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLKGATE_IP2, clk, enable);
+}
+
+static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
+}
+
+static struct clk clk_h200 = {
+	.name		= "hclk200",
+	.id		= -1,
+};
+
+static struct clk clk_h100 = {
+	.name		= "hclk100",
+	.id		= -1,
+};
+
+static struct clk clk_h166 = {
+	.name		= "hclk166",
+	.id		= -1,
+};
+
+static struct clk clk_h133 = {
+	.name		= "hclk133",
+	.id		= -1,
+};
+
+static struct clk clk_p100 = {
+	.name		= "pclk100",
+	.id		= -1,
+};
+
+static struct clk clk_p83 = {
+	.name		= "pclk83",
+	.id		= -1,
+};
+
+static struct clk clk_p66 = {
+	.name		= "pclk66",
+	.id		= -1,
+};
+
+static struct clk *sys_clks[] = {
+	&clk_h200,
+	&clk_h100,
+	&clk_h166,
+	&clk_h133,
+	&clk_p100,
+	&clk_p83,
+	&clk_p66
+};
+
+static struct clk init_clocks_disable[] = {
+	{
+		.name		= "rot",
+		.id		= -1,
+		.parent		= &clk_h166,
+		.enable		= s5pv210_clk_ip0_ctrl,
+		.ctrlbit	= (1<<29),
+	}, {
+		.name		= "otg",
+		.id		= -1,
+		.parent		= &clk_h133,
+		.enable		= s5pv210_clk_ip1_ctrl,
+		.ctrlbit	= (1<<16),
+	}, {
+		.name		= "usb-host",
+		.id		= -1,
+		.parent		= &clk_h133,
+		.enable		= s5pv210_clk_ip1_ctrl,
+		.ctrlbit	= (1<<17),
+	}, {
+		.name		= "lcd",
+		.id		= -1,
+		.parent		= &clk_h166,
+		.enable		= s5pv210_clk_ip1_ctrl,
+		.ctrlbit	= (1<<0),
+	}, {
+		.name		= "cfcon",
+		.id		= 0,
+		.parent		= &clk_h133,
+		.enable		= s5pv210_clk_ip1_ctrl,
+		.ctrlbit	= (1<<25),
+	}, {
+		.name		= "hsmmc",
+		.id		= 0,
+		.parent		= &clk_h133,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1<<16),
+	}, {
+		.name		= "hsmmc",
+		.id		= 1,
+		.parent		= &clk_h133,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1<<17),
+	}, {
+		.name		= "hsmmc",
+		.id		= 2,
+		.parent		= &clk_h133,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1<<18),
+	}, {
+		.name		= "hsmmc",
+		.id		= 3,
+		.parent		= &clk_h133,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1<<19),
+	}, {
+		.name		= "systimer",
+		.id		= -1,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<16),
+	}, {
+		.name		= "watchdog",
+		.id		= -1,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<22),
+	}, {
+		.name		= "rtc",
+		.id		= -1,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<15),
+	}, {
+		.name		= "i2c",
+		.id		= 0,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<7),
+	}, {
+		.name		= "i2c",
+		.id		= 1,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<8),
+	}, {
+		.name		= "i2c",
+		.id		= 2,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<9),
+	}, {
+		.name		= "spi",
+		.id		= 0,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<12),
+	}, {
+		.name		= "spi",
+		.id		= 1,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<13),
+	}, {
+		.name		= "spi",
+		.id		= 2,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<14),
+	}, {
+		.name		= "timers",
+		.id		= -1,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<23),
+	}, {
+		.name		= "adc",
+		.id		= -1,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<24),
+	}, {
+		.name		= "keypad",
+		.id		= -1,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<21),
+	}, {
+		.name		= "i2s_v50",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<4),
+	}, {
+		.name		= "i2s_v32",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<4),
+	}, {
+		.name		= "i2s_v32",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<4),
+	}
+};
+
+static struct clk init_clocks[] = {
+	{
+		.name		= "uart",
+		.id		= 0,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<7),
+	}, {
+		.name		= "uart",
+		.id		= 1,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<8),
+	}, {
+		.name		= "uart",
+		.id		= 2,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<9),
+	}, {
+		.name		= "uart",
+		.id		= 3,
+		.parent		= &clk_p66,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1<<10),
+	},
+};
+
+static struct clksrc_clk clk_mout_apll = {
+	.clk	= {
+		.name		= "mout_apll",
+		.id		= -1,
+	},
+	.sources	= &clk_src_apll,
+	.reg_src	= { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_epll = {
+	.clk	= {
+		.name		= "mout_epll",
+		.id		= -1,
+	},
+	.sources	= &clk_src_epll,
+	.reg_src	= { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_mpll = {
+	.clk = {
+		.name		= "mout_mpll",
+		.id		= -1,
+	},
+	.sources	= &clk_src_mpll,
+	.reg_src	= { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
+};
+
+static struct clk *clkset_uart_list[] = {
+	[6] = &clk_mout_mpll.clk,
+	[7] = &clk_mout_epll.clk,
+};
+
+static struct clksrc_sources clkset_uart = {
+	.sources	= clkset_uart_list,
+	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clksrc_clk clksrcs[] = {
+	{
+		.clk	= {
+			.name		= "uclk1",
+			.id		= -1,
+			.ctrlbit	= (1<<17),
+			.enable		= s5pv210_clk_ip3_ctrl,
+		},
+		.sources = &clkset_uart,
+		.reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
+		.reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
+	}
+};
+
+/* Clock initialisation code */
+static struct clksrc_clk *init_parents[] = {
+	&clk_mout_apll,
+	&clk_mout_epll,
+	&clk_mout_mpll,
+};
+
+#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
+
+void __init_or_cpufreq s5pv210_setup_clocks(void)
+{
+	struct clk *xtal_clk;
+	unsigned long xtal;
+	unsigned long armclk;
+	unsigned long hclk200;
+	unsigned long hclk166;
+	unsigned long hclk133;
+	unsigned long pclk100;
+	unsigned long pclk83;
+	unsigned long pclk66;
+	unsigned long apll;
+	unsigned long mpll;
+	unsigned long epll;
+	unsigned int ptr;
+	u32 clkdiv0, clkdiv1;
+
+	printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+	clkdiv0 = __raw_readl(S5P_CLK_DIV0);
+	clkdiv1 = __raw_readl(S5P_CLK_DIV1);
+
+	printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
+				__func__, clkdiv0, clkdiv1);
+
+	xtal_clk = clk_get(NULL, "xtal");
+	BUG_ON(IS_ERR(xtal_clk));
+
+	xtal = clk_get_rate(xtal_clk);
+	clk_put(xtal_clk);
+
+	printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+	apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
+	mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
+	epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500);
+
+	printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld",
+			apll, mpll, epll);
+
+	armclk = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_APLL);
+	if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX200_MASK)
+		hclk200 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK200);
+	else
+		hclk200 = armclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK200);
+
+	if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX166_MASK) {
+		hclk166 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M);
+		hclk166 = hclk166 / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK166);
+	} else
+		hclk166 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK166);
+
+	if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX133_MASK) {
+		hclk133 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M);
+		hclk133 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133);
+	} else
+		hclk133 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133);
+
+	pclk100 = hclk200 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK100);
+	pclk83 = hclk166 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK83);
+	pclk66 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK66);
+
+	printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld, \
+			HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
+	       armclk, hclk200, hclk166, hclk133, pclk100, pclk83, pclk66);
+
+	clk_fout_apll.rate = apll;
+	clk_fout_mpll.rate = mpll;
+	clk_fout_epll.rate = epll;
+
+	clk_f.rate = armclk;
+	clk_h.rate = hclk133;
+	clk_p.rate = pclk66;
+	clk_p66.rate = pclk66;
+	clk_p83.rate = pclk83;
+	clk_h133.rate = hclk133;
+	clk_h166.rate = hclk166;
+	clk_h200.rate = hclk200;
+
+	for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
+		s3c_set_clksrc(init_parents[ptr], true);
+
+	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+		s3c_set_clksrc(&clksrcs[ptr], true);
+}
+
+static struct clk *clks[] __initdata = {
+	&clk_mout_epll.clk,
+	&clk_mout_mpll.clk,
+};
+
+void __init s5pv210_register_clocks(void)
+{
+	struct clk *clkp;
+	int ret;
+	int ptr;
+
+	ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+	if (ret > 0)
+		printk(KERN_ERR "Failed to register %u clocks\n", ret);
+
+	s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+	s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+	ret = s3c24xx_register_clocks(sys_clks, ARRAY_SIZE(sys_clks));
+	if (ret > 0)
+		printk(KERN_ERR "Failed to register system clocks\n");
+
+	clkp = init_clocks_disable;
+	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+		(clkp->enable)(clkp, 0);
+	}
+
+	s3c_pwmclk_init();
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/cpu.c linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/cpu.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/cpu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/cpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,126 @@
+/* linux/arch/arm/mach-s5pv210/cpu.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/proc-fns.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/s5pv210.h>
+
+/* Initial IO mappings */
+
+static struct map_desc s5pv210_iodesc[] __initdata = {
+	{
+		.virtual	= (unsigned long)S5P_VA_SYSTIMER,
+		.pfn		= __phys_to_pfn(S5PV210_PA_SYSTIMER),
+		.length		= SZ_1M,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)VA_VIC2,
+		.pfn		= __phys_to_pfn(S5PV210_PA_VIC2),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)VA_VIC3,
+		.pfn		= __phys_to_pfn(S5PV210_PA_VIC3),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S5P_VA_SROMC,
+		.pfn		= __phys_to_pfn(S5PV210_PA_SROMC),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}
+};
+
+static void s5pv210_idle(void)
+{
+	if (!need_resched())
+		cpu_do_idle();
+
+	local_irq_enable();
+}
+
+/* s5pv210_map_io
+ *
+ * register the standard cpu IO areas
+*/
+
+void __init s5pv210_map_io(void)
+{
+	iotable_init(s5pv210_iodesc, ARRAY_SIZE(s5pv210_iodesc));
+}
+
+void __init s5pv210_init_clocks(int xtal)
+{
+	printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+	s3c24xx_register_baseclocks(xtal);
+	s5p_register_clocks(xtal);
+	s5pv210_register_clocks();
+	s5pv210_setup_clocks();
+}
+
+void __init s5pv210_init_irq(void)
+{
+	u32 vic[4];	/* S5PV210 supports 4 VIC */
+
+	/* All the VICs are fully populated. */
+	vic[0] = ~0;
+	vic[1] = ~0;
+	vic[2] = ~0;
+	vic[3] = ~0;
+
+	s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+static struct sysdev_class s5pv210_sysclass = {
+	.name	= "s5pv210-core",
+};
+
+static struct sys_device s5pv210_sysdev = {
+	.cls	= &s5pv210_sysclass,
+};
+
+static int __init s5pv210_core_init(void)
+{
+	return sysdev_class_register(&s5pv210_sysclass);
+}
+
+core_initcall(s5pv210_core_init);
+
+int __init s5pv210_init(void)
+{
+	printk(KERN_INFO "S5PV210: Initializing architecture\n");
+
+	/* set idle function */
+	pm_idle = s5pv210_idle;
+
+	return sysdev_register(&s5pv210_sysdev);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,42 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/debug-macro.S
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s3c6400/include/mach/debug-macro.S
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <mach/map.h>
+#include <plat/regs-serial.h>
+
+	/* note, for the boot process to work we have to keep the UART
+	 * virtual address aligned to an 1MiB boundary for the L1
+	 * mapping the head code makes. We keep the UART virtual address
+	 * aligned and add in the offset when we load the value here.
+	 */
+
+	.macro addruart, rx, tmp
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1
+		ldreq	\rx, = S3C_PA_UART
+		ldrne	\rx, = S3C_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+		add	\rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
+#endif
+	.endm
+
+#define fifo_full fifo_full_s5pv210
+#define fifo_level fifo_level_s5pv210
+
+/* include the reset of the code which will do the work, we're only
+ * compiling for a single cpu processor type so the default of s3c2440
+ * will be fine with us.
+ */
+
+#include <plat/debug-macro.S>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/entry-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/entry-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/entry-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,54 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/entry-macro.S
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Low-level IRQ helper macros for the Samsung S5PV210
+ *
+ * This program is free software; you can 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/hardware/vic.h>
+#include <mach/map.h>
+#include <plat/irqs.h>
+
+	.macro	disable_fiq
+	.endm
+
+	.macro	get_irqnr_preamble, base, tmp
+	ldr	\base, =VA_VIC0
+	.endm
+
+	.macro	arch_ret_to_user, tmp1, tmp2
+	.endm
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+	@ check the vic0
+	mov	\irqnr, # S5P_IRQ_OFFSET + 31
+	ldr	\irqstat, [ \base, # VIC_IRQ_STATUS ]
+	teq	\irqstat, #0
+
+	@ otherwise try vic1
+	addeq	\tmp, \base, #(VA_VIC1 - VA_VIC0)
+	addeq	\irqnr, \irqnr, #32
+	ldreq	\irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+	teqeq	\irqstat, #0
+
+	@ otherwise try vic2
+	addeq	\tmp, \base, #(VA_VIC2 - VA_VIC0)
+	addeq	\irqnr, \irqnr, #32
+	ldreq	\irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+	teqeq	\irqstat, #0
+
+	@ otherwise try vic3
+	addeq	\tmp, \base, #(VA_VIC3 - VA_VIC0)
+	addeq	\irqnr, \irqnr, #32
+	ldreq	\irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+	teqeq	\irqstat, #0
+
+	clzne	\irqstat, \irqstat
+	subne	\irqnr, \irqnr, \irqstat
+	.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/gpio.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/gpio.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/gpio.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,129 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/gpio.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5PV210 - GPIO lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H __FILE__
+
+#define gpio_get_value	__gpio_get_value
+#define gpio_set_value	__gpio_set_value
+#define gpio_cansleep	__gpio_cansleep
+#define gpio_to_irq	__gpio_to_irq
+
+/* GPIO bank sizes */
+#define S5PV210_GPIO_A0_NR	(8)
+#define S5PV210_GPIO_A1_NR	(4)
+#define S5PV210_GPIO_B_NR	(8)
+#define S5PV210_GPIO_C0_NR	(5)
+#define S5PV210_GPIO_C1_NR	(5)
+#define S5PV210_GPIO_D0_NR	(4)
+#define S5PV210_GPIO_D1_NR	(6)
+#define S5PV210_GPIO_E0_NR	(8)
+#define S5PV210_GPIO_E1_NR	(5)
+#define S5PV210_GPIO_F0_NR	(8)
+#define S5PV210_GPIO_F1_NR	(8)
+#define S5PV210_GPIO_F2_NR	(8)
+#define S5PV210_GPIO_F3_NR	(6)
+#define S5PV210_GPIO_G0_NR	(7)
+#define S5PV210_GPIO_G1_NR	(7)
+#define S5PV210_GPIO_G2_NR	(7)
+#define S5PV210_GPIO_G3_NR	(7)
+#define S5PV210_GPIO_H0_NR	(8)
+#define S5PV210_GPIO_H1_NR	(8)
+#define S5PV210_GPIO_H2_NR	(8)
+#define S5PV210_GPIO_H3_NR	(8)
+#define S5PV210_GPIO_I_NR	(7)
+#define S5PV210_GPIO_J0_NR	(8)
+#define S5PV210_GPIO_J1_NR	(6)
+#define S5PV210_GPIO_J2_NR	(8)
+#define S5PV210_GPIO_J3_NR	(8)
+#define S5PV210_GPIO_J4_NR	(5)
+
+/* GPIO bank numbers */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+
+#define S5PV210_GPIO_NEXT(__gpio) \
+	((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s5p_gpio_number {
+	S5PV210_GPIO_A0_START	= 0,
+	S5PV210_GPIO_A1_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_A0),
+	S5PV210_GPIO_B_START 	= S5PV210_GPIO_NEXT(S5PV210_GPIO_A1),
+	S5PV210_GPIO_C0_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_B),
+	S5PV210_GPIO_C1_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_C0),
+	S5PV210_GPIO_D0_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_C1),
+	S5PV210_GPIO_D1_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_D0),
+	S5PV210_GPIO_E0_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_D1),
+	S5PV210_GPIO_E1_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_E0),
+	S5PV210_GPIO_F0_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_E1),
+	S5PV210_GPIO_F1_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_F0),
+	S5PV210_GPIO_F2_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_F1),
+	S5PV210_GPIO_F3_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_F2),
+	S5PV210_GPIO_G0_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_F3),
+	S5PV210_GPIO_G1_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_G0),
+	S5PV210_GPIO_G2_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_G1),
+	S5PV210_GPIO_G3_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_G2),
+	S5PV210_GPIO_H0_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_G3),
+	S5PV210_GPIO_H1_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_H0),
+	S5PV210_GPIO_H2_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_H1),
+	S5PV210_GPIO_H3_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_H2),
+	S5PV210_GPIO_I_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_H3),
+	S5PV210_GPIO_J0_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_I),
+	S5PV210_GPIO_J1_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_J0),
+	S5PV210_GPIO_J2_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_J1),
+	S5PV210_GPIO_J3_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_J2),
+	S5PV210_GPIO_J4_START	= S5PV210_GPIO_NEXT(S5PV210_GPIO_J3),
+};
+
+/* S5PV210 GPIO number definitions */
+#define S5PV210_GPA0(_nr)	(S5PV210_GPIO_A0_START + (_nr))
+#define S5PV210_GPA1(_nr)	(S5PV210_GPIO_A1_START + (_nr))
+#define S5PV210_GPB(_nr)	(S5PV210_GPIO_B_START + (_nr))
+#define S5PV210_GPC0(_nr)	(S5PV210_GPIO_C0_START + (_nr))
+#define S5PV210_GPC1(_nr)	(S5PV210_GPIO_C1_START + (_nr))
+#define S5PV210_GPD0(_nr)	(S5PV210_GPIO_D0_START + (_nr))
+#define S5PV210_GPD1(_nr)	(S5PV210_GPIO_D1_START + (_nr))
+#define S5PV210_GPE0(_nr)	(S5PV210_GPIO_E0_START + (_nr))
+#define S5PV210_GPE1(_nr)	(S5PV210_GPIO_E1_START + (_nr))
+#define S5PV210_GPF0(_nr)	(S5PV210_GPIO_F0_START + (_nr))
+#define S5PV210_GPF1(_nr)	(S5PV210_GPIO_F1_START + (_nr))
+#define S5PV210_GPF2(_nr)	(S5PV210_GPIO_F2_START + (_nr))
+#define S5PV210_GPF3(_nr)	(S5PV210_GPIO_F3_START + (_nr))
+#define S5PV210_GPG0(_nr)	(S5PV210_GPIO_G0_START + (_nr))
+#define S5PV210_GPG1(_nr)	(S5PV210_GPIO_G1_START + (_nr))
+#define S5PV210_GPG2(_nr)	(S5PV210_GPIO_G2_START + (_nr))
+#define S5PV210_GPG3(_nr)	(S5PV210_GPIO_G3_START + (_nr))
+#define S5PV210_GPH0(_nr)	(S5PV210_GPIO_H0_START + (_nr))
+#define S5PV210_GPH1(_nr)	(S5PV210_GPIO_H1_START + (_nr))
+#define S5PV210_GPH2(_nr)	(S5PV210_GPIO_H2_START + (_nr))
+#define S5PV210_GPH3(_nr)	(S5PV210_GPIO_H3_START + (_nr))
+#define S5PV210_GPI(_nr)	(S5PV210_GPIO_I_START + (_nr))
+#define S5PV210_GPJ0(_nr)	(S5PV210_GPIO_J0_START + (_nr))
+#define S5PV210_GPJ1(_nr)	(S5PV210_GPIO_J1_START + (_nr))
+#define S5PV210_GPJ2(_nr)	(S5PV210_GPIO_J2_START + (_nr))
+#define S5PV210_GPJ3(_nr)	(S5PV210_GPIO_J3_START + (_nr))
+#define S5PV210_GPJ4(_nr)	(S5PV210_GPIO_J4_START + (_nr))
+
+/* the end of the S5PV210 specific gpios */
+#define S5PV210_GPIO_END	(S5PV210_GPJ4(S5PV210_GPIO_J4_NR) + 1)
+#define S3C_GPIO_END		S5PV210_GPIO_END
+
+/* define the number of gpios we need to the one after the GPJ4() range */
+#define ARCH_NR_GPIOS		(S5PV210_GPJ4(S5PV210_GPIO_J4_NR) +	\
+				 CONFIG_SAMSUNG_GPIO_EXTRA + 1)
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/hardware.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/hardware.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/hardware.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,18 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/hardware.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5PV210 - Hardware support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H __FILE__
+
+/* currently nothing here, placeholder */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/io.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/io.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/io.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/io.h
+ *
+ * Copyright 2008-2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s5p6442/include/mach/io.h
+ *
+ * Default IO routines for S5PV210
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H __FILE__
+
+/* No current ISA/PCI bus support. */
+#define __io(a)		__typesafe_io(a)
+#define __mem_pci(a)	(a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif /* __ASM_ARM_ARCH_IO_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/irqs.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/irqs.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/irqs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,146 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/irqs.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5PV210 - IRQ definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H __FILE__
+
+#include <plat/irqs.h>
+
+/* VIC0: System, DMA, Timer */
+
+#define IRQ_EINT0		S5P_IRQ_VIC0(0)
+#define IRQ_EINT1		S5P_IRQ_VIC0(1)
+#define IRQ_EINT2		S5P_IRQ_VIC0(2)
+#define IRQ_EINT3		S5P_IRQ_VIC0(3)
+#define IRQ_EINT4		S5P_IRQ_VIC0(4)
+#define IRQ_EINT5		S5P_IRQ_VIC0(5)
+#define IRQ_EINT6		S5P_IRQ_VIC0(6)
+#define IRQ_EINT7		S5P_IRQ_VIC0(7)
+#define IRQ_EINT8		S5P_IRQ_VIC0(8)
+#define IRQ_EINT9		S5P_IRQ_VIC0(9)
+#define IRQ_EINT10		S5P_IRQ_VIC0(10)
+#define IRQ_EINT11		S5P_IRQ_VIC0(11)
+#define IRQ_EINT12		S5P_IRQ_VIC0(12)
+#define IRQ_EINT13		S5P_IRQ_VIC0(13)
+#define IRQ_EINT14		S5P_IRQ_VIC0(14)
+#define IRQ_EINT15		S5P_IRQ_VIC0(15)
+#define IRQ_EINT16_31		S5P_IRQ_VIC0(16)
+#define IRQ_BATF		S5P_IRQ_VIC0(17)
+#define IRQ_MDMA		S5P_IRQ_VIC0(18)
+#define IRQ_PDMA0		S5P_IRQ_VIC0(19)
+#define IRQ_PDMA1		S5P_IRQ_VIC0(20)
+#define IRQ_TIMER0_VIC		S5P_IRQ_VIC0(21)
+#define IRQ_TIMER1_VIC		S5P_IRQ_VIC0(22)
+#define IRQ_TIMER2_VIC		S5P_IRQ_VIC0(23)
+#define IRQ_TIMER3_VIC		S5P_IRQ_VIC0(24)
+#define IRQ_TIMER4_VIC		S5P_IRQ_VIC0(25)
+#define IRQ_SYSTIMER		S5P_IRQ_VIC0(26)
+#define IRQ_WDT			S5P_IRQ_VIC0(27)
+#define IRQ_RTC_ALARM		S5P_IRQ_VIC0(28)
+#define IRQ_RTC_TIC		S5P_IRQ_VIC0(29)
+#define IRQ_GPIOINT		S5P_IRQ_VIC0(30)
+#define IRQ_FIMC3		S5P_IRQ_VIC0(31)
+
+/* VIC1: ARM, Power, Memory, Connectivity, Storage */
+
+#define IRQ_CORTEX0		S5P_IRQ_VIC1(0)
+#define IRQ_CORTEX1		S5P_IRQ_VIC1(1)
+#define IRQ_CORTEX2		S5P_IRQ_VIC1(2)
+#define IRQ_CORTEX3		S5P_IRQ_VIC1(3)
+#define IRQ_CORTEX4		S5P_IRQ_VIC1(4)
+#define IRQ_IEMAPC		S5P_IRQ_VIC1(5)
+#define IRQ_IEMIEC		S5P_IRQ_VIC1(6)
+#define IRQ_ONENAND		S5P_IRQ_VIC1(7)
+#define IRQ_NFC			S5P_IRQ_VIC1(8)
+#define IRQ_CFC			S5P_IRQ_VIC1(9)
+#define IRQ_UART0		S5P_IRQ_VIC1(10)
+#define IRQ_UART1		S5P_IRQ_VIC1(11)
+#define IRQ_UART2		S5P_IRQ_VIC1(12)
+#define IRQ_UART3		S5P_IRQ_VIC1(13)
+#define IRQ_IIC			S5P_IRQ_VIC1(14)
+#define IRQ_SPI0		S5P_IRQ_VIC1(15)
+#define IRQ_SPI1		S5P_IRQ_VIC1(16)
+#define IRQ_SPI2		S5P_IRQ_VIC1(17)
+#define IRQ_IRDA		S5P_IRQ_VIC1(18)
+#define IRQ_CAN0		S5P_IRQ_VIC1(19)
+#define IRQ_CAN1		S5P_IRQ_VIC1(20)
+#define IRQ_HSIRX		S5P_IRQ_VIC1(21)
+#define IRQ_HSITX		S5P_IRQ_VIC1(22)
+#define IRQ_UHOST		S5P_IRQ_VIC1(23)
+#define IRQ_OTG			S5P_IRQ_VIC1(24)
+#define IRQ_MSM			S5P_IRQ_VIC1(25)
+#define IRQ_HSMMC0		S5P_IRQ_VIC1(26)
+#define IRQ_HSMMC1		S5P_IRQ_VIC1(27)
+#define IRQ_HSMMC2		S5P_IRQ_VIC1(28)
+#define IRQ_MIPICSI		S5P_IRQ_VIC1(29)
+#define IRQ_MIPIDSI		S5P_IRQ_VIC1(30)
+#define IRQ_ONENAND_AUDI	S5P_IRQ_VIC1(31)
+
+/* VIC2: Multimedia, Audio, Security */
+
+#define IRQ_LCD0		S5P_IRQ_VIC2(0)
+#define IRQ_LCD1		S5P_IRQ_VIC2(1)
+#define IRQ_LCD2		S5P_IRQ_VIC2(2)
+#define IRQ_LCD3		S5P_IRQ_VIC2(3)
+#define IRQ_ROTATOR		S5P_IRQ_VIC2(4)
+#define IRQ_FIMC0		S5P_IRQ_VIC2(5)
+#define IRQ_FIMC1		S5P_IRQ_VIC2(6)
+#define IRQ_FIMC2		S5P_IRQ_VIC2(7)
+#define IRQ_JPEG		S5P_IRQ_VIC2(8)
+#define IRQ_2D			S5P_IRQ_VIC2(9)
+#define IRQ_3D			S5P_IRQ_VIC2(10)
+#define IRQ_MIXER		S5P_IRQ_VIC2(11)
+#define IRQ_HDMI		S5P_IRQ_VIC2(12)
+#define IRQ_IIC1		S5P_IRQ_VIC2(13)
+#define IRQ_MFC			S5P_IRQ_VIC2(14)
+#define IRQ_TVENC		S5P_IRQ_VIC2(15)
+#define IRQ_I2S0		S5P_IRQ_VIC2(16)
+#define IRQ_I2S1		S5P_IRQ_VIC2(17)
+#define IRQ_I2S2		S5P_IRQ_VIC2(18)
+#define IRQ_AC97		S5P_IRQ_VIC2(19)
+#define IRQ_PCM0		S5P_IRQ_VIC2(20)
+#define IRQ_PCM1		S5P_IRQ_VIC2(21)
+#define IRQ_SPDIF		S5P_IRQ_VIC2(22)
+#define IRQ_ADC			S5P_IRQ_VIC2(23)
+#define IRQ_PENDN		S5P_IRQ_VIC2(24)
+#define IRQ_TC			IRQ_PENDN
+#define IRQ_KEYPAD		S5P_IRQ_VIC2(25)
+#define IRQ_CG			S5P_IRQ_VIC2(26)
+#define IRQ_SEC			S5P_IRQ_VIC2(27)
+#define IRQ_SECRX		S5P_IRQ_VIC2(28)
+#define IRQ_SECTX		S5P_IRQ_VIC2(29)
+#define IRQ_SDMIRQ		S5P_IRQ_VIC2(30)
+#define IRQ_SDMFIQ		S5P_IRQ_VIC2(31)
+
+/* VIC3: Etc */
+
+#define IRQ_IPC			S5P_IRQ_VIC3(0)
+#define IRQ_HOSTIF		S5P_IRQ_VIC3(1)
+#define IRQ_MMC3		S5P_IRQ_VIC3(2)
+#define IRQ_CEC			S5P_IRQ_VIC3(3)
+#define IRQ_TSI			S5P_IRQ_VIC3(4)
+#define IRQ_MDNIE0		S5P_IRQ_VIC3(5)
+#define IRQ_MDNIE1		S5P_IRQ_VIC3(6)
+#define IRQ_MDNIE2		S5P_IRQ_VIC3(7)
+#define IRQ_MDNIE3		S5P_IRQ_VIC3(8)
+#define IRQ_VIC_END		S5P_IRQ_VIC3(31)
+
+#define S5P_IRQ_EINT_BASE	(IRQ_VIC_END + 1)
+
+#define S5P_EINT(x)		((x) + S5P_IRQ_EINT_BASE)
+#define IRQ_EINT(x)		S5P_EINT(x)
+
+/* Set the default NR_IRQS */
+
+#define NR_IRQS 		(IRQ_EINT(31) + 1)
+
+#endif /* ASM_ARCH_IRQS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/map.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/map.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/map.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/map.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,65 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/map.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5PV210 - Memory 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_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+#define S5PV210_PA_CHIPID	(0xE0000000)
+#define S5P_PA_CHIPID		S5PV210_PA_CHIPID
+
+#define S5PV210_PA_SYSCON	(0xE0100000)
+#define S5P_PA_SYSCON		S5PV210_PA_SYSCON
+
+#define S5PV210_PA_GPIO		(0xE0200000)
+#define S5P_PA_GPIO		S5PV210_PA_GPIO
+
+#define S5PV210_PA_IIC0		(0xE1800000)
+
+#define S5PV210_PA_TIMER	(0xE2500000)
+#define S5P_PA_TIMER		S5PV210_PA_TIMER
+
+#define S5PV210_PA_SYSTIMER	(0xE2600000)
+
+#define S5PV210_PA_UART		(0xE2900000)
+
+#define S5P_PA_UART0		(S5PV210_PA_UART + 0x0)
+#define S5P_PA_UART1		(S5PV210_PA_UART + 0x400)
+#define S5P_PA_UART2		(S5PV210_PA_UART + 0x800)
+#define S5P_PA_UART3		(S5PV210_PA_UART + 0xC00)
+
+#define S5P_SZ_UART		SZ_256
+
+#define S5PV210_PA_SROMC	(0xE8000000)
+
+#define S5PV210_PA_VIC0		(0xF2000000)
+#define S5P_PA_VIC0		S5PV210_PA_VIC0
+
+#define S5PV210_PA_VIC1		(0xF2100000)
+#define S5P_PA_VIC1		S5PV210_PA_VIC1
+
+#define S5PV210_PA_VIC2		(0xF2200000)
+#define S5P_PA_VIC2		S5PV210_PA_VIC2
+
+#define S5PV210_PA_VIC3		(0xF2300000)
+#define S5P_PA_VIC3		S5PV210_PA_VIC3
+
+#define S5PV210_PA_SDRAM	(0x20000000)
+#define S5P_PA_SDRAM		S5PV210_PA_SDRAM
+
+/* compatibiltiy defines. */
+#define S3C_PA_UART		S5PV210_PA_UART
+#define S3C_PA_IIC		S5PV210_PA_IIC0
+
+#endif /* __ASM_ARCH_MAP_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/memory.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/memory.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/memory.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,23 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/memory.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5PV210 - Memory definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET		UL(0x20000000)
+#define CONSISTENT_DMA_SIZE	(SZ_8M + SZ_4M + SZ_2M)
+
+/* Maximum of 256MiB in one bank */
+#define MAX_PHYSMEM_BITS	32
+#define SECTION_SIZE_BITS	28
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/pwm-clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/pwm-clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/pwm-clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,69 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
+ *
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Based on arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
+ *
+ * S5PV210 - pwm clock and timer support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_PWMCLK_H
+#define __ASM_ARCH_PWMCLK_H __FILE__
+
+/**
+ * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
+ * @cfg: The timer TCFG1 register bits shifted down to 0.
+ *
+ * Return true if the given configuration from TCFG1 is a TCLK instead
+ * any of the TDIV clocks.
+ */
+static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
+{
+	return tcfg == S3C2410_TCFG1_MUX_TCLK;
+}
+
+/**
+ * tcfg_to_divisor() - convert tcfg1 setting to a divisor
+ * @tcfg1: The tcfg1 setting, shifted down.
+ *
+ * Get the divisor value for the given tcfg1 setting. We assume the
+ * caller has already checked to see if this is not a TCLK source.
+ */
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+	return 1 << (1 + tcfg1);
+}
+
+/**
+ * pwm_tdiv_has_div1() - does the tdiv setting have a /1
+ *
+ * Return true if we have a /1 in the tdiv setting.
+ */
+static inline unsigned int pwm_tdiv_has_div1(void)
+{
+	return 0;
+}
+
+/**
+ * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
+ * @div: The divisor to calculate the bit information for.
+ *
+ * Turn a divisor into the necessary bit field for TCFG1.
+ */
+static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
+{
+	return ilog2(div) - 1;
+}
+
+#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
+
+#endif /* __ASM_ARCH_PWMCLK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/regs-clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/regs-clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/regs-clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/regs-clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,169 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5PV210 - Clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_CLKREG(x)		(S3C_VA_SYS + (x))
+
+#define S5P_APLL_LOCK		S5P_CLKREG(0x00)
+#define S5P_MPLL_LOCK		S5P_CLKREG(0x08)
+#define S5P_EPLL_LOCK		S5P_CLKREG(0x10)
+#define S5P_VPLL_LOCK		S5P_CLKREG(0x20)
+
+#define S5P_APLL_CON		S5P_CLKREG(0x100)
+#define S5P_MPLL_CON		S5P_CLKREG(0x108)
+#define S5P_EPLL_CON		S5P_CLKREG(0x110)
+#define S5P_VPLL_CON		S5P_CLKREG(0x120)
+
+#define S5P_CLK_SRC0		S5P_CLKREG(0x200)
+#define S5P_CLK_SRC1		S5P_CLKREG(0x204)
+#define S5P_CLK_SRC2		S5P_CLKREG(0x208)
+#define S5P_CLK_SRC3		S5P_CLKREG(0x20C)
+#define S5P_CLK_SRC4		S5P_CLKREG(0x210)
+#define S5P_CLK_SRC5		S5P_CLKREG(0x214)
+#define S5P_CLK_SRC6		S5P_CLKREG(0x218)
+
+#define S5P_CLK_SRC_MASK0	S5P_CLKREG(0x280)
+#define S5P_CLK_SRC_MASK1	S5P_CLKREG(0x284)
+
+#define S5P_CLK_DIV0		S5P_CLKREG(0x300)
+#define S5P_CLK_DIV1		S5P_CLKREG(0x304)
+#define S5P_CLK_DIV2		S5P_CLKREG(0x308)
+#define S5P_CLK_DIV3		S5P_CLKREG(0x30C)
+#define S5P_CLK_DIV4		S5P_CLKREG(0x310)
+#define S5P_CLK_DIV5		S5P_CLKREG(0x314)
+#define S5P_CLK_DIV6		S5P_CLKREG(0x318)
+#define S5P_CLK_DIV7		S5P_CLKREG(0x31C)
+
+#define S5P_CLKGATE_MAIN0	S5P_CLKREG(0x400)
+#define S5P_CLKGATE_MAIN1	S5P_CLKREG(0x404)
+#define S5P_CLKGATE_MAIN2	S5P_CLKREG(0x408)
+
+#define S5P_CLKGATE_PERI0	S5P_CLKREG(0x420)
+#define S5P_CLKGATE_PERI1	S5P_CLKREG(0x424)
+
+#define S5P_CLKGATE_SCLK0	S5P_CLKREG(0x440)
+#define S5P_CLKGATE_SCLK1	S5P_CLKREG(0x444)
+#define S5P_CLKGATE_IP0		S5P_CLKREG(0x460)
+#define S5P_CLKGATE_IP1		S5P_CLKREG(0x464)
+#define S5P_CLKGATE_IP2		S5P_CLKREG(0x468)
+#define S5P_CLKGATE_IP3		S5P_CLKREG(0x46C)
+#define S5P_CLKGATE_IP4		S5P_CLKREG(0x470)
+
+#define S5P_CLKGATE_BLOCK	S5P_CLKREG(0x480)
+#define S5P_CLKGATE_BUS0	S5P_CLKREG(0x484)
+#define S5P_CLKGATE_BUS1	S5P_CLKREG(0x488)
+#define S5P_CLK_OUT		S5P_CLKREG(0x500)
+
+/* CLKSRC0 */
+#define S5P_CLKSRC0_MUX200_MASK		(0x1<<16)
+#define S5P_CLKSRC0_MUX166_MASK		(0x1<<20)
+#define S5P_CLKSRC0_MUX133_MASK		(0x1<<24)
+
+/* CLKDIV0 */
+#define S5P_CLKDIV0_APLL_SHIFT		(0)
+#define S5P_CLKDIV0_APLL_MASK		(0x7 << S5P_CLKDIV0_APLL_SHIFT)
+#define S5P_CLKDIV0_A2M_SHIFT		(4)
+#define S5P_CLKDIV0_A2M_MASK		(0x7 << S5P_CLKDIV0_A2M_SHIFT)
+#define S5P_CLKDIV0_HCLK200_SHIFT	(8)
+#define S5P_CLKDIV0_HCLK200_MASK	(0x7 << S5P_CLKDIV0_HCLK200_SHIFT)
+#define S5P_CLKDIV0_PCLK100_SHIFT	(12)
+#define S5P_CLKDIV0_PCLK100_MASK	(0x7 << S5P_CLKDIV0_PCLK100_SHIFT)
+#define S5P_CLKDIV0_HCLK166_SHIFT	(16)
+#define S5P_CLKDIV0_HCLK166_MASK	(0xF << S5P_CLKDIV0_HCLK166_SHIFT)
+#define S5P_CLKDIV0_PCLK83_SHIFT	(20)
+#define S5P_CLKDIV0_PCLK83_MASK		(0x7 << S5P_CLKDIV0_PCLK83_SHIFT)
+#define S5P_CLKDIV0_HCLK133_SHIFT	(24)
+#define S5P_CLKDIV0_HCLK133_MASK	(0xF << S5P_CLKDIV0_HCLK133_SHIFT)
+#define S5P_CLKDIV0_PCLK66_SHIFT	(28)
+#define S5P_CLKDIV0_PCLK66_MASK		(0x7 << S5P_CLKDIV0_PCLK66_SHIFT)
+
+/* Registers related to power management */
+#define S5P_PWR_CFG		S5P_CLKREG(0xC000)
+#define S5P_EINT_WAKEUP_MASK	S5P_CLKREG(0xC004)
+#define S5P_WAKEUP_MASK 	S5P_CLKREG(0xC008)
+#define S5P_PWR_MODE		S5P_CLKREG(0xC00C)
+#define S5P_NORMAL_CFG		S5P_CLKREG(0xC010)
+#define S5P_IDLE_CFG		S5P_CLKREG(0xC020)
+#define S5P_STOP_CFG		S5P_CLKREG(0xC030)
+#define S5P_STOP_MEM_CFG	S5P_CLKREG(0xC034)
+#define S5P_SLEEP_CFG		S5P_CLKREG(0xC040)
+
+#define S5P_OSC_FREQ		S5P_CLKREG(0xC100)
+#define S5P_OSC_STABLE		S5P_CLKREG(0xC104)
+#define S5P_PWR_STABLE		S5P_CLKREG(0xC108)
+#define S5P_MTC_STABLE		S5P_CLKREG(0xC110)
+#define S5P_CLAMP_STABLE	S5P_CLKREG(0xC114)
+
+#define S5P_WAKEUP_STAT		S5P_CLKREG(0xC200)
+#define S5P_BLK_PWR_STAT	S5P_CLKREG(0xC204)
+
+#define S5P_OTHERS		S5P_CLKREG(0xE000)
+#define S5P_OM_STAT		S5P_CLKREG(0xE100)
+#define S5P_USB_PHY_CONTROL	S5P_CLKREG(0xE80C)
+#define S5P_DAC_CONTROL		S5P_CLKREG(0xE810)
+
+#define S5P_INFORM0		S5P_CLKREG(0xF000)
+#define S5P_INFORM1		S5P_CLKREG(0xF004)
+#define S5P_INFORM2		S5P_CLKREG(0xF008)
+#define S5P_INFORM3		S5P_CLKREG(0xF00C)
+#define S5P_INFORM4		S5P_CLKREG(0xF010)
+#define S5P_INFORM5		S5P_CLKREG(0xF014)
+#define S5P_INFORM6		S5P_CLKREG(0xF018)
+#define S5P_INFORM7		S5P_CLKREG(0xF01C)
+
+#define S5P_RST_STAT		S5P_CLKREG(0xA000)
+#define S5P_OSC_CON		S5P_CLKREG(0x8000)
+#define S5P_MIPI_PHY_CON0	S5P_CLKREG(0x7200)
+#define S5P_MIPI_PHY_CON1	S5P_CLKREG(0x7204)
+#define S5P_MIPI_CONTROL	S5P_CLKREG(0xE814)
+
+#define S5P_IDLE_CFG_TL_MASK	(3 << 30)
+#define S5P_IDLE_CFG_TM_MASK	(3 << 28)
+#define S5P_IDLE_CFG_TL_ON	(2 << 30)
+#define S5P_IDLE_CFG_TM_ON	(2 << 28)
+#define S5P_IDLE_CFG_DIDLE	(1 << 0)
+
+#define S5P_CFG_WFI_CLEAN		(~(3 << 8))
+#define S5P_CFG_WFI_IDLE		(1 << 8)
+#define S5P_CFG_WFI_STOP		(2 << 8)
+#define S5P_CFG_WFI_SLEEP		(3 << 8)
+
+#define S5P_OTHER_SYS_INT		24
+#define S5P_OTHER_STA_TYPE		23
+#define S5P_OTHER_SYSC_INTOFF		(1 << 0)
+#define STA_TYPE_EXPON			0
+#define STA_TYPE_SFR			1
+
+#define S5P_PWR_STA_EXP_SCALE		0
+#define S5P_PWR_STA_CNT			4
+
+#define S5P_PWR_STABLE_COUNT		85500
+
+#define S5P_SLEEP_CFG_OSC_EN		(1 << 0)
+#define S5P_SLEEP_CFG_USBOSC_EN		(1 << 1)
+
+/* OTHERS Resgister */
+#define S5P_OTHERS_USB_SIG_MASK		(1 << 16)
+#define S5P_OTHERS_MIPI_DPHY_EN		(1 << 28)
+
+/* MIPI */
+#define S5P_MIPI_DPHY_EN		(3)
+
+/* S5P_DAC_CONTROL */
+#define S5P_DAC_ENABLE			(1)
+#define S5P_DAC_DISABLE			(0)
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/regs-irq.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/regs-irq.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/regs-irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/regs-irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5PV210 - IRQ register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_IRQ_H
+#define __ASM_ARCH_REGS_IRQ_H __FILE__
+
+#include <asm/hardware/vic.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_REGS_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/system.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/system.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/system.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5PV210 - system support header
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H __FILE__
+
+static void arch_idle(void)
+{
+	/* nothing here yet */
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+	/* nothing here yet */
+}
+
+#endif /* __ASM_ARCH_SYSTEM_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/tick.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/tick.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/tick.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/tick.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/tick.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s3c6400/include/mach/tick.h
+ *
+ * S5PV210 - Timer tick support definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TICK_H
+#define __ASM_ARCH_TICK_H __FILE__
+
+static inline u32 s3c24xx_ostimer_pending(void)
+{
+	u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
+	return pend & (1 << (IRQ_TIMER4_VIC - S5P_IRQ_VIC0(0)));
+}
+
+#define TICK_MAX	(0xffffffff)
+
+#endif /* __ASM_ARCH_TICK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/timex.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/timex.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/timex.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,29 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2010 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s5p6442/include/mach/timex.h
+ *
+ * S5PV210 - time parameters
+ *
+ * This program is free software; you can 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_TIMEX_H
+#define __ASM_ARCH_TIMEX_H __FILE__
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/uncompress.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/uncompress.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/uncompress.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,24 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/uncompress.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5PV210 - uncompress 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.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/map.h>
+#include <plat/uncompress.h>
+
+static void arch_detect_cpu(void)
+{
+	/* we do not need to do any cpu detection here at the moment. */
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,22 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/vmalloc.h
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s5p6442/include/mach/vmalloc.h
+ *
+ * S5PV210 vmalloc definition
+ *
+ * This program is free software; you can 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_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H __FILE__
+
+#define VMALLOC_END	  (0xE0000000)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/init.c linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/init.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/init.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,44 @@
+/* linux/arch/arm/mach-s5pv210/init.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/s5pv210.h>
+#include <plat/regs-serial.h>
+
+static struct s3c24xx_uart_clksrc s5pv210_serial_clocks[] = {
+	[0] = {
+		.name		= "pclk",
+		.divisor	= 1,
+		.min_baud	= 0,
+		.max_baud	= 0,
+	},
+};
+
+/* uart registration process */
+void __init s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+	struct s3c2410_uartcfg *tcfg = cfg;
+	u32 ucnt;
+
+	for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
+		if (!tcfg->clocks) {
+			tcfg->clocks = s5pv210_serial_clocks;
+			tcfg->clocks_size = ARRAY_SIZE(s5pv210_serial_clocks);
+		}
+	}
+
+	s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,40 @@
+# arch/arm/mach-s5pv210/Kconfig
+#
+# Copyright (c) 2010 Samsung Electronics Co., Ltd.
+#		http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+# Configuration options for the S5PV210/S5PC110
+
+if ARCH_S5PV210
+
+config CPU_S5PV210
+	bool
+	select PLAT_S5P
+	help
+	  Enable S5PV210 CPU support
+
+choice
+	prompt "Select machine type"
+	depends on ARCH_S5PV210
+	default MACH_SMDKV210
+
+config MACH_SMDKV210
+	bool "SMDKV210"
+	select CPU_S5PV210
+	select ARCH_SPARSEMEM_ENABLE
+	help
+	  Machine support for Samsung SMDKV210
+
+config MACH_SMDKC110
+	bool "SMDKC110"
+	select CPU_S5PV210
+	select ARCH_SPARSEMEM_ENABLE
+	help
+	  Machine support for Samsung SMDKC110
+	  S5PC110(MCP) is one of package option of S5PV210
+
+endchoice
+
+endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/mach-smdkc110.c linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/mach-smdkc110.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/mach-smdkc110.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/mach-smdkc110.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,98 @@
+/* linux/arch/arm/mach-s5pv210/mach-smdkc110.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/regs-serial.h>
+#include <plat/s5pv210.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define S5PV210_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
+				 S3C2410_UCON_RXILEVEL |	\
+				 S3C2410_UCON_TXIRQMODE |	\
+				 S3C2410_UCON_RXIRQMODE |	\
+				 S3C2410_UCON_RXFIFO_TOI |	\
+				 S3C2443_UCON_RXERR_IRQEN)
+
+#define S5PV210_ULCON_DEFAULT	S3C2410_LCON_CS8
+
+#define S5PV210_UFCON_DEFAULT	(S3C2410_UFCON_FIFOMODE |	\
+				 S5PV210_UFCON_TXTRIG4 |	\
+				 S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport		= 0,
+		.flags		= 0,
+		.ucon		= S5PV210_UCON_DEFAULT,
+		.ulcon		= S5PV210_ULCON_DEFAULT,
+		.ufcon		= S5PV210_UFCON_DEFAULT,
+	},
+	[1] = {
+		.hwport		= 1,
+		.flags		= 0,
+		.ucon		= S5PV210_UCON_DEFAULT,
+		.ulcon		= S5PV210_ULCON_DEFAULT,
+		.ufcon		= S5PV210_UFCON_DEFAULT,
+	},
+	[2] = {
+		.hwport		= 2,
+		.flags		= 0,
+		.ucon		= S5PV210_UCON_DEFAULT,
+		.ulcon		= S5PV210_ULCON_DEFAULT,
+		.ufcon		= S5PV210_UFCON_DEFAULT,
+	},
+	[3] = {
+		.hwport		= 3,
+		.flags		= 0,
+		.ucon		= S5PV210_UCON_DEFAULT,
+		.ulcon		= S5PV210_ULCON_DEFAULT,
+		.ufcon		= S5PV210_UFCON_DEFAULT,
+	},
+};
+
+static struct platform_device *smdkc110_devices[] __initdata = {
+};
+
+static void __init smdkc110_map_io(void)
+{
+	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+	s3c24xx_init_clocks(24000000);
+	s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
+}
+
+static void __init smdkc110_machine_init(void)
+{
+	platform_add_devices(smdkc110_devices, ARRAY_SIZE(smdkc110_devices));
+}
+
+MACHINE_START(SMDKC110, "SMDKC110")
+	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+	.phys_io	= S3C_PA_UART & 0xfff00000,
+	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S5P_PA_SDRAM + 0x100,
+	.init_irq	= s5pv210_init_irq,
+	.map_io		= smdkc110_map_io,
+	.init_machine	= smdkc110_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/mach-smdkv210.c linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/mach-smdkv210.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/mach-smdkv210.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/mach-smdkv210.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,98 @@
+/* linux/arch/arm/mach-s5pv210/mach-smdkv210.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/regs-serial.h>
+#include <plat/s5pv210.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define S5PV210_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
+				 S3C2410_UCON_RXILEVEL |	\
+				 S3C2410_UCON_TXIRQMODE |	\
+				 S3C2410_UCON_RXIRQMODE |	\
+				 S3C2410_UCON_RXFIFO_TOI |	\
+				 S3C2443_UCON_RXERR_IRQEN)
+
+#define S5PV210_ULCON_DEFAULT	S3C2410_LCON_CS8
+
+#define S5PV210_UFCON_DEFAULT	(S3C2410_UFCON_FIFOMODE |	\
+				 S5PV210_UFCON_TXTRIG4 |	\
+				 S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport		= 0,
+		.flags		= 0,
+		.ucon		= S5PV210_UCON_DEFAULT,
+		.ulcon		= S5PV210_ULCON_DEFAULT,
+		.ufcon		= S5PV210_UFCON_DEFAULT,
+	},
+	[1] = {
+		.hwport		= 1,
+		.flags		= 0,
+		.ucon		= S5PV210_UCON_DEFAULT,
+		.ulcon		= S5PV210_ULCON_DEFAULT,
+		.ufcon		= S5PV210_UFCON_DEFAULT,
+	},
+	[2] = {
+		.hwport		= 2,
+		.flags		= 0,
+		.ucon		= S5PV210_UCON_DEFAULT,
+		.ulcon		= S5PV210_ULCON_DEFAULT,
+		.ufcon		= S5PV210_UFCON_DEFAULT,
+	},
+	[3] = {
+		.hwport		= 3,
+		.flags		= 0,
+		.ucon		= S5PV210_UCON_DEFAULT,
+		.ulcon		= S5PV210_ULCON_DEFAULT,
+		.ufcon		= S5PV210_UFCON_DEFAULT,
+	},
+};
+
+static struct platform_device *smdkv210_devices[] __initdata = {
+};
+
+static void __init smdkv210_map_io(void)
+{
+	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+	s3c24xx_init_clocks(24000000);
+	s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
+}
+
+static void __init smdkv210_machine_init(void)
+{
+	platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices));
+}
+
+MACHINE_START(SMDKV210, "SMDKV210")
+	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+	.phys_io	= S3C_PA_UART & 0xfff00000,
+	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S5P_PA_SDRAM + 0x100,
+	.init_irq	= s5pv210_init_irq,
+	.map_io		= smdkv210_map_io,
+	.init_machine	= smdkv210_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,20 @@
+# arch/arm/mach-s5pv210/Makefile
+#
+# Copyright (c) 2010 Samsung Electronics Co., Ltd.
+# 		http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:=
+obj-				:=
+
+# Core support for S5PV210 system
+
+obj-$(CONFIG_CPU_S5PV210)	+= cpu.o init.o clock.o
+
+# machine support
+
+obj-$(CONFIG_MACH_SMDKV210)	+= mach-smdkv210.o
+obj-$(CONFIG_MACH_SMDKC110)	+= mach-smdkc110.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/Makefile.boot linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/Makefile.boot
--- linux-libre-2.6.33-gnu1/arch/arm/mach-s5pv210/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-s5pv210/Makefile.boot	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,2 @@
+   zreladdr-y	:= 0x20008000
+params_phys-y	:= 0x20000100
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/badge4.c linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/badge4.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/badge4.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/badge4.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,6 +51,10 @@ static struct resource sa1111_resources[
 	},
 };
 
+static struct sa1111_platform_data sa1111_info = {
+	.irq_base	= IRQ_BOARD_END,
+};
+
 static u64 sa1111_dmamask = 0xffffffffUL;
 
 static struct platform_device sa1111_device = {
@@ -59,6 +63,7 @@ static struct platform_device sa1111_dev
 	.dev		= {
 		.dma_mask = &sa1111_dmamask,
 		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &sa1111_info,
 	},
 	.num_resources	= ARRAY_SIZE(sa1111_resources),
 	.resource	= sa1111_resources,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/collie.c linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/collie.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/collie.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/collie.c	2010-05-16 17:17:36.000000000 -0400
@@ -234,6 +234,10 @@ static struct resource locomo_resources[
 	},
 };
 
+static struct locomo_platform_data locomo_info = {
+	.irq_base	= IRQ_BOARD_START,
+};
+
 struct platform_device collie_locomo_device = {
 	.name		= "locomo",
 	.id		= 0,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/cpu-sa1110.c linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/cpu-sa1110.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/cpu-sa1110.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/cpu-sa1110.c	2010-05-16 17:17:36.000000000 -0400
@@ -363,6 +363,9 @@ static int __init sa1110_clk_init(void)
 	struct sdram_params *sdram;
 	const char *name = sdram_name;
 
+	if (!cpu_is_sa1110())
+		return -ENODEV;
+
 	if (!name[0]) {
 		if (machine_is_assabet())
 			name = "TC59SM716-CL3";
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/collie.h linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/include/mach/collie.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/collie.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/include/mach/collie.h	2010-05-16 17:17:36.000000000 -0400
@@ -72,13 +72,6 @@
 #define COLLIE_IRQ_GPIO_GA_INT		IRQ_GPIO25
 #define COLLIE_IRQ_GPIO_MAIN_BAT_LOW	IRQ_GPIO26
 
-#define COLLIE_LCM_IRQ_GPIO_RTS		IRQ_LOCOMO_GPIO0
-#define COLLIE_LCM_IRQ_GPIO_CTS		IRQ_LOCOMO_GPIO1
-#define COLLIE_LCM_IRQ_GPIO_DSR		IRQ_LOCOMO_GPIO2
-#define COLLIE_LCM_IRQ_GPIO_DTR		IRQ_LOCOMO_GPIO3
-#define COLLIE_LCM_IRQ_GPIO_nSD_DETECT	IRQ_LOCOMO_GPIO13
-#define COLLIE_LCM_IRQ_GPIO_nSD_WP	IRQ_LOCOMO_GPIO14
-
 /* GPIO's on the TC35143AF (Toshiba Analog Frontend) */
 #define COLLIE_TC35143_GPIO_BASE	(GPIO_MAX + 13)
 #define COLLIE_TC35143_GPIO_VERSION0    UCB_IO_0
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,7 @@
 */
 #include <mach/hardware.h>
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #0x80000000	@ physical base address
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/irqs.h linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/include/mach/irqs.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/irqs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/include/mach/irqs.h	2010-05-16 17:17:36.000000000 -0400
@@ -68,93 +68,17 @@
 #define IRQ_BOARD_START		49
 #define IRQ_BOARD_END		65
 
-#define IRQ_SA1111_START	(IRQ_BOARD_END)
-#define IRQ_GPAIN0		(IRQ_BOARD_END + 0)
-#define IRQ_GPAIN1		(IRQ_BOARD_END + 1)
-#define IRQ_GPAIN2		(IRQ_BOARD_END + 2)
-#define IRQ_GPAIN3		(IRQ_BOARD_END + 3)
-#define IRQ_GPBIN0		(IRQ_BOARD_END + 4)
-#define IRQ_GPBIN1		(IRQ_BOARD_END + 5)
-#define IRQ_GPBIN2		(IRQ_BOARD_END + 6)
-#define IRQ_GPBIN3		(IRQ_BOARD_END + 7)
-#define IRQ_GPBIN4		(IRQ_BOARD_END + 8)
-#define IRQ_GPBIN5		(IRQ_BOARD_END + 9)
-#define IRQ_GPCIN0		(IRQ_BOARD_END + 10)
-#define IRQ_GPCIN1		(IRQ_BOARD_END + 11)
-#define IRQ_GPCIN2		(IRQ_BOARD_END + 12)
-#define IRQ_GPCIN3		(IRQ_BOARD_END + 13)
-#define IRQ_GPCIN4		(IRQ_BOARD_END + 14)
-#define IRQ_GPCIN5		(IRQ_BOARD_END + 15)
-#define IRQ_GPCIN6		(IRQ_BOARD_END + 16)
-#define IRQ_GPCIN7		(IRQ_BOARD_END + 17)
-#define IRQ_MSTXINT		(IRQ_BOARD_END + 18)
-#define IRQ_MSRXINT		(IRQ_BOARD_END + 19)
-#define IRQ_MSSTOPERRINT	(IRQ_BOARD_END + 20)
-#define IRQ_TPTXINT		(IRQ_BOARD_END + 21)
-#define IRQ_TPRXINT		(IRQ_BOARD_END + 22)
-#define IRQ_TPSTOPERRINT	(IRQ_BOARD_END + 23)
-#define SSPXMTINT		(IRQ_BOARD_END + 24)
-#define SSPRCVINT		(IRQ_BOARD_END + 25)
-#define SSPROR			(IRQ_BOARD_END + 26)
-#define AUDXMTDMADONEA		(IRQ_BOARD_END + 32)
-#define AUDRCVDMADONEA		(IRQ_BOARD_END + 33)
-#define AUDXMTDMADONEB		(IRQ_BOARD_END + 34)
-#define AUDRCVDMADONEB		(IRQ_BOARD_END + 35)
-#define AUDTFSR			(IRQ_BOARD_END + 36)
-#define AUDRFSR			(IRQ_BOARD_END + 37)
-#define AUDTUR			(IRQ_BOARD_END + 38)
-#define AUDROR			(IRQ_BOARD_END + 39)
-#define AUDDTS			(IRQ_BOARD_END + 40)
-#define AUDRDD			(IRQ_BOARD_END + 41)
-#define AUDSTO			(IRQ_BOARD_END + 42)
-#define IRQ_USBPWR		(IRQ_BOARD_END + 43)
-#define IRQ_HCIM		(IRQ_BOARD_END + 44)
-#define IRQ_HCIBUFFACC		(IRQ_BOARD_END + 45)
-#define IRQ_HCIRMTWKP		(IRQ_BOARD_END + 46)
-#define IRQ_NHCIMFCIR		(IRQ_BOARD_END + 47)
-#define IRQ_USB_PORT_RESUME	(IRQ_BOARD_END + 48)
-#define IRQ_S0_READY_NINT	(IRQ_BOARD_END + 49)
-#define IRQ_S1_READY_NINT	(IRQ_BOARD_END + 50)
-#define IRQ_S0_CD_VALID		(IRQ_BOARD_END + 51)
-#define IRQ_S1_CD_VALID		(IRQ_BOARD_END + 52)
-#define IRQ_S0_BVD1_STSCHG	(IRQ_BOARD_END + 53)
-#define IRQ_S1_BVD1_STSCHG	(IRQ_BOARD_END + 54)
-
-#define IRQ_LOCOMO_START	(IRQ_BOARD_END)
-#define IRQ_LOCOMO_KEY		(IRQ_BOARD_END + 0)
-#define IRQ_LOCOMO_GPIO0	(IRQ_BOARD_END + 1)
-#define IRQ_LOCOMO_GPIO1	(IRQ_BOARD_END + 2)
-#define IRQ_LOCOMO_GPIO2	(IRQ_BOARD_END + 3)
-#define IRQ_LOCOMO_GPIO3	(IRQ_BOARD_END + 4)
-#define IRQ_LOCOMO_GPIO4	(IRQ_BOARD_END + 5)
-#define IRQ_LOCOMO_GPIO5	(IRQ_BOARD_END + 6)
-#define IRQ_LOCOMO_GPIO6	(IRQ_BOARD_END + 7)
-#define IRQ_LOCOMO_GPIO7	(IRQ_BOARD_END + 8)
-#define IRQ_LOCOMO_GPIO8	(IRQ_BOARD_END + 9)
-#define IRQ_LOCOMO_GPIO9	(IRQ_BOARD_END + 10)
-#define IRQ_LOCOMO_GPIO10	(IRQ_BOARD_END + 11)
-#define IRQ_LOCOMO_GPIO11	(IRQ_BOARD_END + 12)
-#define IRQ_LOCOMO_GPIO12	(IRQ_BOARD_END + 13)
-#define IRQ_LOCOMO_GPIO13	(IRQ_BOARD_END + 14)
-#define IRQ_LOCOMO_GPIO14	(IRQ_BOARD_END + 15)
-#define IRQ_LOCOMO_GPIO15	(IRQ_BOARD_END + 16)
-#define IRQ_LOCOMO_LT		(IRQ_BOARD_END + 17)
-#define IRQ_LOCOMO_SPI_RFR	(IRQ_BOARD_END + 18)
-#define IRQ_LOCOMO_SPI_RFW	(IRQ_BOARD_END + 19)
-#define IRQ_LOCOMO_SPI_REND	(IRQ_BOARD_END + 20)
-#define IRQ_LOCOMO_SPI_TEND	(IRQ_BOARD_END + 21)
-
 /*
  * Figure out the MAX IRQ number.
  *
  * If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1.
- * If we have an LoCoMo, the max IRQ is IRQ_LOCOMO_SPI_TEND+1
+ * If we have an LoCoMo, the max IRQ is IRQ_BOARD_START + 4
  * Otherwise, we have the standard IRQs only.
  */
 #ifdef CONFIG_SA1111
-#define NR_IRQS			(IRQ_S1_BVD1_STSCHG + 1)
-#elif defined(CONFIG_SHARP_LOCOMO)
-#define NR_IRQS			(IRQ_LOCOMO_SPI_TEND + 1)
+#define NR_IRQS			(IRQ_BOARD_END + 55)
+#elif defined(CONFIG_SHARPSL_LOCOMO)
+#define NR_IRQS			(IRQ_BOARD_START + 4)
 #else
 #define NR_IRQS			(IRQ_BOARD_START)
 #endif
@@ -166,10 +90,3 @@
 #define IRQ_NEPONSET_SMC9196	(IRQ_BOARD_START + 0)
 #define IRQ_NEPONSET_USAR	(IRQ_BOARD_START + 1)
 #define IRQ_NEPONSET_SA1111	(IRQ_BOARD_START + 2)
-
-/* LoCoMo Interrupts (CONFIG_SHARP_LOCOMO) */
-#define IRQ_LOCOMO_KEY_BASE	(IRQ_BOARD_START + 0)
-#define IRQ_LOCOMO_GPIO_BASE	(IRQ_BOARD_START + 1)
-#define IRQ_LOCOMO_LT_BASE	(IRQ_BOARD_START + 2)
-#define IRQ_LOCOMO_SPI_BASE	(IRQ_BOARD_START + 3)
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,4 @@
 /*
  * arch/arm/mach-sa1100/include/mach/vmalloc.h
  */
-#define VMALLOC_END       (0xe8000000)
+#define VMALLOC_END       (0xe8000000UL)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/jornada720.c linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/jornada720.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/jornada720.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/jornada720.c	2010-05-16 17:17:36.000000000 -0400
@@ -208,6 +208,10 @@ static struct resource sa1111_resources[
 	},
 };
 
+static struct sa1111_platform_data sa1111_info = {
+	.irq_base	= IRQ_BOARD_END,
+};
+
 static u64 sa1111_dmamask = 0xffffffffUL;
 
 static struct platform_device sa1111_device = {
@@ -216,6 +220,7 @@ static struct platform_device sa1111_dev
 	.dev		= {
 		.dma_mask = &sa1111_dmamask,
 		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &sa1111_info,
 	},
 	.num_resources	= ARRAY_SIZE(sa1111_resources),
 	.resource	= sa1111_resources,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/jornada720_ssp.c linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/jornada720_ssp.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/jornada720_ssp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/jornada720_ssp.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <mach/jornada720.h>
@@ -130,7 +129,7 @@ void jornada_ssp_end(void)
 };
 EXPORT_SYMBOL(jornada_ssp_end);
 
-static int __init jornada_ssp_probe(struct platform_device *dev)
+static int __devinit jornada_ssp_probe(struct platform_device *dev)
 {
 	int ret;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -57,7 +57,7 @@ config SA1100_COLLIE
 config SA1100_H3100
 	bool "Compaq iPAQ H3100"
 	select HTC_EGPIO
-	select CPU_FREQ_SA1100
+	select CPU_FREQ_SA1110
 	help
 	  Say Y here if you intend to run this kernel on the Compaq iPAQ
 	  H3100 handheld computer.  Information about this machine and the
@@ -68,7 +68,7 @@ config SA1100_H3100
 config SA1100_H3600
 	bool "Compaq iPAQ H3600/H3700"
 	select HTC_EGPIO
-	select CPU_FREQ_SA1100
+	select CPU_FREQ_SA1110
 	help
 	  Say Y here if you intend to run this kernel on the Compaq iPAQ
 	  H3600 handheld computer.  Information about this machine and the
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/neponset.c linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/neponset.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/neponset.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/neponset.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,6 @@
 #include <linux/ioport.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
-#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -241,6 +240,10 @@ static struct resource sa1111_resources[
 	},
 };
 
+static struct sa1111_platform_data sa1111_info = {
+	.irq_base	= IRQ_BOARD_END,
+};
+
 static u64 sa1111_dmamask = 0xffffffffUL;
 
 static struct platform_device sa1111_device = {
@@ -249,6 +252,7 @@ static struct platform_device sa1111_dev
 	.dev		= {
 		.dma_mask = &sa1111_dmamask,
 		.coherent_dma_mask = 0xffffffff,
+		.platform_data = &sa1111_info,
 	},
 	.num_resources	= ARRAY_SIZE(sa1111_resources),
 	.resource	= sa1111_resources,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/time.c linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/time.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-sa1100/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,14 +35,12 @@ static irqreturn_t sa1100_ost0_interrupt
 static int
 sa1100_osmr0_set_next_event(unsigned long delta, struct clock_event_device *c)
 {
-	unsigned long flags, next, oscr;
+	unsigned long next, oscr;
 
-	raw_local_irq_save(flags);
 	OIER |= OIER_E0;
 	next = OSCR + delta;
 	OSMR0 = next;
 	oscr = OSCR;
-	raw_local_irq_restore(flags);
 
 	return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
 }
@@ -50,16 +48,12 @@ sa1100_osmr0_set_next_event(unsigned lon
 static void
 sa1100_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *c)
 {
-	unsigned long flags;
-
 	switch (mode) {
 	case CLOCK_EVT_MODE_ONESHOT:
 	case CLOCK_EVT_MODE_UNUSED:
 	case CLOCK_EVT_MODE_SHUTDOWN:
-		raw_local_irq_save(flags);
 		OIER &= ~OIER_E0;
 		OSSR = OSSR_M0;
-		raw_local_irq_restore(flags);
 		break;
 
 	case CLOCK_EVT_MODE_RESUME:
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shark/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-shark/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shark/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shark/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
  *
 */
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mov	\rx, #0xe0000000
 		orr	\rx, \rx, #0x000003f8
 		.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/board-ap4evb.c linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/board-ap4evb.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/board-ap4evb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/board-ap4evb.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,333 @@
+/*
+ * AP4EVB board support
+ *
+ * Copyright (C) 2010  Magnus Damm
+ * Copyright (C) 2008  Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <mach/common.h>
+#include <mach/sh7372.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+/*
+ * Address	Interface		BusWidth	note
+ * ------------------------------------------------------------------
+ * 0x0000_0000	NOR Flash ROM (MCP)	16bit		SW7 : bit1 = ON
+ * 0x0800_0000	user area		-
+ * 0x1000_0000	NOR Flash ROM (MCP)	16bit		SW7 : bit1 = OFF
+ * 0x1400_0000	Ether (LAN9220)		16bit
+ * 0x1600_0000	user area		-		cannot use with NAND
+ * 0x1800_0000	user area		-
+ * 0x1A00_0000	-
+ * 0x4000_0000	LPDDR2-SDRAM (POP)	32bit
+ */
+
+/*
+ * NOR Flash ROM
+ *
+ *  SW1  |     SW2    | SW7  | NOR Flash ROM
+ *  bit1 | bit1  bit2 | bit1 | Memory allocation
+ * ------+------------+------+------------------
+ *  OFF  | ON     OFF | ON   |    Area 0
+ *  OFF  | ON     OFF | OFF  |    Area 4
+ */
+
+/*
+ * NAND Flash ROM
+ *
+ *  SW1  |     SW2    | SW7  | NAND Flash ROM
+ *  bit1 | bit1  bit2 | bit2 | Memory allocation
+ * ------+------------+------+------------------
+ *  OFF  | ON     OFF | ON   |    FCE 0
+ *  OFF  | ON     OFF | OFF  |    FCE 1
+ */
+
+/*
+ * SMSC 9220
+ *
+ *  SW1		SMSC 9220
+ * -----------------------
+ *  ON		access disable
+ *  OFF		access enable
+ */
+
+/*
+ * KEYSC
+ *
+ * SW43		KEYSC
+ * -------------------------
+ * ON		enable
+ * OFF		disable
+ */
+
+/* MTD */
+static struct mtd_partition nor_flash_partitions[] = {
+	{
+		.name		= "loader",
+		.offset		= 0x00000000,
+		.size		= 512 * 1024,
+	},
+	{
+		.name		= "bootenv",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 512 * 1024,
+	},
+	{
+		.name		= "kernel_ro",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 8 * 1024 * 1024,
+		.mask_flags	= MTD_WRITEABLE,
+	},
+	{
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 8 * 1024 * 1024,
+	},
+	{
+		.name		= "data",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data nor_flash_data = {
+	.width		= 2,
+	.parts		= nor_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+	[0]	= {
+		.start	= 0x00000000,
+		.end	= 0x08000000 - 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,
+};
+
+/* SMSC 9220 */
+static struct resource smc911x_resources[] = {
+	{
+		.start	= 0x14000000,
+		.end	= 0x16000000 - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= 6,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+	},
+};
+
+static struct smsc911x_platform_config smsc911x_info = {
+	.flags		= SMSC911X_USE_16BIT | SMSC911X_SAVE_MAC_ADDRESS,
+	.irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device smc911x_device = {
+	.name           = "smsc911x",
+	.id             = -1,
+	.num_resources  = ARRAY_SIZE(smc911x_resources),
+	.resource       = smc911x_resources,
+	.dev            = {
+		.platform_data = &smsc911x_info,
+	},
+};
+
+/* KEYSC (Needs SW43 set to ON) */
+static struct sh_keysc_info keysc_info = {
+	.mode		= SH_KEYSC_MODE_1,
+	.scan_timing	= 3,
+	.delay		= 2500,
+	.keycodes = {
+		KEY_0, KEY_1, KEY_2, KEY_3, KEY_4,
+		KEY_5, KEY_6, KEY_7, KEY_8, KEY_9,
+		KEY_A, KEY_B, KEY_C, KEY_D, KEY_E,
+		KEY_F, KEY_G, KEY_H, KEY_I, KEY_J,
+		KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
+	},
+};
+
+static struct resource keysc_resources[] = {
+	[0] = {
+		.name	= "KEYSC",
+		.start  = 0xe61b0000,
+		.end    = 0xe61b0063,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 79,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device keysc_device = {
+	.name           = "sh_keysc",
+	.id             = 0, /* "keysc0" clock */
+	.num_resources  = ARRAY_SIZE(keysc_resources),
+	.resource       = keysc_resources,
+	.dev	= {
+		.platform_data	= &keysc_info,
+	},
+};
+
+/* SDHI0 */
+static struct resource sdhi0_resources[] = {
+	[0] = {
+		.name	= "SDHI0",
+		.start  = 0xe6850000,
+		.end    = 0xe68501ff,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 96,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sdhi0_device = {
+	.name           = "sh_mobile_sdhi",
+	.num_resources  = ARRAY_SIZE(sdhi0_resources),
+	.resource       = sdhi0_resources,
+	.id             = 0,
+};
+
+static struct platform_device *ap4evb_devices[] __initdata = {
+	&nor_flash_device,
+	&smc911x_device,
+	&keysc_device,
+	&sdhi0_device,
+};
+
+static struct map_desc ap4evb_io_desc[] __initdata = {
+	/* create a 1:1 entity map for 0xe6xxxxxx
+	 * used by CPGA, INTC and PFC.
+	 */
+	{
+		.virtual	= 0xe6000000,
+		.pfn		= __phys_to_pfn(0xe6000000),
+		.length		= 256 << 20,
+		.type		= MT_DEVICE_NONSHARED
+	},
+};
+
+static void __init ap4evb_map_io(void)
+{
+	iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc));
+
+	/* setup early devices, clocks and console here as well */
+	sh7372_add_early_devices();
+	sh7367_clock_init(); /* use g3 clocks for now */
+	shmobile_setup_console();
+}
+
+static void __init ap4evb_init(void)
+{
+	sh7372_pinmux_init();
+
+	/* enable SCIFA0 */
+	gpio_request(GPIO_FN_SCIFA0_TXD, NULL);
+	gpio_request(GPIO_FN_SCIFA0_RXD, NULL);
+
+	/* enable SMSC911X */
+	gpio_request(GPIO_FN_CS5A,	NULL);
+	gpio_request(GPIO_FN_IRQ6_39,	NULL);
+
+	/* enable LED 1 - 4 */
+	gpio_request(GPIO_PORT185, NULL);
+	gpio_request(GPIO_PORT186, NULL);
+	gpio_request(GPIO_PORT187, NULL);
+	gpio_request(GPIO_PORT188, NULL);
+	gpio_direction_output(GPIO_PORT185, 1);
+	gpio_direction_output(GPIO_PORT186, 1);
+	gpio_direction_output(GPIO_PORT187, 1);
+	gpio_direction_output(GPIO_PORT188, 1);
+	gpio_export(GPIO_PORT185, 0);
+	gpio_export(GPIO_PORT186, 0);
+	gpio_export(GPIO_PORT187, 0);
+	gpio_export(GPIO_PORT188, 0);
+
+	/* enable Debug switch (S6) */
+	gpio_request(GPIO_PORT32, NULL);
+	gpio_request(GPIO_PORT33, NULL);
+	gpio_request(GPIO_PORT34, NULL);
+	gpio_request(GPIO_PORT35, NULL);
+	gpio_direction_input(GPIO_PORT32);
+	gpio_direction_input(GPIO_PORT33);
+	gpio_direction_input(GPIO_PORT34);
+	gpio_direction_input(GPIO_PORT35);
+	gpio_export(GPIO_PORT32, 0);
+	gpio_export(GPIO_PORT33, 0);
+	gpio_export(GPIO_PORT34, 0);
+	gpio_export(GPIO_PORT35, 0);
+
+	/* enable KEYSC */
+	gpio_request(GPIO_FN_KEYOUT0, NULL);
+	gpio_request(GPIO_FN_KEYOUT1, NULL);
+	gpio_request(GPIO_FN_KEYOUT2, NULL);
+	gpio_request(GPIO_FN_KEYOUT3, NULL);
+	gpio_request(GPIO_FN_KEYOUT4, NULL);
+	gpio_request(GPIO_FN_KEYIN0_136, NULL);
+	gpio_request(GPIO_FN_KEYIN1_135, NULL);
+	gpio_request(GPIO_FN_KEYIN2_134, NULL);
+	gpio_request(GPIO_FN_KEYIN3_133, NULL);
+	gpio_request(GPIO_FN_KEYIN4,     NULL);
+
+	/* SDHI0 */
+	gpio_request(GPIO_FN_SDHICD0, NULL);
+	gpio_request(GPIO_FN_SDHIWP0, NULL);
+	gpio_request(GPIO_FN_SDHICMD0, NULL);
+	gpio_request(GPIO_FN_SDHICLK0, NULL);
+	gpio_request(GPIO_FN_SDHID0_3, NULL);
+	gpio_request(GPIO_FN_SDHID0_2, NULL);
+	gpio_request(GPIO_FN_SDHID0_1, NULL);
+	gpio_request(GPIO_FN_SDHID0_0, NULL);
+
+	sh7372_add_standard_devices();
+
+	platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices));
+}
+
+MACHINE_START(AP4EVB, "ap4evb")
+	.phys_io	= 0xe6000000,
+	.io_pg_offst	= ((0xe6000000) >> 18) & 0xfffc,
+	.map_io		= ap4evb_map_io,
+	.init_irq	= sh7372_init_irq,
+	.init_machine	= ap4evb_init,
+	.timer		= &shmobile_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/board-g3evm.c linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/board-g3evm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/board-g3evm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/board-g3evm.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,333 @@
+/*
+ * G3EVM board support
+ *
+ * Copyright (C) 2010  Magnus Damm
+ * Copyright (C) 2008  Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/sh_flctl.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <mach/sh7367.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+static struct mtd_partition nor_flash_partitions[] = {
+	{
+		.name		= "loader",
+		.offset		= 0x00000000,
+		.size		= 512 * 1024,
+	},
+	{
+		.name		= "bootenv",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 512 * 1024,
+	},
+	{
+		.name		= "kernel_ro",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 8 * 1024 * 1024,
+		.mask_flags	= MTD_WRITEABLE,
+	},
+	{
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 8 * 1024 * 1024,
+	},
+	{
+		.name		= "data",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data nor_flash_data = {
+	.width		= 2,
+	.parts		= nor_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+	[0]	= {
+		.start	= 0x00000000,
+		.end	= 0x08000000 - 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,
+};
+
+/* USBHS */
+void usb_host_port_power(int port, int power)
+{
+	if (!power) /* only power-on supported for now */
+		return;
+
+	/* set VBOUT/PWEN and EXTLP0 in DVSTCTR */
+	__raw_writew(__raw_readw(0xe6890008) | 0x600, 0xe6890008);
+}
+
+static struct r8a66597_platdata usb_host_data = {
+	.on_chip = 1,
+	.port_power = usb_host_port_power,
+};
+
+static struct resource usb_host_resources[] = {
+	[0] = {
+		.name	= "USBHS",
+		.start	= 0xe6890000,
+		.end	= 0xe68900e5,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 65,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device usb_host_device = {
+	.name		= "r8a66597_hcd",
+	.id		= 0,
+	.dev = {
+		.platform_data		= &usb_host_data,
+		.dma_mask		= NULL,
+		.coherent_dma_mask	= 0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(usb_host_resources),
+	.resource	= usb_host_resources,
+};
+
+/* KEYSC */
+static struct sh_keysc_info keysc_info = {
+	.mode		= SH_KEYSC_MODE_5,
+	.scan_timing	= 3,
+	.delay		= 100,
+	.keycodes = {
+		KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G,
+		KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N,
+		KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U,
+		KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP,
+		KEY_WAKEUP, KEY_COFFEE, KEY_0, KEY_1, KEY_2, KEY_3, KEY_4,
+		KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_STOP, KEY_COMPUTER,
+	},
+};
+
+static struct resource keysc_resources[] = {
+	[0] = {
+		.name	= "KEYSC",
+		.start  = 0xe61b0000,
+		.end    = 0xe61b000f,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 79,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device keysc_device = {
+	.name           = "sh_keysc",
+	.num_resources  = ARRAY_SIZE(keysc_resources),
+	.resource       = keysc_resources,
+	.dev	= {
+		.platform_data	= &keysc_info,
+	},
+};
+
+static struct mtd_partition nand_partition_info[] = {
+	{
+		.name	= "system",
+		.offset	= 0,
+		.size	= 64 * 1024 * 1024,
+	},
+	{
+		.name	= "userdata",
+		.offset	= MTDPART_OFS_APPEND,
+		.size	= 128 * 1024 * 1024,
+	},
+	{
+		.name	= "cache",
+		.offset	= MTDPART_OFS_APPEND,
+		.size	= 64 * 1024 * 1024,
+	},
+};
+
+static struct resource nand_flash_resources[] = {
+	[0] = {
+		.start	= 0xe6a30000,
+		.end	= 0xe6a3009b,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct sh_flctl_platform_data nand_flash_data = {
+	.parts		= nand_partition_info,
+	.nr_parts	= ARRAY_SIZE(nand_partition_info),
+	.flcmncr_val	= QTSEL_E | FCKSEL_E | TYPESEL_SET | NANWF_E
+			| SHBUSSEL | SEL_16BIT,
+};
+
+static struct platform_device nand_flash_device = {
+	.name		= "sh_flctl",
+	.resource	= nand_flash_resources,
+	.num_resources	= ARRAY_SIZE(nand_flash_resources),
+	.dev		= {
+		.platform_data = &nand_flash_data,
+	},
+};
+
+static struct platform_device *g3evm_devices[] __initdata = {
+	&nor_flash_device,
+	&usb_host_device,
+	&keysc_device,
+	&nand_flash_device,
+};
+
+static struct map_desc g3evm_io_desc[] __initdata = {
+	/* create a 1:1 entity map for 0xe6xxxxxx
+	 * used by CPGA, INTC and PFC.
+	 */
+	{
+		.virtual	= 0xe6000000,
+		.pfn		= __phys_to_pfn(0xe6000000),
+		.length		= 256 << 20,
+		.type		= MT_DEVICE_NONSHARED
+	},
+};
+
+static void __init g3evm_map_io(void)
+{
+	iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc));
+
+	/* setup early devices, clocks and console here as well */
+	sh7367_add_early_devices();
+	sh7367_clock_init();
+	shmobile_setup_console();
+}
+
+static void __init g3evm_init(void)
+{
+	sh7367_pinmux_init();
+
+	/* Lit DS4 LED */
+	gpio_request(GPIO_PORT22, NULL);
+	gpio_direction_output(GPIO_PORT22, 1);
+	gpio_export(GPIO_PORT22, 0);
+
+	/* Lit DS8 LED */
+	gpio_request(GPIO_PORT23, NULL);
+	gpio_direction_output(GPIO_PORT23, 1);
+	gpio_export(GPIO_PORT23, 0);
+
+	/* Lit DS3 LED */
+	gpio_request(GPIO_PORT24, NULL);
+	gpio_direction_output(GPIO_PORT24, 1);
+	gpio_export(GPIO_PORT24, 0);
+
+	/* SCIFA1 */
+	gpio_request(GPIO_FN_SCIFA1_TXD, NULL);
+	gpio_request(GPIO_FN_SCIFA1_RXD, NULL);
+	gpio_request(GPIO_FN_SCIFA1_CTS, NULL);
+	gpio_request(GPIO_FN_SCIFA1_RTS, NULL);
+
+	/* USBHS */
+	gpio_request(GPIO_FN_VBUS0, NULL);
+	gpio_request(GPIO_FN_PWEN, NULL);
+	gpio_request(GPIO_FN_OVCN, NULL);
+	gpio_request(GPIO_FN_OVCN2, NULL);
+	gpio_request(GPIO_FN_EXTLP, NULL);
+	gpio_request(GPIO_FN_IDIN, NULL);
+
+	/* enable clock in SYMSTPCR2 */
+	__raw_writel(__raw_readl(0xe6158048) & ~(1 << 22), 0xe6158048);
+
+	/* setup USB phy */
+	__raw_writew(0x0300, 0xe605810a);	/* USBCR1 */
+	__raw_writew(0x00e0, 0xe60581c0);	/* CPFCH */
+	__raw_writew(0x6010, 0xe60581c6);	/* CGPOSR */
+	__raw_writew(0x8a0a, 0xe605810c);	/* USBCR2 */
+
+	/* KEYSC @ CN7 */
+	gpio_request(GPIO_FN_PORT42_KEYOUT0, NULL);
+	gpio_request(GPIO_FN_PORT43_KEYOUT1, NULL);
+	gpio_request(GPIO_FN_PORT44_KEYOUT2, NULL);
+	gpio_request(GPIO_FN_PORT45_KEYOUT3, NULL);
+	gpio_request(GPIO_FN_PORT46_KEYOUT4, NULL);
+	gpio_request(GPIO_FN_PORT47_KEYOUT5, NULL);
+	gpio_request(GPIO_FN_PORT48_KEYIN0_PU, NULL);
+	gpio_request(GPIO_FN_PORT49_KEYIN1_PU, NULL);
+	gpio_request(GPIO_FN_PORT50_KEYIN2_PU, NULL);
+	gpio_request(GPIO_FN_PORT55_KEYIN3_PU, NULL);
+	gpio_request(GPIO_FN_PORT56_KEYIN4_PU, NULL);
+	gpio_request(GPIO_FN_PORT57_KEYIN5_PU, NULL);
+	gpio_request(GPIO_FN_PORT58_KEYIN6_PU, NULL);
+
+	/* FLCTL */
+	gpio_request(GPIO_FN_FCE0, NULL);
+	gpio_request(GPIO_FN_D0_ED0_NAF0, NULL);
+	gpio_request(GPIO_FN_D1_ED1_NAF1, NULL);
+	gpio_request(GPIO_FN_D2_ED2_NAF2, NULL);
+	gpio_request(GPIO_FN_D3_ED3_NAF3, NULL);
+	gpio_request(GPIO_FN_D4_ED4_NAF4, NULL);
+	gpio_request(GPIO_FN_D5_ED5_NAF5, NULL);
+	gpio_request(GPIO_FN_D6_ED6_NAF6, NULL);
+	gpio_request(GPIO_FN_D7_ED7_NAF7, NULL);
+	gpio_request(GPIO_FN_D8_ED8_NAF8, NULL);
+	gpio_request(GPIO_FN_D9_ED9_NAF9, NULL);
+	gpio_request(GPIO_FN_D10_ED10_NAF10, NULL);
+	gpio_request(GPIO_FN_D11_ED11_NAF11, NULL);
+	gpio_request(GPIO_FN_D12_ED12_NAF12, NULL);
+	gpio_request(GPIO_FN_D13_ED13_NAF13, NULL);
+	gpio_request(GPIO_FN_D14_ED14_NAF14, NULL);
+	gpio_request(GPIO_FN_D15_ED15_NAF15, NULL);
+	gpio_request(GPIO_FN_WE0_XWR0_FWE, NULL);
+	gpio_request(GPIO_FN_FRB, NULL);
+	/* FOE, FCDE, FSC on dedicated pins */
+	__raw_writel(__raw_readl(0xe6158048) & ~(1 << 15), 0xe6158048);
+
+	sh7367_add_standard_devices();
+
+	platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices));
+}
+
+MACHINE_START(G3EVM, "g3evm")
+	.phys_io	= 0xe6000000,
+	.io_pg_offst	= ((0xe6000000) >> 18) & 0xfffc,
+	.map_io		= g3evm_map_io,
+	.init_irq	= sh7367_init_irq,
+	.init_machine	= g3evm_init,
+	.timer		= &shmobile_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/board-g4evm.c linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/board-g4evm.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/board-g4evm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/board-g4evm.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,268 @@
+/*
+ * G4EVM board support
+ *
+ * Copyright (C) 2010  Magnus Damm
+ * Copyright (C) 2008  Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/io.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <linux/gpio.h>
+#include <mach/sh7377.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+static struct mtd_partition nor_flash_partitions[] = {
+	{
+		.name		= "loader",
+		.offset		= 0x00000000,
+		.size		= 512 * 1024,
+	},
+	{
+		.name		= "bootenv",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 512 * 1024,
+	},
+	{
+		.name		= "kernel_ro",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 8 * 1024 * 1024,
+		.mask_flags	= MTD_WRITEABLE,
+	},
+	{
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 8 * 1024 * 1024,
+	},
+	{
+		.name		= "data",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data nor_flash_data = {
+	.width		= 2,
+	.parts		= nor_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+	[0]	= {
+		.start	= 0x00000000,
+		.end	= 0x08000000 - 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,
+};
+
+/* USBHS */
+void usb_host_port_power(int port, int power)
+{
+	if (!power) /* only power-on supported for now */
+		return;
+
+	/* set VBOUT/PWEN and EXTLP0 in DVSTCTR */
+	__raw_writew(__raw_readw(0xe6890008) | 0x600, 0xe6890008);
+}
+
+static struct r8a66597_platdata usb_host_data = {
+	.on_chip = 1,
+	.port_power = usb_host_port_power,
+};
+
+static struct resource usb_host_resources[] = {
+	[0] = {
+		.name	= "USBHS",
+		.start	= 0xe6890000,
+		.end	= 0xe68900e5,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 65,
+		.end	= 65,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device usb_host_device = {
+	.name		= "r8a66597_hcd",
+	.id		= 0,
+	.dev = {
+		.platform_data		= &usb_host_data,
+		.dma_mask		= NULL,
+		.coherent_dma_mask	= 0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(usb_host_resources),
+	.resource	= usb_host_resources,
+};
+
+/* KEYSC */
+static struct sh_keysc_info keysc_info = {
+	.mode		= SH_KEYSC_MODE_5,
+	.scan_timing	= 3,
+	.delay		= 100,
+	.keycodes = {
+		KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F,
+		KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L,
+		KEY_M, KEY_N, KEY_U, KEY_P, KEY_Q, KEY_R,
+		KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, KEY_X,
+		KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP, KEY_WAKEUP, KEY_COFFEE,
+		KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5,
+		KEY_6, KEY_7, KEY_8, KEY_9, KEY_STOP, KEY_COMPUTER,
+	},
+};
+
+static struct resource keysc_resources[] = {
+	[0] = {
+		.name	= "KEYSC",
+		.start  = 0xe61b0000,
+		.end    = 0xe61b000f,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 79,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device keysc_device = {
+	.name           = "sh_keysc",
+	.id             = 0, /* keysc0 clock */
+	.num_resources  = ARRAY_SIZE(keysc_resources),
+	.resource       = keysc_resources,
+	.dev	= {
+		.platform_data	= &keysc_info,
+	},
+};
+
+static struct platform_device *g4evm_devices[] __initdata = {
+	&nor_flash_device,
+	&usb_host_device,
+	&keysc_device,
+};
+
+static struct map_desc g4evm_io_desc[] __initdata = {
+	/* create a 1:1 entity map for 0xe6xxxxxx
+	 * used by CPGA, INTC and PFC.
+	 */
+	{
+		.virtual	= 0xe6000000,
+		.pfn		= __phys_to_pfn(0xe6000000),
+		.length		= 256 << 20,
+		.type		= MT_DEVICE_NONSHARED
+	},
+};
+
+static void __init g4evm_map_io(void)
+{
+	iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc));
+
+	/* setup early devices, clocks and console here as well */
+	sh7377_add_early_devices();
+	sh7367_clock_init(); /* use g3 clocks for now */
+	shmobile_setup_console();
+}
+
+static void __init g4evm_init(void)
+{
+	sh7377_pinmux_init();
+
+	/* Lit DS14 LED */
+	gpio_request(GPIO_PORT109, NULL);
+	gpio_direction_output(GPIO_PORT109, 1);
+	gpio_export(GPIO_PORT109, 1);
+
+	/* Lit DS15 LED */
+	gpio_request(GPIO_PORT110, NULL);
+	gpio_direction_output(GPIO_PORT110, 1);
+	gpio_export(GPIO_PORT110, 1);
+
+	/* Lit DS16 LED */
+	gpio_request(GPIO_PORT112, NULL);
+	gpio_direction_output(GPIO_PORT112, 1);
+	gpio_export(GPIO_PORT112, 1);
+
+	/* Lit DS17 LED */
+	gpio_request(GPIO_PORT113, NULL);
+	gpio_direction_output(GPIO_PORT113, 1);
+	gpio_export(GPIO_PORT113, 1);
+
+	/* USBHS */
+	gpio_request(GPIO_FN_VBUS_0, NULL);
+	gpio_request(GPIO_FN_PWEN, NULL);
+	gpio_request(GPIO_FN_OVCN, NULL);
+	gpio_request(GPIO_FN_OVCN2, NULL);
+	gpio_request(GPIO_FN_EXTLP, NULL);
+	gpio_request(GPIO_FN_IDIN, NULL);
+
+	/* enable clock in SMSTPCR3 */
+	__raw_writel(__raw_readl(0xe615013c) & ~(1 << 22), 0xe615013c);
+
+	/* setup USB phy */
+	__raw_writew(0x0200, 0xe605810a);       /* USBCR1 */
+	__raw_writew(0x00e0, 0xe60581c0);       /* CPFCH */
+	__raw_writew(0x6010, 0xe60581c6);       /* CGPOSR */
+	__raw_writew(0x8a0a, 0xe605810c);       /* USBCR2 */
+
+	/* KEYSC @ CN31 */
+	gpio_request(GPIO_FN_PORT60_KEYOUT5, NULL);
+	gpio_request(GPIO_FN_PORT61_KEYOUT4, NULL);
+	gpio_request(GPIO_FN_PORT62_KEYOUT3, NULL);
+	gpio_request(GPIO_FN_PORT63_KEYOUT2, NULL);
+	gpio_request(GPIO_FN_PORT64_KEYOUT1, NULL);
+	gpio_request(GPIO_FN_PORT65_KEYOUT0, NULL);
+	gpio_request(GPIO_FN_PORT66_KEYIN0_PU, NULL);
+	gpio_request(GPIO_FN_PORT67_KEYIN1_PU, NULL);
+	gpio_request(GPIO_FN_PORT68_KEYIN2_PU, NULL);
+	gpio_request(GPIO_FN_PORT69_KEYIN3_PU, NULL);
+	gpio_request(GPIO_FN_PORT70_KEYIN4_PU, NULL);
+	gpio_request(GPIO_FN_PORT71_KEYIN5_PU, NULL);
+	gpio_request(GPIO_FN_PORT72_KEYIN6_PU, NULL);
+
+	sh7377_add_standard_devices();
+
+	platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices));
+}
+
+MACHINE_START(G4EVM, "g4evm")
+	.phys_io	= 0xe6000000,
+	.io_pg_offst	= ((0xe6000000) >> 18) & 0xfffc,
+	.map_io		= g4evm_map_io,
+	.init_irq	= sh7377_init_irq,
+	.init_machine	= g4evm_init,
+	.timer		= &shmobile_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/clock-sh7367.c linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/clock-sh7367.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/clock-sh7367.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/clock-sh7367.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,103 @@
+/*
+ * Preliminary clock framework support for sh7367
+ *
+ * Copyright (C) 2010  Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+
+struct clk {
+	const char *name;
+	unsigned long rate;
+};
+
+#include <asm/clkdev.h>
+
+int __clk_get(struct clk *clk)
+{
+	return 1;
+}
+EXPORT_SYMBOL(__clk_get);
+
+void __clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(__clk_put);
+
+
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk ? clk->rate : 0;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* a static peripheral clock for now - enough to get sh-sci working */
+static struct clk peripheral_clk = {
+	.name	    = "peripheral_clk",
+	.rate	    = 48000000,
+};
+
+/* a static rclk for now - enough to get sh_cmt working */
+static struct clk r_clk = {
+	.name	    = "r_clk",
+	.rate	    = 32768,
+};
+
+/* a static usb0 for now - enough to get r8a66597 working */
+static struct clk usb0_clk = {
+	.name	    = "usb0",
+};
+
+/* a static keysc0 clk for now - enough to get sh_keysc working */
+static struct clk keysc0_clk = {
+	.name	    = "keysc0",
+};
+
+static struct clk_lookup lookups[] = {
+	{
+		.clk = &peripheral_clk,
+	}, {
+		.clk = &r_clk,
+	}, {
+		.clk = &usb0_clk,
+	}, {
+		.clk = &keysc0_clk,
+	}
+};
+
+void __init sh7367_clock_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(lookups); i++) {
+		lookups[i].con_id = lookups[i].clk->name;
+		clkdev_add(&lookups[i]);
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/console.c linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/console.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/console.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/console.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,31 @@
+/*
+ * SH-Mobile Console
+ *
+ * Copyright (C) 2010  Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <mach/common.h>
+#include <asm/mach/map.h>
+
+void __init shmobile_setup_console(void)
+{
+	parse_early_param();
+
+	/* Let earlyprintk output early console messages */
+	early_platform_driver_probe("earlyprintk", 1, 1);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/clkdev.h linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/clkdev.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/clkdev.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/clkdev.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+int __clk_get(struct clk *clk);
+void __clk_put(struct clk *clk);
+
+#endif /* __ASM_MACH_CLKDEV_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/common.h linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/common.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/common.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,23 @@
+#ifndef __ARCH_MACH_COMMON_H
+#define __ARCH_MACH_COMMON_H
+
+extern struct sys_timer shmobile_timer;
+extern void shmobile_setup_console(void);
+
+extern void sh7367_init_irq(void);
+extern void sh7367_add_early_devices(void);
+extern void sh7367_add_standard_devices(void);
+extern void sh7367_clock_init(void);
+extern void sh7367_pinmux_init(void);
+
+extern void sh7377_init_irq(void);
+extern void sh7377_add_early_devices(void);
+extern void sh7377_add_standard_devices(void);
+extern void sh7377_pinmux_init(void);
+
+extern void sh7372_init_irq(void);
+extern void sh7372_add_early_devices(void);
+extern void sh7372_add_standard_devices(void);
+extern void sh7372_pinmux_init(void);
+
+#endif /* __ARCH_MACH_COMMON_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/dma.h linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/dma.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/dma.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1 @@
+/* empty */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/entry-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/entry-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/entry-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+	.macro  disable_fiq
+	.endm
+
+	.macro  get_irqnr_preamble, base, tmp
+	ldr     \base, =INTFLGA
+	.endm
+
+	.macro  arch_ret_to_user, tmp1, tmp2
+	.endm
+
+	.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+	ldr     \irqnr, [\base]
+	cmp	\irqnr, #0
+	beq	1000f
+	/* intevt to irq number */
+	lsr	\irqnr, \irqnr, #0x5
+	subs	\irqnr, \irqnr, #16
+
+1000:
+	.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/gpio.h linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/gpio.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/gpio.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ * Generic GPIO API and pinmux table support
+ *
+ * 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.
+ */
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+
+#define ARCH_NR_GPIOS 1024
+#include <linux/sh_pfc.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)
+{
+	return -ENOSYS;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+	return -EINVAL;
+}
+
+#endif /* CONFIG_GPIOLIB */
+
+#endif /* __ASM_ARCH_GPIO_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/hardware.h linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/hardware.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/hardware.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_HARDWARE_H
+#define __ASM_MACH_HARDWARE_H
+
+/* INTFLGA register - used by low level interrupt code in entry-macro.S */
+#define INTFLGA			0xe6980018
+
+#endif /* __ASM_MACH_HARDWARE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/io.h linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/io.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/io.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,9 @@
+#ifndef __ASM_MACH_IO_H
+#define __ASM_MACH_IO_H
+
+#define IO_SPACE_LIMIT		0xffffffff
+
+#define __io(a)			((void __iomem *)(a))
+#define __mem_pci(a)		(a)
+
+#endif /* __ASM_MACH_IO_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/irqs.h linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/irqs.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/irqs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,10 @@
+#ifndef __ASM_MACH_IRQS_H
+#define __ASM_MACH_IRQS_H
+
+#define NR_IRQS         512
+#define NR_IRQS_LEGACY  8
+
+#define evt2irq(evt)		(((evt) >> 5) - 16)
+#define irq2evt(irq)		(((irq) + 16) << 5)
+
+#endif /* __ASM_MACH_IRQS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/memory.h linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/memory.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/memory.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_MEMORY_H
+#define __ASM_MACH_MEMORY_H
+
+#define PHYS_OFFSET	UL(CONFIG_MEMORY_START)
+#define MEM_SIZE	UL(CONFIG_MEMORY_SIZE)
+
+#endif /* __ASM_MACH_MEMORY_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/sh7367.h linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/sh7367.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/sh7367.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/sh7367.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,332 @@
+#ifndef __ASM_SH7367_H__
+#define __ASM_SH7367_H__
+
+/* Pin Function Controller:
+ * GPIO_FN_xx - GPIO used to select pin function
+ * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
+ */
+enum {
+	/* 49-1 -> 49-6 (GPIO) */
+	GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
+	GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
+
+	GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
+	GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
+
+	GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
+	GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
+
+	GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
+	GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
+
+	GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
+	GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
+
+	GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
+	GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
+
+	GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
+	GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
+
+	GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
+	GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
+
+	GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
+	GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
+
+	GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
+	GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
+
+	GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
+	GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
+
+	GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
+	GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118, GPIO_PORT119,
+
+	GPIO_PORT120, GPIO_PORT121, GPIO_PORT122, GPIO_PORT123, GPIO_PORT124,
+	GPIO_PORT125, GPIO_PORT126, GPIO_PORT127, GPIO_PORT128, GPIO_PORT129,
+
+	GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
+	GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
+
+	GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
+	GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
+
+	GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
+	GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
+
+	GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
+	GPIO_PORT165, GPIO_PORT166, GPIO_PORT167, GPIO_PORT168, GPIO_PORT169,
+
+	GPIO_PORT170, GPIO_PORT171, GPIO_PORT172, GPIO_PORT173, GPIO_PORT174,
+	GPIO_PORT175, GPIO_PORT176, GPIO_PORT177, GPIO_PORT178, GPIO_PORT179,
+
+	GPIO_PORT180, GPIO_PORT181, GPIO_PORT182, GPIO_PORT183, GPIO_PORT184,
+	GPIO_PORT185, GPIO_PORT186, GPIO_PORT187, GPIO_PORT188, GPIO_PORT189,
+
+	GPIO_PORT190, GPIO_PORT191, GPIO_PORT192, GPIO_PORT193, GPIO_PORT194,
+	GPIO_PORT195, GPIO_PORT196, GPIO_PORT197, GPIO_PORT198, GPIO_PORT199,
+
+	GPIO_PORT200, GPIO_PORT201, GPIO_PORT202, GPIO_PORT203, GPIO_PORT204,
+	GPIO_PORT205, GPIO_PORT206, GPIO_PORT207, GPIO_PORT208, GPIO_PORT209,
+
+	GPIO_PORT210, GPIO_PORT211, GPIO_PORT212, GPIO_PORT213, GPIO_PORT214,
+	GPIO_PORT215, GPIO_PORT216, GPIO_PORT217, GPIO_PORT218, GPIO_PORT219,
+
+	GPIO_PORT220, GPIO_PORT221, GPIO_PORT222, GPIO_PORT223, GPIO_PORT224,
+	GPIO_PORT225, GPIO_PORT226, GPIO_PORT227, GPIO_PORT228, GPIO_PORT229,
+
+	GPIO_PORT230, GPIO_PORT231, GPIO_PORT232, GPIO_PORT233, GPIO_PORT234,
+	GPIO_PORT235, GPIO_PORT236, GPIO_PORT237, GPIO_PORT238, GPIO_PORT239,
+
+	GPIO_PORT240, GPIO_PORT241, GPIO_PORT242, GPIO_PORT243, GPIO_PORT244,
+	GPIO_PORT245, GPIO_PORT246, GPIO_PORT247, GPIO_PORT248, GPIO_PORT249,
+
+	GPIO_PORT250, GPIO_PORT251, GPIO_PORT252, GPIO_PORT253, GPIO_PORT254,
+	GPIO_PORT255, GPIO_PORT256, GPIO_PORT257, GPIO_PORT258, GPIO_PORT259,
+
+	GPIO_PORT260, GPIO_PORT261, GPIO_PORT262, GPIO_PORT263, GPIO_PORT264,
+	GPIO_PORT265, GPIO_PORT266, GPIO_PORT267, GPIO_PORT268, GPIO_PORT269,
+
+	GPIO_PORT270, GPIO_PORT271, GPIO_PORT272,
+
+	/* Special Pull-up / Pull-down Functions */
+	GPIO_FN_PORT48_KEYIN0_PU, GPIO_FN_PORT49_KEYIN1_PU,
+	GPIO_FN_PORT50_KEYIN2_PU, GPIO_FN_PORT55_KEYIN3_PU,
+	GPIO_FN_PORT56_KEYIN4_PU, GPIO_FN_PORT57_KEYIN5_PU,
+	GPIO_FN_PORT58_KEYIN6_PU,
+
+	/* 49-1 (FN) */
+	GPIO_FN_VBUS0, GPIO_FN_CPORT0, GPIO_FN_CPORT1, GPIO_FN_CPORT2,
+	GPIO_FN_CPORT3, GPIO_FN_CPORT4, GPIO_FN_CPORT5, GPIO_FN_CPORT6,
+	GPIO_FN_CPORT7, GPIO_FN_CPORT8, GPIO_FN_CPORT9, GPIO_FN_CPORT10,
+	GPIO_FN_CPORT11, GPIO_FN_SIN2, GPIO_FN_CPORT12, GPIO_FN_XCTS2,
+	GPIO_FN_CPORT13, GPIO_FN_RFSPO4, GPIO_FN_CPORT14, GPIO_FN_RFSPO5,
+	GPIO_FN_CPORT15, GPIO_FN_CPORT16, GPIO_FN_CPORT17, GPIO_FN_SOUT2,
+	GPIO_FN_CPORT18, GPIO_FN_XRTS2, GPIO_FN_CPORT19, GPIO_FN_CPORT20,
+	GPIO_FN_RFSPO6, GPIO_FN_CPORT21, GPIO_FN_STATUS0, GPIO_FN_CPORT22,
+	GPIO_FN_STATUS1, GPIO_FN_CPORT23, GPIO_FN_STATUS2, GPIO_FN_RFSPO7,
+	GPIO_FN_MPORT0, GPIO_FN_MPORT1, GPIO_FN_B_SYNLD1, GPIO_FN_B_SYNLD2,
+	GPIO_FN_XMAINPS, GPIO_FN_XDIVPS, GPIO_FN_XIDRST, GPIO_FN_IDCLK,
+	GPIO_FN_IDIO, GPIO_FN_SOUT1, GPIO_FN_SCIFA4_TXD,
+	GPIO_FN_M02_BERDAT, GPIO_FN_SIN1, GPIO_FN_SCIFA4_RXD, GPIO_FN_XWUP,
+	GPIO_FN_XRTS1, GPIO_FN_SCIFA4_RTS, GPIO_FN_M03_BERCLK,
+	GPIO_FN_XCTS1, GPIO_FN_SCIFA4_CTS,
+
+	/* 49-2 (FN) */
+	GPIO_FN_HSU_IQ_AGC6, GPIO_FN_MFG2_IN2, GPIO_FN_MSIOF2_MCK0,
+	GPIO_FN_HSU_IQ_AGC5, GPIO_FN_MFG2_IN1, GPIO_FN_MSIOF2_MCK1,
+	GPIO_FN_HSU_IQ_AGC4, GPIO_FN_MSIOF2_RSYNC,
+	GPIO_FN_HSU_IQ_AGC3, GPIO_FN_MFG2_OUT1, GPIO_FN_MSIOF2_RSCK,
+	GPIO_FN_HSU_IQ_AGC2, GPIO_FN_PORT42_KEYOUT0,
+	GPIO_FN_HSU_IQ_AGC1, GPIO_FN_PORT43_KEYOUT1,
+	GPIO_FN_HSU_IQ_AGC0, GPIO_FN_PORT44_KEYOUT2,
+	GPIO_FN_HSU_IQ_AGC_ST, GPIO_FN_PORT45_KEYOUT3,
+	GPIO_FN_HSU_IQ_PDO, GPIO_FN_PORT46_KEYOUT4,
+	GPIO_FN_HSU_IQ_PYO, GPIO_FN_PORT47_KEYOUT5,
+	GPIO_FN_HSU_EN_TXMUX_G3MO, GPIO_FN_PORT48_KEYIN0,
+	GPIO_FN_HSU_I_TXMUX_G3MO, GPIO_FN_PORT49_KEYIN1,
+	GPIO_FN_HSU_Q_TXMUX_G3MO, GPIO_FN_PORT50_KEYIN2,
+	GPIO_FN_HSU_SYO, GPIO_FN_PORT51_MSIOF2_TSYNC,
+	GPIO_FN_HSU_SDO, GPIO_FN_PORT52_MSIOF2_TSCK,
+	GPIO_FN_HSU_TGTTI_G3MO, GPIO_FN_PORT53_MSIOF2_TXD,
+	GPIO_FN_B_TIME_STAMP, GPIO_FN_PORT54_MSIOF2_RXD,
+	GPIO_FN_HSU_SDI, GPIO_FN_PORT55_KEYIN3,
+	GPIO_FN_HSU_SCO, GPIO_FN_PORT56_KEYIN4,
+	GPIO_FN_HSU_DREQ, GPIO_FN_PORT57_KEYIN5,
+	GPIO_FN_HSU_DACK, GPIO_FN_PORT58_KEYIN6,
+	GPIO_FN_HSU_CLK61M, GPIO_FN_PORT59_MSIOF2_SS1,
+	GPIO_FN_HSU_XRST, GPIO_FN_PORT60_MSIOF2_SS2,
+	GPIO_FN_PCMCLKO, GPIO_FN_SYNC8KO, GPIO_FN_DNPCM_A, GPIO_FN_UPPCM_A,
+	GPIO_FN_XTALB1L,
+	GPIO_FN_GPS_AGC1, GPIO_FN_SCIFA0_RTS,
+	GPIO_FN_GPS_AGC2, GPIO_FN_SCIFA0_SCK,
+	GPIO_FN_GPS_AGC3, GPIO_FN_SCIFA0_TXD,
+	GPIO_FN_GPS_AGC4, GPIO_FN_SCIFA0_RXD,
+	GPIO_FN_GPS_PWRD, GPIO_FN_SCIFA0_CTS,
+	GPIO_FN_GPS_IM, GPIO_FN_GPS_IS, GPIO_FN_GPS_QM, GPIO_FN_GPS_QS,
+	GPIO_FN_SIUBOMC, GPIO_FN_TPU2TO0,
+	GPIO_FN_SIUCKB, GPIO_FN_TPU2TO1,
+	GPIO_FN_SIUBOLR, GPIO_FN_BBIF2_TSYNC, GPIO_FN_TPU2TO2,
+	GPIO_FN_SIUBOBT, GPIO_FN_BBIF2_TSCK, GPIO_FN_TPU2TO3,
+	GPIO_FN_SIUBOSLD, GPIO_FN_BBIF2_TXD, GPIO_FN_TPU3TO0,
+	GPIO_FN_SIUBILR, GPIO_FN_TPU3TO1,
+	GPIO_FN_SIUBIBT, GPIO_FN_TPU3TO2,
+	GPIO_FN_SIUBISLD, GPIO_FN_TPU3TO3,
+	GPIO_FN_NMI, GPIO_FN_TPU4TO0,
+	GPIO_FN_DNPCM_M, GPIO_FN_TPU4TO1, GPIO_FN_TPU4TO2, GPIO_FN_TPU4TO3,
+	GPIO_FN_IRQ_TMPB,
+	GPIO_FN_PWEN, GPIO_FN_MFG1_OUT1,
+	GPIO_FN_OVCN, GPIO_FN_MFG1_IN1,
+	GPIO_FN_OVCN2, GPIO_FN_MFG1_IN2,
+
+	/* 49-3 (FN) */
+	GPIO_FN_RFSPO1, GPIO_FN_RFSPO2, GPIO_FN_RFSPO3, GPIO_FN_PORT93_VIO_CKO2,
+	GPIO_FN_USBTERM, GPIO_FN_EXTLP, GPIO_FN_IDIN,
+	GPIO_FN_SCIFA5_CTS, GPIO_FN_MFG0_IN1,
+	GPIO_FN_SCIFA5_RTS, GPIO_FN_MFG0_IN2,
+	GPIO_FN_SCIFA5_RXD,
+	GPIO_FN_SCIFA5_TXD,
+	GPIO_FN_SCIFA5_SCK, GPIO_FN_MFG0_OUT1,
+	GPIO_FN_A0_EA0, GPIO_FN_BS,
+	GPIO_FN_A14_EA14, GPIO_FN_PORT102_KEYOUT0,
+	GPIO_FN_A15_EA15, GPIO_FN_PORT103_KEYOUT1, GPIO_FN_DV_CLKOL,
+	GPIO_FN_A16_EA16, GPIO_FN_PORT104_KEYOUT2,
+	GPIO_FN_DV_VSYNCL, GPIO_FN_MSIOF0_SS1,
+	GPIO_FN_A17_EA17, GPIO_FN_PORT105_KEYOUT3,
+	GPIO_FN_DV_HSYNCL, GPIO_FN_MSIOF0_TSYNC,
+	GPIO_FN_A18_EA18, GPIO_FN_PORT106_KEYOUT4,
+	GPIO_FN_DV_DL0, GPIO_FN_MSIOF0_TSCK,
+	GPIO_FN_A19_EA19, GPIO_FN_PORT107_KEYOUT5,
+	GPIO_FN_DV_DL1, GPIO_FN_MSIOF0_TXD,
+	GPIO_FN_A20_EA20, GPIO_FN_PORT108_KEYIN0,
+	GPIO_FN_DV_DL2, GPIO_FN_MSIOF0_RSCK,
+	GPIO_FN_A21_EA21, GPIO_FN_PORT109_KEYIN1,
+	GPIO_FN_DV_DL3, GPIO_FN_MSIOF0_RSYNC,
+	GPIO_FN_A22_EA22, GPIO_FN_PORT110_KEYIN2,
+	GPIO_FN_DV_DL4, GPIO_FN_MSIOF0_MCK0,
+	GPIO_FN_A23_EA23, GPIO_FN_PORT111_KEYIN3,
+	GPIO_FN_DV_DL5, GPIO_FN_MSIOF0_MCK1,
+	GPIO_FN_A24_EA24, GPIO_FN_PORT112_KEYIN4,
+	GPIO_FN_DV_DL6, GPIO_FN_MSIOF0_RXD,
+	GPIO_FN_A25_EA25, GPIO_FN_PORT113_KEYIN5,
+	GPIO_FN_DV_DL7, GPIO_FN_MSIOF0_SS2,
+	GPIO_FN_A26, GPIO_FN_PORT113_KEYIN6, GPIO_FN_DV_CLKIL,
+	GPIO_FN_D0_ED0_NAF0, GPIO_FN_D1_ED1_NAF1, GPIO_FN_D2_ED2_NAF2,
+	GPIO_FN_D3_ED3_NAF3, GPIO_FN_D4_ED4_NAF4, GPIO_FN_D5_ED5_NAF5,
+	GPIO_FN_D6_ED6_NAF6, GPIO_FN_D7_ED7_NAF7, GPIO_FN_D8_ED8_NAF8,
+	GPIO_FN_D9_ED9_NAF9, GPIO_FN_D10_ED10_NAF10, GPIO_FN_D11_ED11_NAF11,
+	GPIO_FN_D12_ED12_NAF12, GPIO_FN_D13_ED13_NAF13,
+	GPIO_FN_D14_ED14_NAF14, GPIO_FN_D15_ED15_NAF15,
+	GPIO_FN_CS4, GPIO_FN_CS5A, GPIO_FN_CS5B, GPIO_FN_FCE1,
+	GPIO_FN_CS6B, GPIO_FN_XCS2, GPIO_FN_FCE0, GPIO_FN_CS6A,
+	GPIO_FN_DACK0, GPIO_FN_WAIT, GPIO_FN_DREQ0, GPIO_FN_RD_XRD,
+	GPIO_FN_A27, GPIO_FN_RDWR_XWE, GPIO_FN_WE0_XWR0_FWE,
+	GPIO_FN_WE1_XWR1, GPIO_FN_FRB, GPIO_FN_CKO,
+	GPIO_FN_NBRSTOUT, GPIO_FN_NBRST,
+
+	/* 49-4 (FN) */
+	GPIO_FN_RFSPO0, GPIO_FN_PORT146_VIO_CKO2, GPIO_FN_TSTMD,
+	GPIO_FN_VIO_VD, GPIO_FN_VIO_HD,
+	GPIO_FN_VIO_D0, GPIO_FN_VIO_D1, GPIO_FN_VIO_D2,
+	GPIO_FN_VIO_D3, GPIO_FN_VIO_D4, GPIO_FN_VIO_D5,
+	GPIO_FN_VIO_D6, GPIO_FN_VIO_D7, GPIO_FN_VIO_D8,
+	GPIO_FN_VIO_D9, GPIO_FN_VIO_D10, GPIO_FN_VIO_D11,
+	GPIO_FN_VIO_D12, GPIO_FN_VIO_D13, GPIO_FN_VIO_D14,
+	GPIO_FN_VIO_D15, GPIO_FN_VIO_CLK, GPIO_FN_VIO_FIELD,
+	GPIO_FN_VIO_CKO,
+	GPIO_FN_MFG3_IN1, GPIO_FN_MFG3_IN2,
+	GPIO_FN_M9_SLCD_A01, GPIO_FN_MFG3_OUT1, GPIO_FN_TPU0TO0,
+	GPIO_FN_M10_SLCD_CK1, GPIO_FN_MFG4_IN1, GPIO_FN_TPU0TO1,
+	GPIO_FN_M11_SLCD_SO1, GPIO_FN_MFG4_IN2, GPIO_FN_TPU0TO2,
+	GPIO_FN_M12_SLCD_CE1, GPIO_FN_MFG4_OUT1, GPIO_FN_TPU0TO3,
+	GPIO_FN_LCDD0, GPIO_FN_PORT175_KEYOUT0, GPIO_FN_DV_D0,
+	GPIO_FN_SIUCKA, GPIO_FN_MFG0_OUT2,
+	GPIO_FN_LCDD1, GPIO_FN_PORT176_KEYOUT1, GPIO_FN_DV_D1,
+	GPIO_FN_SIUAOLR, GPIO_FN_BBIF2_TSYNC1,
+	GPIO_FN_LCDD2, GPIO_FN_PORT177_KEYOUT2, GPIO_FN_DV_D2,
+	GPIO_FN_SIUAOBT, GPIO_FN_BBIF2_TSCK1,
+	GPIO_FN_LCDD3, GPIO_FN_PORT178_KEYOUT3, GPIO_FN_DV_D3,
+	GPIO_FN_SIUAOSLD, GPIO_FN_BBIF2_TXD1,
+	GPIO_FN_LCDD4, GPIO_FN_PORT179_KEYOUT4, GPIO_FN_DV_D4,
+	GPIO_FN_SIUAISPD, GPIO_FN_MFG1_OUT2,
+	GPIO_FN_LCDD5, GPIO_FN_PORT180_KEYOUT5, GPIO_FN_DV_D5,
+	GPIO_FN_SIUAILR, GPIO_FN_MFG2_OUT2,
+	GPIO_FN_LCDD6, GPIO_FN_DV_D6,
+	GPIO_FN_SIUAIBT, GPIO_FN_MFG3_OUT2, GPIO_FN_XWR2,
+	GPIO_FN_LCDD7, GPIO_FN_DV_D7,
+	GPIO_FN_SIUAISLD, GPIO_FN_MFG4_OUT2, GPIO_FN_XWR3,
+	GPIO_FN_LCDD8, GPIO_FN_DV_D8, GPIO_FN_D16, GPIO_FN_ED16,
+	GPIO_FN_LCDD9, GPIO_FN_DV_D9, GPIO_FN_D17, GPIO_FN_ED17,
+	GPIO_FN_LCDD10, GPIO_FN_DV_D10, GPIO_FN_D18, GPIO_FN_ED18,
+	GPIO_FN_LCDD11, GPIO_FN_DV_D11, GPIO_FN_D19, GPIO_FN_ED19,
+	GPIO_FN_LCDD12, GPIO_FN_DV_D12, GPIO_FN_D20, GPIO_FN_ED20,
+	GPIO_FN_LCDD13, GPIO_FN_DV_D13, GPIO_FN_D21, GPIO_FN_ED21,
+	GPIO_FN_LCDD14, GPIO_FN_DV_D14, GPIO_FN_D22, GPIO_FN_ED22,
+	GPIO_FN_LCDD15, GPIO_FN_DV_D15, GPIO_FN_D23, GPIO_FN_ED23,
+	GPIO_FN_LCDD16, GPIO_FN_DV_HSYNC, GPIO_FN_D24, GPIO_FN_ED24,
+	GPIO_FN_LCDD17, GPIO_FN_DV_VSYNC, GPIO_FN_D25, GPIO_FN_ED25,
+	GPIO_FN_LCDD18, GPIO_FN_DREQ2, GPIO_FN_MSIOF0L_TSCK,
+	GPIO_FN_D26, GPIO_FN_ED26,
+	GPIO_FN_LCDD19, GPIO_FN_MSIOF0L_TSYNC,
+	GPIO_FN_D27, GPIO_FN_ED27,
+	GPIO_FN_LCDD20, GPIO_FN_TS_SPSYNC1, GPIO_FN_MSIOF0L_MCK0,
+	GPIO_FN_D28, GPIO_FN_ED28,
+	GPIO_FN_LCDD21, GPIO_FN_TS_SDAT1, GPIO_FN_MSIOF0L_MCK1,
+	GPIO_FN_D29, GPIO_FN_ED29,
+	GPIO_FN_LCDD22, GPIO_FN_TS_SDEN1, GPIO_FN_MSIOF0L_SS1,
+	GPIO_FN_D30, GPIO_FN_ED30,
+	GPIO_FN_LCDD23, GPIO_FN_TS_SCK1, GPIO_FN_MSIOF0L_SS2,
+	GPIO_FN_D31, GPIO_FN_ED31,
+	GPIO_FN_LCDDCK, GPIO_FN_LCDWR, GPIO_FN_DV_CKO, GPIO_FN_SIUAOSPD,
+	GPIO_FN_LCDRD, GPIO_FN_DACK2, GPIO_FN_MSIOF0L_RSYNC,
+
+
+	/* 49-5 (FN) */
+	GPIO_FN_LCDHSYN, GPIO_FN_LCDCS, GPIO_FN_LCDCS2, GPIO_FN_DACK3,
+	GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_DREQ3, GPIO_FN_MSIOF0L_RSCK,
+	GPIO_FN_LCDCSYN, GPIO_FN_LCDCSYN2, GPIO_FN_DV_CKI,
+	GPIO_FN_LCDLCLK, GPIO_FN_DREQ1, GPIO_FN_MSIOF0L_RXD,
+	GPIO_FN_LCDDON, GPIO_FN_LCDDON2, GPIO_FN_DACK1, GPIO_FN_MSIOF0L_TXD,
+	GPIO_FN_VIO_DR0, GPIO_FN_VIO_DR1, GPIO_FN_VIO_DR2, GPIO_FN_VIO_DR3,
+	GPIO_FN_VIO_DR4, GPIO_FN_VIO_DR5, GPIO_FN_VIO_DR6, GPIO_FN_VIO_DR7,
+	GPIO_FN_VIO_VDR, GPIO_FN_VIO_HDR,
+	GPIO_FN_VIO_CLKR, GPIO_FN_VIO_CKOR,
+	GPIO_FN_SCIFA1_TXD, GPIO_FN_GPS_PGFA0,
+	GPIO_FN_SCIFA1_SCK, GPIO_FN_GPS_PGFA1,
+	GPIO_FN_SCIFA1_RTS, GPIO_FN_GPS_EPPSINMON,
+	GPIO_FN_SCIFA1_RXD, GPIO_FN_SCIFA1_CTS,
+	GPIO_FN_MSIOF1_TXD, GPIO_FN_SCIFA1_TXD2, GPIO_FN_GPS_TXD,
+	GPIO_FN_MSIOF1_TSYNC, GPIO_FN_SCIFA1_CTS2, GPIO_FN_I2C_SDA2,
+	GPIO_FN_MSIOF1_TSCK, GPIO_FN_SCIFA1_SCK2,
+	GPIO_FN_MSIOF1_RXD, GPIO_FN_SCIFA1_RXD2, GPIO_FN_GPS_RXD,
+	GPIO_FN_MSIOF1_RSCK, GPIO_FN_SCIFA1_RTS2,
+	GPIO_FN_MSIOF1_RSYNC, GPIO_FN_I2C_SCL2,
+	GPIO_FN_MSIOF1_MCK0, GPIO_FN_MSIOF1_MCK1,
+	GPIO_FN_MSIOF1_SS1, GPIO_FN_EDBGREQ3,
+	GPIO_FN_MSIOF1_SS2,
+	GPIO_FN_PORT236_IROUT, GPIO_FN_IRDA_OUT,
+	GPIO_FN_IRDA_IN, GPIO_FN_IRDA_FIRSEL,
+	GPIO_FN_TPU1TO0, GPIO_FN_TS_SPSYNC3,
+	GPIO_FN_TPU1TO1, GPIO_FN_TS_SDAT3,
+	GPIO_FN_TPU1TO2, GPIO_FN_TS_SDEN3, GPIO_FN_PORT241_MSIOF2_SS1,
+	GPIO_FN_TPU1TO3, GPIO_FN_PORT242_MSIOF2_TSCK,
+	GPIO_FN_M13_BSW, GPIO_FN_PORT243_MSIOF2_TSYNC,
+	GPIO_FN_M14_GSW, GPIO_FN_PORT244_MSIOF2_TXD,
+	GPIO_FN_PORT245_IROUT, GPIO_FN_M15_RSW,
+	GPIO_FN_SOUT3, GPIO_FN_SCIFA2_TXD1,
+	GPIO_FN_SIN3, GPIO_FN_SCIFA2_RXD1,
+	GPIO_FN_XRTS3, GPIO_FN_SCIFA2_RTS1, GPIO_FN_PORT248_MSIOF2_SS2,
+	GPIO_FN_XCTS3, GPIO_FN_SCIFA2_CTS1, GPIO_FN_PORT249_MSIOF2_RXD,
+	GPIO_FN_DINT, GPIO_FN_SCIFA2_SCK1, GPIO_FN_TS_SCK3,
+	GPIO_FN_SDHICLK0, GPIO_FN_TCK2,
+	GPIO_FN_SDHICD0,
+	GPIO_FN_SDHID0_0, GPIO_FN_TMS2,
+	GPIO_FN_SDHID0_1, GPIO_FN_TDO2,
+	GPIO_FN_SDHID0_2, GPIO_FN_TDI2,
+	GPIO_FN_SDHID0_3, GPIO_FN_RTCK2,
+
+	/* 49-6 (FN) */
+	GPIO_FN_SDHICMD0, GPIO_FN_TRST2,
+	GPIO_FN_SDHIWP0, GPIO_FN_EDBGREQ2,
+	GPIO_FN_SDHICLK1, GPIO_FN_TCK3,
+	GPIO_FN_SDHID1_0, GPIO_FN_M11_SLCD_SO2,
+	GPIO_FN_TS_SPSYNC2, GPIO_FN_TMS3,
+	GPIO_FN_SDHID1_1, GPIO_FN_M9_SLCD_AO2,
+	GPIO_FN_TS_SDAT2, GPIO_FN_TDO3,
+	GPIO_FN_SDHID1_2, GPIO_FN_M10_SLCD_CK2,
+	GPIO_FN_TS_SDEN2, GPIO_FN_TDI3,
+	GPIO_FN_SDHID1_3, GPIO_FN_M12_SLCD_CE2,
+	GPIO_FN_TS_SCK2, GPIO_FN_RTCK3,
+	GPIO_FN_SDHICMD1, GPIO_FN_TRST3,
+	GPIO_FN_SDHICLK2, GPIO_FN_SCIFB_SCK,
+	GPIO_FN_SDHID2_0, GPIO_FN_SCIFB_TXD,
+	GPIO_FN_SDHID2_1, GPIO_FN_SCIFB_CTS,
+	GPIO_FN_SDHID2_2, GPIO_FN_SCIFB_RXD,
+	GPIO_FN_SDHID2_3, GPIO_FN_SCIFB_RTS,
+	GPIO_FN_SDHICMD2,
+	GPIO_FN_RESETOUTS,
+	GPIO_FN_DIVLOCK,
+};
+
+#endif /* __ASM_SH7367_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/sh7372.h linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/sh7372.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/sh7372.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/sh7372.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2010 Renesas Solutions Corp.
+ *
+ * Kuninori Morimoto <morimoto.kuninori@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.
+ */
+
+#ifndef __ASM_SH7372_H__
+#define __ASM_SH7372_H__
+
+/*
+ * Pin Function Controller:
+ *	GPIO_FN_xx - GPIO used to select pin function
+ *	GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
+ */
+enum {
+	/* PORT */
+	GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
+	GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
+
+	GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
+	GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
+
+	GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
+	GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
+
+	GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
+	GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
+
+	GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
+	GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
+
+	GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
+	GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
+
+	GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
+	GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
+
+	GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
+	GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
+
+	GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
+	GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
+
+	GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
+	GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
+
+	GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
+	GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
+
+	GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
+	GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118, GPIO_PORT119,
+
+	GPIO_PORT120, GPIO_PORT121, GPIO_PORT122, GPIO_PORT123, GPIO_PORT124,
+	GPIO_PORT125, GPIO_PORT126, GPIO_PORT127, GPIO_PORT128, GPIO_PORT129,
+
+	GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
+	GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
+
+	GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
+	GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
+
+	GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
+	GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
+
+	GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
+	GPIO_PORT165, GPIO_PORT166, GPIO_PORT167, GPIO_PORT168, GPIO_PORT169,
+
+	GPIO_PORT170, GPIO_PORT171, GPIO_PORT172, GPIO_PORT173, GPIO_PORT174,
+	GPIO_PORT175, GPIO_PORT176, GPIO_PORT177, GPIO_PORT178, GPIO_PORT179,
+
+	GPIO_PORT180, GPIO_PORT181, GPIO_PORT182, GPIO_PORT183, GPIO_PORT184,
+	GPIO_PORT185, GPIO_PORT186, GPIO_PORT187, GPIO_PORT188, GPIO_PORT189,
+
+	GPIO_PORT190,
+
+	/* IRQ */
+	GPIO_FN_IRQ0_6,		/* PORT   6 */
+	GPIO_FN_IRQ0_162,	/* PORT 162 */
+	GPIO_FN_IRQ1,		/* PORT  12 */
+	GPIO_FN_IRQ2_4,		/* PORT   4 */
+	GPIO_FN_IRQ2_5,		/* PORT   5 */
+	GPIO_FN_IRQ3_8,		/* PORT   8 */
+	GPIO_FN_IRQ3_16,	/* PORT  16 */
+	GPIO_FN_IRQ4_17,	/* PORT  17 */
+	GPIO_FN_IRQ4_163,	/* PORT 163 */
+	GPIO_FN_IRQ5,		/* PORT  18 */
+	GPIO_FN_IRQ6_39,	/* PORT  39 */
+	GPIO_FN_IRQ6_164,	/* PORT 164 */
+	GPIO_FN_IRQ7_40,	/* PORT  40 */
+	GPIO_FN_IRQ7_167,	/* PORT 167 */
+	GPIO_FN_IRQ8_41,	/* PORT  41 */
+	GPIO_FN_IRQ8_168,	/* PORT 168 */
+	GPIO_FN_IRQ9_42,	/* PORT  42 */
+	GPIO_FN_IRQ9_169,	/* PORT 169 */
+	GPIO_FN_IRQ10,		/* PORT  65 */
+	GPIO_FN_IRQ11,		/* PORT  67 */
+	GPIO_FN_IRQ12_80,	/* PORT  80 */
+	GPIO_FN_IRQ12_137,	/* PORT 137 */
+	GPIO_FN_IRQ13_81,	/* PORT  81 */
+	GPIO_FN_IRQ13_145,	/* PORT 145 */
+	GPIO_FN_IRQ14_82,	/* PORT  82 */
+	GPIO_FN_IRQ14_146,	/* PORT 146 */
+	GPIO_FN_IRQ15_83,	/* PORT  83 */
+	GPIO_FN_IRQ15_147,	/* PORT 147 */
+	GPIO_FN_IRQ16_84,	/* PORT  84 */
+	GPIO_FN_IRQ16_170,	/* PORT 170 */
+	GPIO_FN_IRQ17,		/* PORT  85 */
+	GPIO_FN_IRQ18,		/* PORT  86 */
+	GPIO_FN_IRQ19,		/* PORT  87 */
+	GPIO_FN_IRQ20,		/* PORT  92 */
+	GPIO_FN_IRQ21,		/* PORT  93 */
+	GPIO_FN_IRQ22,		/* PORT  94 */
+	GPIO_FN_IRQ23,		/* PORT  95 */
+	GPIO_FN_IRQ24,		/* PORT 112 */
+	GPIO_FN_IRQ25,		/* PORT 119 */
+	GPIO_FN_IRQ26_121,	/* PORT 121 */
+	GPIO_FN_IRQ26_172,	/* PORT 172 */
+	GPIO_FN_IRQ27_122,	/* PORT 122 */
+	GPIO_FN_IRQ27_180,	/* PORT 180 */
+	GPIO_FN_IRQ28_123,	/* PORT 123 */
+	GPIO_FN_IRQ28_181,	/* PORT 181 */
+	GPIO_FN_IRQ29_129,	/* PORT 129 */
+	GPIO_FN_IRQ29_182,	/* PORT 182 */
+	GPIO_FN_IRQ30_130,	/* PORT 130 */
+	GPIO_FN_IRQ30_183,	/* PORT 183 */
+	GPIO_FN_IRQ31_138,	/* PORT 138 */
+	GPIO_FN_IRQ31_184,	/* PORT 184 */
+
+	/*
+	 * MSIOF0	(PORT 36, 37, 38, 39
+	 * 		      40, 41, 42, 43, 44, 45)
+	 */
+	GPIO_FN_MSIOF0_TSYNC,	GPIO_FN_MSIOF0_TSCK,
+	GPIO_FN_MSIOF0_RXD,	GPIO_FN_MSIOF0_RSCK,
+	GPIO_FN_MSIOF0_RSYNC,	GPIO_FN_MSIOF0_MCK0,
+	GPIO_FN_MSIOF0_MCK1,	GPIO_FN_MSIOF0_SS1,
+	GPIO_FN_MSIOF0_SS2,	GPIO_FN_MSIOF0_TXD,
+
+	/*
+	 * MSIOF1	(PORT 39, 40, 41, 42, 43, 44
+	 * 		      84, 85, 86, 87, 88, 89, 90, 91, 92, 93)
+	 */
+	GPIO_FN_MSIOF1_TSCK_39,	GPIO_FN_MSIOF1_TSYNC_40,
+	GPIO_FN_MSIOF1_TSCK_88,	GPIO_FN_MSIOF1_TSYNC_89,
+	GPIO_FN_MSIOF1_TXD_41,	GPIO_FN_MSIOF1_RXD_42,
+	GPIO_FN_MSIOF1_TXD_90,	GPIO_FN_MSIOF1_RXD_91,
+	GPIO_FN_MSIOF1_SS1_43,	GPIO_FN_MSIOF1_SS2_44,
+	GPIO_FN_MSIOF1_SS1_92,	GPIO_FN_MSIOF1_SS2_93,
+	GPIO_FN_MSIOF1_RSCK,	GPIO_FN_MSIOF1_RSYNC,
+	GPIO_FN_MSIOF1_MCK0,	GPIO_FN_MSIOF1_MCK1,
+
+	/*
+	 * MSIOF2	(PORT 134, 135, 136, 137, 138, 139
+	 *		      148, 149, 150, 151)
+	 */
+	GPIO_FN_MSIOF2_RSCK,	GPIO_FN_MSIOF2_RSYNC,
+	GPIO_FN_MSIOF2_MCK0,	GPIO_FN_MSIOF2_MCK1,
+	GPIO_FN_MSIOF2_SS1,	GPIO_FN_MSIOF2_SS2,
+	GPIO_FN_MSIOF2_TSYNC,	GPIO_FN_MSIOF2_TSCK,
+	GPIO_FN_MSIOF2_RXD,	GPIO_FN_MSIOF2_TXD,
+
+	/* MSIOF3	(PORT 76, 77, 78, 79, 80, 81, 82, 83) */
+	GPIO_FN_BBIF1_RXD,	GPIO_FN_BBIF1_TSYNC,
+	GPIO_FN_BBIF1_TSCK,	GPIO_FN_BBIF1_TXD,
+	GPIO_FN_BBIF1_RSCK,	GPIO_FN_BBIF1_RSYNC,
+	GPIO_FN_BBIF1_FLOW,	GPIO_FN_BB_RX_FLOW_N,
+
+	/* MSIOF4	(PORT 0, 1, 2, 3) */
+	GPIO_FN_BBIF2_TSCK1,	GPIO_FN_BBIF2_TSYNC1,
+	GPIO_FN_BBIF2_TXD1,	GPIO_FN_BBIF2_RXD,
+
+	/* FSI		(PORT 4, 5, 6, 7, 8, 9, 10, 11, 15) */
+	GPIO_FN_FSIACK,		GPIO_FN_FSIBCK,
+	GPIO_FN_FSIAILR,	GPIO_FN_FSIAIBT,
+	GPIO_FN_FSIAISLD,	GPIO_FN_FSIAOMC,
+	GPIO_FN_FSIAOLR,	GPIO_FN_FSIAOBT,
+	GPIO_FN_FSIAOSLD,	GPIO_FN_FSIASPDIF_11,
+	GPIO_FN_FSIASPDIF_15,
+
+	/* FMSI		(PORT 12, 13, 14, 15, 16, 17, 18, 65) */
+	GPIO_FN_FMSOCK,		GPIO_FN_FMSOOLR,
+	GPIO_FN_FMSIOLR,	GPIO_FN_FMSOOBT,
+	GPIO_FN_FMSIOBT,	GPIO_FN_FMSOSLD,
+	GPIO_FN_FMSOILR,	GPIO_FN_FMSIILR,
+	GPIO_FN_FMSOIBT,	GPIO_FN_FMSIIBT,
+	GPIO_FN_FMSISLD,	GPIO_FN_FMSICK,
+
+	/* SCIFA0	(PORT 152, 153, 156, 157, 158) */
+	GPIO_FN_SCIFA0_TXD,	GPIO_FN_SCIFA0_RXD,
+	GPIO_FN_SCIFA0_SCK,	GPIO_FN_SCIFA0_RTS,
+	GPIO_FN_SCIFA0_CTS,
+
+	/* SCIFA1	(PORT 154, 155, 159, 160, 161) */
+	GPIO_FN_SCIFA1_TXD,	GPIO_FN_SCIFA1_RXD,
+	GPIO_FN_SCIFA1_SCK,	GPIO_FN_SCIFA1_RTS,
+	GPIO_FN_SCIFA1_CTS,
+
+	/* SCIFA2	(PORT 94, 95, 96, 97, 98) */
+	GPIO_FN_SCIFA2_CTS1,	GPIO_FN_SCIFA2_RTS1,
+	GPIO_FN_SCIFA2_TXD1,	GPIO_FN_SCIFA2_RXD1,
+	GPIO_FN_SCIFA2_SCK1,
+
+	/* SCIFA3	(PORT 43, 44,
+			     140, 141, 142, 143, 144) */
+	GPIO_FN_SCIFA3_CTS_43,	GPIO_FN_SCIFA3_CTS_140,
+	GPIO_FN_SCIFA3_RTS_44,	GPIO_FN_SCIFA3_RTS_141,
+	GPIO_FN_SCIFA3_SCK,	GPIO_FN_SCIFA3_TXD,
+	GPIO_FN_SCIFA3_RXD,
+
+	/* SCIFA4	(PORT 5, 6) */
+	GPIO_FN_SCIFA4_RXD,	GPIO_FN_SCIFA4_TXD,
+
+	/* SCIFA5	(PORT 8, 12) */
+	GPIO_FN_SCIFA5_RXD,	GPIO_FN_SCIFA5_TXD,
+
+	/* SCIFB	(PORT 162, 163, 164, 165, 166) */
+	GPIO_FN_SCIFB_SCK,	GPIO_FN_SCIFB_RTS,
+	GPIO_FN_SCIFB_CTS,	GPIO_FN_SCIFB_TXD,
+	GPIO_FN_SCIFB_RXD,
+
+	/*
+	 * CEU		(PORT 16, 17,
+	 *		      100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+	 *		      110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+	 *		      120)
+	 */
+	GPIO_FN_VIO_HD,		GPIO_FN_VIO_CKO1,	GPIO_FN_VIO_CKO2,
+	GPIO_FN_VIO_VD,		GPIO_FN_VIO_CLK,	GPIO_FN_VIO_FIELD,
+	GPIO_FN_VIO_CKO,
+	GPIO_FN_VIO_D0,		GPIO_FN_VIO_D1,		GPIO_FN_VIO_D2,
+	GPIO_FN_VIO_D3,		GPIO_FN_VIO_D4,		GPIO_FN_VIO_D5,
+	GPIO_FN_VIO_D6,		GPIO_FN_VIO_D7,		GPIO_FN_VIO_D8,
+	GPIO_FN_VIO_D9,		GPIO_FN_VIO_D10,	GPIO_FN_VIO_D11,
+	GPIO_FN_VIO_D12,	GPIO_FN_VIO_D13,	GPIO_FN_VIO_D14,
+	GPIO_FN_VIO_D15,
+
+	/* USB0		(PORT 113, 114, 115, 116, 117, 167) */
+	GPIO_FN_IDIN_0,		GPIO_FN_EXTLP_0,
+	GPIO_FN_OVCN2_0,	GPIO_FN_PWEN_0,
+	GPIO_FN_OVCN_0,		GPIO_FN_VBUS0_0,
+
+	/* USB1		(PORT 18, 113, 114, 115, 116, 117, 138, 162, 168) */
+	GPIO_FN_IDIN_1_18,	GPIO_FN_IDIN_1_113,
+	GPIO_FN_PWEN_1_115,	GPIO_FN_PWEN_1_138,
+	GPIO_FN_OVCN_1_114,	GPIO_FN_OVCN_1_162,
+	GPIO_FN_EXTLP_1,	GPIO_FN_OVCN2_1,
+	GPIO_FN_VBUS0_1,
+
+	/* GPIO		(PORT 41, 42, 43, 44) */
+	GPIO_FN_GPI0,	GPIO_FN_GPI1,	GPIO_FN_GPO0,	GPIO_FN_GPO1,
+
+	/*
+	 * BSC		(PORT 19,
+	 *		      20, 21, 22, 25, 26, 27, 28, 29,
+	 *		      30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+	 *		      40, 41, 42, 43, 44, 45,
+	 *		      62, 63, 64, 65, 66, 67,
+	 *		      71, 72, 74, 75)
+	 */
+	GPIO_FN_BS,	GPIO_FN_WE1,
+	GPIO_FN_CKO,	GPIO_FN_WAIT,	GPIO_FN_RDWR,
+
+	GPIO_FN_A0,	GPIO_FN_A1,	GPIO_FN_A2,	GPIO_FN_A3,
+	GPIO_FN_A6,	GPIO_FN_A7,	GPIO_FN_A8,	GPIO_FN_A9,
+	GPIO_FN_A10,	GPIO_FN_A11,	GPIO_FN_A12,	GPIO_FN_A13,
+	GPIO_FN_A14,	GPIO_FN_A15,	GPIO_FN_A16,	GPIO_FN_A17,
+	GPIO_FN_A18,	GPIO_FN_A19,	GPIO_FN_A20,	GPIO_FN_A21,
+	GPIO_FN_A22,	GPIO_FN_A23,	GPIO_FN_A24,	GPIO_FN_A25,
+	GPIO_FN_A26,
+
+	GPIO_FN_CS0,	GPIO_FN_CS2,	GPIO_FN_CS4,
+	GPIO_FN_CS5A,	GPIO_FN_CS5B,	GPIO_FN_CS6A,
+
+	/*
+	 * BSC/FLCTL		(PORT 23, 24,
+	 *			      46, 47, 48, 49,
+	 *			      50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+	 *			      60, 61, 69, 70)
+	 */
+	GPIO_FN_RD_FSC,		GPIO_FN_WE0_FWE,
+	GPIO_FN_A4_FOE,		GPIO_FN_A5_FCDE,
+	GPIO_FN_D0_NAF0,	GPIO_FN_D1_NAF1,	GPIO_FN_D2_NAF2,
+	GPIO_FN_D3_NAF3,	GPIO_FN_D4_NAF4,	GPIO_FN_D5_NAF5,
+	GPIO_FN_D6_NAF6,	GPIO_FN_D7_NAF7,	GPIO_FN_D8_NAF8,
+	GPIO_FN_D9_NAF9,	GPIO_FN_D10_NAF10,	GPIO_FN_D11_NAF11,
+	GPIO_FN_D12_NAF12,	GPIO_FN_D13_NAF13,	GPIO_FN_D14_NAF14,
+	GPIO_FN_D15_NAF15,
+
+	/*
+	 * MMCIF(1)		(PORT 84, 85, 86, 87, 88, 89,
+	 *			      90, 91, 92, 99)
+	 */
+	GPIO_FN_MMCD0_0,	GPIO_FN_MMCD0_1,	GPIO_FN_MMCD0_2,
+	GPIO_FN_MMCD0_3,	GPIO_FN_MMCD0_4,	GPIO_FN_MMCD0_5,
+	GPIO_FN_MMCD0_6,	GPIO_FN_MMCD0_7,
+	GPIO_FN_MMCCMD0,	GPIO_FN_MMCCLK0,
+
+	/* MMCIF(2)		(PORT 54, 55, 56, 57, 58, 59, 60, 61, 66, 67) */
+	GPIO_FN_MMCD1_0,	GPIO_FN_MMCD1_1,	GPIO_FN_MMCD1_2,
+	GPIO_FN_MMCD1_3,	GPIO_FN_MMCD1_4,	GPIO_FN_MMCD1_5,
+	GPIO_FN_MMCD1_6,	GPIO_FN_MMCD1_7,
+	GPIO_FN_MMCCLK1,	GPIO_FN_MMCCMD1,
+
+	/* SPU2		(PORT 65) */
+	GPIO_FN_VINT_I,
+
+	/* FLCTL	(PORT 66, 68, 73) */
+	GPIO_FN_FCE1,	GPIO_FN_FCE0,	GPIO_FN_FRB,
+
+	/* HSI		(PORT 76, 77, 78, 79, 80, 81, 82, 83) */
+	GPIO_FN_GP_RX_FLAG,	GPIO_FN_GP_RX_DATA,	GPIO_FN_GP_TX_READY,
+	GPIO_FN_GP_RX_WAKE,	GPIO_FN_MP_TX_FLAG,	GPIO_FN_MP_TX_DATA,
+	GPIO_FN_MP_RX_READY,	GPIO_FN_MP_TX_WAKE,
+
+	/*
+	 * MFI		(PORT 76, 77, 78, 79,
+	 *		      80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+	 *		      90, 91, 92, 93, 94, 95, 96, 97, 98, 99)
+	 */
+	GPIO_FN_MFIv6,	/* see MSEL4CR 6 */
+	GPIO_FN_MFIv4,	/* see MSEL4CR 6 */
+
+	GPIO_FN_MEMC_CS0,		GPIO_FN_MEMC_BUSCLK_MEMC_A0,
+	GPIO_FN_MEMC_CS1_MEMC_A1,	GPIO_FN_MEMC_ADV_MEMC_DREQ0,
+	GPIO_FN_MEMC_WAIT_MEMC_DREQ1,	GPIO_FN_MEMC_NOE,
+	GPIO_FN_MEMC_NWE,		GPIO_FN_MEMC_INT,
+
+	GPIO_FN_MEMC_AD0,	GPIO_FN_MEMC_AD1,	GPIO_FN_MEMC_AD2,
+	GPIO_FN_MEMC_AD3,	GPIO_FN_MEMC_AD4,	GPIO_FN_MEMC_AD5,
+	GPIO_FN_MEMC_AD6,	GPIO_FN_MEMC_AD7,	GPIO_FN_MEMC_AD8,
+	GPIO_FN_MEMC_AD9,	GPIO_FN_MEMC_AD10,	GPIO_FN_MEMC_AD11,
+	GPIO_FN_MEMC_AD12,	GPIO_FN_MEMC_AD13,	GPIO_FN_MEMC_AD14,
+	GPIO_FN_MEMC_AD15,
+
+	/* SIM		(PORT 94, 95, 98) */
+	GPIO_FN_SIM_RST,	GPIO_FN_SIM_CLK,	GPIO_FN_SIM_D,
+
+	/* TPU		(PORT 93, 99, 112, 160, 161) */
+	GPIO_FN_TPU0TO0,	GPIO_FN_TPU0TO1,
+	GPIO_FN_TPU0TO2_93,	GPIO_FN_TPU0TO2_99,
+	GPIO_FN_TPU0TO3,
+
+	/* I2C2		(PORT 110, 111) */
+	GPIO_FN_I2C_SCL2,	GPIO_FN_I2C_SDA2,
+
+	/* I2C3(1)	(PORT 114, 115) */
+	GPIO_FN_I2C_SCL3,	GPIO_FN_I2C_SDA3,
+
+	/* I2C3(2)	(PORT 137, 145) */
+	GPIO_FN_I2C_SCL3S,	GPIO_FN_I2C_SDA3S,
+
+	/* I2C4(2)	(PORT 116, 117) */
+	GPIO_FN_I2C_SCL4,	GPIO_FN_I2C_SDA4,
+
+	/* I2C4(2)	(PORT 146, 147) */
+	GPIO_FN_I2C_SCL4S,	GPIO_FN_I2C_SDA4S,
+
+	/*
+	 * KEYSC	(PORT 121, 122, 123, 124, 125, 126, 127, 128, 129,
+	 *		      130, 131, 132, 133, 134, 135, 136)
+	 */
+	GPIO_FN_KEYOUT0,	GPIO_FN_KEYIN0_121,	GPIO_FN_KEYIN0_136,
+	GPIO_FN_KEYOUT1,	GPIO_FN_KEYIN1_122,	GPIO_FN_KEYIN1_135,
+	GPIO_FN_KEYOUT2,	GPIO_FN_KEYIN2_123,	GPIO_FN_KEYIN2_134,
+	GPIO_FN_KEYOUT3,	GPIO_FN_KEYIN3_124,	GPIO_FN_KEYIN3_133,
+	GPIO_FN_KEYOUT4,	GPIO_FN_KEYIN4,
+	GPIO_FN_KEYOUT5,	GPIO_FN_KEYIN5,
+	GPIO_FN_KEYOUT6,	GPIO_FN_KEYIN6,
+	GPIO_FN_KEYOUT7,	GPIO_FN_KEYIN7,
+
+	/*
+	 * LCDC		(PORT      121, 122, 123, 124, 125, 126, 127, 128, 129,
+	 *		      130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
+	 *		      140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+	 *		      150, 151)
+	 */
+	GPIO_FN_LCDC0_SELECT, /* LCDC 0 */
+	GPIO_FN_LCDC1_SELECT, /* LCDC 1 */
+	GPIO_FN_LCDHSYN,	GPIO_FN_LCDCS,	GPIO_FN_LCDVSYN,
+	GPIO_FN_LCDDCK,		GPIO_FN_LCDWR,	GPIO_FN_LCDRD,
+	GPIO_FN_LCDDISP,	GPIO_FN_LCDRS,	GPIO_FN_LCDLCLK,
+	GPIO_FN_LCDDON,
+
+	GPIO_FN_LCDD0,	GPIO_FN_LCDD1,	GPIO_FN_LCDD2,	GPIO_FN_LCDD3,
+	GPIO_FN_LCDD4,	GPIO_FN_LCDD5,	GPIO_FN_LCDD6,	GPIO_FN_LCDD7,
+	GPIO_FN_LCDD8,	GPIO_FN_LCDD9,	GPIO_FN_LCDD10,	GPIO_FN_LCDD11,
+	GPIO_FN_LCDD12,	GPIO_FN_LCDD13,	GPIO_FN_LCDD14,	GPIO_FN_LCDD15,
+	GPIO_FN_LCDD16,	GPIO_FN_LCDD17,	GPIO_FN_LCDD18,	GPIO_FN_LCDD19,
+	GPIO_FN_LCDD20,	GPIO_FN_LCDD21,	GPIO_FN_LCDD22,	GPIO_FN_LCDD23,
+
+	/* IRDA		(PORT 139, 140, 141, 142) */
+	GPIO_FN_IRDA_OUT,	GPIO_FN_IRDA_IN,	GPIO_FN_IRDA_FIRSEL,
+	GPIO_FN_IROUT_139,	GPIO_FN_IROUT_140,
+
+	/* TSIF1	(PORT 156, 157, 158, 159) */
+	GPIO_FN_TS0_1SELECT, /* TSIF0 - 1 select */
+	GPIO_FN_TS0_2SELECT, /* TSIF0 - 2 select */
+	GPIO_FN_TS1_1SELECT, /* TSIF1 - 1 select */
+	GPIO_FN_TS1_2SELECT, /* TSIF1 - 2 select */
+
+	GPIO_FN_TS_SPSYNC1,	GPIO_FN_TS_SDAT1,
+	GPIO_FN_TS_SDEN1,	GPIO_FN_TS_SCK1,
+
+	/* TSIF2	(PORT 137, 145, 146, 147) */
+	GPIO_FN_TS_SPSYNC2,	GPIO_FN_TS_SDAT2,
+	GPIO_FN_TS_SDEN2,	GPIO_FN_TS_SCK2,
+
+	/* HDMI		(PORT 169, 170) */
+	GPIO_FN_HDMI_HPD,	GPIO_FN_HDMI_CEC,
+
+	/* SDHI0	(PORT 171, 172, 173, 174, 175, 176, 177, 178) */
+	GPIO_FN_SDHICLK0,	GPIO_FN_SDHICD0,
+	GPIO_FN_SDHICMD0,	GPIO_FN_SDHIWP0,
+	GPIO_FN_SDHID0_0,	GPIO_FN_SDHID0_1,
+	GPIO_FN_SDHID0_2,	GPIO_FN_SDHID0_3,
+
+	/* SDHI1	(PORT 179, 180, 181, 182, 183, 184) */
+	GPIO_FN_SDHICLK1,	GPIO_FN_SDHICMD1,	GPIO_FN_SDHID1_0,
+	GPIO_FN_SDHID1_1,	GPIO_FN_SDHID1_2,	GPIO_FN_SDHID1_3,
+
+	/* SDHI2	(PORT 185, 186, 187, 188, 189, 190) */
+	GPIO_FN_SDHICLK2,	GPIO_FN_SDHICMD2,	GPIO_FN_SDHID2_0,
+	GPIO_FN_SDHID2_1,	GPIO_FN_SDHID2_2,	GPIO_FN_SDHID2_3,
+
+	/* SDENC	see MSEL4CR 19 */
+	GPIO_FN_SDENC_CPG,
+	GPIO_FN_SDENC_DV_CLKI,
+};
+
+#endif /* __ASM_SH7372_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/sh7377.h linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/sh7377.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/sh7377.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/sh7377.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,360 @@
+#ifndef __ASM_SH7377_H__
+#define __ASM_SH7377_H__
+
+/* Pin Function Controller:
+ * GPIO_FN_xx - GPIO used to select pin function
+ * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
+ */
+enum {
+	/* 55-1 -> 55-5 (GPIO) */
+	GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
+	GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
+
+	GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
+	GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
+
+	GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
+	GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
+
+	GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
+	GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
+
+	GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
+	GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
+
+	GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
+	GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
+
+	GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
+	GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
+
+	GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
+	GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
+
+	GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
+	GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
+
+	GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
+	GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
+
+	GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
+	GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
+
+	GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
+	GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118,
+
+	GPIO_PORT128, GPIO_PORT129,
+
+	GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
+	GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
+
+	GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
+	GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
+
+	GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
+	GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
+
+	GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
+
+	GPIO_PORT192, GPIO_PORT193, GPIO_PORT194,
+	GPIO_PORT195, GPIO_PORT196, GPIO_PORT197, GPIO_PORT198, GPIO_PORT199,
+
+	GPIO_PORT200, GPIO_PORT201, GPIO_PORT202, GPIO_PORT203, GPIO_PORT204,
+	GPIO_PORT205, GPIO_PORT206, GPIO_PORT207, GPIO_PORT208, GPIO_PORT209,
+
+	GPIO_PORT210, GPIO_PORT211, GPIO_PORT212, GPIO_PORT213, GPIO_PORT214,
+	GPIO_PORT215, GPIO_PORT216, GPIO_PORT217, GPIO_PORT218, GPIO_PORT219,
+
+	GPIO_PORT220, GPIO_PORT221, GPIO_PORT222, GPIO_PORT223, GPIO_PORT224,
+	GPIO_PORT225, GPIO_PORT226, GPIO_PORT227, GPIO_PORT228, GPIO_PORT229,
+
+	GPIO_PORT230, GPIO_PORT231, GPIO_PORT232, GPIO_PORT233, GPIO_PORT234,
+	GPIO_PORT235, GPIO_PORT236, GPIO_PORT237, GPIO_PORT238, GPIO_PORT239,
+
+	GPIO_PORT240, GPIO_PORT241, GPIO_PORT242, GPIO_PORT243, GPIO_PORT244,
+	GPIO_PORT245, GPIO_PORT246, GPIO_PORT247, GPIO_PORT248, GPIO_PORT249,
+
+	GPIO_PORT250, GPIO_PORT251, GPIO_PORT252, GPIO_PORT253, GPIO_PORT254,
+	GPIO_PORT255, GPIO_PORT256, GPIO_PORT257, GPIO_PORT258, GPIO_PORT259,
+
+	GPIO_PORT260, GPIO_PORT261, GPIO_PORT262, GPIO_PORT263, GPIO_PORT264,
+
+	/* Special Pull-up / Pull-down Functions */
+	GPIO_FN_PORT66_KEYIN0_PU, GPIO_FN_PORT67_KEYIN1_PU,
+	GPIO_FN_PORT68_KEYIN2_PU, GPIO_FN_PORT69_KEYIN3_PU,
+	GPIO_FN_PORT70_KEYIN4_PU, GPIO_FN_PORT71_KEYIN5_PU,
+	GPIO_FN_PORT72_KEYIN6_PU,
+
+	/* 55-1 (FN) */
+	GPIO_FN_VBUS_0,
+	GPIO_FN_CPORT0,
+	GPIO_FN_CPORT1,
+	GPIO_FN_CPORT2,
+	GPIO_FN_CPORT3,
+	GPIO_FN_CPORT4,
+	GPIO_FN_CPORT5,
+	GPIO_FN_CPORT6,
+	GPIO_FN_CPORT7,
+	GPIO_FN_CPORT8,
+	GPIO_FN_CPORT9,
+	GPIO_FN_CPORT10,
+	GPIO_FN_CPORT11, GPIO_FN_SIN2,
+	GPIO_FN_CPORT12, GPIO_FN_XCTS2,
+	GPIO_FN_CPORT13, GPIO_FN_RFSPO4,
+	GPIO_FN_CPORT14, GPIO_FN_RFSPO5,
+	GPIO_FN_CPORT15, GPIO_FN_SCIFA0_SCK, GPIO_FN_GPS_AGC2,
+	GPIO_FN_CPORT16, GPIO_FN_SCIFA0_TXD, GPIO_FN_GPS_AGC3,
+	GPIO_FN_CPORT17_IC_OE, GPIO_FN_SOUT2,
+	GPIO_FN_CPORT18, GPIO_FN_XRTS2, GPIO_FN_PORT19_VIO_CKO2,
+	GPIO_FN_CPORT19_MPORT1,
+	GPIO_FN_CPORT20, GPIO_FN_RFSPO6,
+	GPIO_FN_CPORT21, GPIO_FN_STATUS0,
+	GPIO_FN_CPORT22, GPIO_FN_STATUS1,
+	GPIO_FN_CPORT23, GPIO_FN_STATUS2, GPIO_FN_RFSPO7,
+	GPIO_FN_B_SYNLD1,
+	GPIO_FN_B_SYNLD2, GPIO_FN_SYSENMSK,
+	GPIO_FN_XMAINPS,
+	GPIO_FN_XDIVPS,
+	GPIO_FN_XIDRST,
+	GPIO_FN_IDCLK, GPIO_FN_IC_DP,
+	GPIO_FN_IDIO, GPIO_FN_IC_DM,
+	GPIO_FN_SOUT1, GPIO_FN_SCIFA4_TXD, GPIO_FN_M02_BERDAT,
+	GPIO_FN_SIN1, GPIO_FN_SCIFA4_RXD, GPIO_FN_XWUP,
+	GPIO_FN_XRTS1, GPIO_FN_SCIFA4_RTS, GPIO_FN_M03_BERCLK,
+	GPIO_FN_XCTS1, GPIO_FN_SCIFA4_CTS,
+	GPIO_FN_PCMCLKO,
+	GPIO_FN_SYNC8KO,
+
+	/* 55-2 (FN) */
+	GPIO_FN_DNPCM_A,
+	GPIO_FN_UPPCM_A,
+	GPIO_FN_VACK,
+	GPIO_FN_XTALB1L,
+	GPIO_FN_GPS_AGC1, GPIO_FN_SCIFA0_RTS,
+	GPIO_FN_GPS_AGC4, GPIO_FN_SCIFA0_RXD,
+	GPIO_FN_GPS_PWRDOWN, GPIO_FN_SCIFA0_CTS,
+	GPIO_FN_GPS_IM,
+	GPIO_FN_GPS_IS,
+	GPIO_FN_GPS_QM,
+	GPIO_FN_GPS_QS,
+	GPIO_FN_FMSOCK, GPIO_FN_PORT49_IRDA_OUT, GPIO_FN_PORT49_IROUT,
+	GPIO_FN_FMSOOLR, GPIO_FN_BBIF2_TSYNC2, GPIO_FN_TPU2TO2, GPIO_FN_IPORT3,
+	GPIO_FN_FMSIOLR,
+	GPIO_FN_FMSOOBT, GPIO_FN_BBIF2_TSCK2, GPIO_FN_TPU2TO3, GPIO_FN_OPORT1,
+	GPIO_FN_FMSIOBT,
+	GPIO_FN_FMSOSLD, GPIO_FN_BBIF2_TXD2, GPIO_FN_OPORT2,
+	GPIO_FN_FMSOILR, GPIO_FN_PORT53_IRDA_IN, GPIO_FN_TPU3TO3,
+	GPIO_FN_OPORT3, GPIO_FN_FMSIILR,
+	GPIO_FN_FMSOIBT, GPIO_FN_PORT54_IRDA_FIRSEL, GPIO_FN_TPU3TO2,
+	GPIO_FN_FMSIIBT,
+	GPIO_FN_FMSISLD, GPIO_FN_MFG0_OUT1, GPIO_FN_TPU0TO0,
+	GPIO_FN_A0_EA0, GPIO_FN_BS,
+	GPIO_FN_A12_EA12, GPIO_FN_PORT58_VIO_CKOR, GPIO_FN_TPU4TO2,
+	GPIO_FN_A13_EA13, GPIO_FN_PORT59_IROUT, GPIO_FN_MFG0_OUT2,
+	GPIO_FN_TPU0TO1,
+	GPIO_FN_A14_EA14, GPIO_FN_PORT60_KEYOUT5,
+	GPIO_FN_A15_EA15, GPIO_FN_PORT61_KEYOUT4,
+	GPIO_FN_A16_EA16, GPIO_FN_PORT62_KEYOUT3, GPIO_FN_MSIOF0_SS1,
+	GPIO_FN_A17_EA17, GPIO_FN_PORT63_KEYOUT2, GPIO_FN_MSIOF0_TSYNC,
+	GPIO_FN_A18_EA18, GPIO_FN_PORT64_KEYOUT1, GPIO_FN_MSIOF0_TSCK,
+	GPIO_FN_A19_EA19, GPIO_FN_PORT65_KEYOUT0, GPIO_FN_MSIOF0_TXD,
+	GPIO_FN_A20_EA20, GPIO_FN_PORT66_KEYIN0, GPIO_FN_MSIOF0_RSCK,
+	GPIO_FN_A21_EA21, GPIO_FN_PORT67_KEYIN1, GPIO_FN_MSIOF0_RSYNC,
+	GPIO_FN_A22_EA22, GPIO_FN_PORT68_KEYIN2, GPIO_FN_MSIOF0_MCK0,
+	GPIO_FN_A23_EA23, GPIO_FN_PORT69_KEYIN3, GPIO_FN_MSIOF0_MCK1,
+	GPIO_FN_A24_EA24, GPIO_FN_PORT70_KEYIN4, GPIO_FN_MSIOF0_RXD,
+	GPIO_FN_A25_EA25, GPIO_FN_PORT71_KEYIN5, GPIO_FN_MSIOF0_SS2,
+	GPIO_FN_A26, GPIO_FN_PORT72_KEYIN6,
+	GPIO_FN_D0_ED0_NAF0,
+	GPIO_FN_D1_ED1_NAF1,
+	GPIO_FN_D2_ED2_NAF2,
+	GPIO_FN_D3_ED3_NAF3,
+	GPIO_FN_D4_ED4_NAF4,
+	GPIO_FN_D5_ED5_NAF5,
+	GPIO_FN_D6_ED6_NAF6,
+	GPIO_FN_D7_ED7_NAF7,
+	GPIO_FN_D8_ED8_NAF8,
+	GPIO_FN_D9_ED9_NAF9,
+	GPIO_FN_D10_ED10_NAF10,
+	GPIO_FN_D11_ED11_NAF11,
+	GPIO_FN_D12_ED12_NAF12,
+	GPIO_FN_D13_ED13_NAF13,
+	GPIO_FN_D14_ED14_NAF14,
+	GPIO_FN_D15_ED15_NAF15,
+	GPIO_FN_CS4,
+	GPIO_FN_CS5A, GPIO_FN_FMSICK,
+	GPIO_FN_CS5B, GPIO_FN_FCE1,
+
+	/* 55-3 (FN) */
+	GPIO_FN_CS6B, GPIO_FN_XCS2, GPIO_FN_CS6A, GPIO_FN_DACK0,
+	GPIO_FN_FCE0,
+	GPIO_FN_WAIT, GPIO_FN_DREQ0,
+	GPIO_FN_RD_XRD,
+	GPIO_FN_WE0_XWR0_FWE,
+	GPIO_FN_WE1_XWR1,
+	GPIO_FN_FRB,
+	GPIO_FN_CKO,
+	GPIO_FN_NBRSTOUT,
+	GPIO_FN_NBRST,
+	GPIO_FN_GPS_EPPSIN,
+	GPIO_FN_LATCHPULSE,
+	GPIO_FN_LTESIGNAL,
+	GPIO_FN_LEGACYSTATE,
+	GPIO_FN_TCKON,
+	GPIO_FN_VIO_VD, GPIO_FN_PORT128_KEYOUT0, GPIO_FN_IPORT0,
+	GPIO_FN_VIO_HD, GPIO_FN_PORT129_KEYOUT1, GPIO_FN_IPORT1,
+	GPIO_FN_VIO_D0, GPIO_FN_PORT130_KEYOUT2, GPIO_FN_PORT130_MSIOF2_RXD,
+	GPIO_FN_VIO_D1, GPIO_FN_PORT131_KEYOUT3, GPIO_FN_PORT131_MSIOF2_SS1,
+	GPIO_FN_VIO_D2, GPIO_FN_PORT132_KEYOUT4, GPIO_FN_PORT132_MSIOF2_SS2,
+	GPIO_FN_VIO_D3, GPIO_FN_PORT133_KEYOUT5, GPIO_FN_PORT133_MSIOF2_TSYNC,
+	GPIO_FN_VIO_D4, GPIO_FN_PORT134_KEYIN0, GPIO_FN_PORT134_MSIOF2_TXD,
+	GPIO_FN_VIO_D5, GPIO_FN_PORT135_KEYIN1, GPIO_FN_PORT135_MSIOF2_TSCK,
+	GPIO_FN_VIO_D6, GPIO_FN_PORT136_KEYIN2,
+	GPIO_FN_VIO_D7, GPIO_FN_PORT137_KEYIN3,
+	GPIO_FN_VIO_D8, GPIO_FN_M9_SLCD_A01, GPIO_FN_PORT138_FSIAOMC,
+	GPIO_FN_VIO_D9, GPIO_FN_M10_SLCD_CK1, GPIO_FN_PORT139_FSIAOLR,
+	GPIO_FN_VIO_D10, GPIO_FN_M11_SLCD_SO1, GPIO_FN_TPU0TO2,
+	GPIO_FN_PORT140_FSIAOBT,
+	GPIO_FN_VIO_D11, GPIO_FN_M12_SLCD_CE1, GPIO_FN_TPU0TO3,
+	GPIO_FN_PORT141_FSIAOSLD,
+	GPIO_FN_VIO_D12, GPIO_FN_M13_BSW, GPIO_FN_PORT142_FSIACK,
+	GPIO_FN_VIO_D13, GPIO_FN_M14_GSW, GPIO_FN_PORT143_FSIAILR,
+	GPIO_FN_VIO_D14, GPIO_FN_M15_RSW, GPIO_FN_PORT144_FSIAIBT,
+	GPIO_FN_VIO_D15, GPIO_FN_TPU1TO3, GPIO_FN_PORT145_FSIAISLD,
+	GPIO_FN_VIO_CLK, GPIO_FN_PORT146_KEYIN4, GPIO_FN_IPORT2,
+	GPIO_FN_VIO_FIELD, GPIO_FN_PORT147_KEYIN5,
+	GPIO_FN_VIO_CKO, GPIO_FN_PORT148_KEYIN6,
+	GPIO_FN_A27, GPIO_FN_RDWR_XWE, GPIO_FN_MFG0_IN1,
+	GPIO_FN_MFG0_IN2,
+	GPIO_FN_TS_SPSYNC3, GPIO_FN_MSIOF2_RSCK,
+	GPIO_FN_TS_SDAT3, GPIO_FN_MSIOF2_RSYNC,
+	GPIO_FN_TPU1TO2, GPIO_FN_TS_SDEN3, GPIO_FN_PORT153_MSIOF2_SS1,
+	GPIO_FN_SOUT3, GPIO_FN_SCIFA2_TXD1, GPIO_FN_MSIOF2_MCK0,
+	GPIO_FN_SIN3, GPIO_FN_SCIFA2_RXD1, GPIO_FN_MSIOF2_MCK1,
+	GPIO_FN_XRTS3, GPIO_FN_SCIFA2_RTS1, GPIO_FN_PORT156_MSIOF2_SS2,
+	GPIO_FN_XCTS3, GPIO_FN_SCIFA2_CTS1, GPIO_FN_PORT157_MSIOF2_RXD,
+
+	/* 55-4 (FN) */
+	GPIO_FN_DINT, GPIO_FN_SCIFA2_SCK1, GPIO_FN_TS_SCK3,
+	GPIO_FN_PORT159_SCIFB_SCK, GPIO_FN_PORT159_SCIFA5_SCK, GPIO_FN_NMI,
+	GPIO_FN_PORT160_SCIFB_TXD, GPIO_FN_PORT160_SCIFA5_TXD, GPIO_FN_SOUT0,
+	GPIO_FN_PORT161_SCIFB_CTS, GPIO_FN_PORT161_SCIFA5_CTS, GPIO_FN_XCTS0,
+	GPIO_FN_MFG3_IN2,
+	GPIO_FN_PORT162_SCIFB_RXD, GPIO_FN_PORT162_SCIFA5_RXD, GPIO_FN_SIN0,
+	GPIO_FN_MFG3_IN1,
+	GPIO_FN_PORT163_SCIFB_RTS, GPIO_FN_PORT163_SCIFA5_RTS, GPIO_FN_XRTS0,
+	GPIO_FN_MFG3_OUT1,
+	GPIO_FN_TPU3TO0,
+	GPIO_FN_LCDD0, GPIO_FN_PORT192_KEYOUT0, GPIO_FN_EXT_CKI,
+	GPIO_FN_LCDD1, GPIO_FN_PORT193_KEYOUT1, GPIO_FN_PORT193_SCIFA5_CTS,
+	GPIO_FN_BBIF2_TSYNC1,
+	GPIO_FN_LCDD2, GPIO_FN_PORT194_KEYOUT2, GPIO_FN_PORT194_SCIFA5_RTS,
+	GPIO_FN_BBIF2_TSCK1,
+	GPIO_FN_LCDD3, GPIO_FN_PORT195_KEYOUT3, GPIO_FN_PORT195_SCIFA5_RXD,
+	GPIO_FN_BBIF2_TXD1,
+	GPIO_FN_LCDD4, GPIO_FN_PORT196_KEYOUT4, GPIO_FN_PORT196_SCIFA5_TXD,
+	GPIO_FN_LCDD5, GPIO_FN_PORT197_KEYOUT5, GPIO_FN_PORT197_SCIFA5_SCK,
+	GPIO_FN_MFG2_OUT2, GPIO_FN_TPU2TO1,
+	GPIO_FN_LCDD6, GPIO_FN_XWR2,
+	GPIO_FN_LCDD7, GPIO_FN_TPU4TO1, GPIO_FN_MFG4_OUT2, GPIO_FN_XWR3,
+	GPIO_FN_LCDD8, GPIO_FN_PORT200_KEYIN0, GPIO_FN_VIO_DR0, GPIO_FN_D16,
+	GPIO_FN_ED16,
+	GPIO_FN_LCDD9, GPIO_FN_PORT201_KEYIN1, GPIO_FN_VIO_DR1, GPIO_FN_D17,
+	GPIO_FN_ED17,
+	GPIO_FN_LCDD10, GPIO_FN_PORT202_KEYIN2, GPIO_FN_VIO_DR2, GPIO_FN_D18,
+	GPIO_FN_ED18,
+	GPIO_FN_LCDD11, GPIO_FN_PORT203_KEYIN3, GPIO_FN_VIO_DR3, GPIO_FN_D19,
+	GPIO_FN_ED19,
+	GPIO_FN_LCDD12, GPIO_FN_PORT204_KEYIN4, GPIO_FN_VIO_DR4, GPIO_FN_D20,
+	GPIO_FN_ED20,
+	GPIO_FN_LCDD13, GPIO_FN_PORT205_KEYIN5, GPIO_FN_VIO_DR5, GPIO_FN_D21,
+	GPIO_FN_ED21,
+	GPIO_FN_LCDD14, GPIO_FN_PORT206_KEYIN6, GPIO_FN_VIO_DR6, GPIO_FN_D22,
+	GPIO_FN_ED22,
+	GPIO_FN_LCDD15, GPIO_FN_PORT207_MSIOF0L_SS1, GPIO_FN_PORT207_KEYOUT0,
+	GPIO_FN_VIO_DR7,
+	GPIO_FN_D23, GPIO_FN_ED23,
+	GPIO_FN_LCDD16, GPIO_FN_PORT208_MSIOF0L_SS2, GPIO_FN_PORT208_KEYOUT1,
+	GPIO_FN_VIO_VDR,
+	GPIO_FN_D24, GPIO_FN_ED24,
+	GPIO_FN_LCDD17, GPIO_FN_PORT209_KEYOUT2, GPIO_FN_VIO_HDR, GPIO_FN_D25,
+	GPIO_FN_ED25,
+	GPIO_FN_LCDD18, GPIO_FN_DREQ2, GPIO_FN_PORT210_MSIOF0L_SS1, GPIO_FN_D26,
+	GPIO_FN_ED26,
+	GPIO_FN_LCDD19, GPIO_FN_PORT211_MSIOF0L_SS2, GPIO_FN_D27, GPIO_FN_ED27,
+	GPIO_FN_LCDD20, GPIO_FN_TS_SPSYNC1, GPIO_FN_MSIOF0L_MCK0, GPIO_FN_D28,
+	GPIO_FN_ED28,
+	GPIO_FN_LCDD21, GPIO_FN_TS_SDAT1, GPIO_FN_MSIOF0L_MCK1, GPIO_FN_D29,
+	GPIO_FN_ED29,
+	GPIO_FN_LCDD22, GPIO_FN_TS_SDEN1, GPIO_FN_MSIOF0L_RSCK, GPIO_FN_D30,
+	GPIO_FN_ED30,
+	GPIO_FN_LCDD23, GPIO_FN_TS_SCK1, GPIO_FN_MSIOF0L_RSYNC, GPIO_FN_D31,
+	GPIO_FN_ED31,
+	GPIO_FN_LCDDCK, GPIO_FN_LCDWR, GPIO_FN_PORT216_KEYOUT3,
+	GPIO_FN_VIO_CLKR,
+	GPIO_FN_LCDRD, GPIO_FN_DACK2, GPIO_FN_MSIOF0L_TSYNC,
+	GPIO_FN_LCDHSYN, GPIO_FN_LCDCS, GPIO_FN_LCDCS2, GPIO_FN_DACK3,
+	GPIO_FN_PORT218_VIO_CKOR, GPIO_FN_PORT218_KEYOUT4,
+	GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_DREQ3, GPIO_FN_MSIOF0L_TSCK,
+	GPIO_FN_LCDVSYN, GPIO_FN_LCDVSYN2, GPIO_FN_PORT220_KEYOUT5,
+	GPIO_FN_LCDLCLK, GPIO_FN_DREQ1, GPIO_FN_PWEN, GPIO_FN_MSIOF0L_RXD,
+	GPIO_FN_LCDDON, GPIO_FN_LCDDON2, GPIO_FN_DACK1, GPIO_FN_OVCN,
+	GPIO_FN_MSIOF0L_TXD,
+	GPIO_FN_SCIFA1_TXD, GPIO_FN_OVCN2,
+	GPIO_FN_EXTLP, GPIO_FN_SCIFA1_SCK, GPIO_FN_USBTERM,
+	GPIO_FN_PORT226_VIO_CKO2,
+	GPIO_FN_SCIFA1_RTS, GPIO_FN_IDIN,
+	GPIO_FN_SCIFA1_RXD,
+	GPIO_FN_SCIFA1_CTS, GPIO_FN_MFG1_IN1,
+	GPIO_FN_MSIOF1_TXD, GPIO_FN_SCIFA2_TXD2, GPIO_FN_PORT230_FSIAOMC,
+	GPIO_FN_MSIOF1_TSYNC, GPIO_FN_SCIFA2_CTS2, GPIO_FN_PORT231_FSIAOLR,
+	GPIO_FN_MSIOF1_TSCK, GPIO_FN_SCIFA2_SCK2, GPIO_FN_PORT232_FSIAOBT,
+	GPIO_FN_MSIOF1_RXD, GPIO_FN_SCIFA2_RXD2, GPIO_FN_GPS_VCOTRIG,
+	GPIO_FN_PORT233_FSIACK,
+	GPIO_FN_MSIOF1_RSCK, GPIO_FN_SCIFA2_RTS2, GPIO_FN_PORT234_FSIAOSLD,
+	GPIO_FN_MSIOF1_RSYNC, GPIO_FN_OPORT0, GPIO_FN_MFG1_IN2,
+	GPIO_FN_PORT235_FSIAILR,
+	GPIO_FN_MSIOF1_MCK0, GPIO_FN_I2C_SDA2, GPIO_FN_PORT236_FSIAIBT,
+	GPIO_FN_MSIOF1_MCK1, GPIO_FN_I2C_SCL2, GPIO_FN_PORT237_FSIAISLD,
+	GPIO_FN_MSIOF1_SS1, GPIO_FN_EDBGREQ3,
+
+	/* 55-5 (FN) */
+	GPIO_FN_MSIOF1_SS2,
+	GPIO_FN_SCIFA6_TXD,
+	GPIO_FN_PORT241_IRDA_OUT, GPIO_FN_PORT241_IROUT, GPIO_FN_MFG4_OUT1,
+	GPIO_FN_TPU4TO0,
+	GPIO_FN_PORT242_IRDA_IN, GPIO_FN_MFG4_IN2,
+	GPIO_FN_PORT243_IRDA_FIRSEL, GPIO_FN_PORT243_VIO_CKO2,
+	GPIO_FN_PORT244_SCIFA5_CTS, GPIO_FN_MFG2_IN1, GPIO_FN_PORT244_SCIFB_CTS,
+	GPIO_FN_PORT244_MSIOF2_RXD,
+	GPIO_FN_PORT245_SCIFA5_RTS, GPIO_FN_MFG2_IN2, GPIO_FN_PORT245_SCIFB_RTS,
+	GPIO_FN_PORT245_MSIOF2_TXD,
+	GPIO_FN_PORT246_SCIFA5_RXD, GPIO_FN_MFG1_OUT1,
+	GPIO_FN_PORT246_SCIFB_RXD, GPIO_FN_TPU1TO0,
+	GPIO_FN_PORT247_SCIFA5_TXD, GPIO_FN_MFG3_OUT2,
+	GPIO_FN_PORT247_SCIFB_TXD, GPIO_FN_TPU3TO1,
+	GPIO_FN_PORT248_SCIFA5_SCK, GPIO_FN_MFG2_OUT1,
+	GPIO_FN_PORT248_SCIFB_SCK, GPIO_FN_TPU2TO0,
+	GPIO_FN_PORT248_MSIOF2_TSCK,
+	GPIO_FN_PORT249_IROUT, GPIO_FN_MFG4_IN1, GPIO_FN_PORT249_MSIOF2_TSYNC,
+	GPIO_FN_SDHICLK0, GPIO_FN_TCK2_SWCLK_MC0,
+	GPIO_FN_SDHICD0,
+	GPIO_FN_SDHID0_0, GPIO_FN_TMS2_SWDIO_MC0,
+	GPIO_FN_SDHID0_1, GPIO_FN_TDO2_SWO0_MC0,
+	GPIO_FN_SDHID0_2, GPIO_FN_TDI2,
+	GPIO_FN_SDHID0_3, GPIO_FN_RTCK2_SWO1_MC0,
+	GPIO_FN_SDHICMD0, GPIO_FN_TRST2,
+	GPIO_FN_SDHIWP0, GPIO_FN_EDBGREQ2,
+	GPIO_FN_SDHICLK1, GPIO_FN_TCK3_SWCLK_MC1,
+	GPIO_FN_SDHID1_0, GPIO_FN_M11_SLCD_SO2, GPIO_FN_TS_SPSYNC2,
+	GPIO_FN_TMS3_SWDIO_MC1,
+	GPIO_FN_SDHID1_1, GPIO_FN_M9_SLCD_A02, GPIO_FN_TS_SDAT2,
+	GPIO_FN_TDO3_SWO0_MC1,
+	GPIO_FN_SDHID1_2, GPIO_FN_M10_SLCD_CK2, GPIO_FN_TS_SDEN2, GPIO_FN_TDI3,
+	GPIO_FN_SDHID1_3, GPIO_FN_M12_SLCD_CE2, GPIO_FN_TS_SCK2,
+	GPIO_FN_RTCK3_SWO1_MC1,
+	GPIO_FN_SDHICMD1, GPIO_FN_TRST3,
+	GPIO_FN_RESETOUTS,
+};
+
+#endif /* __ASM_SH7377_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/system.h linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/system.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,14 @@
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_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
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/timex.h linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/timex.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/timex.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef __ASM_MACH_TIMEX_H
+#define __ASM_MACH_TIMEX_H
+
+#define CLOCK_TICK_RATE		1193180 /* unused i8253 PIT value */
+
+#endif /* __ASM_MACH_TIMEX_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/uncompress.h linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/uncompress.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/uncompress.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,21 @@
+#ifndef __ASM_MACH_UNCOMPRESS_H
+#define __ASM_MACH_UNCOMPRESS_H
+
+/*
+ * This does not append a newline
+ */
+static void putc(int c)
+{
+}
+
+static inline void flush(void)
+{
+}
+
+static void arch_decomp_setup(void)
+{
+}
+
+#define arch_decomp_wdog()
+
+#endif /* __ASM_MACH_UNCOMPRESS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef __ASM_MACH_VMALLOC_H
+#define __ASM_MACH_VMALLOC_H
+
+#define VMALLOC_END       (PAGE_OFFSET + 0x24000000)
+
+#endif /* __ASM_MACH_VMALLOC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/intc-sh7367.c linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/intc-sh7367.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/intc-sh7367.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/intc-sh7367.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,270 @@
+/*
+ * sh7367 processor support - INTC hardware block
+ *
+ * Copyright (C) 2010  Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sh_intc.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+enum {
+	UNUSED_INTCA = 0,
+	ENABLED,
+	DISABLED,
+
+	/* interrupt sources INTCA */
+	IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
+	IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A,
+	DIRC,
+	CRYPT1_ERR, CRYPT2_STD,
+	IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1,
+	ARM11_IRQPMU, ARM11_COMMTX, ARM11_COMMRX,
+	ETM11_ACQCMP, ETM11_FULL,
+	MFI_MFIM, MFI_MFIS,
+	BBIF1, BBIF2,
+	USBDMAC_USHDMI,
+	USBHS_USHI0, USBHS_USHI1,
+	CMT1_CMT10, CMT1_CMT11, CMT1_CMT12, CMT1_CMT13, CMT2, CMT3,
+	KEYSC_KEY,
+	SCIFA0, SCIFA1, SCIFA2, SCIFA3,
+	MSIOF2, MSIOF1,
+	SCIFA4, SCIFA5, SCIFB,
+	FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
+	SDHI0,
+	SDHI1,
+	MSU_MSU, MSU_MSU2,
+	IREM,
+	SIU,
+	SPU,
+	IRDA,
+	TPU0, TPU1, TPU2, TPU3, TPU4,
+	LCRC,
+	PINT1, PINT2,
+	TTI20,
+	MISTY,
+	DDM,
+	SDHI2,
+	RWDT0, RWDT1,
+	DMAC_1_DEI0, DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3,
+	DMAC_2_DEI4, DMAC_2_DEI5, DMAC_2_DADERR,
+	DMAC2_1_DEI0, DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3,
+	DMAC2_2_DEI4, DMAC2_2_DEI5, DMAC2_2_DADERR,
+	DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3,
+	DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR,
+
+	/* interrupt groups INTCA */
+	DMAC_1, DMAC_2,	DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2,
+	ETM11, ARM11, USBHS, FLCTL, IIC1
+};
+
+static struct intc_vect intca_vectors[] = {
+	INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
+	INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
+	INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
+	INTC_VECT(IRQ6A, 0x02c0), INTC_VECT(IRQ7A, 0x02e0),
+	INTC_VECT(IRQ8A, 0x0300), INTC_VECT(IRQ9A, 0x0320),
+	INTC_VECT(IRQ10A, 0x0340), INTC_VECT(IRQ11A, 0x0360),
+	INTC_VECT(IRQ12A, 0x0380), INTC_VECT(IRQ13A, 0x03a0),
+	INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0),
+	INTC_VECT(DIRC, 0x0560),
+	INTC_VECT(CRYPT1_ERR, 0x05e0),
+	INTC_VECT(CRYPT2_STD, 0x0700),
+	INTC_VECT(IIC1_ALI1, 0x0780), INTC_VECT(IIC1_TACKI1, 0x07a0),
+	INTC_VECT(IIC1_WAITI1, 0x07c0), INTC_VECT(IIC1_DTEI1, 0x07e0),
+	INTC_VECT(ARM11_IRQPMU, 0x0800), INTC_VECT(ARM11_COMMTX, 0x0840),
+	INTC_VECT(ARM11_COMMRX, 0x0860),
+	INTC_VECT(ETM11_ACQCMP, 0x0880), INTC_VECT(ETM11_FULL, 0x08a0),
+	INTC_VECT(MFI_MFIM, 0x0900), INTC_VECT(MFI_MFIS, 0x0920),
+	INTC_VECT(BBIF1, 0x0940), INTC_VECT(BBIF2, 0x0960),
+	INTC_VECT(USBDMAC_USHDMI, 0x0a00),
+	INTC_VECT(USBHS_USHI0, 0x0a20), INTC_VECT(USBHS_USHI1, 0x0a40),
+	INTC_VECT(CMT1_CMT10, 0x0b00), INTC_VECT(CMT1_CMT11, 0x0b20),
+	INTC_VECT(CMT1_CMT12, 0x0b40), INTC_VECT(CMT1_CMT13, 0x0b60),
+	INTC_VECT(CMT2, 0x0b80), INTC_VECT(CMT3, 0x0ba0),
+	INTC_VECT(KEYSC_KEY, 0x0be0),
+	INTC_VECT(SCIFA0, 0x0c00), INTC_VECT(SCIFA1, 0x0c20),
+	INTC_VECT(SCIFA2, 0x0c40), INTC_VECT(SCIFA3, 0x0c60),
+	INTC_VECT(MSIOF2, 0x0c80), INTC_VECT(MSIOF1, 0x0d00),
+	INTC_VECT(SCIFA4, 0x0d20), INTC_VECT(SCIFA5, 0x0d40),
+	INTC_VECT(SCIFB, 0x0d60),
+	INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
+	INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
+	INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20),
+	INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60),
+	INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0),
+	INTC_VECT(SDHI1, 0x0ec0), INTC_VECT(SDHI1, 0x0ee0),
+	INTC_VECT(MSU_MSU, 0x0f20), INTC_VECT(MSU_MSU2, 0x0f40),
+	INTC_VECT(IREM, 0x0f60),
+	INTC_VECT(SIU, 0x0fa0),
+	INTC_VECT(SPU, 0x0fc0),
+	INTC_VECT(IRDA, 0x0480),
+	INTC_VECT(TPU0, 0x04a0), INTC_VECT(TPU1, 0x04c0),
+	INTC_VECT(TPU2, 0x04e0), INTC_VECT(TPU3, 0x0500),
+	INTC_VECT(TPU4, 0x0520),
+	INTC_VECT(LCRC, 0x0540),
+	INTC_VECT(PINT1, 0x1000), INTC_VECT(PINT2, 0x1020),
+	INTC_VECT(TTI20, 0x1100),
+	INTC_VECT(MISTY, 0x1120),
+	INTC_VECT(DDM, 0x1140),
+	INTC_VECT(SDHI2, 0x1200), INTC_VECT(SDHI2, 0x1220),
+	INTC_VECT(SDHI2, 0x1240), INTC_VECT(SDHI2, 0x1260),
+	INTC_VECT(RWDT0, 0x1280), INTC_VECT(RWDT1, 0x12a0),
+	INTC_VECT(DMAC_1_DEI0, 0x2000), INTC_VECT(DMAC_1_DEI1, 0x2020),
+	INTC_VECT(DMAC_1_DEI2, 0x2040), INTC_VECT(DMAC_1_DEI3, 0x2060),
+	INTC_VECT(DMAC_2_DEI4, 0x2080), INTC_VECT(DMAC_2_DEI5, 0x20a0),
+	INTC_VECT(DMAC_2_DADERR, 0x20c0),
+	INTC_VECT(DMAC2_1_DEI0, 0x2100), INTC_VECT(DMAC2_1_DEI1, 0x2120),
+	INTC_VECT(DMAC2_1_DEI2, 0x2140), INTC_VECT(DMAC2_1_DEI3, 0x2160),
+	INTC_VECT(DMAC2_2_DEI4, 0x2180), INTC_VECT(DMAC2_2_DEI5, 0x21a0),
+	INTC_VECT(DMAC2_2_DADERR, 0x21c0),
+	INTC_VECT(DMAC3_1_DEI0, 0x2200), INTC_VECT(DMAC3_1_DEI1, 0x2220),
+	INTC_VECT(DMAC3_1_DEI2, 0x2240), INTC_VECT(DMAC3_1_DEI3, 0x2260),
+	INTC_VECT(DMAC3_2_DEI4, 0x2280), INTC_VECT(DMAC3_2_DEI5, 0x22a0),
+	INTC_VECT(DMAC3_2_DADERR, 0x22c0),
+};
+
+static struct intc_group intca_groups[] __initdata = {
+	INTC_GROUP(DMAC_1, DMAC_1_DEI0,
+		   DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3),
+	INTC_GROUP(DMAC_2, DMAC_2_DEI4,
+		   DMAC_2_DEI5, DMAC_2_DADERR),
+	INTC_GROUP(DMAC2_1, DMAC2_1_DEI0,
+		   DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3),
+	INTC_GROUP(DMAC2_2, DMAC2_2_DEI4,
+		   DMAC2_2_DEI5, DMAC2_2_DADERR),
+	INTC_GROUP(DMAC3_1, DMAC3_1_DEI0,
+		   DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3),
+	INTC_GROUP(DMAC3_2, DMAC3_2_DEI4,
+		   DMAC3_2_DEI5, DMAC3_2_DADERR),
+	INTC_GROUP(ETM11, ETM11_ACQCMP, ETM11_FULL),
+	INTC_GROUP(ARM11, ARM11_IRQPMU, ARM11_COMMTX, ARM11_COMMTX),
+	INTC_GROUP(USBHS, USBHS_USHI0, USBHS_USHI1),
+	INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
+		   FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
+	INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
+};
+
+static struct intc_mask_reg intca_mask_registers[] = {
+	{ 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
+	  { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+	{ 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
+	  { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+	{ 0xe6940080, 0xe69400c0, 8, /* IMR0A / IMCR0A */
+	  { DMAC2_1_DEI3, DMAC2_1_DEI2, DMAC2_1_DEI1, DMAC2_1_DEI0,
+	    ARM11_IRQPMU, 0, ARM11_COMMTX, ARM11_COMMRX } },
+	{ 0xe6940084, 0xe69400c4, 8, /* IMR1A / IMCR1A */
+	  { CRYPT1_ERR, CRYPT2_STD, DIRC, 0,
+	    DMAC_1_DEI3, DMAC_1_DEI2, DMAC_1_DEI1, DMAC_1_DEI0 } },
+	{ 0xe6940088, 0xe69400c8, 8, /* IMR2A / IMCR2A */
+	  { PINT1, PINT2, 0, 0,
+	    BBIF1, BBIF2, MFI_MFIS, MFI_MFIM } },
+	{ 0xe694008c, 0xe69400cc, 8, /* IMR3A / IMCR3A */
+	  { DMAC3_1_DEI3, DMAC3_1_DEI2, DMAC3_1_DEI1, DMAC3_1_DEI0,
+	    DMAC3_2_DADERR, DMAC3_2_DEI5, DMAC3_2_DEI4, IRDA } },
+	{ 0xe6940090, 0xe69400d0, 8, /* IMR4A / IMCR4A */
+	  { DDM, 0, 0, 0,
+	    0, 0, ETM11_FULL, ETM11_ACQCMP } },
+	{ 0xe6940094, 0xe69400d4, 8, /* IMR5A / IMCR5A */
+	  { KEYSC_KEY, DMAC_2_DADERR, DMAC_2_DEI5, DMAC_2_DEI4,
+	    SCIFA3, SCIFA2, SCIFA1, SCIFA0 } },
+	{ 0xe6940098, 0xe69400d8, 8, /* IMR6A / IMCR6A */
+	  { SCIFB, SCIFA5, SCIFA4, MSIOF1,
+	    0, 0, MSIOF2, 0 } },
+	{ 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
+	  { DISABLED, DISABLED, ENABLED, ENABLED,
+	    FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
+	{ 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
+	  { DISABLED, DISABLED, ENABLED, ENABLED,
+	    TTI20, USBDMAC_USHDMI, SPU, SIU } },
+	{ 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
+	  { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
+	    CMT2, USBHS_USHI1, USBHS_USHI0, 0 } },
+	{ 0xe69400a8, 0xe69400e8, 8, /* IMR10A / IMCR10A */
+	  { 0, DMAC2_2_DADERR, DMAC2_2_DEI5, DMAC2_2_DEI4,
+	    0, 0, 0, 0 } },
+	{ 0xe69400ac, 0xe69400ec, 8, /* IMR11A / IMCR11A */
+	  { IIC1_DTEI1, IIC1_WAITI1, IIC1_TACKI1, IIC1_ALI1,
+	    LCRC, MSU_MSU2, IREM, MSU_MSU } },
+	{ 0xe69400b0, 0xe69400f0, 8, /* IMR12A / IMCR12A */
+	  { 0, 0, TPU0, TPU1,
+	    TPU2, TPU3, TPU4, 0 } },
+	{ 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
+	  { DISABLED, DISABLED, ENABLED, ENABLED,
+	    MISTY, CMT3, RWDT1, RWDT0 } },
+};
+
+static struct intc_prio_reg intca_prio_registers[] = {
+	{ 0xe6900010, 0, 32, 4, /* INTPRI00A */
+	  { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+	{ 0xe6900014, 0, 32, 4, /* INTPRI10A */
+	  { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+
+	{ 0xe6940000, 0, 16, 4, /* IPRAA */ { DMAC3_1, DMAC3_2, CMT2, LCRC } },
+	{ 0xe6940004, 0, 16, 4, /* IPRBA */ { IRDA, ETM11, BBIF1, BBIF2 } },
+	{ 0xe6940008, 0, 16, 4, /* IPRCA */ { CRYPT1_ERR, CRYPT2_STD,
+					      CMT1_CMT11, ARM11 } },
+	{ 0xe694000c, 0, 16, 4, /* IPRDA */ { PINT1, PINT2,
+					      CMT1_CMT12, TPU4 } },
+	{ 0xe6940010, 0, 16, 4, /* IPREA */ { DMAC_1, MFI_MFIS,
+					      MFI_MFIM, USBHS } },
+	{ 0xe6940014, 0, 16, 4, /* IPRFA */ { KEYSC_KEY, DMAC_2,
+					      0, CMT1_CMT10 } },
+	{ 0xe6940018, 0, 16, 4, /* IPRGA */ { SCIFA0, SCIFA1,
+					      SCIFA2, SCIFA3 } },
+	{ 0xe694001c, 0, 16, 4, /* IPRGH */ { MSIOF2, USBDMAC_USHDMI,
+					      FLCTL, SDHI0 } },
+	{ 0xe6940020, 0, 16, 4, /* IPRIA */ { MSIOF1, SCIFA4, MSU_MSU, IIC1 } },
+	{ 0xe6940024, 0, 16, 4, /* IPRJA */ { DMAC2_1, DMAC2_2, SIU, TTI20 } },
+	{ 0xe6940028, 0, 16, 4, /* IPRKA */ { 0, CMT1_CMT13, IREM, SDHI1 } },
+	{ 0xe694002c, 0, 16, 4, /* IPRLA */ { TPU0, TPU1, TPU2, TPU3 } },
+	{ 0xe6940030, 0, 16, 4, /* IPRMA */ { MISTY, CMT3, RWDT1, RWDT0 } },
+	{ 0xe6940034, 0, 16, 4, /* IPRNA */ { SCIFB, SCIFA5, SPU, DDM } },
+	{ 0xe6940038, 0, 16, 4, /* IPROA */ { 0, 0, DIRC, SDHI2 } },
+};
+
+static struct intc_sense_reg intca_sense_registers[] __initdata = {
+	{ 0xe6900000, 16, 2, /* ICR1A */
+	  { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+	{ 0xe6900004, 16, 2, /* ICR2A */
+	  { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+};
+
+static struct intc_mask_reg intca_ack_registers[] __initdata = {
+	{ 0xe6900020, 0, 8, /* INTREQ00A */
+	  { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+	{ 0xe6900024, 0, 8, /* INTREQ10A */
+	  { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+};
+
+static struct intc_desc intca_desc __initdata = {
+	.name = "sh7367-intca",
+	.force_enable = ENABLED,
+	.force_disable = DISABLED,
+	.hw = INTC_HW_DESC(intca_vectors, intca_groups,
+			   intca_mask_registers, intca_prio_registers,
+			   intca_sense_registers, intca_ack_registers),
+};
+
+void __init sh7367_init_irq(void)
+{
+	/* INTCA */
+	register_intc_controller(&intca_desc);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/intc-sh7372.c linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/intc-sh7372.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/intc-sh7372.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/intc-sh7372.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,369 @@
+/*
+ * sh7372 processor support - INTC hardware block
+ *
+ * Copyright (C) 2010  Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sh_intc.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+enum {
+	UNUSED_INTCA = 0,
+	ENABLED,
+	DISABLED,
+
+	/* interrupt sources INTCA */
+	IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
+	IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A,
+	IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A,
+	IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A,
+	DIRC,
+	CRYPT_STD,
+	IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1,
+	AP_ARM_IRQPMU, AP_ARM_COMMTX, AP_ARM_COMMRX,
+	MFI_MFIM, MFI_MFIS,
+	BBIF1, BBIF2,
+	USBHSDMAC0_USHDMI,
+	_3DG_SGX540,
+	CMT1_CMT10, CMT1_CMT11, CMT1_CMT12, CMT1_CMT13, CMT2, CMT3,
+	KEYSC_KEY,
+	SCIFA0, SCIFA1, SCIFA2, SCIFA3,
+	MSIOF2, MSIOF1,
+	SCIFA4, SCIFA5, SCIFB,
+	FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
+	SDHI0,
+	SDHI1,
+	IRREM,
+	IRDA,
+	TPU0,
+	TTI20,
+	DDM,
+	SDHI2,
+	RWDT0,
+	DMAC1_1_DEI0, DMAC1_1_DEI1, DMAC1_1_DEI2, DMAC1_1_DEI3,
+	DMAC1_2_DEI4, DMAC1_2_DEI5, DMAC1_2_DADERR,
+	DMAC2_1_DEI0, DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3,
+	DMAC2_2_DEI4, DMAC2_2_DEI5, DMAC2_2_DADERR,
+	DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3,
+	DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR,
+	SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM,
+	HDMI,
+	SPU2_SPU0, SPU2_SPU1,
+	FSI, FMSI,
+	MIPI_HSI,
+	IPMMU_IPMMUD,
+	CEC_1, CEC_2,
+	AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ, AP_ARM_DMAIRQ, AP_ARM_DMASIRQ,
+	MFIS2,
+	CPORTR2S,
+	CMT14, CMT15,
+	MMC_MMC_ERR, MMC_MMC_NOR,
+	IIC4_ALI4, IIC4_TACKI4, IIC4_WAITI4, IIC4_DTEI4,
+	IIC3_ALI3, IIC3_TACKI3, IIC3_WAITI3, IIC3_DTEI3,
+	USB0_USB0I1, USB0_USB0I0,
+	USB1_USB1I1, USB1_USB1I0,
+	USBHSDMAC1_USHDMI,
+
+	/* interrupt groups INTCA */
+	DMAC1_1, DMAC1_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, SHWYSTAT,
+	AP_ARM1, AP_ARM2, SPU2, FLCTL, IIC1
+};
+
+static struct intc_vect intca_vectors[] __initdata = {
+	INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
+	INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
+	INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
+	INTC_VECT(IRQ6A, 0x02c0), INTC_VECT(IRQ7A, 0x02e0),
+	INTC_VECT(IRQ8A, 0x0300), INTC_VECT(IRQ9A, 0x0320),
+	INTC_VECT(IRQ10A, 0x0340), INTC_VECT(IRQ11A, 0x0360),
+	INTC_VECT(IRQ12A, 0x0380), INTC_VECT(IRQ13A, 0x03a0),
+	INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0),
+	INTC_VECT(IRQ16A, 0x3200), INTC_VECT(IRQ17A, 0x3220),
+	INTC_VECT(IRQ18A, 0x3240), INTC_VECT(IRQ19A, 0x3260),
+	INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ31A, 0x32a0),
+	INTC_VECT(IRQ22A, 0x32c0), INTC_VECT(IRQ23A, 0x32e0),
+	INTC_VECT(IRQ24A, 0x3300), INTC_VECT(IRQ25A, 0x3320),
+	INTC_VECT(IRQ26A, 0x3340), INTC_VECT(IRQ27A, 0x3360),
+	INTC_VECT(IRQ28A, 0x3380), INTC_VECT(IRQ29A, 0x33a0),
+	INTC_VECT(IRQ30A, 0x33c0), INTC_VECT(IRQ31A, 0x33e0),
+	INTC_VECT(DIRC, 0x0560),
+	INTC_VECT(CRYPT_STD, 0x0700),
+	INTC_VECT(IIC1_ALI1, 0x0780), INTC_VECT(IIC1_TACKI1, 0x07a0),
+	INTC_VECT(IIC1_WAITI1, 0x07c0), INTC_VECT(IIC1_DTEI1, 0x07e0),
+	INTC_VECT(AP_ARM_IRQPMU, 0x0800), INTC_VECT(AP_ARM_COMMTX, 0x0840),
+	INTC_VECT(AP_ARM_COMMRX, 0x0860),
+	INTC_VECT(MFI_MFIM, 0x0900), INTC_VECT(MFI_MFIS, 0x0920),
+	INTC_VECT(BBIF1, 0x0940), INTC_VECT(BBIF2, 0x0960),
+	INTC_VECT(USBHSDMAC0_USHDMI, 0x0a00),
+	INTC_VECT(_3DG_SGX540, 0x0a60),
+	INTC_VECT(CMT1_CMT10, 0x0b00), INTC_VECT(CMT1_CMT11, 0x0b20),
+	INTC_VECT(CMT1_CMT12, 0x0b40), INTC_VECT(CMT1_CMT13, 0x0b60),
+	INTC_VECT(CMT2, 0x0b80), INTC_VECT(CMT3, 0x0ba0),
+	INTC_VECT(KEYSC_KEY, 0x0be0),
+	INTC_VECT(SCIFA0, 0x0c00), INTC_VECT(SCIFA1, 0x0c20),
+	INTC_VECT(SCIFA2, 0x0c40), INTC_VECT(SCIFA3, 0x0c60),
+	INTC_VECT(MSIOF2, 0x0c80), INTC_VECT(MSIOF1, 0x0d00),
+	INTC_VECT(SCIFA4, 0x0d20), INTC_VECT(SCIFA5, 0x0d40),
+	INTC_VECT(SCIFB, 0x0d60),
+	INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
+	INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
+	INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20),
+	INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60),
+	INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0),
+	INTC_VECT(SDHI1, 0x0ec0),
+	INTC_VECT(IRREM, 0x0f60),
+	INTC_VECT(IRDA, 0x0480),
+	INTC_VECT(TPU0, 0x04a0),
+	INTC_VECT(TTI20, 0x1100),
+	INTC_VECT(DDM, 0x1140),
+	INTC_VECT(SDHI2, 0x1200), INTC_VECT(SDHI2, 0x1220),
+	INTC_VECT(SDHI2, 0x1240), INTC_VECT(SDHI2, 0x1260),
+	INTC_VECT(RWDT0, 0x1280),
+	INTC_VECT(DMAC1_1_DEI0, 0x2000), INTC_VECT(DMAC1_1_DEI1, 0x2020),
+	INTC_VECT(DMAC1_1_DEI2, 0x2040), INTC_VECT(DMAC1_1_DEI3, 0x2060),
+	INTC_VECT(DMAC1_2_DEI4, 0x2080), INTC_VECT(DMAC1_2_DEI5, 0x20a0),
+	INTC_VECT(DMAC1_2_DADERR, 0x20c0),
+	INTC_VECT(DMAC2_1_DEI0, 0x2100), INTC_VECT(DMAC2_1_DEI1, 0x2120),
+	INTC_VECT(DMAC2_1_DEI2, 0x2140), INTC_VECT(DMAC2_1_DEI3, 0x2160),
+	INTC_VECT(DMAC2_2_DEI4, 0x2180), INTC_VECT(DMAC2_2_DEI5, 0x21a0),
+	INTC_VECT(DMAC2_2_DADERR, 0x21c0),
+	INTC_VECT(DMAC3_1_DEI0, 0x2200), INTC_VECT(DMAC3_1_DEI1, 0x2220),
+	INTC_VECT(DMAC3_1_DEI2, 0x2240), INTC_VECT(DMAC3_1_DEI3, 0x2260),
+	INTC_VECT(DMAC3_2_DEI4, 0x2280), INTC_VECT(DMAC3_2_DEI5, 0x22a0),
+	INTC_VECT(DMAC3_2_DADERR, 0x22c0),
+	INTC_VECT(SHWYSTAT_RT, 0x1300), INTC_VECT(SHWYSTAT_HS, 0x1320),
+	INTC_VECT(SHWYSTAT_COM, 0x1340),
+	INTC_VECT(HDMI, 0x17e0),
+	INTC_VECT(SPU2_SPU0, 0x1800), INTC_VECT(SPU2_SPU1, 0x1820),
+	INTC_VECT(FSI, 0x1840),
+	INTC_VECT(FMSI, 0x1860),
+	INTC_VECT(MIPI_HSI, 0x18e0),
+	INTC_VECT(IPMMU_IPMMUD, 0x1920),
+	INTC_VECT(CEC_1, 0x1940), INTC_VECT(CEC_2, 0x1960),
+	INTC_VECT(AP_ARM_CTIIRQ, 0x1980),
+	INTC_VECT(AP_ARM_DMAEXTERRIRQ, 0x19a0),
+	INTC_VECT(AP_ARM_DMAIRQ, 0x19c0),
+	INTC_VECT(AP_ARM_DMASIRQ, 0x19e0),
+	INTC_VECT(MFIS2, 0x1a00),
+	INTC_VECT(CPORTR2S, 0x1a20),
+	INTC_VECT(CMT14, 0x1a40), INTC_VECT(CMT15, 0x1a60),
+	INTC_VECT(MMC_MMC_ERR, 0x1ac0), INTC_VECT(MMC_MMC_NOR, 0x1ae0),
+	INTC_VECT(IIC4_ALI4, 0x1b00), INTC_VECT(IIC4_TACKI4, 0x1b20),
+	INTC_VECT(IIC4_WAITI4, 0x1b40), INTC_VECT(IIC4_DTEI4, 0x1b60),
+	INTC_VECT(IIC3_ALI3, 0x1b80), INTC_VECT(IIC3_TACKI3, 0x1ba0),
+	INTC_VECT(IIC3_WAITI3, 0x1bc0), INTC_VECT(IIC3_DTEI3, 0x1be0),
+	INTC_VECT(USB0_USB0I1, 0x1c80), INTC_VECT(USB0_USB0I0, 0x1ca0),
+	INTC_VECT(USB1_USB1I1, 0x1cc0), INTC_VECT(USB1_USB1I0, 0x1ce0),
+	INTC_VECT(USBHSDMAC1_USHDMI, 0x1d00),
+};
+
+static struct intc_group intca_groups[] __initdata = {
+	INTC_GROUP(DMAC1_1, DMAC1_1_DEI0,
+		   DMAC1_1_DEI1, DMAC1_1_DEI2, DMAC1_1_DEI3),
+	INTC_GROUP(DMAC1_2, DMAC1_2_DEI4,
+		   DMAC1_2_DEI5, DMAC1_2_DADERR),
+	INTC_GROUP(DMAC2_1, DMAC2_1_DEI0,
+		   DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3),
+	INTC_GROUP(DMAC2_2, DMAC2_2_DEI4,
+		   DMAC2_2_DEI5, DMAC2_2_DADERR),
+	INTC_GROUP(DMAC3_1, DMAC3_1_DEI0,
+		   DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3),
+	INTC_GROUP(DMAC3_2, DMAC3_2_DEI4,
+		   DMAC3_2_DEI5, DMAC3_2_DADERR),
+	INTC_GROUP(AP_ARM1, AP_ARM_IRQPMU, AP_ARM_COMMTX, AP_ARM_COMMRX),
+	INTC_GROUP(AP_ARM2, AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ,
+		   AP_ARM_DMAIRQ, AP_ARM_DMASIRQ),
+	INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1),
+	INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
+		   FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
+	INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
+	INTC_GROUP(SHWYSTAT, SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM),
+};
+
+static struct intc_mask_reg intca_mask_registers[] __initdata = {
+	{ 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
+	  { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+	{ 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
+	  { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+	{ 0xe6900048, 0xe6900068, 8, /* INTMSK20A / INTMSKCLR20A */
+	  { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+	{ 0xe690004c, 0xe690006c, 8, /* INTMSK30A / INTMSKCLR30A */
+	  { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+
+	{ 0xe6940080, 0xe69400c0, 8, /* IMR0A / IMCR0A */
+	  { DMAC2_1_DEI3, DMAC2_1_DEI2, DMAC2_1_DEI1, DMAC2_1_DEI0,
+	    AP_ARM_IRQPMU, 0, AP_ARM_COMMTX, AP_ARM_COMMRX } },
+	{ 0xe6940084, 0xe69400c4, 8, /* IMR1A / IMCR1A */
+	  { 0, CRYPT_STD, DIRC, 0,
+	    DMAC1_1_DEI3, DMAC1_1_DEI2, DMAC1_1_DEI1, DMAC1_1_DEI0 } },
+	{ 0xe6940088, 0xe69400c8, 8, /* IMR2A / IMCR2A */
+	  { 0, 0, 0, 0,
+	    BBIF1, BBIF2, MFI_MFIS, MFI_MFIM } },
+	{ 0xe694008c, 0xe69400cc, 8, /* IMR3A / IMCR3A */
+	  { DMAC3_1_DEI3, DMAC3_1_DEI2, DMAC3_1_DEI1, DMAC3_1_DEI0,
+	    DMAC3_2_DADERR, DMAC3_2_DEI5, DMAC3_2_DEI4, IRDA } },
+	{ 0xe6940090, 0xe69400d0, 8, /* IMR4A / IMCR4A */
+	  { DDM, 0, 0, 0,
+	    0, 0, 0, 0 } },
+	{ 0xe6940094, 0xe69400d4, 8, /* IMR5A / IMCR5A */
+	  { KEYSC_KEY, DMAC1_2_DADERR, DMAC1_2_DEI5, DMAC1_2_DEI4,
+	    SCIFA3, SCIFA2, SCIFA1, SCIFA0 } },
+	{ 0xe6940098, 0xe69400d8, 8, /* IMR6A / IMCR6A */
+	  { SCIFB, SCIFA5, SCIFA4, MSIOF1,
+	    0, 0, MSIOF2, 0 } },
+	{ 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
+	  { DISABLED, DISABLED, ENABLED, ENABLED,
+	    FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
+	{ 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
+	  { 0, DISABLED, ENABLED, ENABLED,
+	    TTI20, USBHSDMAC0_USHDMI, 0, 0 } },
+	{ 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
+	  { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
+	    CMT2, 0, 0, _3DG_SGX540 } },
+	{ 0xe69400a8, 0xe69400e8, 8, /* IMR10A / IMCR10A */
+	  { 0, DMAC2_2_DADERR, DMAC2_2_DEI5, DMAC2_2_DEI4,
+	    0, 0, 0, 0 } },
+	{ 0xe69400ac, 0xe69400ec, 8, /* IMR11A / IMCR11A */
+	  { IIC1_DTEI1, IIC1_WAITI1, IIC1_TACKI1, IIC1_ALI1,
+	    0, 0, IRREM, 0 } },
+	{ 0xe69400b0, 0xe69400f0, 8, /* IMR12A / IMCR12A */
+	  { 0, 0, TPU0, 0,
+	    0, 0, 0, 0 } },
+	{ 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
+	  { DISABLED, DISABLED, ENABLED, ENABLED,
+	    0, CMT3, 0, RWDT0 } },
+	{ 0xe6950080, 0xe69500c0, 8, /* IMR0A3 / IMCR0A3 */
+	  { SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, 0,
+	    0, 0, 0, 0 } },
+	{ 0xe6950090, 0xe69500d0, 8, /* IMR4A3 / IMCR4A3 */
+	  { 0, 0, 0, 0,
+	    0, 0, 0, HDMI } },
+	{ 0xe6950094, 0xe69500d4, 8, /* IMR5A3 / IMCR5A3 */
+	  { SPU2_SPU0, SPU2_SPU1, FSI, FMSI,
+	    0, 0, 0, MIPI_HSI } },
+	{ 0xe6950098, 0xe69500d8, 8, /* IMR6A3 / IMCR6A3 */
+	  { 0, IPMMU_IPMMUD, CEC_1, CEC_2,
+	    AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ,
+	    AP_ARM_DMAIRQ, AP_ARM_DMASIRQ } },
+	{ 0xe695009c, 0xe69500dc, 8, /* IMR7A3 / IMCR7A3 */
+	  { MFIS2, CPORTR2S, CMT14, CMT15,
+	    0, 0, MMC_MMC_ERR, MMC_MMC_NOR } },
+	{ 0xe69500a0, 0xe69500e0, 8, /* IMR8A3 / IMCR8A3 */
+	  { IIC4_ALI4, IIC4_TACKI4, IIC4_WAITI4, IIC4_DTEI4,
+	    IIC3_ALI3, IIC3_TACKI3, IIC3_WAITI3, IIC3_DTEI3 } },
+	{ 0xe69500a4, 0xe69500e4, 8, /* IMR9A3 / IMCR9A3 */
+	  { 0, 0, 0, 0,
+	    USB0_USB0I1, USB0_USB0I0, USB1_USB1I1, USB1_USB1I0 } },
+	{ 0xe69500a8, 0xe69500e8, 8, /* IMR10A3 / IMCR10A3 */
+	  { USBHSDMAC1_USHDMI, 0, 0, 0,
+	    0, 0, 0, 0 } },
+};
+
+static struct intc_prio_reg intca_prio_registers[] __initdata = {
+	{ 0xe6900010, 0, 32, 4, /* INTPRI00A */
+	  { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+	{ 0xe6900014, 0, 32, 4, /* INTPRI10A */
+	  { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+	{ 0xe6900018, 0, 32, 4, /* INTPRI20A */
+	  { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+	{ 0xe690001c, 0, 32, 4, /* INTPRI30A */
+	  { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+
+	{ 0xe6940000, 0, 16, 4, /* IPRAA */ { DMAC3_1, DMAC3_2, CMT2, 0 } },
+	{ 0xe6940004, 0, 16, 4, /* IPRBA */ { IRDA, 0, BBIF1, BBIF2 } },
+	{ 0xe6940008, 0, 16, 4, /* IPRCA */ { 0, CRYPT_STD,
+					      CMT1_CMT11, AP_ARM1 } },
+	{ 0xe694000c, 0, 16, 4, /* IPRDA */ { 0, 0,
+					      CMT1_CMT12, 0 } },
+	{ 0xe6940010, 0, 16, 4, /* IPREA */ { DMAC1_1, MFI_MFIS,
+					      MFI_MFIM, 0 } },
+	{ 0xe6940014, 0, 16, 4, /* IPRFA */ { KEYSC_KEY, DMAC1_2,
+					      _3DG_SGX540, CMT1_CMT10 } },
+	{ 0xe6940018, 0, 16, 4, /* IPRGA */ { SCIFA0, SCIFA1,
+					      SCIFA2, SCIFA3 } },
+	{ 0xe694001c, 0, 16, 4, /* IPRGH */ { MSIOF2, USBHSDMAC0_USHDMI,
+					      FLCTL, SDHI0 } },
+	{ 0xe6940020, 0, 16, 4, /* IPRIA */ { MSIOF1, SCIFA4,
+					      0/* MSU */, IIC1 } },
+	{ 0xe6940024, 0, 16, 4, /* IPRJA */ { DMAC2_1, DMAC2_2,
+					      0/* MSUG */, TTI20 } },
+	{ 0xe6940028, 0, 16, 4, /* IPRKA */ { 0, CMT1_CMT13, IRREM, SDHI1 } },
+	{ 0xe694002c, 0, 16, 4, /* IPRLA */ { TPU0, 0, 0, 0 } },
+	{ 0xe6940030, 0, 16, 4, /* IPRMA */ { 0, CMT3, 0, RWDT0 } },
+	{ 0xe6940034, 0, 16, 4, /* IPRNA */ { SCIFB, SCIFA5, 0, DDM } },
+	{ 0xe6940038, 0, 16, 4, /* IPROA */ { 0, 0, DIRC, SDHI2 } },
+	{ 0xe6950000, 0, 16, 4, /* IPRAA3 */ { SHWYSTAT, 0, 0, 0 } },
+	{ 0xe6950024, 0, 16, 4, /* IPRJA3 */ { 0, 0, 0, HDMI } },
+	{ 0xe6950028, 0, 16, 4, /* IPRKA3 */ { SPU2, 0, FSI, FMSI } },
+	{ 0xe695002c, 0, 16, 4, /* IPRLA3 */ { 0, 0, 0, MIPI_HSI } },
+	{ 0xe6950030, 0, 16, 4, /* IPRMA3 */ { IPMMU_IPMMUD, 0,
+					       CEC_1, CEC_2 } },
+	{ 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } },
+	{ 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S,
+					       CMT14, CMT15 } },
+	{ 0xe694003c, 0, 16, 4, /* IPRPA3 */ { 0, 0,
+					       MMC_MMC_ERR, MMC_MMC_NOR } },
+	{ 0xe6940040, 0, 16, 4, /* IPRQA3 */ { IIC4_ALI4, IIC4_TACKI4,
+					       IIC4_WAITI4, IIC4_DTEI4 } },
+	{ 0xe6940044, 0, 16, 4, /* IPRRA3 */ { IIC3_ALI3, IIC3_TACKI3,
+					       IIC3_WAITI3, IIC3_DTEI3 } },
+	{ 0xe6940048, 0, 16, 4, /* IPRSA3 */ { 0/*ERI*/, 0/*RXI*/,
+					       0/*TXI*/, 0/*TEI*/} },
+	{ 0xe694004c, 0, 16, 4, /* IPRTA3 */ { USB0_USB0I1, USB0_USB0I0,
+					       USB1_USB1I1, USB1_USB1I0 } },
+	{ 0xe6940050, 0, 16, 4, /* IPRUA3 */ { USBHSDMAC1_USHDMI, 0, 0, 0 } },
+};
+
+static struct intc_sense_reg intca_sense_registers[] __initdata = {
+	{ 0xe6900000, 32, 4, /* ICR1A */
+	  { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+	{ 0xe6900004, 32, 4, /* ICR2A */
+	  { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+	{ 0xe6900008, 32, 4, /* ICR3A */
+	  { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+	{ 0xe690000c, 32, 4, /* ICR4A */
+	  { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+};
+
+static struct intc_mask_reg intca_ack_registers[] __initdata = {
+	{ 0xe6900020, 0, 8, /* INTREQ00A */
+	  { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+	{ 0xe6900024, 0, 8, /* INTREQ10A */
+	  { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+	{ 0xe6900028, 0, 8, /* INTREQ20A */
+	  { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+	{ 0xe690002c, 0, 8, /* INTREQ30A */
+	  { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+};
+
+static struct intc_desc intca_desc __initdata = {
+	.name = "sh7372-intca",
+	.force_enable = ENABLED,
+	.force_disable = DISABLED,
+	.hw = INTC_HW_DESC(intca_vectors, intca_groups,
+			   intca_mask_registers, intca_prio_registers,
+			   intca_sense_registers, intca_ack_registers),
+};
+
+void __init sh7372_init_irq(void)
+{
+	register_intc_controller(&intca_desc);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/intc-sh7377.c linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/intc-sh7377.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/intc-sh7377.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/intc-sh7377.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,352 @@
+/*
+ * sh7377 processor support - INTC hardware block
+ *
+ * Copyright (C) 2010  Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sh_intc.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+enum {
+	UNUSED_INTCA = 0,
+	ENABLED,
+	DISABLED,
+
+	/* interrupt sources INTCA */
+	IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
+	IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A,
+	IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A,
+	IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A,
+	DIRC,
+	_2DG,
+	CRYPT_STD,
+	IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1,
+	AP_ARM_IRQPMU, AP_ARM_COMMTX, AP_ARM_COMMRX,
+	MFI_MFIM, MFI_MFIS,
+	BBIF1, BBIF2,
+	USBDMAC_USHDMI,
+	USBHS_USHI0, USBHS_USHI1,
+	_3DG_SGX540,
+	CMT1_CMT10, CMT1_CMT11, CMT1_CMT12, CMT1_CMT13, CMT2, CMT3,
+	KEYSC_KEY,
+	SCIFA0, SCIFA1, SCIFA2, SCIFA3,
+	MSIOF2, MSIOF1,
+	SCIFA4, SCIFA5, SCIFB,
+	FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
+	SDHI0,
+	SDHI1,
+	MSU_MSU, MSU_MSU2,
+	IRREM,
+	MSUG,
+	IRDA,
+	TPU0, TPU1, TPU2, TPU3, TPU4,
+	LCRC,
+	PINTCA_PINT1, PINTCA_PINT2,
+	TTI20,
+	MISTY,
+	DDM,
+	RWDT0, RWDT1,
+	DMAC_1_DEI0, DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3,
+	DMAC_2_DEI4, DMAC_2_DEI5, DMAC_2_DADERR,
+	DMAC2_1_DEI0, DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3,
+	DMAC2_2_DEI4, DMAC2_2_DEI5, DMAC2_2_DADERR,
+	DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3,
+	DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR,
+	SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM,
+	ICUSB_ICUSB0, ICUSB_ICUSB1,
+	ICUDMC_ICUDMC1, ICUDMC_ICUDMC2,
+	SPU2_SPU0, SPU2_SPU1,
+	FSI,
+	FMSI,
+	SCUV,
+	IPMMU_IPMMUB,
+	AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ, AP_ARM_DMAIRQ, AP_ARM_DMASIRQ,
+	MFIS2,
+	CPORTR2S,
+	CMT14, CMT15,
+	SCIFA6,
+
+	/* interrupt groups INTCA */
+	DMAC_1, DMAC_2,	DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, SHWYSTAT,
+	AP_ARM1, AP_ARM2, USBHS, SPU2, FLCTL, IIC1,
+	ICUSB, ICUDMC
+};
+
+static struct intc_vect intca_vectors[] = {
+	INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
+	INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
+	INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
+	INTC_VECT(IRQ6A, 0x02c0), INTC_VECT(IRQ7A, 0x02e0),
+	INTC_VECT(IRQ8A, 0x0300), INTC_VECT(IRQ9A, 0x0320),
+	INTC_VECT(IRQ10A, 0x0340), INTC_VECT(IRQ11A, 0x0360),
+	INTC_VECT(IRQ12A, 0x0380), INTC_VECT(IRQ13A, 0x03a0),
+	INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0),
+	INTC_VECT(IRQ16A, 0x3200), INTC_VECT(IRQ17A, 0x3220),
+	INTC_VECT(IRQ18A, 0x3240), INTC_VECT(IRQ19A, 0x3260),
+	INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ31A, 0x32a0),
+	INTC_VECT(IRQ22A, 0x32c0), INTC_VECT(IRQ23A, 0x32e0),
+	INTC_VECT(IRQ24A, 0x3300), INTC_VECT(IRQ25A, 0x3320),
+	INTC_VECT(IRQ26A, 0x3340), INTC_VECT(IRQ27A, 0x3360),
+	INTC_VECT(IRQ28A, 0x3380), INTC_VECT(IRQ29A, 0x33a0),
+	INTC_VECT(IRQ30A, 0x33c0), INTC_VECT(IRQ31A, 0x33e0),
+	INTC_VECT(DIRC, 0x0560),
+	INTC_VECT(_2DG, 0x05e0),
+	INTC_VECT(CRYPT_STD, 0x0700),
+	INTC_VECT(IIC1_ALI1, 0x0780), INTC_VECT(IIC1_TACKI1, 0x07a0),
+	INTC_VECT(IIC1_WAITI1, 0x07c0), INTC_VECT(IIC1_DTEI1, 0x07e0),
+	INTC_VECT(AP_ARM_IRQPMU, 0x0800), INTC_VECT(AP_ARM_COMMTX, 0x0840),
+	INTC_VECT(AP_ARM_COMMRX, 0x0860),
+	INTC_VECT(MFI_MFIM, 0x0900), INTC_VECT(MFI_MFIS, 0x0920),
+	INTC_VECT(BBIF1, 0x0940), INTC_VECT(BBIF2, 0x0960),
+	INTC_VECT(USBDMAC_USHDMI, 0x0a00),
+	INTC_VECT(USBHS_USHI0, 0x0a20), INTC_VECT(USBHS_USHI1, 0x0a40),
+	INTC_VECT(_3DG_SGX540, 0x0a60),
+	INTC_VECT(CMT1_CMT10, 0x0b00), INTC_VECT(CMT1_CMT11, 0x0b20),
+	INTC_VECT(CMT1_CMT12, 0x0b40), INTC_VECT(CMT1_CMT13, 0x0b60),
+	INTC_VECT(CMT2, 0x0b80), INTC_VECT(CMT3, 0x0ba0),
+	INTC_VECT(KEYSC_KEY, 0x0be0),
+	INTC_VECT(SCIFA0, 0x0c00), INTC_VECT(SCIFA1, 0x0c20),
+	INTC_VECT(SCIFA2, 0x0c40), INTC_VECT(SCIFA3, 0x0c60),
+	INTC_VECT(MSIOF2, 0x0c80), INTC_VECT(MSIOF1, 0x0d00),
+	INTC_VECT(SCIFA4, 0x0d20), INTC_VECT(SCIFA5, 0x0d40),
+	INTC_VECT(SCIFB, 0x0d60),
+	INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
+	INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
+	INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20),
+	INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60),
+	INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0),
+	INTC_VECT(SDHI1, 0x0ec0), INTC_VECT(SDHI1, 0x0ee0),
+	INTC_VECT(MSU_MSU, 0x0f20), INTC_VECT(MSU_MSU2, 0x0f40),
+	INTC_VECT(IRREM, 0x0f60),
+	INTC_VECT(MSUG, 0x0fa0),
+	INTC_VECT(IRDA, 0x0480),
+	INTC_VECT(TPU0, 0x04a0), INTC_VECT(TPU1, 0x04c0),
+	INTC_VECT(TPU2, 0x04e0), INTC_VECT(TPU3, 0x0500),
+	INTC_VECT(TPU4, 0x0520),
+	INTC_VECT(LCRC, 0x0540),
+	INTC_VECT(PINTCA_PINT1, 0x1000), INTC_VECT(PINTCA_PINT2, 0x1020),
+	INTC_VECT(TTI20, 0x1100),
+	INTC_VECT(MISTY, 0x1120),
+	INTC_VECT(DDM, 0x1140),
+	INTC_VECT(RWDT0, 0x1280), INTC_VECT(RWDT1, 0x12a0),
+	INTC_VECT(DMAC_1_DEI0, 0x2000), INTC_VECT(DMAC_1_DEI1, 0x2020),
+	INTC_VECT(DMAC_1_DEI2, 0x2040), INTC_VECT(DMAC_1_DEI3, 0x2060),
+	INTC_VECT(DMAC_2_DEI4, 0x2080), INTC_VECT(DMAC_2_DEI5, 0x20a0),
+	INTC_VECT(DMAC_2_DADERR, 0x20c0),
+	INTC_VECT(DMAC2_1_DEI0, 0x2100), INTC_VECT(DMAC2_1_DEI1, 0x2120),
+	INTC_VECT(DMAC2_1_DEI2, 0x2140), INTC_VECT(DMAC2_1_DEI3, 0x2160),
+	INTC_VECT(DMAC2_2_DEI4, 0x2180), INTC_VECT(DMAC2_2_DEI5, 0x21a0),
+	INTC_VECT(DMAC2_2_DADERR, 0x21c0),
+	INTC_VECT(DMAC3_1_DEI0, 0x2200), INTC_VECT(DMAC3_1_DEI1, 0x2220),
+	INTC_VECT(DMAC3_1_DEI2, 0x2240), INTC_VECT(DMAC3_1_DEI3, 0x2260),
+	INTC_VECT(DMAC3_2_DEI4, 0x2280), INTC_VECT(DMAC3_2_DEI5, 0x22a0),
+	INTC_VECT(DMAC3_2_DADERR, 0x22c0),
+	INTC_VECT(SHWYSTAT_RT, 0x1300), INTC_VECT(SHWYSTAT_HS, 0x1d20),
+	INTC_VECT(SHWYSTAT_COM, 0x1340),
+	INTC_VECT(ICUSB_ICUSB0, 0x1700), INTC_VECT(ICUSB_ICUSB1, 0x1720),
+	INTC_VECT(ICUDMC_ICUDMC1, 0x1780), INTC_VECT(ICUDMC_ICUDMC2, 0x17a0),
+	INTC_VECT(SPU2_SPU0, 0x1800), INTC_VECT(SPU2_SPU1, 0x1820),
+	INTC_VECT(FSI, 0x1840),
+	INTC_VECT(FMSI, 0x1860),
+	INTC_VECT(SCUV, 0x1880),
+	INTC_VECT(IPMMU_IPMMUB, 0x1900),
+	INTC_VECT(AP_ARM_CTIIRQ, 0x1980),
+	INTC_VECT(AP_ARM_DMAEXTERRIRQ, 0x19a0),
+	INTC_VECT(AP_ARM_DMAIRQ, 0x19c0),
+	INTC_VECT(AP_ARM_DMASIRQ, 0x19e0),
+	INTC_VECT(MFIS2, 0x1a00),
+	INTC_VECT(CPORTR2S, 0x1a20),
+	INTC_VECT(CMT14, 0x1a40), INTC_VECT(CMT15, 0x1a60),
+	INTC_VECT(SCIFA6, 0x1a80),
+};
+
+static struct intc_group intca_groups[] __initdata = {
+	INTC_GROUP(DMAC_1, DMAC_1_DEI0,
+		   DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3),
+	INTC_GROUP(DMAC_2, DMAC_2_DEI4,
+		   DMAC_2_DEI5, DMAC_2_DADERR),
+	INTC_GROUP(DMAC2_1, DMAC2_1_DEI0,
+		   DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3),
+	INTC_GROUP(DMAC2_2, DMAC2_2_DEI4,
+		   DMAC2_2_DEI5, DMAC2_2_DADERR),
+	INTC_GROUP(DMAC3_1, DMAC3_1_DEI0,
+		   DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3),
+	INTC_GROUP(DMAC3_2, DMAC3_2_DEI4,
+		   DMAC3_2_DEI5, DMAC3_2_DADERR),
+	INTC_GROUP(AP_ARM1, AP_ARM_IRQPMU, AP_ARM_COMMTX, AP_ARM_COMMTX),
+	INTC_GROUP(USBHS, USBHS_USHI0, USBHS_USHI1),
+	INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1),
+	INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
+		   FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
+	INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
+	INTC_GROUP(SHWYSTAT, SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM),
+	INTC_GROUP(ICUSB, ICUSB_ICUSB0, ICUSB_ICUSB1),
+	INTC_GROUP(ICUDMC, ICUDMC_ICUDMC1, ICUDMC_ICUDMC2),
+};
+
+static struct intc_mask_reg intca_mask_registers[] = {
+	{ 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
+	  { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+	{ 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
+	  { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+	{ 0xe6900048, 0xe6900068, 8, /* INTMSK20A / INTMSKCLR20A */
+	  { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+	{ 0xe690004c, 0xe690006c, 8, /* INTMSK30A / INTMSKCLR30A */
+	  { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+
+	{ 0xe6940080, 0xe69400c0, 8, /* IMR0A / IMCR0A */
+	  { DMAC2_1_DEI3, DMAC2_1_DEI2, DMAC2_1_DEI1, DMAC2_1_DEI0,
+	    AP_ARM_IRQPMU, 0, AP_ARM_COMMTX, AP_ARM_COMMRX } },
+	{ 0xe6940084, 0xe69400c4, 8, /* IMR1A / IMCR1A */
+	  { _2DG, CRYPT_STD, DIRC, 0,
+	    DMAC_1_DEI3, DMAC_1_DEI2, DMAC_1_DEI1, DMAC_1_DEI0 } },
+	{ 0xe6940088, 0xe69400c8, 8, /* IMR2A / IMCR2A */
+	  { PINTCA_PINT1, PINTCA_PINT2, 0, 0,
+	    BBIF1, BBIF2, MFI_MFIS, MFI_MFIM } },
+	{ 0xe694008c, 0xe69400cc, 8, /* IMR3A / IMCR3A */
+	  { DMAC3_1_DEI3, DMAC3_1_DEI2, DMAC3_1_DEI1, DMAC3_1_DEI0,
+	    DMAC3_2_DADERR, DMAC3_2_DEI5, DMAC3_2_DEI4, IRDA } },
+	{ 0xe6940090, 0xe69400d0, 8, /* IMR4A / IMCR4A */
+	  { DDM, 0, 0, 0,
+	    0, 0, 0, 0 } },
+	{ 0xe6940094, 0xe69400d4, 8, /* IMR5A / IMCR5A */
+	  { KEYSC_KEY, DMAC_2_DADERR, DMAC_2_DEI5, DMAC_2_DEI4,
+	    SCIFA3, SCIFA2, SCIFA1, SCIFA0 } },
+	{ 0xe6940098, 0xe69400d8, 8, /* IMR6A / IMCR6A */
+	  { SCIFB, SCIFA5, SCIFA4, MSIOF1,
+	    0, 0, MSIOF2, 0 } },
+	{ 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
+	  { DISABLED, DISABLED, ENABLED, ENABLED,
+	    FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
+	{ 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
+	  { DISABLED, DISABLED, ENABLED, ENABLED,
+	    TTI20, USBDMAC_USHDMI, 0, MSUG } },
+	{ 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
+	  { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
+	    CMT2, USBHS_USHI1, USBHS_USHI0, _3DG_SGX540 } },
+	{ 0xe69400a8, 0xe69400e8, 8, /* IMR10A / IMCR10A */
+	  { 0, DMAC2_2_DADERR, DMAC2_2_DEI5, DMAC2_2_DEI4,
+	    0, 0, 0, 0 } },
+	{ 0xe69400ac, 0xe69400ec, 8, /* IMR11A / IMCR11A */
+	  { IIC1_DTEI1, IIC1_WAITI1, IIC1_TACKI1, IIC1_ALI1,
+	    LCRC, MSU_MSU2, IRREM, MSU_MSU } },
+	{ 0xe69400b0, 0xe69400f0, 8, /* IMR12A / IMCR12A */
+	  { 0, 0, TPU0, TPU1,
+	    TPU2, TPU3, TPU4, 0 } },
+	{ 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
+	  { 0, 0, 0, 0,
+	    MISTY, CMT3, RWDT1, RWDT0 } },
+	{ 0xe6950080, 0xe69500c0, 8, /* IMR0A3 / IMCR0A3 */
+	  { SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, 0,
+	    0, 0, 0, 0 } },
+	{ 0xe6950090, 0xe69500d0, 8, /* IMR4A3 / IMCR4A3 */
+	  { ICUSB_ICUSB0, ICUSB_ICUSB1, 0, 0,
+	    ICUDMC_ICUDMC1, ICUDMC_ICUDMC2, 0, 0 } },
+	{ 0xe6950094, 0xe69500d4, 8, /* IMR5A3 / IMCR5A3 */
+	  { SPU2_SPU0, SPU2_SPU1, FSI, FMSI,
+	    SCUV, 0, 0, 0 } },
+	{ 0xe6950098, 0xe69500d8, 8, /* IMR6A3 / IMCR6A3 */
+	  { IPMMU_IPMMUB, 0, 0, 0,
+	    AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ,
+	    AP_ARM_DMAIRQ, AP_ARM_DMASIRQ } },
+	{ 0xe695009c, 0xe69500dc, 8, /* IMR7A3 / IMCR7A3 */
+	  { MFIS2, CPORTR2S, CMT14, CMT15,
+	    SCIFA6, 0, 0, 0 } },
+};
+
+static struct intc_prio_reg intca_prio_registers[] = {
+	{ 0xe6900010, 0, 32, 4, /* INTPRI00A */
+	  { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+	{ 0xe6900014, 0, 32, 4, /* INTPRI10A */
+	  { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+	{ 0xe6900018, 0, 32, 4, /* INTPRI10A */
+	  { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+	{ 0xe690001c, 0, 32, 4, /* INTPRI30A */
+	  { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+
+	{ 0xe6940000, 0, 16, 4, /* IPRAA */ { DMAC3_1, DMAC3_2, CMT2, LCRC } },
+	{ 0xe6940004, 0, 16, 4, /* IPRBA */ { IRDA, 0, BBIF1, BBIF2 } },
+	{ 0xe6940008, 0, 16, 4, /* IPRCA */ { _2DG, CRYPT_STD,
+					      CMT1_CMT11, AP_ARM1 } },
+	{ 0xe694000c, 0, 16, 4, /* IPRDA */ { PINTCA_PINT1, PINTCA_PINT2,
+					      CMT1_CMT12, TPU4 } },
+	{ 0xe6940010, 0, 16, 4, /* IPREA */ { DMAC_1, MFI_MFIS,
+					      MFI_MFIM, USBHS } },
+	{ 0xe6940014, 0, 16, 4, /* IPRFA */ { KEYSC_KEY, DMAC_2,
+					      _3DG_SGX540, CMT1_CMT10 } },
+	{ 0xe6940018, 0, 16, 4, /* IPRGA */ { SCIFA0, SCIFA1,
+					      SCIFA2, SCIFA3 } },
+	{ 0xe694001c, 0, 16, 4, /* IPRGH */ { MSIOF2, USBDMAC_USHDMI,
+					      FLCTL, SDHI0 } },
+	{ 0xe6940020, 0, 16, 4, /* IPRIA */ { MSIOF1, SCIFA4, MSU_MSU, IIC1 } },
+	{ 0xe6940024, 0, 16, 4, /* IPRJA */ { DMAC2_1, DMAC2_2, MSUG, TTI20 } },
+	{ 0xe6940028, 0, 16, 4, /* IPRKA */ { 0, CMT1_CMT13, IRREM, SDHI1 } },
+	{ 0xe694002c, 0, 16, 4, /* IPRLA */ { TPU0, TPU1, TPU2, TPU3 } },
+	{ 0xe6940030, 0, 16, 4, /* IPRMA */ { MISTY, CMT3, RWDT1, RWDT0 } },
+	{ 0xe6940034, 0, 16, 4, /* IPRNA */ { SCIFB, SCIFA5, 0, DDM } },
+	{ 0xe6940038, 0, 16, 4, /* IPROA */ { 0, 0, DIRC, 0 } },
+	{ 0xe6950000, 0, 16, 4, /* IPRAA3 */ { SHWYSTAT, 0, 0, 0 } },
+	{ 0xe6950020, 0, 16, 4, /* IPRIA3 */ { ICUSB, 0, 0, 0 } },
+	{ 0xe6950024, 0, 16, 4, /* IPRJA3 */ { ICUDMC, 0, 0, 0 } },
+	{ 0xe6950028, 0, 16, 4, /* IPRKA3 */ { SPU2, 0, FSI, FMSI } },
+	{ 0xe695002c, 0, 16, 4, /* IPRLA3 */ { SCUV, 0, 0, 0 } },
+	{ 0xe6950030, 0, 16, 4, /* IPRMA3 */ { IPMMU_IPMMUB, 0, 0, 0 } },
+	{ 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } },
+	{ 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S,
+					       CMT14, CMT15 } },
+	{ 0xe694003c, 0, 16, 4, /* IPRPA3 */ { SCIFA6, 0, 0, 0 } },
+};
+
+static struct intc_sense_reg intca_sense_registers[] __initdata = {
+	{ 0xe6900000, 16, 2, /* ICR1A */
+	  { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+	{ 0xe6900004, 16, 2, /* ICR2A */
+	  { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+	{ 0xe6900008, 16, 2, /* ICR3A */
+	  { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+	{ 0xe690000c, 16, 2, /* ICR4A */
+	  { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+};
+
+static struct intc_mask_reg intca_ack_registers[] __initdata = {
+	{ 0xe6900020, 0, 8, /* INTREQ00A */
+	  { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+	{ 0xe6900024, 0, 8, /* INTREQ10A */
+	  { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+	{ 0xe6900028, 0, 8, /* INTREQ20A */
+	  { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+	{ 0xe690002c, 0, 8, /* INTREQ30A */
+	  { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+};
+
+static struct intc_desc intca_desc __initdata = {
+	.name = "sh7377-intca",
+	.force_enable = ENABLED,
+	.force_disable = DISABLED,
+	.hw = INTC_HW_DESC(intca_vectors, intca_groups,
+			   intca_mask_registers, intca_prio_registers,
+			   intca_sense_registers, intca_ack_registers),
+};
+
+void __init sh7377_init_irq(void)
+{
+	register_intc_controller(&intca_desc);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,84 @@
+if ARCH_SHMOBILE
+
+comment "SH-Mobile System Type"
+
+config ARCH_SH7367
+	bool "SH-Mobile G3 (SH7367)"
+	select CPU_V6
+	select HAVE_CLK
+	select COMMON_CLKDEV
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+
+config ARCH_SH7377
+	bool "SH-Mobile G4 (SH7377)"
+	select CPU_V7
+	select HAVE_CLK
+	select COMMON_CLKDEV
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+
+config ARCH_SH7372
+	bool "SH-Mobile AP4 (SH7372)"
+	select CPU_V7
+	select HAVE_CLK
+	select COMMON_CLKDEV
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+
+comment "SH-Mobile Board Type"
+
+config MACH_G3EVM
+	bool "G3EVM board"
+	depends on ARCH_SH7367
+	select ARCH_REQUIRE_GPIOLIB
+
+config MACH_G4EVM
+	bool "G4EVM board"
+	depends on ARCH_SH7377
+	select ARCH_REQUIRE_GPIOLIB
+
+config MACH_AP4EVB
+	bool "AP4EVB board"
+	depends on ARCH_SH7372
+	select ARCH_REQUIRE_GPIOLIB
+
+comment "SH-Mobile System Configuration"
+
+menu "Memory configuration"
+
+config MEMORY_START
+	hex "Physical memory start address"
+	default "0x50000000" if MACH_G3EVM
+	default "0x40000000" if MACH_G4EVM
+	default "0x40000000" if MACH_AP4EVB
+	default "0x00000000"
+	---help---
+	  Tweak this only when porting to a new machine which does not
+	  already have a defconfig. Changing it from the known correct
+	  value on any of the known systems will only lead to disaster.
+
+config MEMORY_SIZE
+	hex "Physical memory size"
+	default "0x08000000" if MACH_G3EVM
+	default "0x08000000" if MACH_G4EVM
+	default "0x10000000" if MACH_AP4EVB
+	default "0x04000000"
+	help
+	  This sets the default memory size assumed by your kernel. It can
+	  be overridden as normal by the 'mem=' argument on the kernel command
+	  line.
+
+endmenu
+
+menu "Timer and clock configuration"
+
+config SH_TIMER_CMT
+	bool "CMT timer driver"
+	default y
+	help
+	  This enables build of the CMT timer driver.
+
+endmenu
+
+endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/Makefile linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,22 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common objects
+obj-y				:= timer.o console.o
+
+# CPU objects
+obj-$(CONFIG_ARCH_SH7367)	+= setup-sh7367.o clock-sh7367.o intc-sh7367.o
+obj-$(CONFIG_ARCH_SH7377)	+= setup-sh7377.o clock-sh7367.o intc-sh7377.o
+obj-$(CONFIG_ARCH_SH7372)	+= setup-sh7372.o clock-sh7367.o intc-sh7372.o
+
+# Pinmux setup
+pfc-$(CONFIG_ARCH_SH7367)	:= pfc-sh7367.o
+pfc-$(CONFIG_ARCH_SH7377)	:= pfc-sh7377.o
+pfc-$(CONFIG_ARCH_SH7372)	:= pfc-sh7372.o
+obj-$(CONFIG_GENERIC_GPIO)	+= $(pfc-y)
+
+# Board objects
+obj-$(CONFIG_MACH_G3EVM)	+= board-g3evm.o
+obj-$(CONFIG_MACH_G4EVM)	+= board-g4evm.o
+obj-$(CONFIG_MACH_AP4EVB)	+= board-ap4evb.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/Makefile.boot linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/Makefile.boot
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/Makefile.boot	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,9 @@
+__ZRELADDR	:= $(shell /bin/bash -c 'printf "0x%08x" \
+		     $$[$(CONFIG_MEMORY_START) + 0x8000]')
+
+   zreladdr-y   := $(__ZRELADDR)
+
+# Unsupported legacy stuff
+#
+#params_phys-y (Instead: Pass atags pointer in r2)
+#initrd_phys-y (Instead: Use compiled-in initramfs)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/pfc-sh7367.c linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/pfc-sh7367.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/pfc-sh7367.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/pfc-sh7367.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1801 @@
+/*
+ * sh7367 processor support - PFC hardware block
+ *
+ * Copyright (C) 2010  Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <mach/sh7367.h>
+
+#define _1(fn, pfx, sfx) fn(pfx, sfx)
+
+#define _10(fn, pfx, sfx)				\
+	_1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx),	\
+	_1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx),	\
+	_1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx),	\
+	_1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx),	\
+	_1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
+
+#define _90(fn, pfx, sfx)				\
+	_10(fn, pfx##1, sfx), _10(fn, pfx##2, sfx),	\
+	_10(fn, pfx##3, sfx), _10(fn, pfx##4, sfx),	\
+	_10(fn, pfx##5, sfx), _10(fn, pfx##6, sfx),	\
+	_10(fn, pfx##7, sfx), _10(fn, pfx##8, sfx),	\
+	_10(fn, pfx##9, sfx)
+
+#define _273(fn, pfx, sfx)		\
+	_10(fn, pfx, sfx), _90(fn, pfx, sfx),		\
+	_10(fn, pfx##10, sfx), _90(fn, pfx##1, sfx),	\
+	_10(fn, pfx##20, sfx), _10(fn, pfx##21, sfx),	\
+	_10(fn, pfx##22, sfx), _10(fn, pfx##23, sfx),	\
+	_10(fn, pfx##24, sfx), _10(fn, pfx##25, sfx),	\
+	_10(fn, pfx##26, sfx), _1(fn, pfx##270, sfx),	\
+	_1(fn, pfx##271, sfx), _1(fn, pfx##272, sfx)
+
+#define _PORT(pfx, sfx) pfx##_##sfx
+#define PORT_273(str) _273(_PORT, PORT, str)
+
+enum {
+	PINMUX_RESERVED = 0,
+
+	PINMUX_DATA_BEGIN,
+	PORT_273(DATA), /* PORT0_DATA -> PORT272_DATA */
+	PINMUX_DATA_END,
+
+	PINMUX_INPUT_BEGIN,
+	PORT_273(IN), /* PORT0_IN -> PORT272_IN */
+	PINMUX_INPUT_END,
+
+	PINMUX_INPUT_PULLUP_BEGIN,
+	PORT_273(IN_PU), /* PORT0_IN_PU -> PORT272_IN_PU */
+	PINMUX_INPUT_PULLUP_END,
+
+	PINMUX_INPUT_PULLDOWN_BEGIN,
+	PORT_273(IN_PD), /* PORT0_IN_PD -> PORT272_IN_PD */
+	PINMUX_INPUT_PULLDOWN_END,
+
+	PINMUX_OUTPUT_BEGIN,
+	PORT_273(OUT), /* PORT0_OUT -> PORT272_OUT */
+	PINMUX_OUTPUT_END,
+
+	PINMUX_FUNCTION_BEGIN,
+	PORT_273(FN_IN), /* PORT0_FN_IN -> PORT272_FN_IN */
+	PORT_273(FN_OUT), /* PORT0_FN_OUT -> PORT272_FN_OUT */
+	PORT_273(FN0), /* PORT0_FN0 -> PORT272_FN0 */
+	PORT_273(FN1), /* PORT0_FN1 -> PORT272_FN1 */
+	PORT_273(FN2), /* PORT0_FN2 -> PORT272_FN2 */
+	PORT_273(FN3), /* PORT0_FN3 -> PORT272_FN3 */
+	PORT_273(FN4), /* PORT0_FN4 -> PORT272_FN4 */
+	PORT_273(FN5), /* PORT0_FN5 -> PORT272_FN5 */
+	PORT_273(FN6), /* PORT0_FN6 -> PORT272_FN6 */
+	PORT_273(FN7), /* PORT0_FN7 -> PORT272_FN7 */
+
+	MSELBCR_MSEL2_1, MSELBCR_MSEL2_0,
+	PINMUX_FUNCTION_END,
+
+	PINMUX_MARK_BEGIN,
+	/* Special Pull-up / Pull-down Functions */
+	PORT48_KEYIN0_PU_MARK, PORT49_KEYIN1_PU_MARK,
+	PORT50_KEYIN2_PU_MARK, PORT55_KEYIN3_PU_MARK,
+	PORT56_KEYIN4_PU_MARK, PORT57_KEYIN5_PU_MARK,
+	PORT58_KEYIN6_PU_MARK,
+
+	/* 49-1 */
+	VBUS0_MARK, CPORT0_MARK, CPORT1_MARK, CPORT2_MARK,
+	CPORT3_MARK, CPORT4_MARK, CPORT5_MARK, CPORT6_MARK,
+	CPORT7_MARK, CPORT8_MARK, CPORT9_MARK, CPORT10_MARK,
+	CPORT11_MARK, SIN2_MARK, CPORT12_MARK, XCTS2_MARK,
+	CPORT13_MARK, RFSPO4_MARK, CPORT14_MARK, RFSPO5_MARK,
+	CPORT15_MARK, CPORT16_MARK, CPORT17_MARK, SOUT2_MARK,
+	CPORT18_MARK, XRTS2_MARK, CPORT19_MARK, CPORT20_MARK,
+	RFSPO6_MARK, CPORT21_MARK, STATUS0_MARK, CPORT22_MARK,
+	STATUS1_MARK, CPORT23_MARK, STATUS2_MARK, RFSPO7_MARK,
+	MPORT0_MARK, MPORT1_MARK, B_SYNLD1_MARK, B_SYNLD2_MARK,
+	XMAINPS_MARK, XDIVPS_MARK, XIDRST_MARK, IDCLK_MARK,
+	IDIO_MARK, SOUT1_MARK, SCIFA4_TXD_MARK,
+	M02_BERDAT_MARK, SIN1_MARK, SCIFA4_RXD_MARK, XWUP_MARK,
+	XRTS1_MARK, SCIFA4_RTS_MARK, M03_BERCLK_MARK,
+	XCTS1_MARK, SCIFA4_CTS_MARK,
+
+	/* 49-2 */
+	HSU_IQ_AGC6_MARK, MFG2_IN2_MARK, MSIOF2_MCK0_MARK,
+	HSU_IQ_AGC5_MARK, MFG2_IN1_MARK, MSIOF2_MCK1_MARK,
+	HSU_IQ_AGC4_MARK, MSIOF2_RSYNC_MARK,
+	HSU_IQ_AGC3_MARK, MFG2_OUT1_MARK, MSIOF2_RSCK_MARK,
+	HSU_IQ_AGC2_MARK, PORT42_KEYOUT0_MARK,
+	HSU_IQ_AGC1_MARK, PORT43_KEYOUT1_MARK,
+	HSU_IQ_AGC0_MARK, PORT44_KEYOUT2_MARK,
+	HSU_IQ_AGC_ST_MARK, PORT45_KEYOUT3_MARK,
+	HSU_IQ_PDO_MARK, PORT46_KEYOUT4_MARK,
+	HSU_IQ_PYO_MARK, PORT47_KEYOUT5_MARK,
+	HSU_EN_TXMUX_G3MO_MARK, PORT48_KEYIN0_MARK,
+	HSU_I_TXMUX_G3MO_MARK, PORT49_KEYIN1_MARK,
+	HSU_Q_TXMUX_G3MO_MARK, PORT50_KEYIN2_MARK,
+	HSU_SYO_MARK, PORT51_MSIOF2_TSYNC_MARK,
+	HSU_SDO_MARK, PORT52_MSIOF2_TSCK_MARK,
+	HSU_TGTTI_G3MO_MARK, PORT53_MSIOF2_TXD_MARK,
+	B_TIME_STAMP_MARK, PORT54_MSIOF2_RXD_MARK,
+	HSU_SDI_MARK, PORT55_KEYIN3_MARK,
+	HSU_SCO_MARK, PORT56_KEYIN4_MARK,
+	HSU_DREQ_MARK, PORT57_KEYIN5_MARK,
+	HSU_DACK_MARK, PORT58_KEYIN6_MARK,
+	HSU_CLK61M_MARK, PORT59_MSIOF2_SS1_MARK,
+	HSU_XRST_MARK, PORT60_MSIOF2_SS2_MARK,
+	PCMCLKO_MARK, SYNC8KO_MARK, DNPCM_A_MARK, UPPCM_A_MARK,
+	XTALB1L_MARK,
+	GPS_AGC1_MARK, SCIFA0_RTS_MARK,
+	GPS_AGC2_MARK, SCIFA0_SCK_MARK,
+	GPS_AGC3_MARK, SCIFA0_TXD_MARK,
+	GPS_AGC4_MARK, SCIFA0_RXD_MARK,
+	GPS_PWRD_MARK, SCIFA0_CTS_MARK,
+	GPS_IM_MARK, GPS_IS_MARK, GPS_QM_MARK, GPS_QS_MARK,
+	SIUBOMC_MARK, TPU2TO0_MARK,
+	SIUCKB_MARK, TPU2TO1_MARK,
+	SIUBOLR_MARK, BBIF2_TSYNC_MARK, TPU2TO2_MARK,
+	SIUBOBT_MARK, BBIF2_TSCK_MARK, TPU2TO3_MARK,
+	SIUBOSLD_MARK, BBIF2_TXD_MARK, TPU3TO0_MARK,
+	SIUBILR_MARK, TPU3TO1_MARK,
+	SIUBIBT_MARK, TPU3TO2_MARK,
+	SIUBISLD_MARK, TPU3TO3_MARK,
+	NMI_MARK, TPU4TO0_MARK,
+	DNPCM_M_MARK, TPU4TO1_MARK, TPU4TO2_MARK, TPU4TO3_MARK,
+	IRQ_TMPB_MARK,
+	PWEN_MARK, MFG1_OUT1_MARK,
+	OVCN_MARK, MFG1_IN1_MARK,
+	OVCN2_MARK, MFG1_IN2_MARK,
+
+	/* 49-3 */
+	RFSPO1_MARK, RFSPO2_MARK, RFSPO3_MARK, PORT93_VIO_CKO2_MARK,
+	USBTERM_MARK, EXTLP_MARK, IDIN_MARK,
+	SCIFA5_CTS_MARK, MFG0_IN1_MARK,
+	SCIFA5_RTS_MARK, MFG0_IN2_MARK,
+	SCIFA5_RXD_MARK,
+	SCIFA5_TXD_MARK,
+	SCIFA5_SCK_MARK, MFG0_OUT1_MARK,
+	A0_EA0_MARK, BS_MARK,
+	A14_EA14_MARK, PORT102_KEYOUT0_MARK,
+	A15_EA15_MARK, PORT103_KEYOUT1_MARK, DV_CLKOL_MARK,
+	A16_EA16_MARK, PORT104_KEYOUT2_MARK,
+	DV_VSYNCL_MARK, MSIOF0_SS1_MARK,
+	A17_EA17_MARK, PORT105_KEYOUT3_MARK,
+	DV_HSYNCL_MARK, MSIOF0_TSYNC_MARK,
+	A18_EA18_MARK, PORT106_KEYOUT4_MARK,
+	DV_DL0_MARK, MSIOF0_TSCK_MARK,
+	A19_EA19_MARK, PORT107_KEYOUT5_MARK,
+	DV_DL1_MARK, MSIOF0_TXD_MARK,
+	A20_EA20_MARK, PORT108_KEYIN0_MARK,
+	DV_DL2_MARK, MSIOF0_RSCK_MARK,
+	A21_EA21_MARK, PORT109_KEYIN1_MARK,
+	DV_DL3_MARK, MSIOF0_RSYNC_MARK,
+	A22_EA22_MARK, PORT110_KEYIN2_MARK,
+	DV_DL4_MARK, MSIOF0_MCK0_MARK,
+	A23_EA23_MARK, PORT111_KEYIN3_MARK,
+	DV_DL5_MARK, MSIOF0_MCK1_MARK,
+	A24_EA24_MARK, PORT112_KEYIN4_MARK,
+	DV_DL6_MARK, MSIOF0_RXD_MARK,
+	A25_EA25_MARK, PORT113_KEYIN5_MARK,
+	DV_DL7_MARK, MSIOF0_SS2_MARK,
+	A26_MARK, PORT113_KEYIN6_MARK, DV_CLKIL_MARK,
+	D0_ED0_NAF0_MARK, D1_ED1_NAF1_MARK, D2_ED2_NAF2_MARK,
+	D3_ED3_NAF3_MARK, D4_ED4_NAF4_MARK, D5_ED5_NAF5_MARK,
+	D6_ED6_NAF6_MARK, D7_ED7_NAF7_MARK, D8_ED8_NAF8_MARK,
+	D9_ED9_NAF9_MARK, D10_ED10_NAF10_MARK, D11_ED11_NAF11_MARK,
+	D12_ED12_NAF12_MARK, D13_ED13_NAF13_MARK,
+	D14_ED14_NAF14_MARK, D15_ED15_NAF15_MARK,
+	CS4_MARK, CS5A_MARK, CS5B_MARK, FCE1_MARK,
+	CS6B_MARK, XCS2_MARK, FCE0_MARK, CS6A_MARK,
+	DACK0_MARK, WAIT_MARK, DREQ0_MARK, RD_XRD_MARK,
+	A27_MARK, RDWR_XWE_MARK, WE0_XWR0_FWE_MARK,
+	WE1_XWR1_MARK, FRB_MARK, CKO_MARK,
+	NBRSTOUT_MARK, NBRST_MARK,
+
+	/* 49-4 */
+	RFSPO0_MARK, PORT146_VIO_CKO2_MARK, TSTMD_MARK,
+	VIO_VD_MARK, VIO_HD_MARK,
+	VIO_D0_MARK, VIO_D1_MARK, VIO_D2_MARK,
+	VIO_D3_MARK, VIO_D4_MARK, VIO_D5_MARK,
+	VIO_D6_MARK, VIO_D7_MARK, VIO_D8_MARK,
+	VIO_D9_MARK, VIO_D10_MARK, VIO_D11_MARK,
+	VIO_D12_MARK, VIO_D13_MARK, VIO_D14_MARK,
+	VIO_D15_MARK, VIO_CLK_MARK, VIO_FIELD_MARK,
+	VIO_CKO_MARK,
+	MFG3_IN1_MARK, MFG3_IN2_MARK,
+	M9_SLCD_A01_MARK, MFG3_OUT1_MARK, TPU0TO0_MARK,
+	M10_SLCD_CK1_MARK, MFG4_IN1_MARK, TPU0TO1_MARK,
+	M11_SLCD_SO1_MARK, MFG4_IN2_MARK, TPU0TO2_MARK,
+	M12_SLCD_CE1_MARK, MFG4_OUT1_MARK, TPU0TO3_MARK,
+	LCDD0_MARK, PORT175_KEYOUT0_MARK, DV_D0_MARK,
+	SIUCKA_MARK, MFG0_OUT2_MARK,
+	LCDD1_MARK, PORT176_KEYOUT1_MARK, DV_D1_MARK,
+	SIUAOLR_MARK, BBIF2_TSYNC1_MARK,
+	LCDD2_MARK, PORT177_KEYOUT2_MARK, DV_D2_MARK,
+	SIUAOBT_MARK, BBIF2_TSCK1_MARK,
+	LCDD3_MARK, PORT178_KEYOUT3_MARK, DV_D3_MARK,
+	SIUAOSLD_MARK, BBIF2_TXD1_MARK,
+	LCDD4_MARK, PORT179_KEYOUT4_MARK, DV_D4_MARK,
+	SIUAISPD_MARK, MFG1_OUT2_MARK,
+	LCDD5_MARK, PORT180_KEYOUT5_MARK, DV_D5_MARK,
+	SIUAILR_MARK, MFG2_OUT2_MARK,
+	LCDD6_MARK, DV_D6_MARK,
+	SIUAIBT_MARK, MFG3_OUT2_MARK, XWR2_MARK,
+	LCDD7_MARK, DV_D7_MARK,
+	SIUAISLD_MARK, MFG4_OUT2_MARK, XWR3_MARK,
+	LCDD8_MARK, DV_D8_MARK, D16_MARK, ED16_MARK,
+	LCDD9_MARK, DV_D9_MARK, D17_MARK, ED17_MARK,
+	LCDD10_MARK, DV_D10_MARK, D18_MARK, ED18_MARK,
+	LCDD11_MARK, DV_D11_MARK, D19_MARK, ED19_MARK,
+	LCDD12_MARK, DV_D12_MARK, D20_MARK, ED20_MARK,
+	LCDD13_MARK, DV_D13_MARK, D21_MARK, ED21_MARK,
+	LCDD14_MARK, DV_D14_MARK, D22_MARK, ED22_MARK,
+	LCDD15_MARK, DV_D15_MARK, D23_MARK, ED23_MARK,
+	LCDD16_MARK, DV_HSYNC_MARK, D24_MARK, ED24_MARK,
+	LCDD17_MARK, DV_VSYNC_MARK, D25_MARK, ED25_MARK,
+	LCDD18_MARK, DREQ2_MARK, MSIOF0L_TSCK_MARK,
+	D26_MARK, ED26_MARK,
+	LCDD19_MARK, MSIOF0L_TSYNC_MARK,
+	D27_MARK, ED27_MARK,
+	LCDD20_MARK, TS_SPSYNC1_MARK, MSIOF0L_MCK0_MARK,
+	D28_MARK, ED28_MARK,
+	LCDD21_MARK, TS_SDAT1_MARK, MSIOF0L_MCK1_MARK,
+	D29_MARK, ED29_MARK,
+	LCDD22_MARK, TS_SDEN1_MARK, MSIOF0L_SS1_MARK,
+	D30_MARK, ED30_MARK,
+	LCDD23_MARK, TS_SCK1_MARK, MSIOF0L_SS2_MARK,
+	D31_MARK, ED31_MARK,
+	LCDDCK_MARK, LCDWR_MARK, DV_CKO_MARK, SIUAOSPD_MARK,
+	LCDRD_MARK, DACK2_MARK, MSIOF0L_RSYNC_MARK,
+
+	/* 49-5 */
+	LCDHSYN_MARK, LCDCS_MARK, LCDCS2_MARK, DACK3_MARK,
+	LCDDISP_MARK, LCDRS_MARK, DREQ3_MARK, MSIOF0L_RSCK_MARK,
+	LCDCSYN_MARK, LCDCSYN2_MARK, DV_CKI_MARK,
+	LCDLCLK_MARK, DREQ1_MARK, MSIOF0L_RXD_MARK,
+	LCDDON_MARK, LCDDON2_MARK, DACK1_MARK, MSIOF0L_TXD_MARK,
+	VIO_DR0_MARK, VIO_DR1_MARK, VIO_DR2_MARK, VIO_DR3_MARK,
+	VIO_DR4_MARK, VIO_DR5_MARK, VIO_DR6_MARK, VIO_DR7_MARK,
+	VIO_VDR_MARK, VIO_HDR_MARK,
+	VIO_CLKR_MARK, VIO_CKOR_MARK,
+	SCIFA1_TXD_MARK, GPS_PGFA0_MARK,
+	SCIFA1_SCK_MARK, GPS_PGFA1_MARK,
+	SCIFA1_RTS_MARK, GPS_EPPSINMON_MARK,
+	SCIFA1_RXD_MARK, SCIFA1_CTS_MARK,
+	MSIOF1_TXD_MARK, SCIFA1_TXD2_MARK, GPS_TXD_MARK,
+	MSIOF1_TSYNC_MARK, SCIFA1_CTS2_MARK, I2C_SDA2_MARK,
+	MSIOF1_TSCK_MARK, SCIFA1_SCK2_MARK,
+	MSIOF1_RXD_MARK, SCIFA1_RXD2_MARK, GPS_RXD_MARK,
+	MSIOF1_RSCK_MARK, SCIFA1_RTS2_MARK,
+	MSIOF1_RSYNC_MARK, I2C_SCL2_MARK,
+	MSIOF1_MCK0_MARK, MSIOF1_MCK1_MARK,
+	MSIOF1_SS1_MARK, EDBGREQ3_MARK,
+	MSIOF1_SS2_MARK,
+	PORT236_IROUT_MARK, IRDA_OUT_MARK,
+	IRDA_IN_MARK, IRDA_FIRSEL_MARK,
+	TPU1TO0_MARK, TS_SPSYNC3_MARK,
+	TPU1TO1_MARK, TS_SDAT3_MARK,
+	TPU1TO2_MARK, TS_SDEN3_MARK, PORT241_MSIOF2_SS1_MARK,
+	TPU1TO3_MARK, PORT242_MSIOF2_TSCK_MARK,
+	M13_BSW_MARK, PORT243_MSIOF2_TSYNC_MARK,
+	M14_GSW_MARK, PORT244_MSIOF2_TXD_MARK,
+	PORT245_IROUT_MARK, M15_RSW_MARK,
+	SOUT3_MARK, SCIFA2_TXD1_MARK,
+	SIN3_MARK, SCIFA2_RXD1_MARK,
+	XRTS3_MARK, SCIFA2_RTS1_MARK, PORT248_MSIOF2_SS2_MARK,
+	XCTS3_MARK, SCIFA2_CTS1_MARK, PORT249_MSIOF2_RXD_MARK,
+	DINT_MARK, SCIFA2_SCK1_MARK, TS_SCK3_MARK,
+	SDHICLK0_MARK, TCK2_MARK,
+	SDHICD0_MARK,
+	SDHID0_0_MARK, TMS2_MARK,
+	SDHID0_1_MARK, TDO2_MARK,
+	SDHID0_2_MARK, TDI2_MARK,
+	SDHID0_3_MARK, RTCK2_MARK,
+
+	/* 49-6 */
+	SDHICMD0_MARK, TRST2_MARK,
+	SDHIWP0_MARK, EDBGREQ2_MARK,
+	SDHICLK1_MARK, TCK3_MARK,
+	SDHID1_0_MARK, M11_SLCD_SO2_MARK,
+	TS_SPSYNC2_MARK, TMS3_MARK,
+	SDHID1_1_MARK, M9_SLCD_AO2_MARK,
+	TS_SDAT2_MARK, TDO3_MARK,
+	SDHID1_2_MARK, M10_SLCD_CK2_MARK,
+	TS_SDEN2_MARK, TDI3_MARK,
+	SDHID1_3_MARK, M12_SLCD_CE2_MARK,
+	TS_SCK2_MARK, RTCK3_MARK,
+	SDHICMD1_MARK, TRST3_MARK,
+	SDHICLK2_MARK, SCIFB_SCK_MARK,
+	SDHID2_0_MARK, SCIFB_TXD_MARK,
+	SDHID2_1_MARK, SCIFB_CTS_MARK,
+	SDHID2_2_MARK, SCIFB_RXD_MARK,
+	SDHID2_3_MARK, SCIFB_RTS_MARK,
+	SDHICMD2_MARK,
+	RESETOUTS_MARK,
+	DIVLOCK_MARK,
+	PINMUX_MARK_END,
+};
+
+#define PORT_DATA_I(nr) \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)
+
+#define PORT_DATA_I_PD(nr) \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+		    PORT##nr##_IN, PORT##nr##_IN_PD)
+
+#define PORT_DATA_I_PU(nr) \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+		    PORT##nr##_IN, PORT##nr##_IN_PU)
+
+#define PORT_DATA_I_PU_PD(nr) \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+		    PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+#define PORT_DATA_O(nr) \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT)
+
+#define PORT_DATA_IO(nr) \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+		    PORT##nr##_IN)
+
+#define PORT_DATA_IO_PD(nr) \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+		    PORT##nr##_IN, PORT##nr##_IN_PD)
+
+#define PORT_DATA_IO_PU(nr) \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+		    PORT##nr##_IN, PORT##nr##_IN_PU)
+
+#define PORT_DATA_IO_PU_PD(nr) \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+		    PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+
+static pinmux_enum_t pinmux_data[] = {
+
+	/* specify valid pin states for each pin in GPIO mode */
+
+	/* 49-1 (GPIO) */
+	PORT_DATA_I_PD(0),
+	PORT_DATA_I_PU(1), PORT_DATA_I_PU(2), PORT_DATA_I_PU(3),
+	PORT_DATA_I_PU(4), PORT_DATA_I_PU(5), PORT_DATA_I_PU(6),
+	PORT_DATA_I_PU(7), PORT_DATA_I_PU(8), PORT_DATA_I_PU(9),
+	PORT_DATA_I_PU(10), PORT_DATA_I_PU(11), PORT_DATA_I_PU(12),
+	PORT_DATA_I_PU(13),
+	PORT_DATA_IO_PU_PD(14), PORT_DATA_IO_PU_PD(15),
+	PORT_DATA_O(16), PORT_DATA_O(17), PORT_DATA_O(18), PORT_DATA_O(19),
+	PORT_DATA_O(20), PORT_DATA_O(21), PORT_DATA_O(22), PORT_DATA_O(23),
+	PORT_DATA_O(24), PORT_DATA_O(25), PORT_DATA_O(26),
+	PORT_DATA_I_PD(27), PORT_DATA_I_PD(28),
+	PORT_DATA_O(29), PORT_DATA_O(30), PORT_DATA_O(31), PORT_DATA_O(32),
+	PORT_DATA_IO_PU(33),
+	PORT_DATA_O(34),
+	PORT_DATA_I_PU(35),
+	PORT_DATA_O(36),
+	PORT_DATA_I_PU_PD(37),
+
+	/* 49-2 (GPIO) */
+	PORT_DATA_IO_PU_PD(38),
+	PORT_DATA_IO_PD(39), PORT_DATA_IO_PD(40), PORT_DATA_IO_PD(41),
+	PORT_DATA_O(42), PORT_DATA_O(43), PORT_DATA_O(44), PORT_DATA_O(45),
+	PORT_DATA_O(46), PORT_DATA_O(47),
+	PORT_DATA_I_PU_PD(48), PORT_DATA_I_PU_PD(49), PORT_DATA_I_PU_PD(50),
+	PORT_DATA_IO_PD(51), PORT_DATA_IO_PD(52),
+	PORT_DATA_O(53),
+	PORT_DATA_IO_PD(54),
+	PORT_DATA_I_PU_PD(55),
+	PORT_DATA_IO_PU_PD(56),
+	PORT_DATA_I_PU_PD(57),
+	PORT_DATA_IO_PU_PD(58),
+	PORT_DATA_O(59), PORT_DATA_O(60), PORT_DATA_O(61), PORT_DATA_O(62),
+	PORT_DATA_O(63),
+	PORT_DATA_I_PU(64),
+	PORT_DATA_O(65), PORT_DATA_O(66), PORT_DATA_O(67), PORT_DATA_O(68),
+	PORT_DATA_IO_PD(69), PORT_DATA_IO_PD(70),
+	PORT_DATA_I_PD(71), PORT_DATA_I_PD(72), PORT_DATA_I_PD(73),
+	PORT_DATA_I_PD(74),
+	PORT_DATA_IO_PU_PD(75), PORT_DATA_IO_PU_PD(76),
+	PORT_DATA_IO_PD(77), PORT_DATA_IO_PD(78),
+	PORT_DATA_O(79),
+	PORT_DATA_IO_PD(80), PORT_DATA_IO_PD(81), PORT_DATA_IO_PD(82),
+	PORT_DATA_IO_PU_PD(83), PORT_DATA_IO_PU_PD(84),
+	PORT_DATA_IO_PU_PD(85), PORT_DATA_IO_PU_PD(86),
+	PORT_DATA_I_PD(87),
+	PORT_DATA_IO_PU_PD(88),
+	PORT_DATA_I_PU_PD(89), PORT_DATA_I_PU_PD(90),
+
+	/* 49-3 (GPIO) */
+	PORT_DATA_O(91), PORT_DATA_O(92), PORT_DATA_O(93), PORT_DATA_O(94),
+	PORT_DATA_I_PU_PD(95),
+	PORT_DATA_IO_PU_PD(96), PORT_DATA_IO_PU_PD(97), PORT_DATA_IO_PU_PD(98),
+	PORT_DATA_IO_PU_PD(99),	PORT_DATA_IO_PU_PD(100),
+	PORT_DATA_IO(101), PORT_DATA_IO(102), PORT_DATA_IO(103),
+	PORT_DATA_IO_PD(104), PORT_DATA_IO_PD(105), PORT_DATA_IO_PD(106),
+	PORT_DATA_IO_PD(107),
+	PORT_DATA_IO_PU_PD(108), PORT_DATA_IO_PU_PD(109),
+	PORT_DATA_IO_PU_PD(110), PORT_DATA_IO_PU_PD(111),
+	PORT_DATA_IO_PU_PD(112), PORT_DATA_IO_PU_PD(113),
+	PORT_DATA_IO_PU_PD(114),
+	PORT_DATA_IO_PU(115), PORT_DATA_IO_PU(116), PORT_DATA_IO_PU(117),
+	PORT_DATA_IO_PU(118), PORT_DATA_IO_PU(119), PORT_DATA_IO_PU(120),
+	PORT_DATA_IO_PU(121), PORT_DATA_IO_PU(122), PORT_DATA_IO_PU(123),
+	PORT_DATA_IO_PU(124), PORT_DATA_IO_PU(125), PORT_DATA_IO_PU(126),
+	PORT_DATA_IO_PU(127), PORT_DATA_IO_PU(128), PORT_DATA_IO_PU(129),
+	PORT_DATA_IO_PU(130),
+	PORT_DATA_O(131), PORT_DATA_O(132), PORT_DATA_O(133),
+	PORT_DATA_IO_PU(134),
+	PORT_DATA_O(135), PORT_DATA_O(136),
+	PORT_DATA_I_PU_PD(137),
+	PORT_DATA_IO(138),
+	PORT_DATA_IO_PU_PD(139),
+	PORT_DATA_IO(140), PORT_DATA_IO(141),
+	PORT_DATA_I_PU(142),
+	PORT_DATA_O(143), PORT_DATA_O(144),
+	PORT_DATA_I_PU(145),
+
+	/* 49-4 (GPIO) */
+	PORT_DATA_O(146),
+	PORT_DATA_I_PU_PD(147),
+	PORT_DATA_I_PD(148), PORT_DATA_I_PD(149),
+	PORT_DATA_IO_PD(150), PORT_DATA_IO_PD(151), PORT_DATA_IO_PD(152),
+	PORT_DATA_IO_PD(153), PORT_DATA_IO_PD(154), PORT_DATA_IO_PD(155),
+	PORT_DATA_IO_PD(156), PORT_DATA_IO_PD(157), PORT_DATA_IO_PD(158),
+	PORT_DATA_IO_PD(159), PORT_DATA_IO_PD(160), PORT_DATA_IO_PD(161),
+	PORT_DATA_IO_PD(162), PORT_DATA_IO_PD(163), PORT_DATA_IO_PD(164),
+	PORT_DATA_IO_PD(165), PORT_DATA_IO_PD(166),
+	PORT_DATA_IO_PU_PD(167),
+	PORT_DATA_O(168),
+	PORT_DATA_I_PD(169), PORT_DATA_I_PD(170),
+	PORT_DATA_O(171),
+	PORT_DATA_IO_PD(172), PORT_DATA_IO_PD(173),
+	PORT_DATA_O(174),
+	PORT_DATA_IO_PD(175), PORT_DATA_IO_PD(176), PORT_DATA_IO_PD(177),
+	PORT_DATA_IO_PD(178), PORT_DATA_IO_PD(179), PORT_DATA_IO_PD(180),
+	PORT_DATA_IO_PD(181), PORT_DATA_IO_PD(182), PORT_DATA_IO_PD(183),
+	PORT_DATA_IO_PD(184), PORT_DATA_IO_PD(185), PORT_DATA_IO_PD(186),
+	PORT_DATA_IO_PD(187), PORT_DATA_IO_PD(188), PORT_DATA_IO_PD(189),
+	PORT_DATA_IO_PD(190), PORT_DATA_IO_PD(191), PORT_DATA_IO_PD(192),
+	PORT_DATA_IO_PD(193), PORT_DATA_IO_PD(194), PORT_DATA_IO_PD(195),
+	PORT_DATA_IO_PD(196), PORT_DATA_IO_PD(197), PORT_DATA_IO_PD(198),
+	PORT_DATA_O(199),
+	PORT_DATA_IO_PD(200),
+
+	/* 49-5 (GPIO) */
+	PORT_DATA_O(201),
+	PORT_DATA_IO_PD(202), PORT_DATA_IO_PD(203),
+	PORT_DATA_I(204),
+	PORT_DATA_O(205),
+	PORT_DATA_IO_PD(206), PORT_DATA_IO_PD(207), PORT_DATA_IO_PD(208),
+	PORT_DATA_IO_PD(209), PORT_DATA_IO_PD(210), PORT_DATA_IO_PD(211),
+	PORT_DATA_IO_PD(212), PORT_DATA_IO_PD(213), PORT_DATA_IO_PD(214),
+	PORT_DATA_IO_PD(215), PORT_DATA_IO_PD(216),
+	PORT_DATA_O(217),
+	PORT_DATA_I_PU_PD(218), PORT_DATA_I_PU_PD(219),
+	PORT_DATA_O(220), PORT_DATA_O(221), PORT_DATA_O(222),
+	PORT_DATA_I_PD(223),
+	PORT_DATA_I_PU_PD(224),
+	PORT_DATA_O(225),
+	PORT_DATA_IO_PD(226),
+	PORT_DATA_IO_PU_PD(227),
+	PORT_DATA_I_PD(228),
+	PORT_DATA_IO_PD(229), PORT_DATA_IO_PD(230),
+	PORT_DATA_I_PU_PD(231), PORT_DATA_I_PU_PD(232),
+	PORT_DATA_IO_PU_PD(233), PORT_DATA_IO_PU_PD(234),
+	PORT_DATA_I_PU_PD(235),
+	PORT_DATA_O(236),
+	PORT_DATA_I_PD(237),
+	PORT_DATA_IO_PU_PD(238), PORT_DATA_IO_PU_PD(239),
+	PORT_DATA_IO_PD(240), PORT_DATA_IO_PD(241),
+	PORT_DATA_IO_PD(242), PORT_DATA_IO_PD(243),
+	PORT_DATA_O(244),
+	PORT_DATA_IO_PU_PD(245),
+	PORT_DATA_O(246),
+	PORT_DATA_I_PD(247),
+	PORT_DATA_IO_PU_PD(248),
+	PORT_DATA_I_PU_PD(249),
+	PORT_DATA_IO_PD(250), PORT_DATA_IO_PD(251),
+	PORT_DATA_IO_PU_PD(252), PORT_DATA_IO_PU_PD(253),
+	PORT_DATA_IO_PU_PD(254), PORT_DATA_IO_PU_PD(255),
+	PORT_DATA_IO_PU_PD(256),
+
+	/* 49-6 (GPIO) */
+	PORT_DATA_IO_PU_PD(257), PORT_DATA_IO_PU_PD(258),
+	PORT_DATA_IO_PD(259),
+	PORT_DATA_IO_PU(260), PORT_DATA_IO_PU(261), PORT_DATA_IO_PU(262),
+	PORT_DATA_IO_PU(263), PORT_DATA_IO_PU(264),
+	PORT_DATA_O(265),
+	PORT_DATA_IO_PU(266), PORT_DATA_IO_PU(267), PORT_DATA_IO_PU(268),
+	PORT_DATA_IO_PU(269), PORT_DATA_IO_PU(270),
+	PORT_DATA_O(271),
+	PORT_DATA_I_PD(272),
+
+	/* Special Pull-up / Pull-down Functions */
+	PINMUX_DATA(PORT48_KEYIN0_PU_MARK, MSELBCR_MSEL2_1,
+		    PORT48_FN2, PORT48_IN_PU),
+	PINMUX_DATA(PORT49_KEYIN1_PU_MARK, MSELBCR_MSEL2_1,
+		    PORT49_FN2, PORT49_IN_PU),
+	PINMUX_DATA(PORT50_KEYIN2_PU_MARK, MSELBCR_MSEL2_1,
+		    PORT50_FN2, PORT50_IN_PU),
+	PINMUX_DATA(PORT55_KEYIN3_PU_MARK, MSELBCR_MSEL2_1,
+		    PORT55_FN2, PORT55_IN_PU),
+	PINMUX_DATA(PORT56_KEYIN4_PU_MARK, MSELBCR_MSEL2_1,
+		    PORT56_FN2, PORT56_IN_PU),
+	PINMUX_DATA(PORT57_KEYIN5_PU_MARK, MSELBCR_MSEL2_1,
+		    PORT57_FN2, PORT57_IN_PU),
+	PINMUX_DATA(PORT58_KEYIN6_PU_MARK, MSELBCR_MSEL2_1,
+		    PORT58_FN2, PORT58_IN_PU),
+
+	/* 49-1 (FN) */
+	PINMUX_DATA(VBUS0_MARK, PORT0_FN1),
+	PINMUX_DATA(CPORT0_MARK, PORT1_FN1),
+	PINMUX_DATA(CPORT1_MARK, PORT2_FN1),
+	PINMUX_DATA(CPORT2_MARK, PORT3_FN1),
+	PINMUX_DATA(CPORT3_MARK, PORT4_FN1),
+	PINMUX_DATA(CPORT4_MARK, PORT5_FN1),
+	PINMUX_DATA(CPORT5_MARK, PORT6_FN1),
+	PINMUX_DATA(CPORT6_MARK, PORT7_FN1),
+	PINMUX_DATA(CPORT7_MARK, PORT8_FN1),
+	PINMUX_DATA(CPORT8_MARK, PORT9_FN1),
+	PINMUX_DATA(CPORT9_MARK, PORT10_FN1),
+	PINMUX_DATA(CPORT10_MARK, PORT11_FN1),
+	PINMUX_DATA(CPORT11_MARK, PORT12_FN1),
+	PINMUX_DATA(SIN2_MARK, PORT12_FN2),
+	PINMUX_DATA(CPORT12_MARK, PORT13_FN1),
+	PINMUX_DATA(XCTS2_MARK, PORT13_FN2),
+	PINMUX_DATA(CPORT13_MARK, PORT14_FN1),
+	PINMUX_DATA(RFSPO4_MARK, PORT14_FN2),
+	PINMUX_DATA(CPORT14_MARK, PORT15_FN1),
+	PINMUX_DATA(RFSPO5_MARK, PORT15_FN2),
+	PINMUX_DATA(CPORT15_MARK, PORT16_FN1),
+	PINMUX_DATA(CPORT16_MARK, PORT17_FN1),
+	PINMUX_DATA(CPORT17_MARK, PORT18_FN1),
+	PINMUX_DATA(SOUT2_MARK, PORT18_FN2),
+	PINMUX_DATA(CPORT18_MARK, PORT19_FN1),
+	PINMUX_DATA(XRTS2_MARK, PORT19_FN1),
+	PINMUX_DATA(CPORT19_MARK, PORT20_FN1),
+	PINMUX_DATA(CPORT20_MARK, PORT21_FN1),
+	PINMUX_DATA(RFSPO6_MARK, PORT21_FN2),
+	PINMUX_DATA(CPORT21_MARK, PORT22_FN1),
+	PINMUX_DATA(STATUS0_MARK, PORT22_FN2),
+	PINMUX_DATA(CPORT22_MARK, PORT23_FN1),
+	PINMUX_DATA(STATUS1_MARK, PORT23_FN2),
+	PINMUX_DATA(CPORT23_MARK, PORT24_FN1),
+	PINMUX_DATA(STATUS2_MARK, PORT24_FN2),
+	PINMUX_DATA(RFSPO7_MARK, PORT24_FN3),
+	PINMUX_DATA(MPORT0_MARK, PORT25_FN1),
+	PINMUX_DATA(MPORT1_MARK, PORT26_FN1),
+	PINMUX_DATA(B_SYNLD1_MARK, PORT27_FN1),
+	PINMUX_DATA(B_SYNLD2_MARK, PORT28_FN1),
+	PINMUX_DATA(XMAINPS_MARK, PORT29_FN1),
+	PINMUX_DATA(XDIVPS_MARK, PORT30_FN1),
+	PINMUX_DATA(XIDRST_MARK, PORT31_FN1),
+	PINMUX_DATA(IDCLK_MARK, PORT32_FN1),
+	PINMUX_DATA(IDIO_MARK, PORT33_FN1),
+	PINMUX_DATA(SOUT1_MARK, PORT34_FN1),
+	PINMUX_DATA(SCIFA4_TXD_MARK, PORT34_FN2),
+	PINMUX_DATA(M02_BERDAT_MARK, PORT34_FN3),
+	PINMUX_DATA(SIN1_MARK, PORT35_FN1),
+	PINMUX_DATA(SCIFA4_RXD_MARK, PORT35_FN2),
+	PINMUX_DATA(XWUP_MARK, PORT35_FN3),
+	PINMUX_DATA(XRTS1_MARK, PORT36_FN1),
+	PINMUX_DATA(SCIFA4_RTS_MARK, PORT36_FN2),
+	PINMUX_DATA(M03_BERCLK_MARK, PORT36_FN3),
+	PINMUX_DATA(XCTS1_MARK, PORT37_FN1),
+	PINMUX_DATA(SCIFA4_CTS_MARK, PORT37_FN2),
+
+	/* 49-2 (FN) */
+	PINMUX_DATA(HSU_IQ_AGC6_MARK, PORT38_FN1),
+	PINMUX_DATA(MFG2_IN2_MARK, PORT38_FN2),
+	PINMUX_DATA(MSIOF2_MCK0_MARK, PORT38_FN3),
+	PINMUX_DATA(HSU_IQ_AGC5_MARK, PORT39_FN1),
+	PINMUX_DATA(MFG2_IN1_MARK, PORT39_FN2),
+	PINMUX_DATA(MSIOF2_MCK1_MARK, PORT39_FN3),
+	PINMUX_DATA(HSU_IQ_AGC4_MARK, PORT40_FN1),
+	PINMUX_DATA(MSIOF2_RSYNC_MARK, PORT40_FN3),
+	PINMUX_DATA(HSU_IQ_AGC3_MARK, PORT41_FN1),
+	PINMUX_DATA(MFG2_OUT1_MARK, PORT41_FN2),
+	PINMUX_DATA(MSIOF2_RSCK_MARK, PORT41_FN3),
+	PINMUX_DATA(HSU_IQ_AGC2_MARK, PORT42_FN1),
+	PINMUX_DATA(PORT42_KEYOUT0_MARK, MSELBCR_MSEL2_1, PORT42_FN2),
+	PINMUX_DATA(HSU_IQ_AGC1_MARK, PORT43_FN1),
+	PINMUX_DATA(PORT43_KEYOUT1_MARK, MSELBCR_MSEL2_1, PORT43_FN2),
+	PINMUX_DATA(HSU_IQ_AGC0_MARK, PORT44_FN1),
+	PINMUX_DATA(PORT44_KEYOUT2_MARK, MSELBCR_MSEL2_1, PORT44_FN2),
+	PINMUX_DATA(HSU_IQ_AGC_ST_MARK, PORT45_FN1),
+	PINMUX_DATA(PORT45_KEYOUT3_MARK, MSELBCR_MSEL2_1, PORT45_FN2),
+	PINMUX_DATA(HSU_IQ_PDO_MARK, PORT46_FN1),
+	PINMUX_DATA(PORT46_KEYOUT4_MARK, MSELBCR_MSEL2_1, PORT46_FN2),
+	PINMUX_DATA(HSU_IQ_PYO_MARK, PORT47_FN1),
+	PINMUX_DATA(PORT47_KEYOUT5_MARK, MSELBCR_MSEL2_1, PORT47_FN2),
+	PINMUX_DATA(HSU_EN_TXMUX_G3MO_MARK, PORT48_FN1),
+	PINMUX_DATA(PORT48_KEYIN0_MARK, MSELBCR_MSEL2_1, PORT48_FN2),
+	PINMUX_DATA(HSU_I_TXMUX_G3MO_MARK, PORT49_FN1),
+	PINMUX_DATA(PORT49_KEYIN1_MARK, MSELBCR_MSEL2_1, PORT49_FN2),
+	PINMUX_DATA(HSU_Q_TXMUX_G3MO_MARK, PORT50_FN1),
+	PINMUX_DATA(PORT50_KEYIN2_MARK, MSELBCR_MSEL2_1, PORT50_FN2),
+	PINMUX_DATA(HSU_SYO_MARK, PORT51_FN1),
+	PINMUX_DATA(PORT51_MSIOF2_TSYNC_MARK, PORT51_FN2),
+	PINMUX_DATA(HSU_SDO_MARK, PORT52_FN1),
+	PINMUX_DATA(PORT52_MSIOF2_TSCK_MARK, PORT52_FN2),
+	PINMUX_DATA(HSU_TGTTI_G3MO_MARK, PORT53_FN1),
+	PINMUX_DATA(PORT53_MSIOF2_TXD_MARK, PORT53_FN2),
+	PINMUX_DATA(B_TIME_STAMP_MARK, PORT54_FN1),
+	PINMUX_DATA(PORT54_MSIOF2_RXD_MARK, PORT54_FN2),
+	PINMUX_DATA(HSU_SDI_MARK, PORT55_FN1),
+	PINMUX_DATA(PORT55_KEYIN3_MARK, MSELBCR_MSEL2_1, PORT55_FN2),
+	PINMUX_DATA(HSU_SCO_MARK, PORT56_FN1),
+	PINMUX_DATA(PORT56_KEYIN4_MARK, MSELBCR_MSEL2_1, PORT56_FN2),
+	PINMUX_DATA(HSU_DREQ_MARK, PORT57_FN1),
+	PINMUX_DATA(PORT57_KEYIN5_MARK, MSELBCR_MSEL2_1, PORT57_FN2),
+	PINMUX_DATA(HSU_DACK_MARK, PORT58_FN1),
+	PINMUX_DATA(PORT58_KEYIN6_MARK, MSELBCR_MSEL2_1, PORT58_FN2),
+	PINMUX_DATA(HSU_CLK61M_MARK, PORT59_FN1),
+	PINMUX_DATA(PORT59_MSIOF2_SS1_MARK, PORT59_FN2),
+	PINMUX_DATA(HSU_XRST_MARK, PORT60_FN1),
+	PINMUX_DATA(PORT60_MSIOF2_SS2_MARK, PORT60_FN2),
+	PINMUX_DATA(PCMCLKO_MARK, PORT61_FN1),
+	PINMUX_DATA(SYNC8KO_MARK, PORT62_FN1),
+	PINMUX_DATA(DNPCM_A_MARK, PORT63_FN1),
+	PINMUX_DATA(UPPCM_A_MARK, PORT64_FN1),
+	PINMUX_DATA(XTALB1L_MARK, PORT65_FN1),
+	PINMUX_DATA(GPS_AGC1_MARK, PORT66_FN1),
+	PINMUX_DATA(SCIFA0_RTS_MARK, PORT66_FN2),
+	PINMUX_DATA(GPS_AGC2_MARK, PORT67_FN1),
+	PINMUX_DATA(SCIFA0_SCK_MARK, PORT67_FN2),
+	PINMUX_DATA(GPS_AGC3_MARK, PORT68_FN1),
+	PINMUX_DATA(SCIFA0_TXD_MARK, PORT68_FN2),
+	PINMUX_DATA(GPS_AGC4_MARK, PORT69_FN1),
+	PINMUX_DATA(SCIFA0_RXD_MARK, PORT69_FN2),
+	PINMUX_DATA(GPS_PWRD_MARK, PORT70_FN1),
+	PINMUX_DATA(SCIFA0_CTS_MARK, PORT70_FN2),
+	PINMUX_DATA(GPS_IM_MARK, PORT71_FN1),
+	PINMUX_DATA(GPS_IS_MARK, PORT72_FN1),
+	PINMUX_DATA(GPS_QM_MARK, PORT73_FN1),
+	PINMUX_DATA(GPS_QS_MARK, PORT74_FN1),
+	PINMUX_DATA(SIUBOMC_MARK, PORT75_FN1),
+	PINMUX_DATA(TPU2TO0_MARK, PORT75_FN3),
+	PINMUX_DATA(SIUCKB_MARK, PORT76_FN1),
+	PINMUX_DATA(TPU2TO1_MARK, PORT76_FN3),
+	PINMUX_DATA(SIUBOLR_MARK, PORT77_FN1),
+	PINMUX_DATA(BBIF2_TSYNC_MARK, PORT77_FN2),
+	PINMUX_DATA(TPU2TO2_MARK, PORT77_FN3),
+	PINMUX_DATA(SIUBOBT_MARK, PORT78_FN1),
+	PINMUX_DATA(BBIF2_TSCK_MARK, PORT78_FN2),
+	PINMUX_DATA(TPU2TO3_MARK, PORT78_FN3),
+	PINMUX_DATA(SIUBOSLD_MARK, PORT79_FN1),
+	PINMUX_DATA(BBIF2_TXD_MARK, PORT79_FN2),
+	PINMUX_DATA(TPU3TO0_MARK, PORT79_FN3),
+	PINMUX_DATA(SIUBILR_MARK, PORT80_FN1),
+	PINMUX_DATA(TPU3TO1_MARK, PORT80_FN3),
+	PINMUX_DATA(SIUBIBT_MARK, PORT81_FN1),
+	PINMUX_DATA(TPU3TO2_MARK, PORT81_FN3),
+	PINMUX_DATA(SIUBISLD_MARK, PORT82_FN1),
+	PINMUX_DATA(TPU3TO3_MARK, PORT82_FN3),
+	PINMUX_DATA(NMI_MARK, PORT83_FN1),
+	PINMUX_DATA(TPU4TO0_MARK, PORT83_FN3),
+	PINMUX_DATA(DNPCM_M_MARK, PORT84_FN1),
+	PINMUX_DATA(TPU4TO1_MARK, PORT84_FN3),
+	PINMUX_DATA(TPU4TO2_MARK, PORT85_FN3),
+	PINMUX_DATA(TPU4TO3_MARK, PORT86_FN3),
+	PINMUX_DATA(IRQ_TMPB_MARK, PORT87_FN1),
+	PINMUX_DATA(PWEN_MARK, PORT88_FN1),
+	PINMUX_DATA(MFG1_OUT1_MARK, PORT88_FN2),
+	PINMUX_DATA(OVCN_MARK, PORT89_FN1),
+	PINMUX_DATA(MFG1_IN1_MARK, PORT89_FN2),
+	PINMUX_DATA(OVCN2_MARK, PORT90_FN1),
+	PINMUX_DATA(MFG1_IN2_MARK, PORT90_FN2),
+
+	/* 49-3 (FN) */
+	PINMUX_DATA(RFSPO1_MARK, PORT91_FN1),
+	PINMUX_DATA(RFSPO2_MARK, PORT92_FN1),
+	PINMUX_DATA(RFSPO3_MARK, PORT93_FN1),
+	PINMUX_DATA(PORT93_VIO_CKO2_MARK, PORT93_FN2),
+	PINMUX_DATA(USBTERM_MARK, PORT94_FN1),
+	PINMUX_DATA(EXTLP_MARK, PORT94_FN2),
+	PINMUX_DATA(IDIN_MARK, PORT95_FN1),
+	PINMUX_DATA(SCIFA5_CTS_MARK, PORT96_FN1),
+	PINMUX_DATA(MFG0_IN1_MARK, PORT96_FN2),
+	PINMUX_DATA(SCIFA5_RTS_MARK, PORT97_FN1),
+	PINMUX_DATA(MFG0_IN2_MARK, PORT97_FN2),
+	PINMUX_DATA(SCIFA5_RXD_MARK, PORT98_FN1),
+	PINMUX_DATA(SCIFA5_TXD_MARK, PORT99_FN1),
+	PINMUX_DATA(SCIFA5_SCK_MARK, PORT100_FN1),
+	PINMUX_DATA(MFG0_OUT1_MARK, PORT100_FN2),
+	PINMUX_DATA(A0_EA0_MARK, PORT101_FN1),
+	PINMUX_DATA(BS_MARK, PORT101_FN2),
+	PINMUX_DATA(A14_EA14_MARK, PORT102_FN1),
+	PINMUX_DATA(PORT102_KEYOUT0_MARK, MSELBCR_MSEL2_0, PORT102_FN2),
+	PINMUX_DATA(A15_EA15_MARK, PORT103_FN1),
+	PINMUX_DATA(PORT103_KEYOUT1_MARK, MSELBCR_MSEL2_0, PORT103_FN2),
+	PINMUX_DATA(DV_CLKOL_MARK, PORT103_FN3),
+	PINMUX_DATA(A16_EA16_MARK, PORT104_FN1),
+	PINMUX_DATA(PORT104_KEYOUT2_MARK, MSELBCR_MSEL2_0, PORT104_FN2),
+	PINMUX_DATA(DV_VSYNCL_MARK, PORT104_FN3),
+	PINMUX_DATA(MSIOF0_SS1_MARK, PORT104_FN4),
+	PINMUX_DATA(A17_EA17_MARK, PORT105_FN1),
+	PINMUX_DATA(PORT105_KEYOUT3_MARK, MSELBCR_MSEL2_0, PORT105_FN2),
+	PINMUX_DATA(DV_HSYNCL_MARK, PORT105_FN3),
+	PINMUX_DATA(MSIOF0_TSYNC_MARK, PORT105_FN4),
+	PINMUX_DATA(A18_EA18_MARK, PORT106_FN1),
+	PINMUX_DATA(PORT106_KEYOUT4_MARK, MSELBCR_MSEL2_0, PORT106_FN2),
+	PINMUX_DATA(DV_DL0_MARK, PORT106_FN3),
+	PINMUX_DATA(MSIOF0_TSCK_MARK, PORT106_FN4),
+	PINMUX_DATA(A19_EA19_MARK, PORT107_FN1),
+	PINMUX_DATA(PORT107_KEYOUT5_MARK, MSELBCR_MSEL2_0, PORT107_FN2),
+	PINMUX_DATA(DV_DL1_MARK, PORT107_FN3),
+	PINMUX_DATA(MSIOF0_TXD_MARK, PORT107_FN4),
+	PINMUX_DATA(A20_EA20_MARK, PORT108_FN1),
+	PINMUX_DATA(PORT108_KEYIN0_MARK, MSELBCR_MSEL2_0, PORT108_FN2),
+	PINMUX_DATA(DV_DL2_MARK, PORT108_FN3),
+	PINMUX_DATA(MSIOF0_RSCK_MARK, PORT108_FN4),
+	PINMUX_DATA(A21_EA21_MARK, PORT109_FN1),
+	PINMUX_DATA(PORT109_KEYIN1_MARK, MSELBCR_MSEL2_0, PORT109_FN2),
+	PINMUX_DATA(DV_DL3_MARK, PORT109_FN3),
+	PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT109_FN4),
+	PINMUX_DATA(A22_EA22_MARK, PORT110_FN1),
+	PINMUX_DATA(PORT110_KEYIN2_MARK, MSELBCR_MSEL2_0, PORT110_FN2),
+	PINMUX_DATA(DV_DL4_MARK, PORT110_FN3),
+	PINMUX_DATA(MSIOF0_MCK0_MARK, PORT110_FN4),
+	PINMUX_DATA(A23_EA23_MARK, PORT111_FN1),
+	PINMUX_DATA(PORT111_KEYIN3_MARK, MSELBCR_MSEL2_0, PORT111_FN2),
+	PINMUX_DATA(DV_DL5_MARK, PORT111_FN3),
+	PINMUX_DATA(MSIOF0_MCK1_MARK, PORT111_FN4),
+	PINMUX_DATA(A24_EA24_MARK, PORT112_FN1),
+	PINMUX_DATA(PORT112_KEYIN4_MARK, MSELBCR_MSEL2_0, PORT112_FN2),
+	PINMUX_DATA(DV_DL6_MARK, PORT112_FN3),
+	PINMUX_DATA(MSIOF0_RXD_MARK, PORT112_FN4),
+	PINMUX_DATA(A25_EA25_MARK, PORT113_FN1),
+	PINMUX_DATA(PORT113_KEYIN5_MARK, MSELBCR_MSEL2_0, PORT113_FN2),
+	PINMUX_DATA(DV_DL7_MARK, PORT113_FN3),
+	PINMUX_DATA(MSIOF0_SS2_MARK, PORT113_FN4),
+	PINMUX_DATA(A26_MARK, PORT114_FN1),
+	PINMUX_DATA(PORT113_KEYIN6_MARK, MSELBCR_MSEL2_0, PORT114_FN2),
+	PINMUX_DATA(DV_CLKIL_MARK, PORT114_FN3),
+	PINMUX_DATA(D0_ED0_NAF0_MARK, PORT115_FN1),
+	PINMUX_DATA(D1_ED1_NAF1_MARK, PORT116_FN1),
+	PINMUX_DATA(D2_ED2_NAF2_MARK, PORT117_FN1),
+	PINMUX_DATA(D3_ED3_NAF3_MARK, PORT118_FN1),
+	PINMUX_DATA(D4_ED4_NAF4_MARK, PORT119_FN1),
+	PINMUX_DATA(D5_ED5_NAF5_MARK, PORT120_FN1),
+	PINMUX_DATA(D6_ED6_NAF6_MARK, PORT121_FN1),
+	PINMUX_DATA(D7_ED7_NAF7_MARK, PORT122_FN1),
+	PINMUX_DATA(D8_ED8_NAF8_MARK, PORT123_FN1),
+	PINMUX_DATA(D9_ED9_NAF9_MARK, PORT124_FN1),
+	PINMUX_DATA(D10_ED10_NAF10_MARK, PORT125_FN1),
+	PINMUX_DATA(D11_ED11_NAF11_MARK, PORT126_FN1),
+	PINMUX_DATA(D12_ED12_NAF12_MARK, PORT127_FN1),
+	PINMUX_DATA(D13_ED13_NAF13_MARK, PORT128_FN1),
+	PINMUX_DATA(D14_ED14_NAF14_MARK, PORT129_FN1),
+	PINMUX_DATA(D15_ED15_NAF15_MARK, PORT130_FN1),
+	PINMUX_DATA(CS4_MARK, PORT131_FN1),
+	PINMUX_DATA(CS5A_MARK, PORT132_FN1),
+	PINMUX_DATA(CS5B_MARK, PORT133_FN1),
+	PINMUX_DATA(FCE1_MARK, PORT133_FN2),
+	PINMUX_DATA(CS6B_MARK, PORT134_FN1),
+	PINMUX_DATA(XCS2_MARK, PORT134_FN2),
+	PINMUX_DATA(FCE0_MARK, PORT135_FN1),
+	PINMUX_DATA(CS6A_MARK, PORT136_FN1),
+	PINMUX_DATA(DACK0_MARK, PORT136_FN2),
+	PINMUX_DATA(WAIT_MARK, PORT137_FN1),
+	PINMUX_DATA(DREQ0_MARK, PORT137_FN2),
+	PINMUX_DATA(RD_XRD_MARK, PORT138_FN1),
+	PINMUX_DATA(A27_MARK, PORT139_FN1),
+	PINMUX_DATA(RDWR_XWE_MARK, PORT139_FN2),
+	PINMUX_DATA(WE0_XWR0_FWE_MARK, PORT140_FN1),
+	PINMUX_DATA(WE1_XWR1_MARK, PORT141_FN1),
+	PINMUX_DATA(FRB_MARK, PORT142_FN1),
+	PINMUX_DATA(CKO_MARK, PORT143_FN1),
+	PINMUX_DATA(NBRSTOUT_MARK, PORT144_FN1),
+	PINMUX_DATA(NBRST_MARK, PORT145_FN1),
+
+	/* 49-4 (FN) */
+	PINMUX_DATA(RFSPO0_MARK, PORT146_FN1),
+	PINMUX_DATA(PORT146_VIO_CKO2_MARK, PORT146_FN2),
+	PINMUX_DATA(TSTMD_MARK, PORT147_FN1),
+	PINMUX_DATA(VIO_VD_MARK, PORT148_FN1),
+	PINMUX_DATA(VIO_HD_MARK, PORT149_FN1),
+	PINMUX_DATA(VIO_D0_MARK, PORT150_FN1),
+	PINMUX_DATA(VIO_D1_MARK, PORT151_FN1),
+	PINMUX_DATA(VIO_D2_MARK, PORT152_FN1),
+	PINMUX_DATA(VIO_D3_MARK, PORT153_FN1),
+	PINMUX_DATA(VIO_D4_MARK, PORT154_FN1),
+	PINMUX_DATA(VIO_D5_MARK, PORT155_FN1),
+	PINMUX_DATA(VIO_D6_MARK, PORT156_FN1),
+	PINMUX_DATA(VIO_D7_MARK, PORT157_FN1),
+	PINMUX_DATA(VIO_D8_MARK, PORT158_FN1),
+	PINMUX_DATA(VIO_D9_MARK, PORT159_FN1),
+	PINMUX_DATA(VIO_D10_MARK, PORT160_FN1),
+	PINMUX_DATA(VIO_D11_MARK, PORT161_FN1),
+	PINMUX_DATA(VIO_D12_MARK, PORT162_FN1),
+	PINMUX_DATA(VIO_D13_MARK, PORT163_FN1),
+	PINMUX_DATA(VIO_D14_MARK, PORT164_FN1),
+	PINMUX_DATA(VIO_D15_MARK, PORT165_FN1),
+	PINMUX_DATA(VIO_CLK_MARK, PORT166_FN1),
+	PINMUX_DATA(VIO_FIELD_MARK, PORT167_FN1),
+	PINMUX_DATA(VIO_CKO_MARK, PORT168_FN1),
+	PINMUX_DATA(MFG3_IN1_MARK, PORT169_FN2),
+	PINMUX_DATA(MFG3_IN2_MARK, PORT170_FN2),
+	PINMUX_DATA(M9_SLCD_A01_MARK, PORT171_FN1),
+	PINMUX_DATA(MFG3_OUT1_MARK, PORT171_FN2),
+	PINMUX_DATA(TPU0TO0_MARK, PORT171_FN3),
+	PINMUX_DATA(M10_SLCD_CK1_MARK, PORT172_FN1),
+	PINMUX_DATA(MFG4_IN1_MARK, PORT172_FN2),
+	PINMUX_DATA(TPU0TO1_MARK, PORT172_FN3),
+	PINMUX_DATA(M11_SLCD_SO1_MARK, PORT173_FN1),
+	PINMUX_DATA(MFG4_IN2_MARK, PORT173_FN2),
+	PINMUX_DATA(TPU0TO2_MARK, PORT173_FN3),
+	PINMUX_DATA(M12_SLCD_CE1_MARK, PORT174_FN1),
+	PINMUX_DATA(MFG4_OUT1_MARK, PORT174_FN2),
+	PINMUX_DATA(TPU0TO3_MARK, PORT174_FN3),
+	PINMUX_DATA(LCDD0_MARK, PORT175_FN1),
+	PINMUX_DATA(PORT175_KEYOUT0_MARK, PORT175_FN2),
+	PINMUX_DATA(DV_D0_MARK, PORT175_FN3),
+	PINMUX_DATA(SIUCKA_MARK, PORT175_FN4),
+	PINMUX_DATA(MFG0_OUT2_MARK, PORT175_FN5),
+	PINMUX_DATA(LCDD1_MARK, PORT176_FN1),
+	PINMUX_DATA(PORT176_KEYOUT1_MARK, PORT176_FN2),
+	PINMUX_DATA(DV_D1_MARK, PORT176_FN3),
+	PINMUX_DATA(SIUAOLR_MARK, PORT176_FN4),
+	PINMUX_DATA(BBIF2_TSYNC1_MARK, PORT176_FN5),
+	PINMUX_DATA(LCDD2_MARK, PORT177_FN1),
+	PINMUX_DATA(PORT177_KEYOUT2_MARK, PORT177_FN2),
+	PINMUX_DATA(DV_D2_MARK, PORT177_FN3),
+	PINMUX_DATA(SIUAOBT_MARK, PORT177_FN4),
+	PINMUX_DATA(BBIF2_TSCK1_MARK, PORT177_FN5),
+	PINMUX_DATA(LCDD3_MARK, PORT178_FN1),
+	PINMUX_DATA(PORT178_KEYOUT3_MARK, PORT178_FN2),
+	PINMUX_DATA(DV_D3_MARK, PORT178_FN3),
+	PINMUX_DATA(SIUAOSLD_MARK, PORT178_FN4),
+	PINMUX_DATA(BBIF2_TXD1_MARK, PORT178_FN5),
+	PINMUX_DATA(LCDD4_MARK, PORT179_FN1),
+	PINMUX_DATA(PORT179_KEYOUT4_MARK, PORT179_FN2),
+	PINMUX_DATA(DV_D4_MARK, PORT179_FN3),
+	PINMUX_DATA(SIUAISPD_MARK, PORT179_FN4),
+	PINMUX_DATA(MFG1_OUT2_MARK, PORT179_FN5),
+	PINMUX_DATA(LCDD5_MARK, PORT180_FN1),
+	PINMUX_DATA(PORT180_KEYOUT5_MARK, PORT180_FN2),
+	PINMUX_DATA(DV_D5_MARK, PORT180_FN3),
+	PINMUX_DATA(SIUAILR_MARK, PORT180_FN4),
+	PINMUX_DATA(MFG2_OUT2_MARK, PORT180_FN5),
+	PINMUX_DATA(LCDD6_MARK, PORT181_FN1),
+	PINMUX_DATA(DV_D6_MARK, PORT181_FN3),
+	PINMUX_DATA(SIUAIBT_MARK, PORT181_FN4),
+	PINMUX_DATA(MFG3_OUT2_MARK, PORT181_FN5),
+	PINMUX_DATA(XWR2_MARK, PORT181_FN7),
+	PINMUX_DATA(LCDD7_MARK, PORT182_FN1),
+	PINMUX_DATA(DV_D7_MARK, PORT182_FN3),
+	PINMUX_DATA(SIUAISLD_MARK, PORT182_FN4),
+	PINMUX_DATA(MFG4_OUT2_MARK, PORT182_FN5),
+	PINMUX_DATA(XWR3_MARK, PORT182_FN7),
+	PINMUX_DATA(LCDD8_MARK, PORT183_FN1),
+	PINMUX_DATA(DV_D8_MARK, PORT183_FN3),
+	PINMUX_DATA(D16_MARK, PORT183_FN6),
+	PINMUX_DATA(ED16_MARK, PORT183_FN7),
+	PINMUX_DATA(LCDD9_MARK, PORT184_FN1),
+	PINMUX_DATA(DV_D9_MARK, PORT184_FN3),
+	PINMUX_DATA(D17_MARK, PORT184_FN6),
+	PINMUX_DATA(ED17_MARK, PORT184_FN7),
+	PINMUX_DATA(LCDD10_MARK, PORT185_FN1),
+	PINMUX_DATA(DV_D10_MARK, PORT185_FN3),
+	PINMUX_DATA(D18_MARK, PORT185_FN6),
+	PINMUX_DATA(ED18_MARK, PORT185_FN7),
+	PINMUX_DATA(LCDD11_MARK, PORT186_FN1),
+	PINMUX_DATA(DV_D11_MARK, PORT186_FN3),
+	PINMUX_DATA(D19_MARK, PORT186_FN6),
+	PINMUX_DATA(ED19_MARK, PORT186_FN7),
+	PINMUX_DATA(LCDD12_MARK, PORT187_FN1),
+	PINMUX_DATA(DV_D12_MARK, PORT187_FN3),
+	PINMUX_DATA(D20_MARK, PORT187_FN6),
+	PINMUX_DATA(ED20_MARK, PORT187_FN7),
+	PINMUX_DATA(LCDD13_MARK, PORT188_FN1),
+	PINMUX_DATA(DV_D13_MARK, PORT188_FN3),
+	PINMUX_DATA(D21_MARK, PORT188_FN6),
+	PINMUX_DATA(ED21_MARK, PORT188_FN7),
+	PINMUX_DATA(LCDD14_MARK, PORT189_FN1),
+	PINMUX_DATA(DV_D14_MARK, PORT189_FN3),
+	PINMUX_DATA(D22_MARK, PORT189_FN6),
+	PINMUX_DATA(ED22_MARK, PORT189_FN7),
+	PINMUX_DATA(LCDD15_MARK, PORT190_FN1),
+	PINMUX_DATA(DV_D15_MARK, PORT190_FN3),
+	PINMUX_DATA(D23_MARK, PORT190_FN6),
+	PINMUX_DATA(ED23_MARK, PORT190_FN7),
+	PINMUX_DATA(LCDD16_MARK, PORT191_FN1),
+	PINMUX_DATA(DV_HSYNC_MARK, PORT191_FN3),
+	PINMUX_DATA(D24_MARK, PORT191_FN6),
+	PINMUX_DATA(ED24_MARK, PORT191_FN7),
+	PINMUX_DATA(LCDD17_MARK, PORT192_FN1),
+	PINMUX_DATA(DV_VSYNC_MARK, PORT192_FN3),
+	PINMUX_DATA(D25_MARK, PORT192_FN6),
+	PINMUX_DATA(ED25_MARK, PORT192_FN7),
+	PINMUX_DATA(LCDD18_MARK, PORT193_FN1),
+	PINMUX_DATA(DREQ2_MARK, PORT193_FN2),
+	PINMUX_DATA(MSIOF0L_TSCK_MARK, PORT193_FN5),
+	PINMUX_DATA(D26_MARK, PORT193_FN6),
+	PINMUX_DATA(ED26_MARK, PORT193_FN7),
+	PINMUX_DATA(LCDD19_MARK, PORT194_FN1),
+	PINMUX_DATA(MSIOF0L_TSYNC_MARK, PORT194_FN5),
+	PINMUX_DATA(D27_MARK, PORT194_FN6),
+	PINMUX_DATA(ED27_MARK, PORT194_FN7),
+	PINMUX_DATA(LCDD20_MARK, PORT195_FN1),
+	PINMUX_DATA(TS_SPSYNC1_MARK, PORT195_FN2),
+	PINMUX_DATA(MSIOF0L_MCK0_MARK, PORT195_FN5),
+	PINMUX_DATA(D28_MARK, PORT195_FN6),
+	PINMUX_DATA(ED28_MARK, PORT195_FN7),
+	PINMUX_DATA(LCDD21_MARK, PORT196_FN1),
+	PINMUX_DATA(TS_SDAT1_MARK, PORT196_FN2),
+	PINMUX_DATA(MSIOF0L_MCK1_MARK, PORT196_FN5),
+	PINMUX_DATA(D29_MARK, PORT196_FN6),
+	PINMUX_DATA(ED29_MARK, PORT196_FN7),
+	PINMUX_DATA(LCDD22_MARK, PORT197_FN1),
+	PINMUX_DATA(TS_SDEN1_MARK, PORT197_FN2),
+	PINMUX_DATA(MSIOF0L_SS1_MARK, PORT197_FN5),
+	PINMUX_DATA(D30_MARK, PORT197_FN6),
+	PINMUX_DATA(ED30_MARK, PORT197_FN7),
+	PINMUX_DATA(LCDD23_MARK, PORT198_FN1),
+	PINMUX_DATA(TS_SCK1_MARK, PORT198_FN2),
+	PINMUX_DATA(MSIOF0L_SS2_MARK, PORT198_FN5),
+	PINMUX_DATA(D31_MARK, PORT198_FN6),
+	PINMUX_DATA(ED31_MARK, PORT198_FN7),
+	PINMUX_DATA(LCDDCK_MARK, PORT199_FN1),
+	PINMUX_DATA(LCDWR_MARK, PORT199_FN2),
+	PINMUX_DATA(DV_CKO_MARK, PORT199_FN3),
+	PINMUX_DATA(SIUAOSPD_MARK, PORT199_FN4),
+	PINMUX_DATA(LCDRD_MARK, PORT200_FN1),
+	PINMUX_DATA(DACK2_MARK, PORT200_FN2),
+	PINMUX_DATA(MSIOF0L_RSYNC_MARK, PORT200_FN5),
+
+	/* 49-5 (FN) */
+	PINMUX_DATA(LCDHSYN_MARK, PORT201_FN1),
+	PINMUX_DATA(LCDCS_MARK, PORT201_FN2),
+	PINMUX_DATA(LCDCS2_MARK, PORT201_FN3),
+	PINMUX_DATA(DACK3_MARK, PORT201_FN4),
+	PINMUX_DATA(LCDDISP_MARK, PORT202_FN1),
+	PINMUX_DATA(LCDRS_MARK, PORT202_FN2),
+	PINMUX_DATA(DREQ3_MARK, PORT202_FN4),
+	PINMUX_DATA(MSIOF0L_RSCK_MARK, PORT202_FN5),
+	PINMUX_DATA(LCDCSYN_MARK, PORT203_FN1),
+	PINMUX_DATA(LCDCSYN2_MARK, PORT203_FN2),
+	PINMUX_DATA(DV_CKI_MARK, PORT203_FN3),
+	PINMUX_DATA(LCDLCLK_MARK, PORT204_FN1),
+	PINMUX_DATA(DREQ1_MARK, PORT204_FN3),
+	PINMUX_DATA(MSIOF0L_RXD_MARK, PORT204_FN5),
+	PINMUX_DATA(LCDDON_MARK, PORT205_FN1),
+	PINMUX_DATA(LCDDON2_MARK, PORT205_FN2),
+	PINMUX_DATA(DACK1_MARK, PORT205_FN3),
+	PINMUX_DATA(MSIOF0L_TXD_MARK, PORT205_FN5),
+	PINMUX_DATA(VIO_DR0_MARK, PORT206_FN1),
+	PINMUX_DATA(VIO_DR1_MARK, PORT207_FN1),
+	PINMUX_DATA(VIO_DR2_MARK, PORT208_FN1),
+	PINMUX_DATA(VIO_DR3_MARK, PORT209_FN1),
+	PINMUX_DATA(VIO_DR4_MARK, PORT210_FN1),
+	PINMUX_DATA(VIO_DR5_MARK, PORT211_FN1),
+	PINMUX_DATA(VIO_DR6_MARK, PORT212_FN1),
+	PINMUX_DATA(VIO_DR7_MARK, PORT213_FN1),
+	PINMUX_DATA(VIO_VDR_MARK, PORT214_FN1),
+	PINMUX_DATA(VIO_HDR_MARK, PORT215_FN1),
+	PINMUX_DATA(VIO_CLKR_MARK, PORT216_FN1),
+	PINMUX_DATA(VIO_CKOR_MARK, PORT217_FN1),
+	PINMUX_DATA(SCIFA1_TXD_MARK, PORT220_FN2),
+	PINMUX_DATA(GPS_PGFA0_MARK, PORT220_FN3),
+	PINMUX_DATA(SCIFA1_SCK_MARK, PORT221_FN2),
+	PINMUX_DATA(GPS_PGFA1_MARK, PORT221_FN3),
+	PINMUX_DATA(SCIFA1_RTS_MARK, PORT222_FN2),
+	PINMUX_DATA(GPS_EPPSINMON_MARK, PORT222_FN3),
+	PINMUX_DATA(SCIFA1_RXD_MARK, PORT223_FN2),
+	PINMUX_DATA(SCIFA1_CTS_MARK, PORT224_FN2),
+	PINMUX_DATA(MSIOF1_TXD_MARK, PORT225_FN1),
+	PINMUX_DATA(SCIFA1_TXD2_MARK, PORT225_FN2),
+	PINMUX_DATA(GPS_TXD_MARK, PORT225_FN3),
+	PINMUX_DATA(MSIOF1_TSYNC_MARK, PORT226_FN1),
+	PINMUX_DATA(SCIFA1_CTS2_MARK, PORT226_FN2),
+	PINMUX_DATA(I2C_SDA2_MARK, PORT226_FN3),
+	PINMUX_DATA(MSIOF1_TSCK_MARK, PORT227_FN1),
+	PINMUX_DATA(SCIFA1_SCK2_MARK, PORT227_FN2),
+	PINMUX_DATA(MSIOF1_RXD_MARK, PORT228_FN1),
+	PINMUX_DATA(SCIFA1_RXD2_MARK, PORT228_FN2),
+	PINMUX_DATA(GPS_RXD_MARK, PORT228_FN3),
+	PINMUX_DATA(MSIOF1_RSCK_MARK, PORT229_FN1),
+	PINMUX_DATA(SCIFA1_RTS2_MARK, PORT229_FN2),
+	PINMUX_DATA(MSIOF1_RSYNC_MARK, PORT230_FN1),
+	PINMUX_DATA(I2C_SCL2_MARK, PORT230_FN3),
+	PINMUX_DATA(MSIOF1_MCK0_MARK, PORT231_FN1),
+	PINMUX_DATA(MSIOF1_MCK1_MARK, PORT232_FN1),
+	PINMUX_DATA(MSIOF1_SS1_MARK, PORT233_FN1),
+	PINMUX_DATA(EDBGREQ3_MARK, PORT233_FN2),
+	PINMUX_DATA(MSIOF1_SS2_MARK, PORT234_FN1),
+	PINMUX_DATA(PORT236_IROUT_MARK, PORT236_FN1),
+	PINMUX_DATA(IRDA_OUT_MARK, PORT236_FN2),
+	PINMUX_DATA(IRDA_IN_MARK, PORT237_FN2),
+	PINMUX_DATA(IRDA_FIRSEL_MARK, PORT238_FN1),
+	PINMUX_DATA(TPU1TO0_MARK, PORT239_FN3),
+	PINMUX_DATA(TS_SPSYNC3_MARK, PORT239_FN4),
+	PINMUX_DATA(TPU1TO1_MARK, PORT240_FN3),
+	PINMUX_DATA(TS_SDAT3_MARK, PORT240_FN4),
+	PINMUX_DATA(TPU1TO2_MARK, PORT241_FN3),
+	PINMUX_DATA(TS_SDEN3_MARK, PORT241_FN4),
+	PINMUX_DATA(PORT241_MSIOF2_SS1_MARK, PORT241_FN5),
+	PINMUX_DATA(TPU1TO3_MARK, PORT242_FN3),
+	PINMUX_DATA(PORT242_MSIOF2_TSCK_MARK, PORT242_FN5),
+	PINMUX_DATA(M13_BSW_MARK, PORT243_FN2),
+	PINMUX_DATA(PORT243_MSIOF2_TSYNC_MARK, PORT243_FN5),
+	PINMUX_DATA(M14_GSW_MARK, PORT244_FN2),
+	PINMUX_DATA(PORT244_MSIOF2_TXD_MARK, PORT244_FN5),
+	PINMUX_DATA(PORT245_IROUT_MARK, PORT245_FN1),
+	PINMUX_DATA(M15_RSW_MARK, PORT245_FN2),
+	PINMUX_DATA(SOUT3_MARK, PORT246_FN1),
+	PINMUX_DATA(SCIFA2_TXD1_MARK, PORT246_FN2),
+	PINMUX_DATA(SIN3_MARK, PORT247_FN1),
+	PINMUX_DATA(SCIFA2_RXD1_MARK, PORT247_FN2),
+	PINMUX_DATA(XRTS3_MARK, PORT248_FN1),
+	PINMUX_DATA(SCIFA2_RTS1_MARK, PORT248_FN2),
+	PINMUX_DATA(PORT248_MSIOF2_SS2_MARK, PORT248_FN5),
+	PINMUX_DATA(XCTS3_MARK, PORT249_FN1),
+	PINMUX_DATA(SCIFA2_CTS1_MARK, PORT249_FN2),
+	PINMUX_DATA(PORT249_MSIOF2_RXD_MARK, PORT249_FN5),
+	PINMUX_DATA(DINT_MARK, PORT250_FN1),
+	PINMUX_DATA(SCIFA2_SCK1_MARK, PORT250_FN2),
+	PINMUX_DATA(TS_SCK3_MARK, PORT250_FN4),
+	PINMUX_DATA(SDHICLK0_MARK, PORT251_FN1),
+	PINMUX_DATA(TCK2_MARK, PORT251_FN2),
+	PINMUX_DATA(SDHICD0_MARK, PORT252_FN1),
+	PINMUX_DATA(SDHID0_0_MARK, PORT253_FN1),
+	PINMUX_DATA(TMS2_MARK, PORT253_FN2),
+	PINMUX_DATA(SDHID0_1_MARK, PORT254_FN1),
+	PINMUX_DATA(TDO2_MARK, PORT254_FN2),
+	PINMUX_DATA(SDHID0_2_MARK, PORT255_FN1),
+	PINMUX_DATA(TDI2_MARK, PORT255_FN2),
+	PINMUX_DATA(SDHID0_3_MARK, PORT256_FN1),
+	PINMUX_DATA(RTCK2_MARK, PORT256_FN2),
+
+	/* 49-6 (FN) */
+	PINMUX_DATA(SDHICMD0_MARK, PORT257_FN1),
+	PINMUX_DATA(TRST2_MARK, PORT257_FN2),
+	PINMUX_DATA(SDHIWP0_MARK, PORT258_FN1),
+	PINMUX_DATA(EDBGREQ2_MARK, PORT258_FN2),
+	PINMUX_DATA(SDHICLK1_MARK, PORT259_FN1),
+	PINMUX_DATA(TCK3_MARK, PORT259_FN4),
+	PINMUX_DATA(SDHID1_0_MARK, PORT260_FN1),
+	PINMUX_DATA(M11_SLCD_SO2_MARK, PORT260_FN2),
+	PINMUX_DATA(TS_SPSYNC2_MARK, PORT260_FN3),
+	PINMUX_DATA(TMS3_MARK, PORT260_FN4),
+	PINMUX_DATA(SDHID1_1_MARK, PORT261_FN1),
+	PINMUX_DATA(M9_SLCD_AO2_MARK, PORT261_FN2),
+	PINMUX_DATA(TS_SDAT2_MARK, PORT261_FN3),
+	PINMUX_DATA(TDO3_MARK, PORT261_FN4),
+	PINMUX_DATA(SDHID1_2_MARK, PORT262_FN1),
+	PINMUX_DATA(M10_SLCD_CK2_MARK, PORT262_FN2),
+	PINMUX_DATA(TS_SDEN2_MARK, PORT262_FN3),
+	PINMUX_DATA(TDI3_MARK, PORT262_FN4),
+	PINMUX_DATA(SDHID1_3_MARK, PORT263_FN1),
+	PINMUX_DATA(M12_SLCD_CE2_MARK, PORT263_FN2),
+	PINMUX_DATA(TS_SCK2_MARK, PORT263_FN3),
+	PINMUX_DATA(RTCK3_MARK, PORT263_FN4),
+	PINMUX_DATA(SDHICMD1_MARK, PORT264_FN1),
+	PINMUX_DATA(TRST3_MARK, PORT264_FN4),
+	PINMUX_DATA(SDHICLK2_MARK, PORT265_FN1),
+	PINMUX_DATA(SCIFB_SCK_MARK, PORT265_FN2),
+	PINMUX_DATA(SDHID2_0_MARK, PORT266_FN1),
+	PINMUX_DATA(SCIFB_TXD_MARK, PORT266_FN2),
+	PINMUX_DATA(SDHID2_1_MARK, PORT267_FN1),
+	PINMUX_DATA(SCIFB_CTS_MARK, PORT267_FN2),
+	PINMUX_DATA(SDHID2_2_MARK, PORT268_FN1),
+	PINMUX_DATA(SCIFB_RXD_MARK, PORT268_FN2),
+	PINMUX_DATA(SDHID2_3_MARK, PORT269_FN1),
+	PINMUX_DATA(SCIFB_RTS_MARK, PORT269_FN2),
+	PINMUX_DATA(SDHICMD2_MARK, PORT270_FN1),
+	PINMUX_DATA(RESETOUTS_MARK, PORT271_FN1),
+	PINMUX_DATA(DIVLOCK_MARK, PORT272_FN1),
+};
+
+#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
+#define GPIO_PORT_273() _273(_GPIO_PORT, , unused)
+#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
+
+static struct pinmux_gpio pinmux_gpios[] = {
+	/* 49-1 -> 49-6 (GPIO) */
+	GPIO_PORT_273(),
+
+	/* Special Pull-up / Pull-down Functions */
+	GPIO_FN(PORT48_KEYIN0_PU), GPIO_FN(PORT49_KEYIN1_PU),
+	GPIO_FN(PORT50_KEYIN2_PU), GPIO_FN(PORT55_KEYIN3_PU),
+	GPIO_FN(PORT56_KEYIN4_PU), GPIO_FN(PORT57_KEYIN5_PU),
+	GPIO_FN(PORT58_KEYIN6_PU),
+
+	/* 49-1 (FN) */
+	GPIO_FN(VBUS0), GPIO_FN(CPORT0), GPIO_FN(CPORT1), GPIO_FN(CPORT2),
+	GPIO_FN(CPORT3), GPIO_FN(CPORT4), GPIO_FN(CPORT5), GPIO_FN(CPORT6),
+	GPIO_FN(CPORT7), GPIO_FN(CPORT8), GPIO_FN(CPORT9), GPIO_FN(CPORT10),
+	GPIO_FN(CPORT11), GPIO_FN(SIN2), GPIO_FN(CPORT12), GPIO_FN(XCTS2),
+	GPIO_FN(CPORT13), GPIO_FN(RFSPO4), GPIO_FN(CPORT14), GPIO_FN(RFSPO5),
+	GPIO_FN(CPORT15), GPIO_FN(CPORT16), GPIO_FN(CPORT17), GPIO_FN(SOUT2),
+	GPIO_FN(CPORT18), GPIO_FN(XRTS2), GPIO_FN(CPORT19), GPIO_FN(CPORT20),
+	GPIO_FN(RFSPO6), GPIO_FN(CPORT21), GPIO_FN(STATUS0), GPIO_FN(CPORT22),
+	GPIO_FN(STATUS1), GPIO_FN(CPORT23), GPIO_FN(STATUS2), GPIO_FN(RFSPO7),
+	GPIO_FN(MPORT0), GPIO_FN(MPORT1), GPIO_FN(B_SYNLD1), GPIO_FN(B_SYNLD2),
+	GPIO_FN(XMAINPS), GPIO_FN(XDIVPS), GPIO_FN(XIDRST), GPIO_FN(IDCLK),
+	GPIO_FN(IDIO), GPIO_FN(SOUT1), GPIO_FN(SCIFA4_TXD),
+	GPIO_FN(M02_BERDAT), GPIO_FN(SIN1), GPIO_FN(SCIFA4_RXD), GPIO_FN(XWUP),
+	GPIO_FN(XRTS1), GPIO_FN(SCIFA4_RTS), GPIO_FN(M03_BERCLK),
+	GPIO_FN(XCTS1), GPIO_FN(SCIFA4_CTS),
+
+	/* 49-2 (FN) */
+	GPIO_FN(HSU_IQ_AGC6), GPIO_FN(MFG2_IN2), GPIO_FN(MSIOF2_MCK0),
+	GPIO_FN(HSU_IQ_AGC5), GPIO_FN(MFG2_IN1), GPIO_FN(MSIOF2_MCK1),
+	GPIO_FN(HSU_IQ_AGC4), GPIO_FN(MSIOF2_RSYNC),
+	GPIO_FN(HSU_IQ_AGC3), GPIO_FN(MFG2_OUT1), GPIO_FN(MSIOF2_RSCK),
+	GPIO_FN(HSU_IQ_AGC2), GPIO_FN(PORT42_KEYOUT0),
+	GPIO_FN(HSU_IQ_AGC1), GPIO_FN(PORT43_KEYOUT1),
+	GPIO_FN(HSU_IQ_AGC0), GPIO_FN(PORT44_KEYOUT2),
+	GPIO_FN(HSU_IQ_AGC_ST), GPIO_FN(PORT45_KEYOUT3),
+	GPIO_FN(HSU_IQ_PDO), GPIO_FN(PORT46_KEYOUT4),
+	GPIO_FN(HSU_IQ_PYO), GPIO_FN(PORT47_KEYOUT5),
+	GPIO_FN(HSU_EN_TXMUX_G3MO), GPIO_FN(PORT48_KEYIN0),
+	GPIO_FN(HSU_I_TXMUX_G3MO), GPIO_FN(PORT49_KEYIN1),
+	GPIO_FN(HSU_Q_TXMUX_G3MO), GPIO_FN(PORT50_KEYIN2),
+	GPIO_FN(HSU_SYO), GPIO_FN(PORT51_MSIOF2_TSYNC),
+	GPIO_FN(HSU_SDO), GPIO_FN(PORT52_MSIOF2_TSCK),
+	GPIO_FN(HSU_TGTTI_G3MO), GPIO_FN(PORT53_MSIOF2_TXD),
+	GPIO_FN(B_TIME_STAMP), GPIO_FN(PORT54_MSIOF2_RXD),
+	GPIO_FN(HSU_SDI), GPIO_FN(PORT55_KEYIN3),
+	GPIO_FN(HSU_SCO), GPIO_FN(PORT56_KEYIN4),
+	GPIO_FN(HSU_DREQ), GPIO_FN(PORT57_KEYIN5),
+	GPIO_FN(HSU_DACK), GPIO_FN(PORT58_KEYIN6),
+	GPIO_FN(HSU_CLK61M), GPIO_FN(PORT59_MSIOF2_SS1),
+	GPIO_FN(HSU_XRST), GPIO_FN(PORT60_MSIOF2_SS2),
+	GPIO_FN(PCMCLKO), GPIO_FN(SYNC8KO), GPIO_FN(DNPCM_A), GPIO_FN(UPPCM_A),
+	GPIO_FN(XTALB1L),
+	GPIO_FN(GPS_AGC1), GPIO_FN(SCIFA0_RTS),
+	GPIO_FN(GPS_AGC2), GPIO_FN(SCIFA0_SCK),
+	GPIO_FN(GPS_AGC3), GPIO_FN(SCIFA0_TXD),
+	GPIO_FN(GPS_AGC4), GPIO_FN(SCIFA0_RXD),
+	GPIO_FN(GPS_PWRD), GPIO_FN(SCIFA0_CTS),
+	GPIO_FN(GPS_IM), GPIO_FN(GPS_IS), GPIO_FN(GPS_QM), GPIO_FN(GPS_QS),
+	GPIO_FN(SIUBOMC), GPIO_FN(TPU2TO0),
+	GPIO_FN(SIUCKB), GPIO_FN(TPU2TO1),
+	GPIO_FN(SIUBOLR), GPIO_FN(BBIF2_TSYNC), GPIO_FN(TPU2TO2),
+	GPIO_FN(SIUBOBT), GPIO_FN(BBIF2_TSCK), GPIO_FN(TPU2TO3),
+	GPIO_FN(SIUBOSLD), GPIO_FN(BBIF2_TXD), GPIO_FN(TPU3TO0),
+	GPIO_FN(SIUBILR), GPIO_FN(TPU3TO1),
+	GPIO_FN(SIUBIBT), GPIO_FN(TPU3TO2),
+	GPIO_FN(SIUBISLD), GPIO_FN(TPU3TO3),
+	GPIO_FN(NMI), GPIO_FN(TPU4TO0),
+	GPIO_FN(DNPCM_M), GPIO_FN(TPU4TO1), GPIO_FN(TPU4TO2), GPIO_FN(TPU4TO3),
+	GPIO_FN(IRQ_TMPB),
+	GPIO_FN(PWEN), GPIO_FN(MFG1_OUT1),
+	GPIO_FN(OVCN), GPIO_FN(MFG1_IN1),
+	GPIO_FN(OVCN2), GPIO_FN(MFG1_IN2),
+
+	/* 49-3 (FN) */
+	GPIO_FN(RFSPO1), GPIO_FN(RFSPO2), GPIO_FN(RFSPO3),
+	GPIO_FN(PORT93_VIO_CKO2),
+	GPIO_FN(USBTERM), GPIO_FN(EXTLP), GPIO_FN(IDIN),
+	GPIO_FN(SCIFA5_CTS), GPIO_FN(MFG0_IN1),
+	GPIO_FN(SCIFA5_RTS), GPIO_FN(MFG0_IN2),
+	GPIO_FN(SCIFA5_RXD),
+	GPIO_FN(SCIFA5_TXD),
+	GPIO_FN(SCIFA5_SCK), GPIO_FN(MFG0_OUT1),
+	GPIO_FN(A0_EA0), GPIO_FN(BS),
+	GPIO_FN(A14_EA14), GPIO_FN(PORT102_KEYOUT0),
+	GPIO_FN(A15_EA15), GPIO_FN(PORT103_KEYOUT1), GPIO_FN(DV_CLKOL),
+	GPIO_FN(A16_EA16), GPIO_FN(PORT104_KEYOUT2),
+	GPIO_FN(DV_VSYNCL), GPIO_FN(MSIOF0_SS1),
+	GPIO_FN(A17_EA17), GPIO_FN(PORT105_KEYOUT3),
+	GPIO_FN(DV_HSYNCL), GPIO_FN(MSIOF0_TSYNC),
+	GPIO_FN(A18_EA18), GPIO_FN(PORT106_KEYOUT4),
+	GPIO_FN(DV_DL0), GPIO_FN(MSIOF0_TSCK),
+	GPIO_FN(A19_EA19), GPIO_FN(PORT107_KEYOUT5),
+	GPIO_FN(DV_DL1), GPIO_FN(MSIOF0_TXD),
+	GPIO_FN(A20_EA20), GPIO_FN(PORT108_KEYIN0),
+	GPIO_FN(DV_DL2), GPIO_FN(MSIOF0_RSCK),
+	GPIO_FN(A21_EA21), GPIO_FN(PORT109_KEYIN1),
+	GPIO_FN(DV_DL3), GPIO_FN(MSIOF0_RSYNC),
+	GPIO_FN(A22_EA22), GPIO_FN(PORT110_KEYIN2),
+	GPIO_FN(DV_DL4), GPIO_FN(MSIOF0_MCK0),
+	GPIO_FN(A23_EA23), GPIO_FN(PORT111_KEYIN3),
+	GPIO_FN(DV_DL5), GPIO_FN(MSIOF0_MCK1),
+	GPIO_FN(A24_EA24), GPIO_FN(PORT112_KEYIN4),
+	GPIO_FN(DV_DL6), GPIO_FN(MSIOF0_RXD),
+	GPIO_FN(A25_EA25), GPIO_FN(PORT113_KEYIN5),
+	GPIO_FN(DV_DL7), GPIO_FN(MSIOF0_SS2),
+	GPIO_FN(A26), GPIO_FN(PORT113_KEYIN6), GPIO_FN(DV_CLKIL),
+	GPIO_FN(D0_ED0_NAF0), GPIO_FN(D1_ED1_NAF1), GPIO_FN(D2_ED2_NAF2),
+	GPIO_FN(D3_ED3_NAF3), GPIO_FN(D4_ED4_NAF4), GPIO_FN(D5_ED5_NAF5),
+	GPIO_FN(D6_ED6_NAF6), GPIO_FN(D7_ED7_NAF7), GPIO_FN(D8_ED8_NAF8),
+	GPIO_FN(D9_ED9_NAF9), GPIO_FN(D10_ED10_NAF10), GPIO_FN(D11_ED11_NAF11),
+	GPIO_FN(D12_ED12_NAF12), GPIO_FN(D13_ED13_NAF13),
+	GPIO_FN(D14_ED14_NAF14), GPIO_FN(D15_ED15_NAF15),
+	GPIO_FN(CS4), GPIO_FN(CS5A), GPIO_FN(CS5B), GPIO_FN(FCE1),
+	GPIO_FN(CS6B), GPIO_FN(XCS2), GPIO_FN(FCE0), GPIO_FN(CS6A),
+	GPIO_FN(DACK0), GPIO_FN(WAIT), GPIO_FN(DREQ0), GPIO_FN(RD_XRD),
+	GPIO_FN(A27), GPIO_FN(RDWR_XWE), GPIO_FN(WE0_XWR0_FWE),
+	GPIO_FN(WE1_XWR1), GPIO_FN(FRB), GPIO_FN(CKO),
+	GPIO_FN(NBRSTOUT), GPIO_FN(NBRST),
+
+	/* 49-4 (FN) */
+	GPIO_FN(RFSPO0), GPIO_FN(PORT146_VIO_CKO2), GPIO_FN(TSTMD),
+	GPIO_FN(VIO_VD), GPIO_FN(VIO_HD),
+	GPIO_FN(VIO_D0), GPIO_FN(VIO_D1), GPIO_FN(VIO_D2),
+	GPIO_FN(VIO_D3), GPIO_FN(VIO_D4), GPIO_FN(VIO_D5),
+	GPIO_FN(VIO_D6), GPIO_FN(VIO_D7), GPIO_FN(VIO_D8),
+	GPIO_FN(VIO_D9), GPIO_FN(VIO_D10), GPIO_FN(VIO_D11),
+	GPIO_FN(VIO_D12), GPIO_FN(VIO_D13), GPIO_FN(VIO_D14),
+	GPIO_FN(VIO_D15), GPIO_FN(VIO_CLK), GPIO_FN(VIO_FIELD),
+	GPIO_FN(VIO_CKO),
+	GPIO_FN(MFG3_IN1), GPIO_FN(MFG3_IN2),
+	GPIO_FN(M9_SLCD_A01), GPIO_FN(MFG3_OUT1), GPIO_FN(TPU0TO0),
+	GPIO_FN(M10_SLCD_CK1), GPIO_FN(MFG4_IN1), GPIO_FN(TPU0TO1),
+	GPIO_FN(M11_SLCD_SO1), GPIO_FN(MFG4_IN2), GPIO_FN(TPU0TO2),
+	GPIO_FN(M12_SLCD_CE1), GPIO_FN(MFG4_OUT1), GPIO_FN(TPU0TO3),
+	GPIO_FN(LCDD0), GPIO_FN(PORT175_KEYOUT0), GPIO_FN(DV_D0),
+	GPIO_FN(SIUCKA), GPIO_FN(MFG0_OUT2),
+	GPIO_FN(LCDD1), GPIO_FN(PORT176_KEYOUT1), GPIO_FN(DV_D1),
+	GPIO_FN(SIUAOLR), GPIO_FN(BBIF2_TSYNC1),
+	GPIO_FN(LCDD2), GPIO_FN(PORT177_KEYOUT2), GPIO_FN(DV_D2),
+	GPIO_FN(SIUAOBT), GPIO_FN(BBIF2_TSCK1),
+	GPIO_FN(LCDD3), GPIO_FN(PORT178_KEYOUT3), GPIO_FN(DV_D3),
+	GPIO_FN(SIUAOSLD), GPIO_FN(BBIF2_TXD1),
+	GPIO_FN(LCDD4), GPIO_FN(PORT179_KEYOUT4), GPIO_FN(DV_D4),
+	GPIO_FN(SIUAISPD), GPIO_FN(MFG1_OUT2),
+	GPIO_FN(LCDD5), GPIO_FN(PORT180_KEYOUT5), GPIO_FN(DV_D5),
+	GPIO_FN(SIUAILR), GPIO_FN(MFG2_OUT2),
+	GPIO_FN(LCDD6), GPIO_FN(DV_D6),
+	GPIO_FN(SIUAIBT), GPIO_FN(MFG3_OUT2), GPIO_FN(XWR2),
+	GPIO_FN(LCDD7), GPIO_FN(DV_D7),
+	GPIO_FN(SIUAISLD), GPIO_FN(MFG4_OUT2), GPIO_FN(XWR3),
+	GPIO_FN(LCDD8), GPIO_FN(DV_D8), GPIO_FN(D16), GPIO_FN(ED16),
+	GPIO_FN(LCDD9), GPIO_FN(DV_D9), GPIO_FN(D17), GPIO_FN(ED17),
+	GPIO_FN(LCDD10), GPIO_FN(DV_D10), GPIO_FN(D18), GPIO_FN(ED18),
+	GPIO_FN(LCDD11), GPIO_FN(DV_D11), GPIO_FN(D19), GPIO_FN(ED19),
+	GPIO_FN(LCDD12), GPIO_FN(DV_D12), GPIO_FN(D20), GPIO_FN(ED20),
+	GPIO_FN(LCDD13), GPIO_FN(DV_D13), GPIO_FN(D21), GPIO_FN(ED21),
+	GPIO_FN(LCDD14), GPIO_FN(DV_D14), GPIO_FN(D22), GPIO_FN(ED22),
+	GPIO_FN(LCDD15), GPIO_FN(DV_D15), GPIO_FN(D23), GPIO_FN(ED23),
+	GPIO_FN(LCDD16), GPIO_FN(DV_HSYNC), GPIO_FN(D24), GPIO_FN(ED24),
+	GPIO_FN(LCDD17), GPIO_FN(DV_VSYNC), GPIO_FN(D25), GPIO_FN(ED25),
+	GPIO_FN(LCDD18), GPIO_FN(DREQ2), GPIO_FN(MSIOF0L_TSCK),
+	GPIO_FN(D26), GPIO_FN(ED26),
+	GPIO_FN(LCDD19), GPIO_FN(MSIOF0L_TSYNC),
+	GPIO_FN(D27), GPIO_FN(ED27),
+	GPIO_FN(LCDD20), GPIO_FN(TS_SPSYNC1), GPIO_FN(MSIOF0L_MCK0),
+	GPIO_FN(D28), GPIO_FN(ED28),
+	GPIO_FN(LCDD21), GPIO_FN(TS_SDAT1), GPIO_FN(MSIOF0L_MCK1),
+	GPIO_FN(D29), GPIO_FN(ED29),
+	GPIO_FN(LCDD22), GPIO_FN(TS_SDEN1), GPIO_FN(MSIOF0L_SS1),
+	GPIO_FN(D30), GPIO_FN(ED30),
+	GPIO_FN(LCDD23), GPIO_FN(TS_SCK1), GPIO_FN(MSIOF0L_SS2),
+	GPIO_FN(D31), GPIO_FN(ED31),
+	GPIO_FN(LCDDCK), GPIO_FN(LCDWR), GPIO_FN(DV_CKO), GPIO_FN(SIUAOSPD),
+	GPIO_FN(LCDRD), GPIO_FN(DACK2), GPIO_FN(MSIOF0L_RSYNC),
+
+	/* 49-5 (FN) */
+	GPIO_FN(LCDHSYN), GPIO_FN(LCDCS), GPIO_FN(LCDCS2), GPIO_FN(DACK3),
+	GPIO_FN(LCDDISP), GPIO_FN(LCDRS), GPIO_FN(DREQ3), GPIO_FN(MSIOF0L_RSCK),
+	GPIO_FN(LCDCSYN), GPIO_FN(LCDCSYN2), GPIO_FN(DV_CKI),
+	GPIO_FN(LCDLCLK), GPIO_FN(DREQ1), GPIO_FN(MSIOF0L_RXD),
+	GPIO_FN(LCDDON), GPIO_FN(LCDDON2), GPIO_FN(DACK1), GPIO_FN(MSIOF0L_TXD),
+	GPIO_FN(VIO_DR0), GPIO_FN(VIO_DR1), GPIO_FN(VIO_DR2), GPIO_FN(VIO_DR3),
+	GPIO_FN(VIO_DR4), GPIO_FN(VIO_DR5), GPIO_FN(VIO_DR6), GPIO_FN(VIO_DR7),
+	GPIO_FN(VIO_VDR), GPIO_FN(VIO_HDR),
+	GPIO_FN(VIO_CLKR), GPIO_FN(VIO_CKOR),
+	GPIO_FN(SCIFA1_TXD), GPIO_FN(GPS_PGFA0),
+	GPIO_FN(SCIFA1_SCK), GPIO_FN(GPS_PGFA1),
+	GPIO_FN(SCIFA1_RTS), GPIO_FN(GPS_EPPSINMON),
+	GPIO_FN(SCIFA1_RXD), GPIO_FN(SCIFA1_CTS),
+	GPIO_FN(MSIOF1_TXD), GPIO_FN(SCIFA1_TXD2), GPIO_FN(GPS_TXD),
+	GPIO_FN(MSIOF1_TSYNC), GPIO_FN(SCIFA1_CTS2), GPIO_FN(I2C_SDA2),
+	GPIO_FN(MSIOF1_TSCK), GPIO_FN(SCIFA1_SCK2),
+	GPIO_FN(MSIOF1_RXD), GPIO_FN(SCIFA1_RXD2), GPIO_FN(GPS_RXD),
+	GPIO_FN(MSIOF1_RSCK), GPIO_FN(SCIFA1_RTS2),
+	GPIO_FN(MSIOF1_RSYNC), GPIO_FN(I2C_SCL2),
+	GPIO_FN(MSIOF1_MCK0), GPIO_FN(MSIOF1_MCK1),
+	GPIO_FN(MSIOF1_SS1), GPIO_FN(EDBGREQ3),
+	GPIO_FN(MSIOF1_SS2),
+	GPIO_FN(PORT236_IROUT), GPIO_FN(IRDA_OUT),
+	GPIO_FN(IRDA_IN), GPIO_FN(IRDA_FIRSEL),
+	GPIO_FN(TPU1TO0), GPIO_FN(TS_SPSYNC3),
+	GPIO_FN(TPU1TO1), GPIO_FN(TS_SDAT3),
+	GPIO_FN(TPU1TO2), GPIO_FN(TS_SDEN3), GPIO_FN(PORT241_MSIOF2_SS1),
+	GPIO_FN(TPU1TO3), GPIO_FN(PORT242_MSIOF2_TSCK),
+	GPIO_FN(M13_BSW), GPIO_FN(PORT243_MSIOF2_TSYNC),
+	GPIO_FN(M14_GSW), GPIO_FN(PORT244_MSIOF2_TXD),
+	GPIO_FN(PORT245_IROUT), GPIO_FN(M15_RSW),
+	GPIO_FN(SOUT3), GPIO_FN(SCIFA2_TXD1),
+	GPIO_FN(SIN3), GPIO_FN(SCIFA2_RXD1),
+	GPIO_FN(XRTS3), GPIO_FN(SCIFA2_RTS1), GPIO_FN(PORT248_MSIOF2_SS2),
+	GPIO_FN(XCTS3), GPIO_FN(SCIFA2_CTS1), GPIO_FN(PORT249_MSIOF2_RXD),
+	GPIO_FN(DINT), GPIO_FN(SCIFA2_SCK1), GPIO_FN(TS_SCK3),
+	GPIO_FN(SDHICLK0), GPIO_FN(TCK2),
+	GPIO_FN(SDHICD0),
+	GPIO_FN(SDHID0_0), GPIO_FN(TMS2),
+	GPIO_FN(SDHID0_1), GPIO_FN(TDO2),
+	GPIO_FN(SDHID0_2), GPIO_FN(TDI2),
+	GPIO_FN(SDHID0_3), GPIO_FN(RTCK2),
+
+	/* 49-6 (FN) */
+	GPIO_FN(SDHICMD0), GPIO_FN(TRST2),
+	GPIO_FN(SDHIWP0), GPIO_FN(EDBGREQ2),
+	GPIO_FN(SDHICLK1), GPIO_FN(TCK3),
+	GPIO_FN(SDHID1_0), GPIO_FN(M11_SLCD_SO2),
+	GPIO_FN(TS_SPSYNC2), GPIO_FN(TMS3),
+	GPIO_FN(SDHID1_1), GPIO_FN(M9_SLCD_AO2),
+	GPIO_FN(TS_SDAT2), GPIO_FN(TDO3),
+	GPIO_FN(SDHID1_2), GPIO_FN(M10_SLCD_CK2),
+	GPIO_FN(TS_SDEN2), GPIO_FN(TDI3),
+	GPIO_FN(SDHID1_3), GPIO_FN(M12_SLCD_CE2),
+	GPIO_FN(TS_SCK2), GPIO_FN(RTCK3),
+	GPIO_FN(SDHICMD1), GPIO_FN(TRST3),
+	GPIO_FN(SDHICLK2), GPIO_FN(SCIFB_SCK),
+	GPIO_FN(SDHID2_0), GPIO_FN(SCIFB_TXD),
+	GPIO_FN(SDHID2_1), GPIO_FN(SCIFB_CTS),
+	GPIO_FN(SDHID2_2), GPIO_FN(SCIFB_RXD),
+	GPIO_FN(SDHID2_3), GPIO_FN(SCIFB_RTS),
+	GPIO_FN(SDHICMD2),
+	GPIO_FN(RESETOUTS),
+	GPIO_FN(DIVLOCK),
+};
+
+/* helper for top 4 bits in PORTnCR */
+#define PCRH(in, in_pd, in_pu, out)		\
+	0, (out), (in), 0,			\
+	0, 0, 0, 0,				\
+	0, 0, (in_pd), 0,			\
+	0, 0, (in_pu), 0
+
+#define PORTCR(nr, reg)						\
+	{ PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) {		\
+		PCRH(PORT##nr##_IN, PORT##nr##_IN_PD,		\
+		     PORT##nr##_IN_PU, PORT##nr##_OUT),		\
+		PORT##nr##_FN0, PORT##nr##_FN1, PORT##nr##_FN2,	\
+		PORT##nr##_FN3,	PORT##nr##_FN4, PORT##nr##_FN5,	\
+		PORT##nr##_FN6, PORT##nr##_FN7 }		\
+	}
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+	PORTCR(0, 0xe6050000), /* PORT0CR */
+	PORTCR(1, 0xe6050001), /* PORT1CR */
+	PORTCR(2, 0xe6050002), /* PORT2CR */
+	PORTCR(3, 0xe6050003), /* PORT3CR */
+	PORTCR(4, 0xe6050004), /* PORT4CR */
+	PORTCR(5, 0xe6050005), /* PORT5CR */
+	PORTCR(6, 0xe6050006), /* PORT6CR */
+	PORTCR(7, 0xe6050007), /* PORT7CR */
+	PORTCR(8, 0xe6050008), /* PORT8CR */
+	PORTCR(9, 0xe6050009), /* PORT9CR */
+
+	PORTCR(10, 0xe605000a), /* PORT10CR */
+	PORTCR(11, 0xe605000b), /* PORT11CR */
+	PORTCR(12, 0xe605000c), /* PORT12CR */
+	PORTCR(13, 0xe605000d), /* PORT13CR */
+	PORTCR(14, 0xe605000e), /* PORT14CR */
+	PORTCR(15, 0xe605000f), /* PORT15CR */
+	PORTCR(16, 0xe6050010), /* PORT16CR */
+	PORTCR(17, 0xe6050011), /* PORT17CR */
+	PORTCR(18, 0xe6050012), /* PORT18CR */
+	PORTCR(19, 0xe6050013), /* PORT19CR */
+
+	PORTCR(20, 0xe6050014), /* PORT20CR */
+	PORTCR(21, 0xe6050015), /* PORT21CR */
+	PORTCR(22, 0xe6050016), /* PORT22CR */
+	PORTCR(23, 0xe6050017), /* PORT23CR */
+	PORTCR(24, 0xe6050018), /* PORT24CR */
+	PORTCR(25, 0xe6050019), /* PORT25CR */
+	PORTCR(26, 0xe605001a), /* PORT26CR */
+	PORTCR(27, 0xe605001b), /* PORT27CR */
+	PORTCR(28, 0xe605001c), /* PORT28CR */
+	PORTCR(29, 0xe605001d), /* PORT29CR */
+
+	PORTCR(30, 0xe605001e), /* PORT30CR */
+	PORTCR(31, 0xe605001f), /* PORT31CR */
+	PORTCR(32, 0xe6050020), /* PORT32CR */
+	PORTCR(33, 0xe6050021), /* PORT33CR */
+	PORTCR(34, 0xe6050022), /* PORT34CR */
+	PORTCR(35, 0xe6050023), /* PORT35CR */
+	PORTCR(36, 0xe6050024), /* PORT36CR */
+	PORTCR(37, 0xe6050025), /* PORT37CR */
+	PORTCR(38, 0xe6050026), /* PORT38CR */
+	PORTCR(39, 0xe6050027), /* PORT39CR */
+
+	PORTCR(40, 0xe6050028), /* PORT40CR */
+	PORTCR(41, 0xe6050029), /* PORT41CR */
+	PORTCR(42, 0xe605002a), /* PORT42CR */
+	PORTCR(43, 0xe605002b), /* PORT43CR */
+	PORTCR(44, 0xe605002c), /* PORT44CR */
+	PORTCR(45, 0xe605002d), /* PORT45CR */
+	PORTCR(46, 0xe605002e), /* PORT46CR */
+	PORTCR(47, 0xe605002f), /* PORT47CR */
+	PORTCR(48, 0xe6050030), /* PORT48CR */
+	PORTCR(49, 0xe6050031), /* PORT49CR */
+
+	PORTCR(50, 0xe6050032), /* PORT50CR */
+	PORTCR(51, 0xe6050033), /* PORT51CR */
+	PORTCR(52, 0xe6050034), /* PORT52CR */
+	PORTCR(53, 0xe6050035), /* PORT53CR */
+	PORTCR(54, 0xe6050036), /* PORT54CR */
+	PORTCR(55, 0xe6050037), /* PORT55CR */
+	PORTCR(56, 0xe6050038), /* PORT56CR */
+	PORTCR(57, 0xe6050039), /* PORT57CR */
+	PORTCR(58, 0xe605003a), /* PORT58CR */
+	PORTCR(59, 0xe605003b), /* PORT59CR */
+
+	PORTCR(60, 0xe605003c), /* PORT60CR */
+	PORTCR(61, 0xe605003d), /* PORT61CR */
+	PORTCR(62, 0xe605003e), /* PORT62CR */
+	PORTCR(63, 0xe605003f), /* PORT63CR */
+	PORTCR(64, 0xe6050040), /* PORT64CR */
+	PORTCR(65, 0xe6050041), /* PORT65CR */
+	PORTCR(66, 0xe6050042), /* PORT66CR */
+	PORTCR(67, 0xe6050043), /* PORT67CR */
+	PORTCR(68, 0xe6050044), /* PORT68CR */
+	PORTCR(69, 0xe6050045), /* PORT69CR */
+
+	PORTCR(70, 0xe6050046), /* PORT70CR */
+	PORTCR(71, 0xe6050047), /* PORT71CR */
+	PORTCR(72, 0xe6050048), /* PORT72CR */
+	PORTCR(73, 0xe6050049), /* PORT73CR */
+	PORTCR(74, 0xe605004a), /* PORT74CR */
+	PORTCR(75, 0xe605004b), /* PORT75CR */
+	PORTCR(76, 0xe605004c), /* PORT76CR */
+	PORTCR(77, 0xe605004d), /* PORT77CR */
+	PORTCR(78, 0xe605004e), /* PORT78CR */
+	PORTCR(79, 0xe605004f), /* PORT79CR */
+
+	PORTCR(80, 0xe6050050), /* PORT80CR */
+	PORTCR(81, 0xe6050051), /* PORT81CR */
+	PORTCR(82, 0xe6050052), /* PORT82CR */
+	PORTCR(83, 0xe6050053), /* PORT83CR */
+	PORTCR(84, 0xe6050054), /* PORT84CR */
+	PORTCR(85, 0xe6050055), /* PORT85CR */
+	PORTCR(86, 0xe6050056), /* PORT86CR */
+	PORTCR(87, 0xe6050057), /* PORT87CR */
+	PORTCR(88, 0xe6051058), /* PORT88CR */
+	PORTCR(89, 0xe6051059), /* PORT89CR */
+
+	PORTCR(90, 0xe605105a), /* PORT90CR */
+	PORTCR(91, 0xe605105b), /* PORT91CR */
+	PORTCR(92, 0xe605105c), /* PORT92CR */
+	PORTCR(93, 0xe605105d), /* PORT93CR */
+	PORTCR(94, 0xe605105e), /* PORT94CR */
+	PORTCR(95, 0xe605105f), /* PORT95CR */
+	PORTCR(96, 0xe6051060), /* PORT96CR */
+	PORTCR(97, 0xe6051061), /* PORT97CR */
+	PORTCR(98, 0xe6051062), /* PORT98CR */
+	PORTCR(99, 0xe6051063), /* PORT99CR */
+
+	PORTCR(100, 0xe6051064), /* PORT100CR */
+	PORTCR(101, 0xe6051065), /* PORT101CR */
+	PORTCR(102, 0xe6051066), /* PORT102CR */
+	PORTCR(103, 0xe6051067), /* PORT103CR */
+	PORTCR(104, 0xe6051068), /* PORT104CR */
+	PORTCR(105, 0xe6051069), /* PORT105CR */
+	PORTCR(106, 0xe605106a), /* PORT106CR */
+	PORTCR(107, 0xe605106b), /* PORT107CR */
+	PORTCR(108, 0xe605106c), /* PORT108CR */
+	PORTCR(109, 0xe605106d), /* PORT109CR */
+
+	PORTCR(110, 0xe605106e), /* PORT110CR */
+	PORTCR(111, 0xe605106f), /* PORT111CR */
+	PORTCR(112, 0xe6051070), /* PORT112CR */
+	PORTCR(113, 0xe6051071), /* PORT113CR */
+	PORTCR(114, 0xe6051072), /* PORT114CR */
+	PORTCR(115, 0xe6051073), /* PORT115CR */
+	PORTCR(116, 0xe6051074), /* PORT116CR */
+	PORTCR(117, 0xe6051075), /* PORT117CR */
+	PORTCR(118, 0xe6051076), /* PORT118CR */
+	PORTCR(119, 0xe6051077), /* PORT119CR */
+
+	PORTCR(120, 0xe6051078), /* PORT120CR */
+	PORTCR(121, 0xe6051079), /* PORT121CR */
+	PORTCR(122, 0xe605107a), /* PORT122CR */
+	PORTCR(123, 0xe605107b), /* PORT123CR */
+	PORTCR(124, 0xe605107c), /* PORT124CR */
+	PORTCR(125, 0xe605107d), /* PORT125CR */
+	PORTCR(126, 0xe605107e), /* PORT126CR */
+	PORTCR(127, 0xe605107f), /* PORT127CR */
+	PORTCR(128, 0xe6051080), /* PORT128CR */
+	PORTCR(129, 0xe6051081), /* PORT129CR */
+
+	PORTCR(130, 0xe6051082), /* PORT130CR */
+	PORTCR(131, 0xe6051083), /* PORT131CR */
+	PORTCR(132, 0xe6051084), /* PORT132CR */
+	PORTCR(133, 0xe6051085), /* PORT133CR */
+	PORTCR(134, 0xe6051086), /* PORT134CR */
+	PORTCR(135, 0xe6051087), /* PORT135CR */
+	PORTCR(136, 0xe6051088), /* PORT136CR */
+	PORTCR(137, 0xe6051089), /* PORT137CR */
+	PORTCR(138, 0xe605108a), /* PORT138CR */
+	PORTCR(139, 0xe605108b), /* PORT139CR */
+
+	PORTCR(140, 0xe605108c), /* PORT140CR */
+	PORTCR(141, 0xe605108d), /* PORT141CR */
+	PORTCR(142, 0xe605108e), /* PORT142CR */
+	PORTCR(143, 0xe605108f), /* PORT143CR */
+	PORTCR(144, 0xe6051090), /* PORT144CR */
+	PORTCR(145, 0xe6051091), /* PORT145CR */
+	PORTCR(146, 0xe6051092), /* PORT146CR */
+	PORTCR(147, 0xe6051093), /* PORT147CR */
+	PORTCR(148, 0xe6051094), /* PORT148CR */
+	PORTCR(149, 0xe6051095), /* PORT149CR */
+
+	PORTCR(150, 0xe6051096), /* PORT150CR */
+	PORTCR(151, 0xe6051097), /* PORT151CR */
+	PORTCR(152, 0xe6051098), /* PORT152CR */
+	PORTCR(153, 0xe6051099), /* PORT153CR */
+	PORTCR(154, 0xe605109a), /* PORT154CR */
+	PORTCR(155, 0xe605109b), /* PORT155CR */
+	PORTCR(156, 0xe605109c), /* PORT156CR */
+	PORTCR(157, 0xe605109d), /* PORT157CR */
+	PORTCR(158, 0xe605109e), /* PORT158CR */
+	PORTCR(159, 0xe605109f), /* PORT159CR */
+
+	PORTCR(160, 0xe60510a0), /* PORT160CR */
+	PORTCR(161, 0xe60510a1), /* PORT161CR */
+	PORTCR(162, 0xe60510a2), /* PORT162CR */
+	PORTCR(163, 0xe60510a3), /* PORT163CR */
+	PORTCR(164, 0xe60510a4), /* PORT164CR */
+	PORTCR(165, 0xe60510a5), /* PORT165CR */
+	PORTCR(166, 0xe60510a6), /* PORT166CR */
+	PORTCR(167, 0xe60510a7), /* PORT167CR */
+	PORTCR(168, 0xe60510a8), /* PORT168CR */
+	PORTCR(169, 0xe60510a9), /* PORT169CR */
+
+	PORTCR(170, 0xe60510aa), /* PORT170CR */
+	PORTCR(171, 0xe60510ab), /* PORT171CR */
+	PORTCR(172, 0xe60510ac), /* PORT172CR */
+	PORTCR(173, 0xe60510ad), /* PORT173CR */
+	PORTCR(174, 0xe60510ae), /* PORT174CR */
+	PORTCR(175, 0xe60520af), /* PORT175CR */
+	PORTCR(176, 0xe60520b0), /* PORT176CR */
+	PORTCR(177, 0xe60520b1), /* PORT177CR */
+	PORTCR(178, 0xe60520b2), /* PORT178CR */
+	PORTCR(179, 0xe60520b3), /* PORT179CR */
+
+	PORTCR(180, 0xe60520b4), /* PORT180CR */
+	PORTCR(181, 0xe60520b5), /* PORT181CR */
+	PORTCR(182, 0xe60520b6), /* PORT182CR */
+	PORTCR(183, 0xe60520b7), /* PORT183CR */
+	PORTCR(184, 0xe60520b8), /* PORT184CR */
+	PORTCR(185, 0xe60520b9), /* PORT185CR */
+	PORTCR(186, 0xe60520ba), /* PORT186CR */
+	PORTCR(187, 0xe60520bb), /* PORT187CR */
+	PORTCR(188, 0xe60520bc), /* PORT188CR */
+	PORTCR(189, 0xe60520bd), /* PORT189CR */
+
+	PORTCR(190, 0xe60520be), /* PORT190CR */
+	PORTCR(191, 0xe60520bf), /* PORT191CR */
+	PORTCR(192, 0xe60520c0), /* PORT192CR */
+	PORTCR(193, 0xe60520c1), /* PORT193CR */
+	PORTCR(194, 0xe60520c2), /* PORT194CR */
+	PORTCR(195, 0xe60520c3), /* PORT195CR */
+	PORTCR(196, 0xe60520c4), /* PORT196CR */
+	PORTCR(197, 0xe60520c5), /* PORT197CR */
+	PORTCR(198, 0xe60520c6), /* PORT198CR */
+	PORTCR(199, 0xe60520c7), /* PORT199CR */
+
+	PORTCR(200, 0xe60520c8), /* PORT200CR */
+	PORTCR(201, 0xe60520c9), /* PORT201CR */
+	PORTCR(202, 0xe60520ca), /* PORT202CR */
+	PORTCR(203, 0xe60520cb), /* PORT203CR */
+	PORTCR(204, 0xe60520cc), /* PORT204CR */
+	PORTCR(205, 0xe60520cd), /* PORT205CR */
+	PORTCR(206, 0xe60520ce), /* PORT206CR */
+	PORTCR(207, 0xe60520cf), /* PORT207CR */
+	PORTCR(208, 0xe60520d0), /* PORT208CR */
+	PORTCR(209, 0xe60520d1), /* PORT209CR */
+
+	PORTCR(210, 0xe60520d2), /* PORT210CR */
+	PORTCR(211, 0xe60520d3), /* PORT211CR */
+	PORTCR(212, 0xe60520d4), /* PORT212CR */
+	PORTCR(213, 0xe60520d5), /* PORT213CR */
+	PORTCR(214, 0xe60520d6), /* PORT214CR */
+	PORTCR(215, 0xe60520d7), /* PORT215CR */
+	PORTCR(216, 0xe60520d8), /* PORT216CR */
+	PORTCR(217, 0xe60520d9), /* PORT217CR */
+	PORTCR(218, 0xe60520da), /* PORT218CR */
+	PORTCR(219, 0xe60520db), /* PORT219CR */
+
+	PORTCR(220, 0xe60520dc), /* PORT220CR */
+	PORTCR(221, 0xe60520dd), /* PORT221CR */
+	PORTCR(222, 0xe60520de), /* PORT222CR */
+	PORTCR(223, 0xe60520df), /* PORT223CR */
+	PORTCR(224, 0xe60520e0), /* PORT224CR */
+	PORTCR(225, 0xe60520e1), /* PORT225CR */
+	PORTCR(226, 0xe60520e2), /* PORT226CR */
+	PORTCR(227, 0xe60520e3), /* PORT227CR */
+	PORTCR(228, 0xe60520e4), /* PORT228CR */
+	PORTCR(229, 0xe60520e5), /* PORT229CR */
+
+	PORTCR(230, 0xe60520e6), /* PORT230CR */
+	PORTCR(231, 0xe60520e7), /* PORT231CR */
+	PORTCR(232, 0xe60520e8), /* PORT232CR */
+	PORTCR(233, 0xe60520e9), /* PORT233CR */
+	PORTCR(234, 0xe60520ea), /* PORT234CR */
+	PORTCR(235, 0xe60520eb), /* PORT235CR */
+	PORTCR(236, 0xe60530ec), /* PORT236CR */
+	PORTCR(237, 0xe60530ed), /* PORT237CR */
+	PORTCR(238, 0xe60530ee), /* PORT238CR */
+	PORTCR(239, 0xe60530ef), /* PORT239CR */
+
+	PORTCR(240, 0xe60530f0), /* PORT240CR */
+	PORTCR(241, 0xe60530f1), /* PORT241CR */
+	PORTCR(242, 0xe60530f2), /* PORT242CR */
+	PORTCR(243, 0xe60530f3), /* PORT243CR */
+	PORTCR(244, 0xe60530f4), /* PORT244CR */
+	PORTCR(245, 0xe60530f5), /* PORT245CR */
+	PORTCR(246, 0xe60530f6), /* PORT246CR */
+	PORTCR(247, 0xe60530f7), /* PORT247CR */
+	PORTCR(248, 0xe60530f8), /* PORT248CR */
+	PORTCR(249, 0xe60530f9), /* PORT249CR */
+
+	PORTCR(250, 0xe60530fa), /* PORT250CR */
+	PORTCR(251, 0xe60530fb), /* PORT251CR */
+	PORTCR(252, 0xe60530fc), /* PORT252CR */
+	PORTCR(253, 0xe60530fd), /* PORT253CR */
+	PORTCR(254, 0xe60530fe), /* PORT254CR */
+	PORTCR(255, 0xe60530ff), /* PORT255CR */
+	PORTCR(256, 0xe6053100), /* PORT256CR */
+	PORTCR(257, 0xe6053101), /* PORT257CR */
+	PORTCR(258, 0xe6053102), /* PORT258CR */
+	PORTCR(259, 0xe6053103), /* PORT259CR */
+
+	PORTCR(260, 0xe6053104), /* PORT260CR */
+	PORTCR(261, 0xe6053105), /* PORT261CR */
+	PORTCR(262, 0xe6053106), /* PORT262CR */
+	PORTCR(263, 0xe6053107), /* PORT263CR */
+	PORTCR(264, 0xe6053108), /* PORT264CR */
+	PORTCR(265, 0xe6053109), /* PORT265CR */
+	PORTCR(266, 0xe605310a), /* PORT266CR */
+	PORTCR(267, 0xe605310b), /* PORT267CR */
+	PORTCR(268, 0xe605310c), /* PORT268CR */
+	PORTCR(269, 0xe605310d), /* PORT269CR */
+
+	PORTCR(270, 0xe605310e), /* PORT270CR */
+	PORTCR(271, 0xe605310f), /* PORT271CR */
+	PORTCR(272, 0xe6053110), /* PORT272CR */
+
+	{ PINMUX_CFG_REG("MSELBCR", 0xe6058024, 32, 1) {
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		MSELBCR_MSEL2_0, MSELBCR_MSEL2_1,
+		0, 0,
+		0, 0 }
+	},
+	{ },
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+	{ PINMUX_DATA_REG("PORTL031_000DR", 0xe6054000, 32) {
+		PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA,
+		PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA,
+		PORT23_DATA, PORT22_DATA, PORT21_DATA, PORT20_DATA,
+		PORT19_DATA, PORT18_DATA, PORT17_DATA, PORT16_DATA,
+		PORT15_DATA, PORT14_DATA, PORT13_DATA, PORT12_DATA,
+		PORT11_DATA, PORT10_DATA, PORT9_DATA, PORT8_DATA,
+		PORT7_DATA, PORT6_DATA, PORT5_DATA, PORT4_DATA,
+		PORT3_DATA, PORT2_DATA, PORT1_DATA, PORT0_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTL063_032DR", 0xe6054004, 32) {
+		PORT63_DATA, PORT62_DATA, PORT61_DATA, PORT60_DATA,
+		PORT59_DATA, PORT58_DATA, PORT57_DATA, PORT56_DATA,
+		PORT55_DATA, PORT54_DATA, PORT53_DATA, PORT52_DATA,
+		PORT51_DATA, PORT50_DATA, PORT49_DATA, PORT48_DATA,
+		PORT47_DATA, PORT46_DATA, PORT45_DATA, PORT44_DATA,
+		PORT43_DATA, PORT42_DATA, PORT41_DATA, PORT40_DATA,
+		PORT39_DATA, PORT38_DATA, PORT37_DATA, PORT36_DATA,
+		PORT35_DATA, PORT34_DATA, PORT33_DATA, PORT32_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTL095_064DR", 0xe6054008, 32) {
+		PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA,
+		PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA,
+		PORT87_DATA, PORT86_DATA, PORT85_DATA, PORT84_DATA,
+		PORT83_DATA, PORT82_DATA, PORT81_DATA, PORT80_DATA,
+		PORT79_DATA, PORT78_DATA, PORT77_DATA, PORT76_DATA,
+		PORT75_DATA, PORT74_DATA, PORT73_DATA, PORT72_DATA,
+		PORT71_DATA, PORT70_DATA, PORT69_DATA, PORT68_DATA,
+		PORT67_DATA, PORT66_DATA, PORT65_DATA, PORT64_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTD127_096DR", 0xe6055004, 32) {
+		PORT127_DATA, PORT126_DATA, PORT125_DATA, PORT124_DATA,
+		PORT123_DATA, PORT122_DATA, PORT121_DATA, PORT120_DATA,
+		PORT119_DATA, PORT118_DATA, PORT117_DATA, PORT116_DATA,
+		PORT115_DATA, PORT114_DATA, PORT113_DATA, PORT112_DATA,
+		PORT111_DATA, PORT110_DATA, PORT109_DATA, PORT108_DATA,
+		PORT107_DATA, PORT106_DATA, PORT105_DATA, PORT104_DATA,
+		PORT103_DATA, PORT102_DATA, PORT101_DATA, PORT100_DATA,
+		PORT99_DATA, PORT98_DATA, PORT97_DATA, PORT96_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTD159_128DR", 0xe6055008, 32) {
+		PORT159_DATA, PORT158_DATA, PORT157_DATA, PORT156_DATA,
+		PORT155_DATA, PORT154_DATA, PORT153_DATA, PORT152_DATA,
+		PORT151_DATA, PORT150_DATA, PORT149_DATA, PORT148_DATA,
+		PORT147_DATA, PORT146_DATA, PORT145_DATA, PORT144_DATA,
+		PORT143_DATA, PORT142_DATA, PORT141_DATA, PORT140_DATA,
+		PORT139_DATA, PORT138_DATA, PORT137_DATA, PORT136_DATA,
+		PORT135_DATA, PORT134_DATA, PORT133_DATA, PORT132_DATA,
+		PORT131_DATA, PORT130_DATA, PORT129_DATA, PORT128_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTR191_160DR", 0xe6056000, 32) {
+		PORT191_DATA, PORT190_DATA, PORT189_DATA, PORT188_DATA,
+		PORT187_DATA, PORT186_DATA, PORT185_DATA, PORT184_DATA,
+		PORT183_DATA, PORT182_DATA, PORT181_DATA, PORT180_DATA,
+		PORT179_DATA, PORT178_DATA, PORT177_DATA, PORT176_DATA,
+		PORT175_DATA, PORT174_DATA, PORT173_DATA, PORT172_DATA,
+		PORT171_DATA, PORT170_DATA, PORT169_DATA, PORT168_DATA,
+		PORT167_DATA, PORT166_DATA, PORT165_DATA, PORT164_DATA,
+		PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTR223_192DR", 0xe6056004, 32) {
+		PORT223_DATA, PORT222_DATA, PORT221_DATA, PORT220_DATA,
+		PORT219_DATA, PORT218_DATA, PORT217_DATA, PORT216_DATA,
+		PORT215_DATA, PORT214_DATA, PORT213_DATA, PORT212_DATA,
+		PORT211_DATA, PORT210_DATA, PORT209_DATA, PORT208_DATA,
+		PORT207_DATA, PORT206_DATA, PORT205_DATA, PORT204_DATA,
+		PORT203_DATA, PORT202_DATA, PORT201_DATA, PORT200_DATA,
+		PORT199_DATA, PORT198_DATA, PORT197_DATA, PORT196_DATA,
+		PORT195_DATA, PORT194_DATA, PORT193_DATA, PORT192_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTU255_224DR", 0xe6057000, 32) {
+		PORT255_DATA, PORT254_DATA, PORT253_DATA, PORT252_DATA,
+		PORT251_DATA, PORT250_DATA, PORT249_DATA, PORT248_DATA,
+		PORT247_DATA, PORT246_DATA, PORT245_DATA, PORT244_DATA,
+		PORT243_DATA, PORT242_DATA, PORT241_DATA, PORT240_DATA,
+		PORT239_DATA, PORT238_DATA, PORT237_DATA, PORT236_DATA,
+		PORT235_DATA, PORT234_DATA, PORT233_DATA, PORT232_DATA,
+		PORT231_DATA, PORT230_DATA, PORT229_DATA, PORT228_DATA,
+		PORT227_DATA, PORT226_DATA, PORT225_DATA, PORT224_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTU287_256DR", 0xe6057004, 32) {
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, PORT272_DATA,
+		PORT271_DATA, PORT270_DATA, PORT269_DATA, PORT268_DATA,
+		PORT267_DATA, PORT266_DATA, PORT265_DATA, PORT264_DATA,
+		PORT263_DATA, PORT262_DATA, PORT261_DATA, PORT260_DATA,
+		PORT259_DATA, PORT258_DATA, PORT257_DATA, PORT256_DATA }
+	},
+	{ },
+};
+
+static struct pinmux_info sh7367_pinmux_info = {
+	.name = "sh7367_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 },
+	.input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_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_PORT0,
+	.last_gpio = GPIO_FN_DIVLOCK,
+
+	.gpios = pinmux_gpios,
+	.cfg_regs = pinmux_config_regs,
+	.data_regs = pinmux_data_regs,
+
+	.gpio_data = pinmux_data,
+	.gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+void sh7367_pinmux_init(void)
+{
+	register_pinmux(&sh7367_pinmux_info);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/pfc-sh7372.c linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/pfc-sh7372.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/pfc-sh7372.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/pfc-sh7372.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1637 @@
+/*
+ * sh7372 processor support - PFC hardware block
+ *
+ * Copyright (C) 2010  Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on
+ * sh7367 processor support - PFC hardware block
+ * Copyright (C) 2010  Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <mach/sh7372.h>
+
+#define _1(fn, pfx, sfx) fn(pfx, sfx)
+
+#define _10(fn, pfx, sfx)				\
+	_1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx),	\
+	_1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx),	\
+	_1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx),	\
+	_1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx),	\
+	_1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
+
+#define _80(fn, pfx, sfx)				\
+	_10(fn, pfx##1, sfx),	_10(fn, pfx##2, sfx),	\
+	_10(fn, pfx##3, sfx),	_10(fn, pfx##4, sfx),	\
+	_10(fn, pfx##5, sfx),	_10(fn, pfx##6, sfx),	\
+	_10(fn, pfx##7, sfx),	_10(fn, pfx##8, sfx)
+
+#define _190(fn, pfx, sfx) \
+	_10(fn, pfx, sfx), _80(fn, pfx, sfx), _10(fn, pfx##9, sfx), \
+	_10(fn, pfx##10, sfx), _80(fn, pfx##1, sfx), _1(fn, pfx##190, sfx)
+
+#define _PORT(pfx, sfx) pfx##_##sfx
+#define PORT_ALL(str) _190(_PORT, PORT, str)
+
+enum {
+	PINMUX_RESERVED = 0,
+
+	/* PORT0_DATA -> PORT190_DATA */
+	PINMUX_DATA_BEGIN,
+	PORT_ALL(DATA),
+	PINMUX_DATA_END,
+
+	/* PORT0_IN -> PORT190_IN */
+	PINMUX_INPUT_BEGIN,
+	PORT_ALL(IN),
+	PINMUX_INPUT_END,
+
+	/* PORT0_IN_PU -> PORT190_IN_PU */
+	PINMUX_INPUT_PULLUP_BEGIN,
+	PORT_ALL(IN_PU),
+	PINMUX_INPUT_PULLUP_END,
+
+	/* PORT0_IN_PD -> PORT190_IN_PD */
+	PINMUX_INPUT_PULLDOWN_BEGIN,
+	PORT_ALL(IN_PD),
+	PINMUX_INPUT_PULLDOWN_END,
+
+	/* PORT0_OUT -> PORT190_OUT */
+	PINMUX_OUTPUT_BEGIN,
+	PORT_ALL(OUT),
+	PINMUX_OUTPUT_END,
+
+	PINMUX_FUNCTION_BEGIN,
+	PORT_ALL(FN_IN),	/* PORT0_FN_IN	-> PORT190_FN_IN */
+	PORT_ALL(FN_OUT),	/* PORT0_FN_OUT	-> PORT190_FN_OUT */
+	PORT_ALL(FN0),		/* PORT0_FN0	-> PORT190_FN0 */
+	PORT_ALL(FN1),		/* PORT0_FN1	-> PORT190_FN1 */
+	PORT_ALL(FN2),		/* PORT0_FN2	-> PORT190_FN2 */
+	PORT_ALL(FN3),		/* PORT0_FN3	-> PORT190_FN3 */
+	PORT_ALL(FN4),		/* PORT0_FN4	-> PORT190_FN4 */
+	PORT_ALL(FN5),		/* PORT0_FN5	-> PORT190_FN5 */
+	PORT_ALL(FN6),		/* PORT0_FN6	-> PORT190_FN6 */
+	PORT_ALL(FN7),		/* PORT0_FN7	-> PORT190_FN7 */
+
+	MSEL1CR_31_0,	MSEL1CR_31_1,
+	MSEL1CR_30_0,	MSEL1CR_30_1,
+	MSEL1CR_29_0,	MSEL1CR_29_1,
+	MSEL1CR_28_0,	MSEL1CR_28_1,
+	MSEL1CR_27_0,	MSEL1CR_27_1,
+	MSEL1CR_26_0,	MSEL1CR_26_1,
+	MSEL1CR_16_0,	MSEL1CR_16_1,
+	MSEL1CR_15_0,	MSEL1CR_15_1,
+	MSEL1CR_14_0,	MSEL1CR_14_1,
+	MSEL1CR_13_0,	MSEL1CR_13_1,
+	MSEL1CR_12_0,	MSEL1CR_12_1,
+	MSEL1CR_9_0,	MSEL1CR_9_1,
+	MSEL1CR_8_0,	MSEL1CR_8_1,
+	MSEL1CR_7_0,	MSEL1CR_7_1,
+	MSEL1CR_6_0,	MSEL1CR_6_1,
+	MSEL1CR_4_0,	MSEL1CR_4_1,
+	MSEL1CR_3_0,	MSEL1CR_3_1,
+	MSEL1CR_2_0,	MSEL1CR_2_1,
+	MSEL1CR_0_0,	MSEL1CR_0_1,
+
+	MSEL3CR_27_0,	MSEL3CR_27_1,
+	MSEL3CR_26_0,	MSEL3CR_26_1,
+	MSEL3CR_21_0,	MSEL3CR_21_1,
+	MSEL3CR_20_0,	MSEL3CR_20_1,
+	MSEL3CR_15_0,	MSEL3CR_15_1,
+	MSEL3CR_9_0,	MSEL3CR_9_1,
+	MSEL3CR_6_0,	MSEL3CR_6_1,
+
+	MSEL4CR_19_0,	MSEL4CR_19_1,
+	MSEL4CR_18_0,	MSEL4CR_18_1,
+	MSEL4CR_17_0,	MSEL4CR_17_1,
+	MSEL4CR_16_0,	MSEL4CR_16_1,
+	MSEL4CR_15_0,	MSEL4CR_15_1,
+	MSEL4CR_14_0,	MSEL4CR_14_1,
+	MSEL4CR_10_0,	MSEL4CR_10_1,
+	MSEL4CR_6_0,	MSEL4CR_6_1,
+	MSEL4CR_4_0,	MSEL4CR_4_1,
+	MSEL4CR_1_0,	MSEL4CR_1_1,
+	PINMUX_FUNCTION_END,
+
+	PINMUX_MARK_BEGIN,
+
+	/* IRQ */
+	IRQ0_6_MARK,	IRQ0_162_MARK,	IRQ1_MARK,	IRQ2_4_MARK,
+	IRQ2_5_MARK,	IRQ3_8_MARK,	IRQ3_16_MARK,	IRQ4_17_MARK,
+	IRQ4_163_MARK,	IRQ5_MARK,	IRQ6_39_MARK,	IRQ6_164_MARK,
+	IRQ7_40_MARK,	IRQ7_167_MARK,	IRQ8_41_MARK,	IRQ8_168_MARK,
+	IRQ9_42_MARK,	IRQ9_169_MARK,	IRQ10_MARK,	IRQ11_MARK,
+	IRQ12_80_MARK,	IRQ12_137_MARK,	IRQ13_81_MARK,	IRQ13_145_MARK,
+	IRQ14_82_MARK,	IRQ14_146_MARK,	IRQ15_83_MARK,	IRQ15_147_MARK,
+	IRQ16_84_MARK,	IRQ16_170_MARK,	IRQ17_MARK,	IRQ18_MARK,
+	IRQ19_MARK,	IRQ20_MARK,	IRQ21_MARK,	IRQ22_MARK,
+	IRQ23_MARK,	IRQ24_MARK,	IRQ25_MARK,	IRQ26_121_MARK,
+	IRQ26_172_MARK,	IRQ27_122_MARK,	IRQ27_180_MARK,	IRQ28_123_MARK,
+	IRQ28_181_MARK,	IRQ29_129_MARK,	IRQ29_182_MARK,	IRQ30_130_MARK,
+	IRQ30_183_MARK,	IRQ31_138_MARK,	IRQ31_184_MARK,
+
+	/* MSIOF0 */
+	MSIOF0_TSYNC_MARK,	MSIOF0_TSCK_MARK,	MSIOF0_RXD_MARK,
+	MSIOF0_RSCK_MARK,	MSIOF0_RSYNC_MARK,	MSIOF0_MCK0_MARK,
+	MSIOF0_MCK1_MARK,	MSIOF0_SS1_MARK,	MSIOF0_SS2_MARK,
+	MSIOF0_TXD_MARK,
+
+	/* MSIOF1 */
+	MSIOF1_TSCK_39_MARK,	MSIOF1_TSYNC_40_MARK,
+	MSIOF1_TSCK_88_MARK,	MSIOF1_TSYNC_89_MARK,
+	MSIOF1_TXD_41_MARK,	MSIOF1_RXD_42_MARK,
+	MSIOF1_TXD_90_MARK,	MSIOF1_RXD_91_MARK,
+	MSIOF1_SS1_43_MARK,	MSIOF1_SS2_44_MARK,
+	MSIOF1_SS1_92_MARK,	MSIOF1_SS2_93_MARK,
+	MSIOF1_RSCK_MARK,	MSIOF1_RSYNC_MARK,
+	MSIOF1_MCK0_MARK,	MSIOF1_MCK1_MARK,
+
+	/* MSIOF2 */
+	MSIOF2_RSCK_MARK,	MSIOF2_RSYNC_MARK,	MSIOF2_MCK0_MARK,
+	MSIOF2_MCK1_MARK,	MSIOF2_SS1_MARK,	MSIOF2_SS2_MARK,
+	MSIOF2_TSYNC_MARK,	MSIOF2_TSCK_MARK,	MSIOF2_RXD_MARK,
+	MSIOF2_TXD_MARK,
+
+	/* MSIOF3 */
+	BBIF1_RXD_MARK,		BBIF1_TSYNC_MARK,	BBIF1_TSCK_MARK,
+	BBIF1_TXD_MARK,		BBIF1_RSCK_MARK,	BBIF1_RSYNC_MARK,
+	BBIF1_FLOW_MARK,	BB_RX_FLOW_N_MARK,
+
+	/* MSIOF4 */
+	BBIF2_TSCK1_MARK,	BBIF2_TSYNC1_MARK,
+	BBIF2_TXD1_MARK,	BBIF2_RXD_MARK,
+
+	/* FSI */
+	FSIACK_MARK,	FSIBCK_MARK,		FSIAILR_MARK,	FSIAIBT_MARK,
+	FSIAISLD_MARK,	FSIAOMC_MARK,		FSIAOLR_MARK,	FSIAOBT_MARK,
+	FSIAOSLD_MARK,	FSIASPDIF_11_MARK,	FSIASPDIF_15_MARK,
+
+	/* FMSI */
+	FMSOCK_MARK,	FMSOOLR_MARK,	FMSIOLR_MARK,	FMSOOBT_MARK,
+	FMSIOBT_MARK,	FMSOSLD_MARK,	FMSOILR_MARK,	FMSIILR_MARK,
+	FMSOIBT_MARK,	FMSIIBT_MARK,	FMSISLD_MARK,	FMSICK_MARK,
+
+	/* SCIFA0 */
+	SCIFA0_TXD_MARK,	SCIFA0_RXD_MARK,	SCIFA0_SCK_MARK,
+	SCIFA0_RTS_MARK,	SCIFA0_CTS_MARK,
+
+	/* SCIFA1 */
+	SCIFA1_TXD_MARK,	SCIFA1_RXD_MARK,	SCIFA1_SCK_MARK,
+	SCIFA1_RTS_MARK,	SCIFA1_CTS_MARK,
+
+	/* SCIFA2 */
+	SCIFA2_CTS1_MARK,	SCIFA2_RTS1_MARK,	SCIFA2_TXD1_MARK,
+	SCIFA2_RXD1_MARK,	SCIFA2_SCK1_MARK,
+
+	/* SCIFA3 */
+	SCIFA3_CTS_43_MARK,	SCIFA3_CTS_140_MARK,	SCIFA3_RTS_44_MARK,
+	SCIFA3_RTS_141_MARK,	SCIFA3_SCK_MARK,	SCIFA3_TXD_MARK,
+	SCIFA3_RXD_MARK,
+
+	/* SCIFA4 */
+	SCIFA4_RXD_MARK,	SCIFA4_TXD_MARK,
+
+	/* SCIFA5 */
+	SCIFA5_RXD_MARK,	SCIFA5_TXD_MARK,
+
+	/* SCIFB */
+	SCIFB_SCK_MARK,	SCIFB_RTS_MARK,	SCIFB_CTS_MARK,
+	SCIFB_TXD_MARK,	SCIFB_RXD_MARK,
+
+	/* CEU */
+	VIO_HD_MARK,	VIO_CKO1_MARK,	VIO_CKO2_MARK,	VIO_VD_MARK,
+	VIO_CLK_MARK,	VIO_FIELD_MARK,	VIO_CKO_MARK,
+	VIO_D0_MARK,	VIO_D1_MARK,	VIO_D2_MARK,	VIO_D3_MARK,
+	VIO_D4_MARK,	VIO_D5_MARK,	VIO_D6_MARK,	VIO_D7_MARK,
+	VIO_D8_MARK,	VIO_D9_MARK,	VIO_D10_MARK,	VIO_D11_MARK,
+	VIO_D12_MARK,	VIO_D13_MARK,	VIO_D14_MARK,	VIO_D15_MARK,
+
+	/* USB0 */
+	IDIN_0_MARK,	EXTLP_0_MARK,	OVCN2_0_MARK,	PWEN_0_MARK,
+	OVCN_0_MARK,	VBUS0_0_MARK,
+
+	/* USB1 */
+	IDIN_1_18_MARK,		IDIN_1_113_MARK,
+	PWEN_1_115_MARK,	PWEN_1_138_MARK,
+	OVCN_1_114_MARK,	OVCN_1_162_MARK,
+	EXTLP_1_MARK,		OVCN2_1_MARK,
+	VBUS0_1_MARK,
+
+	/* GPIO */
+	GPI0_MARK,	GPI1_MARK,	GPO0_MARK,	GPO1_MARK,
+
+	/* BSC */
+	BS_MARK,	WE1_MARK,
+	CKO_MARK,	WAIT_MARK,	RDWR_MARK,
+
+	A0_MARK,	A1_MARK,	A2_MARK,	A3_MARK,
+	A6_MARK,	A7_MARK,	A8_MARK,	A9_MARK,
+	A10_MARK,	A11_MARK,	A12_MARK,	A13_MARK,
+	A14_MARK,	A15_MARK,	A16_MARK,	A17_MARK,
+	A18_MARK,	A19_MARK,	A20_MARK,	A21_MARK,
+	A22_MARK,	A23_MARK,	A24_MARK,	A25_MARK,
+	A26_MARK,
+
+	CS0_MARK,	CS2_MARK,	CS4_MARK,
+	CS5A_MARK,	CS5B_MARK,	CS6A_MARK,
+
+	/* BSC/FLCTL */
+	RD_FSC_MARK,	WE0_FWE_MARK,	A4_FOE_MARK,	A5_FCDE_MARK,
+	D0_NAF0_MARK,	D1_NAF1_MARK,	D2_NAF2_MARK,	D3_NAF3_MARK,
+	D4_NAF4_MARK,	D5_NAF5_MARK,	D6_NAF6_MARK,	D7_NAF7_MARK,
+	D8_NAF8_MARK,	D9_NAF9_MARK,	D10_NAF10_MARK,	D11_NAF11_MARK,
+	D12_NAF12_MARK,	D13_NAF13_MARK,	D14_NAF14_MARK,	D15_NAF15_MARK,
+
+	/* MMCIF(1) */
+	MMCD0_0_MARK,	MMCD0_1_MARK,	MMCD0_2_MARK,	MMCD0_3_MARK,
+	MMCD0_4_MARK,	MMCD0_5_MARK,	MMCD0_6_MARK,	MMCD0_7_MARK,
+	MMCCMD0_MARK,	MMCCLK0_MARK,
+
+	/* MMCIF(2) */
+	MMCD1_0_MARK,	MMCD1_1_MARK,	MMCD1_2_MARK,	MMCD1_3_MARK,
+	MMCD1_4_MARK,	MMCD1_5_MARK,	MMCD1_6_MARK,	MMCD1_7_MARK,
+	MMCCLK1_MARK,	MMCCMD1_MARK,
+
+	/* SPU2 */
+	VINT_I_MARK,
+
+	/* FLCTL */
+	FCE1_MARK,	FCE0_MARK,	FRB_MARK,
+
+	/* HSI */
+	GP_RX_FLAG_MARK,	GP_RX_DATA_MARK,	GP_TX_READY_MARK,
+	GP_RX_WAKE_MARK,	MP_TX_FLAG_MARK,	MP_TX_DATA_MARK,
+	MP_RX_READY_MARK,	MP_TX_WAKE_MARK,
+
+	/* MFI */
+	MFIv6_MARK,
+	MFIv4_MARK,
+
+	MEMC_CS0_MARK,			MEMC_BUSCLK_MEMC_A0_MARK,
+	MEMC_CS1_MEMC_A1_MARK,		MEMC_ADV_MEMC_DREQ0_MARK,
+	MEMC_WAIT_MEMC_DREQ1_MARK,	MEMC_NOE_MARK,
+	MEMC_NWE_MARK,			MEMC_INT_MARK,
+
+	MEMC_AD0_MARK,	MEMC_AD1_MARK,	MEMC_AD2_MARK,
+	MEMC_AD3_MARK,	MEMC_AD4_MARK,	MEMC_AD5_MARK,
+	MEMC_AD6_MARK,	MEMC_AD7_MARK,	MEMC_AD8_MARK,
+	MEMC_AD9_MARK,	MEMC_AD10_MARK,	MEMC_AD11_MARK,
+	MEMC_AD12_MARK,	MEMC_AD13_MARK,	MEMC_AD14_MARK,
+	MEMC_AD15_MARK,
+
+	/* SIM */
+	SIM_RST_MARK,	SIM_CLK_MARK,	SIM_D_MARK,
+
+	/* TPU */
+	TPU0TO0_MARK,		TPU0TO1_MARK,
+	TPU0TO2_93_MARK,	TPU0TO2_99_MARK,
+	TPU0TO3_MARK,
+
+	/* I2C2 */
+	I2C_SCL2_MARK,	I2C_SDA2_MARK,
+
+	/* I2C3(1) */
+	I2C_SCL3_MARK,	I2C_SDA3_MARK,
+
+	/* I2C3(2) */
+	I2C_SCL3S_MARK,	I2C_SDA3S_MARK,
+
+	/* I2C4(2) */
+	I2C_SCL4_MARK,	I2C_SDA4_MARK,
+
+	/* I2C4(2) */
+	I2C_SCL4S_MARK,	I2C_SDA4S_MARK,
+
+	/* KEYSC */
+	KEYOUT0_MARK,	KEYIN0_121_MARK,	KEYIN0_136_MARK,
+	KEYOUT1_MARK,	KEYIN1_122_MARK,	KEYIN1_135_MARK,
+	KEYOUT2_MARK,	KEYIN2_123_MARK,	KEYIN2_134_MARK,
+	KEYOUT3_MARK,	KEYIN3_124_MARK,	KEYIN3_133_MARK,
+	KEYOUT4_MARK,	KEYIN4_MARK,
+	KEYOUT5_MARK,	KEYIN5_MARK,
+	KEYOUT6_MARK,	KEYIN6_MARK,
+	KEYOUT7_MARK,	KEYIN7_MARK,
+
+	/* LCDC */
+	LCDC0_SELECT_MARK,
+	LCDC1_SELECT_MARK,
+	LCDHSYN_MARK,	LCDCS_MARK,	LCDVSYN_MARK,	LCDDCK_MARK,
+	LCDWR_MARK,	LCDRD_MARK,	LCDDISP_MARK,	LCDRS_MARK,
+	LCDLCLK_MARK,	LCDDON_MARK,
+
+	LCDD0_MARK,	LCDD1_MARK,	LCDD2_MARK,	LCDD3_MARK,
+	LCDD4_MARK,	LCDD5_MARK,	LCDD6_MARK,	LCDD7_MARK,
+	LCDD8_MARK,	LCDD9_MARK,	LCDD10_MARK,	LCDD11_MARK,
+	LCDD12_MARK,	LCDD13_MARK,	LCDD14_MARK,	LCDD15_MARK,
+	LCDD16_MARK,	LCDD17_MARK,	LCDD18_MARK,	LCDD19_MARK,
+	LCDD20_MARK,	LCDD21_MARK,	LCDD22_MARK,	LCDD23_MARK,
+
+	/* IRDA */
+	IRDA_OUT_MARK,	IRDA_IN_MARK,	IRDA_FIRSEL_MARK,
+	IROUT_139_MARK,	IROUT_140_MARK,
+
+	/* TSIF1 */
+	TS0_1SELECT_MARK,
+	TS0_2SELECT_MARK,
+	TS1_1SELECT_MARK,
+	TS1_2SELECT_MARK,
+
+	TS_SPSYNC1_MARK,	TS_SDAT1_MARK,
+	TS_SDEN1_MARK,		TS_SCK1_MARK,
+
+	/* TSIF2 */
+	TS_SPSYNC2_MARK,	TS_SDAT2_MARK,
+	TS_SDEN2_MARK,		TS_SCK2_MARK,
+
+	/* HDMI */
+	HDMI_HPD_MARK,	HDMI_CEC_MARK,
+
+	/* SDHI0 */
+	SDHICLK0_MARK,	SDHICD0_MARK,
+	SDHICMD0_MARK,	SDHIWP0_MARK,
+	SDHID0_0_MARK,	SDHID0_1_MARK,
+	SDHID0_2_MARK,	SDHID0_3_MARK,
+
+	/* SDHI1 */
+	SDHICLK1_MARK,	SDHICMD1_MARK,	SDHID1_0_MARK,
+	SDHID1_1_MARK,	SDHID1_2_MARK,	SDHID1_3_MARK,
+
+	/* SDHI2 */
+	SDHICLK2_MARK,	SDHICMD2_MARK,	SDHID2_0_MARK,
+	SDHID2_1_MARK,	SDHID2_2_MARK,	SDHID2_3_MARK,
+
+	/* SDENC */
+	SDENC_CPG_MARK,
+	SDENC_DV_CLKI_MARK,
+
+	PINMUX_MARK_END,
+};
+
+/* PORT_DATA_I_PD(nr) */
+#define _I___D(nr)			     \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+		    PORT##nr##_IN, PORT##nr##_IN_PD)
+
+/* PORT_DATA_I_PU(nr) */
+#define _I__U_(nr)			     \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+		    PORT##nr##_IN, PORT##nr##_IN_PU)
+
+/* PORT_DATA_I_PU_PD(nr) */
+#define _I__UD(nr)			     \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+		    PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+/* PORT_DATA_O(nr) */
+#define __O___(nr)							\
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT)
+
+/* PORT_DATA_IO(nr) */
+#define _IO___(nr)				     \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+		    PORT##nr##_IN)
+
+/* PORT_DATA_IO_PD(nr) */
+#define _IO__D(nr)					     \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+		    PORT##nr##_IN, PORT##nr##_IN_PD)
+
+/* PORT_DATA_IO_PU(nr) */
+#define _IO_U_(nr)					     \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+		    PORT##nr##_IN, PORT##nr##_IN_PU)
+
+/* PORT_DATA_IO_PU_PD(nr) */
+#define _IO_UD(nr)					     \
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+		    PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+
+static pinmux_enum_t pinmux_data[] = {
+
+	/* specify valid pin states for each pin in GPIO mode */
+
+	_IO__D(0), _IO__D(1), __O___(2), _I___D(3), _I___D(4),
+	_I___D(5), _IO_UD(6), _I___D(7), _IO__D(8), __O___(9),
+
+	__O___(10), __O___(11), _IO_UD(12), _IO__D(13), _IO__D(14),
+	__O___(15), _IO__D(16), _IO__D(17), _I___D(18), _IO___(19),
+
+	_IO___(20), _IO___(21), _IO___(22), _IO___(23), _IO___(24),
+	_IO___(25), _IO___(26), _IO___(27), _IO___(28), _IO___(29),
+
+	_IO___(30), _IO___(31), _IO___(32), _IO___(33), _IO___(34),
+	_IO___(35), _IO___(36), _IO___(37), _IO___(38), _IO___(39),
+
+	_IO___(40), _IO___(41), _IO___(42), _IO___(43), _IO___(44),
+	_IO___(45), _IO_U_(46), _IO_U_(47), _IO_U_(48), _IO_U_(49),
+
+	_IO_U_(50), _IO_U_(51), _IO_U_(52), _IO_U_(53), _IO_U_(54),
+	_IO_U_(55), _IO_U_(56), _IO_U_(57), _IO_U_(58), _IO_U_(59),
+
+	_IO_U_(60), _IO_U_(61), _IO___(62), __O___(63), __O___(64),
+	_IO_U_(65), __O___(66), _IO_U_(67), __O___(68), _IO___(69), /*66?*/
+
+	_IO___(70), _IO___(71), __O___(72), _I__U_(73), _I__UD(74),
+	_IO_UD(75), _IO_UD(76), _IO_UD(77), _IO_UD(78), _IO_UD(79),
+
+	_IO_UD(80), _IO_UD(81), _IO_UD(82), _IO_UD(83), _IO_UD(84),
+	_IO_UD(85), _IO_UD(86), _IO_UD(87), _IO_UD(88), _IO_UD(89),
+
+	_IO_UD(90), _IO_UD(91), _IO_UD(92), _IO_UD(93), _IO_UD(94),
+	_IO_UD(95), _IO_U_(96), _IO_UD(97), _IO_UD(98), __O___(99), /*99?*/
+
+	_IO__D(100), _IO__D(101), _IO__D(102), _IO__D(103), _IO__D(104),
+	_IO__D(105), _IO_U_(106), _IO_U_(107), _IO_U_(108), _IO_U_(109),
+
+	_IO_U_(110), _IO_U_(111), _IO__D(112), _IO__D(113), _IO_U_(114),
+	_IO_U_(115), _IO_U_(116), _IO_U_(117), _IO_U_(118), _IO_U_(119),
+
+	_IO_U_(120), _IO__D(121), _IO__D(122), _IO__D(123), _IO__D(124),
+	_IO__D(125), _IO__D(126), _IO__D(127), _IO__D(128), _IO_UD(129),
+
+	_IO_UD(130), _IO_UD(131), _IO_UD(132), _IO_UD(133), _IO_UD(134),
+	_IO_UD(135), _IO__D(136), _IO__D(137), _IO__D(138), _IO__D(139),
+
+	_IO__D(140), _IO__D(141), _IO__D(142), _IO_UD(143), _IO__D(144),
+	_IO__D(145), _IO__D(146), _IO__D(147), _IO__D(148), _IO__D(149),
+
+	_IO__D(150), _IO__D(151), _IO_UD(152), _I___D(153), _IO_UD(154),
+	_I___D(155), _IO__D(156), _IO__D(157), _I___D(158), _IO__D(159),
+
+	__O___(160), _IO__D(161), _IO__D(162), _IO__D(163), _I___D(164),
+	_IO__D(165), _I___D(166), _I___D(167), _I___D(168), _I___D(169),
+
+	_I___D(170), __O___(171), _IO_UD(172), _IO_UD(173), _IO_UD(174),
+	_IO_UD(175), _IO_UD(176), _IO_UD(177), _IO_UD(178), __O___(179),
+
+	_IO_UD(180), _IO_UD(181), _IO_UD(182), _IO_UD(183), _IO_UD(184),
+	__O___(185), _IO_UD(186), _IO_UD(187), _IO_UD(188), _IO_UD(189),
+
+	_IO_UD(190),
+
+	/* IRQ */
+	PINMUX_DATA(IRQ0_6_MARK,	PORT6_FN0, 	MSEL1CR_0_0),
+	PINMUX_DATA(IRQ0_162_MARK,	PORT162_FN0,	MSEL1CR_0_1),
+	PINMUX_DATA(IRQ1_MARK,		PORT12_FN0),
+	PINMUX_DATA(IRQ2_4_MARK,	PORT4_FN0,	MSEL1CR_2_0),
+	PINMUX_DATA(IRQ2_5_MARK,	PORT5_FN0,	MSEL1CR_2_1),
+	PINMUX_DATA(IRQ3_8_MARK,	PORT8_FN0,	MSEL1CR_3_0),
+	PINMUX_DATA(IRQ3_16_MARK,	PORT16_FN0,	MSEL1CR_3_1),
+	PINMUX_DATA(IRQ4_17_MARK,	PORT17_FN0,	MSEL1CR_4_0),
+	PINMUX_DATA(IRQ4_163_MARK,	PORT163_FN0,	MSEL1CR_4_1),
+	PINMUX_DATA(IRQ5_MARK,		PORT18_FN0),
+	PINMUX_DATA(IRQ6_39_MARK,	PORT39_FN0,	MSEL1CR_6_0),
+	PINMUX_DATA(IRQ6_164_MARK,	PORT164_FN0,	MSEL1CR_6_1),
+	PINMUX_DATA(IRQ7_40_MARK,	PORT40_FN0,	MSEL1CR_7_1),
+	PINMUX_DATA(IRQ7_167_MARK,	PORT167_FN0,	MSEL1CR_7_0),
+	PINMUX_DATA(IRQ8_41_MARK,	PORT41_FN0,	MSEL1CR_8_1),
+	PINMUX_DATA(IRQ8_168_MARK,	PORT168_FN0,	MSEL1CR_8_0),
+	PINMUX_DATA(IRQ9_42_MARK,	PORT42_FN0,	MSEL1CR_9_0),
+	PINMUX_DATA(IRQ9_169_MARK,	PORT169_FN0,	MSEL1CR_9_1),
+	PINMUX_DATA(IRQ10_MARK,		PORT65_FN0,	MSEL1CR_9_1),
+	PINMUX_DATA(IRQ11_MARK,		PORT67_FN0),
+	PINMUX_DATA(IRQ12_80_MARK,	PORT80_FN0,	MSEL1CR_12_0),
+	PINMUX_DATA(IRQ12_137_MARK,	PORT137_FN0,	MSEL1CR_12_1),
+	PINMUX_DATA(IRQ13_81_MARK,	PORT81_FN0,	MSEL1CR_13_0),
+	PINMUX_DATA(IRQ13_145_MARK,	PORT145_FN0,	MSEL1CR_13_1),
+	PINMUX_DATA(IRQ14_82_MARK,	PORT82_FN0,	MSEL1CR_14_0),
+	PINMUX_DATA(IRQ14_146_MARK,	PORT146_FN0,	MSEL1CR_14_1),
+	PINMUX_DATA(IRQ15_83_MARK,	PORT83_FN0,	MSEL1CR_15_0),
+	PINMUX_DATA(IRQ15_147_MARK,	PORT147_FN0,	MSEL1CR_15_1),
+	PINMUX_DATA(IRQ16_84_MARK,	PORT84_FN0,	MSEL1CR_16_0),
+	PINMUX_DATA(IRQ16_170_MARK,	PORT170_FN0,	MSEL1CR_16_1),
+	PINMUX_DATA(IRQ17_MARK,		PORT85_FN0),
+	PINMUX_DATA(IRQ18_MARK,		PORT86_FN0),
+	PINMUX_DATA(IRQ19_MARK,		PORT87_FN0),
+	PINMUX_DATA(IRQ20_MARK,		PORT92_FN0),
+	PINMUX_DATA(IRQ21_MARK,		PORT93_FN0),
+	PINMUX_DATA(IRQ22_MARK,		PORT94_FN0),
+	PINMUX_DATA(IRQ23_MARK,		PORT95_FN0),
+	PINMUX_DATA(IRQ24_MARK,		PORT112_FN0),
+	PINMUX_DATA(IRQ25_MARK,		PORT119_FN0),
+	PINMUX_DATA(IRQ26_121_MARK,	PORT121_FN0,	MSEL1CR_26_1),
+	PINMUX_DATA(IRQ26_172_MARK,	PORT172_FN0,	MSEL1CR_26_0),
+	PINMUX_DATA(IRQ27_122_MARK,	PORT122_FN0,	MSEL1CR_27_1),
+	PINMUX_DATA(IRQ27_180_MARK,	PORT180_FN0,	MSEL1CR_27_0),
+	PINMUX_DATA(IRQ28_123_MARK,	PORT123_FN0,	MSEL1CR_28_1),
+	PINMUX_DATA(IRQ28_181_MARK,	PORT181_FN0,	MSEL1CR_28_0),
+	PINMUX_DATA(IRQ29_129_MARK,	PORT129_FN0,	MSEL1CR_29_1),
+	PINMUX_DATA(IRQ29_182_MARK,	PORT182_FN0,	MSEL1CR_29_0),
+	PINMUX_DATA(IRQ30_130_MARK,	PORT130_FN0,	MSEL1CR_30_1),
+	PINMUX_DATA(IRQ30_183_MARK,	PORT183_FN0,	MSEL1CR_30_0),
+	PINMUX_DATA(IRQ31_138_MARK,	PORT138_FN0,	MSEL1CR_31_1),
+	PINMUX_DATA(IRQ31_184_MARK,	PORT184_FN0,	MSEL1CR_31_0),
+
+	/* Function 1 */
+	PINMUX_DATA(BBIF2_TSCK1_MARK,		PORT0_FN1),
+	PINMUX_DATA(BBIF2_TSYNC1_MARK,		PORT1_FN1),
+	PINMUX_DATA(BBIF2_TXD1_MARK,		PORT2_FN1),
+	PINMUX_DATA(BBIF2_RXD_MARK,		PORT3_FN1),
+	PINMUX_DATA(FSIACK_MARK,		PORT4_FN1),
+	PINMUX_DATA(FSIAILR_MARK,		PORT5_FN1),
+	PINMUX_DATA(FSIAIBT_MARK,		PORT6_FN1),
+	PINMUX_DATA(FSIAISLD_MARK,		PORT7_FN1),
+	PINMUX_DATA(FSIAOMC_MARK,		PORT8_FN1),
+	PINMUX_DATA(FSIAOLR_MARK,		PORT9_FN1),
+	PINMUX_DATA(FSIAOBT_MARK,		PORT10_FN1),
+	PINMUX_DATA(FSIAOSLD_MARK,		PORT11_FN1),
+	PINMUX_DATA(FMSOCK_MARK,		PORT12_FN1),
+	PINMUX_DATA(FMSOOLR_MARK,		PORT13_FN1),
+	PINMUX_DATA(FMSOOBT_MARK,		PORT14_FN1),
+	PINMUX_DATA(FMSOSLD_MARK,		PORT15_FN1),
+	PINMUX_DATA(FMSOILR_MARK,		PORT16_FN1),
+	PINMUX_DATA(FMSOIBT_MARK,		PORT17_FN1),
+	PINMUX_DATA(FMSISLD_MARK,		PORT18_FN1),
+	PINMUX_DATA(A0_MARK,			PORT19_FN1),
+	PINMUX_DATA(A1_MARK,			PORT20_FN1),
+	PINMUX_DATA(A2_MARK,			PORT21_FN1),
+	PINMUX_DATA(A3_MARK,			PORT22_FN1),
+	PINMUX_DATA(A4_FOE_MARK,		PORT23_FN1),
+	PINMUX_DATA(A5_FCDE_MARK,		PORT24_FN1),
+	PINMUX_DATA(A6_MARK,			PORT25_FN1),
+	PINMUX_DATA(A7_MARK,			PORT26_FN1),
+	PINMUX_DATA(A8_MARK,			PORT27_FN1),
+	PINMUX_DATA(A9_MARK,			PORT28_FN1),
+	PINMUX_DATA(A10_MARK,			PORT29_FN1),
+	PINMUX_DATA(A11_MARK,			PORT30_FN1),
+	PINMUX_DATA(A12_MARK,			PORT31_FN1),
+	PINMUX_DATA(A13_MARK,			PORT32_FN1),
+	PINMUX_DATA(A14_MARK,			PORT33_FN1),
+	PINMUX_DATA(A15_MARK,			PORT34_FN1),
+	PINMUX_DATA(A16_MARK,			PORT35_FN1),
+	PINMUX_DATA(A17_MARK,			PORT36_FN1),
+	PINMUX_DATA(A18_MARK,			PORT37_FN1),
+	PINMUX_DATA(A19_MARK,			PORT38_FN1),
+	PINMUX_DATA(A20_MARK,			PORT39_FN1),
+	PINMUX_DATA(A21_MARK,			PORT40_FN1),
+	PINMUX_DATA(A22_MARK,			PORT41_FN1),
+	PINMUX_DATA(A23_MARK,			PORT42_FN1),
+	PINMUX_DATA(A24_MARK,			PORT43_FN1),
+	PINMUX_DATA(A25_MARK,			PORT44_FN1),
+	PINMUX_DATA(A26_MARK,			PORT45_FN1),
+	PINMUX_DATA(D0_NAF0_MARK,		PORT46_FN1),
+	PINMUX_DATA(D1_NAF1_MARK,		PORT47_FN1),
+	PINMUX_DATA(D2_NAF2_MARK,		PORT48_FN1),
+	PINMUX_DATA(D3_NAF3_MARK,		PORT49_FN1),
+	PINMUX_DATA(D4_NAF4_MARK,		PORT50_FN1),
+	PINMUX_DATA(D5_NAF5_MARK,		PORT51_FN1),
+	PINMUX_DATA(D6_NAF6_MARK,		PORT52_FN1),
+	PINMUX_DATA(D7_NAF7_MARK,		PORT53_FN1),
+	PINMUX_DATA(D8_NAF8_MARK,		PORT54_FN1),
+	PINMUX_DATA(D9_NAF9_MARK,		PORT55_FN1),
+	PINMUX_DATA(D10_NAF10_MARK,		PORT56_FN1),
+	PINMUX_DATA(D11_NAF11_MARK,		PORT57_FN1),
+	PINMUX_DATA(D12_NAF12_MARK,		PORT58_FN1),
+	PINMUX_DATA(D13_NAF13_MARK,		PORT59_FN1),
+	PINMUX_DATA(D14_NAF14_MARK,		PORT60_FN1),
+	PINMUX_DATA(D15_NAF15_MARK,		PORT61_FN1),
+	PINMUX_DATA(CS0_MARK,			PORT62_FN1),
+	PINMUX_DATA(CS2_MARK,			PORT63_FN1),
+	PINMUX_DATA(CS4_MARK,			PORT64_FN1),
+	PINMUX_DATA(CS5A_MARK,			PORT65_FN1),
+	PINMUX_DATA(CS5B_MARK,			PORT66_FN1),
+	PINMUX_DATA(CS6A_MARK,			PORT67_FN1),
+	PINMUX_DATA(FCE0_MARK,			PORT68_FN1),
+	PINMUX_DATA(RD_FSC_MARK,		PORT69_FN1),
+	PINMUX_DATA(WE0_FWE_MARK,		PORT70_FN1),
+	PINMUX_DATA(WE1_MARK,			PORT71_FN1),
+	PINMUX_DATA(CKO_MARK,			PORT72_FN1),
+	PINMUX_DATA(FRB_MARK,			PORT73_FN1),
+	PINMUX_DATA(WAIT_MARK,			PORT74_FN1),
+	PINMUX_DATA(RDWR_MARK,			PORT75_FN1),
+	PINMUX_DATA(MEMC_AD0_MARK,		PORT76_FN1),
+	PINMUX_DATA(MEMC_AD1_MARK,		PORT77_FN1),
+	PINMUX_DATA(MEMC_AD2_MARK,		PORT78_FN1),
+	PINMUX_DATA(MEMC_AD3_MARK,		PORT79_FN1),
+	PINMUX_DATA(MEMC_AD4_MARK,		PORT80_FN1),
+	PINMUX_DATA(MEMC_AD5_MARK,		PORT81_FN1),
+	PINMUX_DATA(MEMC_AD6_MARK,		PORT82_FN1),
+	PINMUX_DATA(MEMC_AD7_MARK,		PORT83_FN1),
+	PINMUX_DATA(MEMC_AD8_MARK,		PORT84_FN1),
+	PINMUX_DATA(MEMC_AD9_MARK,		PORT85_FN1),
+	PINMUX_DATA(MEMC_AD10_MARK,		PORT86_FN1),
+	PINMUX_DATA(MEMC_AD11_MARK,		PORT87_FN1),
+	PINMUX_DATA(MEMC_AD12_MARK,		PORT88_FN1),
+	PINMUX_DATA(MEMC_AD13_MARK,		PORT89_FN1),
+	PINMUX_DATA(MEMC_AD14_MARK,		PORT90_FN1),
+	PINMUX_DATA(MEMC_AD15_MARK,		PORT91_FN1),
+	PINMUX_DATA(MEMC_CS0_MARK,		PORT92_FN1),
+	PINMUX_DATA(MEMC_BUSCLK_MEMC_A0_MARK,	PORT93_FN1),
+	PINMUX_DATA(MEMC_CS1_MEMC_A1_MARK,	PORT94_FN1),
+	PINMUX_DATA(MEMC_ADV_MEMC_DREQ0_MARK,	PORT95_FN1),
+	PINMUX_DATA(MEMC_WAIT_MEMC_DREQ1_MARK,	PORT96_FN1),
+	PINMUX_DATA(MEMC_NOE_MARK,		PORT97_FN1),
+	PINMUX_DATA(MEMC_NWE_MARK,		PORT98_FN1),
+	PINMUX_DATA(MEMC_INT_MARK,		PORT99_FN1),
+	PINMUX_DATA(VIO_VD_MARK,		PORT100_FN1),
+	PINMUX_DATA(VIO_HD_MARK,		PORT101_FN1),
+	PINMUX_DATA(VIO_D0_MARK,		PORT102_FN1),
+	PINMUX_DATA(VIO_D1_MARK,		PORT103_FN1),
+	PINMUX_DATA(VIO_D2_MARK,		PORT104_FN1),
+	PINMUX_DATA(VIO_D3_MARK,		PORT105_FN1),
+	PINMUX_DATA(VIO_D4_MARK,		PORT106_FN1),
+	PINMUX_DATA(VIO_D5_MARK,		PORT107_FN1),
+	PINMUX_DATA(VIO_D6_MARK,		PORT108_FN1),
+	PINMUX_DATA(VIO_D7_MARK,		PORT109_FN1),
+	PINMUX_DATA(VIO_D8_MARK,		PORT110_FN1),
+	PINMUX_DATA(VIO_D9_MARK,		PORT111_FN1),
+	PINMUX_DATA(VIO_D10_MARK,		PORT112_FN1),
+	PINMUX_DATA(VIO_D11_MARK,		PORT113_FN1),
+	PINMUX_DATA(VIO_D12_MARK,		PORT114_FN1),
+	PINMUX_DATA(VIO_D13_MARK,		PORT115_FN1),
+	PINMUX_DATA(VIO_D14_MARK,		PORT116_FN1),
+	PINMUX_DATA(VIO_D15_MARK,		PORT117_FN1),
+	PINMUX_DATA(VIO_CLK_MARK,		PORT118_FN1),
+	PINMUX_DATA(VIO_FIELD_MARK,		PORT119_FN1),
+	PINMUX_DATA(VIO_CKO_MARK,		PORT120_FN1),
+	PINMUX_DATA(LCDD0_MARK,			PORT121_FN1),
+	PINMUX_DATA(LCDD1_MARK,			PORT122_FN1),
+	PINMUX_DATA(LCDD2_MARK,			PORT123_FN1),
+	PINMUX_DATA(LCDD3_MARK,			PORT124_FN1),
+	PINMUX_DATA(LCDD4_MARK,			PORT125_FN1),
+	PINMUX_DATA(LCDD5_MARK,			PORT126_FN1),
+	PINMUX_DATA(LCDD6_MARK,			PORT127_FN1),
+	PINMUX_DATA(LCDD7_MARK,			PORT128_FN1),
+	PINMUX_DATA(LCDD8_MARK,			PORT129_FN1),
+	PINMUX_DATA(LCDD9_MARK,			PORT130_FN1),
+	PINMUX_DATA(LCDD10_MARK,		PORT131_FN1),
+	PINMUX_DATA(LCDD11_MARK,		PORT132_FN1),
+	PINMUX_DATA(LCDD12_MARK,		PORT133_FN1),
+	PINMUX_DATA(LCDD13_MARK,		PORT134_FN1),
+	PINMUX_DATA(LCDD14_MARK,		PORT135_FN1),
+	PINMUX_DATA(LCDD15_MARK,		PORT136_FN1),
+	PINMUX_DATA(LCDD16_MARK,		PORT137_FN1),
+	PINMUX_DATA(LCDD17_MARK,		PORT138_FN1),
+	PINMUX_DATA(LCDD18_MARK,		PORT139_FN1),
+	PINMUX_DATA(LCDD19_MARK,		PORT140_FN1),
+	PINMUX_DATA(LCDD20_MARK,		PORT141_FN1),
+	PINMUX_DATA(LCDD21_MARK,		PORT142_FN1),
+	PINMUX_DATA(LCDD22_MARK,		PORT143_FN1),
+	PINMUX_DATA(LCDD23_MARK,		PORT144_FN1),
+	PINMUX_DATA(LCDHSYN_MARK,		PORT145_FN1),
+	PINMUX_DATA(LCDVSYN_MARK,		PORT146_FN1),
+	PINMUX_DATA(LCDDCK_MARK,		PORT147_FN1),
+	PINMUX_DATA(LCDRD_MARK,			PORT148_FN1),
+	PINMUX_DATA(LCDDISP_MARK,		PORT149_FN1),
+	PINMUX_DATA(LCDLCLK_MARK,		PORT150_FN1),
+	PINMUX_DATA(LCDDON_MARK,		PORT151_FN1),
+	PINMUX_DATA(SCIFA0_TXD_MARK,		PORT152_FN1),
+	PINMUX_DATA(SCIFA0_RXD_MARK,		PORT153_FN1),
+	PINMUX_DATA(SCIFA1_TXD_MARK,		PORT154_FN1),
+	PINMUX_DATA(SCIFA1_RXD_MARK,		PORT155_FN1),
+	PINMUX_DATA(TS_SPSYNC1_MARK,		PORT156_FN1),
+	PINMUX_DATA(TS_SDAT1_MARK,		PORT157_FN1),
+	PINMUX_DATA(TS_SDEN1_MARK,		PORT158_FN1),
+	PINMUX_DATA(TS_SCK1_MARK,		PORT159_FN1),
+	PINMUX_DATA(TPU0TO0_MARK,		PORT160_FN1),
+	PINMUX_DATA(TPU0TO1_MARK,		PORT161_FN1),
+	PINMUX_DATA(SCIFB_SCK_MARK,		PORT162_FN1),
+	PINMUX_DATA(SCIFB_RTS_MARK,		PORT163_FN1),
+	PINMUX_DATA(SCIFB_CTS_MARK,		PORT164_FN1),
+	PINMUX_DATA(SCIFB_TXD_MARK,		PORT165_FN1),
+	PINMUX_DATA(SCIFB_RXD_MARK,		PORT166_FN1),
+	PINMUX_DATA(VBUS0_0_MARK,		PORT167_FN1),
+	PINMUX_DATA(VBUS0_1_MARK,		PORT168_FN1),
+	PINMUX_DATA(HDMI_HPD_MARK,		PORT169_FN1),
+	PINMUX_DATA(HDMI_CEC_MARK,		PORT170_FN1),
+	PINMUX_DATA(SDHICLK0_MARK,		PORT171_FN1),
+	PINMUX_DATA(SDHICD0_MARK,		PORT172_FN1),
+	PINMUX_DATA(SDHID0_0_MARK,		PORT173_FN1),
+	PINMUX_DATA(SDHID0_1_MARK,		PORT174_FN1),
+	PINMUX_DATA(SDHID0_2_MARK,		PORT175_FN1),
+	PINMUX_DATA(SDHID0_3_MARK,		PORT176_FN1),
+	PINMUX_DATA(SDHICMD0_MARK,		PORT177_FN1),
+	PINMUX_DATA(SDHIWP0_MARK,		PORT178_FN1),
+	PINMUX_DATA(SDHICLK1_MARK,		PORT179_FN1),
+	PINMUX_DATA(SDHID1_0_MARK,		PORT180_FN1),
+	PINMUX_DATA(SDHID1_1_MARK,		PORT181_FN1),
+	PINMUX_DATA(SDHID1_2_MARK,		PORT182_FN1),
+	PINMUX_DATA(SDHID1_3_MARK,		PORT183_FN1),
+	PINMUX_DATA(SDHICMD1_MARK,		PORT184_FN1),
+	PINMUX_DATA(SDHICLK2_MARK,		PORT185_FN1),
+	PINMUX_DATA(SDHID2_0_MARK,		PORT186_FN1),
+	PINMUX_DATA(SDHID2_1_MARK,		PORT187_FN1),
+	PINMUX_DATA(SDHID2_2_MARK,		PORT188_FN1),
+	PINMUX_DATA(SDHID2_3_MARK,		PORT189_FN1),
+	PINMUX_DATA(SDHICMD2_MARK,		PORT190_FN1),
+
+	/* Function 2 */
+	PINMUX_DATA(FSIBCK_MARK,		PORT4_FN2),
+	PINMUX_DATA(SCIFA4_RXD_MARK,		PORT5_FN2),
+	PINMUX_DATA(SCIFA4_TXD_MARK,		PORT6_FN2),
+	PINMUX_DATA(SCIFA5_RXD_MARK,		PORT8_FN2),
+	PINMUX_DATA(FSIASPDIF_11_MARK,		PORT11_FN2),
+	PINMUX_DATA(SCIFA5_TXD_MARK,		PORT12_FN2),
+	PINMUX_DATA(FMSIOLR_MARK,		PORT13_FN2),
+	PINMUX_DATA(FMSIOBT_MARK,		PORT14_FN2),
+	PINMUX_DATA(FSIASPDIF_15_MARK,		PORT15_FN2),
+	PINMUX_DATA(FMSIILR_MARK,		PORT16_FN2),
+	PINMUX_DATA(FMSIIBT_MARK,		PORT17_FN2),
+	PINMUX_DATA(BS_MARK,			PORT19_FN2),
+	PINMUX_DATA(MSIOF0_TSYNC_MARK,		PORT36_FN2),
+	PINMUX_DATA(MSIOF0_TSCK_MARK,		PORT37_FN2),
+	PINMUX_DATA(MSIOF0_RXD_MARK,		PORT38_FN2),
+	PINMUX_DATA(MSIOF0_RSCK_MARK,		PORT39_FN2),
+	PINMUX_DATA(MSIOF0_RSYNC_MARK,		PORT40_FN2),
+	PINMUX_DATA(MSIOF0_MCK0_MARK,		PORT41_FN2),
+	PINMUX_DATA(MSIOF0_MCK1_MARK,		PORT42_FN2),
+	PINMUX_DATA(MSIOF0_SS1_MARK,		PORT43_FN2),
+	PINMUX_DATA(MSIOF0_SS2_MARK,		PORT44_FN2),
+	PINMUX_DATA(MSIOF0_TXD_MARK,		PORT45_FN2),
+	PINMUX_DATA(FMSICK_MARK,		PORT65_FN2),
+	PINMUX_DATA(FCE1_MARK,			PORT66_FN2),
+	PINMUX_DATA(BBIF1_RXD_MARK,		PORT76_FN2),
+	PINMUX_DATA(BBIF1_TSYNC_MARK,		PORT77_FN2),
+	PINMUX_DATA(BBIF1_TSCK_MARK,		PORT78_FN2),
+	PINMUX_DATA(BBIF1_TXD_MARK,		PORT79_FN2),
+	PINMUX_DATA(BBIF1_RSCK_MARK,		PORT80_FN2),
+	PINMUX_DATA(BBIF1_RSYNC_MARK,		PORT81_FN2),
+	PINMUX_DATA(BBIF1_FLOW_MARK,		PORT82_FN2),
+	PINMUX_DATA(BB_RX_FLOW_N_MARK,		PORT83_FN2),
+	PINMUX_DATA(MSIOF1_RSCK_MARK,		PORT84_FN2),
+	PINMUX_DATA(MSIOF1_RSYNC_MARK,		PORT85_FN2),
+	PINMUX_DATA(MSIOF1_MCK0_MARK,		PORT86_FN2),
+	PINMUX_DATA(MSIOF1_MCK1_MARK,		PORT87_FN2),
+	PINMUX_DATA(MSIOF1_TSCK_88_MARK,	PORT88_FN2, MSEL4CR_10_1),
+	PINMUX_DATA(MSIOF1_TSYNC_89_MARK,	PORT89_FN2, MSEL4CR_10_1),
+	PINMUX_DATA(MSIOF1_TXD_90_MARK,		PORT90_FN2, MSEL4CR_10_1),
+	PINMUX_DATA(MSIOF1_RXD_91_MARK,		PORT91_FN2, MSEL4CR_10_1),
+	PINMUX_DATA(MSIOF1_SS1_92_MARK,		PORT92_FN2, MSEL4CR_10_1),
+	PINMUX_DATA(MSIOF1_SS2_93_MARK,		PORT93_FN2, MSEL4CR_10_1),
+	PINMUX_DATA(SCIFA2_CTS1_MARK,		PORT94_FN2),
+	PINMUX_DATA(SCIFA2_RTS1_MARK,		PORT95_FN2),
+	PINMUX_DATA(SCIFA2_TXD1_MARK,		PORT96_FN2),
+	PINMUX_DATA(SCIFA2_RXD1_MARK,		PORT97_FN2),
+	PINMUX_DATA(SCIFA2_SCK1_MARK,		PORT98_FN2),
+	PINMUX_DATA(I2C_SCL2_MARK,		PORT110_FN2),
+	PINMUX_DATA(I2C_SDA2_MARK,		PORT111_FN2),
+	PINMUX_DATA(I2C_SCL3_MARK,		PORT114_FN2, MSEL4CR_16_1),
+	PINMUX_DATA(I2C_SDA3_MARK,		PORT115_FN2, MSEL4CR_16_1),
+	PINMUX_DATA(I2C_SCL4_MARK,		PORT116_FN2, MSEL4CR_17_1),
+	PINMUX_DATA(I2C_SDA4_MARK,		PORT117_FN2, MSEL4CR_17_1),
+	PINMUX_DATA(MSIOF2_RSCK_MARK,		PORT134_FN2),
+	PINMUX_DATA(MSIOF2_RSYNC_MARK,		PORT135_FN2),
+	PINMUX_DATA(MSIOF2_MCK0_MARK,		PORT136_FN2),
+	PINMUX_DATA(MSIOF2_MCK1_MARK,		PORT137_FN2),
+	PINMUX_DATA(MSIOF2_SS1_MARK,		PORT138_FN2),
+	PINMUX_DATA(MSIOF2_SS2_MARK,		PORT139_FN2),
+	PINMUX_DATA(SCIFA3_CTS_140_MARK,	PORT140_FN2, MSEL3CR_9_1),
+	PINMUX_DATA(SCIFA3_RTS_141_MARK,	PORT141_FN2),
+	PINMUX_DATA(SCIFA3_SCK_MARK,		PORT142_FN2),
+	PINMUX_DATA(SCIFA3_TXD_MARK,		PORT143_FN2),
+	PINMUX_DATA(SCIFA3_RXD_MARK,		PORT144_FN2),
+	PINMUX_DATA(MSIOF2_TSYNC_MARK,		PORT148_FN2),
+	PINMUX_DATA(MSIOF2_TSCK_MARK,		PORT149_FN2),
+	PINMUX_DATA(MSIOF2_RXD_MARK,		PORT150_FN2),
+	PINMUX_DATA(MSIOF2_TXD_MARK,		PORT151_FN2),
+	PINMUX_DATA(SCIFA0_SCK_MARK,		PORT156_FN2),
+	PINMUX_DATA(SCIFA0_RTS_MARK,		PORT157_FN2),
+	PINMUX_DATA(SCIFA0_CTS_MARK,		PORT158_FN2),
+	PINMUX_DATA(SCIFA1_SCK_MARK,		PORT159_FN2),
+	PINMUX_DATA(SCIFA1_RTS_MARK,		PORT160_FN2),
+	PINMUX_DATA(SCIFA1_CTS_MARK,		PORT161_FN2),
+
+	/* Function 3 */
+	PINMUX_DATA(VIO_CKO1_MARK,		PORT16_FN3),
+	PINMUX_DATA(VIO_CKO2_MARK,		PORT17_FN3),
+	PINMUX_DATA(IDIN_1_18_MARK,		PORT18_FN3, MSEL4CR_14_1),
+	PINMUX_DATA(MSIOF1_TSCK_39_MARK,	PORT39_FN3, MSEL4CR_10_0),
+	PINMUX_DATA(MSIOF1_TSYNC_40_MARK,	PORT40_FN3, MSEL4CR_10_0),
+	PINMUX_DATA(MSIOF1_TXD_41_MARK,		PORT41_FN3, MSEL4CR_10_0),
+	PINMUX_DATA(MSIOF1_RXD_42_MARK,		PORT42_FN3, MSEL4CR_10_0),
+	PINMUX_DATA(MSIOF1_SS1_43_MARK,		PORT43_FN3, MSEL4CR_10_0),
+	PINMUX_DATA(MSIOF1_SS2_44_MARK,		PORT44_FN3, MSEL4CR_10_0),
+	PINMUX_DATA(MMCD1_0_MARK,		PORT54_FN3, MSEL4CR_15_1),
+	PINMUX_DATA(MMCD1_1_MARK,		PORT55_FN3, MSEL4CR_15_1),
+	PINMUX_DATA(MMCD1_2_MARK,		PORT56_FN3, MSEL4CR_15_1),
+	PINMUX_DATA(MMCD1_3_MARK,		PORT57_FN3, MSEL4CR_15_1),
+	PINMUX_DATA(MMCD1_4_MARK,		PORT58_FN3, MSEL4CR_15_1),
+	PINMUX_DATA(MMCD1_5_MARK,		PORT59_FN3, MSEL4CR_15_1),
+	PINMUX_DATA(MMCD1_6_MARK,		PORT60_FN3, MSEL4CR_15_1),
+	PINMUX_DATA(MMCD1_7_MARK,		PORT61_FN3, MSEL4CR_15_1),
+	PINMUX_DATA(VINT_I_MARK,		PORT65_FN3),
+	PINMUX_DATA(MMCCLK1_MARK,		PORT66_FN3, MSEL4CR_15_1),
+	PINMUX_DATA(MMCCMD1_MARK,		PORT67_FN3, MSEL4CR_15_1),
+	PINMUX_DATA(TPU0TO2_93_MARK,		PORT93_FN3),
+	PINMUX_DATA(TPU0TO2_99_MARK,		PORT99_FN3),
+	PINMUX_DATA(TPU0TO3_MARK,		PORT112_FN3),
+	PINMUX_DATA(IDIN_0_MARK,		PORT113_FN3),
+	PINMUX_DATA(EXTLP_0_MARK,		PORT114_FN3),
+	PINMUX_DATA(OVCN2_0_MARK,		PORT115_FN3),
+	PINMUX_DATA(PWEN_0_MARK,		PORT116_FN3),
+	PINMUX_DATA(OVCN_0_MARK,		PORT117_FN3),
+	PINMUX_DATA(KEYOUT7_MARK,		PORT121_FN3),
+	PINMUX_DATA(KEYOUT6_MARK,		PORT122_FN3),
+	PINMUX_DATA(KEYOUT5_MARK,		PORT123_FN3),
+	PINMUX_DATA(KEYOUT4_MARK,		PORT124_FN3),
+	PINMUX_DATA(KEYOUT3_MARK,		PORT125_FN3),
+	PINMUX_DATA(KEYOUT2_MARK,		PORT126_FN3),
+	PINMUX_DATA(KEYOUT1_MARK,		PORT127_FN3),
+	PINMUX_DATA(KEYOUT0_MARK,		PORT128_FN3),
+	PINMUX_DATA(KEYIN7_MARK,		PORT129_FN3),
+	PINMUX_DATA(KEYIN6_MARK,		PORT130_FN3),
+	PINMUX_DATA(KEYIN5_MARK,		PORT131_FN3),
+	PINMUX_DATA(KEYIN4_MARK,		PORT132_FN3),
+	PINMUX_DATA(KEYIN3_133_MARK,		PORT133_FN3, MSEL4CR_18_0),
+	PINMUX_DATA(KEYIN2_134_MARK,		PORT134_FN3, MSEL4CR_18_0),
+	PINMUX_DATA(KEYIN1_135_MARK,		PORT135_FN3, MSEL4CR_18_0),
+	PINMUX_DATA(KEYIN0_136_MARK,		PORT136_FN3, MSEL4CR_18_0),
+	PINMUX_DATA(TS_SPSYNC2_MARK,		PORT137_FN3),
+	PINMUX_DATA(IROUT_139_MARK,		PORT139_FN3),
+	PINMUX_DATA(IRDA_OUT_MARK,		PORT140_FN3),
+	PINMUX_DATA(IRDA_IN_MARK,		PORT141_FN3),
+	PINMUX_DATA(IRDA_FIRSEL_MARK,		PORT142_FN3),
+	PINMUX_DATA(TS_SDAT2_MARK,		PORT145_FN3),
+	PINMUX_DATA(TS_SDEN2_MARK,		PORT146_FN3),
+	PINMUX_DATA(TS_SCK2_MARK,		PORT147_FN3),
+
+	/* Function 4 */
+	PINMUX_DATA(SCIFA3_CTS_43_MARK,	PORT43_FN4, MSEL3CR_9_0),
+	PINMUX_DATA(SCIFA3_RTS_44_MARK,	PORT44_FN4),
+	PINMUX_DATA(GP_RX_FLAG_MARK,	PORT76_FN4),
+	PINMUX_DATA(GP_RX_DATA_MARK,	PORT77_FN4),
+	PINMUX_DATA(GP_TX_READY_MARK,	PORT78_FN4),
+	PINMUX_DATA(GP_RX_WAKE_MARK,	PORT79_FN4),
+	PINMUX_DATA(MP_TX_FLAG_MARK,	PORT80_FN4),
+	PINMUX_DATA(MP_TX_DATA_MARK,	PORT81_FN4),
+	PINMUX_DATA(MP_RX_READY_MARK,	PORT82_FN4),
+	PINMUX_DATA(MP_TX_WAKE_MARK,	PORT83_FN4),
+	PINMUX_DATA(MMCD0_0_MARK,	PORT84_FN4, MSEL4CR_15_0),
+	PINMUX_DATA(MMCD0_1_MARK,	PORT85_FN4, MSEL4CR_15_0),
+	PINMUX_DATA(MMCD0_2_MARK,	PORT86_FN4, MSEL4CR_15_0),
+	PINMUX_DATA(MMCD0_3_MARK,	PORT87_FN4, MSEL4CR_15_0),
+	PINMUX_DATA(MMCD0_4_MARK,	PORT88_FN4, MSEL4CR_15_0),
+	PINMUX_DATA(MMCD0_5_MARK,	PORT89_FN4, MSEL4CR_15_0),
+	PINMUX_DATA(MMCD0_6_MARK,	PORT90_FN4, MSEL4CR_15_0),
+	PINMUX_DATA(MMCD0_7_MARK,	PORT91_FN4, MSEL4CR_15_0),
+	PINMUX_DATA(MMCCMD0_MARK,	PORT92_FN4, MSEL4CR_15_0),
+	PINMUX_DATA(SIM_RST_MARK,	PORT94_FN4),
+	PINMUX_DATA(SIM_CLK_MARK,	PORT95_FN4),
+	PINMUX_DATA(SIM_D_MARK,		PORT98_FN4),
+	PINMUX_DATA(MMCCLK0_MARK,	PORT99_FN4, MSEL4CR_15_0),
+	PINMUX_DATA(IDIN_1_113_MARK,	PORT113_FN4, MSEL4CR_14_0),
+	PINMUX_DATA(OVCN_1_114_MARK,	PORT114_FN4, MSEL4CR_14_0),
+	PINMUX_DATA(PWEN_1_115_MARK,	PORT115_FN4),
+	PINMUX_DATA(EXTLP_1_MARK,	PORT116_FN4),
+	PINMUX_DATA(OVCN2_1_MARK,	PORT117_FN4),
+	PINMUX_DATA(KEYIN0_121_MARK,	PORT121_FN4, MSEL4CR_18_1),
+	PINMUX_DATA(KEYIN1_122_MARK,	PORT122_FN4, MSEL4CR_18_1),
+	PINMUX_DATA(KEYIN2_123_MARK,	PORT123_FN4, MSEL4CR_18_1),
+	PINMUX_DATA(KEYIN3_124_MARK,	PORT124_FN4, MSEL4CR_18_1),
+	PINMUX_DATA(PWEN_1_138_MARK,	PORT138_FN4),
+	PINMUX_DATA(IROUT_140_MARK,	PORT140_FN4),
+	PINMUX_DATA(LCDCS_MARK,		PORT145_FN4),
+	PINMUX_DATA(LCDWR_MARK,		PORT147_FN4),
+	PINMUX_DATA(LCDRS_MARK,		PORT149_FN4),
+	PINMUX_DATA(OVCN_1_162_MARK,	PORT162_FN4, MSEL4CR_14_1),
+
+	/* Function 5 */
+	PINMUX_DATA(GPI0_MARK,		PORT41_FN5),
+	PINMUX_DATA(GPI1_MARK,		PORT42_FN5),
+	PINMUX_DATA(GPO0_MARK,		PORT43_FN5),
+	PINMUX_DATA(GPO1_MARK,		PORT44_FN5),
+	PINMUX_DATA(I2C_SCL3S_MARK,	PORT137_FN5, MSEL4CR_16_0),
+	PINMUX_DATA(I2C_SDA3S_MARK,	PORT145_FN5, MSEL4CR_16_0),
+	PINMUX_DATA(I2C_SCL4S_MARK,	PORT146_FN5, MSEL4CR_17_0),
+	PINMUX_DATA(I2C_SDA4S_MARK,	PORT147_FN5, MSEL4CR_17_0),
+
+	/* Function select */
+	PINMUX_DATA(LCDC0_SELECT_MARK,	MSEL3CR_6_0),
+	PINMUX_DATA(LCDC1_SELECT_MARK,	MSEL3CR_6_1),
+
+	PINMUX_DATA(TS0_1SELECT_MARK,	MSEL3CR_21_0, MSEL3CR_20_0),
+	PINMUX_DATA(TS0_2SELECT_MARK,	MSEL3CR_21_0, MSEL3CR_20_1),
+	PINMUX_DATA(TS1_1SELECT_MARK,	MSEL3CR_27_0, MSEL3CR_26_0),
+	PINMUX_DATA(TS1_2SELECT_MARK,	MSEL3CR_27_0, MSEL3CR_26_1),
+
+	PINMUX_DATA(SDENC_CPG_MARK,	MSEL4CR_19_0),
+	PINMUX_DATA(SDENC_DV_CLKI_MARK,	MSEL4CR_19_1),
+
+	PINMUX_DATA(MFIv6_MARK,		MSEL4CR_6_0),
+	PINMUX_DATA(MFIv4_MARK,		MSEL4CR_6_1),
+};
+
+#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
+#define GPIO_PORT_ALL() _190(_GPIO_PORT, , unused)
+#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
+
+static struct pinmux_gpio pinmux_gpios[] = {
+
+	/* PORT */
+	GPIO_PORT_ALL(),
+
+	/* IRQ */
+	GPIO_FN(IRQ0_6),	GPIO_FN(IRQ0_162),	GPIO_FN(IRQ1),
+	GPIO_FN(IRQ2_4),	GPIO_FN(IRQ2_5),	GPIO_FN(IRQ3_8),
+	GPIO_FN(IRQ3_16),	GPIO_FN(IRQ4_17),	GPIO_FN(IRQ4_163),
+	GPIO_FN(IRQ5),		GPIO_FN(IRQ6_39),	GPIO_FN(IRQ6_164),
+	GPIO_FN(IRQ7_40),	GPIO_FN(IRQ7_167),	GPIO_FN(IRQ8_41),
+	GPIO_FN(IRQ8_168),	GPIO_FN(IRQ9_42),	GPIO_FN(IRQ9_169),
+	GPIO_FN(IRQ10),		GPIO_FN(IRQ11),		GPIO_FN(IRQ12_80),
+	GPIO_FN(IRQ12_137),	GPIO_FN(IRQ13_81),	GPIO_FN(IRQ13_145),
+	GPIO_FN(IRQ14_82),	GPIO_FN(IRQ14_146),	GPIO_FN(IRQ15_83),
+	GPIO_FN(IRQ15_147),	GPIO_FN(IRQ16_84),	GPIO_FN(IRQ16_170),
+	GPIO_FN(IRQ17),		GPIO_FN(IRQ18),		GPIO_FN(IRQ19),
+	GPIO_FN(IRQ20),		GPIO_FN(IRQ21),		GPIO_FN(IRQ22),
+	GPIO_FN(IRQ23),		GPIO_FN(IRQ24),		GPIO_FN(IRQ25),
+	GPIO_FN(IRQ26_121),	GPIO_FN(IRQ26_172),	GPIO_FN(IRQ27_122),
+	GPIO_FN(IRQ27_180),	GPIO_FN(IRQ28_123),	GPIO_FN(IRQ28_181),
+	GPIO_FN(IRQ29_129),	GPIO_FN(IRQ29_182),	GPIO_FN(IRQ30_130),
+	GPIO_FN(IRQ30_183),	GPIO_FN(IRQ31_138),	GPIO_FN(IRQ31_184),
+
+	/* MSIOF0 */
+	GPIO_FN(MSIOF0_TSYNC),	GPIO_FN(MSIOF0_TSCK),	GPIO_FN(MSIOF0_RXD),
+	GPIO_FN(MSIOF0_RSCK),	GPIO_FN(MSIOF0_RSYNC),	GPIO_FN(MSIOF0_MCK0),
+	GPIO_FN(MSIOF0_MCK1),	GPIO_FN(MSIOF0_SS1),	GPIO_FN(MSIOF0_SS2),
+	GPIO_FN(MSIOF0_TXD),
+
+	/* MSIOF1 */
+	GPIO_FN(MSIOF1_TSCK_39),	GPIO_FN(MSIOF1_TSCK_88),
+	GPIO_FN(MSIOF1_TSYNC_40),	GPIO_FN(MSIOF1_TSYNC_89),
+	GPIO_FN(MSIOF1_TXD_41),		GPIO_FN(MSIOF1_TXD_90),
+	GPIO_FN(MSIOF1_RXD_42),		GPIO_FN(MSIOF1_RXD_91),
+	GPIO_FN(MSIOF1_SS1_43),		GPIO_FN(MSIOF1_SS1_92),
+	GPIO_FN(MSIOF1_SS2_44),		GPIO_FN(MSIOF1_SS2_93),
+	GPIO_FN(MSIOF1_RSCK),		GPIO_FN(MSIOF1_RSYNC),
+	GPIO_FN(MSIOF1_MCK0),		GPIO_FN(MSIOF1_MCK1),
+
+	/* MSIOF2 */
+	GPIO_FN(MSIOF2_RSCK),	GPIO_FN(MSIOF2_RSYNC),	GPIO_FN(MSIOF2_MCK0),
+	GPIO_FN(MSIOF2_MCK1),	GPIO_FN(MSIOF2_SS1),	GPIO_FN(MSIOF2_SS2),
+	GPIO_FN(MSIOF2_TSYNC),	GPIO_FN(MSIOF2_TSCK),	GPIO_FN(MSIOF2_RXD),
+	GPIO_FN(MSIOF2_TXD),
+
+	/* MSIOF3 */
+	GPIO_FN(BBIF1_RXD),	GPIO_FN(BBIF1_TSYNC),	GPIO_FN(BBIF1_TSCK),
+	GPIO_FN(BBIF1_TXD),	GPIO_FN(BBIF1_RSCK),	GPIO_FN(BBIF1_RSYNC),
+	GPIO_FN(BBIF1_FLOW),	GPIO_FN(BB_RX_FLOW_N),
+
+	/* MSIOF4 */
+	GPIO_FN(BBIF2_TSCK1),	GPIO_FN(BBIF2_TSYNC1),
+	GPIO_FN(BBIF2_TXD1),	GPIO_FN(BBIF2_RXD),
+
+	/* FSI */
+	GPIO_FN(FSIACK),	GPIO_FN(FSIBCK),	GPIO_FN(FSIAILR),
+	GPIO_FN(FSIAIBT),	GPIO_FN(FSIAISLD),	GPIO_FN(FSIAOMC),
+	GPIO_FN(FSIAOLR),	GPIO_FN(FSIAOBT),	GPIO_FN(FSIAOSLD),
+	GPIO_FN(FSIASPDIF_11),	GPIO_FN(FSIASPDIF_15),
+
+	/* FMSI */
+	GPIO_FN(FMSOCK),	GPIO_FN(FMSOOLR),	GPIO_FN(FMSIOLR),
+	GPIO_FN(FMSOOBT),	GPIO_FN(FMSIOBT),	GPIO_FN(FMSOSLD),
+	GPIO_FN(FMSOILR),	GPIO_FN(FMSIILR),	GPIO_FN(FMSOIBT),
+	GPIO_FN(FMSIIBT),	GPIO_FN(FMSISLD),	GPIO_FN(FMSICK),
+
+	/* SCIFA0 */
+	GPIO_FN(SCIFA0_TXD),	GPIO_FN(SCIFA0_RXD),	GPIO_FN(SCIFA0_SCK),
+	GPIO_FN(SCIFA0_RTS),	GPIO_FN(SCIFA0_CTS),
+
+	/* SCIFA1 */
+	GPIO_FN(SCIFA1_TXD),	GPIO_FN(SCIFA1_RXD),	GPIO_FN(SCIFA1_SCK),
+	GPIO_FN(SCIFA1_RTS),	GPIO_FN(SCIFA1_CTS),
+
+	/* SCIFA2 */
+	GPIO_FN(SCIFA2_CTS1),	GPIO_FN(SCIFA2_RTS1),	GPIO_FN(SCIFA2_TXD1),
+	GPIO_FN(SCIFA2_RXD1),	GPIO_FN(SCIFA2_SCK1),
+
+	/* SCIFA3 */
+	GPIO_FN(SCIFA3_CTS_43),		GPIO_FN(SCIFA3_CTS_140),
+	GPIO_FN(SCIFA3_RTS_44),		GPIO_FN(SCIFA3_RTS_141),
+	GPIO_FN(SCIFA3_SCK),		GPIO_FN(SCIFA3_TXD),
+	GPIO_FN(SCIFA3_RXD),
+
+	/* SCIFA4 */
+	GPIO_FN(SCIFA4_RXD),	GPIO_FN(SCIFA4_TXD),
+
+	/* SCIFA5 */
+	GPIO_FN(SCIFA5_RXD),	GPIO_FN(SCIFA5_TXD),
+
+	/* SCIFB */
+	GPIO_FN(SCIFB_SCK),	GPIO_FN(SCIFB_RTS),	GPIO_FN(SCIFB_CTS),
+	GPIO_FN(SCIFB_TXD),	GPIO_FN(SCIFB_RXD),
+
+	/* CEU */
+	GPIO_FN(VIO_HD),	GPIO_FN(VIO_CKO1),	GPIO_FN(VIO_CKO2),
+	GPIO_FN(VIO_VD),	GPIO_FN(VIO_CLK),	GPIO_FN(VIO_FIELD),
+	GPIO_FN(VIO_CKO),	GPIO_FN(VIO_D0),	GPIO_FN(VIO_D1),
+	GPIO_FN(VIO_D2),	GPIO_FN(VIO_D3),	GPIO_FN(VIO_D4),
+	GPIO_FN(VIO_D5),	GPIO_FN(VIO_D6),	GPIO_FN(VIO_D7),
+	GPIO_FN(VIO_D8),	GPIO_FN(VIO_D9),	GPIO_FN(VIO_D10),
+	GPIO_FN(VIO_D11),	GPIO_FN(VIO_D12),	GPIO_FN(VIO_D13),
+	GPIO_FN(VIO_D14),	GPIO_FN(VIO_D15),
+
+	/* USB0 */
+	GPIO_FN(IDIN_0),	GPIO_FN(EXTLP_0),	GPIO_FN(OVCN2_0),
+	GPIO_FN(PWEN_0),	GPIO_FN(OVCN_0),	GPIO_FN(VBUS0_0),
+
+	/* USB1 */
+	GPIO_FN(IDIN_1_18),	GPIO_FN(IDIN_1_113),
+	GPIO_FN(OVCN_1_114),	GPIO_FN(OVCN_1_162),
+	GPIO_FN(PWEN_1_115),	GPIO_FN(PWEN_1_138),
+	GPIO_FN(EXTLP_1),	GPIO_FN(OVCN2_1),
+	GPIO_FN(VBUS0_1),
+
+	/* GPIO */
+	GPIO_FN(GPI0),	GPIO_FN(GPI1),	GPIO_FN(GPO0),	GPIO_FN(GPO1),
+
+	/* BSC */
+	GPIO_FN(BS),	GPIO_FN(WE1),	GPIO_FN(CKO),
+	GPIO_FN(WAIT),	GPIO_FN(RDWR),
+
+	GPIO_FN(A0),	GPIO_FN(A1),	GPIO_FN(A2),
+	GPIO_FN(A3),	GPIO_FN(A6),	GPIO_FN(A7),
+	GPIO_FN(A8),	GPIO_FN(A9),	GPIO_FN(A10),
+	GPIO_FN(A11),	GPIO_FN(A12),	GPIO_FN(A13),
+	GPIO_FN(A14),	GPIO_FN(A15),	GPIO_FN(A16),
+	GPIO_FN(A17),	GPIO_FN(A18),	GPIO_FN(A19),
+	GPIO_FN(A20),	GPIO_FN(A21),	GPIO_FN(A22),
+	GPIO_FN(A23),	GPIO_FN(A24),	GPIO_FN(A25),
+	GPIO_FN(A26),
+
+	GPIO_FN(CS0),	GPIO_FN(CS2),	GPIO_FN(CS4),
+	GPIO_FN(CS5A),	GPIO_FN(CS5B),	GPIO_FN(CS6A),
+
+	/* BSC/FLCTL */
+	GPIO_FN(RD_FSC),	GPIO_FN(WE0_FWE),	GPIO_FN(A4_FOE),
+	GPIO_FN(A5_FCDE),	GPIO_FN(D0_NAF0),	GPIO_FN(D1_NAF1),
+	GPIO_FN(D2_NAF2),	GPIO_FN(D3_NAF3),	GPIO_FN(D4_NAF4),
+	GPIO_FN(D5_NAF5),	GPIO_FN(D6_NAF6),	GPIO_FN(D7_NAF7),
+	GPIO_FN(D8_NAF8),	GPIO_FN(D9_NAF9),	GPIO_FN(D10_NAF10),
+	GPIO_FN(D11_NAF11),	GPIO_FN(D12_NAF12),	GPIO_FN(D13_NAF13),
+	GPIO_FN(D14_NAF14),	GPIO_FN(D15_NAF15),
+
+	/* MMCIF(1) */
+	GPIO_FN(MMCD0_0),	GPIO_FN(MMCD0_1),	GPIO_FN(MMCD0_2),
+	GPIO_FN(MMCD0_3),	GPIO_FN(MMCD0_4),	GPIO_FN(MMCD0_5),
+	GPIO_FN(MMCD0_6),	GPIO_FN(MMCD0_7),	GPIO_FN(MMCCMD0),
+	GPIO_FN(MMCCLK0),
+
+	/* MMCIF(2) */
+	GPIO_FN(MMCD1_0),	GPIO_FN(MMCD1_1),	GPIO_FN(MMCD1_2),
+	GPIO_FN(MMCD1_3),	GPIO_FN(MMCD1_4),	GPIO_FN(MMCD1_5),
+	GPIO_FN(MMCD1_6),	GPIO_FN(MMCD1_7),	GPIO_FN(MMCCLK1),
+	GPIO_FN(MMCCMD1),
+
+	/* SPU2 */
+	GPIO_FN(VINT_I),
+
+	/* FLCTL */
+	GPIO_FN(FCE1),	GPIO_FN(FCE0),	GPIO_FN(FRB),
+
+	/* HSI */
+	GPIO_FN(GP_RX_FLAG),	GPIO_FN(GP_RX_DATA),	GPIO_FN(GP_TX_READY),
+	GPIO_FN(GP_RX_WAKE),	GPIO_FN(MP_TX_FLAG),	GPIO_FN(MP_TX_DATA),
+	GPIO_FN(MP_RX_READY),	GPIO_FN(MP_TX_WAKE),
+
+	/* MFI */
+	GPIO_FN(MFIv6),
+	GPIO_FN(MFIv4),
+
+	GPIO_FN(MEMC_BUSCLK_MEMC_A0),	GPIO_FN(MEMC_ADV_MEMC_DREQ0),
+	GPIO_FN(MEMC_WAIT_MEMC_DREQ1),	GPIO_FN(MEMC_CS1_MEMC_A1),
+	GPIO_FN(MEMC_CS0),	GPIO_FN(MEMC_NOE),
+	GPIO_FN(MEMC_NWE),	GPIO_FN(MEMC_INT),
+
+	GPIO_FN(MEMC_AD0),	GPIO_FN(MEMC_AD1),	GPIO_FN(MEMC_AD2),
+	GPIO_FN(MEMC_AD3),	GPIO_FN(MEMC_AD4),	GPIO_FN(MEMC_AD5),
+	GPIO_FN(MEMC_AD6),	GPIO_FN(MEMC_AD7),	GPIO_FN(MEMC_AD8),
+	GPIO_FN(MEMC_AD9),	GPIO_FN(MEMC_AD10),	GPIO_FN(MEMC_AD11),
+	GPIO_FN(MEMC_AD12),	GPIO_FN(MEMC_AD13),	GPIO_FN(MEMC_AD14),
+	GPIO_FN(MEMC_AD15),
+
+	/* SIM */
+	GPIO_FN(SIM_RST),	GPIO_FN(SIM_CLK),	GPIO_FN(SIM_D),
+
+	/* TPU */
+	GPIO_FN(TPU0TO0),	GPIO_FN(TPU0TO1),	GPIO_FN(TPU0TO2_93),
+	GPIO_FN(TPU0TO2_99),	GPIO_FN(TPU0TO3),
+
+	/* I2C2 */
+	GPIO_FN(I2C_SCL2),	GPIO_FN(I2C_SDA2),
+
+	/* I2C3(1) */
+	GPIO_FN(I2C_SCL3),	GPIO_FN(I2C_SDA3),
+
+	/* I2C3(2) */
+	GPIO_FN(I2C_SCL3S),	GPIO_FN(I2C_SDA3S),
+
+	/* I2C4(2) */
+	GPIO_FN(I2C_SCL4),	GPIO_FN(I2C_SDA4),
+
+	/* I2C4(2) */
+	GPIO_FN(I2C_SCL4S),	GPIO_FN(I2C_SDA4S),
+
+	/* KEYSC */
+	GPIO_FN(KEYOUT0),	GPIO_FN(KEYIN0_121),	GPIO_FN(KEYIN0_136),
+	GPIO_FN(KEYOUT1),	GPIO_FN(KEYIN1_122),	GPIO_FN(KEYIN1_135),
+	GPIO_FN(KEYOUT2),	GPIO_FN(KEYIN2_123),	GPIO_FN(KEYIN2_134),
+	GPIO_FN(KEYOUT3),	GPIO_FN(KEYIN3_124),	GPIO_FN(KEYIN3_133),
+	GPIO_FN(KEYOUT4),	GPIO_FN(KEYIN4),	GPIO_FN(KEYOUT5),
+	GPIO_FN(KEYIN5),	GPIO_FN(KEYOUT6),	GPIO_FN(KEYIN6),
+	GPIO_FN(KEYOUT7),	GPIO_FN(KEYIN7),
+
+	/* LCDC */
+	GPIO_FN(LCDHSYN),	GPIO_FN(LCDCS),	GPIO_FN(LCDVSYN),
+	GPIO_FN(LCDDCK),	GPIO_FN(LCDWR),	GPIO_FN(LCDRD),
+	GPIO_FN(LCDDISP),	GPIO_FN(LCDRS),	GPIO_FN(LCDLCLK),
+	GPIO_FN(LCDDON),
+
+	GPIO_FN(LCDD0),		GPIO_FN(LCDD1),		GPIO_FN(LCDD2),
+	GPIO_FN(LCDD3),		GPIO_FN(LCDD4),		GPIO_FN(LCDD5),
+	GPIO_FN(LCDD6),		GPIO_FN(LCDD7),		GPIO_FN(LCDD8),
+	GPIO_FN(LCDD9),		GPIO_FN(LCDD10),	GPIO_FN(LCDD11),
+	GPIO_FN(LCDD12),	GPIO_FN(LCDD13),	GPIO_FN(LCDD14),
+	GPIO_FN(LCDD15),	GPIO_FN(LCDD16),	GPIO_FN(LCDD17),
+	GPIO_FN(LCDD18),	GPIO_FN(LCDD19),	GPIO_FN(LCDD20),
+	GPIO_FN(LCDD21),	GPIO_FN(LCDD22),	GPIO_FN(LCDD23),
+
+	/* IRDA */
+	GPIO_FN(IRDA_OUT),	GPIO_FN(IRDA_IN),	GPIO_FN(IRDA_FIRSEL),
+	GPIO_FN(IROUT_139),	GPIO_FN(IROUT_140),
+
+	/* TSIF1 */
+	GPIO_FN(TS0_1SELECT),
+	GPIO_FN(TS0_2SELECT),
+	GPIO_FN(TS1_1SELECT),
+	GPIO_FN(TS1_2SELECT),
+
+	GPIO_FN(TS_SPSYNC1),	GPIO_FN(TS_SDAT1),
+	GPIO_FN(TS_SDEN1),	GPIO_FN(TS_SCK1),
+
+	/* TSIF2 */
+	GPIO_FN(TS_SPSYNC2),	GPIO_FN(TS_SDAT2),
+	GPIO_FN(TS_SDEN2),	GPIO_FN(TS_SCK2),
+
+	/* HDMI */
+	GPIO_FN(HDMI_HPD),	GPIO_FN(HDMI_CEC),
+
+	/* SDHI0 */
+	GPIO_FN(SDHICLK0),	GPIO_FN(SDHICD0),	GPIO_FN(SDHICMD0),
+	GPIO_FN(SDHIWP0),	GPIO_FN(SDHID0_0),	GPIO_FN(SDHID0_1),
+	GPIO_FN(SDHID0_2),	GPIO_FN(SDHID0_3),
+
+	/* SDHI1 */
+	GPIO_FN(SDHICLK1),	GPIO_FN(SDHICMD1),	GPIO_FN(SDHID1_0),
+	GPIO_FN(SDHID1_1),	GPIO_FN(SDHID1_2),	GPIO_FN(SDHID1_3),
+
+	/* SDHI2 */
+	GPIO_FN(SDHICLK2),	GPIO_FN(SDHICMD2),	GPIO_FN(SDHID2_0),
+	GPIO_FN(SDHID2_1),	GPIO_FN(SDHID2_2),	GPIO_FN(SDHID2_3),
+
+	/* SDENC */
+	GPIO_FN(SDENC_CPG),
+	GPIO_FN(SDENC_DV_CLKI),
+};
+
+/* helper for top 4 bits in PORTnCR */
+#define PCRH(in, in_pd, in_pu, out)		\
+	0, (out), (in), 0,			\
+	0, 0, 0, 0,				\
+	0, 0, (in_pd), 0,			\
+	0, 0, (in_pu), 0
+
+#define PORTCR(nr, reg)						\
+	{ PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) {		\
+		PCRH(PORT##nr##_IN, PORT##nr##_IN_PD,		\
+		     PORT##nr##_IN_PU, PORT##nr##_OUT),		\
+		PORT##nr##_FN0, PORT##nr##_FN1, PORT##nr##_FN2,	\
+		PORT##nr##_FN3,	PORT##nr##_FN4, PORT##nr##_FN5,	\
+		PORT##nr##_FN6, PORT##nr##_FN7 }		\
+	}
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+	PORTCR(0,	0xE6051000), /* PORT0CR */
+	PORTCR(1,	0xE6051001), /* PORT1CR */
+	PORTCR(2,	0xE6051002), /* PORT2CR */
+	PORTCR(3,	0xE6051003), /* PORT3CR */
+	PORTCR(4,	0xE6051004), /* PORT4CR */
+	PORTCR(5,	0xE6051005), /* PORT5CR */
+	PORTCR(6,	0xE6051006), /* PORT6CR */
+	PORTCR(7,	0xE6051007), /* PORT7CR */
+	PORTCR(8,	0xE6051008), /* PORT8CR */
+	PORTCR(9,	0xE6051009), /* PORT9CR */
+	PORTCR(10,	0xE605100A), /* PORT10CR */
+	PORTCR(11,	0xE605100B), /* PORT11CR */
+	PORTCR(12,	0xE605100C), /* PORT12CR */
+	PORTCR(13,	0xE605100D), /* PORT13CR */
+	PORTCR(14,	0xE605100E), /* PORT14CR */
+	PORTCR(15,	0xE605100F), /* PORT15CR */
+	PORTCR(16,	0xE6051010), /* PORT16CR */
+	PORTCR(17,	0xE6051011), /* PORT17CR */
+	PORTCR(18,	0xE6051012), /* PORT18CR */
+	PORTCR(19,	0xE6051013), /* PORT19CR */
+	PORTCR(20,	0xE6051014), /* PORT20CR */
+	PORTCR(21,	0xE6051015), /* PORT21CR */
+	PORTCR(22,	0xE6051016), /* PORT22CR */
+	PORTCR(23,	0xE6051017), /* PORT23CR */
+	PORTCR(24,	0xE6051018), /* PORT24CR */
+	PORTCR(25,	0xE6051019), /* PORT25CR */
+	PORTCR(26,	0xE605101A), /* PORT26CR */
+	PORTCR(27,	0xE605101B), /* PORT27CR */
+	PORTCR(28,	0xE605101C), /* PORT28CR */
+	PORTCR(29,	0xE605101D), /* PORT29CR */
+	PORTCR(30,	0xE605101E), /* PORT30CR */
+	PORTCR(31,	0xE605101F), /* PORT31CR */
+	PORTCR(32,	0xE6051020), /* PORT32CR */
+	PORTCR(33,	0xE6051021), /* PORT33CR */
+	PORTCR(34,	0xE6051022), /* PORT34CR */
+	PORTCR(35,	0xE6051023), /* PORT35CR */
+	PORTCR(36,	0xE6051024), /* PORT36CR */
+	PORTCR(37,	0xE6051025), /* PORT37CR */
+	PORTCR(38,	0xE6051026), /* PORT38CR */
+	PORTCR(39,	0xE6051027), /* PORT39CR */
+	PORTCR(40,	0xE6051028), /* PORT40CR */
+	PORTCR(41,	0xE6051029), /* PORT41CR */
+	PORTCR(42,	0xE605102A), /* PORT42CR */
+	PORTCR(43,	0xE605102B), /* PORT43CR */
+	PORTCR(44,	0xE605102C), /* PORT44CR */
+	PORTCR(45,	0xE605102D), /* PORT45CR */
+	PORTCR(46,	0xE605202E), /* PORT46CR */
+	PORTCR(47,	0xE605202F), /* PORT47CR */
+	PORTCR(48,	0xE6052030), /* PORT48CR */
+	PORTCR(49,	0xE6052031), /* PORT49CR */
+	PORTCR(50,	0xE6052032), /* PORT50CR */
+	PORTCR(51,	0xE6052033), /* PORT51CR */
+	PORTCR(52,	0xE6052034), /* PORT52CR */
+	PORTCR(53,	0xE6052035), /* PORT53CR */
+	PORTCR(54,	0xE6052036), /* PORT54CR */
+	PORTCR(55,	0xE6052037), /* PORT55CR */
+	PORTCR(56,	0xE6052038), /* PORT56CR */
+	PORTCR(57,	0xE6052039), /* PORT57CR */
+	PORTCR(58,	0xE605203A), /* PORT58CR */
+	PORTCR(59,	0xE605203B), /* PORT59CR */
+	PORTCR(60,	0xE605203C), /* PORT60CR */
+	PORTCR(61,	0xE605203D), /* PORT61CR */
+	PORTCR(62,	0xE605203E), /* PORT62CR */
+	PORTCR(63,	0xE605203F), /* PORT63CR */
+	PORTCR(64,	0xE6052040), /* PORT64CR */
+	PORTCR(65,	0xE6052041), /* PORT65CR */
+	PORTCR(66,	0xE6052042), /* PORT66CR */
+	PORTCR(67,	0xE6052043), /* PORT67CR */
+	PORTCR(68,	0xE6052044), /* PORT68CR */
+	PORTCR(69,	0xE6052045), /* PORT69CR */
+	PORTCR(70,	0xE6052046), /* PORT70CR */
+	PORTCR(71,	0xE6052047), /* PORT71CR */
+	PORTCR(72,	0xE6052048), /* PORT72CR */
+	PORTCR(73,	0xE6052049), /* PORT73CR */
+	PORTCR(74,	0xE605204A), /* PORT74CR */
+	PORTCR(75,	0xE605204B), /* PORT75CR */
+	PORTCR(76,	0xE605004C), /* PORT76CR */
+	PORTCR(77,	0xE605004D), /* PORT77CR */
+	PORTCR(78,	0xE605004E), /* PORT78CR */
+	PORTCR(79,	0xE605004F), /* PORT79CR */
+	PORTCR(80,	0xE6050050), /* PORT80CR */
+	PORTCR(81,	0xE6050051), /* PORT81CR */
+	PORTCR(82,	0xE6050052), /* PORT82CR */
+	PORTCR(83,	0xE6050053), /* PORT83CR */
+	PORTCR(84,	0xE6050054), /* PORT84CR */
+	PORTCR(85,	0xE6050055), /* PORT85CR */
+	PORTCR(86,	0xE6050056), /* PORT86CR */
+	PORTCR(87,	0xE6050057), /* PORT87CR */
+	PORTCR(88,	0xE6050058), /* PORT88CR */
+	PORTCR(89,	0xE6050059), /* PORT89CR */
+	PORTCR(90,	0xE605005A), /* PORT90CR */
+	PORTCR(91,	0xE605005B), /* PORT91CR */
+	PORTCR(92,	0xE605005C), /* PORT92CR */
+	PORTCR(93,	0xE605005D), /* PORT93CR */
+	PORTCR(94,	0xE605005E), /* PORT94CR */
+	PORTCR(95,	0xE605005F), /* PORT95CR */
+	PORTCR(96,	0xE6050060), /* PORT96CR */
+	PORTCR(97,	0xE6050061), /* PORT97CR */
+	PORTCR(98,	0xE6050062), /* PORT98CR */
+	PORTCR(99,	0xE6050063), /* PORT99CR */
+	PORTCR(100,	0xE6053064), /* PORT100CR */
+	PORTCR(101,	0xE6053065), /* PORT101CR */
+	PORTCR(102,	0xE6053066), /* PORT102CR */
+	PORTCR(103,	0xE6053067), /* PORT103CR */
+	PORTCR(104,	0xE6053068), /* PORT104CR */
+	PORTCR(105,	0xE6053069), /* PORT105CR */
+	PORTCR(106,	0xE605306A), /* PORT106CR */
+	PORTCR(107,	0xE605306B), /* PORT107CR */
+	PORTCR(108,	0xE605306C), /* PORT108CR */
+	PORTCR(109,	0xE605306D), /* PORT109CR */
+	PORTCR(110,	0xE605306E), /* PORT110CR */
+	PORTCR(111,	0xE605306F), /* PORT111CR */
+	PORTCR(112,	0xE6053070), /* PORT112CR */
+	PORTCR(113,	0xE6053071), /* PORT113CR */
+	PORTCR(114,	0xE6053072), /* PORT114CR */
+	PORTCR(115,	0xE6053073), /* PORT115CR */
+	PORTCR(116,	0xE6053074), /* PORT116CR */
+	PORTCR(117,	0xE6053075), /* PORT117CR */
+	PORTCR(118,	0xE6053076), /* PORT118CR */
+	PORTCR(119,	0xE6053077), /* PORT119CR */
+	PORTCR(120,	0xE6053078), /* PORT120CR */
+	PORTCR(121,	0xE6050079), /* PORT121CR */
+	PORTCR(122,	0xE605007A), /* PORT122CR */
+	PORTCR(123,	0xE605007B), /* PORT123CR */
+	PORTCR(124,	0xE605007C), /* PORT124CR */
+	PORTCR(125,	0xE605007D), /* PORT125CR */
+	PORTCR(126,	0xE605007E), /* PORT126CR */
+	PORTCR(127,	0xE605007F), /* PORT127CR */
+	PORTCR(128,	0xE6050080), /* PORT128CR */
+	PORTCR(129,	0xE6050081), /* PORT129CR */
+	PORTCR(130,	0xE6050082), /* PORT130CR */
+	PORTCR(131,	0xE6050083), /* PORT131CR */
+	PORTCR(132,	0xE6050084), /* PORT132CR */
+	PORTCR(133,	0xE6050085), /* PORT133CR */
+	PORTCR(134,	0xE6050086), /* PORT134CR */
+	PORTCR(135,	0xE6050087), /* PORT135CR */
+	PORTCR(136,	0xE6050088), /* PORT136CR */
+	PORTCR(137,	0xE6050089), /* PORT137CR */
+	PORTCR(138,	0xE605008A), /* PORT138CR */
+	PORTCR(139,	0xE605008B), /* PORT139CR */
+	PORTCR(140,	0xE605008C), /* PORT140CR */
+	PORTCR(141,	0xE605008D), /* PORT141CR */
+	PORTCR(142,	0xE605008E), /* PORT142CR */
+	PORTCR(143,	0xE605008F), /* PORT143CR */
+	PORTCR(144,	0xE6050090), /* PORT144CR */
+	PORTCR(145,	0xE6050091), /* PORT145CR */
+	PORTCR(146,	0xE6050092), /* PORT146CR */
+	PORTCR(147,	0xE6050093), /* PORT147CR */
+	PORTCR(148,	0xE6050094), /* PORT148CR */
+	PORTCR(149,	0xE6050095), /* PORT149CR */
+	PORTCR(150,	0xE6050096), /* PORT150CR */
+	PORTCR(151,	0xE6050097), /* PORT151CR */
+	PORTCR(152,	0xE6053098), /* PORT152CR */
+	PORTCR(153,	0xE6053099), /* PORT153CR */
+	PORTCR(154,	0xE605309A), /* PORT154CR */
+	PORTCR(155,	0xE605309B), /* PORT155CR */
+	PORTCR(156,	0xE605009C), /* PORT156CR */
+	PORTCR(157,	0xE605009D), /* PORT157CR */
+	PORTCR(158,	0xE605009E), /* PORT158CR */
+	PORTCR(159,	0xE605009F), /* PORT159CR */
+	PORTCR(160,	0xE60500A0), /* PORT160CR */
+	PORTCR(161,	0xE60500A1), /* PORT161CR */
+	PORTCR(162,	0xE60500A2), /* PORT162CR */
+	PORTCR(163,	0xE60500A3), /* PORT163CR */
+	PORTCR(164,	0xE60500A4), /* PORT164CR */
+	PORTCR(165,	0xE60500A5), /* PORT165CR */
+	PORTCR(166,	0xE60500A6), /* PORT166CR */
+	PORTCR(167,	0xE60520A7), /* PORT167CR */
+	PORTCR(168,	0xE60520A8), /* PORT168CR */
+	PORTCR(169,	0xE60520A9), /* PORT169CR */
+	PORTCR(170,	0xE60520AA), /* PORT170CR */
+	PORTCR(171,	0xE60520AB), /* PORT171CR */
+	PORTCR(172,	0xE60520AC), /* PORT172CR */
+	PORTCR(173,	0xE60520AD), /* PORT173CR */
+	PORTCR(174,	0xE60520AE), /* PORT174CR */
+	PORTCR(175,	0xE60520AF), /* PORT175CR */
+	PORTCR(176,	0xE60520B0), /* PORT176CR */
+	PORTCR(177,	0xE60520B1), /* PORT177CR */
+	PORTCR(178,	0xE60520B2), /* PORT178CR */
+	PORTCR(179,	0xE60520B3), /* PORT179CR */
+	PORTCR(180,	0xE60520B4), /* PORT180CR */
+	PORTCR(181,	0xE60520B5), /* PORT181CR */
+	PORTCR(182,	0xE60520B6), /* PORT182CR */
+	PORTCR(183,	0xE60520B7), /* PORT183CR */
+	PORTCR(184,	0xE60520B8), /* PORT184CR */
+	PORTCR(185,	0xE60520B9), /* PORT185CR */
+	PORTCR(186,	0xE60520BA), /* PORT186CR */
+	PORTCR(187,	0xE60520BB), /* PORT187CR */
+	PORTCR(188,	0xE60520BC), /* PORT188CR */
+	PORTCR(189,	0xE60520BD), /* PORT189CR */
+	PORTCR(190,	0xE60520BE), /* PORT190CR */
+
+	{ PINMUX_CFG_REG("MSEL1CR", 0xE605800C, 32, 1) {
+			MSEL1CR_31_0,	MSEL1CR_31_1,
+			MSEL1CR_30_0,	MSEL1CR_30_1,
+			MSEL1CR_29_0,	MSEL1CR_29_1,
+			MSEL1CR_28_0,	MSEL1CR_28_1,
+			MSEL1CR_27_0,	MSEL1CR_27_1,
+			MSEL1CR_26_0,	MSEL1CR_26_1,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0,
+			MSEL1CR_16_0,	MSEL1CR_16_1,
+			MSEL1CR_15_0,	MSEL1CR_15_1,
+			MSEL1CR_14_0,	MSEL1CR_14_1,
+			MSEL1CR_13_0,	MSEL1CR_13_1,
+			MSEL1CR_12_0,	MSEL1CR_12_1,
+			0, 0, 0, 0,
+			MSEL1CR_9_0,	MSEL1CR_9_1,
+			MSEL1CR_8_0,	MSEL1CR_8_1,
+			MSEL1CR_7_0,	MSEL1CR_7_1,
+			MSEL1CR_6_0,	MSEL1CR_6_1,
+			0, 0,
+			MSEL1CR_4_0,	MSEL1CR_4_1,
+			MSEL1CR_3_0,	MSEL1CR_3_1,
+			MSEL1CR_2_0,	MSEL1CR_2_1,
+			0, 0,
+			MSEL1CR_0_0,	MSEL1CR_0_1,
+		}
+	},
+	{ PINMUX_CFG_REG("MSEL3CR", 0xE6058020, 32, 1) {
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			MSEL3CR_27_0,	MSEL3CR_27_1,
+			MSEL3CR_26_0,	MSEL3CR_26_1,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			MSEL3CR_21_0,	MSEL3CR_21_1,
+			MSEL3CR_20_0,	MSEL3CR_20_1,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			MSEL3CR_15_0,	MSEL3CR_15_1,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0,
+			MSEL3CR_9_0,	MSEL3CR_9_1,
+			0, 0, 0, 0,
+			MSEL3CR_6_0,	MSEL3CR_6_1,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			}
+	},
+	{ PINMUX_CFG_REG("MSEL4CR", 0xE6058024, 32, 1) {
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			MSEL4CR_19_0,	MSEL4CR_19_1,
+			MSEL4CR_18_0,	MSEL4CR_18_1,
+			MSEL4CR_17_0,	MSEL4CR_17_1,
+			MSEL4CR_16_0,	MSEL4CR_16_1,
+			MSEL4CR_15_0,	MSEL4CR_15_1,
+			MSEL4CR_14_0,	MSEL4CR_14_1,
+			0, 0, 0, 0,
+			0, 0,
+			MSEL4CR_10_0,	MSEL4CR_10_1,
+			0, 0, 0, 0,
+			0, 0,
+			MSEL4CR_6_0,	MSEL4CR_6_1,
+			0, 0,
+			MSEL4CR_4_0,	MSEL4CR_4_1,
+			0, 0, 0, 0,
+			MSEL4CR_1_0,	MSEL4CR_1_1,
+			0, 0,
+		}
+	},
+	{ },
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+	{ PINMUX_DATA_REG("PORTL095_064DR", 0xE6054008, 32) {
+			PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA,
+			PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA,
+			PORT87_DATA, PORT86_DATA, PORT85_DATA, PORT84_DATA,
+			PORT83_DATA, PORT82_DATA, PORT81_DATA, PORT80_DATA,
+			PORT79_DATA, PORT78_DATA, PORT77_DATA, PORT76_DATA,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+		}
+	},
+	{ PINMUX_DATA_REG("PORTL127_096DR", 0xE605400C, 32) {
+			PORT127_DATA, PORT126_DATA, PORT125_DATA, PORT124_DATA,
+			PORT123_DATA, PORT122_DATA, PORT121_DATA, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			PORT99_DATA,  PORT98_DATA,  PORT97_DATA,  PORT96_DATA,
+		}
+	},
+	{ PINMUX_DATA_REG("PORTL159_128DR", 0xE6054010, 32) {
+			PORT159_DATA, PORT158_DATA, PORT157_DATA, PORT156_DATA,
+			0, 0, 0, 0,
+			PORT151_DATA, PORT150_DATA, PORT149_DATA, PORT148_DATA,
+			PORT147_DATA, PORT146_DATA, PORT145_DATA, PORT144_DATA,
+			PORT143_DATA, PORT142_DATA, PORT141_DATA, PORT140_DATA,
+			PORT139_DATA, PORT138_DATA, PORT137_DATA, PORT136_DATA,
+			PORT135_DATA, PORT134_DATA, PORT133_DATA, PORT132_DATA,
+			PORT131_DATA, PORT130_DATA, PORT129_DATA, PORT128_DATA,
+		}
+	},
+	{ PINMUX_DATA_REG("PORTL191_160DR", 0xE6054014, 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,	      PORT166_DATA, PORT165_DATA, PORT164_DATA,
+			PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA,
+		}
+	},
+	{ PINMUX_DATA_REG("PORTD031_000DR", 0xE6055000, 32) {
+			PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA,
+			PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA,
+			PORT23_DATA, PORT22_DATA, PORT21_DATA, PORT20_DATA,
+			PORT19_DATA, PORT18_DATA, PORT17_DATA, PORT16_DATA,
+			PORT15_DATA, PORT14_DATA, PORT13_DATA, PORT12_DATA,
+			PORT11_DATA, PORT10_DATA, PORT9_DATA,  PORT8_DATA,
+			PORT7_DATA,  PORT6_DATA,  PORT5_DATA,  PORT4_DATA,
+			PORT3_DATA,  PORT2_DATA,  PORT1_DATA,  PORT0_DATA,
+		}
+	},
+	{ PINMUX_DATA_REG("PORTD063_032DR", 0xE6055004, 32) {
+			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0,
+			0,           0,           PORT45_DATA, PORT44_DATA,
+			PORT43_DATA, PORT42_DATA, PORT41_DATA, PORT40_DATA,
+			PORT39_DATA, PORT38_DATA, PORT37_DATA, PORT36_DATA,
+			PORT35_DATA, PORT34_DATA, PORT33_DATA, PORT32_DATA,
+		}
+	},
+	{ PINMUX_DATA_REG("PORTR063_032DR", 0xE6056004, 32) {
+			PORT63_DATA, PORT62_DATA, PORT61_DATA, PORT60_DATA,
+			PORT59_DATA, PORT58_DATA, PORT57_DATA, PORT56_DATA,
+			PORT55_DATA, PORT54_DATA, PORT53_DATA, PORT52_DATA,
+			PORT51_DATA, PORT50_DATA, PORT49_DATA, PORT48_DATA,
+			PORT47_DATA, PORT46_DATA, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+		}
+	},
+	{ PINMUX_DATA_REG("PORTR095_064DR", 0xE6056008, 32) {
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			PORT75_DATA, PORT74_DATA, PORT73_DATA, PORT72_DATA,
+			PORT71_DATA, PORT70_DATA, PORT69_DATA, PORT68_DATA,
+			PORT67_DATA, PORT66_DATA, PORT65_DATA, PORT64_DATA,
+		}
+	},
+	{ PINMUX_DATA_REG("PORTR191_160DR", 0xE6056014, 32) {
+			0,	      PORT190_DATA, PORT189_DATA, PORT188_DATA,
+			PORT187_DATA, PORT186_DATA, PORT185_DATA, PORT184_DATA,
+			PORT183_DATA, PORT182_DATA, PORT181_DATA, PORT180_DATA,
+			PORT179_DATA, PORT178_DATA, PORT177_DATA, PORT176_DATA,
+			PORT175_DATA, PORT174_DATA, PORT173_DATA, PORT172_DATA,
+			PORT171_DATA, PORT170_DATA, PORT169_DATA, PORT168_DATA,
+			PORT167_DATA, 0, 0, 0,
+			0, 0, 0, 0,
+		}
+	},
+	{ PINMUX_DATA_REG("PORTU127_096DR", 0xE605700C, 32) {
+			0, 0, 0, 0,
+			0, 0, 0, PORT120_DATA,
+			PORT119_DATA, PORT118_DATA, PORT117_DATA, PORT116_DATA,
+			PORT115_DATA, PORT114_DATA, PORT113_DATA, PORT112_DATA,
+			PORT111_DATA, PORT110_DATA, PORT109_DATA, PORT108_DATA,
+			PORT107_DATA, PORT106_DATA, PORT105_DATA, PORT104_DATA,
+			PORT103_DATA, PORT102_DATA, PORT101_DATA, PORT100_DATA,
+			0, 0, 0, 0,
+		}
+	},
+	{ PINMUX_DATA_REG("PORTU159_128DR", 0xE6057010, 32) {
+			0, 0, 0, 0,
+			PORT155_DATA, PORT154_DATA, PORT153_DATA, PORT152_DATA,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+		}
+	},
+	{ },
+};
+
+static struct pinmux_info sh7372_pinmux_info = {
+	.name = "sh7372_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 },
+	.input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_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_PORT0,
+	.last_gpio = GPIO_FN_SDENC_DV_CLKI,
+
+	.gpios = pinmux_gpios,
+	.cfg_regs = pinmux_config_regs,
+	.data_regs = pinmux_data_regs,
+
+	.gpio_data = pinmux_data,
+	.gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+void sh7372_pinmux_init(void)
+{
+	register_pinmux(&sh7372_pinmux_info);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/pfc-sh7377.c linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/pfc-sh7377.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/pfc-sh7377.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/pfc-sh7377.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1767 @@
+/*
+ * sh7377 processor support - PFC hardware block
+ *
+ * Copyright (C) 2010  NISHIMOTO Hiroki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <mach/sh7377.h>
+
+#define _1(fn, pfx, sfx) fn(pfx, sfx)
+
+#define _10(fn, pfx, sfx)				\
+	_1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx),	\
+	_1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx),	\
+	_1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx),	\
+	_1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx),	\
+	_1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
+
+#define _90(fn, pfx, sfx)				\
+	_10(fn, pfx##1, sfx), _10(fn, pfx##2, sfx),	\
+	_10(fn, pfx##3, sfx), _10(fn, pfx##4, sfx),	\
+	_10(fn, pfx##5, sfx), _10(fn, pfx##6, sfx),	\
+	_10(fn, pfx##7, sfx), _10(fn, pfx##8, sfx),	\
+	_10(fn, pfx##9, sfx)
+
+#define _265(fn, pfx, sfx)				\
+	_10(fn, pfx, sfx), _90(fn, pfx, sfx),		\
+	_10(fn, pfx##10, sfx),				\
+	_1(fn, pfx##110, sfx), _1(fn, pfx##111, sfx),	\
+	_1(fn, pfx##112, sfx), _1(fn, pfx##113, sfx),	\
+	_1(fn, pfx##114, sfx), _1(fn, pfx##115, sfx),	\
+	_1(fn, pfx##116, sfx), _1(fn, pfx##117, sfx),	\
+	_1(fn, pfx##118, sfx),				\
+	_1(fn, pfx##128, sfx), _1(fn, pfx##129, sfx),	\
+	_10(fn, pfx##13, sfx), _10(fn, pfx##14, sfx),	\
+	_10(fn, pfx##15, sfx),				\
+	_1(fn, pfx##160, sfx), _1(fn, pfx##161, sfx),	\
+	_1(fn, pfx##162, sfx), _1(fn, pfx##163, sfx),	\
+	_1(fn, pfx##164, sfx),				\
+	_1(fn, pfx##192, sfx), _1(fn, pfx##193, sfx),	\
+	_1(fn, pfx##194, sfx), _1(fn, pfx##195, sfx),	\
+	_1(fn, pfx##196, sfx), _1(fn, pfx##197, sfx),	\
+	_1(fn, pfx##198, sfx), _1(fn, pfx##199, sfx),	\
+	_10(fn, pfx##20, sfx), _10(fn, pfx##21, sfx),	\
+	_10(fn, pfx##22, sfx), _10(fn, pfx##23, sfx),	\
+	_10(fn, pfx##24, sfx), _10(fn, pfx##25, sfx),	\
+	_1(fn, pfx##260, sfx), _1(fn, pfx##261, sfx),	\
+	_1(fn, pfx##262, sfx), _1(fn, pfx##263, sfx),	\
+	_1(fn, pfx##264, sfx)
+
+#define _PORT(pfx, sfx) pfx##_##sfx
+#define PORT_265(str) _265(_PORT, PORT, str)
+
+enum {
+	PINMUX_RESERVED = 0,
+
+	PINMUX_DATA_BEGIN,
+	PORT_265(DATA), /* PORT0_DATA -> PORT264_DATA */
+	PINMUX_DATA_END,
+
+	PINMUX_INPUT_BEGIN,
+	PORT_265(IN), /* PORT0_IN -> PORT264_IN */
+	PINMUX_INPUT_END,
+
+	PINMUX_INPUT_PULLUP_BEGIN,
+	PORT_265(IN_PU), /* PORT0_IN_PU -> PORT264_IN_PU */
+	PINMUX_INPUT_PULLUP_END,
+
+	PINMUX_INPUT_PULLDOWN_BEGIN,
+	PORT_265(IN_PD), /* PORT0_IN_PD -> PORT264_IN_PD */
+	PINMUX_INPUT_PULLDOWN_END,
+
+	PINMUX_OUTPUT_BEGIN,
+	PORT_265(OUT), /* PORT0_OUT -> PORT264_OUT */
+	PINMUX_OUTPUT_END,
+
+	PINMUX_FUNCTION_BEGIN,
+	PORT_265(FN_IN), /* PORT0_FN_IN -> PORT264_FN_IN */
+	PORT_265(FN_OUT), /* PORT0_FN_OUT -> PORT264_FN_OUT */
+	PORT_265(FN0), /* PORT0_FN0 -> PORT264_FN0 */
+	PORT_265(FN1), /* PORT0_FN1 -> PORT264_FN1 */
+	PORT_265(FN2), /* PORT0_FN2 -> PORT264_FN2 */
+	PORT_265(FN3), /* PORT0_FN3 -> PORT264_FN3 */
+	PORT_265(FN4), /* PORT0_FN4 -> PORT264_FN4 */
+	PORT_265(FN5), /* PORT0_FN5 -> PORT264_FN5 */
+	PORT_265(FN6), /* PORT0_FN6 -> PORT264_FN6 */
+	PORT_265(FN7), /* PORT0_FN7 -> PORT264_FN7 */
+
+	MSELBCR_MSEL17_1, MSELBCR_MSEL17_0,
+	MSELBCR_MSEL16_1, MSELBCR_MSEL16_0,
+	PINMUX_FUNCTION_END,
+
+	PINMUX_MARK_BEGIN,
+	/* Special Pull-up / Pull-down Functions */
+	PORT66_KEYIN0_PU_MARK, PORT67_KEYIN1_PU_MARK,
+	PORT68_KEYIN2_PU_MARK, PORT69_KEYIN3_PU_MARK,
+	PORT70_KEYIN4_PU_MARK, PORT71_KEYIN5_PU_MARK,
+	PORT72_KEYIN6_PU_MARK,
+
+	/* 55-1 */
+	VBUS_0_MARK,
+	CPORT0_MARK,
+	CPORT1_MARK,
+	CPORT2_MARK,
+	CPORT3_MARK,
+	CPORT4_MARK,
+	CPORT5_MARK,
+	CPORT6_MARK,
+	CPORT7_MARK,
+	CPORT8_MARK,
+	CPORT9_MARK,
+	CPORT10_MARK,
+	CPORT11_MARK, SIN2_MARK,
+	CPORT12_MARK, XCTS2_MARK,
+	CPORT13_MARK, RFSPO4_MARK,
+	CPORT14_MARK, RFSPO5_MARK,
+	CPORT15_MARK, SCIFA0_SCK_MARK, GPS_AGC2_MARK,
+	CPORT16_MARK, SCIFA0_TXD_MARK, GPS_AGC3_MARK,
+	CPORT17_IC_OE_MARK, SOUT2_MARK,
+	CPORT18_MARK, XRTS2_MARK, PORT19_VIO_CKO2_MARK,
+	CPORT19_MPORT1_MARK,
+	CPORT20_MARK, RFSPO6_MARK,
+	CPORT21_MARK, STATUS0_MARK,
+	CPORT22_MARK, STATUS1_MARK,
+	CPORT23_MARK, STATUS2_MARK, RFSPO7_MARK,
+	B_SYNLD1_MARK,
+	B_SYNLD2_MARK, SYSENMSK_MARK,
+	XMAINPS_MARK,
+	XDIVPS_MARK,
+	XIDRST_MARK,
+	IDCLK_MARK, IC_DP_MARK,
+	IDIO_MARK, IC_DM_MARK,
+	SOUT1_MARK, SCIFA4_TXD_MARK, M02_BERDAT_MARK,
+	SIN1_MARK, SCIFA4_RXD_MARK, XWUP_MARK,
+	XRTS1_MARK, SCIFA4_RTS_MARK, M03_BERCLK_MARK,
+	XCTS1_MARK, SCIFA4_CTS_MARK,
+	PCMCLKO_MARK,
+	SYNC8KO_MARK,
+
+	/* 55-2 */
+	DNPCM_A_MARK,
+	UPPCM_A_MARK,
+	VACK_MARK,
+	XTALB1L_MARK,
+	GPS_AGC1_MARK, SCIFA0_RTS_MARK,
+	GPS_AGC4_MARK, SCIFA0_RXD_MARK,
+	GPS_PWRDOWN_MARK, SCIFA0_CTS_MARK,
+	GPS_IM_MARK,
+	GPS_IS_MARK,
+	GPS_QM_MARK,
+	GPS_QS_MARK,
+	FMSOCK_MARK, PORT49_IRDA_OUT_MARK, PORT49_IROUT_MARK,
+	FMSOOLR_MARK, BBIF2_TSYNC2_MARK, TPU2TO2_MARK, IPORT3_MARK,
+	FMSIOLR_MARK,
+	FMSOOBT_MARK, BBIF2_TSCK2_MARK, TPU2TO3_MARK, OPORT1_MARK,
+	FMSIOBT_MARK,
+	FMSOSLD_MARK, BBIF2_TXD2_MARK, OPORT2_MARK,
+	FMSOILR_MARK, PORT53_IRDA_IN_MARK, TPU3TO3_MARK, OPORT3_MARK,
+	FMSIILR_MARK,
+	FMSOIBT_MARK, PORT54_IRDA_FIRSEL_MARK, TPU3TO2_MARK, FMSIIBT_MARK,
+	FMSISLD_MARK, MFG0_OUT1_MARK, TPU0TO0_MARK,
+	A0_EA0_MARK, BS_MARK,
+	A12_EA12_MARK, PORT58_VIO_CKOR_MARK, TPU4TO2_MARK,
+	A13_EA13_MARK, PORT59_IROUT_MARK, MFG0_OUT2_MARK, TPU0TO1_MARK,
+	A14_EA14_MARK, PORT60_KEYOUT5_MARK,
+	A15_EA15_MARK, PORT61_KEYOUT4_MARK,
+	A16_EA16_MARK, PORT62_KEYOUT3_MARK, MSIOF0_SS1_MARK,
+	A17_EA17_MARK, PORT63_KEYOUT2_MARK, MSIOF0_TSYNC_MARK,
+	A18_EA18_MARK, PORT64_KEYOUT1_MARK, MSIOF0_TSCK_MARK,
+	A19_EA19_MARK, PORT65_KEYOUT0_MARK, MSIOF0_TXD_MARK,
+	A20_EA20_MARK, PORT66_KEYIN0_MARK, MSIOF0_RSCK_MARK,
+	A21_EA21_MARK, PORT67_KEYIN1_MARK, MSIOF0_RSYNC_MARK,
+	A22_EA22_MARK, PORT68_KEYIN2_MARK, MSIOF0_MCK0_MARK,
+	A23_EA23_MARK, PORT69_KEYIN3_MARK, MSIOF0_MCK1_MARK,
+	A24_EA24_MARK, PORT70_KEYIN4_MARK, MSIOF0_RXD_MARK,
+	A25_EA25_MARK, PORT71_KEYIN5_MARK, MSIOF0_SS2_MARK,
+	A26_MARK, PORT72_KEYIN6_MARK,
+	D0_ED0_NAF0_MARK,
+	D1_ED1_NAF1_MARK,
+	D2_ED2_NAF2_MARK,
+	D3_ED3_NAF3_MARK,
+	D4_ED4_NAF4_MARK,
+	D5_ED5_NAF5_MARK,
+	D6_ED6_NAF6_MARK,
+	D7_ED7_NAF7_MARK,
+	D8_ED8_NAF8_MARK,
+	D9_ED9_NAF9_MARK,
+	D10_ED10_NAF10_MARK,
+	D11_ED11_NAF11_MARK,
+	D12_ED12_NAF12_MARK,
+	D13_ED13_NAF13_MARK,
+	D14_ED14_NAF14_MARK,
+	D15_ED15_NAF15_MARK,
+	CS4_MARK,
+	CS5A_MARK, FMSICK_MARK,
+	CS5B_MARK, FCE1_MARK,
+
+	/* 55-3 */
+	CS6B_MARK, XCS2_MARK, CS6A_MARK, DACK0_MARK,
+	FCE0_MARK,
+	WAIT_MARK, DREQ0_MARK,
+	RD_XRD_MARK,
+	WE0_XWR0_FWE_MARK,
+	WE1_XWR1_MARK,
+	FRB_MARK,
+	CKO_MARK,
+	NBRSTOUT_MARK,
+	NBRST_MARK,
+	GPS_EPPSIN_MARK,
+	LATCHPULSE_MARK,
+	LTESIGNAL_MARK,
+	LEGACYSTATE_MARK,
+	TCKON_MARK,
+	VIO_VD_MARK, PORT128_KEYOUT0_MARK, IPORT0_MARK,
+	VIO_HD_MARK, PORT129_KEYOUT1_MARK, IPORT1_MARK,
+	VIO_D0_MARK, PORT130_KEYOUT2_MARK, PORT130_MSIOF2_RXD_MARK,
+	VIO_D1_MARK, PORT131_KEYOUT3_MARK, PORT131_MSIOF2_SS1_MARK,
+	VIO_D2_MARK, PORT132_KEYOUT4_MARK, PORT132_MSIOF2_SS2_MARK,
+	VIO_D3_MARK, PORT133_KEYOUT5_MARK, PORT133_MSIOF2_TSYNC_MARK,
+	VIO_D4_MARK, PORT134_KEYIN0_MARK, PORT134_MSIOF2_TXD_MARK,
+	VIO_D5_MARK, PORT135_KEYIN1_MARK, PORT135_MSIOF2_TSCK_MARK,
+	VIO_D6_MARK, PORT136_KEYIN2_MARK,
+	VIO_D7_MARK, PORT137_KEYIN3_MARK,
+	VIO_D8_MARK, M9_SLCD_A01_MARK, PORT138_FSIAOMC_MARK,
+	VIO_D9_MARK, M10_SLCD_CK1_MARK, PORT139_FSIAOLR_MARK,
+	VIO_D10_MARK, M11_SLCD_SO1_MARK, TPU0TO2_MARK, PORT140_FSIAOBT_MARK,
+	VIO_D11_MARK, M12_SLCD_CE1_MARK, TPU0TO3_MARK, PORT141_FSIAOSLD_MARK,
+	VIO_D12_MARK, M13_BSW_MARK, PORT142_FSIACK_MARK,
+	VIO_D13_MARK, M14_GSW_MARK, PORT143_FSIAILR_MARK,
+	VIO_D14_MARK, M15_RSW_MARK, PORT144_FSIAIBT_MARK,
+	VIO_D15_MARK, TPU1TO3_MARK, PORT145_FSIAISLD_MARK,
+	VIO_CLK_MARK, PORT146_KEYIN4_MARK, IPORT2_MARK,
+	VIO_FIELD_MARK, PORT147_KEYIN5_MARK,
+	VIO_CKO_MARK, PORT148_KEYIN6_MARK,
+	A27_MARK, RDWR_XWE_MARK, MFG0_IN1_MARK,
+	MFG0_IN2_MARK,
+	TS_SPSYNC3_MARK, MSIOF2_RSCK_MARK,
+	TS_SDAT3_MARK, MSIOF2_RSYNC_MARK,
+	TPU1TO2_MARK, TS_SDEN3_MARK, PORT153_MSIOF2_SS1_MARK,
+	SOUT3_MARK, SCIFA2_TXD1_MARK, MSIOF2_MCK0_MARK,
+	SIN3_MARK, SCIFA2_RXD1_MARK, MSIOF2_MCK1_MARK,
+	XRTS3_MARK, SCIFA2_RTS1_MARK, PORT156_MSIOF2_SS2_MARK,
+	XCTS3_MARK, SCIFA2_CTS1_MARK, PORT157_MSIOF2_RXD_MARK,
+
+	/* 55-4 */
+	DINT_MARK, SCIFA2_SCK1_MARK, TS_SCK3_MARK,
+	PORT159_SCIFB_SCK_MARK, PORT159_SCIFA5_SCK_MARK, NMI_MARK,
+	PORT160_SCIFB_TXD_MARK, PORT160_SCIFA5_TXD_MARK, SOUT0_MARK,
+	PORT161_SCIFB_CTS_MARK, PORT161_SCIFA5_CTS_MARK, XCTS0_MARK,
+	MFG3_IN2_MARK,
+	PORT162_SCIFB_RXD_MARK, PORT162_SCIFA5_RXD_MARK, SIN0_MARK,
+	MFG3_IN1_MARK,
+	PORT163_SCIFB_RTS_MARK, PORT163_SCIFA5_RTS_MARK, XRTS0_MARK,
+	MFG3_OUT1_MARK, TPU3TO0_MARK,
+	LCDD0_MARK, PORT192_KEYOUT0_MARK, EXT_CKI_MARK,
+	LCDD1_MARK, PORT193_KEYOUT1_MARK, PORT193_SCIFA5_CTS_MARK,
+	BBIF2_TSYNC1_MARK,
+	LCDD2_MARK, PORT194_KEYOUT2_MARK, PORT194_SCIFA5_RTS_MARK,
+	BBIF2_TSCK1_MARK,
+	LCDD3_MARK, PORT195_KEYOUT3_MARK, PORT195_SCIFA5_RXD_MARK,
+	BBIF2_TXD1_MARK,
+	LCDD4_MARK, PORT196_KEYOUT4_MARK, PORT196_SCIFA5_TXD_MARK,
+	LCDD5_MARK, PORT197_KEYOUT5_MARK, PORT197_SCIFA5_SCK_MARK,
+	MFG2_OUT2_MARK,
+	TPU2TO1_MARK,
+	LCDD6_MARK, XWR2_MARK,
+	LCDD7_MARK, TPU4TO1_MARK, MFG4_OUT2_MARK, XWR3_MARK,
+	LCDD8_MARK, PORT200_KEYIN0_MARK, VIO_DR0_MARK, D16_MARK, ED16_MARK,
+	LCDD9_MARK, PORT201_KEYIN1_MARK, VIO_DR1_MARK, D17_MARK, ED17_MARK,
+	LCDD10_MARK, PORT202_KEYIN2_MARK, VIO_DR2_MARK, D18_MARK, ED18_MARK,
+	LCDD11_MARK, PORT203_KEYIN3_MARK, VIO_DR3_MARK, D19_MARK, ED19_MARK,
+	LCDD12_MARK, PORT204_KEYIN4_MARK, VIO_DR4_MARK, D20_MARK, ED20_MARK,
+	LCDD13_MARK, PORT205_KEYIN5_MARK, VIO_DR5_MARK, D21_MARK, ED21_MARK,
+	LCDD14_MARK, PORT206_KEYIN6_MARK, VIO_DR6_MARK, D22_MARK, ED22_MARK,
+	LCDD15_MARK, PORT207_MSIOF0L_SS1_MARK, PORT207_KEYOUT0_MARK,
+	VIO_DR7_MARK, D23_MARK, ED23_MARK,
+	LCDD16_MARK, PORT208_MSIOF0L_SS2_MARK, PORT208_KEYOUT1_MARK,
+	VIO_VDR_MARK, D24_MARK, ED24_MARK,
+	LCDD17_MARK, PORT209_KEYOUT2_MARK, VIO_HDR_MARK, D25_MARK, ED25_MARK,
+	LCDD18_MARK, DREQ2_MARK, PORT210_MSIOF0L_SS1_MARK, D26_MARK, ED26_MARK,
+	LCDD19_MARK, PORT211_MSIOF0L_SS2_MARK, D27_MARK, ED27_MARK,
+	LCDD20_MARK, TS_SPSYNC1_MARK, MSIOF0L_MCK0_MARK, D28_MARK, ED28_MARK,
+	LCDD21_MARK, TS_SDAT1_MARK, MSIOF0L_MCK1_MARK, D29_MARK, ED29_MARK,
+	LCDD22_MARK, TS_SDEN1_MARK, MSIOF0L_RSCK_MARK, D30_MARK, ED30_MARK,
+	LCDD23_MARK, TS_SCK1_MARK, MSIOF0L_RSYNC_MARK, D31_MARK, ED31_MARK,
+	LCDDCK_MARK, LCDWR_MARK, PORT216_KEYOUT3_MARK, VIO_CLKR_MARK,
+	LCDRD_MARK, DACK2_MARK, MSIOF0L_TSYNC_MARK,
+	LCDHSYN_MARK, LCDCS_MARK, LCDCS2_MARK, DACK3_MARK,
+	PORT218_VIO_CKOR_MARK, PORT218_KEYOUT4_MARK,
+	LCDDISP_MARK, LCDRS_MARK, DREQ3_MARK, MSIOF0L_TSCK_MARK,
+	LCDVSYN_MARK, LCDVSYN2_MARK, PORT220_KEYOUT5_MARK,
+	LCDLCLK_MARK, DREQ1_MARK, PWEN_MARK, MSIOF0L_RXD_MARK,
+	LCDDON_MARK, LCDDON2_MARK, DACK1_MARK, OVCN_MARK, MSIOF0L_TXD_MARK,
+	SCIFA1_TXD_MARK, OVCN2_MARK,
+	EXTLP_MARK, SCIFA1_SCK_MARK, USBTERM_MARK, PORT226_VIO_CKO2_MARK,
+	SCIFA1_RTS_MARK, IDIN_MARK,
+	SCIFA1_RXD_MARK,
+	SCIFA1_CTS_MARK, MFG1_IN1_MARK,
+	MSIOF1_TXD_MARK, SCIFA2_TXD2_MARK, PORT230_FSIAOMC_MARK,
+	MSIOF1_TSYNC_MARK, SCIFA2_CTS2_MARK, PORT231_FSIAOLR_MARK,
+	MSIOF1_TSCK_MARK, SCIFA2_SCK2_MARK, PORT232_FSIAOBT_MARK,
+	MSIOF1_RXD_MARK, SCIFA2_RXD2_MARK, GPS_VCOTRIG_MARK,
+	PORT233_FSIACK_MARK,
+	MSIOF1_RSCK_MARK, SCIFA2_RTS2_MARK, PORT234_FSIAOSLD_MARK,
+	MSIOF1_RSYNC_MARK, OPORT0_MARK, MFG1_IN2_MARK, PORT235_FSIAILR_MARK,
+	MSIOF1_MCK0_MARK, I2C_SDA2_MARK, PORT236_FSIAIBT_MARK,
+	MSIOF1_MCK1_MARK, I2C_SCL2_MARK, PORT237_FSIAISLD_MARK,
+	MSIOF1_SS1_MARK, EDBGREQ3_MARK,
+
+	/* 55-5 */
+	MSIOF1_SS2_MARK,
+	SCIFA6_TXD_MARK,
+	PORT241_IRDA_OUT_MARK, PORT241_IROUT_MARK, MFG4_OUT1_MARK,
+	TPU4TO0_MARK,
+	PORT242_IRDA_IN_MARK, MFG4_IN2_MARK,
+	PORT243_IRDA_FIRSEL_MARK, PORT243_VIO_CKO2_MARK,
+	PORT244_SCIFA5_CTS_MARK, MFG2_IN1_MARK, PORT244_SCIFB_CTS_MARK,
+	PORT244_MSIOF2_RXD_MARK,
+	PORT245_SCIFA5_RTS_MARK, MFG2_IN2_MARK, PORT245_SCIFB_RTS_MARK,
+	PORT245_MSIOF2_TXD_MARK,
+	PORT246_SCIFA5_RXD_MARK, MFG1_OUT1_MARK, PORT246_SCIFB_RXD_MARK,
+	TPU1TO0_MARK,
+	PORT247_SCIFA5_TXD_MARK, MFG3_OUT2_MARK, PORT247_SCIFB_TXD_MARK,
+	TPU3TO1_MARK,
+	PORT248_SCIFA5_SCK_MARK, MFG2_OUT1_MARK, PORT248_SCIFB_SCK_MARK,
+	TPU2TO0_MARK,
+	PORT248_MSIOF2_TSCK_MARK,
+	PORT249_IROUT_MARK, MFG4_IN1_MARK, PORT249_MSIOF2_TSYNC_MARK,
+	SDHICLK0_MARK, TCK2_SWCLK_MC0_MARK,
+	SDHICD0_MARK,
+	SDHID0_0_MARK, TMS2_SWDIO_MC0_MARK,
+	SDHID0_1_MARK, TDO2_SWO0_MC0_MARK,
+	SDHID0_2_MARK, TDI2_MARK,
+	SDHID0_3_MARK, RTCK2_SWO1_MC0_MARK,
+	SDHICMD0_MARK, TRST2_MARK,
+	SDHIWP0_MARK, EDBGREQ2_MARK,
+	SDHICLK1_MARK, TCK3_SWCLK_MC1_MARK,
+	SDHID1_0_MARK, M11_SLCD_SO2_MARK, TS_SPSYNC2_MARK,
+	TMS3_SWDIO_MC1_MARK,
+	SDHID1_1_MARK, M9_SLCD_A02_MARK, TS_SDAT2_MARK, TDO3_SWO0_MC1_MARK,
+	SDHID1_2_MARK, M10_SLCD_CK2_MARK, TS_SDEN2_MARK, TDI3_MARK,
+	SDHID1_3_MARK, M12_SLCD_CE2_MARK, TS_SCK2_MARK, RTCK3_SWO1_MC1_MARK,
+	SDHICMD1_MARK, TRST3_MARK,
+	RESETOUTS_MARK,
+	PINMUX_MARK_END,
+};
+
+#define PORT_DATA_I(nr)	\
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)
+
+#define PORT_DATA_I_PD(nr)	\
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,	\
+				PORT##nr##_IN, PORT##nr##_IN_PD)
+
+#define PORT_DATA_I_PU(nr)	\
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,	\
+				PORT##nr##_IN, PORT##nr##_IN_PU)
+
+#define PORT_DATA_I_PU_PD(nr)	\
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,	\
+				PORT##nr##_IN, PORT##nr##_IN_PD,	\
+				PORT##nr##_IN_PU)
+
+#define PORT_DATA_O(nr)	\
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,	\
+				PORT##nr##_OUT)
+
+#define PORT_DATA_IO(nr)	\
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,	\
+				PORT##nr##_OUT, PORT##nr##_IN)
+
+#define PORT_DATA_IO_PD(nr)	\
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,	\
+				PORT##nr##_OUT, PORT##nr##_IN,		\
+				PORT##nr##_IN_PD)
+
+#define PORT_DATA_IO_PU(nr)	\
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,	\
+				PORT##nr##_OUT, PORT##nr##_IN,		\
+				PORT##nr##_IN_PU)
+
+#define PORT_DATA_IO_PU_PD(nr)	\
+	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,	\
+				PORT##nr##_OUT, PORT##nr##_IN,		\
+				PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+static pinmux_enum_t pinmux_data[] = {
+	/* specify valid pin states for each pin in GPIO mode */
+	/* 55-1 (GPIO) */
+	PORT_DATA_I_PD(0), PORT_DATA_I_PU(1),
+	PORT_DATA_I_PU(2), PORT_DATA_I_PU(3),
+	PORT_DATA_I_PU(4), PORT_DATA_I_PU(5),
+	PORT_DATA_I_PU(6), PORT_DATA_I_PU(7),
+	PORT_DATA_I_PU(8), PORT_DATA_I_PU(9),
+	PORT_DATA_I_PU(10), PORT_DATA_I_PU(11),
+	PORT_DATA_IO_PU(12), PORT_DATA_IO_PU(13),
+	PORT_DATA_IO_PU_PD(14), PORT_DATA_IO_PU_PD(15),
+	PORT_DATA_O(16), PORT_DATA_IO(17),
+	PORT_DATA_O(18), PORT_DATA_O(19),
+	PORT_DATA_O(20), PORT_DATA_O(21),
+	PORT_DATA_O(22), PORT_DATA_O(23),
+	PORT_DATA_O(24), PORT_DATA_I_PD(25),
+	PORT_DATA_I_PD(26), PORT_DATA_O(27),
+	PORT_DATA_O(28), PORT_DATA_O(29),
+	PORT_DATA_IO(30), PORT_DATA_IO_PU(31),
+	PORT_DATA_IO_PD(32), PORT_DATA_I_PU(33),
+	PORT_DATA_IO_PD(34), PORT_DATA_I_PU_PD(35),
+	PORT_DATA_O(36), PORT_DATA_IO(37),
+
+	/* 55-2 (GPIO) */
+	PORT_DATA_O(38), PORT_DATA_I_PU(39),
+	PORT_DATA_I_PU_PD(40), PORT_DATA_O(41),
+	PORT_DATA_IO_PD(42), PORT_DATA_IO_PD(43),
+	PORT_DATA_IO_PD(44), PORT_DATA_I_PD(45),
+	PORT_DATA_I_PD(46), PORT_DATA_I_PD(47),
+	PORT_DATA_I_PD(48), PORT_DATA_IO_PU_PD(49),
+	PORT_DATA_IO_PD(50), PORT_DATA_IO_PD(51),
+	PORT_DATA_O(52), PORT_DATA_IO_PU_PD(53),
+	PORT_DATA_IO_PU_PD(54), PORT_DATA_IO_PD(55),
+	PORT_DATA_I_PU_PD(56), PORT_DATA_IO(57),
+	PORT_DATA_IO(58), PORT_DATA_IO(59),
+	PORT_DATA_IO(60), PORT_DATA_IO(61),
+	PORT_DATA_IO_PD(62), PORT_DATA_IO_PD(63),
+	PORT_DATA_IO_PD(64), PORT_DATA_IO_PD(65),
+	PORT_DATA_IO_PU_PD(66), PORT_DATA_IO_PU_PD(67),
+	PORT_DATA_IO_PU_PD(68), PORT_DATA_IO_PU_PD(69),
+	PORT_DATA_IO_PU_PD(70), PORT_DATA_IO_PU_PD(71),
+	PORT_DATA_IO_PU_PD(72), PORT_DATA_I_PU_PD(73),
+	PORT_DATA_IO_PU(74), PORT_DATA_IO_PU(75),
+	PORT_DATA_IO_PU(76), PORT_DATA_IO_PU(77),
+	PORT_DATA_IO_PU(78), PORT_DATA_IO_PU(79),
+	PORT_DATA_IO_PU(80), PORT_DATA_IO_PU(81),
+	PORT_DATA_IO_PU(82), PORT_DATA_IO_PU(83),
+	PORT_DATA_IO_PU(84), PORT_DATA_IO_PU(85),
+	PORT_DATA_IO_PU(86), PORT_DATA_IO_PU(87),
+	PORT_DATA_IO_PU(88), PORT_DATA_IO_PU(89),
+	PORT_DATA_O(90), PORT_DATA_IO_PU(91),
+	PORT_DATA_O(92),
+
+	/* 55-3 (GPIO) */
+	PORT_DATA_IO_PU(93),
+	PORT_DATA_O(94),
+	PORT_DATA_I_PU_PD(95),
+	PORT_DATA_IO(96), PORT_DATA_IO(97),
+	PORT_DATA_IO(98), PORT_DATA_I_PU(99),
+	PORT_DATA_O(100), PORT_DATA_O(101),
+	PORT_DATA_I_PU(102), PORT_DATA_IO_PD(103),
+	PORT_DATA_I_PD(104), PORT_DATA_I_PD(105),
+	PORT_DATA_I_PD(106), PORT_DATA_I_PD(107),
+	PORT_DATA_I_PD(108), PORT_DATA_IO_PD(109),
+	PORT_DATA_IO_PD(110), PORT_DATA_I_PD(111),
+	PORT_DATA_IO_PD(112), PORT_DATA_IO_PD(113),
+	PORT_DATA_IO_PD(114), PORT_DATA_I_PD(115),
+	PORT_DATA_I_PD(116), PORT_DATA_IO_PD(117),
+	PORT_DATA_I_PD(118), PORT_DATA_IO_PD(128),
+	PORT_DATA_IO_PD(129), PORT_DATA_IO_PD(130),
+	PORT_DATA_IO_PD(131), PORT_DATA_IO_PD(132),
+	PORT_DATA_IO_PD(133), PORT_DATA_IO_PU_PD(134),
+	PORT_DATA_IO_PU_PD(135), PORT_DATA_IO_PU_PD(136),
+	PORT_DATA_IO_PU_PD(137), PORT_DATA_IO_PD(138),
+	PORT_DATA_IO_PD(139), PORT_DATA_IO_PD(140),
+	PORT_DATA_IO_PD(141), PORT_DATA_IO_PD(142),
+	PORT_DATA_IO_PD(143), PORT_DATA_IO_PU_PD(144),
+	PORT_DATA_IO_PD(145), PORT_DATA_IO_PU_PD(146),
+	PORT_DATA_IO_PU_PD(147), PORT_DATA_IO_PU_PD(148),
+	PORT_DATA_IO_PU_PD(149), PORT_DATA_I_PD(150),
+	PORT_DATA_IO_PU_PD(151), PORT_DATA_IO_PD(152),
+	PORT_DATA_IO_PD(153), PORT_DATA_IO_PD(154),
+	PORT_DATA_I_PD(155), PORT_DATA_IO_PU_PD(156),
+	PORT_DATA_I_PD(157), PORT_DATA_IO_PD(158),
+
+	/* 55-4 (GPIO) */
+	PORT_DATA_IO_PU_PD(159), PORT_DATA_IO_PU_PD(160),
+	PORT_DATA_I_PU_PD(161), PORT_DATA_I_PU_PD(162),
+	PORT_DATA_IO_PU_PD(163), PORT_DATA_I_PU_PD(164),
+	PORT_DATA_IO_PD(192), PORT_DATA_IO_PD(193),
+	PORT_DATA_IO_PD(194), PORT_DATA_IO_PD(195),
+	PORT_DATA_IO_PD(196), PORT_DATA_IO_PD(197),
+	PORT_DATA_IO_PD(198), PORT_DATA_IO_PD(199),
+	PORT_DATA_IO_PU_PD(200), PORT_DATA_IO_PU_PD(201),
+	PORT_DATA_IO_PU_PD(202), PORT_DATA_IO_PU_PD(203),
+	PORT_DATA_IO_PU_PD(204), PORT_DATA_IO_PU_PD(205),
+	PORT_DATA_IO_PU_PD(206), PORT_DATA_IO_PD(207),
+	PORT_DATA_IO_PD(208), PORT_DATA_IO_PD(209),
+	PORT_DATA_IO_PD(210), PORT_DATA_IO_PD(211),
+	PORT_DATA_IO_PD(212), PORT_DATA_IO_PD(213),
+	PORT_DATA_IO_PD(214), PORT_DATA_IO_PD(215),
+	PORT_DATA_IO_PD(216), PORT_DATA_IO_PD(217),
+	PORT_DATA_O(218), PORT_DATA_IO_PD(219),
+	PORT_DATA_IO_PD(220), PORT_DATA_IO_PD(221),
+	PORT_DATA_IO_PU_PD(222),
+	PORT_DATA_I_PU_PD(223), PORT_DATA_I_PU_PD(224),
+	PORT_DATA_IO_PU_PD(225), PORT_DATA_O(226),
+	PORT_DATA_IO_PU_PD(227), PORT_DATA_I_PD(228),
+	PORT_DATA_I_PD(229), PORT_DATA_IO(230),
+	PORT_DATA_IO_PD(231), PORT_DATA_IO_PU_PD(232),
+	PORT_DATA_I_PD(233), PORT_DATA_IO_PU_PD(234),
+	PORT_DATA_IO_PU_PD(235), PORT_DATA_IO_PU_PD(236),
+	PORT_DATA_IO_PD(237), PORT_DATA_IO_PU_PD(238),
+
+	/* 55-5 (GPIO) */
+	PORT_DATA_IO_PU_PD(239), PORT_DATA_IO_PU_PD(240),
+	PORT_DATA_O(241), PORT_DATA_I_PD(242),
+	PORT_DATA_IO_PU_PD(243), PORT_DATA_IO_PU_PD(244),
+	PORT_DATA_IO_PU_PD(245), PORT_DATA_IO_PU_PD(246),
+	PORT_DATA_IO_PU_PD(247), PORT_DATA_IO_PU_PD(248),
+	PORT_DATA_IO_PU_PD(249), PORT_DATA_IO_PD(250),
+	PORT_DATA_IO_PU_PD(251), PORT_DATA_IO_PU_PD(252),
+	PORT_DATA_IO_PU_PD(253), PORT_DATA_IO_PU_PD(254),
+	PORT_DATA_IO_PU_PD(255), PORT_DATA_IO_PU_PD(256),
+	PORT_DATA_IO_PU_PD(257), PORT_DATA_IO_PD(258),
+	PORT_DATA_IO_PU_PD(259), PORT_DATA_IO_PU_PD(260),
+	PORT_DATA_IO_PU_PD(261), PORT_DATA_IO_PU_PD(262),
+	PORT_DATA_IO_PU_PD(263),
+
+	/* Special Pull-up / Pull-down Functions */
+	PINMUX_DATA(PORT66_KEYIN0_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+				PORT66_FN2, PORT66_IN_PU),
+	PINMUX_DATA(PORT67_KEYIN1_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+				PORT67_FN2, PORT67_IN_PU),
+	PINMUX_DATA(PORT68_KEYIN2_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+				PORT68_FN2, PORT68_IN_PU),
+	PINMUX_DATA(PORT69_KEYIN3_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+				PORT69_FN2, PORT69_IN_PU),
+	PINMUX_DATA(PORT70_KEYIN4_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+				PORT70_FN2, PORT70_IN_PU),
+	PINMUX_DATA(PORT71_KEYIN5_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+				PORT71_FN2, PORT71_IN_PU),
+	PINMUX_DATA(PORT72_KEYIN6_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+				PORT72_FN2, PORT72_IN_PU),
+
+
+	/* 55-1 (FN) */
+	PINMUX_DATA(VBUS_0_MARK, PORT0_FN1),
+	PINMUX_DATA(CPORT0_MARK, PORT1_FN1),
+	PINMUX_DATA(CPORT1_MARK, PORT2_FN1),
+	PINMUX_DATA(CPORT2_MARK, PORT3_FN1),
+	PINMUX_DATA(CPORT3_MARK, PORT4_FN1),
+	PINMUX_DATA(CPORT4_MARK, PORT5_FN1),
+	PINMUX_DATA(CPORT5_MARK, PORT6_FN1),
+	PINMUX_DATA(CPORT6_MARK, PORT7_FN1),
+	PINMUX_DATA(CPORT7_MARK, PORT8_FN1),
+	PINMUX_DATA(CPORT8_MARK, PORT9_FN1),
+	PINMUX_DATA(CPORT9_MARK, PORT10_FN1),
+	PINMUX_DATA(CPORT10_MARK, PORT11_FN1),
+	PINMUX_DATA(CPORT11_MARK, PORT12_FN1),
+	PINMUX_DATA(SIN2_MARK, PORT12_FN2),
+	PINMUX_DATA(CPORT12_MARK, PORT13_FN1),
+	PINMUX_DATA(XCTS2_MARK, PORT13_FN2),
+	PINMUX_DATA(CPORT13_MARK, PORT14_FN1),
+	PINMUX_DATA(RFSPO4_MARK, PORT14_FN2),
+	PINMUX_DATA(CPORT14_MARK, PORT15_FN1),
+	PINMUX_DATA(RFSPO5_MARK, PORT15_FN2),
+	PINMUX_DATA(CPORT15_MARK, PORT16_FN1),
+	PINMUX_DATA(SCIFA0_SCK_MARK, PORT16_FN2),
+	PINMUX_DATA(GPS_AGC2_MARK, PORT16_FN3),
+	PINMUX_DATA(CPORT16_MARK, PORT17_FN1),
+	PINMUX_DATA(SCIFA0_TXD_MARK, PORT17_FN2),
+	PINMUX_DATA(GPS_AGC3_MARK, PORT17_FN3),
+	PINMUX_DATA(CPORT17_IC_OE_MARK, PORT18_FN1),
+	PINMUX_DATA(SOUT2_MARK, PORT18_FN2),
+	PINMUX_DATA(CPORT18_MARK, PORT19_FN1),
+	PINMUX_DATA(XRTS2_MARK, PORT19_FN2),
+	PINMUX_DATA(PORT19_VIO_CKO2_MARK, PORT19_FN3),
+	PINMUX_DATA(CPORT19_MPORT1_MARK, PORT20_FN1),
+	PINMUX_DATA(CPORT20_MARK, PORT21_FN1),
+	PINMUX_DATA(RFSPO6_MARK, PORT21_FN2),
+	PINMUX_DATA(CPORT21_MARK, PORT22_FN1),
+	PINMUX_DATA(STATUS0_MARK, PORT22_FN2),
+	PINMUX_DATA(CPORT22_MARK, PORT23_FN1),
+	PINMUX_DATA(STATUS1_MARK, PORT23_FN2),
+	PINMUX_DATA(CPORT23_MARK, PORT24_FN1),
+	PINMUX_DATA(STATUS2_MARK, PORT24_FN2),
+	PINMUX_DATA(RFSPO7_MARK, PORT24_FN3),
+	PINMUX_DATA(B_SYNLD1_MARK, PORT25_FN1),
+	PINMUX_DATA(B_SYNLD2_MARK, PORT26_FN1),
+	PINMUX_DATA(SYSENMSK_MARK, PORT26_FN2),
+	PINMUX_DATA(XMAINPS_MARK, PORT27_FN1),
+	PINMUX_DATA(XDIVPS_MARK, PORT28_FN1),
+	PINMUX_DATA(XIDRST_MARK, PORT29_FN1),
+	PINMUX_DATA(IDCLK_MARK, PORT30_FN1),
+	PINMUX_DATA(IC_DP_MARK, PORT30_FN2),
+	PINMUX_DATA(IDIO_MARK, PORT31_FN1),
+	PINMUX_DATA(IC_DM_MARK, PORT31_FN2),
+	PINMUX_DATA(SOUT1_MARK, PORT32_FN1),
+	PINMUX_DATA(SCIFA4_TXD_MARK, PORT32_FN2),
+	PINMUX_DATA(M02_BERDAT_MARK, PORT32_FN3),
+	PINMUX_DATA(SIN1_MARK, PORT33_FN1),
+	PINMUX_DATA(SCIFA4_RXD_MARK, PORT33_FN2),
+	PINMUX_DATA(XWUP_MARK, PORT33_FN3),
+	PINMUX_DATA(XRTS1_MARK, PORT34_FN1),
+	PINMUX_DATA(SCIFA4_RTS_MARK, PORT34_FN2),
+	PINMUX_DATA(M03_BERCLK_MARK, PORT34_FN3),
+	PINMUX_DATA(XCTS1_MARK, PORT35_FN1),
+	PINMUX_DATA(SCIFA4_CTS_MARK, PORT35_FN2),
+	PINMUX_DATA(PCMCLKO_MARK, PORT36_FN1),
+	PINMUX_DATA(SYNC8KO_MARK, PORT37_FN1),
+
+	/* 55-2 (FN) */
+	PINMUX_DATA(DNPCM_A_MARK, PORT38_FN1),
+	PINMUX_DATA(UPPCM_A_MARK, PORT39_FN1),
+	PINMUX_DATA(VACK_MARK, PORT40_FN1),
+	PINMUX_DATA(XTALB1L_MARK, PORT41_FN1),
+	PINMUX_DATA(GPS_AGC1_MARK, PORT42_FN1),
+	PINMUX_DATA(SCIFA0_RTS_MARK, PORT42_FN2),
+	PINMUX_DATA(GPS_AGC4_MARK, PORT43_FN1),
+	PINMUX_DATA(SCIFA0_RXD_MARK, PORT43_FN2),
+	PINMUX_DATA(GPS_PWRDOWN_MARK, PORT44_FN1),
+	PINMUX_DATA(SCIFA0_CTS_MARK, PORT44_FN2),
+	PINMUX_DATA(GPS_IM_MARK, PORT45_FN1),
+	PINMUX_DATA(GPS_IS_MARK, PORT46_FN1),
+	PINMUX_DATA(GPS_QM_MARK, PORT47_FN1),
+	PINMUX_DATA(GPS_QS_MARK, PORT48_FN1),
+	PINMUX_DATA(FMSOCK_MARK, PORT49_FN1),
+	PINMUX_DATA(PORT49_IRDA_OUT_MARK, PORT49_FN2),
+	PINMUX_DATA(PORT49_IROUT_MARK, PORT49_FN3),
+	PINMUX_DATA(FMSOOLR_MARK, PORT50_FN1),
+	PINMUX_DATA(BBIF2_TSYNC2_MARK, PORT50_FN2),
+	PINMUX_DATA(TPU2TO2_MARK, PORT50_FN3),
+	PINMUX_DATA(IPORT3_MARK, PORT50_FN4),
+	PINMUX_DATA(FMSIOLR_MARK, PORT50_FN5),
+	PINMUX_DATA(FMSOOBT_MARK, PORT51_FN1),
+	PINMUX_DATA(BBIF2_TSCK2_MARK, PORT51_FN2),
+	PINMUX_DATA(TPU2TO3_MARK, PORT51_FN3),
+	PINMUX_DATA(OPORT1_MARK, PORT51_FN4),
+	PINMUX_DATA(FMSIOBT_MARK, PORT51_FN5),
+	PINMUX_DATA(FMSOSLD_MARK, PORT52_FN1),
+	PINMUX_DATA(BBIF2_TXD2_MARK, PORT52_FN2),
+	PINMUX_DATA(OPORT2_MARK, PORT52_FN3),
+	PINMUX_DATA(FMSOILR_MARK, PORT53_FN1),
+	PINMUX_DATA(PORT53_IRDA_IN_MARK, PORT53_FN2),
+	PINMUX_DATA(TPU3TO3_MARK, PORT53_FN3),
+	PINMUX_DATA(OPORT3_MARK, PORT53_FN4),
+	PINMUX_DATA(FMSIILR_MARK, PORT53_FN5),
+	PINMUX_DATA(FMSOIBT_MARK, PORT54_FN1),
+	PINMUX_DATA(PORT54_IRDA_FIRSEL_MARK, PORT54_FN2),
+	PINMUX_DATA(TPU3TO2_MARK, PORT54_FN3),
+	PINMUX_DATA(FMSIIBT_MARK, PORT54_FN4),
+	PINMUX_DATA(FMSISLD_MARK, PORT55_FN1),
+	PINMUX_DATA(MFG0_OUT1_MARK, PORT55_FN2),
+	PINMUX_DATA(TPU0TO0_MARK, PORT55_FN3),
+	PINMUX_DATA(A0_EA0_MARK, PORT57_FN1),
+	PINMUX_DATA(BS_MARK, PORT57_FN2),
+	PINMUX_DATA(A12_EA12_MARK, PORT58_FN1),
+	PINMUX_DATA(PORT58_VIO_CKOR_MARK, PORT58_FN2),
+	PINMUX_DATA(TPU4TO2_MARK, PORT58_FN3),
+	PINMUX_DATA(A13_EA13_MARK, PORT59_FN1),
+	PINMUX_DATA(PORT59_IROUT_MARK, PORT59_FN2),
+	PINMUX_DATA(MFG0_OUT2_MARK, PORT59_FN3),
+	PINMUX_DATA(TPU0TO1_MARK, PORT59_FN4),
+	PINMUX_DATA(A14_EA14_MARK, PORT60_FN1),
+	PINMUX_DATA(PORT60_KEYOUT5_MARK, PORT60_FN2),
+	PINMUX_DATA(A15_EA15_MARK, PORT61_FN1),
+	PINMUX_DATA(PORT61_KEYOUT4_MARK, PORT61_FN2),
+	PINMUX_DATA(A16_EA16_MARK, PORT62_FN1),
+	PINMUX_DATA(PORT62_KEYOUT3_MARK, PORT62_FN2),
+	PINMUX_DATA(MSIOF0_SS1_MARK, PORT62_FN3),
+	PINMUX_DATA(A17_EA17_MARK, PORT63_FN1),
+	PINMUX_DATA(PORT63_KEYOUT2_MARK, PORT63_FN2),
+	PINMUX_DATA(MSIOF0_TSYNC_MARK, PORT63_FN3),
+	PINMUX_DATA(A18_EA18_MARK, PORT64_FN1),
+	PINMUX_DATA(PORT64_KEYOUT1_MARK, PORT64_FN2),
+	PINMUX_DATA(MSIOF0_TSCK_MARK, PORT64_FN3),
+	PINMUX_DATA(A19_EA19_MARK, PORT65_FN1),
+	PINMUX_DATA(PORT65_KEYOUT0_MARK, PORT65_FN2),
+	PINMUX_DATA(MSIOF0_TXD_MARK, PORT65_FN3),
+	PINMUX_DATA(A20_EA20_MARK, PORT66_FN1),
+	PINMUX_DATA(PORT66_KEYIN0_MARK, PORT66_FN2),
+	PINMUX_DATA(MSIOF0_RSCK_MARK, PORT66_FN3),
+	PINMUX_DATA(A21_EA21_MARK, PORT67_FN1),
+	PINMUX_DATA(PORT67_KEYIN1_MARK, PORT67_FN2),
+	PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT67_FN3),
+	PINMUX_DATA(A22_EA22_MARK, PORT68_FN1),
+	PINMUX_DATA(PORT68_KEYIN2_MARK, PORT68_FN2),
+	PINMUX_DATA(MSIOF0_MCK0_MARK, PORT68_FN3),
+	PINMUX_DATA(A23_EA23_MARK, PORT69_FN1),
+	PINMUX_DATA(PORT69_KEYIN3_MARK, PORT69_FN2),
+	PINMUX_DATA(MSIOF0_MCK1_MARK, PORT69_FN3),
+	PINMUX_DATA(A24_EA24_MARK, PORT70_FN1),
+	PINMUX_DATA(PORT70_KEYIN4_MARK, PORT70_FN2),
+	PINMUX_DATA(MSIOF0_RXD_MARK, PORT70_FN3),
+	PINMUX_DATA(A25_EA25_MARK, PORT71_FN1),
+	PINMUX_DATA(PORT71_KEYIN5_MARK, PORT71_FN2),
+	PINMUX_DATA(MSIOF0_SS2_MARK, PORT71_FN3),
+	PINMUX_DATA(A26_MARK, PORT72_FN1),
+	PINMUX_DATA(PORT72_KEYIN6_MARK, PORT72_FN2),
+	PINMUX_DATA(D0_ED0_NAF0_MARK, PORT74_FN1),
+	PINMUX_DATA(D1_ED1_NAF1_MARK, PORT75_FN1),
+	PINMUX_DATA(D2_ED2_NAF2_MARK, PORT76_FN1),
+	PINMUX_DATA(D3_ED3_NAF3_MARK, PORT77_FN1),
+	PINMUX_DATA(D4_ED4_NAF4_MARK, PORT78_FN1),
+	PINMUX_DATA(D5_ED5_NAF5_MARK, PORT79_FN1),
+	PINMUX_DATA(D6_ED6_NAF6_MARK, PORT80_FN1),
+	PINMUX_DATA(D7_ED7_NAF7_MARK, PORT81_FN1),
+	PINMUX_DATA(D8_ED8_NAF8_MARK, PORT82_FN1),
+	PINMUX_DATA(D9_ED9_NAF9_MARK, PORT83_FN1),
+	PINMUX_DATA(D10_ED10_NAF10_MARK, PORT84_FN1),
+	PINMUX_DATA(D11_ED11_NAF11_MARK, PORT85_FN1),
+	PINMUX_DATA(D12_ED12_NAF12_MARK, PORT86_FN1),
+	PINMUX_DATA(D13_ED13_NAF13_MARK, PORT87_FN1),
+	PINMUX_DATA(D14_ED14_NAF14_MARK, PORT88_FN1),
+	PINMUX_DATA(D15_ED15_NAF15_MARK, PORT89_FN1),
+	PINMUX_DATA(CS4_MARK, PORT90_FN1),
+	PINMUX_DATA(CS5A_MARK, PORT91_FN1),
+	PINMUX_DATA(FMSICK_MARK, PORT91_FN2),
+	PINMUX_DATA(CS5B_MARK, PORT92_FN1),
+	PINMUX_DATA(FCE1_MARK, PORT92_FN2),
+
+	/* 55-3 (FN) */
+	PINMUX_DATA(CS6B_MARK, PORT93_FN1),
+	PINMUX_DATA(XCS2_MARK, PORT93_FN2),
+	PINMUX_DATA(CS6A_MARK, PORT93_FN3),
+	PINMUX_DATA(DACK0_MARK, PORT93_FN4),
+	PINMUX_DATA(FCE0_MARK, PORT94_FN1),
+	PINMUX_DATA(WAIT_MARK, PORT95_FN1),
+	PINMUX_DATA(DREQ0_MARK, PORT95_FN2),
+	PINMUX_DATA(RD_XRD_MARK, PORT96_FN1),
+	PINMUX_DATA(WE0_XWR0_FWE_MARK, PORT97_FN1),
+	PINMUX_DATA(WE1_XWR1_MARK, PORT98_FN1),
+	PINMUX_DATA(FRB_MARK, PORT99_FN1),
+	PINMUX_DATA(CKO_MARK, PORT100_FN1),
+	PINMUX_DATA(NBRSTOUT_MARK, PORT101_FN1),
+	PINMUX_DATA(NBRST_MARK, PORT102_FN1),
+	PINMUX_DATA(GPS_EPPSIN_MARK, PORT106_FN1),
+	PINMUX_DATA(LATCHPULSE_MARK, PORT110_FN1),
+	PINMUX_DATA(LTESIGNAL_MARK, PORT111_FN1),
+	PINMUX_DATA(LEGACYSTATE_MARK, PORT112_FN1),
+	PINMUX_DATA(TCKON_MARK, PORT118_FN1),
+	PINMUX_DATA(VIO_VD_MARK, PORT128_FN1),
+	PINMUX_DATA(PORT128_KEYOUT0_MARK, PORT128_FN2),
+	PINMUX_DATA(IPORT0_MARK, PORT128_FN3),
+	PINMUX_DATA(VIO_HD_MARK, PORT129_FN1),
+	PINMUX_DATA(PORT129_KEYOUT1_MARK, PORT129_FN2),
+	PINMUX_DATA(IPORT1_MARK, PORT129_FN3),
+	PINMUX_DATA(VIO_D0_MARK, PORT130_FN1),
+	PINMUX_DATA(PORT130_KEYOUT2_MARK, PORT130_FN2),
+	PINMUX_DATA(PORT130_MSIOF2_RXD_MARK, PORT130_FN3),
+	PINMUX_DATA(VIO_D1_MARK, PORT131_FN1),
+	PINMUX_DATA(PORT131_KEYOUT3_MARK, PORT131_FN2),
+	PINMUX_DATA(PORT131_MSIOF2_SS1_MARK, PORT131_FN3),
+	PINMUX_DATA(VIO_D2_MARK, PORT132_FN1),
+	PINMUX_DATA(PORT132_KEYOUT4_MARK, PORT132_FN2),
+	PINMUX_DATA(PORT132_MSIOF2_SS2_MARK, PORT132_FN3),
+	PINMUX_DATA(VIO_D3_MARK, PORT133_FN1),
+	PINMUX_DATA(PORT133_KEYOUT5_MARK, PORT133_FN2),
+	PINMUX_DATA(PORT133_MSIOF2_TSYNC_MARK, PORT133_FN3),
+	PINMUX_DATA(VIO_D4_MARK, PORT134_FN1),
+	PINMUX_DATA(PORT134_KEYIN0_MARK, PORT134_FN2),
+	PINMUX_DATA(PORT134_MSIOF2_TXD_MARK, PORT134_FN3),
+	PINMUX_DATA(VIO_D5_MARK, PORT135_FN1),
+	PINMUX_DATA(PORT135_KEYIN1_MARK, PORT135_FN2),
+	PINMUX_DATA(PORT135_MSIOF2_TSCK_MARK, PORT135_FN3),
+	PINMUX_DATA(VIO_D6_MARK, PORT136_FN1),
+	PINMUX_DATA(PORT136_KEYIN2_MARK, PORT136_FN2),
+	PINMUX_DATA(VIO_D7_MARK, PORT137_FN1),
+	PINMUX_DATA(PORT137_KEYIN3_MARK, PORT137_FN2),
+	PINMUX_DATA(VIO_D8_MARK, PORT138_FN1),
+	PINMUX_DATA(M9_SLCD_A01_MARK, PORT138_FN2),
+	PINMUX_DATA(PORT138_FSIAOMC_MARK, PORT138_FN3),
+	PINMUX_DATA(VIO_D9_MARK, PORT139_FN1),
+	PINMUX_DATA(M10_SLCD_CK1_MARK, PORT139_FN2),
+	PINMUX_DATA(PORT139_FSIAOLR_MARK, PORT139_FN3),
+	PINMUX_DATA(VIO_D10_MARK, PORT140_FN1),
+	PINMUX_DATA(M11_SLCD_SO1_MARK, PORT140_FN2),
+	PINMUX_DATA(TPU0TO2_MARK, PORT140_FN3),
+	PINMUX_DATA(PORT140_FSIAOBT_MARK, PORT140_FN4),
+	PINMUX_DATA(VIO_D11_MARK, PORT141_FN1),
+	PINMUX_DATA(M12_SLCD_CE1_MARK, PORT141_FN2),
+	PINMUX_DATA(TPU0TO3_MARK, PORT141_FN3),
+	PINMUX_DATA(PORT141_FSIAOSLD_MARK, PORT141_FN4),
+	PINMUX_DATA(VIO_D12_MARK, PORT142_FN1),
+	PINMUX_DATA(M13_BSW_MARK, PORT142_FN2),
+	PINMUX_DATA(PORT142_FSIACK_MARK, PORT142_FN3),
+	PINMUX_DATA(VIO_D13_MARK, PORT143_FN1),
+	PINMUX_DATA(M14_GSW_MARK, PORT143_FN2),
+	PINMUX_DATA(PORT143_FSIAILR_MARK, PORT143_FN3),
+	PINMUX_DATA(VIO_D14_MARK, PORT144_FN1),
+	PINMUX_DATA(M15_RSW_MARK, PORT144_FN2),
+	PINMUX_DATA(PORT144_FSIAIBT_MARK, PORT144_FN3),
+	PINMUX_DATA(VIO_D15_MARK, PORT145_FN1),
+	PINMUX_DATA(TPU1TO3_MARK, PORT145_FN2),
+	PINMUX_DATA(PORT145_FSIAISLD_MARK, PORT145_FN3),
+	PINMUX_DATA(VIO_CLK_MARK, PORT146_FN1),
+	PINMUX_DATA(PORT146_KEYIN4_MARK, PORT146_FN2),
+	PINMUX_DATA(IPORT2_MARK, PORT146_FN3),
+	PINMUX_DATA(VIO_FIELD_MARK, PORT147_FN1),
+	PINMUX_DATA(PORT147_KEYIN5_MARK, PORT147_FN2),
+	PINMUX_DATA(VIO_CKO_MARK, PORT148_FN1),
+	PINMUX_DATA(PORT148_KEYIN6_MARK, PORT148_FN2),
+	PINMUX_DATA(A27_MARK, PORT149_FN1),
+	PINMUX_DATA(RDWR_XWE_MARK, PORT149_FN2),
+	PINMUX_DATA(MFG0_IN1_MARK, PORT149_FN3),
+	PINMUX_DATA(MFG0_IN2_MARK, PORT150_FN1),
+	PINMUX_DATA(TS_SPSYNC3_MARK, PORT151_FN1),
+	PINMUX_DATA(MSIOF2_RSCK_MARK, PORT151_FN2),
+	PINMUX_DATA(TS_SDAT3_MARK, PORT152_FN1),
+	PINMUX_DATA(MSIOF2_RSYNC_MARK, PORT152_FN2),
+	PINMUX_DATA(TPU1TO2_MARK, PORT153_FN1),
+	PINMUX_DATA(TS_SDEN3_MARK, PORT153_FN2),
+	PINMUX_DATA(PORT153_MSIOF2_SS1_MARK, PORT153_FN3),
+	PINMUX_DATA(SOUT3_MARK, PORT154_FN1),
+	PINMUX_DATA(SCIFA2_TXD1_MARK, PORT154_FN2),
+	PINMUX_DATA(MSIOF2_MCK0_MARK, PORT154_FN3),
+	PINMUX_DATA(SIN3_MARK, PORT155_FN1),
+	PINMUX_DATA(SCIFA2_RXD1_MARK, PORT155_FN2),
+	PINMUX_DATA(MSIOF2_MCK1_MARK, PORT155_FN3),
+	PINMUX_DATA(XRTS3_MARK, PORT156_FN1),
+	PINMUX_DATA(SCIFA2_RTS1_MARK, PORT156_FN2),
+	PINMUX_DATA(PORT156_MSIOF2_SS2_MARK, PORT156_FN3),
+	PINMUX_DATA(XCTS3_MARK, PORT157_FN1),
+	PINMUX_DATA(SCIFA2_CTS1_MARK, PORT157_FN2),
+	PINMUX_DATA(PORT157_MSIOF2_RXD_MARK, PORT157_FN3),
+
+	/* 55-4 (FN) */
+	PINMUX_DATA(DINT_MARK, PORT158_FN1),
+	PINMUX_DATA(SCIFA2_SCK1_MARK, PORT158_FN2),
+	PINMUX_DATA(TS_SCK3_MARK, PORT158_FN3),
+	PINMUX_DATA(PORT159_SCIFB_SCK_MARK, PORT159_FN1),
+	PINMUX_DATA(PORT159_SCIFA5_SCK_MARK, PORT159_FN2),
+	PINMUX_DATA(NMI_MARK, PORT159_FN3),
+	PINMUX_DATA(PORT160_SCIFB_TXD_MARK, PORT160_FN1),
+	PINMUX_DATA(PORT160_SCIFA5_TXD_MARK, PORT160_FN2),
+	PINMUX_DATA(SOUT0_MARK, PORT160_FN3),
+	PINMUX_DATA(PORT161_SCIFB_CTS_MARK, PORT161_FN1),
+	PINMUX_DATA(PORT161_SCIFA5_CTS_MARK, PORT161_FN2),
+	PINMUX_DATA(XCTS0_MARK, PORT161_FN3),
+	PINMUX_DATA(MFG3_IN2_MARK, PORT161_FN4),
+	PINMUX_DATA(PORT162_SCIFB_RXD_MARK, PORT162_FN1),
+	PINMUX_DATA(PORT162_SCIFA5_RXD_MARK, PORT162_FN2),
+	PINMUX_DATA(SIN0_MARK, PORT162_FN3),
+	PINMUX_DATA(MFG3_IN1_MARK, PORT162_FN4),
+	PINMUX_DATA(PORT163_SCIFB_RTS_MARK, PORT163_FN1),
+	PINMUX_DATA(PORT163_SCIFA5_RTS_MARK, PORT163_FN2),
+	PINMUX_DATA(XRTS0_MARK, PORT163_FN3),
+	PINMUX_DATA(MFG3_OUT1_MARK, PORT163_FN4),
+	PINMUX_DATA(TPU3TO0_MARK, PORT163_FN5),
+	PINMUX_DATA(LCDD0_MARK, PORT192_FN1),
+	PINMUX_DATA(PORT192_KEYOUT0_MARK, PORT192_FN2),
+	PINMUX_DATA(EXT_CKI_MARK, PORT192_FN3),
+	PINMUX_DATA(LCDD1_MARK, PORT193_FN1),
+	PINMUX_DATA(PORT193_KEYOUT1_MARK, PORT193_FN2),
+	PINMUX_DATA(PORT193_SCIFA5_CTS_MARK, PORT193_FN3),
+	PINMUX_DATA(BBIF2_TSYNC1_MARK, PORT193_FN4),
+	PINMUX_DATA(LCDD2_MARK, PORT194_FN1),
+	PINMUX_DATA(PORT194_KEYOUT2_MARK, PORT194_FN2),
+	PINMUX_DATA(PORT194_SCIFA5_RTS_MARK, PORT194_FN3),
+	PINMUX_DATA(BBIF2_TSCK1_MARK, PORT194_FN4),
+	PINMUX_DATA(LCDD3_MARK, PORT195_FN1),
+	PINMUX_DATA(PORT195_KEYOUT3_MARK, PORT195_FN2),
+	PINMUX_DATA(PORT195_SCIFA5_RXD_MARK, PORT195_FN3),
+	PINMUX_DATA(BBIF2_TXD1_MARK, PORT195_FN4),
+	PINMUX_DATA(LCDD4_MARK, PORT196_FN1),
+	PINMUX_DATA(PORT196_KEYOUT4_MARK, PORT196_FN2),
+	PINMUX_DATA(PORT196_SCIFA5_TXD_MARK, PORT196_FN3),
+	PINMUX_DATA(LCDD5_MARK, PORT197_FN1),
+	PINMUX_DATA(PORT197_KEYOUT5_MARK, PORT197_FN2),
+	PINMUX_DATA(PORT197_SCIFA5_SCK_MARK, PORT197_FN3),
+	PINMUX_DATA(MFG2_OUT2_MARK, PORT197_FN4),
+	PINMUX_DATA(LCDD6_MARK, PORT198_FN1),
+	PINMUX_DATA(LCDD7_MARK, PORT199_FN1),
+	PINMUX_DATA(TPU4TO1_MARK, PORT199_FN2),
+	PINMUX_DATA(MFG4_OUT2_MARK, PORT199_FN3),
+	PINMUX_DATA(LCDD8_MARK, PORT200_FN1),
+	PINMUX_DATA(PORT200_KEYIN0_MARK, PORT200_FN2),
+	PINMUX_DATA(VIO_DR0_MARK, PORT200_FN3),
+	PINMUX_DATA(D16_MARK, PORT200_FN4),
+	PINMUX_DATA(LCDD9_MARK, PORT201_FN1),
+	PINMUX_DATA(PORT201_KEYIN1_MARK, PORT201_FN2),
+	PINMUX_DATA(VIO_DR1_MARK, PORT201_FN3),
+	PINMUX_DATA(D17_MARK, PORT201_FN4),
+	PINMUX_DATA(LCDD10_MARK, PORT202_FN1),
+	PINMUX_DATA(PORT202_KEYIN2_MARK, PORT202_FN2),
+	PINMUX_DATA(VIO_DR2_MARK, PORT202_FN3),
+	PINMUX_DATA(D18_MARK, PORT202_FN4),
+	PINMUX_DATA(LCDD11_MARK, PORT203_FN1),
+	PINMUX_DATA(PORT203_KEYIN3_MARK, PORT203_FN2),
+	PINMUX_DATA(VIO_DR3_MARK, PORT203_FN3),
+	PINMUX_DATA(D19_MARK, PORT203_FN4),
+	PINMUX_DATA(LCDD12_MARK, PORT204_FN1),
+	PINMUX_DATA(PORT204_KEYIN4_MARK, PORT204_FN2),
+	PINMUX_DATA(VIO_DR4_MARK, PORT204_FN3),
+	PINMUX_DATA(D20_MARK, PORT204_FN4),
+	PINMUX_DATA(LCDD13_MARK, PORT205_FN1),
+	PINMUX_DATA(PORT205_KEYIN5_MARK, PORT205_FN2),
+	PINMUX_DATA(VIO_DR5_MARK, PORT205_FN3),
+	PINMUX_DATA(D21_MARK, PORT205_FN4),
+	PINMUX_DATA(LCDD14_MARK, PORT206_FN1),
+	PINMUX_DATA(PORT206_KEYIN6_MARK, PORT206_FN2),
+	PINMUX_DATA(VIO_DR6_MARK, PORT206_FN3),
+	PINMUX_DATA(D22_MARK, PORT206_FN4),
+	PINMUX_DATA(LCDD15_MARK, PORT207_FN1),
+	PINMUX_DATA(PORT207_MSIOF0L_SS1_MARK, PORT207_FN2),
+	PINMUX_DATA(PORT207_KEYOUT0_MARK, PORT207_FN3),
+	PINMUX_DATA(VIO_DR7_MARK, PORT207_FN4),
+	PINMUX_DATA(D23_MARK, PORT207_FN5),
+	PINMUX_DATA(LCDD16_MARK, PORT208_FN1),
+	PINMUX_DATA(PORT208_MSIOF0L_SS2_MARK, PORT208_FN2),
+	PINMUX_DATA(PORT208_KEYOUT1_MARK, PORT208_FN3),
+	PINMUX_DATA(VIO_VDR_MARK, PORT208_FN4),
+	PINMUX_DATA(D24_MARK, PORT208_FN5),
+	PINMUX_DATA(LCDD17_MARK, PORT209_FN1),
+	PINMUX_DATA(PORT209_KEYOUT2_MARK, PORT209_FN2),
+	PINMUX_DATA(VIO_HDR_MARK, PORT209_FN3),
+	PINMUX_DATA(D25_MARK, PORT209_FN4),
+	PINMUX_DATA(LCDD18_MARK, PORT210_FN1),
+	PINMUX_DATA(DREQ2_MARK, PORT210_FN2),
+	PINMUX_DATA(PORT210_MSIOF0L_SS1_MARK, PORT210_FN3),
+	PINMUX_DATA(D26_MARK, PORT210_FN4),
+	PINMUX_DATA(LCDD19_MARK, PORT211_FN1),
+	PINMUX_DATA(PORT211_MSIOF0L_SS2_MARK, PORT211_FN2),
+	PINMUX_DATA(D27_MARK, PORT211_FN3),
+	PINMUX_DATA(LCDD20_MARK, PORT212_FN1),
+	PINMUX_DATA(TS_SPSYNC1_MARK, PORT212_FN2),
+	PINMUX_DATA(MSIOF0L_MCK0_MARK, PORT212_FN3),
+	PINMUX_DATA(D28_MARK, PORT212_FN4),
+	PINMUX_DATA(LCDD21_MARK, PORT213_FN1),
+	PINMUX_DATA(TS_SDAT1_MARK, PORT213_FN2),
+	PINMUX_DATA(MSIOF0L_MCK1_MARK, PORT213_FN3),
+	PINMUX_DATA(D29_MARK, PORT213_FN4),
+	PINMUX_DATA(LCDD22_MARK, PORT214_FN1),
+	PINMUX_DATA(TS_SDEN1_MARK, PORT214_FN2),
+	PINMUX_DATA(MSIOF0L_RSCK_MARK, PORT214_FN3),
+	PINMUX_DATA(D30_MARK, PORT214_FN4),
+	PINMUX_DATA(LCDD23_MARK, PORT215_FN1),
+	PINMUX_DATA(TS_SCK1_MARK, PORT215_FN2),
+	PINMUX_DATA(MSIOF0L_RSYNC_MARK, PORT215_FN3),
+	PINMUX_DATA(D31_MARK, PORT215_FN4),
+	PINMUX_DATA(LCDDCK_MARK, PORT216_FN1),
+	PINMUX_DATA(LCDWR_MARK, PORT216_FN2),
+	PINMUX_DATA(PORT216_KEYOUT3_MARK, PORT216_FN3),
+	PINMUX_DATA(VIO_CLKR_MARK, PORT216_FN4),
+	PINMUX_DATA(LCDRD_MARK, PORT217_FN1),
+	PINMUX_DATA(DACK2_MARK, PORT217_FN2),
+	PINMUX_DATA(MSIOF0L_TSYNC_MARK, PORT217_FN3),
+	PINMUX_DATA(LCDHSYN_MARK, PORT218_FN1),
+	PINMUX_DATA(LCDCS_MARK, PORT218_FN2),
+	PINMUX_DATA(LCDCS2_MARK, PORT218_FN3),
+	PINMUX_DATA(DACK3_MARK, PORT218_FN4),
+	PINMUX_DATA(PORT218_VIO_CKOR_MARK, PORT218_FN5),
+	PINMUX_DATA(PORT218_KEYOUT4_MARK, PORT218_FN6),
+	PINMUX_DATA(LCDDISP_MARK, PORT219_FN1),
+	PINMUX_DATA(LCDRS_MARK, PORT219_FN2),
+	PINMUX_DATA(DREQ3_MARK, PORT219_FN3),
+	PINMUX_DATA(MSIOF0L_TSCK_MARK, PORT219_FN4),
+	PINMUX_DATA(LCDVSYN_MARK, PORT220_FN1),
+	PINMUX_DATA(LCDVSYN2_MARK, PORT220_FN2),
+	PINMUX_DATA(PORT220_KEYOUT5_MARK, PORT220_FN3),
+	PINMUX_DATA(LCDLCLK_MARK, PORT221_FN1),
+	PINMUX_DATA(DREQ1_MARK, PORT221_FN2),
+	PINMUX_DATA(PWEN_MARK, PORT221_FN3),
+	PINMUX_DATA(MSIOF0L_RXD_MARK, PORT221_FN4),
+	PINMUX_DATA(LCDDON_MARK, PORT222_FN1),
+	PINMUX_DATA(LCDDON2_MARK, PORT222_FN2),
+	PINMUX_DATA(DACK1_MARK, PORT222_FN3),
+	PINMUX_DATA(OVCN_MARK, PORT222_FN4),
+	PINMUX_DATA(MSIOF0L_TXD_MARK, PORT222_FN5),
+	PINMUX_DATA(SCIFA1_TXD_MARK, PORT225_FN1),
+	PINMUX_DATA(OVCN2_MARK, PORT225_FN2),
+	PINMUX_DATA(EXTLP_MARK, PORT226_FN1),
+	PINMUX_DATA(SCIFA1_SCK_MARK, PORT226_FN2),
+	PINMUX_DATA(USBTERM_MARK, PORT226_FN3),
+	PINMUX_DATA(PORT226_VIO_CKO2_MARK, PORT226_FN4),
+	PINMUX_DATA(SCIFA1_RTS_MARK, PORT227_FN1),
+	PINMUX_DATA(IDIN_MARK, PORT227_FN2),
+	PINMUX_DATA(SCIFA1_RXD_MARK, PORT228_FN1),
+	PINMUX_DATA(SCIFA1_CTS_MARK, PORT229_FN1),
+	PINMUX_DATA(MFG1_IN1_MARK, PORT229_FN2),
+	PINMUX_DATA(MSIOF1_TXD_MARK, PORT230_FN1),
+	PINMUX_DATA(SCIFA2_TXD2_MARK, PORT230_FN2),
+	PINMUX_DATA(PORT230_FSIAOMC_MARK, PORT230_FN3),
+	PINMUX_DATA(MSIOF1_TSYNC_MARK, PORT231_FN1),
+	PINMUX_DATA(SCIFA2_CTS2_MARK, PORT231_FN2),
+	PINMUX_DATA(PORT231_FSIAOLR_MARK, PORT231_FN3),
+	PINMUX_DATA(MSIOF1_TSCK_MARK, PORT232_FN1),
+	PINMUX_DATA(SCIFA2_SCK2_MARK, PORT232_FN2),
+	PINMUX_DATA(PORT232_FSIAOBT_MARK, PORT232_FN3),
+	PINMUX_DATA(MSIOF1_RXD_MARK, PORT233_FN1),
+	PINMUX_DATA(SCIFA2_RXD2_MARK, PORT233_FN2),
+	PINMUX_DATA(GPS_VCOTRIG_MARK, PORT233_FN3),
+	PINMUX_DATA(PORT233_FSIACK_MARK, PORT233_FN4),
+	PINMUX_DATA(MSIOF1_RSCK_MARK, PORT234_FN1),
+	PINMUX_DATA(SCIFA2_RTS2_MARK, PORT234_FN2),
+	PINMUX_DATA(PORT234_FSIAOSLD_MARK, PORT234_FN3),
+	PINMUX_DATA(MSIOF1_RSYNC_MARK, PORT235_FN1),
+	PINMUX_DATA(OPORT0_MARK, PORT235_FN2),
+	PINMUX_DATA(MFG1_IN2_MARK, PORT235_FN3),
+	PINMUX_DATA(PORT235_FSIAILR_MARK, PORT235_FN4),
+	PINMUX_DATA(MSIOF1_MCK0_MARK, PORT236_FN1),
+	PINMUX_DATA(I2C_SDA2_MARK, PORT236_FN2),
+	PINMUX_DATA(PORT236_FSIAIBT_MARK, PORT236_FN3),
+	PINMUX_DATA(MSIOF1_MCK1_MARK, PORT237_FN1),
+	PINMUX_DATA(I2C_SCL2_MARK, PORT237_FN2),
+	PINMUX_DATA(PORT237_FSIAISLD_MARK, PORT237_FN3),
+	PINMUX_DATA(MSIOF1_SS1_MARK, PORT238_FN1),
+	PINMUX_DATA(EDBGREQ3_MARK, PORT238_FN2),
+
+	/* 55-5 (FN) */
+	PINMUX_DATA(MSIOF1_SS2_MARK, PORT239_FN1),
+	PINMUX_DATA(SCIFA6_TXD_MARK, PORT240_FN1),
+	PINMUX_DATA(PORT241_IRDA_OUT_MARK, PORT241_FN1),
+	PINMUX_DATA(PORT241_IROUT_MARK, PORT241_FN2),
+	PINMUX_DATA(MFG4_OUT1_MARK, PORT241_FN3),
+	PINMUX_DATA(TPU4TO0_MARK, PORT241_FN4),
+	PINMUX_DATA(PORT242_IRDA_IN_MARK, PORT242_FN1),
+	PINMUX_DATA(MFG4_IN2_MARK, PORT242_FN2),
+	PINMUX_DATA(PORT243_IRDA_FIRSEL_MARK, PORT243_FN1),
+	PINMUX_DATA(PORT243_VIO_CKO2_MARK, PORT243_FN2),
+	PINMUX_DATA(PORT244_SCIFA5_CTS_MARK, PORT244_FN1),
+	PINMUX_DATA(MFG2_IN1_MARK, PORT244_FN2),
+	PINMUX_DATA(PORT244_SCIFB_CTS_MARK, PORT244_FN3),
+	PINMUX_DATA(PORT245_SCIFA5_RTS_MARK, PORT245_FN1),
+	PINMUX_DATA(MFG2_IN2_MARK, PORT245_FN2),
+	PINMUX_DATA(PORT245_SCIFB_RTS_MARK, PORT245_FN3),
+	PINMUX_DATA(PORT246_SCIFA5_RXD_MARK, PORT246_FN1),
+	PINMUX_DATA(MFG1_OUT1_MARK, PORT246_FN2),
+	PINMUX_DATA(PORT246_SCIFB_RXD_MARK, PORT246_FN3),
+	PINMUX_DATA(TPU1TO0_MARK, PORT246_FN4),
+	PINMUX_DATA(PORT247_SCIFA5_TXD_MARK, PORT247_FN1),
+	PINMUX_DATA(MFG3_OUT2_MARK, PORT247_FN2),
+	PINMUX_DATA(PORT247_SCIFB_TXD_MARK, PORT247_FN3),
+	PINMUX_DATA(TPU3TO1_MARK, PORT247_FN4),
+	PINMUX_DATA(PORT248_SCIFA5_SCK_MARK, PORT248_FN1),
+	PINMUX_DATA(MFG2_OUT1_MARK, PORT248_FN2),
+	PINMUX_DATA(PORT248_SCIFB_SCK_MARK, PORT248_FN3),
+	PINMUX_DATA(TPU2TO0_MARK, PORT248_FN4),
+	PINMUX_DATA(PORT249_IROUT_MARK, PORT249_FN1),
+	PINMUX_DATA(MFG4_IN1_MARK, PORT249_FN2),
+	PINMUX_DATA(SDHICLK0_MARK, PORT250_FN1),
+	PINMUX_DATA(TCK2_SWCLK_MC0_MARK, PORT250_FN2),
+	PINMUX_DATA(SDHICD0_MARK, PORT251_FN1),
+	PINMUX_DATA(SDHID0_0_MARK, PORT252_FN1),
+	PINMUX_DATA(TMS2_SWDIO_MC0_MARK, PORT252_FN2),
+	PINMUX_DATA(SDHID0_1_MARK, PORT253_FN1),
+	PINMUX_DATA(TDO2_SWO0_MC0_MARK, PORT253_FN2),
+	PINMUX_DATA(SDHID0_2_MARK, PORT254_FN1),
+	PINMUX_DATA(TDI2_MARK, PORT254_FN2),
+	PINMUX_DATA(SDHID0_3_MARK, PORT255_FN1),
+	PINMUX_DATA(RTCK2_SWO1_MC0_MARK, PORT255_FN2),
+	PINMUX_DATA(SDHICMD0_MARK, PORT256_FN1),
+	PINMUX_DATA(TRST2_MARK, PORT256_FN2),
+	PINMUX_DATA(SDHIWP0_MARK, PORT257_FN1),
+	PINMUX_DATA(EDBGREQ2_MARK, PORT257_FN2),
+	PINMUX_DATA(SDHICLK1_MARK, PORT258_FN1),
+	PINMUX_DATA(TCK3_SWCLK_MC1_MARK, PORT258_FN2),
+	PINMUX_DATA(SDHID1_0_MARK, PORT259_FN1),
+	PINMUX_DATA(M11_SLCD_SO2_MARK, PORT259_FN2),
+	PINMUX_DATA(TS_SPSYNC2_MARK, PORT259_FN3),
+	PINMUX_DATA(TMS3_SWDIO_MC1_MARK, PORT259_FN4),
+	PINMUX_DATA(SDHID1_1_MARK, PORT260_FN1),
+	PINMUX_DATA(M9_SLCD_A02_MARK, PORT260_FN2),
+	PINMUX_DATA(TS_SDAT2_MARK, PORT260_FN3),
+	PINMUX_DATA(TDO3_SWO0_MC1_MARK, PORT260_FN4),
+	PINMUX_DATA(SDHID1_2_MARK, PORT261_FN1),
+	PINMUX_DATA(M10_SLCD_CK2_MARK, PORT261_FN2),
+	PINMUX_DATA(TS_SDEN2_MARK, PORT261_FN3),
+	PINMUX_DATA(TDI3_MARK, PORT261_FN4),
+	PINMUX_DATA(SDHID1_3_MARK, PORT262_FN1),
+	PINMUX_DATA(M12_SLCD_CE2_MARK, PORT262_FN2),
+	PINMUX_DATA(TS_SCK2_MARK, PORT262_FN3),
+	PINMUX_DATA(RTCK3_SWO1_MC1_MARK, PORT262_FN4),
+	PINMUX_DATA(SDHICMD1_MARK, PORT263_FN1),
+	PINMUX_DATA(TRST3_MARK, PORT263_FN2),
+	PINMUX_DATA(RESETOUTS_MARK, PORT264_FN1),
+};
+
+#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
+#define GPIO_PORT_265() _265(_GPIO_PORT, , unused)
+#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
+
+static struct pinmux_gpio pinmux_gpios[] = {
+	/* 55-1 -> 55-5 (GPIO) */
+	GPIO_PORT_265(),
+
+	/* Special Pull-up / Pull-down Functions */
+	GPIO_FN(PORT66_KEYIN0_PU), GPIO_FN(PORT67_KEYIN1_PU),
+	GPIO_FN(PORT68_KEYIN2_PU), GPIO_FN(PORT69_KEYIN3_PU),
+	GPIO_FN(PORT70_KEYIN4_PU), GPIO_FN(PORT71_KEYIN5_PU),
+	GPIO_FN(PORT72_KEYIN6_PU),
+
+	/* 55-1 (FN) */
+	GPIO_FN(VBUS_0),
+	GPIO_FN(CPORT0),
+	GPIO_FN(CPORT1),
+	GPIO_FN(CPORT2),
+	GPIO_FN(CPORT3),
+	GPIO_FN(CPORT4),
+	GPIO_FN(CPORT5),
+	GPIO_FN(CPORT6),
+	GPIO_FN(CPORT7),
+	GPIO_FN(CPORT8),
+	GPIO_FN(CPORT9),
+	GPIO_FN(CPORT10),
+	GPIO_FN(CPORT11), GPIO_FN(SIN2),
+	GPIO_FN(CPORT12), GPIO_FN(XCTS2),
+	GPIO_FN(CPORT13), GPIO_FN(RFSPO4),
+	GPIO_FN(CPORT14), GPIO_FN(RFSPO5),
+	GPIO_FN(CPORT15), GPIO_FN(SCIFA0_SCK), GPIO_FN(GPS_AGC2),
+	GPIO_FN(CPORT16), GPIO_FN(SCIFA0_TXD), GPIO_FN(GPS_AGC3),
+	GPIO_FN(CPORT17_IC_OE), GPIO_FN(SOUT2),
+	GPIO_FN(CPORT18), GPIO_FN(XRTS2), GPIO_FN(PORT19_VIO_CKO2),
+	GPIO_FN(CPORT19_MPORT1),
+	GPIO_FN(CPORT20), GPIO_FN(RFSPO6),
+	GPIO_FN(CPORT21), GPIO_FN(STATUS0),
+	GPIO_FN(CPORT22), GPIO_FN(STATUS1),
+	GPIO_FN(CPORT23), GPIO_FN(STATUS2), GPIO_FN(RFSPO7),
+	GPIO_FN(B_SYNLD1),
+	GPIO_FN(B_SYNLD2), GPIO_FN(SYSENMSK),
+	GPIO_FN(XMAINPS),
+	GPIO_FN(XDIVPS),
+	GPIO_FN(XIDRST),
+	GPIO_FN(IDCLK), GPIO_FN(IC_DP),
+	GPIO_FN(IDIO), GPIO_FN(IC_DM),
+	GPIO_FN(SOUT1), GPIO_FN(SCIFA4_TXD), GPIO_FN(M02_BERDAT),
+	GPIO_FN(SIN1), GPIO_FN(SCIFA4_RXD), GPIO_FN(XWUP),
+	GPIO_FN(XRTS1), GPIO_FN(SCIFA4_RTS), GPIO_FN(M03_BERCLK),
+	GPIO_FN(XCTS1), GPIO_FN(SCIFA4_CTS),
+	GPIO_FN(PCMCLKO),
+	GPIO_FN(SYNC8KO),
+
+	/* 55-2 (FN) */
+	GPIO_FN(DNPCM_A),
+	GPIO_FN(UPPCM_A),
+	GPIO_FN(VACK),
+	GPIO_FN(XTALB1L),
+	GPIO_FN(GPS_AGC1), GPIO_FN(SCIFA0_RTS),
+	GPIO_FN(GPS_AGC4), GPIO_FN(SCIFA0_RXD),
+	GPIO_FN(GPS_PWRDOWN), GPIO_FN(SCIFA0_CTS),
+	GPIO_FN(GPS_IM),
+	GPIO_FN(GPS_IS),
+	GPIO_FN(GPS_QM),
+	GPIO_FN(GPS_QS),
+	GPIO_FN(FMSOCK), GPIO_FN(PORT49_IRDA_OUT), GPIO_FN(PORT49_IROUT),
+	GPIO_FN(FMSOOLR), GPIO_FN(BBIF2_TSYNC2), GPIO_FN(TPU2TO2),
+	GPIO_FN(IPORT3), GPIO_FN(FMSIOLR),
+	GPIO_FN(FMSOOBT), GPIO_FN(BBIF2_TSCK2), GPIO_FN(TPU2TO3),
+	GPIO_FN(OPORT1), GPIO_FN(FMSIOBT),
+	GPIO_FN(FMSOSLD), GPIO_FN(BBIF2_TXD2), GPIO_FN(OPORT2),
+	GPIO_FN(FMSOILR), GPIO_FN(PORT53_IRDA_IN), GPIO_FN(TPU3TO3),
+	GPIO_FN(OPORT3), GPIO_FN(FMSIILR),
+	GPIO_FN(FMSOIBT), GPIO_FN(PORT54_IRDA_FIRSEL), GPIO_FN(TPU3TO2),
+	GPIO_FN(FMSIIBT),
+	GPIO_FN(FMSISLD), GPIO_FN(MFG0_OUT1), GPIO_FN(TPU0TO0),
+	GPIO_FN(A0_EA0), GPIO_FN(BS),
+	GPIO_FN(A12_EA12), GPIO_FN(PORT58_VIO_CKOR), GPIO_FN(TPU4TO2),
+	GPIO_FN(A13_EA13), GPIO_FN(PORT59_IROUT), GPIO_FN(MFG0_OUT2),
+	GPIO_FN(TPU0TO1),
+	GPIO_FN(A14_EA14), GPIO_FN(PORT60_KEYOUT5),
+	GPIO_FN(A15_EA15), GPIO_FN(PORT61_KEYOUT4),
+	GPIO_FN(A16_EA16), GPIO_FN(PORT62_KEYOUT3), GPIO_FN(MSIOF0_SS1),
+	GPIO_FN(A17_EA17), GPIO_FN(PORT63_KEYOUT2), GPIO_FN(MSIOF0_TSYNC),
+	GPIO_FN(A18_EA18), GPIO_FN(PORT64_KEYOUT1), GPIO_FN(MSIOF0_TSCK),
+	GPIO_FN(A19_EA19), GPIO_FN(PORT65_KEYOUT0), GPIO_FN(MSIOF0_TXD),
+	GPIO_FN(A20_EA20), GPIO_FN(PORT66_KEYIN0), GPIO_FN(MSIOF0_RSCK),
+	GPIO_FN(A21_EA21), GPIO_FN(PORT67_KEYIN1), GPIO_FN(MSIOF0_RSYNC),
+	GPIO_FN(A22_EA22), GPIO_FN(PORT68_KEYIN2), GPIO_FN(MSIOF0_MCK0),
+	GPIO_FN(A23_EA23), GPIO_FN(PORT69_KEYIN3), GPIO_FN(MSIOF0_MCK1),
+	GPIO_FN(A24_EA24), GPIO_FN(PORT70_KEYIN4), GPIO_FN(MSIOF0_RXD),
+	GPIO_FN(A25_EA25), GPIO_FN(PORT71_KEYIN5), GPIO_FN(MSIOF0_SS2),
+	GPIO_FN(A26), GPIO_FN(PORT72_KEYIN6),
+	GPIO_FN(D0_ED0_NAF0),
+	GPIO_FN(D1_ED1_NAF1),
+	GPIO_FN(D2_ED2_NAF2),
+	GPIO_FN(D3_ED3_NAF3),
+	GPIO_FN(D4_ED4_NAF4),
+	GPIO_FN(D5_ED5_NAF5),
+	GPIO_FN(D6_ED6_NAF6),
+	GPIO_FN(D7_ED7_NAF7),
+	GPIO_FN(D8_ED8_NAF8),
+	GPIO_FN(D9_ED9_NAF9),
+	GPIO_FN(D10_ED10_NAF10),
+	GPIO_FN(D11_ED11_NAF11),
+	GPIO_FN(D12_ED12_NAF12),
+	GPIO_FN(D13_ED13_NAF13),
+	GPIO_FN(D14_ED14_NAF14),
+	GPIO_FN(D15_ED15_NAF15),
+	GPIO_FN(CS4),
+	GPIO_FN(CS5A), GPIO_FN(FMSICK),
+
+	/* 55-3 (FN) */
+	GPIO_FN(CS5B), GPIO_FN(FCE1),
+	GPIO_FN(CS6B), GPIO_FN(XCS2), GPIO_FN(CS6A), GPIO_FN(DACK0),
+	GPIO_FN(FCE0),
+	GPIO_FN(WAIT), GPIO_FN(DREQ0),
+	GPIO_FN(RD_XRD),
+	GPIO_FN(WE0_XWR0_FWE),
+	GPIO_FN(WE1_XWR1),
+	GPIO_FN(FRB),
+	GPIO_FN(CKO),
+	GPIO_FN(NBRSTOUT),
+	GPIO_FN(NBRST),
+	GPIO_FN(GPS_EPPSIN),
+	GPIO_FN(LATCHPULSE),
+	GPIO_FN(LTESIGNAL),
+	GPIO_FN(LEGACYSTATE),
+	GPIO_FN(TCKON),
+	GPIO_FN(VIO_VD), GPIO_FN(PORT128_KEYOUT0), GPIO_FN(IPORT0),
+	GPIO_FN(VIO_HD), GPIO_FN(PORT129_KEYOUT1), GPIO_FN(IPORT1),
+	GPIO_FN(VIO_D0), GPIO_FN(PORT130_KEYOUT2), GPIO_FN(PORT130_MSIOF2_RXD),
+	GPIO_FN(VIO_D1), GPIO_FN(PORT131_KEYOUT3), GPIO_FN(PORT131_MSIOF2_SS1),
+	GPIO_FN(VIO_D2), GPIO_FN(PORT132_KEYOUT4), GPIO_FN(PORT132_MSIOF2_SS2),
+	GPIO_FN(VIO_D3), GPIO_FN(PORT133_KEYOUT5),
+	GPIO_FN(PORT133_MSIOF2_TSYNC),
+	GPIO_FN(VIO_D4), GPIO_FN(PORT134_KEYIN0), GPIO_FN(PORT134_MSIOF2_TXD),
+	GPIO_FN(VIO_D5), GPIO_FN(PORT135_KEYIN1), GPIO_FN(PORT135_MSIOF2_TSCK),
+	GPIO_FN(VIO_D6), GPIO_FN(PORT136_KEYIN2),
+	GPIO_FN(VIO_D7), GPIO_FN(PORT137_KEYIN3),
+	GPIO_FN(VIO_D8), GPIO_FN(M9_SLCD_A01), GPIO_FN(PORT138_FSIAOMC),
+	GPIO_FN(VIO_D9), GPIO_FN(M10_SLCD_CK1), GPIO_FN(PORT139_FSIAOLR),
+	GPIO_FN(VIO_D10), GPIO_FN(M11_SLCD_SO1), GPIO_FN(TPU0TO2),
+	GPIO_FN(PORT140_FSIAOBT),
+	GPIO_FN(VIO_D11), GPIO_FN(M12_SLCD_CE1), GPIO_FN(TPU0TO3),
+	GPIO_FN(PORT141_FSIAOSLD),
+	GPIO_FN(VIO_D12), GPIO_FN(M13_BSW), GPIO_FN(PORT142_FSIACK),
+	GPIO_FN(VIO_D13), GPIO_FN(M14_GSW), GPIO_FN(PORT143_FSIAILR),
+	GPIO_FN(VIO_D14), GPIO_FN(M15_RSW), GPIO_FN(PORT144_FSIAIBT),
+	GPIO_FN(VIO_D15), GPIO_FN(TPU1TO3), GPIO_FN(PORT145_FSIAISLD),
+	GPIO_FN(VIO_CLK), GPIO_FN(PORT146_KEYIN4), GPIO_FN(IPORT2),
+	GPIO_FN(VIO_FIELD), GPIO_FN(PORT147_KEYIN5),
+	GPIO_FN(VIO_CKO), GPIO_FN(PORT148_KEYIN6),
+	GPIO_FN(A27), GPIO_FN(RDWR_XWE), GPIO_FN(MFG0_IN1),
+	GPIO_FN(MFG0_IN2),
+	GPIO_FN(TS_SPSYNC3), GPIO_FN(MSIOF2_RSCK),
+	GPIO_FN(TS_SDAT3), GPIO_FN(MSIOF2_RSYNC),
+	GPIO_FN(TPU1TO2), GPIO_FN(TS_SDEN3), GPIO_FN(PORT153_MSIOF2_SS1),
+	GPIO_FN(SOUT3), GPIO_FN(SCIFA2_TXD1), GPIO_FN(MSIOF2_MCK0),
+	GPIO_FN(SIN3), GPIO_FN(SCIFA2_RXD1), GPIO_FN(MSIOF2_MCK1),
+	GPIO_FN(XRTS3), GPIO_FN(SCIFA2_RTS1), GPIO_FN(PORT156_MSIOF2_SS2),
+	GPIO_FN(XCTS3), GPIO_FN(SCIFA2_CTS1), GPIO_FN(PORT157_MSIOF2_RXD),
+
+	/* 55-4 (FN) */
+	GPIO_FN(DINT), GPIO_FN(SCIFA2_SCK1), GPIO_FN(TS_SCK3),
+	GPIO_FN(PORT159_SCIFB_SCK), GPIO_FN(PORT159_SCIFA5_SCK), GPIO_FN(NMI),
+	GPIO_FN(PORT160_SCIFB_TXD), GPIO_FN(PORT160_SCIFA5_TXD), GPIO_FN(SOUT0),
+	GPIO_FN(PORT161_SCIFB_CTS), GPIO_FN(PORT161_SCIFA5_CTS), GPIO_FN(XCTS0),
+	GPIO_FN(MFG3_IN2),
+	GPIO_FN(PORT162_SCIFB_RXD), GPIO_FN(PORT162_SCIFA5_RXD), GPIO_FN(SIN0),
+	GPIO_FN(MFG3_IN1),
+	GPIO_FN(PORT163_SCIFB_RTS), GPIO_FN(PORT163_SCIFA5_RTS), GPIO_FN(XRTS0),
+	GPIO_FN(MFG3_OUT1), GPIO_FN(TPU3TO0),
+	GPIO_FN(LCDD0), GPIO_FN(PORT192_KEYOUT0), GPIO_FN(EXT_CKI),
+	GPIO_FN(LCDD1), GPIO_FN(PORT193_KEYOUT1), GPIO_FN(PORT193_SCIFA5_CTS),
+	GPIO_FN(BBIF2_TSYNC1),
+	GPIO_FN(LCDD2), GPIO_FN(PORT194_KEYOUT2), GPIO_FN(PORT194_SCIFA5_RTS),
+	GPIO_FN(BBIF2_TSCK1),
+	GPIO_FN(LCDD3), GPIO_FN(PORT195_KEYOUT3), GPIO_FN(PORT195_SCIFA5_RXD),
+	GPIO_FN(BBIF2_TXD1),
+	GPIO_FN(LCDD4), GPIO_FN(PORT196_KEYOUT4), GPIO_FN(PORT196_SCIFA5_TXD),
+	GPIO_FN(LCDD5), GPIO_FN(PORT197_KEYOUT5), GPIO_FN(PORT197_SCIFA5_SCK),
+	GPIO_FN(MFG2_OUT2),
+	GPIO_FN(LCDD6),
+	GPIO_FN(LCDD7), GPIO_FN(TPU4TO1), GPIO_FN(MFG4_OUT2),
+	GPIO_FN(LCDD8), GPIO_FN(PORT200_KEYIN0), GPIO_FN(VIO_DR0),
+	GPIO_FN(D16),
+	GPIO_FN(LCDD9), GPIO_FN(PORT201_KEYIN1), GPIO_FN(VIO_DR1),
+	GPIO_FN(D17),
+	GPIO_FN(LCDD10), GPIO_FN(PORT202_KEYIN2), GPIO_FN(VIO_DR2),
+	GPIO_FN(D18),
+	GPIO_FN(LCDD11), GPIO_FN(PORT203_KEYIN3), GPIO_FN(VIO_DR3),
+	GPIO_FN(D19),
+	GPIO_FN(LCDD12), GPIO_FN(PORT204_KEYIN4), GPIO_FN(VIO_DR4),
+	GPIO_FN(D20),
+	GPIO_FN(LCDD13), GPIO_FN(PORT205_KEYIN5), GPIO_FN(VIO_DR5),
+	GPIO_FN(D21),
+	GPIO_FN(LCDD14), GPIO_FN(PORT206_KEYIN6), GPIO_FN(VIO_DR6),
+	GPIO_FN(D22),
+	GPIO_FN(LCDD15), GPIO_FN(PORT207_MSIOF0L_SS1), GPIO_FN(PORT207_KEYOUT0),
+	GPIO_FN(VIO_DR7), GPIO_FN(D23),
+	GPIO_FN(LCDD16), GPIO_FN(PORT208_MSIOF0L_SS2), GPIO_FN(PORT208_KEYOUT1),
+	GPIO_FN(VIO_VDR), GPIO_FN(D24),
+	GPIO_FN(LCDD17), GPIO_FN(PORT209_KEYOUT2), GPIO_FN(VIO_HDR),
+	GPIO_FN(D25),
+	GPIO_FN(LCDD18), GPIO_FN(DREQ2), GPIO_FN(PORT210_MSIOF0L_SS1),
+	GPIO_FN(D26),
+	GPIO_FN(LCDD19), GPIO_FN(PORT211_MSIOF0L_SS2), GPIO_FN(D27),
+	GPIO_FN(LCDD20), GPIO_FN(TS_SPSYNC1), GPIO_FN(MSIOF0L_MCK0),
+	GPIO_FN(D28),
+	GPIO_FN(LCDD21), GPIO_FN(TS_SDAT1), GPIO_FN(MSIOF0L_MCK1),
+	GPIO_FN(D29),
+	GPIO_FN(LCDD22), GPIO_FN(TS_SDEN1), GPIO_FN(MSIOF0L_RSCK),
+	GPIO_FN(D30),
+	GPIO_FN(LCDD23), GPIO_FN(TS_SCK1), GPIO_FN(MSIOF0L_RSYNC),
+	GPIO_FN(D31),
+	GPIO_FN(LCDDCK), GPIO_FN(LCDWR), GPIO_FN(PORT216_KEYOUT3),
+	GPIO_FN(VIO_CLKR),
+	GPIO_FN(LCDRD), GPIO_FN(DACK2), GPIO_FN(MSIOF0L_TSYNC),
+	GPIO_FN(LCDHSYN), GPIO_FN(LCDCS), GPIO_FN(LCDCS2), GPIO_FN(DACK3),
+	GPIO_FN(PORT218_VIO_CKOR), GPIO_FN(PORT218_KEYOUT4),
+	GPIO_FN(LCDDISP), GPIO_FN(LCDRS), GPIO_FN(DREQ3), GPIO_FN(MSIOF0L_TSCK),
+	GPIO_FN(LCDVSYN), GPIO_FN(LCDVSYN2), GPIO_FN(PORT220_KEYOUT5),
+	GPIO_FN(LCDLCLK), GPIO_FN(DREQ1), GPIO_FN(PWEN), GPIO_FN(MSIOF0L_RXD),
+	GPIO_FN(LCDDON), GPIO_FN(LCDDON2), GPIO_FN(DACK1), GPIO_FN(OVCN),
+	GPIO_FN(MSIOF0L_TXD),
+	GPIO_FN(SCIFA1_TXD), GPIO_FN(OVCN2),
+	GPIO_FN(EXTLP), GPIO_FN(SCIFA1_SCK), GPIO_FN(USBTERM),
+	GPIO_FN(PORT226_VIO_CKO2),
+	GPIO_FN(SCIFA1_RTS), GPIO_FN(IDIN),
+	GPIO_FN(SCIFA1_RXD),
+	GPIO_FN(SCIFA1_CTS), GPIO_FN(MFG1_IN1),
+	GPIO_FN(MSIOF1_TXD), GPIO_FN(SCIFA2_TXD2), GPIO_FN(PORT230_FSIAOMC),
+	GPIO_FN(MSIOF1_TSYNC), GPIO_FN(SCIFA2_CTS2), GPIO_FN(PORT231_FSIAOLR),
+	GPIO_FN(MSIOF1_TSCK), GPIO_FN(SCIFA2_SCK2), GPIO_FN(PORT232_FSIAOBT),
+	GPIO_FN(MSIOF1_RXD), GPIO_FN(SCIFA2_RXD2), GPIO_FN(GPS_VCOTRIG),
+	GPIO_FN(PORT233_FSIACK),
+	GPIO_FN(MSIOF1_RSCK), GPIO_FN(SCIFA2_RTS2), GPIO_FN(PORT234_FSIAOSLD),
+	GPIO_FN(MSIOF1_RSYNC), GPIO_FN(OPORT0), GPIO_FN(MFG1_IN2),
+	GPIO_FN(PORT235_FSIAILR),
+	GPIO_FN(MSIOF1_MCK0), GPIO_FN(I2C_SDA2), GPIO_FN(PORT236_FSIAIBT),
+	GPIO_FN(MSIOF1_MCK1), GPIO_FN(I2C_SCL2), GPIO_FN(PORT237_FSIAISLD),
+	GPIO_FN(MSIOF1_SS1), GPIO_FN(EDBGREQ3),
+
+	/* 55-5 (FN) */
+	GPIO_FN(MSIOF1_SS2),
+	GPIO_FN(SCIFA6_TXD),
+	GPIO_FN(PORT241_IRDA_OUT), GPIO_FN(PORT241_IROUT), GPIO_FN(MFG4_OUT1),
+	GPIO_FN(TPU4TO0),
+	GPIO_FN(PORT242_IRDA_IN), GPIO_FN(MFG4_IN2),
+	GPIO_FN(PORT243_IRDA_FIRSEL), GPIO_FN(PORT243_VIO_CKO2),
+	GPIO_FN(PORT244_SCIFA5_CTS), GPIO_FN(MFG2_IN1),
+	GPIO_FN(PORT244_SCIFB_CTS),
+	GPIO_FN(PORT245_SCIFA5_RTS), GPIO_FN(MFG2_IN2),
+	GPIO_FN(PORT245_SCIFB_RTS),
+	GPIO_FN(PORT246_SCIFA5_RXD), GPIO_FN(MFG1_OUT1),
+	GPIO_FN(PORT246_SCIFB_RXD), GPIO_FN(TPU1TO0),
+	GPIO_FN(PORT247_SCIFA5_TXD), GPIO_FN(MFG3_OUT2),
+	GPIO_FN(PORT247_SCIFB_TXD), GPIO_FN(TPU3TO1),
+	GPIO_FN(PORT248_SCIFA5_SCK), GPIO_FN(MFG2_OUT1),
+	GPIO_FN(PORT248_SCIFB_SCK), GPIO_FN(TPU2TO0),
+	GPIO_FN(PORT249_IROUT), GPIO_FN(MFG4_IN1),
+	GPIO_FN(SDHICLK0), GPIO_FN(TCK2_SWCLK_MC0),
+	GPIO_FN(SDHICD0),
+	GPIO_FN(SDHID0_0), GPIO_FN(TMS2_SWDIO_MC0),
+	GPIO_FN(SDHID0_1), GPIO_FN(TDO2_SWO0_MC0),
+	GPIO_FN(SDHID0_2), GPIO_FN(TDI2),
+	GPIO_FN(SDHID0_3), GPIO_FN(RTCK2_SWO1_MC0),
+	GPIO_FN(SDHICMD0), GPIO_FN(TRST2),
+	GPIO_FN(SDHIWP0), GPIO_FN(EDBGREQ2),
+	GPIO_FN(SDHICLK1), GPIO_FN(TCK3_SWCLK_MC1),
+	GPIO_FN(SDHID1_0), GPIO_FN(M11_SLCD_SO2), GPIO_FN(TS_SPSYNC2),
+	GPIO_FN(TMS3_SWDIO_MC1),
+	GPIO_FN(SDHID1_1), GPIO_FN(M9_SLCD_A02), GPIO_FN(TS_SDAT2),
+	GPIO_FN(TDO3_SWO0_MC1),
+	GPIO_FN(SDHID1_2), GPIO_FN(M10_SLCD_CK2), GPIO_FN(TS_SDEN2),
+	GPIO_FN(TDI3),
+	GPIO_FN(SDHID1_3), GPIO_FN(M12_SLCD_CE2), GPIO_FN(TS_SCK2),
+	GPIO_FN(RTCK3_SWO1_MC1),
+	GPIO_FN(SDHICMD1), GPIO_FN(TRST3),
+	GPIO_FN(RESETOUTS),
+};
+
+/* helper for top 4 bits in PORTnCR */
+#define PCRH(in, in_pd, in_pu, out)	\
+	0, (out), (in), 0,	\
+		0, 0, 0, 0,	\
+		0, 0, (in_pd), 0,	\
+		0, 0, (in_pu), 0
+
+#define PORTCR(nr, reg)	\
+	{ PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) {	\
+			PCRH(PORT##nr##_IN, PORT##nr##_IN_PD,	\
+				 PORT##nr##_IN_PU, PORT##nr##_OUT),	\
+				PORT##nr##_FN0, PORT##nr##_FN1,	\
+				PORT##nr##_FN2, PORT##nr##_FN3,	\
+				PORT##nr##_FN4, PORT##nr##_FN5,	\
+				PORT##nr##_FN6, PORT##nr##_FN7 }	\
+	}
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+	PORTCR(0, 0xe6050000), /* PORT0CR */
+	PORTCR(1, 0xe6050001), /* PORT1CR */
+	PORTCR(2, 0xe6050002), /* PORT2CR */
+	PORTCR(3, 0xe6050003), /* PORT3CR */
+	PORTCR(4, 0xe6050004), /* PORT4CR */
+	PORTCR(5, 0xe6050005), /* PORT5CR */
+	PORTCR(6, 0xe6050006), /* PORT6CR */
+	PORTCR(7, 0xe6050007), /* PORT7CR */
+	PORTCR(8, 0xe6050008), /* PORT8CR */
+	PORTCR(9, 0xe6050009), /* PORT9CR */
+
+	PORTCR(10, 0xe605000a), /* PORT10CR */
+	PORTCR(11, 0xe605000b), /* PORT11CR */
+	PORTCR(12, 0xe605000c), /* PORT12CR */
+	PORTCR(13, 0xe605000d), /* PORT13CR */
+	PORTCR(14, 0xe605000e), /* PORT14CR */
+	PORTCR(15, 0xe605000f), /* PORT15CR */
+	PORTCR(16, 0xe6050010), /* PORT16CR */
+	PORTCR(17, 0xe6050011), /* PORT17CR */
+	PORTCR(18, 0xe6050012), /* PORT18CR */
+	PORTCR(19, 0xe6050013), /* PORT19CR */
+
+	PORTCR(20, 0xe6050014), /* PORT20CR */
+	PORTCR(21, 0xe6050015), /* PORT21CR */
+	PORTCR(22, 0xe6050016), /* PORT22CR */
+	PORTCR(23, 0xe6050017), /* PORT23CR */
+	PORTCR(24, 0xe6050018), /* PORT24CR */
+	PORTCR(25, 0xe6050019), /* PORT25CR */
+	PORTCR(26, 0xe605001a), /* PORT26CR */
+	PORTCR(27, 0xe605001b), /* PORT27CR */
+	PORTCR(28, 0xe605001c), /* PORT28CR */
+	PORTCR(29, 0xe605001d), /* PORT29CR */
+
+	PORTCR(30, 0xe605001e), /* PORT30CR */
+	PORTCR(31, 0xe605001f), /* PORT31CR */
+	PORTCR(32, 0xe6050020), /* PORT32CR */
+	PORTCR(33, 0xe6050021), /* PORT33CR */
+	PORTCR(34, 0xe6050022), /* PORT34CR */
+	PORTCR(35, 0xe6050023), /* PORT35CR */
+	PORTCR(36, 0xe6050024), /* PORT36CR */
+	PORTCR(37, 0xe6050025), /* PORT37CR */
+	PORTCR(38, 0xe6050026), /* PORT38CR */
+	PORTCR(39, 0xe6050027), /* PORT39CR */
+
+	PORTCR(40, 0xe6050028), /* PORT40CR */
+	PORTCR(41, 0xe6050029), /* PORT41CR */
+	PORTCR(42, 0xe605002a), /* PORT42CR */
+	PORTCR(43, 0xe605002b), /* PORT43CR */
+	PORTCR(44, 0xe605002c), /* PORT44CR */
+	PORTCR(45, 0xe605002d), /* PORT45CR */
+	PORTCR(46, 0xe605002e), /* PORT46CR */
+	PORTCR(47, 0xe605002f), /* PORT47CR */
+	PORTCR(48, 0xe6050030), /* PORT48CR */
+	PORTCR(49, 0xe6050031), /* PORT49CR */
+
+	PORTCR(50, 0xe6050032), /* PORT50CR */
+	PORTCR(51, 0xe6050033), /* PORT51CR */
+	PORTCR(52, 0xe6050034), /* PORT52CR */
+	PORTCR(53, 0xe6050035), /* PORT53CR */
+	PORTCR(54, 0xe6050036), /* PORT54CR */
+	PORTCR(55, 0xe6050037), /* PORT55CR */
+	PORTCR(56, 0xe6050038), /* PORT56CR */
+	PORTCR(57, 0xe6050039), /* PORT57CR */
+	PORTCR(58, 0xe605003a), /* PORT58CR */
+	PORTCR(59, 0xe605003b), /* PORT59CR */
+
+	PORTCR(60, 0xe605003c), /* PORT60CR */
+	PORTCR(61, 0xe605003d), /* PORT61CR */
+	PORTCR(62, 0xe605003e), /* PORT62CR */
+	PORTCR(63, 0xe605003f), /* PORT63CR */
+	PORTCR(64, 0xe6050040), /* PORT64CR */
+	PORTCR(65, 0xe6050041), /* PORT65CR */
+	PORTCR(66, 0xe6050042), /* PORT66CR */
+	PORTCR(67, 0xe6050043), /* PORT67CR */
+	PORTCR(68, 0xe6050044), /* PORT68CR */
+	PORTCR(69, 0xe6050045), /* PORT69CR */
+
+	PORTCR(70, 0xe6050046), /* PORT70CR */
+	PORTCR(71, 0xe6050047), /* PORT71CR */
+	PORTCR(72, 0xe6050048), /* PORT72CR */
+	PORTCR(73, 0xe6050049), /* PORT73CR */
+	PORTCR(74, 0xe605004a), /* PORT74CR */
+	PORTCR(75, 0xe605004b), /* PORT75CR */
+	PORTCR(76, 0xe605004c), /* PORT76CR */
+	PORTCR(77, 0xe605004d), /* PORT77CR */
+	PORTCR(78, 0xe605004e), /* PORT78CR */
+	PORTCR(79, 0xe605004f), /* PORT79CR */
+
+	PORTCR(80, 0xe6050050), /* PORT80CR */
+	PORTCR(81, 0xe6050051), /* PORT81CR */
+	PORTCR(82, 0xe6050052), /* PORT82CR */
+	PORTCR(83, 0xe6050053), /* PORT83CR */
+	PORTCR(84, 0xe6050054), /* PORT84CR */
+	PORTCR(85, 0xe6050055), /* PORT85CR */
+	PORTCR(86, 0xe6050056), /* PORT86CR */
+	PORTCR(87, 0xe6050057), /* PORT87CR */
+	PORTCR(88, 0xe6050058), /* PORT88CR */
+	PORTCR(89, 0xe6050059), /* PORT89CR */
+
+	PORTCR(90, 0xe605005a), /* PORT90CR */
+	PORTCR(91, 0xe605005b), /* PORT91CR */
+	PORTCR(92, 0xe605005c), /* PORT92CR */
+	PORTCR(93, 0xe605005d), /* PORT93CR */
+	PORTCR(94, 0xe605005e), /* PORT94CR */
+	PORTCR(95, 0xe605005f), /* PORT95CR */
+	PORTCR(96, 0xe6050060), /* PORT96CR */
+	PORTCR(97, 0xe6050061), /* PORT97CR */
+	PORTCR(98, 0xe6050062), /* PORT98CR */
+	PORTCR(99, 0xe6050063), /* PORT99CR */
+
+	PORTCR(100, 0xe6050064), /* PORT100CR */
+	PORTCR(101, 0xe6050065), /* PORT101CR */
+	PORTCR(102, 0xe6050066), /* PORT102CR */
+	PORTCR(103, 0xe6050067), /* PORT103CR */
+	PORTCR(104, 0xe6050068), /* PORT104CR */
+	PORTCR(105, 0xe6050069), /* PORT105CR */
+	PORTCR(106, 0xe605006a), /* PORT106CR */
+	PORTCR(107, 0xe605006b), /* PORT107CR */
+	PORTCR(108, 0xe605006c), /* PORT108CR */
+	PORTCR(109, 0xe605006d), /* PORT109CR */
+
+	PORTCR(110, 0xe605006e), /* PORT110CR */
+	PORTCR(111, 0xe605006f), /* PORT111CR */
+	PORTCR(112, 0xe6050070), /* PORT112CR */
+	PORTCR(113, 0xe6050071), /* PORT113CR */
+	PORTCR(114, 0xe6050072), /* PORT114CR */
+	PORTCR(115, 0xe6050073), /* PORT115CR */
+	PORTCR(116, 0xe6050074), /* PORT116CR */
+	PORTCR(117, 0xe6050075), /* PORT117CR */
+	PORTCR(118, 0xe6050076), /* PORT118CR */
+
+	PORTCR(128, 0xe6051080), /* PORT128CR */
+	PORTCR(129, 0xe6051081), /* PORT129CR */
+
+	PORTCR(130, 0xe6051082), /* PORT130CR */
+	PORTCR(131, 0xe6051083), /* PORT131CR */
+	PORTCR(132, 0xe6051084), /* PORT132CR */
+	PORTCR(133, 0xe6051085), /* PORT133CR */
+	PORTCR(134, 0xe6051086), /* PORT134CR */
+	PORTCR(135, 0xe6051087), /* PORT135CR */
+	PORTCR(136, 0xe6051088), /* PORT136CR */
+	PORTCR(137, 0xe6051089), /* PORT137CR */
+	PORTCR(138, 0xe605108a), /* PORT138CR */
+	PORTCR(139, 0xe605108b), /* PORT139CR */
+
+	PORTCR(140, 0xe605108c), /* PORT140CR */
+	PORTCR(141, 0xe605108d), /* PORT141CR */
+	PORTCR(142, 0xe605108e), /* PORT142CR */
+	PORTCR(143, 0xe605108f), /* PORT143CR */
+	PORTCR(144, 0xe6051090), /* PORT144CR */
+	PORTCR(145, 0xe6051091), /* PORT145CR */
+	PORTCR(146, 0xe6051092), /* PORT146CR */
+	PORTCR(147, 0xe6051093), /* PORT147CR */
+	PORTCR(148, 0xe6051094), /* PORT148CR */
+	PORTCR(149, 0xe6051095), /* PORT149CR */
+
+	PORTCR(150, 0xe6051096), /* PORT150CR */
+	PORTCR(151, 0xe6051097), /* PORT151CR */
+	PORTCR(152, 0xe6051098), /* PORT152CR */
+	PORTCR(153, 0xe6051099), /* PORT153CR */
+	PORTCR(154, 0xe605109a), /* PORT154CR */
+	PORTCR(155, 0xe605109b), /* PORT155CR */
+	PORTCR(156, 0xe605109c), /* PORT156CR */
+	PORTCR(157, 0xe605109d), /* PORT157CR */
+	PORTCR(158, 0xe605109e), /* PORT158CR */
+	PORTCR(159, 0xe605109f), /* PORT159CR */
+
+	PORTCR(160, 0xe60510a0), /* PORT160CR */
+	PORTCR(161, 0xe60510a1), /* PORT161CR */
+	PORTCR(162, 0xe60510a2), /* PORT162CR */
+	PORTCR(163, 0xe60510a3), /* PORT163CR */
+	PORTCR(164, 0xe60510a4), /* PORT164CR */
+
+	PORTCR(192, 0xe60520c0), /* PORT192CR */
+	PORTCR(193, 0xe60520c1), /* PORT193CR */
+	PORTCR(194, 0xe60520c2), /* PORT194CR */
+	PORTCR(195, 0xe60520c3), /* PORT195CR */
+	PORTCR(196, 0xe60520c4), /* PORT196CR */
+	PORTCR(197, 0xe60520c5), /* PORT197CR */
+	PORTCR(198, 0xe60520c6), /* PORT198CR */
+	PORTCR(199, 0xe60520c7), /* PORT199CR */
+
+	PORTCR(200, 0xe60520c8), /* PORT200CR */
+	PORTCR(201, 0xe60520c9), /* PORT201CR */
+	PORTCR(202, 0xe60520ca), /* PORT202CR */
+	PORTCR(203, 0xe60520cb), /* PORT203CR */
+	PORTCR(204, 0xe60520cc), /* PORT204CR */
+	PORTCR(205, 0xe60520cd), /* PORT205CR */
+	PORTCR(206, 0xe60520ce), /* PORT206CR */
+	PORTCR(207, 0xe60520cf), /* PORT207CR */
+	PORTCR(208, 0xe60520d0), /* PORT208CR */
+	PORTCR(209, 0xe60520d1), /* PORT209CR */
+
+	PORTCR(210, 0xe60520d2), /* PORT210CR */
+	PORTCR(211, 0xe60520d3), /* PORT211CR */
+	PORTCR(212, 0xe60520d4), /* PORT212CR */
+	PORTCR(213, 0xe60520d5), /* PORT213CR */
+	PORTCR(214, 0xe60520d6), /* PORT214CR */
+	PORTCR(215, 0xe60520d7), /* PORT215CR */
+	PORTCR(216, 0xe60520d8), /* PORT216CR */
+	PORTCR(217, 0xe60520d9), /* PORT217CR */
+	PORTCR(218, 0xe60520da), /* PORT218CR */
+	PORTCR(219, 0xe60520db), /* PORT219CR */
+
+	PORTCR(220, 0xe60520dc), /* PORT220CR */
+	PORTCR(221, 0xe60520dd), /* PORT221CR */
+	PORTCR(222, 0xe60520de), /* PORT222CR */
+	PORTCR(223, 0xe60520df), /* PORT223CR */
+	PORTCR(224, 0xe60520e0), /* PORT224CR */
+	PORTCR(225, 0xe60520e1), /* PORT225CR */
+	PORTCR(226, 0xe60520e2), /* PORT226CR */
+	PORTCR(227, 0xe60520e3), /* PORT227CR */
+	PORTCR(228, 0xe60520e4), /* PORT228CR */
+	PORTCR(229, 0xe60520e5), /* PORT229CR */
+
+	PORTCR(230, 0xe60520e6), /* PORT230CR */
+	PORTCR(231, 0xe60520e7), /* PORT231CR */
+	PORTCR(232, 0xe60520e8), /* PORT232CR */
+	PORTCR(233, 0xe60520e9), /* PORT233CR */
+	PORTCR(234, 0xe60520ea), /* PORT234CR */
+	PORTCR(235, 0xe60520eb), /* PORT235CR */
+	PORTCR(236, 0xe60520ec), /* PORT236CR */
+	PORTCR(237, 0xe60520ed), /* PORT237CR */
+	PORTCR(238, 0xe60520ee), /* PORT238CR */
+	PORTCR(239, 0xe60520ef), /* PORT239CR */
+
+	PORTCR(240, 0xe60520f0), /* PORT240CR */
+	PORTCR(241, 0xe60520f1), /* PORT241CR */
+	PORTCR(242, 0xe60520f2), /* PORT242CR */
+	PORTCR(243, 0xe60520f3), /* PORT243CR */
+	PORTCR(244, 0xe60520f4), /* PORT244CR */
+	PORTCR(245, 0xe60520f5), /* PORT245CR */
+	PORTCR(246, 0xe60520f6), /* PORT246CR */
+	PORTCR(247, 0xe60520f7), /* PORT247CR */
+	PORTCR(248, 0xe60520f8), /* PORT248CR */
+	PORTCR(249, 0xe60520f9), /* PORT249CR */
+
+	PORTCR(250, 0xe60520fa), /* PORT250CR */
+	PORTCR(251, 0xe60520fb), /* PORT251CR */
+	PORTCR(252, 0xe60520fc), /* PORT252CR */
+	PORTCR(253, 0xe60520fd), /* PORT253CR */
+	PORTCR(254, 0xe60520fe), /* PORT254CR */
+	PORTCR(255, 0xe60520ff), /* PORT255CR */
+	PORTCR(256, 0xe6052100), /* PORT256CR */
+	PORTCR(257, 0xe6052101), /* PORT257CR */
+	PORTCR(258, 0xe6052102), /* PORT258CR */
+	PORTCR(259, 0xe6052103), /* PORT259CR */
+
+	PORTCR(260, 0xe6052104), /* PORT260CR */
+	PORTCR(261, 0xe6052105), /* PORT261CR */
+	PORTCR(262, 0xe6052106), /* PORT262CR */
+	PORTCR(263, 0xe6052107), /* PORT263CR */
+	PORTCR(264, 0xe6052108), /* PORT264CR */
+
+	{ PINMUX_CFG_REG("MSELBCR", 0xe6058024, 32, 1) {
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			MSELBCR_MSEL17_0, MSELBCR_MSEL17_1,
+			MSELBCR_MSEL16_0, MSELBCR_MSEL16_1,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+	},
+	{ },
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+	{ PINMUX_DATA_REG("PORTL031_000DR", 0xe6054000, 32) {
+			PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA,
+			PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA,
+			PORT23_DATA, PORT22_DATA, PORT21_DATA, PORT20_DATA,
+			PORT19_DATA, PORT18_DATA, PORT17_DATA, PORT16_DATA,
+			PORT15_DATA, PORT14_DATA, PORT13_DATA, PORT12_DATA,
+			PORT11_DATA, PORT10_DATA, PORT9_DATA, PORT8_DATA,
+			PORT7_DATA, PORT6_DATA, PORT5_DATA, PORT4_DATA,
+			PORT3_DATA, PORT2_DATA, PORT1_DATA, PORT0_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTL063_032DR", 0xe6054004, 32) {
+			PORT63_DATA, PORT62_DATA, PORT61_DATA, PORT60_DATA,
+			PORT59_DATA, PORT58_DATA, PORT57_DATA, PORT56_DATA,
+			PORT55_DATA, PORT54_DATA, PORT53_DATA, PORT52_DATA,
+			PORT51_DATA, PORT50_DATA, PORT49_DATA, PORT48_DATA,
+			PORT47_DATA, PORT46_DATA, PORT45_DATA, PORT44_DATA,
+			PORT43_DATA, PORT42_DATA, PORT41_DATA, PORT40_DATA,
+			PORT39_DATA, PORT38_DATA, PORT37_DATA, PORT36_DATA,
+			PORT35_DATA, PORT34_DATA, PORT33_DATA, PORT32_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTL095_064DR", 0xe6054008, 32) {
+			PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA,
+			PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA,
+			PORT87_DATA, PORT86_DATA, PORT85_DATA, PORT84_DATA,
+			PORT83_DATA, PORT82_DATA, PORT81_DATA, PORT80_DATA,
+			PORT79_DATA, PORT78_DATA, PORT77_DATA, PORT76_DATA,
+			PORT75_DATA, PORT74_DATA, PORT73_DATA, PORT72_DATA,
+			PORT71_DATA, PORT70_DATA, PORT69_DATA, PORT68_DATA,
+			PORT67_DATA, PORT66_DATA, PORT65_DATA, PORT64_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTD127_096DR", 0xe605400C, 32) {
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, PORT118_DATA, PORT117_DATA, PORT116_DATA,
+			PORT115_DATA, PORT114_DATA, PORT113_DATA, PORT112_DATA,
+			PORT111_DATA, PORT110_DATA, PORT109_DATA, PORT108_DATA,
+			PORT107_DATA, PORT106_DATA, PORT105_DATA, PORT104_DATA,
+			PORT103_DATA, PORT102_DATA, PORT101_DATA, PORT100_DATA,
+			PORT99_DATA, PORT98_DATA, PORT97_DATA, PORT96_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTD159_128DR", 0xe6055000, 32) {
+			PORT159_DATA, PORT158_DATA, PORT157_DATA, PORT156_DATA,
+			PORT155_DATA, PORT154_DATA, PORT153_DATA, PORT152_DATA,
+			PORT151_DATA, PORT150_DATA, PORT149_DATA, PORT148_DATA,
+			PORT147_DATA, PORT146_DATA, PORT145_DATA, PORT144_DATA,
+			PORT143_DATA, PORT142_DATA, PORT141_DATA, PORT140_DATA,
+			PORT139_DATA, PORT138_DATA, PORT137_DATA, PORT136_DATA,
+			PORT135_DATA, PORT134_DATA, PORT133_DATA, PORT132_DATA,
+			PORT131_DATA, PORT130_DATA, PORT129_DATA, PORT128_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTR191_160DR", 0xe6055004, 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, PORT164_DATA,
+			PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTR223_192DR", 0xe6056000, 32) {
+			PORT223_DATA, PORT222_DATA, PORT221_DATA, PORT220_DATA,
+			PORT219_DATA, PORT218_DATA, PORT217_DATA, PORT216_DATA,
+			PORT215_DATA, PORT214_DATA, PORT213_DATA, PORT212_DATA,
+			PORT211_DATA, PORT210_DATA, PORT209_DATA, PORT208_DATA,
+			PORT207_DATA, PORT206_DATA, PORT205_DATA, PORT204_DATA,
+			PORT203_DATA, PORT202_DATA, PORT201_DATA, PORT200_DATA,
+			PORT199_DATA, PORT198_DATA, PORT197_DATA, PORT196_DATA,
+			PORT195_DATA, PORT194_DATA, PORT193_DATA, PORT192_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTU255_224DR", 0xe6056004, 32) {
+			PORT255_DATA, PORT254_DATA, PORT253_DATA, PORT252_DATA,
+			PORT251_DATA, PORT250_DATA, PORT249_DATA, PORT248_DATA,
+			PORT247_DATA, PORT246_DATA, PORT245_DATA, PORT244_DATA,
+			PORT243_DATA, PORT242_DATA, PORT241_DATA, PORT240_DATA,
+			PORT239_DATA, PORT238_DATA, PORT237_DATA, PORT236_DATA,
+			PORT235_DATA, PORT234_DATA, PORT233_DATA, PORT232_DATA,
+			PORT231_DATA, PORT230_DATA, PORT229_DATA, PORT228_DATA,
+			PORT227_DATA, PORT226_DATA, PORT225_DATA, PORT224_DATA }
+	},
+	{ PINMUX_DATA_REG("PORTU287_256DR", 0xe6056008, 32) {
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, 0,
+			0, 0, 0, PORT264_DATA,
+			PORT263_DATA, PORT262_DATA, PORT261_DATA, PORT260_DATA,
+			PORT259_DATA, PORT258_DATA, PORT257_DATA, PORT256_DATA }
+	},
+	{ },
+};
+
+static struct pinmux_info sh7377_pinmux_info = {
+	.name = "sh7377_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 },
+	.input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_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_PORT0,
+	.last_gpio = GPIO_FN_RESETOUTS,
+
+	.gpios = pinmux_gpios,
+	.cfg_regs = pinmux_config_regs,
+	.data_regs = pinmux_data_regs,
+
+	.gpio_data = pinmux_data,
+	.gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+void sh7377_pinmux_init(void)
+{
+	register_pinmux(&sh7377_pinmux_info);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/setup-sh7367.c linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/setup-sh7367.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/setup-sh7367.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/setup-sh7367.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,198 @@
+/*
+ * sh7367 processor support
+ *
+ * Copyright (C) 2010  Magnus Damm
+ * Copyright (C) 2008  Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xe6c40000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 80, 80, 80, 80 },
+};
+
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xe6c50000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 81, 81, 81, 81 },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xe6c60000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 82, 82, 82, 82 },
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase	= 0xe6c70000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 83, 83, 83, 83 },
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
+	},
+};
+
+static struct plat_sci_port scif4_platform_data = {
+	.mapbase	= 0xe6c80000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 89, 89, 89, 89 },
+};
+
+static struct platform_device scif4_device = {
+	.name		= "sh-sci",
+	.id		= 4,
+	.dev		= {
+		.platform_data	= &scif4_platform_data,
+	},
+};
+
+static struct plat_sci_port scif5_platform_data = {
+	.mapbase	= 0xe6cb0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 90, 90, 90, 90 },
+};
+
+static struct platform_device scif5_device = {
+	.name		= "sh-sci",
+	.id		= 5,
+	.dev		= {
+		.platform_data	= &scif5_platform_data,
+	},
+};
+
+static struct plat_sci_port scif6_platform_data = {
+	.mapbase	= 0xe6c30000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 91, 91, 91, 91 },
+};
+
+static struct platform_device scif6_device = {
+	.name		= "sh-sci",
+	.id		= 6,
+	.dev		= {
+		.platform_data	= &scif6_platform_data,
+	},
+};
+
+static struct sh_timer_config cmt10_platform_data = {
+	.name = "CMT10",
+	.channel_offset = 0x10,
+	.timer_bit = 0,
+	.clk = "r_clk",
+	.clockevent_rating = 125,
+	.clocksource_rating = 125,
+};
+
+static struct resource cmt10_resources[] = {
+	[0] = {
+		.name	= "CMT10",
+		.start	= 0xe6138010,
+		.end	= 0xe613801b,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 72,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device cmt10_device = {
+	.name		= "sh_cmt",
+	.id		= 10,
+	.dev = {
+		.platform_data	= &cmt10_platform_data,
+	},
+	.resource	= cmt10_resources,
+	.num_resources	= ARRAY_SIZE(cmt10_resources),
+};
+
+static struct platform_device *sh7367_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
+	&scif6_device,
+	&cmt10_device,
+};
+
+void __init sh7367_add_standard_devices(void)
+{
+	platform_add_devices(sh7367_early_devices,
+			     ARRAY_SIZE(sh7367_early_devices));
+}
+
+#define SYMSTPCR2 0xe6158048
+#define SYMSTPCR2_CMT1 (1 << 29)
+
+void __init sh7367_add_early_devices(void)
+{
+	/* enable clock to CMT1 */
+	__raw_writel(__raw_readl(SYMSTPCR2) & ~SYMSTPCR2_CMT1, SYMSTPCR2);
+
+	early_platform_add_devices(sh7367_early_devices,
+				   ARRAY_SIZE(sh7367_early_devices));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/setup-sh7372.c linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/setup-sh7372.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/setup-sh7372.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/setup-sh7372.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,199 @@
+/*
+ * sh7372 processor support
+ *
+ * Copyright (C) 2010  Magnus Damm
+ * Copyright (C) 2008  Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_intc.h>
+#include <linux/sh_timer.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xe6c40000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 80, 80, 80, 80 },
+};
+
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xe6c50000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 81, 81, 81, 81 },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xe6c60000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 82, 82, 82, 82 },
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase	= 0xe6c70000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 83, 83, 83, 83 },
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
+	},
+};
+
+static struct plat_sci_port scif4_platform_data = {
+	.mapbase	= 0xe6c80000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 89, 89, 89, 89 },
+};
+
+static struct platform_device scif4_device = {
+	.name		= "sh-sci",
+	.id		= 4,
+	.dev		= {
+		.platform_data	= &scif4_platform_data,
+	},
+};
+
+static struct plat_sci_port scif5_platform_data = {
+	.mapbase	= 0xe6cb0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 90, 90, 90, 90 },
+};
+
+static struct platform_device scif5_device = {
+	.name		= "sh-sci",
+	.id		= 5,
+	.dev		= {
+		.platform_data	= &scif5_platform_data,
+	},
+};
+
+static struct plat_sci_port scif6_platform_data = {
+	.mapbase	= 0xe6c30000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 91, 91, 91, 91 },
+};
+
+static struct platform_device scif6_device = {
+	.name		= "sh-sci",
+	.id		= 6,
+	.dev		= {
+		.platform_data	= &scif6_platform_data,
+	},
+};
+
+static struct sh_timer_config cmt10_platform_data = {
+	.name = "CMT10",
+	.channel_offset = 0x10,
+	.timer_bit = 0,
+	.clk = "r_clk",
+	.clockevent_rating = 125,
+	.clocksource_rating = 125,
+};
+
+static struct resource cmt10_resources[] = {
+	[0] = {
+		.name	= "CMT10",
+		.start	= 0xe6138010,
+		.end	= 0xe613801b,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 72,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device cmt10_device = {
+	.name		= "sh_cmt",
+	.id		= 10,
+	.dev = {
+		.platform_data	= &cmt10_platform_data,
+	},
+	.resource	= cmt10_resources,
+	.num_resources	= ARRAY_SIZE(cmt10_resources),
+};
+
+static struct platform_device *sh7372_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
+	&scif6_device,
+	&cmt10_device,
+};
+
+void __init sh7372_add_standard_devices(void)
+{
+	platform_add_devices(sh7372_early_devices,
+			    ARRAY_SIZE(sh7372_early_devices));
+}
+
+#define SMSTPCR3 0xe615013c
+#define SMSTPCR3_CMT1 (1 << 29)
+
+void __init sh7372_add_early_devices(void)
+{
+	/* enable clock to CMT1 */
+	__raw_writel(__raw_readl(SMSTPCR3) & ~SMSTPCR3_CMT1, SMSTPCR3);
+
+	early_platform_add_devices(sh7372_early_devices,
+				   ARRAY_SIZE(sh7372_early_devices));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/setup-sh7377.c linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/setup-sh7377.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/setup-sh7377.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/setup-sh7377.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,215 @@
+/*
+ * sh7377 processor support
+ *
+ * Copyright (C) 2010  Magnus Damm
+ * Copyright (C) 2008  Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_intc.h>
+#include <linux/sh_timer.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xe6c40000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 80, 80, 80, 80 },
+};
+
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xe6c50000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 81, 81, 81, 81 },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xe6c60000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 82, 82, 82, 82 },
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase	= 0xe6c70000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 83, 83, 83, 83 },
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
+	},
+};
+
+static struct plat_sci_port scif4_platform_data = {
+	.mapbase	= 0xe6c80000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 89, 89, 89, 89 },
+};
+
+static struct platform_device scif4_device = {
+	.name		= "sh-sci",
+	.id		= 4,
+	.dev		= {
+		.platform_data	= &scif4_platform_data,
+	},
+};
+
+static struct plat_sci_port scif5_platform_data = {
+	.mapbase	= 0xe6cb0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 90, 90, 90, 90 },
+};
+
+static struct platform_device scif5_device = {
+	.name		= "sh-sci",
+	.id		= 5,
+	.dev		= {
+		.platform_data	= &scif5_platform_data,
+	},
+};
+
+static struct plat_sci_port scif6_platform_data = {
+	.mapbase	= 0xe6cc0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 196, 196, 196, 196 },
+};
+
+static struct platform_device scif6_device = {
+	.name		= "sh-sci",
+	.id		= 6,
+	.dev		= {
+		.platform_data	= &scif6_platform_data,
+	},
+};
+
+static struct plat_sci_port scif7_platform_data = {
+	.mapbase	= 0xe6c30000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 91, 91, 91, 91 },
+};
+
+static struct platform_device scif7_device = {
+	.name		= "sh-sci",
+	.id		= 7,
+	.dev		= {
+		.platform_data	= &scif7_platform_data,
+	},
+};
+
+static struct sh_timer_config cmt10_platform_data = {
+	.name = "CMT10",
+	.channel_offset = 0x10,
+	.timer_bit = 0,
+	.clk = "r_clk",
+	.clockevent_rating = 125,
+	.clocksource_rating = 125,
+};
+
+static struct resource cmt10_resources[] = {
+	[0] = {
+		.name	= "CMT10",
+		.start	= 0xe6138010,
+		.end	= 0xe613801b,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 72,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device cmt10_device = {
+	.name		= "sh_cmt",
+	.id		= 10,
+	.dev = {
+		.platform_data	= &cmt10_platform_data,
+	},
+	.resource	= cmt10_resources,
+	.num_resources	= ARRAY_SIZE(cmt10_resources),
+};
+
+static struct platform_device *sh7377_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
+	&scif6_device,
+	&scif7_device,
+	&cmt10_device,
+};
+
+void __init sh7377_add_standard_devices(void)
+{
+	platform_add_devices(sh7377_early_devices,
+			    ARRAY_SIZE(sh7377_early_devices));
+}
+
+#define SMSTPCR3 0xe615013c
+#define SMSTPCR3_CMT1 (1 << 29)
+
+void __init sh7377_add_early_devices(void)
+{
+	/* enable clock to CMT1 */
+	__raw_writel(__raw_readl(SMSTPCR3) & ~SMSTPCR3_CMT1, SMSTPCR3);
+
+	early_platform_add_devices(sh7377_early_devices,
+				   ARRAY_SIZE(sh7377_early_devices));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/timer.c linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/timer.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-shmobile/timer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-shmobile/timer.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,46 @@
+/*
+ * SH-Mobile Timer
+ *
+ * Copyright (C) 2010  Magnus Damm
+ * Copyright (C) 2002 - 2009  Paul Mundt
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+#include <linux/platform_device.h>
+#include <asm/mach/time.h>
+
+static void __init shmobile_late_time_init(void)
+{
+	/*
+	 * Make sure all compiled-in early timers register themselves.
+	 *
+	 * Run probe() for two "earlytimer" devices, these will be the
+	 * clockevents and clocksource devices respectively. In the event
+	 * that only a clockevents device is available, we -ENODEV on the
+	 * clocksource and the jiffies clocksource is used transparently
+	 * instead. No error handling is necessary here.
+	 */
+	early_platform_driver_register_all("earlytimer");
+	early_platform_driver_probe("earlytimer", 2, 0);
+}
+
+static void __init shmobile_timer_init(void)
+{
+	late_time_init = shmobile_late_time_init;
+}
+
+struct sys_timer shmobile_timer = {
+	.init		= shmobile_timer_init,
+};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-u300/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-u300/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-u300/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-u300/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -610,34 +610,34 @@ EXPORT_SYMBOL(clk_get_rate);
 
 static unsigned long clk_round_rate_mclk(struct clk *clk, unsigned long rate)
 {
-	if (rate >= 18900000)
+	if (rate <= 18900000)
 		return 18900000;
-	if (rate >= 20800000)
+	if (rate <= 20800000)
 		return 20800000;
-	if (rate >= 23100000)
+	if (rate <= 23100000)
 		return 23100000;
-	if (rate >= 26000000)
+	if (rate <= 26000000)
 		return 26000000;
-	if (rate >= 29700000)
+	if (rate <= 29700000)
 		return 29700000;
-	if (rate >= 34700000)
+	if (rate <= 34700000)
 		return 34700000;
-	if (rate >= 41600000)
+	if (rate <= 41600000)
 		return 41600000;
-	if (rate >= 52000000)
+	if (rate <= 52000000)
 		return 52000000;
 	return -EINVAL;
 }
 
 static unsigned long clk_round_rate_cpuclk(struct clk *clk, unsigned long rate)
 {
-	if (rate >= 13000000)
+	if (rate <= 13000000)
 		return 13000000;
-	if (rate >= 52000000)
+	if (rate <= 52000000)
 		return 52000000;
-	if (rate >= 104000000)
+	if (rate <= 104000000)
 		return 104000000;
-	if (rate >= 208000000)
+	if (rate <= 208000000)
 		return 208000000;
 	return -EINVAL;
 }
@@ -1276,11 +1276,8 @@ static struct clk_lookup lookups[] = {
 
 static void __init clk_register(void)
 {
-	int i;
-
 	/* Register the lookups */
-	for (i = 0; i < ARRAY_SIZE(lookups); i++)
-		clkdev_add(&lookups[i]);
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 }
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-u300/core.c linux-libre-2.6.34-gnu1/arch/arm/mach-u300/core.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-u300/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-u300/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,7 @@
  * arch/arm/mach-u300/core.c
  *
  *
- * Copyright (C) 2007-2009 ST-Ericsson AB
+ * Copyright (C) 2007-2010 ST-Ericsson AB
  * License terms: GNU General Public License (GPL) version 2
  * Core platform support, IRQ handling and device definitions.
  * Author: Linus Walleij <linus.walleij@stericsson.com>
@@ -19,6 +19,7 @@
 #include <linux/amba/bus.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <mach/coh901318.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -29,6 +30,7 @@
 
 #include <mach/hardware.h>
 #include <mach/syscon.h>
+#include <mach/dma_channels.h>
 
 #include "clock.h"
 #include "mmc.h"
@@ -356,7 +358,7 @@ static struct resource ave_resources[] =
 	/*
 	 * The AVE3e requires two regions of 256MB that it considers
 	 * "invisible". The hardware will not be able to access these
-	 * adresses, so they should never point to system RAM.
+	 * addresses, so they should never point to system RAM.
 	 */
 	{
 		.name  = "AVE3e Reserved 0",
@@ -372,8 +374,1019 @@ static struct resource ave_resources[] =
 	},
 };
 
+static struct resource dma_resource[] = {
+	{
+		.start = U300_DMAC_BASE,
+		.end = U300_DMAC_BASE + PAGE_SIZE - 1,
+		.flags =  IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_U300_DMA,
+		.end = IRQ_U300_DMA,
+		.flags =  IORESOURCE_IRQ,
+	}
+};
+
+#ifdef CONFIG_MACH_U300_BS335
+/* points out all dma slave channels.
+ * Syntax is [A1, B1, A2, B2, .... ,-1,-1]
+ * Select all channels from A to B, end of list is marked with -1,-1
+ */
+static int dma_slave_channels[] = {
+	U300_DMA_MSL_TX_0, U300_DMA_SPI_RX,
+	U300_DMA_UART1_TX, U300_DMA_UART1_RX, -1, -1};
+
+/* points out all dma memcpy channels. */
+static int dma_memcpy_channels[] = {
+	U300_DMA_GENERAL_PURPOSE_0, U300_DMA_GENERAL_PURPOSE_8, -1, -1};
+
+#else /* CONFIG_MACH_U300_BS335 */
+
+static int dma_slave_channels[] = {U300_DMA_MSL_TX_0, U300_DMA_SPI_RX, -1, -1};
+static int dma_memcpy_channels[] = {
+	U300_DMA_GENERAL_PURPOSE_0, U300_DMA_GENERAL_PURPOSE_10, -1, -1};
+
+#endif
+
+/** register dma for memory access
+ *
+ * active  1 means dma intends to access memory
+ *         0 means dma wont access memory
+ */
+static void coh901318_access_memory_state(struct device *dev, bool active)
+{
+}
+
+#define flags_memcpy_config (COH901318_CX_CFG_CH_DISABLE | \
+			COH901318_CX_CFG_RM_MEMORY_TO_MEMORY | \
+			COH901318_CX_CFG_LCR_DISABLE | \
+			COH901318_CX_CFG_TC_IRQ_ENABLE | \
+			COH901318_CX_CFG_BE_IRQ_ENABLE)
+#define flags_memcpy_lli_chained (COH901318_CX_CTRL_TC_ENABLE | \
+			COH901318_CX_CTRL_BURST_COUNT_32_BYTES | \
+			COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | \
+			COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | \
+			COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | \
+			COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | \
+			COH901318_CX_CTRL_MASTER_MODE_M1RW | \
+			COH901318_CX_CTRL_TCP_DISABLE | \
+			COH901318_CX_CTRL_TC_IRQ_DISABLE | \
+			COH901318_CX_CTRL_HSP_DISABLE | \
+			COH901318_CX_CTRL_HSS_DISABLE | \
+			COH901318_CX_CTRL_DDMA_LEGACY | \
+			COH901318_CX_CTRL_PRDD_SOURCE)
+#define flags_memcpy_lli (COH901318_CX_CTRL_TC_ENABLE | \
+			COH901318_CX_CTRL_BURST_COUNT_32_BYTES | \
+			COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | \
+			COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | \
+			COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | \
+			COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | \
+			COH901318_CX_CTRL_MASTER_MODE_M1RW | \
+			COH901318_CX_CTRL_TCP_DISABLE | \
+			COH901318_CX_CTRL_TC_IRQ_DISABLE | \
+			COH901318_CX_CTRL_HSP_DISABLE | \
+			COH901318_CX_CTRL_HSS_DISABLE | \
+			COH901318_CX_CTRL_DDMA_LEGACY | \
+			COH901318_CX_CTRL_PRDD_SOURCE)
+#define flags_memcpy_lli_last (COH901318_CX_CTRL_TC_ENABLE | \
+			COH901318_CX_CTRL_BURST_COUNT_32_BYTES | \
+			COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | \
+			COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | \
+			COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | \
+			COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | \
+			COH901318_CX_CTRL_MASTER_MODE_M1RW | \
+			COH901318_CX_CTRL_TCP_DISABLE | \
+			COH901318_CX_CTRL_TC_IRQ_ENABLE | \
+			COH901318_CX_CTRL_HSP_DISABLE | \
+			COH901318_CX_CTRL_HSS_DISABLE | \
+			COH901318_CX_CTRL_DDMA_LEGACY | \
+			COH901318_CX_CTRL_PRDD_SOURCE)
+
+const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = {
+	{
+		.number = U300_DMA_MSL_TX_0,
+		.name = "MSL TX 0",
+		.priority_high = 0,
+		.dev_addr = U300_MSL_BASE + 0 * 0x40 + 0x20,
+	},
+	{
+		.number = U300_DMA_MSL_TX_1,
+		.name = "MSL TX 1",
+		.priority_high = 0,
+		.dev_addr = U300_MSL_BASE + 1 * 0x40 + 0x20,
+		.param.config = COH901318_CX_CFG_CH_DISABLE |
+				COH901318_CX_CFG_LCR_DISABLE |
+				COH901318_CX_CFG_TC_IRQ_ENABLE |
+				COH901318_CX_CFG_BE_IRQ_ENABLE,
+		.param.ctrl_lli_chained = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+		.param.ctrl_lli = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+		.param.ctrl_lli_last = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+	},
+	{
+		.number = U300_DMA_MSL_TX_2,
+		.name = "MSL TX 2",
+		.priority_high = 0,
+		.dev_addr = U300_MSL_BASE + 2 * 0x40 + 0x20,
+		.param.config = COH901318_CX_CFG_CH_DISABLE |
+				COH901318_CX_CFG_LCR_DISABLE |
+				COH901318_CX_CFG_TC_IRQ_ENABLE |
+				COH901318_CX_CFG_BE_IRQ_ENABLE,
+		.param.ctrl_lli_chained = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+		.param.ctrl_lli = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+		.param.ctrl_lli_last = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+		.desc_nbr_max = 10,
+	},
+	{
+		.number = U300_DMA_MSL_TX_3,
+		.name = "MSL TX 3",
+		.priority_high = 0,
+		.dev_addr = U300_MSL_BASE + 3 * 0x40 + 0x20,
+		.param.config = COH901318_CX_CFG_CH_DISABLE |
+				COH901318_CX_CFG_LCR_DISABLE |
+				COH901318_CX_CFG_TC_IRQ_ENABLE |
+				COH901318_CX_CFG_BE_IRQ_ENABLE,
+		.param.ctrl_lli_chained = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+		.param.ctrl_lli = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+		.param.ctrl_lli_last = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+	},
+	{
+		.number = U300_DMA_MSL_TX_4,
+		.name = "MSL TX 4",
+		.priority_high = 0,
+		.dev_addr = U300_MSL_BASE + 4 * 0x40 + 0x20,
+		.param.config = COH901318_CX_CFG_CH_DISABLE |
+				COH901318_CX_CFG_LCR_DISABLE |
+				COH901318_CX_CFG_TC_IRQ_ENABLE |
+				COH901318_CX_CFG_BE_IRQ_ENABLE,
+		.param.ctrl_lli_chained = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+		.param.ctrl_lli = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+		.param.ctrl_lli_last = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+	},
+	{
+		.number = U300_DMA_MSL_TX_5,
+		.name = "MSL TX 5",
+		.priority_high = 0,
+		.dev_addr = U300_MSL_BASE + 5 * 0x40 + 0x20,
+	},
+	{
+		.number = U300_DMA_MSL_TX_6,
+		.name = "MSL TX 6",
+		.priority_high = 0,
+		.dev_addr = U300_MSL_BASE + 6 * 0x40 + 0x20,
+	},
+	{
+		.number = U300_DMA_MSL_RX_0,
+		.name = "MSL RX 0",
+		.priority_high = 0,
+		.dev_addr = U300_MSL_BASE + 0 * 0x40 + 0x220,
+	},
+	{
+		.number = U300_DMA_MSL_RX_1,
+		.name = "MSL RX 1",
+		.priority_high = 0,
+		.dev_addr = U300_MSL_BASE + 1 * 0x40 + 0x220,
+		.param.config = COH901318_CX_CFG_CH_DISABLE |
+				COH901318_CX_CFG_LCR_DISABLE |
+				COH901318_CX_CFG_TC_IRQ_ENABLE |
+				COH901318_CX_CFG_BE_IRQ_ENABLE,
+		.param.ctrl_lli_chained = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+				COH901318_CX_CTRL_PRDD_DEST,
+		.param.ctrl_lli = 0,
+		.param.ctrl_lli_last = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+				COH901318_CX_CTRL_PRDD_DEST,
+	},
+	{
+		.number = U300_DMA_MSL_RX_2,
+		.name = "MSL RX 2",
+		.priority_high = 0,
+		.dev_addr = U300_MSL_BASE + 2 * 0x40 + 0x220,
+		.param.config = COH901318_CX_CFG_CH_DISABLE |
+				COH901318_CX_CFG_LCR_DISABLE |
+				COH901318_CX_CFG_TC_IRQ_ENABLE |
+				COH901318_CX_CFG_BE_IRQ_ENABLE,
+		.param.ctrl_lli_chained = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+				COH901318_CX_CTRL_PRDD_DEST,
+		.param.ctrl_lli = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+				COH901318_CX_CTRL_PRDD_DEST,
+		.param.ctrl_lli_last = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+				COH901318_CX_CTRL_PRDD_DEST,
+	},
+	{
+		.number = U300_DMA_MSL_RX_3,
+		.name = "MSL RX 3",
+		.priority_high = 0,
+		.dev_addr = U300_MSL_BASE + 3 * 0x40 + 0x220,
+		.param.config = COH901318_CX_CFG_CH_DISABLE |
+				COH901318_CX_CFG_LCR_DISABLE |
+				COH901318_CX_CFG_TC_IRQ_ENABLE |
+				COH901318_CX_CFG_BE_IRQ_ENABLE,
+		.param.ctrl_lli_chained = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+				COH901318_CX_CTRL_PRDD_DEST,
+		.param.ctrl_lli = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+				COH901318_CX_CTRL_PRDD_DEST,
+		.param.ctrl_lli_last = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+				COH901318_CX_CTRL_PRDD_DEST,
+	},
+	{
+		.number = U300_DMA_MSL_RX_4,
+		.name = "MSL RX 4",
+		.priority_high = 0,
+		.dev_addr = U300_MSL_BASE + 4 * 0x40 + 0x220,
+		.param.config = COH901318_CX_CFG_CH_DISABLE |
+				COH901318_CX_CFG_LCR_DISABLE |
+				COH901318_CX_CFG_TC_IRQ_ENABLE |
+				COH901318_CX_CFG_BE_IRQ_ENABLE,
+		.param.ctrl_lli_chained = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+				COH901318_CX_CTRL_PRDD_DEST,
+		.param.ctrl_lli = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+				COH901318_CX_CTRL_PRDD_DEST,
+		.param.ctrl_lli_last = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+				COH901318_CX_CTRL_PRDD_DEST,
+	},
+	{
+		.number = U300_DMA_MSL_RX_5,
+		.name = "MSL RX 5",
+		.priority_high = 0,
+		.dev_addr = U300_MSL_BASE + 5 * 0x40 + 0x220,
+		.param.config = COH901318_CX_CFG_CH_DISABLE |
+				COH901318_CX_CFG_LCR_DISABLE |
+				COH901318_CX_CFG_TC_IRQ_ENABLE |
+				COH901318_CX_CFG_BE_IRQ_ENABLE,
+		.param.ctrl_lli_chained = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+				COH901318_CX_CTRL_PRDD_DEST,
+		.param.ctrl_lli = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+				COH901318_CX_CTRL_PRDD_DEST,
+		.param.ctrl_lli_last = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+				COH901318_CX_CTRL_PRDD_DEST,
+	},
+	{
+		.number = U300_DMA_MSL_RX_6,
+		.name = "MSL RX 6",
+		.priority_high = 0,
+		.dev_addr = U300_MSL_BASE + 6 * 0x40 + 0x220,
+	},
+	{
+		.number = U300_DMA_MMCSD_RX_TX,
+		.name = "MMCSD RX TX",
+		.priority_high = 0,
+		.dev_addr =  U300_MMCSD_BASE + 0x080,
+		.param.config = COH901318_CX_CFG_CH_DISABLE |
+				COH901318_CX_CFG_LCR_DISABLE |
+				COH901318_CX_CFG_TC_IRQ_ENABLE |
+				COH901318_CX_CFG_BE_IRQ_ENABLE,
+		.param.ctrl_lli_chained = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_MASTER_MODE_M1RW |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY,
+		.param.ctrl_lli = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_MASTER_MODE_M1RW |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY,
+		.param.ctrl_lli_last = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_MASTER_MODE_M1RW |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY,
+
+	},
+	{
+		.number = U300_DMA_MSPRO_TX,
+		.name = "MSPRO TX",
+		.priority_high = 0,
+	},
+	{
+		.number = U300_DMA_MSPRO_RX,
+		.name = "MSPRO RX",
+		.priority_high = 0,
+	},
+	{
+		.number = U300_DMA_UART0_TX,
+		.name = "UART0 TX",
+		.priority_high = 0,
+	},
+	{
+		.number = U300_DMA_UART0_RX,
+		.name = "UART0 RX",
+		.priority_high = 0,
+	},
+	{
+		.number = U300_DMA_APEX_TX,
+		.name = "APEX TX",
+		.priority_high = 0,
+	},
+	{
+		.number = U300_DMA_APEX_RX,
+		.name = "APEX RX",
+		.priority_high = 0,
+	},
+	{
+		.number = U300_DMA_PCM_I2S0_TX,
+		.name = "PCM I2S0 TX",
+		.priority_high = 1,
+		.dev_addr = U300_PCM_I2S0_BASE + 0x14,
+		.param.config = COH901318_CX_CFG_CH_DISABLE |
+				COH901318_CX_CFG_LCR_DISABLE |
+				COH901318_CX_CFG_TC_IRQ_ENABLE |
+				COH901318_CX_CFG_BE_IRQ_ENABLE,
+		.param.ctrl_lli_chained = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1RW |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+		.param.ctrl_lli = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1RW |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+		.param.ctrl_lli_last = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1RW |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+	},
+	{
+		.number = U300_DMA_PCM_I2S0_RX,
+		.name = "PCM I2S0 RX",
+		.priority_high = 1,
+		.dev_addr = U300_PCM_I2S0_BASE + 0x10,
+		.param.config = COH901318_CX_CFG_CH_DISABLE |
+				COH901318_CX_CFG_LCR_DISABLE |
+				COH901318_CX_CFG_TC_IRQ_ENABLE |
+				COH901318_CX_CFG_BE_IRQ_ENABLE,
+		.param.ctrl_lli_chained = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1RW |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_DEST,
+		.param.ctrl_lli = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1RW |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_DEST,
+		.param.ctrl_lli_last = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1RW |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_DEST,
+	},
+	{
+		.number = U300_DMA_PCM_I2S1_TX,
+		.name = "PCM I2S1 TX",
+		.priority_high = 1,
+		.dev_addr =  U300_PCM_I2S1_BASE + 0x14,
+		.param.config = COH901318_CX_CFG_CH_DISABLE |
+				COH901318_CX_CFG_LCR_DISABLE |
+				COH901318_CX_CFG_TC_IRQ_ENABLE |
+				COH901318_CX_CFG_BE_IRQ_ENABLE,
+		.param.ctrl_lli_chained = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1RW |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+		.param.ctrl_lli = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1RW |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+		.param.ctrl_lli_last = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1RW |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_SOURCE,
+	},
+	{
+		.number = U300_DMA_PCM_I2S1_RX,
+		.name = "PCM I2S1 RX",
+		.priority_high = 1,
+		.dev_addr = U300_PCM_I2S1_BASE + 0x10,
+		.param.config = COH901318_CX_CFG_CH_DISABLE |
+				COH901318_CX_CFG_LCR_DISABLE |
+				COH901318_CX_CFG_TC_IRQ_ENABLE |
+				COH901318_CX_CFG_BE_IRQ_ENABLE,
+		.param.ctrl_lli_chained = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1RW |
+				COH901318_CX_CTRL_TCP_DISABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_DEST,
+		.param.ctrl_lli = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1RW |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_DISABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_DEST,
+		.param.ctrl_lli_last = 0 |
+				COH901318_CX_CTRL_TC_ENABLE |
+				COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+				COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+				COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+				COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+				COH901318_CX_CTRL_MASTER_MODE_M1RW |
+				COH901318_CX_CTRL_TCP_ENABLE |
+				COH901318_CX_CTRL_TC_IRQ_ENABLE |
+				COH901318_CX_CTRL_HSP_ENABLE |
+				COH901318_CX_CTRL_HSS_DISABLE |
+				COH901318_CX_CTRL_DDMA_LEGACY |
+				COH901318_CX_CTRL_PRDD_DEST,
+	},
+	{
+		.number = U300_DMA_XGAM_CDI,
+		.name = "XGAM CDI",
+		.priority_high = 0,
+	},
+	{
+		.number = U300_DMA_XGAM_PDI,
+		.name = "XGAM PDI",
+		.priority_high = 0,
+	},
+	{
+		.number = U300_DMA_SPI_TX,
+		.name = "SPI TX",
+		.priority_high = 0,
+	},
+	{
+		.number = U300_DMA_SPI_RX,
+		.name = "SPI RX",
+		.priority_high = 0,
+	},
+	{
+		.number = U300_DMA_GENERAL_PURPOSE_0,
+		.name = "GENERAL 00",
+		.priority_high = 0,
+
+		.param.config = flags_memcpy_config,
+		.param.ctrl_lli_chained = flags_memcpy_lli_chained,
+		.param.ctrl_lli = flags_memcpy_lli,
+		.param.ctrl_lli_last = flags_memcpy_lli_last,
+	},
+	{
+		.number = U300_DMA_GENERAL_PURPOSE_1,
+		.name = "GENERAL 01",
+		.priority_high = 0,
+
+		.param.config = flags_memcpy_config,
+		.param.ctrl_lli_chained = flags_memcpy_lli_chained,
+		.param.ctrl_lli = flags_memcpy_lli,
+		.param.ctrl_lli_last = flags_memcpy_lli_last,
+	},
+	{
+		.number = U300_DMA_GENERAL_PURPOSE_2,
+		.name = "GENERAL 02",
+		.priority_high = 0,
+
+		.param.config = flags_memcpy_config,
+		.param.ctrl_lli_chained = flags_memcpy_lli_chained,
+		.param.ctrl_lli = flags_memcpy_lli,
+		.param.ctrl_lli_last = flags_memcpy_lli_last,
+	},
+	{
+		.number = U300_DMA_GENERAL_PURPOSE_3,
+		.name = "GENERAL 03",
+		.priority_high = 0,
+
+		.param.config = flags_memcpy_config,
+		.param.ctrl_lli_chained = flags_memcpy_lli_chained,
+		.param.ctrl_lli = flags_memcpy_lli,
+		.param.ctrl_lli_last = flags_memcpy_lli_last,
+	},
+	{
+		.number = U300_DMA_GENERAL_PURPOSE_4,
+		.name = "GENERAL 04",
+		.priority_high = 0,
+
+		.param.config = flags_memcpy_config,
+		.param.ctrl_lli_chained = flags_memcpy_lli_chained,
+		.param.ctrl_lli = flags_memcpy_lli,
+		.param.ctrl_lli_last = flags_memcpy_lli_last,
+	},
+	{
+		.number = U300_DMA_GENERAL_PURPOSE_5,
+		.name = "GENERAL 05",
+		.priority_high = 0,
+
+		.param.config = flags_memcpy_config,
+		.param.ctrl_lli_chained = flags_memcpy_lli_chained,
+		.param.ctrl_lli = flags_memcpy_lli,
+		.param.ctrl_lli_last = flags_memcpy_lli_last,
+	},
+	{
+		.number = U300_DMA_GENERAL_PURPOSE_6,
+		.name = "GENERAL 06",
+		.priority_high = 0,
+
+		.param.config = flags_memcpy_config,
+		.param.ctrl_lli_chained = flags_memcpy_lli_chained,
+		.param.ctrl_lli = flags_memcpy_lli,
+		.param.ctrl_lli_last = flags_memcpy_lli_last,
+	},
+	{
+		.number = U300_DMA_GENERAL_PURPOSE_7,
+		.name = "GENERAL 07",
+		.priority_high = 0,
+
+		.param.config = flags_memcpy_config,
+		.param.ctrl_lli_chained = flags_memcpy_lli_chained,
+		.param.ctrl_lli = flags_memcpy_lli,
+		.param.ctrl_lli_last = flags_memcpy_lli_last,
+	},
+	{
+		.number = U300_DMA_GENERAL_PURPOSE_8,
+		.name = "GENERAL 08",
+		.priority_high = 0,
+
+		.param.config = flags_memcpy_config,
+		.param.ctrl_lli_chained = flags_memcpy_lli_chained,
+		.param.ctrl_lli = flags_memcpy_lli,
+		.param.ctrl_lli_last = flags_memcpy_lli_last,
+	},
+#ifdef CONFIG_MACH_U300_BS335
+	{
+		.number = U300_DMA_UART1_TX,
+		.name = "UART1 TX",
+		.priority_high = 0,
+	},
+	{
+		.number = U300_DMA_UART1_RX,
+		.name = "UART1 RX",
+		.priority_high = 0,
+	}
+#else
+	{
+		.number = U300_DMA_GENERAL_PURPOSE_9,
+		.name = "GENERAL 09",
+		.priority_high = 0,
+
+		.param.config = flags_memcpy_config,
+		.param.ctrl_lli_chained = flags_memcpy_lli_chained,
+		.param.ctrl_lli = flags_memcpy_lli,
+		.param.ctrl_lli_last = flags_memcpy_lli_last,
+	},
+	{
+		.number = U300_DMA_GENERAL_PURPOSE_10,
+		.name = "GENERAL 10",
+		.priority_high = 0,
+
+		.param.config = flags_memcpy_config,
+		.param.ctrl_lli_chained = flags_memcpy_lli_chained,
+		.param.ctrl_lli = flags_memcpy_lli,
+		.param.ctrl_lli_last = flags_memcpy_lli_last,
+	}
+#endif
+};
+
+
+static struct coh901318_platform coh901318_platform = {
+	.chans_slave = dma_slave_channels,
+	.chans_memcpy = dma_memcpy_channels,
+	.access_memory_state = coh901318_access_memory_state,
+	.chan_conf = chan_config,
+	.max_channels = U300_DMA_CHANNELS,
+};
+
 static struct platform_device wdog_device = {
-	.name = "wdog",
+	.name = "coh901327_wdog",
 	.id = -1,
 	.num_resources = ARRAY_SIZE(wdog_resources),
 	.resource = wdog_resources,
@@ -428,11 +1441,23 @@ static struct platform_device ave_device
 	.resource = ave_resources,
 };
 
+static struct platform_device dma_device = {
+	.name		= "coh901318",
+	.id		= -1,
+	.resource	= dma_resource,
+	.num_resources  = ARRAY_SIZE(dma_resource),
+	.dev = {
+		.platform_data = &coh901318_platform,
+		.coherent_dma_mask = ~0,
+	},
+};
+
 /*
  * Notice that AMBA devices are initialized before platform devices.
  *
  */
 static struct platform_device *platform_devs[] __initdata = {
+	&dma_device,
 	&i2c0_device,
 	&i2c1_device,
 	&keypad_device,
@@ -571,7 +1596,7 @@ static void __init u300_init_check_chip(
 /*
  * Some devices and their resources require reserved physical memory from
  * the end of the available RAM. This function traverses the list of devices
- * and assigns actual adresses to these.
+ * and assigns actual addresses to these.
  */
 static void __init u300_assign_physmem(void)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-u300/dummyspichip.c linux-libre-2.6.34-gnu1/arch/arm/mach-u300/dummyspichip.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-u300/dummyspichip.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-u300/dummyspichip.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/mutex.h>
 #include <linux/spi/spi.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 /*
  * WARNING! Do not include this pl022-specific controller header
  * for any generic driver. It is only done in this dummy chip
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-u300/gpio.c linux-libre-2.6.34-gnu1/arch/arm/mach-u300/gpio.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-u300/gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-u300/gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -546,7 +546,7 @@ static void gpio_set_initial_values(void
 	for (i = 0; i < U300_GPIO_MAX; i++) {
 		val = 0;
 		for (j = 0; j < 8; j++)
-			val |= (u32)((u300_gpio_config[i][j].pull_up == DISABLE_PULL_UP)) << j;
+			val |= (u32)((u300_gpio_config[i][j].pull_up == DISABLE_PULL_UP) << j);
 		local_irq_save(flags);
 		writel(val, virtbase + U300_GPIO_PXPER + i * U300_GPIO_PORTX_SPACING);
 		local_irq_restore(flags);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-u300/include/mach/coh901318.h linux-libre-2.6.34-gnu1/arch/arm/mach-u300/include/mach/coh901318.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-u300/include/mach/coh901318.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-u300/include/mach/coh901318.h	2010-05-16 17:17:36.000000000 -0400
@@ -53,7 +53,7 @@ struct coh901318_params {
  * struct coh_dma_channel - dma channel base
  * @name: ascii name of dma channel
  * @number: channel id number
- * @desc_nbr_max: number of preallocated descriptortors
+ * @desc_nbr_max: number of preallocated descriptors
  * @priority_high: prio of channel, 0 low otherwise high.
  * @param: configuration parameters
  * @dev_addr: physical address of periphal connected to channel
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-u300/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-u300/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-u300/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-u300/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -10,8 +10,8 @@
  */
 #include <mach/hardware.h>
 
-	.macro	addruart,rx
-	/* If we move the adress using MMU, use this. */
+	.macro	addruart, rx, tmp
+	/* If we move the address using MMU, use this. */
 	mrc	p15, 0, \rx, c1, c0
 	tst	\rx, #1			@ MMU enabled?
 	ldreq	\rx,	  = U300_SLOW_PER_PHYS_BASE @ MMU off, physical address
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-u300/include/mach/dma_channels.h linux-libre-2.6.34-gnu1/arch/arm/mach-u300/include/mach/dma_channels.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-u300/include/mach/dma_channels.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-u300/include/mach/dma_channels.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,69 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/dma_channels.h
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ * Map file for the U300 dma driver.
+ * Author: Per Friden <per.friden@stericsson.com>
+ */
+
+#ifndef DMA_CHANNELS_H
+#define DMA_CHANNELS_H
+
+#define U300_DMA_MSL_TX_0             0
+#define U300_DMA_MSL_TX_1             1
+#define U300_DMA_MSL_TX_2             2
+#define U300_DMA_MSL_TX_3             3
+#define U300_DMA_MSL_TX_4             4
+#define U300_DMA_MSL_TX_5             5
+#define U300_DMA_MSL_TX_6             6
+#define U300_DMA_MSL_RX_0             7
+#define U300_DMA_MSL_RX_1             8
+#define U300_DMA_MSL_RX_2             9
+#define U300_DMA_MSL_RX_3             10
+#define U300_DMA_MSL_RX_4             11
+#define U300_DMA_MSL_RX_5             12
+#define U300_DMA_MSL_RX_6             13
+#define U300_DMA_MMCSD_RX_TX          14
+#define U300_DMA_MSPRO_TX             15
+#define U300_DMA_MSPRO_RX             16
+#define U300_DMA_UART0_TX             17
+#define U300_DMA_UART0_RX             18
+#define U300_DMA_APEX_TX              19
+#define U300_DMA_APEX_RX              20
+#define U300_DMA_PCM_I2S0_TX          21
+#define U300_DMA_PCM_I2S0_RX          22
+#define U300_DMA_PCM_I2S1_TX          23
+#define U300_DMA_PCM_I2S1_RX          24
+#define U300_DMA_XGAM_CDI             25
+#define U300_DMA_XGAM_PDI             26
+#define U300_DMA_SPI_TX               27
+#define U300_DMA_SPI_RX               28
+#define U300_DMA_GENERAL_PURPOSE_0    29
+#define U300_DMA_GENERAL_PURPOSE_1    30
+#define U300_DMA_GENERAL_PURPOSE_2    31
+#define U300_DMA_GENERAL_PURPOSE_3    32
+#define U300_DMA_GENERAL_PURPOSE_4    33
+#define U300_DMA_GENERAL_PURPOSE_5    34
+#define U300_DMA_GENERAL_PURPOSE_6    35
+#define U300_DMA_GENERAL_PURPOSE_7    36
+#define U300_DMA_GENERAL_PURPOSE_8    37
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_DMA_UART1_TX             38
+#define U300_DMA_UART1_RX             39
+#else
+#define U300_DMA_GENERAL_PURPOSE_9    38
+#define U300_DMA_GENERAL_PURPOSE_10   39
+#endif
+
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_DMA_DEVICE_CHANNELS      32
+#else
+#define U300_DMA_DEVICE_CHANNELS      30
+#endif
+#define U300_DMA_CHANNELS             40
+
+
+#endif /* DMA_CHANNELS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-u300/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-u300/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-u300/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-u300/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -9,4 +9,4 @@
  * End must be above the I/O registers and on an even 2MiB boundary.
  * Author: Linus Walleij <linus.walleij@stericsson.com>
  */
-#define VMALLOC_END	0xfe800000
+#define VMALLOC_END	0xfe800000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-u300/mmc.c linux-libre-2.6.34-gnu1/arch/arm/mach-u300/mmc.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-u300/mmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-u300/mmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/gpio.h>
 #include <linux/amba/mmci.h>
+#include <linux/slab.h>
 
 #include "mmc.h"
 #include "padmux.h"
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/board-mop500.c linux-libre-2.6.34-gnu1/arch/arm/mach-ux500/board-mop500.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/board-mop500.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ux500/board-mop500.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <asm/mach/arch.h>
 
 #include <plat/mtu.h>
+#include <plat/i2c.h>
 
 #include <mach/hardware.h>
 #include <mach/setup.h>
@@ -108,11 +109,96 @@ static struct amba_device pl022_device =
 	.periphid = SSP_PER_ID,
 };
 
+static struct amba_device pl031_device = {
+	.dev = {
+		.init_name = "pl031",
+	},
+	.res = {
+		.start = U8500_RTC_BASE,
+		.end = U8500_RTC_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {IRQ_RTC_RTT, NO_IRQ},
+};
+
+#define U8500_I2C_RESOURCES(id, size)		\
+static struct resource u8500_i2c_resources_##id[] = {	\
+	[0] = {					\
+		.start	= U8500_I2C##id##_BASE,	\
+		.end	= U8500_I2C##id##_BASE + size - 1, \
+		.flags	= IORESOURCE_MEM,	\
+	},					\
+	[1] = {					\
+		.start	= IRQ_I2C##id,		\
+		.end	= IRQ_I2C##id,		\
+		.flags	= IORESOURCE_IRQ	\
+	}					\
+}
+
+U8500_I2C_RESOURCES(0, SZ_4K);
+U8500_I2C_RESOURCES(1, SZ_4K);
+U8500_I2C_RESOURCES(2, SZ_4K);
+U8500_I2C_RESOURCES(3, SZ_4K);
+
+#define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \
+static struct nmk_i2c_controller u8500_i2c_##id = { \
+	/*				\
+	 * slave data setup time, which is	\
+	 * 250 ns,100ns,10ns which is 14,6,2	\
+	 * respectively for a 48 Mhz	\
+	 * i2c clock			\
+	 */				\
+	.slsu		= _slsu,	\
+	/* Tx FIFO threshold */		\
+	.tft		= _tft,		\
+	/* Rx FIFO threshold */		\
+	.rft		= _rft,		\
+	/* std. mode operation */	\
+	.clk_freq	= clk,		\
+	.sm		= _sm,		\
+}
+
+/*
+ * The board uses 4 i2c controllers, initialize all of
+ * them with slave data setup time of 250 ns,
+ * Tx & Rx FIFO threshold values as 1 and standard
+ * mode of operation
+ */
+U8500_I2C_CONTROLLER(0, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
+U8500_I2C_CONTROLLER(1, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
+U8500_I2C_CONTROLLER(2,	0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
+U8500_I2C_CONTROLLER(3,	0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
+
+#define U8500_I2C_PDEVICE(cid)		\
+static struct platform_device i2c_controller##cid = { \
+	.name = "nmk-i2c",		\
+	.id	 = cid,			\
+	.num_resources = 2,		\
+	.resource = u8500_i2c_resources_##cid,	\
+	.dev = {			\
+		.platform_data = &u8500_i2c_##cid \
+	}				\
+}
+
+U8500_I2C_PDEVICE(0);
+U8500_I2C_PDEVICE(1);
+U8500_I2C_PDEVICE(2);
+U8500_I2C_PDEVICE(3);
+
 static struct amba_device *amba_devs[] __initdata = {
 	&uart0_device,
 	&uart1_device,
 	&uart2_device,
 	&pl022_device,
+	&pl031_device,
+};
+
+/* add any platform devices here - TODO */
+static struct platform_device *platform_devs[] __initdata = {
+	&i2c_controller0,
+	&i2c_controller1,
+	&i2c_controller2,
+	&i2c_controller3,
 };
 
 static void __init u8500_timer_init(void)
@@ -139,6 +225,8 @@ static void __init u8500_init_machine(vo
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
 		amba_device_register(amba_devs[i], &iomem_resource);
 
+	platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
+
 	spi_register_board_info(u8500_spi_devices,
 			ARRAY_SIZE(u8500_spi_devices));
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-ux500/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ux500/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -85,11 +85,8 @@ static struct clk_lookup lookups[] = {
 
 static int __init clk_init(void)
 {
-	int i;
-
 	/* register the clock lookups */
-	for (i = 0; i < ARRAY_SIZE(lookups); i++)
-		clkdev_add(&lookups[i]);
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 	return 0;
 }
 arch_initcall(clk_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/cpu-u8500.c linux-libre-2.6.34-gnu1/arch/arm/mach-ux500/cpu-u8500.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/cpu-u8500.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ux500/cpu-u8500.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@ static struct platform_device *platform_
 
 /* minimum static i/o mapping required to boot U8500 platforms */
 static struct map_desc u8500_io_desc[] __initdata = {
+	__IO_DEV_DESC(U8500_UART2_BASE, SZ_4K),
 	__IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K),
 	__IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K),
 	__IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-ux500/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ux500/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -8,12 +8,13 @@
  * published by the Free Software Foundation.
  *
  */
-	.macro	addruart,rx
+#include <mach/hardware.h>
+
+	.macro	addruart, rx, tmp
 	mrc	p15, 0, \rx, c1, c0
-	tst	\rx, #1			@MMU enabled?
-	moveq	\rx, #0x80000000	@MMU off, Physical address
-	movne	\rx, #0xF0000000	@MMU on, Virtual address
-	orr	\rx, \rx, #0x7000
+	tst	\rx, #1					@ MMU enabled?
+	ldreq	\rx, =U8500_UART2_BASE			@ no, physical address
+	ldrne	\rx, =IO_ADDRESS(U8500_UART2_BASE)	@ yes, virtual address
 	.endm
 
 #include <asm/hardware/debug-pl01x.S>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/hardware.h linux-libre-2.6.34-gnu1/arch/arm/mach-ux500/include/mach/hardware.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/hardware.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ux500/include/mach/hardware.h	2010-05-16 17:17:36.000000000 -0400
@@ -68,12 +68,12 @@
 #define U8500_PKAM_BASE		(U8500_PER6_BASE + 0x2000)
 #define U8500_CRYPTO0_BASE	(U8500_PER6_BASE + 0xa000)
 #define U8500_CRYPTO1_BASE	(U8500_PER6_BASE + 0xb000)
-#define U8500_CLKRST6_BASE	(U8500_PER7_BASE + 0xf000)
+#define U8500_CLKRST6_BASE	(U8500_PER6_BASE + 0xf000)
 
 /* per5 base addressess */
 #define U8500_USBOTG_BASE	(U8500_PER5_BASE + 0x00000)
 #define U8500_GPIO5_BASE	(U8500_PER5_BASE + 0x1e000)
-#define U8500_CLKRST5_BASE	(U8500_PER7_BASE + 0x1f000)
+#define U8500_CLKRST5_BASE	(U8500_PER5_BASE + 0x1f000)
 
 /* per4 base addressess */
 #define U8500_BACKUPRAM0_BASE	(U8500_PER4_BASE + 0x0000)
@@ -95,7 +95,7 @@
 #define U8500_UART2_BASE	(U8500_PER3_BASE + 0x7000)
 #define U8500_SDI5_BASE		(U8500_PER3_BASE + 0x8000)
 #define U8500_GPIO3_BASE	(U8500_PER3_BASE + 0xe000)
-#define U8500_CLKRST3_BASE	(U8500_PER7_BASE + 0xf000)
+#define U8500_CLKRST3_BASE	(U8500_PER3_BASE + 0xf000)
 
 /* per2 base addressess */
 #define U8500_I2C3_BASE		(U8500_PER2_BASE + 0x0000)
@@ -123,7 +123,7 @@
 #define U8500_SPI3_BASE		(U8500_PER1_BASE + 0x9000)
 #define U8500_SLIM0_BASE	(U8500_PER1_BASE + 0xa000)
 #define U8500_GPIO1_BASE	(U8500_PER1_BASE + 0xe000)
-#define U8500_CLKRST1_BASE	(U8500_PER2_BASE + 0xf000)
+#define U8500_CLKRST1_BASE	(U8500_PER1_BASE + 0xf000)
 
 /* ST-Ericsson modified pl022 id */
 #define SSP_PER_ID		0x01080022
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-ux500/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-ux500/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -15,4 +15,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#define VMALLOC_END	0xf0000000
+#define VMALLOC_END	0xf0000000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-versatile/core.c linux-libre-2.6.34-gnu1/arch/arm/mach-versatile/core.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-versatile/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-versatile/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/clockchips.h>
 #include <linux/cnt32_to_63.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 
 #include <asm/clkdev.h>
 #include <asm/system.h>
@@ -851,8 +852,7 @@ void __init versatile_init(void)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(lookups); i++)
-		clkdev_add(&lookups[i]);
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	platform_device_register(&versatile_flash_device);
 	platform_device_register(&versatile_i2c_device);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-versatile/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/mach-versatile/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/mach-versatile/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-versatile/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
  *
 */
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx,      #0x10000000
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-versatile/pci.c linux-libre-2.6.34-gnu1/arch/arm/mach-versatile/pci.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-versatile/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-versatile/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
  */
 #include <linux/kernel.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/clock.c linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -90,12 +90,3 @@ void nuc900_subclk_enable(struct clk *cl
 
 	__raw_writel(clken, W90X900_VA_CLKPWR + SUBCLK);
 }
-
-
-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.33-gnu1/arch/arm/mach-w90x900/clock.h linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
 
 void nuc900_clk_enable(struct clk *clk, int enable);
 void nuc900_subclk_enable(struct clk *clk, int enable);
-void clks_register(struct clk_lookup *clks, size_t num);
 
 struct clk {
 	unsigned long		cken;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/cpu.c linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/cpu.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/cpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/cpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,6 +45,7 @@ static struct map_desc nuc900_iodesc[] _
 	IODESC_ENT(UART),
 	IODESC_ENT(TIMER),
 	IODESC_ENT(EBI),
+	IODESC_ENT(GPIO),
 };
 
 /* Initial clock declarations. */
@@ -68,6 +69,11 @@ static DEFINE_CLK(gdma, 27);
 static DEFINE_CLK(adc, 28);
 static DEFINE_CLK(usi, 29);
 static DEFINE_CLK(ext, 0);
+static DEFINE_CLK(timer0, 19);
+static DEFINE_CLK(timer1, 20);
+static DEFINE_CLK(timer2, 21);
+static DEFINE_CLK(timer3, 22);
+static DEFINE_CLK(timer4, 23);
 
 static struct clk_lookup nuc900_clkregs[] = {
 	DEF_CLKLOOK(&clk_lcd, "nuc900-lcd", NULL),
@@ -90,6 +96,11 @@ static struct clk_lookup nuc900_clkregs[
 	DEF_CLKLOOK(&clk_adc, "nuc900-adc", NULL),
 	DEF_CLKLOOK(&clk_usi, "nuc900-spi", NULL),
 	DEF_CLKLOOK(&clk_ext, NULL, "ext"),
+	DEF_CLKLOOK(&clk_timer0, NULL, "timer0"),
+	DEF_CLKLOOK(&clk_timer1, NULL, "timer1"),
+	DEF_CLKLOOK(&clk_timer2, NULL, "timer2"),
+	DEF_CLKLOOK(&clk_timer3, NULL, "timer3"),
+	DEF_CLKLOOK(&clk_timer4, NULL, "timer4"),
 };
 
 /* Initial serial platform data */
@@ -208,6 +219,6 @@ void __init nuc900_map_io(struct map_des
 
 void __init nuc900_init_clocks(void)
 {
-	clks_register(nuc900_clkregs, ARRAY_SIZE(nuc900_clkregs));
+	clkdev_add_table(nuc900_clkregs, ARRAY_SIZE(nuc900_clkregs));
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/cpu.h linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/cpu.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/cpu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/cpu.h	2010-05-16 17:17:36.000000000 -0400
@@ -57,3 +57,4 @@ extern struct platform_device nuc900_dev
 extern struct platform_device nuc900_device_kpi;
 extern struct platform_device nuc900_device_rtc;
 extern struct platform_device nuc900_device_ts;
+extern struct platform_device nuc900_device_lcd;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/dev.c linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/dev.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/mtd.h>
@@ -34,6 +35,7 @@
 #include <mach/regs-serial.h>
 #include <mach/nuc900_spi.h>
 #include <mach/map.h>
+#include <mach/fb.h>
 
 #include "cpu.h"
 
@@ -380,6 +382,47 @@ struct platform_device nuc900_device_kpi
 	.resource	= nuc900_kpi_resource,
 };
 
+#ifdef CONFIG_FB_NUC900
+
+static struct resource nuc900_lcd_resource[] = {
+	[0] = {
+		.start = W90X900_PA_LCD,
+		.end   = W90X900_PA_LCD + W90X900_SZ_LCD - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_LCD,
+		.end   = IRQ_LCD,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static u64 nuc900_device_lcd_dmamask = -1;
+struct platform_device nuc900_device_lcd = {
+	.name             = "nuc900-lcd",
+	.id               = -1,
+	.num_resources    = ARRAY_SIZE(nuc900_lcd_resource),
+	.resource         = nuc900_lcd_resource,
+	.dev              = {
+		.dma_mask               = &nuc900_device_lcd_dmamask,
+		.coherent_dma_mask      = -1,
+	}
+};
+
+void  nuc900_fb_set_platdata(struct nuc900fb_mach_info *pd)
+{
+	struct nuc900fb_mach_info *npd;
+
+	npd = kmalloc(sizeof(*npd), GFP_KERNEL);
+	if (npd) {
+		memcpy(npd, pd, sizeof(*npd));
+		nuc900_device_lcd.dev.platform_data = npd;
+	} else {
+		printk(KERN_ERR "no memory for LCD platform data\n");
+	}
+}
+#endif
+
 /*Here should be your evb resourse,such as LCD*/
 
 static struct platform_device *nuc900_public_dev[] __initdata = {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/include/mach/fb.h linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/include/mach/fb.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/include/mach/fb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/include/mach/fb.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,83 @@
+/* linux/include/asm/arch-nuc900/fb.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Changelog:
+ *
+ *   2008/08/26     vincen.zswan modify this file for LCD.
+ */
+
+#ifndef __ASM_ARM_FB_H
+#define __ASM_ARM_FB_H
+
+
+
+/* LCD Controller Hardware Desc */
+struct nuc900fb_hw {
+	unsigned int lcd_dccs;
+	unsigned int lcd_device_ctrl;
+	unsigned int lcd_mpulcd_cmd;
+	unsigned int lcd_int_cs;
+	unsigned int lcd_crtc_size;
+	unsigned int lcd_crtc_dend;
+	unsigned int lcd_crtc_hr;
+	unsigned int lcd_crtc_hsync;
+	unsigned int lcd_crtc_vr;
+	unsigned int lcd_va_baddr0;
+	unsigned int lcd_va_baddr1;
+	unsigned int lcd_va_fbctrl;
+	unsigned int lcd_va_scale;
+	unsigned int lcd_va_test;
+	unsigned int lcd_va_win;
+	unsigned int lcd_va_stuff;
+};
+
+/* LCD Display Description */
+struct nuc900fb_display {
+	/* LCD Image type */
+	unsigned type;
+
+	/* LCD Screen Size */
+	unsigned short width;
+	unsigned short height;
+
+	/* LCD Screen Info */
+	unsigned short xres;
+	unsigned short yres;
+	unsigned short bpp;
+
+	unsigned long pixclock;
+	unsigned short left_margin;
+	unsigned short right_margin;
+	unsigned short hsync_len;
+	unsigned short upper_margin;
+	unsigned short lower_margin;
+	unsigned short vsync_len;
+
+	/* hardware special register value */
+	unsigned int dccs;
+	unsigned int devctl;
+	unsigned int fbctrl;
+	unsigned int scale;
+};
+
+struct nuc900fb_mach_info {
+	struct nuc900fb_display *displays;
+	unsigned num_displays;
+	unsigned default_display;
+	/* GPIO Setting  Info */
+	unsigned gpio_dir;
+	unsigned gpio_dir_mask;
+	unsigned gpio_data;
+	unsigned gpio_data_mask;
+};
+
+extern void __init nuc900_fb_set_platdata(struct nuc900fb_mach_info *);
+
+#endif /* __ASM_ARM_FB_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/include/mach/regs-ldm.h linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/include/mach/regs-ldm.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/include/mach/regs-ldm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/include/mach/regs-ldm.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,253 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-serial.h
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ *  Description:
+ *     Nuvoton Display, LCM Register list
+ *  Author:  Wang Qiang (rurality.linux@gmail.com) 2009/12/11
+ *
+ */
+
+
+#ifndef __ASM_ARM_W90X900_REGS_LDM_H
+#define __ASM_ARM_W90X900_REGS_LDM_H
+
+#include <mach/map.h>
+
+/* Display Controller Control/Status Register */
+#define REG_LCM_DCCS			(0x00)
+
+#define LCM_DCCS_ENG_RST		(1 << 0)
+#define LCM_DCCS_VA_EN			(1 << 1)
+#define LCM_DCCS_OSD_EN			(1 << 2)
+#define LCM_DCCS_DISP_OUT_EN		(1 << 3)
+#define LCM_DCCS_DISP_INT_EN		(1 << 4)
+#define LCM_DCCS_CMD_ON			(1 << 5)
+#define LCM_DCCS_FIELD_INTR		(1 << 6)
+#define LCM_DCCS_SINGLE			(1 << 7)
+
+enum LCM_DCCS_VA_SRC {
+	LCM_DCCS_VA_SRC_YUV422		= (0 << 8),
+	LCM_DCCS_VA_SRC_YCBCR422	= (1 << 8),
+	LCM_DCCS_VA_SRC_RGB888		= (2 << 8),
+	LCM_DCCS_VA_SRC_RGB666		= (3 << 8),
+	LCM_DCCS_VA_SRC_RGB565		= (4 << 8),
+	LCM_DCCS_VA_SRC_RGB444LOW	= (5 << 8),
+	LCM_DCCS_VA_SRC_RGB444HIGH 	= (7 << 8)
+};
+
+
+/* Display Device Control Register */
+#define REG_LCM_DEV_CTRL		(0x04)
+
+enum LCM_DEV_CTRL_SWAP_YCbCr {
+	LCM_DEV_CTRL_SWAP_UYVY		= (0 << 1),
+	LCM_DEV_CTRL_SWAP_YUYV		= (1 << 1),
+	LCM_DEV_CTRL_SWAP_VYUY		= (2 << 1),
+	LCM_DEV_CTRL_SWAP_YVYU		= (3 << 1)
+};
+
+enum LCM_DEV_CTRL_RGB_SHIFT {
+	LCM_DEV_CTRL_RGB_SHIFT_NOT 	= (0 << 3),
+	LCM_DEV_CTRL_RGB_SHIFT_ONECYCLE = (1 << 3),
+	LCM_DEV_CTRL_RGB_SHIFT_TWOCYCLE = (2 << 3),
+	LCM_DEV_CTRL_RGB_SHIFT_NOT_DEF	= (3 << 3)
+};
+
+enum LCM_DEV_CTRL_DEVICE {
+	LCM_DEV_CTRL_DEVICE_YUV422	= (0 << 5),
+	LCM_DEV_CTRL_DEVICE_YUV444	= (1 << 5),
+	LCM_DEV_CTRL_DEVICE_UNIPAC	= (4 << 5),
+	LCM_DEV_CTRL_DEVICE_SEIKO_EPSON	= (5 << 5),
+	LCM_DEV_CTRL_DEVICE_HIGH_COLOR	= (6 << 5),
+	LCM_DEV_CTRL_DEVICE_MPU		= (7 << 5)
+};
+
+#define LCM_DEV_CTRL_LCD_DDA		(8)
+#define LCM_DEV_CTRL_YUV2CCIR		(16)
+
+enum LCM_DEV_CTRL_LCD_SEL {
+	LCM_DEV_CTRL_LCD_SEL_RGB_GBR	= (0 << 17),
+	LCM_DEV_CTRL_LCD_SEL_BGR_RBG	= (1 << 17),
+	LCM_DEV_CTRL_LCD_SEL_GBR_RGB	= (2 << 17),
+	LCM_DEV_CTRL_LCD_SEL_RBG_BGR	= (3 << 17)
+};
+
+enum LCM_DEV_CTRL_FAL_D {
+	LCM_DEV_CTRL_FAL_D_FALLING	= (0 << 19),
+	LCM_DEV_CTRL_FAL_D_RISING	= (1 << 19),
+};
+
+enum LCM_DEV_CTRL_H_POL {
+	LCM_DEV_CTRL_H_POL_LOW		= (0 << 20),
+	LCM_DEV_CTRL_H_POL_HIGH		= (1 << 20),
+};
+
+enum LCM_DEV_CTRL_V_POL {
+	LCM_DEV_CTRL_V_POL_LOW		= (0 << 21),
+	LCM_DEV_CTRL_V_POL_HIGH		= (1 << 21),
+};
+
+enum LCM_DEV_CTRL_VR_LACE {
+	LCM_DEV_CTRL_VR_LACE_NINTERLACE	= (0 << 22),
+	LCM_DEV_CTRL_VR_LACE_INTERLACE	= (1 << 22),
+};
+
+enum LCM_DEV_CTRL_LACE {
+	LCM_DEV_CTRL_LACE_NINTERLACE	= (0 << 23),
+	LCM_DEV_CTRL_LACE_INTERLACE	= (1 << 23),
+};
+
+enum LCM_DEV_CTRL_RGB_SCALE {
+	LCM_DEV_CTRL_RGB_SCALE_4096 	= (0 << 24),
+	LCM_DEV_CTRL_RGB_SCALE_65536 	= (1 << 24),
+	LCM_DEV_CTRL_RGB_SCALE_262144 	= (2 << 24),
+	LCM_DEV_CTRL_RGB_SCALE_16777216 = (3 << 24),
+};
+
+enum LCM_DEV_CTRL_DBWORD {
+	LCM_DEV_CTRL_DBWORD_HALFWORD	= (0 << 26),
+	LCM_DEV_CTRL_DBWORD_FULLWORD	= (1 << 26),
+};
+
+enum LCM_DEV_CTRL_MPU68 {
+	LCM_DEV_CTRL_MPU68_80_SERIES	= (0 << 27),
+	LCM_DEV_CTRL_MPU68_68_SERIES	= (1 << 27),
+};
+
+enum LCM_DEV_CTRL_DE_POL {
+	LCM_DEV_CTRL_DE_POL_HIGH	= (0 << 28),
+	LCM_DEV_CTRL_DE_POL_LOW		= (1 << 28),
+};
+
+#define LCM_DEV_CTRL_CMD16		(29)
+#define LCM_DEV_CTRL_CM16t18		(30)
+#define LCM_DEV_CTRL_CMD_LOW		(31)
+
+/* MPU-Interface LCD Write Command */
+#define REG_LCM_MPU_CMD			(0x08)
+
+/* Interrupt Control/Status Register */
+#define REG_LCM_INT_CS			(0x0c)
+#define LCM_INT_CS_DISP_F_EN		(1 << 0)
+#define LCM_INT_CS_UNDERRUN_EN   	(1 << 1)
+#define LCM_INT_CS_BUS_ERROR_INT 	(1 << 28)
+#define LCM_INT_CS_UNDERRUN_INT  	(1 << 29)
+#define LCM_INT_CS_DISP_F_STATUS 	(1 << 30)
+#define LCM_INT_CS_DISP_F_INT		(1 << 31)
+
+/* CRTC Display Size Control Register */
+#define REG_LCM_CRTC_SIZE		(0x10)
+#define LCM_CRTC_SIZE_VTTVAL(x)		((x) << 16)
+#define LCM_CRTC_SIZE_HTTVAL(x)		((x) << 0)
+
+/* CRTC Display Enable End */
+#define REG_LCM_CRTC_DEND		(0x14)
+#define LCM_CRTC_DEND_VDENDVAL(x)	((x) << 16)
+#define LCM_CRTC_DEND_HDENDVAL(x)	((x) << 0)
+
+/* CRTC Internal Horizontal Retrace Control Register */
+#define REG_LCM_CRTC_HR			(0x18)
+#define LCM_CRTC_HR_EVAL(x)		((x) << 16)
+#define LCM_CRTC_HR_SVAL(x)		((x) << 0)
+
+/* CRTC Horizontal Sync Control Register */
+#define REG_LCM_CRTC_HSYNC		(0x1C)
+#define LCM_CRTC_HSYNC_SHIFTVAL(x)	((x) << 30)
+#define LCM_CRTC_HSYNC_EVAL(x)		((x) << 16)
+#define LCM_CRTC_HSYNC_SVAL(x)		((x) << 0)
+
+/* CRTC Internal Vertical Retrace Control Register */
+#define REG_LCM_CRTC_VR			(0x20)
+#define LCM_CRTC_VR_EVAL(x)		((x) << 16)
+#define LCM_CRTC_VR_SVAL(x)		((x) << 0)
+
+/* Video Stream Frame Buffer-0 Starting Address */
+#define REG_LCM_VA_BADDR0		(0x24)
+
+/* Video Stream Frame Buffer-1 Starting Address */
+#define REG_LCM_VA_BADDR1		(0x28)
+
+/* Video Stream Frame Buffer Control Register */
+#define REG_LCM_VA_FBCTRL		(0x2C)
+#define LCM_VA_FBCTRL_IO_REGION_HALF	(1 << 28)
+#define LCM_VA_FBCTRL_FIELD_DUAL  	(1 << 29)
+#define LCM_VA_FBCTRL_START_BUF 	(1 << 30)
+#define LCM_VA_FBCTRL_DB_EN		(1 << 31)
+
+/* Video Stream Scaling Control Register */
+#define REG_LCM_VA_SCALE		(0x30)
+#define LCM_VA_SCALE_XCOPY_INTERPOLATION (0 << 15)
+#define LCM_VA_SCALE_XCOPY_DUPLICATION	 (1 << 15)
+
+/* Image Stream Active Window Coordinates */
+#define REG_LCM_VA_WIN			(0x38)
+
+/* Image Stream Stuff Pixel */
+#define REG_LCM_VA_STUFF		(0x3C)
+
+/* OSD Window Starting Coordinates */
+#define REG_LCM_OSD_WINS		(0x40)
+
+/* OSD Window Ending Coordinates */
+#define REG_LCM_OSD_WINE		(0x44)
+
+/* OSD Stream Frame Buffer Starting Address */
+#define REG_LCM_OSD_BADDR		(0x48)
+
+/* OSD Stream Frame Buffer Control Register */
+#define REG_LCM_OSD_FBCTRL		(0x4c)
+
+/* OSD Overlay Control Register */
+#define REG_LCM_OSD_OVERLAY		(0x50)
+
+/* OSD Overlay Color-Key Pattern Register */
+#define REG_LCM_OSD_CKEY		(0x54)
+
+/* OSD Overlay Color-Key Mask Register */
+#define REG_LCM_OSD_CMASK		(0x58)
+
+/* OSD Window Skip1 Register */
+#define REG_LCM_OSD_SKIP1		(0x5C)
+
+/* OSD Window Skip2 Register */
+#define REG_LCM_OSD_SKIP2		(0x60)
+
+/* OSD horizontal up scaling control register */
+#define REG_LCM_OSD_SCALE		(0x64)
+
+/* MPU Vsync control register */
+#define REG_LCM_MPU_VSYNC		(0x68)
+
+/* Hardware cursor control Register */
+#define REG_LCM_HC_CTRL			(0x6C)
+
+/* Hardware cursot tip point potison on va picture */
+#define REG_LCM_HC_POS			(0x70)
+
+/* Hardware Cursor Window Buffer Control Register */
+#define REG_LCM_HC_WBCTRL		(0x74)
+
+/* Hardware cursor memory base address register */
+#define REG_LCM_HC_BADDR		(0x78)
+
+/* Hardware cursor color ram register mapped to bpp = 0 */
+#define REG_LCM_HC_COLOR0		(0x7C)
+
+/* Hardware cursor color ram register mapped to bpp = 1 */
+#define REG_LCM_HC_COLOR1		(0x80)
+
+/* Hardware cursor color ram register mapped to bpp = 2 */
+#define REG_LCM_HC_COLOR2		(0x84)
+
+/* Hardware cursor color ram register mapped to bpp = 3 */
+#define REG_LCM_HC_COLOR3		(0x88)
+
+#endif /* __ASM_ARM_W90X900_REGS_LDM_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
-#define VMALLOC_END	  (0xE0000000)
+#define VMALLOC_END	  (0xe0000000UL)
 
 #endif /* __ASM_ARCH_VMALLOC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/mach-nuc950evb.c linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/mach-nuc950evb.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/mach-nuc950evb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/mach-nuc950evb.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,8 @@
  * This program is free software; 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.
+ *   history:
+ *     Wang Qiang (rurality.linux@gmail.com) add LCD support
  *
  */
 
@@ -18,9 +20,51 @@
 #include <asm/mach/map.h>
 #include <asm/mach-types.h>
 #include <mach/map.h>
+#include <mach/regs-ldm.h>
+#include <mach/fb.h>
 
 #include "nuc950.h"
 
+#ifdef CONFIG_FB_NUC900
+/* LCD Controller */
+static struct nuc900fb_display __initdata nuc950_lcd_info[] = {
+	/* Giantplus Technology GPM1040A0 320x240 Color TFT LCD */
+	[0] = {
+		.type		= LCM_DCCS_VA_SRC_RGB565,
+		.width 		= 320,
+		.height		= 240,
+		.xres		= 320,
+		.yres		= 240,
+		.bpp		= 16,
+		.pixclock	= 200000,
+		.left_margin	= 34,
+		.right_margin   = 54,
+		.hsync_len	= 10,
+		.upper_margin	= 18,
+		.lower_margin	= 4,
+		.vsync_len	= 1,
+		.dccs		= 0x8e00041a,
+		.devctl		= 0x060800c0,
+		.fbctrl		= 0x00a000a0,
+		.scale		= 0x04000400,
+	},
+};
+
+static struct nuc900fb_mach_info nuc950_fb_info __initdata = {
+#if defined(CONFIG_GPM1040A0_320X240)
+	.displays		= &nuc950_lcd_info[0],
+#else
+	.displays		= nuc950_lcd_info,
+#endif
+	.num_displays 		= ARRAY_SIZE(nuc950_lcd_info),
+	.default_display	= 0,
+	.gpio_dir		= 0x00000004,
+	.gpio_dir_mask		= 0xFFFFFFFD,
+	.gpio_data		= 0x00000004,
+	.gpio_data_mask		= 0xFFFFFFFD,
+};
+#endif
+
 static void __init nuc950evb_map_io(void)
 {
 	nuc950_map_io();
@@ -30,6 +74,9 @@ static void __init nuc950evb_map_io(void
 static void __init nuc950evb_init(void)
 {
 	nuc950_board_init();
+#ifdef CONFIG_FB_NUC900
+	nuc900_fb_set_platdata(&nuc950_fb_info);
+#endif
 }
 
 MACHINE_START(W90P950EVB, "W90P950EVB")
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/nuc950.c linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/nuc950.c
--- linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/nuc950.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mach-w90x900/nuc950.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <asm/mach/map.h>
 #include <mach/hardware.h>
+
 #include "cpu.h"
 
 /* define specific CPU platform device */
@@ -25,6 +26,9 @@
 static struct platform_device *nuc950_dev[] __initdata = {
 	&nuc900_device_kpi,
 	&nuc900_device_fmi,
+#ifdef CONFIG_FB_NUC900
+	&nuc900_device_lcd,
+#endif
 };
 
 /* define specific CPU platform io map */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/Makefile linux-libre-2.6.34-gnu1/arch/arm/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -146,6 +146,7 @@ machine-$(CONFIG_ARCH_MX1)		:= mx1
 machine-$(CONFIG_ARCH_MX2)		:= mx2
 machine-$(CONFIG_ARCH_MX25)		:= mx25
 machine-$(CONFIG_ARCH_MX3)		:= mx3
+machine-$(CONFIG_ARCH_MX5)		:= mx5
 machine-$(CONFIG_ARCH_MXC91231)		:= mxc91231
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
@@ -159,32 +160,38 @@ machine-$(CONFIG_ARCH_PNX4008)		:= pnx40
 machine-$(CONFIG_ARCH_PXA)		:= pxa
 machine-$(CONFIG_ARCH_REALVIEW)		:= realview
 machine-$(CONFIG_ARCH_RPC)		:= rpc
-machine-$(CONFIG_ARCH_S3C2410)		:= s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443
+machine-$(CONFIG_ARCH_S3C2410)		:= s3c2410 s3c2400 s3c2412 s3c2440 s3c2443
 machine-$(CONFIG_ARCH_S3C24A0)		:= s3c24a0
-machine-$(CONFIG_ARCH_S3C64XX)		:= s3c6400 s3c6410
+machine-$(CONFIG_ARCH_S3C64XX)		:= s3c64xx
+machine-$(CONFIG_ARCH_S5P6440)		:= s5p6440
+machine-$(CONFIG_ARCH_S5P6442)		:= s5p6442
 machine-$(CONFIG_ARCH_S5PC1XX)		:= s5pc100
+machine-$(CONFIG_ARCH_S5PV210)		:= s5pv210
 machine-$(CONFIG_ARCH_SA1100)		:= sa1100
 machine-$(CONFIG_ARCH_SHARK)		:= shark
+machine-$(CONFIG_ARCH_SHMOBILE) 	:= shmobile
 machine-$(CONFIG_ARCH_STMP378X)		:= stmp378x
 machine-$(CONFIG_ARCH_STMP37XX)		:= stmp37xx
 machine-$(CONFIG_ARCH_U300)		:= u300
 machine-$(CONFIG_ARCH_U8500)		:= ux500
 machine-$(CONFIG_ARCH_VERSATILE)	:= versatile
 machine-$(CONFIG_ARCH_W90X900)		:= w90x900
+machine-$(CONFIG_ARCH_NUC93X)		:= nuc93x
 machine-$(CONFIG_FOOTBRIDGE)		:= footbridge
 
 # Platform directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
 plat-$(CONFIG_ARCH_MXC)		:= mxc
 plat-$(CONFIG_ARCH_OMAP)	:= omap
+plat-$(CONFIG_ARCH_S3C64XX)	:= samsung
 plat-$(CONFIG_ARCH_STMP3XXX)	:= stmp3xxx
 plat-$(CONFIG_PLAT_IOP)		:= iop
 plat-$(CONFIG_PLAT_NOMADIK)	:= nomadik
 plat-$(CONFIG_PLAT_ORION)	:= orion
 plat-$(CONFIG_PLAT_PXA)		:= pxa
-plat-$(CONFIG_PLAT_S3C24XX)	:= s3c24xx s3c samsung
-plat-$(CONFIG_PLAT_S3C64XX)	:= s3c64xx s3c samsung
-plat-$(CONFIG_PLAT_S5PC1XX)	:= s5pc1xx s3c samsung
+plat-$(CONFIG_PLAT_S3C24XX)	:= s3c24xx samsung
+plat-$(CONFIG_PLAT_S5PC1XX)	:= s5pc1xx samsung
+plat-$(CONFIG_PLAT_S5P)		:= s5p samsung
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/alignment.c linux-libre-2.6.34-gnu1/arch/arm/mm/alignment.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/alignment.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/alignment.c	2010-05-16 17:17:36.000000000 -0400
@@ -166,15 +166,15 @@ union offset_union {
  THUMB(	"1:	"ins"	%1, [%2]\n"	)		\
  THUMB(	"	add	%2, %2, #1\n"	)		\
 	"2:\n"						\
-	"	.section .fixup,\"ax\"\n"		\
+	"	.pushsection .fixup,\"ax\"\n"		\
 	"	.align	2\n"				\
 	"3:	mov	%0, #1\n"			\
 	"	b	2b\n"				\
-	"	.previous\n"				\
-	"	.section __ex_table,\"a\"\n"		\
+	"	.popsection\n"				\
+	"	.pushsection __ex_table,\"a\"\n"	\
 	"	.align	3\n"				\
 	"	.long	1b, 3b\n"			\
-	"	.previous\n"				\
+	"	.popsection\n"				\
 	: "=r" (err), "=&r" (val), "=r" (addr)		\
 	: "0" (err), "2" (addr))
 
@@ -226,16 +226,16 @@ union offset_union {
 		"	mov	%1, %1, "NEXT_BYTE"\n"		\
 		"2:	"ins"	%1, [%2]\n"			\
 		"3:\n"						\
-		"	.section .fixup,\"ax\"\n"		\
+		"	.pushsection .fixup,\"ax\"\n"		\
 		"	.align	2\n"				\
 		"4:	mov	%0, #1\n"			\
 		"	b	3b\n"				\
-		"	.previous\n"				\
-		"	.section __ex_table,\"a\"\n"		\
+		"	.popsection\n"				\
+		"	.pushsection __ex_table,\"a\"\n"	\
 		"	.align	3\n"				\
 		"	.long	1b, 4b\n"			\
 		"	.long	2b, 4b\n"			\
-		"	.previous\n"				\
+		"	.popsection\n"				\
 		: "=r" (err), "=&r" (v), "=&r" (a)		\
 		: "0" (err), "1" (v), "2" (a));			\
 		if (err)					\
@@ -266,18 +266,18 @@ union offset_union {
 		"	mov	%1, %1, "NEXT_BYTE"\n"		\
 		"4:	"ins"	%1, [%2]\n"			\
 		"5:\n"						\
-		"	.section .fixup,\"ax\"\n"		\
+		"	.pushsection .fixup,\"ax\"\n"		\
 		"	.align	2\n"				\
 		"6:	mov	%0, #1\n"			\
 		"	b	5b\n"				\
-		"	.previous\n"				\
-		"	.section __ex_table,\"a\"\n"		\
+		"	.popsection\n"				\
+		"	.pushsection __ex_table,\"a\"\n"	\
 		"	.align	3\n"				\
 		"	.long	1b, 6b\n"			\
 		"	.long	2b, 6b\n"			\
 		"	.long	3b, 6b\n"			\
 		"	.long	4b, 6b\n"			\
-		"	.previous\n"				\
+		"	.popsection\n"				\
 		: "=r" (err), "=&r" (v), "=&r" (a)		\
 		: "0" (err), "1" (v), "2" (a));			\
 		if (err)					\
@@ -901,11 +901,7 @@ static int __init alignment_init(void)
 #ifdef CONFIG_PROC_FS
 	struct proc_dir_entry *res;
 
-	res = proc_mkdir("cpu", NULL);
-	if (!res)
-		return -ENOMEM;
-
-	res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, res);
+	res = create_proc_entry("cpu/alignment", S_IWUSR | S_IRUGO, NULL);
 	if (!res)
 		return -ENOMEM;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/cache-fa.S linux-libre-2.6.34-gnu1/arch/arm/mm/cache-fa.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/cache-fa.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/cache-fa.S	2010-05-16 17:17:36.000000000 -0400
@@ -157,7 +157,7 @@ ENTRY(fa_flush_kern_dcache_area)
  *	- start  - virtual start address
  *	- end	 - virtual end address
  */
-ENTRY(fa_dma_inv_range)
+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
@@ -180,7 +180,7 @@ ENTRY(fa_dma_inv_range)
  *	- start  - virtual start address
  *	- end	 - virtual end address
  */
-ENTRY(fa_dma_clean_range)
+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
@@ -205,6 +205,30 @@ ENTRY(fa_dma_flush_range)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(fa_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	fa_dma_clean_range
+	bcs	fa_dma_inv_range
+	b	fa_dma_flush_range
+ENDPROC(fa_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(fa_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(fa_dma_unmap_area)
+
 	__INITDATA
 
 	.type	fa_cache_fns, #object
@@ -215,7 +239,7 @@ ENTRY(fa_cache_fns)
 	.long	fa_coherent_kern_range
 	.long	fa_coherent_user_range
 	.long	fa_flush_kern_dcache_area
-	.long	fa_dma_inv_range
-	.long	fa_dma_clean_range
+	.long	fa_dma_map_area
+	.long	fa_dma_unmap_area
 	.long	fa_dma_flush_range
 	.size	fa_cache_fns, . - fa_cache_fns
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/cache-l2x0.c linux-libre-2.6.34-gnu1/arch/arm/mm/cache-l2x0.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/cache-l2x0.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/cache-l2x0.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,66 @@ static inline void cache_sync(void)
 	cache_wait(base + L2X0_CACHE_SYNC, 1);
 }
 
+static inline void l2x0_clean_line(unsigned long addr)
+{
+	void __iomem *base = l2x0_base;
+	cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
+	writel(addr, base + L2X0_CLEAN_LINE_PA);
+}
+
+static inline void l2x0_inv_line(unsigned long addr)
+{
+	void __iomem *base = l2x0_base;
+	cache_wait(base + L2X0_INV_LINE_PA, 1);
+	writel(addr, base + L2X0_INV_LINE_PA);
+}
+
+#ifdef CONFIG_PL310_ERRATA_588369
+static void debug_writel(unsigned long val)
+{
+	extern void omap_smc1(u32 fn, u32 arg);
+
+	/*
+	 * Texas Instrument secure monitor api to modify the
+	 * PL310 Debug Control Register.
+	 */
+	omap_smc1(0x100, val);
+}
+
+static inline void l2x0_flush_line(unsigned long addr)
+{
+	void __iomem *base = l2x0_base;
+
+	/* Clean by PA followed by Invalidate by PA */
+	cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
+	writel(addr, base + L2X0_CLEAN_LINE_PA);
+	cache_wait(base + L2X0_INV_LINE_PA, 1);
+	writel(addr, base + L2X0_INV_LINE_PA);
+}
+#else
+
+/* Optimised out for non-errata case */
+static inline void debug_writel(unsigned long val)
+{
+}
+
+static inline void l2x0_flush_line(unsigned long addr)
+{
+	void __iomem *base = l2x0_base;
+	cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
+	writel(addr, base + L2X0_CLEAN_INV_LINE_PA);
+}
+#endif
+
+static void l2x0_cache_sync(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&l2x0_lock, flags);
+	cache_sync();
+	spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
 static inline void l2x0_inv_all(void)
 {
 	unsigned long flags;
@@ -62,23 +122,24 @@ static void l2x0_inv_range(unsigned long
 	spin_lock_irqsave(&l2x0_lock, flags);
 	if (start & (CACHE_LINE_SIZE - 1)) {
 		start &= ~(CACHE_LINE_SIZE - 1);
-		cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
-		writel(start, base + L2X0_CLEAN_INV_LINE_PA);
+		debug_writel(0x03);
+		l2x0_flush_line(start);
+		debug_writel(0x00);
 		start += CACHE_LINE_SIZE;
 	}
 
 	if (end & (CACHE_LINE_SIZE - 1)) {
 		end &= ~(CACHE_LINE_SIZE - 1);
-		cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
-		writel(end, base + L2X0_CLEAN_INV_LINE_PA);
+		debug_writel(0x03);
+		l2x0_flush_line(end);
+		debug_writel(0x00);
 	}
 
 	while (start < end) {
 		unsigned long blk_end = start + min(end - start, 4096UL);
 
 		while (start < blk_end) {
-			cache_wait(base + L2X0_INV_LINE_PA, 1);
-			writel(start, base + L2X0_INV_LINE_PA);
+			l2x0_inv_line(start);
 			start += CACHE_LINE_SIZE;
 		}
 
@@ -103,8 +164,7 @@ static void l2x0_clean_range(unsigned lo
 		unsigned long blk_end = start + min(end - start, 4096UL);
 
 		while (start < blk_end) {
-			cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
-			writel(start, base + L2X0_CLEAN_LINE_PA);
+			l2x0_clean_line(start);
 			start += CACHE_LINE_SIZE;
 		}
 
@@ -128,11 +188,12 @@ static void l2x0_flush_range(unsigned lo
 	while (start < end) {
 		unsigned long blk_end = start + min(end - start, 4096UL);
 
+		debug_writel(0x03);
 		while (start < blk_end) {
-			cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
-			writel(start, base + L2X0_CLEAN_INV_LINE_PA);
+			l2x0_flush_line(start);
 			start += CACHE_LINE_SIZE;
 		}
+		debug_writel(0x00);
 
 		if (blk_end < end) {
 			spin_unlock_irqrestore(&l2x0_lock, flags);
@@ -173,6 +234,7 @@ void __init l2x0_init(void __iomem *base
 	outer_cache.inv_range = l2x0_inv_range;
 	outer_cache.clean_range = l2x0_clean_range;
 	outer_cache.flush_range = l2x0_flush_range;
+	outer_cache.sync = l2x0_cache_sync;
 
 	printk(KERN_INFO "L2X0 cache controller enabled\n");
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v3.S linux-libre-2.6.34-gnu1/arch/arm/mm/cache-v3.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v3.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/cache-v3.S	2010-05-16 17:17:36.000000000 -0400
@@ -84,20 +84,6 @@ ENTRY(v3_flush_kern_dcache_area)
 	/* FALLTHROUGH */
 
 /*
- *	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(v3_dma_inv_range)
-	/* FALLTHROUGH */
-
-/*
  *	dma_flush_range(start, end)
  *
  *	Clean and invalidate the specified virtual address range.
@@ -108,18 +94,29 @@ ENTRY(v3_dma_inv_range)
 ENTRY(v3_dma_flush_range)
 	mov	r0, #0
 	mcr	p15, 0, r0, c7, c0, 0		@ flush ID cache
+	mov	pc, lr
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(v3_dma_unmap_area)
+	teq	r2, #DMA_TO_DEVICE
+	bne	v3_dma_flush_range
 	/* FALLTHROUGH */
 
 /*
- *	dma_clean_range(start, end)
- *
- *	Clean (write back) the specified virtual address range.
- *
- *	- start  - virtual start address
- *	- end	 - virtual end address
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
  */
-ENTRY(v3_dma_clean_range)
+ENTRY(v3_dma_map_area)
 	mov	pc, lr
+ENDPROC(v3_dma_unmap_area)
+ENDPROC(v3_dma_map_area)
 
 	__INITDATA
 
@@ -131,7 +128,7 @@ ENTRY(v3_cache_fns)
 	.long	v3_coherent_kern_range
 	.long	v3_coherent_user_range
 	.long	v3_flush_kern_dcache_area
-	.long	v3_dma_inv_range
-	.long	v3_dma_clean_range
+	.long	v3_dma_map_area
+	.long	v3_dma_unmap_area
 	.long	v3_dma_flush_range
 	.size	v3_cache_fns, . - v3_cache_fns
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v4.S linux-libre-2.6.34-gnu1/arch/arm/mm/cache-v4.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v4.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/cache-v4.S	2010-05-16 17:17:36.000000000 -0400
@@ -94,20 +94,6 @@ ENTRY(v4_flush_kern_dcache_area)
 	/* FALLTHROUGH */
 
 /*
- *	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(v4_dma_inv_range)
-	/* FALLTHROUGH */
-
-/*
  *	dma_flush_range(start, end)
  *
  *	Clean and invalidate the specified virtual address range.
@@ -120,18 +106,29 @@ ENTRY(v4_dma_flush_range)
 	mov	r0, #0
 	mcr	p15, 0, r0, c7, c7, 0		@ flush ID cache
 #endif
+	mov	pc, lr
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(v4_dma_unmap_area)
+	teq	r2, #DMA_TO_DEVICE
+	bne	v4_dma_flush_range
 	/* FALLTHROUGH */
 
 /*
- *	dma_clean_range(start, end)
- *
- *	Clean (write back) the specified virtual address range.
- *
- *	- start  - virtual start address
- *	- end	 - virtual end address
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
  */
-ENTRY(v4_dma_clean_range)
+ENTRY(v4_dma_map_area)
 	mov	pc, lr
+ENDPROC(v4_dma_unmap_area)
+ENDPROC(v4_dma_map_area)
 
 	__INITDATA
 
@@ -143,7 +140,7 @@ ENTRY(v4_cache_fns)
 	.long	v4_coherent_kern_range
 	.long	v4_coherent_user_range
 	.long	v4_flush_kern_dcache_area
-	.long	v4_dma_inv_range
-	.long	v4_dma_clean_range
+	.long	v4_dma_map_area
+	.long	v4_dma_unmap_area
 	.long	v4_dma_flush_range
 	.size	v4_cache_fns, . - v4_cache_fns
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v4wb.S linux-libre-2.6.34-gnu1/arch/arm/mm/cache-v4wb.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v4wb.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/cache-v4wb.S	2010-05-16 17:17:36.000000000 -0400
@@ -173,7 +173,7 @@ ENTRY(v4wb_coherent_user_range)
  *	- start  - virtual start address
  *	- end	 - virtual end address
  */
-ENTRY(v4wb_dma_inv_range)
+v4wb_dma_inv_range:
 	tst	r0, #CACHE_DLINESIZE - 1
 	bic	r0, r0, #CACHE_DLINESIZE - 1
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
@@ -194,7 +194,7 @@ ENTRY(v4wb_dma_inv_range)
  *	- start  - virtual start address
  *	- end	 - virtual end address
  */
-ENTRY(v4wb_dma_clean_range)
+v4wb_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
@@ -216,6 +216,30 @@ ENTRY(v4wb_dma_clean_range)
 	.globl	v4wb_dma_flush_range
 	.set	v4wb_dma_flush_range, v4wb_coherent_kern_range
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(v4wb_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	v4wb_dma_clean_range
+	bcs	v4wb_dma_inv_range
+	b	v4wb_dma_flush_range
+ENDPROC(v4wb_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(v4wb_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(v4wb_dma_unmap_area)
+
 	__INITDATA
 
 	.type	v4wb_cache_fns, #object
@@ -226,7 +250,7 @@ ENTRY(v4wb_cache_fns)
 	.long	v4wb_coherent_kern_range
 	.long	v4wb_coherent_user_range
 	.long	v4wb_flush_kern_dcache_area
-	.long	v4wb_dma_inv_range
-	.long	v4wb_dma_clean_range
+	.long	v4wb_dma_map_area
+	.long	v4wb_dma_unmap_area
 	.long	v4wb_dma_flush_range
 	.size	v4wb_cache_fns, . - v4wb_cache_fns
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v4wt.S linux-libre-2.6.34-gnu1/arch/arm/mm/cache-v4wt.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v4wt.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/cache-v4wt.S	2010-05-16 17:17:36.000000000 -0400
@@ -142,23 +142,12 @@ ENTRY(v4wt_flush_kern_dcache_area)
  *	- start  - virtual start address
  *	- end	 - virtual end address
  */
-ENTRY(v4wt_dma_inv_range)
+v4wt_dma_inv_range:
 	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
-	/* FALLTHROUGH */
-
-/*
- *	dma_clean_range(start, end)
- *
- *	Clean the specified virtual address range.
- *
- *	- start  - virtual start address
- *	- end	 - virtual end address
- */
-ENTRY(v4wt_dma_clean_range)
 	mov	pc, lr
 
 /*
@@ -172,6 +161,29 @@ ENTRY(v4wt_dma_clean_range)
 	.globl	v4wt_dma_flush_range
 	.equ	v4wt_dma_flush_range, v4wt_dma_inv_range
 
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(v4wt_dma_unmap_area)
+	add	r1, r1, r0
+	teq	r2, #DMA_TO_DEVICE
+	bne	v4wt_dma_inv_range
+	/* FALLTHROUGH */
+
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(v4wt_dma_map_area)
+	mov	pc, lr
+ENDPROC(v4wt_dma_unmap_area)
+ENDPROC(v4wt_dma_map_area)
+
 	__INITDATA
 
 	.type	v4wt_cache_fns, #object
@@ -182,7 +194,7 @@ ENTRY(v4wt_cache_fns)
 	.long	v4wt_coherent_kern_range
 	.long	v4wt_coherent_user_range
 	.long	v4wt_flush_kern_dcache_area
-	.long	v4wt_dma_inv_range
-	.long	v4wt_dma_clean_range
+	.long	v4wt_dma_map_area
+	.long	v4wt_dma_unmap_area
 	.long	v4wt_dma_flush_range
 	.size	v4wt_cache_fns, . - v4wt_cache_fns
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v6.S linux-libre-2.6.34-gnu1/arch/arm/mm/cache-v6.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v6.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/cache-v6.S	2010-05-16 17:17:36.000000000 -0400
@@ -195,7 +195,7 @@ ENTRY(v6_flush_kern_dcache_area)
  *	- start   - virtual start address of region
  *	- end     - virtual end address of region
  */
-ENTRY(v6_dma_inv_range)
+v6_dma_inv_range:
 	tst	r0, #D_CACHE_LINE_SIZE - 1
 	bic	r0, r0, #D_CACHE_LINE_SIZE - 1
 #ifdef HARVARD_CACHE
@@ -211,6 +211,9 @@ ENTRY(v6_dma_inv_range)
 	mcrne	p15, 0, r1, c7, c15, 1		@ clean & invalidate unified line
 #endif
 1:
+#ifdef CONFIG_SMP
+	str	r0, [r0]			@ write for ownership
+#endif
 #ifdef HARVARD_CACHE
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D line
 #else
@@ -228,9 +231,12 @@ ENTRY(v6_dma_inv_range)
  *	- start   - virtual start address of region
  *	- end     - virtual end address of region
  */
-ENTRY(v6_dma_clean_range)
+v6_dma_clean_range:
 	bic	r0, r0, #D_CACHE_LINE_SIZE - 1
 1:
+#ifdef CONFIG_SMP
+	ldr	r2, [r0]			@ read for ownership
+#endif
 #ifdef HARVARD_CACHE
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D line
 #else
@@ -251,6 +257,10 @@ ENTRY(v6_dma_clean_range)
 ENTRY(v6_dma_flush_range)
 	bic	r0, r0, #D_CACHE_LINE_SIZE - 1
 1:
+#ifdef CONFIG_SMP
+	ldr	r2, [r0]			@ read for ownership
+	str	r2, [r0]			@ write for ownership
+#endif
 #ifdef HARVARD_CACHE
 	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D line
 #else
@@ -263,6 +273,31 @@ ENTRY(v6_dma_flush_range)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(v6_dma_map_area)
+	add	r1, r1, r0
+	teq	r2, #DMA_FROM_DEVICE
+	beq	v6_dma_inv_range
+	teq	r2, #DMA_TO_DEVICE
+	beq	v6_dma_clean_range
+	b	v6_dma_flush_range
+ENDPROC(v6_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(v6_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(v6_dma_unmap_area)
+
 	__INITDATA
 
 	.type	v6_cache_fns, #object
@@ -273,7 +308,7 @@ ENTRY(v6_cache_fns)
 	.long	v6_coherent_kern_range
 	.long	v6_coherent_user_range
 	.long	v6_flush_kern_dcache_area
-	.long	v6_dma_inv_range
-	.long	v6_dma_clean_range
+	.long	v6_dma_map_area
+	.long	v6_dma_unmap_area
 	.long	v6_dma_flush_range
 	.size	v6_cache_fns, . - v6_cache_fns
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v7.S linux-libre-2.6.34-gnu1/arch/arm/mm/cache-v7.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v7.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/cache-v7.S	2010-05-16 17:17:36.000000000 -0400
@@ -167,7 +167,11 @@ ENTRY(v7_coherent_user_range)
 	cmp	r0, r1
 	blo	1b
 	mov	r0, #0
+#ifdef CONFIG_SMP
+	mcr	p15, 0, r0, c7, c1, 6		@ invalidate BTB Inner Shareable
+#else
 	mcr	p15, 0, r0, c7, c5, 6		@ invalidate BTB
+#endif
 	dsb
 	isb
 	mov	pc, lr
@@ -216,7 +220,7 @@ ENDPROC(v7_flush_kern_dcache_area)
  *	- start   - virtual start address of region
  *	- end     - virtual end address of region
  */
-ENTRY(v7_dma_inv_range)
+v7_dma_inv_range:
 	dcache_line_size r2, r3
 	sub	r3, r2, #1
 	tst	r0, r3
@@ -240,7 +244,7 @@ ENDPROC(v7_dma_inv_range)
  *	- start   - virtual start address of region
  *	- end     - virtual end address of region
  */
-ENTRY(v7_dma_clean_range)
+v7_dma_clean_range:
 	dcache_line_size r2, r3
 	sub	r3, r2, #1
 	bic	r0, r0, r3
@@ -271,6 +275,32 @@ ENTRY(v7_dma_flush_range)
 	mov	pc, lr
 ENDPROC(v7_dma_flush_range)
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(v7_dma_map_area)
+	add	r1, r1, r0
+	teq	r2, #DMA_FROM_DEVICE
+	beq	v7_dma_inv_range
+	b	v7_dma_clean_range
+ENDPROC(v7_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(v7_dma_unmap_area)
+	add	r1, r1, r0
+	teq	r2, #DMA_TO_DEVICE
+	bne	v7_dma_inv_range
+	mov	pc, lr
+ENDPROC(v7_dma_unmap_area)
+
 	__INITDATA
 
 	.type	v7_cache_fns, #object
@@ -281,7 +311,7 @@ ENTRY(v7_cache_fns)
 	.long	v7_coherent_kern_range
 	.long	v7_coherent_user_range
 	.long	v7_flush_kern_dcache_area
-	.long	v7_dma_inv_range
-	.long	v7_dma_clean_range
+	.long	v7_dma_map_area
+	.long	v7_dma_unmap_area
 	.long	v7_dma_flush_range
 	.size	v7_cache_fns, . - v7_cache_fns
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/context.c linux-libre-2.6.34-gnu1/arch/arm/mm/context.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/context.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/context.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,12 +10,17 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/percpu.h>
 
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
 
 static DEFINE_SPINLOCK(cpu_asid_lock);
 unsigned int cpu_last_asid = ASID_FIRST_VERSION;
+#ifdef CONFIG_SMP
+DEFINE_PER_CPU(struct mm_struct *, current_mm);
+#endif
 
 /*
  * We fork()ed a process, and we need a new context for the child
@@ -26,13 +31,109 @@ unsigned int cpu_last_asid = ASID_FIRST_
 void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 {
 	mm->context.id = 0;
+	spin_lock_init(&mm->context.id_lock);
+}
+
+static void flush_context(void)
+{
+	/* set the reserved ASID before flushing the TLB */
+	asm("mcr	p15, 0, %0, c13, c0, 1\n" : : "r" (0));
+	isb();
+	local_flush_tlb_all();
+	if (icache_is_vivt_asid_tagged()) {
+		__flush_icache_all();
+		dsb();
+	}
+}
+
+#ifdef CONFIG_SMP
+
+static void set_mm_context(struct mm_struct *mm, unsigned int asid)
+{
+	unsigned long flags;
+
+	/*
+	 * Locking needed for multi-threaded applications where the
+	 * same mm->context.id could be set from different CPUs during
+	 * the broadcast. This function is also called via IPI so the
+	 * mm->context.id_lock has to be IRQ-safe.
+	 */
+	spin_lock_irqsave(&mm->context.id_lock, flags);
+	if (likely((mm->context.id ^ cpu_last_asid) >> ASID_BITS)) {
+		/*
+		 * Old version of ASID found. Set the new one and
+		 * reset mm_cpumask(mm).
+		 */
+		mm->context.id = asid;
+		cpumask_clear(mm_cpumask(mm));
+	}
+	spin_unlock_irqrestore(&mm->context.id_lock, flags);
+
+	/*
+	 * Set the mm_cpumask(mm) bit for the current CPU.
+	 */
+	cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
+}
+
+/*
+ * Reset the ASID on the current CPU. This function call is broadcast
+ * from the CPU handling the ASID rollover and holding cpu_asid_lock.
+ */
+static void reset_context(void *info)
+{
+	unsigned int asid;
+	unsigned int cpu = smp_processor_id();
+	struct mm_struct *mm = per_cpu(current_mm, cpu);
+
+	/*
+	 * Check if a current_mm was set on this CPU as it might still
+	 * be in the early booting stages and using the reserved ASID.
+	 */
+	if (!mm)
+		return;
+
+	smp_rmb();
+	asid = cpu_last_asid + cpu + 1;
+
+	flush_context();
+	set_mm_context(mm, asid);
+
+	/* set the new ASID */
+	asm("mcr	p15, 0, %0, c13, c0, 1\n" : : "r" (mm->context.id));
+	isb();
 }
 
+#else
+
+static inline void set_mm_context(struct mm_struct *mm, unsigned int asid)
+{
+	mm->context.id = asid;
+	cpumask_copy(mm_cpumask(mm), cpumask_of(smp_processor_id()));
+}
+
+#endif
+
 void __new_context(struct mm_struct *mm)
 {
 	unsigned int asid;
 
 	spin_lock(&cpu_asid_lock);
+#ifdef CONFIG_SMP
+	/*
+	 * Check the ASID again, in case the change was broadcast from
+	 * another CPU before we acquired the lock.
+	 */
+	if (unlikely(((mm->context.id ^ cpu_last_asid) >> ASID_BITS) == 0)) {
+		cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
+		spin_unlock(&cpu_asid_lock);
+		return;
+	}
+#endif
+	/*
+	 * At this point, it is guaranteed that the current mm (with
+	 * an old ASID) isn't active on any other CPU since the ASIDs
+	 * are changed simultaneously via IPI.
+	 */
 	asid = ++cpu_last_asid;
 	if (asid == 0)
 		asid = cpu_last_asid = ASID_FIRST_VERSION;
@@ -42,20 +143,15 @@ void __new_context(struct mm_struct *mm)
 	 * to start a new version and flush the TLB.
 	 */
 	if (unlikely((asid & ~ASID_MASK) == 0)) {
-		asid = ++cpu_last_asid;
-		/* set the reserved ASID before flushing the TLB */
-		asm("mcr	p15, 0, %0, c13, c0, 1	@ set reserved context ID\n"
-		    :
-		    : "r" (0));
-		isb();
-		flush_tlb_all();
-		if (icache_is_vivt_asid_tagged()) {
-			__flush_icache_all();
-			dsb();
-		}
+		asid = cpu_last_asid + smp_processor_id() + 1;
+		flush_context();
+#ifdef CONFIG_SMP
+		smp_wmb();
+		smp_call_function(reset_context, NULL, 1);
+#endif
+		cpu_last_asid += NR_CPUS;
 	}
-	spin_unlock(&cpu_asid_lock);
 
-	cpumask_copy(mm_cpumask(mm), cpumask_of(smp_processor_id()));
-	mm->context.id = asid;
+	set_mm_context(mm, asid);
+	spin_unlock(&cpu_asid_lock);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-feroceon.c linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-feroceon.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-feroceon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-feroceon.c	2010-05-16 17:17:36.000000000 -0400
@@ -68,12 +68,13 @@ feroceon_copy_user_page(void *kto, const
 }
 
 void feroceon_copy_user_highpage(struct page *to, struct page *from,
-	unsigned long vaddr)
+	unsigned long vaddr, struct vm_area_struct *vma)
 {
 	void *kto, *kfrom;
 
 	kto = kmap_atomic(to, KM_USER0);
 	kfrom = kmap_atomic(from, KM_USER1);
+	flush_cache_page(vma, vaddr, page_to_pfn(from));
 	feroceon_copy_user_page(kto, kfrom);
 	kunmap_atomic(kfrom, KM_USER1);
 	kunmap_atomic(kto, KM_USER0);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-v3.c linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-v3.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-v3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-v3.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,7 +38,7 @@ v3_copy_user_page(void *kto, const void
 }
 
 void v3_copy_user_highpage(struct page *to, struct page *from,
-	unsigned long vaddr)
+	unsigned long vaddr, struct vm_area_struct *vma)
 {
 	void *kto, *kfrom;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-v4mc.c linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-v4mc.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-v4mc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-v4mc.c	2010-05-16 17:17:36.000000000 -0400
@@ -69,7 +69,7 @@ mc_copy_user_page(void *from, void *to)
 }
 
 void v4_mc_copy_user_highpage(struct page *to, struct page *from,
-	unsigned long vaddr)
+	unsigned long vaddr, struct vm_area_struct *vma)
 {
 	void *kto = kmap_atomic(to, KM_USER1);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-v4wb.c linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-v4wb.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-v4wb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-v4wb.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,12 +48,13 @@ v4wb_copy_user_page(void *kto, const voi
 }
 
 void v4wb_copy_user_highpage(struct page *to, struct page *from,
-	unsigned long vaddr)
+	unsigned long vaddr, struct vm_area_struct *vma)
 {
 	void *kto, *kfrom;
 
 	kto = kmap_atomic(to, KM_USER0);
 	kfrom = kmap_atomic(from, KM_USER1);
+	flush_cache_page(vma, vaddr, page_to_pfn(from));
 	v4wb_copy_user_page(kto, kfrom);
 	kunmap_atomic(kfrom, KM_USER1);
 	kunmap_atomic(kto, KM_USER0);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-v4wt.c linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-v4wt.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-v4wt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-v4wt.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,7 +44,7 @@ v4wt_copy_user_page(void *kto, const voi
 }
 
 void v4wt_copy_user_highpage(struct page *to, struct page *from,
-	unsigned long vaddr)
+	unsigned long vaddr, struct vm_area_struct *vma)
 {
 	void *kto, *kfrom;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-v6.c linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-v6.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-v6.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-v6.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,21 +34,14 @@ static DEFINE_SPINLOCK(v6_lock);
  * attack the kernel's existing mapping of these pages.
  */
 static void v6_copy_user_highpage_nonaliasing(struct page *to,
-	struct page *from, unsigned long vaddr)
+	struct page *from, unsigned long vaddr, struct vm_area_struct *vma)
 {
 	void *kto, *kfrom;
 
 	kfrom = kmap_atomic(from, KM_USER0);
 	kto = kmap_atomic(to, KM_USER1);
 	copy_page(kto, kfrom);
-#ifdef CONFIG_HIGHMEM
-	/*
-	 * kmap_atomic() doesn't set the page virtual address, and
-	 * kunmap_atomic() takes care of cache flushing already.
-	 */
-	if (page_address(to) != NULL)
-#endif
-		__cpuc_flush_dcache_area(kto, PAGE_SIZE);
+	__cpuc_flush_dcache_area(kto, PAGE_SIZE);
 	kunmap_atomic(kto, KM_USER1);
 	kunmap_atomic(kfrom, KM_USER0);
 }
@@ -81,7 +74,7 @@ static void discard_old_kernel_data(void
  * Copy the page, taking account of the cache colour.
  */
 static void v6_copy_user_highpage_aliasing(struct page *to,
-	struct page *from, unsigned long vaddr)
+	struct page *from, unsigned long vaddr, struct vm_area_struct *vma)
 {
 	unsigned int offset = CACHE_COLOUR(vaddr);
 	unsigned long kfrom, kto;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-xsc3.c linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-xsc3.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-xsc3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-xsc3.c	2010-05-16 17:17:36.000000000 -0400
@@ -71,12 +71,13 @@ xsc3_mc_copy_user_page(void *kto, const
 }
 
 void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
-	unsigned long vaddr)
+	unsigned long vaddr, struct vm_area_struct *vma)
 {
 	void *kto, *kfrom;
 
 	kto = kmap_atomic(to, KM_USER0);
 	kfrom = kmap_atomic(from, KM_USER1);
+	flush_cache_page(vma, vaddr, page_to_pfn(from));
 	xsc3_mc_copy_user_page(kto, kfrom);
 	kunmap_atomic(kfrom, KM_USER1);
 	kunmap_atomic(kto, KM_USER0);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-xscale.c linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-xscale.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-xscale.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-xscale.c	2010-05-16 17:17:36.000000000 -0400
@@ -91,7 +91,7 @@ mc_copy_user_page(void *from, void *to)
 }
 
 void xscale_mc_copy_user_highpage(struct page *to, struct page *from,
-	unsigned long vaddr)
+	unsigned long vaddr, struct vm_area_struct *vma)
 {
 	void *kto = kmap_atomic(to, KM_USER1);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/dma-mapping.c linux-libre-2.6.34-gnu1/arch/arm/mm/dma-mapping.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/dma-mapping.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/dma-mapping.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
  */
 #include <linux/module.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/errno.h>
 #include <linux/list.h>
 #include <linux/init.h>
@@ -29,9 +29,6 @@
 #error "CONSISTENT_DMA_SIZE must be multiple of 2MiB"
 #endif
 
-#define CONSISTENT_END	(0xffe00000)
-#define CONSISTENT_BASE	(CONSISTENT_END - CONSISTENT_DMA_SIZE)
-
 #define CONSISTENT_OFFSET(x)	(((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
 #define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
 #define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
@@ -404,78 +401,44 @@ EXPORT_SYMBOL(dma_free_coherent);
  * platforms with CONFIG_DMABOUNCE.
  * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
  */
-void dma_cache_maint(const void *start, size_t size, int direction)
+void ___dma_single_cpu_to_dev(const void *kaddr, size_t size,
+	enum dma_data_direction dir)
 {
-	void (*inner_op)(const void *, const void *);
-	void (*outer_op)(unsigned long, unsigned long);
+	unsigned long paddr;
 
-	BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(start + size - 1));
+	BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
 
-	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();
-	}
+	dmac_map_area(kaddr, size, dir);
 
-	inner_op(start, start + size);
-	outer_op(__pa(start), __pa(start) + size);
+	paddr = __pa(kaddr);
+	if (dir == DMA_FROM_DEVICE) {
+		outer_inv_range(paddr, paddr + size);
+	} else {
+		outer_clean_range(paddr, paddr + size);
+	}
+	/* FIXME: non-speculating: flush on bidirectional mappings? */
 }
-EXPORT_SYMBOL(dma_cache_maint);
+EXPORT_SYMBOL(___dma_single_cpu_to_dev);
 
-static void dma_cache_maint_contiguous(struct page *page, unsigned long offset,
-				       size_t size, int direction)
+void ___dma_single_dev_to_cpu(const void *kaddr, size_t size,
+	enum dma_data_direction dir)
 {
-	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();
-	}
+	BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
 
-	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);
-		}
+	/* FIXME: non-speculating: not required */
+	/* don't bother invalidating if DMA to device */
+	if (dir != DMA_TO_DEVICE) {
+		unsigned long paddr = __pa(kaddr);
+		outer_inv_range(paddr, paddr + size);
 	}
 
-	paddr = page_to_phys(page) + offset;
-	outer_op(paddr, paddr + size);
+	dmac_unmap_area(kaddr, size, dir);
 }
+EXPORT_SYMBOL(___dma_single_dev_to_cpu);
 
-void dma_cache_maint_page(struct page *page, unsigned long offset,
-			  size_t size, int dir)
+static void dma_cache_maint_page(struct page *page, unsigned long offset,
+	size_t size, enum dma_data_direction dir,
+	void (*op)(const void *, size_t, int))
 {
 	/*
 	 * A single sg entry may refer to multiple physically contiguous
@@ -486,20 +449,67 @@ void dma_cache_maint_page(struct page *p
 	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;
+		void *vaddr;
+
+		if (PageHighMem(page)) {
+			if (len + offset > PAGE_SIZE) {
+				if (offset >= PAGE_SIZE) {
+					page += offset / PAGE_SIZE;
+					offset %= PAGE_SIZE;
+				}
+				len = PAGE_SIZE - offset;
 			}
-			len = PAGE_SIZE - offset;
+			vaddr = kmap_high_get(page);
+			if (vaddr) {
+				vaddr += offset;
+				op(vaddr, len, dir);
+				kunmap_high(page);
+			} else if (cache_is_vipt()) {
+				pte_t saved_pte;
+				vaddr = kmap_high_l1_vipt(page, &saved_pte);
+				op(vaddr + offset, len, dir);
+				kunmap_high_l1_vipt(page, saved_pte);
+			}
+		} else {
+			vaddr = page_address(page) + offset;
+			op(vaddr, len, dir);
 		}
-		dma_cache_maint_contiguous(page, offset, len, dir);
 		offset = 0;
 		page++;
 		left -= len;
 	} while (left);
 }
-EXPORT_SYMBOL(dma_cache_maint_page);
+
+void ___dma_page_cpu_to_dev(struct page *page, unsigned long off,
+	size_t size, enum dma_data_direction dir)
+{
+	unsigned long paddr;
+
+	dma_cache_maint_page(page, off, size, dir, dmac_map_area);
+
+	paddr = page_to_phys(page) + off;
+	if (dir == DMA_FROM_DEVICE) {
+		outer_inv_range(paddr, paddr + size);
+	} else {
+		outer_clean_range(paddr, paddr + size);
+	}
+	/* FIXME: non-speculating: flush on bidirectional mappings? */
+}
+EXPORT_SYMBOL(___dma_page_cpu_to_dev);
+
+void ___dma_page_dev_to_cpu(struct page *page, unsigned long off,
+	size_t size, enum dma_data_direction dir)
+{
+	unsigned long paddr = page_to_phys(page) + off;
+
+	/* FIXME: non-speculating: not required */
+	/* don't bother invalidating if DMA to device */
+	if (dir != DMA_TO_DEVICE)
+		outer_inv_range(paddr, paddr + size);
+
+	dma_cache_maint_page(page, off, size, dir, dmac_unmap_area);
+}
+EXPORT_SYMBOL(___dma_page_dev_to_cpu);
 
 /**
  * dma_map_sg - map a set of SG buffers for streaming mode DMA
@@ -573,8 +583,12 @@ void dma_sync_sg_for_cpu(struct device *
 	int i;
 
 	for_each_sg(sg, s, nents, i) {
-		dmabounce_sync_for_cpu(dev, sg_dma_address(s), 0,
-					sg_dma_len(s), dir);
+		if (!dmabounce_sync_for_cpu(dev, sg_dma_address(s), 0,
+					    sg_dma_len(s), dir))
+			continue;
+
+		__dma_page_dev_to_cpu(sg_page(s), s->offset,
+				      s->length, dir);
 	}
 }
 EXPORT_SYMBOL(dma_sync_sg_for_cpu);
@@ -597,9 +611,8 @@ void dma_sync_sg_for_device(struct devic
 					sg_dma_len(s), dir))
 			continue;
 
-		if (!arch_is_coherent())
-			dma_cache_maint_page(sg_page(s), s->offset,
-					     s->length, dir);
+		__dma_page_cpu_to_dev(sg_page(s), s->offset,
+				      s->length, dir);
 	}
 }
 EXPORT_SYMBOL(dma_sync_sg_for_device);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/fault-armv.c linux-libre-2.6.34-gnu1/arch/arm/mm/fault-armv.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/fault-armv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/fault-armv.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/pagemap.h>
+#include <linux/gfp.h>
 
 #include <asm/bugs.h>
 #include <asm/cacheflush.h>
@@ -36,28 +37,12 @@ static unsigned long shared_pte_mask = L
  * Therefore those configurations which might call adjust_pte (those
  * without CONFIG_CPU_CACHE_VIPT) cannot support split page_table_lock.
  */
-static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
+static int do_adjust_pte(struct vm_area_struct *vma, unsigned long address,
+	unsigned long pfn, pte_t *ptep)
 {
-	pgd_t *pgd;
-	pmd_t *pmd;
-	pte_t *pte, entry;
+	pte_t entry = *ptep;
 	int ret;
 
-	pgd = pgd_offset(vma->vm_mm, address);
-	if (pgd_none(*pgd))
-		goto no_pgd;
-	if (pgd_bad(*pgd))
-		goto bad_pgd;
-
-	pmd = pmd_offset(pgd, address);
-	if (pmd_none(*pmd))
-		goto no_pmd;
-	if (pmd_bad(*pmd))
-		goto bad_pmd;
-
-	pte = pte_offset_map(pmd, address);
-	entry = *pte;
-
 	/*
 	 * If this page is present, it's actually being shared.
 	 */
@@ -68,33 +53,55 @@ static int adjust_pte(struct vm_area_str
 	 * fault (ie, is old), we can safely ignore any issues.
 	 */
 	if (ret && (pte_val(entry) & L_PTE_MT_MASK) != shared_pte_mask) {
-		unsigned long pfn = pte_pfn(entry);
 		flush_cache_page(vma, address, pfn);
 		outer_flush_range((pfn << PAGE_SHIFT),
 				  (pfn << PAGE_SHIFT) + PAGE_SIZE);
 		pte_val(entry) &= ~L_PTE_MT_MASK;
 		pte_val(entry) |= shared_pte_mask;
-		set_pte_at(vma->vm_mm, address, pte, entry);
+		set_pte_at(vma->vm_mm, address, ptep, entry);
 		flush_tlb_page(vma, address);
 	}
-	pte_unmap(pte);
+
 	return ret;
+}
 
-bad_pgd:
-	pgd_ERROR(*pgd);
-	pgd_clear(pgd);
-no_pgd:
-	return 0;
+static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
+	unsigned long pfn)
+{
+	spinlock_t *ptl;
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+	int ret;
 
-bad_pmd:
-	pmd_ERROR(*pmd);
-	pmd_clear(pmd);
-no_pmd:
-	return 0;
+	pgd = pgd_offset(vma->vm_mm, address);
+	if (pgd_none_or_clear_bad(pgd))
+		return 0;
+
+	pmd = pmd_offset(pgd, address);
+	if (pmd_none_or_clear_bad(pmd))
+		return 0;
+
+	/*
+	 * This is called while another page table is mapped, so we
+	 * must use the nested version.  This also means we need to
+	 * open-code the spin-locking.
+	 */
+	ptl = pte_lockptr(vma->vm_mm, pmd);
+	pte = pte_offset_map_nested(pmd, address);
+	spin_lock(ptl);
+
+	ret = do_adjust_pte(vma, address, pfn, pte);
+
+	spin_unlock(ptl);
+	pte_unmap_nested(pte);
+
+	return ret;
 }
 
 static void
-make_coherent(struct address_space *mapping, struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
+make_coherent(struct address_space *mapping, struct vm_area_struct *vma,
+	unsigned long addr, pte_t *ptep, unsigned long pfn)
 {
 	struct mm_struct *mm = vma->vm_mm;
 	struct vm_area_struct *mpnt;
@@ -122,11 +129,11 @@ make_coherent(struct address_space *mapp
 		if (!(mpnt->vm_flags & VM_MAYSHARE))
 			continue;
 		offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
-		aliases += adjust_pte(mpnt, mpnt->vm_start + offset);
+		aliases += adjust_pte(mpnt, mpnt->vm_start + offset, pfn);
 	}
 	flush_dcache_mmap_unlock(mapping);
 	if (aliases)
-		adjust_pte(vma, addr);
+		do_adjust_pte(vma, addr, pfn, ptep);
 	else
 		flush_cache_page(vma, addr, pfn);
 }
@@ -144,9 +151,10 @@ make_coherent(struct address_space *mapp
  *
  * Note that the pte lock will be held.
  */
-void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
+	pte_t *ptep)
 {
-	unsigned long pfn = pte_pfn(pte);
+	unsigned long pfn = pte_pfn(*ptep);
 	struct address_space *mapping;
 	struct page *page;
 
@@ -168,7 +176,7 @@ void update_mmu_cache(struct vm_area_str
 #endif
 	if (mapping) {
 		if (cache_is_vivt())
-			make_coherent(mapping, vma, addr, pfn);
+			make_coherent(mapping, vma, addr, ptep, pfn);
 		else if (vma->vm_flags & VM_EXEC)
 			__flush_icache_all();
 	}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/fault.c linux-libre-2.6.34-gnu1/arch/arm/mm/fault.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/fault.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/fault.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/page-flags.h>
 #include <linux/sched.h>
 #include <linux/highmem.h>
+#include <linux/perf_event.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -302,6 +303,12 @@ do_page_fault(unsigned long addr, unsign
 	fault = __do_page_fault(mm, addr, fsr, tsk);
 	up_read(&mm->mmap_sem);
 
+	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, addr);
+	if (fault & VM_FAULT_MAJOR)
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0, regs, addr);
+	else if (fault & VM_FAULT_MINOR)
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0, regs, addr);
+
 	/*
 	 * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR
 	 */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/flush.c linux-libre-2.6.34-gnu1/arch/arm/mm/flush.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/flush.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/flush.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,8 @@
 
 #include <asm/cacheflush.h>
 #include <asm/cachetype.h>
+#include <asm/highmem.h>
+#include <asm/smp_plat.h>
 #include <asm/system.h>
 #include <asm/tlbflush.h>
 
@@ -87,13 +89,26 @@ void flush_cache_page(struct vm_area_str
 	if (vma->vm_flags & VM_EXEC && icache_is_vivt_asid_tagged())
 		__flush_icache_all();
 }
+#else
+#define flush_pfn_alias(pfn,vaddr)	do { } while (0)
+#endif
 
+#ifdef CONFIG_SMP
+static void flush_ptrace_access_other(void *args)
+{
+	__flush_icache_all();
+}
+#endif
+
+static
 void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
-			 unsigned long uaddr, void *kaddr,
-			 unsigned long len, int write)
+			 unsigned long uaddr, void *kaddr, unsigned long len)
 {
 	if (cache_is_vivt()) {
-		vivt_flush_ptrace_access(vma, page, uaddr, kaddr, len, write);
+		if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
+			unsigned long addr = (unsigned long)kaddr;
+			__cpuc_coherent_kern_range(addr, addr + len);
+		}
 		return;
 	}
 
@@ -104,34 +119,59 @@ void flush_ptrace_access(struct vm_area_
 	}
 
 	/* VIPT non-aliasing cache */
-	if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm)) &&
-	    vma->vm_flags & VM_EXEC) {
+	if (vma->vm_flags & VM_EXEC) {
 		unsigned long addr = (unsigned long)kaddr;
-		/* only flushing the kernel mapping on non-aliasing VIPT */
 		__cpuc_coherent_kern_range(addr, addr + len);
+#ifdef CONFIG_SMP
+		if (cache_ops_need_broadcast())
+			smp_call_function(flush_ptrace_access_other,
+					  NULL, 1);
+#endif
 	}
 }
-#else
-#define flush_pfn_alias(pfn,vaddr)	do { } while (0)
+
+/*
+ * Copy user data from/to a page which is mapped into a different
+ * processes address space.  Really, we want to allow our "user
+ * space" model to handle this.
+ *
+ * Note that this code needs to run on the current CPU.
+ */
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+		       unsigned long uaddr, void *dst, const void *src,
+		       unsigned long len)
+{
+#ifdef CONFIG_SMP
+	preempt_disable();
 #endif
+	memcpy(dst, src, len);
+	flush_ptrace_access(vma, page, uaddr, dst, len);
+#ifdef CONFIG_SMP
+	preempt_enable();
+#endif
+}
 
 void __flush_dcache_page(struct address_space *mapping, struct page *page)
 {
-	void *addr = page_address(page);
-
 	/*
 	 * Writeback any data associated with the kernel mapping of this
 	 * page.  This ensures that data in the physical page is mutually
 	 * coherent with the kernels mapping.
 	 */
-#ifdef CONFIG_HIGHMEM
-	/*
-	 * kmap_atomic() doesn't set the page virtual address, and
-	 * kunmap_atomic() takes care of cache flushing already.
-	 */
-	if (addr)
-#endif
-		__cpuc_flush_dcache_area(addr, PAGE_SIZE);
+	if (!PageHighMem(page)) {
+		__cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
+	} else {
+		void *addr = kmap_high_get(page);
+		if (addr) {
+			__cpuc_flush_dcache_area(addr, PAGE_SIZE);
+			kunmap_high(page);
+		} else if (cache_is_vipt()) {
+			pte_t saved_pte;
+			addr = kmap_high_l1_vipt(page, &saved_pte);
+			__cpuc_flush_dcache_area(addr, PAGE_SIZE);
+			kunmap_high_l1_vipt(page, saved_pte);
+		}
+	}
 
 	/*
 	 * If this is a page cache page, and we have an aliasing VIPT cache,
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/highmem.c linux-libre-2.6.34-gnu1/arch/arm/mm/highmem.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/highmem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/highmem.c	2010-05-16 17:17:36.000000000 -0400
@@ -79,7 +79,8 @@ void kunmap_atomic(void *kvaddr, enum km
 	unsigned int idx = type + KM_TYPE_NR * smp_processor_id();
 
 	if (kvaddr >= (void *)FIXADDR_START) {
-		__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
+		if (cache_is_vivt())
+			__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
 #ifdef CONFIG_DEBUG_HIGHMEM
 		BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
 		set_pte_ext(TOP_PTE(vaddr), __pte(0), 0);
@@ -124,3 +125,87 @@ struct page *kmap_atomic_to_page(const v
 	pte = TOP_PTE(vaddr);
 	return pte_page(*pte);
 }
+
+#ifdef CONFIG_CPU_CACHE_VIPT
+
+#include <linux/percpu.h>
+
+/*
+ * The VIVT cache of a highmem page is always flushed before the page
+ * is unmapped. Hence unmapped highmem pages need no cache maintenance
+ * in that case.
+ *
+ * However unmapped pages may still be cached with a VIPT cache, and
+ * it is not possible to perform cache maintenance on them using physical
+ * addresses unfortunately.  So we have no choice but to set up a temporary
+ * virtual mapping for that purpose.
+ *
+ * Yet this VIPT cache maintenance may be triggered from DMA support
+ * functions which are possibly called from interrupt context. As we don't
+ * want to keep interrupt disabled all the time when such maintenance is
+ * taking place, we therefore allow for some reentrancy by preserving and
+ * restoring the previous fixmap entry before the interrupted context is
+ * resumed.  If the reentrancy depth is 0 then there is no need to restore
+ * the previous fixmap, and leaving the current one in place allow it to
+ * be reused the next time without a TLB flush (common with DMA).
+ */
+
+static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth);
+
+void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte)
+{
+	unsigned int idx, cpu = smp_processor_id();
+	int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
+	unsigned long vaddr, flags;
+	pte_t pte, *ptep;
+
+	idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
+	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+	ptep = TOP_PTE(vaddr);
+	pte = mk_pte(page, kmap_prot);
+
+	if (!in_interrupt())
+		preempt_disable();
+
+	raw_local_irq_save(flags);
+	(*depth)++;
+	if (pte_val(*ptep) == pte_val(pte)) {
+		*saved_pte = pte;
+	} else {
+		*saved_pte = *ptep;
+		set_pte_ext(ptep, pte, 0);
+		local_flush_tlb_kernel_page(vaddr);
+	}
+	raw_local_irq_restore(flags);
+
+	return (void *)vaddr;
+}
+
+void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte)
+{
+	unsigned int idx, cpu = smp_processor_id();
+	int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
+	unsigned long vaddr, flags;
+	pte_t pte, *ptep;
+
+	idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
+	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+	ptep = TOP_PTE(vaddr);
+	pte = mk_pte(page, kmap_prot);
+
+	BUG_ON(pte_val(*ptep) != pte_val(pte));
+	BUG_ON(*depth <= 0);
+
+	raw_local_irq_save(flags);
+	(*depth)--;
+	if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) {
+		set_pte_ext(ptep, saved_pte, 0);
+		local_flush_tlb_kernel_page(vaddr);
+	}
+	raw_local_irq_restore(flags);
+
+	if (!in_interrupt())
+		preempt_enable();
+}
+
+#endif  /* CONFIG_CPU_CACHE_VIPT */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/init.c linux-libre-2.6.34-gnu1/arch/arm/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,12 +17,14 @@
 #include <linux/initrd.h>
 #include <linux/sort.h>
 #include <linux/highmem.h>
+#include <linux/gfp.h>
 
 #include <asm/mach-types.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/sizes.h>
 #include <asm/tlb.h>
+#include <asm/fixmap.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -32,19 +34,21 @@
 static unsigned long phys_initrd_start __initdata = 0;
 static unsigned long phys_initrd_size __initdata = 0;
 
-static void __init early_initrd(char **p)
+static int __init early_initrd(char *p)
 {
 	unsigned long start, size;
+	char *endp;
 
-	start = memparse(*p, p);
-	if (**p == ',') {
-		size = memparse((*p) + 1, p);
+	start = memparse(p, &endp);
+	if (*endp == ',') {
+		size = memparse(endp + 1, NULL);
 
 		phys_initrd_start = start;
 		phys_initrd_size = size;
 	}
+	return 0;
 }
-__early_param("initrd=", early_initrd);
+early_param("initrd", early_initrd);
 
 static int __init parse_tag_initrd(const struct tag *tag)
 {
@@ -82,9 +86,6 @@ void show_mem(void)
 	printk("Mem-info:\n");
 	show_free_areas();
 	for_each_online_node(node) {
-		pg_data_t *n = NODE_DATA(node);
-		struct page *map = pgdat_page_nr(n, 0) - n->node_start_pfn;
-
 		for_each_nodebank (i,mi,node) {
 			struct membank *bank = &mi->bank[i];
 			unsigned int pfn1, pfn2;
@@ -93,8 +94,8 @@ void show_mem(void)
 			pfn1 = bank_pfn_start(bank);
 			pfn2 = bank_pfn_end(bank);
 
-			page = map + pfn1;
-			end  = map + pfn2;
+			page = pfn_to_page(pfn1);
+			end  = pfn_to_page(pfn2 - 1) + 1;
 
 			do {
 				total++;
@@ -560,7 +561,7 @@ static void __init free_unused_memmap_no
  */
 void __init mem_init(void)
 {
-	unsigned int codesize, datasize, initsize;
+	unsigned long reserved_pages, free_pages;
 	int i, node;
 
 #ifndef CONFIG_DISCONTIGMEM
@@ -596,6 +597,30 @@ void __init mem_init(void)
 	totalram_pages += totalhigh_pages;
 #endif
 
+	reserved_pages = free_pages = 0;
+
+	for_each_online_node(node) {
+		for_each_nodebank(i, &meminfo, node) {
+			struct membank *bank = &meminfo.bank[i];
+			unsigned int pfn1, pfn2;
+			struct page *page, *end;
+
+			pfn1 = bank_pfn_start(bank);
+			pfn2 = bank_pfn_end(bank);
+
+			page = pfn_to_page(pfn1);
+			end  = pfn_to_page(pfn2 - 1) + 1;
+
+			do {
+				if (PageReserved(page))
+					reserved_pages++;
+				else if (!page_count(page))
+					free_pages++;
+				page++;
+			} while (page < end);
+		}
+	}
+
 	/*
 	 * Since our memory may not be contiguous, calculate the
 	 * real number of pages we have in this system
@@ -608,16 +633,71 @@ void __init mem_init(void)
 	}
 	printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
 
-	codesize = _etext - _text;
-	datasize = _end - _data;
-	initsize = __init_end - __init_begin;
-
-	printk(KERN_NOTICE "Memory: %luKB available (%dK code, "
-		"%dK data, %dK init, %luK highmem)\n",
-		nr_free_pages() << (PAGE_SHIFT-10), codesize >> 10,
-		datasize >> 10, initsize >> 10,
+	printk(KERN_NOTICE "Memory: %luk/%luk available, %luk reserved, %luK highmem\n",
+		nr_free_pages() << (PAGE_SHIFT-10),
+		free_pages << (PAGE_SHIFT-10),
+		reserved_pages << (PAGE_SHIFT-10),
 		totalhigh_pages << (PAGE_SHIFT-10));
 
+#define MLK(b, t) b, t, ((t) - (b)) >> 10
+#define MLM(b, t) b, t, ((t) - (b)) >> 20
+#define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K)
+
+	printk(KERN_NOTICE "Virtual kernel memory layout:\n"
+			"    vector  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
+			"    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
+#ifdef CONFIG_MMU
+			"    DMA     : 0x%08lx - 0x%08lx   (%4ld MB)\n"
+#endif
+			"    vmalloc : 0x%08lx - 0x%08lx   (%4ld MB)\n"
+			"    lowmem  : 0x%08lx - 0x%08lx   (%4ld MB)\n"
+#ifdef CONFIG_HIGHMEM
+			"    pkmap   : 0x%08lx - 0x%08lx   (%4ld MB)\n"
+#endif
+			"    modules : 0x%08lx - 0x%08lx   (%4ld MB)\n"
+			"      .init : 0x%p" " - 0x%p" "   (%4d kB)\n"
+			"      .text : 0x%p" " - 0x%p" "   (%4d kB)\n"
+			"      .data : 0x%p" " - 0x%p" "   (%4d kB)\n",
+
+			MLK(UL(CONFIG_VECTORS_BASE), UL(CONFIG_VECTORS_BASE) +
+				(PAGE_SIZE)),
+			MLK(FIXADDR_START, FIXADDR_TOP),
+#ifdef CONFIG_MMU
+			MLM(CONSISTENT_BASE, CONSISTENT_END),
+#endif
+			MLM(VMALLOC_START, VMALLOC_END),
+			MLM(PAGE_OFFSET, (unsigned long)high_memory),
+#ifdef CONFIG_HIGHMEM
+			MLM(PKMAP_BASE, (PKMAP_BASE) + (LAST_PKMAP) *
+				(PAGE_SIZE)),
+#endif
+			MLM(MODULES_VADDR, MODULES_END),
+
+			MLK_ROUNDUP(__init_begin, __init_end),
+			MLK_ROUNDUP(_text, _etext),
+			MLK_ROUNDUP(_data, _edata));
+
+#undef MLK
+#undef MLM
+#undef MLK_ROUNDUP
+
+	/*
+	 * Check boundaries twice: Some fundamental inconsistencies can
+	 * be detected at build time already.
+	 */
+#ifdef CONFIG_MMU
+	BUILD_BUG_ON(VMALLOC_END			> CONSISTENT_BASE);
+	BUG_ON(VMALLOC_END				> CONSISTENT_BASE);
+
+	BUILD_BUG_ON(TASK_SIZE				> MODULES_VADDR);
+	BUG_ON(TASK_SIZE 				> MODULES_VADDR);
+#endif
+
+#ifdef CONFIG_HIGHMEM
+	BUILD_BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > PAGE_OFFSET);
+	BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE	> PAGE_OFFSET);
+#endif
+
 	if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
 		extern int sysctl_overcommit_memory;
 		/*
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/ioremap.c linux-libre-2.6.34-gnu1/arch/arm/mm/ioremap.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/ioremap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/ioremap.c	2010-05-16 17:17:36.000000000 -0400
@@ -139,8 +139,8 @@ void __check_kvm_seq(struct mm_struct *m
  * which requires the new ioremap'd region to be referenced, the CPU will
  * reference the _old_ region.
  *
- * Note that get_vm_area() allocates a guard 4K page, so we need to mask
- * the size back to 1MB aligned or we will overflow in the loop below.
+ * Note that get_vm_area_caller() allocates a guard 4K page, so we need to
+ * mask the size back to 1MB aligned or we will overflow in the loop below.
  */
 static void unmap_area_sections(unsigned long virt, unsigned long size)
 {
@@ -254,22 +254,8 @@ remap_area_supersections(unsigned long v
 }
 #endif
 
-
-/*
- * Remap an arbitrary physical address space into the kernel virtual
- * address space. Needed when the kernel wants to access high addresses
- * directly.
- *
- * NOTE! We need to allow non-page-aligned mappings too: we will obviously
- * have to convert them into an offset in a page-aligned mapping, but the
- * caller shouldn't need to know that small detail.
- *
- * 'flags' are the extra L_PTE_ flags that you want to specify for this
- * mapping.  See <asm/pgtable.h> for more information.
- */
-void __iomem *
-__arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
-		  unsigned int mtype)
+void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
+	unsigned long offset, size_t size, unsigned int mtype, void *caller)
 {
 	const struct mem_type *type;
 	int err;
@@ -291,7 +277,7 @@ __arm_ioremap_pfn(unsigned long pfn, uns
 	 */
 	size = PAGE_ALIGN(offset + size);
 
- 	area = get_vm_area(size, VM_IOREMAP);
+	area = get_vm_area_caller(size, VM_IOREMAP, caller);
  	if (!area)
  		return NULL;
  	addr = (unsigned long)area->addr;
@@ -318,10 +304,9 @@ __arm_ioremap_pfn(unsigned long pfn, uns
 	flush_cache_vmap(addr, addr + size);
 	return (void __iomem *) (offset + addr);
 }
-EXPORT_SYMBOL(__arm_ioremap_pfn);
 
-void __iomem *
-__arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
+void __iomem *__arm_ioremap_caller(unsigned long phys_addr, size_t size,
+	unsigned int mtype, void *caller)
 {
 	unsigned long last_addr;
  	unsigned long offset = phys_addr & ~PAGE_MASK;
@@ -334,7 +319,33 @@ __arm_ioremap(unsigned long phys_addr, s
 	if (!size || last_addr < phys_addr)
 		return NULL;
 
- 	return __arm_ioremap_pfn(pfn, offset, size, mtype);
+	return __arm_ioremap_pfn_caller(pfn, offset, size, mtype,
+			caller);
+}
+
+/*
+ * Remap an arbitrary physical address space into the kernel virtual
+ * address space. Needed when the kernel wants to access high addresses
+ * directly.
+ *
+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+ * have to convert them into an offset in a page-aligned mapping, but the
+ * caller shouldn't need to know that small detail.
+ */
+void __iomem *
+__arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
+		  unsigned int mtype)
+{
+	return __arm_ioremap_pfn_caller(pfn, offset, size, mtype,
+			__builtin_return_address(0));
+}
+EXPORT_SYMBOL(__arm_ioremap_pfn);
+
+void __iomem *
+__arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
+{
+	return __arm_ioremap_caller(phys_addr, size, mtype,
+			__builtin_return_address(0));
 }
 EXPORT_SYMBOL(__arm_ioremap);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/Kconfig linux-libre-2.6.34-gnu1/arch/arm/mm/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/mm/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -399,7 +399,7 @@ config CPU_V6
 config CPU_32v6K
 	bool "Support ARM V6K processor extensions" if !SMP
 	depends on CPU_V6
-	default y if SMP && !ARCH_MX3
+	default y if SMP && !(ARCH_MX3 || ARCH_OMAP2)
 	help
 	  Say Y here if your ARMv6 processor supports the 'K' extension.
 	  This enables the kernel to use some instructions not present
@@ -410,7 +410,7 @@ config CPU_32v6K
 # ARMv7
 config CPU_V7
 	bool "Support ARM V7 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
-	select CPU_32v6K
+	select CPU_32v6K if !ARCH_OMAP2
 	select CPU_32v7
 	select CPU_ABRT_EV7
 	select CPU_PABRT_V7
@@ -736,6 +736,12 @@ config NEEDS_SYSCALL_FOR_CMPXCHG
 config OUTER_CACHE
 	bool
 
+config OUTER_CACHE_SYNC
+	bool
+	help
+	  The outer cache has a outer_cache_fns.sync function pointer
+	  that can be used to drain the write buffer of the outer cache.
+
 config CACHE_FEROCEON_L2
 	bool "Enable the Feroceon L2 cache controller"
 	depends on ARCH_KIRKWOOD || ARCH_MV78XX0
@@ -754,9 +760,10 @@ 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 || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK
+		   REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4
 	default y
 	select OUTER_CACHE
+	select OUTER_CACHE_SYNC
 	help
 	  This option enables the L2x0 PrimeCell.
 
@@ -779,5 +786,11 @@ config CACHE_XSC3L2
 
 config ARM_L1_CACHE_SHIFT
 	int
-	default 6 if ARCH_OMAP3 || ARCH_S5PC1XX
+	default 6 if ARM_L1_CACHE_SHIFT_6
 	default 5
+
+config ARCH_HAS_BARRIERS
+	bool
+	help
+	  This option allows the use of custom mandatory barriers
+	  included via the mach/barriers.h file.
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/mmu.c linux-libre-2.6.34-gnu1/arch/arm/mm/mmu.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/mmu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/mmu.c	2010-05-16 17:17:36.000000000 -0400
@@ -100,18 +100,17 @@ static struct cachepolicy cache_policies
  * writebuffer to be turned off.  (Note: the write
  * buffer should not be on and the cache off).
  */
-static void __init early_cachepolicy(char **p)
+static int __init early_cachepolicy(char *p)
 {
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(cache_policies); i++) {
 		int len = strlen(cache_policies[i].policy);
 
-		if (memcmp(*p, cache_policies[i].policy, len) == 0) {
+		if (memcmp(p, cache_policies[i].policy, len) == 0) {
 			cachepolicy = i;
 			cr_alignment &= ~cache_policies[i].cr_mask;
 			cr_no_alignment &= ~cache_policies[i].cr_mask;
-			*p += len;
 			break;
 		}
 	}
@@ -130,36 +129,37 @@ static void __init early_cachepolicy(cha
 	}
 	flush_cache_all();
 	set_cr(cr_alignment);
+	return 0;
 }
-__early_param("cachepolicy=", early_cachepolicy);
+early_param("cachepolicy", early_cachepolicy);
 
-static void __init early_nocache(char **__unused)
+static int __init early_nocache(char *__unused)
 {
 	char *p = "buffered";
 	printk(KERN_WARNING "nocache is deprecated; use cachepolicy=%s\n", p);
-	early_cachepolicy(&p);
+	early_cachepolicy(p);
+	return 0;
 }
-__early_param("nocache", early_nocache);
+early_param("nocache", early_nocache);
 
-static void __init early_nowrite(char **__unused)
+static int __init early_nowrite(char *__unused)
 {
 	char *p = "uncached";
 	printk(KERN_WARNING "nowb is deprecated; use cachepolicy=%s\n", p);
-	early_cachepolicy(&p);
+	early_cachepolicy(p);
+	return 0;
 }
-__early_param("nowb", early_nowrite);
+early_param("nowb", early_nowrite);
 
-static void __init early_ecc(char **p)
+static int __init early_ecc(char *p)
 {
-	if (memcmp(*p, "on", 2) == 0) {
+	if (memcmp(p, "on", 2) == 0)
 		ecc_mask = PMD_PROTECTION;
-		*p += 2;
-	} else if (memcmp(*p, "off", 3) == 0) {
+	else if (memcmp(p, "off", 3) == 0)
 		ecc_mask = 0;
-		*p += 3;
-	}
+	return 0;
 }
-__early_param("ecc=", early_ecc);
+early_param("ecc", early_ecc);
 
 static int __init noalign_setup(char *__unused)
 {
@@ -420,6 +420,10 @@ static void __init build_mem_type_table(
 		user_pgprot |= L_PTE_SHARED;
 		kern_pgprot |= L_PTE_SHARED;
 		vecs_pgprot |= L_PTE_SHARED;
+		mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S;
+		mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
+		mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
+		mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
 		mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
 		mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
 #endif
@@ -670,9 +674,9 @@ static unsigned long __initdata vmalloc_
  * bytes. This can be used to increase (or decrease) the vmalloc
  * area - the default is 128m.
  */
-static void __init early_vmalloc(char **arg)
+static int __init early_vmalloc(char *arg)
 {
-	vmalloc_reserve = memparse(*arg, arg);
+	vmalloc_reserve = memparse(arg, NULL);
 
 	if (vmalloc_reserve < SZ_16M) {
 		vmalloc_reserve = SZ_16M;
@@ -687,8 +691,9 @@ static void __init early_vmalloc(char **
 			"vmalloc area is too big, limiting to %luMB\n",
 			vmalloc_reserve >> 20);
 	}
+	return 0;
 }
-__early_param("vmalloc=", early_vmalloc);
+early_param("vmalloc", early_vmalloc);
 
 #define VMALLOC_MIN	(void *)(VMALLOC_END - vmalloc_reserve)
 
@@ -1049,10 +1054,12 @@ void setup_mm_for_reboot(char mode)
 	pgd_t *pgd;
 	int i;
 
-	if (current->mm && current->mm->pgd)
-		pgd = current->mm->pgd;
-	else
-		pgd = init_mm.pgd;
+	/*
+	 * We need to access to user-mode page tables here. For kernel threads
+	 * we don't have any user-mode mappings so we use the context that we
+	 * "borrowed".
+	 */
+	pgd = current->active_mm->pgd;
 
 	base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
 	if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/nommu.c linux-libre-2.6.34-gnu1/arch/arm/mm/nommu.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/nommu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/nommu.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,6 +65,15 @@ void flush_dcache_page(struct page *page
 }
 EXPORT_SYMBOL(flush_dcache_page);
 
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+		       unsigned long uaddr, void *dst, const void *src,
+		       unsigned long len)
+{
+	memcpy(dst, src, len);
+	if (vma->vm_flags & VM_EXEC)
+		__cpuc_coherent_user_range(uaddr, uaddr + len);
+}
+
 void __iomem *__arm_ioremap_pfn(unsigned long pfn, unsigned long offset,
 				size_t size, unsigned int mtype)
 {
@@ -74,6 +83,12 @@ void __iomem *__arm_ioremap_pfn(unsigned
 }
 EXPORT_SYMBOL(__arm_ioremap_pfn);
 
+void __iomem *__arm_ioremap_pfn_caller(unsigned long pfn, unsigned long offset,
+			   size_t size, unsigned int mtype, void *caller)
+{
+	return __arm_ioremap_pfn(pfn, offset, size, mtype);
+}
+
 void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size,
 			    unsigned int mtype)
 {
@@ -81,6 +96,12 @@ void __iomem *__arm_ioremap(unsigned lon
 }
 EXPORT_SYMBOL(__arm_ioremap);
 
+void __iomem *__arm_ioremap_caller(unsigned long phys_addr, size_t size,
+				   unsigned int mtype, void *caller)
+{
+	return __arm_ioremap(phys_addr, size, mtype);
+}
+
 void __iounmap(volatile void __iomem *addr)
 {
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/pgd.c linux-libre-2.6.34-gnu1/arch/arm/mm/pgd.c
--- linux-libre-2.6.33-gnu1/arch/arm/mm/pgd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/pgd.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/mm.h>
+#include <linux/gfp.h>
 #include <linux/highmem.h>
 
 #include <asm/pgalloc.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1020e.S linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm1020e.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1020e.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm1020e.S	2010-05-16 17:17:36.000000000 -0400
@@ -258,7 +258,7 @@ ENTRY(arm1020e_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm1020e_dma_inv_range)
+arm1020e_dma_inv_range:
 	mov	ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
 	tst	r0, #CACHE_DLINESIZE - 1
@@ -284,7 +284,7 @@ ENTRY(arm1020e_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm1020e_dma_clean_range)
+arm1020e_dma_clean_range:
 	mov	ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
 	bic	r0, r0, #CACHE_DLINESIZE - 1
@@ -316,6 +316,30 @@ ENTRY(arm1020e_dma_flush_range)
 	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm1020e_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	arm1020e_dma_clean_range
+	bcs	arm1020e_dma_inv_range
+	b	arm1020e_dma_flush_range
+ENDPROC(arm1020e_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm1020e_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(arm1020e_dma_unmap_area)
+
 ENTRY(arm1020e_cache_fns)
 	.long	arm1020e_flush_kern_cache_all
 	.long	arm1020e_flush_user_cache_all
@@ -323,8 +347,8 @@ ENTRY(arm1020e_cache_fns)
 	.long	arm1020e_coherent_kern_range
 	.long	arm1020e_coherent_user_range
 	.long	arm1020e_flush_kern_dcache_area
-	.long	arm1020e_dma_inv_range
-	.long	arm1020e_dma_clean_range
+	.long	arm1020e_dma_map_area
+	.long	arm1020e_dma_unmap_area
 	.long	arm1020e_dma_flush_range
 
 	.align	5
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1020.S linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm1020.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1020.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm1020.S	2010-05-16 17:17:36.000000000 -0400
@@ -265,7 +265,7 @@ ENTRY(arm1020_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm1020_dma_inv_range)
+arm1020_dma_inv_range:
 	mov	ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
 	tst	r0, #CACHE_DLINESIZE - 1
@@ -295,7 +295,7 @@ ENTRY(arm1020_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm1020_dma_clean_range)
+arm1020_dma_clean_range:
 	mov	ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
 	bic	r0, r0, #CACHE_DLINESIZE - 1
@@ -330,6 +330,30 @@ ENTRY(arm1020_dma_flush_range)
 	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm1020_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	arm1020_dma_clean_range
+	bcs	arm1020_dma_inv_range
+	b	arm1020_dma_flush_range
+ENDPROC(arm1020_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm1020_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(arm1020_dma_unmap_area)
+
 ENTRY(arm1020_cache_fns)
 	.long	arm1020_flush_kern_cache_all
 	.long	arm1020_flush_user_cache_all
@@ -337,8 +361,8 @@ ENTRY(arm1020_cache_fns)
 	.long	arm1020_coherent_kern_range
 	.long	arm1020_coherent_user_range
 	.long	arm1020_flush_kern_dcache_area
-	.long	arm1020_dma_inv_range
-	.long	arm1020_dma_clean_range
+	.long	arm1020_dma_map_area
+	.long	arm1020_dma_unmap_area
 	.long	arm1020_dma_flush_range
 
 	.align	5
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1022.S linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm1022.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1022.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm1022.S	2010-05-16 17:17:36.000000000 -0400
@@ -247,7 +247,7 @@ ENTRY(arm1022_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm1022_dma_inv_range)
+arm1022_dma_inv_range:
 	mov	ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
 	tst	r0, #CACHE_DLINESIZE - 1
@@ -273,7 +273,7 @@ ENTRY(arm1022_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm1022_dma_clean_range)
+arm1022_dma_clean_range:
 	mov	ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
 	bic	r0, r0, #CACHE_DLINESIZE - 1
@@ -305,6 +305,30 @@ ENTRY(arm1022_dma_flush_range)
 	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm1022_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	arm1022_dma_clean_range
+	bcs	arm1022_dma_inv_range
+	b	arm1022_dma_flush_range
+ENDPROC(arm1022_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm1022_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(arm1022_dma_unmap_area)
+
 ENTRY(arm1022_cache_fns)
 	.long	arm1022_flush_kern_cache_all
 	.long	arm1022_flush_user_cache_all
@@ -312,8 +336,8 @@ ENTRY(arm1022_cache_fns)
 	.long	arm1022_coherent_kern_range
 	.long	arm1022_coherent_user_range
 	.long	arm1022_flush_kern_dcache_area
-	.long	arm1022_dma_inv_range
-	.long	arm1022_dma_clean_range
+	.long	arm1022_dma_map_area
+	.long	arm1022_dma_unmap_area
 	.long	arm1022_dma_flush_range
 
 	.align	5
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1026.S linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm1026.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1026.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm1026.S	2010-05-16 17:17:36.000000000 -0400
@@ -241,7 +241,7 @@ ENTRY(arm1026_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm1026_dma_inv_range)
+arm1026_dma_inv_range:
 	mov	ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
 	tst	r0, #CACHE_DLINESIZE - 1
@@ -267,7 +267,7 @@ ENTRY(arm1026_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm1026_dma_clean_range)
+arm1026_dma_clean_range:
 	mov	ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
 	bic	r0, r0, #CACHE_DLINESIZE - 1
@@ -299,6 +299,30 @@ ENTRY(arm1026_dma_flush_range)
 	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm1026_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	arm1026_dma_clean_range
+	bcs	arm1026_dma_inv_range
+	b	arm1026_dma_flush_range
+ENDPROC(arm1026_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm1026_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(arm1026_dma_unmap_area)
+
 ENTRY(arm1026_cache_fns)
 	.long	arm1026_flush_kern_cache_all
 	.long	arm1026_flush_user_cache_all
@@ -306,8 +330,8 @@ ENTRY(arm1026_cache_fns)
 	.long	arm1026_coherent_kern_range
 	.long	arm1026_coherent_user_range
 	.long	arm1026_flush_kern_dcache_area
-	.long	arm1026_dma_inv_range
-	.long	arm1026_dma_clean_range
+	.long	arm1026_dma_map_area
+	.long	arm1026_dma_unmap_area
 	.long	arm1026_dma_flush_range
 
 	.align	5
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm920.S linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm920.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm920.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm920.S	2010-05-16 17:17:36.000000000 -0400
@@ -239,7 +239,7 @@ ENTRY(arm920_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm920_dma_inv_range)
+arm920_dma_inv_range:
 	tst	r0, #CACHE_DLINESIZE - 1
 	bic	r0, r0, #CACHE_DLINESIZE - 1
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
@@ -262,7 +262,7 @@ ENTRY(arm920_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm920_dma_clean_range)
+arm920_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
@@ -288,6 +288,30 @@ ENTRY(arm920_dma_flush_range)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm920_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	arm920_dma_clean_range
+	bcs	arm920_dma_inv_range
+	b	arm920_dma_flush_range
+ENDPROC(arm920_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm920_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(arm920_dma_unmap_area)
+
 ENTRY(arm920_cache_fns)
 	.long	arm920_flush_kern_cache_all
 	.long	arm920_flush_user_cache_all
@@ -295,8 +319,8 @@ ENTRY(arm920_cache_fns)
 	.long	arm920_coherent_kern_range
 	.long	arm920_coherent_user_range
 	.long	arm920_flush_kern_dcache_area
-	.long	arm920_dma_inv_range
-	.long	arm920_dma_clean_range
+	.long	arm920_dma_map_area
+	.long	arm920_dma_unmap_area
 	.long	arm920_dma_flush_range
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm922.S linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm922.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm922.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm922.S	2010-05-16 17:17:36.000000000 -0400
@@ -241,7 +241,7 @@ ENTRY(arm922_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm922_dma_inv_range)
+arm922_dma_inv_range:
 	tst	r0, #CACHE_DLINESIZE - 1
 	bic	r0, r0, #CACHE_DLINESIZE - 1
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
@@ -264,7 +264,7 @@ ENTRY(arm922_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm922_dma_clean_range)
+arm922_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
@@ -290,6 +290,30 @@ ENTRY(arm922_dma_flush_range)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm922_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	arm922_dma_clean_range
+	bcs	arm922_dma_inv_range
+	b	arm922_dma_flush_range
+ENDPROC(arm922_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm922_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(arm922_dma_unmap_area)
+
 ENTRY(arm922_cache_fns)
 	.long	arm922_flush_kern_cache_all
 	.long	arm922_flush_user_cache_all
@@ -297,8 +321,8 @@ ENTRY(arm922_cache_fns)
 	.long	arm922_coherent_kern_range
 	.long	arm922_coherent_user_range
 	.long	arm922_flush_kern_dcache_area
-	.long	arm922_dma_inv_range
-	.long	arm922_dma_clean_range
+	.long	arm922_dma_map_area
+	.long	arm922_dma_unmap_area
 	.long	arm922_dma_flush_range
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm925.S linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm925.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm925.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm925.S	2010-05-16 17:17:36.000000000 -0400
@@ -283,7 +283,7 @@ ENTRY(arm925_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm925_dma_inv_range)
+arm925_dma_inv_range:
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
 	tst	r0, #CACHE_DLINESIZE - 1
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
@@ -308,7 +308,7 @@ ENTRY(arm925_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm925_dma_clean_range)
+arm925_dma_clean_range:
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
 	bic	r0, r0, #CACHE_DLINESIZE - 1
 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
@@ -341,6 +341,30 @@ ENTRY(arm925_dma_flush_range)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm925_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	arm925_dma_clean_range
+	bcs	arm925_dma_inv_range
+	b	arm925_dma_flush_range
+ENDPROC(arm925_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm925_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(arm925_dma_unmap_area)
+
 ENTRY(arm925_cache_fns)
 	.long	arm925_flush_kern_cache_all
 	.long	arm925_flush_user_cache_all
@@ -348,8 +372,8 @@ ENTRY(arm925_cache_fns)
 	.long	arm925_coherent_kern_range
 	.long	arm925_coherent_user_range
 	.long	arm925_flush_kern_dcache_area
-	.long	arm925_dma_inv_range
-	.long	arm925_dma_clean_range
+	.long	arm925_dma_map_area
+	.long	arm925_dma_unmap_area
 	.long	arm925_dma_flush_range
 
 ENTRY(cpu_arm925_dcache_clean_area)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm926.S linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm926.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm926.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm926.S	2010-05-16 17:17:36.000000000 -0400
@@ -246,7 +246,7 @@ ENTRY(arm926_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm926_dma_inv_range)
+arm926_dma_inv_range:
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
 	tst	r0, #CACHE_DLINESIZE - 1
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
@@ -271,7 +271,7 @@ ENTRY(arm926_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm926_dma_clean_range)
+arm926_dma_clean_range:
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
 	bic	r0, r0, #CACHE_DLINESIZE - 1
 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
@@ -304,6 +304,30 @@ ENTRY(arm926_dma_flush_range)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm926_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	arm926_dma_clean_range
+	bcs	arm926_dma_inv_range
+	b	arm926_dma_flush_range
+ENDPROC(arm926_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm926_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(arm926_dma_unmap_area)
+
 ENTRY(arm926_cache_fns)
 	.long	arm926_flush_kern_cache_all
 	.long	arm926_flush_user_cache_all
@@ -311,8 +335,8 @@ ENTRY(arm926_cache_fns)
 	.long	arm926_coherent_kern_range
 	.long	arm926_coherent_user_range
 	.long	arm926_flush_kern_dcache_area
-	.long	arm926_dma_inv_range
-	.long	arm926_dma_clean_range
+	.long	arm926_dma_map_area
+	.long	arm926_dma_unmap_area
 	.long	arm926_dma_flush_range
 
 ENTRY(cpu_arm926_dcache_clean_area)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm940.S linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm940.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm940.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm940.S	2010-05-16 17:17:36.000000000 -0400
@@ -171,7 +171,7 @@ ENTRY(arm940_flush_kern_dcache_area)
  *	- start	- virtual start address
  *	- end	- virtual end address
  */
-ENTRY(arm940_dma_inv_range)
+arm940_dma_inv_range:
 	mov	ip, #0
 	mov	r1, #(CACHE_DSEGMENTS - 1) << 4	@ 4 segments
 1:	orr	r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
@@ -192,7 +192,7 @@ ENTRY(arm940_dma_inv_range)
  *	- start	- virtual start address
  *	- end	- virtual end address
  */
-ENTRY(arm940_dma_clean_range)
+arm940_dma_clean_range:
 ENTRY(cpu_arm940_dcache_clean_area)
 	mov	ip, #0
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -233,6 +233,30 @@ ENTRY(arm940_dma_flush_range)
 	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm940_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	arm940_dma_clean_range
+	bcs	arm940_dma_inv_range
+	b	arm940_dma_flush_range
+ENDPROC(arm940_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm940_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(arm940_dma_unmap_area)
+
 ENTRY(arm940_cache_fns)
 	.long	arm940_flush_kern_cache_all
 	.long	arm940_flush_user_cache_all
@@ -240,8 +264,8 @@ ENTRY(arm940_cache_fns)
 	.long	arm940_coherent_kern_range
 	.long	arm940_coherent_user_range
 	.long	arm940_flush_kern_dcache_area
-	.long	arm940_dma_inv_range
-	.long	arm940_dma_clean_range
+	.long	arm940_dma_map_area
+	.long	arm940_dma_unmap_area
 	.long	arm940_dma_flush_range
 
 	__INIT
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm946.S linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm946.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm946.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/proc-arm946.S	2010-05-16 17:17:36.000000000 -0400
@@ -215,7 +215,7 @@ ENTRY(arm946_flush_kern_dcache_area)
  *	- end	- virtual end address
  * (same as arm926)
  */
-ENTRY(arm946_dma_inv_range)
+arm946_dma_inv_range:
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
 	tst	r0, #CACHE_DLINESIZE - 1
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
@@ -240,7 +240,7 @@ ENTRY(arm946_dma_inv_range)
  *
  * (same as arm926)
  */
-ENTRY(arm946_dma_clean_range)
+arm946_dma_clean_range:
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
 	bic	r0, r0, #CACHE_DLINESIZE - 1
 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
@@ -275,6 +275,30 @@ ENTRY(arm946_dma_flush_range)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm946_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	arm946_dma_clean_range
+	bcs	arm946_dma_inv_range
+	b	arm946_dma_flush_range
+ENDPROC(arm946_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(arm946_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(arm946_dma_unmap_area)
+
 ENTRY(arm946_cache_fns)
 	.long	arm946_flush_kern_cache_all
 	.long	arm946_flush_user_cache_all
@@ -282,8 +306,8 @@ ENTRY(arm946_cache_fns)
 	.long	arm946_coherent_kern_range
 	.long	arm946_coherent_user_range
 	.long	arm946_flush_kern_dcache_area
-	.long	arm946_dma_inv_range
-	.long	arm946_dma_clean_range
+	.long	arm946_dma_map_area
+	.long	arm946_dma_unmap_area
 	.long	arm946_dma_flush_range
 
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/proc-feroceon.S linux-libre-2.6.34-gnu1/arch/arm/mm/proc-feroceon.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/proc-feroceon.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/proc-feroceon.S	2010-05-16 17:17:36.000000000 -0400
@@ -274,7 +274,7 @@ ENTRY(feroceon_range_flush_kern_dcache_a
  * (same as v4wb)
  */
 	.align	5
-ENTRY(feroceon_dma_inv_range)
+feroceon_dma_inv_range:
 	tst	r0, #CACHE_DLINESIZE - 1
 	bic	r0, r0, #CACHE_DLINESIZE - 1
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
@@ -288,7 +288,7 @@ ENTRY(feroceon_dma_inv_range)
 	mov	pc, lr
 
 	.align	5
-ENTRY(feroceon_range_dma_inv_range)
+feroceon_range_dma_inv_range:
 	mrs	r2, cpsr
 	tst	r0, #CACHE_DLINESIZE - 1
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
@@ -314,7 +314,7 @@ ENTRY(feroceon_range_dma_inv_range)
  * (same as v4wb)
  */
 	.align	5
-ENTRY(feroceon_dma_clean_range)
+feroceon_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
@@ -324,7 +324,7 @@ ENTRY(feroceon_dma_clean_range)
 	mov	pc, lr
 
 	.align	5
-ENTRY(feroceon_range_dma_clean_range)
+feroceon_range_dma_clean_range:
 	mrs	r2, cpsr
 	cmp	r1, r0
 	subne	r1, r1, #1			@ top address is inclusive
@@ -367,6 +367,44 @@ ENTRY(feroceon_range_dma_flush_range)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(feroceon_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	feroceon_dma_clean_range
+	bcs	feroceon_dma_inv_range
+	b	feroceon_dma_flush_range
+ENDPROC(feroceon_dma_map_area)
+
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(feroceon_range_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	feroceon_range_dma_clean_range
+	bcs	feroceon_range_dma_inv_range
+	b	feroceon_range_dma_flush_range
+ENDPROC(feroceon_range_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(feroceon_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(feroceon_dma_unmap_area)
+
 ENTRY(feroceon_cache_fns)
 	.long	feroceon_flush_kern_cache_all
 	.long	feroceon_flush_user_cache_all
@@ -374,8 +412,8 @@ ENTRY(feroceon_cache_fns)
 	.long	feroceon_coherent_kern_range
 	.long	feroceon_coherent_user_range
 	.long	feroceon_flush_kern_dcache_area
-	.long	feroceon_dma_inv_range
-	.long	feroceon_dma_clean_range
+	.long	feroceon_dma_map_area
+	.long	feroceon_dma_unmap_area
 	.long	feroceon_dma_flush_range
 
 ENTRY(feroceon_range_cache_fns)
@@ -385,8 +423,8 @@ ENTRY(feroceon_range_cache_fns)
 	.long	feroceon_coherent_kern_range
 	.long	feroceon_coherent_user_range
 	.long	feroceon_range_flush_kern_dcache_area
-	.long	feroceon_range_dma_inv_range
-	.long	feroceon_range_dma_clean_range
+	.long	feroceon_range_dma_map_area
+	.long	feroceon_dma_unmap_area
 	.long	feroceon_range_dma_flush_range
 
 	.align	5
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/proc-mohawk.S linux-libre-2.6.34-gnu1/arch/arm/mm/proc-mohawk.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/proc-mohawk.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/proc-mohawk.S	2010-05-16 17:17:36.000000000 -0400
@@ -218,7 +218,7 @@ ENTRY(mohawk_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(mohawk_dma_inv_range)
+mohawk_dma_inv_range:
 	tst	r0, #CACHE_DLINESIZE - 1
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
 	tst	r1, #CACHE_DLINESIZE - 1
@@ -241,7 +241,7 @@ ENTRY(mohawk_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(mohawk_dma_clean_range)
+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
@@ -268,6 +268,30 @@ ENTRY(mohawk_dma_flush_range)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(mohawk_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	mohawk_dma_clean_range
+	bcs	mohawk_dma_inv_range
+	b	mohawk_dma_flush_range
+ENDPROC(mohawk_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(mohawk_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(mohawk_dma_unmap_area)
+
 ENTRY(mohawk_cache_fns)
 	.long	mohawk_flush_kern_cache_all
 	.long	mohawk_flush_user_cache_all
@@ -275,8 +299,8 @@ ENTRY(mohawk_cache_fns)
 	.long	mohawk_coherent_kern_range
 	.long	mohawk_coherent_user_range
 	.long	mohawk_flush_kern_dcache_area
-	.long	mohawk_dma_inv_range
-	.long	mohawk_dma_clean_range
+	.long	mohawk_dma_map_area
+	.long	mohawk_dma_unmap_area
 	.long	mohawk_dma_flush_range
 
 ENTRY(cpu_mohawk_dcache_clean_area)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/proc-sa1100.S linux-libre-2.6.34-gnu1/arch/arm/mm/proc-sa1100.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/proc-sa1100.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/proc-sa1100.S	2010-05-16 17:17:36.000000000 -0400
@@ -45,7 +45,7 @@ ENTRY(cpu_sa1100_proc_init)
 	mcr	p15, 0, r0, c9, c0, 5		@ Allow read-buffer operations from userland
 	mov	pc, lr
 
-	.previous
+	.section .text
 
 /*
  * cpu_sa1100_proc_fin()
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/proc-xsc3.S linux-libre-2.6.34-gnu1/arch/arm/mm/proc-xsc3.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/proc-xsc3.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/proc-xsc3.S	2010-05-16 17:17:36.000000000 -0400
@@ -257,7 +257,7 @@ ENTRY(xsc3_flush_kern_dcache_area)
  *	- start  - virtual start address
  *	- end	 - virtual end address
  */
-ENTRY(xsc3_dma_inv_range)
+xsc3_dma_inv_range:
 	tst	r0, #CACHELINESIZE - 1
 	bic	r0, r0, #CACHELINESIZE - 1
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean L1 D line
@@ -278,7 +278,7 @@ ENTRY(xsc3_dma_inv_range)
  *	- start  - virtual start address
  *	- end	 - virtual end address
  */
-ENTRY(xsc3_dma_clean_range)
+xsc3_dma_clean_range:
 	bic	r0, r0, #CACHELINESIZE - 1
 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean L1 D line
 	add	r0, r0, #CACHELINESIZE
@@ -304,6 +304,30 @@ ENTRY(xsc3_dma_flush_range)
 	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(xsc3_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	xsc3_dma_clean_range
+	bcs	xsc3_dma_inv_range
+	b	xsc3_dma_flush_range
+ENDPROC(xsc3_dma_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(xsc3_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(xsc3_dma_unmap_area)
+
 ENTRY(xsc3_cache_fns)
 	.long	xsc3_flush_kern_cache_all
 	.long	xsc3_flush_user_cache_all
@@ -311,8 +335,8 @@ ENTRY(xsc3_cache_fns)
 	.long	xsc3_coherent_kern_range
 	.long	xsc3_coherent_user_range
 	.long	xsc3_flush_kern_dcache_area
-	.long	xsc3_dma_inv_range
-	.long	xsc3_dma_clean_range
+	.long	xsc3_dma_map_area
+	.long	xsc3_dma_unmap_area
 	.long	xsc3_dma_flush_range
 
 ENTRY(cpu_xsc3_dcache_clean_area)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/proc-xscale.S linux-libre-2.6.34-gnu1/arch/arm/mm/proc-xscale.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/proc-xscale.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/proc-xscale.S	2010-05-16 17:17:36.000000000 -0400
@@ -315,7 +315,7 @@ ENTRY(xscale_flush_kern_dcache_area)
  *	- start  - virtual start address
  *	- end	 - virtual end address
  */
-ENTRY(xscale_dma_inv_range)
+xscale_dma_inv_range:
 	tst	r0, #CACHELINESIZE - 1
 	bic	r0, r0, #CACHELINESIZE - 1
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
@@ -336,7 +336,7 @@ ENTRY(xscale_dma_inv_range)
  *	- start  - virtual start address
  *	- end	 - virtual end address
  */
-ENTRY(xscale_dma_clean_range)
+xscale_dma_clean_range:
 	bic	r0, r0, #CACHELINESIZE - 1
 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	add	r0, r0, #CACHELINESIZE
@@ -363,6 +363,43 @@ ENTRY(xscale_dma_flush_range)
 	mcr	p15, 0, r0, c7, c10, 4		@ Drain Write (& Fill) Buffer
 	mov	pc, lr
 
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(xscale_dma_map_area)
+	add	r1, r1, r0
+	cmp	r2, #DMA_TO_DEVICE
+	beq	xscale_dma_clean_range
+	bcs	xscale_dma_inv_range
+	b	xscale_dma_flush_range
+ENDPROC(xscale_dma_map_area)
+
+/*
+ *	dma_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(xscale_dma_a0_map_area)
+	add	r1, r1, r0
+	teq	r2, #DMA_TO_DEVICE
+	beq	xscale_dma_clean_range
+	b	xscale_dma_flush_range
+ENDPROC(xscsale_dma_a0_map_area)
+
+/*
+ *	dma_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(xscale_dma_unmap_area)
+	mov	pc, lr
+ENDPROC(xscale_dma_unmap_area)
+
 ENTRY(xscale_cache_fns)
 	.long	xscale_flush_kern_cache_all
 	.long	xscale_flush_user_cache_all
@@ -370,8 +407,8 @@ ENTRY(xscale_cache_fns)
 	.long	xscale_coherent_kern_range
 	.long	xscale_coherent_user_range
 	.long	xscale_flush_kern_dcache_area
-	.long	xscale_dma_inv_range
-	.long	xscale_dma_clean_range
+	.long	xscale_dma_map_area
+	.long	xscale_dma_unmap_area
 	.long	xscale_dma_flush_range
 
 /*
@@ -394,8 +431,8 @@ ENTRY(xscale_80200_A0_A1_cache_fns)
 	.long	xscale_coherent_kern_range
 	.long	xscale_coherent_user_range
 	.long	xscale_flush_kern_dcache_area
-	.long	xscale_dma_flush_range
-	.long	xscale_dma_clean_range
+	.long	xscale_dma_a0_map_area
+	.long	xscale_dma_unmap_area
 	.long	xscale_dma_flush_range
 
 ENTRY(cpu_xscale_dcache_clean_area)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/mm/tlb-v7.S linux-libre-2.6.34-gnu1/arch/arm/mm/tlb-v7.S
--- linux-libre-2.6.33-gnu1/arch/arm/mm/tlb-v7.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/mm/tlb-v7.S	2010-05-16 17:17:36.000000000 -0400
@@ -50,7 +50,11 @@ ENTRY(v7wbi_flush_user_tlb_range)
 	cmp	r0, r1
 	blo	1b
 	mov	ip, #0
+#ifdef CONFIG_SMP
+	mcr	p15, 0, ip, c7, c1, 6		@ flush BTAC/BTB Inner Shareable
+#else
 	mcr	p15, 0, ip, c7, c5, 6		@ flush BTAC/BTB
+#endif
 	dsb
 	mov	pc, lr
 ENDPROC(v7wbi_flush_user_tlb_range)
@@ -79,7 +83,11 @@ ENTRY(v7wbi_flush_kern_tlb_range)
 	cmp	r0, r1
 	blo	1b
 	mov	r2, #0
+#ifdef CONFIG_SMP
+	mcr	p15, 0, r2, c7, c1, 6		@ flush BTAC/BTB Inner Shareable
+#else
 	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
+#endif
 	dsb
 	isb
 	mov	pc, lr
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/nwfpe/entry.S linux-libre-2.6.34-gnu1/arch/arm/nwfpe/entry.S
--- linux-libre-2.6.33-gnu1/arch/arm/nwfpe/entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/nwfpe/entry.S	2010-05-16 17:17:36.000000000 -0400
@@ -111,12 +111,12 @@ next:
 	@ to fault.  Emit the appropriate exception gunk to fix things up.
 	@ ??? For some reason, faults can happen at .Lx2 even with a
 	@ plain LDR instruction.  Weird, but it seems harmless.
-	.section .fixup,"ax"
+	.pushsection .fixup,"ax"
 	.align	2
 .Lfix:	mov	pc, r9			@ let the user eat segfaults
-	.previous
+	.popsection
 
-	.section __ex_table,"a"
+	.pushsection __ex_table,"a"
 	.align	3
 	.long	.Lx1, .Lfix
-	.previous
+	.popsection
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_arm11_core.c linux-libre-2.6.34-gnu1/arch/arm/oprofile/op_model_arm11_core.c
--- linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_arm11_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/oprofile/op_model_arm11_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -132,7 +132,7 @@ static irqreturn_t arm11_pmu_interrupt(i
 	return IRQ_HANDLED;
 }
 
-int arm11_request_interrupts(int *irqs, int nr)
+int arm11_request_interrupts(const int *irqs, int nr)
 {
 	unsigned int i;
 	int ret = 0;
@@ -153,7 +153,7 @@ int arm11_request_interrupts(int *irqs,
 	return ret;
 }
 
-void arm11_release_interrupts(int *irqs, int nr)
+void arm11_release_interrupts(const int *irqs, int nr)
 {
 	unsigned int i;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_arm11_core.h linux-libre-2.6.34-gnu1/arch/arm/oprofile/op_model_arm11_core.h
--- linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_arm11_core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/oprofile/op_model_arm11_core.h	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,7 @@
 int arm11_setup_pmu(void);
 int arm11_start_pmu(void);
 int arm11_stop_pmu(void);
-int arm11_request_interrupts(int *, int);
-void arm11_release_interrupts(int *, int);
+int arm11_request_interrupts(const int *, int);
+void arm11_release_interrupts(const int *, int);
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_mpcore.c linux-libre-2.6.34-gnu1/arch/arm/oprofile/op_model_mpcore.c
--- linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_mpcore.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/oprofile/op_model_mpcore.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 /* #define DEBUG */
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/sched.h>
 #include <linux/oprofile.h>
 #include <linux/interrupt.h>
@@ -43,6 +44,7 @@
 #include <mach/hardware.h>
 #include <mach/board-eb.h>
 #include <asm/system.h>
+#include <asm/pmu.h>
 
 #include "op_counter.h"
 #include "op_arm_model.h"
@@ -58,6 +60,7 @@
  * Bitmask of used SCU counters
  */
 static unsigned int scu_em_used;
+static const struct pmu_irqs *pmu_irqs;
 
 /*
  * 2 helper fns take a counter number from 0-7 (not the userspace-visible counter number)
@@ -225,33 +228,40 @@ static int em_setup_ctrs(void)
 	return 0;
 }
 
-static int arm11_irqs[] = {
-	[0]	= IRQ_EB11MP_PMU_CPU0,
-	[1]	= IRQ_EB11MP_PMU_CPU1,
-	[2]	= IRQ_EB11MP_PMU_CPU2,
-	[3]	= IRQ_EB11MP_PMU_CPU3
-};
-
 static int em_start(void)
 {
 	int ret;
 
-	ret = arm11_request_interrupts(arm11_irqs, ARRAY_SIZE(arm11_irqs));
+	pmu_irqs = reserve_pmu();
+	if (IS_ERR(pmu_irqs)) {
+		ret = PTR_ERR(pmu_irqs);
+		goto out;
+	}
+
+	ret = arm11_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
 	if (ret == 0) {
 		em_call_function(arm11_start_pmu);
 
 		ret = scu_start();
-		if (ret)
-			arm11_release_interrupts(arm11_irqs, ARRAY_SIZE(arm11_irqs));
+		if (ret) {
+			arm11_release_interrupts(pmu_irqs->irqs,
+						 pmu_irqs->num_irqs);
+		} else {
+			release_pmu(pmu_irqs);
+			pmu_irqs = NULL;
+		}
 	}
+
+out:
 	return ret;
 }
 
 static void em_stop(void)
 {
 	em_call_function(arm11_stop_pmu);
-	arm11_release_interrupts(arm11_irqs, ARRAY_SIZE(arm11_irqs));
+	arm11_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
 	scu_stop();
+	release_pmu(pmu_irqs);
 }
 
 /*
@@ -283,15 +293,7 @@ static int em_setup(void)
 	em_route_irq(IRQ_EB11MP_PMU_SCU6, 3);
 	em_route_irq(IRQ_EB11MP_PMU_SCU7, 3);
 
-	/*
-	 * Send CP15 PMU interrupts to the owner CPU.
-	 */
-	em_route_irq(IRQ_EB11MP_PMU_CPU0, 0);
-	em_route_irq(IRQ_EB11MP_PMU_CPU1, 1);
-	em_route_irq(IRQ_EB11MP_PMU_CPU2, 2);
-	em_route_irq(IRQ_EB11MP_PMU_CPU3, 3);
-
-	return 0;
+	return init_pmu();
 }
 
 struct op_arm_model_spec op_mpcore_spec = {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_v6.c linux-libre-2.6.34-gnu1/arch/arm/oprofile/op_model_v6.c
--- linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_v6.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/oprofile/op_model_v6.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,39 +19,47 @@
 /* #define DEBUG */
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/sched.h>
 #include <linux/oprofile.h>
 #include <linux/interrupt.h>
 #include <asm/irq.h>
 #include <asm/system.h>
+#include <asm/pmu.h>
 
 #include "op_counter.h"
 #include "op_arm_model.h"
 #include "op_model_arm11_core.h"
 
-static int irqs[] = {
-#ifdef CONFIG_ARCH_OMAP2
-	3,
-#endif
-#ifdef CONFIG_ARCH_BCMRING
-	IRQ_PMUIRQ, /* for BCMRING, ARM PMU interrupt is 43 */
-#endif
-};
+static const struct pmu_irqs *pmu_irqs;
 
 static void armv6_pmu_stop(void)
 {
 	arm11_stop_pmu();
-	arm11_release_interrupts(irqs, ARRAY_SIZE(irqs));
+	arm11_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
+	release_pmu(pmu_irqs);
+	pmu_irqs = NULL;
 }
 
 static int armv6_pmu_start(void)
 {
 	int ret;
 
-	ret = arm11_request_interrupts(irqs, ARRAY_SIZE(irqs));
-	if (ret >= 0)
+	pmu_irqs = reserve_pmu();
+	if (IS_ERR(pmu_irqs)) {
+		ret = PTR_ERR(pmu_irqs);
+		goto out;
+	}
+
+	ret = arm11_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
+	if (ret >= 0) {
 		ret = arm11_start_pmu();
+	} else {
+		release_pmu(pmu_irqs);
+		pmu_irqs = NULL;
+	}
 
+out:
 	return ret;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_v7.c linux-libre-2.6.34-gnu1/arch/arm/oprofile/op_model_v7.c
--- linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_v7.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/oprofile/op_model_v7.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,11 +11,14 @@
  */
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/oprofile.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/smp.h>
 
+#include <asm/pmu.h>
+
 #include "op_counter.h"
 #include "op_arm_model.h"
 #include "op_model_v7.h"
@@ -295,7 +298,7 @@ static irqreturn_t armv7_pmnc_interrupt(
 	return IRQ_HANDLED;
 }
 
-int armv7_request_interrupts(int *irqs, int nr)
+int armv7_request_interrupts(const int *irqs, int nr)
 {
 	unsigned int i;
 	int ret = 0;
@@ -318,7 +321,7 @@ int armv7_request_interrupts(int *irqs,
 	return ret;
 }
 
-void armv7_release_interrupts(int *irqs, int nr)
+void armv7_release_interrupts(const int *irqs, int nr)
 {
 	unsigned int i;
 
@@ -362,12 +365,7 @@ static void armv7_pmnc_dump_regs(void)
 }
 #endif
 
-
-static int irqs[] = {
-#ifdef CONFIG_ARCH_OMAP3
-	INT_34XX_BENCH_MPU_EMUL,
-#endif
-};
+static const struct pmu_irqs *pmu_irqs;
 
 static void armv7_pmnc_stop(void)
 {
@@ -375,19 +373,29 @@ static void armv7_pmnc_stop(void)
 	armv7_pmnc_dump_regs();
 #endif
 	armv7_stop_pmnc();
-	armv7_release_interrupts(irqs, ARRAY_SIZE(irqs));
+	armv7_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
+	release_pmu(pmu_irqs);
+	pmu_irqs = NULL;
 }
 
 static int armv7_pmnc_start(void)
 {
 	int ret;
 
+	pmu_irqs = reserve_pmu();
+	if (IS_ERR(pmu_irqs))
+		return PTR_ERR(pmu_irqs);
+
 #ifdef DEBUG
 	armv7_pmnc_dump_regs();
 #endif
-	ret = armv7_request_interrupts(irqs, ARRAY_SIZE(irqs));
-	if (ret >= 0)
+	ret = armv7_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
+	if (ret >= 0) {
 		armv7_start_pmnc();
+	} else {
+		release_pmu(pmu_irqs);
+		pmu_irqs = NULL;
+	}
 
 	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_v7.h linux-libre-2.6.34-gnu1/arch/arm/oprofile/op_model_v7.h
--- linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_v7.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/oprofile/op_model_v7.h	2010-05-16 17:17:36.000000000 -0400
@@ -97,7 +97,7 @@
 int armv7_setup_pmu(void);
 int armv7_start_pmu(void);
 int armv7_stop_pmu(void);
-int armv7_request_interrupts(int *, int);
-void armv7_release_interrupts(int *, int);
+int armv7_request_interrupts(const int *, int);
+void armv7_release_interrupts(const int *, int);
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_xscale.c linux-libre-2.6.34-gnu1/arch/arm/oprofile/op_model_xscale.c
--- linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_xscale.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/oprofile/op_model_xscale.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,12 +17,14 @@
 /* #define DEBUG */
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/sched.h>
 #include <linux/oprofile.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 
 #include <asm/cputype.h>
+#include <asm/pmu.h>
 
 #include "op_counter.h"
 #include "op_arm_model.h"
@@ -33,17 +35,6 @@
 #define	PMU_RESET	(CCNT_RESET | PMN_RESET)
 #define PMU_CNT64	0x008	/* Make CCNT count every 64th cycle */
 
-/* TODO do runtime detection */
-#ifdef CONFIG_ARCH_IOP32X
-#define XSCALE_PMU_IRQ  IRQ_IOP32X_CORE_PMU
-#endif
-#ifdef CONFIG_ARCH_IOP33X
-#define XSCALE_PMU_IRQ  IRQ_IOP33X_CORE_PMU
-#endif
-#ifdef CONFIG_ARCH_PXA
-#define XSCALE_PMU_IRQ  IRQ_PMU
-#endif
-
 /*
  * Different types of events that can be counted by the XScale PMU
  * as used by Oprofile userspace. Here primarily for documentation
@@ -367,6 +358,8 @@ static irqreturn_t xscale_pmu_interrupt(
 	return IRQ_HANDLED;
 }
 
+static const struct pmu_irqs *pmu_irqs;
+
 static void xscale_pmu_stop(void)
 {
 	u32 pmnc = read_pmnc();
@@ -374,20 +367,30 @@ static void xscale_pmu_stop(void)
 	pmnc &= ~PMU_ENABLE;
 	write_pmnc(pmnc);
 
-	free_irq(XSCALE_PMU_IRQ, results);
+	free_irq(pmu_irqs->irqs[0], results);
+	release_pmu(pmu_irqs);
+	pmu_irqs = NULL;
 }
 
 static int xscale_pmu_start(void)
 {
 	int ret;
-	u32 pmnc = read_pmnc();
+	u32 pmnc;
 
-	ret = request_irq(XSCALE_PMU_IRQ, xscale_pmu_interrupt, IRQF_DISABLED,
-			"XScale PMU", (void *)results);
+	pmu_irqs = reserve_pmu();
+	if (IS_ERR(pmu_irqs))
+		return PTR_ERR(pmu_irqs);
+
+	pmnc = read_pmnc();
+
+	ret = request_irq(pmu_irqs->irqs[0], xscale_pmu_interrupt,
+			  IRQF_DISABLED, "XScale PMU", (void *)results);
 
 	if (ret < 0) {
 		printk(KERN_ERR "oprofile: unable to request IRQ%d for XScale PMU\n",
-			XSCALE_PMU_IRQ);
+		       pmu_irqs->irqs[0]);
+		release_pmu(pmu_irqs);
+		pmu_irqs = NULL;
 		return ret;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-iop/io.c linux-libre-2.6.34-gnu1/arch/arm/plat-iop/io.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-iop/io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-iop/io.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,8 @@ void * __iomem __iop3xx_ioremap(unsigned
 		retval = (void *) IOP3XX_PMMR_PHYS_TO_VIRT(cookie);
 		break;
 	default:
-		retval = __arm_ioremap(cookie, size, mtype);
+		retval = __arm_ioremap_caller(cookie, size, mtype,
+				__builtin_return_address(0));
 	}
 
 	return retval;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/audmux-v1.c linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/audmux-v1.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/audmux-v1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/audmux-v1.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,8 +50,18 @@ EXPORT_SYMBOL_GPL(mxc_audmux_v1_configur
 
 static int mxc_audmux_v1_init(void)
 {
-	if (cpu_is_mx27() || cpu_is_mx21())
-		audmux_base = IO_ADDRESS(AUDMUX_BASE_ADDR);
+#ifdef CONFIG_MACH_MX21
+	if (cpu_is_mx21())
+		audmux_base = MX21_IO_ADDRESS(MX21_AUDMUX_BASE_ADDR);
+	else
+#endif
+#ifdef CONFIG_MACH_MX27
+	if (cpu_is_mx27())
+		audmux_base = MX27_IO_ADDRESS(MX27_AUDMUX_BASE_ADDR);
+	else
+#endif
+		(void)0;
+	
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/audmux-v2.c linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/audmux-v2.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/audmux-v2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/audmux-v2.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include <mach/audmux.h>
 #include <mach/hardware.h>
 
@@ -190,7 +191,10 @@ static int mxc_audmux_v2_init(void)
 {
 	int ret;
 
-	if (cpu_is_mx35()) {
+	if (cpu_is_mx31())
+		audmux_base = MX31_IO_ADDRESS(MX31_AUDMUX_BASE_ADDR);
+
+	else if (cpu_is_mx35()) {
 		audmux_clk = clk_get(NULL, "audmux");
 		if (IS_ERR(audmux_clk)) {
 			ret = PTR_ERR(audmux_clk);
@@ -198,11 +202,9 @@ static int mxc_audmux_v2_init(void)
 					ret);
 			return ret;
 		}
+		audmux_base = MX35_IO_ADDRESS(MX35_AUDMUX_BASE_ADDR);
 	}
 
-	if (cpu_is_mx31() || cpu_is_mx35())
-		audmux_base = IO_ADDRESS(AUDMUX_BASE_ADDR);
-
 	audmux_debugfs_init();
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/clock.c linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -56,6 +56,7 @@ static void __clk_disable(struct clk *cl
 	__clk_disable(clk->parent);
 	__clk_disable(clk->secondary);
 
+	WARN_ON(!clk->usecount);
 	if (!(--clk->usecount) && clk->disable)
 		clk->disable(clk);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/dma-mx1-mx2.c linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/dma-mx1-mx2.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/dma-mx1-mx2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/dma-mx1-mx2.c	2010-05-16 17:17:36.000000000 -0400
@@ -128,6 +128,18 @@ struct imx_dma_channel {
 	int hw_chaining;
 };
 
+static void __iomem *imx_dmav1_baseaddr;
+
+static void imx_dmav1_writel(unsigned val, unsigned offset)
+{
+	__raw_writel(val, imx_dmav1_baseaddr + offset);
+}
+
+static unsigned imx_dmav1_readl(unsigned offset)
+{
+	return __raw_readl(imx_dmav1_baseaddr + offset);
+}
+
 static struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
 
 static struct clk *dma_clk;
@@ -140,7 +152,6 @@ static int imx_dma_hw_chain(struct imx_d
 		return 0;
 }
 
-
 /*
  * imx_dma_sg_next - prepare next chunk for scatter-gather DMA emulation
  */
@@ -160,17 +171,17 @@ static inline int imx_dma_sg_next(int ch
 		imxdma->resbytes -= now;
 
 	if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ)
-		__raw_writel(sg->dma_address, DMA_BASE + DMA_DAR(channel));
+		imx_dmav1_writel(sg->dma_address, DMA_DAR(channel));
 	else
-		__raw_writel(sg->dma_address, DMA_BASE + DMA_SAR(channel));
+		imx_dmav1_writel(sg->dma_address, DMA_SAR(channel));
 
-	__raw_writel(now, DMA_BASE + DMA_CNTR(channel));
+	imx_dmav1_writel(now, DMA_CNTR(channel));
 
 	pr_debug("imxdma%d: next sg chunk dst 0x%08x, src 0x%08x, "
 		"size 0x%08x\n", channel,
-		 __raw_readl(DMA_BASE + DMA_DAR(channel)),
-		 __raw_readl(DMA_BASE + DMA_SAR(channel)),
-		 __raw_readl(DMA_BASE + DMA_CNTR(channel)));
+		 imx_dmav1_readl(DMA_DAR(channel)),
+		 imx_dmav1_readl(DMA_SAR(channel)),
+		 imx_dmav1_readl(DMA_CNTR(channel)));
 
 	return now;
 }
@@ -218,27 +229,26 @@ imx_dma_setup_single(int channel, dma_ad
 			channel, __func__, (unsigned int)dma_address,
 			dma_length, dev_addr);
 
-		__raw_writel(dev_addr, DMA_BASE + DMA_SAR(channel));
-		__raw_writel(dma_address, DMA_BASE + DMA_DAR(channel));
-		__raw_writel(imxdma->ccr_from_device,
-				DMA_BASE + DMA_CCR(channel));
+		imx_dmav1_writel(dev_addr, DMA_SAR(channel));
+		imx_dmav1_writel(dma_address, DMA_DAR(channel));
+		imx_dmav1_writel(imxdma->ccr_from_device, DMA_CCR(channel));
 	} else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
 		pr_debug("imxdma%d: %s dma_addressg=0x%08x dma_length=%d "
 			"dev_addr=0x%08x for write\n",
 			channel, __func__, (unsigned int)dma_address,
 			dma_length, dev_addr);
 
-		__raw_writel(dma_address, DMA_BASE + DMA_SAR(channel));
-		__raw_writel(dev_addr, DMA_BASE + DMA_DAR(channel));
-		__raw_writel(imxdma->ccr_to_device,
-				DMA_BASE + DMA_CCR(channel));
+		imx_dmav1_writel(dma_address, DMA_SAR(channel));
+		imx_dmav1_writel(dev_addr, DMA_DAR(channel));
+		imx_dmav1_writel(imxdma->ccr_to_device,
+				DMA_CCR(channel));
 	} else {
 		printk(KERN_ERR "imxdma%d: imx_dma_setup_single bad dmamode\n",
 		       channel);
 		return -EINVAL;
 	}
 
-	__raw_writel(dma_length, DMA_BASE + DMA_CNTR(channel));
+	imx_dmav1_writel(dma_length, DMA_CNTR(channel));
 
 	return 0;
 }
@@ -316,17 +326,15 @@ imx_dma_setup_sg(int channel,
 			"dev_addr=0x%08x for read\n",
 			channel, __func__, sg, sgcount, dma_length, dev_addr);
 
-		__raw_writel(dev_addr, DMA_BASE + DMA_SAR(channel));
-		__raw_writel(imxdma->ccr_from_device,
-				DMA_BASE + DMA_CCR(channel));
+		imx_dmav1_writel(dev_addr, DMA_SAR(channel));
+		imx_dmav1_writel(imxdma->ccr_from_device, DMA_CCR(channel));
 	} else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
 		pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d "
 			"dev_addr=0x%08x for write\n",
 			channel, __func__, sg, sgcount, dma_length, dev_addr);
 
-		__raw_writel(dev_addr, DMA_BASE + DMA_DAR(channel));
-		__raw_writel(imxdma->ccr_to_device,
-				DMA_BASE + DMA_CCR(channel));
+		imx_dmav1_writel(dev_addr, DMA_DAR(channel));
+		imx_dmav1_writel(imxdma->ccr_to_device, DMA_CCR(channel));
 	} else {
 		printk(KERN_ERR "imxdma%d: imx_dma_setup_sg bad dmamode\n",
 		       channel);
@@ -360,7 +368,7 @@ imx_dma_config_channel(int channel, unsi
 	imxdma->ccr_from_device = config_port | (config_mem << 2) | dreq;
 	imxdma->ccr_to_device = config_mem | (config_port << 2) | dreq;
 
-	__raw_writel(dmareq, DMA_BASE + DMA_RSSR(channel));
+	imx_dmav1_writel(dmareq, DMA_RSSR(channel));
 
 	return 0;
 }
@@ -368,7 +376,7 @@ EXPORT_SYMBOL(imx_dma_config_channel);
 
 void imx_dma_config_burstlen(int channel, unsigned int burstlen)
 {
-	__raw_writel(burstlen, DMA_BASE + DMA_BLR(channel));
+	imx_dmav1_writel(burstlen, DMA_BLR(channel));
 }
 EXPORT_SYMBOL(imx_dma_config_burstlen);
 
@@ -398,7 +406,7 @@ imx_dma_setup_handlers(int channel,
 	}
 
 	local_irq_save(flags);
-	__raw_writel(1 << channel, DMA_BASE + DMA_DISR);
+	imx_dmav1_writel(1 << channel, DMA_DISR);
 	imxdma->irq_handler = irq_handler;
 	imxdma->err_handler = err_handler;
 	imxdma->data = data;
@@ -462,22 +470,21 @@ void imx_dma_enable(int channel)
 
 	local_irq_save(flags);
 
-	__raw_writel(1 << channel, DMA_BASE + DMA_DISR);
-	__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 |
-		CCR_ACRPT,
-		DMA_BASE + DMA_CCR(channel));
+	imx_dmav1_writel(1 << channel, DMA_DISR);
+	imx_dmav1_writel(imx_dmav1_readl(DMA_DIMR) & ~(1 << channel), DMA_DIMR);
+	imx_dmav1_writel(imx_dmav1_readl(DMA_CCR(channel)) | CCR_CEN |
+		CCR_ACRPT, DMA_CCR(channel));
 
 #ifdef CONFIG_ARCH_MX2
-	if (imxdma->sg && imx_dma_hw_chain(imxdma)) {
+	if ((cpu_is_mx21() || cpu_is_mx27()) &&
+			imxdma->sg && imx_dma_hw_chain(imxdma)) {
 		imxdma->sg = sg_next(imxdma->sg);
 		if (imxdma->sg) {
 			u32 tmp;
 			imx_dma_sg_next(channel, imxdma->sg);
-			tmp = __raw_readl(DMA_BASE + DMA_CCR(channel));
-			__raw_writel(tmp | CCR_RPT | CCR_ACRPT,
-				DMA_BASE + DMA_CCR(channel));
+			tmp = imx_dmav1_readl(DMA_CCR(channel));
+			imx_dmav1_writel(tmp | CCR_RPT | CCR_ACRPT,
+				DMA_CCR(channel));
 		}
 	}
 #endif
@@ -502,11 +509,10 @@ void imx_dma_disable(int channel)
 		del_timer(&imxdma->watchdog);
 
 	local_irq_save(flags);
-	__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));
-	__raw_writel(1 << channel, DMA_BASE + DMA_DISR);
+	imx_dmav1_writel(imx_dmav1_readl(DMA_DIMR) | (1 << channel), DMA_DIMR);
+	imx_dmav1_writel(imx_dmav1_readl(DMA_CCR(channel)) & ~CCR_CEN,
+			DMA_CCR(channel));
+	imx_dmav1_writel(1 << channel, DMA_DISR);
 	imxdma->in_use = 0;
 	local_irq_restore(flags);
 }
@@ -517,7 +523,7 @@ static void imx_dma_watchdog(unsigned lo
 {
 	struct imx_dma_channel *imxdma = &imx_dma_channels[chno];
 
-	__raw_writel(0, DMA_BASE + DMA_CCR(chno));
+	imx_dmav1_writel(0, DMA_CCR(chno));
 	imxdma->in_use = 0;
 	imxdma->sg = NULL;
 
@@ -533,17 +539,17 @@ static irqreturn_t dma_err_handler(int i
 	unsigned int err_mask;
 	int errcode;
 
-	disr = __raw_readl(DMA_BASE + DMA_DISR);
+	disr = imx_dmav1_readl(DMA_DISR);
 
-	err_mask = __raw_readl(DMA_BASE + DMA_DBTOSR) |
-		   __raw_readl(DMA_BASE + DMA_DRTOSR) |
-		   __raw_readl(DMA_BASE + DMA_DSESR)  |
-		   __raw_readl(DMA_BASE + DMA_DBOSR);
+	err_mask = imx_dmav1_readl(DMA_DBTOSR) |
+		   imx_dmav1_readl(DMA_DRTOSR) |
+		   imx_dmav1_readl(DMA_DSESR)  |
+		   imx_dmav1_readl(DMA_DBOSR);
 
 	if (!err_mask)
 		return IRQ_HANDLED;
 
-	__raw_writel(disr & err_mask, DMA_BASE + DMA_DISR);
+	imx_dmav1_writel(disr & err_mask, DMA_DISR);
 
 	for (i = 0; i < IMX_DMA_CHANNELS; i++) {
 		if (!(err_mask & (1 << i)))
@@ -551,20 +557,20 @@ static irqreturn_t dma_err_handler(int i
 		imxdma = &imx_dma_channels[i];
 		errcode = 0;
 
-		if (__raw_readl(DMA_BASE + DMA_DBTOSR) & (1 << i)) {
-			__raw_writel(1 << i, DMA_BASE + DMA_DBTOSR);
+		if (imx_dmav1_readl(DMA_DBTOSR) & (1 << i)) {
+			imx_dmav1_writel(1 << i, DMA_DBTOSR);
 			errcode |= IMX_DMA_ERR_BURST;
 		}
-		if (__raw_readl(DMA_BASE + DMA_DRTOSR) & (1 << i)) {
-			__raw_writel(1 << i, DMA_BASE + DMA_DRTOSR);
+		if (imx_dmav1_readl(DMA_DRTOSR) & (1 << i)) {
+			imx_dmav1_writel(1 << i, DMA_DRTOSR);
 			errcode |= IMX_DMA_ERR_REQUEST;
 		}
-		if (__raw_readl(DMA_BASE + DMA_DSESR) & (1 << i)) {
-			__raw_writel(1 << i, DMA_BASE + DMA_DSESR);
+		if (imx_dmav1_readl(DMA_DSESR) & (1 << i)) {
+			imx_dmav1_writel(1 << i, DMA_DSESR);
 			errcode |= IMX_DMA_ERR_TRANSFER;
 		}
-		if (__raw_readl(DMA_BASE + DMA_DBOSR) & (1 << i)) {
-			__raw_writel(1 << i, DMA_BASE + DMA_DBOSR);
+		if (imx_dmav1_readl(DMA_DBOSR) & (1 << i)) {
+			imx_dmav1_writel(1 << i, DMA_DBOSR);
 			errcode |= IMX_DMA_ERR_BUFFER;
 		}
 		if (imxdma->name && imxdma->err_handler) {
@@ -607,7 +613,7 @@ static void dma_irq_handle_channel(int c
 		if (imxdma->sg) {
 			imx_dma_sg_next(chno, imxdma->sg);
 
-			tmp = __raw_readl(DMA_BASE + DMA_CCR(chno));
+			tmp = imx_dmav1_readl(DMA_CCR(chno));
 
 			if (imx_dma_hw_chain(imxdma)) {
 				/* FIXME: The timeout should probably be
@@ -617,15 +623,13 @@ static void dma_irq_handle_channel(int c
 					jiffies + msecs_to_jiffies(500));
 
 				tmp |= CCR_CEN | CCR_RPT | CCR_ACRPT;
-				__raw_writel(tmp, DMA_BASE +
-						DMA_CCR(chno));
+				imx_dmav1_writel(tmp, DMA_CCR(chno));
 			} else {
-				__raw_writel(tmp & ~CCR_CEN, DMA_BASE +
-						DMA_CCR(chno));
+				imx_dmav1_writel(tmp & ~CCR_CEN, DMA_CCR(chno));
 				tmp |= CCR_CEN;
 			}
 
-			__raw_writel(tmp, DMA_BASE + DMA_CCR(chno));
+			imx_dmav1_writel(tmp, DMA_CCR(chno));
 
 			if (imxdma->prog_handler)
 				imxdma->prog_handler(chno, imxdma->data,
@@ -640,7 +644,7 @@ static void dma_irq_handle_channel(int c
 		}
 	}
 
-	__raw_writel(0, DMA_BASE + DMA_CCR(chno));
+	imx_dmav1_writel(0, DMA_CCR(chno));
 	imxdma->in_use = 0;
 	if (imxdma->irq_handler)
 		imxdma->irq_handler(chno, imxdma->data);
@@ -651,15 +655,16 @@ static irqreturn_t dma_irq_handler(int i
 	int i, disr;
 
 #ifdef CONFIG_ARCH_MX2
-	dma_err_handler(irq, dev_id);
+	if (cpu_is_mx21() || cpu_is_mx27())
+		dma_err_handler(irq, dev_id);
 #endif
 
-	disr = __raw_readl(DMA_BASE + DMA_DISR);
+	disr = imx_dmav1_readl(DMA_DISR);
 
 	pr_debug("imxdma: dma_irq_handler called, disr=0x%08x\n",
 		     disr);
 
-	__raw_writel(disr, DMA_BASE + DMA_DISR);
+	imx_dmav1_writel(disr, DMA_DISR);
 	for (i = 0; i < IMX_DMA_CHANNELS; i++) {
 		if (disr & (1 << i))
 			dma_irq_handle_channel(i);
@@ -699,17 +704,19 @@ int imx_dma_request(int channel, const c
 	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) {
-		imxdma->name = NULL;
-		printk(KERN_CRIT "Can't register IRQ %d for DMA channel %d\n",
-				MXC_INT_DMACH0 + channel, channel);
-		return ret;
+	if (cpu_is_mx21() || cpu_is_mx27()) {
+		ret = request_irq(MX2x_INT_DMACH0 + channel,
+				dma_irq_handler, 0, "DMA", NULL);
+		if (ret) {
+			imxdma->name = NULL;
+			pr_crit("Can't register IRQ %d for DMA channel %d\n",
+					MX2x_INT_DMACH0 + channel, channel);
+			return ret;
+		}
+		init_timer(&imxdma->watchdog);
+		imxdma->watchdog.function = &imx_dma_watchdog;
+		imxdma->watchdog.data = channel;
 	}
-	init_timer(&imxdma->watchdog);
-	imxdma->watchdog.function = &imx_dma_watchdog;
-	imxdma->watchdog.data = channel;
 #endif
 
 	return ret;
@@ -738,7 +745,8 @@ void imx_dma_free(int channel)
 	imxdma->name = NULL;
 
 #ifdef CONFIG_ARCH_MX2
-	free_irq(MXC_INT_DMACH0 + channel, NULL);
+	if (cpu_is_mx21() || cpu_is_mx27())
+		free_irq(MX2x_INT_DMACH0 + channel, NULL);
 #endif
 
 	local_irq_restore(flags);
@@ -796,34 +804,53 @@ static int __init imx_dma_init(void)
 	int ret = 0;
 	int i;
 
+#ifdef CONFIG_ARCH_MX1
+	if (cpu_is_mx1())
+		imx_dmav1_baseaddr = MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR);
+	else
+#endif
+#ifdef CONFIG_MACH_MX21
+	if (cpu_is_mx21())
+		imx_dmav1_baseaddr = MX21_IO_ADDRESS(MX21_DMA_BASE_ADDR);
+	else
+#endif
+#ifdef CONFIG_MACH_MX27
+	if (cpu_is_mx27())
+		imx_dmav1_baseaddr = MX27_IO_ADDRESS(MX27_DMA_BASE_ADDR);
+	else
+#endif
+		BUG();
+
 	dma_clk = clk_get(NULL, "dma");
 	clk_enable(dma_clk);
 
 	/* reset DMA module */
-	__raw_writel(DCR_DRST, DMA_BASE + DMA_DCR);
+	imx_dmav1_writel(DCR_DRST, DMA_DCR);
 
 #ifdef CONFIG_ARCH_MX1
-	ret = request_irq(DMA_INT, dma_irq_handler, 0, "DMA", NULL);
-	if (ret) {
-		printk(KERN_CRIT "Wow!  Can't register IRQ for DMA\n");
-		return ret;
-	}
+	if (cpu_is_mx1()) {
+		ret = request_irq(MX1_DMA_INT, dma_irq_handler, 0, "DMA", NULL);
+		if (ret) {
+			pr_crit("Wow!  Can't register IRQ for DMA\n");
+			return ret;
+		}
 
-	ret = request_irq(DMA_ERR, dma_err_handler, 0, "DMA", NULL);
-	if (ret) {
-		printk(KERN_CRIT "Wow!  Can't register ERRIRQ for DMA\n");
-		free_irq(DMA_INT, NULL);
-		return ret;
+		ret = request_irq(MX1_DMA_ERR, dma_err_handler, 0, "DMA", NULL);
+		if (ret) {
+			pr_crit("Wow!  Can't register ERRIRQ for DMA\n");
+			free_irq(MX1_DMA_INT, NULL);
+			return ret;
+		}
 	}
 #endif
 	/* enable DMA module */
-	__raw_writel(DCR_DEN, DMA_BASE + DMA_DCR);
+	imx_dmav1_writel(DCR_DEN, DMA_DCR);
 
 	/* clear all interrupts */
-	__raw_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_BASE + DMA_DISR);
+	imx_dmav1_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_DISR);
 
 	/* disable interrupts */
-	__raw_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_BASE + DMA_DIMR);
+	imx_dmav1_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_DIMR);
 
 	for (i = 0; i < IMX_DMA_CHANNELS; i++) {
 		imx_dma_channels[i].sg = NULL;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/ehci.c linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/ehci.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/ehci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/ehci.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,25 +25,37 @@
 #define USBCTRL_OTGBASE_OFFSET	0x600
 
 #define MX31_OTG_SIC_SHIFT	29
-#define MX31_OTG_SIC_MASK	(0xf << MX31_OTG_SIC_SHIFT)
+#define MX31_OTG_SIC_MASK	(0x3 << MX31_OTG_SIC_SHIFT)
 #define MX31_OTG_PM_BIT		(1 << 24)
 
 #define MX31_H2_SIC_SHIFT	21
-#define MX31_H2_SIC_MASK	(0xf << MX31_H2_SIC_SHIFT)
+#define MX31_H2_SIC_MASK	(0x3 << MX31_H2_SIC_SHIFT)
 #define MX31_H2_PM_BIT		(1 << 16)
 #define MX31_H2_DT_BIT		(1 << 5)
 
 #define MX31_H1_SIC_SHIFT	13
-#define MX31_H1_SIC_MASK	(0xf << MX31_H1_SIC_SHIFT)
+#define MX31_H1_SIC_MASK	(0x3 << MX31_H1_SIC_SHIFT)
 #define MX31_H1_PM_BIT		(1 << 8)
 #define MX31_H1_DT_BIT		(1 << 4)
 
+#define MX35_OTG_SIC_SHIFT	29
+#define MX35_OTG_SIC_MASK	(0x3 << MX35_OTG_SIC_SHIFT)
+#define MX35_OTG_PM_BIT		(1 << 24)
+
+#define MX35_H1_SIC_SHIFT	21
+#define MX35_H1_SIC_MASK	(0x3 << MX35_H1_SIC_SHIFT)
+#define MX35_H1_PM_BIT		(1 << 8)
+#define MX35_H1_IPPUE_UP_BIT	(1 << 7)
+#define MX35_H1_IPPUE_DOWN_BIT	(1 << 6)
+#define MX35_H1_TLL_BIT		(1 << 5)
+#define MX35_H1_USBTE_BIT	(1 << 4)
+
 int mxc_set_usbcontrol(int port, unsigned int flags)
 {
 	unsigned int v;
-
+#ifdef CONFIG_ARCH_MX3
 	if (cpu_is_mx31()) {
-		v = readl(IO_ADDRESS(MX31_OTG_BASE_ADDR +
+		v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR +
 				     USBCTRL_OTGBASE_OFFSET));
 
 		switch (port) {
@@ -51,15 +63,15 @@ int mxc_set_usbcontrol(int port, unsigne
 			v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
 			v |= (flags & MXC_EHCI_INTERFACE_MASK)
 					<< MX31_OTG_SIC_SHIFT;
-			if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
 				v |= MX31_OTG_PM_BIT;
 
 			break;
 		case 1: /* H1 port */
-			v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT);
+			v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT);
 			v |= (flags & MXC_EHCI_INTERFACE_MASK)
 						<< MX31_H1_SIC_SHIFT;
-			if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
 				v |= MX31_H1_PM_BIT;
 
 			if (!(flags & MXC_EHCI_TTL_ENABLED))
@@ -67,7 +79,7 @@ int mxc_set_usbcontrol(int port, unsigne
 
 			break;
 		case 2:	/* H2 port */
-			v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT);
+			v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT);
 			v |= (flags & MXC_EHCI_INTERFACE_MASK)
 						<< MX31_H2_SIC_SHIFT;
 			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
@@ -77,13 +89,103 @@ int mxc_set_usbcontrol(int port, unsigne
 				v |= MX31_H2_DT_BIT;
 
 			break;
+		default:
+			return -EINVAL;
 		}
 
-		writel(v, IO_ADDRESS(MX31_OTG_BASE_ADDR +
+		writel(v, MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR +
+				     USBCTRL_OTGBASE_OFFSET));
+		return 0;
+	}
+
+	if (cpu_is_mx35()) {
+		v = readl(MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR +
+				     USBCTRL_OTGBASE_OFFSET));
+
+		switch (port) {
+		case 0:	/* OTG port */
+			v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT);
+			v |= (flags & MXC_EHCI_INTERFACE_MASK)
+					<< MX35_OTG_SIC_SHIFT;
+			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+				v |= MX35_OTG_PM_BIT;
+
+			break;
+		case 1: /* H1 port */
+			v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT |
+				MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT);
+			v |= (flags & MXC_EHCI_INTERFACE_MASK)
+						<< MX35_H1_SIC_SHIFT;
+			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+				v |= MX35_H1_PM_BIT;
+
+			if (!(flags & MXC_EHCI_TTL_ENABLED))
+				v |= MX35_H1_TLL_BIT;
+
+			if (flags & MXC_EHCI_INTERNAL_PHY)
+				v |= MX35_H1_USBTE_BIT;
+
+			if (flags & MXC_EHCI_IPPUE_DOWN)
+				v |= MX35_H1_IPPUE_DOWN_BIT;
+
+			if (flags & MXC_EHCI_IPPUE_UP)
+				v |= MX35_H1_IPPUE_UP_BIT;
+
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		writel(v, MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR +
 				     USBCTRL_OTGBASE_OFFSET));
 		return 0;
 	}
+#endif /* CONFIG_ARCH_MX3 */
+#ifdef CONFIG_MACH_MX27
+	if (cpu_is_mx27()) {
+		/* On i.MX27 we can use the i.MX31 USBCTRL bits, they
+		 * are identical
+		 */
+		v = readl(MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR +
+				     USBCTRL_OTGBASE_OFFSET));
+		switch (port) {
+		case 0:	/* OTG port */
+			v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
+			v |= (flags & MXC_EHCI_INTERFACE_MASK)
+					<< MX31_OTG_SIC_SHIFT;
+			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+				v |= MX31_OTG_PM_BIT;
+			break;
+		case 1: /* H1 port */
+			v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT);
+			v |= (flags & MXC_EHCI_INTERFACE_MASK)
+						<< MX31_H1_SIC_SHIFT;
+			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+				v |= MX31_H1_PM_BIT;
+
+			if (!(flags & MXC_EHCI_TTL_ENABLED))
+				v |= MX31_H1_DT_BIT;
+
+			break;
+		case 2:	/* H2 port */
+			v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT);
+			v |= (flags & MXC_EHCI_INTERFACE_MASK)
+						<< MX31_H2_SIC_SHIFT;
+			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+				v |= MX31_H2_PM_BIT;
+
+			if (!(flags & MXC_EHCI_TTL_ENABLED))
+				v |= MX31_H2_DT_BIT;
 
+			break;
+		default:
+			return -EINVAL;
+		}
+		writel(v, MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR +
+				     USBCTRL_OTGBASE_OFFSET));
+		return 0;
+	}
+#endif /* CONFIG_MACH_MX27 */
 	printk(KERN_WARNING
 		"%s() unable to setup USBCONTROL for this CPU\n", __func__);
 	return -EINVAL;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/gpio.c linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/gpio.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -140,16 +140,13 @@ static void mxc_flip_edge(struct mxc_gpi
 	val = __raw_readl(reg);
 	edge = (val >> (bit << 1)) & 3;
 	val &= ~(0x3 << (bit << 1));
-	switch (edge) {
-	case GPIO_INT_HIGH_LEV:
+	if (edge == GPIO_INT_HIGH_LEV) {
 		edge = GPIO_INT_LOW_LEV;
 		pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
-		break;
-	case GPIO_INT_LOW_LEV:
+	} else if (edge == GPIO_INT_LOW_LEV) {
 		edge = GPIO_INT_HIGH_LEV;
 		pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
-		break;
-	default:
+	} else {
 		pr_err("mxc: invalid configuration for GPIO %d: %x\n",
 		       gpio, edge);
 		return;
@@ -157,25 +154,20 @@ static void mxc_flip_edge(struct mxc_gpi
 	__raw_writel(val | (edge << (bit << 1)), reg);
 }
 
-/* handle n interrupts in one status register */
+/* handle 32 interrupts in one status register */
 static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
 {
-	u32 gpio_irq_no;
-
-	gpio_irq_no = port->virtual_irq_start;
-	for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) {
-		u32 gpio = irq_to_gpio(gpio_irq_no);
+	u32 gpio_irq_no_base = port->virtual_irq_start;
 
-		if ((irq_stat & 1) == 0)
-			continue;
+	while (irq_stat != 0) {
+		int irqoffset = fls(irq_stat) - 1;
 
-		BUG_ON(!(irq_desc[gpio_irq_no].handle_irq));
+		if (port->both_edges & (1 << irqoffset))
+			mxc_flip_edge(port, irqoffset);
 
-		if (port->both_edges & (1 << (gpio & 31)))
-			mxc_flip_edge(port, gpio);
+		generic_handle_irq(gpio_irq_no_base + irqoffset);
 
-		irq_desc[gpio_irq_no].handle_irq(gpio_irq_no,
-				&irq_desc[gpio_irq_no]);
+		irq_stat &= ~(1 << irqoffset);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/board-kzmarm11.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/board-kzmarm11.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/board-kzmarm11.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/board-kzmarm11.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,19 +21,19 @@
 /*
  *  KZM-ARM11-01 Board Control Registers on FPGA
  */
-#define KZM_ARM11_CTL1		(CS4_BASE_ADDR + 0x1000)
-#define KZM_ARM11_CTL2		(CS4_BASE_ADDR + 0x1001)
-#define KZM_ARM11_RSW1		(CS4_BASE_ADDR + 0x1002)
-#define KZM_ARM11_BACK_LIGHT	(CS4_BASE_ADDR + 0x1004)
-#define KZM_ARM11_FPGA_REV	(CS4_BASE_ADDR + 0x1008)
-#define KZM_ARM11_7SEG_LED	(CS4_BASE_ADDR + 0x1010)
-#define KZM_ARM11_LEDS		(CS4_BASE_ADDR + 0x1020)
-#define KZM_ARM11_DIPSW2	(CS4_BASE_ADDR + 0x1003)
+#define KZM_ARM11_CTL1		(MX31_CS4_BASE_ADDR + 0x1000)
+#define KZM_ARM11_CTL2		(MX31_CS4_BASE_ADDR + 0x1001)
+#define KZM_ARM11_RSW1		(MX31_CS4_BASE_ADDR + 0x1002)
+#define KZM_ARM11_BACK_LIGHT	(MX31_CS4_BASE_ADDR + 0x1004)
+#define KZM_ARM11_FPGA_REV	(MX31_CS4_BASE_ADDR + 0x1008)
+#define KZM_ARM11_7SEG_LED	(MX31_CS4_BASE_ADDR + 0x1010)
+#define KZM_ARM11_LEDS		(MX31_CS4_BASE_ADDR + 0x1020)
+#define KZM_ARM11_DIPSW2	(MX31_CS4_BASE_ADDR + 0x1003)
 
 /*
  * External UART for touch panel on FPGA
  */
-#define KZM_ARM11_16550		(CS4_BASE_ADDR + 0x1050)
+#define KZM_ARM11_16550		(MX31_CS4_BASE_ADDR + 0x1050)
 
 #endif /* __ARM_ARCH_BOARD_KZM_ARM11_H */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2008 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_BOARD_MX31_3DS_H__
+#define __ASM_ARCH_MXC_BOARD_MX31_3DS_H__
+
+/* Definitions for components on the Debug board */
+
+/* Base address of CPLD controller on the Debug board */
+#define DEBUG_BASE_ADDRESS		CS5_IO_ADDRESS(CS5_BASE_ADDR)
+
+/* LAN9217 ethernet base address */
+#define LAN9217_BASE_ADDR		CS5_BASE_ADDR
+
+/* CPLD config and interrupt base address */
+#define CPLD_ADDR			(DEBUG_BASE_ADDRESS + 0x20000)
+
+/* LED switchs */
+#define CPLD_LED_REG			(CPLD_ADDR + 0x00)
+/* buttons */
+#define CPLD_SWITCH_BUTTONS_REG	(EXPIO_ADDR + 0x08)
+/* status, interrupt */
+#define CPLD_INT_STATUS_REG		(CPLD_ADDR + 0x10)
+#define CPLD_INT_MASK_REG		(CPLD_ADDR + 0x38)
+#define CPLD_INT_RESET_REG		(CPLD_ADDR + 0x20)
+/* magic word for debug CPLD */
+#define CPLD_MAGIC_NUMBER1_REG		(CPLD_ADDR + 0x40)
+#define CPLD_MAGIC_NUMBER2_REG		(CPLD_ADDR + 0x48)
+/* CPLD code version */
+#define CPLD_CODE_VER_REG		(CPLD_ADDR + 0x50)
+/* magic word for debug CPLD */
+#define CPLD_MAGIC_NUMBER3_REG		(CPLD_ADDR + 0x58)
+/* module reset register */
+#define CPLD_MODULE_RESET_REG		(CPLD_ADDR + 0x60)
+/* CPU ID and Personality ID */
+#define CPLD_MCU_BOARD_ID_REG		(CPLD_ADDR + 0x68)
+
+/* CPLD IRQ line for external uart, external ethernet etc */
+#define EXPIO_PARENT_INT	IOMUX_TO_IRQ(MX31_PIN_GPIO1_1)
+
+#define MXC_EXP_IO_BASE		(MXC_BOARD_IRQ_START)
+#define MXC_IRQ_TO_EXPIO(irq)	((irq) - MXC_EXP_IO_BASE)
+
+#define EXPIO_INT_ENET		(MXC_EXP_IO_BASE + 0)
+#define EXPIO_INT_XUART_A	(MXC_EXP_IO_BASE + 1)
+#define EXPIO_INT_XUART_B	(MXC_EXP_IO_BASE + 2)
+#define EXPIO_INT_BUTTON_A	(MXC_EXP_IO_BASE + 3)
+#define EXPIO_INT_BUTTON_B	(MXC_EXP_IO_BASE + 4)
+
+#define MXC_MAX_EXP_IO_LINES	16
+
+#endif /* __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/board-mx31ads.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/board-mx31ads.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/board-mx31ads.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/board-mx31ads.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,7 @@
 #include <mach/hardware.h>
 
 /* Base address of PBC controller */
-#define PBC_BASE_ADDRESS        IO_ADDRESS(CS4_BASE_ADDR)
+#define PBC_BASE_ADDRESS        MX31_CS4_BASE_ADDR_VIRT
 /* Offsets for the PBC Controller register */
 
 /* PBC Board status register offset */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/board-mx31moboard.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/board-mx31moboard.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/board-mx31moboard.h	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@ enum mx31moboard_boards {
 	MX31NOBOARD	= 0,
 	MX31DEVBOARD	= 1,
 	MX31MARXBOT	= 2,
+	MX31SMARTBOT	= 3,
 };
 
 /*
@@ -34,6 +35,7 @@ enum mx31moboard_boards {
 
 extern void mx31moboard_devboard_init(void);
 extern void mx31moboard_marxbot_init(void);
+extern void mx31moboard_smartbot_init(void);
 
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/board-mx31pdk.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/board-mx31pdk.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/board-mx31pdk.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/board-mx31pdk.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,59 +0,0 @@
-/*
- * Copyright 2008 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_BOARD_MX31PDK_H__
-#define __ASM_ARCH_MXC_BOARD_MX31PDK_H__
-
-/* Definitions for components on the Debug board */
-
-/* Base address of CPLD controller on the Debug board */
-#define DEBUG_BASE_ADDRESS		CS5_IO_ADDRESS(CS5_BASE_ADDR)
-
-/* LAN9217 ethernet base address */
-#define LAN9217_BASE_ADDR		CS5_BASE_ADDR
-
-/* CPLD config and interrupt base address */
-#define CPLD_ADDR			(DEBUG_BASE_ADDRESS + 0x20000)
-
-/* LED switchs */
-#define CPLD_LED_REG			(CPLD_ADDR + 0x00)
-/* buttons */
-#define CPLD_SWITCH_BUTTONS_REG	(EXPIO_ADDR + 0x08)
-/* status, interrupt */
-#define CPLD_INT_STATUS_REG		(CPLD_ADDR + 0x10)
-#define CPLD_INT_MASK_REG		(CPLD_ADDR + 0x38)
-#define CPLD_INT_RESET_REG		(CPLD_ADDR + 0x20)
-/* magic word for debug CPLD */
-#define CPLD_MAGIC_NUMBER1_REG		(CPLD_ADDR + 0x40)
-#define CPLD_MAGIC_NUMBER2_REG		(CPLD_ADDR + 0x48)
-/* CPLD code version */
-#define CPLD_CODE_VER_REG		(CPLD_ADDR + 0x50)
-/* magic word for debug CPLD */
-#define CPLD_MAGIC_NUMBER3_REG		(CPLD_ADDR + 0x58)
-/* module reset register */
-#define CPLD_MODULE_RESET_REG		(CPLD_ADDR + 0x60)
-/* CPU ID and Personality ID */
-#define CPLD_MCU_BOARD_ID_REG		(CPLD_ADDR + 0x68)
-
-/* CPLD IRQ line for external uart, external ethernet etc */
-#define EXPIO_PARENT_INT	IOMUX_TO_IRQ(MX31_PIN_GPIO1_1)
-
-#define MXC_EXP_IO_BASE		(MXC_BOARD_IRQ_START)
-#define MXC_IRQ_TO_EXPIO(irq)	((irq) - MXC_EXP_IO_BASE)
-
-#define EXPIO_INT_ENET		(MXC_EXP_IO_BASE + 0)
-#define EXPIO_INT_XUART_A	(MXC_EXP_IO_BASE + 1)
-#define EXPIO_INT_XUART_B	(MXC_EXP_IO_BASE + 2)
-#define EXPIO_INT_BUTTON_A	(MXC_EXP_IO_BASE + 3)
-#define EXPIO_INT_BUTTON_B	(MXC_EXP_IO_BASE + 4)
-
-#define MXC_MAX_EXP_IO_LINES	16
-
-#endif /* __ASM_ARCH_MXC_BOARD_MX31PDK_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/clock.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,13 +26,6 @@
 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;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/common.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/common.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/common.h	2010-05-16 17:17:36.000000000 -0400
@@ -20,14 +20,17 @@ extern void mx25_map_io(void);
 extern void mx27_map_io(void);
 extern void mx31_map_io(void);
 extern void mx35_map_io(void);
+extern void mx51_map_io(void);
 extern void mxc91231_map_io(void);
 extern void mxc_init_irq(void __iomem *);
+extern void tzic_init_irq(void __iomem *);
 extern void mx1_init_irq(void);
 extern void mx21_init_irq(void);
 extern void mx25_init_irq(void);
 extern void mx27_init_irq(void);
 extern void mx31_init_irq(void);
 extern void mx35_init_irq(void);
+extern void mx51_init_irq(void);
 extern void mxc91231_init_irq(void);
 extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
 extern int mx1_clocks_init(unsigned long fref);
@@ -36,6 +39,8 @@ extern int mx25_clocks_init(void);
 extern int mx27_clocks_init(unsigned long fref);
 extern int mx31_clocks_init(unsigned long fref);
 extern int mx35_clocks_init(void);
+extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
+			unsigned long ckih1, unsigned long ckih2);
 extern int mxc91231_clocks_init(unsigned long fref);
 extern int mxc_register_gpios(void);
 extern int mxc_register_device(struct platform_device *pdev, void *data);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  *
  */
+#define IMX_NEEDS_DEPRECATED_SYMBOLS
 
 #ifdef CONFIG_ARCH_MX1
 #include <mach/mx1.h>
@@ -44,15 +45,24 @@
 #define UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
 #endif
 
+#ifdef CONFIG_ARCH_MX5
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#include <mach/mx51.h>
+#define UART_PADDR	MX51_UART1_BASE_ADDR
+#define UART_VADDR	MX51_AIPS1_IO_ADDRESS(MX51_UART1_BASE_ADDR)
+#endif
+
 #ifdef CONFIG_ARCH_MXC91231
 #ifdef UART_PADDR
 #error "CONFIG_DEBUG_LL is incompatible with multiple archs"
 #endif
 #include <mach/mxc91231.h>
 #define UART_PADDR	MXC91231_UART2_BASE_ADDR
-#define UART_VADDR	MXC91231_AIPS1_IO_ADDRESS(MXC91231_UART2_BASE_ADDR)
+#define UART_VADDR	MXC91231_IO_ADDRESS(MXC91231_UART2_BASE_ADDR)
 #endif
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		ldreq	\rx, =UART_PADDR	@ physical
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,13 @@
 #define DMA_MODE_WRITE		1
 #define DMA_MODE_MASK		1
 
-#define DMA_BASE IO_ADDRESS(DMA_BASE_ADDR)
+#define MX1_DMA_REG(offset)	MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR + (offset))
+
+/* DMA Interrupt Mask Register */
+#define MX1_DMA_DIMR		MX1_DMA_REG(0x08)
+
+/* Channel Control Register */
+#define MX1_DMA_CCR(x)		MX1_DMA_REG(0x8c + ((x) << 6))
 
 #define IMX_DMA_MEMSIZE_32	(0 << 4)
 #define IMX_DMA_MEMSIZE_8	(1 << 4)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/entry-macro.S linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/entry-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/entry-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/entry-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
- *  Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *  Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
  */
 
 /*
@@ -18,11 +18,16 @@
 	.endm
 
 	.macro  get_irqnr_preamble, base, tmp
+#ifndef CONFIG_MXC_TZIC
 	ldr	\base, =avic_base
 	ldr	\base, [\base]
 #ifdef CONFIG_MXC_IRQ_PRIOR
 	ldr	r4, [\base, #AVIC_NIMASK]
 #endif
+#elif defined CONFIG_MXC_TZIC
+	ldr	\base, =tzic_base
+	ldr	\base, [\base]
+#endif /* CONFIG_MXC_TZIC */
 	.endm
 
 	.macro  arch_ret_to_user, tmp1, tmp2
@@ -32,6 +37,7 @@
 	@ and returns its number in irqnr
 	@ and returns if an interrupt occured in irqstat
 	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+#ifndef CONFIG_MXC_TZIC
 	@ Load offset & priority of the highest priority
 	@ interrupt pending from AVIC_NIVECSR
 	ldr	\irqstat, [\base, #0x40]
@@ -45,6 +51,32 @@
 	strne	\tmp, [\base, #AVIC_NIMASK]
 	streq	r4, [\base, #AVIC_NIMASK]
 #endif
+#elif defined CONFIG_MXC_TZIC
+	@ Load offset & priority of the highest priority
+	@ interrupt pending.
+	@ 0xD80 is HIPND0 register
+	mov     \irqnr, #0
+	mov     \irqstat, #0x0D80
+1000:
+	ldr     \tmp,   [\irqstat, \base]
+	cmp     \tmp, #0
+	bne     1001f
+	addeq   \irqnr, \irqnr, #32
+	addeq   \irqstat, \irqstat, #4
+	cmp     \irqnr, #128
+	blo     1000b
+	b       2001f
+1001:	mov     \irqstat, #1
+1002:	tst     \tmp, \irqstat
+	bne     2002f
+	movs    \tmp, \tmp, lsr #1
+	addne   \irqnr, \irqnr, #1
+	bne     1002b
+2001:
+	mov  \irqnr, #0
+2002:
+	movs \irqnr, \irqnr
+#endif
 	.endm
 
 	@ irq priority table (not used)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/hardware.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/hardware.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/hardware.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/hardware.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,15 @@
 
 #include <asm/sizes.h>
 
+#define IMX_IO_ADDRESS(addr, module)					\
+	((void __force __iomem *)					\
+	 (((unsigned long)((addr) - (module ## _BASE_ADDR)) < module ## _SIZE) ?\
+	 (addr) - (module ## _BASE_ADDR) + (module ## _BASE_ADDR_VIRT) : 0))
+
+#ifdef CONFIG_ARCH_MX5
+#include <mach/mx51.h>
+#endif
+
 #ifdef CONFIG_ARCH_MX3
 #include <mach/mx3x.h>
 #include <mach/mx31.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,102 +1,14 @@
 /*
-* 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
-#ifdef CONFIG_ARCH_MX25
-# define GPIO_PORT_MAX  3
-#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)
+ * Copyright (C) 2010 Uwe Kleine-Koenig, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __MACH_IOMUX_H__
+#define __MACH_IOMUX_H__
 
+/* This file will go away, please include mach/iomux-mx... directly */
 
 #ifdef CONFIG_ARCH_MX1
 #include <mach/iomux-mx1.h>
@@ -110,25 +22,5 @@
 #include <mach/iomux-mx27.h>
 #endif
 #endif
-#ifdef CONFIG_ARCH_MX25
-#include <mach/iomux-mx25.h>
-#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)
-#define IRQ_GPIOF(x)  (IRQ_GPIOE(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
+#endif /* __MACH_IOMUX_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx1.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx1.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx1.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx1.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,166 +1,155 @@
 /*
-* 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 */
+ * 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 __MACH_IOMUX_MX1_H__
+#define __MACH_IOMUX_MX1_H__
 
-#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)
+#include <mach/iomux-v1.h>
 
+#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
+#endif /* ifndef __MACH_IOMUX_MX1_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx21.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx21.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx21.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx21.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,126 +1,122 @@
 /*
-* 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
+ * 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 __MACH_IOMUX_MX21_H__
+#define __MACH_IOMUX_MX21_H__
 
+#include <mach/iomux-mx2x.h>
+#include <mach/iomux-v1.h>
 
 /* 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)
+#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)
+#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)
+#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)
+#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)
+#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)
-
+#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
+#endif /* ifndef __MACH_IOMUX_MX21_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx25.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx25.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx25.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx25.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,7 @@
  *    Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
  * and
  * arch/arm/plat-mxc/include/mach/iomux-mx35.h
- *    Copyright (C, NO_PAD_CTRL) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de>
+ *    Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de>
  *
  * The code contained herein is licensed under the GNU General Public
  * License. You may obtain a copy of the GNU General Public License
@@ -16,24 +16,11 @@
  * http://www.opensource.org/licenses/gpl-license.html
  * http://www.gnu.org/copyleft/gpl.html
  */
-#ifndef __IOMUX_MX25_H__
-#define __IOMUX_MX25_H__
+#ifndef __MACH_IOMUX_MX25_H__
+#define __MACH_IOMUX_MX25_H__
 
 #include <mach/iomux-v3.h>
 
-#ifndef GPIO_PORTA
-#error Please include mach/iomux.h
-#endif
-
-/*
- *
- * @brief MX25 I/O Pin List
- *
- * @ingroup GPIO_MX25
- */
-
-#ifndef __ASSEMBLY__
-
 /*
  * IOMUX/PAD Bit field definitions
  */
@@ -462,9 +449,11 @@
 #define MX25_PAD_GPIO_C__CAN2_TX	IOMUX_PAD(0x3f8, 0x1fc, 0x16, 0, 0, PAD_CTL_PUS_22K_UP)
 
 #define MX25_PAD_GPIO_D__GPIO_D		IOMUX_PAD(0x3fc, 0x200, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_E__LD16		IOMUX_PAD(0x400, 0x204, 0x02, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_GPIO_D__CAN2_RX	IOMUX_PAD(0x3fc, 0x200, 0x16, 0x484, 1, PAD_CTL_PUS_22K_UP)
 
 #define MX25_PAD_GPIO_E__GPIO_E		IOMUX_PAD(0x400, 0x204, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_F__LD17		IOMUX_PAD(0x404, 0x208, 0x02, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_GPIO_E__AUD7_TXD	IOMUX_PAD(0x400, 0x204, 0x14, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_GPIO_F__GPIO_F		IOMUX_PAD(0x404, 0x208, 0x10, 0, 0, NO_PAD_CTRL)
@@ -513,5 +502,4 @@
 #define MX25_PAD_CTL_GRP_DVS_SDHC1	IOMUX_PAD(0x458, 0x000, 0, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_CTL_GRP_DVS_LCD	IOMUX_PAD(0x45c, 0x000, 0, 0, 0, NO_PAD_CTRL)
 
-#endif // __ASSEMBLY__
-#endif // __IOMUX_MX25_H__
+#endif /* __MACH_IOMUX_MX25_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx27.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx27.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx27.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx27.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,207 +1,205 @@
 /*
-* 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
+ * 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 __MACH_IOMUX_MX27_H__
+#define __MACH_IOMUX_MX27_H__
 
+#include <mach/iomux-mx2x.h>
+#include <mach/iomux-v1.h>
 
 /* 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)
+#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 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)
+#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 PC25_AF_GPT5_TIN	(GPIO_PORTC | GPIO_AF | 25)
+#define PC26_AF_GPT4_TOUT	(GPIO_PORTC | GPIO_AF | 26)
+#define PC27_AF_GPT4_TIN	(GPIO_PORTC | GPIO_AF | 27)
+#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)
+#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)
+#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)
+#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 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)
+/* BOUT GPIO pin functions */
 
+#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 */
+#endif /* __MACH_IOMUX_MX27_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx2x.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx2x.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx2x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx2x.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,237 +1,230 @@
 /*
-* 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
-
+ * 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 __MACH_IOMUX_MX2x_H__
+#define __MACH_IOMUX_MX2x_H__
 
 /* 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)
+#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)
+#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)
+#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)
+#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)
+#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 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)
-
+#define PC15_AOUT_WKGD		(GPIO_PORTC | GPIO_AOUT | GPIO_IN | 15)
+#define PF21_AOUT_DTACK		(GPIO_PORTF | GPIO_AOUT | GPIO_IN | 21)
 
-#endif
+#endif /* ifndef __MACH_IOMUX_MX2x_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx35.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx35.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx35.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx35.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C, NO_PAD_CTRL) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de>
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx3.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx3.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx3.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx3.h	2010-05-16 17:17:36.000000000 -0400
@@ -16,12 +16,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA 02110-1301, USA.
  */
-
-#ifndef __MACH_MX31_IOMUX_H__
-#define __MACH_MX31_IOMUX_H__
+#ifndef __MACH_IOMUX_MX3_H__
+#define __MACH_IOMUX_MX3_H__
 
 #include <linux/types.h>
-
 /*
  * various IOMUX output functions
  */
@@ -34,7 +32,7 @@
 #define	IOMUX_OCONFIG_ALT4 (5 << 4)	/* used as alternate function 4 */
 #define	IOMUX_OCONFIG_ALT5 (6 << 4)	/* used as alternate function 5 */
 #define	IOMUX_OCONFIG_ALT6 (7 << 4)	/* used as alternate function 6 */
-#define	IOMUX_ICONFIG_NONE  0	 	/* not configured for input */
+#define	IOMUX_ICONFIG_NONE  0		/* not configured for input */
 #define	IOMUX_ICONFIG_GPIO  1		/* used as GPIO */
 #define	IOMUX_ICONFIG_FUNC  2		/* used as function */
 #define	IOMUX_ICONFIG_ALT1  4		/* used as alternate function 1 */
@@ -167,11 +165,6 @@ int mxc_iomux_mode(unsigned int pin_mode
 	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.
@@ -633,40 +626,40 @@ enum iomux_pins {
 #define MX31_PIN_TXD2__GPIO1_28		IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_CSI_D4__GPIO3_4	IOMUX_MODE(MX31_PIN_CSI_D4, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_CSI_D5__GPIO3_5	IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_GPIO)
-#define MX31_PIN_USBOTG_DATA0__USBOTG_DATA0    IOMUX_MODE(MX31_PIN_USBOTG_DATA0, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBOTG_DATA1__USBOTG_DATA1    IOMUX_MODE(MX31_PIN_USBOTG_DATA1, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBOTG_DATA2__USBOTG_DATA2    IOMUX_MODE(MX31_PIN_USBOTG_DATA2, IOMUX_CONFIG_FUNC)
-#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)
-#define MX31_PIN_CSPI1_MOSI__USBH1_RXDM        IOMUX_MODE(MX31_PIN_CSPI1_MOSI, IOMUX_CONFIG_ALT1)
-#define MX31_PIN_CSPI1_MISO__USBH1_RXDP        IOMUX_MODE(MX31_PIN_CSPI1_MISO, IOMUX_CONFIG_ALT1)
-#define MX31_PIN_CSPI1_SS0__USBH1_TXDM         IOMUX_MODE(MX31_PIN_CSPI1_SS0,  IOMUX_CONFIG_ALT1)
-#define MX31_PIN_CSPI1_SS1__USBH1_TXDP         IOMUX_MODE(MX31_PIN_CSPI1_SS1,  IOMUX_CONFIG_ALT1)
-#define MX31_PIN_CSPI1_SS2__USBH1_RCV          IOMUX_MODE(MX31_PIN_CSPI1_SS2,  IOMUX_CONFIG_ALT1)
-#define MX31_PIN_CSPI1_SCLK__USBH1_OEB         IOMUX_MODE(MX31_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT1)
-#define MX31_PIN_CSPI1_SPI_RDY__USBH1_FS       IOMUX_MODE(MX31_PIN_CSPI1_SPI_RDY, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_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)
+#define MX31_PIN_CSPI1_MOSI__USBH1_RXDM		IOMUX_MODE(MX31_PIN_CSPI1_MOSI, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_MISO__USBH1_RXDP		IOMUX_MODE(MX31_PIN_CSPI1_MISO, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SS0__USBH1_TXDM		IOMUX_MODE(MX31_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SS1__USBH1_TXDP		IOMUX_MODE(MX31_PIN_CSPI1_SS1, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SS2__USBH1_RCV		IOMUX_MODE(MX31_PIN_CSPI1_SS2, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SCLK__USBH1_OEB		IOMUX_MODE(MX31_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SPI_RDY__USBH1_FS	IOMUX_MODE(MX31_PIN_CSPI1_SPI_RDY, IOMUX_CONFIG_ALT1)
 #define MX31_PIN_SFS6__USBH1_SUSPEND	IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_NFRE_B__GPIO1_11	IOMUX_MODE(MX31_PIN_NFRE_B, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_NFALE__GPIO1_12	IOMUX_MODE(MX31_PIN_NFALE, IOMUX_CONFIG_GPIO)
-#define MX31_PIN_USBH2_DATA0__USBH2_DATA0      IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBH2_DATA1__USBH2_DATA1      IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_DATA0__USBH2_DATA0	IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_DATA1__USBH2_DATA1	IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_STXD3__USBH2_DATA2	IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_SRXD3__USBH2_DATA3	IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_SCK3__USBH2_DATA4	IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_SFS3__USBH2_DATA5	IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_STXD6__USBH2_DATA6	IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_SRXD6__USBH2_DATA7	IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBH2_CLK__USBH2_CLK          IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBH2_DIR__USBH2_DIR          IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBH2_NXT__USBH2_NXT          IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBH2_STP__USBH2_STP          IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_CLK__USBH2_CLK		IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_DIR__USBH2_DIR		IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_NXT__USBH2_NXT		IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_STP__USBH2_STP		IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_SCK6__GPIO1_25		IOMUX_MODE(MX31_PIN_SCK6, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_USB_OC__GPIO1_30	IOMUX_MODE(MX31_PIN_USB_OC, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_I2C_DAT__I2C1_SDA	IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC)
@@ -711,8 +704,8 @@ enum iomux_pins {
 #define MX31_PIN_DSR_DCE1__GPIO2_9	IOMUX_MODE(MX31_PIN_DSR_DCE1, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_RI_DCE1__GPIO2_10	IOMUX_MODE(MX31_PIN_RI_DCE1, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_DCD_DCE1__GPIO2_11	IOMUX_MODE(MX31_PIN_DCD_DCE1, IOMUX_CONFIG_GPIO)
-#define MX31_PIN_STXD5__GPIO1_21       IOMUX_MODE(MX31_PIN_STXD5, IOMUX_CONFIG_GPIO)
-#define MX31_PIN_SRXD5__GPIO1_22       IOMUX_MODE(MX31_PIN_SRXD5, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_STXD5__GPIO1_21	IOMUX_MODE(MX31_PIN_STXD5, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_SRXD5__GPIO1_22	IOMUX_MODE(MX31_PIN_SRXD5, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_GPIO1_3__GPIO1_3	IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_CSPI2_SS1__CSPI3_SS1	IOMUX_MODE(MX31_PIN_CSPI2_SS1, IOMUX_CONFIG_ALT1)
 #define MX31_PIN_RTS1__GPIO2_6		IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_GPIO)
@@ -727,13 +720,14 @@ enum iomux_pins {
 #define MX31_PIN_SCK5__SCK5		IOMUX_MODE(MX31_PIN_SCK5, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_SFS5__SFS5		IOMUX_MODE(MX31_PIN_SFS5, IOMUX_CONFIG_FUNC)
 
-/*XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed by cspi2_ss0, cspi2_ss1, cspi1_ss0
- * cspi1_ss1*/
+/*
+ * XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed with cspi2_ss0,
+ * cspi2_ss1, cspi1_ss0 cspi1_ss1
+ */
 
 /*
  * This function configures the pad value for a IOMUX pin.
  */
 void mxc_iomux_set_pad(enum iomux_pins, u32);
 
-#endif
-
+#endif /* ifndef __MACH_IOMUX_MX3_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx51.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx51.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx51.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx51.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __MACH_IOMUX_MX51_H__
+#define __MACH_IOMUX_MX51_H__
+
+#include <mach/iomux-v3.h>
+
+/*
+ * various IOMUX alternate output functions (1-7)
+ */
+typedef enum iomux_config {
+	IOMUX_CONFIG_ALT0,
+	IOMUX_CONFIG_ALT1,
+	IOMUX_CONFIG_ALT2,
+	IOMUX_CONFIG_ALT3,
+	IOMUX_CONFIG_ALT4,
+	IOMUX_CONFIG_ALT5,
+	IOMUX_CONFIG_ALT6,
+	IOMUX_CONFIG_ALT7,
+	IOMUX_CONFIG_GPIO,	/* added to help user use GPIO mode */
+	IOMUX_CONFIG_SION = 0x1 << 4,	/* LOOPBACK:MUX SION bit */
+} iomux_pin_cfg_t;
+
+/* Pad control groupings */
+#define MX51_UART1_PAD_CTRL	(PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+				PAD_CTL_DSE_HIGH)
+#define MX51_UART2_PAD_CTRL	(PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_DSE_HIGH | \
+				PAD_CTL_SRE_FAST)
+#define MX51_UART3_PAD_CTRL	(PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
+				PAD_CTL_SRE_FAST)
+
+/*
+ * The naming convention for the pad modes is MX51_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named
+ * GPIO_<unit>_<num> see also iomux-v3.h
+ */
+
+/*
+ * FIXME: This was converted using scripts from existing Freescale code to
+ * this form used upstream. Need to verify the name format.
+ */
+
+/*						PAD      MUX   ALT INPSE PATH PADCTRL */
+
+#define MX51_PAD_GPIO_2_0__EIM_D16	IOMUX_PAD(0x3f0, 0x05c, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_1__EIM_D17	IOMUX_PAD(0x3f4, 0x060, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_2__EIM_D18	IOMUX_PAD(0x3f8, 0x064, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_3__EIM_D19	IOMUX_PAD(0x3fc, 0x068, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_4__EIM_D20	IOMUX_PAD(0x400, 0x06c, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_5__EIM_D21	IOMUX_PAD(0x404, 0x070, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_6__EIM_D22	IOMUX_PAD(0x408, 0x074, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_7__EIM_D23	IOMUX_PAD(0x40c, 0x078, 1, 0x0,   0, NO_PAD_CTRL)
+
+/* Babbage UART3 */
+#define MX51_PAD_EIM_D24__UART3_CTS	IOMUX_PAD(0x410, 0x07c, IOMUX_CONFIG_ALT3, 0x0, 0, MX51_UART3_PAD_CTRL)
+#define MX51_PAD_EIM_D25__UART3_RXD	IOMUX_PAD(0x414, 0x080, IOMUX_CONFIG_ALT3, 0x9f4, 0, MX51_UART3_PAD_CTRL)
+#define MX51_PAD_EIM_D26__UART3_TXD	IOMUX_PAD(0x418, 0x084, IOMUX_CONFIG_ALT3, 0x0, 0, MX51_UART3_PAD_CTRL)
+#define MX51_PAD_EIM_D27__UART3_RTS	IOMUX_PAD(0x41c, 0x088, IOMUX_CONFIG_ALT3, 0x9f0, 0, MX51_UART3_PAD_CTRL)
+
+#define MX51_PAD_EIM_D28__EIM_D28	IOMUX_PAD(0x420, 0x08c, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D29__EIM_D29	IOMUX_PAD(0x424, 0x090, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D30__EIM_D30	IOMUX_PAD(0x428, 0x094, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D31__EIM_D31	IOMUX_PAD(0x42c, 0x09c, 0, 0x0,   0, NO_PAD_CTRL)
+
+#define MX51_PAD_GPIO_2_10__EIM_A16	IOMUX_PAD(0x430, 0x09c, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_11__EIM_A17	IOMUX_PAD(0x434, 0x0a0, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_12__EIM_A18	IOMUX_PAD(0x438, 0x0a4, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_13__EIM_A19	IOMUX_PAD(0x43c, 0x0a8, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_14__EIM_A20	IOMUX_PAD(0x440, 0x0ac, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_15__EIM_A21	IOMUX_PAD(0x444, 0x0b0, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_16__EIM_A22	IOMUX_PAD(0x448, 0x0b4, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_17__EIM_A23	IOMUX_PAD(0x44c, 0x0b8, 1, 0x0,   0, NO_PAD_CTRL)
+
+#define MX51_PAD_GPIO_2_18__EIM_A24	IOMUX_PAD(0x450, 0x0bc, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_19__EIM_A25	IOMUX_PAD(0x454, 0x0c0, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_20__EIM_A26	IOMUX_PAD(0x458, 0x0c4, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_21__EIM_A27	IOMUX_PAD(0x45c, 0x0c8, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB0__EIM_EB0	IOMUX_PAD(0x460, 0x0cc, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB1__EIM_EB1	IOMUX_PAD(0x464, 0x0d0, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_22__EIM_EB2	IOMUX_PAD(0x468, 0x0d4, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_23__EIM_EB3	IOMUX_PAD(0x46c, 0x0d8, 1, 0x0,   0, NO_PAD_CTRL)
+
+#define MX51_PAD_GPIO_2_24__EIM_OE	IOMUX_PAD(0x470, 0x0dc, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_25__EIM_CS0	IOMUX_PAD(0x474, 0x0e0, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_26__EIM_CS1	IOMUX_PAD(0x478, 0x0e4, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_27__EIM_CS2	IOMUX_PAD(0x47c, 0x0e8, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_28__EIM_CS3	IOMUX_PAD(0x480, 0x0ec, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_29__EIM_CS4	IOMUX_PAD(0x484, 0x0f0, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_30__EIM_CS5	IOMUX_PAD(0x488, 0x0f4, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_31__EIM_DTACK	IOMUX_PAD(0x48c, 0x0f8, 1, 0x0,   0, NO_PAD_CTRL)
+
+#define MX51_PAD_GPIO_3_1__EIM_LBA	IOMUX_PAD(0x494, 0xFC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_2__EIM_CRE	IOMUX_PAD(0x4A0, 0x100, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DRAM_CS1__DRAM_CS1	IOMUX_PAD(0x4D0, 0x104, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_3__NANDF_WE_B	IOMUX_PAD(0x4E4, 0x108, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_4__NANDF_RE_B	IOMUX_PAD(0x4E8, 0x10C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_5__NANDF_ALE	IOMUX_PAD(0x4EC, 0x110, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_6__NANDF_CLE	IOMUX_PAD(0x4F0, 0x114, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_7__NANDF_WP_B	IOMUX_PAD(0x4F4, 0x118, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_8__NANDF_RB0	IOMUX_PAD(0x4F8, 0x11C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_9__NANDF_RB1	IOMUX_PAD(0x4FC, 0x120, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_10__NANDF_RB2	IOMUX_PAD(0x500, 0x124, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_11__NANDF_RB3	IOMUX_PAD(0x504, 0x128, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_12__GPIO_NAND	IOMUX_PAD(0x514, 0x12C, 3, 0x0, 0, NO_PAD_CTRL)
+/* REVISIT: Not sure of these values
+
+  #define MX51_PAD_GPIO_1___NANDF_RB4	IOMUX_PAD(, , , 0x0, 0, NO_PAD_CTRL)
+  #define MX51_PAD_GPIO_3_13__NANDF_RB5	IOMUX_PAD(0x5D8, 0x130, 3, 0x0, 0, NO_PAD_CTRL)
+  #define MX51_PAD_GPIO_3_15__NANDF_RB7	IOMUX_PAD(0x5E0, 0x138, 3, 0x0, 0, NO_PAD_CTRL)
+*/
+#define MX51_PAD_GPIO_3_14__NANDF_RB6	IOMUX_PAD(0x5DC, 0x134, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_16__NANDF_CS0	IOMUX_PAD(0x518, 0x130, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_17__NANDF_CS1	IOMUX_PAD(0x51C, 0x134, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_18__NANDF_CS2	IOMUX_PAD(0x520, 0x138, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_19__NANDF_CS3	IOMUX_PAD(0x524, 0x13C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_20__NANDF_CS4	IOMUX_PAD(0x528, 0x140, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_21__NANDF_CS5	IOMUX_PAD(0x52C, 0x144, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_22__NANDF_CS6	IOMUX_PAD(0x530, 0x148, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_23__NANDF_CS7	IOMUX_PAD(0x534, 0x14C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_24__NANDF_RDY_INT	IOMUX_PAD(0x538, 0x150, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_25__NANDF_D15	IOMUX_PAD(0x53C, 0x154, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_26__NANDF_D14	IOMUX_PAD(0x540, 0x158, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_27__NANDF_D13	IOMUX_PAD(0x544, 0x15C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_28__NANDF_D12	IOMUX_PAD(0x548, 0x160, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_29__NANDF_D11	IOMUX_PAD(0x54C, 0x164, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_30__NANDF_D10	IOMUX_PAD(0x550, 0x168, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_31__NANDF_D9	IOMUX_PAD(0x554, 0x16C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_0__NANDF_D8	IOMUX_PAD(0x558, 0x170, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_1__NANDF_D7	IOMUX_PAD(0x55C, 0x174, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_2__NANDF_D6	IOMUX_PAD(0x560, 0x178, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_3__NANDF_D5	IOMUX_PAD(0x564, 0x17C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_4__NANDF_D4	IOMUX_PAD(0x568, 0x180, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_5__NANDF_D3	IOMUX_PAD(0x56C, 0x184, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_6__NANDF_D2	IOMUX_PAD(0x570, 0x188, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_7__NANDF_D1	IOMUX_PAD(0x574, 0x18C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_8__NANDF_D0	IOMUX_PAD(0x578, 0x190, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_12__CSI1_D8	IOMUX_PAD(0x57C, 0x194, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_13__CSI1_D9	IOMUX_PAD(0x580, 0x198, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D10__CSI1_D10	IOMUX_PAD(0x584, 0x19C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D11__CSI1_D11	IOMUX_PAD(0x588, 0x1A0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D12__CSI1_D12	IOMUX_PAD(0x58C, 0x1A4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D13__CSI1_D13	IOMUX_PAD(0x590, 0x1A8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D14__CSI1_D14	IOMUX_PAD(0x594, 0x1AC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D15__CSI1_D15	IOMUX_PAD(0x598, 0x1B0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D16__CSI1_D16	IOMUX_PAD(0x59C, 0x1B4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D17__CSI1_D17	IOMUX_PAD(0x5A0, 0x1B8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D18__CSI1_D18	IOMUX_PAD(0x5A4, 0x1BC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D19__CSI1_D19	IOMUX_PAD(0x5A8, 0x1C0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_VSYNC__CSI1_VSYNC	IOMUX_PAD(0x5AC, 0x1C4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_HSYNC__CSI1_HSYNC	IOMUX_PAD(0x5B0, 0x1C8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK	IOMUX_PAD(0x5B4, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_MCLK__CSI1_MCLK	IOMUX_PAD(0x5B8, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_PKE0__CSI1_PKE0	IOMUX_PAD(0x860, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_9__CSI2_D12	IOMUX_PAD(0x5BC, 0x1CC, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_10__CSI2_D13	IOMUX_PAD(0x5C0, 0x1D0, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_11__CSI2_D14	IOMUX_PAD(0x5C4, 0x1D4, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_12__CSI2_D15	IOMUX_PAD(0x5C8, 0x1D8, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_11__CSI2_D16	IOMUX_PAD(0x5CC, 0x1DC, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_12__CSI2_D17	IOMUX_PAD(0x5D0, 0x1E0, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_11__CSI2_D18	IOMUX_PAD(0x5D4, 0x1E4, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_12__CSI2_D19	IOMUX_PAD(0x5D8, 0x1E8, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_13__CSI2_VSYNC	IOMUX_PAD(0x5DC, 0x1EC, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_14__CSI2_HSYNC	IOMUX_PAD(0x5E0, 0x1F0, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_15__CSI2_PIXCLK	IOMUX_PAD(0x5E4, 0x1F4, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_PKE0__CSI2_PKE0	IOMUX_PAD(0x81C, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_16__I2C1_CLK	IOMUX_PAD(0x5E8, 0x1F8, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_17__I2C1_DAT	IOMUX_PAD(0x5EC, 0x1FC, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_18__AUD3_BB_TXD	IOMUX_PAD(0x5F0, 0x200, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_19__AUD3_BB_RXD	IOMUX_PAD(0x5F4, 0x204, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_20__AUD3_BB_CK	IOMUX_PAD(0x5F8, 0x208, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_21__AUD3_BB_FS	IOMUX_PAD(0x5FC, 0x20C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_22__CSPI1_MOSI	IOMUX_PAD(0x600, 0x210, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_23__CSPI1_MISO	IOMUX_PAD(0x604, 0x214, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_24__CSPI1_SS0	IOMUX_PAD(0x608, 0x218, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_25__CSPI1_SS1	IOMUX_PAD(0x60C, 0x21C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_26__CSPI1_RDY	IOMUX_PAD(0x610, 0x220, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_27__CSPI1_SCLK	IOMUX_PAD(0x614, 0x224, 3, 0x0, 0, NO_PAD_CTRL)
+
+/* Babbage UART1 */
+#define MX51_PAD_UART1_RXD__UART1_RXD	IOMUX_PAD(0x618, 0x228,	IOMUX_CONFIG_ALT0, 0x9e4, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
+#define MX51_PAD_UART1_TXD__UART1_TXD	IOMUX_PAD(0x61C, 0x22C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
+#define MX51_PAD_UART1_RTS__UART1_RTS	IOMUX_PAD(0x620, 0x230, IOMUX_CONFIG_ALT0, 0x9e0, 0, MX51_UART1_PAD_CTRL)
+#define MX51_PAD_UART1_CTS__UART1_CTS	IOMUX_PAD(0x624, 0x234, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_UART1_PAD_CTRL)
+
+/* Babbage UART2 */
+#define MX51_PAD_UART2_RXD__UART2_RXD	IOMUX_PAD(0x628, 0x238, IOMUX_CONFIG_ALT0, 0x9ec, 2, MX51_UART2_PAD_CTRL)
+#define MX51_PAD_UART2_TXD__UART2_TXD	IOMUX_PAD(0x62C, 0x23C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_UART2_PAD_CTRL)
+
+#define MX51_PAD_GPIO_1_22__UART3_RXD	IOMUX_PAD(0x630, 0x240, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_23__UART3_TXD	IOMUX_PAD(0x634, 0x244, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_24__OWIRE_LINE	IOMUX_PAD(0x638, 0x248, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW0__KEY_ROW0	IOMUX_PAD(0x63C, 0x24C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW1__KEY_ROW1	IOMUX_PAD(0x640, 0x250, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW2__KEY_ROW2	IOMUX_PAD(0x644, 0x254, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW3__KEY_ROW3	IOMUX_PAD(0x648, 0x258, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL0__KEY_COL0	IOMUX_PAD(0x64C, 0x25C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL1__KEY_COL1	IOMUX_PAD(0x650, 0x260, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL2__KEY_COL2	IOMUX_PAD(0x654, 0x264, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL3__KEY_COL3	IOMUX_PAD(0x658, 0x268, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL4__KEY_COL4	IOMUX_PAD(0x65C, 0x26C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL5__KEY_COL5	IOMUX_PAD(0x660, 0x270, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_25__USBH1_CLK	IOMUX_PAD(0x678, 0x278, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_26__USBH1_DIR	IOMUX_PAD(0x67C, 0x27C, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_27__USBH1_STP	IOMUX_PAD(0x680, 0x280, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_28__USBH1_NXT	IOMUX_PAD(0x684, 0x284, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_11__USBH1_DATA0	IOMUX_PAD(0x688, 0x288, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_12__USBH1_DATA1	IOMUX_PAD(0x68C, 0x28C, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_13__USBH1_DATA2	IOMUX_PAD(0x690, 0x290, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_14__USBH1_DATA3	IOMUX_PAD(0x694, 0x294, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_15__USBH1_DATA4	IOMUX_PAD(0x698, 0x298, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_16__USBH1_DATA5	IOMUX_PAD(0x69C, 0x29C, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_17__USBH1_DATA6	IOMUX_PAD(0x6A0, 0x2A0, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_18__USBH1_DATA7	IOMUX_PAD(0x6A4, 0x2A4, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_0__DI1_PIN11	IOMUX_PAD(0x6A8, 0x2A8, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_1__DI1_PIN12	IOMUX_PAD(0x6AC, 0x2AC, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_2__DI1_PIN13	IOMUX_PAD(0x6B0, 0x2B0, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_3__DI1_D0_CS	IOMUX_PAD(0x6B4, 0x2B4, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_4__DI1_D1_CS	IOMUX_PAD(0x6B8, 0x2B8, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_5__DISPB2_SER_DIN	IOMUX_PAD(0x6BC, 0x2BC, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_6__DISPB2_SER_DIO	IOMUX_PAD(0x6C0, 0x2C0, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_7__DISPB2_SER_CLK	IOMUX_PAD(0x6C4, 0x2C4, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_8__DISPB2_SER_RS	IOMUX_PAD(0x6C8, 0x2C8, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT0__DISP1_DAT0	IOMUX_PAD(0x6CC, 0x2CC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT1__DISP1_DAT1	IOMUX_PAD(0x6D0, 0x2D0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT2__DISP1_DAT2	IOMUX_PAD(0x6D4, 0x2D4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT3__DISP1_DAT3	IOMUX_PAD(0x6D8, 0x2D8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT4__DISP1_DAT4	IOMUX_PAD(0x6DC, 0x2DC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT5__DISP1_DAT5	IOMUX_PAD(0x6E0, 0x2E0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT6__DISP1_DAT6	IOMUX_PAD(0x6E4, 0x2E4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT7__DISP1_DAT7	IOMUX_PAD(0x6E8, 0x2E8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT8__DISP1_DAT8	IOMUX_PAD(0x6EC, 0x2EC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT9__DISP1_DAT9	IOMUX_PAD(0x6F0, 0x2F0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT10__DISP1_DAT10	IOMUX_PAD(0x6F4, 0x2F4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT11__DISP1_DAT11	IOMUX_PAD(0x6F8, 0x2F8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT12__DISP1_DAT12	IOMUX_PAD(0x6FC, 0x2FC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT13__DISP1_DAT13	IOMUX_PAD(0x700, 0x300, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT14__DISP1_DAT14	IOMUX_PAD(0x704, 0x304, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT15__DISP1_DAT15	IOMUX_PAD(0x708, 0x308, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT16__DISP1_DAT16	IOMUX_PAD(0x70C, 0x30C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT17__DISP1_DAT17	IOMUX_PAD(0x710, 0x310, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT18__DISP1_DAT18	IOMUX_PAD(0x714, 0x314, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT19__DISP1_DAT19	IOMUX_PAD(0x718, 0x318, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT20__DISP1_DAT20	IOMUX_PAD(0x71C, 0x31C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT21__DISP1_DAT21	IOMUX_PAD(0x720, 0x320, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT22__DISP1_DAT22	IOMUX_PAD(0x724, 0x324, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT23__DISP1_DAT23	IOMUX_PAD(0x728, 0x328, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN3__DI1_PIN3	IOMUX_PAD(0x72C, 0x32C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN2__DI1_PIN2	IOMUX_PAD(0x734, 0x330, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP1__DI_GP1	IOMUX_PAD(0x73C, 0x334, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP2__DI_GP2	IOMUX_PAD(0x740, 0x338, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP3__DI_GP3	IOMUX_PAD(0x744, 0x33C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_PIN4__DI2_PIN4	IOMUX_PAD(0x748, 0x340, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_PIN2__DI2_PIN2	IOMUX_PAD(0x74C, 0x344, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_PIN3__DI2_PIN3	IOMUX_PAD(0x750, 0x348, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK	IOMUX_PAD(0x754, 0x34C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP4__DI_GP4	IOMUX_PAD(0x758, 0x350, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT0__DISP2_DAT0	IOMUX_PAD(0x75C, 0x354, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT1__DISP2_DAT1	IOMUX_PAD(0x760, 0x358, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT2__DISP2_DAT2	IOMUX_PAD(0x764, 0x35C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT3__DISP2_DAT3	IOMUX_PAD(0x768, 0x360, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT4__DISP2_DAT4	IOMUX_PAD(0x76C, 0x364, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT5__DISP2_DAT5	IOMUX_PAD(0x770, 0x368, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_19__DISP2_DAT6	IOMUX_PAD(0x774, 0x36C, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_29__DISP2_DAT7	IOMUX_PAD(0x778, 0x370, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_30__DISP2_DAT8	IOMUX_PAD(0x77C, 0x374, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_31__DISP2_DAT9	IOMUX_PAD(0x780, 0x378, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT10__DISP2_DAT10	IOMUX_PAD(0x784, 0x37C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT11__DISP2_DAT11	IOMUX_PAD(0x788, 0x380, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT12__DISP2_DAT12	IOMUX_PAD(0x78C, 0x384, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT13__DISP2_DAT13	IOMUX_PAD(0x790, 0x388, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT14__DISP2_DAT14	IOMUX_PAD(0x794, 0x38C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT15__DISP2_DAT15	IOMUX_PAD(0x798, 0x390, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_CMD__SD1_CMD	IOMUX_PAD(0x79C, 0x394, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_CLK__SD1_CLK	IOMUX_PAD(0x7A0, 0x398, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA0__SD1_DATA0	IOMUX_PAD(0x7A4, 0x39C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA1__SD1_DATA1	IOMUX_PAD(0x7A8, 0x3A0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA2__SD1_DATA2	IOMUX_PAD(0x7AC, 0x3A4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA3__SD1_DATA3	IOMUX_PAD(0x7B0, 0x3A8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_0__GPIO1_0	IOMUX_PAD(0x7B4, 0x3AC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_1__GPIO1_1	IOMUX_PAD(0x7B8, 0x3B0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_CMD__SD2_CMD	IOMUX_PAD(0x7BC, 0x3B4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_CLK__SD2_CLK	IOMUX_PAD(0x7C0, 0x3B8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA0__SD2_DATA0	IOMUX_PAD(0x7C4, 0x3BC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA1__SD2_DATA1	IOMUX_PAD(0x7C8, 0x3C0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA2__SD2_DATA2	IOMUX_PAD(0x7CC, 0x3C4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA3__SD2_DATA3	IOMUX_PAD(0x7D0, 0x3C8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_2__GPIO1_2	IOMUX_PAD(0x7D4, 0x3CC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_3__GPIO1_3	IOMUX_PAD(0x7D8, 0x3D0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ	IOMUX_PAD(0x7FC, 0x3D4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_4__GPIO1_4	IOMUX_PAD(0x804, 0x3D8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_5__GPIO1_5	IOMUX_PAD(0x808, 0x3DC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_6__GPIO1_6	IOMUX_PAD(0x80C, 0x3E0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_7__GPIO1_7	IOMUX_PAD(0x810, 0x3E4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_8__GPIO1_8	IOMUX_PAD(0x814, 0x3E8, 0, 0x0, 1, \
+						(PAD_CTL_SRE_SLOW | PAD_CTL_DSE_MED | PAD_CTL_PUS_100K_UP |  PAD_CTL_HYS))
+#define MX51_PAD_GPIO_1_9__GPIO1_9	IOMUX_PAD(0x818, 0x3EC, 0, 0x0, 0, NO_PAD_CTRL)
+
+/* EIM */
+#define MX51_PAD_EIM_DA0__EIM_DA0	IOMUX_PAD(0x7a8, 0x01c, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA1__EIM_DA1	IOMUX_PAD(0x7a8, 0x020, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA2__EIM_DA2	IOMUX_PAD(0x7a8, 0x024, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA3__EIM_DA3	IOMUX_PAD(0x7a8, 0x028, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA4__EIM_DA4	IOMUX_PAD(0x7ac, 0x02c, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA5__EIM_DA5	IOMUX_PAD(0x7ac, 0x030, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA6__EIM_DA6	IOMUX_PAD(0x7ac, 0x034, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA7__EIM_DA7	IOMUX_PAD(0x7ac, 0x038, 0, 0x0,   0, NO_PAD_CTRL)
+
+#define MX51_PAD_EIM_DA8__EIM_DA8	IOMUX_PAD(0x7b0, 0x03c, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA9__EIM_DA9	IOMUX_PAD(0x7b0, 0x040, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA10__EIM_DA10	IOMUX_PAD(0x7b0, 0x044, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA11__EIM_DA11	IOMUX_PAD(0x7b0, 0x048, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA12__EIM_DA12	IOMUX_PAD(0x7bc, 0x04c, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA13__EIM_DA13	IOMUX_PAD(0x7bc, 0x050, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA14__EIM_DA14	IOMUX_PAD(0x7bc, 0x054, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA15__EIM_DA15	IOMUX_PAD(0x7bc, 0x058, 0, 0x0,   0, NO_PAD_CTRL)
+
+#endif /* __MACH_IOMUX_MX51_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-v1.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-v1.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-v1.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-v1.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,103 @@
+/*
+ * 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 __MACH_IOMUX_V1_H__
+#define __MACH_IOMUX_V1_H__
+
+/*
+*  GPIO Module and I/O Multiplexer
+*  x = 0..3 for reg_A, reg_B, reg_C, reg_D
+*/
+#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))
+
+#define MX1_NUM_GPIO_PORT	4
+#define MX21_NUM_GPIO_PORT	6
+#define MX27_NUM_GPIO_PORT	6
+
+#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)
+
+/* 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)
+#define IRQ_GPIOF(x)  (IRQ_GPIOE(32) + x)
+
+extern int 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 /* __MACH_IOMUX_V1_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-v3.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-v3.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-v3.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-v3.h	2010-05-16 17:17:36.000000000 -0400
@@ -81,11 +81,13 @@ struct pad_desc {
 
 #define PAD_CTL_ODE			(1 << 3)
 
-#define PAD_CTL_DSE_STANDARD		(0 << 1)
-#define PAD_CTL_DSE_HIGH		(1 << 1)
-#define PAD_CTL_DSE_MAX			(2 << 1)
+#define PAD_CTL_DSE_LOW			(0 << 1)
+#define PAD_CTL_DSE_MED			(1 << 1)
+#define PAD_CTL_DSE_HIGH		(2 << 1)
+#define PAD_CTL_DSE_MAX			(3 << 1)
 
 #define PAD_CTL_SRE_FAST		(1 << 0)
+#define PAD_CTL_SRE_SLOW		(0 << 0)
 
 /*
  * setups a single pad in the iomuxer
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/irqs.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/irqs.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/irqs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/irqs.h	2010-05-16 17:17:36.000000000 -0400
@@ -12,22 +12,29 @@
 #define __ASM_ARCH_MXC_IRQS_H__
 
 /*
- * So far all i.MX SoCs have 64 internal interrupts
+ * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
  */
+#ifdef CONFIG_MXC_TZIC
+#define MXC_INTERNAL_IRQS	128
+#else
 #define MXC_INTERNAL_IRQS	64
+#endif
 
 #define MXC_GPIO_IRQ_START	MXC_INTERNAL_IRQS
 
-#if defined CONFIG_ARCH_MX1
-#define MXC_GPIO_IRQS		(32 * 4)
-#elif defined CONFIG_ARCH_MX2
+/* these are ordered by size to support multi-SoC kernels */
+#if defined CONFIG_ARCH_MX2
 #define MXC_GPIO_IRQS		(32 * 6)
-#elif defined CONFIG_ARCH_MX3
-#define MXC_GPIO_IRQS		(32 * 3)
+#elif defined CONFIG_ARCH_MX1
+#define MXC_GPIO_IRQS		(32 * 4)
 #elif defined CONFIG_ARCH_MX25
 #define MXC_GPIO_IRQS		(32 * 4)
+#elif defined CONFIG_ARCH_MX5
+#define MXC_GPIO_IRQS		(32 * 4)
 #elif defined CONFIG_ARCH_MXC91231
 #define MXC_GPIO_IRQS		(32 * 4)
+#elif defined CONFIG_ARCH_MX3
+#define MXC_GPIO_IRQS		(32 * 3)
 #endif
 
 /*
@@ -51,6 +58,7 @@
 #else
 #define MX3_IPU_IRQS 0
 #endif
+/* REVISIT: Add IPU irqs on IMX51 */
 
 #define NR_IRQS			(MXC_IPU_IRQ_START + MX3_IPU_IRQS)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/memory.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/memory.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/memory.h	2010-05-16 17:17:36.000000000 -0400
@@ -11,37 +11,45 @@
 #ifndef __ASM_ARCH_MXC_MEMORY_H__
 #define __ASM_ARCH_MXC_MEMORY_H__
 
-#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)
-#elif defined CONFIG_ARCH_MX25
-#define PHYS_OFFSET		UL(0x80000000)
-#elif defined CONFIG_ARCH_MXC91231
-#define PHYS_OFFSET		UL(0x90000000)
+#define MX1_PHYS_OFFSET		UL(0x08000000)
+#define MX21_PHYS_OFFSET	UL(0xc0000000)
+#define MX25_PHYS_OFFSET	UL(0x80000000)
+#define MX27_PHYS_OFFSET	UL(0xa0000000)
+#define MX3x_PHYS_OFFSET	UL(0x80000000)
+#define MX51_PHYS_OFFSET	UL(0x90000000)
+#define MXC91231_PHYS_OFFSET	UL(0x90000000)
+
+#if !defined(CONFIG_RUNTIME_PHYS_OFFSET)
+# if defined CONFIG_ARCH_MX1
+#  define PHYS_OFFSET		MX1_PHYS_OFFSET
+# elif defined CONFIG_MACH_MX21
+#  define PHYS_OFFSET		MX21_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX25
+#  define PHYS_OFFSET		MX25_PHYS_OFFSET
+# elif defined CONFIG_MACH_MX27
+#  define PHYS_OFFSET		MX27_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX3
+#  define PHYS_OFFSET		MX3x_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MXC91231
+#  define PHYS_OFFSET		MXC91231_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX5
+#  define PHYS_OFFSET		MX51_PHYS_OFFSET
+# endif
 #endif
 
-#if defined(CONFIG_MX1_VIDEO)
+#if defined(CONFIG_MX3_VIDEO)
 /*
  * Increase size of DMA-consistent memory region.
- * This is required for i.MX camera driver to capture at least four VGA frames.
+ * This is required for mx3 camera driver to capture at least two QXGA frames.
  */
-#define CONSISTENT_DMA_SIZE SZ_4M
-#endif /* CONFIG_MX1_VIDEO */
+#define CONSISTENT_DMA_SIZE SZ_8M
 
-#if defined(CONFIG_MX3_VIDEO)
+#elif defined(CONFIG_MX1_VIDEO)
 /*
  * Increase size of DMA-consistent memory region.
- * This is required for mx3 camera driver to capture at least two QXGA frames.
+ * This is required for i.MX camera driver to capture at least four VGA frames.
  */
-#define CONSISTENT_DMA_SIZE SZ_8M
-#endif /* CONFIG_MX3_VIDEO */
+#define CONSISTENT_DMA_SIZE SZ_4M
+#endif /* CONFIG_MX1_VIDEO */
 
 #endif /* __ASM_ARCH_MXC_MEMORY_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mtd-xip.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mtd-xip.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mtd-xip.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mtd-xip.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,34 +0,0 @@
-/*
- * MTD primitives for XIP support. Architecture specific functions
- *
- * Do not include this file directly. It's included from linux/mtd/xip.h
- *
- * Copyright (C) 2008 Darius Augulis <augulis.darius@gmail.com>, Teltonika, 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 <mach/mxc_timer.h>
-
-#ifndef __ARCH_IMX_MTD_XIP_H__
-#define __ARCH_IMX_MTD_XIP_H__
-
-#ifdef CONFIG_ARCH_MX1
-/* AITC registers */
-#define AITC_BASE	IO_ADDRESS(AVIC_BASE_ADDR)
-#define NIPNDH		(AITC_BASE + 0x58)
-#define NIPNDL		(AITC_BASE + 0x5C)
-#define INTENABLEH	(AITC_BASE + 0x10)
-#define INTENABLEL	(AITC_BASE + 0x14)
-/* MTD macros */
-#define xip_irqpending() ((__raw_readl(INTENABLEH) &  __raw_readl(NIPNDH)) \
-			|| (__raw_readl(INTENABLEL) &  __raw_readl(NIPNDL)))
-#define xip_currtime()		(__raw_readl(TIMER_BASE + MXC_TCN))
-#define xip_elapsed_since(x)	(signed)((__raw_readl(TIMER_BASE + MXC_TCN) - (x)) / 96)
-#define xip_cpu_idle()		asm volatile ("mcr p15, 0, %0, c7, c0, 4" :: "r" (0))
-#endif /* CONFIG_ARCH_MX1 */
-
-#endif /* __ARCH_IMX_MTD_XIP_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx1.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx1.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx1.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx1.h	2010-05-16 17:17:36.000000000 -0400
@@ -9,156 +9,289 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef __ASM_ARCH_MXC_MX1_H__
-#define __ASM_ARCH_MXC_MX1_H__
+#ifndef __MACH_MX1_H__
+#define __MACH_MX1_H__
 
 #include <mach/vmalloc.h>
 
 /*
  * Memory map
  */
-#define IMX_IO_PHYS	0x00200000
-#define IMX_IO_SIZE	0x00100000
-#define IMX_IO_BASE	VMALLOC_END
+#define MX1_IO_BASE_ADDR	0x00200000
+#define MX1_IO_SIZE		SZ_1M
+#define MX1_IO_BASE_ADDR_VIRT	VMALLOC_END
 
-#define IMX_CS0_PHYS	0x10000000
-#define IMX_CS0_SIZE	0x02000000
+#define MX1_CS0_PHYS		0x10000000
+#define MX1_CS0_SIZE		0x02000000
 
-#define IMX_CS1_PHYS	0x12000000
-#define IMX_CS1_SIZE	0x01000000
+#define MX1_CS1_PHYS		0x12000000
+#define MX1_CS1_SIZE		0x01000000
 
-#define IMX_CS2_PHYS	0x13000000
-#define IMX_CS2_SIZE	0x01000000
+#define MX1_CS2_PHYS		0x13000000
+#define MX1_CS2_SIZE		0x01000000
 
-#define IMX_CS3_PHYS	0x14000000
-#define IMX_CS3_SIZE	0x01000000
+#define MX1_CS3_PHYS		0x14000000
+#define MX1_CS3_SIZE		0x01000000
 
-#define IMX_CS4_PHYS	0x15000000
-#define IMX_CS4_SIZE	0x01000000
+#define MX1_CS4_PHYS		0x15000000
+#define MX1_CS4_SIZE		0x01000000
 
-#define IMX_CS5_PHYS	0x16000000
-#define IMX_CS5_SIZE	0x01000000
+#define MX1_CS5_PHYS		0x16000000
+#define MX1_CS5_SIZE		0x01000000
 
 /*
  *  Register BASEs, based on OFFSETs
  */
-#define AIPI1_BASE_ADDR		(0x00000 + IMX_IO_PHYS)
-#define WDT_BASE_ADDR		(0x01000 + IMX_IO_PHYS)
-#define TIM1_BASE_ADDR		(0x02000 + IMX_IO_PHYS)
-#define TIM2_BASE_ADDR		(0x03000 + IMX_IO_PHYS)
-#define RTC_BASE_ADDR		(0x04000 + IMX_IO_PHYS)
-#define LCDC_BASE_ADDR		(0x05000 + IMX_IO_PHYS)
-#define UART1_BASE_ADDR		(0x06000 + IMX_IO_PHYS)
-#define UART2_BASE_ADDR		(0x07000 + IMX_IO_PHYS)
-#define PWM_BASE_ADDR		(0x08000 + IMX_IO_PHYS)
-#define DMA_BASE_ADDR		(0x09000 + IMX_IO_PHYS)
-#define AIPI2_BASE_ADDR		(0x10000 + IMX_IO_PHYS)
-#define SIM_BASE_ADDR		(0x11000 + IMX_IO_PHYS)
-#define USBD_BASE_ADDR		(0x12000 + IMX_IO_PHYS)
-#define SPI1_BASE_ADDR		(0x13000 + IMX_IO_PHYS)
-#define MMC_BASE_ADDR		(0x14000 + IMX_IO_PHYS)
-#define ASP_BASE_ADDR		(0x15000 + IMX_IO_PHYS)
-#define BTA_BASE_ADDR		(0x16000 + IMX_IO_PHYS)
-#define I2C_BASE_ADDR		(0x17000 + IMX_IO_PHYS)
-#define SSI_BASE_ADDR		(0x18000 + IMX_IO_PHYS)
-#define SPI2_BASE_ADDR		(0x19000 + IMX_IO_PHYS)
-#define MSHC_BASE_ADDR		(0x1A000 + IMX_IO_PHYS)
-#define CCM_BASE_ADDR		(0x1B000 + IMX_IO_PHYS)
-#define SCM_BASE_ADDR		(0x1B804 + IMX_IO_PHYS)
-#define GPIO_BASE_ADDR		(0x1C000 + IMX_IO_PHYS)
-#define EIM_BASE_ADDR		(0x20000 + IMX_IO_PHYS)
-#define SDRAMC_BASE_ADDR	(0x21000 + IMX_IO_PHYS)
-#define MMA_BASE_ADDR		(0x22000 + IMX_IO_PHYS)
-#define AVIC_BASE_ADDR		(0x23000 + IMX_IO_PHYS)
-#define CSI_BASE_ADDR		(0x24000 + IMX_IO_PHYS)
+#define MX1_AIPI1_BASE_ADDR		(0x00000 + MX1_IO_BASE_ADDR)
+#define MX1_WDT_BASE_ADDR		(0x01000 + MX1_IO_BASE_ADDR)
+#define MX1_TIM1_BASE_ADDR		(0x02000 + MX1_IO_BASE_ADDR)
+#define MX1_TIM2_BASE_ADDR		(0x03000 + MX1_IO_BASE_ADDR)
+#define MX1_RTC_BASE_ADDR		(0x04000 + MX1_IO_BASE_ADDR)
+#define MX1_LCDC_BASE_ADDR		(0x05000 + MX1_IO_BASE_ADDR)
+#define MX1_UART1_BASE_ADDR		(0x06000 + MX1_IO_BASE_ADDR)
+#define MX1_UART2_BASE_ADDR		(0x07000 + MX1_IO_BASE_ADDR)
+#define MX1_PWM_BASE_ADDR		(0x08000 + MX1_IO_BASE_ADDR)
+#define MX1_DMA_BASE_ADDR		(0x09000 + MX1_IO_BASE_ADDR)
+#define MX1_AIPI2_BASE_ADDR		(0x10000 + MX1_IO_BASE_ADDR)
+#define MX1_SIM_BASE_ADDR		(0x11000 + MX1_IO_BASE_ADDR)
+#define MX1_USBD_BASE_ADDR		(0x12000 + MX1_IO_BASE_ADDR)
+#define MX1_SPI1_BASE_ADDR		(0x13000 + MX1_IO_BASE_ADDR)
+#define MX1_MMC_BASE_ADDR		(0x14000 + MX1_IO_BASE_ADDR)
+#define MX1_ASP_BASE_ADDR		(0x15000 + MX1_IO_BASE_ADDR)
+#define MX1_BTA_BASE_ADDR		(0x16000 + MX1_IO_BASE_ADDR)
+#define MX1_I2C_BASE_ADDR		(0x17000 + MX1_IO_BASE_ADDR)
+#define MX1_SSI_BASE_ADDR		(0x18000 + MX1_IO_BASE_ADDR)
+#define MX1_SPI2_BASE_ADDR		(0x19000 + MX1_IO_BASE_ADDR)
+#define MX1_MSHC_BASE_ADDR		(0x1A000 + MX1_IO_BASE_ADDR)
+#define MX1_CCM_BASE_ADDR		(0x1B000 + MX1_IO_BASE_ADDR)
+#define MX1_SCM_BASE_ADDR		(0x1B804 + MX1_IO_BASE_ADDR)
+#define MX1_GPIO_BASE_ADDR		(0x1C000 + MX1_IO_BASE_ADDR)
+#define MX1_EIM_BASE_ADDR		(0x20000 + MX1_IO_BASE_ADDR)
+#define MX1_SDRAMC_BASE_ADDR		(0x21000 + MX1_IO_BASE_ADDR)
+#define MX1_MMA_BASE_ADDR		(0x22000 + MX1_IO_BASE_ADDR)
+#define MX1_AVIC_BASE_ADDR		(0x23000 + MX1_IO_BASE_ADDR)
+#define MX1_CSI_BASE_ADDR		(0x24000 + MX1_IO_BASE_ADDR)
 
 /* macro to get at IO space when running virtually */
-#define IO_ADDRESS(x)	((x) - IMX_IO_PHYS + IMX_IO_BASE)
-
-/* define macros needed for entry-macro.S */
-#define AVIC_IO_ADDRESS(x)	IO_ADDRESS(x)
+#define MX1_IO_ADDRESS(x) (						\
+	IMX_IO_ADDRESS(x, MX1_IO))
 
 /* fixed interrput numbers */
-#define INT_SOFTINT		0
-#define CSI_INT			6
-#define DSPA_MAC_INT		7
-#define DSPA_INT		8
-#define COMP_INT		9
-#define MSHC_XINT		10
-#define GPIO_INT_PORTA		11
-#define GPIO_INT_PORTB		12
-#define GPIO_INT_PORTC		13
-#define LCDC_INT		14
-#define SIM_INT			15
-#define SIM_DATA_INT		16
-#define RTC_INT			17
-#define RTC_SAMINT		18
-#define UART2_MINT_PFERR	19
-#define UART2_MINT_RTS		20
-#define UART2_MINT_DTR		21
-#define UART2_MINT_UARTC	22
-#define UART2_MINT_TX		23
-#define UART2_MINT_RX		24
-#define UART1_MINT_PFERR	25
-#define UART1_MINT_RTS		26
-#define UART1_MINT_DTR		27
-#define UART1_MINT_UARTC	28
-#define UART1_MINT_TX		29
-#define UART1_MINT_RX		30
-#define VOICE_DAC_INT		31
-#define VOICE_ADC_INT		32
-#define PEN_DATA_INT		33
-#define PWM_INT			34
-#define SDHC_INT		35
-#define I2C_INT			39
-#define CSPI_INT		41
-#define SSI_TX_INT		42
-#define SSI_TX_ERR_INT		43
-#define SSI_RX_INT		44
-#define SSI_RX_ERR_INT		45
-#define TOUCH_INT		46
-#define USBD_INT0		47
-#define USBD_INT1		48
-#define USBD_INT2		49
-#define USBD_INT3		50
-#define USBD_INT4		51
-#define USBD_INT5		52
-#define USBD_INT6		53
-#define BTSYS_INT		55
-#define BTTIM_INT		56
-#define BTWUI_INT		57
-#define TIM2_INT		58
-#define TIM1_INT		59
-#define DMA_ERR			60
-#define DMA_INT			61
-#define GPIO_INT_PORTD		62
-#define WDT_INT			63
+#define MX1_INT_SOFTINT		0
+#define MX1_CSI_INT		6
+#define MX1_DSPA_MAC_INT	7
+#define MX1_DSPA_INT		8
+#define MX1_COMP_INT		9
+#define MX1_MSHC_XINT		10
+#define MX1_GPIO_INT_PORTA	11
+#define MX1_GPIO_INT_PORTB	12
+#define MX1_GPIO_INT_PORTC	13
+#define MX1_LCDC_INT		14
+#define MX1_SIM_INT		15
+#define MX1_SIM_DATA_INT	16
+#define MX1_RTC_INT		17
+#define MX1_RTC_SAMINT		18
+#define MX1_UART2_MINT_PFERR	19
+#define MX1_UART2_MINT_RTS	20
+#define MX1_UART2_MINT_DTR	21
+#define MX1_UART2_MINT_UARTC	22
+#define MX1_UART2_MINT_TX	23
+#define MX1_UART2_MINT_RX	24
+#define MX1_UART1_MINT_PFERR	25
+#define MX1_UART1_MINT_RTS	26
+#define MX1_UART1_MINT_DTR	27
+#define MX1_UART1_MINT_UARTC	28
+#define MX1_UART1_MINT_TX	29
+#define MX1_UART1_MINT_RX	30
+#define MX1_VOICE_DAC_INT	31
+#define MX1_VOICE_ADC_INT	32
+#define MX1_PEN_DATA_INT	33
+#define MX1_PWM_INT		34
+#define MX1_SDHC_INT		35
+#define MX1_I2C_INT		39
+#define MX1_CSPI_INT		41
+#define MX1_SSI_TX_INT		42
+#define MX1_SSI_TX_ERR_INT	43
+#define MX1_SSI_RX_INT		44
+#define MX1_SSI_RX_ERR_INT	45
+#define MX1_TOUCH_INT		46
+#define MX1_USBD_INT0		47
+#define MX1_USBD_INT1		48
+#define MX1_USBD_INT2		49
+#define MX1_USBD_INT3		50
+#define MX1_USBD_INT4		51
+#define MX1_USBD_INT5		52
+#define MX1_USBD_INT6		53
+#define MX1_BTSYS_INT		55
+#define MX1_BTTIM_INT		56
+#define MX1_BTWUI_INT		57
+#define MX1_TIM2_INT		58
+#define MX1_TIM1_INT		59
+#define MX1_DMA_ERR		60
+#define MX1_DMA_INT		61
+#define MX1_GPIO_INT_PORTD	62
+#define MX1_WDT_INT		63
 
 /* DMA */
-#define DMA_REQ_UART3_T		2
-#define DMA_REQ_UART3_R		3
-#define DMA_REQ_SSI2_T		4
-#define DMA_REQ_SSI2_R		5
-#define DMA_REQ_CSI_STAT	6
-#define DMA_REQ_CSI_R		7
-#define DMA_REQ_MSHC		8
-#define DMA_REQ_DSPA_DCT_DOUT	9
-#define DMA_REQ_DSPA_DCT_DIN	10
-#define DMA_REQ_DSPA_MAC	11
-#define DMA_REQ_EXT		12
-#define DMA_REQ_SDHC		13
-#define DMA_REQ_SPI1_R		14
-#define DMA_REQ_SPI1_T		15
-#define DMA_REQ_SSI_T		16
-#define DMA_REQ_SSI_R		17
-#define DMA_REQ_ASP_DAC		18
-#define DMA_REQ_ASP_ADC		19
-#define DMA_REQ_USP_EP(x)	(20 + (x))
-#define DMA_REQ_SPI2_R		26
-#define DMA_REQ_SPI2_T		27
-#define DMA_REQ_UART2_T		28
-#define DMA_REQ_UART2_R		29
-#define DMA_REQ_UART1_T		30
-#define DMA_REQ_UART1_R		31
+#define MX1_DMA_REQ_UART3_T		2
+#define MX1_DMA_REQ_UART3_R		3
+#define MX1_DMA_REQ_SSI2_T		4
+#define MX1_DMA_REQ_SSI2_R		5
+#define MX1_DMA_REQ_CSI_STAT		6
+#define MX1_DMA_REQ_CSI_R		7
+#define MX1_DMA_REQ_MSHC		8
+#define MX1_DMA_REQ_DSPA_DCT_DOUT	9
+#define MX1_DMA_REQ_DSPA_DCT_DIN	10
+#define MX1_DMA_REQ_DSPA_MAC		11
+#define MX1_DMA_REQ_EXT			12
+#define MX1_DMA_REQ_SDHC		13
+#define MX1_DMA_REQ_SPI1_R		14
+#define MX1_DMA_REQ_SPI1_T		15
+#define MX1_DMA_REQ_SSI_T		16
+#define MX1_DMA_REQ_SSI_R		17
+#define MX1_DMA_REQ_ASP_DAC		18
+#define MX1_DMA_REQ_ASP_ADC		19
+#define MX1_DMA_REQ_USP_EP(x)		(20 + (x))
+#define MX1_DMA_REQ_SPI2_R		26
+#define MX1_DMA_REQ_SPI2_T		27
+#define MX1_DMA_REQ_UART2_T		28
+#define MX1_DMA_REQ_UART2_R		29
+#define MX1_DMA_REQ_UART1_T		30
+#define MX1_DMA_REQ_UART1_R		31
 
-#endif /*  __ASM_ARCH_MXC_MX1_H__ */
+/*
+ * This doesn't depend on IMX_NEEDS_DEPRECATED_SYMBOLS
+ * to not break drivers/usb/gadget/imx_udc.  Should go
+ * away after this driver uses the new name.
+ */
+#define USBD_INT0		MX1_USBD_INT0
+
+#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
+/* these should go away */
+#define IMX_IO_PHYS MX1_IO_BASE_ADDR
+#define IMX_IO_SIZE MX1_IO_SIZE
+#define IMX_IO_BASE MX1_IO_BASE_ADDR_VIRT
+#define IMX_CS0_PHYS MX1_CS0_PHYS
+#define IMX_CS0_SIZE MX1_CS0_SIZE
+#define IMX_CS1_PHYS MX1_CS1_PHYS
+#define IMX_CS1_SIZE MX1_CS1_SIZE
+#define IMX_CS2_PHYS MX1_CS2_PHYS
+#define IMX_CS2_SIZE MX1_CS2_SIZE
+#define IMX_CS3_PHYS MX1_CS3_PHYS
+#define IMX_CS3_SIZE MX1_CS3_SIZE
+#define IMX_CS4_PHYS MX1_CS4_PHYS
+#define IMX_CS4_SIZE MX1_CS4_SIZE
+#define IMX_CS5_PHYS MX1_CS5_PHYS
+#define IMX_CS5_SIZE MX1_CS5_SIZE
+#define AIPI1_BASE_ADDR MX1_AIPI1_BASE_ADDR
+#define WDT_BASE_ADDR MX1_WDT_BASE_ADDR
+#define TIM1_BASE_ADDR MX1_TIM1_BASE_ADDR
+#define TIM2_BASE_ADDR MX1_TIM2_BASE_ADDR
+#define RTC_BASE_ADDR MX1_RTC_BASE_ADDR
+#define LCDC_BASE_ADDR MX1_LCDC_BASE_ADDR
+#define UART1_BASE_ADDR MX1_UART1_BASE_ADDR
+#define UART2_BASE_ADDR MX1_UART2_BASE_ADDR
+#define PWM_BASE_ADDR MX1_PWM_BASE_ADDR
+#define DMA_BASE_ADDR MX1_DMA_BASE_ADDR
+#define AIPI2_BASE_ADDR MX1_AIPI2_BASE_ADDR
+#define SIM_BASE_ADDR MX1_SIM_BASE_ADDR
+#define USBD_BASE_ADDR MX1_USBD_BASE_ADDR
+#define SPI1_BASE_ADDR MX1_SPI1_BASE_ADDR
+#define MMC_BASE_ADDR MX1_MMC_BASE_ADDR
+#define ASP_BASE_ADDR MX1_ASP_BASE_ADDR
+#define BTA_BASE_ADDR MX1_BTA_BASE_ADDR
+#define I2C_BASE_ADDR MX1_I2C_BASE_ADDR
+#define SSI_BASE_ADDR MX1_SSI_BASE_ADDR
+#define SPI2_BASE_ADDR MX1_SPI2_BASE_ADDR
+#define MSHC_BASE_ADDR MX1_MSHC_BASE_ADDR
+#define CCM_BASE_ADDR MX1_CCM_BASE_ADDR
+#define SCM_BASE_ADDR MX1_SCM_BASE_ADDR
+#define GPIO_BASE_ADDR MX1_GPIO_BASE_ADDR
+#define EIM_BASE_ADDR MX1_EIM_BASE_ADDR
+#define SDRAMC_BASE_ADDR MX1_SDRAMC_BASE_ADDR
+#define MMA_BASE_ADDR MX1_MMA_BASE_ADDR
+#define AVIC_BASE_ADDR MX1_AVIC_BASE_ADDR
+#define CSI_BASE_ADDR MX1_CSI_BASE_ADDR
+#define IO_ADDRESS(x) MX1_IO_ADDRESS(x)
+#define AVIC_IO_ADDRESS(x) IO_ADDRESS(x)
+#define INT_SOFTINT MX1_INT_SOFTINT
+#define CSI_INT MX1_CSI_INT
+#define DSPA_MAC_INT MX1_DSPA_MAC_INT
+#define DSPA_INT MX1_DSPA_INT
+#define COMP_INT MX1_COMP_INT
+#define MSHC_XINT MX1_MSHC_XINT
+#define GPIO_INT_PORTA MX1_GPIO_INT_PORTA
+#define GPIO_INT_PORTB MX1_GPIO_INT_PORTB
+#define GPIO_INT_PORTC MX1_GPIO_INT_PORTC
+#define LCDC_INT MX1_LCDC_INT
+#define SIM_INT MX1_SIM_INT
+#define SIM_DATA_INT MX1_SIM_DATA_INT
+#define RTC_INT MX1_RTC_INT
+#define RTC_SAMINT MX1_RTC_SAMINT
+#define UART2_MINT_PFERR MX1_UART2_MINT_PFERR
+#define UART2_MINT_RTS MX1_UART2_MINT_RTS
+#define UART2_MINT_DTR MX1_UART2_MINT_DTR
+#define UART2_MINT_UARTC MX1_UART2_MINT_UARTC
+#define UART2_MINT_TX MX1_UART2_MINT_TX
+#define UART2_MINT_RX MX1_UART2_MINT_RX
+#define UART1_MINT_PFERR MX1_UART1_MINT_PFERR
+#define UART1_MINT_RTS MX1_UART1_MINT_RTS
+#define UART1_MINT_DTR MX1_UART1_MINT_DTR
+#define UART1_MINT_UARTC MX1_UART1_MINT_UARTC
+#define UART1_MINT_TX MX1_UART1_MINT_TX
+#define UART1_MINT_RX MX1_UART1_MINT_RX
+#define VOICE_DAC_INT MX1_VOICE_DAC_INT
+#define VOICE_ADC_INT MX1_VOICE_ADC_INT
+#define PEN_DATA_INT MX1_PEN_DATA_INT
+#define PWM_INT MX1_PWM_INT
+#define SDHC_INT MX1_SDHC_INT
+#define I2C_INT MX1_I2C_INT
+#define CSPI_INT MX1_CSPI_INT
+#define SSI_TX_INT MX1_SSI_TX_INT
+#define SSI_TX_ERR_INT MX1_SSI_TX_ERR_INT
+#define SSI_RX_INT MX1_SSI_RX_INT
+#define SSI_RX_ERR_INT MX1_SSI_RX_ERR_INT
+#define TOUCH_INT MX1_TOUCH_INT
+#define USBD_INT1 MX1_USBD_INT1
+#define USBD_INT2 MX1_USBD_INT2
+#define USBD_INT3 MX1_USBD_INT3
+#define USBD_INT4 MX1_USBD_INT4
+#define USBD_INT5 MX1_USBD_INT5
+#define USBD_INT6 MX1_USBD_INT6
+#define BTSYS_INT MX1_BTSYS_INT
+#define BTTIM_INT MX1_BTTIM_INT
+#define BTWUI_INT MX1_BTWUI_INT
+#define TIM2_INT MX1_TIM2_INT
+#define TIM1_INT MX1_TIM1_INT
+#define DMA_ERR MX1_DMA_ERR
+#define DMA_INT MX1_DMA_INT
+#define GPIO_INT_PORTD MX1_GPIO_INT_PORTD
+#define WDT_INT MX1_WDT_INT
+#define DMA_REQ_UART3_T MX1_DMA_REQ_UART3_T
+#define DMA_REQ_UART3_R MX1_DMA_REQ_UART3_R
+#define DMA_REQ_SSI2_T MX1_DMA_REQ_SSI2_T
+#define DMA_REQ_SSI2_R MX1_DMA_REQ_SSI2_R
+#define DMA_REQ_CSI_STAT MX1_DMA_REQ_CSI_STAT
+#define DMA_REQ_CSI_R MX1_DMA_REQ_CSI_R
+#define DMA_REQ_MSHC MX1_DMA_REQ_MSHC
+#define DMA_REQ_DSPA_DCT_DOUT MX1_DMA_REQ_DSPA_DCT_DOUT
+#define DMA_REQ_DSPA_DCT_DIN MX1_DMA_REQ_DSPA_DCT_DIN
+#define DMA_REQ_DSPA_MAC MX1_DMA_REQ_DSPA_MAC
+#define DMA_REQ_EXT MX1_DMA_REQ_EXT
+#define DMA_REQ_SDHC MX1_DMA_REQ_SDHC
+#define DMA_REQ_SPI1_R MX1_DMA_REQ_SPI1_R
+#define DMA_REQ_SPI1_T MX1_DMA_REQ_SPI1_T
+#define DMA_REQ_SSI_T MX1_DMA_REQ_SSI_T
+#define DMA_REQ_SSI_R MX1_DMA_REQ_SSI_R
+#define DMA_REQ_ASP_DAC MX1_DMA_REQ_ASP_DAC
+#define DMA_REQ_ASP_ADC MX1_DMA_REQ_ASP_ADC
+#define DMA_REQ_USP_EP(x) MX1_DMA_REQ_USP_EP(x)
+#define DMA_REQ_SPI2_R MX1_DMA_REQ_SPI2_R
+#define DMA_REQ_SPI2_T MX1_DMA_REQ_SPI2_T
+#define DMA_REQ_UART2_T MX1_DMA_REQ_UART2_T
+#define DMA_REQ_UART2_R MX1_DMA_REQ_UART2_R
+#define DMA_REQ_UART1_T MX1_DMA_REQ_UART1_T
+#define DMA_REQ_UART1_R MX1_DMA_REQ_UART1_R
+#endif /* ifdef IMX_NEEDS_DEPRECATED_SYMBOLS */
+
+#endif /* ifndef __MACH_MX1_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx21.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx21.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx21.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx21.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,8 +22,8 @@
  * MA  02110-1301, USA.
  */
 
-#ifndef __ASM_ARCH_MXC_MX21_H__
-#define __ASM_ARCH_MXC_MX21_H__
+#ifndef __MACH_MX21_H__
+#define __MACH_MX21_H__
 
 #define MX21_AIPI_BASE_ADDR		0x10000000
 #define MX21_AIPI_BASE_ADDR_VIRT	0xf4000000
@@ -92,6 +92,11 @@
 
 #define MX21_IRAM_BASE_ADDR		0xffffe800	/* internal ram */
 
+#define MX21_IO_ADDRESS(x) (						\
+	IMX_IO_ADDRESS(x, MX21_AIPI) ?:					\
+	IMX_IO_ADDRESS(x, MX21_SAHB1) ?:				\
+	IMX_IO_ADDRESS(x, MX21_X_MEMC))
+
 /* fixed interrupt numbers */
 #define MX21_INT_CSPI3		6
 #define MX21_INT_GPIO		8
@@ -179,6 +184,7 @@
 #define MX21_DMA_REQ_CSI_STAT	30
 #define MX21_DMA_REQ_CSI_RX	31
 
+#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
 /* these should go away */
 #define SDRAM_BASE_ADDR MX21_SDRAM_BASE_ADDR
 #define CSD1_BASE_ADDR MX21_CSD1_BASE_ADDR
@@ -211,5 +217,6 @@
 #define DMA_REQ_FIRI_RX MX21_DMA_REQ_FIRI_RX
 #define DMA_REQ_BMI_TX MX21_DMA_REQ_BMI_TX
 #define DMA_REQ_BMI_RX MX21_DMA_REQ_BMI_RX
+#endif
 
-#endif /* __ASM_ARCH_MXC_MX21_H__ */
+#endif /* ifndef __MACH_MX21_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx21-usbhost.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx21-usbhost.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx21-usbhost.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx21-usbhost.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,38 @@
+/*
+ *	Copyright (C) 2009 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.
+ */
+
+#ifndef __ASM_ARCH_MX21_USBH
+#define __ASM_ARCH_MX21_USBH
+
+enum mx21_usbh_xcvr {
+	/* Values below as used by hardware (HWMODE register) */
+	MX21_USBXCVR_TXDIF_RXDIF = 0,
+	MX21_USBXCVR_TXDIF_RXSE = 1,
+	MX21_USBXCVR_TXSE_RXDIF = 2,
+	MX21_USBXCVR_TXSE_RXSE = 3,
+};
+
+struct mx21_usbh_platform_data {
+	enum mx21_usbh_xcvr host_xcvr; /* tranceiver mode host 1,2 ports */
+	enum mx21_usbh_xcvr otg_xcvr; /* tranceiver mode otg (as host) port */
+	u16 	enable_host1:1,
+		enable_host2:1,
+		enable_otg_host:1, /* enable "OTG" port (as host) */
+		host1_xcverless:1, /* traceiverless host1 port */
+		host1_txenoe:1, /* output enable host1 transmit enable */
+		otg_ext_xcvr:1, /* external tranceiver for OTG port */
+		unused:10;
+};
+
+#endif /* __ASM_ARCH_MX21_USBH */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx25.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx25.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx25.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx25.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,27 +22,27 @@
 #define MX25_GPIO3_BASE_ADDR_VIRT	(MX25_AIPS2_BASE_ADDR_VIRT + 0xa4000)
 #define MX25_GPIO4_BASE_ADDR_VIRT	(MX25_AIPS2_BASE_ADDR_VIRT + 0x9c000)
 
-#define MX25_AIPS1_IO_ADDRESS(x)  \
-	(((x) - MX25_AIPS1_BASE_ADDR) + MX25_AIPS1_BASE_ADDR_VIRT)
-#define MX25_AIPS2_IO_ADDRESS(x)  \
-	(((x) - MX25_AIPS2_BASE_ADDR) + MX25_AIPS2_BASE_ADDR_VIRT)
-#define MX25_AVIC_IO_ADDRESS(x)  \
-	(((x) - MX25_AVIC_BASE_ADDR) + MX25_AVIC_BASE_ADDR_VIRT)
-
-#define __in_range(addr, name)	((addr) >= name##_BASE_ADDR && (addr) < name##_BASE_ADDR + name##_SIZE)
-
-#define MX25_IO_ADDRESS(x)					\
-	(void __force __iomem *)				\
-	(__in_range(x, MX25_AIPS1) ? MX25_AIPS1_IO_ADDRESS(x) :	\
-	__in_range(x, MX25_AIPS2) ? MX25_AIPS2_IO_ADDRESS(x) :	\
-	__in_range(x, MX25_AVIC) ? MX25_AVIC_IO_ADDRESS(x) :	\
-	0xDEADBEEF)
+#define MX25_IO_ADDRESS(x) (					\
+	IMX_IO_ADDRESS(x, MX25_AIPS1) ?:			\
+	IMX_IO_ADDRESS(x, MX25_AIPS2) ?:			\
+	IMX_IO_ADDRESS(x, MX25_AVIC))
 
-#define UART1_BASE_ADDR			0x43f90000
-#define UART2_BASE_ADDR			0x43f94000
+#define MX25_UART1_BASE_ADDR		0x43f90000
+#define MX25_UART2_BASE_ADDR		0x43f94000
 
 #define MX25_FEC_BASE_ADDR		0x50038000
+#define MX25_NFC_BASE_ADDR		0xbb000000
+#define MX25_DRYICE_BASE_ADDR		0x53ffc000
+#define MX25_LCDC_BASE_ADDR		0x53fbc000
 
+#define MX25_INT_DRYICE	25
 #define MX25_INT_FEC	57
+#define MX25_INT_NANDFC	33
+#define MX25_INT_LCDC	39
 
-#endif /* __MACH_MX25_H__ */
+#if defined(IMX_NEEDS_DEPRECATED_SYMBOLS)
+#define UART1_BASE_ADDR			MX25_UART1_BASE_ADDR
+#define UART2_BASE_ADDR			MX25_UART2_BASE_ADDR
+#endif
+
+#endif /* ifndef __MACH_MX25_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx27.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx27.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx27.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx27.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,8 +21,12 @@
  * MA  02110-1301, USA.
  */
 
-#ifndef __ASM_ARCH_MXC_MX27_H__
-#define __ASM_ARCH_MXC_MX27_H__
+#ifndef __MACH_MX27_H__
+#define __MACH_MX27_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
 
 #define MX27_AIPI_BASE_ADDR		0x10000000
 #define MX27_AIPI_BASE_ADDR_VIRT	0xf4000000
@@ -109,11 +113,31 @@
 #define MX27_M3IF_BASE_ADDR			(MX27_X_MEMC_BASE_ADDR + 0x3000)
 #define MX27_PCMCIA_CTL_BASE_ADDR		(MX27_X_MEMC_BASE_ADDR + 0x4000)
 
+#define MX27_WEIM_CSCRx_BASE_ADDR(cs)	(MX27_WEIM_BASE_ADDR + (cs) * 0x10)
+#define MX27_WEIM_CSCRxU(cs)			(MX27_WEIM_CSCRx_BASE_ADDR(cs))
+#define MX27_WEIM_CSCRxL(cs)			(MX27_WEIM_CSCRx_BASE_ADDR(cs) + 0x4)
+#define MX27_WEIM_CSCRxA(cs)			(MX27_WEIM_CSCRx_BASE_ADDR(cs) + 0x8)
+
 #define MX27_PCMCIA_MEM_BASE_ADDR	0xdc000000
 
 /* IRAM */
 #define MX27_IRAM_BASE_ADDR		0xffff4c00	/* internal ram */
 
+#define MX27_IO_ADDRESS(x) (						\
+	IMX_IO_ADDRESS(x, MX27_AIPI) ?:					\
+	IMX_IO_ADDRESS(x, MX27_SAHB1) ?:				\
+	IMX_IO_ADDRESS(x, MX27_X_MEMC))
+
+#ifndef __ASSEMBLER__
+static inline void mx27_setup_weimcs(size_t cs,
+		unsigned upper, unsigned lower, unsigned addional)
+{
+	__raw_writel(upper, MX27_IO_ADDRESS(MX27_WEIM_CSCRxU(cs)));
+	__raw_writel(lower, MX27_IO_ADDRESS(MX27_WEIM_CSCRxL(cs)));
+	__raw_writel(addional, MX27_IO_ADDRESS(MX27_WEIM_CSCRxA(cs)));
+}
+#endif
+
 /* fixed interrupt numbers */
 #define MX27_INT_I2C2		1
 #define MX27_INT_GPT6		2
@@ -225,6 +249,7 @@
 extern int mx27_revision(void);
 #endif
 
+#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
 /* these should go away */
 #define MSHC_BASE_ADDR MX27_MSHC_BASE_ADDR
 #define GPT5_BASE_ADDR MX27_GPT5_BASE_ADDR
@@ -292,5 +317,6 @@ extern int mx27_revision(void);
 #define DMA_REQ_UART6_RX MX27_DMA_REQ_UART6_RX
 #define DMA_REQ_SDHC3 MX27_DMA_REQ_SDHC3
 #define DMA_REQ_NFC MX27_DMA_REQ_NFC
+#endif
 
-#endif /* __ASM_ARCH_MXC_MX27_H__ */
+#endif /* ifndef __MACH_MX27_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx2x.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx2x.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx2x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx2x.h	2010-05-16 17:17:36.000000000 -0400
@@ -20,8 +20,8 @@
  * MA  02110-1301, USA.
  */
 
-#ifndef __ASM_ARCH_MXC_MX2x_H__
-#define __ASM_ARCH_MXC_MX2x_H__
+#ifndef __MACH_MX2x_H__
+#define __MACH_MX2x_H__
 
 /* The following addresses are common between i.MX21 and i.MX27 */
 
@@ -176,6 +176,7 @@
 #define MX2x_DMA_REQ_CSI_STAT	30
 #define MX2x_DMA_REQ_CSI_RX	31
 
+#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
 /* these should go away */
 #define AIPI_BASE_ADDR MX2x_AIPI_BASE_ADDR
 #define AIPI_BASE_ADDR_VIRT MX2x_AIPI_BASE_ADDR_VIRT
@@ -287,5 +288,6 @@
 #define DMA_REQ_UART1_TX MX2x_DMA_REQ_UART1_TX
 #define DMA_REQ_CSI_STAT MX2x_DMA_REQ_CSI_STAT
 #define DMA_REQ_CSI_RX MX2x_DMA_REQ_CSI_RX
+#endif
 
-#endif /* __ASM_ARCH_MXC_MX2x_H__ */
+#endif /* ifndef __MACH_MX2x_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx31.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx31.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx31.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx31.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,3 +1,10 @@
+#ifndef __MACH_MX31_H__
+#define __MACH_MX31_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
 /*
  * IRAM
  */
@@ -107,8 +114,30 @@
 #define MX31_EMI_CTL_BASE_ADDR			(MX31_X_MEMC_BASE_ADDR + 0x4000)
 #define MX31_PCMCIA_CTL_BASE_ADDR		MX31_EMI_CTL_BASE_ADDR
 
+#define MX31_WEIM_CSCRx_BASE_ADDR(cs)	(MX31_WEIM_BASE_ADDR + (cs) * 0x10)
+#define MX31_WEIM_CSCRxU(cs)			(MX31_WEIM_CSCRx_BASE_ADDR(cs))
+#define MX31_WEIM_CSCRxL(cs)			(MX31_WEIM_CSCRx_BASE_ADDR(cs) + 0x4)
+#define MX31_WEIM_CSCRxA(cs)			(MX31_WEIM_CSCRx_BASE_ADDR(cs) + 0x8)
+
 #define MX31_PCMCIA_MEM_BASE_ADDR	0xbc000000
 
+#define MX31_IO_ADDRESS(x) (						\
+	IMX_IO_ADDRESS(x, MX31_AIPS1) ?:				\
+	IMX_IO_ADDRESS(x, MX31_AIPS2) ?:				\
+	IMX_IO_ADDRESS(x, MX31_AVIC) ?:					\
+	IMX_IO_ADDRESS(x, MX31_X_MEMC) ?:				\
+	IMX_IO_ADDRESS(x, MX31_SPBA0))
+
+#ifndef __ASSEMBLER__
+static inline void mx31_setup_weimcs(size_t cs,
+		unsigned upper, unsigned lower, unsigned addional)
+{
+	__raw_writel(upper, MX31_IO_ADDRESS(MX31_WEIM_CSCRxU(cs)));
+	__raw_writel(lower, MX31_IO_ADDRESS(MX31_WEIM_CSCRxL(cs)));
+	__raw_writel(addional, MX31_IO_ADDRESS(MX31_WEIM_CSCRxA(cs)));
+}
+#endif
+
 #define MX31_INT_I2C3		3
 #define MX31_INT_I2C2		4
 #define MX31_INT_MPEG4_ENCODER	5
@@ -186,6 +215,7 @@
 #define MX31_SYSTEM_REV_MIN		MX31_CHIP_REV_1_0
 #define MX31_SYSTEM_REV_NUM		3
 
+#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
 /* these should go away */
 #define ATA_BASE_ADDR MX31_ATA_BASE_ADDR
 #define UART4_BASE_ADDR MX31_UART4_BASE_ADDR
@@ -216,3 +246,6 @@
 #define MXC_INT_UART5 MX31_INT_UART5
 #define MXC_INT_CCM MX31_INT_CCM
 #define MXC_INT_PCMCIA MX31_INT_PCMCIA
+#endif
+
+#endif /* ifndef __MACH_MX31_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx35.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx35.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx35.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx35.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,3 +1,5 @@
+#ifndef __MACH_MX35_H__
+#define __MACH_MX35_H__
 /*
  * IRAM
  */
@@ -104,6 +106,13 @@
 #define MX35_NFC_BASE_ADDR		0xbb000000
 #define MX35_PCMCIA_MEM_BASE_ADDR	0xbc000000
 
+#define MX35_IO_ADDRESS(x) (						\
+	IMX_IO_ADDRESS(x, MX35_AIPS1) ?:				\
+	IMX_IO_ADDRESS(x, MX35_AIPS2) ?:				\
+	IMX_IO_ADDRESS(x, MX35_AVIC) ?:					\
+	IMX_IO_ADDRESS(x, MX35_X_MEMC) ?:				\
+	IMX_IO_ADDRESS(x, MX35_SPBA0))
+
 /*
  * Interrupt numbers
  */
@@ -180,6 +189,7 @@
 #define MX35_SYSTEM_REV_MIN		MX35_CHIP_REV_1_0
 #define MX35_SYSTEM_REV_NUM		3
 
+#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
 /* these should go away */
 #define MXC_FEC_BASE_ADDR MX35_FEC_BASE_ADDR
 #define MXC_INT_OWIRE MX35_INT_OWIRE
@@ -195,3 +205,6 @@
 #define MXC_INT_MLB MX35_INT_MLB
 #define MXC_INT_SPDIF MX35_INT_SPDIF
 #define MXC_INT_FEC MX35_INT_FEC
+#endif
+
+#endif /* ifndef __MACH_MX35_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx3x.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx3x.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx3x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx3x.h	2010-05-16 17:17:36.000000000 -0400
@@ -8,8 +8,8 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef __ASM_ARCH_MXC_MX31_H__
-#define __ASM_ARCH_MXC_MX31_H__
+#ifndef __MACH_MX3x_H__
+#define __MACH_MX3x_H__
 
 /*
  * MX31 memory map:
@@ -269,6 +269,7 @@ static inline int mx31_revision(void)
 }
 #endif
 
+#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
 /* these should go away */
 #define L2CC_BASE_ADDR MX3x_L2CC_BASE_ADDR
 #define L2CC_SIZE MX3x_L2CC_SIZE
@@ -401,5 +402,6 @@ static inline int mx31_revision(void)
 #define CHIP_REV_3_2 MX3x_CHIP_REV_3_2
 #define SYSTEM_REV_MIN MX3x_SYSTEM_REV_MIN
 #define SYSTEM_REV_NUM MX3x_SYSTEM_REV_NUM
+#endif
 
-#endif /*  __ASM_ARCH_MXC_MX31_H__ */
+#endif /* ifndef __MACH_MX3x_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx51.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx51.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx51.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mx51.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,445 @@
+#ifndef __ASM_ARCH_MXC_MX51_H__
+#define __ASM_ARCH_MXC_MX51_H__
+
+/*
+ * MX51 memory map:
+ *
+ *
+ * Virt		Phys		Size	What
+ * ---------------------------------------------------------------------------
+ * FA3E0000	1FFE0000	128K	IRAM (SCCv2 RAM)
+ *         	30000000	256M	GPU
+ *         	40000000	512M	IPU
+ * FA200000	60000000	1M	DEBUG
+ * FB100000	70000000	1M	SPBA 0
+ * FB000000	73F00000	1M	AIPS 1
+ * FB200000	83F00000	1M	AIPS 2
+ *		8FFFC000	16K	TZIC (interrupt controller)
+ *         	90000000	256M	CSD0 SDRAM/DDR
+ *         	A0000000	256M	CSD1 SDRAM/DDR
+ *         	B0000000	128M	CS0 Flash
+ *         	B8000000	128M	CS1 Flash
+ *         	C0000000	128M	CS2 Flash
+ *         	C8000000	64M	CS3 Flash
+ *         	CC000000	32M	CS4 SRAM
+ *         	CE000000	32M	CS5 SRAM
+ *		CFFF0000	64K	NFC (NAND Flash AXI)
+ *
+ */
+
+/*
+ * IROM
+ */
+#define MX51_IROM_BASE_ADDR		0x0
+#define MX51_IROM_SIZE			SZ_64K
+
+/*
+ * IRAM
+ */
+#define MX51_IRAM_BASE_ADDR		0x1FFE0000	/* internal ram */
+#define MX51_IRAM_BASE_ADDR_VIRT	0xFA3E0000
+#define MX51_IRAM_PARTITIONS		16
+#define MX51_IRAM_PARTITIONS_TO1	12
+#define MX51_IRAM_SIZE		(MX51_IRAM_PARTITIONS * SZ_8K)	/* 128KB */
+
+/*
+ * NFC
+ */
+#define MX51_NFC_AXI_BASE_ADDR		0xCFFF0000	/* NAND flash AXI */
+#define MX51_NFC_AXI_SIZE		SZ_64K
+
+/*
+ * Graphics Memory of GPU
+ */
+#define MX51_GPU_BASE_ADDR		0x20000000
+#define MX51_GPU2D_BASE_ADDR		0xD0000000
+
+#define MX51_TZIC_BASE_ADDR_TO1		0x8FFFC000
+#define MX51_TZIC_BASE_ADDR		0xE0000000
+
+#define MX51_DEBUG_BASE_ADDR		0x60000000
+#define MX51_DEBUG_BASE_ADDR_VIRT	0xFA200000
+#define MX51_DEBUG_SIZE			SZ_1M
+#define MX51_ETB_BASE_ADDR		(MX51_DEBUG_BASE_ADDR + 0x00001000)
+#define MX51_ETM_BASE_ADDR		(MX51_DEBUG_BASE_ADDR + 0x00002000)
+#define MX51_TPIU_BASE_ADDR		(MX51_DEBUG_BASE_ADDR + 0x00003000)
+#define MX51_CTI0_BASE_ADDR		(MX51_DEBUG_BASE_ADDR + 0x00004000)
+#define MX51_CTI1_BASE_ADDR		(MX51_DEBUG_BASE_ADDR + 0x00005000)
+#define MX51_CTI2_BASE_ADDR		(MX51_DEBUG_BASE_ADDR + 0x00006000)
+#define MX51_CTI3_BASE_ADDR		(MX51_DEBUG_BASE_ADDR + 0x00007000)
+#define MX51_CORTEX_DBG_BASE_ADDR	(MX51_DEBUG_BASE_ADDR + 0x00008000)
+
+/*
+ * SPBA global module enabled #0
+ */
+#define MX51_SPBA0_BASE_ADDR 		0x70000000
+#define MX51_SPBA0_BASE_ADDR_VIRT	0xFB100000
+#define MX51_SPBA0_SIZE			SZ_1M
+
+#define MX51_MMC_SDHC1_BASE_ADDR	(MX51_SPBA0_BASE_ADDR + 0x00004000)
+#define MX51_MMC_SDHC2_BASE_ADDR	(MX51_SPBA0_BASE_ADDR + 0x00008000)
+#define MX51_UART3_BASE_ADDR 		(MX51_SPBA0_BASE_ADDR + 0x0000C000)
+#define MX51_CSPI1_BASE_ADDR 		(MX51_SPBA0_BASE_ADDR + 0x00010000)
+#define MX51_SSI2_BASE_ADDR		(MX51_SPBA0_BASE_ADDR + 0x00014000)
+#define MX51_MMC_SDHC3_BASE_ADDR	(MX51_SPBA0_BASE_ADDR + 0x00020000)
+#define MX51_MMC_SDHC4_BASE_ADDR	(MX51_SPBA0_BASE_ADDR + 0x00024000)
+#define MX51_SPDIF_BASE_ADDR		(MX51_SPBA0_BASE_ADDR + 0x00028000)
+#define MX51_ATA_DMA_BASE_ADDR		(MX51_SPBA0_BASE_ADDR + 0x00030000)
+#define MX51_SLIM_DMA_BASE_ADDR		(MX51_SPBA0_BASE_ADDR + 0x00034000)
+#define MX51_HSI2C_DMA_BASE_ADDR	(MX51_SPBA0_BASE_ADDR + 0x00038000)
+#define MX51_SPBA_CTRL_BASE_ADDR	(MX51_SPBA0_BASE_ADDR + 0x0003C000)
+
+/*
+ * defines for SPBA modules
+ */
+#define MX51_SPBA_SDHC1	0x04
+#define MX51_SPBA_SDHC2	0x08
+#define MX51_SPBA_UART3	0x0C
+#define MX51_SPBA_CSPI1	0x10
+#define MX51_SPBA_SSI2	0x14
+#define MX51_SPBA_SDHC3	0x20
+#define MX51_SPBA_SDHC4	0x24
+#define MX51_SPBA_SPDIF	0x28
+#define MX51_SPBA_ATA	0x30
+#define MX51_SPBA_SLIM	0x34
+#define MX51_SPBA_HSI2C	0x38
+#define MX51_SPBA_CTRL	0x3C
+
+/*
+ * AIPS 1
+ */
+#define MX51_AIPS1_BASE_ADDR 	0x73F00000
+#define MX51_AIPS1_BASE_ADDR_VIRT	0xFB000000
+#define MX51_AIPS1_SIZE		SZ_1M
+
+#define MX51_OTG_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00080000)
+#define MX51_GPIO1_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00084000)
+#define MX51_GPIO2_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00088000)
+#define MX51_GPIO3_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x0008C000)
+#define MX51_GPIO4_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00090000)
+#define MX51_KPP_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00094000)
+#define MX51_WDOG_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00098000)
+#define MX51_WDOG2_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x0009C000)
+#define MX51_GPT1_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000A0000)
+#define MX51_SRTC_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000A4000)
+#define MX51_IOMUXC_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000A8000)
+#define MX51_EPIT1_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000AC000)
+#define MX51_EPIT2_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000B0000)
+#define MX51_PWM1_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000B4000)
+#define MX51_PWM2_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000B8000)
+#define MX51_UART1_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000BC000)
+#define MX51_UART2_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000C0000)
+#define MX51_SRC_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000D0000)
+#define MX51_CCM_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000D4000)
+#define MX51_GPC_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000D8000)
+
+/*
+ * Defines for modules using static and dynamic DMA channels
+ */
+#define MX51_MXC_DMA_CHANNEL_IRAM	30
+#define MX51_MXC_DMA_CHANNEL_SPDIF_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART1_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART1_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART2_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART2_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART3_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART3_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_MMC1	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_MMC2	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_SSI1_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_SSI1_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_SSI2_RX	MXC_DMA_DYNAMIC_CHANNEL
+#ifdef CONFIG_SDMA_IRAM
+#define MX51_MXC_DMA_CHANNEL_SSI2_TX	(MX51_MXC_DMA_CHANNEL_IRAM + 1)
+#else				/*CONFIG_SDMA_IRAM */
+#define MX51_MXC_DMA_CHANNEL_SSI2_TX	MXC_DMA_DYNAMIC_CHANNEL
+#endif				/*CONFIG_SDMA_IRAM */
+#define MX51_MXC_DMA_CHANNEL_CSPI1_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI1_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI2_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI2_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI3_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI3_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_ATA_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_ATA_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_MEMORY	MXC_DMA_DYNAMIC_CHANNEL
+
+/*
+ * AIPS 2
+ */
+#define MX51_AIPS2_BASE_ADDR		0x83F00000
+#define MX51_AIPS2_BASE_ADDR_VIRT	0xFB200000
+#define MX51_AIPS2_SIZE			SZ_1M
+
+#define MX51_PLL1_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x00080000)
+#define MX51_PLL2_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x00084000)
+#define MX51_PLL3_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x00088000)
+#define MX51_AHBMAX_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x00094000)
+#define MX51_IIM_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x00098000)
+#define MX51_CSU_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x0009C000)
+#define MX51_ARM_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000A0000)
+#define MX51_OWIRE_BASE_ADDR 	(MX51_AIPS2_BASE_ADDR + 0x000A4000)
+#define MX51_FIRI_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000A8000)
+#define MX51_CSPI2_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000AC000)
+#define MX51_SDMA_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000B0000)
+#define MX51_SCC_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000B4000)
+#define MX51_ROMCP_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000B8000)
+#define MX51_RTIC_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000BC000)
+#define MX51_CSPI3_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000C0000)
+#define MX51_I2C2_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000C4000)
+#define MX51_I2C1_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000C8000)
+#define MX51_SSI1_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000CC000)
+#define MX51_AUDMUX_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000D0000)
+#define MX51_M4IF_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000D8000)
+#define MX51_ESDCTL_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000D9000)
+#define MX51_WEIM_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000DA000)
+#define MX51_NFC_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000DB000)
+#define MX51_EMI_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000DBF00)
+#define MX51_MIPI_HSC_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000DC000)
+#define MX51_ATA_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000E0000)
+#define MX51_SIM_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000E4000)
+#define MX51_SSI3BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000E8000)
+#define MX51_MXC_FEC_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000EC000)
+#define MX51_TVE_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000F0000)
+#define MX51_VPU_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000F4000)
+#define MX51_SAHARA_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000F8000)
+
+/*
+ * Memory regions and CS
+ */
+#define MX51_GPU_CTRL_BASE_ADDR		0x30000000
+#define MX51_IPU_CTRL_BASE_ADDR		0x40000000
+#define MX51_CSD0_BASE_ADDR		0x90000000
+#define MX51_CSD1_BASE_ADDR		0xA0000000
+#define MX51_CS0_BASE_ADDR		0xB0000000
+#define MX51_CS1_BASE_ADDR		0xB8000000
+#define MX51_CS2_BASE_ADDR		0xC0000000
+#define MX51_CS3_BASE_ADDR		0xC8000000
+#define MX51_CS4_BASE_ADDR		0xCC000000
+#define MX51_CS5_BASE_ADDR		0xCE000000
+
+/* Does given address belongs to the specified memory region? */
+#define ADDRESS_IN_REGION(addr, start, size)			\
+	(((addr) >= (start)) && ((addr) < (start)+(size)))
+
+/* Does given address belongs to the specified named `module'? */
+#define MX51_IS_MODULE(addr, module)			       \
+	ADDRESS_IN_REGION(addr, MX51_ ## module ## _BASE_ADDR, \
+				MX51_ ## module ## _SIZE)
+/*
+ * 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 MX51_IO_ADDRESS(x)					\
+	(void __iomem *)					\
+	(MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) :	\
+	MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) :	\
+	MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) :	\
+	MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) :	\
+	MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \
+	0xDEADBEEF)
+
+/*
+ * define the address mapping macros: in physical address order
+ */
+#define MX51_IRAM_IO_ADDRESS(x)  \
+	(((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT)
+
+#define MX51_DEBUG_IO_ADDRESS(x)  \
+	(((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT)
+
+#define MX51_SPBA0_IO_ADDRESS(x)  \
+	(((x) - MX51_SPBA0_BASE_ADDR) + MX51_SPBA0_BASE_ADDR_VIRT)
+
+#define MX51_AIPS1_IO_ADDRESS(x)  \
+	(((x) - MX51_AIPS1_BASE_ADDR) + MX51_AIPS1_BASE_ADDR_VIRT)
+
+#define MX51_AIPS2_IO_ADDRESS(x)  \
+	(((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT)
+
+#define MX51_IS_MEM_DEVICE_NONSHARED(x)		0
+
+/*
+ * DMA request assignments
+ */
+#define MX51_DMA_REQ_SSI3_TX1	47
+#define MX51_DMA_REQ_SSI3_RX1	46
+#define MX51_DMA_REQ_SPDIF	45
+#define MX51_DMA_REQ_UART3_TX	44
+#define MX51_DMA_REQ_UART3_RX	43
+#define MX51_DMA_REQ_SLIM_B_TX	42
+#define MX51_DMA_REQ_SDHC4	41
+#define MX51_DMA_REQ_SDHC3	40
+#define MX51_DMA_REQ_CSPI_TX	39
+#define MX51_DMA_REQ_CSPI_RX	38
+#define MX51_DMA_REQ_SSI3_TX2	37
+#define MX51_DMA_REQ_IPU	36
+#define MX51_DMA_REQ_SSI3_RX2	35
+#define MX51_DMA_REQ_EPIT2	34
+#define MX51_DMA_REQ_CTI2_1	33
+#define MX51_DMA_REQ_EMI_WR	32
+#define MX51_DMA_REQ_CTI2_0	31
+#define MX51_DMA_REQ_EMI_RD	30
+#define MX51_DMA_REQ_SSI1_TX1	29
+#define MX51_DMA_REQ_SSI1_RX1	28
+#define MX51_DMA_REQ_SSI1_TX2	27
+#define MX51_DMA_REQ_SSI1_RX2	26
+#define MX51_DMA_REQ_SSI2_TX1	25
+#define MX51_DMA_REQ_SSI2_RX1	24
+#define MX51_DMA_REQ_SSI2_TX2	23
+#define MX51_DMA_REQ_SSI2_RX2	22
+#define MX51_DMA_REQ_SDHC2	21
+#define MX51_DMA_REQ_SDHC1	20
+#define MX51_DMA_REQ_UART1_TX	19
+#define MX51_DMA_REQ_UART1_RX	18
+#define MX51_DMA_REQ_UART2_TX	17
+#define MX51_DMA_REQ_UART2_RX	16
+#define MX51_DMA_REQ_GPU	15
+#define MX51_DMA_REQ_EXTREQ1	14
+#define MX51_DMA_REQ_FIRI_TX	13
+#define MX51_DMA_REQ_FIRI_RX	12
+#define MX51_DMA_REQ_HS_I2C_RX	11
+#define MX51_DMA_REQ_HS_I2C_TX	10
+#define MX51_DMA_REQ_CSPI2_TX	9
+#define MX51_DMA_REQ_CSPI2_RX	8
+#define MX51_DMA_REQ_CSPI1_TX	7
+#define MX51_DMA_REQ_CSPI1_RX	6
+#define MX51_DMA_REQ_SLIM_B	5
+#define MX51_DMA_REQ_ATA_TX_END	4
+#define MX51_DMA_REQ_ATA_TX	3
+#define MX51_DMA_REQ_ATA_RX	2
+#define MX51_DMA_REQ_GPC	1
+#define MX51_DMA_REQ_VPU	0
+
+/*
+ * Interrupt numbers
+ */
+#define MX51_MXC_INT_BASE	0
+#define MX51_MXC_INT_RESV0	0
+#define MX51_MXC_INT_MMC_SDHC1	1
+#define MX51_MXC_INT_MMC_SDHC2	2
+#define MX51_MXC_INT_MMC_SDHC3	3
+#define MX51_MXC_INT_MMC_SDHC4	4
+#define MX51_MXC_INT_RESV5	5
+#define MX51_MXC_INT_SDMA	6
+#define MX51_MXC_INT_IOMUX	7
+#define MX51_MXC_INT_NFC	8
+#define MX51_MXC_INT_VPU	9
+#define MX51_MXC_INT_IPU_ERR	10
+#define MX51_MXC_INT_IPU_SYN	11
+#define MX51_MXC_INT_GPU	12
+#define MX51_MXC_INT_RESV13	13
+#define MX51_MXC_INT_USB_H1	14
+#define MX51_MXC_INT_EMI	15
+#define MX51_MXC_INT_USB_H2	16
+#define MX51_MXC_INT_USB_H3	17
+#define MX51_MXC_INT_USB_OTG	18
+#define MX51_MXC_INT_SAHARA_H0	19
+#define MX51_MXC_INT_SAHARA_H1	20
+#define MX51_MXC_INT_SCC_SMN	21
+#define MX51_MXC_INT_SCC_STZ	22
+#define MX51_MXC_INT_SCC_SCM	23
+#define MX51_MXC_INT_SRTC_NTZ	24
+#define MX51_MXC_INT_SRTC_TZ	25
+#define MX51_MXC_INT_RTIC	26
+#define MX51_MXC_INT_CSU	27
+#define MX51_MXC_INT_SLIM_B	28
+#define MX51_MXC_INT_SSI1	29
+#define MX51_MXC_INT_SSI2	30
+#define MX51_MXC_INT_UART1	31
+#define MX51_MXC_INT_UART2	32
+#define MX51_MXC_INT_UART3	33
+#define MX51_MXC_INT_RESV34	34
+#define MX51_MXC_INT_RESV35	35
+#define MX51_MXC_INT_CSPI1	36
+#define MX51_MXC_INT_CSPI2	37
+#define MX51_MXC_INT_CSPI	38
+#define MX51_MXC_INT_GPT	39
+#define MX51_MXC_INT_EPIT1	40
+#define MX51_MXC_INT_EPIT2	41
+#define MX51_MXC_INT_GPIO1_INT7	42
+#define MX51_MXC_INT_GPIO1_INT6	43
+#define MX51_MXC_INT_GPIO1_INT5	44
+#define MX51_MXC_INT_GPIO1_INT4	45
+#define MX51_MXC_INT_GPIO1_INT3	46
+#define MX51_MXC_INT_GPIO1_INT2	47
+#define MX51_MXC_INT_GPIO1_INT1	48
+#define MX51_MXC_INT_GPIO1_INT0	49
+#define MX51_MXC_INT_GPIO1_LOW	50
+#define MX51_MXC_INT_GPIO1_HIGH	51
+#define MX51_MXC_INT_GPIO2_LOW	52
+#define MX51_MXC_INT_GPIO2_HIGH	53
+#define MX51_MXC_INT_GPIO3_LOW	54
+#define MX51_MXC_INT_GPIO3_HIGH	55
+#define MX51_MXC_INT_GPIO4_LOW	56
+#define MX51_MXC_INT_GPIO4_HIGH	57
+#define MX51_MXC_INT_WDOG1	58
+#define MX51_MXC_INT_WDOG2	59
+#define MX51_MXC_INT_KPP	60
+#define MX51_MXC_INT_PWM1	61
+#define MX51_MXC_INT_I2C1	62
+#define MX51_MXC_INT_I2C2	63
+#define MX51_MXC_INT_HS_I2C	64
+#define MX51_MXC_INT_RESV65	65
+#define MX51_MXC_INT_RESV66	66
+#define MX51_MXC_INT_SIM_IPB	67
+#define MX51_MXC_INT_SIM_DAT	68
+#define MX51_MXC_INT_IIM	69
+#define MX51_MXC_INT_ATA	70
+#define MX51_MXC_INT_CCM1	71
+#define MX51_MXC_INT_CCM2	72
+#define MX51_MXC_INT_GPC1	73
+#define MX51_MXC_INT_GPC2	74
+#define MX51_MXC_INT_SRC	75
+#define MX51_MXC_INT_NM		76
+#define MX51_MXC_INT_PMU	77
+#define MX51_MXC_INT_CTI_IRQ	78
+#define MX51_MXC_INT_CTI1_TG0	79
+#define MX51_MXC_INT_CTI1_TG1	80
+#define MX51_MXC_INT_MCG_ERR	81
+#define MX51_MXC_INT_MCG_TMR	82
+#define MX51_MXC_INT_MCG_FUNC	83
+#define MX51_MXC_INT_GPU2_IRQ	84
+#define MX51_MXC_INT_GPU2_BUSY	85
+#define MX51_MXC_INT_RESV86	86
+#define MX51_MXC_INT_FEC	87
+#define MX51_MXC_INT_OWIRE	88
+#define MX51_MXC_INT_CTI1_TG2	89
+#define MX51_MXC_INT_SJC	90
+#define MX51_MXC_INT_SPDIF	91
+#define MX51_MXC_INT_TVE	92
+#define MX51_MXC_INT_FIRI	93
+#define MX51_MXC_INT_PWM2	94
+#define MX51_MXC_INT_SLIM_EXP	95
+#define MX51_MXC_INT_SSI3	96
+#define MX51_MXC_INT_EMI_BOOT	97
+#define MX51_MXC_INT_CTI1_TG3	98
+#define MX51_MXC_INT_SMC_RX	99
+#define MX51_MXC_INT_VPU_IDLE	100
+#define MX51_MXC_INT_EMI_NFC	101
+#define MX51_MXC_INT_GPU_IDLE	102
+
+/* silicon revisions specific to i.MX51 */
+#define MX51_CHIP_REV_1_0	0x10
+#define MX51_CHIP_REV_1_1	0x11
+#define MX51_CHIP_REV_1_2	0x12
+#define MX51_CHIP_REV_1_3	0x13
+#define MX51_CHIP_REV_2_0	0x20
+#define MX51_CHIP_REV_2_1	0x21
+#define MX51_CHIP_REV_2_2	0x22
+#define MX51_CHIP_REV_2_3	0x23
+#define MX51_CHIP_REV_3_0	0x30
+#define MX51_CHIP_REV_3_1	0x31
+#define MX51_CHIP_REV_3_2	0x32
+
+/* Mandatory defines used globally */
+
+#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
+
+extern int mx51_revision(void);
+#endif
+
+#endif	/*  __ASM_ARCH_MXC_MX51_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mxc91231.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mxc91231.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mxc91231.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mxc91231.h	2010-05-16 17:17:36.000000000 -0400
@@ -184,60 +184,22 @@
 #define MXC91231_CS4_BASE_ADDR		0xB4000000
 #define MXC91231_CS5_BASE_ADDR		0xB6000000
 
-/* Is given address belongs to the specified memory region? */
-#define ADDRESS_IN_REGION(addr, start, size) \
-	(((addr) >= (start)) && ((addr) < (start)+(size)))
-
-/* Is given address belongs to the specified named `module'? */
-#define MXC91231_IS_MODULE(addr, module) \
-	ADDRESS_IN_REGION(addr, MXC91231_ ## module ## _BASE_ADDR, \
-	                        MXC91231_ ## module ## _SIZE)
 /*
  * 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 MXC91231_IO_ADDRESS(x) \
-	(void __iomem *) \
-	(MXC91231_IS_MODULE(x, L2CC) ? MXC91231_L2CC_IO_ADDRESS(x) : \
-	 MXC91231_IS_MODULE(x, AIPS1) ? MXC91231_AIPS1_IO_ADDRESS(x) : \
-	 MXC91231_IS_MODULE(x, AIPS2) ? MXC91231_AIPS2_IO_ADDRESS(x) : \
-	 MXC91231_IS_MODULE(x, SPBA0) ? MXC91231_SPBA0_IO_ADDRESS(x) : \
-	 MXC91231_IS_MODULE(x, SPBA1) ? MXC91231_SPBA1_IO_ADDRESS(x) : \
-	 MXC91231_IS_MODULE(x, ROMP) ? MXC91231_ROMP_IO_ADDRESS(x) : \
-	 MXC91231_IS_MODULE(x, AVIC) ? MXC91231_AVIC_IO_ADDRESS(x) : \
-	 MXC91231_IS_MODULE(x, X_MEMC) ? MXC91231_X_MEMC_IO_ADDRESS(x) : \
-	 0xDEADBEEF)
-
-
-/*
- * define the address mapping macros: in physical address order
+ * it returns 0.
  */
-#define MXC91231_L2CC_IO_ADDRESS(x)  \
-	(((x) - MXC91231_L2CC_BASE_ADDR) + MXC91231_L2CC_BASE_ADDR_VIRT)
 
-#define MXC91231_AIPS1_IO_ADDRESS(x)  \
-	(((x) - MXC91231_AIPS1_BASE_ADDR) + MXC91231_AIPS1_BASE_ADDR_VIRT)
-
-#define MXC91231_SPBA0_IO_ADDRESS(x)  \
-	(((x) - MXC91231_SPBA0_BASE_ADDR) + MXC91231_SPBA0_BASE_ADDR_VIRT)
-
-#define MXC91231_SPBA1_IO_ADDRESS(x)  \
-	(((x) - MXC91231_SPBA1_BASE_ADDR) + MXC91231_SPBA1_BASE_ADDR_VIRT)
-
-#define MXC91231_AIPS2_IO_ADDRESS(x)  \
-	(((x) - MXC91231_AIPS2_BASE_ADDR) + MXC91231_AIPS2_BASE_ADDR_VIRT)
-
-#define MXC91231_ROMP_IO_ADDRESS(x)  \
-	(((x) - MXC91231_ROMP_BASE_ADDR) + MXC91231_ROMP_BASE_ADDR_VIRT)
-
-#define MXC91231_AVIC_IO_ADDRESS(x)  \
-	(((x) - MXC91231_AVIC_BASE_ADDR) + MXC91231_AVIC_BASE_ADDR_VIRT)
-
-#define MXC91231_X_MEMC_IO_ADDRESS(x)  \
-	(((x) - MXC91231_X_MEMC_BASE_ADDR) + MXC91231_X_MEMC_BASE_ADDR_VIRT)
+#define MXC91231_IO_ADDRESS(x) (					\
+	IMX_IO_ADDRESS(x, MXC91231_L2CC) ?:				\
+	IMX_IO_ADDRESS(x, MXC91231_X_MEMC) ?:				\
+	IMX_IO_ADDRESS(x, MXC91231_ROMP) ?:				\
+	IMX_IO_ADDRESS(x, MXC91231_AVIC) ?:				\
+	IMX_IO_ADDRESS(x, MXC91231_AIPS1) ?:				\
+	IMX_IO_ADDRESS(x, MXC91231_SPBA0) ?:				\
+	IMX_IO_ADDRESS(x, MXC91231_SPBA1) ?:				\
+	IMX_IO_ADDRESS(x, MXC91231_AIPS2))
 
 /*
  * Interrupt numbers
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mxc_ehci.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mxc_ehci.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mxc_ehci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mxc_ehci.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,10 @@
 #define MXC_EHCI_POWER_PINS_ENABLED	(1 << 5)
 #define MXC_EHCI_TTL_ENABLED		(1 << 6)
 
+#define MXC_EHCI_INTERNAL_PHY		(1 << 7)
+#define MXC_EHCI_IPPUE_DOWN		(1 << 8)
+#define MXC_EHCI_IPPUE_UP		(1 << 9)
+
 struct mxc_usbh_platform_data {
 	int (*init)(struct platform_device *pdev);
 	int (*exit)(struct platform_device *pdev);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mxc.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mxc.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mxc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/mxc.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #define MXC_CPU_MX27		27
 #define MXC_CPU_MX31		31
 #define MXC_CPU_MX35		35
+#define MXC_CPU_MX51		51
 #define MXC_CPU_MXC91231	91231
 
 #ifndef __ASSEMBLY__
@@ -108,6 +109,18 @@ extern unsigned int __mxc_cpu_type;
 # define cpu_is_mx35()		(0)
 #endif
 
+#ifdef CONFIG_ARCH_MX5
+# ifdef mxc_cpu_type
+#  undef mxc_cpu_type
+#  define mxc_cpu_type __mxc_cpu_type
+# else
+#  define mxc_cpu_type MXC_CPU_MX51
+# endif
+# define cpu_is_mx51()		(mxc_cpu_type == MXC_CPU_MX51)
+#else
+# define cpu_is_mx51()		(0)
+#endif
+
 #ifdef CONFIG_ARCH_MXC91231
 # ifdef mxc_cpu_type
 #  undef mxc_cpu_type
@@ -121,9 +134,10 @@ extern unsigned int __mxc_cpu_type;
 #endif
 
 #if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2)
-#define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10)
-#define CSCR_L(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x4)
-#define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x8)
+/* These are deprecated, use mx[23][157]_setup_weimcs instead. */
+#define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR + n * 0x10))
+#define CSCR_L(n) (IO_ADDRESS(WEIM_BASE_ADDR + n * 0x10 + 0x4))
+#define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR + n * 0x10 + 0x8))
 #endif
 
 #define cpu_is_mx3()	(cpu_is_mx31() || cpu_is_mx35() || cpu_is_mxc91231())
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/ssi.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/ssi.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/ssi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/ssi.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,18 @@
+#ifndef __MACH_SSI_H
+#define __MACH_SSI_H
+
+struct snd_ac97;
+
+extern unsigned char imx_ssi_fiq_start, imx_ssi_fiq_end;
+extern unsigned long imx_ssi_fiq_base, imx_ssi_fiq_tx_buffer, imx_ssi_fiq_rx_buffer;
+
+struct imx_ssi_platform_data {
+	unsigned int flags;
+#define IMX_SSI_DMA            (1 << 0)
+#define IMX_SSI_USE_AC97       (1 << 1)
+	void (*ac97_reset) (struct snd_ac97 *ac97);
+	void (*ac97_warm_reset)(struct snd_ac97 *ac97);
+};
+
+#endif /* __MACH_SSI_H */
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/timex.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/timex.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/timex.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/timex.h	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,8 @@
 #define CLOCK_TICK_RATE		16625000
 #elif defined CONFIG_ARCH_MX25
 #define CLOCK_TICK_RATE		16000000
+#elif defined CONFIG_ARCH_MX5
+#define CLOCK_TICK_RATE		8000000
 #elif defined CONFIG_ARCH_MXC91231
 #define CLOCK_TICK_RATE		13000000
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/uncompress.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/uncompress.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/uncompress.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/uncompress.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,8 +1,6 @@
 /*
  *  arch/arm/plat-mxc/include/mach/uncompress.h
  *
- *
- *
  *  Copyright (C) 1999 ARM Limited
  *  Copyright (C) Shane Nay (shane@minirl.com)
  *
@@ -25,7 +23,6 @@
 
 #define __MXC_BOOT_UNCOMPRESS
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 
 static unsigned long uart_base;
@@ -69,6 +66,7 @@ static inline void flush(void)
 #define MX2X_UART1_BASE_ADDR	0x1000a000
 #define MX3X_UART1_BASE_ADDR	0x43F90000
 #define MX3X_UART2_BASE_ADDR	0x43F94000
+#define MX51_UART1_BASE_ADDR	0x73fbc000
 
 static __inline__ void __arch_decomp_setup(unsigned long arch_id)
 {
@@ -104,6 +102,9 @@ static __inline__ void __arch_decomp_set
 	case MACH_TYPE_MAGX_ZN5:
 		uart_base = MX3X_UART2_BASE_ADDR;
 		break;
+	case MACH_TYPE_MX51_BABBAGE:
+		uart_base = MX51_UART1_BASE_ADDR;
+		break;
 	default:
 		break;
 	}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,6 @@
 #define __ASM_ARCH_MXC_VMALLOC_H__
 
 /* vmalloc ending address */
-#define VMALLOC_END       0xF4000000
+#define VMALLOC_END       0xf4000000UL
 
 #endif /* __ASM_ARCH_MXC_VMALLOC_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/iomux-mx1-mx2.c linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/iomux-mx1-mx2.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/iomux-mx1-mx2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/iomux-mx1-mx2.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,157 +0,0 @@
-/*
- *  arch/arm/mach-mxc/generic.c
- *
- *  author: Sascha Hauer
- *  Created: april 20th, 2004
- *  Copyright: Synertronixx GmbH
- *
- *  Common code for i.MX machines
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/gpio.h>
-
-#include <mach/hardware.h>
-#include <asm/mach/map.h>
-#include <mach/iomux.h>
-
-void mxc_gpio_mode(int gpio_mode)
-{
-	unsigned int pin = gpio_mode & GPIO_PIN_MASK;
-	unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
-	unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT;
-	unsigned int tmp;
-
-	/* Pullup enable */
-	tmp = __raw_readl(VA_GPIO_BASE + MXC_PUEN(port));
-	if (gpio_mode & GPIO_PUEN)
-		tmp |= (1 << pin);
-	else
-		tmp &= ~(1 << pin);
-	__raw_writel(tmp, VA_GPIO_BASE + MXC_PUEN(port));
-
-	/* Data direction */
-	tmp = __raw_readl(VA_GPIO_BASE + MXC_DDIR(port));
-	if (gpio_mode & GPIO_OUT)
-		tmp |= 1 << pin;
-	else
-		tmp &= ~(1 << pin);
-	__raw_writel(tmp, VA_GPIO_BASE + MXC_DDIR(port));
-
-	/* Primary / alternate function */
-	tmp = __raw_readl(VA_GPIO_BASE + MXC_GPR(port));
-	if (gpio_mode & GPIO_AF)
-		tmp |= (1 << pin);
-	else
-		tmp &= ~(1 << pin);
-	__raw_writel(tmp, VA_GPIO_BASE + MXC_GPR(port));
-
-	/* use as gpio? */
-	tmp = __raw_readl(VA_GPIO_BASE + MXC_GIUS(port));
-	if (gpio_mode & (GPIO_PF | GPIO_AF))
-		tmp &= ~(1 << pin);
-	else
-		tmp |= (1 << pin);
-	__raw_writel(tmp, VA_GPIO_BASE + MXC_GIUS(port));
-
-	if (pin < 16) {
-		tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR1(port));
-		tmp &= ~(3 << (pin * 2));
-		tmp |= (ocr << (pin * 2));
-		__raw_writel(tmp, VA_GPIO_BASE + MXC_OCR1(port));
-
-		tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA1(port));
-		tmp &= ~(3 << (pin * 2));
-		tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2);
-		__raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFA1(port));
-
-		tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFB1(port));
-		tmp &= ~(3 << (pin * 2));
-		tmp |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2);
-		__raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB1(port));
-	} else {
-		pin -= 16;
-
-		tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR2(port));
-		tmp &= ~(3 << (pin * 2));
-		tmp |= (ocr << (pin * 2));
-		__raw_writel(tmp, VA_GPIO_BASE + MXC_OCR2(port));
-
-		tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA2(port));
-		tmp &= ~(3 << (pin * 2));
-		tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2);
-		__raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFA2(port));
-
-		tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFB2(port));
-		tmp &= ~(3 << (pin * 2));
-		tmp |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2);
-		__raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB2(port));
-	}
-}
-EXPORT_SYMBOL(mxc_gpio_mode);
-
-int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
-		const char *label)
-{
-	const int *p = pin_list;
-	int i;
-	unsigned gpio;
-	unsigned mode;
-	int ret = -EINVAL;
-
-	for (i = 0; i < count; i++) {
-		gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK);
-		mode = *p & ~(GPIO_PIN_MASK | GPIO_PORT_MASK);
-
-		if (gpio >= (GPIO_PORT_MAX + 1) * 32)
-			goto setup_error;
-
-		ret = gpio_request(gpio, label);
-		if (ret)
-			goto setup_error;
-
-		mxc_gpio_mode(gpio | mode);
-
-		p++;
-	}
-	return 0;
-
-setup_error:
-	mxc_gpio_release_multiple_pins(pin_list, i);
-	return ret;
-}
-EXPORT_SYMBOL(mxc_gpio_setup_multiple_pins);
-
-void mxc_gpio_release_multiple_pins(const int *pin_list, int count)
-{
-	const int *p = pin_list;
-	int i;
-
-	for (i = 0; i < count; i++) {
-		unsigned gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK);
-		gpio_free(gpio);
-		p++;
-	}
-
-}
-EXPORT_SYMBOL(mxc_gpio_release_multiple_pins);
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/iomux-v1.c linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/iomux-v1.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/iomux-v1.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/iomux-v1.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,238 @@
+/*
+ * arch/arm/plat-mxc/iomux-v1.c
+ *
+ * Copyright (C) 2004 Sascha Hauer, Synertronixx GmbH
+ * Copyright (C) 2009 Uwe Kleine-Koenig, Pengutronix
+ *
+ * Common code for i.MX1, 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/map.h>
+#include <mach/iomux-v1.h>
+
+static void __iomem *imx_iomuxv1_baseaddr;
+static unsigned imx_iomuxv1_numports;
+
+static inline unsigned long imx_iomuxv1_readl(unsigned offset)
+{
+	return __raw_readl(imx_iomuxv1_baseaddr + offset);
+}
+
+static inline void imx_iomuxv1_writel(unsigned long val, unsigned offset)
+{
+	__raw_writel(val, imx_iomuxv1_baseaddr + offset);
+}
+
+static inline void imx_iomuxv1_rmwl(unsigned offset,
+		unsigned long mask, unsigned long value)
+{
+	unsigned long reg = imx_iomuxv1_readl(offset);
+
+	reg &= ~mask;
+	reg |= value;
+
+	imx_iomuxv1_writel(reg, offset);
+}
+
+static inline void imx_iomuxv1_set_puen(
+		unsigned int port, unsigned int pin, int on)
+{
+	unsigned long mask = 1 << pin;
+
+	imx_iomuxv1_rmwl(MXC_PUEN(port), mask, on ? mask : 0);
+}
+
+static inline void imx_iomuxv1_set_ddir(
+		unsigned int port, unsigned int pin, int out)
+{
+	unsigned long mask = 1 << pin;
+
+	imx_iomuxv1_rmwl(MXC_DDIR(port), mask, out ? mask : 0);
+}
+
+static inline void imx_iomuxv1_set_gpr(
+		unsigned int port, unsigned int pin, int af)
+{
+	unsigned long mask = 1 << pin;
+
+	imx_iomuxv1_rmwl(MXC_GPR(port), mask, af ? mask : 0);
+}
+
+static inline void imx_iomuxv1_set_gius(
+		unsigned int port, unsigned int pin, int inuse)
+{
+	unsigned long mask = 1 << pin;
+
+	imx_iomuxv1_rmwl(MXC_GIUS(port), mask, inuse ? mask : 0);
+}
+
+static inline void imx_iomuxv1_set_ocr(
+		unsigned int port, unsigned int pin, unsigned int ocr)
+{
+	unsigned long shift = (pin & 0xf) << 1;
+	unsigned long mask = 3 << shift;
+	unsigned long value = ocr << shift;
+	unsigned long offset = pin < 16 ? MXC_OCR1(port) : MXC_OCR2(port);
+
+	imx_iomuxv1_rmwl(offset, mask, value);
+}
+
+static inline void imx_iomuxv1_set_iconfa(
+		unsigned int port, unsigned int pin, unsigned int aout)
+{
+	unsigned long shift = (pin & 0xf) << 1;
+	unsigned long mask = 3 << shift;
+	unsigned long value = aout << shift;
+	unsigned long offset = pin < 16 ? MXC_ICONFA1(port) : MXC_ICONFA2(port);
+
+	imx_iomuxv1_rmwl(offset, mask, value);
+}
+
+static inline void imx_iomuxv1_set_iconfb(
+		unsigned int port, unsigned int pin, unsigned int bout)
+{
+	unsigned long shift = (pin & 0xf) << 1;
+	unsigned long mask = 3 << shift;
+	unsigned long value = bout << shift;
+	unsigned long offset = pin < 16 ? MXC_ICONFB1(port) : MXC_ICONFB2(port);
+
+	imx_iomuxv1_rmwl(offset, mask, value);
+}
+
+int mxc_gpio_mode(int gpio_mode)
+{
+	unsigned int pin = gpio_mode & GPIO_PIN_MASK;
+	unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+	unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT;
+	unsigned int aout = (gpio_mode >> GPIO_AOUT_SHIFT) & 3;
+	unsigned int bout = (gpio_mode >> GPIO_BOUT_SHIFT) & 3;
+
+	if (port >= imx_iomuxv1_numports)
+		return -EINVAL;
+
+	/* Pullup enable */
+	imx_iomuxv1_set_puen(port, pin, gpio_mode & GPIO_PUEN);
+
+	/* Data direction */
+	imx_iomuxv1_set_ddir(port, pin, gpio_mode & GPIO_OUT);
+
+	/* Primary / alternate function */
+	imx_iomuxv1_set_gpr(port, pin, gpio_mode & GPIO_AF);
+
+	/* use as gpio? */
+	imx_iomuxv1_set_gius(port, pin, !(gpio_mode & (GPIO_PF | GPIO_AF)));
+
+	imx_iomuxv1_set_ocr(port, pin, ocr);
+
+	imx_iomuxv1_set_iconfa(port, pin, aout);
+
+	imx_iomuxv1_set_iconfb(port, pin, bout);
+
+	return 0;
+}
+EXPORT_SYMBOL(mxc_gpio_mode);
+
+static int imx_iomuxv1_setup_multiple(const int *list, unsigned count)
+{
+	size_t i;
+	int ret;
+
+	for (i = 0; i < count; ++i) {
+		ret = mxc_gpio_mode(list[i]);
+
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
+		const char *label)
+{
+	size_t i;
+	int ret;
+
+	for (i = 0; i < count; ++i) {
+		unsigned gpio = pin_list[i] & (GPIO_PIN_MASK | GPIO_PORT_MASK);
+
+		ret = gpio_request(gpio, label);
+		if (ret)
+			goto err_gpio_request;
+	}
+
+	ret = imx_iomuxv1_setup_multiple(pin_list, count);
+	if (ret)
+		goto err_setup;
+
+	return 0;
+
+err_setup:
+	BUG_ON(i != count);
+
+err_gpio_request:
+	mxc_gpio_release_multiple_pins(pin_list, i);
+
+	return ret;
+}
+EXPORT_SYMBOL(mxc_gpio_setup_multiple_pins);
+
+void mxc_gpio_release_multiple_pins(const int *pin_list, int count)
+{
+	size_t i;
+
+	for (i = 0; i < count; ++i) {
+		unsigned gpio = pin_list[i] & (GPIO_PIN_MASK | GPIO_PORT_MASK);
+
+		gpio_free(gpio);
+	}
+}
+EXPORT_SYMBOL(mxc_gpio_release_multiple_pins);
+
+static int imx_iomuxv1_init(void)
+{
+#ifdef CONFIG_ARCH_MX1
+	if (cpu_is_mx1()) {
+		imx_iomuxv1_baseaddr = MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR);
+		imx_iomuxv1_numports = MX1_NUM_GPIO_PORT;
+	} else
+#endif
+#ifdef CONFIG_MACH_MX21
+	if (cpu_is_mx21()) {
+		imx_iomuxv1_baseaddr = MX21_IO_ADDRESS(MX21_GPIO_BASE_ADDR);
+		imx_iomuxv1_numports = MX21_NUM_GPIO_PORT;
+	} else
+#endif
+#ifdef CONFIG_MACH_MX27
+	if (cpu_is_mx27()) {
+		imx_iomuxv1_baseaddr = MX27_IO_ADDRESS(MX27_GPIO_BASE_ADDR);
+		imx_iomuxv1_numports = MX27_NUM_GPIO_PORT;
+	} else
+#endif
+		return -ENODEV;
+
+	return 0;
+}
+pure_initcall(imx_iomuxv1_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/Kconfig linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -9,38 +9,43 @@ choice
 config ARCH_MX1
 	bool "MX1-based"
 	select CPU_ARM920T
-	select COMMON_CLKDEV
+	select IMX_HAVE_IOMUX_V1
 	help
 	  This enables support for systems based on the Freescale i.MX1 family
 
 config ARCH_MX2
 	bool "MX2-based"
 	select CPU_ARM926T
-	select COMMON_CLKDEV
+	select IMX_HAVE_IOMUX_V1
 	help
 	  This enables support for systems based on the Freescale i.MX2 family
 
 config ARCH_MX25
 	bool "MX25-based"
 	select CPU_ARM926T
-	select COMMON_CLKDEV
+	select ARCH_MXC_IOMUX_V3
+	select HAVE_FB_IMX
 	help
 	  This enables support for systems based on the Freescale i.MX25 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
 
 config ARCH_MXC91231
 	bool "MXC91231-based"
 	select CPU_V6
-	select COMMON_CLKDEV
 	help
 	  This enables support for systems based on the Freescale MXC91231 family
 
+config ARCH_MX5
+	bool "MX5-based"
+	select CPU_V7
+	help
+	  This enables support for systems based on the Freescale i.MX51 family
+
 endchoice
 
 source "arch/arm/mach-mx1/Kconfig"
@@ -48,12 +53,12 @@ source "arch/arm/mach-mx2/Kconfig"
 source "arch/arm/mach-mx3/Kconfig"
 source "arch/arm/mach-mx25/Kconfig"
 source "arch/arm/mach-mxc91231/Kconfig"
+source "arch/arm/mach-mx5/Kconfig"
 
 endmenu
 
 config MXC_IRQ_PRIOR
 	bool "Use IRQ priority"
-	depends on ARCH_MXC
 	help
 	  Select this if you want to use prioritized IRQ handling.
 	  This feature prevents higher priority ISR to be interrupted
@@ -62,9 +67,16 @@ config MXC_IRQ_PRIOR
 	  requirements for timing.
 	  Say N here, unless you have a specialized requirement.
 
+config MXC_TZIC
+	bool "Enable TrustZone Interrupt Controller"
+	depends on ARCH_MX51
+	help
+	  This will be automatically selected for all processors
+	  containing this interrupt controller.
+	  Say N here only if you are really sure.
+
 config MXC_PWM
 	tristate "Enable PWM driver"
-	depends on ARCH_MXC
 	select HAVE_PWM
 	help
 	  Enable support for the i.MX PWM controller(s).
@@ -74,7 +86,9 @@ config MXC_ULPI
 
 config ARCH_HAS_RNGA
 	bool
-	depends on ARCH_MXC
+
+config IMX_HAVE_IOMUX_V1
+	bool
 
 config ARCH_MXC_IOMUX_V3
 	bool
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/Makefile linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,11 +5,19 @@
 # Common support
 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
+# MX51 uses the TZIC interrupt controller, older platforms use AVIC (irq.o)
+obj-$(CONFIG_MXC_TZIC) += tzic.o
+
+obj-$(CONFIG_ARCH_MX1) += dma-mx1-mx2.o
+obj-$(CONFIG_ARCH_MX2) += dma-mx1-mx2.o
+obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
 obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
 obj-$(CONFIG_MXC_PWM)  += pwm.o
 obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
 obj-$(CONFIG_MXC_ULPI) += ulpi.o
 obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
 obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
+ifdef CONFIG_SND_IMX_SOC
+obj-y += ssi-fiq.o
+obj-y += ssi-fiq-ksym.o
+endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/pwm.c linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/pwm.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/pwm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/pwm.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/ssi-fiq-ksym.c linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/ssi-fiq-ksym.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/ssi-fiq-ksym.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/ssi-fiq-ksym.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,20 @@
+/*
+ * Exported ksyms for the SSI FIQ handler
+ *
+ * Copyright (C) 2009, Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+
+#include <mach/ssi.h>
+
+EXPORT_SYMBOL(imx_ssi_fiq_tx_buffer);
+EXPORT_SYMBOL(imx_ssi_fiq_rx_buffer);
+EXPORT_SYMBOL(imx_ssi_fiq_start);
+EXPORT_SYMBOL(imx_ssi_fiq_end);
+EXPORT_SYMBOL(imx_ssi_fiq_base);
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/ssi-fiq.S linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/ssi-fiq.S
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/ssi-fiq.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/ssi-fiq.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,134 @@
+/*
+ *  Copyright (C) 2009 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * r8  = bit 0-15: tx offset, bit 16-31: tx buffer size
+ * r9  = bit 0-15: rx offset, bit 16-31: rx buffer size
+ */
+
+#define SSI_STX0	0x00
+#define SSI_SRX0	0x08
+#define SSI_SISR	0x14
+#define SSI_SIER	0x18
+#define SSI_SACNT	0x38
+
+#define SSI_SACNT_AC97EN	(1 << 0)
+
+#define SSI_SIER_TFE0_EN	(1 << 0)
+#define SSI_SISR_TFE0		(1 << 0)
+#define SSI_SISR_RFF0		(1 << 2)
+#define SSI_SIER_RFF0_EN	(1 << 2)
+
+		.text
+		.global	imx_ssi_fiq_start
+		.global	imx_ssi_fiq_end
+		.global imx_ssi_fiq_base
+		.global imx_ssi_fiq_rx_buffer
+		.global imx_ssi_fiq_tx_buffer
+
+imx_ssi_fiq_start:
+		ldr r12, imx_ssi_fiq_base
+
+		/* TX */
+		ldr r11, imx_ssi_fiq_tx_buffer
+
+		/* shall we send? */
+		ldr r13, [r12, #SSI_SIER]
+		tst r13, #SSI_SIER_TFE0_EN
+		beq 1f
+
+		/* TX FIFO empty? */
+		ldr r13, [r12, #SSI_SISR]
+		tst r13, #SSI_SISR_TFE0
+		beq 1f
+
+		mov r10, #0x10000
+		sub r10, #1
+		and r10, r10, r8	/* r10: current buffer offset */
+
+		add r11, r11, r10
+
+		ldrh r13, [r11]
+		strh r13, [r12, #SSI_STX0]
+
+		ldrh r13, [r11, #2]
+		strh r13, [r12, #SSI_STX0]
+
+		ldrh r13, [r11, #4]
+		strh r13, [r12, #SSI_STX0]
+
+		ldrh r13, [r11, #6]
+		strh r13, [r12, #SSI_STX0]
+
+		add r10, #8
+		lsr r13, r8, #16	/* r13: buffer size */
+		cmp r10, r13
+		lslgt r8, r13, #16
+		addle r8, #8
+1:
+		/* RX */
+
+		/* shall we receive? */
+		ldr r13, [r12, #SSI_SIER]
+		tst r13, #SSI_SIER_RFF0_EN
+		beq 1f
+
+		/* RX FIFO full? */
+		ldr r13, [r12, #SSI_SISR]
+		tst r13, #SSI_SISR_RFF0
+		beq 1f
+
+		ldr r11, imx_ssi_fiq_rx_buffer
+
+		mov r10, #0x10000
+		sub r10, #1
+		and r10, r10, r9	/* r10: current buffer offset */
+
+		add r11, r11, r10
+
+		ldr r13, [r12, #SSI_SACNT]
+		tst r13, #SSI_SACNT_AC97EN
+
+		ldr r13, [r12, #SSI_SRX0]
+		strh r13, [r11]
+
+		ldr r13, [r12, #SSI_SRX0]
+		strh r13, [r11, #2]
+
+		/* dummy read to skip slot 12 */
+		ldrne r13, [r12, #SSI_SRX0]
+
+		ldr r13, [r12, #SSI_SRX0]
+		strh r13, [r11, #4]
+
+		ldr r13, [r12, #SSI_SRX0]
+		strh r13, [r11, #6]
+
+		/* dummy read to skip slot 12 */
+		ldrne r13, [r12, #SSI_SRX0]
+
+		add r10, #8
+		lsr r13, r9, #16	/* r13: buffer size */
+		cmp r10, r13
+		lslgt r9, r13, #16
+		addle r9, #8
+
+1:
+		@ return from FIQ
+		subs	pc, lr, #4
+imx_ssi_fiq_base:
+		.word 0x0
+imx_ssi_fiq_rx_buffer:
+		.word 0x0
+imx_ssi_fiq_tx_buffer:
+		.word 0x0
+imx_ssi_fiq_end:
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/time.c linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/time.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,9 +30,15 @@
 #include <asm/mach/time.h>
 #include <mach/common.h>
 
+/*
+ * There are 2 versions of the timer hardware on Freescale MXC hardware.
+ * Version 1: MX1/MXL, MX21, MX27.
+ * Version 2: MX25, MX31, MX35, MX37, MX51
+ */
+
 /* defines common for all i.MX */
 #define MXC_TCTL		0x00
-#define MXC_TCTL_TEN		(1 << 0)
+#define MXC_TCTL_TEN		(1 << 0) /* Enable module */
 #define MXC_TPRER		0x04
 
 /* MX1, MX21, MX27 */
@@ -47,8 +53,8 @@
 #define MX2_TSTAT_CAPT		(1 << 1)
 #define MX2_TSTAT_COMP		(1 << 0)
 
-/* MX31, MX35, MX25, MXC91231 */
-#define MX3_TCTL_WAITEN		(1 << 3)
+/* MX31, MX35, MX25, MXC91231, MX5 */
+#define MX3_TCTL_WAITEN		(1 << 3) /* Wait enable mode */
 #define MX3_TCTL_CLK_IPG	(1 << 6)
 #define MX3_TCTL_FRR		(1 << 9)
 #define MX3_IR			0x0c
@@ -57,6 +63,9 @@
 #define MX3_TCN			0x24
 #define MX3_TCMP		0x10
 
+#define timer_is_v1()	(cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
+#define timer_is_v2()	(!timer_is_v1())
+
 static struct clock_event_device clockevent_mxc;
 static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
 
@@ -66,7 +75,7 @@ static inline void gpt_irq_disable(void)
 {
 	unsigned int tmp;
 
-	if (cpu_is_mx3() || cpu_is_mx25())
+	if (timer_is_v2())
 		__raw_writel(0, timer_base + MX3_IR);
 	else {
 		tmp = __raw_readl(timer_base + MXC_TCTL);
@@ -76,7 +85,7 @@ static inline void gpt_irq_disable(void)
 
 static inline void gpt_irq_enable(void)
 {
-	if (cpu_is_mx3() || cpu_is_mx25())
+	if (timer_is_v2())
 		__raw_writel(1<<0, timer_base + MX3_IR);
 	else {
 		__raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
@@ -86,11 +95,13 @@ static inline void gpt_irq_enable(void)
 
 static void gpt_irq_acknowledge(void)
 {
-	if (cpu_is_mx1())
-		__raw_writel(0, timer_base + MX1_2_TSTAT);
-	if (cpu_is_mx2())
-		__raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, timer_base + MX1_2_TSTAT);
-	if (cpu_is_mx3() || cpu_is_mx25())
+	if (timer_is_v1()) {
+		if (cpu_is_mx1())
+			__raw_writel(0, timer_base + MX1_2_TSTAT);
+		else
+			__raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
+				timer_base + MX1_2_TSTAT);
+	} else if (timer_is_v2())
 		__raw_writel(MX3_TSTAT_OF1, timer_base + MX3_TSTAT);
 }
 
@@ -117,7 +128,7 @@ static int __init mxc_clocksource_init(s
 {
 	unsigned int c = clk_get_rate(timer_clk);
 
-	if (cpu_is_mx3() || cpu_is_mx25())
+	if (timer_is_v2())
 		clocksource_mxc.read = mx3_get_cycles;
 
 	clocksource_mxc.mult = clocksource_hz2mult(c,
@@ -180,7 +191,7 @@ static void mxc_set_mode(enum clock_even
 
 	if (mode != clockevent_mode) {
 		/* Set event time into far-far future */
-		if (cpu_is_mx3() || cpu_is_mx25())
+		if (timer_is_v2())
 			__raw_writel(__raw_readl(timer_base + MX3_TCN) - 3,
 					timer_base + MX3_TCMP);
 		else
@@ -233,7 +244,7 @@ static irqreturn_t mxc_timer_interrupt(i
 	struct clock_event_device *evt = &clockevent_mxc;
 	uint32_t tstat;
 
-	if (cpu_is_mx3() || cpu_is_mx25())
+	if (timer_is_v2())
 		tstat = __raw_readl(timer_base + MX3_TSTAT);
 	else
 		tstat = __raw_readl(timer_base + MX1_2_TSTAT);
@@ -264,7 +275,7 @@ static int __init mxc_clockevent_init(st
 {
 	unsigned int c = clk_get_rate(timer_clk);
 
-	if (cpu_is_mx3() || cpu_is_mx25())
+	if (timer_is_v2())
 		clockevent_mxc.set_next_event = mx3_set_next_event;
 
 	clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC,
@@ -296,7 +307,7 @@ void __init mxc_timer_init(struct clk *t
 	__raw_writel(0, timer_base + MXC_TCTL);
 	__raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
 
-	if (cpu_is_mx3() || cpu_is_mx25())
+	if (timer_is_v2())
 		tctl_val = MX3_TCTL_CLK_IPG | MX3_TCTL_FRR | MX3_TCTL_WAITEN | MXC_TCTL_TEN;
 	else
 		tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/tzic.c linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/tzic.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/tzic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/tzic.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+
+/*
+ *****************************************
+ * TZIC Registers                        *
+ *****************************************
+ */
+
+#define TZIC_INTCNTL	0x0000	/* Control register */
+#define TZIC_INTTYPE	0x0004	/* Controller Type register */
+#define TZIC_IMPID	0x0008	/* Distributor Implementer Identification */
+#define TZIC_PRIOMASK	0x000C	/* Priority Mask Reg */
+#define TZIC_SYNCCTRL	0x0010	/* Synchronizer Control register */
+#define TZIC_DSMINT	0x0014	/* DSM interrupt Holdoffregister */
+#define TZIC_INTSEC0(i)	(0x0080 + ((i) << 2)) /* Interrupt Security Reg 0 */
+#define TZIC_ENSET0(i)	(0x0100 + ((i) << 2)) /* Enable Set Reg 0 */
+#define TZIC_ENCLEAR0(i) (0x0180 + ((i) << 2)) /* Enable Clear Reg 0 */
+#define TZIC_SRCSET0	0x0200	/* Source Set Register 0 */
+#define TZIC_SRCCLAR0	0x0280	/* Source Clear Register 0 */
+#define TZIC_PRIORITY0	0x0400	/* Priority Register 0 */
+#define TZIC_PND0	0x0D00	/* Pending Register 0 */
+#define TZIC_HIPND0	0x0D80	/* High Priority Pending Register */
+#define TZIC_WAKEUP0(i)	(0x0E00 + ((i) << 2))	/* Wakeup Config Register */
+#define TZIC_SWINT	0x0F00	/* Software Interrupt Rigger Register */
+#define TZIC_ID0	0x0FD0	/* Indentification Register 0 */
+
+void __iomem *tzic_base; /* Used as irq controller base in entry-macro.S */
+
+/**
+ * tzic_mask_irq() - Disable interrupt number "irq" in the TZIC
+ *
+ * @param  irq          interrupt source number
+ */
+static void tzic_mask_irq(unsigned int irq)
+{
+	int index, off;
+
+	index = irq >> 5;
+	off = irq & 0x1F;
+	__raw_writel(1 << off, tzic_base + TZIC_ENCLEAR0(index));
+}
+
+/**
+ * tzic_unmask_irq() - Enable interrupt number "irq" in the TZIC
+ *
+ * @param  irq          interrupt source number
+ */
+static void tzic_unmask_irq(unsigned int irq)
+{
+	int index, off;
+
+	index = irq >> 5;
+	off = irq & 0x1F;
+	__raw_writel(1 << off, tzic_base + TZIC_ENSET0(index));
+}
+
+static unsigned int wakeup_intr[4];
+
+/**
+ * tzic_set_wake_irq() - Set interrupt number "irq" in the TZIC as a wake-up source.
+ *
+ * @param  irq          interrupt source number
+ * @param  enable       enable as wake-up if equal to non-zero
+ * 			disble as wake-up if equal to zero
+ *
+ * @return       This function returns 0 on success.
+ */
+static int tzic_set_wake_irq(unsigned int irq, unsigned int enable)
+{
+	unsigned int index, off;
+
+	index = irq >> 5;
+	off = irq & 0x1F;
+
+	if (index > 3)
+		return -EINVAL;
+
+	if (enable)
+		wakeup_intr[index] |= (1 << off);
+	else
+		wakeup_intr[index] &= ~(1 << off);
+
+	return 0;
+}
+
+static struct irq_chip mxc_tzic_chip = {
+	.name = "MXC_TZIC",
+	.ack = tzic_mask_irq,
+	.mask = tzic_mask_irq,
+	.unmask = tzic_unmask_irq,
+	.set_wake = tzic_set_wake_irq,
+};
+
+/*
+ * This function initializes the TZIC hardware and disables all the
+ * interrupts. It registers the interrupt enable and disable functions
+ * to the kernel for each interrupt source.
+ */
+void __init tzic_init_irq(void __iomem *irqbase)
+{
+	int i;
+
+	tzic_base = irqbase;
+	/* put the TZIC into the reset value with
+	 * all interrupts disabled
+	 */
+	i = __raw_readl(tzic_base + TZIC_INTCNTL);
+
+	__raw_writel(0x80010001, tzic_base + TZIC_INTCNTL);
+	__raw_writel(0x1f, tzic_base + TZIC_PRIOMASK);
+	__raw_writel(0x02, tzic_base + TZIC_SYNCCTRL);
+
+	for (i = 0; i < 4; i++)
+		__raw_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0(i));
+
+	/* disable all interrupts */
+	for (i = 0; i < 4; i++)
+		__raw_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0(i));
+
+	/* all IRQ no FIQ Warning :: No selection */
+
+	for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
+		set_irq_chip(i, &mxc_tzic_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+
+	pr_info("TrustZone Interrupt Controller (TZIC) initialized\n");
+}
+
+/**
+ * tzic_enable_wake() - enable wakeup interrupt
+ *
+ * @param is_idle		1 if called in idle loop (ENSET0 register);
+ *				0 to be used when called from low power entry
+ * @return			0 if successful; non-zero otherwise
+ */
+int tzic_enable_wake(int is_idle)
+{
+	unsigned int i, v;
+
+	__raw_writel(1, tzic_base + TZIC_DSMINT);
+	if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0))
+		return -EAGAIN;
+
+	for (i = 0; i < 4; i++) {
+		v = is_idle ? __raw_readl(TZIC_ENSET0(i)) : wakeup_intr[i];
+		__raw_writel(v, TZIC_WAKEUP0(i));
+	}
+
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-nomadik/include/plat/i2c.h linux-libre-2.6.34-gnu1/arch/arm/plat-nomadik/include/plat/i2c.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-nomadik/include/plat/i2c.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-nomadik/include/plat/i2c.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+#ifndef __PLAT_I2C_H
+#define __PLAT_I2C_H
+
+enum i2c_freq_mode {
+	I2C_FREQ_MODE_STANDARD,		/* up to 100 Kb/s */
+	I2C_FREQ_MODE_FAST,		/* up to 400 Kb/s */
+	I2C_FREQ_MODE_FAST_PLUS,	/* up to 1 Mb/s */
+	I2C_FREQ_MODE_HIGH_SPEED	/* up to 3.4 Mb/s */
+};
+
+/**
+ * struct nmk_i2c_controller - client specific controller configuration
+ * @clk_freq:	clock frequency for the operation mode
+ * @slsu:	Slave data setup time in ns.
+ *		The needed setup time for three modes of operation
+ *		are 250ns, 100ns and 10ns respectively thus leading
+ *		to the values of 14, 6, 2 for a 48 MHz i2c clk
+ * @tft:	Tx FIFO Threshold in bytes
+ * @rft:	Rx FIFO Threshold in bytes
+ * @sm:		speed mode
+ */
+struct nmk_i2c_controller {
+	unsigned long	clk_freq;
+	unsigned short	slsu;
+	unsigned char 	tft;
+	unsigned char 	rft;
+	enum i2c_freq_mode	sm;
+};
+
+#endif	/* __PLAT_I2C_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-nomadik/timer.c linux-libre-2.6.34-gnu1/arch/arm/plat-nomadik/timer.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-nomadik/timer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-nomadik/timer.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,24 +49,17 @@ static struct clocksource nmdk_clksrc =
 static void nmdk_clkevt_mode(enum clock_event_mode mode,
 			     struct clock_event_device *dev)
 {
-	unsigned long flags;
-
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
-		/* enable interrupts -- and count current value? */
-		raw_local_irq_save(flags);
+		/* count current value? */
 		writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC);
-		raw_local_irq_restore(flags);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 		BUG(); /* Not supported, yet */
 		/* FALLTHROUGH */
 	case CLOCK_EVT_MODE_SHUTDOWN:
 	case CLOCK_EVT_MODE_UNUSED:
-		/* disable irq */
-		raw_local_irq_save(flags);
 		writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC);
-		raw_local_irq_restore(flags);
 		break;
 	case CLOCK_EVT_MODE_RESUME:
 		break;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/clock.c linux-libre-2.6.34-gnu1/arch/arm/plat-omap/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -173,7 +173,7 @@ EXPORT_SYMBOL(clk_get_parent);
  * OMAP specific clock functions shared between omap1 and omap2
  *-------------------------------------------------------------------------*/
 
-unsigned int __initdata mpurate;
+int __initdata mpurate;
 
 /*
  * By default we use the rate set by the bootloader.
@@ -199,6 +199,17 @@ unsigned long followparent_recalc(struct
 	return clk->parent->rate;
 }
 
+/*
+ * Used for clocks that have the same value as the parent clock,
+ * divided by some factor
+ */
+unsigned long omap_fixed_divisor_recalc(struct clk *clk)
+{
+	WARN_ON(!clk->fixed_div);
+
+	return clk->parent->rate / clk->fixed_div;
+}
+
 void clk_reparent(struct clk *child, struct clk *parent)
 {
 	list_del_init(&child->sibling);
@@ -302,6 +313,33 @@ void clk_enable_init_clocks(void)
 	}
 }
 
+/**
+ * omap_clk_get_by_name - locate OMAP struct clk by its name
+ * @name: name of the struct clk to locate
+ *
+ * Locate an OMAP struct clk by its name.  Assumes that struct clk
+ * names are unique.  Returns NULL if not found or a pointer to the
+ * struct clk if found.
+ */
+struct clk *omap_clk_get_by_name(const char *name)
+{
+	struct clk *c;
+	struct clk *ret = NULL;
+
+	mutex_lock(&clocks_mutex);
+
+	list_for_each_entry(c, &clocks, node) {
+		if (!strcmp(c->name, name)) {
+			ret = c;
+			break;
+		}
+	}
+
+	mutex_unlock(&clocks_mutex);
+
+	return ret;
+}
+
 /*
  * Low level helpers
  */
@@ -319,6 +357,16 @@ const struct clkops clkops_null = {
 	.disable	= clkll_disable_null,
 };
 
+/*
+ * Dummy clock
+ *
+ * Used for clock aliases that are needed on some OMAPs, but not others
+ */
+struct clk dummy_ck = {
+	.name	= "dummy",
+	.ops	= &clkops_null,
+};
+
 #ifdef CONFIG_CPU_FREQ
 void clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
 {
@@ -397,8 +445,6 @@ static int clk_debugfs_register_one(stru
 	char *p = s;
 
 	p += sprintf(p, "%s", c->name);
-	if (c->id != 0)
-		sprintf(p, ":%d", c->id);
 	d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
 	if (!d)
 		return -ENOMEM;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/common.c linux-libre-2.6.34-gnu1/arch/arm/plat-omap/common.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/common.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <plat/control.h>
 #include <plat/mux.h>
 #include <plat/fpga.h>
+#include <plat/serial.h>
 
 #include <plat/clock.h>
 
@@ -43,9 +44,6 @@
 
 #define NO_LENGTH_CHECK 0xffffffff
 
-unsigned char omap_bootloader_tag[512];
-int omap_bootloader_tag_len;
-
 struct omap_board_config_kernel *omap_board_config;
 int omap_board_config_size;
 
@@ -99,10 +97,17 @@ EXPORT_SYMBOL(omap_get_var_config);
 
 #include <linux/clocksource.h>
 
+/*
+ * offset_32k holds the init time counter value. It is then subtracted
+ * from every counter read to achieve a counter that counts time from the
+ * kernel boot (needed for sched_clock()).
+ */
+static u32 offset_32k __read_mostly;
+
 #ifdef CONFIG_ARCH_OMAP16XX
 static cycle_t omap16xx_32k_read(struct clocksource *cs)
 {
-	return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED);
+	return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
 }
 #else
 #define omap16xx_32k_read	NULL
@@ -111,7 +116,7 @@ static cycle_t omap16xx_32k_read(struct
 #ifdef CONFIG_ARCH_OMAP2420
 static cycle_t omap2420_32k_read(struct clocksource *cs)
 {
-	return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10);
+	return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap2420_32k_read	NULL
@@ -120,16 +125,16 @@ static cycle_t omap2420_32k_read(struct
 #ifdef CONFIG_ARCH_OMAP2430
 static cycle_t omap2430_32k_read(struct clocksource *cs)
 {
-	return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10);
+	return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap2430_32k_read	NULL
 #endif
 
-#ifdef CONFIG_ARCH_OMAP34XX
+#ifdef CONFIG_ARCH_OMAP3
 static cycle_t omap34xx_32k_read(struct clocksource *cs)
 {
-	return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10);
+	return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap34xx_32k_read	NULL
@@ -138,7 +143,7 @@ static cycle_t omap34xx_32k_read(struct
 #ifdef CONFIG_ARCH_OMAP4
 static cycle_t omap44xx_32k_read(struct clocksource *cs)
 {
-	return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10);
+	return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap44xx_32k_read	NULL
@@ -226,6 +231,8 @@ static int __init omap_init_clocksource_
 		clocksource_32k.mult = clocksource_hz2mult(32768,
 					    clocksource_32k.shift);
 
+		offset_32k = clocksource_32k.read(&clocksource_32k);
+
 		if (clocksource_register(&clocksource_32k))
 			printk(err, clocksource_32k.name);
 	}
@@ -245,6 +252,7 @@ static void __init __omap2_set_globals(s
 	omap2_set_globals_sdrc(omap2_globals);
 	omap2_set_globals_control(omap2_globals);
 	omap2_set_globals_prcm(omap2_globals);
+	omap2_set_globals_uart(omap2_globals);
 }
 
 #endif
@@ -254,11 +262,14 @@ static void __init __omap2_set_globals(s
 static struct omap_globals omap242x_globals = {
 	.class	= OMAP242X_CLASS,
 	.tap	= OMAP2_L4_IO_ADDRESS(0x48014000),
-	.sdrc	= OMAP2_L3_IO_ADDRESS(OMAP2420_SDRC_BASE),
-	.sms	= OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE),
-	.ctrl	= OMAP2_L4_IO_ADDRESS(OMAP2420_CTRL_BASE),
-	.prm	= OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE),
-	.cm	= OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE),
+	.sdrc	= OMAP2420_SDRC_BASE,
+	.sms	= OMAP2420_SMS_BASE,
+	.ctrl	= OMAP2420_CTRL_BASE,
+	.prm	= OMAP2420_PRM_BASE,
+	.cm	= OMAP2420_CM_BASE,
+	.uart1_phys	= OMAP2_UART1_BASE,
+	.uart2_phys	= OMAP2_UART2_BASE,
+	.uart3_phys	= OMAP2_UART3_BASE,
 };
 
 void __init omap2_set_globals_242x(void)
@@ -272,11 +283,14 @@ void __init omap2_set_globals_242x(void)
 static struct omap_globals omap243x_globals = {
 	.class	= OMAP243X_CLASS,
 	.tap	= OMAP2_L4_IO_ADDRESS(0x4900a000),
-	.sdrc	= OMAP2_L3_IO_ADDRESS(OMAP243X_SDRC_BASE),
-	.sms	= OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE),
-	.ctrl	= OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE),
-	.prm	= OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE),
-	.cm	= OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE),
+	.sdrc	= OMAP243X_SDRC_BASE,
+	.sms	= OMAP243X_SMS_BASE,
+	.ctrl	= OMAP243X_CTRL_BASE,
+	.prm	= OMAP2430_PRM_BASE,
+	.cm	= OMAP2430_CM_BASE,
+	.uart1_phys	= OMAP2_UART1_BASE,
+	.uart2_phys	= OMAP2_UART2_BASE,
+	.uart3_phys	= OMAP2_UART3_BASE,
 };
 
 void __init omap2_set_globals_243x(void)
@@ -285,21 +299,31 @@ void __init omap2_set_globals_243x(void)
 }
 #endif
 
-#if defined(CONFIG_ARCH_OMAP3430)
+#if defined(CONFIG_ARCH_OMAP3)
 
-static struct omap_globals omap343x_globals = {
+static struct omap_globals omap3_globals = {
 	.class	= OMAP343X_CLASS,
 	.tap	= OMAP2_L4_IO_ADDRESS(0x4830A000),
-	.sdrc	= OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE),
-	.sms	= OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE),
-	.ctrl	= OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE),
-	.prm	= OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE),
-	.cm	= OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE),
+	.sdrc	= OMAP343X_SDRC_BASE,
+	.sms	= OMAP343X_SMS_BASE,
+	.ctrl	= OMAP343X_CTRL_BASE,
+	.prm	= OMAP3430_PRM_BASE,
+	.cm	= OMAP3430_CM_BASE,
+	.uart1_phys	= OMAP3_UART1_BASE,
+	.uart2_phys	= OMAP3_UART2_BASE,
+	.uart3_phys	= OMAP3_UART3_BASE,
 };
 
 void __init omap2_set_globals_343x(void)
 {
-	__omap2_set_globals(&omap343x_globals);
+	__omap2_set_globals(&omap3_globals);
+}
+
+void __init omap2_set_globals_36xx(void)
+{
+	omap3_globals.uart4_phys = OMAP3_UART4_BASE;
+
+	__omap2_set_globals(&omap3_globals);
 }
 #endif
 
@@ -307,10 +331,14 @@ void __init omap2_set_globals_343x(void)
 static struct omap_globals omap4_globals = {
 	.class	= OMAP443X_CLASS,
 	.tap	= OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE),
-	.ctrl	= OMAP2_L4_IO_ADDRESS(OMAP443X_CTRL_BASE),
-	.prm	= OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE),
-	.cm	= OMAP2_L4_IO_ADDRESS(OMAP4430_CM_BASE),
-	.cm2	= OMAP2_L4_IO_ADDRESS(OMAP4430_CM2_BASE),
+	.ctrl	= OMAP443X_CTRL_BASE,
+	.prm	= OMAP4430_PRM_BASE,
+	.cm	= OMAP4430_CM_BASE,
+	.cm2	= OMAP4430_CM2_BASE,
+	.uart1_phys	= OMAP4_UART1_BASE,
+	.uart2_phys	= OMAP4_UART2_BASE,
+	.uart3_phys	= OMAP4_UART3_BASE,
+	.uart4_phys	= OMAP4_UART4_BASE,
 };
 
 void __init omap2_set_globals_443x(void)
@@ -318,6 +346,7 @@ void __init omap2_set_globals_443x(void)
 	omap2_set_globals_tap(&omap4_globals);
 	omap2_set_globals_control(&omap4_globals);
 	omap2_set_globals_prcm(&omap4_globals);
+	omap2_set_globals_uart(&omap4_globals);
 }
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/devices.c linux-libre-2.6.34-gnu1/arch/arm/plat-omap/devices.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/devices.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/devices.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -28,6 +29,7 @@
 #include <plat/menelaus.h>
 #include <plat/mcbsp.h>
 #include <plat/dsp_common.h>
+#include <plat/omap44xx.h>
 
 #if	defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
 
@@ -192,6 +194,41 @@ void omap_mcbsp_register_board_cfg(struc
 
 /*-------------------------------------------------------------------------*/
 
+#if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \
+		defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE)
+
+static struct resource mcpdm_resources[] = {
+	{
+		.name		= "mcpdm_mem",
+		.start		= OMAP44XX_MCPDM_BASE,
+		.end		= OMAP44XX_MCPDM_BASE + SZ_4K,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.name		= "mcpdm_irq",
+		.start		= OMAP44XX_IRQ_MCPDM,
+		.end		= OMAP44XX_IRQ_MCPDM,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device omap_mcpdm_device = {
+	.name		= "omap-mcpdm",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(mcpdm_resources),
+	.resource	= mcpdm_resources,
+};
+
+static void omap_init_mcpdm(void)
+{
+	(void) platform_device_register(&omap_mcpdm_device);
+}
+#else
+static inline void omap_init_mcpdm(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
 #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
 	defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
 
@@ -244,7 +281,7 @@ fail:
 
 #if defined(CONFIG_HW_RANDOM_OMAP) || defined(CONFIG_HW_RANDOM_OMAP_MODULE)
 
-#ifdef CONFIG_ARCH_OMAP24XX
+#ifdef CONFIG_ARCH_OMAP2
 #define	OMAP_RNG_BASE		0x480A0000
 #else
 #define	OMAP_RNG_BASE		0xfffe5000
@@ -385,6 +422,7 @@ static int __init omap_init_devices(void
 	omap_init_dsp();
 	omap_init_kp();
 	omap_init_rng();
+	omap_init_mcpdm();
 	omap_init_uwire();
 	omap_init_wdt();
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/dma.c linux-libre-2.6.34-gnu1/arch/arm/plat-omap/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <mach/hardware.h>
@@ -936,6 +937,15 @@ void omap_start_dma(int lch)
 {
 	u32 l;
 
+	/*
+	 * The CPC/CDAC register needs to be initialized to zero
+	 * before starting dma transfer.
+	 */
+	if (cpu_is_omap15xx())
+		dma_write(0, CPC(lch));
+	else
+		dma_write(0, CDAC(lch));
+
 	if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
 		int next_lch, cur_lch;
 		char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
@@ -1870,8 +1880,7 @@ static irqreturn_t omap1_dma_irq_handler
 #define omap1_dma_irq_handler	NULL
 #endif
 
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
-			defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP2PLUS
 
 static int omap2_dma_handle_ch(int ch)
 {
@@ -2133,13 +2142,13 @@ static int __init omap_init_dma(void)
 	if (cpu_class_is_omap2()) {
 		int irq;
 		if (cpu_is_omap44xx())
-			irq = INT_44XX_SDMA_IRQ0;
+			irq = OMAP44XX_IRQ_SDMA_0;
 		else
 			irq = INT_24XX_SDMA_IRQ0;
 		setup_irq(irq, &omap24xx_dma_irq);
 	}
 
-	if (cpu_is_omap34xx()) {
+	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
 		/* Enable smartidle idlemodes and autoidle */
 		u32 v = dma_read(OCP_SYSCONFIG);
 		v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK |
@@ -2150,7 +2159,8 @@ static int __init omap_init_dma(void)
 			DMA_SYSCONFIG_AUTOIDLE);
 		dma_write(v , OCP_SYSCONFIG);
 		/* reserve dma channels 0 and 1 in high security devices */
-		if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+		if (cpu_is_omap34xx() &&
+			(omap_type() != OMAP2_DEVICE_TYPE_GP)) {
 			printk(KERN_INFO "Reserving DMA channels 0 and 1 for "
 					"HS ROM code\n");
 			dma_chan[0].dev_id = 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/dmtimer.c linux-libre-2.6.34-gnu1/arch/arm/plat-omap/dmtimer.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/dmtimer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/dmtimer.c	2010-05-16 17:17:36.000000000 -0400
@@ -153,8 +153,7 @@
 struct omap_dm_timer {
 	unsigned long phys_base;
 	int irq;
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
-			defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP2PLUS
 	struct clk *iclk, *fclk;
 #endif
 	void __iomem *io_base;
@@ -163,20 +162,9 @@ struct omap_dm_timer {
 	unsigned posted:1;
 };
 
-#ifdef CONFIG_ARCH_OMAP1
-
-#define omap_dm_clk_enable(x)
-#define omap_dm_clk_disable(x)
-#define omap2_dm_timers			NULL
-#define omap2_dm_source_names		NULL
-#define omap2_dm_source_clocks		NULL
-#define omap3_dm_timers			NULL
-#define omap3_dm_source_names		NULL
-#define omap3_dm_source_clocks		NULL
-#define omap4_dm_timers			NULL
-#define omap4_dm_source_names		NULL
-#define omap4_dm_source_clocks		NULL
+static int dm_timer_count;
 
+#ifdef CONFIG_ARCH_OMAP1
 static struct omap_dm_timer omap1_dm_timers[] = {
 	{ .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 },
 	{ .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 },
@@ -188,20 +176,14 @@ static struct omap_dm_timer omap1_dm_tim
 	{ .phys_base = 0xfffbd400, .irq = INT_1610_GPTIMER8 },
 };
 
-static const int dm_timer_count = ARRAY_SIZE(omap1_dm_timers);
-
-#elif defined(CONFIG_ARCH_OMAP2)
+static const int omap1_dm_timer_count = ARRAY_SIZE(omap1_dm_timers);
 
-#define omap_dm_clk_enable(x)		clk_enable(x)
-#define omap_dm_clk_disable(x)		clk_disable(x)
+#else
 #define omap1_dm_timers			NULL
-#define omap3_dm_timers			NULL
-#define omap3_dm_source_names		NULL
-#define omap3_dm_source_clocks		NULL
-#define omap4_dm_timers			NULL
-#define omap4_dm_source_names		NULL
-#define omap4_dm_source_clocks		NULL
+#define omap1_dm_timer_count		0
+#endif	/* CONFIG_ARCH_OMAP1 */
 
+#ifdef CONFIG_ARCH_OMAP2
 static struct omap_dm_timer omap2_dm_timers[] = {
 	{ .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 },
 	{ .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 },
@@ -225,20 +207,16 @@ static const char *omap2_dm_source_names
 };
 
 static struct clk *omap2_dm_source_clocks[3];
-static const int dm_timer_count = ARRAY_SIZE(omap2_dm_timers);
-
-#elif defined(CONFIG_ARCH_OMAP3)
+static const int omap2_dm_timer_count = ARRAY_SIZE(omap2_dm_timers);
 
-#define omap_dm_clk_enable(x)		clk_enable(x)
-#define omap_dm_clk_disable(x)		clk_disable(x)
-#define omap1_dm_timers			NULL
+#else
 #define omap2_dm_timers			NULL
+#define omap2_dm_timer_count		0
 #define omap2_dm_source_names		NULL
 #define omap2_dm_source_clocks		NULL
-#define omap4_dm_timers			NULL
-#define omap4_dm_source_names		NULL
-#define omap4_dm_source_clocks		NULL
+#endif	/* CONFIG_ARCH_OMAP2 */
 
+#ifdef CONFIG_ARCH_OMAP3
 static struct omap_dm_timer omap3_dm_timers[] = {
 	{ .phys_base = 0x48318000, .irq = INT_24XX_GPTIMER1 },
 	{ .phys_base = 0x49032000, .irq = INT_24XX_GPTIMER2 },
@@ -261,33 +239,29 @@ static const char *omap3_dm_source_names
 };
 
 static struct clk *omap3_dm_source_clocks[2];
-static const int dm_timer_count = ARRAY_SIZE(omap3_dm_timers);
-
-#elif defined(CONFIG_ARCH_OMAP4)
+static const int omap3_dm_timer_count = ARRAY_SIZE(omap3_dm_timers);
 
-#define omap_dm_clk_enable(x)		clk_enable(x)
-#define omap_dm_clk_disable(x)		clk_disable(x)
-#define omap1_dm_timers			NULL
-#define omap2_dm_timers			NULL
-#define omap2_dm_source_names		NULL
-#define omap2_dm_source_clocks		NULL
+#else
 #define omap3_dm_timers			NULL
+#define omap3_dm_timer_count		0
 #define omap3_dm_source_names		NULL
 #define omap3_dm_source_clocks		NULL
+#endif	/* CONFIG_ARCH_OMAP3 */
 
+#ifdef CONFIG_ARCH_OMAP4
 static struct omap_dm_timer omap4_dm_timers[] = {
-	{ .phys_base = 0x4a318000, .irq = INT_44XX_GPTIMER1 },
-	{ .phys_base = 0x48032000, .irq = INT_44XX_GPTIMER2 },
-	{ .phys_base = 0x48034000, .irq = INT_44XX_GPTIMER3 },
-	{ .phys_base = 0x48036000, .irq = INT_44XX_GPTIMER4 },
-	{ .phys_base = 0x40138000, .irq = INT_44XX_GPTIMER5 },
-	{ .phys_base = 0x4013a000, .irq = INT_44XX_GPTIMER6 },
-	{ .phys_base = 0x4013a000, .irq = INT_44XX_GPTIMER7 },
-	{ .phys_base = 0x4013e000, .irq = INT_44XX_GPTIMER8 },
-	{ .phys_base = 0x4803e000, .irq = INT_44XX_GPTIMER9 },
-	{ .phys_base = 0x48086000, .irq = INT_44XX_GPTIMER10 },
-	{ .phys_base = 0x48088000, .irq = INT_44XX_GPTIMER11 },
-	{ .phys_base = 0x4a320000, .irq = INT_44XX_GPTIMER12 },
+	{ .phys_base = 0x4a318000, .irq = OMAP44XX_IRQ_GPT1 },
+	{ .phys_base = 0x48032000, .irq = OMAP44XX_IRQ_GPT2 },
+	{ .phys_base = 0x48034000, .irq = OMAP44XX_IRQ_GPT3 },
+	{ .phys_base = 0x48036000, .irq = OMAP44XX_IRQ_GPT4 },
+	{ .phys_base = 0x40138000, .irq = OMAP44XX_IRQ_GPT5 },
+	{ .phys_base = 0x4013a000, .irq = OMAP44XX_IRQ_GPT6 },
+	{ .phys_base = 0x4013a000, .irq = OMAP44XX_IRQ_GPT7 },
+	{ .phys_base = 0x4013e000, .irq = OMAP44XX_IRQ_GPT8 },
+	{ .phys_base = 0x4803e000, .irq = OMAP44XX_IRQ_GPT9 },
+	{ .phys_base = 0x48086000, .irq = OMAP44XX_IRQ_GPT10 },
+	{ .phys_base = 0x48088000, .irq = OMAP44XX_IRQ_GPT11 },
+	{ .phys_base = 0x4a320000, .irq = OMAP44XX_IRQ_GPT12 },
 };
 static const char *omap4_dm_source_names[] __initdata = {
 	"sys_ck",
@@ -295,13 +269,14 @@ static const char *omap4_dm_source_names
 	NULL
 };
 static struct clk *omap4_dm_source_clocks[2];
-static const int dm_timer_count = ARRAY_SIZE(omap4_dm_timers);
+static const int omap4_dm_timer_count = ARRAY_SIZE(omap4_dm_timers);
 
 #else
-
-#error OMAP architecture not supported!
-
-#endif
+#define omap4_dm_timers			NULL
+#define omap4_dm_timer_count		0
+#define omap4_dm_source_names		NULL
+#define omap4_dm_source_clocks		NULL
+#endif	/* CONFIG_ARCH_OMAP4 */
 
 static struct omap_dm_timer *dm_timers;
 static const char **dm_source_names;
@@ -450,8 +425,12 @@ void omap_dm_timer_enable(struct omap_dm
 	if (timer->enabled)
 		return;
 
-	omap_dm_clk_enable(timer->fclk);
-	omap_dm_clk_enable(timer->iclk);
+#ifdef CONFIG_ARCH_OMAP2PLUS
+	if (cpu_class_is_omap2()) {
+		clk_enable(timer->fclk);
+		clk_enable(timer->iclk);
+	}
+#endif
 
 	timer->enabled = 1;
 }
@@ -462,8 +441,12 @@ void omap_dm_timer_disable(struct omap_d
 	if (!timer->enabled)
 		return;
 
-	omap_dm_clk_disable(timer->iclk);
-	omap_dm_clk_disable(timer->fclk);
+#ifdef CONFIG_ARCH_OMAP2PLUS
+	if (cpu_class_is_omap2()) {
+		clk_disable(timer->iclk);
+		clk_disable(timer->fclk);
+	}
+#endif
 
 	timer->enabled = 0;
 }
@@ -506,8 +489,7 @@ __u32 omap_dm_timer_modify_idlect_mask(_
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
 
-#elif defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
-				defined(CONFIG_ARCH_OMAP4)
+#else
 
 struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
 {
@@ -551,8 +533,7 @@ void omap_dm_timer_stop(struct omap_dm_t
 	if (l & OMAP_TIMER_CTRL_ST) {
 		l &= ~0x1;
 		omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
-			defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP2PLUS
 		/* Readback to make sure write has completed */
 		omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
 		 /*
@@ -764,17 +745,21 @@ int __init omap_dm_timer_init(void)
 
 	if (cpu_class_is_omap1()) {
 		dm_timers = omap1_dm_timers;
+		dm_timer_count = omap1_dm_timer_count;
 		map_size = SZ_2K;
 	} else if (cpu_is_omap24xx()) {
 		dm_timers = omap2_dm_timers;
+		dm_timer_count = omap2_dm_timer_count;
 		dm_source_names = omap2_dm_source_names;
 		dm_source_clocks = omap2_dm_source_clocks;
 	} else if (cpu_is_omap34xx()) {
 		dm_timers = omap3_dm_timers;
+		dm_timer_count = omap3_dm_timer_count;
 		dm_source_names = omap3_dm_source_names;
 		dm_source_clocks = omap3_dm_source_clocks;
 	} else if (cpu_is_omap44xx()) {
 		dm_timers = omap4_dm_timers;
+		dm_timer_count = omap4_dm_timer_count;
 		dm_source_names = omap4_dm_source_names;
 		dm_source_clocks = omap4_dm_source_clocks;
 	}
@@ -793,8 +778,7 @@ int __init omap_dm_timer_init(void)
 		timer->io_base = ioremap(timer->phys_base, map_size);
 		BUG_ON(!timer->io_base);
 
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
-					defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP2PLUS
 		if (cpu_class_is_omap2()) {
 			char clk_name[16];
 			sprintf(clk_name, "gpt%d_ick", i + 1);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/gpio.c linux-libre-2.6.34-gnu1/arch/arm/plat-omap/gpio.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -177,13 +177,11 @@ struct gpio_bank {
 	u16 irq;
 	u16 virtual_irq_start;
 	int method;
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) ||  \
-		defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
 	u32 suspend_wakeup;
 	u32 saved_wakeup;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-			defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP2PLUS
 	u32 non_wakeup_gpios;
 	u32 enabled_non_wakeup_gpios;
 
@@ -204,6 +202,7 @@ struct gpio_bank {
 #define METHOD_GPIO_1610	2
 #define METHOD_GPIO_7XX		3
 #define METHOD_GPIO_24XX	5
+#define METHOD_GPIO_44XX	6
 
 #ifdef CONFIG_ARCH_OMAP16XX
 static struct gpio_bank gpio_bank_1610[5] = {
@@ -248,7 +247,7 @@ static struct gpio_bank gpio_bank_7xx[7]
 };
 #endif
 
-#ifdef CONFIG_ARCH_OMAP24XX
+#ifdef CONFIG_ARCH_OMAP2
 
 static struct gpio_bank gpio_bank_242x[4] = {
 	{ OMAP242X_GPIO1_BASE, NULL, INT_24XX_GPIO_BANK1, IH_GPIO_BASE,
@@ -276,7 +275,7 @@ static struct gpio_bank gpio_bank_243x[5
 
 #endif
 
-#ifdef CONFIG_ARCH_OMAP34XX
+#ifdef CONFIG_ARCH_OMAP3
 static struct gpio_bank gpio_bank_34xx[6] = {
 	{ OMAP34XX_GPIO1_BASE, NULL, INT_34XX_GPIO_BANK1, IH_GPIO_BASE,
 		METHOD_GPIO_24XX },
@@ -313,18 +312,18 @@ static struct omap3_gpio_regs gpio_conte
 
 #ifdef CONFIG_ARCH_OMAP4
 static struct gpio_bank gpio_bank_44xx[6] = {
-	{ OMAP44XX_GPIO1_BASE, NULL, INT_44XX_GPIO_BANK1, IH_GPIO_BASE,
-		METHOD_GPIO_24XX },
-	{ OMAP44XX_GPIO2_BASE, NULL, INT_44XX_GPIO_BANK2, IH_GPIO_BASE + 32,
-		METHOD_GPIO_24XX },
-	{ OMAP44XX_GPIO3_BASE, NULL, INT_44XX_GPIO_BANK3, IH_GPIO_BASE + 64,
-		METHOD_GPIO_24XX },
-	{ OMAP44XX_GPIO4_BASE, NULL, INT_44XX_GPIO_BANK4, IH_GPIO_BASE + 96,
-		METHOD_GPIO_24XX },
-	{ OMAP44XX_GPIO5_BASE, NULL, INT_44XX_GPIO_BANK5, IH_GPIO_BASE + 128,
-		METHOD_GPIO_24XX },
-	{ OMAP44XX_GPIO6_BASE, NULL, INT_44XX_GPIO_BANK6, IH_GPIO_BASE + 160,
-		METHOD_GPIO_24XX },
+	{ OMAP44XX_GPIO1_BASE, NULL, OMAP44XX_IRQ_GPIO1, IH_GPIO_BASE,
+		METHOD_GPIO_44XX },
+	{ OMAP44XX_GPIO2_BASE, NULL, OMAP44XX_IRQ_GPIO2, IH_GPIO_BASE + 32,
+		METHOD_GPIO_44XX },
+	{ OMAP44XX_GPIO3_BASE, NULL, OMAP44XX_IRQ_GPIO3, IH_GPIO_BASE + 64,
+		METHOD_GPIO_44XX },
+	{ OMAP44XX_GPIO4_BASE, NULL, OMAP44XX_IRQ_GPIO4, IH_GPIO_BASE + 96,
+		METHOD_GPIO_44XX },
+	{ OMAP44XX_GPIO5_BASE, NULL, OMAP44XX_IRQ_GPIO5, IH_GPIO_BASE + 128,
+		METHOD_GPIO_44XX },
+	{ OMAP44XX_GPIO6_BASE, NULL, OMAP44XX_IRQ_GPIO6, IH_GPIO_BASE + 160,
+		METHOD_GPIO_44XX },
 };
 
 #endif
@@ -426,13 +425,13 @@ static void _set_gpio_direction(struct g
 		reg += OMAP7XX_GPIO_DIR_CONTROL;
 		break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_OE;
 		break;
 #endif
 #if defined(CONFIG_ARCH_OMAP4)
-	case METHOD_GPIO_24XX:
+	case METHOD_GPIO_44XX:
 		reg += OMAP4_GPIO_OE;
 		break;
 #endif
@@ -493,7 +492,7 @@ static void _set_gpio_dataout(struct gpi
 			l &= ~(1 << gpio);
 		break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 	case METHOD_GPIO_24XX:
 		if (enable)
 			reg += OMAP24XX_GPIO_SETDATAOUT;
@@ -503,7 +502,7 @@ static void _set_gpio_dataout(struct gpi
 		break;
 #endif
 #ifdef CONFIG_ARCH_OMAP4
-	case METHOD_GPIO_24XX:
+	case METHOD_GPIO_44XX:
 		if (enable)
 			reg += OMAP4_GPIO_SETDATAOUT;
 		else
@@ -546,13 +545,13 @@ static int _get_gpio_datain(struct gpio_
 		reg += OMAP7XX_GPIO_DATA_INPUT;
 		break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_DATAIN;
 		break;
 #endif
 #ifdef CONFIG_ARCH_OMAP4
-	case METHOD_GPIO_24XX:
+	case METHOD_GPIO_44XX:
 		reg += OMAP4_GPIO_DATAIN;
 		break;
 #endif
@@ -592,9 +591,9 @@ static int _get_gpio_dataout(struct gpio
 		reg += OMAP7XX_GPIO_DATA_OUTPUT;
 		break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-		defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP2PLUS
 	case METHOD_GPIO_24XX:
+	case METHOD_GPIO_44XX:
 		reg += OMAP24XX_GPIO_DATAOUT;
 		break;
 #endif
@@ -625,11 +624,12 @@ void omap_set_gpio_debounce(int gpio, in
 
 	bank = get_gpio_bank(gpio);
 	reg = bank->base;
-#ifdef CONFIG_ARCH_OMAP4
-	reg += OMAP4_GPIO_DEBOUNCENABLE;
-#else
-	reg += OMAP24XX_GPIO_DEBOUNCE_EN;
-#endif
+
+	if (cpu_is_omap44xx())
+		reg += OMAP4_GPIO_DEBOUNCENABLE;
+	else
+		reg += OMAP24XX_GPIO_DEBOUNCE_EN;
+
 	if (!(bank->mod_usage & l)) {
 		printk(KERN_ERR "GPIO %d not requested\n", gpio);
 		return;
@@ -675,17 +675,17 @@ void omap_set_gpio_debounce_time(int gpi
 	}
 
 	enc_time &= 0xff;
-#ifdef CONFIG_ARCH_OMAP4
-	reg += OMAP4_GPIO_DEBOUNCINGTIME;
-#else
-	reg += OMAP24XX_GPIO_DEBOUNCE_VAL;
-#endif
+
+	if (cpu_is_omap44xx())
+		reg += OMAP4_GPIO_DEBOUNCINGTIME;
+	else
+		reg += OMAP24XX_GPIO_DEBOUNCE_VAL;
+
 	__raw_writel(enc_time, reg);
 }
 EXPORT_SYMBOL(omap_set_gpio_debounce_time);
 
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-				defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP2PLUS
 static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
 						int trigger)
 {
@@ -798,7 +798,7 @@ static int _set_gpio_triggering(struct g
 	case METHOD_MPUIO:
 		reg += OMAP_MPUIO_GPIO_INT_EDGE;
 		l = __raw_readl(reg);
-		if (trigger & IRQ_TYPE_EDGE_BOTH)
+		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
 			bank->toggle_mask |= 1 << gpio;
 		if (trigger & IRQ_TYPE_EDGE_RISING)
 			l |= 1 << gpio;
@@ -812,7 +812,7 @@ static int _set_gpio_triggering(struct g
 	case METHOD_GPIO_1510:
 		reg += OMAP1510_GPIO_INT_CONTROL;
 		l = __raw_readl(reg);
-		if (trigger & IRQ_TYPE_EDGE_BOTH)
+		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
 			bank->toggle_mask |= 1 << gpio;
 		if (trigger & IRQ_TYPE_EDGE_RISING)
 			l |= 1 << gpio;
@@ -846,7 +846,7 @@ static int _set_gpio_triggering(struct g
 	case METHOD_GPIO_7XX:
 		reg += OMAP7XX_GPIO_INT_CONTROL;
 		l = __raw_readl(reg);
-		if (trigger & IRQ_TYPE_EDGE_BOTH)
+		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
 			bank->toggle_mask |= 1 << gpio;
 		if (trigger & IRQ_TYPE_EDGE_RISING)
 			l |= 1 << gpio;
@@ -856,9 +856,9 @@ static int _set_gpio_triggering(struct g
 			goto bad;
 		break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-				defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP2PLUS
 	case METHOD_GPIO_24XX:
+	case METHOD_GPIO_44XX:
 		set_24xx_gpio_triggering(bank, gpio, trigger);
 		break;
 #endif
@@ -937,13 +937,13 @@ static void _clear_gpio_irqbank(struct g
 		reg += OMAP7XX_GPIO_INT_STATUS;
 		break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_IRQSTATUS1;
 		break;
 #endif
 #if defined(CONFIG_ARCH_OMAP4)
-	case METHOD_GPIO_24XX:
+	case METHOD_GPIO_44XX:
 		reg += OMAP4_GPIO_IRQSTATUS0;
 		break;
 #endif
@@ -954,12 +954,11 @@ static void _clear_gpio_irqbank(struct g
 	__raw_writel(gpio_mask, reg);
 
 	/* Workaround for clearing DSP GPIO interrupts to allow retention */
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
-	reg = bank->base + OMAP24XX_GPIO_IRQSTATUS2;
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
-	reg = bank->base + OMAP4_GPIO_IRQSTATUS1;
-#endif
+	if (cpu_is_omap24xx() || cpu_is_omap34xx())
+		reg = bank->base + OMAP24XX_GPIO_IRQSTATUS2;
+	else if (cpu_is_omap44xx())
+		reg = bank->base + OMAP4_GPIO_IRQSTATUS1;
+
 	if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
 		__raw_writel(gpio_mask, reg);
 
@@ -1008,14 +1007,14 @@ static u32 _get_gpio_irqbank_mask(struct
 		inv = 1;
 		break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_IRQENABLE1;
 		mask = 0xffffffff;
 		break;
 #endif
 #if defined(CONFIG_ARCH_OMAP4)
-	case METHOD_GPIO_24XX:
+	case METHOD_GPIO_44XX:
 		reg += OMAP4_GPIO_IRQSTATUSSET0;
 		mask = 0xffffffff;
 		break;
@@ -1077,7 +1076,7 @@ static void _enable_gpio_irqbank(struct
 			l |= gpio_mask;
 		break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 	case METHOD_GPIO_24XX:
 		if (enable)
 			reg += OMAP24XX_GPIO_SETIRQENABLE1;
@@ -1087,7 +1086,7 @@ static void _enable_gpio_irqbank(struct
 		break;
 #endif
 #ifdef CONFIG_ARCH_OMAP4
-	case METHOD_GPIO_24XX:
+	case METHOD_GPIO_44XX:
 		if (enable)
 			reg += OMAP4_GPIO_IRQSTATUSSET0;
 		else
@@ -1131,9 +1130,9 @@ static int _set_gpio_wakeup(struct gpio_
 		spin_unlock_irqrestore(&bank->lock, flags);
 		return 0;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-				defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP2PLUS
 	case METHOD_GPIO_24XX:
+	case METHOD_GPIO_44XX:
 		if (bank->non_wakeup_gpios & (1 << gpio)) {
 			printk(KERN_ERR "Unable to modify wakeup on "
 					"non-wakeup GPIO%d\n",
@@ -1227,9 +1226,9 @@ static void omap_gpio_free(struct gpio_c
 		__raw_writel(1 << offset, reg);
 	}
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-				defined(CONFIG_ARCH_OMAP4)
-	if (bank->method == METHOD_GPIO_24XX) {
+#ifdef CONFIG_ARCH_OMAP2PLUS
+	if ((bank->method == METHOD_GPIO_24XX) ||
+			(bank->method == METHOD_GPIO_44XX)) {
 		/* Disable wake-up during idle for dynamic tick */
 		void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
 		__raw_writel(1 << offset, reg);
@@ -1286,12 +1285,12 @@ static void gpio_irq_handler(unsigned in
 	if (bank->method == METHOD_GPIO_7XX)
 		isr_reg = bank->base + OMAP7XX_GPIO_INT_STATUS;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 	if (bank->method == METHOD_GPIO_24XX)
 		isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
 #endif
 #if defined(CONFIG_ARCH_OMAP4)
-	if (bank->method == METHOD_GPIO_24XX)
+	if (bank->method == METHOD_GPIO_44XX)
 		isr_reg = bank->base + OMAP4_GPIO_IRQSTATUS0;
 #endif
 	while(1) {
@@ -1571,6 +1570,7 @@ static int gpio_is_input(struct gpio_ban
 		reg += OMAP7XX_GPIO_DIR_CONTROL;
 		break;
 	case METHOD_GPIO_24XX:
+	case METHOD_GPIO_44XX:
 		reg += OMAP24XX_GPIO_OE;
 		break;
 	}
@@ -1630,7 +1630,7 @@ static int gpio_2irq(struct gpio_chip *c
 /*---------------------------------------------------------------------*/
 
 static int initialized;
-#if !(defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4))
+#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP2)
 static struct clk * gpio_ick;
 #endif
 
@@ -1756,7 +1756,7 @@ static int __init _omap_gpio_init(void)
 		bank_size = SZ_2K;
 	}
 #endif
-#ifdef CONFIG_ARCH_OMAP24XX
+#ifdef CONFIG_ARCH_OMAP2
 	if (cpu_is_omap242x()) {
 		gpio_bank_count = 4;
 		gpio_bank = gpio_bank_242x;
@@ -1766,7 +1766,7 @@ static int __init _omap_gpio_init(void)
 		gpio_bank = gpio_bank_243x;
 	}
 #endif
-#ifdef CONFIG_ARCH_OMAP34XX
+#ifdef CONFIG_ARCH_OMAP3
 	if (cpu_is_omap34xx()) {
 		gpio_bank_count = OMAP34XX_NR_GPIOS;
 		gpio_bank = gpio_bank_34xx;
@@ -1809,30 +1809,42 @@ static int __init _omap_gpio_init(void)
 			gpio_count = 32; /* 7xx has 32-bit GPIOs */
 		}
 
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-				defined(CONFIG_ARCH_OMAP4)
-		if (bank->method == METHOD_GPIO_24XX) {
+#ifdef CONFIG_ARCH_OMAP2PLUS
+		if ((bank->method == METHOD_GPIO_24XX) ||
+				(bank->method == METHOD_GPIO_44XX)) {
 			static const u32 non_wakeup_gpios[] = {
 				0xe203ffc0, 0x08700040
 			};
-		if (cpu_is_omap44xx()) {
-			__raw_writel(0xffffffff, bank->base +
+
+			if (cpu_is_omap44xx()) {
+				__raw_writel(0xffffffff, bank->base +
 						OMAP4_GPIO_IRQSTATUSCLR0);
-			__raw_writew(0x0015, bank->base +
+				__raw_writew(0x0015, bank->base +
 						OMAP4_GPIO_SYSCONFIG);
-			__raw_writel(0x00000000, bank->base +
+				__raw_writel(0x00000000, bank->base +
 						 OMAP4_GPIO_DEBOUNCENABLE);
-			/* Initialize interface clock ungated, module enabled */
-			__raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
-		} else {
-			__raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1);
-			__raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1);
-			__raw_writew(0x0015, bank->base + OMAP24XX_GPIO_SYSCONFIG);
-			__raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_DEBOUNCE_EN);
+				/*
+				 * Initialize interface clock ungated,
+				 * module enabled
+				 */
+				__raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
+			} else {
+				__raw_writel(0x00000000, bank->base +
+						OMAP24XX_GPIO_IRQENABLE1);
+				__raw_writel(0xffffffff, bank->base +
+						OMAP24XX_GPIO_IRQSTATUS1);
+				__raw_writew(0x0015, bank->base +
+						OMAP24XX_GPIO_SYSCONFIG);
+				__raw_writel(0x00000000, bank->base +
+						OMAP24XX_GPIO_DEBOUNCE_EN);
 
-			/* Initialize interface clock ungated, module enabled */
-			__raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL);
-		}
+				/*
+				 * Initialize interface clock ungated,
+				 * module enabled
+				 */
+				__raw_writel(0, bank->base +
+						OMAP24XX_GPIO_CTRL);
+			}
 			if (i < ARRAY_SIZE(non_wakeup_gpios))
 				bank->non_wakeup_gpios = non_wakeup_gpios[i];
 			gpio_count = 32;
@@ -1903,8 +1915,7 @@ static int __init _omap_gpio_init(void)
 	return 0;
 }
 
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) || \
-		defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
 static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
 {
 	int i;
@@ -1927,7 +1938,7 @@ static int omap_gpio_suspend(struct sys_
 			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
 			break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 		case METHOD_GPIO_24XX:
 			wake_status = bank->base + OMAP24XX_GPIO_WAKE_EN;
 			wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
@@ -1935,7 +1946,7 @@ static int omap_gpio_suspend(struct sys_
 			break;
 #endif
 #ifdef CONFIG_ARCH_OMAP4
-		case METHOD_GPIO_24XX:
+		case METHOD_GPIO_44XX:
 			wake_status = bank->base + OMAP4_GPIO_IRQWAKEN0;
 			wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0;
 			wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0;
@@ -1975,14 +1986,14 @@ static int omap_gpio_resume(struct sys_d
 			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
 			break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 		case METHOD_GPIO_24XX:
 			wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
 			wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
 			break;
 #endif
 #ifdef CONFIG_ARCH_OMAP4
-		case METHOD_GPIO_24XX:
+		case METHOD_GPIO_44XX:
 			wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0;
 			wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0;
 			break;
@@ -2013,8 +2024,7 @@ static struct sys_device omap_gpio_devic
 
 #endif
 
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-				defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP2PLUS
 
 static int workaround_enabled;
 
@@ -2030,29 +2040,42 @@ void omap2_gpio_prepare_for_retention(vo
 
 		if (!(bank->enabled_non_wakeup_gpios))
 			continue;
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
-		bank->saved_datain = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
-		l1 = __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-		l2 = __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-		bank->saved_datain = __raw_readl(bank->base +
-							OMAP4_GPIO_DATAIN);
-		l1 = __raw_readl(bank->base + OMAP4_GPIO_FALLINGDETECT);
-		l2 = __raw_readl(bank->base + OMAP4_GPIO_RISINGDETECT);
-#endif
+
+		if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+			bank->saved_datain = __raw_readl(bank->base +
+					OMAP24XX_GPIO_DATAIN);
+			l1 = __raw_readl(bank->base +
+					OMAP24XX_GPIO_FALLINGDETECT);
+			l2 = __raw_readl(bank->base +
+					OMAP24XX_GPIO_RISINGDETECT);
+		}
+
+		if (cpu_is_omap44xx()) {
+			bank->saved_datain = __raw_readl(bank->base +
+						OMAP4_GPIO_DATAIN);
+			l1 = __raw_readl(bank->base +
+						OMAP4_GPIO_FALLINGDETECT);
+			l2 = __raw_readl(bank->base +
+						OMAP4_GPIO_RISINGDETECT);
+		}
+
 		bank->saved_fallingdetect = l1;
 		bank->saved_risingdetect = l2;
 		l1 &= ~bank->enabled_non_wakeup_gpios;
 		l2 &= ~bank->enabled_non_wakeup_gpios;
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
-		__raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-		__raw_writel(l2, bank->base + OMAP24XX_GPIO_RISINGDETECT);
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-		__raw_writel(l1, bank->base + OMAP4_GPIO_FALLINGDETECT);
-		__raw_writel(l2, bank->base + OMAP4_GPIO_RISINGDETECT);
-#endif
+
+		if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+			__raw_writel(l1, bank->base +
+					OMAP24XX_GPIO_FALLINGDETECT);
+			__raw_writel(l2, bank->base +
+					OMAP24XX_GPIO_RISINGDETECT);
+		}
+
+		if (cpu_is_omap44xx()) {
+			__raw_writel(l1, bank->base + OMAP4_GPIO_FALLINGDETECT);
+			__raw_writel(l2, bank->base + OMAP4_GPIO_RISINGDETECT);
+		}
+
 		c++;
 	}
 	if (!c) {
@@ -2074,20 +2097,23 @@ void omap2_gpio_resume_after_retention(v
 
 		if (!(bank->enabled_non_wakeup_gpios))
 			continue;
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
-		__raw_writel(bank->saved_fallingdetect,
+
+		if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+			__raw_writel(bank->saved_fallingdetect,
 				 bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-		__raw_writel(bank->saved_risingdetect,
+			__raw_writel(bank->saved_risingdetect,
 				 bank->base + OMAP24XX_GPIO_RISINGDETECT);
-		l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-		__raw_writel(bank->saved_fallingdetect,
+			l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
+		}
+
+		if (cpu_is_omap44xx()) {
+			__raw_writel(bank->saved_fallingdetect,
 				 bank->base + OMAP4_GPIO_FALLINGDETECT);
-		__raw_writel(bank->saved_risingdetect,
+			__raw_writel(bank->saved_risingdetect,
 				 bank->base + OMAP4_GPIO_RISINGDETECT);
-		l = __raw_readl(bank->base + OMAP4_GPIO_DATAIN);
-#endif
+			l = __raw_readl(bank->base + OMAP4_GPIO_DATAIN);
+		}
+
 		/* Check if any of the non-wakeup interrupt GPIOs have changed
 		 * state.  If so, generate an IRQ by software.  This is
 		 * horribly racy, but it's the best we can do to work around
@@ -2113,30 +2139,36 @@ void omap2_gpio_resume_after_retention(v
 
 		if (gen) {
 			u32 old0, old1;
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
-			old0 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
-			old1 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-			__raw_writel(old0 | gen, bank->base +
+
+			if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+				old0 = __raw_readl(bank->base +
 					OMAP24XX_GPIO_LEVELDETECT0);
-			__raw_writel(old1 | gen, bank->base +
+				old1 = __raw_readl(bank->base +
 					OMAP24XX_GPIO_LEVELDETECT1);
-			__raw_writel(old0, bank->base + OMAP24XX_GPIO_LEVELDETECT0);
-			__raw_writel(old1, bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-			old0 = __raw_readl(bank->base +
+				__raw_writel(old0 | gen, bank->base +
+					OMAP24XX_GPIO_LEVELDETECT0);
+				__raw_writel(old1 | gen, bank->base +
+					OMAP24XX_GPIO_LEVELDETECT1);
+				__raw_writel(old0, bank->base +
+					OMAP24XX_GPIO_LEVELDETECT0);
+				__raw_writel(old1, bank->base +
+					OMAP24XX_GPIO_LEVELDETECT1);
+			}
+
+			if (cpu_is_omap44xx()) {
+				old0 = __raw_readl(bank->base +
 						OMAP4_GPIO_LEVELDETECT0);
-			old1 = __raw_readl(bank->base +
+				old1 = __raw_readl(bank->base +
 						OMAP4_GPIO_LEVELDETECT1);
-			__raw_writel(old0 | l, bank->base +
+				__raw_writel(old0 | l, bank->base +
 						OMAP4_GPIO_LEVELDETECT0);
-			__raw_writel(old1 | l, bank->base +
+				__raw_writel(old1 | l, bank->base +
 						OMAP4_GPIO_LEVELDETECT1);
-			__raw_writel(old0, bank->base +
+				__raw_writel(old0, bank->base +
 						OMAP4_GPIO_LEVELDETECT0);
-			__raw_writel(old1, bank->base +
+				__raw_writel(old1, bank->base +
 						OMAP4_GPIO_LEVELDETECT1);
-#endif
+			}
 		}
 	}
 
@@ -2144,7 +2176,7 @@ void omap2_gpio_resume_after_retention(v
 
 #endif
 
-#ifdef CONFIG_ARCH_OMAP34XX
+#ifdef CONFIG_ARCH_OMAP3
 /* save the registers of bank 2-6 */
 void omap_gpio_save_context(void)
 {
@@ -2240,8 +2272,7 @@ static int __init omap_gpio_sysinit(void
 
 	mpuio_init();
 
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) || \
-		defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
 	if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
 		if (ret == 0) {
 			ret = sysdev_class_register(&omap_gpio_sysclass);
@@ -2300,8 +2331,7 @@ static int dbg_gpio_show(struct seq_file
 /* FIXME for at least omap2, show pullup/pulldown state */
 
 			irqstat = irq_desc[irq].status;
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) ||	\
-		defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
 			if (is_in && ((bank->suspend_wakeup & mask)
 					|| irqstat & IRQ_TYPE_SENSE_MASK)) {
 				char	*trigger = NULL;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/i2c.c linux-libre-2.6.34-gnu1/arch/arm/plat-omap/i2c.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/i2c.h>
 #include <mach/irqs.h>
 #include <plat/mux.h>
+#include <plat/i2c.h>
 
 #define OMAP_I2C_SIZE		0x3f
 #define OMAP1_I2C_BASE		0xfffb3800
@@ -50,10 +51,10 @@ static const char name[] = "i2c_omap";
 
 static struct resource i2c_resources[][2] = {
 	{ I2C_RESOURCE_BUILDER(0, 0) },
-#if	defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+#if	defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 	{ I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, INT_24XX_I2C2_IRQ) },
 #endif
-#if	defined(CONFIG_ARCH_OMAP34XX)
+#if	defined(CONFIG_ARCH_OMAP3)
 	{ I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, INT_34XX_I2C3_IRQ) },
 #endif
 };
@@ -72,10 +73,10 @@ static struct resource i2c_resources[][2
 static u32 i2c_rate[ARRAY_SIZE(i2c_resources)];
 static struct platform_device omap_i2c_devices[] = {
 	I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_rate[0]),
-#if	defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+#if	defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 	I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_rate[1]),
 #endif
-#if	defined(CONFIG_ARCH_OMAP34XX)
+#if	defined(CONFIG_ARCH_OMAP3)
 	I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_rate[2]),
 #endif
 };
@@ -117,6 +118,11 @@ static int __init omap_i2c_add_bus(int b
 		res[1].start = irq;
 	}
 
+	if (cpu_class_is_omap1())
+		omap1_i2c_mux_pins(bus_id);
+	if (cpu_class_is_omap2())
+		omap2_i2c_mux_pins(bus_id);
+
 	return platform_device_register(pdev);
 }
 
@@ -169,7 +175,7 @@ out:
 subsys_initcall(omap_register_i2c_bus_cmdline);
 
 /**
- * omap_plat_register_i2c_bus - register I2C bus with device descriptors
+ * 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
@@ -177,7 +183,7 @@ subsys_initcall(omap_register_i2c_bus_cm
  *
  * Returns 0 on success or an error code.
  */
-int __init omap_plat_register_i2c_bus(int bus_id, u32 clkrate,
+int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
 			  struct i2c_board_info const *info,
 			  unsigned len)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/blizzard.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/blizzard.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/blizzard.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/blizzard.h	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@ struct blizzard_platform_data {
 	void		(*power_down)(struct device *dev);
 	unsigned long	(*get_clock_rate)(struct device *dev);
 
-	unsigned	te_connected : 1;
+	unsigned	te_connected:1;
 };
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/clkdev_omap.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/clkdev_omap.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/clkdev_omap.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/clkdev_omap.h	2010-05-16 17:17:36.000000000 -0400
@@ -25,17 +25,25 @@ struct omap_clk {
 		},			\
 	}
 
-
+/* Platform flags for the clkdev-OMAP integration code */
 #define CK_310		(1 << 0)
-#define CK_7XX		(1 << 1)
+#define CK_7XX		(1 << 1)	/* 7xx, 850 */
 #define CK_1510		(1 << 2)
-#define CK_16XX		(1 << 3)
-#define CK_243X		(1 << 4)
-#define CK_242X		(1 << 5)
-#define CK_343X		(1 << 6)
-#define CK_3430ES1	(1 << 7)
-#define CK_3430ES2	(1 << 8)
-#define CK_443X		(1 << 9)
+#define CK_16XX		(1 << 3)	/* 16xx, 17xx, 5912 */
+#define CK_242X		(1 << 4)
+#define CK_243X		(1 << 5)
+#define CK_3XXX		(1 << 6)	/* OMAP3 + AM3 common clocks*/
+#define CK_343X		(1 << 7)	/* OMAP34xx common clocks */
+#define CK_3430ES1	(1 << 8)	/* 34xxES1 only */
+#define CK_3430ES2	(1 << 9)	/* 34xxES2, ES3, non-Sitara 35xx only */
+#define CK_3505		(1 << 10)
+#define CK_3517		(1 << 11)
+#define CK_36XX		(1 << 12)	/* OMAP36xx/37xx-specific clocks */
+#define CK_443X		(1 << 13)
+
+#define CK_AM35XX	(CK_3505 | CK_3517)	/* all Sitara AM35xx */
+
+
 
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/clockdomain.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/clockdomain.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/clockdomain.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/clockdomain.h	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
  * OMAP2/3 clockdomain framework functions
  *
  * Copyright (C) 2008 Texas Instruments, Inc.
- * Copyright (C) 2008 Nokia Corporation
+ * Copyright (C) 2008-2009 Nokia Corporation
  *
  * Written by Paul Walmsley
  *
@@ -40,65 +40,95 @@
 #define OMAP34XX_CLKSTCTRL_FORCE_WAKEUP		0x2
 #define OMAP34XX_CLKSTCTRL_ENABLE_AUTO		0x3
 
-/*
- * struct clkdm_pwrdm_autodep - a powerdomain that should have wkdeps
- * and sleepdeps added when a powerdomain should stay active in hwsup mode;
- * and conversely, removed when the powerdomain should be allowed to go
- * inactive in hwsup mode.
+/**
+ * struct clkdm_autodep - clkdm deps to add when entering/exiting hwsup mode
+ * @clkdm: clockdomain to add wkdep+sleepdep on - set name member only
+ * @omap_chip: OMAP chip types that this autodep is valid on
+ *
+ * A clockdomain that should have wkdeps and sleepdeps added when a
+ * clockdomain should stay active in hwsup mode; and conversely,
+ * removed when the clockdomain should be allowed to go inactive in
+ * hwsup mode.
+ *
+ * Autodeps are deprecated and should be removed after
+ * omap_hwmod-based fine-grained module idle control is added.
  */
-struct clkdm_pwrdm_autodep {
-
+struct clkdm_autodep {
 	union {
-		/* Name of the powerdomain to add a wkdep/sleepdep on */
 		const char *name;
-
-		/* Powerdomain pointer (looked up at clkdm_init() time) */
-		struct powerdomain *ptr;
-	} pwrdm;
-
-	/* OMAP chip types that this clockdomain dep is valid on */
+		struct clockdomain *ptr;
+	} clkdm;
 	const struct omap_chip_id omap_chip;
+};
 
+/**
+ * struct clkdm_dep - encode dependencies between clockdomains
+ * @clkdm_name: clockdomain name
+ * @clkdm: pointer to the struct clockdomain of @clkdm_name
+ * @omap_chip: OMAP chip types that this dependency is valid on
+ * @wkdep_usecount: Number of wakeup dependencies causing this clkdm to wake
+ * @sleepdep_usecount: Number of sleep deps that could prevent clkdm from idle
+ *
+ * Statically defined.  @clkdm is resolved from @clkdm_name at runtime and
+ * should not be pre-initialized.
+ *
+ * XXX Should also include hardware (fixed) dependencies.
+ */
+struct clkdm_dep {
+	const char *clkdm_name;
+	struct clockdomain *clkdm;
+	atomic_t wkdep_usecount;
+	atomic_t sleepdep_usecount;
+	const struct omap_chip_id omap_chip;
 };
 
+/**
+ * struct clockdomain - OMAP clockdomain
+ * @name: clockdomain name
+ * @pwrdm: powerdomain containing this clockdomain
+ * @clktrctrl_reg: CLKSTCTRL reg for the given clock domain
+ * @clktrctrl_mask: CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg
+ * @flags: Clockdomain capability flags
+ * @dep_bit: Bit shift of this clockdomain's PM_WKDEP/CM_SLEEPDEP bit
+ * @wkdep_srcs: Clockdomains that can be told to wake this powerdomain up
+ * @sleepdep_srcs: Clockdomains that can be told to keep this clkdm from inact
+ * @omap_chip: OMAP chip types that this clockdomain is valid on
+ * @usecount: Usecount tracking
+ * @node: list_head to link all clockdomains together
+ */
 struct clockdomain {
-
-	/* Clockdomain name */
 	const char *name;
-
 	union {
-		/* Powerdomain enclosing this clockdomain */
 		const char *name;
-
-		/* Powerdomain pointer assigned at clkdm_register() */
 		struct powerdomain *ptr;
 	} pwrdm;
-
-	/* CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg */
+	void __iomem *clkstctrl_reg;
 	const u16 clktrctrl_mask;
-
-	/* Clockdomain capability flags */
 	const u8 flags;
-
-	/* OMAP chip types that this clockdomain is valid on */
+	const u8 dep_bit;
+	struct clkdm_dep *wkdep_srcs;
+	struct clkdm_dep *sleepdep_srcs;
 	const struct omap_chip_id omap_chip;
-
-	/* Usecount tracking */
 	atomic_t usecount;
-
 	struct list_head node;
-
 };
 
-void clkdm_init(struct clockdomain **clkdms, struct clkdm_pwrdm_autodep *autodeps);
-int clkdm_register(struct clockdomain *clkdm);
-int clkdm_unregister(struct clockdomain *clkdm);
+void clkdm_init(struct clockdomain **clkdms, struct clkdm_autodep *autodeps);
 struct clockdomain *clkdm_lookup(const char *name);
 
 int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
 			void *user);
 struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm);
 
+int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+int clkdm_clear_all_wkdeps(struct clockdomain *clkdm);
+int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
+
 void omap2_clkdm_allow_idle(struct clockdomain *clkdm);
 void omap2_clkdm_deny_idle(struct clockdomain *clkdm);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/clock.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,9 +1,9 @@
 /*
- *  arch/arm/plat-omap/include/mach/clock.h
+ * OMAP clock: data structure definitions, function prototypes, shared macros
  *
- *  Copyright (C) 2004 - 2005 Nokia corporation
- *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
- *  Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
+ * Copyright (C) 2004-2005, 2008-2010 Nokia Corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -22,12 +22,13 @@ struct clockdomain;
 struct clkops {
 	int			(*enable)(struct clk *);
 	void			(*disable)(struct clk *);
-	void			(*find_idlest)(struct clk *, void __iomem **, u8 *);
-	void			(*find_companion)(struct clk *, void __iomem **, u8 *);
+	void			(*find_idlest)(struct clk *, void __iomem **,
+					       u8 *, u8 *);
+	void			(*find_companion)(struct clk *, void __iomem **,
+						  u8 *);
 };
 
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
-		defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP2PLUS
 
 struct clksel_rate {
 	u32			val;
@@ -40,6 +41,50 @@ struct clksel {
 	const struct clksel_rate *rates;
 };
 
+/**
+ * struct dpll_data - DPLL registers and integration data
+ * @mult_div1_reg: register containing the DPLL M and N bitfields
+ * @mult_mask: mask of the DPLL M bitfield in @mult_div1_reg
+ * @div1_mask: mask of the DPLL N bitfield in @mult_div1_reg
+ * @clk_bypass: struct clk pointer to the clock's bypass clock input
+ * @clk_ref: struct clk pointer to the clock's reference clock input
+ * @control_reg: register containing the DPLL mode bitfield
+ * @enable_mask: mask of the DPLL mode bitfield in @control_reg
+ * @rate_tolerance: maximum variance allowed from target rate (in Hz)
+ * @last_rounded_rate: cache of the last rate result of omap2_dpll_round_rate()
+ * @last_rounded_m: cache of the last M result of omap2_dpll_round_rate()
+ * @max_multiplier: maximum valid non-bypass multiplier value (actual)
+ * @last_rounded_n: cache of the last N result of omap2_dpll_round_rate()
+ * @min_divider: minimum valid non-bypass divider value (actual)
+ * @max_divider: maximum valid non-bypass divider value (actual)
+ * @modes: possible values of @enable_mask
+ * @autoidle_reg: register containing the DPLL autoidle mode bitfield
+ * @idlest_reg: register containing the DPLL idle status bitfield
+ * @autoidle_mask: mask of the DPLL autoidle mode bitfield in @autoidle_reg
+ * @freqsel_mask: mask of the DPLL jitter correction bitfield in @control_reg
+ * @idlest_mask: mask of the DPLL idle status bitfield in @idlest_reg
+ * @auto_recal_bit: bitshift of the driftguard enable bit in @control_reg
+ * @recal_en_bit: bitshift of the PRM_IRQENABLE_* bit for recalibration IRQs
+ * @recal_st_bit: bitshift of the PRM_IRQSTATUS_* bit for recalibration IRQs
+ * @flags: DPLL type/features (see below)
+ *
+ * Possible values for @flags:
+ * DPLL_J_TYPE: "J-type DPLL" (only some 36xx, 4xxx DPLLs)
+ * NO_DCO_SEL: don't program DCO (only for some J-type DPLLs)
+
+ * @freqsel_mask is only used on the OMAP34xx family and AM35xx.
+ *
+ * XXX Some DPLLs have multiple bypass inputs, so it's not technically
+ * correct to only have one @clk_bypass pointer.
+ *
+ * XXX @rate_tolerance should probably be deprecated - currently there
+ * don't seem to be any usecases for DPLL rounding that is not exact.
+ *
+ * XXX The runtime-variable fields (@last_rounded_rate, @last_rounded_m,
+ * @last_rounded_n) should be separated from the runtime-fixed fields
+ * and placed into a differenct structure, so that the runtime-fixed data
+ * can be placed into read-only space.
+ */
 struct dpll_data {
 	void __iomem		*mult_div1_reg;
 	u32			mult_mask;
@@ -51,13 +96,12 @@ struct dpll_data {
 	unsigned int		rate_tolerance;
 	unsigned long		last_rounded_rate;
 	u16			last_rounded_m;
+	u16			max_multiplier;
 	u8			last_rounded_n;
 	u8			min_divider;
 	u8			max_divider;
-	u32			max_tolerance;
-	u16			max_multiplier;
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
 	u8			modes;
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
 	void __iomem		*autoidle_reg;
 	void __iomem		*idlest_reg;
 	u32			autoidle_mask;
@@ -66,6 +110,7 @@ struct dpll_data {
 	u8			auto_recal_bit;
 	u8			recal_en_bit;
 	u8			recal_st_bit;
+	u8			flags;
 #  endif
 };
 
@@ -75,12 +120,10 @@ struct clk {
 	struct list_head	node;
 	const struct clkops	*ops;
 	const char		*name;
-	int			id;
 	struct clk		*parent;
 	struct list_head	children;
 	struct list_head	sibling;	/* node for children */
 	unsigned long		rate;
-	__u32			flags;
 	void __iomem		*enable_reg;
 	unsigned long		(*recalc)(struct clk *);
 	int			(*set_rate)(struct clk *, unsigned long);
@@ -88,9 +131,9 @@ struct clk {
 	void			(*init)(struct clk *);
 	__u8			enable_bit;
 	__s8			usecount;
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
-		defined(CONFIG_ARCH_OMAP4)
 	u8			fixed_div;
+	u8			flags;
+#ifdef CONFIG_ARCH_OMAP2PLUS
 	void __iomem		*clksel_reg;
 	u32			clksel_mask;
 	const struct clksel	*clksel;
@@ -123,7 +166,7 @@ struct clk_functions {
 #endif
 };
 
-extern unsigned int mpurate;
+extern int mpurate;
 
 extern int clk_init(struct clk_functions *custom_clocks);
 extern void clk_preinit(struct clk *clk);
@@ -134,27 +177,23 @@ extern void propagate_rate(struct clk *c
 extern void recalculate_root_clocks(void);
 extern unsigned long followparent_recalc(struct clk *clk);
 extern void clk_enable_init_clocks(void);
+unsigned long omap_fixed_divisor_recalc(struct clk *clk);
 #ifdef CONFIG_CPU_FREQ
 extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
 extern void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
 #endif
+extern struct clk *omap_clk_get_by_name(const char *name);
 
 extern const struct clkops clkops_null;
 
+extern struct clk dummy_ck;
+
 /* Clock flags */
-/* bit 0 is free */
-#define RATE_FIXED		(1 << 1)	/* Fixed clock rate */
-/* bits 2-4 are free */
-#define ENABLE_REG_32BIT	(1 << 5)	/* Use 32-bit access */
-#define CLOCK_IDLE_CONTROL	(1 << 7)
-#define CLOCK_NO_IDLE_PARENT	(1 << 8)
-#define DELAYED_APP		(1 << 9)	/* Delay application of clock */
-#define CONFIG_PARTICIPANT	(1 << 10)	/* Fundamental clock */
-#define ENABLE_ON_INIT		(1 << 11)	/* Enable upon framework init */
-#define INVERT_ENABLE           (1 << 12)       /* 0 enables, 1 disables */
-#define CLOCK_IN_OMAP4430	(1 << 13)
-#define ALWAYS_ENABLED		(1 << 14)
-/* bits 13-31 are currently free */
+#define ENABLE_REG_32BIT	(1 << 0)	/* Use 32-bit access */
+#define CLOCK_IDLE_CONTROL	(1 << 1)
+#define CLOCK_NO_IDLE_PARENT	(1 << 2)
+#define ENABLE_ON_INIT		(1 << 3)	/* Enable upon framework init */
+#define INVERT_ENABLE		(1 << 4)	/* 0 enables, 1 disables */
 
 /* Clksel_rate flags */
 #define DEFAULT_RATE		(1 << 0)
@@ -162,7 +201,8 @@ extern const struct clkops clkops_null;
 #define RATE_IN_243X		(1 << 2)
 #define RATE_IN_343X		(1 << 3)	/* rates common to all 343X */
 #define RATE_IN_3430ES2		(1 << 4)	/* 3430ES2 rates only */
-#define RATE_IN_4430            (1 << 5)
+#define RATE_IN_36XX		(1 << 5)
+#define RATE_IN_4430		(1 << 6)
 
 #define RATE_IN_24XX		(RATE_IN_242X | RATE_IN_243X)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/common.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/common.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/common.h	2010-05-16 17:17:36.000000000 -0400
@@ -37,21 +37,30 @@ extern void __iomem *gic_cpu_base_addr;
 extern void omap_map_common_io(void);
 extern struct sys_timer omap_timer;
 
-/* IO bases for various OMAP processors */
+/*
+ * IO bases for various OMAP processors
+ * Except the tap base, rest all the io bases
+ * listed are physical addresses.
+ */
 struct omap_globals {
 	u32		class;		/* OMAP class to detect */
 	void __iomem	*tap;		/* Control module ID code */
-	void __iomem	*sdrc;		/* SDRAM Controller */
-	void __iomem	*sms;		/* SDRAM Memory Scheduler */
-	void __iomem	*ctrl;		/* System Control Module */
-	void __iomem	*prm;		/* Power and Reset Management */
-	void __iomem	*cm;		/* Clock Management */
-	void __iomem	*cm2;
+	unsigned long   sdrc;           /* SDRAM Controller */
+	unsigned long   sms;            /* SDRAM Memory Scheduler */
+	unsigned long   ctrl;           /* System Control Module */
+	unsigned long   prm;            /* Power and Reset Management */
+	unsigned long   cm;             /* Clock Management */
+	unsigned long   cm2;
+	unsigned long	uart1_phys;
+	unsigned long	uart2_phys;
+	unsigned long	uart3_phys;
+	unsigned long	uart4_phys;
 };
 
 void omap2_set_globals_242x(void);
 void omap2_set_globals_243x(void);
 void omap2_set_globals_343x(void);
+void omap2_set_globals_36xx(void);
 void omap2_set_globals_443x(void);
 
 /* These get called from omap2_set_globals_xxxx(), do not call these */
@@ -59,6 +68,7 @@ void omap2_set_globals_tap(struct omap_g
 void omap2_set_globals_sdrc(struct omap_globals *);
 void omap2_set_globals_control(struct omap_globals *);
 void omap2_set_globals_prcm(struct omap_globals *);
+void omap2_set_globals_uart(struct omap_globals *);
 
 /**
  * omap_test_timeout - busy-loop, testing a condition
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/control.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/control.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/control.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/control.h	2010-05-16 17:17:36.000000000 -0400
@@ -160,6 +160,14 @@
 #define OMAP343X_CONTROL_SRAMLDO5	(OMAP2_CONTROL_GENERAL + 0x02C0)
 #define OMAP343X_CONTROL_CSI		(OMAP2_CONTROL_GENERAL + 0x02C4)
 
+/* AM35XX only CONTROL_GENERAL register offsets */
+#define AM35XX_CONTROL_MSUSPENDMUX_6    (OMAP2_CONTROL_GENERAL + 0x0038)
+#define AM35XX_CONTROL_DEVCONF2         (OMAP2_CONTROL_GENERAL + 0x0310)
+#define AM35XX_CONTROL_DEVCONF3         (OMAP2_CONTROL_GENERAL + 0x0314)
+#define AM35XX_CONTROL_CBA_PRIORITY     (OMAP2_CONTROL_GENERAL + 0x0320)
+#define AM35XX_CONTROL_LVL_INTR_CLEAR   (OMAP2_CONTROL_GENERAL + 0x0324)
+#define AM35XX_CONTROL_IP_SW_RESET      (OMAP2_CONTROL_GENERAL + 0x0328)
+#define AM35XX_CONTROL_IPSS_CLK_CTRL    (OMAP2_CONTROL_GENERAL + 0x032C)
 
 /* 34xx PADCONF register offsets */
 #define OMAP343X_PADCONF_ETK(i)		(OMAP2_CONTROL_PADCONFS + 0x5a8 + \
@@ -196,6 +204,9 @@
 #define OMAP3_PADCONF_SAD2D_MSTANDBY   0x250
 #define OMAP3_PADCONF_SAD2D_IDLEACK    0x254
 
+/* 44xx control status register offset */
+#define OMAP44XX_CONTROL_STATUS		0x2c4
+
 /*
  * REVISIT: This list of registers is not comprehensive - there are more
  * that should be added.
@@ -257,6 +268,32 @@
 #define OMAP343X_SCRATCHPAD		(OMAP343X_CTRL_BASE + 0x910)
 #define OMAP343X_SCRATCHPAD_ROM_OFFSET	0x19C
 
+/* AM35XX_CONTROL_IPSS_CLK_CTRL bits */
+#define AM35XX_USBOTG_VBUSP_CLK_SHIFT   0
+#define AM35XX_CPGMAC_VBUSP_CLK_SHIFT   1
+#define AM35XX_VPFE_VBUSP_CLK_SHIFT     2
+#define AM35XX_HECC_VBUSP_CLK_SHIFT     3
+#define AM35XX_USBOTG_FCLK_SHIFT        8
+#define AM35XX_CPGMAC_FCLK_SHIFT        9
+#define AM35XX_VPFE_FCLK_SHIFT          10
+
+/*AM35XX CONTROL_LVL_INTR_CLEAR bits*/
+#define AM35XX_CPGMAC_C0_MISC_PULSE_CLR	BIT(0)
+#define AM35XX_CPGMAC_C0_RX_PULSE_CLR	BIT(1)
+#define AM35XX_CPGMAC_C0_RX_THRESH_CLR	BIT(2)
+#define AM35XX_CPGMAC_C0_TX_PULSE_CLR	BIT(3)
+#define AM35XX_USBOTGSS_INT_CLR		BIT(4)
+#define AM35XX_VPFE_CCDC_VD0_INT_CLR	BIT(5)
+#define AM35XX_VPFE_CCDC_VD1_INT_CLR	BIT(6)
+#define AM35XX_VPFE_CCDC_VD2_INT_CLR	BIT(7)
+
+/*AM35XX CONTROL_IP_SW_RESET bits*/
+#define AM35XX_USBOTGSS_SW_RST		BIT(0)
+#define AM35XX_CPGMACSS_SW_RST		BIT(1)
+#define AM35XX_VPFE_VBUSP_SW_RST	BIT(2)
+#define AM35XX_HECC_SW_RST		BIT(3)
+#define AM35XX_VPFE_PCLK_SW_RST		BIT(4)
+
 /*
  * CONTROL OMAP STATUS register to identify OMAP3 features
  */
@@ -292,8 +329,7 @@
 
 
 #ifndef __ASSEMBLY__
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
-		defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP2PLUS
 extern void __iomem *omap_ctrl_base_get(void);
 extern u8 omap_ctrl_readb(u16 offset);
 extern u16 omap_ctrl_readw(u16 offset);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/cpu.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/cpu.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/cpu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/cpu.h	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #define __ASM_ARCH_OMAP_CPU_H
 
 #include <linux/bitops.h>
+#include <plat/multi.h>
 
 /*
  * Omap device type i.e. EMU/HS/TST/GP/BAD
@@ -44,7 +45,7 @@
 int omap_type(void);
 
 struct omap_chip_id {
-	u8 oc;
+	u16 oc;
 	u8 type;
 };
 
@@ -76,75 +77,6 @@ unsigned int omap_rev(void);
 #define GET_OMAP_REVISION()	((omap_rev() >> 8) & 0xff)
 
 /*
- * Test if multicore OMAP support is needed
- */
-#undef MULTI_OMAP1
-#undef MULTI_OMAP2
-#undef OMAP_NAME
-
-#ifdef CONFIG_ARCH_OMAP730
-# ifdef OMAP_NAME
-#  undef  MULTI_OMAP1
-#  define MULTI_OMAP1
-# else
-#  define OMAP_NAME omap730
-# endif
-#endif
-#ifdef CONFIG_ARCH_OMAP850
-# ifdef OMAP_NAME
-#  undef  MULTI_OMAP1
-#  define MULTI_OMAP1
-# else
-#  define OMAP_NAME omap850
-# endif
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-# ifdef OMAP_NAME
-#  undef  MULTI_OMAP1
-#  define MULTI_OMAP1
-# else
-#  define OMAP_NAME omap1510
-# endif
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-# ifdef OMAP_NAME
-#  undef  MULTI_OMAP1
-#  define MULTI_OMAP1
-# else
-#  define OMAP_NAME omap16xx
-# endif
-#endif
-#if (defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX))
-# if (defined(OMAP_NAME) || defined(MULTI_OMAP1))
-#  error "OMAP1 and OMAP2 can't be selected at the same time"
-# endif
-#endif
-#ifdef CONFIG_ARCH_OMAP2420
-# ifdef OMAP_NAME
-#  undef  MULTI_OMAP2
-#  define MULTI_OMAP2
-# else
-#  define OMAP_NAME omap2420
-# endif
-#endif
-#ifdef CONFIG_ARCH_OMAP2430
-# ifdef OMAP_NAME
-#  undef  MULTI_OMAP2
-#  define MULTI_OMAP2
-# else
-#  define OMAP_NAME omap2430
-# endif
-#endif
-#ifdef CONFIG_ARCH_OMAP3430
-# ifdef OMAP_NAME
-#  undef  MULTI_OMAP2
-#  define MULTI_OMAP2
-# else
-#  define OMAP_NAME omap3430
-# endif
-#endif
-
-/*
  * Macros to group OMAP into cpu classes.
  * These can be used in most places.
  * cpu_is_omap7xx():	True for OMAP730, OMAP850
@@ -154,6 +86,7 @@ unsigned int omap_rev(void);
  * cpu_is_omap242x():	True for OMAP2420, OMAP2422, OMAP2423
  * cpu_is_omap243x():	True for OMAP2430
  * cpu_is_omap343x():	True for OMAP3430
+ * cpu_is_omap443x():	True for OMAP4430
  */
 #define GET_OMAP_CLASS	(omap_rev() & 0xff)
 
@@ -232,22 +165,26 @@ IS_OMAP_SUBCLASS(443x, 0x443)
 #endif
 
 #if defined(MULTI_OMAP2)
-# if defined(CONFIG_ARCH_OMAP24XX)
+# if defined(CONFIG_ARCH_OMAP2)
 #  undef  cpu_is_omap24xx
-#  undef  cpu_is_omap242x
-#  undef  cpu_is_omap243x
 #  define cpu_is_omap24xx()		is_omap24xx()
+# endif
+# if defined (CONFIG_ARCH_OMAP2420)
+#  undef  cpu_is_omap242x
 #  define cpu_is_omap242x()		is_omap242x()
+# endif
+# if defined (CONFIG_ARCH_OMAP2430)
+#  undef  cpu_is_omap243x
 #  define cpu_is_omap243x()		is_omap243x()
 # endif
-# if defined(CONFIG_ARCH_OMAP34XX)
+# if defined(CONFIG_ARCH_OMAP3)
 #  undef  cpu_is_omap34xx
 #  undef  cpu_is_omap343x
 #  define cpu_is_omap34xx()		is_omap34xx()
 #  define cpu_is_omap343x()		is_omap343x()
 # endif
 #else
-# if defined(CONFIG_ARCH_OMAP24XX)
+# if defined(CONFIG_ARCH_OMAP2)
 #  undef  cpu_is_omap24xx
 #  define cpu_is_omap24xx()		1
 # endif
@@ -259,7 +196,7 @@ IS_OMAP_SUBCLASS(443x, 0x443)
 #  undef  cpu_is_omap243x
 #  define cpu_is_omap243x()		1
 # endif
-# if defined(CONFIG_ARCH_OMAP34XX)
+# if defined(CONFIG_ARCH_OMAP3)
 #  undef  cpu_is_omap34xx
 #  define cpu_is_omap34xx()		1
 # endif
@@ -286,6 +223,7 @@ IS_OMAP_SUBCLASS(443x, 0x443)
  * cpu_is_omap2423():	True for OMAP2423
  * cpu_is_omap2430():	True for OMAP2430
  * cpu_is_omap3430():	True for OMAP3430
+ * cpu_is_omap4430():	True for OMAP4430
  * cpu_is_omap3505():	True for OMAP3505
  * cpu_is_omap3517():	True for OMAP3517
  */
@@ -334,6 +272,7 @@ IS_OMAP_TYPE(3517, 0x3517)
 #define cpu_is_omap3505()		0
 #define cpu_is_omap3517()		0
 #define cpu_is_omap3430()		0
+#define cpu_is_omap4430()		0
 #define cpu_is_omap3630()		0
 
 /*
@@ -371,7 +310,7 @@ IS_OMAP_TYPE(3517, 0x3517)
 # define cpu_is_omap1710()		is_omap1710()
 #endif
 
-#if defined(CONFIG_ARCH_OMAP24XX)
+#if defined(CONFIG_ARCH_OMAP2)
 # undef  cpu_is_omap2420
 # undef  cpu_is_omap2422
 # undef  cpu_is_omap2423
@@ -382,7 +321,7 @@ IS_OMAP_TYPE(3517, 0x3517)
 # define cpu_is_omap2430()		is_omap2430()
 #endif
 
-#if defined(CONFIG_ARCH_OMAP34XX)
+#if defined(CONFIG_ARCH_OMAP3)
 # undef cpu_is_omap3430
 # undef cpu_is_omap3503
 # undef cpu_is_omap3515
@@ -471,9 +410,12 @@ IS_OMAP_TYPE(3517, 0x3517)
 #define CHIP_IS_OMAP3430ES3_0		(1 << 5)
 #define CHIP_IS_OMAP3430ES3_1		(1 << 6)
 #define CHIP_IS_OMAP3630ES1		(1 << 7)
+#define CHIP_IS_OMAP4430ES1		(1 << 8)
 
 #define CHIP_IS_OMAP24XX		(CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
 
+#define CHIP_IS_OMAP4430		(CHIP_IS_OMAP4430ES1)
+
 /*
  * "GE" here represents "greater than or equal to" in terms of ES
  * levels.  So CHIP_GE_OMAP3430ES2 is intended to match all OMAP3430
@@ -501,6 +443,7 @@ extern u32 omap3_features;
 #define OMAP3_HAS_SGX			BIT(2)
 #define OMAP3_HAS_NEON			BIT(3)
 #define OMAP3_HAS_ISP			BIT(4)
+#define OMAP3_HAS_192MHZ_CLK		BIT(5)
 
 #define OMAP3_HAS_FEATURE(feat,flag)			\
 static inline unsigned int omap3_has_ ##feat(void)	\
@@ -513,5 +456,6 @@ OMAP3_HAS_FEATURE(sgx, SGX)
 OMAP3_HAS_FEATURE(iva, IVA)
 OMAP3_HAS_FEATURE(neon, NEON)
 OMAP3_HAS_FEATURE(isp, ISP)
+OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/display.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/display.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/display.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/display.h	2010-05-16 17:17:36.000000000 -0400
@@ -233,8 +233,12 @@ int omap_rfbi_setup_te(enum omap_rfbi_te
 void dsi_bus_lock(void);
 void dsi_bus_unlock(void);
 int dsi_vc_dcs_write(int channel, u8 *data, int len);
+int dsi_vc_dcs_write_0(int channel, u8 dcs_cmd);
+int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param);
 int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len);
 int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen);
+int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data);
+int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u16 *data);
 int dsi_vc_set_max_rx_packet_size(int channel, u16 len);
 int dsi_vc_send_null(int channel);
 int dsi_vc_send_bta_sync(int channel);
@@ -367,6 +371,10 @@ struct omap_overlay_manager {
 
 	int (*apply)(struct omap_overlay_manager *mgr);
 	int (*wait_for_go)(struct omap_overlay_manager *mgr);
+	int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
+
+	int (*enable)(struct omap_overlay_manager *mgr);
+	int (*disable)(struct omap_overlay_manager *mgr);
 };
 
 struct omap_dss_device {
@@ -426,16 +434,11 @@ struct omap_dss_device {
 		int acb;	/* ac-bias pin frequency */
 
 		enum omap_panel_config config;
-
-		u8 recommended_bpp;
-
-		struct omap_dss_device *ctrl;
 	} panel;
 
 	struct {
 		u8 pixel_size;
 		struct rfbi_timings rfbi_timings;
-		struct omap_dss_device *panel;
 	} ctrl;
 
 	int reset_gpio;
@@ -460,49 +463,6 @@ struct omap_dss_device {
 
 	enum omap_dss_display_state state;
 
-	int (*enable)(struct omap_dss_device *dssdev);
-	void (*disable)(struct omap_dss_device *dssdev);
-
-	int (*suspend)(struct omap_dss_device *dssdev);
-	int (*resume)(struct omap_dss_device *dssdev);
-
-	void (*get_resolution)(struct omap_dss_device *dssdev,
-			u16 *xres, u16 *yres);
-	int (*get_recommended_bpp)(struct omap_dss_device *dssdev);
-
-	int (*check_timings)(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings);
-	void (*set_timings)(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings);
-	void (*get_timings)(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings);
-	int (*update)(struct omap_dss_device *dssdev,
-			       u16 x, u16 y, u16 w, u16 h);
-	int (*sync)(struct omap_dss_device *dssdev);
-	int (*wait_vsync)(struct omap_dss_device *dssdev);
-
-	int (*set_update_mode)(struct omap_dss_device *dssdev,
-			enum omap_dss_update_mode);
-	enum omap_dss_update_mode (*get_update_mode)
-		(struct omap_dss_device *dssdev);
-
-	int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
-	int (*get_te)(struct omap_dss_device *dssdev);
-
-	u8 (*get_rotate)(struct omap_dss_device *dssdev);
-	int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
-
-	bool (*get_mirror)(struct omap_dss_device *dssdev);
-	int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
-
-	int (*run_test)(struct omap_dss_device *dssdev, int test);
-	int (*memory_read)(struct omap_dss_device *dssdev,
-			void *buf, size_t size,
-			u16 x, u16 y, u16 w, u16 h);
-
-	int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
-	u32 (*get_wss)(struct omap_dss_device *dssdev);
-
 	/* platform specific  */
 	int (*platform_enable)(struct omap_dss_device *dssdev);
 	void (*platform_disable)(struct omap_dss_device *dssdev);
@@ -522,11 +482,17 @@ struct omap_dss_driver {
 	int (*resume)(struct omap_dss_device *display);
 	int (*run_test)(struct omap_dss_device *display, int test);
 
-	void (*setup_update)(struct omap_dss_device *dssdev,
-			u16 x, u16 y, u16 w, u16 h);
+	int (*set_update_mode)(struct omap_dss_device *dssdev,
+			enum omap_dss_update_mode);
+	enum omap_dss_update_mode (*get_update_mode)(
+			struct omap_dss_device *dssdev);
+
+	int (*update)(struct omap_dss_device *dssdev,
+			       u16 x, u16 y, u16 w, u16 h);
+	int (*sync)(struct omap_dss_device *dssdev);
 
 	int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
-	int (*wait_for_te)(struct omap_dss_device *dssdev);
+	int (*get_te)(struct omap_dss_device *dssdev);
 
 	u8 (*get_rotate)(struct omap_dss_device *dssdev);
 	int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
@@ -537,6 +503,20 @@ struct omap_dss_driver {
 	int (*memory_read)(struct omap_dss_device *dssdev,
 			void *buf, size_t size,
 			u16 x, u16 y, u16 w, u16 h);
+
+	void (*get_resolution)(struct omap_dss_device *dssdev,
+			u16 *xres, u16 *yres);
+	int (*get_recommended_bpp)(struct omap_dss_device *dssdev);
+
+	int (*check_timings)(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings);
+	void (*set_timings)(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings);
+	void (*get_timings)(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings);
+
+	int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
+	u32 (*get_wss)(struct omap_dss_device *dssdev);
 };
 
 int omap_dss_register_driver(struct omap_dss_driver *);
@@ -561,6 +541,10 @@ struct omap_overlay_manager *omap_dss_ge
 int omap_dss_get_num_overlays(void);
 struct omap_overlay *omap_dss_get_overlay(int num);
 
+void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
+		u16 *xres, u16 *yres);
+int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
+
 typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
 int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
 int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
@@ -572,4 +556,35 @@ int omap_dispc_wait_for_irq_interruptibl
 #define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver)
 #define to_dss_device(x) container_of((x), struct omap_dss_device, dev)
 
+void omapdss_dsi_vc_enable_hs(int channel, bool enable);
+int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable);
+
+int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
+				    u16 *x, u16 *y, u16 *w, u16 *h);
+int omap_dsi_update(struct omap_dss_device *dssdev,
+		int channel,
+		u16 x, u16 y, u16 w, u16 h,
+		void (*callback)(int, void *), void *data);
+
+int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
+void omapdss_dsi_display_disable(struct omap_dss_device *dssdev);
+
+int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
+void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
+void dpi_set_timings(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings);
+int dpi_check_timings(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings);
+
+int omapdss_sdi_display_enable(struct omap_dss_device *dssdev);
+void omapdss_sdi_display_disable(struct omap_dss_device *dssdev);
+
+int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev);
+void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev);
+int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
+		u16 *x, u16 *y, u16 *w, u16 *h);
+int omap_rfbi_update(struct omap_dss_device *dssdev,
+		u16 x, u16 y, u16 w, u16 h,
+		void (*callback)(void *), void *data);
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/dma-44xx.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/dma-44xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/dma-44xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/dma-44xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,147 @@
+/*
+ * OMAP4 SDMA channel definitions
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Santosh Shilimkar (santosh.shilimkar@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ * Paul Walmsley (paul@pwsan.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_OMAP44XX_DMA_H
+#define __ARCH_ARM_MACH_OMAP2_OMAP44XX_DMA_H
+
+#define OMAP44XX_DMA_SYS_REQ0			2
+#define OMAP44XX_DMA_SYS_REQ1			3
+#define OMAP44XX_DMA_GPMC			4
+#define OMAP44XX_DMA_DSS_DISPC_REQ		6
+#define OMAP44XX_DMA_SYS_REQ2			7
+#define OMAP44XX_DMA_MCASP1_AXEVT		8
+#define OMAP44XX_DMA_ISS_REQ1			9
+#define OMAP44XX_DMA_ISS_REQ2			10
+#define OMAP44XX_DMA_MCASP1_AREVT		11
+#define OMAP44XX_DMA_ISS_REQ3			12
+#define OMAP44XX_DMA_ISS_REQ4			13
+#define OMAP44XX_DMA_DSS_RFBI_REQ		14
+#define OMAP44XX_DMA_SPI3_TX0			15
+#define OMAP44XX_DMA_SPI3_RX0			16
+#define OMAP44XX_DMA_MCBSP2_TX			17
+#define OMAP44XX_DMA_MCBSP2_RX			18
+#define OMAP44XX_DMA_MCBSP3_TX			19
+#define OMAP44XX_DMA_MCBSP3_RX			20
+#define OMAP44XX_DMA_C2C_SSCM_GPO0		21
+#define OMAP44XX_DMA_C2C_SSCM_GPO1		22
+#define OMAP44XX_DMA_SPI3_TX1			23
+#define OMAP44XX_DMA_SPI3_RX1			24
+#define OMAP44XX_DMA_I2C3_TX			25
+#define OMAP44XX_DMA_I2C3_RX			26
+#define OMAP44XX_DMA_I2C1_TX			27
+#define OMAP44XX_DMA_I2C1_RX			28
+#define OMAP44XX_DMA_I2C2_TX			29
+#define OMAP44XX_DMA_I2C2_RX			30
+#define OMAP44XX_DMA_MCBSP4_TX			31
+#define OMAP44XX_DMA_MCBSP4_RX			32
+#define OMAP44XX_DMA_MCBSP1_TX			33
+#define OMAP44XX_DMA_MCBSP1_RX			34
+#define OMAP44XX_DMA_SPI1_TX0			35
+#define OMAP44XX_DMA_SPI1_RX0			36
+#define OMAP44XX_DMA_SPI1_TX1			37
+#define OMAP44XX_DMA_SPI1_RX1			38
+#define OMAP44XX_DMA_SPI1_TX2			39
+#define OMAP44XX_DMA_SPI1_RX2			40
+#define OMAP44XX_DMA_SPI1_TX3			41
+#define OMAP44XX_DMA_SPI1_RX3			42
+#define OMAP44XX_DMA_SPI2_TX0			43
+#define OMAP44XX_DMA_SPI2_RX0			44
+#define OMAP44XX_DMA_SPI2_TX1			45
+#define OMAP44XX_DMA_SPI2_RX1			46
+#define OMAP44XX_DMA_MMC2_TX			47
+#define OMAP44XX_DMA_MMC2_RX			48
+#define OMAP44XX_DMA_UART1_TX			49
+#define OMAP44XX_DMA_UART1_RX			50
+#define OMAP44XX_DMA_UART2_TX			51
+#define OMAP44XX_DMA_UART2_RX			52
+#define OMAP44XX_DMA_UART3_TX			53
+#define OMAP44XX_DMA_UART3_RX			54
+#define OMAP44XX_DMA_UART4_TX			55
+#define OMAP44XX_DMA_UART4_RX			56
+#define OMAP44XX_DMA_MMC4_TX			57
+#define OMAP44XX_DMA_MMC4_RX			58
+#define OMAP44XX_DMA_MMC5_TX			59
+#define OMAP44XX_DMA_MMC5_RX			60
+#define OMAP44XX_DMA_MMC1_TX			61
+#define OMAP44XX_DMA_MMC1_RX			62
+#define OMAP44XX_DMA_SYS_REQ3			64
+#define OMAP44XX_DMA_MCPDM_UP			65
+#define OMAP44XX_DMA_MCPDM_DL			66
+#define OMAP44XX_DMA_DMIC_REQ			67
+#define OMAP44XX_DMA_C2C_SSCM_GPO2		68
+#define OMAP44XX_DMA_C2C_SSCM_GPO3		69
+#define OMAP44XX_DMA_SPI4_TX0			70
+#define OMAP44XX_DMA_SPI4_RX0			71
+#define OMAP44XX_DMA_DSS_DSI1_REQ0		72
+#define OMAP44XX_DMA_DSS_DSI1_REQ1		73
+#define OMAP44XX_DMA_DSS_DSI1_REQ2		74
+#define OMAP44XX_DMA_DSS_DSI1_REQ3		75
+#define OMAP44XX_DMA_DSS_HDMI_REQ		76
+#define OMAP44XX_DMA_MMC3_TX			77
+#define OMAP44XX_DMA_MMC3_RX			78
+#define OMAP44XX_DMA_USIM_TX			79
+#define OMAP44XX_DMA_USIM_RX			80
+#define OMAP44XX_DMA_DSS_DSI2_REQ0		81
+#define OMAP44XX_DMA_DSS_DSI2_REQ1		82
+#define OMAP44XX_DMA_DSS_DSI2_REQ2		83
+#define OMAP44XX_DMA_DSS_DSI2_REQ3		84
+#define OMAP44XX_DMA_SLIMBUS1_TX0		85
+#define OMAP44XX_DMA_SLIMBUS1_TX1		86
+#define OMAP44XX_DMA_SLIMBUS1_TX2		87
+#define OMAP44XX_DMA_SLIMBUS1_TX3		88
+#define OMAP44XX_DMA_SLIMBUS1_RX0		89
+#define OMAP44XX_DMA_SLIMBUS1_RX1		90
+#define OMAP44XX_DMA_SLIMBUS1_RX2		91
+#define OMAP44XX_DMA_SLIMBUS1_RX3		92
+#define OMAP44XX_DMA_SLIMBUS2_TX0		93
+#define OMAP44XX_DMA_SLIMBUS2_TX1		94
+#define OMAP44XX_DMA_SLIMBUS2_TX2		95
+#define OMAP44XX_DMA_SLIMBUS2_TX3		96
+#define OMAP44XX_DMA_SLIMBUS2_RX0		97
+#define OMAP44XX_DMA_SLIMBUS2_RX1		98
+#define OMAP44XX_DMA_SLIMBUS2_RX2		99
+#define OMAP44XX_DMA_SLIMBUS2_RX3		100
+#define OMAP44XX_DMA_ABE_REQ_0			101
+#define OMAP44XX_DMA_ABE_REQ_1			102
+#define OMAP44XX_DMA_ABE_REQ_2			103
+#define OMAP44XX_DMA_ABE_REQ_3			104
+#define OMAP44XX_DMA_ABE_REQ_4			105
+#define OMAP44XX_DMA_ABE_REQ_5			106
+#define OMAP44XX_DMA_ABE_REQ_6			107
+#define OMAP44XX_DMA_ABE_REQ_7			108
+#define OMAP44XX_DMA_AES1_P_CTX_IN_REQ		109
+#define OMAP44XX_DMA_AES1_P_DATA_IN_REQ		110
+#define OMAP44XX_DMA_AES1_P_DATA_OUT_REQ	111
+#define OMAP44XX_DMA_AES2_P_CTX_IN_REQ		112
+#define OMAP44XX_DMA_AES2_P_DATA_IN_REQ		113
+#define OMAP44XX_DMA_AES2_P_DATA_OUT_REQ	114
+#define OMAP44XX_DMA_DES_P_CTX_IN_REQ		115
+#define OMAP44XX_DMA_DES_P_DATA_IN_REQ		116
+#define OMAP44XX_DMA_DES_P_DATA_OUT_REQ		117
+#define OMAP44XX_DMA_SHA2_CTXIN_P		118
+#define OMAP44XX_DMA_SHA2_DIN_P			119
+#define OMAP44XX_DMA_SHA2_CTXOUT_P		120
+#define OMAP44XX_DMA_AES1_P_CONTEXT_OUT_REQ	121
+#define OMAP44XX_DMA_AES2_P_CONTEXT_OUT_REQ	122
+#define OMAP44XX_DMA_I2C4_TX			124
+#define OMAP44XX_DMA_I2C4_RX			125
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/dma.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/dma.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/dma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/dma.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,9 @@
 #ifndef __ASM_ARCH_DMA_H
 #define __ASM_ARCH_DMA_H
 
+/* Move omap4 specific defines to dma-44xx.h */
+#include "dma-44xx.h"
+
 /* Hardware registers for omap1 */
 #define OMAP1_DMA_BASE			(0xfffed800)
 
@@ -316,89 +319,6 @@
 #define OMAP34XX_DMA_USIM_TX		79	/* S_DMA_78 */
 #define OMAP34XX_DMA_USIM_RX		80	/* S_DMA_79 */
 
-/* DMA request lines for 44xx */
-#define OMAP44XX_DMA_DSS_DISPC_REQ	6	/* S_DMA_5 */
-#define OMAP44XX_DMA_SYS_REQ2		7	/* S_DMA_6 */
-#define OMAP44XX_DMA_ISS_REQ1		9	/* S_DMA_8 */
-#define OMAP44XX_DMA_ISS_REQ2		10	/* S_DMA_9 */
-#define OMAP44XX_DMA_ISS_REQ3		12	/* S_DMA_11 */
-#define OMAP44XX_DMA_ISS_REQ4		13	/* S_DMA_12 */
-#define OMAP44XX_DMA_DSS_RFBI_REQ	14	/* S_DMA_13 */
-#define OMAP44XX_DMA_SPI3_TX0		15	/* S_DMA_14 */
-#define OMAP44XX_DMA_SPI3_RX0		16	/* S_DMA_15 */
-#define OMAP44XX_DMA_MCBSP2_TX		17	/* S_DMA_16 */
-#define OMAP44XX_DMA_MCBSP2_RX		18	/* S_DMA_17 */
-#define OMAP44XX_DMA_MCBSP3_TX		19	/* S_DMA_18 */
-#define OMAP44XX_DMA_MCBSP3_RX		20	/* S_DMA_19 */
-#define OMAP44XX_DMA_SPI3_TX1		23	/* S_DMA_22 */
-#define OMAP44XX_DMA_SPI3_RX1		24	/* S_DMA_23 */
-#define OMAP44XX_DMA_I2C3_TX		25	/* S_DMA_24 */
-#define OMAP44XX_DMA_I2C3_RX		26	/* S_DMA_25 */
-#define OMAP44XX_DMA_I2C1_TX		27	/* S_DMA_26 */
-#define OMAP44XX_DMA_I2C1_RX		28	/* S_DMA_27 */
-#define OMAP44XX_DMA_I2C2_TX		29	/* S_DMA_28 */
-#define OMAP44XX_DMA_I2C2_RX		30	/* S_DMA_29 */
-#define OMAP44XX_DMA_MCBSP4_TX		31	/* S_DMA_30 */
-#define OMAP44XX_DMA_MCBSP4_RX		32	/* S_DMA_31 */
-#define OMAP44XX_DMA_MCBSP1_TX		33	/* S_DMA_32 */
-#define OMAP44XX_DMA_MCBSP1_RX		34	/* S_DMA_33 */
-#define OMAP44XX_DMA_SPI1_TX0		35	/* S_DMA_34 */
-#define OMAP44XX_DMA_SPI1_RX0		36	/* S_DMA_35 */
-#define OMAP44XX_DMA_SPI1_TX1		37	/* S_DMA_36 */
-#define OMAP44XX_DMA_SPI1_RX1		38	/* S_DMA_37 */
-#define OMAP44XX_DMA_SPI1_TX2		39	/* S_DMA_38 */
-#define OMAP44XX_DMA_SPI1_RX2		40	/* S_DMA_39 */
-#define OMAP44XX_DMA_SPI1_TX3		41	/* S_DMA_40 */
-#define OMAP44XX_DMA_SPI1_RX3		42	/* S_DMA_41 */
-#define OMAP44XX_DMA_SPI2_TX0		43	/* S_DMA_42 */
-#define OMAP44XX_DMA_SPI2_RX0		44	/* S_DMA_43 */
-#define OMAP44XX_DMA_SPI2_TX1		45	/* S_DMA_44 */
-#define OMAP44XX_DMA_SPI2_RX1		46	/* S_DMA_45 */
-#define OMAP44XX_DMA_MMC2_TX		47	/* S_DMA_46 */
-#define OMAP44XX_DMA_MMC2_RX		48	/* S_DMA_47 */
-#define OMAP44XX_DMA_UART1_TX		49	/* S_DMA_48 */
-#define OMAP44XX_DMA_UART1_RX		50	/* S_DMA_49 */
-#define OMAP44XX_DMA_UART2_TX		51	/* S_DMA_50 */
-#define OMAP44XX_DMA_UART2_RX		52	/* S_DMA_51 */
-#define OMAP44XX_DMA_UART3_TX		53	/* S_DMA_52 */
-#define OMAP44XX_DMA_UART3_RX		54	/* S_DMA_53 */
-#define OMAP44XX_DMA_UART4_TX		55	/* S_DMA_54 */
-#define OMAP44XX_DMA_UART4_RX		56	/* S_DMA_55 */
-#define OMAP44XX_DMA_MMC4_TX		57	/* S_DMA_56 */
-#define OMAP44XX_DMA_MMC4_RX		58	/* S_DMA_57 */
-#define OMAP44XX_DMA_MMC5_TX		59	/* S_DMA_58 */
-#define OMAP44XX_DMA_MMC5_RX		60	/* S_DMA_59 */
-#define OMAP44XX_DMA_MMC1_TX		61	/* S_DMA_60 */
-#define OMAP44XX_DMA_MMC1_RX		62	/* S_DMA_61 */
-#define OMAP44XX_DMA_SYS_REQ3		64	/* S_DMA_63 */
-#define OMAP44XX_DMA_MCPDM_UP		65	/* S_DMA_64 */
-#define OMAP44XX_DMA_MCPDM_DL		66	/* S_DMA_65 */
-#define OMAP44XX_DMA_SPI4_TX0		70	/* S_DMA_69 */
-#define OMAP44XX_DMA_SPI4_RX0		71	/* S_DMA_70 */
-#define OMAP44XX_DMA_DSS_DSI1_REQ0	72	/* S_DMA_71 */
-#define OMAP44XX_DMA_DSS_DSI1_REQ1	73	/* S_DMA_72 */
-#define OMAP44XX_DMA_DSS_DSI1_REQ2	74	/* S_DMA_73 */
-#define OMAP44XX_DMA_DSS_DSI1_REQ3	75	/* S_DMA_74 */
-#define OMAP44XX_DMA_DSS_HDMI_REQ	76	/* S_DMA_75 */
-#define OMAP44XX_DMA_MMC3_TX		77	/* S_DMA_76 */
-#define OMAP44XX_DMA_MMC3_RX		78	/* S_DMA_77 */
-#define OMAP44XX_DMA_USIM_TX		79	/* S_DMA_78 */
-#define OMAP44XX_DMA_USIM_RX		80	/* S_DMA_79 */
-#define OMAP44XX_DMA_DSS_DSI2_REQ0	81	/* S_DMA_80 */
-#define OMAP44XX_DMA_DSS_DSI2_REQ1	82	/* S_DMA_81 */
-#define OMAP44XX_DMA_DSS_DSI2_REQ2	83	/* S_DMA_82 */
-#define OMAP44XX_DMA_DSS_DSI2_REQ3	84	/* S_DMA_83 */
-#define OMAP44XX_DMA_ABE_REQ0		101	/* S_DMA_100 */
-#define OMAP44XX_DMA_ABE_REQ1		102	/* S_DMA_101 */
-#define OMAP44XX_DMA_ABE_REQ2		103	/* S_DMA_102 */
-#define OMAP44XX_DMA_ABE_REQ3		104	/* S_DMA_103 */
-#define OMAP44XX_DMA_ABE_REQ4		105	/* S_DMA_104 */
-#define OMAP44XX_DMA_ABE_REQ5		106	/* S_DMA_105 */
-#define OMAP44XX_DMA_ABE_REQ6		107	/* S_DMA_106 */
-#define OMAP44XX_DMA_ABE_REQ7		108	/* S_DMA_107 */
-#define OMAP44XX_DMA_I2C4_TX		124	/* S_DMA_123 */
-#define OMAP44XX_DMA_I2C4_RX		125	/* S_DMA_124 */
-
 /*----------------------------------------------------------------------------*/
 
 #define OMAP1_DMA_TOUT_IRQ		(1 << 0)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/flash.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/flash.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/flash.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/flash.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,16 @@
+/*
+ * Flash support for OMAP1
+ *
+ * This program is free software; you can 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_FLASH_H
+#define __OMAP_FLASH_H
+
+#include <linux/mtd/map.h>
+
+extern void omap1_set_vpp(struct map_info *map, int enable);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/gpmc.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/gpmc.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/gpmc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/gpmc.h	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,8 @@
 
 #define GPMC_CONFIG		0x50
 #define GPMC_STATUS		0x54
+#define GPMC_CS0_BASE		0x60
+#define GPMC_CS_SIZE		0x30
 
 #define GPMC_CONFIG1_WRAPBURST_SUPP     (1 << 31)
 #define GPMC_CONFIG1_READMULTIPLE_SUPP  (1 << 30)
@@ -110,6 +112,6 @@ extern void gpmc_prefetch_reset(void);
 extern int gpmc_prefetch_status(void);
 extern void omap3_gpmc_save_context(void);
 extern void omap3_gpmc_restore_context(void);
-extern void __init gpmc_init(void);
+extern void gpmc_init(void);
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/i2c.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/i2c.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/i2c.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/i2c.h	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,5 @@ static inline int omap_register_i2c_bus(
 }
 #endif
 
-int omap_plat_register_i2c_bus(int bus_id, u32 clkrate,
-				 struct i2c_board_info const *info,
-				 unsigned len);
+void __init omap1_i2c_mux_pins(int bus_id);
+void __init omap2_i2c_mux_pins(int bus_id);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/io.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/io.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/io.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/io.h	2010-05-16 17:17:36.000000000 -0400
@@ -158,10 +158,6 @@
  * VPOM3430 was not working for Int controller
  */
 
-#define L4_WK_34XX_PHYS		L4_WK_34XX_BASE	/* 0x48300000 --> 0xfa300000 */
-#define L4_WK_34XX_VIRT		(L4_WK_34XX_PHYS + OMAP2_L4_IO_OFFSET)
-#define L4_WK_34XX_SIZE		SZ_1M
-
 #define L4_PER_34XX_PHYS	L4_PER_34XX_BASE
 						/* 0x49000000 --> 0xfb000000 */
 #define L4_PER_34XX_VIRT	(L4_PER_34XX_PHYS + OMAP2_L4_IO_OFFSET)
@@ -204,11 +200,6 @@
 #define L4_44XX_VIRT		(L4_44XX_PHYS + OMAP2_L4_IO_OFFSET)
 #define L4_44XX_SIZE		SZ_4M
 
-
-#define L4_WK_44XX_PHYS		L4_WK_44XX_BASE	/* 0x4a300000 --> 0xfc300000 */
-#define L4_WK_44XX_VIRT		(L4_WK_44XX_PHYS + OMAP2_L4_IO_OFFSET)
-#define L4_WK_44XX_SIZE		SZ_1M
-
 #define L4_PER_44XX_PHYS	L4_PER_44XX_BASE
 						/* 0x48000000 --> 0xfa000000 */
 #define L4_PER_44XX_VIRT	(L4_PER_44XX_PHYS + OMAP2_L4_IO_OFFSET)
@@ -268,7 +259,38 @@ 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);
+#ifdef CONFIG_ARCH_OMAP2420
+extern void omap242x_map_common_io(void);
+#else
+static inline void omap242x_map_common_io(void)
+{
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2430
+extern void omap243x_map_common_io(void);
+#else
+static inline void omap243x_map_common_io(void)
+{
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+extern void omap34xx_map_common_io(void);
+#else
+static inline void omap34xx_map_common_io(void)
+{
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+extern void omap44xx_map_common_io(void);
+#else
+static inline void omap44xx_map_common_io(void)
+{
+}
+#endif
+
 extern void omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
 				 struct omap_sdrc_params *sdrc_cs1);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/irqs-44xx.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/irqs-44xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/irqs-44xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/irqs-44xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,144 @@
+/*
+ * OMAP4 Interrupt lines definitions
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * Santosh Shilimkar (santosh.shilimkar@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_OMAP44XX_IRQS_H
+#define __ARCH_ARM_MACH_OMAP2_OMAP44XX_IRQS_H
+
+/* OMAP44XX IRQs numbers definitions */
+#define OMAP44XX_IRQ_LOCALTIMER			29
+#define OMAP44XX_IRQ_LOCALWDT			30
+
+#define OMAP44XX_IRQ_GIC_START			32
+
+#define OMAP44XX_IRQ_PL310			(0 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_CTI0			(1 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_CTI1			(2 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_ELM			(4 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SYS_1N			(7 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SECURITY_EVENTS		(8 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_L3_DBG			(9 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_L3_APP			(10 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_PRCM			(11 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SDMA_0			(12 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SDMA_1			(13 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SDMA_2			(14 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SDMA_3			(15 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MCBSP4			(16 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MCBSP1			(17 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SR_MCU			(18 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SR_CORE			(19 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPMC			(20 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GFX			(21 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MCBSP2			(22 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MCBSP3			(23 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_ISS_5			(24 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DSS_DISPC			(25 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MAIL_U0			(26 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_C2C_SSCM_0			(27 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_TESLA_MMU			(28 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPIO1			(29 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPIO2			(30 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPIO3			(31 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPIO4			(32 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPIO5			(33 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPIO6			(34 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_USIM			(35 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_WDT3			(36 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT1			(37 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT2			(38 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT3			(39 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT4			(40 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT5			(41 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT6			(42 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT7			(43 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT8			(44 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT9			(45 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT10			(46 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT11			(47 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SPI4			(48 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SHA1_S			(49 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_FPKA_SINTREQUEST_S		(50 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SHA1_P			(51 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_RNG			(52 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DSS_DSI1			(53 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_I2C1			(56 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_I2C2			(57 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_HDQ			(58 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MMC5			(59 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_I2C3			(61 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_I2C4			(62 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_AES2_S			(63 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_AES2_P			(64 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SPI1			(65 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SPI2			(66 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_HSI_P1			(67 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_HSI_P2			(68 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_FDIF_3			(69 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_UART4			(70 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_HSI_DMA			(71 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_UART1			(72 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_UART2			(73 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_UART3			(74 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_PBIAS			(75 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_OHCI			(76 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_EHCI			(77 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_TLL			(78 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_AES1_S			(79 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_WDT2			(80 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DES_S			(81 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DES_P			(82 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MMC1			(83 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DSS_DSI2			(84 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_AES1_P			(85 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MMC2			(86 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MPU_ICR			(87 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_C2C_SSCM_1			(88 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_FSUSB			(89 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_FSUSB_SMI			(90 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SPI3			(91 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_HS_USB_MC_N		(92 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_HS_USB_DMA_N		(93 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MMC3			(94 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT12			(95 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MMC4			(96 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SLIMBUS1			(97 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SLIMBUS2			(98 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_ABE			(99 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DUCATI_MMU			(100 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DSS_HDMI			(101 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SR_IVA			(102 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_IVA_HD_POSYNCITRPEND_1	(103 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_IVA_HD_POSYNCITRPEND_0	(104 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_IVA_HD_POMBINTRPEND_0	(107 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MCASP1_AR			(108 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MCASP1_AX			(109 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_EMIF4_1			(110 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_EMIF4_2			(111 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MCPDM			(112 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DMM			(113 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DMIC			(114 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_CDMA_0			(115 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_CDMA_1			(116 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_CDMA_2			(117 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_CDMA_3			(118 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SYS_2N			(119 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_KBD_CTL			(120 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_UNIPRO1			(124 + OMAP44XX_IRQ_GIC_START)
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/irqs.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/irqs.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/irqs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/irqs.h	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,9 @@
 #ifndef __ASM_ARCH_OMAP15XX_IRQS_H
 #define __ASM_ARCH_OMAP15XX_IRQS_H
 
+/* All OMAP4 specific defines are moved to irqs-44xx.h */
+#include "irqs-44xx.h"
+
 /*
  * IRQ numbers for interrupt handler 1
  *
@@ -342,97 +345,16 @@
 #define INT_34XX_MMC3_IRQ	94
 #define INT_34XX_GPT12_IRQ	95
 
-#define	INT_34XX_BENCH_MPU_EMUL	3
-
-
-#define IRQ_GIC_START		32
-#define INT_44XX_LOCALTIMER_IRQ	29
-#define INT_44XX_LOCALWDT_IRQ	30
-
-#define INT_44XX_BENCH_MPU_EMUL	(3 + IRQ_GIC_START)
-#define INT_44XX_SSM_ABORT_IRQ	(6 + IRQ_GIC_START)
-#define INT_44XX_SYS_NIRQ	(7 + IRQ_GIC_START)
-#define INT_44XX_D2D_FW_IRQ	(8 + IRQ_GIC_START)
-#define INT_44XX_PRCM_MPU_IRQ	(11 + IRQ_GIC_START)
-#define INT_44XX_SDMA_IRQ0	(12 + IRQ_GIC_START)
-#define INT_44XX_SDMA_IRQ1	(13 + IRQ_GIC_START)
-#define INT_44XX_SDMA_IRQ2	(14 + IRQ_GIC_START)
-#define INT_44XX_SDMA_IRQ3	(15 + IRQ_GIC_START)
-#define INT_44XX_ISS_IRQ	(24 + IRQ_GIC_START)
-#define INT_44XX_DSS_IRQ	(25 + IRQ_GIC_START)
-#define INT_44XX_MAIL_U0_MPU	(26 + IRQ_GIC_START)
-#define INT_44XX_DSP_MMU	(28 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER1	(37 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER2	(38 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER3	(39 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER4	(40 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER5	(41 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER6	(42 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER7	(43 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER8	(44 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER9	(45 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER10	(46 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER11	(47 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER12	(95 + IRQ_GIC_START)
-#define INT_44XX_SHA1MD5	(51 + IRQ_GIC_START)
-#define INT_44XX_I2C1_IRQ	(56 + IRQ_GIC_START)
-#define INT_44XX_I2C2_IRQ	(57 + IRQ_GIC_START)
-#define INT_44XX_HDQ_IRQ	(58 + IRQ_GIC_START)
-#define INT_44XX_SPI1_IRQ	(65 + IRQ_GIC_START)
-#define INT_44XX_SPI2_IRQ	(66 + IRQ_GIC_START)
-#define INT_44XX_HSI_1_IRQ0	(67 + IRQ_GIC_START)
-#define INT_44XX_HSI_2_IRQ1	(68 + IRQ_GIC_START)
-#define INT_44XX_HSI_1_DMAIRQ	(71 + IRQ_GIC_START)
-#define INT_44XX_UART1_IRQ	(72 + IRQ_GIC_START)
-#define INT_44XX_UART2_IRQ	(73 + IRQ_GIC_START)
-#define INT_44XX_UART3_IRQ	(74 + IRQ_GIC_START)
-#define INT_44XX_UART4_IRQ	(70 + IRQ_GIC_START)
-#define INT_44XX_USB_IRQ_NISO	(76 + IRQ_GIC_START)
-#define INT_44XX_USB_IRQ_ISO	(77 + IRQ_GIC_START)
-#define INT_44XX_USB_IRQ_HGEN	(78 + IRQ_GIC_START)
-#define INT_44XX_USB_IRQ_HSOF	(79 + IRQ_GIC_START)
-#define INT_44XX_USB_IRQ_OTG	(80 + IRQ_GIC_START)
-#define INT_44XX_MCBSP4_IRQ_TX	(81 + IRQ_GIC_START)
-#define INT_44XX_MCBSP4_IRQ_RX	(82 + IRQ_GIC_START)
-#define INT_44XX_MMC_IRQ	(83 + IRQ_GIC_START)
-#define INT_44XX_MMC2_IRQ	(86 + IRQ_GIC_START)
-#define INT_44XX_MCBSP2_IRQ_TX	(89 + IRQ_GIC_START)
-#define INT_44XX_MCBSP2_IRQ_RX	(90 + IRQ_GIC_START)
-#define INT_44XX_SPI3_IRQ	(91 + IRQ_GIC_START)
-#define INT_44XX_SPI5_IRQ	(69 + IRQ_GIC_START)
-
-#define INT_44XX_MCBSP5_IRQ	(16 + IRQ_GIC_START)
-#define INT_44xX_MCBSP1_IRQ	(17 + IRQ_GIC_START)
-#define INT_44XX_MCBSP2_IRQ	(22 + IRQ_GIC_START)
-#define INT_44XX_MCBSP3_IRQ	(23 + IRQ_GIC_START)
-#define INT_44XX_MCBSP4_IRQ	(27 + IRQ_GIC_START)
-#define INT_44XX_HS_USB_MC	(92 + IRQ_GIC_START)
-#define INT_44XX_HS_USB_DMA	(93 + IRQ_GIC_START)
-
-#define INT_44XX_GPIO_BANK1	(29 + IRQ_GIC_START)
-#define INT_44XX_GPIO_BANK2	(30 + IRQ_GIC_START)
-#define INT_44XX_GPIO_BANK3	(31 + IRQ_GIC_START)
-#define INT_44XX_GPIO_BANK4	(32 + IRQ_GIC_START)
-#define INT_44XX_GPIO_BANK5	(33 + IRQ_GIC_START)
-#define INT_44XX_GPIO_BANK6	(34 + IRQ_GIC_START)
-#define INT_44XX_USIM_IRQ	(35 + IRQ_GIC_START)
-#define INT_44XX_WDT3_IRQ	(36 + IRQ_GIC_START)
-#define INT_44XX_SPI4_IRQ	(48 + IRQ_GIC_START)
-#define INT_44XX_SHA1MD52_IRQ	(49 + IRQ_GIC_START)
-#define INT_44XX_FPKA_READY_IRQ	(50 + IRQ_GIC_START)
-#define INT_44XX_SHA1MD51_IRQ	(51 + IRQ_GIC_START)
-#define INT_44XX_RNG_IRQ	(52 + IRQ_GIC_START)
-#define INT_44XX_MMC5_IRQ	(59 + IRQ_GIC_START)
-#define INT_44XX_I2C3_IRQ	(61 + IRQ_GIC_START)
-#define INT_44XX_FPKA_ERROR_IRQ	(64 + IRQ_GIC_START)
-#define INT_44XX_PBIAS_IRQ	(75 + IRQ_GIC_START)
-#define INT_44XX_OHCI_IRQ	(76 + IRQ_GIC_START)
-#define INT_44XX_EHCI_IRQ	(77 + IRQ_GIC_START)
-#define INT_44XX_TLL_IRQ	(78 + IRQ_GIC_START)
-#define INT_44XX_PARTHASH_IRQ	(79 + IRQ_GIC_START)
-#define INT_44XX_MMC3_IRQ	(94 + IRQ_GIC_START)
-#define INT_44XX_MMC4_IRQ	(96 + IRQ_GIC_START)
-
+#define INT_35XX_HECC0_IRQ		24
+#define INT_35XX_HECC1_IRQ		28
+#define INT_35XX_EMAC_C0_RXTHRESH_IRQ	67
+#define INT_35XX_EMAC_C0_RX_PULSE_IRQ	68
+#define INT_35XX_EMAC_C0_TX_PULSE_IRQ	69
+#define INT_35XX_EMAC_C0_MISC_PULSE_IRQ	70
+#define INT_35XX_USBOTG_IRQ		71
+#define INT_35XX_CCDC_VD0_IRQ		88
+#define INT_35XX_CCDC_VD1_IRQ		92
+#define INT_35XX_CCDC_VD2_IRQ		93
 
 /* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730/850) and
  * 16 MPUIO lines */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mcbsp.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/mcbsp.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mcbsp.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/mcbsp.h	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,9 @@
 
 #define OMAP34XX_MCBSP1_BASE	0x48074000
 #define OMAP34XX_MCBSP2_BASE	0x49022000
+#define OMAP34XX_MCBSP2_ST_BASE	0x49028000
+#define OMAP34XX_MCBSP3_BASE	0x49024000
+#define OMAP34XX_MCBSP3_ST_BASE	0x4902A000
 #define OMAP34XX_MCBSP3_BASE	0x49024000
 #define OMAP34XX_MCBSP4_BASE	0x49026000
 #define OMAP34XX_MCBSP5_BASE	0x48096000
@@ -56,7 +59,7 @@
 #define OMAP44XX_MCBSP1_BASE	0x49022000
 #define OMAP44XX_MCBSP2_BASE	0x49024000
 #define OMAP44XX_MCBSP3_BASE	0x49026000
-#define OMAP44XX_MCBSP4_BASE	0x48074000
+#define OMAP44XX_MCBSP4_BASE	0x48096000
 
 #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
 
@@ -103,8 +106,7 @@
 #define AUDIO_DMA_TX		OMAP_DMA_MCBSP1_TX
 #define AUDIO_DMA_RX		OMAP_DMA_MCBSP1_RX
 
-#elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-	defined(CONFIG_ARCH_OMAP4)
+#else
 
 #define OMAP_MCBSP_REG_DRR2	0x00
 #define OMAP_MCBSP_REG_DRR1	0x04
@@ -147,6 +149,15 @@
 #define OMAP_MCBSP_REG_WAKEUPEN	0xA8
 #define OMAP_MCBSP_REG_XCCR	0xAC
 #define OMAP_MCBSP_REG_RCCR	0xB0
+#define OMAP_MCBSP_REG_SSELCR	0xBC
+
+#define OMAP_ST_REG_REV		0x00
+#define OMAP_ST_REG_SYSCONFIG	0x10
+#define OMAP_ST_REG_IRQSTATUS	0x18
+#define OMAP_ST_REG_IRQENABLE	0x1C
+#define OMAP_ST_REG_SGAINCR	0x24
+#define OMAP_ST_REG_SFIRCR	0x28
+#define OMAP_ST_REG_SSELCR	0x2C
 
 #define AUDIO_MCBSP_DATAWRITE	(OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1)
 #define AUDIO_MCBSP_DATAREAD	(OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1)
@@ -265,6 +276,24 @@
 #define ENAWAKEUP		0x0004
 #define SOFTRST			0x0002
 
+/********************** McBSP SSELCR bit definitions ***********************/
+#define SIDETONEEN		0x0400
+
+/********************** McBSP Sidetone SYSCONFIG bit definitions ***********/
+#define ST_AUTOIDLE		0x0001
+
+/********************** McBSP Sidetone SGAINCR bit definitions *************/
+#define ST_CH1GAIN(value)	((value<<16))	/* Bits 16:31 */
+#define ST_CH0GAIN(value)	(value)		/* Bits 0:15 */
+
+/********************** McBSP Sidetone SFIRCR bit definitions **************/
+#define ST_FIRCOEFF(value)	(value)		/* Bits 0:15 */
+
+/********************** McBSP Sidetone SSELCR bit definitions **************/
+#define ST_COEFFWRDONE		0x0004
+#define ST_COEFFWREN		0x0002
+#define ST_SIDETONEEN		0x0001
+
 /********************** McBSP DMA operating modes **************************/
 #define MCBSP_DMA_MODE_ELEMENT		0
 #define MCBSP_DMA_MODE_THRESHOLD	1
@@ -374,11 +403,23 @@ struct omap_mcbsp_platform_data {
 	u8 dma_rx_sync, dma_tx_sync;
 	u16 rx_irq, tx_irq;
 	struct omap_mcbsp_ops *ops;
-#ifdef CONFIG_ARCH_OMAP34XX
+#ifdef CONFIG_ARCH_OMAP3
+	/* Sidetone block for McBSP 2 and 3 */
+	unsigned long phys_base_st;
 	u16 buffer_size;
 #endif
 };
 
+struct omap_mcbsp_st_data {
+	void __iomem *io_base_st;
+	bool running;
+	bool enabled;
+	s16 taps[128];	/* Sidetone filter coefficients */
+	int nr_taps;	/* Number of filter coefficients in use */
+	s16 ch0gain;
+	s16 ch1gain;
+};
+
 struct omap_mcbsp {
 	struct device *dev;
 	unsigned long phys_base;
@@ -410,20 +451,22 @@ struct omap_mcbsp {
 	struct omap_mcbsp_platform_data *pdata;
 	struct clk *iclk;
 	struct clk *fclk;
-#ifdef CONFIG_ARCH_OMAP34XX
+#ifdef CONFIG_ARCH_OMAP3
+	struct omap_mcbsp_st_data *st_data;
 	int dma_op_mode;
 	u16 max_tx_thres;
 	u16 max_rx_thres;
 #endif
+	void *reg_cache;
 };
 extern struct omap_mcbsp **mcbsp_ptr;
-extern int omap_mcbsp_count;
+extern int omap_mcbsp_count, omap_mcbsp_cache_size;
 
 int omap_mcbsp_init(void);
 void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
 					int size);
 void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
-#ifdef CONFIG_ARCH_OMAP34XX
+#ifdef CONFIG_ARCH_OMAP3
 void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
 void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
 u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
@@ -459,4 +502,21 @@ int omap_mcbsp_pollread(unsigned int id,
 int omap_mcbsp_pollwrite(unsigned int id, u16 buf);
 int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type);
 
+#ifdef CONFIG_ARCH_OMAP3
+/* Sidetone specific API */
+int omap_st_set_chgain(unsigned int id, int channel, s16 chgain);
+int omap_st_get_chgain(unsigned int id, int channel, s16 *chgain);
+int omap_st_enable(unsigned int id);
+int omap_st_disable(unsigned int id);
+int omap_st_is_enabled(unsigned int id);
+#else
+static inline int omap_st_set_chgain(unsigned int id, int channel,
+				     s16 chgain) { return 0; }
+static inline int omap_st_get_chgain(unsigned int id, int channel,
+				     s16 *chgain) { return 0; }
+static inline int omap_st_enable(unsigned int id) { return 0; }
+static inline int omap_st_disable(unsigned int id) { return 0; }
+static inline int omap_st_is_enabled(unsigned int id) {  return 0; }
+#endif
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/memory.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/memory.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/memory.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/memory.h	2010-05-16 17:17:36.000000000 -0400
@@ -38,8 +38,7 @@
  */
 #if defined(CONFIG_ARCH_OMAP1)
 #define PHYS_OFFSET		UL(0x10000000)
-#elif defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
-			defined(CONFIG_ARCH_OMAP4)
+#else
 #define PHYS_OFFSET		UL(0x80000000)
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/menelaus.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/menelaus.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/menelaus.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/menelaus.h	2010-05-16 17:17:36.000000000 -0400
@@ -40,7 +40,7 @@ extern int menelaus_set_vcore_hw(unsigne
 
 extern int menelaus_set_regulator_sleep(int enable, u32 val);
 
-#if defined(CONFIG_ARCH_OMAP24XX) && defined(CONFIG_MENELAUS)
+#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_MENELAUS)
 #define omap_has_menelaus()	1
 #else
 #define omap_has_menelaus()	0
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mmc.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/mmc.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mmc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/mmc.h	2010-05-16 17:17:36.000000000 -0400
@@ -55,12 +55,12 @@ struct omap_mmc_platform_data {
 	unsigned int max_freq;
 
 	/* switch the bus to a new slot */
-	int (* switch_slot)(struct device *dev, int slot);
+	int (*switch_slot)(struct device *dev, int slot);
 	/* initialize board-specific MMC functionality, can be NULL if
 	 * not supported */
-	int (* init)(struct device *dev);
-	void (* cleanup)(struct device *dev);
-	void (* shutdown)(struct device *dev);
+	int (*init)(struct device *dev);
+	void (*cleanup)(struct device *dev);
+	void (*shutdown)(struct device *dev);
 
 	/* To handle board related suspend/resume functionality for MMC */
 	int (*suspend)(struct device *dev, int slot);
@@ -96,14 +96,28 @@ struct omap_mmc_platform_data {
 		/* Try to sleep or power off when possible */
 		unsigned power_saving:1;
 
+		/* If using power_saving and the MMC power is not to go off */
+		unsigned no_off:1;
+
+		/* Regulator off remapped to sleep */
+		unsigned vcc_aux_disable_is_sleep:1;
+
 		int switch_pin;			/* gpio (card detect) */
 		int gpio_wp;			/* gpio (write protect) */
 
-		int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
-		int (* set_power)(struct device *dev, int slot, int power_on, int vdd);
-		int (* get_ro)(struct device *dev, int slot);
+		int (*set_bus_mode)(struct device *dev, int slot, int bus_mode);
+		int (*set_power)(struct device *dev, int slot,
+				 int power_on, int vdd);
+		int (*get_ro)(struct device *dev, int slot);
 		int (*set_sleep)(struct device *dev, int slot, int sleep,
 				 int vdd, int cardsleep);
+		void (*remux)(struct device *dev, int slot, int power_on);
+		/* Call back before enabling / disabling regulators */
+		void (*before_set_reg)(struct device *dev, int slot,
+				       int power_on, int vdd);
+		/* Call back after enabling / disabling regulators */
+		void (*after_set_reg)(struct device *dev, int slot,
+				      int power_on, int vdd);
 
 		/* return MMC cover switch state, can be NULL if not supported.
 		 *
@@ -111,14 +125,14 @@ struct omap_mmc_platform_data {
 		 *   0 - closed
 		 *   1 - open
 		 */
-		int (* get_cover_state)(struct device *dev, int slot);
+		int (*get_cover_state)(struct device *dev, int slot);
 
 		const char *name;
 		u32 ocr_mask;
 
 		/* Card detection IRQs */
 		int card_detect_irq;
-		int (* card_detect)(int irq);
+		int (*card_detect)(struct device *dev, int slot);
 
 		unsigned int ban_openended:1;
 
@@ -126,7 +140,8 @@ struct omap_mmc_platform_data {
 };
 
 /* called from board-specific card detection service routine */
-extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed);
+extern void omap_mmc_notify_cover_event(struct device *dev, int slot,
+					int is_closed);
 
 #if	defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
 	defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/multi.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/multi.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/multi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/multi.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,94 @@
+/*
+ * Support for compiling in multiple OMAP processors
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_OMAP_MULTI_H
+#define __PLAT_OMAP_MULTI_H
+
+/*
+ * Test if multicore OMAP support is needed
+ */
+#undef MULTI_OMAP1
+#undef MULTI_OMAP2
+#undef OMAP_NAME
+
+#ifdef CONFIG_ARCH_OMAP730
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP1
+#  define MULTI_OMAP1
+# else
+#  define OMAP_NAME omap730
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP850
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP1
+#  define MULTI_OMAP1
+# else
+#  define OMAP_NAME omap850
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP1
+#  define MULTI_OMAP1
+# else
+#  define OMAP_NAME omap1510
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP1
+#  define MULTI_OMAP1
+# else
+#  define OMAP_NAME omap16xx
+# endif
+#endif
+#if (defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3))
+# if (defined(OMAP_NAME) || defined(MULTI_OMAP1))
+#  error "OMAP1 and OMAP2 can't be selected at the same time"
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP2420
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP2
+#  define MULTI_OMAP2
+# else
+#  define OMAP_NAME omap2420
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP2430
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP2
+#  define MULTI_OMAP2
+# else
+#  define OMAP_NAME omap2430
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP3430
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP2
+#  define MULTI_OMAP2
+# else
+#  define OMAP_NAME omap3430
+# endif
+#endif
+
+#endif	/* __PLAT_OMAP_MULTI_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mux.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/mux.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mux.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/mux.h	2010-05-16 17:17:36.000000000 -0400
@@ -135,7 +135,7 @@ struct pin_config {
 	const unsigned int 	mux_reg;
 	unsigned char		debug;
 
-#if	defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP24XX)
+#if	defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP2)
 	const unsigned char mask_offset;
 	const unsigned char mask;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/nand.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/nand.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/nand.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/nand.h	2010-05-16 17:17:36.000000000 -0400
@@ -15,10 +15,25 @@ struct omap_nand_platform_data {
 	int			cs;
 	int			gpio_irq;
 	struct mtd_partition	*parts;
+	struct gpmc_timings	*gpmc_t;
 	int			nr_parts;
-	int			(*nand_setup)(void __iomem *);
+	int			(*nand_setup)(void);
 	int			(*dev_ready)(struct omap_nand_platform_data *);
 	int			dma_channel;
+	unsigned long		phys_base;
 	void __iomem		*gpmc_cs_baseaddr;
 	void __iomem		*gpmc_baseaddr;
+	int			devsize;
 };
+
+/* size (4 KiB) for IO mapping */
+#define	NAND_IO_SIZE	SZ_4K
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
+extern int gpmc_nand_init(struct omap_nand_platform_data *d);
+#else
+static inline int gpmc_nand_init(struct omap_nand_platform_data *d)
+{
+	return 0;
+}
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap16xx.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/omap16xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap16xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/omap16xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -125,43 +125,43 @@
 #define OMAP16XX_MMCSD2_SSW_MPU_CONF	(TIPB_SWITCH_BASE + 0x160)
 
 /* UART3 Registers Mapping through MPU bus */
-#define UART3_RHR               (OMAP_UART3_BASE + 0)
-#define UART3_THR               (OMAP_UART3_BASE + 0)
-#define UART3_DLL               (OMAP_UART3_BASE + 0)
-#define UART3_IER               (OMAP_UART3_BASE + 4)
-#define UART3_DLH               (OMAP_UART3_BASE + 4)
-#define UART3_IIR               (OMAP_UART3_BASE + 8)
-#define UART3_FCR               (OMAP_UART3_BASE + 8)
-#define UART3_EFR               (OMAP_UART3_BASE + 8)
-#define UART3_LCR               (OMAP_UART3_BASE + 0x0C)
-#define UART3_MCR               (OMAP_UART3_BASE + 0x10)
-#define UART3_XON1_ADDR1        (OMAP_UART3_BASE + 0x10)
-#define UART3_XON2_ADDR2        (OMAP_UART3_BASE + 0x14)
-#define UART3_LSR               (OMAP_UART3_BASE + 0x14)
-#define UART3_TCR               (OMAP_UART3_BASE + 0x18)
-#define UART3_MSR               (OMAP_UART3_BASE + 0x18)
-#define UART3_XOFF1             (OMAP_UART3_BASE + 0x18)
-#define UART3_XOFF2             (OMAP_UART3_BASE + 0x1C)
-#define UART3_SPR               (OMAP_UART3_BASE + 0x1C)
-#define UART3_TLR               (OMAP_UART3_BASE + 0x1C)
-#define UART3_MDR1              (OMAP_UART3_BASE + 0x20)
-#define UART3_MDR2              (OMAP_UART3_BASE + 0x24)
-#define UART3_SFLSR             (OMAP_UART3_BASE + 0x28)
-#define UART3_TXFLL             (OMAP_UART3_BASE + 0x28)
-#define UART3_RESUME            (OMAP_UART3_BASE + 0x2C)
-#define UART3_TXFLH             (OMAP_UART3_BASE + 0x2C)
-#define UART3_SFREGL            (OMAP_UART3_BASE + 0x30)
-#define UART3_RXFLL             (OMAP_UART3_BASE + 0x30)
-#define UART3_SFREGH            (OMAP_UART3_BASE + 0x34)
-#define UART3_RXFLH             (OMAP_UART3_BASE + 0x34)
-#define UART3_BLR               (OMAP_UART3_BASE + 0x38)
-#define UART3_ACREG             (OMAP_UART3_BASE + 0x3C)
-#define UART3_DIV16             (OMAP_UART3_BASE + 0x3C)
-#define UART3_SCR               (OMAP_UART3_BASE + 0x40)
-#define UART3_SSR               (OMAP_UART3_BASE + 0x44)
-#define UART3_EBLR              (OMAP_UART3_BASE + 0x48)
-#define UART3_OSC_12M_SEL       (OMAP_UART3_BASE + 0x4C)
-#define UART3_MVR               (OMAP_UART3_BASE + 0x50)
+#define UART3_RHR               (OMAP1_UART3_BASE + 0)
+#define UART3_THR               (OMAP1_UART3_BASE + 0)
+#define UART3_DLL               (OMAP1_UART3_BASE + 0)
+#define UART3_IER               (OMAP1_UART3_BASE + 4)
+#define UART3_DLH               (OMAP1_UART3_BASE + 4)
+#define UART3_IIR               (OMAP1_UART3_BASE + 8)
+#define UART3_FCR               (OMAP1_UART3_BASE + 8)
+#define UART3_EFR               (OMAP1_UART3_BASE + 8)
+#define UART3_LCR               (OMAP1_UART3_BASE + 0x0C)
+#define UART3_MCR               (OMAP1_UART3_BASE + 0x10)
+#define UART3_XON1_ADDR1        (OMAP1_UART3_BASE + 0x10)
+#define UART3_XON2_ADDR2        (OMAP1_UART3_BASE + 0x14)
+#define UART3_LSR               (OMAP1_UART3_BASE + 0x14)
+#define UART3_TCR               (OMAP1_UART3_BASE + 0x18)
+#define UART3_MSR               (OMAP1_UART3_BASE + 0x18)
+#define UART3_XOFF1             (OMAP1_UART3_BASE + 0x18)
+#define UART3_XOFF2             (OMAP1_UART3_BASE + 0x1C)
+#define UART3_SPR               (OMAP1_UART3_BASE + 0x1C)
+#define UART3_TLR               (OMAP1_UART3_BASE + 0x1C)
+#define UART3_MDR1              (OMAP1_UART3_BASE + 0x20)
+#define UART3_MDR2              (OMAP1_UART3_BASE + 0x24)
+#define UART3_SFLSR             (OMAP1_UART3_BASE + 0x28)
+#define UART3_TXFLL             (OMAP1_UART3_BASE + 0x28)
+#define UART3_RESUME            (OMAP1_UART3_BASE + 0x2C)
+#define UART3_TXFLH             (OMAP1_UART3_BASE + 0x2C)
+#define UART3_SFREGL            (OMAP1_UART3_BASE + 0x30)
+#define UART3_RXFLL             (OMAP1_UART3_BASE + 0x30)
+#define UART3_SFREGH            (OMAP1_UART3_BASE + 0x34)
+#define UART3_RXFLH             (OMAP1_UART3_BASE + 0x34)
+#define UART3_BLR               (OMAP1_UART3_BASE + 0x38)
+#define UART3_ACREG             (OMAP1_UART3_BASE + 0x3C)
+#define UART3_DIV16             (OMAP1_UART3_BASE + 0x3C)
+#define UART3_SCR               (OMAP1_UART3_BASE + 0x40)
+#define UART3_SSR               (OMAP1_UART3_BASE + 0x44)
+#define UART3_EBLR              (OMAP1_UART3_BASE + 0x48)
+#define UART3_OSC_12M_SEL       (OMAP1_UART3_BASE + 0x4C)
+#define UART3_MVR               (OMAP1_UART3_BASE + 0x50)
 
 /*
  * ---------------------------------------------------------------------------
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap24xx.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/omap24xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap24xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/omap24xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,8 +23,8 @@
  *
  */
 
-#ifndef __ASM_ARCH_OMAP24XX_H
-#define __ASM_ARCH_OMAP24XX_H
+#ifndef __ASM_ARCH_OMAP2_H
+#define __ASM_ARCH_OMAP2_H
 
 /*
  * Please place only base defines here and put the rest in device
@@ -85,5 +85,5 @@
 #define OMAP24XX_SEC_AES_BASE	(OMAP24XX_SEC_BASE + 0x6000)
 #define OMAP24XX_SEC_PKA_BASE	(OMAP24XX_SEC_BASE + 0x8000)
 
-#endif /* __ASM_ARCH_OMAP24XX_H */
+#endif /* __ASM_ARCH_OMAP2_H */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap34xx.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/omap34xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap34xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/omap34xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,8 +21,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef __ASM_ARCH_OMAP34XX_H
-#define __ASM_ARCH_OMAP34XX_H
+#ifndef __ASM_ARCH_OMAP3_H
+#define __ASM_ARCH_OMAP3_H
 
 /*
  * Please place only base defines here and put the rest in device
@@ -82,5 +82,5 @@
 
 #define OMAP34XX_MAILBOX_BASE		(L4_34XX_BASE + 0x94000)
 
-#endif /* __ASM_ARCH_OMAP34XX_H */
+#endif /* __ASM_ARCH_OMAP3_H */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap44xx.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/omap44xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap44xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/omap44xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,7 @@
 #define OMAP4430_PRM_BASE		0x4a306000
 #define OMAP44XX_GPMC_BASE		0x50000000
 #define OMAP443X_SCM_BASE		0x4a002000
-#define OMAP443X_CTRL_BASE		OMAP443X_SCM_BASE
+#define OMAP443X_CTRL_BASE		0x4a100000
 #define OMAP44XX_IC_BASE		0x48200000
 #define OMAP44XX_IVA_INTC_BASE		0x40000000
 #define IRQ_SIR_IRQ			0x0040
@@ -40,9 +40,13 @@
 #define OMAP44XX_GIC_CPU_BASE		0x48240100
 #define OMAP44XX_SCU_BASE		0x48240000
 #define OMAP44XX_LOCAL_TWD_BASE		0x48240600
+#define OMAP44XX_L2CACHE_BASE		0x48242000
 #define OMAP44XX_WKUPGEN_BASE		0x48281000
+#define OMAP44XX_MCPDM_BASE		0x40132000
+#define OMAP44XX_MCPDM_L3_BASE		0x49032000
 
 #define OMAP44XX_MAILBOX_BASE		(L4_44XX_BASE + 0xF4000)
+#define OMAP44XX_HSUSB_OTG_BASE		(L4_44XX_BASE + 0xAB000)
 
 #endif /* __ASM_ARCH_OMAP44XX_H */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap_device.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/omap_device.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap_device.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/omap_device.h	2010-05-16 17:17:36.000000000 -0400
@@ -62,6 +62,7 @@
  *
  */
 struct omap_device {
+	u32                             magic;
 	struct platform_device		pdev;
 	struct omap_hwmod		**hwmods;
 	struct omap_device_pm_latency	*pm_lats;
@@ -81,6 +82,7 @@ int omap_device_shutdown(struct platform
 
 /* Core code interface */
 
+bool omap_device_is_valid(struct omap_device *od);
 int omap_device_count_resources(struct omap_device *od);
 int omap_device_fill_resources(struct omap_device *od, struct resource *res);
 
@@ -88,15 +90,16 @@ struct omap_device *omap_device_build(co
 				      struct omap_hwmod *oh, void *pdata,
 				      int pdata_len,
 				      struct omap_device_pm_latency *pm_lats,
-				      int pm_lats_cnt);
+				      int pm_lats_cnt, int is_early_device);
 
 struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
 					 struct omap_hwmod **oh, int oh_cnt,
 					 void *pdata, int pdata_len,
 					 struct omap_device_pm_latency *pm_lats,
-					 int pm_lats_cnt);
+					 int pm_lats_cnt, int is_early_device);
 
 int omap_device_register(struct omap_device *od);
+int omap_early_device_register(struct omap_device *od);
 
 /* OMAP PM interface */
 int omap_device_align_pm_lat(struct platform_device *pdev,
@@ -131,11 +134,15 @@ int omap_device_enable_clocks(struct oma
  */
 struct omap_device_pm_latency {
 	u32 deactivate_lat;
+	u32 deactivate_lat_worst;
 	int (*deactivate_func)(struct omap_device *od);
 	u32 activate_lat;
+	u32 activate_lat_worst;
 	int (*activate_func)(struct omap_device *od);
+	u32 flags;
 };
 
+#define OMAP_DEVICE_LATENCY_AUTO_ADJUST BIT(1)
 
 /* Get omap_device pointer from platform_device pointer */
 #define to_omap_device(x) container_of((x), struct omap_device, pdev)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap_hwmod.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/omap_hwmod.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap_hwmod.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/omap_hwmod.h	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
  * Copyright (C) 2009 Nokia Corporation
  * Paul Walmsley
  *
- * Created in collaboration with (alphabetical order): Benoit Cousson,
+ * Created in collaboration with (alphabetical order): BenoÃ®t Cousson,
  * Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari
  * Poussa, Anand Sawant, Santosh Shilimkar, Richard Woodruff
  *
@@ -33,25 +33,42 @@
 #define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
 
 #include <linux/kernel.h>
+#include <linux/list.h>
 #include <linux/ioport.h>
-
 #include <plat/cpu.h>
 
 struct omap_device;
 
-/* OCP SYSCONFIG bit shifts/masks */
-#define SYSC_MIDLEMODE_SHIFT		12
-#define SYSC_MIDLEMODE_MASK		(0x3 << SYSC_MIDLEMODE_SHIFT)
-#define SYSC_CLOCKACTIVITY_SHIFT	8
-#define SYSC_CLOCKACTIVITY_MASK		(0x3 << SYSC_CLOCKACTIVITY_SHIFT)
-#define SYSC_SIDLEMODE_SHIFT		3
-#define SYSC_SIDLEMODE_MASK		(0x3 << SYSC_SIDLEMODE_SHIFT)
-#define SYSC_ENAWAKEUP_SHIFT		2
-#define SYSC_ENAWAKEUP_MASK		(1 << SYSC_ENAWAKEUP_SHIFT)
-#define SYSC_SOFTRESET_SHIFT		1
-#define SYSC_SOFTRESET_MASK		(1 << SYSC_SOFTRESET_SHIFT)
-#define SYSC_AUTOIDLE_SHIFT		0
-#define SYSC_AUTOIDLE_MASK		(1 << SYSC_AUTOIDLE_SHIFT)
+extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type1;
+extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
+
+/*
+ * OCP SYSCONFIG bit shifts/masks TYPE1. These are for IPs compliant
+ * with the original PRCM protocol defined for OMAP2420
+ */
+#define SYSC_TYPE1_MIDLEMODE_SHIFT	12
+#define SYSC_TYPE1_MIDLEMODE_MASK	(0x3 << SYSC_MIDLEMODE_SHIFT)
+#define SYSC_TYPE1_CLOCKACTIVITY_SHIFT	8
+#define SYSC_TYPE1_CLOCKACTIVITY_MASK	(0x3 << SYSC_CLOCKACTIVITY_SHIFT)
+#define SYSC_TYPE1_SIDLEMODE_SHIFT	3
+#define SYSC_TYPE1_SIDLEMODE_MASK	(0x3 << SYSC_SIDLEMODE_SHIFT)
+#define SYSC_TYPE1_ENAWAKEUP_SHIFT	2
+#define SYSC_TYPE1_ENAWAKEUP_MASK	(1 << SYSC_ENAWAKEUP_SHIFT)
+#define SYSC_TYPE1_SOFTRESET_SHIFT	1
+#define SYSC_TYPE1_SOFTRESET_MASK	(1 << SYSC_SOFTRESET_SHIFT)
+#define SYSC_TYPE1_AUTOIDLE_SHIFT	0
+#define SYSC_TYPE1_AUTOIDLE_MASK	(1 << SYSC_AUTOIDLE_SHIFT)
+
+/*
+ * OCP SYSCONFIG bit shifts/masks TYPE2. These are for IPs compliant
+ * with the new PRCM protocol defined for new OMAP4 IPs.
+ */
+#define SYSC_TYPE2_SOFTRESET_SHIFT	0
+#define SYSC_TYPE2_SOFTRESET_MASK	(1 << SYSC_TYPE2_SOFTRESET_SHIFT)
+#define SYSC_TYPE2_SIDLEMODE_SHIFT	2
+#define SYSC_TYPE2_SIDLEMODE_MASK	(0x3 << SYSC_TYPE2_SIDLEMODE_SHIFT)
+#define SYSC_TYPE2_MIDLEMODE_SHIFT	4
+#define SYSC_TYPE2_MIDLEMODE_MASK	(0x3 << SYSC_TYPE2_MIDLEMODE_SHIFT)
 
 /* OCP SYSSTATUS bit shifts/masks */
 #define SYSS_RESETDONE_SHIFT		0
@@ -62,7 +79,6 @@ struct omap_device;
 #define HWMOD_IDLEMODE_NO		(1 << 1)
 #define HWMOD_IDLEMODE_SMART		(1 << 2)
 
-
 /**
  * struct omap_hwmod_irq_info - MPU IRQs used by the hwmod
  * @name: name of the IRQ channel (module local name)
@@ -94,8 +110,7 @@ struct omap_hwmod_dma_info {
 /**
  * struct omap_hwmod_opt_clk - optional clocks used by this hwmod
  * @role: "sys", "32k", "tv", etc -- for use in clk_get()
- * @clkdev_dev_id: opt clock: clkdev dev_id string
- * @clkdev_con_id: opt clock: clkdev con_id string
+ * @clk: opt clock: OMAP clock name
  * @_clk: pointer to the struct clk (filled in at runtime)
  *
  * The module's interface clock and main functional clock should not
@@ -103,8 +118,7 @@ struct omap_hwmod_dma_info {
  */
 struct omap_hwmod_opt_clk {
 	const char	*role;
-	const char	*clkdev_dev_id;
-	const char	*clkdev_con_id;
+	const char	*clk;
 	struct clk	*_clk;
 };
 
@@ -171,8 +185,7 @@ struct omap_hwmod_addr_space {
  * @master: struct omap_hwmod that initiates OCP transactions on this link
  * @slave: struct omap_hwmod that responds to OCP transactions on this link
  * @addr: address space associated with this link
- * @clkdev_dev_id: interface clock: clkdev dev_id string
- * @clkdev_con_id: interface clock: clkdev con_id string
+ * @clk: interface clock: OMAP clock name
  * @_clk: pointer to the interface struct clk (filled in at runtime)
  * @fw: interface firewall data
  * @addr_cnt: ARRAY_SIZE(@addr)
@@ -191,8 +204,7 @@ struct omap_hwmod_ocp_if {
 	struct omap_hwmod		*master;
 	struct omap_hwmod		*slave;
 	struct omap_hwmod_addr_space	*addr;
-	const char			*clkdev_dev_id;
-	const char			*clkdev_con_id;
+	const char			*clk;
 	struct clk			*_clk;
 	union {
 		struct omap_hwmod_omap2_firewall omap2;
@@ -236,7 +248,25 @@ struct omap_hwmod_ocp_if {
 #define CLOCKACT_TEST_NONE	0x3
 
 /**
- * struct omap_hwmod_sysconfig - hwmod OCP_SYSCONFIG/OCP_SYSSTATUS data
+ * struct omap_hwmod_sysc_fields - hwmod OCP_SYSCONFIG register field offsets.
+ * @midle_shift: Offset of the midle bit
+ * @clkact_shift: Offset of the clockactivity bit
+ * @sidle_shift: Offset of the sidle bit
+ * @enwkup_shift: Offset of the enawakeup bit
+ * @srst_shift: Offset of the softreset bit
+ * @autoidle_shift: Offset of the autoidle bit
+ */
+struct omap_hwmod_sysc_fields {
+	u8 midle_shift;
+	u8 clkact_shift;
+	u8 sidle_shift;
+	u8 enwkup_shift;
+	u8 srst_shift;
+	u8 autoidle_shift;
+};
+
+/**
+ * struct omap_hwmod_class_sysconfig - hwmod class OCP_SYS* data
  * @rev_offs: IP block revision register offset (from module base addr)
  * @sysc_offs: OCP_SYSCONFIG register offset (from module base addr)
  * @syss_offs: OCP_SYSSTATUS register offset (from module base addr)
@@ -252,14 +282,22 @@ struct omap_hwmod_ocp_if {
  * been associated with the clocks marked in @clockact.  This field is
  * only used if HWMOD_SET_DEFAULT_CLOCKACT is set (see below)
  *
+ * @sysc_fields: structure containing the offset positions of various bits in
+ * SYSCONFIG register. This can be populated using omap_hwmod_sysc_type1 or
+ * omap_hwmod_sysc_type2 defined in omap_hwmod_common_data.c depending on
+ * whether the device ip is compliant with the original PRCM protocol
+ * defined for OMAP2420 or the new PRCM protocol for new OMAP4 IPs.
+ * If the device follows a different scheme for the sysconfig register ,
+ * then this field has to be populated with the correct offset structure.
  */
-struct omap_hwmod_sysconfig {
+struct omap_hwmod_class_sysconfig {
 	u16 rev_offs;
 	u16 sysc_offs;
 	u16 syss_offs;
+	u16 sysc_flags;
 	u8 idlemodes;
-	u8 sysc_flags;
 	u8 clockact;
+	struct omap_hwmod_sysc_fields *sysc_fields;
 };
 
 /**
@@ -352,19 +390,33 @@ struct omap_hwmod_omap4_prcm {
 #define _HWMOD_STATE_DISABLED			6
 
 /**
+ * struct omap_hwmod_class - the type of an IP block
+ * @name: name of the hwmod_class
+ * @sysc: device SYSCONFIG/SYSSTATUS register data
+ * @rev: revision of the IP class
+ *
+ * Represent the class of a OMAP hardware "modules" (e.g. timer,
+ * smartreflex, gpio, uart...)
+ */
+struct omap_hwmod_class {
+	const char				*name;
+	struct omap_hwmod_class_sysconfig	*sysc;
+	u32					rev;
+};
+
+/**
  * struct omap_hwmod - integration data for OMAP hardware "modules" (IP blocks)
  * @name: name of the hwmod
+ * @class: struct omap_hwmod_class * to the class of this hwmod
  * @od: struct omap_device currently associated with this hwmod (internal use)
  * @mpu_irqs: ptr to an array of MPU IRQs (see also mpu_irqs_cnt)
  * @sdma_chs: ptr to an array of SDMA channel IDs (see also sdma_chs_cnt)
  * @prcm: PRCM data pertaining to this hwmod
- * @clkdev_dev_id: main clock: clkdev dev_id string
- * @clkdev_con_id: main clock: clkdev con_id string
+ * @main_clk: main clock: OMAP clock name
  * @_clk: pointer to the main struct clk (filled in at runtime)
  * @opt_clks: other device clocks that drivers can request (0..*)
  * @masters: ptr to array of OCP ifs that this hwmod can initiate on
  * @slaves: ptr to array of OCP ifs that this hwmod can respond on
- * @sysconfig: device SYSCONFIG/SYSSTATUS register data
  * @dev_attr: arbitrary device attributes that can be passed to the driver
  * @_sysc_cache: internal-use hwmod flags
  * @_rt_va: cached register target start address (internal use)
@@ -383,16 +435,17 @@ struct omap_hwmod_omap4_prcm {
  * @omap_chip: OMAP chips this hwmod is present on
  * @node: list node for hwmod list (internal use)
  *
- * @clkdev_dev_id, @clkdev_con_id, and @clk all refer to this module's "main
- * clock," which for our purposes is defined as "the functional clock needed
- * for register accesses to complete."  Modules may not have a main clock if
- * the interface clock also serves as a main clock.
+ * @main_clk refers to this module's "main clock," which for our
+ * purposes is defined as "the functional clock needed for register
+ * accesses to complete."  Modules may not have a main clock if the
+ * interface clock also serves as a main clock.
  *
  * Parameter names beginning with an underscore are managed internally by
  * the omap_hwmod code and should not be set during initialization.
  */
 struct omap_hwmod {
 	const char			*name;
+	struct omap_hwmod_class		*class;
 	struct omap_device		*od;
 	struct omap_hwmod_irq_info	*mpu_irqs;
 	struct omap_hwmod_dma_info	*sdma_chs;
@@ -400,13 +453,11 @@ struct omap_hwmod {
 		struct omap_hwmod_omap2_prcm omap2;
 		struct omap_hwmod_omap4_prcm omap4;
 	}				prcm;
-	const char			*clkdev_dev_id;
-	const char			*clkdev_con_id;
+	const char			*main_clk;
 	struct clk			*_clk;
 	struct omap_hwmod_opt_clk	*opt_clks;
 	struct omap_hwmod_ocp_if	**masters; /* connect to *_IA */
 	struct omap_hwmod_ocp_if	**slaves;  /* connect to *_TA */
-	struct omap_hwmod_sysconfig	*sysconfig;
 	void				*dev_attr;
 	u32				_sysc_cache;
 	void __iomem			*_rt_va;
@@ -441,6 +492,8 @@ int omap_hwmod_shutdown(struct omap_hwmo
 int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
 int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
 
+int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode);
+
 int omap_hwmod_reset(struct omap_hwmod *oh);
 void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
 
@@ -465,4 +518,17 @@ int omap_hwmod_set_clockact_none(struct
 int omap_hwmod_enable_wakeup(struct omap_hwmod *oh);
 int omap_hwmod_disable_wakeup(struct omap_hwmod *oh);
 
+int omap_hwmod_for_each_by_class(const char *classname,
+				 int (*fn)(struct omap_hwmod *oh,
+					   void *user),
+				 void *user);
+
+/*
+ * Chip variant-specific hwmod init routines - XXX should be converted
+ * to use initcalls once the initial boot ordering is straightened out
+ */
+extern int omap2420_hwmod_init(void);
+extern int omap2430_hwmod_init(void);
+extern int omap3xxx_hwmod_init(void);
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/powerdomain.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/powerdomain.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/powerdomain.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/powerdomain.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,8 +1,8 @@
 /*
  * OMAP2/3 powerdomain control
  *
- * Copyright (C) 2007-8 Texas Instruments, Inc.
- * Copyright (C) 2007-8 Nokia Corporation
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009 Nokia Corporation
  *
  * Written by Paul Walmsley
  *
@@ -37,6 +37,9 @@
 #define PWRSTS_OFF_RET		((1 << PWRDM_POWER_OFF) | \
 				 (1 << PWRDM_POWER_RET))
 
+#define PWRSTS_RET_ON		((1 << PWRDM_POWER_RET) | \
+				 (1 << PWRDM_POWER_ON))
+
 #define PWRSTS_OFF_RET_ON	(PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON))
 
 
@@ -48,16 +51,16 @@
 					  */
 
 /*
- * Number of memory banks that are power-controllable.	On OMAP3430, the
- * maximum is 4.
+ * Number of memory banks that are power-controllable.	On OMAP4430, the
+ * maximum is 5.
  */
-#define PWRDM_MAX_MEM_BANKS	4
+#define PWRDM_MAX_MEM_BANKS	5
 
 /*
  * Maximum number of clockdomains that can be associated with a powerdomain.
- * CORE powerdomain on OMAP3 is the worst case
+ * CORE powerdomain on OMAP4 is the worst case
  */
-#define PWRDM_MAX_CLKDMS	4
+#define PWRDM_MAX_CLKDMS	9
 
 /* XXX A completely arbitrary number. What is reasonable here? */
 #define PWRDM_TRANSITION_BAILOUT 100000
@@ -65,65 +68,40 @@
 struct clockdomain;
 struct powerdomain;
 
-/* Encodes dependencies between powerdomains - statically defined */
-struct pwrdm_dep {
-
-	/* Powerdomain name */
-	const char *pwrdm_name;
-
-	/* Powerdomain pointer - resolved by the powerdomain code */
-	struct powerdomain *pwrdm;
-
-	/* Flags to mark OMAP chip restrictions, etc. */
-	const struct omap_chip_id omap_chip;
-
-};
-
+/**
+ * struct powerdomain - OMAP powerdomain
+ * @name: Powerdomain name
+ * @omap_chip: represents the OMAP chip types containing this pwrdm
+ * @prcm_offs: the address offset from CM_BASE/PRM_BASE
+ * @pwrsts: Possible powerdomain power states
+ * @pwrsts_logic_ret: Possible logic power states when pwrdm in RETENTION
+ * @flags: Powerdomain flags
+ * @banks: Number of software-controllable memory banks in this powerdomain
+ * @pwrsts_mem_ret: Possible memory bank pwrstates when pwrdm in RETENTION
+ * @pwrsts_mem_on: Possible memory bank pwrstates when pwrdm in ON
+ * @pwrdm_clkdms: Clockdomains in this powerdomain
+ * @node: list_head linking all powerdomains
+ * @state:
+ * @state_counter:
+ * @timer:
+ * @state_timer:
+ */
 struct powerdomain {
-
-	/* Powerdomain name */
 	const char *name;
-
-	/* the address offset from CM_BASE/PRM_BASE */
-	const s16 prcm_offs;
-
-	/* Used to represent the OMAP chip types containing this pwrdm */
 	const struct omap_chip_id omap_chip;
-
-	/* Powerdomains that can be told to wake this powerdomain up */
-	struct pwrdm_dep *wkdep_srcs;
-
-	/* Powerdomains that can be told to keep this pwrdm from inactivity */
-	struct pwrdm_dep *sleepdep_srcs;
-
-	/* Bit shift of this powerdomain's PM_WKDEP/CM_SLEEPDEP bit */
-	const u8 dep_bit;
-
-	/* Possible powerdomain power states */
+	const s16 prcm_offs;
 	const u8 pwrsts;
-
-	/* Possible logic power states when pwrdm in RETENTION */
 	const u8 pwrsts_logic_ret;
-
-	/* Powerdomain flags */
 	const u8 flags;
-
-	/* Number of software-controllable memory banks in this powerdomain */
 	const u8 banks;
-
-	/* Possible memory bank pwrstates when pwrdm in RETENTION */
 	const u8 pwrsts_mem_ret[PWRDM_MAX_MEM_BANKS];
-
-	/* Possible memory bank pwrstates when pwrdm is ON */
 	const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS];
-
-	/* Clockdomains in this powerdomain */
 	struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
-
 	struct list_head node;
-
 	int state;
 	unsigned state_counter[PWRDM_MAX_PWRSTS];
+	unsigned ret_logic_off_counter;
+	unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS];
 
 #ifdef CONFIG_PM_DEBUG
 	s64 timer;
@@ -134,8 +112,6 @@ struct powerdomain {
 
 void pwrdm_init(struct powerdomain **pwrdm_list);
 
-int pwrdm_register(struct powerdomain *pwrdm);
-int pwrdm_unregister(struct powerdomain *pwrdm);
 struct powerdomain *pwrdm_lookup(const char *name);
 
 int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
@@ -149,13 +125,6 @@ int pwrdm_for_each_clkdm(struct powerdom
 			 int (*fn)(struct powerdomain *pwrdm,
 				   struct clockdomain *clkdm));
 
-int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
-int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
-int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
-int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
-int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
-int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
-
 int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
 
 int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
@@ -170,8 +139,10 @@ int pwrdm_set_mem_retst(struct powerdoma
 
 int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm);
 int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_logic_retst(struct powerdomain *pwrdm);
 int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
 int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
+int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank);
 
 int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);
 int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/prcm.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/prcm.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/prcm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/prcm.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,8 +24,9 @@
 #define __ASM_ARM_ARCH_OMAP_PRCM_H
 
 u32 omap_prcm_get_reset_sources(void);
-void omap_prcm_arch_reset(char mode);
-int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name);
+void omap_prcm_arch_reset(char mode, const char *cmd);
+int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest,
+			 const char *name);
 
 #define START_PADCONF_SAVE 0x2
 #define PADCONF_SAVE_DONE  0x1
@@ -33,6 +34,14 @@ int omap2_cm_wait_idlest(void __iomem *r
 void omap3_prcm_save_context(void);
 void omap3_prcm_restore_context(void);
 
+u32 prm_read_mod_reg(s16 module, u16 idx);
+void prm_write_mod_reg(u32 val, s16 module, u16 idx);
+u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
+u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask);
+u32 cm_read_mod_reg(s16 module, u16 idx);
+void cm_write_mod_reg(u32 val, s16 module, u16 idx);
+u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
+
 #endif
 
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/serial.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/serial.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/serial.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/serial.h	2010-05-16 17:17:36.000000000 -0400
@@ -15,37 +15,65 @@
 
 #include <linux/init.h>
 
-#if defined(CONFIG_ARCH_OMAP1)
 /* OMAP1 serial ports */
-#define OMAP_UART1_BASE		0xfffb0000
-#define OMAP_UART2_BASE		0xfffb0800
-#define OMAP_UART3_BASE		0xfffb9800
-#elif defined(CONFIG_ARCH_OMAP2)
+#define OMAP1_UART1_BASE	0xfffb0000
+#define OMAP1_UART2_BASE	0xfffb0800
+#define OMAP1_UART3_BASE	0xfffb9800
+
 /* OMAP2 serial ports */
-#define OMAP_UART1_BASE		0x4806a000
-#define OMAP_UART2_BASE		0x4806c000
-#define OMAP_UART3_BASE		0x4806e000
-#elif defined(CONFIG_ARCH_OMAP3)
+#define OMAP2_UART1_BASE	0x4806a000
+#define OMAP2_UART2_BASE	0x4806c000
+#define OMAP2_UART3_BASE	0x4806e000
+
 /* OMAP3 serial ports */
-#define OMAP_UART1_BASE		0x4806a000
-#define OMAP_UART2_BASE		0x4806c000
-#define OMAP_UART3_BASE		0x49020000
-#elif defined(CONFIG_ARCH_OMAP4)
+#define OMAP3_UART1_BASE	OMAP2_UART1_BASE
+#define OMAP3_UART2_BASE	OMAP2_UART2_BASE
+#define OMAP3_UART3_BASE	0x49020000
+#define OMAP3_UART4_BASE	0x49042000	/* Only on 36xx */
+
 /* OMAP4 serial ports */
-#define OMAP_UART1_BASE		0x4806a000
-#define OMAP_UART2_BASE		0x4806c000
-#define OMAP_UART3_BASE		0x48020000
-#define OMAP_UART4_BASE		0x4806e000
-#endif
+#define OMAP4_UART1_BASE	OMAP2_UART1_BASE
+#define OMAP4_UART2_BASE	OMAP2_UART2_BASE
+#define OMAP4_UART3_BASE	0x48020000
+#define OMAP4_UART4_BASE	0x4806e000
+
+/* External port on Zoom2/3 */
+#define ZOOM_UART_BASE		0x10000000
+#define ZOOM_UART_VIRT		0xfb000000
+
+#define OMAP_PORT_SHIFT		2
+#define OMAP7XX_PORT_SHIFT	0
+#define ZOOM_PORT_SHIFT		1
 
 #define OMAP1510_BASE_BAUD	(12000000/16)
 #define OMAP16XX_BASE_BAUD	(48000000/16)
 #define OMAP24XX_BASE_BAUD	(48000000/16)
 
+/*
+ * DEBUG_LL port encoding stored into the UART1 scratchpad register by
+ * decomp_setup in uncompress.h
+ */
+#define OMAP1UART1		11
+#define OMAP1UART2		12
+#define OMAP1UART3		13
+#define OMAP2UART1		21
+#define OMAP2UART2		22
+#define OMAP2UART3		23
+#define OMAP3UART1		OMAP2UART1
+#define OMAP3UART2		OMAP2UART2
+#define OMAP3UART3		33
+#define OMAP3UART4		34		/* Only on 36xx */
+#define OMAP4UART1		OMAP2UART1
+#define OMAP4UART2		OMAP2UART2
+#define OMAP4UART3		43
+#define OMAP4UART4		44
+#define ZOOM_UART		95		/* Only on zoom2/3 */
+
+/* This is only used by 8250.c for omap1510 */
 #define is_omap_port(pt)	({int __ret = 0;			\
-			if ((pt)->port.mapbase == OMAP_UART1_BASE ||	\
-			    (pt)->port.mapbase == OMAP_UART2_BASE ||	\
-			    (pt)->port.mapbase == OMAP_UART3_BASE)	\
+			if ((pt)->port.mapbase == OMAP1_UART1_BASE ||	\
+			    (pt)->port.mapbase == OMAP1_UART2_BASE ||	\
+			    (pt)->port.mapbase == OMAP1_UART3_BASE)	\
 				__ret = 1;				\
 			__ret;						\
 			})
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/system.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/system.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/system.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,7 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void omap1_arch_reset(char mode)
+static inline void omap1_arch_reset(char mode, const char *cmd)
 {
 	/*
 	 * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28
@@ -43,9 +43,9 @@ static inline void omap1_arch_reset(char
 static inline void arch_reset(char mode, const char *cmd)
 {
 	if (!cpu_class_is_omap2())
-		omap1_arch_reset(mode);
+		omap1_arch_reset(mode, cmd);
 	else
-		omap_prcm_arch_reset(mode);
+		omap_prcm_arch_reset(mode, cmd);
 }
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/uncompress.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/uncompress.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/uncompress.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/uncompress.h	2010-05-16 17:17:36.000000000 -0400
@@ -19,70 +19,155 @@
 
 #include <linux/types.h>
 #include <linux/serial_reg.h>
+
+#include <asm/mach-types.h>
+
 #include <plat/serial.h>
 
-unsigned int system_rev;
+static volatile u8 *uart1_base;
+static int uart1_shift;
 
-#define UART_OMAP_MDR1		0x08	/* mode definition register */
-#define OMAP_ID_730		0x355F
-#define OMAP_ID_850		0x362C
-#define ID_MASK			0x7fff
-#define check_port(base, shift) ((base[UART_OMAP_MDR1 << shift] & 7) == 0)
-#define omap_get_id() ((*(volatile unsigned int *)(0xfffed404)) >> 12) & ID_MASK
+static volatile u8 *uart_base;
+static int uart_shift;
+
+/*
+ * Store the DEBUG_LL uart number into UART1 scratchpad register.
+ * See also debug-macro.S, and serial.c for related code.
+ *
+ * Please note that we currently assume that:
+ * - UART1 clocks are enabled for register access
+ * - UART1 scratchpad register can be used
+ */
+static void set_uart1_scratchpad(unsigned char port)
+{
+	uart1_base[UART_SCR << uart1_shift] = port;
+}
 
 static void putc(int c)
 {
-	volatile u8 * uart = 0;
-	int shift = 2;
+	if (!uart_base)
+		return;
 
-#ifdef CONFIG_MACH_OMAP_PALMTE
-	return;
-#endif
+	while (!(uart_base[UART_LSR << uart_shift] & UART_LSR_THRE))
+		barrier();
+	uart_base[UART_TX << uart_shift] = c;
+}
 
-#ifdef CONFIG_ARCH_OMAP
-#ifdef	CONFIG_OMAP_LL_DEBUG_UART3
-	uart = (volatile u8 *)(OMAP_UART3_BASE);
-#elif defined(CONFIG_OMAP_LL_DEBUG_UART2)
-	uart = (volatile u8 *)(OMAP_UART2_BASE);
-#elif defined(CONFIG_OMAP_LL_DEBUG_UART1)
-	uart = (volatile u8 *)(OMAP_UART1_BASE);
-#elif defined(CONFIG_OMAP_LL_DEBUG_NONE)
-	return;
-#else
-	return;
-#endif
+static inline void flush(void)
+{
+}
 
-#ifdef CONFIG_ARCH_OMAP1
-	/* Determine which serial port to use */
-	do {
-		/* MMU is not on, so cpu_is_omapXXXX() won't work here */
-		unsigned int omap_id = omap_get_id();
+/*
+ * Macros to configure UART1 and debug UART
+ */
+#define _DEBUG_LL_ENTRY(mach, uart1_phys, uart1_shft,			\
+			dbg_uart, dbg_shft, dbg_id)			\
+	if (machine_is_##mach()) {					\
+		uart1_base = (volatile u8 *)(uart1_phys);		\
+		uart1_shift = (uart1_shft);				\
+		uart_base = (volatile u8 *)(dbg_uart);			\
+		uart_shift = (dbg_shft);				\
+		port = (dbg_id);					\
+		set_uart1_scratchpad(port);				\
+		break;							\
+	}
 
-		if (omap_id == OMAP_ID_730 || omap_id == OMAP_ID_850)
-			shift = 0;
+#define DEBUG_LL_OMAP7XX(p, mach)					\
+	_DEBUG_LL_ENTRY(mach, OMAP1_UART1_BASE, OMAP7XX_PORT_SHIFT,	\
+		OMAP1_UART##p##_BASE, OMAP7XX_PORT_SHIFT, OMAP1UART##p)
 
-		if (check_port(uart, shift))
-			break;
-		/* Silent boot if no serial ports are enabled. */
-		return;
-	} while (0);
-#endif /* CONFIG_ARCH_OMAP1 */
-#endif
+#define DEBUG_LL_OMAP1(p, mach)						\
+	_DEBUG_LL_ENTRY(mach, OMAP1_UART1_BASE, OMAP_PORT_SHIFT,	\
+		OMAP1_UART##p##_BASE, OMAP_PORT_SHIFT, OMAP1UART##p)
+
+#define DEBUG_LL_OMAP2(p, mach)						\
+	_DEBUG_LL_ENTRY(mach, OMAP2_UART1_BASE, OMAP_PORT_SHIFT,	\
+		OMAP2_UART##p##_BASE, OMAP_PORT_SHIFT, OMAP2UART##p)
+
+#define DEBUG_LL_OMAP3(p, mach)						\
+	_DEBUG_LL_ENTRY(mach, OMAP3_UART1_BASE, OMAP_PORT_SHIFT,	\
+		OMAP3_UART##p##_BASE, OMAP_PORT_SHIFT, OMAP3UART##p)
+
+#define DEBUG_LL_OMAP4(p, mach)						\
+	_DEBUG_LL_ENTRY(mach, OMAP4_UART1_BASE, OMAP_PORT_SHIFT,	\
+		OMAP4_UART##p##_BASE, OMAP_PORT_SHIFT, OMAP4UART##p)
+
+/* Zoom2/3 shift is different for UART1 and external port */
+#define DEBUG_LL_ZOOM(mach)						\
+	_DEBUG_LL_ENTRY(mach, OMAP2_UART1_BASE, OMAP_PORT_SHIFT,	\
+		ZOOM_UART_BASE, ZOOM_PORT_SHIFT, ZOOM_UART)
+
+static inline void __arch_decomp_setup(unsigned long arch_id)
+{
+	int port = 0;
 
 	/*
-	 * Now, xmit each character
+	 * Initialize the port based on the machine ID from the bootloader.
+	 * Note that we're using macros here instead of switch statement
+	 * as machine_is functions are optimized out for the boards that
+	 * are not selected.
 	 */
-	while (!(uart[UART_LSR << shift] & UART_LSR_THRE))
-		barrier();
-	uart[UART_TX << shift] = c;
-}
+	do {
+		/* omap7xx/8xx based boards using UART1 with shift 0 */
+		DEBUG_LL_OMAP7XX(1, herald);
+		DEBUG_LL_OMAP7XX(1, omap_perseus2);
 
-static inline void flush(void)
-{
+		/* omap15xx/16xx based boards using UART1 */
+		DEBUG_LL_OMAP1(1, ams_delta);
+		DEBUG_LL_OMAP1(1, nokia770);
+		DEBUG_LL_OMAP1(1, omap_h2);
+		DEBUG_LL_OMAP1(1, omap_h3);
+		DEBUG_LL_OMAP1(1, omap_innovator);
+		DEBUG_LL_OMAP1(1, omap_osk);
+		DEBUG_LL_OMAP1(1, omap_palmte);
+		DEBUG_LL_OMAP1(1, omap_palmz71);
+
+		/* omap15xx/16xx based boards using UART2 */
+		DEBUG_LL_OMAP1(2, omap_palmtt);
+
+		/* omap15xx/16xx based boards using UART3 */
+		DEBUG_LL_OMAP1(3, sx1);
+
+		/* omap2 based boards using UART1 */
+		DEBUG_LL_OMAP2(1, omap2evm);
+		DEBUG_LL_OMAP2(1, omap_2430sdp);
+		DEBUG_LL_OMAP2(1, omap_apollon);
+		DEBUG_LL_OMAP2(1, omap_h4);
+
+		/* omap2 based boards using UART3 */
+		DEBUG_LL_OMAP2(3, nokia_n800);
+		DEBUG_LL_OMAP2(3, nokia_n810);
+		DEBUG_LL_OMAP2(3, nokia_n810_wimax);
+
+		/* omap3 based boards using UART1 */
+		DEBUG_LL_OMAP2(1, omap3evm);
+		DEBUG_LL_OMAP3(1, omap_3430sdp);
+		DEBUG_LL_OMAP3(1, omap_3630sdp);
+
+		/* omap3 based boards using UART3 */
+		DEBUG_LL_OMAP3(3, cm_t35);
+		DEBUG_LL_OMAP3(3, igep0020);
+		DEBUG_LL_OMAP3(3, nokia_rx51);
+		DEBUG_LL_OMAP3(3, omap3517evm);
+		DEBUG_LL_OMAP3(3, omap3_beagle);
+		DEBUG_LL_OMAP3(3, omap3_pandora);
+		DEBUG_LL_OMAP3(3, omap_ldp);
+		DEBUG_LL_OMAP3(3, overo);
+		DEBUG_LL_OMAP3(3, touchbook);
+
+		/* omap4 based boards using UART3 */
+		DEBUG_LL_OMAP4(3, omap_4430sdp);
+
+		/* zoom2/3 external uart */
+		DEBUG_LL_ZOOM(omap_zoom2);
+		DEBUG_LL_ZOOM(omap_zoom3);
+
+	} while (0);
 }
 
+#define arch_decomp_setup()	__arch_decomp_setup(arch_id)
+
 /*
  * nothing to do
  */
-#define arch_decomp_setup()
 #define arch_decomp_wdog()
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/usb.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/usb.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/usb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/include/plat/usb.h	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
 #ifndef	__ASM_ARCH_OMAP_USB_H
 #define	__ASM_ARCH_OMAP_USB_H
 
+#include <linux/usb/musb.h>
 #include <plat/board.h>
 
 #define OMAP3_HS_USB_PORTS	3
@@ -42,9 +43,17 @@ struct ehci_hcd_omap_platform_data {
 #define UDC_BASE			OMAP2_UDC_BASE
 #define OMAP_OHCI_BASE			OMAP2_OHCI_BASE
 
-extern void usb_musb_init(void);
+struct omap_musb_board_data {
+	u8	interface_type;
+	u8	mode;
+	u16	power;
+};
 
-extern void usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata);
+enum musb_interface    {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI};
+
+extern void usb_musb_init(struct omap_musb_board_data *board_data);
+
+extern void usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata);
 
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/io.c linux-libre-2.6.34-gnu1/arch/arm/plat-omap/io.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/io.c	2010-05-16 17:17:36.000000000 -0400
@@ -90,8 +90,6 @@ void __iomem *omap_ioremap(unsigned long
 			return XLATE(p, L3_34XX_PHYS, L3_34XX_VIRT);
 		if (BETWEEN(p, L4_34XX_PHYS, L4_34XX_SIZE))
 			return XLATE(p, L4_34XX_PHYS, L4_34XX_VIRT);
-		if (BETWEEN(p, L4_WK_34XX_PHYS, L4_WK_34XX_SIZE))
-			return XLATE(p, L4_WK_34XX_PHYS, L4_WK_34XX_VIRT);
 		if (BETWEEN(p, OMAP34XX_GPMC_PHYS, OMAP34XX_GPMC_SIZE))
 			return XLATE(p, OMAP34XX_GPMC_PHYS, OMAP34XX_GPMC_VIRT);
 		if (BETWEEN(p, OMAP343X_SMS_PHYS, OMAP343X_SMS_SIZE))
@@ -110,8 +108,6 @@ void __iomem *omap_ioremap(unsigned long
 			return XLATE(p, L3_44XX_PHYS, L3_44XX_VIRT);
 		if (BETWEEN(p, L4_44XX_PHYS, L4_44XX_SIZE))
 			return XLATE(p, L4_44XX_PHYS, L4_44XX_VIRT);
-		if (BETWEEN(p, L4_WK_44XX_PHYS, L4_WK_44XX_SIZE))
-			return XLATE(p, L4_WK_44XX_PHYS, L4_WK_44XX_VIRT);
 		if (BETWEEN(p, OMAP44XX_GPMC_PHYS, OMAP44XX_GPMC_SIZE))
 			return XLATE(p, OMAP44XX_GPMC_PHYS, OMAP44XX_GPMC_VIRT);
 		if (BETWEEN(p, OMAP44XX_EMIF1_PHYS, OMAP44XX_EMIF1_SIZE))
@@ -128,7 +124,7 @@ void __iomem *omap_ioremap(unsigned long
 			return XLATE(p, L4_EMU_44XX_PHYS, L4_EMU_44XX_VIRT);
 	}
 #endif
-	return __arm_ioremap(p, size, type);
+	return __arm_ioremap_caller(p, size, type, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(omap_ioremap);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/iommu.c linux-libre-2.6.34-gnu1/arch/arm/plat-omap/iommu.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/iommu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/iommu.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * omap iommu: tlb and pagetable primitives
  *
- * Copyright (C) 2008-2009 Nokia Corporation
+ * Copyright (C) 2008-2010 Nokia Corporation
  *
  * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>,
  *		Paul Mundt and Toshihiro Kobayashi
@@ -13,6 +13,7 @@
 
 #include <linux/err.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/clk.h>
@@ -646,7 +647,7 @@ static size_t iopgtable_clear_entry_core
 		if (*iopte & IOPTE_LARGE) {
 			nent *= 16;
 			/* rewind to the 1st entry */
-			iopte = (u32 *)((u32)iopte & IOLARGE_MASK);
+			iopte = iopte_offset(iopgd, (da & IOLARGE_MASK));
 		}
 		bytes *= nent;
 		memset(iopte, 0, nent * sizeof(*iopte));
@@ -667,7 +668,7 @@ static size_t iopgtable_clear_entry_core
 		if ((*iopgd & IOPGD_SUPER) == IOPGD_SUPER) {
 			nent *= 16;
 			/* rewind to the 1st entry */
-			iopgd = (u32 *)((u32)iopgd & IOSUPER_MASK);
+			iopgd = iopgd_offset(obj, (da & IOSUPER_MASK));
 		}
 		bytes *= nent;
 	}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/iommu-debug.c linux-libre-2.6.34-gnu1/arch/arm/plat-omap/iommu-debug.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/iommu-debug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/iommu-debug.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/platform_device.h>
 #include <linux/debugfs.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/iopgtable.h linux-libre-2.6.34-gnu1/arch/arm/plat-omap/iopgtable.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/iopgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/iopgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * omap iommu: pagetable definitions
  *
- * Copyright (C) 2008-2009 Nokia Corporation
+ * Copyright (C) 2008-2010 Nokia Corporation
  *
  * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
  *
@@ -13,26 +13,52 @@
 #ifndef __PLAT_OMAP_IOMMU_H
 #define __PLAT_OMAP_IOMMU_H
 
+/*
+ * "L2 table" address mask and size definitions.
+ */
 #define IOPGD_SHIFT		20
-#define IOPGD_SIZE		(1 << IOPGD_SHIFT)
+#define IOPGD_SIZE		(1UL << IOPGD_SHIFT)
 #define IOPGD_MASK		(~(IOPGD_SIZE - 1))
-#define IOSECTION_MASK		IOPGD_MASK
-#define PTRS_PER_IOPGD		(1 << (32 - IOPGD_SHIFT))
-#define IOPGD_TABLE_SIZE	(PTRS_PER_IOPGD * sizeof(u32))
 
-#define IOSUPER_SIZE		(IOPGD_SIZE << 4)
+/*
+ * "section" address mask and size definitions.
+ */
+#define IOSECTION_SHIFT		20
+#define IOSECTION_SIZE		(1UL << IOSECTION_SHIFT)
+#define IOSECTION_MASK		(~(IOSECTION_SIZE - 1))
+
+/*
+ * "supersection" address mask and size definitions.
+ */
+#define IOSUPER_SHIFT		24
+#define IOSUPER_SIZE		(1UL << IOSUPER_SHIFT)
 #define IOSUPER_MASK		(~(IOSUPER_SIZE - 1))
 
+#define PTRS_PER_IOPGD		(1UL << (32 - IOPGD_SHIFT))
+#define IOPGD_TABLE_SIZE	(PTRS_PER_IOPGD * sizeof(u32))
+
+/*
+ * "small page" address mask and size definitions.
+ */
 #define IOPTE_SHIFT		12
-#define IOPTE_SIZE		(1 << IOPTE_SHIFT)
+#define IOPTE_SIZE		(1UL << IOPTE_SHIFT)
 #define IOPTE_MASK		(~(IOPTE_SIZE - 1))
-#define IOPAGE_MASK		IOPTE_MASK
-#define PTRS_PER_IOPTE		(1 << (IOPGD_SHIFT - IOPTE_SHIFT))
-#define IOPTE_TABLE_SIZE	(PTRS_PER_IOPTE * sizeof(u32))
 
-#define IOLARGE_SIZE		(IOPTE_SIZE << 4)
+/*
+ * "large page" address mask and size definitions.
+ */
+#define IOLARGE_SHIFT		16
+#define IOLARGE_SIZE		(1UL << IOLARGE_SHIFT)
 #define IOLARGE_MASK		(~(IOLARGE_SIZE - 1))
 
+#define PTRS_PER_IOPTE		(1UL << (IOPGD_SHIFT - IOPTE_SHIFT))
+#define IOPTE_TABLE_SIZE	(PTRS_PER_IOPTE * sizeof(u32))
+
+#define IOPAGE_MASK		IOPTE_MASK
+
+/*
+ * some descriptor attributes.
+ */
 #define IOPGD_TABLE		(1 << 0)
 #define IOPGD_SECTION		(2 << 0)
 #define IOPGD_SUPER		(1 << 18 | 2 << 0)
@@ -40,12 +66,14 @@
 #define IOPTE_SMALL		(2 << 0)
 #define IOPTE_LARGE		(1 << 0)
 
+/* to find an entry in a page-table-directory */
 #define iopgd_index(da)		(((da) >> IOPGD_SHIFT) & (PTRS_PER_IOPGD - 1))
 #define iopgd_offset(obj, da)	((obj)->iopgd + iopgd_index(da))
 
 #define iopte_paddr(iopgd)	(*iopgd & ~((1 << 10) - 1))
 #define iopte_vaddr(iopgd)	((u32 *)phys_to_virt(iopte_paddr(iopgd)))
 
+/* to find an entry in the second-level page table. */
 #define iopte_index(da)		(((da) >> IOPTE_SHIFT) & (PTRS_PER_IOPTE - 1))
 #define iopte_offset(iopgd, da)	(iopte_vaddr(iopgd) + iopte_index(da))
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/iovmm.c linux-libre-2.6.34-gnu1/arch/arm/plat-omap/iovmm.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/iovmm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/iovmm.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/device.h>
 #include <linux/scatterlist.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/Kconfig linux-libre-2.6.34-gnu1/arch/arm/plat-omap/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -7,27 +7,37 @@ config ARCH_OMAP_OTG
 
 choice
 	prompt "OMAP System Type"
-	default ARCH_OMAP1
+	default ARCH_OMAP2PLUS
 
 config ARCH_OMAP1
 	bool "TI OMAP1"
 	select COMMON_CLKDEV
+	help
+	  "Systems based on omap7xx, omap15xx or omap16xx"
+
+config ARCH_OMAP2PLUS
+	bool "TI OMAP2/3/4"
+	select COMMON_CLKDEV
+	help
+	  "Systems based on omap24xx, omap34xx or omap44xx"
 
 config ARCH_OMAP2
 	bool "TI OMAP2"
+	depends on ARCH_OMAP2PLUS
 	select CPU_V6
-	select COMMON_CLKDEV
 
 config ARCH_OMAP3
 	bool "TI OMAP3"
+	depends on ARCH_OMAP2PLUS
 	select CPU_V7
-	select COMMON_CLKDEV
+	select USB_ARCH_HAS_EHCI
+	select ARM_L1_CACHE_SHIFT_6
 
 config ARCH_OMAP4
 	bool "TI OMAP4"
+	depends on ARCH_OMAP2PLUS
 	select CPU_V7
 	select ARM_GIC
-	select COMMON_CLKDEV
 
 endchoice
 
@@ -116,7 +126,7 @@ config OMAP_MPU_TIMER
 
 config OMAP_32K_TIMER
 	bool "Use 32KHz timer"
-	depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX || ARCH_OMAP4
+	depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
 	help
 	  Select this option if you want to enable the OMAP 32KHz timer.
 	  This timer saves power compared to the OMAP_MPU_TIMER, and has
@@ -126,6 +136,23 @@ config OMAP_32K_TIMER
 
 endchoice
 
+config OMAP3_L2_AUX_SECURE_SAVE_RESTORE
+	bool "OMAP3 HS/EMU save and restore for L2 AUX control register"
+	depends on ARCH_OMAP3 && PM
+	default n
+	help
+	  Without this option, L2 Auxiliary control register contents are
+	  lost during off-mode entry on HS/EMU devices. This feature
+	  requires support from PPA / boot-loader in HS/EMU devices, which
+	  currently does not exist by default.
+
+config OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
+	int "Service ID for the support routine to set L2 AUX control"
+	depends on OMAP3_L2_AUX_SECURE_SAVE_RESTORE
+	default 43
+	help
+	  PPA routine service ID for setting L2 auxiliary control register.
+
 config OMAP_32K_TIMER_HZ
 	int "Kernel internal timer frequency for 32KHz timer"
 	range 32 1024
@@ -137,29 +164,10 @@ config OMAP_32K_TIMER_HZ
 
 config OMAP_DM_TIMER
 	bool "Use dual-mode timer"
-	depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX || ARCH_OMAP4
+	depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
 	help
 	 Select this option if you want to use OMAP Dual-Mode timers.
 
-choice
-	prompt "Low-level debug console UART"
-	depends on ARCH_OMAP
-	default OMAP_LL_DEBUG_NONE
-
-config OMAP_LL_DEBUG_UART1
-	bool "UART1"
-
-config OMAP_LL_DEBUG_UART2
-	bool "UART2"
-
-config OMAP_LL_DEBUG_UART3
-	bool "UART3"
-
-config OMAP_LL_DEBUG_NONE
-	bool "None"
-
-endchoice
-
 config OMAP_SERIAL_WAKE
 	bool "Enable wake-up events for serial ports"
 	depends on ARCH_OMAP1 && OMAP_MUX
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/mailbox.c linux-libre-2.6.34-gnu1/arch/arm/plat-omap/mailbox.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/mailbox.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/mailbox.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,9 +25,11 @@
 #include <linux/interrupt.h>
 #include <linux/device.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <plat/mailbox.h>
 
+static struct workqueue_struct *mboxd;
 static struct omap_mbox *mboxes;
 static DEFINE_RWLOCK(mboxes_lock);
 
@@ -188,7 +190,7 @@ static void __mbox_rx_interrupt(struct o
 	/* no more messages in the fifo. clear IRQ source. */
 	ack_mbox_irq(mbox, IRQ_RX);
 nomem:
-	schedule_work(&mbox->rxq->work);
+	queue_work(mboxd, &mbox->rxq->work);
 }
 
 static irqreturn_t mbox_interrupt(int irq, void *p)
@@ -401,12 +403,17 @@ EXPORT_SYMBOL(omap_mbox_unregister);
 
 static int __init omap_mbox_init(void)
 {
+	mboxd = create_workqueue("mboxd");
+	if (!mboxd)
+		return -ENOMEM;
+
 	return 0;
 }
 module_init(omap_mbox_init);
 
 static void __exit omap_mbox_exit(void)
 {
+	destroy_workqueue(mboxd);
 }
 module_exit(omap_mbox_exit);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/mcbsp.c linux-libre-2.6.34-gnu1/arch/arm/plat-omap/mcbsp.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/mcbsp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/mcbsp.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,68 +23,102 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <plat/dma.h>
 #include <plat/mcbsp.h>
 
+#include "../mach-omap2/cm-regbits-34xx.h"
+
 struct omap_mcbsp **mcbsp_ptr;
-int omap_mcbsp_count;
+int omap_mcbsp_count, omap_mcbsp_cache_size;
 
-void omap_mcbsp_write(void __iomem *io_base, u16 reg, u32 val)
+void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
 {
-	if (cpu_class_is_omap1() || cpu_is_omap2420())
-		__raw_writew((u16)val, io_base + reg);
-	else
-		__raw_writel(val, io_base + reg);
+	if (cpu_class_is_omap1()) {
+		((u16 *)mcbsp->reg_cache)[reg / sizeof(u16)] = (u16)val;
+		__raw_writew((u16)val, mcbsp->io_base + reg);
+	} else if (cpu_is_omap2420()) {
+		((u16 *)mcbsp->reg_cache)[reg / sizeof(u32)] = (u16)val;
+		__raw_writew((u16)val, mcbsp->io_base + reg);
+	} else {
+		((u32 *)mcbsp->reg_cache)[reg / sizeof(u32)] = val;
+		__raw_writel(val, mcbsp->io_base + reg);
+	}
 }
 
-int omap_mcbsp_read(void __iomem *io_base, u16 reg)
+int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache)
 {
-	if (cpu_class_is_omap1() || cpu_is_omap2420())
-		return __raw_readw(io_base + reg);
-	else
-		return __raw_readl(io_base + reg);
+	if (cpu_class_is_omap1()) {
+		return !from_cache ? __raw_readw(mcbsp->io_base + reg) :
+				((u16 *)mcbsp->reg_cache)[reg / sizeof(u16)];
+	} else if (cpu_is_omap2420()) {
+		return !from_cache ? __raw_readw(mcbsp->io_base + reg) :
+				((u16 *)mcbsp->reg_cache)[reg / sizeof(u32)];
+	} else {
+		return !from_cache ? __raw_readl(mcbsp->io_base + reg) :
+				((u32 *)mcbsp->reg_cache)[reg / sizeof(u32)];
+	}
 }
 
-#define OMAP_MCBSP_READ(base, reg) \
-			omap_mcbsp_read(base, OMAP_MCBSP_REG_##reg)
-#define OMAP_MCBSP_WRITE(base, reg, val) \
-			omap_mcbsp_write(base, OMAP_MCBSP_REG_##reg, val)
+#ifdef CONFIG_ARCH_OMAP3
+void omap_mcbsp_st_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
+{
+	__raw_writel(val, mcbsp->st_data->io_base_st + reg);
+}
+
+int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
+{
+	return __raw_readl(mcbsp->st_data->io_base_st + reg);
+}
+#endif
+
+#define MCBSP_READ(mcbsp, reg) \
+		omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 0)
+#define MCBSP_WRITE(mcbsp, reg, val) \
+		omap_mcbsp_write(mcbsp, OMAP_MCBSP_REG_##reg, val)
+#define MCBSP_READ_CACHE(mcbsp, reg) \
+		omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1)
 
 #define omap_mcbsp_check_valid_id(id)	(id < omap_mcbsp_count)
 #define id_to_mcbsp_ptr(id)		mcbsp_ptr[id];
 
+#define MCBSP_ST_READ(mcbsp, reg) \
+			omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg)
+#define MCBSP_ST_WRITE(mcbsp, reg, val) \
+			omap_mcbsp_st_write(mcbsp, OMAP_ST_REG_##reg, val)
+
 static void omap_mcbsp_dump_reg(u8 id)
 {
 	struct omap_mcbsp *mcbsp = id_to_mcbsp_ptr(id);
 
 	dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id);
 	dev_dbg(mcbsp->dev, "DRR2:  0x%04x\n",
-			OMAP_MCBSP_READ(mcbsp->io_base, DRR2));
+			MCBSP_READ(mcbsp, DRR2));
 	dev_dbg(mcbsp->dev, "DRR1:  0x%04x\n",
-			OMAP_MCBSP_READ(mcbsp->io_base, DRR1));
+			MCBSP_READ(mcbsp, DRR1));
 	dev_dbg(mcbsp->dev, "DXR2:  0x%04x\n",
-			OMAP_MCBSP_READ(mcbsp->io_base, DXR2));
+			MCBSP_READ(mcbsp, DXR2));
 	dev_dbg(mcbsp->dev, "DXR1:  0x%04x\n",
-			OMAP_MCBSP_READ(mcbsp->io_base, DXR1));
+			MCBSP_READ(mcbsp, DXR1));
 	dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n",
-			OMAP_MCBSP_READ(mcbsp->io_base, SPCR2));
+			MCBSP_READ(mcbsp, SPCR2));
 	dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n",
-			OMAP_MCBSP_READ(mcbsp->io_base, SPCR1));
+			MCBSP_READ(mcbsp, SPCR1));
 	dev_dbg(mcbsp->dev, "RCR2:  0x%04x\n",
-			OMAP_MCBSP_READ(mcbsp->io_base, RCR2));
+			MCBSP_READ(mcbsp, RCR2));
 	dev_dbg(mcbsp->dev, "RCR1:  0x%04x\n",
-			OMAP_MCBSP_READ(mcbsp->io_base, RCR1));
+			MCBSP_READ(mcbsp, RCR1));
 	dev_dbg(mcbsp->dev, "XCR2:  0x%04x\n",
-			OMAP_MCBSP_READ(mcbsp->io_base, XCR2));
+			MCBSP_READ(mcbsp, XCR2));
 	dev_dbg(mcbsp->dev, "XCR1:  0x%04x\n",
-			OMAP_MCBSP_READ(mcbsp->io_base, XCR1));
+			MCBSP_READ(mcbsp, XCR1));
 	dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n",
-			OMAP_MCBSP_READ(mcbsp->io_base, SRGR2));
+			MCBSP_READ(mcbsp, SRGR2));
 	dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n",
-			OMAP_MCBSP_READ(mcbsp->io_base, SRGR1));
+			MCBSP_READ(mcbsp, SRGR1));
 	dev_dbg(mcbsp->dev, "PCR0:  0x%04x\n",
-			OMAP_MCBSP_READ(mcbsp->io_base, PCR0));
+			MCBSP_READ(mcbsp, PCR0));
 	dev_dbg(mcbsp->dev, "***********************\n");
 }
 
@@ -93,15 +127,14 @@ static irqreturn_t omap_mcbsp_tx_irq_han
 	struct omap_mcbsp *mcbsp_tx = dev_id;
 	u16 irqst_spcr2;
 
-	irqst_spcr2 = OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2);
+	irqst_spcr2 = MCBSP_READ(mcbsp_tx, SPCR2);
 	dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", irqst_spcr2);
 
 	if (irqst_spcr2 & XSYNC_ERR) {
 		dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n",
 			irqst_spcr2);
 		/* Writing zero to XSYNC_ERR clears the IRQ */
-		OMAP_MCBSP_WRITE(mcbsp_tx->io_base, SPCR2,
-			irqst_spcr2 & ~(XSYNC_ERR));
+		MCBSP_WRITE(mcbsp_tx, SPCR2, MCBSP_READ_CACHE(mcbsp_tx, SPCR2));
 	} else {
 		complete(&mcbsp_tx->tx_irq_completion);
 	}
@@ -114,15 +147,14 @@ static irqreturn_t omap_mcbsp_rx_irq_han
 	struct omap_mcbsp *mcbsp_rx = dev_id;
 	u16 irqst_spcr1;
 
-	irqst_spcr1 = OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR1);
+	irqst_spcr1 = MCBSP_READ(mcbsp_rx, SPCR1);
 	dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", irqst_spcr1);
 
 	if (irqst_spcr1 & RSYNC_ERR) {
 		dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n",
 			irqst_spcr1);
 		/* Writing zero to RSYNC_ERR clears the IRQ */
-		OMAP_MCBSP_WRITE(mcbsp_rx->io_base, SPCR1,
-			irqst_spcr1 & ~(RSYNC_ERR));
+		MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1));
 	} else {
 		complete(&mcbsp_rx->tx_irq_completion);
 	}
@@ -135,7 +167,7 @@ static void omap_mcbsp_tx_dma_callback(i
 	struct omap_mcbsp *mcbsp_dma_tx = data;
 
 	dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n",
-		OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
+		MCBSP_READ(mcbsp_dma_tx, SPCR2));
 
 	/* We can free the channels */
 	omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
@@ -149,7 +181,7 @@ static void omap_mcbsp_rx_dma_callback(i
 	struct omap_mcbsp *mcbsp_dma_rx = data;
 
 	dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n",
-		OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
+		MCBSP_READ(mcbsp_dma_rx, SPCR2));
 
 	/* We can free the channels */
 	omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
@@ -167,7 +199,6 @@ static void omap_mcbsp_rx_dma_callback(i
 void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
 {
 	struct omap_mcbsp *mcbsp;
-	void __iomem *io_base;
 
 	if (!omap_mcbsp_check_valid_id(id)) {
 		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
@@ -175,30 +206,280 @@ void omap_mcbsp_config(unsigned int id,
 	}
 	mcbsp = id_to_mcbsp_ptr(id);
 
-	io_base = mcbsp->io_base;
 	dev_dbg(mcbsp->dev, "Configuring McBSP%d  phys_base: 0x%08lx\n",
 			mcbsp->id, mcbsp->phys_base);
 
 	/* We write the given config */
-	OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
-	OMAP_MCBSP_WRITE(io_base, SPCR1, config->spcr1);
-	OMAP_MCBSP_WRITE(io_base, RCR2, config->rcr2);
-	OMAP_MCBSP_WRITE(io_base, RCR1, config->rcr1);
-	OMAP_MCBSP_WRITE(io_base, XCR2, config->xcr2);
-	OMAP_MCBSP_WRITE(io_base, XCR1, config->xcr1);
-	OMAP_MCBSP_WRITE(io_base, SRGR2, config->srgr2);
-	OMAP_MCBSP_WRITE(io_base, SRGR1, config->srgr1);
-	OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2);
-	OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1);
-	OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0);
+	MCBSP_WRITE(mcbsp, SPCR2, config->spcr2);
+	MCBSP_WRITE(mcbsp, SPCR1, config->spcr1);
+	MCBSP_WRITE(mcbsp, RCR2, config->rcr2);
+	MCBSP_WRITE(mcbsp, RCR1, config->rcr1);
+	MCBSP_WRITE(mcbsp, XCR2, config->xcr2);
+	MCBSP_WRITE(mcbsp, XCR1, config->xcr1);
+	MCBSP_WRITE(mcbsp, SRGR2, config->srgr2);
+	MCBSP_WRITE(mcbsp, SRGR1, config->srgr1);
+	MCBSP_WRITE(mcbsp, MCR2, config->mcr2);
+	MCBSP_WRITE(mcbsp, MCR1, config->mcr1);
+	MCBSP_WRITE(mcbsp, PCR0, config->pcr0);
 	if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
-		OMAP_MCBSP_WRITE(io_base, XCCR, config->xccr);
-		OMAP_MCBSP_WRITE(io_base, RCCR, config->rccr);
+		MCBSP_WRITE(mcbsp, XCCR, config->xccr);
+		MCBSP_WRITE(mcbsp, RCCR, config->rccr);
 	}
 }
 EXPORT_SYMBOL(omap_mcbsp_config);
 
-#ifdef CONFIG_ARCH_OMAP34XX
+#ifdef CONFIG_ARCH_OMAP3
+static void omap_st_on(struct omap_mcbsp *mcbsp)
+{
+	unsigned int w;
+
+	/*
+	 * Sidetone uses McBSP ICLK - which must not idle when sidetones
+	 * are enabled or sidetones start sounding ugly.
+	 */
+	w = cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
+	w &= ~(1 << (mcbsp->id - 2));
+	cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
+
+	/* Enable McBSP Sidetone */
+	w = MCBSP_READ(mcbsp, SSELCR);
+	MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN);
+
+	w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
+	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w & ~(ST_AUTOIDLE));
+
+	/* Enable Sidetone from Sidetone Core */
+	w = MCBSP_ST_READ(mcbsp, SSELCR);
+	MCBSP_ST_WRITE(mcbsp, SSELCR, w | ST_SIDETONEEN);
+}
+
+static void omap_st_off(struct omap_mcbsp *mcbsp)
+{
+	unsigned int w;
+
+	w = MCBSP_ST_READ(mcbsp, SSELCR);
+	MCBSP_ST_WRITE(mcbsp, SSELCR, w & ~(ST_SIDETONEEN));
+
+	w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
+	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w | ST_AUTOIDLE);
+
+	w = MCBSP_READ(mcbsp, SSELCR);
+	MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN));
+
+	w = cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
+	w |= 1 << (mcbsp->id - 2);
+	cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
+}
+
+static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
+{
+	u16 val, i;
+
+	val = MCBSP_ST_READ(mcbsp, SYSCONFIG);
+	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, val & ~(ST_AUTOIDLE));
+
+	val = MCBSP_ST_READ(mcbsp, SSELCR);
+
+	if (val & ST_COEFFWREN)
+		MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
+
+	MCBSP_ST_WRITE(mcbsp, SSELCR, val | ST_COEFFWREN);
+
+	for (i = 0; i < 128; i++)
+		MCBSP_ST_WRITE(mcbsp, SFIRCR, fir[i]);
+
+	i = 0;
+
+	val = MCBSP_ST_READ(mcbsp, SSELCR);
+	while (!(val & ST_COEFFWRDONE) && (++i < 1000))
+		val = MCBSP_ST_READ(mcbsp, SSELCR);
+
+	MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
+
+	if (i == 1000)
+		dev_err(mcbsp->dev, "McBSP FIR load error!\n");
+}
+
+static void omap_st_chgain(struct omap_mcbsp *mcbsp)
+{
+	u16 w;
+	struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+
+	w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
+	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w & ~(ST_AUTOIDLE));
+
+	w = MCBSP_ST_READ(mcbsp, SSELCR);
+
+	MCBSP_ST_WRITE(mcbsp, SGAINCR, ST_CH0GAIN(st_data->ch0gain) | \
+		      ST_CH1GAIN(st_data->ch1gain));
+}
+
+int omap_st_set_chgain(unsigned int id, int channel, s16 chgain)
+{
+	struct omap_mcbsp *mcbsp;
+	struct omap_mcbsp_st_data *st_data;
+	int ret = 0;
+
+	if (!omap_mcbsp_check_valid_id(id)) {
+		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+		return -ENODEV;
+	}
+
+	mcbsp = id_to_mcbsp_ptr(id);
+	st_data = mcbsp->st_data;
+
+	if (!st_data)
+		return -ENOENT;
+
+	spin_lock_irq(&mcbsp->lock);
+	if (channel == 0)
+		st_data->ch0gain = chgain;
+	else if (channel == 1)
+		st_data->ch1gain = chgain;
+	else
+		ret = -EINVAL;
+
+	if (st_data->enabled)
+		omap_st_chgain(mcbsp);
+	spin_unlock_irq(&mcbsp->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(omap_st_set_chgain);
+
+int omap_st_get_chgain(unsigned int id, int channel, s16 *chgain)
+{
+	struct omap_mcbsp *mcbsp;
+	struct omap_mcbsp_st_data *st_data;
+	int ret = 0;
+
+	if (!omap_mcbsp_check_valid_id(id)) {
+		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+		return -ENODEV;
+	}
+
+	mcbsp = id_to_mcbsp_ptr(id);
+	st_data = mcbsp->st_data;
+
+	if (!st_data)
+		return -ENOENT;
+
+	spin_lock_irq(&mcbsp->lock);
+	if (channel == 0)
+		*chgain = st_data->ch0gain;
+	else if (channel == 1)
+		*chgain = st_data->ch1gain;
+	else
+		ret = -EINVAL;
+	spin_unlock_irq(&mcbsp->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(omap_st_get_chgain);
+
+static int omap_st_start(struct omap_mcbsp *mcbsp)
+{
+	struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+
+	if (st_data && st_data->enabled && !st_data->running) {
+		omap_st_fir_write(mcbsp, st_data->taps);
+		omap_st_chgain(mcbsp);
+
+		if (!mcbsp->free) {
+			omap_st_on(mcbsp);
+			st_data->running = 1;
+		}
+	}
+
+	return 0;
+}
+
+int omap_st_enable(unsigned int id)
+{
+	struct omap_mcbsp *mcbsp;
+	struct omap_mcbsp_st_data *st_data;
+
+	if (!omap_mcbsp_check_valid_id(id)) {
+		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+		return -ENODEV;
+	}
+
+	mcbsp = id_to_mcbsp_ptr(id);
+	st_data = mcbsp->st_data;
+
+	if (!st_data)
+		return -ENODEV;
+
+	spin_lock_irq(&mcbsp->lock);
+	st_data->enabled = 1;
+	omap_st_start(mcbsp);
+	spin_unlock_irq(&mcbsp->lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(omap_st_enable);
+
+static int omap_st_stop(struct omap_mcbsp *mcbsp)
+{
+	struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+
+	if (st_data && st_data->running) {
+		if (!mcbsp->free) {
+			omap_st_off(mcbsp);
+			st_data->running = 0;
+		}
+	}
+
+	return 0;
+}
+
+int omap_st_disable(unsigned int id)
+{
+	struct omap_mcbsp *mcbsp;
+	struct omap_mcbsp_st_data *st_data;
+	int ret = 0;
+
+	if (!omap_mcbsp_check_valid_id(id)) {
+		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+		return -ENODEV;
+	}
+
+	mcbsp = id_to_mcbsp_ptr(id);
+	st_data = mcbsp->st_data;
+
+	if (!st_data)
+		return -ENODEV;
+
+	spin_lock_irq(&mcbsp->lock);
+	omap_st_stop(mcbsp);
+	st_data->enabled = 0;
+	spin_unlock_irq(&mcbsp->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(omap_st_disable);
+
+int omap_st_is_enabled(unsigned int id)
+{
+	struct omap_mcbsp *mcbsp;
+	struct omap_mcbsp_st_data *st_data;
+
+	if (!omap_mcbsp_check_valid_id(id)) {
+		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+		return -ENODEV;
+	}
+
+	mcbsp = id_to_mcbsp_ptr(id);
+	st_data = mcbsp->st_data;
+
+	if (!st_data)
+		return -ENODEV;
+
+
+	return st_data->enabled;
+}
+EXPORT_SYMBOL(omap_st_is_enabled);
+
 /*
  * omap_mcbsp_set_tx_threshold configures how to deal
  * with transmit threshold. the threshold value and handler can be
@@ -207,7 +488,6 @@ EXPORT_SYMBOL(omap_mcbsp_config);
 void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
 {
 	struct omap_mcbsp *mcbsp;
-	void __iomem *io_base;
 
 	if (!cpu_is_omap34xx())
 		return;
@@ -217,9 +497,8 @@ void omap_mcbsp_set_tx_threshold(unsigne
 		return;
 	}
 	mcbsp = id_to_mcbsp_ptr(id);
-	io_base = mcbsp->io_base;
 
-	OMAP_MCBSP_WRITE(io_base, THRSH2, threshold);
+	MCBSP_WRITE(mcbsp, THRSH2, threshold);
 }
 EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold);
 
@@ -231,7 +510,6 @@ EXPORT_SYMBOL(omap_mcbsp_set_tx_threshol
 void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
 {
 	struct omap_mcbsp *mcbsp;
-	void __iomem *io_base;
 
 	if (!cpu_is_omap34xx())
 		return;
@@ -241,9 +519,8 @@ void omap_mcbsp_set_rx_threshold(unsigne
 		return;
 	}
 	mcbsp = id_to_mcbsp_ptr(id);
-	io_base = mcbsp->io_base;
 
-	OMAP_MCBSP_WRITE(io_base, THRSH1, threshold);
+	MCBSP_WRITE(mcbsp, THRSH1, threshold);
 }
 EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold);
 
@@ -313,19 +590,18 @@ static inline void omap34xx_mcbsp_reques
 	if (cpu_is_omap34xx()) {
 		u16 syscon;
 
-		syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON);
+		syscon = MCBSP_READ(mcbsp, SYSCON);
 		syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
 
 		if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
 			syscon |= (ENAWAKEUP | SIDLEMODE(0x02) |
 					CLOCKACTIVITY(0x02));
-			OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN,
-					XRDYEN | RRDYEN);
+			MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
 		} else {
 			syscon |= SIDLEMODE(0x01);
 		}
 
-		OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
+		MCBSP_WRITE(mcbsp, SYSCON, syscon);
 	}
 }
 
@@ -337,7 +613,7 @@ static inline void omap34xx_mcbsp_free(s
 	if (cpu_is_omap34xx()) {
 		u16 syscon;
 
-		syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON);
+		syscon = MCBSP_READ(mcbsp, SYSCON);
 		syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
 		/*
 		 * HW bug workaround - If no_idle mode is taken, we need to
@@ -345,17 +621,19 @@ static inline void omap34xx_mcbsp_free(s
 		 * device will not hit retention anymore.
 		 */
 		syscon |= SIDLEMODE(0x02);
-		OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
+		MCBSP_WRITE(mcbsp, SYSCON, syscon);
 
 		syscon &= ~(SIDLEMODE(0x03));
-		OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
+		MCBSP_WRITE(mcbsp, SYSCON, syscon);
 
-		OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN, 0);
+		MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
 	}
 }
 #else
 static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) {}
 static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) {}
+static inline void omap_st_start(struct omap_mcbsp *mcbsp) {}
+static inline void omap_st_stop(struct omap_mcbsp *mcbsp) {}
 #endif
 
 /*
@@ -392,6 +670,7 @@ EXPORT_SYMBOL(omap_mcbsp_set_io_type);
 int omap_mcbsp_request(unsigned int id)
 {
 	struct omap_mcbsp *mcbsp;
+	void *reg_cache;
 	int err;
 
 	if (!omap_mcbsp_check_valid_id(id)) {
@@ -400,15 +679,21 @@ int omap_mcbsp_request(unsigned int id)
 	}
 	mcbsp = id_to_mcbsp_ptr(id);
 
+	reg_cache = kzalloc(omap_mcbsp_cache_size, GFP_KERNEL);
+	if (!reg_cache) {
+		return -ENOMEM;
+	}
+
 	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 -EBUSY;
+		err = -EBUSY;
+		goto err_kfree;
 	}
 
 	mcbsp->free = 0;
+	mcbsp->reg_cache = reg_cache;
 	spin_unlock(&mcbsp->lock);
 
 	if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
@@ -424,8 +709,8 @@ int omap_mcbsp_request(unsigned int id)
 	 * Make sure that transmitter, receiver and sample-rate generator are
 	 * not running before activating IRQs.
 	 */
-	OMAP_MCBSP_WRITE(mcbsp->io_base, SPCR1, 0);
-	OMAP_MCBSP_WRITE(mcbsp->io_base, SPCR2, 0);
+	MCBSP_WRITE(mcbsp, SPCR1, 0);
+	MCBSP_WRITE(mcbsp, SPCR2, 0);
 
 	if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
 		/* We need to get IRQs here */
@@ -436,7 +721,7 @@ int omap_mcbsp_request(unsigned int id)
 			dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
 					"for McBSP%d\n", mcbsp->tx_irq,
 					mcbsp->id);
-			goto error;
+			goto err_clk_disable;
 		}
 
 		init_completion(&mcbsp->rx_irq_completion);
@@ -446,16 +731,16 @@ int omap_mcbsp_request(unsigned int id)
 			dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
 					"for McBSP%d\n", mcbsp->rx_irq,
 					mcbsp->id);
-			goto tx_irq;
+			goto err_free_irq;
 		}
 	}
 
 	return 0;
-tx_irq:
+err_free_irq:
 	free_irq(mcbsp->tx_irq, (void *)mcbsp);
-error:
+err_clk_disable:
 	if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
-			mcbsp->pdata->ops->free(id);
+		mcbsp->pdata->ops->free(id);
 
 	/* Do procedure specific to omap34xx arch, if applicable */
 	omap34xx_mcbsp_free(mcbsp);
@@ -463,7 +748,12 @@ error:
 	clk_disable(mcbsp->fclk);
 	clk_disable(mcbsp->iclk);
 
+	spin_lock(&mcbsp->lock);
 	mcbsp->free = 1;
+	mcbsp->reg_cache = NULL;
+err_kfree:
+	spin_unlock(&mcbsp->lock);
+	kfree(reg_cache);
 
 	return err;
 }
@@ -472,6 +762,7 @@ EXPORT_SYMBOL(omap_mcbsp_request);
 void omap_mcbsp_free(unsigned int id)
 {
 	struct omap_mcbsp *mcbsp;
+	void *reg_cache;
 
 	if (!omap_mcbsp_check_valid_id(id)) {
 		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
@@ -494,16 +785,18 @@ void omap_mcbsp_free(unsigned int id)
 		free_irq(mcbsp->tx_irq, (void *)mcbsp);
 	}
 
-	spin_lock(&mcbsp->lock);
-	if (mcbsp->free) {
-		dev_err(mcbsp->dev, "McBSP%d was not reserved\n",
-			mcbsp->id);
-		spin_unlock(&mcbsp->lock);
-		return;
-	}
+	reg_cache = mcbsp->reg_cache;
 
-	mcbsp->free = 1;
+	spin_lock(&mcbsp->lock);
+	if (mcbsp->free)
+		dev_err(mcbsp->dev, "McBSP%d was not reserved\n", mcbsp->id);
+	else
+		mcbsp->free = 1;
+	mcbsp->reg_cache = NULL;
 	spin_unlock(&mcbsp->lock);
+
+	if (reg_cache)
+		kfree(reg_cache);
 }
 EXPORT_SYMBOL(omap_mcbsp_free);
 
@@ -515,7 +808,6 @@ EXPORT_SYMBOL(omap_mcbsp_free);
 void omap_mcbsp_start(unsigned int id, int tx, int rx)
 {
 	struct omap_mcbsp *mcbsp;
-	void __iomem *io_base;
 	int idle;
 	u16 w;
 
@@ -524,28 +816,30 @@ void omap_mcbsp_start(unsigned int id, i
 		return;
 	}
 	mcbsp = id_to_mcbsp_ptr(id);
-	io_base = mcbsp->io_base;
 
-	mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
-	mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
+	if (cpu_is_omap34xx())
+		omap_st_start(mcbsp);
 
-	idle = !((OMAP_MCBSP_READ(io_base, SPCR2) |
-		  OMAP_MCBSP_READ(io_base, SPCR1)) & 1);
+	mcbsp->rx_word_length = (MCBSP_READ_CACHE(mcbsp, RCR1) >> 5) & 0x7;
+	mcbsp->tx_word_length = (MCBSP_READ_CACHE(mcbsp, XCR1) >> 5) & 0x7;
+
+	idle = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
+			MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
 
 	if (idle) {
 		/* Start the sample generator */
-		w = OMAP_MCBSP_READ(io_base, SPCR2);
-		OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
+		w = MCBSP_READ_CACHE(mcbsp, SPCR2);
+		MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 6));
 	}
 
 	/* Enable transmitter and receiver */
 	tx &= 1;
-	w = OMAP_MCBSP_READ(io_base, SPCR2);
-	OMAP_MCBSP_WRITE(io_base, SPCR2, w | tx);
+	w = MCBSP_READ_CACHE(mcbsp, SPCR2);
+	MCBSP_WRITE(mcbsp, SPCR2, w | tx);
 
 	rx &= 1;
-	w = OMAP_MCBSP_READ(io_base, SPCR1);
-	OMAP_MCBSP_WRITE(io_base, SPCR1, w | rx);
+	w = MCBSP_READ_CACHE(mcbsp, SPCR1);
+	MCBSP_WRITE(mcbsp, SPCR1, w | rx);
 
 	/*
 	 * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec
@@ -557,18 +851,18 @@ void omap_mcbsp_start(unsigned int id, i
 
 	if (idle) {
 		/* Start frame sync */
-		w = OMAP_MCBSP_READ(io_base, SPCR2);
-		OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
+		w = MCBSP_READ_CACHE(mcbsp, SPCR2);
+		MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7));
 	}
 
 	if (cpu_is_omap2430() || cpu_is_omap34xx()) {
 		/* Release the transmitter and receiver */
-		w = OMAP_MCBSP_READ(io_base, XCCR);
+		w = MCBSP_READ_CACHE(mcbsp, XCCR);
 		w &= ~(tx ? XDISABLE : 0);
-		OMAP_MCBSP_WRITE(io_base, XCCR, w);
-		w = OMAP_MCBSP_READ(io_base, RCCR);
+		MCBSP_WRITE(mcbsp, XCCR, w);
+		w = MCBSP_READ_CACHE(mcbsp, RCCR);
 		w &= ~(rx ? RDISABLE : 0);
-		OMAP_MCBSP_WRITE(io_base, RCCR, w);
+		MCBSP_WRITE(mcbsp, RCCR, w);
 	}
 
 	/* Dump McBSP Regs */
@@ -579,7 +873,6 @@ EXPORT_SYMBOL(omap_mcbsp_start);
 void omap_mcbsp_stop(unsigned int id, int tx, int rx)
 {
 	struct omap_mcbsp *mcbsp;
-	void __iomem *io_base;
 	int idle;
 	u16 w;
 
@@ -589,36 +882,38 @@ void omap_mcbsp_stop(unsigned int id, in
 	}
 
 	mcbsp = id_to_mcbsp_ptr(id);
-	io_base = mcbsp->io_base;
 
 	/* Reset transmitter */
 	tx &= 1;
 	if (cpu_is_omap2430() || cpu_is_omap34xx()) {
-		w = OMAP_MCBSP_READ(io_base, XCCR);
+		w = MCBSP_READ_CACHE(mcbsp, XCCR);
 		w |= (tx ? XDISABLE : 0);
-		OMAP_MCBSP_WRITE(io_base, XCCR, w);
+		MCBSP_WRITE(mcbsp, XCCR, w);
 	}
-	w = OMAP_MCBSP_READ(io_base, SPCR2);
-	OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~tx);
+	w = MCBSP_READ_CACHE(mcbsp, SPCR2);
+	MCBSP_WRITE(mcbsp, SPCR2, w & ~tx);
 
 	/* Reset receiver */
 	rx &= 1;
 	if (cpu_is_omap2430() || cpu_is_omap34xx()) {
-		w = OMAP_MCBSP_READ(io_base, RCCR);
+		w = MCBSP_READ_CACHE(mcbsp, RCCR);
 		w |= (rx ? RDISABLE : 0);
-		OMAP_MCBSP_WRITE(io_base, RCCR, w);
+		MCBSP_WRITE(mcbsp, RCCR, w);
 	}
-	w = OMAP_MCBSP_READ(io_base, SPCR1);
-	OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~rx);
+	w = MCBSP_READ_CACHE(mcbsp, SPCR1);
+	MCBSP_WRITE(mcbsp, SPCR1, w & ~rx);
 
-	idle = !((OMAP_MCBSP_READ(io_base, SPCR2) |
-		  OMAP_MCBSP_READ(io_base, SPCR1)) & 1);
+	idle = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
+			MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
 
 	if (idle) {
 		/* Reset the sample rate generator */
-		w = OMAP_MCBSP_READ(io_base, SPCR2);
-		OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
+		w = MCBSP_READ_CACHE(mcbsp, SPCR2);
+		MCBSP_WRITE(mcbsp, SPCR2, w & ~(1 << 6));
 	}
+
+	if (cpu_is_omap34xx())
+		omap_st_stop(mcbsp);
 }
 EXPORT_SYMBOL(omap_mcbsp_stop);
 
@@ -626,7 +921,6 @@ EXPORT_SYMBOL(omap_mcbsp_stop);
 int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
 {
 	struct omap_mcbsp *mcbsp;
-	void __iomem *base;
 
 	if (!omap_mcbsp_check_valid_id(id)) {
 		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
@@ -634,28 +928,26 @@ int omap_mcbsp_pollwrite(unsigned int id
 	}
 
 	mcbsp = id_to_mcbsp_ptr(id);
-	base = mcbsp->io_base;
 
-	writew(buf, base + OMAP_MCBSP_REG_DXR1);
+	MCBSP_WRITE(mcbsp, DXR1, buf);
 	/* if frame sync error - clear the error */
-	if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
+	if (MCBSP_READ(mcbsp, SPCR2) & XSYNC_ERR) {
 		/* clear error */
-		writew(readw(base + OMAP_MCBSP_REG_SPCR2) & (~XSYNC_ERR),
-		       base + OMAP_MCBSP_REG_SPCR2);
+		MCBSP_WRITE(mcbsp, SPCR2, MCBSP_READ_CACHE(mcbsp, SPCR2));
 		/* resend */
 		return -1;
 	} else {
 		/* wait for transmit confirmation */
 		int attemps = 0;
-		while (!(readw(base + OMAP_MCBSP_REG_SPCR2) & XRDY)) {
+		while (!(MCBSP_READ(mcbsp, SPCR2) & XRDY)) {
 			if (attemps++ > 1000) {
-				writew(readw(base + OMAP_MCBSP_REG_SPCR2) &
-				       (~XRST),
-				       base + OMAP_MCBSP_REG_SPCR2);
+				MCBSP_WRITE(mcbsp, SPCR2,
+						MCBSP_READ_CACHE(mcbsp, SPCR2) &
+						(~XRST));
 				udelay(10);
-				writew(readw(base + OMAP_MCBSP_REG_SPCR2) |
-				       (XRST),
-				       base + OMAP_MCBSP_REG_SPCR2);
+				MCBSP_WRITE(mcbsp, SPCR2,
+						MCBSP_READ_CACHE(mcbsp, SPCR2) |
+						(XRST));
 				udelay(10);
 				dev_err(mcbsp->dev, "Could not write to"
 					" McBSP%d Register\n", mcbsp->id);
@@ -671,7 +963,6 @@ EXPORT_SYMBOL(omap_mcbsp_pollwrite);
 int omap_mcbsp_pollread(unsigned int id, u16 *buf)
 {
 	struct omap_mcbsp *mcbsp;
-	void __iomem *base;
 
 	if (!omap_mcbsp_check_valid_id(id)) {
 		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
@@ -679,26 +970,24 @@ int omap_mcbsp_pollread(unsigned int id,
 	}
 	mcbsp = id_to_mcbsp_ptr(id);
 
-	base = mcbsp->io_base;
 	/* if frame sync error - clear the error */
-	if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
+	if (MCBSP_READ(mcbsp, SPCR1) & RSYNC_ERR) {
 		/* clear error */
-		writew(readw(base + OMAP_MCBSP_REG_SPCR1) & (~RSYNC_ERR),
-		       base + OMAP_MCBSP_REG_SPCR1);
+		MCBSP_WRITE(mcbsp, SPCR1, MCBSP_READ_CACHE(mcbsp, SPCR1));
 		/* resend */
 		return -1;
 	} else {
 		/* wait for recieve confirmation */
 		int attemps = 0;
-		while (!(readw(base + OMAP_MCBSP_REG_SPCR1) & RRDY)) {
+		while (!(MCBSP_READ(mcbsp, SPCR1) & RRDY)) {
 			if (attemps++ > 1000) {
-				writew(readw(base + OMAP_MCBSP_REG_SPCR1) &
-				       (~RRST),
-				       base + OMAP_MCBSP_REG_SPCR1);
+				MCBSP_WRITE(mcbsp, SPCR1,
+						MCBSP_READ_CACHE(mcbsp, SPCR1) &
+						(~RRST));
 				udelay(10);
-				writew(readw(base + OMAP_MCBSP_REG_SPCR1) |
-				       (RRST),
-				       base + OMAP_MCBSP_REG_SPCR1);
+				MCBSP_WRITE(mcbsp, SPCR1,
+						MCBSP_READ_CACHE(mcbsp, SPCR1) |
+						(RRST));
 				udelay(10);
 				dev_err(mcbsp->dev, "Could not read from"
 					" McBSP%d Register\n", mcbsp->id);
@@ -706,7 +995,7 @@ int omap_mcbsp_pollread(unsigned int id,
 			}
 		}
 	}
-	*buf = readw(base + OMAP_MCBSP_REG_DRR1);
+	*buf = MCBSP_READ(mcbsp, DRR1);
 
 	return 0;
 }
@@ -718,7 +1007,6 @@ EXPORT_SYMBOL(omap_mcbsp_pollread);
 void omap_mcbsp_xmit_word(unsigned int id, u32 word)
 {
 	struct omap_mcbsp *mcbsp;
-	void __iomem *io_base;
 	omap_mcbsp_word_length word_length;
 
 	if (!omap_mcbsp_check_valid_id(id)) {
@@ -727,21 +1015,19 @@ void omap_mcbsp_xmit_word(unsigned int i
 	}
 
 	mcbsp = id_to_mcbsp_ptr(id);
-	io_base = mcbsp->io_base;
 	word_length = mcbsp->tx_word_length;
 
 	wait_for_completion(&mcbsp->tx_irq_completion);
 
 	if (word_length > OMAP_MCBSP_WORD_16)
-		OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
-	OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
+		MCBSP_WRITE(mcbsp, DXR2, word >> 16);
+	MCBSP_WRITE(mcbsp, DXR1, word & 0xffff);
 }
 EXPORT_SYMBOL(omap_mcbsp_xmit_word);
 
 u32 omap_mcbsp_recv_word(unsigned int id)
 {
 	struct omap_mcbsp *mcbsp;
-	void __iomem *io_base;
 	u16 word_lsb, word_msb = 0;
 	omap_mcbsp_word_length word_length;
 
@@ -752,13 +1038,12 @@ u32 omap_mcbsp_recv_word(unsigned int id
 	mcbsp = id_to_mcbsp_ptr(id);
 
 	word_length = mcbsp->rx_word_length;
-	io_base = mcbsp->io_base;
 
 	wait_for_completion(&mcbsp->rx_irq_completion);
 
 	if (word_length > OMAP_MCBSP_WORD_16)
-		word_msb = OMAP_MCBSP_READ(io_base, DRR2);
-	word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
+		word_msb = MCBSP_READ(mcbsp, DRR2);
+	word_lsb = MCBSP_READ(mcbsp, DRR1);
 
 	return (word_lsb | (word_msb << 16));
 }
@@ -767,7 +1052,6 @@ EXPORT_SYMBOL(omap_mcbsp_recv_word);
 int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
 {
 	struct omap_mcbsp *mcbsp;
-	void __iomem *io_base;
 	omap_mcbsp_word_length tx_word_length;
 	omap_mcbsp_word_length rx_word_length;
 	u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
@@ -777,7 +1061,6 @@ int omap_mcbsp_spi_master_xmit_word_poll
 		return -ENODEV;
 	}
 	mcbsp = id_to_mcbsp_ptr(id);
-	io_base = mcbsp->io_base;
 	tx_word_length = mcbsp->tx_word_length;
 	rx_word_length = mcbsp->rx_word_length;
 
@@ -785,14 +1068,16 @@ int omap_mcbsp_spi_master_xmit_word_poll
 		return -EINVAL;
 
 	/* First we wait for the transmitter to be ready */
-	spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
+	spcr2 = MCBSP_READ(mcbsp, SPCR2);
 	while (!(spcr2 & XRDY)) {
-		spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
+		spcr2 = MCBSP_READ(mcbsp, SPCR2);
 		if (attempts++ > 1000) {
 			/* We must reset the transmitter */
-			OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST));
+			MCBSP_WRITE(mcbsp, SPCR2,
+				    MCBSP_READ_CACHE(mcbsp, SPCR2) & (~XRST));
 			udelay(10);
-			OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
+			MCBSP_WRITE(mcbsp, SPCR2,
+				    MCBSP_READ_CACHE(mcbsp, SPCR2) | XRST);
 			udelay(10);
 			dev_err(mcbsp->dev, "McBSP%d transmitter not "
 				"ready\n", mcbsp->id);
@@ -802,18 +1087,20 @@ int omap_mcbsp_spi_master_xmit_word_poll
 
 	/* Now we can push the data */
 	if (tx_word_length > OMAP_MCBSP_WORD_16)
-		OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
-	OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
+		MCBSP_WRITE(mcbsp, DXR2, word >> 16);
+	MCBSP_WRITE(mcbsp, DXR1, word & 0xffff);
 
 	/* We wait for the receiver to be ready */
-	spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
+	spcr1 = MCBSP_READ(mcbsp, SPCR1);
 	while (!(spcr1 & RRDY)) {
-		spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
+		spcr1 = MCBSP_READ(mcbsp, SPCR1);
 		if (attempts++ > 1000) {
 			/* We must reset the receiver */
-			OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST));
+			MCBSP_WRITE(mcbsp, SPCR1,
+				    MCBSP_READ_CACHE(mcbsp, SPCR1) & (~RRST));
 			udelay(10);
-			OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
+			MCBSP_WRITE(mcbsp, SPCR1,
+				    MCBSP_READ_CACHE(mcbsp, SPCR1) | RRST);
 			udelay(10);
 			dev_err(mcbsp->dev, "McBSP%d receiver not "
 				"ready\n", mcbsp->id);
@@ -823,8 +1110,8 @@ int omap_mcbsp_spi_master_xmit_word_poll
 
 	/* Receiver is ready, let's read the dummy data */
 	if (rx_word_length > OMAP_MCBSP_WORD_16)
-		word_msb = OMAP_MCBSP_READ(io_base, DRR2);
-	word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
+		word_msb = MCBSP_READ(mcbsp, DRR2);
+	word_lsb = MCBSP_READ(mcbsp, DRR1);
 
 	return 0;
 }
@@ -834,7 +1121,6 @@ int omap_mcbsp_spi_master_recv_word_poll
 {
 	struct omap_mcbsp *mcbsp;
 	u32 clock_word = 0;
-	void __iomem *io_base;
 	omap_mcbsp_word_length tx_word_length;
 	omap_mcbsp_word_length rx_word_length;
 	u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
@@ -845,7 +1131,6 @@ int omap_mcbsp_spi_master_recv_word_poll
 	}
 
 	mcbsp = id_to_mcbsp_ptr(id);
-	io_base = mcbsp->io_base;
 
 	tx_word_length = mcbsp->tx_word_length;
 	rx_word_length = mcbsp->rx_word_length;
@@ -854,14 +1139,16 @@ int omap_mcbsp_spi_master_recv_word_poll
 		return -EINVAL;
 
 	/* First we wait for the transmitter to be ready */
-	spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
+	spcr2 = MCBSP_READ(mcbsp, SPCR2);
 	while (!(spcr2 & XRDY)) {
-		spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
+		spcr2 = MCBSP_READ(mcbsp, SPCR2);
 		if (attempts++ > 1000) {
 			/* We must reset the transmitter */
-			OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST));
+			MCBSP_WRITE(mcbsp, SPCR2,
+				    MCBSP_READ_CACHE(mcbsp, SPCR2) & (~XRST));
 			udelay(10);
-			OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
+			MCBSP_WRITE(mcbsp, SPCR2,
+				    MCBSP_READ_CACHE(mcbsp, SPCR2) | XRST);
 			udelay(10);
 			dev_err(mcbsp->dev, "McBSP%d transmitter not "
 				"ready\n", mcbsp->id);
@@ -871,18 +1158,20 @@ int omap_mcbsp_spi_master_recv_word_poll
 
 	/* We first need to enable the bus clock */
 	if (tx_word_length > OMAP_MCBSP_WORD_16)
-		OMAP_MCBSP_WRITE(io_base, DXR2, clock_word >> 16);
-	OMAP_MCBSP_WRITE(io_base, DXR1, clock_word & 0xffff);
+		MCBSP_WRITE(mcbsp, DXR2, clock_word >> 16);
+	MCBSP_WRITE(mcbsp, DXR1, clock_word & 0xffff);
 
 	/* We wait for the receiver to be ready */
-	spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
+	spcr1 = MCBSP_READ(mcbsp, SPCR1);
 	while (!(spcr1 & RRDY)) {
-		spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
+		spcr1 = MCBSP_READ(mcbsp, SPCR1);
 		if (attempts++ > 1000) {
 			/* We must reset the receiver */
-			OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST));
+			MCBSP_WRITE(mcbsp, SPCR1,
+				    MCBSP_READ_CACHE(mcbsp, SPCR1) & (~RRST));
 			udelay(10);
-			OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
+			MCBSP_WRITE(mcbsp, SPCR1,
+				    MCBSP_READ_CACHE(mcbsp, SPCR1) | RRST);
 			udelay(10);
 			dev_err(mcbsp->dev, "McBSP%d receiver not "
 				"ready\n", mcbsp->id);
@@ -892,8 +1181,8 @@ int omap_mcbsp_spi_master_recv_word_poll
 
 	/* Receiver is ready, there is something for us */
 	if (rx_word_length > OMAP_MCBSP_WORD_16)
-		word_msb = OMAP_MCBSP_READ(io_base, DRR2);
-	word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
+		word_msb = MCBSP_READ(mcbsp, DRR2);
+	word_lsb = MCBSP_READ(mcbsp, DRR1);
 
 	word[0] = (word_lsb | (word_msb << 16));
 
@@ -1107,7 +1396,7 @@ void omap_mcbsp_set_spi_mode(unsigned in
 }
 EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
 
-#ifdef CONFIG_ARCH_OMAP34XX
+#ifdef CONFIG_ARCH_OMAP3
 #define max_thres(m)			(mcbsp->pdata->buffer_size)
 #define valid_threshold(m, val)		((val) <= max_thres(m))
 #define THRESHOLD_PROP_BUILDER(prop)					\
@@ -1198,6 +1487,64 @@ unlock:
 
 static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
 
+static ssize_t st_taps_show(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
+	struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+	ssize_t status = 0;
+	int i;
+
+	spin_lock_irq(&mcbsp->lock);
+	for (i = 0; i < st_data->nr_taps; i++)
+		status += sprintf(&buf[status], (i ? ", %d" : "%d"),
+				  st_data->taps[i]);
+	if (i)
+		status += sprintf(&buf[status], "\n");
+	spin_unlock_irq(&mcbsp->lock);
+
+	return status;
+}
+
+static ssize_t st_taps_store(struct device *dev,
+			     struct device_attribute *attr,
+			     const char *buf, size_t size)
+{
+	struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
+	struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+	int val, tmp, status, i = 0;
+
+	spin_lock_irq(&mcbsp->lock);
+	memset(st_data->taps, 0, sizeof(st_data->taps));
+	st_data->nr_taps = 0;
+
+	do {
+		status = sscanf(buf, "%d%n", &val, &tmp);
+		if (status < 0 || status == 0) {
+			size = -EINVAL;
+			goto out;
+		}
+		if (val < -32768 || val > 32767) {
+			size = -EINVAL;
+			goto out;
+		}
+		st_data->taps[i++] = val;
+		buf += tmp;
+		if (*buf != ',')
+			break;
+		buf++;
+	} while (1);
+
+	st_data->nr_taps = i;
+
+out:
+	spin_unlock_irq(&mcbsp->lock);
+
+	return size;
+}
+
+static DEVICE_ATTR(st_taps, 0644, st_taps_show, st_taps_store);
+
 static const struct attribute *additional_attrs[] = {
 	&dev_attr_max_tx_thres.attr,
 	&dev_attr_max_rx_thres.attr,
@@ -1219,6 +1566,60 @@ static inline void __devexit omap_additi
 	sysfs_remove_group(&dev->kobj, &additional_attr_group);
 }
 
+static const struct attribute *sidetone_attrs[] = {
+	&dev_attr_st_taps.attr,
+	NULL,
+};
+
+static const struct attribute_group sidetone_attr_group = {
+	.attrs = (struct attribute **)sidetone_attrs,
+};
+
+int __devinit omap_st_add(struct omap_mcbsp *mcbsp)
+{
+	struct omap_mcbsp_platform_data *pdata = mcbsp->pdata;
+	struct omap_mcbsp_st_data *st_data;
+	int err;
+
+	st_data = kzalloc(sizeof(*mcbsp->st_data), GFP_KERNEL);
+	if (!st_data) {
+		err = -ENOMEM;
+		goto err1;
+	}
+
+	st_data->io_base_st = ioremap(pdata->phys_base_st, SZ_4K);
+	if (!st_data->io_base_st) {
+		err = -ENOMEM;
+		goto err2;
+	}
+
+	err = sysfs_create_group(&mcbsp->dev->kobj, &sidetone_attr_group);
+	if (err)
+		goto err3;
+
+	mcbsp->st_data = st_data;
+	return 0;
+
+err3:
+	iounmap(st_data->io_base_st);
+err2:
+	kfree(st_data);
+err1:
+	return err;
+
+}
+
+static void __devexit omap_st_remove(struct omap_mcbsp *mcbsp)
+{
+	struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+
+	if (st_data) {
+		sysfs_remove_group(&mcbsp->dev->kobj, &sidetone_attr_group);
+		iounmap(st_data->io_base_st);
+		kfree(st_data);
+	}
+}
+
 static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
 {
 	mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
@@ -1232,6 +1633,12 @@ static inline void __devinit omap34xx_de
 		if (omap_additional_add(mcbsp->dev))
 			dev_warn(mcbsp->dev,
 				"Unable to create additional controls\n");
+
+		if (mcbsp->id == 2 || mcbsp->id == 3)
+			if (omap_st_add(mcbsp))
+				dev_warn(mcbsp->dev,
+				 "Unable to create sidetone controls\n");
+
 	} else {
 		mcbsp->max_tx_thres = -EINVAL;
 		mcbsp->max_rx_thres = -EINVAL;
@@ -1240,13 +1647,17 @@ static inline void __devinit omap34xx_de
 
 static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
 {
-	if (cpu_is_omap34xx())
+	if (cpu_is_omap34xx()) {
 		omap_additional_remove(mcbsp->dev);
+
+		if (mcbsp->id == 2 || mcbsp->id == 3)
+			omap_st_remove(mcbsp);
+	}
 }
 #else
 static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
 static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {}
-#endif /* CONFIG_ARCH_OMAP34XX */
+#endif /* CONFIG_ARCH_OMAP3 */
 
 /*
  * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/omap_device.c linux-libre-2.6.34-gnu1/arch/arm/plat-omap/omap_device.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/omap_device.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/omap_device.c	2010-05-16 17:17:36.000000000 -0400
@@ -79,6 +79,7 @@
 
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/io.h>
 
@@ -90,6 +91,8 @@
 #define IGNORE_WAKEUP_LAT		1
 
 
+#define OMAP_DEVICE_MAGIC 0xf00dcafe
+
 /* Private functions */
 
 /**
@@ -138,10 +141,22 @@ static int _omap_device_activate(struct
 			 "%llu nsec\n", od->pdev.name, od->pm_lat_level,
 			 act_lat);
 
-		WARN(act_lat > odpl->activate_lat, "omap_device: %s.%d: "
-		     "activate step %d took longer than expected (%llu > %d)\n",
-		     od->pdev.name, od->pdev.id, od->pm_lat_level,
-		     act_lat, odpl->activate_lat);
+		if (act_lat > odpl->activate_lat) {
+			odpl->activate_lat_worst = act_lat;
+			if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
+				odpl->activate_lat = act_lat;
+				pr_warning("omap_device: %s.%d: new worst case "
+					   "activate latency %d: %llu\n",
+					   od->pdev.name, od->pdev.id,
+					   od->pm_lat_level, act_lat);
+			} else
+				pr_warning("omap_device: %s.%d: activate "
+					   "latency %d higher than exptected. "
+					   "(%llu > %d)\n",
+					   od->pdev.name, od->pdev.id,
+					   od->pm_lat_level, act_lat,
+					   odpl->activate_lat);
+		}
 
 		od->dev_wakeup_lat -= odpl->activate_lat;
 	}
@@ -194,10 +209,23 @@ static int _omap_device_deactivate(struc
 			 "%llu nsec\n", od->pdev.name, od->pm_lat_level,
 			 deact_lat);
 
-		WARN(deact_lat > odpl->deactivate_lat, "omap_device: %s.%d: "
-		     "deactivate step %d took longer than expected "
-		     "(%llu > %d)\n", od->pdev.name, od->pdev.id,
-		     od->pm_lat_level, deact_lat, odpl->deactivate_lat);
+		if (deact_lat > odpl->deactivate_lat) {
+			odpl->deactivate_lat_worst = deact_lat;
+			if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
+				odpl->deactivate_lat = deact_lat;
+				pr_warning("omap_device: %s.%d: new worst case "
+					   "deactivate latency %d: %llu\n",
+					   od->pdev.name, od->pdev.id,
+					   od->pm_lat_level, deact_lat);
+			} else
+				pr_warning("omap_device: %s.%d: deactivate "
+					   "latency %d higher than exptected. "
+					   "(%llu > %d)\n",
+					   od->pdev.name, od->pdev.id,
+					   od->pm_lat_level, deact_lat,
+					   odpl->deactivate_lat);
+		}
+
 
 		od->dev_wakeup_lat += odpl->activate_lat;
 
@@ -280,6 +308,7 @@ int omap_device_fill_resources(struct om
  * @pdata_len: amount of memory pointed to by @pdata
  * @pm_lats: pointer to a omap_device_pm_latency array for this device
  * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
+ * @is_early_device: should the device be registered as an early device or not
  *
  * Convenience function for building and registering a single
  * omap_device record, which in turn builds and registers a
@@ -291,7 +320,7 @@ struct omap_device *omap_device_build(co
 				      struct omap_hwmod *oh, void *pdata,
 				      int pdata_len,
 				      struct omap_device_pm_latency *pm_lats,
-				      int pm_lats_cnt)
+				      int pm_lats_cnt, int is_early_device)
 {
 	struct omap_hwmod *ohs[] = { oh };
 
@@ -299,7 +328,8 @@ struct omap_device *omap_device_build(co
 		return ERR_PTR(-EINVAL);
 
 	return omap_device_build_ss(pdev_name, pdev_id, ohs, 1, pdata,
-				    pdata_len, pm_lats, pm_lats_cnt);
+				    pdata_len, pm_lats, pm_lats_cnt,
+				    is_early_device);
 }
 
 /**
@@ -311,6 +341,7 @@ struct omap_device *omap_device_build(co
  * @pdata_len: amount of memory pointed to by @pdata
  * @pm_lats: pointer to a omap_device_pm_latency array for this device
  * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
+ * @is_early_device: should the device be registered as an early device or not
  *
  * Convenience function for building and registering an omap_device
  * subsystem record.  Subsystem records consist of multiple
@@ -322,7 +353,7 @@ struct omap_device *omap_device_build_ss
 					 struct omap_hwmod **ohs, int oh_cnt,
 					 void *pdata, int pdata_len,
 					 struct omap_device_pm_latency *pm_lats,
-					 int pm_lats_cnt)
+					 int pm_lats_cnt, int is_early_device)
 {
 	int ret = -ENOMEM;
 	struct omap_device *od;
@@ -378,7 +409,13 @@ struct omap_device *omap_device_build_ss
 	od->pm_lats = pm_lats;
 	od->pm_lats_cnt = pm_lats_cnt;
 
-	ret = omap_device_register(od);
+	od->magic = OMAP_DEVICE_MAGIC;
+
+	if (is_early_device)
+		ret = omap_early_device_register(od);
+	else
+		ret = omap_device_register(od);
+
 	if (ret)
 		goto odbs_exit4;
 
@@ -399,6 +436,24 @@ odbs_exit1:
 }
 
 /**
+ * omap_early_device_register - register an omap_device as an early platform
+ * device.
+ * @od: struct omap_device * to register
+ *
+ * Register the omap_device structure.  This currently just calls
+ * platform_early_add_device() on the underlying platform_device.
+ * Returns 0 by default.
+ */
+int omap_early_device_register(struct omap_device *od)
+{
+	struct platform_device *devices[1];
+
+	devices[0] = &(od->pdev);
+	early_platform_add_devices(devices, 1);
+	return 0;
+}
+
+/**
  * omap_device_register - register an omap_device with one omap_hwmod
  * @od: struct omap_device * to register
  *
@@ -437,8 +492,8 @@ int omap_device_enable(struct platform_d
 	od = _find_by_pdev(pdev);
 
 	if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
-		WARN(1, "omap_device: %s.%d: omap_device_enable() called from "
-		     "invalid state\n", od->pdev.name, od->pdev.id);
+		WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
+		     od->pdev.name, od->pdev.id, __func__, od->_state);
 		return -EINVAL;
 	}
 
@@ -476,8 +531,8 @@ int omap_device_idle(struct platform_dev
 	od = _find_by_pdev(pdev);
 
 	if (od->_state != OMAP_DEVICE_STATE_ENABLED) {
-		WARN(1, "omap_device: %s.%d: omap_device_idle() called from "
-		     "invalid state\n", od->pdev.name, od->pdev.id);
+		WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
+		     od->pdev.name, od->pdev.id, __func__, od->_state);
 		return -EINVAL;
 	}
 
@@ -509,8 +564,8 @@ int omap_device_shutdown(struct platform
 
 	if (od->_state != OMAP_DEVICE_STATE_ENABLED &&
 	    od->_state != OMAP_DEVICE_STATE_IDLE) {
-		WARN(1, "omap_device: %s.%d: omap_device_shutdown() called "
-		     "from invalid state\n", od->pdev.name, od->pdev.id);
+		WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
+		     od->pdev.name, od->pdev.id, __func__, od->_state);
 		return -EINVAL;
 	}
 
@@ -564,6 +619,18 @@ int omap_device_align_pm_lat(struct plat
 }
 
 /**
+ * omap_device_is_valid - Check if pointer is a valid omap_device
+ * @od: struct omap_device *
+ *
+ * Return whether struct omap_device pointer @od points to a valid
+ * omap_device.
+ */
+bool omap_device_is_valid(struct omap_device *od)
+{
+	return (od && od->magic == OMAP_DEVICE_MAGIC);
+}
+
+/**
  * omap_device_get_pwrdm - return the powerdomain * associated with @od
  * @od: struct omap_device *
  *
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-omap/sram.c linux-libre-2.6.34-gnu1/arch/arm/plat-omap/sram.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-omap/sram.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-omap/sram.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,7 +53,7 @@
 #define OMAP4_SRAM_PUB_PA	(OMAP4_SRAM_PA + 0x4000)
 #define OMAP4_SRAM_PUB_VA	(OMAP4_SRAM_VA + 0x4000)
 
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 #define SRAM_BOOTLOADER_SZ	0x00
 #else
 #define SRAM_BOOTLOADER_SZ	0x80
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-pxa/dma.c linux-libre-2.6.34-gnu1/arch/arm/plat-pxa/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-pxa/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-pxa/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
@@ -244,7 +245,7 @@ static void pxa_dma_init_debugfs(void)
 
 	dbgfs_chan = kmalloc(sizeof(*dbgfs_state) * num_dma_channels,
 			     GFP_KERNEL);
-	if (!dbgfs_state)
+	if (!dbgfs_chan)
 		goto err_alloc;
 
 	chandir = debugfs_create_dir("channels", dbgfs_root);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-pxa/pwm.c linux-libre-2.6.34-gnu1/arch/arm/plat-pxa/pwm.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-pxa/pwm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-pxa/pwm.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/clock.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/clock.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,366 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/clock.c
- *
- * Copyright 2004-2005 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C24XX Core clock control support
- *
- * Based on, and code from linux/arch/arm/mach-versatile/clock.c
- **
- **  Copyright (C) 2004 ARM Limited.
- **  Written by Deep Blue Solutions Limited.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/sysdev.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/clk.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <plat/cpu-freq.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-/* clock information */
-
-static LIST_HEAD(clocks);
-
-/* We originally used an mutex here, but some contexts (see resume)
- * are calling functions such as clk_set_parent() with IRQs disabled
- * causing an BUG to be triggered.
- */
-DEFINE_SPINLOCK(clocks_lock);
-
-/* enable and disable calls for use with the clk struct */
-
-static int clk_null_enable(struct clk *clk, int enable)
-{
-	return 0;
-}
-
-/* Clock API calls */
-
-struct clk *clk_get(struct device *dev, const char *id)
-{
-	struct clk *p;
-	struct clk *clk = ERR_PTR(-ENOENT);
-	int idno;
-
-	if (dev == NULL || dev->bus != &platform_bus_type)
-		idno = -1;
-	else
-		idno = to_platform_device(dev)->id;
-
-	spin_lock(&clocks_lock);
-
-	list_for_each_entry(p, &clocks, list) {
-		if (p->id == idno &&
-		    strcmp(id, p->name) == 0 &&
-		    try_module_get(p->owner)) {
-			clk = p;
-			break;
-		}
-	}
-
-	/* check for the case where a device was supplied, but the
-	 * clock that was being searched for is not device specific */
-
-	if (IS_ERR(clk)) {
-		list_for_each_entry(p, &clocks, list) {
-			if (p->id == -1 && strcmp(id, p->name) == 0 &&
-			    try_module_get(p->owner)) {
-				clk = p;
-				break;
-			}
-		}
-	}
-
-	spin_unlock(&clocks_lock);
-	return clk;
-}
-
-void clk_put(struct clk *clk)
-{
-	module_put(clk->owner);
-}
-
-int clk_enable(struct clk *clk)
-{
-	if (IS_ERR(clk) || clk == NULL)
-		return -EINVAL;
-
-	clk_enable(clk->parent);
-
-	spin_lock(&clocks_lock);
-
-	if ((clk->usage++) == 0)
-		(clk->enable)(clk, 1);
-
-	spin_unlock(&clocks_lock);
-	return 0;
-}
-
-void clk_disable(struct clk *clk)
-{
-	if (IS_ERR(clk) || clk == NULL)
-		return;
-
-	spin_lock(&clocks_lock);
-
-	if ((--clk->usage) == 0)
-		(clk->enable)(clk, 0);
-
-	spin_unlock(&clocks_lock);
-	clk_disable(clk->parent);
-}
-
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	if (IS_ERR(clk))
-		return 0;
-
-	if (clk->rate != 0)
-		return clk->rate;
-
-	if (clk->get_rate != NULL)
-		return (clk->get_rate)(clk);
-
-	if (clk->parent != NULL)
-		return clk_get_rate(clk->parent);
-
-	return clk->rate;
-}
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	if (!IS_ERR(clk) && clk->round_rate)
-		return (clk->round_rate)(clk, rate);
-
-	return rate;
-}
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	int ret;
-
-	if (IS_ERR(clk))
-		return -EINVAL;
-
-	/* We do not default just do a clk->rate = rate as
-	 * the clock may have been made this way by choice.
-	 */
-
-	WARN_ON(clk->set_rate == NULL);
-
-	if (clk->set_rate == NULL)
-		return -EINVAL;
-
-	spin_lock(&clocks_lock);
-	ret = (clk->set_rate)(clk, rate);
-	spin_unlock(&clocks_lock);
-
-	return ret;
-}
-
-struct clk *clk_get_parent(struct clk *clk)
-{
-	return clk->parent;
-}
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	int ret = 0;
-
-	if (IS_ERR(clk))
-		return -EINVAL;
-
-	spin_lock(&clocks_lock);
-
-	if (clk->set_parent)
-		ret = (clk->set_parent)(clk, parent);
-
-	spin_unlock(&clocks_lock);
-
-	return ret;
-}
-
-EXPORT_SYMBOL(clk_get);
-EXPORT_SYMBOL(clk_put);
-EXPORT_SYMBOL(clk_enable);
-EXPORT_SYMBOL(clk_disable);
-EXPORT_SYMBOL(clk_get_rate);
-EXPORT_SYMBOL(clk_round_rate);
-EXPORT_SYMBOL(clk_set_rate);
-EXPORT_SYMBOL(clk_get_parent);
-EXPORT_SYMBOL(clk_set_parent);
-
-/* base clocks */
-
-static int clk_default_setrate(struct clk *clk, unsigned long rate)
-{
-	clk->rate = rate;
-	return 0;
-}
-
-struct clk clk_xtal = {
-	.name		= "xtal",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= NULL,
-	.ctrlbit	= 0,
-};
-
-struct clk clk_ext = {
-	.name		= "ext",
-	.id		= -1,
-};
-
-struct clk clk_epll = {
-	.name		= "epll",
-	.id		= -1,
-};
-
-struct clk clk_mpll = {
-	.name		= "mpll",
-	.id		= -1,
-	.set_rate	= clk_default_setrate,
-};
-
-struct clk clk_upll = {
-	.name		= "upll",
-	.id		= -1,
-	.parent		= NULL,
-	.ctrlbit	= 0,
-};
-
-struct clk clk_f = {
-	.name		= "fclk",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= &clk_mpll,
-	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
-};
-
-struct clk clk_h = {
-	.name		= "hclk",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= NULL,
-	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
-};
-
-struct clk clk_p = {
-	.name		= "pclk",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= NULL,
-	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
-};
-
-struct clk clk_usb_bus = {
-	.name		= "usb-bus",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= &clk_upll,
-};
-
-
-
-struct clk s3c24xx_uclk = {
-	.name		= "uclk",
-	.id		= -1,
-};
-
-/* initialise the clock system */
-
-int s3c24xx_register_clock(struct clk *clk)
-{
-	if (clk->enable == NULL)
-		clk->enable = clk_null_enable;
-
-	/* add to the list of available clocks */
-
-	/* Quick check to see if this clock has already been registered. */
-	BUG_ON(clk->list.prev != clk->list.next);
-
-	spin_lock(&clocks_lock);
-	list_add(&clk->list, &clocks);
-	spin_unlock(&clocks_lock);
-
-	return 0;
-}
-
-int s3c24xx_register_clocks(struct clk **clks, int nr_clks)
-{
-	int fails = 0;
-
-	for (; nr_clks > 0; nr_clks--, clks++) {
-		if (s3c24xx_register_clock(*clks) < 0)
-			fails++;
-	}
-
-	return fails;
-}
-
-/* initalise all the clocks */
-
-int __init s3c24xx_register_baseclocks(unsigned long xtal)
-{
-	printk(KERN_INFO "S3C24XX Clocks, Copyright 2004 Simtec Electronics\n");
-
-	clk_xtal.rate = xtal;
-
-	/* register our clocks */
-
-	if (s3c24xx_register_clock(&clk_xtal) < 0)
-		printk(KERN_ERR "failed to register master xtal\n");
-
-	if (s3c24xx_register_clock(&clk_mpll) < 0)
-		printk(KERN_ERR "failed to register mpll clock\n");
-
-	if (s3c24xx_register_clock(&clk_upll) < 0)
-		printk(KERN_ERR "failed to register upll clock\n");
-
-	if (s3c24xx_register_clock(&clk_f) < 0)
-		printk(KERN_ERR "failed to register cpu fclk\n");
-
-	if (s3c24xx_register_clock(&clk_h) < 0)
-		printk(KERN_ERR "failed to register cpu hclk\n");
-
-	if (s3c24xx_register_clock(&clk_p) < 0)
-		printk(KERN_ERR "failed to register cpu pclk\n");
-
-	return 0;
-}
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-fb.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-fb.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-fb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,73 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-fb.c
- *
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for framebuffer 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/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-#include <linux/fb.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-#include <mach/regs-fb.h>
-
-#include <plat/fb.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_fb_resource[] = {
-	[0] = {
-		.start = S3C_PA_FB,
-		.end   = S3C_PA_FB + SZ_16K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_LCD_VSYNC,
-		.end   = IRQ_LCD_VSYNC,
-		.flags = IORESOURCE_IRQ,
-	},
-	[2] = {
-		.start = IRQ_LCD_FIFO,
-		.end   = IRQ_LCD_FIFO,
-		.flags = IORESOURCE_IRQ,
-	},
-	[3] = {
-		.start = IRQ_LCD_SYSTEM,
-		.end   = IRQ_LCD_SYSTEM,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device s3c_device_fb = {
-	.name		  = "s3c-fb",
-	.id		  = -1,
-	.num_resources	  = ARRAY_SIZE(s3c_fb_resource),
-	.resource	  = s3c_fb_resource,
-	.dev.dma_mask	  = &s3c_device_fb.dev.coherent_dma_mask,
-	.dev.coherent_dma_mask = 0xffffffffUL,
-};
-
-void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
-{
-	struct s3c_fb_platdata *npd;
-
-	if (!pd) {
-		printk(KERN_ERR "%s: no platform data\n", __func__);
-		return;
-	}
-
-	npd = kmemdup(pd, sizeof(struct s3c_fb_platdata), GFP_KERNEL);
-	if (!npd)
-		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
-	s3c_device_fb.dev.platform_data = npd;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-hsmmc1.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-hsmmc1.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-hsmmc1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-hsmmc1.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,68 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-hsmmc1.c
- *
- * Copyright (c) 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for hsmmc device 1
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mmc/host.h>
-
-#include <mach/map.h>
-#include <plat/sdhci.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#define S3C_SZ_HSMMC	(0x1000)
-
-static struct resource s3c_hsmmc1_resource[] = {
-	[0] = {
-		.start = S3C_PA_HSMMC1,
-		.end   = S3C_PA_HSMMC1 + S3C_SZ_HSMMC - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_HSMMC1,
-		.end   = IRQ_HSMMC1,
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-static u64 s3c_device_hsmmc1_dmamask = 0xffffffffUL;
-
-struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
-	.max_width	= 4,
-	.host_caps	= (MMC_CAP_4_BIT_DATA |
-			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-};
-
-struct platform_device s3c_device_hsmmc1 = {
-	.name		= "s3c-sdhci",
-	.id		= 1,
-	.num_resources	= ARRAY_SIZE(s3c_hsmmc1_resource),
-	.resource	= s3c_hsmmc1_resource,
-	.dev		= {
-		.dma_mask		= &s3c_device_hsmmc1_dmamask,
-		.coherent_dma_mask	= 0xffffffffUL,
-		.platform_data		= &s3c_hsmmc1_def_platdata,
-	},
-};
-
-void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
-{
-	struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata;
-
-	set->max_width = pd->max_width;
-
-	if (pd->cfg_gpio)
-		set->cfg_gpio = pd->cfg_gpio;
-	if (pd->cfg_card)
-		set->cfg_card = pd->cfg_card;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-hsmmc2.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-hsmmc2.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-hsmmc2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-hsmmc2.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,69 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-hsmmc2.c
- *
- * Copyright (c) 2009 Samsung Electronics
- * Copyright (c) 2009 Maurus Cuelenaere
- *
- * Based on arch/arm/plat-s3c/dev-hsmmc1.c
- * original file Copyright (c) 2008 Simtec Electronics
- *
- * S3C series device definition for hsmmc device 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mmc/host.h>
-
-#include <mach/map.h>
-#include <plat/sdhci.h>
-#include <plat/devs.h>
-
-#define S3C_SZ_HSMMC	(0x1000)
-
-static struct resource s3c_hsmmc2_resource[] = {
-	[0] = {
-		.start = S3C_PA_HSMMC2,
-		.end   = S3C_PA_HSMMC2 + S3C_SZ_HSMMC - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_HSMMC2,
-		.end   = IRQ_HSMMC2,
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-static u64 s3c_device_hsmmc2_dmamask = 0xffffffffUL;
-
-struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
-	.max_width	= 4,
-	.host_caps	= (MMC_CAP_4_BIT_DATA |
-			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-};
-
-struct platform_device s3c_device_hsmmc2 = {
-	.name		= "s3c-sdhci",
-	.id		= 2,
-	.num_resources	= ARRAY_SIZE(s3c_hsmmc2_resource),
-	.resource	= s3c_hsmmc2_resource,
-	.dev		= {
-		.dma_mask		= &s3c_device_hsmmc2_dmamask,
-		.coherent_dma_mask	= 0xffffffffUL,
-		.platform_data		= &s3c_hsmmc2_def_platdata,
-	},
-};
-
-void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
-{
-	struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
-
-	set->max_width = pd->max_width;
-
-	if (pd->cfg_gpio)
-		set->cfg_gpio = pd->cfg_gpio;
-	if (pd->cfg_card)
-		set->cfg_card = pd->cfg_card;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-hsmmc.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-hsmmc.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-hsmmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-hsmmc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,68 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-hsmmc.c
- *
- * Copyright (c) 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for hsmmc devices
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mmc/host.h>
-
-#include <mach/map.h>
-#include <plat/sdhci.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#define S3C_SZ_HSMMC	(0x1000)
-
-static struct resource s3c_hsmmc_resource[] = {
-	[0] = {
-		.start = S3C_PA_HSMMC0,
-		.end   = S3C_PA_HSMMC0 + S3C_SZ_HSMMC - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_HSMMC0,
-		.end   = IRQ_HSMMC0,
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-static u64 s3c_device_hsmmc_dmamask = 0xffffffffUL;
-
-struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
-	.max_width	= 4,
-	.host_caps	= (MMC_CAP_4_BIT_DATA |
-			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-};
-
-struct platform_device s3c_device_hsmmc0 = {
-	.name		= "s3c-sdhci",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(s3c_hsmmc_resource),
-	.resource	= s3c_hsmmc_resource,
-	.dev		= {
-		.dma_mask		= &s3c_device_hsmmc_dmamask,
-		.coherent_dma_mask	= 0xffffffffUL,
-		.platform_data		= &s3c_hsmmc0_def_platdata,
-	},
-};
-
-void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
-{
-	struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata;
-
-	set->max_width = pd->max_width;
-
-	if (pd->cfg_gpio)
-		set->cfg_gpio = pd->cfg_gpio;
-	if (pd->cfg_card)
-		set->cfg_card = pd->cfg_card;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-i2c0.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-i2c0.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-i2c0.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-i2c0.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,71 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-i2c0.c
- *
- * Copyright 2008-2009 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for i2c device 0
- *
- * This program is free software; you can 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/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-	[0] = {
-		.start = S3C_PA_IIC,
-		.end   = S3C_PA_IIC + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_IIC,
-		.end   = IRQ_IIC,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device s3c_device_i2c0 = {
-	.name		  = "s3c2410-i2c",
-#ifdef CONFIG_S3C_DEV_I2C1
-	.id		  = 0,
-#else
-	.id		  = -1,
-#endif
-	.num_resources	  = ARRAY_SIZE(s3c_i2c_resource),
-	.resource	  = s3c_i2c_resource,
-};
-
-static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
-	.flags		= 0,
-	.slave_addr	= 0x10,
-	.frequency	= 100*1000,
-	.sda_delay	= 100,
-};
-
-void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-	struct s3c2410_platform_i2c *npd;
-
-	if (!pd)
-		pd = &default_i2c_data0;
-
-	npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
-	if (!npd)
-		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-	else if (!npd->cfg_gpio)
-		npd->cfg_gpio = s3c_i2c0_cfg_gpio;
-
-	s3c_device_i2c0.dev.platform_data = npd;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-i2c1.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-i2c1.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-i2c1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-i2c1.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,68 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-i2c1.c
- *
- * Copyright 2008-2009 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for i2c device 1
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-	[0] = {
-		.start = S3C_PA_IIC1,
-		.end   = S3C_PA_IIC1 + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_IIC1,
-		.end   = IRQ_IIC1,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device s3c_device_i2c1 = {
-	.name		  = "s3c2410-i2c",
-	.id		  = 1,
-	.num_resources	  = ARRAY_SIZE(s3c_i2c_resource),
-	.resource	  = s3c_i2c_resource,
-};
-
-static struct s3c2410_platform_i2c default_i2c_data1 __initdata = {
-	.flags		= 0,
-	.bus_num	= 1,
-	.slave_addr	= 0x10,
-	.frequency	= 100*1000,
-	.sda_delay	= 100,
-};
-
-void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-	struct s3c2410_platform_i2c *npd;
-
-	if (!pd)
-		pd = &default_i2c_data1;
-
-	npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
-	if (!npd)
-		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-	else if (!npd->cfg_gpio)
-		npd->cfg_gpio = s3c_i2c1_cfg_gpio;
-
-	s3c_device_i2c1.dev.platform_data = npd;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-nand.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-nand.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-nand.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-nand.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,129 +0,0 @@
-/*
- * S3C series device definition for nand 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/kernel.h>
-#include <linux/platform_device.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#include <mach/map.h>
-#include <plat/devs.h>
-#include <plat/nand.h>
-
-static struct resource s3c_nand_resource[] = {
-	[0] = {
-		.start = S3C_PA_NAND,
-		.end   = S3C_PA_NAND + SZ_1M,
-		.flags = IORESOURCE_MEM,
-	}
-};
-
-struct platform_device s3c_device_nand = {
-	.name		  = "s3c2410-nand",
-	.id		  = -1,
-	.num_resources	  = ARRAY_SIZE(s3c_nand_resource),
-	.resource	  = s3c_nand_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_nand);
-
-/**
- * s3c_nand_copy_set() - copy nand set data
- * @set: The new structure, directly copied from the old.
- *
- * Copy all the fields from the NAND set field from what is probably __initdata
- * to new kernel memory. The code returns 0 if the copy happened correctly or
- * an error code for the calling function to display.
- *
- * Note, we currently do not try and look to see if we've already copied the
- * data in a previous set.
- */
-static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set)
-{
-	void *ptr;
-	int size;
-
-	size = sizeof(struct mtd_partition) * set->nr_partitions;
-	if (size) {
-		ptr = kmemdup(set->partitions, size, GFP_KERNEL);
-		set->partitions = ptr;
-
-		if (!ptr)
-			return -ENOMEM;
-	}
-	
-	if (set->nr_map && set->nr_chips) {
-		size = sizeof(int) * set->nr_chips;
-		ptr = kmemdup(set->nr_map, size, GFP_KERNEL);
-		set->nr_map = ptr;
-
-		if (!ptr)
-			return -ENOMEM;
-	}
-
-	if (set->ecc_layout) {
-		ptr = kmemdup(set->ecc_layout,
-			      sizeof(struct nand_ecclayout), GFP_KERNEL);
-		set->ecc_layout = ptr;
-
-		if (!ptr)
-			return -ENOMEM;
-	}
-	
-	return 0;
-}
-
-void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
-{
-	struct s3c2410_platform_nand *npd;
-	int size;
-	int ret;
-
-	/* note, if we get a failure in allocation, we simply drop out of the
-	 * function. If there is so little memory available at initialisation
-	 * time then there is little chance the system is going to run.
-	 */ 
-
-	npd = kmemdup(nand, sizeof(struct s3c2410_platform_nand), GFP_KERNEL);
-	if (!npd) {
-		printk(KERN_ERR "%s: failed copying platform data\n", __func__);
-		return;
-	}
-
-	/* now see if we need to copy any of the nand set data */
-
-	size = sizeof(struct s3c2410_nand_set) * npd->nr_sets;
-	if (size) {
-		struct s3c2410_nand_set *from = npd->sets;
-		struct s3c2410_nand_set *to;
-		int i;
-
-		to = kmemdup(from, size, GFP_KERNEL);
-		npd->sets = to;	/* set, even if we failed */
-
-		if (!to) {
-			printk(KERN_ERR "%s: no memory for sets\n", __func__);
-			return;
-		}
-		
-		for (i = 0; i < npd->nr_sets; i++) {
-			ret = s3c_nand_copy_set(to);
-			if (ret) {
-				printk(KERN_ERR "%s: failed to copy set %d\n",
-				__func__, i);
-				return;
-			}
-			to++;
-		}
-	}
-
-	s3c_device_nand.dev.platform_data = npd;
-}
-
-EXPORT_SYMBOL_GPL(s3c_nand_set_platdata);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-usb.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-usb.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-usb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,50 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-usb.c
- *
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for USB host
- *
- * This program is free software; you can 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/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-
-
-static struct resource s3c_usb_resource[] = {
-	[0] = {
-		.start = S3C_PA_USBHOST,
-		.end   = S3C_PA_USBHOST + 0x100 - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_USBH,
-		.end   = IRQ_USBH,
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-static u64 s3c_device_usb_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_usb = {
-	.name		  = "s3c2410-ohci",
-	.id		  = -1,
-	.num_resources	  = ARRAY_SIZE(s3c_usb_resource),
-	.resource	  = s3c_usb_resource,
-	.dev              = {
-		.dma_mask = &s3c_device_usb_dmamask,
-		.coherent_dma_mask = 0xffffffffUL
-	}
-};
-
-EXPORT_SYMBOL(s3c_device_usb);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-usb-hsotg.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-usb-hsotg.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-usb-hsotg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dev-usb-hsotg.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-usb-hsotg.c
- *
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for USB high-speed UDC/OtG block
- *
- * This program is free software; you can 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/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-
-static struct resource s3c_usb_hsotg_resources[] = {
-	[0] = {
-		.start	= S3C_PA_USB_HSOTG,
-		.end	= S3C_PA_USB_HSOTG + 0x10000 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_OTG,
-		.end	= IRQ_OTG,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device s3c_device_usb_hsotg = {
-	.name		= "s3c-hsotg",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(s3c_usb_hsotg_resources),
-	.resource	= s3c_usb_hsotg_resources,
-};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dma.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/dma.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,86 +0,0 @@
-/* linux/arch/arm/plat-s3c/dma.c
- *
- * Copyright (c) 2003-2009 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C DMA core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct s3c2410_dma_buf;
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-
-#include <mach/dma.h>
-#include <mach/irqs.h>
-
-#include <plat/dma-plat.h>
-
-/* dma channel state information */
-struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
-struct s3c2410_dma_chan *s3c_dma_chan_map[DMACH_MAX];
-
-/* s3c_dma_lookup_channel
- *
- * change the dma channel number given into a real dma channel id
-*/
-
-struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel)
-{
-	if (channel & DMACH_LOW_LEVEL)
-		return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
-	else
-		return s3c_dma_chan_map[channel];
-}
-
-/* do we need to protect the settings of the fields from
- * irq?
-*/
-
-int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn)
-{
-	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
-	if (chan == NULL)
-		return -EINVAL;
-
-	pr_debug("%s: chan=%p, op rtn=%p\n", __func__, chan, rtn);
-
-	chan->op_fn = rtn;
-
-	return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_set_opfn);
-
-int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn)
-{
-	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
-	if (chan == NULL)
-		return -EINVAL;
-
-	pr_debug("%s: chan=%p, callback rtn=%p\n", __func__, chan, rtn);
-
-	chan->callback_fn = rtn;
-
-	return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
-
-int s3c2410_dma_setflags(unsigned int channel, unsigned int flags)
-{
-	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
-	if (chan == NULL)
-		return -EINVAL;
-
-	chan->flags = flags;
-	return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_setflags);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/gpio.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/gpio.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/gpio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,156 +0,0 @@
-/* linux/arch/arm/plat-s3c/gpio.c
- *
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series GPIO core
- *
- * This program is free software; you can 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 <mach/gpio-core.h>
-
-#ifdef CONFIG_S3C_GPIO_TRACK
-struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
-
-static __init void s3c_gpiolib_track(struct s3c_gpio_chip *chip)
-{
-	unsigned int gpn;
-	int i;
-
-	gpn = chip->chip.base;
-	for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
-		BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
-		s3c_gpios[gpn] = chip;
-	}
-}
-#endif /* CONFIG_S3C_GPIO_TRACK */
-
-/* Default routines for controlling GPIO, based on the original S3C24XX
- * GPIO functions which deal with the case where each gpio bank of the
- * chip is as following:
- *
- * base + 0x00: Control register, 2 bits per gpio
- *	        gpio n: 2 bits starting at (2*n)
- *		00 = input, 01 = output, others mean special-function
- * base + 0x04: Data register, 1 bit per gpio
- *		bit n: data bit n
-*/
-
-static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
-{
-	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-	void __iomem *base = ourchip->base;
-	unsigned long flags;
-	unsigned long con;
-
-	local_irq_save(flags);
-
-	con = __raw_readl(base + 0x00);
-	con &= ~(3 << (offset * 2));
-
-	__raw_writel(con, base + 0x00);
-
-	local_irq_restore(flags);
-	return 0;
-}
-
-static int s3c_gpiolib_output(struct gpio_chip *chip,
-			      unsigned offset, int value)
-{
-	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-	void __iomem *base = ourchip->base;
-	unsigned long flags;
-	unsigned long dat;
-	unsigned long con;
-
-	local_irq_save(flags);
-
-	dat = __raw_readl(base + 0x04);
-	dat &= ~(1 << offset);
-	if (value)
-		dat |= 1 << offset;
-	__raw_writel(dat, base + 0x04);
-
-	con = __raw_readl(base + 0x00);
-	con &= ~(3 << (offset * 2));
-	con |= 1 << (offset * 2);
-
-	__raw_writel(con, base + 0x00);
-	__raw_writel(dat, base + 0x04);
-
-	local_irq_restore(flags);
-	return 0;
-}
-
-static void s3c_gpiolib_set(struct gpio_chip *chip,
-			    unsigned offset, int value)
-{
-	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-	void __iomem *base = ourchip->base;
-	unsigned long flags;
-	unsigned long dat;
-
-	local_irq_save(flags);
-
-	dat = __raw_readl(base + 0x04);
-	dat &= ~(1 << offset);
-	if (value)
-		dat |= 1 << offset;
-	__raw_writel(dat, base + 0x04);
-
-	local_irq_restore(flags);
-}
-
-static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
-{
-	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-	unsigned long val;
-
-	val = __raw_readl(ourchip->base + 0x04);
-	val >>= offset;
-	val &= 1;
-
-	return val;
-}
-
-__init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
-{
-	struct gpio_chip *gc = &chip->chip;
-	int ret;
-
-	BUG_ON(!chip->base);
-	BUG_ON(!gc->label);
-	BUG_ON(!gc->ngpio);
-
-	if (!gc->direction_input)
-		gc->direction_input = s3c_gpiolib_input;
-	if (!gc->direction_output)
-		gc->direction_output = s3c_gpiolib_output;
-	if (!gc->set)
-		gc->set = s3c_gpiolib_set;
-	if (!gc->get)
-		gc->get = s3c_gpiolib_get;
-
-#ifdef CONFIG_PM
-	if (chip->pm != NULL) {
-		if (!chip->pm->save || !chip->pm->resume)
-			printk(KERN_ERR "gpio: %s has missing PM functions\n",
-			       gc->label);
-	} else
-		printk(KERN_ERR "gpio: %s has no PM function\n", gc->label);
-#endif
-
-	/* gpiochip_add() prints own failure message on error. */
-	ret = gpiochip_add(gc);
-	if (ret >= 0)
-		s3c_gpiolib_track(chip);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/gpio-config.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/gpio-config.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/gpio-config.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/gpio-config.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,166 +0,0 @@
-/* linux/arch/arm/plat-s3c/gpio-config.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series GPIO configuration core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-
-#include <mach/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-
-int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
-{
-	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
-	unsigned long flags;
-	int offset;
-	int ret;
-
-	if (!chip)
-		return -EINVAL;
-
-	offset = pin - chip->chip.base;
-
-	local_irq_save(flags);
-	ret = s3c_gpio_do_setcfg(chip, offset, config);
-	local_irq_restore(flags);
-
-	return ret;
-}
-EXPORT_SYMBOL(s3c_gpio_cfgpin);
-
-int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
-{
-	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
-	unsigned long flags;
-	int offset, ret;
-
-	if (!chip)
-		return -EINVAL;
-
-	offset = pin - chip->chip.base;
-
-	local_irq_save(flags);
-	ret = s3c_gpio_do_setpull(chip, offset, pull);
-	local_irq_restore(flags);
-
-	return ret;
-}
-EXPORT_SYMBOL(s3c_gpio_setpull);
-
-#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
-int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
-				  unsigned int off, unsigned int cfg)
-{
-	void __iomem *reg = chip->base;
-	unsigned int shift = off;
-	u32 con;
-
-	if (s3c_gpio_is_cfg_special(cfg)) {
-		cfg &= 0xf;
-
-		/* Map output to 0, and SFN2 to 1 */
-		cfg -= 1;
-		if (cfg > 1)
-			return -EINVAL;
-
-		cfg <<= shift;
-	}
-
-	con = __raw_readl(reg);
-	con &= ~(0x1 << shift);
-	con |= cfg;
-	__raw_writel(con, reg);
-
-	return 0;
-}
-
-int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
-			    unsigned int off, unsigned int cfg)
-{
-	void __iomem *reg = chip->base;
-	unsigned int shift = off * 2;
-	u32 con;
-
-	if (s3c_gpio_is_cfg_special(cfg)) {
-		cfg &= 0xf;
-		if (cfg > 3)
-			return -EINVAL;
-
-		cfg <<= shift;
-	}
-
-	con = __raw_readl(reg);
-	con &= ~(0x3 << shift);
-	con |= cfg;
-	__raw_writel(con, reg);
-
-	return 0;
-}
-#endif
-
-#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
-int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
-				 unsigned int off, unsigned int cfg)
-{
-	void __iomem *reg = chip->base;
-	unsigned int shift = (off & 7) * 4;
-	u32 con;
-
-	if (off < 8 && chip->chip.ngpio > 8)
-		reg -= 4;
-
-	if (s3c_gpio_is_cfg_special(cfg)) {
-		cfg &= 0xf;
-		cfg <<= shift;
-	}
-
-	con = __raw_readl(reg);
-	con &= ~(0xf << shift);
-	con |= cfg;
-	__raw_writel(con, reg);
-
-	return 0;
-}
-#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
-
-#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
-int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
-			    unsigned int off, s3c_gpio_pull_t pull)
-{
-	void __iomem *reg = chip->base + 0x08;
-	int shift = off * 2;
-	u32 pup;
-
-	pup = __raw_readl(reg);
-	pup &= ~(3 << shift);
-	pup |= pull << shift;
-	__raw_writel(pup, reg);
-
-	return 0;
-}
-
-s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
-					unsigned int off)
-{
-	void __iomem *reg = chip->base + 0x08;
-	int shift = off * 2;
-	u32 pup = __raw_readl(reg);
-
-	pup >>= shift;
-	pup &= 0x3;
-	return (__force s3c_gpio_pull_t)pup;
-}
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/mach/io.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/mach/io.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/mach/io.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,18 +0,0 @@
-/* arch/arm/plat-s3c/include/mach/io.h
- *
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben-linux@fluff.org>
- *
- * Default IO routines for plat-s3c based systems, such as S3C24A0
- */
-
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-/* No current ISA/PCI bus support. */
-#define __io(a)		__typesafe_io(a)
-#define __mem_pci(a)	(a)
-
-#define IO_SPACE_LIMIT (0xFFFFFFFF)
-
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/mach/timex.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/mach/timex.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/mach/timex.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/timex.h
- *
- * Copyright (c) 2003-2005 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - time parameters
- *
- * This program is free software; you can 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_TIMEX_H
-#define __ASM_ARCH_TIMEX_H
-
-/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
- * a variable is useless. It seems as long as we make our timers an
- * exact multiple of HZ, any value that makes a 1->1 correspondence
- * for the time conversion functions to/from jiffies is acceptable.
-*/
-
-
-#define CLOCK_TICK_RATE 12000000
-
-
-#endif /* __ASM_ARCH_TIMEX_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,20 +0,0 @@
-/* arch/arm/plat-s3c/include/mach/vmalloc.h
- *
- * from arch/arm/mach-iop3xx/include/mach/vmalloc.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 vmalloc definition
-*/
-
-#ifndef __ASM_ARCH_VMALLOC_H
-#define __ASM_ARCH_VMALLOC_H
-
-#define VMALLOC_END	  (0xE0000000)
-
-#endif /* __ASM_ARCH_VMALLOC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/adc.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/adc.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/adc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/adc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,35 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/adc.h
- *
- * Copyright (c) 2008 Simtec Electronics
- *	http://armlinux.simnte.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C24XX ADC driver 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_PLAT_ADC_H
-#define __ASM_PLAT_ADC_H __FILE__
-
-struct s3c_adc_client;
-
-extern int s3c_adc_start(struct s3c_adc_client *client,
-			 unsigned int channel, unsigned int nr_samples);
-
-extern int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch);
-
-extern struct s3c_adc_client *
-	s3c_adc_register(struct platform_device *pdev,
-			 void (*select)(struct s3c_adc_client *client,
-					unsigned selected),
-			 void (*conv)(struct s3c_adc_client *client,
-				      unsigned d0, unsigned d1,
-				      unsigned *samples_left),
-			 unsigned int is_ts);
-
-extern void s3c_adc_release(struct s3c_adc_client *client);
-
-#endif /* __ASM_PLAT_ADC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/audio.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/audio.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/audio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/audio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/audio.h
- *
- * Copyright (c) 2009 Samsung Electronics Co. Ltd
- * Author: Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-/**
- * struct s3c_audio_pdata - common platform data for audio device drivers
- * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode
- */
-struct s3c_audio_pdata {
-	int (*cfg_gpio)(struct platform_device *);
-};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/audio-simtec.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/audio-simtec.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/audio-simtec.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/audio-simtec.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/audio-simtec.h
- *
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	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.
- *
- * Simtec Audio support.
-*/
-
-/**
- * struct s3c24xx_audio_simtec_pdata - platform data for simtec audio
- * @use_mpllin: Select codec clock from MPLLin
- * @output_cdclk: Need to output CDCLK to the codec
- * @have_mic: Set if we have a MIC socket
- * @have_lout: Set if we have a LineOut socket
- * @amp_gpio: GPIO pin to enable the AMP
- * @amp_gain: Option GPIO to control AMP gain
- */
-struct s3c24xx_audio_simtec_pdata {
-	unsigned int	use_mpllin:1;
-	unsigned int	output_cdclk:1;
-
-	unsigned int	have_mic:1;
-	unsigned int	have_lout:1;
-
-	int		amp_gpio;
-	int		amp_gain[2];
-
-	void	(*startup)(void);
-};
-
-extern int simtec_audio_add(const char *codec_name, bool has_lr_routing,
-			    struct s3c24xx_audio_simtec_pdata *pdata);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/clock.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/clock.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,89 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/clock.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *	http://www.simtec.co.uk/products/SWLINUX/
- *	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.
-*/
-
-#include <linux/spinlock.h>
-
-struct clk {
-	struct list_head      list;
-	struct module        *owner;
-	struct clk           *parent;
-	const char           *name;
-	int		      id;
-	int		      usage;
-	unsigned long         rate;
-	unsigned long         ctrlbit;
-
-	int		    (*enable)(struct clk *, int enable);
-	int		    (*set_rate)(struct clk *c, unsigned long rate);
-	unsigned long	    (*get_rate)(struct clk *c);
-	unsigned long	    (*round_rate)(struct clk *c, unsigned long rate);
-	int		    (*set_parent)(struct clk *c, struct clk *parent);
-};
-
-/* other clocks which may be registered by board support */
-
-extern struct clk s3c24xx_dclk0;
-extern struct clk s3c24xx_dclk1;
-extern struct clk s3c24xx_clkout0;
-extern struct clk s3c24xx_clkout1;
-extern struct clk s3c24xx_uclk;
-
-extern struct clk clk_usb_bus;
-
-/* core clock support */
-
-extern struct clk clk_f;
-extern struct clk clk_h;
-extern struct clk clk_p;
-extern struct clk clk_mpll;
-extern struct clk clk_upll;
-extern struct clk clk_epll;
-extern struct clk clk_xtal;
-extern struct clk clk_ext;
-
-/* S3C64XX specific clocks */
-extern struct clk clk_h2;
-extern struct clk clk_27m;
-extern struct clk clk_48m;
-
-/* exports for arch/arm/mach-s3c2410
- *
- * Please DO NOT use these outside of arch/arm/mach-s3c2410
-*/
-
-extern spinlock_t clocks_lock;
-
-extern int s3c2410_clkcon_enable(struct clk *clk, int enable);
-
-extern int s3c24xx_register_clock(struct clk *clk);
-extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks);
-
-extern int s3c24xx_register_baseclocks(unsigned long xtal);
-
-extern void s3c64xx_register_clocks(void);
-
-extern void s3c24xx_setup_clocks(unsigned long fclk,
-				 unsigned long hclk,
-				 unsigned long pclk);
-
-extern void s3c2410_setup_clocks(void);
-extern void s3c2412_setup_clocks(void);
-extern void s3c244x_setup_clocks(void);
-extern void s3c2443_setup_clocks(void);
-
-/* S3C64XX specific functions and clocks */
-
-extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable);
-
-/* Init for pwm clock code */
-
-extern void s3c_pwmclk_init(void);
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/cpu-freq.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/cpu-freq.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/cpu-freq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/cpu-freq.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,145 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/cpu-freq.h
- *
- * Copyright (c) 2006-2007 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C CPU frequency scaling support - driver and board
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/cpufreq.h>
-
-struct s3c_cpufreq_info;
-struct s3c_cpufreq_board;
-struct s3c_iotimings;
-
-/**
- * struct s3c_freq - frequency information (mainly for core drivers)
- * @fclk: The FCLK frequency in Hz.
- * @armclk: The ARMCLK frequency in Hz.
- * @hclk_tns: HCLK cycle time in 10ths of nano-seconds.
- * @hclk: The HCLK frequency in Hz.
- * @pclk: The PCLK frequency in Hz.
- *
- * This contains the frequency information about the current configuration
- * mainly for the core drivers to ensure we do not end up passing about
- * a large number of parameters.
- *
- * The @hclk_tns field is a useful cache for the parts of the drivers that
- * need to calculate IO timings and suchlike.
- */
-struct s3c_freq {
-	unsigned long	fclk;
-	unsigned long	armclk;
-	unsigned long	hclk_tns;	/* in 10ths of ns */
-	unsigned long	hclk;
-	unsigned long	pclk;
-};
-
-/**
- * struct s3c_cpufreq_freqs - s3c cpufreq notification information.
- * @freqs: The cpufreq setting information.
- * @old: The old clock settings.
- * @new: The new clock settings.
- * @pll_changing: Set if the PLL is changing.
- *
- * Wrapper 'struct cpufreq_freqs' so that any drivers receiving the
- * notification can use this information that is not provided by just
- * having the core frequency alone.
- *
- * The pll_changing flag is used to indicate if the PLL itself is
- * being set during this change. This is important as the clocks
- * will temporarily be set to the XTAL clock during this time, so
- * drivers may want to close down their output during this time.
- *
- * Note, this is not being used by any current drivers and therefore
- * may be removed in the future.
- */
-struct s3c_cpufreq_freqs {
-	struct cpufreq_freqs	freqs;
-	struct s3c_freq		old;
-	struct s3c_freq		new;
-
-	unsigned int		pll_changing:1;
-};
-
-#define to_s3c_cpufreq(_cf) container_of(_cf, struct s3c_cpufreq_freqs, freqs)
-
-/**
- * struct s3c_clkdivs - clock divisor information
- * @p_divisor: Divisor from FCLK to PCLK.
- * @h_divisor: Divisor from FCLK to HCLK.
- * @arm_divisor: Divisor from FCLK to ARMCLK (not all CPUs).
- * @dvs: Non-zero if using DVS mode for ARMCLK.
- *
- * Divisor settings for the core clocks.
- */
-struct s3c_clkdivs {
-	int		p_divisor;
-	int		h_divisor;
-	int		arm_divisor;
-	unsigned char	dvs;
-};
-
-#define PLLVAL(_m, _p, _s) (((_m) << 12) | ((_p) << 4) | (_s))
-
-/**
- * struct s3c_pllval - PLL value entry.
- * @freq: The frequency for this entry in Hz.
- * @pll_reg: The PLL register setting for this PLL value.
- */
-struct s3c_pllval {
-	unsigned long		freq;
-	unsigned long		pll_reg;
-};
-
-/**
- * struct s3c_cpufreq_board - per-board cpu frequency informatin
- * @refresh: The SDRAM refresh period in nanoseconds.
- * @auto_io: Set if the IO timing settings should be generated from the
- *	initialisation time hardware registers.
- * @need_io: Set if the board has external IO on any of the chipselect
- *	lines that will require the hardware timing registers to be
- *	updated on a clock change.
- * @max: The maxium frequency limits for the system. Any field that
- *	is left at zero will use the CPU's settings.
- *
- * This contains the board specific settings that affect how the CPU
- * drivers chose settings. These include the memory refresh and IO
- * timing information.
- *
- * Registration depends on the driver being used, the ARMCLK only
- * implementation does not currently need this but the older style
- * driver requires this to be available.
- */
-struct s3c_cpufreq_board {
-	unsigned int	refresh;
-	unsigned int	auto_io:1;	/* automatically init io timings. */
-	unsigned int	need_io:1;	/* set if needs io timing support. */
-
-	/* any non-zero field in here is taken as an upper limit. */
-	struct s3c_freq	max;	/* frequency limits */
-};
-
-/* Things depending on frequency scaling. */
-#ifdef CONFIG_CPU_FREQ_S3C
-#define __init_or_cpufreq
-#else
-#define __init_or_cpufreq __init
-#endif
-
-/* Board functions */
-
-#ifdef CONFIG_CPU_FREQ_S3C
-extern int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board);
-#else
-
-static inline int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
-{
-	return 0;
-}
-#endif  /* CONFIG_CPU_FREQ_S3C */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/cpu.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/cpu.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/cpu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/cpu.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,81 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/cpu.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for S3C24XX CPU 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.
-*/
-
-/* todo - fix when rmk changes iodescs to use `void __iomem *` */
-
-#ifndef __SAMSUNG_PLAT_CPU_H
-#define __SAMSUNG_PLAT_CPU_H
-
-#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
-
-#ifndef MHZ
-#define MHZ (1000*1000)
-#endif
-
-#define print_mhz(m) ((m) / MHZ), (((m) / 1000) % 1000)
-
-/* forward declaration */
-struct s3c24xx_uart_resources;
-struct platform_device;
-struct s3c2410_uartcfg;
-struct map_desc;
-
-/* per-cpu initialisation function table. */
-
-struct cpu_table {
-	unsigned long	idcode;
-	unsigned long	idmask;
-	void		(*map_io)(void);
-	void		(*init_uarts)(struct s3c2410_uartcfg *cfg, int no);
-	void		(*init_clocks)(int xtal);
-	int		(*init)(void);
-	const char	*name;
-};
-
-extern void s3c_init_cpu(unsigned long idcode,
-			 struct cpu_table *cpus, unsigned int cputab_size);
-
-/* core initialisation functions */
-
-extern void s3c24xx_init_irq(void);
-extern void s3c64xx_init_irq(u32 vic0, u32 vic1);
-
-extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
-extern void s3c64xx_init_io(struct map_desc *mach_desc, int size);
-
-extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c24xx_init_clocks(int xtal);
-
-extern void s3c24xx_init_uartdevs(char *name,
-				  struct s3c24xx_uart_resources *res,
-				  struct s3c2410_uartcfg *cfg, int no);
-
-/* timer for 2410/2440 */
-
-struct sys_timer;
-extern struct sys_timer s3c24xx_timer;
-
-/* system device classes */
-
-extern struct sysdev_class s3c2410_sysclass;
-extern struct sysdev_class s3c2410a_sysclass;
-extern struct sysdev_class s3c2412_sysclass;
-extern struct sysdev_class s3c2440_sysclass;
-extern struct sysdev_class s3c2442_sysclass;
-extern struct sysdev_class s3c2443_sysclass;
-extern struct sysdev_class s3c6410_sysclass;
-extern struct sysdev_class s3c64xx_sysclass;
-
-extern void (*s5pc1xx_idle)(void);
-
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,75 +0,0 @@
-/* linux/include/asm-arm/plat-s3c/debug-macro.S
- *
- * Copyright 2005, 2007 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	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.
-*/
-
-#include <plat/regs-serial.h>
-
-/* The S3C2440 implementations are used by default as they are the
- * most widely re-used */
-
-	.macro fifo_level_s3c2440 rd, rx
-		ldr	\rd, [ \rx, # S3C2410_UFSTAT ]
-		and	\rd, \rd, #S3C2440_UFSTAT_TXMASK
-	.endm
-
-#ifndef fifo_level
-#define fifo_level fifo_level_s3c2440
-#endif
-
-	.macro  fifo_full_s3c2440 rd, rx
-		ldr	\rd, [ \rx, # S3C2410_UFSTAT ]
-		tst	\rd, #S3C2440_UFSTAT_TXFULL
-	.endm
-
-#ifndef fifo_full
-#define fifo_full fifo_full_s3c2440
-#endif
-
-	.macro	senduart,rd,rx
-		strb 	\rd, [\rx, # S3C2410_UTXH ]
-	.endm
-
-	.macro	busyuart, rd, rx
-		ldr	\rd, [ \rx, # S3C2410_UFCON ]
-		tst	\rd, #S3C2410_UFCON_FIFOMODE	@ fifo enabled?
-		beq	1001f				@
-		@ FIFO enabled...
-1003:
-		fifo_full \rd, \rx
-		bne	1003b
-		b	1002f
-
-1001:
-		@ busy waiting for non fifo
-		ldr	\rd, [ \rx, # S3C2410_UTRSTAT ]
-		tst	\rd, #S3C2410_UTRSTAT_TXFE
-		beq	1001b
-
-1002:		@ exit busyuart
-	.endm
-
-	.macro	waituart,rd,rx
-		ldr	\rd, [ \rx, # S3C2410_UFCON ]
-		tst	\rd, #S3C2410_UFCON_FIFOMODE	@ fifo enabled?
-		beq	1001f				@
-		@ FIFO enabled...
-1003:
-		fifo_level \rd, \rx
-		teq	\rd, #0
-		bne	1003b
-		b	1002f
-1001:
-		@ idle waiting for non fifo
-		ldr	\rd, [ \rx, # S3C2410_UTRSTAT ]
-		tst	\rd, #S3C2410_UTRSTAT_TXFE
-		beq	1001b
-
-1002:		@ exit busyuart
-	.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/devs.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/devs.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/devs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/devs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,67 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/devs.h
- *
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2410 standard platform devices
- *
- * This program is free software; you can 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>
-
-struct s3c24xx_uart_resources {
-	struct resource		*resources;
-	unsigned long		 nr_resources;
-};
-
-extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
-extern struct s3c24xx_uart_resources s3c64xx_uart_resources[];
-
-extern struct platform_device *s3c24xx_uart_devs[];
-extern struct platform_device *s3c24xx_uart_src[];
-
-extern struct platform_device s3c_device_timer[];
-
-extern struct platform_device s3c64xx_device_iis0;
-extern struct platform_device s3c64xx_device_iis1;
-extern struct platform_device s3c64xx_device_iisv4;
-
-extern struct platform_device s3c64xx_device_pcm0;
-extern struct platform_device s3c64xx_device_pcm1;
-
-extern struct platform_device s3c_device_ts;
-extern struct platform_device s3c_device_fb;
-extern struct platform_device s3c_device_usb;
-extern struct platform_device s3c_device_lcd;
-extern struct platform_device s3c_device_wdt;
-extern struct platform_device s3c_device_i2c0;
-extern struct platform_device s3c_device_i2c1;
-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_iis;
-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;
-
-extern struct platform_device s3c_device_spi0;
-extern struct platform_device s3c_device_spi1;
-
-extern struct platform_device s3c_device_hwmon;
-
-extern struct platform_device s3c_device_nand;
-
-extern struct platform_device s3c_device_usbgadget;
-extern struct platform_device s3c_device_usb_hsotg;
-
-/* s3c2440 specific devices */
-
-#ifdef CONFIG_CPU_S3C2440
-
-extern struct platform_device s3c_device_camif;
-extern struct platform_device s3c_device_ac97;
-
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/dma-core.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/dma-core.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/dma-core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/dma-core.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,22 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/dma.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * Samsung S3C DMA core 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.
-*/
-
-extern struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel);
-
-extern struct s3c2410_dma_chan *s3c_dma_chan_map[];
-
-/* the currently allocated channel information */
-extern struct s3c2410_dma_chan s3c2410_chans[];
-
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/dma.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/dma.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/dma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/dma.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,127 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/dma.h
- *
- * Copyright (C) 2003-2006 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C DMA 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.
-*/
-
-enum s3c2410_dma_buffresult {
-	S3C2410_RES_OK,
-	S3C2410_RES_ERR,
-	S3C2410_RES_ABORT
-};
-
-enum s3c2410_dmasrc {
-	S3C2410_DMASRC_HW,		/* source is memory */
-	S3C2410_DMASRC_MEM		/* source is hardware */
-};
-
-/* enum s3c2410_chan_op
- *
- * operation codes passed to the DMA code by the user, and also used
- * to inform the current channel owner of any changes to the system state
-*/
-
-enum s3c2410_chan_op {
-	S3C2410_DMAOP_START,
-	S3C2410_DMAOP_STOP,
-	S3C2410_DMAOP_PAUSE,
-	S3C2410_DMAOP_RESUME,
-	S3C2410_DMAOP_FLUSH,
-	S3C2410_DMAOP_TIMEOUT,		/* internal signal to handler */
-	S3C2410_DMAOP_STARTED,		/* indicate channel started */
-};
-
-struct s3c2410_dma_client {
-	char                *name;
-};
-
-struct s3c2410_dma_chan;
-
-/* s3c2410_dma_cbfn_t
- *
- * buffer callback routine type
-*/
-
-typedef void (*s3c2410_dma_cbfn_t)(struct s3c2410_dma_chan *,
-				   void *buf, int size,
-				   enum s3c2410_dma_buffresult result);
-
-typedef int  (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *,
-				   enum s3c2410_chan_op );
-
-
-
-/* s3c2410_dma_request
- *
- * request a dma channel exclusivley
-*/
-
-extern int s3c2410_dma_request(unsigned int channel,
-			       struct s3c2410_dma_client *, void *dev);
-
-
-/* s3c2410_dma_ctrl
- *
- * change the state of the dma channel
-*/
-
-extern int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op);
-
-/* s3c2410_dma_setflags
- *
- * set the channel's flags to a given state
-*/
-
-extern int s3c2410_dma_setflags(unsigned int channel,
-				unsigned int flags);
-
-/* s3c2410_dma_free
- *
- * free the dma channel (will also abort any outstanding operations)
-*/
-
-extern int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *);
-
-/* s3c2410_dma_enqueue
- *
- * place the given buffer onto the queue of operations for the channel.
- * The buffer must be allocated from dma coherent memory, or the Dcache/WB
- * drained before the buffer is given to the DMA system.
-*/
-
-extern int s3c2410_dma_enqueue(unsigned int channel, void *id,
-			       dma_addr_t data, int size);
-
-/* s3c2410_dma_config
- *
- * configure the dma channel
-*/
-
-extern int s3c2410_dma_config(unsigned int channel, int xferunit);
-
-/* s3c2410_dma_devconfig
- *
- * configure the device we're talking to
-*/
-
-extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source,
-				 unsigned long devaddr);
-
-/* s3c2410_dma_getposition
- *
- * get the position that the dma transfer is currently at
-*/
-
-extern int s3c2410_dma_getposition(unsigned int channel,
-				   dma_addr_t *src, dma_addr_t *dest);
-
-extern int s3c2410_dma_set_opfn(unsigned int, s3c2410_dma_opfn_t rtn);
-extern int s3c2410_dma_set_buffdone_fn(unsigned int, s3c2410_dma_cbfn_t rtn);
-
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/fb.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/fb.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/fb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/fb.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,80 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/fb.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C - FB platform data 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 __PLAT_S3C_FB_H
-#define __PLAT_S3C_FB_H __FILE__
-
-/**
- * struct s3c_fb_pd_win - per window setup data
- * @win_mode: The display parameters to initialise (not for window 0)
- * @virtual_x: The virtual X size.
- * @virtual_y: The virtual Y size.
- */
-struct s3c_fb_pd_win {
-	struct fb_videomode	win_mode;
-
-	unsigned short		default_bpp;
-	unsigned short		max_bpp;
-	unsigned short		virtual_x;
-	unsigned short		virtual_y;
-};
-
-/**
- * struct s3c_fb_platdata -  S3C driver platform specific information
- * @setup_gpio: Setup the external GPIO pins to the right state to transfer
- *		the data from the display system to the connected display
- *		device.
- * @vidcon0: The base vidcon0 values to control the panel data format.
- * @vidcon1: The base vidcon1 values to control the panel data output.
- * @win: The setup data for each hardware window, or NULL for unused.
- * @display_mode: The LCD output display mode.
- *
- * The platform data supplies the video driver with all the information
- * it requires to work with the display(s) attached to the machine. It
- * controls the initial mode, the number of display windows (0 is always
- * the base framebuffer) that are initialised etc.
- *
- */
-struct s3c_fb_platdata {
-	void	(*setup_gpio)(void);
-
-	struct s3c_fb_pd_win	*win[S3C_FB_MAX_WIN];
-
-	u32			 vidcon0;
-	u32			 vidcon1;
-};
-
-/**
- * s3c_fb_set_platdata() - Setup the FB device with platform data.
- * @pd: The platform data to set. The data is copied from the passed structure
- *      so the machine data can mark the data __initdata so that any unused
- *      machines will end up dumping their data at runtime.
- */
-extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
-
-/**
- * s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD
- *
- * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
- */
-extern void s3c64xx_fb_gpio_setup_24bpp(void);
-
-/**
- * s5pc100_fb_gpio_setup_24bpp() - S5PC100 setup function for 24bpp LCD
- *
- * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
- */
-extern void s5pc100_fb_gpio_setup_24bpp(void);
-
-#endif /* __PLAT_S3C_FB_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/gpio-cfg.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/gpio-cfg.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/gpio-cfg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/gpio-cfg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,110 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C Platform - GPIO pin configuration
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* This file contains the necessary definitions to get the basic gpio
- * pin configuration done such as setting a pin to input or output or
- * changing the pull-{up,down} configurations.
- */
-
-/* Note, this interface is being added to the s3c64xx arch first and will
- * be added to the s3c24xx systems later.
- */
-
-#ifndef __PLAT_GPIO_CFG_H
-#define __PLAT_GPIO_CFG_H __FILE__
-
-typedef unsigned int __bitwise__ s3c_gpio_pull_t;
-
-/* forward declaration if gpio-core.h hasn't been included */
-struct s3c_gpio_chip;
-
-/**
- * struct s3c_gpio_cfg GPIO configuration
- * @cfg_eint: Configuration setting when used for external interrupt source
- * @get_pull: Read the current pull configuration for the GPIO
- * @set_pull: Set the current pull configuraiton for the GPIO
- * @set_config: Set the current configuration for the GPIO
- * @get_config: Read the current configuration for the GPIO
- *
- * Each chip can have more than one type of GPIO bank available and some
- * have different capabilites even when they have the same control register
- * layouts. Provide an point to vector control routine and provide any
- * per-bank configuration information that other systems such as the
- * external interrupt code will need.
- */
-struct s3c_gpio_cfg {
-	unsigned int	cfg_eint;
-
-	s3c_gpio_pull_t	(*get_pull)(struct s3c_gpio_chip *chip, unsigned offs);
-	int		(*set_pull)(struct s3c_gpio_chip *chip, unsigned offs,
-				    s3c_gpio_pull_t pull);
-
-	unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs);
-	int	 (*set_config)(struct s3c_gpio_chip *chip, unsigned offs,
-			       unsigned config);
-};
-
-#define S3C_GPIO_SPECIAL_MARK	(0xfffffff0)
-#define S3C_GPIO_SPECIAL(x)	(S3C_GPIO_SPECIAL_MARK | (x))
-
-/* Defines for generic pin configurations */
-#define S3C_GPIO_INPUT	(S3C_GPIO_SPECIAL(0))
-#define S3C_GPIO_OUTPUT	(S3C_GPIO_SPECIAL(1))
-#define S3C_GPIO_SFN(x)	(S3C_GPIO_SPECIAL(x))
-
-#define s3c_gpio_is_cfg_special(_cfg) \
-	(((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK)
-
-/**
- * s3c_gpio_cfgpin() - Change the GPIO function of a pin.
- * @pin pin The pin number to configure.
- * @pin to The configuration for the pin's function.
- *
- * Configure which function is actually connected to the external
- * pin, such as an gpio input, output or some form of special function
- * connected to an internal peripheral block.
- */
-extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
-
-/* Define values for the pull-{up,down} available for each gpio pin.
- *
- * These values control the state of the weak pull-{up,down} resistors
- * available on most pins on the S3C series. Not all chips support both
- * up or down settings, and it may be dependant on the chip that is being
- * used to whether the particular mode is available.
- */
-#define S3C_GPIO_PULL_NONE	((__force s3c_gpio_pull_t)0x00)
-#define S3C_GPIO_PULL_DOWN	((__force s3c_gpio_pull_t)0x01)
-#define S3C_GPIO_PULL_UP	((__force s3c_gpio_pull_t)0x02)
-
-/**
- * s3c_gpio_setpull() - set the state of a gpio pin pull resistor
- * @pin: The pin number to configure the pull resistor.
- * @pull: The configuration for the pull resistor.
- *
- * This function sets the state of the pull-{up,down} resistor for the
- * specified pin. It will return 0 if successfull, or a negative error
- * code if the pin cannot support the requested pull setting.
-*/
-extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
-
-/**
- * s3c_gpio_getpull() - get the pull resistor state of a gpio pin
- * @pin: The pin number to get the settings for
- *
- * Read the pull resistor value for the specified pin.
-*/
-extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
-
-#endif /* __PLAT_GPIO_CFG_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,176 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg-helper.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C Platform - GPIO pin configuration helper 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.
-*/
-
-/* This is meant for core cpu support, machine or other driver files
- * should not be including this header.
- */
-
-#ifndef __PLAT_GPIO_CFG_HELPERS_H
-#define __PLAT_GPIO_CFG_HELPERS_H __FILE__
-
-/* As a note, all gpio configuration functions are entered exclusively, either
- * with the relevant lock held or the system prevented from doing anything else
- * by disabling interrupts.
-*/
-
-static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip,
-				     unsigned int off, unsigned int config)
-{
-	return (chip->config->set_config)(chip, off, config);
-}
-
-static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
-				      unsigned int off, s3c_gpio_pull_t pull)
-{
-	return (chip->config->set_pull)(chip, off, pull);
-}
-
-/**
- * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @cfg: The configuration value to set.
- *
- * This helper deal with the GPIO cases where the control register
- * has two bits of configuration per gpio, which have the following
- * functions:
- *	00 = input
- *	01 = output
- *	1x = special function
-*/
-extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
-				   unsigned int off, unsigned int cfg);
-
-/**
- * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A)
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @cfg: The configuration value to set.
- *
- * This helper deal with the GPIO cases where the control register
- * has one bit of configuration for the gpio, where setting the bit
- * means the pin is in special function mode and unset means output.
-*/
-extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
-				     unsigned int off, unsigned int cfg);
-
-/**
- * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @cfg: The configuration value to set.
- *
- * This helper deal with the GPIO cases where the control register has 4 bits
- * of control per GPIO, generally in the form of:
- *	0000 = Input
- *	0001 = Output
- *	others = Special functions (dependant on bank)
- *
- * Note, since the code to deal with the case where there are two control
- * registers instead of one, we do not have a seperate set of functions for
- * each case.
-*/
-extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
-					unsigned int off, unsigned int cfg);
-
-
-/* Pull-{up,down} resistor controls.
- *
- * S3C2410,S3C2440,S3C24A0 = Pull-UP,
- * S3C2412,S3C2413 = Pull-Down
- * S3C6400,S3C6410 = Pull-Both [None,Down,Up,Undef]
- * S3C2443 = Pull-Both [not same as S3C6400]
- */
-
-/**
- * s3c_gpio_setpull_1up() - Pull configuration for choice of up or none.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @param: pull: The pull mode being requested.
- *
- * This is a helper function for the case where we have GPIOs with one
- * bit configuring the presence of a pull-up resistor.
- */
-extern int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
-				unsigned int off, s3c_gpio_pull_t pull);
-
-/**
- * s3c_gpio_setpull_1down() - Pull configuration for choice of down or none
- * @chip: The gpio chip that is being configured
- * @off: The offset for the GPIO being configured
- * @param: pull: The pull mode being requested
- *
- * This is a helper function for the case where we have GPIOs with one
- * bit configuring the presence of a pull-down resistor.
- */
-extern int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
-				  unsigned int off, s3c_gpio_pull_t pull);
-
-/**
- * s3c_gpio_setpull_upown() - Pull configuration for choice of up, down or none
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @param: pull: The pull mode being requested.
- *
- * This is a helper function for the case where we have GPIOs with two
- * bits configuring the presence of a pull resistor, in the following
- * order:
- *	00 = No pull resistor connected
- *	01 = Pull-up resistor connected
- *	10 = Pull-down resistor connected
- */
-extern int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
-				   unsigned int off, s3c_gpio_pull_t pull);
-
-
-/**
- * s3c_gpio_getpull_updown() - Get configuration for choice of up, down or none
- * @chip: The gpio chip that the GPIO pin belongs to
- * @off: The offset to the pin to get the configuration of.
- *
- * This helper function reads the state of the pull-{up,down} resistor for the
- * given GPIO in the same case as s3c_gpio_setpull_upown.
-*/
-extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
-					       unsigned int off);
-
-/**
- * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @param: pull: The pull mode being requested.
- *
- * This is a helper function for the case where we have GPIOs with two
- * bits configuring the presence of a pull resistor, in the following
- * order:
- *	00 = Pull-up resistor connected
- *	10 = Pull-down resistor connected
- *	x1 = No pull up resistor
- */
-extern int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip,
-				    unsigned int off, s3c_gpio_pull_t pull);
-
-/**
- * s3c_gpio_getpull_s3c2443() - Get configuration for s3c2443 pull resistors
- * @chip: The gpio chip that the GPIO pin belongs to.
- * @off: The offset to the pin to get the configuration of.
- *
- * This helper function reads the state of the pull-{up,down} resistor for the
- * given GPIO in the same case as s3c_gpio_setpull_upown.
-*/
-extern s3c_gpio_pull_t s3c_gpio_getpull_s3c24xx(struct s3c_gpio_chip *chip,
-						unsigned int off);
-
-#endif /* __PLAT_GPIO_CFG_HELPERS_H */
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/gpio-core.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/gpio-core.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/gpio-core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/gpio-core.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,107 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/gpio-core.h
- *
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C Platform - GPIO core
- *
- * This program is free software; you can 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 the core gpiolib support functions that the s3c platforms may
- * need to extend or change depending on the hardware and the s3c chip
- * selected at build or found at run time.
- *
- * These definitions are not intended for driver inclusion, there is
- * nothing here that should not live outside the platform and core
- * specific code.
-*/
-
-struct s3c_gpio_chip;
-
-/**
- * struct s3c_gpio_pm - power management (suspend/resume) information
- * @save: Routine to save the state of the GPIO block
- * @resume: Routine to resume the GPIO block.
- */
-struct s3c_gpio_pm {
-	void (*save)(struct s3c_gpio_chip *chip);
-	void (*resume)(struct s3c_gpio_chip *chip);
-};
-
-struct s3c_gpio_cfg;
-
-/**
- * struct s3c_gpio_chip - wrapper for specific implementation of gpio
- * @chip: The chip structure to be exported via gpiolib.
- * @base: The base pointer to the gpio configuration registers.
- * @config: special function and pull-resistor control information.
- * @pm_save: Save information for suspend/resume support.
- *
- * This wrapper provides the necessary information for the Samsung
- * specific gpios being registered with gpiolib.
- */
-struct s3c_gpio_chip {
-	struct gpio_chip	chip;
-	struct s3c_gpio_cfg	*config;
-	struct s3c_gpio_pm	*pm;
-	void __iomem		*base;
-#ifdef CONFIG_PM
-	u32			pm_save[4];
-#endif
-};
-
-static inline struct s3c_gpio_chip *to_s3c_gpio(struct gpio_chip *gpc)
-{
-	return container_of(gpc, struct s3c_gpio_chip, chip);
-}
-
-/** s3c_gpiolib_add() - add the s3c specific version of a gpio_chip.
- * @chip: The chip to register
- *
- * This is a wrapper to gpiochip_add() that takes our specific gpio chip
- * information and makes the necessary alterations for the platform and
- * notes the information for use with the configuration systems and any
- * other parts of the system.
- */
-extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip);
-
-/* CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
- * for use with the configuration calls, and other parts of the s3c gpiolib
- * support code.
- *
- * Not all s3c support code will need this, as some configurations of cpu
- * may only support one or two different configuration options and have an
- * easy gpio to s3c_gpio_chip mapping function. If this is the case, then
- * the machine support file should provide its own s3c_gpiolib_getchip()
- * and any other necessary functions.
- */
-
-#ifdef CONFIG_S3C_GPIO_TRACK
-extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
-
-static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip)
-{
-	return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL;
-}
-#else
-/* machine specific code should provide s3c_gpiolib_getchip */
-
-static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { }
-#endif
-
-#ifdef CONFIG_PM
-extern struct s3c_gpio_pm s3c_gpio_pm_1bit;
-extern struct s3c_gpio_pm s3c_gpio_pm_2bit;
-extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
-#define __gpio_pm(x) x
-#else
-#define s3c_gpio_pm_1bit NULL
-#define s3c_gpio_pm_2bit NULL
-#define s3c_gpio_pm_4bit NULL
-#define __gpio_pm(x) NULL
-
-#endif /* CONFIG_PM */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/hwmon.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/hwmon.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/hwmon.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/hwmon.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/hwmon.h
- *
- * Copyright 2005 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C - HWMon interface for ADC
- *
- * This program is free software; you can 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_ADC_HWMON_H
-#define __ASM_ARCH_ADC_HWMON_H __FILE__
-
-/**
- * s3c_hwmon_chcfg - channel configuration
- * @name: The name to give this channel.
- * @mult: Multiply the ADC value read by this.
- * @div: Divide the value from the ADC by this.
- *
- * The value read from the ADC is converted to a value that
- * hwmon expects (mV) by result = (value_read * @mult) / @div.
- */
-struct s3c_hwmon_chcfg {
-	const char	*name;
-	unsigned int	mult;
-	unsigned int	div;
-};
-
-/**
- * s3c_hwmon_pdata - HWMON platform data
- * @in: One configuration for each possible channel used.
- */
-struct s3c_hwmon_pdata {
-	struct s3c_hwmon_chcfg	*in[8];
-};
-
-#endif /* __ASM_ARCH_ADC_HWMON_H */
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/iic-core.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/iic-core.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/iic-core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/iic-core.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,35 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/iic-core.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C - I2C Controller core functions
- *
- * This program is free software; you can 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_IIC_CORE_H
-#define __ASM_ARCH_IIC_CORE_H __FILE__
-
-/* These functions are only for use with the core support code, such as
- * the cpu specific initialisation code
- */
-
-/* re-define device name depending on support. */
-static inline void s3c_i2c0_setname(char *name)
-{
-	/* currently this device is always compiled in */
-	s3c_device_i2c0.name = name;
-}
-
-static inline void s3c_i2c1_setname(char *name)
-{
-#ifdef CONFIG_S3C_DEV_I2C1
-	s3c_device_i2c1.name = name;
-#endif
-}
-
-#endif /* __ASM_ARCH_IIC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/iic.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/iic.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/iic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/iic.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,62 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/iic.h
- *
- * Copyright 2004-2009 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * 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
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_IIC_H
-#define __ASM_ARCH_IIC_H __FILE__
-
-#define S3C_IICFLG_FILTER	(1<<0)	/* enable s3c2440 filter */
-
-/**
- *	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;
-	unsigned int	flags;
-	unsigned int	slave_addr;
-	unsigned long	frequency;
-	unsigned int	sda_delay;
-
-	void	(*cfg_gpio)(struct platform_device *dev);
-};
-
-/**
- * s3c_i2c0_set_platdata - set platform data for i2c0 device
- * @i2c: The platform data to set, or NULL for default data.
- *
- * Register the given platform data for use with the i2c0 device. This
- * call copies the platform data, so the caller can use __initdata for
- * their copy.
- *
- * This call will set cfg_gpio if is null to the default platform
- * implementation.
- *
- * Any user of s3c_device_i2c0 should call this, even if it is with
- * NULL to ensure that the device is given the default platform data
- * as the driver will no longer carry defaults.
- */
-extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c);
-extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c);
-
-/* defined by architecture to configure gpio */
-extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
-extern void s3c_i2c1_cfg_gpio(struct platform_device *dev);
-
-#endif /* __ASM_ARCH_IIC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/map-base.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/map-base.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/map-base.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/map-base.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,46 +0,0 @@
-/* linux/include/asm-arm/plat-s3c/map.h
- *
- * Copyright 2003, 2007 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C - Memory map definitions (virtual addresses)
- *
- * This program is free software; you can 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_MAP_H
-#define __ASM_PLAT_MAP_H __FILE__
-
-/* Fit all our registers in at 0xF4000000 upwards, trying to use as
- * little of the VA space as possible so vmalloc and friends have a
- * better chance of getting memory.
- *
- * we try to ensure stuff like the IRQ registers are available for
- * an single MOVS instruction (ie, only 8 bits of set data)
- */
-
-#define S3C_ADDR_BASE	(0xF4000000)
-
-#ifndef __ASSEMBLY__
-#define S3C_ADDR(x)	((void __iomem __force *)S3C_ADDR_BASE + (x))
-#else
-#define S3C_ADDR(x)	(S3C_ADDR_BASE + (x))
-#endif
-
-#define S3C_VA_IRQ	S3C_ADDR(0x00000000)	/* irq controller(s) */
-#define S3C_VA_SYS	S3C_ADDR(0x00100000)	/* system control */
-#define S3C_VA_MEM	S3C_ADDR(0x00200000)	/* memory control */
-#define S3C_VA_TIMER	S3C_ADDR(0x00300000)	/* timer block */
-#define S3C_VA_WATCHDOG	S3C_ADDR(0x00400000)	/* watchdog */
-#define S3C_VA_UART	S3C_ADDR(0x01000000)	/* UART */
-
-/* This is used for the CPU specific mappings that may be needed, so that
- * they do not need to directly used S3C_ADDR() and thus make it easier to
- * modify the space for mapping.
- */
-#define S3C_ADDR_CPU(x)	S3C_ADDR(0x00500000 + (x))
-
-#endif /* __ASM_PLAT_MAP_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/nand.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/nand.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/nand.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/nand.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,67 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/nand.h
- *
- * Copyright (c) 2004 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - NAND device controller 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.
-*/
-
-/**
- * struct s3c2410_nand_set - define a set of one or more nand chips
- * @disable_ecc:	Entirely disable ECC - Dangerous
- * @flash_bbt: 		Openmoko u-boot can create a Bad Block Table
- *			Setting this flag will allow the kernel to
- *			look for it at boot time and also skip the NAND
- *			scan.
- * @options:		Default value to set into 'struct nand_chip' options.
- * @nr_chips:		Number of chips in this set
- * @nr_partitions:	Number of partitions pointed to by @partitions
- * @name:		Name of set (optional)
- * @nr_map:		Map for low-layer logical to physical chip numbers (option)
- * @partitions:		The mtd partition list
- *
- * define a set of one or more nand chips registered with an unique mtd. Also
- * allows to pass flag to the underlying NAND layer. 'disable_ecc' will trigger
- * a warning at boot time.
- */
-struct s3c2410_nand_set {
-	unsigned int		disable_ecc:1;
-	unsigned int		flash_bbt:1;
-
-	unsigned int		options;
-	int			nr_chips;
-	int			nr_partitions;
-	char			*name;
-	int			*nr_map;
-	struct mtd_partition	*partitions;
-	struct nand_ecclayout	*ecc_layout;
-};
-
-struct s3c2410_platform_nand {
-	/* timing information for controller, all times in nanoseconds */
-
-	int	tacls;	/* time for active CLE/ALE to nWE/nOE */
-	int	twrph0;	/* active time for nWE/nOE */
-	int	twrph1;	/* time for release CLE/ALE from nWE/nOE inactive */
-
-	unsigned int	ignore_unset_ecc:1;
-
-	int			nr_sets;
-	struct s3c2410_nand_set *sets;
-
-	void			(*select_chip)(struct s3c2410_nand_set *,
-					       int chip);
-};
-
-/**
- * s3c_nand_set_platdata() - register NAND platform data.
- * @nand: The NAND platform data to register with s3c_device_nand.
- *
- * This function copies the given NAND platform data, @nand and registers
- * it with the s3c_device_nand. This allows @nand to be __initdata.
-*/
-extern void s3c_nand_set_platdata(struct s3c2410_platform_nand *nand);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/pm.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/pm.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/pm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/pm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,189 +0,0 @@
-/* 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;
-
-extern unsigned char pm_uart_udivslot;  /* true to save UART UDIVSLOT */
-
-/* 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;
-	u32	udivslot;
-};
-
-/* 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
-
-#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
-/**
- * s3c_pm_debug_smdkled() - Debug PM suspend/resume via SMDK Board LEDs
- * @set: set bits for the state of the LEDs
- * @clear: clear bits for the state of the LEDs.
- */
-extern void s3c_pm_debug_smdkled(u32 set, u32 clear);
-
-#else
-static inline void s3c_pm_debug_smdkled(u32 set, u32 clear) { }
-#endif /* CONFIG_S3C_PM_DEBUG_LED_SMDK */
-
-/* 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.33-gnu1/arch/arm/plat-s3c/include/plat/regs-ac97.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-ac97.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-ac97.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-ac97.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,67 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-ac97.h
- *
- * Copyright (c) 2006 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.
- *
- * S3C2440 AC97 Controller
-*/
-
-#ifndef __ASM_ARCH_REGS_AC97_H
-#define __ASM_ARCH_REGS_AC97_H __FILE__
-
-#define S3C_AC97_GLBCTRL				(0x00)
-
-#define S3C_AC97_GLBCTRL_CODECREADYIE			(1<<22)
-#define S3C_AC97_GLBCTRL_PCMOUTURIE			(1<<21)
-#define S3C_AC97_GLBCTRL_PCMINORIE			(1<<20)
-#define S3C_AC97_GLBCTRL_MICINORIE			(1<<19)
-#define S3C_AC97_GLBCTRL_PCMOUTTIE			(1<<18)
-#define S3C_AC97_GLBCTRL_PCMINTIE			(1<<17)
-#define S3C_AC97_GLBCTRL_MICINTIE			(1<<16)
-#define S3C_AC97_GLBCTRL_PCMOUTTM_OFF			(0<<12)
-#define S3C_AC97_GLBCTRL_PCMOUTTM_PIO			(1<<12)
-#define S3C_AC97_GLBCTRL_PCMOUTTM_DMA			(2<<12)
-#define S3C_AC97_GLBCTRL_PCMOUTTM_MASK			(3<<12)
-#define S3C_AC97_GLBCTRL_PCMINTM_OFF			(0<<10)
-#define S3C_AC97_GLBCTRL_PCMINTM_PIO			(1<<10)
-#define S3C_AC97_GLBCTRL_PCMINTM_DMA			(2<<10)
-#define S3C_AC97_GLBCTRL_PCMINTM_MASK			(3<<10)
-#define S3C_AC97_GLBCTRL_MICINTM_OFF			(0<<8)
-#define S3C_AC97_GLBCTRL_MICINTM_PIO			(1<<8)
-#define S3C_AC97_GLBCTRL_MICINTM_DMA			(2<<8)
-#define S3C_AC97_GLBCTRL_MICINTM_MASK			(3<<8)
-#define S3C_AC97_GLBCTRL_TRANSFERDATAENABLE		(1<<3)
-#define S3C_AC97_GLBCTRL_ACLINKON			(1<<2)
-#define S3C_AC97_GLBCTRL_WARMRESET			(1<<1)
-#define S3C_AC97_GLBCTRL_COLDRESET			(1<<0)
-
-#define S3C_AC97_GLBSTAT				(0x04)
-
-#define S3C_AC97_GLBSTAT_CODECREADY			(1<<22)
-#define S3C_AC97_GLBSTAT_PCMOUTUR			(1<<21)
-#define S3C_AC97_GLBSTAT_PCMINORI			(1<<20)
-#define S3C_AC97_GLBSTAT_MICINORI			(1<<19)
-#define S3C_AC97_GLBSTAT_PCMOUTTI			(1<<18)
-#define S3C_AC97_GLBSTAT_PCMINTI			(1<<17)
-#define S3C_AC97_GLBSTAT_MICINTI			(1<<16)
-#define S3C_AC97_GLBSTAT_MAINSTATE_IDLE			(0<<0)
-#define S3C_AC97_GLBSTAT_MAINSTATE_INIT			(1<<0)
-#define S3C_AC97_GLBSTAT_MAINSTATE_READY		(2<<0)
-#define S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE		(3<<0)
-#define S3C_AC97_GLBSTAT_MAINSTATE_LP			(4<<0)
-#define S3C_AC97_GLBSTAT_MAINSTATE_WARM			(5<<0)
-
-#define S3C_AC97_CODEC_CMD				(0x08)
-
-#define S3C_AC97_CODEC_CMD_READ				(1<<23)
-
-#define S3C_AC97_STAT					(0x0c)
-#define S3C_AC97_PCM_ADDR				(0x10)
-#define S3C_AC97_PCM_DATA				(0x18)
-#define S3C_AC97_MIC_DATA				(0x1C)
-
-#endif /* __ASM_ARCH_REGS_AC97_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-adc.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-adc.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-adc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-adc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,60 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-adc.h
- *
- * Copyright (c) 2004 Shannon Holland <holland@loser.net>
- *
- * This program is free software; yosu can 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 ADC registers
-*/
-
-#ifndef __ASM_ARCH_REGS_ADC_H
-#define __ASM_ARCH_REGS_ADC_H "regs-adc.h"
-
-#define S3C2410_ADCREG(x) (x)
-
-#define S3C2410_ADCCON	   S3C2410_ADCREG(0x00)
-#define S3C2410_ADCTSC	   S3C2410_ADCREG(0x04)
-#define S3C2410_ADCDLY	   S3C2410_ADCREG(0x08)
-#define S3C2410_ADCDAT0	   S3C2410_ADCREG(0x0C)
-#define S3C2410_ADCDAT1	   S3C2410_ADCREG(0x10)
-
-
-/* ADCCON Register Bits */
-#define S3C2410_ADCCON_ECFLG		(1<<15)
-#define S3C2410_ADCCON_PRSCEN		(1<<14)
-#define S3C2410_ADCCON_PRSCVL(x)	(((x)&0xFF)<<6)
-#define S3C2410_ADCCON_PRSCVLMASK	(0xFF<<6)
-#define S3C2410_ADCCON_SELMUX(x)	(((x)&0x7)<<3)
-#define S3C2410_ADCCON_MUXMASK		(0x7<<3)
-#define S3C2410_ADCCON_STDBM		(1<<2)
-#define S3C2410_ADCCON_READ_START	(1<<1)
-#define S3C2410_ADCCON_ENABLE_START	(1<<0)
-#define S3C2410_ADCCON_STARTMASK	(0x3<<0)
-
-
-/* ADCTSC Register Bits */
-#define S3C2410_ADCTSC_YM_SEN		(1<<7)
-#define S3C2410_ADCTSC_YP_SEN		(1<<6)
-#define S3C2410_ADCTSC_XM_SEN		(1<<5)
-#define S3C2410_ADCTSC_XP_SEN		(1<<4)
-#define S3C2410_ADCTSC_PULL_UP_DISABLE	(1<<3)
-#define S3C2410_ADCTSC_AUTO_PST		(1<<2)
-#define S3C2410_ADCTSC_XY_PST(x)	(((x)&0x3)<<0)
-
-/* ADCDAT0 Bits */
-#define S3C2410_ADCDAT0_UPDOWN		(1<<15)
-#define S3C2410_ADCDAT0_AUTO_PST	(1<<14)
-#define S3C2410_ADCDAT0_XY_PST		(0x3<<12)
-#define S3C2410_ADCDAT0_XPDATA_MASK	(0x03FF)
-
-/* ADCDAT1 Bits */
-#define S3C2410_ADCDAT1_UPDOWN		(1<<15)
-#define S3C2410_ADCDAT1_AUTO_PST	(1<<14)
-#define S3C2410_ADCDAT1_XY_PST		(0x3<<12)
-#define S3C2410_ADCDAT1_YPDATA_MASK	(0x03FF)
-
-#endif /* __ASM_ARCH_REGS_ADC_H */
-
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-fb.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-fb.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-fb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-fb.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,366 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/regs-fb.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      http://armlinux.simtec.co.uk/
- *      Ben Dooks <ben@simtec.co.uk>
- *
- * S3C Platform - new-style framebuffer register definitions
- *
- * This is the register set for the new style framebuffer interface
- * found from the S3C2443 onwards into the S3C2416, S3C2450 and the
- * S3C64XX series such as the S3C6400 and S3C6410.
- *
- * The file does not contain the cpu specific items which are based on
- * whichever architecture is selected, it only contains the core of the
- * register set. See <mach/regs-fb.h> to get the specifics.
- *
- * Note, we changed to using regs-fb.h as it avoids any clashes with
- * the original regs-lcd.h so out of the way of regs-lcd.h as well as
- * indicating the newer block is much more than just an LCD interface.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* Please do not include this file directly, use <mach/regs-fb.h> to
- * ensure all the localised SoC support is included as necessary.
-*/
-
-/* VIDCON0 */
-
-#define VIDCON0					(0x00)
-#define VIDCON0_INTERLACE			(1 << 29)
-#define VIDCON0_VIDOUT_MASK			(0x3 << 26)
-#define VIDCON0_VIDOUT_SHIFT			(26)
-#define VIDCON0_VIDOUT_RGB			(0x0 << 26)
-#define VIDCON0_VIDOUT_TV			(0x1 << 26)
-#define VIDCON0_VIDOUT_I80_LDI0			(0x2 << 26)
-#define VIDCON0_VIDOUT_I80_LDI1			(0x3 << 26)
-
-#define VIDCON0_L1_DATA_MASK			(0x7 << 23)
-#define VIDCON0_L1_DATA_SHIFT			(23)
-#define VIDCON0_L1_DATA_16BPP			(0x0 << 23)
-#define VIDCON0_L1_DATA_18BPP16			(0x1 << 23)
-#define VIDCON0_L1_DATA_18BPP9			(0x2 << 23)
-#define VIDCON0_L1_DATA_24BPP			(0x3 << 23)
-#define VIDCON0_L1_DATA_18BPP			(0x4 << 23)
-#define VIDCON0_L1_DATA_16BPP8			(0x5 << 23)
-
-#define VIDCON0_L0_DATA_MASK			(0x7 << 20)
-#define VIDCON0_L0_DATA_SHIFT			(20)
-#define VIDCON0_L0_DATA_16BPP			(0x0 << 20)
-#define VIDCON0_L0_DATA_18BPP16			(0x1 << 20)
-#define VIDCON0_L0_DATA_18BPP9			(0x2 << 20)
-#define VIDCON0_L0_DATA_24BPP			(0x3 << 20)
-#define VIDCON0_L0_DATA_18BPP			(0x4 << 20)
-#define VIDCON0_L0_DATA_16BPP8			(0x5 << 20)
-
-#define VIDCON0_PNRMODE_MASK			(0x3 << 17)
-#define VIDCON0_PNRMODE_SHIFT			(17)
-#define VIDCON0_PNRMODE_RGB			(0x0 << 17)
-#define VIDCON0_PNRMODE_BGR			(0x1 << 17)
-#define VIDCON0_PNRMODE_SERIAL_RGB		(0x2 << 17)
-#define VIDCON0_PNRMODE_SERIAL_BGR		(0x3 << 17)
-
-#define VIDCON0_CLKVALUP			(1 << 16)
-#define VIDCON0_CLKVAL_F_MASK			(0xff << 6)
-#define VIDCON0_CLKVAL_F_SHIFT			(6)
-#define VIDCON0_CLKVAL_F_LIMIT			(0xff)
-#define VIDCON0_CLKVAL_F(_x)			((_x) << 6)
-#define VIDCON0_VLCKFREE			(1 << 5)
-#define VIDCON0_CLKDIR				(1 << 4)
-
-#define VIDCON0_CLKSEL_MASK			(0x3 << 2)
-#define VIDCON0_CLKSEL_SHIFT			(2)
-#define VIDCON0_CLKSEL_HCLK			(0x0 << 2)
-#define VIDCON0_CLKSEL_LCD			(0x1 << 2)
-#define VIDCON0_CLKSEL_27M			(0x3 << 2)
-
-#define VIDCON0_ENVID				(1 << 1)
-#define VIDCON0_ENVID_F				(1 << 0)
-
-#define VIDCON1					(0x04)
-#define VIDCON1_LINECNT_MASK			(0x7ff << 16)
-#define VIDCON1_LINECNT_SHIFT			(16)
-#define VIDCON1_LINECNT_GET(_v)			(((_v) >> 16) & 0x7ff)
-#define VIDCON1_VSTATUS_MASK			(0x3 << 13)
-#define VIDCON1_VSTATUS_SHIFT			(13)
-#define VIDCON1_VSTATUS_VSYNC			(0x0 << 13)
-#define VIDCON1_VSTATUS_BACKPORCH		(0x1 << 13)
-#define VIDCON1_VSTATUS_ACTIVE			(0x2 << 13)
-#define VIDCON1_VSTATUS_FRONTPORCH		(0x0 << 13)
-
-#define VIDCON1_INV_VCLK			(1 << 7)
-#define VIDCON1_INV_HSYNC			(1 << 6)
-#define VIDCON1_INV_VSYNC			(1 << 5)
-#define VIDCON1_INV_VDEN			(1 << 4)
-
-/* VIDCON2 */
-
-#define VIDCON2					(0x08)
-#define VIDCON2_EN601				(1 << 23)
-#define VIDCON2_TVFMTSEL_SW			(1 << 14)
-
-#define VIDCON2_TVFMTSEL1_MASK			(0x3 << 12)
-#define VIDCON2_TVFMTSEL1_SHIFT			(12)
-#define VIDCON2_TVFMTSEL1_RGB			(0x0 << 12)
-#define VIDCON2_TVFMTSEL1_YUV422		(0x1 << 12)
-#define VIDCON2_TVFMTSEL1_YUV444		(0x2 << 12)
-
-#define VIDCON2_ORGYCbCr			(1 << 8)
-#define VIDCON2_YUVORDCrCb			(1 << 7)
-
-/* VIDTCON0 */
-
-#define VIDTCON0_VBPDE_MASK			(0xff << 24)
-#define VIDTCON0_VBPDE_SHIFT			(24)
-#define VIDTCON0_VBPDE_LIMIT			(0xff)
-#define VIDTCON0_VBPDE(_x)			((_x) << 24)
-
-#define VIDTCON0_VBPD_MASK			(0xff << 16)
-#define VIDTCON0_VBPD_SHIFT			(16)
-#define VIDTCON0_VBPD_LIMIT			(0xff)
-#define VIDTCON0_VBPD(_x)			((_x) << 16)
-
-#define VIDTCON0_VFPD_MASK			(0xff << 8)
-#define VIDTCON0_VFPD_SHIFT			(8)
-#define VIDTCON0_VFPD_LIMIT			(0xff)
-#define VIDTCON0_VFPD(_x)			((_x) << 8)
-
-#define VIDTCON0_VSPW_MASK			(0xff << 0)
-#define VIDTCON0_VSPW_SHIFT			(0)
-#define VIDTCON0_VSPW_LIMIT			(0xff)
-#define VIDTCON0_VSPW(_x)			((_x) << 0)
-
-/* VIDTCON1 */
-
-#define VIDTCON1_VFPDE_MASK			(0xff << 24)
-#define VIDTCON1_VFPDE_SHIFT			(24)
-#define VIDTCON1_VFPDE_LIMIT			(0xff)
-#define VIDTCON1_VFPDE(_x)			((_x) << 24)
-
-#define VIDTCON1_HBPD_MASK			(0xff << 16)
-#define VIDTCON1_HBPD_SHIFT			(16)
-#define VIDTCON1_HBPD_LIMIT			(0xff)
-#define VIDTCON1_HBPD(_x)			((_x) << 16)
-
-#define VIDTCON1_HFPD_MASK			(0xff << 8)
-#define VIDTCON1_HFPD_SHIFT			(8)
-#define VIDTCON1_HFPD_LIMIT			(0xff)
-#define VIDTCON1_HFPD(_x)			((_x) << 8)
-
-#define VIDTCON1_HSPW_MASK			(0xff << 0)
-#define VIDTCON1_HSPW_SHIFT			(0)
-#define VIDTCON1_HSPW_LIMIT			(0xff)
-#define VIDTCON1_HSPW(_x)			((_x) << 0)
-
-#define VIDTCON2				(0x18)
-#define VIDTCON2_LINEVAL_MASK			(0x7ff << 11)
-#define VIDTCON2_LINEVAL_SHIFT			(11)
-#define VIDTCON2_LINEVAL_LIMIT			(0x7ff)
-#define VIDTCON2_LINEVAL(_x)			((_x) << 11)
-
-#define VIDTCON2_HOZVAL_MASK			(0x7ff << 0)
-#define VIDTCON2_HOZVAL_SHIFT			(0)
-#define VIDTCON2_HOZVAL_LIMIT			(0x7ff)
-#define VIDTCON2_HOZVAL(_x)			((_x) << 0)
-
-/* WINCONx */
-
-
-#define WINCONx_BITSWP				(1 << 18)
-#define WINCONx_BYTSWP				(1 << 17)
-#define WINCONx_HAWSWP				(1 << 16)
-#define WINCONx_BURSTLEN_MASK			(0x3 << 9)
-#define WINCONx_BURSTLEN_SHIFT			(9)
-#define WINCONx_BURSTLEN_16WORD			(0x0 << 9)
-#define WINCONx_BURSTLEN_8WORD			(0x1 << 9)
-#define WINCONx_BURSTLEN_4WORD			(0x2 << 9)
-
-#define WINCONx_ENWIN				(1 << 0)
-#define WINCON0_BPPMODE_MASK			(0xf << 2)
-#define WINCON0_BPPMODE_SHIFT			(2)
-#define WINCON0_BPPMODE_1BPP			(0x0 << 2)
-#define WINCON0_BPPMODE_2BPP			(0x1 << 2)
-#define WINCON0_BPPMODE_4BPP			(0x2 << 2)
-#define WINCON0_BPPMODE_8BPP_PALETTE		(0x3 << 2)
-#define WINCON0_BPPMODE_16BPP_565		(0x5 << 2)
-#define WINCON0_BPPMODE_16BPP_1555		(0x7 << 2)
-#define WINCON0_BPPMODE_18BPP_666		(0x8 << 2)
-#define WINCON0_BPPMODE_24BPP_888		(0xb << 2)
-
-#define WINCON1_BLD_PIX				(1 << 6)
-
-#define WINCON1_ALPHA_SEL			(1 << 1)
-#define WINCON1_BPPMODE_MASK			(0xf << 2)
-#define WINCON1_BPPMODE_SHIFT			(2)
-#define WINCON1_BPPMODE_1BPP			(0x0 << 2)
-#define WINCON1_BPPMODE_2BPP			(0x1 << 2)
-#define WINCON1_BPPMODE_4BPP			(0x2 << 2)
-#define WINCON1_BPPMODE_8BPP_PALETTE		(0x3 << 2)
-#define WINCON1_BPPMODE_8BPP_1232		(0x4 << 2)
-#define WINCON1_BPPMODE_16BPP_565		(0x5 << 2)
-#define WINCON1_BPPMODE_16BPP_A1555		(0x6 << 2)
-#define WINCON1_BPPMODE_16BPP_I1555		(0x7 << 2)
-#define WINCON1_BPPMODE_18BPP_666		(0x8 << 2)
-#define WINCON1_BPPMODE_18BPP_A1665		(0x9 << 2)
-#define WINCON1_BPPMODE_19BPP_A1666		(0xa << 2)
-#define WINCON1_BPPMODE_24BPP_888		(0xb << 2)
-#define WINCON1_BPPMODE_24BPP_A1887		(0xc << 2)
-#define WINCON1_BPPMODE_25BPP_A1888		(0xd << 2)
-#define WINCON1_BPPMODE_28BPP_A4888		(0xd << 2)
-
-
-#define VIDOSDxA_TOPLEFT_X_MASK			(0x7ff << 11)
-#define VIDOSDxA_TOPLEFT_X_SHIFT		(11)
-#define VIDOSDxA_TOPLEFT_X_LIMIT		(0x7ff)
-#define VIDOSDxA_TOPLEFT_X(_x)			((_x) << 11)
-
-#define VIDOSDxA_TOPLEFT_Y_MASK			(0x7ff << 0)
-#define VIDOSDxA_TOPLEFT_Y_SHIFT		(0)
-#define VIDOSDxA_TOPLEFT_Y_LIMIT		(0x7ff)
-#define VIDOSDxA_TOPLEFT_Y(_x)			((_x) << 0)
-
-#define VIDOSDxB_BOTRIGHT_X_MASK		(0x7ff << 11)
-#define VIDOSDxB_BOTRIGHT_X_SHIFT		(11)
-#define VIDOSDxB_BOTRIGHT_X_LIMIT		(0x7ff)
-#define VIDOSDxB_BOTRIGHT_X(_x)			((_x) << 11)
-
-#define VIDOSDxB_BOTRIGHT_Y_MASK		(0x7ff << 0)
-#define VIDOSDxB_BOTRIGHT_Y_SHIFT		(0)
-#define VIDOSDxB_BOTRIGHT_Y_LIMIT		(0x7ff)
-#define VIDOSDxB_BOTRIGHT_Y(_x)			((_x) << 0)
-
-/* For VIDOSD[1..4]C */
-#define VIDISD14C_ALPHA0_R(_x)			((_x) << 20)
-#define VIDISD14C_ALPHA0_G_MASK			(0xf << 16)
-#define VIDISD14C_ALPHA0_G_SHIFT		(16)
-#define VIDISD14C_ALPHA0_G_LIMIT		(0xf)
-#define VIDISD14C_ALPHA0_G(_x)			((_x) << 16)
-#define VIDISD14C_ALPHA0_B_MASK			(0xf << 12)
-#define VIDISD14C_ALPHA0_B_SHIFT		(12)
-#define VIDISD14C_ALPHA0_B_LIMIT		(0xf)
-#define VIDISD14C_ALPHA0_B(_x)			((_x) << 12)
-#define VIDISD14C_ALPHA1_R_MASK			(0xf << 8)
-#define VIDISD14C_ALPHA1_R_SHIFT		(8)
-#define VIDISD14C_ALPHA1_R_LIMIT		(0xf)
-#define VIDISD14C_ALPHA1_R(_x)			((_x) << 8)
-#define VIDISD14C_ALPHA1_G_MASK			(0xf << 4)
-#define VIDISD14C_ALPHA1_G_SHIFT		(4)
-#define VIDISD14C_ALPHA1_G_LIMIT		(0xf)
-#define VIDISD14C_ALPHA1_G(_x)			((_x) << 4)
-#define VIDISD14C_ALPHA1_B_MASK			(0xf << 0)
-#define VIDISD14C_ALPHA1_B_SHIFT		(0)
-#define VIDISD14C_ALPHA1_B_LIMIT		(0xf)
-#define VIDISD14C_ALPHA1_B(_x)			((_x) << 0)
-
-/* Video buffer addresses */
-#define VIDW_BUF_START(_buff)			(0xA0 + ((_buff) * 8))
-#define VIDW_BUF_START1(_buff)			(0xA4 + ((_buff) * 8))
-#define VIDW_BUF_END(_buff)			(0xD0 + ((_buff) * 8))
-#define VIDW_BUF_END1(_buff)			(0xD4 + ((_buff) * 8))
-#define VIDW_BUF_SIZE(_buff)			(0x100 + ((_buff) * 4))
-
-#define VIDW_BUF_SIZE_OFFSET_MASK		(0x1fff << 13)
-#define VIDW_BUF_SIZE_OFFSET_SHIFT		(13)
-#define VIDW_BUF_SIZE_OFFSET_LIMIT		(0x1fff)
-#define VIDW_BUF_SIZE_OFFSET(_x)		((_x) << 13)
-
-#define VIDW_BUF_SIZE_PAGEWIDTH_MASK		(0x1fff << 0)
-#define VIDW_BUF_SIZE_PAGEWIDTH_SHIFT		(0)
-#define VIDW_BUF_SIZE_PAGEWIDTH_LIMIT		(0x1fff)
-#define VIDW_BUF_SIZE_PAGEWIDTH(_x)		((_x) << 0)
-
-/* Interrupt controls and status */
-
-#define VIDINTCON0_FIFOINTERVAL_MASK		(0x3f << 20)
-#define VIDINTCON0_FIFOINTERVAL_SHIFT		(20)
-#define VIDINTCON0_FIFOINTERVAL_LIMIT		(0x3f)
-#define VIDINTCON0_FIFOINTERVAL(_x)		((_x) << 20)
-
-#define VIDINTCON0_INT_SYSMAINCON		(1 << 19)
-#define VIDINTCON0_INT_SYSSUBCON		(1 << 18)
-#define VIDINTCON0_INT_I80IFDONE		(1 << 17)
-
-#define VIDINTCON0_FRAMESEL0_MASK		(0x3 << 15)
-#define VIDINTCON0_FRAMESEL0_SHIFT		(15)
-#define VIDINTCON0_FRAMESEL0_BACKPORCH		(0x0 << 15)
-#define VIDINTCON0_FRAMESEL0_VSYNC		(0x1 << 15)
-#define VIDINTCON0_FRAMESEL0_ACTIVE		(0x2 << 15)
-#define VIDINTCON0_FRAMESEL0_FRONTPORCH		(0x3 << 15)
-
-#define VIDINTCON0_FRAMESEL1			(1 << 14)
-#define VIDINTCON0_FRAMESEL1_NONE		(0x0 << 14)
-#define VIDINTCON0_FRAMESEL1_BACKPORCH		(0x1 << 14)
-#define VIDINTCON0_FRAMESEL1_VSYNC		(0x2 << 14)
-#define VIDINTCON0_FRAMESEL1_FRONTPORCH		(0x3 << 14)
-
-#define VIDINTCON0_INT_FRAME			(1 << 12)
-#define VIDINTCON0_FIFIOSEL_MASK		(0x7f << 5)
-#define VIDINTCON0_FIFIOSEL_SHIFT		(5)
-#define VIDINTCON0_FIFIOSEL_WINDOW0		(0x1 << 5)
-#define VIDINTCON0_FIFIOSEL_WINDOW1		(0x2 << 5)
-
-#define VIDINTCON0_FIFOLEVEL_MASK		(0x7 << 2)
-#define VIDINTCON0_FIFOLEVEL_SHIFT		(2)
-#define VIDINTCON0_FIFOLEVEL_TO25PC		(0x0 << 2)
-#define VIDINTCON0_FIFOLEVEL_TO50PC		(0x1 << 2)
-#define VIDINTCON0_FIFOLEVEL_TO75PC		(0x2 << 2)
-#define VIDINTCON0_FIFOLEVEL_EMPTY		(0x3 << 2)
-#define VIDINTCON0_FIFOLEVEL_FULL		(0x4 << 2)
-
-#define VIDINTCON0_INT_FIFO_MASK		(0x3 << 0)
-#define VIDINTCON0_INT_FIFO_SHIFT		(0)
-#define VIDINTCON0_INT_ENABLE			(1 << 0)
-
-#define VIDINTCON1				(0x134)
-#define VIDINTCON1_INT_I180			(1 << 2)
-#define VIDINTCON1_INT_FRAME			(1 << 1)
-#define VIDINTCON1_INT_FIFO			(1 << 0)
-
-/* Window colour-key control registers */
-
-#define WxKEYCON0_KEYBL_EN			(1 << 26)
-#define WxKEYCON0_KEYEN_F			(1 << 25)
-#define WxKEYCON0_DIRCON			(1 << 24)
-#define WxKEYCON0_COMPKEY_MASK			(0xffffff << 0)
-#define WxKEYCON0_COMPKEY_SHIFT			(0)
-#define WxKEYCON0_COMPKEY_LIMIT			(0xffffff)
-#define WxKEYCON0_COMPKEY(_x)			((_x) << 0)
-#define WxKEYCON1_COLVAL_MASK			(0xffffff << 0)
-#define WxKEYCON1_COLVAL_SHIFT			(0)
-#define WxKEYCON1_COLVAL_LIMIT			(0xffffff)
-#define WxKEYCON1_COLVAL(_x)			((_x) << 0)
-
-
-/* Window blanking (MAP) */
-
-#define WINxMAP_MAP				(1 << 24)
-#define WINxMAP_MAP_COLOUR_MASK			(0xffffff << 0)
-#define WINxMAP_MAP_COLOUR_SHIFT		(0)
-#define WINxMAP_MAP_COLOUR_LIMIT		(0xffffff)
-#define WINxMAP_MAP_COLOUR(_x)			((_x) << 0)
-
-#define WPALCON_PAL_UPDATE			(1 << 9)
-#define WPALCON_W1PAL_MASK			(0x7 << 3)
-#define WPALCON_W1PAL_SHIFT			(3)
-#define WPALCON_W1PAL_25BPP_A888		(0x0 << 3)
-#define WPALCON_W1PAL_24BPP			(0x1 << 3)
-#define WPALCON_W1PAL_19BPP_A666		(0x2 << 3)
-#define WPALCON_W1PAL_18BPP_A665		(0x3 << 3)
-#define WPALCON_W1PAL_18BPP			(0x4 << 3)
-#define WPALCON_W1PAL_16BPP_A555		(0x5 << 3)
-#define WPALCON_W1PAL_16BPP_565			(0x6 << 3)
-
-#define WPALCON_W0PAL_MASK			(0x7 << 0)
-#define WPALCON_W0PAL_SHIFT			(0)
-#define WPALCON_W0PAL_25BPP_A888		(0x0 << 0)
-#define WPALCON_W0PAL_24BPP			(0x1 << 0)
-#define WPALCON_W0PAL_19BPP_A666		(0x2 << 0)
-#define WPALCON_W0PAL_18BPP_A665		(0x3 << 0)
-#define WPALCON_W0PAL_18BPP			(0x4 << 0)
-#define WPALCON_W0PAL_16BPP_A555		(0x5 << 0)
-#define WPALCON_W0PAL_16BPP_565			(0x6 << 0)
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-fb-v4.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-fb-v4.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-fb-v4.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-fb-v4.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,235 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/regs-fb-v4.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      http://armlinux.simtec.co.uk/
- *      Ben Dooks <ben@simtec.co.uk>
- *
- * S3C64XX - new-style framebuffer register definitions
- *
- * This is the register set for the new style framebuffer interface
- * found from the S3C2443 onwards and specifically the S3C64XX series
- * S3C6400 and S3C6410.
- *
- * The file contains the cpu specific items which change between whichever
- * architecture is selected. See <plat/regs-fb.h> for the core definitions
- * that are the same.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* include the core definitions here, in case we really do need to
- * override them at a later date.
-*/
-
-#include <plat/regs-fb.h>
-
-#define S3C_FB_MAX_WIN (5)  /* number of hardware windows available. */
-#define VIDCON1_FSTATUS_EVEN	(1 << 15)
-
-/* Video timing controls */
-#define VIDTCON0				(0x10)
-#define VIDTCON1				(0x14)
-#define VIDTCON2				(0x18)
-
-/* Window position controls */
-
-#define WINCON(_win)				(0x20 + ((_win) * 4))
-
-/* OSD1 and OSD4 do not have register D */
-
-#define VIDOSD_A(_win)				(0x40 + ((_win) * 16))
-#define VIDOSD_B(_win)				(0x44 + ((_win) * 16))
-#define VIDOSD_C(_win)				(0x48 + ((_win) * 16))
-#define VIDOSD_D(_win)				(0x4C + ((_win) * 16))
-
-
-#define VIDINTCON0				(0x130)
-
-#define WxKEYCONy(_win, _con)			((0x140 + ((_win) * 8)) + ((_con) * 4))
-
-/* WINCONx */
-
-#define WINCONx_CSCWIDTH_MASK			(0x3 << 26)
-#define WINCONx_CSCWIDTH_SHIFT			(26)
-#define WINCONx_CSCWIDTH_WIDE			(0x0 << 26)
-#define WINCONx_CSCWIDTH_NARROW			(0x3 << 26)
-
-#define WINCONx_ENLOCAL				(1 << 22)
-#define WINCONx_BUFSTATUS			(1 << 21)
-#define WINCONx_BUFSEL				(1 << 20)
-#define WINCONx_BUFAUTOEN			(1 << 19)
-#define WINCONx_YCbCr				(1 << 13)
-
-#define WINCON1_LOCALSEL_CAMIF			(1 << 23)
-
-#define WINCON2_LOCALSEL_CAMIF			(1 << 23)
-#define WINCON2_BLD_PIX				(1 << 6)
-
-#define WINCON2_ALPHA_SEL			(1 << 1)
-#define WINCON2_BPPMODE_MASK			(0xf << 2)
-#define WINCON2_BPPMODE_SHIFT			(2)
-#define WINCON2_BPPMODE_1BPP			(0x0 << 2)
-#define WINCON2_BPPMODE_2BPP			(0x1 << 2)
-#define WINCON2_BPPMODE_4BPP			(0x2 << 2)
-#define WINCON2_BPPMODE_8BPP_1232		(0x4 << 2)
-#define WINCON2_BPPMODE_16BPP_565		(0x5 << 2)
-#define WINCON2_BPPMODE_16BPP_A1555		(0x6 << 2)
-#define WINCON2_BPPMODE_16BPP_I1555		(0x7 << 2)
-#define WINCON2_BPPMODE_18BPP_666		(0x8 << 2)
-#define WINCON2_BPPMODE_18BPP_A1665		(0x9 << 2)
-#define WINCON2_BPPMODE_19BPP_A1666		(0xa << 2)
-#define WINCON2_BPPMODE_24BPP_888		(0xb << 2)
-#define WINCON2_BPPMODE_24BPP_A1887		(0xc << 2)
-#define WINCON2_BPPMODE_25BPP_A1888		(0xd << 2)
-#define WINCON2_BPPMODE_28BPP_A4888		(0xd << 2)
-
-#define WINCON3_BLD_PIX				(1 << 6)
-
-#define WINCON3_ALPHA_SEL			(1 << 1)
-#define WINCON3_BPPMODE_MASK			(0xf << 2)
-#define WINCON3_BPPMODE_SHIFT			(2)
-#define WINCON3_BPPMODE_1BPP			(0x0 << 2)
-#define WINCON3_BPPMODE_2BPP			(0x1 << 2)
-#define WINCON3_BPPMODE_4BPP			(0x2 << 2)
-#define WINCON3_BPPMODE_16BPP_565		(0x5 << 2)
-#define WINCON3_BPPMODE_16BPP_A1555		(0x6 << 2)
-#define WINCON3_BPPMODE_16BPP_I1555		(0x7 << 2)
-#define WINCON3_BPPMODE_18BPP_666		(0x8 << 2)
-#define WINCON3_BPPMODE_18BPP_A1665		(0x9 << 2)
-#define WINCON3_BPPMODE_19BPP_A1666		(0xa << 2)
-#define WINCON3_BPPMODE_24BPP_888		(0xb << 2)
-#define WINCON3_BPPMODE_24BPP_A1887		(0xc << 2)
-#define WINCON3_BPPMODE_25BPP_A1888		(0xd << 2)
-#define WINCON3_BPPMODE_28BPP_A4888		(0xd << 2)
-
-#define VIDINTCON0_FIFIOSEL_WINDOW2		(0x10 << 5)
-#define VIDINTCON0_FIFIOSEL_WINDOW3		(0x20 << 5)
-#define VIDINTCON0_FIFIOSEL_WINDOW4		(0x40 << 5)
-
-#define DITHMODE				(0x170)
-#define WINxMAP(_win)				(0x180 + ((_win) * 4))
-
-
-#define DITHMODE_R_POS_MASK			(0x3 << 5)
-#define DITHMODE_R_POS_SHIFT			(5)
-#define DITHMODE_R_POS_8BIT			(0x0 << 5)
-#define DITHMODE_R_POS_6BIT			(0x1 << 5)
-#define DITHMODE_R_POS_5BIT			(0x2 << 5)
-
-#define DITHMODE_G_POS_MASK			(0x3 << 3)
-#define DITHMODE_G_POS_SHIFT			(3)
-#define DITHMODE_G_POS_8BIT			(0x0 << 3)
-#define DITHMODE_G_POS_6BIT			(0x1 << 3)
-#define DITHMODE_G_POS_5BIT			(0x2 << 3)
-
-#define DITHMODE_B_POS_MASK			(0x3 << 1)
-#define DITHMODE_B_POS_SHIFT			(1)
-#define DITHMODE_B_POS_8BIT			(0x0 << 1)
-#define DITHMODE_B_POS_6BIT			(0x1 << 1)
-#define DITHMODE_B_POS_5BIT			(0x2 << 1)
-
-#define DITHMODE_DITH_EN			(1 << 0)
-
-#define WPALCON					(0x1A0)
-
-/* Palette control */
-/* Note for S5PC100: you can still use those macros on WPALCON (aka WPALCON_L),
- * but make sure that WPALCON_H W2PAL-W4PAL entries are zeroed out */
-#define WPALCON_W4PAL_16BPP_A555		(1 << 8)
-#define WPALCON_W3PAL_16BPP_A555		(1 << 7)
-#define WPALCON_W2PAL_16BPP_A555		(1 << 6)
-
-
-/* system specific implementation code for palette sizes, and other
- * information that changes depending on which architecture is being
- * compiled.
-*/
-
-/* return true if window _win has OSD register D */
-#define s3c_fb_has_osd_d(_win) ((_win) != 4 && (_win) != 0)
-
-static inline unsigned int s3c_fb_win_pal_size(unsigned int win)
-{
-	if (win < 2)
-		return 256;
-	if (win < 4)
-		return 16;
-	if (win == 4)
-		return 4;
-
-	BUG();	/* shouldn't get here */
-}
-
-static inline int s3c_fb_validate_win_bpp(unsigned int win, unsigned int bpp)
-{
-	/* all windows can do 1/2 bpp */
-
-	if ((bpp == 25 || bpp == 19) && win == 0)
-		return 0;	/* win 0 does not have 19 or 25bpp modes */
-
-	if (bpp == 4 && win == 4)
-		return 0;
-
-	if (bpp == 8 && (win >= 3))
-		return 0;	/* win 3/4 cannot do 8bpp in any mode */
-
-	return 1;
-}
-
-static inline int s3c_fb_pal_is16(unsigned int window)
-{
-	return window > 1;
-}
-
-struct s3c_fb_palette {
-	struct fb_bitfield	r;
-	struct fb_bitfield	g;
-	struct fb_bitfield	b;
-	struct fb_bitfield	a;
-};
-
-static inline void s3c_fb_init_palette(unsigned int window,
-				       struct s3c_fb_palette *palette)
-{
-	if (window < 2) {
-		/* Windows 0/1 are 8/8/8 or A/8/8/8 */
-		palette->r.offset = 16;
-		palette->r.length = 8;
-		palette->g.offset = 8;
-		palette->g.length = 8;
-		palette->b.offset = 0;
-		palette->b.length = 8;
-	} else {
-		/* currently we assume RGB 5/6/5 */
-		palette->r.offset = 11;
-		palette->r.length = 5;
-		palette->g.offset = 5;
-		palette->g.length = 6;
-		palette->b.offset = 0;
-		palette->b.length = 5;
-	}
-}
-
-/* Notes on per-window bpp settings
- *
- * Value	Win0	 Win1	  Win2	   Win3	    Win 4
- * 0000		1(P)	 1(P)	  1(P)	   1(P)	    1(P)
- * 0001		2(P)	 2(P)     2(P)	   2(P)	    2(P)
- * 0010		4(P)	 4(P)     4(P)	   4(P)     -none-
- * 0011		8(P)	 8(P)     -none-   -none-   -none-
- * 0100		-none-	 8(A232)  8(A232)  -none-   -none-
- * 0101		16(565)	 16(565)  16(565)  16(565)   16(565)
- * 0110		-none-	 16(A555) 16(A555) 16(A555)  16(A555)
- * 0111		16(I555) 16(I565) 16(I555) 16(I555)  16(I555)
- * 1000		18(666)	 18(666)  18(666)  18(666)   18(666)
- * 1001		-none-	 18(A665) 18(A665) 18(A665)  16(A665)
- * 1010		-none-	 19(A666) 19(A666) 19(A666)  19(A666)
- * 1011		24(888)	 24(888)  24(888)  24(888)   24(888)
- * 1100		-none-	 24(A887) 24(A887) 24(A887)  24(A887)
- * 1101		-none-	 25(A888) 25(A888) 25(A888)  25(A888)
- * 1110		-none-	 -none-	  -none-   -none-    -none-
- * 1111		-none-	 -none-   -none-   -none-    -none-
-*/
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-iic.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-iic.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-iic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-iic.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,56 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-iic.h
- *
- * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
- *		http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2410 I2C Controller
-*/
-
-#ifndef __ASM_ARCH_REGS_IIC_H
-#define __ASM_ARCH_REGS_IIC_H __FILE__
-
-/* see s3c2410x user guide, v1.1, section 9 (p447) for more info */
-
-#define S3C2410_IICREG(x) (x)
-
-#define S3C2410_IICCON    S3C2410_IICREG(0x00)
-#define S3C2410_IICSTAT   S3C2410_IICREG(0x04)
-#define S3C2410_IICADD    S3C2410_IICREG(0x08)
-#define S3C2410_IICDS     S3C2410_IICREG(0x0C)
-#define S3C2440_IICLC	  S3C2410_IICREG(0x10)
-
-#define S3C2410_IICCON_ACKEN		(1<<7)
-#define S3C2410_IICCON_TXDIV_16		(0<<6)
-#define S3C2410_IICCON_TXDIV_512	(1<<6)
-#define S3C2410_IICCON_IRQEN		(1<<5)
-#define S3C2410_IICCON_IRQPEND		(1<<4)
-#define S3C2410_IICCON_SCALE(x)		((x)&15)
-#define S3C2410_IICCON_SCALEMASK	(0xf)
-
-#define S3C2410_IICSTAT_MASTER_RX	(2<<6)
-#define S3C2410_IICSTAT_MASTER_TX	(3<<6)
-#define S3C2410_IICSTAT_SLAVE_RX	(0<<6)
-#define S3C2410_IICSTAT_SLAVE_TX	(1<<6)
-#define S3C2410_IICSTAT_MODEMASK	(3<<6)
-
-#define S3C2410_IICSTAT_START		(1<<5)
-#define S3C2410_IICSTAT_BUSBUSY		(1<<5)
-#define S3C2410_IICSTAT_TXRXEN		(1<<4)
-#define S3C2410_IICSTAT_ARBITR		(1<<3)
-#define S3C2410_IICSTAT_ASSLAVE		(1<<2)
-#define S3C2410_IICSTAT_ADDR0		(1<<1)
-#define S3C2410_IICSTAT_LASTBIT		(1<<0)
-
-#define S3C2410_IICLC_SDA_DELAY0	(0 << 0)
-#define S3C2410_IICLC_SDA_DELAY5	(1 << 0)
-#define S3C2410_IICLC_SDA_DELAY10	(2 << 0)
-#define S3C2410_IICLC_SDA_DELAY15	(3 << 0)
-#define S3C2410_IICLC_SDA_DELAY_MASK	(3 << 0)
-
-#define S3C2410_IICLC_FILTER_ON		(1<<2)
-
-#endif /* __ASM_ARCH_REGS_IIC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-irqtype.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-irqtype.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-irqtype.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-irqtype.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,21 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/regs-irqtype.h
- *
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C - IRQ detection types.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-/* values for S3C2410_EXTINT0/1/2 and other cpus in the series, including
- * the S3C64XX
-*/
-#define S3C2410_EXTINT_LOWLEV	 (0x00)
-#define S3C2410_EXTINT_HILEV	 (0x01)
-#define S3C2410_EXTINT_FALLEDGE	 (0x02)
-#define S3C2410_EXTINT_RISEEDGE	 (0x04)
-#define S3C2410_EXTINT_BOTHEDGE	 (0x06)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-nand.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-nand.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-nand.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-nand.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,123 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-nand.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics <linux@simtec.co.uk>
- *	http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can 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 NAND register definitions
-*/
-
-#ifndef __ASM_ARM_REGS_NAND
-#define __ASM_ARM_REGS_NAND
-
-
-#define S3C2410_NFREG(x) (x)
-
-#define S3C2410_NFCONF  S3C2410_NFREG(0x00)
-#define S3C2410_NFCMD   S3C2410_NFREG(0x04)
-#define S3C2410_NFADDR  S3C2410_NFREG(0x08)
-#define S3C2410_NFDATA  S3C2410_NFREG(0x0C)
-#define S3C2410_NFSTAT  S3C2410_NFREG(0x10)
-#define S3C2410_NFECC   S3C2410_NFREG(0x14)
-
-#define S3C2440_NFCONT   S3C2410_NFREG(0x04)
-#define S3C2440_NFCMD    S3C2410_NFREG(0x08)
-#define S3C2440_NFADDR   S3C2410_NFREG(0x0C)
-#define S3C2440_NFDATA   S3C2410_NFREG(0x10)
-#define S3C2440_NFECCD0  S3C2410_NFREG(0x14)
-#define S3C2440_NFECCD1  S3C2410_NFREG(0x18)
-#define S3C2440_NFECCD   S3C2410_NFREG(0x1C)
-#define S3C2440_NFSTAT   S3C2410_NFREG(0x20)
-#define S3C2440_NFESTAT0 S3C2410_NFREG(0x24)
-#define S3C2440_NFESTAT1 S3C2410_NFREG(0x28)
-#define S3C2440_NFMECC0  S3C2410_NFREG(0x2C)
-#define S3C2440_NFMECC1  S3C2410_NFREG(0x30)
-#define S3C2440_NFSECC   S3C2410_NFREG(0x34)
-#define S3C2440_NFSBLK   S3C2410_NFREG(0x38)
-#define S3C2440_NFEBLK   S3C2410_NFREG(0x3C)
-
-#define S3C2412_NFSBLK		S3C2410_NFREG(0x20)
-#define S3C2412_NFEBLK		S3C2410_NFREG(0x24)
-#define S3C2412_NFSTAT		S3C2410_NFREG(0x28)
-#define S3C2412_NFMECC_ERR0	S3C2410_NFREG(0x2C)
-#define S3C2412_NFMECC_ERR1	S3C2410_NFREG(0x30)
-#define S3C2412_NFMECC0		S3C2410_NFREG(0x34)
-#define S3C2412_NFMECC1		S3C2410_NFREG(0x38)
-#define S3C2412_NFSECC		S3C2410_NFREG(0x3C)
-
-#define S3C2410_NFCONF_EN          (1<<15)
-#define S3C2410_NFCONF_512BYTE     (1<<14)
-#define S3C2410_NFCONF_4STEP       (1<<13)
-#define S3C2410_NFCONF_INITECC     (1<<12)
-#define S3C2410_NFCONF_nFCE        (1<<11)
-#define S3C2410_NFCONF_TACLS(x)    ((x)<<8)
-#define S3C2410_NFCONF_TWRPH0(x)   ((x)<<4)
-#define S3C2410_NFCONF_TWRPH1(x)   ((x)<<0)
-
-#define S3C2410_NFSTAT_BUSY        (1<<0)
-
-#define S3C2440_NFCONF_BUSWIDTH_8	(0<<0)
-#define S3C2440_NFCONF_BUSWIDTH_16	(1<<0)
-#define S3C2440_NFCONF_ADVFLASH		(1<<3)
-#define S3C2440_NFCONF_TACLS(x)		((x)<<12)
-#define S3C2440_NFCONF_TWRPH0(x)	((x)<<8)
-#define S3C2440_NFCONF_TWRPH1(x)	((x)<<4)
-
-#define S3C2440_NFCONT_LOCKTIGHT	(1<<13)
-#define S3C2440_NFCONT_SOFTLOCK		(1<<12)
-#define S3C2440_NFCONT_ILLEGALACC_EN	(1<<10)
-#define S3C2440_NFCONT_RNBINT_EN	(1<<9)
-#define S3C2440_NFCONT_RN_FALLING	(1<<8)
-#define S3C2440_NFCONT_SPARE_ECCLOCK	(1<<6)
-#define S3C2440_NFCONT_MAIN_ECCLOCK	(1<<5)
-#define S3C2440_NFCONT_INITECC		(1<<4)
-#define S3C2440_NFCONT_nFCE		(1<<1)
-#define S3C2440_NFCONT_ENABLE		(1<<0)
-
-#define S3C2440_NFSTAT_READY		(1<<0)
-#define S3C2440_NFSTAT_nCE		(1<<1)
-#define S3C2440_NFSTAT_RnB_CHANGE	(1<<2)
-#define S3C2440_NFSTAT_ILLEGAL_ACCESS	(1<<3)
-
-#define S3C2412_NFCONF_NANDBOOT		(1<<31)
-#define S3C2412_NFCONF_ECCCLKCON	(1<<30)
-#define S3C2412_NFCONF_ECC_MLC		(1<<24)
-#define S3C2412_NFCONF_TACLS_MASK	(7<<12)	/* 1 extra bit of Tacls */
-
-#define S3C2412_NFCONT_ECC4_DIRWR	(1<<18)
-#define S3C2412_NFCONT_LOCKTIGHT	(1<<17)
-#define S3C2412_NFCONT_SOFTLOCK		(1<<16)
-#define S3C2412_NFCONT_ECC4_ENCINT	(1<<13)
-#define S3C2412_NFCONT_ECC4_DECINT	(1<<12)
-#define S3C2412_NFCONT_MAIN_ECC_LOCK	(1<<7)
-#define S3C2412_NFCONT_INIT_MAIN_ECC	(1<<5)
-#define S3C2412_NFCONT_nFCE1		(1<<2)
-#define S3C2412_NFCONT_nFCE0		(1<<1)
-
-#define S3C2412_NFSTAT_ECC_ENCDONE	(1<<7)
-#define S3C2412_NFSTAT_ECC_DECDONE	(1<<6)
-#define S3C2412_NFSTAT_ILLEGAL_ACCESS	(1<<5)
-#define S3C2412_NFSTAT_RnB_CHANGE	(1<<4)
-#define S3C2412_NFSTAT_nFCE1		(1<<3)
-#define S3C2412_NFSTAT_nFCE0		(1<<2)
-#define S3C2412_NFSTAT_Res1		(1<<1)
-#define S3C2412_NFSTAT_READY		(1<<0)
-
-#define S3C2412_NFECCERR_SERRDATA(x)	(((x) >> 21) & 0xf)
-#define S3C2412_NFECCERR_SERRBIT(x)	(((x) >> 18) & 0x7)
-#define S3C2412_NFECCERR_MERRDATA(x)	(((x) >> 7) & 0x3ff)
-#define S3C2412_NFECCERR_MERRBIT(x)	(((x) >> 4) & 0x7)
-#define S3C2412_NFECCERR_SPARE_ERR(x)	(((x) >> 2) & 0x3)
-#define S3C2412_NFECCERR_MAIN_ERR(x)	(((x) >> 2) & 0x3)
-#define S3C2412_NFECCERR_NONE		(0)
-#define S3C2412_NFECCERR_1BIT		(1)
-#define S3C2412_NFECCERR_MULTIBIT	(2)
-#define S3C2412_NFECCERR_ECCAREA	(3)
-
-
-
-#endif /* __ASM_ARM_REGS_NAND */
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-rtc.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-rtc.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-rtc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-rtc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,61 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-rtc.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 Internal RTC register definition
-*/
-
-#ifndef __ASM_ARCH_REGS_RTC_H
-#define __ASM_ARCH_REGS_RTC_H __FILE__
-
-#define S3C2410_RTCREG(x) (x)
-
-#define S3C2410_RTCCON	      S3C2410_RTCREG(0x40)
-#define S3C2410_RTCCON_RTCEN  (1<<0)
-#define S3C2410_RTCCON_CLKSEL (1<<1)
-#define S3C2410_RTCCON_CNTSEL (1<<2)
-#define S3C2410_RTCCON_CLKRST (1<<3)
-
-#define S3C2410_TICNT	      S3C2410_RTCREG(0x44)
-#define S3C2410_TICNT_ENABLE  (1<<7)
-
-#define S3C2410_RTCALM	      S3C2410_RTCREG(0x50)
-#define S3C2410_RTCALM_ALMEN  (1<<6)
-#define S3C2410_RTCALM_YEAREN (1<<5)
-#define S3C2410_RTCALM_MONEN  (1<<4)
-#define S3C2410_RTCALM_DAYEN  (1<<3)
-#define S3C2410_RTCALM_HOUREN (1<<2)
-#define S3C2410_RTCALM_MINEN  (1<<1)
-#define S3C2410_RTCALM_SECEN  (1<<0)
-
-#define S3C2410_RTCALM_ALL \
-  S3C2410_RTCALM_ALMEN | S3C2410_RTCALM_YEAREN | S3C2410_RTCALM_MONEN |\
-  S3C2410_RTCALM_DAYEN | S3C2410_RTCALM_HOUREN | S3C2410_RTCALM_MINEN |\
-  S3C2410_RTCALM_SECEN
-
-
-#define S3C2410_ALMSEC	      S3C2410_RTCREG(0x54)
-#define S3C2410_ALMMIN	      S3C2410_RTCREG(0x58)
-#define S3C2410_ALMHOUR	      S3C2410_RTCREG(0x5c)
-
-#define S3C2410_ALMDATE	      S3C2410_RTCREG(0x60)
-#define S3C2410_ALMMON	      S3C2410_RTCREG(0x64)
-#define S3C2410_ALMYEAR	      S3C2410_RTCREG(0x68)
-
-#define S3C2410_RTCRST	      S3C2410_RTCREG(0x6c)
-
-#define S3C2410_RTCSEC	      S3C2410_RTCREG(0x70)
-#define S3C2410_RTCMIN	      S3C2410_RTCREG(0x74)
-#define S3C2410_RTCHOUR	      S3C2410_RTCREG(0x78)
-#define S3C2410_RTCDATE	      S3C2410_RTCREG(0x7c)
-#define S3C2410_RTCDAY	      S3C2410_RTCREG(0x80)
-#define S3C2410_RTCMON	      S3C2410_RTCREG(0x84)
-#define S3C2410_RTCYEAR	      S3C2410_RTCREG(0x88)
-
-
-#endif /* __ASM_ARCH_REGS_RTC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,82 +0,0 @@
-/* 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_BLC_16BIT	(0 << 13)
-#define S3C64XX_IISMOD_BLC_8BIT		(1 << 13)
-#define S3C64XX_IISMOD_BLC_24BIT	(2 << 13)
-#define S3C64XX_IISMOD_BLC_MASK		(3 << 13)
-
-#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 S3C64XX_IISMOD_CDCLKCON		(1 << 12)
-
-#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.33-gnu1/arch/arm/plat-s3c/include/plat/regs-sdhci.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-sdhci.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-sdhci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-sdhci.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,87 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/regs-sdhci.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C Platform - SDHCI (HSMMC) register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __PLAT_S3C_SDHCI_REGS_H
-#define __PLAT_S3C_SDHCI_REGS_H __FILE__
-
-#define S3C_SDHCI_CONTROL2			(0x80)
-#define S3C_SDHCI_CONTROL3			(0x84)
-#define S3C64XX_SDHCI_CONTROL4			(0x8C)
-
-#define S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR	(1 << 31)
-#define S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK		(1 << 30)
-#define S3C_SDHCI_CTRL2_CDINVRXD3		(1 << 29)
-#define S3C_SDHCI_CTRL2_SLCARDOUT		(1 << 28)
-
-#define S3C_SDHCI_CTRL2_FLTCLKSEL_MASK		(0xf << 24)
-#define S3C_SDHCI_CTRL2_FLTCLKSEL_SHIFT		(24)
-#define S3C_SDHCI_CTRL2_FLTCLKSEL(_x)		((_x) << 24)
-
-#define S3C_SDHCI_CTRL2_LVLDAT_MASK		(0xff << 16)
-#define S3C_SDHCI_CTRL2_LVLDAT_SHIFT		(16)
-#define S3C_SDHCI_CTRL2_LVLDAT(_x)		((_x) << 16)
-
-#define S3C_SDHCI_CTRL2_ENFBCLKTX		(1 << 15)
-#define S3C_SDHCI_CTRL2_ENFBCLKRX		(1 << 14)
-#define S3C_SDHCI_CTRL2_SDCDSEL			(1 << 13)
-#define S3C_SDHCI_CTRL2_SDSIGPC			(1 << 12)
-#define S3C_SDHCI_CTRL2_ENBUSYCHKTXSTART	(1 << 11)
-
-#define S3C_SDHCI_CTRL2_DFCNT_MASK		(0x3 << 9)
-#define S3C_SDHCI_CTRL2_DFCNT_SHIFT		(9)
-#define S3C_SDHCI_CTRL2_DFCNT_NONE		(0x0 << 9)
-#define S3C_SDHCI_CTRL2_DFCNT_4SDCLK		(0x1 << 9)
-#define S3C_SDHCI_CTRL2_DFCNT_16SDCLK		(0x2 << 9)
-#define S3C_SDHCI_CTRL2_DFCNT_64SDCLK		(0x3 << 9)
-
-#define S3C_SDHCI_CTRL2_ENCLKOUTHOLD		(1 << 8)
-#define S3C_SDHCI_CTRL2_RWAITMODE		(1 << 7)
-#define S3C_SDHCI_CTRL2_DISBUFRD		(1 << 6)
-#define S3C_SDHCI_CTRL2_SELBASECLK_MASK		(0x3 << 4)
-#define S3C_SDHCI_CTRL2_SELBASECLK_SHIFT	(4)
-#define S3C_SDHCI_CTRL2_PWRSYNC			(1 << 3)
-#define S3C_SDHCI_CTRL2_ENCLKOUTMSKCON		(1 << 1)
-#define S3C_SDHCI_CTRL2_HWINITFIN		(1 << 0)
-
-#define S3C_SDHCI_CTRL3_FCSEL3			(1 << 31)
-#define S3C_SDHCI_CTRL3_FCSEL2			(1 << 23)
-#define S3C_SDHCI_CTRL3_FCSEL1			(1 << 15)
-#define S3C_SDHCI_CTRL3_FCSEL0			(1 << 7)
-
-#define S3C_SDHCI_CTRL3_FIA3_MASK		(0x7f << 24)
-#define S3C_SDHCI_CTRL3_FIA3_SHIFT		(24)
-#define S3C_SDHCI_CTRL3_FIA3(_x)		((_x) << 24)
-
-#define S3C_SDHCI_CTRL3_FIA2_MASK		(0x7f << 16)
-#define S3C_SDHCI_CTRL3_FIA2_SHIFT		(16)
-#define S3C_SDHCI_CTRL3_FIA2(_x)		((_x) << 16)
-
-#define S3C_SDHCI_CTRL3_FIA1_MASK		(0x7f << 8)
-#define S3C_SDHCI_CTRL3_FIA1_SHIFT		(8)
-#define S3C_SDHCI_CTRL3_FIA1(_x)		((_x) << 8)
-
-#define S3C_SDHCI_CTRL3_FIA0_MASK		(0x7f << 0)
-#define S3C_SDHCI_CTRL3_FIA0_SHIFT		(0)
-#define S3C_SDHCI_CTRL3_FIA0(_x)		((_x) << 0)
-
-#define S3C64XX_SDHCI_CONTROL4_DRIVE_MASK	(0x3 << 16)
-#define S3C64XX_SDHCI_CONTROL4_DRIVE_SHIFT	(16)
-#define S3C64XX_SDHCI_CONTROL4_DRIVE_2mA	(0x0 << 16)
-#define S3C64XX_SDHCI_CONTROL4_DRIVE_4mA	(0x1 << 16)
-#define S3C64XX_SDHCI_CONTROL4_DRIVE_7mA	(0x2 << 16)
-#define S3C64XX_SDHCI_CONTROL4_DRIVE_9mA	(0x3 << 16)
-
-#define S3C64XX_SDHCI_CONTROL4_BUSY		(1)
-
-#endif /* __PLAT_S3C_SDHCI_REGS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-serial.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-serial.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-serial.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-serial.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,251 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-serial.h
- *
- *  From linux/include/asm-arm/hardware/serial_s3c2410.h
- *
- *  Internal header file for Samsung S3C2410 serial ports (UART0-2)
- *
- *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
- *
- *  Additional defines, Copyright 2003 Simtec Electronics (linux@simtec.co.uk)
- *
- *  Adapted from:
- *
- *  Internal header file for MX1ADS serial ports (UART1 & 2)
- *
- *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef __ASM_ARM_REGS_SERIAL_H
-#define __ASM_ARM_REGS_SERIAL_H
-
-#define S3C24XX_VA_UART0      (S3C_VA_UART)
-#define S3C24XX_VA_UART1      (S3C_VA_UART + 0x4000 )
-#define S3C24XX_VA_UART2      (S3C_VA_UART + 0x8000 )
-#define S3C24XX_VA_UART3      (S3C_VA_UART + 0xC000 )
-
-#define S3C2410_PA_UART0      (S3C24XX_PA_UART)
-#define S3C2410_PA_UART1      (S3C24XX_PA_UART + 0x4000 )
-#define S3C2410_PA_UART2      (S3C24XX_PA_UART + 0x8000 )
-#define S3C2443_PA_UART3      (S3C24XX_PA_UART + 0xC000 )
-
-#define S3C2410_URXH	  (0x24)
-#define S3C2410_UTXH	  (0x20)
-#define S3C2410_ULCON	  (0x00)
-#define S3C2410_UCON	  (0x04)
-#define S3C2410_UFCON	  (0x08)
-#define S3C2410_UMCON	  (0x0C)
-#define S3C2410_UBRDIV	  (0x28)
-#define S3C2410_UTRSTAT	  (0x10)
-#define S3C2410_UERSTAT	  (0x14)
-#define S3C2410_UFSTAT	  (0x18)
-#define S3C2410_UMSTAT	  (0x1C)
-
-#define S3C2410_LCON_CFGMASK	  ((0xF<<3)|(0x3))
-
-#define S3C2410_LCON_CS5	  (0x0)
-#define S3C2410_LCON_CS6	  (0x1)
-#define S3C2410_LCON_CS7	  (0x2)
-#define S3C2410_LCON_CS8	  (0x3)
-#define S3C2410_LCON_CSMASK	  (0x3)
-
-#define S3C2410_LCON_PNONE	  (0x0)
-#define S3C2410_LCON_PEVEN	  (0x5 << 3)
-#define S3C2410_LCON_PODD	  (0x4 << 3)
-#define S3C2410_LCON_PMASK	  (0x7 << 3)
-
-#define S3C2410_LCON_STOPB	  (1<<2)
-#define S3C2410_LCON_IRM          (1<<6)
-
-#define S3C2440_UCON_CLKMASK	  (3<<10)
-#define S3C2440_UCON_PCLK	  (0<<10)
-#define S3C2440_UCON_UCLK	  (1<<10)
-#define S3C2440_UCON_PCLK2	  (2<<10)
-#define S3C2440_UCON_FCLK	  (3<<10)
-#define S3C2443_UCON_EPLL	  (3<<10)
-
-#define S3C6400_UCON_CLKMASK	(3<<10)
-#define S3C6400_UCON_PCLK	(0<<10)
-#define S3C6400_UCON_PCLK2	(2<<10)
-#define S3C6400_UCON_UCLK0	(1<<10)
-#define S3C6400_UCON_UCLK1	(3<<10)
-
-#define S3C2440_UCON2_FCLK_EN	  (1<<15)
-#define S3C2440_UCON0_DIVMASK	  (15 << 12)
-#define S3C2440_UCON1_DIVMASK	  (15 << 12)
-#define S3C2440_UCON2_DIVMASK	  (7 << 12)
-#define S3C2440_UCON_DIVSHIFT	  (12)
-
-#define S3C2412_UCON_CLKMASK	(3<<10)
-#define S3C2412_UCON_UCLK	(1<<10)
-#define S3C2412_UCON_USYSCLK	(3<<10)
-#define S3C2412_UCON_PCLK	(0<<10)
-#define S3C2412_UCON_PCLK2	(2<<10)
-
-#define S3C2410_UCON_UCLK	  (1<<10)
-#define S3C2410_UCON_SBREAK	  (1<<4)
-
-#define S3C2410_UCON_TXILEVEL	  (1<<9)
-#define S3C2410_UCON_RXILEVEL	  (1<<8)
-#define S3C2410_UCON_TXIRQMODE	  (1<<2)
-#define S3C2410_UCON_RXIRQMODE	  (1<<0)
-#define S3C2410_UCON_RXFIFO_TOI	  (1<<7)
-#define S3C2443_UCON_RXERR_IRQEN  (1<<6)
-#define S3C2443_UCON_LOOPBACK	  (1<<5)
-
-#define S3C2410_UCON_DEFAULT	  (S3C2410_UCON_TXILEVEL  | \
-				   S3C2410_UCON_RXILEVEL  | \
-				   S3C2410_UCON_TXIRQMODE | \
-				   S3C2410_UCON_RXIRQMODE | \
-				   S3C2410_UCON_RXFIFO_TOI)
-
-#define S3C2410_UFCON_FIFOMODE	  (1<<0)
-#define S3C2410_UFCON_TXTRIG0	  (0<<6)
-#define S3C2410_UFCON_RXTRIG8	  (1<<4)
-#define S3C2410_UFCON_RXTRIG12	  (2<<4)
-
-/* S3C2440 FIFO trigger levels */
-#define S3C2440_UFCON_RXTRIG1	  (0<<4)
-#define S3C2440_UFCON_RXTRIG8	  (1<<4)
-#define S3C2440_UFCON_RXTRIG16	  (2<<4)
-#define S3C2440_UFCON_RXTRIG32	  (3<<4)
-
-#define S3C2440_UFCON_TXTRIG0	  (0<<6)
-#define S3C2440_UFCON_TXTRIG16	  (1<<6)
-#define S3C2440_UFCON_TXTRIG32	  (2<<6)
-#define S3C2440_UFCON_TXTRIG48	  (3<<6)
-
-#define S3C2410_UFCON_RESETBOTH	  (3<<1)
-#define S3C2410_UFCON_RESETTX	  (1<<2)
-#define S3C2410_UFCON_RESETRX	  (1<<1)
-
-#define S3C2410_UFCON_DEFAULT	  (S3C2410_UFCON_FIFOMODE | \
-				   S3C2410_UFCON_TXTRIG0  | \
-				   S3C2410_UFCON_RXTRIG8 )
-
-#define	S3C2410_UMCOM_AFC	  (1<<4)
-#define	S3C2410_UMCOM_RTS_LOW	  (1<<0)
-
-#define S3C2412_UMCON_AFC_63	(0<<5)		/* same as s3c2443 */
-#define S3C2412_UMCON_AFC_56	(1<<5)
-#define S3C2412_UMCON_AFC_48	(2<<5)
-#define S3C2412_UMCON_AFC_40	(3<<5)
-#define S3C2412_UMCON_AFC_32	(4<<5)
-#define S3C2412_UMCON_AFC_24	(5<<5)
-#define S3C2412_UMCON_AFC_16	(6<<5)
-#define S3C2412_UMCON_AFC_8	(7<<5)
-
-#define S3C2410_UFSTAT_TXFULL	  (1<<9)
-#define S3C2410_UFSTAT_RXFULL	  (1<<8)
-#define S3C2410_UFSTAT_TXMASK	  (15<<4)
-#define S3C2410_UFSTAT_TXSHIFT	  (4)
-#define S3C2410_UFSTAT_RXMASK	  (15<<0)
-#define S3C2410_UFSTAT_RXSHIFT	  (0)
-
-/* UFSTAT S3C24A0 */
-#define S3C24A0_UFSTAT_TXFULL	  (1 << 14)
-#define S3C24A0_UFSTAT_RXFULL	  (1 << 6)
-#define S3C24A0_UFSTAT_TXMASK	  (63 << 8)
-#define S3C24A0_UFSTAT_TXSHIFT	  (8)
-#define S3C24A0_UFSTAT_RXMASK	  (63)
-#define S3C24A0_UFSTAT_RXSHIFT	  (0)
-
-/* UFSTAT S3C2443 same as S3C2440 */
-#define S3C2440_UFSTAT_TXFULL	  (1<<14)
-#define S3C2440_UFSTAT_RXFULL	  (1<<6)
-#define S3C2440_UFSTAT_TXSHIFT	  (8)
-#define S3C2440_UFSTAT_RXSHIFT	  (0)
-#define S3C2440_UFSTAT_TXMASK	  (63<<8)
-#define S3C2440_UFSTAT_RXMASK	  (63)
-
-#define S3C2410_UTRSTAT_TXE	  (1<<2)
-#define S3C2410_UTRSTAT_TXFE	  (1<<1)
-#define S3C2410_UTRSTAT_RXDR	  (1<<0)
-
-#define S3C2410_UERSTAT_OVERRUN	  (1<<0)
-#define S3C2410_UERSTAT_FRAME	  (1<<2)
-#define S3C2410_UERSTAT_BREAK	  (1<<3)
-#define S3C2443_UERSTAT_PARITY	  (1<<1)
-
-#define S3C2410_UERSTAT_ANY	  (S3C2410_UERSTAT_OVERRUN | \
-				   S3C2410_UERSTAT_FRAME | \
-				   S3C2410_UERSTAT_BREAK)
-
-#define S3C2410_UMSTAT_CTS	  (1<<0)
-#define S3C2410_UMSTAT_DeltaCTS	  (1<<2)
-
-#define S3C2443_DIVSLOT		  (0x2C)
-
-/* S3C64XX interrupt registers. */
-#define S3C64XX_UINTP		0x30
-#define S3C64XX_UINTSP		0x34
-#define S3C64XX_UINTM		0x38
-
-#ifndef __ASSEMBLY__
-
-/* struct s3c24xx_uart_clksrc
- *
- * this structure defines a named clock source that can be used for the
- * uart, so that the best clock can be selected for the requested baud
- * rate.
- *
- * min_baud and max_baud define the range of baud-rates this clock is
- * acceptable for, if they are both zero, it is assumed any baud rate that
- * can be generated from this clock will be used.
- *
- * divisor gives the divisor from the clock to the one seen by the uart
-*/
-
-struct s3c24xx_uart_clksrc {
-	const char	*name;
-	unsigned int	 divisor;
-	unsigned int	 min_baud;
-	unsigned int	 max_baud;
-};
-
-/* configuration structure for per-machine configurations for the
- * serial port
- *
- * the pointer is setup by the machine specific initialisation from the
- * arch/arm/mach-s3c2410/ directory.
-*/
-
-struct s3c2410_uartcfg {
-	unsigned char	   hwport;	 /* hardware port number */
-	unsigned char	   unused;
-	unsigned short	   flags;
-	upf_t		   uart_flags;	 /* default uart flags */
-
-	unsigned long	   ucon;	 /* value of ucon for port */
-	unsigned long	   ulcon;	 /* value of ulcon for port */
-	unsigned long	   ufcon;	 /* value of ufcon for port */
-
-	struct s3c24xx_uart_clksrc *clocks;
-	unsigned int		    clocks_size;
-};
-
-/* s3c24xx_uart_devs
- *
- * this is exported from the core as we cannot use driver_register(),
- * or platform_add_device() before the console_initcall()
-*/
-
-extern struct platform_device *s3c24xx_uart_devs[4];
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __ASM_ARM_REGS_SERIAL_H */
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-timer.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-timer.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-timer.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-timer.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,124 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-timer.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 Timer configuration
-*/
-
-#ifndef __ASM_ARCH_REGS_TIMER_H
-#define __ASM_ARCH_REGS_TIMER_H
-
-#define S3C_TIMERREG(x) (S3C_VA_TIMER + (x))
-#define S3C_TIMERREG2(tmr,reg) S3C_TIMERREG((reg)+0x0c+((tmr)*0x0c))
-
-#define S3C2410_TCFG0	      S3C_TIMERREG(0x00)
-#define S3C2410_TCFG1	      S3C_TIMERREG(0x04)
-#define S3C2410_TCON	      S3C_TIMERREG(0x08)
-
-#define S3C64XX_TINT_CSTAT    S3C_TIMERREG(0x44)
-
-#define S3C2410_TCFG_PRESCALER0_MASK (255<<0)
-#define S3C2410_TCFG_PRESCALER1_MASK (255<<8)
-#define S3C2410_TCFG_PRESCALER1_SHIFT (8)
-#define S3C2410_TCFG_DEADZONE_MASK   (255<<16)
-#define S3C2410_TCFG_DEADZONE_SHIFT  (16)
-
-#define S3C2410_TCFG1_MUX4_DIV2	  (0<<16)
-#define S3C2410_TCFG1_MUX4_DIV4	  (1<<16)
-#define S3C2410_TCFG1_MUX4_DIV8	  (2<<16)
-#define S3C2410_TCFG1_MUX4_DIV16  (3<<16)
-#define S3C2410_TCFG1_MUX4_TCLK1  (4<<16)
-#define S3C2410_TCFG1_MUX4_MASK	  (15<<16)
-#define S3C2410_TCFG1_MUX4_SHIFT  (16)
-
-#define S3C2410_TCFG1_MUX3_DIV2	  (0<<12)
-#define S3C2410_TCFG1_MUX3_DIV4	  (1<<12)
-#define S3C2410_TCFG1_MUX3_DIV8	  (2<<12)
-#define S3C2410_TCFG1_MUX3_DIV16  (3<<12)
-#define S3C2410_TCFG1_MUX3_TCLK1  (4<<12)
-#define S3C2410_TCFG1_MUX3_MASK	  (15<<12)
-
-
-#define S3C2410_TCFG1_MUX2_DIV2	  (0<<8)
-#define S3C2410_TCFG1_MUX2_DIV4	  (1<<8)
-#define S3C2410_TCFG1_MUX2_DIV8	  (2<<8)
-#define S3C2410_TCFG1_MUX2_DIV16  (3<<8)
-#define S3C2410_TCFG1_MUX2_TCLK1  (4<<8)
-#define S3C2410_TCFG1_MUX2_MASK	  (15<<8)
-
-
-#define S3C2410_TCFG1_MUX1_DIV2	  (0<<4)
-#define S3C2410_TCFG1_MUX1_DIV4	  (1<<4)
-#define S3C2410_TCFG1_MUX1_DIV8	  (2<<4)
-#define S3C2410_TCFG1_MUX1_DIV16  (3<<4)
-#define S3C2410_TCFG1_MUX1_TCLK0  (4<<4)
-#define S3C2410_TCFG1_MUX1_MASK	  (15<<4)
-
-#define S3C2410_TCFG1_MUX0_DIV2	  (0<<0)
-#define S3C2410_TCFG1_MUX0_DIV4	  (1<<0)
-#define S3C2410_TCFG1_MUX0_DIV8	  (2<<0)
-#define S3C2410_TCFG1_MUX0_DIV16  (3<<0)
-#define S3C2410_TCFG1_MUX0_TCLK0  (4<<0)
-#define S3C2410_TCFG1_MUX0_MASK	  (15<<0)
-
-#define S3C2410_TCFG1_MUX_DIV2	  (0<<0)
-#define S3C2410_TCFG1_MUX_DIV4	  (1<<0)
-#define S3C2410_TCFG1_MUX_DIV8	  (2<<0)
-#define S3C2410_TCFG1_MUX_DIV16   (3<<0)
-#define S3C2410_TCFG1_MUX_TCLK    (4<<0)
-#define S3C2410_TCFG1_MUX_MASK	  (15<<0)
-
-#define S3C64XX_TCFG1_MUX_DIV1	  (0<<0)
-#define S3C64XX_TCFG1_MUX_DIV2	  (1<<0)
-#define S3C64XX_TCFG1_MUX_DIV4	  (2<<0)
-#define S3C64XX_TCFG1_MUX_DIV8    (3<<0)
-#define S3C64XX_TCFG1_MUX_DIV16   (4<<0)
-#define S3C64XX_TCFG1_MUX_TCLK    (5<<0)  /* 3 sets of TCLK */
-#define S3C64XX_TCFG1_MUX_MASK	  (15<<0)
-
-#define S3C2410_TCFG1_SHIFT(x)	  ((x) * 4)
-
-/* for each timer, we have an count buffer, an compare buffer and
- * an observation buffer
-*/
-
-/* WARNING - timer 4 has no buffer reg, and it's observation is at +4 */
-
-#define S3C2410_TCNTB(tmr)    S3C_TIMERREG2(tmr, 0x00)
-#define S3C2410_TCMPB(tmr)    S3C_TIMERREG2(tmr, 0x04)
-#define S3C2410_TCNTO(tmr)    S3C_TIMERREG2(tmr, (((tmr) == 4) ? 0x04 : 0x08))
-
-#define S3C2410_TCON_T4RELOAD	  (1<<22)
-#define S3C2410_TCON_T4MANUALUPD  (1<<21)
-#define S3C2410_TCON_T4START	  (1<<20)
-
-#define S3C2410_TCON_T3RELOAD	  (1<<19)
-#define S3C2410_TCON_T3INVERT	  (1<<18)
-#define S3C2410_TCON_T3MANUALUPD  (1<<17)
-#define S3C2410_TCON_T3START	  (1<<16)
-
-#define S3C2410_TCON_T2RELOAD	  (1<<15)
-#define S3C2410_TCON_T2INVERT	  (1<<14)
-#define S3C2410_TCON_T2MANUALUPD  (1<<13)
-#define S3C2410_TCON_T2START	  (1<<12)
-
-#define S3C2410_TCON_T1RELOAD	  (1<<11)
-#define S3C2410_TCON_T1INVERT	  (1<<10)
-#define S3C2410_TCON_T1MANUALUPD  (1<<9)
-#define S3C2410_TCON_T1START	  (1<<8)
-
-#define S3C2410_TCON_T0DEADZONE	  (1<<4)
-#define S3C2410_TCON_T0RELOAD	  (1<<3)
-#define S3C2410_TCON_T0INVERT	  (1<<2)
-#define S3C2410_TCON_T0MANUALUPD  (1<<1)
-#define S3C2410_TCON_T0START	  (1<<0)
-
-#endif /*  __ASM_ARCH_REGS_TIMER_H */
-
-
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,377 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      http://armlinux.simtec.co.uk/
- *      Ben Dooks <ben@simtec.co.uk>
- *
- * S3C - USB2.0 Highspeed/OtG device 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_USB_HSOTG_H
-#define __PLAT_S3C64XX_REGS_USB_HSOTG_H __FILE__
-
-#define S3C_HSOTG_REG(x) (x)
-
-#define S3C_GOTGCTL				S3C_HSOTG_REG(0x000)
-#define S3C_GOTGCTL_BSESVLD			(1 << 19)
-#define S3C_GOTGCTL_ASESVLD			(1 << 18)
-#define S3C_GOTGCTL_DBNC_SHORT			(1 << 17)
-#define S3C_GOTGCTL_CONID_B			(1 << 16)
-#define S3C_GOTGCTL_DEVHNPEN			(1 << 11)
-#define S3C_GOTGCTL_HSSETHNPEN			(1 << 10)
-#define S3C_GOTGCTL_HNPREQ			(1 << 9)
-#define S3C_GOTGCTL_HSTNEGSCS			(1 << 8)
-#define S3C_GOTGCTL_SESREQ			(1 << 1)
-#define S3C_GOTGCTL_SESREQSCS			(1 << 0)
-
-#define S3C_GOTGINT				S3C_HSOTG_REG(0x004)
-#define S3C_GOTGINT_DbnceDone			(1 << 19)
-#define S3C_GOTGINT_ADevTOUTChg			(1 << 18)
-#define S3C_GOTGINT_HstNegDet			(1 << 17)
-#define S3C_GOTGINT_HstnegSucStsChng		(1 << 9)
-#define S3C_GOTGINT_SesReqSucStsChng		(1 << 8)
-#define S3C_GOTGINT_SesEndDet			(1 << 2)
-
-#define S3C_GAHBCFG				S3C_HSOTG_REG(0x008)
-#define S3C_GAHBCFG_PTxFEmpLvl			(1 << 8)
-#define S3C_GAHBCFG_NPTxFEmpLvl			(1 << 7)
-#define S3C_GAHBCFG_DMAEn			(1 << 5)
-#define S3C_GAHBCFG_HBstLen_MASK		(0xf << 1)
-#define S3C_GAHBCFG_HBstLen_SHIFT		(1)
-#define S3C_GAHBCFG_HBstLen_Single		(0x0 << 1)
-#define S3C_GAHBCFG_HBstLen_Incr		(0x1 << 1)
-#define S3C_GAHBCFG_HBstLen_Incr4		(0x3 << 1)
-#define S3C_GAHBCFG_HBstLen_Incr8		(0x5 << 1)
-#define S3C_GAHBCFG_HBstLen_Incr16		(0x7 << 1)
-#define S3C_GAHBCFG_GlblIntrEn			(1 << 0)
-
-#define S3C_GUSBCFG				S3C_HSOTG_REG(0x00C)
-#define S3C_GUSBCFG_PHYLPClkSel			(1 << 15)
-#define S3C_GUSBCFG_HNPCap			(1 << 9)
-#define S3C_GUSBCFG_SRPCap			(1 << 8)
-#define S3C_GUSBCFG_PHYIf16			(1 << 3)
-#define S3C_GUSBCFG_TOutCal_MASK		(0x7 << 0)
-#define S3C_GUSBCFG_TOutCal_SHIFT		(0)
-#define S3C_GUSBCFG_TOutCal_LIMIT		(0x7)
-#define S3C_GUSBCFG_TOutCal(_x)			((_x) << 0)
-
-#define S3C_GRSTCTL				S3C_HSOTG_REG(0x010)
-
-#define S3C_GRSTCTL_AHBIdle			(1 << 31)
-#define S3C_GRSTCTL_DMAReq			(1 << 30)
-#define S3C_GRSTCTL_TxFNum_MASK			(0x1f << 6)
-#define S3C_GRSTCTL_TxFNum_SHIFT		(6)
-#define S3C_GRSTCTL_TxFNum_LIMIT		(0x1f)
-#define S3C_GRSTCTL_TxFNum(_x)			((_x) << 6)
-#define S3C_GRSTCTL_TxFFlsh			(1 << 5)
-#define S3C_GRSTCTL_RxFFlsh			(1 << 4)
-#define S3C_GRSTCTL_INTknQFlsh			(1 << 3)
-#define S3C_GRSTCTL_FrmCntrRst			(1 << 2)
-#define S3C_GRSTCTL_HSftRst			(1 << 1)
-#define S3C_GRSTCTL_CSftRst			(1 << 0)
-
-#define S3C_GINTSTS				S3C_HSOTG_REG(0x014)
-#define S3C_GINTMSK				S3C_HSOTG_REG(0x018)
-
-#define S3C_GINTSTS_WkUpInt			(1 << 31)
-#define S3C_GINTSTS_SessReqInt			(1 << 30)
-#define S3C_GINTSTS_DisconnInt			(1 << 29)
-#define S3C_GINTSTS_ConIDStsChng		(1 << 28)
-#define S3C_GINTSTS_PTxFEmp			(1 << 26)
-#define S3C_GINTSTS_HChInt			(1 << 25)
-#define S3C_GINTSTS_PrtInt			(1 << 24)
-#define S3C_GINTSTS_FetSusp			(1 << 22)
-#define S3C_GINTSTS_incompIP			(1 << 21)
-#define S3C_GINTSTS_IncomplSOIN			(1 << 20)
-#define S3C_GINTSTS_OEPInt			(1 << 19)
-#define S3C_GINTSTS_IEPInt			(1 << 18)
-#define S3C_GINTSTS_EPMis			(1 << 17)
-#define S3C_GINTSTS_EOPF			(1 << 15)
-#define S3C_GINTSTS_ISOutDrop			(1 << 14)
-#define S3C_GINTSTS_EnumDone			(1 << 13)
-#define S3C_GINTSTS_USBRst			(1 << 12)
-#define S3C_GINTSTS_USBSusp			(1 << 11)
-#define S3C_GINTSTS_ErlySusp			(1 << 10)
-#define S3C_GINTSTS_GOUTNakEff			(1 << 7)
-#define S3C_GINTSTS_GINNakEff			(1 << 6)
-#define S3C_GINTSTS_NPTxFEmp			(1 << 5)
-#define S3C_GINTSTS_RxFLvl			(1 << 4)
-#define S3C_GINTSTS_SOF				(1 << 3)
-#define S3C_GINTSTS_OTGInt			(1 << 2)
-#define S3C_GINTSTS_ModeMis			(1 << 1)
-#define S3C_GINTSTS_CurMod_Host			(1 << 0)
-
-#define S3C_GRXSTSR				S3C_HSOTG_REG(0x01C)
-#define S3C_GRXSTSP				S3C_HSOTG_REG(0x020)
-
-#define S3C_GRXSTS_FN_MASK			(0x7f << 25)
-#define S3C_GRXSTS_FN_SHIFT			(25)
-
-#define S3C_GRXSTS_PktSts_MASK			(0xf << 17)
-#define S3C_GRXSTS_PktSts_SHIFT			(17)
-#define S3C_GRXSTS_PktSts_GlobalOutNAK		(0x1 << 17)
-#define S3C_GRXSTS_PktSts_OutRX			(0x2 << 17)
-#define S3C_GRXSTS_PktSts_OutDone		(0x3 << 17)
-#define S3C_GRXSTS_PktSts_SetupDone		(0x4 << 17)
-#define S3C_GRXSTS_PktSts_SetupRX		(0x6 << 17)
-
-#define S3C_GRXSTS_DPID_MASK			(0x3 << 15)
-#define S3C_GRXSTS_DPID_SHIFT			(15)
-#define S3C_GRXSTS_ByteCnt_MASK			(0x7ff << 4)
-#define S3C_GRXSTS_ByteCnt_SHIFT		(4)
-#define S3C_GRXSTS_EPNum_MASK			(0xf << 0)
-#define S3C_GRXSTS_EPNum_SHIFT			(0)
-
-#define S3C_GRXFSIZ				S3C_HSOTG_REG(0x024)
-
-#define S3C_GNPTXFSIZ				S3C_HSOTG_REG(0x028)
-
-#define S3C_GNPTXFSIZ_NPTxFDep_MASK		(0xffff << 16)
-#define S3C_GNPTXFSIZ_NPTxFDep_SHIFT		(16)
-#define S3C_GNPTXFSIZ_NPTxFDep_LIMIT		(0xffff)
-#define S3C_GNPTXFSIZ_NPTxFDep(_x)		((_x) << 16)
-#define S3C_GNPTXFSIZ_NPTxFStAddr_MASK		(0xffff << 0)
-#define S3C_GNPTXFSIZ_NPTxFStAddr_SHIFT		(0)
-#define S3C_GNPTXFSIZ_NPTxFStAddr_LIMIT		(0xffff)
-#define S3C_GNPTXFSIZ_NPTxFStAddr(_x)		((_x) << 0)
-
-#define S3C_GNPTXSTS				S3C_HSOTG_REG(0x02C)
-
-#define S3C_GNPTXSTS_NPtxQTop_MASK		(0x7f << 24)
-#define S3C_GNPTXSTS_NPtxQTop_SHIFT		(24)
-
-#define S3C_GNPTXSTS_NPTxQSpcAvail_MASK		(0xff << 16)
-#define S3C_GNPTXSTS_NPTxQSpcAvail_SHIFT	(16)
-#define S3C_GNPTXSTS_NPTxQSpcAvail_GET(_v)	(((_v) >> 16) & 0xff)
-
-#define S3C_GNPTXSTS_NPTxFSpcAvail_MASK		(0xffff << 0)
-#define S3C_GNPTXSTS_NPTxFSpcAvail_SHIFT	(0)
-#define S3C_GNPTXSTS_NPTxFSpcAvail_GET(_v)	(((_v) >> 0) & 0xffff)
-
-
-#define S3C_HPTXFSIZ				S3C_HSOTG_REG(0x100)
-
-#define S3C_DPTXFSIZn(_a)			S3C_HSOTG_REG(0x104 + (((_a) - 1) * 4))
-
-#define S3C_DPTXFSIZn_DPTxFSize_MASK		(0xffff << 16)
-#define S3C_DPTXFSIZn_DPTxFSize_SHIFT		(16)
-#define S3C_DPTXFSIZn_DPTxFSize_GET(_v)		(((_v) >> 16) & 0xffff)
-#define S3C_DPTXFSIZn_DPTxFSize_LIMIT		(0xffff)
-#define S3C_DPTXFSIZn_DPTxFSize(_x)		((_x) << 16)
-
-#define S3C_DPTXFSIZn_DPTxFStAddr_MASK		(0xffff << 0)
-#define S3C_DPTXFSIZn_DPTxFStAddr_SHIFT		(0)
-
-/* Device mode registers */
-#define S3C_DCFG				S3C_HSOTG_REG(0x800)
-
-#define S3C_DCFG_EPMisCnt_MASK			(0x1f << 18)
-#define S3C_DCFG_EPMisCnt_SHIFT			(18)
-#define S3C_DCFG_EPMisCnt_LIMIT			(0x1f)
-#define S3C_DCFG_EPMisCnt(_x)			((_x) << 18)
-
-#define S3C_DCFG_PerFrInt_MASK			(0x3 << 11)
-#define S3C_DCFG_PerFrInt_SHIFT			(11)
-#define S3C_DCFG_PerFrInt_LIMIT			(0x3)
-#define S3C_DCFG_PerFrInt(_x)			((_x) << 11)
-
-#define S3C_DCFG_DevAddr_MASK			(0x7f << 4)
-#define S3C_DCFG_DevAddr_SHIFT			(4)
-#define S3C_DCFG_DevAddr_LIMIT			(0x7f)
-#define S3C_DCFG_DevAddr(_x)			((_x) << 4)
-
-#define S3C_DCFG_NZStsOUTHShk			(1 << 2)
-
-#define S3C_DCFG_DevSpd_MASK			(0x3 << 0)
-#define S3C_DCFG_DevSpd_SHIFT			(0)
-#define S3C_DCFG_DevSpd_HS			(0x0 << 0)
-#define S3C_DCFG_DevSpd_FS			(0x1 << 0)
-#define S3C_DCFG_DevSpd_LS			(0x2 << 0)
-#define S3C_DCFG_DevSpd_FS48			(0x3 << 0)
-
-#define S3C_DCTL				S3C_HSOTG_REG(0x804)
-
-#define S3C_DCTL_PWROnPrgDone			(1 << 11)
-#define S3C_DCTL_CGOUTNak			(1 << 10)
-#define S3C_DCTL_SGOUTNak			(1 << 9)
-#define S3C_DCTL_CGNPInNAK			(1 << 8)
-#define S3C_DCTL_SGNPInNAK			(1 << 7)
-#define S3C_DCTL_TstCtl_MASK			(0x7 << 4)
-#define S3C_DCTL_TstCtl_SHIFT			(4)
-#define S3C_DCTL_GOUTNakSts			(1 << 3)
-#define S3C_DCTL_GNPINNakSts			(1 << 2)
-#define S3C_DCTL_SftDiscon			(1 << 1)
-#define S3C_DCTL_RmtWkUpSig			(1 << 0)
-
-#define S3C_DSTS				S3C_HSOTG_REG(0x808)
-
-#define S3C_DSTS_SOFFN_MASK			(0x3fff << 8)
-#define S3C_DSTS_SOFFN_SHIFT			(8)
-#define S3C_DSTS_SOFFN_LIMIT			(0x3fff)
-#define S3C_DSTS_SOFFN(_x)			((_x) << 8)
-#define S3C_DSTS_ErraticErr			(1 << 3)
-#define S3C_DSTS_EnumSpd_MASK			(0x3 << 1)
-#define S3C_DSTS_EnumSpd_SHIFT			(1)
-#define S3C_DSTS_EnumSpd_HS			(0x0 << 1)
-#define S3C_DSTS_EnumSpd_FS			(0x1 << 1)
-#define S3C_DSTS_EnumSpd_LS			(0x2 << 1)
-#define S3C_DSTS_EnumSpd_FS48			(0x3 << 1)
-
-#define S3C_DSTS_SuspSts			(1 << 0)
-
-#define S3C_DIEPMSK				S3C_HSOTG_REG(0x810)
-
-#define S3C_DIEPMSK_INEPNakEffMsk		(1 << 6)
-#define S3C_DIEPMSK_INTknEPMisMsk		(1 << 5)
-#define S3C_DIEPMSK_INTknTXFEmpMsk		(1 << 4)
-#define S3C_DIEPMSK_TimeOUTMsk			(1 << 3)
-#define S3C_DIEPMSK_AHBErrMsk			(1 << 2)
-#define S3C_DIEPMSK_EPDisbldMsk			(1 << 1)
-#define S3C_DIEPMSK_XferComplMsk		(1 << 0)
-
-#define S3C_DOEPMSK				S3C_HSOTG_REG(0x814)
-
-#define S3C_DOEPMSK_Back2BackSetup		(1 << 6)
-#define S3C_DOEPMSK_OUTTknEPdisMsk		(1 << 4)
-#define S3C_DOEPMSK_SetupMsk			(1 << 3)
-#define S3C_DOEPMSK_AHBErrMsk			(1 << 2)
-#define S3C_DOEPMSK_EPDisbldMsk			(1 << 1)
-#define S3C_DOEPMSK_XferComplMsk		(1 << 0)
-
-#define S3C_DAINT				S3C_HSOTG_REG(0x818)
-#define S3C_DAINTMSK				S3C_HSOTG_REG(0x81C)
-
-#define S3C_DAINT_OutEP_SHIFT			(16)
-#define S3C_DAINT_OutEP(x)			(1 << ((x) + 16))
-#define S3C_DAINT_InEP(x)			(1 << (x))
-
-#define S3C_DTKNQR1				S3C_HSOTG_REG(0x820)
-#define S3C_DTKNQR2				S3C_HSOTG_REG(0x824)
-#define S3C_DTKNQR3				S3C_HSOTG_REG(0x830)
-#define S3C_DTKNQR4				S3C_HSOTG_REG(0x834)
-
-#define S3C_DVBUSDIS				S3C_HSOTG_REG(0x828)
-#define S3C_DVBUSPULSE				S3C_HSOTG_REG(0x82C)
-
-#define S3C_DIEPCTL0				S3C_HSOTG_REG(0x900)
-#define S3C_DOEPCTL0				S3C_HSOTG_REG(0xB00)
-#define S3C_DIEPCTL(_a)				S3C_HSOTG_REG(0x900 + ((_a) * 0x20))
-#define S3C_DOEPCTL(_a)				S3C_HSOTG_REG(0xB00 + ((_a) * 0x20))
-
-/* EP0 specialness:
- * bits[29..28] - reserved (no SetD0PID, SetD1PID)
- * bits[25..22] - should always be zero, this isn't a periodic endpoint
- * bits[10..0] - MPS setting differenct for EP0
-*/
-#define S3C_D0EPCTL_MPS_MASK			(0x3 << 0)
-#define S3C_D0EPCTL_MPS_SHIFT			(0)
-#define S3C_D0EPCTL_MPS_64			(0x0 << 0)
-#define S3C_D0EPCTL_MPS_32			(0x1 << 0)
-#define S3C_D0EPCTL_MPS_16			(0x2 << 0)
-#define S3C_D0EPCTL_MPS_8			(0x3 << 0)
-
-#define S3C_DxEPCTL_EPEna			(1 << 31)
-#define S3C_DxEPCTL_EPDis			(1 << 30)
-#define S3C_DxEPCTL_SetD1PID			(1 << 29)
-#define S3C_DxEPCTL_SetOddFr			(1 << 29)
-#define S3C_DxEPCTL_SetD0PID			(1 << 28)
-#define S3C_DxEPCTL_SetEvenFr			(1 << 28)
-#define S3C_DxEPCTL_SNAK			(1 << 27)
-#define S3C_DxEPCTL_CNAK			(1 << 26)
-#define S3C_DxEPCTL_TxFNum_MASK			(0xf << 22)
-#define S3C_DxEPCTL_TxFNum_SHIFT		(22)
-#define S3C_DxEPCTL_TxFNum_LIMIT		(0xf)
-#define S3C_DxEPCTL_TxFNum(_x)			((_x) << 22)
-
-#define S3C_DxEPCTL_Stall			(1 << 21)
-#define S3C_DxEPCTL_Snp				(1 << 20)
-#define S3C_DxEPCTL_EPType_MASK			(0x3 << 18)
-#define S3C_DxEPCTL_EPType_SHIFT		(18)
-#define S3C_DxEPCTL_EPType_Control		(0x0 << 18)
-#define S3C_DxEPCTL_EPType_Iso			(0x1 << 18)
-#define S3C_DxEPCTL_EPType_Bulk			(0x2 << 18)
-#define S3C_DxEPCTL_EPType_Intterupt		(0x3 << 18)
-
-#define S3C_DxEPCTL_NAKsts			(1 << 17)
-#define S3C_DxEPCTL_DPID			(1 << 16)
-#define S3C_DxEPCTL_EOFrNum			(1 << 16)
-#define S3C_DxEPCTL_USBActEp			(1 << 15)
-#define S3C_DxEPCTL_NextEp_MASK			(0xf << 11)
-#define S3C_DxEPCTL_NextEp_SHIFT		(11)
-#define S3C_DxEPCTL_NextEp_LIMIT		(0xf)
-#define S3C_DxEPCTL_NextEp(_x)			((_x) << 11)
-
-#define S3C_DxEPCTL_MPS_MASK			(0x7ff << 0)
-#define S3C_DxEPCTL_MPS_SHIFT			(0)
-#define S3C_DxEPCTL_MPS_LIMIT			(0x7ff)
-#define S3C_DxEPCTL_MPS(_x)			((_x) << 0)
-
-#define S3C_DIEPINT(_a)				S3C_HSOTG_REG(0x908 + ((_a) * 0x20))
-#define S3C_DOEPINT(_a)				S3C_HSOTG_REG(0xB08 + ((_a) * 0x20))
-
-#define S3C_DxEPINT_INEPNakEff			(1 << 6)
-#define S3C_DxEPINT_Back2BackSetup		(1 << 6)
-#define S3C_DxEPINT_INTknEPMis			(1 << 5)
-#define S3C_DxEPINT_INTknTXFEmp			(1 << 4)
-#define S3C_DxEPINT_OUTTknEPdis			(1 << 4)
-#define S3C_DxEPINT_Timeout			(1 << 3)
-#define S3C_DxEPINT_Setup			(1 << 3)
-#define S3C_DxEPINT_AHBErr			(1 << 2)
-#define S3C_DxEPINT_EPDisbld			(1 << 1)
-#define S3C_DxEPINT_XferCompl			(1 << 0)
-
-#define S3C_DIEPTSIZ0				S3C_HSOTG_REG(0x910)
-
-#define S3C_DIEPTSIZ0_PktCnt_MASK		(0x3 << 19)
-#define S3C_DIEPTSIZ0_PktCnt_SHIFT		(19)
-#define S3C_DIEPTSIZ0_PktCnt_LIMIT		(0x3)
-#define S3C_DIEPTSIZ0_PktCnt(_x)		((_x) << 19)
-
-#define S3C_DIEPTSIZ0_XferSize_MASK		(0x7f << 0)
-#define S3C_DIEPTSIZ0_XferSize_SHIFT		(0)
-#define S3C_DIEPTSIZ0_XferSize_LIMIT		(0x7f)
-#define S3C_DIEPTSIZ0_XferSize(_x)		((_x) << 0)
-
-
-#define DOEPTSIZ0				S3C_HSOTG_REG(0xB10)
-#define S3C_DOEPTSIZ0_SUPCnt_MASK		(0x3 << 29)
-#define S3C_DOEPTSIZ0_SUPCnt_SHIFT		(29)
-#define S3C_DOEPTSIZ0_SUPCnt_LIMIT		(0x3)
-#define S3C_DOEPTSIZ0_SUPCnt(_x)		((_x) << 29)
-
-#define S3C_DOEPTSIZ0_PktCnt			(1 << 19)
-#define S3C_DOEPTSIZ0_XferSize_MASK		(0x7f << 0)
-#define S3C_DOEPTSIZ0_XferSize_SHIFT		(0)
-
-#define S3C_DIEPTSIZ(_a)			S3C_HSOTG_REG(0x910 + ((_a) * 0x20))
-#define S3C_DOEPTSIZ(_a)			S3C_HSOTG_REG(0xB10 + ((_a) * 0x20))
-
-#define S3C_DxEPTSIZ_MC_MASK			(0x3 << 29)
-#define S3C_DxEPTSIZ_MC_SHIFT			(29)
-#define S3C_DxEPTSIZ_MC_LIMIT			(0x3)
-#define S3C_DxEPTSIZ_MC(_x)			((_x) << 29)
-
-#define S3C_DxEPTSIZ_PktCnt_MASK		(0x3ff << 19)
-#define S3C_DxEPTSIZ_PktCnt_SHIFT		(19)
-#define S3C_DxEPTSIZ_PktCnt_GET(_v)		(((_v) >> 19) & 0x3ff)
-#define S3C_DxEPTSIZ_PktCnt_LIMIT		(0x3ff)
-#define S3C_DxEPTSIZ_PktCnt(_x)			((_x) << 19)
-
-#define S3C_DxEPTSIZ_XferSize_MASK		(0x7ffff << 0)
-#define S3C_DxEPTSIZ_XferSize_SHIFT		(0)
-#define S3C_DxEPTSIZ_XferSize_GET(_v)		(((_v) >> 0) & 0x7ffff)
-#define S3C_DxEPTSIZ_XferSize_LIMIT		(0x7ffff)
-#define S3C_DxEPTSIZ_XferSize(_x)		((_x) << 0)
-
-
-#define S3C_DIEPDMA(_a)				S3C_HSOTG_REG(0x914 + ((_a) * 0x20))
-#define S3C_DOEPDMA(_a)				S3C_HSOTG_REG(0xB14 + ((_a) * 0x20))
-
-#define S3C_EPFIFO(_a)				S3C_HSOTG_REG(0x1000 + ((_a) * 0x1000))
-
-#endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,50 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      http://armlinux.simtec.co.uk/
- *      Ben Dooks <ben@simtec.co.uk>
- *
- * S3C - USB2.0 Highspeed/OtG device PHY 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.
-*/
-
-/* Note, this is a seperate header file as some of the clock framework
- * needs to touch this if the clk_48m is used as the USB OHCI or other
- * peripheral source.
-*/
-
-#ifndef __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H
-#define __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H __FILE__
-
-/* S3C64XX_PA_USB_HSPHY */
-
-#define S3C_HSOTG_PHYREG(x)	((x) + S3C_VA_USB_HSPHY)
-
-#define S3C_PHYPWR				S3C_HSOTG_PHYREG(0x00)
-#define SRC_PHYPWR_OTG_DISABLE			(1 << 4)
-#define SRC_PHYPWR_ANALOG_POWERDOWN		(1 << 3)
-#define SRC_PHYPWR_FORCE_SUSPEND		(1 << 1)
-
-#define S3C_PHYCLK				S3C_HSOTG_PHYREG(0x04)
-#define S3C_PHYCLK_MODE_USB11			(1 << 6)
-#define S3C_PHYCLK_EXT_OSC			(1 << 5)
-#define S3C_PHYCLK_CLK_FORCE			(1 << 4)
-#define S3C_PHYCLK_ID_PULL			(1 << 2)
-#define S3C_PHYCLK_CLKSEL_MASK			(0x3 << 0)
-#define S3C_PHYCLK_CLKSEL_SHIFT			(0)
-#define S3C_PHYCLK_CLKSEL_48M			(0x0 << 0)
-#define S3C_PHYCLK_CLKSEL_12M			(0x2 << 0)
-#define S3C_PHYCLK_CLKSEL_24M			(0x3 << 0)
-
-#define S3C_RSTCON				S3C_HSOTG_PHYREG(0x08)
-#define S3C_RSTCON_PHYCLK			(1 << 2)
-#define S3C_RSTCON_HCLK				(1 << 2)
-#define S3C_RSTCON_PHY				(1 << 0)
-
-#define S3C_PHYTUNE				S3C_HSOTG_PHYREG(0x20)
-
-#endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-watchdog.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-watchdog.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-watchdog.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/regs-watchdog.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-watchdog.h
- *
- * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
- *		      http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2410 Watchdog timer control
-*/
-
-
-#ifndef __ASM_ARCH_REGS_WATCHDOG_H
-#define __ASM_ARCH_REGS_WATCHDOG_H
-
-#define S3C_WDOGREG(x) ((x) + S3C_VA_WATCHDOG)
-
-#define S3C2410_WTCON	   S3C_WDOGREG(0x00)
-#define S3C2410_WTDAT	   S3C_WDOGREG(0x04)
-#define S3C2410_WTCNT	   S3C_WDOGREG(0x08)
-
-/* the watchdog can either generate a reset pulse, or an
- * interrupt.
- */
-
-#define S3C2410_WTCON_RSTEN   (0x01)
-#define S3C2410_WTCON_INTEN   (1<<2)
-#define S3C2410_WTCON_ENABLE  (1<<5)
-
-#define S3C2410_WTCON_DIV16   (0<<3)
-#define S3C2410_WTCON_DIV32   (1<<3)
-#define S3C2410_WTCON_DIV64   (2<<3)
-#define S3C2410_WTCON_DIV128  (3<<3)
-
-#define S3C2410_WTCON_PRESCALE(x) ((x) << 8)
-#define S3C2410_WTCON_PRESCALE_MASK (0xff00)
-
-#endif /* __ASM_ARCH_REGS_WATCHDOG_H */
-
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/sdhci.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/sdhci.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/sdhci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/sdhci.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,226 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/sdhci.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C Platform - SDHCI (HSMMC) platform data 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 __PLAT_S3C_SDHCI_H
-#define __PLAT_S3C_SDHCI_H __FILE__
-
-struct platform_device;
-struct mmc_host;
-struct mmc_card;
-struct mmc_ios;
-
-/**
- * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI
- * @max_width: The maximum number of data bits supported.
- * @host_caps: Standard MMC host capabilities bit field.
- * @cfg_gpio: Configure the GPIO for a specific card bit-width
- * @cfg_card: Configure the interface for a specific card and speed. This
- *            is necessary the controllers and/or GPIO blocks require the
- *	      changing of driver-strength and other controls dependant on
- *	      the card and speed of operation.
- *
- * Initialisation data specific to either the machine or the platform
- * for the device driver to use or call-back when configuring gpio or
- * card speed information.
-*/
-struct s3c_sdhci_platdata {
-	unsigned int	max_width;
-	unsigned int	host_caps;
-
-	char		**clocks;	/* set of clock sources */
-
-	void	(*cfg_gpio)(struct platform_device *dev, int width);
-	void	(*cfg_card)(struct platform_device *dev,
-			    void __iomem *regbase,
-			    struct mmc_ios *ios,
-			    struct mmc_card *card);
-};
-
-/**
- * s3c_sdhci0_set_platdata - Set platform data for S3C SDHCI device.
- * @pd: Platform data to register to device.
- *
- * Register the given platform data for use withe S3C SDHCI device.
- * The call will copy the platform data, so the board definitions can
- * make the structure itself __initdata.
- */
-extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd);
-extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd);
-extern void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd);
-
-/* Default platform data, exported so that per-cpu initialisation can
- * set the correct one when there are more than one cpu type selected.
-*/
-
-extern struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata;
-extern struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata;
-extern struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata;
-
-/* Helper function availablity */
-
-extern void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
-extern void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
-extern void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
-extern void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
-extern void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
-extern void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
-
-/* S3C6400 SDHCI setup */
-
-#ifdef CONFIG_S3C6400_SETUP_SDHCI
-extern char *s3c6400_hsmmc_clksrcs[4];
-
-#ifdef CONFIG_S3C_DEV_HSMMC
-extern void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
-					 void __iomem *r,
-					 struct mmc_ios *ios,
-					 struct mmc_card *card);
-
-static inline void s3c6400_default_sdhci0(void)
-{
-	s3c_hsmmc0_def_platdata.clocks = s3c6400_hsmmc_clksrcs;
-	s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
-	s3c_hsmmc0_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
-}
-
-#else
-static inline void s3c6400_default_sdhci0(void) { }
-#endif  /* CONFIG_S3C_DEV_HSMMC */
-
-#ifdef CONFIG_S3C_DEV_HSMMC1
-static inline void s3c6400_default_sdhci1(void)
-{
-	s3c_hsmmc1_def_platdata.clocks = s3c6400_hsmmc_clksrcs;
-	s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
-	s3c_hsmmc1_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
-}
-#else
-static inline void s3c6400_default_sdhci1(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC1 */
-
-#ifdef CONFIG_S3C_DEV_HSMMC2
-static inline void s3c6400_default_sdhci2(void)
-{
-	s3c_hsmmc2_def_platdata.clocks = s3c6400_hsmmc_clksrcs;
-	s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
-	s3c_hsmmc2_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
-}
-#else
-static inline void s3c6400_default_sdhci2(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC2 */
-
-#else
-static inline void s3c6400_default_sdhci0(void) { }
-static inline void s3c6400_default_sdhci1(void) { }
-#endif /* CONFIG_S3C6400_SETUP_SDHCI */
-
-/* S3C6410 SDHCI setup */
-
-#ifdef CONFIG_S3C6410_SETUP_SDHCI
-extern char *s3c6410_hsmmc_clksrcs[4];
-
-extern void s3c6410_setup_sdhci0_cfg_card(struct platform_device *dev,
-					   void __iomem *r,
-					   struct mmc_ios *ios,
-					   struct mmc_card *card);
-
-#ifdef CONFIG_S3C_DEV_HSMMC
-static inline void s3c6410_default_sdhci0(void)
-{
-	s3c_hsmmc0_def_platdata.clocks = s3c6410_hsmmc_clksrcs;
-	s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
-	s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci0_cfg_card;
-}
-#else
-static inline void s3c6410_default_sdhci0(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC */
-
-#ifdef CONFIG_S3C_DEV_HSMMC1
-static inline void s3c6410_default_sdhci1(void)
-{
-	s3c_hsmmc1_def_platdata.clocks = s3c6410_hsmmc_clksrcs;
-	s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
-	s3c_hsmmc1_def_platdata.cfg_card = s3c6410_setup_sdhci0_cfg_card;
-}
-#else
-static inline void s3c6410_default_sdhci1(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC1 */
-
-#ifdef CONFIG_S3C_DEV_HSMMC2
-static inline void s3c6410_default_sdhci2(void)
-{
-	s3c_hsmmc2_def_platdata.clocks = s3c6410_hsmmc_clksrcs;
-	s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
-	s3c_hsmmc2_def_platdata.cfg_card = s3c6410_setup_sdhci0_cfg_card;
-}
-#else
-static inline void s3c6410_default_sdhci2(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC2 */
-
-#else
-static inline void s3c6410_default_sdhci0(void) { }
-static inline void s3c6410_default_sdhci1(void) { }
-#endif /* CONFIG_S3C6410_SETUP_SDHCI */
-
-/* S5PC100 SDHCI setup */
-
-#ifdef CONFIG_S5PC100_SETUP_SDHCI
-extern char *s5pc100_hsmmc_clksrcs[4];
-
-extern void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
-					   void __iomem *r,
-					   struct mmc_ios *ios,
-					   struct mmc_card *card);
-
-#ifdef CONFIG_S3C_DEV_HSMMC
-static inline void s5pc100_default_sdhci0(void)
-{
-	s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
-	s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio;
-	s3c_hsmmc0_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
-}
-#else
-static inline void s5pc100_default_sdhci0(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC */
-
-#ifdef CONFIG_S3C_DEV_HSMMC1
-static inline void s5pc100_default_sdhci1(void)
-{
-	s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
-	s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio;
-	s3c_hsmmc1_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
-}
-#else
-static inline void s5pc100_default_sdhci1(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC1 */
-
-#ifdef CONFIG_S3C_DEV_HSMMC2
-static inline void s5pc100_default_sdhci2(void)
-{
-	s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
-	s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio;
-	s3c_hsmmc2_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
-}
-#else
-static inline void s5pc100_default_sdhci2(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC1 */
-
-
-#else
-static inline void s5pc100_default_sdhci0(void) { }
-static inline void s5pc100_default_sdhci1(void) { }
-static inline void s5pc100_default_sdhci2(void) { }
-#endif /* CONFIG_S5PC100_SETUP_SDHCI */
-
-#endif /* __PLAT_S3C_SDHCI_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/udc-hs.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/udc-hs.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/udc-hs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/udc-hs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,29 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/udc-hs.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C USB2.0 High-speed / OtG platform 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.
-*/
-
-enum s3c_hostg_dmamode {
-	S3C_HSOTG_DMA_NONE,	/* do not use DMA at-all */
-	S3C_HSOTG_DMA_ONLY,	/* always use DMA */
-	S3C_HSOTG_DMA_DRV,	/* DMA is chosen by driver */
-};
-
-/**
- * struct s3c_hsotg_plat - platform data for high-speed otg/udc
- * @dma: Whether to use DMA or not.
- * @is_osc: The clock source is an oscillator, not a crystal
- */
-struct s3c_hsotg_plat {
-	enum s3c_hostg_dmamode	dma;
-	unsigned int		is_osc : 1;
-};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/uncompress.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/uncompress.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/uncompress.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/uncompress.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,186 +0,0 @@
-/* linux/include/asm-arm/plat-s3c/uncompress.h
- *
- * Copyright 2003, 2007 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C - uncompress 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.
-*/
-
-#ifndef __ASM_PLAT_UNCOMPRESS_H
-#define __ASM_PLAT_UNCOMPRESS_H
-
-typedef unsigned int upf_t;	/* cannot include linux/serial_core.h */
-
-/* uart setup */
-
-static unsigned int fifo_mask;
-static unsigned int fifo_max;
-
-/* forward declerations */
-
-static void arch_detect_cpu(void);
-
-/* defines for UART registers */
-
-#include <plat/regs-serial.h>
-#include <plat/regs-watchdog.h>
-
-/* working in physical space... */
-#undef S3C2410_WDOGREG
-#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
-
-/* how many bytes we allow into the FIFO at a time in FIFO mode */
-#define FIFO_MAX	 (14)
-
-#define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT)
-
-static __inline__ void
-uart_wr(unsigned int reg, unsigned int val)
-{
-	volatile unsigned int *ptr;
-
-	ptr = (volatile unsigned int *)(reg + uart_base);
-	*ptr = val;
-}
-
-static __inline__ unsigned int
-uart_rd(unsigned int reg)
-{
-	volatile unsigned int *ptr;
-
-	ptr = (volatile unsigned int *)(reg + uart_base);
-	return *ptr;
-}
-
-/* we can deal with the case the UARTs are being run
- * in FIFO mode, so that we don't hold up our execution
- * waiting for tx to happen...
-*/
-
-static void putc(int ch)
-{
-	if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
-		int level;
-
-		while (1) {
-			level = uart_rd(S3C2410_UFSTAT);
-			level &= fifo_mask;
-
-			if (level < fifo_max)
-				break;
-		}
-
-	} else {
-		/* not using fifos */
-
-		while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE)
-			barrier();
-	}
-
-	/* write byte to transmission register */
-	uart_wr(S3C2410_UTXH, ch);
-}
-
-static inline void flush(void)
-{
-}
-
-#define __raw_writel(d, ad)			\
-	do {							\
-		*((volatile unsigned int __force *)(ad)) = (d); \
-	} while (0)
-
-/* CONFIG_S3C_BOOT_WATCHDOG
- *
- * Simple boot-time watchdog setup, to reboot the system if there is
- * any problem with the boot process
-*/
-
-#ifdef CONFIG_S3C_BOOT_WATCHDOG
-
-#define WDOG_COUNT (0xff00)
-
-static inline void arch_decomp_wdog(void)
-{
-	__raw_writel(WDOG_COUNT, S3C2410_WTCNT);
-}
-
-static void arch_decomp_wdog_start(void)
-{
-	__raw_writel(WDOG_COUNT, S3C2410_WTDAT);
-	__raw_writel(WDOG_COUNT, S3C2410_WTCNT);
-	__raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON);
-}
-
-#else
-#define arch_decomp_wdog_start()
-#define arch_decomp_wdog()
-#endif
-
-#ifdef CONFIG_S3C_BOOT_ERROR_RESET
-
-static void arch_decomp_error(const char *x)
-{
-	putstr("\n\n");
-	putstr(x);
-	putstr("\n\n -- System resetting\n");
-
-	__raw_writel(0x4000, S3C2410_WTDAT);
-	__raw_writel(0x4000, S3C2410_WTCNT);
-	__raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
-
-	while(1);
-}
-
-#define arch_error arch_decomp_error
-#endif
-
-static void error(char *err);
-
-#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
-static inline void arch_enable_uart_fifo(void)
-{
-	u32 fifocon = uart_rd(S3C2410_UFCON);
-
-	if (!(fifocon & S3C2410_UFCON_FIFOMODE)) {
-		fifocon |= S3C2410_UFCON_RESETBOTH;
-		uart_wr(S3C2410_UFCON, fifocon);
-
-		/* wait for fifo reset to complete */
-		while (1) {
-			fifocon = uart_rd(S3C2410_UFCON);
-			if (!(fifocon & S3C2410_UFCON_RESETBOTH))
-				break;
-		}
-	}
-}
-#else
-#define arch_enable_uart_fifo() do { } while(0)
-#endif
-
-
-static void
-arch_decomp_setup(void)
-{
-	/* we may need to setup the uart(s) here if we are not running
-	 * on an BAST... the BAST will have left the uarts configured
-	 * after calling linux.
-	 */
-
-	arch_detect_cpu();
-	arch_decomp_wdog_start();
-
-	/* Enable the UART FIFOs if they where not enabled and our
-	 * configuration says we should turn them on.
-	 */
-
-	arch_enable_uart_fifo();
-}
-
-
-#endif /* __ASM_PLAT_UNCOMPRESS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/usb-control.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/usb-control.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/usb-control.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/usb-control.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-/* 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.33-gnu1/arch/arm/plat-s3c/include/plat/watchdog-reset.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/watchdog-reset.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/watchdog-reset.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/include/plat/watchdog-reset.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/watchdog-reset.h
- *
- * Copyright (c) 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - System define for arch_reset() 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.
-*/
-
-#include <plat/regs-watchdog.h>
-#include <mach/map.h>
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-static inline void arch_wdt_reset(void)
-{
-	struct clk *wdtclk;
-
-	printk("arch_reset: attempting watchdog reset\n");
-
-	__raw_writel(0, S3C2410_WTCON);	  /* disable watchdog, to be safe  */
-
-	wdtclk = clk_get(NULL, "watchdog");
-	if (!IS_ERR(wdtclk)) {
-		clk_enable(wdtclk);
-	} else
-		printk(KERN_WARNING "%s: warning: cannot get watchdog clock\n", __func__);
-
-	/* put initial values into count and data */
-	__raw_writel(0x80, S3C2410_WTCNT);
-	__raw_writel(0x80, S3C2410_WTDAT);
-
-	/* set the watchdog to go and reset... */
-	__raw_writel(S3C2410_WTCON_ENABLE|S3C2410_WTCON_DIV16|S3C2410_WTCON_RSTEN |
-		     S3C2410_WTCON_PRESCALE(0x20), S3C2410_WTCON);
-
-	/* wait for reset to assert... */
-	mdelay(500);
-
-	printk(KERN_ERR "Watchdog reset failed to assert reset\n");
-
-	/* delay to allow the serial port to show the message */
-	mdelay(50);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/init.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/init.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/init.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,160 +0,0 @@
-/* linux/arch/arm/plat-s3c/init.c
- *
- * Copyright (c) 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series CPU initialisation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <mach/hardware.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/clock.h>
-
-#include <plat/regs-serial.h>
-
-static struct cpu_table *cpu;
-
-static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode,
-						struct cpu_table *tab,
-						unsigned int count)
-{
-	for (; count != 0; count--, tab++) {
-		if ((idcode & tab->idmask) == tab->idcode)
-			return tab;
-	}
-
-	return NULL;
-}
-
-void __init s3c_init_cpu(unsigned long idcode,
-			 struct cpu_table *cputab, unsigned int cputab_size)
-{
-	cpu = s3c_lookup_cpu(idcode, cputab, cputab_size);
-
-	if (cpu == NULL) {
-		printk(KERN_ERR "Unknown CPU type 0x%08lx\n", idcode);
-		panic("Unknown S3C24XX CPU");
-	}
-
-	printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
-
-	if (cpu->map_io == NULL || cpu->init == NULL) {
-		printk(KERN_ERR "CPU %s support not enabled\n", cpu->name);
-		panic("Unsupported Samsung CPU");
-	}
-
-	cpu->map_io();
-}
-
-/* s3c24xx_init_clocks
- *
- * Initialise the clock subsystem and associated information from the
- * given master crystal value.
- *
- * xtal  = 0 -> use default PLL crystal value (normally 12MHz)
- *      != 0 -> PLL crystal value in Hz
-*/
-
-void __init s3c24xx_init_clocks(int xtal)
-{
-	if (xtal == 0)
-		xtal = 12*1000*1000;
-
-	if (cpu == NULL)
-		panic("s3c24xx_init_clocks: no cpu setup?\n");
-
-	if (cpu->init_clocks == NULL)
-		panic("s3c24xx_init_clocks: cpu has no clock init\n");
-	else
-		(cpu->init_clocks)(xtal);
-}
-
-/* uart management */
-
-static int nr_uarts __initdata = 0;
-
-static struct s3c2410_uartcfg uart_cfgs[CONFIG_SERIAL_SAMSUNG_UARTS];
-
-/* s3c24xx_init_uartdevs
- *
- * copy the specified platform data and configuration into our central
- * set of devices, before the data is thrown away after the init process.
- *
- * This also fills in the array passed to the serial driver for the
- * early initialisation of the console.
-*/
-
-void __init s3c24xx_init_uartdevs(char *name,
-				  struct s3c24xx_uart_resources *res,
-				  struct s3c2410_uartcfg *cfg, int no)
-{
-	struct platform_device *platdev;
-	struct s3c2410_uartcfg *cfgptr = uart_cfgs;
-	struct s3c24xx_uart_resources *resp;
-	int uart;
-
-	memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
-
-	for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
-		platdev = s3c24xx_uart_src[cfgptr->hwport];
-
-		resp = res + cfgptr->hwport;
-
-		s3c24xx_uart_devs[uart] = platdev;
-
-		platdev->name = name;
-		platdev->resource = resp->resources;
-		platdev->num_resources = resp->nr_resources;
-
-		platdev->dev.platform_data = cfgptr;
-	}
-
-	nr_uarts = no;
-}
-
-void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-	if (cpu == NULL)
-		return;
-
-	if (cpu->init_uarts == NULL) {
-		printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n");
-	} else
-		(cpu->init_uarts)(cfg, no);
-}
-
-static int __init s3c_arch_init(void)
-{
-	int ret;
-
-	// do the correct init for cpu
-
-	if (cpu == NULL)
-		panic("s3c_arch_init: NULL cpu\n");
-
-	ret = (cpu->init)();
-	if (ret != 0)
-		return ret;
-
-	ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
-	return ret;
-}
-
-arch_initcall(s3c_arch_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/Kconfig linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,215 +0,0 @@
-# Copyright 2007 Simtec Electronics
-#
-# Licensed under GPLv2
-
-config PLAT_S3C
-	bool
-	depends on ARCH_S3C2410 || ARCH_S3C24A0 || ARCH_S3C64XX
-	default y
-	select NO_IOPORT
-	help
-	  Base platform code for any Samsung S3C device
-
-# low-level serial option nodes
-
-if PLAT_S3C
-
-config CPU_LLSERIAL_S3C2410_ONLY
-	bool
-	default y if CPU_LLSERIAL_S3C2410 && !CPU_LLSERIAL_S3C2440
-
-config CPU_LLSERIAL_S3C2440_ONLY
-	bool
-	default y if CPU_LLSERIAL_S3C2440 && !CPU_LLSERIAL_S3C2410
-
-config CPU_LLSERIAL_S3C2410
-	bool
-	help
-	  Selected if there is an S3C2410 (or register compatible) serial
-	  low-level implementation needed
-
-config CPU_LLSERIAL_S3C2440
-	bool
-	help
-	  Selected if there is an S3C2440 (or register compatible) serial
-	  low-level implementation needed
-
-# boot configurations
-
-comment "Boot options"
-
-config S3C_BOOT_WATCHDOG
-	bool "S3C Initialisation watchdog"
-	depends on S3C2410_WATCHDOG
-	help
-	  Say y to enable the watchdog during the kernel decompression
-	  stage. If the kernel fails to uncompress, then the watchdog
-	  will trigger a reset and the system should restart.
-
-config S3C_BOOT_ERROR_RESET
-	bool "S3C Reboot on decompression error"
-	help
-	  Say y here to use the watchdog to reset the system if the
-	  kernel decompressor detects an error during decompression.
-
-config S3C_BOOT_UART_FORCE_FIFO
-       bool "Force UART FIFO on during boot process"
-       default y
-       help
-         Say Y here to force the UART FIFOs on during the kernel
-	 uncompressor
-
-comment "Power management"
-
-config S3C2410_PM_DEBUG
-	bool "S3C2410 PM Suspend debug"
-	depends on PM
-	help
-	  Say Y here if you want verbose debugging from the PM Suspend and
-	  Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
-	  for more information.
-
-config S3C_PM_DEBUG_LED_SMDK
-       bool "SMDK LED suspend/resume debugging"
-       depends on PM && (MACH_SMDK6410)
-       help
-         Say Y here to enable the use of the SMDK LEDs on the baseboard
-	 for debugging of the state of the suspend and resume process.
-
-	 Note, this currently only works for S3C64XX based SMDK boards.
-
-config S3C2410_PM_CHECK
-	bool "S3C2410 PM Suspend Memory CRC"
-	depends on PM && CRC32
-	help
- 	  Enable the PM code's memory area checksum over sleep. This option
-	  will generate CRCs of all blocks of memory, and store them before
-	  going to sleep. The blocks are then checked on resume for any
-	  errors.
-
-	  Note, this can take several seconds depending on memory size
-	  and CPU speed.
-
-	  See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
-
-config S3C2410_PM_CHECK_CHUNKSIZE
-	int "S3C2410 PM Suspend CRC Chunksize (KiB)"
-	depends on PM && S3C2410_PM_CHECK
-	default 64
-	help
-	  Set the chunksize in Kilobytes of the CRC for checking memory
-	  corruption over suspend and resume. A smaller value will mean that
-	  the CRC data block will take more memory, but wil identify any
-	  faults with better precision.
-
-	  See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
-
-config S3C_LOWLEVEL_UART_PORT
-	int "S3C UART to use for low-level messages"
-	default 0
-	help
-	  Choice of which UART port to use for the low-level messages,
-	  such as the `Uncompressing...` at start time. The value of
-	  this configuration should be between zero and two. The port
-	  must have been initialised by the boot-loader before use.
-
-# options for gpiolib support
-
-config S3C_GPIO_SPACE
-	int "Space between gpio banks"
-	default 0
-	help
-	  Add a number of spare GPIO entries between each bank for debugging
-	  purposes. This allows any problems where an counter overflows from
-	  one bank to another to be caught, at the expense of using a little
-	  more memory.
-
-config S3C_GPIO_TRACK
-	bool
-	help
-	  Internal configuration option to enable the s3c specific gpio
-	  chip tracking if the platform requires it.
-
-config S3C_GPIO_PULL_UPDOWN
-	bool
-	help
-	  Internal configuration to enable the correct GPIO pull helper
-
-config S3C_GPIO_PULL_DOWN
-	bool
-	help
-	  Internal configuration to enable the correct GPIO pull helper
-
-config S3C_GPIO_PULL_UP
-	bool
-	help
-	  Internal configuration to enable the correct GPIO pull helper
-
-config S3C_GPIO_CFG_S3C24XX
-	bool
-	help
-	  Internal configuration to enable S3C24XX style GPIO configuration
-	  functions.
-
-config S3C_GPIO_CFG_S3C64XX
-	bool
-	help
-	  Internal configuration to enable S3C64XX style GPIO configuration
-	  functions.
-
-config S5P_GPIO_CFG_S5PC1XX
-	bool
-	help
-	  Internal configuration to enable S5PC1XX style GPIO configuration
-	  functions.
-
-# DMA
-
-config S3C_DMA
-	bool
-	help
-	  Internal configuration for S3C DMA core
-
-# device definitions to compile in
-
-config S3C_DEV_HSMMC
-	bool
-	help
-	  Compile in platform device definitions for HSMMC code
-
-config S3C_DEV_HSMMC1
-	bool
-	help
-	  Compile in platform device definitions for HSMMC channel 1
-
-config S3C_DEV_HSMMC2
-	bool
-	help
-	  Compile in platform device definitions for HSMMC channel 2
-
-config S3C_DEV_I2C1
-	bool
-	help
-	  Compile in platform device definitions for I2C channel 1
-
-config S3C_DEV_FB
-	bool
-	help
-	  Compile in platform device definition for framebuffer
-
-config S3C_DEV_USB_HOST
-	bool
-	help
-	  Compile in platform device definition for USB host.
-
-config S3C_DEV_USB_HSOTG
-	bool
-	help
-	  Compile in platform device definition for USB high-speed OtG
-
-config S3C_DEV_NAND
-	bool
-	help
-	  Compile in platform device definition for NAND controller
-
-endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/Makefile linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,45 +0,0 @@
-# arch/arm/plat-s3c/Makefile
-#
-# Copyright 2008 Simtec Electronics
-#
-# Licensed under GPLv2
-
-obj-y				:=
-obj-m				:=
-obj-n				:=
-obj-				:=
-
-# Core support for all Samsung SoCs
-
-obj-y				+=  init.o
-obj-y				+= time.o
-obj-y				+= clock.o
-obj-y				+= pwm-clock.o
-obj-y				+= gpio.o
-obj-y				+= gpio-config.o
-
-# DMA support
-
-obj-$(CONFIG_S3C_DMA)		+= dma.o
-
-# PM support
-
-obj-$(CONFIG_PM)		+= pm.o
-obj-$(CONFIG_PM)		+= pm-gpio.o
-obj-$(CONFIG_S3C2410_PM_CHECK)	+= pm-check.o
-
-# PWM support
-
-obj-$(CONFIG_HAVE_PWM)		+= pwm.o
-
-# devices
-
-obj-$(CONFIG_S3C_DEV_HSMMC)	+= dev-hsmmc.o
-obj-$(CONFIG_S3C_DEV_HSMMC1)	+= dev-hsmmc1.o
-obj-$(CONFIG_S3C_DEV_HSMMC2)	+= dev-hsmmc2.o
-obj-y				+= dev-i2c0.o
-obj-$(CONFIG_S3C_DEV_I2C1)	+= dev-i2c1.o
-obj-$(CONFIG_S3C_DEV_FB)	+= dev-fb.o
-obj-$(CONFIG_S3C_DEV_USB_HOST)	+= dev-usb.o
-obj-$(CONFIG_S3C_DEV_USB_HSOTG)	+= dev-usb-hsotg.o
-obj-$(CONFIG_S3C_DEV_NAND)	+= dev-nand.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/pm.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/pm.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/pm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/pm.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,378 +0,0 @@
-/* linux/arch/arm/plat-s3c/pm.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2004-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 <mach/map.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-clock.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. */
-
-unsigned char pm_uart_udivslot;
-
-#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);
-
-	if (pm_uart_udivslot)
-		save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT);
-
-	S3C_PMDBG("UART[%d]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n",
-		  uart, save->ulcon, save->ucon, save->ufcon, save->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);
-
-	s3c_pm_arch_update_uart(regs, save);
-
-	__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);
-
-	if (pm_uart_udivslot)
-		__raw_writel(save->udivslot, regs + S3C2443_DIVSLOT);
-}
-
-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__);
-
-	/* LEDs should now be 1110 */
-	s3c_pm_debug_smdkled(1 << 1, 0);
-
-	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.33-gnu1/arch/arm/plat-s3c/pm-check.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/pm-check.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/pm-check.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/pm-check.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,242 +0,0 @@
-/* linux/arch/arm/plat-s3c/pm-check.c
- *  originally in linux/arch/arm/plat-s3c24xx/pm.c
- *
- * Copyright (c) 2004-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.33-gnu1/arch/arm/plat-s3c/pm-gpio.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/pm-gpio.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/pm-gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/pm-gpio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,380 +0,0 @@
-
-/* linux/arch/arm/plat-s3c/pm-gpio.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series GPIO 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/kernel.h>
-#include <linux/sysdev.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-
-#include <mach/gpio-core.h>
-#include <plat/pm.h>
-
-/* PM GPIO helpers */
-
-#define OFFS_CON	(0x00)
-#define OFFS_DAT	(0x04)
-#define OFFS_UP		(0x08)
-
-static void s3c_gpio_pm_1bit_save(struct s3c_gpio_chip *chip)
-{
-	chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
-	chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
-}
-
-static void s3c_gpio_pm_1bit_resume(struct s3c_gpio_chip *chip)
-{
-	void __iomem *base = chip->base;
-	u32 old_gpcon = __raw_readl(base + OFFS_CON);
-	u32 old_gpdat = __raw_readl(base + OFFS_DAT);
-	u32 gps_gpcon = chip->pm_save[0];
-	u32 gps_gpdat = chip->pm_save[1];
-	u32 gpcon;
-
-	/* GPACON only has one bit per control / data and no PULLUPs.
-	 * GPACON[x] = 0 => Output, 1 => SFN */
-
-	/* first set all SFN bits to SFN */
-
-	gpcon = old_gpcon | gps_gpcon;
-	__raw_writel(gpcon, base + OFFS_CON);
-
-	/* now set all the other bits */
-
-	__raw_writel(gps_gpdat, base + OFFS_DAT);
-	__raw_writel(gps_gpcon, base + OFFS_CON);
-
-	S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
-		  chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
-}
-
-struct s3c_gpio_pm s3c_gpio_pm_1bit = {
-	.save	= s3c_gpio_pm_1bit_save,
-	.resume = s3c_gpio_pm_1bit_resume,
-};
-
-static void s3c_gpio_pm_2bit_save(struct s3c_gpio_chip *chip)
-{
-	chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
-	chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
-	chip->pm_save[2] = __raw_readl(chip->base + OFFS_UP);
-}
-
-/* Test whether the given masked+shifted bits of an GPIO configuration
- * are one of the SFN (special function) modes. */
-
-static inline int is_sfn(unsigned long con)
-{
-	return con >= 2;
-}
-
-/* Test if the given masked+shifted GPIO configuration is an input */
-
-static inline int is_in(unsigned long con)
-{
-	return con == 0;
-}
-
-/* Test if the given masked+shifted GPIO configuration is an output */
-
-static inline int is_out(unsigned long con)
-{
-	return con == 1;
-}
-
-/**
- * s3c_gpio_pm_2bit_resume() - restore the given GPIO bank
- * @chip: The chip information to resume.
- *
- * 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
- * from the order that the CON and DAT registers are set in.
- *
- * The three states the pin can be are {IN,OUT,SFN} which gives us 9
- * combinations of changes to check. Three of these, if the pin stays
- * in the same configuration can be discounted. This leaves us with
- * the following:
- *
- * { IN => OUT }  Change DAT first
- * { IN => SFN }  Change CON first
- * { OUT => SFN } Change CON first, so new data will not glitch
- * { OUT => IN }  Change CON first, so new data will not glitch
- * { SFN => IN }  Change CON first
- * { SFN => OUT } Change DAT first, so new data will not glitch [1]
- *
- * We do not currently deal with the UP registers as these control
- * weak resistors, so a small delay in change should not need to bring
- * these into the calculations.
- *
- * [1] this assumes that writing to a pin DAT whilst in SFN will set the
- *     state for when it is next output.
- */
-static void s3c_gpio_pm_2bit_resume(struct s3c_gpio_chip *chip)
-{
-	void __iomem *base = chip->base;
-	u32 old_gpcon = __raw_readl(base + OFFS_CON);
-	u32 old_gpdat = __raw_readl(base + OFFS_DAT);
-	u32 gps_gpcon = chip->pm_save[0];
-	u32 gps_gpdat = chip->pm_save[1];
-	u32 gpcon, old, new, mask;
-	u32 change_mask = 0x0;
-	int nr;
-
-	/* restore GPIO pull-up settings */
-	__raw_writel(chip->pm_save[2], base + OFFS_UP);
-
-	/* Create a change_mask of all the items that need to have
-	 * their CON value changed before their DAT value, so that
-	 * we minimise the work between the two settings.
-	 */
-
-	for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) {
-		old = (old_gpcon & mask) >> nr;
-		new = (gps_gpcon & mask) >> nr;
-
-		/* If there is no change, then skip */
-
-		if (old == new)
-			continue;
-
-		/* If both are special function, then skip */
-
-		if (is_sfn(old) && is_sfn(new))
-			continue;
-
-		/* Change is IN => OUT, do not change now */
-
-		if (is_in(old) && is_out(new))
-			continue;
-
-		/* Change is SFN => OUT, do not change now */
-
-		if (is_sfn(old) && is_out(new))
-			continue;
-
-		/* We should now be at the case of IN=>SFN,
-		 * OUT=>SFN, OUT=>IN, SFN=>IN. */
-
-		change_mask |= mask;
-	}
-
-
-	/* Write the new CON settings */
-
-	gpcon = old_gpcon & ~change_mask;
-	gpcon |= gps_gpcon & change_mask;
-
-	__raw_writel(gpcon, base + OFFS_CON);
-
-	/* Now change any items that require DAT,CON */
-
-	__raw_writel(gps_gpdat, base + OFFS_DAT);
-	__raw_writel(gps_gpcon, base + OFFS_CON);
-
-	S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
-		  chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
-}
-
-struct s3c_gpio_pm s3c_gpio_pm_2bit = {
-	.save	= s3c_gpio_pm_2bit_save,
-	.resume = s3c_gpio_pm_2bit_resume,
-};
-
-#ifdef CONFIG_ARCH_S3C64XX
-static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
-{
-	chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
-	chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT);
-	chip->pm_save[3] = __raw_readl(chip->base + OFFS_UP);
-
-	if (chip->chip.ngpio > 8)
-		chip->pm_save[0] = __raw_readl(chip->base - 4);
-}
-
-static u32 s3c_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon)
-{
-	u32 old, new, mask;
-	u32 change_mask = 0x0;
-	int nr;
-
-	for (nr = 0, mask = 0x0f; nr < 16; nr += 4, mask <<= 4) {
-		old = (old_gpcon & mask) >> nr;
-		new = (gps_gpcon & mask) >> nr;
-
-		/* If there is no change, then skip */
-
-		if (old == new)
-			continue;
-
-		/* If both are special function, then skip */
-
-		if (is_sfn(old) && is_sfn(new))
-			continue;
-
-		/* Change is IN => OUT, do not change now */
-
-		if (is_in(old) && is_out(new))
-			continue;
-
-		/* Change is SFN => OUT, do not change now */
-
-		if (is_sfn(old) && is_out(new))
-			continue;
-
-		/* We should now be at the case of IN=>SFN,
-		 * OUT=>SFN, OUT=>IN, SFN=>IN. */
-
-		change_mask |= mask;
-	}
-
-	return change_mask;
-}
-
-static void s3c_gpio_pm_4bit_con(struct s3c_gpio_chip *chip, int index)
-{
-	void __iomem *con = chip->base + (index * 4);
-	u32 old_gpcon = __raw_readl(con);
-	u32 gps_gpcon = chip->pm_save[index + 1];
-	u32 gpcon, mask;
-
-	mask = s3c_gpio_pm_4bit_mask(old_gpcon, gps_gpcon);
-
-	gpcon = old_gpcon & ~mask;
-	gpcon |= gps_gpcon & mask;
-
-	__raw_writel(gpcon, con);
-}
-
-static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip)
-{
-	void __iomem *base = chip->base;
-	u32 old_gpcon[2];
-	u32 old_gpdat = __raw_readl(base + OFFS_DAT);
-	u32 gps_gpdat = chip->pm_save[2];
-
-	/* First, modify the CON settings */
-
-	old_gpcon[0] = 0;
-	old_gpcon[1] = __raw_readl(base + OFFS_CON);
-
-	s3c_gpio_pm_4bit_con(chip, 0);
-	if (chip->chip.ngpio > 8) {
-		old_gpcon[0] = __raw_readl(base - 4);
-		s3c_gpio_pm_4bit_con(chip, -1);
-	}
-
-	/* Now change the configurations that require DAT,CON */
-
-	__raw_writel(chip->pm_save[2], base + OFFS_DAT);
-	__raw_writel(chip->pm_save[1], base + OFFS_CON);
-	if (chip->chip.ngpio > 8)
-		__raw_writel(chip->pm_save[0], base - 4);
-
-	__raw_writel(chip->pm_save[2], base + OFFS_DAT);
-	__raw_writel(chip->pm_save[3], base + OFFS_UP);
-
-	if (chip->chip.ngpio > 8) {
-		S3C_PMDBG("%s: CON4 %08x,%08x => %08x,%08x, DAT %08x => %08x\n",
-			  chip->chip.label, old_gpcon[0], old_gpcon[1],
-			  __raw_readl(base - 4),
-			  __raw_readl(base + OFFS_CON),
-			  old_gpdat, gps_gpdat);
-	} else
-		S3C_PMDBG("%s: CON4 %08x => %08x, DAT %08x => %08x\n",
-			  chip->chip.label, old_gpcon[1],
-			  __raw_readl(base + OFFS_CON),
-			  old_gpdat, gps_gpdat);
-}
-
-struct s3c_gpio_pm s3c_gpio_pm_4bit = {
-	.save	= s3c_gpio_pm_4bit_save,
-	.resume = s3c_gpio_pm_4bit_resume,
-};
-#endif /* CONFIG_ARCH_S3C64XX */
-
-/**
- * s3c_pm_save_gpio() - save gpio chip data for suspend
- * @ourchip: The chip for suspend.
- */
-static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip)
-{
-	struct s3c_gpio_pm *pm = ourchip->pm;
-
-	if (pm == NULL || pm->save == NULL)
-		S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
-	else
-		pm->save(ourchip);
-}
-
-/**
- * s3c_pm_save_gpios() - Save the state of the GPIO banks.
- *
- * For all the GPIO banks, save the state of each one ready for going
- * into a suspend mode.
- */
-void s3c_pm_save_gpios(void)
-{
-	struct s3c_gpio_chip *ourchip;
-	unsigned int gpio_nr;
-
-	for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
-		ourchip = s3c_gpiolib_getchip(gpio_nr);
-		if (!ourchip)
-			continue;
-
-		s3c_pm_save_gpio(ourchip);
-
-		S3C_PMDBG("%s: save %08x,%08x,%08x,%08x\n",
-			  ourchip->chip.label,
-			  ourchip->pm_save[0],
-			  ourchip->pm_save[1],
-			  ourchip->pm_save[2],
-			  ourchip->pm_save[3]);
-
-		gpio_nr += ourchip->chip.ngpio;
-		gpio_nr += CONFIG_S3C_GPIO_SPACE;
-	}
-}
-
-/**
- * s3c_pm_resume_gpio() - restore gpio chip data after suspend
- * @ourchip: The suspended chip.
- */
-static void s3c_pm_resume_gpio(struct s3c_gpio_chip *ourchip)
-{
-	struct s3c_gpio_pm *pm = ourchip->pm;
-
-	if (pm == NULL || pm->resume == NULL)
-		S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
-	else
-		pm->resume(ourchip);
-}
-
-void s3c_pm_restore_gpios(void)
-{
-	struct s3c_gpio_chip *ourchip;
-	unsigned int gpio_nr;
-
-	for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
-		ourchip = s3c_gpiolib_getchip(gpio_nr);
-		if (!ourchip)
-			continue;
-
-		s3c_pm_resume_gpio(ourchip);
-
-		gpio_nr += ourchip->chip.ngpio;
-		gpio_nr += CONFIG_S3C_GPIO_SPACE;
-	}
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/pwm.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/pwm.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/pwm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/pwm.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,410 +0,0 @@
-/* arch/arm/plat-s3c/pwm.c
- *
- * Copyright (c) 2007 Ben Dooks
- * Copyright (c) 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
- *
- * S3C series PWM device core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
-*/
-
-#include <linux/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>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-#include <plat/regs-timer.h>
-
-struct pwm_device {
-	struct list_head	 list;
-	struct platform_device	*pdev;
-
-	struct clk		*clk_div;
-	struct clk		*clk;
-	const char		*label;
-
-	unsigned int		 period_ns;
-	unsigned int		 duty_ns;
-
-	unsigned char		 tcon_base;
-	unsigned char		 running;
-	unsigned char		 use_count;
-	unsigned char		 pwm_id;
-};
-
-#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
-
-static struct clk *clk_scaler[2];
-
-/* Standard setup for a timer block. */
-
-#define TIMER_RESOURCE_SIZE (1)
-
-#define TIMER_RESOURCE(_tmr, _irq)			\
-	(struct resource [TIMER_RESOURCE_SIZE]) {	\
-		[0] = {					\
-			.start	= _irq,			\
-			.end	= _irq,			\
-			.flags	= IORESOURCE_IRQ	\
-		}					\
-	}
-
-#define DEFINE_S3C_TIMER(_tmr_no, _irq)			\
-	.name		= "s3c24xx-pwm",		\
-	.id		= _tmr_no,			\
-	.num_resources	= TIMER_RESOURCE_SIZE,		\
-	.resource	= TIMER_RESOURCE(_tmr_no, _irq),	\
-
-/* since we already have an static mapping for the timer, we do not
- * bother setting any IO resource for the base.
- */
-
-struct platform_device s3c_device_timer[] = {
-	[0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
-	[1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
-	[2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
-	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
-	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
-};
-
-static inline int pwm_is_tdiv(struct pwm_device *pwm)
-{
-	return clk_get_parent(pwm->clk) == pwm->clk_div;
-}
-
-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, list) {
-		if (pwm->pwm_id == pwm_id) {
-			found = 1;
-			break;
-		}
-	}
-
-	if (found) {
-		if (pwm->use_count == 0) {
-			pwm->use_count = 1;
-			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
-		printk(KERN_ERR "PWM%d device already freed\n", pwm->pwm_id);
-
-	mutex_unlock(&pwm_lock);
-}
-
-EXPORT_SYMBOL(pwm_free);
-
-#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
-#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
-#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
-#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
-
-int pwm_enable(struct pwm_device *pwm)
-{
-	unsigned long flags;
-	unsigned long tcon;
-
-	local_irq_save(flags);
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon |= pwm_tcon_start(pwm);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-
-	pwm->running = 1;
-	return 0;
-}
-
-EXPORT_SYMBOL(pwm_enable);
-
-void pwm_disable(struct pwm_device *pwm)
-{
-	unsigned long flags;
-	unsigned long tcon;
-
-	local_irq_save(flags);
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon &= ~pwm_tcon_start(pwm);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-
-	pwm->running = 0;
-}
-
-EXPORT_SYMBOL(pwm_disable);
-
-static unsigned long pwm_calc_tin(struct pwm_device *pwm, unsigned long freq)
-{
-	unsigned long tin_parent_rate;
-	unsigned int div;
-
-	tin_parent_rate = clk_get_rate(clk_get_parent(pwm->clk_div));
-	pwm_dbg(pwm, "tin parent at %lu\n", tin_parent_rate);
-
-	for (div = 2; div <= 16; div *= 2) {
-		if ((tin_parent_rate / (div << 16)) < freq)
-			return tin_parent_rate / div;
-	}
-
-	return tin_parent_rate / 16;
-}
-
-#define NS_IN_HZ (1000000000UL)
-
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
-	unsigned long tin_rate;
-	unsigned long tin_ns;
-	unsigned long period;
-	unsigned long flags;
-	unsigned long tcon;
-	unsigned long tcnt;
-	long tcmp;
-
-	/* We currently avoid using 64bit arithmetic by using the
-	 * fact that anything faster than 1Hz is easily representable
-	 * by 32bits. */
-
-	if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
-		return -ERANGE;
-
-	if (duty_ns > period_ns)
-		return -EINVAL;
-
-	if (period_ns == pwm->period_ns &&
-	    duty_ns == pwm->duty_ns)
-		return 0;
-
-	/* The TCMP and TCNT can be read without a lock, they're not
-	 * shared between the timers. */
-
-	tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id));
-	tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id));
-
-	period = NS_IN_HZ / period_ns;
-
-	pwm_dbg(pwm, "duty_ns=%d, period_ns=%d (%lu)\n",
-		duty_ns, period_ns, period);
-
-	/* Check to see if we are changing the clock rate of the PWM */
-
-	if (pwm->period_ns != period_ns) {
-		if (pwm_is_tdiv(pwm)) {
-			tin_rate = pwm_calc_tin(pwm, period);
-			clk_set_rate(pwm->clk_div, tin_rate);
-		} else
-			tin_rate = clk_get_rate(pwm->clk);
-
-		pwm->period_ns = period_ns;
-
-		pwm_dbg(pwm, "tin_rate=%lu\n", tin_rate);
-
-		tin_ns = NS_IN_HZ / tin_rate;
-		tcnt = period_ns / tin_ns;
-	} else
-		tin_ns = NS_IN_HZ / clk_get_rate(pwm->clk);
-
-	/* Note, counters count down */
-
-	tcmp = duty_ns / tin_ns;
-	tcmp = tcnt - tcmp;
-	/* the pwm hw only checks the compare register after a decrement,
-	   so the pin never toggles if tcmp = tcnt */
-	if (tcmp == tcnt)
-		tcmp--;
-
-	pwm_dbg(pwm, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
-
-	if (tcmp < 0)
-		tcmp = 0;
-
-	/* Update the PWM register block. */
-
-	local_irq_save(flags);
-
-	__raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id));
-	__raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id));
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon |= pwm_tcon_manulupdate(pwm);
-	tcon |= pwm_tcon_autoreload(pwm);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	tcon &= ~pwm_tcon_manulupdate(pwm);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-EXPORT_SYMBOL(pwm_config);
-
-static int pwm_register(struct pwm_device *pwm)
-{
-	pwm->duty_ns = -1;
-	pwm->period_ns = -1;
-
-	mutex_lock(&pwm_lock);
-	list_add_tail(&pwm->list, &pwm_list);
-	mutex_unlock(&pwm_lock);
-
-	return 0;
-}
-
-static int s3c_pwm_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct pwm_device *pwm;
-	unsigned long flags;
-	unsigned long tcon;
-	unsigned int id = pdev->id;
-	int ret;
-
-	if (id == 4) {
-		dev_err(dev, "TIMER4 is currently not supported\n");
-		return -ENXIO;
-	}
-
-	pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
-	if (pwm == NULL) {
-		dev_err(dev, "failed to allocate pwm_device\n");
-		return -ENOMEM;
-	}
-
-	pwm->pdev = pdev;
-	pwm->pwm_id = id;
-
-	/* calculate base of control bits in TCON */
-	pwm->tcon_base = id == 0 ? 0 : (id * 4) + 4;
-
-	pwm->clk = clk_get(dev, "pwm-tin");
-	if (IS_ERR(pwm->clk)) {
-		dev_err(dev, "failed to get pwm tin clk\n");
-		ret = PTR_ERR(pwm->clk);
-		goto err_alloc;
-	}
-
-	pwm->clk_div = clk_get(dev, "pwm-tdiv");
-	if (IS_ERR(pwm->clk_div)) {
-		dev_err(dev, "failed to get pwm tdiv clk\n");
-		ret = PTR_ERR(pwm->clk_div);
-		goto err_clk_tin;
-	}
-
-	local_irq_save(flags);
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon |= pwm_tcon_invert(pwm);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-
-
-	ret = pwm_register(pwm);
-	if (ret) {
-		dev_err(dev, "failed to register pwm\n");
-		goto err_clk_tdiv;
-	}
-
-	pwm_dbg(pwm, "config bits %02x\n",
-		(__raw_readl(S3C2410_TCON) >> pwm->tcon_base) & 0x0f);
-
-	dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
-		 clk_get_rate(pwm->clk),
-		 clk_get_rate(pwm->clk_div),
-		 pwm_is_tdiv(pwm) ? "div" : "ext", pwm->tcon_base);
-
-	platform_set_drvdata(pdev, pwm);
-	return 0;
-
- err_clk_tdiv:
-	clk_put(pwm->clk_div);
-
- err_clk_tin:
-	clk_put(pwm->clk);
-
- err_alloc:
-	kfree(pwm);
-	return ret;
-}
-
-static int __devexit s3c_pwm_remove(struct platform_device *pdev)
-{
-	struct pwm_device *pwm = platform_get_drvdata(pdev);
-
-	clk_put(pwm->clk_div);
-	clk_put(pwm->clk);
-	kfree(pwm);
-
-	return 0;
-}
-
-static struct platform_driver s3c_pwm_driver = {
-	.driver		= {
-		.name	= "s3c24xx-pwm",
-		.owner	= THIS_MODULE,
-	},
-	.probe		= s3c_pwm_probe,
-	.remove		= __devexit_p(s3c_pwm_remove),
-};
-
-static int __init pwm_init(void)
-{
-	int ret;
-
-	clk_scaler[0] = clk_get(NULL, "pwm-scaler0");
-	clk_scaler[1] = clk_get(NULL, "pwm-scaler1");
-
-	if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
-		printk(KERN_ERR "%s: failed to get scaler clocks\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = platform_driver_register(&s3c_pwm_driver);
-	if (ret)
-		printk(KERN_ERR "%s: failed to add pwm driver\n", __func__);
-
-	return ret;
-}
-
-arch_initcall(pwm_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/pwm-clock.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/pwm-clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/pwm-clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/pwm-clock.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,463 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/pwm-clock.c
- *
- * Copyright (c) 2007 Simtec Electronics
- * Copyright (c) 2007, 2008 Ben Dooks
- *	Ben Dooks <ben-linux@fluff.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.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/log2.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <asm/irq.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-#include <plat/regs-timer.h>
-#include <mach/pwm-clock.h>
-
-/* Each of the timers 0 through 5 go through the following
- * clock tree, with the inputs depending on the timers.
- *
- * pclk ---- [ prescaler 0 ] -+---> timer 0
- *			      +---> timer 1
- *
- * pclk ---- [ prescaler 1 ] -+---> timer 2
- *			      +---> timer 3
- *			      \---> timer 4
- *
- * Which are fed into the timers as so:
- *
- * prescaled 0 ---- [ div 2,4,8,16 ] ---\
- *				       [mux] -> timer 0
- * tclk 0 ------------------------------/
- *
- * prescaled 0 ---- [ div 2,4,8,16 ] ---\
- *				       [mux] -> timer 1
- * tclk 0 ------------------------------/
- *
- *
- * prescaled 1 ---- [ div 2,4,8,16 ] ---\
- *				       [mux] -> timer 2
- * tclk 1 ------------------------------/
- *
- * prescaled 1 ---- [ div 2,4,8,16 ] ---\
- *				       [mux] -> timer 3
- * tclk 1 ------------------------------/
- *
- * prescaled 1 ---- [ div 2,4,8, 16 ] --\
- *				       [mux] -> timer 4
- * tclk 1 ------------------------------/
- *
- * Since the mux and the divider are tied together in the
- * same register space, it is impossible to set the parent
- * and the rate at the same time. To avoid this, we add an
- * intermediate 'prescaled-and-divided' clock to select
- * as the parent for the timer input clock called tdiv.
- *
- * prescaled clk --> pwm-tdiv ---\
- *                             [ mux ] --> timer X
- * tclk -------------------------/
-*/
-
-static struct clk clk_timer_scaler[];
-
-static unsigned long clk_pwm_scaler_get_rate(struct clk *clk)
-{
-	unsigned long tcfg0 = __raw_readl(S3C2410_TCFG0);
-
-	if (clk == &clk_timer_scaler[1]) {
-		tcfg0 &= S3C2410_TCFG_PRESCALER1_MASK;
-		tcfg0 >>= S3C2410_TCFG_PRESCALER1_SHIFT;
-	} else {
-		tcfg0 &= S3C2410_TCFG_PRESCALER0_MASK;
-	}
-
-	return clk_get_rate(clk->parent) / (tcfg0 + 1);
-}
-
-static unsigned long clk_pwm_scaler_round_rate(struct clk *clk,
-					       unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long divisor = parent_rate / rate;
-
-	if (divisor > 256)
-		divisor = 256;
-	else if (divisor < 2)
-		divisor = 2;
-
-	return parent_rate / divisor;
-}
-
-static int clk_pwm_scaler_set_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned long round = clk_pwm_scaler_round_rate(clk, rate);
-	unsigned long tcfg0;
-	unsigned long divisor;
-	unsigned long flags;
-
-	divisor = clk_get_rate(clk->parent) / round;
-	divisor--;
-
-	local_irq_save(flags);
-	tcfg0 = __raw_readl(S3C2410_TCFG0);
-
-	if (clk == &clk_timer_scaler[1]) {
-		tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
-		tcfg0 |= divisor << S3C2410_TCFG_PRESCALER1_SHIFT;
-	} else {
-		tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
-		tcfg0 |= divisor;
-	}
-
-	__raw_writel(tcfg0, S3C2410_TCFG0);
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-static struct clk clk_timer_scaler[] = {
-	[0]	= {
-		.name		= "pwm-scaler0",
-		.id		= -1,
-		.get_rate	= clk_pwm_scaler_get_rate,
-		.set_rate	= clk_pwm_scaler_set_rate,
-		.round_rate	= clk_pwm_scaler_round_rate,
-	},
-	[1]	= {
-		.name		= "pwm-scaler1",
-		.id		= -1,
-		.get_rate	= clk_pwm_scaler_get_rate,
-		.set_rate	= clk_pwm_scaler_set_rate,
-		.round_rate	= clk_pwm_scaler_round_rate,
-	},
-};
-
-static struct clk clk_timer_tclk[] = {
-	[0]	= {
-		.name		= "pwm-tclk0",
-		.id		= -1,
-	},
-	[1]	= {
-		.name		= "pwm-tclk1",
-		.id		= -1,
-	},
-};
-
-struct pwm_tdiv_clk {
-	struct clk	clk;
-	unsigned int	divisor;
-};
-
-static inline struct pwm_tdiv_clk *to_tdiv(struct clk *clk)
-{
-	return container_of(clk, struct pwm_tdiv_clk, clk);
-}
-
-static unsigned long clk_pwm_tdiv_get_rate(struct clk *clk)
-{
-	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-	unsigned int divisor;
-
-	tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
-	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
-	if (pwm_cfg_src_is_tclk(tcfg1))
-		divisor = to_tdiv(clk)->divisor;
-	else
-		divisor = tcfg_to_divisor(tcfg1);
-
-	return clk_get_rate(clk->parent) / divisor;
-}
-
-static unsigned long clk_pwm_tdiv_round_rate(struct clk *clk,
-					     unsigned long rate)
-{
-	unsigned long parent_rate;
-	unsigned long divisor;
-
-	parent_rate = clk_get_rate(clk->parent);
-	divisor = parent_rate / rate;
-
-	if (divisor <= 1 && pwm_tdiv_has_div1())
-		divisor = 1;
-	else if (divisor <= 2)
-		divisor = 2;
-	else if (divisor <= 4)
-		divisor = 4;
-	else if (divisor <= 8)
-		divisor = 8;
-	else
-		divisor = 16;
-
-	return parent_rate / divisor;
-}
-
-static unsigned long clk_pwm_tdiv_bits(struct pwm_tdiv_clk *divclk)
-{
-	return pwm_tdiv_div_bits(divclk->divisor);
-}
-
-static void clk_pwm_tdiv_update(struct pwm_tdiv_clk *divclk)
-{
-	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-	unsigned long bits = clk_pwm_tdiv_bits(divclk);
-	unsigned long flags;
-	unsigned long shift =  S3C2410_TCFG1_SHIFT(divclk->clk.id);
-
-	local_irq_save(flags);
-
-	tcfg1 = __raw_readl(S3C2410_TCFG1);
-	tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
-	tcfg1 |= bits << shift;
-	__raw_writel(tcfg1, S3C2410_TCFG1);
-
-	local_irq_restore(flags);
-}
-
-static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate)
-{
-	struct pwm_tdiv_clk *divclk = to_tdiv(clk);
-	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long divisor;
-
-	tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
-	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
-	rate = clk_round_rate(clk, rate);
-	divisor = parent_rate / rate;
-
-	if (divisor > 16)
-		return -EINVAL;
-
-	divclk->divisor = divisor;
-
-	/* Update the current MUX settings if we are currently
-	 * selected as the clock source for this clock. */
-
-	if (!pwm_cfg_src_is_tclk(tcfg1))
-		clk_pwm_tdiv_update(divclk);
-
-	return 0;
-}
-
-static struct pwm_tdiv_clk clk_timer_tdiv[] = {
-	[0]	= {
-		.clk	= {
-			.name		= "pwm-tdiv",
-			.parent		= &clk_timer_scaler[0],
-			.get_rate	= clk_pwm_tdiv_get_rate,
-			.set_rate	= clk_pwm_tdiv_set_rate,
-			.round_rate	= clk_pwm_tdiv_round_rate,
-		},
-	},
-	[1]	= {
-		.clk	= {
-			.name		= "pwm-tdiv",
-			.parent		= &clk_timer_scaler[0],
-			.get_rate	= clk_pwm_tdiv_get_rate,
-			.set_rate	= clk_pwm_tdiv_set_rate,
-			.round_rate	= clk_pwm_tdiv_round_rate,
-		}
-	},
-	[2]	= {
-		.clk	= {
-			.name		= "pwm-tdiv",
-			.parent		= &clk_timer_scaler[1],
-			.get_rate	= clk_pwm_tdiv_get_rate,
-			.set_rate	= clk_pwm_tdiv_set_rate,
-			.round_rate	= clk_pwm_tdiv_round_rate,
-		},
-	},
-	[3]	= {
-		.clk	= {
-			.name		= "pwm-tdiv",
-			.parent		= &clk_timer_scaler[1],
-			.get_rate	= clk_pwm_tdiv_get_rate,
-			.set_rate	= clk_pwm_tdiv_set_rate,
-			.round_rate	= clk_pwm_tdiv_round_rate,
-		},
-	},
-	[4]	= {
-		.clk	= {
-			.name		= "pwm-tdiv",
-			.parent		= &clk_timer_scaler[1],
-			.get_rate	= clk_pwm_tdiv_get_rate,
-			.set_rate	= clk_pwm_tdiv_set_rate,
-			.round_rate	= clk_pwm_tdiv_round_rate,
-		},
-	},
-};
-
-static int __init clk_pwm_tdiv_register(unsigned int id)
-{
-	struct pwm_tdiv_clk *divclk = &clk_timer_tdiv[id];
-	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-
-	tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
-	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
-	divclk->clk.id = id;
-	divclk->divisor = tcfg_to_divisor(tcfg1);
-
-	return s3c24xx_register_clock(&divclk->clk);
-}
-
-static inline struct clk *s3c24xx_pwmclk_tclk(unsigned int id)
-{
-	return (id >= 2) ? &clk_timer_tclk[1] : &clk_timer_tclk[0];
-}
-
-static inline struct clk *s3c24xx_pwmclk_tdiv(unsigned int id)
-{
-	return &clk_timer_tdiv[id].clk;
-}
-
-static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent)
-{
-	unsigned int id = clk->id;
-	unsigned long tcfg1;
-	unsigned long flags;
-	unsigned long bits;
-	unsigned long shift = S3C2410_TCFG1_SHIFT(id);
-
-	if (parent == s3c24xx_pwmclk_tclk(id))
-		bits = S3C_TCFG1_MUX_TCLK << shift;
-	else if (parent == s3c24xx_pwmclk_tdiv(id))
-		bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift;
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	local_irq_save(flags);
-
-	tcfg1 = __raw_readl(S3C2410_TCFG1);
-	tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
-	__raw_writel(tcfg1 | bits, S3C2410_TCFG1);
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-static struct clk clk_tin[] = {
-	[0]	= {
-		.name		= "pwm-tin",
-		.id		= 0,
-		.set_parent	= clk_pwm_tin_set_parent,
-	},
-	[1]	= {
-		.name		= "pwm-tin",
-		.id		= 1,
-		.set_parent	= clk_pwm_tin_set_parent,
-	},
-	[2]	= {
-		.name		= "pwm-tin",
-		.id		= 2,
-		.set_parent	= clk_pwm_tin_set_parent,
-	},
-	[3]	= {
-		.name		= "pwm-tin",
-		.id		= 3,
-		.set_parent	= clk_pwm_tin_set_parent,
-	},
-	[4]	= {
-		.name		= "pwm-tin",
-		.id		= 4,
-		.set_parent	= clk_pwm_tin_set_parent,
-	},
-};
-
-static __init int clk_pwm_tin_register(struct clk *pwm)
-{
-	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-	unsigned int id = pwm->id;
-
-	struct clk *parent;
-	int ret;
-
-	ret = s3c24xx_register_clock(pwm);
-	if (ret < 0)
-		return ret;
-
-	tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
-	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
-	if (pwm_cfg_src_is_tclk(tcfg1))
-		parent = s3c24xx_pwmclk_tclk(id);
-	else
-		parent = s3c24xx_pwmclk_tdiv(id);
-
-	return clk_set_parent(pwm, parent);
-}
-
-/**
- * s3c_pwmclk_init() - initialise pwm clocks
- *
- * Initialise and register the clocks which provide the inputs for the
- * pwm timer blocks.
- *
- * Note, this call is required by the time core, so must be called after
- * the base clocks are added and before any of the initcalls are run.
- */
-__init void s3c_pwmclk_init(void)
-{
-	struct clk *clk_timers;
-	unsigned int clk;
-	int ret;
-
-	clk_timers = clk_get(NULL, "timers");
-	if (IS_ERR(clk_timers)) {
-		printk(KERN_ERR "%s: no parent clock\n", __func__);
-		return;
-	}
-
-	for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++) {
-		clk_timer_scaler[clk].parent = clk_timers;
-		ret = s3c24xx_register_clock(&clk_timer_scaler[clk]);
-		if (ret < 0) {
-			printk(KERN_ERR "error adding pwm scaler%d clock\n", clk);
-			return;
-		}
-	}
-
-	for (clk = 0; clk < ARRAY_SIZE(clk_timer_tclk); clk++) {
-		ret = s3c24xx_register_clock(&clk_timer_tclk[clk]);
-		if (ret < 0) {
-			printk(KERN_ERR "error adding pww tclk%d\n", clk);
-			return;
-		}
-	}
-
-	for (clk = 0; clk < ARRAY_SIZE(clk_timer_tdiv); clk++) {
-		ret = clk_pwm_tdiv_register(clk);
-		if (ret < 0) {
-			printk(KERN_ERR "error adding pwm%d tdiv clock\n", clk);
-			return;
-		}
-	}
-
-	for (clk = 0; clk < ARRAY_SIZE(clk_tin); clk++) {
-		ret = clk_pwm_tin_register(&clk_tin[clk]);
-		if (ret < 0) {
-			printk(KERN_ERR "error adding pwm%d tin clock\n", clk);
-			return;
-		}
-	}
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/time.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/time.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c/time.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,285 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/time.c
- *
- * Copyright (C) 2003-2005 Simtec Electronics
- *	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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You 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/sched.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-
-#include <asm/system.h>
-#include <asm/leds.h>
-#include <asm/mach-types.h>
-
-#include <asm/irq.h>
-#include <mach/map.h>
-#include <plat/regs-timer.h>
-#include <mach/regs-irq.h>
-#include <asm/mach/time.h>
-#include <mach/tick.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-static unsigned long timer_startval;
-static unsigned long timer_usec_ticks;
-
-#ifndef TICK_MAX
-#define TICK_MAX (0xffff)
-#endif
-
-#define TIMER_USEC_SHIFT 16
-
-/* we use the shifted arithmetic to work out the ratio of timer ticks
- * to usecs, as often the peripheral clock is not a nice even multiple
- * of 1MHz.
- *
- * shift of 14 and 15 are too low for the 12MHz, 16 seems to be ok
- * for the current HZ value of 200 without producing overflows.
- *
- * Original patch by Dimitry Andric, updated by Ben Dooks
-*/
-
-
-/* timer_mask_usec_ticks
- *
- * given a clock and divisor, make the value to pass into timer_ticks_to_usec
- * to scale the ticks into usecs
-*/
-
-static inline unsigned long
-timer_mask_usec_ticks(unsigned long scaler, unsigned long pclk)
-{
-	unsigned long den = pclk / 1000;
-
-	return ((1000 << TIMER_USEC_SHIFT) * scaler + (den >> 1)) / den;
-}
-
-/* timer_ticks_to_usec
- *
- * convert timer ticks to usec.
-*/
-
-static inline unsigned long timer_ticks_to_usec(unsigned long ticks)
-{
-	unsigned long res;
-
-	res = ticks * timer_usec_ticks;
-	res += 1 << (TIMER_USEC_SHIFT - 4);	/* round up slightly */
-
-	return res >> TIMER_USEC_SHIFT;
-}
-
-/***
- * Returns microsecond  since last clock interrupt.  Note that interrupts
- * will have been disabled by do_gettimeoffset()
- * IRQs are disabled before entering here from do_gettimeofday()
- */
-
-static unsigned long s3c2410_gettimeoffset (void)
-{
-	unsigned long tdone;
-	unsigned long tval;
-
-	/* work out how many ticks have gone since last timer interrupt */
-
-	tval =  __raw_readl(S3C2410_TCNTO(4));
-	tdone = timer_startval - tval;
-
-	/* check to see if there is an interrupt pending */
-
-	if (s3c24xx_ostimer_pending()) {
-		/* re-read the timer, and try and fix up for the missed
-		 * interrupt. Note, the interrupt may go off before the
-		 * timer has re-loaded from wrapping.
-		 */
-
-		tval =  __raw_readl(S3C2410_TCNTO(4));
-		tdone = timer_startval - tval;
-
-		if (tval != 0)
-			tdone += timer_startval;
-	}
-
-	return timer_ticks_to_usec(tdone);
-}
-
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t
-s3c2410_timer_interrupt(int irq, void *dev_id)
-{
-	timer_tick();
-	return IRQ_HANDLED;
-}
-
-static struct irqaction s3c2410_timer_irq = {
-	.name		= "S3C2410 Timer Tick",
-	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= s3c2410_timer_interrupt,
-};
-
-#define use_tclk1_12() ( \
-	machine_is_bast()	|| \
-	machine_is_vr1000()	|| \
-	machine_is_anubis()	|| \
-	machine_is_osiris())
-
-static struct clk *tin;
-static struct clk *tdiv;
-static struct clk *timerclk;
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- *
- * Currently we only use timer4, as it is the only timer which has no
- * other function that can be exploited externally
- */
-static void s3c2410_timer_setup (void)
-{
-	unsigned long tcon;
-	unsigned long tcnt;
-	unsigned long tcfg1;
-	unsigned long tcfg0;
-
-	tcnt = TICK_MAX;  /* default value for tcnt */
-
-	/* configure the system for whichever machine is in use */
-
-	if (use_tclk1_12()) {
-		/* timer is at 12MHz, scaler is 1 */
-		timer_usec_ticks = timer_mask_usec_ticks(1, 12000000);
-		tcnt = 12000000 / HZ;
-
-		tcfg1 = __raw_readl(S3C2410_TCFG1);
-		tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
-		tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1;
-		__raw_writel(tcfg1, S3C2410_TCFG1);
-	} else {
-		unsigned long pclk;
-		struct clk *tscaler;
-
-		/* for the h1940 (and others), we use the pclk from the core
-		 * to generate the timer values. since values around 50 to
-		 * 70MHz are not values we can directly generate the timer
-		 * value from, we need to pre-scale and divide before using it.
-		 *
-		 * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz
-		 * (8.45 ticks per usec)
-		 */
-
-		pclk = clk_get_rate(timerclk);
-
-		/* configure clock tick */
-
-		timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
-
-		tscaler = clk_get_parent(tdiv);
-
-		clk_set_rate(tscaler, pclk / 3);
-		clk_set_rate(tdiv, pclk / 6);
-		clk_set_parent(tin, tdiv);
-
-		tcnt = clk_get_rate(tin) / HZ;
-	}
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcfg0 = __raw_readl(S3C2410_TCFG0);
-	tcfg1 = __raw_readl(S3C2410_TCFG1);
-
-	/* timers reload after counting zero, so reduce the count by 1 */
-
-	tcnt--;
-
-	printk(KERN_DEBUG "timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx, usec %08lx\n",
-	       tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks);
-
-	/* check to see if timer is within 16bit range... */
-	if (tcnt > TICK_MAX) {
-		panic("setup_timer: HZ is too small, cannot configure timer!");
-		return;
-	}
-
-	__raw_writel(tcfg1, S3C2410_TCFG1);
-	__raw_writel(tcfg0, S3C2410_TCFG0);
-
-	timer_startval = tcnt;
-	__raw_writel(tcnt, S3C2410_TCNTB(4));
-
-	/* ensure timer is stopped... */
-
-	tcon &= ~(7<<20);
-	tcon |= S3C2410_TCON_T4RELOAD;
-	tcon |= S3C2410_TCON_T4MANUALUPD;
-
-	__raw_writel(tcon, S3C2410_TCON);
-	__raw_writel(tcnt, S3C2410_TCNTB(4));
-	__raw_writel(tcnt, S3C2410_TCMPB(4));
-
-	/* start the timer running */
-	tcon |= S3C2410_TCON_T4START;
-	tcon &= ~S3C2410_TCON_T4MANUALUPD;
-	__raw_writel(tcon, S3C2410_TCON);
-}
-
-static void __init s3c2410_timer_resources(void)
-{
-	struct platform_device tmpdev;
-
-	tmpdev.dev.bus = &platform_bus_type;
-	tmpdev.id = 4;
-
-	timerclk = clk_get(NULL, "timers");
-	if (IS_ERR(timerclk))
-		panic("failed to get clock for system timer");
-
-	clk_enable(timerclk);
-
-	if (!use_tclk1_12()) {
-		tin = clk_get(&tmpdev.dev, "pwm-tin");
-		if (IS_ERR(tin))
-			panic("failed to get pwm-tin clock for system timer");
-
-		tdiv = clk_get(&tmpdev.dev, "pwm-tdiv");
-		if (IS_ERR(tdiv))
-			panic("failed to get pwm-tdiv clock for system timer");
-	}
-
-	clk_enable(tin);
-}
-
-static void __init s3c2410_timer_init(void)
-{
-	s3c2410_timer_resources();
-	s3c2410_timer_setup();
-	setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
-}
-
-struct sys_timer s3c24xx_timer = {
-	.init		= s3c2410_timer_init,
-	.offset		= s3c2410_gettimeoffset,
-	.resume		= s3c2410_timer_setup
-};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/adc.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/adc.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/adc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/adc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,435 +0,0 @@
-/* arch/arm/plat-s3c24xx/adc.c
- *
- * Copyright (c) 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
- *
- * S3C24XX ADC device core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/list.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-
-#include <plat/regs-adc.h>
-#include <plat/adc.h>
-
-/* This driver is designed to control the usage of the ADC block between
- * the touchscreen and any other drivers that may need to use it, such as
- * the hwmon driver.
- *
- * Priority will be given to the touchscreen driver, but as this itself is
- * rate limited it should not starve other requests which are processed in
- * order that they are received.
- *
- * Each user registers to get a client block which uniquely identifies it
- * and stores information such as the necessary functions to callback when
- * action is required.
- */
-
-struct s3c_adc_client {
-	struct platform_device	*pdev;
-	struct list_head	 pend;
-	wait_queue_head_t	*wait;
-
-	unsigned int		 nr_samples;
-	int			 result;
-	unsigned char		 is_ts;
-	unsigned char		 channel;
-
-	void	(*select_cb)(struct s3c_adc_client *c, unsigned selected);
-	void	(*convert_cb)(struct s3c_adc_client *c,
-			      unsigned val1, unsigned val2,
-			      unsigned *samples_left);
-};
-
-struct adc_device {
-	struct platform_device	*pdev;
-	struct platform_device	*owner;
-	struct clk		*clk;
-	struct s3c_adc_client	*cur;
-	struct s3c_adc_client	*ts_pend;
-	void __iomem		*regs;
-
-	unsigned int		 prescale;
-
-	int			 irq;
-};
-
-static struct adc_device *adc_dev;
-
-static LIST_HEAD(adc_pending);
-
-#define adc_dbg(_adc, msg...) dev_dbg(&(_adc)->pdev->dev, msg)
-
-static inline void s3c_adc_convert(struct adc_device *adc)
-{
-	unsigned con = readl(adc->regs + S3C2410_ADCCON);
-
-	con |= S3C2410_ADCCON_ENABLE_START;
-	writel(con, adc->regs + S3C2410_ADCCON);
-}
-
-static inline void s3c_adc_select(struct adc_device *adc,
-				  struct s3c_adc_client *client)
-{
-	unsigned con = readl(adc->regs + S3C2410_ADCCON);
-
-	client->select_cb(client, 1);
-
-	con &= ~S3C2410_ADCCON_MUXMASK;
-	con &= ~S3C2410_ADCCON_STDBM;
-	con &= ~S3C2410_ADCCON_STARTMASK;
-
-	if (!client->is_ts)
-		con |= S3C2410_ADCCON_SELMUX(client->channel);
-
-	writel(con, adc->regs + S3C2410_ADCCON);
-}
-
-static void s3c_adc_dbgshow(struct adc_device *adc)
-{
-	adc_dbg(adc, "CON=%08x, TSC=%08x, DLY=%08x\n",
-		readl(adc->regs + S3C2410_ADCCON),
-		readl(adc->regs + S3C2410_ADCTSC),
-		readl(adc->regs + S3C2410_ADCDLY));
-}
-
-static void s3c_adc_try(struct adc_device *adc)
-{
-	struct s3c_adc_client *next = adc->ts_pend;
-
-	if (!next && !list_empty(&adc_pending)) {
-		next = list_first_entry(&adc_pending,
-					struct s3c_adc_client, pend);
-		list_del(&next->pend);
-	} else
-		adc->ts_pend = NULL;
-
-	if (next) {
-		adc_dbg(adc, "new client is %p\n", next);
-		adc->cur = next;
-		s3c_adc_select(adc, next);
-		s3c_adc_convert(adc);
-		s3c_adc_dbgshow(adc);
-	}
-}
-
-int s3c_adc_start(struct s3c_adc_client *client,
-		  unsigned int channel, unsigned int nr_samples)
-{
-	struct adc_device *adc = adc_dev;
-	unsigned long flags;
-
-	if (!adc) {
-		printk(KERN_ERR "%s: failed to find adc\n", __func__);
-		return -EINVAL;
-	}
-
-	if (client->is_ts && adc->ts_pend)
-		return -EAGAIN;
-
-	local_irq_save(flags);
-
-	client->channel = channel;
-	client->nr_samples = nr_samples;
-
-	if (client->is_ts)
-		adc->ts_pend = client;
-	else
-		list_add_tail(&client->pend, &adc_pending);
-
-	if (!adc->cur)
-		s3c_adc_try(adc);
-	local_irq_restore(flags);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(s3c_adc_start);
-
-static void s3c_convert_done(struct s3c_adc_client *client,
-			     unsigned v, unsigned u, unsigned *left)
-{
-	client->result = v;
-	wake_up(client->wait);
-}
-
-int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)
-{
-	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
-	int ret;
-
-	client->convert_cb = s3c_convert_done;
-	client->wait = &wake;
-	client->result = -1;
-
-	ret = s3c_adc_start(client, ch, 1);
-	if (ret < 0)
-		goto err;
-
-	ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);
-	if (client->result < 0) {
-		ret = -ETIMEDOUT;
-		goto err;
-	}
-
-	client->convert_cb = NULL;
-	return client->result;
-
-err:
-	return ret;
-}
-EXPORT_SYMBOL_GPL(s3c_adc_read);
-
-static void s3c_adc_default_select(struct s3c_adc_client *client,
-				   unsigned select)
-{
-}
-
-struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev,
-					void (*select)(struct s3c_adc_client *client,
-						       unsigned int selected),
-					void (*conv)(struct s3c_adc_client *client,
-						     unsigned d0, unsigned d1,
-						     unsigned *samples_left),
-					unsigned int is_ts)
-{
-	struct s3c_adc_client *client;
-
-	WARN_ON(!pdev);
-
-	if (!select)
-		select = s3c_adc_default_select;
-
-	if (!pdev)
-		return ERR_PTR(-EINVAL);
-
-	client = kzalloc(sizeof(struct s3c_adc_client), GFP_KERNEL);
-	if (!client) {
-		dev_err(&pdev->dev, "no memory for adc client\n");
-		return ERR_PTR(-ENOMEM);
-	}
-
-	client->pdev = pdev;
-	client->is_ts = is_ts;
-	client->select_cb = select;
-	client->convert_cb = conv;
-
-	return client;
-}
-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);
-
-static irqreturn_t s3c_adc_irq(int irq, void *pw)
-{
-	struct adc_device *adc = pw;
-	struct s3c_adc_client *client = adc->cur;
-	unsigned long flags;
-	unsigned data0, data1;
-
-	if (!client) {
-		dev_warn(&adc->pdev->dev, "%s: no adc pending\n", __func__);
-		return IRQ_HANDLED;
-	}
-
-	data0 = readl(adc->regs + S3C2410_ADCDAT0);
-	data1 = readl(adc->regs + S3C2410_ADCDAT1);
-	adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1);
-
-	client->nr_samples--;
-
-	if (client->convert_cb)
-		(client->convert_cb)(client, data0 & 0x3ff, data1 & 0x3ff,
-				     &client->nr_samples);
-
-	if (client->nr_samples > 0) {
-		/* fire another conversion for this */
-
-		client->select_cb(client, 1);
-		s3c_adc_convert(adc);
-	} else {
-		local_irq_save(flags);
-		(client->select_cb)(client, 0);
-		adc->cur = NULL;
-
-		s3c_adc_try(adc);
-		local_irq_restore(flags);
-	}
-
-	return IRQ_HANDLED;
-}
-
-static int s3c_adc_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct adc_device *adc;
-	struct resource *regs;
-	int ret;
-
-	adc = kzalloc(sizeof(struct adc_device), GFP_KERNEL);
-	if (adc == NULL) {
-		dev_err(dev, "failed to allocate adc_device\n");
-		return -ENOMEM;
-	}
-
-	adc->pdev = pdev;
-	adc->prescale = S3C2410_ADCCON_PRSCVL(49);
-
-	adc->irq = platform_get_irq(pdev, 1);
-	if (adc->irq <= 0) {
-		dev_err(dev, "failed to get adc irq\n");
-		ret = -ENOENT;
-		goto err_alloc;
-	}
-
-	ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc);
-	if (ret < 0) {
-		dev_err(dev, "failed to attach adc irq\n");
-		goto err_alloc;
-	}
-
-	adc->clk = clk_get(dev, "adc");
-	if (IS_ERR(adc->clk)) {
-		dev_err(dev, "failed to get adc clock\n");
-		ret = PTR_ERR(adc->clk);
-		goto err_irq;
-	}
-
-	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!regs) {
-		dev_err(dev, "failed to find registers\n");
-		ret = -ENXIO;
-		goto err_clk;
-	}
-
-	adc->regs = ioremap(regs->start, resource_size(regs));
-	if (!adc->regs) {
-		dev_err(dev, "failed to map registers\n");
-		ret = -ENXIO;
-		goto err_clk;
-	}
-
-	clk_enable(adc->clk);
-
-	writel(adc->prescale | S3C2410_ADCCON_PRSCEN,
-	       adc->regs + S3C2410_ADCCON);
-
-	dev_info(dev, "attached adc driver\n");
-
-	platform_set_drvdata(pdev, adc);
-	adc_dev = adc;
-
-	return 0;
-
- err_clk:
-	clk_put(adc->clk);
-
- err_irq:
-	free_irq(adc->irq, adc);
-
- err_alloc:
-	kfree(adc);
-	return ret;
-}
-
-static int __devexit s3c_adc_remove(struct platform_device *pdev)
-{
-	struct adc_device *adc = platform_get_drvdata(pdev);
-
-	iounmap(adc->regs);
-	free_irq(adc->irq, adc);
-	clk_disable(adc->clk);
-	clk_put(adc->clk);
-	kfree(adc);
-
-	return 0;
-}
-
-#ifdef CONFIG_PM
-static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	struct adc_device *adc = platform_get_drvdata(pdev);
-	u32 con;
-
-	con = readl(adc->regs + S3C2410_ADCCON);
-	con |= S3C2410_ADCCON_STDBM;
-	writel(con, adc->regs + S3C2410_ADCCON);
-
-	clk_disable(adc->clk);
-
-	return 0;
-}
-
-static int s3c_adc_resume(struct platform_device *pdev)
-{
-	struct adc_device *adc = platform_get_drvdata(pdev);
-
-	clk_enable(adc->clk);
-
-	writel(adc->prescale | S3C2410_ADCCON_PRSCEN,
-	       adc->regs + S3C2410_ADCCON);
-
-	return 0;
-}
-
-#else
-#define s3c_adc_suspend NULL
-#define s3c_adc_resume NULL
-#endif
-
-static struct platform_driver s3c_adc_driver = {
-	.driver		= {
-		.name	= "s3c24xx-adc",
-		.owner	= THIS_MODULE,
-	},
-	.probe		= s3c_adc_probe,
-	.remove		= __devexit_p(s3c_adc_remove),
-	.suspend	= s3c_adc_suspend,
-	.resume		= s3c_adc_resume,
-};
-
-static int __init adc_init(void)
-{
-	int ret;
-
-	ret = platform_driver_register(&s3c_adc_driver);
-	if (ret)
-		printk(KERN_ERR "%s: failed to add adc driver\n", __func__);
-
-	return ret;
-}
-
-arch_initcall(adc_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/clock-dclk.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/clock-dclk.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/clock-dclk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/clock-dclk.c	2010-05-16 17:17:36.000000000 -0400
@@ -161,14 +161,18 @@ static int s3c24xx_clkout_setparent(stru
 
 /* external clock definitions */
 
+static struct clk_ops dclk_ops = {
+	.set_parent	= s3c24xx_dclk_setparent,
+	.set_rate	= s3c24xx_set_dclk_rate,
+	.round_rate	= s3c24xx_round_dclk_rate,
+};
+
 struct clk s3c24xx_dclk0 = {
 	.name		= "dclk0",
 	.id		= -1,
 	.ctrlbit	= S3C2410_DCLKCON_DCLK0EN,
 	.enable	        = s3c24xx_dclk_enable,
-	.set_parent	= s3c24xx_dclk_setparent,
-	.set_rate	= s3c24xx_set_dclk_rate,
-	.round_rate	= s3c24xx_round_dclk_rate,
+	.ops		= &dclk_ops,
 };
 
 struct clk s3c24xx_dclk1 = {
@@ -176,19 +180,21 @@ struct clk s3c24xx_dclk1 = {
 	.id		= -1,
 	.ctrlbit	= S3C2410_DCLKCON_DCLK1EN,
 	.enable		= s3c24xx_dclk_enable,
-	.set_parent	= s3c24xx_dclk_setparent,
-	.set_rate	= s3c24xx_set_dclk_rate,
-	.round_rate	= s3c24xx_round_dclk_rate,
+	.ops		= &dclk_ops,
+};
+
+static struct clk_ops clkout_ops = {
+	.set_parent	= s3c24xx_clkout_setparent,
 };
 
 struct clk s3c24xx_clkout0 = {
 	.name		= "clkout0",
 	.id		= -1,
-	.set_parent	= s3c24xx_clkout_setparent,
+	.ops		= &clkout_ops,
 };
 
 struct clk s3c24xx_clkout1 = {
 	.name		= "clkout1",
 	.id		= -1,
-	.set_parent	= s3c24xx_clkout_setparent,
+	.ops		= &clkout_ops,
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/cpu.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/cpu.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/cpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/cpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,9 +49,7 @@
 #include <plat/s3c2400.h>
 #include <plat/s3c2410.h>
 #include <plat/s3c2412.h>
-#include "s3c244x.h"
-#include <plat/s3c2440.h>
-#include <plat/s3c2442.h>
+#include <plat/s3c244x.h>
 #include <plat/s3c2443.h>
 
 /* table of supported CPUs */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/cpu-freq.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/cpu-freq.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/cpu-freq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/cpu-freq.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/sysdev.h>
 #include <linux/kobject.h>
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/devs.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/devs.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/devs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/devs.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -32,6 +33,7 @@
 
 #include <plat/regs-serial.h>
 #include <plat/udc.h>
+#include <plat/mci.h>
 
 #include <plat/devs.h>
 #include <plat/cpu.h>
@@ -112,34 +114,6 @@ struct s3c24xx_uart_resources s3c2410_ua
 	},
 };
 
-/* yart devices */
-
-static struct platform_device s3c24xx_uart_device0 = {
-	.id		= 0,
-};
-
-static struct platform_device s3c24xx_uart_device1 = {
-	.id		= 1,
-};
-
-static struct platform_device s3c24xx_uart_device2 = {
-	.id		= 2,
-};
-
-static struct platform_device s3c24xx_uart_device3 = {
-	.id		= 3,
-};
-
-struct platform_device *s3c24xx_uart_src[4] = {
-	&s3c24xx_uart_device0,
-	&s3c24xx_uart_device1,
-	&s3c24xx_uart_device2,
-	&s3c24xx_uart_device3,
-};
-
-struct platform_device *s3c24xx_uart_devs[4] = {
-};
-
 /* LCD Controller */
 
 static struct resource s3c_lcd_resource[] = {
@@ -185,9 +159,27 @@ void __init s3c24xx_fb_set_platdata(stru
 }
 
 /* Touchscreen */
+
+static struct resource s3c_ts_resource[] = {
+	[0] = {
+		.start = S3C24XX_PA_ADC,
+		.end   = S3C24XX_PA_ADC + S3C24XX_SZ_ADC - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_TC,
+		.end   = IRQ_TC,
+		.flags = IORESOURCE_IRQ,
+	},
+
+};
+
 struct platform_device s3c_device_ts = {
 	.name		  = "s3c2410-ts",
 	.id		  = -1,
+	.dev.parent	= &s3c_device_adc.dev,
+	.num_resources	  = ARRAY_SIZE(s3c_ts_resource),
+	.resource	  = s3c_ts_resource,
 };
 EXPORT_SYMBOL(s3c_device_ts);
 
@@ -379,6 +371,18 @@ struct platform_device s3c_device_sdi =
 
 EXPORT_SYMBOL(s3c_device_sdi);
 
+void s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
+{
+	struct s3c24xx_mci_pdata *npd;
+
+	npd = kmemdup(pdata, sizeof(struct s3c24xx_mci_pdata), GFP_KERNEL);
+	if (!npd)
+		printk(KERN_ERR "%s: no memory to copy pdata", __func__);
+
+	s3c_device_sdi.dev.platform_data = npd;
+}
+
+
 /* SPI (0) */
 
 static struct resource s3c_spi0_resource[] = {
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/dma.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,7 @@
 #include <mach/dma.h>
 #include <mach/map.h>
 
-#include <plat/dma-plat.h>
+#include <plat/dma-s3c24xx.h>
 #include <plat/regs-dma.h>
 
 /* io map for dma */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/gpiolib.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/gpiolib.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/gpiolib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/gpiolib.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,7 +20,7 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 
-#include <mach/gpio-core.h>
+#include <plat/gpio-core.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <plat/pm.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/audio-simtec.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/audio-simtec.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/audio-simtec.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/audio-simtec.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,37 @@
+/* arch/arm/plat-s3c24xx/include/plat/audio-simtec.h
+ *
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	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.
+ *
+ * Simtec Audio support.
+*/
+
+/**
+ * struct s3c24xx_audio_simtec_pdata - platform data for simtec audio
+ * @use_mpllin: Select codec clock from MPLLin
+ * @output_cdclk: Need to output CDCLK to the codec
+ * @have_mic: Set if we have a MIC socket
+ * @have_lout: Set if we have a LineOut socket
+ * @amp_gpio: GPIO pin to enable the AMP
+ * @amp_gain: Option GPIO to control AMP gain
+ */
+struct s3c24xx_audio_simtec_pdata {
+	unsigned int	use_mpllin:1;
+	unsigned int	output_cdclk:1;
+
+	unsigned int	have_mic:1;
+	unsigned int	have_lout:1;
+
+	int		amp_gpio;
+	int		amp_gain[2];
+
+	void	(*startup)(void);
+};
+
+extern int simtec_audio_add(const char *codec_name, bool has_lr_routing,
+			    struct s3c24xx_audio_simtec_pdata *pdata);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h	2010-05-16 17:17:36.000000000 -0400
@@ -135,7 +135,7 @@ struct s3c_cpufreq_config {
  * @locktime_m: The lock-time in uS for the MPLL.
  * @locktime_u: The lock-time in uS for the UPLL.
  * @locttime_bits: The number of bits each LOCKTIME field.
- * @need_pll: Set if this driver needs to change the PLL values to acheive
+ * @need_pll: Set if this driver needs to change the PLL values to achieve
  *	any frequency changes. This is really only need by devices like the
  *	S3C2410 where there is no or limited divider between the PLL and the
  *	ARMCLK.
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/dma-plat.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/dma-plat.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/dma-plat.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/dma-plat.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,84 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/include/plat/dma-plat.h
- *
- * Copyright (C) 2006 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C24XX DMA 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 <plat/dma-core.h>
-
-extern struct sysdev_class dma_sysclass;
-extern struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
-
-#define DMA_CH_VALID		(1<<31)
-#define DMA_CH_NEVER		(1<<30)
-
-struct s3c24xx_dma_addr {
-	unsigned long		from;
-	unsigned long		to;
-};
-
-/* struct s3c24xx_dma_map
- *
- * this holds the mapping information for the channel selected
- * to be connected to the specified device
-*/
-
-struct s3c24xx_dma_map {
-	const char		*name;
-	struct s3c24xx_dma_addr  hw_addr;
-
-	unsigned long		 channels[S3C_DMA_CHANNELS];
-	unsigned long		 channels_rx[S3C_DMA_CHANNELS];
-};
-
-struct s3c24xx_dma_selection {
-	struct s3c24xx_dma_map	*map;
-	unsigned long		 map_size;
-	unsigned long		 dcon_mask;
-
-	void	(*select)(struct s3c2410_dma_chan *chan,
-			  struct s3c24xx_dma_map *map);
-
-	void	(*direction)(struct s3c2410_dma_chan *chan,
-			     struct s3c24xx_dma_map *map,
-			     enum s3c2410_dmasrc dir);
-};
-
-extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
-
-/* struct s3c24xx_dma_order_ch
- *
- * channel map for one of the `enum dma_ch` dma channels. the list
- * entry contains a set of low-level channel numbers, orred with
- * DMA_CH_VALID, which are checked in the order in the array.
-*/
-
-struct s3c24xx_dma_order_ch {
-	unsigned int	list[S3C_DMA_CHANNELS];	/* list of channels */
-	unsigned int	flags;				/* flags */
-};
-
-/* struct s3c24xx_dma_order
- *
- * information provided by either the core or the board to give the
- * dma system a hint on how to allocate channels
-*/
-
-struct s3c24xx_dma_order {
-	struct s3c24xx_dma_order_ch	channels[DMACH_MAX];
-};
-
-extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map);
-
-/* DMA init code, called from the cpu support code */
-
-extern int s3c2410_dma_init(void);
-
-extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq,
-			    unsigned int stride);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/mci.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/mci.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/mci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/mci.h	2010-05-16 17:17:36.000000000 -0400
@@ -40,4 +40,13 @@ struct s3c24xx_mci_pdata {
 				     unsigned short vdd);
 };
 
+/**
+ * s3c24xx_mci_set_platdata - set platform data for mmc/sdi device
+ * @pdata: The platform data
+ *
+ * Copy the platform data supplied by @pdata so that this can be marked
+ * __initdata.
+ */
+extern void s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata);
+
 #endif /* _ARCH_NCI_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/pm-core.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/pm-core.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/pm-core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/pm-core.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,64 +0,0 @@
-/* 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);
-}
-
-static inline void s3c_pm_arch_update_uart(void __iomem *regs,
-					   struct pm_uart_save *save)
-{
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/s3c2440.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/s3c2440.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/s3c2440.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/s3c2440.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/s3c2440.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2440 cpu 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.
-*/
-
-#ifdef CONFIG_CPU_S3C2440
-extern  int s3c2440_init(void);
-#else
-#define s3c2440_init NULL
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/s3c2442.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/s3c2442.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/s3c2442.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/s3c2442.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/s3c2442.h
- *
- * Copyright (c) 2006 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2442 cpu 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.
-*/
-
-#ifdef CONFIG_CPU_S3C2442
-extern  int s3c2442_init(void);
-#else
-#define s3c2442_init NULL
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/s3c244x.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/s3c244x.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/s3c244x.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/include/plat/s3c244x.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,37 @@
+/* linux/arch/arm/plat-s3c24xx/include/plat/s3c244x.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C2440 and S3C2442 cpu 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.
+*/
+
+#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
+
+extern void s3c244x_map_io(void);
+
+extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c244x_init_clocks(int xtal);
+
+#else
+#define s3c244x_init_clocks NULL
+#define s3c244x_init_uarts NULL
+#define s3c244x_map_io NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2440
+extern  int s3c2440_init(void);
+#else
+#define s3c2440_init NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2442
+extern  int s3c2442_init(void);
+#else
+#define s3c2442_init NULL
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/Kconfig linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -14,58 +14,40 @@ config PLAT_S3C24XX
 
 if PLAT_S3C24XX
 
-# code that is shared between a number of the s3c24xx implementations
+# low-level serial option nodes
 
-config S3C2410_CLOCK
+config CPU_LLSERIAL_S3C2410_ONLY
 	bool
-	help
-	  Clock code for the S3C2410, and similar processors which
-	  is currently includes the S3C2410, S3C2440, S3C2442.
+	default y if CPU_LLSERIAL_S3C2410 && !CPU_LLSERIAL_S3C2440
 
-config S3C24XX_DCLK
+config CPU_LLSERIAL_S3C2440_ONLY
 	bool
-	help
-	  Clock code for supporting DCLK/CLKOUT on S3C24XX architectures
+	default y if CPU_LLSERIAL_S3C2440 && !CPU_LLSERIAL_S3C2410
 
-config CPU_S3C244X
+config CPU_LLSERIAL_S3C2410
 	bool
-	depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
 	help
-	  Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
-
-config S3C2440_CPUFREQ
-	bool "S3C2440/S3C2442 CPU Frequency scaling support"
-	depends on CPU_FREQ_S3C24XX && (CPU_S3C2440 || CPU_S3C2442)
-	select S3C2410_CPUFREQ_UTILS
-	default y
-	help
-	  CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs.
+	  Selected if there is an S3C2410 (or register compatible) serial
+	  low-level implementation needed
 
-config S3C2440_XTAL_12000000
+config CPU_LLSERIAL_S3C2440
 	bool
 	help
-	  Indicate that the build needs to support 12MHz system
-	  crystal.
+	  Selected if there is an S3C2440 (or register compatible) serial
+	  low-level implementation needed
 
-config S3C2440_XTAL_16934400
-	bool
-	help
-	  Indicate that the build needs to support 16.9344MHz system
-	  crystal.
+# code that is shared between a number of the s3c24xx implementations
 
-config S3C2440_PLL_12000000
+config S3C2410_CLOCK
 	bool
-	depends on S3C2440_CPUFREQ && S3C2440_XTAL_12000000
-	default y if CPU_FREQ_S3C24XX_PLL
 	help
-	  PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals.
+	  Clock code for the S3C2410, and similar processors which
+	  is currently includes the S3C2410, S3C2440, S3C2442.
 
-config S3C2440_PLL_16934400
+config S3C24XX_DCLK
 	bool
-	depends on S3C2440_CPUFREQ && S3C2440_XTAL_16934400
-	default y if CPU_FREQ_S3C24XX_PLL
 	help
-	  PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals.
+	  Clock code for supporting DCLK/CLKOUT on S3C24XX architectures
 
 config S3C24XX_PWM
 	bool "PWM device support"
@@ -74,7 +56,6 @@ config S3C24XX_PWM
 	  Support for exporting the PWM timer blocks via the pwm device
 	  system.
 
-
 # gpio configurations
 
 config S3C24XX_GPIO_EXTRA
@@ -117,13 +98,6 @@ config S3C2410_DMA_DEBUG
 	  Enable debugging output for the DMA code. This option sends info
 	  to the kernel log, at priority KERN_DEBUG.
 
-config S3C24XX_ADC
-	bool "ADC common driver support"
-	help
-	  Core support for the ADC block found in the S3C24XX SoC systems
-	  for drivers such as the touchscreen and hwmon to use to share
-	  this resource.
-
 # SPI default pin configuration code
 
 config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/Makefile linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -25,20 +25,12 @@ obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) +
 
 # Architecture dependant builds
 
-obj-$(CONFIG_CPU_S3C244X)	+= s3c244x.o
-obj-$(CONFIG_CPU_S3C244X)	+= s3c244x-irq.o
-obj-$(CONFIG_CPU_S3C244X)	+= s3c244x-clock.o
-obj-$(CONFIG_S3C2440_CPUFREQ)	+= s3c2440-cpufreq.o
-obj-$(CONFIG_S3C2440_PLL_12000000) += s3c2440-pll-12000000.o
-obj-$(CONFIG_S3C2440_PLL_16934400) += s3c2440-pll-16934400.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_S3C2410_CLOCK)	+= s3c2410-clock.o
 obj-$(CONFIG_S3C2410_DMA)	+= dma.o
-obj-$(CONFIG_S3C24XX_ADC)	+= adc.o
 obj-$(CONFIG_S3C2410_IOTIMING)	+= s3c2410-iotiming.o
 obj-$(CONFIG_S3C2412_IOTIMING)	+= s3c2412-iotiming.o
 obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += s3c2410-cpufreq-utils.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2410-iotiming.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2410-iotiming.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c2410-iotiming.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/cpufreq.h>
 #include <linux/seq_file.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/map.h>
 #include <mach/regs-mem.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2412-iotiming.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c2412-iotiming.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2412-iotiming.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c2412-iotiming.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <linux/amba/pl093.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,311 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c
- *
- * Copyright (c) 2006-2009 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *	Vincent Sanders <vince@simtec.co.uk>
- *
- * S3C2440/S3C2442 CPU Frequency scaling
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/cpufreq.h>
-#include <linux/sysdev.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/cpu.h>
-#include <plat/cpu-freq-core.h>
-#include <plat/clock.h>
-
-static struct clk *xtal;
-static struct clk *fclk;
-static struct clk *hclk;
-static struct clk *armclk;
-
-/* HDIV: 1, 2, 3, 4, 6, 8 */
-
-static inline int within_khz(unsigned long a, unsigned long b)
-{
-	long diff = a - b;
-
-	return (diff >= -1000 && diff <= 1000);
-}
-
-/**
- * s3c2440_cpufreq_calcdivs - calculate divider settings
- * @cfg: The cpu frequency settings.
- *
- * Calcualte the divider values for the given frequency settings
- * specified in @cfg. The values are stored in @cfg for later use
- * by the relevant set routine if the request settings can be reached.
- */
-int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
-{
-	unsigned int hdiv, pdiv;
-	unsigned long hclk, fclk, armclk;
-	unsigned long hclk_max;
-
-	fclk = cfg->freq.fclk;
-	armclk = cfg->freq.armclk;
-	hclk_max = cfg->max.hclk;
-
-	s3c_freq_dbg("%s: fclk is %lu, armclk %lu, max hclk %lu\n",
-		     __func__, fclk, armclk, hclk_max);
-
-	if (armclk > fclk) {
-		printk(KERN_WARNING "%s: armclk > fclk\n", __func__);
-		armclk = fclk;
-	}
-
-	/* if we are in DVS, we need HCLK to be <= ARMCLK */
-	if (armclk < fclk && armclk < hclk_max)
-		hclk_max = armclk;
-
-	for (hdiv = 1; hdiv < 9; hdiv++) {
-		if (hdiv == 5 || hdiv == 7)
-			hdiv++;
-
-		hclk = (fclk / hdiv);
-		if (hclk <= hclk_max || within_khz(hclk, hclk_max))
-			break;
-	}
-
-	s3c_freq_dbg("%s: hclk %lu, div %d\n", __func__, hclk, hdiv);
-
-	if (hdiv > 8)
-		goto invalid;
-
-	pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
-
-	if ((hclk / pdiv) > cfg->max.pclk)
-		pdiv++;
-
-	s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv);
-
-	if (pdiv > 2)
-		goto invalid;
-
-	pdiv *= hdiv;
-
-	/* calculate a valid armclk */
-
-	if (armclk < hclk)
-		armclk = hclk;
-
-	/* if we're running armclk lower than fclk, this really means
-	 * that the system should go into dvs mode, which means that
-	 * armclk is connected to hclk. */
-	if (armclk < fclk) {
-		cfg->divs.dvs = 1;
-		armclk = hclk;
-	} else
-		cfg->divs.dvs = 0;
-
-	cfg->freq.armclk = armclk;
-
-	/* store the result, and then return */
-
-	cfg->divs.h_divisor = hdiv;
-	cfg->divs.p_divisor = pdiv;
-
-	return 0;
-
- invalid:
-	return -EINVAL;
-}
-
-#define CAMDIVN_HCLK_HALF (S3C2440_CAMDIVN_HCLK3_HALF | \
-			   S3C2440_CAMDIVN_HCLK4_HALF)
-
-/**
- * s3c2440_cpufreq_setdivs - set the cpu frequency divider settings
- * @cfg: The cpu frequency settings.
- *
- * Set the divisors from the settings in @cfg, which where generated
- * during the calculation phase by s3c2440_cpufreq_calcdivs().
- */
-static void s3c2440_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
-{
-	unsigned long clkdiv, camdiv;
-
-	s3c_freq_dbg("%s: divsiors: h=%d, p=%d\n", __func__,
-		     cfg->divs.h_divisor, cfg->divs.p_divisor);
-
-	clkdiv = __raw_readl(S3C2410_CLKDIVN);
-	camdiv = __raw_readl(S3C2440_CAMDIVN);
-
-	clkdiv &= ~(S3C2440_CLKDIVN_HDIVN_MASK | S3C2440_CLKDIVN_PDIVN);
-	camdiv &= ~CAMDIVN_HCLK_HALF;
-
-	switch (cfg->divs.h_divisor) {
-	case 1:
-		clkdiv |= S3C2440_CLKDIVN_HDIVN_1;
-		break;
-
-	case 2:
-		clkdiv |= S3C2440_CLKDIVN_HDIVN_2;
-		break;
-
-	case 6:
-		camdiv |= S3C2440_CAMDIVN_HCLK3_HALF;
-	case 3:
-		clkdiv |= S3C2440_CLKDIVN_HDIVN_3_6;
-		break;
-
-	case 8:
-		camdiv |= S3C2440_CAMDIVN_HCLK4_HALF;
-	case 4:
-		clkdiv |= S3C2440_CLKDIVN_HDIVN_4_8;
-		break;
-
-	default:
-		BUG();	/* we don't expect to get here. */
-	}
-
-	if (cfg->divs.p_divisor != cfg->divs.h_divisor)
-		clkdiv |= S3C2440_CLKDIVN_PDIVN;
-
-	/* todo - set pclk. */
-
-	/* Write the divisors first with hclk intentionally halved so that
-	 * when we write clkdiv we will under-frequency instead of over. We
-	 * then make a short delay and remove the hclk halving if necessary.
-	 */
-
-	__raw_writel(camdiv | CAMDIVN_HCLK_HALF, S3C2440_CAMDIVN);
-	__raw_writel(clkdiv, S3C2410_CLKDIVN);
-
-	ndelay(20);
-	__raw_writel(camdiv, S3C2440_CAMDIVN);
-
-	clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk);
-}
-
-static int run_freq_for(unsigned long max_hclk, unsigned long fclk,
-			int *divs,
-			struct cpufreq_frequency_table *table,
-			size_t table_size)
-{
-	unsigned long freq;
-	int index = 0;
-	int div;
-
-	for (div = *divs; div > 0; div = *divs++) {
-		freq = fclk / div;
-
-		if (freq > max_hclk && div != 1)
-			continue;
-
-		freq /= 1000; /* table is in kHz */
-		index = s3c_cpufreq_addfreq(table, index, table_size, freq);
-		if (index < 0)
-			break;
-	}
-
-	return index;
-}
-
-static int hclk_divs[] = { 1, 2, 3, 4, 6, 8, -1 };
-
-static int s3c2440_cpufreq_calctable(struct s3c_cpufreq_config *cfg,
-				     struct cpufreq_frequency_table *table,
-				     size_t table_size)
-{
-	int ret;
-
-	WARN_ON(cfg->info == NULL);
-	WARN_ON(cfg->board == NULL);
-
-	ret = run_freq_for(cfg->info->max.hclk,
-			   cfg->info->max.fclk,
-			   hclk_divs,
-			   table, table_size);
-
-	s3c_freq_dbg("%s: returning %d\n", __func__, ret);
-
-	return ret;
-}
-
-struct s3c_cpufreq_info s3c2440_cpufreq_info = {
-	.max		= {
-		.fclk	= 400000000,
-		.hclk	= 133333333,
-		.pclk	=  66666666,
-	},
-
-	.locktime_m	= 300,
-	.locktime_u	= 300,
-	.locktime_bits	= 16,
-
-	.name		= "s3c244x",
-	.calc_iotiming	= s3c2410_iotiming_calc,
-	.set_iotiming	= s3c2410_iotiming_set,
-	.get_iotiming	= s3c2410_iotiming_get,
-	.set_fvco	= s3c2410_set_fvco,
-
-	.set_refresh	= s3c2410_cpufreq_setrefresh,
-	.set_divs	= s3c2440_cpufreq_setdivs,
-	.calc_divs	= s3c2440_cpufreq_calcdivs,
-	.calc_freqtable	= s3c2440_cpufreq_calctable,
-
-	.resume_clocks	= s3c244x_setup_clocks,
-
-	.debug_io_show  = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
-};
-
-static int s3c2440_cpufreq_add(struct sys_device *sysdev)
-{
-	xtal = s3c_cpufreq_clk_get(NULL, "xtal");
-	hclk = s3c_cpufreq_clk_get(NULL, "hclk");
-	fclk = s3c_cpufreq_clk_get(NULL, "fclk");
-	armclk = s3c_cpufreq_clk_get(NULL, "armclk");
-
-	if (IS_ERR(xtal) || IS_ERR(hclk) || IS_ERR(fclk) || IS_ERR(armclk)) {
-		printk(KERN_ERR "%s: failed to get clocks\n", __func__);
-		return -ENOENT;
-	}
-
-	return s3c_cpufreq_register(&s3c2440_cpufreq_info);
-}
-
-static struct sysdev_driver s3c2440_cpufreq_driver = {
-	.add		= s3c2440_cpufreq_add,
-};
-
-static int s3c2440_cpufreq_init(void)
-{
-	return sysdev_driver_register(&s3c2440_sysclass,
-				      &s3c2440_cpufreq_driver);
-}
-
-/* arch_initcall adds the clocks we need, so use subsys_initcall. */
-subsys_initcall(s3c2440_cpufreq_init);
-
-static struct sysdev_driver s3c2442_cpufreq_driver = {
-	.add		= s3c2440_cpufreq_add,
-};
-
-static int s3c2442_cpufreq_init(void)
-{
-	return sysdev_driver_register(&s3c2442_sysclass,
-				      &s3c2442_cpufreq_driver);
-}
-
-subsys_initcall(s3c2442_cpufreq_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,97 +0,0 @@
-/* arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c
- *
- * Copyright (c) 2006-2007 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *	Vincent Sanders <vince@arm.linux.org.uk>
- *
- * S3C2440/S3C2442 CPU PLL tables (12MHz Crystal)
- *
- * This program is free software; you can 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/kernel.h>
-#include <linux/sysdev.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include <plat/cpu.h>
-#include <plat/cpu-freq-core.h>
-
-static struct cpufreq_frequency_table s3c2440_plls_12[] __initdata = {
-	{ .frequency = 75000000,	.index = PLLVAL(0x75, 3, 3),  }, 	/* FVco 600.000000 */
-	{ .frequency = 80000000,	.index = PLLVAL(0x98, 4, 3),  }, 	/* FVco 640.000000 */
-	{ .frequency = 90000000,	.index = PLLVAL(0x70, 2, 3),  }, 	/* FVco 720.000000 */
-	{ .frequency = 100000000,	.index = PLLVAL(0x5c, 1, 3),  }, 	/* FVco 800.000000 */
-	{ .frequency = 110000000,	.index = PLLVAL(0x66, 1, 3),  }, 	/* FVco 880.000000 */
-	{ .frequency = 120000000,	.index = PLLVAL(0x70, 1, 3),  }, 	/* FVco 960.000000 */
-	{ .frequency = 150000000,	.index = PLLVAL(0x75, 3, 2),  }, 	/* FVco 600.000000 */
-	{ .frequency = 160000000,	.index = PLLVAL(0x98, 4, 2),  }, 	/* FVco 640.000000 */
-	{ .frequency = 170000000,	.index = PLLVAL(0x4d, 1, 2),  }, 	/* FVco 680.000000 */
-	{ .frequency = 180000000,	.index = PLLVAL(0x70, 2, 2),  }, 	/* FVco 720.000000 */
-	{ .frequency = 190000000,	.index = PLLVAL(0x57, 1, 2),  }, 	/* FVco 760.000000 */
-	{ .frequency = 200000000,	.index = PLLVAL(0x5c, 1, 2),  }, 	/* FVco 800.000000 */
-	{ .frequency = 210000000,	.index = PLLVAL(0x84, 2, 2),  }, 	/* FVco 840.000000 */
-	{ .frequency = 220000000,	.index = PLLVAL(0x66, 1, 2),  }, 	/* FVco 880.000000 */
-	{ .frequency = 230000000,	.index = PLLVAL(0x6b, 1, 2),  }, 	/* FVco 920.000000 */
-	{ .frequency = 240000000,	.index = PLLVAL(0x70, 1, 2),  }, 	/* FVco 960.000000 */
-	{ .frequency = 300000000,	.index = PLLVAL(0x75, 3, 1),  }, 	/* FVco 600.000000 */
-	{ .frequency = 310000000,	.index = PLLVAL(0x93, 4, 1),  }, 	/* FVco 620.000000 */
-	{ .frequency = 320000000,	.index = PLLVAL(0x98, 4, 1),  }, 	/* FVco 640.000000 */
-	{ .frequency = 330000000,	.index = PLLVAL(0x66, 2, 1),  }, 	/* FVco 660.000000 */
-	{ .frequency = 340000000,	.index = PLLVAL(0x4d, 1, 1),  }, 	/* FVco 680.000000 */
-	{ .frequency = 350000000,	.index = PLLVAL(0xa7, 4, 1),  }, 	/* FVco 700.000000 */
-	{ .frequency = 360000000,	.index = PLLVAL(0x70, 2, 1),  }, 	/* FVco 720.000000 */
-	{ .frequency = 370000000,	.index = PLLVAL(0xb1, 4, 1),  }, 	/* FVco 740.000000 */
-	{ .frequency = 380000000,	.index = PLLVAL(0x57, 1, 1),  }, 	/* FVco 760.000000 */
-	{ .frequency = 390000000,	.index = PLLVAL(0x7a, 2, 1),  }, 	/* FVco 780.000000 */
-	{ .frequency = 400000000,	.index = PLLVAL(0x5c, 1, 1),  }, 	/* FVco 800.000000 */
-};
-
-static int s3c2440_plls12_add(struct sys_device *dev)
-{
-	struct clk *xtal_clk;
-	unsigned long xtal;
-
-	xtal_clk = clk_get(NULL, "xtal");
-	if (IS_ERR(xtal_clk))
-		return PTR_ERR(xtal_clk);
-
-	xtal = clk_get_rate(xtal_clk);
-	clk_put(xtal_clk);
-
-	if (xtal == 12000000) {
-		printk(KERN_INFO "Using PLL table for 12MHz crystal\n");
-		return s3c_plltab_register(s3c2440_plls_12,
-					   ARRAY_SIZE(s3c2440_plls_12));
-	}
-
-	return 0;
-}
-
-static struct sysdev_driver s3c2440_plls12_drv = {
-	.add	= s3c2440_plls12_add,
-};
-
-static int __init s3c2440_pll_12mhz(void)
-{
-	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_plls12_drv);
-
-}
-
-arch_initcall(s3c2440_pll_12mhz);
-
-static struct sysdev_driver s3c2442_plls12_drv = {
-	.add	= s3c2440_plls12_add,
-};
-
-static int __init s3c2442_pll_12mhz(void)
-{
-	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_plls12_drv);
-
-}
-
-arch_initcall(s3c2442_pll_12mhz);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,127 +0,0 @@
-/* arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c
- *
- * Copyright (c) 2006-2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *	Vincent Sanders <vince@arm.linux.org.uk>
- *
- * S3C2440/S3C2442 CPU PLL tables (16.93444MHz Crystal)
- *
- * This program is free software; you can 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/kernel.h>
-#include <linux/sysdev.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include <plat/cpu.h>
-#include <plat/cpu-freq-core.h>
-
-static struct cpufreq_frequency_table s3c2440_plls_169344[] __initdata = {
-	{ .frequency = 78019200,	.index = PLLVAL(121, 5, 3), 	}, 	/* FVco 624.153600 */
-	{ .frequency = 84067200,	.index = PLLVAL(131, 5, 3), 	}, 	/* FVco 672.537600 */
-	{ .frequency = 90115200,	.index = PLLVAL(141, 5, 3), 	}, 	/* FVco 720.921600 */
-	{ .frequency = 96163200,	.index = PLLVAL(151, 5, 3), 	}, 	/* FVco 769.305600 */
-	{ .frequency = 102135600,	.index = PLLVAL(185, 6, 3), 	}, 	/* FVco 817.084800 */
-	{ .frequency = 108259200,	.index = PLLVAL(171, 5, 3), 	}, 	/* FVco 866.073600 */
-	{ .frequency = 114307200,	.index = PLLVAL(127, 3, 3), 	}, 	/* FVco 914.457600 */
-	{ .frequency = 120234240,	.index = PLLVAL(134, 3, 3), 	}, 	/* FVco 961.873920 */
-	{ .frequency = 126161280,	.index = PLLVAL(141, 3, 3), 	}, 	/* FVco 1009.290240 */
-	{ .frequency = 132088320,	.index = PLLVAL(148, 3, 3), 	}, 	/* FVco 1056.706560 */
-	{ .frequency = 138015360,	.index = PLLVAL(155, 3, 3), 	}, 	/* FVco 1104.122880 */
-	{ .frequency = 144789120,	.index = PLLVAL(163, 3, 3), 	}, 	/* FVco 1158.312960 */
-	{ .frequency = 150100363,	.index = PLLVAL(187, 9, 2), 	}, 	/* FVco 600.401454 */
-	{ .frequency = 156038400,	.index = PLLVAL(121, 5, 2), 	}, 	/* FVco 624.153600 */
-	{ .frequency = 162086400,	.index = PLLVAL(126, 5, 2), 	}, 	/* FVco 648.345600 */
-	{ .frequency = 168134400,	.index = PLLVAL(131, 5, 2), 	}, 	/* FVco 672.537600 */
-	{ .frequency = 174048000,	.index = PLLVAL(177, 7, 2), 	}, 	/* FVco 696.192000 */
-	{ .frequency = 180230400,	.index = PLLVAL(141, 5, 2), 	}, 	/* FVco 720.921600 */
-	{ .frequency = 186278400,	.index = PLLVAL(124, 4, 2), 	}, 	/* FVco 745.113600 */
-	{ .frequency = 192326400,	.index = PLLVAL(151, 5, 2), 	}, 	/* FVco 769.305600 */
-	{ .frequency = 198132480,	.index = PLLVAL(109, 3, 2), 	}, 	/* FVco 792.529920 */
-	{ .frequency = 204271200,	.index = PLLVAL(185, 6, 2), 	}, 	/* FVco 817.084800 */
-	{ .frequency = 210268800,	.index = PLLVAL(141, 4, 2), 	}, 	/* FVco 841.075200 */
-	{ .frequency = 216518400,	.index = PLLVAL(171, 5, 2), 	}, 	/* FVco 866.073600 */
-	{ .frequency = 222264000,	.index = PLLVAL(97, 2, 2), 	}, 	/* FVco 889.056000 */
-	{ .frequency = 228614400,	.index = PLLVAL(127, 3, 2), 	}, 	/* FVco 914.457600 */
-	{ .frequency = 234259200,	.index = PLLVAL(158, 4, 2), 	}, 	/* FVco 937.036800 */
-	{ .frequency = 240468480,	.index = PLLVAL(134, 3, 2), 	}, 	/* FVco 961.873920 */
-	{ .frequency = 246960000,	.index = PLLVAL(167, 4, 2), 	}, 	/* FVco 987.840000 */
-	{ .frequency = 252322560,	.index = PLLVAL(141, 3, 2), 	}, 	/* FVco 1009.290240 */
-	{ .frequency = 258249600,	.index = PLLVAL(114, 2, 2), 	}, 	/* FVco 1032.998400 */
-	{ .frequency = 264176640,	.index = PLLVAL(148, 3, 2), 	}, 	/* FVco 1056.706560 */
-	{ .frequency = 270950400,	.index = PLLVAL(120, 2, 2), 	}, 	/* FVco 1083.801600 */
-	{ .frequency = 276030720,	.index = PLLVAL(155, 3, 2), 	}, 	/* FVco 1104.122880 */
-	{ .frequency = 282240000,	.index = PLLVAL(92, 1, 2), 	}, 	/* FVco 1128.960000 */
-	{ .frequency = 289578240,	.index = PLLVAL(163, 3, 2), 	}, 	/* FVco 1158.312960 */
-	{ .frequency = 294235200,	.index = PLLVAL(131, 2, 2), 	}, 	/* FVco 1176.940800 */
-	{ .frequency = 300200727,	.index = PLLVAL(187, 9, 1), 	}, 	/* FVco 600.401454 */
-	{ .frequency = 306358690,	.index = PLLVAL(191, 9, 1), 	}, 	/* FVco 612.717380 */
-	{ .frequency = 312076800,	.index = PLLVAL(121, 5, 1), 	}, 	/* FVco 624.153600 */
-	{ .frequency = 318366720,	.index = PLLVAL(86, 3, 1), 	}, 	/* FVco 636.733440 */
-	{ .frequency = 324172800,	.index = PLLVAL(126, 5, 1), 	}, 	/* FVco 648.345600 */
-	{ .frequency = 330220800,	.index = PLLVAL(109, 4, 1), 	}, 	/* FVco 660.441600 */
-	{ .frequency = 336268800,	.index = PLLVAL(131, 5, 1), 	}, 	/* FVco 672.537600 */
-	{ .frequency = 342074880,	.index = PLLVAL(93, 3, 1), 	}, 	/* FVco 684.149760 */
-	{ .frequency = 348096000,	.index = PLLVAL(177, 7, 1), 	}, 	/* FVco 696.192000 */
-	{ .frequency = 355622400,	.index = PLLVAL(118, 4, 1), 	}, 	/* FVco 711.244800 */
-	{ .frequency = 360460800,	.index = PLLVAL(141, 5, 1), 	}, 	/* FVco 720.921600 */
-	{ .frequency = 366206400,	.index = PLLVAL(165, 6, 1), 	}, 	/* FVco 732.412800 */
-	{ .frequency = 372556800,	.index = PLLVAL(124, 4, 1), 	}, 	/* FVco 745.113600 */
-	{ .frequency = 378201600,	.index = PLLVAL(126, 4, 1), 	}, 	/* FVco 756.403200 */
-	{ .frequency = 384652800,	.index = PLLVAL(151, 5, 1), 	}, 	/* FVco 769.305600 */
-	{ .frequency = 391608000,	.index = PLLVAL(177, 6, 1), 	}, 	/* FVco 783.216000 */
-	{ .frequency = 396264960,	.index = PLLVAL(109, 3, 1), 	}, 	/* FVco 792.529920 */
-	{ .frequency = 402192000,	.index = PLLVAL(87, 2, 1), 	}, 	/* FVco 804.384000 */
-};
-
-static int s3c2440_plls169344_add(struct sys_device *dev)
-{
-	struct clk *xtal_clk;
-	unsigned long xtal;
-
-	xtal_clk = clk_get(NULL, "xtal");
-	if (IS_ERR(xtal_clk))
-		return PTR_ERR(xtal_clk);
-
-	xtal = clk_get_rate(xtal_clk);
-	clk_put(xtal_clk);
-
-	if (xtal == 169344000) {
-		printk(KERN_INFO "Using PLL table for 16.9344MHz crystal\n");
-		return s3c_plltab_register(s3c2440_plls_169344,
-					   ARRAY_SIZE(s3c2440_plls_169344));
-	}
-
-	return 0;
-}
-
-static struct sysdev_driver s3c2440_plls169344_drv = {
-	.add	= s3c2440_plls169344_add,
-};
-
-static int __init s3c2440_pll_16934400(void)
-{
-	return sysdev_driver_register(&s3c2440_sysclass,
-				      &s3c2440_plls169344_drv);
-
-}
-
-arch_initcall(s3c2440_pll_16934400);
-
-static struct sysdev_driver s3c2442_plls169344_drv = {
-	.add	= s3c2440_plls169344_add,
-};
-
-static int __init s3c2442_pll_16934400(void)
-{
-	return sysdev_driver_register(&s3c2442_sysclass,
-				      &s3c2442_plls169344_drv);
-
-}
-
-arch_initcall(s3c2442_pll_16934400);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c244x.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c244x.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c244x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c244x.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,196 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/s3c244x.c
- *
- * Copyright (c) 2004-2006 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C2440 and S3C2442 Mobile CPU support (not S3C2443)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/sysdev.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <plat/cpu-freq.h>
-
-#include <mach/regs-clock.h>
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-gpioj.h>
-#include <mach/regs-dsc.h>
-
-#include <plat/s3c2410.h>
-#include <plat/s3c2440.h>
-#include "s3c244x.h"
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/pll.h>
-
-static struct map_desc s3c244x_iodesc[] __initdata = {
-	IODESC_ENT(CLKPWR),
-	IODESC_ENT(TIMER),
-	IODESC_ENT(WATCHDOG),
-};
-
-/* uart initialisation */
-
-void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-	s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
-}
-
-void __init s3c244x_map_io(void)
-{
-	/* register our io-tables */
-
-	iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
-
-	/* rename any peripherals used differing from the s3c2410 */
-
-	s3c_device_sdi.name  = "s3c2440-sdi";
-	s3c_device_i2c0.name  = "s3c2440-i2c";
-	s3c_device_nand.name = "s3c2440-nand";
-	s3c_device_ts.name = "s3c2440-ts";
-	s3c_device_usbgadget.name = "s3c2440-usbgadget";
-}
-
-void __init_or_cpufreq s3c244x_setup_clocks(void)
-{
-	struct clk *xtal_clk;
-	unsigned long clkdiv;
-	unsigned long camdiv;
-	unsigned long xtal;
-	unsigned long hclk, fclk, pclk;
-	int hdiv = 1;
-
-	xtal_clk = clk_get(NULL, "xtal");
-	xtal = clk_get_rate(xtal_clk);
-	clk_put(xtal_clk);
-
-	fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
-
-	clkdiv = __raw_readl(S3C2410_CLKDIVN);
-	camdiv = __raw_readl(S3C2440_CAMDIVN);
-
-	/* work out clock scalings */
-
-	switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
-	case S3C2440_CLKDIVN_HDIVN_1:
-		hdiv = 1;
-		break;
-
-	case S3C2440_CLKDIVN_HDIVN_2:
-		hdiv = 2;
-		break;
-
-	case S3C2440_CLKDIVN_HDIVN_4_8:
-		hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
-		break;
-
-	case S3C2440_CLKDIVN_HDIVN_3_6:
-		hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
-		break;
-	}
-
-	hclk = fclk / hdiv;
-	pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2 : 1);
-
-	/* print brief summary of clocks, etc */
-
-	printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
-	       print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
-
-	s3c24xx_setup_clocks(fclk, hclk, pclk);
-}
-
-void __init s3c244x_init_clocks(int xtal)
-{
-	/* initialise the clocks here, to allow other things like the
-	 * console to use them, and to add new ones after the initialisation
-	 */
-
-	s3c24xx_register_baseclocks(xtal);
-	s3c244x_setup_clocks();
-	s3c2410_baseclk_add();
-}
-
-#ifdef CONFIG_PM
-
-static struct sleep_save s3c244x_sleep[] = {
-	SAVE_ITEM(S3C2440_DSC0),
-	SAVE_ITEM(S3C2440_DSC1),
-	SAVE_ITEM(S3C2440_GPJDAT),
-	SAVE_ITEM(S3C2440_GPJCON),
-	SAVE_ITEM(S3C2440_GPJUP)
-};
-
-static int s3c244x_suspend(struct sys_device *dev, pm_message_t state)
-{
-	s3c_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
-	return 0;
-}
-
-static int s3c244x_resume(struct sys_device *dev)
-{
-	s3c_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
-	return 0;
-}
-
-#else
-#define s3c244x_suspend NULL
-#define s3c244x_resume  NULL
-#endif
-
-/* Since the S3C2442 and S3C2440 share  items, put both sysclasses here */
-
-struct sysdev_class s3c2440_sysclass = {
-	.name		= "s3c2440-core",
-	.suspend	= s3c244x_suspend,
-	.resume		= s3c244x_resume
-};
-
-struct sysdev_class s3c2442_sysclass = {
-	.name		= "s3c2442-core",
-	.suspend	= s3c244x_suspend,
-	.resume		= s3c244x_resume
-};
-
-/* need to register class before we actually register the device, and
- * we also need to ensure that it has been initialised before any of the
- * drivers even try to use it (even if not on an s3c2440 based system)
- * as a driver which may support both 2410 and 2440 may try and use it.
-*/
-
-static int __init s3c2440_core_init(void)
-{
-	return sysdev_class_register(&s3c2440_sysclass);
-}
-
-core_initcall(s3c2440_core_init);
-
-static int __init s3c2442_core_init(void)
-{
-	return sysdev_class_register(&s3c2442_sysclass);
-}
-
-core_initcall(s3c2442_core_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c244x-clock.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c244x-clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c244x-clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c244x-clock.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,136 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c
- *
- * Copyright (c) 2004-2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2440/S3C2442 Common clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You 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/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/sysdev.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/atomic.h>
-#include <asm/irq.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent)
-{
-	unsigned long camdivn;
-	unsigned long dvs;
-
-	if (parent == &clk_f)
-		dvs = 0;
-	else if (parent == &clk_h)
-		dvs = S3C2440_CAMDIVN_DVSEN;
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	camdivn  = __raw_readl(S3C2440_CAMDIVN);
-	camdivn &= ~S3C2440_CAMDIVN_DVSEN;
-	camdivn |= dvs;
-	__raw_writel(camdivn, S3C2440_CAMDIVN);
-
-	return 0;
-}
-
-static struct clk clk_arm = {
-	.name		= "armclk",
-	.id		= -1,
-	.set_parent	= s3c2440_setparent_armclk,
-};
-
-static int s3c244x_clk_add(struct sys_device *sysdev)
-{
-	unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
-	unsigned long clkdivn;
-	struct clk *clock_upll;
-	int ret;
-
-	printk("S3C244X: Clock Support, DVS %s\n",
-	       (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
-
-	clk_arm.parent = (camdivn & S3C2440_CAMDIVN_DVSEN) ? &clk_h : &clk_f;
-
-	ret = s3c24xx_register_clock(&clk_arm);
-	if (ret < 0) {
-		printk(KERN_ERR "S3C24XX: Failed to add armclk (%d)\n", ret);
-		return ret;
-	}
-
-	clock_upll = clk_get(NULL, "upll");
-	if (IS_ERR(clock_upll)) {
-		printk(KERN_ERR "S3C244X: Failed to get upll clock\n");
-		return -ENOENT;
-	}
-
-	/* check rate of UPLL, and if it is near 96MHz, then change
-	 * to using half the UPLL rate for the system */
-
-	if (clk_get_rate(clock_upll) > (94 * MHZ)) {
-		clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
-
-		spin_lock(&clocks_lock);
-
-		clkdivn = __raw_readl(S3C2410_CLKDIVN);
-		clkdivn |= S3C2440_CLKDIVN_UCLK;
-		__raw_writel(clkdivn, S3C2410_CLKDIVN);
-
-		spin_unlock(&clocks_lock);
-	}
-
-	return 0;
-}
-
-static struct sysdev_driver s3c2440_clk_driver = {
-	.add		= s3c244x_clk_add,
-};
-
-static int s3c2440_clk_init(void)
-{
-	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver);
-}
-
-arch_initcall(s3c2440_clk_init);
-
-static struct sysdev_driver s3c2442_clk_driver = {
-	.add		= s3c244x_clk_add,
-};
-
-static int s3c2442_clk_init(void)
-{
-	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
-}
-
-arch_initcall(s3c2442_clk_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c244x.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c244x.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c244x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c244x.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/s3c244x.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for S3C2440 and S3C2442 cpu 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.
-*/
-
-#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
-
-extern void s3c244x_map_io(void);
-
-extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c244x_init_clocks(int xtal);
-
-#else
-#define s3c244x_init_clocks NULL
-#define s3c244x_init_uarts NULL
-#define s3c244x_map_io NULL
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c244x-irq.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c244x-irq.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c244x-irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c24xx/s3c244x-irq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,142 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/s3c244x-irq.c
- *
- * Copyright (c) 2003-2004 Simtec Electronics
- *	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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You 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/module.h>
-#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 <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/irq.h>
-
-/* camera irq */
-
-static void s3c_irq_demux_cam(unsigned int irq,
-			      struct irq_desc *desc)
-{
-	unsigned int subsrc, submsk;
-
-	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	subsrc &= ~submsk;
-	subsrc >>= 11;
-	subsrc &= 3;
-
-	if (subsrc != 0) {
-		if (subsrc & 1) {
-			generic_handle_irq(IRQ_S3C2440_CAM_C);
-		}
-		if (subsrc & 2) {
-			generic_handle_irq(IRQ_S3C2440_CAM_P);
-		}
-	}
-}
-
-#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
-
-static void
-s3c_irq_cam_mask(unsigned int irqno)
-{
-	s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
-}
-
-static void
-s3c_irq_cam_unmask(unsigned int irqno)
-{
-	s3c_irqsub_unmask(irqno, INTMSK_CAM);
-}
-
-static void
-s3c_irq_cam_ack(unsigned int irqno)
-{
-	s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
-}
-
-static struct irq_chip s3c_irq_cam = {
-	.mask	    = s3c_irq_cam_mask,
-	.unmask	    = s3c_irq_cam_unmask,
-	.ack	    = s3c_irq_cam_ack,
-};
-
-static int s3c244x_irq_add(struct sys_device *sysdev)
-{
-	unsigned int irqno;
-
-	set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
-	set_irq_handler(IRQ_NFCON, handle_level_irq);
-	set_irq_flags(IRQ_NFCON, IRQF_VALID);
-
-	/* add chained handler for camera */
-
-	set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
-	set_irq_handler(IRQ_CAM, handle_level_irq);
-	set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
-
-	for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
-		set_irq_chip(irqno, &s3c_irq_cam);
-		set_irq_handler(irqno, handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	return 0;
-}
-
-static struct sysdev_driver s3c2440_irq_driver = {
-	.add		= s3c244x_irq_add,
-	.suspend	= s3c24xx_irq_suspend,
-	.resume		= s3c24xx_irq_resume,
-};
-
-static int s3c2440_irq_init(void)
-{
-	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
-}
-
-arch_initcall(s3c2440_irq_init);
-
-static struct sysdev_driver s3c2442_irq_driver = {
-	.add		= s3c244x_irq_add,
-	.suspend	= s3c24xx_irq_suspend,
-	.resume		= s3c24xx_irq_resume,
-};
-
-
-static int s3c2442_irq_init(void)
-{
-	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_irq_driver);
-}
-
-arch_initcall(s3c2442_irq_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/clock.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/clock.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,300 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/clock.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C64XX Base clock 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/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <plat/regs-sys.h>
-#include <plat/regs-clock.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/clock.h>
-
-struct clk clk_h2 = {
-	.name		= "hclk2",
-	.id		= -1,
-	.rate		= 0,
-};
-
-struct clk clk_27m = {
-	.name		= "clk_27m",
-	.id		= -1,
-	.rate		= 27000000,
-};
-
-static int clk_48m_ctrl(struct clk *clk, int enable)
-{
-	unsigned long flags;
-	u32 val;
-
-	/* can't rely on clock lock, this register has other usages */
-	local_irq_save(flags);
-
-	val = __raw_readl(S3C64XX_OTHERS);
-	if (enable)
-		val |= S3C64XX_OTHERS_USBMASK;
-	else
-		val &= ~S3C64XX_OTHERS_USBMASK;
-
-	__raw_writel(val, S3C64XX_OTHERS);
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-struct clk clk_48m = {
-	.name		= "clk_48m",
-	.id		= -1,
-	.rate		= 48000000,
-	.enable		= clk_48m_ctrl,
-};
-
-static int inline s3c64xx_gate(void __iomem *reg,
-				struct clk *clk,
-				int enable)
-{
-	unsigned int ctrlbit = clk->ctrlbit;
-	u32 con;
-
-	con = __raw_readl(reg);
-
-	if (enable)
-		con |= ctrlbit;
-	else
-		con &= ~ctrlbit;
-
-	__raw_writel(con, reg);
-	return 0;
-}
-
-static int s3c64xx_pclk_ctrl(struct clk *clk, int enable)
-{
-	return s3c64xx_gate(S3C_PCLK_GATE, clk, enable);
-}
-
-static int s3c64xx_hclk_ctrl(struct clk *clk, int enable)
-{
-	return s3c64xx_gate(S3C_HCLK_GATE, clk, enable);
-}
-
-int s3c64xx_sclk_ctrl(struct clk *clk, int enable)
-{
-	return s3c64xx_gate(S3C_SCLK_GATE, clk, enable);
-}
-
-static struct clk init_clocks_disable[] = {
-	{
-		.name		= "nand",
-		.id		= -1,
-		.parent		= &clk_h,
-	}, {
-		.name		= "adc",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c64xx_pclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_PCLK_TSADC,
-	}, {
-		.name		= "i2c",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c64xx_pclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_PCLK_IIC,
-	}, {
-		.name		= "iis",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s3c64xx_pclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_PCLK_IIS0,
-	}, {
-		.name		= "iis",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s3c64xx_pclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_PCLK_IIS1,
-	}, {
-		.name		= "spi",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s3c64xx_pclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_PCLK_SPI0,
-	}, {
-		.name		= "spi",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s3c64xx_pclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_PCLK_SPI1,
-	}, {
-		.name		= "48m",
-		.id		= 0,
-		.parent		= &clk_48m,
-		.enable		= s3c64xx_sclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_SCLK_MMC0_48,
-	}, {
-		.name		= "48m",
-		.id		= 1,
-		.parent		= &clk_48m,
-		.enable		= s3c64xx_sclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_SCLK_MMC1_48,
-	}, {
-		.name		= "48m",
-		.id		= 2,
-		.parent		= &clk_48m,
-		.enable		= s3c64xx_sclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_SCLK_MMC2_48,
-	}, {
-		.name		= "dma0",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s3c64xx_hclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_HCLK_DMA0,
-	}, {
-		.name		= "dma1",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s3c64xx_hclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_HCLK_DMA1,
-	},
-};
-
-static struct clk init_clocks[] = {
-	{
-		.name		= "lcd",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s3c64xx_hclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_HCLK_LCD,
-	}, {
-		.name		= "gpio",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c64xx_pclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_PCLK_GPIO,
-	}, {
-		.name		= "usb-host",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s3c64xx_hclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_HCLK_UHOST,
-	}, {
-		.name		= "hsmmc",
-		.id		= 0,
-		.parent		= &clk_h,
-		.enable		= s3c64xx_hclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_HCLK_HSMMC0,
-	}, {
-		.name		= "hsmmc",
-		.id		= 1,
-		.parent		= &clk_h,
-		.enable		= s3c64xx_hclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_HCLK_HSMMC1,
-	}, {
-		.name		= "hsmmc",
-		.id		= 2,
-		.parent		= &clk_h,
-		.enable		= s3c64xx_hclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_HCLK_HSMMC2,
-	}, {
-		.name		= "timers",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c64xx_pclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_PCLK_PWM,
-	}, {
-		.name		= "uart",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s3c64xx_pclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_PCLK_UART0,
-	}, {
-		.name		= "uart",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s3c64xx_pclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_PCLK_UART1,
-	}, {
-		.name		= "uart",
-		.id		= 2,
-		.parent		= &clk_p,
-		.enable		= s3c64xx_pclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_PCLK_UART2,
-	}, {
-		.name		= "uart",
-		.id		= 3,
-		.parent		= &clk_p,
-		.enable		= s3c64xx_pclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_PCLK_UART3,
-	}, {
-		.name		= "rtc",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c64xx_pclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_PCLK_RTC,
-	}, {
-		.name		= "watchdog",
-		.id		= -1,
-		.parent		= &clk_p,
-		.ctrlbit	= S3C_CLKCON_PCLK_WDT,
-	}, {
-		.name		= "ac97",
-		.id		= -1,
-		.parent		= &clk_p,
-		.ctrlbit	= S3C_CLKCON_PCLK_AC97,
-	}
-};
-
-static struct clk *clks[] __initdata = {
-	&clk_ext,
-	&clk_epll,
-	&clk_27m,
-	&clk_48m,
-	&clk_h2,
-};
-
-void __init s3c64xx_register_clocks(void)
-{
-	struct clk *clkp;
-	int ret;
-	int ptr;
-
-	s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
-
-	clkp = init_clocks;
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-	}
-
-	clkp = init_clocks_disable;
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
-
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-
-		(clkp->enable)(clkp, 0);
-	}
-
-	s3c_pwmclk_init();
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/cpu.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/cpu.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/cpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/cpu.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,156 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/cpu.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C64XX CPU 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/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/sysdev.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <plat/regs-serial.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/clock.h>
-
-#include <plat/s3c6400.h>
-#include <plat/s3c6410.h>
-
-/* table of supported CPUs */
-
-static const char name_s3c6400[] = "S3C6400";
-static const char name_s3c6410[] = "S3C6410";
-
-static struct cpu_table cpu_ids[] __initdata = {
-	{
-		.idcode		= 0x36400000,
-		.idmask		= 0xfffff000,
-		.map_io		= s3c6400_map_io,
-		.init_clocks	= s3c6400_init_clocks,
-		.init_uarts	= s3c6400_init_uarts,
-		.init		= s3c6400_init,
-		.name		= name_s3c6400,
-	}, {
-		.idcode		= 0x36410100,
-		.idmask		= 0xffffff00,
-		.map_io		= s3c6410_map_io,
-		.init_clocks	= s3c6410_init_clocks,
-		.init_uarts	= s3c6410_init_uarts,
-		.init		= s3c6410_init,
-		.name		= name_s3c6410,
-	},
-};
-
-/* minimal IO mapping */
-
-/* see notes on uart map in arch/arm/mach-s3c6400/include/mach/debug-macro.S */
-#define UART_OFFS (S3C_PA_UART & 0xfffff)
-
-static struct map_desc s3c_iodesc[] __initdata = {
-	{
-		.virtual	= (unsigned long)S3C_VA_SYS,
-		.pfn		= __phys_to_pfn(S3C64XX_PA_SYSCON),
-		.length		= SZ_4K,
-		.type		= MT_DEVICE,
-	}, {
-		.virtual	= (unsigned long)(S3C_VA_UART + UART_OFFS),
-		.pfn		= __phys_to_pfn(S3C_PA_UART),
-		.length		= SZ_4K,
-		.type		= MT_DEVICE,
-	}, {
-		.virtual	= (unsigned long)S3C_VA_VIC0,
-		.pfn		= __phys_to_pfn(S3C64XX_PA_VIC0),
-		.length		= SZ_16K,
-		.type		= MT_DEVICE,
-	}, {
-		.virtual	= (unsigned long)S3C_VA_VIC1,
-		.pfn		= __phys_to_pfn(S3C64XX_PA_VIC1),
-		.length		= SZ_16K,
-		.type		= MT_DEVICE,
-	}, {
-		.virtual	= (unsigned long)S3C_VA_TIMER,
-		.pfn		= __phys_to_pfn(S3C_PA_TIMER),
-		.length		= SZ_16K,
-		.type		= MT_DEVICE,
-	}, {
-		.virtual	= (unsigned long)S3C64XX_VA_GPIO,
-		.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,
-	}, {
-		.virtual	= (unsigned long)S3C_VA_WATCHDOG,
-		.pfn		= __phys_to_pfn(S3C64XX_PA_WATCHDOG),
-		.length		= SZ_4K,
-		.type		= MT_DEVICE,
-	}, {
-		.virtual	= (unsigned long)S3C_VA_USB_HSPHY,
-		.pfn		= __phys_to_pfn(S3C64XX_PA_USB_HSPHY),
-		.length		= SZ_1K,
-		.type		= MT_DEVICE,
-	},
-};
-
-
-struct sysdev_class s3c64xx_sysclass = {
-	.name	= "s3c64xx-core",
-};
-
-static struct sys_device s3c64xx_sysdev = {
-	.cls	= &s3c64xx_sysclass,
-};
-
-
-/* read cpu identification code */
-
-void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
-{
-	unsigned long idcode;
-
-	/* initialise the io descriptors we need for initialisation */
-	iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
-	iotable_init(mach_desc, size);
-
-	idcode = __raw_readl(S3C_VA_SYS + 0x118);
-	if (!idcode) {
-		/* S3C6400 has the ID register in a different place,
-		 * and needs a write before it can be read. */
-
-		__raw_writel(0x0, S3C_VA_SYS + 0xA1C);
-		idcode = __raw_readl(S3C_VA_SYS + 0xA1C);
-	}
-
-	s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
-}
-
-static __init int s3c64xx_sysdev_init(void)
-{
-	sysdev_class_register(&s3c64xx_sysclass);
-	return sysdev_register(&s3c64xx_sysdev);
-}
-
-core_initcall(s3c64xx_sysdev_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/cpufreq.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/cpufreq.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/cpufreq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/cpufreq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,270 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/cpufreq.c
- *
- * Copyright 2009 Wolfson Microelectronics plc
- *
- * S3C64xx CPUfreq Support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/regulator/consumer.h>
-
-static struct clk *armclk;
-static struct regulator *vddarm;
-static unsigned long regulator_latency;
-
-#ifdef CONFIG_CPU_S3C6410
-struct s3c64xx_dvfs {
-	unsigned int vddarm_min;
-	unsigned int vddarm_max;
-};
-
-static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = {
-	[0] = { 1000000, 1150000 },
-	[1] = { 1050000, 1150000 },
-	[2] = { 1100000, 1150000 },
-	[3] = { 1200000, 1350000 },
-};
-
-static struct cpufreq_frequency_table s3c64xx_freq_table[] = {
-	{ 0,  66000 },
-	{ 0, 133000 },
-	{ 1, 222000 },
-	{ 1, 266000 },
-	{ 2, 333000 },
-	{ 2, 400000 },
-	{ 2, 532000 },
-	{ 2, 533000 },
-	{ 3, 667000 },
-	{ 0, CPUFREQ_TABLE_END },
-};
-#endif
-
-static int s3c64xx_cpufreq_verify_speed(struct cpufreq_policy *policy)
-{
-	if (policy->cpu != 0)
-		return -EINVAL;
-
-	return cpufreq_frequency_table_verify(policy, s3c64xx_freq_table);
-}
-
-static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu)
-{
-	if (cpu != 0)
-		return 0;
-
-	return clk_get_rate(armclk) / 1000;
-}
-
-static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
-				      unsigned int target_freq,
-				      unsigned int relation)
-{
-	int ret;
-	unsigned int i;
-	struct cpufreq_freqs freqs;
-	struct s3c64xx_dvfs *dvfs;
-
-	ret = cpufreq_frequency_table_target(policy, s3c64xx_freq_table,
-					     target_freq, relation, &i);
-	if (ret != 0)
-		return ret;
-
-	freqs.cpu = 0;
-	freqs.old = clk_get_rate(armclk) / 1000;
-	freqs.new = s3c64xx_freq_table[i].frequency;
-	freqs.flags = 0;
-	dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[i].index];
-
-	if (freqs.old == freqs.new)
-		return 0;
-
-	pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new);
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
-#ifdef CONFIG_REGULATOR
-	if (vddarm && freqs.new > freqs.old) {
-		ret = regulator_set_voltage(vddarm,
-					    dvfs->vddarm_min,
-					    dvfs->vddarm_max);
-		if (ret != 0) {
-			pr_err("cpufreq: Failed to set VDDARM for %dkHz: %d\n",
-			       freqs.new, ret);
-			goto err;
-		}
-	}
-#endif
-
-	ret = clk_set_rate(armclk, freqs.new * 1000);
-	if (ret < 0) {
-		pr_err("cpufreq: Failed to set rate %dkHz: %d\n",
-		       freqs.new, ret);
-		goto err;
-	}
-
-#ifdef CONFIG_REGULATOR
-	if (vddarm && freqs.new < freqs.old) {
-		ret = regulator_set_voltage(vddarm,
-					    dvfs->vddarm_min,
-					    dvfs->vddarm_max);
-		if (ret != 0) {
-			pr_err("cpufreq: Failed to set VDDARM for %dkHz: %d\n",
-			       freqs.new, ret);
-			goto err_clk;
-		}
-	}
-#endif
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
-	pr_debug("cpufreq: Set actual frequency %lukHz\n",
-		 clk_get_rate(armclk) / 1000);
-
-	return 0;
-
-err_clk:
-	if (clk_set_rate(armclk, freqs.old * 1000) < 0)
-		pr_err("Failed to restore original clock rate\n");
-err:
-	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
-	return ret;
-}
-
-#ifdef CONFIG_REGULATOR
-static void __init s3c64xx_cpufreq_config_regulator(void)
-{
-	int count, v, i, found;
-	struct cpufreq_frequency_table *freq;
-	struct s3c64xx_dvfs *dvfs;
-
-	count = regulator_count_voltages(vddarm);
-	if (count < 0) {
-		pr_err("cpufreq: Unable to check supported voltages\n");
-	}
-
-	freq = s3c64xx_freq_table;
-	while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) {
-		if (freq->frequency == CPUFREQ_ENTRY_INVALID)
-			continue;
-
-		dvfs = &s3c64xx_dvfs_table[freq->index];
-		found = 0;
-
-		for (i = 0; i < count; i++) {
-			v = regulator_list_voltage(vddarm, i);
-			if (v >= dvfs->vddarm_min && v <= dvfs->vddarm_max)
-				found = 1;
-		}
-
-		if (!found) {
-			pr_debug("cpufreq: %dkHz unsupported by regulator\n",
-				 freq->frequency);
-			freq->frequency = CPUFREQ_ENTRY_INVALID;
-		}
-
-		freq++;
-	}
-
-	/* Guess based on having to do an I2C/SPI write; in future we
-	 * will be able to query the regulator performance here. */
-	regulator_latency = 1 * 1000 * 1000;
-}
-#endif
-
-static int __init s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
-{
-	int ret;
-	struct cpufreq_frequency_table *freq;
-
-	if (policy->cpu != 0)
-		return -EINVAL;
-
-	if (s3c64xx_freq_table == NULL) {
-		pr_err("cpufreq: No frequency information for this CPU\n");
-		return -ENODEV;
-	}
-
-	armclk = clk_get(NULL, "armclk");
-	if (IS_ERR(armclk)) {
-		pr_err("cpufreq: Unable to obtain ARMCLK: %ld\n",
-		       PTR_ERR(armclk));
-		return PTR_ERR(armclk);
-	}
-
-#ifdef CONFIG_REGULATOR
-	vddarm = regulator_get(NULL, "vddarm");
-	if (IS_ERR(vddarm)) {
-		ret = PTR_ERR(vddarm);
-		pr_err("cpufreq: Failed to obtain VDDARM: %d\n", ret);
-		pr_err("cpufreq: Only frequency scaling available\n");
-		vddarm = NULL;
-	} else {
-		s3c64xx_cpufreq_config_regulator();
-	}
-#endif
-
-	freq = s3c64xx_freq_table;
-	while (freq->frequency != CPUFREQ_TABLE_END) {
-		unsigned long r;
-
-		/* Check for frequencies we can generate */
-		r = clk_round_rate(armclk, freq->frequency * 1000);
-		r /= 1000;
-		if (r != freq->frequency) {
-			pr_debug("cpufreq: %dkHz unsupported by clock\n",
-				 freq->frequency);
-			freq->frequency = CPUFREQ_ENTRY_INVALID;
-		}
-
-		/* If we have no regulator then assume startup
-		 * frequency is the maximum we can support. */
-		if (!vddarm && freq->frequency > s3c64xx_cpufreq_get_speed(0))
-			freq->frequency = CPUFREQ_ENTRY_INVALID;
-
-		freq++;
-	}
-
-	policy->cur = clk_get_rate(armclk) / 1000;
-
-	/* Datasheet says PLL stabalisation time (if we were to use
-	 * the PLLs, which we don't currently) is ~300us worst case,
-	 * but add some fudge.
-	 */
-	policy->cpuinfo.transition_latency = (500 * 1000) + regulator_latency;
-
-	ret = cpufreq_frequency_table_cpuinfo(policy, s3c64xx_freq_table);
-	if (ret != 0) {
-		pr_err("cpufreq: Failed to configure frequency table: %d\n",
-		       ret);
-		regulator_put(vddarm);
-		clk_put(armclk);
-	}
-
-	return ret;
-}
-
-static struct cpufreq_driver s3c64xx_cpufreq_driver = {
-	.owner		= THIS_MODULE,
-	.flags          = 0,
-	.verify		= s3c64xx_cpufreq_verify_speed,
-	.target		= s3c64xx_cpufreq_set_target,
-	.get		= s3c64xx_cpufreq_get_speed,
-	.init		= s3c64xx_cpufreq_driver_init,
-	.name		= "s3c",
-};
-
-static int __init s3c64xx_cpufreq_init(void)
-{
-	return cpufreq_register_driver(&s3c64xx_cpufreq_driver);
-}
-module_init(s3c64xx_cpufreq_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/dev-audio.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/dev-audio.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/dev-audio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/dev-audio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,167 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-audio.c
- *
- * Copyright 2009 Wolfson Microelectronics
- *      Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
-
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-#include <mach/dma.h>
-#include <mach/gpio.h>
-
-#include <plat/devs.h>
-#include <plat/audio.h>
-#include <plat/gpio-bank-d.h>
-#include <plat/gpio-bank-e.h>
-#include <plat/gpio-cfg.h>
-
-static struct resource s3c64xx_iis0_resource[] = {
-	[0] = {
-		.start = S3C64XX_PA_IIS0,
-		.end   = S3C64XX_PA_IIS0 + 0x100 - 1,
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-struct platform_device s3c64xx_device_iis0 = {
-	.name		  = "s3c64xx-iis",
-	.id		  = 0,
-	.num_resources	  = ARRAY_SIZE(s3c64xx_iis0_resource),
-	.resource	  = s3c64xx_iis0_resource,
-};
-EXPORT_SYMBOL(s3c64xx_device_iis0);
-
-static struct resource s3c64xx_iis1_resource[] = {
-	[0] = {
-		.start = S3C64XX_PA_IIS1,
-		.end   = S3C64XX_PA_IIS1 + 0x100 - 1,
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-struct platform_device s3c64xx_device_iis1 = {
-	.name		  = "s3c64xx-iis",
-	.id		  = 1,
-	.num_resources	  = ARRAY_SIZE(s3c64xx_iis1_resource),
-	.resource	  = s3c64xx_iis1_resource,
-};
-EXPORT_SYMBOL(s3c64xx_device_iis1);
-
-static struct resource s3c64xx_iisv4_resource[] = {
-	[0] = {
-		.start = S3C64XX_PA_IISV4,
-		.end   = S3C64XX_PA_IISV4 + 0x100 - 1,
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-struct platform_device s3c64xx_device_iisv4 = {
-	.name		  = "s3c64xx-iis-v4",
-	.id		  = -1,
-	.num_resources	  = ARRAY_SIZE(s3c64xx_iisv4_resource),
-	.resource	  = s3c64xx_iisv4_resource,
-};
-EXPORT_SYMBOL(s3c64xx_device_iisv4);
-
-
-/* PCM Controller platform_devices */
-
-static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
-{
-	switch (pdev->id) {
-	case 0:
-		s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_PCM0_SCLK);
-		s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_PCM0_EXTCLK);
-		s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_PCM0_FSYNC);
-		s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_PCM0_SIN);
-		s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_PCM0_SOUT);
-		break;
-	case 1:
-		s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_PCM1_SCLK);
-		s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_PCM1_EXTCLK);
-		s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_PCM1_FSYNC);
-		s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_PCM1_SIN);
-		s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_PCM1_SOUT);
-		break;
-	default:
-		printk(KERN_DEBUG "Invalid PCM Controller number!");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static struct resource s3c64xx_pcm0_resource[] = {
-	[0] = {
-		.start = S3C64XX_PA_PCM0,
-		.end   = S3C64XX_PA_PCM0 + 0x100 - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = DMACH_PCM0_TX,
-		.end   = DMACH_PCM0_TX,
-		.flags = IORESOURCE_DMA,
-	},
-	[2] = {
-		.start = DMACH_PCM0_RX,
-		.end   = DMACH_PCM0_RX,
-		.flags = IORESOURCE_DMA,
-	},
-};
-
-static struct s3c_audio_pdata s3c_pcm0_pdata = {
-	.cfg_gpio = s3c64xx_pcm_cfg_gpio,
-};
-
-struct platform_device s3c64xx_device_pcm0 = {
-	.name		  = "samsung-pcm",
-	.id		  = 0,
-	.num_resources	  = ARRAY_SIZE(s3c64xx_pcm0_resource),
-	.resource	  = s3c64xx_pcm0_resource,
-	.dev = {
-		.platform_data = &s3c_pcm0_pdata,
-	},
-};
-EXPORT_SYMBOL(s3c64xx_device_pcm0);
-
-static struct resource s3c64xx_pcm1_resource[] = {
-	[0] = {
-		.start = S3C64XX_PA_PCM1,
-		.end   = S3C64XX_PA_PCM1 + 0x100 - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = DMACH_PCM1_TX,
-		.end   = DMACH_PCM1_TX,
-		.flags = IORESOURCE_DMA,
-	},
-	[2] = {
-		.start = DMACH_PCM1_RX,
-		.end   = DMACH_PCM1_RX,
-		.flags = IORESOURCE_DMA,
-	},
-};
-
-static struct s3c_audio_pdata s3c_pcm1_pdata = {
-	.cfg_gpio = s3c64xx_pcm_cfg_gpio,
-};
-
-struct platform_device s3c64xx_device_pcm1 = {
-	.name		  = "samsung-pcm",
-	.id		  = 1,
-	.num_resources	  = ARRAY_SIZE(s3c64xx_pcm1_resource),
-	.resource	  = s3c64xx_pcm1_resource,
-	.dev = {
-		.platform_data = &s3c_pcm1_pdata,
-	},
-};
-EXPORT_SYMBOL(s3c64xx_device_pcm1);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/dev-uart.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/dev-uart.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/dev-uart.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/dev-uart.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,176 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/dev-uart.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * Base S3C64XX UART resource and device definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/irq.h>
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-
-/* Serial port registrations */
-
-/* 64xx uarts are closer together */
-
-static struct resource s3c64xx_uart0_resource[] = {
-	[0] = {
-		.start	= S3C_PA_UART0,
-		.end	= S3C_PA_UART0 + 0x100,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_S3CUART_RX0,
-		.end	= IRQ_S3CUART_RX0,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		.start	= IRQ_S3CUART_TX0,
-		.end	= IRQ_S3CUART_TX0,
-		.flags	= IORESOURCE_IRQ,
-
-	},
-	[3] = {
-		.start	= IRQ_S3CUART_ERR0,
-		.end	= IRQ_S3CUART_ERR0,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-static struct resource s3c64xx_uart1_resource[] = {
-	[0] = {
-		.start = S3C_PA_UART1,
-		.end   = S3C_PA_UART1 + 0x100,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_S3CUART_RX1,
-		.end	= IRQ_S3CUART_RX1,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		.start	= IRQ_S3CUART_TX1,
-		.end	= IRQ_S3CUART_TX1,
-		.flags	= IORESOURCE_IRQ,
-
-	},
-	[3] = {
-		.start	= IRQ_S3CUART_ERR1,
-		.end	= IRQ_S3CUART_ERR1,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct resource s3c6xx_uart2_resource[] = {
-	[0] = {
-		.start = S3C_PA_UART2,
-		.end   = S3C_PA_UART2 + 0x100,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_S3CUART_RX2,
-		.end	= IRQ_S3CUART_RX2,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		.start	= IRQ_S3CUART_TX2,
-		.end	= IRQ_S3CUART_TX2,
-		.flags	= IORESOURCE_IRQ,
-
-	},
-	[3] = {
-		.start	= IRQ_S3CUART_ERR2,
-		.end	= IRQ_S3CUART_ERR2,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct resource s3c64xx_uart3_resource[] = {
-	[0] = {
-		.start = S3C_PA_UART3,
-		.end   = S3C_PA_UART3 + 0x100,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_S3CUART_RX3,
-		.end	= IRQ_S3CUART_RX3,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		.start	= IRQ_S3CUART_TX3,
-		.end	= IRQ_S3CUART_TX3,
-		.flags	= IORESOURCE_IRQ,
-
-	},
-	[3] = {
-		.start	= IRQ_S3CUART_ERR3,
-		.end	= IRQ_S3CUART_ERR3,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-
-struct s3c24xx_uart_resources s3c64xx_uart_resources[] __initdata = {
-	[0] = {
-		.resources	= s3c64xx_uart0_resource,
-		.nr_resources	= ARRAY_SIZE(s3c64xx_uart0_resource),
-	},
-	[1] = {
-		.resources	= s3c64xx_uart1_resource,
-		.nr_resources	= ARRAY_SIZE(s3c64xx_uart1_resource),
-	},
-	[2] = {
-		.resources	= s3c6xx_uart2_resource,
-		.nr_resources	= ARRAY_SIZE(s3c6xx_uart2_resource),
-	},
-	[3] = {
-		.resources	= s3c64xx_uart3_resource,
-		.nr_resources	= ARRAY_SIZE(s3c64xx_uart3_resource),
-	},
-};
-
-/* uart devices */
-
-static struct platform_device s3c24xx_uart_device0 = {
-	.id		= 0,
-};
-
-static struct platform_device s3c24xx_uart_device1 = {
-	.id		= 1,
-};
-
-static struct platform_device s3c24xx_uart_device2 = {
-	.id		= 2,
-};
-
-static struct platform_device s3c24xx_uart_device3 = {
-	.id		= 3,
-};
-
-struct platform_device *s3c24xx_uart_src[4] = {
-	&s3c24xx_uart_device0,
-	&s3c24xx_uart_device1,
-	&s3c24xx_uart_device2,
-	&s3c24xx_uart_device3,
-};
-
-struct platform_device *s3c24xx_uart_devs[4] = {
-};
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/dma.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/dma.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,750 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/dma.c
- *
- * Copyright 2009 Openmoko, Inc.
- * Copyright 2009 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C64XX DMA core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/dmapool.h>
-#include <linux/sysdev.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <mach/dma.h>
-#include <mach/map.h>
-#include <mach/irqs.h>
-
-#include <plat/dma-plat.h>
-#include <plat/regs-sys.h>
-
-#include <asm/hardware/pl080.h>
-
-/* dma channel state information */
-
-struct s3c64xx_dmac {
-	struct sys_device	 sysdev;
-	struct clk		*clk;
-	void __iomem		*regs;
-	struct s3c2410_dma_chan *channels;
-	enum dma_ch		 chanbase;
-};
-
-/* pool to provide LLI buffers */
-static struct dma_pool *dma_pool;
-
-/* Debug configuration and code */
-
-static unsigned char debug_show_buffs = 0;
-
-static void dbg_showchan(struct s3c2410_dma_chan *chan)
-{
-	pr_debug("DMA%d: %08x->%08x L %08x C %08x,%08x S %08x\n",
-		 chan->number,
-		 readl(chan->regs + PL080_CH_SRC_ADDR),
-		 readl(chan->regs + PL080_CH_DST_ADDR),
-		 readl(chan->regs + PL080_CH_LLI),
-		 readl(chan->regs + PL080_CH_CONTROL),
-		 readl(chan->regs + PL080S_CH_CONTROL2),
-		 readl(chan->regs + PL080S_CH_CONFIG));
-}
-
-static void show_lli(struct pl080s_lli *lli)
-{
-	pr_debug("LLI[%p] %08x->%08x, NL %08x C %08x,%08x\n",
-		 lli, lli->src_addr, lli->dst_addr, lli->next_lli,
-		 lli->control0, lli->control1);
-}
-
-static void dbg_showbuffs(struct s3c2410_dma_chan *chan)
-{
-	struct s3c64xx_dma_buff *ptr;
-	struct s3c64xx_dma_buff *end;
-
-	pr_debug("DMA%d: buffs next %p, curr %p, end %p\n",
-		 chan->number, chan->next, chan->curr, chan->end);
-
-	ptr = chan->next;
-	end = chan->end;
-
-	if (debug_show_buffs) {
-		for (; ptr != NULL; ptr = ptr->next) {
-			pr_debug("DMA%d: %08x ",
-				 chan->number, ptr->lli_dma);
-			show_lli(ptr->lli);
-		}
-	}
-}
-
-/* End of Debug */
-
-static struct s3c2410_dma_chan *s3c64xx_dma_map_channel(unsigned int channel)
-{
-	struct s3c2410_dma_chan *chan;
-	unsigned int start, offs;
-
-	start = 0;
-
-	if (channel >= DMACH_PCM1_TX)
-		start = 8;
-
-	for (offs = 0; offs < 8; offs++) {
-		chan = &s3c2410_chans[start + offs];
-		if (!chan->in_use)
-			goto found;
-	}
-
-	return NULL;
-
-found:
-	s3c_dma_chan_map[channel] = chan;
-	return chan;
-}
-
-int s3c2410_dma_config(unsigned int channel, int xferunit)
-{
-	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
-	if (chan == NULL)
-		return -EINVAL;
-
-	switch (xferunit) {
-	case 1:
-		chan->hw_width = 0;
-		break;
-	case 2:
-		chan->hw_width = 1;
-		break;
-	case 4:
-		chan->hw_width = 2;
-		break;
-	default:
-		printk(KERN_ERR "%s: illegal width %d\n", __func__, xferunit);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_config);
-
-static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
-				 struct pl080s_lli *lli,
-				 dma_addr_t data, int size)
-{
-	dma_addr_t src, dst;
-	u32 control0, control1;
-
-	switch (chan->source) {
-	case S3C2410_DMASRC_HW:
-		src = chan->dev_addr;
-		dst = data;
-		control0 = PL080_CONTROL_SRC_AHB2;
-		control0 |= PL080_CONTROL_DST_INCR;
-		break;
-
-	case S3C2410_DMASRC_MEM:
-		src = data;
-		dst = chan->dev_addr;
-		control0 = PL080_CONTROL_DST_AHB2;
-		control0 |= PL080_CONTROL_SRC_INCR;
-		break;
-	default:
-		BUG();
-	}
-
-	/* note, we do not currently setup any of the burst controls */
-
-	control1 = size >> chan->hw_width;	/* size in no of xfers */
-	control0 |= PL080_CONTROL_PROT_SYS;	/* always in priv. mode */
-	control0 |= PL080_CONTROL_TC_IRQ_EN;	/* always fire IRQ */
-	control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT;
-	control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT;
-
-	lli->src_addr = src;
-	lli->dst_addr = dst;
-	lli->next_lli = 0;
-	lli->control0 = control0;
-	lli->control1 = control1;
-}
-
-static void s3c64xx_lli_to_regs(struct s3c2410_dma_chan *chan,
-				struct pl080s_lli *lli)
-{
-	void __iomem *regs = chan->regs;
-
-	pr_debug("%s: LLI %p => regs\n", __func__, lli);
-	show_lli(lli);
-
-	writel(lli->src_addr, regs + PL080_CH_SRC_ADDR);
-	writel(lli->dst_addr, regs + PL080_CH_DST_ADDR);
-	writel(lli->next_lli, regs + PL080_CH_LLI);
-	writel(lli->control0, regs + PL080_CH_CONTROL);
-	writel(lli->control1, regs + PL080S_CH_CONTROL2);
-}
-
-static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan)
-{
-	struct s3c64xx_dmac *dmac = chan->dmac;
-	u32 config;
-	u32 bit = chan->bit;
-
-	dbg_showchan(chan);
-
-	pr_debug("%s: clearing interrupts\n", __func__);
-
-	/* clear interrupts */
-	writel(bit, dmac->regs + PL080_TC_CLEAR);
-	writel(bit, dmac->regs + PL080_ERR_CLEAR);
-
-	pr_debug("%s: starting channel\n", __func__);
-
-	config = readl(chan->regs + PL080S_CH_CONFIG);
-	config |= PL080_CONFIG_ENABLE;
-
-	pr_debug("%s: writing config %08x\n", __func__, config);
-	writel(config, chan->regs + PL080S_CH_CONFIG);
-
-	return 0;
-}
-
-static int s3c64xx_dma_stop(struct s3c2410_dma_chan *chan)
-{
-	u32 config;
-	int timeout;
-
-	pr_debug("%s: stopping channel\n", __func__);
-
-	dbg_showchan(chan);
-
-	config = readl(chan->regs + PL080S_CH_CONFIG);
-	config |= PL080_CONFIG_HALT;
-	writel(config, chan->regs + PL080S_CH_CONFIG);
-
-	timeout = 1000;
-	do {
-		config = readl(chan->regs + PL080S_CH_CONFIG);
-		pr_debug("%s: %d - config %08x\n", __func__, timeout, config);
-		if (config & PL080_CONFIG_ACTIVE)
-			udelay(10);
-		else
-			break;
-		} while (--timeout > 0);
-
-	if (config & PL080_CONFIG_ACTIVE) {
-		printk(KERN_ERR "%s: channel still active\n", __func__);
-		return -EFAULT;
-	}
-
-	config = readl(chan->regs + PL080S_CH_CONFIG);
-	config &= ~PL080_CONFIG_ENABLE;
-	writel(config, chan->regs + PL080S_CH_CONFIG);
-
-	return 0;
-}
-
-static inline void s3c64xx_dma_bufffdone(struct s3c2410_dma_chan *chan,
-					 struct s3c64xx_dma_buff *buf,
-					 enum s3c2410_dma_buffresult result)
-{
-	if (chan->callback_fn != NULL)
-		(chan->callback_fn)(chan, buf->pw, 0, result);
-}
-
-static void s3c64xx_dma_freebuff(struct s3c64xx_dma_buff *buff)
-{
-	dma_pool_free(dma_pool, buff->lli, buff->lli_dma);
-	kfree(buff);
-}
-
-static int s3c64xx_dma_flush(struct s3c2410_dma_chan *chan)
-{
-	struct s3c64xx_dma_buff *buff, *next;
-	u32 config;
-
-	dbg_showchan(chan);
-
-	pr_debug("%s: flushing channel\n", __func__);
-
-	config = readl(chan->regs + PL080S_CH_CONFIG);
-	config &= ~PL080_CONFIG_ENABLE;
-	writel(config, chan->regs + PL080S_CH_CONFIG);
-
-	/* dump all the buffers associated with this channel */
-
-	for (buff = chan->curr; buff != NULL; buff = next) {
-		next = buff->next;
-		pr_debug("%s: buff %p (next %p)\n", __func__, buff, buff->next);
-
-		s3c64xx_dma_bufffdone(chan, buff, S3C2410_RES_ABORT);
-		s3c64xx_dma_freebuff(buff);
-	}
-
-	chan->curr = chan->next = chan->end = NULL;
-
-	return 0;
-}
-
-int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op)
-{
-	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
-	WARN_ON(!chan);
-	if (!chan)
-		return -EINVAL;
-
-	switch (op) {
-	case S3C2410_DMAOP_START:
-		return s3c64xx_dma_start(chan);
-
-	case S3C2410_DMAOP_STOP:
-		return s3c64xx_dma_stop(chan);
-
-	case S3C2410_DMAOP_FLUSH:
-		return s3c64xx_dma_flush(chan);
-
-	/* belive PAUSE/RESUME are no-ops */
-	case S3C2410_DMAOP_PAUSE:
-	case S3C2410_DMAOP_RESUME:
-	case S3C2410_DMAOP_STARTED:
-	case S3C2410_DMAOP_TIMEOUT:
-		return 0;
-	}
-
-	return -ENOENT;
-}
-EXPORT_SYMBOL(s3c2410_dma_ctrl);
-
-/* s3c2410_dma_enque
- *
- */
-
-int s3c2410_dma_enqueue(unsigned int channel, void *id,
-			dma_addr_t data, int size)
-{
-	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-	struct s3c64xx_dma_buff *next;
-	struct s3c64xx_dma_buff *buff;
-	struct pl080s_lli *lli;
-	unsigned long flags;
-	int ret;
-
-	WARN_ON(!chan);
-	if (!chan)
-		return -EINVAL;
-
-	buff = kzalloc(sizeof(struct s3c64xx_dma_buff), GFP_ATOMIC);
-	if (!buff) {
-		printk(KERN_ERR "%s: no memory for buffer\n", __func__);
-		return -ENOMEM;
-	}
-
-	lli = dma_pool_alloc(dma_pool, GFP_ATOMIC, &buff->lli_dma);
-	if (!lli) {
-		printk(KERN_ERR "%s: no memory for lli\n", __func__);
-		ret = -ENOMEM;
-		goto err_buff;
-	}
-
-	pr_debug("%s: buff %p, dp %08x lli (%p, %08x) %d\n",
-		 __func__, buff, data, lli, (u32)buff->lli_dma, size);
-
-	buff->lli = lli;
-	buff->pw = id;
-
-	s3c64xx_dma_fill_lli(chan, lli, data, size);
-
-	local_irq_save(flags);
-
-	if ((next = chan->next) != NULL) {
-		struct s3c64xx_dma_buff *end = chan->end;
-		struct pl080s_lli *endlli = end->lli;
-
-		pr_debug("enquing onto channel\n");
-
-		end->next = buff;
-		endlli->next_lli = buff->lli_dma;
-
-		if (chan->flags & S3C2410_DMAF_CIRCULAR) {
-			struct s3c64xx_dma_buff *curr = chan->curr;
-			lli->next_lli = curr->lli_dma;
-		}
-
-		if (next == chan->curr) {
-			writel(buff->lli_dma, chan->regs + PL080_CH_LLI);
-			chan->next = buff;
-		}
-
-		show_lli(endlli);
-		chan->end = buff;
-	} else {
-		pr_debug("enquing onto empty channel\n");
-
-		chan->curr = buff;
-		chan->next = buff;
-		chan->end = buff;
-
-		s3c64xx_lli_to_regs(chan, lli);
-	}
-
-	local_irq_restore(flags);
-
-	show_lli(lli);
-
-	dbg_showchan(chan);
-	dbg_showbuffs(chan);
-	return 0;
-
-err_buff:
-	kfree(buff);
-	return ret;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_enqueue);
-
-
-int s3c2410_dma_devconfig(int channel,
-			  enum s3c2410_dmasrc source,
-			  unsigned long devaddr)
-{
-	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-	u32 peripheral;
-	u32 config = 0;
-
-	pr_debug("%s: channel %d, source %d, dev %08lx, chan %p\n",
-		 __func__, channel, source, devaddr, chan);
-
-	WARN_ON(!chan);
-	if (!chan)
-		return -EINVAL;
-
-	peripheral = (chan->peripheral & 0xf);
-	chan->source = source;
-	chan->dev_addr = devaddr;
-
-	pr_debug("%s: peripheral %d\n", __func__, peripheral);
-
-	switch (source) {
-	case S3C2410_DMASRC_HW:
-		config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
-		config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT;
-		break;
-	case S3C2410_DMASRC_MEM:
-		config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
-		config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT;
-		break;
-	default:
-		printk(KERN_ERR "%s: bad source\n", __func__);
-		return -EINVAL;
-	}
-
-	/* allow TC and ERR interrupts */
-	config |= PL080_CONFIG_TC_IRQ_MASK;
-	config |= PL080_CONFIG_ERR_IRQ_MASK;
-
-	pr_debug("%s: config %08x\n", __func__, config);
-
-	writel(config, chan->regs + PL080S_CH_CONFIG);
-
-	return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_devconfig);
-
-
-int s3c2410_dma_getposition(unsigned int channel,
-			    dma_addr_t *src, dma_addr_t *dst)
-{
-	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
-	WARN_ON(!chan);
-	if (!chan)
-		return -EINVAL;
-
-	if (src != NULL)
-		*src = readl(chan->regs + PL080_CH_SRC_ADDR);
-
-	if (dst != NULL)
-		*dst = readl(chan->regs + PL080_CH_DST_ADDR);
-
-	return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_getposition);
-
-/* s3c2410_request_dma
- *
- * get control of an dma channel
-*/
-
-int s3c2410_dma_request(unsigned int channel,
-			struct s3c2410_dma_client *client,
-			void *dev)
-{
-	struct s3c2410_dma_chan *chan;
-	unsigned long flags;
-
-	pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
-		 channel, client->name, dev);
-
-	local_irq_save(flags);
-
-	chan = s3c64xx_dma_map_channel(channel);
-	if (chan == NULL) {
-		local_irq_restore(flags);
-		return -EBUSY;
-	}
-
-	dbg_showchan(chan);
-
-	chan->client = client;
-	chan->in_use = 1;
-	chan->peripheral = channel;
-
-	local_irq_restore(flags);
-
-	/* need to setup */
-
-	pr_debug("%s: channel initialised, %p\n", __func__, chan);
-
-	return chan->number | DMACH_LOW_LEVEL;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_request);
-
-/* s3c2410_dma_free
- *
- * release the given channel back to the system, will stop and flush
- * any outstanding transfers, and ensure the channel is ready for the
- * next claimant.
- *
- * Note, although a warning is currently printed if the freeing client
- * info is not the same as the registrant's client info, the free is still
- * allowed to go through.
-*/
-
-int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
-{
-	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-	unsigned long flags;
-
-	if (chan == NULL)
-		return -EINVAL;
-
-	local_irq_save(flags);
-
-	if (chan->client != client) {
-		printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
-		       channel, chan->client, client);
-	}
-
-	/* sort out stopping and freeing the channel */
-
-
-	chan->client = NULL;
-	chan->in_use = 0;
-
-	if (!(channel & DMACH_LOW_LEVEL))
-		s3c_dma_chan_map[channel] = NULL;
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_free);
-
-static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
-{
-	struct s3c64xx_dmac *dmac = pw;
-	struct s3c2410_dma_chan *chan;
-	enum s3c2410_dma_buffresult res;
-	u32 tcstat, errstat;
-	u32 bit;
-	int offs;
-
-	tcstat = readl(dmac->regs + PL080_TC_STATUS);
-	errstat = readl(dmac->regs + PL080_ERR_STATUS);
-
-	for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) {
-		struct s3c64xx_dma_buff *buff;
-
-		if (!(errstat & bit) && !(tcstat & bit))
-			continue;
-
-		chan = dmac->channels + offs;
-		res = S3C2410_RES_ERR;
-
-		if (tcstat & bit) {
-			writel(bit, dmac->regs + PL080_TC_CLEAR);
-			res = S3C2410_RES_OK;
-		}
-
-		if (errstat & bit)
-			writel(bit, dmac->regs + PL080_ERR_CLEAR);
-
-		/* 'next' points to the buffer that is next to the
-		 * currently active buffer.
-		 * For CIRCULAR queues, 'next' will be same as 'curr'
-		 * when 'end' is the active buffer.
-		 */
-		buff = chan->curr;
-		while (buff && buff != chan->next
-				&& buff->next != chan->next)
-			buff = buff->next;
-
-		if (!buff)
-			BUG();
-
-		if (buff == chan->next)
-			buff = chan->end;
-
-		s3c64xx_dma_bufffdone(chan, buff, res);
-
-		/* Free the node and update curr, if non-circular queue */
-		if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) {
-			chan->curr = buff->next;
-			s3c64xx_dma_freebuff(buff);
-		}
-
-		/* Update 'next' */
-		buff = chan->next;
-		if (chan->next == chan->end) {
-			chan->next = chan->curr;
-			if (!(chan->flags & S3C2410_DMAF_CIRCULAR))
-				chan->end = NULL;
-		} else {
-			chan->next = buff->next;
-		}
-	}
-
-	return IRQ_HANDLED;
-}
-
-static struct sysdev_class dma_sysclass = {
-	.name		= "s3c64xx-dma",
-};
-
-static int s3c64xx_dma_init1(int chno, enum dma_ch chbase,
-			     int irq, unsigned int base)
-{
-	struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno];
-	struct s3c64xx_dmac *dmac;
-	char clkname[16];
-	void __iomem *regs;
-	void __iomem *regptr;
-	int err, ch;
-
-	dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL);
-	if (!dmac) {
-		printk(KERN_ERR "%s: failed to alloc mem\n", __func__);
-		return -ENOMEM;
-	}
-
-	dmac->sysdev.id = chno / 8;
-	dmac->sysdev.cls = &dma_sysclass;
-
-	err = sysdev_register(&dmac->sysdev);
-	if (err) {
-		printk(KERN_ERR "%s: failed to register sysdevice\n", __func__);
-		goto err_alloc;
-	}
-
-	regs = ioremap(base, 0x200);
-	if (!regs) {
-		printk(KERN_ERR "%s: failed to ioremap()\n", __func__);
-		err = -ENXIO;
-		goto err_dev;
-	}
-
-	snprintf(clkname, sizeof(clkname), "dma%d", dmac->sysdev.id);
-
-	dmac->clk = clk_get(NULL, clkname);
-	if (IS_ERR(dmac->clk)) {
-		printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname);
-		err = PTR_ERR(dmac->clk);
-		goto err_map;
-	}
-
-	clk_enable(dmac->clk);
-
-	dmac->regs = regs;
-	dmac->chanbase = chbase;
-	dmac->channels = chptr;
-
-	err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac);
-	if (err < 0) {
-		printk(KERN_ERR "%s: failed to get irq\n", __func__);
-		goto err_clk;
-	}
-
-	regptr = regs + PL080_Cx_BASE(0);
-
-	for (ch = 0; ch < 8; ch++, chno++, chptr++) {
-		printk(KERN_INFO "%s: registering DMA %d (%p)\n",
-		       __func__, chno, regptr);
-
-		chptr->bit = 1 << ch;
-		chptr->number = chno;
-		chptr->dmac = dmac;
-		chptr->regs = regptr;
-		regptr += PL008_Cx_STRIDE;
-	}
-
-	/* for the moment, permanently enable the controller */
-	writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG);
-
-	printk(KERN_INFO "PL080: IRQ %d, at %p\n", irq, regs);
-
-	return 0;
-
-err_clk:
-	clk_disable(dmac->clk);
-	clk_put(dmac->clk);
-err_map:
-	iounmap(regs);
-err_dev:
-	sysdev_unregister(&dmac->sysdev);
-err_alloc:
-	kfree(dmac);
-	return err;
-}
-
-static int __init s3c64xx_dma_init(void)
-{
-	int ret;
-
-	printk(KERN_INFO "%s: Registering DMA channels\n", __func__);
-
-	dma_pool = dma_pool_create("DMA-LLI", NULL, sizeof(struct pl080s_lli), 16, 0);
-	if (!dma_pool) {
-		printk(KERN_ERR "%s: failed to create pool\n", __func__);
-		return -ENOMEM;
-	}
-
-	ret = sysdev_class_register(&dma_sysclass);
-	if (ret) {
-		printk(KERN_ERR "%s: failed to create sysclass\n", __func__);
-		return -ENOMEM;
-	}
-
-	/* Set all DMA configuration to be DMA, not SDMA */
-	writel(0xffffff, S3C_SYSREG(0x110));
-
-	/* Register standard DMA controlers */
-	s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000);
-	s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000);
-
-	return 0;
-}
-
-arch_initcall(s3c64xx_dma_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/gpiolib.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/gpiolib.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/gpiolib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/gpiolib.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,446 +0,0 @@
-/* arch/arm/plat-s3c64xx/gpiolib.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C64XX - GPIOlib support 
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include <mach/map.h>
-#include <mach/gpio.h>
-#include <mach/gpio-core.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-#include <plat/regs-gpio.h>
-
-/* GPIO bank summary:
- *
- * Bank	GPIOs	Style	SlpCon	ExtInt Group
- * A	8	4Bit	Yes	1
- * B	7	4Bit	Yes	1
- * C	8	4Bit	Yes	2
- * D	5	4Bit	Yes	3
- * E	5	4Bit	Yes	None
- * F	16	2Bit	Yes	4 [1]
- * G	7	4Bit	Yes	5
- * H	10	4Bit[2]	Yes	6
- * I	16	2Bit	Yes	None
- * J	12	2Bit	Yes	None
- * K	16	4Bit[2]	No	None
- * L	15	4Bit[2] No	None
- * M	6	4Bit	No	IRQ_EINT
- * N	16	2Bit	No	IRQ_EINT
- * O	16	2Bit	Yes	7
- * P	15	2Bit	Yes	8
- * Q	9	2Bit	Yes	9
- *
- * [1] BANKF pins 14,15 do not form part of the external interrupt sources
- * [2] BANK has two control registers, GPxCON0 and GPxCON1
- */
-
-#define OFF_GPCON	(0x00)
-#define OFF_GPDAT	(0x04)
-
-#define con_4bit_shift(__off) ((__off) * 4)
-
-#if 1
-#define gpio_dbg(x...) do { } while(0)
-#else
-#define gpio_dbg(x...) printk(KERN_DEBUG x)
-#endif
-
-/* The s3c64xx_gpiolib_4bit routines are to control the gpio banks where
- * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
- * following example:
- *
- * base + 0x00: Control register, 4 bits per gpio
- *	        gpio n: 4 bits starting at (4*n)
- *		0000 = input, 0001 = output, others mean special-function
- * base + 0x04: Data register, 1 bit per gpio
- *		bit n: data bit n
- *
- * Note, since the data register is one bit per gpio and is at base + 0x4
- * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of
- * the output.
-*/
-
-static int s3c64xx_gpiolib_4bit_input(struct gpio_chip *chip, unsigned offset)
-{
-	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-	void __iomem *base = ourchip->base;
-	unsigned long con;
-
-	con = __raw_readl(base + OFF_GPCON);
-	con &= ~(0xf << con_4bit_shift(offset));
-	__raw_writel(con, base + OFF_GPCON);
-
-	gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
-
-	return 0;
-}
-
-static int s3c64xx_gpiolib_4bit_output(struct gpio_chip *chip,
-				       unsigned offset, int value)
-{
-	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-	void __iomem *base = ourchip->base;
-	unsigned long con;
-	unsigned long dat;
-
-	con = __raw_readl(base + OFF_GPCON);
-	con &= ~(0xf << con_4bit_shift(offset));
-	con |= 0x1 << con_4bit_shift(offset);
-
-	dat = __raw_readl(base + OFF_GPDAT);
-	if (value)
-		dat |= 1 << offset;
-	else
-		dat &= ~(1 << offset);
-
-	__raw_writel(dat, base + OFF_GPDAT);
-	__raw_writel(con, base + OFF_GPCON);
-	__raw_writel(dat, base + OFF_GPDAT);
-
-	gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
-
-	return 0;
-}
-
-/* The next set of routines are for the case where the GPIO configuration
- * registers are 4 bits per GPIO but there is more than one register (the
- * bank has more than 8 GPIOs.
- *
- * This case is the similar to the 4 bit case, but the registers are as
- * follows:
- *
- * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
- *	        gpio n: 4 bits starting at (4*n)
- *		0000 = input, 0001 = output, others mean special-function
- * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
- *	        gpio n: 4 bits starting at (4*n)
- *		0000 = input, 0001 = output, others mean special-function
- * base + 0x08: Data register, 1 bit per gpio
- *		bit n: data bit n
- *
- * To allow us to use the s3c_gpiolib_get and s3c_gpiolib_set routines we
- * store the 'base + 0x4' address so that these routines see the data
- * register at ourchip->base + 0x04.
-*/
-
-static int s3c64xx_gpiolib_4bit2_input(struct gpio_chip *chip, unsigned offset)
-{
-	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-	void __iomem *base = ourchip->base;
-	void __iomem *regcon = base;
-	unsigned long con;
-
-	if (offset > 7)
-		offset -= 8;
-	else
-		regcon -= 4;
-
-	con = __raw_readl(regcon);
-	con &= ~(0xf << con_4bit_shift(offset));
-	__raw_writel(con, regcon);
-
-	gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
-
-	return 0;
-
-}
-
-static int s3c64xx_gpiolib_4bit2_output(struct gpio_chip *chip,
-				       unsigned offset, int value)
-{
-	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-	void __iomem *base = ourchip->base;
-	void __iomem *regcon = base;
-	unsigned long con;
-	unsigned long dat;
-
-	if (offset > 7)
-		offset -= 8;
-	else
-		regcon -= 4;
-
-	con = __raw_readl(regcon);
-	con &= ~(0xf << con_4bit_shift(offset));
-	con |= 0x1 << con_4bit_shift(offset);
-
-	dat = __raw_readl(base + OFF_GPDAT);
-	if (value)
-		dat |= 1 << offset;
-	else
-		dat &= ~(1 << offset);
-
-	__raw_writel(dat, base + OFF_GPDAT);
-	__raw_writel(con, regcon);
-	__raw_writel(dat, base + OFF_GPDAT);
-
-	gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
-
-	return 0;
-}
-
-static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
-	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
-	.set_pull	= s3c_gpio_setpull_updown,
-	.get_pull	= s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
-	.cfg_eint	= 7,
-	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
-	.set_pull	= s3c_gpio_setpull_updown,
-	.get_pull	= s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
-	.cfg_eint	= 3,
-	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
-	.set_pull	= s3c_gpio_setpull_updown,
-	.get_pull	= s3c_gpio_getpull_updown,
-};
-
-int s3c64xx_gpio2int_gpm(struct gpio_chip *chip, unsigned pin)
-{
-	return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
-}
-
-static struct s3c_gpio_chip gpio_4bit[] = {
-	{
-		.base	= S3C64XX_GPA_BASE,
-		.config	= &gpio_4bit_cfg_eint0111,
-		.chip	= {
-			.base	= S3C64XX_GPA(0),
-			.ngpio	= S3C64XX_GPIO_A_NR,
-			.label	= "GPA",
-		},
-	}, {
-		.base	= S3C64XX_GPB_BASE,
-		.config	= &gpio_4bit_cfg_eint0111,
-		.chip	= {
-			.base	= S3C64XX_GPB(0),
-			.ngpio	= S3C64XX_GPIO_B_NR,
-			.label	= "GPB",
-		},
-	}, {
-		.base	= S3C64XX_GPC_BASE,
-		.config	= &gpio_4bit_cfg_eint0111,
-		.chip	= {
-			.base	= S3C64XX_GPC(0),
-			.ngpio	= S3C64XX_GPIO_C_NR,
-			.label	= "GPC",
-		},
-	}, {
-		.base	= S3C64XX_GPD_BASE,
-		.config	= &gpio_4bit_cfg_eint0111,
-		.chip	= {
-			.base	= S3C64XX_GPD(0),
-			.ngpio	= S3C64XX_GPIO_D_NR,
-			.label	= "GPD",
-		},
-	}, {
-		.base	= S3C64XX_GPE_BASE,
-		.config	= &gpio_4bit_cfg_noint,
-		.chip	= {
-			.base	= S3C64XX_GPE(0),
-			.ngpio	= S3C64XX_GPIO_E_NR,
-			.label	= "GPE",
-		},
-	}, {
-		.base	= S3C64XX_GPG_BASE,
-		.config	= &gpio_4bit_cfg_eint0111,
-		.chip	= {
-			.base	= S3C64XX_GPG(0),
-			.ngpio	= S3C64XX_GPIO_G_NR,
-			.label	= "GPG",
-		},
-	}, {
-		.base	= S3C64XX_GPM_BASE,
-		.config	= &gpio_4bit_cfg_eint0011,
-		.chip	= {
-			.base	= S3C64XX_GPM(0),
-			.ngpio	= S3C64XX_GPIO_M_NR,
-			.label	= "GPM",
-			.to_irq = s3c64xx_gpio2int_gpm,
-		},
-	},
-};
-
-int s3c64xx_gpio2int_gpl(struct gpio_chip *chip, unsigned pin)
-{
-	return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
-}
-
-static struct s3c_gpio_chip gpio_4bit2[] = {
-	{
-		.base	= S3C64XX_GPH_BASE + 0x4,
-		.config	= &gpio_4bit_cfg_eint0111,
-		.chip	= {
-			.base	= S3C64XX_GPH(0),
-			.ngpio	= S3C64XX_GPIO_H_NR,
-			.label	= "GPH",
-		},
-	}, {
-		.base	= S3C64XX_GPK_BASE + 0x4,
-		.config	= &gpio_4bit_cfg_noint,
-		.chip	= {
-			.base	= S3C64XX_GPK(0),
-			.ngpio	= S3C64XX_GPIO_K_NR,
-			.label	= "GPK",
-		},
-	}, {
-		.base	= S3C64XX_GPL_BASE + 0x4,
-		.config	= &gpio_4bit_cfg_eint0011,
-		.chip	= {
-			.base	= S3C64XX_GPL(0),
-			.ngpio	= S3C64XX_GPIO_L_NR,
-			.label	= "GPL",
-			.to_irq = s3c64xx_gpio2int_gpl,
-		},
-	},
-};
-
-static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
-	.set_config	= s3c_gpio_setcfg_s3c24xx,
-	.set_pull	= s3c_gpio_setpull_updown,
-	.get_pull	= s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
-	.cfg_eint	= 2,
-	.set_config	= s3c_gpio_setcfg_s3c24xx,
-	.set_pull	= s3c_gpio_setpull_updown,
-	.get_pull	= s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
-	.cfg_eint	= 3,
-	.set_config	= s3c_gpio_setcfg_s3c24xx,
-	.set_pull	= s3c_gpio_setpull_updown,
-	.get_pull	= s3c_gpio_getpull_updown,
-};
-
-int s3c64xx_gpio2int_gpn(struct gpio_chip *chip, unsigned pin)
-{
-	return IRQ_EINT(0) + pin;
-}
-
-static struct s3c_gpio_chip gpio_2bit[] = {
-	{
-		.base	= S3C64XX_GPF_BASE,
-		.config	= &gpio_2bit_cfg_eint11,
-		.chip	= {
-			.base	= S3C64XX_GPF(0),
-			.ngpio	= S3C64XX_GPIO_F_NR,
-			.label	= "GPF",
-		},
-	}, {
-		.base	= S3C64XX_GPI_BASE,
-		.config	= &gpio_2bit_cfg_noint,
-		.chip	= {
-			.base	= S3C64XX_GPI(0),
-			.ngpio	= S3C64XX_GPIO_I_NR,
-			.label	= "GPI",
-		},
-	}, {
-		.base	= S3C64XX_GPJ_BASE,
-		.config	= &gpio_2bit_cfg_noint,
-		.chip	= {
-			.base	= S3C64XX_GPJ(0),
-			.ngpio	= S3C64XX_GPIO_J_NR,
-			.label	= "GPJ",
-		},
-	}, {
-		.base	= S3C64XX_GPN_BASE,
-		.config	= &gpio_2bit_cfg_eint10,
-		.chip	= {
-			.base	= S3C64XX_GPN(0),
-			.ngpio	= S3C64XX_GPIO_N_NR,
-			.label	= "GPN",
-			.to_irq = s3c64xx_gpio2int_gpn,
-		},
-	}, {
-		.base	= S3C64XX_GPO_BASE,
-		.config	= &gpio_2bit_cfg_eint11,
-		.chip	= {
-			.base	= S3C64XX_GPO(0),
-			.ngpio	= S3C64XX_GPIO_O_NR,
-			.label	= "GPO",
-		},
-	}, {
-		.base	= S3C64XX_GPP_BASE,
-		.config	= &gpio_2bit_cfg_eint11,
-		.chip	= {
-			.base	= S3C64XX_GPP(0),
-			.ngpio	= S3C64XX_GPIO_P_NR,
-			.label	= "GPP",
-		},
-	}, {
-		.base	= S3C64XX_GPQ_BASE,
-		.config	= &gpio_2bit_cfg_eint11,
-		.chip	= {
-			.base	= S3C64XX_GPQ(0),
-			.ngpio	= S3C64XX_GPIO_Q_NR,
-			.label	= "GPQ",
-		},
-	},
-};
-
-static __init void s3c64xx_gpiolib_add_4bit(struct s3c_gpio_chip *chip)
-{
-	chip->chip.direction_input = s3c64xx_gpiolib_4bit_input;
-	chip->chip.direction_output = s3c64xx_gpiolib_4bit_output;
-	chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
-}
-
-static __init void s3c64xx_gpiolib_add_4bit2(struct s3c_gpio_chip *chip)
-{
-	chip->chip.direction_input = s3c64xx_gpiolib_4bit2_input;
-	chip->chip.direction_output = s3c64xx_gpiolib_4bit2_output;
-	chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
-}
-
-static __init void s3c64xx_gpiolib_add_2bit(struct s3c_gpio_chip *chip)
-{
-	chip->pm = __gpio_pm(&s3c_gpio_pm_2bit);
-}
-
-static __init void s3c64xx_gpiolib_add(struct s3c_gpio_chip *chips,
-				       int nr_chips,
-				       void (*fn)(struct s3c_gpio_chip *))
-{
-	for (; nr_chips > 0; nr_chips--, chips++) {
-		if (fn)
-			(fn)(chips);
-		s3c_gpiolib_add(chips);
-	}
-}
-
-static __init int s3c64xx_gpiolib_init(void)
-{
-	s3c64xx_gpiolib_add(gpio_4bit, ARRAY_SIZE(gpio_4bit),
-			    s3c64xx_gpiolib_add_4bit);
-
-	s3c64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2),
-			    s3c64xx_gpiolib_add_4bit2);
-
-	s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit),
-			    s3c64xx_gpiolib_add_2bit);
-
-	return 0;
-}
-
-core_initcall(s3c64xx_gpiolib_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/dma-plat.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/dma-plat.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/dma-plat.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/dma-plat.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,70 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/dma-plat.h
- *
- * Copyright 2009 Openmoko, Inc.
- * Copyright 2009 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C64XX DMA core
- *
- * This program is free software; you can 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 DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
-
-struct s3c64xx_dma_buff;
-
-/** s3c64xx_dma_buff - S3C64XX DMA buffer descriptor
- * @next: Pointer to next buffer in queue or ring.
- * @pw: Client provided identifier
- * @lli: Pointer to hardware descriptor this buffer is associated with.
- * @lli_dma: Hardare address of the descriptor.
- */
-struct s3c64xx_dma_buff {
-	struct s3c64xx_dma_buff *next;
-
-	void			*pw;
-	struct pl080s_lli	*lli;
-	dma_addr_t		 lli_dma;
-};
-
-struct s3c64xx_dmac;
-
-struct s3c2410_dma_chan {
-	unsigned char		 number;      /* number of this dma channel */
-	unsigned char		 in_use;      /* channel allocated */
-	unsigned char		 bit;	      /* bit for enable/disable/etc */
-	unsigned char		 hw_width;
-	unsigned char		 peripheral;
-
-	unsigned int		 flags;
-	enum s3c2410_dmasrc	 source;
-
-
-	dma_addr_t		dev_addr;
-
-	struct s3c2410_dma_client *client;
-	struct s3c64xx_dmac	*dmac;		/* pointer to controller */
-
-	void __iomem		*regs;
-
-	/* cdriver callbacks */
-	s3c2410_dma_cbfn_t	 callback_fn;	/* buffer done callback */
-	s3c2410_dma_opfn_t	 op_fn;		/* channel op callback */
-
-	/* buffer list and information */
-	struct s3c64xx_dma_buff	*curr;		/* current dma buffer */
-	struct s3c64xx_dma_buff	*next;		/* next buffer to load */
-	struct s3c64xx_dma_buff	*end;		/* end of queue */
-
-	/* note, when channel is running in circular mode, curr is the
-	 * first buffer enqueued, end is the last and curr is where the
-	 * last buffer-done event is set-at. The buffers are not freed
-	 * and the last buffer hardware descriptor points back to the
-	 * first.
-	 */
-};
-
-#include <plat/dma-core.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-a.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-a.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-a.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-a.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,48 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-a.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * 	Ben Dooks <ben@simtec.co.uk>
- * 	http://armlinux.simtec.co.uk/
- *
- * GPIO Bank A register and configuration definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define S3C64XX_GPACON			(S3C64XX_GPA_BASE + 0x00)
-#define S3C64XX_GPADAT			(S3C64XX_GPA_BASE + 0x04)
-#define S3C64XX_GPAPUD			(S3C64XX_GPA_BASE + 0x08)
-#define S3C64XX_GPACONSLP		(S3C64XX_GPA_BASE + 0x0c)
-#define S3C64XX_GPAPUDSLP		(S3C64XX_GPA_BASE + 0x10)
-
-#define S3C64XX_GPA_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
-#define S3C64XX_GPA_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
-#define S3C64XX_GPA_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
-
-#define S3C64XX_GPA0_UART_RXD0		(0x02 << 0)
-#define S3C64XX_GPA0_EINT_G1_0		(0x07 << 0)
-
-#define S3C64XX_GPA1_UART_TXD0		(0x02 << 4)
-#define S3C64XX_GPA1_EINT_G1_1		(0x07 << 4)
-
-#define S3C64XX_GPA2_UART_nCTS0		(0x02 << 8)
-#define S3C64XX_GPA2_EINT_G1_2		(0x07 << 8)
-
-#define S3C64XX_GPA3_UART_nRTS0		(0x02 << 12)
-#define S3C64XX_GPA3_EINT_G1_3		(0x07 << 12)
-
-#define S3C64XX_GPA4_UART_RXD1		(0x02 << 16)
-#define S3C64XX_GPA4_EINT_G1_4		(0x07 << 16)
-
-#define S3C64XX_GPA5_UART_TXD1		(0x02 << 20)
-#define S3C64XX_GPA5_EINT_G1_5		(0x07 << 20)
-
-#define S3C64XX_GPA6_UART_nCTS1		(0x02 << 24)
-#define S3C64XX_GPA6_EINT_G1_6		(0x07 << 24)
-
-#define S3C64XX_GPA7_UART_nRTS1		(0x02 << 28)
-#define S3C64XX_GPA7_EINT_G1_7		(0x07 << 28)
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-b.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-b.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-b.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-b.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,60 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-b.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * 	Ben Dooks <ben@simtec.co.uk>
- * 	http://armlinux.simtec.co.uk/
- *
- * GPIO Bank B register and configuration definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define S3C64XX_GPBCON			(S3C64XX_GPB_BASE + 0x00)
-#define S3C64XX_GPBDAT			(S3C64XX_GPB_BASE + 0x04)
-#define S3C64XX_GPBPUD			(S3C64XX_GPB_BASE + 0x08)
-#define S3C64XX_GPBCONSLP		(S3C64XX_GPB_BASE + 0x0c)
-#define S3C64XX_GPBPUDSLP		(S3C64XX_GPB_BASE + 0x10)
-
-#define S3C64XX_GPB_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
-#define S3C64XX_GPB_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
-#define S3C64XX_GPB_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
-
-#define S3C64XX_GPB0_UART_RXD2		(0x02 << 0)
-#define S3C64XX_GPB0_EXTDMA_REQ		(0x03 << 0)
-#define S3C64XX_GPB0_IrDA_RXD		(0x04 << 0)
-#define S3C64XX_GPB0_ADDR_CF0		(0x05 << 0)
-#define S3C64XX_GPB0_EINT_G1_8		(0x07 << 0)
-
-#define S3C64XX_GPB1_UART_TXD2		(0x02 << 4)
-#define S3C64XX_GPB1_EXTDMA_ACK		(0x03 << 4)
-#define S3C64XX_GPB1_IrDA_TXD		(0x04 << 4)
-#define S3C64XX_GPB1_ADDR_CF1		(0x05 << 4)
-#define S3C64XX_GPB1_EINT_G1_9		(0x07 << 4)
-
-#define S3C64XX_GPB2_UART_RXD3		(0x02 << 8)
-#define S3C64XX_GPB2_IrDA_RXD		(0x03 << 8)
-#define S3C64XX_GPB2_EXTDMA_REQ		(0x04 << 8)
-#define S3C64XX_GPB2_ADDR_CF2		(0x05 << 8)
-#define S3C64XX_GPB2_I2C_SCL1		(0x06 << 8)
-#define S3C64XX_GPB2_EINT_G1_10		(0x07 << 8)
-
-#define S3C64XX_GPB3_UART_TXD3		(0x02 << 12)
-#define S3C64XX_GPB3_IrDA_TXD		(0x03 << 12)
-#define S3C64XX_GPB3_EXTDMA_ACK		(0x04 << 12)
-#define S3C64XX_GPB3_I2C_SDA1		(0x06 << 12)
-#define S3C64XX_GPB3_EINT_G1_11		(0x07 << 12)
-
-#define S3C64XX_GPB4_IrDA_SDBW		(0x02 << 16)
-#define S3C64XX_GPB4_CAM_FIELD		(0x03 << 16)
-#define S3C64XX_GPB4_CF_DATA_DIR	(0x04 << 16)
-#define S3C64XX_GPB4_EINT_G1_12		(0x07 << 16)
-
-#define S3C64XX_GPB5_I2C_SCL0		(0x02 << 20)
-#define S3C64XX_GPB5_EINT_G1_13		(0x07 << 20)
-
-#define S3C64XX_GPB6_I2C_SDA0		(0x02 << 24)
-#define S3C64XX_GPB6_EINT_G1_14		(0x07 << 24)
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-c.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-c.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-c.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-c.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,53 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-c.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * 	Ben Dooks <ben@simtec.co.uk>
- * 	http://armlinux.simtec.co.uk/
- *
- * GPIO Bank C register and configuration definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define S3C64XX_GPCCON			(S3C64XX_GPC_BASE + 0x00)
-#define S3C64XX_GPCDAT			(S3C64XX_GPC_BASE + 0x04)
-#define S3C64XX_GPCPUD			(S3C64XX_GPC_BASE + 0x08)
-#define S3C64XX_GPCCONSLP		(S3C64XX_GPC_BASE + 0x0c)
-#define S3C64XX_GPCPUDSLP		(S3C64XX_GPC_BASE + 0x10)
-
-#define S3C64XX_GPC_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
-#define S3C64XX_GPC_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
-#define S3C64XX_GPC_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
-
-#define S3C64XX_GPC0_SPI_MISO0		(0x02 << 0)
-#define S3C64XX_GPC0_EINT_G2_0		(0x07 << 0)
-
-#define S3C64XX_GPC1_SPI_CLKO		(0x02 << 4)
-#define S3C64XX_GPC1_EINT_G2_1		(0x07 << 4)
-
-#define S3C64XX_GPC2_SPI_MOSIO		(0x02 << 8)
-#define S3C64XX_GPC2_EINT_G2_2		(0x07 << 8)
-
-#define S3C64XX_GPC3_SPI_nCSO		(0x02 << 12)
-#define S3C64XX_GPC3_EINT_G2_3		(0x07 << 12)
-
-#define S3C64XX_GPC4_SPI_MISO1		(0x02 << 16)
-#define S3C64XX_GPC4_MMC2_CMD		(0x03 << 16)
-#define S3C64XX_GPC4_I2S_V40_DO0	(0x05 << 16)
-#define S3C64XX_GPC4_EINT_G2_4		(0x07 << 16)
-
-#define S3C64XX_GPC5_SPI_CLK1		(0x02 << 20)
-#define S3C64XX_GPC5_MMC2_CLK		(0x03 << 20)
-#define S3C64XX_GPC5_I2S_V40_DO1	(0x05 << 20)
-#define S3C64XX_GPC5_EINT_G2_5		(0x07 << 20)
-
-#define S3C64XX_GPC6_SPI_MOSI1		(0x02 << 24)
-#define S3C64XX_GPC6_EINT_G2_6		(0x07 << 24)
-
-#define S3C64XX_GPC7_SPI_nCS1		(0x02 << 28)
-#define S3C64XX_GPC7_I2S_V40_DO2	(0x05 << 28)
-#define S3C64XX_GPC7_EINT_G2_7		(0x07 << 28)
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-d.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-d.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-d.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-d.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-d.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * 	Ben Dooks <ben@simtec.co.uk>
- * 	http://armlinux.simtec.co.uk/
- *
- * GPIO Bank D register and configuration definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define S3C64XX_GPDCON			(S3C64XX_GPD_BASE + 0x00)
-#define S3C64XX_GPDDAT			(S3C64XX_GPD_BASE + 0x04)
-#define S3C64XX_GPDPUD			(S3C64XX_GPD_BASE + 0x08)
-#define S3C64XX_GPDCONSLP		(S3C64XX_GPD_BASE + 0x0c)
-#define S3C64XX_GPDPUDSLP		(S3C64XX_GPD_BASE + 0x10)
-
-#define S3C64XX_GPD_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
-#define S3C64XX_GPD_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
-#define S3C64XX_GPD_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
-
-#define S3C64XX_GPD0_PCM0_SCLK		(0x02 << 0)
-#define S3C64XX_GPD0_I2S0_CLK		(0x03 << 0)
-#define S3C64XX_GPD0_AC97_BITCLK	(0x04 << 0)
-#define S3C64XX_GPD0_EINT_G3_0		(0x07 << 0)
-
-#define S3C64XX_GPD1_PCM0_EXTCLK	(0x02 << 4)
-#define S3C64XX_GPD1_I2S0_CDCLK		(0x03 << 4)
-#define S3C64XX_GPD1_AC97_nRESET	(0x04 << 4)
-#define S3C64XX_GPD1_EINT_G3_1		(0x07 << 4)
-
-#define S3C64XX_GPD2_PCM0_FSYNC		(0x02 << 8)
-#define S3C64XX_GPD2_I2S0_LRCLK		(0x03 << 8)
-#define S3C64XX_GPD2_AC97_SYNC		(0x04 << 8)
-#define S3C64XX_GPD2_EINT_G3_2		(0x07 << 8)
-
-#define S3C64XX_GPD3_PCM0_SIN		(0x02 << 12)
-#define S3C64XX_GPD3_I2S0_DI		(0x03 << 12)
-#define S3C64XX_GPD3_AC97_SDI		(0x04 << 12)
-#define S3C64XX_GPD3_EINT_G3_3		(0x07 << 12)
-
-#define S3C64XX_GPD4_PCM0_SOUT		(0x02 << 16)
-#define S3C64XX_GPD4_I2S0_D0		(0x03 << 16)
-#define S3C64XX_GPD4_AC97_SDO		(0x04 << 16)
-#define S3C64XX_GPD4_EINT_G3_4		(0x07 << 16)
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-e.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-e.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-e.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-e.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,44 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-e.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * 	Ben Dooks <ben@simtec.co.uk>
- * 	http://armlinux.simtec.co.uk/
- *
- * GPIO Bank E register and configuration definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define S3C64XX_GPECON			(S3C64XX_GPE_BASE + 0x00)
-#define S3C64XX_GPEDAT			(S3C64XX_GPE_BASE + 0x04)
-#define S3C64XX_GPEPUD			(S3C64XX_GPE_BASE + 0x08)
-#define S3C64XX_GPECONSLP		(S3C64XX_GPE_BASE + 0x0c)
-#define S3C64XX_GPEPUDSLP		(S3C64XX_GPE_BASE + 0x10)
-
-#define S3C64XX_GPE_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
-#define S3C64XX_GPE_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
-#define S3C64XX_GPE_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
-
-#define S3C64XX_GPE0_PCM1_SCLK		(0x02 << 0)
-#define S3C64XX_GPE0_I2S1_CLK		(0x03 << 0)
-#define S3C64XX_GPE0_AC97_BITCLK	(0x04 << 0)
-
-#define S3C64XX_GPE1_PCM1_EXTCLK	(0x02 << 4)
-#define S3C64XX_GPE1_I2S1_CDCLK		(0x03 << 4)
-#define S3C64XX_GPE1_AC97_nRESET	(0x04 << 4)
-
-#define S3C64XX_GPE2_PCM1_FSYNC		(0x02 << 8)
-#define S3C64XX_GPE2_I2S1_LRCLK		(0x03 << 8)
-#define S3C64XX_GPE2_AC97_SYNC		(0x04 << 8)
-
-#define S3C64XX_GPE3_PCM1_SIN		(0x02 << 12)
-#define S3C64XX_GPE3_I2S1_DI		(0x03 << 12)
-#define S3C64XX_GPE3_AC97_SDI		(0x04 << 12)
-
-#define S3C64XX_GPE4_PCM1_SOUT		(0x02 << 16)
-#define S3C64XX_GPE4_I2S1_D0		(0x03 << 16)
-#define S3C64XX_GPE4_AC97_SDO		(0x04 << 16)
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-f.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-f.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-f.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-f.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,71 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-f.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * 	Ben Dooks <ben@simtec.co.uk>
- * 	http://armlinux.simtec.co.uk/
- *
- * GPIO Bank F register and configuration definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define S3C64XX_GPFCON			(S3C64XX_GPF_BASE + 0x00)
-#define S3C64XX_GPFDAT			(S3C64XX_GPF_BASE + 0x04)
-#define S3C64XX_GPFPUD			(S3C64XX_GPF_BASE + 0x08)
-#define S3C64XX_GPFCONSLP		(S3C64XX_GPF_BASE + 0x0c)
-#define S3C64XX_GPFPUDSLP		(S3C64XX_GPF_BASE + 0x10)
-
-#define S3C64XX_GPF_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
-#define S3C64XX_GPF_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
-#define S3C64XX_GPF_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
-
-#define S3C64XX_GPF0_CAMIF_CLK		(0x02 << 0)
-#define S3C64XX_GPF0_EINT_G4_0		(0x03 << 0)
-
-#define S3C64XX_GPF1_CAMIF_HREF		(0x02 << 2)
-#define S3C64XX_GPF1_EINT_G4_1		(0x03 << 2)
-
-#define S3C64XX_GPF2_CAMIF_PCLK		(0x02 << 4)
-#define S3C64XX_GPF2_EINT_G4_2		(0x03 << 4)
-
-#define S3C64XX_GPF3_CAMIF_nRST		(0x02 << 6)
-#define S3C64XX_GPF3_EINT_G4_3		(0x03 << 6)
-
-#define S3C64XX_GPF4_CAMIF_VSYNC	(0x02 << 8)
-#define S3C64XX_GPF4_EINT_G4_4		(0x03 << 8)
-
-#define S3C64XX_GPF5_CAMIF_YDATA0	(0x02 << 10)
-#define S3C64XX_GPF5_EINT_G4_5		(0x03 << 10)
-
-#define S3C64XX_GPF6_CAMIF_YDATA1	(0x02 << 12)
-#define S3C64XX_GPF6_EINT_G4_6		(0x03 << 12)
-
-#define S3C64XX_GPF7_CAMIF_YDATA2	(0x02 << 14)
-#define S3C64XX_GPF7_EINT_G4_7		(0x03 << 14)
-
-#define S3C64XX_GPF8_CAMIF_YDATA3	(0x02 << 16)
-#define S3C64XX_GPF8_EINT_G4_8		(0x03 << 16)
-
-#define S3C64XX_GPF9_CAMIF_YDATA4	(0x02 << 18)
-#define S3C64XX_GPF9_EINT_G4_9		(0x03 << 18)
-
-#define S3C64XX_GPF10_CAMIF_YDATA5	(0x02 << 20)
-#define S3C64XX_GPF10_EINT_G4_10	(0x03 << 20)
-
-#define S3C64XX_GPF11_CAMIF_YDATA6	(0x02 << 22)
-#define S3C64XX_GPF11_EINT_G4_11	(0x03 << 22)
-
-#define S3C64XX_GPF12_CAMIF_YDATA7	(0x02 << 24)
-#define S3C64XX_GPF12_EINT_G4_12	(0x03 << 24)
-
-#define S3C64XX_GPF13_PWM_ECLK		(0x02 << 26)
-#define S3C64XX_GPF13_EINT_G4_13	(0x03 << 26)
-
-#define S3C64XX_GPF14_PWM_TOUT0		(0x02 << 28)
-#define S3C64XX_GPF14_CLKOUT0		(0x03 << 28)
-
-#define S3C64XX_GPF15_PWM_TOUT1		(0x02 << 30)
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-g.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-g.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-g.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-g.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,42 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-g.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * 	Ben Dooks <ben@simtec.co.uk>
- * 	http://armlinux.simtec.co.uk/
- *
- * GPIO Bank G register and configuration definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define S3C64XX_GPGCON			(S3C64XX_GPG_BASE + 0x00)
-#define S3C64XX_GPGDAT			(S3C64XX_GPG_BASE + 0x04)
-#define S3C64XX_GPGPUD			(S3C64XX_GPG_BASE + 0x08)
-#define S3C64XX_GPGCONSLP		(S3C64XX_GPG_BASE + 0x0c)
-#define S3C64XX_GPGPUDSLP		(S3C64XX_GPG_BASE + 0x10)
-
-#define S3C64XX_GPG_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
-#define S3C64XX_GPG_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
-#define S3C64XX_GPG_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
-
-#define S3C64XX_GPG0_MMC0_CLK		(0x02 << 0)
-#define S3C64XX_GPG0_EINT_G5_0		(0x07 << 0)
-
-#define S3C64XX_GPG1_MMC0_CMD		(0x02 << 4)
-#define S3C64XX_GPG1_EINT_G5_1		(0x07 << 4)
-
-#define S3C64XX_GPG2_MMC0_DATA0		(0x02 << 8)
-#define S3C64XX_GPG2_EINT_G5_2		(0x07 << 8)
-
-#define S3C64XX_GPG3_MMC0_DATA1		(0x02 << 12)
-#define S3C64XX_GPG3_EINT_G5_3		(0x07 << 12)
-
-#define S3C64XX_GPG4_MMC0_DATA2		(0x02 << 16)
-#define S3C64XX_GPG4_EINT_G5_4		(0x07 << 16)
-
-#define S3C64XX_GPG5_MMC0_DATA3		(0x02 << 20)
-#define S3C64XX_GPG5_EINT_G5_5		(0x07 << 20)
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,74 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * 	Ben Dooks <ben@simtec.co.uk>
- * 	http://armlinux.simtec.co.uk/
- *
- * GPIO Bank H register and configuration definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define S3C64XX_GPHCON0			(S3C64XX_GPH_BASE + 0x00)
-#define S3C64XX_GPHCON1			(S3C64XX_GPH_BASE + 0x04)
-#define S3C64XX_GPHDAT			(S3C64XX_GPH_BASE + 0x08)
-#define S3C64XX_GPHPUD			(S3C64XX_GPH_BASE + 0x0c)
-#define S3C64XX_GPHCONSLP		(S3C64XX_GPH_BASE + 0x10)
-#define S3C64XX_GPHPUDSLP		(S3C64XX_GPH_BASE + 0x14)
-
-#define S3C64XX_GPH_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
-#define S3C64XX_GPH_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
-#define S3C64XX_GPH_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
-
-#define S3C64XX_GPH0_MMC1_CLK		(0x02 << 0)
-#define S3C64XX_GPH0_KP_COL0		(0x04 << 0)
-#define S3C64XX_GPH0_EINT_G6_0		(0x07 << 0)
-
-#define S3C64XX_GPH1_MMC1_CMD		(0x02 << 4)
-#define S3C64XX_GPH1_KP_COL1		(0x04 << 4)
-#define S3C64XX_GPH1_EINT_G6_1		(0x07 << 4)
-
-#define S3C64XX_GPH2_MMC1_DATA0		(0x02 << 8)
-#define S3C64XX_GPH2_KP_COL2		(0x04 << 8)
-#define S3C64XX_GPH2_EINT_G6_2		(0x07 << 8)
-
-#define S3C64XX_GPH3_MMC1_DATA1		(0x02 << 12)
-#define S3C64XX_GPH3_KP_COL3		(0x04 << 12)
-#define S3C64XX_GPH3_EINT_G6_3		(0x07 << 12)
-
-#define S3C64XX_GPH4_MMC1_DATA2		(0x02 << 16)
-#define S3C64XX_GPH4_KP_COL4		(0x04 << 16)
-#define S3C64XX_GPH4_EINT_G6_4		(0x07 << 16)
-
-#define S3C64XX_GPH5_MMC1_DATA3		(0x02 << 20)
-#define S3C64XX_GPH5_KP_COL5		(0x04 << 20)
-#define S3C64XX_GPH5_EINT_G6_5		(0x07 << 20)
-
-#define S3C64XX_GPH6_MMC1_DATA4		(0x02 << 24)
-#define S3C64XX_GPH6_MMC2_DATA0		(0x03 << 24)
-#define S3C64XX_GPH6_KP_COL6		(0x04 << 24)
-#define S3C64XX_GPH6_I2S_V40_BCLK	(0x05 << 24)
-#define S3C64XX_GPH6_ADDR_CF0		(0x06 << 24)
-#define S3C64XX_GPH6_EINT_G6_6		(0x07 << 24)
-
-#define S3C64XX_GPH7_MMC1_DATA5		(0x02 << 28)
-#define S3C64XX_GPH7_MMC2_DATA1		(0x03 << 28)
-#define S3C64XX_GPH7_KP_COL7		(0x04 << 28)
-#define S3C64XX_GPH7_I2S_V40_CDCLK	(0x05 << 28)
-#define S3C64XX_GPH7_ADDR_CF1		(0x06 << 28)
-#define S3C64XX_GPH7_EINT_G6_7		(0x07 << 28)
-
-#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.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-i.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-i.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-i.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-i.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,40 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-i.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * 	Ben Dooks <ben@simtec.co.uk>
- * 	http://armlinux.simtec.co.uk/
- *
- * GPIO Bank I register and configuration definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define S3C64XX_GPICON			(S3C64XX_GPI_BASE + 0x00)
-#define S3C64XX_GPIDAT			(S3C64XX_GPI_BASE + 0x04)
-#define S3C64XX_GPIPUD			(S3C64XX_GPI_BASE + 0x08)
-#define S3C64XX_GPICONSLP		(S3C64XX_GPI_BASE + 0x0c)
-#define S3C64XX_GPIPUDSLP		(S3C64XX_GPI_BASE + 0x10)
-
-#define S3C64XX_GPI_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
-#define S3C64XX_GPI_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
-#define S3C64XX_GPI_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
-
-#define S3C64XX_GPI0_VD0		(0x02 << 0)
-#define S3C64XX_GPI1_VD1		(0x02 << 2)
-#define S3C64XX_GPI2_VD2		(0x02 << 4)
-#define S3C64XX_GPI3_VD3		(0x02 << 6)
-#define S3C64XX_GPI4_VD4		(0x02 << 8)
-#define S3C64XX_GPI5_VD5		(0x02 << 10)
-#define S3C64XX_GPI6_VD6		(0x02 << 12)
-#define S3C64XX_GPI7_VD7		(0x02 << 14)
-#define S3C64XX_GPI8_VD8		(0x02 << 16)
-#define S3C64XX_GPI9_VD9		(0x02 << 18)
-#define S3C64XX_GPI10_VD10		(0x02 << 20)
-#define S3C64XX_GPI11_VD11		(0x02 << 22)
-#define S3C64XX_GPI12_VD12		(0x02 << 24)
-#define S3C64XX_GPI13_VD13		(0x02 << 26)
-#define S3C64XX_GPI14_VD14		(0x02 << 28)
-#define S3C64XX_GPI15_VD15		(0x02 << 30)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-j.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-j.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-j.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-j.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,36 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-j.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * 	Ben Dooks <ben@simtec.co.uk>
- * 	http://armlinux.simtec.co.uk/
- *
- * GPIO Bank J register and configuration definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define S3C64XX_GPJCON			(S3C64XX_GPJ_BASE + 0x00)
-#define S3C64XX_GPJDAT			(S3C64XX_GPJ_BASE + 0x04)
-#define S3C64XX_GPJPUD			(S3C64XX_GPJ_BASE + 0x08)
-#define S3C64XX_GPJCONSLP		(S3C64XX_GPJ_BASE + 0x0c)
-#define S3C64XX_GPJPUDSLP		(S3C64XX_GPJ_BASE + 0x10)
-
-#define S3C64XX_GPJ_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
-#define S3C64XX_GPJ_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
-#define S3C64XX_GPJ_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
-
-#define S3C64XX_GPJ0_VD16		(0x02 << 0)
-#define S3C64XX_GPJ1_VD17		(0x02 << 2)
-#define S3C64XX_GPJ2_VD18		(0x02 << 4)
-#define S3C64XX_GPJ3_VD19		(0x02 << 6)
-#define S3C64XX_GPJ4_VD20		(0x02 << 8)
-#define S3C64XX_GPJ5_VD21		(0x02 << 10)
-#define S3C64XX_GPJ6_VD22		(0x02 << 12)
-#define S3C64XX_GPJ7_VD23		(0x02 << 14)
-#define S3C64XX_GPJ8_LCD_HSYNC		(0x02 << 16)
-#define S3C64XX_GPJ9_LCD_VSYNC		(0x02 << 18)
-#define S3C64XX_GPJ10_LCD_VDEN		(0x02 << 20)
-#define S3C64XX_GPJ11_LCD_VCLK		(0x02 << 22)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-n.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-n.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-n.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-n.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,54 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-n.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * 	Ben Dooks <ben@simtec.co.uk>
- * 	http://armlinux.simtec.co.uk/
- *
- * GPIO Bank N register and configuration definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define S3C64XX_GPNCON			(S3C64XX_GPN_BASE + 0x00)
-#define S3C64XX_GPNDAT			(S3C64XX_GPN_BASE + 0x04)
-#define S3C64XX_GPNPUD			(S3C64XX_GPN_BASE + 0x08)
-
-#define S3C64XX_GPN_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
-#define S3C64XX_GPN_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
-#define S3C64XX_GPN_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
-
-#define S3C64XX_GPN0_EINT0		(0x02 << 0)
-#define S3C64XX_GPN0_KP_ROW0		(0x03 << 0)
-
-#define S3C64XX_GPN1_EINT1		(0x02 << 2)
-#define S3C64XX_GPN1_KP_ROW1		(0x03 << 2)
-
-#define S3C64XX_GPN2_EINT2		(0x02 << 4)
-#define S3C64XX_GPN2_KP_ROW2		(0x03 << 4)
-
-#define S3C64XX_GPN3_EINT3		(0x02 << 6)
-#define S3C64XX_GPN3_KP_ROW3		(0x03 << 6)
-
-#define S3C64XX_GPN4_EINT4		(0x02 << 8)
-#define S3C64XX_GPN4_KP_ROW4		(0x03 << 8)
-
-#define S3C64XX_GPN5_EINT5		(0x02 << 10)
-#define S3C64XX_GPN5_KP_ROW5		(0x03 << 10)
-
-#define S3C64XX_GPN6_EINT6		(0x02 << 12)
-#define S3C64XX_GPN6_KP_ROW6		(0x03 << 12)
-
-#define S3C64XX_GPN7_EINT7		(0x02 << 14)
-#define S3C64XX_GPN7_KP_ROW7		(0x03 << 14)
-
-#define S3C64XX_GPN8_EINT8		(0x02 << 16)
-#define S3C64XX_GPN9_EINT9		(0x02 << 18)
-#define S3C64XX_GPN10_EINT10		(0x02 << 20)
-#define S3C64XX_GPN11_EINT11		(0x02 << 22)
-#define S3C64XX_GPN12_EINT12		(0x02 << 24)
-#define S3C64XX_GPN13_EINT13		(0x02 << 26)
-#define S3C64XX_GPN14_EINT14		(0x02 << 28)
-#define S3C64XX_GPN15_EINT15		(0x02 << 30)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-o.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-o.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-o.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-o.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,70 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-o.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * 	Ben Dooks <ben@simtec.co.uk>
- * 	http://armlinux.simtec.co.uk/
- *
- * GPIO Bank O register and configuration definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define S3C64XX_GPOCON			(S3C64XX_GPO_BASE + 0x00)
-#define S3C64XX_GPODAT			(S3C64XX_GPO_BASE + 0x04)
-#define S3C64XX_GPOPUD			(S3C64XX_GPO_BASE + 0x08)
-#define S3C64XX_GPOCONSLP		(S3C64XX_GPO_BASE + 0x0c)
-#define S3C64XX_GPOPUDSLP		(S3C64XX_GPO_BASE + 0x10)
-
-#define S3C64XX_GPO_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
-#define S3C64XX_GPO_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
-#define S3C64XX_GPO_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
-
-#define S3C64XX_GPO0_MEM0_nCS2		(0x02 << 0)
-#define S3C64XX_GPO0_EINT_G7_0		(0x03 << 0)
-
-#define S3C64XX_GPO1_MEM0_nCS3		(0x02 << 2)
-#define S3C64XX_GPO1_EINT_G7_1		(0x03 << 2)
-
-#define S3C64XX_GPO2_MEM0_nCS4		(0x02 << 4)
-#define S3C64XX_GPO2_EINT_G7_2		(0x03 << 4)
-
-#define S3C64XX_GPO3_MEM0_nCS5		(0x02 << 6)
-#define S3C64XX_GPO3_EINT_G7_3		(0x03 << 6)
-
-#define S3C64XX_GPO4_EINT_G7_4		(0x03 << 8)
-
-#define S3C64XX_GPO5_EINT_G7_5		(0x03 << 10)
-
-#define S3C64XX_GPO6_MEM0_ADDR6		(0x02 << 12)
-#define S3C64XX_GPO6_EINT_G7_6		(0x03 << 12)
-
-#define S3C64XX_GPO7_MEM0_ADDR7		(0x02 << 14)
-#define S3C64XX_GPO7_EINT_G7_7		(0x03 << 14)
-
-#define S3C64XX_GPO8_MEM0_ADDR8		(0x02 << 16)
-#define S3C64XX_GPO8_EINT_G7_8		(0x03 << 16)
-
-#define S3C64XX_GPO9_MEM0_ADDR9		(0x02 << 18)
-#define S3C64XX_GPO9_EINT_G7_9		(0x03 << 18)
-
-#define S3C64XX_GPO10_MEM0_ADDR10	(0x02 << 20)
-#define S3C64XX_GPO10_EINT_G7_10	(0x03 << 20)
-
-#define S3C64XX_GPO11_MEM0_ADDR11	(0x02 << 22)
-#define S3C64XX_GPO11_EINT_G7_11	(0x03 << 22)
-
-#define S3C64XX_GPO12_MEM0_ADDR12	(0x02 << 24)
-#define S3C64XX_GPO12_EINT_G7_12	(0x03 << 24)
-
-#define S3C64XX_GPO13_MEM0_ADDR13	(0x02 << 26)
-#define S3C64XX_GPO13_EINT_G7_13	(0x03 << 26)
-
-#define S3C64XX_GPO14_MEM0_ADDR14	(0x02 << 28)
-#define S3C64XX_GPO14_EINT_G7_14	(0x03 << 28)
-
-#define S3C64XX_GPO15_MEM0_ADDR15	(0x02 << 30)
-#define S3C64XX_GPO15_EINT_G7_15	(0x03 << 30)
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-p.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-p.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-p.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-p.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,69 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-p.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * 	Ben Dooks <ben@simtec.co.uk>
- * 	http://armlinux.simtec.co.uk/
- *
- * GPIO Bank P register and configuration definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define S3C64XX_GPPCON			(S3C64XX_GPP_BASE + 0x00)
-#define S3C64XX_GPPDAT			(S3C64XX_GPP_BASE + 0x04)
-#define S3C64XX_GPPPUD			(S3C64XX_GPP_BASE + 0x08)
-#define S3C64XX_GPPCONSLP		(S3C64XX_GPP_BASE + 0x0c)
-#define S3C64XX_GPPPUDSLP		(S3C64XX_GPP_BASE + 0x10)
-
-#define S3C64XX_GPP_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
-#define S3C64XX_GPP_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
-#define S3C64XX_GPP_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
-
-#define S3C64XX_GPP0_MEM0_ADDRV		(0x02 << 0)
-#define S3C64XX_GPP0_EINT_G8_0		(0x03 << 0)
-
-#define S3C64XX_GPP1_MEM0_SMCLK		(0x02 << 2)
-#define S3C64XX_GPP1_EINT_G8_1		(0x03 << 2)
-
-#define S3C64XX_GPP2_MEM0_nWAIT		(0x02 << 4)
-#define S3C64XX_GPP2_EINT_G8_2		(0x03 << 4)
-
-#define S3C64XX_GPP3_MEM0_RDY0_ALE	(0x02 << 6)
-#define S3C64XX_GPP3_EINT_G8_3		(0x03 << 6)
-
-#define S3C64XX_GPP4_MEM0_RDY1_CLE	(0x02 << 8)
-#define S3C64XX_GPP4_EINT_G8_4		(0x03 << 8)
-
-#define S3C64XX_GPP5_MEM0_INTsm0_FWE	(0x02 << 10)
-#define S3C64XX_GPP5_EINT_G8_5		(0x03 << 10)
-
-#define S3C64XX_GPP6_MEM0_(null)	(0x02 << 12)
-#define S3C64XX_GPP6_EINT_G8_6		(0x03 << 12)
-
-#define S3C64XX_GPP7_MEM0_INTsm1_FRE	(0x02 << 14)
-#define S3C64XX_GPP7_EINT_G8_7		(0x03 << 14)
-
-#define S3C64XX_GPP8_MEM0_RPn_RnB	(0x02 << 16)
-#define S3C64XX_GPP8_EINT_G8_8		(0x03 << 16)
-
-#define S3C64XX_GPP9_MEM0_ATA_RESET	(0x02 << 18)
-#define S3C64XX_GPP9_EINT_G8_9		(0x03 << 18)
-
-#define S3C64XX_GPP10_MEM0_ATA_INPACK	(0x02 << 20)
-#define S3C64XX_GPP10_EINT_G8_10	(0x03 << 20)
-
-#define S3C64XX_GPP11_MEM0_ATA_REG	(0x02 << 22)
-#define S3C64XX_GPP11_EINT_G8_11	(0x03 << 22)
-
-#define S3C64XX_GPP12_MEM0_ATA_WE	(0x02 << 24)
-#define S3C64XX_GPP12_EINT_G8_12	(0x03 << 24)
-
-#define S3C64XX_GPP13_MEM0_ATA_OE	(0x02 << 26)
-#define S3C64XX_GPP13_EINT_G8_13	(0x03 << 26)
-
-#define S3C64XX_GPP14_MEM0_ATA_CD	(0x02 << 28)
-#define S3C64XX_GPP14_EINT_G8_14	(0x03 << 28)
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-q.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-q.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-q.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-q.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,46 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-q.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * 	Ben Dooks <ben@simtec.co.uk>
- * 	http://armlinux.simtec.co.uk/
- *
- * GPIO Bank Q register and configuration definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define S3C64XX_GPQCON			(S3C64XX_GPQ_BASE + 0x00)
-#define S3C64XX_GPQDAT			(S3C64XX_GPQ_BASE + 0x04)
-#define S3C64XX_GPQPUD			(S3C64XX_GPQ_BASE + 0x08)
-#define S3C64XX_GPQCONSLP		(S3C64XX_GPQ_BASE + 0x0c)
-#define S3C64XX_GPQPUDSLP		(S3C64XX_GPQ_BASE + 0x10)
-
-#define S3C64XX_GPQ_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
-#define S3C64XX_GPQ_INPUT(__gpio)	(0x0 << ((__gpio) * 2))
-#define S3C64XX_GPQ_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
-
-#define S3C64XX_GPQ0_MEM0_ADDR18_RAS	(0x02 << 0)
-#define S3C64XX_GPQ0_EINT_G9_0		(0x03 << 0)
-
-#define S3C64XX_GPQ1_MEM0_ADDR19_CAS	(0x02 << 2)
-#define S3C64XX_GPQ1_EINT_G9_1		(0x03 << 2)
-
-#define S3C64XX_GPQ2_EINT_G9_2		(0x03 << 4)
-
-#define S3C64XX_GPQ3_EINT_G9_3		(0x03 << 6)
-
-#define S3C64XX_GPQ4_EINT_G9_4		(0x03 << 8)
-
-#define S3C64XX_GPQ5_EINT_G9_5		(0x03 << 10)
-
-#define S3C64XX_GPQ6_EINT_G9_6		(0x03 << 12)
-
-#define S3C64XX_GPQ7_MEM0_ADDR17_WENDMC	(0x02 << 14)
-#define S3C64XX_GPQ7_EINT_G9_7		(0x03 << 14)
-
-#define S3C64XX_GPQ8_MEM0_ADDR16_APDMC	(0x02 << 16)
-#define S3C64XX_GPQ8_EINT_G9_8		(0x03 << 16)
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/irqs.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/irqs.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/irqs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/irqs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,210 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/mach/irqs.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C64XX - Common IRQ support
- */
-
-#ifndef __ASM_PLAT_S3C64XX_IRQS_H
-#define __ASM_PLAT_S3C64XX_IRQS_H __FILE__
-
-/* we keep the first set of CPU IRQs out of the range of
- * the ISA space, so that the PC104 has them to itself
- * and we don't end up having to do horrible things to the
- * standard ISA drivers....
- *
- * note, since we're using the VICs, our start must be a
- * mulitple of 32 to allow the common code to work
- */
-
-#define S3C_IRQ_OFFSET	(32)
-
-#define S3C_IRQ(x)	((x) + S3C_IRQ_OFFSET)
-
-#define S3C_VIC0_BASE	S3C_IRQ(0)
-#define S3C_VIC1_BASE	S3C_IRQ(32)
-
-/* UART interrupts, each UART has 4 intterupts per channel so
- * use the space between the ISA and S3C main interrupts. Note, these
- * are not in the same order as the S3C24XX series! */
-
-#define IRQ_S3CUART_BASE0	(16)
-#define IRQ_S3CUART_BASE1	(20)
-#define IRQ_S3CUART_BASE2	(24)
-#define IRQ_S3CUART_BASE3	(28)
-
-#define UART_IRQ_RXD		(0)
-#define UART_IRQ_ERR		(1)
-#define UART_IRQ_TXD		(2)
-#define UART_IRQ_MODEM		(3)
-
-#define IRQ_S3CUART_RX0		(IRQ_S3CUART_BASE0 + UART_IRQ_RXD)
-#define IRQ_S3CUART_TX0		(IRQ_S3CUART_BASE0 + UART_IRQ_TXD)
-#define IRQ_S3CUART_ERR0	(IRQ_S3CUART_BASE0 + UART_IRQ_ERR)
-
-#define IRQ_S3CUART_RX1		(IRQ_S3CUART_BASE1 + UART_IRQ_RXD)
-#define IRQ_S3CUART_TX1		(IRQ_S3CUART_BASE1 + UART_IRQ_TXD)
-#define IRQ_S3CUART_ERR1	(IRQ_S3CUART_BASE1 + UART_IRQ_ERR)
-
-#define IRQ_S3CUART_RX2		(IRQ_S3CUART_BASE2 + UART_IRQ_RXD)
-#define IRQ_S3CUART_TX2		(IRQ_S3CUART_BASE2 + UART_IRQ_TXD)
-#define IRQ_S3CUART_ERR2	(IRQ_S3CUART_BASE2 + UART_IRQ_ERR)
-
-#define IRQ_S3CUART_RX3		(IRQ_S3CUART_BASE3 + UART_IRQ_RXD)
-#define IRQ_S3CUART_TX3		(IRQ_S3CUART_BASE3 + UART_IRQ_TXD)
-#define IRQ_S3CUART_ERR3	(IRQ_S3CUART_BASE3 + UART_IRQ_ERR)
-
-/* VIC based IRQs */
-
-#define S3C64XX_IRQ_VIC0(x)	(S3C_VIC0_BASE + (x))
-#define S3C64XX_IRQ_VIC1(x)	(S3C_VIC1_BASE + (x))
-
-/* VIC0 */
-
-#define IRQ_EINT0_3		S3C64XX_IRQ_VIC0(0)
-#define IRQ_EINT4_11		S3C64XX_IRQ_VIC0(1)
-#define IRQ_RTC_TIC		S3C64XX_IRQ_VIC0(2)
-#define IRQ_CAMIF_C		S3C64XX_IRQ_VIC0(3)
-#define IRQ_CAMIF_P		S3C64XX_IRQ_VIC0(4)
-#define IRQ_CAMIF_MC		S3C64XX_IRQ_VIC0(5)
-#define IRQ_S3C6410_IIC1	S3C64XX_IRQ_VIC0(5)
-#define IRQ_S3C6410_IIS		S3C64XX_IRQ_VIC0(6)
-#define IRQ_S3C6400_CAMIF_MP	S3C64XX_IRQ_VIC0(6)
-#define IRQ_CAMIF_WE_C		S3C64XX_IRQ_VIC0(7)
-#define IRQ_S3C6410_G3D		S3C64XX_IRQ_VIC0(8)
-#define IRQ_S3C6400_CAMIF_WE_P	S3C64XX_IRQ_VIC0(8)
-#define IRQ_POST0		S3C64XX_IRQ_VIC0(9)
-#define IRQ_ROTATOR		S3C64XX_IRQ_VIC0(10)
-#define IRQ_2D			S3C64XX_IRQ_VIC0(11)
-#define IRQ_TVENC		S3C64XX_IRQ_VIC0(12)
-#define IRQ_SCALER		S3C64XX_IRQ_VIC0(13)
-#define IRQ_BATF		S3C64XX_IRQ_VIC0(14)
-#define IRQ_JPEG		S3C64XX_IRQ_VIC0(15)
-#define IRQ_MFC			S3C64XX_IRQ_VIC0(16)
-#define IRQ_SDMA0		S3C64XX_IRQ_VIC0(17)
-#define IRQ_SDMA1		S3C64XX_IRQ_VIC0(18)
-#define IRQ_ARM_DMAERR		S3C64XX_IRQ_VIC0(19)
-#define IRQ_ARM_DMA		S3C64XX_IRQ_VIC0(20)
-#define IRQ_ARM_DMAS		S3C64XX_IRQ_VIC0(21)
-#define IRQ_KEYPAD		S3C64XX_IRQ_VIC0(22)
-#define IRQ_TIMER0_VIC		S3C64XX_IRQ_VIC0(23)
-#define IRQ_TIMER1_VIC		S3C64XX_IRQ_VIC0(24)
-#define IRQ_TIMER2_VIC		S3C64XX_IRQ_VIC0(25)
-#define IRQ_WDT			S3C64XX_IRQ_VIC0(26)
-#define IRQ_TIMER3_VIC		S3C64XX_IRQ_VIC0(27)
-#define IRQ_TIMER4_VIC		S3C64XX_IRQ_VIC0(28)
-#define IRQ_LCD_FIFO		S3C64XX_IRQ_VIC0(29)
-#define IRQ_LCD_VSYNC		S3C64XX_IRQ_VIC0(30)
-#define IRQ_LCD_SYSTEM		S3C64XX_IRQ_VIC0(31)
-
-/* VIC1 */
-
-#define IRQ_EINT12_19		S3C64XX_IRQ_VIC1(0)
-#define IRQ_EINT20_27		S3C64XX_IRQ_VIC1(1)
-#define IRQ_PCM0		S3C64XX_IRQ_VIC1(2)
-#define IRQ_PCM1		S3C64XX_IRQ_VIC1(3)
-#define IRQ_AC97		S3C64XX_IRQ_VIC1(4)
-#define IRQ_UART0		S3C64XX_IRQ_VIC1(5)
-#define IRQ_UART1		S3C64XX_IRQ_VIC1(6)
-#define IRQ_UART2		S3C64XX_IRQ_VIC1(7)
-#define IRQ_UART3		S3C64XX_IRQ_VIC1(8)
-#define IRQ_DMA0		S3C64XX_IRQ_VIC1(9)
-#define IRQ_DMA1		S3C64XX_IRQ_VIC1(10)
-#define IRQ_ONENAND0		S3C64XX_IRQ_VIC1(11)
-#define IRQ_ONENAND1		S3C64XX_IRQ_VIC1(12)
-#define IRQ_NFC			S3C64XX_IRQ_VIC1(13)
-#define IRQ_CFCON		S3C64XX_IRQ_VIC1(14)
-#define IRQ_USBH		S3C64XX_IRQ_VIC1(15)
-#define IRQ_SPI0		S3C64XX_IRQ_VIC1(16)
-#define IRQ_SPI1		S3C64XX_IRQ_VIC1(17)
-#define IRQ_IIC			S3C64XX_IRQ_VIC1(18)
-#define IRQ_HSItx		S3C64XX_IRQ_VIC1(19)
-#define IRQ_HSIrx		S3C64XX_IRQ_VIC1(20)
-#define IRQ_RESERVED		S3C64XX_IRQ_VIC1(21)
-#define IRQ_MSM			S3C64XX_IRQ_VIC1(22)
-#define IRQ_HOSTIF		S3C64XX_IRQ_VIC1(23)
-#define IRQ_HSMMC0		S3C64XX_IRQ_VIC1(24)
-#define IRQ_HSMMC1		S3C64XX_IRQ_VIC1(25)
-#define IRQ_HSMMC2		IRQ_SPI1	/* shared with SPI1 */
-#define IRQ_OTG			S3C64XX_IRQ_VIC1(26)
-#define IRQ_IRDA		S3C64XX_IRQ_VIC1(27)
-#define IRQ_RTC_ALARM		S3C64XX_IRQ_VIC1(28)
-#define IRQ_SEC			S3C64XX_IRQ_VIC1(29)
-#define IRQ_PENDN		S3C64XX_IRQ_VIC1(30)
-#define IRQ_TC			IRQ_PENDN
-#define IRQ_ADC			S3C64XX_IRQ_VIC1(31)
-
-#define S3C64XX_TIMER_IRQ(x)	S3C_IRQ(64 + (x))
-
-#define IRQ_TIMER0		S3C64XX_TIMER_IRQ(0)
-#define IRQ_TIMER1		S3C64XX_TIMER_IRQ(1)
-#define IRQ_TIMER2		S3C64XX_TIMER_IRQ(2)
-#define IRQ_TIMER3		S3C64XX_TIMER_IRQ(3)
-#define IRQ_TIMER4		S3C64XX_TIMER_IRQ(4)
-
-/* compatibility for device defines */
-
-#define IRQ_IIC1		IRQ_S3C6410_IIC1
-
-/* Since the IRQ_EINT(x) are a linear mapping on current s3c64xx series
- * we just defined them as an IRQ_EINT(x) macro from S3C_IRQ_EINT_BASE
- * which we place after the pair of VICs. */
-
-#define S3C_IRQ_EINT_BASE	S3C_IRQ(64+5)
-
-#define S3C_EINT(x)		((x) + S3C_IRQ_EINT_BASE)
-#define IRQ_EINT(x)		S3C_EINT(x)
-#define IRQ_EINT_BIT(x)		((x) - S3C_EINT(0))
-
-/* Next the external interrupt groups. These are similar to the IRQ_EINT(x)
- * that they are sourced from the GPIO pins but with a different scheme for
- * priority and source indication.
- *
- * The IRQ_EINT(x) can be thought of as 'group 0' of the available GPIO
- * interrupts, but for historical reasons they are kept apart from these
- * next interrupts.
- *
- * Use IRQ_EINT_GROUP(group, offset) to get the number for use in the
- * machine specific support files.
- */
-
-#define IRQ_EINT_GROUP1_NR	(15)
-#define IRQ_EINT_GROUP2_NR	(8)
-#define IRQ_EINT_GROUP3_NR	(5)
-#define IRQ_EINT_GROUP4_NR	(14)
-#define IRQ_EINT_GROUP5_NR	(7)
-#define IRQ_EINT_GROUP6_NR	(10)
-#define IRQ_EINT_GROUP7_NR	(16)
-#define IRQ_EINT_GROUP8_NR	(15)
-#define IRQ_EINT_GROUP9_NR	(9)
-
-#define IRQ_EINT_GROUP_BASE	S3C_EINT(28)
-#define IRQ_EINT_GROUP1_BASE	(IRQ_EINT_GROUP_BASE + 0x00)
-#define IRQ_EINT_GROUP2_BASE	(IRQ_EINT_GROUP1_BASE + IRQ_EINT_GROUP1_NR)
-#define IRQ_EINT_GROUP3_BASE	(IRQ_EINT_GROUP2_BASE + IRQ_EINT_GROUP2_NR)
-#define IRQ_EINT_GROUP4_BASE	(IRQ_EINT_GROUP3_BASE + IRQ_EINT_GROUP3_NR)
-#define IRQ_EINT_GROUP5_BASE	(IRQ_EINT_GROUP4_BASE + IRQ_EINT_GROUP4_NR)
-#define IRQ_EINT_GROUP6_BASE	(IRQ_EINT_GROUP5_BASE + IRQ_EINT_GROUP5_NR)
-#define IRQ_EINT_GROUP7_BASE	(IRQ_EINT_GROUP6_BASE + IRQ_EINT_GROUP6_NR)
-#define IRQ_EINT_GROUP8_BASE	(IRQ_EINT_GROUP7_BASE + IRQ_EINT_GROUP7_NR)
-#define IRQ_EINT_GROUP9_BASE	(IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR)
-
-#define IRQ_EINT_GROUP(group, no)	(IRQ_EINT_GROUP##group##_BASE + (no))
-
-/* Define a group of interrupts for board-specific use (eg, for MFD
- * interrupt controllers). */
-#define IRQ_BOARD_START (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1)
-
-#define IRQ_BOARD_NR 16
-
-#define IRQ_BOARD_END (IRQ_BOARD_START + IRQ_BOARD_NR)
-
-/* Set the default NR_IRQS */
-
-#define NR_IRQS	(IRQ_BOARD_END + 1)
-
-#endif /* __ASM_PLAT_S3C64XX_IRQS_H */
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/pll.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/pll.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/pll.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/pll.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,74 +0,0 @@
-/* arch/arm/plat-s3c64xx/include/plat/pll.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C64XX PLL 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.
-*/
-
-#define S3C6400_PLL_MDIV_MASK	((1 << (25-16+1)) - 1)
-#define S3C6400_PLL_PDIV_MASK	((1 << (13-8+1)) - 1)
-#define S3C6400_PLL_SDIV_MASK	((1 << (2-0+1)) - 1)
-#define S3C6400_PLL_MDIV_SHIFT	(16)
-#define S3C6400_PLL_PDIV_SHIFT	(8)
-#define S3C6400_PLL_SDIV_SHIFT	(0)
-
-#include <asm/div64.h>
-
-static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
-					    u32 pllcon)
-{
-	u32 mdiv, pdiv, sdiv;
-	u64 fvco = baseclk;
-
-	mdiv = (pllcon >> S3C6400_PLL_MDIV_SHIFT) & S3C6400_PLL_MDIV_MASK;
-	pdiv = (pllcon >> S3C6400_PLL_PDIV_SHIFT) & S3C6400_PLL_PDIV_MASK;
-	sdiv = (pllcon >> S3C6400_PLL_SDIV_SHIFT) & S3C6400_PLL_SDIV_MASK;
-
-	fvco *= mdiv;
-	do_div(fvco, (pdiv << sdiv));
-
-	return (unsigned long)fvco;
-}
-
-#define S3C6400_EPLL_MDIV_MASK	((1 << (23-16)) - 1)
-#define S3C6400_EPLL_PDIV_MASK	((1 << (13-8)) - 1)
-#define S3C6400_EPLL_SDIV_MASK	((1 << (2-0)) - 1)
-#define S3C6400_EPLL_MDIV_SHIFT	(16)
-#define S3C6400_EPLL_PDIV_SHIFT	(8)
-#define S3C6400_EPLL_SDIV_SHIFT	(0)
-#define S3C6400_EPLL_KDIV_MASK  (0xffff)
-
-static inline unsigned long s3c6400_get_epll(unsigned long baseclk)
-{
-	unsigned long result;
-	u32 epll0 = __raw_readl(S3C_EPLL_CON0);
-	u32 epll1 = __raw_readl(S3C_EPLL_CON1);
-	u32 mdiv, pdiv, sdiv, kdiv;
-	u64 tmp;
-
-	mdiv = (epll0 >> S3C6400_EPLL_MDIV_SHIFT) & S3C6400_EPLL_MDIV_MASK;
-	pdiv = (epll0 >> S3C6400_EPLL_PDIV_SHIFT) & S3C6400_EPLL_PDIV_MASK;
-	sdiv = (epll0 >> S3C6400_EPLL_SDIV_SHIFT) & S3C6400_EPLL_SDIV_MASK;
-	kdiv = epll1 & S3C6400_EPLL_KDIV_MASK;
-
-	/* We need to multiple baseclk by mdiv (the integer part) and kdiv
-	 * which is in 2^16ths, so shift mdiv up (does not overflow) and
-	 * add kdiv before multiplying. The use of tmp is to avoid any
-	 * overflows before shifting bac down into result when multipling
-	 * by the mdiv and kdiv pair.
-	 */
-
-	tmp = baseclk;
-	tmp *= (mdiv << 16) + kdiv;
-	do_div(tmp, (pdiv << sdiv));
-	result = tmp >> 16;
-
-	return result;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/pm-core.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/pm-core.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/pm-core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/pm-core.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,98 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/pm-core.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C64XX - 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.
- */
-
-#include <plat/regs-gpio.h>
-
-static inline void s3c_pm_debug_init_uart(void)
-{
-	u32 tmp = __raw_readl(S3C_PCLK_GATE);
-
-	/* As a note, since the S3C64XX UARTs generally have multiple
-	 * clock sources, we simply enable PCLK at the moment and hope
-	 * that the resume settings for the UART are suitable for the
-	 * use with PCLK.
-	 */
-
-	tmp |= S3C_CLKCON_PCLK_UART0;
-	tmp |= S3C_CLKCON_PCLK_UART1;
-	tmp |= S3C_CLKCON_PCLK_UART2;
-	tmp |= S3C_CLKCON_PCLK_UART3;
-
-	__raw_writel(tmp, S3C_PCLK_GATE);
-	udelay(10);
-}
-
-static inline void s3c_pm_arch_prepare_irqs(void)
-{
-	/* VIC should have already been taken care of */
-
-	/* clear any pending EINT0 interrupts */
-	__raw_writel(__raw_readl(S3C64XX_EINT0PEND), S3C64XX_EINT0PEND);
-}
-
-static inline void s3c_pm_arch_stop_clocks(void)
-{
-}
-
-static inline void s3c_pm_arch_show_resume_irqs(void)
-{
-}
-
-/* make these defines, we currently do not have any need to change
- * the IRQ wake controls depending on the CPU we are running on */
-
-#define s3c_irqwake_eintallow	((1 << 28) - 1)
-#define s3c_irqwake_intallow	(0)
-
-static inline void s3c_pm_arch_update_uart(void __iomem *regs,
-					   struct pm_uart_save *save)
-{
-	u32 ucon = __raw_readl(regs + S3C2410_UCON);
-	u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK;
-	u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK;
-	u32 new_ucon;
-	u32 delta;
-
-	/* S3C64XX UART blocks only support level interrupts, so ensure that
-	 * when we restore unused UART blocks we force the level interrupt
-	 * settigs. */
-	save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL;
-
-	/* We have a constraint on changing the clock type of the UART
-	 * between UCLKx and PCLK, so ensure that when we restore UCON
-	 * that the CLK field is correctly modified if the bootloader
-	 * has changed anything.
-	 */
-	if (ucon_clk != save_clk) {
-		new_ucon = save->ucon;
-		delta = ucon_clk ^ save_clk;
-
-		/* change from UCLKx => wrong PCLK,
-		 * either UCLK can be tested for by a bit-test
-		 * with UCLK0 */
-		if (ucon_clk & S3C6400_UCON_UCLK0 &&
-		    !(save_clk & S3C6400_UCON_UCLK0) &&
-		    delta & S3C6400_UCON_PCLK2) {
-			new_ucon &= ~S3C6400_UCON_UCLK0;
-		} else if (delta == S3C6400_UCON_PCLK2) {
-			/* as an precaution, don't change from
-			 * PCLK2 => PCLK or vice-versa */
-			new_ucon ^= S3C6400_UCON_PCLK2;
-		}
-
-		S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n",
-			  ucon, new_ucon, save->ucon);
-		save->ucon = new_ucon;
-	}
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-clock.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-clock.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,225 +0,0 @@
-/* arch/arm/plat-s3c64xx/include/plat/regs-clock.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C64XX clock register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __PLAT_REGS_CLOCK_H
-#define __PLAT_REGS_CLOCK_H __FILE__
-
-#define S3C_CLKREG(x)		(S3C_VA_SYS + (x))
-
-#define S3C_APLL_LOCK		S3C_CLKREG(0x00)
-#define S3C_MPLL_LOCK		S3C_CLKREG(0x04)
-#define S3C_EPLL_LOCK		S3C_CLKREG(0x08)
-#define S3C_APLL_CON		S3C_CLKREG(0x0C)
-#define S3C_MPLL_CON		S3C_CLKREG(0x10)
-#define S3C_EPLL_CON0		S3C_CLKREG(0x14)
-#define S3C_EPLL_CON1		S3C_CLKREG(0x18)
-#define S3C_CLK_SRC		S3C_CLKREG(0x1C)
-#define S3C_CLK_DIV0		S3C_CLKREG(0x20)
-#define S3C_CLK_DIV1		S3C_CLKREG(0x24)
-#define S3C_CLK_DIV2		S3C_CLKREG(0x28)
-#define S3C_CLK_OUT		S3C_CLKREG(0x2C)
-#define S3C_HCLK_GATE		S3C_CLKREG(0x30)
-#define S3C_PCLK_GATE		S3C_CLKREG(0x34)
-#define S3C_SCLK_GATE		S3C_CLKREG(0x38)
-#define S3C_MEM0_GATE		S3C_CLKREG(0x3C)
-
-/* CLKDIV0 */
-#define S3C6400_CLKDIV0_MFC_MASK	(0xf << 28)
-#define S3C6400_CLKDIV0_MFC_SHIFT	(28)
-#define S3C6400_CLKDIV0_JPEG_MASK	(0xf << 24)
-#define S3C6400_CLKDIV0_JPEG_SHIFT	(24)
-#define S3C6400_CLKDIV0_CAM_MASK	(0xf << 20)
-#define S3C6400_CLKDIV0_CAM_SHIFT	(20)
-#define S3C6400_CLKDIV0_SECURITY_MASK	(0x3 << 18)
-#define S3C6400_CLKDIV0_SECURITY_SHIFT	(18)
-#define S3C6400_CLKDIV0_PCLK_MASK	(0xf << 12)
-#define S3C6400_CLKDIV0_PCLK_SHIFT	(12)
-#define S3C6400_CLKDIV0_HCLK2_MASK	(0x7 << 9)
-#define S3C6400_CLKDIV0_HCLK2_SHIFT	(9)
-#define S3C6400_CLKDIV0_HCLK_MASK	(0x1 << 8)
-#define S3C6400_CLKDIV0_HCLK_SHIFT	(8)
-#define S3C6400_CLKDIV0_MPLL_MASK	(0x1 << 4)
-#define S3C6400_CLKDIV0_MPLL_SHIFT	(4)
-#define S3C6400_CLKDIV0_ARM_MASK	(0x7 << 0)
-#define S3C6410_CLKDIV0_ARM_MASK	(0xf << 0)
-#define S3C6400_CLKDIV0_ARM_SHIFT	(0)
-
-/* CLKDIV1 */
-#define S3C6410_CLKDIV1_FIMC_MASK	(0xf << 24)
-#define S3C6410_CLKDIV1_FIMC_SHIFT	(24)
-#define S3C6400_CLKDIV1_UHOST_MASK	(0xf << 20)
-#define S3C6400_CLKDIV1_UHOST_SHIFT	(20)
-#define S3C6400_CLKDIV1_SCALER_MASK	(0xf << 16)
-#define S3C6400_CLKDIV1_SCALER_SHIFT	(16)
-#define S3C6400_CLKDIV1_LCD_MASK	(0xf << 12)
-#define S3C6400_CLKDIV1_LCD_SHIFT	(12)
-#define S3C6400_CLKDIV1_MMC2_MASK	(0xf << 8)
-#define S3C6400_CLKDIV1_MMC2_SHIFT	(8)
-#define S3C6400_CLKDIV1_MMC1_MASK	(0xf << 4)
-#define S3C6400_CLKDIV1_MMC1_SHIFT	(4)
-#define S3C6400_CLKDIV1_MMC0_MASK	(0xf << 0)
-#define S3C6400_CLKDIV1_MMC0_SHIFT	(0)
-
-/* CLKDIV2 */
-#define S3C6410_CLKDIV2_AUDIO2_MASK	(0xf << 24)
-#define S3C6410_CLKDIV2_AUDIO2_SHIFT	(24)
-#define S3C6400_CLKDIV2_IRDA_MASK	(0xf << 20)
-#define S3C6400_CLKDIV2_IRDA_SHIFT	(20)
-#define S3C6400_CLKDIV2_UART_MASK	(0xf << 16)
-#define S3C6400_CLKDIV2_UART_SHIFT	(16)
-#define S3C6400_CLKDIV2_AUDIO1_MASK	(0xf << 12)
-#define S3C6400_CLKDIV2_AUDIO1_SHIFT	(12)
-#define S3C6400_CLKDIV2_AUDIO0_MASK	(0xf << 8)
-#define S3C6400_CLKDIV2_AUDIO0_SHIFT	(8)
-#define S3C6400_CLKDIV2_SPI1_MASK	(0xf << 4)
-#define S3C6400_CLKDIV2_SPI1_SHIFT	(4)
-#define S3C6400_CLKDIV2_SPI0_MASK	(0xf << 0)
-#define S3C6400_CLKDIV2_SPI0_SHIFT	(0)
-
-/* HCLK GATE Registers */
-#define S3C_CLKCON_HCLK_3DSE	(1<<31)
-#define S3C_CLKCON_HCLK_UHOST	(1<<29)
-#define S3C_CLKCON_HCLK_SECUR	(1<<28)
-#define S3C_CLKCON_HCLK_SDMA1	(1<<27)
-#define S3C_CLKCON_HCLK_SDMA0	(1<<26)
-#define S3C_CLKCON_HCLK_IROM	(1<<25)
-#define S3C_CLKCON_HCLK_DDR1	(1<<24)
-#define S3C_CLKCON_HCLK_DDR0	(1<<23)
-#define S3C_CLKCON_HCLK_MEM1	(1<<22)
-#define S3C_CLKCON_HCLK_MEM0	(1<<21)
-#define S3C_CLKCON_HCLK_USB	(1<<20)
-#define S3C_CLKCON_HCLK_HSMMC2	(1<<19)
-#define S3C_CLKCON_HCLK_HSMMC1	(1<<18)
-#define S3C_CLKCON_HCLK_HSMMC0	(1<<17)
-#define S3C_CLKCON_HCLK_MDP	(1<<16)
-#define S3C_CLKCON_HCLK_DHOST	(1<<15)
-#define S3C_CLKCON_HCLK_IHOST	(1<<14)
-#define S3C_CLKCON_HCLK_DMA1	(1<<13)
-#define S3C_CLKCON_HCLK_DMA0	(1<<12)
-#define S3C_CLKCON_HCLK_JPEG	(1<<11)
-#define S3C_CLKCON_HCLK_CAMIF	(1<<10)
-#define S3C_CLKCON_HCLK_SCALER	(1<<9)
-#define S3C_CLKCON_HCLK_2D	(1<<8)
-#define S3C_CLKCON_HCLK_TV	(1<<7)
-#define S3C_CLKCON_HCLK_POST0	(1<<5)
-#define S3C_CLKCON_HCLK_ROT	(1<<4)
-#define S3C_CLKCON_HCLK_LCD	(1<<3)
-#define S3C_CLKCON_HCLK_TZIC	(1<<2)
-#define S3C_CLKCON_HCLK_INTC	(1<<1)
-#define S3C_CLKCON_HCLK_MFC	(1<<0)
-
-/* PCLK GATE Registers */
-#define S3C6410_CLKCON_PCLK_I2C1	(1<<27)
-#define S3C6410_CLKCON_PCLK_IIS2	(1<<26)
-#define S3C_CLKCON_PCLK_SKEY		(1<<24)
-#define S3C_CLKCON_PCLK_CHIPID		(1<<23)
-#define S3C_CLKCON_PCLK_SPI1		(1<<22)
-#define S3C_CLKCON_PCLK_SPI0		(1<<21)
-#define S3C_CLKCON_PCLK_HSIRX		(1<<20)
-#define S3C_CLKCON_PCLK_HSITX		(1<<19)
-#define S3C_CLKCON_PCLK_GPIO		(1<<18)
-#define S3C_CLKCON_PCLK_IIC		(1<<17)
-#define S3C_CLKCON_PCLK_IIS1		(1<<16)
-#define S3C_CLKCON_PCLK_IIS0		(1<<15)
-#define S3C_CLKCON_PCLK_AC97		(1<<14)
-#define S3C_CLKCON_PCLK_TZPC		(1<<13)
-#define S3C_CLKCON_PCLK_TSADC		(1<<12)
-#define S3C_CLKCON_PCLK_KEYPAD		(1<<11)
-#define S3C_CLKCON_PCLK_IRDA		(1<<10)
-#define S3C_CLKCON_PCLK_PCM1		(1<<9)
-#define S3C_CLKCON_PCLK_PCM0		(1<<8)
-#define S3C_CLKCON_PCLK_PWM		(1<<7)
-#define S3C_CLKCON_PCLK_RTC		(1<<6)
-#define S3C_CLKCON_PCLK_WDT		(1<<5)
-#define S3C_CLKCON_PCLK_UART3		(1<<4)
-#define S3C_CLKCON_PCLK_UART2		(1<<3)
-#define S3C_CLKCON_PCLK_UART1		(1<<2)
-#define S3C_CLKCON_PCLK_UART0		(1<<1)
-#define S3C_CLKCON_PCLK_MFC		(1<<0)
-
-/* SCLK GATE Registers */
-#define S3C_CLKCON_SCLK_UHOST		(1<<30)
-#define S3C_CLKCON_SCLK_MMC2_48		(1<<29)
-#define S3C_CLKCON_SCLK_MMC1_48		(1<<28)
-#define S3C_CLKCON_SCLK_MMC0_48		(1<<27)
-#define S3C_CLKCON_SCLK_MMC2		(1<<26)
-#define S3C_CLKCON_SCLK_MMC1		(1<<25)
-#define S3C_CLKCON_SCLK_MMC0		(1<<24)
-#define S3C_CLKCON_SCLK_SPI1_48 	(1<<23)
-#define S3C_CLKCON_SCLK_SPI0_48 	(1<<22)
-#define S3C_CLKCON_SCLK_SPI1		(1<<21)
-#define S3C_CLKCON_SCLK_SPI0		(1<<20)
-#define S3C_CLKCON_SCLK_DAC27		(1<<19)
-#define S3C_CLKCON_SCLK_TV27		(1<<18)
-#define S3C_CLKCON_SCLK_SCALER27	(1<<17)
-#define S3C_CLKCON_SCLK_SCALER		(1<<16)
-#define S3C_CLKCON_SCLK_LCD27		(1<<15)
-#define S3C_CLKCON_SCLK_LCD		(1<<14)
-#define S3C6400_CLKCON_SCLK_POST1_27	(1<<13)
-#define S3C6410_CLKCON_FIMC		(1<<13)
-#define S3C_CLKCON_SCLK_POST0_27	(1<<12)
-#define S3C6400_CLKCON_SCLK_POST1	(1<<11)
-#define S3C6410_CLKCON_SCLK_AUDIO2	(1<<11)
-#define S3C_CLKCON_SCLK_POST0		(1<<10)
-#define S3C_CLKCON_SCLK_AUDIO1		(1<<9)
-#define S3C_CLKCON_SCLK_AUDIO0		(1<<8)
-#define S3C_CLKCON_SCLK_SECUR		(1<<7)
-#define S3C_CLKCON_SCLK_IRDA		(1<<6)
-#define S3C_CLKCON_SCLK_UART		(1<<5)
-#define S3C_CLKCON_SCLK_ONENAND 	(1<<4)
-#define S3C_CLKCON_SCLK_MFC		(1<<3)
-#define S3C_CLKCON_SCLK_CAM		(1<<2)
-#define S3C_CLKCON_SCLK_JPEG		(1<<1)
-
-/* CLKSRC */
-
-#define S3C6400_CLKSRC_APLL_MOUT	(1 << 0)
-#define S3C6400_CLKSRC_MPLL_MOUT	(1 << 1)
-#define S3C6400_CLKSRC_EPLL_MOUT	(1 << 2)
-#define S3C6400_CLKSRC_APLL_MOUT_SHIFT	(0)
-#define S3C6400_CLKSRC_MPLL_MOUT_SHIFT	(1)
-#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT	(2)
-#define S3C6400_CLKSRC_MFC		(1 << 4)
-
-#define S3C6410_CLKSRC_TV27_MASK	(0x1 << 31)
-#define S3C6410_CLKSRC_TV27_SHIFT	(31)
-#define S3C6410_CLKSRC_DAC27_MASK	(0x1 << 30)
-#define S3C6410_CLKSRC_DAC27_SHIFT	(30)
-#define S3C6400_CLKSRC_SCALER_MASK	(0x3 << 28)
-#define S3C6400_CLKSRC_SCALER_SHIFT	(28)
-#define S3C6400_CLKSRC_LCD_MASK		(0x3 << 26)
-#define S3C6400_CLKSRC_LCD_SHIFT	(26)
-#define S3C6400_CLKSRC_IRDA_MASK	(0x3 << 24)
-#define S3C6400_CLKSRC_IRDA_SHIFT	(24)
-#define S3C6400_CLKSRC_MMC2_MASK	(0x3 << 22)
-#define S3C6400_CLKSRC_MMC2_SHIFT	(22)
-#define S3C6400_CLKSRC_MMC1_MASK	(0x3 << 20)
-#define S3C6400_CLKSRC_MMC1_SHIFT	(20)
-#define S3C6400_CLKSRC_MMC0_MASK	(0x3 << 18)
-#define S3C6400_CLKSRC_MMC0_SHIFT	(18)
-#define S3C6400_CLKSRC_SPI1_MASK	(0x3 << 16)
-#define S3C6400_CLKSRC_SPI1_SHIFT	(16)
-#define S3C6400_CLKSRC_SPI0_MASK	(0x3 << 14)
-#define S3C6400_CLKSRC_SPI0_SHIFT	(14)
-#define S3C6400_CLKSRC_UART_MASK	(0x1 << 13)
-#define S3C6400_CLKSRC_UART_SHIFT	(13)
-#define S3C6400_CLKSRC_AUDIO1_MASK	(0x7 << 10)
-#define S3C6400_CLKSRC_AUDIO1_SHIFT	(10)
-#define S3C6400_CLKSRC_AUDIO0_MASK	(0x7 << 7)
-#define S3C6400_CLKSRC_AUDIO0_SHIFT	(7)
-#define S3C6400_CLKSRC_UHOST_MASK	(0x3 << 5)
-#define S3C6400_CLKSRC_UHOST_SHIFT	(5)
-
-
-#endif /* _PLAT_REGS_CLOCK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,187 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/mach/regs-gpio.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C64XX - GPIO register definitions
- */
-
-#ifndef __ASM_PLAT_S3C64XX_REGS_GPIO_H
-#define __ASM_PLAT_S3C64XX_REGS_GPIO_H __FILE__
-
-/* Base addresses for each of the banks */
-
-#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.33-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-/* 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.33-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-modem.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-modem.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-modem.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-modem.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,31 +0,0 @@
-/* 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.33-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,116 +0,0 @@
-/* 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.33-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-sys.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-sys.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-sys.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-sys.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,28 +0,0 @@
-/* arch/arm/plat-s3c64xx/include/plat/regs-sys.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C64XX system register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __PLAT_REGS_SYS_H
-#define __PLAT_REGS_SYS_H __FILE__
-
-#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)
-
-#endif /* _PLAT_REGS_SYS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/s3c6400.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/s3c6400.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/s3c6400.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/s3c6400.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,36 +0,0 @@
-/* arch/arm/plat-s3c64xx/include/plat/s3c6400.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * Header file for s3c6400 cpu 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.
-*/
-
-/* Common init code for S3C6400 related SoCs */
-
-extern void s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-extern void s3c6400_register_clocks(unsigned armclk_divlimit);
-extern void s3c6400_setup_clocks(void);
-
-#ifdef CONFIG_CPU_S3C6400
-
-extern  int s3c6400_init(void);
-extern void s3c6400_init_irq(void);
-extern void s3c6400_map_io(void);
-extern void s3c6400_init_clocks(int xtal);
-
-#define s3c6400_init_uarts s3c6400_common_init_uarts
-
-#else
-#define s3c6400_init_clocks NULL
-#define s3c6400_init_uarts NULL
-#define s3c6400_map_io NULL
-#define s3c6400_init NULL
-#endif
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/s3c6410.h linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/s3c6410.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/s3c6410.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/include/plat/s3c6410.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,29 +0,0 @@
-/* arch/arm/plat-s3c64xx/include/plat/s3c6410.h
- *
- * Copyright 2008 Openmoko,  Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * Header file for s3c6410 cpu 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.
-*/
-
-#ifdef CONFIG_CPU_S3C6410
-
-extern  int s3c6410_init(void);
-extern void s3c6410_init_irq(void);
-extern void s3c6410_map_io(void);
-extern void s3c6410_init_clocks(int xtal);
-
-#define s3c6410_init_uarts s3c6400_common_init_uarts
-
-#else
-#define s3c6410_init_clocks NULL
-#define s3c6410_init_uarts NULL
-#define s3c6410_map_io NULL
-#define s3c6410_init NULL
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/irq.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/irq.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/irq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,256 +0,0 @@
-/* arch/arm/plat-s3c64xx/irq.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C64XX - Interrupt handling
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/serial_core.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include <asm/hardware/vic.h>
-
-#include <mach/map.h>
-#include <plat/regs-serial.h>
-#include <plat/regs-timer.h>
-#include <plat/cpu.h>
-
-/* Timer interrupt handling */
-
-static void s3c_irq_demux_timer(unsigned int base_irq, unsigned int sub_irq)
-{
-	generic_handle_irq(sub_irq);
-}
-
-static void s3c_irq_demux_timer0(unsigned int irq, struct irq_desc *desc)
-{
-	s3c_irq_demux_timer(irq, IRQ_TIMER0);
-}
-
-static void s3c_irq_demux_timer1(unsigned int irq, struct irq_desc *desc)
-{
-	s3c_irq_demux_timer(irq, IRQ_TIMER1);
-}
-
-static void s3c_irq_demux_timer2(unsigned int irq, struct irq_desc *desc)
-{
-	s3c_irq_demux_timer(irq, IRQ_TIMER2);
-}
-
-static void s3c_irq_demux_timer3(unsigned int irq, struct irq_desc *desc)
-{
-	s3c_irq_demux_timer(irq, IRQ_TIMER3);
-}
-
-static void s3c_irq_demux_timer4(unsigned int irq, struct irq_desc *desc)
-{
-	s3c_irq_demux_timer(irq, IRQ_TIMER4);
-}
-
-/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
-
-static void s3c_irq_timer_mask(unsigned int irq)
-{
-	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
-
-	reg &= 0x1f;  /* mask out pending interrupts */
-	reg &= ~(1 << (irq - IRQ_TIMER0));
-	__raw_writel(reg, S3C64XX_TINT_CSTAT);
-}
-
-static void s3c_irq_timer_unmask(unsigned int irq)
-{
-	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
-
-	reg &= 0x1f;  /* mask out pending interrupts */
-	reg |= 1 << (irq - IRQ_TIMER0);
-	__raw_writel(reg, S3C64XX_TINT_CSTAT);
-}
-
-static void s3c_irq_timer_ack(unsigned int irq)
-{
-	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
-
-	reg &= 0x1f;
-	reg |= (1 << 5) << (irq - IRQ_TIMER0);
-	__raw_writel(reg, S3C64XX_TINT_CSTAT);
-}
-
-static struct irq_chip s3c_irq_timer = {
-	.name		= "s3c-timer",
-	.mask		= s3c_irq_timer_mask,
-	.unmask		= s3c_irq_timer_unmask,
-	.ack		= s3c_irq_timer_ack,
-};
-
-struct uart_irq {
-	void __iomem	*regs;
-	unsigned int	 base_irq;
-	unsigned int	 parent_irq;
-};
-
-/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
- * are consecutive when looking up the interrupt in the demux routines.
- */
-static struct uart_irq uart_irqs[] = {
-	[0] = {
-		.regs		= S3C_VA_UART0,
-		.base_irq	= IRQ_S3CUART_BASE0,
-		.parent_irq	= IRQ_UART0,
-	},
-	[1] = {
-		.regs		= S3C_VA_UART1,
-		.base_irq	= IRQ_S3CUART_BASE1,
-		.parent_irq	= IRQ_UART1,
-	},
-	[2] = {
-		.regs		= S3C_VA_UART2,
-		.base_irq	= IRQ_S3CUART_BASE2,
-		.parent_irq	= IRQ_UART2,
-	},
-	[3] = {
-		.regs		= S3C_VA_UART3,
-		.base_irq	= IRQ_S3CUART_BASE3,
-		.parent_irq	= IRQ_UART3,
-	},
-};
-
-static inline void __iomem *s3c_irq_uart_base(unsigned int irq)
-{
-	struct uart_irq *uirq = get_irq_chip_data(irq);
-	return uirq->regs;
-}
-
-static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
-{
-	return irq & 3;
-}
-
-/* UART interrupt registers, not worth adding to seperate include header */
-
-static void s3c_irq_uart_mask(unsigned int irq)
-{
-	void __iomem *regs = s3c_irq_uart_base(irq);
-	unsigned int bit = s3c_irq_uart_bit(irq);
-	u32 reg;
-
-	reg = __raw_readl(regs + S3C64XX_UINTM);
-	reg |= (1 << bit);
-	__raw_writel(reg, regs + S3C64XX_UINTM);
-}
-
-static void s3c_irq_uart_maskack(unsigned int irq)
-{
-	void __iomem *regs = s3c_irq_uart_base(irq);
-	unsigned int bit = s3c_irq_uart_bit(irq);
-	u32 reg;
-
-	reg = __raw_readl(regs + S3C64XX_UINTM);
-	reg |= (1 << bit);
-	__raw_writel(reg, regs + S3C64XX_UINTM);
-	__raw_writel(1 << bit, regs + S3C64XX_UINTP);
-}
-
-static void s3c_irq_uart_unmask(unsigned int irq)
-{
-	void __iomem *regs = s3c_irq_uart_base(irq);
-	unsigned int bit = s3c_irq_uart_bit(irq);
-	u32 reg;
-
-	reg = __raw_readl(regs + S3C64XX_UINTM);
-	reg &= ~(1 << bit);
-	__raw_writel(reg, regs + S3C64XX_UINTM);
-}
-
-static void s3c_irq_uart_ack(unsigned int irq)
-{
-	void __iomem *regs = s3c_irq_uart_base(irq);
-	unsigned int bit = s3c_irq_uart_bit(irq);
-
-	__raw_writel(1 << bit, regs + S3C64XX_UINTP);
-}
-
-static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
-{
-	struct uart_irq *uirq = &uart_irqs[irq - IRQ_UART0];
-	u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
-	int base = uirq->base_irq;
-
-	if (pend & (1 << 0))
-		generic_handle_irq(base);
-	if (pend & (1 << 1))
-		generic_handle_irq(base + 1);
-	if (pend & (1 << 2))
-		generic_handle_irq(base + 2);
-	if (pend & (1 << 3))
-		generic_handle_irq(base + 3);
-}
-
-static struct irq_chip s3c_irq_uart = {
-	.name		= "s3c-uart",
-	.mask		= s3c_irq_uart_mask,
-	.unmask		= s3c_irq_uart_unmask,
-	.mask_ack	= s3c_irq_uart_maskack,
-	.ack		= s3c_irq_uart_ack,
-};
-
-static void __init s3c64xx_uart_irq(struct uart_irq *uirq)
-{
-	void __iomem *reg_base = uirq->regs;
-	unsigned int irq;
-	int offs;
-
-	/* mask all interrupts at the start. */
-	__raw_writel(0xf, reg_base + S3C64XX_UINTM);
-
-	for (offs = 0; offs < 3; offs++) {
-		irq = uirq->base_irq + offs;
-
-		set_irq_chip(irq, &s3c_irq_uart);
-		set_irq_chip_data(irq, uirq);
-		set_irq_handler(irq, handle_level_irq);
-		set_irq_flags(irq, IRQF_VALID);
-	}
-
-	set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
-}
-
-void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
-{
-	int uart, irq;
-
-	printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
-
-	/* initialise the pair of VICs */
-	vic_init(S3C_VA_VIC0, S3C_VIC0_BASE, vic0_valid, 0);
-	vic_init(S3C_VA_VIC1, S3C_VIC1_BASE, vic1_valid, 0);
-
-	/* add the timer sub-irqs */
-
-	set_irq_chained_handler(IRQ_TIMER0_VIC, s3c_irq_demux_timer0);
-	set_irq_chained_handler(IRQ_TIMER1_VIC, s3c_irq_demux_timer1);
-	set_irq_chained_handler(IRQ_TIMER2_VIC, s3c_irq_demux_timer2);
-	set_irq_chained_handler(IRQ_TIMER3_VIC, s3c_irq_demux_timer3);
-	set_irq_chained_handler(IRQ_TIMER4_VIC, s3c_irq_demux_timer4);
-
-	for (irq = IRQ_TIMER0; irq <= IRQ_TIMER4; irq++) {
-		set_irq_chip(irq, &s3c_irq_timer);
-		set_irq_handler(irq, handle_level_irq);
-		set_irq_flags(irq, IRQF_VALID);
-	}
-
-	for (uart = 0; uart < ARRAY_SIZE(uart_irqs); uart++)
-		s3c64xx_uart_irq(&uart_irqs[uart]);
-}
-
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/irq-eint.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/irq-eint.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/irq-eint.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/irq-eint.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,213 +0,0 @@
-/* arch/arm/plat-s3c64xx/irq-eint.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C64XX - Interrupt handling for IRQ_EINT(x)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/sysdev.h>
-#include <linux/gpio.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include <asm/hardware/vic.h>
-
-#include <plat/regs-irqtype.h>
-#include <plat/regs-gpio.h>
-#include <plat/gpio-cfg.h>
-
-#include <mach/map.h>
-#include <plat/cpu.h>
-#include <plat/pm.h>
-
-#define eint_offset(irq)	((irq) - IRQ_EINT(0))
-#define eint_irq_to_bit(irq)	(1 << eint_offset(irq))
-
-static inline void s3c_irq_eint_mask(unsigned int irq)
-{
-	u32 mask;
-
-	mask = __raw_readl(S3C64XX_EINT0MASK);
-	mask |= eint_irq_to_bit(irq);
-	__raw_writel(mask, S3C64XX_EINT0MASK);
-}
-
-static void s3c_irq_eint_unmask(unsigned int irq)
-{
-	u32 mask;
-
-	mask = __raw_readl(S3C64XX_EINT0MASK);
-	mask &= ~eint_irq_to_bit(irq);
-	__raw_writel(mask, S3C64XX_EINT0MASK);
-}
-
-static inline void s3c_irq_eint_ack(unsigned int irq)
-{
-	__raw_writel(eint_irq_to_bit(irq), S3C64XX_EINT0PEND);
-}
-
-static void s3c_irq_eint_maskack(unsigned int irq)
-{
-	/* compiler should in-line these */
-	s3c_irq_eint_mask(irq);
-	s3c_irq_eint_ack(irq);
-}
-
-static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
-{
-	int offs = eint_offset(irq);
-	int pin, pin_val;
-	int shift;
-	u32 ctrl, mask;
-	u32 newvalue = 0;
-	void __iomem *reg;
-
-	if (offs > 27)
-		return -EINVAL;
-
-	if (offs <= 15)
-		reg = S3C64XX_EINT0CON0;
-	else
-		reg = S3C64XX_EINT0CON1;
-
-	switch (type) {
-	case IRQ_TYPE_NONE:
-		printk(KERN_WARNING "No edge setting!\n");
-		break;
-
-	case IRQ_TYPE_EDGE_RISING:
-		newvalue = S3C2410_EXTINT_RISEEDGE;
-		break;
-
-	case IRQ_TYPE_EDGE_FALLING:
-		newvalue = S3C2410_EXTINT_FALLEDGE;
-		break;
-
-	case IRQ_TYPE_EDGE_BOTH:
-		newvalue = S3C2410_EXTINT_BOTHEDGE;
-		break;
-
-	case IRQ_TYPE_LEVEL_LOW:
-		newvalue = S3C2410_EXTINT_LOWLEV;
-		break;
-
-	case IRQ_TYPE_LEVEL_HIGH:
-		newvalue = S3C2410_EXTINT_HILEV;
-		break;
-
-	default:
-		printk(KERN_ERR "No such irq type %d", type);
-		return -1;
-	}
-
-	if (offs <= 15)
-		shift = (offs / 2) * 4;
-	else
-		shift = ((offs - 16) / 2) * 4;
-	mask = 0x7 << shift;
-
-	ctrl = __raw_readl(reg);
-	ctrl &= ~mask;
-	ctrl |= newvalue << shift;
-	__raw_writel(ctrl, reg);
-
-	/* set the GPIO pin appropriately */
-
-	if (offs < 16) {
-		pin = S3C64XX_GPN(offs);
-		pin_val = S3C_GPIO_SFN(2);
-	} else if (offs < 23) {
-		pin = S3C64XX_GPL(offs + 8 - 16);
-		pin_val = S3C_GPIO_SFN(3);
-	} else {
-		pin = S3C64XX_GPM(offs - 23);
-		pin_val = S3C_GPIO_SFN(3);
-	}
-
-	s3c_gpio_cfgpin(pin, pin_val);
-
-	return 0;
-}
-
-static struct irq_chip s3c_irq_eint = {
-	.name		= "s3c-eint",
-	.mask		= s3c_irq_eint_mask,
-	.unmask		= s3c_irq_eint_unmask,
-	.mask_ack	= s3c_irq_eint_maskack,
-	.ack		= s3c_irq_eint_ack,
-	.set_type	= s3c_irq_eint_set_type,
-	.set_wake	= s3c_irqext_wake,
-};
-
-/* s3c_irq_demux_eint
- *
- * This function demuxes the IRQ from the group0 external interrupts,
- * from IRQ_EINT(0) to IRQ_EINT(27). It is designed to be inlined into
- * the specific handlers s3c_irq_demux_eintX_Y.
- */
-static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end)
-{
-	u32 status = __raw_readl(S3C64XX_EINT0PEND);
-	u32 mask = __raw_readl(S3C64XX_EINT0MASK);
-	unsigned int irq;
-
-	status &= ~mask;
-	status >>= start;
-	status &= (1 << (end - start + 1)) - 1;
-
-	for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
-		if (status & 1)
-			generic_handle_irq(irq);
-
-		status >>= 1;
-	}
-}
-
-static void s3c_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
-{
-	s3c_irq_demux_eint(0, 3);
-}
-
-static void s3c_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
-{
-	s3c_irq_demux_eint(4, 11);
-}
-
-static void s3c_irq_demux_eint12_19(unsigned int irq, struct irq_desc *desc)
-{
-	s3c_irq_demux_eint(12, 19);
-}
-
-static void s3c_irq_demux_eint20_27(unsigned int irq, struct irq_desc *desc)
-{
-	s3c_irq_demux_eint(20, 27);
-}
-
-static int __init s3c64xx_init_irq_eint(void)
-{
-	int irq;
-
-	for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
-		set_irq_chip(irq, &s3c_irq_eint);
-		set_irq_handler(irq, handle_level_irq);
-		set_irq_flags(irq, IRQF_VALID);
-	}
-
-	set_irq_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3);
-	set_irq_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11);
-	set_irq_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19);
-	set_irq_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27);
-
-	return 0;
-}
-
-arch_initcall(s3c64xx_init_irq_eint);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/irq-pm.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/irq-pm.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/irq-pm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/irq-pm.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,111 +0,0 @@
-/* arch/arm/plat-s3c64xx/irq-pm.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C64XX - Interrupt handling Power Management
- *
- * This program is free software; you can 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/sysdev.h>
-#include <linux/interrupt.h>
-#include <linux/serial_core.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include <mach/map.h>
-
-#include <plat/regs-serial.h>
-#include <plat/regs-timer.h>
-#include <plat/regs-gpio.h>
-#include <plat/cpu.h>
-#include <plat/pm.h>
-
-/* We handled all the IRQ types in this code, to save having to make several
- * small files to handle each different type separately. Having the EINT_GRP
- * code here shouldn't be as much bloat as the IRQ table space needed when
- * they are enabled. The added benefit is we ensure that these registers are
- * in the same state as we suspended.
- */
-
-static struct sleep_save irq_save[] = {
-	SAVE_ITEM(S3C64XX_PRIORITY),
-	SAVE_ITEM(S3C64XX_EINT0CON0),
-	SAVE_ITEM(S3C64XX_EINT0CON1),
-	SAVE_ITEM(S3C64XX_EINT0FLTCON0),
-	SAVE_ITEM(S3C64XX_EINT0FLTCON1),
-	SAVE_ITEM(S3C64XX_EINT0FLTCON2),
-	SAVE_ITEM(S3C64XX_EINT0FLTCON3),
-	SAVE_ITEM(S3C64XX_EINT0MASK),
-	SAVE_ITEM(S3C64XX_TINT_CSTAT),
-};
-
-static struct irq_grp_save {
-	u32	fltcon;
-	u32	con;
-	u32	mask;
-} eint_grp_save[5];
-
-static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS];
-
-static int s3c64xx_irq_pm_suspend(struct sys_device *dev, pm_message_t state)
-{
-	struct irq_grp_save *grp = eint_grp_save;
-	int i;
-
-	S3C_PMDBG("%s: suspending IRQs\n", __func__);
-
-	s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
-
-	for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
-		irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM);
-
-	for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
-		grp->con = __raw_readl(S3C64XX_EINT12CON + (i * 4));
-		grp->mask = __raw_readl(S3C64XX_EINT12MASK + (i * 4));
-		grp->fltcon = __raw_readl(S3C64XX_EINT12FLTCON + (i * 4));
-	}
-
-	return 0;
-}
-
-static int s3c64xx_irq_pm_resume(struct sys_device *dev)
-{
-	struct irq_grp_save *grp = eint_grp_save;
-	int i;
-
-	S3C_PMDBG("%s: resuming IRQs\n", __func__);
-
-	s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
-
-	for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
-		__raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM);
-
-	for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
-		__raw_writel(grp->con, S3C64XX_EINT12CON + (i * 4));
-		__raw_writel(grp->mask, S3C64XX_EINT12MASK + (i * 4));
-		__raw_writel(grp->fltcon, S3C64XX_EINT12FLTCON + (i * 4));
-	}
-
-	S3C_PMDBG("%s: IRQ configuration restored\n", __func__);
-	return 0;
-}
-
-static struct sysdev_driver s3c64xx_irq_driver = {
-	.suspend = s3c64xx_irq_pm_suspend,
-	.resume	 = s3c64xx_irq_pm_resume,
-};
-
-static int __init s3c64xx_irq_pm_init(void)
-{
-	return sysdev_driver_register(&s3c64xx_sysclass, &s3c64xx_irq_driver);
-}
-
-arch_initcall(s3c64xx_irq_pm_init);
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/Kconfig linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,71 +0,0 @@
-# Copyright 2008 Openmoko, Inc.
-# Copyright 2008 Simtec Electronics
-#	Ben Dooks <ben@simtec.co.uk>
-#
-# Licensed under GPLv2
-
-config PLAT_S3C64XX
-	bool
-	depends on ARCH_S3C64XX
-	default y
-	select CPU_V6
-	select PLAT_S3C
-	select ARM_VIC
-	select NO_IOPORT
-	select ARCH_REQUIRE_GPIOLIB
-	select S3C_GPIO_TRACK
-	select S3C_GPIO_PULL_UPDOWN
-	select S3C_GPIO_CFG_S3C24XX
-	select S3C_GPIO_CFG_S3C64XX
-	select S3C_DEV_NAND
-	select USB_ARCH_HAS_OHCI
-	help
-	  Base platform code for any Samsung S3C64XX device
-
-if PLAT_S3C64XX
-
-# Configuration options shared by all S3C64XX implementations
-
-config CPU_S3C6400_INIT
-	bool
-	help
-	  Common initialisation code for the S3C6400 that is shared
-	  by other CPUs in the series, such as the S3C6410.
-
-config CPU_S3C6400_CLOCK
-	bool
-	help
-	  Common clock support code for the S3C6400 that is shared
-	  by other CPUs in the series, such as the S3C6410.
-
-config S3C64XX_DMA
-	bool "S3C64XX DMA"
-	select S3C_DMA
-
-# platform specific device setup
-
-config S3C64XX_SETUP_I2C0
-	bool
-	default y
-	help
-	  Common setup code for i2c bus 0.
-
-	  Note, currently since i2c0 is always compiled, this setup helper
-	  is always compiled with it.
-
-config S3C64XX_SETUP_I2C1
-	bool
-	help
-	  Common setup code for i2c bus 1.
-
-config S3C64XX_SETUP_FB_24BPP
-	bool
-	help
-	  Common setup code for S3C64XX with an 24bpp RGB display helper.
-
-config S3C64XX_SETUP_SDHCI_GPIO
-	bool
-	help
-	  Common setup code for S3C64XX SDHCI GPIO configurations
-
-endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/Makefile linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,44 +0,0 @@
-# arch/arm/plat-s3c64xx/Makefile
-#
-# Copyright 2008 Openmoko, Inc.
-# Copyright 2008 Simtec Electronics
-#
-# Licensed under GPLv2
-
-obj-y				:=
-obj-m				:=
-obj-n				:= dummy.o
-obj-				:=
-
-# Core files
-
-obj-y				+= dev-uart.o
-obj-y				+= cpu.o
-obj-y				+= irq.o
-obj-y				+= irq-eint.o
-obj-y				+= clock.o
-obj-y				+= gpiolib.o
-
-# CPU support
-
-obj-$(CONFIG_CPU_S3C6400_INIT)	+= s3c6400-init.o
-obj-$(CONFIG_CPU_S3C6400_CLOCK)	+= s3c6400-clock.o
-obj-$(CONFIG_CPU_FREQ_S3C64XX)  += cpufreq.o
-
-# PM support
-
-obj-$(CONFIG_PM)		+= pm.o
-obj-$(CONFIG_PM)		+= sleep.o
-obj-$(CONFIG_PM)		+= irq-pm.o
-
-# DMA support
-
-obj-$(CONFIG_S3C64XX_DMA)	+= dma.o
-
-# Device setup
-
-obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
-obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o
-obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
-obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
-obj-$(CONFIG_SND_S3C24XX_SOC) += dev-audio.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/pm.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/pm.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/pm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/pm.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,173 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/pm.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C64XX CPU PM 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/serial_core.h>
-#include <linux/io.h>
-
-#include <mach/map.h>
-
-#include <plat/pm.h>
-#include <plat/regs-sys.h>
-#include <plat/regs-gpio.h>
-#include <plat/regs-clock.h>
-#include <plat/regs-syscon-power.h>
-#include <plat/regs-gpio-memport.h>
-
-#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
-#include <plat/gpio-bank-n.h>
-
-void s3c_pm_debug_smdkled(u32 set, u32 clear)
-{
-	unsigned long flags;
-	u32 reg;
-
-	local_irq_save(flags);
-	reg = __raw_readl(S3C64XX_GPNCON);
-	reg &= ~(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) |
-		 S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15));
-	reg |= S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) |
-	       S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15);
-	__raw_writel(reg, S3C64XX_GPNCON);
-
-	reg = __raw_readl(S3C64XX_GPNDAT);
-	reg &= ~(clear << 12);
-	reg |= set << 12;
-	__raw_writel(reg, S3C64XX_GPNDAT);
-
-	local_irq_restore(flags);
-}
-#endif
-
-static struct sleep_save core_save[] = {
-	SAVE_ITEM(S3C_APLL_LOCK),
-	SAVE_ITEM(S3C_MPLL_LOCK),
-	SAVE_ITEM(S3C_EPLL_LOCK),
-	SAVE_ITEM(S3C_CLK_SRC),
-	SAVE_ITEM(S3C_CLK_DIV0),
-	SAVE_ITEM(S3C_CLK_DIV1),
-	SAVE_ITEM(S3C_CLK_DIV2),
-	SAVE_ITEM(S3C_CLK_OUT),
-	SAVE_ITEM(S3C_HCLK_GATE),
-	SAVE_ITEM(S3C_PCLK_GATE),
-	SAVE_ITEM(S3C_SCLK_GATE),
-	SAVE_ITEM(S3C_MEM0_GATE),
-
-	SAVE_ITEM(S3C_EPLL_CON1),
-	SAVE_ITEM(S3C_EPLL_CON0),
-
-	SAVE_ITEM(S3C64XX_MEM0DRVCON),
-	SAVE_ITEM(S3C64XX_MEM1DRVCON),
-
-#ifndef CONFIG_CPU_FREQ
-	SAVE_ITEM(S3C_APLL_CON),
-	SAVE_ITEM(S3C_MPLL_CON),
-#endif
-};
-
-static struct sleep_save misc_save[] = {
-	SAVE_ITEM(S3C64XX_AHB_CON0),
-	SAVE_ITEM(S3C64XX_AHB_CON1),
-	SAVE_ITEM(S3C64XX_AHB_CON2),
-	
-	SAVE_ITEM(S3C64XX_SPCON),
-
-	SAVE_ITEM(S3C64XX_MEM0CONSTOP),
-	SAVE_ITEM(S3C64XX_MEM1CONSTOP),
-	SAVE_ITEM(S3C64XX_MEM0CONSLP0),
-	SAVE_ITEM(S3C64XX_MEM0CONSLP1),
-	SAVE_ITEM(S3C64XX_MEM1CONSLP),
-};
-
-void s3c_pm_configure_extint(void)
-{
-	__raw_writel(s3c_irqwake_eintmask, S3C64XX_EINT_MASK);
-}
-
-void s3c_pm_restore_core(void)
-{
-	__raw_writel(0, S3C64XX_EINT_MASK);
-
-	s3c_pm_debug_smdkled(1 << 2, 0);
-
-	s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
-	s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
-}
-
-void s3c_pm_save_core(void)
-{
-	s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
-	s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
-}
-
-/* since both s3c6400 and s3c6410 share the same sleep pm calls, we
- * put the per-cpu code in here until any new cpu comes along and changes
- * this.
- */
-
-static void s3c64xx_cpu_suspend(void)
-{
-	unsigned long tmp;
-
-	/* set our standby method to sleep */
-
-	tmp = __raw_readl(S3C64XX_PWR_CFG);
-	tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
-	tmp |= S3C64XX_PWRCFG_CFG_WFI_SLEEP;
-	__raw_writel(tmp, S3C64XX_PWR_CFG);
-
-	/* clear any old wakeup */
-
-	__raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT),
-		     S3C64XX_WAKEUP_STAT);
-
-	/* set the LED state to 0110 over sleep */
-	s3c_pm_debug_smdkled(3 << 1, 0xf);
-
-	/* issue the standby signal into the pm unit. Note, we
-	 * issue a write-buffer drain just in case */
-
-	tmp = 0;
-
-	asm("b 1f\n\t"
-	    ".align 5\n\t"
-	    "1:\n\t"
-	    "mcr p15, 0, %0, c7, c10, 5\n\t"
-	    "mcr p15, 0, %0, c7, c10, 4\n\t"
-	    "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp));
-
-	/* we should never get past here */
-
-	panic("sleep resumed to originator?");
-}
-
-static void s3c64xx_pm_prepare(void)
-{
-	/* store address of resume. */
-	__raw_writel(virt_to_phys(s3c_cpu_resume), S3C64XX_INFORM0);
-
-	/* ensure previous wakeup state is cleared before sleeping */
-	__raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT), S3C64XX_WAKEUP_STAT);
-}
-
-static int s3c64xx_pm_init(void)
-{
-	pm_cpu_prep = s3c64xx_pm_prepare;
-	pm_cpu_sleep = s3c64xx_cpu_suspend;
-	pm_uart_udivslot = 1;
-	return 0;
-}
-
-arch_initcall(s3c64xx_pm_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/s3c6400-clock.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/s3c6400-clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/s3c6400-clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/s3c6400-clock.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,758 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/s3c6400-clock.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C6400 based common clock 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/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/sysdev.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <plat/cpu-freq.h>
-
-#include <plat/regs-clock.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-
-/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
- * ext_xtal_mux for want of an actual name from the manual.
-*/
-
-static struct clk clk_ext_xtal_mux = {
-	.name		= "ext_xtal",
-	.id		= -1,
-};
-
-#define clk_fin_apll clk_ext_xtal_mux
-#define clk_fin_mpll clk_ext_xtal_mux
-#define clk_fin_epll clk_ext_xtal_mux
-
-#define clk_fout_mpll	clk_mpll
-#define clk_fout_epll	clk_epll
-
-struct clk_sources {
-	unsigned int	nr_sources;
-	struct clk	**sources;
-};
-
-struct clksrc_clk {
-	struct clk		clk;
-	unsigned int		mask;
-	unsigned int		shift;
-
-	struct clk_sources	*sources;
-
-	unsigned int		divider_shift;
-	void __iomem		*reg_divider;
-};
-
-static struct clk clk_fout_apll = {
-	.name		= "fout_apll",
-	.id		= -1,
-};
-
-static struct clk *clk_src_apll_list[] = {
-	[0] = &clk_fin_apll,
-	[1] = &clk_fout_apll,
-};
-
-static struct clk_sources clk_src_apll = {
-	.sources	= clk_src_apll_list,
-	.nr_sources	= ARRAY_SIZE(clk_src_apll_list),
-};
-
-static struct clksrc_clk clk_mout_apll = {
-	.clk	= {
-		.name		= "mout_apll",
-		.id		= -1,
-	},
-	.shift		= S3C6400_CLKSRC_APLL_MOUT_SHIFT,
-	.mask		= S3C6400_CLKSRC_APLL_MOUT,
-	.sources	= &clk_src_apll,
-};
-
-static struct clk *clk_src_epll_list[] = {
-	[0] = &clk_fin_epll,
-	[1] = &clk_fout_epll,
-};
-
-static struct clk_sources clk_src_epll = {
-	.sources	= clk_src_epll_list,
-	.nr_sources	= ARRAY_SIZE(clk_src_epll_list),
-};
-
-static struct clksrc_clk clk_mout_epll = {
-	.clk	= {
-		.name		= "mout_epll",
-		.id		= -1,
-	},
-	.shift		= S3C6400_CLKSRC_EPLL_MOUT_SHIFT,
-	.mask		= S3C6400_CLKSRC_EPLL_MOUT,
-	.sources	= &clk_src_epll,
-};
-
-static struct clk *clk_src_mpll_list[] = {
-	[0] = &clk_fin_mpll,
-	[1] = &clk_fout_mpll,
-};
-
-static struct clk_sources clk_src_mpll = {
-	.sources	= clk_src_mpll_list,
-	.nr_sources	= ARRAY_SIZE(clk_src_mpll_list),
-};
-
-static struct clksrc_clk clk_mout_mpll = {
-	.clk = {
-		.name		= "mout_mpll",
-		.id		= -1,
-	},
-	.shift		= S3C6400_CLKSRC_MPLL_MOUT_SHIFT,
-	.mask		= S3C6400_CLKSRC_MPLL_MOUT,
-	.sources	= &clk_src_mpll,
-};
-
-static unsigned int armclk_mask;
-
-static unsigned long s3c64xx_clk_arm_get_rate(struct clk *clk)
-{
-	unsigned long rate = clk_get_rate(clk->parent);
-	u32 clkdiv;
-
-	/* divisor mask starts at bit0, so no need to shift */
-	clkdiv = __raw_readl(S3C_CLK_DIV0) & armclk_mask;
-
-	return rate / (clkdiv + 1);
-}
-
-static unsigned long s3c64xx_clk_arm_round_rate(struct clk *clk,
-						unsigned long rate)
-{
-	unsigned long parent = clk_get_rate(clk->parent);
-	u32 div;
-
-	if (parent < rate)
-		return parent;
-
-	div = (parent / rate) - 1;
-	if (div > armclk_mask)
-		div = armclk_mask;
-
-	return parent / (div + 1);
-}
-
-static int s3c64xx_clk_arm_set_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned long parent = clk_get_rate(clk->parent);
-	u32 div;
-	u32 val;
-
-	if (rate < parent / (armclk_mask + 1))
-		return -EINVAL;
-
-	rate = clk_round_rate(clk, rate);
-	div = clk_get_rate(clk->parent) / rate;
-
-	val = __raw_readl(S3C_CLK_DIV0);
-	val &= ~armclk_mask;
-	val |= (div - 1);
-	__raw_writel(val, S3C_CLK_DIV0);
-
-	return 0;
-
-}
-
-static struct clk clk_arm = {
-	.name		= "armclk",
-	.id		= -1,
-	.parent		= &clk_mout_apll.clk,
-	.get_rate	= s3c64xx_clk_arm_get_rate,
-	.set_rate	= s3c64xx_clk_arm_set_rate,
-	.round_rate	= s3c64xx_clk_arm_round_rate,
-};
-
-static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk)
-{
-	unsigned long rate = clk_get_rate(clk->parent);
-
-	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
-
-	if (__raw_readl(S3C_CLK_DIV0) & S3C6400_CLKDIV0_MPLL_MASK)
-		rate /= 2;
-
-	return rate;
-}
-
-static struct clk clk_dout_mpll = {
-	.name		= "dout_mpll",
-	.id		= -1,
-	.parent		= &clk_mout_mpll.clk,
-	.get_rate	= s3c64xx_clk_doutmpll_get_rate,
-};
-
-static struct clk *clkset_spi_mmc_list[] = {
-	&clk_mout_epll.clk,
-	&clk_dout_mpll,
-	&clk_fin_epll,
-	&clk_27m,
-};
-
-static struct clk_sources clkset_spi_mmc = {
-	.sources	= clkset_spi_mmc_list,
-	.nr_sources	= ARRAY_SIZE(clkset_spi_mmc_list),
-};
-
-static struct clk *clkset_irda_list[] = {
-	&clk_mout_epll.clk,
-	&clk_dout_mpll,
-	NULL,
-	&clk_27m,
-};
-
-static struct clk_sources clkset_irda = {
-	.sources	= clkset_irda_list,
-	.nr_sources	= ARRAY_SIZE(clkset_irda_list),
-};
-
-static struct clk *clkset_uart_list[] = {
-	&clk_mout_epll.clk,
-	&clk_dout_mpll,
-	NULL,
-	NULL
-};
-
-static struct clk_sources clkset_uart = {
-	.sources	= clkset_uart_list,
-	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
-};
-
-static struct clk *clkset_uhost_list[] = {
-	&clk_48m,
-	&clk_mout_epll.clk,
-	&clk_dout_mpll,
-	&clk_fin_epll,
-};
-
-static struct clk_sources clkset_uhost = {
-	.sources	= clkset_uhost_list,
-	.nr_sources	= ARRAY_SIZE(clkset_uhost_list),
-};
-
-
-/* The peripheral clocks are all controlled via clocksource followed
- * by an optional divider and gate stage. We currently roll this into
- * one clock which hides the intermediate clock from the mux.
- *
- * Note, the JPEG clock can only be an even divider...
- *
- * The scaler and LCD clocks depend on the S3C64XX version, and also
- * have a common parent divisor so are not included here.
- */
-
-static inline struct clksrc_clk *to_clksrc(struct clk *clk)
-{
-	return container_of(clk, struct clksrc_clk, clk);
-}
-
-static unsigned long s3c64xx_getrate_clksrc(struct clk *clk)
-{
-	struct clksrc_clk *sclk = to_clksrc(clk);
-	unsigned long rate = clk_get_rate(clk->parent);
-	u32 clkdiv = __raw_readl(sclk->reg_divider);
-
-	clkdiv >>= sclk->divider_shift;
-	clkdiv &= 0xf;
-	clkdiv++;
-
-	rate /= clkdiv;
-	return rate;
-}
-
-static int s3c64xx_setrate_clksrc(struct clk *clk, unsigned long rate)
-{
-	struct clksrc_clk *sclk = to_clksrc(clk);
-	void __iomem *reg = sclk->reg_divider;
-	unsigned int div;
-	u32 val;
-
-	rate = clk_round_rate(clk, rate);
-	div = clk_get_rate(clk->parent) / rate;
-	if (div > 16)
-		return -EINVAL;
-
-	val = __raw_readl(reg);
-	val &= ~(0xf << sclk->divider_shift);
-	val |= (div - 1) << sclk->divider_shift;
-	__raw_writel(val, reg);
-
-	return 0;
-}
-
-static int s3c64xx_setparent_clksrc(struct clk *clk, struct clk *parent)
-{
-	struct clksrc_clk *sclk = to_clksrc(clk);
-	struct clk_sources *srcs = sclk->sources;
-	u32 clksrc = __raw_readl(S3C_CLK_SRC);
-	int src_nr = -1;
-	int ptr;
-
-	for (ptr = 0; ptr < srcs->nr_sources; ptr++)
-		if (srcs->sources[ptr] == parent) {
-			src_nr = ptr;
-			break;
-		}
-
-	if (src_nr >= 0) {
-		clksrc &= ~sclk->mask;
-		clksrc |= src_nr << sclk->shift;
-
-		__raw_writel(clksrc, S3C_CLK_SRC);
-
-		clk->parent = parent;
-		return 0;
-	}
-
-	return -EINVAL;
-}
-
-static unsigned long s3c64xx_roundrate_clksrc(struct clk *clk,
-					      unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	int div;
-
-	if (rate > parent_rate)
-		rate = parent_rate;
-	else {
-		div = parent_rate / rate;
-
-		if (div == 0)
-			div = 1;
-		if (div > 16)
-			div = 16;
-
-		rate = parent_rate / div;
-	}
-
-	return rate;
-}
-
-static struct clksrc_clk clk_mmc0 = {
-	.clk	= {
-		.name		= "mmc_bus",
-		.id		= 0,
-		.ctrlbit        = S3C_CLKCON_SCLK_MMC0,
-		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
-	},
-	.shift		= S3C6400_CLKSRC_MMC0_SHIFT,
-	.mask		= S3C6400_CLKSRC_MMC0_MASK,
-	.sources	= &clkset_spi_mmc,
-	.divider_shift	= S3C6400_CLKDIV1_MMC0_SHIFT,
-	.reg_divider	= S3C_CLK_DIV1,
-};
-
-static struct clksrc_clk clk_mmc1 = {
-	.clk	= {
-		.name		= "mmc_bus",
-		.id		= 1,
-		.ctrlbit        = S3C_CLKCON_SCLK_MMC1,
-		.enable		= s3c64xx_sclk_ctrl,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
-	},
-	.shift		= S3C6400_CLKSRC_MMC1_SHIFT,
-	.mask		= S3C6400_CLKSRC_MMC1_MASK,
-	.sources	= &clkset_spi_mmc,
-	.divider_shift	= S3C6400_CLKDIV1_MMC1_SHIFT,
-	.reg_divider	= S3C_CLK_DIV1,
-};
-
-static struct clksrc_clk clk_mmc2 = {
-	.clk	= {
-		.name		= "mmc_bus",
-		.id		= 2,
-		.ctrlbit        = S3C_CLKCON_SCLK_MMC2,
-		.enable		= s3c64xx_sclk_ctrl,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
-	},
-	.shift		= S3C6400_CLKSRC_MMC2_SHIFT,
-	.mask		= S3C6400_CLKSRC_MMC2_MASK,
-	.sources	= &clkset_spi_mmc,
-	.divider_shift	= S3C6400_CLKDIV1_MMC2_SHIFT,
-	.reg_divider	= S3C_CLK_DIV1,
-};
-
-static struct clksrc_clk clk_usbhost = {
-	.clk	= {
-		.name		= "usb-bus-host",
-		.id		= -1,
-		.ctrlbit        = S3C_CLKCON_SCLK_UHOST,
-		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
-	},
-	.shift		= S3C6400_CLKSRC_UHOST_SHIFT,
-	.mask		= S3C6400_CLKSRC_UHOST_MASK,
-	.sources	= &clkset_uhost,
-	.divider_shift	= S3C6400_CLKDIV1_UHOST_SHIFT,
-	.reg_divider	= S3C_CLK_DIV1,
-};
-
-static struct clksrc_clk clk_uart_uclk1 = {
-	.clk	= {
-		.name		= "uclk1",
-		.id		= -1,
-		.ctrlbit        = S3C_CLKCON_SCLK_UART,
-		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
-	},
-	.shift		= S3C6400_CLKSRC_UART_SHIFT,
-	.mask		= S3C6400_CLKSRC_UART_MASK,
-	.sources	= &clkset_uart,
-	.divider_shift	= S3C6400_CLKDIV2_UART_SHIFT,
-	.reg_divider	= S3C_CLK_DIV2,
-};
-
-/* Where does UCLK0 come from? */
-
-static struct clksrc_clk clk_spi0 = {
-	.clk	= {
-		.name		= "spi-bus",
-		.id		= 0,
-		.ctrlbit        = S3C_CLKCON_SCLK_SPI0,
-		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
-	},
-	.shift		= S3C6400_CLKSRC_SPI0_SHIFT,
-	.mask		= S3C6400_CLKSRC_SPI0_MASK,
-	.sources	= &clkset_spi_mmc,
-	.divider_shift	= S3C6400_CLKDIV2_SPI0_SHIFT,
-	.reg_divider	= S3C_CLK_DIV2,
-};
-
-static struct clksrc_clk clk_spi1 = {
-	.clk	= {
-		.name		= "spi-bus",
-		.id		= 1,
-		.ctrlbit        = S3C_CLKCON_SCLK_SPI1,
-		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
-	},
-	.shift		= S3C6400_CLKSRC_SPI1_SHIFT,
-	.mask		= S3C6400_CLKSRC_SPI1_MASK,
-	.sources	= &clkset_spi_mmc,
-	.divider_shift	= S3C6400_CLKDIV2_SPI1_SHIFT,
-	.reg_divider	= S3C_CLK_DIV2,
-};
-
-static struct clk clk_iis_cd0 = {
-	.name		= "iis_cdclk0",
-	.id		= -1,
-};
-
-static struct clk clk_iis_cd1 = {
-	.name		= "iis_cdclk1",
-	.id		= -1,
-};
-
-static struct clk clk_pcm_cd = {
-	.name		= "pcm_cdclk",
-	.id		= -1,
-};
-
-static struct clk *clkset_audio0_list[] = {
-	[0] = &clk_mout_epll.clk,
-	[1] = &clk_dout_mpll,
-	[2] = &clk_fin_epll,
-	[3] = &clk_iis_cd0,
-	[4] = &clk_pcm_cd,
-};
-
-static struct clk_sources clkset_audio0 = {
-	.sources	= clkset_audio0_list,
-	.nr_sources	= ARRAY_SIZE(clkset_audio0_list),
-};
-
-static struct clksrc_clk clk_audio0 = {
-	.clk	= {
-		.name		= "audio-bus",
-		.id		= 0,
-		.ctrlbit        = S3C_CLKCON_SCLK_AUDIO0,
-		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
-	},
-	.shift		= S3C6400_CLKSRC_AUDIO0_SHIFT,
-	.mask		= S3C6400_CLKSRC_AUDIO0_MASK,
-	.sources	= &clkset_audio0,
-	.divider_shift	= S3C6400_CLKDIV2_AUDIO0_SHIFT,
-	.reg_divider	= S3C_CLK_DIV2,
-};
-
-static struct clk *clkset_audio1_list[] = {
-	[0] = &clk_mout_epll.clk,
-	[1] = &clk_dout_mpll,
-	[2] = &clk_fin_epll,
-	[3] = &clk_iis_cd1,
-	[4] = &clk_pcm_cd,
-};
-
-static struct clk_sources clkset_audio1 = {
-	.sources	= clkset_audio1_list,
-	.nr_sources	= ARRAY_SIZE(clkset_audio1_list),
-};
-
-static struct clksrc_clk clk_audio1 = {
-	.clk	= {
-		.name		= "audio-bus",
-		.id		= 1,
-		.ctrlbit        = S3C_CLKCON_SCLK_AUDIO1,
-		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
-	},
-	.shift		= S3C6400_CLKSRC_AUDIO1_SHIFT,
-	.mask		= S3C6400_CLKSRC_AUDIO1_MASK,
-	.sources	= &clkset_audio1,
-	.divider_shift	= S3C6400_CLKDIV2_AUDIO1_SHIFT,
-	.reg_divider	= S3C_CLK_DIV2,
-};
-
-static struct clksrc_clk clk_irda = {
-	.clk	= {
-		.name		= "irda-bus",
-		.id		= 0,
-		.ctrlbit        = S3C_CLKCON_SCLK_IRDA,
-		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
-	},
-	.shift		= S3C6400_CLKSRC_IRDA_SHIFT,
-	.mask		= S3C6400_CLKSRC_IRDA_MASK,
-	.sources	= &clkset_irda,
-	.divider_shift	= S3C6400_CLKDIV2_IRDA_SHIFT,
-	.reg_divider	= S3C_CLK_DIV2,
-};
-
-static struct clk *clkset_camif_list[] = {
-	&clk_h2,
-};
-
-static struct clk_sources clkset_camif = {
-	.sources	= clkset_camif_list,
-	.nr_sources	= ARRAY_SIZE(clkset_camif_list),
-};
-
-static struct clksrc_clk clk_camif = {
-	.clk	= {
-		.name		= "camera",
-		.id		= -1,
-		.ctrlbit        = S3C_CLKCON_SCLK_CAM,
-		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
-	},
-	.shift		= 0,
-	.mask		= 0,
-	.sources	= &clkset_camif,
-	.divider_shift	= S3C6400_CLKDIV0_CAM_SHIFT,
-	.reg_divider	= S3C_CLK_DIV0,
-};
-
-/* Clock initialisation code */
-
-static struct clksrc_clk *init_parents[] = {
-	&clk_mout_apll,
-	&clk_mout_epll,
-	&clk_mout_mpll,
-	&clk_mmc0,
-	&clk_mmc1,
-	&clk_mmc2,
-	&clk_usbhost,
-	&clk_uart_uclk1,
-	&clk_spi0,
-	&clk_spi1,
-	&clk_audio0,
-	&clk_audio1,
-	&clk_irda,
-	&clk_camif,
-};
-
-static void __init_or_cpufreq s3c6400_set_clksrc(struct clksrc_clk *clk)
-{
-	struct clk_sources *srcs = clk->sources;
-	u32 clksrc = __raw_readl(S3C_CLK_SRC);
-
-	clksrc &= clk->mask;
-	clksrc >>= clk->shift;
-
-	if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
-		printk(KERN_ERR "%s: bad source %d\n",
-		       clk->clk.name, clksrc);
-		return;
-	}
-
-	clk->clk.parent = srcs->sources[clksrc];
-
-	printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
-	       clk->clk.name, clk->clk.parent->name, clksrc,
-	       clk_get_rate(&clk->clk));
-}
-
-#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
-
-void __init_or_cpufreq s3c6400_setup_clocks(void)
-{
-	struct clk *xtal_clk;
-	unsigned long xtal;
-	unsigned long fclk;
-	unsigned long hclk;
-	unsigned long hclk2;
-	unsigned long pclk;
-	unsigned long epll;
-	unsigned long apll;
-	unsigned long mpll;
-	unsigned int ptr;
-	u32 clkdiv0;
-
-	printk(KERN_DEBUG "%s: registering clocks\n", __func__);
-
-	clkdiv0 = __raw_readl(S3C_CLK_DIV0);
-	printk(KERN_DEBUG "%s: clkdiv0 = %08x\n", __func__, clkdiv0);
-
-	xtal_clk = clk_get(NULL, "xtal");
-	BUG_ON(IS_ERR(xtal_clk));
-
-	xtal = clk_get_rate(xtal_clk);
-	clk_put(xtal_clk);
-
-	printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
-
-	/* For now assume the mux always selects the crystal */
-	clk_ext_xtal_mux.parent = xtal_clk;
-
-	epll = s3c6400_get_epll(xtal);
-	mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON));
-	apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON));
-
-	fclk = mpll;
-
-	printk(KERN_INFO "S3C64XX: PLL settings, A=%ld, M=%ld, E=%ld\n",
-	       apll, mpll, epll);
-
-	hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
-	hclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK);
-	pclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK);
-
-	printk(KERN_INFO "S3C64XX: HCLK2=%ld, HCLK=%ld, PCLK=%ld\n",
-	       hclk2, hclk, pclk);
-
-	clk_fout_mpll.rate = mpll;
-	clk_fout_epll.rate = epll;
-	clk_fout_apll.rate = apll;
-
-	clk_h2.rate = hclk2;
-	clk_h.rate = hclk;
-	clk_p.rate = pclk;
-	clk_f.rate = fclk;
-
-	for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
-		s3c6400_set_clksrc(init_parents[ptr]);
-}
-
-static struct clk *clks[] __initdata = {
-	&clk_ext_xtal_mux,
-	&clk_iis_cd0,
-	&clk_iis_cd1,
-	&clk_pcm_cd,
-	&clk_mout_epll.clk,
-	&clk_mout_mpll.clk,
-	&clk_dout_mpll,
-	&clk_mmc0.clk,
-	&clk_mmc1.clk,
-	&clk_mmc2.clk,
-	&clk_usbhost.clk,
-	&clk_uart_uclk1.clk,
-	&clk_spi0.clk,
-	&clk_spi1.clk,
-	&clk_audio0.clk,
-	&clk_audio1.clk,
-	&clk_irda.clk,
-	&clk_camif.clk,
-	&clk_arm,
-};
-
-/**
- * s3c6400_register_clocks - register clocks for s3c6400 and above
- * @armclk_divlimit: Divisor mask for ARMCLK
- *
- * Register the clocks for the S3C6400 and above SoC range, such
- * as ARMCLK and the clocks which have divider chains attached.
- *
- * This call does not setup the clocks, which is left to the
- * s3c6400_setup_clocks() call which may be needed by the cpufreq
- * or resume code to re-set the clocks if the bootloader has changed
- * them.
- */
-void __init s3c6400_register_clocks(unsigned armclk_divlimit)
-{
-	struct clk *clkp;
-	int ret;
-	int ptr;
-
-	armclk_mask = armclk_divlimit;
-
-	for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
-		clkp = clks[ptr];
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-	}
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/s3c6400-init.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/s3c6400-init.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/s3c6400-init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/s3c6400-init.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,29 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/s3c6400-init.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C6400 - CPU initialisation (common with other S3C64XX chips)
- *
- * This program is free software; you can 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/init.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/s3c6400.h>
-#include <plat/s3c6410.h>
-
-/* uart registration process */
-
-void __init s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-	s3c24xx_init_uartdevs("s3c6400-uart", s3c64xx_uart_resources, cfg, no);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/setup-fb-24bpp.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/setup-fb-24bpp.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/setup-fb-24bpp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/setup-fb-24bpp.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/setup-fb-24bpp.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * Base S3C64XX setup information for 24bpp LCD framebuffer
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fb.h>
-
-#include <mach/regs-fb.h>
-#include <mach/gpio.h>
-#include <plat/fb.h>
-#include <plat/gpio-cfg.h>
-
-extern void s3c64xx_fb_gpio_setup_24bpp(void)
-{
-	unsigned int gpio;
-
-	for (gpio = S3C64XX_GPI(0); gpio <= S3C64XX_GPI(15); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-
-	for (gpio = S3C64XX_GPJ(0); gpio <= S3C64XX_GPJ(11); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/setup-i2c0.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/setup-i2c0.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/setup-i2c0.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/setup-i2c0.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,31 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/setup-i2c0.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * Base S3C64XX I2C bus 0 gpio configuration
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-struct platform_device; /* don't need the contents */
-
-#include <mach/gpio.h>
-#include <plat/iic.h>
-#include <plat/gpio-bank-b.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c0_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgpin(S3C64XX_GPB(5), S3C64XX_GPB5_I2C_SCL0);
-	s3c_gpio_cfgpin(S3C64XX_GPB(6), S3C64XX_GPB6_I2C_SDA0);
-	s3c_gpio_setpull(S3C64XX_GPB(5), S3C_GPIO_PULL_UP);
-	s3c_gpio_setpull(S3C64XX_GPB(6), S3C_GPIO_PULL_UP);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/setup-i2c1.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/setup-i2c1.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/setup-i2c1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/setup-i2c1.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,31 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/setup-i2c1.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * Base S3C64XX I2C bus 1 gpio configuration
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-struct platform_device; /* don't need the contents */
-
-#include <mach/gpio.h>
-#include <plat/iic.h>
-#include <plat/gpio-bank-b.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c1_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgpin(S3C64XX_GPB(2), S3C64XX_GPB2_I2C_SCL1);
-	s3c_gpio_cfgpin(S3C64XX_GPB(3), S3C64XX_GPB3_I2C_SDA1);
-	s3c_gpio_setpull(S3C64XX_GPB(2), S3C_GPIO_PULL_UP);
-	s3c_gpio_setpull(S3C64XX_GPB(3), S3C_GPIO_PULL_UP);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,75 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c
- *
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C64XX - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <mach/gpio.h>
-#include <plat/gpio-cfg.h>
-
-void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
-{
-	unsigned int gpio;
-	unsigned int end;
-
-	end = S3C64XX_GPG(2 + width);
-
-	/* Set all the necessary GPG pins to special-function 0 */
-	for (gpio = S3C64XX_GPG(0); gpio < end; gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-
-	s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
-	s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(2));
-}
-
-void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
-{
-	unsigned int gpio;
-	unsigned int end;
-
-	end = S3C64XX_GPH(2 + width);
-
-	/* Set all the necessary GPG pins to special-function 0 */
-	for (gpio = S3C64XX_GPH(0); gpio < end; gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-
-	s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
-	s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(3));
-}
-
-void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
-{
-	unsigned int gpio;
-	unsigned int end;
-
-	end = S3C64XX_GPH(6 + width);
-
-	/* Set all the necessary GPH pins to special-function 1 */
-	for (gpio = S3C64XX_GPH(6); gpio < end; gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-
-	/* Set all the necessary GPC pins to special-function 1 */
-	for (gpio = S3C64XX_GPC(4); gpio < S3C64XX_GPC(6); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/sleep.S linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/sleep.S
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/sleep.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s3c64xx/sleep.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,144 +0,0 @@
-/* linux/0arch/arm/plat-s3c64xx/sleep.S
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C64XX CPU sleep 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/linkage.h>
-#include <asm/assembler.h>
-#include <mach/map.h>
-
-#undef S3C64XX_VA_GPIO
-#define S3C64XX_VA_GPIO (0x0)
-
-#include <plat/regs-gpio.h>
-#include <plat/gpio-bank-n.h>
-
-#define LL_UART (S3C_PA_UART + (0x400 * CONFIG_S3C_LOWLEVEL_UART_PORT))
-
-	.text
-
-	/* s3c_cpu_save
-	 *
-	 * Save enough processor state to allow the restart of the pm.c
-	 * code after resume.
-	 *
-	 * entry:
-	 *	r0 = pointer to the save block
-	*/
-
-ENTRY(s3c_cpu_save)
-	stmfd	sp!, { r4 - r12, lr }
-
-	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
-	mrc	p15, 0, r5, c3, c0, 0	@ Domain ID
-	mrc	p15, 0, r6, c2, c0, 0	@ Translation Table BASE0
-	mrc	p15, 0, r7, c2, c0, 1	@ Translation Table BASE1
-	mrc	p15, 0, r8, c2, c0, 2	@ Translation Table Control
-	mrc	p15, 0, r9, c1, c0, 0	@ Control register
-	mrc	p15, 0, r10, c1, c0, 1	@ Auxiliary control register
-	mrc	p15, 0, r11, c1, c0, 2	@ Co-processor access controls
-
-	stmia	r0, { r4 - r13 }	@ Save CP registers and SP
-
-	@@ save our state to ram
-	bl	s3c_pm_cb_flushcache
-
-	@@ call final suspend code
-	ldr	r0, =pm_cpu_sleep
-	ldr	pc, [r0]
-	
-	@@ return to the caller, after the MMU is turned on.
-	@@ restore the last bits of the stack and return.
-resume_with_mmu:
-	ldmfd	sp!, { r4 - r12, pc }	@ return, from sp from s3c_cpu_save
-
-	.data
-
-	/* the next bit is code, but it requires easy access to the
-	 * s3c_sleep_save_phys data before the MMU is switched on, so
-	 * we store the code that needs this variable in the .data where
-	 * the value can be written to (the .text segment is RO).
-	*/
-
-	.global	s3c_sleep_save_phys
-s3c_sleep_save_phys:
-	.word	0
-
-	/* Sleep magic, the word before the resume entry point so that the
-	 * bootloader can check for a resumeable image. */
-
-	.word	0x2bedf00d
-
-	/* s3c_cpu_reusme
-	 *
-	 * This is the entry point, stored by whatever method the bootloader
-	 * requires to get the kernel runnign again. This code expects to be
-	 * entered with no caches live and the MMU disabled. It will then
-	 * restore the MMU and other basic CP registers saved and restart
-	 * the kernel C code to finish the resume code.
-	*/
-
-ENTRY(s3c_cpu_resume)
-	msr	cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
-	ldr	r2, =LL_UART		/* for debug */
-
-#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
-	/* Initialise the GPIO state if we are debugging via the SMDK LEDs,
-	 * as the uboot version supplied resets these to inputs during the
-	 * resume checks.
-	*/
-
-	ldr	r3, =S3C64XX_PA_GPIO
-	ldr	r0, [ r3, #S3C64XX_GPNCON ]
-	bic	r0, r0, #(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) | \
-			  S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15))
-	orr	r0, r0, #(S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) | \
-			  S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15))
-	str	r0, [ r3, #S3C64XX_GPNCON ]
-
-	ldr	r0, [ r3, #S3C64XX_GPNDAT ]
-	bic	r0, r0, #0xf << 12			@ GPN12..15
-	orr	r0, r0, #1 << 15			@ GPN15
-	str	r0, [ r3, #S3C64XX_GPNDAT ]
-#endif
-
-	/* __v6_setup from arch/arm/mm/proc-v6.S, ensure that the caches
-	 * are thoroughly cleaned just in case the bootloader didn't do it
-	 * for us. */
-	mov	r0, #0
-	mcr	p15, 0, r0, c7, c14, 0		@ clean+invalidate D cache
-	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
-	mcr	p15, 0, r0, c7, c15, 0		@ clean+invalidate cache
-	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
-	@@mcr	p15, 0, r0, c8, c7, 0		@ invalidate I + D TLBs
-	@@mcr	p15, 0, r0, c7, c7, 0		@ Invalidate I + D caches
-
-	ldr	r0, s3c_sleep_save_phys
-	ldmia	r0, { r4 - r13 }
-
-	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
-	mcr	p15, 0, r5, c3, c0, 0	@ Domain ID
-	mcr	p15, 0, r6, c2, c0, 0	@ Translation Table BASE0
-	mcr	p15, 0, r7, c2, c0, 1	@ Translation Table BASE1
-	mcr	p15, 0, r8, c2, c0, 2	@ Translation Table Control
-	mcr	p15, 0, r10, c1, c0, 1	@ Auxiliary control register
-
-	mov	r0, #0			@ restore copro access controls
-	mcr	p15, 0, r11, c1, c0, 2	@ Co-processor access controls
-	mcr 	p15, 0, r0, c7, c5, 4
-
-	ldr	r2, =resume_with_mmu
-	mcr	p15, 0, r9, c1, c0, 0		/* turn mmu back on */
-	nop
-	mov	pc, r2				/* jump back */
-
-	.end
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/clock.c linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/clock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,149 @@
+/* linux/arch/arm/plat-s5p/clock.c
+ *
+ * Copyright 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P - Common clock 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/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+#include <asm/div64.h>
+
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p-clock.h>
+
+/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
+ * clk_ext_xtal_mux.
+*/
+struct clk clk_ext_xtal_mux = {
+	.name		= "ext_xtal",
+	.id		= -1,
+};
+
+static struct clk s5p_clk_27m = {
+	.name		= "clk_27m",
+	.id		= -1,
+	.rate		= 27000000,
+};
+
+/* 48MHz USB Phy clock output */
+struct clk clk_48m = {
+	.name		= "clk_48m",
+	.id		= -1,
+	.rate		= 48000000,
+};
+
+/* APLL clock output
+ * No need .ctrlbit, this is always on
+*/
+struct clk clk_fout_apll = {
+	.name		= "fout_apll",
+	.id		= -1,
+};
+
+/* MPLL clock output
+ * No need .ctrlbit, this is always on
+*/
+struct clk clk_fout_mpll = {
+	.name		= "fout_mpll",
+	.id		= -1,
+};
+
+/* EPLL clock output */
+struct clk clk_fout_epll = {
+	.name		= "fout_epll",
+	.id		= -1,
+	.ctrlbit	= (1 << 31),
+};
+
+/* ARM clock */
+struct clk clk_arm = {
+	.name		= "armclk",
+	.id		= -1,
+	.rate		= 0,
+	.ctrlbit	= 0,
+};
+
+/* Possible clock sources for APLL Mux */
+static struct clk *clk_src_apll_list[] = {
+	[0] = &clk_fin_apll,
+	[1] = &clk_fout_apll,
+};
+
+struct clksrc_sources clk_src_apll = {
+	.sources	= clk_src_apll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_apll_list),
+};
+
+/* Possible clock sources for MPLL Mux */
+static struct clk *clk_src_mpll_list[] = {
+	[0] = &clk_fin_mpll,
+	[1] = &clk_fout_mpll,
+};
+
+struct clksrc_sources clk_src_mpll = {
+	.sources	= clk_src_mpll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_mpll_list),
+};
+
+/* Possible clock sources for EPLL Mux */
+static struct clk *clk_src_epll_list[] = {
+	[0] = &clk_fin_epll,
+	[1] = &clk_fout_epll,
+};
+
+struct clksrc_sources clk_src_epll = {
+	.sources	= clk_src_epll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_epll_list),
+};
+
+struct clk clk_vpll = {
+	.name		= "vpll",
+	.id		= -1,
+};
+
+int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable)
+{
+	unsigned int ctrlbit = clk->ctrlbit;
+	u32 con;
+
+	con = __raw_readl(reg);
+	con = enable ? (con | ctrlbit) : (con & ~ctrlbit);
+	__raw_writel(con, reg);
+	return 0;
+}
+
+static struct clk *s5p_clks[] __initdata = {
+	&clk_ext_xtal_mux,
+	&clk_48m,
+	&s5p_clk_27m,
+	&clk_fout_apll,
+	&clk_fout_mpll,
+	&clk_fout_epll,
+	&clk_arm,
+	&clk_vpll,
+};
+
+void __init s5p_register_clocks(unsigned long xtal_freq)
+{
+	int ret;
+
+	clk_ext_xtal_mux.rate = xtal_freq;
+
+	ret = s3c24xx_register_clocks(s5p_clks, ARRAY_SIZE(s5p_clks));
+	if (ret > 0)
+		printk(KERN_ERR "Failed to register s5p clocks\n");
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/cpu.c linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/cpu.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/cpu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/cpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,113 @@
+/* linux/arch/arm/plat-s5p/cpu.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P CPU 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/module.h>
+#include <mach/map.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/regs-clock.h>
+#include <plat/cpu.h>
+#include <plat/s5p6440.h>
+#include <plat/s5p6442.h>
+#include <plat/s5pv210.h>
+
+/* table of supported CPUs */
+
+static const char name_s5p6440[] = "S5P6440";
+static const char name_s5p6442[] = "S5P6442";
+static const char name_s5pv210[] = "S5PV210/S5PC110";
+
+static struct cpu_table cpu_ids[] __initdata = {
+	{
+		.idcode		= 0x56440100,
+		.idmask		= 0xffffff00,
+		.map_io		= s5p6440_map_io,
+		.init_clocks	= s5p6440_init_clocks,
+		.init_uarts	= s5p6440_init_uarts,
+		.init		= s5p6440_init,
+		.name		= name_s5p6440,
+	}, {
+		.idcode		= 0x36442000,
+		.idmask		= 0xffffff00,
+		.map_io		= s5p6442_map_io,
+		.init_clocks	= s5p6442_init_clocks,
+		.init_uarts	= s5p6442_init_uarts,
+		.init		= s5p6442_init,
+		.name		= name_s5p6442,
+	}, {
+		.idcode		= 0x43110000,
+		.idmask		= 0xfffff000,
+		.map_io		= s5pv210_map_io,
+		.init_clocks	= s5pv210_init_clocks,
+		.init_uarts	= s5pv210_init_uarts,
+		.init		= s5pv210_init,
+		.name		= name_s5pv210,
+	},
+};
+
+/* minimal IO mapping */
+
+static struct map_desc s5p_iodesc[] __initdata = {
+	{
+		.virtual	= (unsigned long)S5P_VA_CHIPID,
+		.pfn		= __phys_to_pfn(S5P_PA_CHIPID),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S3C_VA_SYS,
+		.pfn		= __phys_to_pfn(S5P_PA_SYSCON),
+		.length		= SZ_64K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S3C_VA_UART,
+		.pfn		= __phys_to_pfn(S3C_PA_UART),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)VA_VIC0,
+		.pfn		= __phys_to_pfn(S5P_PA_VIC0),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)VA_VIC1,
+		.pfn		= __phys_to_pfn(S5P_PA_VIC1),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S3C_VA_TIMER,
+		.pfn		= __phys_to_pfn(S5P_PA_TIMER),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S5P_VA_GPIO,
+		.pfn		= __phys_to_pfn(S5P_PA_GPIO),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	},
+};
+
+/* read cpu identification code */
+
+void __init s5p_init_io(struct map_desc *mach_desc,
+			int size, void __iomem *cpuid_addr)
+{
+	unsigned long idcode;
+
+	/* initialize the io descriptors we need for initialization */
+	iotable_init(s5p_iodesc, ARRAY_SIZE(s5p_iodesc));
+	if (mach_desc)
+		iotable_init(mach_desc, size);
+
+	idcode = __raw_readl(cpuid_addr);
+	s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/dev-uart.c linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/dev-uart.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/dev-uart.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/dev-uart.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,139 @@
+/* linux/arch/arm/plat-s5p/dev-uart.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Base S5P UART resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+ /* Serial port registrations */
+
+static struct resource s5p_uart0_resource[] = {
+	[0] = {
+		.start	= S5P_PA_UART0,
+		.end	= S5P_PA_UART0 + S5P_SZ_UART,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_S5P_UART_RX0,
+		.end	= IRQ_S5P_UART_RX0,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= IRQ_S5P_UART_TX0,
+		.end	= IRQ_S5P_UART_TX0,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start	= IRQ_S5P_UART_ERR0,
+		.end	= IRQ_S5P_UART_ERR0,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct resource s5p_uart1_resource[] = {
+	[0] = {
+		.start	= S5P_PA_UART1,
+		.end	= S5P_PA_UART1 + S5P_SZ_UART,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_S5P_UART_RX1,
+		.end	= IRQ_S5P_UART_RX1,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= IRQ_S5P_UART_TX1,
+		.end	= IRQ_S5P_UART_TX1,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start	= IRQ_S5P_UART_ERR1,
+		.end	= IRQ_S5P_UART_ERR1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource s5p_uart2_resource[] = {
+	[0] = {
+		.start	= S5P_PA_UART2,
+		.end	= S5P_PA_UART2 + S5P_SZ_UART,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_S5P_UART_RX2,
+		.end	= IRQ_S5P_UART_RX2,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= IRQ_S5P_UART_TX2,
+		.end	= IRQ_S5P_UART_TX2,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start	= IRQ_S5P_UART_ERR2,
+		.end	= IRQ_S5P_UART_ERR2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource s5p_uart3_resource[] = {
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 3
+	[0] = {
+		.start	= S5P_PA_UART3,
+		.end	= S5P_PA_UART3 + S5P_SZ_UART,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_S5P_UART_RX3,
+		.end	= IRQ_S5P_UART_RX3,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= IRQ_S5P_UART_TX3,
+		.end	= IRQ_S5P_UART_TX3,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start	= IRQ_S5P_UART_ERR3,
+		.end	= IRQ_S5P_UART_ERR3,
+		.flags	= IORESOURCE_IRQ,
+	},
+#endif
+};
+
+struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = {
+	[0] = {
+		.resources	= s5p_uart0_resource,
+		.nr_resources	= ARRAY_SIZE(s5p_uart0_resource),
+	},
+	[1] = {
+		.resources	= s5p_uart1_resource,
+		.nr_resources	= ARRAY_SIZE(s5p_uart1_resource),
+	},
+	[2] = {
+		.resources	= s5p_uart2_resource,
+		.nr_resources	= ARRAY_SIZE(s5p_uart2_resource),
+	},
+	[3] = {
+		.resources	= s5p_uart3_resource,
+		.nr_resources	= ARRAY_SIZE(s5p_uart3_resource),
+	},
+};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/include/plat/irqs.h linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/include/plat/irqs.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/include/plat/irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/include/plat/irqs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,90 @@
+/* linux/arch/arm/plat-s5p/include/plat/irqs.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P Common IRQ support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_S5P_IRQS_H
+#define __ASM_PLAT_S5P_IRQS_H __FILE__
+
+/* we keep the first set of CPU IRQs out of the range of
+ * the ISA space, so that the PC104 has them to itself
+ * and we don't end up having to do horrible things to the
+ * standard ISA drivers....
+ *
+ * note, since we're using the VICs, our start must be a
+ * mulitple of 32 to allow the common code to work
+ */
+
+#define S5P_IRQ_OFFSET		(32)
+
+#define S5P_IRQ(x)		((x) + S5P_IRQ_OFFSET)
+
+#define S5P_VIC0_BASE		S5P_IRQ(0)
+#define S5P_VIC1_BASE		S5P_IRQ(32)
+#define S5P_VIC2_BASE		S5P_IRQ(64)
+#define S5P_VIC3_BASE		S5P_IRQ(96)
+
+#define VIC_BASE(x)		(S5P_VIC0_BASE + ((x)*32))
+
+#define IRQ_VIC0_BASE		S5P_VIC0_BASE
+#define IRQ_VIC1_BASE		S5P_VIC1_BASE
+#define IRQ_VIC2_BASE		S5P_VIC2_BASE
+
+/* UART interrupts, each UART has 4 intterupts per channel so
+ * use the space between the ISA and S3C main interrupts. Note, these
+ * are not in the same order as the S3C24XX series! */
+
+#define IRQ_S5P_UART_BASE0	(16)
+#define IRQ_S5P_UART_BASE1	(20)
+#define IRQ_S5P_UART_BASE2	(24)
+#define IRQ_S5P_UART_BASE3	(28)
+
+#define UART_IRQ_RXD		(0)
+#define UART_IRQ_ERR		(1)
+#define UART_IRQ_TXD		(2)
+
+#define IRQ_S5P_UART_RX0	(IRQ_S5P_UART_BASE0 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX0	(IRQ_S5P_UART_BASE0 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR0	(IRQ_S5P_UART_BASE0 + UART_IRQ_ERR)
+
+#define IRQ_S5P_UART_RX1	(IRQ_S5P_UART_BASE1 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX1	(IRQ_S5P_UART_BASE1 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR1	(IRQ_S5P_UART_BASE1 + UART_IRQ_ERR)
+
+#define IRQ_S5P_UART_RX2	(IRQ_S5P_UART_BASE2 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX2	(IRQ_S5P_UART_BASE2 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR2	(IRQ_S5P_UART_BASE2 + UART_IRQ_ERR)
+
+#define IRQ_S5P_UART_RX3	(IRQ_S5P_UART_BASE3 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX3	(IRQ_S5P_UART_BASE3 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR3	(IRQ_S5P_UART_BASE3 + UART_IRQ_ERR)
+
+/* S3C compatibilty defines */
+#define IRQ_S3CUART_RX0		IRQ_S5P_UART_RX0
+#define IRQ_S3CUART_RX1		IRQ_S5P_UART_RX1
+#define IRQ_S3CUART_RX2		IRQ_S5P_UART_RX2
+#define IRQ_S3CUART_RX3		IRQ_S5P_UART_RX3
+
+/* VIC based IRQs */
+
+#define S5P_IRQ_VIC0(x)		(S5P_VIC0_BASE + (x))
+#define S5P_IRQ_VIC1(x)		(S5P_VIC1_BASE + (x))
+#define S5P_IRQ_VIC2(x)		(S5P_VIC2_BASE + (x))
+#define S5P_IRQ_VIC3(x)		(S5P_VIC3_BASE + (x))
+
+#define S5P_TIMER_IRQ(x)	S5P_IRQ(11 + (x))
+
+#define IRQ_TIMER0		S5P_TIMER_IRQ(0)
+#define IRQ_TIMER1		S5P_TIMER_IRQ(1)
+#define IRQ_TIMER2		S5P_TIMER_IRQ(2)
+#define IRQ_TIMER3		S5P_TIMER_IRQ(3)
+#define IRQ_TIMER4		S5P_TIMER_IRQ(4)
+
+#endif /* __ASM_PLAT_S5P_IRQS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/include/plat/map-s5p.h linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/include/plat/map-s5p.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/include/plat/map-s5p.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/include/plat/map-s5p.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,34 @@
+/* linux/arch/arm/plat-s5p/include/plat/map-s5p.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P - Memory 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_PLAT_MAP_S5P_H
+#define __ASM_PLAT_MAP_S5P_H __FILE__
+
+#define S5P_VA_CHIPID		S3C_ADDR(0x00700000)
+#define S5P_VA_GPIO		S3C_ADDR(0x00500000)
+#define S5P_VA_SYSTIMER		S3C_ADDR(0x01200000)
+#define S5P_VA_SROMC		S3C_ADDR(0x01100000)
+
+#define S5P_VA_UART0		(S3C_VA_UART + 0x0)
+#define S5P_VA_UART1		(S3C_VA_UART + 0x400)
+#define S5P_VA_UART2		(S3C_VA_UART + 0x800)
+#define S5P_VA_UART3		(S3C_VA_UART + 0xC00)
+
+#define S3C_UART_OFFSET		(0x400)
+
+#define VA_VIC(x)		(S3C_VA_IRQ + ((x) * 0x10000))
+#define VA_VIC0			VA_VIC(0)
+#define VA_VIC1			VA_VIC(1)
+#define VA_VIC2			VA_VIC(2)
+#define VA_VIC3			VA_VIC(3)
+
+#endif /* __ASM_PLAT_MAP_S5P_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/include/plat/pll.h linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/include/plat/pll.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/include/plat/pll.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/include/plat/pll.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,83 @@
+/* arch/arm/plat-s5p/include/plat/pll.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P PLL code
+ *
+ * Based on arch/arm/plat-s3c64xx/include/plat/pll.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 PLL45XX_MDIV_MASK	(0x3FF)
+#define PLL45XX_PDIV_MASK	(0x3F)
+#define PLL45XX_SDIV_MASK	(0x7)
+#define PLL45XX_MDIV_SHIFT	(16)
+#define PLL45XX_PDIV_SHIFT	(8)
+#define PLL45XX_SDIV_SHIFT	(0)
+
+#include <asm/div64.h>
+
+enum pll45xx_type_t {
+	pll_4500,
+	pll_4502,
+	pll_4508
+};
+
+static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
+					    enum pll45xx_type_t pll_type)
+{
+	u32 mdiv, pdiv, sdiv;
+	u64 fvco = baseclk;
+
+	mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
+	pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
+	sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
+
+	if (pll_type == pll_4508)
+		sdiv = sdiv - 1;
+
+	fvco *= mdiv;
+	do_div(fvco, (pdiv << sdiv));
+
+	return (unsigned long)fvco;
+}
+
+#define PLL90XX_MDIV_MASK	(0xFF)
+#define PLL90XX_PDIV_MASK	(0x3F)
+#define PLL90XX_SDIV_MASK	(0x7)
+#define PLL90XX_KDIV_MASK	(0xffff)
+#define PLL90XX_MDIV_SHIFT	(16)
+#define PLL90XX_PDIV_SHIFT	(8)
+#define PLL90XX_SDIV_SHIFT	(0)
+#define PLL90XX_KDIV_SHIFT	(0)
+
+static inline unsigned long s5p_get_pll90xx(unsigned long baseclk,
+					    u32 pll_con, u32 pll_conk)
+{
+	unsigned long result;
+	u32 mdiv, pdiv, sdiv, kdiv;
+	u64 tmp;
+
+	mdiv = (pll_con >> PLL90XX_MDIV_SHIFT) & PLL90XX_MDIV_MASK;
+	pdiv = (pll_con >> PLL90XX_PDIV_SHIFT) & PLL90XX_PDIV_MASK;
+	sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK;
+	kdiv = pll_conk & PLL90XX_KDIV_MASK;
+
+	/* We need to multiple baseclk by mdiv (the integer part) and kdiv
+	 * which is in 2^16ths, so shift mdiv up (does not overflow) and
+	 * add kdiv before multiplying. The use of tmp is to avoid any
+	 * overflows before shifting bac down into result when multipling
+	 * by the mdiv and kdiv pair.
+	 */
+
+	tmp = baseclk;
+	tmp *= (mdiv << 16) + kdiv;
+	do_div(tmp, (pdiv << sdiv));
+	result = tmp >> 16;
+
+	return result;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/include/plat/s5p6440.h linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/include/plat/s5p6440.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/include/plat/s5p6440.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/include/plat/s5p6440.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,37 @@
+/* arch/arm/plat-s5p/include/plat/s5p6440.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Header file for s5p6440 cpu 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.
+*/
+
+ /* Common init code for S5P6440 related SoCs */
+
+extern void s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s5p6440_register_clocks(void);
+extern void s5p6440_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5P6440
+
+extern  int s5p6440_init(void);
+extern void s5p6440_init_irq(void);
+extern void s5p6440_map_io(void);
+extern void s5p6440_init_clocks(int xtal);
+
+#define s5p6440_init_uarts s5p6440_common_init_uarts
+
+#else
+#define s5p6440_init_clocks NULL
+#define s5p6440_init_uarts NULL
+#define s5p6440_map_io NULL
+#define s5p6440_init NULL
+#endif
+
+/* S5P6440 timer */
+
+extern struct sys_timer s5p6440_timer;
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/include/plat/s5p6442.h linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/include/plat/s5p6442.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/include/plat/s5p6442.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/include/plat/s5p6442.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,33 @@
+/* arch/arm/plat-s5p/include/plat/s5p6442.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Header file for s5p6442 cpu 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.
+*/
+
+/* Common init code for S5P6442 related SoCs */
+
+extern void s5p6442_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s5p6442_register_clocks(void);
+extern void s5p6442_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5P6442
+
+extern  int s5p6442_init(void);
+extern void s5p6442_init_irq(void);
+extern void s5p6442_map_io(void);
+extern void s5p6442_init_clocks(int xtal);
+
+#define s5p6442_init_uarts s5p6442_common_init_uarts
+
+#else
+#define s5p6442_init_clocks NULL
+#define s5p6442_init_uarts NULL
+#define s5p6442_map_io NULL
+#define s5p6442_init NULL
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/include/plat/s5p-clock.h linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/include/plat/s5p-clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/include/plat/s5p-clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/include/plat/s5p-clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,40 @@
+/* linux/arch/arm/plat-s5p/include/plat/s5p-clock.h
+ *
+ * Copyright 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Header file for s5p clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_S5P_CLOCK_H
+#define __ASM_PLAT_S5P_CLOCK_H __FILE__
+
+#include <linux/clk.h>
+
+#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
+
+#define clk_fin_apll clk_ext_xtal_mux
+#define clk_fin_mpll clk_ext_xtal_mux
+#define clk_fin_epll clk_ext_xtal_mux
+#define clk_fin_vpll clk_ext_xtal_mux
+
+extern struct clk clk_ext_xtal_mux;
+extern struct clk clk_48m;
+extern struct clk clk_fout_apll;
+extern struct clk clk_fout_mpll;
+extern struct clk clk_fout_epll;
+extern struct clk clk_arm;
+extern struct clk clk_vpll;
+
+extern struct clksrc_sources clk_src_apll;
+extern struct clksrc_sources clk_src_mpll;
+extern struct clksrc_sources clk_src_epll;
+
+extern int s5p6440_clk48m_ctrl(struct clk *clk, int enable);
+extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable);
+
+#endif /* __ASM_PLAT_S5P_CLOCK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/include/plat/s5pv210.h linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/include/plat/s5pv210.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/include/plat/s5pv210.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/include/plat/s5pv210.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,33 @@
+/* linux/arch/arm/plat-s5p/include/plat/s5pv210.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Header file for s5pv210 cpu 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.
+*/
+
+/* Common init code for S5PV210 related SoCs */
+
+extern void s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s5pv210_register_clocks(void);
+extern void s5pv210_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5PV210
+
+extern  int s5pv210_init(void);
+extern void s5pv210_init_irq(void);
+extern void s5pv210_map_io(void);
+extern void s5pv210_init_clocks(int xtal);
+
+#define s5pv210_init_uarts s5pv210_common_init_uarts
+
+#else
+#define s5pv210_init_clocks NULL
+#define s5pv210_init_uarts NULL
+#define s5pv210_map_io NULL
+#define s5pv210_init NULL
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/irq.c linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/irq.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,72 @@
+/* arch/arm/plat-s5p/irq.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P - Interrupt handling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/hardware/vic.h>
+
+#include <linux/serial_core.h>
+#include <mach/map.h>
+#include <plat/regs-timer.h>
+#include <plat/regs-serial.h>
+#include <plat/cpu.h>
+#include <plat/irq-vic-timer.h>
+#include <plat/irq-uart.h>
+
+/*
+ * Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
+ * are consecutive when looking up the interrupt in the demux routines.
+ */
+static struct s3c_uart_irq uart_irqs[] = {
+	[0] = {
+		.regs		= S5P_VA_UART0,
+		.base_irq	= IRQ_S5P_UART_BASE0,
+		.parent_irq	= IRQ_UART0,
+	},
+	[1] = {
+		.regs		= S5P_VA_UART1,
+		.base_irq	= IRQ_S5P_UART_BASE1,
+		.parent_irq	= IRQ_UART1,
+	},
+	[2] = {
+		.regs		= S5P_VA_UART2,
+		.base_irq	= IRQ_S5P_UART_BASE2,
+		.parent_irq	= IRQ_UART2,
+	},
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 3
+	[3] = {
+		.regs		= S5P_VA_UART3,
+		.base_irq	= IRQ_S5P_UART_BASE3,
+		.parent_irq	= IRQ_UART3,
+	},
+#endif
+};
+
+void __init s5p_init_irq(u32 *vic, u32 num_vic)
+{
+	int irq;
+
+	/* initialize the VICs */
+	for (irq = 0; irq < num_vic; irq++)
+		vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0);
+
+	s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0);
+	s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1);
+	s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2);
+	s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3);
+	s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4);
+
+	s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/Kconfig linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,25 @@
+# arch/arm/plat-s5p/Kconfig
+#
+# Copyright (c) 2009 Samsung Electronics Co., Ltd.
+#		http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+config PLAT_S5P
+	bool
+	depends on (ARCH_S5P6440 || ARCH_S5P6442 || ARCH_S5PV210)
+	default y
+	select ARM_VIC
+	select NO_IOPORT
+	select ARCH_REQUIRE_GPIOLIB
+	select S3C_GPIO_TRACK
+	select SAMSUNG_GPIOLIB_4BIT
+	select S3C_GPIO_CFG_S3C64XX
+	select S3C_GPIO_PULL_UPDOWN
+	select S3C_GPIO_CFG_S3C24XX
+	select PLAT_SAMSUNG
+	select SAMSUNG_CLKSRC
+	select SAMSUNG_IRQ_VIC_TIMER
+	select SAMSUNG_IRQ_UART
+	help
+	  Base platform code for Samsung's S5P series SoC.
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/Makefile linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,19 @@
+# arch/arm/plat-s5p/Makefile
+#
+# Copyright (c) 2009 Samsung Electronics Co., Ltd.
+# 		http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:= dummy.o
+obj-				:=
+
+# Core files
+
+obj-y				+= dev-uart.o
+obj-y				+= cpu.o
+obj-y				+= clock.o
+obj-y				+= irq.o
+obj-y				+= setup-i2c0.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/setup-i2c0.c linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/setup-i2c0.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5p/setup-i2c0.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5p/setup-i2c0.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,25 @@
+/* linux/arch/arm/plat-s5p/setup-i2c0.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * I2C0 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/setup-i2c0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/iic.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+	/* Will be populated later */
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/clock.c linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,25 +64,13 @@ struct clk clk_54m = {
 	.rate		= 54000000,
 };
 
-static int clk_default_setrate(struct clk *clk, unsigned long rate)
-{
-	clk->rate = rate;
-	return 0;
-}
-
-static int clk_dummy_enable(struct clk *clk, int enable)
-{
-	return 0;
-}
-
 struct clk clk_hd0 = {
 	.name		= "hclkd0",
 	.id		= -1,
 	.rate		= 0,
 	.parent		= NULL,
 	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
-	.enable		= clk_dummy_enable,
+	.ops		= &clk_ops_def_setrate,
 };
 
 struct clk clk_pd0 = {
@@ -91,8 +79,7 @@ struct clk clk_pd0 = {
 	.rate		= 0,
 	.parent		= NULL,
 	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
-	.enable		= clk_dummy_enable,
+	.ops		= &clk_ops_def_setrate,
 };
 
 static int s5pc1xx_clk_gate(void __iomem *reg, struct clk *clk, int enable)
@@ -686,6 +673,8 @@ static struct clk s5pc100_init_clocks[]
 static struct clk *clks[] __initdata = {
 	&clk_ext,
 	&clk_epll,
+	&clk_pd0,
+	&clk_hd0,
 	&clk_27m,
 	&clk_48m,
 	&clk_54m,
@@ -700,16 +689,8 @@ void __init s5pc1xx_register_clocks(void
 
 	s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
 
-	clkp = s5pc100_init_clocks;
-	size = ARRAY_SIZE(s5pc100_init_clocks);
-
-	for (ptr = 0; ptr < size; ptr++, clkp++) {
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-	}
+	s3c_register_clocks(s5pc100_init_clocks,
+			    ARRAY_SIZE(s5pc100_init_clocks));
 
 	clkp = s5pc100_init_clocks_disable;
 	size = ARRAY_SIZE(s5pc100_init_clocks_disable);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/dev-uart.c linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/dev-uart.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/dev-uart.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/dev-uart.c	2010-05-16 17:17:36.000000000 -0400
@@ -143,32 +143,3 @@ struct s3c24xx_uart_resources s5pc1xx_ua
 		.nr_resources	= ARRAY_SIZE(s5pc1xx_uart3_resource),
 	},
 };
-
-/* uart devices */
-
-static struct platform_device s3c24xx_uart_device0 = {
-	.id		= 0,
-};
-
-static struct platform_device s3c24xx_uart_device1 = {
-	.id		= 1,
-};
-
-static struct platform_device s3c24xx_uart_device2 = {
-	.id		= 2,
-};
-
-static struct platform_device s3c24xx_uart_device3 = {
-	.id		= 3,
-};
-
-struct platform_device *s3c24xx_uart_src[4] = {
-	&s3c24xx_uart_device0,
-	&s3c24xx_uart_device1,
-	&s3c24xx_uart_device2,
-	&s3c24xx_uart_device3,
-};
-
-struct platform_device *s3c24xx_uart_devs[4] = {
-};
-
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/gpio-config.c linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/gpio-config.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/gpio-config.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/gpio-config.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,7 @@
 #include <linux/gpio.h>
 #include <linux/io.h>
 
-#include <mach/gpio-core.h>
+#include <plat/gpio-core.h>
 #include <plat/gpio-cfg-s5pc1xx.h>
 
 s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/gpiolib.c linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/gpiolib.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/gpiolib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/gpiolib.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,8 +17,8 @@
 #include <linux/gpio.h>
 
 #include <mach/map.h>
-#include <mach/gpio-core.h>
 
+#include <plat/gpio-core.h>
 #include <plat/gpio-cfg.h>
 #include <plat/gpio-cfg-helpers.h>
 #include <plat/regs-gpio.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/irqs.h linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/include/plat/irqs.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/irqs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/include/plat/irqs.h	2010-05-16 17:17:36.000000000 -0400
@@ -88,11 +88,11 @@
 #define IRQ_MDMA		S5PC1XX_IRQ_VIC0(18)
 #define IRQ_PDMA0		S5PC1XX_IRQ_VIC0(19)
 #define IRQ_PDMA1		S5PC1XX_IRQ_VIC0(20)
-#define IRQ_TIMER0		S5PC1XX_IRQ_VIC0(21)
-#define IRQ_TIMER1		S5PC1XX_IRQ_VIC0(22)
-#define IRQ_TIMER2		S5PC1XX_IRQ_VIC0(23)
-#define IRQ_TIMER3		S5PC1XX_IRQ_VIC0(24)
-#define IRQ_TIMER4		S5PC1XX_IRQ_VIC0(25)
+#define IRQ_TIMER0_VIC		S5PC1XX_IRQ_VIC0(21)
+#define IRQ_TIMER1_VIC		S5PC1XX_IRQ_VIC0(22)
+#define IRQ_TIMER2_VIC		S5PC1XX_IRQ_VIC0(23)
+#define IRQ_TIMER3_VIC		S5PC1XX_IRQ_VIC0(24)
+#define IRQ_TIMER4_VIC		S5PC1XX_IRQ_VIC0(25)
 #define IRQ_SYSTIMER		S5PC1XX_IRQ_VIC0(26)
 #define IRQ_WDT			S5PC1XX_IRQ_VIC0(27)
 #define IRQ_RTC_ALARM		S5PC1XX_IRQ_VIC0(28)
@@ -171,8 +171,15 @@
 #define IRQ_SDMIRQ		S5PC1XX_IRQ_VIC2(30)
 #define IRQ_SDMFIQ		S5PC1XX_IRQ_VIC2(31)
 
+#define IRQ_TIMER(x)		(IRQ_SDMFIQ + 1 + (x))
+#define IRQ_TIMER0		IRQ_TIMER(0)
+#define IRQ_TIMER1		IRQ_TIMER(1)
+#define IRQ_TIMER2		IRQ_TIMER(2)
+#define IRQ_TIMER3		IRQ_TIMER(3)
+#define IRQ_TIMER4		IRQ_TIMER(4)
+
 /* External interrupt */
-#define S3C_IRQ_EINT_BASE	(IRQ_SDMFIQ + 1)
+#define S3C_IRQ_EINT_BASE	(IRQ_SDMFIQ + 6)
 
 #define S3C_EINT(x)		(S3C_IRQ_EINT_BASE + (x - 16))
 #define IRQ_EINT(x)		(x < 16 ? IRQ_EINT0 + x : S3C_EINT(x))
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -61,73 +61,10 @@
 #define S5PC100_EPLL_MASK		0xffffffff
 #define S5PC100_EPLLVAL(_m, _p, _s)	((_m) << 16 | ((_p) << 8) | ((_s)))
 
-/* CLKSRC0 */
-#define S5PC100_CLKSRC0_APLL_MASK		(0x1<<0)
-#define S5PC100_CLKSRC0_APLL_SHIFT		(0)
-#define S5PC100_CLKSRC0_MPLL_MASK		(0x1<<4)
-#define S5PC100_CLKSRC0_MPLL_SHIFT		(4)
-#define S5PC100_CLKSRC0_EPLL_MASK		(0x1<<8)
-#define S5PC100_CLKSRC0_EPLL_SHIFT		(8)
-#define S5PC100_CLKSRC0_HPLL_MASK		(0x1<<12)
-#define S5PC100_CLKSRC0_HPLL_SHIFT		(12)
-#define S5PC100_CLKSRC0_AMMUX_MASK		(0x1<<16)
-#define S5PC100_CLKSRC0_AMMUX_SHIFT		(16)
-#define S5PC100_CLKSRC0_HREF_MASK		(0x1<<20)
-#define S5PC100_CLKSRC0_HREF_SHIFT		(20)
-#define S5PC100_CLKSRC0_ONENAND_MASK	(0x1<<24)
-#define S5PC100_CLKSRC0_ONENAND_SHIFT	(24)
-
-
-/* CLKSRC1 */
-#define S5PC100_CLKSRC1_UART_MASK		(0x1<<0)
-#define S5PC100_CLKSRC1_UART_SHIFT		(0)
-#define S5PC100_CLKSRC1_SPI0_MASK		(0x3<<4)
-#define S5PC100_CLKSRC1_SPI0_SHIFT		(4)
-#define S5PC100_CLKSRC1_SPI1_MASK		(0x3<<8)
-#define S5PC100_CLKSRC1_SPI1_SHIFT		(8)
-#define S5PC100_CLKSRC1_SPI2_MASK		(0x3<<12)
-#define S5PC100_CLKSRC1_SPI2_SHIFT		(12)
-#define S5PC100_CLKSRC1_IRDA_MASK		(0x3<<16)
-#define S5PC100_CLKSRC1_IRDA_SHIFT		(16)
-#define S5PC100_CLKSRC1_UHOST_MASK		(0x3<<20)
-#define S5PC100_CLKSRC1_UHOST_SHIFT		(20)
-#define S5PC100_CLKSRC1_CLK48M_MASK		(0x1<<24)
+/* CLKSRC0..CLKSRC3 -> mostly removed due to clksrc updates */
+#define S5PC100_CLKSRC1_CLK48M_MASK	(0x1<<24)
 #define S5PC100_CLKSRC1_CLK48M_SHIFT	(24)
 
-/* CLKSRC2 */
-#define S5PC100_CLKSRC2_MMC0_MASK		(0x3<<0)
-#define S5PC100_CLKSRC2_MMC0_SHIFT		(0)
-#define S5PC100_CLKSRC2_MMC1_MASK		(0x3<<4)
-#define S5PC100_CLKSRC2_MMC1_SHIFT		(4)
-#define S5PC100_CLKSRC2_MMC2_MASK		(0x3<<8)
-#define S5PC100_CLKSRC2_MMC2_SHIFT		(8)
-#define S5PC100_CLKSRC2_LCD_MASK		(0x3<<12)
-#define S5PC100_CLKSRC2_LCD_SHIFT		(12)
-#define S5PC100_CLKSRC2_FIMC0_MASK		(0x3<<16)
-#define S5PC100_CLKSRC2_FIMC0_SHIFT		(16)
-#define S5PC100_CLKSRC2_FIMC1_MASK		(0x3<<20)
-#define S5PC100_CLKSRC2_FIMC1_SHIFT		(20)
-#define S5PC100_CLKSRC2_FIMC2_MASK		(0x3<<24)
-#define S5PC100_CLKSRC2_FIMC2_SHIFT		(24)
-#define S5PC100_CLKSRC2_MIXER_MASK		(0x3<<28)
-#define S5PC100_CLKSRC2_MIXER_SHIFT		(28)
-
-/* CLKSRC3 */
-#define S5PC100_CLKSRC3_PWI_MASK		(0x3<<0)
-#define S5PC100_CLKSRC3_PWI_SHIFT		(0)
-#define S5PC100_CLKSRC3_HCLKD2_MASK		(0x1<<4)
-#define S5PC100_CLKSRC3_HCLKD2_SHIFT	(4)
-#define S5PC100_CLKSRC3_I2SD2_MASK		(0x3<<8)
-#define S5PC100_CLKSRC3_I2SD2_SHIFT		(8)
-#define S5PC100_CLKSRC3_AUDIO0_MASK		(0x7<<12)
-#define S5PC100_CLKSRC3_AUDIO0_SHIFT	(12)
-#define S5PC100_CLKSRC3_AUDIO1_MASK		(0x7<<16)
-#define S5PC100_CLKSRC3_AUDIO1_SHIFT	(16)
-#define S5PC100_CLKSRC3_AUDIO2_MASK		(0x7<<20)
-#define S5PC100_CLKSRC3_AUDIO2_SHIFT	(20)
-#define S5PC100_CLKSRC3_SPDIF_MASK		(0x3<<24)
-#define S5PC100_CLKSRC3_SPDIF_SHIFT		(24)
-
 /* CLKDIV0 */
 #define S5PC100_CLKDIV0_APLL_MASK		(0x1<<0)
 #define S5PC100_CLKDIV0_APLL_SHIFT		(0)
@@ -140,7 +77,7 @@
 #define S5PC100_CLKDIV0_SECSS_MASK		(0x7<<16)
 #define S5PC100_CLKDIV0_SECSS_SHIFT		(16)
 
-/* CLKDIV1 */
+/* CLKDIV1 (OneNAND clock only used in one place, removed) */
 #define S5PC100_CLKDIV1_APLL2_MASK		(0x7<<0)
 #define S5PC100_CLKDIV1_APLL2_SHIFT		(0)
 #define S5PC100_CLKDIV1_MPLL_MASK		(0x3<<4)
@@ -151,56 +88,12 @@
 #define S5PC100_CLKDIV1_D1_SHIFT		(12)
 #define S5PC100_CLKDIV1_PCLKD1_MASK		(0x7<<16)
 #define S5PC100_CLKDIV1_PCLKD1_SHIFT	(16)
-#define S5PC100_CLKDIV1_ONENAND_MASK	(0x3<<20)
-#define S5PC100_CLKDIV1_ONENAND_SHIFT	(20)
 #define S5PC100_CLKDIV1_CAM_MASK		(0x1F<<24)
 #define S5PC100_CLKDIV1_CAM_SHIFT		(24)
 
-/* CLKDIV2 */
-#define S5PC100_CLKDIV2_UART_MASK		(0x7<<0)
-#define S5PC100_CLKDIV2_UART_SHIFT		(0)
-#define S5PC100_CLKDIV2_SPI0_MASK		(0xf<<4)
-#define S5PC100_CLKDIV2_SPI0_SHIFT		(4)
-#define S5PC100_CLKDIV2_SPI1_MASK		(0xf<<8)
-#define S5PC100_CLKDIV2_SPI1_SHIFT		(8)
-#define S5PC100_CLKDIV2_SPI2_MASK		(0xf<<12)
-#define S5PC100_CLKDIV2_SPI2_SHIFT		(12)
-#define S5PC100_CLKDIV2_IRDA_MASK		(0xf<<16)
-#define S5PC100_CLKDIV2_IRDA_SHIFT		(16)
-#define S5PC100_CLKDIV2_UHOST_MASK		(0xf<<20)
-#define S5PC100_CLKDIV2_UHOST_SHIFT		(20)
-
-/* CLKDIV3 */
-#define S5PC100_CLKDIV3_MMC0_MASK		(0xf<<0)
-#define S5PC100_CLKDIV3_MMC0_SHIFT		(0)
-#define S5PC100_CLKDIV3_MMC1_MASK		(0xf<<4)
-#define S5PC100_CLKDIV3_MMC1_SHIFT		(4)
-#define S5PC100_CLKDIV3_MMC2_MASK		(0xf<<8)
-#define S5PC100_CLKDIV3_MMC2_SHIFT		(8)
-#define S5PC100_CLKDIV3_LCD_MASK		(0xf<<12)
-#define S5PC100_CLKDIV3_LCD_SHIFT		(12)
-#define S5PC100_CLKDIV3_FIMC0_MASK		(0xf<<16)
-#define S5PC100_CLKDIV3_FIMC0_SHIFT		(16)
-#define S5PC100_CLKDIV3_FIMC1_MASK		(0xf<<20)
-#define S5PC100_CLKDIV3_FIMC1_SHIFT		(20)
-#define S5PC100_CLKDIV3_FIMC2_MASK		(0xf<<24)
-#define S5PC100_CLKDIV3_FIMC2_SHIFT		(24)
-#define S5PC100_CLKDIV3_HDMI_MASK		(0xf<<28)
-#define S5PC100_CLKDIV3_HDMI_SHIFT		(28)
-
-/* CLKDIV4 */
-#define S5PC100_CLKDIV4_PWI_MASK		(0x7<<0)
-#define S5PC100_CLKDIV4_PWI_SHIFT		(0)
-#define S5PC100_CLKDIV4_HCLKD2_MASK		(0x7<<4)
-#define S5PC100_CLKDIV4_HCLKD2_SHIFT	(4)
-#define S5PC100_CLKDIV4_I2SD2_MASK		(0xf<<8)
-#define S5PC100_CLKDIV4_I2SD2_SHIFT		(8)
-#define S5PC100_CLKDIV4_AUDIO0_MASK		(0xf<<12)
-#define S5PC100_CLKDIV4_AUDIO0_SHIFT	(12)
-#define S5PC100_CLKDIV4_AUDIO1_MASK		(0xf<<16)
-#define S5PC100_CLKDIV4_AUDIO1_SHIFT	(16)
-#define S5PC100_CLKDIV4_AUDIO2_MASK		(0xf<<20)
-#define S5PC100_CLKDIV4_AUDIO2_SHIFT	(20)
+/* CLKDIV2 => removed in clksrc update */
+/* CLKDIV3 => removed in clksrc update, or not needed */
+/* CLKDIV4 => removed in clksrc update, or not needed */
 
 /* HCLKD0/PCLKD0 Clock Gate 0 Registers */
 #define S5PC100_CLKGATE_D00_INTC		(1<<0)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/irq.c linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/irq.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,87 +20,14 @@
 #include <asm/hardware/vic.h>
 
 #include <mach/map.h>
-#include <plat/regs-timer.h>
+#include <plat/irq-vic-timer.h>
+#include <plat/irq-uart.h>
 #include <plat/cpu.h>
 
-/* Timer interrupt handling */
-
-static void s3c_irq_demux_timer(unsigned int base_irq, unsigned int sub_irq)
-{
-	generic_handle_irq(sub_irq);
-}
-
-static void s3c_irq_demux_timer0(unsigned int irq, struct irq_desc *desc)
-{
-	s3c_irq_demux_timer(irq, IRQ_TIMER0);
-}
-
-static void s3c_irq_demux_timer1(unsigned int irq, struct irq_desc *desc)
-{
-	s3c_irq_demux_timer(irq, IRQ_TIMER1);
-}
-
-static void s3c_irq_demux_timer2(unsigned int irq, struct irq_desc *desc)
-{
-	s3c_irq_demux_timer(irq, IRQ_TIMER2);
-}
-
-static void s3c_irq_demux_timer3(unsigned int irq, struct irq_desc *desc)
-{
-	s3c_irq_demux_timer(irq, IRQ_TIMER3);
-}
-
-static void s3c_irq_demux_timer4(unsigned int irq, struct irq_desc *desc)
-{
-	s3c_irq_demux_timer(irq, IRQ_TIMER4);
-}
-
-/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
-
-static void s3c_irq_timer_mask(unsigned int irq)
-{
-	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
-
-	reg &= 0x1f;  /* mask out pending interrupts */
-	reg &= ~(1 << (irq - IRQ_TIMER0));
-	__raw_writel(reg, S3C64XX_TINT_CSTAT);
-}
-
-static void s3c_irq_timer_unmask(unsigned int irq)
-{
-	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
-
-	reg &= 0x1f;  /* mask out pending interrupts */
-	reg |= 1 << (irq - IRQ_TIMER0);
-	__raw_writel(reg, S3C64XX_TINT_CSTAT);
-}
-
-static void s3c_irq_timer_ack(unsigned int irq)
-{
-	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
-
-	reg &= 0x1f;  /* mask out pending interrupts */
-	reg |= (1 << 5) << (irq - IRQ_TIMER0);
-	__raw_writel(reg, S3C64XX_TINT_CSTAT);
-}
-
-static struct irq_chip s3c_irq_timer = {
-	.name		= "s3c-timer",
-	.mask		= s3c_irq_timer_mask,
-	.unmask		= s3c_irq_timer_unmask,
-	.ack		= s3c_irq_timer_ack,
-};
-
-struct uart_irq {
-	void __iomem	*regs;
-	unsigned int	 base_irq;
-	unsigned int	 parent_irq;
-};
-
 /* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
  * are consecutive when looking up the interrupt in the demux routines.
  */
-static struct uart_irq uart_irqs[] = {
+static struct s3c_uart_irq uart_irqs[] = {
 	[0] = {
 		.regs		= (void *)S3C_VA_UART0,
 		.base_irq	= IRQ_S3CUART_BASE0,
@@ -123,113 +50,9 @@ static struct uart_irq uart_irqs[] = {
 	},
 };
 
-static inline void __iomem *s3c_irq_uart_base(unsigned int irq)
-{
-	struct uart_irq *uirq = get_irq_chip_data(irq);
-	return uirq->regs;
-}
-
-static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
-{
-	return irq & 3;
-}
-
-/* UART interrupt registers, not worth adding to seperate include header */
-#define S3C64XX_UINTP	0x30
-#define S3C64XX_UINTSP	0x34
-#define S3C64XX_UINTM	0x38
-
-static void s3c_irq_uart_mask(unsigned int irq)
-{
-	void __iomem *regs = s3c_irq_uart_base(irq);
-	unsigned int bit = s3c_irq_uart_bit(irq);
-	u32 reg;
-
-	reg = __raw_readl(regs + S3C64XX_UINTM);
-	reg |= (1 << bit);
-	__raw_writel(reg, regs + S3C64XX_UINTM);
-}
-
-static void s3c_irq_uart_maskack(unsigned int irq)
-{
-	void __iomem *regs = s3c_irq_uart_base(irq);
-	unsigned int bit = s3c_irq_uart_bit(irq);
-	u32 reg;
-
-	reg = __raw_readl(regs + S3C64XX_UINTM);
-	reg |= (1 << bit);
-	__raw_writel(reg, regs + S3C64XX_UINTM);
-	__raw_writel(1 << bit, regs + S3C64XX_UINTP);
-}
-
-static void s3c_irq_uart_unmask(unsigned int irq)
-{
-	void __iomem *regs = s3c_irq_uart_base(irq);
-	unsigned int bit = s3c_irq_uart_bit(irq);
-	u32 reg;
-
-	reg = __raw_readl(regs + S3C64XX_UINTM);
-	reg &= ~(1 << bit);
-	__raw_writel(reg, regs + S3C64XX_UINTM);
-}
-
-static void s3c_irq_uart_ack(unsigned int irq)
-{
-	void __iomem *regs = s3c_irq_uart_base(irq);
-	unsigned int bit = s3c_irq_uart_bit(irq);
-
-	__raw_writel(1 << bit, regs + S3C64XX_UINTP);
-}
-
-static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
-{
-	struct uart_irq *uirq = &uart_irqs[irq - IRQ_UART0];
-	u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
-	int base = uirq->base_irq;
-
-	if (pend & (1 << 0))
-		generic_handle_irq(base);
-	if (pend & (1 << 1))
-		generic_handle_irq(base + 1);
-	if (pend & (1 << 2))
-		generic_handle_irq(base + 2);
-	if (pend & (1 << 3))
-		generic_handle_irq(base + 3);
-}
-
-static struct irq_chip s3c_irq_uart = {
-	.name		= "s3c-uart",
-	.mask		= s3c_irq_uart_mask,
-	.unmask		= s3c_irq_uart_unmask,
-	.mask_ack	= s3c_irq_uart_maskack,
-	.ack		= s3c_irq_uart_ack,
-};
-
-static void __init s5pc1xx_uart_irq(struct uart_irq *uirq)
-{
-	void __iomem *reg_base = uirq->regs;
-	unsigned int irq;
-	int offs;
-
-	/* mask all interrupts at the start. */
-	__raw_writel(0xf, reg_base + S3C64XX_UINTM);
-
-	for (offs = 0; offs < 3; offs++) {
-		irq = uirq->base_irq + offs;
-
-		set_irq_chip(irq, &s3c_irq_uart);
-		set_irq_chip_data(irq, uirq);
-		set_irq_handler(irq, handle_level_irq);
-		set_irq_flags(irq, IRQF_VALID);
-	}
-
-	set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
-}
-
 void __init s5pc1xx_init_irq(u32 *vic_valid, int num)
 {
 	int i;
-	int uart, irq;
 
 	printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
 
@@ -240,20 +63,13 @@ void __init s5pc1xx_init_irq(u32 *vic_va
 
 	/* add the timer sub-irqs */
 
-	set_irq_chained_handler(IRQ_TIMER0, s3c_irq_demux_timer0);
-	set_irq_chained_handler(IRQ_TIMER1, s3c_irq_demux_timer1);
-	set_irq_chained_handler(IRQ_TIMER2, s3c_irq_demux_timer2);
-	set_irq_chained_handler(IRQ_TIMER3, s3c_irq_demux_timer3);
-	set_irq_chained_handler(IRQ_TIMER4, s3c_irq_demux_timer4);
-
-	for (irq = IRQ_TIMER0; irq <= IRQ_TIMER4; irq++) {
-		set_irq_chip(irq, &s3c_irq_timer);
-		set_irq_handler(irq, handle_level_irq);
-		set_irq_flags(irq, IRQF_VALID);
-	}
+	s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0);
+	s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1);
+	s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2);
+	s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3);
+	s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4);
 
-	for (uart = 0; uart < ARRAY_SIZE(uart_irqs); uart++)
-		s5pc1xx_uart_irq(&uart_irqs[uart]);
+	s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
 }
 
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/Kconfig linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,9 @@ config PLAT_S5PC1XX
 	select ARM_VIC
 	select NO_IOPORT
 	select ARCH_REQUIRE_GPIOLIB
+	select SAMSUNG_CLKSRC
+	select SAMSUNG_IRQ_UART
+	select SAMSUNG_IRQ_VIC_TIMER
 	select S3C_GPIO_TRACK
 	select S3C_GPIO_PULL_UPDOWN
 	select S3C_GPIO_CFG_S3C24XX
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/s5pc100-clock.c linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/s5pc100-clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/s5pc100-clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-s5pc1xx/s5pc100-clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 
 #include <plat/regs-clock.h>
 #include <plat/clock.h>
+#include <plat/clock-clksrc.h>
 #include <plat/cpu.h>
 #include <plat/pll.h>
 #include <plat/devs.h>
@@ -51,23 +52,6 @@ static struct clk clk_ext_xtal_mux = {
 #define clk_fout_mpll	clk_mpll
 #define clk_vclk_54m	clk_54m
 
-struct clk_sources {
-	unsigned int	nr_sources;
-	struct clk	**sources;
-};
-
-struct clksrc_clk {
-	struct clk		clk;
-	unsigned int		mask;
-	unsigned int		shift;
-
-	struct clk_sources	*sources;
-
-	unsigned int		divider_shift;
-	void __iomem		*reg_divider;
-	void __iomem		*reg_source;
-};
-
 /* APLL */
 static struct clk clk_fout_apll = {
 	.name		= "fout_apll",
@@ -80,7 +64,7 @@ static struct clk *clk_src_apll_list[] =
 	[1] = &clk_fout_apll,
 };
 
-static struct clk_sources clk_src_apll = {
+static struct clksrc_sources clk_src_apll = {
 	.sources	= clk_src_apll_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_apll_list),
 };
@@ -90,10 +74,8 @@ static struct clksrc_clk clk_mout_apll =
 		.name		= "mout_apll",
 		.id		= -1,
 	},
-	.shift		= S5PC100_CLKSRC0_APLL_SHIFT,
-	.mask		= S5PC100_CLKSRC0_APLL_MASK,
 	.sources	= &clk_src_apll,
-	.reg_source	= S5PC100_CLKSRC0,
+	.reg_src = { .reg = S5PC100_CLKSRC0, .shift = 0, .size = 1, },
 };
 
 static unsigned long s5pc100_clk_dout_apll_get_rate(struct clk *clk)
@@ -111,7 +93,9 @@ static struct clk clk_dout_apll = {
 	.name		= "dout_apll",
 	.id		= -1,
 	.parent		= &clk_mout_apll.clk,
-	.get_rate	= s5pc100_clk_dout_apll_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_apll_get_rate,
+	},
 };
 
 static unsigned long s5pc100_clk_arm_get_rate(struct clk *clk)
@@ -165,9 +149,11 @@ static struct clk clk_arm = {
 	.name		= "armclk",
 	.id		= -1,
 	.parent		= &clk_dout_apll,
-	.get_rate	= s5pc100_clk_arm_get_rate,
-	.set_rate	= s5pc100_clk_arm_set_rate,
-	.round_rate	= s5pc100_clk_arm_round_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_arm_get_rate,
+		.set_rate	= s5pc100_clk_arm_set_rate,
+		.round_rate	= s5pc100_clk_arm_round_rate,
+	},
 };
 
 static unsigned long s5pc100_clk_dout_d0_bus_get_rate(struct clk *clk)
@@ -185,7 +171,9 @@ static struct clk clk_dout_d0_bus = {
 	.name		= "dout_d0_bus",
 	.id		= -1,
 	.parent		= &clk_arm,
-	.get_rate	= s5pc100_clk_dout_d0_bus_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_d0_bus_get_rate,
+	},
 };
 
 static unsigned long s5pc100_clk_dout_pclkd0_get_rate(struct clk *clk)
@@ -203,7 +191,9 @@ static struct clk clk_dout_pclkd0 = {
 	.name		= "dout_pclkd0",
 	.id		= -1,
 	.parent		= &clk_dout_d0_bus,
-	.get_rate	= s5pc100_clk_dout_pclkd0_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_pclkd0_get_rate,
+	},
 };
 
 static unsigned long s5pc100_clk_dout_apll2_get_rate(struct clk *clk)
@@ -221,7 +211,9 @@ static struct clk clk_dout_apll2 = {
 	.name		= "dout_apll2",
 	.id		= -1,
 	.parent		= &clk_mout_apll.clk,
-	.get_rate	= s5pc100_clk_dout_apll2_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_apll2_get_rate,
+	},
 };
 
 /* MPLL */
@@ -230,7 +222,7 @@ static struct clk *clk_src_mpll_list[] =
 	[1] = &clk_fout_mpll,
 };
 
-static struct clk_sources clk_src_mpll = {
+static struct clksrc_sources clk_src_mpll = {
 	.sources	= clk_src_mpll_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_mpll_list),
 };
@@ -240,10 +232,8 @@ static struct clksrc_clk clk_mout_mpll =
 		.name		= "mout_mpll",
 		.id		= -1,
 	},
-	.shift		= S5PC100_CLKSRC0_MPLL_SHIFT,
-	.mask		= S5PC100_CLKSRC0_MPLL_MASK,
 	.sources	= &clk_src_mpll,
-	.reg_source	= S5PC100_CLKSRC0,
+	.reg_src = { .reg = S5PC100_CLKSRC0, .shift = 4, .size = 1, },
 };
 
 static struct clk *clkset_am_list[] = {
@@ -251,7 +241,7 @@ static struct clk *clkset_am_list[] = {
 	[1] = &clk_dout_apll2,
 };
 
-static struct clk_sources clk_src_am = {
+static struct clksrc_sources clk_src_am = {
 	.sources	= clkset_am_list,
 	.nr_sources	= ARRAY_SIZE(clkset_am_list),
 };
@@ -261,10 +251,8 @@ static struct clksrc_clk clk_mout_am = {
 		.name		= "mout_am",
 		.id		= -1,
 	},
-	.shift		= S5PC100_CLKSRC0_AMMUX_SHIFT,
-	.mask		= S5PC100_CLKSRC0_AMMUX_MASK,
 	.sources	= &clk_src_am,
-	.reg_source	= S5PC100_CLKSRC0,
+	.reg_src = { .reg = S5PC100_CLKSRC0, .shift = 16, .size = 1, },
 };
 
 static unsigned long s5pc100_clk_dout_d1_bus_get_rate(struct clk *clk)
@@ -284,7 +272,9 @@ static struct clk clk_dout_d1_bus = {
 	.name		= "dout_d1_bus",
 	.id		= -1,
 	.parent		= &clk_mout_am.clk,
-	.get_rate	= s5pc100_clk_dout_d1_bus_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_d1_bus_get_rate,
+	},
 };
 
 static struct clk *clkset_onenand_list[] = {
@@ -292,7 +282,7 @@ static struct clk *clkset_onenand_list[]
 	[1] = &clk_dout_d1_bus,
 };
 
-static struct clk_sources clk_src_onenand = {
+static struct clksrc_sources clk_src_onenand = {
 	.sources	= clkset_onenand_list,
 	.nr_sources	= ARRAY_SIZE(clkset_onenand_list),
 };
@@ -302,10 +292,8 @@ static struct clksrc_clk clk_mout_onenan
 		.name		= "mout_onenand",
 		.id		= -1,
 	},
-	.shift		= S5PC100_CLKSRC0_ONENAND_SHIFT,
-	.mask		= S5PC100_CLKSRC0_ONENAND_MASK,
 	.sources	= &clk_src_onenand,
-	.reg_source	= S5PC100_CLKSRC0,
+	.reg_src = { .reg = S5PC100_CLKSRC0, .shift = 24, .size = 1, },
 };
 
 static unsigned long s5pc100_clk_dout_pclkd1_get_rate(struct clk *clk)
@@ -325,7 +313,9 @@ static struct clk clk_dout_pclkd1 = {
 	.name		= "dout_pclkd1",
 	.id		= -1,
 	.parent		= &clk_dout_d1_bus,
-	.get_rate	= s5pc100_clk_dout_pclkd1_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_pclkd1_get_rate,
+	},
 };
 
 static unsigned long s5pc100_clk_dout_mpll2_get_rate(struct clk *clk)
@@ -345,7 +335,9 @@ static struct clk clk_dout_mpll2 = {
 	.name		= "dout_mpll2",
 	.id		= -1,
 	.parent		= &clk_mout_am.clk,
-	.get_rate	= s5pc100_clk_dout_mpll2_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_mpll2_get_rate,
+	},
 };
 
 static unsigned long s5pc100_clk_dout_cam_get_rate(struct clk *clk)
@@ -365,7 +357,9 @@ static struct clk clk_dout_cam = {
 	.name		= "dout_cam",
 	.id		= -1,
 	.parent		= &clk_dout_mpll2,
-	.get_rate	= s5pc100_clk_dout_cam_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_cam_get_rate,
+	},
 };
 
 static unsigned long s5pc100_clk_dout_mpll_get_rate(struct clk *clk)
@@ -385,7 +379,9 @@ static struct clk clk_dout_mpll = {
 	.name		= "dout_mpll",
 	.id		= -1,
 	.parent		= &clk_mout_am.clk,
-	.get_rate	= s5pc100_clk_dout_mpll_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_mpll_get_rate,
+	},
 };
 
 /* EPLL */
@@ -399,7 +395,7 @@ static struct clk *clk_src_epll_list[] =
 	[1] = &clk_fout_epll,
 };
 
-static struct clk_sources clk_src_epll = {
+static struct clksrc_sources clk_src_epll = {
 	.sources	= clk_src_epll_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_epll_list),
 };
@@ -409,10 +405,8 @@ static struct clksrc_clk clk_mout_epll =
 		.name		= "mout_epll",
 		.id		= -1,
 	},
-	.shift		= S5PC100_CLKSRC0_EPLL_SHIFT,
-	.mask		= S5PC100_CLKSRC0_EPLL_MASK,
-	.sources	= &clk_src_epll,
-	.reg_source	= S5PC100_CLKSRC0,
+	.sources = &clk_src_epll,
+	.reg_src = { .reg = S5PC100_CLKSRC0, .shift = 8, .size = 1, },
 };
 
 /* HPLL */
@@ -426,7 +420,7 @@ static struct clk *clk_src_hpll_list[] =
 	[1] = &clk_fout_hpll,
 };
 
-static struct clk_sources clk_src_hpll = {
+static struct clksrc_sources clk_src_hpll = {
 	.sources	= clk_src_hpll_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_hpll_list),
 };
@@ -436,10 +430,8 @@ static struct clksrc_clk clk_mout_hpll =
 		.name		= "mout_hpll",
 		.id		= -1,
 	},
-	.shift		= S5PC100_CLKSRC0_HPLL_SHIFT,
-	.mask		= S5PC100_CLKSRC0_HPLL_MASK,
-	.sources	= &clk_src_hpll,
-	.reg_source	= S5PC100_CLKSRC0,
+	.sources = &clk_src_hpll,
+	.reg_src = { .reg = S5PC100_CLKSRC0, .shift = 12, .size = 1, },
 };
 
 /* Peripherals */
@@ -454,190 +446,6 @@ static struct clksrc_clk clk_mout_hpll =
  * have a common parent divisor so are not included here.
  */
 
-static inline struct clksrc_clk *to_clksrc(struct clk *clk)
-{
-	return container_of(clk, struct clksrc_clk, clk);
-}
-
-static unsigned long s5pc100_getrate_clksrc(struct clk *clk)
-{
-	struct clksrc_clk *sclk = to_clksrc(clk);
-	unsigned long rate = clk_get_rate(clk->parent);
-	u32 clkdiv = __raw_readl(sclk->reg_divider);
-
-	clkdiv >>= sclk->divider_shift;
-	clkdiv &= 0xf;
-	clkdiv++;
-
-	rate /= clkdiv;
-	return rate;
-}
-
-static int s5pc100_setrate_clksrc(struct clk *clk, unsigned long rate)
-{
-	struct clksrc_clk *sclk = to_clksrc(clk);
-	void __iomem *reg = sclk->reg_divider;
-	unsigned int div;
-	u32 val;
-
-	rate = clk_round_rate(clk, rate);
-	div = clk_get_rate(clk->parent) / rate;
-	if (div > 16)
-		return -EINVAL;
-
-	val = __raw_readl(reg);
-	val &= ~(0xf << sclk->divider_shift);
-	val |= (div - 1) << sclk->divider_shift;
-	__raw_writel(val, reg);
-
-	return 0;
-}
-
-static int s5pc100_setparent_clksrc(struct clk *clk, struct clk *parent)
-{
-	struct clksrc_clk *sclk = to_clksrc(clk);
-	struct clk_sources *srcs = sclk->sources;
-	u32 clksrc = __raw_readl(sclk->reg_source);
-	int src_nr = -1;
-	int ptr;
-
-	for (ptr = 0; ptr < srcs->nr_sources; ptr++)
-		if (srcs->sources[ptr] == parent) {
-			src_nr = ptr;
-			break;
-		}
-
-	if (src_nr >= 0) {
-		clksrc &= ~sclk->mask;
-		clksrc |= src_nr << sclk->shift;
-
-		__raw_writel(clksrc, sclk->reg_source);
-		return 0;
-	}
-
-	return -EINVAL;
-}
-
-static unsigned long s5pc100_roundrate_clksrc(struct clk *clk,
-					      unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	int div;
-
-	if (rate > parent_rate)
-		rate = parent_rate;
-	else {
-		div = rate / parent_rate;
-
-		if (div == 0)
-			div = 1;
-		if (div > 16)
-			div = 16;
-
-		rate = parent_rate / div;
-	}
-
-	return rate;
-}
-
-static struct clk *clkset_spi_list[] = {
-	&clk_mout_epll.clk,
-	&clk_dout_mpll2,
-	&clk_fin_epll,
-	&clk_mout_hpll.clk,
-};
-
-static struct clk_sources clkset_spi = {
-	.sources	= clkset_spi_list,
-	.nr_sources	= ARRAY_SIZE(clkset_spi_list),
-};
-
-static struct clksrc_clk clk_spi0 = {
-	.clk	= {
-		.name		= "spi_bus",
-		.id		= 0,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI0,
-		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
-	},
-	.shift		= S5PC100_CLKSRC1_SPI0_SHIFT,
-	.mask		= S5PC100_CLKSRC1_SPI0_MASK,
-	.sources	= &clkset_spi,
-	.divider_shift	= S5PC100_CLKDIV2_SPI0_SHIFT,
-	.reg_divider	= S5PC100_CLKDIV2,
-	.reg_source	= S5PC100_CLKSRC1,
-};
-
-static struct clksrc_clk clk_spi1 = {
-	.clk	= {
-		.name		= "spi_bus",
-		.id		= 1,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI1,
-		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
-	},
-	.shift		= S5PC100_CLKSRC1_SPI1_SHIFT,
-	.mask		= S5PC100_CLKSRC1_SPI1_MASK,
-	.sources	= &clkset_spi,
-	.divider_shift	= S5PC100_CLKDIV2_SPI1_SHIFT,
-	.reg_divider	= S5PC100_CLKDIV2,
-	.reg_source	= S5PC100_CLKSRC1,
-};
-
-static struct clksrc_clk clk_spi2 = {
-	.clk	= {
-		.name		= "spi_bus",
-		.id		= 2,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI2,
-		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
-	},
-	.shift		= S5PC100_CLKSRC1_SPI2_SHIFT,
-	.mask		= S5PC100_CLKSRC1_SPI2_MASK,
-	.sources	= &clkset_spi,
-	.divider_shift	= S5PC100_CLKDIV2_SPI2_SHIFT,
-	.reg_divider	= S5PC100_CLKDIV2,
-	.reg_source	= S5PC100_CLKSRC1,
-};
-
-static struct clk *clkset_uart_list[] = {
-	&clk_mout_epll.clk,
-	&clk_dout_mpll,
-};
-
-static struct clk_sources clkset_uart = {
-	.sources	= clkset_uart_list,
-	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
-};
-
-static struct clksrc_clk clk_uart_uclk1 = {
-	.clk	= {
-		.name		= "uclk1",
-		.id		= -1,
-		.ctrlbit        = S5PC100_CLKGATE_SCLK0_UART,
-		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
-	},
-	.shift		= S5PC100_CLKSRC1_UART_SHIFT,
-	.mask		= S5PC100_CLKSRC1_UART_MASK,
-	.sources	= &clkset_uart,
-	.divider_shift	= S5PC100_CLKDIV2_UART_SHIFT,
-	.reg_divider	= S5PC100_CLKDIV2,
-	.reg_source	= S5PC100_CLKSRC1,
-};
-
 static struct clk clk_iis_cd0 = {
 	.name		= "iis_cdclk0",
 	.id		= -1,
@@ -672,28 +480,31 @@ static struct clk *clkset_audio0_list[]
 	&clk_mout_hpll.clk,
 };
 
-static struct clk_sources clkset_audio0 = {
+static struct clksrc_sources clkset_audio0 = {
 	.sources	= clkset_audio0_list,
 	.nr_sources	= ARRAY_SIZE(clkset_audio0_list),
 };
 
-static struct clksrc_clk clk_audio0 = {
-	.clk	= {
-		.name		= "audio-bus",
-		.id		= 0,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO0,
-		.enable		= s5pc100_sclk1_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
-	},
-	.shift		= S5PC100_CLKSRC3_AUDIO0_SHIFT,
-	.mask		= S5PC100_CLKSRC3_AUDIO0_MASK,
-	.sources	= &clkset_audio0,
-	.divider_shift	= S5PC100_CLKDIV4_AUDIO0_SHIFT,
-	.reg_divider	= S5PC100_CLKDIV4,
-	.reg_source	= S5PC100_CLKSRC3,
+static struct clk *clkset_spi_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll2,
+	&clk_fin_epll,
+	&clk_mout_hpll.clk,
+};
+
+static struct clksrc_sources clkset_spi = {
+	.sources	= clkset_spi_list,
+	.nr_sources	= ARRAY_SIZE(clkset_spi_list),
+};
+
+static struct clk *clkset_uart_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+};
+
+static struct clksrc_sources clkset_uart = {
+	.sources	= clkset_uart_list,
+	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
 };
 
 static struct clk *clkset_audio1_list[] = {
@@ -705,30 +516,11 @@ static struct clk *clkset_audio1_list[]
 	&clk_mout_hpll.clk,
 };
 
-static struct clk_sources clkset_audio1 = {
+static struct clksrc_sources clkset_audio1 = {
 	.sources	= clkset_audio1_list,
 	.nr_sources	= ARRAY_SIZE(clkset_audio1_list),
 };
 
-static struct clksrc_clk clk_audio1 = {
-	.clk	= {
-		.name		= "audio-bus",
-		.id		= 1,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO1,
-		.enable		= s5pc100_sclk1_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
-	},
-	.shift		= S5PC100_CLKSRC3_AUDIO1_SHIFT,
-	.mask		= S5PC100_CLKSRC3_AUDIO1_MASK,
-	.sources	= &clkset_audio1,
-	.divider_shift	= S5PC100_CLKDIV4_AUDIO1_SHIFT,
-	.reg_divider	= S5PC100_CLKDIV4,
-	.reg_source	= S5PC100_CLKSRC3,
-};
-
 static struct clk *clkset_audio2_list[] = {
 	&clk_mout_epll.clk,
 	&clk_dout_mpll,
@@ -737,52 +529,56 @@ static struct clk *clkset_audio2_list[]
 	&clk_mout_hpll.clk,
 };
 
-static struct clk_sources clkset_audio2 = {
+static struct clksrc_sources clkset_audio2 = {
 	.sources	= clkset_audio2_list,
 	.nr_sources	= ARRAY_SIZE(clkset_audio2_list),
 };
 
-static struct clksrc_clk clk_audio2 = {
-	.clk	= {
-		.name		= "audio-bus",
-		.id		= 2,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO2,
-		.enable		= s5pc100_sclk1_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+static struct clksrc_clk clksrc_audio[] = {
+	{
+		.clk	= {
+			.name		= "audio-bus",
+			.id		= 0,
+			.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO0,
+			.enable		= s5pc100_sclk1_ctrl,
+		},
+		.sources = &clkset_audio0,
+		.reg_div = { .reg = S5PC100_CLKDIV4, .shift = 12, .size = 4, },
+		.reg_src = { .reg = S5PC100_CLKSRC3, .shift = 12, .size = 3, },
+	}, {
+		.clk	= {
+			.name		= "audio-bus",
+			.id		= 1,
+			.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO1,
+			.enable		= s5pc100_sclk1_ctrl,
+		},
+		.sources = &clkset_audio1,
+		.reg_div = { .reg = S5PC100_CLKDIV4, .shift = 16, .size = 4, },
+		.reg_src = { .reg = S5PC100_CLKSRC3, .shift = 16, .size = 3, },
+	}, {
+		.clk	= {
+			.name		= "audio-bus",
+			.id		= 2,
+			.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO2,
+			.enable		= s5pc100_sclk1_ctrl,
+		},
+		.sources = &clkset_audio2,
+		.reg_div = { .reg = S5PC100_CLKDIV4, .shift = 20, .size = 4, },
+		.reg_src = { .reg = S5PC100_CLKSRC3, .shift = 20, .size = 3, },
 	},
-	.shift		= S5PC100_CLKSRC3_AUDIO2_SHIFT,
-	.mask		= S5PC100_CLKSRC3_AUDIO2_MASK,
-	.sources	= &clkset_audio2,
-	.divider_shift	= S5PC100_CLKDIV4_AUDIO2_SHIFT,
-	.reg_divider	= S5PC100_CLKDIV4,
-	.reg_source	= S5PC100_CLKSRC3,
 };
 
 static struct clk *clkset_spdif_list[] = {
-	&clk_audio0.clk,
-	&clk_audio1.clk,
-	&clk_audio2.clk,
+	&clksrc_audio[0].clk,
+	&clksrc_audio[1].clk,
+	&clksrc_audio[2].clk,
 };
 
-static struct clk_sources clkset_spdif = {
+static struct clksrc_sources clkset_spdif = {
 	.sources	= clkset_spdif_list,
 	.nr_sources	= ARRAY_SIZE(clkset_spdif_list),
 };
 
-static struct clksrc_clk clk_spdif = {
-	.clk	= {
-		.name		= "spdif",
-		.id		= -1,
-	},
-	.shift		= S5PC100_CLKSRC3_SPDIF_SHIFT,
-	.mask		= S5PC100_CLKSRC3_SPDIF_MASK,
-	.sources	= &clkset_spdif,
-	.reg_source	= S5PC100_CLKSRC3,
-};
-
 static struct clk *clkset_lcd_fimc_list[] = {
 	&clk_mout_epll.clk,
 	&clk_dout_mpll,
@@ -790,87 +586,11 @@ static struct clk *clkset_lcd_fimc_list[
 	&clk_vclk_54m,
 };
 
-static struct clk_sources clkset_lcd_fimc = {
+static struct clksrc_sources clkset_lcd_fimc = {
 	.sources	= clkset_lcd_fimc_list,
 	.nr_sources	= ARRAY_SIZE(clkset_lcd_fimc_list),
 };
 
-static struct clksrc_clk clk_lcd = {
-	.clk	= {
-		.name		= "lcd",
-		.id		= -1,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_LCD,
-		.enable		= s5pc100_sclk1_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
-	},
-	.shift		= S5PC100_CLKSRC2_LCD_SHIFT,
-	.mask		= S5PC100_CLKSRC2_LCD_MASK,
-	.sources	= &clkset_lcd_fimc,
-	.divider_shift	= S5PC100_CLKDIV3_LCD_SHIFT,
-	.reg_divider	= S5PC100_CLKDIV3,
-	.reg_source	= S5PC100_CLKSRC2,
-};
-
-static struct clksrc_clk clk_fimc0 = {
-	.clk	= {
-		.name		= "fimc",
-		.id		= 0,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC0,
-		.enable		= s5pc100_sclk1_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
-	},
-	.shift		= S5PC100_CLKSRC2_FIMC0_SHIFT,
-	.mask		= S5PC100_CLKSRC2_FIMC0_MASK,
-	.sources	= &clkset_lcd_fimc,
-	.divider_shift	= S5PC100_CLKDIV3_FIMC0_SHIFT,
-	.reg_divider	= S5PC100_CLKDIV3,
-	.reg_source	= S5PC100_CLKSRC2,
-};
-
-static struct clksrc_clk clk_fimc1 = {
-	.clk	= {
-		.name		= "fimc",
-		.id		= 1,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC1,
-		.enable		= s5pc100_sclk1_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
-	},
-	.shift		= S5PC100_CLKSRC2_FIMC1_SHIFT,
-	.mask		= S5PC100_CLKSRC2_FIMC1_MASK,
-	.sources	= &clkset_lcd_fimc,
-	.divider_shift	= S5PC100_CLKDIV3_FIMC1_SHIFT,
-	.reg_divider	= S5PC100_CLKDIV3,
-	.reg_source	= S5PC100_CLKSRC2,
-};
-
-static struct clksrc_clk clk_fimc2 = {
-	.clk	= {
-		.name		= "fimc",
-		.id		= 2,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC2,
-		.enable		= s5pc100_sclk1_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
-	},
-	.shift		= S5PC100_CLKSRC2_FIMC2_SHIFT,
-	.mask		= S5PC100_CLKSRC2_FIMC2_MASK,
-	.sources	= &clkset_lcd_fimc,
-	.divider_shift	= S5PC100_CLKDIV3_FIMC2_SHIFT,
-	.reg_divider	= S5PC100_CLKDIV3,
-	.reg_source	= S5PC100_CLKSRC2,
-};
-
 static struct clk *clkset_mmc_list[] = {
 	&clk_mout_epll.clk,
 	&clk_dout_mpll,
@@ -878,69 +598,11 @@ static struct clk *clkset_mmc_list[] = {
 	&clk_mout_hpll.clk ,
 };
 
-static struct clk_sources clkset_mmc = {
+static struct clksrc_sources clkset_mmc = {
 	.sources	= clkset_mmc_list,
 	.nr_sources	= ARRAY_SIZE(clkset_mmc_list),
 };
 
-static struct clksrc_clk clk_mmc0 = {
-	.clk	= {
-		.name		= "mmc_bus",
-		.id		= 0,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC0,
-		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
-	},
-	.shift		= S5PC100_CLKSRC2_MMC0_SHIFT,
-	.mask		= S5PC100_CLKSRC2_MMC0_MASK,
-	.sources	= &clkset_mmc,
-	.divider_shift	= S5PC100_CLKDIV3_MMC0_SHIFT,
-	.reg_divider	= S5PC100_CLKDIV3,
-	.reg_source	= S5PC100_CLKSRC2,
-};
-
-static struct clksrc_clk clk_mmc1 = {
-	.clk	= {
-		.name		= "mmc_bus",
-		.id		= 1,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC1,
-		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
-	},
-	.shift		= S5PC100_CLKSRC2_MMC1_SHIFT,
-	.mask		= S5PC100_CLKSRC2_MMC1_MASK,
-	.sources	= &clkset_mmc,
-	.divider_shift	= S5PC100_CLKDIV3_MMC1_SHIFT,
-	.reg_divider	= S5PC100_CLKDIV3,
-	.reg_source	= S5PC100_CLKSRC2,
-};
-
-static struct clksrc_clk clk_mmc2 = {
-	.clk	= {
-		.name		= "mmc_bus",
-		.id		= 2,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC2,
-		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
-	},
-	.shift		= S5PC100_CLKSRC2_MMC2_SHIFT,
-	.mask		= S5PC100_CLKSRC2_MMC2_MASK,
-	.sources	= &clkset_mmc,
-	.divider_shift	= S5PC100_CLKDIV3_MMC2_SHIFT,
-	.reg_divider	= S5PC100_CLKDIV3,
-	.reg_source	= S5PC100_CLKSRC2,
-};
-
-
 static struct clk *clkset_usbhost_list[] = {
 	&clk_mout_epll.clk,
 	&clk_dout_mpll,
@@ -948,28 +610,141 @@ static struct clk *clkset_usbhost_list[]
 	&clk_48m,
 };
 
-static struct clk_sources clkset_usbhost = {
+static struct clksrc_sources clkset_usbhost = {
 	.sources	= clkset_usbhost_list,
 	.nr_sources	= ARRAY_SIZE(clkset_usbhost_list),
 };
 
-static struct clksrc_clk clk_usbhost = {
-	.clk	= {
-		.name		= "usbhost",
-		.id		= -1,
-		.ctrlbit        = S5PC100_CLKGATE_SCLK0_USBHOST,
-		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
-	},
-	.shift		= S5PC100_CLKSRC1_UHOST_SHIFT,
-	.mask		= S5PC100_CLKSRC1_UHOST_MASK,
-	.sources	= &clkset_usbhost,
-	.divider_shift	= S5PC100_CLKDIV2_UHOST_SHIFT,
-	.reg_divider	= S5PC100_CLKDIV2,
-	.reg_source	= S5PC100_CLKSRC1,
+static struct clksrc_clk clksrc_clks[] = {
+	{
+		.clk	= {
+			.name		= "spi_bus",
+			.id		= 0,
+			.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI0,
+			.enable		= s5pc100_sclk0_ctrl,
+
+		},
+		.sources = &clkset_spi,
+		.reg_div = { .reg = S5PC100_CLKDIV2, .shift = 4, .size = 4, },
+		.reg_src = { .reg = S5PC100_CLKSRC1, .shift = 4, .size = 2, },
+	}, {
+		.clk	= {
+			.name		= "spi_bus",
+			.id		= 1,
+			.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI1,
+			.enable		= s5pc100_sclk0_ctrl,
+		},
+		.sources = &clkset_spi,
+		.reg_div = { .reg = S5PC100_CLKDIV2, .shift = 8, .size = 4, },
+		.reg_src = { .reg = S5PC100_CLKSRC1, .shift = 8, .size = 2, },
+	}, {
+		.clk	= {
+			.name		= "spi_bus",
+			.id		= 2,
+			.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI2,
+			.enable		= s5pc100_sclk0_ctrl,
+		},
+		.sources = &clkset_spi,
+		.reg_div = { .reg = S5PC100_CLKDIV2, .shift = 12, .size = 4, },
+		.reg_src = { .reg = S5PC100_CLKSRC1, .shift = 12, .size = 2, },
+	}, {
+		.clk	= {
+			.name		= "uclk1",
+			.id		= -1,
+			.ctrlbit        = S5PC100_CLKGATE_SCLK0_UART,
+			.enable		= s5pc100_sclk0_ctrl,
+		},
+		.sources = &clkset_uart,
+		.reg_div = { .reg = S5PC100_CLKDIV2, .shift = 0, .size = 3, },
+		.reg_src = { .reg = S5PC100_CLKSRC1, .shift = 0, .size = 1, },
+	}, {
+		.clk	= {
+			.name		= "spdif",
+			.id		= -1,
+		},
+		.sources	= &clkset_spdif,
+		.reg_src = { .reg = S5PC100_CLKSRC3, .shift = 24, .size = 2, },
+	}, {
+		.clk	= {
+			.name		= "lcd",
+			.id		= -1,
+			.ctrlbit	= S5PC100_CLKGATE_SCLK1_LCD,
+			.enable		= s5pc100_sclk1_ctrl,
+		},
+		.sources = &clkset_lcd_fimc,
+		.reg_div = { .reg = S5PC100_CLKDIV3, .shift = 12, .size = 4, },
+		.reg_src = { .reg = S5PC100_CLKSRC2, .shift = 12, .size = 2, },
+	}, {
+		.clk	= {
+			.name		= "fimc",
+			.id		= 0,
+			.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC0,
+			.enable		= s5pc100_sclk1_ctrl,
+		},
+		.sources = &clkset_lcd_fimc,
+		.reg_div = { .reg = S5PC100_CLKDIV3, .shift = 16, .size = 4, },
+		.reg_src = { .reg = S5PC100_CLKSRC2, .shift = 16, .size = 2, },
+	}, {
+		.clk	= {
+			.name		= "fimc",
+			.id		= 1,
+			.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC1,
+			.enable		= s5pc100_sclk1_ctrl,
+		},
+		.sources	= &clkset_lcd_fimc,
+		.reg_div = { .reg = S5PC100_CLKDIV3, .shift = 20, .size = 4, },
+		.reg_src = { .reg = S5PC100_CLKSRC2, .shift = 20, .size = 2, },
+	}, {
+		.clk	= {
+			.name		= "fimc",
+			.id		= 2,
+			.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC2,
+			.enable		= s5pc100_sclk1_ctrl,
+		},
+		.sources = &clkset_lcd_fimc,
+		.reg_div = { .reg = S5PC100_CLKDIV3, .shift = 24, .size = 4, },
+		.reg_src = { .reg = S5PC100_CLKSRC2, .shift = 24, .size = 2, },
+	}, {
+		.clk	= {
+			.name		= "mmc_bus",
+			.id		= 0,
+			.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC0,
+			.enable		= s5pc100_sclk0_ctrl,
+		},
+		.sources = &clkset_mmc,
+		.reg_div = { .reg = S5PC100_CLKDIV3, .shift = 0, .size = 4, },
+		.reg_src = { .reg = S5PC100_CLKSRC2, .shift = 0, .size = 2, },
+	}, {
+		.clk	= {
+			.name		= "mmc_bus",
+			.id		= 1,
+			.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC1,
+			.enable		= s5pc100_sclk0_ctrl,
+		},
+		.sources = &clkset_mmc,
+		.reg_div = { .reg = S5PC100_CLKDIV3, .shift = 4, .size = 4, },
+		.reg_src = { .reg = S5PC100_CLKSRC2, .shift = 4, .size = 2, },
+	}, {
+		.clk	= {
+			.name		= "mmc_bus",
+			.id		= 2,
+			.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC2,
+			.enable		= s5pc100_sclk0_ctrl,
+		},
+		.sources	= &clkset_mmc,
+		.reg_div = { .reg = S5PC100_CLKDIV3, .shift = 8, .size = 4, },
+		.reg_src = { .reg = S5PC100_CLKSRC2, .shift = 8, .size = 2, },
+	}, {
+		.clk	= {
+			.name		= "usbhost",
+			.id		= -1,
+			.ctrlbit        = S5PC100_CLKGATE_SCLK0_USBHOST,
+			.enable		= s5pc100_sclk0_ctrl,
+		},
+		.sources = &clkset_usbhost,
+		.reg_div = { .reg = S5PC100_CLKDIV2, .shift = 20, .size = 4, },
+		.reg_src = { .reg = S5PC100_CLKSRC1, .shift = 20, .size = 2, },
+	}
 };
 
 /* Clock initialisation code */
@@ -981,45 +756,8 @@ static struct clksrc_clk *init_parents[]
 	&clk_mout_onenand,
 	&clk_mout_epll,
 	&clk_mout_hpll,
-	&clk_spi0,
-	&clk_spi1,
-	&clk_spi2,
-	&clk_uart_uclk1,
-	&clk_audio0,
-	&clk_audio1,
-	&clk_audio2,
-	&clk_spdif,
-	&clk_lcd,
-	&clk_fimc0,
-	&clk_fimc1,
-	&clk_fimc2,
-	&clk_mmc0,
-	&clk_mmc1,
-	&clk_mmc2,
-	&clk_usbhost,
 };
 
-static void __init_or_cpufreq s5pc100_set_clksrc(struct clksrc_clk *clk)
-{
-	struct clk_sources *srcs = clk->sources;
-	u32 clksrc = __raw_readl(clk->reg_source);
-
-	clksrc &= clk->mask;
-	clksrc >>= clk->shift;
-
-	if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
-		printk(KERN_ERR "%s: bad source %d\n",
-		       clk->clk.name, clksrc);
-		return;
-	}
-
-	clk->clk.parent = srcs->sources[clksrc];
-
-	printk(KERN_INFO "%s: source is %s (%d), rate is %ld.%03ld MHz\n",
-		clk->clk.name, clk->clk.parent->name, clksrc,
-		print_mhz(clk_get_rate(&clk->clk)));
-}
-
 #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
 
 void __init_or_cpufreq s5pc100_setup_clocks(void)
@@ -1083,17 +821,25 @@ void __init_or_cpufreq s5pc100_setup_clo
 	clk_f.rate = armclk;
 
 	for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
-		s5pc100_set_clksrc(init_parents[ptr]);
+		s3c_set_clksrc(init_parents[ptr], true);
+
+	for (ptr = 0; ptr < ARRAY_SIZE(clksrc_audio); ptr++)
+		s3c_set_clksrc(clksrc_audio + ptr, true);
+
+	for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++)
+		s3c_set_clksrc(clksrc_clks + ptr, true);
 }
 
 static struct clk *clks[] __initdata = {
 	&clk_ext_xtal_mux,
-	&clk_mout_apll.clk,
 	&clk_dout_apll,
 	&clk_dout_d0_bus,
 	&clk_dout_pclkd0,
 	&clk_dout_apll2,
+	&clk_mout_apll.clk,
 	&clk_mout_mpll.clk,
+	&clk_mout_epll.clk,
+	&clk_mout_hpll.clk,
 	&clk_mout_am.clk,
 	&clk_dout_d1_bus,
 	&clk_mout_onenand.clk,
@@ -1101,29 +847,12 @@ static struct clk *clks[] __initdata = {
 	&clk_dout_mpll2,
 	&clk_dout_cam,
 	&clk_dout_mpll,
-	&clk_mout_epll.clk,
 	&clk_fout_epll,
 	&clk_iis_cd0,
 	&clk_iis_cd1,
 	&clk_iis_cd2,
 	&clk_pcm_cd0,
 	&clk_pcm_cd1,
-	&clk_spi0.clk,
-	&clk_spi1.clk,
-	&clk_spi2.clk,
-	&clk_uart_uclk1.clk,
-	&clk_audio0.clk,
-	&clk_audio1.clk,
-	&clk_audio2.clk,
-	&clk_spdif.clk,
-	&clk_lcd.clk,
-	&clk_fimc0.clk,
-	&clk_fimc1.clk,
-	&clk_fimc2.clk,
-	&clk_mmc0.clk,
-	&clk_mmc1.clk,
-	&clk_mmc2.clk,
-	&clk_usbhost.clk,
 	&clk_arm,
 };
 
@@ -1141,4 +870,7 @@ void __init s5pc100_register_clocks(void
 			       clkp->name, ret);
 		}
 	}
+
+	s3c_register_clksrc(clksrc_audio, ARRAY_SIZE(clksrc_audio));
+	s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks));
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/adc.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/adc.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/adc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/adc.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,475 @@
+/* arch/arm/plat-samsung/adc.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ *
+ * Samsung ADC device core
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <plat/regs-adc.h>
+#include <plat/adc.h>
+
+/* This driver is designed to control the usage of the ADC block between
+ * the touchscreen and any other drivers that may need to use it, such as
+ * the hwmon driver.
+ *
+ * Priority will be given to the touchscreen driver, but as this itself is
+ * rate limited it should not starve other requests which are processed in
+ * order that they are received.
+ *
+ * Each user registers to get a client block which uniquely identifies it
+ * and stores information such as the necessary functions to callback when
+ * action is required.
+ */
+
+enum s3c_cpu_type {
+	TYPE_S3C24XX,
+	TYPE_S3C64XX
+};
+
+struct s3c_adc_client {
+	struct platform_device	*pdev;
+	struct list_head	 pend;
+	wait_queue_head_t	*wait;
+
+	unsigned int		 nr_samples;
+	int			 result;
+	unsigned char		 is_ts;
+	unsigned char		 channel;
+
+	void	(*select_cb)(struct s3c_adc_client *c, unsigned selected);
+	void	(*convert_cb)(struct s3c_adc_client *c,
+			      unsigned val1, unsigned val2,
+			      unsigned *samples_left);
+};
+
+struct adc_device {
+	struct platform_device	*pdev;
+	struct platform_device	*owner;
+	struct clk		*clk;
+	struct s3c_adc_client	*cur;
+	struct s3c_adc_client	*ts_pend;
+	void __iomem		*regs;
+
+	unsigned int		 prescale;
+
+	int			 irq;
+};
+
+static struct adc_device *adc_dev;
+
+static LIST_HEAD(adc_pending);
+
+#define adc_dbg(_adc, msg...) dev_dbg(&(_adc)->pdev->dev, msg)
+
+static inline void s3c_adc_convert(struct adc_device *adc)
+{
+	unsigned con = readl(adc->regs + S3C2410_ADCCON);
+
+	con |= S3C2410_ADCCON_ENABLE_START;
+	writel(con, adc->regs + S3C2410_ADCCON);
+}
+
+static inline void s3c_adc_select(struct adc_device *adc,
+				  struct s3c_adc_client *client)
+{
+	unsigned con = readl(adc->regs + S3C2410_ADCCON);
+
+	client->select_cb(client, 1);
+
+	con &= ~S3C2410_ADCCON_MUXMASK;
+	con &= ~S3C2410_ADCCON_STDBM;
+	con &= ~S3C2410_ADCCON_STARTMASK;
+
+	if (!client->is_ts)
+		con |= S3C2410_ADCCON_SELMUX(client->channel);
+
+	writel(con, adc->regs + S3C2410_ADCCON);
+}
+
+static void s3c_adc_dbgshow(struct adc_device *adc)
+{
+	adc_dbg(adc, "CON=%08x, TSC=%08x, DLY=%08x\n",
+		readl(adc->regs + S3C2410_ADCCON),
+		readl(adc->regs + S3C2410_ADCTSC),
+		readl(adc->regs + S3C2410_ADCDLY));
+}
+
+static void s3c_adc_try(struct adc_device *adc)
+{
+	struct s3c_adc_client *next = adc->ts_pend;
+
+	if (!next && !list_empty(&adc_pending)) {
+		next = list_first_entry(&adc_pending,
+					struct s3c_adc_client, pend);
+		list_del(&next->pend);
+	} else
+		adc->ts_pend = NULL;
+
+	if (next) {
+		adc_dbg(adc, "new client is %p\n", next);
+		adc->cur = next;
+		s3c_adc_select(adc, next);
+		s3c_adc_convert(adc);
+		s3c_adc_dbgshow(adc);
+	}
+}
+
+int s3c_adc_start(struct s3c_adc_client *client,
+		  unsigned int channel, unsigned int nr_samples)
+{
+	struct adc_device *adc = adc_dev;
+	unsigned long flags;
+
+	if (!adc) {
+		printk(KERN_ERR "%s: failed to find adc\n", __func__);
+		return -EINVAL;
+	}
+
+	if (client->is_ts && adc->ts_pend)
+		return -EAGAIN;
+
+	local_irq_save(flags);
+
+	client->channel = channel;
+	client->nr_samples = nr_samples;
+
+	if (client->is_ts)
+		adc->ts_pend = client;
+	else
+		list_add_tail(&client->pend, &adc_pending);
+
+	if (!adc->cur)
+		s3c_adc_try(adc);
+	local_irq_restore(flags);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(s3c_adc_start);
+
+static void s3c_convert_done(struct s3c_adc_client *client,
+			     unsigned v, unsigned u, unsigned *left)
+{
+	client->result = v;
+	wake_up(client->wait);
+}
+
+int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)
+{
+	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
+	int ret;
+
+	client->convert_cb = s3c_convert_done;
+	client->wait = &wake;
+	client->result = -1;
+
+	ret = s3c_adc_start(client, ch, 1);
+	if (ret < 0)
+		goto err;
+
+	ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);
+	if (client->result < 0) {
+		ret = -ETIMEDOUT;
+		goto err;
+	}
+
+	client->convert_cb = NULL;
+	return client->result;
+
+err:
+	return ret;
+}
+EXPORT_SYMBOL_GPL(s3c_adc_read);
+
+static void s3c_adc_default_select(struct s3c_adc_client *client,
+				   unsigned select)
+{
+}
+
+struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev,
+					void (*select)(struct s3c_adc_client *client,
+						       unsigned int selected),
+					void (*conv)(struct s3c_adc_client *client,
+						     unsigned d0, unsigned d1,
+						     unsigned *samples_left),
+					unsigned int is_ts)
+{
+	struct s3c_adc_client *client;
+
+	WARN_ON(!pdev);
+
+	if (!select)
+		select = s3c_adc_default_select;
+
+	if (!pdev)
+		return ERR_PTR(-EINVAL);
+
+	client = kzalloc(sizeof(struct s3c_adc_client), GFP_KERNEL);
+	if (!client) {
+		dev_err(&pdev->dev, "no memory for adc client\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	client->pdev = pdev;
+	client->is_ts = is_ts;
+	client->select_cb = select;
+	client->convert_cb = conv;
+
+	return client;
+}
+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);
+
+static irqreturn_t s3c_adc_irq(int irq, void *pw)
+{
+	struct adc_device *adc = pw;
+	struct s3c_adc_client *client = adc->cur;
+	enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data;
+	unsigned long flags;
+	unsigned data0, data1;
+
+	if (!client) {
+		dev_warn(&adc->pdev->dev, "%s: no adc pending\n", __func__);
+		goto exit;
+	}
+
+	data0 = readl(adc->regs + S3C2410_ADCDAT0);
+	data1 = readl(adc->regs + S3C2410_ADCDAT1);
+	adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1);
+
+	client->nr_samples--;
+
+	if (cpu == TYPE_S3C64XX) {
+		/* S3C64XX ADC resolution is 12-bit */
+		data0 &= 0xfff;
+		data1 &= 0xfff;
+	} else {
+		data0 &= 0x3ff;
+		data1 &= 0x3ff;
+	}
+
+	if (client->convert_cb)
+		(client->convert_cb)(client, data0, data1, &client->nr_samples);
+
+	if (client->nr_samples > 0) {
+		/* fire another conversion for this */
+
+		client->select_cb(client, 1);
+		s3c_adc_convert(adc);
+	} else {
+		local_irq_save(flags);
+		(client->select_cb)(client, 0);
+		adc->cur = NULL;
+
+		s3c_adc_try(adc);
+		local_irq_restore(flags);
+	}
+
+exit:
+	if (cpu == TYPE_S3C64XX) {
+		/* Clear ADC interrupt */
+		writel(0, adc->regs + S3C64XX_ADCCLRINT);
+	}
+	return IRQ_HANDLED;
+}
+
+static int s3c_adc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct adc_device *adc;
+	struct resource *regs;
+	int ret;
+	unsigned tmp;
+
+	adc = kzalloc(sizeof(struct adc_device), GFP_KERNEL);
+	if (adc == NULL) {
+		dev_err(dev, "failed to allocate adc_device\n");
+		return -ENOMEM;
+	}
+
+	adc->pdev = pdev;
+	adc->prescale = S3C2410_ADCCON_PRSCVL(49);
+
+	adc->irq = platform_get_irq(pdev, 1);
+	if (adc->irq <= 0) {
+		dev_err(dev, "failed to get adc irq\n");
+		ret = -ENOENT;
+		goto err_alloc;
+	}
+
+	ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc);
+	if (ret < 0) {
+		dev_err(dev, "failed to attach adc irq\n");
+		goto err_alloc;
+	}
+
+	adc->clk = clk_get(dev, "adc");
+	if (IS_ERR(adc->clk)) {
+		dev_err(dev, "failed to get adc clock\n");
+		ret = PTR_ERR(adc->clk);
+		goto err_irq;
+	}
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs) {
+		dev_err(dev, "failed to find registers\n");
+		ret = -ENXIO;
+		goto err_clk;
+	}
+
+	adc->regs = ioremap(regs->start, resource_size(regs));
+	if (!adc->regs) {
+		dev_err(dev, "failed to map registers\n");
+		ret = -ENXIO;
+		goto err_clk;
+	}
+
+	clk_enable(adc->clk);
+
+	tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
+	if (platform_get_device_id(pdev)->driver_data == TYPE_S3C64XX) {
+		/* Enable 12-bit ADC resolution */
+		tmp |= S3C64XX_ADCCON_RESSEL;
+	}
+	writel(tmp, adc->regs + S3C2410_ADCCON);
+
+	dev_info(dev, "attached adc driver\n");
+
+	platform_set_drvdata(pdev, adc);
+	adc_dev = adc;
+
+	return 0;
+
+ err_clk:
+	clk_put(adc->clk);
+
+ err_irq:
+	free_irq(adc->irq, adc);
+
+ err_alloc:
+	kfree(adc);
+	return ret;
+}
+
+static int __devexit s3c_adc_remove(struct platform_device *pdev)
+{
+	struct adc_device *adc = platform_get_drvdata(pdev);
+
+	iounmap(adc->regs);
+	free_irq(adc->irq, adc);
+	clk_disable(adc->clk);
+	clk_put(adc->clk);
+	kfree(adc);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct adc_device *adc = platform_get_drvdata(pdev);
+	u32 con;
+
+	con = readl(adc->regs + S3C2410_ADCCON);
+	con |= S3C2410_ADCCON_STDBM;
+	writel(con, adc->regs + S3C2410_ADCCON);
+
+	disable_irq(adc->irq);
+	clk_disable(adc->clk);
+
+	return 0;
+}
+
+static int s3c_adc_resume(struct platform_device *pdev)
+{
+	struct adc_device *adc = platform_get_drvdata(pdev);
+
+	clk_enable(adc->clk);
+	enable_irq(adc->irq);
+
+	writel(adc->prescale | S3C2410_ADCCON_PRSCEN,
+	       adc->regs + S3C2410_ADCCON);
+
+	return 0;
+}
+
+#else
+#define s3c_adc_suspend NULL
+#define s3c_adc_resume NULL
+#endif
+
+static struct platform_device_id s3c_adc_driver_ids[] = {
+	{
+		.name           = "s3c24xx-adc",
+		.driver_data    = TYPE_S3C24XX,
+	}, {
+		.name           = "s3c64xx-adc",
+		.driver_data    = TYPE_S3C64XX,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, s3c_adc_driver_ids);
+
+static struct platform_driver s3c_adc_driver = {
+	.id_table	= s3c_adc_driver_ids,
+	.driver		= {
+		.name	= "s3c-adc",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= s3c_adc_probe,
+	.remove		= __devexit_p(s3c_adc_remove),
+	.suspend	= s3c_adc_suspend,
+	.resume		= s3c_adc_resume,
+};
+
+static int __init adc_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&s3c_adc_driver);
+	if (ret)
+		printk(KERN_ERR "%s: failed to add adc driver\n", __func__);
+
+	return ret;
+}
+
+arch_initcall(adc_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/clock.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/clock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,409 @@
+/* linux/arch/arm/plat-s3c24xx/clock.c
+ *
+ * Copyright 2004-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX Core clock control support
+ *
+ * Based on, and code from linux/arch/arm/mach-versatile/clock.c
+ **
+ **  Copyright (C) 2004 ARM Limited.
+ **  Written by Deep Blue Solutions Limited.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+/* clock information */
+
+static LIST_HEAD(clocks);
+
+/* We originally used an mutex here, but some contexts (see resume)
+ * are calling functions such as clk_set_parent() with IRQs disabled
+ * causing an BUG to be triggered.
+ */
+DEFINE_SPINLOCK(clocks_lock);
+
+/* enable and disable calls for use with the clk struct */
+
+static int clk_null_enable(struct clk *clk, int enable)
+{
+	return 0;
+}
+
+/* Clock API calls */
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	struct clk *p;
+	struct clk *clk = ERR_PTR(-ENOENT);
+	int idno;
+
+	if (dev == NULL || dev->bus != &platform_bus_type)
+		idno = -1;
+	else
+		idno = to_platform_device(dev)->id;
+
+	spin_lock(&clocks_lock);
+
+	list_for_each_entry(p, &clocks, list) {
+		if (p->id == idno &&
+		    strcmp(id, p->name) == 0 &&
+		    try_module_get(p->owner)) {
+			clk = p;
+			break;
+		}
+	}
+
+	/* check for the case where a device was supplied, but the
+	 * clock that was being searched for is not device specific */
+
+	if (IS_ERR(clk)) {
+		list_for_each_entry(p, &clocks, list) {
+			if (p->id == -1 && strcmp(id, p->name) == 0 &&
+			    try_module_get(p->owner)) {
+				clk = p;
+				break;
+			}
+		}
+	}
+
+	spin_unlock(&clocks_lock);
+	return clk;
+}
+
+void clk_put(struct clk *clk)
+{
+	module_put(clk->owner);
+}
+
+int clk_enable(struct clk *clk)
+{
+	if (IS_ERR(clk) || clk == NULL)
+		return -EINVAL;
+
+	clk_enable(clk->parent);
+
+	spin_lock(&clocks_lock);
+
+	if ((clk->usage++) == 0)
+		(clk->enable)(clk, 1);
+
+	spin_unlock(&clocks_lock);
+	return 0;
+}
+
+void clk_disable(struct clk *clk)
+{
+	if (IS_ERR(clk) || clk == NULL)
+		return;
+
+	spin_lock(&clocks_lock);
+
+	if ((--clk->usage) == 0)
+		(clk->enable)(clk, 0);
+
+	spin_unlock(&clocks_lock);
+	clk_disable(clk->parent);
+}
+
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (IS_ERR(clk))
+		return 0;
+
+	if (clk->rate != 0)
+		return clk->rate;
+
+	if (clk->ops != NULL && clk->ops->get_rate != NULL)
+		return (clk->ops->get_rate)(clk);
+
+	if (clk->parent != NULL)
+		return clk_get_rate(clk->parent);
+
+	return clk->rate;
+}
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	if (!IS_ERR(clk) && clk->ops && clk->ops->round_rate)
+		return (clk->ops->round_rate)(clk, rate);
+
+	return rate;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int ret;
+
+	if (IS_ERR(clk))
+		return -EINVAL;
+
+	/* We do not default just do a clk->rate = rate as
+	 * the clock may have been made this way by choice.
+	 */
+
+	WARN_ON(clk->ops == NULL);
+	WARN_ON(clk->ops && clk->ops->set_rate == NULL);
+
+	if (clk->ops == NULL || clk->ops->set_rate == NULL)
+		return -EINVAL;
+
+	spin_lock(&clocks_lock);
+	ret = (clk->ops->set_rate)(clk, rate);
+	spin_unlock(&clocks_lock);
+
+	return ret;
+}
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+	return clk->parent;
+}
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	int ret = 0;
+
+	if (IS_ERR(clk))
+		return -EINVAL;
+
+	spin_lock(&clocks_lock);
+
+	if (clk->ops && clk->ops->set_parent)
+		ret = (clk->ops->set_parent)(clk, parent);
+
+	spin_unlock(&clocks_lock);
+
+	return ret;
+}
+
+EXPORT_SYMBOL(clk_get);
+EXPORT_SYMBOL(clk_put);
+EXPORT_SYMBOL(clk_enable);
+EXPORT_SYMBOL(clk_disable);
+EXPORT_SYMBOL(clk_get_rate);
+EXPORT_SYMBOL(clk_round_rate);
+EXPORT_SYMBOL(clk_set_rate);
+EXPORT_SYMBOL(clk_get_parent);
+EXPORT_SYMBOL(clk_set_parent);
+
+/* base clocks */
+
+int clk_default_setrate(struct clk *clk, unsigned long rate)
+{
+	clk->rate = rate;
+	return 0;
+}
+
+struct clk_ops clk_ops_def_setrate = {
+	.set_rate	= clk_default_setrate,
+};
+
+struct clk clk_xtal = {
+	.name		= "xtal",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+};
+
+struct clk clk_ext = {
+	.name		= "ext",
+	.id		= -1,
+};
+
+struct clk clk_epll = {
+	.name		= "epll",
+	.id		= -1,
+};
+
+struct clk clk_mpll = {
+	.name		= "mpll",
+	.id		= -1,
+	.ops		= &clk_ops_def_setrate,
+};
+
+struct clk clk_upll = {
+	.name		= "upll",
+	.id		= -1,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+};
+
+struct clk clk_f = {
+	.name		= "fclk",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= &clk_mpll,
+	.ctrlbit	= 0,
+};
+
+struct clk clk_h = {
+	.name		= "hclk",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+	.ops		= &clk_ops_def_setrate,
+};
+
+struct clk clk_p = {
+	.name		= "pclk",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+	.ops		= &clk_ops_def_setrate,
+};
+
+struct clk clk_usb_bus = {
+	.name		= "usb-bus",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= &clk_upll,
+};
+
+
+struct clk s3c24xx_uclk = {
+	.name		= "uclk",
+	.id		= -1,
+};
+
+/* initialise the clock system */
+
+/**
+ * s3c24xx_register_clock() - register a clock
+ * @clk: The clock to register
+ *
+ * Add the specified clock to the list of clocks known by the system.
+ */
+int s3c24xx_register_clock(struct clk *clk)
+{
+	if (clk->enable == NULL)
+		clk->enable = clk_null_enable;
+
+	/* add to the list of available clocks */
+
+	/* Quick check to see if this clock has already been registered. */
+	BUG_ON(clk->list.prev != clk->list.next);
+
+	spin_lock(&clocks_lock);
+	list_add(&clk->list, &clocks);
+	spin_unlock(&clocks_lock);
+
+	return 0;
+}
+
+/**
+ * s3c24xx_register_clocks() - register an array of clock pointers
+ * @clks: Pointer to an array of struct clk pointers
+ * @nr_clks: The number of clocks in the @clks array.
+ *
+ * Call s3c24xx_register_clock() for all the clock pointers contained
+ * in the @clks list. Returns the number of failures.
+ */
+int s3c24xx_register_clocks(struct clk **clks, int nr_clks)
+{
+	int fails = 0;
+
+	for (; nr_clks > 0; nr_clks--, clks++) {
+		if (s3c24xx_register_clock(*clks) < 0) {
+			struct clk *clk = *clks;
+			printk(KERN_ERR "%s: failed to register %p: %s\n",
+			       __func__, clk, clk->name);
+			fails++;
+		}
+	}
+
+	return fails;
+}
+
+/**
+ * s3c_register_clocks() - register an array of clocks
+ * @clkp: Pointer to the first clock in the array.
+ * @nr_clks: Number of clocks to register.
+ *
+ * Call s3c24xx_register_clock() on the @clkp array given, printing an
+ * error if it fails to register the clock (unlikely).
+ */
+void __init s3c_register_clocks(struct clk *clkp, int nr_clks)
+{
+	int ret;
+
+	for (; nr_clks > 0; nr_clks--, clkp++) {
+		ret = s3c24xx_register_clock(clkp);
+
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+	}
+}
+
+/* initalise all the clocks */
+
+int __init s3c24xx_register_baseclocks(unsigned long xtal)
+{
+	printk(KERN_INFO "S3C24XX Clocks, Copyright 2004 Simtec Electronics\n");
+
+	clk_xtal.rate = xtal;
+
+	/* register our clocks */
+
+	if (s3c24xx_register_clock(&clk_xtal) < 0)
+		printk(KERN_ERR "failed to register master xtal\n");
+
+	if (s3c24xx_register_clock(&clk_mpll) < 0)
+		printk(KERN_ERR "failed to register mpll clock\n");
+
+	if (s3c24xx_register_clock(&clk_upll) < 0)
+		printk(KERN_ERR "failed to register upll clock\n");
+
+	if (s3c24xx_register_clock(&clk_f) < 0)
+		printk(KERN_ERR "failed to register cpu fclk\n");
+
+	if (s3c24xx_register_clock(&clk_h) < 0)
+		printk(KERN_ERR "failed to register cpu hclk\n");
+
+	if (s3c24xx_register_clock(&clk_p) < 0)
+		printk(KERN_ERR "failed to register cpu pclk\n");
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/clock-clksrc.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/clock-clksrc.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/clock-clksrc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/clock-clksrc.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,212 @@
+/* linux/arch/arm/plat-samsung/clock-clksrc.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu-freq.h>
+
+static inline struct clksrc_clk *to_clksrc(struct clk *clk)
+{
+	return container_of(clk, struct clksrc_clk, clk);
+}
+
+static inline u32 bit_mask(u32 shift, u32 nr_bits)
+{
+	u32 mask = 0xffffffff >> (32 - nr_bits);
+
+	return mask << shift;
+}
+
+static unsigned long s3c_getrate_clksrc(struct clk *clk)
+{
+	struct clksrc_clk *sclk = to_clksrc(clk);
+	unsigned long rate = clk_get_rate(clk->parent);
+	u32 clkdiv = __raw_readl(sclk->reg_div.reg);
+	u32 mask = bit_mask(sclk->reg_div.shift, sclk->reg_div.size);
+
+	clkdiv &= mask;
+	clkdiv >>= sclk->reg_div.shift;
+	clkdiv++;
+
+	rate /= clkdiv;
+	return rate;
+}
+
+static int s3c_setrate_clksrc(struct clk *clk, unsigned long rate)
+{
+	struct clksrc_clk *sclk = to_clksrc(clk);
+	void __iomem *reg = sclk->reg_div.reg;
+	unsigned int div;
+	u32 mask = bit_mask(sclk->reg_div.shift, sclk->reg_div.size);
+	u32 val;
+
+	rate = clk_round_rate(clk, rate);
+	div = clk_get_rate(clk->parent) / rate;
+	if (div > (1 << sclk->reg_div.size))
+		return -EINVAL;
+
+	val = __raw_readl(reg);
+	val &= ~mask;
+	val |= (div - 1) << sclk->reg_div.shift;
+	__raw_writel(val, reg);
+
+	return 0;
+}
+
+static int s3c_setparent_clksrc(struct clk *clk, struct clk *parent)
+{
+	struct clksrc_clk *sclk = to_clksrc(clk);
+	struct clksrc_sources *srcs = sclk->sources;
+	u32 clksrc = __raw_readl(sclk->reg_src.reg);
+	u32 mask = bit_mask(sclk->reg_src.shift, sclk->reg_src.size);
+	int src_nr = -1;
+	int ptr;
+
+	for (ptr = 0; ptr < srcs->nr_sources; ptr++)
+		if (srcs->sources[ptr] == parent) {
+			src_nr = ptr;
+			break;
+		}
+
+	if (src_nr >= 0) {
+		clk->parent = parent;
+
+		clksrc &= ~mask;
+		clksrc |= src_nr << sclk->reg_src.shift;
+
+		__raw_writel(clksrc, sclk->reg_src.reg);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static unsigned long s3c_roundrate_clksrc(struct clk *clk,
+					      unsigned long rate)
+{
+	struct clksrc_clk *sclk = to_clksrc(clk);
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	int max_div = 1 << sclk->reg_div.size;
+	int div;
+
+	if (rate >= parent_rate)
+		rate = parent_rate;
+	else {
+		div = parent_rate / rate;
+		if (parent_rate % rate)
+			div++;
+
+		if (div == 0)
+			div = 1;
+		if (div > max_div)
+			div = max_div;
+
+		rate = parent_rate / div;
+	}
+
+	return rate;
+}
+
+/* Clock initialisation code */
+
+void __init_or_cpufreq s3c_set_clksrc(struct clksrc_clk *clk, bool announce)
+{
+	struct clksrc_sources *srcs = clk->sources;
+	u32 mask = bit_mask(clk->reg_src.shift, clk->reg_src.size);
+	u32 clksrc;
+
+	if (!clk->reg_src.reg) {
+		if (!clk->clk.parent)
+			printk(KERN_ERR "%s: no parent clock specified\n",
+				clk->clk.name);
+		return;
+	}
+
+	clksrc = __raw_readl(clk->reg_src.reg);
+	clksrc &= mask;
+	clksrc >>= clk->reg_src.shift;
+
+	if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
+		printk(KERN_ERR "%s: bad source %d\n",
+		       clk->clk.name, clksrc);
+		return;
+	}
+
+	clk->clk.parent = srcs->sources[clksrc];
+
+	if (announce)
+		printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
+		       clk->clk.name, clk->clk.parent->name, clksrc,
+		       clk_get_rate(&clk->clk));
+}
+
+static struct clk_ops clksrc_ops = {
+	.set_parent	= s3c_setparent_clksrc,
+	.get_rate	= s3c_getrate_clksrc,
+	.set_rate	= s3c_setrate_clksrc,
+	.round_rate	= s3c_roundrate_clksrc,
+};
+
+static struct clk_ops clksrc_ops_nodiv = {
+	.set_parent	= s3c_setparent_clksrc,
+};
+
+static struct clk_ops clksrc_ops_nosrc = {
+	.get_rate	= s3c_getrate_clksrc,
+	.set_rate	= s3c_setrate_clksrc,
+	.round_rate	= s3c_roundrate_clksrc,
+};
+
+void __init s3c_register_clksrc(struct clksrc_clk *clksrc, int size)
+{
+	int ret;
+
+	for (; size > 0; size--, clksrc++) {
+		if (!clksrc->reg_div.reg && !clksrc->reg_src.reg)
+			printk(KERN_ERR "%s: clock %s has no registers set\n",
+			       __func__, clksrc->clk.name);
+
+		/* fill in the default functions */
+
+		if (!clksrc->clk.ops) {
+			if (!clksrc->reg_div.reg)
+				clksrc->clk.ops = &clksrc_ops_nodiv;
+			else if (!clksrc->reg_src.reg)
+				clksrc->clk.ops = &clksrc_ops_nosrc;
+			else
+				clksrc->clk.ops = &clksrc_ops;
+		}
+
+		/* setup the clocksource, but do not announce it
+		 * as it may be re-set by the setup routines
+		 * called after the rest of the clocks have been
+		 * registered
+		 */
+		s3c_set_clksrc(clksrc, false);
+
+		ret = s3c24xx_register_clock(&clksrc->clk);
+
+		if (ret < 0) {
+			printk(KERN_ERR "%s: failed to register %s (%d)\n",
+			       __func__, clksrc->clk.name, ret);
+		}
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-fb.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-fb.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-fb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,74 @@
+/* linux/arch/arm/plat-s3c/dev-fb.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for framebuffer 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/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/gfp.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/regs-fb.h>
+
+#include <plat/fb.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_fb_resource[] = {
+	[0] = {
+		.start = S3C_PA_FB,
+		.end   = S3C_PA_FB + SZ_16K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_LCD_VSYNC,
+		.end   = IRQ_LCD_VSYNC,
+		.flags = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start = IRQ_LCD_FIFO,
+		.end   = IRQ_LCD_FIFO,
+		.flags = IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start = IRQ_LCD_SYSTEM,
+		.end   = IRQ_LCD_SYSTEM,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device s3c_device_fb = {
+	.name		  = "s3c-fb",
+	.id		  = -1,
+	.num_resources	  = ARRAY_SIZE(s3c_fb_resource),
+	.resource	  = s3c_fb_resource,
+	.dev.dma_mask	  = &s3c_device_fb.dev.coherent_dma_mask,
+	.dev.coherent_dma_mask = 0xffffffffUL,
+};
+
+void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
+{
+	struct s3c_fb_platdata *npd;
+
+	if (!pd) {
+		printk(KERN_ERR "%s: no platform data\n", __func__);
+		return;
+	}
+
+	npd = kmemdup(pd, sizeof(struct s3c_fb_platdata), GFP_KERNEL);
+	if (!npd)
+		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+
+	s3c_device_fb.dev.platform_data = npd;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-hsmmc1.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-hsmmc1.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-hsmmc1.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-hsmmc1.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-s3c/dev-hsmmc1.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for hsmmc device 1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mmc/host.h>
+
+#include <mach/map.h>
+#include <plat/sdhci.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#define S3C_SZ_HSMMC	(0x1000)
+
+static struct resource s3c_hsmmc1_resource[] = {
+	[0] = {
+		.start = S3C_PA_HSMMC1,
+		.end   = S3C_PA_HSMMC1 + S3C_SZ_HSMMC - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_HSMMC1,
+		.end   = IRQ_HSMMC1,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static u64 s3c_device_hsmmc1_dmamask = 0xffffffffUL;
+
+struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
+	.max_width	= 4,
+	.host_caps	= (MMC_CAP_4_BIT_DATA |
+			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+};
+
+struct platform_device s3c_device_hsmmc1 = {
+	.name		= "s3c-sdhci",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(s3c_hsmmc1_resource),
+	.resource	= s3c_hsmmc1_resource,
+	.dev		= {
+		.dma_mask		= &s3c_device_hsmmc1_dmamask,
+		.coherent_dma_mask	= 0xffffffffUL,
+		.platform_data		= &s3c_hsmmc1_def_platdata,
+	},
+};
+
+void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+	struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata;
+
+	set->max_width = pd->max_width;
+
+	if (pd->cfg_gpio)
+		set->cfg_gpio = pd->cfg_gpio;
+	if (pd->cfg_card)
+		set->cfg_card = pd->cfg_card;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-hsmmc2.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-hsmmc2.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-hsmmc2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-hsmmc2.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,69 @@
+/* linux/arch/arm/plat-s3c/dev-hsmmc2.c
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * Copyright (c) 2009 Maurus Cuelenaere
+ *
+ * Based on arch/arm/plat-s3c/dev-hsmmc1.c
+ * original file Copyright (c) 2008 Simtec Electronics
+ *
+ * S3C series device definition for hsmmc device 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mmc/host.h>
+
+#include <mach/map.h>
+#include <plat/sdhci.h>
+#include <plat/devs.h>
+
+#define S3C_SZ_HSMMC	(0x1000)
+
+static struct resource s3c_hsmmc2_resource[] = {
+	[0] = {
+		.start = S3C_PA_HSMMC2,
+		.end   = S3C_PA_HSMMC2 + S3C_SZ_HSMMC - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_HSMMC2,
+		.end   = IRQ_HSMMC2,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static u64 s3c_device_hsmmc2_dmamask = 0xffffffffUL;
+
+struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
+	.max_width	= 4,
+	.host_caps	= (MMC_CAP_4_BIT_DATA |
+			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+};
+
+struct platform_device s3c_device_hsmmc2 = {
+	.name		= "s3c-sdhci",
+	.id		= 2,
+	.num_resources	= ARRAY_SIZE(s3c_hsmmc2_resource),
+	.resource	= s3c_hsmmc2_resource,
+	.dev		= {
+		.dma_mask		= &s3c_device_hsmmc2_dmamask,
+		.coherent_dma_mask	= 0xffffffffUL,
+		.platform_data		= &s3c_hsmmc2_def_platdata,
+	},
+};
+
+void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+	struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
+
+	set->max_width = pd->max_width;
+
+	if (pd->cfg_gpio)
+		set->cfg_gpio = pd->cfg_gpio;
+	if (pd->cfg_card)
+		set->cfg_card = pd->cfg_card;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-hsmmc.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-hsmmc.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-hsmmc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-hsmmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-s3c/dev-hsmmc.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for hsmmc devices
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mmc/host.h>
+
+#include <mach/map.h>
+#include <plat/sdhci.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#define S3C_SZ_HSMMC	(0x1000)
+
+static struct resource s3c_hsmmc_resource[] = {
+	[0] = {
+		.start = S3C_PA_HSMMC0,
+		.end   = S3C_PA_HSMMC0 + S3C_SZ_HSMMC - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_HSMMC0,
+		.end   = IRQ_HSMMC0,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static u64 s3c_device_hsmmc_dmamask = 0xffffffffUL;
+
+struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
+	.max_width	= 4,
+	.host_caps	= (MMC_CAP_4_BIT_DATA |
+			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+};
+
+struct platform_device s3c_device_hsmmc0 = {
+	.name		= "s3c-sdhci",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(s3c_hsmmc_resource),
+	.resource	= s3c_hsmmc_resource,
+	.dev		= {
+		.dma_mask		= &s3c_device_hsmmc_dmamask,
+		.coherent_dma_mask	= 0xffffffffUL,
+		.platform_data		= &s3c_hsmmc0_def_platdata,
+	},
+};
+
+void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+	struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata;
+
+	set->max_width = pd->max_width;
+
+	if (pd->cfg_gpio)
+		set->cfg_gpio = pd->cfg_gpio;
+	if (pd->cfg_card)
+		set->cfg_card = pd->cfg_card;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-i2c0.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-i2c0.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-i2c0.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-i2c0.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,72 @@
+/* linux/arch/arm/plat-s3c/dev-i2c0.c
+ *
+ * Copyright 2008-2009 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for i2c device 0
+ *
+ * This program is free software; you can 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/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+	[0] = {
+		.start = S3C_PA_IIC,
+		.end   = S3C_PA_IIC + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_IIC,
+		.end   = IRQ_IIC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device s3c_device_i2c0 = {
+	.name		  = "s3c2410-i2c",
+#ifdef CONFIG_S3C_DEV_I2C1
+	.id		  = 0,
+#else
+	.id		  = -1,
+#endif
+	.num_resources	  = ARRAY_SIZE(s3c_i2c_resource),
+	.resource	  = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
+	.flags		= 0,
+	.slave_addr	= 0x10,
+	.frequency	= 100*1000,
+	.sda_delay	= 100,
+};
+
+void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+	struct s3c2410_platform_i2c *npd;
+
+	if (!pd)
+		pd = &default_i2c_data0;
+
+	npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+	if (!npd)
+		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+	else if (!npd->cfg_gpio)
+		npd->cfg_gpio = s3c_i2c0_cfg_gpio;
+
+	s3c_device_i2c0.dev.platform_data = npd;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-i2c1.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-i2c1.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-i2c1.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-i2c1.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,69 @@
+/* linux/arch/arm/plat-s3c/dev-i2c1.c
+ *
+ * Copyright 2008-2009 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for i2c device 1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+	[0] = {
+		.start = S3C_PA_IIC1,
+		.end   = S3C_PA_IIC1 + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_IIC1,
+		.end   = IRQ_IIC1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device s3c_device_i2c1 = {
+	.name		  = "s3c2410-i2c",
+	.id		  = 1,
+	.num_resources	  = ARRAY_SIZE(s3c_i2c_resource),
+	.resource	  = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data1 __initdata = {
+	.flags		= 0,
+	.bus_num	= 1,
+	.slave_addr	= 0x10,
+	.frequency	= 100*1000,
+	.sda_delay	= 100,
+};
+
+void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+	struct s3c2410_platform_i2c *npd;
+
+	if (!pd)
+		pd = &default_i2c_data1;
+
+	npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+	if (!npd)
+		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+	else if (!npd->cfg_gpio)
+		npd->cfg_gpio = s3c_i2c1_cfg_gpio;
+
+	s3c_device_i2c1.dev.platform_data = npd;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-nand.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-nand.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-nand.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-nand.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,130 @@
+/*
+ * S3C series device definition for nand 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/gfp.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <mach/map.h>
+#include <plat/devs.h>
+#include <plat/nand.h>
+
+static struct resource s3c_nand_resource[] = {
+	[0] = {
+		.start = S3C_PA_NAND,
+		.end   = S3C_PA_NAND + SZ_1M,
+		.flags = IORESOURCE_MEM,
+	}
+};
+
+struct platform_device s3c_device_nand = {
+	.name		  = "s3c2410-nand",
+	.id		  = -1,
+	.num_resources	  = ARRAY_SIZE(s3c_nand_resource),
+	.resource	  = s3c_nand_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_nand);
+
+/**
+ * s3c_nand_copy_set() - copy nand set data
+ * @set: The new structure, directly copied from the old.
+ *
+ * Copy all the fields from the NAND set field from what is probably __initdata
+ * to new kernel memory. The code returns 0 if the copy happened correctly or
+ * an error code for the calling function to display.
+ *
+ * Note, we currently do not try and look to see if we've already copied the
+ * data in a previous set.
+ */
+static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set)
+{
+	void *ptr;
+	int size;
+
+	size = sizeof(struct mtd_partition) * set->nr_partitions;
+	if (size) {
+		ptr = kmemdup(set->partitions, size, GFP_KERNEL);
+		set->partitions = ptr;
+
+		if (!ptr)
+			return -ENOMEM;
+	}
+	
+	if (set->nr_map && set->nr_chips) {
+		size = sizeof(int) * set->nr_chips;
+		ptr = kmemdup(set->nr_map, size, GFP_KERNEL);
+		set->nr_map = ptr;
+
+		if (!ptr)
+			return -ENOMEM;
+	}
+
+	if (set->ecc_layout) {
+		ptr = kmemdup(set->ecc_layout,
+			      sizeof(struct nand_ecclayout), GFP_KERNEL);
+		set->ecc_layout = ptr;
+
+		if (!ptr)
+			return -ENOMEM;
+	}
+	
+	return 0;
+}
+
+void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
+{
+	struct s3c2410_platform_nand *npd;
+	int size;
+	int ret;
+
+	/* note, if we get a failure in allocation, we simply drop out of the
+	 * function. If there is so little memory available at initialisation
+	 * time then there is little chance the system is going to run.
+	 */ 
+
+	npd = kmemdup(nand, sizeof(struct s3c2410_platform_nand), GFP_KERNEL);
+	if (!npd) {
+		printk(KERN_ERR "%s: failed copying platform data\n", __func__);
+		return;
+	}
+
+	/* now see if we need to copy any of the nand set data */
+
+	size = sizeof(struct s3c2410_nand_set) * npd->nr_sets;
+	if (size) {
+		struct s3c2410_nand_set *from = npd->sets;
+		struct s3c2410_nand_set *to;
+		int i;
+
+		to = kmemdup(from, size, GFP_KERNEL);
+		npd->sets = to;	/* set, even if we failed */
+
+		if (!to) {
+			printk(KERN_ERR "%s: no memory for sets\n", __func__);
+			return;
+		}
+		
+		for (i = 0; i < npd->nr_sets; i++) {
+			ret = s3c_nand_copy_set(to);
+			if (ret) {
+				printk(KERN_ERR "%s: failed to copy set %d\n",
+				__func__, i);
+				return;
+			}
+			to++;
+		}
+	}
+
+	s3c_device_nand.dev.platform_data = npd;
+}
+
+EXPORT_SYMBOL_GPL(s3c_nand_set_platdata);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-uart.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-uart.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-uart.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-uart.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,44 @@
+/* linux/arch/arm/plat-samsung/dev-uart.c
+ *	originally from arch/arm/plat-s3c24xx/devs.c
+ *x
+ * Copyright (c) 2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Base S3C24XX platform device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+/* uart devices */
+
+static struct platform_device s3c24xx_uart_device0 = {
+	.id		= 0,
+};
+
+static struct platform_device s3c24xx_uart_device1 = {
+	.id		= 1,
+};
+
+static struct platform_device s3c24xx_uart_device2 = {
+	.id		= 2,
+};
+
+static struct platform_device s3c24xx_uart_device3 = {
+	.id		= 3,
+};
+
+struct platform_device *s3c24xx_uart_src[4] = {
+	&s3c24xx_uart_device0,
+	&s3c24xx_uart_device1,
+	&s3c24xx_uart_device2,
+	&s3c24xx_uart_device3,
+};
+
+struct platform_device *s3c24xx_uart_devs[4] = {
+};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-usb.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-usb.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-usb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,70 @@
+/* linux/arch/arm/plat-s3c/dev-usb.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for USB host
+ *
+ * This program is free software; you can 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/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+#include <plat/usb-control.h>
+
+static struct resource s3c_usb_resource[] = {
+	[0] = {
+		.start = S3C_PA_USBHOST,
+		.end   = S3C_PA_USBHOST + 0x100 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_USBH,
+		.end   = IRQ_USBH,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static u64 s3c_device_usb_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_ohci = {
+	.name		  = "s3c2410-ohci",
+	.id		  = -1,
+	.num_resources	  = ARRAY_SIZE(s3c_usb_resource),
+	.resource	  = s3c_usb_resource,
+	.dev              = {
+		.dma_mask = &s3c_device_usb_dmamask,
+		.coherent_dma_mask = 0xffffffffUL
+	}
+};
+
+EXPORT_SYMBOL(s3c_device_ohci);
+
+/**
+ * s3c_ohci_set_platdata - initialise OHCI device platform data
+ * @info: The platform data.
+ *
+ * This call copies the @info passed in and sets the device .platform_data
+ * field to that copy. The @info is copied so that the original can be marked
+ * __initdata.
+ */
+void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info)
+{
+	struct s3c2410_hcd_info *npd;
+
+	npd = kmemdup(info, sizeof(struct s3c2410_hcd_info), GFP_KERNEL);
+	if (!npd)
+		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+
+	s3c_device_ohci.dev.platform_data = npd;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-usb-hsotg.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-usb-hsotg.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dev-usb-hsotg.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dev-usb-hsotg.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,48 @@
+/* linux/arch/arm/plat-s3c/dev-usb-hsotg.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for USB high-speed UDC/OtG block
+ *
+ * This program is free software; you can 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/string.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+static struct resource s3c_usb_hsotg_resources[] = {
+	[0] = {
+		.start	= S3C_PA_USB_HSOTG,
+		.end	= S3C_PA_USB_HSOTG + 0x10000 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_OTG,
+		.end	= IRQ_OTG,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 s3c_hsotg_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s3c_device_usb_hsotg = {
+	.name		= "s3c-hsotg",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(s3c_usb_hsotg_resources),
+	.resource	= s3c_usb_hsotg_resources,
+	.dev		= {
+		.dma_mask		= &s3c_hsotg_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dma.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/dma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,84 @@
+/* linux/arch/arm/plat-samsung/dma.c
+ *
+ * Copyright (c) 2003-2009 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C DMA core
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct s3c2410_dma_buf;
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+/* dma channel state information */
+struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
+struct s3c2410_dma_chan *s3c_dma_chan_map[DMACH_MAX];
+
+/* s3c_dma_lookup_channel
+ *
+ * change the dma channel number given into a real dma channel id
+*/
+
+struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel)
+{
+	if (channel & DMACH_LOW_LEVEL)
+		return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
+	else
+		return s3c_dma_chan_map[channel];
+}
+
+/* do we need to protect the settings of the fields from
+ * irq?
+*/
+
+int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn)
+{
+	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	pr_debug("%s: chan=%p, op rtn=%p\n", __func__, chan, rtn);
+
+	chan->op_fn = rtn;
+
+	return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_set_opfn);
+
+int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn)
+{
+	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	pr_debug("%s: chan=%p, callback rtn=%p\n", __func__, chan, rtn);
+
+	chan->callback_fn = rtn;
+
+	return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
+
+int s3c2410_dma_setflags(unsigned int channel, unsigned int flags)
+{
+	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	chan->flags = flags;
+	return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_setflags);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/gpio.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/gpio.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,156 @@
+/* linux/arch/arm/plat-s3c/gpio.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series GPIO core
+ *
+ * This program is free software; you can 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 <plat/gpio-core.h>
+
+#ifdef CONFIG_S3C_GPIO_TRACK
+struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
+
+static __init void s3c_gpiolib_track(struct s3c_gpio_chip *chip)
+{
+	unsigned int gpn;
+	int i;
+
+	gpn = chip->chip.base;
+	for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
+		BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
+		s3c_gpios[gpn] = chip;
+	}
+}
+#endif /* CONFIG_S3C_GPIO_TRACK */
+
+/* Default routines for controlling GPIO, based on the original S3C24XX
+ * GPIO functions which deal with the case where each gpio bank of the
+ * chip is as following:
+ *
+ * base + 0x00: Control register, 2 bits per gpio
+ *	        gpio n: 2 bits starting at (2*n)
+ *		00 = input, 01 = output, others mean special-function
+ * base + 0x04: Data register, 1 bit per gpio
+ *		bit n: data bit n
+*/
+
+static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	unsigned long flags;
+	unsigned long con;
+
+	local_irq_save(flags);
+
+	con = __raw_readl(base + 0x00);
+	con &= ~(3 << (offset * 2));
+
+	__raw_writel(con, base + 0x00);
+
+	local_irq_restore(flags);
+	return 0;
+}
+
+static int s3c_gpiolib_output(struct gpio_chip *chip,
+			      unsigned offset, int value)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	unsigned long flags;
+	unsigned long dat;
+	unsigned long con;
+
+	local_irq_save(flags);
+
+	dat = __raw_readl(base + 0x04);
+	dat &= ~(1 << offset);
+	if (value)
+		dat |= 1 << offset;
+	__raw_writel(dat, base + 0x04);
+
+	con = __raw_readl(base + 0x00);
+	con &= ~(3 << (offset * 2));
+	con |= 1 << (offset * 2);
+
+	__raw_writel(con, base + 0x00);
+	__raw_writel(dat, base + 0x04);
+
+	local_irq_restore(flags);
+	return 0;
+}
+
+static void s3c_gpiolib_set(struct gpio_chip *chip,
+			    unsigned offset, int value)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	unsigned long flags;
+	unsigned long dat;
+
+	local_irq_save(flags);
+
+	dat = __raw_readl(base + 0x04);
+	dat &= ~(1 << offset);
+	if (value)
+		dat |= 1 << offset;
+	__raw_writel(dat, base + 0x04);
+
+	local_irq_restore(flags);
+}
+
+static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	unsigned long val;
+
+	val = __raw_readl(ourchip->base + 0x04);
+	val >>= offset;
+	val &= 1;
+
+	return val;
+}
+
+__init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
+{
+	struct gpio_chip *gc = &chip->chip;
+	int ret;
+
+	BUG_ON(!chip->base);
+	BUG_ON(!gc->label);
+	BUG_ON(!gc->ngpio);
+
+	if (!gc->direction_input)
+		gc->direction_input = s3c_gpiolib_input;
+	if (!gc->direction_output)
+		gc->direction_output = s3c_gpiolib_output;
+	if (!gc->set)
+		gc->set = s3c_gpiolib_set;
+	if (!gc->get)
+		gc->get = s3c_gpiolib_get;
+
+#ifdef CONFIG_PM
+	if (chip->pm != NULL) {
+		if (!chip->pm->save || !chip->pm->resume)
+			printk(KERN_ERR "gpio: %s has missing PM functions\n",
+			       gc->label);
+	} else
+		printk(KERN_ERR "gpio: %s has no PM function\n", gc->label);
+#endif
+
+	/* gpiochip_add() prints own failure message on error. */
+	ret = gpiochip_add(gc);
+	if (ret >= 0)
+		s3c_gpiolib_track(chip);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/gpio-config.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/gpio-config.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/gpio-config.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/gpio-config.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,166 @@
+/* linux/arch/arm/plat-s3c/gpio-config.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series GPIO configuration core
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
+{
+	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+	unsigned long flags;
+	int offset;
+	int ret;
+
+	if (!chip)
+		return -EINVAL;
+
+	offset = pin - chip->chip.base;
+
+	local_irq_save(flags);
+	ret = s3c_gpio_do_setcfg(chip, offset, config);
+	local_irq_restore(flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_cfgpin);
+
+int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
+{
+	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+	unsigned long flags;
+	int offset, ret;
+
+	if (!chip)
+		return -EINVAL;
+
+	offset = pin - chip->chip.base;
+
+	local_irq_save(flags);
+	ret = s3c_gpio_do_setpull(chip, offset, pull);
+	local_irq_restore(flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_setpull);
+
+#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
+int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
+				  unsigned int off, unsigned int cfg)
+{
+	void __iomem *reg = chip->base;
+	unsigned int shift = off;
+	u32 con;
+
+	if (s3c_gpio_is_cfg_special(cfg)) {
+		cfg &= 0xf;
+
+		/* Map output to 0, and SFN2 to 1 */
+		cfg -= 1;
+		if (cfg > 1)
+			return -EINVAL;
+
+		cfg <<= shift;
+	}
+
+	con = __raw_readl(reg);
+	con &= ~(0x1 << shift);
+	con |= cfg;
+	__raw_writel(con, reg);
+
+	return 0;
+}
+
+int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
+			    unsigned int off, unsigned int cfg)
+{
+	void __iomem *reg = chip->base;
+	unsigned int shift = off * 2;
+	u32 con;
+
+	if (s3c_gpio_is_cfg_special(cfg)) {
+		cfg &= 0xf;
+		if (cfg > 3)
+			return -EINVAL;
+
+		cfg <<= shift;
+	}
+
+	con = __raw_readl(reg);
+	con &= ~(0x3 << shift);
+	con |= cfg;
+	__raw_writel(con, reg);
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
+int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+				 unsigned int off, unsigned int cfg)
+{
+	void __iomem *reg = chip->base;
+	unsigned int shift = (off & 7) * 4;
+	u32 con;
+
+	if (off < 8 && chip->chip.ngpio > 8)
+		reg -= 4;
+
+	if (s3c_gpio_is_cfg_special(cfg)) {
+		cfg &= 0xf;
+		cfg <<= shift;
+	}
+
+	con = __raw_readl(reg);
+	con &= ~(0xf << shift);
+	con |= cfg;
+	__raw_writel(con, reg);
+
+	return 0;
+}
+#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
+
+#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
+int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
+			    unsigned int off, s3c_gpio_pull_t pull)
+{
+	void __iomem *reg = chip->base + 0x08;
+	int shift = off * 2;
+	u32 pup;
+
+	pup = __raw_readl(reg);
+	pup &= ~(3 << shift);
+	pup |= pull << shift;
+	__raw_writel(pup, reg);
+
+	return 0;
+}
+
+s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
+					unsigned int off)
+{
+	void __iomem *reg = chip->base + 0x08;
+	int shift = off * 2;
+	u32 pup = __raw_readl(reg);
+
+	pup >>= shift;
+	pup &= 0x3;
+	return (__force s3c_gpio_pull_t)pup;
+}
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/gpiolib.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/gpiolib.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/gpiolib.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/gpiolib.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,199 @@
+/* arch/arm/plat-samsung/gpiolib.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * SAMSUNG - GPIOlib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/gpio.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+#ifndef DEBUG_GPIO
+#define gpio_dbg(x...) do { } while (0)
+#else
+#define gpio_dbg(x...) printk(KERN_DEBUG x)
+#endif
+
+/* The samsung_gpiolib_4bit routines are to control the gpio banks where
+ * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
+ * following example:
+ *
+ * base + 0x00: Control register, 4 bits per gpio
+ *		gpio n: 4 bits starting at (4*n)
+ *		0000 = input, 0001 = output, others mean special-function
+ * base + 0x04: Data register, 1 bit per gpio
+ *		bit n: data bit n
+ *
+ * Note, since the data register is one bit per gpio and is at base + 0x4
+ * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of
+ * the output.
+*/
+
+static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
+				      unsigned int offset)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	unsigned long con;
+
+	con = __raw_readl(base + GPIOCON_OFF);
+	con &= ~(0xf << con_4bit_shift(offset));
+	__raw_writel(con, base + GPIOCON_OFF);
+
+	gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
+
+	return 0;
+}
+
+static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
+				       unsigned int offset, int value)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	unsigned long con;
+	unsigned long dat;
+
+	con = __raw_readl(base + GPIOCON_OFF);
+	con &= ~(0xf << con_4bit_shift(offset));
+	con |= 0x1 << con_4bit_shift(offset);
+
+	dat = __raw_readl(base + GPIODAT_OFF);
+
+	if (value)
+		dat |= 1 << offset;
+	else
+		dat &= ~(1 << offset);
+
+	__raw_writel(dat, base + GPIODAT_OFF);
+	__raw_writel(con, base + GPIOCON_OFF);
+	__raw_writel(dat, base + GPIODAT_OFF);
+
+	gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
+	return 0;
+}
+
+/* The next set of routines are for the case where the GPIO configuration
+ * registers are 4 bits per GPIO but there is more than one register (the
+ * bank has more than 8 GPIOs.
+ *
+ * This case is the similar to the 4 bit case, but the registers are as
+ * follows:
+ *
+ * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
+ *		gpio n: 4 bits starting at (4*n)
+ *		0000 = input, 0001 = output, others mean special-function
+ * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
+ *		gpio n: 4 bits starting at (4*n)
+ *		0000 = input, 0001 = output, others mean special-function
+ * base + 0x08: Data register, 1 bit per gpio
+ *		bit n: data bit n
+ *
+ * To allow us to use the s3c_gpiolib_get and s3c_gpiolib_set routines we
+ * store the 'base + 0x4' address so that these routines see the data
+ * register at ourchip->base + 0x04.
+ */
+
+static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
+				       unsigned int offset)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	void __iomem *regcon = base;
+	unsigned long con;
+
+	if (offset > 7)
+		offset -= 8;
+	else
+		regcon -= 4;
+
+	con = __raw_readl(regcon);
+	con &= ~(0xf << con_4bit_shift(offset));
+	__raw_writel(con, regcon);
+
+	gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
+
+	return 0;
+}
+
+static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
+					unsigned int offset, int value)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	void __iomem *regcon = base;
+	unsigned long con;
+	unsigned long dat;
+	unsigned con_offset = offset;
+
+	if (con_offset > 7)
+		con_offset -= 8;
+	else
+		regcon -= 4;
+
+	con = __raw_readl(regcon);
+	con &= ~(0xf << con_4bit_shift(con_offset));
+	con |= 0x1 << con_4bit_shift(con_offset);
+
+	dat = __raw_readl(base + GPIODAT_OFF);
+
+	if (value)
+		dat |= 1 << offset;
+	else
+		dat &= ~(1 << offset);
+
+	__raw_writel(dat, base + GPIODAT_OFF);
+	__raw_writel(con, regcon);
+	__raw_writel(dat, base + GPIODAT_OFF);
+
+	gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
+	return 0;
+}
+
+void __init samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip)
+{
+	chip->chip.direction_input = samsung_gpiolib_4bit_input;
+	chip->chip.direction_output = samsung_gpiolib_4bit_output;
+	chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
+}
+
+void __init samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip)
+{
+	chip->chip.direction_input = samsung_gpiolib_4bit2_input;
+	chip->chip.direction_output = samsung_gpiolib_4bit2_output;
+	chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
+}
+
+void __init samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
+					   int nr_chips)
+{
+	for (; nr_chips > 0; nr_chips--, chip++) {
+		samsung_gpiolib_add_4bit(chip);
+		s3c_gpiolib_add(chip);
+	}
+}
+
+void __init samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
+					    int nr_chips)
+{
+	for (; nr_chips > 0; nr_chips--, chip++) {
+		samsung_gpiolib_add_4bit2(chip);
+		s3c_gpiolib_add(chip);
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/adc.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/adc.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/adc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/adc.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,35 @@
+/* arch/arm/plat-samsung/include/plat/adc.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *	http://armlinux.simnte.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C ADC driver 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_PLAT_ADC_H
+#define __ASM_PLAT_ADC_H __FILE__
+
+struct s3c_adc_client;
+
+extern int s3c_adc_start(struct s3c_adc_client *client,
+			 unsigned int channel, unsigned int nr_samples);
+
+extern int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch);
+
+extern struct s3c_adc_client *
+	s3c_adc_register(struct platform_device *pdev,
+			 void (*select)(struct s3c_adc_client *client,
+					unsigned selected),
+			 void (*conv)(struct s3c_adc_client *client,
+				      unsigned d0, unsigned d1,
+				      unsigned *samples_left),
+			 unsigned int is_ts);
+
+extern void s3c_adc_release(struct s3c_adc_client *client);
+
+#endif /* __ASM_PLAT_ADC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/audio.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/audio.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/audio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/audio.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,25 @@
+/* arch/arm/plat-samsung/include/plat/audio.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co. Ltd
+ * Author: Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* The machine init code calls s3c*_ac97_setup_gpio with
+ * one of these defines in order to select appropriate bank
+ * of GPIO for AC97 pins
+ */
+#define S3C64XX_AC97_GPD  0
+#define S3C64XX_AC97_GPE  1
+extern void s3c64xx_ac97_setup_gpio(int);
+
+/**
+ * struct s3c_audio_pdata - common platform data for audio device drivers
+ * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode
+ */
+struct s3c_audio_pdata {
+	int (*cfg_gpio)(struct platform_device *);
+};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/clock-clksrc.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/clock-clksrc.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/clock-clksrc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/clock-clksrc.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,83 @@
+/* linux/arch/arm/plat-samsung/include/plat/clock-clksrc.h
+ *
+ * Parts taken from arch/arm/plat-s3c64xx/clock.c
+ *	Copyright 2008 Openmoko, Inc.
+ *	Copyright 2008 Simtec Electronics
+ *		Ben Dooks <ben@simtec.co.uk>
+ *		http://armlinux.simtec.co.uk/
+ *
+ * Copyright 2009 Ben Dooks <ben-linux@fluff.org>
+ * Copyright 2009 Harald Welte
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/**
+ * struct clksrc_sources - list of sources for a given clock
+ * @sources: array of pointers to clocks
+ * @nr_sources: The size of @sources
+ */
+struct clksrc_sources {
+	unsigned int	nr_sources;
+	struct clk	**sources;
+};
+
+/**
+ * struct clksrc_reg - register definition for clock control bits
+ * @reg: pointer to the register in virtual memory.
+ * @shift: the shift in bits to where the bitfield is.
+ * @size: the size in bits of the bitfield.
+ *
+ * This specifies the size and position of the bits we are interested
+ * in within the register specified by @reg.
+ */
+struct clksrc_reg {
+	void __iomem		*reg;
+	unsigned short		shift;
+	unsigned short		size;
+};
+
+/**
+ * struct clksrc_clk - class of clock for newer style samsung devices.
+ * @clk: the standard clock representation
+ * @sources: the sources for this clock
+ * @reg_src: the register definition for selecting the clock's source
+ * @reg_div: the register definition for the clock's output divisor
+ *
+ * This clock implements the features required by the newer SoCs where
+ * the standard clock block provides an input mux and a post-mux divisor
+ * to provide the periperhal's clock.
+ *
+ * The array of @sources provides the mapping of mux position to the
+ * clock, and @reg_src shows the code where to modify to change the mux
+ * position. The @reg_div defines how to change the divider settings on
+ * the output.
+ */
+struct clksrc_clk {
+	struct clk		clk;
+	struct clksrc_sources	*sources;
+
+	struct clksrc_reg	reg_src;
+	struct clksrc_reg	reg_div;
+};
+
+/**
+ * s3c_set_clksrc() - setup the clock from the register settings
+ * @clk: The clock to setup.
+ * @announce: true to announce the setting to printk().
+ *
+ * Setup the clock from the current register settings, for when the
+ * kernel boots or if it is resuming from a possibly unknown state.
+ */
+extern void s3c_set_clksrc(struct clksrc_clk *clk, bool announce);
+
+/**
+ * s3c_register_clksrc() register clocks from an array of clksrc clocks
+ * @srcs: The array of clocks to register
+ * @size: The size of the @srcs array.
+ *
+ * Initialise and register the array of clocks described by @srcs.
+ */
+extern void s3c_register_clksrc(struct clksrc_clk *srcs, int size);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/clock.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/clock.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,115 @@
+/* linux/arch/arm/plat-s3c/include/plat/clock.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	http://www.simtec.co.uk/products/SWLINUX/
+ *	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.
+*/
+
+#include <linux/spinlock.h>
+
+struct clk;
+
+/**
+ * struct clk_ops - standard clock operations
+ * @set_rate: set the clock rate, see clk_set_rate().
+ * @get_rate: get the clock rate, see clk_get_rate().
+ * @round_rate: round a given clock rate, see clk_round_rate().
+ * @set_parent: set the clock's parent, see clk_set_parent().
+ *
+ * Group the common clock implementations together so that we
+ * don't have to keep setting the same fiels again. We leave
+ * enable in struct clk.
+ *
+ * Adding an extra layer of indirection into the process should
+ * not be a problem as it is unlikely these operations are going
+ * to need to be called quickly.
+ */
+struct clk_ops {
+	int		    (*set_rate)(struct clk *c, unsigned long rate);
+	unsigned long	    (*get_rate)(struct clk *c);
+	unsigned long	    (*round_rate)(struct clk *c, unsigned long rate);
+	int		    (*set_parent)(struct clk *c, struct clk *parent);
+};
+
+struct clk {
+	struct list_head      list;
+	struct module        *owner;
+	struct clk           *parent;
+	const char           *name;
+	int		      id;
+	int		      usage;
+	unsigned long         rate;
+	unsigned long         ctrlbit;
+
+	struct clk_ops		*ops;
+	int		    (*enable)(struct clk *, int enable);
+};
+
+/* other clocks which may be registered by board support */
+
+extern struct clk s3c24xx_dclk0;
+extern struct clk s3c24xx_dclk1;
+extern struct clk s3c24xx_clkout0;
+extern struct clk s3c24xx_clkout1;
+extern struct clk s3c24xx_uclk;
+
+extern struct clk clk_usb_bus;
+
+/* core clock support */
+
+extern struct clk clk_f;
+extern struct clk clk_h;
+extern struct clk clk_p;
+extern struct clk clk_mpll;
+extern struct clk clk_upll;
+extern struct clk clk_epll;
+extern struct clk clk_xtal;
+extern struct clk clk_ext;
+
+/* S3C64XX specific clocks */
+extern struct clk clk_h2;
+extern struct clk clk_27m;
+extern struct clk clk_48m;
+
+extern int clk_default_setrate(struct clk *clk, unsigned long rate);
+extern struct clk_ops clk_ops_def_setrate;
+
+/* exports for arch/arm/mach-s3c2410
+ *
+ * Please DO NOT use these outside of arch/arm/mach-s3c2410
+*/
+
+extern spinlock_t clocks_lock;
+
+extern int s3c2410_clkcon_enable(struct clk *clk, int enable);
+
+extern int s3c24xx_register_clock(struct clk *clk);
+extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks);
+
+extern void s3c_register_clocks(struct clk *clk, int nr_clks);
+
+extern int s3c24xx_register_baseclocks(unsigned long xtal);
+
+extern void s5p_register_clocks(unsigned long xtal_freq);
+
+extern void s3c24xx_setup_clocks(unsigned long fclk,
+				 unsigned long hclk,
+				 unsigned long pclk);
+
+extern void s3c2410_setup_clocks(void);
+extern void s3c2412_setup_clocks(void);
+extern void s3c244x_setup_clocks(void);
+extern void s3c2443_setup_clocks(void);
+
+/* S3C64XX specific functions and clocks */
+
+extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable);
+
+/* Init for pwm clock code */
+
+extern void s3c_pwmclk_init(void);
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/cpu-freq.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/cpu-freq.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/cpu-freq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/cpu-freq.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,145 @@
+/* arch/arm/plat-samsung/include/plat/cpu-freq.h
+ *
+ * Copyright (c) 2006-2007 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C CPU frequency scaling support - driver and board
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/cpufreq.h>
+
+struct s3c_cpufreq_info;
+struct s3c_cpufreq_board;
+struct s3c_iotimings;
+
+/**
+ * struct s3c_freq - frequency information (mainly for core drivers)
+ * @fclk: The FCLK frequency in Hz.
+ * @armclk: The ARMCLK frequency in Hz.
+ * @hclk_tns: HCLK cycle time in 10ths of nano-seconds.
+ * @hclk: The HCLK frequency in Hz.
+ * @pclk: The PCLK frequency in Hz.
+ *
+ * This contains the frequency information about the current configuration
+ * mainly for the core drivers to ensure we do not end up passing about
+ * a large number of parameters.
+ *
+ * The @hclk_tns field is a useful cache for the parts of the drivers that
+ * need to calculate IO timings and suchlike.
+ */
+struct s3c_freq {
+	unsigned long	fclk;
+	unsigned long	armclk;
+	unsigned long	hclk_tns;	/* in 10ths of ns */
+	unsigned long	hclk;
+	unsigned long	pclk;
+};
+
+/**
+ * struct s3c_cpufreq_freqs - s3c cpufreq notification information.
+ * @freqs: The cpufreq setting information.
+ * @old: The old clock settings.
+ * @new: The new clock settings.
+ * @pll_changing: Set if the PLL is changing.
+ *
+ * Wrapper 'struct cpufreq_freqs' so that any drivers receiving the
+ * notification can use this information that is not provided by just
+ * having the core frequency alone.
+ *
+ * The pll_changing flag is used to indicate if the PLL itself is
+ * being set during this change. This is important as the clocks
+ * will temporarily be set to the XTAL clock during this time, so
+ * drivers may want to close down their output during this time.
+ *
+ * Note, this is not being used by any current drivers and therefore
+ * may be removed in the future.
+ */
+struct s3c_cpufreq_freqs {
+	struct cpufreq_freqs	freqs;
+	struct s3c_freq		old;
+	struct s3c_freq		new;
+
+	unsigned int		pll_changing:1;
+};
+
+#define to_s3c_cpufreq(_cf) container_of(_cf, struct s3c_cpufreq_freqs, freqs)
+
+/**
+ * struct s3c_clkdivs - clock divisor information
+ * @p_divisor: Divisor from FCLK to PCLK.
+ * @h_divisor: Divisor from FCLK to HCLK.
+ * @arm_divisor: Divisor from FCLK to ARMCLK (not all CPUs).
+ * @dvs: Non-zero if using DVS mode for ARMCLK.
+ *
+ * Divisor settings for the core clocks.
+ */
+struct s3c_clkdivs {
+	int		p_divisor;
+	int		h_divisor;
+	int		arm_divisor;
+	unsigned char	dvs;
+};
+
+#define PLLVAL(_m, _p, _s) (((_m) << 12) | ((_p) << 4) | (_s))
+
+/**
+ * struct s3c_pllval - PLL value entry.
+ * @freq: The frequency for this entry in Hz.
+ * @pll_reg: The PLL register setting for this PLL value.
+ */
+struct s3c_pllval {
+	unsigned long		freq;
+	unsigned long		pll_reg;
+};
+
+/**
+ * struct s3c_cpufreq_board - per-board cpu frequency informatin
+ * @refresh: The SDRAM refresh period in nanoseconds.
+ * @auto_io: Set if the IO timing settings should be generated from the
+ *	initialisation time hardware registers.
+ * @need_io: Set if the board has external IO on any of the chipselect
+ *	lines that will require the hardware timing registers to be
+ *	updated on a clock change.
+ * @max: The maxium frequency limits for the system. Any field that
+ *	is left at zero will use the CPU's settings.
+ *
+ * This contains the board specific settings that affect how the CPU
+ * drivers chose settings. These include the memory refresh and IO
+ * timing information.
+ *
+ * Registration depends on the driver being used, the ARMCLK only
+ * implementation does not currently need this but the older style
+ * driver requires this to be available.
+ */
+struct s3c_cpufreq_board {
+	unsigned int	refresh;
+	unsigned int	auto_io:1;	/* automatically init io timings. */
+	unsigned int	need_io:1;	/* set if needs io timing support. */
+
+	/* any non-zero field in here is taken as an upper limit. */
+	struct s3c_freq	max;	/* frequency limits */
+};
+
+/* Things depending on frequency scaling. */
+#ifdef CONFIG_CPU_FREQ_S3C
+#define __init_or_cpufreq
+#else
+#define __init_or_cpufreq __init
+#endif
+
+/* Board functions */
+
+#ifdef CONFIG_CPU_FREQ_S3C
+extern int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board);
+#else
+
+static inline int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
+{
+	return 0;
+}
+#endif  /* CONFIG_CPU_FREQ_S3C */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/cpu.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/cpu.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/cpu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/cpu.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,84 @@
+/* linux/arch/arm/plat-samsung/include/plat/cpu.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C24XX CPU 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.
+*/
+
+/* todo - fix when rmk changes iodescs to use `void __iomem *` */
+
+#ifndef __SAMSUNG_PLAT_CPU_H
+#define __SAMSUNG_PLAT_CPU_H
+
+#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
+
+#ifndef MHZ
+#define MHZ (1000*1000)
+#endif
+
+#define print_mhz(m) ((m) / MHZ), (((m) / 1000) % 1000)
+
+/* forward declaration */
+struct s3c24xx_uart_resources;
+struct platform_device;
+struct s3c2410_uartcfg;
+struct map_desc;
+
+/* per-cpu initialisation function table. */
+
+struct cpu_table {
+	unsigned long	idcode;
+	unsigned long	idmask;
+	void		(*map_io)(void);
+	void		(*init_uarts)(struct s3c2410_uartcfg *cfg, int no);
+	void		(*init_clocks)(int xtal);
+	int		(*init)(void);
+	const char	*name;
+};
+
+extern void s3c_init_cpu(unsigned long idcode,
+			 struct cpu_table *cpus, unsigned int cputab_size);
+
+/* core initialisation functions */
+
+extern void s3c24xx_init_irq(void);
+extern void s3c64xx_init_irq(u32 vic0, u32 vic1);
+extern void s5p_init_irq(u32 *vic, u32 num_vic);
+
+extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
+extern void s3c64xx_init_io(struct map_desc *mach_desc, int size);
+extern void s5p_init_io(struct map_desc *mach_desc,
+			int size, void __iomem *cpuid_addr);
+
+extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c24xx_init_clocks(int xtal);
+
+extern void s3c24xx_init_uartdevs(char *name,
+				  struct s3c24xx_uart_resources *res,
+				  struct s3c2410_uartcfg *cfg, int no);
+
+/* timer for 2410/2440 */
+
+struct sys_timer;
+extern struct sys_timer s3c24xx_timer;
+
+/* system device classes */
+
+extern struct sysdev_class s3c2410_sysclass;
+extern struct sysdev_class s3c2410a_sysclass;
+extern struct sysdev_class s3c2412_sysclass;
+extern struct sysdev_class s3c2440_sysclass;
+extern struct sysdev_class s3c2442_sysclass;
+extern struct sysdev_class s3c2443_sysclass;
+extern struct sysdev_class s3c6410_sysclass;
+extern struct sysdev_class s3c64xx_sysclass;
+
+extern void (*s5pc1xx_idle)(void);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,87 @@
+/* arch/arm/plat-samsung/include/plat/debug-macro.S
+ *
+ * Copyright 2005, 2007 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	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.
+*/
+
+#include <plat/regs-serial.h>
+
+/* The S5PV210/S5PC110 and S5P6442 implementations are as belows. */
+
+	.macro fifo_level_s5pv210 rd, rx
+		ldr	\rd, [ \rx, # S3C2410_UFSTAT ]
+		and	\rd, \rd, #S5PV210_UFSTAT_TXMASK
+	.endm
+
+	.macro  fifo_full_s5pv210 rd, rx
+		ldr	\rd, [ \rx, # S3C2410_UFSTAT ]
+		tst	\rd, #S5PV210_UFSTAT_TXFULL
+	.endm
+
+/* The S3C2440 implementations are used by default as they are the
+ * most widely re-used */
+
+	.macro fifo_level_s3c2440 rd, rx
+		ldr	\rd, [ \rx, # S3C2410_UFSTAT ]
+		and	\rd, \rd, #S3C2440_UFSTAT_TXMASK
+	.endm
+
+#ifndef fifo_level
+#define fifo_level fifo_level_s3c2440
+#endif
+
+	.macro  fifo_full_s3c2440 rd, rx
+		ldr	\rd, [ \rx, # S3C2410_UFSTAT ]
+		tst	\rd, #S3C2440_UFSTAT_TXFULL
+	.endm
+
+#ifndef fifo_full
+#define fifo_full fifo_full_s3c2440
+#endif
+
+	.macro	senduart,rd,rx
+		strb 	\rd, [\rx, # S3C2410_UTXH ]
+	.endm
+
+	.macro	busyuart, rd, rx
+		ldr	\rd, [ \rx, # S3C2410_UFCON ]
+		tst	\rd, #S3C2410_UFCON_FIFOMODE	@ fifo enabled?
+		beq	1001f				@
+		@ FIFO enabled...
+1003:
+		fifo_full \rd, \rx
+		bne	1003b
+		b	1002f
+
+1001:
+		@ busy waiting for non fifo
+		ldr	\rd, [ \rx, # S3C2410_UTRSTAT ]
+		tst	\rd, #S3C2410_UTRSTAT_TXFE
+		beq	1001b
+
+1002:		@ exit busyuart
+	.endm
+
+	.macro	waituart,rd,rx
+		ldr	\rd, [ \rx, # S3C2410_UFCON ]
+		tst	\rd, #S3C2410_UFCON_FIFOMODE	@ fifo enabled?
+		beq	1001f				@
+		@ FIFO enabled...
+1003:
+		fifo_level \rd, \rx
+		teq	\rd, #0
+		bne	1003b
+		b	1002f
+1001:
+		@ idle waiting for non fifo
+		ldr	\rd, [ \rx, # S3C2410_UTRSTAT ]
+		tst	\rd, #S3C2410_UTRSTAT_TXFE
+		beq	1001b
+
+1002:		@ exit busyuart
+	.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/devs.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/devs.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/devs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/devs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,74 @@
+/* arch/arm/plat-samsung/include/plat/devs.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2410 standard platform devices
+ *
+ * This program is free software; you can 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>
+
+struct s3c24xx_uart_resources {
+	struct resource		*resources;
+	unsigned long		 nr_resources;
+};
+
+extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
+extern struct s3c24xx_uart_resources s3c64xx_uart_resources[];
+extern struct s3c24xx_uart_resources s5p_uart_resources[];
+
+extern struct platform_device *s3c24xx_uart_devs[];
+extern struct platform_device *s3c24xx_uart_src[];
+
+extern struct platform_device s3c_device_timer[];
+
+extern struct platform_device s3c64xx_device_iis0;
+extern struct platform_device s3c64xx_device_iis1;
+extern struct platform_device s3c64xx_device_iisv4;
+
+extern struct platform_device s3c64xx_device_spi0;
+extern struct platform_device s3c64xx_device_spi1;
+
+extern struct platform_device s3c64xx_device_pcm0;
+extern struct platform_device s3c64xx_device_pcm1;
+
+extern struct platform_device s3c64xx_device_ac97;
+
+extern struct platform_device s3c_device_ts;
+
+extern struct platform_device s3c_device_fb;
+extern struct platform_device s3c_device_ohci;
+extern struct platform_device s3c_device_lcd;
+extern struct platform_device s3c_device_wdt;
+extern struct platform_device s3c_device_i2c0;
+extern struct platform_device s3c_device_i2c1;
+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_iis;
+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;
+
+extern struct platform_device s3c_device_spi0;
+extern struct platform_device s3c_device_spi1;
+
+extern struct platform_device s3c_device_hwmon;
+
+extern struct platform_device s3c_device_nand;
+
+extern struct platform_device s3c_device_usbgadget;
+extern struct platform_device s3c_device_usb_hsotg;
+
+/* s3c2440 specific devices */
+
+#ifdef CONFIG_CPU_S3C2440
+
+extern struct platform_device s3c_device_camif;
+extern struct platform_device s3c_device_ac97;
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/dma-core.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/dma-core.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/dma-core.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/dma-core.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,22 @@
+/* arch/arm/plat-s3c/include/plat/dma.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * Samsung S3C DMA core 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.
+*/
+
+extern struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel);
+
+extern struct s3c2410_dma_chan *s3c_dma_chan_map[];
+
+/* the currently allocated channel information */
+extern struct s3c2410_dma_chan s3c2410_chans[];
+
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/dma.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/dma.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/dma.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,127 @@
+/* arch/arm/plat-samsung/include/plat/dma.h
+ *
+ * Copyright (C) 2003-2006 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C DMA 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.
+*/
+
+enum s3c2410_dma_buffresult {
+	S3C2410_RES_OK,
+	S3C2410_RES_ERR,
+	S3C2410_RES_ABORT
+};
+
+enum s3c2410_dmasrc {
+	S3C2410_DMASRC_HW,		/* source is memory */
+	S3C2410_DMASRC_MEM		/* source is hardware */
+};
+
+/* enum s3c2410_chan_op
+ *
+ * operation codes passed to the DMA code by the user, and also used
+ * to inform the current channel owner of any changes to the system state
+*/
+
+enum s3c2410_chan_op {
+	S3C2410_DMAOP_START,
+	S3C2410_DMAOP_STOP,
+	S3C2410_DMAOP_PAUSE,
+	S3C2410_DMAOP_RESUME,
+	S3C2410_DMAOP_FLUSH,
+	S3C2410_DMAOP_TIMEOUT,		/* internal signal to handler */
+	S3C2410_DMAOP_STARTED,		/* indicate channel started */
+};
+
+struct s3c2410_dma_client {
+	char                *name;
+};
+
+struct s3c2410_dma_chan;
+
+/* s3c2410_dma_cbfn_t
+ *
+ * buffer callback routine type
+*/
+
+typedef void (*s3c2410_dma_cbfn_t)(struct s3c2410_dma_chan *,
+				   void *buf, int size,
+				   enum s3c2410_dma_buffresult result);
+
+typedef int  (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *,
+				   enum s3c2410_chan_op );
+
+
+
+/* s3c2410_dma_request
+ *
+ * request a dma channel exclusivley
+*/
+
+extern int s3c2410_dma_request(unsigned int channel,
+			       struct s3c2410_dma_client *, void *dev);
+
+
+/* s3c2410_dma_ctrl
+ *
+ * change the state of the dma channel
+*/
+
+extern int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op);
+
+/* s3c2410_dma_setflags
+ *
+ * set the channel's flags to a given state
+*/
+
+extern int s3c2410_dma_setflags(unsigned int channel,
+				unsigned int flags);
+
+/* s3c2410_dma_free
+ *
+ * free the dma channel (will also abort any outstanding operations)
+*/
+
+extern int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *);
+
+/* s3c2410_dma_enqueue
+ *
+ * place the given buffer onto the queue of operations for the channel.
+ * The buffer must be allocated from dma coherent memory, or the Dcache/WB
+ * drained before the buffer is given to the DMA system.
+*/
+
+extern int s3c2410_dma_enqueue(unsigned int channel, void *id,
+			       dma_addr_t data, int size);
+
+/* s3c2410_dma_config
+ *
+ * configure the dma channel
+*/
+
+extern int s3c2410_dma_config(unsigned int channel, int xferunit);
+
+/* s3c2410_dma_devconfig
+ *
+ * configure the device we're talking to
+*/
+
+extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source,
+				 unsigned long devaddr);
+
+/* s3c2410_dma_getposition
+ *
+ * get the position that the dma transfer is currently at
+*/
+
+extern int s3c2410_dma_getposition(unsigned int channel,
+				   dma_addr_t *src, dma_addr_t *dest);
+
+extern int s3c2410_dma_set_opfn(unsigned int, s3c2410_dma_opfn_t rtn);
+extern int s3c2410_dma_set_buffdone_fn(unsigned int, s3c2410_dma_cbfn_t rtn);
+
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,84 @@
+/* linux/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
+ *
+ * Copyright (C) 2006 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C24XX DMA support - per SoC functions
+ *
+ * This program is free software; you can 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 <plat/dma-core.h>
+
+extern struct sysdev_class dma_sysclass;
+extern struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
+
+#define DMA_CH_VALID		(1<<31)
+#define DMA_CH_NEVER		(1<<30)
+
+struct s3c24xx_dma_addr {
+	unsigned long		from;
+	unsigned long		to;
+};
+
+/* struct s3c24xx_dma_map
+ *
+ * this holds the mapping information for the channel selected
+ * to be connected to the specified device
+*/
+
+struct s3c24xx_dma_map {
+	const char		*name;
+	struct s3c24xx_dma_addr  hw_addr;
+
+	unsigned long		 channels[S3C_DMA_CHANNELS];
+	unsigned long		 channels_rx[S3C_DMA_CHANNELS];
+};
+
+struct s3c24xx_dma_selection {
+	struct s3c24xx_dma_map	*map;
+	unsigned long		 map_size;
+	unsigned long		 dcon_mask;
+
+	void	(*select)(struct s3c2410_dma_chan *chan,
+			  struct s3c24xx_dma_map *map);
+
+	void	(*direction)(struct s3c2410_dma_chan *chan,
+			     struct s3c24xx_dma_map *map,
+			     enum s3c2410_dmasrc dir);
+};
+
+extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
+
+/* struct s3c24xx_dma_order_ch
+ *
+ * channel map for one of the `enum dma_ch` dma channels. the list
+ * entry contains a set of low-level channel numbers, orred with
+ * DMA_CH_VALID, which are checked in the order in the array.
+*/
+
+struct s3c24xx_dma_order_ch {
+	unsigned int	list[S3C_DMA_CHANNELS];	/* list of channels */
+	unsigned int	flags;				/* flags */
+};
+
+/* struct s3c24xx_dma_order
+ *
+ * information provided by either the core or the board to give the
+ * dma system a hint on how to allocate channels
+*/
+
+struct s3c24xx_dma_order {
+	struct s3c24xx_dma_order_ch	channels[DMACH_MAX];
+};
+
+extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map);
+
+/* DMA init code, called from the cpu support code */
+
+extern int s3c2410_dma_init(void);
+
+extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq,
+			    unsigned int stride);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/fb.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/fb.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/fb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/fb.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,80 @@
+/* arch/arm/plat-samsung/include/plat/fb.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - FB platform data 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 __PLAT_S3C_FB_H
+#define __PLAT_S3C_FB_H __FILE__
+
+/**
+ * struct s3c_fb_pd_win - per window setup data
+ * @win_mode: The display parameters to initialise (not for window 0)
+ * @virtual_x: The virtual X size.
+ * @virtual_y: The virtual Y size.
+ */
+struct s3c_fb_pd_win {
+	struct fb_videomode	win_mode;
+
+	unsigned short		default_bpp;
+	unsigned short		max_bpp;
+	unsigned short		virtual_x;
+	unsigned short		virtual_y;
+};
+
+/**
+ * struct s3c_fb_platdata -  S3C driver platform specific information
+ * @setup_gpio: Setup the external GPIO pins to the right state to transfer
+ *		the data from the display system to the connected display
+ *		device.
+ * @vidcon0: The base vidcon0 values to control the panel data format.
+ * @vidcon1: The base vidcon1 values to control the panel data output.
+ * @win: The setup data for each hardware window, or NULL for unused.
+ * @display_mode: The LCD output display mode.
+ *
+ * The platform data supplies the video driver with all the information
+ * it requires to work with the display(s) attached to the machine. It
+ * controls the initial mode, the number of display windows (0 is always
+ * the base framebuffer) that are initialised etc.
+ *
+ */
+struct s3c_fb_platdata {
+	void	(*setup_gpio)(void);
+
+	struct s3c_fb_pd_win	*win[S3C_FB_MAX_WIN];
+
+	u32			 vidcon0;
+	u32			 vidcon1;
+};
+
+/**
+ * s3c_fb_set_platdata() - Setup the FB device with platform data.
+ * @pd: The platform data to set. The data is copied from the passed structure
+ *      so the machine data can mark the data __initdata so that any unused
+ *      machines will end up dumping their data at runtime.
+ */
+extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
+
+/**
+ * s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
+ */
+extern void s3c64xx_fb_gpio_setup_24bpp(void);
+
+/**
+ * s5pc100_fb_gpio_setup_24bpp() - S5PC100 setup function for 24bpp LCD
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
+ */
+extern void s5pc100_fb_gpio_setup_24bpp(void);
+
+#endif /* __PLAT_S3C_FB_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/gpio-cfg.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/gpio-cfg.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/gpio-cfg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/gpio-cfg.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,110 @@
+/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - GPIO pin configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* This file contains the necessary definitions to get the basic gpio
+ * pin configuration done such as setting a pin to input or output or
+ * changing the pull-{up,down} configurations.
+ */
+
+/* Note, this interface is being added to the s3c64xx arch first and will
+ * be added to the s3c24xx systems later.
+ */
+
+#ifndef __PLAT_GPIO_CFG_H
+#define __PLAT_GPIO_CFG_H __FILE__
+
+typedef unsigned int __bitwise__ s3c_gpio_pull_t;
+
+/* forward declaration if gpio-core.h hasn't been included */
+struct s3c_gpio_chip;
+
+/**
+ * struct s3c_gpio_cfg GPIO configuration
+ * @cfg_eint: Configuration setting when used for external interrupt source
+ * @get_pull: Read the current pull configuration for the GPIO
+ * @set_pull: Set the current pull configuraiton for the GPIO
+ * @set_config: Set the current configuration for the GPIO
+ * @get_config: Read the current configuration for the GPIO
+ *
+ * Each chip can have more than one type of GPIO bank available and some
+ * have different capabilites even when they have the same control register
+ * layouts. Provide an point to vector control routine and provide any
+ * per-bank configuration information that other systems such as the
+ * external interrupt code will need.
+ */
+struct s3c_gpio_cfg {
+	unsigned int	cfg_eint;
+
+	s3c_gpio_pull_t	(*get_pull)(struct s3c_gpio_chip *chip, unsigned offs);
+	int		(*set_pull)(struct s3c_gpio_chip *chip, unsigned offs,
+				    s3c_gpio_pull_t pull);
+
+	unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs);
+	int	 (*set_config)(struct s3c_gpio_chip *chip, unsigned offs,
+			       unsigned config);
+};
+
+#define S3C_GPIO_SPECIAL_MARK	(0xfffffff0)
+#define S3C_GPIO_SPECIAL(x)	(S3C_GPIO_SPECIAL_MARK | (x))
+
+/* Defines for generic pin configurations */
+#define S3C_GPIO_INPUT	(S3C_GPIO_SPECIAL(0))
+#define S3C_GPIO_OUTPUT	(S3C_GPIO_SPECIAL(1))
+#define S3C_GPIO_SFN(x)	(S3C_GPIO_SPECIAL(x))
+
+#define s3c_gpio_is_cfg_special(_cfg) \
+	(((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK)
+
+/**
+ * s3c_gpio_cfgpin() - Change the GPIO function of a pin.
+ * @pin pin The pin number to configure.
+ * @pin to The configuration for the pin's function.
+ *
+ * Configure which function is actually connected to the external
+ * pin, such as an gpio input, output or some form of special function
+ * connected to an internal peripheral block.
+ */
+extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
+
+/* Define values for the pull-{up,down} available for each gpio pin.
+ *
+ * These values control the state of the weak pull-{up,down} resistors
+ * available on most pins on the S3C series. Not all chips support both
+ * up or down settings, and it may be dependant on the chip that is being
+ * used to whether the particular mode is available.
+ */
+#define S3C_GPIO_PULL_NONE	((__force s3c_gpio_pull_t)0x00)
+#define S3C_GPIO_PULL_DOWN	((__force s3c_gpio_pull_t)0x01)
+#define S3C_GPIO_PULL_UP	((__force s3c_gpio_pull_t)0x02)
+
+/**
+ * s3c_gpio_setpull() - set the state of a gpio pin pull resistor
+ * @pin: The pin number to configure the pull resistor.
+ * @pull: The configuration for the pull resistor.
+ *
+ * This function sets the state of the pull-{up,down} resistor for the
+ * specified pin. It will return 0 if successfull, or a negative error
+ * code if the pin cannot support the requested pull setting.
+*/
+extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_getpull() - get the pull resistor state of a gpio pin
+ * @pin: The pin number to get the settings for
+ *
+ * Read the pull resistor value for the specified pin.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
+
+#endif /* __PLAT_GPIO_CFG_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,176 @@
+/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg-helper.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - GPIO pin configuration helper 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.
+*/
+
+/* This is meant for core cpu support, machine or other driver files
+ * should not be including this header.
+ */
+
+#ifndef __PLAT_GPIO_CFG_HELPERS_H
+#define __PLAT_GPIO_CFG_HELPERS_H __FILE__
+
+/* As a note, all gpio configuration functions are entered exclusively, either
+ * with the relevant lock held or the system prevented from doing anything else
+ * by disabling interrupts.
+*/
+
+static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip,
+				     unsigned int off, unsigned int config)
+{
+	return (chip->config->set_config)(chip, off, config);
+}
+
+static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
+				      unsigned int off, s3c_gpio_pull_t pull)
+{
+	return (chip->config->set_pull)(chip, off, pull);
+}
+
+/**
+ * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register
+ * has two bits of configuration per gpio, which have the following
+ * functions:
+ *	00 = input
+ *	01 = output
+ *	1x = special function
+*/
+extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
+				   unsigned int off, unsigned int cfg);
+
+/**
+ * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A)
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register
+ * has one bit of configuration for the gpio, where setting the bit
+ * means the pin is in special function mode and unset means output.
+*/
+extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+				     unsigned int off, unsigned int cfg);
+
+/**
+ * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ *	0000 = Input
+ *	0001 = Output
+ *	others = Special functions (dependant on bank)
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a separate set of functions for
+ * each case.
+*/
+extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+					unsigned int off, unsigned int cfg);
+
+
+/* Pull-{up,down} resistor controls.
+ *
+ * S3C2410,S3C2440,S3C24A0 = Pull-UP,
+ * S3C2412,S3C2413 = Pull-Down
+ * S3C6400,S3C6410 = Pull-Both [None,Down,Up,Undef]
+ * S3C2443 = Pull-Both [not same as S3C6400]
+ */
+
+/**
+ * s3c_gpio_setpull_1up() - Pull configuration for choice of up or none.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @param: pull: The pull mode being requested.
+ *
+ * This is a helper function for the case where we have GPIOs with one
+ * bit configuring the presence of a pull-up resistor.
+ */
+extern int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
+				unsigned int off, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_setpull_1down() - Pull configuration for choice of down or none
+ * @chip: The gpio chip that is being configured
+ * @off: The offset for the GPIO being configured
+ * @param: pull: The pull mode being requested
+ *
+ * This is a helper function for the case where we have GPIOs with one
+ * bit configuring the presence of a pull-down resistor.
+ */
+extern int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
+				  unsigned int off, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_setpull_upown() - Pull configuration for choice of up, down or none
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @param: pull: The pull mode being requested.
+ *
+ * This is a helper function for the case where we have GPIOs with two
+ * bits configuring the presence of a pull resistor, in the following
+ * order:
+ *	00 = No pull resistor connected
+ *	01 = Pull-up resistor connected
+ *	10 = Pull-down resistor connected
+ */
+extern int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
+				   unsigned int off, s3c_gpio_pull_t pull);
+
+
+/**
+ * s3c_gpio_getpull_updown() - Get configuration for choice of up, down or none
+ * @chip: The gpio chip that the GPIO pin belongs to
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This helper function reads the state of the pull-{up,down} resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_upown.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
+					       unsigned int off);
+
+/**
+ * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @param: pull: The pull mode being requested.
+ *
+ * This is a helper function for the case where we have GPIOs with two
+ * bits configuring the presence of a pull resistor, in the following
+ * order:
+ *	00 = Pull-up resistor connected
+ *	10 = Pull-down resistor connected
+ *	x1 = No pull up resistor
+ */
+extern int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip,
+				    unsigned int off, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_getpull_s3c2443() - Get configuration for s3c2443 pull resistors
+ * @chip: The gpio chip that the GPIO pin belongs to.
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This helper function reads the state of the pull-{up,down} resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_upown.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_s3c24xx(struct s3c_gpio_chip *chip,
+						unsigned int off);
+
+#endif /* __PLAT_GPIO_CFG_HELPERS_H */
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/gpio-core.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/gpio-core.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/gpio-core.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/gpio-core.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,137 @@
+/* linux/arch/arm/plat-s3c/include/plat/gpio-core.h
+ *
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - GPIO core
+ *
+ * This program is free software; you can 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 GPIOCON_OFF	(0x00)
+#define GPIODAT_OFF	(0x04)
+
+#define con_4bit_shift(__off) ((__off) * 4)
+
+/* Define the core gpiolib support functions that the s3c platforms may
+ * need to extend or change depending on the hardware and the s3c chip
+ * selected at build or found at run time.
+ *
+ * These definitions are not intended for driver inclusion, there is
+ * nothing here that should not live outside the platform and core
+ * specific code.
+*/
+
+struct s3c_gpio_chip;
+
+/**
+ * struct s3c_gpio_pm - power management (suspend/resume) information
+ * @save: Routine to save the state of the GPIO block
+ * @resume: Routine to resume the GPIO block.
+ */
+struct s3c_gpio_pm {
+	void (*save)(struct s3c_gpio_chip *chip);
+	void (*resume)(struct s3c_gpio_chip *chip);
+};
+
+struct s3c_gpio_cfg;
+
+/**
+ * struct s3c_gpio_chip - wrapper for specific implementation of gpio
+ * @chip: The chip structure to be exported via gpiolib.
+ * @base: The base pointer to the gpio configuration registers.
+ * @config: special function and pull-resistor control information.
+ * @pm_save: Save information for suspend/resume support.
+ *
+ * This wrapper provides the necessary information for the Samsung
+ * specific gpios being registered with gpiolib.
+ */
+struct s3c_gpio_chip {
+	struct gpio_chip	chip;
+	struct s3c_gpio_cfg	*config;
+	struct s3c_gpio_pm	*pm;
+	void __iomem		*base;
+#ifdef CONFIG_PM
+	u32			pm_save[4];
+#endif
+};
+
+static inline struct s3c_gpio_chip *to_s3c_gpio(struct gpio_chip *gpc)
+{
+	return container_of(gpc, struct s3c_gpio_chip, chip);
+}
+
+/** s3c_gpiolib_add() - add the s3c specific version of a gpio_chip.
+ * @chip: The chip to register
+ *
+ * This is a wrapper to gpiochip_add() that takes our specific gpio chip
+ * information and makes the necessary alterations for the platform and
+ * notes the information for use with the configuration systems and any
+ * other parts of the system.
+ */
+extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip);
+
+/* CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
+ * for use with the configuration calls, and other parts of the s3c gpiolib
+ * support code.
+ *
+ * Not all s3c support code will need this, as some configurations of cpu
+ * may only support one or two different configuration options and have an
+ * easy gpio to s3c_gpio_chip mapping function. If this is the case, then
+ * the machine support file should provide its own s3c_gpiolib_getchip()
+ * and any other necessary functions.
+ */
+
+/**
+ * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
+ * @chip: The gpio chip that is being configured.
+ * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ * 0000 = Input
+ * 0001 = Output
+ * others = Special functions (dependant on bank)
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a seperate set of function
+ * (samsung_gpiolib_add_4bit2_chips)for each case.
+ */
+extern void samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
+					   int nr_chips);
+extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
+					    int nr_chips);
+
+extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
+extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
+
+#ifdef CONFIG_S3C_GPIO_TRACK
+extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
+
+static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip)
+{
+	return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL;
+}
+#else
+/* machine specific code should provide s3c_gpiolib_getchip */
+
+#include <mach/gpio-track.h>
+
+static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { }
+#endif
+
+#ifdef CONFIG_PM
+extern struct s3c_gpio_pm s3c_gpio_pm_1bit;
+extern struct s3c_gpio_pm s3c_gpio_pm_2bit;
+extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
+#define __gpio_pm(x) x
+#else
+#define s3c_gpio_pm_1bit NULL
+#define s3c_gpio_pm_2bit NULL
+#define s3c_gpio_pm_4bit NULL
+#define __gpio_pm(x) NULL
+
+#endif /* CONFIG_PM */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/hwmon.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/hwmon.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/hwmon.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/hwmon.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,41 @@
+/* linux/arch/arm/plat-s3c/include/plat/hwmon.h
+ *
+ * Copyright 2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C - HWMon interface for ADC
+ *
+ * This program is free software; you can 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_ADC_HWMON_H
+#define __ASM_ARCH_ADC_HWMON_H __FILE__
+
+/**
+ * s3c_hwmon_chcfg - channel configuration
+ * @name: The name to give this channel.
+ * @mult: Multiply the ADC value read by this.
+ * @div: Divide the value from the ADC by this.
+ *
+ * The value read from the ADC is converted to a value that
+ * hwmon expects (mV) by result = (value_read * @mult) / @div.
+ */
+struct s3c_hwmon_chcfg {
+	const char	*name;
+	unsigned int	mult;
+	unsigned int	div;
+};
+
+/**
+ * s3c_hwmon_pdata - HWMON platform data
+ * @in: One configuration for each possible channel used.
+ */
+struct s3c_hwmon_pdata {
+	struct s3c_hwmon_chcfg	*in[8];
+};
+
+#endif /* __ASM_ARCH_ADC_HWMON_H */
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/iic-core.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/iic-core.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/iic-core.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/iic-core.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,35 @@
+/* arch/arm/mach-s3c2410/include/mach/iic-core.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - I2C Controller core functions
+ *
+ * This program is free software; you can 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_IIC_CORE_H
+#define __ASM_ARCH_IIC_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+/* re-define device name depending on support. */
+static inline void s3c_i2c0_setname(char *name)
+{
+	/* currently this device is always compiled in */
+	s3c_device_i2c0.name = name;
+}
+
+static inline void s3c_i2c1_setname(char *name)
+{
+#ifdef CONFIG_S3C_DEV_I2C1
+	s3c_device_i2c1.name = name;
+#endif
+}
+
+#endif /* __ASM_ARCH_IIC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/iic.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/iic.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/iic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/iic.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,62 @@
+/* arch/arm/plat-s3c/include/plat/iic.h
+ *
+ * Copyright 2004-2009 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_IIC_H
+#define __ASM_ARCH_IIC_H __FILE__
+
+#define S3C_IICFLG_FILTER	(1<<0)	/* enable s3c2440 filter */
+
+/**
+ *	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;
+	unsigned int	flags;
+	unsigned int	slave_addr;
+	unsigned long	frequency;
+	unsigned int	sda_delay;
+
+	void	(*cfg_gpio)(struct platform_device *dev);
+};
+
+/**
+ * s3c_i2c0_set_platdata - set platform data for i2c0 device
+ * @i2c: The platform data to set, or NULL for default data.
+ *
+ * Register the given platform data for use with the i2c0 device. This
+ * call copies the platform data, so the caller can use __initdata for
+ * their copy.
+ *
+ * This call will set cfg_gpio if is null to the default platform
+ * implementation.
+ *
+ * Any user of s3c_device_i2c0 should call this, even if it is with
+ * NULL to ensure that the device is given the default platform data
+ * as the driver will no longer carry defaults.
+ */
+extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c);
+
+/* defined by architecture to configure gpio */
+extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c1_cfg_gpio(struct platform_device *dev);
+
+#endif /* __ASM_ARCH_IIC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/irq-uart.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/irq-uart.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/irq-uart.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/irq-uart.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,20 @@
+/* arch/arm/plat-samsung/include/plat/irq-uart.h
+ *
+ * Copyright (c) 2010 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for Samsung SoC UART IRQ demux for S3C64XX and later
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct s3c_uart_irq {
+	void __iomem	*regs;
+	unsigned int	 base_irq;
+	unsigned int	 parent_irq;
+};
+
+extern void s3c_init_uart_irqs(struct s3c_uart_irq *irq, unsigned int nr_irqs);
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/irq-vic-timer.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/irq-vic-timer.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/irq-vic-timer.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/irq-vic-timer.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,13 @@
+/* arch/arm/plat-samsung/include/plat/irq-vic-timer.h
+ *
+ * Copyright (c) 2010 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for Samsung SoC IRQ VIC timer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+extern void s3c_init_vic_timer_irq(unsigned int vic, unsigned int timer);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/map-base.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/map-base.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/map-base.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/map-base.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,46 @@
+/* linux/include/asm-arm/plat-s3c/map.h
+ *
+ * Copyright 2003, 2007 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - Memory map definitions (virtual addresses)
+ *
+ * This program is free software; you can 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_MAP_H
+#define __ASM_PLAT_MAP_H __FILE__
+
+/* Fit all our registers in at 0xF4000000 upwards, trying to use as
+ * little of the VA space as possible so vmalloc and friends have a
+ * better chance of getting memory.
+ *
+ * we try to ensure stuff like the IRQ registers are available for
+ * an single MOVS instruction (ie, only 8 bits of set data)
+ */
+
+#define S3C_ADDR_BASE	(0xF4000000)
+
+#ifndef __ASSEMBLY__
+#define S3C_ADDR(x)	((void __iomem __force *)S3C_ADDR_BASE + (x))
+#else
+#define S3C_ADDR(x)	(S3C_ADDR_BASE + (x))
+#endif
+
+#define S3C_VA_IRQ	S3C_ADDR(0x00000000)	/* irq controller(s) */
+#define S3C_VA_SYS	S3C_ADDR(0x00100000)	/* system control */
+#define S3C_VA_MEM	S3C_ADDR(0x00200000)	/* memory control */
+#define S3C_VA_TIMER	S3C_ADDR(0x00300000)	/* timer block */
+#define S3C_VA_WATCHDOG	S3C_ADDR(0x00400000)	/* watchdog */
+#define S3C_VA_UART	S3C_ADDR(0x01000000)	/* UART */
+
+/* This is used for the CPU specific mappings that may be needed, so that
+ * they do not need to directly used S3C_ADDR() and thus make it easier to
+ * modify the space for mapping.
+ */
+#define S3C_ADDR_CPU(x)	S3C_ADDR(0x00500000 + (x))
+
+#endif /* __ASM_PLAT_MAP_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/nand.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/nand.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/nand.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/nand.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,67 @@
+/* arch/arm/mach-s3c2410/include/mach/nand.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - NAND device 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
+ * published by the Free Software Foundation.
+*/
+
+/**
+ * struct s3c2410_nand_set - define a set of one or more nand chips
+ * @disable_ecc:	Entirely disable ECC - Dangerous
+ * @flash_bbt: 		Openmoko u-boot can create a Bad Block Table
+ *			Setting this flag will allow the kernel to
+ *			look for it at boot time and also skip the NAND
+ *			scan.
+ * @options:		Default value to set into 'struct nand_chip' options.
+ * @nr_chips:		Number of chips in this set
+ * @nr_partitions:	Number of partitions pointed to by @partitions
+ * @name:		Name of set (optional)
+ * @nr_map:		Map for low-layer logical to physical chip numbers (option)
+ * @partitions:		The mtd partition list
+ *
+ * define a set of one or more nand chips registered with an unique mtd. Also
+ * allows to pass flag to the underlying NAND layer. 'disable_ecc' will trigger
+ * a warning at boot time.
+ */
+struct s3c2410_nand_set {
+	unsigned int		disable_ecc:1;
+	unsigned int		flash_bbt:1;
+
+	unsigned int		options;
+	int			nr_chips;
+	int			nr_partitions;
+	char			*name;
+	int			*nr_map;
+	struct mtd_partition	*partitions;
+	struct nand_ecclayout	*ecc_layout;
+};
+
+struct s3c2410_platform_nand {
+	/* timing information for controller, all times in nanoseconds */
+
+	int	tacls;	/* time for active CLE/ALE to nWE/nOE */
+	int	twrph0;	/* active time for nWE/nOE */
+	int	twrph1;	/* time for release CLE/ALE from nWE/nOE inactive */
+
+	unsigned int	ignore_unset_ecc:1;
+
+	int			nr_sets;
+	struct s3c2410_nand_set *sets;
+
+	void			(*select_chip)(struct s3c2410_nand_set *,
+					       int chip);
+};
+
+/**
+ * s3c_nand_set_platdata() - register NAND platform data.
+ * @nand: The NAND platform data to register with s3c_device_nand.
+ *
+ * This function copies the given NAND platform data, @nand and registers
+ * it with the s3c_device_nand. This allows @nand to be __initdata.
+*/
+extern void s3c_nand_set_platdata(struct s3c2410_platform_nand *nand);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/pm.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/pm.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/pm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/pm.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,189 @@
+/* arch/arm/plat-samsung/include/plat/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;
+
+extern unsigned char pm_uart_udivslot;  /* true to save UART UDIVSLOT */
+
+/* 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;
+	u32	udivslot;
+};
+
+/* 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_SAMSUNG_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
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+/**
+ * s3c_pm_debug_smdkled() - Debug PM suspend/resume via SMDK Board LEDs
+ * @set: set bits for the state of the LEDs
+ * @clear: clear bits for the state of the LEDs.
+ */
+extern void s3c_pm_debug_smdkled(u32 set, u32 clear);
+
+#else
+static inline void s3c_pm_debug_smdkled(u32 set, u32 clear) { }
+#endif /* CONFIG_S3C_PM_DEBUG_LED_SMDK */
+
+/* suspend memory checking */
+
+#ifdef CONFIG_SAMSUNG_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.33-gnu1/arch/arm/plat-samsung/include/plat/regs-ac97.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-ac97.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-ac97.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-ac97.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,67 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-ac97.h
+ *
+ * Copyright (c) 2006 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.
+ *
+ * S3C2440 AC97 Controller
+*/
+
+#ifndef __ASM_ARCH_REGS_AC97_H
+#define __ASM_ARCH_REGS_AC97_H __FILE__
+
+#define S3C_AC97_GLBCTRL				(0x00)
+
+#define S3C_AC97_GLBCTRL_CODECREADYIE			(1<<22)
+#define S3C_AC97_GLBCTRL_PCMOUTURIE			(1<<21)
+#define S3C_AC97_GLBCTRL_PCMINORIE			(1<<20)
+#define S3C_AC97_GLBCTRL_MICINORIE			(1<<19)
+#define S3C_AC97_GLBCTRL_PCMOUTTIE			(1<<18)
+#define S3C_AC97_GLBCTRL_PCMINTIE			(1<<17)
+#define S3C_AC97_GLBCTRL_MICINTIE			(1<<16)
+#define S3C_AC97_GLBCTRL_PCMOUTTM_OFF			(0<<12)
+#define S3C_AC97_GLBCTRL_PCMOUTTM_PIO			(1<<12)
+#define S3C_AC97_GLBCTRL_PCMOUTTM_DMA			(2<<12)
+#define S3C_AC97_GLBCTRL_PCMOUTTM_MASK			(3<<12)
+#define S3C_AC97_GLBCTRL_PCMINTM_OFF			(0<<10)
+#define S3C_AC97_GLBCTRL_PCMINTM_PIO			(1<<10)
+#define S3C_AC97_GLBCTRL_PCMINTM_DMA			(2<<10)
+#define S3C_AC97_GLBCTRL_PCMINTM_MASK			(3<<10)
+#define S3C_AC97_GLBCTRL_MICINTM_OFF			(0<<8)
+#define S3C_AC97_GLBCTRL_MICINTM_PIO			(1<<8)
+#define S3C_AC97_GLBCTRL_MICINTM_DMA			(2<<8)
+#define S3C_AC97_GLBCTRL_MICINTM_MASK			(3<<8)
+#define S3C_AC97_GLBCTRL_TRANSFERDATAENABLE		(1<<3)
+#define S3C_AC97_GLBCTRL_ACLINKON			(1<<2)
+#define S3C_AC97_GLBCTRL_WARMRESET			(1<<1)
+#define S3C_AC97_GLBCTRL_COLDRESET			(1<<0)
+
+#define S3C_AC97_GLBSTAT				(0x04)
+
+#define S3C_AC97_GLBSTAT_CODECREADY			(1<<22)
+#define S3C_AC97_GLBSTAT_PCMOUTUR			(1<<21)
+#define S3C_AC97_GLBSTAT_PCMINORI			(1<<20)
+#define S3C_AC97_GLBSTAT_MICINORI			(1<<19)
+#define S3C_AC97_GLBSTAT_PCMOUTTI			(1<<18)
+#define S3C_AC97_GLBSTAT_PCMINTI			(1<<17)
+#define S3C_AC97_GLBSTAT_MICINTI			(1<<16)
+#define S3C_AC97_GLBSTAT_MAINSTATE_IDLE			(0<<0)
+#define S3C_AC97_GLBSTAT_MAINSTATE_INIT			(1<<0)
+#define S3C_AC97_GLBSTAT_MAINSTATE_READY		(2<<0)
+#define S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE		(3<<0)
+#define S3C_AC97_GLBSTAT_MAINSTATE_LP			(4<<0)
+#define S3C_AC97_GLBSTAT_MAINSTATE_WARM			(5<<0)
+
+#define S3C_AC97_CODEC_CMD				(0x08)
+
+#define S3C_AC97_CODEC_CMD_READ				(1<<23)
+
+#define S3C_AC97_STAT					(0x0c)
+#define S3C_AC97_PCM_ADDR				(0x10)
+#define S3C_AC97_PCM_DATA				(0x18)
+#define S3C_AC97_MIC_DATA				(0x1C)
+
+#endif /* __ASM_ARCH_REGS_AC97_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-adc.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-adc.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-adc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-adc.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,64 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-adc.h
+ *
+ * Copyright (c) 2004 Shannon Holland <holland@loser.net>
+ *
+ * This program is free software; yosu can 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 ADC registers
+*/
+
+#ifndef __ASM_ARCH_REGS_ADC_H
+#define __ASM_ARCH_REGS_ADC_H "regs-adc.h"
+
+#define S3C2410_ADCREG(x) (x)
+
+#define S3C2410_ADCCON	   S3C2410_ADCREG(0x00)
+#define S3C2410_ADCTSC	   S3C2410_ADCREG(0x04)
+#define S3C2410_ADCDLY	   S3C2410_ADCREG(0x08)
+#define S3C2410_ADCDAT0	   S3C2410_ADCREG(0x0C)
+#define S3C2410_ADCDAT1	   S3C2410_ADCREG(0x10)
+#define S3C64XX_ADCUPDN		S3C2410_ADCREG(0x14)
+#define S3C64XX_ADCCLRINT	S3C2410_ADCREG(0x18)
+#define S3C64XX_ADCCLRINTPNDNUP	S3C2410_ADCREG(0x20)
+
+
+/* ADCCON Register Bits */
+#define S3C64XX_ADCCON_RESSEL		(1<<16)
+#define S3C2410_ADCCON_ECFLG		(1<<15)
+#define S3C2410_ADCCON_PRSCEN		(1<<14)
+#define S3C2410_ADCCON_PRSCVL(x)	(((x)&0xFF)<<6)
+#define S3C2410_ADCCON_PRSCVLMASK	(0xFF<<6)
+#define S3C2410_ADCCON_SELMUX(x)	(((x)&0x7)<<3)
+#define S3C2410_ADCCON_MUXMASK		(0x7<<3)
+#define S3C2410_ADCCON_STDBM		(1<<2)
+#define S3C2410_ADCCON_READ_START	(1<<1)
+#define S3C2410_ADCCON_ENABLE_START	(1<<0)
+#define S3C2410_ADCCON_STARTMASK	(0x3<<0)
+
+
+/* ADCTSC Register Bits */
+#define S3C2410_ADCTSC_YM_SEN		(1<<7)
+#define S3C2410_ADCTSC_YP_SEN		(1<<6)
+#define S3C2410_ADCTSC_XM_SEN		(1<<5)
+#define S3C2410_ADCTSC_XP_SEN		(1<<4)
+#define S3C2410_ADCTSC_PULL_UP_DISABLE	(1<<3)
+#define S3C2410_ADCTSC_AUTO_PST		(1<<2)
+#define S3C2410_ADCTSC_XY_PST(x)	(((x)&0x3)<<0)
+
+/* ADCDAT0 Bits */
+#define S3C2410_ADCDAT0_UPDOWN		(1<<15)
+#define S3C2410_ADCDAT0_AUTO_PST	(1<<14)
+#define S3C2410_ADCDAT0_XY_PST		(0x3<<12)
+#define S3C2410_ADCDAT0_XPDATA_MASK	(0x03FF)
+
+/* ADCDAT1 Bits */
+#define S3C2410_ADCDAT1_UPDOWN		(1<<15)
+#define S3C2410_ADCDAT1_AUTO_PST	(1<<14)
+#define S3C2410_ADCDAT1_XY_PST		(0x3<<12)
+#define S3C2410_ADCDAT1_YPDATA_MASK	(0x03FF)
+
+#endif /* __ASM_ARCH_REGS_ADC_H */
+
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-fb.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-fb.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-fb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-fb.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,366 @@
+/* arch/arm/plat-samsung/include/plat/regs-fb.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      http://armlinux.simtec.co.uk/
+ *      Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - new-style framebuffer register definitions
+ *
+ * This is the register set for the new style framebuffer interface
+ * found from the S3C2443 onwards into the S3C2416, S3C2450 and the
+ * S3C64XX series such as the S3C6400 and S3C6410.
+ *
+ * The file does not contain the cpu specific items which are based on
+ * whichever architecture is selected, it only contains the core of the
+ * register set. See <mach/regs-fb.h> to get the specifics.
+ *
+ * Note, we changed to using regs-fb.h as it avoids any clashes with
+ * the original regs-lcd.h so out of the way of regs-lcd.h as well as
+ * indicating the newer block is much more than just an LCD interface.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Please do not include this file directly, use <mach/regs-fb.h> to
+ * ensure all the localised SoC support is included as necessary.
+*/
+
+/* VIDCON0 */
+
+#define VIDCON0					(0x00)
+#define VIDCON0_INTERLACE			(1 << 29)
+#define VIDCON0_VIDOUT_MASK			(0x3 << 26)
+#define VIDCON0_VIDOUT_SHIFT			(26)
+#define VIDCON0_VIDOUT_RGB			(0x0 << 26)
+#define VIDCON0_VIDOUT_TV			(0x1 << 26)
+#define VIDCON0_VIDOUT_I80_LDI0			(0x2 << 26)
+#define VIDCON0_VIDOUT_I80_LDI1			(0x3 << 26)
+
+#define VIDCON0_L1_DATA_MASK			(0x7 << 23)
+#define VIDCON0_L1_DATA_SHIFT			(23)
+#define VIDCON0_L1_DATA_16BPP			(0x0 << 23)
+#define VIDCON0_L1_DATA_18BPP16			(0x1 << 23)
+#define VIDCON0_L1_DATA_18BPP9			(0x2 << 23)
+#define VIDCON0_L1_DATA_24BPP			(0x3 << 23)
+#define VIDCON0_L1_DATA_18BPP			(0x4 << 23)
+#define VIDCON0_L1_DATA_16BPP8			(0x5 << 23)
+
+#define VIDCON0_L0_DATA_MASK			(0x7 << 20)
+#define VIDCON0_L0_DATA_SHIFT			(20)
+#define VIDCON0_L0_DATA_16BPP			(0x0 << 20)
+#define VIDCON0_L0_DATA_18BPP16			(0x1 << 20)
+#define VIDCON0_L0_DATA_18BPP9			(0x2 << 20)
+#define VIDCON0_L0_DATA_24BPP			(0x3 << 20)
+#define VIDCON0_L0_DATA_18BPP			(0x4 << 20)
+#define VIDCON0_L0_DATA_16BPP8			(0x5 << 20)
+
+#define VIDCON0_PNRMODE_MASK			(0x3 << 17)
+#define VIDCON0_PNRMODE_SHIFT			(17)
+#define VIDCON0_PNRMODE_RGB			(0x0 << 17)
+#define VIDCON0_PNRMODE_BGR			(0x1 << 17)
+#define VIDCON0_PNRMODE_SERIAL_RGB		(0x2 << 17)
+#define VIDCON0_PNRMODE_SERIAL_BGR		(0x3 << 17)
+
+#define VIDCON0_CLKVALUP			(1 << 16)
+#define VIDCON0_CLKVAL_F_MASK			(0xff << 6)
+#define VIDCON0_CLKVAL_F_SHIFT			(6)
+#define VIDCON0_CLKVAL_F_LIMIT			(0xff)
+#define VIDCON0_CLKVAL_F(_x)			((_x) << 6)
+#define VIDCON0_VLCKFREE			(1 << 5)
+#define VIDCON0_CLKDIR				(1 << 4)
+
+#define VIDCON0_CLKSEL_MASK			(0x3 << 2)
+#define VIDCON0_CLKSEL_SHIFT			(2)
+#define VIDCON0_CLKSEL_HCLK			(0x0 << 2)
+#define VIDCON0_CLKSEL_LCD			(0x1 << 2)
+#define VIDCON0_CLKSEL_27M			(0x3 << 2)
+
+#define VIDCON0_ENVID				(1 << 1)
+#define VIDCON0_ENVID_F				(1 << 0)
+
+#define VIDCON1					(0x04)
+#define VIDCON1_LINECNT_MASK			(0x7ff << 16)
+#define VIDCON1_LINECNT_SHIFT			(16)
+#define VIDCON1_LINECNT_GET(_v)			(((_v) >> 16) & 0x7ff)
+#define VIDCON1_VSTATUS_MASK			(0x3 << 13)
+#define VIDCON1_VSTATUS_SHIFT			(13)
+#define VIDCON1_VSTATUS_VSYNC			(0x0 << 13)
+#define VIDCON1_VSTATUS_BACKPORCH		(0x1 << 13)
+#define VIDCON1_VSTATUS_ACTIVE			(0x2 << 13)
+#define VIDCON1_VSTATUS_FRONTPORCH		(0x0 << 13)
+
+#define VIDCON1_INV_VCLK			(1 << 7)
+#define VIDCON1_INV_HSYNC			(1 << 6)
+#define VIDCON1_INV_VSYNC			(1 << 5)
+#define VIDCON1_INV_VDEN			(1 << 4)
+
+/* VIDCON2 */
+
+#define VIDCON2					(0x08)
+#define VIDCON2_EN601				(1 << 23)
+#define VIDCON2_TVFMTSEL_SW			(1 << 14)
+
+#define VIDCON2_TVFMTSEL1_MASK			(0x3 << 12)
+#define VIDCON2_TVFMTSEL1_SHIFT			(12)
+#define VIDCON2_TVFMTSEL1_RGB			(0x0 << 12)
+#define VIDCON2_TVFMTSEL1_YUV422		(0x1 << 12)
+#define VIDCON2_TVFMTSEL1_YUV444		(0x2 << 12)
+
+#define VIDCON2_ORGYCbCr			(1 << 8)
+#define VIDCON2_YUVORDCrCb			(1 << 7)
+
+/* VIDTCON0 */
+
+#define VIDTCON0_VBPDE_MASK			(0xff << 24)
+#define VIDTCON0_VBPDE_SHIFT			(24)
+#define VIDTCON0_VBPDE_LIMIT			(0xff)
+#define VIDTCON0_VBPDE(_x)			((_x) << 24)
+
+#define VIDTCON0_VBPD_MASK			(0xff << 16)
+#define VIDTCON0_VBPD_SHIFT			(16)
+#define VIDTCON0_VBPD_LIMIT			(0xff)
+#define VIDTCON0_VBPD(_x)			((_x) << 16)
+
+#define VIDTCON0_VFPD_MASK			(0xff << 8)
+#define VIDTCON0_VFPD_SHIFT			(8)
+#define VIDTCON0_VFPD_LIMIT			(0xff)
+#define VIDTCON0_VFPD(_x)			((_x) << 8)
+
+#define VIDTCON0_VSPW_MASK			(0xff << 0)
+#define VIDTCON0_VSPW_SHIFT			(0)
+#define VIDTCON0_VSPW_LIMIT			(0xff)
+#define VIDTCON0_VSPW(_x)			((_x) << 0)
+
+/* VIDTCON1 */
+
+#define VIDTCON1_VFPDE_MASK			(0xff << 24)
+#define VIDTCON1_VFPDE_SHIFT			(24)
+#define VIDTCON1_VFPDE_LIMIT			(0xff)
+#define VIDTCON1_VFPDE(_x)			((_x) << 24)
+
+#define VIDTCON1_HBPD_MASK			(0xff << 16)
+#define VIDTCON1_HBPD_SHIFT			(16)
+#define VIDTCON1_HBPD_LIMIT			(0xff)
+#define VIDTCON1_HBPD(_x)			((_x) << 16)
+
+#define VIDTCON1_HFPD_MASK			(0xff << 8)
+#define VIDTCON1_HFPD_SHIFT			(8)
+#define VIDTCON1_HFPD_LIMIT			(0xff)
+#define VIDTCON1_HFPD(_x)			((_x) << 8)
+
+#define VIDTCON1_HSPW_MASK			(0xff << 0)
+#define VIDTCON1_HSPW_SHIFT			(0)
+#define VIDTCON1_HSPW_LIMIT			(0xff)
+#define VIDTCON1_HSPW(_x)			((_x) << 0)
+
+#define VIDTCON2				(0x18)
+#define VIDTCON2_LINEVAL_MASK			(0x7ff << 11)
+#define VIDTCON2_LINEVAL_SHIFT			(11)
+#define VIDTCON2_LINEVAL_LIMIT			(0x7ff)
+#define VIDTCON2_LINEVAL(_x)			((_x) << 11)
+
+#define VIDTCON2_HOZVAL_MASK			(0x7ff << 0)
+#define VIDTCON2_HOZVAL_SHIFT			(0)
+#define VIDTCON2_HOZVAL_LIMIT			(0x7ff)
+#define VIDTCON2_HOZVAL(_x)			((_x) << 0)
+
+/* WINCONx */
+
+
+#define WINCONx_BITSWP				(1 << 18)
+#define WINCONx_BYTSWP				(1 << 17)
+#define WINCONx_HAWSWP				(1 << 16)
+#define WINCONx_BURSTLEN_MASK			(0x3 << 9)
+#define WINCONx_BURSTLEN_SHIFT			(9)
+#define WINCONx_BURSTLEN_16WORD			(0x0 << 9)
+#define WINCONx_BURSTLEN_8WORD			(0x1 << 9)
+#define WINCONx_BURSTLEN_4WORD			(0x2 << 9)
+
+#define WINCONx_ENWIN				(1 << 0)
+#define WINCON0_BPPMODE_MASK			(0xf << 2)
+#define WINCON0_BPPMODE_SHIFT			(2)
+#define WINCON0_BPPMODE_1BPP			(0x0 << 2)
+#define WINCON0_BPPMODE_2BPP			(0x1 << 2)
+#define WINCON0_BPPMODE_4BPP			(0x2 << 2)
+#define WINCON0_BPPMODE_8BPP_PALETTE		(0x3 << 2)
+#define WINCON0_BPPMODE_16BPP_565		(0x5 << 2)
+#define WINCON0_BPPMODE_16BPP_1555		(0x7 << 2)
+#define WINCON0_BPPMODE_18BPP_666		(0x8 << 2)
+#define WINCON0_BPPMODE_24BPP_888		(0xb << 2)
+
+#define WINCON1_BLD_PIX				(1 << 6)
+
+#define WINCON1_ALPHA_SEL			(1 << 1)
+#define WINCON1_BPPMODE_MASK			(0xf << 2)
+#define WINCON1_BPPMODE_SHIFT			(2)
+#define WINCON1_BPPMODE_1BPP			(0x0 << 2)
+#define WINCON1_BPPMODE_2BPP			(0x1 << 2)
+#define WINCON1_BPPMODE_4BPP			(0x2 << 2)
+#define WINCON1_BPPMODE_8BPP_PALETTE		(0x3 << 2)
+#define WINCON1_BPPMODE_8BPP_1232		(0x4 << 2)
+#define WINCON1_BPPMODE_16BPP_565		(0x5 << 2)
+#define WINCON1_BPPMODE_16BPP_A1555		(0x6 << 2)
+#define WINCON1_BPPMODE_16BPP_I1555		(0x7 << 2)
+#define WINCON1_BPPMODE_18BPP_666		(0x8 << 2)
+#define WINCON1_BPPMODE_18BPP_A1665		(0x9 << 2)
+#define WINCON1_BPPMODE_19BPP_A1666		(0xa << 2)
+#define WINCON1_BPPMODE_24BPP_888		(0xb << 2)
+#define WINCON1_BPPMODE_24BPP_A1887		(0xc << 2)
+#define WINCON1_BPPMODE_25BPP_A1888		(0xd << 2)
+#define WINCON1_BPPMODE_28BPP_A4888		(0xd << 2)
+
+
+#define VIDOSDxA_TOPLEFT_X_MASK			(0x7ff << 11)
+#define VIDOSDxA_TOPLEFT_X_SHIFT		(11)
+#define VIDOSDxA_TOPLEFT_X_LIMIT		(0x7ff)
+#define VIDOSDxA_TOPLEFT_X(_x)			((_x) << 11)
+
+#define VIDOSDxA_TOPLEFT_Y_MASK			(0x7ff << 0)
+#define VIDOSDxA_TOPLEFT_Y_SHIFT		(0)
+#define VIDOSDxA_TOPLEFT_Y_LIMIT		(0x7ff)
+#define VIDOSDxA_TOPLEFT_Y(_x)			((_x) << 0)
+
+#define VIDOSDxB_BOTRIGHT_X_MASK		(0x7ff << 11)
+#define VIDOSDxB_BOTRIGHT_X_SHIFT		(11)
+#define VIDOSDxB_BOTRIGHT_X_LIMIT		(0x7ff)
+#define VIDOSDxB_BOTRIGHT_X(_x)			((_x) << 11)
+
+#define VIDOSDxB_BOTRIGHT_Y_MASK		(0x7ff << 0)
+#define VIDOSDxB_BOTRIGHT_Y_SHIFT		(0)
+#define VIDOSDxB_BOTRIGHT_Y_LIMIT		(0x7ff)
+#define VIDOSDxB_BOTRIGHT_Y(_x)			((_x) << 0)
+
+/* For VIDOSD[1..4]C */
+#define VIDISD14C_ALPHA0_R(_x)			((_x) << 20)
+#define VIDISD14C_ALPHA0_G_MASK			(0xf << 16)
+#define VIDISD14C_ALPHA0_G_SHIFT		(16)
+#define VIDISD14C_ALPHA0_G_LIMIT		(0xf)
+#define VIDISD14C_ALPHA0_G(_x)			((_x) << 16)
+#define VIDISD14C_ALPHA0_B_MASK			(0xf << 12)
+#define VIDISD14C_ALPHA0_B_SHIFT		(12)
+#define VIDISD14C_ALPHA0_B_LIMIT		(0xf)
+#define VIDISD14C_ALPHA0_B(_x)			((_x) << 12)
+#define VIDISD14C_ALPHA1_R_MASK			(0xf << 8)
+#define VIDISD14C_ALPHA1_R_SHIFT		(8)
+#define VIDISD14C_ALPHA1_R_LIMIT		(0xf)
+#define VIDISD14C_ALPHA1_R(_x)			((_x) << 8)
+#define VIDISD14C_ALPHA1_G_MASK			(0xf << 4)
+#define VIDISD14C_ALPHA1_G_SHIFT		(4)
+#define VIDISD14C_ALPHA1_G_LIMIT		(0xf)
+#define VIDISD14C_ALPHA1_G(_x)			((_x) << 4)
+#define VIDISD14C_ALPHA1_B_MASK			(0xf << 0)
+#define VIDISD14C_ALPHA1_B_SHIFT		(0)
+#define VIDISD14C_ALPHA1_B_LIMIT		(0xf)
+#define VIDISD14C_ALPHA1_B(_x)			((_x) << 0)
+
+/* Video buffer addresses */
+#define VIDW_BUF_START(_buff)			(0xA0 + ((_buff) * 8))
+#define VIDW_BUF_START1(_buff)			(0xA4 + ((_buff) * 8))
+#define VIDW_BUF_END(_buff)			(0xD0 + ((_buff) * 8))
+#define VIDW_BUF_END1(_buff)			(0xD4 + ((_buff) * 8))
+#define VIDW_BUF_SIZE(_buff)			(0x100 + ((_buff) * 4))
+
+#define VIDW_BUF_SIZE_OFFSET_MASK		(0x1fff << 13)
+#define VIDW_BUF_SIZE_OFFSET_SHIFT		(13)
+#define VIDW_BUF_SIZE_OFFSET_LIMIT		(0x1fff)
+#define VIDW_BUF_SIZE_OFFSET(_x)		((_x) << 13)
+
+#define VIDW_BUF_SIZE_PAGEWIDTH_MASK		(0x1fff << 0)
+#define VIDW_BUF_SIZE_PAGEWIDTH_SHIFT		(0)
+#define VIDW_BUF_SIZE_PAGEWIDTH_LIMIT		(0x1fff)
+#define VIDW_BUF_SIZE_PAGEWIDTH(_x)		((_x) << 0)
+
+/* Interrupt controls and status */
+
+#define VIDINTCON0_FIFOINTERVAL_MASK		(0x3f << 20)
+#define VIDINTCON0_FIFOINTERVAL_SHIFT		(20)
+#define VIDINTCON0_FIFOINTERVAL_LIMIT		(0x3f)
+#define VIDINTCON0_FIFOINTERVAL(_x)		((_x) << 20)
+
+#define VIDINTCON0_INT_SYSMAINCON		(1 << 19)
+#define VIDINTCON0_INT_SYSSUBCON		(1 << 18)
+#define VIDINTCON0_INT_I80IFDONE		(1 << 17)
+
+#define VIDINTCON0_FRAMESEL0_MASK		(0x3 << 15)
+#define VIDINTCON0_FRAMESEL0_SHIFT		(15)
+#define VIDINTCON0_FRAMESEL0_BACKPORCH		(0x0 << 15)
+#define VIDINTCON0_FRAMESEL0_VSYNC		(0x1 << 15)
+#define VIDINTCON0_FRAMESEL0_ACTIVE		(0x2 << 15)
+#define VIDINTCON0_FRAMESEL0_FRONTPORCH		(0x3 << 15)
+
+#define VIDINTCON0_FRAMESEL1			(1 << 14)
+#define VIDINTCON0_FRAMESEL1_NONE		(0x0 << 14)
+#define VIDINTCON0_FRAMESEL1_BACKPORCH		(0x1 << 14)
+#define VIDINTCON0_FRAMESEL1_VSYNC		(0x2 << 14)
+#define VIDINTCON0_FRAMESEL1_FRONTPORCH		(0x3 << 14)
+
+#define VIDINTCON0_INT_FRAME			(1 << 12)
+#define VIDINTCON0_FIFIOSEL_MASK		(0x7f << 5)
+#define VIDINTCON0_FIFIOSEL_SHIFT		(5)
+#define VIDINTCON0_FIFIOSEL_WINDOW0		(0x1 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW1		(0x2 << 5)
+
+#define VIDINTCON0_FIFOLEVEL_MASK		(0x7 << 2)
+#define VIDINTCON0_FIFOLEVEL_SHIFT		(2)
+#define VIDINTCON0_FIFOLEVEL_TO25PC		(0x0 << 2)
+#define VIDINTCON0_FIFOLEVEL_TO50PC		(0x1 << 2)
+#define VIDINTCON0_FIFOLEVEL_TO75PC		(0x2 << 2)
+#define VIDINTCON0_FIFOLEVEL_EMPTY		(0x3 << 2)
+#define VIDINTCON0_FIFOLEVEL_FULL		(0x4 << 2)
+
+#define VIDINTCON0_INT_FIFO_MASK		(0x3 << 0)
+#define VIDINTCON0_INT_FIFO_SHIFT		(0)
+#define VIDINTCON0_INT_ENABLE			(1 << 0)
+
+#define VIDINTCON1				(0x134)
+#define VIDINTCON1_INT_I180			(1 << 2)
+#define VIDINTCON1_INT_FRAME			(1 << 1)
+#define VIDINTCON1_INT_FIFO			(1 << 0)
+
+/* Window colour-key control registers */
+
+#define WxKEYCON0_KEYBL_EN			(1 << 26)
+#define WxKEYCON0_KEYEN_F			(1 << 25)
+#define WxKEYCON0_DIRCON			(1 << 24)
+#define WxKEYCON0_COMPKEY_MASK			(0xffffff << 0)
+#define WxKEYCON0_COMPKEY_SHIFT			(0)
+#define WxKEYCON0_COMPKEY_LIMIT			(0xffffff)
+#define WxKEYCON0_COMPKEY(_x)			((_x) << 0)
+#define WxKEYCON1_COLVAL_MASK			(0xffffff << 0)
+#define WxKEYCON1_COLVAL_SHIFT			(0)
+#define WxKEYCON1_COLVAL_LIMIT			(0xffffff)
+#define WxKEYCON1_COLVAL(_x)			((_x) << 0)
+
+
+/* Window blanking (MAP) */
+
+#define WINxMAP_MAP				(1 << 24)
+#define WINxMAP_MAP_COLOUR_MASK			(0xffffff << 0)
+#define WINxMAP_MAP_COLOUR_SHIFT		(0)
+#define WINxMAP_MAP_COLOUR_LIMIT		(0xffffff)
+#define WINxMAP_MAP_COLOUR(_x)			((_x) << 0)
+
+#define WPALCON_PAL_UPDATE			(1 << 9)
+#define WPALCON_W1PAL_MASK			(0x7 << 3)
+#define WPALCON_W1PAL_SHIFT			(3)
+#define WPALCON_W1PAL_25BPP_A888		(0x0 << 3)
+#define WPALCON_W1PAL_24BPP			(0x1 << 3)
+#define WPALCON_W1PAL_19BPP_A666		(0x2 << 3)
+#define WPALCON_W1PAL_18BPP_A665		(0x3 << 3)
+#define WPALCON_W1PAL_18BPP			(0x4 << 3)
+#define WPALCON_W1PAL_16BPP_A555		(0x5 << 3)
+#define WPALCON_W1PAL_16BPP_565			(0x6 << 3)
+
+#define WPALCON_W0PAL_MASK			(0x7 << 0)
+#define WPALCON_W0PAL_SHIFT			(0)
+#define WPALCON_W0PAL_25BPP_A888		(0x0 << 0)
+#define WPALCON_W0PAL_24BPP			(0x1 << 0)
+#define WPALCON_W0PAL_19BPP_A666		(0x2 << 0)
+#define WPALCON_W0PAL_18BPP_A665		(0x3 << 0)
+#define WPALCON_W0PAL_18BPP			(0x4 << 0)
+#define WPALCON_W0PAL_16BPP_A555		(0x5 << 0)
+#define WPALCON_W0PAL_16BPP_565			(0x6 << 0)
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-fb-v4.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-fb-v4.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-fb-v4.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,235 @@
+/* arch/arm/plat-samsung/include/plat/regs-fb-v4.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      http://armlinux.simtec.co.uk/
+ *      Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - new-style framebuffer register definitions
+ *
+ * This is the register set for the new style framebuffer interface
+ * found from the S3C2443 onwards and specifically the S3C64XX series
+ * S3C6400 and S3C6410.
+ *
+ * The file contains the cpu specific items which change between whichever
+ * architecture is selected. See <plat/regs-fb.h> for the core definitions
+ * that are the same.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* include the core definitions here, in case we really do need to
+ * override them at a later date.
+*/
+
+#include <plat/regs-fb.h>
+
+#define S3C_FB_MAX_WIN (5)  /* number of hardware windows available. */
+#define VIDCON1_FSTATUS_EVEN	(1 << 15)
+
+/* Video timing controls */
+#define VIDTCON0				(0x10)
+#define VIDTCON1				(0x14)
+#define VIDTCON2				(0x18)
+
+/* Window position controls */
+
+#define WINCON(_win)				(0x20 + ((_win) * 4))
+
+/* OSD1 and OSD4 do not have register D */
+
+#define VIDOSD_A(_win)				(0x40 + ((_win) * 16))
+#define VIDOSD_B(_win)				(0x44 + ((_win) * 16))
+#define VIDOSD_C(_win)				(0x48 + ((_win) * 16))
+#define VIDOSD_D(_win)				(0x4C + ((_win) * 16))
+
+
+#define VIDINTCON0				(0x130)
+
+#define WxKEYCONy(_win, _con)			((0x140 + ((_win) * 8)) + ((_con) * 4))
+
+/* WINCONx */
+
+#define WINCONx_CSCWIDTH_MASK			(0x3 << 26)
+#define WINCONx_CSCWIDTH_SHIFT			(26)
+#define WINCONx_CSCWIDTH_WIDE			(0x0 << 26)
+#define WINCONx_CSCWIDTH_NARROW			(0x3 << 26)
+
+#define WINCONx_ENLOCAL				(1 << 22)
+#define WINCONx_BUFSTATUS			(1 << 21)
+#define WINCONx_BUFSEL				(1 << 20)
+#define WINCONx_BUFAUTOEN			(1 << 19)
+#define WINCONx_YCbCr				(1 << 13)
+
+#define WINCON1_LOCALSEL_CAMIF			(1 << 23)
+
+#define WINCON2_LOCALSEL_CAMIF			(1 << 23)
+#define WINCON2_BLD_PIX				(1 << 6)
+
+#define WINCON2_ALPHA_SEL			(1 << 1)
+#define WINCON2_BPPMODE_MASK			(0xf << 2)
+#define WINCON2_BPPMODE_SHIFT			(2)
+#define WINCON2_BPPMODE_1BPP			(0x0 << 2)
+#define WINCON2_BPPMODE_2BPP			(0x1 << 2)
+#define WINCON2_BPPMODE_4BPP			(0x2 << 2)
+#define WINCON2_BPPMODE_8BPP_1232		(0x4 << 2)
+#define WINCON2_BPPMODE_16BPP_565		(0x5 << 2)
+#define WINCON2_BPPMODE_16BPP_A1555		(0x6 << 2)
+#define WINCON2_BPPMODE_16BPP_I1555		(0x7 << 2)
+#define WINCON2_BPPMODE_18BPP_666		(0x8 << 2)
+#define WINCON2_BPPMODE_18BPP_A1665		(0x9 << 2)
+#define WINCON2_BPPMODE_19BPP_A1666		(0xa << 2)
+#define WINCON2_BPPMODE_24BPP_888		(0xb << 2)
+#define WINCON2_BPPMODE_24BPP_A1887		(0xc << 2)
+#define WINCON2_BPPMODE_25BPP_A1888		(0xd << 2)
+#define WINCON2_BPPMODE_28BPP_A4888		(0xd << 2)
+
+#define WINCON3_BLD_PIX				(1 << 6)
+
+#define WINCON3_ALPHA_SEL			(1 << 1)
+#define WINCON3_BPPMODE_MASK			(0xf << 2)
+#define WINCON3_BPPMODE_SHIFT			(2)
+#define WINCON3_BPPMODE_1BPP			(0x0 << 2)
+#define WINCON3_BPPMODE_2BPP			(0x1 << 2)
+#define WINCON3_BPPMODE_4BPP			(0x2 << 2)
+#define WINCON3_BPPMODE_16BPP_565		(0x5 << 2)
+#define WINCON3_BPPMODE_16BPP_A1555		(0x6 << 2)
+#define WINCON3_BPPMODE_16BPP_I1555		(0x7 << 2)
+#define WINCON3_BPPMODE_18BPP_666		(0x8 << 2)
+#define WINCON3_BPPMODE_18BPP_A1665		(0x9 << 2)
+#define WINCON3_BPPMODE_19BPP_A1666		(0xa << 2)
+#define WINCON3_BPPMODE_24BPP_888		(0xb << 2)
+#define WINCON3_BPPMODE_24BPP_A1887		(0xc << 2)
+#define WINCON3_BPPMODE_25BPP_A1888		(0xd << 2)
+#define WINCON3_BPPMODE_28BPP_A4888		(0xd << 2)
+
+#define VIDINTCON0_FIFIOSEL_WINDOW2		(0x10 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW3		(0x20 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW4		(0x40 << 5)
+
+#define DITHMODE				(0x170)
+#define WINxMAP(_win)				(0x180 + ((_win) * 4))
+
+
+#define DITHMODE_R_POS_MASK			(0x3 << 5)
+#define DITHMODE_R_POS_SHIFT			(5)
+#define DITHMODE_R_POS_8BIT			(0x0 << 5)
+#define DITHMODE_R_POS_6BIT			(0x1 << 5)
+#define DITHMODE_R_POS_5BIT			(0x2 << 5)
+
+#define DITHMODE_G_POS_MASK			(0x3 << 3)
+#define DITHMODE_G_POS_SHIFT			(3)
+#define DITHMODE_G_POS_8BIT			(0x0 << 3)
+#define DITHMODE_G_POS_6BIT			(0x1 << 3)
+#define DITHMODE_G_POS_5BIT			(0x2 << 3)
+
+#define DITHMODE_B_POS_MASK			(0x3 << 1)
+#define DITHMODE_B_POS_SHIFT			(1)
+#define DITHMODE_B_POS_8BIT			(0x0 << 1)
+#define DITHMODE_B_POS_6BIT			(0x1 << 1)
+#define DITHMODE_B_POS_5BIT			(0x2 << 1)
+
+#define DITHMODE_DITH_EN			(1 << 0)
+
+#define WPALCON					(0x1A0)
+
+/* Palette control */
+/* Note for S5PC100: you can still use those macros on WPALCON (aka WPALCON_L),
+ * but make sure that WPALCON_H W2PAL-W4PAL entries are zeroed out */
+#define WPALCON_W4PAL_16BPP_A555		(1 << 8)
+#define WPALCON_W3PAL_16BPP_A555		(1 << 7)
+#define WPALCON_W2PAL_16BPP_A555		(1 << 6)
+
+
+/* system specific implementation code for palette sizes, and other
+ * information that changes depending on which architecture is being
+ * compiled.
+*/
+
+/* return true if window _win has OSD register D */
+#define s3c_fb_has_osd_d(_win) ((_win) != 4 && (_win) != 0)
+
+static inline unsigned int s3c_fb_win_pal_size(unsigned int win)
+{
+	if (win < 2)
+		return 256;
+	if (win < 4)
+		return 16;
+	if (win == 4)
+		return 4;
+
+	BUG();	/* shouldn't get here */
+}
+
+static inline int s3c_fb_validate_win_bpp(unsigned int win, unsigned int bpp)
+{
+	/* all windows can do 1/2 bpp */
+
+	if ((bpp == 25 || bpp == 19) && win == 0)
+		return 0;	/* win 0 does not have 19 or 25bpp modes */
+
+	if (bpp == 4 && win == 4)
+		return 0;
+
+	if (bpp == 8 && (win >= 3))
+		return 0;	/* win 3/4 cannot do 8bpp in any mode */
+
+	return 1;
+}
+
+static inline int s3c_fb_pal_is16(unsigned int window)
+{
+	return window > 1;
+}
+
+struct s3c_fb_palette {
+	struct fb_bitfield	r;
+	struct fb_bitfield	g;
+	struct fb_bitfield	b;
+	struct fb_bitfield	a;
+};
+
+static inline void s3c_fb_init_palette(unsigned int window,
+				       struct s3c_fb_palette *palette)
+{
+	if (window < 2) {
+		/* Windows 0/1 are 8/8/8 or A/8/8/8 */
+		palette->r.offset = 16;
+		palette->r.length = 8;
+		palette->g.offset = 8;
+		palette->g.length = 8;
+		palette->b.offset = 0;
+		palette->b.length = 8;
+	} else {
+		/* currently we assume RGB 5/6/5 */
+		palette->r.offset = 11;
+		palette->r.length = 5;
+		palette->g.offset = 5;
+		palette->g.length = 6;
+		palette->b.offset = 0;
+		palette->b.length = 5;
+	}
+}
+
+/* Notes on per-window bpp settings
+ *
+ * Value	Win0	 Win1	  Win2	   Win3	    Win 4
+ * 0000		1(P)	 1(P)	  1(P)	   1(P)	    1(P)
+ * 0001		2(P)	 2(P)     2(P)	   2(P)	    2(P)
+ * 0010		4(P)	 4(P)     4(P)	   4(P)     -none-
+ * 0011		8(P)	 8(P)     -none-   -none-   -none-
+ * 0100		-none-	 8(A232)  8(A232)  -none-   -none-
+ * 0101		16(565)	 16(565)  16(565)  16(565)   16(565)
+ * 0110		-none-	 16(A555) 16(A555) 16(A555)  16(A555)
+ * 0111		16(I555) 16(I565) 16(I555) 16(I555)  16(I555)
+ * 1000		18(666)	 18(666)  18(666)  18(666)   18(666)
+ * 1001		-none-	 18(A665) 18(A665) 18(A665)  16(A665)
+ * 1010		-none-	 19(A666) 19(A666) 19(A666)  19(A666)
+ * 1011		24(888)	 24(888)  24(888)  24(888)   24(888)
+ * 1100		-none-	 24(A887) 24(A887) 24(A887)  24(A887)
+ * 1101		-none-	 25(A888) 25(A888) 25(A888)  25(A888)
+ * 1110		-none-	 -none-	  -none-   -none-    -none-
+ * 1111		-none-	 -none-   -none-   -none-    -none-
+*/
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-iic.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-iic.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-iic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-iic.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,56 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-iic.h
+ *
+ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ *		http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 I2C Controller
+*/
+
+#ifndef __ASM_ARCH_REGS_IIC_H
+#define __ASM_ARCH_REGS_IIC_H __FILE__
+
+/* see s3c2410x user guide, v1.1, section 9 (p447) for more info */
+
+#define S3C2410_IICREG(x) (x)
+
+#define S3C2410_IICCON    S3C2410_IICREG(0x00)
+#define S3C2410_IICSTAT   S3C2410_IICREG(0x04)
+#define S3C2410_IICADD    S3C2410_IICREG(0x08)
+#define S3C2410_IICDS     S3C2410_IICREG(0x0C)
+#define S3C2440_IICLC	  S3C2410_IICREG(0x10)
+
+#define S3C2410_IICCON_ACKEN		(1<<7)
+#define S3C2410_IICCON_TXDIV_16		(0<<6)
+#define S3C2410_IICCON_TXDIV_512	(1<<6)
+#define S3C2410_IICCON_IRQEN		(1<<5)
+#define S3C2410_IICCON_IRQPEND		(1<<4)
+#define S3C2410_IICCON_SCALE(x)		((x)&15)
+#define S3C2410_IICCON_SCALEMASK	(0xf)
+
+#define S3C2410_IICSTAT_MASTER_RX	(2<<6)
+#define S3C2410_IICSTAT_MASTER_TX	(3<<6)
+#define S3C2410_IICSTAT_SLAVE_RX	(0<<6)
+#define S3C2410_IICSTAT_SLAVE_TX	(1<<6)
+#define S3C2410_IICSTAT_MODEMASK	(3<<6)
+
+#define S3C2410_IICSTAT_START		(1<<5)
+#define S3C2410_IICSTAT_BUSBUSY		(1<<5)
+#define S3C2410_IICSTAT_TXRXEN		(1<<4)
+#define S3C2410_IICSTAT_ARBITR		(1<<3)
+#define S3C2410_IICSTAT_ASSLAVE		(1<<2)
+#define S3C2410_IICSTAT_ADDR0		(1<<1)
+#define S3C2410_IICSTAT_LASTBIT		(1<<0)
+
+#define S3C2410_IICLC_SDA_DELAY0	(0 << 0)
+#define S3C2410_IICLC_SDA_DELAY5	(1 << 0)
+#define S3C2410_IICLC_SDA_DELAY10	(2 << 0)
+#define S3C2410_IICLC_SDA_DELAY15	(3 << 0)
+#define S3C2410_IICLC_SDA_DELAY_MASK	(3 << 0)
+
+#define S3C2410_IICLC_FILTER_ON		(1<<2)
+
+#endif /* __ASM_ARCH_REGS_IIC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-irqtype.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-irqtype.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-irqtype.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-irqtype.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,21 @@
+/* arch/arm/plat-s3c/include/plat/regs-irqtype.h
+ *
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C - IRQ detection types.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* values for S3C2410_EXTINT0/1/2 and other cpus in the series, including
+ * the S3C64XX
+*/
+#define S3C2410_EXTINT_LOWLEV	 (0x00)
+#define S3C2410_EXTINT_HILEV	 (0x01)
+#define S3C2410_EXTINT_FALLEDGE	 (0x02)
+#define S3C2410_EXTINT_RISEEDGE	 (0x04)
+#define S3C2410_EXTINT_BOTHEDGE	 (0x06)
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-nand.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-nand.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-nand.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-nand.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,123 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-nand.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics <linux@simtec.co.uk>
+ *	http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can 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 NAND register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_NAND
+#define __ASM_ARM_REGS_NAND
+
+
+#define S3C2410_NFREG(x) (x)
+
+#define S3C2410_NFCONF  S3C2410_NFREG(0x00)
+#define S3C2410_NFCMD   S3C2410_NFREG(0x04)
+#define S3C2410_NFADDR  S3C2410_NFREG(0x08)
+#define S3C2410_NFDATA  S3C2410_NFREG(0x0C)
+#define S3C2410_NFSTAT  S3C2410_NFREG(0x10)
+#define S3C2410_NFECC   S3C2410_NFREG(0x14)
+
+#define S3C2440_NFCONT   S3C2410_NFREG(0x04)
+#define S3C2440_NFCMD    S3C2410_NFREG(0x08)
+#define S3C2440_NFADDR   S3C2410_NFREG(0x0C)
+#define S3C2440_NFDATA   S3C2410_NFREG(0x10)
+#define S3C2440_NFECCD0  S3C2410_NFREG(0x14)
+#define S3C2440_NFECCD1  S3C2410_NFREG(0x18)
+#define S3C2440_NFECCD   S3C2410_NFREG(0x1C)
+#define S3C2440_NFSTAT   S3C2410_NFREG(0x20)
+#define S3C2440_NFESTAT0 S3C2410_NFREG(0x24)
+#define S3C2440_NFESTAT1 S3C2410_NFREG(0x28)
+#define S3C2440_NFMECC0  S3C2410_NFREG(0x2C)
+#define S3C2440_NFMECC1  S3C2410_NFREG(0x30)
+#define S3C2440_NFSECC   S3C2410_NFREG(0x34)
+#define S3C2440_NFSBLK   S3C2410_NFREG(0x38)
+#define S3C2440_NFEBLK   S3C2410_NFREG(0x3C)
+
+#define S3C2412_NFSBLK		S3C2410_NFREG(0x20)
+#define S3C2412_NFEBLK		S3C2410_NFREG(0x24)
+#define S3C2412_NFSTAT		S3C2410_NFREG(0x28)
+#define S3C2412_NFMECC_ERR0	S3C2410_NFREG(0x2C)
+#define S3C2412_NFMECC_ERR1	S3C2410_NFREG(0x30)
+#define S3C2412_NFMECC0		S3C2410_NFREG(0x34)
+#define S3C2412_NFMECC1		S3C2410_NFREG(0x38)
+#define S3C2412_NFSECC		S3C2410_NFREG(0x3C)
+
+#define S3C2410_NFCONF_EN          (1<<15)
+#define S3C2410_NFCONF_512BYTE     (1<<14)
+#define S3C2410_NFCONF_4STEP       (1<<13)
+#define S3C2410_NFCONF_INITECC     (1<<12)
+#define S3C2410_NFCONF_nFCE        (1<<11)
+#define S3C2410_NFCONF_TACLS(x)    ((x)<<8)
+#define S3C2410_NFCONF_TWRPH0(x)   ((x)<<4)
+#define S3C2410_NFCONF_TWRPH1(x)   ((x)<<0)
+
+#define S3C2410_NFSTAT_BUSY        (1<<0)
+
+#define S3C2440_NFCONF_BUSWIDTH_8	(0<<0)
+#define S3C2440_NFCONF_BUSWIDTH_16	(1<<0)
+#define S3C2440_NFCONF_ADVFLASH		(1<<3)
+#define S3C2440_NFCONF_TACLS(x)		((x)<<12)
+#define S3C2440_NFCONF_TWRPH0(x)	((x)<<8)
+#define S3C2440_NFCONF_TWRPH1(x)	((x)<<4)
+
+#define S3C2440_NFCONT_LOCKTIGHT	(1<<13)
+#define S3C2440_NFCONT_SOFTLOCK		(1<<12)
+#define S3C2440_NFCONT_ILLEGALACC_EN	(1<<10)
+#define S3C2440_NFCONT_RNBINT_EN	(1<<9)
+#define S3C2440_NFCONT_RN_FALLING	(1<<8)
+#define S3C2440_NFCONT_SPARE_ECCLOCK	(1<<6)
+#define S3C2440_NFCONT_MAIN_ECCLOCK	(1<<5)
+#define S3C2440_NFCONT_INITECC		(1<<4)
+#define S3C2440_NFCONT_nFCE		(1<<1)
+#define S3C2440_NFCONT_ENABLE		(1<<0)
+
+#define S3C2440_NFSTAT_READY		(1<<0)
+#define S3C2440_NFSTAT_nCE		(1<<1)
+#define S3C2440_NFSTAT_RnB_CHANGE	(1<<2)
+#define S3C2440_NFSTAT_ILLEGAL_ACCESS	(1<<3)
+
+#define S3C2412_NFCONF_NANDBOOT		(1<<31)
+#define S3C2412_NFCONF_ECCCLKCON	(1<<30)
+#define S3C2412_NFCONF_ECC_MLC		(1<<24)
+#define S3C2412_NFCONF_TACLS_MASK	(7<<12)	/* 1 extra bit of Tacls */
+
+#define S3C2412_NFCONT_ECC4_DIRWR	(1<<18)
+#define S3C2412_NFCONT_LOCKTIGHT	(1<<17)
+#define S3C2412_NFCONT_SOFTLOCK		(1<<16)
+#define S3C2412_NFCONT_ECC4_ENCINT	(1<<13)
+#define S3C2412_NFCONT_ECC4_DECINT	(1<<12)
+#define S3C2412_NFCONT_MAIN_ECC_LOCK	(1<<7)
+#define S3C2412_NFCONT_INIT_MAIN_ECC	(1<<5)
+#define S3C2412_NFCONT_nFCE1		(1<<2)
+#define S3C2412_NFCONT_nFCE0		(1<<1)
+
+#define S3C2412_NFSTAT_ECC_ENCDONE	(1<<7)
+#define S3C2412_NFSTAT_ECC_DECDONE	(1<<6)
+#define S3C2412_NFSTAT_ILLEGAL_ACCESS	(1<<5)
+#define S3C2412_NFSTAT_RnB_CHANGE	(1<<4)
+#define S3C2412_NFSTAT_nFCE1		(1<<3)
+#define S3C2412_NFSTAT_nFCE0		(1<<2)
+#define S3C2412_NFSTAT_Res1		(1<<1)
+#define S3C2412_NFSTAT_READY		(1<<0)
+
+#define S3C2412_NFECCERR_SERRDATA(x)	(((x) >> 21) & 0xf)
+#define S3C2412_NFECCERR_SERRBIT(x)	(((x) >> 18) & 0x7)
+#define S3C2412_NFECCERR_MERRDATA(x)	(((x) >> 7) & 0x3ff)
+#define S3C2412_NFECCERR_MERRBIT(x)	(((x) >> 4) & 0x7)
+#define S3C2412_NFECCERR_SPARE_ERR(x)	(((x) >> 2) & 0x3)
+#define S3C2412_NFECCERR_MAIN_ERR(x)	(((x) >> 2) & 0x3)
+#define S3C2412_NFECCERR_NONE		(0)
+#define S3C2412_NFECCERR_1BIT		(1)
+#define S3C2412_NFECCERR_MULTIBIT	(2)
+#define S3C2412_NFECCERR_ECCAREA	(3)
+
+
+
+#endif /* __ASM_ARM_REGS_NAND */
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-rtc.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-rtc.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-rtc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-rtc.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,61 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-rtc.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 Internal RTC register definition
+*/
+
+#ifndef __ASM_ARCH_REGS_RTC_H
+#define __ASM_ARCH_REGS_RTC_H __FILE__
+
+#define S3C2410_RTCREG(x) (x)
+
+#define S3C2410_RTCCON	      S3C2410_RTCREG(0x40)
+#define S3C2410_RTCCON_RTCEN  (1<<0)
+#define S3C2410_RTCCON_CLKSEL (1<<1)
+#define S3C2410_RTCCON_CNTSEL (1<<2)
+#define S3C2410_RTCCON_CLKRST (1<<3)
+
+#define S3C2410_TICNT	      S3C2410_RTCREG(0x44)
+#define S3C2410_TICNT_ENABLE  (1<<7)
+
+#define S3C2410_RTCALM	      S3C2410_RTCREG(0x50)
+#define S3C2410_RTCALM_ALMEN  (1<<6)
+#define S3C2410_RTCALM_YEAREN (1<<5)
+#define S3C2410_RTCALM_MONEN  (1<<4)
+#define S3C2410_RTCALM_DAYEN  (1<<3)
+#define S3C2410_RTCALM_HOUREN (1<<2)
+#define S3C2410_RTCALM_MINEN  (1<<1)
+#define S3C2410_RTCALM_SECEN  (1<<0)
+
+#define S3C2410_RTCALM_ALL \
+  S3C2410_RTCALM_ALMEN | S3C2410_RTCALM_YEAREN | S3C2410_RTCALM_MONEN |\
+  S3C2410_RTCALM_DAYEN | S3C2410_RTCALM_HOUREN | S3C2410_RTCALM_MINEN |\
+  S3C2410_RTCALM_SECEN
+
+
+#define S3C2410_ALMSEC	      S3C2410_RTCREG(0x54)
+#define S3C2410_ALMMIN	      S3C2410_RTCREG(0x58)
+#define S3C2410_ALMHOUR	      S3C2410_RTCREG(0x5c)
+
+#define S3C2410_ALMDATE	      S3C2410_RTCREG(0x60)
+#define S3C2410_ALMMON	      S3C2410_RTCREG(0x64)
+#define S3C2410_ALMYEAR	      S3C2410_RTCREG(0x68)
+
+#define S3C2410_RTCRST	      S3C2410_RTCREG(0x6c)
+
+#define S3C2410_RTCSEC	      S3C2410_RTCREG(0x70)
+#define S3C2410_RTCMIN	      S3C2410_RTCREG(0x74)
+#define S3C2410_RTCHOUR	      S3C2410_RTCREG(0x78)
+#define S3C2410_RTCDATE	      S3C2410_RTCREG(0x7c)
+#define S3C2410_RTCDAY	      S3C2410_RTCREG(0x80)
+#define S3C2410_RTCMON	      S3C2410_RTCREG(0x84)
+#define S3C2410_RTCYEAR	      S3C2410_RTCREG(0x88)
+
+
+#endif /* __ASM_ARCH_REGS_RTC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,82 @@
+/* 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_BLC_16BIT	(0 << 13)
+#define S3C64XX_IISMOD_BLC_8BIT		(1 << 13)
+#define S3C64XX_IISMOD_BLC_24BIT	(2 << 13)
+#define S3C64XX_IISMOD_BLC_MASK		(3 << 13)
+
+#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 S3C64XX_IISMOD_CDCLKCON		(1 << 12)
+
+#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.33-gnu1/arch/arm/plat-samsung/include/plat/regs-sdhci.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-sdhci.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-sdhci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-sdhci.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,87 @@
+/* linux/arch/arm/plat-s3c/include/plat/regs-sdhci.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - SDHCI (HSMMC) register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_S3C_SDHCI_REGS_H
+#define __PLAT_S3C_SDHCI_REGS_H __FILE__
+
+#define S3C_SDHCI_CONTROL2			(0x80)
+#define S3C_SDHCI_CONTROL3			(0x84)
+#define S3C64XX_SDHCI_CONTROL4			(0x8C)
+
+#define S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR	(1 << 31)
+#define S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK		(1 << 30)
+#define S3C_SDHCI_CTRL2_CDINVRXD3		(1 << 29)
+#define S3C_SDHCI_CTRL2_SLCARDOUT		(1 << 28)
+
+#define S3C_SDHCI_CTRL2_FLTCLKSEL_MASK		(0xf << 24)
+#define S3C_SDHCI_CTRL2_FLTCLKSEL_SHIFT		(24)
+#define S3C_SDHCI_CTRL2_FLTCLKSEL(_x)		((_x) << 24)
+
+#define S3C_SDHCI_CTRL2_LVLDAT_MASK		(0xff << 16)
+#define S3C_SDHCI_CTRL2_LVLDAT_SHIFT		(16)
+#define S3C_SDHCI_CTRL2_LVLDAT(_x)		((_x) << 16)
+
+#define S3C_SDHCI_CTRL2_ENFBCLKTX		(1 << 15)
+#define S3C_SDHCI_CTRL2_ENFBCLKRX		(1 << 14)
+#define S3C_SDHCI_CTRL2_SDCDSEL			(1 << 13)
+#define S3C_SDHCI_CTRL2_SDSIGPC			(1 << 12)
+#define S3C_SDHCI_CTRL2_ENBUSYCHKTXSTART	(1 << 11)
+
+#define S3C_SDHCI_CTRL2_DFCNT_MASK		(0x3 << 9)
+#define S3C_SDHCI_CTRL2_DFCNT_SHIFT		(9)
+#define S3C_SDHCI_CTRL2_DFCNT_NONE		(0x0 << 9)
+#define S3C_SDHCI_CTRL2_DFCNT_4SDCLK		(0x1 << 9)
+#define S3C_SDHCI_CTRL2_DFCNT_16SDCLK		(0x2 << 9)
+#define S3C_SDHCI_CTRL2_DFCNT_64SDCLK		(0x3 << 9)
+
+#define S3C_SDHCI_CTRL2_ENCLKOUTHOLD		(1 << 8)
+#define S3C_SDHCI_CTRL2_RWAITMODE		(1 << 7)
+#define S3C_SDHCI_CTRL2_DISBUFRD		(1 << 6)
+#define S3C_SDHCI_CTRL2_SELBASECLK_MASK		(0x3 << 4)
+#define S3C_SDHCI_CTRL2_SELBASECLK_SHIFT	(4)
+#define S3C_SDHCI_CTRL2_PWRSYNC			(1 << 3)
+#define S3C_SDHCI_CTRL2_ENCLKOUTMSKCON		(1 << 1)
+#define S3C_SDHCI_CTRL2_HWINITFIN		(1 << 0)
+
+#define S3C_SDHCI_CTRL3_FCSEL3			(1 << 31)
+#define S3C_SDHCI_CTRL3_FCSEL2			(1 << 23)
+#define S3C_SDHCI_CTRL3_FCSEL1			(1 << 15)
+#define S3C_SDHCI_CTRL3_FCSEL0			(1 << 7)
+
+#define S3C_SDHCI_CTRL3_FIA3_MASK		(0x7f << 24)
+#define S3C_SDHCI_CTRL3_FIA3_SHIFT		(24)
+#define S3C_SDHCI_CTRL3_FIA3(_x)		((_x) << 24)
+
+#define S3C_SDHCI_CTRL3_FIA2_MASK		(0x7f << 16)
+#define S3C_SDHCI_CTRL3_FIA2_SHIFT		(16)
+#define S3C_SDHCI_CTRL3_FIA2(_x)		((_x) << 16)
+
+#define S3C_SDHCI_CTRL3_FIA1_MASK		(0x7f << 8)
+#define S3C_SDHCI_CTRL3_FIA1_SHIFT		(8)
+#define S3C_SDHCI_CTRL3_FIA1(_x)		((_x) << 8)
+
+#define S3C_SDHCI_CTRL3_FIA0_MASK		(0x7f << 0)
+#define S3C_SDHCI_CTRL3_FIA0_SHIFT		(0)
+#define S3C_SDHCI_CTRL3_FIA0(_x)		((_x) << 0)
+
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_MASK	(0x3 << 16)
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_SHIFT	(16)
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_2mA	(0x0 << 16)
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_4mA	(0x1 << 16)
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_7mA	(0x2 << 16)
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_9mA	(0x3 << 16)
+
+#define S3C64XX_SDHCI_CONTROL4_BUSY		(1)
+
+#endif /* __PLAT_S3C_SDHCI_REGS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-serial.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-serial.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-serial.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-serial.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,281 @@
+/* arch/arm/plat-samsung/include/plat/regs-serial.h
+ *
+ *  From linux/include/asm-arm/hardware/serial_s3c2410.h
+ *
+ *  Internal header file for Samsung S3C2410 serial ports (UART0-2)
+ *
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *
+ *  Additional defines, Copyright 2003 Simtec Electronics (linux@simtec.co.uk)
+ *
+ *  Adapted from:
+ *
+ *  Internal header file for MX1ADS serial ports (UART1 & 2)
+ *
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __ASM_ARM_REGS_SERIAL_H
+#define __ASM_ARM_REGS_SERIAL_H
+
+#define S3C24XX_VA_UART0      (S3C_VA_UART)
+#define S3C24XX_VA_UART1      (S3C_VA_UART + 0x4000 )
+#define S3C24XX_VA_UART2      (S3C_VA_UART + 0x8000 )
+#define S3C24XX_VA_UART3      (S3C_VA_UART + 0xC000 )
+
+#define S3C2410_PA_UART0      (S3C24XX_PA_UART)
+#define S3C2410_PA_UART1      (S3C24XX_PA_UART + 0x4000 )
+#define S3C2410_PA_UART2      (S3C24XX_PA_UART + 0x8000 )
+#define S3C2443_PA_UART3      (S3C24XX_PA_UART + 0xC000 )
+
+#define S3C2410_URXH	  (0x24)
+#define S3C2410_UTXH	  (0x20)
+#define S3C2410_ULCON	  (0x00)
+#define S3C2410_UCON	  (0x04)
+#define S3C2410_UFCON	  (0x08)
+#define S3C2410_UMCON	  (0x0C)
+#define S3C2410_UBRDIV	  (0x28)
+#define S3C2410_UTRSTAT	  (0x10)
+#define S3C2410_UERSTAT	  (0x14)
+#define S3C2410_UFSTAT	  (0x18)
+#define S3C2410_UMSTAT	  (0x1C)
+
+#define S3C2410_LCON_CFGMASK	  ((0xF<<3)|(0x3))
+
+#define S3C2410_LCON_CS5	  (0x0)
+#define S3C2410_LCON_CS6	  (0x1)
+#define S3C2410_LCON_CS7	  (0x2)
+#define S3C2410_LCON_CS8	  (0x3)
+#define S3C2410_LCON_CSMASK	  (0x3)
+
+#define S3C2410_LCON_PNONE	  (0x0)
+#define S3C2410_LCON_PEVEN	  (0x5 << 3)
+#define S3C2410_LCON_PODD	  (0x4 << 3)
+#define S3C2410_LCON_PMASK	  (0x7 << 3)
+
+#define S3C2410_LCON_STOPB	  (1<<2)
+#define S3C2410_LCON_IRM          (1<<6)
+
+#define S3C2440_UCON_CLKMASK	  (3<<10)
+#define S3C2440_UCON_PCLK	  (0<<10)
+#define S3C2440_UCON_UCLK	  (1<<10)
+#define S3C2440_UCON_PCLK2	  (2<<10)
+#define S3C2440_UCON_FCLK	  (3<<10)
+#define S3C2443_UCON_EPLL	  (3<<10)
+
+#define S3C6400_UCON_CLKMASK	(3<<10)
+#define S3C6400_UCON_PCLK	(0<<10)
+#define S3C6400_UCON_PCLK2	(2<<10)
+#define S3C6400_UCON_UCLK0	(1<<10)
+#define S3C6400_UCON_UCLK1	(3<<10)
+
+#define S3C2440_UCON2_FCLK_EN	  (1<<15)
+#define S3C2440_UCON0_DIVMASK	  (15 << 12)
+#define S3C2440_UCON1_DIVMASK	  (15 << 12)
+#define S3C2440_UCON2_DIVMASK	  (7 << 12)
+#define S3C2440_UCON_DIVSHIFT	  (12)
+
+#define S3C2412_UCON_CLKMASK	(3<<10)
+#define S3C2412_UCON_UCLK	(1<<10)
+#define S3C2412_UCON_USYSCLK	(3<<10)
+#define S3C2412_UCON_PCLK	(0<<10)
+#define S3C2412_UCON_PCLK2	(2<<10)
+
+#define S3C2410_UCON_UCLK	  (1<<10)
+#define S3C2410_UCON_SBREAK	  (1<<4)
+
+#define S3C2410_UCON_TXILEVEL	  (1<<9)
+#define S3C2410_UCON_RXILEVEL	  (1<<8)
+#define S3C2410_UCON_TXIRQMODE	  (1<<2)
+#define S3C2410_UCON_RXIRQMODE	  (1<<0)
+#define S3C2410_UCON_RXFIFO_TOI	  (1<<7)
+#define S3C2443_UCON_RXERR_IRQEN  (1<<6)
+#define S3C2443_UCON_LOOPBACK	  (1<<5)
+
+#define S3C2410_UCON_DEFAULT	  (S3C2410_UCON_TXILEVEL  | \
+				   S3C2410_UCON_RXILEVEL  | \
+				   S3C2410_UCON_TXIRQMODE | \
+				   S3C2410_UCON_RXIRQMODE | \
+				   S3C2410_UCON_RXFIFO_TOI)
+
+#define S3C2410_UFCON_FIFOMODE	  (1<<0)
+#define S3C2410_UFCON_TXTRIG0	  (0<<6)
+#define S3C2410_UFCON_RXTRIG8	  (1<<4)
+#define S3C2410_UFCON_RXTRIG12	  (2<<4)
+
+/* S3C2440 FIFO trigger levels */
+#define S3C2440_UFCON_RXTRIG1	  (0<<4)
+#define S3C2440_UFCON_RXTRIG8	  (1<<4)
+#define S3C2440_UFCON_RXTRIG16	  (2<<4)
+#define S3C2440_UFCON_RXTRIG32	  (3<<4)
+
+#define S3C2440_UFCON_TXTRIG0	  (0<<6)
+#define S3C2440_UFCON_TXTRIG16	  (1<<6)
+#define S3C2440_UFCON_TXTRIG32	  (2<<6)
+#define S3C2440_UFCON_TXTRIG48	  (3<<6)
+
+#define S3C2410_UFCON_RESETBOTH	  (3<<1)
+#define S3C2410_UFCON_RESETTX	  (1<<2)
+#define S3C2410_UFCON_RESETRX	  (1<<1)
+
+#define S3C2410_UFCON_DEFAULT	  (S3C2410_UFCON_FIFOMODE | \
+				   S3C2410_UFCON_TXTRIG0  | \
+				   S3C2410_UFCON_RXTRIG8 )
+
+#define	S3C2410_UMCOM_AFC	  (1<<4)
+#define	S3C2410_UMCOM_RTS_LOW	  (1<<0)
+
+#define S3C2412_UMCON_AFC_63	(0<<5)		/* same as s3c2443 */
+#define S3C2412_UMCON_AFC_56	(1<<5)
+#define S3C2412_UMCON_AFC_48	(2<<5)
+#define S3C2412_UMCON_AFC_40	(3<<5)
+#define S3C2412_UMCON_AFC_32	(4<<5)
+#define S3C2412_UMCON_AFC_24	(5<<5)
+#define S3C2412_UMCON_AFC_16	(6<<5)
+#define S3C2412_UMCON_AFC_8	(7<<5)
+
+#define S3C2410_UFSTAT_TXFULL	  (1<<9)
+#define S3C2410_UFSTAT_RXFULL	  (1<<8)
+#define S3C2410_UFSTAT_TXMASK	  (15<<4)
+#define S3C2410_UFSTAT_TXSHIFT	  (4)
+#define S3C2410_UFSTAT_RXMASK	  (15<<0)
+#define S3C2410_UFSTAT_RXSHIFT	  (0)
+
+/* UFSTAT S3C24A0 */
+#define S3C24A0_UFSTAT_TXFULL	  (1 << 14)
+#define S3C24A0_UFSTAT_RXFULL	  (1 << 6)
+#define S3C24A0_UFSTAT_TXMASK	  (63 << 8)
+#define S3C24A0_UFSTAT_TXSHIFT	  (8)
+#define S3C24A0_UFSTAT_RXMASK	  (63)
+#define S3C24A0_UFSTAT_RXSHIFT	  (0)
+
+/* UFSTAT S3C2443 same as S3C2440 */
+#define S3C2440_UFSTAT_TXFULL	  (1<<14)
+#define S3C2440_UFSTAT_RXFULL	  (1<<6)
+#define S3C2440_UFSTAT_TXSHIFT	  (8)
+#define S3C2440_UFSTAT_RXSHIFT	  (0)
+#define S3C2440_UFSTAT_TXMASK	  (63<<8)
+#define S3C2440_UFSTAT_RXMASK	  (63)
+
+#define S3C2410_UTRSTAT_TXE	  (1<<2)
+#define S3C2410_UTRSTAT_TXFE	  (1<<1)
+#define S3C2410_UTRSTAT_RXDR	  (1<<0)
+
+#define S3C2410_UERSTAT_OVERRUN	  (1<<0)
+#define S3C2410_UERSTAT_FRAME	  (1<<2)
+#define S3C2410_UERSTAT_BREAK	  (1<<3)
+#define S3C2443_UERSTAT_PARITY	  (1<<1)
+
+#define S3C2410_UERSTAT_ANY	  (S3C2410_UERSTAT_OVERRUN | \
+				   S3C2410_UERSTAT_FRAME | \
+				   S3C2410_UERSTAT_BREAK)
+
+#define S3C2410_UMSTAT_CTS	  (1<<0)
+#define S3C2410_UMSTAT_DeltaCTS	  (1<<2)
+
+#define S3C2443_DIVSLOT		  (0x2C)
+
+/* S3C64XX interrupt registers. */
+#define S3C64XX_UINTP		0x30
+#define S3C64XX_UINTSP		0x34
+#define S3C64XX_UINTM		0x38
+
+/* Following are specific to S5PV210 and S5P6442 */
+#define S5PV210_UCON_CLKMASK	(1<<10)
+#define S5PV210_UCON_PCLK	(0<<10)
+#define S5PV210_UCON_UCLK	(1<<10)
+
+#define S5PV210_UFCON_TXTRIG0	(0<<8)
+#define S5PV210_UFCON_TXTRIG4	(1<<8)
+#define S5PV210_UFCON_TXTRIG8	(2<<8)
+#define S5PV210_UFCON_TXTRIG16	(3<<8)
+#define S5PV210_UFCON_TXTRIG32	(4<<8)
+#define S5PV210_UFCON_TXTRIG64	(5<<8)
+#define S5PV210_UFCON_TXTRIG128 (6<<8)
+#define S5PV210_UFCON_TXTRIG256 (7<<8)
+
+#define S5PV210_UFCON_RXTRIG1	(0<<4)
+#define S5PV210_UFCON_RXTRIG4	(1<<4)
+#define S5PV210_UFCON_RXTRIG8	(2<<4)
+#define S5PV210_UFCON_RXTRIG16	(3<<4)
+#define S5PV210_UFCON_RXTRIG32	(4<<4)
+#define S5PV210_UFCON_RXTRIG64	(5<<4)
+#define S5PV210_UFCON_RXTRIG128	(6<<4)
+#define S5PV210_UFCON_RXTRIG256	(7<<4)
+
+#define S5PV210_UFSTAT_TXFULL	(1<<24)
+#define S5PV210_UFSTAT_RXFULL	(1<<8)
+#define S5PV210_UFSTAT_TXMASK	(255<<16)
+#define S5PV210_UFSTAT_TXSHIFT	(16)
+#define S5PV210_UFSTAT_RXMASK	(255<<0)
+#define S5PV210_UFSTAT_RXSHIFT	(0)
+
+#ifndef __ASSEMBLY__
+
+/* struct s3c24xx_uart_clksrc
+ *
+ * this structure defines a named clock source that can be used for the
+ * uart, so that the best clock can be selected for the requested baud
+ * rate.
+ *
+ * min_baud and max_baud define the range of baud-rates this clock is
+ * acceptable for, if they are both zero, it is assumed any baud rate that
+ * can be generated from this clock will be used.
+ *
+ * divisor gives the divisor from the clock to the one seen by the uart
+*/
+
+struct s3c24xx_uart_clksrc {
+	const char	*name;
+	unsigned int	 divisor;
+	unsigned int	 min_baud;
+	unsigned int	 max_baud;
+};
+
+/* configuration structure for per-machine configurations for the
+ * serial port
+ *
+ * the pointer is setup by the machine specific initialisation from the
+ * arch/arm/mach-s3c2410/ directory.
+*/
+
+struct s3c2410_uartcfg {
+	unsigned char	   hwport;	 /* hardware port number */
+	unsigned char	   unused;
+	unsigned short	   flags;
+	upf_t		   uart_flags;	 /* default uart flags */
+
+	unsigned long	   ucon;	 /* value of ucon for port */
+	unsigned long	   ulcon;	 /* value of ulcon for port */
+	unsigned long	   ufcon;	 /* value of ufcon for port */
+
+	struct s3c24xx_uart_clksrc *clocks;
+	unsigned int		    clocks_size;
+};
+
+/* s3c24xx_uart_devs
+ *
+ * this is exported from the core as we cannot use driver_register(),
+ * or platform_add_device() before the console_initcall()
+*/
+
+extern struct platform_device *s3c24xx_uart_devs[4];
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_ARM_REGS_SERIAL_H */
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-timer.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-timer.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-timer.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-timer.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,124 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-timer.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 Timer configuration
+*/
+
+#ifndef __ASM_ARCH_REGS_TIMER_H
+#define __ASM_ARCH_REGS_TIMER_H
+
+#define S3C_TIMERREG(x) (S3C_VA_TIMER + (x))
+#define S3C_TIMERREG2(tmr,reg) S3C_TIMERREG((reg)+0x0c+((tmr)*0x0c))
+
+#define S3C2410_TCFG0	      S3C_TIMERREG(0x00)
+#define S3C2410_TCFG1	      S3C_TIMERREG(0x04)
+#define S3C2410_TCON	      S3C_TIMERREG(0x08)
+
+#define S3C64XX_TINT_CSTAT    S3C_TIMERREG(0x44)
+
+#define S3C2410_TCFG_PRESCALER0_MASK (255<<0)
+#define S3C2410_TCFG_PRESCALER1_MASK (255<<8)
+#define S3C2410_TCFG_PRESCALER1_SHIFT (8)
+#define S3C2410_TCFG_DEADZONE_MASK   (255<<16)
+#define S3C2410_TCFG_DEADZONE_SHIFT  (16)
+
+#define S3C2410_TCFG1_MUX4_DIV2	  (0<<16)
+#define S3C2410_TCFG1_MUX4_DIV4	  (1<<16)
+#define S3C2410_TCFG1_MUX4_DIV8	  (2<<16)
+#define S3C2410_TCFG1_MUX4_DIV16  (3<<16)
+#define S3C2410_TCFG1_MUX4_TCLK1  (4<<16)
+#define S3C2410_TCFG1_MUX4_MASK	  (15<<16)
+#define S3C2410_TCFG1_MUX4_SHIFT  (16)
+
+#define S3C2410_TCFG1_MUX3_DIV2	  (0<<12)
+#define S3C2410_TCFG1_MUX3_DIV4	  (1<<12)
+#define S3C2410_TCFG1_MUX3_DIV8	  (2<<12)
+#define S3C2410_TCFG1_MUX3_DIV16  (3<<12)
+#define S3C2410_TCFG1_MUX3_TCLK1  (4<<12)
+#define S3C2410_TCFG1_MUX3_MASK	  (15<<12)
+
+
+#define S3C2410_TCFG1_MUX2_DIV2	  (0<<8)
+#define S3C2410_TCFG1_MUX2_DIV4	  (1<<8)
+#define S3C2410_TCFG1_MUX2_DIV8	  (2<<8)
+#define S3C2410_TCFG1_MUX2_DIV16  (3<<8)
+#define S3C2410_TCFG1_MUX2_TCLK1  (4<<8)
+#define S3C2410_TCFG1_MUX2_MASK	  (15<<8)
+
+
+#define S3C2410_TCFG1_MUX1_DIV2	  (0<<4)
+#define S3C2410_TCFG1_MUX1_DIV4	  (1<<4)
+#define S3C2410_TCFG1_MUX1_DIV8	  (2<<4)
+#define S3C2410_TCFG1_MUX1_DIV16  (3<<4)
+#define S3C2410_TCFG1_MUX1_TCLK0  (4<<4)
+#define S3C2410_TCFG1_MUX1_MASK	  (15<<4)
+
+#define S3C2410_TCFG1_MUX0_DIV2	  (0<<0)
+#define S3C2410_TCFG1_MUX0_DIV4	  (1<<0)
+#define S3C2410_TCFG1_MUX0_DIV8	  (2<<0)
+#define S3C2410_TCFG1_MUX0_DIV16  (3<<0)
+#define S3C2410_TCFG1_MUX0_TCLK0  (4<<0)
+#define S3C2410_TCFG1_MUX0_MASK	  (15<<0)
+
+#define S3C2410_TCFG1_MUX_DIV2	  (0<<0)
+#define S3C2410_TCFG1_MUX_DIV4	  (1<<0)
+#define S3C2410_TCFG1_MUX_DIV8	  (2<<0)
+#define S3C2410_TCFG1_MUX_DIV16   (3<<0)
+#define S3C2410_TCFG1_MUX_TCLK    (4<<0)
+#define S3C2410_TCFG1_MUX_MASK	  (15<<0)
+
+#define S3C64XX_TCFG1_MUX_DIV1	  (0<<0)
+#define S3C64XX_TCFG1_MUX_DIV2	  (1<<0)
+#define S3C64XX_TCFG1_MUX_DIV4	  (2<<0)
+#define S3C64XX_TCFG1_MUX_DIV8    (3<<0)
+#define S3C64XX_TCFG1_MUX_DIV16   (4<<0)
+#define S3C64XX_TCFG1_MUX_TCLK    (5<<0)  /* 3 sets of TCLK */
+#define S3C64XX_TCFG1_MUX_MASK	  (15<<0)
+
+#define S3C2410_TCFG1_SHIFT(x)	  ((x) * 4)
+
+/* for each timer, we have an count buffer, an compare buffer and
+ * an observation buffer
+*/
+
+/* WARNING - timer 4 has no buffer reg, and it's observation is at +4 */
+
+#define S3C2410_TCNTB(tmr)    S3C_TIMERREG2(tmr, 0x00)
+#define S3C2410_TCMPB(tmr)    S3C_TIMERREG2(tmr, 0x04)
+#define S3C2410_TCNTO(tmr)    S3C_TIMERREG2(tmr, (((tmr) == 4) ? 0x04 : 0x08))
+
+#define S3C2410_TCON_T4RELOAD	  (1<<22)
+#define S3C2410_TCON_T4MANUALUPD  (1<<21)
+#define S3C2410_TCON_T4START	  (1<<20)
+
+#define S3C2410_TCON_T3RELOAD	  (1<<19)
+#define S3C2410_TCON_T3INVERT	  (1<<18)
+#define S3C2410_TCON_T3MANUALUPD  (1<<17)
+#define S3C2410_TCON_T3START	  (1<<16)
+
+#define S3C2410_TCON_T2RELOAD	  (1<<15)
+#define S3C2410_TCON_T2INVERT	  (1<<14)
+#define S3C2410_TCON_T2MANUALUPD  (1<<13)
+#define S3C2410_TCON_T2START	  (1<<12)
+
+#define S3C2410_TCON_T1RELOAD	  (1<<11)
+#define S3C2410_TCON_T1INVERT	  (1<<10)
+#define S3C2410_TCON_T1MANUALUPD  (1<<9)
+#define S3C2410_TCON_T1START	  (1<<8)
+
+#define S3C2410_TCON_T0DEADZONE	  (1<<4)
+#define S3C2410_TCON_T0RELOAD	  (1<<3)
+#define S3C2410_TCON_T0INVERT	  (1<<2)
+#define S3C2410_TCON_T0MANUALUPD  (1<<1)
+#define S3C2410_TCON_T0START	  (1<<0)
+
+#endif /*  __ASM_ARCH_REGS_TIMER_H */
+
+
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,377 @@
+/* arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      http://armlinux.simtec.co.uk/
+ *      Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - USB2.0 Highspeed/OtG device 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_USB_HSOTG_H
+#define __PLAT_S3C64XX_REGS_USB_HSOTG_H __FILE__
+
+#define S3C_HSOTG_REG(x) (x)
+
+#define S3C_GOTGCTL				S3C_HSOTG_REG(0x000)
+#define S3C_GOTGCTL_BSESVLD			(1 << 19)
+#define S3C_GOTGCTL_ASESVLD			(1 << 18)
+#define S3C_GOTGCTL_DBNC_SHORT			(1 << 17)
+#define S3C_GOTGCTL_CONID_B			(1 << 16)
+#define S3C_GOTGCTL_DEVHNPEN			(1 << 11)
+#define S3C_GOTGCTL_HSSETHNPEN			(1 << 10)
+#define S3C_GOTGCTL_HNPREQ			(1 << 9)
+#define S3C_GOTGCTL_HSTNEGSCS			(1 << 8)
+#define S3C_GOTGCTL_SESREQ			(1 << 1)
+#define S3C_GOTGCTL_SESREQSCS			(1 << 0)
+
+#define S3C_GOTGINT				S3C_HSOTG_REG(0x004)
+#define S3C_GOTGINT_DbnceDone			(1 << 19)
+#define S3C_GOTGINT_ADevTOUTChg			(1 << 18)
+#define S3C_GOTGINT_HstNegDet			(1 << 17)
+#define S3C_GOTGINT_HstnegSucStsChng		(1 << 9)
+#define S3C_GOTGINT_SesReqSucStsChng		(1 << 8)
+#define S3C_GOTGINT_SesEndDet			(1 << 2)
+
+#define S3C_GAHBCFG				S3C_HSOTG_REG(0x008)
+#define S3C_GAHBCFG_PTxFEmpLvl			(1 << 8)
+#define S3C_GAHBCFG_NPTxFEmpLvl			(1 << 7)
+#define S3C_GAHBCFG_DMAEn			(1 << 5)
+#define S3C_GAHBCFG_HBstLen_MASK		(0xf << 1)
+#define S3C_GAHBCFG_HBstLen_SHIFT		(1)
+#define S3C_GAHBCFG_HBstLen_Single		(0x0 << 1)
+#define S3C_GAHBCFG_HBstLen_Incr		(0x1 << 1)
+#define S3C_GAHBCFG_HBstLen_Incr4		(0x3 << 1)
+#define S3C_GAHBCFG_HBstLen_Incr8		(0x5 << 1)
+#define S3C_GAHBCFG_HBstLen_Incr16		(0x7 << 1)
+#define S3C_GAHBCFG_GlblIntrEn			(1 << 0)
+
+#define S3C_GUSBCFG				S3C_HSOTG_REG(0x00C)
+#define S3C_GUSBCFG_PHYLPClkSel			(1 << 15)
+#define S3C_GUSBCFG_HNPCap			(1 << 9)
+#define S3C_GUSBCFG_SRPCap			(1 << 8)
+#define S3C_GUSBCFG_PHYIf16			(1 << 3)
+#define S3C_GUSBCFG_TOutCal_MASK		(0x7 << 0)
+#define S3C_GUSBCFG_TOutCal_SHIFT		(0)
+#define S3C_GUSBCFG_TOutCal_LIMIT		(0x7)
+#define S3C_GUSBCFG_TOutCal(_x)			((_x) << 0)
+
+#define S3C_GRSTCTL				S3C_HSOTG_REG(0x010)
+
+#define S3C_GRSTCTL_AHBIdle			(1 << 31)
+#define S3C_GRSTCTL_DMAReq			(1 << 30)
+#define S3C_GRSTCTL_TxFNum_MASK			(0x1f << 6)
+#define S3C_GRSTCTL_TxFNum_SHIFT		(6)
+#define S3C_GRSTCTL_TxFNum_LIMIT		(0x1f)
+#define S3C_GRSTCTL_TxFNum(_x)			((_x) << 6)
+#define S3C_GRSTCTL_TxFFlsh			(1 << 5)
+#define S3C_GRSTCTL_RxFFlsh			(1 << 4)
+#define S3C_GRSTCTL_INTknQFlsh			(1 << 3)
+#define S3C_GRSTCTL_FrmCntrRst			(1 << 2)
+#define S3C_GRSTCTL_HSftRst			(1 << 1)
+#define S3C_GRSTCTL_CSftRst			(1 << 0)
+
+#define S3C_GINTSTS				S3C_HSOTG_REG(0x014)
+#define S3C_GINTMSK				S3C_HSOTG_REG(0x018)
+
+#define S3C_GINTSTS_WkUpInt			(1 << 31)
+#define S3C_GINTSTS_SessReqInt			(1 << 30)
+#define S3C_GINTSTS_DisconnInt			(1 << 29)
+#define S3C_GINTSTS_ConIDStsChng		(1 << 28)
+#define S3C_GINTSTS_PTxFEmp			(1 << 26)
+#define S3C_GINTSTS_HChInt			(1 << 25)
+#define S3C_GINTSTS_PrtInt			(1 << 24)
+#define S3C_GINTSTS_FetSusp			(1 << 22)
+#define S3C_GINTSTS_incompIP			(1 << 21)
+#define S3C_GINTSTS_IncomplSOIN			(1 << 20)
+#define S3C_GINTSTS_OEPInt			(1 << 19)
+#define S3C_GINTSTS_IEPInt			(1 << 18)
+#define S3C_GINTSTS_EPMis			(1 << 17)
+#define S3C_GINTSTS_EOPF			(1 << 15)
+#define S3C_GINTSTS_ISOutDrop			(1 << 14)
+#define S3C_GINTSTS_EnumDone			(1 << 13)
+#define S3C_GINTSTS_USBRst			(1 << 12)
+#define S3C_GINTSTS_USBSusp			(1 << 11)
+#define S3C_GINTSTS_ErlySusp			(1 << 10)
+#define S3C_GINTSTS_GOUTNakEff			(1 << 7)
+#define S3C_GINTSTS_GINNakEff			(1 << 6)
+#define S3C_GINTSTS_NPTxFEmp			(1 << 5)
+#define S3C_GINTSTS_RxFLvl			(1 << 4)
+#define S3C_GINTSTS_SOF				(1 << 3)
+#define S3C_GINTSTS_OTGInt			(1 << 2)
+#define S3C_GINTSTS_ModeMis			(1 << 1)
+#define S3C_GINTSTS_CurMod_Host			(1 << 0)
+
+#define S3C_GRXSTSR				S3C_HSOTG_REG(0x01C)
+#define S3C_GRXSTSP				S3C_HSOTG_REG(0x020)
+
+#define S3C_GRXSTS_FN_MASK			(0x7f << 25)
+#define S3C_GRXSTS_FN_SHIFT			(25)
+
+#define S3C_GRXSTS_PktSts_MASK			(0xf << 17)
+#define S3C_GRXSTS_PktSts_SHIFT			(17)
+#define S3C_GRXSTS_PktSts_GlobalOutNAK		(0x1 << 17)
+#define S3C_GRXSTS_PktSts_OutRX			(0x2 << 17)
+#define S3C_GRXSTS_PktSts_OutDone		(0x3 << 17)
+#define S3C_GRXSTS_PktSts_SetupDone		(0x4 << 17)
+#define S3C_GRXSTS_PktSts_SetupRX		(0x6 << 17)
+
+#define S3C_GRXSTS_DPID_MASK			(0x3 << 15)
+#define S3C_GRXSTS_DPID_SHIFT			(15)
+#define S3C_GRXSTS_ByteCnt_MASK			(0x7ff << 4)
+#define S3C_GRXSTS_ByteCnt_SHIFT		(4)
+#define S3C_GRXSTS_EPNum_MASK			(0xf << 0)
+#define S3C_GRXSTS_EPNum_SHIFT			(0)
+
+#define S3C_GRXFSIZ				S3C_HSOTG_REG(0x024)
+
+#define S3C_GNPTXFSIZ				S3C_HSOTG_REG(0x028)
+
+#define S3C_GNPTXFSIZ_NPTxFDep_MASK		(0xffff << 16)
+#define S3C_GNPTXFSIZ_NPTxFDep_SHIFT		(16)
+#define S3C_GNPTXFSIZ_NPTxFDep_LIMIT		(0xffff)
+#define S3C_GNPTXFSIZ_NPTxFDep(_x)		((_x) << 16)
+#define S3C_GNPTXFSIZ_NPTxFStAddr_MASK		(0xffff << 0)
+#define S3C_GNPTXFSIZ_NPTxFStAddr_SHIFT		(0)
+#define S3C_GNPTXFSIZ_NPTxFStAddr_LIMIT		(0xffff)
+#define S3C_GNPTXFSIZ_NPTxFStAddr(_x)		((_x) << 0)
+
+#define S3C_GNPTXSTS				S3C_HSOTG_REG(0x02C)
+
+#define S3C_GNPTXSTS_NPtxQTop_MASK		(0x7f << 24)
+#define S3C_GNPTXSTS_NPtxQTop_SHIFT		(24)
+
+#define S3C_GNPTXSTS_NPTxQSpcAvail_MASK		(0xff << 16)
+#define S3C_GNPTXSTS_NPTxQSpcAvail_SHIFT	(16)
+#define S3C_GNPTXSTS_NPTxQSpcAvail_GET(_v)	(((_v) >> 16) & 0xff)
+
+#define S3C_GNPTXSTS_NPTxFSpcAvail_MASK		(0xffff << 0)
+#define S3C_GNPTXSTS_NPTxFSpcAvail_SHIFT	(0)
+#define S3C_GNPTXSTS_NPTxFSpcAvail_GET(_v)	(((_v) >> 0) & 0xffff)
+
+
+#define S3C_HPTXFSIZ				S3C_HSOTG_REG(0x100)
+
+#define S3C_DPTXFSIZn(_a)			S3C_HSOTG_REG(0x104 + (((_a) - 1) * 4))
+
+#define S3C_DPTXFSIZn_DPTxFSize_MASK		(0xffff << 16)
+#define S3C_DPTXFSIZn_DPTxFSize_SHIFT		(16)
+#define S3C_DPTXFSIZn_DPTxFSize_GET(_v)		(((_v) >> 16) & 0xffff)
+#define S3C_DPTXFSIZn_DPTxFSize_LIMIT		(0xffff)
+#define S3C_DPTXFSIZn_DPTxFSize(_x)		((_x) << 16)
+
+#define S3C_DPTXFSIZn_DPTxFStAddr_MASK		(0xffff << 0)
+#define S3C_DPTXFSIZn_DPTxFStAddr_SHIFT		(0)
+
+/* Device mode registers */
+#define S3C_DCFG				S3C_HSOTG_REG(0x800)
+
+#define S3C_DCFG_EPMisCnt_MASK			(0x1f << 18)
+#define S3C_DCFG_EPMisCnt_SHIFT			(18)
+#define S3C_DCFG_EPMisCnt_LIMIT			(0x1f)
+#define S3C_DCFG_EPMisCnt(_x)			((_x) << 18)
+
+#define S3C_DCFG_PerFrInt_MASK			(0x3 << 11)
+#define S3C_DCFG_PerFrInt_SHIFT			(11)
+#define S3C_DCFG_PerFrInt_LIMIT			(0x3)
+#define S3C_DCFG_PerFrInt(_x)			((_x) << 11)
+
+#define S3C_DCFG_DevAddr_MASK			(0x7f << 4)
+#define S3C_DCFG_DevAddr_SHIFT			(4)
+#define S3C_DCFG_DevAddr_LIMIT			(0x7f)
+#define S3C_DCFG_DevAddr(_x)			((_x) << 4)
+
+#define S3C_DCFG_NZStsOUTHShk			(1 << 2)
+
+#define S3C_DCFG_DevSpd_MASK			(0x3 << 0)
+#define S3C_DCFG_DevSpd_SHIFT			(0)
+#define S3C_DCFG_DevSpd_HS			(0x0 << 0)
+#define S3C_DCFG_DevSpd_FS			(0x1 << 0)
+#define S3C_DCFG_DevSpd_LS			(0x2 << 0)
+#define S3C_DCFG_DevSpd_FS48			(0x3 << 0)
+
+#define S3C_DCTL				S3C_HSOTG_REG(0x804)
+
+#define S3C_DCTL_PWROnPrgDone			(1 << 11)
+#define S3C_DCTL_CGOUTNak			(1 << 10)
+#define S3C_DCTL_SGOUTNak			(1 << 9)
+#define S3C_DCTL_CGNPInNAK			(1 << 8)
+#define S3C_DCTL_SGNPInNAK			(1 << 7)
+#define S3C_DCTL_TstCtl_MASK			(0x7 << 4)
+#define S3C_DCTL_TstCtl_SHIFT			(4)
+#define S3C_DCTL_GOUTNakSts			(1 << 3)
+#define S3C_DCTL_GNPINNakSts			(1 << 2)
+#define S3C_DCTL_SftDiscon			(1 << 1)
+#define S3C_DCTL_RmtWkUpSig			(1 << 0)
+
+#define S3C_DSTS				S3C_HSOTG_REG(0x808)
+
+#define S3C_DSTS_SOFFN_MASK			(0x3fff << 8)
+#define S3C_DSTS_SOFFN_SHIFT			(8)
+#define S3C_DSTS_SOFFN_LIMIT			(0x3fff)
+#define S3C_DSTS_SOFFN(_x)			((_x) << 8)
+#define S3C_DSTS_ErraticErr			(1 << 3)
+#define S3C_DSTS_EnumSpd_MASK			(0x3 << 1)
+#define S3C_DSTS_EnumSpd_SHIFT			(1)
+#define S3C_DSTS_EnumSpd_HS			(0x0 << 1)
+#define S3C_DSTS_EnumSpd_FS			(0x1 << 1)
+#define S3C_DSTS_EnumSpd_LS			(0x2 << 1)
+#define S3C_DSTS_EnumSpd_FS48			(0x3 << 1)
+
+#define S3C_DSTS_SuspSts			(1 << 0)
+
+#define S3C_DIEPMSK				S3C_HSOTG_REG(0x810)
+
+#define S3C_DIEPMSK_INEPNakEffMsk		(1 << 6)
+#define S3C_DIEPMSK_INTknEPMisMsk		(1 << 5)
+#define S3C_DIEPMSK_INTknTXFEmpMsk		(1 << 4)
+#define S3C_DIEPMSK_TimeOUTMsk			(1 << 3)
+#define S3C_DIEPMSK_AHBErrMsk			(1 << 2)
+#define S3C_DIEPMSK_EPDisbldMsk			(1 << 1)
+#define S3C_DIEPMSK_XferComplMsk		(1 << 0)
+
+#define S3C_DOEPMSK				S3C_HSOTG_REG(0x814)
+
+#define S3C_DOEPMSK_Back2BackSetup		(1 << 6)
+#define S3C_DOEPMSK_OUTTknEPdisMsk		(1 << 4)
+#define S3C_DOEPMSK_SetupMsk			(1 << 3)
+#define S3C_DOEPMSK_AHBErrMsk			(1 << 2)
+#define S3C_DOEPMSK_EPDisbldMsk			(1 << 1)
+#define S3C_DOEPMSK_XferComplMsk		(1 << 0)
+
+#define S3C_DAINT				S3C_HSOTG_REG(0x818)
+#define S3C_DAINTMSK				S3C_HSOTG_REG(0x81C)
+
+#define S3C_DAINT_OutEP_SHIFT			(16)
+#define S3C_DAINT_OutEP(x)			(1 << ((x) + 16))
+#define S3C_DAINT_InEP(x)			(1 << (x))
+
+#define S3C_DTKNQR1				S3C_HSOTG_REG(0x820)
+#define S3C_DTKNQR2				S3C_HSOTG_REG(0x824)
+#define S3C_DTKNQR3				S3C_HSOTG_REG(0x830)
+#define S3C_DTKNQR4				S3C_HSOTG_REG(0x834)
+
+#define S3C_DVBUSDIS				S3C_HSOTG_REG(0x828)
+#define S3C_DVBUSPULSE				S3C_HSOTG_REG(0x82C)
+
+#define S3C_DIEPCTL0				S3C_HSOTG_REG(0x900)
+#define S3C_DOEPCTL0				S3C_HSOTG_REG(0xB00)
+#define S3C_DIEPCTL(_a)				S3C_HSOTG_REG(0x900 + ((_a) * 0x20))
+#define S3C_DOEPCTL(_a)				S3C_HSOTG_REG(0xB00 + ((_a) * 0x20))
+
+/* EP0 specialness:
+ * bits[29..28] - reserved (no SetD0PID, SetD1PID)
+ * bits[25..22] - should always be zero, this isn't a periodic endpoint
+ * bits[10..0] - MPS setting differenct for EP0
+*/
+#define S3C_D0EPCTL_MPS_MASK			(0x3 << 0)
+#define S3C_D0EPCTL_MPS_SHIFT			(0)
+#define S3C_D0EPCTL_MPS_64			(0x0 << 0)
+#define S3C_D0EPCTL_MPS_32			(0x1 << 0)
+#define S3C_D0EPCTL_MPS_16			(0x2 << 0)
+#define S3C_D0EPCTL_MPS_8			(0x3 << 0)
+
+#define S3C_DxEPCTL_EPEna			(1 << 31)
+#define S3C_DxEPCTL_EPDis			(1 << 30)
+#define S3C_DxEPCTL_SetD1PID			(1 << 29)
+#define S3C_DxEPCTL_SetOddFr			(1 << 29)
+#define S3C_DxEPCTL_SetD0PID			(1 << 28)
+#define S3C_DxEPCTL_SetEvenFr			(1 << 28)
+#define S3C_DxEPCTL_SNAK			(1 << 27)
+#define S3C_DxEPCTL_CNAK			(1 << 26)
+#define S3C_DxEPCTL_TxFNum_MASK			(0xf << 22)
+#define S3C_DxEPCTL_TxFNum_SHIFT		(22)
+#define S3C_DxEPCTL_TxFNum_LIMIT		(0xf)
+#define S3C_DxEPCTL_TxFNum(_x)			((_x) << 22)
+
+#define S3C_DxEPCTL_Stall			(1 << 21)
+#define S3C_DxEPCTL_Snp				(1 << 20)
+#define S3C_DxEPCTL_EPType_MASK			(0x3 << 18)
+#define S3C_DxEPCTL_EPType_SHIFT		(18)
+#define S3C_DxEPCTL_EPType_Control		(0x0 << 18)
+#define S3C_DxEPCTL_EPType_Iso			(0x1 << 18)
+#define S3C_DxEPCTL_EPType_Bulk			(0x2 << 18)
+#define S3C_DxEPCTL_EPType_Intterupt		(0x3 << 18)
+
+#define S3C_DxEPCTL_NAKsts			(1 << 17)
+#define S3C_DxEPCTL_DPID			(1 << 16)
+#define S3C_DxEPCTL_EOFrNum			(1 << 16)
+#define S3C_DxEPCTL_USBActEp			(1 << 15)
+#define S3C_DxEPCTL_NextEp_MASK			(0xf << 11)
+#define S3C_DxEPCTL_NextEp_SHIFT		(11)
+#define S3C_DxEPCTL_NextEp_LIMIT		(0xf)
+#define S3C_DxEPCTL_NextEp(_x)			((_x) << 11)
+
+#define S3C_DxEPCTL_MPS_MASK			(0x7ff << 0)
+#define S3C_DxEPCTL_MPS_SHIFT			(0)
+#define S3C_DxEPCTL_MPS_LIMIT			(0x7ff)
+#define S3C_DxEPCTL_MPS(_x)			((_x) << 0)
+
+#define S3C_DIEPINT(_a)				S3C_HSOTG_REG(0x908 + ((_a) * 0x20))
+#define S3C_DOEPINT(_a)				S3C_HSOTG_REG(0xB08 + ((_a) * 0x20))
+
+#define S3C_DxEPINT_INEPNakEff			(1 << 6)
+#define S3C_DxEPINT_Back2BackSetup		(1 << 6)
+#define S3C_DxEPINT_INTknEPMis			(1 << 5)
+#define S3C_DxEPINT_INTknTXFEmp			(1 << 4)
+#define S3C_DxEPINT_OUTTknEPdis			(1 << 4)
+#define S3C_DxEPINT_Timeout			(1 << 3)
+#define S3C_DxEPINT_Setup			(1 << 3)
+#define S3C_DxEPINT_AHBErr			(1 << 2)
+#define S3C_DxEPINT_EPDisbld			(1 << 1)
+#define S3C_DxEPINT_XferCompl			(1 << 0)
+
+#define S3C_DIEPTSIZ0				S3C_HSOTG_REG(0x910)
+
+#define S3C_DIEPTSIZ0_PktCnt_MASK		(0x3 << 19)
+#define S3C_DIEPTSIZ0_PktCnt_SHIFT		(19)
+#define S3C_DIEPTSIZ0_PktCnt_LIMIT		(0x3)
+#define S3C_DIEPTSIZ0_PktCnt(_x)		((_x) << 19)
+
+#define S3C_DIEPTSIZ0_XferSize_MASK		(0x7f << 0)
+#define S3C_DIEPTSIZ0_XferSize_SHIFT		(0)
+#define S3C_DIEPTSIZ0_XferSize_LIMIT		(0x7f)
+#define S3C_DIEPTSIZ0_XferSize(_x)		((_x) << 0)
+
+
+#define DOEPTSIZ0				S3C_HSOTG_REG(0xB10)
+#define S3C_DOEPTSIZ0_SUPCnt_MASK		(0x3 << 29)
+#define S3C_DOEPTSIZ0_SUPCnt_SHIFT		(29)
+#define S3C_DOEPTSIZ0_SUPCnt_LIMIT		(0x3)
+#define S3C_DOEPTSIZ0_SUPCnt(_x)		((_x) << 29)
+
+#define S3C_DOEPTSIZ0_PktCnt			(1 << 19)
+#define S3C_DOEPTSIZ0_XferSize_MASK		(0x7f << 0)
+#define S3C_DOEPTSIZ0_XferSize_SHIFT		(0)
+
+#define S3C_DIEPTSIZ(_a)			S3C_HSOTG_REG(0x910 + ((_a) * 0x20))
+#define S3C_DOEPTSIZ(_a)			S3C_HSOTG_REG(0xB10 + ((_a) * 0x20))
+
+#define S3C_DxEPTSIZ_MC_MASK			(0x3 << 29)
+#define S3C_DxEPTSIZ_MC_SHIFT			(29)
+#define S3C_DxEPTSIZ_MC_LIMIT			(0x3)
+#define S3C_DxEPTSIZ_MC(_x)			((_x) << 29)
+
+#define S3C_DxEPTSIZ_PktCnt_MASK		(0x3ff << 19)
+#define S3C_DxEPTSIZ_PktCnt_SHIFT		(19)
+#define S3C_DxEPTSIZ_PktCnt_GET(_v)		(((_v) >> 19) & 0x3ff)
+#define S3C_DxEPTSIZ_PktCnt_LIMIT		(0x3ff)
+#define S3C_DxEPTSIZ_PktCnt(_x)			((_x) << 19)
+
+#define S3C_DxEPTSIZ_XferSize_MASK		(0x7ffff << 0)
+#define S3C_DxEPTSIZ_XferSize_SHIFT		(0)
+#define S3C_DxEPTSIZ_XferSize_GET(_v)		(((_v) >> 0) & 0x7ffff)
+#define S3C_DxEPTSIZ_XferSize_LIMIT		(0x7ffff)
+#define S3C_DxEPTSIZ_XferSize(_x)		((_x) << 0)
+
+
+#define S3C_DIEPDMA(_a)				S3C_HSOTG_REG(0x914 + ((_a) * 0x20))
+#define S3C_DOEPDMA(_a)				S3C_HSOTG_REG(0xB14 + ((_a) * 0x20))
+
+#define S3C_EPFIFO(_a)				S3C_HSOTG_REG(0x1000 + ((_a) * 0x1000))
+
+#endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,50 @@
+/* arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      http://armlinux.simtec.co.uk/
+ *      Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - USB2.0 Highspeed/OtG device PHY 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.
+*/
+
+/* Note, this is a separate header file as some of the clock framework
+ * needs to touch this if the clk_48m is used as the USB OHCI or other
+ * peripheral source.
+*/
+
+#ifndef __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H
+#define __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H __FILE__
+
+/* S3C64XX_PA_USB_HSPHY */
+
+#define S3C_HSOTG_PHYREG(x)	((x) + S3C_VA_USB_HSPHY)
+
+#define S3C_PHYPWR				S3C_HSOTG_PHYREG(0x00)
+#define SRC_PHYPWR_OTG_DISABLE			(1 << 4)
+#define SRC_PHYPWR_ANALOG_POWERDOWN		(1 << 3)
+#define SRC_PHYPWR_FORCE_SUSPEND		(1 << 1)
+
+#define S3C_PHYCLK				S3C_HSOTG_PHYREG(0x04)
+#define S3C_PHYCLK_MODE_USB11			(1 << 6)
+#define S3C_PHYCLK_EXT_OSC			(1 << 5)
+#define S3C_PHYCLK_CLK_FORCE			(1 << 4)
+#define S3C_PHYCLK_ID_PULL			(1 << 2)
+#define S3C_PHYCLK_CLKSEL_MASK			(0x3 << 0)
+#define S3C_PHYCLK_CLKSEL_SHIFT			(0)
+#define S3C_PHYCLK_CLKSEL_48M			(0x0 << 0)
+#define S3C_PHYCLK_CLKSEL_12M			(0x2 << 0)
+#define S3C_PHYCLK_CLKSEL_24M			(0x3 << 0)
+
+#define S3C_RSTCON				S3C_HSOTG_PHYREG(0x08)
+#define S3C_RSTCON_PHYCLK			(1 << 2)
+#define S3C_RSTCON_HCLK				(1 << 2)
+#define S3C_RSTCON_PHY				(1 << 0)
+
+#define S3C_PHYTUNE				S3C_HSOTG_PHYREG(0x20)
+
+#endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-watchdog.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-watchdog.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/regs-watchdog.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/regs-watchdog.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,41 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-watchdog.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ *		      http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 Watchdog timer control
+*/
+
+
+#ifndef __ASM_ARCH_REGS_WATCHDOG_H
+#define __ASM_ARCH_REGS_WATCHDOG_H
+
+#define S3C_WDOGREG(x) ((x) + S3C_VA_WATCHDOG)
+
+#define S3C2410_WTCON	   S3C_WDOGREG(0x00)
+#define S3C2410_WTDAT	   S3C_WDOGREG(0x04)
+#define S3C2410_WTCNT	   S3C_WDOGREG(0x08)
+
+/* the watchdog can either generate a reset pulse, or an
+ * interrupt.
+ */
+
+#define S3C2410_WTCON_RSTEN   (0x01)
+#define S3C2410_WTCON_INTEN   (1<<2)
+#define S3C2410_WTCON_ENABLE  (1<<5)
+
+#define S3C2410_WTCON_DIV16   (0<<3)
+#define S3C2410_WTCON_DIV32   (1<<3)
+#define S3C2410_WTCON_DIV64   (2<<3)
+#define S3C2410_WTCON_DIV128  (3<<3)
+
+#define S3C2410_WTCON_PRESCALE(x) ((x) << 8)
+#define S3C2410_WTCON_PRESCALE_MASK (0xff00)
+
+#endif /* __ASM_ARCH_REGS_WATCHDOG_H */
+
+
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,67 @@
+/* linux/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
+ *
+ * Copyright (C) 2009 Samsung Electronics Ltd.
+ *	Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __S3C64XX_PLAT_SPI_H
+#define __S3C64XX_PLAT_SPI_H
+
+/**
+ * struct s3c64xx_spi_csinfo - ChipSelect description
+ * @fb_delay: Slave specific feedback delay.
+ *            Refer to FB_CLK_SEL register definition in SPI chapter.
+ * @line: Custom 'identity' of the CS line.
+ * @set_level: CS line control.
+ *
+ * This is per SPI-Slave Chipselect information.
+ * Allocate and initialize one in machine init code and make the
+ * spi_board_info.controller_data point to it.
+ */
+struct s3c64xx_spi_csinfo {
+	u8 fb_delay;
+	unsigned line;
+	void (*set_level)(unsigned line_id, int lvl);
+};
+
+/**
+ * struct s3c64xx_spi_info - SPI Controller defining structure
+ * @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field.
+ * @src_clk_name: Platform name of the corresponding clock.
+ * @num_cs: Number of CS this controller emulates.
+ * @cfg_gpio: Configure pins for this SPI controller.
+ * @fifo_lvl_mask: All tx fifo_lvl fields start at offset-6
+ * @rx_lvl_offset: Depends on tx fifo_lvl field and bus number
+ * @high_speed: If the controller supports HIGH_SPEED_EN bit
+ */
+struct s3c64xx_spi_info {
+	int src_clk_nr;
+	char *src_clk_name;
+
+	int num_cs;
+
+	int (*cfg_gpio)(struct platform_device *pdev);
+
+	/* Following two fields are for future compatibility */
+	int fifo_lvl_mask;
+	int rx_lvl_offset;
+	int high_speed;
+};
+
+/**
+ * s3c64xx_spi_set_info - SPI Controller configure callback by the board
+ *				initialization code.
+ * @cntrlr: SPI controller number the configuration is for.
+ * @src_clk_nr: Clock the SPI controller is to use to generate SPI clocks.
+ * @num_cs: Number of elements in the 'cs' array.
+ *
+ * Call this from machine init code for each SPI Controller that
+ * has some chips attached to it.
+ */
+extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
+
+#endif /* __S3C64XX_PLAT_SPI_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/sdhci.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/sdhci.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/sdhci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/sdhci.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,221 @@
+/* linux/arch/arm/plat-s3c/include/plat/sdhci.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - SDHCI (HSMMC) platform data 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 __PLAT_S3C_SDHCI_H
+#define __PLAT_S3C_SDHCI_H __FILE__
+
+struct platform_device;
+struct mmc_host;
+struct mmc_card;
+struct mmc_ios;
+
+/**
+ * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI
+ * @max_width: The maximum number of data bits supported.
+ * @host_caps: Standard MMC host capabilities bit field.
+ * @cfg_gpio: Configure the GPIO for a specific card bit-width
+ * @cfg_card: Configure the interface for a specific card and speed. This
+ *            is necessary the controllers and/or GPIO blocks require the
+ *	      changing of driver-strength and other controls dependant on
+ *	      the card and speed of operation.
+ *
+ * Initialisation data specific to either the machine or the platform
+ * for the device driver to use or call-back when configuring gpio or
+ * card speed information.
+*/
+struct s3c_sdhci_platdata {
+	unsigned int	max_width;
+	unsigned int	host_caps;
+
+	char		**clocks;	/* set of clock sources */
+
+	void	(*cfg_gpio)(struct platform_device *dev, int width);
+	void	(*cfg_card)(struct platform_device *dev,
+			    void __iomem *regbase,
+			    struct mmc_ios *ios,
+			    struct mmc_card *card);
+};
+
+/**
+ * s3c_sdhci0_set_platdata - Set platform data for S3C SDHCI device.
+ * @pd: Platform data to register to device.
+ *
+ * Register the given platform data for use withe S3C SDHCI device.
+ * The call will copy the platform data, so the board definitions can
+ * make the structure itself __initdata.
+ */
+extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd);
+extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd);
+extern void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd);
+
+/* Default platform data, exported so that per-cpu initialisation can
+ * set the correct one when there are more than one cpu type selected.
+*/
+
+extern struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata;
+extern struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata;
+extern struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata;
+
+/* Helper function availablity */
+
+extern void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
+extern void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
+
+/* S3C6400 SDHCI setup */
+
+#ifdef CONFIG_S3C64XX_SETUP_SDHCI
+extern char *s3c64xx_hsmmc_clksrcs[4];
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+extern void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
+					 void __iomem *r,
+					 struct mmc_ios *ios,
+					 struct mmc_card *card);
+
+static inline void s3c6400_default_sdhci0(void)
+{
+	s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+	s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
+	s3c_hsmmc0_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
+}
+
+#else
+static inline void s3c6400_default_sdhci0(void) { }
+#endif  /* CONFIG_S3C_DEV_HSMMC */
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static inline void s3c6400_default_sdhci1(void)
+{
+	s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+	s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
+	s3c_hsmmc1_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
+}
+#else
+static inline void s3c6400_default_sdhci1(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static inline void s3c6400_default_sdhci2(void)
+{
+	s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+	s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
+	s3c_hsmmc2_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
+}
+#else
+static inline void s3c6400_default_sdhci2(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC2 */
+
+/* S3C6410 SDHCI setup */
+
+extern void s3c6410_setup_sdhci_cfg_card(struct platform_device *dev,
+					 void __iomem *r,
+					 struct mmc_ios *ios,
+					 struct mmc_card *card);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static inline void s3c6410_default_sdhci0(void)
+{
+	s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+	s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
+	s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
+}
+#else
+static inline void s3c6410_default_sdhci0(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC */
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static inline void s3c6410_default_sdhci1(void)
+{
+	s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+	s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
+	s3c_hsmmc1_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
+}
+#else
+static inline void s3c6410_default_sdhci1(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static inline void s3c6410_default_sdhci2(void)
+{
+	s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+	s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
+	s3c_hsmmc2_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
+}
+#else
+static inline void s3c6410_default_sdhci2(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC2 */
+
+#else
+static inline void s3c6410_default_sdhci0(void) { }
+static inline void s3c6410_default_sdhci1(void) { }
+static inline void s3c6400_default_sdhci0(void) { }
+static inline void s3c6400_default_sdhci1(void) { }
+
+#endif /* CONFIG_S3C64XX_SETUP_SDHCI */
+
+/* S5PC100 SDHCI setup */
+
+#ifdef CONFIG_S5PC100_SETUP_SDHCI
+extern char *s5pc100_hsmmc_clksrcs[4];
+
+extern void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
+					   void __iomem *r,
+					   struct mmc_ios *ios,
+					   struct mmc_card *card);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static inline void s5pc100_default_sdhci0(void)
+{
+	s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+	s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio;
+	s3c_hsmmc0_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s5pc100_default_sdhci0(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC */
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static inline void s5pc100_default_sdhci1(void)
+{
+	s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+	s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio;
+	s3c_hsmmc1_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s5pc100_default_sdhci1(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static inline void s5pc100_default_sdhci2(void)
+{
+	s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+	s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio;
+	s3c_hsmmc2_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s5pc100_default_sdhci2(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+
+#else
+static inline void s5pc100_default_sdhci0(void) { }
+static inline void s5pc100_default_sdhci1(void) { }
+static inline void s5pc100_default_sdhci2(void) { }
+#endif /* CONFIG_S5PC100_SETUP_SDHCI */
+
+#endif /* __PLAT_S3C_SDHCI_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/udc-hs.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/udc-hs.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/udc-hs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/udc-hs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,29 @@
+/* arch/arm/plat-s3c/include/plat/udc-hs.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C USB2.0 High-speed / OtG platform 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.
+*/
+
+enum s3c_hsotg_dmamode {
+	S3C_HSOTG_DMA_NONE,	/* do not use DMA at-all */
+	S3C_HSOTG_DMA_ONLY,	/* always use DMA */
+	S3C_HSOTG_DMA_DRV,	/* DMA is chosen by driver */
+};
+
+/**
+ * struct s3c_hsotg_plat - platform data for high-speed otg/udc
+ * @dma: Whether to use DMA or not.
+ * @is_osc: The clock source is an oscillator, not a crystal
+ */
+struct s3c_hsotg_plat {
+	enum s3c_hsotg_dmamode	dma;
+	unsigned int		is_osc : 1;
+};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/uncompress.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/uncompress.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/uncompress.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/uncompress.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,184 @@
+/* arch/arm/plat-samsung/include/plat/uncompress.h
+ *
+ * Copyright 2003, 2007 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - uncompress 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.
+*/
+
+#ifndef __ASM_PLAT_UNCOMPRESS_H
+#define __ASM_PLAT_UNCOMPRESS_H
+
+typedef unsigned int upf_t;	/* cannot include linux/serial_core.h */
+
+/* uart setup */
+
+static unsigned int fifo_mask;
+static unsigned int fifo_max;
+
+/* forward declerations */
+
+static void arch_detect_cpu(void);
+
+/* defines for UART registers */
+
+#include <plat/regs-serial.h>
+#include <plat/regs-watchdog.h>
+
+/* working in physical space... */
+#undef S3C2410_WDOGREG
+#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
+
+/* how many bytes we allow into the FIFO at a time in FIFO mode */
+#define FIFO_MAX	 (14)
+
+#define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT)
+
+static __inline__ void
+uart_wr(unsigned int reg, unsigned int val)
+{
+	volatile unsigned int *ptr;
+
+	ptr = (volatile unsigned int *)(reg + uart_base);
+	*ptr = val;
+}
+
+static __inline__ unsigned int
+uart_rd(unsigned int reg)
+{
+	volatile unsigned int *ptr;
+
+	ptr = (volatile unsigned int *)(reg + uart_base);
+	return *ptr;
+}
+
+/* we can deal with the case the UARTs are being run
+ * in FIFO mode, so that we don't hold up our execution
+ * waiting for tx to happen...
+*/
+
+static void putc(int ch)
+{
+	if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
+		int level;
+
+		while (1) {
+			level = uart_rd(S3C2410_UFSTAT);
+			level &= fifo_mask;
+
+			if (level < fifo_max)
+				break;
+		}
+
+	} else {
+		/* not using fifos */
+
+		while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE)
+			barrier();
+	}
+
+	/* write byte to transmission register */
+	uart_wr(S3C2410_UTXH, ch);
+}
+
+static inline void flush(void)
+{
+}
+
+#define __raw_writel(d, ad)			\
+	do {							\
+		*((volatile unsigned int __force *)(ad)) = (d); \
+	} while (0)
+
+/* CONFIG_S3C_BOOT_WATCHDOG
+ *
+ * Simple boot-time watchdog setup, to reboot the system if there is
+ * any problem with the boot process
+*/
+
+#ifdef CONFIG_S3C_BOOT_WATCHDOG
+
+#define WDOG_COUNT (0xff00)
+
+static inline void arch_decomp_wdog(void)
+{
+	__raw_writel(WDOG_COUNT, S3C2410_WTCNT);
+}
+
+static void arch_decomp_wdog_start(void)
+{
+	__raw_writel(WDOG_COUNT, S3C2410_WTDAT);
+	__raw_writel(WDOG_COUNT, S3C2410_WTCNT);
+	__raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON);
+}
+
+#else
+#define arch_decomp_wdog_start()
+#define arch_decomp_wdog()
+#endif
+
+#ifdef CONFIG_S3C_BOOT_ERROR_RESET
+
+static void arch_decomp_error(const char *x)
+{
+	putstr("\n\n");
+	putstr(x);
+	putstr("\n\n -- System resetting\n");
+
+	__raw_writel(0x4000, S3C2410_WTDAT);
+	__raw_writel(0x4000, S3C2410_WTCNT);
+	__raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
+
+	while(1);
+}
+
+#define arch_error arch_decomp_error
+#endif
+
+#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
+static inline void arch_enable_uart_fifo(void)
+{
+	u32 fifocon = uart_rd(S3C2410_UFCON);
+
+	if (!(fifocon & S3C2410_UFCON_FIFOMODE)) {
+		fifocon |= S3C2410_UFCON_RESETBOTH;
+		uart_wr(S3C2410_UFCON, fifocon);
+
+		/* wait for fifo reset to complete */
+		while (1) {
+			fifocon = uart_rd(S3C2410_UFCON);
+			if (!(fifocon & S3C2410_UFCON_RESETBOTH))
+				break;
+		}
+	}
+}
+#else
+#define arch_enable_uart_fifo() do { } while(0)
+#endif
+
+
+static void
+arch_decomp_setup(void)
+{
+	/* we may need to setup the uart(s) here if we are not running
+	 * on an BAST... the BAST will have left the uarts configured
+	 * after calling linux.
+	 */
+
+	arch_detect_cpu();
+	arch_decomp_wdog_start();
+
+	/* Enable the UART FIFOs if they where not enabled and our
+	 * configuration says we should turn them on.
+	 */
+
+	arch_enable_uart_fifo();
+}
+
+
+#endif /* __ASM_PLAT_UNCOMPRESS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/usb-control.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/usb-control.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/usb-control.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/usb-control.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,43 @@
+/* arch/arm/plat-samsung/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);
+	}
+}
+
+extern void s3c_ohci_set_platdata(struct s3c2410_hcd_info *info);
+
+#endif /*__ASM_ARCH_USBCONTROL_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/watchdog-reset.h linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/watchdog-reset.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/include/plat/watchdog-reset.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/include/plat/watchdog-reset.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,49 @@
+/* arch/arm/plat-s3c/include/plat/watchdog-reset.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - System define for arch_reset() 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.
+*/
+
+#include <plat/regs-watchdog.h>
+#include <mach/map.h>
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+static inline void arch_wdt_reset(void)
+{
+	struct clk *wdtclk;
+
+	printk("arch_reset: attempting watchdog reset\n");
+
+	__raw_writel(0, S3C2410_WTCON);	  /* disable watchdog, to be safe  */
+
+	wdtclk = clk_get(NULL, "watchdog");
+	if (!IS_ERR(wdtclk)) {
+		clk_enable(wdtclk);
+	} else
+		printk(KERN_WARNING "%s: warning: cannot get watchdog clock\n", __func__);
+
+	/* put initial values into count and data */
+	__raw_writel(0x80, S3C2410_WTCNT);
+	__raw_writel(0x80, S3C2410_WTDAT);
+
+	/* set the watchdog to go and reset... */
+	__raw_writel(S3C2410_WTCON_ENABLE|S3C2410_WTCON_DIV16|S3C2410_WTCON_RSTEN |
+		     S3C2410_WTCON_PRESCALE(0x20), S3C2410_WTCON);
+
+	/* wait for reset to assert... */
+	mdelay(500);
+
+	printk(KERN_ERR "Watchdog reset failed to assert reset\n");
+
+	/* delay to allow the serial port to show the message */
+	mdelay(50);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/init.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/init.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/init.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,160 @@
+/* linux/arch/arm/plat-s3c/init.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series CPU initialisation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+
+#include <plat/regs-serial.h>
+
+static struct cpu_table *cpu;
+
+static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode,
+						struct cpu_table *tab,
+						unsigned int count)
+{
+	for (; count != 0; count--, tab++) {
+		if ((idcode & tab->idmask) == tab->idcode)
+			return tab;
+	}
+
+	return NULL;
+}
+
+void __init s3c_init_cpu(unsigned long idcode,
+			 struct cpu_table *cputab, unsigned int cputab_size)
+{
+	cpu = s3c_lookup_cpu(idcode, cputab, cputab_size);
+
+	if (cpu == NULL) {
+		printk(KERN_ERR "Unknown CPU type 0x%08lx\n", idcode);
+		panic("Unknown S3C24XX CPU");
+	}
+
+	printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
+
+	if (cpu->map_io == NULL || cpu->init == NULL) {
+		printk(KERN_ERR "CPU %s support not enabled\n", cpu->name);
+		panic("Unsupported Samsung CPU");
+	}
+
+	cpu->map_io();
+}
+
+/* s3c24xx_init_clocks
+ *
+ * Initialise the clock subsystem and associated information from the
+ * given master crystal value.
+ *
+ * xtal  = 0 -> use default PLL crystal value (normally 12MHz)
+ *      != 0 -> PLL crystal value in Hz
+*/
+
+void __init s3c24xx_init_clocks(int xtal)
+{
+	if (xtal == 0)
+		xtal = 12*1000*1000;
+
+	if (cpu == NULL)
+		panic("s3c24xx_init_clocks: no cpu setup?\n");
+
+	if (cpu->init_clocks == NULL)
+		panic("s3c24xx_init_clocks: cpu has no clock init\n");
+	else
+		(cpu->init_clocks)(xtal);
+}
+
+/* uart management */
+
+static int nr_uarts __initdata = 0;
+
+static struct s3c2410_uartcfg uart_cfgs[CONFIG_SERIAL_SAMSUNG_UARTS];
+
+/* s3c24xx_init_uartdevs
+ *
+ * copy the specified platform data and configuration into our central
+ * set of devices, before the data is thrown away after the init process.
+ *
+ * This also fills in the array passed to the serial driver for the
+ * early initialisation of the console.
+*/
+
+void __init s3c24xx_init_uartdevs(char *name,
+				  struct s3c24xx_uart_resources *res,
+				  struct s3c2410_uartcfg *cfg, int no)
+{
+	struct platform_device *platdev;
+	struct s3c2410_uartcfg *cfgptr = uart_cfgs;
+	struct s3c24xx_uart_resources *resp;
+	int uart;
+
+	memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
+
+	for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
+		platdev = s3c24xx_uart_src[cfgptr->hwport];
+
+		resp = res + cfgptr->hwport;
+
+		s3c24xx_uart_devs[uart] = platdev;
+
+		platdev->name = name;
+		platdev->resource = resp->resources;
+		platdev->num_resources = resp->nr_resources;
+
+		platdev->dev.platform_data = cfgptr;
+	}
+
+	nr_uarts = no;
+}
+
+void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+	if (cpu == NULL)
+		return;
+
+	if (cpu->init_uarts == NULL) {
+		printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n");
+	} else
+		(cpu->init_uarts)(cfg, no);
+}
+
+static int __init s3c_arch_init(void)
+{
+	int ret;
+
+	// do the correct init for cpu
+
+	if (cpu == NULL)
+		panic("s3c_arch_init: NULL cpu\n");
+
+	ret = (cpu->init)();
+	if (ret != 0)
+		return ret;
+
+	ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
+	return ret;
+}
+
+arch_initcall(s3c_arch_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/irq-uart.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/irq-uart.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/irq-uart.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/irq-uart.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,143 @@
+/* arch/arm/plat-samsung/irq-uart.c
+ *	originally part of arch/arm/plat-s3c64xx/irq.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * Samsung- UART Interrupt handling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/serial_core.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <plat/irq-uart.h>
+#include <plat/regs-serial.h>
+#include <plat/cpu.h>
+
+/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
+ * are consecutive when looking up the interrupt in the demux routines.
+ */
+
+static inline void __iomem *s3c_irq_uart_base(unsigned int irq)
+{
+	struct s3c_uart_irq *uirq = get_irq_chip_data(irq);
+	return uirq->regs;
+}
+
+static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
+{
+	return irq & 3;
+}
+
+static void s3c_irq_uart_mask(unsigned int irq)
+{
+	void __iomem *regs = s3c_irq_uart_base(irq);
+	unsigned int bit = s3c_irq_uart_bit(irq);
+	u32 reg;
+
+	reg = __raw_readl(regs + S3C64XX_UINTM);
+	reg |= (1 << bit);
+	__raw_writel(reg, regs + S3C64XX_UINTM);
+}
+
+static void s3c_irq_uart_maskack(unsigned int irq)
+{
+	void __iomem *regs = s3c_irq_uart_base(irq);
+	unsigned int bit = s3c_irq_uart_bit(irq);
+	u32 reg;
+
+	reg = __raw_readl(regs + S3C64XX_UINTM);
+	reg |= (1 << bit);
+	__raw_writel(reg, regs + S3C64XX_UINTM);
+	__raw_writel(1 << bit, regs + S3C64XX_UINTP);
+}
+
+static void s3c_irq_uart_unmask(unsigned int irq)
+{
+	void __iomem *regs = s3c_irq_uart_base(irq);
+	unsigned int bit = s3c_irq_uart_bit(irq);
+	u32 reg;
+
+	reg = __raw_readl(regs + S3C64XX_UINTM);
+	reg &= ~(1 << bit);
+	__raw_writel(reg, regs + S3C64XX_UINTM);
+}
+
+static void s3c_irq_uart_ack(unsigned int irq)
+{
+	void __iomem *regs = s3c_irq_uart_base(irq);
+	unsigned int bit = s3c_irq_uart_bit(irq);
+
+	__raw_writel(1 << bit, regs + S3C64XX_UINTP);
+}
+
+static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
+{
+	struct s3c_uart_irq *uirq = desc->handler_data;
+	u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
+	int base = uirq->base_irq;
+
+	if (pend & (1 << 0))
+		generic_handle_irq(base);
+	if (pend & (1 << 1))
+		generic_handle_irq(base + 1);
+	if (pend & (1 << 2))
+		generic_handle_irq(base + 2);
+	if (pend & (1 << 3))
+		generic_handle_irq(base + 3);
+}
+
+static struct irq_chip s3c_irq_uart = {
+	.name		= "s3c-uart",
+	.mask		= s3c_irq_uart_mask,
+	.unmask		= s3c_irq_uart_unmask,
+	.mask_ack	= s3c_irq_uart_maskack,
+	.ack		= s3c_irq_uart_ack,
+};
+
+static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
+{
+	struct irq_desc *desc = irq_to_desc(uirq->parent_irq);
+	void __iomem *reg_base = uirq->regs;
+	unsigned int irq;
+	int offs;
+
+	/* mask all interrupts at the start. */
+	__raw_writel(0xf, reg_base + S3C64XX_UINTM);
+
+	for (offs = 0; offs < 3; offs++) {
+		irq = uirq->base_irq + offs;
+
+		set_irq_chip(irq, &s3c_irq_uart);
+		set_irq_chip_data(irq, uirq);
+		set_irq_handler(irq, handle_level_irq);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	desc->handler_data = uirq;
+	set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
+}
+
+/**
+ * s3c_init_uart_irqs() - initialise UART IRQs and the necessary demuxing
+ * @irq: The interrupt data for registering
+ * @nr_irqs: The number of interrupt descriptions in @irq.
+ *
+ * Register the UART interrupts specified by @irq including the demuxing
+ * routines. This supports the S3C6400 and newer style of devices.
+ */
+void __init s3c_init_uart_irqs(struct s3c_uart_irq *irq, unsigned int nr_irqs)
+{
+	for (; nr_irqs > 0; nr_irqs--, irq++)
+		s3c_init_uart_irq(irq);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/irq-vic-timer.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/irq-vic-timer.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/irq-vic-timer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/irq-vic-timer.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,86 @@
+/* arch/arm/plat-samsung/irq-vic-timer.c
+ *	originally part of arch/arm/plat-s3c64xx/irq.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Interrupt handling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <plat/irq-vic-timer.h>
+#include <plat/regs-timer.h>
+
+static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc)
+{
+	generic_handle_irq((int)desc->handler_data);
+}
+
+/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
+
+static void s3c_irq_timer_mask(unsigned int irq)
+{
+	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
+
+	reg &= 0x1f;  /* mask out pending interrupts */
+	reg &= ~(1 << (irq - IRQ_TIMER0));
+	__raw_writel(reg, S3C64XX_TINT_CSTAT);
+}
+
+static void s3c_irq_timer_unmask(unsigned int irq)
+{
+	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
+
+	reg &= 0x1f;  /* mask out pending interrupts */
+	reg |= 1 << (irq - IRQ_TIMER0);
+	__raw_writel(reg, S3C64XX_TINT_CSTAT);
+}
+
+static void s3c_irq_timer_ack(unsigned int irq)
+{
+	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
+
+	reg &= 0x1f;
+	reg |= (1 << 5) << (irq - IRQ_TIMER0);
+	__raw_writel(reg, S3C64XX_TINT_CSTAT);
+}
+
+static struct irq_chip s3c_irq_timer = {
+	.name		= "s3c-timer",
+	.mask		= s3c_irq_timer_mask,
+	.unmask		= s3c_irq_timer_unmask,
+	.ack		= s3c_irq_timer_ack,
+};
+
+/**
+ * s3c_init_vic_timer_irq() - initialise timer irq chanined off VIC.\
+ * @parent_irq: The parent IRQ on the VIC for the timer.
+ * @timer_irq: The IRQ to be used for the timer.
+ *
+ * Register the necessary IRQ chaining and support for the timer IRQs
+ * chained of the VIC.
+ */
+void __init s3c_init_vic_timer_irq(unsigned int parent_irq,
+				   unsigned int timer_irq)
+{
+	struct irq_desc *desc = irq_to_desc(parent_irq);
+
+	set_irq_chained_handler(parent_irq, s3c_irq_demux_vic_timer);
+
+	set_irq_chip(timer_irq, &s3c_irq_timer);
+	set_irq_handler(timer_irq, handle_level_irq);
+	set_irq_flags(timer_irq, IRQF_VALID);
+
+	desc->handler_data = (void *)timer_irq;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/Kconfig linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/Kconfig
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -7,11 +7,240 @@
 config PLAT_SAMSUNG
 	bool
 	depends on ARCH_S3C2410 || ARCH_S3C24A0 || ARCH_S3C64XX || ARCH_S5PC1XX
+	select NO_IOPORT
 	default y
 	help
 	  Base platform code for all Samsung SoC based systems
 
 if PLAT_SAMSUNG
 
+# boot configurations
+
+comment "Boot options"
+
+config S3C_BOOT_WATCHDOG
+	bool "S3C Initialisation watchdog"
+	depends on S3C2410_WATCHDOG
+	help
+	  Say y to enable the watchdog during the kernel decompression
+	  stage. If the kernel fails to uncompress, then the watchdog
+	  will trigger a reset and the system should restart.
+
+config S3C_BOOT_ERROR_RESET
+	bool "S3C Reboot on decompression error"
+	help
+	  Say y here to use the watchdog to reset the system if the
+	  kernel decompressor detects an error during decompression.
+
+config S3C_BOOT_UART_FORCE_FIFO
+       bool "Force UART FIFO on during boot process"
+       default y
+       help
+         Say Y here to force the UART FIFOs on during the kernel
+	 uncompressor
+
+
+config S3C_LOWLEVEL_UART_PORT
+	int "S3C UART to use for low-level messages"
+	default 0
+	help
+	  Choice of which UART port to use for the low-level messages,
+	  such as the `Uncompressing...` at start time. The value of
+	  this configuration should be between zero and two. The port
+	  must have been initialised by the boot-loader before use.
+
+# clock options
+
+config SAMSUNG_CLKSRC
+	bool
+	help
+	  Select the clock code for the clksrc implementation
+	  used by newer systems such as the S3C64XX.
+
+# options for IRQ support
+
+config SAMSUNG_IRQ_VIC_TIMER
+       bool
+       help
+         Internal configuration to build the VIC timer interrupt code.
+
+config SAMSUNG_IRQ_UART
+       bool
+       help
+         Internal configuration to build the IRQ UART demux code.
+
+# options for gpio configuration support
+
+config SAMSUNG_GPIOLIB_4BIT
+	bool
+	help
+	  GPIOlib file contains the 4 bit modification functions for gpio
+	  configuration. GPIOlib shall be compiled only for S3C64XX and S5P
+	  series of processors.
+
+config S3C_GPIO_CFG_S3C24XX
+	bool
+	help
+	  Internal configuration to enable S3C24XX style GPIO configuration
+	  functions.
+
+config S3C_GPIO_CFG_S3C64XX
+	bool
+	help
+	  Internal configuration to enable S3C64XX style GPIO configuration
+	  functions.
+
+config S5P_GPIO_CFG_S5PC1XX
+	bool
+	help
+	  Internal configuration to enable S5PC1XX style GPIO configuration
+	  functions.
+
+config S3C_GPIO_PULL_UPDOWN
+	bool
+	help
+	  Internal configuration to enable the correct GPIO pull helper
+
+config S3C_GPIO_PULL_DOWN
+	bool
+	help
+	  Internal configuration to enable the correct GPIO pull helper
+
+config S3C_GPIO_PULL_UP
+	bool
+	help
+	  Internal configuration to enable the correct GPIO pull helper
+
+config SAMSUNG_GPIO_EXTRA
+	int "Number of additional GPIO pins"
+	default 0
+	help
+	  Use additional GPIO space in addition to the GPIO's the SOC
+	  provides. This allows expanding the GPIO space for use with
+	  GPIO expanders.
+
+config S3C_GPIO_SPACE
+	int "Space between gpio banks"
+	default 0
+	help
+	  Add a number of spare GPIO entries between each bank for debugging
+	  purposes. This allows any problems where an counter overflows from
+	  one bank to another to be caught, at the expense of using a little
+	  more memory.
+
+config S3C_GPIO_TRACK
+	bool
+	help
+	  Internal configuration option to enable the s3c specific gpio
+	  chip tracking if the platform requires it.
+
+# ADC driver
+
+config S3C_ADC
+	bool "ADC common driver support"
+	help
+	  Core support for the ADC block found in the Samsung SoC systems
+	  for drivers such as the touchscreen and hwmon to use to share
+	  this resource.
+
+# device definitions to compile in
+
+config S3C_DEV_HSMMC
+	bool
+	help
+	  Compile in platform device definitions for HSMMC code
+
+config S3C_DEV_HSMMC1
+	bool
+	help
+	  Compile in platform device definitions for HSMMC channel 1
+
+config S3C_DEV_HSMMC2
+	bool
+	help
+	  Compile in platform device definitions for HSMMC channel 2
+
+config S3C_DEV_I2C1
+	bool
+	help
+	  Compile in platform device definitions for I2C channel 1
+
+config S3C_DEV_FB
+	bool
+	help
+	  Compile in platform device definition for framebuffer
+
+config S3C_DEV_USB_HOST
+	bool
+	help
+	  Compile in platform device definition for USB host.
+
+config S3C_DEV_USB_HSOTG
+	bool
+	help
+	  Compile in platform device definition for USB high-speed OtG
+
+config S3C_DEV_NAND
+	bool
+	help
+	  Compile in platform device definition for NAND controller
+
+config S3C64XX_DEV_SPI
+	bool
+	help
+	  Compile in platform device definitions for S3C64XX's type
+	  SPI controllers.
+
+# DMA
+
+config S3C_DMA
+	bool
+	help
+	  Internal configuration for S3C DMA core
+
+comment "Power management"
+
+config SAMSUNG_PM_DEBUG
+	bool "S3C2410 PM Suspend debug"
+	depends on PM
+	help
+	  Say Y here if you want verbose debugging from the PM Suspend and
+	  Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
+	  for more information.
+
+config S3C_PM_DEBUG_LED_SMDK
+       bool "SMDK LED suspend/resume debugging"
+       depends on PM && (MACH_SMDK6410)
+       help
+         Say Y here to enable the use of the SMDK LEDs on the baseboard
+	 for debugging of the state of the suspend and resume process.
+
+	 Note, this currently only works for S3C64XX based SMDK boards.
+
+config SAMSUNG_PM_CHECK
+	bool "S3C2410 PM Suspend Memory CRC"
+	depends on PM && CRC32
+	help
+	  Enable the PM code's memory area checksum over sleep. This option
+	  will generate CRCs of all blocks of memory, and store them before
+	  going to sleep. The blocks are then checked on resume for any
+	  errors.
+
+	  Note, this can take several seconds depending on memory size
+	  and CPU speed.
+
+	  See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
+
+config SAMSUNG_PM_CHECK_CHUNKSIZE
+	int "S3C2410 PM Suspend CRC Chunksize (KiB)"
+	depends on PM && SAMSUNG_PM_CHECK
+	default 64
+	help
+	  Set the chunksize in Kilobytes of the CRC for checking memory
+	  corruption over suspend and resume. A smaller value will mean that
+	  the CRC data block will take more memory, but wil identify any
+	  faults with better precision.
+
+	  See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
 
 endif
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/Makefile linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/Makefile
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -9,3 +9,48 @@ obj-m				:=
 obj-n				:= dummy.o
 obj-				:=
 
+# Objects we always build independent of SoC choice
+
+obj-y				+= init.o
+obj-y				+= time.o
+obj-y				+= clock.o
+obj-y				+= pwm-clock.o
+obj-y				+= gpio.o
+obj-y				+= gpio-config.o
+
+obj-$(CONFIG_SAMSUNG_GPIOLIB_4BIT)	+= gpiolib.o
+obj-$(CONFIG_SAMSUNG_CLKSRC)	+= clock-clksrc.o
+
+obj-$(CONFIG_SAMSUNG_IRQ_UART)	+= irq-uart.o
+obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o
+
+# ADC
+
+obj-$(CONFIG_S3C_ADC)	+= adc.o
+
+# devices
+
+obj-$(CONFIG_S3C_DEV_HSMMC)	+= dev-hsmmc.o
+obj-$(CONFIG_S3C_DEV_HSMMC1)	+= dev-hsmmc1.o
+obj-$(CONFIG_S3C_DEV_HSMMC2)	+= dev-hsmmc2.o
+obj-y				+= dev-i2c0.o
+obj-$(CONFIG_S3C_DEV_I2C1)	+= dev-i2c1.o
+obj-$(CONFIG_S3C_DEV_FB)	+= dev-fb.o
+obj-y				+= dev-uart.o
+obj-$(CONFIG_S3C_DEV_USB_HOST)	+= dev-usb.o
+obj-$(CONFIG_S3C_DEV_USB_HSOTG)	+= dev-usb-hsotg.o
+obj-$(CONFIG_S3C_DEV_NAND)	+= dev-nand.o
+
+# DMA support
+
+obj-$(CONFIG_S3C_DMA)		+= dma.o
+
+# PM support
+
+obj-$(CONFIG_PM)		+= pm.o
+obj-$(CONFIG_PM)		+= pm-gpio.o
+obj-$(CONFIG_SAMSUNG_PM_CHECK)	+= pm-check.o
+
+# PWM support
+
+obj-$(CONFIG_HAVE_PWM)		+= pwm.o
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/pm.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/pm.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/pm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,378 @@
+/* linux/arch/arm/plat-s3c/pm.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2004-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 <mach/map.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-irq.h>
+#include <asm/irq.h>
+
+#include <plat/pm.h>
+#include <mach/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_SAMSUNG_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_SAMSUNG_PM_DEBUG */
+
+/* Save the UART configurations if we are configured for debug. */
+
+unsigned char pm_uart_udivslot;
+
+#ifdef CONFIG_SAMSUNG_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);
+
+	if (pm_uart_udivslot)
+		save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT);
+
+	S3C_PMDBG("UART[%d]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n",
+		  uart, save->ulcon, save->ucon, save->ufcon, save->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);
+
+	s3c_pm_arch_update_uart(regs, save);
+
+	__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);
+
+	if (pm_uart_udivslot)
+		__raw_writel(save->udivslot, regs + S3C2443_DIVSLOT);
+}
+
+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__);
+
+	/* LEDs should now be 1110 */
+	s3c_pm_debug_smdkled(1 << 1, 0);
+
+	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.33-gnu1/arch/arm/plat-samsung/pm-check.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/pm-check.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/pm-check.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/pm-check.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,243 @@
+/* linux/arch/arm/plat-s3c/pm-check.c
+ *  originally in linux/arch/arm/plat-s3c24xx/pm.c
+ *
+ * Copyright (c) 2004-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 <linux/slab.h>
+
+#include <plat/pm.h>
+
+#if CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE < 1
+#error CONFIG_SAMSUNG_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_SAMSUNG_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_SAMSUNG_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.33-gnu1/arch/arm/plat-samsung/pm-gpio.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/pm-gpio.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/pm-gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/pm-gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,380 @@
+
+/* linux/arch/arm/plat-s3c/pm-gpio.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series GPIO 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/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-core.h>
+#include <plat/pm.h>
+
+/* PM GPIO helpers */
+
+#define OFFS_CON	(0x00)
+#define OFFS_DAT	(0x04)
+#define OFFS_UP		(0x08)
+
+static void s3c_gpio_pm_1bit_save(struct s3c_gpio_chip *chip)
+{
+	chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
+	chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
+}
+
+static void s3c_gpio_pm_1bit_resume(struct s3c_gpio_chip *chip)
+{
+	void __iomem *base = chip->base;
+	u32 old_gpcon = __raw_readl(base + OFFS_CON);
+	u32 old_gpdat = __raw_readl(base + OFFS_DAT);
+	u32 gps_gpcon = chip->pm_save[0];
+	u32 gps_gpdat = chip->pm_save[1];
+	u32 gpcon;
+
+	/* GPACON only has one bit per control / data and no PULLUPs.
+	 * GPACON[x] = 0 => Output, 1 => SFN */
+
+	/* first set all SFN bits to SFN */
+
+	gpcon = old_gpcon | gps_gpcon;
+	__raw_writel(gpcon, base + OFFS_CON);
+
+	/* now set all the other bits */
+
+	__raw_writel(gps_gpdat, base + OFFS_DAT);
+	__raw_writel(gps_gpcon, base + OFFS_CON);
+
+	S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
+		  chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
+}
+
+struct s3c_gpio_pm s3c_gpio_pm_1bit = {
+	.save	= s3c_gpio_pm_1bit_save,
+	.resume = s3c_gpio_pm_1bit_resume,
+};
+
+static void s3c_gpio_pm_2bit_save(struct s3c_gpio_chip *chip)
+{
+	chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
+	chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
+	chip->pm_save[2] = __raw_readl(chip->base + OFFS_UP);
+}
+
+/* Test whether the given masked+shifted bits of an GPIO configuration
+ * are one of the SFN (special function) modes. */
+
+static inline int is_sfn(unsigned long con)
+{
+	return con >= 2;
+}
+
+/* Test if the given masked+shifted GPIO configuration is an input */
+
+static inline int is_in(unsigned long con)
+{
+	return con == 0;
+}
+
+/* Test if the given masked+shifted GPIO configuration is an output */
+
+static inline int is_out(unsigned long con)
+{
+	return con == 1;
+}
+
+/**
+ * s3c_gpio_pm_2bit_resume() - restore the given GPIO bank
+ * @chip: The chip information to resume.
+ *
+ * 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
+ * from the order that the CON and DAT registers are set in.
+ *
+ * The three states the pin can be are {IN,OUT,SFN} which gives us 9
+ * combinations of changes to check. Three of these, if the pin stays
+ * in the same configuration can be discounted. This leaves us with
+ * the following:
+ *
+ * { IN => OUT }  Change DAT first
+ * { IN => SFN }  Change CON first
+ * { OUT => SFN } Change CON first, so new data will not glitch
+ * { OUT => IN }  Change CON first, so new data will not glitch
+ * { SFN => IN }  Change CON first
+ * { SFN => OUT } Change DAT first, so new data will not glitch [1]
+ *
+ * We do not currently deal with the UP registers as these control
+ * weak resistors, so a small delay in change should not need to bring
+ * these into the calculations.
+ *
+ * [1] this assumes that writing to a pin DAT whilst in SFN will set the
+ *     state for when it is next output.
+ */
+static void s3c_gpio_pm_2bit_resume(struct s3c_gpio_chip *chip)
+{
+	void __iomem *base = chip->base;
+	u32 old_gpcon = __raw_readl(base + OFFS_CON);
+	u32 old_gpdat = __raw_readl(base + OFFS_DAT);
+	u32 gps_gpcon = chip->pm_save[0];
+	u32 gps_gpdat = chip->pm_save[1];
+	u32 gpcon, old, new, mask;
+	u32 change_mask = 0x0;
+	int nr;
+
+	/* restore GPIO pull-up settings */
+	__raw_writel(chip->pm_save[2], base + OFFS_UP);
+
+	/* Create a change_mask of all the items that need to have
+	 * their CON value changed before their DAT value, so that
+	 * we minimise the work between the two settings.
+	 */
+
+	for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) {
+		old = (old_gpcon & mask) >> nr;
+		new = (gps_gpcon & mask) >> nr;
+
+		/* If there is no change, then skip */
+
+		if (old == new)
+			continue;
+
+		/* If both are special function, then skip */
+
+		if (is_sfn(old) && is_sfn(new))
+			continue;
+
+		/* Change is IN => OUT, do not change now */
+
+		if (is_in(old) && is_out(new))
+			continue;
+
+		/* Change is SFN => OUT, do not change now */
+
+		if (is_sfn(old) && is_out(new))
+			continue;
+
+		/* We should now be at the case of IN=>SFN,
+		 * OUT=>SFN, OUT=>IN, SFN=>IN. */
+
+		change_mask |= mask;
+	}
+
+
+	/* Write the new CON settings */
+
+	gpcon = old_gpcon & ~change_mask;
+	gpcon |= gps_gpcon & change_mask;
+
+	__raw_writel(gpcon, base + OFFS_CON);
+
+	/* Now change any items that require DAT,CON */
+
+	__raw_writel(gps_gpdat, base + OFFS_DAT);
+	__raw_writel(gps_gpcon, base + OFFS_CON);
+
+	S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
+		  chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
+}
+
+struct s3c_gpio_pm s3c_gpio_pm_2bit = {
+	.save	= s3c_gpio_pm_2bit_save,
+	.resume = s3c_gpio_pm_2bit_resume,
+};
+
+#ifdef CONFIG_ARCH_S3C64XX
+static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
+{
+	chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
+	chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT);
+	chip->pm_save[3] = __raw_readl(chip->base + OFFS_UP);
+
+	if (chip->chip.ngpio > 8)
+		chip->pm_save[0] = __raw_readl(chip->base - 4);
+}
+
+static u32 s3c_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon)
+{
+	u32 old, new, mask;
+	u32 change_mask = 0x0;
+	int nr;
+
+	for (nr = 0, mask = 0x0f; nr < 16; nr += 4, mask <<= 4) {
+		old = (old_gpcon & mask) >> nr;
+		new = (gps_gpcon & mask) >> nr;
+
+		/* If there is no change, then skip */
+
+		if (old == new)
+			continue;
+
+		/* If both are special function, then skip */
+
+		if (is_sfn(old) && is_sfn(new))
+			continue;
+
+		/* Change is IN => OUT, do not change now */
+
+		if (is_in(old) && is_out(new))
+			continue;
+
+		/* Change is SFN => OUT, do not change now */
+
+		if (is_sfn(old) && is_out(new))
+			continue;
+
+		/* We should now be at the case of IN=>SFN,
+		 * OUT=>SFN, OUT=>IN, SFN=>IN. */
+
+		change_mask |= mask;
+	}
+
+	return change_mask;
+}
+
+static void s3c_gpio_pm_4bit_con(struct s3c_gpio_chip *chip, int index)
+{
+	void __iomem *con = chip->base + (index * 4);
+	u32 old_gpcon = __raw_readl(con);
+	u32 gps_gpcon = chip->pm_save[index + 1];
+	u32 gpcon, mask;
+
+	mask = s3c_gpio_pm_4bit_mask(old_gpcon, gps_gpcon);
+
+	gpcon = old_gpcon & ~mask;
+	gpcon |= gps_gpcon & mask;
+
+	__raw_writel(gpcon, con);
+}
+
+static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip)
+{
+	void __iomem *base = chip->base;
+	u32 old_gpcon[2];
+	u32 old_gpdat = __raw_readl(base + OFFS_DAT);
+	u32 gps_gpdat = chip->pm_save[2];
+
+	/* First, modify the CON settings */
+
+	old_gpcon[0] = 0;
+	old_gpcon[1] = __raw_readl(base + OFFS_CON);
+
+	s3c_gpio_pm_4bit_con(chip, 0);
+	if (chip->chip.ngpio > 8) {
+		old_gpcon[0] = __raw_readl(base - 4);
+		s3c_gpio_pm_4bit_con(chip, -1);
+	}
+
+	/* Now change the configurations that require DAT,CON */
+
+	__raw_writel(chip->pm_save[2], base + OFFS_DAT);
+	__raw_writel(chip->pm_save[1], base + OFFS_CON);
+	if (chip->chip.ngpio > 8)
+		__raw_writel(chip->pm_save[0], base - 4);
+
+	__raw_writel(chip->pm_save[2], base + OFFS_DAT);
+	__raw_writel(chip->pm_save[3], base + OFFS_UP);
+
+	if (chip->chip.ngpio > 8) {
+		S3C_PMDBG("%s: CON4 %08x,%08x => %08x,%08x, DAT %08x => %08x\n",
+			  chip->chip.label, old_gpcon[0], old_gpcon[1],
+			  __raw_readl(base - 4),
+			  __raw_readl(base + OFFS_CON),
+			  old_gpdat, gps_gpdat);
+	} else
+		S3C_PMDBG("%s: CON4 %08x => %08x, DAT %08x => %08x\n",
+			  chip->chip.label, old_gpcon[1],
+			  __raw_readl(base + OFFS_CON),
+			  old_gpdat, gps_gpdat);
+}
+
+struct s3c_gpio_pm s3c_gpio_pm_4bit = {
+	.save	= s3c_gpio_pm_4bit_save,
+	.resume = s3c_gpio_pm_4bit_resume,
+};
+#endif /* CONFIG_ARCH_S3C64XX */
+
+/**
+ * s3c_pm_save_gpio() - save gpio chip data for suspend
+ * @ourchip: The chip for suspend.
+ */
+static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip)
+{
+	struct s3c_gpio_pm *pm = ourchip->pm;
+
+	if (pm == NULL || pm->save == NULL)
+		S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
+	else
+		pm->save(ourchip);
+}
+
+/**
+ * s3c_pm_save_gpios() - Save the state of the GPIO banks.
+ *
+ * For all the GPIO banks, save the state of each one ready for going
+ * into a suspend mode.
+ */
+void s3c_pm_save_gpios(void)
+{
+	struct s3c_gpio_chip *ourchip;
+	unsigned int gpio_nr;
+
+	for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
+		ourchip = s3c_gpiolib_getchip(gpio_nr);
+		if (!ourchip)
+			continue;
+
+		s3c_pm_save_gpio(ourchip);
+
+		S3C_PMDBG("%s: save %08x,%08x,%08x,%08x\n",
+			  ourchip->chip.label,
+			  ourchip->pm_save[0],
+			  ourchip->pm_save[1],
+			  ourchip->pm_save[2],
+			  ourchip->pm_save[3]);
+
+		gpio_nr += ourchip->chip.ngpio;
+		gpio_nr += CONFIG_S3C_GPIO_SPACE;
+	}
+}
+
+/**
+ * s3c_pm_resume_gpio() - restore gpio chip data after suspend
+ * @ourchip: The suspended chip.
+ */
+static void s3c_pm_resume_gpio(struct s3c_gpio_chip *ourchip)
+{
+	struct s3c_gpio_pm *pm = ourchip->pm;
+
+	if (pm == NULL || pm->resume == NULL)
+		S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
+	else
+		pm->resume(ourchip);
+}
+
+void s3c_pm_restore_gpios(void)
+{
+	struct s3c_gpio_chip *ourchip;
+	unsigned int gpio_nr;
+
+	for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
+		ourchip = s3c_gpiolib_getchip(gpio_nr);
+		if (!ourchip)
+			continue;
+
+		s3c_pm_resume_gpio(ourchip);
+
+		gpio_nr += ourchip->chip.ngpio;
+		gpio_nr += CONFIG_S3C_GPIO_SPACE;
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/pwm.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/pwm.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/pwm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/pwm.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,446 @@
+/* arch/arm/plat-s3c/pwm.c
+ *
+ * Copyright (c) 2007 Ben Dooks
+ * Copyright (c) 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ *
+ * S3C series PWM device core
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pwm.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+#include <plat/regs-timer.h>
+
+struct pwm_device {
+	struct list_head	 list;
+	struct platform_device	*pdev;
+
+	struct clk		*clk_div;
+	struct clk		*clk;
+	const char		*label;
+
+	unsigned int		 period_ns;
+	unsigned int		 duty_ns;
+
+	unsigned char		 tcon_base;
+	unsigned char		 running;
+	unsigned char		 use_count;
+	unsigned char		 pwm_id;
+};
+
+#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
+
+static struct clk *clk_scaler[2];
+
+/* Standard setup for a timer block. */
+
+#define TIMER_RESOURCE_SIZE (1)
+
+#define TIMER_RESOURCE(_tmr, _irq)			\
+	(struct resource [TIMER_RESOURCE_SIZE]) {	\
+		[0] = {					\
+			.start	= _irq,			\
+			.end	= _irq,			\
+			.flags	= IORESOURCE_IRQ	\
+		}					\
+	}
+
+#define DEFINE_S3C_TIMER(_tmr_no, _irq)			\
+	.name		= "s3c24xx-pwm",		\
+	.id		= _tmr_no,			\
+	.num_resources	= TIMER_RESOURCE_SIZE,		\
+	.resource	= TIMER_RESOURCE(_tmr_no, _irq),	\
+
+/* since we already have an static mapping for the timer, we do not
+ * bother setting any IO resource for the base.
+ */
+
+struct platform_device s3c_device_timer[] = {
+	[0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
+	[1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
+	[2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
+	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
+	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
+};
+
+static inline int pwm_is_tdiv(struct pwm_device *pwm)
+{
+	return clk_get_parent(pwm->clk) == pwm->clk_div;
+}
+
+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, list) {
+		if (pwm->pwm_id == pwm_id) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (found) {
+		if (pwm->use_count == 0) {
+			pwm->use_count = 1;
+			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
+		printk(KERN_ERR "PWM%d device already freed\n", pwm->pwm_id);
+
+	mutex_unlock(&pwm_lock);
+}
+
+EXPORT_SYMBOL(pwm_free);
+
+#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
+#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
+#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
+#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
+
+int pwm_enable(struct pwm_device *pwm)
+{
+	unsigned long flags;
+	unsigned long tcon;
+
+	local_irq_save(flags);
+
+	tcon = __raw_readl(S3C2410_TCON);
+	tcon |= pwm_tcon_start(pwm);
+	__raw_writel(tcon, S3C2410_TCON);
+
+	local_irq_restore(flags);
+
+	pwm->running = 1;
+	return 0;
+}
+
+EXPORT_SYMBOL(pwm_enable);
+
+void pwm_disable(struct pwm_device *pwm)
+{
+	unsigned long flags;
+	unsigned long tcon;
+
+	local_irq_save(flags);
+
+	tcon = __raw_readl(S3C2410_TCON);
+	tcon &= ~pwm_tcon_start(pwm);
+	__raw_writel(tcon, S3C2410_TCON);
+
+	local_irq_restore(flags);
+
+	pwm->running = 0;
+}
+
+EXPORT_SYMBOL(pwm_disable);
+
+static unsigned long pwm_calc_tin(struct pwm_device *pwm, unsigned long freq)
+{
+	unsigned long tin_parent_rate;
+	unsigned int div;
+
+	tin_parent_rate = clk_get_rate(clk_get_parent(pwm->clk_div));
+	pwm_dbg(pwm, "tin parent at %lu\n", tin_parent_rate);
+
+	for (div = 2; div <= 16; div *= 2) {
+		if ((tin_parent_rate / (div << 16)) < freq)
+			return tin_parent_rate / div;
+	}
+
+	return tin_parent_rate / 16;
+}
+
+#define NS_IN_HZ (1000000000UL)
+
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+	unsigned long tin_rate;
+	unsigned long tin_ns;
+	unsigned long period;
+	unsigned long flags;
+	unsigned long tcon;
+	unsigned long tcnt;
+	long tcmp;
+
+	/* We currently avoid using 64bit arithmetic by using the
+	 * fact that anything faster than 1Hz is easily representable
+	 * by 32bits. */
+
+	if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
+		return -ERANGE;
+
+	if (duty_ns > period_ns)
+		return -EINVAL;
+
+	if (period_ns == pwm->period_ns &&
+	    duty_ns == pwm->duty_ns)
+		return 0;
+
+	/* The TCMP and TCNT can be read without a lock, they're not
+	 * shared between the timers. */
+
+	tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id));
+	tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id));
+
+	period = NS_IN_HZ / period_ns;
+
+	pwm_dbg(pwm, "duty_ns=%d, period_ns=%d (%lu)\n",
+		duty_ns, period_ns, period);
+
+	/* Check to see if we are changing the clock rate of the PWM */
+
+	if (pwm->period_ns != period_ns) {
+		if (pwm_is_tdiv(pwm)) {
+			tin_rate = pwm_calc_tin(pwm, period);
+			clk_set_rate(pwm->clk_div, tin_rate);
+		} else
+			tin_rate = clk_get_rate(pwm->clk);
+
+		pwm->period_ns = period_ns;
+
+		pwm_dbg(pwm, "tin_rate=%lu\n", tin_rate);
+
+		tin_ns = NS_IN_HZ / tin_rate;
+		tcnt = period_ns / tin_ns;
+	} else
+		tin_ns = NS_IN_HZ / clk_get_rate(pwm->clk);
+
+	/* Note, counters count down */
+
+	tcmp = duty_ns / tin_ns;
+	tcmp = tcnt - tcmp;
+	/* the pwm hw only checks the compare register after a decrement,
+	   so the pin never toggles if tcmp = tcnt */
+	if (tcmp == tcnt)
+		tcmp--;
+
+	pwm_dbg(pwm, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
+
+	if (tcmp < 0)
+		tcmp = 0;
+
+	/* Update the PWM register block. */
+
+	local_irq_save(flags);
+
+	__raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id));
+	__raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id));
+
+	tcon = __raw_readl(S3C2410_TCON);
+	tcon |= pwm_tcon_manulupdate(pwm);
+	tcon |= pwm_tcon_autoreload(pwm);
+	__raw_writel(tcon, S3C2410_TCON);
+
+	tcon &= ~pwm_tcon_manulupdate(pwm);
+	__raw_writel(tcon, S3C2410_TCON);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(pwm_config);
+
+static int pwm_register(struct pwm_device *pwm)
+{
+	pwm->duty_ns = -1;
+	pwm->period_ns = -1;
+
+	mutex_lock(&pwm_lock);
+	list_add_tail(&pwm->list, &pwm_list);
+	mutex_unlock(&pwm_lock);
+
+	return 0;
+}
+
+static int s3c_pwm_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct pwm_device *pwm;
+	unsigned long flags;
+	unsigned long tcon;
+	unsigned int id = pdev->id;
+	int ret;
+
+	if (id == 4) {
+		dev_err(dev, "TIMER4 is currently not supported\n");
+		return -ENXIO;
+	}
+
+	pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
+	if (pwm == NULL) {
+		dev_err(dev, "failed to allocate pwm_device\n");
+		return -ENOMEM;
+	}
+
+	pwm->pdev = pdev;
+	pwm->pwm_id = id;
+
+	/* calculate base of control bits in TCON */
+	pwm->tcon_base = id == 0 ? 0 : (id * 4) + 4;
+
+	pwm->clk = clk_get(dev, "pwm-tin");
+	if (IS_ERR(pwm->clk)) {
+		dev_err(dev, "failed to get pwm tin clk\n");
+		ret = PTR_ERR(pwm->clk);
+		goto err_alloc;
+	}
+
+	pwm->clk_div = clk_get(dev, "pwm-tdiv");
+	if (IS_ERR(pwm->clk_div)) {
+		dev_err(dev, "failed to get pwm tdiv clk\n");
+		ret = PTR_ERR(pwm->clk_div);
+		goto err_clk_tin;
+	}
+
+	local_irq_save(flags);
+
+	tcon = __raw_readl(S3C2410_TCON);
+	tcon |= pwm_tcon_invert(pwm);
+	__raw_writel(tcon, S3C2410_TCON);
+
+	local_irq_restore(flags);
+
+
+	ret = pwm_register(pwm);
+	if (ret) {
+		dev_err(dev, "failed to register pwm\n");
+		goto err_clk_tdiv;
+	}
+
+	pwm_dbg(pwm, "config bits %02x\n",
+		(__raw_readl(S3C2410_TCON) >> pwm->tcon_base) & 0x0f);
+
+	dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
+		 clk_get_rate(pwm->clk),
+		 clk_get_rate(pwm->clk_div),
+		 pwm_is_tdiv(pwm) ? "div" : "ext", pwm->tcon_base);
+
+	platform_set_drvdata(pdev, pwm);
+	return 0;
+
+ err_clk_tdiv:
+	clk_put(pwm->clk_div);
+
+ err_clk_tin:
+	clk_put(pwm->clk);
+
+ err_alloc:
+	kfree(pwm);
+	return ret;
+}
+
+static int __devexit s3c_pwm_remove(struct platform_device *pdev)
+{
+	struct pwm_device *pwm = platform_get_drvdata(pdev);
+
+	clk_put(pwm->clk_div);
+	clk_put(pwm->clk);
+	kfree(pwm);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct pwm_device *pwm = platform_get_drvdata(pdev);
+
+	/* No one preserve these values during suspend so reset them
+	 * Otherwise driver leaves PWM unconfigured if same values
+	 * passed to pwm_config
+	 */
+	pwm->period_ns = 0;
+	pwm->duty_ns = 0;
+
+	return 0;
+}
+
+static int s3c_pwm_resume(struct platform_device *pdev)
+{
+	struct pwm_device *pwm = platform_get_drvdata(pdev);
+	unsigned long tcon;
+
+	/* Restore invertion */
+	tcon = __raw_readl(S3C2410_TCON);
+	tcon |= pwm_tcon_invert(pwm);
+	__raw_writel(tcon, S3C2410_TCON);
+
+	return 0;
+}
+
+#else
+#define s3c_pwm_suspend NULL
+#define s3c_pwm_resume NULL
+#endif
+
+static struct platform_driver s3c_pwm_driver = {
+	.driver		= {
+		.name	= "s3c24xx-pwm",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= s3c_pwm_probe,
+	.remove		= __devexit_p(s3c_pwm_remove),
+	.suspend	= s3c_pwm_suspend,
+	.resume		= s3c_pwm_resume,
+};
+
+static int __init pwm_init(void)
+{
+	int ret;
+
+	clk_scaler[0] = clk_get(NULL, "pwm-scaler0");
+	clk_scaler[1] = clk_get(NULL, "pwm-scaler1");
+
+	if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
+		printk(KERN_ERR "%s: failed to get scaler clocks\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = platform_driver_register(&s3c_pwm_driver);
+	if (ret)
+		printk(KERN_ERR "%s: failed to add pwm driver\n", __func__);
+
+	return ret;
+}
+
+arch_initcall(pwm_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/pwm-clock.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/pwm-clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/pwm-clock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/pwm-clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,455 @@
+/* linux/arch/arm/plat-s3c24xx/pwm-clock.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ * Copyright (c) 2007, 2008 Ben Dooks
+ *	Ben Dooks <ben-linux@fluff.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.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/log2.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <asm/irq.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+#include <plat/regs-timer.h>
+#include <mach/pwm-clock.h>
+
+/* Each of the timers 0 through 5 go through the following
+ * clock tree, with the inputs depending on the timers.
+ *
+ * pclk ---- [ prescaler 0 ] -+---> timer 0
+ *			      +---> timer 1
+ *
+ * pclk ---- [ prescaler 1 ] -+---> timer 2
+ *			      +---> timer 3
+ *			      \---> timer 4
+ *
+ * Which are fed into the timers as so:
+ *
+ * prescaled 0 ---- [ div 2,4,8,16 ] ---\
+ *				       [mux] -> timer 0
+ * tclk 0 ------------------------------/
+ *
+ * prescaled 0 ---- [ div 2,4,8,16 ] ---\
+ *				       [mux] -> timer 1
+ * tclk 0 ------------------------------/
+ *
+ *
+ * prescaled 1 ---- [ div 2,4,8,16 ] ---\
+ *				       [mux] -> timer 2
+ * tclk 1 ------------------------------/
+ *
+ * prescaled 1 ---- [ div 2,4,8,16 ] ---\
+ *				       [mux] -> timer 3
+ * tclk 1 ------------------------------/
+ *
+ * prescaled 1 ---- [ div 2,4,8, 16 ] --\
+ *				       [mux] -> timer 4
+ * tclk 1 ------------------------------/
+ *
+ * Since the mux and the divider are tied together in the
+ * same register space, it is impossible to set the parent
+ * and the rate at the same time. To avoid this, we add an
+ * intermediate 'prescaled-and-divided' clock to select
+ * as the parent for the timer input clock called tdiv.
+ *
+ * prescaled clk --> pwm-tdiv ---\
+ *                             [ mux ] --> timer X
+ * tclk -------------------------/
+*/
+
+static struct clk clk_timer_scaler[];
+
+static unsigned long clk_pwm_scaler_get_rate(struct clk *clk)
+{
+	unsigned long tcfg0 = __raw_readl(S3C2410_TCFG0);
+
+	if (clk == &clk_timer_scaler[1]) {
+		tcfg0 &= S3C2410_TCFG_PRESCALER1_MASK;
+		tcfg0 >>= S3C2410_TCFG_PRESCALER1_SHIFT;
+	} else {
+		tcfg0 &= S3C2410_TCFG_PRESCALER0_MASK;
+	}
+
+	return clk_get_rate(clk->parent) / (tcfg0 + 1);
+}
+
+static unsigned long clk_pwm_scaler_round_rate(struct clk *clk,
+					       unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long divisor = parent_rate / rate;
+
+	if (divisor > 256)
+		divisor = 256;
+	else if (divisor < 2)
+		divisor = 2;
+
+	return parent_rate / divisor;
+}
+
+static int clk_pwm_scaler_set_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long round = clk_pwm_scaler_round_rate(clk, rate);
+	unsigned long tcfg0;
+	unsigned long divisor;
+	unsigned long flags;
+
+	divisor = clk_get_rate(clk->parent) / round;
+	divisor--;
+
+	local_irq_save(flags);
+	tcfg0 = __raw_readl(S3C2410_TCFG0);
+
+	if (clk == &clk_timer_scaler[1]) {
+		tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
+		tcfg0 |= divisor << S3C2410_TCFG_PRESCALER1_SHIFT;
+	} else {
+		tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
+		tcfg0 |= divisor;
+	}
+
+	__raw_writel(tcfg0, S3C2410_TCFG0);
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static struct clk_ops clk_pwm_scaler_ops = {
+	.get_rate	= clk_pwm_scaler_get_rate,
+	.set_rate	= clk_pwm_scaler_set_rate,
+	.round_rate	= clk_pwm_scaler_round_rate,
+};
+
+static struct clk clk_timer_scaler[] = {
+	[0]	= {
+		.name		= "pwm-scaler0",
+		.id		= -1,
+		.ops		= &clk_pwm_scaler_ops,
+	},
+	[1]	= {
+		.name		= "pwm-scaler1",
+		.id		= -1,
+		.ops		= &clk_pwm_scaler_ops,
+	},
+};
+
+static struct clk clk_timer_tclk[] = {
+	[0]	= {
+		.name		= "pwm-tclk0",
+		.id		= -1,
+	},
+	[1]	= {
+		.name		= "pwm-tclk1",
+		.id		= -1,
+	},
+};
+
+struct pwm_tdiv_clk {
+	struct clk	clk;
+	unsigned int	divisor;
+};
+
+static inline struct pwm_tdiv_clk *to_tdiv(struct clk *clk)
+{
+	return container_of(clk, struct pwm_tdiv_clk, clk);
+}
+
+static unsigned long clk_pwm_tdiv_get_rate(struct clk *clk)
+{
+	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+	unsigned int divisor;
+
+	tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
+	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+	if (pwm_cfg_src_is_tclk(tcfg1))
+		divisor = to_tdiv(clk)->divisor;
+	else
+		divisor = tcfg_to_divisor(tcfg1);
+
+	return clk_get_rate(clk->parent) / divisor;
+}
+
+static unsigned long clk_pwm_tdiv_round_rate(struct clk *clk,
+					     unsigned long rate)
+{
+	unsigned long parent_rate;
+	unsigned long divisor;
+
+	parent_rate = clk_get_rate(clk->parent);
+	divisor = parent_rate / rate;
+
+	if (divisor <= 1 && pwm_tdiv_has_div1())
+		divisor = 1;
+	else if (divisor <= 2)
+		divisor = 2;
+	else if (divisor <= 4)
+		divisor = 4;
+	else if (divisor <= 8)
+		divisor = 8;
+	else
+		divisor = 16;
+
+	return parent_rate / divisor;
+}
+
+static unsigned long clk_pwm_tdiv_bits(struct pwm_tdiv_clk *divclk)
+{
+	return pwm_tdiv_div_bits(divclk->divisor);
+}
+
+static void clk_pwm_tdiv_update(struct pwm_tdiv_clk *divclk)
+{
+	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+	unsigned long bits = clk_pwm_tdiv_bits(divclk);
+	unsigned long flags;
+	unsigned long shift =  S3C2410_TCFG1_SHIFT(divclk->clk.id);
+
+	local_irq_save(flags);
+
+	tcfg1 = __raw_readl(S3C2410_TCFG1);
+	tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
+	tcfg1 |= bits << shift;
+	__raw_writel(tcfg1, S3C2410_TCFG1);
+
+	local_irq_restore(flags);
+}
+
+static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate)
+{
+	struct pwm_tdiv_clk *divclk = to_tdiv(clk);
+	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long divisor;
+
+	tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
+	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+	rate = clk_round_rate(clk, rate);
+	divisor = parent_rate / rate;
+
+	if (divisor > 16)
+		return -EINVAL;
+
+	divclk->divisor = divisor;
+
+	/* Update the current MUX settings if we are currently
+	 * selected as the clock source for this clock. */
+
+	if (!pwm_cfg_src_is_tclk(tcfg1))
+		clk_pwm_tdiv_update(divclk);
+
+	return 0;
+}
+
+static struct clk_ops clk_tdiv_ops = {
+	.get_rate	= clk_pwm_tdiv_get_rate,
+	.set_rate	= clk_pwm_tdiv_set_rate,
+	.round_rate	= clk_pwm_tdiv_round_rate,
+};
+
+static struct pwm_tdiv_clk clk_timer_tdiv[] = {
+	[0]	= {
+		.clk	= {
+			.name	= "pwm-tdiv",
+			.ops	= &clk_tdiv_ops,
+			.parent	= &clk_timer_scaler[0],
+		},
+	},
+	[1]	= {
+		.clk	= {
+			.name	= "pwm-tdiv",
+			.ops	= &clk_tdiv_ops,
+			.parent	= &clk_timer_scaler[0],
+		}
+	},
+	[2]	= {
+		.clk	= {
+			.name	= "pwm-tdiv",
+			.ops	= &clk_tdiv_ops,
+			.parent	= &clk_timer_scaler[1],
+		},
+	},
+	[3]	= {
+		.clk	= {
+			.name	= "pwm-tdiv",
+			.ops	= &clk_tdiv_ops,
+			.parent	= &clk_timer_scaler[1],
+		},
+	},
+	[4]	= {
+		.clk	= {
+			.name	= "pwm-tdiv",
+			.ops	= &clk_tdiv_ops,
+			.parent	= &clk_timer_scaler[1],
+		},
+	},
+};
+
+static int __init clk_pwm_tdiv_register(unsigned int id)
+{
+	struct pwm_tdiv_clk *divclk = &clk_timer_tdiv[id];
+	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+
+	tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
+	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+	divclk->clk.id = id;
+	divclk->divisor = tcfg_to_divisor(tcfg1);
+
+	return s3c24xx_register_clock(&divclk->clk);
+}
+
+static inline struct clk *s3c24xx_pwmclk_tclk(unsigned int id)
+{
+	return (id >= 2) ? &clk_timer_tclk[1] : &clk_timer_tclk[0];
+}
+
+static inline struct clk *s3c24xx_pwmclk_tdiv(unsigned int id)
+{
+	return &clk_timer_tdiv[id].clk;
+}
+
+static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent)
+{
+	unsigned int id = clk->id;
+	unsigned long tcfg1;
+	unsigned long flags;
+	unsigned long bits;
+	unsigned long shift = S3C2410_TCFG1_SHIFT(id);
+
+	if (parent == s3c24xx_pwmclk_tclk(id))
+		bits = S3C_TCFG1_MUX_TCLK << shift;
+	else if (parent == s3c24xx_pwmclk_tdiv(id))
+		bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift;
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	local_irq_save(flags);
+
+	tcfg1 = __raw_readl(S3C2410_TCFG1);
+	tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
+	__raw_writel(tcfg1 | bits, S3C2410_TCFG1);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static struct clk_ops clk_tin_ops = {
+	.set_parent	= clk_pwm_tin_set_parent,
+};
+
+static struct clk clk_tin[] = {
+	[0]	= {
+		.name	= "pwm-tin",
+		.id	= 0,
+		.ops	= &clk_tin_ops,
+	},
+	[1]	= {
+		.name	= "pwm-tin",
+		.id	= 1,
+		.ops	= &clk_tin_ops,
+	},
+	[2]	= {
+		.name	= "pwm-tin",
+		.id	= 2,
+		.ops	= &clk_tin_ops,
+	},
+	[3]	= {
+		.name	= "pwm-tin",
+		.id	= 3,
+		.ops	= &clk_tin_ops,
+	},
+	[4]	= {
+		.name	= "pwm-tin",
+		.id	= 4,
+		.ops	= &clk_tin_ops,
+	},
+};
+
+static __init int clk_pwm_tin_register(struct clk *pwm)
+{
+	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+	unsigned int id = pwm->id;
+
+	struct clk *parent;
+	int ret;
+
+	ret = s3c24xx_register_clock(pwm);
+	if (ret < 0)
+		return ret;
+
+	tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
+	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+	if (pwm_cfg_src_is_tclk(tcfg1))
+		parent = s3c24xx_pwmclk_tclk(id);
+	else
+		parent = s3c24xx_pwmclk_tdiv(id);
+
+	return clk_set_parent(pwm, parent);
+}
+
+/**
+ * s3c_pwmclk_init() - initialise pwm clocks
+ *
+ * Initialise and register the clocks which provide the inputs for the
+ * pwm timer blocks.
+ *
+ * Note, this call is required by the time core, so must be called after
+ * the base clocks are added and before any of the initcalls are run.
+ */
+__init void s3c_pwmclk_init(void)
+{
+	struct clk *clk_timers;
+	unsigned int clk;
+	int ret;
+
+	clk_timers = clk_get(NULL, "timers");
+	if (IS_ERR(clk_timers)) {
+		printk(KERN_ERR "%s: no parent clock\n", __func__);
+		return;
+	}
+
+	for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++)
+		clk_timer_scaler[clk].parent = clk_timers;
+
+	s3c_register_clocks(clk_timer_scaler, ARRAY_SIZE(clk_timer_scaler));
+	s3c_register_clocks(clk_timer_tclk, ARRAY_SIZE(clk_timer_tclk));
+
+	for (clk = 0; clk < ARRAY_SIZE(clk_timer_tdiv); clk++) {
+		ret = clk_pwm_tdiv_register(clk);
+
+		if (ret < 0) {
+			printk(KERN_ERR "error adding pwm%d tdiv clock\n", clk);
+			return;
+		}
+	}
+
+	for (clk = 0; clk < ARRAY_SIZE(clk_tin); clk++) {
+		ret = clk_pwm_tin_register(&clk_tin[clk]);
+		if (ret < 0) {
+			printk(KERN_ERR "error adding pwm%d tin clock\n", clk);
+			return;
+		}
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/time.c linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/time.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/time.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-samsung/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,285 @@
+/* linux/arch/arm/plat-samsung/time.c
+ *
+ * Copyright (C) 2003-2005 Simtec Electronics
+ *	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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include <asm/system.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+
+#include <asm/irq.h>
+#include <mach/map.h>
+#include <plat/regs-timer.h>
+#include <mach/regs-irq.h>
+#include <asm/mach/time.h>
+#include <mach/tick.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+static unsigned long timer_startval;
+static unsigned long timer_usec_ticks;
+
+#ifndef TICK_MAX
+#define TICK_MAX (0xffff)
+#endif
+
+#define TIMER_USEC_SHIFT 16
+
+/* we use the shifted arithmetic to work out the ratio of timer ticks
+ * to usecs, as often the peripheral clock is not a nice even multiple
+ * of 1MHz.
+ *
+ * shift of 14 and 15 are too low for the 12MHz, 16 seems to be ok
+ * for the current HZ value of 200 without producing overflows.
+ *
+ * Original patch by Dimitry Andric, updated by Ben Dooks
+*/
+
+
+/* timer_mask_usec_ticks
+ *
+ * given a clock and divisor, make the value to pass into timer_ticks_to_usec
+ * to scale the ticks into usecs
+*/
+
+static inline unsigned long
+timer_mask_usec_ticks(unsigned long scaler, unsigned long pclk)
+{
+	unsigned long den = pclk / 1000;
+
+	return ((1000 << TIMER_USEC_SHIFT) * scaler + (den >> 1)) / den;
+}
+
+/* timer_ticks_to_usec
+ *
+ * convert timer ticks to usec.
+*/
+
+static inline unsigned long timer_ticks_to_usec(unsigned long ticks)
+{
+	unsigned long res;
+
+	res = ticks * timer_usec_ticks;
+	res += 1 << (TIMER_USEC_SHIFT - 4);	/* round up slightly */
+
+	return res >> TIMER_USEC_SHIFT;
+}
+
+/***
+ * Returns microsecond  since last clock interrupt.  Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ * IRQs are disabled before entering here from do_gettimeofday()
+ */
+
+static unsigned long s3c2410_gettimeoffset (void)
+{
+	unsigned long tdone;
+	unsigned long tval;
+
+	/* work out how many ticks have gone since last timer interrupt */
+
+	tval =  __raw_readl(S3C2410_TCNTO(4));
+	tdone = timer_startval - tval;
+
+	/* check to see if there is an interrupt pending */
+
+	if (s3c24xx_ostimer_pending()) {
+		/* re-read the timer, and try and fix up for the missed
+		 * interrupt. Note, the interrupt may go off before the
+		 * timer has re-loaded from wrapping.
+		 */
+
+		tval =  __raw_readl(S3C2410_TCNTO(4));
+		tdone = timer_startval - tval;
+
+		if (tval != 0)
+			tdone += timer_startval;
+	}
+
+	return timer_ticks_to_usec(tdone);
+}
+
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t
+s3c2410_timer_interrupt(int irq, void *dev_id)
+{
+	timer_tick();
+	return IRQ_HANDLED;
+}
+
+static struct irqaction s3c2410_timer_irq = {
+	.name		= "S3C2410 Timer Tick",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= s3c2410_timer_interrupt,
+};
+
+#define use_tclk1_12() ( \
+	machine_is_bast()	|| \
+	machine_is_vr1000()	|| \
+	machine_is_anubis()	|| \
+	machine_is_osiris())
+
+static struct clk *tin;
+static struct clk *tdiv;
+static struct clk *timerclk;
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ *
+ * Currently we only use timer4, as it is the only timer which has no
+ * other function that can be exploited externally
+ */
+static void s3c2410_timer_setup (void)
+{
+	unsigned long tcon;
+	unsigned long tcnt;
+	unsigned long tcfg1;
+	unsigned long tcfg0;
+
+	tcnt = TICK_MAX;  /* default value for tcnt */
+
+	/* configure the system for whichever machine is in use */
+
+	if (use_tclk1_12()) {
+		/* timer is at 12MHz, scaler is 1 */
+		timer_usec_ticks = timer_mask_usec_ticks(1, 12000000);
+		tcnt = 12000000 / HZ;
+
+		tcfg1 = __raw_readl(S3C2410_TCFG1);
+		tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
+		tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1;
+		__raw_writel(tcfg1, S3C2410_TCFG1);
+	} else {
+		unsigned long pclk;
+		struct clk *tscaler;
+
+		/* for the h1940 (and others), we use the pclk from the core
+		 * to generate the timer values. since values around 50 to
+		 * 70MHz are not values we can directly generate the timer
+		 * value from, we need to pre-scale and divide before using it.
+		 *
+		 * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz
+		 * (8.45 ticks per usec)
+		 */
+
+		pclk = clk_get_rate(timerclk);
+
+		/* configure clock tick */
+
+		timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
+
+		tscaler = clk_get_parent(tdiv);
+
+		clk_set_rate(tscaler, pclk / 3);
+		clk_set_rate(tdiv, pclk / 6);
+		clk_set_parent(tin, tdiv);
+
+		tcnt = clk_get_rate(tin) / HZ;
+	}
+
+	tcon = __raw_readl(S3C2410_TCON);
+	tcfg0 = __raw_readl(S3C2410_TCFG0);
+	tcfg1 = __raw_readl(S3C2410_TCFG1);
+
+	/* timers reload after counting zero, so reduce the count by 1 */
+
+	tcnt--;
+
+	printk(KERN_DEBUG "timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx, usec %08lx\n",
+	       tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks);
+
+	/* check to see if timer is within 16bit range... */
+	if (tcnt > TICK_MAX) {
+		panic("setup_timer: HZ is too small, cannot configure timer!");
+		return;
+	}
+
+	__raw_writel(tcfg1, S3C2410_TCFG1);
+	__raw_writel(tcfg0, S3C2410_TCFG0);
+
+	timer_startval = tcnt;
+	__raw_writel(tcnt, S3C2410_TCNTB(4));
+
+	/* ensure timer is stopped... */
+
+	tcon &= ~(7<<20);
+	tcon |= S3C2410_TCON_T4RELOAD;
+	tcon |= S3C2410_TCON_T4MANUALUPD;
+
+	__raw_writel(tcon, S3C2410_TCON);
+	__raw_writel(tcnt, S3C2410_TCNTB(4));
+	__raw_writel(tcnt, S3C2410_TCMPB(4));
+
+	/* start the timer running */
+	tcon |= S3C2410_TCON_T4START;
+	tcon &= ~S3C2410_TCON_T4MANUALUPD;
+	__raw_writel(tcon, S3C2410_TCON);
+}
+
+static void __init s3c2410_timer_resources(void)
+{
+	struct platform_device tmpdev;
+
+	tmpdev.dev.bus = &platform_bus_type;
+	tmpdev.id = 4;
+
+	timerclk = clk_get(NULL, "timers");
+	if (IS_ERR(timerclk))
+		panic("failed to get clock for system timer");
+
+	clk_enable(timerclk);
+
+	if (!use_tclk1_12()) {
+		tin = clk_get(&tmpdev.dev, "pwm-tin");
+		if (IS_ERR(tin))
+			panic("failed to get pwm-tin clock for system timer");
+
+		tdiv = clk_get(&tmpdev.dev, "pwm-tdiv");
+		if (IS_ERR(tdiv))
+			panic("failed to get pwm-tdiv clock for system timer");
+	}
+
+	clk_enable(tin);
+}
+
+static void __init s3c2410_timer_init(void)
+{
+	s3c2410_timer_resources();
+	s3c2410_timer_setup();
+	setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
+}
+
+struct sys_timer s3c24xx_timer = {
+	.init		= s3c2410_timer_init,
+	.offset		= s3c2410_gettimeoffset,
+	.resume		= s3c2410_timer_setup
+};
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-stmp3xxx/clock.c linux-libre-2.6.34-gnu1/arch/arm/plat-stmp3xxx/clock.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-stmp3xxx/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-stmp3xxx/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -1126,9 +1126,8 @@ static int __init clk_init(void)
 			if (ops && ops->set_parent)
 				ops->set_parent(cl->clk, cl->clk->parent);
 		}
-
-		clkdev_add(cl);
 	}
+	clkdev_add_table(onchip_clks, ARRAY_SIZE(onchip_clks));
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-stmp3xxx/dma.c linux-libre-2.6.34-gnu1/arch/arm/plat-stmp3xxx/dma.c
--- linux-libre-2.6.33-gnu1/arch/arm/plat-stmp3xxx/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-stmp3xxx/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
  * http://www.opensource.org/licenses/gpl-license.html
  * http://www.gnu.org/copyleft/gpl.html
  */
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/dmapool.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S linux-libre-2.6.34-gnu1/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S
--- linux-libre-2.6.33-gnu1/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
-		.macro	addruart,rx
+		.macro	addruart, rx, tmp
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #0x80000000	@ physical base address
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/plat-stmp3xxx/include/mach/vmalloc.h linux-libre-2.6.34-gnu1/arch/arm/plat-stmp3xxx/include/mach/vmalloc.h
--- linux-libre-2.6.33-gnu1/arch/arm/plat-stmp3xxx/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/plat-stmp3xxx/include/mach/vmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -9,4 +9,4 @@
  * http://www.opensource.org/licenses/gpl-license.html
  * http://www.gnu.org/copyleft/gpl.html
  */
-#define VMALLOC_END       (0xF0000000)
+#define VMALLOC_END       0xf0000000UL
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/tools/mach-types linux-libre-2.6.34-gnu1/arch/arm/tools/mach-types
--- linux-libre-2.6.33-gnu1/arch/arm/tools/mach-types	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/tools/mach-types	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Sat Feb 20 14:16:15 2010
+# Last update: Sat May 1 10:36:42 2010
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -2663,7 +2663,7 @@ reb01			MACH_REB01		REB01			2675
 aquila			MACH_AQUILA		AQUILA			2676
 spark_sls_hw2		MACH_SPARK_SLS_HW2	SPARK_SLS_HW2		2677
 sheeva_esata		MACH_ESATA_SHEEVAPLUG	ESATA_SHEEVAPLUG	2678
-surf7x30		MACH_SURF7X30		SURF7X30		2679
+msm7x30_surf		MACH_MSM7X30_SURF	MSM7X30_SURF		2679
 micro2440		MACH_MICRO2440		MICRO2440		2680
 am2440			MACH_AM2440		AM2440			2681
 tq2440			MACH_TQ2440		TQ2440			2682
@@ -2678,3 +2678,129 @@ vc088x			MACH_VC088X		VC088X			2690
 mioa702			MACH_MIOA702		MIOA702			2691
 hpmin			MACH_HPMIN		HPMIN			2692
 ak880xak		MACH_AK880XAK		AK880XAK		2693
+arm926tomap850		MACH_ARM926TOMAP850	ARM926TOMAP850		2694
+lkevm			MACH_LKEVM		LKEVM			2695
+mw6410			MACH_MW6410		MW6410			2696
+terastation_wxl		MACH_TERASTATION_WXL	TERASTATION_WXL		2697
+cpu8000e		MACH_CPU8000E		CPU8000E		2698
+catania			MACH_CATANIA		CATANIA			2699
+tokyo			MACH_TOKYO		TOKYO			2700
+msm7201a_surf		MACH_MSM7201A_SURF	MSM7201A_SURF		2701
+msm7201a_ffa		MACH_MSM7201A_FFA	MSM7201A_FFA		2702
+msm7x25_surf		MACH_MSM7X25_SURF	MSM7X25_SURF		2703
+msm7x25_ffa		MACH_MSM7X25_FFA	MSM7X25_FFA		2704
+msm7x27_surf		MACH_MSM7X27_SURF	MSM7X27_SURF		2705
+msm7x27_ffa		MACH_MSM7X27_FFA	MSM7X27_FFA		2706
+msm7x30_ffa		MACH_MSM7X30_FFA	MSM7X30_FFA		2707
+qsd8x50_surf		MACH_QSD8X50_SURF	QSD8X50_SURF		2708
+qsd8x50_comet		MACH_QSD8X50_COMET	QSD8X50_COMET		2709
+qsd8x50_ffa		MACH_QSD8X50_FFA	QSD8X50_FFA		2710
+qsd8x50a_surf		MACH_QSD8X50A_SURF	QSD8X50A_SURF		2711
+qsd8x50a_ffa		MACH_QSD8X50A_FFA	QSD8X50A_FFA		2712
+adx_xgcp10		MACH_ADX_XGCP10		ADX_XGCP10		2713
+mcgwumts2a		MACH_MCGWUMTS2A		MCGWUMTS2A		2714
+mobikt			MACH_MOBIKT		MOBIKT			2715
+mx53_evk		MACH_MX53_EVK		MX53_EVK		2716
+igep0030		MACH_IGEP0030		IGEP0030		2717
+axell_h40_h50_ctrl	MACH_AXELL_H40_H50_CTRL	AXELL_H40_H50_CTRL	2718
+dtcommod		MACH_DTCOMMOD		DTCOMMOD		2719
+gould			MACH_GOULD		GOULD			2720
+siberia			MACH_SIBERIA		SIBERIA			2721
+sbc3530			MACH_SBC3530		SBC3530			2722
+qarm			MACH_QARM		QARM			2723
+mips			MACH_MIPS		MIPS			2724
+mx27grb			MACH_MX27GRB		MX27GRB			2725
+sbc8100			MACH_SBC8100		SBC8100			2726
+saarb			MACH_SAARB		SAARB			2727
+omap3mini		MACH_OMAP3MINI		OMAP3MINI		2728
+cnmbook7se		MACH_CNMBOOK7SE		CNMBOOK7SE		2729
+catan			MACH_CATAN		CATAN			2730
+harmony			MACH_HARMONY		HARMONY			2731
+tonga			MACH_TONGA		TONGA			2732
+cybook_orizon		MACH_CYBOOK_ORIZON	CYBOOK_ORIZON		2733
+htcrhodiumcdma		MACH_HTCRHODIUMCDMA	HTCRHODIUMCDMA		2734
+epc_g45			MACH_EPC_G45		EPC_G45			2735
+epc_lpc3250		MACH_EPC_LPC3250	EPC_LPC3250		2736
+mxc91341evb		MACH_MXC91341EVB	MXC91341EVB		2737
+rtw1000			MACH_RTW1000		RTW1000			2738
+bobcat			MACH_BOBCAT		BOBCAT			2739
+trizeps6		MACH_TRIZEPS6		TRIZEPS6		2740
+msm7x30_fluid		MACH_MSM7X30_FLUID	MSM7X30_FLUID		2741
+nedap9263		MACH_NEDAP9263		NEDAP9263		2742
+netgear_ms2110		MACH_NETGEAR_MS2110	NETGEAR_MS2110		2743
+bmx			MACH_BMX		BMX			2744
+netstream		MACH_NETSTREAM		NETSTREAM		2745
+vpnext_rcu		MACH_VPNEXT_RCU		VPNEXT_RCU		2746
+vpnext_mpu		MACH_VPNEXT_MPU		VPNEXT_MPU		2747
+bcmring_tablet_v1	MACH_BCMRING_TABLET_V1	BCMRING_TABLET_V1	2748
+sgarm10			MACH_SGARM10		SGARM10			2749
+cm_t3517		MACH_CM_T3517		CM_T3517		2750
+omap3_cps		MACH_OMAP3_CPS		OMAP3_CPS		2751
+axar1500_receiver	MACH_AXAR1500_RECEIVER	AXAR1500_RECEIVER	2752
+wbd222			MACH_WBD222		WBD222			2753
+mt65xx			MACH_MT65XX		MT65XX			2754
+msm8x60_surf		MACH_MSM8X60_SURF	MSM8X60_SURF		2755
+msm8x60_sim		MACH_MSM8X60_SIM	MSM8X60_SIM		2756
+vmc300			MACH_VMC300		VMC300			2757
+tcc8000_sdk		MACH_TCC8000_SDK	TCC8000_SDK		2758
+nanos			MACH_NANOS		NANOS			2759
+stamp9g10		MACH_STAMP9G10		STAMP9G10		2760
+stamp9g45		MACH_STAMP9G45		STAMP9G45		2761
+h6053			MACH_H6053		H6053			2762
+smint01			MACH_SMINT01		SMINT01			2763
+prtlvt2			MACH_PRTLVT2		PRTLVT2			2764
+ap420			MACH_AP420		AP420			2765
+htcshift		MACH_HTCSHIFT		HTCSHIFT		2766
+davinci_dm365_fc	MACH_DAVINCI_DM365_FC	DAVINCI_DM365_FC	2767
+msm8x55_surf		MACH_MSM8X55_SURF	MSM8X55_SURF		2768
+msm8x55_ffa		MACH_MSM8X55_FFA	MSM8X55_FFA		2769
+esl_vamana		MACH_ESL_VAMANA		ESL_VAMANA		2770
+sbc35			MACH_SBC35		SBC35			2771
+mpx6446			MACH_MPX6446		MPX6446			2772
+oreo_controller		MACH_OREO_CONTROLLER	OREO_CONTROLLER		2773
+kopin_models		MACH_KOPIN_MODELS	KOPIN_MODELS		2774
+ttc_vision2		MACH_TTC_VISION2	TTC_VISION2		2775
+cns3420vb		MACH_CNS3420VB		CNS3420VB		2776
+lpc2			MACH_LPC2		LPC2			2777
+olympus			MACH_OLYMPUS		OLYMPUS			2778
+vortex			MACH_VORTEX		VORTEX			2779
+s5pc200			MACH_S5PC200		S5PC200			2780
+ecucore_9263		MACH_ECUCORE_9263	ECUCORE_9263		2781
+smdkc200		MACH_SMDKC200		SMDKC200		2782
+emsiso_sx27		MACH_EMSISO_SX27	EMSISO_SX27		2783
+apx_som9g45_ek		MACH_APX_SOM9G45_EK	APX_SOM9G45_EK		2784
+songshan		MACH_SONGSHAN		SONGSHAN		2785
+tianshan		MACH_TIANSHAN		TIANSHAN		2786
+vpx500			MACH_VPX500		VPX500			2787
+am3517sam		MACH_AM3517SAM		AM3517SAM		2788
+skat91_sim508		MACH_SKAT91_SIM508	SKAT91_SIM508		2789
+skat91_s3e		MACH_SKAT91_S3E		SKAT91_S3E		2790
+omap4_panda		MACH_OMAP4_PANDA	OMAP4_PANDA		2791
+df7220			MACH_DF7220		DF7220			2792
+nemini			MACH_NEMINI		NEMINI			2793
+t8200			MACH_T8200		T8200			2794
+apf51			MACH_APF51		APF51			2795
+dr_rc_unit		MACH_DR_RC_UNIT		DR_RC_UNIT		2796
+bordeaux		MACH_BORDEAUX		BORDEAUX		2797
+catania_b		MACH_CATANIA_B		CATANIA_B		2798
+mx51_ocean		MACH_MX51_OCEAN		MX51_OCEAN		2799
+ti8168evm		MACH_TI8168EVM		TI8168EVM		2800
+neocoreomap		MACH_NEOCOREOMAP	NEOCOREOMAP		2801
+withings_wbp		MACH_WITHINGS_WBP	WITHINGS_WBP		2802
+dbps			MACH_DBPS		DBPS			2803
+sbc9261			MACH_SBC9261		SBC9261			2804
+pcbfp0001		MACH_PCBFP0001		PCBFP0001		2805
+speedy			MACH_SPEEDY		SPEEDY			2806
+chrysaor		MACH_CHRYSAOR		CHRYSAOR		2807
+tango			MACH_TANGO		TANGO			2808
+synology_dsx11		MACH_SYNOLOGY_DSX11	SYNOLOGY_DSX11		2809
+hanlin_v3ext		MACH_HANLIN_V3EXT	HANLIN_V3EXT		2810
+hanlin_v5		MACH_HANLIN_V5		HANLIN_V5		2811
+hanlin_v3plus		MACH_HANLIN_V3PLUS	HANLIN_V3PLUS		2812
+iriver_story		MACH_IRIVER_STORY	IRIVER_STORY		2813
+irex_iliad		MACH_IREX_ILIAD		IREX_ILIAD		2814
+irex_dr1000		MACH_IREX_DR1000	IREX_DR1000		2815
+teton_bga		MACH_TETON_BGA		TETON_BGA		2816
+snapper9g45		MACH_SNAPPER9G45	SNAPPER9G45		2817
+tam3517			MACH_TAM3517		TAM3517			2818
+pdc100			MACH_PDC100		PDC100			2819
diff -druNp linux-libre-2.6.33-gnu1/arch/arm/vfp/vfpmodule.c linux-libre-2.6.34-gnu1/arch/arm/vfp/vfpmodule.c
--- linux-libre-2.6.33-gnu1/arch/arm/vfp/vfpmodule.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/arm/vfp/vfpmodule.c	2010-05-16 17:17:36.000000000 -0400
@@ -428,54 +428,60 @@ 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)
+void vfp_sync_hwstate(struct thread_info *thread)
 {
+	unsigned int cpu = get_cpu();
+
 	/*
-	 * 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.
+	 * If the thread we're interested in is the current owner of the
+	 * hardware VFP state, then we need to save its state.
 	 */
-	thread->vfpstate.hard.cpu = NR_CPUS;
+	if (last_VFP_context[cpu] == &thread->vfpstate) {
+		u32 fpexc = fmrx(FPEXC);
+
+		/*
+		 * Save the last VFP state on this CPU.
+		 */
+		fmxr(FPEXC, fpexc | FPEXC_EN);
+		vfp_save_state(&thread->vfpstate, fpexc | FPEXC_EN);
+		fmxr(FPEXC, fpexc);
+	}
+
+	put_cpu();
 }
-#else
-void vfp_sync_state(struct thread_info *thread)
+
+void vfp_flush_hwstate(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 the thread we're interested in is the current owner of the
+	 * hardware VFP state, then we need to save its state.
 	 */
-	if (fpexc & FPEXC_EN)
-		goto out;
+	if (last_VFP_context[cpu] == &thread->vfpstate) {
+		u32 fpexc = fmrx(FPEXC);
 
-	if (!last_VFP_context[cpu])
-		goto out;
+		fmxr(FPEXC, fpexc & ~FPEXC_EN);
 
-	/*
-	 * 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;
+	}
 
+#ifdef CONFIG_SMP
 	/*
-	 * Set the context to NULL to force a reload the next time the thread
-	 * uses the VFP.
+	 * For SMP we still have to take care of the case where the thread
+	 * migrates to another CPU and then back to the original CPU on which
+	 * the last VFP user is still the same thread. Mark the thread VFP
+	 * state as belonging to a non-existent CPU so that the saved one will
+	 * be reloaded in the above case.
 	 */
-	last_VFP_context[cpu] = NULL;
-
-out:
+	thread->vfpstate.hard.cpu = NR_CPUS;
+#endif
 	put_cpu();
 }
-#endif
 
 #include <linux/smp.h>
 
@@ -528,7 +534,7 @@ static int __init vfp_init(void)
 		 */
 		elf_hwcap |= HWCAP_VFP;
 #ifdef CONFIG_VFPv3
-		if (VFP_arch >= 3) {
+		if (VFP_arch >= 2) {
 			elf_hwcap |= HWCAP_VFPv3;
 
 			/*
diff -druNp linux-libre-2.6.33-gnu1/arch/avr32/include/asm/pgtable.h linux-libre-2.6.34-gnu1/arch/avr32/include/asm/pgtable.h
--- linux-libre-2.6.33-gnu1/arch/avr32/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/avr32/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -325,7 +325,7 @@ static inline pte_t pte_modify(pte_t pte
 
 struct vm_area_struct;
 extern void update_mmu_cache(struct vm_area_struct * vma,
-			     unsigned long address, pte_t pte);
+			     unsigned long address, pte_t *ptep);
 
 /*
  * Encode and decode a swap entry
diff -druNp linux-libre-2.6.33-gnu1/arch/avr32/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/avr32/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/avr32/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/avr32/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -124,6 +124,8 @@ struct pt_regs {
 
 #include <asm/ocd.h>
 
+#define arch_has_single_step()		(1)
+
 #define arch_ptrace_attach(child)       ocd_enable(child)
 
 #define user_mode(regs)                 (((regs)->sr & MODE_MASK) == MODE_USER)
diff -druNp linux-libre-2.6.33-gnu1/arch/avr32/kernel/process.c linux-libre-2.6.34-gnu1/arch/avr32/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/avr32/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/avr32/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/fs.h>
 #include <linux/pm.h>
 #include <linux/ptrace.h>
+#include <linux/slab.h>
 #include <linux/reboot.h>
 #include <linux/tick.h>
 #include <linux/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/avr32/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/avr32/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/avr32/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/avr32/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,9 +28,9 @@ static struct pt_regs *get_user_regs(str
 				  THREAD_SIZE - sizeof(struct pt_regs));
 }
 
-static void ptrace_single_step(struct task_struct *tsk)
+void user_enable_single_step(struct task_struct *tsk)
 {
-	pr_debug("ptrace_single_step: pid=%u, PC=0x%08lx, SR=0x%08lx\n",
+	pr_debug("user_enable_single_step: pid=%u, PC=0x%08lx, SR=0x%08lx\n",
 		 tsk->pid, task_pt_regs(tsk)->pc, task_pt_regs(tsk)->sr);
 
 	/*
@@ -49,6 +49,11 @@ static void ptrace_single_step(struct ta
 	set_tsk_thread_flag(tsk, TIF_SINGLE_STEP);
 }
 
+void user_disable_single_step(struct task_struct *child)
+{
+	/* XXX(hch): a no-op here seems wrong.. */
+}
+
 /*
  * Called by kernel/ptrace.c when detaching
  *
@@ -167,50 +172,6 @@ long arch_ptrace(struct task_struct *chi
 		ret = ptrace_write_user(child, addr, data);
 		break;
 
-	/* continue and stop at next (return from) syscall */
-	case PTRACE_SYSCALL:
-	/* restart after signal */
-	case PTRACE_CONT:
-		ret = -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;
-		/* XXX: Are we sure no breakpoints are active here? */
-		wake_up_process(child);
-		ret = 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:
-		ret = 0;
-		if (child->exit_state == EXIT_ZOMBIE)
-			break;
-		child->exit_code = SIGKILL;
-		wake_up_process(child);
-		break;
-
-	/*
-	 * execute single instruction.
-	 */
-	case PTRACE_SINGLESTEP:
-		ret = -EIO;
-		if (!valid_signal(data))
-			break;
-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		ptrace_single_step(child);
-		child->exit_code = data;
-		wake_up_process(child);
-		ret = 0;
-		break;
-
 	case PTRACE_GETREGS:
 		ret = ptrace_getregs(child, (void __user *)data);
 		break;
diff -druNp linux-libre-2.6.33-gnu1/arch/avr32/mach-at32ap/at32ap700x.c linux-libre-2.6.34-gnu1/arch/avr32/mach-at32ap/at32ap700x.c
--- linux-libre-2.6.33-gnu1/arch/avr32/mach-at32ap/at32ap700x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/avr32/mach-at32ap/at32ap700x.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/usb/atmel_usba_udc.h>
@@ -1770,10 +1771,13 @@ at32_add_device_usba(unsigned int id, st
 					  ARRAY_SIZE(usba0_resource)))
 		goto out_free_pdev;
 
-	if (data)
+	if (data) {
 		usba_data.pdata.vbus_pin = data->vbus_pin;
-	else
+		usba_data.pdata.vbus_pin_inverted = data->vbus_pin_inverted;
+	} else {
 		usba_data.pdata.vbus_pin = -EINVAL;
+		usba_data.pdata.vbus_pin_inverted = -EINVAL;
+	}
 
 	data = &usba_data.pdata;
 	data->num_ep = ARRAY_SIZE(at32_usba_ep);
diff -druNp linux-libre-2.6.33-gnu1/arch/avr32/mach-at32ap/extint.c linux-libre-2.6.34-gnu1/arch/avr32/mach-at32ap/extint.c
--- linux-libre-2.6.33-gnu1/arch/avr32/mach-at32ap/extint.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/avr32/mach-at32ap/extint.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/irq.h>
 #include <linux/platform_device.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/avr32/mach-at32ap/hsmc.c linux-libre-2.6.34-gnu1/arch/avr32/mach-at32ap/hsmc.c
--- linux-libre-2.6.33-gnu1/arch/avr32/mach-at32ap/hsmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/avr32/mach-at32ap/hsmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <mach/smc.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/avr32/mm/dma-coherent.c linux-libre-2.6.34-gnu1/arch/avr32/mm/dma-coherent.c
--- linux-libre-2.6.33-gnu1/arch/avr32/mm/dma-coherent.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/avr32/mm/dma-coherent.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <asm/addrspace.h>
 #include <asm/cacheflush.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/avr32/mm/init.c linux-libre-2.6.34-gnu1/arch/avr32/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/avr32/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/avr32/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/avr32/mm/ioremap.c linux-libre-2.6.34-gnu1/arch/avr32/mm/ioremap.c
--- linux-libre-2.6.33-gnu1/arch/avr32/mm/ioremap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/avr32/mm/ioremap.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/pgtable.h>
 #include <asm/addrspace.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/avr32/mm/tlb.c linux-libre-2.6.34-gnu1/arch/avr32/mm/tlb.c
--- linux-libre-2.6.33-gnu1/arch/avr32/mm/tlb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/avr32/mm/tlb.c	2010-05-16 17:17:36.000000000 -0400
@@ -101,7 +101,7 @@ static void update_dtlb(unsigned long ad
 }
 
 void update_mmu_cache(struct vm_area_struct *vma,
-		      unsigned long address, pte_t pte)
+		      unsigned long address, pte_t *ptep)
 {
 	unsigned long flags;
 
@@ -110,7 +110,7 @@ void update_mmu_cache(struct vm_area_str
 		return;
 
 	local_irq_save(flags);
-	update_dtlb(address, pte);
+	update_dtlb(address, *ptep);
 	local_irq_restore(flags);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/boot/Makefile linux-libre-2.6.34-gnu1/arch/blackfin/boot/Makefile
--- linux-libre-2.6.33-gnu1/arch/blackfin/boot/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/boot/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -8,14 +8,18 @@
 
 MKIMAGE := $(srctree)/scripts/mkuboot.sh
 
-targets := vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma
-extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma
+targets := vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma vmImage.xip
+extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.xip
+
+UIMAGE_OPTS-y :=
+UIMAGE_OPTS-$(CONFIG_RAMKERNEL) += -a $(CONFIG_BOOT_LOAD)
+UIMAGE_OPTS-$(CONFIG_ROMKERNEL) += -a $(CONFIG_ROM_BASE) -x
 
 quiet_cmd_uimage = UIMAGE  $@
       cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \
-                   -C $(2) -n '$(MACHINE)-$(KERNELRELEASE)' -a $(CONFIG_BOOT_LOAD) \
+                   -C $(2) -n '$(MACHINE)-$(KERNELRELEASE)' \
                    -e $(shell $(NM) vmlinux | awk '$$NF == "__start" {print $$1}') \
-                   -d $< $@
+                   $(UIMAGE_OPTS-y) -d $< $@
 
 $(obj)/vmlinux.bin: vmlinux FORCE
 	$(call if_changed,objcopy)
@@ -29,6 +33,12 @@ $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.b
 $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,lzma)
 
+# The mkimage tool wants 64bytes prepended to the image
+quiet_cmd_mk_bin_xip = BIN     $@
+      cmd_mk_bin_xip = ( printf '%64s' | tr ' ' '\377' ; cat $< ) > $@
+$(obj)/vmlinux.bin.xip: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,mk_bin_xip)
+
 $(obj)/vmImage.bin: $(obj)/vmlinux.bin
 	$(call if_changed,uimage,none)
 
@@ -41,10 +51,15 @@ $(obj)/vmImage.gz: $(obj)/vmlinux.bin.gz
 $(obj)/vmImage.lzma: $(obj)/vmlinux.bin.lzma
 	$(call if_changed,uimage,lzma)
 
+$(obj)/vmImage.xip: $(obj)/vmlinux.bin.xip
+	$(call if_changed,uimage,none)
+
 suffix-y                      := bin
 suffix-$(CONFIG_KERNEL_GZIP)  := gz
 suffix-$(CONFIG_KERNEL_BZIP2) := bz2
 suffix-$(CONFIG_KERNEL_LZMA)  := lzma
+suffix-$(CONFIG_ROMKERNEL)    := xip
+
 $(obj)/vmImage: $(obj)/vmImage.$(suffix-y)
 	@ln -sf $(notdir $<) $@
 
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF518F-EZBRD_defconfig linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF518F-EZBRD_defconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF518F-EZBRD_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF518F-EZBRD_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,22 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,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_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -101,7 +130,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_BF518=y
 # CONFIG_BF537 is not set
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=0
@@ -154,8 +182,8 @@ CONFIG_BF_REV_0_0=y
 # CONFIG_BF_REV_0_6 is not set
 # CONFIG_BF_REV_ANY is not set
 # CONFIG_BF_REV_NONE is not set
-CONFIG_BF51x=y
 CONFIG_MEM_MT48LC32M8A2_75=y
+CONFIG_BF51x=y
 CONFIG_BFIN518F_EZBRD=y
 
 #
@@ -313,7 +341,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -322,16 +349,18 @@ CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -342,7 +371,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -398,11 +427,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -426,7 +450,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -437,6 +460,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -450,7 +474,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -461,13 +488,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -488,6 +510,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
@@ -545,6 +568,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
 #
 # CONFIG_MTD_DATAFLASH is not set
 # CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -560,6 +584,11 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -576,10 +605,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT 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_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -614,6 +653,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
@@ -622,10 +664,14 @@ CONFIG_BFIN_MAC=y
 CONFIG_BFIN_TX_DESC_NUM=10
 CONFIG_BFIN_RX_DESC_NUM=20
 # CONFIG_BFIN_MAC_RMII is not set
+CONFIG_BFIN_MAC_USE_HWSTAMP=y
 # CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -634,15 +680,16 @@ CONFIG_BFIN_RX_DESC_NUM=20
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -677,7 +724,10 @@ CONFIG_INPUT=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_UINPUT is not set
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
@@ -688,16 +738,13 @@ CONFIG_INPUT_MISC=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 # CONFIG_BFIN_SPORT is not set
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
 CONFIG_VT=y
 CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
@@ -715,6 +762,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -726,12 +774,10 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
+CONFIG_BFIN_OTP=y
+# CONFIG_BFIN_OTP_WRITE_ENABLE is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -739,6 +785,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -771,14 +818,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -795,13 +834,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_SPI_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -817,6 +861,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -827,11 +872,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -853,28 +902,20 @@ 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
 # CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -912,10 +953,11 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_SPI is not set
 CONFIG_SDH_BFIN=m
 CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND=y
-# 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
 # CONFIG_ACCESSIBILITY is not set
@@ -950,6 +992,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -961,6 +1004,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
 # CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -981,10 +1025,21 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=m
@@ -994,9 +1049,13 @@ CONFIG_EXT2_FS=m
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1006,6 +1065,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
@@ -1027,13 +1091,9 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 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
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1042,8 +1102,8 @@ CONFIG_SYSFS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
-# CONFIG_YAFFS_FS is not set
 # CONFIG_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
@@ -1062,7 +1122,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1127,14 +1186,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1142,31 +1206,39 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1191,6 +1263,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1199,14 +1272,14 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 CONFIG_CRYPTO=y
 
 #
 # 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
@@ -1238,11 +1311,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1279,6 +1354,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1286,11 +1362,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1299,6 +1377,8 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF526-EZBRD_defconfig linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF526-EZBRD_defconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF526-EZBRD_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF526-EZBRD_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,22 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,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_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -101,7 +130,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_BF526=y
 # CONFIG_BF537 is not set
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=0
@@ -154,8 +182,7 @@ CONFIG_BF_REV_0_0=y
 # CONFIG_BF_REV_0_6 is not set
 # CONFIG_BF_REV_ANY is not set
 # CONFIG_BF_REV_NONE is not set
-CONFIG_BF52x=y
-CONFIG_MEM_MT48LC32M16A2TG_75=y
+CONFIG_MEM_MT48H32M16LFCJ_75=y
 CONFIG_IRQ_PLL_WAKEUP=7
 CONFIG_IRQ_DMA0_ERROR=7
 CONFIG_IRQ_DMAR0_BLK=7
@@ -200,7 +227,9 @@ CONFIG_IRQ_MEM_DMA1=13
 CONFIG_IRQ_WATCH=13
 CONFIG_IRQ_PORTF_INTA=13
 CONFIG_IRQ_PORTF_INTB=13
+CONFIG_BF52x=y
 # CONFIG_BFIN527_EZKIT is not set
+# CONFIG_BFIN527_EZKIT_V2 is not set
 # CONFIG_BFIN527_BLUETECHNIX_CM is not set
 CONFIG_BFIN526_EZBRD=y
 
@@ -318,7 +347,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -327,16 +355,18 @@ CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -347,6 +377,10 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
+# Asynchronous Memory Configuration
+#
+
+#
 # EBIU_AMGCTL Global Control
 #
 CONFIG_C_AMCKEN=y
@@ -399,11 +433,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -427,7 +456,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -438,6 +466,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -451,7 +480,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -462,13 +494,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -489,6 +516,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
@@ -549,6 +577,7 @@ CONFIG_MTD_PHYSMAP=y
 # CONFIG_MTD_DATAFLASH is not set
 CONFIG_MTD_M25P80=y
 CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -564,11 +593,6 @@ 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_BFIN=m
-CONFIG_BFIN_NAND_BASE=0x20212000
-CONFIG_BFIN_NAND_CLE=2
-CONFIG_BFIN_NAND_ALE=1
-CONFIG_BFIN_NAND_READY=3
 CONFIG_MTD_NAND_IDS=m
 # CONFIG_MTD_NAND_BF5XX is not set
 # CONFIG_MTD_NAND_DISKONCHIP is not set
@@ -578,6 +602,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
@@ -595,10 +624,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT 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_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -622,10 +661,6 @@ CONFIG_BLK_DEV_SR=m
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -642,6 +677,7 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
@@ -666,6 +702,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
@@ -675,9 +714,12 @@ CONFIG_BFIN_TX_DESC_NUM=10
 CONFIG_BFIN_RX_DESC_NUM=20
 CONFIG_BFIN_MAC_RMII=y
 # CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -686,15 +728,16 @@ CONFIG_BFIN_MAC_RMII=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # USB Network Adapters
@@ -744,7 +787,11 @@ CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_YEALINK is not set
 # CONFIG_INPUT_CM109 is not set
 # CONFIG_INPUT_UINPUT is not set
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_BFIN_ROTARY is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
@@ -755,16 +802,13 @@ CONFIG_INPUT_MISC=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 # CONFIG_BFIN_SPORT is not set
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
 CONFIG_VT=y
 CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
@@ -782,6 +826,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -793,14 +838,10 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_OTP=y
 # CONFIG_BFIN_OTP_WRITE_ENABLE is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -808,6 +849,7 @@ CONFIG_BFIN_OTP=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -841,14 +883,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -865,13 +899,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -887,6 +926,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -897,11 +937,20 @@ CONFIG_GPIO_SYSFS=y
 #
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_AD5252 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
 # CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADCXX is not set
@@ -914,11 +963,13 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
 # CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_F71882FG is not set
 # CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
 # CONFIG_SENSORS_GL518SM is not set
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
@@ -934,17 +985,24 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
 # CONFIG_SENSORS_MAX1111 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
@@ -954,9 +1012,8 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -983,28 +1040,20 @@ 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
 # CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -1026,7 +1075,6 @@ 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
 
 #
@@ -1039,30 +1087,35 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
-CONFIG_HID_BRIGHT=y
 CONFIG_HID_CHERRY=y
 CONFIG_HID_CHICONY=y
 CONFIG_HID_CYPRESS=y
-CONFIG_HID_DELL=y
+# CONFIG_HID_DRAGONRISE is not set
 CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
 CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
 CONFIG_HID_MICROSOFT=y
 CONFIG_HID_MONTEREY=y
+# CONFIG_HID_NTRIG is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
 CONFIG_HID_SUNPLUS=y
-CONFIG_THRUSTMASTER_FF=m
-CONFIG_ZEROPLUS_FF=m
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -1088,6 +1141,7 @@ CONFIG_USB_MON=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
 # CONFIG_USB_ISP1362_HCD is not set
@@ -1118,18 +1172,17 @@ CONFIG_USB_INVENTRA_DMA=y
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1165,7 +1218,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
@@ -1177,6 +1229,13 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+CONFIG_NOP_USB_XCEIV=y
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1212,6 +1271,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -1223,6 +1283,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
 # CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -1243,10 +1304,21 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=m
@@ -1256,9 +1328,13 @@ CONFIG_EXT2_FS=m
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1268,6 +1344,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
@@ -1291,13 +1372,9 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 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
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1316,17 +1393,8 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1345,7 +1413,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1360,7 +1427,7 @@ CONFIG_SMB_FS=m
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-CONFIG_NLS=m
+CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_NLS_CODEPAGE_437=m
 # CONFIG_NLS_CODEPAGE_737 is not set
@@ -1410,14 +1477,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1425,31 +1497,39 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1474,6 +1554,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1482,15 +1563,15 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 # CONFIG_SECURITY_ROOTPLUG is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 CONFIG_CRYPTO=y
 
 #
 # 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
@@ -1522,11 +1603,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1563,6 +1646,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1570,11 +1654,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1584,6 +1670,8 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF527-EZKIT_defconfig linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF527-EZKIT_defconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF527-EZKIT_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF527-EZKIT_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,22 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,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_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -101,7 +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_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -132,29 +160,28 @@ CONFIG_BF527=y
 # CONFIG_BF537 is not set
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=0
 CONFIG_BF_REV_MAX=2
 # CONFIG_BF_REV_0_0 is not set
-# CONFIG_BF_REV_0_1 is not set
-CONFIG_BF_REV_0_2=y
+CONFIG_BF_REV_0_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
 # CONFIG_BF_REV_0_5 is not set
 # CONFIG_BF_REV_0_6 is not set
 # CONFIG_BF_REV_ANY is not set
 # CONFIG_BF_REV_NONE is not set
-CONFIG_BF52x=y
 CONFIG_MEM_MT48LC32M16A2TG_75=y
 CONFIG_IRQ_PLL_WAKEUP=7
 CONFIG_IRQ_DMA0_ERROR=7
@@ -200,7 +227,9 @@ CONFIG_IRQ_MEM_DMA1=13
 CONFIG_IRQ_WATCH=13
 CONFIG_IRQ_PORTF_INTA=13
 CONFIG_IRQ_PORTF_INTB=13
+CONFIG_BF52x=y
 CONFIG_BFIN527_EZKIT=y
+# CONFIG_BFIN527_EZKIT_V2 is not set
 # CONFIG_BFIN527_BLUETECHNIX_CM is not set
 # CONFIG_BFIN526_EZBRD is not set
 
@@ -318,7 +347,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -327,16 +355,18 @@ CONFIG_BFIN_GPTIMERS=y
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -347,7 +377,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -403,11 +433,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -431,7 +456,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -442,6 +466,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -455,7 +480,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -508,13 +536,8 @@ CONFIG_SIR_BFIN_DMA=y
 # CONFIG_MCS_FIR is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_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
 
@@ -535,6 +558,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
@@ -593,6 +617,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
 # CONFIG_MTD_DATAFLASH is not set
 CONFIG_MTD_M25P80=y
 CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -608,11 +633,6 @@ 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_BFIN=m
-CONFIG_BFIN_NAND_BASE=0x20212000
-CONFIG_BFIN_NAND_CLE=2
-CONFIG_BFIN_NAND_ALE=1
-CONFIG_BFIN_NAND_READY=3
 CONFIG_MTD_NAND_IDS=m
 # CONFIG_MTD_NAND_BF5XX is not set
 # CONFIG_MTD_NAND_DISKONCHIP is not set
@@ -622,6 +642,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
@@ -639,10 +664,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT 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_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -666,10 +701,6 @@ CONFIG_BLK_DEV_SR=m
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -686,6 +717,7 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
@@ -710,6 +742,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
@@ -720,9 +755,12 @@ CONFIG_BFIN_TX_DESC_NUM=10
 CONFIG_BFIN_RX_DESC_NUM=20
 CONFIG_BFIN_MAC_RMII=y
 # CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -731,15 +769,16 @@ CONFIG_BFIN_MAC_RMII=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # USB Network Adapters
@@ -789,7 +828,11 @@ CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_YEALINK is not set
 # CONFIG_INPUT_CM109 is not set
 # CONFIG_INPUT_UINPUT is not set
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_BFIN_ROTARY is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
@@ -800,16 +843,13 @@ CONFIG_INPUT_MISC=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=m
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
 CONFIG_VT=y
 CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
@@ -827,6 +867,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -838,14 +879,10 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_OTP=y
 # CONFIG_BFIN_OTP_WRITE_ENABLE is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -853,6 +890,7 @@ CONFIG_BFIN_OTP=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -886,14 +924,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -910,13 +940,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -932,6 +967,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -942,11 +978,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -973,28 +1013,21 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -1030,15 +1063,18 @@ CONFIG_FB_BFIN_T350MCQB=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_LMS283GF05 is not set
 CONFIG_LCD_LTV350QV=m
 # 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_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=m
+# CONFIG_BACKLIGHT_ADP8870 is not set
 
 #
 # Display device support
@@ -1066,6 +1102,7 @@ CONFIG_SOUND=m
 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
@@ -1074,6 +1111,11 @@ CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
 CONFIG_SND_DRIVERS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_MTPAV is not set
@@ -1084,7 +1126,6 @@ CONFIG_SND_SPI=y
 #
 # ALSA Blackfin devices
 #
-# CONFIG_SND_BLACKFIN_AD1836 is not set
 # CONFIG_SND_BFIN_AD73322 is not set
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
@@ -1094,15 +1135,19 @@ 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_SOC_ADAU1371 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set
+# CONFIG_SND_BF5XX_TDM 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_HAVE_COLD_RESET is not set
+CONFIG_SND_BF5XX_SOC_AD1980=m
 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_I2C_AND_SPI=m
 # CONFIG_SND_SOC_ALL_CODECS is not set
 CONFIG_SND_SOC_AD1980=m
 CONFIG_SND_SOC_SSM2602=m
@@ -1110,7 +1155,6 @@ CONFIG_SND_SOC_SSM2602=m
 CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 
 #
@@ -1123,30 +1167,35 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
-CONFIG_HID_BRIGHT=y
 CONFIG_HID_CHERRY=y
 CONFIG_HID_CHICONY=y
 CONFIG_HID_CYPRESS=y
-CONFIG_HID_DELL=y
+# CONFIG_HID_DRAGONRISE is not set
 CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
 CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
 CONFIG_HID_MICROSOFT=y
 CONFIG_HID_MONTEREY=y
+# CONFIG_HID_NTRIG is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
 CONFIG_HID_SUNPLUS=y
-CONFIG_THRUSTMASTER_FF=m
-CONFIG_ZEROPLUS_FF=m
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -1172,6 +1221,7 @@ CONFIG_USB_MON=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
 # CONFIG_USB_ISP1362_HCD is not set
@@ -1188,9 +1238,7 @@ CONFIG_USB_MUSB_HOST=y
 # CONFIG_USB_MUSB_PERIPHERAL is not set
 # CONFIG_USB_MUSB_OTG 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_USB_MUSB_DEBUG is not set
 
 #
@@ -1202,18 +1250,17 @@ CONFIG_USB_INVENTRA_DMA=y
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1249,7 +1296,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
@@ -1261,6 +1307,13 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+CONFIG_NOP_USB_XCEIV=y
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1296,6 +1349,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -1307,6 +1361,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
 # CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -1327,10 +1382,21 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=m
@@ -1340,9 +1406,13 @@ CONFIG_EXT2_FS=m
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1352,6 +1422,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
@@ -1376,13 +1451,9 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 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
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1401,17 +1472,8 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1430,7 +1492,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1445,7 +1506,7 @@ CONFIG_SMB_FS=m
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-CONFIG_NLS=m
+CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_NLS_CODEPAGE_437=m
 # CONFIG_NLS_CODEPAGE_737 is not set
@@ -1495,14 +1556,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1510,31 +1576,39 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1559,6 +1633,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1567,15 +1642,15 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 # CONFIG_SECURITY_ROOTPLUG is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 CONFIG_CRYPTO=y
 
 #
 # 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
@@ -1607,11 +1682,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1648,6 +1725,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1655,11 +1733,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1669,6 +1749,8 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF527-EZKIT-V2_defconfig linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF527-EZKIT-V2_defconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF527-EZKIT-V2_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF527-EZKIT-V2_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1811 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32.2
+#
+# CONFIG_MMU is not set
+# CONFIG_FPU is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+CONFIG_EPOLL=y
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF 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=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+# CONFIG_FREEZER is not set
+
+#
+# Blackfin Processor Options
+#
+
+#
+# Processor and Board Settings
+#
+# CONFIG_BF512 is not set
+# CONFIG_BF514 is not set
+# CONFIG_BF516 is not set
+# CONFIG_BF518 is not set
+# CONFIG_BF522 is not set
+# CONFIG_BF523 is not set
+# CONFIG_BF524 is not set
+# CONFIG_BF525 is not set
+# CONFIG_BF526 is not set
+CONFIG_BF527=y
+# CONFIG_BF531 is not set
+# CONFIG_BF532 is not set
+# CONFIG_BF533 is not set
+# CONFIG_BF534 is not set
+# CONFIG_BF536 is not set
+# CONFIG_BF537 is not set
+# CONFIG_BF538 is not set
+# CONFIG_BF539 is not set
+# CONFIG_BF542_std is not set
+# CONFIG_BF542M is not set
+# CONFIG_BF544_std is not set
+# CONFIG_BF544M is not set
+# CONFIG_BF547_std is not set
+# CONFIG_BF547M is not set
+# CONFIG_BF548_std is not set
+# CONFIG_BF548M is not set
+# CONFIG_BF549_std is not set
+# CONFIG_BF549M is not set
+# CONFIG_BF561 is not set
+CONFIG_BF_REV_MIN=0
+CONFIG_BF_REV_MAX=2
+# CONFIG_BF_REV_0_0 is not set
+# CONFIG_BF_REV_0_1 is not set
+CONFIG_BF_REV_0_2=y
+# CONFIG_BF_REV_0_3 is not set
+# CONFIG_BF_REV_0_4 is not set
+# CONFIG_BF_REV_0_5 is not set
+# CONFIG_BF_REV_0_6 is not set
+# CONFIG_BF_REV_ANY is not set
+# CONFIG_BF_REV_NONE is not set
+CONFIG_MEM_MT48LC32M16A2TG_75=y
+CONFIG_IRQ_PLL_WAKEUP=7
+CONFIG_IRQ_DMA0_ERROR=7
+CONFIG_IRQ_DMAR0_BLK=7
+CONFIG_IRQ_DMAR1_BLK=7
+CONFIG_IRQ_DMAR0_OVR=7
+CONFIG_IRQ_DMAR1_OVR=7
+CONFIG_IRQ_PPI_ERROR=7
+CONFIG_IRQ_MAC_ERROR=7
+CONFIG_IRQ_SPORT0_ERROR=7
+CONFIG_IRQ_SPORT1_ERROR=7
+CONFIG_IRQ_UART0_ERROR=7
+CONFIG_IRQ_UART1_ERROR=7
+CONFIG_IRQ_RTC=8
+CONFIG_IRQ_PPI=8
+CONFIG_IRQ_SPORT0_RX=9
+CONFIG_IRQ_SPORT0_TX=9
+CONFIG_IRQ_SPORT1_RX=9
+CONFIG_IRQ_SPORT1_TX=9
+CONFIG_IRQ_TWI=10
+CONFIG_IRQ_UART0_RX=10
+CONFIG_IRQ_UART0_TX=10
+CONFIG_IRQ_UART1_RX=10
+CONFIG_IRQ_UART1_TX=10
+CONFIG_IRQ_OPTSEC=11
+CONFIG_IRQ_CNT=11
+CONFIG_IRQ_MAC_RX=11
+CONFIG_IRQ_PORTH_INTA=11
+CONFIG_IRQ_MAC_TX=11
+CONFIG_IRQ_PORTH_INTB=11
+CONFIG_IRQ_TIMER0=8
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
+CONFIG_IRQ_PORTG_INTA=12
+CONFIG_IRQ_PORTG_INTB=12
+CONFIG_IRQ_MEM_DMA0=13
+CONFIG_IRQ_MEM_DMA1=13
+CONFIG_IRQ_WATCH=13
+CONFIG_IRQ_PORTF_INTA=13
+CONFIG_IRQ_PORTF_INTB=13
+CONFIG_BF52x=y
+# CONFIG_BFIN527_EZKIT is not set
+CONFIG_BFIN527_EZKIT_V2=y
+# CONFIG_BFIN527_BLUETECHNIX_CM is not set
+# CONFIG_BFIN526_EZBRD is not set
+
+#
+# BF527 Specific Configuration
+#
+
+#
+# Alternative Multiplexing Scheme
+#
+# CONFIG_BF527_SPORT0_PORTF is not set
+CONFIG_BF527_SPORT0_PORTG=y
+CONFIG_BF527_SPORT0_TSCLK_PG10=y
+# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set
+CONFIG_BF527_UART1_PORTF=y
+# CONFIG_BF527_UART1_PORTG is not set
+# CONFIG_BF527_NAND_D_PORTF is not set
+CONFIG_BF527_NAND_D_PORTH=y
+
+#
+# Interrupt Priority Assignment
+#
+
+#
+# Priority
+#
+CONFIG_IRQ_SPI=10
+CONFIG_IRQ_SPI_ERROR=7
+CONFIG_IRQ_NFC_ERROR=7
+CONFIG_IRQ_HDMA_ERROR=7
+CONFIG_IRQ_HDMA=7
+CONFIG_IRQ_USB_EINT=10
+CONFIG_IRQ_USB_INT0=11
+CONFIG_IRQ_USB_INT1=11
+CONFIG_IRQ_USB_INT2=11
+CONFIG_IRQ_USB_DMA=11
+
+#
+# Board customizations
+#
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_BOOT_LOAD=0x1000
+
+#
+# Clock/PLL Setup
+#
+CONFIG_CLKIN_HZ=25000000
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=600000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133333333
+CONFIG_MIN_SCLK_HZ=27000000
+
+#
+# Kernel Timer/Scheduler
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_TICKSOURCE_GPTMR0 is not set
+CONFIG_TICKSOURCE_CORETMR=y
+# CONFIG_CYCLES_CLOCKSOURCE is not set
+# CONFIG_GPTMR0_CLOCKSOURCE is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# Misc
+#
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
+#
+# Memory Optimizations
+#
+CONFIG_I_ENTRY_L1=y
+CONFIG_EXCPT_IRQ_SYSC_L1=y
+CONFIG_DO_IRQ_L1=y
+CONFIG_CORE_TIMER_IRQ_L1=y
+CONFIG_IDLE_L1=y
+# CONFIG_SCHEDULE_L1 is not set
+CONFIG_ARITHMETIC_OPS_L1=y
+CONFIG_ACCESS_OK_L1=y
+# CONFIG_MEMSET_L1 is not set
+# CONFIG_MEMCPY_L1 is not set
+# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set
+# CONFIG_IP_CHECKSUM_L1 is not set
+CONFIG_CACHELINE_ALIGNED_L1=y
+# CONFIG_SYSCALL_TAB_L1 is not set
+# CONFIG_CPLB_SWITCH_TAB_L1 is not set
+CONFIG_APP_STACK_L1=y
+
+#
+# Speed Optimizations
+#
+CONFIG_BFIN_INS_LOWOVERHEAD=y
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
+CONFIG_BFIN_GPTIMERS=y
+# CONFIG_DMA_UNCACHED_4M is not set
+# CONFIG_DMA_UNCACHED_2M is not set
+CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
+# CONFIG_DMA_UNCACHED_NONE is not set
+
+#
+# Cache Support
+#
+CONFIG_BFIN_ICACHE=y
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+CONFIG_BFIN_EXTMEM_DCACHEABLE=y
+CONFIG_BFIN_EXTMEM_WRITEBACK=y
+# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
+
+#
+# Memory Protection Unit
+#
+# CONFIG_MPU is not set
+
+#
+# Asynchronous Memory Configuration
+#
+
+#
+# EBIU_AMGCTL Global Control
+#
+CONFIG_C_AMCKEN=y
+CONFIG_C_CDPRIO=y
+# CONFIG_C_AMBEN is not set
+# CONFIG_C_AMBEN_B0 is not set
+# CONFIG_C_AMBEN_B0_B1 is not set
+# CONFIG_C_AMBEN_B0_B1_B2 is not set
+CONFIG_C_AMBEN_ALL=y
+
+#
+# EBIU_AMBCTL Control
+#
+CONFIG_BANK_0=0x7BB0
+CONFIG_BANK_1=0x7BB0
+CONFIG_BANK_2=0x7BB0
+CONFIG_BANK_3=0x99B2
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF_FDPIC=y
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_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 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_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+CONFIG_BFIN_SIR=m
+CONFIG_BFIN_SIR0=y
+CONFIG_SIR_BFIN_DMA=y
+# CONFIG_SIR_BFIN_PIO is not set
+
+#
+# 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_MCS_FIR is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+CONFIG_MTD_JEDECPROBE=m
+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 is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=m
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_GPIO_ADDR is not set
+# CONFIG_MTD_UCLINUX is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=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_IDS=m
+# CONFIG_MTD_NAND_BF5XX is not set
+# 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 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=y
+# CONFIG_AD525X_DPOT 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_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA 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_BFIN_MAC=y
+CONFIG_BFIN_MAC_USE_L1=y
+CONFIG_BFIN_TX_DESC_NUM=10
+CONFIG_BFIN_RX_DESC_NUM=20
+CONFIG_BFIN_MAC_RMII=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN 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 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_ADP5520=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD 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=y
+CONFIG_TOUCHSCREEN_AD7879=y
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_WM97XX 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 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_BFIN_ROTARY is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_BFIN_DMA_INTERFACE=m
+# CONFIG_BFIN_PPI is not set
+# CONFIG_BFIN_PPIFCD is not set
+# CONFIG_BFIN_SIMPLE_TIMER is not set
+# CONFIG_BFIN_SPI_ADC is not set
+CONFIG_BFIN_SPORT=m
+# CONFIG_BFIN_TWI_LCD is not set
+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_BFIN_JTAG_COMM=m
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+CONFIG_SERIAL_BFIN_DMA=y
+# CONFIG_SERIAL_BFIN_PIO is not set
+# CONFIG_SERIAL_BFIN_UART0 is not set
+CONFIG_SERIAL_BFIN_UART1=y
+# CONFIG_BFIN_UART1_CTSRTS is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_BFIN_SPORT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_BFIN_OTP=y
+# CONFIG_BFIN_OTP_WRITE_ENABLE 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_COMPAT=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_BLACKFIN_TWI=y
+CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
+# 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_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BFIN=y
+# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+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_ADP5520 is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_BFIN_WDT=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+CONFIG_PMIC_ADP5520=y
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_BFIN_T350MCQB is not set
+CONFIG_FB_BFIN_LQ035Q1=y
+# CONFIG_FB_BFIN_7393 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=m
+# CONFIG_LCD_LMS283GF05 is not set
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_TDO24M is not set
+# CONFIG_LCD_VGG2432A4 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_GENERIC=m
+# CONFIG_BACKLIGHT_ADP5520 is not set
+# CONFIG_BACKLIGHT_ADP8870 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 is not set
+# CONFIG_LOGO_BLACKFIN_VGA16 is not set
+CONFIG_LOGO_BLACKFIN_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_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_SPI=y
+
+#
+# ALSA Blackfin devices
+#
+# 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_SOC_ADAU1371 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set
+# CONFIG_SND_BF5XX_TDM 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_HAVE_COLD_RESET is not set
+CONFIG_SND_BF5XX_SOC_AD1980=m
+CONFIG_SND_BF5XX_SOC_SPORT=m
+CONFIG_SND_BF5XX_SOC_I2S=m
+CONFIG_SND_BF5XX_SOC_AC97=m
+CONFIG_SND_BF5XX_SPORT_NUM=0
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# 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_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+# CONFIG_HID_DRAGONRISE is not set
+CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
+CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+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_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# 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_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+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_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# 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_MUSB_HDRC_HCD=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST 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_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+CONFIG_NOP_USB_XCEIV=y
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
+CONFIG_LEDS_ADP5520=y
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_BFIN=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# 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_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# 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_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 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=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=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 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 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=m
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_VERBOSE=y
+CONFIG_DEBUG_MMRS=y
+CONFIG_DEBUG_HWERR=y
+CONFIG_EXACT_HWERR=y
+CONFIG_DEBUG_DOUBLEFAULT=y
+CONFIG_DEBUG_DOUBLEFAULT_PRINT=y
+# CONFIG_DEBUG_DOUBLEFAULT_RESET is not set
+# CONFIG_DEBUG_ICACHE_CHECK is not set
+CONFIG_DEBUG_HUNT_FOR_ZERO=y
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=1
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
+CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CPLB_INFO=y
+CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_TOMOYO is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+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.33-gnu1/arch/blackfin/configs/BF533-EZKIT_defconfig linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF533-EZKIT_defconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF533-EZKIT_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF533-EZKIT_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,22 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,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_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -101,7 +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_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_BF533=y
 # CONFIG_BF537 is not set
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=3
@@ -228,7 +256,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_TICKSOURCE_GPTMR0 is not set
 CONFIG_TICKSOURCE_CORETMR=y
-# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_CYCLES_CLOCKSOURCE=y
 # CONFIG_GPTMR0_CLOCKSOURCE is not set
 CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
@@ -280,7 +308,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -289,19 +316,18 @@ CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
 # Cache Support
 #
-#
-# Cache Support
-#
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -312,7 +338,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -358,6 +384,7 @@ CONFIG_PM=y
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_PM_BFIN_SLEEP_DEEPER=y
 # CONFIG_PM_BFIN_SLEEP is not set
@@ -379,11 +406,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -407,7 +429,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -418,6 +439,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -431,7 +453,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -475,13 +500,8 @@ CONFIG_IRTTY_SIR=m
 #
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -502,6 +522,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
@@ -559,6 +580,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
 #
 # CONFIG_MTD_DATAFLASH is not set
 # CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -574,6 +596,11 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -590,9 +617,14 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -616,9 +648,12 @@ CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_SMC91X=y
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -627,15 +662,16 @@ CONFIG_SMC91X=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -679,15 +715,12 @@ CONFIG_INPUT_EVDEV=m
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=y
-# CONFIG_BFIN_TIMER_LATENCY is not set
-CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_BFIN_JTAG_COMM=m
@@ -701,6 +734,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -711,12 +745,8 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -734,13 +764,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -753,9 +788,6 @@ CONFIG_GPIO_SYSFS=y
 #
 # I2C GPIO expanders:
 #
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_PCA953X is not set
-# CONFIG_GPIO_PCF857X is not set
 
 #
 # PCI GPIO expanders:
@@ -766,11 +798,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -793,23 +829,10 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_EZX_PCAP is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -826,14 +849,12 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
-# 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 is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -864,6 +885,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
 # CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -884,10 +906,20 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
@@ -896,9 +928,13 @@ CONFIG_RTC_DRV_BFIN=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -908,6 +944,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
@@ -926,13 +967,9 @@ CONFIG_INOTIFY_USER=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -951,17 +988,8 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -980,7 +1008,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1045,14 +1072,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1060,31 +1092,39 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1109,6 +1149,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1117,14 +1158,14 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 CONFIG_CRYPTO=y
 
 #
 # 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
@@ -1156,11 +1197,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1197,6 +1240,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1204,11 +1248,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1218,6 +1264,8 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF533-STAMP_defconfig linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF533-STAMP_defconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF533-STAMP_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF533-STAMP_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,22 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,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_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -101,7 +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_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_BF533=y
 # CONFIG_BF537 is not set
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=3
@@ -228,7 +256,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_TICKSOURCE_GPTMR0 is not set
 CONFIG_TICKSOURCE_CORETMR=y
-# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_CYCLES_CLOCKSOURCE=y
 # CONFIG_GPTMR0_CLOCKSOURCE is not set
 CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
@@ -280,7 +308,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -289,16 +316,18 @@ CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -309,7 +338,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -355,6 +384,7 @@ CONFIG_PM=y
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_PM_BFIN_SLEEP_DEEPER=y
 # CONFIG_PM_BFIN_SLEEP is not set
@@ -376,11 +406,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -404,7 +429,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -415,6 +439,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -428,7 +453,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -474,13 +502,8 @@ CONFIG_SIR_BFIN_DMA=y
 #
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -501,6 +524,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
@@ -560,6 +584,7 @@ CONFIG_MTD_BFIN_ASYNC=m
 #
 # CONFIG_MTD_DATAFLASH is not set
 # CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -575,6 +600,11 @@ CONFIG_MTD_BFIN_ASYNC=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
@@ -591,10 +621,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT 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_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -618,9 +658,12 @@ CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_SMC91X=y
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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,15 +672,16 @@ CONFIG_SMC91X=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -672,7 +716,10 @@ CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_TOUCHSCREEN is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_UINPUT is not set
-CONFIG_CONFIG_INPUT_PCF8574=m
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
@@ -683,16 +730,13 @@ CONFIG_CONFIG_INPUT_PCF8574=m
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=m
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_BFIN_JTAG_COMM=m
@@ -706,6 +750,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -716,12 +761,8 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -729,6 +770,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -759,14 +801,6 @@ CONFIG_I2C_HELPER_AUTO=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -783,13 +817,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -805,6 +844,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -815,11 +855,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -841,26 +885,18 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -904,6 +940,7 @@ CONFIG_ADV7393_1XMEM=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
 
 #
@@ -913,19 +950,27 @@ CONFIG_ADV7393_1XMEM=y
 # CONFIG_LOGO is not set
 CONFIG_SOUND=m
 CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
+CONFIG_SND_JACK=y
 # CONFIG_SND_SEQUENCER is not set
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
 CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_HRTIMER is not set
 # CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
 CONFIG_SND_DRIVERS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_MTPAV is not set
@@ -936,13 +981,6 @@ CONFIG_SND_SPI=y
 #
 # ALSA Blackfin devices
 #
-CONFIG_SND_BLACKFIN_AD1836=m
-CONFIG_SND_BLACKFIN_AD1836_TDM=y
-# CONFIG_SND_BLACKFIN_AD1836_I2S is not set
-CONFIG_SND_BLACKFIN_AD1836_MULSUB=y
-# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set
-CONFIG_SND_BLACKFIN_SPORT=0
-CONFIG_SND_BLACKFIN_SPI_PFBIT=4
 CONFIG_SND_BFIN_SPORT=0
 CONFIG_SND_BFIN_AD73322=m
 CONFIG_SND_BFIN_AD73322_SPORT0_SE=10
@@ -953,16 +991,20 @@ CONFIG_SND_SOC_AC97_BUS=y
 CONFIG_SND_BF5XX_I2S=m
 # CONFIG_SND_BF5XX_SOC_SSM2602 is not set
 CONFIG_SND_BF5XX_SOC_AD73311=m
+# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set
 CONFIG_SND_BFIN_AD73311_SE=4
+# CONFIG_SND_BF5XX_TDM 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_HAVE_COLD_RESET is not set
+CONFIG_SND_BF5XX_SOC_AD1980=m
 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_I2C_AND_SPI=m
 # CONFIG_SND_SOC_ALL_CODECS is not set
 CONFIG_SND_SOC_AD1980=m
 CONFIG_SND_SOC_AD73311=m
@@ -970,14 +1012,12 @@ CONFIG_SND_SOC_AD73311=m
 CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 # CONFIG_HID_PID is not set
 
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1014,6 +1054,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -1025,6 +1066,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
 # CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -1045,10 +1087,21 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
@@ -1057,9 +1110,13 @@ CONFIG_RTC_DRV_BFIN=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1069,6 +1126,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
@@ -1087,13 +1149,9 @@ CONFIG_INOTIFY_USER=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1112,17 +1170,8 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1141,7 +1190,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1206,14 +1254,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1221,31 +1274,39 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1270,6 +1331,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1278,14 +1340,14 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 CONFIG_CRYPTO=y
 
 #
 # 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
@@ -1317,11 +1379,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1358,6 +1422,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1365,11 +1430,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1379,6 +1446,8 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF537-STAMP_defconfig linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF537-STAMP_defconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF537-STAMP_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF537-STAMP_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,22 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,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_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -101,7 +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_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_FREEZER=y
 CONFIG_BF537=y
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=2
@@ -184,7 +212,8 @@ CONFIG_IRQ_MEM_DMA1=13
 CONFIG_IRQ_WATCH=13
 CONFIG_IRQ_SPI=10
 CONFIG_BFIN537_STAMP=y
-# CONFIG_BFIN537_BLUETECHNIX_CM is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM_E is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM_U is not set
 # CONFIG_BFIN537_BLUETECHNIX_TCM is not set
 # CONFIG_PNAV10 is not set
 # CONFIG_CAMSIG_MINOTAUR is not set
@@ -235,7 +264,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_TICKSOURCE_GPTMR0 is not set
 CONFIG_TICKSOURCE_CORETMR=y
-# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_CYCLES_CLOCKSOURCE=y
 # CONFIG_GPTMR0_CLOCKSOURCE is not set
 CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
@@ -287,7 +316,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -296,16 +324,18 @@ CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -316,7 +346,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -362,6 +392,7 @@ CONFIG_PM=y
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_PM_BFIN_SLEEP_DEEPER=y
 # CONFIG_PM_BFIN_SLEEP is not set
@@ -384,11 +415,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -412,7 +438,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -423,6 +448,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -436,14 +462,34 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
+CONFIG_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+CONFIG_CAN_DEV=m
+# CONFIG_CAN_CALC_BITTIMING is not set
+CONFIG_CAN_BFIN=m
+# CONFIG_CAN_SJA1000 is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+# CONFIG_CAN_DEBUG_DEVICES is not set
 CONFIG_IRDA=m
 
 #
@@ -483,13 +529,8 @@ CONFIG_SIR_BFIN_DMA=y
 #
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -510,6 +551,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
@@ -568,6 +610,7 @@ CONFIG_MTD_PHYSMAP=m
 #
 # CONFIG_MTD_DATAFLASH is not set
 # CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -583,6 +626,11 @@ CONFIG_MTD_PHYSMAP=m
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -599,10 +647,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT 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_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -637,6 +695,9 @@ 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
@@ -647,9 +708,12 @@ CONFIG_BFIN_TX_DESC_NUM=10
 CONFIG_BFIN_RX_DESC_NUM=20
 # CONFIG_BFIN_MAC_RMII is not set
 # CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -658,15 +722,16 @@ CONFIG_BFIN_RX_DESC_NUM=20
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -701,7 +766,10 @@ CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_TOUCHSCREEN is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_UINPUT is not set
-CONFIG_CONFIG_INPUT_PCF8574=m
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
@@ -712,16 +780,13 @@ CONFIG_CONFIG_INPUT_PCF8574=m
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=m
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_BFIN_JTAG_COMM=m
@@ -735,6 +800,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -746,17 +812,8 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-CONFIG_CAN4LINUX=y
-
-#
-# linux embedded drivers
-#
-CONFIG_CAN_BLACKFIN=m
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -764,6 +821,7 @@ CONFIG_CAN_BLACKFIN=m
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -796,14 +854,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-CONFIG_SENSORS_AD5252=m
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_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
@@ -820,13 +870,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -842,6 +897,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -852,11 +908,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -878,26 +938,18 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -929,9 +981,6 @@ CONFIG_FB_CFB_IMAGEBLIT=m
 # CONFIG_FB_BFIN_T350MCQB is not set
 # CONFIG_FB_BFIN_LQ035Q1 is not set
 CONFIG_FB_BF537_LQ035=m
-CONFIG_LQ035_SLAVE_ADDR=0x58
-# CONFIG_FB_BFIN_LANDSCAPE is not set
-# CONFIG_FB_BFIN_BGR is not set
 CONFIG_FB_BFIN_7393=m
 CONFIG_NTSC=y
 # CONFIG_PAL is not set
@@ -946,15 +995,18 @@ CONFIG_ADV7393_1XMEM=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_LMS283GF05 is not set
 # CONFIG_LCD_LTV350QV is not set
 # CONFIG_LCD_ILI9320 is not set
 # CONFIG_LCD_TDO24M is not set
 # CONFIG_LCD_VGG2432A4 is not set
 # CONFIG_LCD_PLATFORM is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=m
-CONFIG_BACKLIGHT_CORGI=m
+CONFIG_BACKLIGHT_GENERIC=m
+# CONFIG_BACKLIGHT_ADP8870 is not set
 
 #
 # Display device support
@@ -963,19 +1015,27 @@ CONFIG_BACKLIGHT_CORGI=m
 # CONFIG_LOGO is not set
 CONFIG_SOUND=m
 CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
+CONFIG_SND_JACK=y
 # CONFIG_SND_SEQUENCER is not set
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
 CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_HRTIMER is not set
 # CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
 CONFIG_SND_DRIVERS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_MTPAV is not set
@@ -986,13 +1046,6 @@ CONFIG_SND_SPI=y
 #
 # ALSA Blackfin devices
 #
-CONFIG_SND_BLACKFIN_AD1836=m
-CONFIG_SND_BLACKFIN_AD1836_TDM=y
-# CONFIG_SND_BLACKFIN_AD1836_I2S is not set
-CONFIG_SND_BLACKFIN_AD1836_MULSUB=y
-# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set
-CONFIG_SND_BLACKFIN_SPORT=0
-CONFIG_SND_BLACKFIN_SPI_PFBIT=4
 CONFIG_SND_BFIN_SPORT=0
 CONFIG_SND_BFIN_AD73322=m
 CONFIG_SND_BFIN_AD73322_SPORT0_SE=10
@@ -1003,16 +1056,20 @@ CONFIG_SND_SOC_AC97_BUS=y
 CONFIG_SND_BF5XX_I2S=m
 # CONFIG_SND_BF5XX_SOC_SSM2602 is not set
 CONFIG_SND_BF5XX_SOC_AD73311=m
+# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set
 CONFIG_SND_BFIN_AD73311_SE=4
+# CONFIG_SND_BF5XX_TDM 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_HAVE_COLD_RESET is not set
+CONFIG_SND_BF5XX_SOC_AD1980=m
 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_I2C_AND_SPI=m
 # CONFIG_SND_SOC_ALL_CODECS is not set
 CONFIG_SND_SOC_AD1980=m
 CONFIG_SND_SOC_AD73311=m
@@ -1020,14 +1077,12 @@ CONFIG_SND_SOC_AD73311=m
 CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 # CONFIG_HID_PID is not set
 
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1064,6 +1119,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -1075,6 +1131,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
 # CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -1095,10 +1152,21 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
@@ -1107,9 +1175,13 @@ CONFIG_RTC_DRV_BFIN=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1119,6 +1191,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
@@ -1137,13 +1214,9 @@ CONFIG_INOTIFY_USER=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1162,17 +1235,8 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1191,7 +1255,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1256,14 +1319,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1271,31 +1339,39 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1320,6 +1396,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1328,14 +1405,14 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 CONFIG_CRYPTO=y
 
 #
 # 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
@@ -1367,11 +1444,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1408,6 +1487,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1415,11 +1495,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1429,6 +1511,8 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF538-EZKIT_defconfig linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF538-EZKIT_defconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF538-EZKIT_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF538-EZKIT_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,22 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,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_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -101,7 +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_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_BF537 is not set
 CONFIG_BF538=y
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=4
@@ -246,7 +274,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_TICKSOURCE_GPTMR0 is not set
 CONFIG_TICKSOURCE_CORETMR=y
-# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_CYCLES_CLOCKSOURCE=y
 # CONFIG_GPTMR0_CLOCKSOURCE is not set
 CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
@@ -298,7 +326,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -307,16 +334,18 @@ CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -327,7 +356,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -383,11 +412,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -411,7 +435,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -422,6 +445,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -435,14 +459,34 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
+CONFIG_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+CONFIG_CAN_DEV=m
+# CONFIG_CAN_CALC_BITTIMING is not set
+CONFIG_CAN_BFIN=m
+# CONFIG_CAN_SJA1000 is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+# CONFIG_CAN_DEBUG_DEVICES is not set
 CONFIG_IRDA=m
 
 #
@@ -481,13 +525,8 @@ CONFIG_SIR_BFIN_DMA=y
 #
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -508,6 +547,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
@@ -566,6 +606,7 @@ CONFIG_MTD_PHYSMAP=m
 #
 # CONFIG_MTD_DATAFLASH is not set
 # CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -581,11 +622,6 @@ 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_BFIN=m
-CONFIG_BFIN_NAND_BASE=0x20212000
-CONFIG_BFIN_NAND_CLE=2
-CONFIG_BFIN_NAND_ALE=1
-CONFIG_BFIN_NAND_READY=3
 CONFIG_MTD_NAND_IDS=m
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
@@ -593,6 +629,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
@@ -643,14 +684,20 @@ 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_SMC91X=y
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -659,15 +706,16 @@ CONFIG_SMC91X=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -700,14 +748,17 @@ CONFIG_INPUT_EVDEV=m
 # 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=y
 CONFIG_TOUCHSCREEN_AD7879=y
-# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
 # CONFIG_TOUCHSCREEN_FUJITSU is not set
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
 # CONFIG_TOUCHSCREEN_MTOUCH is not set
 # CONFIG_TOUCHSCREEN_INEXIO is not set
 # CONFIG_TOUCHSCREEN_MK712 is not set
@@ -715,9 +766,13 @@ CONFIG_TOUCHSCREEN_AD7879=y
 # 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 is not set
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
@@ -728,16 +783,13 @@ CONFIG_INPUT_MISC=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=m
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_BFIN_JTAG_COMM=m
@@ -751,6 +803,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -765,12 +818,8 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -778,6 +827,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 # CONFIG_I2C_CHARDEV is not set
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -810,14 +860,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -834,13 +876,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -856,6 +903,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -866,11 +914,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -892,26 +944,17 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -947,6 +990,7 @@ CONFIG_FB_BFIN_LQ035Q1=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
 
 #
@@ -957,14 +1001,12 @@ CONFIG_FB_BFIN_LQ035Q1=m
 # 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 is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1001,6 +1043,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -1012,6 +1055,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
 # CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -1032,10 +1076,21 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
@@ -1044,9 +1099,13 @@ CONFIG_RTC_DRV_BFIN=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1056,6 +1115,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
@@ -1074,13 +1138,9 @@ CONFIG_INOTIFY_USER=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1099,17 +1159,8 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1128,7 +1179,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1193,14 +1243,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1208,31 +1263,39 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1257,6 +1320,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1265,14 +1329,14 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 CONFIG_CRYPTO=y
 
 #
 # 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
@@ -1304,11 +1368,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1345,6 +1411,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1352,11 +1419,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1366,6 +1435,8 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF548-EZKIT_defconfig linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF548-EZKIT_defconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF548-EZKIT_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF548-EZKIT_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31.5
-# Mon Nov  2 22:02:56 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -12,7 +11,6 @@ CONFIG_GENERIC_CSUM=y
 CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
@@ -49,11 +47,12 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -89,24 +88,23 @@ CONFIG_EPOLL=y
 # CONFIG_AIO is not set
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
 CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 
 #
 # GCOV-based kernel profiling
 #
 # CONFIG_GCOV_KERNEL is not set
-# CONFIG_SLOW_WORK is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_SLOW_WORK_DEBUG is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_BASE_SMALL=0
@@ -163,15 +161,15 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_BF537 is not set
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
 CONFIG_BF548_std=y
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=0
@@ -185,7 +183,6 @@ CONFIG_BF_REV_0_2=y
 # CONFIG_BF_REV_0_6 is not set
 # CONFIG_BF_REV_ANY is not set
 # CONFIG_BF_REV_NONE is not set
-CONFIG_BF54x=y
 CONFIG_IRQ_PLL_WAKEUP=7
 CONFIG_IRQ_RTC=8
 CONFIG_IRQ_SPORT0_RX=9
@@ -221,6 +218,8 @@ CONFIG_IRQ_SPI1=10
 CONFIG_IRQ_SPI2=10
 CONFIG_IRQ_TWI0=11
 CONFIG_IRQ_TWI1=11
+CONFIG_BF548=y
+CONFIG_BF54x=y
 CONFIG_BFIN548_EZKIT=y
 # CONFIG_BFIN548_BLUETECHNIX_CM is not set
 
@@ -387,12 +386,14 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 CONFIG_DMA_UNCACHED_2M=y
 # CONFIG_DMA_UNCACHED_1M is not set
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
@@ -505,6 +506,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -528,7 +530,24 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
+CONFIG_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+CONFIG_CAN_DEV=m
+# CONFIG_CAN_CALC_BITTIMING is not set
+CONFIG_CAN_BFIN=m
+# CONFIG_CAN_SJA1000 is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+# CONFIG_CAN_DEBUG_DEVICES is not set
 CONFIG_IRDA=m
 
 #
@@ -663,6 +682,7 @@ CONFIG_MTD_PHYSMAP=y
 # CONFIG_MTD_DATAFLASH is not set
 CONFIG_MTD_M25P80=y
 CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -711,10 +731,10 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
-# CONFIG_AD525X_DPOT is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -767,7 +787,8 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
-CONFIG_SATA_PMP=y
+CONFIG_ATA_VERBOSE_ERROR=y
+# CONFIG_SATA_PMP is not set
 CONFIG_ATA_SFF=y
 # CONFIG_SATA_MV is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -808,6 +829,7 @@ CONFIG_MII=y
 # CONFIG_ETHOC is not set
 CONFIG_SMSC911X=y
 # CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -818,12 +840,10 @@ CONFIG_SMSC911X=y
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
 # CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
 # CONFIG_WLAN_PRE80211 is not set
 CONFIG_WLAN_80211=y
 CONFIG_LIBERTAS=m
@@ -877,10 +897,12 @@ CONFIG_INPUT_EVBUG=m
 CONFIG_INPUT_KEYBOARD=y
 # CONFIG_KEYBOARD_ADP5588 is not set
 # CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_QT2160 is not set
 CONFIG_KEYBOARD_BFIN=y
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_GPIO is not set
 # CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
 # CONFIG_KEYBOARD_OPENCORES is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
@@ -900,6 +922,7 @@ CONFIG_TOUCHSCREEN_AD7877=m
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
 # CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
 # CONFIG_TOUCHSCREEN_MTOUCH is not set
 # CONFIG_TOUCHSCREEN_INEXIO is not set
 # CONFIG_TOUCHSCREEN_MK712 is not set
@@ -910,7 +933,6 @@ CONFIG_TOUCHSCREEN_AD7877=m
 # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
 # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
 # CONFIG_TOUCHSCREEN_TSC2007 is not set
-# CONFIG_TOUCHSCREEN_W90X900 is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_ATI_REMOTE is not set
 # CONFIG_INPUT_ATI_REMOTE2 is not set
@@ -976,11 +998,6 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_OTP=y
 # CONFIG_BFIN_OTP_WRITE_ENABLE is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -988,6 +1005,7 @@ CONFIG_BFIN_OTP=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -1021,9 +1039,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1078,11 +1093,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -1116,8 +1135,10 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
 # CONFIG_REGULATOR is not set
@@ -1192,6 +1213,7 @@ CONFIG_LOGO=y
 CONFIG_LOGO_BLACKFIN_CLUT224=y
 CONFIG_SOUND=y
 CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SND=y
 CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=y
@@ -1245,7 +1267,6 @@ CONFIG_SND_SOC_AD1980=y
 CONFIG_AC97_BUS=y
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 
 #
@@ -1268,6 +1289,7 @@ CONFIG_HID_CYPRESS=y
 CONFIG_HID_EZKEY=y
 # CONFIG_HID_KYE is not set
 CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
 # CONFIG_HID_KENSINGTON is not set
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
@@ -1422,10 +1444,11 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_SPI is not set
 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
 # CONFIG_ACCESSIBILITY is not set
@@ -1472,6 +1495,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
 # CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -1522,6 +1546,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
@@ -1563,7 +1588,6 @@ CONFIG_NTFS_RW=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
 CONFIG_MISC_FILESYSTEMS=y
@@ -1595,7 +1619,6 @@ 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=m
 CONFIG_NFS_V3=y
@@ -1680,6 +1703,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1714,12 +1738,14 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
@@ -1730,7 +1756,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_VERBOSE=y
@@ -1766,7 +1791,6 @@ CONFIG_CRYPTO=y
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_MANAGER2 is not set
 # CONFIG_CRYPTO_GF128MUL is not set
@@ -1798,11 +1822,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF561-ACVILON_defconfig linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF561-ACVILON_defconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF561-ACVILON_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF561-ACVILON_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -114,7 +114,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBDAF=y
+# CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -1486,19 +1486,10 @@ CONFIG_DEBUG_INFO=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_TRACING_SUPPORT=y
-CONFIG_FTRACE=y
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_ENABLE_DEFAULT_TRACERS is not set
-# CONFIG_BOOT_TRACER is not set
-CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
-# CONFIG_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
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF561-EZKIT_defconfig linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF561-EZKIT_defconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF561-EZKIT_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/configs/BF561-EZKIT_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31.5
-# Mon Nov  2 21:59:31 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -12,7 +11,6 @@ CONFIG_GENERIC_CSUM=y
 CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
@@ -49,11 +47,12 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -89,17 +88,15 @@ CONFIG_EPOLL=y
 # CONFIG_AIO is not set
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
 CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 
 #
@@ -163,15 +160,15 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_BF537 is not set
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 CONFIG_BF561=y
 # CONFIG_SMP is not set
@@ -180,9 +177,9 @@ CONFIG_BF_REV_MAX=5
 # CONFIG_BF_REV_0_0 is not set
 # CONFIG_BF_REV_0_1 is not set
 # CONFIG_BF_REV_0_2 is not set
-# CONFIG_BF_REV_0_3 is not set
+CONFIG_BF_REV_0_3=y
 # CONFIG_BF_REV_0_4 is not set
-CONFIG_BF_REV_0_5=y
+# CONFIG_BF_REV_0_5 is not set
 # CONFIG_BF_REV_0_6 is not set
 # CONFIG_BF_REV_ANY is not set
 # CONFIG_BF_REV_NONE is not set
@@ -298,7 +295,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_TICKSOURCE_GPTMR0 is not set
 CONFIG_TICKSOURCE_CORETMR=y
-# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_CYCLES_CLOCKSOURCE=y
 # CONFIG_GPTMR0_CLOCKSOURCE is not set
 CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
@@ -353,12 +350,14 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
@@ -370,9 +369,11 @@ CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
-CONFIG_BFIN_EXTMEM_WRITEBACK=y
-# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
-# CONFIG_BFIN_L2_DCACHEABLE is not set
+# CONFIG_BFIN_EXTMEM_WRITEBACK is not set
+CONFIG_BFIN_EXTMEM_WRITETHROUGH=y
+CONFIG_BFIN_L2_DCACHEABLE=y
+# CONFIG_BFIN_L2_WRITEBACK is not set
+CONFIG_BFIN_L2_WRITETHROUGH=y
 
 #
 # Memory Protection Unit
@@ -472,6 +473,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -613,6 +615,7 @@ CONFIG_MTD_PHYSMAP=m
 #
 # CONFIG_MTD_DATAFLASH is not set
 # CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -685,6 +688,7 @@ CONFIG_SMC91X=y
 # CONFIG_ETHOC is not set
 # CONFIG_SMSC911X is not set
 # CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -695,14 +699,10 @@ CONFIG_SMC91X=y
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
 # CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_WLAN is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -782,11 +782,6 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -838,11 +833,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -865,6 +864,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_MC13783 is not set
 # CONFIG_EZX_PCAP is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
@@ -884,7 +884,6 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 # CONFIG_HID_PID is not set
 
@@ -923,6 +922,7 @@ CONFIG_HID=m
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
@@ -957,7 +957,6 @@ CONFIG_INOTIFY_USER=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
 CONFIG_MISC_FILESYSTEMS=y
@@ -989,7 +988,6 @@ 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=m
 CONFIG_NFS_V3=y
@@ -1064,6 +1062,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1098,26 +1097,24 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
-# CONFIG_BRANCH_PROFILE_NONE is not set
-# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
-# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_VERBOSE=y
@@ -1153,7 +1150,6 @@ CONFIG_CRYPTO=y
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_MANAGER2 is not set
 # CONFIG_CRYPTO_GF128MUL is not set
@@ -1185,11 +1181,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/configs/H8606_defconfig linux-libre-2.6.34-gnu1/arch/blackfin/configs/H8606_defconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/configs/H8606_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/configs/H8606_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -834,13 +834,6 @@ CONFIG_SND_VERBOSE_PROCFS=y
 #
 # ALSA Blackfin devices
 #
-CONFIG_SND_BLACKFIN_AD1836=m
-CONFIG_SND_BLACKFIN_AD1836_TDM=y
-# CONFIG_SND_BLACKFIN_AD1836_I2S is not set
-CONFIG_SND_BLACKFIN_AD1836_MULSUB=y
-# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set
-CONFIG_SND_BLACKFIN_SPORT=0
-CONFIG_SND_BLACKFIN_SPI_PFBIT=4
 # CONFIG_SND_BFIN_AD73311 is not set
 
 #
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/configs/PNAV-10_defconfig linux-libre-2.6.34-gnu1/arch/blackfin/configs/PNAV-10_defconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/configs/PNAV-10_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/configs/PNAV-10_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,21 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -25,16 +31,32 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
@@ -58,6 +80,10 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -65,11 +91,14 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_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
@@ -77,11 +106,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -97,7 +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_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -128,15 +153,15 @@ CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_BF537=y
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=2
@@ -180,7 +205,8 @@ CONFIG_IRQ_MEM_DMA1=13
 CONFIG_IRQ_WATCH=13
 CONFIG_IRQ_SPI=10
 # CONFIG_BFIN537_STAMP is not set
-# CONFIG_BFIN537_BLUETECHNIX_CM is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM_E is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM_U is not set
 # CONFIG_BFIN537_BLUETECHNIX_TCM is not set
 CONFIG_PNAV10=y
 # CONFIG_CAMSIG_MINOTAUR is not set
@@ -282,7 +308,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -291,16 +316,18 @@ CONFIG_BFIN_GPTIMERS=y
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -311,7 +338,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -367,11 +394,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -395,7 +417,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -406,6 +427,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -419,7 +441,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -430,13 +455,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -455,6 +475,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
@@ -506,6 +527,7 @@ CONFIG_MTD_UCLINUX=y
 #
 # CONFIG_MTD_DATAFLASH is not set
 # CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -521,11 +543,6 @@ CONFIG_MTD_NAND=y
 # CONFIG_MTD_NAND_VERIFY_WRITE is not set
 # CONFIG_MTD_NAND_ECC_SMC is not set
 # CONFIG_MTD_NAND_MUSEUM_IDS is not set
-CONFIG_MTD_NAND_BFIN=y
-CONFIG_BFIN_NAND_BASE=0x20100000
-CONFIG_BFIN_NAND_CLE=2
-CONFIG_BFIN_NAND_ALE=1
-CONFIG_BFIN_NAND_READY=44
 CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
@@ -533,6 +550,11 @@ CONFIG_MTD_NAND_IDS=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
@@ -549,10 +571,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT 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_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -587,6 +619,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
@@ -597,9 +632,12 @@ CONFIG_BFIN_TX_DESC_NUM=100
 CONFIG_BFIN_RX_DESC_NUM=100
 CONFIG_BFIN_MAC_RMII=y
 # CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -608,15 +646,16 @@ CONFIG_BFIN_MAC_RMII=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -649,14 +688,17 @@ CONFIG_INPUT_EVDEV=y
 # 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=y
 # CONFIG_TOUCHSCREEN_AD7879_I2C is not set
 # CONFIG_TOUCHSCREEN_AD7879_SPI is not set
 # CONFIG_TOUCHSCREEN_AD7879 is not set
-# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
 # CONFIG_TOUCHSCREEN_FUJITSU is not set
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
 # CONFIG_TOUCHSCREEN_MTOUCH is not set
 # CONFIG_TOUCHSCREEN_INEXIO is not set
 # CONFIG_TOUCHSCREEN_MK712 is not set
@@ -665,6 +707,7 @@ CONFIG_TOUCHSCREEN_AD7877=y
 # 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
@@ -673,7 +716,9 @@ CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_YEALINK is not set
 # CONFIG_INPUT_CM109 is not set
 CONFIG_INPUT_UINPUT=y
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
@@ -684,16 +729,13 @@ CONFIG_INPUT_UINPUT=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=y
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_BFIN_TWI_LCD is not set
-# CONFIG_SIMPLE_GPIO is not set
 # CONFIG_VT is not set
 CONFIG_DEVKMEM=y
 # CONFIG_BFIN_JTAG_COMM is not set
@@ -707,6 +749,7 @@ CONFIG_DEVKMEM=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -719,24 +762,17 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-CONFIG_CAN4LINUX=y
-
-#
-# linux embedded drivers
-#
-CONFIG_CAN_BLACKFIN=m
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -769,14 +805,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
-CONFIG_SENSORS_PCF8574=m
-# 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
@@ -792,20 +820,29 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB 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_AD5252 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
 # CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADCXX is not set
@@ -818,11 +855,13 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
 # CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_F71882FG is not set
 # CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
 # CONFIG_SENSORS_GL518SM is not set
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
@@ -838,17 +877,24 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
 # CONFIG_SENSORS_MAX1111 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
@@ -858,9 +904,8 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -875,28 +920,19 @@ 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_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -928,24 +964,24 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_BFIN_T350MCQB is not set
 # CONFIG_FB_BFIN_LQ035Q1 is not set
 CONFIG_FB_BF537_LQ035=y
-CONFIG_LQ035_SLAVE_ADDR=0x58
-CONFIG_FB_BFIN_LANDSCAPE=y
-# CONFIG_FB_BFIN_BGR is not set
 # CONFIG_FB_BFIN_7393 is not set
 # CONFIG_FB_HITACHI_TX09 is not set
 # CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_LMS283GF05 is not set
 # CONFIG_LCD_LTV350QV is not set
 # CONFIG_LCD_ILI9320 is not set
 # CONFIG_LCD_TDO24M is not set
 # CONFIG_LCD_VGG2432A4 is not set
 # CONFIG_LCD_PLATFORM is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=y
+# CONFIG_BACKLIGHT_ADP8870 is not set
 
 #
 # Display device support
@@ -954,6 +990,7 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y
 # CONFIG_LOGO is not set
 CONFIG_SOUND=y
 CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SND=m
 # CONFIG_SND_SEQUENCER is not set
 # CONFIG_SND_MIXER_OSS is not set
@@ -963,6 +1000,11 @@ CONFIG_SND=m
 # CONFIG_SND_VERBOSE_PROCFS is not set
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
 CONFIG_SND_DRIVERS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_MTPAV is not set
@@ -973,7 +1015,6 @@ CONFIG_SND_SPI=y
 #
 # ALSA Blackfin devices
 #
-# CONFIG_SND_BLACKFIN_AD1836 is not set
 # CONFIG_SND_BFIN_AD73322 is not set
 # CONFIG_SND_SOC is not set
 CONFIG_SOUND_PRIME=y
@@ -993,9 +1034,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
@@ -1031,6 +1076,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -1042,6 +1088,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
 # CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -1062,10 +1109,21 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1078,9 +1136,13 @@ 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_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1090,6 +1152,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
@@ -1108,13 +1175,9 @@ CONFIG_INOTIFY_USER=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1123,17 +1186,8 @@ CONFIG_SYSFS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
-CONFIG_YAFFS_FS=y
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1152,7 +1206,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1217,18 +1270,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
 # 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
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_DEBUG_VERBOSE=y
@@ -1245,6 +1299,7 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
 # CONFIG_EARLY_PRINTK is not set
 # CONFIG_CPLB_INFO is not set
 # CONFIG_ACCESS_CHECK is not set
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1253,14 +1308,14 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 CONFIG_CRYPTO=y
 
 #
 # 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
@@ -1292,11 +1347,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1333,6 +1390,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1340,11 +1398,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1356,3 +1416,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.33-gnu1/arch/blackfin/configs/TCM-BF518_defconfig linux-libre-2.6.34-gnu1/arch/blackfin/configs/TCM-BF518_defconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/configs/TCM-BF518_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/configs/TCM-BF518_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1375 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32.3
+#
+# CONFIG_MMU is not set
+# CONFIG_FPU is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+CONFIG_EPOLL=y
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF 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_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+# CONFIG_FREEZER is not set
+
+#
+# Blackfin Processor Options
+#
+
+#
+# Processor and Board Settings
+#
+# CONFIG_BF512 is not set
+# CONFIG_BF514 is not set
+# CONFIG_BF516 is not set
+CONFIG_BF518=y
+# CONFIG_BF522 is not set
+# CONFIG_BF523 is not set
+# CONFIG_BF524 is not set
+# CONFIG_BF525 is not set
+# CONFIG_BF526 is not set
+# CONFIG_BF527 is not set
+# CONFIG_BF531 is not set
+# CONFIG_BF532 is not set
+# CONFIG_BF533 is not set
+# CONFIG_BF534 is not set
+# CONFIG_BF536 is not set
+# CONFIG_BF537 is not set
+# CONFIG_BF538 is not set
+# CONFIG_BF539 is not set
+# CONFIG_BF542_std is not set
+# CONFIG_BF542M is not set
+# CONFIG_BF544_std is not set
+# CONFIG_BF544M is not set
+# CONFIG_BF547_std is not set
+# CONFIG_BF547M is not set
+# CONFIG_BF548_std is not set
+# CONFIG_BF548M is not set
+# CONFIG_BF549_std is not set
+# CONFIG_BF549M is not set
+# CONFIG_BF561 is not set
+CONFIG_BF_REV_MIN=0
+CONFIG_BF_REV_MAX=2
+# CONFIG_BF_REV_0_0 is not set
+CONFIG_BF_REV_0_1=y
+# CONFIG_BF_REV_0_2 is not set
+# CONFIG_BF_REV_0_3 is not set
+# CONFIG_BF_REV_0_4 is not set
+# CONFIG_BF_REV_0_5 is not set
+# CONFIG_BF_REV_0_6 is not set
+# CONFIG_BF_REV_ANY is not set
+# CONFIG_BF_REV_NONE is not set
+CONFIG_BF51x=y
+# CONFIG_BFIN518F_EZBRD is not set
+CONFIG_BFIN518F_TCM=y
+
+#
+# BF518 Specific Configuration
+#
+
+#
+# Alternative Multiplexing Scheme
+#
+# CONFIG_BF518_SPORT0_PORTF is not set
+CONFIG_BF518_SPORT0_PORTG=y
+CONFIG_BF518_SPORT0_TSCLK_PG10=y
+# CONFIG_BF518_SPORT0_TSCLK_PG14 is not set
+CONFIG_BF518_UART1_PORTF=y
+# CONFIG_BF518_UART1_PORTG is not set
+
+#
+# Interrupt Priority Assignment
+#
+
+#
+# Priority
+#
+CONFIG_IRQ_PLL_WAKEUP=7
+CONFIG_IRQ_DMA0_ERROR=7
+CONFIG_IRQ_DMAR0_BLK=7
+CONFIG_IRQ_DMAR1_BLK=7
+CONFIG_IRQ_DMAR0_OVR=7
+CONFIG_IRQ_DMAR1_OVR=7
+CONFIG_IRQ_PPI_ERROR=7
+CONFIG_IRQ_MAC_ERROR=7
+CONFIG_IRQ_SPORT0_ERROR=7
+CONFIG_IRQ_SPORT1_ERROR=7
+CONFIG_IRQ_PTP_ERROR=7
+CONFIG_IRQ_UART0_ERROR=7
+CONFIG_IRQ_UART1_ERROR=7
+CONFIG_IRQ_RTC=8
+CONFIG_IRQ_PPI=8
+CONFIG_IRQ_SPORT0_RX=9
+CONFIG_IRQ_SPORT0_TX=9
+CONFIG_IRQ_SPORT1_RX=9
+CONFIG_IRQ_SPORT1_TX=9
+CONFIG_IRQ_TWI=10
+CONFIG_IRQ_SPI0=10
+CONFIG_IRQ_UART0_RX=10
+CONFIG_IRQ_UART0_TX=10
+CONFIG_IRQ_UART1_RX=10
+CONFIG_IRQ_UART1_TX=10
+CONFIG_IRQ_OPTSEC=11
+CONFIG_IRQ_CNT=11
+CONFIG_IRQ_MAC_RX=11
+CONFIG_IRQ_PORTH_INTA=11
+CONFIG_IRQ_MAC_TX=11
+CONFIG_IRQ_PORTH_INTB=11
+CONFIG_IRQ_TIMER0=12
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
+CONFIG_IRQ_PORTG_INTA=12
+CONFIG_IRQ_PORTG_INTB=12
+CONFIG_IRQ_MEM_DMA0=13
+CONFIG_IRQ_MEM_DMA1=13
+CONFIG_IRQ_WATCH=13
+CONFIG_IRQ_PORTF_INTA=13
+CONFIG_IRQ_PORTF_INTB=13
+CONFIG_IRQ_SPI0_ERROR=7
+CONFIG_IRQ_SPI1_ERROR=7
+CONFIG_IRQ_RSI_INT0=7
+CONFIG_IRQ_RSI_INT1=7
+CONFIG_IRQ_PWM_TRIP=10
+CONFIG_IRQ_PWM_SYNC=10
+CONFIG_IRQ_PTP_STAT=10
+
+#
+# Board customizations
+#
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_BOOT_LOAD=0x1000
+
+#
+# Clock/PLL Setup
+#
+CONFIG_CLKIN_HZ=25000000
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=400000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133333333
+CONFIG_MIN_SCLK_HZ=27000000
+
+#
+# Kernel Timer/Scheduler
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+
+#
+# Clock event device
+#
+# CONFIG_TICKSOURCE_GPTMR0 is not set
+CONFIG_TICKSOURCE_CORETMR=y
+
+#
+# Clock souce
+#
+# CONFIG_CYCLES_CLOCKSOURCE is not set
+# CONFIG_GPTMR0_CLOCKSOURCE is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# Misc
+#
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
+#
+# Memory Optimizations
+#
+CONFIG_I_ENTRY_L1=y
+CONFIG_EXCPT_IRQ_SYSC_L1=y
+CONFIG_DO_IRQ_L1=y
+CONFIG_CORE_TIMER_IRQ_L1=y
+CONFIG_IDLE_L1=y
+# CONFIG_SCHEDULE_L1 is not set
+CONFIG_ARITHMETIC_OPS_L1=y
+CONFIG_ACCESS_OK_L1=y
+# CONFIG_MEMSET_L1 is not set
+# CONFIG_MEMCPY_L1 is not set
+# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set
+# CONFIG_IP_CHECKSUM_L1 is not set
+CONFIG_CACHELINE_ALIGNED_L1=y
+# CONFIG_SYSCALL_TAB_L1 is not set
+# CONFIG_CPLB_SWITCH_TAB_L1 is not set
+CONFIG_APP_STACK_L1=y
+
+#
+# Speed Optimizations
+#
+CONFIG_BFIN_INS_LOWOVERHEAD=y
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
+CONFIG_BFIN_GPTIMERS=m
+# CONFIG_DMA_UNCACHED_4M is not set
+# CONFIG_DMA_UNCACHED_2M is not set
+CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
+# CONFIG_DMA_UNCACHED_NONE is not set
+
+#
+# Cache Support
+#
+CONFIG_BFIN_ICACHE=y
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+CONFIG_BFIN_EXTMEM_DCACHEABLE=y
+CONFIG_BFIN_EXTMEM_WRITEBACK=y
+# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
+
+#
+# Memory Protection Unit
+#
+# CONFIG_MPU is not set
+
+#
+# Asynchronous Memory Configuration
+#
+
+#
+# EBIU_AMGCTL Global Control
+#
+CONFIG_C_AMCKEN=y
+CONFIG_C_CDPRIO=y
+# CONFIG_C_AMBEN is not set
+# CONFIG_C_AMBEN_B0 is not set
+# CONFIG_C_AMBEN_B0_B1 is not set
+# CONFIG_C_AMBEN_B0_B1_B2 is not set
+CONFIG_C_AMBEN_ALL=y
+
+#
+# EBIU_AMBCTL Control
+#
+CONFIG_BANK_0=0x7BB0
+CONFIG_BANK_1=0x7BB0
+CONFIG_BANK_2=0x7BB0
+CONFIG_BANK_3=0x99B2
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF_FDPIC=y
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_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 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_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=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=y
+CONFIG_MTD_ROM=m
+# 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_UCLINUX is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT 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_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI 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_BFIN_MAC=y
+CONFIG_BFIN_TX_DESC_NUM=10
+CONFIG_BFIN_RX_DESC_NUM=20
+# CONFIG_BFIN_MAC_RMII is not set
+CONFIG_BFIN_MAC_USE_HWSTAMP=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN 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=y
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_BFIN_DMA_INTERFACE=m
+# CONFIG_BFIN_PPI is not set
+# CONFIG_BFIN_PPIFCD is not set
+# CONFIG_BFIN_SIMPLE_TIMER is not set
+# CONFIG_BFIN_SPI_ADC is not set
+# CONFIG_BFIN_SPORT is not set
+# CONFIG_BFIN_TWI_LCD is not set
+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_BFIN_JTAG_COMM=m
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+CONFIG_SERIAL_BFIN_DMA=y
+# CONFIG_SERIAL_BFIN_PIO is not set
+CONFIG_SERIAL_BFIN_UART0=y
+# CONFIG_BFIN_UART0_CTSRTS is not set
+# CONFIG_SERIAL_BFIN_UART1 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_BFIN_SPORT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_BFIN_OTP=y
+# CONFIG_BFIN_OTP_WRITE_ENABLE 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_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_BLACKFIN_TWI=y
+CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BFIN=y
+CONFIG_SPI_BFIN_LOCK=y
+# CONFIG_SPI_BFIN_SPORT is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_BFIN_WDT=y
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# 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=y
+CONFIG_MMC_DEBUG=y
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+CONFIG_MMC_SPI=y
+# CONFIG_SDH_BFIN is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_BFIN=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# 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_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=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=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=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_VERBOSE=y
+CONFIG_DEBUG_MMRS=y
+CONFIG_DEBUG_HWERR=y
+CONFIG_EXACT_HWERR=y
+CONFIG_DEBUG_DOUBLEFAULT=y
+CONFIG_DEBUG_DOUBLEFAULT_PRINT=y
+# CONFIG_DEBUG_DOUBLEFAULT_RESET is not set
+# CONFIG_DEBUG_ICACHE_CHECK is not set
+CONFIG_DEBUG_HUNT_FOR_ZERO=y
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=1
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
+CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CPLB_INFO=y
+CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_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_TOMOYO is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=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.33-gnu1/arch/blackfin/include/asm/bfin_can.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/bfin_can.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/bfin_can.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/bfin_can.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,725 @@
+/*
+ * bfin_can.h - interface to Blackfin CANs
+ *
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __ASM_BFIN_CAN_H__
+#define __ASM_BFIN_CAN_H__
+
+/*
+ * transmit and receive channels
+ */
+#define TRANSMIT_CHL            24
+#define RECEIVE_STD_CHL         0
+#define RECEIVE_EXT_CHL         4
+#define RECEIVE_RTR_CHL         8
+#define RECEIVE_EXT_RTR_CHL     12
+#define MAX_CHL_NUMBER          32
+
+/*
+ * All Blackfin system MMRs are padded to 32bits even if the register
+ * itself is only 16bits.  So use a helper macro to streamline this.
+ */
+#define __BFP(m) u16 m; u16 __pad_##m
+
+/*
+ * bfin can registers layout
+ */
+struct bfin_can_mask_regs {
+	__BFP(aml);
+	__BFP(amh);
+};
+
+struct bfin_can_channel_regs {
+	u16 data[8];
+	__BFP(dlc);
+	__BFP(tsv);
+	__BFP(id0);
+	__BFP(id1);
+};
+
+struct bfin_can_regs {
+	/*
+	 * global control and status registers
+	 */
+	__BFP(mc1);           /* offset 0x00 */
+	__BFP(md1);           /* offset 0x04 */
+	__BFP(trs1);          /* offset 0x08 */
+	__BFP(trr1);          /* offset 0x0c */
+	__BFP(ta1);           /* offset 0x10 */
+	__BFP(aa1);           /* offset 0x14 */
+	__BFP(rmp1);          /* offset 0x18 */
+	__BFP(rml1);          /* offset 0x1c */
+	__BFP(mbtif1);        /* offset 0x20 */
+	__BFP(mbrif1);        /* offset 0x24 */
+	__BFP(mbim1);         /* offset 0x28 */
+	__BFP(rfh1);          /* offset 0x2c */
+	__BFP(opss1);         /* offset 0x30 */
+	u32 __pad1[3];
+	__BFP(mc2);           /* offset 0x40 */
+	__BFP(md2);           /* offset 0x44 */
+	__BFP(trs2);          /* offset 0x48 */
+	__BFP(trr2);          /* offset 0x4c */
+	__BFP(ta2);           /* offset 0x50 */
+	__BFP(aa2);           /* offset 0x54 */
+	__BFP(rmp2);          /* offset 0x58 */
+	__BFP(rml2);          /* offset 0x5c */
+	__BFP(mbtif2);        /* offset 0x60 */
+	__BFP(mbrif2);        /* offset 0x64 */
+	__BFP(mbim2);         /* offset 0x68 */
+	__BFP(rfh2);          /* offset 0x6c */
+	__BFP(opss2);         /* offset 0x70 */
+	u32 __pad2[3];
+	__BFP(clock);         /* offset 0x80 */
+	__BFP(timing);        /* offset 0x84 */
+	__BFP(debug);         /* offset 0x88 */
+	__BFP(status);        /* offset 0x8c */
+	__BFP(cec);           /* offset 0x90 */
+	__BFP(gis);           /* offset 0x94 */
+	__BFP(gim);           /* offset 0x98 */
+	__BFP(gif);           /* offset 0x9c */
+	__BFP(control);       /* offset 0xa0 */
+	__BFP(intr);          /* offset 0xa4 */
+	u32 __pad3[1];
+	__BFP(mbtd);          /* offset 0xac */
+	__BFP(ewr);           /* offset 0xb0 */
+	__BFP(esr);           /* offset 0xb4 */
+	u32 __pad4[2];
+	__BFP(ucreg);         /* offset 0xc0 */
+	__BFP(uccnt);         /* offset 0xc4 */
+	__BFP(ucrc);          /* offset 0xc8 */
+	__BFP(uccnf);         /* offset 0xcc */
+	u32 __pad5[12];
+
+	/*
+	 * channel(mailbox) mask and message registers
+	 */
+	struct bfin_can_mask_regs msk[MAX_CHL_NUMBER];    /* offset 0x100 */
+	struct bfin_can_channel_regs chl[MAX_CHL_NUMBER]; /* offset 0x200 */
+};
+
+#undef __BFP
+
+/* CAN_CONTROL Masks */
+#define SRS			0x0001	/* Software Reset */
+#define DNM			0x0002	/* Device Net Mode */
+#define ABO			0x0004	/* Auto-Bus On Enable */
+#define TXPRIO		0x0008	/* TX Priority (Priority/Mailbox*) */
+#define WBA			0x0010	/* Wake-Up On CAN Bus Activity Enable */
+#define SMR			0x0020	/* Sleep Mode Request */
+#define CSR			0x0040	/* CAN Suspend Mode Request */
+#define CCR			0x0080	/* CAN Configuration Mode Request */
+
+/* CAN_STATUS Masks */
+#define WT			0x0001	/* TX Warning Flag */
+#define WR			0x0002	/* RX Warning Flag */
+#define EP			0x0004	/* Error Passive Mode */
+#define EBO			0x0008	/* Error Bus Off Mode */
+#define SMA			0x0020	/* Sleep Mode Acknowledge */
+#define CSA			0x0040	/* Suspend Mode Acknowledge */
+#define CCA			0x0080	/* Configuration Mode Acknowledge */
+#define MBPTR		0x1F00	/* Mailbox Pointer */
+#define TRM			0x4000	/* Transmit Mode */
+#define REC			0x8000	/* Receive Mode */
+
+/* CAN_CLOCK Masks */
+#define BRP			0x03FF	/* Bit-Rate Pre-Scaler */
+
+/* CAN_TIMING Masks */
+#define TSEG1		0x000F	/* Time Segment 1 */
+#define TSEG2		0x0070	/* Time Segment 2 */
+#define SAM			0x0080	/* Sampling */
+#define SJW			0x0300	/* Synchronization Jump Width */
+
+/* CAN_DEBUG Masks */
+#define DEC			0x0001	/* Disable CAN Error Counters */
+#define DRI			0x0002	/* Disable CAN RX Input */
+#define DTO			0x0004	/* Disable CAN TX Output */
+#define DIL			0x0008	/* Disable CAN Internal Loop */
+#define MAA			0x0010	/* Mode Auto-Acknowledge Enable */
+#define MRB			0x0020	/* Mode Read Back Enable */
+#define CDE			0x8000	/* CAN Debug Enable */
+
+/* CAN_CEC Masks */
+#define RXECNT		0x00FF	/* Receive Error Counter */
+#define TXECNT		0xFF00	/* Transmit Error Counter */
+
+/* CAN_INTR Masks */
+#define MBRIRQ	0x0001	/* Mailbox Receive Interrupt */
+#define MBTIRQ	0x0002	/* Mailbox Transmit Interrupt */
+#define GIRQ		0x0004	/* Global Interrupt */
+#define SMACK		0x0008	/* Sleep Mode Acknowledge */
+#define CANTX		0x0040	/* CAN TX Bus Value */
+#define CANRX		0x0080	/* CAN RX Bus Value */
+
+/* CAN_MBxx_ID1 and CAN_MBxx_ID0 Masks */
+#define DFC			0xFFFF	/* Data Filtering Code (If Enabled) (ID0) */
+#define EXTID_LO	0xFFFF	/* Lower 16 Bits of Extended Identifier (ID0) */
+#define EXTID_HI	0x0003	/* Upper 2 Bits of Extended Identifier (ID1) */
+#define BASEID		0x1FFC	/* Base Identifier */
+#define IDE			0x2000	/* Identifier Extension */
+#define RTR			0x4000	/* Remote Frame Transmission Request */
+#define AME			0x8000	/* Acceptance Mask Enable */
+
+/* CAN_MBxx_TIMESTAMP Masks */
+#define TSV			0xFFFF	/* Timestamp */
+
+/* CAN_MBxx_LENGTH Masks */
+#define DLC			0x000F	/* Data Length Code */
+
+/* CAN_AMxxH and CAN_AMxxL Masks */
+#define DFM			0xFFFF	/* Data Field Mask (If Enabled) (CAN_AMxxL) */
+#define EXTID_LO	0xFFFF	/* Lower 16 Bits of Extended Identifier (CAN_AMxxL) */
+#define EXTID_HI	0x0003	/* Upper 2 Bits of Extended Identifier (CAN_AMxxH) */
+#define BASEID		0x1FFC	/* Base Identifier */
+#define AMIDE		0x2000	/* Acceptance Mask ID Extension Enable */
+#define FMD			0x4000	/* Full Mask Data Field Enable */
+#define FDF			0x8000	/* Filter On Data Field Enable */
+
+/* CAN_MC1 Masks */
+#define MC0			0x0001	/* Enable Mailbox 0 */
+#define MC1			0x0002	/* Enable Mailbox 1 */
+#define MC2			0x0004	/* Enable Mailbox 2 */
+#define MC3			0x0008	/* Enable Mailbox 3 */
+#define MC4			0x0010	/* Enable Mailbox 4 */
+#define MC5			0x0020	/* Enable Mailbox 5 */
+#define MC6			0x0040	/* Enable Mailbox 6 */
+#define MC7			0x0080	/* Enable Mailbox 7 */
+#define MC8			0x0100	/* Enable Mailbox 8 */
+#define MC9			0x0200	/* Enable Mailbox 9 */
+#define MC10		0x0400	/* Enable Mailbox 10 */
+#define MC11		0x0800	/* Enable Mailbox 11 */
+#define MC12		0x1000	/* Enable Mailbox 12 */
+#define MC13		0x2000	/* Enable Mailbox 13 */
+#define MC14		0x4000	/* Enable Mailbox 14 */
+#define MC15		0x8000	/* Enable Mailbox 15 */
+
+/* CAN_MC2 Masks */
+#define MC16		0x0001	/* Enable Mailbox 16 */
+#define MC17		0x0002	/* Enable Mailbox 17 */
+#define MC18		0x0004	/* Enable Mailbox 18 */
+#define MC19		0x0008	/* Enable Mailbox 19 */
+#define MC20		0x0010	/* Enable Mailbox 20 */
+#define MC21		0x0020	/* Enable Mailbox 21 */
+#define MC22		0x0040	/* Enable Mailbox 22 */
+#define MC23		0x0080	/* Enable Mailbox 23 */
+#define MC24		0x0100	/* Enable Mailbox 24 */
+#define MC25		0x0200	/* Enable Mailbox 25 */
+#define MC26		0x0400	/* Enable Mailbox 26 */
+#define MC27		0x0800	/* Enable Mailbox 27 */
+#define MC28		0x1000	/* Enable Mailbox 28 */
+#define MC29		0x2000	/* Enable Mailbox 29 */
+#define MC30		0x4000	/* Enable Mailbox 30 */
+#define MC31		0x8000	/* Enable Mailbox 31 */
+
+/* CAN_MD1 Masks */
+#define MD0			0x0001	/* Enable Mailbox 0 For Receive */
+#define MD1			0x0002	/* Enable Mailbox 1 For Receive */
+#define MD2			0x0004	/* Enable Mailbox 2 For Receive */
+#define MD3			0x0008	/* Enable Mailbox 3 For Receive */
+#define MD4			0x0010	/* Enable Mailbox 4 For Receive */
+#define MD5			0x0020	/* Enable Mailbox 5 For Receive */
+#define MD6			0x0040	/* Enable Mailbox 6 For Receive */
+#define MD7			0x0080	/* Enable Mailbox 7 For Receive */
+#define MD8			0x0100	/* Enable Mailbox 8 For Receive */
+#define MD9			0x0200	/* Enable Mailbox 9 For Receive */
+#define MD10		0x0400	/* Enable Mailbox 10 For Receive */
+#define MD11		0x0800	/* Enable Mailbox 11 For Receive */
+#define MD12		0x1000	/* Enable Mailbox 12 For Receive */
+#define MD13		0x2000	/* Enable Mailbox 13 For Receive */
+#define MD14		0x4000	/* Enable Mailbox 14 For Receive */
+#define MD15		0x8000	/* Enable Mailbox 15 For Receive */
+
+/* CAN_MD2 Masks */
+#define MD16		0x0001	/* Enable Mailbox 16 For Receive */
+#define MD17		0x0002	/* Enable Mailbox 17 For Receive */
+#define MD18		0x0004	/* Enable Mailbox 18 For Receive */
+#define MD19		0x0008	/* Enable Mailbox 19 For Receive */
+#define MD20		0x0010	/* Enable Mailbox 20 For Receive */
+#define MD21		0x0020	/* Enable Mailbox 21 For Receive */
+#define MD22		0x0040	/* Enable Mailbox 22 For Receive */
+#define MD23		0x0080	/* Enable Mailbox 23 For Receive */
+#define MD24		0x0100	/* Enable Mailbox 24 For Receive */
+#define MD25		0x0200	/* Enable Mailbox 25 For Receive */
+#define MD26		0x0400	/* Enable Mailbox 26 For Receive */
+#define MD27		0x0800	/* Enable Mailbox 27 For Receive */
+#define MD28		0x1000	/* Enable Mailbox 28 For Receive */
+#define MD29		0x2000	/* Enable Mailbox 29 For Receive */
+#define MD30		0x4000	/* Enable Mailbox 30 For Receive */
+#define MD31		0x8000	/* Enable Mailbox 31 For Receive */
+
+/* CAN_RMP1 Masks */
+#define RMP0		0x0001	/* RX Message Pending In Mailbox 0 */
+#define RMP1		0x0002	/* RX Message Pending In Mailbox 1 */
+#define RMP2		0x0004	/* RX Message Pending In Mailbox 2 */
+#define RMP3		0x0008	/* RX Message Pending In Mailbox 3 */
+#define RMP4		0x0010	/* RX Message Pending In Mailbox 4 */
+#define RMP5		0x0020	/* RX Message Pending In Mailbox 5 */
+#define RMP6		0x0040	/* RX Message Pending In Mailbox 6 */
+#define RMP7		0x0080	/* RX Message Pending In Mailbox 7 */
+#define RMP8		0x0100	/* RX Message Pending In Mailbox 8 */
+#define RMP9		0x0200	/* RX Message Pending In Mailbox 9 */
+#define RMP10		0x0400	/* RX Message Pending In Mailbox 10 */
+#define RMP11		0x0800	/* RX Message Pending In Mailbox 11 */
+#define RMP12		0x1000	/* RX Message Pending In Mailbox 12 */
+#define RMP13		0x2000	/* RX Message Pending In Mailbox 13 */
+#define RMP14		0x4000	/* RX Message Pending In Mailbox 14 */
+#define RMP15		0x8000	/* RX Message Pending In Mailbox 15 */
+
+/* CAN_RMP2 Masks */
+#define RMP16		0x0001	/* RX Message Pending In Mailbox 16 */
+#define RMP17		0x0002	/* RX Message Pending In Mailbox 17 */
+#define RMP18		0x0004	/* RX Message Pending In Mailbox 18 */
+#define RMP19		0x0008	/* RX Message Pending In Mailbox 19 */
+#define RMP20		0x0010	/* RX Message Pending In Mailbox 20 */
+#define RMP21		0x0020	/* RX Message Pending In Mailbox 21 */
+#define RMP22		0x0040	/* RX Message Pending In Mailbox 22 */
+#define RMP23		0x0080	/* RX Message Pending In Mailbox 23 */
+#define RMP24		0x0100	/* RX Message Pending In Mailbox 24 */
+#define RMP25		0x0200	/* RX Message Pending In Mailbox 25 */
+#define RMP26		0x0400	/* RX Message Pending In Mailbox 26 */
+#define RMP27		0x0800	/* RX Message Pending In Mailbox 27 */
+#define RMP28		0x1000	/* RX Message Pending In Mailbox 28 */
+#define RMP29		0x2000	/* RX Message Pending In Mailbox 29 */
+#define RMP30		0x4000	/* RX Message Pending In Mailbox 30 */
+#define RMP31		0x8000	/* RX Message Pending In Mailbox 31 */
+
+/* CAN_RML1 Masks */
+#define RML0		0x0001	/* RX Message Lost In Mailbox 0 */
+#define RML1		0x0002	/* RX Message Lost In Mailbox 1 */
+#define RML2		0x0004	/* RX Message Lost In Mailbox 2 */
+#define RML3		0x0008	/* RX Message Lost In Mailbox 3 */
+#define RML4		0x0010	/* RX Message Lost In Mailbox 4 */
+#define RML5		0x0020	/* RX Message Lost In Mailbox 5 */
+#define RML6		0x0040	/* RX Message Lost In Mailbox 6 */
+#define RML7		0x0080	/* RX Message Lost In Mailbox 7 */
+#define RML8		0x0100	/* RX Message Lost In Mailbox 8 */
+#define RML9		0x0200	/* RX Message Lost In Mailbox 9 */
+#define RML10		0x0400	/* RX Message Lost In Mailbox 10 */
+#define RML11		0x0800	/* RX Message Lost In Mailbox 11 */
+#define RML12		0x1000	/* RX Message Lost In Mailbox 12 */
+#define RML13		0x2000	/* RX Message Lost In Mailbox 13 */
+#define RML14		0x4000	/* RX Message Lost In Mailbox 14 */
+#define RML15		0x8000	/* RX Message Lost In Mailbox 15 */
+
+/* CAN_RML2 Masks */
+#define RML16		0x0001	/* RX Message Lost In Mailbox 16 */
+#define RML17		0x0002	/* RX Message Lost In Mailbox 17 */
+#define RML18		0x0004	/* RX Message Lost In Mailbox 18 */
+#define RML19		0x0008	/* RX Message Lost In Mailbox 19 */
+#define RML20		0x0010	/* RX Message Lost In Mailbox 20 */
+#define RML21		0x0020	/* RX Message Lost In Mailbox 21 */
+#define RML22		0x0040	/* RX Message Lost In Mailbox 22 */
+#define RML23		0x0080	/* RX Message Lost In Mailbox 23 */
+#define RML24		0x0100	/* RX Message Lost In Mailbox 24 */
+#define RML25		0x0200	/* RX Message Lost In Mailbox 25 */
+#define RML26		0x0400	/* RX Message Lost In Mailbox 26 */
+#define RML27		0x0800	/* RX Message Lost In Mailbox 27 */
+#define RML28		0x1000	/* RX Message Lost In Mailbox 28 */
+#define RML29		0x2000	/* RX Message Lost In Mailbox 29 */
+#define RML30		0x4000	/* RX Message Lost In Mailbox 30 */
+#define RML31		0x8000	/* RX Message Lost In Mailbox 31 */
+
+/* CAN_OPSS1 Masks */
+#define OPSS0		0x0001	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 0 */
+#define OPSS1		0x0002	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 1 */
+#define OPSS2		0x0004	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 2 */
+#define OPSS3		0x0008	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 3 */
+#define OPSS4		0x0010	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 4 */
+#define OPSS5		0x0020	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 5 */
+#define OPSS6		0x0040	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 6 */
+#define OPSS7		0x0080	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 7 */
+#define OPSS8		0x0100	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 8 */
+#define OPSS9		0x0200	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 9 */
+#define OPSS10		0x0400	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 10 */
+#define OPSS11		0x0800	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 11 */
+#define OPSS12		0x1000	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 12 */
+#define OPSS13		0x2000	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 13 */
+#define OPSS14		0x4000	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 14 */
+#define OPSS15		0x8000	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 15 */
+
+/* CAN_OPSS2 Masks */
+#define OPSS16		0x0001	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 16 */
+#define OPSS17		0x0002	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 17 */
+#define OPSS18		0x0004	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 18 */
+#define OPSS19		0x0008	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 19 */
+#define OPSS20		0x0010	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 20 */
+#define OPSS21		0x0020	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 21 */
+#define OPSS22		0x0040	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 22 */
+#define OPSS23		0x0080	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 23 */
+#define OPSS24		0x0100	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 24 */
+#define OPSS25		0x0200	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 25 */
+#define OPSS26		0x0400	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 26 */
+#define OPSS27		0x0800	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 27 */
+#define OPSS28		0x1000	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 28 */
+#define OPSS29		0x2000	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 29 */
+#define OPSS30		0x4000	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 30 */
+#define OPSS31		0x8000	/* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 31 */
+
+/* CAN_TRR1 Masks */
+#define TRR0		0x0001	/* Deny But Don't Lock Access To Mailbox 0 */
+#define TRR1		0x0002	/* Deny But Don't Lock Access To Mailbox 1 */
+#define TRR2		0x0004	/* Deny But Don't Lock Access To Mailbox 2 */
+#define TRR3		0x0008	/* Deny But Don't Lock Access To Mailbox 3 */
+#define TRR4		0x0010	/* Deny But Don't Lock Access To Mailbox 4 */
+#define TRR5		0x0020	/* Deny But Don't Lock Access To Mailbox 5 */
+#define TRR6		0x0040	/* Deny But Don't Lock Access To Mailbox 6 */
+#define TRR7		0x0080	/* Deny But Don't Lock Access To Mailbox 7 */
+#define TRR8		0x0100	/* Deny But Don't Lock Access To Mailbox 8 */
+#define TRR9		0x0200	/* Deny But Don't Lock Access To Mailbox 9 */
+#define TRR10		0x0400	/* Deny But Don't Lock Access To Mailbox 10 */
+#define TRR11		0x0800	/* Deny But Don't Lock Access To Mailbox 11 */
+#define TRR12		0x1000	/* Deny But Don't Lock Access To Mailbox 12 */
+#define TRR13		0x2000	/* Deny But Don't Lock Access To Mailbox 13 */
+#define TRR14		0x4000	/* Deny But Don't Lock Access To Mailbox 14 */
+#define TRR15		0x8000	/* Deny But Don't Lock Access To Mailbox 15 */
+
+/* CAN_TRR2 Masks */
+#define TRR16		0x0001	/* Deny But Don't Lock Access To Mailbox 16 */
+#define TRR17		0x0002	/* Deny But Don't Lock Access To Mailbox 17 */
+#define TRR18		0x0004	/* Deny But Don't Lock Access To Mailbox 18 */
+#define TRR19		0x0008	/* Deny But Don't Lock Access To Mailbox 19 */
+#define TRR20		0x0010	/* Deny But Don't Lock Access To Mailbox 20 */
+#define TRR21		0x0020	/* Deny But Don't Lock Access To Mailbox 21 */
+#define TRR22		0x0040	/* Deny But Don't Lock Access To Mailbox 22 */
+#define TRR23		0x0080	/* Deny But Don't Lock Access To Mailbox 23 */
+#define TRR24		0x0100	/* Deny But Don't Lock Access To Mailbox 24 */
+#define TRR25		0x0200	/* Deny But Don't Lock Access To Mailbox 25 */
+#define TRR26		0x0400	/* Deny But Don't Lock Access To Mailbox 26 */
+#define TRR27		0x0800	/* Deny But Don't Lock Access To Mailbox 27 */
+#define TRR28		0x1000	/* Deny But Don't Lock Access To Mailbox 28 */
+#define TRR29		0x2000	/* Deny But Don't Lock Access To Mailbox 29 */
+#define TRR30		0x4000	/* Deny But Don't Lock Access To Mailbox 30 */
+#define TRR31		0x8000	/* Deny But Don't Lock Access To Mailbox 31 */
+
+/* CAN_TRS1 Masks */
+#define TRS0		0x0001	/* Remote Frame Request For Mailbox 0 */
+#define TRS1		0x0002	/* Remote Frame Request For Mailbox 1 */
+#define TRS2		0x0004	/* Remote Frame Request For Mailbox 2 */
+#define TRS3		0x0008	/* Remote Frame Request For Mailbox 3 */
+#define TRS4		0x0010	/* Remote Frame Request For Mailbox 4 */
+#define TRS5		0x0020	/* Remote Frame Request For Mailbox 5 */
+#define TRS6		0x0040	/* Remote Frame Request For Mailbox 6 */
+#define TRS7		0x0080	/* Remote Frame Request For Mailbox 7 */
+#define TRS8		0x0100	/* Remote Frame Request For Mailbox 8 */
+#define TRS9		0x0200	/* Remote Frame Request For Mailbox 9 */
+#define TRS10		0x0400	/* Remote Frame Request For Mailbox 10 */
+#define TRS11		0x0800	/* Remote Frame Request For Mailbox 11 */
+#define TRS12		0x1000	/* Remote Frame Request For Mailbox 12 */
+#define TRS13		0x2000	/* Remote Frame Request For Mailbox 13 */
+#define TRS14		0x4000	/* Remote Frame Request For Mailbox 14 */
+#define TRS15		0x8000	/* Remote Frame Request For Mailbox 15 */
+
+/* CAN_TRS2 Masks */
+#define TRS16		0x0001	/* Remote Frame Request For Mailbox 16 */
+#define TRS17		0x0002	/* Remote Frame Request For Mailbox 17 */
+#define TRS18		0x0004	/* Remote Frame Request For Mailbox 18 */
+#define TRS19		0x0008	/* Remote Frame Request For Mailbox 19 */
+#define TRS20		0x0010	/* Remote Frame Request For Mailbox 20 */
+#define TRS21		0x0020	/* Remote Frame Request For Mailbox 21 */
+#define TRS22		0x0040	/* Remote Frame Request For Mailbox 22 */
+#define TRS23		0x0080	/* Remote Frame Request For Mailbox 23 */
+#define TRS24		0x0100	/* Remote Frame Request For Mailbox 24 */
+#define TRS25		0x0200	/* Remote Frame Request For Mailbox 25 */
+#define TRS26		0x0400	/* Remote Frame Request For Mailbox 26 */
+#define TRS27		0x0800	/* Remote Frame Request For Mailbox 27 */
+#define TRS28		0x1000	/* Remote Frame Request For Mailbox 28 */
+#define TRS29		0x2000	/* Remote Frame Request For Mailbox 29 */
+#define TRS30		0x4000	/* Remote Frame Request For Mailbox 30 */
+#define TRS31		0x8000	/* Remote Frame Request For Mailbox 31 */
+
+/* CAN_AA1 Masks */
+#define AA0			0x0001	/* Aborted Message In Mailbox 0 */
+#define AA1			0x0002	/* Aborted Message In Mailbox 1 */
+#define AA2			0x0004	/* Aborted Message In Mailbox 2 */
+#define AA3			0x0008	/* Aborted Message In Mailbox 3 */
+#define AA4			0x0010	/* Aborted Message In Mailbox 4 */
+#define AA5			0x0020	/* Aborted Message In Mailbox 5 */
+#define AA6			0x0040	/* Aborted Message In Mailbox 6 */
+#define AA7			0x0080	/* Aborted Message In Mailbox 7 */
+#define AA8			0x0100	/* Aborted Message In Mailbox 8 */
+#define AA9			0x0200	/* Aborted Message In Mailbox 9 */
+#define AA10		0x0400	/* Aborted Message In Mailbox 10 */
+#define AA11		0x0800	/* Aborted Message In Mailbox 11 */
+#define AA12		0x1000	/* Aborted Message In Mailbox 12 */
+#define AA13		0x2000	/* Aborted Message In Mailbox 13 */
+#define AA14		0x4000	/* Aborted Message In Mailbox 14 */
+#define AA15		0x8000	/* Aborted Message In Mailbox 15 */
+
+/* CAN_AA2 Masks */
+#define AA16		0x0001	/* Aborted Message In Mailbox 16 */
+#define AA17		0x0002	/* Aborted Message In Mailbox 17 */
+#define AA18		0x0004	/* Aborted Message In Mailbox 18 */
+#define AA19		0x0008	/* Aborted Message In Mailbox 19 */
+#define AA20		0x0010	/* Aborted Message In Mailbox 20 */
+#define AA21		0x0020	/* Aborted Message In Mailbox 21 */
+#define AA22		0x0040	/* Aborted Message In Mailbox 22 */
+#define AA23		0x0080	/* Aborted Message In Mailbox 23 */
+#define AA24		0x0100	/* Aborted Message In Mailbox 24 */
+#define AA25		0x0200	/* Aborted Message In Mailbox 25 */
+#define AA26		0x0400	/* Aborted Message In Mailbox 26 */
+#define AA27		0x0800	/* Aborted Message In Mailbox 27 */
+#define AA28		0x1000	/* Aborted Message In Mailbox 28 */
+#define AA29		0x2000	/* Aborted Message In Mailbox 29 */
+#define AA30		0x4000	/* Aborted Message In Mailbox 30 */
+#define AA31		0x8000	/* Aborted Message In Mailbox 31 */
+
+/* CAN_TA1 Masks */
+#define TA0			0x0001	/* Transmit Successful From Mailbox 0 */
+#define TA1			0x0002	/* Transmit Successful From Mailbox 1 */
+#define TA2			0x0004	/* Transmit Successful From Mailbox 2 */
+#define TA3			0x0008	/* Transmit Successful From Mailbox 3 */
+#define TA4			0x0010	/* Transmit Successful From Mailbox 4 */
+#define TA5			0x0020	/* Transmit Successful From Mailbox 5 */
+#define TA6			0x0040	/* Transmit Successful From Mailbox 6 */
+#define TA7			0x0080	/* Transmit Successful From Mailbox 7 */
+#define TA8			0x0100	/* Transmit Successful From Mailbox 8 */
+#define TA9			0x0200	/* Transmit Successful From Mailbox 9 */
+#define TA10		0x0400	/* Transmit Successful From Mailbox 10 */
+#define TA11		0x0800	/* Transmit Successful From Mailbox 11 */
+#define TA12		0x1000	/* Transmit Successful From Mailbox 12 */
+#define TA13		0x2000	/* Transmit Successful From Mailbox 13 */
+#define TA14		0x4000	/* Transmit Successful From Mailbox 14 */
+#define TA15		0x8000	/* Transmit Successful From Mailbox 15 */
+
+/* CAN_TA2 Masks */
+#define TA16		0x0001	/* Transmit Successful From Mailbox 16 */
+#define TA17		0x0002	/* Transmit Successful From Mailbox 17 */
+#define TA18		0x0004	/* Transmit Successful From Mailbox 18 */
+#define TA19		0x0008	/* Transmit Successful From Mailbox 19 */
+#define TA20		0x0010	/* Transmit Successful From Mailbox 20 */
+#define TA21		0x0020	/* Transmit Successful From Mailbox 21 */
+#define TA22		0x0040	/* Transmit Successful From Mailbox 22 */
+#define TA23		0x0080	/* Transmit Successful From Mailbox 23 */
+#define TA24		0x0100	/* Transmit Successful From Mailbox 24 */
+#define TA25		0x0200	/* Transmit Successful From Mailbox 25 */
+#define TA26		0x0400	/* Transmit Successful From Mailbox 26 */
+#define TA27		0x0800	/* Transmit Successful From Mailbox 27 */
+#define TA28		0x1000	/* Transmit Successful From Mailbox 28 */
+#define TA29		0x2000	/* Transmit Successful From Mailbox 29 */
+#define TA30		0x4000	/* Transmit Successful From Mailbox 30 */
+#define TA31		0x8000	/* Transmit Successful From Mailbox 31 */
+
+/* CAN_MBTD Masks */
+#define TDPTR		0x001F	/* Mailbox To Temporarily Disable */
+#define TDA			0x0040	/* Temporary Disable Acknowledge */
+#define TDR			0x0080	/* Temporary Disable Request */
+
+/* CAN_RFH1 Masks */
+#define RFH0		0x0001	/* Enable Automatic Remote Frame Handling For Mailbox 0 */
+#define RFH1		0x0002	/* Enable Automatic Remote Frame Handling For Mailbox 1 */
+#define RFH2		0x0004	/* Enable Automatic Remote Frame Handling For Mailbox 2 */
+#define RFH3		0x0008	/* Enable Automatic Remote Frame Handling For Mailbox 3 */
+#define RFH4		0x0010	/* Enable Automatic Remote Frame Handling For Mailbox 4 */
+#define RFH5		0x0020	/* Enable Automatic Remote Frame Handling For Mailbox 5 */
+#define RFH6		0x0040	/* Enable Automatic Remote Frame Handling For Mailbox 6 */
+#define RFH7		0x0080	/* Enable Automatic Remote Frame Handling For Mailbox 7 */
+#define RFH8		0x0100	/* Enable Automatic Remote Frame Handling For Mailbox 8 */
+#define RFH9		0x0200	/* Enable Automatic Remote Frame Handling For Mailbox 9 */
+#define RFH10		0x0400	/* Enable Automatic Remote Frame Handling For Mailbox 10 */
+#define RFH11		0x0800	/* Enable Automatic Remote Frame Handling For Mailbox 11 */
+#define RFH12		0x1000	/* Enable Automatic Remote Frame Handling For Mailbox 12 */
+#define RFH13		0x2000	/* Enable Automatic Remote Frame Handling For Mailbox 13 */
+#define RFH14		0x4000	/* Enable Automatic Remote Frame Handling For Mailbox 14 */
+#define RFH15		0x8000	/* Enable Automatic Remote Frame Handling For Mailbox 15 */
+
+/* CAN_RFH2 Masks */
+#define RFH16		0x0001	/* Enable Automatic Remote Frame Handling For Mailbox 16 */
+#define RFH17		0x0002	/* Enable Automatic Remote Frame Handling For Mailbox 17 */
+#define RFH18		0x0004	/* Enable Automatic Remote Frame Handling For Mailbox 18 */
+#define RFH19		0x0008	/* Enable Automatic Remote Frame Handling For Mailbox 19 */
+#define RFH20		0x0010	/* Enable Automatic Remote Frame Handling For Mailbox 20 */
+#define RFH21		0x0020	/* Enable Automatic Remote Frame Handling For Mailbox 21 */
+#define RFH22		0x0040	/* Enable Automatic Remote Frame Handling For Mailbox 22 */
+#define RFH23		0x0080	/* Enable Automatic Remote Frame Handling For Mailbox 23 */
+#define RFH24		0x0100	/* Enable Automatic Remote Frame Handling For Mailbox 24 */
+#define RFH25		0x0200	/* Enable Automatic Remote Frame Handling For Mailbox 25 */
+#define RFH26		0x0400	/* Enable Automatic Remote Frame Handling For Mailbox 26 */
+#define RFH27		0x0800	/* Enable Automatic Remote Frame Handling For Mailbox 27 */
+#define RFH28		0x1000	/* Enable Automatic Remote Frame Handling For Mailbox 28 */
+#define RFH29		0x2000	/* Enable Automatic Remote Frame Handling For Mailbox 29 */
+#define RFH30		0x4000	/* Enable Automatic Remote Frame Handling For Mailbox 30 */
+#define RFH31		0x8000	/* Enable Automatic Remote Frame Handling For Mailbox 31 */
+
+/* CAN_MBTIF1 Masks */
+#define MBTIF0		0x0001	/* TX Interrupt Active In Mailbox 0 */
+#define MBTIF1		0x0002	/* TX Interrupt Active In Mailbox 1 */
+#define MBTIF2		0x0004	/* TX Interrupt Active In Mailbox 2 */
+#define MBTIF3		0x0008	/* TX Interrupt Active In Mailbox 3 */
+#define MBTIF4		0x0010	/* TX Interrupt Active In Mailbox 4 */
+#define MBTIF5		0x0020	/* TX Interrupt Active In Mailbox 5 */
+#define MBTIF6		0x0040	/* TX Interrupt Active In Mailbox 6 */
+#define MBTIF7		0x0080	/* TX Interrupt Active In Mailbox 7 */
+#define MBTIF8		0x0100	/* TX Interrupt Active In Mailbox 8 */
+#define MBTIF9		0x0200	/* TX Interrupt Active In Mailbox 9 */
+#define MBTIF10		0x0400	/* TX Interrupt Active In Mailbox 10 */
+#define MBTIF11		0x0800	/* TX Interrupt Active In Mailbox 11 */
+#define MBTIF12		0x1000	/* TX Interrupt Active In Mailbox 12 */
+#define MBTIF13		0x2000	/* TX Interrupt Active In Mailbox 13 */
+#define MBTIF14		0x4000	/* TX Interrupt Active In Mailbox 14 */
+#define MBTIF15		0x8000	/* TX Interrupt Active In Mailbox 15 */
+
+/* CAN_MBTIF2 Masks */
+#define MBTIF16		0x0001	/* TX Interrupt Active In Mailbox 16 */
+#define MBTIF17		0x0002	/* TX Interrupt Active In Mailbox 17 */
+#define MBTIF18		0x0004	/* TX Interrupt Active In Mailbox 18 */
+#define MBTIF19		0x0008	/* TX Interrupt Active In Mailbox 19 */
+#define MBTIF20		0x0010	/* TX Interrupt Active In Mailbox 20 */
+#define MBTIF21		0x0020	/* TX Interrupt Active In Mailbox 21 */
+#define MBTIF22		0x0040	/* TX Interrupt Active In Mailbox 22 */
+#define MBTIF23		0x0080	/* TX Interrupt Active In Mailbox 23 */
+#define MBTIF24		0x0100	/* TX Interrupt Active In Mailbox 24 */
+#define MBTIF25		0x0200	/* TX Interrupt Active In Mailbox 25 */
+#define MBTIF26		0x0400	/* TX Interrupt Active In Mailbox 26 */
+#define MBTIF27		0x0800	/* TX Interrupt Active In Mailbox 27 */
+#define MBTIF28		0x1000	/* TX Interrupt Active In Mailbox 28 */
+#define MBTIF29		0x2000	/* TX Interrupt Active In Mailbox 29 */
+#define MBTIF30		0x4000	/* TX Interrupt Active In Mailbox 30 */
+#define MBTIF31		0x8000	/* TX Interrupt Active In Mailbox 31 */
+
+/* CAN_MBRIF1 Masks */
+#define MBRIF0		0x0001	/* RX Interrupt Active In Mailbox 0 */
+#define MBRIF1		0x0002	/* RX Interrupt Active In Mailbox 1 */
+#define MBRIF2		0x0004	/* RX Interrupt Active In Mailbox 2 */
+#define MBRIF3		0x0008	/* RX Interrupt Active In Mailbox 3 */
+#define MBRIF4		0x0010	/* RX Interrupt Active In Mailbox 4 */
+#define MBRIF5		0x0020	/* RX Interrupt Active In Mailbox 5 */
+#define MBRIF6		0x0040	/* RX Interrupt Active In Mailbox 6 */
+#define MBRIF7		0x0080	/* RX Interrupt Active In Mailbox 7 */
+#define MBRIF8		0x0100	/* RX Interrupt Active In Mailbox 8 */
+#define MBRIF9		0x0200	/* RX Interrupt Active In Mailbox 9 */
+#define MBRIF10		0x0400	/* RX Interrupt Active In Mailbox 10 */
+#define MBRIF11		0x0800	/* RX Interrupt Active In Mailbox 11 */
+#define MBRIF12		0x1000	/* RX Interrupt Active In Mailbox 12 */
+#define MBRIF13		0x2000	/* RX Interrupt Active In Mailbox 13 */
+#define MBRIF14		0x4000	/* RX Interrupt Active In Mailbox 14 */
+#define MBRIF15		0x8000	/* RX Interrupt Active In Mailbox 15 */
+
+/* CAN_MBRIF2 Masks */
+#define MBRIF16		0x0001	/* RX Interrupt Active In Mailbox 16 */
+#define MBRIF17		0x0002	/* RX Interrupt Active In Mailbox 17 */
+#define MBRIF18		0x0004	/* RX Interrupt Active In Mailbox 18 */
+#define MBRIF19		0x0008	/* RX Interrupt Active In Mailbox 19 */
+#define MBRIF20		0x0010	/* RX Interrupt Active In Mailbox 20 */
+#define MBRIF21		0x0020	/* RX Interrupt Active In Mailbox 21 */
+#define MBRIF22		0x0040	/* RX Interrupt Active In Mailbox 22 */
+#define MBRIF23		0x0080	/* RX Interrupt Active In Mailbox 23 */
+#define MBRIF24		0x0100	/* RX Interrupt Active In Mailbox 24 */
+#define MBRIF25		0x0200	/* RX Interrupt Active In Mailbox 25 */
+#define MBRIF26		0x0400	/* RX Interrupt Active In Mailbox 26 */
+#define MBRIF27		0x0800	/* RX Interrupt Active In Mailbox 27 */
+#define MBRIF28		0x1000	/* RX Interrupt Active In Mailbox 28 */
+#define MBRIF29		0x2000	/* RX Interrupt Active In Mailbox 29 */
+#define MBRIF30		0x4000	/* RX Interrupt Active In Mailbox 30 */
+#define MBRIF31		0x8000	/* RX Interrupt Active In Mailbox 31 */
+
+/* CAN_MBIM1 Masks */
+#define MBIM0		0x0001	/* Enable Interrupt For Mailbox 0 */
+#define MBIM1		0x0002	/* Enable Interrupt For Mailbox 1 */
+#define MBIM2		0x0004	/* Enable Interrupt For Mailbox 2 */
+#define MBIM3		0x0008	/* Enable Interrupt For Mailbox 3 */
+#define MBIM4		0x0010	/* Enable Interrupt For Mailbox 4 */
+#define MBIM5		0x0020	/* Enable Interrupt For Mailbox 5 */
+#define MBIM6		0x0040	/* Enable Interrupt For Mailbox 6 */
+#define MBIM7		0x0080	/* Enable Interrupt For Mailbox 7 */
+#define MBIM8		0x0100	/* Enable Interrupt For Mailbox 8 */
+#define MBIM9		0x0200	/* Enable Interrupt For Mailbox 9 */
+#define MBIM10		0x0400	/* Enable Interrupt For Mailbox 10 */
+#define MBIM11		0x0800	/* Enable Interrupt For Mailbox 11 */
+#define MBIM12		0x1000	/* Enable Interrupt For Mailbox 12 */
+#define MBIM13		0x2000	/* Enable Interrupt For Mailbox 13 */
+#define MBIM14		0x4000	/* Enable Interrupt For Mailbox 14 */
+#define MBIM15		0x8000	/* Enable Interrupt For Mailbox 15 */
+
+/* CAN_MBIM2 Masks */
+#define MBIM16		0x0001	/* Enable Interrupt For Mailbox 16 */
+#define MBIM17		0x0002	/* Enable Interrupt For Mailbox 17 */
+#define MBIM18		0x0004	/* Enable Interrupt For Mailbox 18 */
+#define MBIM19		0x0008	/* Enable Interrupt For Mailbox 19 */
+#define MBIM20		0x0010	/* Enable Interrupt For Mailbox 20 */
+#define MBIM21		0x0020	/* Enable Interrupt For Mailbox 21 */
+#define MBIM22		0x0040	/* Enable Interrupt For Mailbox 22 */
+#define MBIM23		0x0080	/* Enable Interrupt For Mailbox 23 */
+#define MBIM24		0x0100	/* Enable Interrupt For Mailbox 24 */
+#define MBIM25		0x0200	/* Enable Interrupt For Mailbox 25 */
+#define MBIM26		0x0400	/* Enable Interrupt For Mailbox 26 */
+#define MBIM27		0x0800	/* Enable Interrupt For Mailbox 27 */
+#define MBIM28		0x1000	/* Enable Interrupt For Mailbox 28 */
+#define MBIM29		0x2000	/* Enable Interrupt For Mailbox 29 */
+#define MBIM30		0x4000	/* Enable Interrupt For Mailbox 30 */
+#define MBIM31		0x8000	/* Enable Interrupt For Mailbox 31 */
+
+/* CAN_GIM Masks */
+#define EWTIM		0x0001	/* Enable TX Error Count Interrupt */
+#define EWRIM		0x0002	/* Enable RX Error Count Interrupt */
+#define EPIM		0x0004	/* Enable Error-Passive Mode Interrupt */
+#define BOIM		0x0008	/* Enable Bus Off Interrupt */
+#define WUIM		0x0010	/* Enable Wake-Up Interrupt */
+#define UIAIM		0x0020	/* Enable Access To Unimplemented Address Interrupt */
+#define AAIM		0x0040	/* Enable Abort Acknowledge Interrupt */
+#define RMLIM		0x0080	/* Enable RX Message Lost Interrupt */
+#define UCEIM		0x0100	/* Enable Universal Counter Overflow Interrupt */
+#define EXTIM		0x0200	/* Enable External Trigger Output Interrupt */
+#define ADIM		0x0400	/* Enable Access Denied Interrupt */
+
+/* CAN_GIS Masks */
+#define EWTIS		0x0001	/* TX Error Count IRQ Status */
+#define EWRIS		0x0002	/* RX Error Count IRQ Status */
+#define EPIS		0x0004	/* Error-Passive Mode IRQ Status */
+#define BOIS		0x0008	/* Bus Off IRQ Status */
+#define WUIS		0x0010	/* Wake-Up IRQ Status */
+#define UIAIS		0x0020	/* Access To Unimplemented Address IRQ Status */
+#define AAIS		0x0040	/* Abort Acknowledge IRQ Status */
+#define RMLIS		0x0080	/* RX Message Lost IRQ Status */
+#define UCEIS		0x0100	/* Universal Counter Overflow IRQ Status */
+#define EXTIS		0x0200	/* External Trigger Output IRQ Status */
+#define ADIS		0x0400	/* Access Denied IRQ Status */
+
+/* CAN_GIF Masks */
+#define EWTIF		0x0001	/* TX Error Count IRQ Flag */
+#define EWRIF		0x0002	/* RX Error Count IRQ Flag */
+#define EPIF		0x0004	/* Error-Passive Mode IRQ Flag */
+#define BOIF		0x0008	/* Bus Off IRQ Flag */
+#define WUIF		0x0010	/* Wake-Up IRQ Flag */
+#define UIAIF		0x0020	/* Access To Unimplemented Address IRQ Flag */
+#define AAIF		0x0040	/* Abort Acknowledge IRQ Flag */
+#define RMLIF		0x0080	/* RX Message Lost IRQ Flag */
+#define UCEIF		0x0100	/* Universal Counter Overflow IRQ Flag */
+#define EXTIF		0x0200	/* External Trigger Output IRQ Flag */
+#define ADIF		0x0400	/* Access Denied IRQ Flag */
+
+/* CAN_UCCNF Masks */
+#define UCCNF		0x000F	/* Universal Counter Mode */
+#define UC_STAMP	0x0001	/*  Timestamp Mode */
+#define UC_WDOG		0x0002	/*  Watchdog Mode */
+#define UC_AUTOTX	0x0003	/*  Auto-Transmit Mode */
+#define UC_ERROR	0x0006	/*  CAN Error Frame Count */
+#define UC_OVER		0x0007	/*  CAN Overload Frame Count */
+#define UC_LOST		0x0008	/*  Arbitration Lost During TX Count */
+#define UC_AA		0x0009	/*  TX Abort Count */
+#define UC_TA		0x000A	/*  TX Successful Count */
+#define UC_REJECT	0x000B	/*  RX Message Rejected Count */
+#define UC_RML		0x000C	/*  RX Message Lost Count */
+#define UC_RX		0x000D	/*  Total Successful RX Messages Count */
+#define UC_RMP		0x000E	/*  Successful RX W/Matching ID Count */
+#define UC_ALL		0x000F	/*  Correct Message On CAN Bus Line Count */
+#define UCRC		0x0020	/* Universal Counter Reload/Clear */
+#define UCCT		0x0040	/* Universal Counter CAN Trigger */
+#define UCE			0x0080	/* Universal Counter Enable */
+
+/* CAN_ESR Masks */
+#define ACKE		0x0004	/* Acknowledge Error */
+#define SER			0x0008	/* Stuff Error */
+#define CRCE		0x0010	/* CRC Error */
+#define SA0			0x0020	/* Stuck At Dominant Error */
+#define BEF			0x0040	/* Bit Error Flag */
+#define FER			0x0080	/* Form Error Flag */
+
+/* CAN_EWR Masks */
+#define EWLREC		0x00FF	/* RX Error Count Limit (For EWRIS) */
+#define EWLTEC		0xFF00	/* TX Error Count Limit (For EWTIS) */
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/bfin-lq035q1.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/bfin-lq035q1.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/bfin-lq035q1.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/bfin-lq035q1.h	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,9 @@
 #ifndef BFIN_LQ035Q1_H
 #define BFIN_LQ035Q1_H
 
+/*
+ * LCD Modes
+ */
 #define LQ035_RL	(0 << 8)	/* Right -> Left Scan */
 #define LQ035_LR	(1 << 8)	/* Left -> Right Scan */
 #define LQ035_TB	(1 << 9)	/* Top -> Botton Scan */
@@ -17,9 +20,18 @@
 #define LQ035_NORM	(1 << 13)	/* Reversal */
 #define LQ035_REV	(0 << 13)	/* Reversal */
 
+/*
+ * PPI Modes
+ */
+
+#define USE_RGB565_16_BIT_PPI	1
+#define USE_RGB565_8_BIT_PPI	2
+#define USE_RGB888_8_BIT_PPI	3
+
 struct bfin_lq035q1fb_disp_info {
 
 	unsigned	mode;
+	unsigned	ppi_mode;
 	/* GPIOs */
 	int		use_bl;
 	unsigned 	gpio_bl;
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/bfin_sport.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/bfin_sport.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/bfin_sport.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/bfin_sport.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
- * bfin_sport.h - userspace header for bfin sport driver
+ * bfin_sport.h - interface to Blackfin SPORTs
  *
- * Copyright 2004-2008 Analog Devices Inc.
+ * Copyright 2004-2009 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later.
  */
@@ -9,16 +9,6 @@
 #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
-
 /* Sport mode: it can be set to TDM, i2s or others */
 #define NORM_MODE	0x0
 #define TDM_MODE	0x1
@@ -35,7 +25,7 @@ struct sport_config {
 	unsigned int mode:3;
 
 	/* if TDM mode is selected, channels must be set */
-	int channels;		/* Must be in 8 units */
+	int channels;	/* Must be in 8 units */
 	unsigned int frame_delay:4;	/* Delay between frame sync pulse and first bit */
 
 	/* I2S mode */
@@ -69,94 +59,137 @@ struct sport_config {
 
 #ifdef __KERNEL__
 
+#include <linux/types.h>
+
+/*
+ * All Blackfin system MMRs are padded to 32bits even if the register
+ * itself is only 16bits.  So use a helper macro to streamline this.
+ */
+#define __BFP(m) u16 m; u16 __pad_##m
 struct sport_register {
-	unsigned short tcr1;
-	unsigned short reserved0;
-	unsigned short tcr2;
-	unsigned short reserved1;
-	unsigned short tclkdiv;
-	unsigned short reserved2;
-	unsigned short tfsdiv;
-	unsigned short reserved3;
-	unsigned long tx;
-	unsigned long reserved_l0;
-	unsigned long rx;
-	unsigned long reserved_l1;
-	unsigned short rcr1;
-	unsigned short reserved4;
-	unsigned short rcr2;
-	unsigned short reserved5;
-	unsigned short rclkdiv;
-	unsigned short reserved6;
-	unsigned short rfsdiv;
-	unsigned short reserved7;
-	unsigned short stat;
-	unsigned short reserved8;
-	unsigned short chnl;
-	unsigned short reserved9;
-	unsigned short mcmc1;
-	unsigned short reserved10;
-	unsigned short mcmc2;
-	unsigned short reserved11;
-	unsigned long mtcs0;
-	unsigned long mtcs1;
-	unsigned long mtcs2;
-	unsigned long mtcs3;
-	unsigned long mrcs0;
-	unsigned long mrcs1;
-	unsigned long mrcs2;
-	unsigned long mrcs3;
+	__BFP(tcr1);
+	__BFP(tcr2);
+	__BFP(tclkdiv);
+	__BFP(tfsdiv);
+	union {
+		u32 tx32;
+		u16 tx16;
+	};
+	u32 __pad_tx;
+	union {
+		u32 rx32;	/* use the anomaly wrapper below */
+		u16 rx16;
+	};
+	u32 __pad_rx;
+	__BFP(rcr1);
+	__BFP(rcr2);
+	__BFP(rclkdiv);
+	__BFP(rfsdiv);
+	__BFP(stat);
+	__BFP(chnl);
+	__BFP(mcmc1);
+	__BFP(mcmc2);
+	u32 mtcs0;
+	u32 mtcs1;
+	u32 mtcs2;
+	u32 mtcs3;
+	u32 mrcs0;
+	u32 mrcs1;
+	u32 mrcs2;
+	u32 mrcs3;
 };
+#undef __BFP
 
-struct sport_dev {
-	struct cdev cdev;	/* Char device structure */
+#define bfin_read_sport_rx32(base) \
+({ \
+	struct sport_register *__mmrs = (void *)base; \
+	u32 __ret; \
+	unsigned long flags; \
+	if (ANOMALY_05000473) \
+		local_irq_save(flags); \
+	__ret = __mmrs->rx32; \
+	if (ANOMALY_05000473) \
+		local_irq_restore(flags); \
+	__ret; \
+})
 
-	int sport_num;
+#endif
 
-	int dma_rx_chan;
-	int dma_tx_chan;
+/* Workaround defBF*.h SPORT MMRs till they get cleansed */
+#undef DTYPE_NORM
+#undef SLEN
+#undef SP_WOFF
+#undef SP_WSIZE
 
-	int rx_irq;
-	unsigned char *rx_buf;	/* Buffer store the received data */
-	int rx_len;		/* How many bytes will be received */
-	int rx_received;	/* How many bytes has been received */
+/* SPORT_TCR1 Masks */
+#define TSPEN		0x0001	/* TX enable */
+#define ITCLK		0x0002	/* Internal TX Clock Select */
+#define TDTYPE		0x000C	/* TX Data Formatting Select */
+#define DTYPE_NORM	0x0000	/* Data Format Normal */
+#define DTYPE_ULAW	0x0008	/* Compand Using u-Law */
+#define DTYPE_ALAW	0x000C	/* Compand Using A-Law */
+#define TLSBIT		0x0010	/* TX Bit Order */
+#define ITFS		0x0200	/* Internal TX Frame Sync Select */
+#define TFSR		0x0400	/* TX Frame Sync Required Select */
+#define DITFS		0x0800	/* Data Independent TX Frame Sync Select */
+#define LTFS		0x1000	/* Low TX Frame Sync Select */
+#define LATFS		0x2000	/* Late TX Frame Sync Select */
+#define TCKFE		0x4000	/* TX Clock Falling Edge Select */
 
-	int tx_irq;
-	const unsigned char *tx_buf;
-	int tx_len;
-	int tx_sent;
+/* SPORT_TCR2 Masks */
+#define SLEN		0x001F	/* SPORT TX Word Length (2 - 31) */
+#define DP_SLEN(x)	BFIN_DEPOSIT(SLEN, x)
+#define EX_SLEN(x)	BFIN_EXTRACT(SLEN, x)
+#define TXSE		0x0100	/* TX Secondary Enable */
+#define TSFSE		0x0200	/* TX Stereo Frame Sync Enable */
+#define TRFST		0x0400	/* TX Right-First Data Order */
 
-	int err_irq;
+/* SPORT_RCR1 Masks */
+#define RSPEN		0x0001	/* RX enable */
+#define IRCLK		0x0002	/* Internal RX Clock Select */
+#define RDTYPE		0x000C	/* RX Data Formatting Select */
+/* DTYPE_* defined above */
+#define RLSBIT		0x0010	/* RX Bit Order */
+#define IRFS		0x0200	/* Internal RX Frame Sync Select */
+#define RFSR		0x0400	/* RX Frame Sync Required Select */
+#define LRFS		0x1000	/* Low RX Frame Sync Select */
+#define LARFS		0x2000	/* Late RX Frame Sync Select */
+#define RCKFE		0x4000	/* RX Clock Falling Edge Select */
 
-	struct mutex mutex;	/* mutual exclusion semaphore */
-	struct task_struct *task;
+/* SPORT_RCR2 Masks */
+/* SLEN defined above */
+#define RXSE		0x0100	/* RX Secondary Enable */
+#define RSFSE		0x0200	/* RX Stereo Frame Sync Enable */
+#define RRFST		0x0400	/* Right-First Data Order */
 
-	wait_queue_head_t waitq;
-	int	wait_con;
-	struct sport_register *regs;
-	struct sport_config config;
-};
+/* SPORT_STAT Masks */
+#define RXNE		0x0001	/* RX FIFO Not Empty Status */
+#define RUVF		0x0002	/* RX Underflow Status */
+#define ROVF		0x0004	/* RX Overflow Status */
+#define TXF		0x0008	/* TX FIFO Full Status */
+#define TUVF		0x0010	/* TX Underflow Status */
+#define TOVF		0x0020	/* TX Overflow Status */
+#define TXHRE		0x0040	/* TX Hold Register Empty */
 
-#endif
+/* SPORT_MCMC1 Masks */
+#define SP_WOFF		0x03FF	/* Multichannel Window Offset Field */
+#define DP_SP_WOFF(x)	BFIN_DEPOSIT(SP_WOFF, x)
+#define EX_SP_WOFF(x)	BFIN_EXTRACT(SP_WOFF, x)
+#define SP_WSIZE	0xF000	/* Multichannel Window Size Field */
+#define DP_SP_WSIZE(x)	BFIN_DEPOSIT(SP_WSIZE, x)
+#define EX_SP_WSIZE(x)	BFIN_EXTRACT(SP_WSIZE, x)
 
-#define SPORT_TCR1	0
-#define	SPORT_TCR2	1
-#define	SPORT_TCLKDIV	2
-#define	SPORT_TFSDIV	3
-#define	SPORT_RCR1	8
-#define	SPORT_RCR2	9
-#define SPORT_RCLKDIV	10
-#define	SPORT_RFSDIV	11
-#define SPORT_CHANNEL	13
-#define SPORT_MCMC1	14
-#define SPORT_MCMC2	15
-#define SPORT_MTCS0	16
-#define SPORT_MTCS1	17
-#define SPORT_MTCS2	18
-#define SPORT_MTCS3	19
-#define SPORT_MRCS0	20
-#define SPORT_MRCS1	21
-#define SPORT_MRCS2	22
-#define SPORT_MRCS3	23
+/* SPORT_MCMC2 Masks */
+#define MCCRM		0x0003	/* Multichannel Clock Recovery Mode */
+#define REC_BYPASS	0x0000	/* Bypass Mode (No Clock Recovery) */
+#define REC_2FROM4	0x0002	/* Recover 2 MHz Clock from 4 MHz Clock */
+#define REC_8FROM16	0x0003	/* Recover 8 MHz Clock from 16 MHz Clock */
+#define MCDTXPE		0x0004	/* Multichannel DMA Transmit Packing */
+#define MCDRXPE		0x0008	/* Multichannel DMA Receive Packing */
+#define MCMEN		0x0010	/* Multichannel Frame Mode Enable */
+#define FSDR		0x0080	/* Multichannel Frame Sync to Data Relationship */
+#define MFD		0xF000	/* Multichannel Frame Delay */
+#define DP_MFD(x)	BFIN_DEPOSIT(MFD, x)
+#define EX_MFD(x)	BFIN_EXTRACT(MFD, x)
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/bfin_watchdog.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/bfin_watchdog.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/bfin_watchdog.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/bfin_watchdog.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,30 @@
+/*
+ * bfin_watchdog.h - Blackfin watchdog definitions
+ *
+ * Copyright 2006-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef _BFIN_WATCHDOG_H
+#define _BFIN_WATCHDOG_H
+
+/* Bit in SWRST that indicates boot caused by watchdog */
+#define SWRST_RESET_WDOG 0x4000
+
+/* Bit in WDOG_CTL that indicates watchdog has expired (WDR0) */
+#define WDOG_EXPIRED 0x8000
+
+/* Masks for WDEV field in WDOG_CTL register */
+#define ICTL_RESET   0x0
+#define ICTL_NMI     0x2
+#define ICTL_GPI     0x4
+#define ICTL_NONE    0x6
+#define ICTL_MASK    0x6
+
+/* Masks for WDEN field in WDOG_CTL register */
+#define WDEN_MASK    0x0FF0
+#define WDEN_ENABLE  0x0000
+#define WDEN_DISABLE 0x0AD0
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/bitops.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/bitops.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/bitops.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/bitops.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,22 +7,41 @@
 #ifndef _BLACKFIN_BITOPS_H
 #define _BLACKFIN_BITOPS_H
 
-#ifndef CONFIG_SMP
-# include <asm-generic/bitops.h>
-#else
+#include <linux/compiler.h>
+
+#include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/__fls.h>
+#include <asm-generic/bitops/fls64.h>
+#include <asm-generic/bitops/find.h>
 
 #ifndef _LINUX_BITOPS_H
 #error only <linux/bitops.h> can be included directly
 #endif
 
-#include <linux/compiler.h>
-#include <asm/byteorder.h>	/* swab32 */
-
-#include <asm-generic/bitops/ffs.h>
-#include <asm-generic/bitops/__ffs.h>
 #include <asm-generic/bitops/sched.h>
-#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/ffs.h>
+#include <asm-generic/bitops/lock.h>
+#include <asm-generic/bitops/ext2-non-atomic.h>
+#include <asm-generic/bitops/ext2-atomic.h>
+#include <asm-generic/bitops/minix.h>
+
+#ifndef CONFIG_SMP
+#include <linux/irqflags.h>
+
+/*
+ * clear_bit may not imply a memory barrier
+ */
+#ifndef smp_mb__before_clear_bit
+#define smp_mb__before_clear_bit()	smp_mb()
+#define smp_mb__after_clear_bit()	smp_mb()
+#endif
+#include <asm-generic/bitops/atomic.h>
+#include <asm-generic/bitops/non-atomic.h>
+#else
 
+#include <asm/byteorder.h>	/* swab32 */
 #include <linux/linkage.h>
 
 asmlinkage int __raw_bit_set_asm(volatile unsigned long *addr, int nr);
@@ -89,19 +108,36 @@ static inline int test_and_change_bit(in
 
 #include <asm-generic/bitops/non-atomic.h>
 
-#include <asm-generic/bitops/find.h>
-#include <asm-generic/bitops/hweight.h>
-#include <asm-generic/bitops/lock.h>
+#endif /* CONFIG_SMP */
 
-#include <asm-generic/bitops/ext2-atomic.h>
-#include <asm-generic/bitops/ext2-non-atomic.h>
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
 
-#include <asm-generic/bitops/minix.h>
+static inline unsigned int hweight32(unsigned int w)
+{
+	unsigned int res;
 
-#include <asm-generic/bitops/fls.h>
-#include <asm-generic/bitops/__fls.h>
-#include <asm-generic/bitops/fls64.h>
+	__asm__ ("%0.l = ONES %0;"
+		"%0 = %0.l (Z);"
+		: "=d" (res) : "d" (w));
+	return res;
+}
 
-#endif /* CONFIG_SMP */
+static inline unsigned int hweight64(__u64 w)
+{
+	return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
+}
+
+static inline unsigned int hweight16(unsigned int w)
+{
+	return hweight32(w & 0xffff);
+}
+
+static inline unsigned int hweight8(unsigned int w)
+{
+	return hweight32(w & 0xff);
+}
 
 #endif				/* _BLACKFIN_BITOPS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/context.S linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/context.S
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/context.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/context.S	2010-05-16 17:17:36.000000000 -0400
@@ -73,6 +73,11 @@
 #else
 	cli r0;
 #endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+	sp += -12;
+	call _trace_hardirqs_off;
+	sp += 12;
+#endif
 	[--sp] = RETI;  /*orig_pc*/
 	/* Clear all L registers.  */
 	r0 = 0 (x);
@@ -279,6 +284,13 @@
 	RETN = [sp++];
 	RETX = [sp++];
 	RETI = [sp++];
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+	sp += -12;
+	call _trace_hardirqs_on;
+	sp += 12;
+#endif
+
 	RETS = [sp++];
 
 #ifdef CONFIG_SMP
@@ -374,3 +386,13 @@
 
 	(R7:0, P5:0) = [SP++];
 .endm
+
+.macro pseudo_long_call func:req, scratch:req
+#ifdef CONFIG_ROMKERNEL
+	\scratch\().l = \func;
+	\scratch\().h = \func;
+	call (\scratch);
+#else
+	call \func;
+#endif
+.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/cpu.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/cpu.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/cpu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/cpu.h	2010-05-16 17:17:36.000000000 -0400
@@ -17,8 +17,6 @@ struct blackfin_cpudata {
 	struct task_struct *idle;
 	unsigned int imemctl;
 	unsigned int dmemctl;
-	unsigned long dcache_invld_count;
-	unsigned long icache_invld_count;
 };
 
 DECLARE_PER_CPU(struct blackfin_cpudata, cpu_data);
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/def_LPBlackfin.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/def_LPBlackfin.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/def_LPBlackfin.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/def_LPBlackfin.h	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,8 @@
 #include <mach/anomaly.h>
 
 #define MK_BMSK_(x) (1<<x)
+#define BFIN_DEPOSIT(mask, x)	(((x) << __ffs(mask)) & (mask))
+#define BFIN_EXTRACT(mask, x)	(((x) & (mask)) >> __ffs(mask))
 
 #ifndef __ASSEMBLY__
 
@@ -23,62 +25,30 @@
 # define NOP_PAD_ANOMALY_05000198
 #endif
 
-#define bfin_read8(addr) ({ \
-	uint32_t __v; \
-	__asm__ __volatile__( \
-		NOP_PAD_ANOMALY_05000198 \
-		"%0 = b[%1] (z);" \
-		: "=d" (__v) \
-		: "a" (addr) \
-	); \
-	__v; })
-
-#define bfin_read16(addr) ({ \
-	uint32_t __v; \
-	__asm__ __volatile__( \
-		NOP_PAD_ANOMALY_05000198 \
-		"%0 = w[%1] (z);" \
-		: "=d" (__v) \
-		: "a" (addr) \
-	); \
-	__v; })
-
-#define bfin_read32(addr) ({ \
-	uint32_t __v; \
+#define _bfin_readX(addr, size, asm_size, asm_ext) ({ \
+	u32 __v; \
 	__asm__ __volatile__( \
 		NOP_PAD_ANOMALY_05000198 \
-		"%0 = [%1];" \
+		"%0 = " #asm_size "[%1]" #asm_ext ";" \
 		: "=d" (__v) \
 		: "a" (addr) \
 	); \
 	__v; })
-
-#define bfin_write8(addr, val) \
-	__asm__ __volatile__( \
-		NOP_PAD_ANOMALY_05000198 \
-		"b[%0] = %1;" \
-		: \
-		: "a" (addr), "d" ((uint8_t)(val)) \
-		: "memory" \
-	)
-
-#define bfin_write16(addr, val) \
+#define _bfin_writeX(addr, val, size, asm_size) \
 	__asm__ __volatile__( \
 		NOP_PAD_ANOMALY_05000198 \
-		"w[%0] = %1;" \
+		#asm_size "[%0] = %1;" \
 		: \
-		: "a" (addr), "d" ((uint16_t)(val)) \
+		: "a" (addr), "d" ((u##size)(val)) \
 		: "memory" \
 	)
 
-#define bfin_write32(addr, val) \
-	__asm__ __volatile__( \
-		NOP_PAD_ANOMALY_05000198 \
-		"[%0] = %1;" \
-		: \
-		: "a" (addr), "d" (val) \
-		: "memory" \
-	)
+#define bfin_read8(addr)  _bfin_readX(addr,  8, b, (z))
+#define bfin_read16(addr) _bfin_readX(addr, 16, w, (z))
+#define bfin_read32(addr) _bfin_readX(addr, 32,  ,    )
+#define bfin_write8(addr, val)  _bfin_writeX(addr, val,  8, b)
+#define bfin_write16(addr, val) _bfin_writeX(addr, val, 16, w)
+#define bfin_write32(addr, val) _bfin_writeX(addr, val, 32,  )
 
 #endif /* __ASSEMBLY__ */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/delay.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/delay.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/delay.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/delay.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,10 +30,22 @@ __asm__ __volatile__ (
 
 #define	HZSCALE		(268435456 / (1000000/HZ))
 
-static inline void udelay(unsigned long usecs)
+static inline unsigned long __to_delay(unsigned long scale)
 {
 	extern unsigned long loops_per_jiffy;
-	__delay((((usecs * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6);
+	return (((scale * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6;
+}
+
+static inline void udelay(unsigned long usecs)
+{
+	__delay(__to_delay(usecs));
+}
+
+static inline void ndelay(unsigned long nsecs)
+{
+	__delay(__to_delay(1) * nsecs / 1000);
 }
 
+#define ndelay ndelay
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/dma.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/dma.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/dma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/dma.h	2010-05-16 17:17:36.000000000 -0400
@@ -262,6 +262,10 @@ static inline void dma_disable_irq(unsig
 {
 	disable_irq(dma_ch[channel].irq);
 }
+static inline void dma_disable_irq_nosync(unsigned int channel)
+{
+	disable_irq_nosync(dma_ch[channel].irq);
+}
 static inline void dma_enable_irq(unsigned int channel)
 {
 	enable_irq(dma_ch[channel].irq);
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/dma-mapping.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/dma-mapping.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/dma-mapping.h	2010-05-16 17:17:36.000000000 -0400
@@ -44,13 +44,8 @@ dma_mapping_error(struct device *dev, dm
 extern void
 __dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir);
 static inline void
-_dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir)
+__dma_sync_inline(dma_addr_t addr, size_t size, enum dma_data_direction dir)
 {
-	if (!__builtin_constant_p(dir)) {
-		__dma_sync(addr, size, dir);
-		return;
-	}
-
 	switch (dir) {
 	case DMA_NONE:
 		BUG();
@@ -64,14 +59,15 @@ _dma_sync(dma_addr_t addr, size_t size,
 		break;
 	}
 }
+static inline void
+_dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir)
+{
+	if (__builtin_constant_p(dir))
+		__dma_sync_inline(addr, size, dir);
+	else
+		__dma_sync(addr, size, dir);
+}
 
-/*
- * 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 dir)
@@ -88,14 +84,6 @@ dma_map_page(struct device *dev, struct
 	return dma_map_single(dev, page_address(page) + offset, size, dir);
 }
 
-/*
- * 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 dir)
@@ -110,30 +98,9 @@ dma_unmap_page(struct device *dev, dma_a
 	dma_unmap_single(dev, dma_addr, size, dir);
 }
 
-/*
- * 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 dir);
 
-/*
- * Unmap a set of streaming mode DMA translations.
- * Again, cpu read rules concerning calls here are the same as for
- * pci_unmap_single() above.
- */
 static inline void
 dma_unmap_sg(struct device *dev, struct scatterlist *sg,
 	     int nhwentries, enum dma_data_direction dir)
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/dpmc.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/dpmc.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/dpmc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/dpmc.h	2010-05-16 17:17:36.000000000 -0400
@@ -75,7 +75,7 @@
 
 #define VLEV			0x00F0	/* Internal Voltage Level */
 #ifdef __ADSPBF52x__
-#define VLEV_085 		0x0040	/* VLEV = 0.85 V (-5% - +10% Accuracy) */
+#define VLEV_085		0x0040	/* VLEV = 0.85 V (-5% - +10% Accuracy) */
 #define VLEV_090		0x0050	/* VLEV = 0.90 V (-5% - +10% Accuracy) */
 #define VLEV_095		0x0060	/* VLEV = 0.95 V (-5% - +10% Accuracy) */
 #define VLEV_100		0x0070	/* VLEV = 1.00 V (-5% - +10% Accuracy) */
@@ -84,7 +84,7 @@
 #define VLEV_115		0x00A0	/* VLEV = 1.15 V (-5% - +10% Accuracy) */
 #define VLEV_120		0x00B0	/* VLEV = 1.20 V (-5% - +10% Accuracy) */
 #else
-#define VLEV_085 		0x0060	/* VLEV = 0.85 V (-5% - +10% Accuracy) */
+#define VLEV_085		0x0060	/* VLEV = 0.85 V (-5% - +10% Accuracy) */
 #define VLEV_090		0x0070	/* VLEV = 0.90 V (-5% - +10% Accuracy) */
 #define VLEV_095		0x0080	/* VLEV = 0.95 V (-5% - +10% Accuracy) */
 #define VLEV_100		0x0090	/* VLEV = 1.00 V (-5% - +10% Accuracy) */
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/elf.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/elf.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/elf.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,12 +22,15 @@
 #define EF_BFIN_CODE_IN_L2	0x00000040	/* --code-in-l2 */
 #define EF_BFIN_DATA_IN_L2	0x00000080	/* --data-in-l2 */
 
+#if 1	/* core dumps not supported, but linux/elfcore.h needs these */
 typedef unsigned long elf_greg_t;
 
-#define ELF_NGREG 40 /* (sizeof(struct user_regs_struct) / sizeof(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 { } elf_fpregset_t;
+#endif
+
 /*
  * This is used to ensure we don't load something for the wrong architecture.
  */
@@ -55,6 +58,9 @@ do {											\
 	_regs->p2	= _dynamic_addr;				\
 } while(0)
 
+#if 0
+#define CORE_DUMP_USE_REGSET
+#endif
 #define ELF_FDPIC_CORE_EFLAGS	EF_BFIN_FDPIC
 #define ELF_EXEC_PAGESIZE	4096
 
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/ftrace.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/ftrace.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/ftrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/ftrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -10,4 +10,57 @@
 
 #define MCOUNT_INSN_SIZE	6 /* sizeof "[++sp] = rets; call __mcount;" */
 
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_FRAME_POINTER
+#include <linux/mm.h>
+
+extern inline void *return_address(unsigned int level)
+{
+	unsigned long *endstack, *fp, *ret_addr;
+	unsigned int current_level = 0;
+
+	if (level == 0)
+		return __builtin_return_address(0);
+
+	fp = (unsigned long *)__builtin_frame_address(0);
+	endstack = (unsigned long *)PAGE_ALIGN((unsigned long)&level);
+
+	while (((unsigned long)fp & 0x3) == 0 && fp &&
+	       (fp + 1) < endstack && current_level < level) {
+		fp = (unsigned long *)*fp;
+		current_level++;
+	}
+
+	if (((unsigned long)fp & 0x3) == 0 && fp &&
+	    (fp + 1) < endstack)
+		ret_addr = (unsigned long *)*(fp + 1);
+	else
+		ret_addr = NULL;
+
+	return ret_addr;
+}
+
+#else
+
+extern inline void *return_address(unsigned int level)
+{
+	return NULL;
+}
+
+#endif /* CONFIG_FRAME_POINTER */
+
+#define HAVE_ARCH_CALLER_ADDR
+
+/* inline function or macro may lead to unexpected result */
+#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#define CALLER_ADDR1 ((unsigned long)return_address(1))
+#define CALLER_ADDR2 ((unsigned long)return_address(2))
+#define CALLER_ADDR3 ((unsigned long)return_address(3))
+#define CALLER_ADDR4 ((unsigned long)return_address(4))
+#define CALLER_ADDR5 ((unsigned long)return_address(5))
+#define CALLER_ADDR6 ((unsigned long)return_address(6))
+
+#endif /* __ASSEMBLY__ */
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/gpio.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/gpio.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/gpio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/gpio.h	2010-05-16 17:17:36.000000000 -0400
@@ -70,6 +70,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/compiler.h>
+
 /***********************************************************
 *
 * FUNCTIONS: Blackfin General Purpose Ports Access Functions
@@ -223,6 +225,9 @@ int bfin_gpio_direction_output(unsigned
 int bfin_gpio_get_value(unsigned gpio);
 void bfin_gpio_set_value(unsigned gpio, int value);
 
+#include <asm/irq.h>
+#include <asm/errno.h>
+
 #ifdef CONFIG_GPIOLIB
 #include <asm-generic/gpio.h>		/* cansleep wrappers */
 
@@ -247,6 +252,11 @@ static inline int gpio_cansleep(unsigned
 	return __gpio_cansleep(gpio);
 }
 
+static inline int gpio_to_irq(unsigned gpio)
+{
+	return __gpio_to_irq(gpio);
+}
+
 #else /* !CONFIG_GPIOLIB */
 
 static inline int gpio_request(unsigned gpio, const char *label)
@@ -279,10 +289,6 @@ static inline void gpio_set_value(unsign
 	return bfin_gpio_set_value(gpio, value);
 }
 
-#include <asm-generic/gpio.h>		/* cansleep wrappers */
-#endif	/* !CONFIG_GPIOLIB */
-#include <asm/irq.h>
-
 static inline int gpio_to_irq(unsigned gpio)
 {
 	if (likely(gpio < MAX_BLACKFIN_GPIOS))
@@ -291,6 +297,9 @@ static inline int gpio_to_irq(unsigned g
 	return -EINVAL;
 }
 
+#include <asm-generic/gpio.h>		/* cansleep wrappers */
+#endif	/* !CONFIG_GPIOLIB */
+
 static inline int irq_to_gpio(unsigned irq)
 {
 	return (irq - GPIO_IRQ_BASE);
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/irq.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/irq.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/irq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,9 @@
 
 #include <linux/irqflags.h>
 
+/* IRQs that may be used by external irq_chip controllers */
+#define NR_SPARE_IRQS	32
+
 #include <mach/anomaly.h>
 
 /* SYS_IRQS and NR_IRQS are defined in <mach-bf5xx/irq.h> */
@@ -35,4 +38,8 @@
 
 #include <asm-generic/irq.h>
 
+#ifdef CONFIG_NMI_WATCHDOG
+# define ARCH_HAS_NMI_WATCHDOG
+#endif
+
 #endif				/* _BFIN_IRQ_H_ */
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/mmu_context.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/mmu_context.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/mmu_context.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/mmu_context.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,12 +7,13 @@
 #ifndef __BLACKFIN_MMU_CONTEXT_H__
 #define __BLACKFIN_MMU_CONTEXT_H__
 
-#include <linux/gfp.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <asm/setup.h>
 #include <asm/page.h>
 #include <asm/pgalloc.h>
 #include <asm/cplbinit.h>
+#include <asm/sections.h>
 
 /* Note: L1 stacks are CPU-private things, so we bluntly disable this
    feature in SMP mode, and use the per-CPU scratch SRAM bank only to
@@ -117,9 +118,16 @@ static inline void protect_page(struct m
 				unsigned long flags)
 {
 	unsigned long *mask = mm->context.page_rwx_mask;
-	unsigned long page = addr >> 12;
-	unsigned long idx = page >> 5;
-	unsigned long bit = 1 << (page & 31);
+	unsigned long page;
+	unsigned long idx;
+	unsigned long bit;
+
+	if (unlikely(addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE))
+		page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> 12;
+	else
+		page = addr >> 12;
+	idx = page >> 5;
+	bit = 1 << (page & 31);
 
 	if (flags & VM_READ)
 		mask[idx] |= bit;
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/nand.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/nand.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/nand.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/nand.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * BF5XX - NAND flash controller platfrom_device info
+ * BF5XX - NAND flash controller platform_device info
  *
  * Copyright 2007-2008 Analog Devices, Inc.
  *
@@ -8,7 +8,7 @@
 
 /* struct bf5xx_nand_platform
  *
- * define a interface between platfrom board specific code and
+ * define a interface between platform board specific code and
  * bf54x NFC driver.
  *
  * nr_partitions = number of partitions pointed to be partitoons (or zero)
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/nmi.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/nmi.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/nmi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/nmi.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2
+ */
+
+#ifndef _BFIN_NMI_H_
+#define _BFIN_NMI_H_
+
+#include <linux/nmi.h>
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/page.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/page.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/page.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/page.h	2010-05-16 17:17:36.000000000 -0400
@@ -15,4 +15,7 @@
 	((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
 		 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#include <asm-generic/memory_model.h>
+#include <asm-generic/getorder.h>
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,8 @@
 
 #ifndef __ASSEMBLY__
 
+struct task_struct;
+
 /* this struct defines the way the registers are stored on the
    stack during a system call. */
 
@@ -101,9 +103,30 @@ struct pt_regs {
    master interrupt enable.  */
 #define user_mode(regs) (!(((regs)->ipend & ~0x10) & (((regs)->ipend & ~0x10) - 1)))
 #define instruction_pointer(regs) ((regs)->pc)
+#define user_stack_pointer(regs)  ((regs)->usp)
 #define profile_pc(regs) instruction_pointer(regs)
 extern void show_regs(struct pt_regs *);
 
+#define arch_has_single_step()	(1)
+extern void user_enable_single_step(struct task_struct *child);
+extern void user_disable_single_step(struct task_struct *child);
+/* common code demands this function */
+#define ptrace_disable(child) user_disable_single_step(child)
+
+/*
+ * Get the address of the live pt_regs for the specified task.
+ * These are saved onto the top kernel stack when the process
+ * is not running.
+ *
+ * Note: if a user thread is execve'd from kernel space, the
+ * kernel stack will not be empty on entry to the kernel, so
+ * ptracing these tasks will fail.
+ */
+#define task_pt_regs(task) \
+	(struct pt_regs *) \
+	    ((unsigned long)task_stack_page(task) + \
+	     (THREAD_SIZE - sizeof(struct pt_regs)))
+
 #endif  /*  __KERNEL__  */
 
 #endif				/* __ASSEMBLY__ */
@@ -173,4 +196,6 @@ extern void show_regs(struct pt_regs *);
 #define PT_FDPIC_EXEC 232
 #define PT_FDPIC_INTERP 236
 
+#define PT_LAST_PSEUDO PT_FDPIC_INTERP
+
 #endif				/* _BFIN_PTRACE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/sections.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/sections.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/sections.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/sections.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,9 @@ extern unsigned long memory_start, memor
 extern char _stext_l1[], _etext_l1[], _text_l1_lma[], __weak _text_l1_len[];
 extern char _sdata_l1[], _edata_l1[], _sbss_l1[], _ebss_l1[],
 	_data_l1_lma[], __weak _data_l1_len[];
+#ifdef CONFIG_ROMKERNEL
+extern char _data_lma[], _data_len[], _sinitdata[], _einitdata[], _init_data_lma[], _init_data_len[];
+#endif
 extern char _sdata_b_l1[], _edata_b_l1[], _sbss_b_l1[], _ebss_b_l1[],
 	_data_b_l1_lma[], __weak _data_b_l1_len[];
 extern char _stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[],
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/smp.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/smp.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/smp.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/smp.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,8 +22,23 @@ extern char coreb_trampoline_start, core
 struct corelock_slot {
 	int lock;
 };
+extern struct corelock_slot corelock;
+
+#ifdef __ARCH_SYNC_CORE_ICACHE
+extern unsigned long icache_invld_count[NR_CPUS];
+#endif
+#ifdef __ARCH_SYNC_CORE_DCACHE
+extern unsigned long dcache_invld_count[NR_CPUS];
+#endif
 
 void smp_icache_flush_range_others(unsigned long start,
 				   unsigned long end);
+#ifdef CONFIG_HOTPLUG_CPU
+void coreb_sleep(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
+void cpu_die(void);
+void platform_cpu_die(void);
+int __cpu_disable(void);
+int __cpu_die(unsigned int cpu);
+#endif
 
 #endif /* !__ASM_BLACKFIN_SMP_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/syscall.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/syscall.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/syscall.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/syscall.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,96 @@
+/*
+ * Magic syscall break down functions
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __ASM_BLACKFIN_SYSCALL_H__
+#define __ASM_BLACKFIN_SYSCALL_H__
+
+/*
+ * Blackfin syscalls are simple:
+ *	enter:
+ *		p0: syscall number
+ *		r{0,1,2,3,4,5}: syscall args 0,1,2,3,4,5
+ *	exit:
+ *		r0: return/error value
+ */
+
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+static inline long
+syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+	return regs->p0;
+}
+
+static inline void
+syscall_rollback(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->p0 = regs->orig_p0;
+}
+
+static inline long
+syscall_get_error(struct task_struct *task, struct pt_regs *regs)
+{
+	return IS_ERR_VALUE(regs->r0) ? regs->r0 : 0;
+}
+
+static inline long
+syscall_get_return_value(struct task_struct *task, struct pt_regs *regs)
+{
+	return regs->r0;
+}
+
+static inline void
+syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
+                         int error, long val)
+{
+	regs->r0 = error ? -error : val;
+}
+
+/**
+ *	syscall_get_arguments()
+ *	@task:   unused
+ *	@regs:   the register layout to extract syscall arguments from
+ *	@i:      first syscall argument to extract
+ *	@n:      number of syscall arguments to extract
+ *	@args:   array to return the syscall arguments in
+ *
+ * args[0] gets i'th argument, args[n - 1] gets the i+n-1'th argument
+ */
+static inline void
+syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
+                      unsigned int i, unsigned int n, unsigned long *args)
+{
+	/*
+	 * Assume the ptrace layout doesn't change -- r5 is first in memory,
+	 * then r4, ..., then r0.  So we simply reverse the ptrace register
+	 * array in memory to store into the args array.
+	 */
+	long *aregs = &regs->r0 - i;
+
+	BUG_ON(i > 5 || i + n > 6);
+
+	while (n--)
+		*args++ = *aregs--;
+}
+
+/* See syscall_get_arguments() comments */
+static inline void
+syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
+                      unsigned int i, unsigned int n, const unsigned long *args)
+{
+	long *aregs = &regs->r0 - i;
+
+	BUG_ON(i > 5 || i + n > 6);
+
+	while (n--)
+		*aregs-- = *args++;
+}
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/thread_info.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/thread_info.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/thread_info.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/thread_info.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2009 Analog Devices Inc.
+ * Copyright 2004-2010 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later.
  */
@@ -17,7 +17,7 @@
 /* Thread Align Mask to reach to the top of the stack
  * for any process
  */
-#define ALIGN_PAGE_MASK         0xffffe000
+#define ALIGN_PAGE_MASK		0xffffe000
 
 /*
  * Size of kernel stack for each process. This must be a power of 2...
@@ -57,7 +57,7 @@ struct thread_info {
 	.exec_domain	= &default_exec_domain,	\
 	.flags		= 0,			\
 	.cpu		= 0,			\
-	.preempt_count  = INIT_PREEMPT_COUNT,   \
+	.preempt_count	= INIT_PREEMPT_COUNT,	\
 	.restart_block	= {			\
 		.fn = do_no_restart_syscall,	\
 	},					\
@@ -73,8 +73,7 @@ __attribute_const__
 static inline struct thread_info *current_thread_info(void)
 {
 	struct thread_info *ti;
-      __asm__("%0 = sp;" : "=da"(ti) :
-	);
+	__asm__("%0 = sp;" : "=da"(ti));
 	return (struct thread_info *)((long)ti & ~((long)THREAD_SIZE-1));
 }
 
@@ -99,21 +98,23 @@ static inline struct thread_info *curren
 #define TIF_NEED_RESCHED	2	/* rescheduling necessary */
 #define TIF_POLLING_NRFLAG	3	/* true if poll_idle() is polling
 					   TIF_NEED_RESCHED */
-#define TIF_MEMDIE              4
+#define TIF_MEMDIE		4
 #define TIF_RESTORE_SIGMASK	5	/* restore signal mask in do_signal() */
-#define TIF_FREEZE              6       /* is freezing for suspend */
-#define TIF_IRQ_SYNC            7       /* sync pipeline stage */
-#define TIF_NOTIFY_RESUME       8       /* callback before returning to user */
+#define TIF_FREEZE		6	/* is freezing for suspend */
+#define TIF_IRQ_SYNC		7	/* sync pipeline stage */
+#define TIF_NOTIFY_RESUME	8	/* callback before returning to user */
+#define TIF_SINGLESTEP		9
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
-#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 #define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
-#define _TIF_FREEZE             (1<<TIF_FREEZE)
-#define _TIF_IRQ_SYNC           (1<<TIF_IRQ_SYNC)
+#define _TIF_FREEZE		(1<<TIF_FREEZE)
+#define _TIF_IRQ_SYNC		(1<<TIF_IRQ_SYNC)
+#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
+#define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
 
 #define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/time.h linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/time.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/time.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/time.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,9 +23,7 @@
  */
 
 #ifndef CONFIG_CPU_FREQ
-#define TIME_SCALE 1
-#define __bfin_cycles_off (0)
-#define __bfin_cycles_mod (0)
+# define TIME_SCALE 1
 #else
 /*
  * Blackfin CPU frequency scaling supports max Core Clock 1, 1/2 and 1/4 .
@@ -33,9 +31,16 @@
  * adjust the Core Timer Presale Register. This way we don't lose time.
  */
 #define TIME_SCALE 4
+
+# ifdef CONFIG_CYCLES_CLOCKSOURCE
 extern unsigned long long __bfin_cycles_off;
 extern unsigned int __bfin_cycles_mod;
+# endif
+#endif
+
+#if defined(CONFIG_TICKSOURCE_CORETMR)
+extern void bfin_coretmr_init(void);
+extern void bfin_coretmr_clockevent_init(void);
 #endif
 
-extern void __init setup_core_timer(void);
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/Kconfig linux-libre-2.6.34-gnu1/arch/blackfin/Kconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -23,12 +23,15 @@ config RWSEM_XCHGADD_ALGORITHM
 
 config BLACKFIN
 	def_bool y
+	select HAVE_ARCH_KGDB
+	select HAVE_ARCH_TRACEHOOK
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_FUNCTION_TRACER
+	select HAVE_FUNCTION_TRACE_MCOUNT_TEST
 	select HAVE_IDE
-	select HAVE_KERNEL_GZIP
-	select HAVE_KERNEL_BZIP2
-	select HAVE_KERNEL_LZMA
+	select HAVE_KERNEL_GZIP if RAMKERNEL
+	select HAVE_KERNEL_BZIP2 if RAMKERNEL
+	select HAVE_KERNEL_LZMA if RAMKERNEL
 	select HAVE_OPROFILE
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 
@@ -45,9 +48,6 @@ config ZONE_DMA
 config GENERIC_FIND_NEXT_BIT
 	def_bool y
 
-config GENERIC_HWEIGHT
-	def_bool y
-
 config GENERIC_HARDIRQS
 	def_bool y
 
@@ -239,7 +239,7 @@ endchoice
 
 config SMP
 	depends on BF561
-	select GENERIC_CLOCKEVENTS
+	select TICKSOURCE_CORETMR
 	bool "Symmetric multi-processing support"
 	---help---
 	  This enables support for systems with more than one CPU,
@@ -253,11 +253,20 @@ config NR_CPUS
 	depends on SMP
 	default 2 if BF561
 
+config HOTPLUG_CPU
+	bool "Support for hot-pluggable CPUs"
+	depends on SMP && HOTPLUG
+	default y
+
 config IRQ_PER_CPU
 	bool
 	depends on SMP
 	default y
 
+config HAVE_LEGACY_PER_CPU_AREA
+	def_bool y
+	depends on SMP
+
 config BF_REV_MIN
 	int
 	default 0 if (BF51x || BF52x || (BF54x && !BF54xM))
@@ -349,7 +358,7 @@ config MEM_MT48LC8M32B2B5_7
 
 config MEM_MT48LC32M16A2TG_75
 	bool
-	depends on (BFIN527_EZKIT || BFIN532_IP0X || BLACKSTAMP)
+	depends on (BFIN527_EZKIT || BFIN527_EZKIT_V2 || BFIN532_IP0X || BLACKSTAMP)
 	default y
 
 config MEM_MT48LC32M8A2_75
@@ -401,10 +410,18 @@ config BOOT_LOAD
 config ROM_BASE
 	hex "Kernel ROM Base"
 	depends on ROMKERNEL
-	default "0x20040000"
+	default "0x20040040"
 	range 0x20000000 0x20400000 if !(BF54x || BF561)
 	range 0x20000000 0x30000000 if (BF54x || BF561)
 	help
+	  Make sure your ROM base does not include any file-header
+	  information that is prepended to the kernel.
+
+	  For example, the bootable U-Boot format (created with
+	  mkimage) has a 64 byte header (0x40).  So while the image
+	  you write to flash might start at say 0x20080000, you have
+	  to add 0x40 to get the kernel's ROM base as it will come
+	  after the header.
 
 comment "Clock/PLL Setup"
 
@@ -448,7 +465,7 @@ config VCO_MULT
 	range 1 64
 	default "22" if BFIN533_EZKIT
 	default "45" if BFIN533_STAMP
-	default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM || BFIN538_EZKIT)
+	default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN527_EZKIT_V2 || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM || BFIN538_EZKIT)
 	default "22" if BFIN533_BLUETECHNIX_CM
 	default "20" if (BFIN537_BLUETECHNIX_CM_E || BFIN537_BLUETECHNIX_CM_U || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM)
 	default "20" if BFIN561_EZKIT
@@ -609,23 +626,23 @@ config GENERIC_CLOCKEVENTS
 	bool "Generic clock events"
 	default y
 
-choice
-	prompt "Kernel Tick Source"
+menu "Clock event device"
 	depends on GENERIC_CLOCKEVENTS
-	default TICKSOURCE_CORETMR
-
 config TICKSOURCE_GPTMR0
-	bool "Gptimer0 (SCLK domain)"
+	bool "GPTimer0"
+	depends on !SMP
 	select BFIN_GPTIMERS
 
 config TICKSOURCE_CORETMR
-	bool "Core timer (CCLK domain)"
-
-endchoice
+	bool "Core timer"
+	default y
+endmenu
 
-config CYCLES_CLOCKSOURCE
-	bool "Use 'CYCLES' as a clocksource"
+menu "Clock souce"
 	depends on GENERIC_CLOCKEVENTS
+config CYCLES_CLOCKSOURCE
+	bool "CYCLES"
+	default y
 	depends on !BFIN_SCRATCH_REG_CYCLES
 	depends on !SMP
 	help
@@ -636,10 +653,10 @@ config CYCLES_CLOCKSOURCE
 	  writing the registers will most likely crash the kernel.
 
 config GPTMR0_CLOCKSOURCE
-	bool "Use GPTimer0 as a clocksource"
+	bool "GPTimer0"
 	select BFIN_GPTIMERS
-	depends on GENERIC_CLOCKEVENTS
 	depends on !TICKSOURCE_GPTMR0
+endmenu
 
 config ARCH_USES_GETTIMEOFFSET
 	depends on !GENERIC_CLOCKEVENTS
@@ -1116,24 +1133,6 @@ config PCI
 
 source "drivers/pci/Kconfig"
 
-config HOTPLUG
-	bool "Support for hot-pluggable device"
-	  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.
-
-	  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"
 
 source "drivers/pci/hotplug/Kconfig"
@@ -1147,7 +1146,6 @@ source "fs/Kconfig.binfmt"
 endmenu
 
 menu "Power management options"
-	depends on !SMP
 
 source "kernel/power/Kconfig"
 
@@ -1240,7 +1238,6 @@ config PM_BFIN_WAKE_GP
 endmenu
 
 menu "CPU Frequency scaling"
-	depends on !SMP
 
 source "drivers/cpufreq/Kconfig"
 
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/Kconfig.debug linux-libre-2.6.34-gnu1/arch/blackfin/Kconfig.debug
--- linux-libre-2.6.33-gnu1/arch/blackfin/Kconfig.debug	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/Kconfig.debug	2010-05-16 17:17:36.000000000 -0400
@@ -18,9 +18,6 @@ config DEBUG_STACK_USAGE
 
 	  This option will slow down process creation somewhat.
 
-config HAVE_ARCH_KGDB
-	def_bool y
-
 config DEBUG_VERBOSE
 	bool "Verbose fault messages"
 	default y
@@ -238,6 +235,15 @@ config EARLY_PRINTK
 	  all of this lives in the init section and is thrown away after the
 	  kernel boots completely.
 
+config NMI_WATCHDOG
+	bool "Enable NMI watchdog to help debugging lockup on SMP"
+	default n
+	depends on (SMP && !BFIN_SCRATCH_REG_RETN)
+	help
+	  If any CPU in the system does not execute the period local timer
+	  interrupt for more than 5 seconds, then the NMI handler dumps debug
+	  information. This information can be used to debug the lockup.
+
 config CPLB_INFO
 	bool "Display the CPLB information"
 	help
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/bfin_dma_5xx.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/bfin_dma_5xx.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/bfin_dma_5xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/bfin_dma_5xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -91,7 +91,7 @@ late_initcall(proc_dma_init);
  */
 int request_dma(unsigned int channel, const char *device_id)
 {
-	pr_debug("request_dma() : BEGIN \n");
+	pr_debug("request_dma() : BEGIN\n");
 
 	if (device_id == NULL)
 		printk(KERN_WARNING "request_dma(%u): no device_id given\n", channel);
@@ -107,7 +107,7 @@ int request_dma(unsigned int channel, co
 #endif
 
 	if (atomic_cmpxchg(&dma_ch[channel].chan_status, 0, 1)) {
-		pr_debug("DMA CHANNEL IN USE  \n");
+		pr_debug("DMA CHANNEL IN USE\n");
 		return -EBUSY;
 	}
 
@@ -131,7 +131,7 @@ int request_dma(unsigned int channel, co
 	 * you have to request DMA, before doing any operations on
 	 * descriptor/channel
 	 */
-	pr_debug("request_dma() : END  \n");
+	pr_debug("request_dma() : END\n");
 	return 0;
 }
 EXPORT_SYMBOL(request_dma);
@@ -171,7 +171,7 @@ static void clear_dma_buffer(unsigned in
 
 void free_dma(unsigned int channel)
 {
-	pr_debug("freedma() : BEGIN \n");
+	pr_debug("freedma() : BEGIN\n");
 	BUG_ON(channel >= MAX_DMA_CHANNELS ||
 			!atomic_read(&dma_ch[channel].chan_status));
 
@@ -185,7 +185,7 @@ void free_dma(unsigned int channel)
 	/* Clear the DMA Variable in the Channel */
 	atomic_set(&dma_ch[channel].chan_status, 0);
 
-	pr_debug("freedma() : END \n");
+	pr_debug("freedma() : END\n");
 }
 EXPORT_SYMBOL(free_dma);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/bfin_gpio.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/bfin_gpio.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/bfin_gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/bfin_gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -1289,44 +1289,50 @@ __initcall(gpio_register_proc);
 #endif
 
 #ifdef CONFIG_GPIOLIB
-int bfin_gpiolib_direction_input(struct gpio_chip *chip, unsigned gpio)
+static int bfin_gpiolib_direction_input(struct gpio_chip *chip, unsigned gpio)
 {
 	return bfin_gpio_direction_input(gpio);
 }
 
-int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio, int level)
+static int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio, int level)
 {
 	return bfin_gpio_direction_output(gpio, level);
 }
 
-int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio)
+static int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio)
 {
 	return bfin_gpio_get_value(gpio);
 }
 
-void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value)
+static void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value)
 {
 	return bfin_gpio_set_value(gpio, value);
 }
 
-int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio)
+static int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio)
 {
 	return bfin_gpio_request(gpio, chip->label);
 }
 
-void bfin_gpiolib_gpio_free(struct gpio_chip *chip, unsigned gpio)
+static void bfin_gpiolib_gpio_free(struct gpio_chip *chip, unsigned gpio)
 {
 	return bfin_gpio_free(gpio);
 }
 
+static int bfin_gpiolib_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
+{
+	return gpio + GPIO_IRQ_BASE;
+}
+
 static struct gpio_chip bfin_chip = {
-	.label			= "Blackfin-GPIOlib",
+	.label			= "BFIN-GPIO",
 	.direction_input	= bfin_gpiolib_direction_input,
 	.get			= bfin_gpiolib_get_value,
 	.direction_output	= bfin_gpiolib_direction_output,
 	.set			= bfin_gpiolib_set_value,
 	.request		= bfin_gpiolib_gpio_request,
 	.free			= bfin_gpiolib_gpio_free,
+	.to_irq			= bfin_gpiolib_gpio_to_irq,
 	.base			= 0,
 	.ngpio			= MAX_BLACKFIN_GPIOS,
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/cplb-mpu/cplbinit.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/cplb-mpu/cplbinit.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/cplb-mpu/cplbinit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/cplb-mpu/cplbinit.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,6 +64,15 @@ void __init generate_cplb_tables_cpu(uns
 		icplb_tbl[cpu][i_i++].data = i_data | (addr == 0 ? CPLB_USER_RD : 0);
 	}
 
+#ifdef CONFIG_ROMKERNEL
+	/* Cover kernel XIP flash area */
+	addr = CONFIG_ROM_BASE & ~(4 * 1024 * 1024 - 1);
+	dcplb_tbl[cpu][i_d].addr = addr;
+	dcplb_tbl[cpu][i_d++].data = d_data | CPLB_USER_RD;
+	icplb_tbl[cpu][i_i].addr = addr;
+	icplb_tbl[cpu][i_i++].data = i_data | CPLB_USER_RD;
+#endif
+
 	/* Cover L1 memory.  One 4M area for code and data each is enough.  */
 #if L1_DATA_A_LENGTH > 0 || L1_DATA_B_LENGTH > 0
 	dcplb_tbl[cpu][i_d].addr = get_l1_data_a_start_cpu(cpu);
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/cplb-mpu/cplbmgr.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/cplb-mpu/cplbmgr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/cplb-mpu/cplbmgr.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,12 @@ int nr_dcplb_miss[NR_CPUS], nr_icplb_mis
 int nr_icplb_supv_miss[NR_CPUS], nr_dcplb_prot[NR_CPUS];
 int nr_cplb_flush[NR_CPUS];
 
+#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
+#define MGR_ATTR __attribute__((l1_text))
+#else
+#define MGR_ATTR
+#endif
+
 /*
  * Given the contents of the status register, return the index of the
  * CPLB that caused the fault.
@@ -59,7 +65,7 @@ static int icplb_rr_index[NR_CPUS], dcpl
 /*
  * Find an ICPLB entry to be evicted and return its index.
  */
-static int evict_one_icplb(unsigned int cpu)
+MGR_ATTR static int evict_one_icplb(unsigned int cpu)
 {
 	int i;
 	for (i = first_switched_icplb; i < MAX_CPLBS; i++)
@@ -74,7 +80,7 @@ static int evict_one_icplb(unsigned int
 	return i;
 }
 
-static int evict_one_dcplb(unsigned int cpu)
+MGR_ATTR static int evict_one_dcplb(unsigned int cpu)
 {
 	int i;
 	for (i = first_switched_dcplb; i < MAX_CPLBS; i++)
@@ -89,7 +95,7 @@ static int evict_one_dcplb(unsigned int
 	return i;
 }
 
-static noinline int dcplb_miss(unsigned int cpu)
+MGR_ATTR static noinline int dcplb_miss(unsigned int cpu)
 {
 	unsigned long addr = bfin_read_DCPLB_FAULT_ADDR();
 	int status = bfin_read_DCPLB_STATUS();
@@ -114,10 +120,15 @@ static noinline int dcplb_miss(unsigned
 		d_data = L2_DMEMORY;
 	} else if (addr >= physical_mem_end) {
 		if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) {
-			addr &= ~(4 * 1024 * 1024 - 1);
-			d_data &= ~PAGE_SIZE_4KB;
-			d_data |= PAGE_SIZE_4MB;
-			d_data |= CPLB_USER_RD | CPLB_USER_WR;
+			mask = current_rwx_mask[cpu];
+			if (mask) {
+				int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT;
+				int idx = page >> 5;
+				int bit = 1 << (page & 31);
+
+				if (mask[idx] & bit)
+					d_data |= CPLB_USER_RD;
+			}
 		} else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
 		    && (status & (FAULT_RW | FAULT_USERSUPV)) == FAULT_USERSUPV) {
 			addr &= ~(1 * 1024 * 1024 - 1);
@@ -126,7 +137,9 @@ static noinline int dcplb_miss(unsigned
 		} else
 			return CPLB_PROT_VIOL;
 	} else if (addr >= _ramend) {
-	    d_data |= CPLB_USER_RD | CPLB_USER_WR;
+		d_data |= CPLB_USER_RD | CPLB_USER_WR;
+		if (reserved_mem_dcache_on)
+			d_data |= CPLB_L1_CHBL;
 	} else {
 		mask = current_rwx_mask[cpu];
 		if (mask) {
@@ -156,7 +169,7 @@ static noinline int dcplb_miss(unsigned
 	return 0;
 }
 
-static noinline int icplb_miss(unsigned int cpu)
+MGR_ATTR static noinline int icplb_miss(unsigned int cpu)
 {
 	unsigned long addr = bfin_read_ICPLB_FAULT_ADDR();
 	int status = bfin_read_ICPLB_STATUS();
@@ -204,10 +217,19 @@ static noinline int icplb_miss(unsigned
 		i_data = L2_IMEMORY;
 	} else if (addr >= physical_mem_end) {
 		if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) {
-			addr &= ~(4 * 1024 * 1024 - 1);
-			i_data &= ~PAGE_SIZE_4KB;
-			i_data |= PAGE_SIZE_4MB;
-			i_data |= CPLB_USER_RD;
+			if (!(status & FAULT_USERSUPV)) {
+				unsigned long *mask = current_rwx_mask[cpu];
+
+				if (mask) {
+					int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT;
+					int idx = page >> 5;
+					int bit = 1 << (page & 31);
+
+					mask += 2 * page_mask_nelts;
+					if (mask[idx] & bit)
+						i_data |= CPLB_USER_RD;
+				}
+			}
 		} else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
 		    && (status & FAULT_USERSUPV)) {
 			addr &= ~(1 * 1024 * 1024 - 1);
@@ -217,6 +239,8 @@ static noinline int icplb_miss(unsigned
 		    return CPLB_PROT_VIOL;
 	} else if (addr >= _ramend) {
 		i_data |= CPLB_USER_RD;
+		if (reserved_mem_icache_on)
+			i_data |= CPLB_L1_CHBL;
 	} else {
 		/*
 		 * Two cases to distinguish - a supervisor access must
@@ -251,7 +275,7 @@ static noinline int icplb_miss(unsigned
 	return 0;
 }
 
-static noinline int dcplb_protection_fault(unsigned int cpu)
+MGR_ATTR static noinline int dcplb_protection_fault(unsigned int cpu)
 {
 	int status = bfin_read_DCPLB_STATUS();
 
@@ -271,7 +295,7 @@ static noinline int dcplb_protection_fau
 	return CPLB_PROT_VIOL;
 }
 
-int cplb_hdr(int seqstat, struct pt_regs *regs)
+MGR_ATTR int cplb_hdr(int seqstat, struct pt_regs *regs)
 {
 	int cause = seqstat & 0x3f;
 	unsigned int cpu = raw_smp_processor_id();
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/cplb-nompu/cplbinit.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/cplb-nompu/cplbinit.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/cplb-nompu/cplbinit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/cplb-nompu/cplbinit.c	2010-05-16 17:17:36.000000000 -0400
@@ -56,6 +56,15 @@ void __init generate_cplb_tables_cpu(uns
 		i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_4MB;
 	}
 
+#ifdef CONFIG_ROMKERNEL
+	/* Cover kernel XIP flash area */
+	addr = CONFIG_ROM_BASE & ~(4 * 1024 * 1024 - 1);
+	d_tbl[i_d].addr = addr;
+	d_tbl[i_d++].data = SDRAM_DGENERIC | PAGE_SIZE_4MB;
+	i_tbl[i_i].addr = addr;
+	i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_4MB;
+#endif
+
 	/* Cover L1 memory.  One 4M area for code and data each is enough.  */
 	if (cpu == 0) {
 		if (L1_DATA_A_LENGTH || L1_DATA_B_LENGTH) {
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/dma-mapping.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/dma-mapping.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/dma-mapping.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/dma-mapping.c	2010-05-16 17:17:36.000000000 -0400
@@ -116,7 +116,7 @@ EXPORT_SYMBOL(dma_free_coherent);
 void __dma_sync(dma_addr_t addr, size_t size,
 		enum dma_data_direction dir)
 {
-	_dma_sync(addr, size, dir);
+	__dma_sync_inline(addr, size, dir);
 }
 EXPORT_SYMBOL(__dma_sync);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/entry.S linux-libre-2.6.34-gnu1/arch/blackfin/kernel/entry.S
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/entry.S	2010-05-16 17:17:36.000000000 -0400
@@ -44,7 +44,7 @@ ENTRY(_ret_from_fork)
 	sti r4;
 #endif /* CONFIG_IPIPE */
 	SP += -12;
-	call _schedule_tail;
+	pseudo_long_call _schedule_tail, p5;
 	SP += 12;
 	r0 = [sp + PT_IPEND];
 	cc = bittst(r0,1);
@@ -79,7 +79,7 @@ ENTRY(_sys_vfork)
 	r0 += 24;
 	[--sp] = rets;
 	SP += -12;
-	call _bfin_vfork;
+	pseudo_long_call _bfin_vfork, p2;
 	SP += 12;
 	rets = [sp++];
 	rts;
@@ -90,7 +90,7 @@ ENTRY(_sys_clone)
 	r0 += 24;
 	[--sp] = rets;
 	SP += -12;
-	call _bfin_clone;
+	pseudo_long_call _bfin_clone, p2;
 	SP += 12;
 	rets = [sp++];
 	rts;
@@ -101,7 +101,7 @@ ENTRY(_sys_rt_sigreturn)
 	r0 += 24;
 	[--sp] = rets;
 	SP += -12;
-	call _do_rt_sigreturn;
+	pseudo_long_call _do_rt_sigreturn, p2;
 	SP += 12;
 	rets = [sp++];
 	rts;
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/ftrace.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/ftrace.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/ftrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/ftrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,8 @@
  * 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)
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
+                           unsigned long frame_pointer)
 {
 	struct ftrace_graph_ent trace;
 	unsigned long return_hooker = (unsigned long)&return_to_handler;
@@ -24,7 +25,8 @@ void prepare_ftrace_return(unsigned long
 	if (unlikely(atomic_read(&current->tracing_graph_pause)))
 		return;
 
-	if (ftrace_push_return_trace(*parent, self_addr, &trace.depth, 0) == -EBUSY)
+	if (ftrace_push_return_trace(*parent, self_addr, &trace.depth,
+	                             frame_pointer) == -EBUSY)
 		return;
 
 	trace.func = self_addr;
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/ftrace-entry.S linux-libre-2.6.34-gnu1/arch/blackfin/kernel/ftrace-entry.S
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/ftrace-entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/ftrace-entry.S	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * mcount and friends -- ftrace stuff
  *
- * Copyright (C) 2009 Analog Devices Inc.
+ * Copyright (C) 2009-2010 Analog Devices Inc.
  * Licensed under the GPL-2 or later.
  */
 
@@ -21,6 +21,15 @@
  * function will be waiting there.  mmmm pie.
  */
 ENTRY(__mcount)
+#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
+	/* optional micro optimization: return if stopped */
+	p1.l = _function_trace_stop;
+	p1.h = _function_trace_stop;
+	r3 = [p1];
+	cc = r3 == 0;
+	if ! cc jump _ftrace_stub (bp);
+#endif
+
 	/* save third function arg early so we can do testing below */
 	[--sp] = r2;
 
@@ -106,9 +115,12 @@ ENTRY(_ftrace_graph_caller)
 	[--sp] = r1;
 	[--sp] = rets;
 
-	/* prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) */
-	r0 = sp;
-	r1 = rets;
+	/* prepare_ftrace_return(parent, self_addr, frame_pointer) */
+	r0 = sp;	/* unsigned long *parent */
+	r1 = rets;	/* unsigned long self_addr */
+#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST
+	r2 = fp;	/* unsigned long frame_pointer */
+#endif
 	r0 += 16;	/* skip the 4 local regs on stack */
 	r1 += -MCOUNT_INSN_SIZE;
 	call _prepare_ftrace_return;
@@ -127,6 +139,9 @@ ENTRY(_return_to_handler)
 	[--sp] = r1;
 
 	/* get original return address */
+#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST
+	r0 = fp;	/* Blackfin is sane, so omit this */
+#endif
 	call _ftrace_return_to_handler;
 	rets = r0;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/init_task.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/init_task.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/init_task.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/init_task.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,5 +28,5 @@ EXPORT_SYMBOL(init_task);
  * "init_task" linker map entry.
  */
 union thread_union init_thread_union
-    __attribute__ ((__section__(".init_task.data"))) = {
+    __init_task_data = {
 INIT_THREAD_INFO(init_task)};
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/ipipe.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/ipipe.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/ipipe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/ipipe.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/interrupt.h>
 #include <linux/percpu.h>
 #include <linux/bitops.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/kthread.h>
 #include <linux/unistd.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/kgdb.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/kgdb.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/kgdb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/kgdb.c	2010-05-16 17:17:36.000000000 -0400
@@ -145,7 +145,7 @@ void gdb_regs_to_pt_regs(unsigned long *
 #endif
 }
 
-struct hw_breakpoint {
+static struct hw_breakpoint {
 	unsigned int occupied:1;
 	unsigned int skip:1;
 	unsigned int enabled:1;
@@ -155,7 +155,7 @@ struct hw_breakpoint {
 	unsigned int addr;
 } breakinfo[HW_WATCHPOINT_NUM];
 
-int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
+static int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
 {
 	int breakno;
 	int bfin_type;
@@ -202,7 +202,7 @@ int bfin_set_hw_break(unsigned long addr
 	return -ENOSPC;
 }
 
-int bfin_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
+static int bfin_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
 {
 	int breakno;
 	int bfin_type;
@@ -230,7 +230,7 @@ int bfin_remove_hw_break(unsigned long a
 	return 0;
 }
 
-void bfin_remove_all_hw_break(void)
+static void bfin_remove_all_hw_break(void)
 {
 	int breakno;
 
@@ -242,7 +242,7 @@ void bfin_remove_all_hw_break(void)
 		breakinfo[breakno].type = TYPE_DATA_WATCHPOINT;
 }
 
-void bfin_correct_hw_break(void)
+static void bfin_correct_hw_break(void)
 {
 	int breakno;
 	unsigned int wpiactl = 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/Makefile linux-libre-2.6.34-gnu1/arch/blackfin/kernel/Makefile
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@ obj-$(CONFIG_CPLB_INFO)              +=
 obj-$(CONFIG_MODULES)                += module.o
 obj-$(CONFIG_KGDB)                   += kgdb.o
 obj-$(CONFIG_KGDB_TESTS)             += kgdb_test.o
+obj-$(CONFIG_NMI_WATCHDOG)           += nmi.o
 obj-$(CONFIG_EARLY_PRINTK)           += early_printk.o
 obj-$(CONFIG_EARLY_PRINTK)           += shadow_console.o
 obj-$(CONFIG_STACKTRACE)             += stacktrace.o
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/nmi.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/nmi.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/nmi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/nmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,299 @@
+/*
+ * Blackfin nmi_watchdog Driver
+ *
+ * Originally based on bfin_wdt.c
+ * Copyright 2010-2010 Analog Devices Inc.
+ *		Graff Yang <graf.yang@analog.com>
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/bitops.h>
+#include <linux/hardirq.h>
+#include <linux/sysdev.h>
+#include <linux/pm.h>
+#include <linux/nmi.h>
+#include <linux/smp.h>
+#include <linux/timer.h>
+#include <asm/blackfin.h>
+#include <asm/atomic.h>
+#include <asm/cacheflush.h>
+#include <asm/bfin_watchdog.h>
+
+#define DRV_NAME "nmi-wdt"
+
+#define NMI_WDT_TIMEOUT 5          /* 5 seconds */
+#define NMI_CHECK_TIMEOUT (4 * HZ) /* 4 seconds in jiffies */
+static int nmi_wdt_cpu = 1;
+
+static unsigned int timeout = NMI_WDT_TIMEOUT;
+static int nmi_active;
+
+static unsigned short wdoga_ctl;
+static unsigned int wdoga_cnt;
+static struct corelock_slot saved_corelock;
+static atomic_t nmi_touched[NR_CPUS];
+static struct timer_list ntimer;
+
+enum {
+	COREA_ENTER_NMI = 0,
+	COREA_EXIT_NMI,
+	COREB_EXIT_NMI,
+
+	NMI_EVENT_NR,
+};
+static unsigned long nmi_event __attribute__ ((__section__(".l2.bss")));
+
+/* we are in nmi, non-atomic bit ops is safe */
+static inline void set_nmi_event(int event)
+{
+	__set_bit(event, &nmi_event);
+}
+
+static inline void wait_nmi_event(int event)
+{
+	while (!test_bit(event, &nmi_event))
+		barrier();
+	__clear_bit(event, &nmi_event);
+}
+
+static inline void send_corea_nmi(void)
+{
+	wdoga_ctl = bfin_read_WDOGA_CTL();
+	wdoga_cnt = bfin_read_WDOGA_CNT();
+
+	bfin_write_WDOGA_CTL(WDEN_DISABLE);
+	bfin_write_WDOGA_CNT(0);
+	bfin_write_WDOGA_CTL(WDEN_ENABLE | ICTL_NMI);
+}
+
+static inline void restore_corea_nmi(void)
+{
+	bfin_write_WDOGA_CTL(WDEN_DISABLE);
+	bfin_write_WDOGA_CTL(WDOG_EXPIRED | WDEN_DISABLE | ICTL_NONE);
+
+	bfin_write_WDOGA_CNT(wdoga_cnt);
+	bfin_write_WDOGA_CTL(wdoga_ctl);
+}
+
+static inline void save_corelock(void)
+{
+	saved_corelock = corelock;
+	corelock.lock = 0;
+}
+
+static inline void restore_corelock(void)
+{
+	corelock = saved_corelock;
+}
+
+
+static inline void nmi_wdt_keepalive(void)
+{
+	bfin_write_WDOGB_STAT(0);
+}
+
+static inline void nmi_wdt_stop(void)
+{
+	bfin_write_WDOGB_CTL(WDEN_DISABLE);
+}
+
+/* before calling this function, you must stop the WDT */
+static inline void nmi_wdt_clear(void)
+{
+	/* clear TRO bit, disable event generation */
+	bfin_write_WDOGB_CTL(WDOG_EXPIRED | WDEN_DISABLE | ICTL_NONE);
+}
+
+static inline void nmi_wdt_start(void)
+{
+	bfin_write_WDOGB_CTL(WDEN_ENABLE | ICTL_NMI);
+}
+
+static inline int nmi_wdt_running(void)
+{
+	return ((bfin_read_WDOGB_CTL() & WDEN_MASK) != WDEN_DISABLE);
+}
+
+static inline int nmi_wdt_set_timeout(unsigned long t)
+{
+	u32 cnt, max_t, sclk;
+	int run;
+
+	sclk = get_sclk();
+	max_t = -1 / sclk;
+	cnt = t * sclk;
+	if (t > max_t) {
+		pr_warning("NMI: timeout value is too large\n");
+		return -EINVAL;
+	}
+
+	run = nmi_wdt_running();
+	nmi_wdt_stop();
+	bfin_write_WDOGB_CNT(cnt);
+	if (run)
+		nmi_wdt_start();
+
+	timeout = t;
+
+	return 0;
+}
+
+int check_nmi_wdt_touched(void)
+{
+	unsigned int this_cpu = smp_processor_id();
+	unsigned int cpu;
+
+	cpumask_t mask = cpu_online_map;
+
+	if (!atomic_read(&nmi_touched[this_cpu]))
+		return 0;
+
+	atomic_set(&nmi_touched[this_cpu], 0);
+
+	cpu_clear(this_cpu, mask);
+	for_each_cpu_mask(cpu, mask) {
+		invalidate_dcache_range((unsigned long)(&nmi_touched[cpu]),
+				(unsigned long)(&nmi_touched[cpu]));
+		if (!atomic_read(&nmi_touched[cpu]))
+			return 0;
+		atomic_set(&nmi_touched[cpu], 0);
+	}
+
+	return 1;
+}
+
+static void nmi_wdt_timer(unsigned long data)
+{
+	if (check_nmi_wdt_touched())
+		nmi_wdt_keepalive();
+
+	mod_timer(&ntimer, jiffies + NMI_CHECK_TIMEOUT);
+}
+
+static int __init init_nmi_wdt(void)
+{
+	nmi_wdt_set_timeout(timeout);
+	nmi_wdt_start();
+	nmi_active = true;
+
+	init_timer(&ntimer);
+	ntimer.function = nmi_wdt_timer;
+	ntimer.expires = jiffies + NMI_CHECK_TIMEOUT;
+	add_timer(&ntimer);
+
+	pr_info("nmi_wdt: initialized: timeout=%d sec\n", timeout);
+	return 0;
+}
+device_initcall(init_nmi_wdt);
+
+void touch_nmi_watchdog(void)
+{
+	atomic_set(&nmi_touched[smp_processor_id()], 1);
+}
+
+/* Suspend/resume support */
+#ifdef CONFIG_PM
+static int nmi_wdt_suspend(struct sys_device *dev, pm_message_t state)
+{
+	nmi_wdt_stop();
+	return 0;
+}
+
+static int nmi_wdt_resume(struct sys_device *dev)
+{
+	if (nmi_active)
+		nmi_wdt_start();
+	return 0;
+}
+
+static struct sysdev_class nmi_sysclass = {
+	.name		= DRV_NAME,
+	.resume		= nmi_wdt_resume,
+	.suspend	= nmi_wdt_suspend,
+};
+
+static struct sys_device device_nmi_wdt = {
+	.id	= 0,
+	.cls	= &nmi_sysclass,
+};
+
+static int __init init_nmi_wdt_sysfs(void)
+{
+	int error;
+
+	if (!nmi_active)
+		return 0;
+
+	error = sysdev_class_register(&nmi_sysclass);
+	if (!error)
+		error = sysdev_register(&device_nmi_wdt);
+	return error;
+}
+late_initcall(init_nmi_wdt_sysfs);
+
+#endif	/* CONFIG_PM */
+
+
+asmlinkage notrace void do_nmi(struct pt_regs *fp)
+{
+	unsigned int cpu = smp_processor_id();
+	nmi_enter();
+
+	cpu_pda[cpu].__nmi_count += 1;
+
+	if (cpu == nmi_wdt_cpu) {
+		/* CoreB goes here first */
+
+		/* reload the WDOG_STAT */
+		nmi_wdt_keepalive();
+
+		/* clear nmi interrupt for CoreB */
+		nmi_wdt_stop();
+		nmi_wdt_clear();
+
+		/* trigger NMI interrupt of CoreA */
+		send_corea_nmi();
+
+		/* waiting CoreB to enter NMI */
+		wait_nmi_event(COREA_ENTER_NMI);
+
+		/* recover WDOGA's settings */
+		restore_corea_nmi();
+
+		save_corelock();
+
+		/* corelock is save/cleared, CoreA is dummping messages */
+
+		wait_nmi_event(COREA_EXIT_NMI);
+	} else {
+		/* OK, CoreA entered NMI */
+		set_nmi_event(COREA_ENTER_NMI);
+	}
+
+	pr_emerg("\nNMI Watchdog detected LOCKUP, dump for CPU %d\n", cpu);
+	dump_bfin_process(fp);
+	dump_bfin_mem(fp);
+	show_regs(fp);
+	dump_bfin_trace_buffer();
+	show_stack(current, (unsigned long *)fp);
+
+	if (cpu == nmi_wdt_cpu) {
+		pr_emerg("This fault is not recoverable, sorry!\n");
+
+		/* CoreA dump finished, restore the corelock */
+		restore_corelock();
+
+		set_nmi_event(COREB_EXIT_NMI);
+	} else {
+		/* CoreB dump finished, notice the CoreA we are done */
+		set_nmi_event(COREA_EXIT_NMI);
+
+		/* synchronize with CoreA */
+		wait_nmi_event(COREB_EXIT_NMI);
+	}
+
+	nmi_exit();
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/process.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/unistd.h>
 #include <linux/user.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/tick.h>
 #include <linux/fs.h>
@@ -98,13 +99,6 @@ void cpu_idle(void)
 	}
 }
 
-/* Fill in the fpu structure for a core dump.  */
-
-int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpregs)
-{
-	return 1;
-}
-
 /*
  * This gets run with P1 containing the
  * function to call, and R1 containing
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
- * these modifications are Copyright 2004-2009 Analog Devices Inc.
+ * these modifications are Copyright 2004-2010 Analog Devices Inc.
  *
  * Licensed under the GPL-2
  */
@@ -9,10 +9,13 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
+#include <linux/elf.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
+#include <linux/regset.h>
 #include <linux/signal.h>
+#include <linux/tracehook.h>
 #include <linux/uaccess.h>
 
 #include <asm/page.h>
@@ -25,90 +28,57 @@
 #include <asm/cacheflush.h>
 #include <asm/mem_map.h>
 
-#define TEXT_OFFSET 0
 /*
  * does not yet catch signals sent when the child dies.
  * in exit.c or in signal.c.
  */
 
-/* determines which bits in the SYSCFG reg the user has access to. */
-/* 1 = access 0 = no access */
-#define SYSCFG_MASK 0x0007	/* SYSCFG reg */
-/* sets the trace bits. */
-#define TRACE_BITS 0x0001
-
-/* Find the stack offset for a register, relative to thread.esp0. */
-#define PT_REG(reg)	((long)&((struct pt_regs *)0)->reg)
-
-/*
- * Get the address of the live pt_regs for the specified task.
- * These are saved onto the top kernel stack when the process
- * is not running.
- *
- * Note: if a user thread is execve'd from kernel space, the
- * kernel stack will not be empty on entry to the kernel, so
- * ptracing these tasks will fail.
- */
-static inline struct pt_regs *get_user_regs(struct task_struct *task)
-{
-	return (struct pt_regs *)
-	    ((unsigned long)task_stack_page(task) +
-	     (THREAD_SIZE - sizeof(struct pt_regs)));
-}
-
-/*
- * Get all user integer registers.
- */
-static inline int ptrace_getregs(struct task_struct *tsk, void __user *uregs)
-{
-	struct pt_regs regs;
-	memcpy(&regs, get_user_regs(tsk), sizeof(regs));
-	regs.usp = tsk->thread.usp;
-	return copy_to_user(uregs, &regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
-}
-
-/* Mapping from PT_xxx to the stack offset at which the register is
- * saved.  Notice that usp has no stack-slot and needs to be treated
- * specially (see get_reg/put_reg below).
- */
-
 /*
  * Get contents of register REGNO in task TASK.
  */
-static inline long get_reg(struct task_struct *task, int regno)
+static inline long
+get_reg(struct task_struct *task, long regno, unsigned long __user *datap)
 {
-	unsigned char *reg_ptr;
+	long tmp;
+	struct pt_regs *regs = task_pt_regs(task);
 
-	struct pt_regs *regs =
-	    (struct pt_regs *)((unsigned long)task_stack_page(task) +
-			       (THREAD_SIZE - sizeof(struct pt_regs)));
-	reg_ptr = (char *)regs;
+	if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0)
+		return -EIO;
 
 	switch (regno) {
+	case PT_TEXT_ADDR:
+		tmp = task->mm->start_code;
+		break;
+	case PT_TEXT_END_ADDR:
+		tmp = task->mm->end_code;
+		break;
+	case PT_DATA_ADDR:
+		tmp = task->mm->start_data;
+		break;
 	case PT_USP:
-		return task->thread.usp;
+		tmp = task->thread.usp;
+		break;
 	default:
-		if (regno <= 216)
-			return *(long *)(reg_ptr + regno);
+		if (regno < sizeof(*regs)) {
+			void *reg_ptr = regs;
+			tmp = *(long *)(reg_ptr + regno);
+		} else
+			return -EIO;
 	}
-	/* slight mystery ... never seems to come here but kernel misbehaves without this code! */
 
-	printk(KERN_WARNING "Request to get for unknown register %d\n", regno);
-	return 0;
+	return put_user(tmp, datap);
 }
 
 /*
  * Write contents of register REGNO in task TASK.
  */
 static inline int
-put_reg(struct task_struct *task, int regno, unsigned long data)
+put_reg(struct task_struct *task, long regno, unsigned long data)
 {
-	char *reg_ptr;
+	struct pt_regs *regs = task_pt_regs(task);
 
-	struct pt_regs *regs =
-	    (struct pt_regs *)((unsigned long)task_stack_page(task) +
-			       (THREAD_SIZE - sizeof(struct pt_regs)));
-	reg_ptr = (char *)regs;
+	if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0)
+		return -EIO;
 
 	switch (regno) {
 	case PT_PC:
@@ -125,10 +95,18 @@ put_reg(struct task_struct *task, int re
 		regs->usp = data;
 		task->thread.usp = data;
 		break;
+	case PT_SYSCFG:	/* don't let userspace screw with this */
+		if ((data & ~1) != 0x6)
+			pr_warning("ptrace: ignore syscfg write of %#lx\n", data);
+		break;		/* regs->syscfg = data; break; */
 	default:
-		if (regno <= 216)
-			*(long *)(reg_ptr + regno) = data;
+		if (regno < sizeof(*regs)) {
+			void *reg_offset = regs;
+			*(long *)(reg_offset + regno) = data;
+		}
+		/* Ignore writes to pseudo registers */
 	}
+
 	return 0;
 }
 
@@ -160,24 +138,98 @@ static inline int is_user_addr_valid(str
 	return -EIO;
 }
 
-void ptrace_enable(struct task_struct *child)
+/*
+ * retrieve the contents of Blackfin userspace general registers
+ */
+static int genregs_get(struct task_struct *target,
+		       const struct user_regset *regset,
+		       unsigned int pos, unsigned int count,
+		       void *kbuf, void __user *ubuf)
 {
-	unsigned long tmp;
-	tmp = get_reg(child, PT_SYSCFG) | (TRACE_BITS);
-	put_reg(child, PT_SYSCFG, tmp);
+	struct pt_regs *regs = task_pt_regs(target);
+	int ret;
+
+	/* This sucks ... */
+	regs->usp = target->thread.usp;
+
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				  regs, 0, sizeof(*regs));
+	if (ret < 0)
+		return ret;
+
+	return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+					sizeof(*regs), -1);
 }
 
 /*
- * Called by kernel/ptrace.c when detaching..
- *
- * Make sure the single step bit is not set.
+ * update the contents of the Blackfin userspace general registers
  */
-void ptrace_disable(struct task_struct *child)
+static int genregs_set(struct task_struct *target,
+		       const struct user_regset *regset,
+		       unsigned int pos, unsigned int count,
+		       const void *kbuf, const void __user *ubuf)
 {
-	unsigned long tmp;
-	/* make sure the single step bit is not set. */
-	tmp = get_reg(child, PT_SYSCFG) & ~TRACE_BITS;
-	put_reg(child, PT_SYSCFG, tmp);
+	struct pt_regs *regs = task_pt_regs(target);
+	int ret;
+
+	/* Don't let people set SYSCFG (it's at the end of pt_regs) */
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				 regs, 0, PT_SYSCFG);
+	if (ret < 0)
+		return ret;
+
+	/* This sucks ... */
+	target->thread.usp = regs->usp;
+	/* regs->retx = regs->pc; */
+
+	return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+					PT_SYSCFG, -1);
+}
+
+/*
+ * Define the register sets available on the Blackfin under Linux
+ */
+enum bfin_regset {
+	REGSET_GENERAL,
+};
+
+static const struct user_regset bfin_regsets[] = {
+	[REGSET_GENERAL] = {
+		.core_note_type = NT_PRSTATUS,
+		.n              = sizeof(struct pt_regs) / sizeof(long),
+		.size           = sizeof(long),
+		.align          = sizeof(long),
+		.get            = genregs_get,
+		.set            = genregs_set,
+	},
+};
+
+static const struct user_regset_view user_bfin_native_view = {
+	.name      = "Blackfin",
+	.e_machine = EM_BLACKFIN,
+	.regsets   = bfin_regsets,
+	.n         = ARRAY_SIZE(bfin_regsets),
+};
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+	return &user_bfin_native_view;
+}
+
+void user_enable_single_step(struct task_struct *child)
+{
+	struct pt_regs *regs = task_pt_regs(child);
+	regs->syscfg |= SYSCFG_SSSTEP;
+
+	set_tsk_thread_flag(child, TIF_SINGLESTEP);
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+	struct pt_regs *regs = task_pt_regs(child);
+	regs->syscfg &= ~SYSCFG_SSSTEP;
+
+	clear_tsk_thread_flag(child, TIF_SINGLESTEP);
 }
 
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -240,40 +292,6 @@ long arch_ptrace(struct task_struct *chi
 			break;
 		}
 
-		/* read the word at location addr in the USER area. */
-	case PTRACE_PEEKUSR:
-		{
-			unsigned long tmp;
-			ret = -EIO;
-			tmp = 0;
-			if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) {
-				printk(KERN_WARNING "ptrace error : PEEKUSR : temporarily returning "
-				                    "0 - %x sizeof(pt_regs) is %lx\n",
-				     (int)addr, sizeof(struct pt_regs));
-				break;
-			}
-			if (addr == sizeof(struct pt_regs)) {
-				/* PT_TEXT_ADDR */
-				tmp = child->mm->start_code + TEXT_OFFSET;
-			} else if (addr == (sizeof(struct pt_regs) + 4)) {
-				/* PT_TEXT_END_ADDR */
-				tmp = child->mm->end_code;
-			} else if (addr == (sizeof(struct pt_regs) + 8)) {
-				/* PT_DATA_ADDR */
-				tmp = child->mm->start_data;
-#ifdef CONFIG_BINFMT_ELF_FDPIC
-			} else if (addr == (sizeof(struct pt_regs) + 12)) {
-				goto case_PTRACE_GETFDPIC_EXEC;
-			} else if (addr == (sizeof(struct pt_regs) + 16)) {
-				goto case_PTRACE_GETFDPIC_INTERP;
-#endif
-			} else {
-				tmp = get_reg(child, addr);
-			}
-			ret = put_user(tmp, datap);
-			break;
-		}
-
 #ifdef CONFIG_BINFMT_ELF_FDPIC
 	case PTRACE_GETFDPIC: {
 		unsigned long tmp = 0;
@@ -336,78 +354,36 @@ long arch_ptrace(struct task_struct *chi
 			break;
 		}
 
-	case PTRACE_POKEUSR:	/* write the word at location addr in the USER area */
-		ret = -EIO;
-		if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) {
-			printk(KERN_WARNING "ptrace error : POKEUSR: temporarily returning 0\n");
-			break;
-		}
-
-		if (addr >= (sizeof(struct pt_regs))) {
-			ret = 0;
-			break;
-		}
-		if (addr == PT_SYSCFG) {
-			data &= SYSCFG_MASK;
-			data |= get_reg(child, PT_SYSCFG);
+	case PTRACE_PEEKUSR:
+		switch (addr) {
+#ifdef CONFIG_BINFMT_ELF_FDPIC	/* backwards compat */
+		case PT_FDPIC_EXEC:   goto case_PTRACE_GETFDPIC_EXEC;
+		case PT_FDPIC_INTERP: goto case_PTRACE_GETFDPIC_INTERP;
+#endif
+		default:
+			ret = get_reg(child, addr, datap);
 		}
-		ret = put_reg(child, addr, data);
-		break;
-
-	case PTRACE_SYSCALL:	/* continue and stop at next (return from) syscall */
-	case PTRACE_CONT:	/* restart after signal. */
-		pr_debug("ptrace: syscall/cont\n");
-
-		ret = -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;
-		ptrace_disable(child);
-		pr_debug("ptrace: before wake_up_process\n");
-		wake_up_process(child);
-		ret = 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:
-		ret = 0;
-		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
-			break;
-		child->exit_code = SIGKILL;
-		ptrace_disable(child);
-		wake_up_process(child);
+		pr_debug("ptrace: PEEKUSR reg %li with %#lx = %i\n", addr, data, ret);
 		break;
 
-	case PTRACE_SINGLESTEP:	/* set the trap flag. */
-		pr_debug("ptrace: single step\n");
-		ret = -EIO;
-		if (!valid_signal(data))
-			break;
-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		ptrace_enable(child);
-		child->exit_code = data;
-		wake_up_process(child);
-		ret = 0;
+	case PTRACE_POKEUSR:
+		ret = put_reg(child, addr, data);
+		pr_debug("ptrace: POKEUSR reg %li with %li = %i\n", addr, data, ret);
 		break;
 
 	case PTRACE_GETREGS:
-		/* Get all gp regs from the child. */
-		ret = ptrace_getregs(child, datap);
-		break;
+		pr_debug("ptrace: PTRACE_GETREGS\n");
+		return copy_regset_to_user(child, &user_bfin_native_view,
+					   REGSET_GENERAL,
+					   0, sizeof(struct pt_regs),
+					   (void __user *)data);
 
 	case PTRACE_SETREGS:
-		printk(KERN_WARNING "ptrace: SETREGS: **** NOT IMPLEMENTED ***\n");
-		/* Set all gp regs in the child. */
-		ret = 0;
-		break;
+		pr_debug("ptrace: PTRACE_SETREGS\n");
+		return copy_regset_from_user(child, &user_bfin_native_view,
+					     REGSET_GENERAL,
+					     0, sizeof(struct pt_regs),
+					     (const void __user *)data);
 
 	default:
 		ret = ptrace_request(child, request, addr, data);
@@ -417,27 +393,21 @@ long arch_ptrace(struct task_struct *chi
 	return ret;
 }
 
-asmlinkage void syscall_trace(void)
+asmlinkage int syscall_trace_enter(struct pt_regs *regs)
 {
-	if (!test_thread_flag(TIF_SYSCALL_TRACE))
-		return;
+	int ret = 0;
 
-	if (!(current->ptrace & PT_PTRACED))
-		return;
+	if (test_thread_flag(TIF_SYSCALL_TRACE))
+		ret = tracehook_report_syscall_entry(regs);
 
-	/* the 0x80 provides a way for the tracing parent to distinguish
-	 * between a syscall stop and SIGTRAP delivery
-	 */
-	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-				 ? 0x80 : 0));
+	return ret;
+}
 
-	/*
-	 * this isn't the same as continuing with a signal, but it will do
-	 * for normal use.  strace only continues with a signal if the
-	 * stopping signal is not SIGTRAP.  -brl
-	 */
-	if (current->exit_code) {
-		send_sig(current->exit_code, current, 1);
-		current->exit_code = 0;
-	}
+asmlinkage void syscall_trace_leave(struct pt_regs *regs)
+{
+	int step;
+
+	step = test_thread_flag(TIF_SINGLESTEP);
+	if (step || test_thread_flag(TIF_SYSCALL_TRACE))
+		tracehook_report_syscall_exit(regs, step);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/setup.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/setup.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -220,6 +220,16 @@ void __init bfin_relocate_l1_mem(void)
 		memcpy(_stext_l2, _l2_lma, l2_len);
 }
 
+#ifdef CONFIG_ROMKERNEL
+void __init bfin_relocate_xip_data(void)
+{
+	early_shadow_stamp();
+
+	memcpy(_sdata, _data_lma, (unsigned long)_data_len - THREAD_SIZE + sizeof(struct thread_info));
+	memcpy(_sinitdata, _init_data_lma, (unsigned long)_init_data_len);
+}
+#endif
+
 /* add_memory_region to memmap */
 static void __init add_memory_region(unsigned long long start,
 			      unsigned long long size, int type)
@@ -504,7 +514,7 @@ static __init void memory_setup(void)
 #endif
 	unsigned long max_mem;
 
-	_rambase = (unsigned long)_stext;
+	_rambase = CONFIG_BOOT_LOAD;
 	_ramstart = (unsigned long)_end;
 
 	if (DMA_UNCACHED_REGION > (_ramend - _ramstart)) {
@@ -597,7 +607,12 @@ static __init void memory_setup(void)
 	}
 
 #ifdef CONFIG_MPU
+#if defined(CONFIG_ROMFS_ON_MTD) && defined(CONFIG_MTD_ROM)
+	page_mask_nelts = (((_ramend + ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE -
+					ASYNC_BANK0_BASE) >> PAGE_SHIFT) + 31) / 32;
+#else
 	page_mask_nelts = ((_ramend >> PAGE_SHIFT) + 31) / 32;
+#endif
 	page_mask_order = get_order(3 * page_mask_nelts * sizeof(long));
 #endif
 
@@ -630,7 +645,7 @@ static __init void memory_setup(void)
 		__bss_start, __bss_stop,
 		_sdata, _edata,
 		(void *)&init_thread_union,
-		(void *)((int)(&init_thread_union) + 0x2000),
+		(void *)((int)(&init_thread_union) + THREAD_SIZE),
 		__init_begin, __init_end,
 		(void *)_ramstart, (void *)memory_end
 #ifdef CONFIG_MTD_UCLINUX
@@ -792,10 +807,17 @@ static inline int __init get_mem_size(vo
 	BUG();
 }
 
+__attribute__((weak))
+void __init native_machine_early_platform_add_devices(void)
+{
+}
+
 void __init setup_arch(char **cmdline_p)
 {
 	unsigned long sclk, cclk;
 
+	native_machine_early_platform_add_devices();
+
 	enable_shadow_console();
 
 	/* Check to make sure we are running on the right processor */
@@ -1217,10 +1239,10 @@ static int show_cpuinfo(struct seq_file
 		   dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS,
 		   BFIN_DLINES);
 #ifdef __ARCH_SYNC_CORE_DCACHE
-	seq_printf(m, "SMP Dcache Flushes\t: %lu\n\n", cpudata->dcache_invld_count);
+	seq_printf(m, "SMP Dcache Flushes\t: %lu\n\n", dcache_invld_count[cpu_num]);
 #endif
 #ifdef __ARCH_SYNC_CORE_ICACHE
-	seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", cpudata->icache_invld_count);
+	seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", icache_invld_count[cpu_num]);
 #endif
 
 	if (cpu_num != num_possible_cpus() - 1)
@@ -1249,8 +1271,8 @@ static int show_cpuinfo(struct seq_file
 	seq_printf(m, "board memory\t: %ld kB (0x%p -> 0x%p)\n",
 		 physical_mem_end >> 10, (void *)0, (void *)physical_mem_end);
 	seq_printf(m, "kernel memory\t: %d kB (0x%p -> 0x%p)\n",
-		((int)memory_end - (int)_stext) >> 10,
-		_stext,
+		((int)memory_end - (int)_rambase) >> 10,
+		(void *)_rambase,
 		(void *)memory_end);
 	seq_printf(m, "\n");
 
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/signal.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/signal.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/signal.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/signal.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2009 Analog Devices Inc.
+ * Copyright 2004-2010 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later
  */
@@ -17,6 +17,7 @@
 #include <asm/cacheflush.h>
 #include <asm/ucontext.h>
 #include <asm/fixed_code.h>
+#include <asm/syscall.h>
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
@@ -50,6 +51,9 @@ rt_restore_sigcontext(struct pt_regs *re
 	unsigned long usp = 0;
 	int err = 0;
 
+	/* Always make any pending restarted system calls return -EINTR */
+	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
 #define RESTORE(x) err |= __get_user(regs->x, &sc->sc_##x)
 
 	/* restore passed registers */
@@ -206,16 +210,6 @@ setup_rt_frame(int sig, struct k_sigacti
 	regs->r1 = (unsigned long)(&frame->info);
 	regs->r2 = (unsigned long)(&frame->uc);
 
-	/*
-	 * Clear the trace flag when entering the signal handler, but
-	 * notify any tracer that was single-stepping it. The tracer
-	 * may want to single-step inside the handler too.
-	 */
-	if (regs->syscfg & TRACE_BITS) {
-		regs->syscfg &= ~TRACE_BITS;
-		ptrace_notify(SIGTRAP);
-	}
-
 	return 0;
 
  give_sigsegv:
@@ -247,6 +241,11 @@ handle_restart(struct pt_regs *regs, str
 		regs->r0 = regs->orig_r0;
 		regs->pc -= 2;
 		break;
+
+	case -ERESTART_RESTARTBLOCK:
+		regs->p0 = __NR_restart_syscall;
+		regs->pc -= 2;
+		break;
 	}
 }
 
@@ -315,6 +314,9 @@ asmlinkage void do_signal(struct pt_regs
 			 * clear the TIF_RESTORE_SIGMASK flag */
 			if (test_thread_flag(TIF_RESTORE_SIGMASK))
 				clear_thread_flag(TIF_RESTORE_SIGMASK);
+
+			tracehook_signal_handler(signr, &info, &ka, regs,
+				test_thread_flag(TIF_SINGLESTEP));
 		}
 
 		return;
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/time-ts.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/time-ts.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/time-ts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/time-ts.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <asm/blackfin.h>
 #include <asm/time.h>
 #include <asm/gptimers.h>
+#include <asm/nmi.h>
 
 /* Accelerators for sched_clock()
  * convert from cycles(64bits) => nanoseconds (64bits)
@@ -50,7 +51,11 @@
 
 static notrace cycle_t bfin_read_cycles(struct clocksource *cs)
 {
+#ifdef CONFIG_CPU_FREQ
 	return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod);
+#else
+	return get_cycles();
+#endif
 }
 
 static struct clocksource bfin_cs_cycles = {
@@ -132,7 +137,6 @@ static int __init bfin_cs_gptimer0_init(
 # define bfin_cs_gptimer0_init()
 #endif
 
-
 #if defined(CONFIG_GPTMR0_CLOCKSOURCE) || defined(CONFIG_CYCLES_CLOCKSOURCE)
 /* prefer to use cycles since it has higher rating */
 notrace unsigned long long sched_clock(void)
@@ -145,47 +149,8 @@ notrace unsigned long long sched_clock(v
 }
 #endif
 
-#ifdef CONFIG_CORE_TIMER_IRQ_L1
-__attribute__((l1_text))
-#endif
-irqreturn_t timer_interrupt(int irq, void *dev_id);
-
-static int bfin_timer_set_next_event(unsigned long, \
-		struct clock_event_device *);
-
-static void bfin_timer_set_mode(enum clock_event_mode, \
-		struct clock_event_device *);
-
-static struct clock_event_device clockevent_bfin = {
-#if defined(CONFIG_TICKSOURCE_GPTMR0)
-	.name		= "bfin_gptimer0",
-	.rating		= 300,
-	.irq		= IRQ_TIMER0,
-#else
-	.name		= "bfin_core_timer",
-	.rating		= 350,
-	.irq		= IRQ_CORETMR,
-#endif
-	.shift		= 32,
-	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.set_next_event = bfin_timer_set_next_event,
-	.set_mode	= bfin_timer_set_mode,
-};
-
-static struct irqaction bfin_timer_irq = {
 #if defined(CONFIG_TICKSOURCE_GPTMR0)
-	.name		= "Blackfin GPTimer0",
-#else
-	.name		= "Blackfin CoreTimer",
-#endif
-	.flags		= IRQF_DISABLED | IRQF_TIMER | \
-			  IRQF_IRQPOLL | IRQF_PERCPU,
-	.handler	= timer_interrupt,
-	.dev_id		= &clockevent_bfin,
-};
-
-#if defined(CONFIG_TICKSOURCE_GPTMR0)
-static int bfin_timer_set_next_event(unsigned long cycles,
+static int bfin_gptmr0_set_next_event(unsigned long cycles,
                                      struct clock_event_device *evt)
 {
 	disable_gptimers(TIMER0bit);
@@ -196,7 +161,7 @@ static int bfin_timer_set_next_event(uns
 	return 0;
 }
 
-static void bfin_timer_set_mode(enum clock_event_mode mode,
+static void bfin_gptmr0_set_mode(enum clock_event_mode mode,
 				struct clock_event_device *evt)
 {
 	switch (mode) {
@@ -224,25 +189,65 @@ static void bfin_timer_set_mode(enum clo
 	}
 }
 
-static void bfin_timer_ack(void)
+static void bfin_gptmr0_ack(void)
 {
 	set_gptimer_status(TIMER_GROUP1, TIMER_STATUS_TIMIL0);
 }
 
-static void __init bfin_timer_init(void)
+static void __init bfin_gptmr0_init(void)
 {
 	disable_gptimers(TIMER0bit);
 }
 
-static unsigned long  __init bfin_clockevent_check(void)
+#ifdef CONFIG_CORE_TIMER_IRQ_L1
+__attribute__((l1_text))
+#endif
+irqreturn_t bfin_gptmr0_interrupt(int irq, void *dev_id)
 {
-	setup_irq(IRQ_TIMER0, &bfin_timer_irq);
-	return get_sclk();
+	struct clock_event_device *evt = dev_id;
+	smp_mb();
+	evt->event_handler(evt);
+	bfin_gptmr0_ack();
+	return IRQ_HANDLED;
 }
 
-#else /* CONFIG_TICKSOURCE_CORETMR */
+static struct irqaction gptmr0_irq = {
+	.name		= "Blackfin GPTimer0",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | \
+			  IRQF_IRQPOLL | IRQF_PERCPU,
+	.handler	= bfin_gptmr0_interrupt,
+};
 
-static int bfin_timer_set_next_event(unsigned long cycles,
+static struct clock_event_device clockevent_gptmr0 = {
+	.name		= "bfin_gptimer0",
+	.rating		= 300,
+	.irq		= IRQ_TIMER0,
+	.shift		= 32,
+	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_next_event = bfin_gptmr0_set_next_event,
+	.set_mode	= bfin_gptmr0_set_mode,
+};
+
+static void __init bfin_gptmr0_clockevent_init(struct clock_event_device *evt)
+{
+	unsigned long clock_tick;
+
+	clock_tick = get_sclk();
+	evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift);
+	evt->max_delta_ns = clockevent_delta2ns(-1, evt);
+	evt->min_delta_ns = clockevent_delta2ns(100, evt);
+
+	evt->cpumask = cpumask_of(0);
+
+	clockevents_register_device(evt);
+}
+#endif /* CONFIG_TICKSOURCE_GPTMR0 */
+
+#if defined(CONFIG_TICKSOURCE_CORETMR)
+/* per-cpu local core timer */
+static DEFINE_PER_CPU(struct clock_event_device, coretmr_events);
+
+static int bfin_coretmr_set_next_event(unsigned long cycles,
 				struct clock_event_device *evt)
 {
 	bfin_write_TCNTL(TMPWR);
@@ -253,7 +258,7 @@ static int bfin_timer_set_next_event(uns
 	return 0;
 }
 
-static void bfin_timer_set_mode(enum clock_event_mode mode,
+static void bfin_coretmr_set_mode(enum clock_event_mode mode,
 				struct clock_event_device *evt)
 {
 	switch (mode) {
@@ -285,19 +290,13 @@ static void bfin_timer_set_mode(enum clo
 	}
 }
 
-static void bfin_timer_ack(void)
-{
-}
-
-static void __init bfin_timer_init(void)
+void bfin_coretmr_init(void)
 {
 	/* power up the timer, but don't enable it just yet */
 	bfin_write_TCNTL(TMPWR);
 	CSYNC();
 
-	/*
-	 * the TSCALE prescaler counter.
-	 */
+	/* the TSCALE prescaler counter. */
 	bfin_write_TSCALE(TIME_SCALE - 1);
 	bfin_write_TPERIOD(0);
 	bfin_write_TCOUNT(0);
@@ -305,48 +304,54 @@ static void __init bfin_timer_init(void)
 	CSYNC();
 }
 
-static unsigned long  __init bfin_clockevent_check(void)
-{
-	setup_irq(IRQ_CORETMR, &bfin_timer_irq);
-	return get_cclk() / TIME_SCALE;
-}
-
-void __init setup_core_timer(void)
+#ifdef CONFIG_CORE_TIMER_IRQ_L1
+__attribute__((l1_text))
+#endif
+irqreturn_t bfin_coretmr_interrupt(int irq, void *dev_id)
 {
-	bfin_timer_init();
-	bfin_timer_set_mode(CLOCK_EVT_MODE_PERIODIC, NULL);
-}
-#endif /* CONFIG_TICKSOURCE_GPTMR0 */
+	int cpu = smp_processor_id();
+	struct clock_event_device *evt = &per_cpu(coretmr_events, cpu);
 
-/*
- * timer_interrupt() needs to keep up the real-time clock,
- * as well as call the "do_timer()" routine every clocktick
- */
-irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = dev_id;
 	smp_mb();
 	evt->event_handler(evt);
-	bfin_timer_ack();
+
+	touch_nmi_watchdog();
+
 	return IRQ_HANDLED;
 }
 
-static int __init bfin_clockevent_init(void)
+static struct irqaction coretmr_irq = {
+	.name		= "Blackfin CoreTimer",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | \
+			  IRQF_IRQPOLL | IRQF_PERCPU,
+	.handler	= bfin_coretmr_interrupt,
+};
+
+void bfin_coretmr_clockevent_init(void)
 {
-	unsigned long timer_clk;
+	unsigned long clock_tick;
+	unsigned int cpu = smp_processor_id();
+	struct clock_event_device *evt = &per_cpu(coretmr_events, cpu);
 
-	timer_clk = bfin_clockevent_check();
+	evt->name = "bfin_core_timer";
+	evt->rating = 350;
+	evt->irq = -1;
+	evt->shift = 32;
+	evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+	evt->set_next_event = bfin_coretmr_set_next_event;
+	evt->set_mode = bfin_coretmr_set_mode;
 
-	bfin_timer_init();
+	clock_tick = get_cclk() / TIME_SCALE;
+	evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift);
+	evt->max_delta_ns = clockevent_delta2ns(-1, evt);
+	evt->min_delta_ns = clockevent_delta2ns(100, evt);
 
-	clockevent_bfin.mult = div_sc(timer_clk, NSEC_PER_SEC, clockevent_bfin.shift);
-	clockevent_bfin.max_delta_ns = clockevent_delta2ns(-1, &clockevent_bfin);
-	clockevent_bfin.min_delta_ns = clockevent_delta2ns(100, &clockevent_bfin);
-	clockevent_bfin.cpumask = cpumask_of(0);
-	clockevents_register_device(&clockevent_bfin);
+	evt->cpumask = cpumask_of(cpu);
 
-	return 0;
+	clockevents_register_device(evt);
 }
+#endif /* CONFIG_TICKSOURCE_CORETMR */
+
 
 void __init time_init(void)
 {
@@ -370,5 +375,21 @@ void __init time_init(void)
 
 	bfin_cs_cycles_init();
 	bfin_cs_gptimer0_init();
-	bfin_clockevent_init();
+
+#if defined(CONFIG_TICKSOURCE_CORETMR)
+	bfin_coretmr_init();
+	setup_irq(IRQ_CORETMR, &coretmr_irq);
+	bfin_coretmr_clockevent_init();
+#endif
+
+#if defined(CONFIG_TICKSOURCE_GPTMR0)
+	bfin_gptmr0_init();
+	setup_irq(IRQ_TIMER0, &gptmr0_irq);
+	gptmr0_irq.dev_id = &clockevent_gptmr0;
+	bfin_gptmr0_clockevent_init(&clockevent_gptmr0);
+#endif
+
+#if !defined(CONFIG_TICKSOURCE_CORETMR) && !defined(CONFIG_TICKSOURCE_GPTMR0)
+# error at least one clock event device is required
+#endif
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/traps.c linux-libre-2.6.34-gnu1/arch/blackfin/kernel/traps.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/traps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/traps.c	2010-05-16 17:17:36.000000000 -0400
@@ -138,6 +138,12 @@ static void decode_address(char *buf, un
 		if (!mm)
 			continue;
 
+		if (!down_read_trylock(&mm->mmap_sem)) {
+			if (!in_atomic)
+				mmput(mm);
+			continue;
+		}
+
 		for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) {
 			struct vm_area_struct *vma;
 
@@ -177,6 +183,7 @@ static void decode_address(char *buf, un
 					sprintf(buf, "[ %s vma:0x%lx-0x%lx]",
 						name, vma->vm_start, vma->vm_end);
 
+				up_read(&mm->mmap_sem);
 				if (!in_atomic)
 					mmput(mm);
 
@@ -186,11 +193,16 @@ static void decode_address(char *buf, un
 				goto done;
 			}
 		}
+
+		up_read(&mm->mmap_sem);
 		if (!in_atomic)
 			mmput(mm);
 	}
 
-	/* we were unable to find this address anywhere */
+	/*
+	 * we were unable to find this address anywhere,
+	 * or some MMs were skipped because they were in use.
+	 */
 	sprintf(buf, "/* kernel dynamic memory */");
 
 done:
@@ -248,9 +260,7 @@ asmlinkage notrace void trap_c(struct pt
 #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
 	int j;
 #endif
-#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
 	unsigned int cpu = raw_smp_processor_id();
-#endif
 	const char *strerror = NULL;
 	int sig = 0;
 	siginfo_t info;
@@ -639,7 +649,17 @@ asmlinkage notrace void trap_c(struct pt
 	{
 		info.si_signo = sig;
 		info.si_errno = 0;
-		info.si_addr = (void __user *)fp->pc;
+		switch (trapnr) {
+		case VEC_CPLB_VL:
+		case VEC_MISALI_D:
+		case VEC_CPLB_M:
+		case VEC_CPLB_MHIT:
+			info.si_addr = (void __user *)cpu_pda[cpu].dcplb_fault_addr;
+			break;
+		default:
+			info.si_addr = (void __user *)fp->pc;
+			break;
+		}
 		force_sig_info(sig, &info, current);
 	}
 
@@ -712,7 +732,7 @@ static void decode_instruction(unsigned
 			verbose_printk("RTE");
 		else if (opcode == 0x0025)
 			verbose_printk("EMUEXCPT");
-		else if (opcode == 0x0040 && opcode <= 0x0047)
+		else if (opcode >= 0x0040 && opcode <= 0x0047)
 			verbose_printk("STI R%i", opcode & 7);
 		else if (opcode >= 0x0050 && opcode <= 0x0057)
 			verbose_printk("JUMP (P%i)", opcode & 7);
@@ -1096,7 +1116,7 @@ void dump_bfin_mem(struct pt_regs *fp)
 			/* And the last RETI points to the current userspace context */
 			if ((fp + 1)->pc >= current->mm->start_code &&
 			    (fp + 1)->pc <= current->mm->end_code) {
-				verbose_printk(KERN_NOTICE "It might be better to look around here : \n");
+				verbose_printk(KERN_NOTICE "It might be better to look around here :\n");
 				verbose_printk(KERN_NOTICE "-------------------------------------------\n");
 				show_regs(fp + 1);
 				verbose_printk(KERN_NOTICE "-------------------------------------------\n");
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/kernel/vmlinux.lds.S linux-libre-2.6.34-gnu1/arch/blackfin/kernel/vmlinux.lds.S
--- linux-libre-2.6.33-gnu1/arch/blackfin/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/kernel/vmlinux.lds.S	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,12 @@ _jiffies = _jiffies_64;
 
 SECTIONS
 {
+#ifdef CONFIG_RAMKERNEL
 	. = CONFIG_BOOT_LOAD;
+#else
+	. = CONFIG_ROM_BASE;
+#endif
+
 	/* Neither the text, ro_data or bss section need to be aligned
 	 * So pack them back to back
 	 */
@@ -31,6 +36,12 @@ SECTIONS
 		LOCK_TEXT
 		IRQENTRY_TEXT
 		KPROBES_TEXT
+#ifdef CONFIG_ROMKERNEL
+		__sinittext = .;
+		INIT_TEXT
+		__einittext = .;
+		EXIT_TEXT
+#endif
 		*(.text.*)
 		*(.fixup)
 
@@ -50,8 +61,14 @@ SECTIONS
 
 	/* Just in case the first read only is a 32-bit access */
 	RO_DATA(4)
+	__rodata_end = .;
 
+#ifdef CONFIG_ROMKERNEL
+	. = CONFIG_BOOT_LOAD;
+	.bss : AT(__rodata_end)
+#else
 	.bss :
+#endif
 	{
 		. = ALIGN(4);
 		___bss_start = .;
@@ -67,7 +84,11 @@ SECTIONS
 		___bss_stop = .;
 	}
 
+#if defined(CONFIG_ROMKERNEL)
+	.data : AT(LOADADDR(.bss) + SIZEOF(.bss))
+#else
 	.data :
+#endif
 	{
 		__sdata = .;
 		/* This gets done first, so the glob doesn't suck it in */
@@ -94,6 +115,8 @@ SECTIONS
 
 		__edata = .;
 	}
+	__data_lma = LOADADDR(.data);
+	__data_len = SIZEOF(.data);
 
 	/* The init section should be last, so when we free it, it goes into
 	 * the general memory pool, and (hopefully) will decrease fragmentation
@@ -103,25 +126,58 @@ SECTIONS
 	. = ALIGN(PAGE_SIZE);
 	___init_begin = .;
 
+#ifdef CONFIG_RAMKERNEL
 	INIT_TEXT_SECTION(PAGE_SIZE)
-	. = ALIGN(16);
-	INIT_DATA_SECTION(16)
-	PERCPU(4)
 
-	/* we have to discard exit text and such at runtime, not link time, to
+	/* We have to discard exit text and such at runtime, not link time, to
 	 * handle embedded cross-section references (alt instructions, bug
-	 * table, eh_frame, etc...)
+	 * table, eh_frame, etc...).  We need all of our .text up front and
+	 * .data after it for PCREL call issues.
 	 */
 	.exit.text :
 	{
 		EXIT_TEXT
 	}
+
+	. = ALIGN(16);
+	INIT_DATA_SECTION(16)
+	PERCPU(4)
+
 	.exit.data :
 	{
 		EXIT_DATA
 	}
 
 	.text_l1 L1_CODE_START : AT(LOADADDR(.exit.data) + SIZEOF(.exit.data))
+#else
+	.init.data : AT(__data_lma + __data_len)
+	{
+		__sinitdata = .;
+		INIT_DATA
+		INIT_SETUP(16)
+		INIT_CALLS
+		CON_INITCALL
+		SECURITY_INITCALL
+		INIT_RAM_FS
+
+		. = ALIGN(4);
+		___per_cpu_load = .;
+		___per_cpu_start = .;
+		*(.data.percpu.first)
+		*(.data.percpu.page_aligned)
+		*(.data.percpu)
+		*(.data.percpu.shared_aligned)
+		___per_cpu_end = .;
+
+		EXIT_DATA
+		__einitdata = .;
+	}
+	__init_data_lma = LOADADDR(.init.data);
+	__init_data_len = SIZEOF(.init.data);
+	__init_data_end = .;
+
+	.text_l1 L1_CODE_START : AT(__init_data_lma + __init_data_len)
+#endif
 	{
 		. = ALIGN(4);
 		__stext_l1 = .;
@@ -202,7 +258,11 @@ SECTIONS
 	/* Force trailing alignment of our init section so that when we
 	 * free our init memory, we don't leave behind a partial page.
 	 */
+#ifdef CONFIG_RAMKERNEL
 	. = __l2_lma + __l2_len;
+#else
+	. = __init_data_end;
+#endif
 	. = ALIGN(PAGE_SIZE);
 	___init_end = .;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/boards/ezbrd.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf518/boards/ezbrd.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/boards/ezbrd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf518/boards/ezbrd.c	2010-05-16 17:17:36.000000000 -0400
@@ -382,30 +382,93 @@ static struct platform_device bfin_spi1_
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = UART0_THR,
+		.end = UART0_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
 	{
-		.start = 0xFFC02000,
-		.end = 0xFFC020FF,
+		.start = UART1_THR,
+		.end = UART1_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
-#endif
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART1_ERROR,
+		.end = IRQ_UART1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_TX,
+		.end = CH_UART1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart1_peripherals[] = {
+	P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
 	.name = "bfin-uart",
 	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.num_resources = ARRAY_SIZE(bfin_uart1_resources),
+	.resource = bfin_uart1_resources,
+	.dev = {
+		.platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -499,16 +562,75 @@ static struct i2c_board_info __initdata
 };
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 #include <linux/input.h>
@@ -593,7 +715,12 @@ static struct platform_device *stamp_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -610,9 +737,13 @@ static struct platform_device *stamp_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
 	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
 	&bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 	&bfin_device_gpiokeys,
@@ -644,6 +775,33 @@ static int __init ezbrd_init(void)
 
 arch_initcall(ezbrd_init);
 
+static struct platform_device *ezbrd_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(ezbrd_early_devices,
+		ARRAY_SIZE(ezbrd_early_devices));
+}
+
 void native_machine_restart(char *cmd)
 {
 	/* workaround reboot hang when booting from SPI */
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/boards/Kconfig linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf518/boards/Kconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/boards/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf518/boards/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -9,4 +9,9 @@ config BFIN518F_EZBRD
 	help
 	  BF518-EZBRD board support.
 
+config BFIN518F_TCM
+       bool "Bluetechnix TCM-BF518"
+       help
+         Bluetechnix TCM-BF518 board support.
+
 endchoice
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/boards/Makefile linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf518/boards/Makefile
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/boards/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf518/boards/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -3,3 +3,4 @@
 #
 
 obj-$(CONFIG_BFIN518F_EZBRD)            += ezbrd.o
+obj-$(CONFIG_BFIN518F_TCM)		+= tcm-bf518.o
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/boards/tcm-bf518.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf518/boards/tcm-bf518.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/boards/tcm-bf518.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf518/boards/tcm-bf518.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,753 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *                2005 National ICT Australia (NICTA)
+ *                      Aidan Williams <aidan@nicta.com.au>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/device.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/dma.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/reboot.h>
+#include <asm/portmux.h>
+#include <asm/dpmc.h>
+#include <asm/bfin_sdh.h>
+#include <linux/spi/ad7877.h>
+#include <net/dsa.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+const char bfin_board_name[] = "Bluetechnix TCM-BF518";
+
+/*
+ *  Driver needs to know address, irq and flag pin.
+ */
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition tcm_partitions[] = {
+	{
+		.name       = "bootloader(nor)",
+		.size       = 0x40000,
+		.offset     = 0,
+	},
+	{
+		.name       = "linux(nor)",
+		.size       = 0x1C0000,
+		.offset     = MTDPART_OFS_APPEND,
+	}
+};
+
+static struct physmap_flash_data tcm_flash_data = {
+	.width      = 2,
+	.parts      = tcm_partitions,
+	.nr_parts   = ARRAY_SIZE(tcm_partitions),
+};
+
+static struct resource tcm_flash_resource = {
+	.start = 0x20000000,
+	.end   = 0x201fffff,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device tcm_flash_device = {
+	.name          = "physmap-flash",
+	.id            = 0,
+	.dev = {
+		.platform_data = &tcm_flash_data,
+	},
+	.num_resources = 1,
+	.resource      = &tcm_flash_resource,
+};
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+	.name = "rtc-bfin",
+	.id   = -1,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+	.name = "bfin_mii_bus",
+};
+
+static struct platform_device bfin_mac_device = {
+	.name = "bfin_mac",
+	.dev.platform_data = &bfin_mii_bus,
+};
+#endif
+
+#if defined(CONFIG_MTD_M25P80) \
+	|| defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+	{
+		.name = "bootloader(spi)",
+		.size = 0x00040000,
+		.offset = 0,
+		.mask_flags = MTD_CAP_ROM
+	}, {
+		.name = "linux kernel(spi)",
+		.size = MTDPART_SIZ_FULL,
+		.offset = MTDPART_OFS_APPEND,
+	}
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+	.name = "m25p80",
+	.parts = bfin_spi_flash_partitions,
+	.nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+	.type = "m25p16",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+	.enable_dma = 0,         /* use dma transfer with this chip*/
+	.bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC) \
+	|| defined(CONFIG_BFIN_SPI_ADC_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+	.enable_dma = 1,         /* use dma transfer with this chip*/
+	.bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+static struct bfin5xx_spi_chip mmc_spi_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 16,
+};
+
+static const struct ad7877_platform_data bfin_ad7877_ts_info = {
+	.model			= 7877,
+	.vref_delay_usecs	= 50,	/* internal, no capacitor */
+	.x_plate_ohms		= 419,
+	.y_plate_ohms		= 486,
+	.pressure_max		= 1000,
+	.pressure_min		= 0,
+	.stopacq_polarity	= 1,
+	.first_conversion_delay	= 3,
+	.acquisition_time	= 1,
+	.averaging		= 1,
+	.pen_down_acc_interval	= 1,
+};
+#endif
+
+#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \
+	 && defined(CONFIG_SND_SOC_WM8731_SPI)
+static struct bfin5xx_spi_chip spi_wm8731_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+static struct bfin5xx_spi_chip spidev_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 8,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) \
+	|| defined(CONFIG_MTD_M25P80_MODULE)
+	{
+		/* the modalias must be the same as spi device driver name */
+		.modalias = "m25p80", /* Name of spi_driver for this device */
+		.max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0, /* Framework bus number */
+		.chip_select = 2, /* SPI0_SSEL2 */
+		.platform_data = &bfin_spi_flash_data,
+		.controller_data = &spi_flash_chip_info,
+		.mode = SPI_MODE_3,
+	},
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC) \
+	|| defined(CONFIG_BFIN_SPI_ADC_MODULE)
+	{
+		.modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+		.max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0, /* Framework bus number */
+		.chip_select = 1, /* Framework chip select. */
+		.platform_data = NULL, /* No spi_driver specific config */
+		.controller_data = &spi_adc_chip_info,
+	},
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+	{
+		.modalias = "mmc_spi",
+		.max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.chip_select = 5,
+		.controller_data = &mmc_spi_chip_info,
+		.mode = SPI_MODE_3,
+	},
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+	{
+		.modalias		= "ad7877",
+		.platform_data		= &bfin_ad7877_ts_info,
+		.irq			= IRQ_PF8,
+		.max_speed_hz	= 12500000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num	= 0,
+		.chip_select  = 2,
+		.controller_data = &spi_ad7877_chip_info,
+	},
+#endif
+#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \
+	 && defined(CONFIG_SND_SOC_WM8731_SPI)
+	{
+		.modalias	= "wm8731",
+		.max_speed_hz	= 3125000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num	= 0,
+		.chip_select    = 5,
+		.controller_data = &spi_wm8731_chip_info,
+		.mode = SPI_MODE_0,
+	},
+#endif
+#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+	{
+		.modalias = "spidev",
+		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.chip_select = 1,
+		.controller_data = &spidev_chip_info,
+	},
+#endif
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+	{
+		.modalias = "bfin-lq035q1-spi",
+		.max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.chip_select = 1,
+		.controller_data = &lq035q1_spi_chip_info,
+		.mode = SPI_CPHA | SPI_CPOL,
+	},
+#endif
+};
+
+/* SPI controller data */
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* SPI (0) */
+static struct bfin5xx_spi_master bfin_spi0_info = {
+	.num_chipselect = 6,
+	.enable_dma = 1,  /* master has the ability to do dma transfer */
+	.pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
+};
+
+static struct resource bfin_spi0_resource[] = {
+	[0] = {
+		.start = SPI0_REGBASE,
+		.end   = SPI0_REGBASE + 0xFF,
+		.flags = IORESOURCE_MEM,
+		},
+	[1] = {
+		.start = CH_SPI0,
+		.end   = CH_SPI0,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = IRQ_SPI0,
+		.end   = IRQ_SPI0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device bfin_spi0_device = {
+	.name = "bfin-spi",
+	.id = 0, /* Bus number */
+	.num_resources = ARRAY_SIZE(bfin_spi0_resource),
+	.resource = bfin_spi0_resource,
+	.dev = {
+		.platform_data = &bfin_spi0_info, /* Passed to driver */
+	},
+};
+
+/* SPI (1) */
+static struct bfin5xx_spi_master bfin_spi1_info = {
+	.num_chipselect = 5,
+	.enable_dma = 1,  /* master has the ability to do dma transfer */
+	.pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0},
+};
+
+static struct resource bfin_spi1_resource[] = {
+	[0] = {
+		.start = SPI1_REGBASE,
+		.end   = SPI1_REGBASE + 0xFF,
+		.flags = IORESOURCE_MEM,
+		},
+	[1] = {
+		.start = CH_SPI1,
+		.end   = CH_SPI1,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = IRQ_SPI1,
+		.end   = IRQ_SPI1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device bfin_spi1_device = {
+	.name = "bfin-spi",
+	.id = 1, /* Bus number */
+	.num_resources = ARRAY_SIZE(bfin_spi1_resource),
+	.resource = bfin_spi1_resource,
+	.dev = {
+		.platform_data = &bfin_spi1_info, /* Passed to driver */
+	},
+};
+#endif  /* spi master and devices */
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
+	{
+		.start = UART0_THR,
+		.end = UART0_GCTL+2,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+	{
+		.start = UART1_THR,
+		.end = UART1_GCTL+2,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART1_ERROR,
+		.end = IRQ_UART1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_TX,
+		.end = CH_UART1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+	P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
+	.name = "bfin-uart",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_uart1_resources),
+	.resource = bfin_uart1_resources,
+	.dev = {
+		.platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+static struct resource bfin_sir0_resources[] = {
+	{
+		.start = 0xFFC00400,
+		.end = 0xFFC004FF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX+1,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device bfin_sir0_device = {
+	.name = "bfin_sir",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sir0_resources),
+	.resource = bfin_sir0_resources,
+};
+#endif
+#ifdef CONFIG_BFIN_SIR1
+static struct resource bfin_sir1_resources[] = {
+	{
+		.start = 0xFFC02000,
+		.end = 0xFFC020FF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX+1,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device bfin_sir1_device = {
+	.name = "bfin_sir",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sir1_resources),
+	.resource = bfin_sir1_resources,
+};
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct resource bfin_twi0_resource[] = {
+	[0] = {
+		.start = TWI0_REGBASE,
+		.end   = TWI0_REGBASE,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_TWI,
+		.end   = IRQ_TWI,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device i2c_bfin_twi_device = {
+	.name = "i2c-bfin-twi",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_twi0_resource),
+	.resource = bfin_twi0_resource,
+};
+#endif
+
+static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
+#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
+	{
+		I2C_BOARD_INFO("pcf8574_lcd", 0x22),
+	},
+#endif
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
+	{
+		I2C_BOARD_INFO("pcf8574_keypad", 0x27),
+		.irq = IRQ_PF8,
+	},
+#endif
+};
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
+static struct platform_device bfin_sport0_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#endif
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+static struct gpio_keys_button bfin_gpio_keys_table[] = {
+	{BTN_0, GPIO_PG0, 1, "gpio-keys: BTN0"},
+	{BTN_1, GPIO_PG13, 1, "gpio-keys: BTN1"},
+};
+
+static struct gpio_keys_platform_data bfin_gpio_keys_data = {
+	.buttons        = bfin_gpio_keys_table,
+	.nbuttons       = ARRAY_SIZE(bfin_gpio_keys_table),
+};
+
+static struct platform_device bfin_device_gpiokeys = {
+	.name      = "gpio-keys",
+	.dev = {
+		.platform_data = &bfin_gpio_keys_data,
+	},
+};
+#endif
+
+#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE)
+
+static struct bfin_sd_host bfin_sdh_data = {
+	.dma_chan = CH_RSI,
+	.irq_int0 = IRQ_RSI_INT0,
+	.pin_req = {P_RSI_DATA0, P_RSI_DATA1, P_RSI_DATA2, P_RSI_DATA3, P_RSI_CMD, P_RSI_CLK, 0},
+};
+
+static struct platform_device bf51x_sdh_device = {
+	.name = "bfin-sdh",
+	.id = 0,
+	.dev = {
+		.platform_data = &bfin_sdh_data,
+	},
+};
+#endif
+
+static const unsigned int cclk_vlev_datasheet[] =
+{
+	VRPAIR(VLEV_100, 400000000),
+	VRPAIR(VLEV_105, 426000000),
+	VRPAIR(VLEV_110, 500000000),
+	VRPAIR(VLEV_115, 533000000),
+	VRPAIR(VLEV_120, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+	.tuple_tab = cclk_vlev_datasheet,
+	.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+	.vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+	.name = "bfin dpmc",
+	.dev = {
+		.platform_data = &bfin_dmpc_vreg_data,
+	},
+};
+
+static struct platform_device *tcm_devices[] __initdata = {
+
+	&bfin_dpmc,
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+	&rtc_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	&bfin_mii_bus,
+	&bfin_mac_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+	&bfin_spi0_device,
+	&bfin_spi1_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+	&bfin_sir0_device,
+#endif
+#ifdef CONFIG_BFIN_SIR1
+	&bfin_sir1_device,
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+	&i2c_bfin_twi_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#endif
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+	&bfin_device_gpiokeys,
+#endif
+
+#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE)
+	&bf51x_sdh_device,
+#endif
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+	&tcm_flash_device,
+#endif
+};
+
+static int __init tcm_init(void)
+{
+	printk(KERN_INFO "%s(): registering device resources\n", __func__);
+	i2c_register_board_info(0, bfin_i2c_board_info,
+				ARRAY_SIZE(bfin_i2c_board_info));
+	platform_add_devices(tcm_devices, ARRAY_SIZE(tcm_devices));
+	spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+	return 0;
+}
+
+arch_initcall(tcm_init);
+
+static struct platform_device *tcm_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(tcm_early_devices,
+		ARRAY_SIZE(tcm_early_devices));
+}
+
+void native_machine_restart(char *cmd)
+{
+	/* workaround reboot hang when booting from SPI */
+	if ((bfin_read_SYSCR() & 0x7) == 0x3)
+		bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
+}
+
+void bfin_get_ether_addr(char *addr)
+{
+	random_ether_addr(addr);
+	printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
+}
+EXPORT_SYMBOL(bfin_get_ether_addr);
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/irq.h linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf518/include/mach/irq.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/irq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf518/include/mach/irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -151,7 +151,17 @@
 
 #define GPIO_IRQ_BASE	IRQ_PF0
 
-#define NR_IRQS     (IRQ_PH15 + 1)
+#define IRQ_MAC_PHYINT		119 /* PHY_INT Interrupt */
+#define IRQ_MAC_MMCINT		120 /* MMC Counter Interrupt */
+#define IRQ_MAC_RXFSINT		121 /* RX Frame-Status Interrupt */
+#define IRQ_MAC_TXFSINT		122 /* TX Frame-Status Interrupt */
+#define IRQ_MAC_WAKEDET		123 /* Wake-Up Interrupt */
+#define IRQ_MAC_RXDMAERR	124 /* RX DMA Direction Error Interrupt */
+#define IRQ_MAC_TXDMAERR	125 /* TX DMA Direction Error Interrupt */
+#define IRQ_MAC_STMDONE		126 /* Station Mgt. Transfer Done Interrupt */
+
+#define NR_MACH_IRQS	(IRQ_MAC_STMDONE + 1)
+#define NR_IRQS		(NR_MACH_IRQS + NR_SPARE_IRQS)
 
 #define IVG7            7
 #define IVG8            8
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/mem_map.h linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf518/include/mach/mem_map.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/mem_map.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf518/include/mach/mem_map.h	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,7 @@
 #define L1_DATA_A_START		0xFF800000
 #define L1_DATA_B_START		0xFF900000
 
-#define L1_CODE_LENGTH		0xC000
+#define L1_CODE_LENGTH		0x8000
 
 #ifdef CONFIG_BFIN_DCACHE
 
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/boards/cm_bf527.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf527/boards/cm_bf527.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/boards/cm_bf527.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf527/boards/cm_bf527.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/i2c.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
-#include <linux/usb/sl811.h>
 #include <linux/usb/musb.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
@@ -270,50 +269,6 @@ static struct platform_device dm9000_dev
 };
 #endif
 
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
-static struct resource sl811_hcd_resources[] = {
-	{
-		.start = 0x20340000,
-		.end = 0x20340000,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = 0x20340004,
-		.end = 0x20340004,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = CONFIG_USB_SL811_BFIN_IRQ,
-		.end = CONFIG_USB_SL811_BFIN_IRQ,
-		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-	},
-};
-
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
-void sl811_port_power(struct device *dev, int is_on)
-{
-	gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
-	gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
-}
-#endif
-
-static struct sl811_platform_data sl811_priv = {
-	.potpg = 10,
-	.power = 250,       /* == 500mA */
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
-	.port_power = &sl811_port_power,
-#endif
-};
-
-static struct platform_device sl811_hcd_device = {
-	.name = "sl811-hcd",
-	.id = 0,
-	.dev = {
-		.platform_data = &sl811_priv,
-	},
-	.num_resources = ARRAY_SIZE(sl811_hcd_resources),
-	.resource = sl811_hcd_resources,
-};
-#endif
-
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
 	.name = "bfin_mii_bus",
@@ -384,8 +339,8 @@ static struct bfin5xx_spi_chip spi_adc_c
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+	|| defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
@@ -462,8 +417,8 @@ static struct spi_board_info bfin_spi_bo
 	},
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+	|| defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 	{
 		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -603,30 +558,105 @@ static struct platform_device cm_flash_d
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = UART0_THR,
+		.end = UART0_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
 	{
-		.start = 0xFFC02000,
-		.end = 0xFFC020FF,
+		.start = UART1_THR,
+		.end = UART1_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART1_ERROR,
+		.end = IRQ_UART1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_TX,
+		.end = CH_UART1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX,
+		.flags = IORESOURCE_DMA,
+	},
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+	{	/* CTS pin */
+		.start = GPIO_PF9,
+		.end = GPIO_PF9,
+		.flags = IORESOURCE_IO,
+	},
+	{	/* RTS pin */
+		.start = GPIO_PF10,
+		.end = GPIO_PF10,
+		.flags = IORESOURCE_IO,
+	},
 #endif
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart1_peripherals[] = {
+	P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
 	.name = "bfin-uart",
 	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.num_resources = ARRAY_SIZE(bfin_uart1_resources),
+	.resource = bfin_uart1_resources,
+	.dev = {
+		.platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -725,16 +755,75 @@ static struct i2c_board_info __initdata
 };
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 #include <linux/input.h>
@@ -795,10 +884,6 @@ static struct platform_device *cmbf527_d
 	&rtc_device,
 #endif
 
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
-	&sl811_hcd_device,
-#endif
-
 #if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
 	&bfin_isp1760_device,
 #endif
@@ -829,7 +914,12 @@ static struct platform_device *cmbf527_d
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -846,9 +936,13 @@ static struct platform_device *cmbf527_d
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
 	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
 	&bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 	&bfin_device_gpiokeys,
@@ -871,6 +965,33 @@ static int __init cm_init(void)
 
 arch_initcall(cm_init);
 
+static struct platform_device *cmbf527_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(cmbf527_early_devices,
+		ARRAY_SIZE(cmbf527_early_devices));
+}
+
 void native_machine_restart(char *cmd)
 {
 	/* workaround reboot hang when booting from SPI */
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/boards/ezbrd.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf527/boards/ezbrd.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/boards/ezbrd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf527/boards/ezbrd.c	2010-05-16 17:17:36.000000000 -0400
@@ -274,8 +274,8 @@ static const struct ad7879_platform_data
 	.median			= 2,	/* do 8 measurements */
 	.averaging 		= 1,	/* take the average of 4 middle samples */
 	.pen_down_acc_interval 	= 255,	/* 9.4 ms */
-	.gpio_output		= 1,	/* configure AUX/VBAT/GPIO as GPIO output */
-	.gpio_default 		= 1,	/* During initialization set GPIO = HIGH */
+	.gpio_export		= 1,	/* Export GPIO to gpiolib */
+	.gpio_base		= -1,	/* Dynamic allocation */
 };
 #endif
 
@@ -439,30 +439,105 @@ static struct platform_device bfin_spi0_
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = UART0_THR,
+		.end = UART0_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
 	{
-		.start = 0xFFC02000,
-		.end = 0xFFC020FF,
+		.start = UART1_THR,
+		.end = UART1_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART1_ERROR,
+		.end = IRQ_UART1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_TX,
+		.end = CH_UART1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX,
+		.flags = IORESOURCE_DMA,
+	},
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+	{	/* CTS pin */
+		.start = GPIO_PG0,
+		.end = GPIO_PG0,
+		.flags = IORESOURCE_IO,
+	},
+	{	/* RTS pin */
+		.start = GPIO_PF10,
+		.end = GPIO_PF10,
+		.flags = IORESOURCE_IO,
+	},
 #endif
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart1_peripherals[] = {
+	P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
 	.name = "bfin-uart",
 	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.num_resources = ARRAY_SIZE(bfin_uart1_resources),
+	.resource = bfin_uart1_resources,
+	.dev = {
+		.platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -556,16 +631,75 @@ static struct i2c_board_info __initdata
 };
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 #include <linux/input.h>
@@ -615,9 +749,10 @@ static struct platform_device bfin_dpmc
 #include <asm/bfin-lq035q1.h>
 
 static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = {
-	.mode = 	LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
-	.use_bl = 	1,
-	.gpio_bl =	GPIO_PG12,
+	.mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
+	.ppi_mode = USE_RGB565_16_BIT_PPI,
+	.use_bl = 1,
+	.gpio_bl = GPIO_PG12,
 };
 
 static struct resource bfin_lq035q1_resources[] = {
@@ -665,7 +800,12 @@ static struct platform_device *stamp_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
@@ -686,9 +826,13 @@ static struct platform_device *stamp_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
 	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
 	&bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 	&bfin_device_gpiokeys,
@@ -711,6 +855,33 @@ static int __init ezbrd_init(void)
 
 arch_initcall(ezbrd_init);
 
+static struct platform_device *ezbrd_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(ezbrd_early_devices,
+		ARRAY_SIZE(ezbrd_early_devices));
+}
+
 void native_machine_restart(char *cmd)
 {
 	/* workaround reboot hang when booting from SPI */
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/boards/ezkit.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf527/boards/ezkit.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/boards/ezkit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf527/boards/ezkit.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,8 +16,9 @@
 #include <linux/i2c.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
-#include <linux/usb/sl811.h>
 #include <linux/usb/musb.h>
+#include <linux/leds.h>
+#include <linux/input.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/reboot.h>
@@ -29,7 +30,11 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
+#ifdef CONFIG_BFIN527_EZKIT_V2
+const char bfin_board_name[] = "ADI BF527-EZKIT V2";
+#else
 const char bfin_board_name[] = "ADI BF527-EZKIT";
+#endif
 
 /*
  *  Driver needs to know address, irq and flag pin.
@@ -143,6 +148,33 @@ static struct platform_device bf52x_t350
 };
 #endif
 
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+#include <asm/bfin-lq035q1.h>
+
+static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = {
+	.mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
+	.ppi_mode = USE_RGB565_8_BIT_PPI,
+};
+
+static struct resource bfin_lq035q1_resources[] = {
+	{
+		.start = IRQ_PPI_ERROR,
+		.end = IRQ_PPI_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device bfin_lq035q1_device = {
+	.name		= "bfin-lq035q1",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(bfin_lq035q1_resources),
+	.resource	= bfin_lq035q1_resources,
+	.dev		= {
+		.platform_data = &bfin_lq035q1_data,
+	},
+};
+#endif
+
 #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
 static struct mtd_partition ezkit_partitions[] = {
 	{
@@ -326,50 +358,6 @@ static struct platform_device dm9000_dev
 };
 #endif
 
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
-static struct resource sl811_hcd_resources[] = {
-	{
-		.start = 0x20340000,
-		.end = 0x20340000,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = 0x20340004,
-		.end = 0x20340004,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = CONFIG_USB_SL811_BFIN_IRQ,
-		.end = CONFIG_USB_SL811_BFIN_IRQ,
-		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-	},
-};
-
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
-void sl811_port_power(struct device *dev, int is_on)
-{
-	gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
-	gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
-}
-#endif
-
-static struct sl811_platform_data sl811_priv = {
-	.potpg = 10,
-	.power = 250,       /* == 500mA */
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
-	.port_power = &sl811_port_power,
-#endif
-};
-
-static struct platform_device sl811_hcd_device = {
-	.name = "sl811-hcd",
-	.id = 0,
-	.dev = {
-		.platform_data = &sl811_priv,
-	},
-	.num_resources = ARRAY_SIZE(sl811_hcd_resources),
-	.resource = sl811_hcd_resources,
-};
-#endif
-
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
 	.name = "bfin_mii_bus",
@@ -440,8 +428,8 @@ static struct bfin5xx_spi_chip spi_adc_c
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+	|| defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
@@ -488,8 +476,7 @@ static const struct ad7879_platform_data
 	.median			= 2,	/* do 8 measurements */
 	.averaging 		= 1,	/* take the average of 4 middle samples */
 	.pen_down_acc_interval 	= 255,	/* 9.4 ms */
-	.gpio_output		= 1,	/* configure AUX/VBAT/GPIO as GPIO output */
-	.gpio_default 		= 1,	/* During initialization set GPIO = HIGH */
+	.gpio_export		= 0,	/* Export GPIO to gpiolib */
 };
 #endif
 
@@ -500,14 +487,6 @@ static struct bfin5xx_spi_chip spi_ad787
 };
 #endif
 
-#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \
-	 && defined(CONFIG_SND_SOC_WM8731_SPI)
-static struct bfin5xx_spi_chip spi_wm8731_chip_info = {
-	.enable_dma = 0,
-	.bits_per_word = 16,
-};
-#endif
-
 #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
 static struct bfin5xx_spi_chip spidev_chip_info = {
 	.enable_dma = 0,
@@ -515,6 +494,29 @@ static struct bfin5xx_spi_chip spidev_ch
 };
 #endif
 
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+	.name = "bfin-i2s",
+	.id = CONFIG_SND_BF5XX_SPORT_NUM,
+	/* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+	.name = "bfin-tdm",
+	.id = CONFIG_SND_BF5XX_SPORT_NUM,
+	/* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+static struct bfin5xx_spi_chip lq035q1_spi_chip_info = {
+	.enable_dma	= 0,
+	.bits_per_word	= 8,
+};
+#endif
+
 static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_MTD_M25P80) \
 	|| defined(CONFIG_MTD_M25P80_MODULE)
@@ -542,8 +544,8 @@ static struct spi_board_info bfin_spi_bo
 	},
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+	|| defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 	{
 		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -586,17 +588,6 @@ static struct spi_board_info bfin_spi_bo
 		.mode = SPI_CPHA | SPI_CPOL,
 	},
 #endif
-#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \
-	 && defined(CONFIG_SND_SOC_WM8731_SPI)
-	{
-		.modalias	= "wm8731",
-		.max_speed_hz	= 3125000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num	= 0,
-		.chip_select    = 5,
-		.controller_data = &spi_wm8731_chip_info,
-		.mode = SPI_MODE_0,
-	},
-#endif
 #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
 	{
 		.modalias = "spidev",
@@ -606,6 +597,16 @@ static struct spi_board_info bfin_spi_bo
 		.controller_data = &spidev_chip_info,
 	},
 #endif
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+	{
+		.modalias = "bfin-lq035q1-spi",
+		.max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.chip_select = 7,
+		.controller_data = &lq035q1_spi_chip_info,
+		.mode = SPI_CPHA | SPI_CPOL,
+	},
+#endif
 };
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
@@ -647,30 +648,105 @@ static struct platform_device bfin_spi0_
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = UART0_THR,
+		.end = UART0_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
 	{
-		.start = 0xFFC02000,
-		.end = 0xFFC020FF,
+		.start = UART1_THR,
+		.end = UART1_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART1_ERROR,
+		.end = IRQ_UART1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_TX,
+		.end = CH_UART1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX,
+		.flags = IORESOURCE_DMA,
+	},
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+	{	/* CTS pin */
+		.start = GPIO_PF9,
+		.end = GPIO_PF9,
+		.flags = IORESOURCE_IO,
+	},
+	{	/* RTS pin */
+		.start = GPIO_PF10,
+		.end = GPIO_PF10,
+		.flags = IORESOURCE_IO,
+	},
 #endif
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart1_peripherals[] = {
+	P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
 	.name = "bfin-uart",
 	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.num_resources = ARRAY_SIZE(bfin_uart1_resources),
+	.resource = bfin_uart1_resources,
+	.dev = {
+		.platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -749,6 +825,71 @@ static struct platform_device i2c_bfin_t
 };
 #endif
 
+#if defined(CONFIG_PMIC_ADP5520) || defined(CONFIG_PMIC_ADP5520_MODULE)
+#include <linux/mfd/adp5520.h>
+
+	/*
+	 *  ADP5520/5501 LEDs Data
+	 */
+
+static struct led_info adp5520_leds[] = {
+	{
+		.name = "adp5520-led1",
+		.default_trigger = "none",
+		.flags = FLAG_ID_ADP5520_LED1_ADP5501_LED0 | ADP5520_LED_OFFT_600ms,
+	},
+};
+
+static struct adp5520_leds_platform_data adp5520_leds_data = {
+	.num_leds = ARRAY_SIZE(adp5520_leds),
+	.leds = adp5520_leds,
+	.fade_in = ADP5520_FADE_T_600ms,
+	.fade_out = ADP5520_FADE_T_600ms,
+	.led_on_time = ADP5520_LED_ONT_600ms,
+};
+
+	/*
+	 *  ADP5520 Keypad Data
+	 */
+
+static const unsigned short adp5520_keymap[ADP5520_KEYMAPSIZE] = {
+	[ADP5520_KEY(3, 3)]	= KEY_1,
+	[ADP5520_KEY(2, 3)]	= KEY_2,
+	[ADP5520_KEY(1, 3)]	= KEY_3,
+	[ADP5520_KEY(0, 3)]	= KEY_UP,
+	[ADP5520_KEY(3, 2)]	= KEY_4,
+	[ADP5520_KEY(2, 2)]	= KEY_5,
+	[ADP5520_KEY(1, 2)]	= KEY_6,
+	[ADP5520_KEY(0, 2)]	= KEY_DOWN,
+	[ADP5520_KEY(3, 1)]	= KEY_7,
+	[ADP5520_KEY(2, 1)]	= KEY_8,
+	[ADP5520_KEY(1, 1)]	= KEY_9,
+	[ADP5520_KEY(0, 1)]	= KEY_DOT,
+	[ADP5520_KEY(3, 0)]	= KEY_BACKSPACE,
+	[ADP5520_KEY(2, 0)]	= KEY_0,
+	[ADP5520_KEY(1, 0)]	= KEY_HELP,
+	[ADP5520_KEY(0, 0)]	= KEY_ENTER,
+};
+
+static struct adp5520_keys_platform_data adp5520_keys_data = {
+	.rows_en_mask	= ADP5520_ROW_R3 | ADP5520_ROW_R2 | ADP5520_ROW_R1 | ADP5520_ROW_R0,
+	.cols_en_mask	= ADP5520_COL_C3 | ADP5520_COL_C2 | ADP5520_COL_C1 | ADP5520_COL_C0,
+	.keymap		= adp5520_keymap,
+	.keymapsize	= ARRAY_SIZE(adp5520_keymap),
+	.repeat		= 0,
+};
+
+	/*
+	 *  ADP5520/5501 Multifuction Device Init Data
+	 */
+
+static struct adp5520_platform_data adp5520_pdev_data = {
+	.leds = &adp5520_leds_data,
+	.keys = &adp5520_keys_data,
+};
+
+#endif
+
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
 	{
@@ -766,22 +907,99 @@ static struct i2c_board_info __initdata
 		I2C_BOARD_INFO("bfin-adv7393", 0x2B),
 	},
 #endif
+#if defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
+	{
+		I2C_BOARD_INFO("ad7879", 0x2C),
+		.irq = IRQ_PF8,
+		.platform_data = (void *)&bfin_ad7879_ts_info,
+	},
+#endif
+#if defined(CONFIG_PMIC_ADP5520) || defined(CONFIG_PMIC_ADP5520_MODULE)
+	{
+		I2C_BOARD_INFO("pmic-adp5520", 0x32),
+		.irq = IRQ_PF9,
+		.platform_data = (void *)&adp5520_pdev_data,
+	},
+#endif
+#if defined(CONFIG_SND_SOC_SSM2602) || defined(CONFIG_SND_SOC_SSM2602_MODULE)
+	{
+		I2C_BOARD_INFO("ssm2602", 0x1b),
+	},
+#endif
 };
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
-#include <linux/input.h>
 #include <linux/gpio_keys.h>
 
 static struct gpio_keys_button bfin_gpio_keys_table[] = {
@@ -803,7 +1021,6 @@ static struct platform_device bfin_devic
 #endif
 
 #if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE)
-#include <linux/input.h>
 #include <asm/bfin_rotary.h>
 
 static struct bfin_rotary_platform_data bfin_rotary_data = {
@@ -872,10 +1089,6 @@ static struct platform_device *stamp_dev
 	&rtc_device,
 #endif
 
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
-	&sl811_hcd_device,
-#endif
-
 #if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
 	&bfin_isp1760_device,
 #endif
@@ -909,8 +1122,17 @@ static struct platform_device *stamp_dev
 	&bf52x_t350mcqb_device,
 #endif
 
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+	&bfin_lq035q1_device,
+#endif
+
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -927,9 +1149,13 @@ static struct platform_device *stamp_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
 	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
 	&bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 	&bfin_device_gpiokeys,
@@ -942,6 +1168,14 @@ static struct platform_device *stamp_dev
 #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
 	&ezkit_flash_device,
 #endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+	&bfin_i2s,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+	&bfin_tdm,
+#endif
 };
 
 static int __init ezkit_init(void)
@@ -956,6 +1190,33 @@ static int __init ezkit_init(void)
 
 arch_initcall(ezkit_init);
 
+static struct platform_device *ezkit_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(ezkit_early_devices,
+		ARRAY_SIZE(ezkit_early_devices));
+}
+
 void native_machine_restart(char *cmd)
 {
 	/* workaround reboot hang when booting from SPI */
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/boards/Kconfig linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf527/boards/Kconfig
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/boards/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf527/boards/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,11 @@ config BFIN527_EZKIT
 	help
 	  BF527-EZKIT-LITE board support.
 
+config BFIN527_EZKIT_V2
+	bool "BF527-EZKIT-V2"
+	help
+	  BF527-EZKIT-LITE V2.1+ board support.
+
 config BFIN527_BLUETECHNIX_CM
 	bool "Bluetechnix CM-BF527"
 	help
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/boards/Makefile linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf527/boards/Makefile
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/boards/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf527/boards/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -3,5 +3,6 @@
 #
 
 obj-$(CONFIG_BFIN527_EZKIT)            += ezkit.o
+obj-$(CONFIG_BFIN527_EZKIT_V2)         += ezkit.o
 obj-$(CONFIG_BFIN527_BLUETECHNIX_CM)   += cm_bf527.o
 obj-$(CONFIG_BFIN526_EZBRD)            += ezbrd.o
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/irq.h linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf527/include/mach/irq.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/irq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf527/include/mach/irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -151,7 +151,17 @@
 
 #define GPIO_IRQ_BASE	IRQ_PF0
 
-#define NR_IRQS     (IRQ_PH15+1)
+#define IRQ_MAC_PHYINT		119 /* PHY_INT Interrupt */
+#define IRQ_MAC_MMCINT		120 /* MMC Counter Interrupt */
+#define IRQ_MAC_RXFSINT		121 /* RX Frame-Status Interrupt */
+#define IRQ_MAC_TXFSINT		122 /* TX Frame-Status Interrupt */
+#define IRQ_MAC_WAKEDET		123 /* Wake-Up Interrupt */
+#define IRQ_MAC_RXDMAERR	124 /* RX DMA Direction Error Interrupt */
+#define IRQ_MAC_TXDMAERR	125 /* TX DMA Direction Error Interrupt */
+#define IRQ_MAC_STMDONE		126 /* Station Mgt. Transfer Done Interrupt */
+
+#define NR_MACH_IRQS	(IRQ_MAC_STMDONE + 1)
+#define NR_IRQS		(NR_MACH_IRQS + NR_SPARE_IRQS)
 
 #define IVG7            7
 #define IVG8            8
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/blackstamp.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf533/boards/blackstamp.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/blackstamp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf533/boards/blackstamp.c	2010-05-16 17:17:36.000000000 -0400
@@ -195,21 +195,50 @@ static struct platform_device bfin_spi0_
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = BFIN_UART_THR,
+		.end = BFIN_UART_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX + 1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
 	.name = "bfin-uart",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -241,16 +270,75 @@ static struct platform_device bfin_sir0_
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 #include <linux/input.h>
@@ -344,7 +432,9 @@ static struct platform_device *stamp_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -354,9 +444,13 @@ static struct platform_device *stamp_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
 	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
 	&bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 	&bfin_device_gpiokeys,
@@ -392,3 +486,27 @@ static int __init blackstamp_init(void)
 }
 
 arch_initcall(blackstamp_init);
+
+static struct platform_device *stamp_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(stamp_early_devices,
+		ARRAY_SIZE(stamp_early_devices));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/cm_bf533.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf533/boards/cm_bf533.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/cm_bf533.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf533/boards/cm_bf533.c	2010-05-16 17:17:36.000000000 -0400
@@ -71,7 +71,7 @@ static struct bfin5xx_spi_chip spi_adc_c
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
@@ -110,7 +110,7 @@ static struct spi_board_info bfin_spi_bo
 	},
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 	{
 		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -242,21 +242,50 @@ static struct platform_device smsc911x_d
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = BFIN_UART_THR,
+		.end = BFIN_UART_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX + 1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
 	.name = "bfin-uart",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -288,16 +317,75 @@ static struct platform_device bfin_sir0_
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 static struct resource isp1362_hcd_resources[] = {
@@ -432,7 +520,9 @@ static struct platform_device *cm_bf533_
 	&bfin_dpmc,
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -442,9 +532,13 @@ static struct platform_device *cm_bf533_
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
 	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
 	&bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
 	&rtc_device,
@@ -486,3 +580,27 @@ static int __init cm_bf533_init(void)
 }
 
 arch_initcall(cm_bf533_init);
+
+static struct platform_device *cm_bf533_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(cm_bf533_early_devices,
+		ARRAY_SIZE(cm_bf533_early_devices));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/ezkit.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf533/boards/ezkit.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/ezkit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf533/boards/ezkit.c	2010-05-16 17:17:36.000000000 -0400
@@ -222,7 +222,7 @@ static struct bfin5xx_spi_chip spi_adc_c
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
@@ -261,7 +261,7 @@ static struct spi_board_info bfin_spi_bo
 	},
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 	{
 		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -320,21 +320,50 @@ static struct platform_device bfin_spi0_
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = BFIN_UART_THR,
+		.end = BFIN_UART_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX + 1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
 	.name = "bfin-uart",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -444,6 +473,30 @@ static struct i2c_board_info __initdata
 #endif
 };
 
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+	.name = "bfin-i2s",
+	.id = CONFIG_SND_BF5XX_SPORT_NUM,
+	/* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+	.name = "bfin-tdm",
+	.id = CONFIG_SND_BF5XX_SPORT_NUM,
+	/* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+static struct platform_device bfin_ac97 = {
+	.name = "bfin-ac97",
+	.id = CONFIG_SND_BF5XX_SPORT_NUM,
+	/* TODO: add platform data here */
+};
+#endif
+
 static struct platform_device *ezkit_devices[] __initdata = {
 
 	&bfin_dpmc,
@@ -471,7 +524,9 @@ static struct platform_device *ezkit_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -487,6 +542,18 @@ static struct platform_device *ezkit_dev
 #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
 	&i2c_gpio_device,
 #endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+	&bfin_i2s,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+	&bfin_tdm,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+	&bfin_ac97,
+#endif
 };
 
 static int __init ezkit_init(void)
@@ -500,3 +567,18 @@ static int __init ezkit_init(void)
 }
 
 arch_initcall(ezkit_init);
+
+static struct platform_device *ezkit_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(ezkit_early_devices,
+		ARRAY_SIZE(ezkit_early_devices));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/H8606.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf533/boards/H8606.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/H8606.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf533/boards/H8606.c	2010-05-16 17:17:36.000000000 -0400
@@ -171,7 +171,7 @@ static struct bfin5xx_spi_chip spi_adc_c
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
@@ -206,7 +206,7 @@ static struct spi_board_info bfin_spi_bo
 	},
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 	{
 		.modalias = "ad1836",
 		.max_speed_hz = 16,
@@ -257,21 +257,50 @@ static struct platform_device bfin_spi0_
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = BFIN_UART_THR,
+		.end = BFIN_UART_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX + 1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
 	.name = "bfin-uart",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -394,7 +423,9 @@ static struct platform_device *h8606_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
@@ -424,3 +455,18 @@ static int __init H8606_init(void)
 }
 
 arch_initcall(H8606_init);
+
+static struct platform_device *H8606_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(H8606_early_devices,
+		ARRAY_SIZE(H8606_early_devices));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/ip0x.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf533/boards/ip0x.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/ip0x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf533/boards/ip0x.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/usb/isp1362.h>
 #endif
 #include <asm/irq.h>
+#include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
 
@@ -143,21 +144,50 @@ static struct platform_device spi_bfin_m
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = BFIN_UART_THR,
+		.end = BFIN_UART_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX + 1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
 	.name = "bfin-uart",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -241,7 +271,9 @@ static struct platform_device *ip0x_devi
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -276,3 +308,18 @@ static int __init ip0x_init(void)
 }
 
 arch_initcall(ip0x_init);
+
+static struct platform_device *ip0x_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(ip0x_early_devices,
+		ARRAY_SIZE(ip0x_early_devices));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/stamp.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf533/boards/stamp.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/stamp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf533/boards/stamp.c	2010-05-16 17:17:36.000000000 -0400
@@ -184,7 +184,7 @@ static struct bfin5xx_spi_chip spi_adc_c
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
@@ -251,7 +251,7 @@ static struct spi_board_info bfin_spi_bo
 	},
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 	{
 		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -322,21 +322,50 @@ static struct platform_device bfin_spi0_
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = BFIN_UART_THR,
+		.end = BFIN_UART_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX + 1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
 	.name = "bfin-uart",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -368,16 +397,75 @@ static struct platform_device bfin_sir0_
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 #include <linux/input.h>
@@ -474,6 +562,30 @@ static struct platform_device bfin_dpmc
 	},
 };
 
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+	.name = "bfin-i2s",
+	.id = CONFIG_SND_BF5XX_SPORT_NUM,
+	/* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+	.name = "bfin-tdm",
+	.id = CONFIG_SND_BF5XX_SPORT_NUM,
+	/* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+static struct platform_device bfin_ac97 = {
+	.name = "bfin-ac97",
+	.id = CONFIG_SND_BF5XX_SPORT_NUM,
+	/* TODO: add platform data here */
+};
+#endif
+
 static struct platform_device *stamp_devices[] __initdata = {
 
 	&bfin_dpmc,
@@ -495,7 +607,9 @@ static struct platform_device *stamp_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -505,9 +619,13 @@ static struct platform_device *stamp_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
 	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
 	&bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 	&bfin_device_gpiokeys,
@@ -520,6 +638,18 @@ static struct platform_device *stamp_dev
 #if defined(CONFIG_MTD_BFIN_ASYNC) || defined(CONFIG_MTD_BFIN_ASYNC_MODULE)
 	&stamp_flash_device,
 #endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+	&bfin_i2s,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+	&bfin_tdm,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+	&bfin_ac97,
+#endif
 };
 
 static int __init stamp_init(void)
@@ -548,6 +678,30 @@ static int __init stamp_init(void)
 
 arch_initcall(stamp_init);
 
+static struct platform_device *stamp_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(stamp_early_devices,
+		ARRAY_SIZE(stamp_early_devices));
+}
+
 void native_machine_restart(char *cmd)
 {
 	/* workaround pull up on cpld / flash pin not being strong enough */
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/include/mach/irq.h linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf533/include/mach/irq.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/include/mach/irq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf533/include/mach/irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -104,7 +104,8 @@ Core        Emulation               **
 
 #define GPIO_IRQ_BASE		IRQ_PF0
 
-#define	NR_IRQS		(IRQ_PF15+1)
+#define NR_MACH_IRQS		(IRQ_PF15 + 1)
+#define NR_IRQS			(NR_MACH_IRQS + NR_SPARE_IRQS)
 
 #define IVG7			7
 #define IVG8			8
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/cm_bf537e.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/boards/cm_bf537e.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/cm_bf537e.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/boards/cm_bf537e.c	2010-05-16 17:17:36.000000000 -0400
@@ -73,7 +73,7 @@ static struct bfin5xx_spi_chip spi_adc_c
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
@@ -112,7 +112,7 @@ static struct spi_board_info bfin_spi_bo
 	},
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 	{
 		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -329,8 +329,8 @@ static struct platform_device cm_flash_d
 #ifdef CONFIG_SERIAL_BFIN_UART0
 static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = UART0_THR,
+		.end = UART0_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
 	{
@@ -373,18 +373,25 @@ static struct resource bfin_uart0_resour
 #endif
 };
 
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
 static struct platform_device bfin_uart0_device = {
 	.name = "bfin-uart",
 	.id = 0,
 	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
 	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
 };
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
 static struct resource bfin_uart1_resources[] = {
 	{
-		.start = 0xFFC02000,
-		.end = 0xFFC020FF,
+		.start = UART1_THR,
+		.end = UART1_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
 	{
@@ -427,11 +434,18 @@ static struct resource bfin_uart1_resour
 #endif
 };
 
+unsigned short bfin_uart1_peripherals[] = {
+	P_UART1_TX, P_UART1_RX, 0
+};
+
 static struct platform_device bfin_uart1_device = {
 	.name = "bfin-uart",
 	.id = 1,
 	.num_resources = ARRAY_SIZE(bfin_uart1_resources),
 	.resource = bfin_uart1_resources,
+	.dev = {
+		.platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+	},
 };
 #endif
 #endif
@@ -512,16 +526,75 @@ static struct platform_device i2c_bfin_t
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
@@ -633,9 +706,13 @@ static struct platform_device *cm_bf537e
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
 	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
 	&bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 	&isp1362_hcd_device,
@@ -683,6 +760,33 @@ static int __init cm_bf537e_init(void)
 
 arch_initcall(cm_bf537e_init);
 
+static struct platform_device *cm_bf537e_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(cm_bf537e_early_devices,
+		ARRAY_SIZE(cm_bf537e_early_devices));
+}
+
 void bfin_get_ether_addr(char *addr)
 {
 	random_ether_addr(addr);
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/cm_bf537u.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/boards/cm_bf537u.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/cm_bf537u.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/boards/cm_bf537u.c	2010-05-16 17:17:36.000000000 -0400
@@ -74,7 +74,7 @@ static struct bfin5xx_spi_chip spi_adc_c
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
@@ -113,7 +113,7 @@ static struct spi_board_info bfin_spi_bo
 	},
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 	{
 		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -327,25 +327,93 @@ static struct platform_device cm_flash_d
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = UART0_THR,
+		.end = UART0_GCTL+2,
 		.flags = IORESOURCE_MEM,
-	}, {
-		.start = 0xFFC02000,
-		.end = 0xFFC020FF,
+	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+	{
+		.start = UART1_THR,
+		.end = UART1_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART1_ERROR,
+		.end = IRQ_UART1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_TX,
+		.end = CH_UART1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart1_peripherals[] = {
+	P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
 	.name = "bfin-uart",
 	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.num_resources = ARRAY_SIZE(bfin_uart1_resources),
+	.resource = bfin_uart1_resources,
+	.dev = {
+		.platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -423,16 +491,75 @@ static struct platform_device i2c_bfin_t
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
@@ -522,7 +649,12 @@ static struct platform_device *cm_bf537u
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -539,9 +671,13 @@ static struct platform_device *cm_bf537u
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
 	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
 	&bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 	&isp1362_hcd_device,
@@ -589,6 +725,33 @@ static int __init cm_bf537u_init(void)
 
 arch_initcall(cm_bf537u_init);
 
+static struct platform_device *cm_bf537u_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(cm_bf537u_early_devices,
+		ARRAY_SIZE(cm_bf537u_early_devices));
+}
+
 void bfin_get_ether_addr(char *addr)
 {
 	random_ether_addr(addr);
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/minotaur.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/boards/minotaur.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/minotaur.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/boards/minotaur.c	2010-05-16 17:17:36.000000000 -0400
@@ -211,25 +211,93 @@ static struct platform_device bfin_spi0_
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = UART0_THR,
+		.end = UART0_GCTL+2,
 		.flags = IORESOURCE_MEM,
-	}, {
-		.start = 0xFFC02000,
-		.end = 0xFFC020FF,
+	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+	{
+		.start = UART1_THR,
+		.end = UART1_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART1_ERROR,
+		.end = IRQ_UART1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_TX,
+		.end = CH_UART1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart1_peripherals[] = {
+	P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
 	.name = "bfin-uart",
 	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.num_resources = ARRAY_SIZE(bfin_uart1_resources),
+	.resource = bfin_uart1_resources,
+	.dev = {
+		.platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -309,16 +377,75 @@ static struct platform_device i2c_bfin_t
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 static struct platform_device *minotaur_devices[] __initdata = {
 #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
@@ -343,7 +470,12 @@ static struct platform_device *minotaur_
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -360,9 +492,13 @@ static struct platform_device *minotaur_
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
 	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
 	&bfin_sport1_uart_device,
 #endif
+#endif
 
 };
 
@@ -380,6 +516,33 @@ static int __init minotaur_init(void)
 
 arch_initcall(minotaur_init);
 
+static struct platform_device *minotaur_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(minotaur_early_devices,
+		ARRAY_SIZE(minotaur_early_devices));
+}
+
 void native_machine_restart(char *cmd)
 {
 	/* workaround reboot hang when booting from SPI */
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/pnav10.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/boards/pnav10.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/pnav10.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/boards/pnav10.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
-#include <linux/usb/sl811.h>
 
 #include <linux/spi/ad7877.h>
 
@@ -99,51 +98,6 @@ static struct platform_device smc91x_dev
 };
 #endif
 
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
-static struct resource sl811_hcd_resources[] = {
-	{
-		.start = 0x20340000,
-		.end = 0x20340000,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = 0x20340004,
-		.end = 0x20340004,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = CONFIG_USB_SL811_BFIN_IRQ,
-		.end = CONFIG_USB_SL811_BFIN_IRQ,
-		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-	},
-};
-
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
-void sl811_port_power(struct device *dev, int is_on)
-{
-	gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
-	gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
-
-}
-#endif
-
-static struct sl811_platform_data sl811_priv = {
-	.potpg = 10,
-	.power = 250,       /* == 500mA */
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
-	.port_power = &sl811_port_power,
-#endif
-};
-
-static struct platform_device sl811_hcd_device = {
-	.name = "sl811-hcd",
-	.id = 0,
-	.dev = {
-		.platform_data = &sl811_priv,
-	},
-	.num_resources = ARRAY_SIZE(sl811_hcd_resources),
-	.resource = sl811_hcd_resources,
-};
-#endif
-
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
 	.name = "bfin_mii_bus",
@@ -221,8 +175,8 @@ static struct bfin5xx_spi_chip spi_adc_c
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+	|| defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
@@ -284,8 +238,8 @@ static struct spi_board_info bfin_spi_bo
 	},
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+	|| defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 	{
 		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -362,25 +316,93 @@ static struct platform_device bfin_fb_de
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = UART0_THR,
+		.end = UART0_GCTL+2,
 		.flags = IORESOURCE_MEM,
-	}, {
-		.start = 0xFFC02000,
-		.end = 0xFFC020FF,
+	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+	{
+		.start = UART1_THR,
+		.end = UART1_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART1_ERROR,
+		.end = IRQ_UART1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_TX,
+		.end = CH_UART1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart1_peripherals[] = {
+	P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
 	.name = "bfin-uart",
 	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.num_resources = ARRAY_SIZE(bfin_uart1_resources),
+	.resource = bfin_uart1_resources,
+	.dev = {
+		.platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -446,10 +468,6 @@ static struct platform_device *stamp_dev
 	&rtc_device,
 #endif
 
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
-	&sl811_hcd_device,
-#endif
-
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
 	&smc91x_device,
 #endif
@@ -472,7 +490,12 @@ static struct platform_device *stamp_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -498,6 +521,24 @@ static int __init pnav_init(void)
 
 arch_initcall(pnav_init);
 
+static struct platform_device *stamp_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(stamp_early_devices,
+		ARRAY_SIZE(stamp_early_devices));
+}
+
 void bfin_get_ether_addr(char *addr)
 {
 	random_ether_addr(addr);
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/stamp.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/boards/stamp.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/stamp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/boards/stamp.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,10 +20,12 @@
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb/isp1362.h>
 #endif
+#include <linux/i2c.h>
+#include <linux/i2c/adp5588.h>
+#include <linux/etherdevice.h>
 #include <linux/ata_platform.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
-#include <linux/i2c.h>
 #include <linux/usb/sl811.h>
 #include <linux/spi/mmc_spi.h>
 #include <linux/leds.h>
@@ -33,6 +35,14 @@
 #include <asm/reboot.h>
 #include <asm/portmux.h>
 #include <asm/dpmc.h>
+#ifdef CONFIG_REGULATOR_ADP_SWITCH
+#include <linux/regulator/adp_switch.h>
+#endif
+#ifdef CONFIG_REGULATOR_AD5398
+#include <linux/regulator/ad5398.h>
+#endif
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/userspace-consumer.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -208,8 +218,8 @@ static struct resource sl811_hcd_resourc
 		.end = 0x20340004,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = CONFIG_USB_SL811_BFIN_IRQ,
-		.end = CONFIG_USB_SL811_BFIN_IRQ,
+		.start = IRQ_PF4,
+		.end = IRQ_PF4,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
 	},
 };
@@ -454,6 +464,9 @@ static struct physmap_flash_data stamp_f
 	.width      = 2,
 	.parts      = stamp_partitions,
 	.nr_parts   = ARRAY_SIZE(stamp_partitions),
+#ifdef CONFIG_ROMKERNEL
+	.probe_type = "map_rom",
+#endif
 };
 
 static struct resource stamp_flash_resource = {
@@ -515,20 +528,19 @@ static struct bfin5xx_spi_chip spi_adc_c
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
-	|| defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+	|| defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_AD1938) \
-	|| defined(CONFIG_SND_BF5XX_SOC_AD1938_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD193X) \
+	|| defined(CONFIG_SND_BF5XX_SOC_AD193X_MODULE)
 static struct bfin5xx_spi_chip ad1938_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 8,
-	.cs_gpio = GPIO_PF5,
 };
 #endif
 
@@ -644,6 +656,42 @@ static struct ad714x_platform_data ad714
 };
 #endif
 
+#if defined(CONFIG_AD2S90) || defined(CONFIG_AD2S90_MODULE)
+static struct bfin5xx_spi_chip ad2s90_spi_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD2S120X) || defined(CONFIG_AD2S120X_MODULE)
+unsigned short ad2s120x_platform_data[] = {
+	/* used as SAMPLE and RDVEL */
+	GPIO_PF5, GPIO_PF6, 0
+};
+
+static struct bfin5xx_spi_chip ad2s120x_spi_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD2S1210) || defined(CONFIG_AD2S1210_MODULE)
+unsigned short ad2s1210_platform_data[] = {
+	/* use as SAMPLE, A0, A1 */
+	GPIO_PF7, GPIO_PF8, GPIO_PF9,
+# if defined(CONFIG_AD2S1210_GPIO_INPUT) || defined(CONFIG_AD2S1210_GPIO_OUTPUT)
+	/* the RES0 and RES1 pins */
+	GPIO_PF4, GPIO_PF5,
+# endif
+	0,
+};
+
+static struct bfin5xx_spi_chip ad2s1210_spi_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 8,
+};
+#endif
+
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 #define MMC_SPI_CARD_DETECT_INT IRQ_PF5
 
@@ -686,11 +734,11 @@ static const struct ad7877_platform_data
 	.y_plate_ohms		= 486,
 	.pressure_max		= 1000,
 	.pressure_min		= 0,
-	.stopacq_polarity 	= 1,
-	.first_conversion_delay = 3,
-	.acquisition_time 	= 1,
-	.averaging 		= 1,
-	.pen_down_acc_interval 	= 1,
+	.stopacq_polarity	= 1,
+	.first_conversion_delay	= 3,
+	.acquisition_time	= 1,
+	.averaging		= 1,
+	.pen_down_acc_interval	= 1,
 };
 #endif
 
@@ -701,13 +749,13 @@ static const struct ad7879_platform_data
 	.x_plate_ohms		= 620,	/* 620 Ohm from the touch datasheet */
 	.pressure_max		= 10000,
 	.pressure_min		= 0,
-	.first_conversion_delay = 3,	/* wait 512us before do a first conversion */
-	.acquisition_time 	= 1,	/* 4us acquisition time per sample */
+	.first_conversion_delay	= 3,	/* wait 512us before do a first conversion */
+	.acquisition_time	= 1,	/* 4us acquisition time per sample */
 	.median			= 2,	/* do 8 measurements */
-	.averaging 		= 1,	/* take the average of 4 middle samples */
-	.pen_down_acc_interval 	= 255,	/* 9.4 ms */
-	.gpio_output		= 1,	/* configure AUX/VBAT/GPIO as GPIO output */
-	.gpio_default 		= 1,	/* During initialization set GPIO = HIGH */
+	.averaging		= 1,	/* take the average of 4 middle samples */
+	.pen_down_acc_interval	= 255,	/* 9.4 ms */
+	.gpio_export		= 1,	/* Export GPIO to gpiolib */
+	.gpio_base		= -1,	/* Dynamic allocation */
 };
 #endif
 
@@ -742,6 +790,11 @@ static const struct adxl34x_platform_dat
 /*	.ev_code_act_inactivity = KEY_A,*/	/* EV_KEY */
 	.power_mode = ADXL_AUTO_SLEEP | ADXL_LINK,
 	.fifo_mode = ADXL_FIFO_STREAM,
+	.orientation_enable = ADXL_EN_ORIENTATION_3D,
+	.deadzone_angle = ADXL_DEADZONE_ANGLE_10p8,
+	.divisor_length =  ADXL_LP_FILTER_DIVISOR_16,
+	/* EV_KEY {+Z, +Y, +X, -X, -Y, -Z} */
+	.ev_codes_orient_3d = {BTN_Z, BTN_Y, BTN_X, BTN_A, BTN_B, BTN_C},
 };
 #endif
 
@@ -813,6 +866,35 @@ static struct adf702x_platform_data adf7
 	.adf702x_regs = adf7021_regs,
 	.tx_reg = TXREG,
 };
+static inline void adf702x_mac_init(void)
+{
+	random_ether_addr(adf7021_platform_data.mac_addr);
+}
+#else
+static inline void adf702x_mac_init(void) {}
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+#include <linux/spi/ads7846.h>
+static struct bfin5xx_spi_chip ad7873_spi_chip_info = {
+	.bits_per_word	= 8,
+};
+
+static int ads7873_get_pendown_state(void)
+{
+	return gpio_get_value(GPIO_PF6);
+}
+
+static struct ads7846_platform_data __initdata ad7873_pdata = {
+	.model		= 7873,		/* AD7873 */
+	.x_max		= 0xfff,
+	.y_max		= 0xfff,
+	.x_plate_ohms	= 620,
+	.debounce_max	= 1,
+	.debounce_rep	= 0,
+	.debounce_tol	= (~0),
+	.get_pendown_state = ads7873_get_pendown_state,
+};
 #endif
 
 #if defined(CONFIG_MTD_DATAFLASH) \
@@ -893,24 +975,25 @@ static struct spi_board_info bfin_spi_bo
 	},
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
-	|| defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+	|| defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
 	{
-		.modalias = "ad1836",
+		.modalias = "ad183x",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
 		.chip_select = 4,/* CONFIG_SND_BLACKFIN_SPI_PFBIT */
+		.platform_data = "ad1836", /* only includes chip name for the moment */
 		.controller_data = &ad1836_spi_chip_info,
 		.mode = SPI_MODE_3,
 	},
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_AD1938) || defined(CONFIG_SND_BF5XX_SOC_AD1938_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD193X) || defined(CONFIG_SND_BF5XX_SOC_AD193X_MODULE)
 	{
-		.modalias = "ad1938",
+		.modalias = "ad193x",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
-		.chip_select = 0,/* CONFIG_SND_BLACKFIN_SPI_PFBIT */
+		.chip_select = 5,
 		.controller_data = &ad1938_spi_chip_info,
 		.mode = SPI_MODE_3,
 	},
@@ -929,6 +1012,37 @@ static struct spi_board_info bfin_spi_bo
 	},
 #endif
 
+#if defined(CONFIG_AD2S90) || defined(CONFIG_AD2S90_MODULE)
+	{
+		.modalias = "ad2s90",
+		.bus_num = 0,
+		.chip_select = 3,            /* change it for your board */
+		.platform_data = NULL,
+		.controller_data = &ad2s90_spi_chip_info,
+	},
+#endif
+
+#if defined(CONFIG_AD2S120X) || defined(CONFIG_AD2S120X_MODULE)
+	{
+		.modalias = "ad2s120x",
+		.bus_num = 0,
+		.chip_select = 4,            /* CS, change it for your board */
+		.platform_data = ad2s120x_platform_data,
+		.controller_data = &ad2s120x_spi_chip_info,
+	},
+#endif
+
+#if defined(CONFIG_AD2S1210) || defined(CONFIG_AD2S1210_MODULE)
+	{
+		.modalias = "ad2s1210",
+		.max_speed_hz = 8192000,
+		.bus_num = 0,
+		.chip_select = 4,            /* CS, change it for your board */
+		.platform_data = ad2s1210_platform_data,
+		.controller_data = &ad2s1210_spi_chip_info,
+	},
+#endif
+
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 	{
 		.modalias = "mmc_spi",
@@ -1016,7 +1130,18 @@ static struct spi_board_info bfin_spi_bo
 		.mode = SPI_MODE_0,
 	},
 #endif
-
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+	{
+		.modalias = "ads7846",
+		.max_speed_hz = 2000000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.irq = IRQ_PF6,
+		.chip_select = GPIO_PF10 + MAX_CTRL_CS,	/* GPIO controlled SSEL */
+		.controller_data = &ad7873_spi_chip_info,
+		.platform_data = &ad7873_pdata,
+		.mode = SPI_MODE_0,
+	},
+#endif
 };
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
@@ -1132,9 +1257,10 @@ static struct platform_device bfin_fb_de
 #include <asm/bfin-lq035q1.h>
 
 static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = {
-	.mode = 	LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
-	.use_bl = 	0,	/* let something else control the LCD Blacklight */
-	.gpio_bl =	GPIO_PF7,
+	.mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
+	.ppi_mode = USE_RGB565_16_BIT_PPI,
+	.use_bl = 0,	/* let something else control the LCD Blacklight */
+	.gpio_bl = GPIO_PF7,
 };
 
 static struct resource bfin_lq035q1_resources[] = {
@@ -1148,8 +1274,8 @@ static struct resource bfin_lq035q1_reso
 static struct platform_device bfin_lq035q1_device = {
 	.name		= "bfin-lq035q1",
 	.id		= -1,
-	.num_resources 	= ARRAY_SIZE(bfin_lq035q1_resources),
-	.resource 	= bfin_lq035q1_resources,
+	.num_resources	= ARRAY_SIZE(bfin_lq035q1_resources),
+	.resource	= bfin_lq035q1_resources,
 	.dev		= {
 		.platform_data = &bfin_lq035q1_data,
 	},
@@ -1157,30 +1283,105 @@ static struct platform_device bfin_lq035
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = UART0_THR,
+		.end = UART0_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+	{	/* CTS pin */
+		.start = GPIO_PG7,
+		.end = GPIO_PG7,
+		.flags = IORESOURCE_IO,
+	},
+	{	/* RTS pin */
+		.start = GPIO_PG6,
+		.end = GPIO_PG6,
+		.flags = IORESOURCE_IO,
+	},
+#endif
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
 	{
-		.start = 0xFFC02000,
-		.end = 0xFFC020FF,
+		.start = UART1_THR,
+		.end = UART1_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
-#endif
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART1_ERROR,
+		.end = IRQ_UART1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_TX,
+		.end = CH_UART1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart1_peripherals[] = {
+	P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
 	.name = "bfin-uart",
 	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.num_resources = ARRAY_SIZE(bfin_uart1_resources),
+	.resource = bfin_uart1_resources,
+	.dev = {
+		.platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -1260,7 +1461,6 @@ static struct platform_device i2c_bfin_t
 #endif
 
 #if defined(CONFIG_KEYBOARD_ADP5588) || defined(CONFIG_KEYBOARD_ADP5588_MODULE)
-#include <linux/i2c/adp5588.h>
 static const unsigned short adp5588_keymap[ADP5588_KEYMAPSIZE] = {
 	[0]	 = KEY_GRAVE,
 	[1]	 = KEY_1,
@@ -1457,7 +1657,6 @@ static struct adp5520_platform_data adp5
 #endif
 
 #if defined(CONFIG_GPIO_ADP5588) || defined(CONFIG_GPIO_ADP5588_MODULE)
-#include <linux/i2c/adp5588.h>
 static struct adp5588_gpio_platform_data adp5588_gpio_data = {
 	.gpio_start = 50,
 	.pullup_dis_mask = 0,
@@ -1516,6 +1715,101 @@ static struct adp8870_backlight_platform
 };
 #endif
 
+#if defined(CONFIG_BACKLIGHT_ADP8860) || defined(CONFIG_BACKLIGHT_ADP8860_MODULE)
+#include <linux/i2c/adp8860.h>
+static struct led_info adp8860_leds[] = {
+	{
+		.name = "adp8860-led7",
+		.default_trigger = "none",
+		.flags = ADP8860_LED_D7 | ADP8860_LED_OFFT_600ms,
+	},
+};
+
+static struct adp8860_backlight_platform_data adp8860_pdata = {
+	.bl_led_assign = ADP8860_BL_D1 | ADP8860_BL_D2 | ADP8860_BL_D3 |
+			 ADP8860_BL_D4 | ADP8860_BL_D5 | ADP8860_BL_D6,	/* 1 = Backlight 0 = Individual LED */
+
+	.bl_fade_in = ADP8860_FADE_T_1200ms,		/* Backlight Fade-In Timer */
+	.bl_fade_out = ADP8860_FADE_T_1200ms,		/* Backlight Fade-Out Timer */
+	.bl_fade_law = ADP8860_FADE_LAW_CUBIC1,		/* fade-on/fade-off transfer characteristic */
+
+	.en_ambl_sens = 1,				/* 1 = enable ambient light sensor */
+	.abml_filt = ADP8860_BL_AMBL_FILT_320ms,	/* Light sensor filter time */
+
+	.l1_daylight_max = ADP8860_BL_CUR_mA(20),	/* use BL_CUR_mA(I) 0 <= I <= 30 mA */
+	.l1_daylight_dim = ADP8860_BL_CUR_mA(0),	/* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
+	.l2_office_max = ADP8860_BL_CUR_mA(6),		/* use BL_CUR_mA(I) 0 <= I <= 30 mA */
+	.l2_office_dim = ADP8860_BL_CUR_mA(0),		/* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
+	.l3_dark_max = ADP8860_BL_CUR_mA(2),		/* use BL_CUR_mA(I) 0 <= I <= 30 mA */
+	.l3_dark_dim = ADP8860_BL_CUR_mA(0),		/* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
+
+	.l2_trip = ADP8860_L2_COMP_CURR_uA(710),	/* use L2_COMP_CURR_uA(I) 0 <= I <= 1106 uA */
+	.l2_hyst = ADP8860_L2_COMP_CURR_uA(73),		/* use L2_COMP_CURR_uA(I) 0 <= I <= 1106 uA */
+	.l3_trip = ADP8860_L3_COMP_CURR_uA(43),		/* use L3_COMP_CURR_uA(I) 0 <= I <= 138 uA */
+	.l3_hyst = ADP8860_L3_COMP_CURR_uA(11),		/* use L3_COMP_CURR_uA(I) 0 <= I <= 138 uA */
+
+	.leds = adp8860_leds,
+	.num_leds = ARRAY_SIZE(adp8860_leds),
+	.led_fade_law = ADP8860_FADE_LAW_SQUARE,	/* fade-on/fade-off transfer characteristic */
+	.led_fade_in = ADP8860_FADE_T_600ms,
+	.led_fade_out = ADP8860_FADE_T_600ms,
+	.led_on_time = ADP8860_LED_ONT_200ms,
+};
+#endif
+
+#if defined(CONFIG_REGULATOR_AD5398) || defined(CONFIG_REGULATOR_AD5398_MODULE)
+static struct regulator_consumer_supply ad5398_consumer = {
+	.supply = "current",
+};
+
+static struct regulator_init_data ad5398_regulator_data = {
+	.constraints = {
+		.name = "current range",
+		.max_uA = 120000,
+		.valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies = 1,
+	.consumer_supplies     = &ad5398_consumer,
+};
+
+static struct ad5398_platform_data ad5398_i2c_platform_data = {
+	.current_bits = 10,
+	.current_offset = 4,
+	.regulator_data = &ad5398_regulator_data,
+};
+
+#if defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER) || \
+	defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER_MODULE)
+static struct platform_device ad5398_virt_consumer_device = {
+	.name = "reg-virt-consumer",
+	.id = 0,
+	.dev = {
+		.platform_data = "current", /* Passed to driver */
+	},
+};
+#endif
+#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \
+	defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE)
+static struct regulator_bulk_data ad5398_bulk_data = {
+	.supply = "current",
+};
+
+static struct regulator_userspace_consumer_data ad5398_userspace_comsumer_data = {
+	.name = "ad5398",
+	.num_supplies = 1,
+	.supplies = &ad5398_bulk_data,
+};
+
+static struct platform_device ad5398_userspace_consumer_device = {
+	.name = "reg-userspace-consumer",
+	.id = 0,
+	.dev = {
+		.platform_data = &ad5398_userspace_comsumer_data,
+	},
+};
+#endif
+#endif
+
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #if defined(CONFIG_INPUT_AD714X_I2C) || defined(CONFIG_INPUT_AD714X_I2C_MODULE)
 	{
@@ -1524,6 +1818,52 @@ static struct i2c_board_info __initdata
 		.platform_data = (void *)&ad7142_i2c_platform_data,
 	},
 #endif
+
+#if defined(CONFIG_AD7150) || defined(CONFIG_AD7150_MODULE)
+	{
+		I2C_BOARD_INFO("ad7150", 0x48),
+		.irq = IRQ_PG5, /* fixme: use real interrupt number */
+	},
+#endif
+
+#if defined(CONFIG_AD7152) || defined(CONFIG_AD7152_MODULE)
+	{
+		I2C_BOARD_INFO("ad7152", 0x48),
+	},
+#endif
+
+#if defined(CONFIG_AD774X) || defined(CONFIG_AD774X_MODULE)
+	{
+		I2C_BOARD_INFO("ad774x", 0x48),
+	},
+#endif
+
+#if defined(CONFIG_AD7414) || defined(CONFIG_AD7414_MODULE)
+	{
+		I2C_BOARD_INFO("ad7414", 0x9),
+		.irq = IRQ_PG5,
+		/*
+		 * platform_data pointer is borrwoed by the driver to
+		 * store custimer defined IRQ ALART level mode.
+		 * only IRQF_TRIGGER_HIGH and IRQF_TRIGGER_LOW are valid.
+		 */
+		.platform_data = (void *)IRQF_TRIGGER_LOW,
+	},
+#endif
+
+#if defined(CONFIG_AD7416) || defined(CONFIG_AD7416_MODULE)
+	{
+		I2C_BOARD_INFO("ad7417", 0xb),
+		.irq = IRQ_PG5,
+		/*
+		 * platform_data pointer is borrwoed by the driver to
+		 * store custimer defined IRQ ALART level mode.
+		 * only IRQF_TRIGGER_HIGH and IRQF_TRIGGER_LOW are valid.
+		 */
+		.platform_data = (void *)IRQF_TRIGGER_LOW,
+	},
+#endif
+
 #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
 	{
 		I2C_BOARD_INFO("pcf8574_lcd", 0x22),
@@ -1595,24 +1935,105 @@ static struct i2c_board_info __initdata
 		I2C_BOARD_INFO("adau1761", 0x38),
 	},
 #endif
+#if defined(CONFIG_SND_SOC_ADAU1361) || defined(CONFIG_SND_SOC_ADAU1361_MODULE)
+	{
+		I2C_BOARD_INFO("adau1361", 0x38),
+	},
+#endif
 #if defined(CONFIG_AD525X_DPOT) || defined(CONFIG_AD525X_DPOT_MODULE)
 	{
 		I2C_BOARD_INFO("ad5258", 0x18),
 	},
 #endif
+#if defined(CONFIG_SND_SOC_SSM2602) || defined(CONFIG_SND_SOC_SSM2602_MODULE)
+	{
+		I2C_BOARD_INFO("ssm2602", 0x1b),
+	},
+#endif
+#if defined(CONFIG_REGULATOR_AD5398) || defined(CONFIG_REGULATOR_AD5398_MODULE)
+	{
+		I2C_BOARD_INFO("ad5398", 0xC),
+		.platform_data = (void *)&ad5398_i2c_platform_data,
+	},
+#endif
+#if defined(CONFIG_BACKLIGHT_ADP8860) || defined(CONFIG_BACKLIGHT_ADP8860_MODULE)
+	{
+		I2C_BOARD_INFO("adp8860", 0x2A),
+		.platform_data = (void *)&adp8860_pdata,
+	},
+#endif
 };
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
 #define CF_IDE_NAND_CARD_USE_HDD_INTERFACE
@@ -1701,13 +2122,121 @@ static struct platform_device bfin_dpmc
 	},
 };
 
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+	.name = "bfin-i2s",
+	.id = CONFIG_SND_BF5XX_SPORT_NUM,
+	/* TODO: add platform data here */
+};
+#endif
+
 #if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
 static struct platform_device bfin_tdm = {
 	.name = "bfin-tdm",
+	.id = CONFIG_SND_BF5XX_SPORT_NUM,
 	/* TODO: add platform data here */
 };
 #endif
 
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+static struct platform_device bfin_ac97 = {
+	.name = "bfin-ac97",
+	.id = CONFIG_SND_BF5XX_SPORT_NUM,
+	/* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_REGULATOR_ADP_SWITCH) || defined(CONFIG_REGULATOR_ADP_SWITCH_MODULE)
+#define REGULATOR_ADP122        "adp122"
+#define REGULATOR_ADP150        "adp150"
+
+static struct regulator_consumer_supply adp122_consumers = {
+		.supply = REGULATOR_ADP122,
+};
+
+static struct regulator_consumer_supply adp150_consumers = {
+		.supply = REGULATOR_ADP150,
+};
+
+static struct regulator_init_data adp_switch_regulator_data[] = {
+	{
+		.constraints = {
+			.name = REGULATOR_ADP122,
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+			.min_uA = 0,
+			.max_uA = 300000,
+		},
+		.num_consumer_supplies = 1,	/* only 1 */
+		.consumer_supplies     = &adp122_consumers,
+		.driver_data	       = (void *)GPIO_PF2, /* gpio port only */
+	},
+	{
+		.constraints = {
+			.name = REGULATOR_ADP150,
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+			.min_uA = 0,
+			.max_uA = 150000,
+		},
+		.num_consumer_supplies = 1,	/* only 1 */
+		.consumer_supplies     = &adp150_consumers,
+		.driver_data	       = (void *)GPIO_PF3, /* gpio port only */
+	},
+};
+
+static struct adp_switch_platform_data adp_switch_pdata = {
+	.regulator_num = ARRAY_SIZE(adp_switch_regulator_data),
+	.regulator_data = adp_switch_regulator_data,
+};
+
+static struct platform_device adp_switch_device = {
+	.name = "adp_switch",
+	.id = 0,
+	.dev = {
+		.platform_data = &adp_switch_pdata,
+	},
+};
+
+#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \
+	defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE)
+static struct regulator_bulk_data adp122_bulk_data = {
+	.supply = REGULATOR_ADP122,
+};
+
+static struct regulator_userspace_consumer_data adp122_userspace_comsumer_data = {
+	.name = REGULATOR_ADP122,
+	.num_supplies = 1,
+	.supplies = &adp122_bulk_data,
+};
+
+static struct platform_device adp122_userspace_consumer_device = {
+	.name = "reg-userspace-consumer",
+	.id = 0,
+	.dev = {
+		.platform_data = &adp122_userspace_comsumer_data,
+	},
+};
+
+static struct regulator_bulk_data adp150_bulk_data = {
+	.supply = REGULATOR_ADP150,
+};
+
+static struct regulator_userspace_consumer_data adp150_userspace_comsumer_data = {
+	.name = REGULATOR_ADP150,
+	.num_supplies = 1,
+	.supplies = &adp150_bulk_data,
+};
+
+static struct platform_device adp150_userspace_consumer_device = {
+	.name = "reg-userspace-consumer",
+	.id = 1,
+	.dev = {
+		.platform_data = &adp150_userspace_comsumer_data,
+	},
+};
+#endif
+#endif
+
+
 static struct platform_device *stamp_devices[] __initdata = {
 
 	&bfin_dpmc,
@@ -1771,7 +2300,12 @@ static struct platform_device *stamp_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -1788,9 +2322,13 @@ static struct platform_device *stamp_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
 	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
 	&bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
 	&bfin_pata_device,
@@ -1808,18 +2346,46 @@ static struct platform_device *stamp_dev
 	&stamp_flash_device,
 #endif
 
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+	&bfin_i2s,
+#endif
+
 #if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
 	&bfin_tdm,
 #endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+	&bfin_ac97,
+#endif
+#if defined(CONFIG_REGULATOR_AD5398) || defined(CONFIG_REGULATOR_AD5398_MODULE)
+#if defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER) || \
+	defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER_MODULE)
+	&ad5398_virt_consumer_device,
+#endif
+#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \
+	defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE)
+	&ad5398_userspace_consumer_device,
+#endif
+#endif
+
+#if defined(CONFIG_REGULATOR_ADP_SWITCH) || defined(CONFIG_REGULATOR_ADP_SWITCH_MODULE)
+	&adp_switch_device,
+#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \
+	defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE)
+	&adp122_userspace_consumer_device,
+	&adp150_userspace_consumer_device,
+#endif
+#endif
 };
 
 static int __init stamp_init(void)
 {
 	printk(KERN_INFO "%s(): registering device resources\n", __func__);
-	i2c_register_board_info(0, bfin_i2c_board_info,
-				ARRAY_SIZE(bfin_i2c_board_info));
 	bfin_plat_nand_init();
+	adf702x_mac_init();
 	platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+	i2c_register_board_info(0, bfin_i2c_board_info,
+				ARRAY_SIZE(bfin_i2c_board_info));
 	spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
 
 	return 0;
@@ -1827,6 +2393,34 @@ static int __init stamp_init(void)
 
 arch_initcall(stamp_init);
 
+
+static struct platform_device *stamp_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(stamp_early_devices,
+		ARRAY_SIZE(stamp_early_devices));
+}
+
 void native_machine_restart(char *cmd)
 {
 	/* workaround reboot hang when booting from SPI */
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/tcm_bf537.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/boards/tcm_bf537.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/tcm_bf537.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/boards/tcm_bf537.c	2010-05-16 17:17:36.000000000 -0400
@@ -74,7 +74,7 @@ static struct bfin5xx_spi_chip spi_adc_c
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
@@ -113,7 +113,7 @@ static struct spi_board_info bfin_spi_bo
 	},
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 	{
 		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -327,25 +327,93 @@ static struct platform_device cm_flash_d
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = UART0_THR,
+		.end = UART0_GCTL+2,
 		.flags = IORESOURCE_MEM,
-	}, {
-		.start = 0xFFC02000,
-		.end = 0xFFC020FF,
+	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+	{
+		.start = UART1_THR,
+		.end = UART1_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART1_ERROR,
+		.end = IRQ_UART1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_TX,
+		.end = CH_UART1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart1_peripherals[] = {
+	P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
 	.name = "bfin-uart",
 	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.num_resources = ARRAY_SIZE(bfin_uart1_resources),
+	.resource = bfin_uart1_resources,
+	.dev = {
+		.platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -425,16 +493,75 @@ static struct platform_device i2c_bfin_t
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
@@ -524,7 +651,12 @@ static struct platform_device *cm_bf537_
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -541,9 +673,13 @@ static struct platform_device *cm_bf537_
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
 	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
 	&bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 	&isp1362_hcd_device,
@@ -591,6 +727,33 @@ static int __init tcm_bf537_init(void)
 
 arch_initcall(tcm_bf537_init);
 
+static struct platform_device *cm_bf537_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(cm_bf537_early_devices,
+		ARRAY_SIZE(cm_bf537_early_devices));
+}
+
 void bfin_get_ether_addr(char *addr)
 {
 	random_ether_addr(addr);
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/include/mach/irq.h linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/include/mach/irq.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/include/mach/irq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/include/mach/irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -134,7 +134,17 @@
 
 #define GPIO_IRQ_BASE	IRQ_PF0
 
-#define NR_IRQS     (IRQ_PH15+1)
+#define IRQ_MAC_PHYINT		98 /* PHY_INT Interrupt */
+#define IRQ_MAC_MMCINT		99 /* MMC Counter Interrupt */
+#define IRQ_MAC_RXFSINT		100 /* RX Frame-Status Interrupt */
+#define IRQ_MAC_TXFSINT		101 /* TX Frame-Status Interrupt */
+#define IRQ_MAC_WAKEDET		102 /* Wake-Up Interrupt */
+#define IRQ_MAC_RXDMAERR	103 /* RX DMA Direction Error Interrupt */
+#define IRQ_MAC_TXDMAERR	104 /* TX DMA Direction Error Interrupt */
+#define IRQ_MAC_STMDONE		105 /* Station Mgt. Transfer Done Interrupt */
+
+#define NR_MACH_IRQS	(IRQ_MAC_STMDONE + 1)
+#define NR_IRQS		(NR_MACH_IRQS + NR_SPARE_IRQS)
 
 #define IVG7            7
 #define IVG8            8
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/boards/ezkit.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf538/boards/ezkit.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/boards/ezkit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf538/boards/ezkit.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,37 +41,148 @@ static struct platform_device rtc_device
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = UART0_THR,
+		.end = UART0_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+	{	/* CTS pin */
+		.start = GPIO_PG7,
+		.end = GPIO_PG7,
+		.flags = IORESOURCE_IO,
+	},
+	{	/* RTS pin */
+		.start = GPIO_PG6,
+		.end = GPIO_PG6,
+		.flags = IORESOURCE_IO,
+	},
+#endif
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
 	{
-		.start = 0xFFC02000,
-		.end = 0xFFC020FF,
+		.start = UART1_THR,
+		.end = UART1_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART1_ERROR,
+		.end = IRQ_UART1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_TX,
+		.end = CH_UART1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+	P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
+	.name = "bfin-uart",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_uart1_resources),
+	.resource = bfin_uart1_resources,
+	.dev = {
+		.platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+	},
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART2
+static struct resource bfin_uart2_resources[] = {
 	{
-		.start = 0xFFC02100,
-		.end = 0xFFC021FF,
+		.start = UART2_THR,
+		.end = UART2_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
-#endif
+	{
+		.start = IRQ_UART2_RX,
+		.end = IRQ_UART2_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART2_ERROR,
+		.end = IRQ_UART2_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART2_TX,
+		.end = CH_UART2_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART2_RX,
+		.end = CH_UART2_RX,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart2_peripherals[] = {
+	P_UART2_TX, P_UART2_RX, 0
+};
+
+static struct platform_device bfin_uart2_device = {
 	.name = "bfin-uart",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.id = 2,
+	.num_resources = ARRAY_SIZE(bfin_uart2_resources),
+	.resource = bfin_uart2_resources,
+	.dev = {
+		.platform_data = &bfin_uart2_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -151,6 +262,145 @@ static struct platform_device bfin_sir2_
 #endif
 #endif
 
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
+static struct platform_device bfin_sport0_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+static struct resource bfin_sport2_uart_resources[] = {
+	{
+		.start = SPORT2_TCR1,
+		.end = SPORT2_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT2_RX,
+		.end = IRQ_SPORT2_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT2_ERROR,
+		.end = IRQ_SPORT2_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport2_peripherals[] = {
+	P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS,
+	P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0
+};
+
+static struct platform_device bfin_sport2_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 2,
+	.num_resources = ARRAY_SIZE(bfin_sport2_uart_resources),
+	.resource = bfin_sport2_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport2_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+static struct resource bfin_sport3_uart_resources[] = {
+	{
+		.start = SPORT3_TCR1,
+		.end = SPORT3_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT3_RX,
+		.end = IRQ_SPORT3_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT3_ERROR,
+		.end = IRQ_SPORT3_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport3_peripherals[] = {
+	P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS,
+	P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0
+};
+
+static struct platform_device bfin_sport3_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 3,
+	.num_resources = ARRAY_SIZE(bfin_sport3_uart_resources),
+	.resource = bfin_sport3_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport3_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#endif
+
 #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
 unsigned short bfin_can_peripherals[] = {
 	P_CAN0_RX, P_CAN0_TX, 0
@@ -268,8 +518,8 @@ static const struct ad7879_platform_data
 	.median			= 2,	/* do 8 measurements */
 	.averaging 		= 1,	/* take the average of 4 middle samples */
 	.pen_down_acc_interval 	= 255,	/* 9.4 ms */
-	.gpio_output		= 1,	/* configure AUX/VBAT/GPIO as GPIO output */
-	.gpio_default 		= 1,	/* During initialization set GPIO = HIGH */
+	.gpio_export		= 1,	/* Export GPIO to gpiolib */
+	.gpio_base		= -1,	/* Dynamic allocation */
 };
 #endif
 
@@ -284,9 +534,10 @@ static struct bfin5xx_spi_chip spi_ad787
 #include <asm/bfin-lq035q1.h>
 
 static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = {
-	.mode = 	LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
-	.use_bl = 	0,	/* let something else control the LCD Blacklight */
-	.gpio_bl =	GPIO_PF7,
+	.mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
+	.ppi_mode = USE_RGB565_16_BIT_PPI,
+	.use_bl = 0,	/* let something else control the LCD Blacklight */
+	.gpio_bl = GPIO_PF7,
 };
 
 static struct resource bfin_lq035q1_resources[] = {
@@ -622,7 +873,15 @@ static struct platform_device *cm_bf538_
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+	&bfin_uart2_device,
+#endif
 #endif
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
@@ -648,6 +907,21 @@ static struct platform_device *cm_bf538_
 #endif
 #endif
 
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+	&bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+	&bfin_sport3_uart_device,
+#endif
+#endif
+
 #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
 	&bfin_can_device,
 #endif
@@ -683,3 +957,39 @@ static int __init ezkit_init(void)
 }
 
 arch_initcall(ezkit_init);
+
+static struct platform_device *ezkit_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+	&bfin_uart2_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+	&bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+	&bfin_sport3_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(ezkit_early_devices,
+		ARRAY_SIZE(ezkit_early_devices));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/include/mach/irq.h linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf538/include/mach/irq.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/include/mach/irq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf538/include/mach/irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -110,7 +110,8 @@
 
 #define GPIO_IRQ_BASE	IRQ_PF0
 
-#define NR_IRQS     (IRQ_PF15+1)
+#define NR_MACH_IRQS	(IRQ_PF15 + 1)
+#define NR_IRQS		(NR_MACH_IRQS + NR_SPARE_IRQS)
 
 #define IVG7            7
 #define IVG8            8
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/boards/cm_bf548.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf548/boards/cm_bf548.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/boards/cm_bf548.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf548/boards/cm_bf548.c	2010-05-16 17:17:36.000000000 -0400
@@ -127,44 +127,211 @@ static struct platform_device rtc_device
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = UART0_DLL,
+		.end = UART0_RBR+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
 	{
-		.start = 0xFFC02000,
-		.end = 0xFFC020FF,
+		.start = UART1_DLL,
+		.end = UART1_RBR+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART1_ERROR,
+		.end = IRQ_UART1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_TX,
+		.end = CH_UART1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX,
+		.flags = IORESOURCE_DMA,
+	},
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+	{	/* CTS pin -- 0 means not supported */
+		.start = GPIO_PE10,
+		.end = GPIO_PE10,
+		.flags = IORESOURCE_IO,
+	},
+	{	/* RTS pin -- 0 means not supported */
+		.start = GPIO_PE9,
+		.end = GPIO_PE9,
+		.flags = IORESOURCE_IO,
+	},
+#endif
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+	P_UART1_TX, P_UART1_RX,
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+	P_UART1_RTS, P_UART1_CTS,
+#endif
+	0
+};
+
+static struct platform_device bfin_uart1_device = {
+	.name = "bfin-uart",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_uart1_resources),
+	.resource = bfin_uart1_resources,
+	.dev = {
+		.platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+	},
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART2
+static struct resource bfin_uart2_resources[] = {
 	{
-		.start = 0xFFC02100,
-		.end = 0xFFC021FF,
+		.start = UART2_DLL,
+		.end = UART2_RBR+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART2_RX,
+		.end = IRQ_UART2_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART2_ERROR,
+		.end = IRQ_UART2_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART2_TX,
+		.end = CH_UART2_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART2_RX,
+		.end = CH_UART2_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart2_peripherals[] = {
+	P_UART2_TX, P_UART2_RX, 0
+};
+
+static struct platform_device bfin_uart2_device = {
+	.name = "bfin-uart",
+	.id = 2,
+	.num_resources = ARRAY_SIZE(bfin_uart2_resources),
+	.resource = bfin_uart2_resources,
+	.dev = {
+		.platform_data = &bfin_uart2_peripherals, /* Passed to driver */
+	},
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART3
+static struct resource bfin_uart3_resources[] = {
 	{
-		.start = 0xFFC03100,
-		.end = 0xFFC031FF,
+		.start = UART3_DLL,
+		.end = UART3_RBR+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART3_RX,
+		.end = IRQ_UART3_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART3_ERROR,
+		.end = IRQ_UART3_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART3_TX,
+		.end = CH_UART3_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART3_RX,
+		.end = CH_UART3_RX,
+		.flags = IORESOURCE_DMA,
+	},
+#ifdef CONFIG_BFIN_UART3_CTSRTS
+	{	/* CTS pin -- 0 means not supported */
+		.start = GPIO_PB3,
+		.end = GPIO_PB3,
+		.flags = IORESOURCE_IO,
+	},
+	{	/* RTS pin -- 0 means not supported */
+		.start = GPIO_PB2,
+		.end = GPIO_PB2,
+		.flags = IORESOURCE_IO,
+	},
 #endif
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart3_peripherals[] = {
+	P_UART3_TX, P_UART3_RX,
+#ifdef CONFIG_BFIN_UART3_CTSRTS
+	P_UART3_RTS, P_UART3_CTS,
+#endif
+	0
+};
+
+static struct platform_device bfin_uart3_device = {
 	.name = "bfin-uart",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.id = 3,
+	.num_resources = ARRAY_SIZE(bfin_uart3_resources),
+	.resource = bfin_uart3_resources,
+	.dev = {
+		.platform_data = &bfin_uart3_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -359,6 +526,145 @@ static struct platform_device musb_devic
 };
 #endif
 
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
+static struct platform_device bfin_sport0_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+static struct resource bfin_sport2_uart_resources[] = {
+	{
+		.start = SPORT2_TCR1,
+		.end = SPORT2_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT2_RX,
+		.end = IRQ_SPORT2_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT2_ERROR,
+		.end = IRQ_SPORT2_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport2_peripherals[] = {
+	P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS,
+	P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0
+};
+
+static struct platform_device bfin_sport2_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 2,
+	.num_resources = ARRAY_SIZE(bfin_sport2_uart_resources),
+	.resource = bfin_sport2_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport2_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+static struct resource bfin_sport3_uart_resources[] = {
+	{
+		.start = SPORT3_TCR1,
+		.end = SPORT3_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT3_RX,
+		.end = IRQ_SPORT3_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT3_ERROR,
+		.end = IRQ_SPORT3_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport3_peripherals[] = {
+	P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS,
+	P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0
+};
+
+static struct platform_device bfin_sport3_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 3,
+	.num_resources = ARRAY_SIZE(bfin_sport3_uart_resources),
+	.resource = bfin_sport3_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport3_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#endif
+
 #if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE)
 static struct resource bfin_atapi_resources[] = {
 	{
@@ -752,7 +1058,18 @@ static struct platform_device *cm_bf548_
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+	&bfin_uart2_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+	&bfin_uart3_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -782,6 +1099,21 @@ static struct platform_device *cm_bf548_
 	&musb_device,
 #endif
 
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+	&bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+	&bfin_sport3_uart_device,
+#endif
+#endif
+
 #if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE)
 	&bfin_atapi_device,
 #endif
@@ -833,3 +1165,42 @@ static int __init cm_bf548_init(void)
 }
 
 arch_initcall(cm_bf548_init);
+
+static struct platform_device *cm_bf548_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+	&bfin_uart2_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+	&bfin_uart3_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+	&bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+	&bfin_sport3_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(cm_bf548_early_devices,
+		ARRAY_SIZE(cm_bf548_early_devices));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/boards/ezkit.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf548/boards/ezkit.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/boards/ezkit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf548/boards/ezkit.c	2010-05-16 17:17:36.000000000 -0400
@@ -232,44 +232,211 @@ static struct platform_device rtc_device
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = UART0_DLL,
+		.end = UART0_RBR+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
 	{
-		.start = 0xFFC02000,
-		.end = 0xFFC020FF,
+		.start = UART1_DLL,
+		.end = UART1_RBR+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART1_ERROR,
+		.end = IRQ_UART1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_TX,
+		.end = CH_UART1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX,
+		.flags = IORESOURCE_DMA,
+	},
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+	{	/* CTS pin -- 0 means not supported */
+		.start = GPIO_PE10,
+		.end = GPIO_PE10,
+		.flags = IORESOURCE_IO,
+	},
+	{	/* RTS pin -- 0 means not supported */
+		.start = GPIO_PE9,
+		.end = GPIO_PE9,
+		.flags = IORESOURCE_IO,
+	},
+#endif
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+	P_UART1_TX, P_UART1_RX,
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+	P_UART1_RTS, P_UART1_CTS,
+#endif
+	0
+};
+
+static struct platform_device bfin_uart1_device = {
+	.name = "bfin-uart",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_uart1_resources),
+	.resource = bfin_uart1_resources,
+	.dev = {
+		.platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+	},
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART2
+static struct resource bfin_uart2_resources[] = {
 	{
-		.start = 0xFFC02100,
-		.end = 0xFFC021FF,
+		.start = UART2_DLL,
+		.end = UART2_RBR+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART2_RX,
+		.end = IRQ_UART2_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART2_ERROR,
+		.end = IRQ_UART2_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART2_TX,
+		.end = CH_UART2_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART2_RX,
+		.end = CH_UART2_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart2_peripherals[] = {
+	P_UART2_TX, P_UART2_RX, 0
+};
+
+static struct platform_device bfin_uart2_device = {
+	.name = "bfin-uart",
+	.id = 2,
+	.num_resources = ARRAY_SIZE(bfin_uart2_resources),
+	.resource = bfin_uart2_resources,
+	.dev = {
+		.platform_data = &bfin_uart2_peripherals, /* Passed to driver */
+	},
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART3
+static struct resource bfin_uart3_resources[] = {
 	{
-		.start = 0xFFC03100,
-		.end = 0xFFC031FF,
+		.start = UART3_DLL,
+		.end = UART3_RBR+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART3_RX,
+		.end = IRQ_UART3_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART3_ERROR,
+		.end = IRQ_UART3_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART3_TX,
+		.end = CH_UART3_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART3_RX,
+		.end = CH_UART3_RX,
+		.flags = IORESOURCE_DMA,
+	},
+#ifdef CONFIG_BFIN_UART3_CTSRTS
+	{	/* CTS pin -- 0 means not supported */
+		.start = GPIO_PB3,
+		.end = GPIO_PB3,
+		.flags = IORESOURCE_IO,
+	},
+	{	/* RTS pin -- 0 means not supported */
+		.start = GPIO_PB2,
+		.end = GPIO_PB2,
+		.flags = IORESOURCE_IO,
+	},
 #endif
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart3_peripherals[] = {
+	P_UART3_TX, P_UART3_RX,
+#ifdef CONFIG_BFIN_UART3_CTSRTS
+	P_UART3_RTS, P_UART3_CTS,
+#endif
+	0
+};
+
+static struct platform_device bfin_uart3_device = {
 	.name = "bfin-uart",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.id = 3,
+	.num_resources = ARRAY_SIZE(bfin_uart3_resources),
+	.resource = bfin_uart3_resources,
+	.dev = {
+		.platform_data = &bfin_uart3_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -464,6 +631,145 @@ static struct platform_device musb_devic
 };
 #endif
 
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
+static struct platform_device bfin_sport0_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+	.resource = bfin_sport0_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+	{
+		.start = SPORT1_TCR1,
+		.end = SPORT1_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT1_RX,
+		.end = IRQ_SPORT1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT1_ERROR,
+		.end = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+	P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+	.resource = bfin_sport1_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+static struct resource bfin_sport2_uart_resources[] = {
+	{
+		.start = SPORT2_TCR1,
+		.end = SPORT2_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT2_RX,
+		.end = IRQ_SPORT2_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT2_ERROR,
+		.end = IRQ_SPORT2_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport2_peripherals[] = {
+	P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS,
+	P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0
+};
+
+static struct platform_device bfin_sport2_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 2,
+	.num_resources = ARRAY_SIZE(bfin_sport2_uart_resources),
+	.resource = bfin_sport2_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport2_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+static struct resource bfin_sport3_uart_resources[] = {
+	{
+		.start = SPORT3_TCR1,
+		.end = SPORT3_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT3_RX,
+		.end = IRQ_SPORT3_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT3_ERROR,
+		.end = IRQ_SPORT3_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+unsigned short bfin_sport3_peripherals[] = {
+	P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS,
+	P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0
+};
+
+static struct platform_device bfin_sport3_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 3,
+	.num_resources = ARRAY_SIZE(bfin_sport3_uart_resources),
+	.resource = bfin_sport3_uart_resources,
+	.dev = {
+		.platform_data = &bfin_sport3_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#endif
+
 #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
 unsigned short bfin_can_peripherals[] = {
 	P_CAN0_RX, P_CAN0_TX, 0
@@ -657,8 +963,8 @@ static struct bfin5xx_spi_chip spi_flash
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+	|| defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
@@ -714,8 +1020,8 @@ static struct spi_board_info bfin_spi_bo
 		.mode = SPI_MODE_3,
 	},
 #endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+	|| defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 	{
 		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -951,6 +1257,30 @@ static struct platform_device bfin_dpmc
 	},
 };
 
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+	.name = "bfin-i2s",
+	.id = CONFIG_SND_BF5XX_SPORT_NUM,
+	/* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+	.name = "bfin-tdm",
+	.id = CONFIG_SND_BF5XX_SPORT_NUM,
+	/* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+static struct platform_device bfin_ac97 = {
+	.name = "bfin-ac97",
+	.id = CONFIG_SND_BF5XX_SPORT_NUM,
+	/* TODO: add platform data here */
+};
+#endif
+
 static struct platform_device *ezkit_devices[] __initdata = {
 
 	&bfin_dpmc,
@@ -960,7 +1290,18 @@ static struct platform_device *ezkit_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+	&bfin_uart2_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+	&bfin_uart3_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -994,6 +1335,21 @@ static struct platform_device *ezkit_dev
 	&bfin_isp1760_device,
 #endif
 
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+	&bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+	&bfin_sport3_uart_device,
+#endif
+#endif
+
 #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
 	&bfin_can_device,
 #endif
@@ -1037,6 +1393,18 @@ static struct platform_device *ezkit_dev
 #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
 	&ezkit_flash_device,
 #endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+	&bfin_i2s,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+	&bfin_tdm,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+	&bfin_ac97,
+#endif
 };
 
 static int __init ezkit_init(void)
@@ -1058,3 +1426,42 @@ static int __init ezkit_init(void)
 }
 
 arch_initcall(ezkit_init);
+
+static struct platform_device *ezkit_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+	&bfin_uart2_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+	&bfin_uart3_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+	&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+	&bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+	&bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+	&bfin_sport3_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(ezkit_early_devices,
+		ARRAY_SIZE(ezkit_early_devices));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/irq.h linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf548/include/mach/irq.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/irq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf548/include/mach/irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -317,7 +317,8 @@ Events         (highest priority)  EMU
 
 #define GPIO_IRQ_BASE	IRQ_PA0
 
-#define NR_IRQS     (IRQ_PJ15+1)
+#define NR_MACH_IRQS	(IRQ_PJ15 + 1)
+#define NR_IRQS		(NR_MACH_IRQS + NR_SPARE_IRQS)
 
 /* For compatibility reasons with existing code */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/acvilon.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/boards/acvilon.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/acvilon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/boards/acvilon.c	2010-05-16 17:17:36.000000000 -0400
@@ -176,7 +176,7 @@ static struct resource smsc911x_resource
 };
 
 static struct smsc911x_platform_config smsc911x_config = {
-	.flags = SMSC911X_USE_32BIT,
+	.flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
 	.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
 	.irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
 	.phy_interface = PHY_INTERFACE_MODE_MII,
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/cm_bf561.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/boards/cm_bf561.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/cm_bf561.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/boards/cm_bf561.c	2010-05-16 17:17:36.000000000 -0400
@@ -72,7 +72,7 @@ static struct bfin5xx_spi_chip spi_adc_c
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
@@ -111,7 +111,7 @@ static struct spi_board_info bfin_spi_bo
 	},
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 	{
 		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -305,21 +305,50 @@ static struct platform_device isp1362_hc
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = BFIN_UART_THR,
+		.end = BFIN_UART_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART_RX,
+		.end = IRQ_UART_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART_ERROR,
+		.end = IRQ_UART_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART_TX,
+		.end = CH_UART_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART_RX,
+		.end = CH_UART_RX,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
 	.name = "bfin-uart",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -463,7 +492,9 @@ static struct platform_device *cm_bf561_
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -516,3 +547,18 @@ static int __init cm_bf561_init(void)
 }
 
 arch_initcall(cm_bf561_init);
+
+static struct platform_device *cm_bf561_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(cm_bf561_early_devices,
+		ARRAY_SIZE(cm_bf561_early_devices));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/ezkit.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/boards/ezkit.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/ezkit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/boards/ezkit.c	2010-05-16 17:17:36.000000000 -0400
@@ -160,21 +160,50 @@ static struct platform_device smc91x_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
 	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
+		.start = BFIN_UART_THR,
+		.end = BFIN_UART_GCTL+2,
 		.flags = IORESOURCE_MEM,
 	},
+	{
+		.start = IRQ_UART_RX,
+		.end = IRQ_UART_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART_ERROR,
+		.end = IRQ_UART_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART_TX,
+		.end = CH_UART_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART_RX,
+		.end = CH_UART_RX,
+		.flags = IORESOURCE_DMA,
+	},
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
 	.name = "bfin-uart",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -245,8 +274,8 @@ static struct platform_device ezkit_flas
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+	|| defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
@@ -299,8 +328,8 @@ static struct platform_device bfin_spi0_
 #endif
 
 static struct spi_board_info bfin_spi_board_info[] __initdata = {
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+	|| defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 	{
 		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -412,7 +441,9 @@ static struct platform_device *ezkit_dev
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -458,3 +489,18 @@ static int __init ezkit_init(void)
 }
 
 arch_initcall(ezkit_init);
+
+static struct platform_device *ezkit_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(ezkit_early_devices,
+		ARRAY_SIZE(ezkit_early_devices));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/tepla.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/boards/tepla.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/tepla.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/boards/tepla.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,52 @@ static struct platform_device smc91x_dev
 	.resource      = smc91x_resources,
 };
 
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
+	{
+		.start = BFIN_UART_THR,
+		.end = BFIN_UART_GCTL+2,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_UART_RX,
+		.end = IRQ_UART_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART_ERROR,
+		.end = IRQ_UART_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART_TX,
+		.end = CH_UART_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART_RX,
+		.end = CH_UART_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+	},
+};
+#endif
+#endif
+
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
 static struct resource bfin_sir0_resources[] = {
@@ -73,6 +119,13 @@ static struct platform_device bfin_sir0_
 
 static struct platform_device *tepla_devices[] __initdata = {
 	&smc91x_device,
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#endif
+
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
 	&bfin_sir0_device,
@@ -87,3 +140,18 @@ static int __init tepla_init(void)
 }
 
 arch_initcall(tepla_init);
+
+static struct platform_device *tepla_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(tepla_early_devices,
+		ARRAY_SIZE(tepla_early_devices));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/hotplug.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/hotplug.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/hotplug.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/hotplug.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2007-2009 Analog Devices Inc.
+ *               Graff Yang <graf.yang@analog.com>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <asm/blackfin.h>
+#include <asm/smp.h>
+#define SIC_SYSIRQ(irq)	(irq - (IRQ_CORETMR + 1))
+
+int hotplug_coreb;
+
+void platform_cpu_die(void)
+{
+	unsigned long iwr[2] = {0, 0};
+	unsigned long bank = SIC_SYSIRQ(IRQ_SUPPLE_0) / 32;
+	unsigned long bit = 1 << (SIC_SYSIRQ(IRQ_SUPPLE_0) % 32);
+
+	hotplug_coreb = 1;
+
+	iwr[bank] = bit;
+
+	/* disable core timer */
+	bfin_write_TCNTL(0);
+
+	/* clear ipi interrupt IRQ_SUPPLE_0 */
+	bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (10 + 1)));
+	SSYNC();
+
+	coreb_sleep(iwr[0], iwr[1], 0);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/include/mach/irq.h linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/include/mach/irq.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/include/mach/irq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/include/mach/irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -265,7 +265,8 @@
 
 #define GPIO_IRQ_BASE		IRQ_PF0
 
-#define NR_IRQS			(IRQ_PF47 + 1)
+#define NR_MACH_IRQS		(IRQ_PF47 + 1)
+#define NR_IRQS			(NR_MACH_IRQS + NR_SPARE_IRQS)
 
 #define IVG7			7
 #define IVG8			8
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/include/mach/smp.h linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/include/mach/smp.h
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/include/mach/smp.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/include/mach/smp.h	2010-05-16 17:17:36.000000000 -0400
@@ -25,4 +25,6 @@ void platform_send_ipi_cpu(unsigned int
 
 void platform_clear_ipi(unsigned int cpu);
 
+void bfin_local_timer_setup(void);
+
 #endif /* !_MACH_BF561_SMP */
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/Makefile linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/Makefile
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -6,3 +6,4 @@ obj-y := ints-priority.o dma.o
 
 obj-$(CONFIG_BF561_COREB) += coreb.o
 obj-$(CONFIG_SMP)  += smp.o secondary.o atomic.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/secondary.S linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/secondary.S
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/secondary.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/secondary.S	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <asm/blackfin.h>
 #include <asm/asm-offsets.h>
+#include <asm/trace.h>
 
 __INIT
 
@@ -62,6 +63,8 @@ ENTRY(_coreb_trampoline_start)
 	M2 = r0;
 	M3 = r0;
 
+	trace_buffer_init(p0,r0);
+
 	/* Turn off the icache */
 	p0.l = LO(IMEM_CONTROL);
 	p0.h = HI(IMEM_CONTROL);
@@ -159,6 +162,41 @@ ENTRY(_coreb_trampoline_start)
 ENDPROC(_coreb_trampoline_start)
 ENTRY(_coreb_trampoline_end)
 
+.section ".text"
+ENTRY(_set_sicb_iwr)
+	P0.H = hi(SICB_IWR0);
+	P0.L = lo(SICB_IWR0);
+	P1.H = hi(SICB_IWR1);
+	P1.L = lo(SICB_IWR1);
+	[P0] = R0;
+	[P1] = R1;
+	SSYNC;
+	RTS;
+ENDPROC(_set_sicb_iwr)
+
+ENTRY(_coreb_sleep)
+	sp.l = lo(INITIAL_STACK);
+	sp.h = hi(INITIAL_STACK);
+	fp = sp;
+	usp = sp;
+
+	call _set_sicb_iwr;
+
+	CLI R2;
+	SSYNC;
+	IDLE;
+	STI R2;
+
+	R0 = IWR_DISABLE_ALL;
+	R1 = IWR_DISABLE_ALL;
+	call _set_sicb_iwr;
+
+	p0.h = hi(COREB_L1_CODE_START);
+	p0.l = lo(COREB_L1_CODE_START);
+	jump (p0);
+ENDPROC(_coreb_sleep)
+
+__CPUINIT
 ENTRY(_coreb_start)
 	[--sp] = reti;
 
@@ -176,12 +214,20 @@ ENTRY(_coreb_start)
 	sp = [p0];
 	usp = sp;
 	fp = sp;
+#ifdef CONFIG_HOTPLUG_CPU
+	p0.l = _hotplug_coreb;
+	p0.h = _hotplug_coreb;
+	r0 = [p0];
+	cc = BITTST(r0, 0);
+	if cc jump 3f;
+#endif
 	sp += -12;
 	call _init_pda
 	sp += 12;
+#ifdef CONFIG_HOTPLUG_CPU
+3:
+#endif
 	call _secondary_start_kernel;
 .L_exit:
 	jump.s	.L_exit;
 ENDPROC(_coreb_start)
-
-__FINIT
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/smp.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/smp.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/smp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,11 +11,10 @@
 #include <linux/delay.h>
 #include <asm/smp.h>
 #include <asm/dma.h>
+#include <asm/time.h>
 
 static DEFINE_SPINLOCK(boot_lock);
 
-static cpumask_t cpu_callin_map;
-
 /*
  * platform_init_cpus() - Tell the world about how many cores we
  * have. This is called while setting up the architecture support
@@ -66,13 +65,15 @@ void __cpuinit platform_secondary_init(u
 	bfin_write_SICB_IAR5(bfin_read_SICA_IAR5());
 	bfin_write_SICB_IAR6(bfin_read_SICA_IAR6());
 	bfin_write_SICB_IAR7(bfin_read_SICA_IAR7());
+	bfin_write_SICB_IWR0(IWR_DISABLE_ALL);
+	bfin_write_SICB_IWR1(IWR_DISABLE_ALL);
 	SSYNC();
 
 	/* Store CPU-private information to the cpu_data array. */
 	bfin_setup_cpudata(cpu);
 
 	/* We are done with local CPU inits, unblock the boot CPU. */
-	cpu_set(cpu, cpu_callin_map);
+	set_cpu_online(cpu, true);
 	spin_lock(&boot_lock);
 	spin_unlock(&boot_lock);
 }
@@ -81,28 +82,28 @@ int __cpuinit platform_boot_secondary(un
 {
 	unsigned long timeout;
 
-	/* CoreB already running?! */
-	BUG_ON((bfin_read_SICA_SYSCR() & COREB_SRAM_INIT) == 0);
-
 	printk(KERN_INFO "Booting Core B.\n");
 
 	spin_lock(&boot_lock);
 
-	/* Kick CoreB, which should start execution from CORE_SRAM_BASE. */
-	SSYNC();
-	bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~COREB_SRAM_INIT);
-	SSYNC();
+	if ((bfin_read_SICA_SYSCR() & COREB_SRAM_INIT) == 0) {
+		/* CoreB already running, sending ipi to wakeup it */
+		platform_send_ipi_cpu(cpu, IRQ_SUPPLE_0);
+	} else {
+		/* Kick CoreB, which should start execution from CORE_SRAM_BASE. */
+		bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~COREB_SRAM_INIT);
+		SSYNC();
+	}
 
 	timeout = jiffies + 1 * HZ;
 	while (time_before(jiffies, timeout)) {
-		if (cpu_isset(cpu, cpu_callin_map))
+		if (cpu_online(cpu))
 			break;
 		udelay(100);
 		barrier();
 	}
 
-	if (cpu_isset(cpu, cpu_callin_map)) {
-		cpu_set(cpu, cpu_online_map);
+	if (cpu_online(cpu)) {
 		/* release the lock and let coreb run */
 		spin_unlock(&boot_lock);
 		return 0;
@@ -147,3 +148,20 @@ void platform_clear_ipi(unsigned int cpu
 	bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (10 + cpu)));
 	SSYNC();
 }
+
+/*
+ * Setup core B's local core timer.
+ * In SMP, core timer is used for clock event device.
+ */
+void __cpuinit bfin_local_timer_setup(void)
+{
+#if defined(CONFIG_TICKSOURCE_CORETMR)
+	bfin_coretmr_init();
+	bfin_coretmr_clockevent_init();
+	get_irq_chip(IRQ_CORETMR)->unmask(IRQ_CORETMR);
+#else
+	/* Power down the core timer, just to play safe. */
+	bfin_write_TCNTL(0);
+#endif
+
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/cpufreq.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-common/cpufreq.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/cpufreq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-common/cpufreq.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,10 +11,13 @@
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/fs.h>
+#include <linux/delay.h>
 #include <asm/blackfin.h>
 #include <asm/time.h>
 #include <asm/dpmc.h>
 
+#define CPUFREQ_CPU 0
+
 /* this is the table of CCLK frequencies, in Hz */
 /* .index is the entry in the auxillary dpm_state_table[] */
 static struct cpufreq_frequency_table bfin_freq_table[] = {
@@ -41,64 +44,124 @@ static struct bfin_dpm_state {
 	unsigned int tscale; /* change the divider on the core timer interrupt */
 } dpm_state_table[3];
 
+#if defined(CONFIG_CYCLES_CLOCKSOURCE)
 /*
-   normalized to maximum frequncy offset for CYCLES,
-   used in time-ts cycles clock source, but could be used
-   somewhere also.
+ * normalized to maximum frequncy offset for CYCLES,
+ * used in time-ts cycles clock source, but could be used
+ * somewhere also.
  */
 unsigned long long __bfin_cycles_off;
 unsigned int __bfin_cycles_mod;
+#endif
 
 /**************************************************************************/
+static void __init bfin_init_tables(unsigned long cclk, unsigned long sclk)
+{
 
-static unsigned int bfin_getfreq_khz(unsigned int cpu)
+	unsigned long csel, min_cclk;
+	int index;
+
+	/* Anomaly 273 seems to still exist on non-BF54x w/dcache turned on */
+#if ANOMALY_05000273 || ANOMALY_05000274 || \
+	(!defined(CONFIG_BF54x) && defined(CONFIG_BFIN_EXTMEM_DCACHEABLE))
+	min_cclk = sclk * 2;
+#else
+	min_cclk = sclk;
+#endif
+	csel = ((bfin_read_PLL_DIV() & CSEL) >> 4);
+
+	for (index = 0;  (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) {
+		bfin_freq_table[index].frequency = cclk >> index;
+		dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */
+		dpm_state_table[index].tscale =  (TIME_SCALE / (1 << csel)) - 1;
+
+		pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n",
+						 bfin_freq_table[index].frequency,
+						 dpm_state_table[index].csel,
+						 dpm_state_table[index].tscale);
+	}
+	return;
+}
+
+static void bfin_adjust_core_timer(void *info)
 {
-	/* The driver only support single cpu */
-	if (cpu != 0)
-		return -1;
+	unsigned int tscale;
+	unsigned int index = *(unsigned int *)info;
 
-	return get_cclk() / 1000;
+	/* we have to adjust the core timer, because it is using cclk */
+	tscale = dpm_state_table[index].tscale;
+	bfin_write_TSCALE(tscale);
+	return;
 }
 
+static unsigned int bfin_getfreq_khz(unsigned int cpu)
+{
+	/* Both CoreA/B have the same core clock */
+	return get_cclk() / 1000;
+}
 
-static int bfin_target(struct cpufreq_policy *policy,
+static int bfin_target(struct cpufreq_policy *poli,
 			unsigned int target_freq, unsigned int relation)
 {
-	unsigned int index, plldiv, tscale;
+	unsigned int index, plldiv, cpu;
 	unsigned long flags, cclk_hz;
 	struct cpufreq_freqs freqs;
+	static unsigned long lpj_ref;
+	static unsigned int  lpj_ref_freq;
+
+#if defined(CONFIG_CYCLES_CLOCKSOURCE)
 	cycles_t cycles;
+#endif
 
-	if (cpufreq_frequency_table_target(policy, bfin_freq_table,
-		 target_freq, relation, &index))
-		return -EINVAL;
+	for_each_online_cpu(cpu) {
+		struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
 
-	cclk_hz = bfin_freq_table[index].frequency;
+		if (!policy)
+			continue;
 
-	freqs.old = bfin_getfreq_khz(0);
-	freqs.new = cclk_hz;
-	freqs.cpu = 0;
+		if (cpufreq_frequency_table_target(policy, bfin_freq_table,
+				 target_freq, relation, &index))
+			return -EINVAL;
 
-	pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n",
-		 cclk_hz, target_freq, freqs.old);
+		cclk_hz = bfin_freq_table[index].frequency;
 
-	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-	local_irq_save_hw(flags);
-		plldiv = (bfin_read_PLL_DIV() & SSEL) | dpm_state_table[index].csel;
-		tscale = dpm_state_table[index].tscale;
-		bfin_write_PLL_DIV(plldiv);
-		/* we have to adjust the core timer, because it is using cclk */
-		bfin_write_TSCALE(tscale);
-		cycles = get_cycles();
-		SSYNC();
-	cycles += 10; /* ~10 cycles we lose after get_cycles() */
-	__bfin_cycles_off += (cycles << __bfin_cycles_mod) - (cycles << index);
-	__bfin_cycles_mod = index;
-	local_irq_restore_hw(flags);
-	/* TODO: just test case for cycles clock source, remove later */
-	pr_debug("cpufreq: done\n");
-	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+		freqs.old = bfin_getfreq_khz(0);
+		freqs.new = cclk_hz;
+		freqs.cpu = cpu;
+
+		pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n",
+			 cclk_hz, target_freq, freqs.old);
+
+		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+		if (cpu == CPUFREQ_CPU) {
+			local_irq_save_hw(flags);
+			plldiv = (bfin_read_PLL_DIV() & SSEL) |
+						dpm_state_table[index].csel;
+			bfin_write_PLL_DIV(plldiv);
+			on_each_cpu(bfin_adjust_core_timer, &index, 1);
+#if defined(CONFIG_CYCLES_CLOCKSOURCE)
+			cycles = get_cycles();
+			SSYNC();
+			cycles += 10; /* ~10 cycles we lose after get_cycles() */
+			__bfin_cycles_off +=
+			    (cycles << __bfin_cycles_mod) - (cycles << index);
+			__bfin_cycles_mod = index;
+#endif
+			if (!lpj_ref_freq) {
+				lpj_ref = loops_per_jiffy;
+				lpj_ref_freq = freqs.old;
+			}
+			if (freqs.new != freqs.old) {
+				loops_per_jiffy = cpufreq_scale(lpj_ref,
+						lpj_ref_freq, freqs.new);
+			}
+			local_irq_restore_hw(flags);
+		}
+		/* TODO: just test case for cycles clock source, remove later */
+		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+	}
 
+	pr_debug("cpufreq: done\n");
 	return 0;
 }
 
@@ -110,37 +173,16 @@ static int bfin_verify_speed(struct cpuf
 static int __init __bfin_cpu_init(struct cpufreq_policy *policy)
 {
 
-	unsigned long cclk, sclk, csel, min_cclk;
-	int index;
-
-	if (policy->cpu != 0)
-		return -EINVAL;
+	unsigned long cclk, sclk;
 
 	cclk = get_cclk() / 1000;
 	sclk = get_sclk() / 1000;
 
-#if ANOMALY_05000273 || ANOMALY_05000274 || \
-	(!defined(CONFIG_BF54x) && defined(CONFIG_BFIN_EXTMEM_DCACHEABLE))
-	min_cclk = sclk * 2;
-#else
-	min_cclk = sclk;
-#endif
-	csel = ((bfin_read_PLL_DIV() & CSEL) >> 4);
-
-	for (index = 0;  (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) {
-		bfin_freq_table[index].frequency = cclk >> index;
-		dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */
-		dpm_state_table[index].tscale =  (TIME_SCALE / (1 << csel)) - 1;
-
-		pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n",
-						 bfin_freq_table[index].frequency,
-						 dpm_state_table[index].csel,
-						 dpm_state_table[index].tscale);
-	}
+	if (policy->cpu == CPUFREQ_CPU)
+		bfin_init_tables(cclk, sclk);
 
 	policy->cpuinfo.transition_latency = 50000; /* 50us assumed */
 
-	/*Now ,only support one cpu */
 	policy->cur = cclk;
 	cpufreq_frequency_table_get_attr(bfin_freq_table, policy->cpu);
 	return cpufreq_frequency_table_cpuinfo(policy, bfin_freq_table);
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/entry.S linux-libre-2.6.34-gnu1/arch/blackfin/mach-common/entry.S
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-common/entry.S	2010-05-16 17:17:36.000000000 -0400
@@ -405,7 +405,7 @@ ENTRY(_double_fault)
 
 	r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
 	SP += -12;
-	call _double_fault_c;
+	pseudo_long_call _double_fault_c, p5;
 	SP += 12;
 .L_double_fault_panic:
         JUMP .L_double_fault_panic
@@ -447,7 +447,7 @@ ENTRY(_exception_to_level5)
 
 	r0 = sp; 	/* stack frame pt_regs pointer argument ==> r0 */
 	SP += -12;
-	call _trap_c;
+	pseudo_long_call _trap_c, p4;
 	SP += 12;
 
 	/* If interrupts were off during the exception (IPEND[4] = 1), turn them off
@@ -482,6 +482,8 @@ ENTRY(_trap) /* Exception: 4th entry int
 	[--sp] = ASTAT;
 	[--sp] = (R7:6,P5:4);
 
+	ANOMALY_283_315_WORKAROUND(p5, r7)
+
 #ifdef CONFIG_EXACT_HWERR
 	/* Make sure all pending read/writes complete. This will ensure any
 	 * accesses which could cause hardware errors completes, and signal
@@ -492,8 +494,6 @@ ENTRY(_trap) /* Exception: 4th entry int
 	ssync;
 #endif
 
-	ANOMALY_283_315_WORKAROUND(p5, r7)
-
 #ifdef CONFIG_DEBUG_DOUBLEFAULT
 	/*
 	 * Save these registers, as they are only valid in exception context
@@ -551,7 +551,7 @@ ENTRY(_kernel_execve)
 	p0 = sp;
 	sp += -16;
 	[sp + 12] = p0;
-	call _do_execve;
+	pseudo_long_call _do_execve, p5;
 	SP += 16;
 	cc = r0 == 0;
 	if ! cc jump .Lexecve_failed;
@@ -626,13 +626,6 @@ ENTRY(_system_call)
 	p0 = [sp + PT_ORIG_P0];
 #endif /* CONFIG_IPIPE */
 
-	/* Check the System Call */
-	r7 = __NR_syscall;
-	/* System call number is passed in P0 */
-	r6 = p0;
-	cc = r6 < r7;
-	if ! cc jump .Lbadsys;
-
 	/* are we tracing syscalls?*/
 	r7 = sp;
 	r6.l = lo(ALIGN_PAGE_MASK);
@@ -642,6 +635,14 @@ ENTRY(_system_call)
 	r7 = [p2+TI_FLAGS];
 	CC = BITTST(r7,TIF_SYSCALL_TRACE);
 	if CC JUMP _sys_trace;
+	CC = BITTST(r7,TIF_SINGLESTEP);
+	if CC JUMP _sys_trace;
+
+	/* Make sure the system call # is valid */
+	p4 = __NR_syscall;
+	/* System call number is passed in P0 */
+	cc = p4 <= p0;
+	if cc jump .Lbadsys;
 
 	/* Execute the appropriate system call */
 
@@ -704,7 +705,7 @@ ENTRY(_system_call)
 	sp += 4;
 
 	SP += -12;
-	call _schedule;
+	pseudo_long_call _schedule, p4;
 	SP += 12;
 
 	jump .Lresume_userspace_1;
@@ -723,7 +724,7 @@ ENTRY(_system_call)
 
 	r0 = sp;
 	SP += -12;
-	call _do_notify_resume;
+	pseudo_long_call _do_notify_resume, p5;
 	SP += 12;
 
 .Lsyscall_really_exit:
@@ -736,11 +737,17 @@ ENDPROC(_system_call)
  * this symbol need not be global anyways, so ...
  */
 _sys_trace:
-	call _syscall_trace;
-
-	/* Execute the appropriate system call */
+	r0 = sp;
+	pseudo_long_call _syscall_trace_enter, p5;
 
+	/* Make sure the system call # is valid */
 	p4 = [SP + PT_P0];
+	p3 = __NR_syscall;
+	cc = p3 <= p4;
+	r0 = -ENOSYS;
+	if cc jump .Lsys_trace_badsys;
+
+	/* Execute the appropriate system call */
 	p5.l = _sys_call_table;
 	p5.h = _sys_call_table;
 	p5 = p5 + (p4 << 2);
@@ -758,9 +765,11 @@ _sys_trace:
 	SP += -12;
 	call (p5);
 	SP += 24;
+.Lsys_trace_badsys:
 	[sp + PT_R0] = r0;
 
-	call _syscall_trace;
+	r0 = sp;
+	pseudo_long_call _syscall_trace_leave, p5;
 	jump .Lresume_userspace;
 ENDPROC(_sys_trace)
 
@@ -816,8 +825,8 @@ ENDPROC(_resume)
 
 ENTRY(_ret_from_exception)
 #ifdef CONFIG_IPIPE
-	p2.l = _per_cpu__ipipe_percpu_domain;
-	p2.h = _per_cpu__ipipe_percpu_domain;
+	p2.l = _ipipe_percpu_domain;
+	p2.h = _ipipe_percpu_domain;
 	r0.l = _ipipe_root;
 	r0.h = _ipipe_root;
 	r2 = [p2];
@@ -966,6 +975,13 @@ ENTRY(_evt_evt14)
 #else
 	cli r0;
 #endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+	[--sp] = rets;
+	sp += -12;
+	call _trace_hardirqs_off;
+	sp += 12;
+	rets = [sp++];
+#endif
 	[--sp] = RETI;
 	SP += 4;
 	rts;
@@ -989,6 +1005,14 @@ ENTRY(_schedule_and_signal_from_int)
 	p1 = rets;
 	[sp + PT_RESERVED] = p1;
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+	/* trace_hardirqs_on() checks if all irqs are disabled. But here IRQ 15
+	 * is turned on, so disable all irqs. */
+	cli r0;
+	sp += -12;
+	call _trace_hardirqs_on;
+	sp += 12;
+#endif
 #ifdef CONFIG_SMP
 	GET_PDA(p0, r0); 	/* Fetch current PDA (can't migrate to other CPU here) */
 	r0 = [p0 + PDA_IRQFLAGS];
@@ -1007,7 +1031,8 @@ ENTRY(_schedule_and_signal_from_int)
 
 	r0 = sp;
 	sp += -12;
-	call _finish_atomic_sections;
+
+	pseudo_long_call _finish_atomic_sections, p5;
 	sp += 12;
 	jump.s .Lresume_userspace;
 ENDPROC(_schedule_and_signal_from_int)
@@ -1357,7 +1382,7 @@ ENTRY(_sys_call_table)
 	.long _sys_newuname
 	.long _sys_ni_syscall	/* old sys_modify_ldt */
 	.long _sys_adjtimex
-	.long _sys_ni_syscall	/* 125 */ /* sys_mprotect */
+	.long _sys_mprotect	/* 125 */
 	.long _sys_ni_syscall	/* old sys_sigprocmask */
 	.long _sys_ni_syscall	/* old "creat_module" */
 	.long _sys_init_module
@@ -1376,16 +1401,16 @@ ENTRY(_sys_call_table)
 	.long _sys_getdents
 	.long _sys_ni_syscall	/* sys_select */
 	.long _sys_flock
-	.long _sys_ni_syscall	/* sys_msync */
+	.long _sys_msync
 	.long _sys_readv		/* 145 */
 	.long _sys_writev
 	.long _sys_getsid
 	.long _sys_fdatasync
 	.long _sys_sysctl
-	.long _sys_ni_syscall	/* 150 */ /* sys_mlock */
-	.long _sys_ni_syscall	/* sys_munlock */
-	.long _sys_ni_syscall	/* sys_mlockall */
-	.long _sys_ni_syscall	/* sys_munlockall */
+	.long _sys_mlock	/* 150 */
+	.long _sys_munlock
+	.long _sys_mlockall
+	.long _sys_munlockall
 	.long _sys_sched_setparam
 	.long _sys_sched_getparam /* 155 */
 	.long _sys_sched_setscheduler
@@ -1450,8 +1475,8 @@ ENTRY(_sys_call_table)
 	.long _sys_setfsuid	/* 215 */
 	.long _sys_setfsgid
 	.long _sys_pivot_root
-	.long _sys_ni_syscall	/* sys_mincore */
-	.long _sys_ni_syscall	/* sys_madvise */
+	.long _sys_mincore
+	.long _sys_madvise
 	.long _sys_getdents64	/* 220 */
 	.long _sys_fcntl64
 	.long _sys_ni_syscall	/* reserved for TUX */
@@ -1507,7 +1532,7 @@ ENTRY(_sys_call_table)
 	.long _sys_utimes
 	.long _sys_fadvise64_64
 	.long _sys_ni_syscall /* vserver */
-	.long _sys_ni_syscall /* 275, mbind */
+	.long _sys_mbind	/* 275 */
 	.long _sys_ni_syscall /* get_mempolicy */
 	.long _sys_ni_syscall /* set_mempolicy */
 	.long _sys_mq_open
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/head.S linux-libre-2.6.34-gnu1/arch/blackfin/mach-common/head.S
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/head.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-common/head.S	2010-05-16 17:17:36.000000000 -0400
@@ -144,8 +144,8 @@ ENTRY(__start)
 #endif
 
 	/* Initialize stack pointer */
-	sp.l = _init_thread_union;
-	sp.h = _init_thread_union;
+	sp.l = _init_thread_union + THREAD_SIZE;
+	sp.h = _init_thread_union + THREAD_SIZE;
 	fp = sp;
 	usp = sp;
 
@@ -186,6 +186,11 @@ ENTRY(__start)
 
 	/* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
 	call _bfin_relocate_l1_mem;
+
+#ifdef CONFIG_ROMKERNEL
+	call _bfin_relocate_xip_data;
+#endif
+
 #ifdef CONFIG_BFIN_KERNEL_CLOCK
 	/* Only use on-chip scratch space for stack when absolutely required
 	 * to avoid Anomaly 05000227 ... we know the init_clocks() func only
@@ -257,12 +262,7 @@ ENTRY(_real_start)
 	R0 = R7;
 	call _cmdline_init;
 
-	/* Load the current thread pointer and stack */
-	p1 = THREAD_SIZE + 4 (z);	/* +4 is for reti loading */
-	sp = sp + p1;
-	usp = sp;
-	fp = sp;
-	sp += -12;
+	sp += -12 + 4; /* +4 is for reti loading above */
 	call _init_pda
 	sp += 12;
 	jump.l _start_kernel;
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/interrupt.S linux-libre-2.6.34-gnu1/arch/blackfin/mach-common/interrupt.S
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/interrupt.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-common/interrupt.S	2010-05-16 17:17:36.000000000 -0400
@@ -88,6 +88,13 @@ __common_int_entry:
 #else
 	cli r1;
 #endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+	[--sp] = r0;
+	sp += -12;
+	call _trace_hardirqs_off;
+	sp += 12;
+	r0 = [sp++];
+#endif
 	[--sp] = RETI;  /* orig_pc */
 	/* Clear all L registers.  */
 	r1 = 0 (x);
@@ -109,10 +116,10 @@ __common_int_entry:
 	cc = r0 == 0;
 	if cc jump .Lcommon_restore_context;
 #else /* CONFIG_IPIPE */
-	call _do_irq;
+	pseudo_long_call _do_irq, p2;
 	SP += 12;
 #endif /* CONFIG_IPIPE */
-	call _return_from_int;
+	pseudo_long_call _return_from_int, p2;
 .Lcommon_restore_context:
 	RESTORE_CONTEXT
 	rti;
@@ -168,7 +175,7 @@ ENTRY(_evt_ivhw)
 
 	r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
 	SP += -12;
-	call _trap_c;
+	pseudo_long_call _trap_c, p5;
 	SP += 12;
 
 #ifdef EBIU_ERRMST
@@ -179,7 +186,7 @@ ENTRY(_evt_ivhw)
 	w[p0] = r0.l;
 #endif
 
-	call _ret_from_exception;
+	pseudo_long_call _ret_from_exception, p2;
 
 .Lcommon_restore_all_sys:
 	RESTORE_ALL_SYS
@@ -187,12 +194,28 @@ ENTRY(_evt_ivhw)
 ENDPROC(_evt_ivhw)
 
 /* Interrupt routine for evt2 (NMI).
- * We don't actually use this, so just return.
  * For inner circle type details, please see:
  * http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:nmi
  */
 ENTRY(_evt_nmi)
+#ifndef CONFIG_NMI_WATCHDOG
 .weak _evt_nmi
+#else
+	/* Not take account of CPLBs, this handler will not return */
+	SAVE_ALL_SYS
+	r0 = sp;
+	r1 = retn;
+	[sp + PT_PC] = r1;
+	trace_buffer_save(p4,r5);
+
+	ANOMALY_283_315_WORKAROUND(p4, r5)
+
+	SP += -12;
+	call _do_nmi;
+	SP += 12;
+1:
+	jump 1b;
+#endif
 	rtn;
 ENDPROC(_evt_nmi)
 
@@ -223,7 +246,7 @@ ENTRY(_evt_system_call)
 #ifdef CONFIG_FRAME_POINTER
 	fp = 0;
 #endif
-	call _system_call;
+	pseudo_long_call _system_call, p2;
 	jump .Lcommon_restore_context;
 ENDPROC(_evt_system_call)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/ints-priority.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-common/ints-priority.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/ints-priority.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-common/ints-priority.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <asm/dpmc.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/bfin_sport.h>
+#include <asm/bfin_can.h>
 
 #define SIC_SYSIRQ(irq)	(irq - (IRQ_CORETMR + 1))
 
@@ -172,7 +173,12 @@ static void bfin_internal_mask_irq(unsig
 	local_irq_restore_hw(flags);
 }
 
+#ifdef CONFIG_SMP
+static void bfin_internal_unmask_irq_affinity(unsigned int irq,
+		const struct cpumask *affinity)
+#else
 static void bfin_internal_unmask_irq(unsigned int irq)
+#endif
 {
 	unsigned long flags;
 
@@ -185,16 +191,38 @@ static void bfin_internal_unmask_irq(uns
 	local_irq_save_hw(flags);
 	mask_bank = SIC_SYSIRQ(irq) / 32;
 	mask_bit = SIC_SYSIRQ(irq) % 32;
-	bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) |
-			     (1 << mask_bit));
 #ifdef CONFIG_SMP
-	bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) |
-			     (1 << mask_bit));
+	if (cpumask_test_cpu(0, affinity))
+#endif
+		bfin_write_SIC_IMASK(mask_bank,
+			bfin_read_SIC_IMASK(mask_bank) |
+			(1 << mask_bit));
+#ifdef CONFIG_SMP
+	if (cpumask_test_cpu(1, affinity))
+		bfin_write_SICB_IMASK(mask_bank,
+			bfin_read_SICB_IMASK(mask_bank) |
+			(1 << mask_bit));
 #endif
 #endif
 	local_irq_restore_hw(flags);
 }
 
+#ifdef CONFIG_SMP
+static void bfin_internal_unmask_irq(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	bfin_internal_unmask_irq_affinity(irq, desc->affinity);
+}
+
+static int bfin_internal_set_affinity(unsigned int irq, const struct cpumask *mask)
+{
+	bfin_internal_mask_irq(irq);
+	bfin_internal_unmask_irq_affinity(irq, mask);
+
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_PM
 int bfin_internal_set_wake(unsigned int irq, unsigned int state)
 {
@@ -224,11 +252,6 @@ int bfin_internal_set_wake(unsigned int
 	wakeup |= USBWE;
 	break;
 #endif
-#ifdef IRQ_KEY
-	case IRQ_KEY:
-	wakeup |= KPADWE;
-	break;
-#endif
 #ifdef CONFIG_BF54x
 	case IRQ_CNT:
 	wakeup |= ROTWE;
@@ -270,6 +293,9 @@ static struct irq_chip bfin_internal_irq
 	.mask_ack = bfin_internal_mask_irq,
 	.disable = bfin_internal_mask_irq,
 	.enable = bfin_internal_unmask_irq,
+#ifdef CONFIG_SMP
+	.set_affinity = bfin_internal_set_affinity,
+#endif
 #ifdef CONFIG_PM
 	.set_wake = bfin_internal_set_wake,
 #endif
@@ -294,7 +320,6 @@ static int error_int_mask;
 static void bfin_generic_error_mask_irq(unsigned int irq)
 {
 	error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR));
-
 	if (!error_int_mask)
 		bfin_internal_mask_irq(IRQ_GENERIC_ERROR);
 }
@@ -385,6 +410,127 @@ static void bfin_demux_error_irq(unsigne
 }
 #endif				/* BF537_GENERIC_ERROR_INT_DEMUX */
 
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static int mac_stat_int_mask;
+
+static void bfin_mac_status_ack_irq(unsigned int irq)
+{
+	switch (irq) {
+	case IRQ_MAC_MMCINT:
+		bfin_write_EMAC_MMC_TIRQS(
+			bfin_read_EMAC_MMC_TIRQE() &
+			bfin_read_EMAC_MMC_TIRQS());
+		bfin_write_EMAC_MMC_RIRQS(
+			bfin_read_EMAC_MMC_RIRQE() &
+			bfin_read_EMAC_MMC_RIRQS());
+		break;
+	case IRQ_MAC_RXFSINT:
+		bfin_write_EMAC_RX_STKY(
+			bfin_read_EMAC_RX_IRQE() &
+			bfin_read_EMAC_RX_STKY());
+		break;
+	case IRQ_MAC_TXFSINT:
+		bfin_write_EMAC_TX_STKY(
+			bfin_read_EMAC_TX_IRQE() &
+			bfin_read_EMAC_TX_STKY());
+		break;
+	case IRQ_MAC_WAKEDET:
+		 bfin_write_EMAC_WKUP_CTL(
+			bfin_read_EMAC_WKUP_CTL() | MPKS | RWKS);
+		break;
+	default:
+		/* These bits are W1C */
+		bfin_write_EMAC_SYSTAT(1L << (irq - IRQ_MAC_PHYINT));
+		break;
+	}
+}
+
+static void bfin_mac_status_mask_irq(unsigned int irq)
+{
+	mac_stat_int_mask &= ~(1L << (irq - IRQ_MAC_PHYINT));
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+	switch (irq) {
+	case IRQ_MAC_PHYINT:
+		bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() & ~PHYIE);
+		break;
+	default:
+		break;
+	}
+#else
+	if (!mac_stat_int_mask)
+		bfin_internal_mask_irq(IRQ_MAC_ERROR);
+#endif
+	bfin_mac_status_ack_irq(irq);
+}
+
+static void bfin_mac_status_unmask_irq(unsigned int irq)
+{
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+	switch (irq) {
+	case IRQ_MAC_PHYINT:
+		bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() | PHYIE);
+		break;
+	default:
+		break;
+	}
+#else
+	if (!mac_stat_int_mask)
+		bfin_internal_unmask_irq(IRQ_MAC_ERROR);
+#endif
+	mac_stat_int_mask |= 1L << (irq - IRQ_MAC_PHYINT);
+}
+
+#ifdef CONFIG_PM
+int bfin_mac_status_set_wake(unsigned int irq, unsigned int state)
+{
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+	return bfin_internal_set_wake(IRQ_GENERIC_ERROR, state);
+#else
+	return bfin_internal_set_wake(IRQ_MAC_ERROR, state);
+#endif
+}
+#endif
+
+static struct irq_chip bfin_mac_status_irqchip = {
+	.name = "MACST",
+	.ack = bfin_ack_noop,
+	.mask_ack = bfin_mac_status_mask_irq,
+	.mask = bfin_mac_status_mask_irq,
+	.unmask = bfin_mac_status_unmask_irq,
+#ifdef CONFIG_PM
+	.set_wake = bfin_mac_status_set_wake,
+#endif
+};
+
+static void bfin_demux_mac_status_irq(unsigned int int_err_irq,
+				 struct irq_desc *inta_desc)
+{
+	int i, irq = 0;
+	u32 status = bfin_read_EMAC_SYSTAT();
+
+	for (i = 0; i < (IRQ_MAC_STMDONE - IRQ_MAC_PHYINT); i++)
+		if (status & (1L << i)) {
+			irq = IRQ_MAC_PHYINT + i;
+			break;
+		}
+
+	if (irq) {
+		if (mac_stat_int_mask & (1L << (irq - IRQ_MAC_PHYINT))) {
+			bfin_handle_irq(irq);
+		} else {
+			bfin_mac_status_ack_irq(irq);
+			pr_debug("IRQ %d:"
+				 " MASKED MAC ERROR INTERRUPT ASSERTED\n",
+				 irq);
+		}
+	} else
+		printk(KERN_ERR
+		       "%s : %s : LINE %d :\nIRQ ?: MAC ERROR"
+		       " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
+		       __func__, __FILE__, __LINE__);
+}
+#endif
+
 static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle)
 {
 #ifdef CONFIG_IPIPE
@@ -1031,7 +1177,6 @@ int __init init_arch_irq(void)
 #elif defined(CONFIG_BF538) || defined(CONFIG_BF539)
 		case IRQ_PORTF_INTA:
 #endif
-
 			set_irq_chained_handler(irq,
 						bfin_demux_gpio_irq);
 			break;
@@ -1040,29 +1185,36 @@ int __init init_arch_irq(void)
 			set_irq_chained_handler(irq, bfin_demux_error_irq);
 			break;
 #endif
-
-#ifdef CONFIG_SMP
-#ifdef CONFIG_TICKSOURCE_GPTMR0
-		case IRQ_TIMER0:
-#endif
-#ifdef CONFIG_TICKSOURCE_CORETMR
-		case IRQ_CORETMR:
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+		case IRQ_MAC_ERROR:
+			set_irq_chained_handler(irq, bfin_demux_mac_status_irq);
+			break;
 #endif
+#ifdef CONFIG_SMP
 		case IRQ_SUPPLE_0:
 		case IRQ_SUPPLE_1:
 			set_irq_handler(irq, handle_percpu_irq);
 			break;
 #endif
 
-#ifdef CONFIG_IPIPE
-#ifndef CONFIG_TICKSOURCE_CORETMR
-		case IRQ_TIMER0:
+#ifdef CONFIG_TICKSOURCE_CORETMR
+		case IRQ_CORETMR:
+# ifdef CONFIG_SMP
+			set_irq_handler(irq, handle_percpu_irq);
+			break;
+# else
 			set_irq_handler(irq, handle_simple_irq);
 			break;
+# endif
 #endif
-		case IRQ_CORETMR:
+
+#ifdef CONFIG_TICKSOURCE_GPTMR0
+		case IRQ_TIMER0:
 			set_irq_handler(irq, handle_simple_irq);
 			break;
+#endif
+
+#ifdef CONFIG_IPIPE
 		default:
 			set_irq_handler(irq, handle_level_irq);
 			break;
@@ -1078,14 +1230,22 @@ int __init init_arch_irq(void)
 	for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++)
 		set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip,
 					 handle_level_irq);
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	set_irq_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq);
+#endif
 #endif
 
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++)
+		set_irq_chip_and_handler(irq, &bfin_mac_status_irqchip,
+					 handle_level_irq);
+#endif
 	/* if configured as edge, then will be changed to do_edge_IRQ */
-	for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++)
+	for (irq = GPIO_IRQ_BASE;
+		irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++)
 		set_irq_chip_and_handler(irq, &bfin_gpio_irqchip,
 					 handle_level_irq);
 
-
 	bfin_write_IMASK(0);
 	CSYNC();
 	ilat = bfin_read_ILAT();
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/pm.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-common/pm.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/pm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-common/pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/suspend.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/smp.c linux-libre-2.6.34-gnu1/arch/blackfin/mach-common/smp.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/smp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mach-common/smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/smp.h>
 #include <linux/seq_file.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
 #include <asm/mmu_context.h>
@@ -122,9 +123,17 @@ static void ipi_call_function(unsigned i
 	wait = msg->call_struct.wait;
 	cpu_clear(cpu, msg->call_struct.pending);
 	func(info);
-	if (wait)
+	if (wait) {
+#ifdef __ARCH_SYNC_CORE_DCACHE
+		/*
+		 * 'wait' usually means synchronization between CPUs.
+		 * Invalidate D cache in case shared data was changed
+		 * by func() to ensure cache coherence.
+		 */
+		resync_core_dcache();
+#endif
 		cpu_clear(cpu, msg->call_struct.waitmask);
-	else
+	} else
 		kfree(msg);
 }
 
@@ -219,6 +228,13 @@ int smp_call_function(void (*func)(void
 			blackfin_dcache_invalidate_range(
 				(unsigned long)(&msg->call_struct.waitmask),
 				(unsigned long)(&msg->call_struct.waitmask));
+#ifdef __ARCH_SYNC_CORE_DCACHE
+		/*
+		 * Invalidate D cache in case shared data was changed by
+		 * other processors to ensure cache coherence.
+		 */
+		resync_core_dcache();
+#endif
 		kfree(msg);
 	}
 	return 0;
@@ -261,6 +277,13 @@ int smp_call_function_single(int cpuid,
 			blackfin_dcache_invalidate_range(
 				(unsigned long)(&msg->call_struct.waitmask),
 				(unsigned long)(&msg->call_struct.waitmask));
+#ifdef __ARCH_SYNC_CORE_DCACHE
+		/*
+		 * Invalidate D cache in case shared data was changed by
+		 * other processors to ensure cache coherence.
+		 */
+		resync_core_dcache();
+#endif
 		kfree(msg);
 	}
 	return 0;
@@ -322,8 +345,11 @@ void smp_send_stop(void)
 
 int __cpuinit __cpu_up(unsigned int cpu)
 {
-	struct task_struct *idle;
 	int ret;
+	static struct task_struct *idle;
+
+	if (idle)
+		free_task(idle);
 
 	idle = fork_idle(cpu);
 	if (IS_ERR(idle)) {
@@ -332,7 +358,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
 	}
 
 	secondary_stack = task_stack_page(idle) + THREAD_SIZE;
-	smp_wmb();
 
 	ret = platform_boot_secondary(cpu, idle);
 
@@ -343,9 +368,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
 
 static void __cpuinit setup_secondary(unsigned int cpu)
 {
-#if !defined(CONFIG_TICKSOURCE_GPTMR0)
-	struct irq_desc *timer_desc;
-#endif
 	unsigned long ilat;
 
 	bfin_write_IMASK(0);
@@ -360,17 +382,6 @@ static void __cpuinit setup_secondary(un
 	bfin_irq_flags |= IMASK_IVG15 |
 	    IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
 	    IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
-
-#if defined(CONFIG_TICKSOURCE_GPTMR0)
-	/* Power down the core timer, just to play safe. */
-	bfin_write_TCNTL(0);
-
-	/* system timer0 has been setup by CoreA. */
-#else
-	timer_desc = irq_desc + IRQ_CORETMR;
-	setup_core_timer();
-	timer_desc->chip->enable(IRQ_CORETMR);
-#endif
 }
 
 void __cpuinit secondary_start_kernel(void)
@@ -405,7 +416,6 @@ void __cpuinit secondary_start_kernel(vo
 	atomic_inc(&mm->mm_users);
 	atomic_inc(&mm->mm_count);
 	current->active_mm = mm;
-	BUG_ON(current->mm);	/* Can't be, but better be safe than sorry. */
 
 	preempt_disable();
 
@@ -413,6 +423,9 @@ void __cpuinit secondary_start_kernel(vo
 
 	platform_secondary_init(cpu);
 
+	/* setup local core timer */
+	bfin_local_timer_setup();
+
 	local_irq_enable();
 
 	/*
@@ -462,25 +475,58 @@ void smp_icache_flush_range_others(unsig
 EXPORT_SYMBOL_GPL(smp_icache_flush_range_others);
 
 #ifdef __ARCH_SYNC_CORE_ICACHE
+unsigned long icache_invld_count[NR_CPUS];
 void resync_core_icache(void)
 {
 	unsigned int cpu = get_cpu();
 	blackfin_invalidate_entire_icache();
-	++per_cpu(cpu_data, cpu).icache_invld_count;
+	icache_invld_count[cpu]++;
 	put_cpu();
 }
 EXPORT_SYMBOL(resync_core_icache);
 #endif
 
 #ifdef __ARCH_SYNC_CORE_DCACHE
+unsigned long dcache_invld_count[NR_CPUS];
 unsigned long barrier_mask __attribute__ ((__section__(".l2.bss")));
 
 void resync_core_dcache(void)
 {
 	unsigned int cpu = get_cpu();
 	blackfin_invalidate_entire_dcache();
-	++per_cpu(cpu_data, cpu).dcache_invld_count;
+	dcache_invld_count[cpu]++;
 	put_cpu();
 }
 EXPORT_SYMBOL(resync_core_dcache);
 #endif
+
+#ifdef CONFIG_HOTPLUG_CPU
+int __cpuexit __cpu_disable(void)
+{
+	unsigned int cpu = smp_processor_id();
+
+	if (cpu == 0)
+		return -EPERM;
+
+	set_cpu_online(cpu, false);
+	return 0;
+}
+
+static DECLARE_COMPLETION(cpu_killed);
+
+int __cpuexit __cpu_die(unsigned int cpu)
+{
+	return wait_for_completion_timeout(&cpu_killed, 5000);
+}
+
+void cpu_die(void)
+{
+	complete(&cpu_killed);
+
+	atomic_dec(&init_mm.mm_users);
+	atomic_dec(&init_mm.mm_count);
+
+	local_irq_disable();
+	platform_cpu_die();
+}
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/Makefile linux-libre-2.6.34-gnu1/arch/blackfin/Makefile
--- linux-libre-2.6.33-gnu1/arch/blackfin/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,9 @@ OBJCOPYFLAGS     := -O binary -R .note -
 GZFLAGS          := -9
 
 KBUILD_CFLAGS           += $(call cc-option,-mno-fdpic)
+ifeq ($(CONFIG_ROMKERNEL),y)
+KBUILD_CFLAGS           += -mlong-calls
+endif
 KBUILD_AFLAGS           += $(call cc-option,-mno-fdpic)
 CFLAGS_MODULE    += -mlong-calls
 LDFLAGS_MODULE   += -m elf32bfin
@@ -130,7 +133,6 @@ KBUILD_CFLAGS += -Iarch/$(ARCH)/mach-$(M
 KBUILD_CPPFLAGS	+= $(patsubst %,-I$(srctree)/%include,$(machdirs))
 
 CLEAN_FILES += \
-	arch/$(ARCH)/include/asm/asm-offsets.h \
 	arch/$(ARCH)/kernel/asm-offsets.s \
 
 archclean:
@@ -138,7 +140,7 @@ archclean:
 
 INSTALL_PATH ?= /tftpboot
 boot := arch/$(ARCH)/boot
-BOOT_TARGETS = vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma
+BOOT_TARGETS = vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma vmImage.xip
 PHONY += $(BOOT_TARGETS) install
 KBUILD_IMAGE := $(boot)/vmImage
 
@@ -156,6 +158,7 @@ define archhelp
   echo  '  vmImage.bz2     - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.bz2)'
   echo  '* vmImage.gz      - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.gz)'
   echo  '  vmImage.lzma    - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.lzma)'
+  echo  '  vmImage.xip     - XIP Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.xip)'
   echo  '  install         - Install kernel using'
   echo  '                     (your) ~/bin/$(INSTALLKERNEL) or'
   echo  '                     (distribution) PATH: $(INSTALLKERNEL) or'
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mm/init.c linux-libre-2.6.34-gnu1/arch/blackfin/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
  * Licensed under the GPL-2 or later.
  */
 
+#include <linux/gfp.h>
 #include <linux/swap.h>
 #include <linux/bootmem.h>
 #include <linux/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mm/isram-driver.c linux-libre-2.6.34-gnu1/arch/blackfin/mm/isram-driver.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mm/isram-driver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mm/isram-driver.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/sched.h>
 
@@ -62,7 +63,7 @@ static void isram_write(const void *addr
 	uint32_t cmd;
 	unsigned long flags;
 
-	if (addr >= (void *)(L1_CODE_START + L1_CODE_LENGTH))
+	if (unlikely(addr >= (void *)(L1_CODE_START + L1_CODE_LENGTH)))
 		return;
 
 	cmd = IADDR2DTEST(addr) | 2;             /* write */
@@ -93,7 +94,7 @@ static uint64_t isram_read(const void *a
 	unsigned long flags;
 	uint64_t ret;
 
-	if (addr > (void *)(L1_CODE_START + L1_CODE_LENGTH))
+	if (unlikely(addr > (void *)(L1_CODE_START + L1_CODE_LENGTH)))
 		return 0;
 
 	cmd = IADDR2DTEST(addr) | 0;              /* read */
@@ -120,7 +121,7 @@ static bool isram_check_addr(const void
 {
 	if ((addr >= (void *)L1_CODE_START) &&
 	    (addr < (void *)(L1_CODE_START + L1_CODE_LENGTH))) {
-		if ((addr + n) > (void *)(L1_CODE_START + L1_CODE_LENGTH)) {
+		if (unlikely((addr + n) > (void *)(L1_CODE_START + L1_CODE_LENGTH))) {
 			show_stack(NULL, NULL);
 			pr_err("copy involving %p length (%zu) too long\n", addr, n);
 		}
diff -druNp linux-libre-2.6.33-gnu1/arch/blackfin/mm/sram-alloc.c linux-libre-2.6.34-gnu1/arch/blackfin/mm/sram-alloc.c
--- linux-libre-2.6.33-gnu1/arch/blackfin/mm/sram-alloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/blackfin/mm/sram-alloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 #include <asm/blackfin.h>
 #include <asm/mem_map.h>
 #include "blackfin_sram.h"
@@ -402,7 +403,7 @@ void *l1_data_A_sram_alloc(size_t size)
 	void *addr;
 	unsigned int cpu;
 
-	cpu = get_cpu();
+	cpu = smp_processor_id();
 	/* add mutex operation */
 	spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
 
@@ -411,7 +412,6 @@ void *l1_data_A_sram_alloc(size_t size)
 
 	/* add mutex operation */
 	spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
-	put_cpu();
 
 	pr_debug("Allocated address in l1_data_A_sram_alloc is 0x%lx+0x%lx\n",
 		 (long unsigned int)addr, size);
@@ -430,7 +430,7 @@ int l1_data_A_sram_free(const void *addr
 	int ret;
 	unsigned int cpu;
 
-	cpu = get_cpu();
+	cpu = smp_processor_id();
 	/* add mutex operation */
 	spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
 
@@ -439,7 +439,6 @@ int l1_data_A_sram_free(const void *addr
 
 	/* add mutex operation */
 	spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
-	put_cpu();
 
 	return ret;
 #else
@@ -455,7 +454,7 @@ void *l1_data_B_sram_alloc(size_t size)
 	void *addr;
 	unsigned int cpu;
 
-	cpu = get_cpu();
+	cpu = smp_processor_id();
 	/* add mutex operation */
 	spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
 
@@ -464,7 +463,6 @@ void *l1_data_B_sram_alloc(size_t size)
 
 	/* add mutex operation */
 	spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
-	put_cpu();
 
 	pr_debug("Allocated address in l1_data_B_sram_alloc is 0x%lx+0x%lx\n",
 		 (long unsigned int)addr, size);
@@ -483,7 +481,7 @@ int l1_data_B_sram_free(const void *addr
 	int ret;
 	unsigned int cpu;
 
-	cpu = get_cpu();
+	cpu = smp_processor_id();
 	/* add mutex operation */
 	spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
 
@@ -492,7 +490,6 @@ int l1_data_B_sram_free(const void *addr
 
 	/* add mutex operation */
 	spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
-	put_cpu();
 
 	return ret;
 #else
@@ -540,7 +537,7 @@ void *l1_inst_sram_alloc(size_t size)
 	void *addr;
 	unsigned int cpu;
 
-	cpu = get_cpu();
+	cpu = smp_processor_id();
 	/* add mutex operation */
 	spin_lock_irqsave(&per_cpu(l1_inst_sram_lock, cpu), flags);
 
@@ -549,7 +546,6 @@ void *l1_inst_sram_alloc(size_t size)
 
 	/* add mutex operation */
 	spin_unlock_irqrestore(&per_cpu(l1_inst_sram_lock, cpu), flags);
-	put_cpu();
 
 	pr_debug("Allocated address in l1_inst_sram_alloc is 0x%lx+0x%lx\n",
 		 (long unsigned int)addr, size);
@@ -568,7 +564,7 @@ int l1_inst_sram_free(const void *addr)
 	int ret;
 	unsigned int cpu;
 
-	cpu = get_cpu();
+	cpu = smp_processor_id();
 	/* add mutex operation */
 	spin_lock_irqsave(&per_cpu(l1_inst_sram_lock, cpu), flags);
 
@@ -577,7 +573,6 @@ int l1_inst_sram_free(const void *addr)
 
 	/* add mutex operation */
 	spin_unlock_irqrestore(&per_cpu(l1_inst_sram_lock, cpu), flags);
-	put_cpu();
 
 	return ret;
 #else
@@ -593,7 +588,7 @@ void *l1sram_alloc(size_t size)
 	void *addr;
 	unsigned int cpu;
 
-	cpu = get_cpu();
+	cpu = smp_processor_id();
 	/* add mutex operation */
 	spin_lock_irqsave(&per_cpu(l1sram_lock, cpu), flags);
 
@@ -602,7 +597,6 @@ void *l1sram_alloc(size_t size)
 
 	/* add mutex operation */
 	spin_unlock_irqrestore(&per_cpu(l1sram_lock, cpu), flags);
-	put_cpu();
 
 	return addr;
 }
@@ -614,7 +608,7 @@ void *l1sram_alloc_max(size_t *psize)
 	void *addr;
 	unsigned int cpu;
 
-	cpu = get_cpu();
+	cpu = smp_processor_id();
 	/* add mutex operation */
 	spin_lock_irqsave(&per_cpu(l1sram_lock, cpu), flags);
 
@@ -623,7 +617,6 @@ void *l1sram_alloc_max(size_t *psize)
 
 	/* add mutex operation */
 	spin_unlock_irqrestore(&per_cpu(l1sram_lock, cpu), flags);
-	put_cpu();
 
 	return addr;
 }
@@ -635,7 +628,7 @@ int l1sram_free(const void *addr)
 	int ret;
 	unsigned int cpu;
 
-	cpu = get_cpu();
+	cpu = smp_processor_id();
 	/* add mutex operation */
 	spin_lock_irqsave(&per_cpu(l1sram_lock, cpu), flags);
 
@@ -644,7 +637,6 @@ int l1sram_free(const void *addr)
 
 	/* add mutex operation */
 	spin_unlock_irqrestore(&per_cpu(l1sram_lock, cpu), flags);
-	put_cpu();
 
 	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v10/drivers/i2c.c linux-libre-2.6.34-gnu1/arch/cris/arch-v10/drivers/i2c.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v10/drivers/i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v10/drivers/i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v10/drivers/sync_serial.c linux-libre-2.6.34-gnu1/arch/cris/arch-v10/drivers/sync_serial.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v10/drivers/sync_serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v10/drivers/sync_serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/errno.h>
 #include <linux/major.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/poll.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v10/kernel/entry.S linux-libre-2.6.34-gnu1/arch/cris/arch-v10/kernel/entry.S
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v10/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v10/kernel/entry.S	2010-05-16 17:17:36.000000000 -0400
@@ -358,7 +358,7 @@ mmu_bus_fault:
 1:	btstq	12, $r1		   ; Refill?
 	bpl	2f
 	lsrq	24, $r1     ; Get PGD index (bit 24-31)
-	move.d  [per_cpu__current_pgd], $r0 ; PGD for the current process
+	move.d  [current_pgd], $r0 ; PGD for the current process
 	move.d	[$r0+$r1.d], $r0   ; Get PMD
 	beq	2f
 	nop
@@ -692,7 +692,7 @@ sys_call_table:
 	.long sys_swapon
 	.long sys_reboot
 	.long sys_old_readdir
-	.long old_mmap		/* 90 */
+	.long sys_old_mmap	/* 90 */
 	.long sys_munmap
 	.long sys_truncate
 	.long sys_ftruncate
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v10/kernel/irq.c linux-libre-2.6.34-gnu1/arch/cris/arch-v10/kernel/irq.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v10/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v10/kernel/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -133,7 +133,7 @@ static void end_crisv10_irq(unsigned int
 }
 
 static struct irq_chip crisv10_irq_type = {
-	.typename =    "CRISv10",
+	.name =        "CRISv10",
 	.startup =     startup_crisv10_irq,
 	.shutdown =    shutdown_crisv10_irq,
 	.enable =      enable_crisv10_irq,
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v10/kernel/process.c linux-libre-2.6.34-gnu1/arch/cris/arch-v10/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v10/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v10/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,9 +11,9 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/fs.h>
-#include <linux/slab.h>
 #include <arch/svinto.h>
 #include <linux/init.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v10/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/cris/arch-v10/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v10/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v10/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -127,57 +127,6 @@ long arch_ptrace(struct task_struct *chi
 			ret = 0;
 			break;
 
-		case PTRACE_SYSCALL:
-		case PTRACE_CONT:
-			ret = -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;
-			
-			/* TODO: make sure any pending breakpoint is killed */
-			wake_up_process(child);
-			ret = 0;
-			
-			break;
-		
- 		/* Make the child exit by sending it a sigkill. */
-		case PTRACE_KILL:
-			ret = 0;
-			
-			if (child->exit_state == EXIT_ZOMBIE)
-				break;
-			
-			child->exit_code = SIGKILL;
-			
-			/* TODO: make sure any pending breakpoint is killed */
-			wake_up_process(child);
-			break;
-
-		/* Set the trap flag. */
-		case PTRACE_SINGLESTEP:
-			ret = -EIO;
-			
-			if (!valid_signal(data))
-				break;
-			
-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-
-			/* TODO: set some clever breakpoint mechanism... */
-
-			child->exit_code = data;
-			wake_up_process(child);
-			ret = 0;
-			break;
-
 		/* Get all GP registers from the child. */
 		case PTRACE_GETREGS: {
 		  	int i;
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v10/lib/old_checksum.c linux-libre-2.6.34-gnu1/arch/cris/arch-v10/lib/old_checksum.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v10/lib/old_checksum.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v10/lib/old_checksum.c	2010-05-16 17:17:36.000000000 -0400
@@ -77,7 +77,7 @@ __wsum csum_partial(const void *p, int l
 		sum += *buff++;
 
 	if (endMarker > buff)
-		sum += *(const u8 *)buff;	/* add extra byte seperately */
+		sum += *(const u8 *)buff;	/* add extra byte separately */
 
 	BITOFF;
 	return (__force __wsum)sum;
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/drivers/cryptocop.c linux-libre-2.6.34-gnu1/arch/cris/arch-v32/drivers/cryptocop.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/drivers/cryptocop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/drivers/cryptocop.c	2010-05-16 17:17:36.000000000 -0400
@@ -628,9 +628,9 @@ static int create_output_descriptors(str
 		cdesc->dma_descr->buf = (char*)virt_to_phys(operation->tfrm_op.indata[*iniov_ix].iov_base + *iniov_offset);
 		cdesc->dma_descr->after = cdesc->dma_descr->buf + dlength;
 
+		assert(desc_len >= dlength);
 		desc_len -= dlength;
 		*iniov_offset += dlength;
-		assert(desc_len >= 0);
 		if (*iniov_offset >= operation->tfrm_op.indata[*iniov_ix].iov_len) {
 			*iniov_offset = 0;
 			++(*iniov_ix);
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/drivers/i2c.c linux-libre-2.6.34-gnu1/arch/cris/arch-v32/drivers/i2c.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/drivers/i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/drivers/i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,6 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/drivers/pci/bios.c linux-libre-2.6.34-gnu1/arch/cris/arch-v32/drivers/pci/bios.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/drivers/pci/bios.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/drivers/pci/bios.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,18 +41,16 @@ int pci_mmap_page_range(struct pci_dev *
 	return 0;
 }
 
-void
-pcibios_align_resource(void *data, struct resource *res,
+resource_size_t
+pcibios_align_resource(void *data, const struct resource *res,
 		       resource_size_t size, resource_size_t align)
 {
-	if (res->flags & IORESOURCE_IO) {
-		resource_size_t start = res->start;
+	resource_size_t start = res->start;
 
-		if (start & 0x300) {
-			start = (start + 0x3ff) & ~0x3ff;
-			res->start = start;
-		}
-	}
+	if ((res->flags & IORESOURCE_IO) && (start & 0x300))
+		start = (start + 0x3ff) & ~0x3ff;
+
+	return start;
 }
 
 int pcibios_enable_resources(struct pci_dev *dev, int mask)
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/drivers/pci/dma.c linux-libre-2.6.34-gnu1/arch/cris/arch-v32/drivers/pci/dma.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/drivers/pci/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/drivers/pci/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 
 void *dma_alloc_coherent(struct device *dev, size_t size,
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/drivers/sync_serial.c linux-libre-2.6.34-gnu1/arch/cris/arch-v32/drivers/sync_serial.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/drivers/sync_serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/drivers/sync_serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/errno.h>
 #include <linux/major.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/poll.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/kernel/entry.S linux-libre-2.6.34-gnu1/arch/cris/arch-v32/kernel/entry.S
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/kernel/entry.S	2010-05-16 17:17:36.000000000 -0400
@@ -615,7 +615,7 @@ sys_call_table:
 	.long sys_swapon
 	.long sys_reboot
 	.long sys_old_readdir
-	.long old_mmap		/* 90 */
+	.long sys_old_mmap	/* 90 */
 	.long sys_munmap
 	.long sys_truncate
 	.long sys_ftruncate
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/kernel/irq.c linux-libre-2.6.34-gnu1/arch/cris/arch-v32/kernel/irq.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/kernel/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -336,7 +336,7 @@ int set_affinity_crisv32_irq(unsigned in
 }
 
 static struct irq_chip crisv32_irq_type = {
-	.typename =    "CRISv32",
+	.name =        "CRISv32",
 	.startup =     startup_crisv32_irq,
 	.shutdown =    shutdown_crisv32_irq,
 	.enable =      enable_crisv32_irq,
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/kernel/pinmux.c linux-libre-2.6.34-gnu1/arch/cris/arch-v32/kernel/pinmux.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/kernel/pinmux.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/kernel/pinmux.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,7 +54,7 @@ crisv32_pinmux_alloc(int port, int first
 
 	crisv32_pinmux_init();
 
-	if (port > PORTS)
+	if (port > PORTS || port < 0)
 		return -EINVAL;
 
 	spin_lock_irqsave(&pinmux_lock, flags);
@@ -197,7 +197,7 @@ crisv32_pinmux_dealloc(int port, int fir
 
 	crisv32_pinmux_init();
 
-	if (port > PORTS)
+	if (port > PORTS || port < 0)
 		return -EINVAL;
 
 	spin_lock_irqsave(&pinmux_lock, flags);
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/kernel/process.c linux-libre-2.6.34-gnu1/arch/cris/arch-v32/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,9 +9,9 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/fs.h>
-#include <linux/slab.h>
 #include <hwregs/reg_rdwr.h>
 #include <hwregs/reg_map.h>
 #include <hwregs/timer_defs.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/cris/arch-v32/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -78,6 +78,35 @@ int put_reg(struct task_struct *task, un
 	return 0;
 }
 
+void user_enable_single_step(struct task_struct *child)
+{
+	unsigned long tmp;
+
+	/*
+	 * Set up SPC if not set already (in which case we have no other
+	 * choice but to trust it).
+	 */
+	if (!get_reg(child, PT_SPC)) {
+		/* In case we're stopped in a delay slot. */
+		tmp = get_reg(child, PT_ERP) & ~1;
+		put_reg(child, PT_SPC, tmp);
+	}
+	tmp = get_reg(child, PT_CCS) | SBIT_USER;
+	put_reg(child, PT_CCS, tmp);
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+	put_reg(child, PT_SPC, 0);
+
+	if (!get_debugreg(child->pid, PT_BP_CTRL)) {
+		unsigned long tmp;
+		/* If no h/w bp configured, disable S bit. */
+		tmp = get_reg(child, PT_CCS) & ~SBIT_USER;
+		put_reg(child, PT_CCS, tmp);
+	}
+}
+
 /*
  * Called by kernel/ptrace.c when detaching.
  *
@@ -89,8 +118,7 @@ ptrace_disable(struct task_struct *child
 	unsigned long tmp;
 
 	/* Deconfigure SPC and S-bit. */
-	tmp = get_reg(child, PT_CCS) & ~SBIT_USER;
-	put_reg(child, PT_CCS, tmp);
+	user_disable_single_step(child);
 	put_reg(child, PT_SPC, 0);
 
 	/* Deconfigure any watchpoints associated with the child. */
@@ -169,83 +197,6 @@ long arch_ptrace(struct task_struct *chi
 			ret = 0;
 			break;
 
-		case PTRACE_SYSCALL:
-		case PTRACE_CONT:
-			ret = -EIO;
-
-			if (!valid_signal(data))
-				break;
-
-			/* Continue means no single-step. */
-			put_reg(child, PT_SPC, 0);
-
-			if (!get_debugreg(child->pid, PT_BP_CTRL)) {
-				unsigned long tmp;
-				/* If no h/w bp configured, disable S bit. */
-				tmp = get_reg(child, PT_CCS) & ~SBIT_USER;
-				put_reg(child, PT_CCS, tmp);
-			}
-
-			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;
-
-			/* TODO: make sure any pending breakpoint is killed */
-			wake_up_process(child);
-			ret = 0;
-
-			break;
-
-		/* Make the child exit by sending it a sigkill. */
-		case PTRACE_KILL:
-			ret = 0;
-
-			if (child->exit_state == EXIT_ZOMBIE)
-				break;
-
-			child->exit_code = SIGKILL;
-
-			/* Deconfigure single-step and h/w bp. */
-			ptrace_disable(child);
-
-			/* TODO: make sure any pending breakpoint is killed */
-			wake_up_process(child);
-			break;
-
-		/* Set the trap flag. */
-		case PTRACE_SINGLESTEP:	{
-			unsigned long tmp;
-			ret = -EIO;
-
-			/* Set up SPC if not set already (in which case we have
-			   no other choice but to trust it). */
-			if (!get_reg(child, PT_SPC)) {
-				/* In case we're stopped in a delay slot. */
-				tmp = get_reg(child, PT_ERP) & ~1;
-				put_reg(child, PT_SPC, tmp);
-			}
-			tmp = get_reg(child, PT_CCS) | SBIT_USER;
-			put_reg(child, PT_CCS, tmp);
-
-			if (!valid_signal(data))
-				break;
-
-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-
-			/* TODO: set some clever breakpoint mechanism... */
-
-			child->exit_code = data;
-			wake_up_process(child);
-			ret = 0;
-			break;
-
-		}
-
 		/* Get all GP registers from the child. */
 		case PTRACE_GETREGS: {
 			int i;
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/kernel/signal.c linux-libre-2.6.34-gnu1/arch/cris/arch-v32/kernel/signal.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/kernel/signal.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/kernel/signal.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
 
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/errno.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/mach-a3/pinmux.c linux-libre-2.6.34-gnu1/arch/cris/arch-v32/mach-a3/pinmux.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/mach-a3/pinmux.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/mach-a3/pinmux.c	2010-05-16 17:17:36.000000000 -0400
@@ -242,7 +242,7 @@ crisv32_pinmux_dealloc(int port, int fir
 
 	crisv32_pinmux_init();
 
-	if (port > PORTS)
+	if (port > PORTS || port < 0)
 		return -EINVAL;
 
 	spin_lock_irqsave(&pinmux_lock, flags);
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/mach-fs/arbiter.c linux-libre-2.6.34-gnu1/arch/cris/arch-v32/mach-fs/arbiter.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/mach-fs/arbiter.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/mach-fs/arbiter.c	2010-05-16 17:17:36.000000000 -0400
@@ -332,7 +332,7 @@ int crisv32_arbiter_unwatch(int id)
 	if (id == 0)
 		intr_mask.bp0 = regk_marb_no;
 	else if (id == 1)
-		intr_mask.bp2 = regk_marb_no;
+		intr_mask.bp1 = regk_marb_no;
 	else if (id == 2)
 		intr_mask.bp2 = regk_marb_no;
 	else if (id == 3)
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/mach-fs/pinmux.c linux-libre-2.6.34-gnu1/arch/cris/arch-v32/mach-fs/pinmux.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/mach-fs/pinmux.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/mach-fs/pinmux.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,7 +54,7 @@ crisv32_pinmux_alloc(int port, int first
 
 	crisv32_pinmux_init();
 
-	if (port > PORTS)
+	if (port > PORTS || port < 0)
 		return -EINVAL;
 
 	spin_lock_irqsave(&pinmux_lock, flags);
@@ -195,7 +195,7 @@ int crisv32_pinmux_dealloc(int port, int
 
 	crisv32_pinmux_init();
 
-	if (port > PORTS)
+	if (port > PORTS || port < 0)
 		return -EINVAL;
 
 	spin_lock_irqsave(&pinmux_lock, flags);
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/mm/mmu.S linux-libre-2.6.34-gnu1/arch/cris/arch-v32/mm/mmu.S
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/mm/mmu.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/mm/mmu.S	2010-05-16 17:17:36.000000000 -0400
@@ -115,7 +115,7 @@
 #ifdef CONFIG_SMP
 	move    $s7, $acr	; PGD
 #else
-	move.d  per_cpu__current_pgd, $acr ; PGD
+	move.d  current_pgd, $acr ; PGD
 #endif
 	; Look up PMD in PGD
 	lsrq	24, $r0	; Get PMD index into PGD (bit 24-31)
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/arch-v32/mm/tlb.c linux-libre-2.6.34-gnu1/arch/cris/arch-v32/mm/tlb.c
--- linux-libre-2.6.33-gnu1/arch/cris/arch-v32/mm/tlb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/arch-v32/mm/tlb.c	2010-05-16 17:17:36.000000000 -0400
@@ -189,7 +189,7 @@ switch_mm(struct mm_struct *prev, struct
 		spin_unlock(&mmu_context_lock);
 
 		/*
-		 * Remember the pgd for the fault handlers. Keep a seperate
+		 * Remember the pgd for the fault handlers. Keep a separate
 		 * copy of it because current and active_mm might be invalid
 		 * at points where * there's still a need to derefer the pgd.
 		 */
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/include/arch-v32/arch/ptrace.h linux-libre-2.6.34-gnu1/arch/cris/include/arch-v32/arch/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/cris/include/arch-v32/arch/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/include/arch-v32/arch/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -108,6 +108,7 @@ struct switch_stack {
 
 #ifdef __KERNEL__
 
+#define arch_has_single_step() (1)
 #define user_mode(regs) (((regs)->ccs & (1 << (U_CCS_BITNR + CCS_SHIFT))) != 0)
 #define instruction_pointer(regs) ((regs)->erp)
 extern void show_regs(struct pt_regs *);
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/include/asm/pci.h linux-libre-2.6.34-gnu1/arch/cris/include/asm/pci.h
--- linux-libre-2.6.33-gnu1/arch/cris/include/asm/pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/include/asm/pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -44,14 +44,6 @@ struct pci_dev;
  */
 #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)
-
 #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);
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/include/asm/pgtable.h linux-libre-2.6.34-gnu1/arch/cris/include/asm/pgtable.h
--- linux-libre-2.6.33-gnu1/arch/cris/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -270,7 +270,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD
  * Actually I am not sure on what this could be used for.
  */
 static inline void update_mmu_cache(struct vm_area_struct * vma,
-	unsigned long address, pte_t pte)
+	unsigned long address, pte_t *ptep)
 {
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/include/asm/unistd.h linux-libre-2.6.34-gnu1/arch/cris/include/asm/unistd.h
--- linux-libre-2.6.33-gnu1/arch/cris/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/include/asm/unistd.h	2010-05-16 17:17:36.000000000 -0400
@@ -352,6 +352,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
@@ -364,6 +365,7 @@
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_MMAP
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/Kconfig linux-libre-2.6.34-gnu1/arch/cris/Kconfig
--- linux-libre-2.6.33-gnu1/arch/cris/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,12 @@ config RWSEM_GENERIC_SPINLOCK
 config RWSEM_XCHGADD_ALGORITHM
 	bool
 
+config GENERIC_TIME
+	def_bool y
+
+config ARCH_USES_GETTIMEOFFSET
+	def_bool y
+
 config GENERIC_IOMAP
        bool
        default y
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/kernel/irq.c linux-libre-2.6.34-gnu1/arch/cris/kernel/irq.c
--- linux-libre-2.6.33-gnu1/arch/cris/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/kernel/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,7 +29,6 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/init.h>
 #include <linux/seq_file.h>
@@ -63,7 +62,7 @@ int show_interrupts(struct seq_file *p,
 		for_each_online_cpu(j)
 			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
-		seq_printf(p, " %14s", irq_desc[i].chip->typename);
+		seq_printf(p, " %14s", 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.33-gnu1/arch/cris/kernel/module.c linux-libre-2.6.34-gnu1/arch/cris/kernel/module.c
--- linux-libre-2.6.33-gnu1/arch/cris/kernel/module.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/kernel/module.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #if 0
 #define DEBUGP printk
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/kernel/profile.c linux-libre-2.6.34-gnu1/arch/cris/kernel/profile.c
--- linux-libre-2.6.33-gnu1/arch/cris/kernel/profile.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/kernel/profile.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/kernel/sys_cris.c linux-libre-2.6.34-gnu1/arch/cris/kernel/sys_cris.c
--- linux-libre-2.6.33-gnu1/arch/cris/kernel/sys_cris.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/kernel/sys_cris.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,24 +26,6 @@
 #include <asm/uaccess.h>
 #include <asm/segment.h>
 
-asmlinkage unsigned long old_mmap(unsigned long __user *args)
-{        
-	unsigned long buffer[6];
-	int err = -EFAULT;
-
-	if (copy_from_user(&buffer, args, sizeof(buffer)))
-		goto out;
-
-	err = -EINVAL;
-	if (buffer[5] & ~PAGE_MASK) /* verify that offset is on page boundary */
-		goto out;
-
-	err = sys_mmap_pgoff(buffer[0], buffer[1], buffer[2], buffer[3],
-                       buffer[4], buffer[5] >> PAGE_SHIFT);
-out:
-	return err;
-}
-
 asmlinkage long
 sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
           unsigned long flags, unsigned long fd, unsigned long pgoff)
@@ -51,81 +33,3 @@ sys_mmap2(unsigned long addr, unsigned l
 	/* bug(?): 8Kb pages here */
         return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
 }
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly. (same as arch/i386)
- */
-
-asmlinkage int sys_ipc (uint call, int first, int second,
-			int third, void __user *ptr, long fifth)
-{
-	int version, ret;
-
-	version = call >> 16; /* hack for backward compatibility */
-	call &= 0xffff;
-
-	switch (call) {
-	case SEMOP:
-		return sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL);
-	case SEMTIMEDOP:
-		return sys_semtimedop(first, (struct sembuf __user *)ptr, second,
-					(const struct timespec __user *)fifth);
-
-	case SEMGET:
-		return sys_semget (first, second, third);
-	case SEMCTL: {
-		union semun fourth;
-		if (!ptr)
-			return -EINVAL;
-		if (get_user(fourth.__pad, (void * __user *) ptr))
-			return -EFAULT;
-		return sys_semctl (first, second, third, fourth);
-	}
-
-	case MSGSND:
-		return sys_msgsnd (first, (struct msgbuf __user *) ptr, 
-				   second, third);
-	case MSGRCV:
-		switch (version) {
-		case 0: {
-			struct ipc_kludge tmp;
-			if (!ptr)
-				return -EINVAL;
-			
-			if (copy_from_user(&tmp,
-					   (struct ipc_kludge __user *) ptr, 
-					   sizeof (tmp)))
-				return -EFAULT;
-			return sys_msgrcv (first, tmp.msgp, second,
-					   tmp.msgtyp, third);
-		}
-		default:
-			return sys_msgrcv (first,
-					   (struct msgbuf __user *) ptr,
-					   second, fifth, third);
-		}
-	case MSGGET:
-		return sys_msgget ((key_t) first, second);
-	case MSGCTL:
-		return sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
-
-	case SHMAT: {
-                ulong raddr;
-                ret = do_shmat (first, (char __user *) ptr, second, &raddr);
-                if (ret)
-                        return ret;
-                return put_user (raddr, (ulong __user *) third);
-        }
-	case SHMDT: 
-		return sys_shmdt ((char __user *)ptr);
-	case SHMGET:
-		return sys_shmget (first, second, third);
-	case SHMCTL:
-		return sys_shmctl (first, second,
-				   (struct shmid_ds __user *) ptr);
-	default:
-		return -ENOSYS;
-	}
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/kernel/time.c linux-libre-2.6.34-gnu1/arch/cris/kernel/time.c
--- linux-libre-2.6.33-gnu1/arch/cris/kernel/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/kernel/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,75 +42,11 @@ unsigned long loops_per_usec;
 extern unsigned long do_slow_gettimeoffset(void);
 static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
 
-/*
- * This version of gettimeofday has near microsecond resolution.
- *
- * Note: Division is quite slow on CRIS and do_gettimeofday is called
- *       rather often. Maybe we should do some kind of approximation here
- *       (a naive approximation would be to divide by 1024).
- */
-void do_gettimeofday(struct timeval *tv)
-{
-	unsigned long flags;
-	signed long usec, sec;
-	local_irq_save(flags);
-	usec = do_gettimeoffset();
-
-        /*
-	 * If time_adjust is negative then NTP is slowing the clock
-	 * so make sure not to go into next possible interval.
-	 * Better to lose some accuracy than have time go backwards..
-	 */
-	if (unlikely(time_adjust < 0) && usec > tickadj)
-		usec = tickadj;
-
-	sec = xtime.tv_sec;
-	usec += xtime.tv_nsec / 1000;
-	local_irq_restore(flags);
-
-	while (usec >= 1000000) {
-		usec -= 1000000;
-		sec++;
-	}
-
-	tv->tv_sec = sec;
-	tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
+u32 arch_gettimeoffset(void)
 {
-	time_t wtm_sec, sec = tv->tv_sec;
-	long wtm_nsec, nsec = tv->tv_nsec;
-
-	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-		return -EINVAL;
-
-	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!
-	 */
-	nsec -= do_gettimeoffset() * NSEC_PER_USEC;
-
-	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);
-	clock_was_set();
-	return 0;
+	return do_gettimeoffset() * 1000;
 }
 
-EXPORT_SYMBOL(do_settimeofday);
-
-
 /*
  * BUG: This routine does not handle hour overflow properly; it just
  *      sets the minutes. Usually you'll only notice that after reboot!
diff -druNp linux-libre-2.6.33-gnu1/arch/cris/mm/init.c linux-libre-2.6.34-gnu1/arch/cris/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/cris/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/cris/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  *
  */
 
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <asm/tlb.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/include/asm/dma-mapping.h linux-libre-2.6.34-gnu1/arch/frv/include/asm/dma-mapping.h
--- linux-libre-2.6.33-gnu1/arch/frv/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/include/asm/dma-mapping.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,11 @@
 #include <asm/scatterlist.h>
 #include <asm/io.h>
 
+/*
+ * See Documentation/DMA-API.txt for the description of how the
+ * following DMA API should work.
+ */
+
 #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)
 
@@ -16,24 +21,9 @@ extern unsigned long __nongprelbss dma_c
 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)
@@ -41,30 +31,9 @@ void dma_unmap_single(struct device *dev
 	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)
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/include/asm/pci.h linux-libre-2.6.34-gnu1/arch/frv/include/asm/pci.h
--- linux-libre-2.6.33-gnu1/arch/frv/include/asm/pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/include/asm/pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -43,14 +43,6 @@ extern void pci_free_consistent(struct p
 /* Return the index of the PCI controller for device PDEV. */
 #define pci_controller_num(PDEV)	(0)
 
-/* 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,
@@ -68,41 +60,4 @@ static inline void pci_dma_burst_advice(
 #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)
-{
-	BUG_ON(direction == PCI_DMA_NONE);
-
-	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;
-	BUG_ON(direction == PCI_DMA_NONE);
-
-	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 /* _ASM_FRV_PCI_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/include/asm/pgtable.h linux-libre-2.6.34-gnu1/arch/frv/include/asm/pgtable.h
--- linux-libre-2.6.33-gnu1/arch/frv/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -505,7 +505,7 @@ static inline int pte_file(pte_t pte)
 /*
  * 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)
+static inline void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
 	struct mm_struct *mm;
 	unsigned long ampr;
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/frv/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/frv/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -84,8 +84,6 @@ extern void show_regs(struct pt_regs *);
 #define task_pt_regs(task) ((task)->thread.frame0)
 
 #define arch_has_single_step()	(1)
-extern void user_enable_single_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
 
 #endif /* !__ASSEMBLY__ */
 #endif /* __KERNEL__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/include/asm/segment.h linux-libre-2.6.34-gnu1/arch/frv/include/asm/segment.h
--- linux-libre-2.6.33-gnu1/arch/frv/include/asm/segment.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/include/asm/segment.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,12 +21,12 @@ typedef struct {
 
 #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)
+#define KERNEL_DS		MAKE_MM_SEG(0xdfffffffUL)
 #else
-#define USER_DS			KERNEL_DS
+#define USER_DS			MAKE_MM_SEG(memory_end)
+#define KERNEL_DS		MAKE_MM_SEG(0xe0000000UL)
 #endif
 
 #define get_ds()		(KERNEL_DS)
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/include/asm/uaccess.h linux-libre-2.6.34-gnu1/arch/frv/include/asm/uaccess.h
--- linux-libre-2.6.33-gnu1/arch/frv/include/asm/uaccess.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/include/asm/uaccess.h	2010-05-16 17:17:36.000000000 -0400
@@ -27,8 +27,6 @@
 #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
  */
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/include/asm/unistd.h linux-libre-2.6.34-gnu1/arch/frv/include/asm/unistd.h
--- linux-libre-2.6.33-gnu1/arch/frv/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/include/asm/unistd.h	2010-05-16 17:17:36.000000000 -0400
@@ -354,6 +354,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 /* #define __ARCH_WANT_SYS_GETHOSTNAME */
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 /* #define __ARCH_WANT_SYS_SGETMASK */
 /* #define __ARCH_WANT_SYS_SIGNAL */
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/kernel/irq.c linux-libre-2.6.34-gnu1/arch/frv/kernel/irq.c
--- linux-libre-2.6.33-gnu1/arch/frv/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/kernel/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/kernel/sysctl.c linux-libre-2.6.34-gnu1/arch/frv/kernel/sysctl.c
--- linux-libre-2.6.33-gnu1/arch/frv/kernel/sysctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/kernel/sysctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,6 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/kernel/sys_frv.c linux-libre-2.6.34-gnu1/arch/frv/kernel/sys_frv.c
--- linux-libre-2.6.33-gnu1/arch/frv/kernel/sys_frv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/kernel/sys_frv.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,92 +42,3 @@ asmlinkage long sys_mmap2(unsigned long
 	return sys_mmap_pgoff(addr, len, prot, flags, fd,
 			      pgoff >> (PAGE_SHIFT - 12));
 }
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage long sys_ipc(unsigned long call,
-			unsigned long first,
-			unsigned long second,
-			unsigned long third,
-			void __user *ptr,
-			unsigned long fifth)
-{
-	int version, ret;
-
-	version = call >> 16; /* hack for backward compatibility */
-	call &= 0xffff;
-
-	switch (call) {
-	case SEMOP:
-		return sys_semtimedop(first, (struct sembuf __user *)ptr, second, NULL);
-	case SEMTIMEDOP:
-		return sys_semtimedop(first, (struct sembuf __user *)ptr, second,
-				      (const struct timespec __user *)fifth);
-
-	case SEMGET:
-		return sys_semget (first, second, third);
-	case SEMCTL: {
-		union semun fourth;
-		if (!ptr)
-			return -EINVAL;
-		if (get_user(fourth.__pad, (void * __user *) ptr))
-			return -EFAULT;
-		return sys_semctl (first, second, third, fourth);
-	}
-
-	case MSGSND:
-		return sys_msgsnd (first, (struct msgbuf __user *) ptr,
-				   second, third);
-	case MSGRCV:
-		switch (version) {
-		case 0: {
-			struct ipc_kludge tmp;
-			if (!ptr)
-				return -EINVAL;
-
-			if (copy_from_user(&tmp,
-					   (struct ipc_kludge __user *) ptr,
-					   sizeof (tmp)))
-				return -EFAULT;
-			return sys_msgrcv (first, tmp.msgp, second,
-					   tmp.msgtyp, third);
-		}
-		default:
-			return sys_msgrcv (first,
-					   (struct msgbuf __user *) ptr,
-					   second, fifth, third);
-		}
-	case MSGGET:
-		return sys_msgget ((key_t) first, second);
-	case MSGCTL:
-		return sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
-
-	case SHMAT:
-		switch (version) {
-		default: {
-			ulong raddr;
-			ret = do_shmat (first, (char __user *) ptr, second, &raddr);
-			if (ret)
-				return ret;
-			return put_user (raddr, (ulong __user *) third);
-		}
-		case 1:	/* iBCS2 emulator entry point */
-			if (!segment_eq(get_fs(), get_ds()))
-				return -EINVAL;
-			/* The "(ulong *) third" is valid _only_ because of the kernel segment thing */
-			return do_shmat (first, (char __user *) ptr, second, (ulong *) third);
-		}
-	case SHMDT:
-		return sys_shmdt ((char __user *)ptr);
-	case SHMGET:
-		return sys_shmget (first, second, third);
-	case SHMCTL:
-		return sys_shmctl (first, second,
-				   (struct shmid_ds __user *) ptr);
-	default:
-		return -ENOSYS;
-	}
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/mb93090-mb00/pci-dma.c linux-libre-2.6.34-gnu1/arch/frv/mb93090-mb00/pci-dma.c
--- linux-libre-2.6.33-gnu1/arch/frv/mb93090-mb00/pci-dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/mb93090-mb00/pci-dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include <linux/list.h>
 #include <linux/pci.h>
@@ -38,13 +37,6 @@ void dma_free_coherent(struct device *hw
 
 EXPORT_SYMBOL(dma_free_coherent);
 
-/*
- * 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.
- */
 dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
 			  enum dma_data_direction direction)
 {
@@ -57,22 +49,6 @@ dma_addr_t dma_map_single(struct device
 
 EXPORT_SYMBOL(dma_map_single);
 
-/*
- * Map a set of buffers described by scatterlist in streaming
- * mode for DMA.  This is the scather-gather version of the
- * above dma_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 dma_map_single are
- * the same here.
- */
 int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	       enum dma_data_direction direction)
 {
@@ -103,13 +79,6 @@ int dma_map_sg(struct device *dev, struc
 
 EXPORT_SYMBOL(dma_map_sg);
 
-/*
- * Map a single page of the indicated size for DMA in streaming mode.
- * The 32-bit bus address to use is returned.
- *
- * Device ownership issues as mentioned above for dma_map_single are
- * the same here.
- */
 dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
 			size_t size, enum dma_data_direction direction)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/mb93090-mb00/pci-dma-nommu.c linux-libre-2.6.34-gnu1/arch/frv/mb93090-mb00/pci-dma-nommu.c
--- linux-libre-2.6.33-gnu1/arch/frv/mb93090-mb00/pci-dma-nommu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/mb93090-mb00/pci-dma-nommu.c	2010-05-16 17:17:36.000000000 -0400
@@ -106,13 +106,6 @@ void dma_free_coherent(struct device *hw
 
 EXPORT_SYMBOL(dma_free_coherent);
 
-/*
- * 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 dma_unmap_single or pci_dma_sync_single is performed.
- */
 dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
 			  enum dma_data_direction direction)
 {
@@ -125,22 +118,6 @@ dma_addr_t dma_map_single(struct device
 
 EXPORT_SYMBOL(dma_map_single);
 
-/*
- * Map a set of buffers described by scatterlist in streaming
- * mode for DMA.  This is the scather-gather version of the
- * above dma_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 dma_map_single are
- * the same here.
- */
 int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	       enum dma_data_direction direction)
 {
@@ -157,13 +134,6 @@ int dma_map_sg(struct device *dev, struc
 
 EXPORT_SYMBOL(dma_map_sg);
 
-/*
- * Map a single page of the indicated size for DMA in streaming mode.
- * The 32-bit bus address to use is returned.
- *
- * Device ownership issues as mentioned above for dma_map_single are
- * the same here.
- */
 dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
 			size_t size, enum dma_data_direction direction)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/mb93090-mb00/pci-frv.c linux-libre-2.6.34-gnu1/arch/frv/mb93090-mb00/pci-frv.c
--- linux-libre-2.6.33-gnu1/arch/frv/mb93090-mb00/pci-frv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/mb93090-mb00/pci-frv.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,18 +32,16 @@
  * but we want to try to avoid allocating at 0x2900-0x2bff
  * which might have be mirrored at 0x0100-0x03ff..
  */
-void
-pcibios_align_resource(void *data, struct resource *res,
+resource_size_t
+pcibios_align_resource(void *data, const struct resource *res,
 		       resource_size_t size, resource_size_t align)
 {
-	if (res->flags & IORESOURCE_IO) {
-		resource_size_t start = res->start;
+	resource_size_t start = res->start;
 
-		if (start & 0x300) {
-			start = (start + 0x3ff) & ~0x3ff;
-			res->start = start;
-		}
-	}
+	if ((res->flags & IORESOURCE_IO) && (start & 0x300))
+		start = (start + 0x3ff) & ~0x3ff;
+
+	return start;
 }
 
 
@@ -96,8 +94,7 @@ static void __init pcibios_allocate_bus_
 				r = &dev->resource[idx];
 				if (!r->start)
 					continue;
-				if (pci_claim_resource(dev, idx) < 0)
-					printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev));
+				pci_claim_resource(dev, idx);
 			}
 		}
 		pcibios_allocate_bus_resources(&bus->children);
@@ -127,7 +124,6 @@ static void __init pcibios_allocate_reso
 				DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
 				    r->start, r->end, r->flags, disabled, pass);
 				if (pci_claim_resource(dev, idx) < 0) {
-					printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, pci_name(dev));
 					/* We'll assign a new address later */
 					r->end -= r->start;
 					r->start = 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/mb93090-mb00/pci-irq.c linux-libre-2.6.34-gnu1/arch/frv/mb93090-mb00/pci-irq.c
--- linux-libre-2.6.33-gnu1/arch/frv/mb93090-mb00/pci-irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/mb93090-mb00/pci-irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,6 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/mb93090-mb00/pci-vdk.c linux-libre-2.6.34-gnu1/arch/frv/mb93090-mb00/pci-vdk.c
--- linux-libre-2.6.33-gnu1/arch/frv/mb93090-mb00/pci-vdk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/mb93090-mb00/pci-vdk.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 
 #include <asm/segment.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/mm/dma-alloc.c linux-libre-2.6.34-gnu1/arch/frv/mm/dma-alloc.c
--- linux-libre-2.6.33-gnu1/arch/frv/mm/dma-alloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/mm/dma-alloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/hardirq.h>
+#include <linux/gfp.h>
 
 #include <asm/pgalloc.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/mm/init.c linux-libre-2.6.34-gnu1/arch/frv/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/frv/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/pagemap.h>
+#include <linux/gfp.h>
 #include <linux/swap.h>
 #include <linux/mm.h>
 #include <linux/kernel.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/frv/mm/pgalloc.c linux-libre-2.6.34-gnu1/arch/frv/mm/pgalloc.c
--- linux-libre-2.6.33-gnu1/arch/frv/mm/pgalloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/frv/mm/pgalloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,7 @@
  */
 
 #include <linux/sched.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/quicklist.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/h8300/include/asm/io.h linux-libre-2.6.34-gnu1/arch/h8300/include/asm/io.h
--- linux-libre-2.6.33-gnu1/arch/h8300/include/asm/io.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/h8300/include/asm/io.h	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,7 @@
  * memory location directly.
  */
 /* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
- * two accesses to memory, which may be undesireable for some devices.
+ * two accesses to memory, which may be undesirable for some devices.
  */
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/h8300/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/h8300/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/h8300/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/h8300/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -55,6 +55,8 @@ struct pt_regs {
 /* Find the stack offset for a register, relative to thread.esp0. */
 #define PT_REG(reg)	((long)&((struct pt_regs *)0)->reg)
 
+#define arch_has_single_step()	(1)
+
 #define user_mode(regs) (!((regs)->ccr & PS_S))
 #define instruction_pointer(regs) ((regs)->pc)
 #define profile_pc(regs) instruction_pointer(regs)
diff -druNp linux-libre-2.6.33-gnu1/arch/h8300/include/asm/unistd.h linux-libre-2.6.34-gnu1/arch/h8300/include/asm/unistd.h
--- linux-libre-2.6.33-gnu1/arch/h8300/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/h8300/include/asm/unistd.h	2010-05-16 17:17:36.000000000 -0400
@@ -336,6 +336,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
@@ -348,6 +349,8 @@
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_MMAP
+#define __ARCH_WANT_SYS_OLD_SELECT
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff -druNp linux-libre-2.6.33-gnu1/arch/h8300/kernel/process.c linux-libre-2.6.34-gnu1/arch/h8300/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/h8300/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/h8300/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,11 +32,11 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/interrupt.h>
 #include <linux/reboot.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/h8300/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/h8300/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/h8300/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/h8300/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,25 +34,20 @@
 /* cpu depend functions */
 extern long h8300_get_reg(struct task_struct *task, int regno);
 extern int  h8300_put_reg(struct task_struct *task, int regno, unsigned long data);
-extern void h8300_disable_trace(struct task_struct *child);
-extern void h8300_enable_trace(struct task_struct *child);
+
+
+void user_disable_single_step(struct task_struct *child)
+{
+}
 
 /*
  * does not yet catch signals sent when the child dies.
  * in exit.c or in signal.c.
  */
 
-inline
-static int read_long(struct task_struct * tsk, unsigned long addr,
-	unsigned long * result)
-{
-	*result = *(unsigned long *)addr;
-	return 0;
-}
-
 void ptrace_disable(struct task_struct *child)
 {
-	h8300_disable_trace(child);
+	user_disable_single_step(child);
 }
 
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -60,17 +55,6 @@ long arch_ptrace(struct task_struct *chi
 	int ret;
 
 	switch (request) {
-		case PTRACE_PEEKTEXT: /* read word at location addr. */ 
-		case PTRACE_PEEKDATA: {
-			unsigned long tmp;
-
-			ret = read_long(child, addr, &tmp);
-			if (ret < 0)
-				break ;
-			ret = put_user(tmp, (unsigned long *) data);
-			break ;
-		}
-
 	/* read the word at location addr in the USER area. */
 		case PTRACE_PEEKUSR: {
 			unsigned long tmp = 0;
@@ -109,11 +93,6 @@ long arch_ptrace(struct task_struct *chi
 		}
 
       /* when I and D space are separate, this will have to be fixed. */
-		case PTRACE_POKETEXT: /* write the word at location addr. */
-		case PTRACE_POKEDATA:
-			ret = generic_ptrace_pokedata(child, addr, data);
-			break;
-
 		case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
 			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) {
 				ret = -EIO;
@@ -131,53 +110,6 @@ long arch_ptrace(struct task_struct *chi
 			}
 			ret = -EIO;
 			break ;
-		case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
-		case PTRACE_CONT: { /* restart after signal. */
-			ret = -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;
-			wake_up_process(child);
-			/* make sure the single step bit is not set. */
-			h8300_disable_trace(child);
-			ret = 0;
-		}
-
-/*
- * 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: {
-
-			ret = 0;
-			if (child->exit_state == EXIT_ZOMBIE) /* already dead */
-				break;
-			child->exit_code = SIGKILL;
-			h8300_disable_trace(child);
-			wake_up_process(child);
-			break;
-		}
-
-		case PTRACE_SINGLESTEP: {  /* set the trap flag. */
-			ret = -EIO;
-			if (!valid_signal(data))
-				break;
-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-			child->exit_code = data;
-			h8300_enable_trace(child);
-			wake_up_process(child);
-			ret = 0;
-			break;
-		}
-
-		case PTRACE_DETACH:	/* detach a process that was attached. */
-			ret = ptrace_detach(child, data);
-			break;
 
 		case PTRACE_GETREGS: { /* Get all gp regs from the child. */
 		  	int i;
@@ -210,7 +142,7 @@ long arch_ptrace(struct task_struct *chi
 		}
 
 		default:
-			ret = -EIO;
+			ret = ptrace_request(child, request, addr, data);
 			break;
 	}
 	return ret;
diff -druNp linux-libre-2.6.33-gnu1/arch/h8300/kernel/syscalls.S linux-libre-2.6.34-gnu1/arch/h8300/kernel/syscalls.S
--- linux-libre-2.6.33-gnu1/arch/h8300/kernel/syscalls.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/h8300/kernel/syscalls.S	2010-05-16 17:17:36.000000000 -0400
@@ -96,7 +96,7 @@ SYMBOL_NAME_LABEL(sys_call_table)
 	.long SYMBOL_NAME(sys_settimeofday)
 	.long SYMBOL_NAME(sys_getgroups16)	/* 80 */
 	.long SYMBOL_NAME(sys_setgroups16)
-	.long SYMBOL_NAME(old_select)
+	.long SYMBOL_NAME(sys_old_select)
 	.long SYMBOL_NAME(sys_symlink)
 	.long SYMBOL_NAME(sys_lstat)
 	.long SYMBOL_NAME(sys_readlink)		/* 85 */
@@ -104,7 +104,7 @@ SYMBOL_NAME_LABEL(sys_call_table)
 	.long SYMBOL_NAME(sys_swapon)
 	.long SYMBOL_NAME(sys_reboot)
 	.long SYMBOL_NAME(sys_old_readdir)
-	.long SYMBOL_NAME(old_mmap)		/* 90 */
+	.long SYMBOL_NAME(sys_old_mmap)		/* 90 */
 	.long SYMBOL_NAME(sys_munmap)
 	.long SYMBOL_NAME(sys_truncate)
 	.long SYMBOL_NAME(sys_ftruncate)
diff -druNp linux-libre-2.6.33-gnu1/arch/h8300/kernel/sys_h8300.c linux-libre-2.6.34-gnu1/arch/h8300/kernel/sys_h8300.c
--- linux-libre-2.6.33-gnu1/arch/h8300/kernel/sys_h8300.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/h8300/kernel/sys_h8300.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,144 +26,6 @@
 #include <asm/traps.h>
 #include <asm/unistd.h>
 
-/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
- * handle more than 4 system call parameters, so these system calls
- * used a memory block for parameter passing..
- */
-
-struct mmap_arg_struct {
-	unsigned long addr;
-	unsigned long len;
-	unsigned long prot;
-	unsigned long flags;
-	unsigned long fd;
-	unsigned long offset;
-};
-
-asmlinkage int old_mmap(struct mmap_arg_struct *arg)
-{
-	struct mmap_arg_struct a;
-	int error = -EFAULT;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		goto out;
-
-	error = -EINVAL;
-	if (a.offset & ~PAGE_MASK)
-		goto out;
-
-	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
-			       a.offset >> PAGE_SHIFT);
-out:
-	return error;
-}
-
-struct sel_arg_struct {
-	unsigned long n;
-	fd_set *inp, *outp, *exp;
-	struct timeval *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	/* sys_select() does the appropriate kernel locking */
-	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-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;
-
-	if (call <= SEMCTL)
-		switch (call) {
-		case SEMOP:
-			return sys_semop (first, (struct sembuf *)ptr, second);
-		case SEMGET:
-			return sys_semget (first, second, third);
-		case SEMCTL: {
-			union semun fourth;
-			if (!ptr)
-				return -EINVAL;
-			if (get_user(fourth.__pad, (void **) ptr))
-				return -EFAULT;
-			return sys_semctl (first, second, third, fourth);
-			}
-		default:
-			return -EINVAL;
-		}
-	if (call <= MSGCTL) 
-		switch (call) {
-		case MSGSND:
-			return sys_msgsnd (first, (struct msgbuf *) ptr, 
-					  second, third);
-		case MSGRCV:
-			switch (version) {
-			case 0: {
-				struct ipc_kludge tmp;
-				if (!ptr)
-					return -EINVAL;
-				if (copy_from_user (&tmp,
-						    (struct ipc_kludge *)ptr,
-						    sizeof (tmp)))
-					return -EFAULT;
-				return sys_msgrcv (first, tmp.msgp, second,
-						   tmp.msgtyp, third);
-				}
-			default:
-				return sys_msgrcv (first,
-						   (struct msgbuf *) ptr,
-						   second, fifth, third);
-			}
-		case MSGGET:
-			return sys_msgget ((key_t) first, second);
-		case MSGCTL:
-			return sys_msgctl (first, second,
-					   (struct msqid_ds *) ptr);
-		default:
-			return -EINVAL;
-		}
-	if (call <= SHMCTL) 
-		switch (call) {
-		case SHMAT:
-			switch (version) {
-			default: {
-				ulong raddr;
-				ret = do_shmat (first, (char *) ptr,
-						 second, &raddr);
-				if (ret)
-					return ret;
-				return put_user (raddr, (ulong *) third);
-			}
-			}
-		case SHMDT: 
-			return sys_shmdt ((char *)ptr);
-		case SHMGET:
-			return sys_shmget (first, second, third);
-		case SHMCTL:
-			return sys_shmctl (first, second,
-					   (struct shmid_ds *) ptr);
-		default:
-			return -EINVAL;
-		}
-
-	return -EINVAL;
-}
-
 /* sys_cacheflush -- no support.  */
 asmlinkage int
 sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
diff -druNp linux-libre-2.6.33-gnu1/arch/h8300/mm/init.c linux-libre-2.6.34-gnu1/arch/h8300/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/h8300/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/h8300/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,7 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/bootmem.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 
 #include <asm/setup.h>
 #include <asm/segment.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/h8300/mm/kmap.c linux-libre-2.6.34-gnu1/arch/h8300/mm/kmap.c
--- linux-libre-2.6.33-gnu1/arch/h8300/mm/kmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/h8300/mm/kmap.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include <asm/setup.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/h8300/mm/memory.c linux-libre-2.6.34-gnu1/arch/h8300/mm/memory.c
--- linux-libre-2.6.33-gnu1/arch/h8300/mm/memory.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/h8300/mm/memory.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 
 #include <asm/setup.h>
 #include <asm/segment.h>
@@ -44,8 +43,8 @@ void cache_push_v (unsigned long vaddr,
 {
 }
 
-/* Map some physical address range into the kernel address space. The
- * code is copied and adapted from map_chunk().
+/*
+ * Map some physical address range into the kernel address space.
  */
 
 unsigned long kernel_map(unsigned long paddr, unsigned long size,
diff -druNp linux-libre-2.6.33-gnu1/arch/h8300/platform/h8300h/ptrace_h8300h.c linux-libre-2.6.34-gnu1/arch/h8300/platform/h8300h/ptrace_h8300h.c
--- linux-libre-2.6.33-gnu1/arch/h8300/platform/h8300h/ptrace_h8300h.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/h8300/platform/h8300h/ptrace_h8300h.c	2010-05-16 17:17:36.000000000 -0400
@@ -60,7 +60,7 @@ int h8300_put_reg(struct task_struct *ta
 }
 
 /* disable singlestep */
-void h8300_disable_trace(struct task_struct *child)
+void user_disable_single_step(struct task_struct *child)
 {
 	if((long)child->thread.breakinfo.addr != -1L) {
 		*child->thread.breakinfo.addr = child->thread.breakinfo.inst;
@@ -264,7 +264,7 @@ static unsigned short *getnextpc(struct
 
 /* Set breakpoint(s) to simulate a single step from the current PC.  */
 
-void h8300_enable_trace(struct task_struct *child)
+void user_enable_single_step(struct task_struct *child)
 {
 	unsigned short *nextpc;
 	nextpc = getnextpc(child,(unsigned short *)h8300_get_reg(child, PT_PC));
@@ -276,7 +276,7 @@ void h8300_enable_trace(struct task_stru
 asmlinkage void trace_trap(unsigned long bp)
 {
 	if ((unsigned long)current->thread.breakinfo.addr == bp) {
-		h8300_disable_trace(current);
+		user_disable_single_step(current);
 		force_sig(SIGTRAP,current);
 	} else
 	        force_sig(SIGILL,current);
diff -druNp linux-libre-2.6.33-gnu1/arch/h8300/platform/h8s/ptrace_h8s.c linux-libre-2.6.34-gnu1/arch/h8300/platform/h8s/ptrace_h8s.c
--- linux-libre-2.6.33-gnu1/arch/h8300/platform/h8s/ptrace_h8s.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/h8300/platform/h8s/ptrace_h8s.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,13 +65,13 @@ int h8300_put_reg(struct task_struct *ta
 }
 
 /* disable singlestep */
-void h8300_disable_trace(struct task_struct *child)
+void user_disable_single_step(struct task_struct *child)
 {
 	*(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) &= ~EXR_TRACE;
 }
 
 /* enable singlestep */
-void h8300_enable_trace(struct task_struct *child)
+void user_enable_single_step(struct task_struct *child)
 {
 	*(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) |= EXR_TRACE;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/configs/bigsur_defconfig linux-libre-2.6.34-gnu1/arch/ia64/configs/bigsur_defconfig
--- linux-libre-2.6.33-gnu1/arch/ia64/configs/bigsur_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/configs/bigsur_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -131,8 +131,6 @@ CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 # CONFIG_VIRTUAL_MEM_MAP is not set
-CONFIG_IA32_SUPPORT=y
-CONFIG_COMPAT=y
 # CONFIG_IA64_MCA_RECOVERY is not set
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/configs/generic_defconfig linux-libre-2.6.34-gnu1/arch/ia64/configs/generic_defconfig
--- linux-libre-2.6.33-gnu1/arch/ia64/configs/generic_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/configs/generic_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -205,8 +205,6 @@ CONFIG_VIRTUAL_MEM_MAP=y
 CONFIG_HOLES_IN_ZONE=y
 CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
 CONFIG_HAVE_ARCH_NODEDATA_EXTENSION=y
-CONFIG_IA32_SUPPORT=y
-CONFIG_COMPAT=y
 CONFIG_COMPAT_FOR_U64_ALIGNMENT=y
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/configs/gensparse_defconfig linux-libre-2.6.34-gnu1/arch/ia64/configs/gensparse_defconfig
--- linux-libre-2.6.33-gnu1/arch/ia64/configs/gensparse_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/configs/gensparse_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -139,8 +139,6 @@ CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
 CONFIG_NUMA=y
 CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
-CONFIG_IA32_SUPPORT=y
-CONFIG_COMPAT=y
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/configs/sim_defconfig linux-libre-2.6.34-gnu1/arch/ia64/configs/sim_defconfig
--- linux-libre-2.6.33-gnu1/arch/ia64/configs/sim_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/configs/sim_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -130,8 +130,6 @@ CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 # CONFIG_VIRTUAL_MEM_MAP is not set
-CONFIG_IA32_SUPPORT=y
-CONFIG_COMPAT=y
 # CONFIG_IA64_MCA_RECOVERY is not set
 # CONFIG_PERFMON is not set
 CONFIG_IA64_PALINFO=m
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/configs/tiger_defconfig linux-libre-2.6.34-gnu1/arch/ia64/configs/tiger_defconfig
--- linux-libre-2.6.33-gnu1/arch/ia64/configs/tiger_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/configs/tiger_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -154,7 +154,6 @@ CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_VIRTUAL_MEM_MAP=y
 CONFIG_HOLES_IN_ZONE=y
-# CONFIG_IA32_SUPPORT is not set
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/configs/xen_domu_defconfig linux-libre-2.6.34-gnu1/arch/ia64/configs/xen_domu_defconfig
--- linux-libre-2.6.33-gnu1/arch/ia64/configs/xen_domu_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/configs/xen_domu_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -200,8 +200,6 @@ CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_VIRTUAL_MEM_MAP=y
 CONFIG_HOLES_IN_ZONE=y
-# CONFIG_IA32_SUPPORT is not set
-# CONFIG_COMPAT_FOR_U64_ALIGNMENT is not set
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/configs/zx1_defconfig linux-libre-2.6.34-gnu1/arch/ia64/configs/zx1_defconfig
--- linux-libre-2.6.33-gnu1/arch/ia64/configs/zx1_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/configs/zx1_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -150,8 +150,6 @@ CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_VIRTUAL_MEM_MAP=y
 CONFIG_HOLES_IN_ZONE=y
-CONFIG_IA32_SUPPORT=y
-CONFIG_COMPAT=y
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/hp/common/aml_nfw.c linux-libre-2.6.34-gnu1/arch/ia64/hp/common/aml_nfw.c
--- linux-libre-2.6.33-gnu1/arch/ia64/hp/common/aml_nfw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/hp/common/aml_nfw.c	2010-05-16 17:17:36.000000000 -0400
@@ -77,7 +77,7 @@ static void aml_nfw_execute(struct ia64_
 		     c->arg[4], c->arg[5], c->arg[6], c->arg[7]);
 }
 
-static void aml_nfw_read_arg(u8 *offset, u32 bit_width, acpi_integer *value)
+static void aml_nfw_read_arg(u8 *offset, u32 bit_width, u64 *value)
 {
 	switch (bit_width) {
 	case 8:
@@ -95,7 +95,7 @@ static void aml_nfw_read_arg(u8 *offset,
 	}
 }
 
-static void aml_nfw_write_arg(u8 *offset, u32 bit_width, acpi_integer *value)
+static void aml_nfw_write_arg(u8 *offset, u32 bit_width, u64 *value)
 {
 	switch (bit_width) {
 	case 8:
@@ -114,7 +114,7 @@ static void aml_nfw_write_arg(u8 *offset
 }
 
 static acpi_status aml_nfw_handler(u32 function, acpi_physical_address address,
-	u32 bit_width, acpi_integer *value, void *handler_context,
+	u32 bit_width, u64 *value, void *handler_context,
 	void *region_context)
 {
 	struct ia64_nfw_context *context = handler_context;
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/ia32/audit.c linux-libre-2.6.34-gnu1/arch/ia64/ia32/audit.c
--- linux-libre-2.6.33-gnu1/arch/ia64/ia32/audit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/ia32/audit.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,42 +0,0 @@
-#include "../../x86/include/asm/unistd_32.h"
-
-unsigned ia32_dir_class[] = {
-#include <asm-generic/audit_dir_write.h>
-~0U
-};
-
-unsigned ia32_chattr_class[] = {
-#include <asm-generic/audit_change_attr.h>
-~0U
-};
-
-unsigned ia32_write_class[] = {
-#include <asm-generic/audit_write.h>
-~0U
-};
-
-unsigned ia32_read_class[] = {
-#include <asm-generic/audit_read.h>
-~0U
-};
-
-unsigned ia32_signal_class[] = {
-#include <asm-generic/audit_signal.h>
-~0U
-};
-
-int ia32_classify_syscall(unsigned syscall)
-{
-	switch(syscall) {
-	case __NR_open:
-		return 2;
-	case __NR_openat:
-		return 3;
-	case __NR_socketcall:
-		return 4;
-	case __NR_execve:
-		return 5;
-	default:
-		return 1;
-	}
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/ia32/binfmt_elf32.c linux-libre-2.6.34-gnu1/arch/ia64/ia32/binfmt_elf32.c
--- linux-libre-2.6.33-gnu1/arch/ia64/ia32/binfmt_elf32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/ia32/binfmt_elf32.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,245 +0,0 @@
-/*
- * IA-32 ELF support.
- *
- * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
- * Copyright (C) 2001 Hewlett-Packard Co
- *	David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * 06/16/00	A. Mallick	initialize csd/ssd/tssd/cflg for ia32_load_state
- * 04/13/01	D. Mosberger	dropped saving tssd in ar.k1---it's not needed
- * 09/14/01	D. Mosberger	fixed memory management for gdt/tss page
- */
-
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/security.h>
-
-#include <asm/param.h>
-#include <asm/signal.h>
-
-#include "ia32priv.h"
-#include "elfcore32.h"
-
-/* Override some function names */
-#undef start_thread
-#define start_thread			ia32_start_thread
-#define elf_format			elf32_format
-#define init_elf_binfmt			init_elf32_binfmt
-#define exit_elf_binfmt			exit_elf32_binfmt
-
-#undef CLOCKS_PER_SEC
-#define CLOCKS_PER_SEC	IA32_CLOCKS_PER_SEC
-
-extern void ia64_elf32_init (struct pt_regs *regs);
-
-static void elf32_set_personality (void);
-
-static unsigned long __attribute ((unused))
-randomize_stack_top(unsigned long stack_top);
-
-#define setup_arg_pages(bprm,tos,exec)		ia32_setup_arg_pages(bprm,exec)
-#define elf_map				elf32_map
-
-#undef SET_PERSONALITY
-#define SET_PERSONALITY(ex)	elf32_set_personality()
-
-#define elf_read_implies_exec(ex, have_pt_gnu_stack)	(!(have_pt_gnu_stack))
-
-/* Ugly but avoids duplication */
-#include "../../../fs/binfmt_elf.c"
-
-extern struct page *ia32_shared_page[];
-extern unsigned long *ia32_gdt;
-extern struct page *ia32_gate_page;
-
-int
-ia32_install_shared_page (struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-	vmf->page = ia32_shared_page[smp_processor_id()];
-	get_page(vmf->page);
-	return 0;
-}
-
-int
-ia32_install_gate_page (struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-	vmf->page = ia32_gate_page;
-	get_page(vmf->page);
-	return 0;
-}
-
-
-static const struct vm_operations_struct ia32_shared_page_vm_ops = {
-	.fault = ia32_install_shared_page
-};
-
-static const struct vm_operations_struct ia32_gate_page_vm_ops = {
-	.fault = ia32_install_gate_page
-};
-
-void
-ia64_elf32_init (struct pt_regs *regs)
-{
-	struct vm_area_struct *vma;
-
-	/*
-	 * Map GDT below 4GB, where the processor can find it.  We need to map
-	 * it with privilege level 3 because the IVE uses non-privileged accesses to these
-	 * tables.  IA-32 segmentation is used to protect against IA-32 accesses to them.
-	 */
-	vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
-	if (vma) {
-		vma->vm_mm = current->mm;
-		vma->vm_start = IA32_GDT_OFFSET;
-		vma->vm_end = vma->vm_start + PAGE_SIZE;
-		vma->vm_page_prot = PAGE_SHARED;
-		vma->vm_flags = VM_READ|VM_MAYREAD|VM_RESERVED;
-		vma->vm_ops = &ia32_shared_page_vm_ops;
-		down_write(&current->mm->mmap_sem);
-		{
-			if (insert_vm_struct(current->mm, vma)) {
-				kmem_cache_free(vm_area_cachep, vma);
-				up_write(&current->mm->mmap_sem);
-				BUG();
-			}
-		}
-		up_write(&current->mm->mmap_sem);
-	}
-
-	/*
-	 * When user stack is not executable, push sigreturn code to stack makes
-	 * segmentation fault raised when returning to kernel. So now sigreturn
-	 * code is locked in specific gate page, which is pointed by pretcode
-	 * when setup_frame_ia32
-	 */
-	vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
-	if (vma) {
-		vma->vm_mm = current->mm;
-		vma->vm_start = IA32_GATE_OFFSET;
-		vma->vm_end = vma->vm_start + PAGE_SIZE;
-		vma->vm_page_prot = PAGE_COPY_EXEC;
-		vma->vm_flags = VM_READ | VM_MAYREAD | VM_EXEC
-				| VM_MAYEXEC | VM_RESERVED;
-		vma->vm_ops = &ia32_gate_page_vm_ops;
-		down_write(&current->mm->mmap_sem);
-		{
-			if (insert_vm_struct(current->mm, vma)) {
-				kmem_cache_free(vm_area_cachep, vma);
-				up_write(&current->mm->mmap_sem);
-				BUG();
-			}
-		}
-		up_write(&current->mm->mmap_sem);
-	}
-
-	/*
-	 * Install LDT as anonymous memory.  This gives us all-zero segment descriptors
-	 * until a task modifies them via modify_ldt().
-	 */
-	vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
-	if (vma) {
-		vma->vm_mm = current->mm;
-		vma->vm_start = IA32_LDT_OFFSET;
-		vma->vm_end = vma->vm_start + PAGE_ALIGN(IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE);
-		vma->vm_page_prot = PAGE_SHARED;
-		vma->vm_flags = VM_READ|VM_WRITE|VM_MAYREAD|VM_MAYWRITE;
-		down_write(&current->mm->mmap_sem);
-		{
-			if (insert_vm_struct(current->mm, vma)) {
-				kmem_cache_free(vm_area_cachep, vma);
-				up_write(&current->mm->mmap_sem);
-				BUG();
-			}
-		}
-		up_write(&current->mm->mmap_sem);
-	}
-
-	ia64_psr(regs)->ac = 0;		/* turn off alignment checking */
-	regs->loadrs = 0;
-	/*
-	 *  According to the ABI %edx points to an `atexit' handler.  Since we don't have
-	 *  one we'll set it to 0 and initialize all the other registers just to make
-	 *  things more deterministic, ala the i386 implementation.
-	 */
-	regs->r8 = 0;	/* %eax */
-	regs->r11 = 0;	/* %ebx */
-	regs->r9 = 0;	/* %ecx */
-	regs->r10 = 0;	/* %edx */
-	regs->r13 = 0;	/* %ebp */
-	regs->r14 = 0;	/* %esi */
-	regs->r15 = 0;	/* %edi */
-
-	current->thread.eflag = IA32_EFLAG;
-	current->thread.fsr = IA32_FSR_DEFAULT;
-	current->thread.fcr = IA32_FCR_DEFAULT;
-	current->thread.fir = 0;
-	current->thread.fdr = 0;
-
-	/*
-	 * Setup GDTD.  Note: GDTD is the descrambled version of the pseudo-descriptor
-	 * format defined by Figure 3-11 "Pseudo-Descriptor Format" in the IA-32
-	 * architecture manual. Also note that the only fields that are not ignored are
-	 * `base', `limit', 'G', `P' (must be 1) and `S' (must be 0).
-	 */
-	regs->r31 = IA32_SEG_UNSCRAMBLE(IA32_SEG_DESCRIPTOR(IA32_GDT_OFFSET, IA32_PAGE_SIZE - 1,
-							    0, 0, 0, 1, 0, 0, 0));
-	/* Setup the segment selectors */
-	regs->r16 = (__USER_DS << 16) | __USER_DS; /* ES == DS, GS, FS are zero */
-	regs->r17 = (__USER_DS << 16) | __USER_CS; /* SS, CS; ia32_load_state() sets TSS and LDT */
-
-	ia32_load_segment_descriptors(current);
-	ia32_load_state(current);
-}
-
-/*
- * Undo the override of setup_arg_pages() without this ia32_setup_arg_pages()
- * will suffer infinite self recursion.
- */
-#undef setup_arg_pages
-
-int
-ia32_setup_arg_pages (struct linux_binprm *bprm, int executable_stack)
-{
-	int ret;
-
-	ret = setup_arg_pages(bprm, IA32_STACK_TOP, executable_stack);
-	if (!ret) {
-		/*
-		 * Can't do it in ia64_elf32_init(). Needs to be done before
-		 * calls to elf32_map()
-		 */
-		current->thread.ppl = ia32_init_pp_list();
-	}
-
-	return ret;
-}
-
-static void
-elf32_set_personality (void)
-{
-	set_personality(PER_LINUX32);
-	current->thread.map_base  = IA32_PAGE_OFFSET/3;
-}
-
-static unsigned long
-elf32_map(struct file *filep, unsigned long addr, struct elf_phdr *eppnt,
-		int prot, int type, unsigned long unused)
-{
-	unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK;
-
-	return ia32_do_mmap(filep, (addr & IA32_PAGE_MASK), eppnt->p_filesz + pgoff, prot, type,
-			    eppnt->p_offset - pgoff);
-}
-
-#define cpu_uses_ia32el()	(local_cpu_data->family > 0x1f)
-
-static int __init check_elf32_binfmt(void)
-{
-	if (cpu_uses_ia32el()) {
-		printk("Please use IA-32 EL for executing IA-32 binaries\n");
-		unregister_binfmt(&elf_format);
-	}
-	return 0;
-}
-
-module_init(check_elf32_binfmt)
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/ia32/elfcore32.h linux-libre-2.6.34-gnu1/arch/ia64/ia32/elfcore32.h
--- linux-libre-2.6.33-gnu1/arch/ia64/ia32/elfcore32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/ia32/elfcore32.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,148 +0,0 @@
-/*
- * IA-32 ELF core dump support.
- *
- * Copyright (C) 2003 Arun Sharma <arun.sharma@intel.com>
- *
- * Derived from the x86_64 version
- */
-#ifndef _ELFCORE32_H_
-#define _ELFCORE32_H_
-
-#include <asm/intrinsics.h>
-#include <asm/uaccess.h>
-
-/* Override elfcore.h */
-#define _LINUX_ELFCORE_H 1
-typedef unsigned int elf_greg_t;
-
-#define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct ia32_user_i387_struct elf_fpregset_t;
-typedef struct ia32_user_fxsr_struct elf_fpxregset_t;
-
-struct elf_siginfo
-{
-	int	si_signo;			/* signal number */
-	int	si_code;			/* extra code */
-	int	si_errno;			/* errno */
-};
-
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING
-/*
- * Hacks are here since types between compat_timeval (= pair of s32) and
- * ia64-native timeval (= pair of s64) are not compatible, at least a file
- * arch/ia64/ia32/../../../fs/binfmt_elf.c will get warnings from compiler on
- * use of cputime_to_timeval(), which usually an alias of jiffies_to_timeval().
- */
-#define cputime_to_timeval(a,b) \
-	do { (b)->tv_usec = 0; (b)->tv_sec = (a)/NSEC_PER_SEC; } while(0)
-#else
-#define jiffies_to_timeval(a,b) \
-	do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; } while(0)
-#endif
-
-struct elf_prstatus
-{
-	struct elf_siginfo pr_info;	/* Info associated with signal */
-	short	pr_cursig;		/* Current signal */
-	unsigned int pr_sigpend;	/* Set of pending signals */
-	unsigned int pr_sighold;	/* Set of held signals */
-	pid_t	pr_pid;
-	pid_t	pr_ppid;
-	pid_t	pr_pgrp;
-	pid_t	pr_sid;
-	struct compat_timeval pr_utime;	/* User time */
-	struct compat_timeval pr_stime;	/* System time */
-	struct compat_timeval pr_cutime;	/* Cumulative user time */
-	struct compat_timeval pr_cstime;	/* Cumulative system time */
-	elf_gregset_t pr_reg;	/* GP registers */
-	int pr_fpvalid;		/* True if math co-processor being used.  */
-};
-
-#define ELF_PRARGSZ	(80)	/* Number of chars for args */
-
-struct elf_prpsinfo
-{
-	char	pr_state;	/* numeric process state */
-	char	pr_sname;	/* char for pr_state */
-	char	pr_zomb;	/* zombie */
-	char	pr_nice;	/* nice val */
-	unsigned int pr_flag;	/* flags */
-	__u16	pr_uid;
-	__u16	pr_gid;
-	pid_t	pr_pid, pr_ppid, pr_pgrp, pr_sid;
-	/* Lots missing */
-	char	pr_fname[16];	/* filename of executable */
-	char	pr_psargs[ELF_PRARGSZ];	/* initial part of arg list */
-};
-
-#define ELF_CORE_COPY_REGS(pr_reg, regs)       		\
-	pr_reg[0] = regs->r11;				\
-	pr_reg[1] = regs->r9;				\
-	pr_reg[2] = regs->r10;				\
-	pr_reg[3] = regs->r14;				\
-	pr_reg[4] = regs->r15;				\
-	pr_reg[5] = regs->r13;				\
-	pr_reg[6] = regs->r8;				\
-	pr_reg[7] = regs->r16 & 0xffff;			\
-	pr_reg[8] = (regs->r16 >> 16) & 0xffff;		\
-	pr_reg[9] = (regs->r16 >> 32) & 0xffff;		\
-	pr_reg[10] = (regs->r16 >> 48) & 0xffff;	\
-	pr_reg[11] = regs->r1; 				\
-	pr_reg[12] = regs->cr_iip;			\
-	pr_reg[13] = regs->r17 & 0xffff;		\
-	pr_reg[14] = ia64_getreg(_IA64_REG_AR_EFLAG);	\
-	pr_reg[15] = regs->r12;				\
-	pr_reg[16] = (regs->r17 >> 16) & 0xffff;
-
-static inline void elf_core_copy_regs(elf_gregset_t *elfregs,
-				      struct pt_regs *regs)
-{
-	ELF_CORE_COPY_REGS((*elfregs), regs)
-}
-
-static inline int elf_core_copy_task_regs(struct task_struct *t,
-					  elf_gregset_t* elfregs)
-{
-	ELF_CORE_COPY_REGS((*elfregs), task_pt_regs(t));
-	return 1;
-}
-
-static inline int
-elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpregset_t *fpu)
-{
-	struct ia32_user_i387_struct *fpstate = (void*)fpu;
-	mm_segment_t old_fs;
-
-	if (!tsk_used_math(tsk))
-		return 0;
-	
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	save_ia32_fpstate(tsk, (struct ia32_user_i387_struct __user *) fpstate);
-	set_fs(old_fs);
-
-	return 1;
-}
-
-#define ELF_CORE_COPY_XFPREGS 1
-#define ELF_CORE_XFPREG_TYPE NT_PRXFPREG
-static inline int
-elf_core_copy_task_xfpregs(struct task_struct *tsk, elf_fpxregset_t *xfpu)
-{
-	struct ia32_user_fxsr_struct *fpxstate = (void*) xfpu;
-	mm_segment_t old_fs;
-
-	if (!tsk_used_math(tsk))
-		return 0;
-
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	save_ia32_fpxstate(tsk, (struct ia32_user_fxsr_struct __user *) fpxstate);
-	set_fs(old_fs);
-
-	return 1;
-}
-
-#endif /* _ELFCORE32_H_ */
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/ia32/ia32_entry.S linux-libre-2.6.34-gnu1/arch/ia64/ia32/ia32_entry.S
--- linux-libre-2.6.33-gnu1/arch/ia64/ia32/ia32_entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/ia32/ia32_entry.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,468 +0,0 @@
-#include <asm/asmmacro.h>
-#include <asm/ia32.h>
-#include <asm/asm-offsets.h>
-#include <asm/signal.h>
-#include <asm/thread_info.h>
-
-#include "../kernel/minstate.h"
-
-	/*
-	 * execve() is special because in case of success, we need to
-	 * setup a null register window frame (in case an IA-32 process
-	 * is exec'ing an IA-64 program).
-	 */
-ENTRY(ia32_execve)
-	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3)
-	alloc loc1=ar.pfs,3,2,4,0
-	mov loc0=rp
-	.body
-	zxt4 out0=in0			// filename
-	;;				// stop bit between alloc and call
-	zxt4 out1=in1			// argv
-	zxt4 out2=in2			// envp
-	add out3=16,sp			// regs
-	br.call.sptk.few rp=sys32_execve
-1:	cmp.ge p6,p0=r8,r0
-	mov ar.pfs=loc1			// restore ar.pfs
-	;;
-(p6)	mov ar.pfs=r0			// clear ar.pfs in case of success
-	sxt4 r8=r8			// return 64-bit result
-	mov rp=loc0
-	br.ret.sptk.few rp
-END(ia32_execve)
-
-ENTRY(ia32_clone)
-	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
-	alloc r16=ar.pfs,5,2,6,0
-	DO_SAVE_SWITCH_STACK
-	mov loc0=rp
-	mov loc1=r16				// save ar.pfs across do_fork
-	.body
-	zxt4 out1=in1				// newsp
-	mov out3=16				// stacksize (compensates for 16-byte scratch area)
-	adds out2=IA64_SWITCH_STACK_SIZE+16,sp	// out2 = &regs
-	mov out0=in0				// out0 = clone_flags
-	zxt4 out4=in2				// out4 = parent_tidptr
-	zxt4 out5=in4				// out5 = child_tidptr
-	br.call.sptk.many rp=do_fork
-.ret0:	.restore sp
-	adds sp=IA64_SWITCH_STACK_SIZE,sp	// pop the switch stack
-	mov ar.pfs=loc1
-	mov rp=loc0
-	br.ret.sptk.many rp
-END(ia32_clone)
-
-GLOBAL_ENTRY(ia32_ret_from_clone)
-	PT_REGS_UNWIND_INFO(0)
-{	/*
-	 * Some versions of gas generate bad unwind info if the first instruction of a
-	 * procedure doesn't go into the first slot of a bundle.  This is a workaround.
-	 */
-	nop.m 0
-	nop.i 0
-	/*
-	 * We need to call schedule_tail() to complete the scheduling process.
-	 * Called by ia64_switch_to after do_fork()->copy_thread().  r8 contains the
-	 * address of the previously executing task.
-	 */
-	br.call.sptk.many rp=ia64_invoke_schedule_tail
-}
-.ret1:
-	adds r2=TI_FLAGS+IA64_TASK_SIZE,r13
-	;;
-	ld4 r2=[r2]
-	;;
-	mov r8=0
-	and r2=_TIF_SYSCALL_TRACEAUDIT,r2
-	;;
-	cmp.ne p6,p0=r2,r0
-(p6)	br.cond.spnt .ia32_strace_check_retval
-	;;					// prevent RAW on r8
-END(ia32_ret_from_clone)
-	// fall through
-GLOBAL_ENTRY(ia32_ret_from_syscall)
-	PT_REGS_UNWIND_INFO(0)
-
-	cmp.ge p6,p7=r8,r0                      // syscall executed successfully?
-	adds r2=IA64_PT_REGS_R8_OFFSET+16,sp    // r2 = &pt_regs.r8
-	;;
-	alloc r3=ar.pfs,0,0,0,0			// drop the syscall argument frame
-	st8 [r2]=r8                             // store return value in slot for r8
-	br.cond.sptk.many ia64_leave_kernel
-END(ia32_ret_from_syscall)
-
-	//
-	// Invoke a system call, but do some tracing before and after the call.
-	// We MUST preserve the current register frame throughout this routine
-	// because some system calls (such as ia64_execve) directly
-	// manipulate ar.pfs.
-	//
-	// Input:
-	//	r8 = syscall number
-	//	b6 = syscall entry point
-	//
-GLOBAL_ENTRY(ia32_trace_syscall)
-	PT_REGS_UNWIND_INFO(0)
-	mov r3=-38
-	adds r2=IA64_PT_REGS_R8_OFFSET+16,sp
-	;;
-	st8 [r2]=r3				// initialize return code to -ENOSYS
-	br.call.sptk.few rp=syscall_trace_enter	// give parent a chance to catch syscall args
-	cmp.lt p6,p0=r8,r0			// check tracehook
-	adds r2=IA64_PT_REGS_R8_OFFSET+16,sp	// r2 = &pt_regs.r8
-	;;
-(p6)	st8.spill [r2]=r8			// store return value in slot for r8
-(p6)	br.spnt.few .ret4
-.ret2:	// Need to reload arguments (they may be changed by the tracing process)
-	adds r2=IA64_PT_REGS_R1_OFFSET+16,sp	// r2 = &pt_regs.r1
-	adds r3=IA64_PT_REGS_R13_OFFSET+16,sp	// r3 = &pt_regs.r13
-	mov r15=IA32_NR_syscalls
-	;;
-	ld4 r8=[r2],IA64_PT_REGS_R9_OFFSET-IA64_PT_REGS_R1_OFFSET
-	movl r16=ia32_syscall_table
-	;;
-	ld4 r33=[r2],8				// r9 == ecx
-	ld4 r37=[r3],16				// r13 == ebp
-	cmp.ltu.unc p6,p7=r8,r15
-	;;
-	ld4 r34=[r2],8				// r10 == edx
-	ld4 r36=[r3],8				// r15 == edi
-(p6)	shladd r16=r8,3,r16	// force ni_syscall if not valid syscall number
-	;;
-	ld8 r16=[r16]
-	;;
-	ld4 r32=[r2],8				// r11 == ebx
-	mov b6=r16
-	ld4 r35=[r3],8				// r14 == esi
-	br.call.sptk.few rp=b6			// do the syscall
-.ia32_strace_check_retval:
-	cmp.lt p6,p0=r8,r0			// syscall failed?
-	adds r2=IA64_PT_REGS_R8_OFFSET+16,sp	// r2 = &pt_regs.r8
-	;;
-	st8.spill [r2]=r8			// store return value in slot for r8
-	br.call.sptk.few rp=syscall_trace_leave	// give parent a chance to catch return value
-.ret4:	alloc r2=ar.pfs,0,0,0,0			// drop the syscall argument frame
-	br.cond.sptk.many ia64_leave_kernel
-END(ia32_trace_syscall)
-
-GLOBAL_ENTRY(sys32_vfork)
-	alloc r16=ar.pfs,2,2,4,0;;
-	mov out0=IA64_CLONE_VFORK|IA64_CLONE_VM|SIGCHLD	// out0 = clone_flags
-	br.cond.sptk.few .fork1			// do the work
-END(sys32_vfork)
-
-GLOBAL_ENTRY(sys32_fork)
-	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
-	alloc r16=ar.pfs,2,2,4,0
-	mov out0=SIGCHLD			// out0 = clone_flags
-	;;
-.fork1:
-	mov loc0=rp
-	mov loc1=r16				// save ar.pfs across do_fork
-	DO_SAVE_SWITCH_STACK
-
-	.body
-
-	mov out1=0
-	mov out3=0
-	adds out2=IA64_SWITCH_STACK_SIZE+16,sp	// out2 = &regs
-	br.call.sptk.few rp=do_fork
-.ret5:	.restore sp
-	adds sp=IA64_SWITCH_STACK_SIZE,sp	// pop the switch stack
-	mov ar.pfs=loc1
-	mov rp=loc0
-	br.ret.sptk.many rp
-END(sys32_fork)
-
-	.rodata
-	.align 8
-	.globl ia32_syscall_table
-ia32_syscall_table:
-	data8 sys_ni_syscall	  /* 0	-  old "setup(" system call*/
-	data8 sys_exit
-	data8 sys32_fork
-	data8 sys_read
-	data8 sys_write
-	data8 compat_sys_open	  /* 5 */
-	data8 sys_close
-	data8 sys32_waitpid
-	data8 sys_creat
-	data8 sys_link
-	data8 sys_unlink	  /* 10 */
-	data8 ia32_execve
-	data8 sys_chdir
-	data8 compat_sys_time
-	data8 sys_mknod
-	data8 sys_chmod		  /* 15 */
-	data8 sys_lchown	/* 16-bit version */
-	data8 sys_ni_syscall	  /* old break syscall holder */
-	data8 sys_ni_syscall
-	data8 sys32_lseek
-	data8 sys_getpid	  /* 20 */
-	data8 compat_sys_mount
-	data8 sys_oldumount
-	data8 sys_setuid	/* 16-bit version */
-	data8 sys_getuid	/* 16-bit version */
-	data8 compat_sys_stime    /* 25 */
-	data8 compat_sys_ptrace
-	data8 sys32_alarm
-	data8 sys_ni_syscall
-	data8 sys_pause
-	data8 compat_sys_utime	  /* 30 */
-	data8 sys_ni_syscall	  /* old stty syscall holder */
-	data8 sys_ni_syscall	  /* old gtty syscall holder */
-	data8 sys_access
-	data8 sys_nice
-	data8 sys_ni_syscall	  /* 35 */	  /* old ftime syscall holder */
-	data8 sys_sync
-	data8 sys_kill
-	data8 sys_rename
-	data8 sys_mkdir
-	data8 sys_rmdir		  /* 40 */
-	data8 sys_dup
-	data8 sys_ia64_pipe
-	data8 compat_sys_times
-	data8 sys_ni_syscall	  /* old prof syscall holder */
-	data8 sys32_brk		  /* 45 */
-	data8 sys_setgid	/* 16-bit version */
-	data8 sys_getgid	/* 16-bit version */
-	data8 sys32_signal
-	data8 sys_geteuid	/* 16-bit version */
-	data8 sys_getegid	/* 16-bit version */	  /* 50 */
-	data8 sys_acct
-	data8 sys_umount	  /* recycled never used phys( */
-	data8 sys_ni_syscall	  /* old lock syscall holder */
-	data8 compat_sys_ioctl
-	data8 compat_sys_fcntl	  /* 55 */
-	data8 sys_ni_syscall	  /* old mpx syscall holder */
-	data8 sys_setpgid
-	data8 sys_ni_syscall	  /* old ulimit syscall holder */
-	data8 sys_ni_syscall
-	data8 sys_umask		  /* 60 */
-	data8 sys_chroot
-	data8 compat_sys_ustat
-	data8 sys_dup2
-	data8 sys_getppid
-	data8 sys_getpgrp	  /* 65 */
-	data8 sys_setsid
-	data8 sys32_sigaction
-	data8 sys_ni_syscall
-	data8 sys_ni_syscall
-	data8 sys_setreuid	/* 16-bit version */	  /* 70 */
-	data8 sys_setregid	/* 16-bit version */
-	data8 sys32_sigsuspend
-	data8 compat_sys_sigpending
-	data8 sys_sethostname
-	data8 compat_sys_setrlimit	  /* 75 */
-	data8 compat_sys_old_getrlimit
-	data8 compat_sys_getrusage
-	data8 compat_sys_gettimeofday
-	data8 compat_sys_settimeofday
-	data8 sys32_getgroups16	  /* 80 */
-	data8 sys32_setgroups16
-	data8 sys32_old_select
-	data8 sys_symlink
-	data8 sys_ni_syscall
-	data8 sys_readlink	  /* 85 */
-	data8 sys_uselib
-	data8 sys_swapon
-	data8 sys_reboot
-	data8 compat_sys_old_readdir
-	data8 sys32_mmap	  /* 90 */
-	data8 sys32_munmap
-	data8 sys_truncate
-	data8 sys_ftruncate
-	data8 sys_fchmod
-	data8 sys_fchown	/* 16-bit version */	  /* 95 */
-	data8 sys_getpriority
-	data8 sys_setpriority
-	data8 sys_ni_syscall	  /* old profil syscall holder */
-	data8 compat_sys_statfs
-	data8 compat_sys_fstatfs	  /* 100 */
-	data8 sys_ni_syscall	/* ioperm */
-	data8 compat_sys_socketcall
-	data8 sys_syslog
-	data8 compat_sys_setitimer
-	data8 compat_sys_getitimer	  /* 105 */
-	data8 compat_sys_newstat
-	data8 compat_sys_newlstat
-	data8 compat_sys_newfstat
-	data8 sys_ni_syscall
-	data8 sys_ni_syscall	/* iopl */	/* 110 */
-	data8 sys_vhangup
-	data8 sys_ni_syscall		/* used to be sys_idle */
-	data8 sys_ni_syscall
-	data8 compat_sys_wait4
-	data8 sys_swapoff	  /* 115 */
-	data8 compat_sys_sysinfo
-	data8 sys32_ipc
-	data8 sys_fsync
-	data8 sys32_sigreturn
-	data8 ia32_clone	  /* 120 */
-	data8 sys_setdomainname
-	data8 sys32_newuname
-	data8 sys32_modify_ldt
-	data8 compat_sys_adjtimex
-	data8 sys32_mprotect	  /* 125 */
-	data8 compat_sys_sigprocmask
-	data8 sys_ni_syscall	/* create_module */
-	data8 sys_ni_syscall	/* init_module */
-	data8 sys_ni_syscall	/* delete_module */
-	data8 sys_ni_syscall	/* get_kernel_syms */  /* 130 */
-	data8 sys32_quotactl
-	data8 sys_getpgid
-	data8 sys_fchdir
-	data8 sys_ni_syscall	/* sys_bdflush */
-	data8 sys_sysfs		/* 135 */
-	data8 sys32_personality
-	data8 sys_ni_syscall	  /* for afs_syscall */
-	data8 sys_setfsuid	/* 16-bit version */
-	data8 sys_setfsgid	/* 16-bit version */
-	data8 sys_llseek	  /* 140 */
-	data8 compat_sys_getdents
-	data8 compat_sys_select
-	data8 sys_flock
-	data8 sys32_msync
-	data8 compat_sys_readv	  /* 145 */
-	data8 compat_sys_writev
-	data8 sys_getsid
-	data8 sys_fdatasync
-	data8 compat_sys_sysctl
-	data8 sys_mlock		  /* 150 */
-	data8 sys_munlock
-	data8 sys_mlockall
-	data8 sys_munlockall
-	data8 sys_sched_setparam
-	data8 sys_sched_getparam  /* 155 */
-	data8 sys_sched_setscheduler
-	data8 sys_sched_getscheduler
-	data8 sys_sched_yield
-	data8 sys_sched_get_priority_max
-	data8 sys_sched_get_priority_min	 /* 160 */
-	data8 sys32_sched_rr_get_interval
-	data8 compat_sys_nanosleep
-	data8 sys32_mremap
-	data8 sys_setresuid	/* 16-bit version */
-	data8 sys32_getresuid16	/* 16-bit version */	  /* 165 */
-	data8 sys_ni_syscall	/* vm86 */
-	data8 sys_ni_syscall	/* sys_query_module */
-	data8 sys_poll
-	data8 sys_ni_syscall	/* nfsservctl */
-	data8 sys_setresgid	  /* 170 */
-	data8 sys32_getresgid16
-	data8 sys_prctl
-	data8 sys32_rt_sigreturn
-	data8 sys32_rt_sigaction
-	data8 sys32_rt_sigprocmask /* 175 */
-	data8 sys_rt_sigpending
-	data8 compat_sys_rt_sigtimedwait
-	data8 sys32_rt_sigqueueinfo
-	data8 compat_sys_rt_sigsuspend
-	data8 sys32_pread	  /* 180 */
-	data8 sys32_pwrite
-	data8 sys_chown	/* 16-bit version */
-	data8 sys_getcwd
-	data8 sys_capget
-	data8 sys_capset	  /* 185 */
-	data8 sys32_sigaltstack
-	data8 sys32_sendfile
-	data8 sys_ni_syscall		  /* streams1 */
-	data8 sys_ni_syscall		  /* streams2 */
-	data8 sys32_vfork	  /* 190 */
-	data8 compat_sys_getrlimit
-	data8 sys32_mmap2
-	data8 sys32_truncate64
-	data8 sys32_ftruncate64
-	data8 sys32_stat64	  /* 195 */
-	data8 sys32_lstat64
-	data8 sys32_fstat64
-	data8 sys_lchown
-	data8 sys_getuid
-	data8 sys_getgid	  /* 200 */
-	data8 sys_geteuid
-	data8 sys_getegid
-	data8 sys_setreuid
-	data8 sys_setregid
-	data8 sys_getgroups	  /* 205 */
-	data8 sys_setgroups
-	data8 sys_fchown
-	data8 sys_setresuid
-	data8 sys_getresuid
-	data8 sys_setresgid	  /* 210 */
-	data8 sys_getresgid
-	data8 sys_chown
-	data8 sys_setuid
-	data8 sys_setgid
-	data8 sys_setfsuid	  /* 215 */
-	data8 sys_setfsgid
-	data8 sys_pivot_root
-	data8 sys_mincore
-	data8 sys_madvise
-	data8 compat_sys_getdents64	  /* 220 */
-	data8 compat_sys_fcntl64
-	data8 sys_ni_syscall		/* reserved for TUX */
-	data8 sys_ni_syscall		/* reserved for Security */
-	data8 sys_gettid
-	data8 sys_readahead	  /* 225 */
- 	data8 sys_setxattr
- 	data8 sys_lsetxattr
- 	data8 sys_fsetxattr
- 	data8 sys_getxattr
- 	data8 sys_lgetxattr	/* 230 */
- 	data8 sys_fgetxattr
- 	data8 sys_listxattr
- 	data8 sys_llistxattr
- 	data8 sys_flistxattr
- 	data8 sys_removexattr	/* 235 */
- 	data8 sys_lremovexattr
- 	data8 sys_fremovexattr
-	data8 sys_tkill
- 	data8 sys_sendfile64
-	data8 compat_sys_futex	/* 240 */
-	data8 compat_sys_sched_setaffinity
-	data8 compat_sys_sched_getaffinity
-	data8 sys32_set_thread_area
-	data8 sys32_get_thread_area
- 	data8 compat_sys_io_setup	/* 245 */
- 	data8 sys_io_destroy
- 	data8 compat_sys_io_getevents
- 	data8 compat_sys_io_submit
- 	data8 sys_io_cancel
- 	data8 sys_fadvise64	/* 250 */
-	data8 sys_ni_syscall
-	data8 sys_exit_group
- 	data8 sys_lookup_dcookie
-	data8 sys_epoll_create
-	data8 sys32_epoll_ctl	/* 255 */
-	data8 sys32_epoll_wait
-	data8 sys_remap_file_pages
-	data8 sys_set_tid_address
- 	data8 compat_sys_timer_create
- 	data8 compat_sys_timer_settime	/* 260 */
- 	data8 compat_sys_timer_gettime
- 	data8 sys_timer_getoverrun
- 	data8 sys_timer_delete
- 	data8 compat_sys_clock_settime
- 	data8 compat_sys_clock_gettime /* 265 */
- 	data8 compat_sys_clock_getres
- 	data8 compat_sys_clock_nanosleep
-	data8 compat_sys_statfs64
-	data8 compat_sys_fstatfs64
- 	data8 sys_tgkill	/* 270 */
- 	data8 compat_sys_utimes
- 	data8 sys32_fadvise64_64
- 	data8 sys_ni_syscall
-  	data8 sys_ni_syscall
- 	data8 sys_ni_syscall	/* 275 */
-  	data8 sys_ni_syscall
-  	data8 compat_sys_mq_open
-  	data8 sys_mq_unlink
-  	data8 compat_sys_mq_timedsend
-  	data8 compat_sys_mq_timedreceive	/* 280 */
-  	data8 compat_sys_mq_notify
-  	data8 compat_sys_mq_getsetattr
-	data8 sys_ni_syscall		/* reserved for kexec */
-	data8 compat_sys_waitid
-
-	// guard against failures to increase IA32_NR_syscalls
-	.org ia32_syscall_table + 8*IA32_NR_syscalls
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/ia32/ia32_ldt.c linux-libre-2.6.34-gnu1/arch/ia64/ia32/ia32_ldt.c
--- linux-libre-2.6.33-gnu1/arch/ia64/ia32/ia32_ldt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/ia32/ia32_ldt.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2001, 2004 Hewlett-Packard Co
- *	David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * Adapted from arch/i386/kernel/ldt.c
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/vmalloc.h>
-
-#include <asm/uaccess.h>
-
-#include "ia32priv.h"
-
-/*
- * read_ldt() is not really atomic - this is not a problem since synchronization of reads
- * and writes done to the LDT has to be assured by user-space anyway. Writes are atomic,
- * to protect the security checks done on new descriptors.
- */
-static int
-read_ldt (void __user *ptr, unsigned long bytecount)
-{
-	unsigned long bytes_left, n;
-	char __user *src, *dst;
-	char buf[256];	/* temporary buffer (don't overflow kernel stack!) */
-
-	if (bytecount > IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE)
-		bytecount = IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE;
-
-	bytes_left = bytecount;
-
-	src = (void __user *) IA32_LDT_OFFSET;
-	dst = ptr;
-
-	while (bytes_left) {
-		n = sizeof(buf);
-		if (n > bytes_left)
-			n = bytes_left;
-
-		/*
-		 * We know we're reading valid memory, but we still must guard against
-		 * running out of memory.
-		 */
-		if (__copy_from_user(buf, src, n))
-			return -EFAULT;
-
-		if (copy_to_user(dst, buf, n))
-			return -EFAULT;
-
-		src += n;
-		dst += n;
-		bytes_left -= n;
-	}
-	return bytecount;
-}
-
-static int
-read_default_ldt (void __user * ptr, unsigned long bytecount)
-{
-	unsigned long size;
-	int err;
-
-	/* XXX fix me: should return equivalent of default_ldt[0] */
-	err = 0;
-	size = 8;
-	if (size > bytecount)
-		size = bytecount;
-
-	err = size;
-	if (clear_user(ptr, size))
-		err = -EFAULT;
-
-	return err;
-}
-
-static int
-write_ldt (void __user * ptr, unsigned long bytecount, int oldmode)
-{
-	struct ia32_user_desc ldt_info;
-	__u64 entry;
-	int ret;
-
-	if (bytecount != sizeof(ldt_info))
-		return -EINVAL;
-	if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
-		return -EFAULT;
-
-	if (ldt_info.entry_number >= IA32_LDT_ENTRIES)
-		return -EINVAL;
-	if (ldt_info.contents == 3) {
-		if (oldmode)
-			return -EINVAL;
-		if (ldt_info.seg_not_present == 0)
-			return -EINVAL;
-	}
-
-	if (ldt_info.base_addr == 0 && ldt_info.limit == 0
-	    && (oldmode || (ldt_info.contents == 0 && ldt_info.read_exec_only == 1
-			    && ldt_info.seg_32bit == 0 && ldt_info.limit_in_pages == 0
-			    && ldt_info.seg_not_present == 1 && ldt_info.useable == 0)))
-		/* allow LDTs to be cleared by the user */
-		entry = 0;
-	else
-		/* we must set the "Accessed" bit as IVE doesn't emulate it */
-		entry = IA32_SEG_DESCRIPTOR(ldt_info.base_addr, ldt_info.limit,
-					    (((ldt_info.read_exec_only ^ 1) << 1)
-					     | (ldt_info.contents << 2)) | 1,
-					    1, 3, ldt_info.seg_not_present ^ 1,
-					    (oldmode ? 0 : ldt_info.useable),
-					    ldt_info.seg_32bit,
-					    ldt_info.limit_in_pages);
-	/*
-	 * Install the new entry.  We know we're accessing valid (mapped) user-level
-	 * memory, but we still need to guard against out-of-memory, hence we must use
-	 * put_user().
-	 */
-	ret = __put_user(entry, (__u64 __user *) IA32_LDT_OFFSET + ldt_info.entry_number);
-	ia32_load_segment_descriptors(current);
-	return ret;
-}
-
-asmlinkage int
-sys32_modify_ldt (int func, unsigned int ptr, unsigned int bytecount)
-{
-	int ret = -ENOSYS;
-
-	switch (func) {
-	      case 0:
-		ret = read_ldt(compat_ptr(ptr), bytecount);
-		break;
-	      case 1:
-		ret = write_ldt(compat_ptr(ptr), bytecount, 1);
-		break;
-	      case 2:
-		ret = read_default_ldt(compat_ptr(ptr), bytecount);
-		break;
-	      case 0x11:
-		ret = write_ldt(compat_ptr(ptr), bytecount, 0);
-		break;
-	}
-	return ret;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/ia32/ia32priv.h linux-libre-2.6.34-gnu1/arch/ia64/ia32/ia32priv.h
--- linux-libre-2.6.33-gnu1/arch/ia64/ia32/ia32priv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/ia32/ia32priv.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,532 +0,0 @@
-#ifndef _ASM_IA64_IA32_PRIV_H
-#define _ASM_IA64_IA32_PRIV_H
-
-
-#include <asm/ia32.h>
-
-#ifdef CONFIG_IA32_SUPPORT
-
-#include <linux/binfmts.h>
-#include <linux/compat.h>
-#include <linux/rbtree.h>
-
-#include <asm/processor.h>
-
-/*
- * 32 bit structures for IA32 support.
- */
-
-#define IA32_PAGE_SIZE		(1UL << IA32_PAGE_SHIFT)
-#define IA32_PAGE_MASK		(~(IA32_PAGE_SIZE - 1))
-#define IA32_PAGE_ALIGN(addr)	(((addr) + IA32_PAGE_SIZE - 1) & IA32_PAGE_MASK)
-#define IA32_CLOCKS_PER_SEC	100	/* Cast in stone for IA32 Linux */
-
-/*
- * partially mapped pages provide precise accounting of which 4k sub pages
- * are mapped and which ones are not, thereby improving IA-32 compatibility.
- */
-struct ia64_partial_page {
-	struct ia64_partial_page *next; /* linked list, sorted by address */
-	struct rb_node		pp_rb;
-	/* 64K is the largest "normal" page supported by ia64 ABI. So 4K*64
-	 * should suffice.*/
-	unsigned long		bitmap;
-	unsigned int		base;
-};
-
-struct ia64_partial_page_list {
-	struct ia64_partial_page *pp_head; /* list head, points to the lowest
-					   * addressed partial page */
-	struct rb_root		ppl_rb;
-	struct ia64_partial_page *pp_hint; /* pp_hint->next is the last
-					   * accessed partial page */
-	atomic_t		pp_count; /* reference count */
-};
-
-#if PAGE_SHIFT > IA32_PAGE_SHIFT
-struct ia64_partial_page_list* ia32_init_pp_list (void);
-#else
-# define ia32_init_pp_list()	0
-#endif
-
-/* sigcontext.h */
-/*
- * As documented in the iBCS2 standard..
- *
- * The first part of "struct _fpstate" is just the
- * normal i387 hardware setup, the extra "status"
- * word is used to save the coprocessor status word
- * before entering the handler.
- */
-struct _fpreg_ia32 {
-       unsigned short significand[4];
-       unsigned short exponent;
-};
-
-struct _fpxreg_ia32 {
-        unsigned short significand[4];
-        unsigned short exponent;
-        unsigned short padding[3];
-};
-
-struct _xmmreg_ia32 {
-        unsigned int element[4];
-};
-
-
-struct _fpstate_ia32 {
-       unsigned int    cw,
-		       sw,
-		       tag,
-		       ipoff,
-		       cssel,
-		       dataoff,
-		       datasel;
-       struct _fpreg_ia32      _st[8];
-       unsigned short  status;
-       unsigned short  magic;          /* 0xffff = regular FPU data only */
-
-       /* FXSR FPU environment */
-       unsigned int         _fxsr_env[6];   /* FXSR FPU env is ignored */
-       unsigned int         mxcsr;
-       unsigned int         reserved;
-       struct _fpxreg_ia32  _fxsr_st[8];    /* FXSR FPU reg data is ignored */
-       struct _xmmreg_ia32  _xmm[8];
-       unsigned int         padding[56];
-};
-
-struct sigcontext_ia32 {
-       unsigned short gs, __gsh;
-       unsigned short fs, __fsh;
-       unsigned short es, __esh;
-       unsigned short ds, __dsh;
-       unsigned int edi;
-       unsigned int esi;
-       unsigned int ebp;
-       unsigned int esp;
-       unsigned int ebx;
-       unsigned int edx;
-       unsigned int ecx;
-       unsigned int eax;
-       unsigned int trapno;
-       unsigned int err;
-       unsigned int eip;
-       unsigned short cs, __csh;
-       unsigned int eflags;
-       unsigned int esp_at_signal;
-       unsigned short ss, __ssh;
-       unsigned int fpstate;		/* really (struct _fpstate_ia32 *) */
-       unsigned int oldmask;
-       unsigned int cr2;
-};
-
-/* user.h */
-/*
- * IA32 (Pentium III/4) FXSR, SSE support
- *
- * Provide support for the GDB 5.0+ PTRACE_{GET|SET}FPXREGS requests for
- * interacting with the FXSR-format floating point environment.  Floating
- * point data can be accessed in the regular format in the usual manner,
- * and both the standard and SIMD floating point data can be accessed via
- * the new ptrace requests.  In either case, changes to the FPU environment
- * will be reflected in the task's state as expected.
- */
-struct ia32_user_i387_struct {
-	int	cwd;
-	int	swd;
-	int	twd;
-	int	fip;
-	int	fcs;
-	int	foo;
-	int	fos;
-	/* 8*10 bytes for each FP-reg = 80 bytes */
-	struct _fpreg_ia32 	st_space[8];
-};
-
-struct ia32_user_fxsr_struct {
-	unsigned short	cwd;
-	unsigned short	swd;
-	unsigned short	twd;
-	unsigned short	fop;
-	int	fip;
-	int	fcs;
-	int	foo;
-	int	fos;
-	int	mxcsr;
-	int	reserved;
-	int	st_space[32];	/* 8*16 bytes for each FP-reg = 128 bytes */
-	int	xmm_space[32];	/* 8*16 bytes for each XMM-reg = 128 bytes */
-	int	padding[56];
-};
-
-/* signal.h */
-#define IA32_SET_SA_HANDLER(ka,handler,restorer)				\
-				((ka)->sa.sa_handler = (__sighandler_t)		\
-					(((unsigned long)(restorer) << 32)	\
-					 | ((handler) & 0xffffffff)))
-#define IA32_SA_HANDLER(ka)	((unsigned long) (ka)->sa.sa_handler & 0xffffffff)
-#define IA32_SA_RESTORER(ka)	((unsigned long) (ka)->sa.sa_handler >> 32)
-
-#define __IA32_NR_sigreturn 119
-#define __IA32_NR_rt_sigreturn 173
-
-struct sigaction32 {
-       unsigned int sa_handler;		/* Really a pointer, but need to deal with 32 bits */
-       unsigned int sa_flags;
-       unsigned int sa_restorer;	/* Another 32 bit pointer */
-       compat_sigset_t sa_mask;		/* A 32 bit mask */
-};
-
-struct old_sigaction32 {
-       unsigned int  sa_handler;	/* Really a pointer, but need to deal
-					     with 32 bits */
-       compat_old_sigset_t sa_mask;		/* A 32 bit mask */
-       unsigned int sa_flags;
-       unsigned int sa_restorer;	/* Another 32 bit pointer */
-};
-
-typedef struct sigaltstack_ia32 {
-	unsigned int	ss_sp;
-	int		ss_flags;
-	unsigned int	ss_size;
-} stack_ia32_t;
-
-struct ucontext_ia32 {
-	unsigned int	  uc_flags;
-	unsigned int	  uc_link;
-	stack_ia32_t	  uc_stack;
-	struct sigcontext_ia32 uc_mcontext;
-	sigset_t	  uc_sigmask;	/* mask last for extensibility */
-};
-
-struct stat64 {
-	unsigned long long	st_dev;
-	unsigned char	__pad0[4];
-	unsigned int	__st_ino;
-	unsigned int	st_mode;
-	unsigned int	st_nlink;
-	unsigned int	st_uid;
-	unsigned int	st_gid;
-	unsigned long long	st_rdev;
-	unsigned char	__pad3[4];
-	unsigned int	st_size_lo;
-	unsigned int	st_size_hi;
-	unsigned int	st_blksize;
-	unsigned int	st_blocks;	/* Number 512-byte blocks allocated. */
-	unsigned int	__pad4;		/* future possible st_blocks high bits */
-	unsigned int	st_atime;
-	unsigned int	st_atime_nsec;
-	unsigned int	st_mtime;
-	unsigned int	st_mtime_nsec;
-	unsigned int	st_ctime;
-	unsigned int	st_ctime_nsec;
-	unsigned int	st_ino_lo;
-	unsigned int	st_ino_hi;
-};
-
-typedef struct compat_siginfo {
-	int si_signo;
-	int si_errno;
-	int si_code;
-
-	union {
-		int _pad[((128/sizeof(int)) - 3)];
-
-		/* kill() */
-		struct {
-			unsigned int _pid;	/* sender's pid */
-			unsigned int _uid;	/* sender's uid */
-		} _kill;
-
-		/* POSIX.1b timers */
-		struct {
-			compat_timer_t _tid;		/* timer id */
-			int _overrun;		/* overrun count */
-			char _pad[sizeof(unsigned int) - sizeof(int)];
-			compat_sigval_t _sigval;	/* same as below */
-			int _sys_private;       /* not to be passed to user */
-		} _timer;
-
-		/* POSIX.1b signals */
-		struct {
-			unsigned int _pid;	/* sender's pid */
-			unsigned int _uid;	/* sender's uid */
-			compat_sigval_t _sigval;
-		} _rt;
-
-		/* SIGCHLD */
-		struct {
-			unsigned int _pid;	/* which child */
-			unsigned int _uid;	/* sender's uid */
-			int _status;		/* exit code */
-			compat_clock_t _utime;
-			compat_clock_t _stime;
-		} _sigchld;
-
-		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
-		struct {
-			unsigned int _addr;	/* faulting insn/memory ref. */
-		} _sigfault;
-
-		/* SIGPOLL */
-		struct {
-			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
-			int _fd;
-		} _sigpoll;
-	} _sifields;
-} compat_siginfo_t;
-
-/*
- * IA-32 ELF specific definitions for IA-64.
- */
-
-#define _ASM_IA64_ELF_H		/* Don't include elf.h */
-
-#include <linux/sched.h>
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) ((x)->e_machine == EM_386)
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_CLASS	ELFCLASS32
-#define ELF_DATA	ELFDATA2LSB
-#define ELF_ARCH	EM_386
-
-#define IA32_STACK_TOP		IA32_PAGE_OFFSET
-#define IA32_GATE_OFFSET	IA32_PAGE_OFFSET
-#define IA32_GATE_END		IA32_PAGE_OFFSET + PAGE_SIZE
-
-/*
- * The system segments (GDT, TSS, LDT) have to be mapped below 4GB so the IA-32 engine can
- * access them.
- */
-#define IA32_GDT_OFFSET		(IA32_PAGE_OFFSET + PAGE_SIZE)
-#define IA32_TSS_OFFSET		(IA32_PAGE_OFFSET + 2*PAGE_SIZE)
-#define IA32_LDT_OFFSET		(IA32_PAGE_OFFSET + 3*PAGE_SIZE)
-
-#define ELF_EXEC_PAGESIZE	IA32_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		(IA32_PAGE_OFFSET/3 + 0x1000000)
-
-void ia64_elf32_init(struct pt_regs *regs);
-#define ELF_PLAT_INIT(_r, load_addr)	ia64_elf32_init(_r)
-
-/* This macro yields a bitmask that programs can use to figure out
-   what instruction set this CPU supports.  */
-#define ELF_HWCAP	0
-
-/* This macro yields a string that ld.so will use to load
-   implementation specific libraries for optimization.  Not terribly
-   relevant until we have real hardware to play with... */
-#define ELF_PLATFORM	NULL
-
-#ifdef __KERNEL__
-# define SET_PERSONALITY(EX)				\
-	(current->personality = PER_LINUX)
-#endif
-
-#define IA32_EFLAG	0x200
-
-/*
- * IA-32 ELF specific definitions for IA-64.
- */
-
-#define __USER_CS      0x23
-#define __USER_DS      0x2B
-
-/*
- * The per-cpu GDT has 32 entries: see <asm-i386/segment.h>
- */
-#define GDT_ENTRIES 32
-
-#define GDT_SIZE	(GDT_ENTRIES * 8)
-
-#define TSS_ENTRY 14
-#define LDT_ENTRY	(TSS_ENTRY + 1)
-
-#define IA32_SEGSEL_RPL		(0x3 << 0)
-#define IA32_SEGSEL_TI		(0x1 << 2)
-#define IA32_SEGSEL_INDEX_SHIFT	3
-
-#define _TSS			((unsigned long) TSS_ENTRY << IA32_SEGSEL_INDEX_SHIFT)
-#define _LDT			((unsigned long) LDT_ENTRY << IA32_SEGSEL_INDEX_SHIFT)
-
-#define IA32_SEG_BASE		16
-#define IA32_SEG_TYPE		40
-#define IA32_SEG_SYS		44
-#define IA32_SEG_DPL		45
-#define IA32_SEG_P		47
-#define IA32_SEG_HIGH_LIMIT	48
-#define IA32_SEG_AVL		52
-#define IA32_SEG_DB		54
-#define IA32_SEG_G		55
-#define IA32_SEG_HIGH_BASE	56
-
-#define IA32_SEG_DESCRIPTOR(base, limit, segtype, nonsysseg, dpl, segpresent, avl, segdb, gran)	\
-	       (((limit) & 0xffff)								\
-		| (((unsigned long) (base) & 0xffffff) << IA32_SEG_BASE)			\
-		| ((unsigned long) (segtype) << IA32_SEG_TYPE)					\
-		| ((unsigned long) (nonsysseg) << IA32_SEG_SYS)					\
-		| ((unsigned long) (dpl) << IA32_SEG_DPL)					\
-		| ((unsigned long) (segpresent) << IA32_SEG_P)					\
-		| ((((unsigned long) (limit) >> 16) & 0xf) << IA32_SEG_HIGH_LIMIT)		\
-		| ((unsigned long) (avl) << IA32_SEG_AVL)					\
-		| ((unsigned long) (segdb) << IA32_SEG_DB)					\
-		| ((unsigned long) (gran) << IA32_SEG_G)					\
-		| ((((unsigned long) (base) >> 24) & 0xff) << IA32_SEG_HIGH_BASE))
-
-#define SEG_LIM		32
-#define SEG_TYPE	52
-#define SEG_SYS		56
-#define SEG_DPL		57
-#define SEG_P		59
-#define SEG_AVL		60
-#define SEG_DB		62
-#define SEG_G		63
-
-/* Unscramble an IA-32 segment descriptor into the IA-64 format.  */
-#define IA32_SEG_UNSCRAMBLE(sd)									 \
-	(   (((sd) >> IA32_SEG_BASE) & 0xffffff) | ((((sd) >> IA32_SEG_HIGH_BASE) & 0xff) << 24) \
-	 | ((((sd) & 0xffff) | ((((sd) >> IA32_SEG_HIGH_LIMIT) & 0xf) << 16)) << SEG_LIM)	 \
-	 | ((((sd) >> IA32_SEG_TYPE) & 0xf) << SEG_TYPE)					 \
-	 | ((((sd) >> IA32_SEG_SYS) & 0x1) << SEG_SYS)						 \
-	 | ((((sd) >> IA32_SEG_DPL) & 0x3) << SEG_DPL)						 \
-	 | ((((sd) >> IA32_SEG_P) & 0x1) << SEG_P)						 \
-	 | ((((sd) >> IA32_SEG_AVL) & 0x1) << SEG_AVL)						 \
-	 | ((((sd) >> IA32_SEG_DB) & 0x1) << SEG_DB)						 \
-	 | ((((sd) >> IA32_SEG_G) & 0x1) << SEG_G))
-
-#define IA32_IOBASE	0x2000000000000000UL /* Virtual address for I/O space */
-
-#define IA32_CR0	0x80000001	/* Enable PG and PE bits */
-#define IA32_CR4	0x600		/* MMXEX and FXSR on */
-
-/*
- *  IA32 floating point control registers starting values
- */
-
-#define IA32_FSR_DEFAULT	0x55550000		/* set all tag bits */
-#define IA32_FCR_DEFAULT	0x17800000037fUL	/* extended precision, all masks */
-
-#define IA32_PTRACE_GETREGS	12
-#define IA32_PTRACE_SETREGS	13
-#define IA32_PTRACE_GETFPREGS	14
-#define IA32_PTRACE_SETFPREGS	15
-#define IA32_PTRACE_GETFPXREGS	18
-#define IA32_PTRACE_SETFPXREGS	19
-
-#define ia32_start_thread(regs,new_ip,new_sp) do {				\
-	set_fs(USER_DS);							\
-	ia64_psr(regs)->cpl = 3;	/* set user mode */			\
-	ia64_psr(regs)->ri = 0;		/* clear return slot number */		\
-	ia64_psr(regs)->is = 1;		/* IA-32 instruction set */		\
-	regs->cr_iip = new_ip;							\
-	regs->ar_rsc = 0xc;		/* enforced lazy mode, priv. level 3 */	\
-	regs->ar_rnat = 0;							\
-	regs->loadrs = 0;							\
-	regs->r12 = new_sp;							\
-} while (0)
-
-/*
- * Local Descriptor Table (LDT) related declarations.
- */
-
-#define IA32_LDT_ENTRIES	8192		/* Maximum number of LDT entries supported. */
-#define IA32_LDT_ENTRY_SIZE	8		/* The size of each LDT entry. */
-
-#define LDT_entry_a(info) \
-	((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
-
-#define LDT_entry_b(info)				\
-	(((info)->base_addr & 0xff000000) |		\
-	(((info)->base_addr & 0x00ff0000) >> 16) |	\
-	((info)->limit & 0xf0000) |			\
-	(((info)->read_exec_only ^ 1) << 9) |		\
-	((info)->contents << 10) |			\
-	(((info)->seg_not_present ^ 1) << 15) |		\
-	((info)->seg_32bit << 22) |			\
-	((info)->limit_in_pages << 23) |		\
-	((info)->useable << 20) |			\
-	0x7100)
-
-#define LDT_empty(info) (			\
-	(info)->base_addr	== 0	&&	\
-	(info)->limit		== 0	&&	\
-	(info)->contents	== 0	&&	\
-	(info)->read_exec_only	== 1	&&	\
-	(info)->seg_32bit	== 0	&&	\
-	(info)->limit_in_pages	== 0	&&	\
-	(info)->seg_not_present	== 1	&&	\
-	(info)->useable		== 0	)
-
-static inline void
-load_TLS (struct thread_struct *t, unsigned int cpu)
-{
-	extern unsigned long *cpu_gdt_table[NR_CPUS];
-
-	memcpy(cpu_gdt_table[cpu] + GDT_ENTRY_TLS_MIN + 0, &t->tls_array[0], sizeof(long));
-	memcpy(cpu_gdt_table[cpu] + GDT_ENTRY_TLS_MIN + 1, &t->tls_array[1], sizeof(long));
-	memcpy(cpu_gdt_table[cpu] + GDT_ENTRY_TLS_MIN + 2, &t->tls_array[2], sizeof(long));
-}
-
-struct ia32_user_desc {
-	unsigned int entry_number;
-	unsigned int base_addr;
-	unsigned int limit;
-	unsigned int seg_32bit:1;
-	unsigned int contents:2;
-	unsigned int read_exec_only:1;
-	unsigned int limit_in_pages:1;
-	unsigned int seg_not_present:1;
-	unsigned int useable:1;
-};
-
-struct linux_binprm;
-
-extern void ia32_init_addr_space (struct pt_regs *regs);
-extern int ia32_setup_arg_pages (struct linux_binprm *bprm, int exec_stack);
-extern unsigned long ia32_do_mmap (struct file *, unsigned long, unsigned long, int, int, loff_t);
-extern void ia32_load_segment_descriptors (struct task_struct *task);
-
-#define ia32f2ia64f(dst,src)			\
-do {						\
-	ia64_ldfe(6,src);			\
-	ia64_stop();				\
-	ia64_stf_spill(dst, 6);			\
-} while(0)
-
-#define ia64f2ia32f(dst,src)			\
-do {						\
-	ia64_ldf_fill(6, src);			\
-	ia64_stop();				\
-	ia64_stfe(dst, 6);			\
-} while(0)
-
-struct user_regs_struct32 {
-	__u32 ebx, ecx, edx, esi, edi, ebp, eax;
-	unsigned short ds, __ds, es, __es;
-	unsigned short fs, __fs, gs, __gs;
-	__u32 orig_eax, eip;
-	unsigned short cs, __cs;
-	__u32 eflags, esp;
-	unsigned short ss, __ss;
-};
-
-/* Prototypes for use in elfcore32.h */
-extern int save_ia32_fpstate (struct task_struct *, struct ia32_user_i387_struct __user *);
-extern int save_ia32_fpxstate (struct task_struct *, struct ia32_user_fxsr_struct __user *);
-
-#endif /* !CONFIG_IA32_SUPPORT */
-
-#endif /* _ASM_IA64_IA32_PRIV_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/ia32/ia32_signal.c linux-libre-2.6.34-gnu1/arch/ia64/ia32/ia32_signal.c
--- linux-libre-2.6.33-gnu1/arch/ia64/ia32/ia32_signal.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/ia32/ia32_signal.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1010 +0,0 @@
-/*
- * IA32 Architecture-specific signal handling support.
- *
- * Copyright (C) 1999, 2001-2002, 2005 Hewlett-Packard Co
- *	David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
- * Copyright (C) 2000 VA Linux Co
- * Copyright (C) 2000 Don Dugger <n0ano@valinux.com>
- *
- * Derived from i386 and Alpha versions.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/personality.h>
-#include <linux/ptrace.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/smp.h>
-#include <linux/stddef.h>
-#include <linux/syscalls.h>
-#include <linux/unistd.h>
-#include <linux/wait.h>
-#include <linux/compat.h>
-
-#include <asm/intrinsics.h>
-#include <asm/uaccess.h>
-#include <asm/rse.h>
-#include <asm/sigcontext.h>
-
-#include "ia32priv.h"
-
-#include "../kernel/sigframe.h"
-
-#define A(__x)		((unsigned long)(__x))
-
-#define DEBUG_SIG	0
-#define _BLOCKABLE	(~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
-#define __IA32_NR_sigreturn            119
-#define __IA32_NR_rt_sigreturn         173
-
-struct sigframe_ia32
-{
-       int pretcode;
-       int sig;
-       struct sigcontext_ia32 sc;
-       struct _fpstate_ia32 fpstate;
-       unsigned int extramask[_COMPAT_NSIG_WORDS-1];
-       char retcode[8];
-};
-
-struct rt_sigframe_ia32
-{
-       int pretcode;
-       int sig;
-       int pinfo;
-       int puc;
-       compat_siginfo_t info;
-       struct ucontext_ia32 uc;
-       struct _fpstate_ia32 fpstate;
-       char retcode[8];
-};
-
-int
-copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
-{
-	unsigned long tmp;
-	int err;
-
-	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);
-
-	if (to->si_code < 0)
-		err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
-	else {
-		switch (to->si_code >> 16) {
-		      case __SI_CHLD >> 16:
-			err |= __get_user(to->si_utime, &from->si_utime);
-			err |= __get_user(to->si_stime, &from->si_stime);
-			err |= __get_user(to->si_status, &from->si_status);
-		      default:
-			err |= __get_user(to->si_pid, &from->si_pid);
-			err |= __get_user(to->si_uid, &from->si_uid);
-			break;
-		      case __SI_FAULT >> 16:
-			err |= __get_user(tmp, &from->si_addr);
-			to->si_addr = (void __user *) tmp;
-			break;
-		      case __SI_POLL >> 16:
-			err |= __get_user(to->si_band, &from->si_band);
-			err |= __get_user(to->si_fd, &from->si_fd);
-			break;
-		      case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
-		      case __SI_MESGQ >> 16:
-			err |= __get_user(to->si_pid, &from->si_pid);
-			err |= __get_user(to->si_uid, &from->si_uid);
-			err |= __get_user(to->si_int, &from->si_int);
-			break;
-		}
-	}
-	return err;
-}
-
-int
-copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
-{
-	unsigned int addr;
-	int err;
-
-	if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
-		return -EFAULT;
-
-	/* If you change siginfo_t structure, please be sure
-	   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.
-	   This routine must convert siginfo from 64bit to 32bit as well
-	   at the same time.  */
-	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);
-	if (from->si_code < 0)
-		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
-	else {
-		switch (from->si_code >> 16) {
-		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);
-		default:
-			err |= __put_user(from->si_pid, &to->si_pid);
-			err |= __put_user(from->si_uid, &to->si_uid);
-			break;
-		case __SI_FAULT >> 16:
-			/* avoid type-checking warnings by copying _pad[0] in lieu of si_addr... */
-			err |= __put_user(from->_sifields._pad[0], &to->si_addr);
-			break;
-		case __SI_POLL >> 16:
-			err |= __put_user(from->si_band, &to->si_band);
-			err |= __put_user(from->si_fd, &to->si_fd);
-			break;
-		case __SI_TIMER >> 16:
-			err |= __put_user(from->si_tid, &to->si_tid);
-			err |= __put_user(from->si_overrun, &to->si_overrun);
-			addr = (unsigned long) from->si_ptr;
-			err |= __put_user(addr, &to->si_ptr);
-			break;
-		case __SI_RT >> 16:	/* Not generated by the kernel as of now.  */
-		case __SI_MESGQ >> 16:
-			err |= __put_user(from->si_uid, &to->si_uid);
-			err |= __put_user(from->si_pid, &to->si_pid);
-			addr = (unsigned long) from->si_ptr;
-			err |= __put_user(addr, &to->si_ptr);
-			break;
-		}
-	}
-	return err;
-}
-
-
-/*
- *  SAVE and RESTORE of ia32 fpstate info, from ia64 current state
- *  Used in exception handler to pass the fpstate to the user, and restore
- *  the fpstate while returning from the exception handler.
- *
- *    fpstate info and their mapping to IA64 regs:
- *    fpstate    REG(BITS)      Attribute    Comments
- *    cw         ar.fcr(0:12)                with bits 7 and 6 not used
- *    sw         ar.fsr(0:15)
- *    tag        ar.fsr(16:31)               with odd numbered bits not used
- *                                           (read returns 0, writes ignored)
- *    ipoff      ar.fir(0:31)
- *    cssel      ar.fir(32:47)
- *    dataoff    ar.fdr(0:31)
- *    datasel    ar.fdr(32:47)
- *
- *    _st[(0+TOS)%8]   f8
- *    _st[(1+TOS)%8]   f9
- *    _st[(2+TOS)%8]   f10
- *    _st[(3+TOS)%8]   f11                   (f8..f11 from ptregs)
- *      : :            :                     (f12..f15 from live reg)
- *      : :            :
- *    _st[(7+TOS)%8]   f15                   TOS=sw.top(bits11:13)
- *
- *    status     Same as sw     RO
- *    magic      0                           as X86_FXSR_MAGIC in ia32
- *    mxcsr      Bits(7:15)=ar.fcr(39:47)
- *               Bits(0:5) =ar.fsr(32:37)    with bit 6 reserved
- *    _xmm[0..7] f16..f31                    (live registers)
- *                                           with _xmm[0]
- *                                             Bit(64:127)=f17(0:63)
- *                                             Bit(0:63)=f16(0:63)
- *    All other fields unused...
- */
-
-static int
-save_ia32_fpstate_live (struct _fpstate_ia32 __user *save)
-{
-	struct task_struct *tsk = current;
-	struct pt_regs *ptp;
-	struct _fpreg_ia32 *fpregp;
-	char buf[32];
-	unsigned long fsr, fcr, fir, fdr;
-	unsigned long new_fsr;
-	unsigned long num128[2];
-	unsigned long mxcsr=0;
-	int fp_tos, fr8_st_map;
-
-	if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
-		return -EFAULT;
-
-	/* Read in fsr, fcr, fir, fdr and copy onto fpstate */
-	fsr = ia64_getreg(_IA64_REG_AR_FSR);
-	fcr = ia64_getreg(_IA64_REG_AR_FCR);
-	fir = ia64_getreg(_IA64_REG_AR_FIR);
-	fdr = ia64_getreg(_IA64_REG_AR_FDR);
-
-	/*
-	 * We need to clear the exception state before calling the signal handler. Clear
-	 * the bits 15, bits 0-7 in fp status word. Similar to the functionality of fnclex
-	 * instruction.
-	 */
-	new_fsr = fsr & ~0x80ff;
-	ia64_setreg(_IA64_REG_AR_FSR, new_fsr);
-
-	__put_user(fcr & 0xffff, &save->cw);
-	__put_user(fsr & 0xffff, &save->sw);
-	__put_user((fsr>>16) & 0xffff, &save->tag);
-	__put_user(fir, &save->ipoff);
-	__put_user((fir>>32) & 0xffff, &save->cssel);
-	__put_user(fdr, &save->dataoff);
-	__put_user((fdr>>32) & 0xffff, &save->datasel);
-	__put_user(fsr & 0xffff, &save->status);
-
-	mxcsr = ((fcr>>32) & 0xff80) | ((fsr>>32) & 0x3f);
-	__put_user(mxcsr & 0xffff, &save->mxcsr);
-	__put_user( 0, &save->magic); //#define X86_FXSR_MAGIC   0x0000
-
-	/*
-	 * save f8..f11  from pt_regs
-	 * save f12..f15 from live register set
-	 */
-	/*
-	 *  Find the location where f8 has to go in fp reg stack.  This depends on
-	 *  TOP(11:13) field of sw. Other f reg continue sequentially from where f8 maps
-	 *  to.
-	 */
-	fp_tos = (fsr>>11)&0x7;
-	fr8_st_map = (8-fp_tos)&0x7;
-	ptp = task_pt_regs(tsk);
-	fpregp = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
-	ia64f2ia32f(fpregp, &ptp->f8);
-	copy_to_user(&save->_st[(0+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
-	ia64f2ia32f(fpregp, &ptp->f9);
-	copy_to_user(&save->_st[(1+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
-	ia64f2ia32f(fpregp, &ptp->f10);
-	copy_to_user(&save->_st[(2+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
-	ia64f2ia32f(fpregp, &ptp->f11);
-	copy_to_user(&save->_st[(3+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
-
-	ia64_stfe(fpregp, 12);
-	copy_to_user(&save->_st[(4+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
-	ia64_stfe(fpregp, 13);
-	copy_to_user(&save->_st[(5+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
-	ia64_stfe(fpregp, 14);
-	copy_to_user(&save->_st[(6+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
-	ia64_stfe(fpregp, 15);
-	copy_to_user(&save->_st[(7+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
-
-	ia64_stf8(&num128[0], 16);
-	ia64_stf8(&num128[1], 17);
-	copy_to_user(&save->_xmm[0], num128, sizeof(struct _xmmreg_ia32));
-
-	ia64_stf8(&num128[0], 18);
-	ia64_stf8(&num128[1], 19);
-	copy_to_user(&save->_xmm[1], num128, sizeof(struct _xmmreg_ia32));
-
-	ia64_stf8(&num128[0], 20);
-	ia64_stf8(&num128[1], 21);
-	copy_to_user(&save->_xmm[2], num128, sizeof(struct _xmmreg_ia32));
-
-	ia64_stf8(&num128[0], 22);
-	ia64_stf8(&num128[1], 23);
-	copy_to_user(&save->_xmm[3], num128, sizeof(struct _xmmreg_ia32));
-
-	ia64_stf8(&num128[0], 24);
-	ia64_stf8(&num128[1], 25);
-	copy_to_user(&save->_xmm[4], num128, sizeof(struct _xmmreg_ia32));
-
-	ia64_stf8(&num128[0], 26);
-	ia64_stf8(&num128[1], 27);
-	copy_to_user(&save->_xmm[5], num128, sizeof(struct _xmmreg_ia32));
-
-	ia64_stf8(&num128[0], 28);
-	ia64_stf8(&num128[1], 29);
-	copy_to_user(&save->_xmm[6], num128, sizeof(struct _xmmreg_ia32));
-
-	ia64_stf8(&num128[0], 30);
-	ia64_stf8(&num128[1], 31);
-	copy_to_user(&save->_xmm[7], num128, sizeof(struct _xmmreg_ia32));
-	return 0;
-}
-
-static int
-restore_ia32_fpstate_live (struct _fpstate_ia32 __user *save)
-{
-	struct task_struct *tsk = current;
-	struct pt_regs *ptp;
-	unsigned int lo, hi;
-	unsigned long num128[2];
-	unsigned long num64, mxcsr;
-	struct _fpreg_ia32 *fpregp;
-	char buf[32];
-	unsigned long fsr, fcr, fir, fdr;
-	int fp_tos, fr8_st_map;
-
-	if (!access_ok(VERIFY_READ, save, sizeof(*save)))
-		return(-EFAULT);
-
-	/*
-	 * Updating fsr, fcr, fir, fdr.
-	 * Just a bit more complicated than save.
-	 * - Need to make sure that we don't write any value other than the
-	 *   specific fpstate info
-	 * - Need to make sure that the untouched part of frs, fdr, fir, fcr
-	 *   should remain same while writing.
-	 * So, we do a read, change specific fields and write.
-	 */
-	fsr = ia64_getreg(_IA64_REG_AR_FSR);
-	fcr = ia64_getreg(_IA64_REG_AR_FCR);
-	fir = ia64_getreg(_IA64_REG_AR_FIR);
-	fdr = ia64_getreg(_IA64_REG_AR_FDR);
-
-	__get_user(mxcsr, (unsigned int __user *)&save->mxcsr);
-	/* setting bits 0..5 8..12 with cw and 39..47 from mxcsr */
-	__get_user(lo, (unsigned int __user *)&save->cw);
-	num64 = mxcsr & 0xff10;
-	num64 = (num64 << 32) | (lo & 0x1f3f);
-	fcr = (fcr & (~0xff1000001f3fUL)) | num64;
-
-	/* setting bits 0..31 with sw and tag and 32..37 from mxcsr */
-	__get_user(lo, (unsigned int __user *)&save->sw);
-	/* set bits 15,7 (fsw.b, fsw.es) to reflect the current error status */
-	if ( !(lo & 0x7f) )
-		lo &= (~0x8080);
-	__get_user(hi, (unsigned int __user *)&save->tag);
-	num64 = mxcsr & 0x3f;
-	num64 = (num64 << 16) | (hi & 0xffff);
-	num64 = (num64 << 16) | (lo & 0xffff);
-	fsr = (fsr & (~0x3fffffffffUL)) | num64;
-
-	/* setting bits 0..47 with cssel and ipoff */
-	__get_user(lo, (unsigned int __user *)&save->ipoff);
-	__get_user(hi, (unsigned int __user *)&save->cssel);
-	num64 = hi & 0xffff;
-	num64 = (num64 << 32) | lo;
-	fir = (fir & (~0xffffffffffffUL)) | num64;
-
-	/* setting bits 0..47 with datasel and dataoff */
-	__get_user(lo, (unsigned int __user *)&save->dataoff);
-	__get_user(hi, (unsigned int __user *)&save->datasel);
-	num64 = hi & 0xffff;
-	num64 = (num64 << 32) | lo;
-	fdr = (fdr & (~0xffffffffffffUL)) | num64;
-
-	ia64_setreg(_IA64_REG_AR_FSR, fsr);
-	ia64_setreg(_IA64_REG_AR_FCR, fcr);
-	ia64_setreg(_IA64_REG_AR_FIR, fir);
-	ia64_setreg(_IA64_REG_AR_FDR, fdr);
-
-	/*
-	 * restore f8..f11 onto pt_regs
-	 * restore f12..f15 onto live registers
-	 */
-	/*
-	 *  Find the location where f8 has to go in fp reg stack.  This depends on
-	 *  TOP(11:13) field of sw. Other f reg continue sequentially from where f8 maps
-	 *  to.
-	 */
-	fp_tos = (fsr>>11)&0x7;
-	fr8_st_map = (8-fp_tos)&0x7;
-	fpregp = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
-
-	ptp = task_pt_regs(tsk);
-	copy_from_user(fpregp, &save->_st[(0+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
-	ia32f2ia64f(&ptp->f8, fpregp);
-	copy_from_user(fpregp, &save->_st[(1+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
-	ia32f2ia64f(&ptp->f9, fpregp);
-	copy_from_user(fpregp, &save->_st[(2+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
-	ia32f2ia64f(&ptp->f10, fpregp);
-	copy_from_user(fpregp, &save->_st[(3+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
-	ia32f2ia64f(&ptp->f11, fpregp);
-
-	copy_from_user(fpregp, &save->_st[(4+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
-	ia64_ldfe(12, fpregp);
-	copy_from_user(fpregp, &save->_st[(5+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
-	ia64_ldfe(13, fpregp);
-	copy_from_user(fpregp, &save->_st[(6+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
-	ia64_ldfe(14, fpregp);
-	copy_from_user(fpregp, &save->_st[(7+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
-	ia64_ldfe(15, fpregp);
-
-	copy_from_user(num128, &save->_xmm[0], sizeof(struct _xmmreg_ia32));
-	ia64_ldf8(16, &num128[0]);
-	ia64_ldf8(17, &num128[1]);
-
-	copy_from_user(num128, &save->_xmm[1], sizeof(struct _xmmreg_ia32));
-	ia64_ldf8(18, &num128[0]);
-	ia64_ldf8(19, &num128[1]);
-
-	copy_from_user(num128, &save->_xmm[2], sizeof(struct _xmmreg_ia32));
-	ia64_ldf8(20, &num128[0]);
-	ia64_ldf8(21, &num128[1]);
-
-	copy_from_user(num128, &save->_xmm[3], sizeof(struct _xmmreg_ia32));
-	ia64_ldf8(22, &num128[0]);
-	ia64_ldf8(23, &num128[1]);
-
-	copy_from_user(num128, &save->_xmm[4], sizeof(struct _xmmreg_ia32));
-	ia64_ldf8(24, &num128[0]);
-	ia64_ldf8(25, &num128[1]);
-
-	copy_from_user(num128, &save->_xmm[5], sizeof(struct _xmmreg_ia32));
-	ia64_ldf8(26, &num128[0]);
-	ia64_ldf8(27, &num128[1]);
-
-	copy_from_user(num128, &save->_xmm[6], sizeof(struct _xmmreg_ia32));
-	ia64_ldf8(28, &num128[0]);
-	ia64_ldf8(29, &num128[1]);
-
-	copy_from_user(num128, &save->_xmm[7], sizeof(struct _xmmreg_ia32));
-	ia64_ldf8(30, &num128[0]);
-	ia64_ldf8(31, &num128[1]);
-	return 0;
-}
-
-static inline void
-sigact_set_handler (struct k_sigaction *sa, unsigned int handler, unsigned int restorer)
-{
-	if (handler + 1 <= 2)
-		/* SIG_DFL, SIG_IGN, or SIG_ERR: must sign-extend to 64-bits */
-		sa->sa.sa_handler = (__sighandler_t) A((int) handler);
-	else
-		sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler);
-}
-
-asmlinkage long
-sys32_sigsuspend (int history0, int history1, old_sigset_t mask)
-{
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
-	current->saved_sigmask = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	current->state = TASK_INTERRUPTIBLE;
-	schedule();
-	set_restore_sigmask();
-	return -ERESTARTNOHAND;
-}
-
-asmlinkage long
-sys32_signal (int sig, unsigned int handler)
-{
-	struct k_sigaction new_sa, old_sa;
-	int ret;
-
-	sigact_set_handler(&new_sa, handler, 0);
-	new_sa.sa.sa_flags = SA_ONESHOT | SA_NOMASK;
-	sigemptyset(&new_sa.sa.sa_mask);
-
-	ret = do_sigaction(sig, &new_sa, &old_sa);
-
-	return ret ? ret : IA32_SA_HANDLER(&old_sa);
-}
-
-asmlinkage long
-sys32_rt_sigaction (int sig, struct sigaction32 __user *act,
-		    struct sigaction32 __user *oact, unsigned int sigsetsize)
-{
-	struct k_sigaction new_ka, old_ka;
-	unsigned int handler, restorer;
-	int ret;
-
-	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(compat_sigset_t))
-		return -EINVAL;
-
-	if (act) {
-		ret = get_user(handler, &act->sa_handler);
-		ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
-		ret |= get_user(restorer, &act->sa_restorer);
-		ret |= copy_from_user(&new_ka.sa.sa_mask, &act->sa_mask, sizeof(compat_sigset_t));
-		if (ret)
-			return -EFAULT;
-
-		sigact_set_handler(&new_ka, handler, restorer);
-	}
-
-	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
-
-	if (!ret && oact) {
-		ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler);
-		ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-		ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer);
-		ret |= copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, sizeof(compat_sigset_t));
-	}
-	return ret;
-}
-
-
-asmlinkage long
-sys32_rt_sigprocmask (int how, compat_sigset_t __user *set, compat_sigset_t __user *oset,
-		      unsigned int sigsetsize)
-{
-	mm_segment_t old_fs = get_fs();
-	sigset_t s;
-	long ret;
-
-	if (sigsetsize > sizeof(s))
-		return -EINVAL;
-
-	if (set) {
-		memset(&s, 0, sizeof(s));
-		if (copy_from_user(&s.sig, set, sigsetsize))
-			return -EFAULT;
-	}
-	set_fs(KERNEL_DS);
-	ret = sys_rt_sigprocmask(how,
-				 set ? (sigset_t __user *) &s : NULL,
-				 oset ? (sigset_t __user *) &s : NULL, sizeof(s));
-	set_fs(old_fs);
-	if (ret)
-		return ret;
-	if (oset) {
-		if (copy_to_user(oset, &s.sig, sigsetsize))
-			return -EFAULT;
-	}
-	return 0;
-}
-
-asmlinkage long
-sys32_rt_sigqueueinfo (int pid, int sig, compat_siginfo_t __user *uinfo)
-{
-	mm_segment_t old_fs = get_fs();
-	siginfo_t info;
-	int ret;
-
-	if (copy_siginfo_from_user32(&info, uinfo))
-		return -EFAULT;
-	set_fs(KERNEL_DS);
-	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
-	set_fs(old_fs);
-	return ret;
-}
-
-asmlinkage long
-sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigaction32 __user *oact)
-{
-	struct k_sigaction new_ka, old_ka;
-	unsigned int handler, restorer;
-	int ret;
-
-	if (act) {
-		compat_old_sigset_t mask;
-
-		ret = get_user(handler, &act->sa_handler);
-		ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
-		ret |= get_user(restorer, &act->sa_restorer);
-		ret |= get_user(mask, &act->sa_mask);
-		if (ret)
-			return ret;
-
-		sigact_set_handler(&new_ka, handler, restorer);
-		siginitset(&new_ka.sa.sa_mask, mask);
-	}
-
-	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
-
-	if (!ret && oact) {
-		ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler);
-		ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-		ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer);
-		ret |= put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
-	}
-
-	return ret;
-}
-
-static int
-setup_sigcontext_ia32 (struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __user *fpstate,
-		       struct pt_regs *regs, unsigned long mask)
-{
-	int  err = 0;
-	unsigned long flag;
-
-	if (!access_ok(VERIFY_WRITE, sc, sizeof(*sc)))
-		return -EFAULT;
-
-	err |= __put_user((regs->r16 >> 32) & 0xffff, (unsigned int __user *)&sc->fs);
-	err |= __put_user((regs->r16 >> 48) & 0xffff, (unsigned int __user *)&sc->gs);
-	err |= __put_user((regs->r16 >> 16) & 0xffff, (unsigned int __user *)&sc->es);
-	err |= __put_user(regs->r16 & 0xffff, (unsigned int __user *)&sc->ds);
-	err |= __put_user(regs->r15, &sc->edi);
-	err |= __put_user(regs->r14, &sc->esi);
-	err |= __put_user(regs->r13, &sc->ebp);
-	err |= __put_user(regs->r12, &sc->esp);
-	err |= __put_user(regs->r11, &sc->ebx);
-	err |= __put_user(regs->r10, &sc->edx);
-	err |= __put_user(regs->r9, &sc->ecx);
-	err |= __put_user(regs->r8, &sc->eax);
-#if 0
-	err |= __put_user(current->tss.trap_no, &sc->trapno);
-	err |= __put_user(current->tss.error_code, &sc->err);
-#endif
-	err |= __put_user(regs->cr_iip, &sc->eip);
-	err |= __put_user(regs->r17 & 0xffff, (unsigned int __user *)&sc->cs);
-	/*
-	 *  `eflags' is in an ar register for this context
-	 */
-	flag = ia64_getreg(_IA64_REG_AR_EFLAG);
-	err |= __put_user((unsigned int)flag, &sc->eflags);
-	err |= __put_user(regs->r12, &sc->esp_at_signal);
-	err |= __put_user((regs->r17 >> 16) & 0xffff, (unsigned int __user *)&sc->ss);
-
-	if ( save_ia32_fpstate_live(fpstate) < 0 )
-		err = -EFAULT;
-	else
-		err |= __put_user((u32)(u64)fpstate, &sc->fpstate);
-
-#if 0
-	tmp = save_i387(fpstate);
-	if (tmp < 0)
-		err = 1;
-	else
-		err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
-
-	/* non-iBCS2 extensions.. */
-#endif
-	err |= __put_user(mask, &sc->oldmask);
-#if 0
-	err |= __put_user(current->tss.cr2, &sc->cr2);
-#endif
-	return err;
-}
-
-static int
-restore_sigcontext_ia32 (struct pt_regs *regs, struct sigcontext_ia32 __user *sc, int *peax)
-{
-	unsigned int err = 0;
-
-	/* Always make any pending restarted system calls return -EINTR */
-	current_thread_info()->restart_block.fn = do_no_restart_syscall;
-
-	if (!access_ok(VERIFY_READ, sc, sizeof(*sc)))
-		return(-EFAULT);
-
-#define COPY(ia64x, ia32x)	err |= __get_user(regs->ia64x, &sc->ia32x)
-
-#define copyseg_gs(tmp)		(regs->r16 |= (unsigned long) (tmp) << 48)
-#define copyseg_fs(tmp)		(regs->r16 |= (unsigned long) (tmp) << 32)
-#define copyseg_cs(tmp)		(regs->r17 |= tmp)
-#define copyseg_ss(tmp)		(regs->r17 |= (unsigned long) (tmp) << 16)
-#define copyseg_es(tmp)		(regs->r16 |= (unsigned long) (tmp) << 16)
-#define copyseg_ds(tmp)		(regs->r16 |= tmp)
-
-#define COPY_SEG(seg)					\
-	{						\
-		unsigned short tmp;			\
-		err |= __get_user(tmp, &sc->seg);	\
-		copyseg_##seg(tmp);			\
-	}
-#define COPY_SEG_STRICT(seg)				\
-	{						\
-		unsigned short tmp;			\
-		err |= __get_user(tmp, &sc->seg);	\
-		copyseg_##seg(tmp|3);			\
-	}
-
-	/* To make COPY_SEGs easier, we zero r16, r17 */
-	regs->r16 = 0;
-	regs->r17 = 0;
-
-	COPY_SEG(gs);
-	COPY_SEG(fs);
-	COPY_SEG(es);
-	COPY_SEG(ds);
-	COPY(r15, edi);
-	COPY(r14, esi);
-	COPY(r13, ebp);
-	COPY(r12, esp);
-	COPY(r11, ebx);
-	COPY(r10, edx);
-	COPY(r9, ecx);
-	COPY(cr_iip, eip);
-	COPY_SEG_STRICT(cs);
-	COPY_SEG_STRICT(ss);
-	ia32_load_segment_descriptors(current);
-	{
-		unsigned int tmpflags;
-		unsigned long flag;
-
-		/*
-		 *  IA32 `eflags' is not part of `pt_regs', it's in an ar register which
-		 *  is part of the thread context.  Fortunately, we are executing in the
-		 *  IA32 process's context.
-		 */
-		err |= __get_user(tmpflags, &sc->eflags);
-		flag = ia64_getreg(_IA64_REG_AR_EFLAG);
-		flag &= ~0x40DD5;
-		flag |= (tmpflags & 0x40DD5);
-		ia64_setreg(_IA64_REG_AR_EFLAG, flag);
-
-		regs->r1 = -1;	/* disable syscall checks, r1 is orig_eax */
-	}
-
-	{
-		struct _fpstate_ia32 __user *buf = NULL;
-		u32    fpstate_ptr;
-		err |= get_user(fpstate_ptr, &(sc->fpstate));
-		buf = compat_ptr(fpstate_ptr);
-		if (buf) {
-			err |= restore_ia32_fpstate_live(buf);
-		}
-	}
-
-#if 0
-	{
-		struct _fpstate * buf;
-		err |= __get_user(buf, &sc->fpstate);
-		if (buf) {
-			if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
-				goto badframe;
-			err |= restore_i387(buf);
-		}
-	}
-#endif
-
-	err |= __get_user(*peax, &sc->eax);
-	return err;
-
-#if 0
-  badframe:
-	return 1;
-#endif
-}
-
-/*
- * Determine which stack to use..
- */
-static inline void __user *
-get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
-{
-	unsigned long esp;
-
-	/* Default to using normal stack (truncate off sign-extension of bit 31: */
-	esp = (unsigned int) regs->r12;
-
-	/* This is the X/Open sanctioned signal stack switching.  */
-	if (ka->sa.sa_flags & SA_ONSTACK) {
-		int onstack = sas_ss_flags(esp);
-
-		if (onstack == 0)
-			esp = current->sas_ss_sp + current->sas_ss_size;
-		else if (onstack == SS_ONSTACK) {
-			/*
-			 * 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 (!likely(on_sig_stack(esp - frame_size)))
-				return (void __user *) -1L;
-		}
-	}
-	/* Legacy stack switching not supported */
-
-	esp -= frame_size;
-	/* Align the stack pointer according to the i386 ABI,
-	 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
-	esp = ((esp + 4) & -16ul) - 4;
-	return (void __user *) esp;
-}
-
-static int
-setup_frame_ia32 (int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs)
-{
-	struct exec_domain *ed = current_thread_info()->exec_domain;
-	struct sigframe_ia32 __user *frame;
-	int err = 0;
-
-	frame = get_sigframe(ka, regs, sizeof(*frame));
-
-	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-		goto give_sigsegv;
-
-	err |= __put_user((ed && ed->signal_invmap && sig < 32
-			   ? (int)(ed->signal_invmap[sig]) : sig), &frame->sig);
-
-	err |= setup_sigcontext_ia32(&frame->sc, &frame->fpstate, regs, set->sig[0]);
-
-	if (_COMPAT_NSIG_WORDS > 1)
-		err |= __copy_to_user(frame->extramask, (char *) &set->sig + 4,
-				      sizeof(frame->extramask));
-
-	/* Set up to return from userspace.  If provided, use a stub
-	   already in userspace.  */
-	if (ka->sa.sa_flags & SA_RESTORER) {
-		unsigned int restorer = IA32_SA_RESTORER(ka);
-		err |= __put_user(restorer, &frame->pretcode);
-	} else {
-		/* Pointing to restorer in ia32 gate page */
-		err |= __put_user(IA32_GATE_OFFSET, &frame->pretcode);
-	}
-
-	/* This is popl %eax ; movl $,%eax ; int $0x80
-	 * and there for historical reasons only.
-	 * See arch/i386/kernel/signal.c
-	 */
-
-	err |= __put_user(0xb858, (short __user *)(frame->retcode+0));
-	err |= __put_user(__IA32_NR_sigreturn, (int __user *)(frame->retcode+2));
-	err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
-
-	if (err)
-		goto give_sigsegv;
-
-	/* Set up registers for signal handler */
-	regs->r12 = (unsigned long) frame;
-	regs->cr_iip = IA32_SA_HANDLER(ka);
-
-	set_fs(USER_DS);
-
-#if 0
-	regs->eflags &= ~TF_MASK;
-#endif
-
-#if 0
-	printk("SIG deliver (%s:%d): sig=%d sp=%p pc=%lx ra=%x\n",
-               current->comm, current->pid, sig, (void *) frame, regs->cr_iip, frame->pretcode);
-#endif
-
-	return 1;
-
-  give_sigsegv:
-	force_sigsegv(sig, current);
-	return 0;
-}
-
-static int
-setup_rt_frame_ia32 (int sig, struct k_sigaction *ka, siginfo_t *info,
-		     sigset_t *set, struct pt_regs * regs)
-{
-	struct exec_domain *ed = current_thread_info()->exec_domain;
-	compat_uptr_t pinfo, puc;
-	struct rt_sigframe_ia32 __user *frame;
-	int err = 0;
-
-	frame = get_sigframe(ka, regs, sizeof(*frame));
-
-	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-		goto give_sigsegv;
-
-	err |= __put_user((ed && ed->signal_invmap
-			   && sig < 32 ? ed->signal_invmap[sig] : sig), &frame->sig);
-
-	pinfo = (long __user) &frame->info;
-	puc = (long __user) &frame->uc;
-	err |= __put_user(pinfo, &frame->pinfo);
-	err |= __put_user(puc, &frame->puc);
-	err |= copy_siginfo_to_user32(&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(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-	err |= __put_user(sas_ss_flags(regs->r12), &frame->uc.uc_stack.ss_flags);
-	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
-	err |= setup_sigcontext_ia32(&frame->uc.uc_mcontext, &frame->fpstate, regs, set->sig[0]);
-	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
-	if (err)
-		goto give_sigsegv;
-
-	/* Set up to return from userspace.  If provided, use a stub
-	   already in userspace.  */
-	if (ka->sa.sa_flags & SA_RESTORER) {
-		unsigned int restorer = IA32_SA_RESTORER(ka);
-		err |= __put_user(restorer, &frame->pretcode);
-	} else {
-		/* Pointing to rt_restorer in ia32 gate page */
-		err |= __put_user(IA32_GATE_OFFSET + 8, &frame->pretcode);
-	}
-
-	/* This is movl $,%eax ; int $0x80
-	 * and there for historical reasons only.
-	 * See arch/i386/kernel/signal.c
-	 */
-
-	err |= __put_user(0xb8, (char __user *)(frame->retcode+0));
-	err |= __put_user(__IA32_NR_rt_sigreturn, (int __user *)(frame->retcode+1));
-	err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
-
-	if (err)
-		goto give_sigsegv;
-
-	/* Set up registers for signal handler */
-	regs->r12 = (unsigned long) frame;
-	regs->cr_iip = IA32_SA_HANDLER(ka);
-
-	set_fs(USER_DS);
-
-#if 0
-	regs->eflags &= ~TF_MASK;
-#endif
-
-#if 0
-	printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%x\n",
-               current->comm, current->pid, (void *) frame, regs->cr_iip, frame->pretcode);
-#endif
-
-	return 1;
-
-give_sigsegv:
-	force_sigsegv(sig, current);
-	return 0;
-}
-
-int
-ia32_setup_frame1 (int sig, struct k_sigaction *ka, siginfo_t *info,
-		   sigset_t *set, struct pt_regs *regs)
-{
-       /* Set up the stack frame */
-       if (ka->sa.sa_flags & SA_SIGINFO)
-               return setup_rt_frame_ia32(sig, ka, info, set, regs);
-       else
-               return setup_frame_ia32(sig, ka, set, regs);
-}
-
-asmlinkage long
-sys32_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5,
-		 int arg6, int arg7, struct pt_regs regs)
-{
-	unsigned long esp = (unsigned int) regs.r12;
-	struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(esp - 8);
-	sigset_t set;
-	int eax;
-
-	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
-		goto badframe;
-
-	if (__get_user(set.sig[0], &frame->sc.oldmask)
-	    || (_COMPAT_NSIG_WORDS > 1 && __copy_from_user((char *) &set.sig + 4, &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_ia32(&regs, &frame->sc, &eax))
-		goto badframe;
-	return eax;
-
-  badframe:
-	force_sig(SIGSEGV, current);
-	return 0;
-}
-
-asmlinkage long
-sys32_rt_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4,
-		    int arg5, int arg6, int arg7, struct pt_regs regs)
-{
-	unsigned long esp = (unsigned int) regs.r12;
-	struct rt_sigframe_ia32 __user *frame = (struct rt_sigframe_ia32 __user *)(esp - 4);
-	sigset_t set;
-	int eax;
-
-	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_ia32(&regs, &frame->uc.uc_mcontext, &eax))
-		goto badframe;
-
-	/* It is more difficult to avoid calling this function than to
-	   call it and ignore errors.  */
-	do_sigaltstack((stack_t __user *) &frame->uc.uc_stack, NULL, esp);
-
-	return eax;
-
-  badframe:
-	force_sig(SIGSEGV, current);
-	return 0;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/ia32/ia32_support.c linux-libre-2.6.34-gnu1/arch/ia64/ia32/ia32_support.c
--- linux-libre-2.6.33-gnu1/arch/ia64/ia32/ia32_support.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/ia32/ia32_support.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,253 +0,0 @@
-/*
- * IA32 helper functions
- *
- * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
- * Copyright (C) 2000 Asit K. Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 2001-2002 Hewlett-Packard Co
- *	David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * 06/16/00	A. Mallick	added csd/ssd/tssd for ia32 thread context
- * 02/19/01	D. Mosberger	dropped tssd; it's not needed
- * 09/14/01	D. Mosberger	fixed memory management for gdt/tss page
- * 09/29/01	D. Mosberger	added ia32_load_segment_descriptors()
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-
-#include <asm/intrinsics.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-
-#include "ia32priv.h"
-
-extern int die_if_kernel (char *str, struct pt_regs *regs, long err);
-
-struct page *ia32_shared_page[NR_CPUS];
-unsigned long *ia32_boot_gdt;
-unsigned long *cpu_gdt_table[NR_CPUS];
-struct page *ia32_gate_page;
-
-static unsigned long
-load_desc (u16 selector)
-{
-	unsigned long *table, limit, index;
-
-	if (!selector)
-		return 0;
-	if (selector & IA32_SEGSEL_TI) {
-		table = (unsigned long *) IA32_LDT_OFFSET;
-		limit = IA32_LDT_ENTRIES;
-	} else {
-		table = cpu_gdt_table[smp_processor_id()];
-		limit = IA32_PAGE_SIZE / sizeof(ia32_boot_gdt[0]);
-	}
-	index = selector >> IA32_SEGSEL_INDEX_SHIFT;
-	if (index >= limit)
-		return 0;
-	return IA32_SEG_UNSCRAMBLE(table[index]);
-}
-
-void
-ia32_load_segment_descriptors (struct task_struct *task)
-{
-	struct pt_regs *regs = task_pt_regs(task);
-
-	/* Setup the segment descriptors */
-	regs->r24 = load_desc(regs->r16 >> 16);		/* ESD */
-	regs->r27 = load_desc(regs->r16 >>  0);		/* DSD */
-	regs->r28 = load_desc(regs->r16 >> 32);		/* FSD */
-	regs->r29 = load_desc(regs->r16 >> 48);		/* GSD */
-	regs->ar_csd = load_desc(regs->r17 >>  0);	/* CSD */
-	regs->ar_ssd = load_desc(regs->r17 >> 16);	/* SSD */
-}
-
-int
-ia32_clone_tls (struct task_struct *child, struct pt_regs *childregs)
-{
-	struct desc_struct *desc;
-	struct ia32_user_desc info;
-	int idx;
-
-	if (copy_from_user(&info, (void __user *)(childregs->r14 & 0xffffffff), sizeof(info)))
-		return -EFAULT;
-	if (LDT_empty(&info))
-		return -EINVAL;
-
-	idx = info.entry_number;
-	if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
-		return -EINVAL;
-
-	desc = child->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
-	desc->a = LDT_entry_a(&info);
-	desc->b = LDT_entry_b(&info);
-
-	/* XXX: can this be done in a cleaner way ? */
-	load_TLS(&child->thread, smp_processor_id());
-	ia32_load_segment_descriptors(child);
-	load_TLS(&current->thread, smp_processor_id());
-
-	return 0;
-}
-
-void
-ia32_save_state (struct task_struct *t)
-{
-	t->thread.eflag = ia64_getreg(_IA64_REG_AR_EFLAG);
-	t->thread.fsr   = ia64_getreg(_IA64_REG_AR_FSR);
-	t->thread.fcr   = ia64_getreg(_IA64_REG_AR_FCR);
-	t->thread.fir   = ia64_getreg(_IA64_REG_AR_FIR);
-	t->thread.fdr   = ia64_getreg(_IA64_REG_AR_FDR);
-	ia64_set_kr(IA64_KR_IO_BASE, t->thread.old_iob);
-	ia64_set_kr(IA64_KR_TSSD, t->thread.old_k1);
-}
-
-void
-ia32_load_state (struct task_struct *t)
-{
-	unsigned long eflag, fsr, fcr, fir, fdr, tssd;
-	struct pt_regs *regs = task_pt_regs(t);
-
-	eflag = t->thread.eflag;
-	fsr = t->thread.fsr;
-	fcr = t->thread.fcr;
-	fir = t->thread.fir;
-	fdr = t->thread.fdr;
-	tssd = load_desc(_TSS);					/* TSSD */
-
-	ia64_setreg(_IA64_REG_AR_EFLAG, eflag);
-	ia64_setreg(_IA64_REG_AR_FSR, fsr);
-	ia64_setreg(_IA64_REG_AR_FCR, fcr);
-	ia64_setreg(_IA64_REG_AR_FIR, fir);
-	ia64_setreg(_IA64_REG_AR_FDR, fdr);
-	current->thread.old_iob = ia64_get_kr(IA64_KR_IO_BASE);
-	current->thread.old_k1 = ia64_get_kr(IA64_KR_TSSD);
-	ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE);
-	ia64_set_kr(IA64_KR_TSSD, tssd);
-
-	regs->r17 = (_TSS << 48) | (_LDT << 32) | (__u32) regs->r17;
-	regs->r30 = load_desc(_LDT);				/* LDTD */
-	load_TLS(&t->thread, smp_processor_id());
-}
-
-/*
- * Setup IA32 GDT and TSS
- */
-void
-ia32_gdt_init (void)
-{
-	int cpu = smp_processor_id();
-
-	ia32_shared_page[cpu] = alloc_page(GFP_KERNEL);
-	if (!ia32_shared_page[cpu])
-		panic("failed to allocate ia32_shared_page[%d]\n", cpu);
-
-	cpu_gdt_table[cpu] = page_address(ia32_shared_page[cpu]);
-
-	/* Copy from the boot cpu's GDT */
-	memcpy(cpu_gdt_table[cpu], ia32_boot_gdt, PAGE_SIZE);
-}
-
-
-/*
- * Setup IA32 GDT and TSS
- */
-static void
-ia32_boot_gdt_init (void)
-{
-	unsigned long ldt_size;
-
-	ia32_shared_page[0] = alloc_page(GFP_KERNEL);
-	if (!ia32_shared_page[0])
-		panic("failed to allocate ia32_shared_page[0]\n");
-
-	ia32_boot_gdt = page_address(ia32_shared_page[0]);
-	cpu_gdt_table[0] = ia32_boot_gdt;
-
-	/* CS descriptor in IA-32 (scrambled) format */
-	ia32_boot_gdt[__USER_CS >> 3]
-		= IA32_SEG_DESCRIPTOR(0, (IA32_GATE_END-1) >> IA32_PAGE_SHIFT,
-				      0xb, 1, 3, 1, 1, 1, 1);
-
-	/* DS descriptor in IA-32 (scrambled) format */
-	ia32_boot_gdt[__USER_DS >> 3]
-		= IA32_SEG_DESCRIPTOR(0, (IA32_GATE_END-1) >> IA32_PAGE_SHIFT,
-				      0x3, 1, 3, 1, 1, 1, 1);
-
-	ldt_size = PAGE_ALIGN(IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE);
-	ia32_boot_gdt[TSS_ENTRY] = IA32_SEG_DESCRIPTOR(IA32_TSS_OFFSET, 235,
-						       0xb, 0, 3, 1, 1, 1, 0);
-	ia32_boot_gdt[LDT_ENTRY] = IA32_SEG_DESCRIPTOR(IA32_LDT_OFFSET, ldt_size - 1,
-						       0x2, 0, 3, 1, 1, 1, 0);
-}
-
-static void
-ia32_gate_page_init(void)
-{
-	unsigned long *sr;
-
-	ia32_gate_page = alloc_page(GFP_KERNEL);
-	sr = page_address(ia32_gate_page);
-	/* This is popl %eax ; movl $,%eax ; int $0x80 */
-	*sr++ = 0xb858 | (__IA32_NR_sigreturn << 16) | (0x80cdUL << 48);
-
-	/* This is movl $,%eax ; int $0x80 */
-	*sr = 0xb8 | (__IA32_NR_rt_sigreturn << 8) | (0x80cdUL << 40);
-}
-
-void
-ia32_mem_init(void)
-{
-	ia32_boot_gdt_init();
-	ia32_gate_page_init();
-}
-
-/*
- * Handle bad IA32 interrupt via syscall
- */
-void
-ia32_bad_interrupt (unsigned long int_num, struct pt_regs *regs)
-{
-	siginfo_t siginfo;
-
-	if (die_if_kernel("Bad IA-32 interrupt", regs, int_num))
-		return;
-
-	siginfo.si_signo = SIGTRAP;
-	siginfo.si_errno = int_num;	/* XXX is it OK to abuse si_errno like this? */
-	siginfo.si_flags = 0;
-	siginfo.si_isr = 0;
-	siginfo.si_addr = NULL;
-	siginfo.si_imm = 0;
-	siginfo.si_code = TRAP_BRKPT;
-	force_sig_info(SIGTRAP, &siginfo, current);
-}
-
-void
-ia32_cpu_init (void)
-{
-	/* initialize global ia32 state - CR0 and CR4 */
-	ia64_setreg(_IA64_REG_AR_CFLAG, (((ulong) IA32_CR4 << 32) | IA32_CR0));
-}
-
-static int __init
-ia32_init (void)
-{
-#if PAGE_SHIFT > IA32_PAGE_SHIFT
-	{
-		extern struct kmem_cache *ia64_partial_page_cachep;
-
-		ia64_partial_page_cachep = kmem_cache_create("ia64_partial_page_cache",
-					sizeof(struct ia64_partial_page),
-					0, SLAB_PANIC, NULL);
-	}
-#endif
-	return 0;
-}
-
-__initcall(ia32_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/ia32/ia32_traps.c linux-libre-2.6.34-gnu1/arch/ia64/ia32/ia32_traps.c
--- linux-libre-2.6.33-gnu1/arch/ia64/ia32/ia32_traps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/ia32/ia32_traps.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,156 +0,0 @@
-/*
- * IA-32 exception handlers
- *
- * Copyright (C) 2000 Asit K. Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 2001-2002 Hewlett-Packard Co
- *	David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * 06/16/00	A. Mallick	added siginfo for most cases (close to IA32)
- * 09/29/00	D. Mosberger	added ia32_intercept()
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include "ia32priv.h"
-
-#include <asm/intrinsics.h>
-#include <asm/ptrace.h>
-
-int
-ia32_intercept (struct pt_regs *regs, unsigned long isr)
-{
-	switch ((isr >> 16) & 0xff) {
-	      case 0:	/* Instruction intercept fault */
-	      case 4:	/* Locked Data reference fault */
-	      case 1:	/* Gate intercept trap */
-		return -1;
-
-	      case 2:	/* System flag trap */
-		if (((isr >> 14) & 0x3) >= 2) {
-			/* MOV SS, POP SS instructions */
-			ia64_psr(regs)->id = 1;
-			return 0;
-		} else
-			return -1;
-	}
-	return -1;
-}
-
-int
-ia32_exception (struct pt_regs *regs, unsigned long isr)
-{
-	struct siginfo siginfo;
-
-	/* initialize these fields to avoid leaking kernel bits to user space: */
-	siginfo.si_errno = 0;
-	siginfo.si_flags = 0;
-	siginfo.si_isr = 0;
-	siginfo.si_imm = 0;
-	switch ((isr >> 16) & 0xff) {
-	      case 1:
-	      case 2:
-		siginfo.si_signo = SIGTRAP;
-		if (isr == 0)
-			siginfo.si_code = TRAP_TRACE;
-		else if (isr & 0x4)
-			siginfo.si_code = TRAP_BRANCH;
-		else
-			siginfo.si_code = TRAP_BRKPT;
-		break;
-
-	      case 3:
-		siginfo.si_signo = SIGTRAP;
-		siginfo.si_code = TRAP_BRKPT;
-		break;
-
-	      case 0:	/* Divide fault */
-		siginfo.si_signo = SIGFPE;
-		siginfo.si_code = FPE_INTDIV;
-		break;
-
-	      case 4:	/* Overflow */
-	      case 5:	/* Bounds fault */
-		siginfo.si_signo = SIGFPE;
-		siginfo.si_code = 0;
-		break;
-
-	      case 6:	/* Invalid Op-code */
-		siginfo.si_signo = SIGILL;
-		siginfo.si_code = ILL_ILLOPN;
-		break;
-
-	      case 7:	/* FP DNA */
-	      case 8:	/* Double Fault */
-	      case 9:	/* Invalid TSS */
-	      case 11:	/* Segment not present */
-	      case 12:	/* Stack fault */
-	      case 13:	/* General Protection Fault */
-		siginfo.si_signo = SIGSEGV;
-		siginfo.si_code = 0;
-		break;
-
-	      case 16:	/* Pending FP error */
-		{
-			unsigned long fsr, fcr;
-
-			fsr = ia64_getreg(_IA64_REG_AR_FSR);
-			fcr = ia64_getreg(_IA64_REG_AR_FCR);
-
-			siginfo.si_signo = SIGFPE;
-			/*
-			 * (~cwd & swd) will mask out exceptions that are not set to unmasked
-			 * status.  0x3f is the exception bits in these regs, 0x200 is the
-			 * C1 reg you need in case of a stack fault, 0x040 is the stack
-			 * fault bit.  We should only be taking one exception at a time,
-			 * so if this combination doesn't produce any single exception,
-			 * then we have a bad program that isn't synchronizing its FPU usage
-			 * and it will suffer the consequences since we won't be able to
-			 * fully reproduce the context of the exception
-			 */
-			siginfo.si_isr = isr;
-			siginfo.si_flags = __ISR_VALID;
-			switch(((~fcr) & (fsr & 0x3f)) | (fsr & 0x240)) {
-				case 0x000:
-				default:
-					siginfo.si_code = 0;
-					break;
-				case 0x001: /* Invalid Op */
-				case 0x040: /* Stack Fault */
-				case 0x240: /* Stack Fault | Direction */
-					siginfo.si_code = FPE_FLTINV;
-					break;
-				case 0x002: /* Denormalize */
-				case 0x010: /* Underflow */
-					siginfo.si_code = FPE_FLTUND;
-					break;
-				case 0x004: /* Zero Divide */
-					siginfo.si_code = FPE_FLTDIV;
-					break;
-				case 0x008: /* Overflow */
-					siginfo.si_code = FPE_FLTOVF;
-					break;
-				case 0x020: /* Precision */
-					siginfo.si_code = FPE_FLTRES;
-					break;
-			}
-
-			break;
-		}
-
-	      case 17:	/* Alignment check */
-		siginfo.si_signo = SIGSEGV;
-		siginfo.si_code = BUS_ADRALN;
-		break;
-
-	      case 19:	/* SSE Numeric error */
-		siginfo.si_signo = SIGFPE;
-		siginfo.si_code = 0;
-		break;
-
-	      default:
-		return -1;
-	}
-	force_sig_info(siginfo.si_signo, &siginfo, current);
-	return 0;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/ia32/Makefile linux-libre-2.6.34-gnu1/arch/ia64/ia32/Makefile
--- linux-libre-2.6.33-gnu1/arch/ia64/ia32/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/ia32/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,11 +0,0 @@
-#
-# Makefile for the ia32 kernel emulation subsystem.
-#
-
-obj-y := ia32_entry.o sys_ia32.o ia32_signal.o \
-	 ia32_support.o ia32_traps.o binfmt_elf32.o ia32_ldt.o
-obj-$(CONFIG_AUDIT) += audit.o
-
-# Don't let GCC uses f16-f31 so that save_ia32_fpstate_live() and
-# restore_ia32_fpstate_live() can be sure the live register contain user-level state.
-CFLAGS_ia32_signal.o += -mfixed-range=f16-f31
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/ia32/sys_ia32.c linux-libre-2.6.34-gnu1/arch/ia64/ia32/sys_ia32.c
--- linux-libre-2.6.33-gnu1/arch/ia64/ia32/sys_ia32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/ia32/sys_ia32.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2765 +0,0 @@
-/*
- * sys_ia32.c: Conversion between 32bit and 64bit native syscalls. Derived from sys_sparc32.c.
- *
- * Copyright (C) 2000		VA Linux Co
- * Copyright (C) 2000		Don Dugger <n0ano@valinux.com>
- * Copyright (C) 1999		Arun Sharma <arun.sharma@intel.com>
- * Copyright (C) 1997,1998	Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 1997		David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 2000-2003, 2005 Hewlett-Packard Co
- *	David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 2004		Gordon Jin <gordon.jin@intel.com>
- *
- * These routines maintain argument size conversion between 32bit and 64bit
- * environment.
- */
-
-#include <linux/kernel.h>
-#include <linux/syscalls.h>
-#include <linux/sysctl.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/signal.h>
-#include <linux/resource.h>
-#include <linux/times.h>
-#include <linux/utsname.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/sem.h>
-#include <linux/msg.h>
-#include <linux/mm.h>
-#include <linux/shm.h>
-#include <linux/slab.h>
-#include <linux/uio.h>
-#include <linux/socket.h>
-#include <linux/quota.h>
-#include <linux/poll.h>
-#include <linux/eventpoll.h>
-#include <linux/personality.h>
-#include <linux/ptrace.h>
-#include <linux/regset.h>
-#include <linux/stat.h>
-#include <linux/ipc.h>
-#include <linux/capability.h>
-#include <linux/compat.h>
-#include <linux/vfs.h>
-#include <linux/mman.h>
-#include <linux/mutex.h>
-
-#include <asm/intrinsics.h>
-#include <asm/types.h>
-#include <asm/uaccess.h>
-#include <asm/unistd.h>
-
-#include "ia32priv.h"
-
-#include <net/scm.h>
-#include <net/sock.h>
-
-#define DEBUG	0
-
-#if DEBUG
-# define DBG(fmt...)	printk(KERN_DEBUG fmt)
-#else
-# define DBG(fmt...)
-#endif
-
-#define ROUND_UP(x,a)	((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
-
-#define OFFSET4K(a)		((a) & 0xfff)
-#define PAGE_START(addr)	((addr) & PAGE_MASK)
-#define MINSIGSTKSZ_IA32	2048
-
-#define high2lowuid(uid) ((uid) > 65535 ? 65534 : (uid))
-#define high2lowgid(gid) ((gid) > 65535 ? 65534 : (gid))
-
-/*
- * Anything that modifies or inspects ia32 user virtual memory must hold this semaphore
- * while doing so.
- */
-/* XXX make per-mm: */
-static DEFINE_MUTEX(ia32_mmap_mutex);
-
-asmlinkage long
-sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp,
-	      struct pt_regs *regs)
-{
-	long error;
-	char *filename;
-	unsigned long old_map_base, old_task_size, tssd;
-
-	filename = getname(name);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		return error;
-
-	old_map_base  = current->thread.map_base;
-	old_task_size = current->thread.task_size;
-	tssd = ia64_get_kr(IA64_KR_TSSD);
-
-	/* we may be exec'ing a 64-bit process: reset map base, task-size, and io-base: */
-	current->thread.map_base  = DEFAULT_MAP_BASE;
-	current->thread.task_size = DEFAULT_TASK_SIZE;
-	ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob);
-	ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1);
-
-	error = compat_do_execve(filename, argv, envp, regs);
-	putname(filename);
-
-	if (error < 0) {
-		/* oops, execve failed, switch back to old values... */
-		ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE);
-		ia64_set_kr(IA64_KR_TSSD, tssd);
-		current->thread.map_base  = old_map_base;
-		current->thread.task_size = old_task_size;
-	}
-
-	return error;
-}
-
-
-#if PAGE_SHIFT > IA32_PAGE_SHIFT
-
-
-static int
-get_page_prot (struct vm_area_struct *vma, unsigned long addr)
-{
-	int prot = 0;
-
-	if (!vma || vma->vm_start > addr)
-		return 0;
-
-	if (vma->vm_flags & VM_READ)
-		prot |= PROT_READ;
-	if (vma->vm_flags & VM_WRITE)
-		prot |= PROT_WRITE;
-	if (vma->vm_flags & VM_EXEC)
-		prot |= PROT_EXEC;
-	return prot;
-}
-
-/*
- * Map a subpage by creating an anonymous page that contains the union of the old page and
- * the subpage.
- */
-static unsigned long
-mmap_subpage (struct file *file, unsigned long start, unsigned long end, int prot, int flags,
-	      loff_t off)
-{
-	void *page = NULL;
-	struct inode *inode;
-	unsigned long ret = 0;
-	struct vm_area_struct *vma = find_vma(current->mm, start);
-	int old_prot = get_page_prot(vma, start);
-
-	DBG("mmap_subpage(file=%p,start=0x%lx,end=0x%lx,prot=%x,flags=%x,off=0x%llx)\n",
-	    file, start, end, prot, flags, off);
-
-
-	/* Optimize the case where the old mmap and the new mmap are both anonymous */
-	if ((old_prot & PROT_WRITE) && (flags & MAP_ANONYMOUS) && !vma->vm_file) {
-		if (clear_user((void __user *) start, end - start)) {
-			ret = -EFAULT;
-			goto out;
-		}
-		goto skip_mmap;
-	}
-
-	page = (void *) get_zeroed_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
-	if (old_prot)
-		copy_from_user(page, (void __user *) PAGE_START(start), PAGE_SIZE);
-
-	down_write(&current->mm->mmap_sem);
-	{
-		ret = do_mmap(NULL, PAGE_START(start), PAGE_SIZE, prot | PROT_WRITE,
-			      flags | MAP_FIXED | MAP_ANONYMOUS, 0);
-	}
-	up_write(&current->mm->mmap_sem);
-
-	if (IS_ERR((void *) ret))
-		goto out;
-
-	if (old_prot) {
-		/* copy back the old page contents.  */
-		if (offset_in_page(start))
-			copy_to_user((void __user *) PAGE_START(start), page,
-				     offset_in_page(start));
-		if (offset_in_page(end))
-			copy_to_user((void __user *) end, page + offset_in_page(end),
-				     PAGE_SIZE - offset_in_page(end));
-	}
-
-	if (!(flags & MAP_ANONYMOUS)) {
-		/* read the file contents */
-		inode = file->f_path.dentry->d_inode;
-		if (!inode->i_fop || !file->f_op->read
-		    || ((*file->f_op->read)(file, (char __user *) start, end - start, &off) < 0))
-		{
-			ret = -EINVAL;
-			goto out;
-		}
-	}
-
- skip_mmap:
-	if (!(prot & PROT_WRITE))
-		ret = sys_mprotect(PAGE_START(start), PAGE_SIZE, prot | old_prot);
-  out:
-	if (page)
-		free_page((unsigned long) page);
-	return ret;
-}
-
-/* SLAB cache for ia64_partial_page structures */
-struct kmem_cache *ia64_partial_page_cachep;
-
-/*
- * init ia64_partial_page_list.
- * return 0 means kmalloc fail.
- */
-struct ia64_partial_page_list*
-ia32_init_pp_list(void)
-{
-	struct ia64_partial_page_list *p;
-
-	if ((p = kmalloc(sizeof(*p), GFP_KERNEL)) == NULL)
-		return p;
-	p->pp_head = NULL;
-	p->ppl_rb = RB_ROOT;
-	p->pp_hint = NULL;
-	atomic_set(&p->pp_count, 1);
-	return p;
-}
-
-/*
- * Search for the partial page with @start in partial page list @ppl.
- * If finds the partial page, return the found partial page.
- * Else, return 0 and provide @pprev, @rb_link, @rb_parent to
- * be used by later __ia32_insert_pp().
- */
-static struct ia64_partial_page *
-__ia32_find_pp(struct ia64_partial_page_list *ppl, unsigned int start,
-	struct ia64_partial_page **pprev, struct rb_node ***rb_link,
-	struct rb_node **rb_parent)
-{
-	struct ia64_partial_page *pp;
-	struct rb_node **__rb_link, *__rb_parent, *rb_prev;
-
-	pp = ppl->pp_hint;
-	if (pp && pp->base == start)
-		return pp;
-
-	__rb_link = &ppl->ppl_rb.rb_node;
-	rb_prev = __rb_parent = NULL;
-
-	while (*__rb_link) {
-		__rb_parent = *__rb_link;
-		pp = rb_entry(__rb_parent, struct ia64_partial_page, pp_rb);
-
-		if (pp->base == start) {
-			ppl->pp_hint = pp;
-			return pp;
-		} else if (pp->base < start) {
-			rb_prev = __rb_parent;
-			__rb_link = &__rb_parent->rb_right;
-		} else {
-			__rb_link = &__rb_parent->rb_left;
-		}
-	}
-
-	*rb_link = __rb_link;
-	*rb_parent = __rb_parent;
-	*pprev = NULL;
-	if (rb_prev)
-		*pprev = rb_entry(rb_prev, struct ia64_partial_page, pp_rb);
-	return NULL;
-}
-
-/*
- * insert @pp into @ppl.
- */
-static void
-__ia32_insert_pp(struct ia64_partial_page_list *ppl,
-	struct ia64_partial_page *pp, struct ia64_partial_page *prev,
-	struct rb_node **rb_link, struct rb_node *rb_parent)
-{
-	/* link list */
-	if (prev) {
-		pp->next = prev->next;
-		prev->next = pp;
-	} else {
-		ppl->pp_head = pp;
-		if (rb_parent)
-			pp->next = rb_entry(rb_parent,
-				struct ia64_partial_page, pp_rb);
-		else
-			pp->next = NULL;
-	}
-
-	/* link rb */
-	rb_link_node(&pp->pp_rb, rb_parent, rb_link);
-	rb_insert_color(&pp->pp_rb, &ppl->ppl_rb);
-
-	ppl->pp_hint = pp;
-}
-
-/*
- * delete @pp from partial page list @ppl.
- */
-static void
-__ia32_delete_pp(struct ia64_partial_page_list *ppl,
-	struct ia64_partial_page *pp, struct ia64_partial_page *prev)
-{
-	if (prev) {
-		prev->next = pp->next;
-		if (ppl->pp_hint == pp)
-			ppl->pp_hint = prev;
-	} else {
-		ppl->pp_head = pp->next;
-		if (ppl->pp_hint == pp)
-			ppl->pp_hint = pp->next;
-	}
-	rb_erase(&pp->pp_rb, &ppl->ppl_rb);
-	kmem_cache_free(ia64_partial_page_cachep, pp);
-}
-
-static struct ia64_partial_page *
-__pp_prev(struct ia64_partial_page *pp)
-{
-	struct rb_node *prev = rb_prev(&pp->pp_rb);
-	if (prev)
-		return rb_entry(prev, struct ia64_partial_page, pp_rb);
-	else
-		return NULL;
-}
-
-/*
- * Delete partial pages with address between @start and @end.
- * @start and @end are page aligned.
- */
-static void
-__ia32_delete_pp_range(unsigned int start, unsigned int end)
-{
-	struct ia64_partial_page *pp, *prev;
-	struct rb_node **rb_link, *rb_parent;
-
-	if (start >= end)
-		return;
-
-	pp = __ia32_find_pp(current->thread.ppl, start, &prev,
-					&rb_link, &rb_parent);
-	if (pp)
-		prev = __pp_prev(pp);
-	else {
-		if (prev)
-			pp = prev->next;
-		else
-			pp = current->thread.ppl->pp_head;
-	}
-
-	while (pp && pp->base < end) {
-		struct ia64_partial_page *tmp = pp->next;
-		__ia32_delete_pp(current->thread.ppl, pp, prev);
-		pp = tmp;
-	}
-}
-
-/*
- * Set the range between @start and @end in bitmap.
- * @start and @end should be IA32 page aligned and in the same IA64 page.
- */
-static int
-__ia32_set_pp(unsigned int start, unsigned int end, int flags)
-{
-	struct ia64_partial_page *pp, *prev;
-	struct rb_node ** rb_link, *rb_parent;
-	unsigned int pstart, start_bit, end_bit, i;
-
-	pstart = PAGE_START(start);
-	start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE;
-	end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE;
-	if (end_bit == 0)
-		end_bit = PAGE_SIZE / IA32_PAGE_SIZE;
-	pp = __ia32_find_pp(current->thread.ppl, pstart, &prev,
-					&rb_link, &rb_parent);
-	if (pp) {
-		for (i = start_bit; i < end_bit; i++)
-			set_bit(i, &pp->bitmap);
-		/*
-		 * Check: if this partial page has been set to a full page,
-		 * then delete it.
-		 */
-		if (find_first_zero_bit(&pp->bitmap, sizeof(pp->bitmap)*8) >=
-				PAGE_SIZE/IA32_PAGE_SIZE) {
-			__ia32_delete_pp(current->thread.ppl, pp, __pp_prev(pp));
-		}
-		return 0;
-	}
-
-	/*
-	 * MAP_FIXED may lead to overlapping mmap.
-	 * In this case, the requested mmap area may already mmaped as a full
-	 * page. So check vma before adding a new partial page.
-	 */
-	if (flags & MAP_FIXED) {
-		struct vm_area_struct *vma = find_vma(current->mm, pstart);
-		if (vma && vma->vm_start <= pstart)
-			return 0;
-	}
-
-	/* new a ia64_partial_page */
-	pp = kmem_cache_alloc(ia64_partial_page_cachep, GFP_KERNEL);
-	if (!pp)
-		return -ENOMEM;
-	pp->base = pstart;
-	pp->bitmap = 0;
-	for (i=start_bit; i<end_bit; i++)
-		set_bit(i, &(pp->bitmap));
-	pp->next = NULL;
-	__ia32_insert_pp(current->thread.ppl, pp, prev, rb_link, rb_parent);
-	return 0;
-}
-
-/*
- * @start and @end should be IA32 page aligned, but don't need to be in the
- * same IA64 page. Split @start and @end to make sure they're in the same IA64
- * page, then call __ia32_set_pp().
- */
-static void
-ia32_set_pp(unsigned int start, unsigned int end, int flags)
-{
-	down_write(&current->mm->mmap_sem);
-	if (flags & MAP_FIXED) {
-		/*
-		 * MAP_FIXED may lead to overlapping mmap. When this happens,
-		 * a series of complete IA64 pages results in deletion of
-		 * old partial pages in that range.
-		 */
-		__ia32_delete_pp_range(PAGE_ALIGN(start), PAGE_START(end));
-	}
-
-	if (end < PAGE_ALIGN(start)) {
-		__ia32_set_pp(start, end, flags);
-	} else {
-		if (offset_in_page(start))
-			__ia32_set_pp(start, PAGE_ALIGN(start), flags);
-		if (offset_in_page(end))
-			__ia32_set_pp(PAGE_START(end), end, flags);
-	}
-	up_write(&current->mm->mmap_sem);
-}
-
-/*
- * Unset the range between @start and @end in bitmap.
- * @start and @end should be IA32 page aligned and in the same IA64 page.
- * After doing that, if the bitmap is 0, then free the page and return 1,
- * 	else return 0;
- * If not find the partial page in the list, then
- * 	If the vma exists, then the full page is set to a partial page;
- *	Else return -ENOMEM.
- */
-static int
-__ia32_unset_pp(unsigned int start, unsigned int end)
-{
-	struct ia64_partial_page *pp, *prev;
-	struct rb_node ** rb_link, *rb_parent;
-	unsigned int pstart, start_bit, end_bit, i;
-	struct vm_area_struct *vma;
-
-	pstart = PAGE_START(start);
-	start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE;
-	end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE;
-	if (end_bit == 0)
-		end_bit = PAGE_SIZE / IA32_PAGE_SIZE;
-
-	pp = __ia32_find_pp(current->thread.ppl, pstart, &prev,
-					&rb_link, &rb_parent);
-	if (pp) {
-		for (i = start_bit; i < end_bit; i++)
-			clear_bit(i, &pp->bitmap);
-		if (pp->bitmap == 0) {
-			__ia32_delete_pp(current->thread.ppl, pp, __pp_prev(pp));
-			return 1;
-		}
-		return 0;
-	}
-
-	vma = find_vma(current->mm, pstart);
-	if (!vma || vma->vm_start > pstart) {
-		return -ENOMEM;
-	}
-
-	/* new a ia64_partial_page */
-	pp = kmem_cache_alloc(ia64_partial_page_cachep, GFP_KERNEL);
-	if (!pp)
-		return -ENOMEM;
-	pp->base = pstart;
-	pp->bitmap = 0;
-	for (i = 0; i < start_bit; i++)
-		set_bit(i, &(pp->bitmap));
-	for (i = end_bit; i < PAGE_SIZE / IA32_PAGE_SIZE; i++)
-		set_bit(i, &(pp->bitmap));
-	pp->next = NULL;
-	__ia32_insert_pp(current->thread.ppl, pp, prev, rb_link, rb_parent);
-	return 0;
-}
-
-/*
- * Delete pp between PAGE_ALIGN(start) and PAGE_START(end) by calling
- * __ia32_delete_pp_range(). Unset possible partial pages by calling
- * __ia32_unset_pp().
- * The returned value see __ia32_unset_pp().
- */
-static int
-ia32_unset_pp(unsigned int *startp, unsigned int *endp)
-{
-	unsigned int start = *startp, end = *endp;
-	int ret = 0;
-
-	down_write(&current->mm->mmap_sem);
-
-	__ia32_delete_pp_range(PAGE_ALIGN(start), PAGE_START(end));
-
-	if (end < PAGE_ALIGN(start)) {
-		ret = __ia32_unset_pp(start, end);
-		if (ret == 1) {
-			*startp = PAGE_START(start);
-			*endp = PAGE_ALIGN(end);
-		}
-		if (ret == 0) {
-			/* to shortcut sys_munmap() in sys32_munmap() */
-			*startp = PAGE_START(start);
-			*endp = PAGE_START(end);
-		}
-	} else {
-		if (offset_in_page(start)) {
-			ret = __ia32_unset_pp(start, PAGE_ALIGN(start));
-			if (ret == 1)
-				*startp = PAGE_START(start);
-			if (ret == 0)
-				*startp = PAGE_ALIGN(start);
-			if (ret < 0)
-				goto out;
-		}
-		if (offset_in_page(end)) {
-			ret = __ia32_unset_pp(PAGE_START(end), end);
-			if (ret == 1)
-				*endp = PAGE_ALIGN(end);
-			if (ret == 0)
-				*endp = PAGE_START(end);
-		}
-	}
-
- out:
-	up_write(&current->mm->mmap_sem);
-	return ret;
-}
-
-/*
- * Compare the range between @start and @end with bitmap in partial page.
- * @start and @end should be IA32 page aligned and in the same IA64 page.
- */
-static int
-__ia32_compare_pp(unsigned int start, unsigned int end)
-{
-	struct ia64_partial_page *pp, *prev;
-	struct rb_node ** rb_link, *rb_parent;
-	unsigned int pstart, start_bit, end_bit, size;
-	unsigned int first_bit, next_zero_bit;	/* the first range in bitmap */
-
-	pstart = PAGE_START(start);
-
-	pp = __ia32_find_pp(current->thread.ppl, pstart, &prev,
-					&rb_link, &rb_parent);
-	if (!pp)
-		return 1;
-
-	start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE;
-	end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE;
-	size = sizeof(pp->bitmap) * 8;
-	first_bit = find_first_bit(&pp->bitmap, size);
-	next_zero_bit = find_next_zero_bit(&pp->bitmap, size, first_bit);
-	if ((start_bit < first_bit) || (end_bit > next_zero_bit)) {
-		/* exceeds the first range in bitmap */
-		return -ENOMEM;
-	} else if ((start_bit == first_bit) && (end_bit == next_zero_bit)) {
-		first_bit = find_next_bit(&pp->bitmap, size, next_zero_bit);
-		if ((next_zero_bit < first_bit) && (first_bit < size))
-			return 1;	/* has next range */
-		else
-			return 0; 	/* no next range */
-	} else
-		return 1;
-}
-
-/*
- * @start and @end should be IA32 page aligned, but don't need to be in the
- * same IA64 page. Split @start and @end to make sure they're in the same IA64
- * page, then call __ia32_compare_pp().
- *
- * Take this as example: the range is the 1st and 2nd 4K page.
- * Return 0 if they fit bitmap exactly, i.e. bitmap = 00000011;
- * Return 1 if the range doesn't cover whole bitmap, e.g. bitmap = 00001111;
- * Return -ENOMEM if the range exceeds the bitmap, e.g. bitmap = 00000001 or
- * 	bitmap = 00000101.
- */
-static int
-ia32_compare_pp(unsigned int *startp, unsigned int *endp)
-{
-	unsigned int start = *startp, end = *endp;
-	int retval = 0;
-
-	down_write(&current->mm->mmap_sem);
-
-	if (end < PAGE_ALIGN(start)) {
-		retval = __ia32_compare_pp(start, end);
-		if (retval == 0) {
-			*startp = PAGE_START(start);
-			*endp = PAGE_ALIGN(end);
-		}
-	} else {
-		if (offset_in_page(start)) {
-			retval = __ia32_compare_pp(start,
-						   PAGE_ALIGN(start));
-			if (retval == 0)
-				*startp = PAGE_START(start);
-			if (retval < 0)
-				goto out;
-		}
-		if (offset_in_page(end)) {
-			retval = __ia32_compare_pp(PAGE_START(end), end);
-			if (retval == 0)
-				*endp = PAGE_ALIGN(end);
-		}
-	}
-
- out:
-	up_write(&current->mm->mmap_sem);
-	return retval;
-}
-
-static void
-__ia32_drop_pp_list(struct ia64_partial_page_list *ppl)
-{
-	struct ia64_partial_page *pp = ppl->pp_head;
-
-	while (pp) {
-		struct ia64_partial_page *next = pp->next;
-		kmem_cache_free(ia64_partial_page_cachep, pp);
-		pp = next;
-	}
-
-	kfree(ppl);
-}
-
-void
-ia32_drop_ia64_partial_page_list(struct task_struct *task)
-{
-	struct ia64_partial_page_list* ppl = task->thread.ppl;
-
-	if (ppl && atomic_dec_and_test(&ppl->pp_count))
-		__ia32_drop_pp_list(ppl);
-}
-
-/*
- * Copy current->thread.ppl to ppl (already initialized).
- */
-static int
-__ia32_copy_pp_list(struct ia64_partial_page_list *ppl)
-{
-	struct ia64_partial_page *pp, *tmp, *prev;
-	struct rb_node **rb_link, *rb_parent;
-
-	ppl->pp_head = NULL;
-	ppl->pp_hint = NULL;
-	ppl->ppl_rb = RB_ROOT;
-	rb_link = &ppl->ppl_rb.rb_node;
-	rb_parent = NULL;
-	prev = NULL;
-
-	for (pp = current->thread.ppl->pp_head; pp; pp = pp->next) {
-		tmp = kmem_cache_alloc(ia64_partial_page_cachep, GFP_KERNEL);
-		if (!tmp)
-			return -ENOMEM;
-		*tmp = *pp;
-		__ia32_insert_pp(ppl, tmp, prev, rb_link, rb_parent);
-		prev = tmp;
-		rb_link = &tmp->pp_rb.rb_right;
-		rb_parent = &tmp->pp_rb;
-	}
-	return 0;
-}
-
-int
-ia32_copy_ia64_partial_page_list(struct task_struct *p,
-				unsigned long clone_flags)
-{
-	int retval = 0;
-
-	if (clone_flags & CLONE_VM) {
-		atomic_inc(&current->thread.ppl->pp_count);
-		p->thread.ppl = current->thread.ppl;
-	} else {
-		p->thread.ppl = ia32_init_pp_list();
-		if (!p->thread.ppl)
-			return -ENOMEM;
-		down_write(&current->mm->mmap_sem);
-		{
-			retval = __ia32_copy_pp_list(p->thread.ppl);
-		}
-		up_write(&current->mm->mmap_sem);
-	}
-
-	return retval;
-}
-
-static unsigned long
-emulate_mmap (struct file *file, unsigned long start, unsigned long len, int prot, int flags,
-	      loff_t off)
-{
-	unsigned long tmp, end, pend, pstart, ret, is_congruent, fudge = 0;
-	struct inode *inode;
-	loff_t poff;
-
-	end = start + len;
-	pstart = PAGE_START(start);
-	pend = PAGE_ALIGN(end);
-
-	if (flags & MAP_FIXED) {
-		ia32_set_pp((unsigned int)start, (unsigned int)end, flags);
-		if (start > pstart) {
-			if (flags & MAP_SHARED)
-				printk(KERN_INFO
-				       "%s(%d): emulate_mmap() can't share head (addr=0x%lx)\n",
-				       current->comm, task_pid_nr(current), start);
-			ret = mmap_subpage(file, start, min(PAGE_ALIGN(start), end), prot, flags,
-					   off);
-			if (IS_ERR((void *) ret))
-				return ret;
-			pstart += PAGE_SIZE;
-			if (pstart >= pend)
-				goto out;	/* done */
-		}
-		if (end < pend) {
-			if (flags & MAP_SHARED)
-				printk(KERN_INFO
-				       "%s(%d): emulate_mmap() can't share tail (end=0x%lx)\n",
-				       current->comm, task_pid_nr(current), end);
-			ret = mmap_subpage(file, max(start, PAGE_START(end)), end, prot, flags,
-					   (off + len) - offset_in_page(end));
-			if (IS_ERR((void *) ret))
-				return ret;
-			pend -= PAGE_SIZE;
-			if (pstart >= pend)
-				goto out;	/* done */
-		}
-	} else {
-		/*
-		 * If a start address was specified, use it if the entire rounded out area
-		 * is available.
-		 */
-		if (start && !pstart)
-			fudge = 1;	/* handle case of mapping to range (0,PAGE_SIZE) */
-		tmp = arch_get_unmapped_area(file, pstart - fudge, pend - pstart, 0, flags);
-		if (tmp != pstart) {
-			pstart = tmp;
-			start = pstart + offset_in_page(off);	/* make start congruent with off */
-			end = start + len;
-			pend = PAGE_ALIGN(end);
-		}
-	}
-
-	poff = off + (pstart - start);	/* note: (pstart - start) may be negative */
-	is_congruent = (flags & MAP_ANONYMOUS) || (offset_in_page(poff) == 0);
-
-	if ((flags & MAP_SHARED) && !is_congruent)
-		printk(KERN_INFO "%s(%d): emulate_mmap() can't share contents of incongruent mmap "
-		       "(addr=0x%lx,off=0x%llx)\n", current->comm, task_pid_nr(current), start, off);
-
-	DBG("mmap_body: mapping [0x%lx-0x%lx) %s with poff 0x%llx\n", pstart, pend,
-	    is_congruent ? "congruent" : "not congruent", poff);
-
-	down_write(&current->mm->mmap_sem);
-	{
-		if (!(flags & MAP_ANONYMOUS) && is_congruent)
-			ret = do_mmap(file, pstart, pend - pstart, prot, flags | MAP_FIXED, poff);
-		else
-			ret = do_mmap(NULL, pstart, pend - pstart,
-				      prot | ((flags & MAP_ANONYMOUS) ? 0 : PROT_WRITE),
-				      flags | MAP_FIXED | MAP_ANONYMOUS, 0);
-	}
-	up_write(&current->mm->mmap_sem);
-
-	if (IS_ERR((void *) ret))
-		return ret;
-
-	if (!is_congruent) {
-		/* read the file contents */
-		inode = file->f_path.dentry->d_inode;
-		if (!inode->i_fop || !file->f_op->read
-		    || ((*file->f_op->read)(file, (char __user *) pstart, pend - pstart, &poff)
-			< 0))
-		{
-			sys_munmap(pstart, pend - pstart);
-			return -EINVAL;
-		}
-		if (!(prot & PROT_WRITE) && sys_mprotect(pstart, pend - pstart, prot) < 0)
-			return -EINVAL;
-	}
-
-	if (!(flags & MAP_FIXED))
-		ia32_set_pp((unsigned int)start, (unsigned int)end, flags);
-out:
-	return start;
-}
-
-#endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */
-
-static inline unsigned int
-get_prot32 (unsigned int prot)
-{
-	if (prot & PROT_WRITE)
-		/* on x86, PROT_WRITE implies PROT_READ which implies PROT_EEC */
-		prot |= PROT_READ | PROT_WRITE | PROT_EXEC;
-	else if (prot & (PROT_READ | PROT_EXEC))
-		/* on x86, there is no distinction between PROT_READ and PROT_EXEC */
-		prot |= (PROT_READ | PROT_EXEC);
-
-	return prot;
-}
-
-unsigned long
-ia32_do_mmap (struct file *file, unsigned long addr, unsigned long len, int prot, int flags,
-	      loff_t offset)
-{
-	DBG("ia32_do_mmap(file=%p,addr=0x%lx,len=0x%lx,prot=%x,flags=%x,offset=0x%llx)\n",
-	    file, addr, len, prot, flags, offset);
-
-	if (file && (!file->f_op || !file->f_op->mmap))
-		return -ENODEV;
-
-	len = IA32_PAGE_ALIGN(len);
-	if (len == 0)
-		return addr;
-
-	if (len > IA32_PAGE_OFFSET || addr > IA32_PAGE_OFFSET - len)
-	{
-		if (flags & MAP_FIXED)
-			return -ENOMEM;
-		else
-		return -EINVAL;
-	}
-
-	if (OFFSET4K(offset))
-		return -EINVAL;
-
-	prot = get_prot32(prot);
-
-	if (flags & MAP_HUGETLB)
-		return -ENOMEM;
-
-#if PAGE_SHIFT > IA32_PAGE_SHIFT
-	mutex_lock(&ia32_mmap_mutex);
-	{
-		addr = emulate_mmap(file, addr, len, prot, flags, offset);
-	}
-	mutex_unlock(&ia32_mmap_mutex);
-#else
-	down_write(&current->mm->mmap_sem);
-	{
-		addr = do_mmap(file, addr, len, prot, flags, offset);
-	}
-	up_write(&current->mm->mmap_sem);
-#endif
-	DBG("ia32_do_mmap: returning 0x%lx\n", addr);
-	return addr;
-}
-
-/*
- * Linux/i386 didn't use to be able to handle more than 4 system call parameters, so these
- * system calls used a memory block for parameter passing..
- */
-
-struct mmap_arg_struct {
-	unsigned int addr;
-	unsigned int len;
-	unsigned int prot;
-	unsigned int flags;
-	unsigned int fd;
-	unsigned int offset;
-};
-
-asmlinkage long
-sys32_mmap (struct mmap_arg_struct __user *arg)
-{
-	struct mmap_arg_struct a;
-	struct file *file = NULL;
-	unsigned long addr;
-	int flags;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-
-	if (OFFSET4K(a.offset))
-		return -EINVAL;
-
-	flags = a.flags;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(a.fd);
-		if (!file)
-			return -EBADF;
-	}
-
-	addr = ia32_do_mmap(file, a.addr, a.len, a.prot, flags, a.offset);
-
-	if (file)
-		fput(file);
-	return addr;
-}
-
-asmlinkage long
-sys32_mmap2 (unsigned int addr, unsigned int len, unsigned int prot, unsigned int flags,
-	     unsigned int fd, unsigned int pgoff)
-{
-	struct file *file = NULL;
-	unsigned long retval;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			return -EBADF;
-	}
-
-	retval = ia32_do_mmap(file, addr, len, prot, flags,
-			      (unsigned long) pgoff << IA32_PAGE_SHIFT);
-
-	if (file)
-		fput(file);
-	return retval;
-}
-
-asmlinkage long
-sys32_munmap (unsigned int start, unsigned int len)
-{
-	unsigned int end = start + len;
-	long ret;
-
-#if PAGE_SHIFT <= IA32_PAGE_SHIFT
-	ret = sys_munmap(start, end - start);
-#else
-	if (OFFSET4K(start))
-		return -EINVAL;
-
-	end = IA32_PAGE_ALIGN(end);
-	if (start >= end)
-		return -EINVAL;
-
-	ret = ia32_unset_pp(&start, &end);
-	if (ret < 0)
-		return ret;
-
-	if (start >= end)
-		return 0;
-
-	mutex_lock(&ia32_mmap_mutex);
-	ret = sys_munmap(start, end - start);
-	mutex_unlock(&ia32_mmap_mutex);
-#endif
-	return ret;
-}
-
-#if PAGE_SHIFT > IA32_PAGE_SHIFT
-
-/*
- * When mprotect()ing a partial page, we set the permission to the union of the old
- * settings and the new settings.  In other words, it's only possible to make access to a
- * partial page less restrictive.
- */
-static long
-mprotect_subpage (unsigned long address, int new_prot)
-{
-	int old_prot;
-	struct vm_area_struct *vma;
-
-	if (new_prot == PROT_NONE)
-		return 0;		/* optimize case where nothing changes... */
-	vma = find_vma(current->mm, address);
-	old_prot = get_page_prot(vma, address);
-	return sys_mprotect(address, PAGE_SIZE, new_prot | old_prot);
-}
-
-#endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */
-
-asmlinkage long
-sys32_mprotect (unsigned int start, unsigned int len, int prot)
-{
-	unsigned int end = start + len;
-#if PAGE_SHIFT > IA32_PAGE_SHIFT
-	long retval = 0;
-#endif
-
-	prot = get_prot32(prot);
-
-#if PAGE_SHIFT <= IA32_PAGE_SHIFT
-	return sys_mprotect(start, end - start, prot);
-#else
-	if (OFFSET4K(start))
-		return -EINVAL;
-
-	end = IA32_PAGE_ALIGN(end);
-	if (end < start)
-		return -EINVAL;
-
-	retval = ia32_compare_pp(&start, &end);
-
-	if (retval < 0)
-		return retval;
-
-	mutex_lock(&ia32_mmap_mutex);
-	{
-		if (offset_in_page(start)) {
-			/* start address is 4KB aligned but not page aligned. */
-			retval = mprotect_subpage(PAGE_START(start), prot);
-			if (retval < 0)
-				goto out;
-
-			start = PAGE_ALIGN(start);
-			if (start >= end)
-				goto out;	/* retval is already zero... */
-		}
-
-		if (offset_in_page(end)) {
-			/* end address is 4KB aligned but not page aligned. */
-			retval = mprotect_subpage(PAGE_START(end), prot);
-			if (retval < 0)
-				goto out;
-
-			end = PAGE_START(end);
-		}
-		retval = sys_mprotect(start, end - start, prot);
-	}
-  out:
-	mutex_unlock(&ia32_mmap_mutex);
-	return retval;
-#endif
-}
-
-asmlinkage long
-sys32_mremap (unsigned int addr, unsigned int old_len, unsigned int new_len,
-		unsigned int flags, unsigned int new_addr)
-{
-	long ret;
-
-#if PAGE_SHIFT <= IA32_PAGE_SHIFT
-	ret = sys_mremap(addr, old_len, new_len, flags, new_addr);
-#else
-	unsigned int old_end, new_end;
-
-	if (OFFSET4K(addr))
-		return -EINVAL;
-
-	old_len = IA32_PAGE_ALIGN(old_len);
-	new_len = IA32_PAGE_ALIGN(new_len);
-	old_end = addr + old_len;
-	new_end = addr + new_len;
-
-	if (!new_len)
-		return -EINVAL;
-
-	if ((flags & MREMAP_FIXED) && (OFFSET4K(new_addr)))
-		return -EINVAL;
-
-	if (old_len >= new_len) {
-		ret = sys32_munmap(addr + new_len, old_len - new_len);
-		if (ret && old_len != new_len)
-			return ret;
-		ret = addr;
-		if (!(flags & MREMAP_FIXED) || (new_addr == addr))
-			return ret;
-		old_len = new_len;
-	}
-
-	addr = PAGE_START(addr);
-	old_len = PAGE_ALIGN(old_end) - addr;
-	new_len = PAGE_ALIGN(new_end) - addr;
-
-	mutex_lock(&ia32_mmap_mutex);
-	ret = sys_mremap(addr, old_len, new_len, flags, new_addr);
-	mutex_unlock(&ia32_mmap_mutex);
-
-	if ((ret >= 0) && (old_len < new_len)) {
-		/* mremap expanded successfully */
-		ia32_set_pp(old_end, new_end, flags);
-	}
-#endif
-	return ret;
-}
-
-asmlinkage unsigned long
-sys32_alarm (unsigned int seconds)
-{
-	return alarm_setitimer(seconds);
-}
-
-struct sel_arg_struct {
-	unsigned int n;
-	unsigned int inp;
-	unsigned int outp;
-	unsigned int exp;
-	unsigned int tvp;
-};
-
-asmlinkage long
-sys32_old_select (struct sel_arg_struct __user *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
-				 compat_ptr(a.exp), compat_ptr(a.tvp));
-}
-
-#define SEMOP		 1
-#define SEMGET		 2
-#define SEMCTL		 3
-#define SEMTIMEDOP	 4
-#define MSGSND		11
-#define MSGRCV		12
-#define MSGGET		13
-#define MSGCTL		14
-#define SHMAT		21
-#define SHMDT		22
-#define SHMGET		23
-#define SHMCTL		24
-
-asmlinkage long
-sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)
-{
-	int version;
-
-	version = call >> 16; /* hack for backward compatibility */
-	call &= 0xffff;
-
-	switch (call) {
-	      case SEMTIMEDOP:
-		if (fifth)
-			return compat_sys_semtimedop(first, compat_ptr(ptr),
-				second, compat_ptr(fifth));
-		/* else fall through for normal semop() */
-	      case SEMOP:
-		/* struct sembuf is the same on 32 and 64bit :)) */
-		return sys_semtimedop(first, compat_ptr(ptr), second,
-				      NULL);
-	      case SEMGET:
-		return sys_semget(first, second, third);
-	      case SEMCTL:
-		return compat_sys_semctl(first, second, third, compat_ptr(ptr));
-
-	      case MSGSND:
-		return compat_sys_msgsnd(first, second, third, compat_ptr(ptr));
-	      case MSGRCV:
-		return compat_sys_msgrcv(first, second, fifth, third, version, compat_ptr(ptr));
-	      case MSGGET:
-		return sys_msgget((key_t) first, second);
-	      case MSGCTL:
-		return compat_sys_msgctl(first, second, compat_ptr(ptr));
-
-	      case SHMAT:
-		return compat_sys_shmat(first, second, third, version, compat_ptr(ptr));
-		break;
-	      case SHMDT:
-		return sys_shmdt(compat_ptr(ptr));
-	      case SHMGET:
-		return sys_shmget(first, (unsigned)second, third);
-	      case SHMCTL:
-		return compat_sys_shmctl(first, second, compat_ptr(ptr));
-
-	      default:
-		return -ENOSYS;
-	}
-	return -EINVAL;
-}
-
-asmlinkage long
-compat_sys_wait4 (compat_pid_t pid, compat_uint_t * stat_addr, int options,
-		 struct compat_rusage *ru);
-
-asmlinkage long
-sys32_waitpid (int pid, unsigned int *stat_addr, int options)
-{
-	return compat_sys_wait4(pid, stat_addr, options, NULL);
-}
-
-/*
- *  The order in which registers are stored in the ptrace regs structure
- */
-#define PT_EBX	0
-#define PT_ECX	1
-#define PT_EDX	2
-#define PT_ESI	3
-#define PT_EDI	4
-#define PT_EBP	5
-#define PT_EAX	6
-#define PT_DS	7
-#define PT_ES	8
-#define PT_FS	9
-#define PT_GS	10
-#define PT_ORIG_EAX 11
-#define PT_EIP	12
-#define PT_CS	13
-#define PT_EFL	14
-#define PT_UESP	15
-#define PT_SS	16
-
-static unsigned int
-getreg (struct task_struct *child, int regno)
-{
-	struct pt_regs *child_regs;
-
-	child_regs = task_pt_regs(child);
-	switch (regno / sizeof(int)) {
-	      case PT_EBX: return child_regs->r11;
-	      case PT_ECX: return child_regs->r9;
-	      case PT_EDX: return child_regs->r10;
-	      case PT_ESI: return child_regs->r14;
-	      case PT_EDI: return child_regs->r15;
-	      case PT_EBP: return child_regs->r13;
-	      case PT_EAX: return child_regs->r8;
-	      case PT_ORIG_EAX: return child_regs->r1; /* see dispatch_to_ia32_handler() */
-	      case PT_EIP: return child_regs->cr_iip;
-	      case PT_UESP: return child_regs->r12;
-	      case PT_EFL: return child->thread.eflag;
-	      case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
-		return __USER_DS;
-	      case PT_CS: return __USER_CS;
-	      default:
-		printk(KERN_ERR "ia32.getreg(): unknown register %d\n", regno);
-		break;
-	}
-	return 0;
-}
-
-static void
-putreg (struct task_struct *child, int regno, unsigned int value)
-{
-	struct pt_regs *child_regs;
-
-	child_regs = task_pt_regs(child);
-	switch (regno / sizeof(int)) {
-	      case PT_EBX: child_regs->r11 = value; break;
-	      case PT_ECX: child_regs->r9 = value; break;
-	      case PT_EDX: child_regs->r10 = value; break;
-	      case PT_ESI: child_regs->r14 = value; break;
-	      case PT_EDI: child_regs->r15 = value; break;
-	      case PT_EBP: child_regs->r13 = value; break;
-	      case PT_EAX: child_regs->r8 = value; break;
-	      case PT_ORIG_EAX: child_regs->r1 = value; break;
-	      case PT_EIP: child_regs->cr_iip = value; break;
-	      case PT_UESP: child_regs->r12 = value; break;
-	      case PT_EFL: child->thread.eflag = value; break;
-	      case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
-		if (value != __USER_DS)
-			printk(KERN_ERR
-			       "ia32.putreg: attempt to set invalid segment register %d = %x\n",
-			       regno, value);
-		break;
-	      case PT_CS:
-		if (value != __USER_CS)
-			printk(KERN_ERR
-			       "ia32.putreg: attempt to set invalid segment register %d = %x\n",
-			       regno, value);
-		break;
-	      default:
-		printk(KERN_ERR "ia32.putreg: unknown register %d\n", regno);
-		break;
-	}
-}
-
-static void
-put_fpreg (int regno, struct _fpreg_ia32 __user *reg, struct pt_regs *ptp,
-	   struct switch_stack *swp, int tos)
-{
-	struct _fpreg_ia32 *f;
-	char buf[32];
-
-	f = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
-	if ((regno += tos) >= 8)
-		regno -= 8;
-	switch (regno) {
-	      case 0:
-		ia64f2ia32f(f, &ptp->f8);
-		break;
-	      case 1:
-		ia64f2ia32f(f, &ptp->f9);
-		break;
-	      case 2:
-		ia64f2ia32f(f, &ptp->f10);
-		break;
-	      case 3:
-		ia64f2ia32f(f, &ptp->f11);
-		break;
-	      case 4:
-	      case 5:
-	      case 6:
-	      case 7:
-		ia64f2ia32f(f, &swp->f12 + (regno - 4));
-		break;
-	}
-	copy_to_user(reg, f, sizeof(*reg));
-}
-
-static void
-get_fpreg (int regno, struct _fpreg_ia32 __user *reg, struct pt_regs *ptp,
-	   struct switch_stack *swp, int tos)
-{
-
-	if ((regno += tos) >= 8)
-		regno -= 8;
-	switch (regno) {
-	      case 0:
-		copy_from_user(&ptp->f8, reg, sizeof(*reg));
-		break;
-	      case 1:
-		copy_from_user(&ptp->f9, reg, sizeof(*reg));
-		break;
-	      case 2:
-		copy_from_user(&ptp->f10, reg, sizeof(*reg));
-		break;
-	      case 3:
-		copy_from_user(&ptp->f11, reg, sizeof(*reg));
-		break;
-	      case 4:
-	      case 5:
-	      case 6:
-	      case 7:
-		copy_from_user(&swp->f12 + (regno - 4), reg, sizeof(*reg));
-		break;
-	}
-	return;
-}
-
-int
-save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __user *save)
-{
-	struct switch_stack *swp;
-	struct pt_regs *ptp;
-	int i, tos;
-
-	if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
-		return -EFAULT;
-
-	__put_user(tsk->thread.fcr & 0xffff, &save->cwd);
-	__put_user(tsk->thread.fsr & 0xffff, &save->swd);
-	__put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd);
-	__put_user(tsk->thread.fir, &save->fip);
-	__put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs);
-	__put_user(tsk->thread.fdr, &save->foo);
-	__put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos);
-
-	/*
-	 *  Stack frames start with 16-bytes of temp space
-	 */
-	swp = (struct switch_stack *)(tsk->thread.ksp + 16);
-	ptp = task_pt_regs(tsk);
-	tos = (tsk->thread.fsr >> 11) & 7;
-	for (i = 0; i < 8; i++)
-		put_fpreg(i, &save->st_space[i], ptp, swp, tos);
-	return 0;
-}
-
-static int
-restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __user *save)
-{
-	struct switch_stack *swp;
-	struct pt_regs *ptp;
-	int i, tos;
-	unsigned int fsrlo, fsrhi, num32;
-
-	if (!access_ok(VERIFY_READ, save, sizeof(*save)))
-		return(-EFAULT);
-
-	__get_user(num32, (unsigned int __user *)&save->cwd);
-	tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
-	__get_user(fsrlo, (unsigned int __user *)&save->swd);
-	__get_user(fsrhi, (unsigned int __user *)&save->twd);
-	num32 = (fsrhi << 16) | fsrlo;
-	tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
-	__get_user(num32, (unsigned int __user *)&save->fip);
-	tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
-	__get_user(num32, (unsigned int __user *)&save->foo);
-	tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;
-
-	/*
-	 *  Stack frames start with 16-bytes of temp space
-	 */
-	swp = (struct switch_stack *)(tsk->thread.ksp + 16);
-	ptp = task_pt_regs(tsk);
-	tos = (tsk->thread.fsr >> 11) & 7;
-	for (i = 0; i < 8; i++)
-		get_fpreg(i, &save->st_space[i], ptp, swp, tos);
-	return 0;
-}
-
-int
-save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __user *save)
-{
-	struct switch_stack *swp;
-	struct pt_regs *ptp;
-	int i, tos;
-	unsigned long mxcsr=0;
-	unsigned long num128[2];
-
-	if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
-		return -EFAULT;
-
-	__put_user(tsk->thread.fcr & 0xffff, &save->cwd);
-	__put_user(tsk->thread.fsr & 0xffff, &save->swd);
-	__put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd);
-	__put_user(tsk->thread.fir, &save->fip);
-	__put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs);
-	__put_user(tsk->thread.fdr, &save->foo);
-	__put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos);
-
-        /*
-         *  Stack frames start with 16-bytes of temp space
-         */
-        swp = (struct switch_stack *)(tsk->thread.ksp + 16);
-        ptp = task_pt_regs(tsk);
-	tos = (tsk->thread.fsr >> 11) & 7;
-        for (i = 0; i < 8; i++)
-		put_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos);
-
-	mxcsr = ((tsk->thread.fcr>>32) & 0xff80) | ((tsk->thread.fsr>>32) & 0x3f);
-	__put_user(mxcsr & 0xffff, &save->mxcsr);
-	for (i = 0; i < 8; i++) {
-		memcpy(&(num128[0]), &(swp->f16) + i*2, sizeof(unsigned long));
-		memcpy(&(num128[1]), &(swp->f17) + i*2, sizeof(unsigned long));
-		copy_to_user(&save->xmm_space[0] + 4*i, num128, sizeof(struct _xmmreg_ia32));
-	}
-	return 0;
-}
-
-static int
-restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __user *save)
-{
-	struct switch_stack *swp;
-	struct pt_regs *ptp;
-	int i, tos;
-	unsigned int fsrlo, fsrhi, num32;
-	int mxcsr;
-	unsigned long num64;
-	unsigned long num128[2];
-
-	if (!access_ok(VERIFY_READ, save, sizeof(*save)))
-		return(-EFAULT);
-
-	__get_user(num32, (unsigned int __user *)&save->cwd);
-	tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
-	__get_user(fsrlo, (unsigned int __user *)&save->swd);
-	__get_user(fsrhi, (unsigned int __user *)&save->twd);
-	num32 = (fsrhi << 16) | fsrlo;
-	tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
-	__get_user(num32, (unsigned int __user *)&save->fip);
-	tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
-	__get_user(num32, (unsigned int __user *)&save->foo);
-	tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;
-
-	/*
-	 *  Stack frames start with 16-bytes of temp space
-	 */
-	swp = (struct switch_stack *)(tsk->thread.ksp + 16);
-	ptp = task_pt_regs(tsk);
-	tos = (tsk->thread.fsr >> 11) & 7;
-	for (i = 0; i < 8; i++)
-	get_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos);
-
-	__get_user(mxcsr, (unsigned int __user *)&save->mxcsr);
-	num64 = mxcsr & 0xff10;
-	tsk->thread.fcr = (tsk->thread.fcr & (~0xff1000000000UL)) | (num64<<32);
-	num64 = mxcsr & 0x3f;
-	tsk->thread.fsr = (tsk->thread.fsr & (~0x3f00000000UL)) | (num64<<32);
-
-	for (i = 0; i < 8; i++) {
-		copy_from_user(num128, &save->xmm_space[0] + 4*i, sizeof(struct _xmmreg_ia32));
-		memcpy(&(swp->f16) + i*2, &(num128[0]), sizeof(unsigned long));
-		memcpy(&(swp->f17) + i*2, &(num128[1]), sizeof(unsigned long));
-	}
-	return 0;
-}
-
-long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
-	compat_ulong_t caddr, compat_ulong_t cdata)
-{
-	unsigned long addr = caddr;
-	unsigned long data = cdata;
-	unsigned int tmp;
-	long i, ret;
-
-	switch (request) {
-	      case PTRACE_PEEKUSR:	/* read word at addr in USER area */
-		ret = -EIO;
-		if ((addr & 3) || addr > 17*sizeof(int))
-			break;
-
-		tmp = getreg(child, addr);
-		if (!put_user(tmp, (unsigned int __user *) compat_ptr(data)))
-			ret = 0;
-		break;
-
-	      case PTRACE_POKEUSR:	/* write word at addr in USER area */
-		ret = -EIO;
-		if ((addr & 3) || addr > 17*sizeof(int))
-			break;
-
-		putreg(child, addr, data);
-		ret = 0;
-		break;
-
-	      case IA32_PTRACE_GETREGS:
-		if (!access_ok(VERIFY_WRITE, compat_ptr(data), 17*sizeof(int))) {
-			ret = -EIO;
-			break;
-		}
-		for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
-			put_user(getreg(child, i), (unsigned int __user *) compat_ptr(data));
-			data += sizeof(int);
-		}
-		ret = 0;
-		break;
-
-	      case IA32_PTRACE_SETREGS:
-		if (!access_ok(VERIFY_READ, compat_ptr(data), 17*sizeof(int))) {
-			ret = -EIO;
-			break;
-		}
-		for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
-			get_user(tmp, (unsigned int __user *) compat_ptr(data));
-			putreg(child, i, tmp);
-			data += sizeof(int);
-		}
-		ret = 0;
-		break;
-
-	      case IA32_PTRACE_GETFPREGS:
-		ret = save_ia32_fpstate(child, (struct ia32_user_i387_struct __user *)
-					compat_ptr(data));
-		break;
-
-	      case IA32_PTRACE_GETFPXREGS:
-		ret = save_ia32_fpxstate(child, (struct ia32_user_fxsr_struct __user *)
-					 compat_ptr(data));
-		break;
-
-	      case IA32_PTRACE_SETFPREGS:
-		ret = restore_ia32_fpstate(child, (struct ia32_user_i387_struct __user *)
-					   compat_ptr(data));
-		break;
-
-	      case IA32_PTRACE_SETFPXREGS:
-		ret = restore_ia32_fpxstate(child, (struct ia32_user_fxsr_struct __user *)
-					    compat_ptr(data));
-		break;
-
-	      default:
-		return compat_ptrace_request(child, request, caddr, cdata);
-	}
-	return ret;
-}
-
-typedef struct {
-	unsigned int	ss_sp;
-	unsigned int	ss_flags;
-	unsigned int	ss_size;
-} ia32_stack_t;
-
-asmlinkage long
-sys32_sigaltstack (ia32_stack_t __user *uss32, ia32_stack_t __user *uoss32,
-		   long arg2, long arg3, long arg4, long arg5, long arg6,
-		   long arg7, struct pt_regs pt)
-{
-	stack_t uss, uoss;
-	ia32_stack_t buf32;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-
-	if (uss32) {
-		if (copy_from_user(&buf32, uss32, sizeof(ia32_stack_t)))
-			return -EFAULT;
-		uss.ss_sp = (void __user *) (long) buf32.ss_sp;
-		uss.ss_flags = buf32.ss_flags;
-		/* MINSIGSTKSZ is different for ia32 vs ia64. We lie here to pass the
-	           check and set it to the user requested value later */
-		if ((buf32.ss_flags != SS_DISABLE) && (buf32.ss_size < MINSIGSTKSZ_IA32)) {
-			ret = -ENOMEM;
-			goto out;
-		}
-		uss.ss_size = MINSIGSTKSZ;
-	}
-	set_fs(KERNEL_DS);
-	ret = do_sigaltstack(uss32 ? (stack_t __user *) &uss : NULL,
-			     (stack_t __user *) &uoss, pt.r12);
- 	current->sas_ss_size = buf32.ss_size;
-	set_fs(old_fs);
-out:
-	if (ret < 0)
-		return(ret);
-	if (uoss32) {
-		buf32.ss_sp = (long __user) uoss.ss_sp;
-		buf32.ss_flags = uoss.ss_flags;
-		buf32.ss_size = uoss.ss_size;
-		if (copy_to_user(uoss32, &buf32, sizeof(ia32_stack_t)))
-			return -EFAULT;
-	}
-	return ret;
-}
-
-asmlinkage int
-sys32_msync (unsigned int start, unsigned int len, int flags)
-{
-	unsigned int addr;
-
-	if (OFFSET4K(start))
-		return -EINVAL;
-	addr = PAGE_START(start);
-	return sys_msync(addr, len + (start - addr), flags);
-}
-
-asmlinkage long
-sys32_newuname (struct new_utsname __user *name)
-{
-	int ret = sys_newuname(name);
-
-	if (!ret)
-		if (copy_to_user(name->machine, "i686\0\0\0", 8))
-			ret = -EFAULT;
-	return ret;
-}
-
-asmlinkage long
-sys32_getresuid16 (u16 __user *ruid, u16 __user *euid, u16 __user *suid)
-{
-	uid_t a, b, c;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-
-	set_fs(KERNEL_DS);
-	ret = sys_getresuid((uid_t __user *) &a, (uid_t __user *) &b, (uid_t __user *) &c);
-	set_fs(old_fs);
-
-	if (put_user(a, ruid) || put_user(b, euid) || put_user(c, suid))
-		return -EFAULT;
-	return ret;
-}
-
-asmlinkage long
-sys32_getresgid16 (u16 __user *rgid, u16 __user *egid, u16 __user *sgid)
-{
-	gid_t a, b, c;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-
-	set_fs(KERNEL_DS);
-	ret = sys_getresgid((gid_t __user *) &a, (gid_t __user *) &b, (gid_t __user *) &c);
-	set_fs(old_fs);
-
-	if (ret)
-		return ret;
-
-	return put_user(a, rgid) | put_user(b, egid) | put_user(c, sgid);
-}
-
-asmlinkage long
-sys32_lseek (unsigned int fd, int offset, unsigned int whence)
-{
-	/* Sign-extension of "offset" is important here... */
-	return sys_lseek(fd, offset, whence);
-}
-
-static int
-groups16_to_user(short __user *grouplist, struct group_info *group_info)
-{
-	int i;
-	short group;
-
-	for (i = 0; i < group_info->ngroups; i++) {
-		group = (short)GROUP_AT(group_info, i);
-		if (put_user(group, grouplist+i))
-			return -EFAULT;
-	}
-
-	return 0;
-}
-
-static int
-groups16_from_user(struct group_info *group_info, short __user *grouplist)
-{
-	int i;
-	short group;
-
-	for (i = 0; i < group_info->ngroups; i++) {
-		if (get_user(group, grouplist+i))
-			return  -EFAULT;
-		GROUP_AT(group_info, i) = (gid_t)group;
-	}
-
-	return 0;
-}
-
-asmlinkage long
-sys32_getgroups16 (int gidsetsize, short __user *grouplist)
-{
-	const struct cred *cred = current_cred();
-	int i;
-
-	if (gidsetsize < 0)
-		return -EINVAL;
-
-	i = cred->group_info->ngroups;
-	if (gidsetsize) {
-		if (i > gidsetsize) {
-			i = -EINVAL;
-			goto out;
-		}
-		if (groups16_to_user(grouplist, cred->group_info)) {
-			i = -EFAULT;
-			goto out;
-		}
-	}
-out:
-	return i;
-}
-
-asmlinkage long
-sys32_setgroups16 (int gidsetsize, short __user *grouplist)
-{
-	struct group_info *group_info;
-	int retval;
-
-	if (!capable(CAP_SETGID))
-		return -EPERM;
-	if ((unsigned)gidsetsize > NGROUPS_MAX)
-		return -EINVAL;
-
-	group_info = groups_alloc(gidsetsize);
-	if (!group_info)
-		return -ENOMEM;
-	retval = groups16_from_user(group_info, grouplist);
-	if (retval) {
-		put_group_info(group_info);
-		return retval;
-	}
-
-	retval = set_current_groups(group_info);
-	put_group_info(group_info);
-
-	return retval;
-}
-
-asmlinkage long
-sys32_truncate64 (unsigned int path, unsigned int len_lo, unsigned int len_hi)
-{
-	return sys_truncate(compat_ptr(path), ((unsigned long) len_hi << 32) | len_lo);
-}
-
-asmlinkage long
-sys32_ftruncate64 (int fd, unsigned int len_lo, unsigned int len_hi)
-{
-	return sys_ftruncate(fd, ((unsigned long) len_hi << 32) | len_lo);
-}
-
-static int
-putstat64 (struct stat64 __user *ubuf, struct kstat *kbuf)
-{
-	int err;
-	u64 hdev;
-
-	if (clear_user(ubuf, sizeof(*ubuf)))
-		return -EFAULT;
-
-	hdev = huge_encode_dev(kbuf->dev);
-	err  = __put_user(hdev, (u32 __user*)&ubuf->st_dev);
-	err |= __put_user(hdev >> 32, ((u32 __user*)&ubuf->st_dev) + 1);
-	err |= __put_user(kbuf->ino, &ubuf->__st_ino);
-	err |= __put_user(kbuf->ino, &ubuf->st_ino_lo);
-	err |= __put_user(kbuf->ino >> 32, &ubuf->st_ino_hi);
-	err |= __put_user(kbuf->mode, &ubuf->st_mode);
-	err |= __put_user(kbuf->nlink, &ubuf->st_nlink);
-	err |= __put_user(kbuf->uid, &ubuf->st_uid);
-	err |= __put_user(kbuf->gid, &ubuf->st_gid);
-	hdev = huge_encode_dev(kbuf->rdev);
-	err  = __put_user(hdev, (u32 __user*)&ubuf->st_rdev);
-	err |= __put_user(hdev >> 32, ((u32 __user*)&ubuf->st_rdev) + 1);
-	err |= __put_user(kbuf->size, &ubuf->st_size_lo);
-	err |= __put_user((kbuf->size >> 32), &ubuf->st_size_hi);
-	err |= __put_user(kbuf->atime.tv_sec, &ubuf->st_atime);
-	err |= __put_user(kbuf->atime.tv_nsec, &ubuf->st_atime_nsec);
-	err |= __put_user(kbuf->mtime.tv_sec, &ubuf->st_mtime);
-	err |= __put_user(kbuf->mtime.tv_nsec, &ubuf->st_mtime_nsec);
-	err |= __put_user(kbuf->ctime.tv_sec, &ubuf->st_ctime);
-	err |= __put_user(kbuf->ctime.tv_nsec, &ubuf->st_ctime_nsec);
-	err |= __put_user(kbuf->blksize, &ubuf->st_blksize);
-	err |= __put_user(kbuf->blocks, &ubuf->st_blocks);
-	return err;
-}
-
-asmlinkage long
-sys32_stat64 (char __user *filename, struct stat64 __user *statbuf)
-{
-	struct kstat s;
-	long ret = vfs_stat(filename, &s);
-	if (!ret)
-		ret = putstat64(statbuf, &s);
-	return ret;
-}
-
-asmlinkage long
-sys32_lstat64 (char __user *filename, struct stat64 __user *statbuf)
-{
-	struct kstat s;
-	long ret = vfs_lstat(filename, &s);
-	if (!ret)
-		ret = putstat64(statbuf, &s);
-	return ret;
-}
-
-asmlinkage long
-sys32_fstat64 (unsigned int fd, struct stat64 __user *statbuf)
-{
-	struct kstat s;
-	long ret = vfs_fstat(fd, &s);
-	if (!ret)
-		ret = putstat64(statbuf, &s);
-	return ret;
-}
-
-asmlinkage long
-sys32_sched_rr_get_interval (pid_t pid, struct compat_timespec __user *interval)
-{
-	mm_segment_t old_fs = get_fs();
-	struct timespec t;
-	long ret;
-
-	set_fs(KERNEL_DS);
-	ret = sys_sched_rr_get_interval(pid, (struct timespec __user *) &t);
-	set_fs(old_fs);
-	if (put_compat_timespec(&t, interval))
-		return -EFAULT;
-	return ret;
-}
-
-asmlinkage long
-sys32_pread (unsigned int fd, void __user *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
-{
-	return sys_pread64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
-}
-
-asmlinkage long
-sys32_pwrite (unsigned int fd, void __user *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
-{
-	return sys_pwrite64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
-}
-
-asmlinkage long
-sys32_sendfile (int out_fd, int in_fd, int __user *offset, unsigned int count)
-{
-	mm_segment_t old_fs = get_fs();
-	long ret;
-	off_t of;
-
-	if (offset && get_user(of, offset))
-		return -EFAULT;
-
-	set_fs(KERNEL_DS);
-	ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *) &of : NULL, count);
-	set_fs(old_fs);
-
-	if (offset && put_user(of, offset))
-		return -EFAULT;
-
-	return ret;
-}
-
-asmlinkage long
-sys32_personality (unsigned int personality)
-{
-	long ret;
-
-	if (current->personality == PER_LINUX32 && personality == PER_LINUX)
-		personality = PER_LINUX32;
-	ret = sys_personality(personality);
-	if (ret == PER_LINUX32)
-		ret = PER_LINUX;
-	return ret;
-}
-
-asmlinkage unsigned long
-sys32_brk (unsigned int brk)
-{
-	unsigned long ret, obrk;
-	struct mm_struct *mm = current->mm;
-
-	obrk = mm->brk;
-	ret = sys_brk(brk);
-	if (ret < obrk)
-		clear_user(compat_ptr(ret), PAGE_ALIGN(ret) - ret);
-	return ret;
-}
-
-/* Structure for ia32 emulation on ia64 */
-struct epoll_event32
-{
-	u32 events;
-	u32 data[2];
-};
-
-asmlinkage long
-sys32_epoll_ctl(int epfd, int op, int fd, struct epoll_event32 __user *event)
-{
-	mm_segment_t old_fs = get_fs();
-	struct epoll_event event64;
-	int error;
-	u32 data_halfword;
-
-	if (!access_ok(VERIFY_READ, event, sizeof(struct epoll_event32)))
-		return -EFAULT;
-
-	__get_user(event64.events, &event->events);
-	__get_user(data_halfword, &event->data[0]);
-	event64.data = data_halfword;
-	__get_user(data_halfword, &event->data[1]);
- 	event64.data |= (u64)data_halfword << 32;
-
-	set_fs(KERNEL_DS);
-	error = sys_epoll_ctl(epfd, op, fd, (struct epoll_event __user *) &event64);
-	set_fs(old_fs);
-
-	return error;
-}
-
-asmlinkage long
-sys32_epoll_wait(int epfd, struct epoll_event32 __user * events, int maxevents,
-		 int timeout)
-{
-	struct epoll_event *events64 = NULL;
-	mm_segment_t old_fs = get_fs();
-	int numevents, size;
-	int evt_idx;
-	int do_free_pages = 0;
-
-	if (maxevents <= 0) {
-		return -EINVAL;
-	}
-
-	/* Verify that the area passed by the user is writeable */
-	if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event32)))
-		return -EFAULT;
-
-	/*
- 	 * Allocate space for the intermediate copy.  If the space needed
-	 * is large enough to cause kmalloc to fail, then try again with
-	 * __get_free_pages.
-	 */
-	size = maxevents * sizeof(struct epoll_event);
-	events64 = kmalloc(size, GFP_KERNEL);
-	if (events64 == NULL) {
-		events64 = (struct epoll_event *)
-				__get_free_pages(GFP_KERNEL, get_order(size));
-		if (events64 == NULL)
-			return -ENOMEM;
-		do_free_pages = 1;
-	}
-
-	/* Do the system call */
-	set_fs(KERNEL_DS); /* copy_to/from_user should work on kernel mem*/
-	numevents = sys_epoll_wait(epfd, (struct epoll_event __user *) events64,
-				   maxevents, timeout);
-	set_fs(old_fs);
-
-	/* Don't modify userspace memory if we're returning an error */
-	if (numevents > 0) {
-		/* Translate the 64-bit structures back into the 32-bit
-		   structures */
-		for (evt_idx = 0; evt_idx < numevents; evt_idx++) {
-			__put_user(events64[evt_idx].events,
-				   &events[evt_idx].events);
-			__put_user((u32)events64[evt_idx].data,
-				   &events[evt_idx].data[0]);
-			__put_user((u32)(events64[evt_idx].data >> 32),
-				   &events[evt_idx].data[1]);
-		}
-	}
-
-	if (do_free_pages)
-		free_pages((unsigned long) events64, get_order(size));
-	else
-		kfree(events64);
-	return numevents;
-}
-
-/*
- * Get a yet unused TLS descriptor index.
- */
-static int
-get_free_idx (void)
-{
-	struct thread_struct *t = &current->thread;
-	int idx;
-
-	for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
-		if (desc_empty(t->tls_array + idx))
-			return idx + GDT_ENTRY_TLS_MIN;
-	return -ESRCH;
-}
-
-static void set_tls_desc(struct task_struct *p, int idx,
-		const struct ia32_user_desc *info, int n)
-{
-	struct thread_struct *t = &p->thread;
-	struct desc_struct *desc = &t->tls_array[idx - GDT_ENTRY_TLS_MIN];
-	int cpu;
-
-	/*
-	 * We must not get preempted while modifying the TLS.
-	 */
-	cpu = get_cpu();
-
-	while (n-- > 0) {
-		if (LDT_empty(info)) {
-			desc->a = 0;
-			desc->b = 0;
-		} else {
-			desc->a = LDT_entry_a(info);
-			desc->b = LDT_entry_b(info);
-		}
-
-		++info;
-		++desc;
-	}
-
-	if (t == &current->thread)
-		load_TLS(t, cpu);
-
-	put_cpu();
-}
-
-/*
- * Set a given TLS descriptor:
- */
-asmlinkage int
-sys32_set_thread_area (struct ia32_user_desc __user *u_info)
-{
-	struct ia32_user_desc info;
-	int idx;
-
-	if (copy_from_user(&info, u_info, sizeof(info)))
-		return -EFAULT;
-	idx = info.entry_number;
-
-	/*
-	 * index -1 means the kernel should try to find and allocate an empty descriptor:
-	 */
-	if (idx == -1) {
-		idx = get_free_idx();
-		if (idx < 0)
-			return idx;
-		if (put_user(idx, &u_info->entry_number))
-			return -EFAULT;
-	}
-
-	if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
-		return -EINVAL;
-
-	set_tls_desc(current, idx, &info, 1);
-	return 0;
-}
-
-/*
- * Get the current Thread-Local Storage area:
- */
-
-#define GET_BASE(desc) (			\
-	(((desc)->a >> 16) & 0x0000ffff) |	\
-	(((desc)->b << 16) & 0x00ff0000) |	\
-	( (desc)->b        & 0xff000000)   )
-
-#define GET_LIMIT(desc) (			\
-	((desc)->a & 0x0ffff) |			\
-	 ((desc)->b & 0xf0000) )
-
-#define GET_32BIT(desc)		(((desc)->b >> 22) & 1)
-#define GET_CONTENTS(desc)	(((desc)->b >> 10) & 3)
-#define GET_WRITABLE(desc)	(((desc)->b >>  9) & 1)
-#define GET_LIMIT_PAGES(desc)	(((desc)->b >> 23) & 1)
-#define GET_PRESENT(desc)	(((desc)->b >> 15) & 1)
-#define GET_USEABLE(desc)	(((desc)->b >> 20) & 1)
-
-static void fill_user_desc(struct ia32_user_desc *info, int idx,
-		const struct desc_struct *desc)
-{
-	info->entry_number = idx;
-	info->base_addr = GET_BASE(desc);
-	info->limit = GET_LIMIT(desc);
-	info->seg_32bit = GET_32BIT(desc);
-	info->contents = GET_CONTENTS(desc);
-	info->read_exec_only = !GET_WRITABLE(desc);
-	info->limit_in_pages = GET_LIMIT_PAGES(desc);
-	info->seg_not_present = !GET_PRESENT(desc);
-	info->useable = GET_USEABLE(desc);
-}
-
-asmlinkage int
-sys32_get_thread_area (struct ia32_user_desc __user *u_info)
-{
-	struct ia32_user_desc info;
-	struct desc_struct *desc;
-	int idx;
-
-	if (get_user(idx, &u_info->entry_number))
-		return -EFAULT;
-	if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
-		return -EINVAL;
-
-	desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
-	fill_user_desc(&info, idx, desc);
-
-	if (copy_to_user(u_info, &info, sizeof(info)))
-		return -EFAULT;
-	return 0;
-}
-
-struct regset_get {
-	void *kbuf;
-	void __user *ubuf;
-};
-
-struct regset_set {
-	const void *kbuf;
-	const void __user *ubuf;
-};
-
-struct regset_getset {
-	struct task_struct *target;
-	const struct user_regset *regset;
-	union {
-		struct regset_get get;
-		struct regset_set set;
-	} u;
-	unsigned int pos;
-	unsigned int count;
-	int ret;
-};
-
-static void getfpreg(struct task_struct *task, int regno, int *val)
-{
-	switch (regno / sizeof(int)) {
-	case 0:
-		*val = task->thread.fcr & 0xffff;
-		break;
-	case 1:
-		*val = task->thread.fsr & 0xffff;
-		break;
-	case 2:
-		*val = (task->thread.fsr>>16) & 0xffff;
-		break;
-	case 3:
-		*val = task->thread.fir;
-		break;
-	case 4:
-		*val = (task->thread.fir>>32) & 0xffff;
-		break;
-	case 5:
-		*val = task->thread.fdr;
-		break;
-	case 6:
-		*val = (task->thread.fdr >> 32) & 0xffff;
-		break;
-	}
-}
-
-static void setfpreg(struct task_struct *task, int regno, int val)
-{
-	switch (regno / sizeof(int)) {
-	case 0:
-		task->thread.fcr = (task->thread.fcr & (~0x1f3f))
-			| (val & 0x1f3f);
-		break;
-	case 1:
-		task->thread.fsr = (task->thread.fsr & (~0xffff)) | val;
-		break;
-	case 2:
-		task->thread.fsr = (task->thread.fsr & (~0xffff0000))
-			| (val << 16);
-		break;
-	case 3:
-		task->thread.fir = (task->thread.fir & (~0xffffffff)) | val;
-		break;
-	case 5:
-		task->thread.fdr = (task->thread.fdr & (~0xffffffff)) | val;
-		break;
-	}
-}
-
-static void access_fpreg_ia32(int regno, void *reg,
-		struct pt_regs *pt, struct switch_stack *sw,
-		int tos, int write)
-{
-	void *f;
-
-	if ((regno += tos) >= 8)
-		regno -= 8;
-	if (regno < 4)
-		f = &pt->f8 + regno;
-	else if (regno <= 7)
-		f = &sw->f12 + (regno - 4);
-	else {
-		printk(KERN_ERR "regno must be less than 7 \n");
-		 return;
-	}
-
-	if (write)
-		memcpy(f, reg, sizeof(struct _fpreg_ia32));
-	else
-		memcpy(reg, f, sizeof(struct _fpreg_ia32));
-}
-
-static void do_fpregs_get(struct unw_frame_info *info, void *arg)
-{
-	struct regset_getset *dst = arg;
-	struct task_struct *task = dst->target;
-	struct pt_regs *pt;
-	int start, end, tos;
-	char buf[80];
-
-	if (dst->count == 0 || unw_unwind_to_user(info) < 0)
-		return;
-	if (dst->pos < 7 * sizeof(int)) {
-		end = min((dst->pos + dst->count),
-			(unsigned int)(7 * sizeof(int)));
-		for (start = dst->pos; start < end; start += sizeof(int))
-			getfpreg(task, start, (int *)(buf + start));
-		dst->ret = user_regset_copyout(&dst->pos, &dst->count,
-				&dst->u.get.kbuf, &dst->u.get.ubuf, buf,
-				0, 7 * sizeof(int));
-		if (dst->ret || dst->count == 0)
-			return;
-	}
-	if (dst->pos < sizeof(struct ia32_user_i387_struct)) {
-		pt = task_pt_regs(task);
-		tos = (task->thread.fsr >> 11) & 7;
-		end = min(dst->pos + dst->count,
-			(unsigned int)(sizeof(struct ia32_user_i387_struct)));
-		start = (dst->pos - 7 * sizeof(int)) /
-			sizeof(struct _fpreg_ia32);
-		end = (end - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
-		for (; start < end; start++)
-			access_fpreg_ia32(start,
-				(struct _fpreg_ia32 *)buf + start,
-				pt, info->sw, tos, 0);
-		dst->ret = user_regset_copyout(&dst->pos, &dst->count,
-				&dst->u.get.kbuf, &dst->u.get.ubuf,
-				buf, 7 * sizeof(int),
-				sizeof(struct ia32_user_i387_struct));
-		if (dst->ret || dst->count == 0)
-			return;
-	}
-}
-
-static void do_fpregs_set(struct unw_frame_info *info, void *arg)
-{
-	struct regset_getset *dst = arg;
-	struct task_struct *task = dst->target;
-	struct pt_regs *pt;
-	char buf[80];
-	int end, start, tos;
-
-	if (dst->count == 0 || unw_unwind_to_user(info) < 0)
-		return;
-
-	if (dst->pos < 7 * sizeof(int)) {
-		start = dst->pos;
-		dst->ret = user_regset_copyin(&dst->pos, &dst->count,
-				&dst->u.set.kbuf, &dst->u.set.ubuf, buf,
-				0, 7 * sizeof(int));
-		if (dst->ret)
-			return;
-		for (; start < dst->pos; start += sizeof(int))
-			setfpreg(task, start, *((int *)(buf + start)));
-		if (dst->count == 0)
-			return;
-	}
-	if (dst->pos < sizeof(struct ia32_user_i387_struct)) {
-		start = (dst->pos - 7 * sizeof(int)) /
-			sizeof(struct _fpreg_ia32);
-		dst->ret = user_regset_copyin(&dst->pos, &dst->count,
-				&dst->u.set.kbuf, &dst->u.set.ubuf,
-				buf, 7 * sizeof(int),
-				sizeof(struct ia32_user_i387_struct));
-		if (dst->ret)
-			return;
-		pt = task_pt_regs(task);
-		tos = (task->thread.fsr >> 11) & 7;
-		end = (dst->pos - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
-		for (; start < end; start++)
-			access_fpreg_ia32(start,
-				(struct _fpreg_ia32 *)buf + start,
-				pt, info->sw, tos, 1);
-		if (dst->count == 0)
-			return;
-	}
-}
-
-#define OFFSET(member) ((int)(offsetof(struct ia32_user_fxsr_struct, member)))
-static void getfpxreg(struct task_struct *task, int start, int end, char *buf)
-{
-	int min_val;
-
-	min_val = min(end, OFFSET(fop));
-	while (start < min_val) {
-		if (start == OFFSET(cwd))
-			*((short *)buf) = task->thread.fcr & 0xffff;
-		else if (start == OFFSET(swd))
-			*((short *)buf) = task->thread.fsr & 0xffff;
-		else if (start == OFFSET(twd))
-			*((short *)buf) = (task->thread.fsr>>16) & 0xffff;
-		buf += 2;
-		start += 2;
-	}
-	/* skip fop element */
-	if (start == OFFSET(fop)) {
-		start += 2;
-		buf += 2;
-	}
-	while (start < end) {
-		if (start == OFFSET(fip))
-			*((int *)buf) = task->thread.fir;
-		else if (start == OFFSET(fcs))
-			*((int *)buf) = (task->thread.fir>>32) & 0xffff;
-		else if (start == OFFSET(foo))
-			*((int *)buf) = task->thread.fdr;
-		else if (start == OFFSET(fos))
-			*((int *)buf) = (task->thread.fdr>>32) & 0xffff;
-		else if (start == OFFSET(mxcsr))
-			*((int *)buf) = ((task->thread.fcr>>32) & 0xff80)
-					 | ((task->thread.fsr>>32) & 0x3f);
-		buf += 4;
-		start += 4;
-	}
-}
-
-static void setfpxreg(struct task_struct *task, int start, int end, char *buf)
-{
-	int min_val, num32;
-	short num;
-	unsigned long num64;
-
-	min_val = min(end, OFFSET(fop));
-	while (start < min_val) {
-		num = *((short *)buf);
-		if (start == OFFSET(cwd)) {
-			task->thread.fcr = (task->thread.fcr & (~0x1f3f))
-						| (num & 0x1f3f);
-		} else if (start == OFFSET(swd)) {
-			task->thread.fsr = (task->thread.fsr & (~0xffff)) | num;
-		} else if (start == OFFSET(twd)) {
-			task->thread.fsr = (task->thread.fsr & (~0xffff0000))
-				| (((int)num) << 16);
-		}
-		buf += 2;
-		start += 2;
-	}
-	/* skip fop element */
-	if (start == OFFSET(fop)) {
-		start += 2;
-		buf += 2;
-	}
-	while (start < end) {
-		num32 = *((int *)buf);
-		if (start == OFFSET(fip))
-			task->thread.fir = (task->thread.fir & (~0xffffffff))
-						 | num32;
-		else if (start == OFFSET(foo))
-			task->thread.fdr = (task->thread.fdr & (~0xffffffff))
-						 | num32;
-		else if (start == OFFSET(mxcsr)) {
-			num64 = num32 & 0xff10;
-			task->thread.fcr = (task->thread.fcr &
-				(~0xff1000000000UL)) | (num64<<32);
-			num64 = num32 & 0x3f;
-			task->thread.fsr = (task->thread.fsr &
-				(~0x3f00000000UL)) | (num64<<32);
-		}
-		buf += 4;
-		start += 4;
-	}
-}
-
-static void do_fpxregs_get(struct unw_frame_info *info, void *arg)
-{
-	struct regset_getset *dst = arg;
-	struct task_struct *task = dst->target;
-	struct pt_regs *pt;
-	char buf[128];
-	int start, end, tos;
-
-	if (dst->count == 0 || unw_unwind_to_user(info) < 0)
-		return;
-	if (dst->pos < OFFSET(st_space[0])) {
-		end = min(dst->pos + dst->count, (unsigned int)32);
-		getfpxreg(task, dst->pos, end, buf);
-		dst->ret = user_regset_copyout(&dst->pos, &dst->count,
-				&dst->u.get.kbuf, &dst->u.get.ubuf, buf,
-				0, OFFSET(st_space[0]));
-		if (dst->ret || dst->count == 0)
-			return;
-	}
-	if (dst->pos < OFFSET(xmm_space[0])) {
-		pt = task_pt_regs(task);
-		tos = (task->thread.fsr >> 11) & 7;
-		end = min(dst->pos + dst->count,
-				(unsigned int)OFFSET(xmm_space[0]));
-		start = (dst->pos - OFFSET(st_space[0])) / 16;
-		end = (end - OFFSET(st_space[0])) / 16;
-		for (; start < end; start++)
-			access_fpreg_ia32(start, buf + 16 * start, pt,
-						info->sw, tos, 0);
-		dst->ret = user_regset_copyout(&dst->pos, &dst->count,
-				&dst->u.get.kbuf, &dst->u.get.ubuf,
-				buf, OFFSET(st_space[0]), OFFSET(xmm_space[0]));
-		if (dst->ret || dst->count == 0)
-			return;
-	}
-	if (dst->pos < OFFSET(padding[0]))
-		dst->ret = user_regset_copyout(&dst->pos, &dst->count,
-				&dst->u.get.kbuf, &dst->u.get.ubuf,
-				&info->sw->f16, OFFSET(xmm_space[0]),
-				OFFSET(padding[0]));
-}
-
-static void do_fpxregs_set(struct unw_frame_info *info, void *arg)
-{
-	struct regset_getset *dst = arg;
-	struct task_struct *task = dst->target;
-	char buf[128];
-	int start, end;
-
-	if (dst->count == 0 || unw_unwind_to_user(info) < 0)
-		return;
-
-	if (dst->pos < OFFSET(st_space[0])) {
-		start = dst->pos;
-		dst->ret = user_regset_copyin(&dst->pos, &dst->count,
-				&dst->u.set.kbuf, &dst->u.set.ubuf,
-				buf, 0, OFFSET(st_space[0]));
-		if (dst->ret)
-			return;
-		setfpxreg(task, start, dst->pos, buf);
-		if (dst->count == 0)
-			return;
-	}
-	if (dst->pos < OFFSET(xmm_space[0])) {
-		struct pt_regs *pt;
-		int tos;
-		pt = task_pt_regs(task);
-		tos = (task->thread.fsr >> 11) & 7;
-		start = (dst->pos - OFFSET(st_space[0])) / 16;
-		dst->ret = user_regset_copyin(&dst->pos, &dst->count,
-				&dst->u.set.kbuf, &dst->u.set.ubuf,
-				buf, OFFSET(st_space[0]), OFFSET(xmm_space[0]));
-		if (dst->ret)
-			return;
-		end = (dst->pos - OFFSET(st_space[0])) / 16;
-		for (; start < end; start++)
-			access_fpreg_ia32(start, buf + 16 * start, pt, info->sw,
-						 tos, 1);
-		if (dst->count == 0)
-			return;
-	}
-	if (dst->pos < OFFSET(padding[0]))
-		dst->ret = user_regset_copyin(&dst->pos, &dst->count,
-				&dst->u.set.kbuf, &dst->u.set.ubuf,
-				&info->sw->f16, OFFSET(xmm_space[0]),
-				 OFFSET(padding[0]));
-}
-#undef OFFSET
-
-static int do_regset_call(void (*call)(struct unw_frame_info *, void *),
-		struct task_struct *target,
-		const struct user_regset *regset,
-		unsigned int pos, unsigned int count,
-		const void *kbuf, const void __user *ubuf)
-{
-	struct regset_getset info = { .target = target, .regset = regset,
-		.pos = pos, .count = count,
-		.u.set = { .kbuf = kbuf, .ubuf = ubuf },
-		.ret = 0 };
-
-	if (target == current)
-		unw_init_running(call, &info);
-	else {
-		struct unw_frame_info ufi;
-		memset(&ufi, 0, sizeof(ufi));
-		unw_init_from_blocked_task(&ufi, target);
-		(*call)(&ufi, &info);
-	}
-
-	return info.ret;
-}
-
-static int ia32_fpregs_get(struct task_struct *target,
-		const struct user_regset *regset,
-		unsigned int pos, unsigned int count,
-		void *kbuf, void __user *ubuf)
-{
-	return do_regset_call(do_fpregs_get, target, regset, pos, count,
-		kbuf, ubuf);
-}
-
-static int ia32_fpregs_set(struct task_struct *target,
-		const struct user_regset *regset,
-		unsigned int pos, unsigned int count,
-		const void *kbuf, const void __user *ubuf)
-{
-	return do_regset_call(do_fpregs_set, target, regset, pos, count,
-		kbuf, ubuf);
-}
-
-static int ia32_fpxregs_get(struct task_struct *target,
-		const struct user_regset *regset,
-		unsigned int pos, unsigned int count,
-		void *kbuf, void __user *ubuf)
-{
-	return do_regset_call(do_fpxregs_get, target, regset, pos, count,
-		kbuf, ubuf);
-}
-
-static int ia32_fpxregs_set(struct task_struct *target,
-		const struct user_regset *regset,
-		unsigned int pos, unsigned int count,
-		const void *kbuf, const void __user *ubuf)
-{
-	return do_regset_call(do_fpxregs_set, target, regset, pos, count,
-		kbuf, ubuf);
-}
-
-static int ia32_genregs_get(struct task_struct *target,
-		const struct user_regset *regset,
-		unsigned int pos, unsigned int count,
-		void *kbuf, void __user *ubuf)
-{
-	if (kbuf) {
-		u32 *kp = kbuf;
-		while (count > 0) {
-			*kp++ = getreg(target, pos);
-			pos += 4;
-			count -= 4;
-		}
-	} else {
-		u32 __user *up = ubuf;
-		while (count > 0) {
-			if (__put_user(getreg(target, pos), up++))
-				return -EFAULT;
-			pos += 4;
-			count -= 4;
-		}
-	}
-	return 0;
-}
-
-static int ia32_genregs_set(struct task_struct *target,
-		const struct user_regset *regset,
-		unsigned int pos, unsigned int count,
-		const void *kbuf, const void __user *ubuf)
-{
-	int ret = 0;
-
-	if (kbuf) {
-		const u32 *kp = kbuf;
-		while (!ret && count > 0) {
-			putreg(target, pos, *kp++);
-			pos += 4;
-			count -= 4;
-		}
-	} else {
-		const u32 __user *up = ubuf;
-		u32 val;
-		while (!ret && count > 0) {
-			ret = __get_user(val, up++);
-			if (!ret)
-				putreg(target, pos, val);
-			pos += 4;
-			count -= 4;
-		}
-	}
-	return ret;
-}
-
-static int ia32_tls_active(struct task_struct *target,
-		const struct user_regset *regset)
-{
-	struct thread_struct *t = &target->thread;
-	int n = GDT_ENTRY_TLS_ENTRIES;
-	while (n > 0 && desc_empty(&t->tls_array[n -1]))
-		--n;
-	return n;
-}
-
-static int ia32_tls_get(struct task_struct *target,
-		const struct user_regset *regset, unsigned int pos,
-		unsigned int count, void *kbuf, void __user *ubuf)
-{
-	const struct desc_struct *tls;
-
-	if (pos > GDT_ENTRY_TLS_ENTRIES * sizeof(struct ia32_user_desc) ||
-			(pos % sizeof(struct ia32_user_desc)) != 0 ||
-			(count % sizeof(struct ia32_user_desc)) != 0)
-		return -EINVAL;
-
-	pos /= sizeof(struct ia32_user_desc);
-	count /= sizeof(struct ia32_user_desc);
-
-	tls = &target->thread.tls_array[pos];
-
-	if (kbuf) {
-		struct ia32_user_desc *info = kbuf;
-		while (count-- > 0)
-			fill_user_desc(info++, GDT_ENTRY_TLS_MIN + pos++,
-					tls++);
-	} else {
-		struct ia32_user_desc __user *u_info = ubuf;
-		while (count-- > 0) {
-			struct ia32_user_desc info;
-			fill_user_desc(&info, GDT_ENTRY_TLS_MIN + pos++, tls++);
-			if (__copy_to_user(u_info++, &info, sizeof(info)))
-				return -EFAULT;
-		}
-	}
-
-	return 0;
-}
-
-static int ia32_tls_set(struct task_struct *target,
-		const struct user_regset *regset, unsigned int pos,
-		unsigned int count, const void *kbuf, const void __user *ubuf)
-{
-	struct ia32_user_desc infobuf[GDT_ENTRY_TLS_ENTRIES];
-	const struct ia32_user_desc *info;
-
-	if (pos > GDT_ENTRY_TLS_ENTRIES * sizeof(struct ia32_user_desc) ||
-			(pos % sizeof(struct ia32_user_desc)) != 0 ||
-			(count % sizeof(struct ia32_user_desc)) != 0)
-		return -EINVAL;
-
-	if (kbuf)
-		info = kbuf;
-	else if (__copy_from_user(infobuf, ubuf, count))
-		return -EFAULT;
-	else
-		info = infobuf;
-
-	set_tls_desc(target,
-		GDT_ENTRY_TLS_MIN + (pos / sizeof(struct ia32_user_desc)),
-		info, count / sizeof(struct ia32_user_desc));
-
-	return 0;
-}
-
-/*
- * This should match arch/i386/kernel/ptrace.c:native_regsets.
- * XXX ioperm? vm86?
- */
-static const struct user_regset ia32_regsets[] = {
-	{
-		.core_note_type = NT_PRSTATUS,
-		.n = sizeof(struct user_regs_struct32)/4,
-		.size = 4, .align = 4,
-		.get = ia32_genregs_get, .set = ia32_genregs_set
-	},
-	{
-		.core_note_type = NT_PRFPREG,
-		.n = sizeof(struct ia32_user_i387_struct) / 4,
-		.size = 4, .align = 4,
-		.get = ia32_fpregs_get, .set = ia32_fpregs_set
-	},
-	{
-		.core_note_type = NT_PRXFPREG,
-		.n = sizeof(struct ia32_user_fxsr_struct) / 4,
-		.size = 4, .align = 4,
-		.get = ia32_fpxregs_get, .set = ia32_fpxregs_set
-	},
-	{
-		.core_note_type = NT_386_TLS,
-		.n = GDT_ENTRY_TLS_ENTRIES,
-		.bias = GDT_ENTRY_TLS_MIN,
-		.size = sizeof(struct ia32_user_desc),
-		.align = sizeof(struct ia32_user_desc),
-		.active = ia32_tls_active,
-		.get = ia32_tls_get, .set = ia32_tls_set,
-	},
-};
-
-const struct user_regset_view user_ia32_view = {
-	.name = "i386", .e_machine = EM_386,
-	.regsets = ia32_regsets, .n = ARRAY_SIZE(ia32_regsets)
-};
-
-long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high, 
-			__u32 len_low, __u32 len_high, int advice)
-{ 
-	return sys_fadvise64_64(fd,
-			       (((u64)offset_high)<<32) | offset_low,
-			       (((u64)len_high)<<32) | len_low,
-			       advice); 
-} 
-
-#ifdef	NOTYET  /* UNTESTED FOR IA64 FROM HERE DOWN */
-
-asmlinkage long sys32_setreuid(compat_uid_t ruid, compat_uid_t euid)
-{
-	uid_t sruid, seuid;
-
-	sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid);
-	seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid);
-	return sys_setreuid(sruid, seuid);
-}
-
-asmlinkage long
-sys32_setresuid(compat_uid_t ruid, compat_uid_t euid,
-		compat_uid_t suid)
-{
-	uid_t sruid, seuid, ssuid;
-
-	sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid);
-	seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid);
-	ssuid = (suid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)suid);
-	return sys_setresuid(sruid, seuid, ssuid);
-}
-
-asmlinkage long
-sys32_setregid(compat_gid_t rgid, compat_gid_t egid)
-{
-	gid_t srgid, segid;
-
-	srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid);
-	segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid);
-	return sys_setregid(srgid, segid);
-}
-
-asmlinkage long
-sys32_setresgid(compat_gid_t rgid, compat_gid_t egid,
-		compat_gid_t sgid)
-{
-	gid_t srgid, segid, ssgid;
-
-	srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid);
-	segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid);
-	ssgid = (sgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)sgid);
-	return sys_setresgid(srgid, segid, ssgid);
-}
-#endif /* NOTYET */
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/include/asm/acpi.h linux-libre-2.6.34-gnu1/arch/ia64/include/asm/acpi.h
--- linux-libre-2.6.33-gnu1/arch/ia64/include/asm/acpi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/include/asm/acpi.h	2010-05-16 17:17:36.000000000 -0400
@@ -98,8 +98,34 @@ ia64_acpi_release_global_lock (unsigned
 #endif
 #define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */
 static inline void disable_acpi(void) { }
+static inline void pci_acpi_crs_quirks(void) { }
 
+#ifdef CONFIG_IA64_GENERIC
 const char *acpi_get_sysname (void);
+#else
+static inline const char *acpi_get_sysname (void)
+{
+# if defined (CONFIG_IA64_HP_SIM)
+	return "hpsim";
+# elif defined (CONFIG_IA64_HP_ZX1)
+	return "hpzx1";
+# elif defined (CONFIG_IA64_HP_ZX1_SWIOTLB)
+	return "hpzx1_swiotlb";
+# elif defined (CONFIG_IA64_SGI_SN2)
+	return "sn2";
+# elif defined (CONFIG_IA64_SGI_UV)
+	return "uv";
+# elif defined (CONFIG_IA64_DIG)
+	return "dig";
+# elif defined (CONFIG_IA64_XEN_GUEST)
+	return "xen";
+# elif defined(CONFIG_IA64_DIG_VTD)
+	return "dig_vtd";
+# else
+#	error Unknown platform.  Fix acpi.c.
+# endif
+}
+#endif
 int acpi_request_vector (u32 int_type);
 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/include/asm/compat.h linux-libre-2.6.34-gnu1/arch/ia64/include/asm/compat.h
--- linux-libre-2.6.33-gnu1/arch/ia64/include/asm/compat.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/include/asm/compat.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,8 @@
  */
 #include <linux/types.h>
 
-#define COMPAT_USER_HZ	100
+#define COMPAT_USER_HZ		100
+#define COMPAT_UTS_MACHINE	"i686\0\0\0"
 
 typedef u32		compat_size_t;
 typedef s32		compat_ssize_t;
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/include/asm/dmi.h linux-libre-2.6.34-gnu1/arch/ia64/include/asm/dmi.h
--- linux-libre-2.6.33-gnu1/arch/ia64/include/asm/dmi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/include/asm/dmi.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 #ifndef _ASM_DMI_H
 #define _ASM_DMI_H 1
 
+#include <linux/slab.h>
 #include <asm/io.h>
 
 /* Use normal IO mappings for DMI */
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/include/asm/elf.h linux-libre-2.6.34-gnu1/arch/ia64/include/asm/elf.h
--- linux-libre-2.6.33-gnu1/arch/ia64/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/include/asm/elf.h	2010-05-16 17:17:36.000000000 -0400
@@ -219,54 +219,6 @@ do {										\
 	NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR);		\
 } while (0)
 
-
-/*
- * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
- * extra segments containing the gate DSO contents.  Dumping its
- * contents makes post-mortem fully interpretable later without matching up
- * the same kernel and hardware config to see what PC values meant.
- * Dumping its extra ELF program headers includes all the other information
- * a debugger needs to easily find how the gate DSO was being used.
- */
-#define ELF_CORE_EXTRA_PHDRS		(GATE_EHDR->e_phnum)
-#define ELF_CORE_WRITE_EXTRA_PHDRS						\
-do {										\
-	const struct elf_phdr *const gate_phdrs =			      \
-		(const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);   \
-	int i;									\
-	Elf64_Off ofs = 0;						      \
-	for (i = 0; i < GATE_EHDR->e_phnum; ++i) {				\
-		struct elf_phdr phdr = gate_phdrs[i];			      \
-		if (phdr.p_type == PT_LOAD) {					\
-			phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);	      \
-			phdr.p_filesz = phdr.p_memsz;			      \
-			if (ofs == 0) {					      \
-				ofs = phdr.p_offset = offset;		      \
-			offset += phdr.p_filesz;				\
-		}							      \
-		else							      \
-				phdr.p_offset = ofs;			      \
-		}							      \
-		else							      \
-			phdr.p_offset += ofs;					\
-		phdr.p_paddr = 0; /* match other core phdrs */			\
-		DUMP_WRITE(&phdr, sizeof(phdr));				\
-	}									\
-} while (0)
-#define ELF_CORE_WRITE_EXTRA_DATA					\
-do {									\
-	const struct elf_phdr *const gate_phdrs =			      \
-		(const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);   \
-	int i;								\
-	for (i = 0; i < GATE_EHDR->e_phnum; ++i) {			\
-		if (gate_phdrs[i].p_type == PT_LOAD) {			      \
-			DUMP_WRITE((void *) gate_phdrs[i].p_vaddr,	      \
-				   PAGE_ALIGN(gate_phdrs[i].p_memsz));	      \
-			break;						      \
-		}							      \
-	}								\
-} while (0)
-
 /*
  * format for entries in the Global Offset Table
  */
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/include/asm/ia32.h linux-libre-2.6.34-gnu1/arch/ia64/include/asm/ia32.h
--- linux-libre-2.6.33-gnu1/arch/ia64/include/asm/ia32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/include/asm/ia32.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,40 +0,0 @@
-#ifndef _ASM_IA64_IA32_H
-#define _ASM_IA64_IA32_H
-
-
-#include <asm/ptrace.h>
-#include <asm/signal.h>
-
-#define IA32_NR_syscalls		285	/* length of syscall table */
-#define IA32_PAGE_SHIFT			12	/* 4KB pages */
-
-#ifndef __ASSEMBLY__
-
-# ifdef CONFIG_IA32_SUPPORT
-
-#define IA32_PAGE_OFFSET	0xc0000000
-
-extern void ia32_cpu_init (void);
-extern void ia32_mem_init (void);
-extern void ia32_gdt_init (void);
-extern int ia32_exception (struct pt_regs *regs, unsigned long isr);
-extern int ia32_intercept (struct pt_regs *regs, unsigned long isr);
-extern int ia32_clone_tls (struct task_struct *child, struct pt_regs *childregs);
-
-# endif /* !CONFIG_IA32_SUPPORT */
-
-/* Declare this unconditionally, so we don't get warnings for unreachable code.  */
-extern int ia32_setup_frame1 (int sig, struct k_sigaction *ka, siginfo_t *info,
-			      sigset_t *set, struct pt_regs *regs);
-#if PAGE_SHIFT > IA32_PAGE_SHIFT
-extern int ia32_copy_ia64_partial_page_list(struct task_struct *,
-					unsigned long);
-extern void ia32_drop_ia64_partial_page_list(struct task_struct *);
-#else
-# define ia32_copy_ia64_partial_page_list(a1, a2)	0
-# define ia32_drop_ia64_partial_page_list(a1)	do { ; } while (0)
-#endif
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* _ASM_IA64_IA32_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/include/asm/pci.h linux-libre-2.6.34-gnu1/arch/ia64/include/asm/pci.h
--- linux-libre-2.6.33-gnu1/arch/ia64/include/asm/pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/include/asm/pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -56,20 +56,6 @@ pcibios_penalize_isa_irq (int irq, int a
 
 #include <asm-generic/pci-dma-compat.h>
 
-/* pci_unmap_{single,page} is not a nop, thus... */
-#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_PCI
 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 					enum pci_dma_burst_strategy *strat,
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/include/asm/percpu.h linux-libre-2.6.34-gnu1/arch/ia64/include/asm/percpu.h
--- linux-libre-2.6.33-gnu1/arch/ia64/include/asm/percpu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/include/asm/percpu.h	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,7 @@
 #define PERCPU_ENOUGH_ROOM PERCPU_PAGE_SIZE
 
 #ifdef __ASSEMBLY__
-# define THIS_CPU(var)	(per_cpu__##var)  /* use this to mark accesses to per-CPU variables... */
+# define THIS_CPU(var)	(var)  /* use this to mark accesses to per-CPU variables... */
 #else /* !__ASSEMBLY__ */
 
 
@@ -39,7 +39,7 @@ extern void *per_cpu_init(void);
  * On the positive side, using __ia64_per_cpu_var() instead of __get_cpu_var() is slightly
  * more efficient.
  */
-#define __ia64_per_cpu_var(var)	per_cpu__##var
+#define __ia64_per_cpu_var(var)	var
 
 #include <asm-generic/percpu.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/include/asm/pgtable.h linux-libre-2.6.34-gnu1/arch/ia64/include/asm/pgtable.h
--- linux-libre-2.6.33-gnu1/arch/ia64/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -462,7 +462,7 @@ pte_same (pte_t a, pte_t b)
 	return pte_val(a) == pte_val(b);
 }
 
-#define update_mmu_cache(vma, address, pte) do { } while (0)
+#define update_mmu_cache(vma, address, ptep) do { } while (0)
 
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 extern void paging_init (void);
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/include/asm/processor.h linux-libre-2.6.34-gnu1/arch/ia64/include/asm/processor.h
--- linux-libre-2.6.33-gnu1/arch/ia64/include/asm/processor.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/include/asm/processor.h	2010-05-16 17:17:36.000000000 -0400
@@ -270,23 +270,6 @@ typedef struct {
 		 (int __user *) (addr));							\
 })
 
-#ifdef CONFIG_IA32_SUPPORT
-struct desc_struct {
-	unsigned int a, b;
-};
-
-#define desc_empty(desc)		(!((desc)->a | (desc)->b))
-#define desc_equal(desc1, desc2)	(((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
-
-#define GDT_ENTRY_TLS_ENTRIES	3
-#define GDT_ENTRY_TLS_MIN	6
-#define GDT_ENTRY_TLS_MAX 	(GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
-
-#define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8)
-
-struct ia64_partial_page_list;
-#endif
-
 struct thread_struct {
 	__u32 flags;			/* various thread flags (see IA64_THREAD_*) */
 	/* writing on_ustack is performance-critical, so it's worth spending 8 bits on it... */
@@ -298,29 +281,6 @@ struct thread_struct {
 	__u64 rbs_bot;			/* the base address for the RBS */
 	int last_fph_cpu;		/* CPU that may hold the contents of f32-f127 */
 
-#ifdef CONFIG_IA32_SUPPORT
-	__u64 eflag;			/* IA32 EFLAGS reg */
-	__u64 fsr;			/* IA32 floating pt status reg */
-	__u64 fcr;			/* IA32 floating pt control reg */
-	__u64 fir;			/* IA32 fp except. instr. reg */
-	__u64 fdr;			/* IA32 fp except. data reg */
-	__u64 old_k1;			/* old value of ar.k1 */
-	__u64 old_iob;			/* old IOBase value */
-	struct ia64_partial_page_list *ppl; /* partial page list for 4K page size issue */
-        /* cached TLS descriptors. */
-	struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
-
-# define INIT_THREAD_IA32	.eflag =	0,			\
-				.fsr =		0,			\
-				.fcr =		0x17800000037fULL,	\
-				.fir =		0,			\
-				.fdr =		0,			\
-				.old_k1 =	0,			\
-				.old_iob =	0,			\
-				.ppl =		NULL,
-#else
-# define INIT_THREAD_IA32
-#endif /* CONFIG_IA32_SUPPORT */
 #ifdef CONFIG_PERFMON
 	void *pfm_context;		     /* pointer to detailed PMU context */
 	unsigned long pfm_needs_checking;    /* when >0, pending perfmon work on kernel exit */
@@ -342,7 +302,6 @@ struct thread_struct {
 	.rbs_bot =	STACK_TOP - DEFAULT_USER_STACK_SIZE,	\
 	.task_size =	DEFAULT_TASK_SIZE,			\
 	.last_fph_cpu =  -1,					\
-	INIT_THREAD_IA32					\
 	INIT_THREAD_PM						\
 	.dbr =		{0, },					\
 	.ibr =		{0, },					\
@@ -485,11 +444,6 @@ extern void __ia64_load_fpu (struct ia64
 extern void ia64_save_debug_regs (unsigned long *save_area);
 extern void ia64_load_debug_regs (unsigned long *save_area);
 
-#ifdef CONFIG_IA32_SUPPORT
-extern void ia32_save_state (struct task_struct *task);
-extern void ia32_load_state (struct task_struct *task);
-#endif
-
 #define ia64_fph_enable()	do { ia64_rsm(IA64_PSR_DFH); ia64_srlz_d(); } while (0)
 #define ia64_fph_disable()	do { ia64_ssm(IA64_PSR_DFH); ia64_srlz_d(); } while (0)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/ia64/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/ia64/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -319,11 +319,7 @@ static inline unsigned long user_stack_p
 	ptrace_attach_sync_user_rbs(child)
 
   #define arch_has_single_step()  (1)
-  extern void user_enable_single_step(struct task_struct *);
-  extern void user_disable_single_step(struct task_struct *);
-
   #define arch_has_block_step()   (1)
-  extern void user_enable_block_step(struct task_struct *);
 
 #endif /* !__KERNEL__ */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/include/asm/scatterlist.h linux-libre-2.6.34-gnu1/arch/ia64/include/asm/scatterlist.h
--- linux-libre-2.6.33-gnu1/arch/ia64/include/asm/scatterlist.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/include/asm/scatterlist.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,25 +2,6 @@
 #define _ASM_IA64_SCATTERLIST_H
 
 /*
- * Modified 1998-1999, 2001-2002, 2004
- *	David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-
-#include <asm/types.h>
-
-struct scatterlist {
-#ifdef CONFIG_DEBUG_SG
-	unsigned long sg_magic;
-#endif
-	unsigned long page_link;
-	unsigned int offset;
-	unsigned int length;	/* buffer length */
-
-	dma_addr_t dma_address;
-	unsigned int dma_length;
-};
-
-/*
  * It used to be that ISA_DMA_THRESHOLD had something to do with the
  * DMA-limits of ISA-devices.  Nowadays, its only remaining use (apart
  * from the aha1542.c driver, which isn't 64-bit clean anyhow) is to
@@ -30,9 +11,6 @@ struct scatterlist {
  */
 #define ISA_DMA_THRESHOLD	0xffffffff
 
-#define sg_dma_len(sg)		((sg)->dma_length)
-#define sg_dma_address(sg)	((sg)->dma_address)
-
-#define	ARCH_HAS_SG_CHAIN
+#include <asm-generic/scatterlist.h>
 
 #endif /* _ASM_IA64_SCATTERLIST_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/include/asm/syscall.h linux-libre-2.6.34-gnu1/arch/ia64/include/asm/syscall.h
--- linux-libre-2.6.33-gnu1/arch/ia64/include/asm/syscall.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/include/asm/syscall.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,33 +22,18 @@ static inline long syscall_get_nr(struct
 	if ((long)regs->cr_ifs < 0) /* Not a syscall */
 		return -1;
 
-#ifdef CONFIG_IA32_SUPPORT
-	if (IS_IA32_PROCESS(regs))
-		return regs->r1;
-#endif
-
 	return regs->r15;
 }
 
 static inline void syscall_rollback(struct task_struct *task,
 				    struct pt_regs *regs)
 {
-#ifdef CONFIG_IA32_SUPPORT
-	if (IS_IA32_PROCESS(regs))
-		regs->r8 = regs->r1;
-#endif
-
 	/* do nothing */
 }
 
 static inline long syscall_get_error(struct task_struct *task,
 				     struct pt_regs *regs)
 {
-#ifdef CONFIG_IA32_SUPPORT
-	if (IS_IA32_PROCESS(regs))
-		return regs->r8;
-#endif
-
 	return regs->r10 == -1 ? regs->r8:0;
 }
 
@@ -62,13 +47,6 @@ static inline void syscall_set_return_va
 					    struct pt_regs *regs,
 					    int error, long val)
 {
-#ifdef CONFIG_IA32_SUPPORT
-	if (IS_IA32_PROCESS(regs)) {
-		regs->r8 = (long) error ? error : val;
-		return;
-	}
-#endif
-
 	if (error) {
 		/* error < 0, but ia64 uses > 0 return value */
 		regs->r8 = -error;
@@ -89,37 +67,6 @@ static inline void syscall_get_arguments
 {
 	BUG_ON(i + n > 6);
 
-#ifdef CONFIG_IA32_SUPPORT
-	if (IS_IA32_PROCESS(regs)) {
-		switch (i + n) {
-		case 6:
-			if (!n--) break;
-			*args++ = regs->r13;
-		case 5:
-			if (!n--) break;
-			*args++ = regs->r15;
-		case 4:
-			if (!n--) break;
-			*args++ = regs->r14;
-		case 3:
-			if (!n--) break;
-			*args++ = regs->r10;
-		case 2:
-			if (!n--) break;
-			*args++ = regs->r9;
-		case 1:
-			if (!n--) break;
-			*args++ = regs->r11;
-		case 0:
-			if (!n--) break;
-		default:
-			BUG();
-			break;
-		}
-
-		return;
-	}
-#endif
 	ia64_syscall_get_set_arguments(task, regs, i, n, args, 0);
 }
 
@@ -130,34 +77,6 @@ static inline void syscall_set_arguments
 {
 	BUG_ON(i + n > 6);
 
-#ifdef CONFIG_IA32_SUPPORT
-	if (IS_IA32_PROCESS(regs)) {
-		switch (i + n) {
-		case 6:
-			if (!n--) break;
-			regs->r13 = *args++;
-		case 5:
-			if (!n--) break;
-			regs->r15 = *args++;
-		case 4:
-			if (!n--) break;
-			regs->r14 = *args++;
-		case 3:
-			if (!n--) break;
-			regs->r10 = *args++;
-		case 2:
-			if (!n--) break;
-			regs->r9 = *args++;
-		case 1:
-			if (!n--) break;
-			regs->r11 = *args++;
-		case 0:
-			if (!n--) break;
-		}
-
-		return;
-	}
-#endif
 	ia64_syscall_get_set_arguments(task, regs, i, n, args, 1);
 }
 #endif	/* _ASM_SYSCALL_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/include/asm/system.h linux-libre-2.6.34-gnu1/arch/ia64/include/asm/system.h
--- linux-libre-2.6.33-gnu1/arch/ia64/include/asm/system.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/include/asm/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -191,15 +191,6 @@ do {								\
 
 #ifdef __KERNEL__
 
-#ifdef CONFIG_IA32_SUPPORT
-# define IS_IA32_PROCESS(regs)	(ia64_psr(regs)->is != 0)
-#else
-# define IS_IA32_PROCESS(regs)		0
-struct task_struct;
-static inline void ia32_save_state(struct task_struct *t __attribute__((unused))){}
-static inline void ia32_load_state(struct task_struct *t __attribute__((unused))){}
-#endif
-
 /*
  * Context switch from one thread to another.  If the two threads have
  * different address spaces, schedule() has already taken care of
@@ -233,7 +224,7 @@ extern void ia64_account_on_switch (stru
 
 #define IA64_HAS_EXTRA_STATE(t)							\
 	((t)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID)	\
-	 || IS_IA32_PROCESS(task_pt_regs(t)) || PERFMON_IS_SYSWIDE())
+	 || PERFMON_IS_SYSWIDE())
 
 #define __switch_to(prev,next,last) do {							 \
 	IA64_ACCOUNT_ON_SWITCH(prev, next);							 \
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/include/asm/unistd.h linux-libre-2.6.34-gnu1/arch/ia64/include/asm/unistd.h
--- linux-libre-2.6.33-gnu1/arch/ia64/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/include/asm/unistd.h	2010-05-16 17:17:36.000000000 -0400
@@ -335,20 +335,6 @@
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 
-#ifdef CONFIG_IA32_SUPPORT
-# 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_PAUSE
-# define __ARCH_WANT_SYS_SIGPENDING
-# define __ARCH_WANT_SYS_SIGPROCMASK
-# define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
-# define __ARCH_WANT_COMPAT_SYS_TIME
-#endif
-
 #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)
 
 #include <linux/types.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/include/asm/xen/events.h linux-libre-2.6.34-gnu1/arch/ia64/include/asm/xen/events.h
--- linux-libre-2.6.33-gnu1/arch/ia64/include/asm/xen/events.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/include/asm/xen/events.h	2010-05-16 17:17:36.000000000 -0400
@@ -36,10 +36,6 @@ static inline int xen_irqs_disabled(stru
 	return !(ia64_psr(regs)->i);
 }
 
-static inline void handle_irq(int irq, struct pt_regs *regs)
-{
-	__do_IRQ(irq);
-}
 #define irq_ctx_init(cpu)	do { } while (0)
 
 #endif /* _ASM_IA64_XEN_EVENTS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/Kconfig linux-libre-2.6.34-gnu1/arch/ia64/Kconfig
--- linux-libre-2.6.33-gnu1/arch/ia64/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -53,6 +53,9 @@ config MMU
 	bool
 	default y
 
+config NEED_DMA_MAP_STATE
+	def_bool y
+
 config SWIOTLB
        bool
 
@@ -499,23 +502,6 @@ config ARCH_PROC_KCORE_TEXT
 	def_bool y
 	depends on PROC_KCORE
 
-config IA32_SUPPORT
-	bool "Support for Linux/x86 binaries"
-	help
-	  IA-64 processors can execute IA-32 (X86) instructions.  By
-	  saying Y here, the kernel will include IA-32 system call
-	  emulation support which makes it possible to transparently
-	  run IA-32 Linux binaries on an IA-64 Linux system.
-	  If in doubt, say Y.
-
-config COMPAT
-	bool
-	depends on IA32_SUPPORT
-	default y
-
-config COMPAT_FOR_U64_ALIGNMENT
-	def_bool COMPAT
-
 config IA64_MCA_RECOVERY
 	tristate "MCA recovery from errors other than TLB."
 
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/acpi.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/acpi.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/acpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/acpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,8 @@
 #include <linux/efi.h>
 #include <linux/mmzone.h>
 #include <linux/nodemask.h>
+#include <linux/slab.h>
+#include <acpi/processor.h>
 #include <asm/io.h>
 #include <asm/iosapic.h>
 #include <asm/machvec.h>
@@ -60,11 +62,6 @@
 
 #define PREFIX			"ACPI: "
 
-void (*pm_idle) (void);
-EXPORT_SYMBOL(pm_idle);
-void (*pm_power_off) (void);
-EXPORT_SYMBOL(pm_power_off);
-
 u32 acpi_rsdt_forced;
 unsigned int acpi_cpei_override;
 unsigned int acpi_cpei_phys_cpuid;
@@ -83,12 +80,10 @@ static unsigned long __init acpi_find_rs
 		       "v1.0/r0.71 tables no longer supported\n");
 	return rsdp_phys;
 }
-#endif
 
 const char __init *
 acpi_get_sysname(void)
 {
-#ifdef CONFIG_IA64_GENERIC
 	unsigned long rsdp_phys;
 	struct acpi_table_rsdp *rsdp;
 	struct acpi_table_xsdt *xsdt;
@@ -143,30 +138,8 @@ acpi_get_sysname(void)
 #endif
 
 	return "dig";
-#else
-# if defined (CONFIG_IA64_HP_SIM)
-	return "hpsim";
-# elif defined (CONFIG_IA64_HP_ZX1)
-	return "hpzx1";
-# elif defined (CONFIG_IA64_HP_ZX1_SWIOTLB)
-	return "hpzx1_swiotlb";
-# elif defined (CONFIG_IA64_SGI_SN2)
-	return "sn2";
-# elif defined (CONFIG_IA64_SGI_UV)
-	return "uv";
-# elif defined (CONFIG_IA64_DIG)
-	return "dig";
-# elif defined (CONFIG_IA64_XEN_GUEST)
-	return "xen";
-# elif defined(CONFIG_IA64_DIG_VTD)
-	return "dig_vtd";
-# else
-#	error Unknown platform.  Fix acpi.c.
-# endif
-#endif
 }
-
-#ifdef CONFIG_ACPI
+#endif /* CONFIG_IA64_GENERIC */
 
 #define ACPI_MAX_PLATFORM_INTERRUPTS	256
 
@@ -881,8 +854,8 @@ __init void prefill_possible_map(void)
 
 	possible = available_cpus + additional_cpus;
 
-	if (possible > NR_CPUS)
-		possible = NR_CPUS;
+	if (possible > nr_cpu_ids)
+		possible = nr_cpu_ids;
 
 	printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n",
 		possible, max((possible - available_cpus), 0));
@@ -936,6 +909,8 @@ int acpi_map_lsapic(acpi_handle handle,
 	cpu_set(cpu, cpu_present_map);
 	ia64_cpu_to_sapicid[cpu] = physid;
 
+	acpi_processor_set_pdc(handle);
+
 	*pcpu = cpu;
 	return (0);
 }
@@ -1060,5 +1035,3 @@ void acpi_restore_state_mem(void) {}
  * do_suspend_lowlevel()
  */
 void do_suspend_lowlevel(void) {}
-
-#endif				/* CONFIG_ACPI */
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/acpi-ext.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/acpi-ext.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/acpi-ext.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/acpi-ext.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/acpi.h>
 
 #include <asm/acpi-ext.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/audit.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/audit.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/audit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/audit.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,20 +30,11 @@ static unsigned signal_class[] = {
 
 int audit_classify_arch(int arch)
 {
-#ifdef CONFIG_IA32_SUPPORT
-	if (arch == AUDIT_ARCH_I386)
-		return 1;
-#endif
 	return 0;
 }
 
 int audit_classify_syscall(int abi, unsigned syscall)
 {
-#ifdef CONFIG_IA32_SUPPORT
-	extern int ia32_classify_syscall(unsigned);
-	if (abi == AUDIT_ARCH_I386)
-		return ia32_classify_syscall(syscall);
-#endif
 	switch(syscall) {
 	case __NR_open:
 		return 2;
@@ -58,18 +49,6 @@ int audit_classify_syscall(int abi, unsi
 
 static int __init audit_classes_init(void)
 {
-#ifdef CONFIG_IA32_SUPPORT
-	extern __u32 ia32_dir_class[];
-	extern __u32 ia32_write_class[];
-	extern __u32 ia32_read_class[];
-	extern __u32 ia32_chattr_class[];
-	extern __u32 ia32_signal_class[];
-	audit_register_class(AUDIT_CLASS_WRITE_32, ia32_write_class);
-	audit_register_class(AUDIT_CLASS_READ_32, ia32_read_class);
-	audit_register_class(AUDIT_CLASS_DIR_WRITE_32, ia32_dir_class);
-	audit_register_class(AUDIT_CLASS_CHATTR_32, ia32_chattr_class);
-	audit_register_class(AUDIT_CLASS_SIGNAL_32, ia32_signal_class);
-#endif
 	audit_register_class(AUDIT_CLASS_WRITE, write_class);
 	audit_register_class(AUDIT_CLASS_READ, read_class);
 	audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/cpufreq/acpi-cpufreq.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/cpufreq/acpi-cpufreq.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/cpufreq/acpi-cpufreq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/cpufreq/acpi-cpufreq.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/efi.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/efi.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/efi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/efi.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/efi.h>
 #include <linux/kexec.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/elfcore.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/elfcore.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/elfcore.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/elfcore.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,80 @@
+#include <linux/elf.h>
+#include <linux/coredump.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+
+#include <asm/elf.h>
+
+
+Elf64_Half elf_core_extra_phdrs(void)
+{
+	return GATE_EHDR->e_phnum;
+}
+
+int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
+			       unsigned long limit)
+{
+	const struct elf_phdr *const gate_phdrs =
+		(const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
+	int i;
+	Elf64_Off ofs = 0;
+
+	for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
+		struct elf_phdr phdr = gate_phdrs[i];
+
+		if (phdr.p_type == PT_LOAD) {
+			phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);
+			phdr.p_filesz = phdr.p_memsz;
+			if (ofs == 0) {
+				ofs = phdr.p_offset = offset;
+				offset += phdr.p_filesz;
+			} else {
+				phdr.p_offset = ofs;
+			}
+		} else {
+			phdr.p_offset += ofs;
+		}
+		phdr.p_paddr = 0; /* match other core phdrs */
+		*size += sizeof(phdr);
+		if (*size > limit || !dump_write(file, &phdr, sizeof(phdr)))
+			return 0;
+	}
+	return 1;
+}
+
+int elf_core_write_extra_data(struct file *file, size_t *size,
+			      unsigned long limit)
+{
+	const struct elf_phdr *const gate_phdrs =
+		(const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
+	int i;
+
+	for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
+		if (gate_phdrs[i].p_type == PT_LOAD) {
+			void *addr = (void *)gate_phdrs[i].p_vaddr;
+			size_t memsz = PAGE_ALIGN(gate_phdrs[i].p_memsz);
+
+			*size += memsz;
+			if (*size > limit || !dump_write(file, addr, memsz))
+				return 0;
+			break;
+		}
+	}
+	return 1;
+}
+
+size_t elf_core_extra_data_size(void)
+{
+	const struct elf_phdr *const gate_phdrs =
+		(const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
+	int i;
+	size_t size = 0;
+
+	for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
+		if (gate_phdrs[i].p_type == PT_LOAD) {
+			size += PAGE_ALIGN(gate_phdrs[i].p_memsz);
+			break;
+		}
+	}
+	return size;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/entry.S linux-libre-2.6.34-gnu1/arch/ia64/kernel/entry.S
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/entry.S	2010-05-16 17:17:36.000000000 -0400
@@ -71,15 +71,6 @@ ENTRY(ia64_execve)
 	add out3=16,sp			// regs
 	br.call.sptk.many rp=sys_execve
 .ret0:
-#ifdef CONFIG_IA32_SUPPORT
-	/*
-	 * Check if we're returning to ia32 mode. If so, we need to restore ia32 registers
-	 * from pt_regs.
-	 */
-	adds r16=PT(CR_IPSR)+16,sp
-	;;
-	ld8 r16=[r16]
-#endif
 	cmp4.ge p6,p7=r8,r0
 	mov ar.pfs=loc1			// restore ar.pfs
 	sxt4 r8=r8			// return 64-bit result
@@ -108,12 +99,6 @@ ENTRY(ia64_execve)
 	ldf.fill f23=[sp];	ldf.fill f24=[sp];	mov f25=f0
 	ldf.fill f26=[sp];	ldf.fill f27=[sp];	mov f28=f0
 	ldf.fill f29=[sp];	ldf.fill f30=[sp];	mov f31=f0
-#ifdef CONFIG_IA32_SUPPORT
-	tbit.nz p6,p0=r16, IA64_PSR_IS_BIT
-	movl loc0=ia64_ret_from_ia32_execve
-	;;
-(p6)	mov rp=loc0
-#endif
 	br.ret.sptk.many rp
 END(ia64_execve)
 
@@ -848,30 +833,6 @@ __paravirt_work_processed_syscall:
 	br.cond.sptk.many rbs_switch	// B
 END(__paravirt_leave_syscall)
 
-#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
-#ifdef CONFIG_IA32_SUPPORT
-GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
-	PT_REGS_UNWIND_INFO(0)
-	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
-	adds r3=PT(R10)+16,sp			// r3 = &pt_regs.r10
-	;;
-	.mem.offset 0,0
-	st8.spill [r2]=r8	// store return value in slot for r8 and set unat bit
-	.mem.offset 8,0
-	st8.spill [r3]=r0	// clear error indication in slot for r10 and set unat bit
-#ifdef CONFIG_PARAVIRT
-	;;
-	// don't fall through, ia64_leave_kernel may be #define'd
-	br.cond.sptk.few ia64_leave_kernel
-	;;
-#endif /* CONFIG_PARAVIRT */
-END(ia64_ret_from_ia32_execve)
-#ifndef CONFIG_PARAVIRT
-	// fall through
-#endif
-#endif /* CONFIG_IA32_SUPPORT */
-#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
-
 GLOBAL_ENTRY(__paravirt_leave_kernel)
 	PT_REGS_UNWIND_INFO(0)
 	/*
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/ia64_ksyms.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/ia64_ksyms.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/ia64_ksyms.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/ia64_ksyms.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,9 +30,9 @@ EXPORT_SYMBOL(max_low_pfn);	/* defined b
 #endif
 
 #include <asm/processor.h>
-EXPORT_SYMBOL(per_cpu__ia64_cpu_info);
+EXPORT_SYMBOL(ia64_cpu_info);
 #ifdef CONFIG_SMP
-EXPORT_SYMBOL(per_cpu__local_per_cpu_offset);
+EXPORT_SYMBOL(local_per_cpu_offset);
 #endif
 
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/iosapic.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/iosapic.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/iosapic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/iosapic.c	2010-05-16 17:17:36.000000000 -0400
@@ -86,6 +86,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/string.h>
 #include <linux/bootmem.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/irq_ia64.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/irq_ia64.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/irq_ia64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/irq_ia64.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/kernel_stat.h>
-#include <linux/slab.h>
 #include <linux/ptrace.h>
 #include <linux/random.h>	/* for rand_initialize_irq() */
 #include <linux/signal.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/ivt.S linux-libre-2.6.34-gnu1/arch/ia64/kernel/ivt.S
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/ivt.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/ivt.S	2010-05-16 17:17:36.000000000 -0400
@@ -49,7 +49,6 @@
 
 #include <asm/asmmacro.h>
 #include <asm/break.h>
-#include <asm/ia32.h>
 #include <asm/kregs.h>
 #include <asm/asm-offsets.h>
 #include <asm/pgtable.h>
@@ -1386,28 +1385,6 @@ END(ia32_exception)
 // 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept  (30,31,59,70,71)
 ENTRY(ia32_intercept)
 	DBG_FAULT(46)
-#ifdef	CONFIG_IA32_SUPPORT
-	mov r31=pr
-	MOV_FROM_ISR(r16)
-	;;
-	extr.u r17=r16,16,8	// get ISR.code
-	mov r18=ar.eflag
-	MOV_FROM_IIM(r19)	// old eflag value
-	;;
-	cmp.ne p6,p0=2,r17
-(p6)	br.cond.spnt 1f		// not a system flag fault
-	xor r16=r18,r19
-	;;
-	extr.u r17=r16,18,1	// get the eflags.ac bit
-	;;
-	cmp.eq p6,p0=0,r17
-(p6)	br.cond.spnt 1f		// eflags.ac bit didn't change
-	;;
-	mov pr=r31,-1		// restore predicate registers
-	RFI
-
-1:
-#endif	// CONFIG_IA32_SUPPORT
 	FAULT(46)
 END(ia32_intercept)
 
@@ -1416,12 +1393,7 @@ END(ia32_intercept)
 // 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt  (74)
 ENTRY(ia32_interrupt)
 	DBG_FAULT(47)
-#ifdef CONFIG_IA32_SUPPORT
-	mov r31=pr
-	br.sptk.many dispatch_to_ia32_handler
-#else
 	FAULT(47)
-#endif
 END(ia32_interrupt)
 
 	.org ia64_ivt+0x6c00
@@ -1715,89 +1687,3 @@ ENTRY(dispatch_illegal_op_fault)
 (p6)	br.call.dpnt.many b6=b6		// call returns to ia64_leave_kernel
 	br.sptk.many ia64_leave_kernel
 END(dispatch_illegal_op_fault)
-
-#ifdef CONFIG_IA32_SUPPORT
-
-	/*
-	 * There is no particular reason for this code to be here, other than that
-	 * there happens to be space here that would go unused otherwise.  If this
-	 * fault ever gets "unreserved", simply moved the following code to a more
-	 * suitable spot...
-	 */
-
-	// IA32 interrupt entry point
-
-ENTRY(dispatch_to_ia32_handler)
-	SAVE_MIN
-	;;
-	MOV_FROM_ISR(r14)
-	SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24)
-				// guarantee that interruption collection is on
-	;;
-	SSM_PSR_I(p15, p15, r3)
-	adds r3=8,r2		// Base pointer for SAVE_REST
-	;;
-	SAVE_REST
-	;;
-	mov r15=0x80
-	shr r14=r14,16		// Get interrupt number
-	;;
-	cmp.ne p6,p0=r14,r15
-(p6)	br.call.dpnt.many b6=non_ia32_syscall
-
-	adds r14=IA64_PT_REGS_R8_OFFSET + 16,sp	// 16 byte hole per SW conventions
-	adds r15=IA64_PT_REGS_R1_OFFSET + 16,sp
-	;;
-	cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
-	ld8 r8=[r14]		// get r8
-	;;
-	st8 [r15]=r8		// save original EAX in r1 (IA32 procs don't use the GP)
-	;;
-	alloc r15=ar.pfs,0,0,6,0	// must first in an insn group
-	;;
-	ld4 r8=[r14],8		// r8 == eax (syscall number)
-	mov r15=IA32_NR_syscalls
-	;;
-	cmp.ltu.unc p6,p7=r8,r15
-	ld4 out1=[r14],8	// r9 == ecx
-	;;
-	ld4 out2=[r14],8	// r10 == edx
-	;;
-	ld4 out0=[r14]		// r11 == ebx
-	adds r14=(IA64_PT_REGS_R13_OFFSET) + 16,sp
-	;;
-	ld4 out5=[r14],PT(R14)-PT(R13)	// r13 == ebp
-	;;
-	ld4 out3=[r14],PT(R15)-PT(R14)	// r14 == esi
-	adds r2=TI_FLAGS+IA64_TASK_SIZE,r13
-	;;
-	ld4 out4=[r14]		// r15 == edi
-	movl r16=ia32_syscall_table
-	;;
-(p6)	shladd r16=r8,3,r16	// force ni_syscall if not valid syscall number
-	ld4 r2=[r2]		// r2 = current_thread_info()->flags
-	;;
-	ld8 r16=[r16]
-	and r2=_TIF_SYSCALL_TRACEAUDIT,r2	// mask trace or audit
-	;;
-	mov b6=r16
-	movl r15=ia32_ret_from_syscall
-	cmp.eq p8,p0=r2,r0
-	;;
-	mov rp=r15
-(p8)	br.call.sptk.many b6=b6
-	br.cond.sptk ia32_trace_syscall
-
-non_ia32_syscall:
-	alloc r15=ar.pfs,0,0,2,0
-	mov out0=r14				// interrupt #
-	add out1=16,sp				// pointer to pt_regs
-	;;			// avoid WAW on CFM
-	br.call.sptk.many rp=ia32_bad_interrupt
-.ret1:	movl r15=ia64_leave_kernel
-	;;
-	mov rp=r15
-	br.ret.sptk.many rp
-END(dispatch_to_ia32_handler)
-
-#endif /* CONFIG_IA32_SUPPORT */
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/kprobes.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/kprobes.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/kprobes.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/kprobes.c	2010-05-16 17:17:36.000000000 -0400
@@ -870,7 +870,7 @@ static int __kprobes pre_kprobes_handler
 		return 1;
 
 ss_probe:
-#if !defined(CONFIG_PREEMPT) || defined(CONFIG_FREEZER)
+#if !defined(CONFIG_PREEMPT)
 	if (p->ainsn.inst_flag == INST_FLAG_BOOSTABLE && !p->post_handler) {
 		/* Boost up -- we can execute copied instructions directly */
 		ia64_psr(regs)->ri = p->ainsn.slot;
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/Makefile linux-libre-2.6.34-gnu1/arch/ia64/kernel/Makefile
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -8,15 +8,13 @@ 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	\
+obj-y := 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 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 dma-mapping.o
 
+obj-$(CONFIG_ACPI)		+= acpi.o acpi-ext.o
 obj-$(CONFIG_IA64_BRL_EMU)	+= brl_emu.o
-obj-$(CONFIG_IA64_GENERIC)	+= acpi-ext.o
-obj-$(CONFIG_IA64_HP_ZX1)	+= acpi-ext.o
-obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += acpi-ext.o
 
 obj-$(CONFIG_IA64_PALINFO)	+= palinfo.o
 obj-$(CONFIG_IOSAPIC)		+= iosapic.o
@@ -47,6 +45,8 @@ endif
 obj-$(CONFIG_DMAR)		+= pci-dma.o
 obj-$(CONFIG_SWIOTLB)		+= pci-swiotlb.o
 
+obj-$(CONFIG_BINFMT_ELF)	+= elfcore.o
+
 # fp_emulate() expects f2-f5,f16-f31 to contain the user-level state.
 CFLAGS_traps.o  += -mfixed-range=f2-f5,f16-f31
 
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/mca.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/mca.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/mca.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/mca.c	2010-05-16 17:17:36.000000000 -0400
@@ -85,6 +85,7 @@
 #include <linux/cpumask.h>
 #include <linux/kdebug.h>
 #include <linux/cpu.h>
+#include <linux/gfp.h>
 
 #include <asm/delay.h>
 #include <asm/machvec.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/mca_drv.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/mca_drv.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/mca_drv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/mca_drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/smp.h>
 #include <linux/workqueue.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 
 #include <asm/delay.h>
 #include <asm/machvec.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/pci-swiotlb.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/pci-swiotlb.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/pci-swiotlb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/pci-swiotlb.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 /* Glue code to lib/swiotlb.c */
 
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include <linux/cache.h>
 #include <linux/module.h>
 #include <linux/dma-mapping.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/perfmon.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/perfmon.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/perfmon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/perfmon.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@
 #include <linux/rcupdate.h>
 #include <linux/completion.h>
 #include <linux/tracehook.h>
+#include <linux/slab.h>
 
 #include <asm/errno.h>
 #include <asm/intrinsics.h>
@@ -2315,6 +2316,7 @@ pfm_smpl_buffer_alloc(struct task_struct
 		DPRINT(("Cannot allocate vma\n"));
 		goto error_kmem;
 	}
+	INIT_LIST_HEAD(&vma->anon_vma_chain);
 
 	/*
 	 * partially initialize the vma for the sampling buffer
@@ -2713,7 +2715,7 @@ pfm_context_create(pfm_context_t *ctx, v
 			goto buffer_error;
 	}
 
-	DPRINT(("ctx=%p flags=0x%x system=%d notify_block=%d excl_idle=%d no_msg=%d ctx_fd=%d \n",
+	DPRINT(("ctx=%p flags=0x%x system=%d notify_block=%d excl_idle=%d no_msg=%d ctx_fd=%d\n",
 		ctx,
 		ctx_flags,
 		ctx->ctx_fl_system,
@@ -3677,7 +3679,7 @@ pfm_restart(pfm_context_t *ctx, void *ar
 	 * "self-monitoring".
 	 */
 	if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) {
-		DPRINT(("unblocking [%d] \n", task_pid_nr(task)));
+		DPRINT(("unblocking [%d]\n", task_pid_nr(task)));
 		complete(&ctx->ctx_restart_done);
 	} else {
 		DPRINT(("[%d] armed exit trap\n", task_pid_nr(task)));
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/process.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,11 +15,11 @@
 #include <linux/kallsyms.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/notifier.h>
 #include <linux/personality.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/stddef.h>
 #include <linux/thread_info.h>
 #include <linux/unistd.h>
@@ -33,7 +33,6 @@
 #include <asm/cpu.h>
 #include <asm/delay.h>
 #include <asm/elf.h>
-#include <asm/ia32.h>
 #include <asm/irq.h>
 #include <asm/kexec.h>
 #include <asm/pgalloc.h>
@@ -60,6 +59,10 @@ unsigned long idle_halt;
 EXPORT_SYMBOL(idle_halt);
 unsigned long idle_nomwait;
 EXPORT_SYMBOL(idle_nomwait);
+void (*pm_idle) (void);
+EXPORT_SYMBOL(pm_idle);
+void (*pm_power_off) (void);
+EXPORT_SYMBOL(pm_power_off);
 
 void
 ia64_do_show_stack (struct unw_frame_info *info, void *arg)
@@ -358,11 +361,6 @@ ia64_save_extra (struct task_struct *tas
 	if (info & PFM_CPUINFO_SYST_WIDE)
 		pfm_syst_wide_update_task(task, info, 0);
 #endif
-
-#ifdef CONFIG_IA32_SUPPORT
-	if (IS_IA32_PROCESS(task_pt_regs(task)))
-		ia32_save_state(task);
-#endif
 }
 
 void
@@ -383,11 +381,6 @@ ia64_load_extra (struct task_struct *tas
 	if (info & PFM_CPUINFO_SYST_WIDE) 
 		pfm_syst_wide_update_task(task, info, 1);
 #endif
-
-#ifdef CONFIG_IA32_SUPPORT
-	if (IS_IA32_PROCESS(task_pt_regs(task)))
-		ia32_load_state(task);
-#endif
 }
 
 /*
@@ -426,7 +419,7 @@ copy_thread(unsigned long clone_flags,
 	     unsigned long user_stack_base, unsigned long user_stack_size,
 	     struct task_struct *p, struct pt_regs *regs)
 {
-	extern char ia64_ret_from_clone, ia32_ret_from_clone;
+	extern char ia64_ret_from_clone;
 	struct switch_stack *child_stack, *stack;
 	unsigned long rbs, child_rbs, rbs_size;
 	struct pt_regs *child_ptregs;
@@ -457,7 +450,7 @@ copy_thread(unsigned long clone_flags,
 	memcpy((void *) child_rbs, (void *) rbs, rbs_size);
 
 	if (likely(user_mode(child_ptregs))) {
-		if ((clone_flags & CLONE_SETTLS) && !IS_IA32_PROCESS(regs))
+		if (clone_flags & CLONE_SETTLS)
 			child_ptregs->r13 = regs->r16;	/* see sys_clone2() in entry.S */
 		if (user_stack_base) {
 			child_ptregs->r12 = user_stack_base + user_stack_size - 16;
@@ -477,10 +470,7 @@ copy_thread(unsigned long clone_flags,
 		child_ptregs->r13 = (unsigned long) p;		/* set `current' pointer */
 	}
 	child_stack->ar_bspstore = child_rbs + rbs_size;
-	if (IS_IA32_PROCESS(regs))
-		child_stack->b0 = (unsigned long) &ia32_ret_from_clone;
-	else
-		child_stack->b0 = (unsigned long) &ia64_ret_from_clone;
+	child_stack->b0 = (unsigned long) &ia64_ret_from_clone;
 
 	/* copy parts of thread_struct: */
 	p->thread.ksp = (unsigned long) child_stack - 16;
@@ -515,22 +505,6 @@ copy_thread(unsigned long clone_flags,
 	p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR)
 			   | THREAD_FLAGS_TO_SET);
 	ia64_drop_fpu(p);	/* don't pick up stale state from a CPU's fph */
-#ifdef CONFIG_IA32_SUPPORT
-	/*
-	 * If we're cloning an IA32 task then save the IA32 extra
-	 * state from the current task to the new task
-	 */
-	if (IS_IA32_PROCESS(task_pt_regs(current))) {
-		ia32_save_state(p);
-		if (clone_flags & CLONE_SETTLS)
-			retval = ia32_clone_tls(p, child_ptregs);
-
-		/* Copy partially mapped page list */
-		if (!retval)
-			retval = ia32_copy_ia64_partial_page_list(p,
-								clone_flags);
-	}
-#endif
 
 #ifdef CONFIG_PERFMON
 	if (current->thread.pfm_context)
@@ -704,15 +678,6 @@ EXPORT_SYMBOL(kernel_thread);
 int
 kernel_thread_helper (int (*fn)(void *), void *arg)
 {
-#ifdef CONFIG_IA32_SUPPORT
-	if (IS_IA32_PROCESS(task_pt_regs(current))) {
-		/* A kernel thread is always a 64-bit process. */
-		current->thread.map_base  = DEFAULT_MAP_BASE;
-		current->thread.task_size = DEFAULT_TASK_SIZE;
-		ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob);
-		ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1);
-	}
-#endif
 	return (*fn)(arg);
 }
 
@@ -725,14 +690,6 @@ flush_thread (void)
 	/* drop floating-point and debug-register state if it exists: */
 	current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID);
 	ia64_drop_fpu(current);
-#ifdef CONFIG_IA32_SUPPORT
-	if (IS_IA32_PROCESS(task_pt_regs(current))) {
-		ia32_drop_ia64_partial_page_list(current);
-		current->thread.task_size = IA32_PAGE_OFFSET;
-		set_fs(USER_DS);
-		memset(current->thread.tls_array, 0, sizeof(current->thread.tls_array));
-	}
-#endif
 }
 
 /*
@@ -753,8 +710,6 @@ exit_thread (void)
 	if (current->thread.flags & IA64_THREAD_DBG_VALID)
 		pfm_release_debug_registers(current);
 #endif
-	if (IS_IA32_PROCESS(task_pt_regs(current)))
-		ia32_drop_ia64_partial_page_list(current);
 }
 
 unsigned long
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,6 @@
  */
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
@@ -1250,13 +1249,8 @@ syscall_trace_enter (long arg0, long arg
 		long syscall;
 		int arch;
 
-		if (IS_IA32_PROCESS(&regs)) {
-			syscall = regs.r1;
-			arch = AUDIT_ARCH_I386;
-		} else {
-			syscall = regs.r15;
-			arch = AUDIT_ARCH_IA64;
-		}
+		syscall = regs.r15;
+		arch = AUDIT_ARCH_IA64;
 
 		audit_syscall_entry(arch, syscall, arg0, arg1, arg2, arg3);
 	}
@@ -2172,11 +2166,6 @@ static const struct user_regset_view use
 
 const struct user_regset_view *task_user_regset_view(struct task_struct *tsk)
 {
-#ifdef CONFIG_IA32_SUPPORT
-	extern const struct user_regset_view user_ia32_view;
-	if (IS_IA32_PROCESS(task_pt_regs(tsk)))
-		return &user_ia32_view;
-#endif
 	return &user_ia64_view;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/setup.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/setup.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,7 +46,6 @@
 #include <linux/kexec.h>
 #include <linux/crash_dump.h>
 
-#include <asm/ia32.h>
 #include <asm/machvec.h>
 #include <asm/mca.h>
 #include <asm/meminit.h>
@@ -1016,10 +1015,6 @@ cpu_init (void)
 	ia64_mmu_init(ia64_imva(cpu_data));
 	ia64_mca_cpu_init(ia64_imva(cpu_data));
 
-#ifdef CONFIG_IA32_SUPPORT
-	ia32_cpu_init();
-#endif
-
 	/* Clear ITC to eliminate sched_clock() overflows in human time.  */
 	ia64_set_itc(0);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/signal.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/signal.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/signal.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/signal.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@
 #include <linux/unistd.h>
 #include <linux/wait.h>
 
-#include <asm/ia32.h>
 #include <asm/intrinsics.h>
 #include <asm/uaccess.h>
 #include <asm/rse.h>
@@ -425,14 +424,8 @@ static long
 handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset,
 	       struct sigscratch *scr)
 {
-	if (IS_IA32_PROCESS(&scr->pt)) {
-		/* send signal to IA-32 process */
-		if (!ia32_setup_frame1(sig, ka, info, oldset, &scr->pt))
-			return 0;
-	} else
-		/* send signal to IA-64 process */
-		if (!setup_frame(sig, ka, info, oldset, scr))
-			return 0;
+	if (!setup_frame(sig, ka, info, oldset, scr))
+		return 0;
 
 	spin_lock_irq(&current->sighand->siglock);
 	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
@@ -462,7 +455,6 @@ ia64_do_signal (struct sigscratch *scr,
 	siginfo_t info;
 	long restart = in_syscall;
 	long errno = scr->pt.r8;
-#	define ERR_CODE(c)	(IS_IA32_PROCESS(&scr->pt) ? -(c) : (c))
 
 	/*
 	 * In the ia64_leave_kernel code path, we want the common case to go fast, which
@@ -490,14 +482,7 @@ ia64_do_signal (struct sigscratch *scr,
 		 * inferior call), thus it's important to check for restarting _after_
 		 * get_signal_to_deliver().
 		 */
-		if (IS_IA32_PROCESS(&scr->pt)) {
-			if (in_syscall) {
-				if (errno >= 0)
-					restart = 0;
-				else
-					errno = -errno;
-			}
-		} else if ((long) scr->pt.r10 != -1)
+		if ((long) scr->pt.r10 != -1)
 			/*
 			 * A system calls has to be restarted only if one of the error codes
 			 * ERESTARTNOHAND, ERESTARTSYS, or ERESTARTNOINTR is returned.  If r10
@@ -513,22 +498,18 @@ ia64_do_signal (struct sigscratch *scr,
 			switch (errno) {
 			      case ERESTART_RESTARTBLOCK:
 			      case ERESTARTNOHAND:
-				scr->pt.r8 = ERR_CODE(EINTR);
+				scr->pt.r8 = EINTR;
 				/* note: scr->pt.r10 is already -1 */
 				break;
 
 			      case ERESTARTSYS:
 				if ((ka.sa.sa_flags & SA_RESTART) == 0) {
-					scr->pt.r8 = ERR_CODE(EINTR);
+					scr->pt.r8 = EINTR;
 					/* note: scr->pt.r10 is already -1 */
 					break;
 				}
 			      case ERESTARTNOINTR:
-				if (IS_IA32_PROCESS(&scr->pt)) {
-					scr->pt.r8 = scr->pt.r1;
-					scr->pt.cr_iip -= 2;
-				} else
-					ia64_decrement_ip(&scr->pt);
+				ia64_decrement_ip(&scr->pt);
 				restart = 0; /* don't restart twice if handle_signal() fails... */
 			}
 		}
@@ -555,21 +536,14 @@ ia64_do_signal (struct sigscratch *scr,
 		if (errno == ERESTARTNOHAND || errno == ERESTARTSYS || errno == ERESTARTNOINTR
 		    || errno == ERESTART_RESTARTBLOCK)
 		{
-			if (IS_IA32_PROCESS(&scr->pt)) {
-				scr->pt.r8 = scr->pt.r1;
-				scr->pt.cr_iip -= 2;
-				if (errno == ERESTART_RESTARTBLOCK)
-					scr->pt.r8 = 0;	/* x86 version of __NR_restart_syscall */
-			} else {
-				/*
-				 * Note: the syscall number is in r15 which is saved in
-				 * pt_regs so all we need to do here is adjust ip so that
-				 * the "break" instruction gets re-executed.
-				 */
-				ia64_decrement_ip(&scr->pt);
-				if (errno == ERESTART_RESTARTBLOCK)
-					scr->pt.r15 = __NR_restart_syscall;
-			}
+			/*
+			 * Note: the syscall number is in r15 which is saved in
+			 * pt_regs so all we need to do here is adjust ip so that
+			 * the "break" instruction gets re-executed.
+			 */
+			ia64_decrement_ip(&scr->pt);
+			if (errno == ERESTART_RESTARTBLOCK)
+				scr->pt.r15 = __NR_restart_syscall;
 		}
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/smpboot.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/smpboot.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/smpboot.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/smpboot.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,7 +44,6 @@
 #include <asm/cache.h>
 #include <asm/current.h>
 #include <asm/delay.h>
-#include <asm/ia32.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/machvec.h>
@@ -443,10 +442,6 @@ smp_callin (void)
 		calibrate_delay();
 	local_cpu_data->loops_per_jiffy = loops_per_jiffy;
 
-#ifdef CONFIG_IA32_SUPPORT
-	ia32_gdt_init();
-#endif
-
 	/*
 	 * Allow the master to continue.
 	 */
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/time.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/time.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -61,7 +61,7 @@ unsigned long long sched_clock(void)
 
 #ifdef CONFIG_PARAVIRT
 static void
-paravirt_clocksource_resume(void)
+paravirt_clocksource_resume(struct clocksource *cs)
 {
 	if (pv_time_ops.clocksource_resume)
 		pv_time_ops.clocksource_resume();
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/topology.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/topology.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/topology.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/topology.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/node.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/nodemask.h>
@@ -282,7 +283,7 @@ static ssize_t cache_show(struct kobject
 	return ret;
 }
 
-static struct sysfs_ops cache_sysfs_ops = {
+static const struct sysfs_ops cache_sysfs_ops = {
 	.show   = cache_show
 };
 
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/traps.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/traps.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/traps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/traps.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/kdebug.h>
 
 #include <asm/fpswa.h>
-#include <asm/ia32.h>
 #include <asm/intrinsics.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>
@@ -626,10 +625,6 @@ ia64_fault (unsigned long vector, unsign
 		break;
 
 	      case 45:
-#ifdef CONFIG_IA32_SUPPORT
-		if (ia32_exception(&regs, isr) == 0)
-			return;
-#endif
 		printk(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n");
 		printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n",
 		       iip, ifa, isr);
@@ -637,10 +632,6 @@ ia64_fault (unsigned long vector, unsign
 		break;
 
 	      case 46:
-#ifdef CONFIG_IA32_SUPPORT
-		if (ia32_intercept(&regs, isr) == 0)
-			return;
-#endif
 		printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n");
 		printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",
 		       iip, ifa, isr, iim);
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kernel/uncached.c linux-libre-2.6.34-gnu1/arch/ia64/kernel/uncached.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kernel/uncached.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kernel/uncached.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,9 +18,9 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/efi.h>
 #include <linux/genalloc.h>
+#include <linux/gfp.h>
 #include <asm/page.h>
 #include <asm/pal.h>
 #include <asm/system.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kvm/Kconfig linux-libre-2.6.34-gnu1/arch/ia64/kvm/Kconfig
--- linux-libre-2.6.33-gnu1/arch/ia64/kvm/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kvm/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@ config KVM
 	select ANON_INODES
 	select HAVE_KVM_IRQCHIP
 	select KVM_APIC_ARCHITECTURE
+	select KVM_MMIO
 	---help---
 	  Support hosting fully virtualized guest machines using hardware
 	  virtualization extensions.  You will need a fairly recent
@@ -47,6 +48,7 @@ config KVM_INTEL
 	  Provides support for KVM on Itanium 2 processors equipped with the VT
 	  extensions.
 
+source drivers/vhost/Kconfig
 source drivers/virtio/Kconfig
 
 endif # VIRTUALIZATION
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kvm/kvm_fw.c linux-libre-2.6.34-gnu1/arch/ia64/kvm/kvm_fw.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kvm/kvm_fw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kvm/kvm_fw.c	2010-05-16 17:17:36.000000000 -0400
@@ -75,7 +75,7 @@ static void set_pal_result(struct kvm_vc
 	struct exit_ctl_data *p;
 
 	p = kvm_get_exit_data(vcpu);
-	if (p && p->exit_reason == EXIT_REASON_PAL_CALL) {
+	if (p->exit_reason == EXIT_REASON_PAL_CALL) {
 		p->u.pal_data.ret = result;
 		return ;
 	}
@@ -87,7 +87,7 @@ static void set_sal_result(struct kvm_vc
 	struct exit_ctl_data *p;
 
 	p = kvm_get_exit_data(vcpu);
-	if (p && p->exit_reason == EXIT_REASON_SAL_CALL) {
+	if (p->exit_reason == EXIT_REASON_SAL_CALL) {
 		p->u.sal_data.ret = result;
 		return ;
 	}
@@ -322,7 +322,7 @@ static  u64 kvm_get_pal_call_index(struc
 	struct exit_ctl_data *p;
 
 	p = kvm_get_exit_data(vcpu);
-	if (p && (p->exit_reason == EXIT_REASON_PAL_CALL))
+	if (p->exit_reason == EXIT_REASON_PAL_CALL)
 		index = p->u.pal_data.gr28;
 
 	return index;
@@ -646,18 +646,16 @@ static void kvm_get_sal_call_data(struct
 
 	p = kvm_get_exit_data(vcpu);
 
-	if (p) {
-		if (p->exit_reason == EXIT_REASON_SAL_CALL) {
-			*in0 = p->u.sal_data.in0;
-			*in1 = p->u.sal_data.in1;
-			*in2 = p->u.sal_data.in2;
-			*in3 = p->u.sal_data.in3;
-			*in4 = p->u.sal_data.in4;
-			*in5 = p->u.sal_data.in5;
-			*in6 = p->u.sal_data.in6;
-			*in7 = p->u.sal_data.in7;
-			return ;
-		}
+	if (p->exit_reason == EXIT_REASON_SAL_CALL) {
+		*in0 = p->u.sal_data.in0;
+		*in1 = p->u.sal_data.in1;
+		*in2 = p->u.sal_data.in2;
+		*in3 = p->u.sal_data.in3;
+		*in4 = p->u.sal_data.in4;
+		*in5 = p->u.sal_data.in5;
+		*in6 = p->u.sal_data.in6;
+		*in7 = p->u.sal_data.in7;
+		return ;
 	}
 	*in0 = 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kvm/kvm-ia64.c linux-libre-2.6.34-gnu1/arch/ia64/kvm/kvm-ia64.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kvm/kvm-ia64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kvm/kvm-ia64.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,8 +23,8 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/percpu.h>
-#include <linux/gfp.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/kvm_host.h>
 #include <linux/kvm.h>
@@ -241,10 +241,10 @@ static int handle_mmio(struct kvm_vcpu *
 	return 0;
 mmio:
 	if (p->dir)
-		r = kvm_io_bus_read(&vcpu->kvm->mmio_bus, p->addr,
+		r = kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, p->addr,
 				    p->size, &p->data);
 	else
-		r = kvm_io_bus_write(&vcpu->kvm->mmio_bus, p->addr,
+		r = kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, p->addr,
 				     p->size, &p->data);
 	if (r)
 		printk(KERN_ERR"kvm: No iodevice found! addr:%lx\n", p->addr);
@@ -636,12 +636,9 @@ static void kvm_vcpu_post_transition(str
 static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	union context *host_ctx, *guest_ctx;
-	int r;
+	int r, idx;
 
-	/*
-	 * down_read() may sleep and return with interrupts enabled
-	 */
-	down_read(&vcpu->kvm->slots_lock);
+	idx = srcu_read_lock(&vcpu->kvm->srcu);
 
 again:
 	if (signal_pending(current)) {
@@ -663,7 +660,7 @@ again:
 	if (r < 0)
 		goto vcpu_run_fail;
 
-	up_read(&vcpu->kvm->slots_lock);
+	srcu_read_unlock(&vcpu->kvm->srcu, idx);
 	kvm_guest_enter();
 
 	/*
@@ -687,7 +684,7 @@ again:
 	kvm_guest_exit();
 	preempt_enable();
 
-	down_read(&vcpu->kvm->slots_lock);
+	idx = srcu_read_lock(&vcpu->kvm->srcu);
 
 	r = kvm_handle_exit(kvm_run, vcpu);
 
@@ -697,10 +694,10 @@ again:
 	}
 
 out:
-	up_read(&vcpu->kvm->slots_lock);
+	srcu_read_unlock(&vcpu->kvm->srcu, idx);
 	if (r > 0) {
 		kvm_resched(vcpu);
-		down_read(&vcpu->kvm->slots_lock);
+		idx = srcu_read_lock(&vcpu->kvm->srcu);
 		goto again;
 	}
 
@@ -971,7 +968,7 @@ long kvm_arch_vm_ioctl(struct file *filp
 			goto out;
 		r = kvm_setup_default_irq_routing(kvm);
 		if (r) {
-			kfree(kvm->arch.vioapic);
+			kvm_ioapic_destroy(kvm);
 			goto out;
 		}
 		break;
@@ -1377,12 +1374,14 @@ static void free_kvm(struct kvm *kvm)
 
 static void kvm_release_vm_pages(struct kvm *kvm)
 {
+	struct kvm_memslots *slots;
 	struct kvm_memory_slot *memslot;
 	int i, j;
 	unsigned long base_gfn;
 
-	for (i = 0; i < kvm->nmemslots; i++) {
-		memslot = &kvm->memslots[i];
+	slots = rcu_dereference(kvm->memslots);
+	for (i = 0; i < slots->nmemslots; i++) {
+		memslot = &slots->memslots[i];
 		base_gfn = memslot->base_gfn;
 
 		for (j = 0; j < memslot->npages; j++) {
@@ -1405,6 +1404,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm
 	kfree(kvm->arch.vioapic);
 	kvm_release_vm_pages(kvm);
 	kvm_free_physmem(kvm);
+	cleanup_srcu_struct(&kvm->srcu);
 	free_kvm(kvm);
 }
 
@@ -1576,15 +1576,15 @@ out:
 	return r;
 }
 
-int kvm_arch_set_memory_region(struct kvm *kvm,
-		struct kvm_userspace_memory_region *mem,
+int kvm_arch_prepare_memory_region(struct kvm *kvm,
+		struct kvm_memory_slot *memslot,
 		struct kvm_memory_slot old,
+		struct kvm_userspace_memory_region *mem,
 		int user_alloc)
 {
 	unsigned long i;
 	unsigned long pfn;
-	int npages = mem->memory_size >> PAGE_SHIFT;
-	struct kvm_memory_slot *memslot = &kvm->memslots[mem->slot];
+	int npages = memslot->npages;
 	unsigned long base_gfn = memslot->base_gfn;
 
 	if (base_gfn + npages > (KVM_MAX_MEM_SIZE >> PAGE_SHIFT))
@@ -1608,6 +1608,14 @@ int kvm_arch_set_memory_region(struct kv
 	return 0;
 }
 
+void kvm_arch_commit_memory_region(struct kvm *kvm,
+		struct kvm_userspace_memory_region *mem,
+		struct kvm_memory_slot old,
+		int user_alloc)
+{
+	return;
+}
+
 void kvm_arch_flush_shadow(struct kvm *kvm)
 {
 	kvm_flush_remote_tlbs(kvm);
@@ -1794,7 +1802,8 @@ static int kvm_ia64_sync_dirty_log(struc
 {
 	struct kvm_memory_slot *memslot;
 	int r, i;
-	long n, base;
+	long base;
+	unsigned long n;
 	unsigned long *dirty_bitmap = (unsigned long *)(kvm->arch.vm_base +
 			offsetof(struct kvm_vm_data, kvm_mem_dirty_log));
 
@@ -1802,12 +1811,12 @@ static int kvm_ia64_sync_dirty_log(struc
 	if (log->slot >= KVM_MEMORY_SLOTS)
 		goto out;
 
-	memslot = &kvm->memslots[log->slot];
+	memslot = &kvm->memslots->memslots[log->slot];
 	r = -ENOENT;
 	if (!memslot->dirty_bitmap)
 		goto out;
 
-	n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+	n = kvm_dirty_bitmap_bytes(memslot);
 	base = memslot->base_gfn / BITS_PER_LONG;
 
 	for (i = 0; i < n/sizeof(long); ++i) {
@@ -1823,10 +1832,11 @@ int kvm_vm_ioctl_get_dirty_log(struct kv
 		struct kvm_dirty_log *log)
 {
 	int r;
-	int n;
+	unsigned long n;
 	struct kvm_memory_slot *memslot;
 	int is_dirty = 0;
 
+	mutex_lock(&kvm->slots_lock);
 	spin_lock(&kvm->arch.dirty_log_lock);
 
 	r = kvm_ia64_sync_dirty_log(kvm, log);
@@ -1840,12 +1850,13 @@ int kvm_vm_ioctl_get_dirty_log(struct kv
 	/* If nothing is dirty, don't bother messing with page tables. */
 	if (is_dirty) {
 		kvm_flush_remote_tlbs(kvm);
-		memslot = &kvm->memslots[log->slot];
-		n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+		memslot = &kvm->memslots->memslots[log->slot];
+		n = kvm_dirty_bitmap_bytes(memslot);
 		memset(memslot->dirty_bitmap, 0, n);
 	}
 	r = 0;
 out:
+	mutex_unlock(&kvm->slots_lock);
 	spin_unlock(&kvm->arch.dirty_log_lock);
 	return r;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kvm/mmio.c linux-libre-2.6.34-gnu1/arch/ia64/kvm/mmio.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kvm/mmio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kvm/mmio.c	2010-05-16 17:17:36.000000000 -0400
@@ -316,8 +316,8 @@ void emulate_io_inst(struct kvm_vcpu *vc
 		return;
 	} else {
 		inst_type = -1;
-		panic_vm(vcpu, "Unsupported MMIO access instruction! \
-				Bunld[0]=0x%lx, Bundle[1]=0x%lx\n",
+		panic_vm(vcpu, "Unsupported MMIO access instruction! "
+				"Bunld[0]=0x%lx, Bundle[1]=0x%lx\n",
 				bundle.i64[0], bundle.i64[1]);
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/kvm/vcpu.c linux-libre-2.6.34-gnu1/arch/ia64/kvm/vcpu.c
--- linux-libre-2.6.33-gnu1/arch/ia64/kvm/vcpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/kvm/vcpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -1639,8 +1639,8 @@ void vcpu_set_psr(struct kvm_vcpu *vcpu,
 	 * Otherwise panic
 	 */
 	if (val & (IA64_PSR_PK | IA64_PSR_IS | IA64_PSR_VM))
-		panic_vm(vcpu, "Only support guests with vpsr.pk =0 \
-				& vpsr.is=0\n");
+		panic_vm(vcpu, "Only support guests with vpsr.pk =0 "
+				"& vpsr.is=0\n");
 
 	/*
 	 * For those IA64_PSR bits: id/da/dd/ss/ed/ia
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/Makefile linux-libre-2.6.34-gnu1/arch/ia64/Makefile
--- linux-libre-2.6.33-gnu1/arch/ia64/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -46,7 +46,6 @@ head-y := arch/ia64/kernel/head.o arch/i
 
 libs-y				+= arch/ia64/lib/
 core-y				+= arch/ia64/kernel/ arch/ia64/mm/
-core-$(CONFIG_IA32_SUPPORT)	+= arch/ia64/ia32/
 core-$(CONFIG_IA64_DIG) 	+= arch/ia64/dig/
 core-$(CONFIG_IA64_DIG_VTD) 	+= arch/ia64/dig/
 core-$(CONFIG_IA64_GENERIC) 	+= arch/ia64/dig/
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/mm/discontig.c linux-libre-2.6.34-gnu1/arch/ia64/mm/discontig.c
--- linux-libre-2.6.33-gnu1/arch/ia64/mm/discontig.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/mm/discontig.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/acpi.h>
 #include <linux/efi.h>
 #include <linux/nodemask.h>
+#include <linux/slab.h>
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
 #include <asm/meminit.h>
@@ -459,7 +460,7 @@ static void __init initialize_pernode_da
 		cpu = 0;
 		node = node_cpuid[cpu].nid;
 		cpu0_cpu_info = (struct cpuinfo_ia64 *)(__phys_per_cpu_start +
-			((char *)&per_cpu__ia64_cpu_info - __per_cpu_start));
+			((char *)&ia64_cpu_info - __per_cpu_start));
 		cpu0_cpu_info->node_data = mem_data[node].node_data;
 	}
 #endif /* CONFIG_SMP */
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/mm/hugetlbpage.c linux-libre-2.6.34-gnu1/arch/ia64/mm/hugetlbpage.c
--- linux-libre-2.6.33-gnu1/arch/ia64/mm/hugetlbpage.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/mm/hugetlbpage.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
 #include <linux/hugetlb.h>
 #include <linux/pagemap.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/log2.h>
 #include <asm/mman.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/mm/init.c linux-libre-2.6.34-gnu1/arch/ia64/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/ia64/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/kexec.h>
 
 #include <asm/dma.h>
-#include <asm/ia32.h>
 #include <asm/io.h>
 #include <asm/machvec.h>
 #include <asm/numa.h>
@@ -118,6 +117,7 @@ ia64_init_addr_space (void)
 	 */
 	vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
 	if (vma) {
+		INIT_LIST_HEAD(&vma->anon_vma_chain);
 		vma->vm_mm = current->mm;
 		vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
 		vma->vm_end = vma->vm_start + PAGE_SIZE;
@@ -136,6 +136,7 @@ ia64_init_addr_space (void)
 	if (!(current->personality & MMAP_PAGE_ZERO)) {
 		vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
 		if (vma) {
+			INIT_LIST_HEAD(&vma->anon_vma_chain);
 			vma->vm_mm = current->mm;
 			vma->vm_end = PAGE_SIZE;
 			vma->vm_page_prot = __pgprot(pgprot_val(PAGE_READONLY) | _PAGE_MA_NAT);
@@ -668,10 +669,6 @@ mem_init (void)
 			fsyscall_table[i] = sys_call_table[i] | 1;
 	}
 	setup_gate();
-
-#ifdef CONFIG_IA32_SUPPORT
-	ia32_mem_init();
-#endif
 }
 
 #ifdef CONFIG_MEMORY_HOTPLUG
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/mm/tlb.c linux-libre-2.6.34-gnu1/arch/ia64/mm/tlb.c
--- linux-libre-2.6.33-gnu1/arch/ia64/mm/tlb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/mm/tlb.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/smp.h>
 #include <linux/mm.h>
 #include <linux/bootmem.h>
+#include <linux/slab.h>
 
 #include <asm/delay.h>
 #include <asm/mmu_context.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/pci/pci.c linux-libre-2.6.34-gnu1/arch/ia64/pci/pci.c
--- linux-libre-2.6.33-gnu1/arch/ia64/pci/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/pci/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -320,9 +320,9 @@ static __devinit acpi_status add_window(
 static void __devinit
 pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl)
 {
-	int i, j;
+	int i;
 
-	j = 0;
+	pci_bus_remove_resources(bus);
 	for (i = 0; i < ctrl->windows; i++) {
 		struct resource *res = &ctrl->window[i].resource;
 		/* HP's firmware has a hack to work around a Windows bug.
@@ -330,13 +330,7 @@ pcibios_setup_root_windows(struct pci_bu
 		if ((res->flags & IORESOURCE_MEM) &&
 		    (res->end - res->start < 16))
 			continue;
-		if (j >= PCI_BUS_NUM_RESOURCES) {
-			dev_warn(&bus->dev,
-				 "ignoring host bridge window %pR (no space)\n",
-				 res);
-			continue;
-		}
-		bus->resource[j++] = res;
+		pci_bus_add_resource(bus, res, 0);
 	}
 }
 
@@ -452,13 +446,12 @@ EXPORT_SYMBOL(pcibios_bus_to_resource);
 static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
 {
 	unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
-	struct resource *devr = &dev->resource[idx];
+	struct resource *devr = &dev->resource[idx], *busr;
 
 	if (!dev->bus)
 		return 0;
-	for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
-		struct resource *busr = dev->bus->resource[i];
 
+	pci_bus_for_each_resource(dev->bus, busr, i) {
 		if (!busr || ((busr->flags ^ devr->flags) & type_mask))
 			continue;
 		if ((devr->start) && (devr->start >= busr->start) &&
@@ -547,10 +540,11 @@ pcibios_disable_device (struct pci_dev *
 		acpi_pci_irq_disable(dev);
 }
 
-void
-pcibios_align_resource (void *data, struct resource *res,
+resource_size_t
+pcibios_align_resource (void *data, const struct resource *res,
 		        resource_size_t size, resource_size_t align)
 {
+	return res->start;
 }
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/bte.c linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/bte.c
--- linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/bte.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/bte.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/bootmem.h>
 #include <linux/string.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <asm/sn/bte.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/io_acpi_init.c linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/io_acpi_init.c
--- linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/io_acpi_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/io_acpi_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <asm/sn/sn_sal.h>
 #include "xtalk/hubdev.h"
 #include <linux/acpi.h>
+#include <linux/slab.h>
 
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/io_common.c linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/io_common.c
--- linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/io_common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/io_common.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
  */
 
 #include <linux/bootmem.h>
+#include <linux/slab.h>
 #include <asm/sn/types.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/sn_feature_sets.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/io_init.c linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/io_init.c
--- linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/io_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/io_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
  * Copyright (C) 1992 - 1997, 2000-2006 Silicon Graphics, Inc. All rights reserved.
  */
 
+#include <linux/slab.h>
 #include <asm/sn/types.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/irq.c linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/irq.c
--- linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/spinlock.h>
 #include <linux/init.h>
 #include <linux/rculist.h>
+#include <linux/slab.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/intr.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/msi_sn.c linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/msi_sn.c
--- linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/msi_sn.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/msi_sn.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/pci.h>
 #include <linux/cpumask.h>
 #include <linux/msi.h>
+#include <linux/slab.h>
 
 #include <asm/sn/addrs.h>
 #include <asm/sn/intr.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/setup.c linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/setup.c
--- linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -241,7 +241,7 @@ static void __cpuinit sn_check_for_wars(
  * Note:  This stuff is duped here because Altix requires the PCDP to
  * locate a usable VGA device due to lack of proper ACPI support.  Structures
  * could be used from drivers/firmware/pcdp.h, but it was decided that moving
- * this file to a more public location just for Altix use was undesireable.
+ * this file to a more public location just for Altix use was undesirable.
  */
 
 struct hcdp_uart_desc {
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/sn/pci/pcibr/pcibr_provider.c linux-libre-2.6.34-gnu1/arch/ia64/sn/pci/pcibr/pcibr_provider.c
--- linux-libre-2.6.33-gnu1/arch/ia64/sn/pci/pcibr/pcibr_provider.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/sn/pci/pcibr/pcibr_provider.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/geo.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/sn/pci/pci_dma.c linux-libre-2.6.34-gnu1/arch/ia64/sn/pci/pci_dma.c
--- linux-libre-2.6.33-gnu1/arch/ia64/sn/pci/pci_dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/sn/pci/pci_dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  * a description of how these routines should be used.
  */
 
+#include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <asm/dma.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/sn/pci/tioca_provider.c linux-libre-2.6.34-gnu1/arch/ia64/sn/pci/tioca_provider.c
--- linux-libre-2.6.33-gnu1/arch/ia64/sn/pci/tioca_provider.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/sn/pci/tioca_provider.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/bitmap.h>
+#include <linux/slab.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/sn/pci/tioce_provider.c linux-libre-2.6.34-gnu1/arch/ia64/sn/pci/tioce_provider.c
--- linux-libre-2.6.33-gnu1/arch/ia64/sn/pci/tioce_provider.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/sn/pci/tioce_provider.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/addrs.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/uv/kernel/setup.c linux-libre-2.6.34-gnu1/arch/ia64/uv/kernel/setup.c
--- linux-libre-2.6.33-gnu1/arch/ia64/uv/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/uv/kernel/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -104,7 +104,7 @@ void __init uv_setup(char **cmdline_p)
 		uv_cpu_hub_info(cpu)->lowmem_remap_top =
 			lowmem_redir_base + 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)->n_val = n_val;
 		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;
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/xen/grant-table.c linux-libre-2.6.34-gnu1/arch/ia64/xen/grant-table.c
--- linux-libre-2.6.33-gnu1/arch/ia64/xen/grant-table.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/xen/grant-table.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 
 #include <xen/interface/xen.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/xen/hypercall.S linux-libre-2.6.34-gnu1/arch/ia64/xen/hypercall.S
--- linux-libre-2.6.33-gnu1/arch/ia64/xen/hypercall.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/xen/hypercall.S	2010-05-16 17:17:36.000000000 -0400
@@ -58,11 +58,6 @@ __HCALL2(xen_ptcga, HYPERPRIVOP_PTC_GA)
 __HCALL2(xen_set_rr, HYPERPRIVOP_SET_RR)
 __HCALL2(xen_set_kr, HYPERPRIVOP_SET_KR)
 
-#ifdef CONFIG_IA32_SUPPORT
-__HCALL0(xen_get_eflag, HYPERPRIVOP_GET_EFLAG)
-__HCALL1(xen_set_eflag, HYPERPRIVOP_SET_EFLAG)	// refer SDM vol1 3.1.8
-#endif /* CONFIG_IA32_SUPPORT */
-
 GLOBAL_ENTRY(xen_set_rr0_to_rr4)
 	mov r8=r32
 	mov r9=r33
diff -druNp linux-libre-2.6.33-gnu1/arch/ia64/xen/xen_pv_ops.c linux-libre-2.6.34-gnu1/arch/ia64/xen/xen_pv_ops.c
--- linux-libre-2.6.33-gnu1/arch/ia64/xen/xen_pv_ops.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/ia64/xen/xen_pv_ops.c	2010-05-16 17:17:36.000000000 -0400
@@ -301,11 +301,6 @@ static void xen_setreg(int regnum, unsig
 	case _IA64_REG_AR_KR0 ... _IA64_REG_AR_KR7:
 		xen_set_kr(regnum - _IA64_REG_AR_KR0, val);
 		break;
-#ifdef CONFIG_IA32_SUPPORT
-	case _IA64_REG_AR_EFLAG:
-		xen_set_eflag(val);
-		break;
-#endif
 	case _IA64_REG_AR_ITC:
 		xen_set_itc(val);
 		break;
@@ -332,11 +327,6 @@ static unsigned long xen_getreg(int regn
 	case _IA64_REG_PSR:
 		res = xen_get_psr();
 		break;
-#ifdef CONFIG_IA32_SUPPORT
-	case _IA64_REG_AR_EFLAG:
-		res = xen_get_eflag();
-		break;
-#endif
 	case _IA64_REG_AR_ITC:
 		res = xen_get_itc();
 		break;
@@ -710,9 +700,6 @@ extern unsigned long xen_getreg(int regn
 
 __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"
@@ -789,9 +776,6 @@ __DEFINE_FUNC(setreg,
 	      ";;\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)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/Kconfig linux-libre-2.6.34-gnu1/arch/Kconfig
--- linux-libre-2.6.33-gnu1/arch/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -3,11 +3,9 @@
 #
 
 config OPROFILE
-	tristate "OProfile system profiling (EXPERIMENTAL)"
+	tristate "OProfile system profiling"
 	depends on PROFILING
 	depends on HAVE_OPROFILE
-	depends on TRACING_SUPPORT
-	select TRACING
 	select RING_BUFFER
 	select RING_BUFFER_ALLOW_SWAP
 	help
@@ -17,20 +15,6 @@ config OPROFILE
 
 	  If unsure, say N.
 
-config OPROFILE_IBS
-	bool "OProfile AMD IBS support (EXPERIMENTAL)"
-	default n
-	depends on OPROFILE && SMP && X86
-	help
-          Instruction-Based Sampling (IBS) is a new profiling
-          technique that provides rich, precise program performance
-          information. IBS is introduced by AMD Family10h processors
-          (AMD Opteron Quad-Core processor "Barcelona") to overcome
-          the limitations of conventional performance counter
-          sampling.
-
-	  If unsure, say N.
-
 config OPROFILE_EVENT_MULTIPLEX
 	bool "OProfile multiplexing support (EXPERIMENTAL)"
 	default n
@@ -57,6 +41,17 @@ config KPROBES
 	  for kernel debugging, non-intrusive instrumentation and testing.
 	  If in doubt, say "N".
 
+config OPTPROBES
+	bool "Kprobes jump optimization support (EXPERIMENTAL)"
+	default y
+	depends on KPROBES
+	depends on !PREEMPT
+	depends on HAVE_OPTPROBES
+	select KALLSYMS_ALL
+	help
+	  This option will allow kprobes to optimize breakpoint to
+	  a jump for reducing its overhead.
+
 config HAVE_EFFICIENT_UNALIGNED_ACCESS
 	bool
 	help
@@ -99,6 +94,8 @@ config HAVE_KPROBES
 config HAVE_KRETPROBES
 	bool
 
+config HAVE_OPTPROBES
+	bool
 #
 # An arch should select this if it provides all these things:
 #
@@ -121,6 +118,14 @@ config HAVE_DMA_ATTRS
 config USE_GENERIC_SMP_HELPERS
 	bool
 
+config HAVE_REGS_AND_STACK_ACCESS_API
+	bool
+	help
+	  This symbol should be selected by an architecure if it supports
+	  the API needed to access registers and stack entries from pt_regs,
+	  declared in asm/ptrace.h
+	  For example the kprobes-based event tracer needs this API.
+
 config HAVE_CLK
 	bool
 	help
diff -druNp linux-libre-2.6.33-gnu1/arch/m32r/include/asm/local.h linux-libre-2.6.34-gnu1/arch/m32r/include/asm/local.h
--- linux-libre-2.6.33-gnu1/arch/m32r/include/asm/local.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m32r/include/asm/local.h	2010-05-16 17:17:36.000000000 -0400
@@ -338,29 +338,4 @@ static inline void local_set_mask(unsign
  * 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.33-gnu1/arch/m32r/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/m32r/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/m32r/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m32r/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -120,6 +120,8 @@ struct pt_regs {
 
 #include <asm/m32r.h>		/* M32R_PSW_BSM, M32R_PSW_BPM */
 
+#define arch_has_single_step() (1)
+
 struct task_struct;
 extern void init_debug_traps(struct task_struct *);
 #define arch_ptrace_attach(child) \
diff -druNp linux-libre-2.6.33-gnu1/arch/m32r/include/asm/tlbflush.h linux-libre-2.6.34-gnu1/arch/m32r/include/asm/tlbflush.h
--- linux-libre-2.6.33-gnu1/arch/m32r/include/asm/tlbflush.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m32r/include/asm/tlbflush.h	2010-05-16 17:17:36.000000000 -0400
@@ -92,6 +92,6 @@ static __inline__ void __flush_tlb_all(v
 	);
 }
 
-extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
+extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
 
 #endif	/* _ASM_M32R_TLBFLUSH_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/m32r/include/asm/unistd.h linux-libre-2.6.34-gnu1/arch/m32r/include/asm/unistd.h
--- linux-libre-2.6.33-gnu1/arch/m32r/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m32r/include/asm/unistd.h	2010-05-16 17:17:36.000000000 -0400
@@ -339,6 +339,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
diff -druNp linux-libre-2.6.33-gnu1/arch/m32r/kernel/process.c linux-libre-2.6.34-gnu1/arch/m32r/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/m32r/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m32r/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,10 +21,10 @@
  */
 
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/hardirq.h>
 
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/m32r/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/m32r/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/m32r/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m32r/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -580,6 +580,35 @@ init_debug_traps(struct task_struct *chi
 	}
 }
 
+void user_enable_single_step(struct task_struct *child)
+{
+	unsigned long next_pc;
+	unsigned long pc, insn;
+
+	clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+
+	/* Compute next pc.  */
+	pc = get_stack_long(child, PT_BPC);
+
+	if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0)
+	    != sizeof(insn))
+		break;
+
+	compute_next_pc(insn, pc, &next_pc, child);
+	if (next_pc & 0x80000000)
+		break;
+
+	if (embed_debug_trap(child, next_pc))
+		break;
+
+	invalidate_cache();
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+	unregister_all_debug_traps(child);
+	invalidate_cache();
+}
 
 /*
  * Called by kernel/ptrace.c when detaching..
@@ -630,74 +659,6 @@ arch_ptrace(struct task_struct *child, l
 		ret = ptrace_write_user(child, addr, data);
 		break;
 
-	/*
-	 * continue/restart and stop at next (return from) syscall
-	 */
-	case PTRACE_SYSCALL:
-	case PTRACE_CONT:
-		ret = -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;
-		wake_up_process(child);
-		ret = 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: {
-		ret = 0;
-		unregister_all_debug_traps(child);
-		invalidate_cache();
-		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
-			break;
-		child->exit_code = SIGKILL;
-		wake_up_process(child);
-		break;
-	}
-
-	/*
-	 * execute single instruction.
-	 */
-	case PTRACE_SINGLESTEP: {
-		unsigned long next_pc;
-		unsigned long pc, insn;
-
-		ret = -EIO;
-		if (!valid_signal(data))
-			break;
-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-
-		/* Compute next pc.  */
-		pc = get_stack_long(child, PT_BPC);
-
-		if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0)
-		    != sizeof(insn))
-			break;
-
-		compute_next_pc(insn, pc, &next_pc, child);
-		if (next_pc & 0x80000000)
-			break;
-
-		if (embed_debug_trap(child, next_pc))
-			break;
-
-		invalidate_cache();
-		child->exit_code = data;
-
-		/* give it a chance to run. */
-		wake_up_process(child);
-		ret = 0;
-		break;
-	}
-
 	case PTRACE_GETREGS:
 		ret = ptrace_getregs(child, (void __user *)data);
 		break;
diff -druNp linux-libre-2.6.33-gnu1/arch/m32r/kernel/sys_m32r.c linux-libre-2.6.34-gnu1/arch/m32r/kernel/sys_m32r.c
--- linux-libre-2.6.33-gnu1/arch/m32r/kernel/sys_m32r.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m32r/kernel/sys_m32r.c	2010-05-16 17:17:36.000000000 -0400
@@ -76,98 +76,6 @@ asmlinkage int sys_tas(int __user *addr)
 	return oldval;
 }
 
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage int sys_ipc(uint call, int first, int second,
-		       int third, void __user *ptr, long fifth)
-{
-	int version, ret;
-
-	version = call >> 16; /* hack for backward compatibility */
-	call &= 0xffff;
-
-	switch (call) {
-	case SEMOP:
-		return sys_semtimedop(first, (struct sembuf __user *)ptr,
-				      second, NULL);
-	case SEMTIMEDOP:
-		return sys_semtimedop(first, (struct sembuf __user *)ptr,
-				      second, (const struct timespec __user *)fifth);
-	case SEMGET:
-		return sys_semget (first, second, third);
-	case SEMCTL: {
-		union semun fourth;
-		if (!ptr)
-			return -EINVAL;
-		if (get_user(fourth.__pad, (void __user * __user *) ptr))
-			return -EFAULT;
-		return sys_semctl (first, second, third, fourth);
-		}
-
-	case MSGSND:
-		return sys_msgsnd (first, (struct msgbuf __user *) ptr,
-				   second, third);
-	case MSGRCV:
-		switch (version) {
-		case 0: {
-			struct ipc_kludge tmp;
-			if (!ptr)
-				return -EINVAL;
-
-			if (copy_from_user(&tmp,
-					   (struct ipc_kludge __user *) ptr,
-					   sizeof (tmp)))
-				return -EFAULT;
-			return sys_msgrcv (first, tmp.msgp, second,
-					   tmp.msgtyp, third);
-			}
-		default:
-			return sys_msgrcv (first,
-					   (struct msgbuf __user *) ptr,
-					   second, fifth, third);
-		}
-	case MSGGET:
-		return sys_msgget ((key_t) first, second);
-	case MSGCTL:
-		return sys_msgctl (first, second,
-				   (struct msqid_ds __user *) ptr);
-	case SHMAT: {
-		ulong raddr;
-
-		if (!access_ok(VERIFY_WRITE, (ulong __user *) third,
-				      sizeof(ulong)))
-			return -EFAULT;
-		ret = do_shmat (first, (char __user *) ptr, second, &raddr);
-		if (ret)
-			return ret;
-		return put_user (raddr, (ulong __user *) third);
-		}
-	case SHMDT:
-		return sys_shmdt ((char __user *)ptr);
-	case SHMGET:
-		return sys_shmget (first, second, third);
-	case SHMCTL:
-		return sys_shmctl (first, second,
-				   (struct shmid_ds __user *) ptr);
-	default:
-		return -ENOSYS;
-	}
-}
-
-asmlinkage int sys_uname(struct old_utsname __user * name)
-{
-	int err;
-	if (!name)
-		return -EFAULT;
-	down_read(&uts_sem);
-	err = copy_to_user(name, utsname(), sizeof (*name));
-	up_read(&uts_sem);
-	return err?-EFAULT:0;
-}
-
 asmlinkage int sys_cacheflush(void *addr, int bytes, int cache)
 {
 	/* This should flush more selectively ...  */
diff -druNp linux-libre-2.6.33-gnu1/arch/m32r/mm/fault.c linux-libre-2.6.34-gnu1/arch/m32r/mm/fault.c
--- linux-libre-2.6.33-gnu1/arch/m32r/mm/fault.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m32r/mm/fault.c	2010-05-16 17:17:36.000000000 -0400
@@ -336,7 +336,7 @@ vmalloc_fault:
 
 		addr = (address & PAGE_MASK);
 		set_thread_fault_code(error_code);
-		update_mmu_cache(NULL, addr, *pte_k);
+		update_mmu_cache(NULL, addr, pte_k);
 		set_thread_fault_code(0);
 		return;
 	}
@@ -349,7 +349,7 @@ vmalloc_fault:
 #define ITLB_END	(unsigned long *)(ITLB_BASE + (NR_TLB_ENTRIES * 8))
 #define DTLB_END	(unsigned long *)(DTLB_BASE + (NR_TLB_ENTRIES * 8))
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr,
-	pte_t pte)
+	pte_t *ptep)
 {
 	volatile unsigned long *entry1, *entry2;
 	unsigned long pte_data, flags;
@@ -365,7 +365,7 @@ void update_mmu_cache(struct vm_area_str
 
 	vaddr = (vaddr & PAGE_MASK) | get_asid();
 
-	pte_data = pte_val(pte);
+	pte_data = pte_val(*ptep);
 
 #ifdef CONFIG_CHIP_OPSP
 	entry1 = (unsigned long *)ITLB_BASE;
diff -druNp linux-libre-2.6.33-gnu1/arch/m32r/mm/fault-nommu.c linux-libre-2.6.34-gnu1/arch/m32r/mm/fault-nommu.c
--- linux-libre-2.6.33-gnu1/arch/m32r/mm/fault-nommu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m32r/mm/fault-nommu.c	2010-05-16 17:17:36.000000000 -0400
@@ -95,7 +95,7 @@ asmlinkage void do_page_fault(struct pt_
  * update_mmu_cache()
  *======================================================================*/
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
-	pte_t pte)
+	pte_t *ptep)
 {
 	BUG();
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/m32r/mm/init.c linux-libre-2.6.34-gnu1/arch/m32r/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/m32r/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m32r/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/bitops.h>
 #include <linux/nodemask.h>
 #include <linux/pfn.h>
+#include <linux/gfp.h>
 #include <asm/types.h>
 #include <asm/processor.h>
 #include <asm/page.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/amiga/config.c linux-libre-2.6.34-gnu1/arch/m68k/amiga/config.c
--- linux-libre-2.6.33-gnu1/arch/m68k/amiga/config.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/amiga/config.c	2010-05-16 17:17:36.000000000 -0400
@@ -480,7 +480,7 @@ static void __init amiga_sched_init(irq_
 	static struct resource sched_res = {
 		.name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff,
 	};
-	jiffy_ticks = (amiga_eclock+HZ/2)/HZ;
+	jiffy_ticks = DIV_ROUND_CLOSEST(amiga_eclock, HZ);
 
 	if (request_resource(&mb_resources._ciab, &sched_res))
 		printk("Cannot allocate ciab.ta{lo,hi}\n");
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/atari/atakeyb.c linux-libre-2.6.34-gnu1/arch/m68k/atari/atakeyb.c
--- linux-libre-2.6.33-gnu1/arch/m68k/atari/atakeyb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/atari/atakeyb.c	2010-05-16 17:17:36.000000000 -0400
@@ -121,7 +121,7 @@ KEYBOARD_STATE kb_state;
  * bytes have been lost and in which state of the packet structure we are now.
  * This usually causes keyboards bytes to be interpreted as mouse movements
  * and vice versa, which is very annoying. It seems better to throw away some
- * bytes (that are usually mouse bytes) than to misinterpret them. Therefor I
+ * bytes (that are usually mouse bytes) than to misinterpret them. Therefore I
  * introduced the RESYNC state for IKBD data. In this state, the bytes up to
  * one that really looks like a key event (0x04..0xf2) or the start of a mouse
  * packet (0xf8..0xfb) are thrown away, but at most 2 bytes. This at least
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/bvme6000/rtc.c linux-libre-2.6.34-gnu1/arch/m68k/bvme6000/rtc.c
--- linux-libre-2.6.33-gnu1/arch/m68k/bvme6000/rtc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/bvme6000/rtc.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
-#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/ioport.h>
 #include <linux/capability.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/configs/mac_defconfig linux-libre-2.6.34-gnu1/arch/m68k/configs/mac_defconfig
--- linux-libre-2.6.33-gnu1/arch/m68k/configs/mac_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/configs/mac_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -701,6 +701,11 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 #
 # Non-8250 serial port support
 #
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_PMACZILOG=y
+CONFIG_SERIAL_PMACZILOG_TTYS=y
+CONFIG_SERIAL_PMACZILOG_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -834,9 +839,7 @@ CONFIG_HIDRAW=y
 #
 # Character devices
 #
-CONFIG_MAC_SCC=y
 CONFIG_MAC_HID=y
-CONFIG_SERIAL_CONSOLE=y
 
 #
 # File systems
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/configs/multi_defconfig linux-libre-2.6.34-gnu1/arch/m68k/configs/multi_defconfig
--- linux-libre-2.6.33-gnu1/arch/m68k/configs/multi_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/configs/multi_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -822,6 +822,11 @@ CONFIG_A2232=y
 #
 # Non-8250 serial port support
 #
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_PMACZILOG=y
+CONFIG_SERIAL_PMACZILOG_TTYS=y
+CONFIG_SERIAL_PMACZILOG_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -982,7 +987,6 @@ CONFIG_ATARI_MIDI=y
 CONFIG_ATARI_DSP56K=m
 CONFIG_AMIGA_BUILTIN_SERIAL=y
 CONFIG_MULTIFACE_III_TTY=m
-CONFIG_MAC_SCC=y
 CONFIG_MAC_HID=y
 CONFIG_MVME147_SCC=y
 CONFIG_SERIAL167=y
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/atomic_mm.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/atomic_mm.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/atomic_mm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/atomic_mm.h	2010-05-16 17:17:36.000000000 -0400
@@ -148,14 +148,18 @@ static inline int atomic_xchg(atomic_t *
 static inline int atomic_sub_and_test(int i, atomic_t *v)
 {
 	char c;
-	__asm__ __volatile__("subl %2,%1; seq %0" : "=d" (c), "+m" (*v): "g" (i));
+	__asm__ __volatile__("subl %2,%1; seq %0"
+			     : "=d" (c), "+m" (*v)
+			     : "id" (i));
 	return c != 0;
 }
 
 static inline int atomic_add_negative(int i, atomic_t *v)
 {
 	char c;
-	__asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i));
+	__asm__ __volatile__("addl %2,%1; smi %0"
+			     : "=d" (c), "+m" (*v)
+			     : "id" (i));
 	return c != 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/fbio.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/fbio.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/fbio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/fbio.h	2010-05-16 17:17:36.000000000 -0400
@@ -173,7 +173,7 @@ struct mdi_cfginfo {
 	int     mdi_ncluts;     /* Number of implemented CLUTs in this MDI */
         int     mdi_type;       /* FBTYPE name */
         int     mdi_height;     /* height */
-        int     mdi_width;      /* widht */
+        int     mdi_width;      /* width */
         int     mdi_size;       /* available ram */
         int     mdi_mode;       /* 8bpp, 16bpp or 32bpp */
         int     mdi_pixfreq;    /* pixel clock (from PROM) */
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/io_no.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/io_no.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/io_no.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/io_no.h	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,7 @@
  * memory location directly.
  */
 /* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
- * two accesses to memory, which may be undesireable for some devices.
+ * two accesses to memory, which may be undesirable for some devices.
  */
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/machw.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/machw.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/machw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/machw.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,29 +21,4 @@
 #define VIDEOMEMSIZE	(4096*1024)
 #define VIDEOMEMMASK	(-4096*1024)
 
-#ifndef __ASSEMBLY__
-
-#include <linux/types.h>
-
-#if 0
-/*
-** SCC Z8530
-*/
-
-#define MAC_SCC_BAS (0x50F04000)
-struct MAC_SCC
- {
-  u_char cha_a_ctrl;
-  u_char char_dummy1;
-  u_char cha_a_data;
-  u_char char_dummy2;
-  u_char cha_b_ctrl;
-  u_char char_dummy3;
-  u_char cha_b_data;
- };
-# define mac_scc ((*(volatile struct SCC*)MAC_SCC_BAS))
-#endif
-
-#endif /* __ASSEMBLY__ */
-
 #endif /* linux/machw.h */
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/macints.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/macints.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/macints.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/macints.h	2010-05-16 17:17:36.000000000 -0400
@@ -37,7 +37,6 @@
 
 #define VIA1_SOURCE_BASE	8
 #define VIA2_SOURCE_BASE	16
-#define MAC_SCC_SOURCE_BASE	24
 #define PSC3_SOURCE_BASE	24
 #define PSC4_SOURCE_BASE	32
 #define PSC5_SOURCE_BASE	40
@@ -96,26 +95,12 @@
 #define IRQ_PSC3_2	  (26)
 #define IRQ_PSC3_3	  (27)
 
-/* Level 4 (SCC) interrupts */
-#define IRQ_SCC		     (32)
-#define IRQ_SCCA	     (33)
-#define IRQ_SCCB	     (34)
-#if 0 /* FIXME: are there multiple interrupt conditions on the SCC ?? */
-/* SCC interrupts */
-#define IRQ_SCCB_TX	     (32)
-#define IRQ_SCCB_STAT	     (33)
-#define IRQ_SCCB_RX	     (34)
-#define IRQ_SCCB_SPCOND	     (35)
-#define IRQ_SCCA_TX	     (36)
-#define IRQ_SCCA_STAT	     (37)
-#define IRQ_SCCA_RX	     (38)
-#define IRQ_SCCA_SPCOND	     (39)
-#endif
-
 /* Level 4 (PSC, AV Macs only) interrupts */
 #define IRQ_PSC4_0	  (32)
 #define IRQ_PSC4_1	  (33)
+#define IRQ_MAC_SCC_A	  IRQ_PSC4_1
 #define IRQ_PSC4_2	  (34)
+#define IRQ_MAC_SCC_B	  IRQ_PSC4_2
 #define IRQ_PSC4_3	  (35)
 #define IRQ_MAC_MACE_DMA  IRQ_PSC4_3
 
@@ -146,6 +131,9 @@
 #define IRQ_BABOON_2	  (66)
 #define IRQ_BABOON_3	  (67)
 
+/* On non-PSC machines, the serial ports share an IRQ */
+#define IRQ_MAC_SCC	  IRQ_AUTO_4
+
 #define SLOT2IRQ(x)	  (x + 47)
 #define IRQ2SLOT(x)	  (x - 47)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/mcfuart.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/mcfuart.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/mcfuart.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/mcfuart.h	2010-05-16 17:17:36.000000000 -0400
@@ -212,5 +212,10 @@ struct mcf_platform_uart {
 #define	MCFUART_URF_RXS		0xc0		/* Receiver status */
 #endif
 
+#if defined(CONFIG_M5272)
+#define MCFUART_TXFIFOSIZE	25
+#else
+#define MCFUART_TXFIFOSIZE	1
+#endif
 /****************************************************************************/
 #endif	/* mcfuart_h */
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/pgtable_mm.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/pgtable_mm.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/pgtable_mm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/pgtable_mm.h	2010-05-16 17:17:36.000000000 -0400
@@ -115,7 +115,7 @@ extern void kernel_set_cachemode(void *a
  * they are updated on demand.
  */
 static inline void update_mmu_cache(struct vm_area_struct *vma,
-				    unsigned long address, pte_t pte)
+				    unsigned long address, pte_t *ptep)
 {
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -71,6 +71,8 @@ struct switch_stack {
 #define PTRACE_GETFPREGS          14
 #define PTRACE_SETFPREGS          15
 
+#define PTRACE_GET_THREAD_AREA    25
+
 #define PTRACE_SINGLEBLOCK	33	/* resume execution until next branch */
 
 #ifdef __KERNEL__
@@ -85,18 +87,10 @@ struct switch_stack {
 #define profile_pc(regs) instruction_pointer(regs)
 extern void show_regs(struct pt_regs *);
 
-/*
- * These are defined as per linux/ptrace.h.
- */
-struct task_struct;
-
 #define arch_has_single_step()	(1)
-extern void user_enable_single_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
 
 #ifdef CONFIG_MMU
 #define arch_has_block_step()	(1)
-extern void user_enable_block_step(struct task_struct *);
 #endif
 
 #endif /* __KERNEL__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/sigcontext.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/sigcontext.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/sigcontext.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/sigcontext.h	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,11 @@ struct sigcontext {
 	unsigned long  sc_pc;
 	unsigned short sc_formatvec;
 #ifndef __uClinux__
+# ifdef __mcoldfire__
+	unsigned long  sc_fpregs[2][2];	/* room for two fp registers */
+# else
 	unsigned long  sc_fpregs[2*3];  /* room for two fp registers */
+# endif
 	unsigned long  sc_fpcntl[3];
 	unsigned char  sc_fpstate[216];
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/siginfo.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/siginfo.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/siginfo.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/siginfo.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,97 +1,6 @@
 #ifndef _M68K_SIGINFO_H
 #define _M68K_SIGINFO_H
 
-#ifndef __uClinux__
-#define HAVE_ARCH_SIGINFO_T
-#define HAVE_ARCH_COPY_SIGINFO
-#endif
-
 #include <asm-generic/siginfo.h>
 
-#ifndef __uClinux__
-
-typedef struct siginfo {
-	int si_signo;
-	int si_errno;
-	int si_code;
-
-	union {
-		int _pad[SI_PAD_SIZE];
-
-		/* kill() */
-		struct {
-			__kernel_pid_t _pid;	/* sender's pid */
-			__kernel_uid_t _uid;	/* backwards compatibility */
-			__kernel_uid32_t _uid32; /* sender's uid */
-		} _kill;
-
-		/* POSIX.1b timers */
-		struct {
-			timer_t _tid;		/* timer id */
-			int _overrun;		/* overrun count */
-			char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
-			sigval_t _sigval;	/* same as below */
-			int _sys_private;       /* not to be passed to user */
-		} _timer;
-
-		/* POSIX.1b signals */
-		struct {
-			__kernel_pid_t _pid;	/* sender's pid */
-			__kernel_uid_t _uid;	/* backwards compatibility */
-			sigval_t _sigval;
-			__kernel_uid32_t _uid32; /* sender's uid */
-		} _rt;
-
-		/* SIGCHLD */
-		struct {
-			__kernel_pid_t _pid;	/* which child */
-			__kernel_uid_t _uid;	/* backwards compatibility */
-			int _status;		/* exit code */
-			clock_t _utime;
-			clock_t _stime;
-			__kernel_uid32_t _uid32; /* sender's uid */
-		} _sigchld;
-
-		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
-		struct {
-			void *_addr; /* faulting insn/memory ref. */
-		} _sigfault;
-
-		/* SIGPOLL */
-		struct {
-			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
-			int _fd;
-		} _sigpoll;
-	} _sifields;
-} siginfo_t;
-
-#define UID16_SIGINFO_COMPAT_NEEDED
-
-/*
- * How these fields are to be accessed.
- */
-#undef si_uid
-#ifdef __KERNEL__
-#define si_uid		_sifields._kill._uid32
-#define si_uid16	_sifields._kill._uid
-#else
-#define si_uid		_sifields._kill._uid
-#endif
-
-#ifdef __KERNEL__
-
-#include <linux/string.h>
-
-static inline void copy_siginfo(struct siginfo *to, struct siginfo *from)
-{
-	if (from->si_code < 0)
-		memcpy(to, from, sizeof(*to));
-	else
-		/* _sigchld is currently the largest know union member */
-		memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
-}
-
-#endif /* __KERNEL__ */
-#endif /* !__uClinux__ */
-
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/swab.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/swab.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/swab.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/swab.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,7 @@ static inline __attribute_const__ __u32
 }
 
 #define __arch_swab32 __arch_swab32
-#elif !defined(__uClinux__)
+#elif !defined(__mcoldfire__)
 
 static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/thread_info_mm.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/thread_info_mm.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/thread_info_mm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/thread_info_mm.h	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@ struct thread_info {
 	struct exec_domain	*exec_domain;	/* execution domain */
 	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
 	__u32 cpu; /* should always be 0 on m68k */
+	unsigned long		tp_value;	/* thread pointer */
 	struct restart_block    restart_block;
 };
 #endif /* __ASSEMBLY__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/thread_info_no.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/thread_info_no.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/thread_info_no.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/thread_info_no.h	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@ struct thread_info {
 	unsigned long	   flags;		/* low level flags */
 	int		   cpu;			/* cpu we're on */
 	int		   preempt_count;	/* 0 => preemptable, <0 => BUG */
+	unsigned long	   tp_value;		/* thread pointer */
 	struct restart_block restart_block;
 };
 
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/ucontext.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/ucontext.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/ucontext.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/ucontext.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,11 @@ typedef greg_t gregset_t[NGREG];
 
 typedef struct fpregset {
 	int f_fpcntl[3];
+#ifdef __mcoldfire__
+	int f_fpregs[8][2];
+#else
 	int f_fpregs[8*3];
+#endif
 } fpregset_t;
 
 struct mcontext {
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/unistd.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/unistd.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/unistd.h	2010-05-16 17:17:36.000000000 -0400
@@ -336,10 +336,14 @@
 #define __NR_pwritev		330
 #define __NR_rt_tgsigqueueinfo	331
 #define __NR_perf_event_open	332
+#define __NR_get_thread_area	333
+#define __NR_set_thread_area	334
+#define __NR_atomic_cmpxchg_32	335
+#define __NR_atomic_barrier	336
 
 #ifdef __KERNEL__
 
-#define NR_syscalls		333
+#define NR_syscalls		337
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
@@ -347,6 +351,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
@@ -359,6 +364,8 @@
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_MMAP
+#define __ARCH_WANT_SYS_OLD_SELECT
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/include/asm/virtconvert.h linux-libre-2.6.34-gnu1/arch/m68k/include/asm/virtconvert.h
--- linux-libre-2.6.33-gnu1/arch/m68k/include/asm/virtconvert.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/include/asm/virtconvert.h	2010-05-16 17:17:36.000000000 -0400
@@ -31,12 +31,7 @@ static inline void *phys_to_virt(unsigne
 #define page_to_phys(page) \
 	__pa(PAGE_OFFSET + (((page) - pg_data_map[0].node_mem_map) << PAGE_SHIFT))
 #else
-#define page_to_phys(_page) ({						\
-	struct page *__page = _page;					\
-	struct pglist_data *pgdat;					\
-	pgdat = pg_data_table[page_to_nid(__page)];			\
-	page_to_pfn(__page) << PAGE_SHIFT;				\
-})
+#define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
 #endif
 #else
 #define page_to_phys(page)	(((page) - mem_map) << PAGE_SHIFT)
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/Kconfig linux-libre-2.6.34-gnu1/arch/m68k/Kconfig
--- linux-libre-2.6.33-gnu1/arch/m68k/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -536,10 +536,6 @@ config GVPIOEXT_PLIP
 	  Say Y to enable doing IP over the parallel port on your GVP
 	  IO-Extender card, N otherwise.
 
-config MAC_SCC
-	tristate "Macintosh serial support"
-	depends on MAC
-
 config MAC_HID
 	bool
 	depends on INPUT_ADBHID
@@ -595,7 +591,7 @@ config DN_SERIAL
 
 config SERIAL_CONSOLE
 	bool "Support for serial port console"
-	depends on (AMIGA || ATARI || MAC || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || MAC_SCC=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL)
+	depends on (AMIGA || ATARI || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL)
 	---help---
 	  If you say Y here, it will be possible to use a serial port as the
 	  system console (the system console is the device which receives all
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/kernel/dma.c linux-libre-2.6.34-gnu1/arch/m68k/kernel/dma.c
--- linux-libre-2.6.33-gnu1/arch/m68k/kernel/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/kernel/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include <asm/pgalloc.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/kernel/entry.S linux-libre-2.6.34-gnu1/arch/m68k/kernel/entry.S
--- linux-libre-2.6.33-gnu1/arch/m68k/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/kernel/entry.S	2010-05-16 17:17:36.000000000 -0400
@@ -510,7 +510,7 @@ sys_call_table:
 	.long sys_settimeofday
 	.long sys_getgroups16	/* 80 */
 	.long sys_setgroups16
-	.long old_select
+	.long sys_old_select
 	.long sys_symlink
 	.long sys_lstat
 	.long sys_readlink	/* 85 */
@@ -518,7 +518,7 @@ sys_call_table:
 	.long sys_swapon
 	.long sys_reboot
 	.long sys_old_readdir
-	.long old_mmap		/* 90 */
+	.long sys_old_mmap	/* 90 */
 	.long sys_munmap
 	.long sys_truncate
 	.long sys_ftruncate
@@ -761,4 +761,8 @@ sys_call_table:
 	.long sys_pwritev		/* 330 */
 	.long sys_rt_tgsigqueueinfo
 	.long sys_perf_event_open
+	.long sys_get_thread_area
+	.long sys_set_thread_area
+	.long sys_atomic_cmpxchg_32	/* 335 */
+	.long sys_atomic_barrier
 
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/kernel/process.c linux-libre-2.6.34-gnu1/arch/m68k/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/m68k/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,13 +15,13 @@
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/reboot.h>
 #include <linux/init_task.h>
@@ -251,6 +251,10 @@ int copy_thread(unsigned long clone_flag
 
 	p->thread.usp = usp;
 	p->thread.ksp = (unsigned long)childstack;
+
+	if (clone_flags & CLONE_SETTLS)
+		task_thread_info(p)->tp_value = regs->d5;
+
 	/*
 	 * Must save the current SFC/DFC value, NOT the value when
 	 * the parent was last descheduled - RGH  10-08-96
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/m68k/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/m68k/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -245,6 +245,11 @@ long arch_ptrace(struct task_struct *chi
 			ret = -EFAULT;
 		break;
 
+	case PTRACE_GET_THREAD_AREA:
+		ret = put_user(task_thread_info(child)->tp_value,
+			       (unsigned long __user *)data);
+		break;
+
 	default:
 		ret = ptrace_request(child, request, addr, data);
 		break;
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/kernel/signal.c linux-libre-2.6.34-gnu1/arch/m68k/kernel/signal.c
--- linux-libre-2.6.33-gnu1/arch/m68k/kernel/signal.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/kernel/signal.c	2010-05-16 17:17:36.000000000 -0400
@@ -897,10 +897,17 @@ static void setup_rt_frame (int sig, str
 
 	/* Set up to return from userspace.  */
 	err |= __put_user(frame->retcode, &frame->pretcode);
+#ifdef __mcoldfire__
+	/* movel #__NR_rt_sigreturn,d0; trap #0 */
+	err |= __put_user(0x203c0000, (long __user *)(frame->retcode + 0));
+	err |= __put_user(0x00004e40 + (__NR_rt_sigreturn << 16),
+			  (long __user *)(frame->retcode + 4));
+#else
 	/* moveq #,d0; notb d0; trap #0 */
 	err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
 			  (long __user *)(frame->retcode + 0));
 	err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4));
+#endif
 
 	if (err)
 		goto give_sigsegv;
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/kernel/sys_m68k.c linux-libre-2.6.34-gnu1/arch/m68k/kernel/sys_m68k.c
--- linux-libre-2.6.33-gnu1/arch/m68k/kernel/sys_m68k.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/kernel/sys_m68k.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,11 @@
 #include <asm/traps.h>
 #include <asm/page.h>
 #include <asm/unistd.h>
+#include <linux/elf.h>
+#include <asm/tlb.h>
+
+asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
+			     unsigned long error_code);
 
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags,
@@ -41,137 +46,6 @@ asmlinkage long sys_mmap2(unsigned long
 	return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
 }
 
-/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
- * handle more than 4 system call parameters, so these system calls
- * used a memory block for parameter passing..
- */
-
-struct mmap_arg_struct {
-	unsigned long addr;
-	unsigned long len;
-	unsigned long prot;
-	unsigned long flags;
-	unsigned long fd;
-	unsigned long offset;
-};
-
-asmlinkage int old_mmap(struct mmap_arg_struct __user *arg)
-{
-	struct mmap_arg_struct a;
-	int error = -EFAULT;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		goto out;
-
-	error = -EINVAL;
-	if (a.offset & ~PAGE_MASK)
-		goto out;
-
-	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
-			       a.offset >> PAGE_SHIFT);
-out:
-	return error;
-}
-
-struct sel_arg_struct {
-	unsigned long n;
-	fd_set __user *inp, *outp, *exp;
-	struct timeval __user *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct __user *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	/* sys_select() does the appropriate kernel locking */
-	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage int sys_ipc (uint call, int first, int second,
-			int third, void __user *ptr, long fifth)
-{
-	int version, ret;
-
-	version = call >> 16; /* hack for backward compatibility */
-	call &= 0xffff;
-
-	if (call <= SEMCTL)
-		switch (call) {
-		case SEMOP:
-			return sys_semop (first, ptr, second);
-		case SEMGET:
-			return sys_semget (first, second, third);
-		case SEMCTL: {
-			union semun fourth;
-			if (!ptr)
-				return -EINVAL;
-			if (get_user(fourth.__pad, (void __user *__user *) ptr))
-				return -EFAULT;
-			return sys_semctl (first, second, third, fourth);
-			}
-		default:
-			return -ENOSYS;
-		}
-	if (call <= MSGCTL)
-		switch (call) {
-		case MSGSND:
-			return sys_msgsnd (first, ptr, second, third);
-		case MSGRCV:
-			switch (version) {
-			case 0: {
-				struct ipc_kludge tmp;
-				if (!ptr)
-					return -EINVAL;
-				if (copy_from_user (&tmp, ptr, sizeof (tmp)))
-					return -EFAULT;
-				return sys_msgrcv (first, tmp.msgp, second,
-						   tmp.msgtyp, third);
-				}
-			default:
-				return sys_msgrcv (first, ptr,
-						   second, fifth, third);
-			}
-		case MSGGET:
-			return sys_msgget ((key_t) first, second);
-		case MSGCTL:
-			return sys_msgctl (first, second, ptr);
-		default:
-			return -ENOSYS;
-		}
-	if (call <= SHMCTL)
-		switch (call) {
-		case SHMAT:
-			switch (version) {
-			default: {
-				ulong raddr;
-				ret = do_shmat (first, ptr, second, &raddr);
-				if (ret)
-					return ret;
-				return put_user (raddr, (ulong __user *) third);
-			}
-			}
-		case SHMDT:
-			return sys_shmdt (ptr);
-		case SHMGET:
-			return sys_shmget (first, second, third);
-		case SHMCTL:
-			return sys_shmctl (first, second, ptr);
-		default:
-			return -ENOSYS;
-		}
-
-	return -EINVAL;
-}
-
 /* Convert virtual (user) address VADDR to physical address PADDR */
 #define virt_to_phys_040(vaddr)						\
 ({									\
@@ -595,3 +469,79 @@ int kernel_execve(const char *filename,
 			: "d" (__a), "d" (__b), "d" (__c));
 	return __res;
 }
+
+asmlinkage unsigned long sys_get_thread_area(void)
+{
+	return current_thread_info()->tp_value;
+}
+
+asmlinkage int sys_set_thread_area(unsigned long tp)
+{
+	current_thread_info()->tp_value = tp;
+	return 0;
+}
+
+/* This syscall gets its arguments in A0 (mem), D2 (oldval) and
+   D1 (newval).  */
+asmlinkage int
+sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
+		      unsigned long __user * mem)
+{
+	/* This was borrowed from ARM's implementation.  */
+	for (;;) {
+		struct mm_struct *mm = current->mm;
+		pgd_t *pgd;
+		pmd_t *pmd;
+		pte_t *pte;
+		spinlock_t *ptl;
+		unsigned long mem_value;
+
+		down_read(&mm->mmap_sem);
+		pgd = pgd_offset(mm, (unsigned long)mem);
+		if (!pgd_present(*pgd))
+			goto bad_access;
+		pmd = pmd_offset(pgd, (unsigned long)mem);
+		if (!pmd_present(*pmd))
+			goto bad_access;
+		pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl);
+		if (!pte_present(*pte) || !pte_dirty(*pte)
+		    || !pte_write(*pte)) {
+			pte_unmap_unlock(pte, ptl);
+			goto bad_access;
+		}
+
+		mem_value = *mem;
+		if (mem_value == oldval)
+			*mem = newval;
+
+		pte_unmap_unlock(pte, ptl);
+		up_read(&mm->mmap_sem);
+		return mem_value;
+
+	      bad_access:
+		up_read(&mm->mmap_sem);
+		/* This is not necessarily a bad access, we can get here if
+		   a memory we're trying to write to should be copied-on-write.
+		   Make the kernel do the necessary page stuff, then re-iterate.
+		   Simulate a write access fault to do that.  */
+		{
+			/* The first argument of the function corresponds to
+			   D1, which is the first field of struct pt_regs.  */
+			struct pt_regs *fp = (struct pt_regs *)&newval;
+
+			/* '3' is an RMW flag.  */
+			if (do_page_fault(fp, (unsigned long)mem, 3))
+				/* If the do_page_fault() failed, we don't
+				   have anything meaningful to return.
+				   There should be a SIGSEGV pending for
+				   the process.  */
+				return 0xdeadbeef;
+		}
+	}
+}
+
+asmlinkage int sys_atomic_barrier(void)
+{
+	/* no code needed for uniprocs */
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/mac/config.c linux-libre-2.6.34-gnu1/arch/m68k/mac/config.c
--- linux-libre-2.6.33-gnu1/arch/m68k/mac/config.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/mac/config.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,8 @@
 #include <linux/init.h>
 #include <linux/vt_kern.h>
 #include <linux/platform_device.h>
+#include <linux/adb.h>
+#include <linux/cuda.h>
 
 #define BOOTINFO_COMPAT_1_0
 #include <asm/setup.h>
@@ -44,12 +46,7 @@
 #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;
 
 /* The phys. video addr. - might be bogus on some machines */
@@ -70,8 +67,6 @@ extern void baboon_init(void);
 
 extern void mac_mksound(unsigned int, unsigned int);
 
-extern void nubus_sweep_video(void);
-
 static void mac_get_model(char *str);
 static void mac_identify(void);
 static void mac_report_hardware(void);
@@ -168,12 +163,6 @@ void __init config_mac(void)
 #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
 	mach_beep = mac_mksound;
 #endif
-#ifdef CONFIG_HEARTBEAT
-#if 0
-	mach_heartbeat = mac_heartbeat;
-	mach_heartbeat_irq = IRQ_MAC_TIMER;
-#endif
-#endif
 
 	/*
 	 * Determine hardware present
@@ -191,27 +180,19 @@ void __init config_mac(void)
 	if (macintosh_config->ident == MAC_MODEL_IICI
 	    || macintosh_config->ident == MAC_MODEL_IIFX)
 		mach_l2_flush = mac_cache_card_flush;
-
-	/*
-	 * Check for machine specific fixups.
-	 */
-
-#ifdef OLD_NUBUS_CODE
-	nubus_sweep_video();
-#endif
 }
 
 
 /*
- *	Macintosh Table: hardcoded model configuration data.
+ * Macintosh Table: hardcoded model configuration data.
  *
- *	Much of this was defined by Alan, based on who knows what docs.
- *	I've added a lot more, and some of that was pure guesswork based
- *	on hardware pages present on the Mac web site. Possibly wildly
- *	inaccurate, so look here if a new Mac model won't run. Example: if
- *	a Mac crashes immediately after the VIA1 registers have been dumped
- *	to the screen, it probably died attempting to read DirB on a RBV.
- *	Meaning it should have MAC_VIA_IIci here :-)
+ * Much of this was defined by Alan, based on who knows what docs.
+ * I've added a lot more, and some of that was pure guesswork based
+ * on hardware pages present on the Mac web site. Possibly wildly
+ * inaccurate, so look here if a new Mac model won't run. Example: if
+ * a Mac crashes immediately after the VIA1 registers have been dumped
+ * to the screen, it probably died attempting to read DirB on a RBV.
+ * Meaning it should have MAC_VIA_IIci here :-)
  */
 
 struct mac_model *macintosh_config;
@@ -219,7 +200,7 @@ EXPORT_SYMBOL(macintosh_config);
 
 static struct mac_model mac_data_table[] = {
 	/*
-	 *	We'll pretend to be a Macintosh II, that's pretty safe.
+	 * We'll pretend to be a Macintosh II, that's pretty safe.
 	 */
 
 	{
@@ -230,12 +211,11 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type	= MAC_FLOPPY_IWM
+		.floppy_type	= MAC_FLOPPY_IWM,
 	},
 
 	/*
-	 *	Original MacII hardware
-	 *
+	 * Original Mac II hardware
 	 */
 
 	{
@@ -246,7 +226,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type	= MAC_FLOPPY_IWM
+		.floppy_type	= MAC_FLOPPY_IWM,
 	}, {
 		.ident		= MAC_MODEL_IIX,
 		.name		= "IIx",
@@ -255,7 +235,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_IICX,
 		.name		= "IIcx",
@@ -264,7 +244,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_SE30,
 		.name		= "SE/30",
@@ -273,13 +253,13 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	},
 
 	/*
-	 *	Weirdified MacII hardware - all subtly different. Gee thanks
-	 *	Apple. All these boxes seem to have VIA2 in a different place to
-	 *	the MacII (+1A000 rather than +4000)
+	 * Weirdified Mac II hardware - all subtly different. Gee thanks
+	 * Apple. All these boxes seem to have VIA2 in a different place to
+	 * the Mac II (+1A000 rather than +4000)
 	 * CSA: see http://developer.apple.com/technotes/hw/hw_09.html
 	 */
 
@@ -291,7 +271,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_IIFX,
 		.name		= "IIfx",
@@ -300,7 +280,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_IOP,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_IOP
+		.floppy_type	= MAC_FLOPPY_SWIM_IOP,
 	}, {
 		.ident		= MAC_MODEL_IISI,
 		.name		= "IIsi",
@@ -309,7 +289,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_IIVI,
 		.name		= "IIvi",
@@ -318,7 +298,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_IIVX,
 		.name		= "IIvx",
@@ -327,11 +307,11 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	},
 
 	/*
-	 *	Classic models (guessing: similar to SE/30 ?? Nope, similar to LC ...)
+	 * Classic models (guessing: similar to SE/30? Nope, similar to LC...)
 	 */
 
 	{
@@ -342,7 +322,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_CCL,
 		.name		= "Color Classic",
@@ -351,11 +331,11 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	},
 
 	/*
-	 *	Some Mac LC machines. Basically the same as the IIci, ADB like IIsi
+	 * Some Mac LC machines. Basically the same as the IIci, ADB like IIsi
 	 */
 
 	{
@@ -366,7 +346,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_LCII,
 		.name		= "LC II",
@@ -375,7 +355,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_LCIII,
 		.name		= "LC III",
@@ -384,17 +364,17 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	},
 
 	/*
-	 *	Quadra. Video is at 0xF9000000, via is like a MacII. We label it differently
-	 *	as some of the stuff connected to VIA2 seems different. Better SCSI chip and
-	 *	onboard ethernet using a NatSemi SONIC except the 660AV and 840AV which use an
-	 *	AMD 79C940 (MACE).
-	 *	The 700, 900 and 950 have some I/O chips in the wrong place to
-	 *	confuse us. The 840AV has a SCSI location of its own (same as
-	 *	the 660AV).
+	 * Quadra. Video is at 0xF9000000, via is like a MacII. We label it
+	 * differently as some of the stuff connected to VIA2 seems different.
+	 * Better SCSI chip and onboard ethernet using a NatSemi SONIC except
+	 * the 660AV and 840AV which use an AMD 79C940 (MACE).
+	 * The 700, 900 and 950 have some I/O chips in the wrong place to
+	 * confuse us. The 840AV has a SCSI location of its own (same as
+	 * the 660AV).
 	 */
 
 	{
@@ -405,7 +385,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_QUADRA,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1,
 	}, {
 		.ident		= MAC_MODEL_Q605_ACC,
 		.name		= "Quadra 605",
@@ -414,7 +394,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_QUADRA,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1,
 	}, {
 		.ident		= MAC_MODEL_Q610,
 		.name		= "Quadra 610",
@@ -424,7 +404,7 @@ static struct mac_model mac_data_table[]
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1,
 	}, {
 		.ident		= MAC_MODEL_Q630,
 		.name		= "Quadra 630",
@@ -435,7 +415,7 @@ static struct mac_model mac_data_table[]
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1,
 	}, {
 		.ident		= MAC_MODEL_Q650,
 		.name		= "Quadra 650",
@@ -445,9 +425,9 @@ static struct mac_model mac_data_table[]
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1,
 	},
-	/*	The Q700 does have a NS Sonic */
+	/* The Q700 does have a NS Sonic */
 	{
 		.ident		= MAC_MODEL_Q700,
 		.name		= "Quadra 700",
@@ -457,7 +437,7 @@ static struct mac_model mac_data_table[]
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1,
 	}, {
 		.ident		= MAC_MODEL_Q800,
 		.name		= "Quadra 800",
@@ -467,7 +447,7 @@ static struct mac_model mac_data_table[]
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1,
 	}, {
 		.ident		= MAC_MODEL_Q840,
 		.name		= "Quadra 840AV",
@@ -477,7 +457,7 @@ static struct mac_model mac_data_table[]
 		.scc_type	= MAC_SCC_PSC,
 		.ether_type	= MAC_ETHER_MACE,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_AV
+		.floppy_type	= MAC_FLOPPY_AV,
 	}, {
 		.ident		= MAC_MODEL_Q900,
 		.name		= "Quadra 900",
@@ -487,7 +467,7 @@ static struct mac_model mac_data_table[]
 		.scc_type	= MAC_SCC_IOP,
 		.ether_type	= MAC_ETHER_SONIC,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_IOP
+		.floppy_type	= MAC_FLOPPY_SWIM_IOP,
 	}, {
 		.ident		= MAC_MODEL_Q950,
 		.name		= "Quadra 950",
@@ -497,60 +477,60 @@ static struct mac_model mac_data_table[]
 		.scc_type	= MAC_SCC_IOP,
 		.ether_type	= MAC_ETHER_SONIC,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_IOP
+		.floppy_type	= MAC_FLOPPY_SWIM_IOP,
 	},
 
 	/*
-	 *	Performa - more LC type machines
+	 * Performa - more LC type machines
 	 */
 
 	{
 		.ident		= MAC_MODEL_P460,
-		.name		=  "Performa 460",
+		.name		= "Performa 460",
 		.adb_type	= MAC_ADB_IISI,
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_P475,
-		.name		=  "Performa 475",
+		.name		= "Performa 475",
 		.adb_type	= MAC_ADB_CUDA,
 		.via_type	= MAC_VIA_QUADRA,
 		.scsi_type	= MAC_SCSI_QUADRA,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1,
 	}, {
 		.ident		= MAC_MODEL_P475F,
-		.name		=  "Performa 475",
+		.name		= "Performa 475",
 		.adb_type	= MAC_ADB_CUDA,
 		.via_type	= MAC_VIA_QUADRA,
 		.scsi_type	= MAC_SCSI_QUADRA,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1,
 	}, {
 		.ident		= MAC_MODEL_P520,
-		.name		=  "Performa 520",
+		.name		= "Performa 520",
 		.adb_type	= MAC_ADB_CUDA,
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_P550,
-		.name		=  "Performa 550",
+		.name		= "Performa 550",
 		.adb_type	= MAC_ADB_CUDA,
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	},
-	/* These have the comm slot, and therefore the possibility of SONIC ethernet */
+	/* These have the comm slot, and therefore possibly SONIC ethernet */
 	{
 		.ident		= MAC_MODEL_P575,
 		.name		= "Performa 575",
@@ -560,7 +540,7 @@ static struct mac_model mac_data_table[]
 		.scc_type	= MAC_SCC_II,
 		.ether_type	= MAC_ETHER_SONIC,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1,
 	}, {
 		.ident		= MAC_MODEL_P588,
 		.name		= "Performa 588",
@@ -571,7 +551,7 @@ static struct mac_model mac_data_table[]
 		.scc_type	= MAC_SCC_II,
 		.ether_type	= MAC_ETHER_SONIC,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1,
 	}, {
 		.ident		= MAC_MODEL_TV,
 		.name		= "TV",
@@ -580,7 +560,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_P600,
 		.name		= "Performa 600",
@@ -589,14 +569,14 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	},
 
 	/*
-	 *	Centris - just guessing again; maybe like Quadra
+	 * Centris - just guessing again; maybe like Quadra.
+	 * The C610 may or may not have SONIC. We probe to make sure.
 	 */
 
-	/* The C610 may or may not have SONIC.  We probe to make sure */
 	{
 		.ident		= MAC_MODEL_C610,
 		.name		= "Centris 610",
@@ -606,7 +586,7 @@ static struct mac_model mac_data_table[]
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR1
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1,
 	}, {
 		.ident		= MAC_MODEL_C650,
 		.name		= "Centris 650",
@@ -616,7 +596,7 @@ static struct mac_model mac_data_table[]
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR1
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1,
 	}, {
 		.ident		= MAC_MODEL_C660,
 		.name		= "Centris 660AV",
@@ -626,7 +606,7 @@ static struct mac_model mac_data_table[]
 		.scc_type	= MAC_SCC_PSC,
 		.ether_type	= MAC_ETHER_MACE,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_AV
+		.floppy_type	= MAC_FLOPPY_AV,
 	},
 
 	/*
@@ -643,7 +623,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_PB145,
 		.name		= "PowerBook 145",
@@ -652,7 +632,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_PB150,
 		.name		= "PowerBook 150",
@@ -662,7 +642,7 @@ static struct mac_model mac_data_table[]
 		.ide_type	= MAC_IDE_PB,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_PB160,
 		.name		= "PowerBook 160",
@@ -671,7 +651,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_PB165,
 		.name		= "PowerBook 165",
@@ -680,7 +660,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_PB165C,
 		.name		= "PowerBook 165c",
@@ -689,7 +669,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_PB170,
 		.name		= "PowerBook 170",
@@ -698,7 +678,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_PB180,
 		.name		= "PowerBook 180",
@@ -707,7 +687,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_PB180C,
 		.name		= "PowerBook 180c",
@@ -716,7 +696,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_PB190,
 		.name		= "PowerBook 190",
@@ -726,7 +706,7 @@ static struct mac_model mac_data_table[]
 		.ide_type	= MAC_IDE_BABOON,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_PB520,
 		.name		= "PowerBook 520",
@@ -736,7 +716,7 @@ static struct mac_model mac_data_table[]
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	},
 
 	/*
@@ -757,7 +737,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_PB230,
 		.name		= "PowerBook Duo 230",
@@ -766,7 +746,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_PB250,
 		.name		= "PowerBook Duo 250",
@@ -775,7 +755,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_PB270C,
 		.name		= "PowerBook Duo 270c",
@@ -784,7 +764,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_PB280,
 		.name		= "PowerBook Duo 280",
@@ -793,7 +773,7 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	}, {
 		.ident		= MAC_MODEL_PB280C,
 		.name		= "PowerBook Duo 280c",
@@ -802,17 +782,44 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
 		.nubus_type	= MAC_NUBUS,
-		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2,
 	},
 
 	/*
-	 *	Other stuff ??
+	 * Other stuff?
 	 */
+
 	{
 		.ident		= -1
 	}
 };
 
+static struct resource scc_a_rsrcs[] = {
+	{ .flags = IORESOURCE_MEM },
+	{ .flags = IORESOURCE_IRQ },
+};
+
+static struct resource scc_b_rsrcs[] = {
+	{ .flags = IORESOURCE_MEM },
+	{ .flags = IORESOURCE_IRQ },
+};
+
+struct platform_device scc_a_pdev = {
+	.name           = "scc",
+	.id             = 0,
+	.num_resources  = ARRAY_SIZE(scc_a_rsrcs),
+	.resource       = scc_a_rsrcs,
+};
+EXPORT_SYMBOL(scc_a_pdev);
+
+struct platform_device scc_b_pdev = {
+	.name           = "scc",
+	.id             = 1,
+	.num_resources  = ARRAY_SIZE(scc_b_rsrcs),
+	.resource       = scc_b_rsrcs,
+};
+EXPORT_SYMBOL(scc_b_pdev);
+
 static void __init mac_identify(void)
 {
 	struct mac_model *m;
@@ -823,7 +830,8 @@ static void __init mac_identify(void)
 		/* no bootinfo model id -> NetBSD booter was used! */
 		/* XXX FIXME: breaks for model > 31 */
 		model = (mac_bi_data.cpuid >> 2) & 63;
-		printk(KERN_WARNING "No bootinfo model ID, using cpuid instead (hey, use Penguin!)\n");
+		printk(KERN_WARNING "No bootinfo model ID, using cpuid instead "
+		       "(obsolete bootloader?)\n");
 	}
 
 	macintosh_config = mac_data_table;
@@ -834,10 +842,29 @@ static void __init mac_identify(void)
 		}
 	}
 
-	/* We need to pre-init the IOPs, if any. Otherwise */
-	/* the serial console won't work if the user had   */
-	/* the serial ports set to "Faster" mode in MacOS. */
+	/* Set up serial port resources for the console initcall. */
+
+	scc_a_rsrcs[0].start = (resource_size_t) mac_bi_data.sccbase + 2;
+	scc_a_rsrcs[0].end   = scc_a_rsrcs[0].start;
+	scc_b_rsrcs[0].start = (resource_size_t) mac_bi_data.sccbase;
+	scc_b_rsrcs[0].end   = scc_b_rsrcs[0].start;
 
+	switch (macintosh_config->scc_type) {
+	case MAC_SCC_PSC:
+		scc_a_rsrcs[1].start = scc_a_rsrcs[1].end = IRQ_MAC_SCC_A;
+		scc_b_rsrcs[1].start = scc_b_rsrcs[1].end = IRQ_MAC_SCC_B;
+		break;
+	default:
+		scc_a_rsrcs[1].start = scc_a_rsrcs[1].end = IRQ_MAC_SCC;
+		scc_b_rsrcs[1].start = scc_b_rsrcs[1].end = IRQ_MAC_SCC;
+		break;
+	}
+
+	/*
+	 * We need to pre-init the IOPs, if any. Otherwise
+	 * the serial console won't work if the user had
+	 * the serial ports set to "Faster" mode in MacOS.
+	 */
 	iop_preinit();
 
 	printk(KERN_INFO "Detected Macintosh model: %d \n", model);
@@ -846,7 +873,8 @@ static void __init mac_identify(void)
 	 * Report booter data:
 	 */
 	printk(KERN_DEBUG " Penguin bootinfo data:\n");
-	printk(KERN_DEBUG " Video: addr 0x%lx row 0x%lx depth %lx dimensions %ld x %ld\n",
+	printk(KERN_DEBUG " Video: addr 0x%lx "
+		"row 0x%lx depth %lx dimensions %ld x %ld\n",
 		mac_bi_data.videoaddr, mac_bi_data.videorow,
 		mac_bi_data.videodepth, mac_bi_data.dimensions & 0xFFFF,
 		mac_bi_data.dimensions >> 16);
@@ -863,6 +891,10 @@ static void __init mac_identify(void)
 	oss_init();
 	psc_init();
 	baboon_init();
+
+#ifdef CONFIG_ADB_CUDA
+	find_via_cuda();
+#endif
 }
 
 static void __init mac_report_hardware(void)
@@ -876,23 +908,50 @@ static void mac_get_model(char *str)
 	strcat(str, macintosh_config->name);
 }
 
-static struct resource swim_resources[1];
+static struct resource swim_rsrc = { .flags = IORESOURCE_MEM };
 
-static struct platform_device swim_device = {
+static struct platform_device swim_pdev = {
 	.name		= "swim",
 	.id		= -1,
-	.num_resources	= ARRAY_SIZE(swim_resources),
-	.resource	= swim_resources,
+	.num_resources	= 1,
+	.resource	= &swim_rsrc,
 };
 
-static struct platform_device *mac_platform_devices[] __initdata = {
-	&swim_device
+static struct platform_device esp_0_pdev = {
+	.name		= "mac_esp",
+	.id		= 0,
+};
+
+static struct platform_device esp_1_pdev = {
+	.name		= "mac_esp",
+	.id		= 1,
+};
+
+static struct platform_device sonic_pdev = {
+	.name		= "macsonic",
+	.id		= -1,
+};
+
+static struct platform_device mace_pdev = {
+	.name		= "macmace",
+	.id		= -1,
 };
 
 int __init mac_platform_init(void)
 {
 	u8 *swim_base;
 
+	/*
+	 * Serial devices
+	 */
+
+	platform_device_register(&scc_a_pdev);
+	platform_device_register(&scc_b_pdev);
+
+	/*
+	 * Floppy device
+	 */
+
 	switch (macintosh_config->floppy_type) {
 	case MAC_FLOPPY_SWIM_ADDR1:
 		swim_base = (u8 *)(VIA1_BASE + 0x1E000);
@@ -901,16 +960,47 @@ int __init mac_platform_init(void)
 		swim_base = (u8 *)(VIA1_BASE + 0x16000);
 		break;
 	default:
-		return 0;
+		swim_base = NULL;
+		break;
 	}
 
-	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;
+	if (swim_base) {
+		swim_rsrc.start = (resource_size_t) swim_base,
+		swim_rsrc.end   = (resource_size_t) swim_base + 0x2000,
+		platform_device_register(&swim_pdev);
+	}
 
-	return platform_add_devices(mac_platform_devices,
-				    ARRAY_SIZE(mac_platform_devices));
+	/*
+	 * SCSI device(s)
+	 */
+
+	switch (macintosh_config->scsi_type) {
+	case MAC_SCSI_QUADRA:
+	case MAC_SCSI_QUADRA3:
+		platform_device_register(&esp_0_pdev);
+		break;
+	case MAC_SCSI_QUADRA2:
+		platform_device_register(&esp_0_pdev);
+		if ((macintosh_config->ident == MAC_MODEL_Q900) ||
+		    (macintosh_config->ident == MAC_MODEL_Q950))
+			platform_device_register(&esp_1_pdev);
+		break;
+	}
+
+	/*
+	 * Ethernet device
+	 */
+
+	switch (macintosh_config->ether_type) {
+	case MAC_ETHER_SONIC:
+		platform_device_register(&sonic_pdev);
+		break;
+	case MAC_ETHER_MACE:
+		platform_device_register(&mace_pdev);
+		break;
+	}
+
+	return 0;
 }
 
 arch_initcall(mac_platform_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/mac/debug.c linux-libre-2.6.34-gnu1/arch/m68k/mac/debug.c
--- linux-libre-2.6.33-gnu1/arch/m68k/mac/debug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/mac/debug.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,365 +0,0 @@
-/*
- * linux/arch/m68k/mac/debug.c
- *
- * Shamelessly stolen (SCC code and general framework) from:
- *
- * linux/arch/m68k/atari/debug.c
- *
- * Atari debugging and serial console stuff
- *
- * Assembled of parts of former atari/config.c 97-12-18 by Roman Hodek
- *
- * 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/types.h>
-#include <linux/sched.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#define BOOTINFO_COMPAT_1_0
-#include <asm/setup.h>
-#include <asm/bootinfo.h>
-#include <asm/macints.h>
-
-extern unsigned long mac_videobase;
-extern unsigned long mac_rowbytes;
-
-extern void mac_serial_print(const char *);
-
-#define DEBUG_HEADS
-#undef DEBUG_SCREEN
-#define DEBUG_SERIAL
-
-/*
- * These two auxiliary debug functions should go away ASAP. Only usage:
- * before the console output is up (after head.S come some other crucial
- * setup routines :-) it permits writing 'data' to the screen as bit patterns
- * (good luck reading those). Helped to figure that the bootinfo contained
- * garbage data on the amount and size of memory chunks ...
- *
- * The 'pos' argument now simply means 'linefeed after print' ...
- */
-
-#ifdef DEBUG_SCREEN
-static int peng, line;
-#endif
-
-#if 0
-
-void mac_debugging_short(int pos, short num)
-{
-#ifdef DEBUG_SCREEN
-	unsigned char *pengoffset;
-	unsigned char *pptr;
-	int i;
-#endif
-
-#ifdef DEBUG_SERIAL
-	printk("debug: %d !\n", num);
-#endif
-
-#ifdef DEBUG_SCREEN
-	if (!MACH_IS_MAC) {
-		/* printk("debug: %d !\n", num); */
-		return;
-	}
-
-	/* calculate current offset */
-	pengoffset = (unsigned char *)mac_videobase +
-		(150+line*2) * mac_rowbytes + 80 * peng;
-
-	pptr = pengoffset;
-
-	for (i = 0; i < 8 * sizeof(short); i++) { /* # of bits */
-		/*        value        mask for bit i, reverse order */
-		*pptr++ = (num & (1 << (8*sizeof(short)-i-1)) ? 0xFF : 0x00);
-	}
-
-	peng++;
-
-	if (pos) {
-		line++;
-		peng = 0;
-	}
-#endif
-}
-
-void mac_debugging_long(int pos, long addr)
-{
-#ifdef DEBUG_SCREEN
-	unsigned char *pengoffset;
-	unsigned char *pptr;
-	int i;
-#endif
-
-#ifdef DEBUG_SERIAL
-	printk("debug: #%ld !\n", addr);
-#endif
-
-#ifdef DEBUG_SCREEN
-	if (!MACH_IS_MAC) {
-		/* printk("debug: #%ld !\n", addr); */
-		return;
-	}
-
-	pengoffset=(unsigned char *)(mac_videobase+(150+line*2)*mac_rowbytes)
-		    +80*peng;
-
-	pptr = pengoffset;
-
-	for (i = 0; i < 8 * sizeof(long); i++) { /* # of bits */
-		*pptr++ = (addr & (1 << (8*sizeof(long)-i-1)) ? 0xFF : 0x00);
-	}
-
-	peng++;
-
-	if (pos) {
-		line++;
-		peng = 0;
-	}
-#endif
-}
-
-#endif  /*  0  */
-
-#ifdef DEBUG_SERIAL
-/*
- * TODO: serial debug code
- */
-
-struct mac_SCC {
-	u_char cha_b_ctrl;
-	u_char char_dummy1;
-	u_char cha_a_ctrl;
-	u_char char_dummy2;
-	u_char cha_b_data;
-	u_char char_dummy3;
-	u_char cha_a_data;
-};
-
-# define scc (*((volatile struct mac_SCC*)mac_bi_data.sccbase))
-
-static int scc_port = -1;
-
-static struct console mac_console_driver = {
-	.name	= "debug",
-	.flags	= CON_PRINTBUFFER,
-	.index	= -1,
-};
-
-/*
- * Crude hack to get console output to the screen before the framebuffer
- * is initialized (happens a lot later in 2.1!).
- * We just use the console routines declared in head.S, this will interfere
- * with regular framebuffer console output and should be used exclusively
- * to debug kernel problems manifesting before framebuffer init (aka WSOD)
- *
- * To keep this hack from interfering with the regular console driver, either
- * deregister this driver before/on framebuffer console init, or silence this
- * function after the fbcon driver is running (will lose console messages!?).
- * To debug real early bugs, need to write a 'mac_register_console_hack()'
- * that is called from start_kernel() before setup_arch() and just registers
- * this driver if Mac.
- */
-
-static void mac_debug_console_write(struct console *co, const char *str,
-				    unsigned int count)
-{
-	mac_serial_print(str);
-}
-
-
-
-/* Mac: loops_per_jiffy min. 19000 ^= .5 us; MFPDELAY was 0.6 us*/
-
-#define uSEC 1
-
-static inline void mac_sccb_out(char c)
-{
-	int i;
-
-	do {
-		for (i = uSEC; i > 0; --i)
-			barrier();
-	} while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */
-	for (i = uSEC; i > 0; --i)
-		barrier();
-	scc.cha_b_data = c;
-}
-
-static inline void mac_scca_out(char c)
-{
-	int i;
-
-	do {
-		for (i = uSEC; i > 0; --i)
-			barrier();
-	} while (!(scc.cha_a_ctrl & 0x04)); /* wait for tx buf empty */
-	for (i = uSEC; i > 0; --i)
-		barrier();
-	scc.cha_a_data = c;
-}
-
-static void mac_sccb_console_write(struct console *co, const char *str,
-				   unsigned int count)
-{
-	while (count--) {
-		if (*str == '\n')
-			mac_sccb_out('\r');
-		mac_sccb_out(*str++);
-	}
-}
-
-static void mac_scca_console_write(struct console *co, const char *str,
-				   unsigned int count)
-{
-	while (count--) {
-		if (*str == '\n')
-			mac_scca_out('\r');
-		mac_scca_out(*str++);
-	}
-}
-
-
-/* The following two functions do a quick'n'dirty initialization of the MFP or
- * SCC serial ports. They're used by the debugging interface, kgdb, and the
- * serial console code. */
-#define SCCB_WRITE(reg,val)				\
-	do {						\
-		int i;					\
-		scc.cha_b_ctrl = (reg);			\
-		for (i = uSEC; i > 0; --i)		\
-			barrier();			\
-		scc.cha_b_ctrl = (val);			\
-		for (i = uSEC; i > 0; --i)		\
-			barrier();			\
-	} while(0)
-
-#define SCCA_WRITE(reg,val)				\
-	do {						\
-		int i;					\
-		scc.cha_a_ctrl = (reg);			\
-		for (i = uSEC; i > 0; --i)		\
-			barrier();			\
-		scc.cha_a_ctrl = (val);			\
-		for (i = uSEC; i > 0; --i)		\
-			barrier();			\
-	} while(0)
-
-/* loops_per_jiffy isn't initialized yet, so we can't use udelay(). This does a
- * delay of ~ 60us. */
-/* Mac: loops_per_jiffy min. 19000 ^= .5 us; MFPDELAY was 0.6 us*/
-#define LONG_DELAY()					\
-	do {						\
-		int i;					\
-		for (i = 60*uSEC; i > 0; --i)		\
-		    barrier();				\
-	} while(0)
-
-static void __init mac_init_scc_port(int cflag, int port)
-{
-	/*
-	 * baud rates: 1200, 1800, 2400, 4800, 9600, 19.2k, 38.4k, 57.6k, 115.2k
-	 */
-
-	static int clksrc_table[9] =
-		/* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */
-		{ 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 };
-	static int clkmode_table[9] =
-		/* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */
-		{ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 };
-	static int div_table[9] =
-		/* reg12 (BRG low) */
-		{ 94, 62, 46, 22, 10, 4, 1, 0, 0 };
-
-	int baud = cflag & CBAUD;
-	int clksrc, clkmode, div, reg3, reg5;
-
-	if (cflag & CBAUDEX)
-		baud += B38400;
-	if (baud < B1200 || baud > B38400+2)
-		baud = B9600; /* use default 9600bps for non-implemented rates */
-	baud -= B1200; /* tables starts at 1200bps */
-
-	clksrc  = clksrc_table[baud];
-	clkmode = clkmode_table[baud];
-	div     = div_table[baud];
-
-	reg3 = (((cflag & CSIZE) == CS8) ? 0xc0 : 0x40);
-	reg5 = (((cflag & CSIZE) == CS8) ? 0x60 : 0x20) | 0x82 /* assert DTR/RTS */;
-
-	if (port == 1) {
-		(void)scc.cha_b_ctrl;	/* reset reg pointer */
-		SCCB_WRITE(9, 0xc0);	/* reset */
-		LONG_DELAY();		/* extra delay after WR9 access */
-		SCCB_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 |
-			   0x04 /* 1 stopbit */ |
-			   clkmode);
-		SCCB_WRITE(3, reg3);
-		SCCB_WRITE(5, reg5);
-		SCCB_WRITE(9, 0);	/* no interrupts */
-		LONG_DELAY();		/* extra delay after WR9 access */
-		SCCB_WRITE(10, 0);	/* NRZ mode */
-		SCCB_WRITE(11, clksrc);	/* main clock source */
-		SCCB_WRITE(12, div);	/* BRG value */
-		SCCB_WRITE(13, 0);	/* BRG high byte */
-		SCCB_WRITE(14, 1);
-		SCCB_WRITE(3, reg3 | 1);
-		SCCB_WRITE(5, reg5 | 8);
-	} else if (port == 0) {
-		(void)scc.cha_a_ctrl;	/* reset reg pointer */
-		SCCA_WRITE(9, 0xc0);	/* reset */
-		LONG_DELAY();		/* extra delay after WR9 access */
-		SCCA_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 |
-			  0x04 /* 1 stopbit */ |
-			  clkmode);
-		SCCA_WRITE(3, reg3);
-		SCCA_WRITE(5, reg5);
-		SCCA_WRITE(9, 0);	/* no interrupts */
-		LONG_DELAY();		/* extra delay after WR9 access */
-		SCCA_WRITE(10, 0);	/* NRZ mode */
-		SCCA_WRITE(11, clksrc);	/* main clock source */
-		SCCA_WRITE(12, div);	/* BRG value */
-		SCCA_WRITE(13, 0);	/* BRG high byte */
-		SCCA_WRITE(14, 1);
-		SCCA_WRITE(3, reg3 | 1);
-		SCCA_WRITE(5, reg5 | 8);
-	}
-}
-#endif /* DEBUG_SERIAL */
-
-static int __init mac_debug_setup(char *arg)
-{
-	if (!MACH_IS_MAC)
-		return 0;
-
-#ifdef DEBUG_SERIAL
-	if (!strcmp(arg, "ser") || !strcmp(arg, "ser1")) {
-		/* Mac modem port */
-		mac_init_scc_port(B9600|CS8, 0);
-		mac_console_driver.write = mac_scca_console_write;
-		scc_port = 0;
-	} else if (!strcmp(arg, "ser2")) {
-		/* Mac printer port */
-		mac_init_scc_port(B9600|CS8, 1);
-		mac_console_driver.write = mac_sccb_console_write;
-		scc_port = 1;
-	}
-#endif
-#ifdef DEBUG_HEADS
-	if (!strcmp(arg, "scn") || !strcmp(arg, "con")) {
-		/* display, using head.S console routines */
-		mac_console_driver.write = mac_debug_console_write;
-	}
-#endif
-	if (mac_console_driver.write)
-		register_console(&mac_console_driver);
-	return 0;
-}
-
-early_param("debug", mac_debug_setup);
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/mac/macints.c linux-libre-2.6.34-gnu1/arch/m68k/mac/macints.c
--- linux-libre-2.6.33-gnu1/arch/m68k/mac/macints.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/mac/macints.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,9 +34,7 @@
  *
  *	3	- unused (?)
  *
- *	4	- SCC (slot number determined by reading RR3 on the SSC itself)
- *		  - slot 1: SCC channel A
- *		  - slot 2: SCC channel B
+ *	4	- SCC
  *
  *	5	- unused (?)
  *		  [serial errors or special conditions seem to raise level 6
@@ -55,8 +53,6 @@
  *		  - slot 5: Slot $E
  *
  *	4	- SCC IOP
- *		  - slot 1: SCC channel A
- *		  - slot 2: SCC channel B
  *
  *	5	- ISM IOP (ADB?)
  *
@@ -136,13 +132,8 @@
 #include <asm/irq_regs.h>
 #include <asm/mac_oss.h>
 
-#define DEBUG_SPURIOUS
 #define SHUTUP_SONIC
 
-/* SCC interrupt mask */
-
-static int scc_mask;
-
 /*
  * VIA/RBV hooks
  */
@@ -191,13 +182,6 @@ extern void baboon_irq_disable(int);
 extern void baboon_irq_clear(int);
 
 /*
- * SCC interrupt routines
- */
-
-static void scc_irq_enable(unsigned int);
-static void scc_irq_disable(unsigned int);
-
-/*
  * console_loglevel determines NMI handler function
  */
 
@@ -221,8 +205,6 @@ void __init mac_init_IRQ(void)
 #ifdef DEBUG_MACINTS
 	printk("mac_init_IRQ(): Setting things up...\n");
 #endif
-	scc_mask = 0;
-
 	m68k_setup_irq_controller(&mac_irq_controller, IRQ_USER,
 				  NUM_MAC_SOURCES - IRQ_USER);
 	/* Make sure the SONIC interrupt is cleared or things get ugly */
@@ -283,15 +265,16 @@ void mac_enable_irq(unsigned int irq)
 			via_irq_enable(irq);
 		break;
 	case 3:
-	case 4:
 	case 5:
 	case 6:
 		if (psc_present)
 			psc_irq_enable(irq);
 		else if (oss_present)
 			oss_irq_enable(irq);
-		else if (irq_src == 4)
-			scc_irq_enable(irq);
+		break;
+	case 4:
+		if (psc_present)
+			psc_irq_enable(irq);
 		break;
 	case 8:
 		if (baboon_present)
@@ -316,15 +299,16 @@ void mac_disable_irq(unsigned int irq)
 			via_irq_disable(irq);
 		break;
 	case 3:
-	case 4:
 	case 5:
 	case 6:
 		if (psc_present)
 			psc_irq_disable(irq);
 		else if (oss_present)
 			oss_irq_disable(irq);
-		else if (irq_src == 4)
-			scc_irq_disable(irq);
+		break;
+	case 4:
+		if (psc_present)
+			psc_irq_disable(irq);
 		break;
 	case 8:
 		if (baboon_present)
@@ -347,7 +331,6 @@ void mac_clear_irq(unsigned int irq)
 			via_irq_clear(irq);
 		break;
 	case 3:
-	case 4:
 	case 5:
 	case 6:
 		if (psc_present)
@@ -355,6 +338,10 @@ void mac_clear_irq(unsigned int irq)
 		else if (oss_present)
 			oss_irq_clear(irq);
 		break;
+	case 4:
+		if (psc_present)
+			psc_irq_clear(irq);
+		break;
 	case 8:
 		if (baboon_present)
 			baboon_irq_clear(irq);
@@ -374,13 +361,17 @@ int mac_irq_pending(unsigned int irq)
 		else
 			return via_irq_pending(irq);
 	case 3:
-	case 4:
 	case 5:
 	case 6:
 		if (psc_present)
 			return psc_irq_pending(irq);
 		else if (oss_present)
 			return oss_irq_pending(irq);
+		break;
+	case 4:
+		if (psc_present)
+			psc_irq_pending(irq);
+		break;
 	}
 	return 0;
 }
@@ -448,59 +439,3 @@ irqreturn_t mac_nmi_handler(int irq, voi
 	in_nmi--;
 	return IRQ_HANDLED;
 }
-
-/*
- * Simple routines for masking and unmasking
- * SCC interrupts in cases where this can't be
- * done in hardware (only the PSC can do that.)
- */
-
-static void scc_irq_enable(unsigned int irq)
-{
-	int irq_idx = IRQ_IDX(irq);
-
-	scc_mask |= (1 << irq_idx);
-}
-
-static void scc_irq_disable(unsigned int irq)
-{
-	int irq_idx = IRQ_IDX(irq);
-
-	scc_mask &= ~(1 << irq_idx);
-}
-
-/*
- * SCC master interrupt handler. We have to do a bit of magic here
- * to figure out what channel gave us the interrupt; putting this
- * here is cleaner than hacking it into drivers/char/macserial.c.
- */
-
-void mac_scc_dispatch(int irq, void *dev_id)
-{
-	volatile unsigned char *scc = (unsigned char *) mac_bi_data.sccbase + 2;
-	unsigned char reg;
-	unsigned long flags;
-
-	/* Read RR3 from the chip. Always do this on channel A */
-	/* This must be an atomic operation so disable irqs.   */
-
-	local_irq_save(flags);
-	*scc = 3;
-	reg = *scc;
-	local_irq_restore(flags);
-
-	/* Now dispatch. Bits 0-2 are for channel B and */
-	/* bits 3-5 are for channel A. We can safely    */
-	/* ignore the remaining bits here.              */
-	/*                                              */
-	/* Note that we're ignoring scc_mask for now.   */
-	/* If we actually mask the ints then we tend to */
-	/* get hammered by very persistent SCC irqs,    */
-	/* and since they're autovector interrupts they */
-	/* pretty much kill the system.                 */
-
-	if (reg & 0x38)
-		m68k_handle_int(IRQ_SCCA);
-	if (reg & 0x07)
-		m68k_handle_int(IRQ_SCCB);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/mac/Makefile linux-libre-2.6.34-gnu1/arch/m68k/mac/Makefile
--- linux-libre-2.6.33-gnu1/arch/m68k/mac/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/mac/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -3,4 +3,4 @@
 #
 
 obj-y		:= config.o macints.o iop.o via.o oss.o psc.o \
-			baboon.o macboing.o debug.o misc.o
+			baboon.o macboing.o misc.o
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/mac/misc.c linux-libre-2.6.34-gnu1/arch/m68k/mac/misc.c
--- linux-libre-2.6.33-gnu1/arch/m68k/mac/misc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/mac/misc.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,6 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/rtc.h>
 #include <linux/mm.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/mac/oss.c linux-libre-2.6.34-gnu1/arch/m68k/mac/oss.c
--- linux-libre-2.6.33-gnu1/arch/m68k/mac/oss.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/mac/oss.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,6 @@ static irqreturn_t oss_irq(int, void *);
 static irqreturn_t oss_nubus_irq(int, void *);
 
 extern irqreturn_t via1_irq(int, void *);
-extern irqreturn_t mac_scc_dispatch(int, void *);
 
 /*
  * Initialize the OSS
@@ -69,9 +68,6 @@ void __init oss_register_interrupts(void
 	if (request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK,
 			"scsi", (void *) oss))
 		pr_err("Couldn't register %s interrupt\n", "scsi");
-	if (request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK,
-			"scc", mac_scc_dispatch))
-		pr_err("Couldn't register %s interrupt\n", "scc");
 	if (request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK,
 			"nubus", (void *) oss))
 		pr_err("Couldn't register %s interrupt\n", "nubus");
@@ -172,9 +168,7 @@ void oss_irq_enable(int irq) {
 	printk("oss_irq_enable(%d)\n", irq);
 #endif
 	switch(irq) {
-		case IRQ_SCC:
-		case IRQ_SCCA:
-		case IRQ_SCCB:
+		case IRQ_MAC_SCC:
 			oss->irq_level[OSS_IOPSCC] = OSS_IRQLEV_IOPSCC;
 			break;
 		case IRQ_MAC_ADB:
@@ -212,9 +206,7 @@ void oss_irq_disable(int irq) {
 	printk("oss_irq_disable(%d)\n", irq);
 #endif
 	switch(irq) {
-		case IRQ_SCC:
-		case IRQ_SCCA:
-		case IRQ_SCCB:
+		case IRQ_MAC_SCC:
 			oss->irq_level[OSS_IOPSCC] = OSS_IRQLEV_DISABLED;
 			break;
 		case IRQ_MAC_ADB:
@@ -250,9 +242,7 @@ void oss_irq_disable(int irq) {
 void oss_irq_clear(int irq) {
 	/* FIXME: how to do this on OSS? */
 	switch(irq) {
-		case IRQ_SCC:
-		case IRQ_SCCA:
-		case IRQ_SCCB:
+		case IRQ_MAC_SCC:
 			oss->irq_pending &= ~OSS_IP_IOPSCC;
 			break;
 		case IRQ_MAC_ADB:
@@ -280,9 +270,7 @@ void oss_irq_clear(int irq) {
 int oss_irq_pending(int irq)
 {
 	switch(irq) {
-		case IRQ_SCC:
-		case IRQ_SCCA:
-		case IRQ_SCCB:
+		case IRQ_MAC_SCC:
 			return oss->irq_pending & OSS_IP_IOPSCC;
 			break;
 		case IRQ_MAC_ADB:
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/mac/via.c linux-libre-2.6.34-gnu1/arch/m68k/mac/via.c
--- linux-libre-2.6.33-gnu1/arch/m68k/mac/via.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/mac/via.c	2010-05-16 17:17:36.000000000 -0400
@@ -84,8 +84,6 @@ void via_irq_enable(int irq);
 void via_irq_disable(int irq);
 void via_irq_clear(int irq);
 
-extern irqreturn_t mac_scc_dispatch(int, void *);
-
 /*
  * Initialize the VIAs
  *
@@ -311,11 +309,6 @@ void __init via_register_interrupts(void
 	if (request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
 			"via2", (void *) via2))
 		pr_err("Couldn't register %s interrupt\n", "via2");
-	if (!psc_present) {
-		if (request_irq(IRQ_AUTO_4, mac_scc_dispatch, IRQ_FLG_LOCK,
-				"scc", mac_scc_dispatch))
-			pr_err("Couldn't register %s interrupt\n", "scc");
-	}
 	if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq,
 			IRQ_FLG_LOCK|IRQ_FLG_FAST, "nubus", (void *) via2))
 		pr_err("Couldn't register %s interrupt\n", "nubus");
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/mm/init.c linux-libre-2.6.34-gnu1/arch/m68k/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/m68k/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 
 #include <asm/setup.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/mm/kmap.c linux-libre-2.6.34-gnu1/arch/m68k/mm/kmap.c
--- linux-libre-2.6.33-gnu1/arch/m68k/mm/kmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/mm/kmap.c	2010-05-16 17:17:36.000000000 -0400
@@ -99,8 +99,7 @@ static inline void free_io_area(void *ad
 #endif
 
 /*
- * Map some physical address range into the kernel address space. The
- * code is copied and adapted from map_chunk().
+ * Map some physical address range into the kernel address space.
  */
 /* Rewritten by Andreas Schwab to remove all races. */
 
@@ -116,7 +115,7 @@ void __iomem *__ioremap(unsigned long ph
 	/*
 	 * Don't allow mappings that wrap..
 	 */
-	if (!size || size > physaddr + size)
+	if (!size || physaddr > (unsigned long)(-size))
 		return NULL;
 
 #ifdef CONFIG_AMIGA
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/mm/memory.c linux-libre-2.6.34-gnu1/arch/m68k/mm/memory.c
--- linux-libre-2.6.33-gnu1/arch/m68k/mm/memory.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/mm/memory.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,9 +9,9 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/pagemap.h>
+#include <linux/gfp.h>
 
 #include <asm/setup.h>
 #include <asm/segment.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/mm/motorola.c linux-libre-2.6.34-gnu1/arch/m68k/mm/motorola.c
--- linux-libre-2.6.33-gnu1/arch/m68k/mm/motorola.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/mm/motorola.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 
 #include <asm/setup.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/mvme16x/rtc.c linux-libre-2.6.34-gnu1/arch/m68k/mvme16x/rtc.c
--- linux-libre-2.6.33-gnu1/arch/m68k/mvme16x/rtc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/mvme16x/rtc.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
-#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/ioport.h>
 #include <linux/capability.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/sun3/sun3dvma.c linux-libre-2.6.34-gnu1/arch/m68k/sun3/sun3dvma.c
--- linux-libre-2.6.33-gnu1/arch/m68k/sun3/sun3dvma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/sun3/sun3dvma.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/m68k/sun3x/dvma.c linux-libre-2.6.34-gnu1/arch/m68k/sun3x/dvma.c
--- linux-libre-2.6.33-gnu1/arch/m68k/sun3x/dvma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68k/sun3x/dvma.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/bitops.h>
 #include <linux/mm.h>
 #include <linux/bootmem.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include <asm/sun3x.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/dma.c linux-libre-2.6.34-gnu1/arch/m68knommu/kernel/dma.c
--- linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68knommu/kernel/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/entry.S linux-libre-2.6.34-gnu1/arch/m68knommu/kernel/entry.S
--- linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68knommu/kernel/entry.S	2010-05-16 17:17:36.000000000 -0400
@@ -145,6 +145,6 @@ ENTRY(ret_from_user_signal)
 	trap #0
 
 ENTRY(ret_from_user_rt_signal)
-	move #__NR_rt_sigreturn,%d0
+	movel #__NR_rt_sigreturn,%d0
 	trap #0
 
diff -druNp linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/process.c linux-libre-2.6.34-gnu1/arch/m68knommu/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68knommu/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,11 +23,11 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/interrupt.h>
 #include <linux/reboot.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -221,6 +221,10 @@ int copy_thread(unsigned long clone_flag
 
 	p->thread.usp = usp;
 	p->thread.ksp = (unsigned long)childstack;
+
+	if (clone_flags & CLONE_SETTLS)
+		task_thread_info(p)->tp_value = regs->d5;
+
 	/*
 	 * Must save the current SFC/DFC value, NOT the value when
 	 * the parent was last descheduled - RGH  10-08-96
diff -druNp linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/m68knommu/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68knommu/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -116,12 +116,6 @@ long arch_ptrace(struct task_struct *chi
 	int ret;
 
 	switch (request) {
-		/* when I and D space are separate, these will need to be fixed. */
-		case PTRACE_PEEKTEXT: /* read word at location addr. */ 
-		case PTRACE_PEEKDATA:
-			ret = generic_ptrace_peekdata(child, addr, data);
-			break;
-
 		/* read the word at location addr in the USER area. */
 		case PTRACE_PEEKUSR: {
 			unsigned long tmp;
@@ -160,12 +154,6 @@ long arch_ptrace(struct task_struct *chi
 			break;
 		}
 
-		/* when I and D space are separate, this will have to be fixed. */
-		case PTRACE_POKETEXT: /* write the word at location addr. */
-		case PTRACE_POKEDATA:
-			ret = generic_ptrace_pokedata(child, addr, data);
-			break;
-
 		case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
 			ret = -EIO;
 			if ((addr & 3) || addr < 0 ||
@@ -202,66 +190,6 @@ long arch_ptrace(struct task_struct *chi
 			}
 			break;
 
-		case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
-		case PTRACE_CONT: { /* restart after signal. */
-			long tmp;
-
-			ret = -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;
-			/* make sure the single step bit is not set. */
-			tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
-			put_reg(child, PT_SR, tmp);
-			wake_up_process(child);
-			ret = 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: {
-			long tmp;
-
-			ret = 0;
-			if (child->exit_state == EXIT_ZOMBIE) /* already dead */
-				break;
-			child->exit_code = SIGKILL;
-			/* make sure the single step bit is not set. */
-			tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
-			put_reg(child, PT_SR, tmp);
-			wake_up_process(child);
-			break;
-		}
-
-		case PTRACE_SINGLESTEP: {  /* set the trap flag. */
-			long tmp;
-
-			ret = -EIO;
-			if (!valid_signal(data))
-				break;
-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-			tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
-			put_reg(child, PT_SR, tmp);
-
-			child->exit_code = data;
-			/* give it a chance to run. */
-			wake_up_process(child);
-			ret = 0;
-			break;
-		}
-
-		case PTRACE_DETACH:	/* detach a process that was attached. */
-			ret = ptrace_detach(child, data);
-			break;
-
 		case PTRACE_GETREGS: { /* Get all gp regs from the child. */
 		  	int i;
 			unsigned long tmp;
@@ -319,8 +247,13 @@ long arch_ptrace(struct task_struct *chi
 		}
 #endif
 
+	case PTRACE_GET_THREAD_AREA:
+		ret = put_user(task_thread_info(child)->tp_value,
+			       (unsigned long __user *)data);
+		break;
+
 		default:
-			ret = -EIO;
+			ret = ptrace_request(child, request, addr, data);
 			break;
 	}
 	return ret;
diff -druNp linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/syscalltable.S linux-libre-2.6.34-gnu1/arch/m68knommu/kernel/syscalltable.S
--- linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/syscalltable.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68knommu/kernel/syscalltable.S	2010-05-16 17:17:36.000000000 -0400
@@ -100,7 +100,7 @@ ENTRY(sys_call_table)
 	.long sys_settimeofday
 	.long sys_getgroups16	/* 80 */
 	.long sys_setgroups16
-	.long old_select
+	.long sys_old_select
 	.long sys_symlink
 	.long sys_lstat
 	.long sys_readlink	/* 85 */
@@ -108,7 +108,7 @@ ENTRY(sys_call_table)
 	.long sys_ni_syscall	/* sys_swapon */
 	.long sys_reboot
 	.long sys_old_readdir
-	.long old_mmap		/* 90 */
+	.long sys_old_mmap	/* 90 */
 	.long sys_munmap
 	.long sys_truncate
 	.long sys_ftruncate
@@ -351,6 +351,10 @@ ENTRY(sys_call_table)
 	.long sys_pwritev		/* 330 */
 	.long sys_rt_tgsigqueueinfo
 	.long sys_perf_event_open
+	.long sys_get_thread_area
+	.long sys_set_thread_area
+	.long sys_atomic_cmpxchg_32	/* 335 */
+	.long sys_atomic_barrier
 
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long sys_ni_syscall
diff -druNp linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/sys_m68k.c linux-libre-2.6.34-gnu1/arch/m68knommu/kernel/sys_m68k.c
--- linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/sys_m68k.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68knommu/kernel/sys_m68k.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,142 +27,6 @@
 #include <asm/cacheflush.h>
 #include <asm/unistd.h>
 
-/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
- * handle more than 4 system call parameters, so these system calls
- * used a memory block for parameter passing..
- */
-
-struct mmap_arg_struct {
-	unsigned long addr;
-	unsigned long len;
-	unsigned long prot;
-	unsigned long flags;
-	unsigned long fd;
-	unsigned long offset;
-};
-
-asmlinkage int old_mmap(struct mmap_arg_struct *arg)
-{
-	struct mmap_arg_struct a;
-	int error = -EFAULT;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		goto out;
-
-	error = -EINVAL;
-	if (a.offset & ~PAGE_MASK)
-		goto out;
-
-	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
-				a.offset >> PAGE_SHIFT);
-out:
-	return error;
-}
-
-struct sel_arg_struct {
-	unsigned long n;
-	fd_set *inp, *outp, *exp;
-	struct timeval *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	/* sys_select() does the appropriate kernel locking */
-	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-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;
-
-	if (call <= SEMCTL)
-		switch (call) {
-		case SEMOP:
-			return sys_semop (first, (struct sembuf *)ptr, second);
-		case SEMGET:
-			return sys_semget (first, second, third);
-		case SEMCTL: {
-			union semun fourth;
-			if (!ptr)
-				return -EINVAL;
-			if (get_user(fourth.__pad, (void **) ptr))
-				return -EFAULT;
-			return sys_semctl (first, second, third, fourth);
-			}
-		default:
-			return -EINVAL;
-		}
-	if (call <= MSGCTL) 
-		switch (call) {
-		case MSGSND:
-			return sys_msgsnd (first, (struct msgbuf *) ptr, 
-					  second, third);
-		case MSGRCV:
-			switch (version) {
-			case 0: {
-				struct ipc_kludge tmp;
-				if (!ptr)
-					return -EINVAL;
-				if (copy_from_user (&tmp,
-						    (struct ipc_kludge *)ptr,
-						    sizeof (tmp)))
-					return -EFAULT;
-				return sys_msgrcv (first, tmp.msgp, second,
-						   tmp.msgtyp, third);
-				}
-			default:
-				return sys_msgrcv (first,
-						   (struct msgbuf *) ptr,
-						   second, fifth, third);
-			}
-		case MSGGET:
-			return sys_msgget ((key_t) first, second);
-		case MSGCTL:
-			return sys_msgctl (first, second,
-					   (struct msqid_ds *) ptr);
-		default:
-			return -EINVAL;
-		}
-	if (call <= SHMCTL)
-		switch (call) {
-		case SHMAT:
-			switch (version) {
-			default: {
-				ulong raddr;
-				ret = do_shmat (first, ptr, second, &raddr);
-				if (ret)
-					return ret;
-				return put_user (raddr, (ulong __user *) third);
-			}
-			}
-		case SHMDT:
-			return sys_shmdt (ptr);
-		case SHMGET:
-			return sys_shmget (first, second, third);
-		case SHMCTL:
-			return sys_shmctl (first, second, ptr);
-		default:
-			return -ENOSYS;
-		}
-
-	return -EINVAL;
-}
-
 /* sys_cacheflush -- flush (part of) the processor cache.  */
 asmlinkage int
 sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
@@ -190,3 +54,39 @@ int kernel_execve(const char *filename,
 			: "d" (__a), "d" (__b), "d" (__c));
 	return __res;
 }
+
+asmlinkage unsigned long sys_get_thread_area(void)
+{
+	return current_thread_info()->tp_value;
+}
+
+asmlinkage int sys_set_thread_area(unsigned long tp)
+{
+	current_thread_info()->tp_value = tp;
+	return 0;
+}
+
+/* This syscall gets its arguments in A0 (mem), D2 (oldval) and
+   D1 (newval).  */
+asmlinkage int
+sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
+		      unsigned long __user * mem)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long mem_value;
+
+	down_read(&mm->mmap_sem);
+
+	mem_value = *mem;
+	if (mem_value == oldval)
+		*mem = newval;
+
+	up_read(&mm->mmap_sem);
+	return mem_value;
+}
+
+asmlinkage int sys_atomic_barrier(void)
+{
+	/* no code needed for uniprocs */
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/m68knommu/Makefile linux-libre-2.6.34-gnu1/arch/m68knommu/Makefile
--- linux-libre-2.6.33-gnu1/arch/m68knommu/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68knommu/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -94,7 +94,7 @@ cflags-$(CONFIG_M520x)		:= $(call cc-opt
 cflags-$(CONFIG_M523x)		:= $(call cc-option,-mcpu=523x,-m5307)
 cflags-$(CONFIG_M5249)		:= $(call cc-option,-mcpu=5249,-m5200)
 cflags-$(CONFIG_M5271)		:= $(call cc-option,-mcpu=5271,-m5307)
-cflags-$(CONFIG_M5272)		:= $(call cc-option,-mcpu=5271,-m5200)
+cflags-$(CONFIG_M5272)		:= $(call cc-option,-mcpu=5272,-m5307)
 cflags-$(CONFIG_M5275)		:= $(call cc-option,-mcpu=5275,-m5307)
 cflags-$(CONFIG_M528x)		:= $(call cc-option,-m528x,-m5307)
 cflags-$(CONFIG_M5307)		:= $(call cc-option,-m5307,-m5200)
diff -druNp linux-libre-2.6.33-gnu1/arch/m68knommu/mm/init.c linux-libre-2.6.34-gnu1/arch/m68knommu/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/m68knommu/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68knommu/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,7 +29,7 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/bootmem.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 
 #include <asm/setup.h>
 #include <asm/segment.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/m68knommu/mm/kmap.c linux-libre-2.6.34-gnu1/arch/m68knommu/mm/kmap.c
--- linux-libre-2.6.33-gnu1/arch/m68knommu/mm/kmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68knommu/mm/kmap.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include <asm/setup.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/m68knommu/mm/memory.c linux-libre-2.6.34-gnu1/arch/m68knommu/mm/memory.c
--- linux-libre-2.6.33-gnu1/arch/m68knommu/mm/memory.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68knommu/mm/memory.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 
 #include <asm/segment.h>
 #include <asm/page.h>
@@ -24,7 +23,6 @@
 
 /*
  * Map some physical address range into the kernel address space.
- * The code is copied and adapted from map_chunk().
  */
 
 unsigned long kernel_map(unsigned long paddr, unsigned long size,
diff -druNp linux-libre-2.6.33-gnu1/arch/m68knommu/platform/68360/ints.c linux-libre-2.6.34-gnu1/arch/m68knommu/platform/68360/ints.c
--- linux-libre-2.6.33-gnu1/arch/m68knommu/platform/68360/ints.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/m68knommu/platform/68360/ints.c	2010-05-16 17:17:36.000000000 -0400
@@ -107,7 +107,6 @@ void init_IRQ(void)
 	_ramvec[vba+CPMVEC_PIO_PC7]     = inthandler;  /* pio - pc7 */
 	_ramvec[vba+CPMVEC_PIO_PC6]     = inthandler;  /* pio - pc6 */
 	_ramvec[vba+CPMVEC_TIMER3]      = inthandler;  /* timer 3 */
-	_ramvec[vba+CPMVEC_RISCTIMER]   = inthandler;  /* reserved */
 	_ramvec[vba+CPMVEC_PIO_PC5]     = inthandler;  /* pio - pc5 */
 	_ramvec[vba+CPMVEC_PIO_PC4]     = inthandler;  /* pio - pc4 */
 	_ramvec[vba+CPMVEC_RESERVED2]   = inthandler;  /* reserved */
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/boot/Makefile linux-libre-2.6.34-gnu1/arch/microblaze/boot/Makefile
--- linux-libre-2.6.33-gnu1/arch/microblaze/boot/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/boot/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -23,8 +23,6 @@ $(obj)/system.dtb: $(obj)/$(DTB).dtb
 endif
 
 $(obj)/linux.bin: vmlinux FORCE
-	[ -n $(CONFIG_INITRAMFS_SOURCE) ] && [ ! -e $(CONFIG_INITRAMFS_SOURCE) ] && \
-	touch $(CONFIG_INITRAMFS_SOURCE) || echo "No CPIO image"
 	$(call if_changed,objcopy)
 	$(call if_changed,uimage)
 	@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
@@ -62,6 +60,4 @@ quiet_cmd_dtc = DTC     $@
 $(obj)/%.dtb: $(dtstree)/%.dts FORCE
 	$(call if_changed,dtc)
 
-clean-kernel += linux.bin linux.bin.gz simpleImage.*
-
-clean-files += *.dtb simpleImage.*.unstrip
+clean-files += *.dtb simpleImage.*.unstrip linux.bin.ub
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/configs/mmu_defconfig linux-libre-2.6.34-gnu1/arch/microblaze/configs/mmu_defconfig
--- linux-libre-2.6.33-gnu1/arch/microblaze/configs/mmu_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/configs/mmu_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc6
-# Wed Feb  3 10:02:59 2010
+# Linux kernel version: 2.6.34-rc6
+# Thu May  6 11:22:14 2010
 #
 CONFIG_MICROBLAZE=y
 # CONFIG_SWAP is not set
@@ -22,8 +22,6 @@ CONFIG_GENERIC_CSUM=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-# CONFIG_PCI is not set
-CONFIG_NO_DMA=y
 CONFIG_DTC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
@@ -56,7 +54,6 @@ CONFIG_RCU_FANOUT=32
 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
@@ -106,6 +103,8 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
@@ -245,13 +244,20 @@ 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
+
+#
+# Bus Options
+#
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_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
@@ -341,7 +347,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
 CONFIG_OF_DEVICE=y
+CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
@@ -370,6 +378,7 @@ CONFIG_MISC_DEVICES=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -383,9 +392,30 @@ CONFIG_NETDEVICES=y
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_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_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
@@ -394,6 +424,7 @@ CONFIG_NET_ETHERNET=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_KS8842 is not set
 # CONFIG_KS8851_MLL is not set
 CONFIG_XILINX_EMACLITE=y
@@ -444,6 +475,7 @@ CONFIG_SERIAL_UARTLITE=y
 CONFIG_SERIAL_UARTLITE_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -471,6 +503,12 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
@@ -502,6 +540,7 @@ CONFIG_USB_ARCH_HAS_EHCI=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
 
@@ -572,6 +611,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -595,6 +635,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=y
 CONFIG_CIFS_STATS=y
 CONFIG_CIFS_STATS2=y
@@ -696,6 +737,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_OBJECTS is not set
 CONFIG_DEBUG_SLAB=y
 # CONFIG_DEBUG_SLAB_LEAK is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 CONFIG_DEBUG_SPINLOCK=y
 # CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_LOCK_ALLOC is not set
@@ -741,6 +783,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
 # 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_EARLY_PRINTK=y
 # CONFIG_HEART_BEAT is not set
@@ -862,5 +905,6 @@ 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
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/configs/nommu_defconfig linux-libre-2.6.34-gnu1/arch/microblaze/configs/nommu_defconfig
--- linux-libre-2.6.33-gnu1/arch/microblaze/configs/nommu_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/configs/nommu_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc6
-# Wed Feb  3 10:03:21 2010
+# Linux kernel version: 2.6.34-rc6
+# Thu May  6 11:25:12 2010
 #
 CONFIG_MICROBLAZE=y
 # CONFIG_SWAP is not set
@@ -22,8 +22,6 @@ CONFIG_GENERIC_CSUM=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-# CONFIG_PCI is not set
-CONFIG_NO_DMA=y
 CONFIG_DTC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
@@ -58,7 +56,6 @@ CONFIG_RCU_FANOUT=32
 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
@@ -96,6 +93,8 @@ CONFIG_SLAB=y
 # CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
@@ -209,11 +208,14 @@ CONFIG_PROC_DEVICETREE=y
 #
 # Advanced setup
 #
+# CONFIG_ADVANCED_OPTIONS is not set
 
 #
 # Default settings for advanced configuration options are used
 #
+CONFIG_LOWMEM_SIZE=0x30000000
 CONFIG_KERNEL_START=0x90000000
+CONFIG_TASK_SIZE=0x80000000
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -235,13 +237,20 @@ CONFIG_BINFMT_FLAT=y
 # CONFIG_BINFMT_SHARED_FLAT is not set
 # CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
+
+#
+# Bus Options
+#
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_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
@@ -413,6 +422,7 @@ CONFIG_MTD_UCLINUX=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
 CONFIG_OF_DEVICE=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
@@ -442,6 +452,7 @@ CONFIG_MISC_DEVICES=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -458,6 +469,7 @@ 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
@@ -466,6 +478,7 @@ CONFIG_NET_ETHERNET=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_KS8842 is not set
 # CONFIG_KS8851_MLL is not set
 # CONFIG_XILINX_EMACLITE is not set
@@ -516,6 +529,7 @@ CONFIG_SERIAL_UARTLITE=y
 CONFIG_SERIAL_UARTLITE_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -544,6 +558,12 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
@@ -593,6 +613,7 @@ CONFIG_USB_ARCH_HAS_EHCI=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
 
@@ -661,6 +682,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -689,6 +711,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -733,6 +756,7 @@ CONFIG_DEBUG_OBJECTS_TIMERS=y
 # CONFIG_DEBUG_OBJECTS_WORK is not set
 CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -758,6 +782,7 @@ CONFIG_DEBUG_SG=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -782,6 +807,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_EARLY_PRINTK=y
 # CONFIG_HEART_BEAT is not set
@@ -901,5 +927,6 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 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.33-gnu1/arch/microblaze/include/asm/cache.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/cache.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/cache.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/cache.h	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,7 @@
 
 #include <asm/registers.h>
 
-#define L1_CACHE_SHIFT	2
+#define L1_CACHE_SHIFT 5
 /* word-granular cache in microblaze */
 #define L1_CACHE_BYTES	(1 << L1_CACHE_SHIFT)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/device.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/device.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/device.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/device.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,10 @@ struct device_node;
 struct dev_archdata {
 	/* Optional pointer to an OF device node */
 	struct device_node	*of_node;
+
+	/* DMA operations on that device */
+	struct dma_map_ops	*dma_ops;
+	void                    *dma_data;
 };
 
 struct pdev_archdata {
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/dma.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/dma.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/dma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/dma.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,4 +18,10 @@
 #define MAX_DMA_ADDRESS (CONFIG_KERNEL_START + memory_size - 1)
 #endif
 
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy     (0)
+#endif
+
 #endif /* _ASM_MICROBLAZE_DMA_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/dma-mapping.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/dma-mapping.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/dma-mapping.h	2010-05-16 17:17:36.000000000 -0400
@@ -1 +1,153 @@
-#include <asm-generic/dma-mapping-broken.h>
+/*
+ * Implements the generic device dma API for microblaze and the pci
+ *
+ * Copyright (C) 2009-2010 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2009-2010 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 is base on powerpc and x86 dma-mapping.h versions
+ * Copyright (C) 2004 IBM
+ */
+
+#ifndef _ASM_MICROBLAZE_DMA_MAPPING_H
+#define _ASM_MICROBLAZE_DMA_MAPPING_H
+
+/*
+ * See Documentation/PCI/PCI-DMA-mapping.txt and
+ * Documentation/DMA-API.txt for documentation.
+ */
+
+#include <linux/types.h>
+#include <linux/cache.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-debug.h>
+#include <linux/dma-attrs.h>
+#include <asm/io.h>
+#include <asm-generic/dma-coherent.h>
+
+#define DMA_ERROR_CODE		(~(dma_addr_t)0x0)
+
+#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)
+
+static inline unsigned long device_to_mask(struct device *dev)
+{
+	if (dev->dma_mask && *dev->dma_mask)
+		return *dev->dma_mask;
+	/* Assume devices without mask can take 32 bit addresses */
+	return 0xfffffffful;
+}
+
+extern struct dma_map_ops *dma_ops;
+
+/*
+ * Available generic sets of operations
+ */
+extern struct dma_map_ops dma_direct_ops;
+
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+	/* We don't handle the NULL dev case for ISA for now. We could
+	 * do it via an out of line call but it is not needed for now. The
+	 * 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) || !dev->archdata.dma_ops)
+		return NULL;
+
+	return dev->archdata.dma_ops;
+}
+
+static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
+{
+	dev->archdata.dma_ops = ops;
+}
+
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+
+	if (unlikely(!ops))
+		return 0;
+	if (!ops->dma_supported)
+		return 1;
+	return ops->dma_supported(dev, mask);
+}
+
+#ifdef CONFIG_PCI
+/* We have our own implementation of pci_set_dma_mask() */
+#define HAVE_ARCH_PCI_SET_DMA_MASK
+
+#endif
+
+static inline int dma_set_mask(struct device *dev, u64 dma_mask)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+
+	if (unlikely(ops == NULL))
+		return -EIO;
+	if (ops->set_dma_mask)
+		return ops->set_dma_mask(dev, dma_mask);
+	if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+		return -EIO;
+	*dev->dma_mask = dma_mask;
+	return 0;
+}
+
+#include <asm-generic/dma-mapping-common.h>
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	if (ops->mapping_error)
+		return ops->mapping_error(dev, dma_addr);
+
+	return (dma_addr == DMA_ERROR_CODE);
+}
+
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_is_consistent(d, h)	(1)
+
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+					dma_addr_t *dma_handle, gfp_t flag)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	void *memory;
+
+	BUG_ON(!ops);
+
+	memory = ops->alloc_coherent(dev, size, dma_handle, flag);
+
+	debug_dma_alloc_coherent(dev, size, *dma_handle, memory);
+	return memory;
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+				     void *cpu_addr, dma_addr_t dma_handle)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+
+	BUG_ON(!ops);
+	debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
+	ops->free_coherent(dev, size, cpu_addr, dma_handle);
+}
+
+static inline int dma_get_cache_alignment(void)
+{
+	return L1_CACHE_BYTES;
+}
+
+static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+		enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+	__dma_sync(vaddr, size, (int)direction);
+}
+
+#endif	/* _ASM_MICROBLAZE_DMA_MAPPING_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/entry.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/entry.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/entry.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/entry.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,7 @@
  * places
  */
 
-#define PER_CPU(var) per_cpu__##var
+#define PER_CPU(var) var
 
 # ifndef __ASSEMBLY__
 DECLARE_PER_CPU(unsigned int, KSP); /* Saved kernel stack pointer */
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/exceptions.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/exceptions.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/exceptions.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/exceptions.h	2010-05-16 17:17:36.000000000 -0400
@@ -64,12 +64,6 @@ asmlinkage void full_exception(struct pt
 void die(const char *str, struct pt_regs *fp, long err);
 void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr);
 
-#ifdef CONFIG_MMU
-void __bug(const char *file, int line, void *data);
-int bad_trap(int trap_num, struct pt_regs *regs);
-int debug_trap(struct pt_regs *regs);
-#endif /* CONFIG_MMU */
-
 #if defined(CONFIG_KGDB)
 void (*debugger)(struct pt_regs *regs);
 int (*debugger_bpt)(struct pt_regs *regs);
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/futex.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/futex.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/futex.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/futex.h	2010-05-16 17:17:36.000000000 -0400
@@ -55,7 +55,7 @@ futex_atomic_op_inuser(int encoded_op, i
 		__futex_atomic_op("or %1,%0,%4;", ret, oldval, uaddr, oparg);
 		break;
 	case FUTEX_OP_ANDN:
-		__futex_atomic_op("and %1,%0,%4;", ret, oldval, uaddr, oparg);
+		__futex_atomic_op("andn %1,%0,%4;", ret, oldval, uaddr, oparg);
 		break;
 	case FUTEX_OP_XOR:
 		__futex_atomic_op("xor %1,%0,%4;", ret, oldval, uaddr, oparg);
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/io.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/io.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/io.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/io.h	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,23 @@
 #include <asm/page.h>
 #include <linux/types.h>
 #include <linux/mm.h>          /* Get struct page {...} */
+#include <asm-generic/iomap.h>
 
+#ifndef CONFIG_PCI
+#define _IO_BASE	0
+#define _ISA_MEM_BASE	0
+#define PCI_DRAM_OFFSET	0
+#else
+#define _IO_BASE	isa_io_base
+#define _ISA_MEM_BASE	isa_mem_base
+#define PCI_DRAM_OFFSET	pci_dram_offset
+#endif
+
+extern unsigned long isa_io_base;
+extern unsigned long pci_io_base;
+extern unsigned long pci_dram_offset;
+
+extern resource_size_t isa_mem_base;
 
 #define IO_SPACE_LIMIT (0xFFFFFFFF)
 
@@ -92,6 +108,11 @@ static inline void writel(unsigned int v
 #define iowrite16(v, addr)	__raw_writew((u16)(v), (u16 *)(addr))
 #define iowrite32(v, addr)	__raw_writel((u32)(v), (u32 *)(addr))
 
+#define ioread16be(addr)	__raw_readw((u16 *)(addr))
+#define ioread32be(addr)	__raw_readl((u32 *)(addr))
+#define iowrite16be(v, addr)	__raw_writew((u16)(v), (u16 *)(addr))
+#define iowrite32be(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
@@ -118,15 +139,10 @@ static inline void writel(unsigned int v
 
 #ifdef CONFIG_MMU
 
-#define mm_ptov(addr)		((void *)__phys_to_virt(addr))
-#define mm_vtop(addr)		((unsigned long)__virt_to_phys(addr))
 #define phys_to_virt(addr)	((void *)__phys_to_virt(addr))
 #define virt_to_phys(addr)	((unsigned long)__virt_to_phys(addr))
 #define virt_to_bus(addr)	((unsigned long)__virt_to_phys(addr))
 
-#define __page_address(page) \
-		(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
-#define page_to_phys(page)	virt_to_phys((void *)__page_address(page))
 #define page_to_bus(page)	(page_to_phys(page))
 #define bus_to_virt(addr)	(phys_to_virt(addr))
 
@@ -227,15 +243,7 @@ static inline void __iomem *__ioremap(ph
 #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 */
-}
+#define ioport_map(port, nr)	((void __iomem *)(port))
+#define ioport_unmap(addr)
 
 #endif /* _ASM_MICROBLAZE_IO_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/irq.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/irq.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/irq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,12 @@
 
 #include <linux/interrupt.h>
 
+/* This type is the placeholder for a hardware interrupt number. It has to
+ * be big enough to enclose whatever representation is used by a given
+ * platform.
+ */
+typedef unsigned long irq_hw_number_t;
+
 extern unsigned int nr_irq;
 
 #define NO_IRQ (-1)
@@ -21,7 +27,8 @@ extern unsigned int nr_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
+/**
+ * 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
  *
@@ -40,4 +47,32 @@ static inline void irq_dispose_mapping(u
 	return;
 }
 
+struct irq_host;
+
+/**
+ * irq_create_mapping - Map a hardware interrupt into linux virq space
+ * @host: host owning this hardware interrupt or NULL for default host
+ * @hwirq: hardware irq number in that host space
+ *
+ * Only one mapping per hardware interrupt is permitted. Returns a linux
+ * virq number.
+ * If the sense/trigger is to be specified, set_irq_type() should be called
+ * on the number returned from that call.
+ */
+extern unsigned int irq_create_mapping(struct irq_host *host,
+					irq_hw_number_t hwirq);
+
+/**
+ * irq_create_of_mapping - Map a hardware interrupt into linux virq space
+ * @controller: Device node of the interrupt controller
+ * @inspec: Interrupt specifier from the device-tree
+ * @intsize: Size of the interrupt specifier from the device-tree
+ *
+ * This function is identical to irq_create_mapping except that it takes
+ * as input informations straight from the device-tree (typically the results
+ * of the of_irq_map_*() functions.
+ */
+extern unsigned int irq_create_of_mapping(struct device_node *controller,
+					u32 *intspec, unsigned int intsize);
+
 #endif /* _ASM_MICROBLAZE_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/page.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/page.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/page.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/page.h	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,9 @@
 
 #ifndef __ASSEMBLY__
 
+/* MS be sure that SLAB allocates aligned objects */
+#define ARCH_KMALLOC_MINALIGN	L1_CACHE_BYTES
+
 #define PAGE_UP(addr)	(((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1)))
 #define PAGE_DOWN(addr)	((addr)&(~((PAGE_SIZE)-1)))
 
@@ -62,12 +65,6 @@ extern unsigned int __page_offset;
 #define PAGE_OFFSET	CONFIG_KERNEL_START
 
 /*
- * MAP_NR -- given an address, calculate the index of the page struct which
- * points to the address's page.
- */
-#define MAP_NR(addr) (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT)
-
-/*
  * The basic type of a PTE - 32 bit physical addressing.
  */
 typedef unsigned long pte_basic_t;
@@ -76,14 +73,7 @@ typedef unsigned long pte_basic_t;
 
 #endif /* CONFIG_MMU */
 
-#  ifndef CONFIG_MMU
-#  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)
-#  else /* CONFIG_MMU */
-extern void copy_page(void *to, void *from);
-#  endif /* CONFIG_MMU */
-
+# define copy_page(to, from)			memcpy((to), (from), PAGE_SIZE)
 # define clear_page(pgaddr)			memset((pgaddr), 0, PAGE_SIZE)
 
 # define clear_user_page(pgaddr, vaddr, page)	memset((pgaddr), 0, PAGE_SIZE)
@@ -154,7 +144,11 @@ extern int page_is_ram(unsigned long pfn
 # define pfn_to_virt(pfn)	__va(pfn_to_phys((pfn)))
 
 #  ifdef CONFIG_MMU
-#  define virt_to_page(kaddr) 	(mem_map +  MAP_NR(kaddr))
+
+#  define virt_to_page(kaddr)	(pfn_to_page(__pa(kaddr) >> PAGE_SHIFT))
+#  define page_to_virt(page)   __va(page_to_pfn(page) << PAGE_SHIFT)
+#  define page_to_phys(page)     (page_to_pfn(page) << PAGE_SHIFT)
+
 #  else /* CONFIG_MMU */
 #  define virt_to_page(vaddr)	(pfn_to_page(virt_to_pfn(vaddr)))
 #  define page_to_virt(page)	(pfn_to_virt(page_to_pfn(page)))
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/pci-bridge.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/pci-bridge.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/pci-bridge.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/pci-bridge.h	2010-05-16 17:17:36.000000000 -0400
@@ -1 +1,196 @@
+#ifndef _ASM_MICROBLAZE_PCI_BRIDGE_H
+#define _ASM_MICROBLAZE_PCI_BRIDGE_H
+#ifdef __KERNEL__
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
 #include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/ioport.h>
+
+struct device_node;
+
+enum {
+	/* Force re-assigning all resources (ignore firmware
+	 * setup completely)
+	 */
+	PCI_REASSIGN_ALL_RSRC	= 0x00000001,
+
+	/* Re-assign all bus numbers */
+	PCI_REASSIGN_ALL_BUS	= 0x00000002,
+
+	/* Do not try to assign, just use existing setup */
+	PCI_PROBE_ONLY		= 0x00000004,
+
+	/* Don't bother with ISA alignment unless the bridge has
+	 * ISA forwarding enabled
+	 */
+	PCI_CAN_SKIP_ISA_ALIGN	= 0x00000008,
+
+	/* Enable domain numbers in /proc */
+	PCI_ENABLE_PROC_DOMAINS	= 0x00000010,
+	/* ... except for domain 0 */
+	PCI_COMPAT_DOMAIN_0		= 0x00000020,
+};
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct pci_controller {
+	struct pci_bus *bus;
+	char is_dynamic;
+	struct device_node *dn;
+	struct list_head list_node;
+	struct device *parent;
+
+	int first_busno;
+	int last_busno;
+
+	int self_busno;
+
+	void __iomem *io_base_virt;
+	resource_size_t io_base_phys;
+
+	resource_size_t pci_io_size;
+
+	/* Some machines (PReP) have a non 1:1 mapping of
+	 * the PCI memory space in the CPU bus space
+	 */
+	resource_size_t pci_mem_offset;
+
+	/* Some machines have a special region to forward the ISA
+	 * "memory" cycles such as VGA memory regions. Left to 0
+	 * if unsupported
+	 */
+	resource_size_t isa_mem_phys;
+	resource_size_t isa_mem_size;
+
+	struct pci_ops *ops;
+	unsigned int __iomem *cfg_addr;
+	void __iomem *cfg_data;
+
+	/*
+	 * Used for variants of PCI indirect handling and possible quirks:
+	 *  SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
+	 *  EXT_REG - provides access to PCI-e extended registers
+	 *  SURPRESS_PRIMARY_BUS - we surpress the setting of PCI_PRIMARY_BUS
+	 *   on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS
+	 *   to determine which bus number to match on when generating type0
+	 *   config cycles
+	 *  NO_PCIE_LINK - the Freescale PCI-e controllers have issues with
+	 *   hanging if we don't have link and try to do config cycles to
+	 *   anything but the PHB.  Only allow talking to the PHB if this is
+	 *   set.
+	 *  BIG_ENDIAN - cfg_addr is a big endian register
+	 *  BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs
+	 *   on the PLB4.  Effectively disable MRM commands by setting this.
+	 */
+#define INDIRECT_TYPE_SET_CFG_TYPE		0x00000001
+#define INDIRECT_TYPE_EXT_REG		0x00000002
+#define INDIRECT_TYPE_SURPRESS_PRIMARY_BUS	0x00000004
+#define INDIRECT_TYPE_NO_PCIE_LINK		0x00000008
+#define INDIRECT_TYPE_BIG_ENDIAN		0x00000010
+#define INDIRECT_TYPE_BROKEN_MRM		0x00000020
+	u32 indirect_type;
+
+	/* Currently, we limit ourselves to 1 IO range and 3 mem
+	 * ranges since the common pci_bus structure can't handle more
+	 */
+	struct resource io_resource;
+	struct resource mem_resources[3];
+	int global_number;	/* PCI domain number */
+};
+
+static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
+{
+	return bus->sysdata;
+}
+
+static inline int isa_vaddr_is_ioport(void __iomem *address)
+{
+	/* No specific ISA handling on ppc32 at this stage, it
+	 * all goes through PCI
+	 */
+	return 0;
+}
+
+/* These are used for config access before all the PCI probing
+   has been done. */
+extern int early_read_config_byte(struct pci_controller *hose, int bus,
+			int dev_fn, int where, u8 *val);
+extern int early_read_config_word(struct pci_controller *hose, int bus,
+			int dev_fn, int where, u16 *val);
+extern int early_read_config_dword(struct pci_controller *hose, int bus,
+			int dev_fn, int where, u32 *val);
+extern int early_write_config_byte(struct pci_controller *hose, int bus,
+			int dev_fn, int where, u8 val);
+extern int early_write_config_word(struct pci_controller *hose, int bus,
+			int dev_fn, int where, u16 val);
+extern int early_write_config_dword(struct pci_controller *hose, int bus,
+			int dev_fn, int where, u32 val);
+
+extern int early_find_capability(struct pci_controller *hose, int bus,
+				 int dev_fn, int cap);
+
+extern void setup_indirect_pci(struct pci_controller *hose,
+			       resource_size_t cfg_addr,
+			       resource_size_t cfg_data, u32 flags);
+
+/* Get the PCI host controller for an OF device */
+extern struct pci_controller *pci_find_hose_for_OF_device(
+			struct device_node *node);
+
+/* Fill up host controller resources from the OF node */
+extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
+			struct device_node *dev, int primary);
+
+/* Allocate & free a PCI host bridge structure */
+extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev);
+extern void pcibios_free_controller(struct pci_controller *phb);
+extern void pcibios_setup_phb_resources(struct pci_controller *hose);
+
+#ifdef CONFIG_PCI
+extern unsigned int pci_flags;
+
+static inline void pci_set_flags(int flags)
+{
+	pci_flags = flags;
+}
+
+static inline void pci_add_flags(int flags)
+{
+	pci_flags |= flags;
+}
+
+static inline int pci_has_flag(int flag)
+{
+	return pci_flags & flag;
+}
+
+extern struct list_head hose_list;
+
+extern unsigned long pci_address_to_pio(phys_addr_t address);
+extern int pcibios_vaddr_is_ioport(void __iomem *address);
+#else
+static inline unsigned long pci_address_to_pio(phys_addr_t address)
+{
+	return (unsigned long)-1;
+}
+static inline int pcibios_vaddr_is_ioport(void __iomem *address)
+{
+	return 0;
+}
+
+static inline void pci_set_flags(int flags) { }
+static inline void pci_add_flags(int flags) { }
+static inline int pci_has_flag(int flag)
+{
+	return 0;
+}
+#endif	/* CONFIG_PCI */
+
+#endif	/* __KERNEL__ */
+#endif	/* _ASM_MICROBLAZE_PCI_BRIDGE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/pci.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/pci.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -1 +1,169 @@
-#include <asm-generic/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.
+ *
+ * Based on powerpc version
+ */
+
+#ifndef __ASM_MICROBLAZE_PCI_H
+#define __ASM_MICROBLAZE_PCI_H
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+
+#include <asm/scatterlist.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+
+#define PCIBIOS_MIN_IO		0x1000
+#define PCIBIOS_MIN_MEM		0x10000000
+
+struct pci_dev;
+
+/* Values for the `which' argument to sys_pciconfig_iobase syscall.  */
+#define IOBASE_BRIDGE_NUMBER	0
+#define IOBASE_MEMORY		1
+#define IOBASE_IO		2
+#define IOBASE_ISA_IO		3
+#define IOBASE_ISA_MEM		4
+
+#define pcibios_scan_all_fns(a, b)	0
+
+/*
+ * Set this to 1 if you want the kernel to re-assign all PCI
+ * bus numbers (don't do that on ppc64 yet !)
+ */
+#define pcibios_assign_all_busses() \
+	(pci_has_flag(PCI_REASSIGN_ALL_BUS))
+
+static inline void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+
+static inline void pcibios_penalize_isa_irq(int irq, int active)
+{
+	/* We don't do dynamic PCI IRQ allocation */
+}
+
+#ifdef CONFIG_PCI
+extern void set_pci_dma_ops(struct dma_map_ops *dma_ops);
+extern struct dma_map_ops *get_pci_dma_ops(void);
+#else	/* CONFIG_PCI */
+#define set_pci_dma_ops(d)
+#define get_pci_dma_ops()	NULL
+#endif
+
+#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
+
+extern int pci_domain_nr(struct pci_bus *bus);
+
+/* Decide whether to display the domain number in /proc */
+extern int pci_proc_domain(struct pci_bus *bus);
+
+struct vm_area_struct;
+/* Map a range of PCI memory or I/O space for a device into user space */
+int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state, int write_combine);
+
+/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
+#define HAVE_PCI_MMAP	1
+
+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);
+
+#define HAVE_PCI_LEGACY	1
+
+/* The PCI address space does equal the physical memory
+ * address space (no IOMMU).  The IDE and SCSI device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS     (1)
+
+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;
+}
+
+extern void pcibios_claim_one_bus(struct pci_bus *b);
+
+extern void pcibios_finish_adding_to_bus(struct pci_bus *bus);
+
+extern void pcibios_resource_survey(void);
+
+extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
+extern int remove_phb_dynamic(struct pci_controller *phb);
+
+extern struct pci_dev *of_create_pci_dev(struct device_node *node,
+					struct pci_bus *bus, int devfn);
+
+extern void of_scan_pci_bridge(struct device_node *node,
+				struct pci_dev *dev);
+
+extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
+extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus);
+
+extern int pci_read_irq_line(struct pci_dev *dev);
+
+extern int pci_bus_find_capability(struct pci_bus *bus,
+						unsigned int devfn, int cap);
+
+struct file;
+extern pgprot_t	pci_phys_mem_access_prot(struct file *file,
+					 unsigned long pfn,
+					 unsigned long size,
+					 pgprot_t prot);
+
+#define HAVE_ARCH_PCI_RESOURCE_TO_USER
+extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
+				 const struct resource *rsrc,
+				 resource_size_t *start, resource_size_t *end);
+
+extern void pcibios_setup_bus_devices(struct pci_bus *bus);
+extern void pcibios_setup_bus_self(struct pci_bus *bus);
+
+/* This part of code was originaly in xilinx-pci.h */
+#ifdef CONFIG_PCI_XILINX
+extern void __init xilinx_pci_init(void);
+#else
+static inline void __init xilinx_pci_init(void) { return; }
+#endif
+
+#endif	/* __KERNEL__ */
+#endif /* __ASM_MICROBLAZE_PCI_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/pgalloc.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/pgalloc.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/pgalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/pgalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <asm/io.h>
 #include <asm/page.h>
 #include <asm/cache.h>
+#include <asm/pgtable.h>
 
 #define PGDIR_ORDER	0
 
@@ -107,22 +108,7 @@ extern inline void free_pgd_slow(pgd_t *
 #define pmd_alloc_one_fast(mm, address)	({ BUG(); ((pmd_t *)1); })
 #define pmd_alloc_one(mm, address)	({ BUG(); ((pmd_t *)2); })
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-		unsigned long address)
-{
-	pte_t *pte;
-	extern int mem_init_done;
-	extern void *early_get_page(void);
-	if (mem_init_done) {
-		pte = (pte_t *)__get_free_page(GFP_KERNEL |
-					__GFP_REPEAT | __GFP_ZERO);
-	} else {
-		pte = (pte_t *)early_get_page();
-		if (pte)
-			clear_page(pte);
-	}
-	return pte;
-}
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
 
 static inline struct page *pte_alloc_one(struct mm_struct *mm,
 		unsigned long address)
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/pgtable.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/pgtable.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,10 @@
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
 
+#ifndef __ASSEMBLY__
+extern int mem_init_done;
+#endif
+
 #ifndef CONFIG_MMU
 
 #define pgd_present(pgd)	(1) /* pages are always present on non MMU */
@@ -51,6 +55,8 @@ static inline int pte_file(pte_t pte) {
 
 #define arch_enter_lazy_cpu_mode()	do {} while (0)
 
+#define pgprot_noncached_wc(prot)	prot
+
 #else /* CONFIG_MMU */
 
 #include <asm-generic/4level-fixup.h>
@@ -68,7 +74,6 @@ static inline int pte_file(pte_t pte) {
 
 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;
 
 /*
  * The following only work if pte_present() is true.
@@ -85,11 +90,25 @@ static inline pte_t pte_mkspecial(pte_t
 #define VMALLOC_START	(CONFIG_KERNEL_START + \
 				max(32 * 1024 * 1024UL, memory_size))
 #define VMALLOC_END	ioremap_bot
-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
 
 #endif /* __ASSEMBLY__ */
 
 /*
+ * Macro to mark a page protection value as "uncacheable".
+ */
+
+#define _PAGE_CACHE_CTL	(_PAGE_GUARDED | _PAGE_NO_CACHE | \
+							_PAGE_WRITETHRU)
+
+#define pgprot_noncached(prot) \
+			(__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
+					_PAGE_NO_CACHE | _PAGE_GUARDED))
+
+#define pgprot_noncached_wc(prot) \
+			 (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
+							_PAGE_NO_CACHE))
+
+/*
  * The MicroBlaze MMU is identical to the PPC-40x MMU, and uses a hash
  * table containing PTEs, together with a set of 16 segment registers, to
  * define the virtual to physical address mapping.
@@ -397,7 +416,7 @@ static inline unsigned long pte_update(p
 	mts     rmsr, %2\n\
 	nop"
 	: "=&r" (old), "=&r" (tmp), "=&r" (msr), "=m" (*p)
-	: "r" ((unsigned long)(p+1) - 4), "r" (clr), "r" (set), "m" (*p)
+	: "r" ((unsigned long)(p + 1) - 4), "r" (clr), "r" (set), "m" (*p)
 	: "cc");
 
 	return old;
@@ -493,15 +512,6 @@ static inline pmd_t *pmd_offset(pgd_t *d
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 
 /*
- * When flushing the tlb entry for a page, we also need to flush the hash
- * table entry.  flush_hash_page is assembler (for speed) in hashtable.S.
- */
-extern int flush_hash_page(unsigned context, unsigned long va, pte_t *ptep);
-
-/* Add an HPTE to the hash table */
-extern void add_hash_page(unsigned context, unsigned long va, pte_t *ptep);
-
-/*
  * Encode and decode a swap entry.
  * Note that the bits we use in a PTE for representing a swap entry
  * must not include the _PAGE_PRESENT bit, or the _PAGE_HASHPTE bit
@@ -514,15 +524,7 @@ extern void add_hash_page(unsigned conte
 #define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) >> 2 })
 #define __swp_entry_to_pte(x)	((pte_t) { (x).val << 2 })
 
-
-/* CONFIG_APUS */
-/* For virtual address to physical address conversion */
-extern void cache_clear(__u32 addr, int length);
-extern void cache_push(__u32 addr, int length);
-extern int mm_end_of_chunk(unsigned long addr, int len);
 extern unsigned long iopa(unsigned long addr);
-/* extern unsigned long mm_ptov(unsigned long addr) \
-	__attribute__ ((const)); TBD */
 
 /* Values for nocacheflag and cmode */
 /* These are not used by the APUS kernel_map, but prevents
@@ -533,18 +535,6 @@ extern unsigned long iopa(unsigned long
 #define	IOMAP_NOCACHE_NONSER	2
 #define	IOMAP_NO_COPYBACK	3
 
-/*
- * Map some physical address range into the kernel address space.
- */
-extern unsigned long kernel_map(unsigned long paddr, unsigned long size,
-				int nocacheflag, unsigned long *memavailp);
-
-/*
- * Set cache mode of (kernel space) address range.
- */
-extern void kernel_set_cachemode(unsigned long address, unsigned long size,
-				unsigned int cmode);
-
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
 #define kern_addr_valid(addr)	(1)
 
@@ -558,26 +548,15 @@ extern void kernel_set_cachemode(unsigne
 void do_page_fault(struct pt_regs *regs, unsigned long address,
 		   unsigned long error_code);
 
-void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
-			     unsigned int size, int flags);
-
-void __init adjust_total_lowmem(void);
 void mapin_ram(void);
 int map_page(unsigned long va, phys_addr_t pa, int flags);
 
 extern int mem_init_done;
-extern unsigned long ioremap_base;
-extern unsigned long ioremap_bot;
 
 asmlinkage void __init mmu_init(void);
 
 void __init *early_get_page(void);
 
-void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle);
-void consistent_free(void *vaddr);
-void consistent_sync(void *vaddr, size_t size, int direction);
-void consistent_sync_page(struct page *page, unsigned long offset,
-	size_t size, int direction);
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
@@ -586,6 +565,14 @@ void consistent_sync_page(struct page *p
 #ifndef __ASSEMBLY__
 #include <asm-generic/pgtable.h>
 
+extern unsigned long ioremap_bot, ioremap_base;
+
+void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle);
+void consistent_free(size_t size, void *vaddr);
+void consistent_sync(void *vaddr, size_t size, int direction);
+void consistent_sync_page(struct page *page, unsigned long offset,
+	size_t size, int direction);
+
 void setup_memory(void);
 #endif /* __ASSEMBLY__ */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/processor.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/processor.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/processor.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/processor.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
 #include <asm/ptrace.h>
 #include <asm/setup.h>
 #include <asm/registers.h>
-#include <asm/segment.h>
 #include <asm/entry.h>
 #include <asm/current.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/prom.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/prom.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/prom.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/prom.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,30 +26,25 @@
 #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))
-
-extern struct device_node *of_chosen;
-
 #define HAVE_ARCH_DEVTREE_FIXUPS
 
-extern struct device_node *allnodes;	/* temporary while merging */
-extern rwlock_t devtree_lock;	/* temporary while merging */
-
-/* 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 int early_uartlite_console(void);
 
-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);
+#ifdef CONFIG_PCI
+/*
+ * PCI <-> OF matching functions
+ * (XXX should these be here?)
+ */
+struct pci_bus;
+struct pci_dev;
+extern int pci_device_from_OF_node(struct device_node *node,
+					u8 *bus, u8 *devfn);
+extern struct device_node *pci_busdev_to_OF_node(struct pci_bus *bus,
+							int devfn);
+extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev);
+extern void pci_create_OF_bus_map(void);
+#endif
 
 /*
  * OF address retreival & translation
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/segment.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/segment.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/segment.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/segment.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-/*
- * 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.
- */
-
-#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 MAKE_MM_SEG(s)       ((mm_segment_t) { (s) })
-
-#  ifndef CONFIG_MMU
-#  define KERNEL_DS	MAKE_MM_SEG(0)
-#  define USER_DS	KERNEL_DS
-#  else
-#  define KERNEL_DS	MAKE_MM_SEG(0xFFFFFFFF)
-#  define USER_DS	MAKE_MM_SEG(TASK_SIZE - 1)
-#  endif
-
-# define get_ds()	(KERNEL_DS)
-# define get_fs()	(current_thread_info()->addr_limit)
-# define set_fs(val)	(current_thread_info()->addr_limit = (val))
-
-# define segment_eq(a, b)	((a).seg == (b).seg)
-
-# endif /* __ASSEMBLY__ */
-#endif /* _ASM_MICROBLAZE_SEGMENT_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/system.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/system.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/system.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -87,6 +87,9 @@ void free_initmem(void);
 extern char *klimit;
 extern void ret_from_fork(void);
 
+extern void *alloc_maybe_bootmem(size_t size, gfp_t mask);
+extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
+
 #ifdef CONFIG_DEBUG_FS
 extern struct dentry *of_debugfs_root;
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/thread_info.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/thread_info.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/thread_info.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/thread_info.h	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #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
@@ -60,6 +59,10 @@ struct cpu_context {
 	__u32	fsr;
 };
 
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
 struct thread_info {
 	struct task_struct	*task; /* main task structure */
 	struct exec_domain	*exec_domain; /* execution domain */
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/tlbflush.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/tlbflush.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/tlbflush.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/tlbflush.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,8 @@
 extern void _tlbie(unsigned long address);
 extern void _tlbia(void);
 
-#define __tlbia()	_tlbia()
+#define __tlbia()	{ preempt_disable(); _tlbia(); preempt_enable(); }
+#define __tlbie(x)	{ _tlbie(x); }
 
 static inline void local_flush_tlb_all(void)
 	{ __tlbia(); }
@@ -31,14 +32,14 @@ static inline void local_flush_tlb_mm(st
 	{ __tlbia(); }
 static inline void local_flush_tlb_page(struct vm_area_struct *vma,
 				unsigned long vmaddr)
-	{ _tlbie(vmaddr); }
+	{ __tlbie(vmaddr); }
 static inline void local_flush_tlb_range(struct vm_area_struct *vma,
 		unsigned long start, unsigned long end)
 	{ __tlbia(); }
 
 #define flush_tlb_kernel_range(start, end)	do { } while (0)
 
-#define update_mmu_cache(vma, addr, pte)	do { } while (0)
+#define update_mmu_cache(vma, addr, ptep)	do { } while (0)
 
 #define flush_tlb_all local_flush_tlb_all
 #define flush_tlb_mm local_flush_tlb_mm
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/uaccess.h linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/uaccess.h
--- linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/uaccess.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/include/asm/uaccess.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,101 +22,73 @@
 #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
 
-#define __clear_user(addr, n)	(memset((void *)(addr), 0, (n)), 0)
-
-#ifndef CONFIG_MMU
-
-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)
-
-/* Undefined function to trigger linker error */
-extern int bad_user_access_length(void);
-
-/* 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;					\
-})
+/*
+ * 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 MAKE_MM_SEG(s)       ((mm_segment_t) { (s) })
 
-#define __get_user_bad()	(bad_user_access_length(), (-EFAULT))
+#  ifndef CONFIG_MMU
+#  define KERNEL_DS	MAKE_MM_SEG(0)
+#  define USER_DS	KERNEL_DS
+#  else
+#  define KERNEL_DS	MAKE_MM_SEG(0xFFFFFFFF)
+#  define USER_DS	MAKE_MM_SEG(TASK_SIZE - 1)
+#  endif
 
-/* FIXME is not there defined __pu_val */
-#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 get_ds()	(KERNEL_DS)
+# define get_fs()	(current_thread_info()->addr_limit)
+# define set_fs(val)	(current_thread_info()->addr_limit = (val))
 
-#define __put_user_bad()	(bad_user_access_length(), (-EFAULT))
+# define segment_eq(a, b)	((a).seg == (b).seg)
 
-#define put_user(x, ptr)	__put_user((x), (ptr))
-#define get_user(x, ptr)	__get_user((x), (ptr))
+/*
+ * 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;
+};
 
-#define copy_to_user(to, from, n)	(memcpy((to), (from), (n)), 0)
-#define copy_from_user(to, from, n)	(memcpy((to), (from), (n)), 0)
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
 
-#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)))
+#ifndef CONFIG_MMU
 
-static inline unsigned long clear_user(void *addr, unsigned long size)
+/* Check against bounds of physical memory */
+static inline int ___range_ok(unsigned long addr, unsigned long size)
 {
-	if (access_ok(VERIFY_WRITE, addr, size))
-		size = __clear_user(addr, size);
-	return size;
+	return ((addr < memory_start) ||
+		((addr + size) > memory_end));
 }
 
-/* Returns 0 if exception not found and fixup otherwise.  */
-extern unsigned long search_exception_table(unsigned long);
+#define __range_ok(addr, size) \
+		___range_ok((unsigned long)(addr), (unsigned long)(size))
 
-extern long strncpy_from_user(char *dst, const char *src, long count);
-extern long strnlen_user(const char *src, long count);
+#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0)
 
-#else /* CONFIG_MMU */
+#else
 
 /*
  * Address is valid if:
@@ -129,22 +101,119 @@ extern long strnlen_user(const char *src
 /* || printk("access_ok failed for %s at 0x%08lx (size %d), seg 0x%08x\n",
  type?"WRITE":"READ",addr,size,get_fs().seg)) */
 
-/*
- * All the __XXX versions macros/functions below do not perform
- * access checking. It is assumed that the necessary checks have been
- * already performed before the finction (macro) is called.
- */
+#endif
 
-#define get_user(x, ptr)						\
-({									\
-	access_ok(VERIFY_READ, (ptr), sizeof(*(ptr)))			\
-		? __get_user((x), (ptr)) : -EFAULT;			\
+#ifdef CONFIG_MMU
+# define __FIXUP_SECTION	".section .fixup,\"ax\"\n"
+# define __EX_TABLE_SECTION	".section __ex_table,\"a\"\n"
+#else
+# define __FIXUP_SECTION	".section .discard,\"ax\"\n"
+# define __EX_TABLE_SECTION	".section .discard,\"a\"\n"
+#endif
+
+extern unsigned long __copy_tofrom_user(void __user *to,
+		const void __user *from, unsigned long size);
+
+/* Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail. */
+static inline unsigned long __must_check __clear_user(void __user *to,
+							unsigned long n)
+{
+	/* normal memset with two words to __ex_table */
+	__asm__ __volatile__ (				\
+			"1:	sb	r0, %2, r0;"	\
+			"	addik	%0, %0, -1;"	\
+			"	bneid	%0, 1b;"	\
+			"	addik	%2, %2, 1;"	\
+			"2:			"	\
+			__EX_TABLE_SECTION		\
+			".word	1b,2b;"			\
+			".previous;"			\
+		: "=r"(n)				\
+		: "0"(n), "r"(to)
+	);
+	return n;
+}
+
+static inline unsigned long __must_check clear_user(void __user *to,
+							unsigned long n)
+{
+	might_sleep();
+	if (unlikely(!access_ok(VERIFY_WRITE, to, n)))
+		return n;
+
+	return __clear_user(to, n);
+}
+
+/* put_user and get_user macros */
+extern long __user_bad(void);
+
+#define __get_user_asm(insn, __gu_ptr, __gu_val, __gu_err)	\
+({								\
+	__asm__ __volatile__ (					\
+			"1:"	insn	" %1, %2, r0;"		\
+			"	addk	%0, r0, r0;"		\
+			"2:			"		\
+			__FIXUP_SECTION				\
+			"3:	brid	2b;"			\
+			"	addik	%0, r0, %3;"		\
+			".previous;"				\
+			__EX_TABLE_SECTION			\
+			".word	1b,3b;"				\
+			".previous;"				\
+		: "=&r"(__gu_err), "=r"(__gu_val)		\
+		: "r"(__gu_ptr), "i"(-EFAULT)			\
+	);							\
 })
 
-#define put_user(x, ptr)						\
+/**
+ * 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)))
+
+#define __get_user_check(x, ptr, size)					\
 ({									\
-	access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr)))			\
-		? __put_user((x), (ptr)) : -EFAULT;			\
+	unsigned long __gu_val = 0;					\
+	const typeof(*(ptr)) __user *__gu_addr = (ptr);			\
+	int __gu_err = 0;						\
+									\
+	if (access_ok(VERIFY_READ, __gu_addr, size)) {			\
+		switch (size) {						\
+		case 1:							\
+			__get_user_asm("lbu", __gu_addr, __gu_val,	\
+				       __gu_err);			\
+			break;						\
+		case 2:							\
+			__get_user_asm("lhu", __gu_addr, __gu_val,	\
+				       __gu_err);			\
+			break;						\
+		case 4:							\
+			__get_user_asm("lw", __gu_addr, __gu_val,	\
+				       __gu_err);			\
+			break;						\
+		default:						\
+			__gu_err = __user_bad();			\
+			break;						\
+		}							\
+	} else {							\
+		__gu_err = -EFAULT;					\
+	}								\
+	x = (typeof(*(ptr)))__gu_val;					\
+	__gu_err;							\
 })
 
 #define __get_user(x, ptr)						\
@@ -163,28 +232,102 @@ extern long strnlen_user(const char *src
 		__get_user_asm("lw", (ptr), __gu_val, __gu_err);	\
 		break;							\
 	default:							\
-		__gu_val = 0; __gu_err = -EINVAL;			\
+		/* __gu_val = 0; __gu_err = -EINVAL;*/ __gu_err = __user_bad();\
 	}								\
 	x = (__typeof__(*(ptr))) __gu_val;				\
 	__gu_err;							\
 })
 
-#define __get_user_asm(insn, __gu_ptr, __gu_val, __gu_err)		\
+
+#define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err)	\
+({								\
+	__asm__ __volatile__ (					\
+			"1:"	insn	" %1, %2, r0;"		\
+			"	addk	%0, r0, r0;"		\
+			"2:			"		\
+			__FIXUP_SECTION				\
+			"3:	brid	2b;"			\
+			"	addik	%0, r0, %3;"		\
+			".previous;"				\
+			__EX_TABLE_SECTION			\
+			".word	1b,3b;"				\
+			".previous;"				\
+		: "=&r"(__gu_err)				\
+		: "r"(__gu_val), "r"(__gu_ptr), "i"(-EFAULT)	\
+	);							\
+})
+
+#define __put_user_asm_8(__gu_ptr, __gu_val, __gu_err)		\
+({								\
+	__asm__ __volatile__ ("	lwi	%0, %1, 0;"		\
+			"1:	swi	%0, %2, 0;"		\
+			"	lwi	%0, %1, 4;"		\
+			"2:	swi	%0, %2, 4;"		\
+			"	addk	%0, r0, r0;"		\
+			"3:			"		\
+			__FIXUP_SECTION				\
+			"4:	brid	3b;"			\
+			"	addik	%0, r0, %3;"		\
+			".previous;"				\
+			__EX_TABLE_SECTION			\
+			".word	1b,4b,2b,4b;"			\
+			".previous;"				\
+		: "=&r"(__gu_err)				\
+		: "r"(&__gu_val), "r"(__gu_ptr), "i"(-EFAULT)	\
+		);						\
+})
+
+/**
+ * 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((x), (ptr), sizeof(*(ptr)))
+
+#define __put_user_check(x, ptr, size)					\
 ({									\
-	__asm__ __volatile__ (						\
-			"1:"	insn	" %1, %2, r0;			\
-				addk	%0, r0, r0;			\
-			2:						\
-			.section .fixup,\"ax\";				\
-			3:	brid	2b;				\
-				addik	%0, r0, %3;			\
-			.previous;					\
-			.section __ex_table,\"a\";			\
-			.word	1b,3b;					\
-			.previous;"					\
-		: "=r"(__gu_err), "=r"(__gu_val)			\
-		: "r"(__gu_ptr), "i"(-EFAULT)				\
-	);								\
+	typeof(*(ptr)) __pu_val;					\
+	typeof(*(ptr)) __user *__pu_addr = (ptr);			\
+	int __pu_err = 0;						\
+									\
+	__pu_val = (x);							\
+	if (access_ok(VERIFY_WRITE, __pu_addr, size)) {			\
+		switch (size) {						\
+		case 1:							\
+			__put_user_asm("sb", __pu_addr, __pu_val,	\
+				       __pu_err);			\
+			break;						\
+		case 2:							\
+			__put_user_asm("sh", __pu_addr, __pu_val,	\
+				       __pu_err);			\
+			break;						\
+		case 4:							\
+			__put_user_asm("sw", __pu_addr, __pu_val,	\
+				       __pu_err);			\
+			break;						\
+		case 8:							\
+			__put_user_asm_8(__pu_addr, __pu_val, __pu_err);\
+			break;						\
+		default:						\
+			__pu_err = __user_bad();			\
+			break;						\
+		}							\
+	} else {							\
+		__pu_err = -EFAULT;					\
+	}								\
+	__pu_err;							\
 })
 
 #define __put_user(x, ptr)						\
@@ -195,7 +338,7 @@ extern long strnlen_user(const char *src
 	case 1:								\
 		__put_user_asm("sb", (ptr), __gu_val, __gu_err);	\
 		break;							\
-	case 2: 							\
+	case 2:								\
 		__put_user_asm("sh", (ptr), __gu_val, __gu_err);	\
 		break;							\
 	case 4:								\
@@ -205,121 +348,70 @@ extern long strnlen_user(const char *src
 		__put_user_asm_8((ptr), __gu_val, __gu_err);		\
 		break;							\
 	default:							\
-		__gu_err = -EINVAL;					\
+		/*__gu_err = -EINVAL;*/	__gu_err = __user_bad();	\
 	}								\
 	__gu_err;							\
 })
 
-#define __put_user_asm_8(__gu_ptr, __gu_val, __gu_err)	\
-({							\
-__asm__ __volatile__ ("	lwi	%0, %1, 0;		\
-		1:	swi	%0, %2, 0;		\
-			lwi	%0, %1, 4;		\
-		2:	swi	%0, %2, 4;		\
-			addk	%0,r0,r0;		\
-		3:					\
-		.section .fixup,\"ax\";			\
-		4:	brid	3b;			\
-			addik	%0, r0, %3;		\
-		.previous;				\
-		.section __ex_table,\"a\";		\
-		.word	1b,4b,2b,4b;			\
-		.previous;"				\
-	: "=&r"(__gu_err)				\
-	: "r"(&__gu_val),				\
-	"r"(__gu_ptr), "i"(-EFAULT)			\
-	);						\
-})
-
-#define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err)	\
-({								\
-	__asm__ __volatile__ (					\
-			"1:"	insn	" %1, %2, r0;		\
-				addk	%0, r0, r0;		\
-			2:					\
-			.section .fixup,\"ax\";			\
-			3:	brid	2b;			\
-				addik	%0, r0, %3;		\
-			.previous;				\
-			.section __ex_table,\"a\";		\
-			.word	1b,3b;				\
-			.previous;"				\
-		: "=r"(__gu_err)				\
-		: "r"(__gu_val), "r"(__gu_ptr), "i"(-EFAULT)	\
-	);							\
-})
-
-/*
- * Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail.
- */
-static inline int clear_user(char *to, int size)
-{
-	if (size && access_ok(VERIFY_WRITE, to, size)) {
-		__asm__ __volatile__ ("				\
-				1:				\
-					sb	r0, %2, r0;	\
-					addik	%0, %0, -1;	\
-					bneid	%0, 1b;		\
-					addik	%2, %2, 1;	\
-				2:				\
-				.section __ex_table,\"a\";	\
-				.word	1b,2b;			\
-				.section .text;"		\
-			: "=r"(size)				\
-			: "0"(size), "r"(to)
-		);
-	}
-	return size;
-}
 
-#define __copy_from_user(to, from, n)	copy_from_user((to), (from), (n))
+/* copy_to_from_user */
+#define __copy_from_user(to, from, n)	\
+	__copy_tofrom_user((__force void __user *)(to), \
+				(void __user *)(from), (n))
 #define __copy_from_user_inatomic(to, from, n) \
 		copy_from_user((to), (from), (n))
 
-#define copy_to_user(to, from, n)					\
-	(access_ok(VERIFY_WRITE, (to), (n)) ?				\
-		__copy_tofrom_user((void __user *)(to),			\
-			(__force const void __user *)(from), (n))	\
-		: -EFAULT)
+static inline long copy_from_user(void *to,
+		const void __user *from, unsigned long n)
+{
+	might_sleep();
+	if (access_ok(VERIFY_READ, from, n))
+		return __copy_from_user(to, from, n);
+	return n;
+}
 
-#define __copy_to_user(to, from, n)	copy_to_user((to), (from), (n))
+#define __copy_to_user(to, from, n)	\
+		__copy_tofrom_user((void __user *)(to), \
+			(__force const void __user *)(from), (n))
 #define __copy_to_user_inatomic(to, from, n)	copy_to_user((to), (from), (n))
 
-#define copy_from_user(to, from, n)					\
-	(access_ok(VERIFY_READ, (from), (n)) ?				\
-		__copy_tofrom_user((__force void __user *)(to),		\
-			(void __user *)(from), (n))			\
-		: -EFAULT)
+static inline long copy_to_user(void __user *to,
+		const void *from, unsigned long n)
+{
+	might_sleep();
+	if (access_ok(VERIFY_WRITE, to, n))
+		return __copy_to_user(to, from, n);
+	return n;
+}
 
+/*
+ * Copy a null terminated string from userspace.
+ */
 extern int __strncpy_user(char *to, const char __user *from, int len);
-extern int __strnlen_user(const char __user *sstr, int len);
 
-#define strncpy_from_user(to, from, len)	\
-		(access_ok(VERIFY_READ, from, 1) ?	\
-			__strncpy_user(to, from, len) : -EFAULT)
-#define strnlen_user(str, len)	\
-		(access_ok(VERIFY_READ, str, 1) ? __strnlen_user(str, len) : 0)
-
-#endif /* CONFIG_MMU */
+#define __strncpy_from_user	__strncpy_user
 
-extern unsigned long __copy_tofrom_user(void __user *to,
-		const void __user *from, unsigned long size);
+static inline long
+strncpy_from_user(char *dst, const char __user *src, long count)
+{
+	if (!access_ok(VERIFY_READ, src, 1))
+		return -EFAULT;
+	return __strncpy_from_user(dst, src, 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.
+ * Return the size of a string (including the ending 0)
  *
- * 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.
+ * Return 0 on exception, a value greater than N if too long
  */
-struct exception_table_entry {
-	unsigned long insn, fixup;
-};
+extern int __strnlen_user(const char __user *sstr, int len);
+
+static inline long strnlen_user(const char __user *src, long n)
+{
+	if (!access_ok(VERIFY_READ, src, 1))
+		return 0;
+	return __strnlen_user(src, n);
+}
 
 #endif  /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/Kconfig linux-libre-2.6.34-gnu1/arch/microblaze/Kconfig
--- linux-libre-2.6.33-gnu1/arch/microblaze/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,8 @@ config MICROBLAZE
 	select USB_ARCH_HAS_EHCI
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select HAVE_OPROFILE
+	select HAVE_DMA_ATTRS
+	select HAVE_DMA_API_DEBUG
 	select TRACING_SUPPORT
 
 config SWAP
@@ -73,12 +75,6 @@ config LOCKDEP_SUPPORT
 config HAVE_LATENCYTOP_SUPPORT
 	def_bool y
 
-config PCI
-	def_bool n
-
-config NO_DMA
-	def_bool y
-
 config DTC
 	def_bool y
 
@@ -130,6 +126,7 @@ config CMDLINE_FORCE
 
 config OF
 	def_bool y
+	select OF_FLATTREE
 
 config PROC_DEVICETREE
 	bool "Support for device tree in /proc"
@@ -145,7 +142,6 @@ menu "Advanced setup"
 
 config ADVANCED_OPTIONS
 	bool "Prompt for advanced kernel configuration options"
-	depends on MMU
 	help
 	  This option will enable prompting for a variety of advanced kernel
 	  configuration options.  These options can cause the kernel to not
@@ -157,6 +153,15 @@ config ADVANCED_OPTIONS
 comment "Default settings for advanced configuration options are used"
 	depends on !ADVANCED_OPTIONS
 
+config XILINX_UNCACHED_SHADOW
+	bool "Are you using uncached shadow for RAM ?"
+	depends on ADVANCED_OPTIONS && !MMU
+	default n
+	help
+	  This is needed to be able to allocate uncachable memory regions.
+	  The feature requires the design to define the RAM memory controller
+	  window to be twice as large as the actual physical memory.
+
 config HIGHMEM_START_BOOL
 	bool "Set high memory pool address"
 	depends on ADVANCED_OPTIONS && HIGHMEM
@@ -174,7 +179,7 @@ config HIGHMEM_START
 
 config LOWMEM_SIZE_BOOL
 	bool "Set maximum low memory"
-	depends on ADVANCED_OPTIONS
+	depends on ADVANCED_OPTIONS && MMU
 	help
 	  This option allows you to set the maximum amount of memory which
 	  will be used as "low memory", that is, memory which the kernel can
@@ -186,7 +191,6 @@ config LOWMEM_SIZE_BOOL
 
 config LOWMEM_SIZE
 	hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL
-	depends on MMU
 	default "0x30000000"
 
 config KERNEL_START_BOOL
@@ -207,7 +211,7 @@ config KERNEL_START
 
 config TASK_SIZE_BOOL
 	bool "Set custom user task size"
-	depends on ADVANCED_OPTIONS
+	depends on ADVANCED_OPTIONS && MMU
 	help
 	  This option allows you to set the amount of virtual address space
 	  allocated to user tasks.  This can be useful in optimizing the
@@ -217,42 +221,34 @@ config TASK_SIZE_BOOL
 
 config TASK_SIZE
 	hex "Size of user task space" if TASK_SIZE_BOOL
-	depends on MMU
 	default "0x80000000"
 
-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 the consistent memory pool.  This pool of virtual
-	  memory is used to make consistent memory allocations.
+endmenu
 
-config CONSISTENT_START
-	hex "Base virtual address of consistent memory pool" if CONSISTENT_START_BOOL
-	depends on MMU
-	default "0xff100000" if NOT_COHERENT_CACHE
+source "mm/Kconfig"
 
-config CONSISTENT_SIZE_BOOL
-	bool "Set custom consistent memory pool size"
-	depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
-	help
-	  This option allows you to set the size of the the
-	  consistent memory pool.  This pool of virtual memory
-	  is used to make consistent memory allocations.
+menu "Exectuable file formats"
 
-config CONSISTENT_SIZE
-	hex "Size of consistent memory pool" if CONSISTENT_SIZE_BOOL
-	depends on MMU
-	default "0x00200000" if NOT_COHERENT_CACHE
+source "fs/Kconfig.binfmt"
 
 endmenu
 
-source "mm/Kconfig"
+menu "Bus Options"
 
-menu "Exectuable file formats"
+config PCI
+	bool "PCI support"
 
-source "fs/Kconfig.binfmt"
+config PCI_DOMAINS
+	def_bool PCI
+
+config PCI_SYSCALL
+	def_bool PCI
+
+config PCI_XILINX
+	bool "Xilinx PCI host bridge support"
+	depends on PCI
+
+source "drivers/pci/Kconfig"
 
 endmenu
 
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/asm-offsets.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/asm-offsets.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/asm-offsets.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/asm-offsets.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/hardirq.h>
 #include <linux/thread_info.h>
 #include <linux/kbuild.h>
+#include <asm/cpuinfo.h>
 
 int main(int argc, char *argv[])
 {
@@ -90,6 +91,7 @@ int main(int argc, char *argv[])
 	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
 	DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
 	DEFINE(TI_CPU_CONTEXT, offsetof(struct thread_info, cpu_context));
+	DEFINE(TI_PREEMPT_COUNT, offsetof(struct thread_info, preempt_count));
 	BLANK();
 
 	/* struct cpu_context */
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/cache.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/cpu/cache.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/cache.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/cpu/cache.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,25 +15,6 @@
 #include <asm/cpuinfo.h>
 #include <asm/pvr.h>
 
-static inline void __invalidate_flush_icache(unsigned int addr)
-{
-	__asm__ __volatile__ ("wic	%0, r0;"	\
-					: : "r" (addr));
-}
-
-static inline void __flush_dcache(unsigned int addr)
-{
-	__asm__ __volatile__ ("wdc.flush	%0, r0;"	\
-					: : "r" (addr));
-}
-
-static inline void __invalidate_dcache(unsigned int baseaddr,
-						unsigned int offset)
-{
-	__asm__ __volatile__ ("wdc.clear	%0, %1;"	\
-					: : "r" (baseaddr), "r" (offset));
-}
-
 static inline void __enable_icache_msr(void)
 {
 	__asm__ __volatile__ ("	msrset	r0, %0;		\
@@ -115,13 +96,16 @@ static inline void __disable_dcache_noms
 }
 
 
-/* Helper macro for computing the limits of cache range loops */
+/* Helper macro for computing the limits of cache range loops
+ *
+ * End address can be unaligned which is OK for C implementation.
+ * ASM implementation align it in ASM macros
+ */
 #define CACHE_LOOP_LIMITS(start, end, cache_line_length, cache_size)	\
 do {									\
 	int align = ~(cache_line_length - 1);				\
 	end = min(start + cache_size, end);				\
 	start &= align;							\
-	end = ((end & align) + cache_line_length);			\
 } while (0);
 
 /*
@@ -130,9 +114,9 @@ do {									\
  */
 #define CACHE_ALL_LOOP(cache_size, line_length, op)			\
 do {									\
-	unsigned int len = cache_size;					\
+	unsigned int len = cache_size - line_length;			\
 	int step = -line_length;					\
-	BUG_ON(step >= 0);						\
+	WARN_ON(step >= 0);						\
 									\
 	__asm__ __volatile__ (" 1:      " #op " %0, r0;			\
 					bgtid   %0, 1b;			\
@@ -141,30 +125,26 @@ do {									\
 					: "memory");			\
 } while (0);
 
-
-#define CACHE_ALL_LOOP2(cache_size, line_length, op)			\
-do {									\
-	unsigned int len = cache_size;					\
-	int step = -line_length;					\
-	BUG_ON(step >= 0);						\
-									\
-	__asm__ __volatile__ (" 1:      " #op " r0, %0;			\
-					bgtid   %0, 1b;			\
-					addk    %0, %0, %1;		\
-					" : : "r" (len), "r" (step)	\
-					: "memory");			\
-} while (0);
-
-/* for wdc.flush/clear */
+/* Used for wdc.flush/clear which can use rB for offset which is not possible
+ * to use for simple wdc or wic.
+ *
+ * start address is cache aligned
+ * end address is not aligned, if end is aligned then I have to substract
+ * cacheline length because I can't flush/invalidate the next cacheline.
+ * If is not, I align it because I will flush/invalidate whole line.
+ */
 #define CACHE_RANGE_LOOP_2(start, end, line_length, op)			\
 do {									\
 	int step = -line_length;					\
-	int count = end - start;					\
-	BUG_ON(count <= 0);						\
+	int align = ~(line_length - 1);					\
+	int count;							\
+	end = ((end & align) == end) ? end - line_length : end & align;	\
+	count = end - start;						\
+	WARN_ON(count < 0);						\
 									\
-	__asm__ __volatile__ (" 1:	" #op " %0, %1;			\
-					bgtid   %1, 1b;			\
-					addk    %1, %1, %2;		\
+	__asm__ __volatile__ (" 1:	" #op "	%0, %1;			\
+					bgtid	%1, 1b;			\
+					addk	%1, %1, %2;		\
 					" : : "r" (start), "r" (count),	\
 					"r" (step) : "memory");		\
 } while (0);
@@ -173,9 +153,11 @@ do {									\
 #define CACHE_RANGE_LOOP_1(start, end, line_length, op)			\
 do {									\
 	int volatile temp;						\
-	BUG_ON(end - start <= 0);					\
+	int align = ~(line_length - 1);					\
+	end = ((end & align) == end) ? end - line_length : end & align;	\
+	WARN_ON(end - start < 0);					\
 									\
-	__asm__ __volatile__ (" 1:	" #op " %1, r0;			\
+	__asm__ __volatile__ (" 1:	" #op "	%1, r0;			\
 					cmpu	%0, %1, %2;		\
 					bgtid	%0, 1b;			\
 					addk	%1, %1, %3;		\
@@ -183,10 +165,14 @@ do {									\
 					"r" (line_length) : "memory");	\
 } while (0);
 
+#define ASM_LOOP
+
 static void __flush_icache_range_msr_irq(unsigned long start, unsigned long end)
 {
 	unsigned long flags;
-
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 				(unsigned int)start, (unsigned int) end);
 
@@ -196,8 +182,13 @@ static void __flush_icache_range_msr_irq
 	local_irq_save(flags);
 	__disable_icache_msr();
 
+#ifdef ASM_LOOP
 	CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
-
+#else
+	for (i = start; i < end; i += cpuinfo.icache_line_length)
+		__asm__ __volatile__ ("wic	%0, r0;"	\
+				: : "r" (i));
+#endif
 	__enable_icache_msr();
 	local_irq_restore(flags);
 }
@@ -206,7 +197,9 @@ static void __flush_icache_range_nomsr_i
 				unsigned long end)
 {
 	unsigned long flags;
-
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 				(unsigned int)start, (unsigned int) end);
 
@@ -216,7 +209,13 @@ static void __flush_icache_range_nomsr_i
 	local_irq_save(flags);
 	__disable_icache_nomsr();
 
+#ifdef ASM_LOOP
 	CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
+#else
+	for (i = start; i < end; i += cpuinfo.icache_line_length)
+		__asm__ __volatile__ ("wic	%0, r0;"	\
+				: : "r" (i));
+#endif
 
 	__enable_icache_nomsr();
 	local_irq_restore(flags);
@@ -225,25 +224,41 @@ static void __flush_icache_range_nomsr_i
 static void __flush_icache_range_noirq(unsigned long start,
 				unsigned long end)
 {
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 				(unsigned int)start, (unsigned int) end);
 
 	CACHE_LOOP_LIMITS(start, end,
 			cpuinfo.icache_line_length, cpuinfo.icache_size);
+#ifdef ASM_LOOP
 	CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
+#else
+	for (i = start; i < end; i += cpuinfo.icache_line_length)
+		__asm__ __volatile__ ("wic	%0, r0;"	\
+				: : "r" (i));
+#endif
 }
 
 static void __flush_icache_all_msr_irq(void)
 {
 	unsigned long flags;
-
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s\n", __func__);
 
 	local_irq_save(flags);
 	__disable_icache_msr();
-
+#ifdef ASM_LOOP
 	CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
-
+#else
+	for (i = 0; i < cpuinfo.icache_size;
+		 i += cpuinfo.icache_line_length)
+			__asm__ __volatile__ ("wic	%0, r0;" \
+					: : "r" (i));
+#endif
 	__enable_icache_msr();
 	local_irq_restore(flags);
 }
@@ -251,35 +266,59 @@ static void __flush_icache_all_msr_irq(v
 static void __flush_icache_all_nomsr_irq(void)
 {
 	unsigned long flags;
-
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s\n", __func__);
 
 	local_irq_save(flags);
 	__disable_icache_nomsr();
-
+#ifdef ASM_LOOP
 	CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
-
+#else
+	for (i = 0; i < cpuinfo.icache_size;
+		 i += cpuinfo.icache_line_length)
+			__asm__ __volatile__ ("wic	%0, r0;" \
+					: : "r" (i));
+#endif
 	__enable_icache_nomsr();
 	local_irq_restore(flags);
 }
 
 static void __flush_icache_all_noirq(void)
 {
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s\n", __func__);
+#ifdef ASM_LOOP
 	CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
+#else
+	for (i = 0; i < cpuinfo.icache_size;
+		 i += cpuinfo.icache_line_length)
+			__asm__ __volatile__ ("wic	%0, r0;" \
+					: : "r" (i));
+#endif
 }
 
 static void __invalidate_dcache_all_msr_irq(void)
 {
 	unsigned long flags;
-
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s\n", __func__);
 
 	local_irq_save(flags);
 	__disable_dcache_msr();
-
+#ifdef ASM_LOOP
 	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
-
+#else
+	for (i = 0; i < cpuinfo.dcache_size;
+		 i += cpuinfo.dcache_line_length)
+			__asm__ __volatile__ ("wdc	%0, r0;" \
+					: : "r" (i));
+#endif
 	__enable_dcache_msr();
 	local_irq_restore(flags);
 }
@@ -287,60 +326,111 @@ static void __invalidate_dcache_all_msr_
 static void __invalidate_dcache_all_nomsr_irq(void)
 {
 	unsigned long flags;
-
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s\n", __func__);
 
 	local_irq_save(flags);
 	__disable_dcache_nomsr();
-
+#ifdef ASM_LOOP
 	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
-
+#else
+	for (i = 0; i < cpuinfo.dcache_size;
+		 i += cpuinfo.dcache_line_length)
+			__asm__ __volatile__ ("wdc	%0, r0;" \
+					: : "r" (i));
+#endif
 	__enable_dcache_nomsr();
 	local_irq_restore(flags);
 }
 
 static void __invalidate_dcache_all_noirq_wt(void)
 {
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s\n", __func__);
+#ifdef ASM_LOOP
 	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc)
+#else
+	for (i = 0; i < cpuinfo.dcache_size;
+		 i += cpuinfo.dcache_line_length)
+			__asm__ __volatile__ ("wdc	%0, r0;" \
+					: : "r" (i));
+#endif
 }
 
-/* FIXME this is weird - should be only wdc but not work
- * MS: I am getting bus errors and other weird things */
+/* FIXME It is blindly invalidation as is expected
+ * but can't be called on noMMU in microblaze_cache_init below
+ *
+ * MS: noMMU kernel won't boot if simple wdc is used
+ * The reason should be that there are discared data which kernel needs
+ */
 static void __invalidate_dcache_all_wb(void)
 {
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s\n", __func__);
-	CACHE_ALL_LOOP2(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
-					wdc.clear)
+#ifdef ASM_LOOP
+	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
+					wdc)
+#else
+	for (i = 0; i < cpuinfo.dcache_size;
+		 i += cpuinfo.dcache_line_length)
+			__asm__ __volatile__ ("wdc	%0, r0;" \
+					: : "r" (i));
+#endif
 }
 
 static void __invalidate_dcache_range_wb(unsigned long start,
 						unsigned long end)
 {
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 				(unsigned int)start, (unsigned int) end);
 
 	CACHE_LOOP_LIMITS(start, end,
 			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+#ifdef ASM_LOOP
 	CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.clear);
+#else
+	for (i = start; i < end; i += cpuinfo.dcache_line_length)
+		__asm__ __volatile__ ("wdc.clear	%0, r0;"	\
+				: : "r" (i));
+#endif
 }
 
 static void __invalidate_dcache_range_nomsr_wt(unsigned long start,
 							unsigned long end)
 {
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 				(unsigned int)start, (unsigned int) end);
 	CACHE_LOOP_LIMITS(start, end,
 			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
 
+#ifdef ASM_LOOP
 	CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
+#else
+	for (i = start; i < end; i += cpuinfo.dcache_line_length)
+		__asm__ __volatile__ ("wdc	%0, r0;"	\
+				: : "r" (i));
+#endif
 }
 
 static void __invalidate_dcache_range_msr_irq_wt(unsigned long start,
 							unsigned long end)
 {
 	unsigned long flags;
-
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 				(unsigned int)start, (unsigned int) end);
 	CACHE_LOOP_LIMITS(start, end,
@@ -349,7 +439,13 @@ static void __invalidate_dcache_range_ms
 	local_irq_save(flags);
 	__disable_dcache_msr();
 
+#ifdef ASM_LOOP
 	CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
+#else
+	for (i = start; i < end; i += cpuinfo.dcache_line_length)
+		__asm__ __volatile__ ("wdc	%0, r0;"	\
+				: : "r" (i));
+#endif
 
 	__enable_dcache_msr();
 	local_irq_restore(flags);
@@ -359,7 +455,9 @@ static void __invalidate_dcache_range_no
 							unsigned long end)
 {
 	unsigned long flags;
-
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 				(unsigned int)start, (unsigned int) end);
 
@@ -369,7 +467,13 @@ static void __invalidate_dcache_range_no
 	local_irq_save(flags);
 	__disable_dcache_nomsr();
 
+#ifdef ASM_LOOP
 	CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
+#else
+	for (i = start; i < end; i += cpuinfo.dcache_line_length)
+		__asm__ __volatile__ ("wdc	%0, r0;"	\
+				: : "r" (i));
+#endif
 
 	__enable_dcache_nomsr();
 	local_irq_restore(flags);
@@ -377,19 +481,38 @@ static void __invalidate_dcache_range_no
 
 static void __flush_dcache_all_wb(void)
 {
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s\n", __func__);
+#ifdef ASM_LOOP
 	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
 				wdc.flush);
+#else
+	for (i = 0; i < cpuinfo.dcache_size;
+		 i += cpuinfo.dcache_line_length)
+			__asm__ __volatile__ ("wdc.flush	%0, r0;" \
+					: : "r" (i));
+#endif
 }
 
 static void __flush_dcache_range_wb(unsigned long start, unsigned long end)
 {
+#ifndef ASM_LOOP
+	int i;
+#endif
 	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 				(unsigned int)start, (unsigned int) end);
 
 	CACHE_LOOP_LIMITS(start, end,
 			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+#ifdef ASM_LOOP
 	CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.flush);
+#else
+	for (i = start; i < end; i += cpuinfo.dcache_line_length)
+		__asm__ __volatile__ ("wdc.flush	%0, r0;"	\
+				: : "r" (i));
+#endif
 }
 
 /* struct for wb caches and for wt caches */
@@ -493,7 +616,7 @@ const struct scache wt_nomsr_noirq = {
 #define CPUVER_7_20_A	0x0c
 #define CPUVER_7_20_D	0x0f
 
-#define INFO(s)	printk(KERN_INFO "cache: " s " \n");
+#define INFO(s)	printk(KERN_INFO "cache: " s "\n");
 
 void microblaze_cache_init(void)
 {
@@ -532,4 +655,13 @@ void microblaze_cache_init(void)
 			}
 		}
 	}
+/* FIXME Invalidation is done in U-BOOT
+ * WT cache: Data is already written to main memory
+ * WB cache: Discard data on noMMU which caused that kernel doesn't boot
+ */
+	/* invalidate_dcache(); */
+	enable_dcache();
+
+	invalidate_icache();
+	enable_icache();
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/cpuinfo.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/cpu/cpuinfo.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/cpuinfo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/cpu/cpuinfo.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <asm/cpuinfo.h>
 #include <asm/pvr.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/mb.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/cpu/mb.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/mb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/cpu/mb.c	2010-05-16 17:17:36.000000000 -0400
@@ -98,15 +98,17 @@ static int show_cpuinfo(struct seq_file
 
 	if (cpuinfo.use_icache)
 		count += seq_printf(m,
-				"Icache:\t\t%ukB\n",
-				cpuinfo.icache_size >> 10);
+				"Icache:\t\t%ukB\tline length:\t%dB\n",
+				cpuinfo.icache_size >> 10,
+				cpuinfo.icache_line_length);
 	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);
+				"Dcache:\t\t%ukB\tline length:\t%dB\n",
+				cpuinfo.dcache_size >> 10,
+				cpuinfo.dcache_line_length);
 		if (cpuinfo.dcache_wb)
 			count += seq_printf(m, "\t\twrite-back\n");
 		else
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/dma.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/dma.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/dma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2009-2010 PetaLogix
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation
+ *
+ * Provide default implementations of the DMA mapping callbacks for
+ * directly mapped busses.
+ */
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
+#include <linux/dma-debug.h>
+#include <asm/bug.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Generic direct DMA implementation
+ *
+ * This implementation supports a per-device offset that can be applied if
+ * the address at which memory is visible to devices is not 0. Platform code
+ * can set archdata.dma_data to an unsigned long holding the offset. By
+ * default the offset is PCI_DRAM_OFFSET.
+ */
+static inline void __dma_sync_page(unsigned long paddr, unsigned long offset,
+				size_t size, enum dma_data_direction direction)
+{
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		flush_dcache_range(paddr + offset, paddr + offset + size);
+		break;
+	case DMA_FROM_DEVICE:
+		invalidate_dcache_range(paddr + offset, paddr + offset + size);
+		break;
+	default:
+		BUG();
+	}
+}
+
+static unsigned long get_dma_direct_offset(struct device *dev)
+{
+	if (likely(dev))
+		return (unsigned long)dev->archdata.dma_data;
+
+	return PCI_DRAM_OFFSET; /* FIXME Not sure if is correct */
+}
+
+#define NOT_COHERENT_CACHE
+
+static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
+				dma_addr_t *dma_handle, gfp_t flag)
+{
+#ifdef NOT_COHERENT_CACHE
+	return consistent_alloc(flag, size, dma_handle);
+#else
+	void *ret;
+	struct page *page;
+	int node = dev_to_node(dev);
+
+	/* ignore region specifiers */
+	flag  &= ~(__GFP_HIGHMEM);
+
+	page = alloc_pages_node(node, flag, get_order(size));
+	if (page == NULL)
+		return NULL;
+	ret = page_address(page);
+	memset(ret, 0, size);
+	*dma_handle = virt_to_phys(ret) + get_dma_direct_offset(dev);
+
+	return ret;
+#endif
+}
+
+static void dma_direct_free_coherent(struct device *dev, size_t size,
+			      void *vaddr, dma_addr_t dma_handle)
+{
+#ifdef NOT_COHERENT_CACHE
+	consistent_free(size, vaddr);
+#else
+	free_pages((unsigned long)vaddr, get_order(size));
+#endif
+}
+
+static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
+			     int nents, enum dma_data_direction direction,
+			     struct dma_attrs *attrs)
+{
+	struct scatterlist *sg;
+	int i;
+
+	/* FIXME this part of code is untested */
+	for_each_sg(sgl, sg, nents, i) {
+		sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev);
+		sg->dma_length = sg->length;
+		__dma_sync_page(page_to_phys(sg_page(sg)), sg->offset,
+							sg->length, direction);
+	}
+
+	return nents;
+}
+
+static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg,
+				int nents, enum dma_data_direction direction,
+				struct dma_attrs *attrs)
+{
+}
+
+static int dma_direct_dma_supported(struct device *dev, u64 mask)
+{
+	return 1;
+}
+
+static inline dma_addr_t dma_direct_map_page(struct device *dev,
+					     struct page *page,
+					     unsigned long offset,
+					     size_t size,
+					     enum dma_data_direction direction,
+					     struct dma_attrs *attrs)
+{
+	__dma_sync_page(page_to_phys(page), offset, size, direction);
+	return page_to_phys(page) + offset + get_dma_direct_offset(dev);
+}
+
+static inline void dma_direct_unmap_page(struct device *dev,
+					 dma_addr_t dma_address,
+					 size_t size,
+					 enum dma_data_direction direction,
+					 struct dma_attrs *attrs)
+{
+/* There is not necessary to do cache cleanup
+ *
+ * phys_to_virt is here because in __dma_sync_page is __virt_to_phys and
+ * dma_address is physical address
+ */
+	__dma_sync_page(dma_address, 0 , size, direction);
+}
+
+struct dma_map_ops dma_direct_ops = {
+	.alloc_coherent	= dma_direct_alloc_coherent,
+	.free_coherent	= dma_direct_free_coherent,
+	.map_sg		= dma_direct_map_sg,
+	.unmap_sg	= dma_direct_unmap_sg,
+	.dma_supported	= dma_direct_dma_supported,
+	.map_page	= dma_direct_map_page,
+	.unmap_page	= dma_direct_unmap_page,
+};
+EXPORT_SYMBOL(dma_direct_ops);
+
+/* Number of entries preallocated for DMA-API debugging */
+#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
+
+static int __init dma_init(void)
+{
+       dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+
+       return 0;
+}
+fs_initcall(dma_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/entry-nommu.S linux-libre-2.6.34-gnu1/arch/microblaze/kernel/entry-nommu.S
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/entry-nommu.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/entry-nommu.S	2010-05-16 17:17:36.000000000 -0400
@@ -476,6 +476,8 @@ ENTRY(ret_from_fork)
 	nop
 
 work_pending:
+	enable_irq
+
 	andi	r11, r19, _TIF_NEED_RESCHED
 	beqi	r11, 1f
 	bralid	r15, schedule
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/entry.S linux-libre-2.6.34-gnu1/arch/microblaze/kernel/entry.S
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/entry.S	2010-05-16 17:17:36.000000000 -0400
@@ -305,7 +305,7 @@ C_ENTRY(_user_exception):
 	swi	r11, r1, PTO+PT_R1;		/* Store user SP.  */
 	addi	r11, r0, 1;
 	swi	r11, r0, TOPHYS(PER_CPU(KM));	/* Now we're in kernel-mode.  */
-2:	lwi	r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE));	/* get saved current */
+2:	lwi	CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
 	/* Save away the syscall number.  */
 	swi	r12, r1, PTO+PT_R0;
 	tovirt(r1,r1)
@@ -322,8 +322,7 @@ C_ENTRY(_user_exception):
 	rtid	r11, 0
 	nop
 3:
-	add	r11, r0, CURRENT_TASK	 /* Get current task ptr into r11 */
-	lwi	r11, r11, TS_THREAD_INFO /* get thread info */
+	lwi	r11, CURRENT_TASK, TS_THREAD_INFO /* get thread info */
 	lwi	r11, r11, TI_FLAGS	 /* get flags in thread info */
 	andi	r11, r11, _TIF_WORK_SYSCALL_MASK
 	beqi	r11, 4f
@@ -382,60 +381,50 @@ C_ENTRY(ret_from_trap):
 /* See if returning to kernel mode, if so, skip resched &c.  */
 	bnei	r11, 2f;
 
+	swi	r3, r1, PTO + PT_R3
+	swi	r4, r1, PTO + PT_R4
+
 	/* We're returning to user mode, so check for various conditions that
 	 * trigger rescheduling. */
-	# FIXME: Restructure all these flag checks.
-	add	r11, r0, CURRENT_TASK;	/* Get current task ptr into r11 */
-	lwi	r11, r11, TS_THREAD_INFO;	/* get thread info */
+	/* FIXME: Restructure all these flag checks. */
+	lwi	r11, CURRENT_TASK, TS_THREAD_INFO;	/* get thread info */
 	lwi	r11, r11, TI_FLAGS;		/* get flags in thread info */
 	andi	r11, r11, _TIF_WORK_SYSCALL_MASK
 	beqi	r11, 1f
 
-	swi	r3, r1, PTO + PT_R3
-	swi	r4, r1, PTO + PT_R4
 	brlid	r15, do_syscall_trace_leave
 	addik	r5, r1, PTO + PT_R0
-	lwi	r3, r1, PTO + PT_R3
-	lwi	r4, r1, PTO + PT_R4
 1:
-
 	/* We're returning to user mode, so check for various conditions that
 	 * trigger rescheduling. */
-	/* Get current task ptr into r11 */
-	add	r11, r0, CURRENT_TASK;	/* Get current task ptr into r11 */
-	lwi	r11, r11, TS_THREAD_INFO;	/* get thread info */
+	/* get thread info from current task */
+	lwi	r11, CURRENT_TASK, TS_THREAD_INFO;
 	lwi	r11, r11, TI_FLAGS;		/* get flags in thread info */
 	andi	r11, r11, _TIF_NEED_RESCHED;
 	beqi	r11, 5f;
 
-	swi	r3, r1, PTO + PT_R3; /* store syscall result */
-	swi	r4, r1, PTO + PT_R4;
 	bralid	r15, schedule;	/* Call scheduler */
 	nop;				/* delay slot */
-	lwi	r3, r1, PTO + PT_R3; /* restore syscall result */
-	lwi	r4, r1, PTO + PT_R4;
 
 	/* Maybe handle a signal */
-5:	add	r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
-	lwi	r11, r11, TS_THREAD_INFO;	/* get thread info */
+5:	/* get thread info from current task*/
+	lwi	r11, CURRENT_TASK, TS_THREAD_INFO;
 	lwi	r11, r11, TI_FLAGS;	/* get flags in thread info */
 	andi	r11, r11, _TIF_SIGPENDING;
 	beqi	r11, 1f;		/* Signals to handle, handle them */
 
-	swi	r3, r1, PTO + PT_R3; /* store syscall result */
-	swi	r4, r1, PTO + PT_R4;
 	la	r5, r1, PTO;		/* Arg 1: struct pt_regs *regs */
-	add	r6, r0, r0;		/* Arg 2: sigset_t *oldset */
 	addi	r7, r0, 1;		/* Arg 3: int in_syscall */
 	bralid	r15, do_signal;	/* Handle any signals */
-	nop;
+	add	r6, r0, r0;		/* Arg 2: sigset_t *oldset */
+
+/* Finally, return to user state.  */
+1:
 	lwi	r3, r1, PTO + PT_R3; /* restore syscall result */
 	lwi	r4, r1, PTO + PT_R4;
 
-/* Finally, return to user state.  */
-1:	swi	r0, r0, PER_CPU(KM);	/* Now officially in user state. */
-	add	r11, r0, CURRENT_TASK;	/* Get current task ptr into r11 */
-	swi	r11, r0, PER_CPU(CURRENT_SAVE); /* save current */
+	swi	r0, r0, PER_CPU(KM);	/* Now officially in user state. */
+	swi	CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
 	VM_OFF;
 	tophys(r1,r1);
 	RESTORE_REGS;
@@ -565,7 +554,7 @@ C_ENTRY(sys_rt_sigreturn_wrapper):
 	swi	r11, r1, PTO+PT_R1; /* Store user SP.  */		\
 	addi	r11, r0, 1;						\
 	swi	r11, r0, TOPHYS(PER_CPU(KM)); /* Now we're in kernel-mode.*/\
-2:	lwi	r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\
+2:	lwi	CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));	\
 	/* Save away the syscall number.  */				\
 	swi	r0, r1, PTO+PT_R0;					\
 	tovirt(r1,r1)
@@ -673,9 +662,7 @@ C_ENTRY(ret_from_exc):
 
 	/* We're returning to user mode, so check for various conditions that
 	   trigger rescheduling. */
-	/* Get current task ptr into r11 */
-	add	r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
-	lwi	r11, r11, TS_THREAD_INFO;	/* get thread info */
+	lwi	r11, CURRENT_TASK, TS_THREAD_INFO;	/* get thread info */
 	lwi	r11, r11, TI_FLAGS;	/* get flags in thread info */
 	andi	r11, r11, _TIF_NEED_RESCHED;
 	beqi	r11, 5f;
@@ -685,8 +672,7 @@ C_ENTRY(ret_from_exc):
 	nop;				/* delay slot */
 
 	/* Maybe handle a signal */
-5:	add	r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
-	lwi	r11, r11, TS_THREAD_INFO;	/* get thread info */
+5:	lwi	r11, CURRENT_TASK, TS_THREAD_INFO;	/* get thread info */
 	lwi	r11, r11, TI_FLAGS;	/* get flags in thread info */
 	andi	r11, r11, _TIF_SIGPENDING;
 	beqi	r11, 1f;		/* Signals to handle, handle them */
@@ -705,15 +691,13 @@ C_ENTRY(ret_from_exc):
 	 * store return registers separately because this macros is use
 	 * for others exceptions */
 	la	r5, r1, PTO;		/* Arg 1: struct pt_regs *regs */
-	add	r6, r0, r0;		/* Arg 2: sigset_t *oldset */
 	addi	r7, r0, 0;		/* Arg 3: int in_syscall */
 	bralid	r15, do_signal;	/* Handle any signals */
-	nop;
+	add	r6, r0, r0;		/* Arg 2: sigset_t *oldset */
 
 /* Finally, return to user state.  */
 1:	swi	r0, r0, PER_CPU(KM);	/* Now officially in user state. */
-	add	r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
-	swi	r11, r0, PER_CPU(CURRENT_SAVE); /* save current */
+	swi	CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
 	VM_OFF;
 	tophys(r1,r1);
 
@@ -802,7 +786,7 @@ C_ENTRY(_interrupt):
 	swi	r11, r0, TOPHYS(PER_CPU(KM));
 
 2:
-	lwi	r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
+	lwi	CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
 	swi	r0, r1, PTO + PT_R0;
 	tovirt(r1,r1)
 	la	r5, r1, PTO;
@@ -817,8 +801,7 @@ ret_from_irq:
 	lwi	r11, r1, PTO + PT_MODE;
 	bnei	r11, 2f;
 
-	add	r11, r0, CURRENT_TASK;
-	lwi	r11, r11, TS_THREAD_INFO;
+	lwi	r11, CURRENT_TASK, TS_THREAD_INFO;
 	lwi	r11, r11, TI_FLAGS; /* MS: get flags from thread info */
 	andi	r11, r11, _TIF_NEED_RESCHED;
 	beqi	r11, 5f
@@ -826,8 +809,7 @@ ret_from_irq:
 	nop; /* delay slot */
 
     /* Maybe handle a signal */
-5:	add	r11, r0, CURRENT_TASK;
-	lwi	r11, r11, TS_THREAD_INFO; /* MS: get thread info */
+5:	lwi	r11, CURRENT_TASK, TS_THREAD_INFO; /* MS: get thread info */
 	lwi	r11, r11, TI_FLAGS; /* get flags in thread info */
 	andi	r11, r11, _TIF_SIGPENDING;
 	beqid	r11, no_intr_resched
@@ -842,8 +824,7 @@ no_intr_resched:
     /* Disable interrupts, we are now committed to the state restore */
 	disable_irq
 	swi	r0, r0, PER_CPU(KM); /* MS: Now officially in user state. */
-	add	r11, r0, CURRENT_TASK;
-	swi	r11, r0, PER_CPU(CURRENT_SAVE);
+	swi	CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE);
 	VM_OFF;
 	tophys(r1,r1);
 	lwi	r3, r1, PTO + PT_R3; /* MS: restore saved r3, r4 registers */
@@ -853,7 +834,28 @@ no_intr_resched:
 	lwi	r1, r1, PT_R1 - PT_SIZE;
 	bri	6f;
 /* MS: Return to kernel state. */
-2:	VM_OFF /* MS: turn off MMU */
+2:
+#ifdef CONFIG_PREEMPT
+	lwi	r11, CURRENT_TASK, TS_THREAD_INFO;
+	/* MS: get preempt_count from thread info */
+	lwi	r5, r11, TI_PREEMPT_COUNT;
+	bgti	r5, restore;
+
+	lwi	r5, r11, TI_FLAGS;		/* get flags in thread info */
+	andi	r5, r5, _TIF_NEED_RESCHED;
+	beqi	r5, restore /* if zero jump over */
+
+preempt:
+	/* interrupts are off that's why I am calling preempt_chedule_irq */
+	bralid	r15, preempt_schedule_irq
+	nop
+	lwi	r11, CURRENT_TASK, TS_THREAD_INFO;	/* get thread info */
+	lwi	r5, r11, TI_FLAGS;		/* get flags in thread info */
+	andi	r5, r5, _TIF_NEED_RESCHED;
+	bnei	r5, preempt /* if non zero jump to resched */
+restore:
+#endif
+	VM_OFF /* MS: turn off MMU */
 	tophys(r1,r1)
 	lwi	r3, r1, PTO + PT_R3; /* MS: restore saved r3, r4 registers */
 	lwi	r4, r1, PTO + PT_R4;
@@ -915,7 +917,7 @@ C_ENTRY(_debug_exception):
 	swi	r11, r1, PTO+PT_R1; /* Store user SP.  */
 	addi	r11, r0, 1;
 	swi	r11, r0, TOPHYS(PER_CPU(KM));	/* Now we're in kernel-mode.  */
-2:	lwi	r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
+2:	lwi	CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
 	/* Save away the syscall number.  */
 	swi	r0, r1, PTO+PT_R0;
 	tovirt(r1,r1)
@@ -935,8 +937,7 @@ dbtrap_call:	rtbd	r11, 0;
 	bnei	r11, 2f;
 
 	/* Get current task ptr into r11 */
-	add	r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
-	lwi	r11, r11, TS_THREAD_INFO;	/* get thread info */
+	lwi	r11, CURRENT_TASK, TS_THREAD_INFO;	/* get thread info */
 	lwi	r11, r11, TI_FLAGS;	/* get flags in thread info */
 	andi	r11, r11, _TIF_NEED_RESCHED;
 	beqi	r11, 5f;
@@ -949,8 +950,7 @@ dbtrap_call:	rtbd	r11, 0;
 	/* XXX m68knommu also checks TASK_STATE & TASK_COUNTER here.  */
 
 	/* Maybe handle a signal */
-5:	add	r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
-	lwi	r11, r11, TS_THREAD_INFO;	/* get thread info */
+5:	lwi	r11, CURRENT_TASK, TS_THREAD_INFO;	/* get thread info */
 	lwi	r11, r11, TI_FLAGS;	/* get flags in thread info */
 	andi	r11, r11, _TIF_SIGPENDING;
 	beqi	r11, 1f;		/* Signals to handle, handle them */
@@ -966,16 +966,14 @@ dbtrap_call:	rtbd	r11, 0;
 	   (in a possibly modified form) after do_signal returns.  */
 
 	la	r5, r1, PTO;		/* Arg 1: struct pt_regs *regs */
-	add	r6, r0, r0;		/* Arg 2: sigset_t *oldset */
 	addi  r7, r0, 0;	/* Arg 3: int in_syscall */
 	bralid	r15, do_signal;	/* Handle any signals */
-	nop;
+	add	r6, r0, r0;		/* Arg 2: sigset_t *oldset */
 
 
 /* Finally, return to user state.  */
 1:	swi	r0, r0, PER_CPU(KM);	/* Now officially in user state. */
-	add	r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
-	swi	r11, r0, PER_CPU(CURRENT_SAVE); /* save current */
+	swi	CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
 	VM_OFF;
 	tophys(r1,r1);
 
@@ -1007,7 +1005,7 @@ DBTRAP_return:		/* Make global symbol fo
 
 ENTRY(_switch_to)
 	/* prepare return value */
-	addk	r3, r0, r31
+	addk	r3, r0, CURRENT_TASK
 
 	/* save registers in cpu_context */
 	/* use r11 and r12, volatile registers, as temp register */
@@ -1051,10 +1049,10 @@ ENTRY(_switch_to)
 	nop
 	swi	r12, r11, CC_FSR
 
-	/* update r31, the current */
-	lwi	r31, r6, TI_TASK/* give me pointer to task which will be next */
+	/* update r31, the current-give me pointer to task which will be next */
+	lwi	CURRENT_TASK, r6, TI_TASK
 	/* stored it to current_save too */
-	swi	r31, r0, PER_CPU(CURRENT_SAVE)
+	swi	CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE)
 
 	/* get new process' cpu context and restore */
 	/* give me start where start context of next task */
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/exceptions.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/exceptions.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/exceptions.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/exceptions.c	2010-05-16 17:17:36.000000000 -0400
@@ -121,7 +121,7 @@ asmlinkage void full_exception(struct pt
 		}
 		printk(KERN_WARNING "Divide by zero exception " \
 							"in kernel mode.\n");
-		die("Divide by exception", regs, SIGBUS);
+		die("Divide by zero exception", regs, SIGBUS);
 		break;
 	case MICROBLAZE_FPU_EXCEPTION:
 		pr_debug(KERN_WARNING "FPU exception\n");
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/ftrace.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/ftrace.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/ftrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/ftrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -151,13 +151,10 @@ int ftrace_make_nop(struct module *mod,
 	return ret;
 }
 
-static int ret_addr; /* initialized as 0 by default */
-
 /* I believe that first is called ftrace_make_nop before this function */
 int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 {
 	int ret;
-	ret_addr = addr; /* saving where the barrier jump is */
 	pr_debug("%s: addr:0x%x, rec->ip: 0x%x, imm:0x%x\n",
 		__func__, (unsigned int)addr, (unsigned int)rec->ip, imm);
 	ret = ftrace_modify_code(rec->ip, imm);
@@ -194,12 +191,9 @@ int ftrace_update_ftrace_func(ftrace_fun
 	ret = ftrace_modify_code(ip, upper);
 	ret += ftrace_modify_code(ip + 4, lower);
 
-	/* We just need to remove the rtsd r15, 8 by NOP */
-	BUG_ON(!ret_addr);
-	if (ret_addr)
-		ret += ftrace_modify_code(ret_addr, MICROBLAZE_NOP);
-	else
-		ret = 1; /* fault */
+	/* We just need to replace the rtsd r15, 8 with NOP */
+	ret += ftrace_modify_code((unsigned long)&ftrace_caller,
+				  MICROBLAZE_NOP);
 
 	/* All changes are done - lets do caches consistent */
 	flush_icache();
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/head.S linux-libre-2.6.34-gnu1/arch/microblaze/kernel/head.S
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/head.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/head.S	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
  * for more details.
  */
 
+#include <linux/init.h>
 #include <linux/linkage.h>
 #include <asm/thread_info.h>
 #include <asm/page.h>
@@ -49,8 +50,14 @@ swapper_pg_dir:
 
 #endif /* CONFIG_MMU */
 
-	.text
+	__HEAD
 ENTRY(_start)
+#if CONFIG_KERNEL_BASE_ADDR == 0
+	brai	TOPHYS(real_start)
+	.org	0x100
+real_start:
+#endif
+
 	mfs	r1, rmsr
 	andi	r1, r1, ~2
 	mts	rmsr, r1
@@ -99,8 +106,8 @@ no_fdt_arg:
 	tophys(r4,r4)			/* convert to phys address */
 	ori	r3, r0, COMMAND_LINE_SIZE - 1 /* number of loops */
 _copy_command_line:
-	lbu	r7, r5, r6 /* r7=r5+r6 - r5 contain pointer to command line */
-	sb	r7, r4, r6		/* addr[r4+r6]= r7*/
+	lbu	r2, r5, r6 /* r2=r5+r6 - r5 contain pointer to command line */
+	sb	r2, r4, r6		/* addr[r4+r6]= r2*/
 	addik	r6, r6, 1		/* increment counting */
 	bgtid	r3, _copy_command_line	/* loop for all entries       */
 	addik	r3, r3, -1		/* descrement loop */
@@ -128,7 +135,7 @@ _copy_bram:
 	 * virtual to physical.
 	 */
 	nop
-	addik	r3, r0, 63		/* Invalidate all TLB entries */
+	addik	r3, r0, MICROBLAZE_TLB_SIZE -1	/* Invalidate all TLB entries */
 _invalidate:
 	mts	rtlbx, r3
 	mts	rtlbhi, r0			/* flush: ensure V is clear   */
@@ -136,6 +143,11 @@ _invalidate:
 	addik	r3, r3, -1
 	/* sync */
 
+	/* Setup the kernel PID */
+	mts	rpid,r0			/* Load the kernel PID */
+	nop
+	bri	4
+
 	/*
 	 * We should still be executing code at physical address area
 	 * RAM_BASEADDR at this point. However, kernel code is at
@@ -146,10 +158,6 @@ _invalidate:
 	addik	r3,r0, CONFIG_KERNEL_START /* Load the kernel virtual address */
 	tophys(r4,r3)			/* Load the kernel physical address */
 
-	mts	rpid,r0			/* Load the kernel PID */
-	nop
-	bri	4
-
 	/*
 	 * Configure and load two entries into TLB slots 0 and 1.
 	 * In case we are pinning TLBs, these are reserved in by the
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/hw_exception_handler.S linux-libre-2.6.34-gnu1/arch/microblaze/kernel/hw_exception_handler.S
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/hw_exception_handler.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/hw_exception_handler.S	2010-05-16 17:17:36.000000000 -0400
@@ -313,13 +313,13 @@ _hw_exception_handler:
 	mfs	r5, rmsr;
 	nop
 	swi	r5, r1, 0;
-	mfs	r3, resr
+	mfs	r4, resr
 	nop
-	mfs	r4, rear;
+	mfs	r3, rear;
 	nop
 
 #ifndef CONFIG_MMU
-	andi	r5, r3, 0x1000;		/* Check ESR[DS] */
+	andi	r5, r4, 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
@@ -327,13 +327,14 @@ not_in_delay_slot:
 	swi	r17, r1, PT_R17
 #endif
 
-	andi	r5, r3, 0x1F;		/* Extract ESR[EXC] */
+	andi	r5, r4, 0x1F;		/* Extract ESR[EXC] */
 
 #ifdef CONFIG_MMU
 	/* Calculate exception vector offset = r5 << 2 */
 	addk	r6, r5, r5; /* << 1 */
 	addk	r6, r6, r6; /* << 2 */
 
+#ifdef DEBUG
 /* counting which exception happen */
 	lwi	r5, r0, 0x200 + TOPHYS(r0_ram)
 	addi	r5, r5, 1
@@ -341,6 +342,7 @@ not_in_delay_slot:
 	lwi	r5, r6, 0x200 + TOPHYS(r0_ram)
 	addi	r5, r5, 1
 	swi	r5, r6, 0x200 + TOPHYS(r0_ram)
+#endif
 /* end */
 	/* Load the HW Exception vector */
 	lwi	r6, r6, TOPHYS(_MB_HW_ExceptionVectorTable)
@@ -376,7 +378,7 @@ handle_other_ex: /* Handle Other excepti
 	swi	r18, r1, PT_R18
 
 	or	r5, r1, r0
-	andi	r6, r3, 0x1F; /* Load ESR[EC] */
+	andi	r6, r4, 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
@@ -426,11 +428,11 @@ handle_other_ex: /* Handle Other excepti
  */
 handle_unaligned_ex:
 	/* Working registers already saved: R3, R4, R5, R6
-	 *  R3 = ESR
-	 *  R4 = EAR
+	 *  R4 = ESR
+	 *  R3 = EAR
 	 */
 #ifdef CONFIG_MMU
-	andi	r6, r3, 0x1000			/* Check ESR[DS] */
+	andi	r6, r4, 0x1000			/* Check ESR[DS] */
 	beqi	r6, _no_delayslot		/* Branch if ESR[DS] not set */
 	mfs	r17, rbtr;	/* ESR[DS] set - return address in BTR */
 	nop
@@ -439,7 +441,7 @@ _no_delayslot:
 	RESTORE_STATE;
 	bri	unaligned_data_trap
 #endif
-	andi	r6, r3, 0x3E0; /* Mask and extract the register operand */
+	andi	r6, r4, 0x3E0; /* Mask and extract the register operand */
 	srl	r6, r6; /* r6 >> 5 */
 	srl	r6, r6;
 	srl	r6, r6;
@@ -448,33 +450,33 @@ _no_delayslot:
 	/* Store the register operand in a temporary location */
 	sbi	r6, r0, TOPHYS(ex_reg_op);
 
-	andi	r6, r3, 0x400; /* Extract ESR[S] */
+	andi	r6, r4, 0x400; /* Extract ESR[S] */
 	bnei	r6, ex_sw;
 ex_lw:
-	andi	r6, r3, 0x800; /* Extract ESR[W] */
+	andi	r6, r4, 0x800; /* Extract ESR[W] */
 	beqi	r6, ex_lhw;
-	lbui	r5, r4, 0; /* Exception address in r4 */
+	lbui	r5, r3, 0; /* Exception address in r3 */
 	/* 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;
+	lbui	r5, r3, 1;
 	sbi	r5, r0, TOPHYS(ex_tmp_data_loc_1);
-	lbui	r5, r4, 2;
+	lbui	r5, r3, 2;
 	sbi	r5, r0, TOPHYS(ex_tmp_data_loc_2);
-	lbui	r5, r4, 3;
+	lbui	r5, r3, 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);
+	/* Get the destination register value into r4 */
+	lwi	r4, r0, TOPHYS(ex_tmp_data_loc_0);
 	bri	ex_lw_tail;
 ex_lhw:
-	lbui	r5, r4, 0; /* Exception address in r4 */
+	lbui	r5, r3, 0; /* Exception address in r3 */
 	/* 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;
+	lbui	r5, r3, 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);
+	/* Get the destination register value into r4 */
+	lhui	r4, r0, TOPHYS(ex_tmp_data_loc_0);
 ex_lw_tail:
 	/* Get the destination register number into r5 */
 	lbui	r5, r0, TOPHYS(ex_reg_op);
@@ -502,25 +504,25 @@ ex_sw_tail:
 	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);
+	swi	r4, 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;
+	lbui	r4, r0, TOPHYS(ex_tmp_data_loc_0);
+	sbi	r4, r3, 0;
+	lbui	r4, r0, TOPHYS(ex_tmp_data_loc_1);
+	sbi	r4, r3, 1;
+	lbui	r4, r0, TOPHYS(ex_tmp_data_loc_2);
+	sbi	r4, r3, 2;
+	lbui	r4, r0, TOPHYS(ex_tmp_data_loc_3);
+	sbi	r4, r3, 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;
+	swi	r4, r0, TOPHYS(ex_tmp_data_loc_0);
+	lbui	r4, r0, TOPHYS(ex_tmp_data_loc_2);
+	sbi	r4, r3, 0;
+	lbui	r4, r0, TOPHYS(ex_tmp_data_loc_3);
+	sbi	r4, r3, 1;
 ex_sw_end: /* Exception handling of store word, ends. */
 
 ex_handler_done:
@@ -560,21 +562,16 @@ ex_handler_done:
 		 */
 		mfs	r11, rpid
 		nop
-		bri	4
-		mfs	r3, rear		/* Get faulting address */
-		nop
 		/* If we are faulting a kernel address, we have to use the
 		 * kernel page tables.
 		 */
-		ori	r4, r0, CONFIG_KERNEL_START
-		cmpu	r4, r3, r4
-		bgti	r4, ex3
+		ori	r5, r0, CONFIG_KERNEL_START
+		cmpu	r5, r3, r5
+		bgti	r5, ex3
 		/* First, check if it was a zone fault (which means a user
 		 * tried to access a kernel or read-protected page - always
 		 * a SEGV). All other faults here must be stores, so no
 		 * need to check ESR_S as well. */
-		mfs	r4, resr
-		nop
 		andi	r4, r4, 0x800		/* ESR_Z - zone protection */
 		bnei	r4, ex2
 
@@ -589,8 +586,6 @@ ex_handler_done:
 		 * tried to access a kernel or read-protected page - always
 		 * a SEGV). All other faults here must be stores, so no
 		 * need to check ESR_S as well. */
-		mfs	r4, resr
-		nop
 		andi	r4, r4, 0x800		/* ESR_Z */
 		bnei	r4, ex2
 		/* get current task address */
@@ -665,8 +660,6 @@ ex_handler_done:
 		 * R3 = ESR
 		 */
 
-		mfs	r3, rear		/* Get faulting address */
-		nop
 		RESTORE_STATE;
 		bri	page_fault_instr_trap
 
@@ -677,18 +670,15 @@ ex_handler_done:
 	 */
 	handle_data_tlb_miss_exception:
 		/* Working registers already saved: R3, R4, R5, R6
-		 * R3 = ESR
+		 * R3 = EAR, R4 = ESR
 		 */
 		mfs	r11, rpid
 		nop
-		bri	4
-		mfs	r3, rear		/* Get faulting address */
-		nop
 
 		/* If we are faulting a kernel address, we have to use the
 		 * kernel page tables. */
-		ori	r4, r0, CONFIG_KERNEL_START
-		cmpu	r4, r3, r4
+		ori	r6, r0, CONFIG_KERNEL_START
+		cmpu	r4, r3, r6
 		bgti	r4, ex5
 		ori	r4, r0, swapper_pg_dir
 		mts	rpid, r0		/* TLB will have 0 TID */
@@ -731,9 +721,8 @@ ex_handler_done:
 		 * Many of these bits are software only. Bits we don't set
 		 * here we (properly should) assume have the appropriate value.
 		 */
+		brid	finish_tlb_load
 		andni	r4, r4, 0x0ce2		/* Make sure 20, 21 are zero */
-
-		bri	finish_tlb_load
 	ex7:
 		/* The bailout. Restore registers to pre-exception conditions
 		 * and call the heavyweights to help us out.
@@ -754,9 +743,6 @@ ex_handler_done:
 		 */
 		mfs	r11, rpid
 		nop
-		bri	4
-		mfs	r3, rear		/* Get faulting address */
-		nop
 
 		/* If we are faulting a kernel address, we have to use the
 		 * kernel page tables.
@@ -792,7 +778,7 @@ ex_handler_done:
 		lwi	r4, r5, 0		/* Get Linux PTE */
 
 		andi	r6, r4, _PAGE_PRESENT
-		beqi	r6, ex7
+		beqi	r6, ex10
 
 		ori	r4, r4, _PAGE_ACCESSED
 		swi	r4, r5, 0
@@ -805,9 +791,8 @@ ex_handler_done:
 		 * Many of these bits are software only. Bits we don't set
 		 * here we (properly should) assume have the appropriate value.
 		 */
+		brid	finish_tlb_load
 		andni	r4, r4, 0x0ce2		/* Make sure 20, 21 are zero */
-
-		bri	finish_tlb_load
 	ex10:
 		/* The bailout. Restore registers to pre-exception conditions
 		 * and call the heavyweights to help us out.
@@ -837,9 +822,9 @@ ex_handler_done:
 		andi	r5, r5, (MICROBLAZE_TLB_SIZE-1)
 		ori	r6, r0, 1
 		cmp	r31, r5, r6
-		blti	r31, sem
+		blti	r31, ex12
 		addik	r5, r6, 1
-	sem:
+	ex12:
 		/* MS: save back current TLB index */
 		swi	r5, r0, TOPHYS(tlb_index)
 
@@ -859,7 +844,6 @@ ex_handler_done:
 		nop
 
 		/* Done...restore registers and get out of here. */
-	ex12:
 		mts	rpid, r11
 		nop
 		bri 4
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/irq.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/irq.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/ftrace.h>
 #include <linux/kernel.h>
 #include <linux/hardirq.h>
 #include <linux/interrupt.h>
@@ -32,7 +33,7 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
 
 static u32 concurrent_irq;
 
-void do_IRQ(struct pt_regs *regs)
+void __irq_entry do_IRQ(struct pt_regs *regs)
 {
 	unsigned int irq;
 	struct pt_regs *old_regs = set_irq_regs(regs);
@@ -93,3 +94,18 @@ skip:
 	}
 	return 0;
 }
+
+/* MS: There is no any advance mapping mechanism. We are using simple 32bit
+  intc without any cascades or any connection that's why mapping is 1:1 */
+unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
+{
+	return hwirq;
+}
+EXPORT_SYMBOL_GPL(irq_create_mapping);
+
+unsigned int irq_create_of_mapping(struct device_node *controller,
+					u32 *intspec, unsigned int intsize)
+{
+	return intspec[0];
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/Makefile linux-libre-2.6.34-gnu1/arch/microblaze/kernel/Makefile
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,7 @@ endif
 
 extra-y := head.o vmlinux.lds
 
-obj-y += exceptions.o \
+obj-y += dma.o 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 reset.o
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/microblaze_ksyms.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/microblaze_ksyms.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/microblaze_ksyms.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/microblaze_ksyms.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,3 +52,14 @@ EXPORT_SYMBOL_GPL(_ebss);
 extern void _mcount(void);
 EXPORT_SYMBOL(_mcount);
 #endif
+
+/*
+ * Assembly functions that may be used (directly or indirectly) by modules
+ */
+EXPORT_SYMBOL(__copy_tofrom_user);
+EXPORT_SYMBOL(__strncpy_user);
+
+#ifdef CONFIG_OPT_LIB_ASM
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memmove);
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/misc.S linux-libre-2.6.34-gnu1/arch/microblaze/kernel/misc.S
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/misc.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/misc.S	2010-05-16 17:17:36.000000000 -0400
@@ -26,9 +26,10 @@
  * We avoid flushing the pinned 0, 1 and possibly 2 entries.
  */
 .globl _tlbia;
+.type  _tlbia, @function
 .align 4;
 _tlbia:
-	addik	r12, r0, 63 /* flush all entries (63 - 3) */
+	addik	r12, r0, MICROBLAZE_TLB_SIZE - 1 /* flush all entries (63 - 3) */
 	/* isync */
 _tlbia_1:
 	mts	rtlbx, r12
@@ -41,11 +42,13 @@ _tlbia_1:
 	/* sync */
 	rtsd	r15, 8
 	nop
+	.size  _tlbia, . - _tlbia
 
 /*
  * Flush MMU TLB for a particular address (in r5)
  */
 .globl _tlbie;
+.type  _tlbie, @function
 .align 4;
 _tlbie:
 	mts	rtlbsx, r5 /* look up the address in TLB */
@@ -59,17 +62,20 @@ _tlbie_1:
 	rtsd	r15, 8
 	nop
 
+	.size  _tlbie, . - _tlbie
+
 /*
  * Allocate TLB entry for early console
  */
 .globl early_console_reg_tlb_alloc;
+.type  early_console_reg_tlb_alloc, @function
 .align 4;
 early_console_reg_tlb_alloc:
 	/*
 	 * Load a TLB entry for the UART, so that microblaze_progress() can use
 	 * the UARTs nice and early.  We use a 4k real==virtual mapping.
 	 */
-	ori	r4, r0, 63
+	ori	r4, r0, MICROBLAZE_TLB_SIZE - 1
 	mts	rtlbx, r4 /* TLB slot 2 */
 
 	or	r4,r5,r0
@@ -86,35 +92,4 @@ early_console_reg_tlb_alloc:
 	rtsd	r15, 8
 	nop
 
-/*
- * Copy a whole page (4096 bytes).
- */
-#define COPY_16_BYTES		\
-	lwi	r7, r6, 0;	\
-	lwi	r8, r6, 4;	\
-	lwi	r9, r6, 8;	\
-	lwi	r10, r6, 12;	\
-	swi	r7, r5, 0;	\
-	swi	r8, r5, 4;	\
-	swi	r9, r5, 8;	\
-	swi	r10, r5, 12
-
-
-/* FIXME DCACHE_LINE_BYTES (CONFIG_XILINX_MICROBLAZE0_DCACHE_LINE_LEN * 4)*/
-#define DCACHE_LINE_BYTES (4 * 4)
-
-.globl copy_page;
-.align 4;
-copy_page:
-	ori	r11, r0, (PAGE_SIZE/DCACHE_LINE_BYTES) - 1
-_copy_page_loop:
-	COPY_16_BYTES
-#if DCACHE_LINE_BYTES >= 32
-	COPY_16_BYTES
-#endif
-	addik	r6, r6, DCACHE_LINE_BYTES
-	addik	r5, r5, DCACHE_LINE_BYTES
-	bneid	r11, _copy_page_loop
-	addik	r11, r11, -1
-	rtsd	r15, 8
-	nop
+	.size  early_console_reg_tlb_alloc, . - early_console_reg_tlb_alloc
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/module.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/module.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/module.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/module.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,11 +12,11 @@
 #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>
+#include <asm/cacheflush.h>
 
 void *module_alloc(unsigned long size)
 {
@@ -152,6 +152,7 @@ int apply_relocate_add(Elf32_Shdr *sechd
 int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
 		struct module *module)
 {
+	flush_dcache();
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/of_platform.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/of_platform.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/of_platform.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/of_platform.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #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>
@@ -185,7 +184,7 @@ 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;
+	return to_of_device(dev)->node->phandle == *ph;
 }
 
 struct of_device *of_find_device_by_phandle(phandle ph)
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/process.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/bitops.h>
 #include <asm/system.h>
 #include <asm/pgalloc.h>
+#include <asm/uaccess.h> /* for USER_DS macros */
 #include <asm/cacheflush.h>
 
 void show_regs(struct pt_regs *regs)
@@ -74,7 +75,10 @@ __setup("hlt", hlt_setup);
 
 void default_idle(void)
 {
-	if (!hlt_counter) {
+	if (likely(hlt_counter)) {
+		while (!need_resched())
+			cpu_relax();
+	} else {
 		clear_thread_flag(TIF_POLLING_NRFLAG);
 		smp_mb__after_clear_bit();
 		local_irq_disable();
@@ -82,9 +86,7 @@ void default_idle(void)
 			cpu_sleep();
 		local_irq_enable();
 		set_thread_flag(TIF_POLLING_NRFLAG);
-	} else
-		while (!need_resched())
-			cpu_relax();
+	}
 }
 
 void cpu_idle(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/prom.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/prom.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/prom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/prom.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,697 +42,20 @@
 #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((u32)of_read_ulong(prop, l/4));
-
-		prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l);
-		if (prop) {
-			initrd_end = (unsigned long)
-					__va((u32)of_read_ulong(prop, 1/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
-#ifndef CONFIG_CMDLINE_FORCE
-	if (p == NULL || l == 0 || (l == 1 && (*p) == 0))
-#endif
-		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)
+void __init early_init_dt_scan_chosen_arch(unsigned long node)
 {
-	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;
+	/* No Microblaze specific code here */
 }
 
-#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)
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
 {
-	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);
+	lmb_add(base, size);
 }
 
-/**
- * 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)
+u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
 {
-	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;
-	}
+	return lmb_alloc(size, align);
 }
-#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 */
@@ -775,11 +98,6 @@ void __init early_init_devtree(void *par
 	/* 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 ...
@@ -799,33 +117,18 @@ void __init early_init_devtree(void *par
 
 	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)
+#ifdef CONFIG_BLK_DEV_INITRD
+void __init early_init_dt_setup_initrd_arch(unsigned long start,
+		unsigned long end)
 {
-	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;
+	initrd_start = (unsigned long)__va(start);
+	initrd_end = (unsigned long)__va(end);
+	initrd_below_start_ok = 1;
 }
-EXPORT_SYMBOL(machine_is_compatible);
+#endif
 
 /*******
  *
@@ -838,273 +141,6 @@ EXPORT_SYMBOL(machine_is_compatible);
  *
  *******/
 
-/**
- *	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_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;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -75,29 +75,8 @@ long arch_ptrace(struct task_struct *chi
 {
 	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:
@@ -130,50 +109,8 @@ long arch_ptrace(struct task_struct *chi
 		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;
+		rval = ptrace_request(child, request, addr, data);
 	}
 	return rval;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/setup.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/setup.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,10 @@
 #include <linux/io.h>
 #include <linux/bug.h>
 #include <linux/param.h>
+#include <linux/pci.h>
 #include <linux/cache.h>
+#include <linux/of_platform.h>
+#include <linux/dma-mapping.h>
 #include <asm/cacheflush.h>
 #include <asm/entry.h>
 #include <asm/cpuinfo.h>
@@ -54,14 +57,10 @@ void __init setup_arch(char **cmdline_p)
 
 	microblaze_cache_init();
 
-	invalidate_dcache();
-	enable_dcache();
-
-	invalidate_icache();
-	enable_icache();
-
 	setup_memory();
 
+	xilinx_pci_init();
+
 #if defined(CONFIG_SELFMOD_INTC) || defined(CONFIG_SELFMOD_TIMER)
 	printk(KERN_NOTICE "Self modified code enable\n");
 #endif
@@ -93,6 +92,12 @@ inline unsigned get_romfs_len(unsigned *
 }
 #endif	/* CONFIG_MTD_UCLINUX_EBSS */
 
+#if defined(CONFIG_EARLY_PRINTK) && defined(CONFIG_SERIAL_UARTLITE_CONSOLE)
+#define eprintk early_printk
+#else
+#define eprintk printk
+#endif
+
 void __init machine_early_init(const char *cmdline, unsigned int ram,
 		unsigned int fdt, unsigned int msr)
 {
@@ -140,32 +145,32 @@ void __init machine_early_init(const cha
 	setup_early_printk(NULL);
 #endif
 
-	early_printk("Ramdisk addr 0x%08x, ", ram);
+	eprintk("Ramdisk addr 0x%08x, ", ram);
 	if (fdt)
-		early_printk("FDT at 0x%08x\n", fdt);
+		eprintk("FDT at 0x%08x\n", fdt);
 	else
-		early_printk("Compiled-in FDT at 0x%08x\n",
+		eprintk("Compiled-in FDT at 0x%08x\n",
 					(unsigned int)_fdt_start);
 
 #ifdef CONFIG_MTD_UCLINUX
-	early_printk("Found romfs @ 0x%08x (0x%08x)\n",
+	eprintk("Found romfs @ 0x%08x (0x%08x)\n",
 			romfs_base, romfs_size);
-	early_printk("#### klimit %p ####\n", old_klimit);
+	eprintk("#### klimit %p ####\n", old_klimit);
 	BUG_ON(romfs_size < 0); /* What else can we do? */
 
-	early_printk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n",
+	eprintk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n",
 			romfs_size, romfs_base, (unsigned)&_ebss);
 
-	early_printk("New klimit: 0x%08x\n", (unsigned)klimit);
+	eprintk("New klimit: 0x%08x\n", (unsigned)klimit);
 #endif
 
 #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
 	if (msr)
-		early_printk("!!!Your kernel has setup MSR instruction but "
+		eprintk("!!!Your kernel has setup MSR instruction but "
 				"CPU don't have it %d\n", msr);
 #else
 	if (!msr)
-		early_printk("!!!Your kernel not setup MSR instruction but "
+		eprintk("!!!Your kernel not setup MSR instruction but "
 				"CPU have it %d\n", msr);
 #endif
 
@@ -188,3 +193,37 @@ static int microblaze_debugfs_init(void)
 }
 arch_initcall(microblaze_debugfs_init);
 #endif
+
+static int 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 dflt_plat_bus_notifier = {
+	.notifier_call = dflt_bus_notify,
+	.priority = INT_MAX,
+};
+
+static struct notifier_block dflt_of_bus_notifier = {
+	.notifier_call = dflt_bus_notify,
+	.priority = INT_MAX,
+};
+
+static int __init setup_bus_notifier(void)
+{
+	bus_register_notifier(&platform_bus_type, &dflt_plat_bus_notifier);
+	bus_register_notifier(&of_platform_bus_type, &dflt_of_bus_notifier);
+
+	return 0;
+}
+
+arch_initcall(setup_bus_notifier);
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/sys_microblaze.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/sys_microblaze.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/sys_microblaze.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/sys_microblaze.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/semaphore.h>
 #include <linux/uaccess.h>
 #include <linux/unistd.h>
+#include <linux/slab.h>
 
 #include <asm/syscalls.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/traps.c linux-libre-2.6.34-gnu1/arch/microblaze/kernel/traps.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/traps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/traps.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,13 +22,11 @@ void trap_init(void)
 	__enable_hw_exceptions();
 }
 
-static int kstack_depth_to_print = 24;
+static unsigned long kstack_depth_to_print = 24;
 
 static int __init kstack_setup(char *s)
 {
-	kstack_depth_to_print = strict_strtoul(s, 0, NULL);
-
-	return 1;
+	return !strict_strtoul(s, 0, &kstack_depth_to_print);
 }
 __setup("kstack=", kstack_setup);
 
@@ -97,37 +95,3 @@ void dump_stack(void)
 	show_stack(NULL, NULL);
 }
 EXPORT_SYMBOL(dump_stack);
-
-#ifdef CONFIG_MMU
-void __bug(const char *file, int line, void *data)
-{
-	if (data)
-		printk(KERN_CRIT "kernel BUG at %s:%d (data = %p)!\n",
-			file, line, data);
-	else
-		printk(KERN_CRIT "kernel BUG at %s:%d!\n", file, line);
-
-	machine_halt();
-}
-
-int bad_trap(int trap_num, struct pt_regs *regs)
-{
-	printk(KERN_CRIT
-		"unimplemented trap %d called at 0x%08lx, pid %d!\n",
-		trap_num, regs->pc, current->pid);
-	return -ENOSYS;
-}
-
-int debug_trap(struct pt_regs *regs)
-{
-	int i;
-	printk(KERN_CRIT "debug trap\n");
-	for (i = 0; i < 32; i++) {
-		/* printk("r%i:%08X\t",i,regs->gpr[i]); */
-		if ((i % 4) == 3)
-			printk(KERN_CRIT "\n");
-	}
-	printk(KERN_CRIT "pc:%08lX\tmsr:%08lX\n", regs->pc, regs->msr);
-	return -ENOSYS;
-}
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/kernel/vmlinux.lds.S linux-libre-2.6.34-gnu1/arch/microblaze/kernel/vmlinux.lds.S
--- linux-libre-2.6.33-gnu1/arch/microblaze/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/kernel/vmlinux.lds.S	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,8 @@ SECTIONS {
 	.text : AT(ADDR(.text) - LOAD_OFFSET) {
 		_text = . ;
 		_stext = . ;
-		*(.text .text.*)
+		HEAD_TEXT
+		TEXT_TEXT
 		*(.fixup)
 		EXIT_TEXT
 		EXIT_CALL
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/lib/fastcopy.S linux-libre-2.6.34-gnu1/arch/microblaze/lib/fastcopy.S
--- linux-libre-2.6.33-gnu1/arch/microblaze/lib/fastcopy.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/lib/fastcopy.S	2010-05-16 17:17:36.000000000 -0400
@@ -30,8 +30,9 @@
  */
 
 #include <linux/linkage.h>
-
+	.text
 	.globl	memcpy
+	.type  memcpy, @function
 	.ent	memcpy
 
 memcpy:
@@ -345,9 +346,11 @@ a_done:
 	rtsd	r15, 8
 	nop
 
+.size  memcpy, . - memcpy
 .end memcpy
 /*----------------------------------------------------------------------------*/
 	.globl	memmove
+	.type  memmove, @function
 	.ent	memmove
 
 memmove:
@@ -659,4 +662,5 @@ d_done:
 	rtsd	r15, 8
 	nop
 
+.size  memmove, . - memmove
 .end memmove
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/lib/Makefile linux-libre-2.6.34-gnu1/arch/microblaze/lib/Makefile
--- linux-libre-2.6.33-gnu1/arch/microblaze/lib/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/lib/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -10,5 +10,4 @@ else
 lib-y += memcpy.o memmove.o
 endif
 
-lib-$(CONFIG_NO_MMU) += uaccess.o
-lib-$(CONFIG_MMU) += uaccess_old.o
+lib-y += uaccess_old.o
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/lib/memcpy.c linux-libre-2.6.34-gnu1/arch/microblaze/lib/memcpy.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/lib/memcpy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/lib/memcpy.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,7 +53,7 @@ void *memcpy(void *v_dst, const void *v_
 	const uint32_t *i_src;
 	uint32_t *i_dst;
 
-	if (c >= 4) {
+	if (likely(c >= 4)) {
 		unsigned  value, buf_hold;
 
 		/* Align the dstination to a word boundry. */
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/lib/memset.c linux-libre-2.6.34-gnu1/arch/microblaze/lib/memset.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/lib/memset.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/lib/memset.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,22 +33,23 @@
 #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;
+	uint32_t w32 = 0;
 #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 (unlikely(c)) {
+		/* Make a repeating word out of it */
+		w32 = c;
+		w32 |= w32 << 8;
+		w32 |= w32 << 16;
+	}
 
-	if (n >= 4) {
+	if (likely(n >= 4)) {
 		/* Align the destination to a word boundary */
 		/* This is done in an endian independant manner */
 		switch ((unsigned) src & 3) {
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/lib/uaccess.c linux-libre-2.6.34-gnu1/arch/microblaze/lib/uaccess.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/lib/uaccess.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/lib/uaccess.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,48 +0,0 @@
-/*
- * 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;
-}
-
-unsigned long __copy_tofrom_user(void __user *to,
-		const void __user *from, unsigned long size)
-{
-	memcpy(to, from, size);
-	return 0;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/lib/uaccess_old.S linux-libre-2.6.34-gnu1/arch/microblaze/lib/uaccess_old.S
--- linux-libre-2.6.33-gnu1/arch/microblaze/lib/uaccess_old.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/lib/uaccess_old.S	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 	.text
 .globl __strncpy_user;
+.type  __strncpy_user, @function
 .align 4;
 __strncpy_user:
 
@@ -50,7 +51,7 @@ __strncpy_user:
 3:
 	rtsd	r15,8
 	nop
-
+	.size   __strncpy_user, . - __strncpy_user
 
 	.section	.fixup, "ax"
 	.align	2
@@ -72,6 +73,7 @@ __strncpy_user:
 
 	.text
 .globl __strnlen_user;
+.type  __strnlen_user, @function
 .align 4;
 __strnlen_user:
 	addik	r3,r6,0
@@ -90,7 +92,7 @@ __strnlen_user:
 3:
 	rtsd	r15,8
 	nop
-
+	.size   __strnlen_user, . - __strnlen_user
 
 	.section	.fixup,"ax"
 4:
@@ -108,6 +110,7 @@ __strnlen_user:
  */
 	.text
 .globl __copy_tofrom_user;
+.type  __copy_tofrom_user, @function
 .align 4;
 __copy_tofrom_user:
 	/*
@@ -116,20 +119,34 @@ __copy_tofrom_user:
 	 * r7, r3 - count
 	 * r4 - tempval
 	 */
-	addik	r3,r7,0
-	beqi	r3,3f
-1:
-	lbu	r4,r6,r0
-	addik	r6,r6,1
-2:
-	sb	r4,r5,r0
-	addik	r3,r3,-1
-	bneid	r3,1b
-	addik	r5,r5,1		/* delay slot */
+	beqid	r7, 3f /* zero size is not likely */
+	andi	r3, r7, 0x3 /* filter add count */
+	bneid	r3, 4f /* if is odd value then byte copying */
+	or	r3, r5, r6 /* find if is any to/from unaligned */
+	andi	r3, r3, 0x3 /* mask unaligned */
+	bneid	r3, 1f /* it is unaligned -> then jump */
+	or	r3, r0, r0
+
+/* at least one 4 byte copy */
+5:	lw	r4, r6, r3
+6:	sw	r4, r5, r3
+	addik	r7, r7, -4
+	bneid	r7, 5b
+	addik	r3, r3, 4
+	addik	r3, r7, 0
+	rtsd	r15, 8
+	nop
+4:	or	r3, r0, r0
+1:	lbu	r4,r6,r3
+2:	sb	r4,r5,r3
+	addik	r7,r7,-1
+	bneid	r7,1b
+	addik	r3,r3,1		/* delay slot */
 3:
+	addik	r3,r7,0
 	rtsd	r15,8
 	nop
-
+	.size   __copy_tofrom_user, . - __copy_tofrom_user
 
 	.section	__ex_table,"a"
-	.word	1b,3b,2b,3b
+	.word	1b,3b,2b,3b,5b,3b,6b,3b
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/Makefile linux-libre-2.6.34-gnu1/arch/microblaze/Makefile
--- linux-libre-2.6.33-gnu1/arch/microblaze/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -50,6 +50,7 @@ libs-y += $(LIBGCC)
 core-y += arch/microblaze/kernel/
 core-y += arch/microblaze/mm/
 core-y += arch/microblaze/platform/
+core-$(CONFIG_PCI) += arch/microblaze/pci/
 
 drivers-$(CONFIG_OPROFILE) += arch/microblaze/oprofile/
 
@@ -83,7 +84,7 @@ define archhelp
   echo '* linux.bin    - Create raw binary'
   echo '  linux.bin.gz - Create compressed raw binary'
   echo '  simpleImage.<dt> - ELF image with $(arch)/boot/dts/<dt>.dts linked in'
-  echo '                   - stripped elf with fdt blob
+  echo '                   - stripped elf with fdt blob'
   echo '  simpleImage.<dt>.unstrip - full ELF image with fdt blob'
   echo '  *_defconfig      - Select default config from arch/microblaze/configs'
   echo ''
@@ -93,3 +94,5 @@ define archhelp
   echo '  name of a dts file from the arch/microblaze/boot/dts/ directory'
   echo '  (minus the .dts extension).'
 endef
+
+MRPROPER_FILES += $(boot)/simpleImage.*
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/mm/consistent.c linux-libre-2.6.34-gnu1/arch/microblaze/mm/consistent.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/mm/consistent.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/mm/consistent.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,255 @@
+/*
+ * Microblaze support for cache consistent memory.
+ * Copyright (C) 2010 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2010 PetaLogix
+ * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * Based on PowerPC version derived from arch/arm/mm/consistent.c
+ * Copyright (C) 2001 Dan Malek (dmalek@jlc.net)
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#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/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/gfp.h>
+
+#include <asm/pgalloc.h>
+#include <linux/io.h>
+#include <linux/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/mmu.h>
+#include <linux/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/cpuinfo.h>
+#include <asm/tlbflush.h>
+
+#ifndef CONFIG_MMU
+/* I have to use dcache values because I can't relate on ram size */
+# define UNCACHED_SHADOW_MASK (cpuinfo.dcache_high - cpuinfo.dcache_base + 1)
+#endif
+
+/*
+ * Consistent memory allocators. Used for DMA devices that want to
+ * share uncached memory with the processor core.
+ * My crufty no-MMU approach is simple. In the HW platform we can optionally
+ * mirror the DDR up above the processor cacheable region.  So, memory accessed
+ * in this mirror region will not be cached.  It's alloced from the same
+ * pool as normal memory, but the handle we return is shifted up into the
+ * uncached region.  This will no doubt cause big problems if memory allocated
+ * here is not also freed properly. -- JW
+ */
+void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
+{
+	unsigned long order, vaddr;
+	void *ret;
+	unsigned int i, err = 0;
+	struct page *page, *end;
+
+#ifdef CONFIG_MMU
+	phys_addr_t pa;
+	struct vm_struct *area;
+	unsigned long va;
+#endif
+
+	if (in_interrupt())
+		BUG();
+
+	/* Only allocate page size areas. */
+	size = PAGE_ALIGN(size);
+	order = get_order(size);
+
+	vaddr = __get_free_pages(gfp, order);
+	if (!vaddr)
+		return NULL;
+
+	/*
+	 * we need to ensure that there are no cachelines in use,
+	 * or worse dirty in this area.
+	 */
+	flush_dcache_range(virt_to_phys((void *)vaddr),
+					virt_to_phys((void *)vaddr) + size);
+
+#ifndef CONFIG_MMU
+	ret = (void *)vaddr;
+	/*
+	 * Here's the magic!  Note if the uncached shadow is not implemented,
+	 * it's up to the calling code to also test that condition and make
+	 * other arranegments, such as manually flushing the cache and so on.
+	 */
+# ifdef CONFIG_XILINX_UNCACHED_SHADOW
+	ret = (void *)((unsigned) ret | UNCACHED_SHADOW_MASK);
+# endif
+	if ((unsigned int)ret > cpuinfo.dcache_base &&
+				(unsigned int)ret < cpuinfo.dcache_high)
+		printk(KERN_WARNING
+			"ERROR: Your cache coherent area is CACHED!!!\n");
+
+	/* dma_handle is same as physical (shadowed) address */
+	*dma_handle = (dma_addr_t)ret;
+#else
+	/* Allocate some common virtual space to map the new pages. */
+	area = get_vm_area(size, VM_ALLOC);
+	if (!area) {
+		free_pages(vaddr, order);
+		return NULL;
+	}
+	va = (unsigned long) area->addr;
+	ret = (void *)va;
+
+	/* This gives us the real physical address of the first page. */
+	*dma_handle = pa = virt_to_bus((void *)vaddr);
+#endif
+
+	/*
+	 * free wasted pages.  We skip the first page since we know
+	 * that it will have count = 1 and won't require freeing.
+	 * We also mark the pages in use as reserved so that
+	 * remap_page_range works.
+	 */
+	page = virt_to_page(vaddr);
+	end = page + (1 << order);
+
+	split_page(page, order);
+
+	for (i = 0; i < size && err == 0; i += PAGE_SIZE) {
+#ifdef CONFIG_MMU
+		/* MS: This is the whole magic - use cache inhibit pages */
+		err = map_page(va + i, pa + i, _PAGE_KERNEL | _PAGE_NO_CACHE);
+#endif
+
+		SetPageReserved(page);
+		page++;
+	}
+
+	/* Free the otherwise unused pages. */
+	while (page < end) {
+		__free_page(page);
+		page++;
+	}
+
+	if (err) {
+		free_pages(vaddr, order);
+		return NULL;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(consistent_alloc);
+
+/*
+ * free page(s) as defined by the above mapping.
+ */
+void consistent_free(size_t size, void *vaddr)
+{
+	struct page *page;
+
+	if (in_interrupt())
+		BUG();
+
+	size = PAGE_ALIGN(size);
+
+#ifndef CONFIG_MMU
+	/* Clear SHADOW_MASK bit in address, and free as per usual */
+# ifdef CONFIG_XILINX_UNCACHED_SHADOW
+	vaddr = (void *)((unsigned)vaddr & ~UNCACHED_SHADOW_MASK);
+# endif
+	page = virt_to_page(vaddr);
+
+	do {
+		ClearPageReserved(page);
+		__free_page(page);
+		page++;
+	} while (size -= PAGE_SIZE);
+#else
+	do {
+		pte_t *ptep;
+		unsigned long pfn;
+
+		ptep = pte_offset_kernel(pmd_offset(pgd_offset_k(
+						(unsigned int)vaddr),
+					(unsigned int)vaddr),
+				(unsigned int)vaddr);
+		if (!pte_none(*ptep) && pte_present(*ptep)) {
+			pfn = pte_pfn(*ptep);
+			pte_clear(&init_mm, (unsigned int)vaddr, ptep);
+			if (pfn_valid(pfn)) {
+				page = pfn_to_page(pfn);
+
+				ClearPageReserved(page);
+				__free_page(page);
+			}
+		}
+		vaddr += PAGE_SIZE;
+	} while (size -= PAGE_SIZE);
+
+	/* flush tlb */
+	flush_tlb_all();
+#endif
+}
+EXPORT_SYMBOL(consistent_free);
+
+/*
+ * make an area consistent.
+ */
+void consistent_sync(void *vaddr, size_t size, int direction)
+{
+	unsigned long start;
+	unsigned long end;
+
+	start = (unsigned long)vaddr;
+
+	/* Convert start address back down to unshadowed memory region */
+#ifdef CONFIG_XILINX_UNCACHED_SHADOW
+	start &= ~UNCACHED_SHADOW_MASK;
+#endif
+	end = start + size;
+
+	switch (direction) {
+	case PCI_DMA_NONE:
+		BUG();
+	case PCI_DMA_FROMDEVICE:	/* invalidate only */
+		invalidate_dcache_range(start, end);
+		break;
+	case PCI_DMA_TODEVICE:		/* writeback only */
+		flush_dcache_range(start, end);
+		break;
+	case PCI_DMA_BIDIRECTIONAL:	/* writeback and invalidate */
+		flush_dcache_range(start, end);
+		break;
+	}
+}
+EXPORT_SYMBOL(consistent_sync);
+
+/*
+ * consistent_sync_page makes memory consistent. identical
+ * to consistent_sync, but takes a struct page instead of a
+ * virtual address
+ */
+void consistent_sync_page(struct page *page, unsigned long offset,
+	size_t size, int direction)
+{
+	unsigned long start = (unsigned long)page_address(page) + offset;
+	consistent_sync((void *)start, size, direction);
+}
+EXPORT_SYMBOL(consistent_sync_page);
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/mm/fault.c linux-libre-2.6.34-gnu1/arch/microblaze/mm/fault.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/mm/fault.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/mm/fault.c	2010-05-16 17:17:36.000000000 -0400
@@ -106,7 +106,7 @@ void do_page_fault(struct pt_regs *regs,
 	regs->esr = error_code;
 
 	/* On a kernel SLB miss we can only check for a valid exception entry */
-	if (kernel_mode(regs) && (address >= TASK_SIZE)) {
+	if (unlikely(kernel_mode(regs) && (address >= TASK_SIZE))) {
 		printk(KERN_WARNING "kernel task_size exceed");
 		_exception(SIGSEGV, regs, code, address);
 	}
@@ -122,7 +122,7 @@ void do_page_fault(struct pt_regs *regs,
 	}
 #endif /* CONFIG_KGDB */
 
-	if (in_atomic() || !mm) {
+	if (unlikely(in_atomic() || !mm)) {
 		if (kernel_mode(regs))
 			goto bad_area_nosemaphore;
 
@@ -150,7 +150,7 @@ void do_page_fault(struct pt_regs *regs,
 	 * 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 (kernel_mode(regs) && !search_exception_tables(regs->pc))
 			goto bad_area_nosemaphore;
 
@@ -158,16 +158,16 @@ void do_page_fault(struct pt_regs *regs,
 	}
 
 	vma = find_vma(mm, address);
-	if (!vma)
+	if (unlikely(!vma))
 		goto bad_area;
 
 	if (vma->vm_start <= address)
 		goto good_area;
 
-	if (!(vma->vm_flags & VM_GROWSDOWN))
+	if (unlikely(!(vma->vm_flags & VM_GROWSDOWN)))
 		goto bad_area;
 
-	if (!is_write)
+	if (unlikely(!is_write))
 		goto bad_area;
 
 	/*
@@ -179,7 +179,7 @@ void do_page_fault(struct pt_regs *regs,
 	 * before setting the user r1.  Thus we allow the stack to
 	 * expand to 1MB without further checks.
 	 */
-	if (address + 0x100000 < vma->vm_end) {
+	if (unlikely(address + 0x100000 < vma->vm_end)) {
 
 		/* get user regs even if this fault is in kernel mode */
 		struct pt_regs *uregs = current->thread.regs;
@@ -209,15 +209,15 @@ good_area:
 	code = SEGV_ACCERR;
 
 	/* a write */
-	if (is_write) {
-		if (!(vma->vm_flags & VM_WRITE))
+	if (unlikely(is_write)) {
+		if (unlikely(!(vma->vm_flags & VM_WRITE)))
 			goto bad_area;
 	/* a read */
 	} else {
 		/* protection fault */
-		if (error_code & 0x08000000)
+		if (unlikely(error_code & 0x08000000))
 			goto bad_area;
-		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+		if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC))))
 			goto bad_area;
 	}
 
@@ -235,7 +235,7 @@ survive:
 			goto do_sigbus;
 		BUG();
 	}
-	if (fault & VM_FAULT_MAJOR)
+	if (unlikely(fault & VM_FAULT_MAJOR))
 		current->maj_flt++;
 	else
 		current->min_flt++;
@@ -273,16 +273,11 @@ bad_area_nosemaphore:
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-	if (current->pid == 1) {
-		yield();
-		down_read(&mm->mmap_sem);
-		goto survive;
-	}
 	up_read(&mm->mmap_sem);
-	printk(KERN_WARNING "VM: killing process %s\n", current->comm);
-	if (user_mode(regs))
-		do_exit(SIGKILL);
-	bad_page_fault(regs, address, SIGKILL);
+	if (!user_mode(regs))
+		bad_page_fault(regs, address, SIGKILL);
+	else
+		pagefault_out_of_memory();
 	return;
 
 do_sigbus:
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/mm/init.c linux-libre-2.6.34-gnu1/arch/microblaze/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/initrd.h>
 #include <linux/pagemap.h>
 #include <linux/pfn.h>
+#include <linux/slab.h>
 #include <linux/swap.h>
 
 #include <asm/page.h>
@@ -23,6 +24,9 @@
 #include <asm/sections.h>
 #include <asm/tlb.h>
 
+/* Use for MMU and noMMU because of PCI generic code */
+int mem_init_done;
+
 #ifndef CONFIG_MMU
 unsigned int __page_offset;
 EXPORT_SYMBOL(__page_offset);
@@ -30,7 +34,6 @@ EXPORT_SYMBOL(__page_offset);
 #else
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
-int mem_init_done;
 static int init_bootmem_done;
 #endif /* CONFIG_MMU */
 
@@ -44,6 +47,7 @@ unsigned long memory_start;
 EXPORT_SYMBOL(memory_start);
 unsigned long memory_end; /* due to mm/nommu.c */
 unsigned long memory_size;
+EXPORT_SYMBOL(memory_size);
 
 /*
  * paging_init() sets up the page tables - in fact we've already done this.
@@ -163,7 +167,6 @@ void free_init_pages(char *what, unsigne
 	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++;
 	}
@@ -193,12 +196,6 @@ void free_initmem(void)
 			(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);
@@ -208,20 +205,14 @@ void __init mem_init(void)
 	printk(KERN_INFO "Memory: %luk/%luk available\n",
 	       nr_free_pages() << (PAGE_SHIFT-10),
 	       num_physpages << (PAGE_SHIFT-10));
-#ifdef CONFIG_MMU
 	mem_init_done = 1;
-#endif
 }
 
 #ifndef CONFIG_MMU
-/* Check against bounds of physical memory */
-int ___range_ok(unsigned long addr, unsigned long size)
+int page_is_ram(unsigned long pfn)
 {
-	return ((addr < memory_start) ||
-		((addr + size) > memory_end));
+	return __range_ok(pfn, 0);
 }
-EXPORT_SYMBOL(___range_ok);
-
 #else
 int page_is_ram(unsigned long pfn)
 {
@@ -349,4 +340,27 @@ void __init *early_get_page(void)
 	}
 	return p;
 }
+
 #endif /* CONFIG_MMU */
+
+void * __init_refok alloc_maybe_bootmem(size_t size, gfp_t mask)
+{
+	if (mem_init_done)
+		return kmalloc(size, mask);
+	else
+		return alloc_bootmem(size);
+}
+
+void * __init_refok zalloc_maybe_bootmem(size_t size, gfp_t mask)
+{
+	void *p;
+
+	if (mem_init_done)
+		p = kzalloc(size, mask);
+	else {
+		p = alloc_bootmem(size);
+		if (p)
+			memset(p, 0, size);
+	}
+	return p;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/mm/Makefile linux-libre-2.6.34-gnu1/arch/microblaze/mm/Makefile
--- linux-libre-2.6.33-gnu1/arch/microblaze/mm/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/mm/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,6 @@
 # Makefile
 #
 
-obj-y := init.o
+obj-y := consistent.o init.o
 
 obj-$(CONFIG_MMU) += pgtable.o mmu_context.o fault.o
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/mm/pgtable.c linux-libre-2.6.34-gnu1/arch/microblaze/mm/pgtable.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/mm/pgtable.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/mm/pgtable.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 
 unsigned long ioremap_base;
 unsigned long ioremap_bot;
+EXPORT_SYMBOL(ioremap_bot);
 
 /* The maximum lowmem defaults to 768Mb, but this can be configured to
  * another value.
@@ -103,7 +104,7 @@ static void __iomem *__ioremap(phys_addr
 		area = get_vm_area(size, VM_IOREMAP);
 		if (area == NULL)
 			return NULL;
-		v = VMALLOC_VMADDR(area->addr);
+		v = (unsigned long) area->addr;
 	} else {
 		v = (ioremap_bot -= size);
 	}
@@ -154,31 +155,13 @@ int map_page(unsigned long va, phys_addr
 		err = 0;
 		set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT,
 				__pgprot(flags)));
-		if (mem_init_done)
+		if (unlikely(mem_init_done))
 			flush_HPTE(0, va, pmd_val(*pd));
 			/* flush_HPTE(0, va, pg); */
 	}
 	return err;
 }
 
-void __init adjust_total_lowmem(void)
-{
-/* TBD */
-#if 0
-	unsigned long max_low_mem = MAX_LOW_MEM;
-
-	if (total_lowmem > max_low_mem) {
-		total_lowmem = max_low_mem;
-#ifndef CONFIG_HIGHMEM
-		printk(KERN_INFO "Warning, memory limited to %ld Mb, use "
-				"CONFIG_HIGHMEM to reach %ld Mb\n",
-				max_low_mem >> 20, total_memory >> 20);
-		total_memory = total_lowmem;
-#endif /* CONFIG_HIGHMEM */
-	}
-#endif
-}
-
 /*
  * Map in all of physical memory starting at CONFIG_KERNEL_START.
  */
@@ -206,24 +189,6 @@ void __init mapin_ram(void)
 /* is x a power of 2? */
 #define is_power_of_2(x)	((x) != 0 && (((x) & ((x) - 1)) == 0))
 
-/*
- * Set up a mapping for a block of I/O.
- * virt, phys, size must all be page-aligned.
- * This should only be called before ioremap is called.
- */
-void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
-			     unsigned int size, int flags)
-{
-	int i;
-
-	if (virt > CONFIG_KERNEL_START && virt < ioremap_bot)
-		ioremap_bot = ioremap_base = virt;
-
-	/* Put it in the page tables. */
-	for (i = 0; i < size; i += PAGE_SIZE)
-		map_page(virt + i, phys + i, flags);
-}
-
 /* Scan the real Linux page tables and return a PTE pointer for
  * a virtual address in a context.
  * Returns true (1) if PTE was found, zero otherwise.  The pointer to
@@ -274,3 +239,18 @@ unsigned long iopa(unsigned long addr)
 
 	return pa;
 }
+
+__init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+		unsigned long address)
+{
+	pte_t *pte;
+	if (mem_init_done) {
+		pte = (pte_t *)__get_free_page(GFP_KERNEL |
+					__GFP_REPEAT | __GFP_ZERO);
+	} else {
+		pte = (pte_t *)early_get_page();
+		if (pte)
+			clear_page(pte);
+	}
+	return pte;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/pci/indirect_pci.c linux-libre-2.6.34-gnu1/arch/microblaze/pci/indirect_pci.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/pci/indirect_pci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/pci/indirect_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,163 @@
+/*
+ * Support for indirect PCI bridges.
+ *
+ * Copyright (C) 1998 Gabriel Paubert.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+
+static int
+indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+		     int len, u32 *val)
+{
+	struct pci_controller *hose = pci_bus_to_host(bus);
+	volatile void __iomem *cfg_data;
+	u8 cfg_type = 0;
+	u32 bus_no, reg;
+
+	if (hose->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) {
+		if (bus->number != hose->first_busno)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+		if (devfn != 0)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	if (hose->indirect_type & INDIRECT_TYPE_SET_CFG_TYPE)
+		if (bus->number != hose->first_busno)
+			cfg_type = 1;
+
+	bus_no = (bus->number == hose->first_busno) ?
+			hose->self_busno : bus->number;
+
+	if (hose->indirect_type & INDIRECT_TYPE_EXT_REG)
+		reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
+	else
+		reg = offset & 0xfc; /* Only 3 bits for function */
+
+	if (hose->indirect_type & INDIRECT_TYPE_BIG_ENDIAN)
+		out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+			 (devfn << 8) | reg | cfg_type));
+	else
+		out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+			 (devfn << 8) | reg | cfg_type));
+
+	/*
+	 * Note: the caller has already checked that offset is
+	 * suitably aligned and that len is 1, 2 or 4.
+	 */
+	cfg_data = hose->cfg_data + (offset & 3); /* Only 3 bits for function */
+	switch (len) {
+	case 1:
+		*val = in_8(cfg_data);
+		break;
+	case 2:
+		*val = in_le16(cfg_data);
+		break;
+	default:
+		*val = in_le32(cfg_data);
+		break;
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+		      int len, u32 val)
+{
+	struct pci_controller *hose = pci_bus_to_host(bus);
+	volatile void __iomem *cfg_data;
+	u8 cfg_type = 0;
+	u32 bus_no, reg;
+
+	if (hose->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) {
+		if (bus->number != hose->first_busno)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+		if (devfn != 0)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	if (hose->indirect_type & INDIRECT_TYPE_SET_CFG_TYPE)
+		if (bus->number != hose->first_busno)
+			cfg_type = 1;
+
+	bus_no = (bus->number == hose->first_busno) ?
+			hose->self_busno : bus->number;
+
+	if (hose->indirect_type & INDIRECT_TYPE_EXT_REG)
+		reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
+	else
+		reg = offset & 0xfc;
+
+	if (hose->indirect_type & INDIRECT_TYPE_BIG_ENDIAN)
+		out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+			 (devfn << 8) | reg | cfg_type));
+	else
+		out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+			 (devfn << 8) | reg | cfg_type));
+
+	/* surpress setting of PCI_PRIMARY_BUS */
+	if (hose->indirect_type & INDIRECT_TYPE_SURPRESS_PRIMARY_BUS)
+		if ((offset == PCI_PRIMARY_BUS) &&
+			(bus->number == hose->first_busno))
+			val &= 0xffffff00;
+
+	/* Workaround for PCI_28 Errata in 440EPx/GRx */
+	if ((hose->indirect_type & INDIRECT_TYPE_BROKEN_MRM) &&
+			offset == PCI_CACHE_LINE_SIZE) {
+		val = 0;
+	}
+
+	/*
+	 * Note: the caller has already checked that offset is
+	 * suitably aligned and that len is 1, 2 or 4.
+	 */
+	cfg_data = hose->cfg_data + (offset & 3);
+	switch (len) {
+	case 1:
+		out_8(cfg_data, val);
+		break;
+	case 2:
+		out_le16(cfg_data, val);
+		break;
+	default:
+		out_le32(cfg_data, val);
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops indirect_pci_ops = {
+	.read = indirect_read_config,
+	.write = indirect_write_config,
+};
+
+void __init
+setup_indirect_pci(struct pci_controller *hose,
+		   resource_size_t cfg_addr,
+		   resource_size_t cfg_data, u32 flags)
+{
+	resource_size_t base = cfg_addr & PAGE_MASK;
+	void __iomem *mbase;
+
+	mbase = ioremap(base, PAGE_SIZE);
+	hose->cfg_addr = mbase + (cfg_addr & ~PAGE_MASK);
+	if ((cfg_data & PAGE_MASK) != base)
+		mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE);
+	hose->cfg_data = mbase + (cfg_data & ~PAGE_MASK);
+	hose->ops = &indirect_pci_ops;
+	hose->indirect_type = flags;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/pci/iomap.c linux-libre-2.6.34-gnu1/arch/microblaze/pci/iomap.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/pci/iomap.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/pci/iomap.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,39 @@
+/*
+ * ppc64 "iomap" interface implementation.
+ *
+ * (C) Copyright 2004 Linus Torvalds
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pci-bridge.h>
+
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
+{
+	resource_size_t start = pci_resource_start(dev, bar);
+	resource_size_t len = pci_resource_len(dev, bar);
+	unsigned long flags = pci_resource_flags(dev, bar);
+
+	if (!len)
+		return NULL;
+	if (max && len > max)
+		len = max;
+	if (flags & IORESOURCE_IO)
+		return ioport_map(start, len);
+	if (flags & IORESOURCE_MEM)
+		return ioremap(start, len);
+	/* What? */
+	return NULL;
+}
+EXPORT_SYMBOL(pci_iomap);
+
+void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+{
+	if (isa_vaddr_is_ioport(addr))
+		return;
+	if (pcibios_vaddr_is_ioport(addr))
+		return;
+	iounmap(addr);
+}
+EXPORT_SYMBOL(pci_iounmap);
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/pci/Makefile linux-libre-2.6.34-gnu1/arch/microblaze/pci/Makefile
--- linux-libre-2.6.33-gnu1/arch/microblaze/pci/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/pci/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,6 @@
+#
+# Makefile
+#
+
+obj-$(CONFIG_PCI)		+= pci_32.o pci-common.o indirect_pci.o iomap.o
+obj-$(CONFIG_PCI_XILINX)	+= xilinx_pci.o
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/pci/pci_32.c linux-libre-2.6.34-gnu1/arch/microblaze/pci/pci_32.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/pci/pci_32.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/pci/pci_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,431 @@
+/*
+ * Common pmac/prep/chrp pci routines. -- Cort
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/capability.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+#include <linux/list.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/sections.h>
+#include <asm/pci-bridge.h>
+#include <asm/byteorder.h>
+#include <asm/uaccess.h>
+
+#undef DEBUG
+
+unsigned long isa_io_base;
+unsigned long pci_dram_offset;
+int pcibios_assign_bus_offset = 1;
+
+static u8 *pci_to_OF_bus_map;
+
+/* By default, we don't re-assign bus numbers. We do this only on
+ * some pmacs
+ */
+static int pci_assign_all_buses;
+
+static int pci_bus_count;
+
+/*
+ * Functions below are used on OpenFirmware machines.
+ */
+static void
+make_one_node_map(struct device_node *node, u8 pci_bus)
+{
+	const int *bus_range;
+	int len;
+
+	if (pci_bus >= pci_bus_count)
+		return;
+	bus_range = of_get_property(node, "bus-range", &len);
+	if (bus_range == NULL || len < 2 * sizeof(int)) {
+		printk(KERN_WARNING "Can't get bus-range for %s, "
+		       "assuming it starts at 0\n", node->full_name);
+		pci_to_OF_bus_map[pci_bus] = 0;
+	} else
+		pci_to_OF_bus_map[pci_bus] = bus_range[0];
+
+	for_each_child_of_node(node, node) {
+		struct pci_dev *dev;
+		const unsigned int *class_code, *reg;
+
+		class_code = of_get_property(node, "class-code", NULL);
+		if (!class_code ||
+			((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
+			(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
+			continue;
+		reg = of_get_property(node, "reg", NULL);
+		if (!reg)
+			continue;
+		dev = pci_get_bus_and_slot(pci_bus, ((reg[0] >> 8) & 0xff));
+		if (!dev || !dev->subordinate) {
+			pci_dev_put(dev);
+			continue;
+		}
+		make_one_node_map(node, dev->subordinate->number);
+		pci_dev_put(dev);
+	}
+}
+
+void
+pcibios_make_OF_bus_map(void)
+{
+	int i;
+	struct pci_controller *hose, *tmp;
+	struct property *map_prop;
+	struct device_node *dn;
+
+	pci_to_OF_bus_map = kmalloc(pci_bus_count, GFP_KERNEL);
+	if (!pci_to_OF_bus_map) {
+		printk(KERN_ERR "Can't allocate OF bus map !\n");
+		return;
+	}
+
+	/* We fill the bus map with invalid values, that helps
+	 * debugging.
+	 */
+	for (i = 0; i < pci_bus_count; i++)
+		pci_to_OF_bus_map[i] = 0xff;
+
+	/* For each hose, we begin searching bridges */
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+		struct device_node *node = hose->dn;
+
+		if (!node)
+			continue;
+		make_one_node_map(node, hose->first_busno);
+	}
+	dn = of_find_node_by_path("/");
+	map_prop = of_find_property(dn, "pci-OF-bus-map", NULL);
+	if (map_prop) {
+		BUG_ON(pci_bus_count > map_prop->length);
+		memcpy(map_prop->value, pci_to_OF_bus_map, pci_bus_count);
+	}
+	of_node_put(dn);
+#ifdef DEBUG
+	printk(KERN_INFO "PCI->OF bus map:\n");
+	for (i = 0; i < pci_bus_count; i++) {
+		if (pci_to_OF_bus_map[i] == 0xff)
+			continue;
+		printk(KERN_INFO "%d -> %d\n", i, pci_to_OF_bus_map[i]);
+	}
+#endif
+}
+
+typedef int (*pci_OF_scan_iterator)(struct device_node *node, void *data);
+
+static struct device_node *scan_OF_pci_childs(struct device_node *parent,
+					pci_OF_scan_iterator filter, void *data)
+{
+	struct device_node *node;
+	struct device_node *sub_node;
+
+	for_each_child_of_node(parent, node) {
+		const unsigned int *class_code;
+
+		if (filter(node, data)) {
+			of_node_put(node);
+			return node;
+		}
+
+		/* For PCI<->PCI bridges or CardBus bridges, we go down
+		 * 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.
+		 */
+		class_code = of_get_property(node, "class-code", NULL);
+		if ((!class_code ||
+			((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
+			(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
+			strcmp(node->name, "multifunc-device"))
+			continue;
+		sub_node = scan_OF_pci_childs(node, filter, data);
+		if (sub_node) {
+			of_node_put(node);
+			return sub_node;
+		}
+	}
+	return NULL;
+}
+
+static struct device_node *scan_OF_for_pci_dev(struct device_node *parent,
+					       unsigned int devfn)
+{
+	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 && 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;
+}
+
+
+static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus)
+{
+	struct device_node *parent, *np;
+
+	/* Are we a root bus ? */
+	if (bus->self == NULL || bus->parent == NULL) {
+		struct pci_controller *hose = pci_bus_to_host(bus);
+		if (hose == NULL)
+			return NULL;
+		return of_node_get(hose->dn);
+	}
+
+	/* not a root bus, we need to get our parent */
+	parent = scan_OF_for_pci_bus(bus->parent);
+	if (parent == NULL)
+		return NULL;
+
+	/* now iterate for children for a match */
+	np = scan_OF_for_pci_dev(parent, bus->self->devfn);
+	of_node_put(parent);
+
+	return np;
+}
+
+/*
+ * Scans the OF tree for a device node matching a PCI device
+ */
+struct device_node *
+pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
+{
+	struct device_node *parent, *np;
+
+	pr_debug("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn);
+	parent = scan_OF_for_pci_bus(bus);
+	if (parent == NULL)
+		return NULL;
+	pr_debug(" parent is %s\n", parent ? parent->full_name : "<NULL>");
+	np = scan_OF_for_pci_dev(parent, devfn);
+	of_node_put(parent);
+	pr_debug(" result is %s\n", np ? np->full_name : "<NULL>");
+
+	/* XXX most callers don't release the returned node
+	 * mostly because ppc64 doesn't increase the refcount,
+	 * we need to fix that.
+	 */
+	return np;
+}
+EXPORT_SYMBOL(pci_busdev_to_OF_node);
+
+struct device_node*
+pci_device_to_OF_node(struct pci_dev *dev)
+{
+	return pci_busdev_to_OF_node(dev->bus, dev->devfn);
+}
+EXPORT_SYMBOL(pci_device_to_OF_node);
+
+static int
+find_OF_pci_device_filter(struct device_node *node, void *data)
+{
+	return ((void *)node == data);
+}
+
+/*
+ * Returns the PCI device matching a given OF node
+ */
+int
+pci_device_from_OF_node(struct device_node *node, u8 *bus, u8 *devfn)
+{
+	const unsigned int *reg;
+	struct pci_controller *hose;
+	struct pci_dev *dev = NULL;
+
+	/* Make sure it's really a PCI device */
+	hose = pci_find_hose_for_OF_device(node);
+	if (!hose || !hose->dn)
+		return -ENODEV;
+	if (!scan_OF_pci_childs(hose->dn,
+			find_OF_pci_device_filter, (void *)node))
+		return -ENODEV;
+	reg = of_get_property(node, "reg", NULL);
+	if (!reg)
+		return -ENODEV;
+	*bus = (reg[0] >> 16) & 0xff;
+	*devfn = ((reg[0] >> 8) & 0xff);
+
+	/* Ok, here we need some tweak. If we have already renumbered
+	 * all busses, we can't rely on the OF bus number any more.
+	 * the pci_to_OF_bus_map is not enough as several PCI busses
+	 * may match the same OF bus number.
+	 */
+	if (!pci_to_OF_bus_map)
+		return 0;
+
+	for_each_pci_dev(dev)
+		if (pci_to_OF_bus_map[dev->bus->number] == *bus &&
+				dev->devfn == *devfn) {
+			*bus = dev->bus->number;
+			pci_dev_put(dev);
+			return 0;
+		}
+
+	return -ENODEV;
+}
+EXPORT_SYMBOL(pci_device_from_OF_node);
+
+/* We create the "pci-OF-bus-map" property now so it appears in the
+ * /proc device tree
+ */
+void __init
+pci_create_OF_bus_map(void)
+{
+	struct property *of_prop;
+	struct device_node *dn;
+
+	of_prop = (struct property *) alloc_bootmem(sizeof(struct property) + \
+									 256);
+	if (!of_prop)
+		return;
+	dn = of_find_node_by_path("/");
+	if (dn) {
+		memset(of_prop, -1, sizeof(struct property) + 256);
+		of_prop->name = "pci-OF-bus-map";
+		of_prop->length = 256;
+		of_prop->value = &of_prop[1];
+		prom_add_property(dn, of_prop);
+		of_node_put(dn);
+	}
+}
+
+static void __devinit pcibios_scan_phb(struct pci_controller *hose)
+{
+	struct pci_bus *bus;
+	struct device_node *node = hose->dn;
+	unsigned long io_offset;
+	struct resource *res = &hose->io_resource;
+
+	pr_debug("PCI: Scanning PHB %s\n",
+		 node ? node->full_name : "<NO NAME>");
+
+	/* Create an empty bus for the toplevel */
+	bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
+	if (bus == NULL) {
+		printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
+		       hose->global_number);
+		return;
+	}
+	bus->secondary = hose->first_busno;
+	hose->bus = bus;
+
+	/* Fixup IO space offset */
+	io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
+	res->start = (res->start + io_offset) & 0xffffffffu;
+	res->end = (res->end + io_offset) & 0xffffffffu;
+
+	/* Wire up PHB bus resources */
+	pcibios_setup_phb_resources(hose);
+
+	/* Scan children */
+	hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
+}
+
+static int __init pcibios_init(void)
+{
+	struct pci_controller *hose, *tmp;
+	int next_busno = 0;
+
+	printk(KERN_INFO "PCI: Probing PCI hardware\n");
+
+	if (pci_flags & PCI_REASSIGN_ALL_BUS) {
+		printk(KERN_INFO "setting pci_asign_all_busses\n");
+		pci_assign_all_buses = 1;
+	}
+
+	/* Scan all of the recorded PCI controllers.  */
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+		if (pci_assign_all_buses)
+			hose->first_busno = next_busno;
+		hose->last_busno = 0xff;
+		pcibios_scan_phb(hose);
+		printk(KERN_INFO "calling pci_bus_add_devices()\n");
+		pci_bus_add_devices(hose->bus);
+		if (pci_assign_all_buses || next_busno <= hose->last_busno)
+			next_busno = hose->last_busno + \
+					pcibios_assign_bus_offset;
+	}
+	pci_bus_count = next_busno;
+
+	/* OpenFirmware based machines need a map of OF bus
+	 * numbers vs. kernel bus numbers since we may have to
+	 * remap them.
+	 */
+	if (pci_assign_all_buses)
+		pcibios_make_OF_bus_map();
+
+	/* Call common code to handle resource allocation */
+	pcibios_resource_survey();
+
+	return 0;
+}
+
+subsys_initcall(pcibios_init);
+
+static struct pci_controller*
+pci_bus_to_hose(int bus)
+{
+	struct pci_controller *hose, *tmp;
+
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+		if (bus >= hose->first_busno && bus <= hose->last_busno)
+			return hose;
+	return NULL;
+}
+
+/* Provide information on locations of various I/O regions in physical
+ * memory.  Do this on a per-card basis so that we choose the right
+ * root bridge.
+ * Note that the returned IO or memory base is a physical address
+ */
+
+long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
+{
+	struct pci_controller *hose;
+	long result = -EOPNOTSUPP;
+
+	hose = pci_bus_to_hose(bus);
+	if (!hose)
+		return -ENODEV;
+
+	switch (which) {
+	case IOBASE_BRIDGE_NUMBER:
+		return (long)hose->first_busno;
+	case IOBASE_MEMORY:
+		return (long)hose->pci_mem_offset;
+	case IOBASE_IO:
+		return (long)hose->io_base_phys;
+	case IOBASE_ISA_IO:
+		return (long)isa_io_base;
+	case IOBASE_ISA_MEM:
+		return (long)isa_mem_base;
+	}
+
+	return result;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/pci/pci-common.c linux-libre-2.6.34-gnu1/arch/microblaze/pci/pci-common.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/pci/pci-common.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/pci/pci-common.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1642 @@
+/*
+ * Contains common pci routines for ALL ppc platform
+ * (based on pci_32.c and pci_64.c)
+ *
+ * Port for PPC64 David Engebretsen, IBM Corp.
+ * Contains common pci routines for ppc64 platform, pSeries and iSeries brands.
+ *
+ * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
+ *   Rework, based on alpha PCI code.
+ *
+ * Common pmac/prep/chrp pci routines. -- Cort
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+#include <linux/syscalls.h>
+#include <linux/irq.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/byteorder.h>
+
+static DEFINE_SPINLOCK(hose_spinlock);
+LIST_HEAD(hose_list);
+
+/* XXX kill that some day ... */
+static int global_phb_number;		/* Global phb counter */
+
+/* ISA Memory physical address */
+resource_size_t isa_mem_base;
+
+/* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */
+unsigned int pci_flags;
+
+static struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
+
+void set_pci_dma_ops(struct dma_map_ops *dma_ops)
+{
+	pci_dma_ops = dma_ops;
+}
+
+struct dma_map_ops *get_pci_dma_ops(void)
+{
+	return pci_dma_ops;
+}
+EXPORT_SYMBOL(get_pci_dma_ops);
+
+int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
+{
+	return dma_set_mask(&dev->dev, mask);
+}
+
+int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
+{
+	int rc;
+
+	rc = dma_set_mask(&dev->dev, mask);
+	dev->dev.coherent_dma_mask = dev->dma_mask;
+
+	return rc;
+}
+
+struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
+{
+	struct pci_controller *phb;
+
+	phb = zalloc_maybe_bootmem(sizeof(struct pci_controller), GFP_KERNEL);
+	if (!phb)
+		return NULL;
+	spin_lock(&hose_spinlock);
+	phb->global_number = global_phb_number++;
+	list_add_tail(&phb->list_node, &hose_list);
+	spin_unlock(&hose_spinlock);
+	phb->dn = dev;
+	phb->is_dynamic = mem_init_done;
+	return phb;
+}
+
+void pcibios_free_controller(struct pci_controller *phb)
+{
+	spin_lock(&hose_spinlock);
+	list_del(&phb->list_node);
+	spin_unlock(&hose_spinlock);
+
+	if (phb->is_dynamic)
+		kfree(phb);
+}
+
+static resource_size_t pcibios_io_size(const struct pci_controller *hose)
+{
+	return hose->io_resource.end - hose->io_resource.start + 1;
+}
+
+int pcibios_vaddr_is_ioport(void __iomem *address)
+{
+	int ret = 0;
+	struct pci_controller *hose;
+	resource_size_t size;
+
+	spin_lock(&hose_spinlock);
+	list_for_each_entry(hose, &hose_list, list_node) {
+		size = pcibios_io_size(hose);
+		if (address >= hose->io_base_virt &&
+		    address < (hose->io_base_virt + size)) {
+			ret = 1;
+			break;
+		}
+	}
+	spin_unlock(&hose_spinlock);
+	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.
+ */
+int pci_domain_nr(struct pci_bus *bus)
+{
+	struct pci_controller *hose = pci_bus_to_host(bus);
+
+	return hose->global_number;
+}
+EXPORT_SYMBOL(pci_domain_nr);
+
+/* This routine is meant to be used early during boot, when the
+ * PCI bus numbers have not yet been assigned, and you need to
+ * issue PCI config cycles to an OF device.
+ * It could also be used to "fix" RTAS config cycles if you want
+ * to set pci_assign_all_buses to 1 and still use RTAS for PCI
+ * config cycles.
+ */
+struct pci_controller *pci_find_hose_for_OF_device(struct device_node *node)
+{
+	while (node) {
+		struct pci_controller *hose, *tmp;
+		list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+			if (hose->dn == node)
+				return hose;
+		node = node->parent;
+	}
+	return NULL;
+}
+
+static ssize_t pci_show_devspec(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct pci_dev *pdev;
+	struct device_node *np;
+
+	pdev = to_pci_dev(dev);
+	np = pci_device_to_OF_node(pdev);
+	if (np == NULL || np->full_name == NULL)
+		return 0;
+	return sprintf(buf, "%s", np->full_name);
+}
+static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
+
+/* Add sysfs properties */
+int pcibios_add_platform_entries(struct pci_dev *pdev)
+{
+	return device_create_file(&pdev->dev, &dev_attr_devspec);
+}
+
+char __devinit *pcibios_setup(char *str)
+{
+	return str;
+}
+
+/*
+ * Reads the interrupt pin to determine if interrupt is use by card.
+ * If the interrupt is used, then gets the interrupt line from the
+ * openfirmware and sets it in the pci_dev and pci_config line.
+ */
+int pci_read_irq_line(struct pci_dev *pci_dev)
+{
+	struct of_irq oirq;
+	unsigned int virq;
+
+	/* The current device-tree that iSeries generates from the HV
+	 * PCI informations doesn't contain proper interrupt routing,
+	 * and all the fallback would do is print out crap, so we
+	 * don't attempt to resolve the interrupts here at all, some
+	 * iSeries specific fixup does it.
+	 *
+	 * In the long run, we will hopefully fix the generated device-tree
+	 * instead.
+	 */
+	pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev));
+
+#ifdef DEBUG
+	memset(&oirq, 0xff, sizeof(oirq));
+#endif
+	/* Try to get a mapping from the device-tree */
+	if (of_irq_map_pci(pci_dev, &oirq)) {
+		u8 line, pin;
+
+		/* If that fails, lets fallback to what is in the config
+		 * space and map that through the default controller. We
+		 * also set the type to level low since that's what PCI
+		 * interrupts are. If your platform does differently, then
+		 * either provide a proper interrupt tree or don't use this
+		 * function.
+		 */
+		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
+			return -1;
+		if (pin == 0)
+			return -1;
+		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
+		    line == 0xff || line == 0) {
+			return -1;
+		}
+		pr_debug(" No map ! Using line %d (pin %d) from PCI config\n",
+			 line, pin);
+
+		virq = irq_create_mapping(NULL, line);
+		if (virq != NO_IRQ)
+			set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
+	} else {
+		pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
+			 oirq.size, oirq.specifier[0], oirq.specifier[1],
+			 oirq.controller ? oirq.controller->full_name :
+			 "<default>");
+
+		virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+					     oirq.size);
+	}
+	if (virq == NO_IRQ) {
+		pr_debug(" Failed to map !\n");
+		return -1;
+	}
+
+	pr_debug(" Mapped to linux irq %d\n", virq);
+
+	pci_dev->irq = virq;
+
+	return 0;
+}
+EXPORT_SYMBOL(pci_read_irq_line);
+
+/*
+ * Platform support for /proc/bus/pci/X/Y mmap()s,
+ * modelled on the sparc64 implementation by Dave Miller.
+ *  -- paulus.
+ */
+
+/*
+ * Adjust vm_pgoff of VMA such that it is the physical page offset
+ * corresponding to the 32-bit pci bus offset for DEV requested by the user.
+ *
+ * Basically, the user finds the base address for his device which he wishes
+ * to mmap.  They read the 32-bit value from the config space base register,
+ * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
+ * offset parameter of mmap on /proc/bus/pci/XXX for that device.
+ *
+ * Returns negative error code on failure, zero on success.
+ */
+static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
+					       resource_size_t *offset,
+					       enum pci_mmap_state mmap_state)
+{
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	unsigned long io_offset = 0;
+	int i, res_bit;
+
+	if (hose == 0)
+		return NULL;		/* should never happen */
+
+	/* If memory, add on the PCI bridge address offset */
+	if (mmap_state == pci_mmap_mem) {
+#if 0 /* See comment in pci_resource_to_user() for why this is disabled */
+		*offset += hose->pci_mem_offset;
+#endif
+		res_bit = IORESOURCE_MEM;
+	} else {
+		io_offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+		*offset += io_offset;
+		res_bit = IORESOURCE_IO;
+	}
+
+	/*
+	 * Check that the offset requested corresponds to one of the
+	 * resources of the device.
+	 */
+	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+		struct resource *rp = &dev->resource[i];
+		int flags = rp->flags;
+
+		/* treat ROM as memory (should be already) */
+		if (i == PCI_ROM_RESOURCE)
+			flags |= IORESOURCE_MEM;
+
+		/* Active and same type? */
+		if ((flags & res_bit) == 0)
+			continue;
+
+		/* In the range of this resource? */
+		if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
+			continue;
+
+		/* found it! construct the final physical address */
+		if (mmap_state == pci_mmap_io)
+			*offset += hose->io_base_phys - io_offset;
+		return rp;
+	}
+
+	return NULL;
+}
+
+/*
+ * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
+ * device mapping.
+ */
+static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
+				      pgprot_t protection,
+				      enum pci_mmap_state mmap_state,
+				      int write_combine)
+{
+	pgprot_t prot = protection;
+
+	/* Write combine is always 0 on non-memory space mappings. On
+	 * memory space, if the user didn't pass 1, we check for a
+	 * "prefetchable" resource. This is a bit hackish, but we use
+	 * this to workaround the inability of /sysfs to provide a write
+	 * combine bit
+	 */
+	if (mmap_state != pci_mmap_mem)
+		write_combine = 0;
+	else if (write_combine == 0) {
+		if (rp->flags & IORESOURCE_PREFETCH)
+			write_combine = 1;
+	}
+
+	return pgprot_noncached(prot);
+}
+
+/*
+ * This one is used by /dev/mem and fbdev who have no clue about the
+ * PCI device, it tries to find the PCI device first and calls the
+ * above routine
+ */
+pgprot_t pci_phys_mem_access_prot(struct file *file,
+				  unsigned long pfn,
+				  unsigned long size,
+				  pgprot_t prot)
+{
+	struct pci_dev *pdev = NULL;
+	struct resource *found = NULL;
+	resource_size_t offset = ((resource_size_t)pfn) << PAGE_SHIFT;
+	int i;
+
+	if (page_is_ram(pfn))
+		return prot;
+
+	prot = pgprot_noncached(prot);
+	for_each_pci_dev(pdev) {
+		for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+			struct resource *rp = &pdev->resource[i];
+			int flags = rp->flags;
+
+			/* Active and same type? */
+			if ((flags & IORESOURCE_MEM) == 0)
+				continue;
+			/* In the range of this resource? */
+			if (offset < (rp->start & PAGE_MASK) ||
+			    offset > rp->end)
+				continue;
+			found = rp;
+			break;
+		}
+		if (found)
+			break;
+	}
+	if (found) {
+		if (found->flags & IORESOURCE_PREFETCH)
+			prot = pgprot_noncached_wc(prot);
+		pci_dev_put(pdev);
+	}
+
+	pr_debug("PCI: Non-PCI map for %llx, prot: %lx\n",
+		 (unsigned long long)offset, pgprot_val(prot));
+
+	return prot;
+}
+
+/*
+ * Perform the actual remap of the pages for a PCI device mapping, as
+ * appropriate for this architecture.  The region in the process to map
+ * is described by vm_start and vm_end members of VMA, the base physical
+ * address is found in vm_pgoff.
+ * The pci device structure is provided so that architectures may make mapping
+ * decisions on a per-device or per-bus basis.
+ *
+ * Returns a negative error code on failure, zero on success.
+ */
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state, int write_combine)
+{
+	resource_size_t offset =
+		((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT;
+	struct resource *rp;
+	int ret;
+
+	rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
+	if (rp == NULL)
+		return -EINVAL;
+
+	vma->vm_pgoff = offset >> PAGE_SHIFT;
+	vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
+						  vma->vm_page_prot,
+						  mmap_state, write_combine);
+
+	ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
+
+	return ret;
+}
+
+/* This provides legacy IO read access on a bus */
+int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size)
+{
+	unsigned long offset;
+	struct pci_controller *hose = pci_bus_to_host(bus);
+	struct resource *rp = &hose->io_resource;
+	void __iomem *addr;
+
+	/* Check if port can be supported by that bus. We only check
+	 * the ranges of the PHB though, not the bus itself as the rules
+	 * for forwarding legacy cycles down bridges are not our problem
+	 * here. So if the host bridge supports it, we do it.
+	 */
+	offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+	offset += port;
+
+	if (!(rp->flags & IORESOURCE_IO))
+		return -ENXIO;
+	if (offset < rp->start || (offset + size) > rp->end)
+		return -ENXIO;
+	addr = hose->io_base_virt + port;
+
+	switch (size) {
+	case 1:
+		*((u8 *)val) = in_8(addr);
+		return 1;
+	case 2:
+		if (port & 1)
+			return -EINVAL;
+		*((u16 *)val) = in_le16(addr);
+		return 2;
+	case 4:
+		if (port & 3)
+			return -EINVAL;
+		*((u32 *)val) = in_le32(addr);
+		return 4;
+	}
+	return -EINVAL;
+}
+
+/* This provides legacy IO write access on a bus */
+int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size)
+{
+	unsigned long offset;
+	struct pci_controller *hose = pci_bus_to_host(bus);
+	struct resource *rp = &hose->io_resource;
+	void __iomem *addr;
+
+	/* Check if port can be supported by that bus. We only check
+	 * the ranges of the PHB though, not the bus itself as the rules
+	 * for forwarding legacy cycles down bridges are not our problem
+	 * here. So if the host bridge supports it, we do it.
+	 */
+	offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+	offset += port;
+
+	if (!(rp->flags & IORESOURCE_IO))
+		return -ENXIO;
+	if (offset < rp->start || (offset + size) > rp->end)
+		return -ENXIO;
+	addr = hose->io_base_virt + port;
+
+	/* WARNING: The generic code is idiotic. It gets passed a pointer
+	 * to what can be a 1, 2 or 4 byte quantity and always reads that
+	 * as a u32, which means that we have to correct the location of
+	 * the data read within those 32 bits for size 1 and 2
+	 */
+	switch (size) {
+	case 1:
+		out_8(addr, val >> 24);
+		return 1;
+	case 2:
+		if (port & 1)
+			return -EINVAL;
+		out_le16(addr, val >> 16);
+		return 2;
+	case 4:
+		if (port & 3)
+			return -EINVAL;
+		out_le32(addr, val);
+		return 4;
+	}
+	return -EINVAL;
+}
+
+/* This provides legacy IO or memory mmap access on a bus */
+int pci_mmap_legacy_page_range(struct pci_bus *bus,
+			       struct vm_area_struct *vma,
+			       enum pci_mmap_state mmap_state)
+{
+	struct pci_controller *hose = pci_bus_to_host(bus);
+	resource_size_t offset =
+		((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT;
+	resource_size_t size = vma->vm_end - vma->vm_start;
+	struct resource *rp;
+
+	pr_debug("pci_mmap_legacy_page_range(%04x:%02x, %s @%llx..%llx)\n",
+		 pci_domain_nr(bus), bus->number,
+		 mmap_state == pci_mmap_mem ? "MEM" : "IO",
+		 (unsigned long long)offset,
+		 (unsigned long long)(offset + size - 1));
+
+	if (mmap_state == pci_mmap_mem) {
+		/* Hack alert !
+		 *
+		 * Because X is lame and can fail starting if it gets an error
+		 * trying to mmap legacy_mem (instead of just moving on without
+		 * legacy memory access) we fake it here by giving it anonymous
+		 * memory, effectively behaving just like /dev/zero
+		 */
+		if ((offset + size) > hose->isa_mem_size) {
+#ifdef CONFIG_MMU
+			printk(KERN_DEBUG
+				"Process %s (pid:%d) mapped non-existing PCI"
+				"legacy memory for 0%04x:%02x\n",
+				current->comm, current->pid, pci_domain_nr(bus),
+								bus->number);
+#endif
+			if (vma->vm_flags & VM_SHARED)
+				return shmem_zero_setup(vma);
+			return 0;
+		}
+		offset += hose->isa_mem_phys;
+	} else {
+		unsigned long io_offset = (unsigned long)hose->io_base_virt - \
+								_IO_BASE;
+		unsigned long roffset = offset + io_offset;
+		rp = &hose->io_resource;
+		if (!(rp->flags & IORESOURCE_IO))
+			return -ENXIO;
+		if (roffset < rp->start || (roffset + size) > rp->end)
+			return -ENXIO;
+		offset += hose->io_base_phys;
+	}
+	pr_debug(" -> mapping phys %llx\n", (unsigned long long)offset);
+
+	vma->vm_pgoff = offset >> PAGE_SHIFT;
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+			       vma->vm_end - vma->vm_start,
+			       vma->vm_page_prot);
+}
+
+void pci_resource_to_user(const struct pci_dev *dev, int bar,
+			  const struct resource *rsrc,
+			  resource_size_t *start, resource_size_t *end)
+{
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	resource_size_t offset = 0;
+
+	if (hose == NULL)
+		return;
+
+	if (rsrc->flags & IORESOURCE_IO)
+		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+
+	/* We pass a fully fixed up address to userland for MMIO instead of
+	 * a BAR value because X is lame and expects to be able to use that
+	 * to pass to /dev/mem !
+	 *
+	 * That means that we'll have potentially 64 bits values where some
+	 * userland apps only expect 32 (like X itself since it thinks only
+	 * Sparc has 64 bits MMIO) but if we don't do that, we break it on
+	 * 32 bits CHRPs :-(
+	 *
+	 * Hopefully, the sysfs insterface is immune to that gunk. Once X
+	 * has been fixed (and the fix spread enough), we can re-enable the
+	 * 2 lines below and pass down a BAR value to userland. In that case
+	 * we'll also have to re-enable the matching code in
+	 * __pci_mmap_make_offset().
+	 *
+	 * BenH.
+	 */
+#if 0
+	else if (rsrc->flags & IORESOURCE_MEM)
+		offset = hose->pci_mem_offset;
+#endif
+
+	*start = rsrc->start - offset;
+	*end = rsrc->end - offset;
+}
+
+/**
+ * pci_process_bridge_OF_ranges - Parse PCI bridge resources from device tree
+ * @hose: newly allocated pci_controller to be setup
+ * @dev: device node of the host bridge
+ * @primary: set if primary bus (32 bits only, soon to be deprecated)
+ *
+ * This function will parse the "ranges" property of a PCI host bridge device
+ * node and setup the resource mapping of a pci controller based on its
+ * content.
+ *
+ * Life would be boring if it wasn't for a few issues that we have to deal
+ * with here:
+ *
+ *   - We can only cope with one IO space range and up to 3 Memory space
+ *     ranges. However, some machines (thanks Apple !) tend to split their
+ *     space into lots of small contiguous ranges. So we have to coalesce.
+ *
+ *   - We can only cope with all memory ranges having the same offset
+ *     between CPU addresses and PCI addresses. Unfortunately, some bridges
+ *     are setup for a large 1:1 mapping along with a small "window" which
+ *     maps PCI address 0 to some arbitrary high address of the CPU space in
+ *     order to give access to the ISA memory hole.
+ *     The way out of here that I've chosen for now is to always set the
+ *     offset based on the first resource found, then override it if we
+ *     have a different offset and the previous was set by an ISA hole.
+ *
+ *   - Some busses have IO space not starting at 0, which causes trouble with
+ *     the way we do our IO resource renumbering. The code somewhat deals with
+ *     it for 64 bits but I would expect problems on 32 bits.
+ *
+ *   - Some 32 bits platforms such as 4xx can have physical space larger than
+ *     32 bits so we need to use 64 bits values for the parsing
+ */
+void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
+					    struct device_node *dev,
+					    int primary)
+{
+	const u32 *ranges;
+	int rlen;
+	int pna = of_n_addr_cells(dev);
+	int np = pna + 5;
+	int memno = 0, isa_hole = -1;
+	u32 pci_space;
+	unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size;
+	unsigned long long isa_mb = 0;
+	struct resource *res;
+
+	printk(KERN_INFO "PCI host bridge %s %s ranges:\n",
+	       dev->full_name, primary ? "(primary)" : "");
+
+	/* Get ranges property */
+	ranges = of_get_property(dev, "ranges", &rlen);
+	if (ranges == NULL)
+		return;
+
+	/* Parse it */
+	pr_debug("Parsing ranges property...\n");
+	while ((rlen -= np * 4) >= 0) {
+		/* Read next ranges element */
+		pci_space = ranges[0];
+		pci_addr = of_read_number(ranges + 1, 2);
+		cpu_addr = of_translate_address(dev, ranges + 3);
+		size = of_read_number(ranges + pna + 3, 2);
+
+		pr_debug("pci_space: 0x%08x pci_addr:0x%016llx "
+				"cpu_addr:0x%016llx size:0x%016llx\n",
+					pci_space, pci_addr, cpu_addr, size);
+
+		ranges += np;
+
+		/* If we failed translation or got a zero-sized region
+		 * (some FW try to feed us with non sensical zero sized regions
+		 * such as power3 which look like some kind of attempt
+		 * at exposing the VGA memory hole)
+		 */
+		if (cpu_addr == OF_BAD_ADDR || size == 0)
+			continue;
+
+		/* Now consume following elements while they are contiguous */
+		for (; rlen >= np * sizeof(u32);
+		     ranges += np, rlen -= np * 4) {
+			if (ranges[0] != pci_space)
+				break;
+			pci_next = of_read_number(ranges + 1, 2);
+			cpu_next = of_translate_address(dev, ranges + 3);
+			if (pci_next != pci_addr + size ||
+			    cpu_next != cpu_addr + size)
+				break;
+			size += of_read_number(ranges + pna + 3, 2);
+		}
+
+		/* Act based on address space type */
+		res = NULL;
+		switch ((pci_space >> 24) & 0x3) {
+		case 1:		/* PCI IO space */
+			printk(KERN_INFO
+			       "  IO 0x%016llx..0x%016llx -> 0x%016llx\n",
+			       cpu_addr, cpu_addr + size - 1, pci_addr);
+
+			/* We support only one IO range */
+			if (hose->pci_io_size) {
+				printk(KERN_INFO
+				       " \\--> Skipped (too many) !\n");
+				continue;
+			}
+			/* On 32 bits, limit I/O space to 16MB */
+			if (size > 0x01000000)
+				size = 0x01000000;
+
+			/* 32 bits needs to map IOs here */
+			hose->io_base_virt = ioremap(cpu_addr, size);
+
+			/* Expect trouble if pci_addr is not 0 */
+			if (primary)
+				isa_io_base =
+					(unsigned long)hose->io_base_virt;
+			/* pci_io_size and io_base_phys always represent IO
+			 * space starting at 0 so we factor in pci_addr
+			 */
+			hose->pci_io_size = pci_addr + size;
+			hose->io_base_phys = cpu_addr - pci_addr;
+
+			/* Build resource */
+			res = &hose->io_resource;
+			res->flags = IORESOURCE_IO;
+			res->start = pci_addr;
+			break;
+		case 2:		/* PCI Memory space */
+		case 3:		/* PCI 64 bits Memory space */
+			printk(KERN_INFO
+			       " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
+			       cpu_addr, cpu_addr + size - 1, pci_addr,
+			       (pci_space & 0x40000000) ? "Prefetch" : "");
+
+			/* We support only 3 memory ranges */
+			if (memno >= 3) {
+				printk(KERN_INFO
+				       " \\--> Skipped (too many) !\n");
+				continue;
+			}
+			/* Handles ISA memory hole space here */
+			if (pci_addr == 0) {
+				isa_mb = cpu_addr;
+				isa_hole = memno;
+				if (primary || isa_mem_base == 0)
+					isa_mem_base = cpu_addr;
+				hose->isa_mem_phys = cpu_addr;
+				hose->isa_mem_size = size;
+			}
+
+			/* We get the PCI/Mem offset from the first range or
+			 * the, current one if the offset came from an ISA
+			 * hole. If they don't match, bugger.
+			 */
+			if (memno == 0 ||
+			    (isa_hole >= 0 && pci_addr != 0 &&
+			     hose->pci_mem_offset == isa_mb))
+				hose->pci_mem_offset = cpu_addr - pci_addr;
+			else if (pci_addr != 0 &&
+				 hose->pci_mem_offset != cpu_addr - pci_addr) {
+				printk(KERN_INFO
+				       " \\--> Skipped (offset mismatch) !\n");
+				continue;
+			}
+
+			/* Build resource */
+			res = &hose->mem_resources[memno++];
+			res->flags = IORESOURCE_MEM;
+			if (pci_space & 0x40000000)
+				res->flags |= IORESOURCE_PREFETCH;
+			res->start = cpu_addr;
+			break;
+		}
+		if (res != NULL) {
+			res->name = dev->full_name;
+			res->end = res->start + size - 1;
+			res->parent = NULL;
+			res->sibling = NULL;
+			res->child = NULL;
+		}
+	}
+
+	/* If there's an ISA hole and the pci_mem_offset is -not- matching
+	 * the ISA hole offset, then we need to remove the ISA hole from
+	 * the resource list for that brige
+	 */
+	if (isa_hole >= 0 && hose->pci_mem_offset != isa_mb) {
+		unsigned int next = isa_hole + 1;
+		printk(KERN_INFO " Removing ISA hole at 0x%016llx\n", isa_mb);
+		if (next < memno)
+			memmove(&hose->mem_resources[isa_hole],
+				&hose->mem_resources[next],
+				sizeof(struct resource) * (memno - next));
+		hose->mem_resources[--memno].flags = 0;
+	}
+}
+
+/* Decide whether to display the domain number in /proc */
+int pci_proc_domain(struct pci_bus *bus)
+{
+	struct pci_controller *hose = pci_bus_to_host(bus);
+
+	if (!(pci_flags & PCI_ENABLE_PROC_DOMAINS))
+		return 0;
+	if (pci_flags & PCI_COMPAT_DOMAIN_0)
+		return hose->global_number != 0;
+	return 1;
+}
+
+void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+			     struct resource *res)
+{
+	resource_size_t offset = 0, mask = (resource_size_t)-1;
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+
+	if (!hose)
+		return;
+	if (res->flags & IORESOURCE_IO) {
+		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+		mask = 0xffffffffu;
+	} else if (res->flags & IORESOURCE_MEM)
+		offset = hose->pci_mem_offset;
+
+	region->start = (res->start - offset) & mask;
+	region->end = (res->end - offset) & mask;
+}
+EXPORT_SYMBOL(pcibios_resource_to_bus);
+
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			     struct pci_bus_region *region)
+{
+	resource_size_t offset = 0, mask = (resource_size_t)-1;
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+
+	if (!hose)
+		return;
+	if (res->flags & IORESOURCE_IO) {
+		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+		mask = 0xffffffffu;
+	} else if (res->flags & IORESOURCE_MEM)
+		offset = hose->pci_mem_offset;
+	res->start = (region->start + offset) & mask;
+	res->end = (region->end + offset) & mask;
+}
+EXPORT_SYMBOL(pcibios_bus_to_resource);
+
+/* Fixup a bus resource into a linux resource */
+static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
+{
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	resource_size_t offset = 0, mask = (resource_size_t)-1;
+
+	if (res->flags & IORESOURCE_IO) {
+		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+		mask = 0xffffffffu;
+	} else if (res->flags & IORESOURCE_MEM)
+		offset = hose->pci_mem_offset;
+
+	res->start = (res->start + offset) & mask;
+	res->end = (res->end + offset) & mask;
+}
+
+/* This header fixup will do the resource fixup for all devices as they are
+ * probed, but not for bridge ranges
+ */
+static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
+{
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	int i;
+
+	if (!hose) {
+		printk(KERN_ERR "No host bridge for PCI dev %s !\n",
+		       pci_name(dev));
+		return;
+	}
+	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+		struct resource *res = dev->resource + i;
+		if (!res->flags)
+			continue;
+		/* On platforms that have PCI_PROBE_ONLY set, we don't
+		 * consider 0 as an unassigned BAR value. It's technically
+		 * a valid value, but linux doesn't like it... so when we can
+		 * re-assign things, we do so, but if we can't, we keep it
+		 * around and hope for the best...
+		 */
+		if (res->start == 0 && !(pci_flags & PCI_PROBE_ONLY)) {
+			pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]" \
+							"is unassigned\n",
+				 pci_name(dev), i,
+				 (unsigned long long)res->start,
+				 (unsigned long long)res->end,
+				 (unsigned int)res->flags);
+			res->end -= res->start;
+			res->start = 0;
+			res->flags |= IORESOURCE_UNSET;
+			continue;
+		}
+
+		pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n",
+			 pci_name(dev), i,
+			 (unsigned long long)res->start,\
+			 (unsigned long long)res->end,
+			 (unsigned int)res->flags);
+
+		fixup_resource(res, dev);
+
+		pr_debug("PCI:%s            %016llx-%016llx\n",
+			 pci_name(dev),
+			 (unsigned long long)res->start,
+			 (unsigned long long)res->end);
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);
+
+/* This function tries to figure out if a bridge resource has been initialized
+ * by the firmware or not. It doesn't have to be absolutely bullet proof, but
+ * things go more smoothly when it gets it right. It should covers cases such
+ * as Apple "closed" bridge resources and bare-metal pSeries unassigned bridges
+ */
+static int __devinit pcibios_uninitialized_bridge_resource(struct pci_bus *bus,
+							   struct resource *res)
+{
+	struct pci_controller *hose = pci_bus_to_host(bus);
+	struct pci_dev *dev = bus->self;
+	resource_size_t offset;
+	u16 command;
+	int i;
+
+	/* We don't do anything if PCI_PROBE_ONLY is set */
+	if (pci_flags & PCI_PROBE_ONLY)
+		return 0;
+
+	/* Job is a bit different between memory and IO */
+	if (res->flags & IORESOURCE_MEM) {
+		/* If the BAR is non-0 (res != pci_mem_offset) then it's
+		 * probably been initialized by somebody
+		 */
+		if (res->start != hose->pci_mem_offset)
+			return 0;
+
+		/* The BAR is 0, let's check if memory decoding is enabled on
+		 * the bridge. If not, we consider it unassigned
+		 */
+		pci_read_config_word(dev, PCI_COMMAND, &command);
+		if ((command & PCI_COMMAND_MEMORY) == 0)
+			return 1;
+
+		/* Memory decoding is enabled and the BAR is 0. If any of
+		 * the bridge resources covers that starting address (0 then
+		 * it's good enough for us for memory
+		 */
+		for (i = 0; i < 3; i++) {
+			if ((hose->mem_resources[i].flags & IORESOURCE_MEM) &&
+			   hose->mem_resources[i].start == hose->pci_mem_offset)
+				return 0;
+		}
+
+		/* Well, it starts at 0 and we know it will collide so we may as
+		 * well consider it as unassigned. That covers the Apple case.
+		 */
+		return 1;
+	} else {
+		/* If the BAR is non-0, then we consider it assigned */
+		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+		if (((res->start - offset) & 0xfffffffful) != 0)
+			return 0;
+
+		/* Here, we are a bit different than memory as typically IO
+		 * space starting at low addresses -is- valid. What we do
+		 * instead if that we consider as unassigned anything that
+		 * doesn't have IO enabled in the PCI command register,
+		 * and that's it.
+		 */
+		pci_read_config_word(dev, PCI_COMMAND, &command);
+		if (command & PCI_COMMAND_IO)
+			return 0;
+
+		/* It's starting at 0 and IO is disabled in the bridge, consider
+		 * it unassigned
+		 */
+		return 1;
+	}
+}
+
+/* Fixup resources of a PCI<->PCI bridge */
+static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
+{
+	struct resource *res;
+	int i;
+
+	struct pci_dev *dev = bus->self;
+
+	pci_bus_for_each_resource(bus, res, i) {
+		res = bus->resource[i];
+		if (!res)
+			continue;
+		if (!res->flags)
+			continue;
+		if (i >= 3 && bus->self->transparent)
+			continue;
+
+		pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n",
+			 pci_name(dev), i,
+			 (unsigned long long)res->start,\
+			 (unsigned long long)res->end,
+			 (unsigned int)res->flags);
+
+		/* Perform fixup */
+		fixup_resource(res, dev);
+
+		/* Try to detect uninitialized P2P bridge resources,
+		 * and clear them out so they get re-assigned later
+		 */
+		if (pcibios_uninitialized_bridge_resource(bus, res)) {
+			res->flags = 0;
+			pr_debug("PCI:%s            (unassigned)\n",
+								pci_name(dev));
+		} else {
+			pr_debug("PCI:%s            %016llx-%016llx\n",
+				 pci_name(dev),
+				 (unsigned long long)res->start,
+				 (unsigned long long)res->end);
+		}
+	}
+}
+
+void __devinit pcibios_setup_bus_self(struct pci_bus *bus)
+{
+	/* Fix up the bus resources for P2P bridges */
+	if (bus->self != NULL)
+		pcibios_fixup_bridge(bus);
+}
+
+void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+
+	pr_debug("PCI: Fixup bus devices %d (%s)\n",
+		 bus->number, bus->self ? pci_name(bus->self) : "PHB");
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		struct dev_archdata *sd = &dev->dev.archdata;
+
+		/* Setup OF node pointer in archdata */
+		sd->of_node = pci_device_to_OF_node(dev);
+
+		/* Fixup NUMA node as it may not be setup yet by the generic
+		 * code and is needed by the DMA init
+		 */
+		set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
+
+		/* Hook up default DMA ops */
+		sd->dma_ops = pci_dma_ops;
+		sd->dma_data = (void *)PCI_DRAM_OFFSET;
+
+		/* Read default IRQs and fixup if necessary */
+		pci_read_irq_line(dev);
+	}
+}
+
+void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+{
+	/* When called from the generic PCI probe, read PCI<->PCI bridge
+	 * bases. This is -not- called when generating the PCI tree from
+	 * the OF device-tree.
+	 */
+	if (bus->self != NULL)
+		pci_read_bridge_bases(bus);
+
+	/* Now fixup the bus bus */
+	pcibios_setup_bus_self(bus);
+
+	/* Now fixup devices on that bus */
+	pcibios_setup_bus_devices(bus);
+}
+EXPORT_SYMBOL(pcibios_fixup_bus);
+
+static int skip_isa_ioresource_align(struct pci_dev *dev)
+{
+	if ((pci_flags & PCI_CAN_SKIP_ISA_ALIGN) &&
+	    !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA))
+		return 1;
+	return 0;
+}
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ *
+ * Why? Because some silly external IO cards only decode
+ * the low 10 bits of the IO address. The 0x00-0xff region
+ * is reserved for motherboard devices that decode all 16
+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+ * but we want to try to avoid allocating at 0x2900-0x2bff
+ * which might have be mirrored at 0x0100-0x03ff..
+ */
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+				resource_size_t size, resource_size_t align)
+{
+	struct pci_dev *dev = data;
+	resource_size_t start = res->start;
+
+	if (res->flags & IORESOURCE_IO) {
+		if (skip_isa_ioresource_align(dev))
+			return start;
+		if (start & 0x300)
+			start = (start + 0x3ff) & ~0x3ff;
+	}
+
+	return start;
+}
+EXPORT_SYMBOL(pcibios_align_resource);
+
+/*
+ * Reparent resource children of pr that conflict with res
+ * under res, and make res replace those children.
+ */
+static int __init reparent_resources(struct resource *parent,
+				     struct resource *res)
+{
+	struct resource *p, **pp;
+	struct resource **firstpp = NULL;
+
+	for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
+		if (p->end < res->start)
+			continue;
+		if (res->end < p->start)
+			break;
+		if (p->start < res->start || p->end > res->end)
+			return -1;	/* not completely contained */
+		if (firstpp == NULL)
+			firstpp = pp;
+	}
+	if (firstpp == NULL)
+		return -1;	/* didn't find any conflicting entries? */
+	res->parent = parent;
+	res->child = *firstpp;
+	res->sibling = *pp;
+	*firstpp = res;
+	*pp = NULL;
+	for (p = res->child; p != NULL; p = p->sibling) {
+		p->parent = res;
+		pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n",
+			 p->name,
+			 (unsigned long long)p->start,
+			 (unsigned long long)p->end, res->name);
+	}
+	return 0;
+}
+
+/*
+ *  Handle resources of PCI devices.  If the world were perfect, we could
+ *  just allocate all the resource regions and do nothing more.  It isn't.
+ *  On the other hand, we cannot just re-allocate all devices, as it would
+ *  require us to know lots of host bridge internals.  So we attempt to
+ *  keep as much of the original configuration as possible, but tweak it
+ *  when it's found to be wrong.
+ *
+ *  Known BIOS problems we have to work around:
+ *	- I/O or memory regions not configured
+ *	- regions configured, but not enabled in the command register
+ *	- bogus I/O addresses above 64K used
+ *	- expansion ROMs left enabled (this may sound harmless, but given
+ *	  the fact the PCI specs explicitly allow address decoders to be
+ *	  shared between expansion ROMs and other resource regions, it's
+ *	  at least dangerous)
+ *
+ *  Our solution:
+ *	(1) Allocate resources for all buses behind PCI-to-PCI bridges.
+ *	    This gives us fixed barriers on where we can allocate.
+ *	(2) Allocate resources for all enabled devices.  If there is
+ *	    a collision, just mark the resource as unallocated. Also
+ *	    disable expansion ROMs during this step.
+ *	(3) Try to allocate resources for disabled devices.  If the
+ *	    resources were assigned correctly, everything goes well,
+ *	    if they weren't, they won't disturb allocation of other
+ *	    resources.
+ *	(4) Assign new addresses to resources which were either
+ *	    not configured at all or misconfigured.  If explicitly
+ *	    requested by the user, configure expansion ROM address
+ *	    as well.
+ */
+
+void pcibios_allocate_bus_resources(struct pci_bus *bus)
+{
+	struct pci_bus *b;
+	int i;
+	struct resource *res, *pr;
+
+	pr_debug("PCI: Allocating bus resources for %04x:%02x...\n",
+		 pci_domain_nr(bus), bus->number);
+
+	pci_bus_for_each_resource(bus, res, i) {
+		res = bus->resource[i];
+		if (!res || !res->flags
+		    || res->start > res->end || res->parent)
+			continue;
+		if (bus->parent == NULL)
+			pr = (res->flags & IORESOURCE_IO) ?
+				&ioport_resource : &iomem_resource;
+		else {
+			/* Don't bother with non-root busses when
+			 * re-assigning all resources. We clear the
+			 * resource flags as if they were colliding
+			 * and as such ensure proper re-allocation
+			 * later.
+			 */
+			if (pci_flags & PCI_REASSIGN_ALL_RSRC)
+				goto clear_resource;
+			pr = pci_find_parent_resource(bus->self, res);
+			if (pr == res) {
+				/* this happens when the generic PCI
+				 * code (wrongly) decides that this
+				 * bridge is transparent  -- paulus
+				 */
+				continue;
+			}
+		}
+
+		pr_debug("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "
+			 "[0x%x], parent %p (%s)\n",
+			 bus->self ? pci_name(bus->self) : "PHB",
+			 bus->number, i,
+			 (unsigned long long)res->start,
+			 (unsigned long long)res->end,
+			 (unsigned int)res->flags,
+			 pr, (pr && pr->name) ? pr->name : "nil");
+
+		if (pr && !(pr->flags & IORESOURCE_UNSET)) {
+			if (request_resource(pr, res) == 0)
+				continue;
+			/*
+			 * Must be a conflict with an existing entry.
+			 * Move that entry (or entries) under the
+			 * bridge resource and try again.
+			 */
+			if (reparent_resources(pr, res) == 0)
+				continue;
+		}
+		printk(KERN_WARNING "PCI: Cannot allocate resource region "
+		       "%d of PCI bridge %d, will remap\n", i, bus->number);
+clear_resource:
+		res->flags = 0;
+	}
+
+	list_for_each_entry(b, &bus->children, node)
+		pcibios_allocate_bus_resources(b);
+}
+
+static inline void __devinit alloc_resource(struct pci_dev *dev, int idx)
+{
+	struct resource *pr, *r = &dev->resource[idx];
+
+	pr_debug("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n",
+		 pci_name(dev), idx,
+		 (unsigned long long)r->start,
+		 (unsigned long long)r->end,
+		 (unsigned int)r->flags);
+
+	pr = pci_find_parent_resource(dev, r);
+	if (!pr || (pr->flags & IORESOURCE_UNSET) ||
+	    request_resource(pr, r) < 0) {
+		printk(KERN_WARNING "PCI: Cannot allocate resource region %d"
+		       " of device %s, will remap\n", idx, pci_name(dev));
+		if (pr)
+			pr_debug("PCI:  parent is %p: %016llx-%016llx [%x]\n",
+				 pr,
+				 (unsigned long long)pr->start,
+				 (unsigned long long)pr->end,
+				 (unsigned int)pr->flags);
+		/* We'll assign a new address later */
+		r->flags |= IORESOURCE_UNSET;
+		r->end -= r->start;
+		r->start = 0;
+	}
+}
+
+static void __init pcibios_allocate_resources(int pass)
+{
+	struct pci_dev *dev = NULL;
+	int idx, disabled;
+	u16 command;
+	struct resource *r;
+
+	for_each_pci_dev(dev) {
+		pci_read_config_word(dev, PCI_COMMAND, &command);
+		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
+				disabled = !(command & PCI_COMMAND_MEMORY);
+			if (pass == disabled)
+				alloc_resource(dev, idx);
+		}
+		if (pass)
+			continue;
+		r = &dev->resource[PCI_ROM_RESOURCE];
+		if (r->flags) {
+			/* Turn the ROM off, leave the resource region,
+			 * but keep it unregistered.
+			 */
+			u32 reg;
+			pci_read_config_dword(dev, dev->rom_base_reg, &reg);
+			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);
+			}
+		}
+	}
+}
+
+static void __init pcibios_reserve_legacy_regions(struct pci_bus *bus)
+{
+	struct pci_controller *hose = pci_bus_to_host(bus);
+	resource_size_t	offset;
+	struct resource *res, *pres;
+	int i;
+
+	pr_debug("Reserving legacy ranges for domain %04x\n",
+							pci_domain_nr(bus));
+
+	/* Check for IO */
+	if (!(hose->io_resource.flags & IORESOURCE_IO))
+		goto no_io;
+	offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+	res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+	BUG_ON(res == NULL);
+	res->name = "Legacy IO";
+	res->flags = IORESOURCE_IO;
+	res->start = offset;
+	res->end = (offset + 0xfff) & 0xfffffffful;
+	pr_debug("Candidate legacy IO: %pR\n", res);
+	if (request_resource(&hose->io_resource, res)) {
+		printk(KERN_DEBUG
+		       "PCI %04x:%02x Cannot reserve Legacy IO %pR\n",
+		       pci_domain_nr(bus), bus->number, res);
+		kfree(res);
+	}
+
+ no_io:
+	/* Check for memory */
+	offset = hose->pci_mem_offset;
+	pr_debug("hose mem offset: %016llx\n", (unsigned long long)offset);
+	for (i = 0; i < 3; i++) {
+		pres = &hose->mem_resources[i];
+		if (!(pres->flags & IORESOURCE_MEM))
+			continue;
+		pr_debug("hose mem res: %pR\n", pres);
+		if ((pres->start - offset) <= 0xa0000 &&
+		    (pres->end - offset) >= 0xbffff)
+			break;
+	}
+	if (i >= 3)
+		return;
+	res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+	BUG_ON(res == NULL);
+	res->name = "Legacy VGA memory";
+	res->flags = IORESOURCE_MEM;
+	res->start = 0xa0000 + offset;
+	res->end = 0xbffff + offset;
+	pr_debug("Candidate VGA memory: %pR\n", res);
+	if (request_resource(pres, res)) {
+		printk(KERN_DEBUG
+		       "PCI %04x:%02x Cannot reserve VGA memory %pR\n",
+		       pci_domain_nr(bus), bus->number, res);
+		kfree(res);
+	}
+}
+
+void __init pcibios_resource_survey(void)
+{
+	struct pci_bus *b;
+
+	/* Allocate and assign resources. If we re-assign everything, then
+	 * we skip the allocate phase
+	 */
+	list_for_each_entry(b, &pci_root_buses, node)
+		pcibios_allocate_bus_resources(b);
+
+	if (!(pci_flags & PCI_REASSIGN_ALL_RSRC)) {
+		pcibios_allocate_resources(0);
+		pcibios_allocate_resources(1);
+	}
+
+	/* Before we start assigning unassigned resource, we try to reserve
+	 * the low IO area and the VGA memory area if they intersect the
+	 * bus available resources to avoid allocating things on top of them
+	 */
+	if (!(pci_flags & PCI_PROBE_ONLY)) {
+		list_for_each_entry(b, &pci_root_buses, node)
+			pcibios_reserve_legacy_regions(b);
+	}
+
+	/* Now, if the platform didn't decide to blindly trust the firmware,
+	 * we proceed to assigning things that were left unassigned
+	 */
+	if (!(pci_flags & PCI_PROBE_ONLY)) {
+		pr_debug("PCI: Assigning unassigned resources...\n");
+		pci_assign_unassigned_resources();
+	}
+}
+
+#ifdef CONFIG_HOTPLUG
+
+/* This is used by the PCI hotplug driver to allocate resource
+ * of newly plugged busses. We can try to consolidate with the
+ * rest of the code later, for now, keep it as-is as our main
+ * resource allocation function doesn't deal with sub-trees yet.
+ */
+void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+	struct pci_bus *child_bus;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		int i;
+
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			struct resource *r = &dev->resource[i];
+
+			if (r->parent || !r->start || !r->flags)
+				continue;
+
+			pr_debug("PCI: Claiming %s: "
+				 "Resource %d: %016llx..%016llx [%x]\n",
+				 pci_name(dev), i,
+				 (unsigned long long)r->start,
+				 (unsigned long long)r->end,
+				 (unsigned int)r->flags);
+
+			pci_claim_resource(dev, i);
+		}
+	}
+
+	list_for_each_entry(child_bus, &bus->children, node)
+		pcibios_claim_one_bus(child_bus);
+}
+EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
+
+
+/* pcibios_finish_adding_to_bus
+ *
+ * This is to be called by the hotplug code after devices have been
+ * added to a bus, this include calling it for a PHB that is just
+ * being added
+ */
+void pcibios_finish_adding_to_bus(struct pci_bus *bus)
+{
+	pr_debug("PCI: Finishing adding to hotplug bus %04x:%02x\n",
+		 pci_domain_nr(bus), bus->number);
+
+	/* Allocate bus and devices resources */
+	pcibios_allocate_bus_resources(bus);
+	pcibios_claim_one_bus(bus);
+
+	/* Add new devices to global lists.  Register in proc, sysfs. */
+	pci_bus_add_devices(bus);
+
+	/* Fixup EEH */
+	/* eeh_add_device_tree_late(bus); */
+}
+EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus);
+
+#endif /* CONFIG_HOTPLUG */
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	return pci_enable_resources(dev, mask);
+}
+
+void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
+{
+	struct pci_bus *bus = hose->bus;
+	struct resource *res;
+	int i;
+
+	/* Hookup PHB IO resource */
+	bus->resource[0] = res = &hose->io_resource;
+
+	if (!res->flags) {
+		printk(KERN_WARNING "PCI: I/O resource not set for host"
+		       " bridge %s (domain %d)\n",
+		       hose->dn->full_name, hose->global_number);
+		/* Workaround for lack of IO resource only on 32-bit */
+		res->start = (unsigned long)hose->io_base_virt - isa_io_base;
+		res->end = res->start + IO_SPACE_LIMIT;
+		res->flags = IORESOURCE_IO;
+	}
+
+	pr_debug("PCI: PHB IO resource    = %016llx-%016llx [%lx]\n",
+		 (unsigned long long)res->start,
+		 (unsigned long long)res->end,
+		 (unsigned long)res->flags);
+
+	/* Hookup PHB Memory resources */
+	for (i = 0; i < 3; ++i) {
+		res = &hose->mem_resources[i];
+		if (!res->flags) {
+			if (i > 0)
+				continue;
+			printk(KERN_ERR "PCI: Memory resource 0 not set for "
+			       "host bridge %s (domain %d)\n",
+			       hose->dn->full_name, hose->global_number);
+
+			/* Workaround for lack of MEM resource only on 32-bit */
+			res->start = hose->pci_mem_offset;
+			res->end = (resource_size_t)-1LL;
+			res->flags = IORESOURCE_MEM;
+
+		}
+		bus->resource[i+1] = res;
+
+		pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n",
+			i, (unsigned long long)res->start,
+			(unsigned long long)res->end,
+			(unsigned long)res->flags);
+	}
+
+	pr_debug("PCI: PHB MEM offset     = %016llx\n",
+		 (unsigned long long)hose->pci_mem_offset);
+	pr_debug("PCI: PHB IO  offset     = %08lx\n",
+		 (unsigned long)hose->io_base_virt - _IO_BASE);
+}
+
+/*
+ * Null PCI config access functions, for the case when we can't
+ * find a hose.
+ */
+#define NULL_PCI_OP(rw, size, type)					\
+static int								\
+null_##rw##_config_##size(struct pci_dev *dev, int offset, type val)	\
+{									\
+	return PCIBIOS_DEVICE_NOT_FOUND;				\
+}
+
+static int
+null_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+		 int len, u32 *val)
+{
+	return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static int
+null_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+		  int len, u32 val)
+{
+	return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static struct pci_ops null_pci_ops = {
+	.read = null_read_config,
+	.write = null_write_config,
+};
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+static struct pci_bus *
+fake_pci_bus(struct pci_controller *hose, int busnr)
+{
+	static struct pci_bus bus;
+
+	if (!hose)
+		printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);
+
+	bus.number = busnr;
+	bus.sysdata = hose;
+	bus.ops = hose ? hose->ops : &null_pci_ops;
+	return &bus;
+}
+
+#define EARLY_PCI_OP(rw, size, type)					\
+int early_##rw##_config_##size(struct pci_controller *hose, int bus,	\
+			       int devfn, int offset, type value)	\
+{									\
+	return pci_bus_##rw##_config_##size(fake_pci_bus(hose, bus),	\
+					    devfn, offset, value);	\
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
+
+int early_find_capability(struct pci_controller *hose, int bus, int devfn,
+			  int cap)
+{
+	return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/microblaze/pci/xilinx_pci.c linux-libre-2.6.34-gnu1/arch/microblaze/pci/xilinx_pci.c
--- linux-libre-2.6.33-gnu1/arch/microblaze/pci/xilinx_pci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/microblaze/pci/xilinx_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,168 @@
+/*
+ * PCI support for Xilinx plbv46_pci soft-core which can be used on
+ * Xilinx Virtex ML410 / ML510 boards.
+ *
+ * Copyright 2009 Roderick Colenbrander
+ * Copyright 2009 Secret Lab Technologies Ltd.
+ *
+ * The pci bridge fixup code was copied from ppc4xx_pci.c and was written
+ * by Benjamin Herrenschmidt.
+ * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/ioport.h>
+#include <linux/of.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+#define XPLB_PCI_ADDR 0x10c
+#define XPLB_PCI_DATA 0x110
+#define XPLB_PCI_BUS  0x114
+
+#define PCI_HOST_ENABLE_CMD (PCI_COMMAND_SERR | PCI_COMMAND_PARITY | \
+				PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY)
+
+static struct of_device_id xilinx_pci_match[] = {
+	{ .compatible = "xlnx,plbv46-pci-1.03.a", },
+	{}
+};
+
+/**
+ * xilinx_pci_fixup_bridge - Block Xilinx PHB configuration.
+ */
+static void xilinx_pci_fixup_bridge(struct pci_dev *dev)
+{
+	struct pci_controller *hose;
+	int i;
+
+	if (dev->devfn || dev->bus->self)
+		return;
+
+	hose = pci_bus_to_host(dev->bus);
+	if (!hose)
+		return;
+
+	if (!of_match_node(xilinx_pci_match, hose->dn))
+		return;
+
+	/* Hide the PCI host BARs from the kernel as their content doesn't
+	 * fit well in the resource management
+	 */
+	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+		dev->resource[i].start = 0;
+		dev->resource[i].end = 0;
+		dev->resource[i].flags = 0;
+	}
+
+	dev_info(&dev->dev, "Hiding Xilinx plb-pci host bridge resources %s\n",
+		 pci_name(dev));
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, xilinx_pci_fixup_bridge);
+
+#ifdef DEBUG
+/**
+ * xilinx_pci_exclude_device - Don't do config access for non-root bus
+ *
+ * This is a hack.  Config access to any bus other than bus 0 does not
+ * currently work on the ML510 so we prevent it here.
+ */
+static int
+xilinx_pci_exclude_device(struct pci_controller *hose, u_char bus, u8 devfn)
+{
+	return (bus != 0);
+}
+
+/**
+ * xilinx_early_pci_scan - List pci config space for available devices
+ *
+ * List pci devices in very early phase.
+ */
+void __init xilinx_early_pci_scan(struct pci_controller *hose)
+{
+	u32 bus = 0;
+	u32 val, dev, func, offset;
+
+	/* Currently we have only 2 device connected - up-to 32 devices */
+	for (dev = 0; dev < 2; dev++) {
+		/* List only first function number - up-to 8 functions */
+		for (func = 0; func < 1; func++) {
+			printk(KERN_INFO "%02x:%02x:%02x", bus, dev, func);
+			/* read the first 64 standardized bytes */
+			/* Up-to 192 bytes can be list of capabilities */
+			for (offset = 0; offset < 64; offset += 4) {
+				early_read_config_dword(hose, bus,
+					PCI_DEVFN(dev, func), offset, &val);
+				if (offset == 0 && val == 0xFFFFFFFF) {
+					printk(KERN_CONT "\nABSENT");
+					break;
+				}
+				if (!(offset % 0x10))
+					printk(KERN_CONT "\n%04x:    ", offset);
+
+				printk(KERN_CONT "%08x  ", val);
+			}
+			printk(KERN_INFO "\n");
+		}
+	}
+}
+#else
+void __init xilinx_early_pci_scan(struct pci_controller *hose)
+{
+}
+#endif
+
+/**
+ * xilinx_pci_init - Find and register a Xilinx PCI host bridge
+ */
+void __init xilinx_pci_init(void)
+{
+	struct pci_controller *hose;
+	struct resource r;
+	void __iomem *pci_reg;
+	struct device_node *pci_node;
+
+	pci_node = of_find_matching_node(NULL, xilinx_pci_match);
+	if (!pci_node)
+		return;
+
+	if (of_address_to_resource(pci_node, 0, &r)) {
+		pr_err("xilinx-pci: cannot resolve base address\n");
+		return;
+	}
+
+	hose = pcibios_alloc_controller(pci_node);
+	if (!hose) {
+		pr_err("xilinx-pci: pcibios_alloc_controller() failed\n");
+		return;
+	}
+
+	/* Setup config space */
+	setup_indirect_pci(hose, r.start + XPLB_PCI_ADDR,
+			   r.start + XPLB_PCI_DATA,
+			   INDIRECT_TYPE_SET_CFG_TYPE);
+
+	/* According to the xilinx plbv46_pci documentation the soft-core starts
+	 * a self-init when the bus master enable bit is set. Without this bit
+	 * set the pci bus can't be scanned.
+	 */
+	early_write_config_word(hose, 0, 0, PCI_COMMAND, PCI_HOST_ENABLE_CMD);
+
+	/* Set the max latency timer to 255 */
+	early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0xff);
+
+	/* Set the max bus number to 255, and bus/subbus no's to 0 */
+	pci_reg = of_iomap(pci_node, 0);
+	out_be32(pci_reg + XPLB_PCI_BUS, 0x000000ff);
+	iounmap(pci_reg);
+
+	/* Register the host bridge with the linux kernel! */
+	pci_process_bridge_OF_ranges(hose, pci_node,
+					INDIRECT_TYPE_SET_CFG_TYPE);
+
+	pr_info("xilinx-pci: Registered PCI host bridge\n");
+	xilinx_early_pci_scan(hose);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/clocks.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/clocks.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/clocks.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/clocks.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,8 +40,6 @@
 static unsigned int au1x00_clock; /*  Hz */
 static unsigned long uart_baud_base;
 
-static DEFINE_SPINLOCK(time_lock);
-
 /*
  * Set the au1000_clock
  */
@@ -84,9 +82,6 @@ void set_au1x00_uart_baud_base(unsigned
 unsigned long au1xxx_calc_clock(void)
 {
 	unsigned long cpu_speed;
-	unsigned long flags;
-
-	spin_lock_irqsave(&time_lock, flags);
 
 	/*
 	 * On early Au1000, sys_cpupll was write-only. Since these
@@ -108,8 +103,6 @@ unsigned long au1xxx_calc_clock(void)
 	set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)
 							  & 0x03) + 2) * 16));
 
-	spin_unlock_irqrestore(&time_lock, flags);
-
 	set_au1x00_speed(cpu_speed);
 
 	return cpu_speed;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/dbdma.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/dbdma.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/dbdma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/dbdma.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
  *
  */
 
+#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
@@ -58,7 +59,6 @@ static DEFINE_SPINLOCK(au1xxx_dbdma_spin
 
 static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
 static int dbdma_initialized;
-static void au1xxx_dbdma_init(void);
 
 static dbdev_tab_t dbdev_tab[] = {
 #ifdef CONFIG_SOC_AU1550
@@ -237,7 +237,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u
        void (*callback)(int, void *), void *callparam)
 {
 	unsigned long   flags;
-	u32		used, chan, rv;
+	u32		used, chan;
 	u32		dcp;
 	int		i;
 	dbdev_tab_t	*stp, *dtp;
@@ -250,8 +250,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u
 	 * which can't be done successfully during board set up.
 	 */
 	if (!dbdma_initialized)
-		au1xxx_dbdma_init();
-	dbdma_initialized = 1;
+		return 0;
 
 	stp = find_dbdev_id(srcid);
 	if (stp == NULL)
@@ -261,7 +260,6 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u
 		return 0;
 
 	used = 0;
-	rv = 0;
 
 	/* Check to see if we can get both channels. */
 	spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
@@ -282,63 +280,65 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u
 		used++;
 	spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
 
-	if (!used) {
-		/* Let's see if we can allocate a channel for it. */
-		ctp = NULL;
-		chan = 0;
-		spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
-		for (i = 0; i < NUM_DBDMA_CHANS; i++)
-			if (chan_tab_ptr[i] == NULL) {
-				/*
-				 * If kmalloc fails, it is caught below same
-				 * as a channel not available.
-				 */
-				ctp = kmalloc(sizeof(chan_tab_t), GFP_ATOMIC);
-				chan_tab_ptr[i] = ctp;
-				break;
-			}
-		spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
-
-		if (ctp != NULL) {
-			memset(ctp, 0, sizeof(chan_tab_t));
-			ctp->chan_index = chan = i;
-			dcp = DDMA_CHANNEL_BASE;
-			dcp += (0x0100 * chan);
-			ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
-			cp = (au1x_dma_chan_t *)dcp;
-			ctp->chan_src = stp;
-			ctp->chan_dest = dtp;
-			ctp->chan_callback = callback;
-			ctp->chan_callparam = callparam;
-
-			/* Initialize channel configuration. */
-			i = 0;
-			if (stp->dev_intlevel)
-				i |= DDMA_CFG_SED;
-			if (stp->dev_intpolarity)
-				i |= DDMA_CFG_SP;
-			if (dtp->dev_intlevel)
-				i |= DDMA_CFG_DED;
-			if (dtp->dev_intpolarity)
-				i |= DDMA_CFG_DP;
-			if ((stp->dev_flags & DEV_FLAGS_SYNC) ||
-				(dtp->dev_flags & DEV_FLAGS_SYNC))
-					i |= DDMA_CFG_SYNC;
-			cp->ddma_cfg = i;
-			au_sync();
+	if (used)
+		return 0;
 
-			/* Return a non-zero value that can be used to
-			 * find the channel information in subsequent
-			 * operations.
+	/* Let's see if we can allocate a channel for it. */
+	ctp = NULL;
+	chan = 0;
+	spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
+	for (i = 0; i < NUM_DBDMA_CHANS; i++)
+		if (chan_tab_ptr[i] == NULL) {
+			/*
+			 * If kmalloc fails, it is caught below same
+			 * as a channel not available.
 			 */
-			rv = (u32)(&chan_tab_ptr[chan]);
-		} else {
-			/* Release devices */
-			stp->dev_flags &= ~DEV_FLAGS_INUSE;
-			dtp->dev_flags &= ~DEV_FLAGS_INUSE;
+			ctp = kmalloc(sizeof(chan_tab_t), GFP_ATOMIC);
+			chan_tab_ptr[i] = ctp;
+			break;
 		}
+	spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
+
+	if (ctp != NULL) {
+		memset(ctp, 0, sizeof(chan_tab_t));
+		ctp->chan_index = chan = i;
+		dcp = DDMA_CHANNEL_BASE;
+		dcp += (0x0100 * chan);
+		ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
+		cp = (au1x_dma_chan_t *)dcp;
+		ctp->chan_src = stp;
+		ctp->chan_dest = dtp;
+		ctp->chan_callback = callback;
+		ctp->chan_callparam = callparam;
+
+		/* Initialize channel configuration. */
+		i = 0;
+		if (stp->dev_intlevel)
+			i |= DDMA_CFG_SED;
+		if (stp->dev_intpolarity)
+			i |= DDMA_CFG_SP;
+		if (dtp->dev_intlevel)
+			i |= DDMA_CFG_DED;
+		if (dtp->dev_intpolarity)
+			i |= DDMA_CFG_DP;
+		if ((stp->dev_flags & DEV_FLAGS_SYNC) ||
+			(dtp->dev_flags & DEV_FLAGS_SYNC))
+				i |= DDMA_CFG_SYNC;
+		cp->ddma_cfg = i;
+		au_sync();
+
+		/*
+		 * Return a non-zero value that can be used to find the channel
+		 * information in subsequent operations.
+		 */
+		return (u32)(&chan_tab_ptr[chan]);
 	}
-	return rv;
+
+	/* Release devices */
+	stp->dev_flags &= ~DEV_FLAGS_INUSE;
+	dtp->dev_flags &= ~DEV_FLAGS_INUSE;
+
+	return 0;
 }
 EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc);
 
@@ -572,7 +572,7 @@ EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc);
  * This updates the source pointer and byte count.  Normally used
  * for memory to fifo transfers.
  */
-u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
+u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags)
 {
 	chan_tab_t		*ctp;
 	au1x_ddma_desc_t	*dp;
@@ -598,7 +598,7 @@ u32 _au1xxx_dbdma_put_source(u32 chanid,
 		return 0;
 
 	/* Load up buffer address and byte count. */
-	dp->dscr_source0 = virt_to_phys(buf);
+	dp->dscr_source0 = buf & ~0UL;
 	dp->dscr_cmd1 = nbytes;
 	/* Check flags */
 	if (flags & DDMA_FLAGS_IE)
@@ -625,14 +625,13 @@ u32 _au1xxx_dbdma_put_source(u32 chanid,
 	/* Return something non-zero. */
 	return nbytes;
 }
-EXPORT_SYMBOL(_au1xxx_dbdma_put_source);
+EXPORT_SYMBOL(au1xxx_dbdma_put_source);
 
 /* Put a destination buffer into the DMA ring.
  * This updates the destination pointer and byte count.  Normally used
  * to place an empty buffer into the ring for fifo to memory transfers.
  */
-u32
-_au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
+u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags)
 {
 	chan_tab_t		*ctp;
 	au1x_ddma_desc_t	*dp;
@@ -662,7 +661,7 @@ _au1xxx_dbdma_put_dest(u32 chanid, void
 	if (flags & DDMA_FLAGS_NOIE)
 		dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
 
-	dp->dscr_dest0 = virt_to_phys(buf);
+	dp->dscr_dest0 = buf & ~0UL;
 	dp->dscr_cmd1 = nbytes;
 #if 0
 	printk(KERN_DEBUG "cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
@@ -688,7 +687,7 @@ _au1xxx_dbdma_put_dest(u32 chanid, void
 	/* Return something non-zero. */
 	return nbytes;
 }
-EXPORT_SYMBOL(_au1xxx_dbdma_put_dest);
+EXPORT_SYMBOL(au1xxx_dbdma_put_dest);
 
 /*
  * Get a destination buffer into the DMA ring.
@@ -871,28 +870,6 @@ static irqreturn_t dbdma_interrupt(int i
 	return IRQ_RETVAL(1);
 }
 
-static void au1xxx_dbdma_init(void)
-{
-	int irq_nr;
-
-	dbdma_gptr->ddma_config = 0;
-	dbdma_gptr->ddma_throttle = 0;
-	dbdma_gptr->ddma_inten = 0xffff;
-	au_sync();
-
-#if defined(CONFIG_SOC_AU1550)
-	irq_nr = AU1550_DDMA_INT;
-#elif defined(CONFIG_SOC_AU1200)
-	irq_nr = AU1200_DDMA_INT;
-#else
-	#error Unknown Au1x00 SOC
-#endif
-
-	if (request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED,
-			"Au1xxx dbdma", (void *)dbdma_gptr))
-		printk(KERN_ERR "Can't get 1550 dbdma irq");
-}
-
 void au1xxx_dbdma_dump(u32 chanid)
 {
 	chan_tab_t	 *ctp;
@@ -906,7 +883,7 @@ void au1xxx_dbdma_dump(u32 chanid)
 	dtp = ctp->chan_dest;
 	cp = ctp->chan_ptr;
 
-	printk(KERN_DEBUG "Chan %x, stp %x (dev %d)  dtp %x (dev %d) \n",
+	printk(KERN_DEBUG "Chan %x, stp %x (dev %d)  dtp %x (dev %d)\n",
 			  (u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp,
 			  dtp - dbdev_tab);
 	printk(KERN_DEBUG "desc base %x, get %x, put %x, cur %x\n",
@@ -1041,4 +1018,38 @@ void au1xxx_dbdma_resume(void)
 	}
 }
 #endif	/* CONFIG_PM */
+
+static int __init au1xxx_dbdma_init(void)
+{
+	int irq_nr, ret;
+
+	dbdma_gptr->ddma_config = 0;
+	dbdma_gptr->ddma_throttle = 0;
+	dbdma_gptr->ddma_inten = 0xffff;
+	au_sync();
+
+	switch (alchemy_get_cputype()) {
+	case ALCHEMY_CPU_AU1550:
+		irq_nr = AU1550_DDMA_INT;
+		break;
+	case ALCHEMY_CPU_AU1200:
+		irq_nr = AU1200_DDMA_INT;
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	ret = request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED,
+			"Au1xxx dbdma", (void *)dbdma_gptr);
+	if (ret)
+		printk(KERN_ERR "Cannot grab DBDMA interrupt!\n");
+	else {
+		dbdma_initialized = 1;
+		printk(KERN_INFO "Alchemy DBDMA initialized\n");
+	}
+
+	return ret;
+}
+subsys_initcall(au1xxx_dbdma_init);
+
 #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/dma.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/dma.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,8 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  *
  */
+
+#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -188,17 +190,14 @@ int request_au1000_dma(int dev_id, const
 		dev = &dma_dev_table[dev_id];
 
 	if (irqhandler) {
-		chan->irq = AU1000_DMA_INT_BASE + i;
 		chan->irq_dev = irq_dev_id;
 		ret = request_irq(chan->irq, irqhandler, irqflags, dev_str,
 				  chan->irq_dev);
 		if (ret) {
-			chan->irq = 0;
 			chan->irq_dev = NULL;
 			return ret;
 		}
 	} else {
-		chan->irq = 0;
 		chan->irq_dev = NULL;
 	}
 
@@ -226,13 +225,40 @@ void free_au1000_dma(unsigned int dmanr)
 	}
 
 	disable_dma(dmanr);
-	if (chan->irq)
+	if (chan->irq_dev)
 		free_irq(chan->irq, chan->irq_dev);
 
-	chan->irq = 0;
 	chan->irq_dev = NULL;
 	chan->dev_id = -1;
 }
 EXPORT_SYMBOL(free_au1000_dma);
 
+static int __init au1000_dma_init(void)
+{
+        int base, i;
+
+        switch (alchemy_get_cputype()) {
+        case ALCHEMY_CPU_AU1000:
+                base = AU1000_DMA_INT_BASE;
+                break;
+        case ALCHEMY_CPU_AU1500:
+                base = AU1500_DMA_INT_BASE;
+                break;
+        case ALCHEMY_CPU_AU1100:
+                base = AU1100_DMA_INT_BASE;
+                break;
+        default:
+                goto out;
+        }
+
+        for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++)
+                au1000_dma_table[i].irq = base + i;
+
+        printk(KERN_INFO "Alchemy DMA initialized\n");
+
+out:
+        return 0;
+}
+arch_initcall(au1000_dma_init);
+
 #endif /* AU1000 AU1500 AU1100 */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/gpiolib-au1000.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/gpiolib-au1000.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/gpiolib-au1000.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/gpiolib-au1000.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,7 +36,6 @@
 #include <asm/mach-au1x00/au1000.h>
 #include <asm/mach-au1x00/gpio.h>
 
-#if !defined(CONFIG_SOC_AU1000)
 static int gpio2_get(struct gpio_chip *chip, unsigned offset)
 {
 	return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE);
@@ -63,7 +62,7 @@ static int gpio2_to_irq(struct gpio_chip
 {
 	return alchemy_gpio2_to_irq(offset + ALCHEMY_GPIO2_BASE);
 }
-#endif /* !defined(CONFIG_SOC_AU1000) */
+
 
 static int gpio1_get(struct gpio_chip *chip, unsigned offset)
 {
@@ -104,7 +103,6 @@ struct gpio_chip alchemy_gpio_chip[] = {
 		.base			= ALCHEMY_GPIO1_BASE,
 		.ngpio			= ALCHEMY_GPIO1_NUM,
 	},
-#if !defined(CONFIG_SOC_AU1000)
 	[1] = {
 		.label                  = "alchemy-gpio2",
 		.direction_input        = gpio2_direction_input,
@@ -115,15 +113,13 @@ struct gpio_chip alchemy_gpio_chip[] = {
 		.base                   = ALCHEMY_GPIO2_BASE,
 		.ngpio                  = ALCHEMY_GPIO2_NUM,
 	},
-#endif
 };
 
 static int __init alchemy_gpiolib_init(void)
 {
 	gpiochip_add(&alchemy_gpio_chip[0]);
-#if !defined(CONFIG_SOC_AU1000)
-	gpiochip_add(&alchemy_gpio_chip[1]);
-#endif
+	if (alchemy_get_cputype() != ALCHEMY_CPU_AU1000)
+		gpiochip_add(&alchemy_gpio_chip[1]);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/irq.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/irq.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,168 +39,180 @@
 
 static int au1x_ic_settype(unsigned int irq, unsigned int flow_type);
 
-/* per-processor fixed function irqs */
-struct au1xxx_irqmap au1xxx_ic0_map[] __initdata = {
-
-#if defined(CONFIG_SOC_AU1000)
-	{ AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
-	{ AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
-	{ AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
+/* NOTE on interrupt priorities: The original writers of this code said:
+ *
+ * Because of the tight timing of SETUP token to reply transactions,
+ * the USB devices-side packet complete interrupt (USB_DEV_REQ_INT)
+ * needs the highest priority.
+ */
 
-#elif defined(CONFIG_SOC_AU1500)
+/* per-processor fixed function irqs */
+struct au1xxx_irqmap {
+	int im_irq;
+	int im_type;
+	int im_request;		/* set 1 to get higher priority */
+};
 
-	{ AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
-	{ AU1000_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
-	{ AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
-	{ AU1000_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
-	{ AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
-	{ AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+struct au1xxx_irqmap au1000_irqmap[] __initdata = {
+	{ AU1000_UART0_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_UART1_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_UART2_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_UART3_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_SSI0_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_SSI1_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_DMA_INT_BASE,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_DMA_INT_BASE+1,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_DMA_INT_BASE+2,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_DMA_INT_BASE+3,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_DMA_INT_BASE+4,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_DMA_INT_BASE+5,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_DMA_INT_BASE+6,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_DMA_INT_BASE+7,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_TOY_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1000_TOY_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1000_TOY_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1000_TOY_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1000_RTC_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1000_RTC_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1000_RTC_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1000_RTC_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 1 },
+	{ AU1000_IRDA_TX_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_IRDA_RX_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH,  1 },
 	{ AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
-	{ AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
-
-#elif defined(CONFIG_SOC_AU1100)
+	{ AU1000_USB_HOST_INT,	  IRQ_TYPE_LEVEL_LOW,   0 },
+	{ AU1000_ACSYNC_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1000_MAC0_DMA_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_MAC1_DMA_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1000_AC97C_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ -1, },
+};
 
-	{ AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
-	{ AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
-	{ AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
+struct au1xxx_irqmap au1500_irqmap[] __initdata = {
+	{ AU1500_UART0_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1500_PCI_INTA,	  IRQ_TYPE_LEVEL_LOW,   0 },
+	{ AU1500_PCI_INTB,	  IRQ_TYPE_LEVEL_LOW,   0 },
+	{ AU1500_UART3_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1500_PCI_INTC,	  IRQ_TYPE_LEVEL_LOW,   0 },
+	{ AU1500_PCI_INTD,	  IRQ_TYPE_LEVEL_LOW,   0 },
+	{ AU1500_DMA_INT_BASE,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1500_DMA_INT_BASE+1,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1500_DMA_INT_BASE+2,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1500_DMA_INT_BASE+3,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1500_DMA_INT_BASE+4,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1500_DMA_INT_BASE+5,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1500_DMA_INT_BASE+6,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1500_DMA_INT_BASE+7,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1500_TOY_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1500_TOY_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1500_TOY_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1500_TOY_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1500_RTC_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1500_RTC_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1500_RTC_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1500_RTC_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 1 },
+	{ AU1500_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH,  1 },
+	{ AU1500_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1500_USB_HOST_INT,	  IRQ_TYPE_LEVEL_LOW,   0 },
+	{ AU1500_ACSYNC_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1500_MAC0_DMA_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1500_MAC1_DMA_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1500_AC97C_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ -1, },
+};
 
-#elif defined(CONFIG_SOC_AU1550)
+struct au1xxx_irqmap au1100_irqmap[] __initdata = {
+	{ AU1100_UART0_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_UART1_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_SD_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_UART3_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_SSI0_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_SSI1_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_DMA_INT_BASE,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_DMA_INT_BASE+1,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_DMA_INT_BASE+2,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_DMA_INT_BASE+3,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_DMA_INT_BASE+4,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_DMA_INT_BASE+5,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_DMA_INT_BASE+6,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_DMA_INT_BASE+7,  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_TOY_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1100_TOY_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1100_TOY_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1100_TOY_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1100_RTC_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1100_RTC_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1100_RTC_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1100_RTC_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 1 },
+	{ AU1100_IRDA_TX_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_IRDA_RX_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH,  1 },
+	{ AU1100_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1100_USB_HOST_INT,	  IRQ_TYPE_LEVEL_LOW,   0 },
+	{ AU1100_ACSYNC_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1100_MAC0_DMA_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_LCD_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1100_AC97C_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ -1, },
+};
 
-	{ AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
-	{ AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
-	{ AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
-	{ AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
-	{ AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
-	{ AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
-	{ AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+struct au1xxx_irqmap au1550_irqmap[] __initdata = {
+	{ AU1550_UART0_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1550_PCI_INTA,	  IRQ_TYPE_LEVEL_LOW,   0 },
+	{ AU1550_PCI_INTB,	  IRQ_TYPE_LEVEL_LOW,   0 },
+	{ AU1550_DDMA_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1550_CRYPTO_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1550_PCI_INTC,	  IRQ_TYPE_LEVEL_LOW,   0 },
+	{ AU1550_PCI_INTD,	  IRQ_TYPE_LEVEL_LOW,   0 },
+	{ AU1550_PCI_RST_INT,	  IRQ_TYPE_LEVEL_LOW,   0 },
+	{ AU1550_UART1_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1550_UART3_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1550_PSC0_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1550_PSC1_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1550_PSC2_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1550_PSC3_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1550_TOY_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1550_TOY_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1550_TOY_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1550_TOY_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1550_RTC_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1550_RTC_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1550_RTC_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1550_RTC_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 1 },
+	{ AU1550_NAND_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH,  1 },
 	{ AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
-	{ AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-
-#elif defined(CONFIG_SOC_AU1200)
-
-	{ AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
-	{ AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
-	{ AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
-	{ AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+	{ AU1550_USB_HOST_INT,	  IRQ_TYPE_LEVEL_LOW,   0 },
+	{ AU1550_MAC0_DMA_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1550_MAC1_DMA_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ -1, },
+};
 
-#else
-#error "Error: Unknown Alchemy SOC"
-#endif
+struct au1xxx_irqmap au1200_irqmap[] __initdata = {
+	{ AU1200_UART0_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1200_SWT_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1200_SD_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1200_DDMA_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1200_MAE_BE_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1200_UART1_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1200_MAE_FE_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1200_PSC0_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1200_PSC1_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1200_AES_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1200_CAMERA_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1200_TOY_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1200_TOY_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1200_TOY_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1200_TOY_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1200_RTC_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1200_RTC_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1200_RTC_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1200_RTC_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 1 },
+	{ AU1200_NAND_INT,	  IRQ_TYPE_EDGE_RISING, 0 },
+	{ AU1200_USB_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1200_LCD_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ AU1200_MAE_BOTH_INT,	  IRQ_TYPE_LEVEL_HIGH,  0 },
+	{ -1, },
 };
 
 
@@ -306,7 +318,7 @@ static void au1x_ic1_unmask(unsigned int
  * nowhere in the current kernel sources is it disabled.	--mlau
  */
 #if defined(CONFIG_MIPS_PB1000)
-	if (irq_nr == AU1000_GPIO_15)
+	if (irq_nr == AU1000_GPIO15_INT)
 		au_writel(0x4000, PB1000_MDR); /* enable int */
 #endif
 	au_sync();
@@ -378,11 +390,13 @@ static void au1x_ic1_maskack(unsigned in
 
 static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
 {
-	unsigned int bit = irq - AU1000_INTC1_INT_BASE;
+	int bit = irq - AU1000_INTC1_INT_BASE;
 	unsigned long wakemsk, flags;
 
-	/* only GPIO 0-7 can act as wakeup source: */
-	if ((irq < AU1000_GPIO_0) || (irq > AU1000_GPIO_7))
+	/* only GPIO 0-7 can act as wakeup source.  Fortunately these
+	 * are wired up identically on all supported variants.
+	 */
+	if ((bit < 0) || (bit > 7))
 		return -EINVAL;
 
 	local_irq_save(flags);
@@ -504,11 +518,11 @@ static int au1x_ic_settype(unsigned int
 asmlinkage void plat_irq_dispatch(void)
 {
 	unsigned int pending = read_c0_status() & read_c0_cause();
-	unsigned long s, off, bit;
+	unsigned long s, off;
 
 	if (pending & CAUSEF_IP7) {
-		do_IRQ(MIPS_CPU_IRQ_BASE + 7);
-		return;
+		off = MIPS_CPU_IRQ_BASE + 7;
+		goto handle;
 	} else if (pending & CAUSEF_IP2) {
 		s = IC0_REQ0INT;
 		off = AU1000_INTC0_INT_BASE;
@@ -524,58 +538,20 @@ asmlinkage void plat_irq_dispatch(void)
 	} else
 		goto spurious;
 
-	bit = 0;
 	s = au_readl(s);
 	if (unlikely(!s)) {
 spurious:
 		spurious_interrupt();
 		return;
 	}
-#ifdef AU1000_USB_DEV_REQ_INT
-	/*
-	 * Because of the tight timing of SETUP token to reply
-	 * transactions, the USB devices-side packet complete
-	 * interrupt needs the highest priority.
-	 */
-	bit = 1 << (AU1000_USB_DEV_REQ_INT - AU1000_INTC0_INT_BASE);
-	if ((pending & CAUSEF_IP2) && (s & bit)) {
-		do_IRQ(AU1000_USB_DEV_REQ_INT);
-		return;
-	}
-#endif
-	do_IRQ(__ffs(s) + off);
+	off += __ffs(s);
+handle:
+	do_IRQ(off);
 }
 
-/* setup edge/level and assign request 0/1 */
-void __init au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count)
+static void __init au1000_init_irq(struct au1xxx_irqmap *map)
 {
 	unsigned int bit, irq_nr;
-
-	while (count--) {
-		irq_nr = map[count].im_irq;
-
-		if (((irq_nr < AU1000_INTC0_INT_BASE) ||
-		     (irq_nr >= AU1000_INTC0_INT_BASE + 32)) &&
-		    ((irq_nr < AU1000_INTC1_INT_BASE) ||
-		     (irq_nr >= AU1000_INTC1_INT_BASE + 32)))
-			continue;
-
-		if (irq_nr >= AU1000_INTC1_INT_BASE) {
-			bit = irq_nr - AU1000_INTC1_INT_BASE;
-			if (map[count].im_request)
-				au_writel(1 << bit, IC1_ASSIGNCLR);
-		} else {
-			bit = irq_nr - AU1000_INTC0_INT_BASE;
-			if (map[count].im_request)
-				au_writel(1 << bit, IC0_ASSIGNCLR);
-		}
-
-		au1x_ic_settype(irq_nr, map[count].im_type);
-	}
-}
-
-void __init arch_init_irq(void)
-{
 	int i;
 
 	/*
@@ -585,7 +561,7 @@ void __init arch_init_irq(void)
 	au_writel(0xffffffff, IC0_CFG1CLR);
 	au_writel(0xffffffff, IC0_CFG2CLR);
 	au_writel(0xffffffff, IC0_MASKCLR);
-	au_writel(0xffffffff, IC0_ASSIGNSET);
+	au_writel(0xffffffff, IC0_ASSIGNCLR);
 	au_writel(0xffffffff, IC0_WAKECLR);
 	au_writel(0xffffffff, IC0_SRCSET);
 	au_writel(0xffffffff, IC0_FALLINGCLR);
@@ -596,7 +572,7 @@ void __init arch_init_irq(void)
 	au_writel(0xffffffff, IC1_CFG1CLR);
 	au_writel(0xffffffff, IC1_CFG2CLR);
 	au_writel(0xffffffff, IC1_MASKCLR);
-	au_writel(0xffffffff, IC1_ASSIGNSET);
+	au_writel(0xffffffff, IC1_ASSIGNCLR);
 	au_writel(0xffffffff, IC1_WAKECLR);
 	au_writel(0xffffffff, IC1_SRCSET);
 	au_writel(0xffffffff, IC1_FALLINGCLR);
@@ -619,11 +595,43 @@ void __init arch_init_irq(void)
 	/*
 	 * Initialize IC0, which is fixed per processor.
 	 */
-	au1xxx_setup_irqmap(au1xxx_ic0_map, ARRAY_SIZE(au1xxx_ic0_map));
+	while (map->im_irq != -1) {
+		irq_nr = map->im_irq;
 
-	/* Boards can register additional (GPIO-based) IRQs.
-	*/
-	board_init_irq();
+		if (irq_nr >= AU1000_INTC1_INT_BASE) {
+			bit = irq_nr - AU1000_INTC1_INT_BASE;
+			if (map->im_request)
+				au_writel(1 << bit, IC1_ASSIGNSET);
+		} else {
+			bit = irq_nr - AU1000_INTC0_INT_BASE;
+			if (map->im_request)
+				au_writel(1 << bit, IC0_ASSIGNSET);
+		}
+
+		au1x_ic_settype(irq_nr, map->im_type);
+		++map;
+	}
 
 	set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3);
 }
+
+void __init arch_init_irq(void)
+{
+	switch (alchemy_get_cputype()) {
+	case ALCHEMY_CPU_AU1000:
+		au1000_init_irq(au1000_irqmap);
+		break;
+	case ALCHEMY_CPU_AU1500:
+		au1000_init_irq(au1500_irqmap);
+		break;
+	case ALCHEMY_CPU_AU1100:
+		au1000_init_irq(au1100_irqmap);
+		break;
+	case ALCHEMY_CPU_AU1550:
+		au1000_init_irq(au1550_irqmap);
+		break;
+	case ALCHEMY_CPU_AU1200:
+		au1000_init_irq(au1200_irqmap);
+		break;
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/Makefile linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/Makefile
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,14 +5,15 @@
 # Makefile for the Alchemy Au1xx0 CPUs, generic files.
 #
 
-obj-y += prom.o irq.o puts.o time.o reset.o \
-	clocks.o platform.o power.o setup.o \
+obj-y += prom.o time.o clocks.o platform.o power.o setup.o \
 	sleeper.o dma.o dbdma.o
 
+obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += irq.o
+
 # optional gpiolib support
 ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
  ifeq ($(CONFIG_GPIOLIB),y)
-  obj-$(CONFIG_ALCHEMY_GPIO_AU1000) += gpiolib-au1000.o
+  obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += gpiolib-au1000.o
  endif
 endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/platform.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/platform.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/platform.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/platform.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,39 +19,40 @@
 #include <asm/mach-au1x00/au1xxx.h>
 #include <asm/mach-au1x00/au1xxx_dbdma.h>
 #include <asm/mach-au1x00/au1100_mmc.h>
+#include <asm/mach-au1x00/au1xxx_eth.h>
 
-#define PORT(_base, _irq)				\
-	{						\
-		.iobase		= _base,		\
-		.membase	= (void __iomem *)_base,\
-		.mapbase	= CPHYSADDR(_base),	\
-		.irq		= _irq,			\
-		.regshift	= 2,			\
-		.iotype		= UPIO_AU,		\
-		.flags		= UPF_SKIP_TEST 	\
+#define PORT(_base, _irq)					\
+	{							\
+		.mapbase	= _base,			\
+		.irq		= _irq,				\
+		.regshift	= 2,				\
+		.iotype		= UPIO_AU,			\
+		.flags		= UPF_SKIP_TEST | UPF_IOREMAP |	\
+				  UPF_FIXED_TYPE,		\
+		.type		= PORT_16550A,			\
 	}
 
 static struct plat_serial8250_port au1x00_uart_data[] = {
 #if defined(CONFIG_SERIAL_8250_AU1X00)
 #if defined(CONFIG_SOC_AU1000)
-	PORT(UART0_ADDR, AU1000_UART0_INT),
-	PORT(UART1_ADDR, AU1000_UART1_INT),
-	PORT(UART2_ADDR, AU1000_UART2_INT),
-	PORT(UART3_ADDR, AU1000_UART3_INT),
+	PORT(UART0_PHYS_ADDR, AU1000_UART0_INT),
+	PORT(UART1_PHYS_ADDR, AU1000_UART1_INT),
+	PORT(UART2_PHYS_ADDR, AU1000_UART2_INT),
+	PORT(UART3_PHYS_ADDR, AU1000_UART3_INT),
 #elif defined(CONFIG_SOC_AU1500)
-	PORT(UART0_ADDR, AU1500_UART0_INT),
-	PORT(UART3_ADDR, AU1500_UART3_INT),
+	PORT(UART0_PHYS_ADDR, AU1500_UART0_INT),
+	PORT(UART3_PHYS_ADDR, AU1500_UART3_INT),
 #elif defined(CONFIG_SOC_AU1100)
-	PORT(UART0_ADDR, AU1100_UART0_INT),
-	PORT(UART1_ADDR, AU1100_UART1_INT),
-	PORT(UART3_ADDR, AU1100_UART3_INT),
+	PORT(UART0_PHYS_ADDR, AU1100_UART0_INT),
+	PORT(UART1_PHYS_ADDR, AU1100_UART1_INT),
+	PORT(UART3_PHYS_ADDR, AU1100_UART3_INT),
 #elif defined(CONFIG_SOC_AU1550)
-	PORT(UART0_ADDR, AU1550_UART0_INT),
-	PORT(UART1_ADDR, AU1550_UART1_INT),
-	PORT(UART3_ADDR, AU1550_UART3_INT),
+	PORT(UART0_PHYS_ADDR, AU1550_UART0_INT),
+	PORT(UART1_PHYS_ADDR, AU1550_UART1_INT),
+	PORT(UART3_PHYS_ADDR, AU1550_UART3_INT),
 #elif defined(CONFIG_SOC_AU1200)
-	PORT(UART0_ADDR, AU1200_UART0_INT),
-	PORT(UART1_ADDR, AU1200_UART1_INT),
+	PORT(UART0_PHYS_ADDR, AU1200_UART0_INT),
+	PORT(UART1_PHYS_ADDR, AU1200_UART1_INT),
 #endif
 #endif	/* CONFIG_SERIAL_8250_AU1X00 */
 	{ },
@@ -73,8 +74,8 @@ static struct resource au1xxx_usb_ohci_r
 		.flags		= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start		= AU1000_USB_HOST_INT,
-		.end		= AU1000_USB_HOST_INT,
+		.start		= FOR_PLATFORM_C_USB_HOST_INT,
+		.end		= FOR_PLATFORM_C_USB_HOST_INT,
 		.flags		= IORESOURCE_IRQ,
 	},
 };
@@ -132,8 +133,8 @@ static struct resource au1xxx_usb_ehci_r
 		.flags		= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start		= AU1000_USB_HOST_INT,
-		.end		= AU1000_USB_HOST_INT,
+		.start		= AU1200_USB_INT,
+		.end		= AU1200_USB_INT,
 		.flags		= IORESOURCE_IRQ,
 	},
 };
@@ -308,11 +309,6 @@ static struct platform_device au1200_mmc
 #endif /* #ifndef CONFIG_MIPS_DB1200 */
 #endif /* #ifdef CONFIG_SOC_AU1200 */
 
-static struct platform_device au1x00_pcmcia_device = {
-	.name 		= "au1x00-pcmcia",
-	.id 		= 0,
-};
-
 /* All Alchemy demoboards with I2C have this #define in their headers */
 #ifdef SMBUS_PSC_BASE
 static struct resource pbdb_smbus_resources[] = {
@@ -331,10 +327,92 @@ static struct platform_device pbdb_smbus
 };
 #endif
 
+/* Macro to help defining the Ethernet MAC resources */
+#define MAC_RES(_base, _enable, _irq)			\
+	{						\
+		.start	= CPHYSADDR(_base),		\
+		.end	= CPHYSADDR(_base + 0xffff),	\
+		.flags	= IORESOURCE_MEM,		\
+	},						\
+	{						\
+		.start	= CPHYSADDR(_enable),		\
+		.end	= CPHYSADDR(_enable + 0x3),	\
+		.flags	= IORESOURCE_MEM,		\
+	},						\
+	{						\
+		.start	= _irq,				\
+		.end	= _irq,				\
+		.flags	= IORESOURCE_IRQ		\
+	}
+
+static struct resource au1xxx_eth0_resources[] = {
+#if defined(CONFIG_SOC_AU1000)
+	MAC_RES(AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT),
+#elif defined(CONFIG_SOC_AU1100)
+	MAC_RES(AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT),
+#elif defined(CONFIG_SOC_AU1550)
+	MAC_RES(AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT),
+#elif defined(CONFIG_SOC_AU1500)
+	MAC_RES(AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT),
+#endif
+};
+
+
+static struct au1000_eth_platform_data au1xxx_eth0_platform_data = {
+	.phy1_search_mac0 = 1,
+};
+
+static struct platform_device au1xxx_eth0_device = {
+	.name		= "au1000-eth",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(au1xxx_eth0_resources),
+	.resource	= au1xxx_eth0_resources,
+	.dev.platform_data = &au1xxx_eth0_platform_data,
+};
+
+#ifndef CONFIG_SOC_AU1100
+static struct resource au1xxx_eth1_resources[] = {
+#if defined(CONFIG_SOC_AU1000)
+	MAC_RES(AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT),
+#elif defined(CONFIG_SOC_AU1550)
+	MAC_RES(AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT),
+#elif defined(CONFIG_SOC_AU1500)
+	MAC_RES(AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT),
+#endif
+};
+
+static struct au1000_eth_platform_data au1xxx_eth1_platform_data = {
+	.phy1_search_mac0 = 1,
+};
+
+static struct platform_device au1xxx_eth1_device = {
+	.name		= "au1000-eth",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(au1xxx_eth1_resources),
+	.resource	= au1xxx_eth1_resources,
+	.dev.platform_data = &au1xxx_eth1_platform_data,
+};
+#endif
+
+void __init au1xxx_override_eth_cfg(unsigned int port,
+			struct au1000_eth_platform_data *eth_data)
+{
+	if (!eth_data || port > 1)
+		return;
+
+	if (port == 0)
+		memcpy(&au1xxx_eth0_platform_data, eth_data,
+			sizeof(struct au1000_eth_platform_data));
+#ifndef CONFIG_SOC_AU1100
+	else
+		memcpy(&au1xxx_eth1_platform_data, eth_data,
+			sizeof(struct au1000_eth_platform_data));
+#endif
+}
+
 static struct platform_device *au1xxx_platform_devices[] __initdata = {
 	&au1xx0_uart_device,
 	&au1xxx_usb_ohci_device,
-	&au1x00_pcmcia_device,
 #ifdef CONFIG_FB_AU1100
 	&au1100_lcd_device,
 #endif
@@ -351,6 +429,7 @@ static struct platform_device *au1xxx_pl
 #ifdef SMBUS_PSC_BASE
 	&pbdb_smbus_device,
 #endif
+	&au1xxx_eth0_device,
 };
 
 static int __init au1xxx_platform_init(void)
@@ -362,6 +441,12 @@ static int __init au1xxx_platform_init(v
 	for (i = 0; au1x00_uart_data[i].flags; i++)
 		au1x00_uart_data[i].uartclk = uartclk;
 
+#ifndef CONFIG_SOC_AU1100
+	/* Register second MAC if enabled in pinfunc */
+	if (!(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2))
+		platform_device_register(&au1xxx_eth1_device);
+#endif
+
 	return platform_add_devices(au1xxx_platform_devices,
 				    ARRAY_SIZE(au1xxx_platform_devices));
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/prom.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/prom.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/prom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/prom.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,29 +43,15 @@ int prom_argc;
 char **prom_argv;
 char **prom_envp;
 
-char * __init_or_module prom_getcmdline(void)
-{
-	return &(arcs_cmdline[0]);
-}
-
 void prom_init_cmdline(void)
 {
-	char *cp;
-	int actr;
-
-	actr = 1; /* Always ignore argv[0] */
+	int i;
 
-	cp = &(arcs_cmdline[0]);
-	while (actr < prom_argc) {
-		strcpy(cp, prom_argv[actr]);
-		cp += strlen(prom_argv[actr]);
-		*cp++ = ' ';
-		actr++;
+	for (i = 1; i < prom_argc; i++) {
+		strlcat(arcs_cmdline, prom_argv[i], COMMAND_LINE_SIZE);
+		if (i < (prom_argc - 1))
+			strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
 	}
-	if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
-		--cp;
-	if (prom_argc > 1)
-		*cp = '\0';
 }
 
 char *prom_getenv(char *envname)
@@ -121,14 +107,12 @@ static inline void str2eaddr(unsigned ch
 int prom_get_ethernet_addr(char *ethernet_addr)
 {
 	char *ethaddr_str;
-	char *argptr;
 
 	/* Check the environment variables first */
 	ethaddr_str = prom_getenv("ethaddr");
 	if (!ethaddr_str) {
 		/* Check command line */
-		argptr = prom_getcmdline();
-		ethaddr_str = strstr(argptr, "ethaddr=");
+		ethaddr_str = strstr(arcs_cmdline, "ethaddr=");
 		if (!ethaddr_str)
 			return -1;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/puts.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/puts.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/puts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/puts.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,68 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *	Low level UART routines to directly access Alchemy UART.
- *
- * Copyright 2001, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@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.
- *
- *  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.
- */
-
-#include <asm/mach-au1x00/au1000.h>
-
-#define SERIAL_BASE   UART_BASE
-#define SER_CMD       0x7
-#define SER_DATA      0x1
-#define TX_BUSY       0x20
-
-#define TIMEOUT       0xffffff
-#define SLOW_DOWN
-
-static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE;
-
-#ifdef SLOW_DOWN
-static inline void slow_down(void)
-{
-	int k;
-
-	for (k = 0; k < 10000; k++);
-}
-#else
-#define slow_down()
-#endif
-
-void
-prom_putchar(const unsigned char c)
-{
-	unsigned char ch;
-	int i = 0;
-
-	do {
-		ch = com1[SER_CMD];
-		slow_down();
-		i++;
-		if (i > TIMEOUT)
-			break;
-	} while (0 == (ch & TX_BUSY));
-
-	com1[SER_DATA] = c;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/reset.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/reset.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/reset.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/reset.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,188 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *	Au1xx0 reset routines.
- *
- * Copyright 2001, 2006, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@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.
- *
- *  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.
- */
-
-#include <linux/gpio.h>
-
-#include <asm/cacheflush.h>
-#include <asm/mach-au1x00/au1000.h>
-
-void au1000_restart(char *command)
-{
-	/* Set all integrated peripherals to disabled states */
-	extern void board_reset(void);
-	u32 prid = read_c0_prid();
-
-	printk(KERN_NOTICE "\n** Resetting Integrated Peripherals\n");
-
-	switch (prid & 0xFF000000) {
-	case 0x00000000: /* Au1000 */
-		au_writel(0x02, 0xb0000010); /* ac97_enable */
-		au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
-		asm("sync");
-		au_writel(0x00, 0xb017fffc); /* usbh_enable */
-		au_writel(0x00, 0xb0200058); /* usbd_enable */
-		au_writel(0x00, 0xb0300040); /* ir_enable */
-		au_writel(0x00, 0xb4004104); /* mac dma */
-		au_writel(0x00, 0xb4004114); /* mac dma */
-		au_writel(0x00, 0xb4004124); /* mac dma */
-		au_writel(0x00, 0xb4004134); /* mac dma */
-		au_writel(0x00, 0xb0520000); /* macen0 */
-		au_writel(0x00, 0xb0520004); /* macen1 */
-		au_writel(0x00, 0xb1000008); /* i2s_enable  */
-		au_writel(0x00, 0xb1100100); /* uart0_enable */
-		au_writel(0x00, 0xb1200100); /* uart1_enable */
-		au_writel(0x00, 0xb1300100); /* uart2_enable */
-		au_writel(0x00, 0xb1400100); /* uart3_enable */
-		au_writel(0x02, 0xb1600100); /* ssi0_enable */
-		au_writel(0x02, 0xb1680100); /* ssi1_enable */
-		au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
-		au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
-		au_writel(0x00, 0xb1900028); /* sys_clksrc */
-		au_writel(0x10, 0xb1900060); /* sys_cpupll */
-		au_writel(0x00, 0xb1900064); /* sys_auxpll */
-		au_writel(0x00, 0xb1900100); /* sys_pininputen */
-		break;
-	case 0x01000000: /* Au1500 */
-		au_writel(0x02, 0xb0000010); /* ac97_enable */
-		au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
-		asm("sync");
-		au_writel(0x00, 0xb017fffc); /* usbh_enable */
-		au_writel(0x00, 0xb0200058); /* usbd_enable */
-		au_writel(0x00, 0xb4004104); /* mac dma */
-		au_writel(0x00, 0xb4004114); /* mac dma */
-		au_writel(0x00, 0xb4004124); /* mac dma */
-		au_writel(0x00, 0xb4004134); /* mac dma */
-		au_writel(0x00, 0xb1520000); /* macen0 */
-		au_writel(0x00, 0xb1520004); /* macen1 */
-		au_writel(0x00, 0xb1100100); /* uart0_enable */
-		au_writel(0x00, 0xb1400100); /* uart3_enable */
-		au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
-		au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
-		au_writel(0x00, 0xb1900028); /* sys_clksrc */
-		au_writel(0x10, 0xb1900060); /* sys_cpupll */
-		au_writel(0x00, 0xb1900064); /* sys_auxpll */
-		au_writel(0x00, 0xb1900100); /* sys_pininputen */
-		break;
-	case 0x02000000: /* Au1100 */
-		au_writel(0x02, 0xb0000010); /* ac97_enable */
-		au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
-		asm("sync");
-		au_writel(0x00, 0xb017fffc); /* usbh_enable */
-		au_writel(0x00, 0xb0200058); /* usbd_enable */
-		au_writel(0x00, 0xb0300040); /* ir_enable */
-		au_writel(0x00, 0xb4004104); /* mac dma */
-		au_writel(0x00, 0xb4004114); /* mac dma */
-		au_writel(0x00, 0xb4004124); /* mac dma */
-		au_writel(0x00, 0xb4004134); /* mac dma */
-		au_writel(0x00, 0xb0520000); /* macen0 */
-		au_writel(0x00, 0xb1000008); /* i2s_enable  */
-		au_writel(0x00, 0xb1100100); /* uart0_enable */
-		au_writel(0x00, 0xb1200100); /* uart1_enable */
-		au_writel(0x00, 0xb1400100); /* uart3_enable */
-		au_writel(0x02, 0xb1600100); /* ssi0_enable */
-		au_writel(0x02, 0xb1680100); /* ssi1_enable */
-		au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
-		au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
-		au_writel(0x00, 0xb1900028); /* sys_clksrc */
-		au_writel(0x10, 0xb1900060); /* sys_cpupll */
-		au_writel(0x00, 0xb1900064); /* sys_auxpll */
-		au_writel(0x00, 0xb1900100); /* sys_pininputen */
-		break;
-	case 0x03000000: /* Au1550 */
-		au_writel(0x00, 0xb1a00004); /* psc 0 */
-		au_writel(0x00, 0xb1b00004); /* psc 1 */
-		au_writel(0x00, 0xb0a00004); /* psc 2 */
-		au_writel(0x00, 0xb0b00004); /* psc 3 */
-		au_writel(0x00, 0xb017fffc); /* usbh_enable */
-		au_writel(0x00, 0xb0200058); /* usbd_enable */
-		au_writel(0x00, 0xb4004104); /* mac dma */
-		au_writel(0x00, 0xb4004114); /* mac dma */
-		au_writel(0x00, 0xb4004124); /* mac dma */
-		au_writel(0x00, 0xb4004134); /* mac dma */
-		au_writel(0x00, 0xb1520000); /* macen0 */
-		au_writel(0x00, 0xb1520004); /* macen1 */
-		au_writel(0x00, 0xb1100100); /* uart0_enable */
-		au_writel(0x00, 0xb1200100); /* uart1_enable */
-		au_writel(0x00, 0xb1400100); /* uart3_enable */
-		au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
-		au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
-		au_writel(0x00, 0xb1900028); /* sys_clksrc */
-		au_writel(0x10, 0xb1900060); /* sys_cpupll */
-		au_writel(0x00, 0xb1900064); /* sys_auxpll */
-		au_writel(0x00, 0xb1900100); /* sys_pininputen */
-		break;
-	}
-
-	set_c0_status(ST0_BEV | ST0_ERL);
-	change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
-	flush_cache_all();
-	write_c0_wired(0);
-
-	/* Give board a chance to do a hardware reset */
-	board_reset();
-
-	/* Jump to the beggining in case board_reset() is empty */
-	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
-}
-
-void au1000_halt(void)
-{
-#if defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_DB1550)
-	/* Power off system */
-	printk(KERN_NOTICE "\n** Powering off...\n");
-	au_writew(au_readw(0xAF00001C) | (3 << 14), 0xAF00001C);
-	au_sync();
-	while (1); /* should not get here */
-#else
-	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
-#ifdef CONFIG_MIPS_MIRAGE
-	gpio_direction_output(210, 1);
-#endif
-#ifdef CONFIG_MIPS_DB1200
-	au_writew(au_readw(0xB980001C) | (1 << 14), 0xB980001C);
-#endif
-#ifdef CONFIG_PM
-	au_sleep();
-
-	/* Should not get here */
-	printk(KERN_ERR "Unable to put CPU in sleep mode\n");
-	while (1);
-#else
-	while (1)
-		__asm__(".set\tmips3\n\t"
-	                "wait\n\t"
-			".set\tmips0");
-#endif
-#endif /* defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_DB1550) */
-}
-
-void au1000_power_off(void)
-{
-	au1000_halt();
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/setup.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,18 +29,13 @@
 #include <linux/ioport.h>
 #include <linux/jiffies.h>
 #include <linux/module.h>
-#include <linux/pm.h>
 
 #include <asm/mipsregs.h>
-#include <asm/reboot.h>
 #include <asm/time.h>
 
 #include <au1000.h>
 
 extern void __init board_setup(void);
-extern void au1000_restart(char *);
-extern void au1000_halt(void);
-extern void au1000_power_off(void);
 extern void set_cpuspec(void);
 
 void __init plat_mem_setup(void)
@@ -57,10 +52,6 @@ void __init plat_mem_setup(void)
 	/* this is faster than wasting cycles trying to approximate it */
 	preset_lpj = (est_freq >> 1) / HZ;
 
-	_machine_restart = au1000_restart;
-	_machine_halt = au1000_halt;
-	pm_power_off = au1000_power_off;
-
 	board_setup();  /* board specific setup */
 
 	if (au1xxx_cpu_needs_config_od())
@@ -78,37 +69,20 @@ void __init plat_mem_setup(void)
 	iomem_resource.end = IOMEM_RESOURCE_END;
 }
 
-#if defined(CONFIG_64BIT_PHYS_ADDR)
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI)
 /* This routine should be valid for all Au1x based boards */
 phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
 {
+	u32 start = (u32)Au1500_PCI_MEM_START;
+	u32 end   = (u32)Au1500_PCI_MEM_END;
+
 	/* Don't fixup 36-bit addresses */
 	if ((phys_addr >> 32) != 0)
 		return phys_addr;
 
-#ifdef CONFIG_PCI
-	{
-		u32 start = (u32)Au1500_PCI_MEM_START;
-		u32 end   = (u32)Au1500_PCI_MEM_END;
-
-		/* Check for PCI memory window */
-		if (phys_addr >= start && (phys_addr + size - 1) <= end)
-			return (phys_t)
-			       ((phys_addr - start) + Au1500_PCI_MEM_START);
-	}
-#endif
-
-	/*
-	 * All Au1xx0 SOCs have a PCMCIA controller.
-	 * We setup our 32-bit pseudo addresses to be equal to the
-	 * 36-bit addr >> 4, to make it easier to check the address
-	 * and fix it.
-	 * The PCMCIA socket 0 physical attribute address is 0xF 4000 0000.
-	 * The pseudo address we use is 0xF400 0000. Any address over
-	 * 0xF400 0000 is a PCMCIA pseudo address.
-	 */
-	if ((phys_addr >= 0xF4000000) && (phys_addr < 0xFFFFFFFF))
-		return (phys_t)(phys_addr << 4);
+	/* Check for PCI memory window */
+	if (phys_addr >= start && (phys_addr + size - 1) <= end)
+		return (phys_t)((phys_addr - start) + Au1500_PCI_MEM_START);
 
 	/* default nop */
 	return phys_addr;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/time.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/time.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/common/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Manuel Lauss <mano@roarinelk.homelinux.net>
+ * Copyright (C) 2008-2009 Manuel Lauss <manuel.lauss@gmail.com>
  *
  * Previous incarnations were:
  * Copyright (C) 2001, 2006, 2008 MontaVista Software, <source@mvista.com>
@@ -85,7 +85,6 @@ static struct clock_event_device au1x_rt
 	.name		= "rtcmatch2",
 	.features	= CLOCK_EVT_FEAT_ONESHOT,
 	.rating		= 100,
-	.irq		= AU1000_RTC_MATCH2_INT,
 	.set_next_event	= au1x_rtcmatch2_set_next_event,
 	.set_mode	= au1x_rtcmatch2_set_mode,
 	.cpumask	= cpu_all_mask,
@@ -98,11 +97,13 @@ static struct irqaction au1x_rtcmatch2_i
 	.dev_id		= &au1x_rtcmatch2_clockdev,
 };
 
-void __init plat_time_init(void)
+static int __init alchemy_time_init(unsigned int m2int)
 {
 	struct clock_event_device *cd = &au1x_rtcmatch2_clockdev;
 	unsigned long t;
 
+	au1x_rtcmatch2_clockdev.irq = m2int;
+
 	/* Check if firmware (YAMON, ...) has enabled 32kHz and clock
 	 * has been detected.  If so install the rtcmatch2 clocksource,
 	 * otherwise don't bother.  Note that both bits being set is by
@@ -148,13 +149,18 @@ void __init plat_time_init(void)
 	cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd);
 	cd->min_delta_ns = clockevent_delta2ns(8, cd);	/* ~0.25ms */
 	clockevents_register_device(cd);
-	setup_irq(AU1000_RTC_MATCH2_INT, &au1x_rtcmatch2_irqaction);
+	setup_irq(m2int, &au1x_rtcmatch2_irqaction);
 
 	printk(KERN_INFO "Alchemy clocksource installed\n");
 
-	return;
+	return 0;
 
 cntr_err:
+	return -1;
+}
+
+static void __init alchemy_setup_c0timer(void)
+{
 	/*
 	 * MIPS kernel assigns 'au1k_wait' to 'cpu_wait' before this
 	 * function is called.  Because the Alchemy counters are unusable
@@ -166,3 +172,22 @@ cntr_err:
 	r4k_clockevent_init();
 	init_r4k_clocksource();
 }
+
+static int alchemy_m2inttab[] __initdata = {
+	AU1000_RTC_MATCH2_INT,
+	AU1500_RTC_MATCH2_INT,
+	AU1100_RTC_MATCH2_INT,
+	AU1550_RTC_MATCH2_INT,
+	AU1200_RTC_MATCH2_INT,
+};
+
+void __init plat_time_init(void)
+{
+	int t;
+
+	t = alchemy_get_cputype();
+	if (t == ALCHEMY_CPU_UNKNOWN)
+		alchemy_setup_c0timer();
+	else if (alchemy_time_init(alchemy_m2inttab[t]))
+		alchemy_setup_c0timer();
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/bcsr.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/bcsr.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/bcsr.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/bcsr.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,148 @@
+/*
+ * bcsr.h -- Db1xxx/Pb1xxx Devboard CPLD registers ("BCSR") abstraction.
+ *
+ * All Alchemy development boards (except, of course, the weird PB1000)
+ * have a few registers in a CPLD with standardised layout; they mostly
+ * only differ in base address.
+ * All registers are 16bits wide with 32bit spacing.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <asm/addrspace.h>
+#include <asm/io.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+static struct bcsr_reg {
+	void __iomem *raddr;
+	spinlock_t lock;
+} bcsr_regs[BCSR_CNT];
+
+static void __iomem *bcsr_virt;	/* KSEG1 addr of BCSR base */
+static int bcsr_csc_base;	/* linux-irq of first cascaded irq */
+
+void __init bcsr_init(unsigned long bcsr1_phys, unsigned long bcsr2_phys)
+{
+	int i;
+
+	bcsr1_phys = KSEG1ADDR(CPHYSADDR(bcsr1_phys));
+	bcsr2_phys = KSEG1ADDR(CPHYSADDR(bcsr2_phys));
+
+	bcsr_virt = (void __iomem *)bcsr1_phys;
+
+	for (i = 0; i < BCSR_CNT; i++) {
+		if (i >= BCSR_HEXLEDS)
+			bcsr_regs[i].raddr = (void __iomem *)bcsr2_phys +
+					(0x04 * (i - BCSR_HEXLEDS));
+		else
+			bcsr_regs[i].raddr = (void __iomem *)bcsr1_phys +
+					(0x04 * i);
+
+		spin_lock_init(&bcsr_regs[i].lock);
+	}
+}
+
+unsigned short bcsr_read(enum bcsr_id reg)
+{
+	unsigned short r;
+	unsigned long flags;
+
+	spin_lock_irqsave(&bcsr_regs[reg].lock, flags);
+	r = __raw_readw(bcsr_regs[reg].raddr);
+	spin_unlock_irqrestore(&bcsr_regs[reg].lock, flags);
+	return r;
+}
+EXPORT_SYMBOL_GPL(bcsr_read);
+
+void bcsr_write(enum bcsr_id reg, unsigned short val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&bcsr_regs[reg].lock, flags);
+	__raw_writew(val, bcsr_regs[reg].raddr);
+	wmb();
+	spin_unlock_irqrestore(&bcsr_regs[reg].lock, flags);
+}
+EXPORT_SYMBOL_GPL(bcsr_write);
+
+void bcsr_mod(enum bcsr_id reg, unsigned short clr, unsigned short set)
+{
+	unsigned short r;
+	unsigned long flags;
+
+	spin_lock_irqsave(&bcsr_regs[reg].lock, flags);
+	r = __raw_readw(bcsr_regs[reg].raddr);
+	r &= ~clr;
+	r |= set;
+	__raw_writew(r, bcsr_regs[reg].raddr);
+	wmb();
+	spin_unlock_irqrestore(&bcsr_regs[reg].lock, flags);
+}
+EXPORT_SYMBOL_GPL(bcsr_mod);
+
+/*
+ * DB1200/PB1200 CPLD IRQ muxer
+ */
+static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)
+{
+	unsigned short bisr = __raw_readw(bcsr_virt + BCSR_REG_INTSTAT);
+
+	for ( ; bisr; bisr &= bisr - 1)
+		generic_handle_irq(bcsr_csc_base + __ffs(bisr));
+}
+
+/* NOTE: both the enable and mask bits must be cleared, otherwise the
+ * CPLD generates tons of spurious interrupts (at least on my DB1200).
+ *	-- mlau
+ */
+static void bcsr_irq_mask(unsigned int irq_nr)
+{
+	unsigned short v = 1 << (irq_nr - bcsr_csc_base);
+	__raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
+	__raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
+	wmb();
+}
+
+static void bcsr_irq_maskack(unsigned int irq_nr)
+{
+	unsigned short v = 1 << (irq_nr - bcsr_csc_base);
+	__raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
+	__raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
+	__raw_writew(v, bcsr_virt + BCSR_REG_INTSTAT);	/* ack */
+	wmb();
+}
+
+static void bcsr_irq_unmask(unsigned int irq_nr)
+{
+	unsigned short v = 1 << (irq_nr - bcsr_csc_base);
+	__raw_writew(v, bcsr_virt + BCSR_REG_INTSET);
+	__raw_writew(v, bcsr_virt + BCSR_REG_MASKSET);
+	wmb();
+}
+
+static struct irq_chip bcsr_irq_type = {
+	.name		= "CPLD",
+	.mask		= bcsr_irq_mask,
+	.mask_ack	= bcsr_irq_maskack,
+	.unmask		= bcsr_irq_unmask,
+};
+
+void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq)
+{
+	unsigned int irq;
+
+	/* mask & disable & ack all */
+	__raw_writew(0xffff, bcsr_virt + BCSR_REG_INTCLR);
+	__raw_writew(0xffff, bcsr_virt + BCSR_REG_MASKCLR);
+	__raw_writew(0xffff, bcsr_virt + BCSR_REG_INTSTAT);
+	wmb();
+
+	bcsr_csc_base = csc_start;
+
+	for (irq = csc_start; irq <= csc_end; irq++)
+		set_irq_chip_and_handler_name(irq, &bcsr_irq_type,
+			handle_level_irq, "level");
+
+	set_irq_chained_handler(hook_irq, bcsr_csc_handler);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/db1200/Makefile linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/db1200/Makefile
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/db1200/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/db1200/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1 @@
+obj-y += setup.o platform.o
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/db1200/platform.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/db1200/platform.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/db1200/platform.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/db1200/platform.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,561 @@
+/*
+ * DBAu1200 board platform device registration
+ *
+ * Copyright (C) 2008-2009 Manuel Lauss
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/dma-mapping.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/mmc/host.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/smc91x.h>
+
+#include <asm/mach-au1x00/au1100_mmc.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+#include <asm/mach-au1x00/au1550_spi.h>
+#include <asm/mach-db1x00/bcsr.h>
+#include <asm/mach-db1x00/db1200.h>
+
+#include "../platform.h"
+
+static struct mtd_partition db1200_spiflash_parts[] = {
+	{
+		.name	= "DB1200 SPI flash",
+		.offset	= 0,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct flash_platform_data db1200_spiflash_data = {
+	.name		= "s25fl001",
+	.parts		= db1200_spiflash_parts,
+	.nr_parts	= ARRAY_SIZE(db1200_spiflash_parts),
+	.type		= "m25p10",
+};
+
+static struct spi_board_info db1200_spi_devs[] __initdata = {
+	{
+		/* TI TMP121AIDBVR temp sensor */
+		.modalias	= "tmp121",
+		.max_speed_hz	= 2000000,
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.mode		= 0,
+	},
+	{
+		/* Spansion S25FL001D0FMA SPI flash */
+		.modalias	= "m25p80",
+		.max_speed_hz	= 50000000,
+		.bus_num	= 0,
+		.chip_select	= 1,
+		.mode		= 0,
+		.platform_data	= &db1200_spiflash_data,
+	},
+};
+
+static struct i2c_board_info db1200_i2c_devs[] __initdata = {
+	{
+		/* AT24C04-10 I2C eeprom */
+		I2C_BOARD_INFO("24c04", 0x52),
+	},
+	{
+		/* Philips NE1619 temp/voltage sensor (adm1025 drv) */
+		I2C_BOARD_INFO("ne1619", 0x2d),
+	},
+	{
+		/* I2S audio codec WM8731 */
+		I2C_BOARD_INFO("wm8731", 0x1b),
+	},
+};
+
+/**********************************************************************/
+
+static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+				 unsigned int ctrl)
+{
+	struct nand_chip *this = mtd->priv;
+	unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
+
+	ioaddr &= 0xffffff00;
+
+	if (ctrl & NAND_CLE) {
+		ioaddr += MEM_STNAND_CMD;
+	} else if (ctrl & NAND_ALE) {
+		ioaddr += MEM_STNAND_ADDR;
+	} else {
+		/* assume we want to r/w real data  by default */
+		ioaddr += MEM_STNAND_DATA;
+	}
+	this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
+	if (cmd != NAND_CMD_NONE) {
+		__raw_writeb(cmd, this->IO_ADDR_W);
+		wmb();
+	}
+}
+
+static int au1200_nand_device_ready(struct mtd_info *mtd)
+{
+	return __raw_readl((void __iomem *)MEM_STSTAT) & 1;
+}
+
+static const char *db1200_part_probes[] = { "cmdlinepart", NULL };
+
+static struct mtd_partition db1200_nand_parts[] = {
+	{
+		.name	= "NAND FS 0",
+		.offset	= 0,
+		.size	= 8 * 1024 * 1024,
+	},
+	{
+		.name	= "NAND FS 1",
+		.offset	= MTDPART_OFS_APPEND,
+		.size	= MTDPART_SIZ_FULL
+	},
+};
+
+struct platform_nand_data db1200_nand_platdata = {
+	.chip = {
+		.nr_chips	= 1,
+		.chip_offset	= 0,
+		.nr_partitions	= ARRAY_SIZE(db1200_nand_parts),
+		.partitions	= db1200_nand_parts,
+		.chip_delay	= 20,
+		.part_probe_types = db1200_part_probes,
+	},
+	.ctrl = {
+		.dev_ready	= au1200_nand_device_ready,
+		.cmd_ctrl	= au1200_nand_cmd_ctrl,
+	},
+};
+
+static struct resource db1200_nand_res[] = {
+	[0] = {
+		.start	= DB1200_NAND_PHYS_ADDR,
+		.end	= DB1200_NAND_PHYS_ADDR + 0xff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device db1200_nand_dev = {
+	.name		= "gen_nand",
+	.num_resources	= ARRAY_SIZE(db1200_nand_res),
+	.resource	= db1200_nand_res,
+	.id		= -1,
+	.dev		= {
+		.platform_data = &db1200_nand_platdata,
+	}
+};
+
+/**********************************************************************/
+
+static struct smc91x_platdata db1200_eth_data = {
+	.flags	= SMC91X_NOWAIT | SMC91X_USE_16BIT,
+	.leda	= RPC_LED_100_10,
+	.ledb	= RPC_LED_TX_RX,
+};
+
+static struct resource db1200_eth_res[] = {
+	[0] = {
+		.start	= DB1200_ETH_PHYS_ADDR,
+		.end	= DB1200_ETH_PHYS_ADDR + 0xf,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= DB1200_ETH_INT,
+		.end	= DB1200_ETH_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device db1200_eth_dev = {
+	.dev	= {
+		.platform_data	= &db1200_eth_data,
+	},
+	.name		= "smc91x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(db1200_eth_res),
+	.resource	= db1200_eth_res,
+};
+
+/**********************************************************************/
+
+static struct resource db1200_ide_res[] = {
+	[0] = {
+		.start	= DB1200_IDE_PHYS_ADDR,
+		.end 	= DB1200_IDE_PHYS_ADDR + DB1200_IDE_PHYS_LEN - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= DB1200_IDE_INT,
+		.end	= DB1200_IDE_INT,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static u64 ide_dmamask = DMA_32BIT_MASK;
+
+static struct platform_device db1200_ide_dev = {
+	.name		= "au1200-ide",
+	.id		= 0,
+	.dev = {
+		.dma_mask 		= &ide_dmamask,
+		.coherent_dma_mask	= DMA_32BIT_MASK,
+	},
+	.num_resources	= ARRAY_SIZE(db1200_ide_res),
+	.resource	= db1200_ide_res,
+};
+
+/**********************************************************************/
+
+static struct platform_device db1200_rtc_dev = {
+	.name	= "rtc-au1xxx",
+	.id	= -1,
+};
+
+/**********************************************************************/
+
+/* SD carddetects:  they're supposed to be edge-triggered, but ack
+ * doesn't seem to work (CPLD Rev 2).  Instead, the screaming one
+ * is disabled and its counterpart enabled.  The 500ms timeout is
+ * because the carddetect isn't debounced in hardware.
+ */
+static irqreturn_t db1200_mmc_cd(int irq, void *ptr)
+{
+	void(*mmc_cd)(struct mmc_host *, unsigned long);
+
+	if (irq == DB1200_SD0_INSERT_INT) {
+		disable_irq_nosync(DB1200_SD0_INSERT_INT);
+		enable_irq(DB1200_SD0_EJECT_INT);
+	} else {
+		disable_irq_nosync(DB1200_SD0_EJECT_INT);
+		enable_irq(DB1200_SD0_INSERT_INT);
+	}
+
+	/* link against CONFIG_MMC=m */
+	mmc_cd = symbol_get(mmc_detect_change);
+	if (mmc_cd) {
+		mmc_cd(ptr, msecs_to_jiffies(500));
+		symbol_put(mmc_detect_change);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int db1200_mmc_cd_setup(void *mmc_host, int en)
+{
+	int ret;
+
+	if (en) {
+		ret = request_irq(DB1200_SD0_INSERT_INT, db1200_mmc_cd,
+				  IRQF_DISABLED, "sd_insert", mmc_host);
+		if (ret)
+			goto out;
+
+		ret = request_irq(DB1200_SD0_EJECT_INT, db1200_mmc_cd,
+				  IRQF_DISABLED, "sd_eject", mmc_host);
+		if (ret) {
+			free_irq(DB1200_SD0_INSERT_INT, mmc_host);
+			goto out;
+		}
+
+		if (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT)
+			enable_irq(DB1200_SD0_EJECT_INT);
+		else
+			enable_irq(DB1200_SD0_INSERT_INT);
+
+	} else {
+		free_irq(DB1200_SD0_INSERT_INT, mmc_host);
+		free_irq(DB1200_SD0_EJECT_INT, mmc_host);
+	}
+	ret = 0;
+out:
+	return ret;
+}
+
+static void db1200_mmc_set_power(void *mmc_host, int state)
+{
+	if (state) {
+		bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
+		msleep(400);	/* stabilization time */
+	} else
+		bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
+}
+
+static int db1200_mmc_card_readonly(void *mmc_host)
+{
+	return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 1 : 0;
+}
+
+static int db1200_mmc_card_inserted(void *mmc_host)
+{
+	return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT) ? 1 : 0;
+}
+
+static void db1200_mmcled_set(struct led_classdev *led,
+			      enum led_brightness brightness)
+{
+	if (brightness != LED_OFF)
+		bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
+	else
+		bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
+}
+
+static struct led_classdev db1200_mmc_led = {
+	.brightness_set	= db1200_mmcled_set,
+};
+
+/* needed by arch/mips/alchemy/common/platform.c */
+struct au1xmmc_platform_data au1xmmc_platdata[] = {
+	[0] = {
+		.cd_setup	= db1200_mmc_cd_setup,
+		.set_power	= db1200_mmc_set_power,
+		.card_inserted	= db1200_mmc_card_inserted,
+		.card_readonly	= db1200_mmc_card_readonly,
+		.led		= &db1200_mmc_led,
+	},
+};
+
+/**********************************************************************/
+
+static struct resource au1200_psc0_res[] = {
+	[0] = {
+		.start	= PSC0_PHYS_ADDR,
+		.end	= PSC0_PHYS_ADDR + 0x000fffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AU1200_PSC0_INT,
+		.end	= AU1200_PSC0_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= DSCR_CMD0_PSC0_TX,
+		.end	= DSCR_CMD0_PSC0_TX,
+		.flags	= IORESOURCE_DMA,
+	},
+	[3] = {
+		.start	= DSCR_CMD0_PSC0_RX,
+		.end	= DSCR_CMD0_PSC0_RX,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device db1200_i2c_dev = {
+	.name		= "au1xpsc_smbus",
+	.id		= 0,	/* bus number */
+	.num_resources	= ARRAY_SIZE(au1200_psc0_res),
+	.resource	= au1200_psc0_res,
+};
+
+static void db1200_spi_cs_en(struct au1550_spi_info *spi, int cs, int pol)
+{
+	if (cs)
+		bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_SPISEL);
+	else
+		bcsr_mod(BCSR_RESETS, BCSR_RESETS_SPISEL, 0);
+}
+
+static struct au1550_spi_info db1200_spi_platdata = {
+	.mainclk_hz	= 50000000,	/* PSC0 clock */
+	.num_chipselect = 2,
+	.activate_cs	= db1200_spi_cs_en,
+};
+
+static u64 spi_dmamask = DMA_32BIT_MASK;
+
+static struct platform_device db1200_spi_dev = {
+	.dev	= {
+		.dma_mask		= &spi_dmamask,
+		.coherent_dma_mask	= DMA_32BIT_MASK,
+		.platform_data		= &db1200_spi_platdata,
+	},
+	.name		= "au1550-spi",
+	.id		= 0,	/* bus number */
+	.num_resources	= ARRAY_SIZE(au1200_psc0_res),
+	.resource	= au1200_psc0_res,
+};
+
+static struct resource au1200_psc1_res[] = {
+	[0] = {
+		.start	= PSC1_PHYS_ADDR,
+		.end	= PSC1_PHYS_ADDR + 0x000fffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AU1200_PSC1_INT,
+		.end	= AU1200_PSC1_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= DSCR_CMD0_PSC1_TX,
+		.end	= DSCR_CMD0_PSC1_TX,
+		.flags	= IORESOURCE_DMA,
+	},
+	[3] = {
+		.start	= DSCR_CMD0_PSC1_RX,
+		.end	= DSCR_CMD0_PSC1_RX,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device db1200_audio_dev = {
+	/* name assigned later based on switch setting */
+	.id		= 1,	/* PSC ID */
+	.num_resources	= ARRAY_SIZE(au1200_psc1_res),
+	.resource	= au1200_psc1_res,
+};
+
+static struct platform_device *db1200_devs[] __initdata = {
+	NULL,		/* PSC0, selected by S6.8 */
+	&db1200_ide_dev,
+	&db1200_eth_dev,
+	&db1200_rtc_dev,
+	&db1200_nand_dev,
+	&db1200_audio_dev,
+};
+
+static int __init db1200_dev_init(void)
+{
+	unsigned long pfc;
+	unsigned short sw;
+	int swapped;
+
+	i2c_register_board_info(0, db1200_i2c_devs,
+				ARRAY_SIZE(db1200_i2c_devs));
+	spi_register_board_info(db1200_spi_devs,
+				ARRAY_SIZE(db1200_i2c_devs));
+
+	/* SWITCHES:	S6.8 I2C/SPI selector  (OFF=I2C  ON=SPI)
+	 *		S6.7 AC97/I2S selector (OFF=AC97 ON=I2S)
+	 */
+
+	/* NOTE: GPIO215 controls OTG VBUS supply.  In SPI mode however
+	 * this pin is claimed by PSC0 (unused though, but pinmux doesn't
+	 * allow to free it without crippling the SPI interface).
+	 * As a result, in SPI mode, OTG simply won't work (PSC0 uses
+	 * it as an input pin which is pulled high on the boards).
+	 */
+	pfc = __raw_readl((void __iomem *)SYS_PINFUNC) & ~SYS_PINFUNC_P0A;
+
+	/* switch off OTG VBUS supply */
+	gpio_request(215, "otg-vbus");
+	gpio_direction_output(215, 1);
+
+	printk(KERN_INFO "DB1200 device configuration:\n");
+
+	sw = bcsr_read(BCSR_SWITCHES);
+	if (sw & BCSR_SWITCHES_DIP_8) {
+		db1200_devs[0] = &db1200_i2c_dev;
+		bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
+
+		pfc |= (2 << 17);	/* GPIO2 block owns GPIO215 */
+
+		printk(KERN_INFO " S6.8 OFF: PSC0 mode I2C\n");
+		printk(KERN_INFO "   OTG port VBUS supply available!\n");
+	} else {
+		db1200_devs[0] = &db1200_spi_dev;
+		bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC0MUX);
+
+		pfc |= (1 << 17);	/* PSC0 owns GPIO215 */
+
+		printk(KERN_INFO " S6.8 ON : PSC0 mode SPI\n");
+		printk(KERN_INFO "   OTG port VBUS supply disabled\n");
+	}
+	__raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
+	wmb();
+
+	/* Audio: DIP7 selects I2S(0)/AC97(1), but need I2C for I2S!
+	 * so: DIP7=1 || DIP8=0 => AC97, DIP7=0 && DIP8=1 => I2S
+	 */
+	sw &= BCSR_SWITCHES_DIP_8 | BCSR_SWITCHES_DIP_7;
+	if (sw == BCSR_SWITCHES_DIP_8) {
+		bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC1MUX);
+		db1200_audio_dev.name = "au1xpsc_i2s";
+		printk(KERN_INFO " S6.7 ON : PSC1 mode I2S\n");
+	} else {
+		bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC1MUX, 0);
+		db1200_audio_dev.name = "au1xpsc_ac97";
+		printk(KERN_INFO " S6.7 OFF: PSC1 mode AC97\n");
+	}
+
+	/* Audio PSC clock is supplied externally. (FIXME: platdata!!) */
+	__raw_writel(PSC_SEL_CLK_SERCLK,
+		(void __iomem *)KSEG1ADDR(PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
+	wmb();
+
+	db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
+				    PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+				    PCMCIA_MEM_PHYS_ADDR,
+				    PCMCIA_MEM_PHYS_ADDR  + 0x000400000 - 1,
+				    PCMCIA_IO_PHYS_ADDR,
+				    PCMCIA_IO_PHYS_ADDR   + 0x000010000 - 1,
+				    DB1200_PC0_INT,
+				    DB1200_PC0_INSERT_INT,
+				    /*DB1200_PC0_STSCHG_INT*/0,
+				    DB1200_PC0_EJECT_INT,
+				    0);
+
+	db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
+				    PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
+				    PCMCIA_MEM_PHYS_ADDR  + 0x004000000,
+				    PCMCIA_MEM_PHYS_ADDR  + 0x004400000 - 1,
+				    PCMCIA_IO_PHYS_ADDR   + 0x004000000,
+				    PCMCIA_IO_PHYS_ADDR   + 0x004010000 - 1,
+				    DB1200_PC1_INT,
+				    DB1200_PC1_INSERT_INT,
+				    /*DB1200_PC1_STSCHG_INT*/0,
+				    DB1200_PC1_EJECT_INT,
+				    1);
+
+	swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
+	db1x_register_norflash(64 << 20, 2, swapped);
+
+	return platform_add_devices(db1200_devs, ARRAY_SIZE(db1200_devs));
+}
+device_initcall(db1200_dev_init);
+
+/* au1200fb calls these: STERBT EINEN TRAGISCHEN TOD!!! */
+int board_au1200fb_panel(void)
+{
+	return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
+}
+
+int board_au1200fb_panel_init(void)
+{
+	/* Apply power */
+	bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
+				BCSR_BOARD_LCDBL);
+	return 0;
+}
+
+int board_au1200fb_panel_shutdown(void)
+{
+	/* Remove power */
+	bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
+			     BCSR_BOARD_LCDBL, 0);
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/db1200/setup.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/db1200/setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/db1200/setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/db1200/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,82 @@
+/*
+ * Alchemy/AMD/RMI DB1200 board setup.
+ *
+ * Licensed under the terms outlined in the file COPYING in the root of
+ * this source archive.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-db1x00/bcsr.h>
+#include <asm/mach-db1x00/db1200.h>
+
+const char *get_system_type(void)
+{
+	return "Alchemy Db1200";
+}
+
+void __init board_setup(void)
+{
+	unsigned long freq0, clksrc, div, pfc;
+	unsigned short whoami;
+
+	bcsr_init(DB1200_BCSR_PHYS_ADDR,
+		  DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS);
+
+	whoami = bcsr_read(BCSR_WHOAMI);
+	printk(KERN_INFO "Alchemy/AMD/RMI DB1200 Board, CPLD Rev %d"
+		"  Board-ID %d  Daughtercard ID %d\n",
+		(whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
+
+	/* SMBus/SPI on PSC0, Audio on PSC1 */
+	pfc = __raw_readl((void __iomem *)SYS_PINFUNC);
+	pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
+	pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3);
+	pfc |= SYS_PINFUNC_P1C;	/* SPI is configured later */
+	__raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
+	wmb();
+
+	/* Clock configurations: PSC0: ~50MHz via Clkgen0, derived from
+	 * CPU clock; all other clock generators off/unused.
+	 */
+	div = (get_au1x00_speed() + 25000000) / 50000000;
+	if (div & 1)
+		div++;
+	div = ((div >> 1) - 1) & 0xff;
+
+	freq0 = div << SYS_FC_FRDIV0_BIT;
+	__raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
+	wmb();
+	freq0 |= SYS_FC_FE0;	/* enable F0 */
+	__raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
+	wmb();
+
+	/* psc0_intclk comes 1:1 from F0 */
+	clksrc = SYS_CS_MUX_FQ0 << SYS_CS_ME0_BIT;
+	__raw_writel(clksrc, (void __iomem *)SYS_CLKSRC);
+	wmb();
+}
+
+static int __init db1200_arch_init(void)
+{
+	/* GPIO7 is low-level triggered CPLD cascade */
+	set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
+	bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
+
+	/* insert/eject pairs: one of both is always screaming.  To avoid
+	 * issues they must not be automatically enabled when initially
+	 * requested.
+	 */
+	irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
+	irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
+	irq_to_desc(DB1200_PC0_INSERT_INT)->status |= IRQ_NOAUTOEN;
+	irq_to_desc(DB1200_PC0_EJECT_INT)->status |= IRQ_NOAUTOEN;
+	irq_to_desc(DB1200_PC1_INSERT_INT)->status |= IRQ_NOAUTOEN;
+	irq_to_desc(DB1200_PC1_EJECT_INT)->status |= IRQ_NOAUTOEN;
+
+	return 0;
+}
+arch_initcall(db1200_arch_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/db1x00/board_setup.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/db1x00/board_setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/db1x00/board_setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/db1x00/board_setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,59 +29,139 @@
 
 #include <linux/gpio.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
 
 #include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_eth.h>
 #include <asm/mach-db1x00/db1x00.h>
+#include <asm/mach-db1x00/bcsr.h>
+#include <asm/reboot.h>
 
 #include <prom.h>
 
+#ifdef CONFIG_MIPS_DB1500
+char irq_tab_alchemy[][5] __initdata = {
+	[12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - HPT371   */
+	[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
+};
+
+#endif
 
-static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+
+#ifdef CONFIG_MIPS_DB1550
+char irq_tab_alchemy[][5] __initdata = {
+	[11] = { -1, AU1550_PCI_INTC, 0xff, 0xff, 0xff }, /* IDSEL 11 - on-board HPT371 */
+	[12] = { -1, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD, AU1550_PCI_INTA }, /* IDSEL 12 - PCI slot 2 (left) */
+	[13] = { -1, AU1550_PCI_INTA, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD }, /* IDSEL 13 - PCI slot 1 (right) */
+};
+#endif
+
+
+#ifdef CONFIG_MIPS_BOSPORUS
+char irq_tab_alchemy[][5] __initdata = {
+	[11] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 11 - miniPCI  */
+	[12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - SN1741   */
+	[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
+};
+
+/*
+ * Micrel/Kendin 5 port switch attached to MAC0,
+ * MAC0 is associated with PHY address 5 (== WAN port)
+ * MAC1 is not associated with any PHY, since it's connected directly
+ * to the switch.
+ * no interrupts are used
+ */
+static struct au1000_eth_platform_data eth0_pdata = {
+	.phy_static_config	= 1,
+	.phy_addr		= 5,
+};
+
+static void bosporus_power_off(void)
+{
+	printk(KERN_INFO "It's now safe to turn off power\n");
+	while (1)
+		asm volatile (".set mips3 ; wait ; .set mips0");
+}
 
 const char *get_system_type(void)
 {
-#ifdef CONFIG_MIPS_BOSPORUS
 	return "Alchemy Bosporus Gateway Reference";
-#else
-	return "Alchemy Db1x00";
+}
 #endif
+
+
+#ifdef CONFIG_MIPS_MIRAGE
+char irq_tab_alchemy[][5] __initdata = {
+	[11] = { -1, AU1500_PCI_INTD, 0xff, 0xff, 0xff }, /* IDSEL 11 - SMI VGX */
+	[12] = { -1, 0xff, 0xff, AU1500_PCI_INTC, 0xff }, /* IDSEL 12 - PNX1300 */
+	[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 13 - miniPCI */
+};
+
+static void mirage_power_off(void)
+{
+	alchemy_gpio_direction_output(210, 1);
 }
 
-void board_reset(void)
+const char *get_system_type(void)
 {
-	/* Hit BCSR.SW_RESET[RESET] */
-	bcsr->swreset = 0x0000;
+	return "Alchemy Mirage";
+}
+#endif
+
+
+#if defined(CONFIG_MIPS_BOSPORUS) || defined(CONFIG_MIPS_MIRAGE)
+static void mips_softreset(void)
+{
+	asm volatile ("jr\t%0" : : "r"(0xbfc00000));
 }
 
+#else
+
+const char *get_system_type(void)
+{
+	return "Alchemy Db1x00";
+}
+#endif
+
+
 void __init board_setup(void)
 {
-	u32 pin_func = 0;
-	char *argptr;
+	unsigned long bcsr1, bcsr2;
+	u32 pin_func;
 
-	argptr = prom_getcmdline();
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-	argptr = strstr(argptr, "console=");
-	if (argptr == NULL) {
-		argptr = prom_getcmdline();
-		strcat(argptr, " console=ttyS0,115200");
-	}
+	bcsr1 = DB1000_BCSR_PHYS_ADDR;
+	bcsr2 = DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS;
+
+	pin_func = 0;
+
+#ifdef CONFIG_MIPS_DB1000
+	printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n");
 #endif
+#ifdef CONFIG_MIPS_DB1500
+	printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n");
+#endif
+#ifdef CONFIG_MIPS_DB1100
+	printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n");
+#endif
+#ifdef CONFIG_MIPS_BOSPORUS
+	au1xxx_override_eth_cfg(0, &eth0_pdata);
 
-#ifdef CONFIG_FB_AU1100
-	argptr = strstr(argptr, "video=");
-	if (argptr == NULL) {
-		argptr = prom_getcmdline();
-		/* default panel */
-		/*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
-	}
+	printk(KERN_INFO "AMD Alchemy Bosporus Board\n");
 #endif
+#ifdef CONFIG_MIPS_MIRAGE
+	printk(KERN_INFO "AMD Alchemy Mirage Board\n");
+#endif
+#ifdef CONFIG_MIPS_DB1550
+	printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n");
 
-#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
-	/* au1000 does not support vra, au1500 and au1100 do */
-	strcat(argptr, " au1000_audio=vra");
-	argptr = prom_getcmdline();
+	bcsr1 = DB1550_BCSR_PHYS_ADDR;
+	bcsr2 = DB1550_BCSR_PHYS_ADDR + DB1550_BCSR_HEXLED_OFS;
 #endif
 
+	/* initialize board register space */
+	bcsr_init(bcsr1, bcsr2);
+
 	/* Not valid for Au1550 */
 #if defined(CONFIG_IRDA) && \
    (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
@@ -89,11 +169,10 @@ void __init board_setup(void)
 	pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF;
 	au_writel(pin_func, SYS_PINFUNC);
 	/* Power off until the driver is in use */
-	bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK;
-	bcsr->resets |=  BCSR_RESETS_IRDA_MODE_OFF;
-	au_sync();
+	bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK,
+				BCSR_RESETS_IRDA_MODE_OFF);
 #endif
-	bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */
+	bcsr_write(BCSR_PCMCIA, 0);	/* turn off PCMCIA power */
 
 	/* Enable GPIO[31:0] inputs */
 	alchemy_gpio1_input_enable();
@@ -120,26 +199,53 @@ void __init board_setup(void)
 	 * be part of the audio driver.
 	 */
 	alchemy_gpio_direction_output(209, 1);
-#endif
-
-	au_sync();
 
-#ifdef CONFIG_MIPS_DB1000
-	printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n");
-#endif
-#ifdef CONFIG_MIPS_DB1500
-	printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n");
-#endif
-#ifdef CONFIG_MIPS_DB1100
-	printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n");
+	pm_power_off = mirage_power_off;
+	_machine_halt = mirage_power_off;
+	_machine_restart = (void(*)(char *))mips_softreset;
 #endif
+
 #ifdef CONFIG_MIPS_BOSPORUS
-	printk(KERN_INFO "AMD Alchemy Bosporus Board\n");
-#endif
-#ifdef CONFIG_MIPS_MIRAGE
-	printk(KERN_INFO "AMD Alchemy Mirage Board\n");
+	pm_power_off = bosporus_power_off;
+	_machine_halt = bosporus_power_off;
+	_machine_restart = (void(*)(char *))mips_softreset;
 #endif
-#ifdef CONFIG_MIPS_DB1550
-	printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n");
+	au_sync();
+}
+
+static int __init db1x00_init_irq(void)
+{
+#if defined(CONFIG_MIPS_MIRAGE)
+	set_irq_type(AU1500_GPIO7_INT, IRQF_TRIGGER_RISING); /* TS pendown */
+#elif defined(CONFIG_MIPS_DB1550)
+	set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW);  /* CD0# */
+	set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW);  /* CD1# */
+	set_irq_type(AU1550_GPIO3_INT, IRQF_TRIGGER_LOW);  /* CARD0# */
+	set_irq_type(AU1550_GPIO5_INT, IRQF_TRIGGER_LOW);  /* CARD1# */
+	set_irq_type(AU1550_GPIO21_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
+	set_irq_type(AU1550_GPIO22_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
+#elif defined(CONFIG_MIPS_DB1500)
+	set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
+	set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
+	set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
+	set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
+	set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
+	set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
+#elif defined(CONFIG_MIPS_DB1100)
+	set_irq_type(AU1100_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
+	set_irq_type(AU1100_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
+	set_irq_type(AU1100_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
+	set_irq_type(AU1100_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
+	set_irq_type(AU1100_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
+	set_irq_type(AU1100_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
+#elif defined(CONFIG_MIPS_DB1000)
+	set_irq_type(AU1000_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
+	set_irq_type(AU1000_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
+	set_irq_type(AU1000_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
+	set_irq_type(AU1000_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
+	set_irq_type(AU1000_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
+	set_irq_type(AU1000_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
 #endif
+	return 0;
 }
+arch_initcall(db1x00_init_irq);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/db1x00/irqmap.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/db1x00/irqmap.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/db1x00/irqmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/db1x00/irqmap.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,90 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *	Au1xxx irq map table
- *
- * Copyright 2003 Embedded Edge, LLC
- *		dan@embeddededge.com
- *
- *  This program is free software; you can redistribute	 it and/or modify it
- *  under  the terms of	 the GNU 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.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-
-#include <asm/mach-au1x00/au1000.h>
-
-#ifdef CONFIG_MIPS_DB1500
-char irq_tab_alchemy[][5] __initdata = {
-	[12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - HPT371   */
-	[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
-};
-#endif
-
-#ifdef CONFIG_MIPS_BOSPORUS
-char irq_tab_alchemy[][5] __initdata = {
-	[11] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 11 - miniPCI  */
-	[12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - SN1741   */
-	[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
-};
-#endif
-
-#ifdef CONFIG_MIPS_MIRAGE
-char irq_tab_alchemy[][5] __initdata = {
-	[11] = { -1, INTD, INTX, INTX, INTX }, /* IDSEL 11 - SMI VGX */
-	[12] = { -1, INTX, INTX, INTC, INTX }, /* IDSEL 12 - PNX1300 */
-	[13] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 13 - miniPCI */
-};
-#endif
-
-#ifdef CONFIG_MIPS_DB1550
-char irq_tab_alchemy[][5] __initdata = {
-	[11] = { -1, INTC, INTX, INTX, INTX }, /* IDSEL 11 - on-board HPT371 */
-	[12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left) */
-	[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */
-};
-#endif
-
-
-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-
-#ifndef CONFIG_MIPS_MIRAGE
-#ifdef CONFIG_MIPS_DB1550
-	{ AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 IRQ# */
-	{ AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 IRQ# */
-#else
-	{ AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 Fully_Interted# */
-	{ AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 STSCHG# */
-	{ AU1000_GPIO_2, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 IRQ# */
-
-	{ AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 Fully_Interted# */
-	{ AU1000_GPIO_4, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 STSCHG# */
-	{ AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 IRQ# */
-#endif
-#else
-	{ AU1000_GPIO_7, IRQF_TRIGGER_RISING, 0 }, /* touchscreen pen down */
-#endif
-
-};
-
-void __init board_init_irq(void)
-{
-	au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/db1x00/Makefile linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/db1x00/Makefile
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/db1x00/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/db1x00/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,4 +5,4 @@
 # Makefile for the Alchemy Semiconductor DBAu1xx0 boards.
 #
 
-obj-y := board_setup.o irqmap.o
+obj-y := board_setup.o platform.o
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/db1x00/platform.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/db1x00/platform.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/db1x00/platform.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/db1x00/platform.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,118 @@
+/*
+ * DBAu1xxx board platform device registration
+ *
+ * Copyright (C) 2009 Manuel Lauss
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-db1x00/bcsr.h>
+#include "../platform.h"
+
+/* DB1xxx PCMCIA interrupt sources:
+ * CD0/1 	GPIO0/3
+ * STSCHG0/1	GPIO1/4
+ * CARD0/1	GPIO2/5
+ * Db1550:	0/1, 21/22, 3/5
+ */
+
+#define DB1XXX_HAS_PCMCIA
+#define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT)
+
+#if defined(CONFIG_MIPS_DB1000)
+#define DB1XXX_PCMCIA_CD0	AU1000_GPIO0_INT
+#define DB1XXX_PCMCIA_STSCHG0	AU1000_GPIO1_INT
+#define DB1XXX_PCMCIA_CARD0	AU1000_GPIO2_INT
+#define DB1XXX_PCMCIA_CD1	AU1000_GPIO3_INT
+#define DB1XXX_PCMCIA_STSCHG1	AU1000_GPIO4_INT
+#define DB1XXX_PCMCIA_CARD1	AU1000_GPIO5_INT
+#define BOARD_FLASH_SIZE	0x02000000 /* 32MB */
+#define BOARD_FLASH_WIDTH	4 /* 32-bits */
+#elif defined(CONFIG_MIPS_DB1100)
+#define DB1XXX_PCMCIA_CD0	AU1100_GPIO0_INT
+#define DB1XXX_PCMCIA_STSCHG0	AU1100_GPIO1_INT
+#define DB1XXX_PCMCIA_CARD0	AU1100_GPIO2_INT
+#define DB1XXX_PCMCIA_CD1	AU1100_GPIO3_INT
+#define DB1XXX_PCMCIA_STSCHG1	AU1100_GPIO4_INT
+#define DB1XXX_PCMCIA_CARD1	AU1100_GPIO5_INT
+#define BOARD_FLASH_SIZE	0x02000000 /* 32MB */
+#define BOARD_FLASH_WIDTH	4 /* 32-bits */
+#elif defined(CONFIG_MIPS_DB1500)
+#define DB1XXX_PCMCIA_CD0	AU1500_GPIO0_INT
+#define DB1XXX_PCMCIA_STSCHG0	AU1500_GPIO1_INT
+#define DB1XXX_PCMCIA_CARD0	AU1500_GPIO2_INT
+#define DB1XXX_PCMCIA_CD1	AU1500_GPIO3_INT
+#define DB1XXX_PCMCIA_STSCHG1	AU1500_GPIO4_INT
+#define DB1XXX_PCMCIA_CARD1	AU1500_GPIO5_INT
+#define BOARD_FLASH_SIZE	0x02000000 /* 32MB */
+#define BOARD_FLASH_WIDTH	4 /* 32-bits */
+#elif defined(CONFIG_MIPS_DB1550)
+#define DB1XXX_PCMCIA_CD0	AU1550_GPIO0_INT
+#define DB1XXX_PCMCIA_STSCHG0	AU1550_GPIO21_INT
+#define DB1XXX_PCMCIA_CARD0	AU1550_GPIO3_INT
+#define DB1XXX_PCMCIA_CD1	AU1550_GPIO1_INT
+#define DB1XXX_PCMCIA_STSCHG1	AU1550_GPIO22_INT
+#define DB1XXX_PCMCIA_CARD1	AU1550_GPIO5_INT
+#define BOARD_FLASH_SIZE	0x08000000 /* 128MB */
+#define BOARD_FLASH_WIDTH	4 /* 32-bits */
+#else
+/* other board: no PCMCIA */
+#undef DB1XXX_HAS_PCMCIA
+#undef F_SWAPPED
+#define F_SWAPPED 0
+#if defined(CONFIG_MIPS_BOSPORUS)
+#define BOARD_FLASH_SIZE	0x01000000 /* 16MB */
+#define BOARD_FLASH_WIDTH	2 /* 16-bits */
+#elif defined(CONFIG_MIPS_MIRAGE)
+#define BOARD_FLASH_SIZE	0x04000000 /* 64MB */
+#define BOARD_FLASH_WIDTH	4 /* 32-bits */
+#endif
+#endif
+
+static int __init db1xxx_dev_init(void)
+{
+#ifdef DB1XXX_HAS_PCMCIA
+	db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
+				    PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+				    PCMCIA_MEM_PHYS_ADDR,
+				    PCMCIA_MEM_PHYS_ADDR  + 0x000400000 - 1,
+				    PCMCIA_IO_PHYS_ADDR,
+				    PCMCIA_IO_PHYS_ADDR   + 0x000010000 - 1,
+				    DB1XXX_PCMCIA_CARD0,
+				    DB1XXX_PCMCIA_CD0,
+				    /*DB1XXX_PCMCIA_STSCHG0*/0,
+				    0,
+				    0);
+
+	db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
+				    PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
+				    PCMCIA_MEM_PHYS_ADDR  + 0x004000000,
+				    PCMCIA_MEM_PHYS_ADDR  + 0x004400000 - 1,
+				    PCMCIA_IO_PHYS_ADDR   + 0x004000000,
+				    PCMCIA_IO_PHYS_ADDR   + 0x004010000 - 1,
+				    DB1XXX_PCMCIA_CARD1,
+				    DB1XXX_PCMCIA_CD1,
+				    /*DB1XXX_PCMCIA_STSCHG1*/0,
+				    0,
+				    1);
+#endif
+	db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED);
+	return 0;
+}
+device_initcall(db1xxx_dev_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/Makefile linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/Makefile
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
 # Alchemy Develboards
 #
 
-obj-y += prom.o
+obj-y += prom.o bcsr.o platform.o
 obj-$(CONFIG_PM)		+= pm.o
 obj-$(CONFIG_MIPS_PB1000)	+= pb1000/
 obj-$(CONFIG_MIPS_PB1100)	+= pb1100/
@@ -11,8 +11,10 @@ obj-$(CONFIG_MIPS_PB1500)	+= pb1500/
 obj-$(CONFIG_MIPS_PB1550)	+= pb1550/
 obj-$(CONFIG_MIPS_DB1000)	+= db1x00/
 obj-$(CONFIG_MIPS_DB1100)	+= db1x00/
-obj-$(CONFIG_MIPS_DB1200)	+= pb1200/
+obj-$(CONFIG_MIPS_DB1200)	+= db1200/
 obj-$(CONFIG_MIPS_DB1500)	+= db1x00/
 obj-$(CONFIG_MIPS_DB1550)	+= db1x00/
 obj-$(CONFIG_MIPS_BOSPORUS)	+= db1x00/
 obj-$(CONFIG_MIPS_MIRAGE)	+= db1x00/
+
+EXTRA_CFLAGS += -Werror
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1000/board_setup.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1000/board_setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1000/board_setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1000/board_setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,11 +31,7 @@
 #include <asm/mach-pb1x00/pb1000.h>
 #include <prom.h>
 
-
-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-	{ AU1000_GPIO_15, IRQF_TRIGGER_LOW, 0 },
-};
-
+#include "../platform.h"
 
 const char *get_system_type(void)
 {
@@ -46,25 +42,14 @@ void board_reset(void)
 {
 }
 
-void __init board_init_irq(void)
-{
-	au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
-}
-
 void __init board_setup(void)
 {
 	u32 pin_func, static_cfg0;
 	u32 sys_freqctrl, sys_clksrc;
 	u32 prid = read_c0_prid();
 
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-	char *argptr = prom_getcmdline();
-	argptr = strstr(argptr, "console=");
-	if (argptr == NULL) {
-		argptr = prom_getcmdline();
-		strcat(argptr, " console=ttyS0,115200");
-	}
-#endif
+	sys_freqctrl = 0;
+	sys_clksrc = 0;
 
 	/* Set AUX clock to 12 MHz * 8 = 96 MHz */
 	au_writel(8, SYS_AUXPLL);
@@ -193,3 +178,16 @@ void __init board_setup(void)
 		break;
 	}
 }
+
+static int __init pb1000_init_irq(void)
+{
+	set_irq_type(AU1000_GPIO15_INT, IRQF_TRIGGER_LOW);
+	return 0;
+}
+arch_initcall(pb1000_init_irq);
+
+static int __init pb1000_device_init(void)
+{
+	return db1x_register_norflash(8 * 1024 * 1024, 4, 0);
+}
+device_initcall(pb1000_device_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1100/board_setup.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1100/board_setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1100/board_setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1100/board_setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,19 +29,11 @@
 #include <linux/interrupt.h>
 
 #include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-pb1x00/pb1100.h>
+#include <asm/mach-db1x00/bcsr.h>
 
 #include <prom.h>
 
 
-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-	{ AU1000_GPIO_9,  IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card Fully_Inserted# */
-	{ AU1000_GPIO_10, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card STSCHG# */
-	{ AU1000_GPIO_11, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card IRQ# */
-	{ AU1000_GPIO_13, IRQF_TRIGGER_LOW, 0 }, /* DC_IRQ# */
-};
-
-
 const char *get_system_type(void)
 {
 	return "Alchemy Pb1100";
@@ -49,43 +41,15 @@ const char *get_system_type(void)
 
 void board_reset(void)
 {
-	/* Hit BCSR.RST_VDDI[SOFT_RESET] */
-	au_writel(0x00000000, PB1100_RST_VDDI);
-}
-
-void __init board_init_irq(void)
-{
-	au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+	bcsr_write(BCSR_SYSTEM, 0);
 }
 
 void __init board_setup(void)
 {
 	volatile void __iomem *base = (volatile void __iomem *)0xac000000UL;
-	char *argptr;
-
-	argptr = prom_getcmdline();
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-	argptr = strstr(argptr, "console=");
-	if (argptr == NULL) {
-		argptr = prom_getcmdline();
-		strcat(argptr, " console=ttyS0,115200");
-	}
-#endif
 
-#ifdef CONFIG_FB_AU1100
-	argptr = strstr(argptr, "video=");
-	if (argptr == NULL) {
-		argptr = prom_getcmdline();
-		/* default panel */
-		/*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
-	}
-#endif
-
-#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
-	/* au1000 does not support vra, au1500 and au1100 do */
-	strcat(argptr, " au1000_audio=vra");
-	argptr = prom_getcmdline();
-#endif
+	bcsr_init(DB1000_BCSR_PHYS_ADDR,
+		  DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
 
 	/* Set AUX clock to 12 MHz * 8 = 96 MHz */
 	au_writel(8, SYS_AUXPLL);
@@ -155,3 +119,14 @@ void __init board_setup(void)
 		au_sync();
 	}
 }
+
+static int __init pb1100_init_irq(void)
+{
+	set_irq_type(AU1100_GPIO9_INT,  IRQF_TRIGGER_LOW); /* PCCD# */
+	set_irq_type(AU1100_GPIO10_INT, IRQF_TRIGGER_LOW); /* PCSTSCHG# */
+	set_irq_type(AU1100_GPIO11_INT, IRQF_TRIGGER_LOW); /* PCCard# */
+	set_irq_type(AU1100_GPIO13_INT, IRQF_TRIGGER_LOW); /* DC_IRQ# */
+
+	return 0;
+}
+arch_initcall(pb1100_init_irq);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1100/Makefile linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1100/Makefile
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1100/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1100/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,4 +5,4 @@
 # Makefile for the Alchemy Semiconductor Pb1100 board.
 #
 
-obj-y := board_setup.o
+obj-y := board_setup.o platform.o
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1100/platform.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1100/platform.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1100/platform.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1100/platform.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,50 @@
+/*
+ * Pb1100 board platform device registration
+ *
+ * Copyright (C) 2009 Manuel Lauss
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/init.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+#include "../platform.h"
+
+static int __init pb1100_dev_init(void)
+{
+	int swapped;
+
+	/* PCMCIA. single socket, identical to Pb1500 */
+	db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
+				    PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+				    PCMCIA_MEM_PHYS_ADDR,
+				    PCMCIA_MEM_PHYS_ADDR  + 0x000400000 - 1,
+				    PCMCIA_IO_PHYS_ADDR,
+				    PCMCIA_IO_PHYS_ADDR   + 0x000010000 - 1,
+				    AU1100_GPIO11_INT,	 /* card */
+				    AU1100_GPIO9_INT,	 /* insert */
+				    /*AU1100_GPIO10_INT*/0, /* stschg */
+				    0,			 /* eject */
+				    0);			 /* id */
+
+	swapped = bcsr_read(BCSR_STATUS) &  BCSR_STATUS_DB1000_SWAPBOOT;
+	db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
+
+	return 0;
+}
+device_initcall(pb1100_dev_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1200/board_setup.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1200/board_setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1200/board_setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1200/board_setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,11 +25,23 @@
  */
 
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/sched.h>
 
-#include <prom.h>
-#include <au1xxx.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+#ifdef CONFIG_MIPS_PB1200
+#include <asm/mach-pb1x00/pb1200.h>
+#endif
+
+#ifdef CONFIG_MIPS_DB1200
+#include <asm/mach-db1x00/db1200.h>
+#define PB1200_INT_BEGIN DB1200_INT_BEGIN
+#define PB1200_INT_END DB1200_INT_END
+#endif
 
+#include <prom.h>
 
 const char *get_system_type(void)
 {
@@ -38,25 +50,15 @@ const char *get_system_type(void)
 
 void board_reset(void)
 {
-	bcsr->resets = 0;
-	bcsr->system = 0;
+	bcsr_write(BCSR_RESETS, 0);
+	bcsr_write(BCSR_SYSTEM, 0);
 }
 
 void __init board_setup(void)
 {
-	char *argptr;
-
-	argptr = prom_getcmdline();
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-	argptr = strstr(argptr, "console=");
-	if (argptr == NULL) {
-		argptr = prom_getcmdline();
-		strcat(argptr, " console=ttyS0,115200");
-	}
-#endif
-#ifdef CONFIG_FB_AU1200
-	strcat(argptr, " video=au1200fb:panel:bs");
-#endif
+	printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
+	bcsr_init(PB1200_BCSR_PHYS_ADDR,
+		  PB1200_BCSR_PHYS_ADDR + PB1200_BCSR_HEXLED_OFS);
 
 #if 0
 	{
@@ -82,7 +84,7 @@ void __init board_setup(void)
 		u32 pin_func;
 
 		/* Select SMBus in CPLD */
-		bcsr->resets &= ~BCSR_RESETS_PCS0MUX;
+		bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
 
 		pin_func = au_readl(SYS_PINFUNC);
 		au_sync();
@@ -116,38 +118,54 @@ void __init board_setup(void)
 
 	/*
 	 * The Pb1200 development board uses external MUX for PSC0 to
-	 * support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
+	 * support SMB/SPI. bcsr_resets bit 12: 0=SMB 1=SPI
 	 */
 #ifdef CONFIG_I2C_AU1550
-	bcsr->resets &= ~BCSR_RESETS_PCS0MUX;
+	bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
 #endif
 	au_sync();
+}
 
-#ifdef CONFIG_MIPS_PB1200
-	printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
-#endif
-#ifdef CONFIG_MIPS_DB1200
-	printk(KERN_INFO "AMD Alchemy Db1200 Board\n");
-#endif
+static int __init pb1200_init_irq(void)
+{
+	/* We have a problem with CPLD rev 3. */
+	if (BCSR_WHOAMI_CPLD(bcsr_read(BCSR_WHOAMI)) <= 3) {
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "Pb1200 must be at CPLD rev 4. Please have Pb1200\n");
+		printk(KERN_ERR "updated to latest revision. This software will\n");
+		printk(KERN_ERR "not work on anything less than CPLD rev 4.\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		panic("Game over.  Your score is 0.");
+	}
+
+	set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
+	bcsr_init_irq(PB1200_INT_BEGIN, PB1200_INT_END, AU1200_GPIO7_INT);
+
+	return 0;
 }
+arch_initcall(pb1200_init_irq);
+
 
 int board_au1200fb_panel(void)
 {
-	BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
-	int p;
-
-	p = bcsr->switches;
-	p >>= 8;
-	p &= 0x0F;
-	return p;
+	return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
 }
 
 int board_au1200fb_panel_init(void)
 {
 	/* Apply power */
-	BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
-
-	bcsr->board |= BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL;
+	bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
+				BCSR_BOARD_LCDBL);
 	/* printk(KERN_DEBUG "board_au1200fb_panel_init()\n"); */
 	return 0;
 }
@@ -155,10 +173,8 @@ int board_au1200fb_panel_init(void)
 int board_au1200fb_panel_shutdown(void)
 {
 	/* Remove power */
-	BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
-
-	bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
-			 BCSR_BOARD_LCDBL);
+	bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
+			     BCSR_BOARD_LCDBL, 0);
 	/* printk(KERN_DEBUG "board_au1200fb_panel_shutdown()\n"); */
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1200/irqmap.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1200/irqmap.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1200/irqmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1200/irqmap.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,134 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *	Au1xxx irq map table
- *
- *  This program is free software; you can redistribute	 it and/or modify it
- *  under  the terms of	 the GNU 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.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-
-#include <asm/mach-au1x00/au1000.h>
-
-#ifdef CONFIG_MIPS_PB1200
-#include <asm/mach-pb1x00/pb1200.h>
-#endif
-
-#ifdef CONFIG_MIPS_DB1200
-#include <asm/mach-db1x00/db1200.h>
-#define PB1200_INT_BEGIN DB1200_INT_BEGIN
-#define PB1200_INT_END DB1200_INT_END
-#endif
-
-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-	/* This is external interrupt cascade */
-	{ AU1000_GPIO_7, IRQF_TRIGGER_LOW, 0 },
-};
-
-
-/*
- * Support for External interrupts on the Pb1200 Development platform.
- */
-
-static void pb1200_cascade_handler(unsigned int irq, struct irq_desc *d)
-{
-	unsigned short bisr = bcsr->int_status;
-
-	for ( ; bisr; bisr &= bisr - 1)
-		generic_handle_irq(PB1200_INT_BEGIN + __ffs(bisr));
-}
-
-/* NOTE: both the enable and mask bits must be cleared, otherwise the
- * CPLD generates tons of spurious interrupts (at least on the DB1200).
- */
-static void pb1200_mask_irq(unsigned int irq_nr)
-{
-	bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
-	bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN);
-	au_sync();
-}
-
-static void pb1200_maskack_irq(unsigned int irq_nr)
-{
-	bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
-	bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN);
-	bcsr->int_status = 1 << (irq_nr - PB1200_INT_BEGIN);	/* ack */
-	au_sync();
-}
-
-static void pb1200_unmask_irq(unsigned int irq_nr)
-{
-	bcsr->intset = 1 << (irq_nr - PB1200_INT_BEGIN);
-	bcsr->intset_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
-	au_sync();
-}
-
-static struct irq_chip pb1200_cpld_irq_type = {
-#ifdef CONFIG_MIPS_PB1200
-	.name = "Pb1200 Ext",
-#endif
-#ifdef CONFIG_MIPS_DB1200
-	.name = "Db1200 Ext",
-#endif
-	.mask		= pb1200_mask_irq,
-	.mask_ack	= pb1200_maskack_irq,
-	.unmask		= pb1200_unmask_irq,
-};
-
-void __init board_init_irq(void)
-{
-	unsigned int irq;
-
-	au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
-
-#ifdef CONFIG_MIPS_PB1200
-	/* We have a problem with CPLD rev 3. */
-	if (((bcsr->whoami & BCSR_WHOAMI_CPLD) >> 4) <= 3) {
-		printk(KERN_ERR "WARNING!!!\n");
-		printk(KERN_ERR "WARNING!!!\n");
-		printk(KERN_ERR "WARNING!!!\n");
-		printk(KERN_ERR "WARNING!!!\n");
-		printk(KERN_ERR "WARNING!!!\n");
-		printk(KERN_ERR "WARNING!!!\n");
-		printk(KERN_ERR "Pb1200 must be at CPLD rev 4. Please have Pb1200\n");
-		printk(KERN_ERR "updated to latest revision. This software will\n");
-		printk(KERN_ERR "not work on anything less than CPLD rev 4.\n");
-		printk(KERN_ERR "WARNING!!!\n");
-		printk(KERN_ERR "WARNING!!!\n");
-		printk(KERN_ERR "WARNING!!!\n");
-		printk(KERN_ERR "WARNING!!!\n");
-		printk(KERN_ERR "WARNING!!!\n");
-		printk(KERN_ERR "WARNING!!!\n");
-		panic("Game over.  Your score is 0.");
-	}
-#endif
-	/* mask & disable & ack all */
-	bcsr->intclr_mask = 0xffff;
-	bcsr->intclr = 0xffff;
-	bcsr->int_status = 0xffff;
-	au_sync();
-
-	for (irq = PB1200_INT_BEGIN; irq <= PB1200_INT_END; irq++)
-		set_irq_chip_and_handler_name(irq, &pb1200_cpld_irq_type,
-					 handle_level_irq, "level");
-
-	set_irq_chained_handler(AU1000_GPIO_7, pb1200_cascade_handler);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1200/Makefile linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1200/Makefile
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1200/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1200/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,6 @@
 # Makefile for the Alchemy Semiconductor Pb1200/DBAu1200 boards.
 #
 
-obj-y := board_setup.o irqmap.o platform.o
+obj-y := board_setup.o platform.o
 
 EXTRA_CFLAGS += -Werror
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1200/platform.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1200/platform.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1200/platform.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1200/platform.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,27 +26,30 @@
 
 #include <asm/mach-au1x00/au1xxx.h>
 #include <asm/mach-au1x00/au1100_mmc.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+#include "../platform.h"
 
 static int mmc_activity;
 
 static void pb1200mmc0_set_power(void *mmc_host, int state)
 {
 	if (state)
-		bcsr->board |= BCSR_BOARD_SD0PWR;
+		bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
 	else
-		bcsr->board &= ~BCSR_BOARD_SD0PWR;
+		bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
 
-	au_sync_delay(1);
+	msleep(1);
 }
 
 static int pb1200mmc0_card_readonly(void *mmc_host)
 {
-	return (bcsr->status & BCSR_STATUS_SD0WP) ? 1 : 0;
+	return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 1 : 0;
 }
 
 static int pb1200mmc0_card_inserted(void *mmc_host)
 {
-	return (bcsr->sig_status & BCSR_INT_SD0INSERT) ? 1 : 0;
+	return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT) ? 1 : 0;
 }
 
 static void pb1200_mmcled_set(struct led_classdev *led,
@@ -54,10 +57,10 @@ static void pb1200_mmcled_set(struct led
 {
 	if (brightness != LED_OFF) {
 		if (++mmc_activity == 1)
-			bcsr->disk_leds &= ~(1 << 8);
+			bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
 	} else {
 		if (--mmc_activity == 0)
-			bcsr->disk_leds |= (1 << 8);
+			bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
 	}
 }
 
@@ -65,27 +68,25 @@ static struct led_classdev pb1200mmc_led
 	.brightness_set	= pb1200_mmcled_set,
 };
 
-#ifndef CONFIG_MIPS_DB1200
 static void pb1200mmc1_set_power(void *mmc_host, int state)
 {
 	if (state)
-		bcsr->board |= BCSR_BOARD_SD1PWR;
+		bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR);
 	else
-		bcsr->board &= ~BCSR_BOARD_SD1PWR;
+		bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0);
 
-	au_sync_delay(1);
+	msleep(1);
 }
 
 static int pb1200mmc1_card_readonly(void *mmc_host)
 {
-	return (bcsr->status & BCSR_STATUS_SD1WP) ? 1 : 0;
+	return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD1WP) ? 1 : 0;
 }
 
 static int pb1200mmc1_card_inserted(void *mmc_host)
 {
-	return (bcsr->sig_status & BCSR_INT_SD1INSERT) ? 1 : 0;
+	return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) ? 1 : 0;
 }
-#endif
 
 const struct au1xmmc_platform_data au1xmmc_platdata[2] = {
 	[0] = {
@@ -95,7 +96,6 @@ const struct au1xmmc_platform_data au1xm
 		.cd_setup	= NULL,		/* use poll-timer in driver */
 		.led		= &pb1200mmc_led,
 	},
-#ifndef CONFIG_MIPS_DB1200
 	[1] = {
 		.set_power	= pb1200mmc1_set_power,
 		.card_inserted	= pb1200mmc1_card_inserted,
@@ -103,7 +103,6 @@ const struct au1xmmc_platform_data au1xm
 		.cd_setup	= NULL,		/* use poll-timer in driver */
 		.led		= &pb1200mmc_led,
 	},
-#endif
 };
 
 static struct resource ide_resources[] = {
@@ -169,8 +168,36 @@ static struct platform_device *board_pla
 
 static int __init board_register_devices(void)
 {
+	int swapped;
+
+	db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
+				    PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+				    PCMCIA_MEM_PHYS_ADDR,
+				    PCMCIA_MEM_PHYS_ADDR  + 0x000400000 - 1,
+				    PCMCIA_IO_PHYS_ADDR,
+				    PCMCIA_IO_PHYS_ADDR   + 0x000010000 - 1,
+				    PB1200_PC0_INT,
+				    PB1200_PC0_INSERT_INT,
+				    /*PB1200_PC0_STSCHG_INT*/0,
+				    PB1200_PC0_EJECT_INT,
+				    0);
+
+	db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x008000000,
+				    PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1,
+				    PCMCIA_MEM_PHYS_ADDR  + 0x008000000,
+				    PCMCIA_MEM_PHYS_ADDR  + 0x008400000 - 1,
+				    PCMCIA_IO_PHYS_ADDR   + 0x008000000,
+				    PCMCIA_IO_PHYS_ADDR   + 0x008010000 - 1,
+				    PB1200_PC1_INT,
+				    PB1200_PC1_INSERT_INT,
+				    /*PB1200_PC1_STSCHG_INT*/0,
+				    PB1200_PC1_EJECT_INT,
+				    1);
+
+	swapped = bcsr_read(BCSR_STATUS) &  BCSR_STATUS_DB1200_SWAPBOOT;
+	db1x_register_norflash(128 * 1024 * 1024, 2, swapped);
+
 	return platform_add_devices(board_platform_devices,
 				    ARRAY_SIZE(board_platform_devices));
 }
-
-arch_initcall(board_register_devices);
+device_initcall(board_register_devices);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1500/board_setup.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1500/board_setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1500/board_setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1500/board_setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,22 +29,14 @@
 #include <linux/interrupt.h>
 
 #include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-pb1x00/pb1500.h>
+#include <asm/mach-db1x00/bcsr.h>
 
 #include <prom.h>
 
 
 char irq_tab_alchemy[][5] __initdata = {
-	[12] = { -1, INTA, INTX, INTX, INTX },   /* IDSEL 12 - HPT370	*/
-	[13] = { -1, INTA, INTB, INTC, INTD },   /* IDSEL 13 - PCI slot */
-};
-
-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-	{ AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 },
-	{ AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 },
-	{ AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 },
-	{ AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 },
-	{ AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 },
+	[12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff },   /* IDSEL 12 - HPT370	*/
+	[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD },   /* IDSEL 13 - PCI slot */
 };
 
 
@@ -55,35 +47,16 @@ const char *get_system_type(void)
 
 void board_reset(void)
 {
-	/* Hit BCSR.RST_VDDI[SOFT_RESET] */
-	au_writel(0x00000000, PB1500_RST_VDDI);
-}
-
-void __init board_init_irq(void)
-{
-	au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+	bcsr_write(BCSR_SYSTEM, 0);
 }
 
 void __init board_setup(void)
 {
 	u32 pin_func;
 	u32 sys_freqctrl, sys_clksrc;
-	char *argptr;
-
-	argptr = prom_getcmdline();
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-	argptr = strstr(argptr, "console=");
-	if (argptr == NULL) {
-		argptr = prom_getcmdline();
-		strcat(argptr, " console=ttyS0,115200");
-	}
-#endif
 
-#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
-	/* au1000 does not support vra, au1500 and au1100 do */
-	strcat(argptr, " au1000_audio=vra");
-	argptr = prom_getcmdline();
-#endif
+	bcsr_init(DB1000_BCSR_PHYS_ADDR,
+		  DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
 
 	sys_clksrc = sys_freqctrl = pin_func = 0;
 	/* Set AUX clock to 12 MHz * 8 = 96 MHz */
@@ -163,3 +136,18 @@ void __init board_setup(void)
 		au_sync();
 	}
 }
+
+static int __init pb1500_init_irq(void)
+{
+	set_irq_type(AU1500_GPIO9_INT, IRQF_TRIGGER_LOW);   /* CD0# */
+	set_irq_type(AU1500_GPIO10_INT, IRQF_TRIGGER_LOW);  /* CARD0 */
+	set_irq_type(AU1500_GPIO11_INT, IRQF_TRIGGER_LOW);  /* STSCHG0# */
+	set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
+	set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
+
+	return 0;
+}
+arch_initcall(pb1500_init_irq);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1500/Makefile linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1500/Makefile
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1500/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1500/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,4 +5,4 @@
 # Makefile for the Alchemy Semiconductor Pb1500 board.
 #
 
-obj-y := board_setup.o
+obj-y := board_setup.o platform.o
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1500/platform.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1500/platform.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1500/platform.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1500/platform.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,49 @@
+/*
+ * Pb1500 board platform device registration
+ *
+ * Copyright (C) 2009 Manuel Lauss
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/init.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+#include "../platform.h"
+
+static int __init pb1500_dev_init(void)
+{
+	int swapped;
+
+	/* PCMCIA. single socket, identical to Pb1500 */
+	db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
+				    PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+				    PCMCIA_MEM_PHYS_ADDR,
+				    PCMCIA_MEM_PHYS_ADDR  + 0x000400000 - 1,
+				    PCMCIA_IO_PHYS_ADDR,
+				    PCMCIA_IO_PHYS_ADDR   + 0x000010000 - 1,
+				    AU1500_GPIO11_INT,	 /* card */
+				    AU1500_GPIO9_INT,	 /* insert */
+				    /*AU1500_GPIO10_INT*/0, /* stschg */
+				    0,			 /* eject */
+				    0);			 /* id */
+
+	swapped = bcsr_read(BCSR_STATUS) &  BCSR_STATUS_DB1000_SWAPBOOT;
+	db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
+
+	return 0;
+}
+device_initcall(pb1500_dev_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1550/board_setup.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1550/board_setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1550/board_setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1550/board_setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,18 +32,15 @@
 
 #include <asm/mach-au1x00/au1000.h>
 #include <asm/mach-pb1x00/pb1550.h>
+#include <asm/mach-db1x00/bcsr.h>
+#include <asm/mach-au1x00/gpio.h>
 
 #include <prom.h>
 
 
 char irq_tab_alchemy[][5] __initdata = {
-	[12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left)  */
-	[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */
-};
-
-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-	{ AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 },
-	{ AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 },
+	[12] = { -1, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD, AU1550_PCI_INTA }, /* IDSEL 12 - PCI slot 2 (left)  */
+	[13] = { -1, AU1550_PCI_INTA, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD }, /* IDSEL 13 - PCI slot 1 (right) */
 };
 
 const char *get_system_type(void)
@@ -53,28 +50,17 @@ const char *get_system_type(void)
 
 void board_reset(void)
 {
-	/* Hit BCSR.SYSTEM[RESET] */
-	au_writew(au_readw(0xAF00001C) & ~BCSR_SYSTEM_RESET, 0xAF00001C);
-}
-
-void __init board_init_irq(void)
-{
-	au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+	bcsr_write(BCSR_SYSTEM, 0);
 }
 
 void __init board_setup(void)
 {
 	u32 pin_func;
 
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-	char *argptr;
-	argptr = prom_getcmdline();
-	argptr = strstr(argptr, "console=");
-	if (argptr == NULL) {
-		argptr = prom_getcmdline();
-		strcat(argptr, " console=ttyS0,115200");
-	}
-#endif
+	bcsr_init(PB1550_BCSR_PHYS_ADDR,
+		  PB1550_BCSR_PHYS_ADDR + PB1550_BCSR_HEXLED_OFS);
+
+	alchemy_gpio2_enable();
 
 	/*
 	 * Enable PSC1 SYNC for AC'97.  Normaly done in audio driver,
@@ -85,8 +71,21 @@ void __init board_setup(void)
 	pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
 	au_writel(pin_func, SYS_PINFUNC);
 
-	au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */
-	au_sync();
+	bcsr_write(BCSR_PCMCIA, 0);	/* turn off PCMCIA power */
 
 	printk(KERN_INFO "AMD Alchemy Pb1550 Board\n");
 }
+
+static int __init pb1550_init_irq(void)
+{
+	set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1550_GPIO201_205_INT, IRQF_TRIGGER_HIGH);
+
+	/* enable both PCMCIA card irqs in the shared line */
+	alchemy_gpio2_enable_int(201);
+	alchemy_gpio2_enable_int(202);
+
+	return 0;
+}
+arch_initcall(pb1550_init_irq);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1550/Makefile linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1550/Makefile
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1550/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1550/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,4 +5,4 @@
 # Makefile for the Alchemy Semiconductor Pb1550 board.
 #
 
-obj-y := board_setup.o
+obj-y := board_setup.o platform.o
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1550/platform.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1550/platform.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pb1550/platform.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pb1550/platform.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,69 @@
+/*
+ * Pb1550 board platform device registration
+ *
+ * Copyright (C) 2009 Manuel Lauss
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/init.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-pb1x00/pb1550.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+#include "../platform.h"
+
+static int __init pb1550_dev_init(void)
+{
+	int swapped;
+
+	/* Pb1550, like all others, also has statuschange irqs; however they're
+	* wired up on one of the Au1550's shared GPIO201_205 line, which also
+	* services the PCMCIA card interrupts.  So we ignore statuschange and
+	* use the GPIO201_205 exclusively for card interrupts, since a) pcmcia
+	* drivers are used to shared irqs and b) statuschange isn't really use-
+	* ful anyway.
+	*/
+	db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
+				    PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+				    PCMCIA_MEM_PHYS_ADDR,
+				    PCMCIA_MEM_PHYS_ADDR  + 0x000400000 - 1,
+				    PCMCIA_IO_PHYS_ADDR,
+				    PCMCIA_IO_PHYS_ADDR   + 0x000010000 - 1,
+				    AU1550_GPIO201_205_INT,
+				    AU1550_GPIO0_INT,
+				    0,
+				    0,
+				    0);
+
+	db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x008000000,
+				    PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1,
+				    PCMCIA_MEM_PHYS_ADDR  + 0x008000000,
+				    PCMCIA_MEM_PHYS_ADDR  + 0x008400000 - 1,
+				    PCMCIA_IO_PHYS_ADDR   + 0x008000000,
+				    PCMCIA_IO_PHYS_ADDR   + 0x008010000 - 1,
+				    AU1550_GPIO201_205_INT,
+				    AU1550_GPIO1_INT,
+				    0,
+				    0,
+				    1);
+
+	swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_PB1550_SWAPBOOT;
+	db1x_register_norflash(128 * 1024 * 1024, 4, swapped);
+
+	return 0;
+}
+device_initcall(pb1550_dev_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/platform.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/platform.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/platform.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/platform.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,222 @@
+/*
+ * devoard misc stuff.
+ */
+
+#include <linux/init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/physmap.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+static void db1x_power_off(void)
+{
+	bcsr_write(BCSR_RESETS, 0);
+	bcsr_write(BCSR_SYSTEM, BCSR_SYSTEM_PWROFF | BCSR_SYSTEM_RESET);
+}
+
+static void db1x_reset(char *c)
+{
+	bcsr_write(BCSR_RESETS, 0);
+	bcsr_write(BCSR_SYSTEM, 0);
+}
+
+static int __init db1x_poweroff_setup(void)
+{
+	if (!pm_power_off)
+		pm_power_off = db1x_power_off;
+	if (!_machine_halt)
+		_machine_halt = db1x_power_off;
+	if (!_machine_restart)
+		_machine_restart = db1x_reset;
+
+	return 0;
+}
+late_initcall(db1x_poweroff_setup);
+
+/* register a pcmcia socket */
+int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start,
+				       phys_addr_t pcmcia_attr_end,
+				       phys_addr_t pcmcia_mem_start,
+				       phys_addr_t pcmcia_mem_end,
+				       phys_addr_t pcmcia_io_start,
+				       phys_addr_t pcmcia_io_end,
+				       int card_irq,
+				       int cd_irq,
+				       int stschg_irq,
+				       int eject_irq,
+				       int id)
+{
+	int cnt, i, ret;
+	struct resource *sr;
+	struct platform_device *pd;
+
+	cnt = 5;
+	if (eject_irq)
+		cnt++;
+	if (stschg_irq)
+		cnt++;
+
+	sr = kzalloc(sizeof(struct resource) * cnt, GFP_KERNEL);
+	if (!sr)
+		return -ENOMEM;
+
+	pd = platform_device_alloc("db1xxx_pcmcia", id);
+	if (!pd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	sr[0].name	= "pcmcia-attr";
+	sr[0].flags	= IORESOURCE_MEM;
+	sr[0].start	= pcmcia_attr_start;
+	sr[0].end	= pcmcia_attr_end;
+
+	sr[1].name	= "pcmcia-mem";
+	sr[1].flags	= IORESOURCE_MEM;
+	sr[1].start	= pcmcia_mem_start;
+	sr[1].end	= pcmcia_mem_end;
+
+	sr[2].name	= "pcmcia-io";
+	sr[2].flags	= IORESOURCE_MEM;
+	sr[2].start	= pcmcia_io_start;
+	sr[2].end	= pcmcia_io_end;
+
+	sr[3].name	= "insert";
+	sr[3].flags	= IORESOURCE_IRQ;
+	sr[3].start = sr[3].end = cd_irq;
+
+	sr[4].name	= "card";
+	sr[4].flags	= IORESOURCE_IRQ;
+	sr[4].start = sr[4].end = card_irq;
+
+	i = 5;
+	if (stschg_irq) {
+		sr[i].name	= "stschg";
+		sr[i].flags	= IORESOURCE_IRQ;
+		sr[i].start = sr[i].end = stschg_irq;
+		i++;
+	}
+	if (eject_irq) {
+		sr[i].name	= "eject";
+		sr[i].flags	= IORESOURCE_IRQ;
+		sr[i].start = sr[i].end = eject_irq;
+	}
+
+	pd->resource = sr;
+	pd->num_resources = cnt;
+
+	ret = platform_device_add(pd);
+	if (!ret)
+		return 0;
+
+	platform_device_put(pd);
+out:
+	kfree(sr);
+	return ret;
+}
+
+#define YAMON_SIZE	0x00100000
+#define YAMON_ENV_SIZE	0x00040000
+
+int __init db1x_register_norflash(unsigned long size, int width,
+				  int swapped)
+{
+	struct physmap_flash_data *pfd;
+	struct platform_device *pd;
+	struct mtd_partition *parts;
+	struct resource *res;
+	int ret, i;
+
+	if (size < (8 * 1024 * 1024))
+		return -EINVAL;
+
+	ret = -ENOMEM;
+	parts = kzalloc(sizeof(struct mtd_partition) * 5, GFP_KERNEL);
+	if (!parts)
+		goto out;
+
+	res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+	if (!res)
+		goto out1;
+
+	pfd = kzalloc(sizeof(struct physmap_flash_data), GFP_KERNEL);
+	if (!pfd)
+		goto out2;
+
+	pd = platform_device_alloc("physmap-flash", 0);
+	if (!pd)
+		goto out3;
+
+	/* NOR flash ends at 0x20000000, regardless of size */
+	res->start = 0x20000000 - size;
+	res->end = 0x20000000 - 1;
+	res->flags = IORESOURCE_MEM;
+
+	/* partition setup.  Most Develboards have a switch which allows
+	 * to swap the physical locations of the 2 NOR flash banks.
+	 */
+	i = 0;
+	if (!swapped) {
+		/* first NOR chip */
+		parts[i].offset = 0;
+		parts[i].name = "User FS";
+		parts[i].size = size / 2;
+		i++;
+	}
+
+	parts[i].offset = MTDPART_OFS_APPEND;
+	parts[i].name = "User FS 2";
+	parts[i].size = (size / 2) - (0x20000000 - 0x1fc00000);
+	i++;
+
+	parts[i].offset = MTDPART_OFS_APPEND;
+	parts[i].name = "YAMON";
+	parts[i].size = YAMON_SIZE;
+	parts[i].mask_flags = MTD_WRITEABLE;
+	i++;
+
+	parts[i].offset = MTDPART_OFS_APPEND;
+	parts[i].name = "raw kernel";
+	parts[i].size = 0x00400000 - YAMON_SIZE - YAMON_ENV_SIZE;
+	i++;
+
+	parts[i].offset = MTDPART_OFS_APPEND;
+	parts[i].name = "YAMON Env";
+	parts[i].size = YAMON_ENV_SIZE;
+	parts[i].mask_flags = MTD_WRITEABLE;
+	i++;
+
+	if (swapped) {
+		parts[i].offset = MTDPART_OFS_APPEND;
+		parts[i].name = "User FS";
+		parts[i].size = size / 2;
+		i++;
+	}
+
+	pfd->width = width;
+	pfd->parts = parts;
+	pfd->nr_parts = 5;
+
+	pd->dev.platform_data = pfd;
+	pd->resource = res;
+	pd->num_resources = 1;
+
+	ret = platform_device_add(pd);
+	if (!ret)
+		return ret;
+
+	platform_device_put(pd);
+out3:
+	kfree(pfd);
+out2:
+	kfree(res);
+out1:
+	kfree(parts);
+out:
+	return ret;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/platform.h linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/platform.h
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/platform.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/platform.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,21 @@
+#ifndef _DEVBOARD_PLATFORM_H_
+#define _DEVBOARD_PLATFORM_H_
+
+#include <linux/init.h>
+
+int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start,
+				       phys_addr_t pcmcia_attr_len,
+				       phys_addr_t pcmcia_mem_start,
+				       phys_addr_t pcmcia_mem_end,
+				       phys_addr_t pcmcia_io_start,
+				       phys_addr_t pcmcia_io_end,
+				       int card_irq,
+				       int cd_irq,
+				       int stschg_irq,
+				       int eject_irq,
+				       int id);
+
+int __init db1x_register_norflash(unsigned long size, int width,
+				  int swapped);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pm.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pm.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/pm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/sysfs.h>
 #include <asm/mach-au1x00/au1000.h>
 #include <asm/mach-au1x00/gpio.h>
+#include <asm/mach-db1x00/bcsr.h>
 
 /*
  * Generic suspend userspace interface for Alchemy development boards.
@@ -26,6 +27,20 @@ static unsigned long db1x_pm_last_wakesr
 
 static int db1x_pm_enter(suspend_state_t state)
 {
+	unsigned short bcsrs[16];
+	int i, j, hasint;
+
+	/* save CPLD regs */
+	hasint = bcsr_read(BCSR_WHOAMI);
+	hasint = BCSR_WHOAMI_BOARD(hasint) >= BCSR_WHOAMI_DB1200;
+	j = (hasint) ? BCSR_MASKSET : BCSR_SYSTEM;
+
+	for (i = BCSR_STATUS; i <= j; i++)
+		bcsrs[i] = bcsr_read(i);
+
+	/* shut off hexleds */
+	bcsr_write(BCSR_HEXCLEAR, 3);
+
 	/* enable GPIO based wakeup */
 	alchemy_gpio1_input_enable();
 
@@ -52,6 +67,23 @@ static int db1x_pm_enter(suspend_state_t
 	/* ...and now the sandman can come! */
 	au_sleep();
 
+
+	/* restore CPLD regs */
+	for (i = BCSR_STATUS; i <= BCSR_SYSTEM; i++)
+		bcsr_write(i, bcsrs[i]);
+
+	/* restore CPLD int registers */
+	if (hasint) {
+		bcsr_write(BCSR_INTCLR, 0xffff);
+		bcsr_write(BCSR_MASKCLR, 0xffff);
+		bcsr_write(BCSR_INTSTAT, 0xffff);
+		bcsr_write(BCSR_INTSET, bcsrs[BCSR_INTSET]);
+		bcsr_write(BCSR_MASKSET, bcsrs[BCSR_MASKSET]);
+	}
+
+	/* light up hexleds */
+	bcsr_write(BCSR_HEXCLEAR, 0);
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/prom.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/prom.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/devboards/prom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/devboards/prom.c	2010-05-16 17:17:36.000000000 -0400
@@ -60,3 +60,8 @@ void __init prom_init(void)
 		strict_strtoul(memsize_str, 0, &memsize);
 	add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
+
+void prom_putchar(unsigned char c)
+{
+    alchemy_uart_putchar(UART0_PHYS_ADDR, c);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/Kconfig linux-libre-2.6.34-gnu1/arch/mips/alchemy/Kconfig
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
-# au1000-style gpio
-config ALCHEMY_GPIO_AU1000
+# au1000-style gpio and interrupt controllers
+config ALCHEMY_GPIOINT_AU1000
 	bool
 
 # select this in your board config if you don't want to use the gpio
@@ -20,12 +20,14 @@ config MIPS_MTX1
 	select HW_HAS_PCI
 	select SOC_AU1500
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
 
 config MIPS_BOSPORUS
 	bool "Alchemy Bosporus board"
 	select SOC_AU1500
 	select DMA_NONCOHERENT
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
 
 config MIPS_DB1000
 	bool "Alchemy DB1000 board"
@@ -33,12 +35,14 @@ config MIPS_DB1000
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
 
 config MIPS_DB1100
 	bool "Alchemy DB1100 board"
 	select SOC_AU1100
 	select DMA_NONCOHERENT
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
 
 config MIPS_DB1200
 	bool "Alchemy DB1200 board"
@@ -46,6 +50,7 @@ config MIPS_DB1200
 	select DMA_COHERENT
 	select MIPS_DISABLE_OBSOLETE_IDE
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
 
 config MIPS_DB1500
 	bool "Alchemy DB1500 board"
@@ -55,6 +60,7 @@ config MIPS_DB1500
 	select MIPS_DISABLE_OBSOLETE_IDE
 	select SYS_SUPPORTS_BIG_ENDIAN
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
 
 config MIPS_DB1550
 	bool "Alchemy DB1550 board"
@@ -63,12 +69,14 @@ config MIPS_DB1550
 	select DMA_NONCOHERENT
 	select MIPS_DISABLE_OBSOLETE_IDE
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
 
 config MIPS_MIRAGE
 	bool "Alchemy Mirage board"
 	select DMA_NONCOHERENT
 	select SOC_AU1500
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
 
 config MIPS_PB1000
 	bool "Alchemy PB1000 board"
@@ -77,6 +85,7 @@ config MIPS_PB1000
 	select HW_HAS_PCI
 	select SWAP_IO_SPACE
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
 
 config MIPS_PB1100
 	bool "Alchemy PB1100 board"
@@ -85,6 +94,7 @@ config MIPS_PB1100
 	select HW_HAS_PCI
 	select SWAP_IO_SPACE
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
 
 config MIPS_PB1200
 	bool "Alchemy PB1200 board"
@@ -92,6 +102,7 @@ config MIPS_PB1200
 	select DMA_NONCOHERENT
 	select MIPS_DISABLE_OBSOLETE_IDE
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
 
 config MIPS_PB1500
 	bool "Alchemy PB1500 board"
@@ -99,6 +110,7 @@ config MIPS_PB1500
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
 
 config MIPS_PB1550
 	bool "Alchemy PB1550 board"
@@ -107,39 +119,41 @@ config MIPS_PB1550
 	select HW_HAS_PCI
 	select MIPS_DISABLE_OBSOLETE_IDE
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
 
 config MIPS_XXS1500
 	bool "MyCable XXS1500 board"
 	select DMA_NONCOHERENT
 	select SOC_AU1500
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
 
 endchoice
 
 config SOC_AU1000
 	bool
 	select SOC_AU1X00
-	select ALCHEMY_GPIO_AU1000
+	select ALCHEMY_GPIOINT_AU1000
 
 config SOC_AU1100
 	bool
 	select SOC_AU1X00
-	select ALCHEMY_GPIO_AU1000
+	select ALCHEMY_GPIOINT_AU1000
 
 config SOC_AU1500
 	bool
 	select SOC_AU1X00
-	select ALCHEMY_GPIO_AU1000
+	select ALCHEMY_GPIOINT_AU1000
 
 config SOC_AU1550
 	bool
 	select SOC_AU1X00
-	select ALCHEMY_GPIO_AU1000
+	select ALCHEMY_GPIOINT_AU1000
 
 config SOC_AU1200
 	bool
 	select SOC_AU1X00
-	select ALCHEMY_GPIO_AU1000
+	select ALCHEMY_GPIOINT_AU1000
 
 config SOC_AU1X00
 	bool
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/mtx-1/board_setup.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/mtx-1/board_setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/mtx-1/board_setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/mtx-1/board_setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,32 +30,43 @@
 
 #include <linux/gpio.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
 
+#include <asm/reboot.h>
 #include <asm/mach-au1x00/au1000.h>
 
 #include <prom.h>
 
+char irq_tab_alchemy[][5] __initdata = {
+	[0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 00 - AdapterA-Slot0 (top) */
+	[1] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
+	[2] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 02 - AdapterB-Slot0 (top) */
+	[3] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
+	[4] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 04 - AdapterC-Slot0 (top) */
+	[5] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
+	[6] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 06 - AdapterD-Slot0 (top) */
+	[7] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
+};
+
 extern int (*board_pci_idsel)(unsigned int devsel, int assert);
 int mtx1_pci_idsel(unsigned int devsel, int assert);
 
-void board_reset(void)
+static void mtx1_reset(char *c)
 {
 	/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
 	au_writel(0x00000000, 0xAE00001C);
 }
 
-void __init board_setup(void)
+static void mtx1_power_off(void)
 {
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-	char *argptr;
-	argptr = prom_getcmdline();
-	argptr = strstr(argptr, "console=");
-	if (argptr == NULL) {
-		argptr = prom_getcmdline();
-		strcat(argptr, " console=ttyS0,115200");
-	}
-#endif
+	printk(KERN_ALERT "It's now safe to remove power\n");
+	while (1)
+		asm volatile (".set mips3 ; wait ; .set mips1");
+}
 
+void __init board_setup(void)
+{
 	alchemy_gpio2_enable();
 
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
@@ -86,6 +97,10 @@ void __init board_setup(void)
 	alchemy_gpio_direction_output(211, 1);	/* green on */
 	alchemy_gpio_direction_output(212, 0);	/* red off */
 
+	pm_power_off = mtx1_power_off;
+	_machine_halt = mtx1_power_off;
+	_machine_restart = mtx1_reset;
+
 	printk(KERN_INFO "4G Systems MTX-1 Board\n");
 }
 
@@ -109,3 +124,15 @@ mtx1_pci_idsel(unsigned int devsel, int
 	au_sync_udelay(1);
 	return 1;
 }
+
+static int __init mtx1_init_irq(void)
+{
+	set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
+	set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
+
+	return 0;
+}
+arch_initcall(mtx1_init_irq);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/mtx-1/init.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/mtx-1/init.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/mtx-1/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/mtx-1/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/init.h>
 
 #include <asm/bootinfo.h>
+#include <asm/mach-au1x00/au1000.h>
 
 #include <prom.h>
 
@@ -58,3 +59,8 @@ void __init prom_init(void)
 		strict_strtoul(memsize_str, 0, &memsize);
 	add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
+
+void prom_putchar(unsigned char c)
+{
+	alchemy_uart_putchar(UART0_PHYS_ADDR, c);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/mtx-1/irqmap.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/mtx-1/irqmap.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/mtx-1/irqmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/mtx-1/irqmap.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,56 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *	Au1xxx irq map table
- *
- * Copyright 2003 Embedded Edge, LLC
- *		dan@embeddededge.com
- *
- *  This program is free software; you can redistribute	 it and/or modify it
- *  under  the terms of	 the GNU 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.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <asm/mach-au1x00/au1000.h>
-
-char irq_tab_alchemy[][5] __initdata = {
-	[0] = { -1, INTA, INTA, INTX, INTX }, /* IDSEL 00 - AdapterA-Slot0 (top) */
-	[1] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
-	[2] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 02 - AdapterB-Slot0 (top) */
-	[3] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
-	[4] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 04 - AdapterC-Slot0 (top) */
-	[5] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
-	[6] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 06 - AdapterD-Slot0 (top) */
-	[7] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
-};
-
-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-       { AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 },
-       { AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 },
-       { AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 },
-       { AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 },
-       { AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 },
-};
-
-
-void __init board_init_irq(void)
-{
-	au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/mtx-1/Makefile linux-libre-2.6.34-gnu1/arch/mips/alchemy/mtx-1/Makefile
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/mtx-1/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/mtx-1/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
 # Makefile for 4G Systems MTX-1 board.
 #
 
-lib-y := init.o board_setup.o irqmap.o
+lib-y := init.o board_setup.o
 obj-y := platform.o
 
 EXTRA_CFLAGS += -Werror
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/xxs1500/board_setup.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/xxs1500/board_setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/xxs1500/board_setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/xxs1500/board_setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,31 +25,35 @@
 
 #include <linux/gpio.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/pm.h>
 
+#include <asm/reboot.h>
 #include <asm/mach-au1x00/au1000.h>
 
 #include <prom.h>
 
-void board_reset(void)
+static void xxs1500_reset(char *c)
 {
 	/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
 	au_writel(0x00000000, 0xAE00001C);
 }
 
+static void xxs1500_power_off(void)
+{
+	printk(KERN_ALERT "It's now safe to remove power\n");
+	while (1)
+		asm volatile (".set mips3 ; wait ; .set mips1");
+}
+
 void __init board_setup(void)
 {
 	u32 pin_func;
 
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-	char *argptr;
-	argptr = prom_getcmdline();
-	argptr = strstr(argptr, "console=");
-	if (argptr == NULL) {
-		argptr = prom_getcmdline();
-		strcat(argptr, " console=ttyS0,115200");
-	}
-#endif
+	pm_power_off = xxs1500_power_off;
+	_machine_halt = xxs1500_power_off;
+	_machine_restart = xxs1500_reset;
 
 	alchemy_gpio1_input_enable();
 	alchemy_gpio2_enable();
@@ -68,22 +72,6 @@ void __init board_setup(void)
 	/* Enable DTR = USB power up */
 	au_writel(0x01, UART3_ADDR + UART_MCR); /* UART_MCR_DTR is 0x01??? */
 
-#ifdef CONFIG_PCMCIA_XXS1500
-	/* GPIO 0, 1, and 4 are inputs */
-	alchemy_gpio_direction_input(0);
-	alchemy_gpio_direction_input(1);
-	alchemy_gpio_direction_input(4);
-
-	/* GPIO2 208/9/10/11 are inputs */
-	alchemy_gpio_direction_input(208);
-	alchemy_gpio_direction_input(209);
-	alchemy_gpio_direction_input(210);
-	alchemy_gpio_direction_input(211);
-
-	/* Turn off power */
-	alchemy_gpio_direction_output(214, 0);
-#endif
-
 #ifdef CONFIG_PCI
 #if defined(__MIPSEB__)
 	au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
@@ -92,3 +80,23 @@ void __init board_setup(void)
 #endif
 #endif
 }
+
+static int __init xxs1500_init_irq(void)
+{
+	set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
+	set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1500_GPIO207_INT, IRQF_TRIGGER_LOW);
+
+	set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW);
+	set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* CF irq */
+	set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW);
+
+	return 0;
+}
+arch_initcall(xxs1500_init_irq);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/xxs1500/init.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/xxs1500/init.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/xxs1500/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/xxs1500/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 
 #include <asm/bootinfo.h>
+#include <asm/mach-au1x00/au1000.h>
 
 #include <prom.h>
 
@@ -56,3 +57,8 @@ void __init prom_init(void)
 		strict_strtoul(memsize_str, 0, &memsize);
 	add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
+
+void prom_putchar(unsigned char c)
+{
+	alchemy_uart_putchar(UART0_PHYS_ADDR, c);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/xxs1500/irqmap.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/xxs1500/irqmap.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/xxs1500/irqmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/xxs1500/irqmap.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,52 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *	Au1xxx irq map table
- *
- * Copyright 2003 Embedded Edge, LLC
- *		dan@embeddededge.com
- *
- *  This program is free software; you can redistribute	 it and/or modify it
- *  under  the terms of	 the GNU 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.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <asm/mach-au1x00/au1000.h>
-
-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-	{ AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 },
-	{ AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 },
-	{ AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 },
-	{ AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 },
-	{ AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 },
-	{ AU1500_GPIO_207, IRQF_TRIGGER_LOW, 0 },
-
-	{ AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 },
-	{ AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 },
-	{ AU1000_GPIO_2, IRQF_TRIGGER_LOW, 0 },
-	{ AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 },
-	{ AU1000_GPIO_4, IRQF_TRIGGER_LOW, 0 }, /* CF interrupt */
-	{ AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 },
-};
-
-void __init board_init_irq(void)
-{
-	au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/xxs1500/Makefile linux-libre-2.6.34-gnu1/arch/mips/alchemy/xxs1500/Makefile
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/xxs1500/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/xxs1500/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,4 +5,6 @@
 # Makefile for MyCable XXS1500 board.
 #
 
-lib-y := init.o board_setup.o irqmap.o
+lib-y := init.o board_setup.o platform.o
+
+EXTRA_CFLAGS += -Werror
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/alchemy/xxs1500/platform.c linux-libre-2.6.34-gnu1/arch/mips/alchemy/xxs1500/platform.c
--- linux-libre-2.6.33-gnu1/arch/mips/alchemy/xxs1500/platform.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/alchemy/xxs1500/platform.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,63 @@
+/*
+ * XXS1500 board platform device registration
+ *
+ * Copyright (C) 2009 Manuel Lauss
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-au1x00/au1000.h>
+
+static struct resource xxs1500_pcmcia_res[] = {
+	{
+		.name	= "pcmcia-io",
+		.flags	= IORESOURCE_MEM,
+		.start	= PCMCIA_IO_PHYS_ADDR,
+		.end	= PCMCIA_IO_PHYS_ADDR + 0x000400000 - 1,
+	},
+	{
+		.name	= "pcmcia-attr",
+		.flags	= IORESOURCE_MEM,
+		.start	= PCMCIA_ATTR_PHYS_ADDR,
+		.end	= PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+	},
+	{
+		.name	= "pcmcia-mem",
+		.flags	= IORESOURCE_MEM,
+		.start	= PCMCIA_MEM_PHYS_ADDR,
+		.end	= PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
+	},
+};
+
+static struct platform_device xxs1500_pcmcia_dev = {
+	.name		= "xxs1500_pcmcia",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(xxs1500_pcmcia_res),
+	.resource	= xxs1500_pcmcia_res,
+};
+
+static struct platform_device *xxs1500_devs[] __initdata = {
+	&xxs1500_pcmcia_dev,
+};
+
+static int __init xxs1500_dev_init(void)
+{
+	return platform_add_devices(xxs1500_devs,
+				    ARRAY_SIZE(xxs1500_devs));
+}
+device_initcall(xxs1500_dev_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/ar7/clock.c linux-libre-2.6.34-gnu1/arch/mips/ar7/clock.c
--- linux-libre-2.6.33-gnu1/arch/mips/ar7/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/ar7/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
  * Copyright (C) 2007 Eugene Konev <ejka@openwrt.org>
+ * Copyright (C) 2009 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
@@ -24,6 +25,8 @@
 #include <linux/delay.h>
 #include <linux/gcd.h>
 #include <linux/io.h>
+#include <linux/err.h>
+#include <linux/clk.h>
 
 #include <asm/addrspace.h>
 #include <asm/mach-ar7/ar7.h>
@@ -94,12 +97,16 @@ struct tnetd7200_clocks {
 	struct tnetd7200_clock usb;
 };
 
-int ar7_cpu_clock = 150000000;
-EXPORT_SYMBOL(ar7_cpu_clock);
-int ar7_bus_clock = 125000000;
-EXPORT_SYMBOL(ar7_bus_clock);
-int ar7_dsp_clock;
-EXPORT_SYMBOL(ar7_dsp_clock);
+static struct clk bus_clk = {
+	.rate	= 125000000,
+};
+
+static struct clk cpu_clk = {
+	.rate	= 150000000,
+};
+
+static struct clk dsp_clk;
+static struct clk vbus_clk;
 
 static void approximate(int base, int target, int *prediv,
 			int *postdiv, int *mul)
@@ -185,7 +192,7 @@ static int tnetd7300_get_clock(u32 shift
 		base_clock = AR7_XTAL_CLOCK;
 		break;
 	case BOOT_PLL_SOURCE_CPU:
-		base_clock = ar7_cpu_clock;
+		base_clock = cpu_clk.rate;
 		break;
 	}
 
@@ -212,11 +219,11 @@ static void tnetd7300_set_clock(u32 shif
 	u32 *bootcr, u32 frequency)
 {
 	int prediv, postdiv, mul;
-	int base_clock = ar7_bus_clock;
+	int base_clock = bus_clk.rate;
 
 	switch ((*bootcr & (BOOT_PLL_SOURCE_MASK << shift)) >> shift) {
 	case BOOT_PLL_SOURCE_BUS:
-		base_clock = ar7_bus_clock;
+		base_clock = bus_clk.rate;
 		break;
 	case BOOT_PLL_SOURCE_REF:
 		base_clock = AR7_REF_CLOCK;
@@ -225,7 +232,7 @@ static void tnetd7300_set_clock(u32 shif
 		base_clock = AR7_XTAL_CLOCK;
 		break;
 	case BOOT_PLL_SOURCE_CPU:
-		base_clock = ar7_cpu_clock;
+		base_clock = cpu_clk.rate;
 		break;
 	}
 
@@ -247,18 +254,18 @@ static void __init tnetd7300_init_clocks
 					ioremap_nocache(UR8_REGS_CLOCKS,
 					sizeof(struct tnetd7300_clocks));
 
-	ar7_bus_clock = tnetd7300_get_clock(BUS_PLL_SOURCE_SHIFT,
+	bus_clk.rate = tnetd7300_get_clock(BUS_PLL_SOURCE_SHIFT,
 		&clocks->bus, bootcr, AR7_AFE_CLOCK);
 
 	if (*bootcr & BOOT_PLL_ASYNC_MODE)
-		ar7_cpu_clock = tnetd7300_get_clock(CPU_PLL_SOURCE_SHIFT,
+		cpu_clk.rate = tnetd7300_get_clock(CPU_PLL_SOURCE_SHIFT,
 			&clocks->cpu, bootcr, AR7_AFE_CLOCK);
 	else
-		ar7_cpu_clock = ar7_bus_clock;
+		cpu_clk.rate = bus_clk.rate;
 
-	if (ar7_dsp_clock == 250000000)
+	if (dsp_clk.rate == 250000000)
 		tnetd7300_set_clock(DSP_PLL_SOURCE_SHIFT, &clocks->dsp,
-			bootcr, ar7_dsp_clock);
+			bootcr, dsp_clk.rate);
 
 	iounmap(clocks);
 	iounmap(bootcr);
@@ -343,20 +350,20 @@ static void __init tnetd7200_init_clocks
 		printk(KERN_INFO "Clocks: Setting DSP clock\n");
 		calculate(dsp_base, TNETD7200_DEF_DSP_CLK,
 			&dsp_prediv, &dsp_postdiv, &dsp_mul);
-		ar7_bus_clock =
+		bus_clk.rate =
 			((dsp_base / dsp_prediv) * dsp_mul) / dsp_postdiv;
 		tnetd7200_set_clock(dsp_base, &clocks->dsp,
 			dsp_prediv, dsp_postdiv * 2, dsp_postdiv, dsp_mul * 2,
-			ar7_bus_clock);
+			bus_clk.rate);
 
 		printk(KERN_INFO "Clocks: Setting CPU clock\n");
 		calculate(cpu_base, TNETD7200_DEF_CPU_CLK, &cpu_prediv,
 			&cpu_postdiv, &cpu_mul);
-		ar7_cpu_clock =
+		cpu_clk.rate =
 			((cpu_base / cpu_prediv) * cpu_mul) / cpu_postdiv;
 		tnetd7200_set_clock(cpu_base, &clocks->cpu,
 			cpu_prediv, cpu_postdiv, -1, cpu_mul,
-			ar7_cpu_clock);
+			cpu_clk.rate);
 
 	} else
 		if (*bootcr & BOOT_PLL_2TO1_MODE) {
@@ -365,48 +372,90 @@ static void __init tnetd7200_init_clocks
 			printk(KERN_INFO "Clocks: Setting CPU clock\n");
 			calculate(cpu_base, TNETD7200_DEF_CPU_CLK, &cpu_prediv,
 				&cpu_postdiv, &cpu_mul);
-			ar7_cpu_clock = ((cpu_base / cpu_prediv) * cpu_mul)
+			cpu_clk.rate = ((cpu_base / cpu_prediv) * cpu_mul)
 								/ cpu_postdiv;
 			tnetd7200_set_clock(cpu_base, &clocks->cpu,
 				cpu_prediv, cpu_postdiv, -1, cpu_mul,
-				ar7_cpu_clock);
+				cpu_clk.rate);
 
 			printk(KERN_INFO "Clocks: Setting DSP clock\n");
 			calculate(dsp_base, TNETD7200_DEF_DSP_CLK, &dsp_prediv,
 				&dsp_postdiv, &dsp_mul);
-			ar7_bus_clock = ar7_cpu_clock / 2;
+			bus_clk.rate = cpu_clk.rate / 2;
 			tnetd7200_set_clock(dsp_base, &clocks->dsp,
 				dsp_prediv, dsp_postdiv * 2, dsp_postdiv,
-				dsp_mul * 2, ar7_bus_clock);
+				dsp_mul * 2, bus_clk.rate);
 		} else {
 			printk(KERN_INFO "Clocks: Sync 1:1 mode\n");
 
 			printk(KERN_INFO "Clocks: Setting DSP clock\n");
 			calculate(dsp_base, TNETD7200_DEF_DSP_CLK, &dsp_prediv,
 				&dsp_postdiv, &dsp_mul);
-			ar7_bus_clock = ((dsp_base / dsp_prediv) * dsp_mul)
+			bus_clk.rate = ((dsp_base / dsp_prediv) * dsp_mul)
 								/ dsp_postdiv;
 			tnetd7200_set_clock(dsp_base, &clocks->dsp,
 				dsp_prediv, dsp_postdiv * 2, dsp_postdiv,
-				dsp_mul * 2, ar7_bus_clock);
+				dsp_mul * 2, bus_clk.rate);
 
-			ar7_cpu_clock = ar7_bus_clock;
+			cpu_clk.rate = bus_clk.rate;
 		}
 
 	printk(KERN_INFO "Clocks: Setting USB clock\n");
-	usb_base = ar7_bus_clock;
+	usb_base = bus_clk.rate;
 	calculate(usb_base, TNETD7200_DEF_USB_CLK, &usb_prediv,
 		&usb_postdiv, &usb_mul);
 	tnetd7200_set_clock(usb_base, &clocks->usb,
 		usb_prediv, usb_postdiv, -1, usb_mul,
 		TNETD7200_DEF_USB_CLK);
 
-	ar7_dsp_clock = ar7_cpu_clock;
+	dsp_clk.rate = cpu_clk.rate;
 
 	iounmap(clocks);
 	iounmap(bootcr);
 }
 
+/*
+ * Linux clock API
+ */
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	if (!strcmp(id, "bus"))
+		return &bus_clk;
+	/* cpmac and vbus share the same rate */
+	if (!strcmp(id, "cpmac"))
+		return &vbus_clk;
+	if (!strcmp(id, "cpu"))
+		return &cpu_clk;
+	if (!strcmp(id, "dsp"));
+		return &dsp_clk;
+	if (!strcmp(id, "vbus"))
+		return &vbus_clk;
+	return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
+
 int __init ar7_init_clocks(void)
 {
 	switch (ar7_chip_id()) {
@@ -415,12 +464,14 @@ int __init ar7_init_clocks(void)
 		tnetd7200_init_clocks();
 		break;
 	case AR7_CHIP_7300:
-		ar7_dsp_clock = tnetd7300_dsp_clock();
+		dsp_clk.rate = tnetd7300_dsp_clock();
 		tnetd7300_init_clocks();
 		break;
 	default:
 		break;
 	}
+	/* adjust vbus clock rate */
+	vbus_clk.rate = bus_clk.rate / 2;
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/ar7/gpio.c linux-libre-2.6.34-gnu1/arch/mips/ar7/gpio.c
--- linux-libre-2.6.33-gnu1/arch/mips/ar7/gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/ar7/gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
  * Copyright (C) 2007 Eugene Konev <ejka@openwrt.org>
+ * Copyright (C) 2009 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
@@ -18,31 +19,113 @@
  */
 
 #include <linux/module.h>
+#include <linux/gpio.h>
 
 #include <asm/mach-ar7/gpio.h>
 
-static const char *ar7_gpio_list[AR7_GPIO_MAX];
+struct ar7_gpio_chip {
+	void __iomem		*regs;
+	struct gpio_chip	chip;
+};
 
-int gpio_request(unsigned gpio, const char *label)
+static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
 {
-	if (gpio >= AR7_GPIO_MAX)
-		return -EINVAL;
+	struct ar7_gpio_chip *gpch =
+				container_of(chip, struct ar7_gpio_chip, chip);
+	void __iomem *gpio_in = gpch->regs + AR7_GPIO_INPUT;
 
-	if (ar7_gpio_list[gpio])
-		return -EBUSY;
+	return readl(gpio_in) & (1 << gpio);
+}
 
-	if (label)
-		ar7_gpio_list[gpio] = label;
-	else
-		ar7_gpio_list[gpio] = "busy";
+static void ar7_gpio_set_value(struct gpio_chip *chip,
+				unsigned gpio, int value)
+{
+	struct ar7_gpio_chip *gpch =
+				container_of(chip, struct ar7_gpio_chip, chip);
+	void __iomem *gpio_out = gpch->regs + AR7_GPIO_OUTPUT;
+	unsigned tmp;
+
+	tmp = readl(gpio_out) & ~(1 << gpio);
+	if (value)
+		tmp |= 1 << gpio;
+	writel(tmp, gpio_out);
+}
+
+static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+	struct ar7_gpio_chip *gpch =
+				container_of(chip, struct ar7_gpio_chip, chip);
+	void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR;
+
+	writel(readl(gpio_dir) | (1 << gpio), gpio_dir);
 
 	return 0;
 }
-EXPORT_SYMBOL(gpio_request);
 
-void gpio_free(unsigned gpio)
+static int ar7_gpio_direction_output(struct gpio_chip *chip,
+					unsigned gpio, int value)
 {
-	BUG_ON(!ar7_gpio_list[gpio]);
-	ar7_gpio_list[gpio] = NULL;
+	struct ar7_gpio_chip *gpch =
+				container_of(chip, struct ar7_gpio_chip, chip);
+	void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR;
+
+	ar7_gpio_set_value(chip, gpio, value);
+	writel(readl(gpio_dir) & ~(1 << gpio), gpio_dir);
+
+	return 0;
 }
-EXPORT_SYMBOL(gpio_free);
+
+static struct ar7_gpio_chip ar7_gpio_chip = {
+	.chip = {
+		.label			= "ar7-gpio",
+		.direction_input	= ar7_gpio_direction_input,
+		.direction_output	= ar7_gpio_direction_output,
+		.set			= ar7_gpio_set_value,
+		.get			= ar7_gpio_get_value,
+		.base			= 0,
+		.ngpio			= AR7_GPIO_MAX,
+	}
+};
+
+int ar7_gpio_enable(unsigned gpio)
+{
+	void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
+
+	writel(readl(gpio_en) | (1 << gpio), gpio_en);
+
+	return 0;
+}
+EXPORT_SYMBOL(ar7_gpio_enable);
+
+int ar7_gpio_disable(unsigned gpio)
+{
+	void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
+
+	writel(readl(gpio_en) & ~(1 << gpio), gpio_en);
+
+	return 0;
+}
+EXPORT_SYMBOL(ar7_gpio_disable);
+
+static int __init ar7_gpio_init(void)
+{
+	int ret;
+
+	ar7_gpio_chip.regs = ioremap_nocache(AR7_REGS_GPIO,
+					AR7_REGS_GPIO + 0x10);
+
+	if (!ar7_gpio_chip.regs) {
+		printk(KERN_ERR "ar7-gpio: failed to ioremap regs\n");
+		return -ENOMEM;
+	}
+
+	ret = gpiochip_add(&ar7_gpio_chip.chip);
+	if (ret) {
+		printk(KERN_ERR "ar7-gpio: failed to add gpiochip\n");
+		return ret;
+	}
+	printk(KERN_INFO "ar7-gpio: registered %d GPIOs\n",
+				ar7_gpio_chip.chip.ngpio);
+	return ret;
+}
+arch_initcall(ar7_gpio_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/ar7/memory.c linux-libre-2.6.34-gnu1/arch/mips/ar7/memory.c
--- linux-libre-2.6.33-gnu1/arch/mips/ar7/memory.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/ar7/memory.c	2010-05-16 17:17:36.000000000 -0400
@@ -62,8 +62,7 @@ void __init prom_meminit(void)
 	unsigned long pages;
 
 	pages = memsize() >> PAGE_SHIFT;
-	add_memory_region(PHYS_OFFSET, pages << PAGE_SHIFT,
-			  BOOT_MEM_RAM);
+	add_memory_region(PHYS_OFFSET, pages << PAGE_SHIFT, BOOT_MEM_RAM);
 }
 
 void __init prom_free_prom_memory(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/ar7/platform.c linux-libre-2.6.34-gnu1/arch/mips/ar7/platform.c
--- linux-libre-2.6.33-gnu1/arch/mips/ar7/platform.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/ar7/platform.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,45 +34,50 @@
 #include <linux/etherdevice.h>
 #include <linux/phy.h>
 #include <linux/phy_fixed.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
 
 #include <asm/addrspace.h>
 #include <asm/mach-ar7/ar7.h>
 #include <asm/mach-ar7/gpio.h>
 #include <asm/mach-ar7/prom.h>
 
+/*****************************************************************************
+ * VLYNQ Bus
+ ****************************************************************************/
 struct plat_vlynq_data {
 	struct plat_vlynq_ops ops;
 	int gpio_bit;
 	int reset_bit;
 };
 
-
 static int vlynq_on(struct vlynq_device *dev)
 {
-	int result;
+	int ret;
 	struct plat_vlynq_data *pdata = dev->dev.platform_data;
 
-	result = gpio_request(pdata->gpio_bit, "vlynq");
-	if (result)
+	ret = gpio_request(pdata->gpio_bit, "vlynq");
+	if (ret)
 		goto out;
 
 	ar7_device_reset(pdata->reset_bit);
 
-	result = ar7_gpio_disable(pdata->gpio_bit);
-	if (result)
+	ret = ar7_gpio_disable(pdata->gpio_bit);
+	if (ret)
 		goto out_enabled;
 
-	result = ar7_gpio_enable(pdata->gpio_bit);
-	if (result)
+	ret = ar7_gpio_enable(pdata->gpio_bit);
+	if (ret)
 		goto out_enabled;
 
-	result = gpio_direction_output(pdata->gpio_bit, 0);
-	if (result)
+	ret = gpio_direction_output(pdata->gpio_bit, 0);
+	if (ret)
 		goto out_gpio_enabled;
 
 	msleep(50);
 
 	gpio_set_value(pdata->gpio_bit, 1);
+
 	msleep(50);
 
 	return 0;
@@ -83,320 +88,384 @@ out_enabled:
 	ar7_device_disable(pdata->reset_bit);
 	gpio_free(pdata->gpio_bit);
 out:
-	return result;
+	return ret;
 }
 
 static void vlynq_off(struct vlynq_device *dev)
 {
 	struct plat_vlynq_data *pdata = dev->dev.platform_data;
+
 	ar7_gpio_disable(pdata->gpio_bit);
 	gpio_free(pdata->gpio_bit);
 	ar7_device_disable(pdata->reset_bit);
 }
 
-static struct resource physmap_flash_resource = {
-	.name = "mem",
-	.flags = IORESOURCE_MEM,
-	.start = 0x10000000,
-	.end = 0x107fffff,
-};
-
-static struct resource cpmac_low_res[] = {
+static struct resource vlynq_low_res[] = {
 	{
-		.name = "regs",
-		.flags = IORESOURCE_MEM,
-		.start = AR7_REGS_MAC0,
-		.end = AR7_REGS_MAC0 + 0x7ff,
+		.name	= "regs",
+		.flags	= IORESOURCE_MEM,
+		.start	= AR7_REGS_VLYNQ0,
+		.end	= AR7_REGS_VLYNQ0 + 0xff,
 	},
 	{
-		.name = "irq",
-		.flags = IORESOURCE_IRQ,
-		.start = 27,
-		.end = 27,
+		.name	= "irq",
+		.flags	= IORESOURCE_IRQ,
+		.start	= 29,
+		.end	= 29,
 	},
-};
-
-static struct resource cpmac_high_res[] = {
 	{
-		.name = "regs",
-		.flags = IORESOURCE_MEM,
-		.start = AR7_REGS_MAC1,
-		.end = AR7_REGS_MAC1 + 0x7ff,
+		.name	= "mem",
+		.flags	= IORESOURCE_MEM,
+		.start	= 0x04000000,
+		.end	= 0x04ffffff,
 	},
 	{
-		.name = "irq",
-		.flags = IORESOURCE_IRQ,
-		.start = 41,
-		.end = 41,
+		.name	= "devirq",
+		.flags	= IORESOURCE_IRQ,
+		.start	= 80,
+		.end	= 111,
 	},
 };
 
-static struct resource vlynq_low_res[] = {
+static struct resource vlynq_high_res[] = {
 	{
-		.name = "regs",
-		.flags = IORESOURCE_MEM,
-		.start = AR7_REGS_VLYNQ0,
-		.end = AR7_REGS_VLYNQ0 + 0xff,
+		.name	= "regs",
+		.flags	= IORESOURCE_MEM,
+		.start	= AR7_REGS_VLYNQ1,
+		.end	= AR7_REGS_VLYNQ1 + 0xff,
 	},
 	{
-		.name = "irq",
-		.flags = IORESOURCE_IRQ,
-		.start = 29,
-		.end = 29,
+		.name	= "irq",
+		.flags	= IORESOURCE_IRQ,
+		.start	= 33,
+		.end	= 33,
 	},
 	{
-		.name = "mem",
-		.flags = IORESOURCE_MEM,
-		.start = 0x04000000,
-		.end = 0x04ffffff,
+		.name	= "mem",
+		.flags	= IORESOURCE_MEM,
+		.start	= 0x0c000000,
+		.end	= 0x0cffffff,
 	},
 	{
-		.name = "devirq",
-		.flags = IORESOURCE_IRQ,
-		.start = 80,
-		.end = 111,
+		.name	= "devirq",
+		.flags	= IORESOURCE_IRQ,
+		.start	= 112,
+		.end	= 143,
 	},
 };
 
-static struct resource vlynq_high_res[] = {
-	{
-		.name = "regs",
-		.flags = IORESOURCE_MEM,
-		.start = AR7_REGS_VLYNQ1,
-		.end = AR7_REGS_VLYNQ1 + 0xff,
+static struct plat_vlynq_data vlynq_low_data = {
+	.ops = {
+		.on	= vlynq_on,
+		.off	= vlynq_off,
 	},
-	{
-		.name = "irq",
-		.flags = IORESOURCE_IRQ,
-		.start = 33,
-		.end = 33,
+	.reset_bit	= 20,
+	.gpio_bit	= 18,
+};
+
+static struct plat_vlynq_data vlynq_high_data = {
+	.ops = {
+		.on	= vlynq_on,
+		.off	= vlynq_off,
 	},
-	{
-		.name = "mem",
-		.flags = IORESOURCE_MEM,
-		.start = 0x0c000000,
-		.end = 0x0cffffff,
+	.reset_bit	= 16,
+	.gpio_bit	= 19,
+};
+
+static struct platform_device vlynq_low = {
+	.id		= 0,
+	.name		= "vlynq",
+	.dev = {
+		.platform_data	= &vlynq_low_data,
 	},
-	{
-		.name = "devirq",
-		.flags = IORESOURCE_IRQ,
-		.start = 112,
-		.end = 143,
+	.resource	= vlynq_low_res,
+	.num_resources	= ARRAY_SIZE(vlynq_low_res),
+};
+
+static struct platform_device vlynq_high = {
+	.id		= 1,
+	.name		= "vlynq",
+	.dev = {
+		.platform_data	= &vlynq_high_data,
 	},
+	.resource	= vlynq_high_res,
+	.num_resources	= ARRAY_SIZE(vlynq_high_res),
 };
 
-static struct resource usb_res[] = {
-	{
-		.name = "regs",
-		.flags = IORESOURCE_MEM,
-		.start = AR7_REGS_USB,
-		.end = AR7_REGS_USB + 0xff,
+/*****************************************************************************
+ * Flash
+ ****************************************************************************/
+static struct resource physmap_flash_resource = {
+	.name	= "mem",
+	.flags	= IORESOURCE_MEM,
+	.start	= 0x10000000,
+	.end	= 0x107fffff,
+};
+
+static struct physmap_flash_data physmap_flash_data = {
+	.width	= 2,
+};
+
+static struct platform_device physmap_flash = {
+	.name		= "physmap-flash",
+	.dev = {
+		.platform_data	= &physmap_flash_data,
 	},
+	.resource	= &physmap_flash_resource,
+	.num_resources	= 1,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+static struct resource cpmac_low_res[] = {
 	{
-		.name = "irq",
-		.flags = IORESOURCE_IRQ,
-		.start = 32,
-		.end = 32,
+		.name	= "regs",
+		.flags	= IORESOURCE_MEM,
+		.start	= AR7_REGS_MAC0,
+		.end	= AR7_REGS_MAC0 + 0x7ff,
 	},
 	{
-		.name = "mem",
-		.flags = IORESOURCE_MEM,
-		.start = 0x03400000,
-		.end = 0x03401fff,
+		.name	= "irq",
+		.flags	= IORESOURCE_IRQ,
+		.start	= 27,
+		.end 	= 27,
 	},
 };
 
-static struct physmap_flash_data physmap_flash_data = {
-	.width = 2,
+static struct resource cpmac_high_res[] = {
+	{
+		.name	= "regs",
+		.flags	= IORESOURCE_MEM,
+		.start	= AR7_REGS_MAC1,
+		.end	= AR7_REGS_MAC1 + 0x7ff,
+	},
+	{
+		.name	= "irq",
+		.flags	= IORESOURCE_IRQ,
+		.start	= 41,
+		.end	= 41,
+	},
 };
 
 static struct fixed_phy_status fixed_phy_status __initdata = {
-	.link = 1,
-	.speed = 100,
-	.duplex = 1,
+	.link		= 1,
+	.speed		= 100,
+	.duplex		= 1,
 };
 
 static struct plat_cpmac_data cpmac_low_data = {
-	.reset_bit = 17,
-	.power_bit = 20,
-	.phy_mask = 0x80000000,
+	.reset_bit	= 17,
+	.power_bit	= 20,
+	.phy_mask	= 0x80000000,
 };
 
 static struct plat_cpmac_data cpmac_high_data = {
-	.reset_bit = 21,
-	.power_bit = 22,
-	.phy_mask = 0x7fffffff,
-};
-
-static struct plat_vlynq_data vlynq_low_data = {
-	.ops.on = vlynq_on,
-	.ops.off = vlynq_off,
-	.reset_bit = 20,
-	.gpio_bit = 18,
-};
-
-static struct plat_vlynq_data vlynq_high_data = {
-	.ops.on = vlynq_on,
-	.ops.off = vlynq_off,
-	.reset_bit = 16,
-	.gpio_bit = 19,
-};
-
-static struct platform_device physmap_flash = {
-	.id = 0,
-	.name = "physmap-flash",
-	.dev.platform_data = &physmap_flash_data,
-	.resource = &physmap_flash_resource,
-	.num_resources = 1,
+	.reset_bit	= 21,
+	.power_bit	= 22,
+	.phy_mask	= 0x7fffffff,
 };
 
 static u64 cpmac_dma_mask = DMA_BIT_MASK(32);
+
 static struct platform_device cpmac_low = {
-	.id = 0,
-	.name = "cpmac",
+	.id		= 0,
+	.name		= "cpmac",
 	.dev = {
-		.dma_mask = &cpmac_dma_mask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-		.platform_data = &cpmac_low_data,
+		.dma_mask		= &cpmac_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= &cpmac_low_data,
 	},
-	.resource = cpmac_low_res,
-	.num_resources = ARRAY_SIZE(cpmac_low_res),
+	.resource	= cpmac_low_res,
+	.num_resources	= ARRAY_SIZE(cpmac_low_res),
 };
 
 static struct platform_device cpmac_high = {
-	.id = 1,
-	.name = "cpmac",
+	.id		= 1,
+	.name		= "cpmac",
 	.dev = {
-		.dma_mask = &cpmac_dma_mask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-		.platform_data = &cpmac_high_data,
+		.dma_mask		= &cpmac_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= &cpmac_high_data,
 	},
-	.resource = cpmac_high_res,
-	.num_resources = ARRAY_SIZE(cpmac_high_res),
+	.resource	= cpmac_high_res,
+	.num_resources	= ARRAY_SIZE(cpmac_high_res),
 };
 
-static struct platform_device vlynq_low = {
-	.id = 0,
-	.name = "vlynq",
-	.dev.platform_data = &vlynq_low_data,
-	.resource = vlynq_low_res,
-	.num_resources = ARRAY_SIZE(vlynq_low_res),
-};
+static inline unsigned char char2hex(char h)
+{
+	switch (h) {
+	case '0': case '1': case '2': case '3': case '4':
+	case '5': case '6': case '7': case '8': case '9':
+		return h - '0';
+	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+		return h - 'A' + 10;
+	case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+		return h - 'a' + 10;
+	default:
+		return 0;
+	}
+}
 
-static struct platform_device vlynq_high = {
-	.id = 1,
-	.name = "vlynq",
-	.dev.platform_data = &vlynq_high_data,
-	.resource = vlynq_high_res,
-	.num_resources = ARRAY_SIZE(vlynq_high_res),
+static void cpmac_get_mac(int instance, unsigned char *dev_addr)
+{
+	int i;
+	char name[5], default_mac[ETH_ALEN], *mac;
+
+	mac = NULL;
+	sprintf(name, "mac%c", 'a' + instance);
+	mac = prom_getenv(name);
+	if (!mac) {
+		sprintf(name, "mac%c", 'a');
+		mac = prom_getenv(name);
+	}
+	if (!mac) {
+		random_ether_addr(default_mac);
+		mac = default_mac;
+	}
+	for (i = 0; i < 6; i++)
+		dev_addr[i] = (char2hex(mac[i * 3]) << 4) +
+			char2hex(mac[i * 3 + 1]);
+}
+
+/*****************************************************************************
+ * USB
+ ****************************************************************************/
+static struct resource usb_res[] = {
+	{
+		.name	= "regs",
+		.flags	= IORESOURCE_MEM,
+		.start	= AR7_REGS_USB,
+		.end	= AR7_REGS_USB + 0xff,
+	},
+	{
+		.name	= "irq",
+		.flags	= IORESOURCE_IRQ,
+		.start	= 32,
+		.end	= 32,
+	},
+	{
+		.name	= "mem",
+		.flags	= IORESOURCE_MEM,
+		.start	= 0x03400000,
+		.end	= 0x03401fff,
+	},
 };
 
+static struct platform_device ar7_udc = {
+	.name		= "ar7_udc",
+	.resource	= usb_res,
+	.num_resources	= ARRAY_SIZE(usb_res),
+};
 
+/*****************************************************************************
+ * LEDs
+ ****************************************************************************/
 static struct gpio_led default_leds[] = {
 	{
-		.name = "status",
-		.gpio = 8,
-		.active_low = 1,
+		.name			= "status",
+		.gpio			= 8,
+		.active_low		= 1,
 	},
 };
 
 static struct gpio_led dsl502t_leds[] = {
 	{
-		.name = "status",
-		.gpio = 9,
-		.active_low = 1,
+		.name			= "status",
+		.gpio			= 9,
+		.active_low		= 1,
 	},
 	{
-		.name = "ethernet",
-		.gpio = 7,
-		.active_low = 1,
+		.name			= "ethernet",
+		.gpio			= 7,
+		.active_low		= 1,
 	},
 	{
-		.name = "usb",
-		.gpio = 12,
-		.active_low = 1,
+		.name			= "usb",
+		.gpio			= 12,
+		.active_low		= 1,
 	},
 };
 
 static struct gpio_led dg834g_leds[] = {
 	{
-		.name = "ppp",
-		.gpio = 6,
-		.active_low = 1,
+		.name			= "ppp",
+		.gpio			= 6,
+		.active_low		= 1,
 	},
 	{
-		.name = "status",
-		.gpio = 7,
-		.active_low = 1,
+		.name			= "status",
+		.gpio			= 7,
+		.active_low		= 1,
 	},
 	{
-		.name = "adsl",
-		.gpio = 8,
-		.active_low = 1,
+		.name			= "adsl",
+		.gpio			= 8,
+		.active_low		= 1,
 	},
 	{
-		.name = "wifi",
-		.gpio = 12,
-		.active_low = 1,
+		.name			= "wifi",
+		.gpio			= 12,
+		.active_low		= 1,
 	},
 	{
-		.name = "power",
-		.gpio = 14,
-		.active_low = 1,
-		.default_trigger = "default-on",
+		.name			= "power",
+		.gpio			= 14,
+		.active_low		= 1,
+		.default_trigger	= "default-on",
 	},
 };
 
 static struct gpio_led fb_sl_leds[] = {
 	{
-		.name = "1",
-		.gpio = 7,
+		.name			= "1",
+		.gpio			= 7,
 	},
 	{
-		.name = "2",
-		.gpio = 13,
-		.active_low = 1,
+		.name			= "2",
+		.gpio			= 13,
+		.active_low		= 1,
 	},
 	{
-		.name = "3",
-		.gpio = 10,
-		.active_low = 1,
+		.name			= "3",
+		.gpio			= 10,
+		.active_low		= 1,
 	},
 	{
-		.name = "4",
-		.gpio = 12,
-		.active_low = 1,
+		.name			= "4",
+		.gpio			= 12,
+		.active_low		= 1,
 	},
 	{
-		.name = "5",
-		.gpio = 9,
-		.active_low = 1,
+		.name			= "5",
+		.gpio			= 9,
+		.active_low		= 1,
 	},
 };
 
 static struct gpio_led fb_fon_leds[] = {
 	{
-		.name = "1",
-		.gpio = 8,
+		.name			= "1",
+		.gpio			= 8,
 	},
 	{
-		.name = "2",
-		.gpio = 3,
-		.active_low = 1,
+		.name			= "2",
+		.gpio			= 3,
+		.active_low		= 1,
 	},
 	{
-		.name = "3",
-		.gpio = 5,
+		.name			= "3",
+		.gpio			= 5,
 	},
 	{
-		.name = "4",
-		.gpio = 4,
-		.active_low = 1,
+		.name			= "4",
+		.gpio			= 4,
+		.active_low		= 1,
 	},
 	{
-		.name = "5",
-		.gpio = 11,
-		.active_low = 1,
+		.name			= "5",
+		.gpio			= 11,
+		.active_low		= 1,
 	},
 };
 
@@ -404,69 +473,11 @@ static struct gpio_led_platform_data ar7
 
 static struct platform_device ar7_gpio_leds = {
 	.name = "leds-gpio",
-	.id = -1,
 	.dev = {
 		.platform_data = &ar7_led_data,
 	}
 };
 
-static struct platform_device ar7_udc = {
-	.id = -1,
-	.name = "ar7_udc",
-	.resource = usb_res,
-	.num_resources = ARRAY_SIZE(usb_res),
-};
-
-static struct resource ar7_wdt_res = {
-	.name = "regs",
-	.start = -1, /* Filled at runtime */
-	.end = -1, /* Filled at runtime */
-	.flags = IORESOURCE_MEM,
-};
-
-static struct platform_device ar7_wdt = {
-	.id = -1,
-	.name  = "ar7_wdt",
-	.resource = &ar7_wdt_res,
-	.num_resources = 1,
-};
-
-static inline unsigned char char2hex(char h)
-{
-	switch (h) {
-	case '0': case '1': case '2': case '3': case '4':
-	case '5': case '6': case '7': case '8': case '9':
-		return h - '0';
-	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
-		return h - 'A' + 10;
-	case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
-		return h - 'a' + 10;
-	default:
-		return 0;
-	}
-}
-
-static void cpmac_get_mac(int instance, unsigned char *dev_addr)
-{
-	int i;
-	char name[5], default_mac[ETH_ALEN], *mac;
-
-	mac = NULL;
-	sprintf(name, "mac%c", 'a' + instance);
-	mac = prom_getenv(name);
-	if (!mac) {
-		sprintf(name, "mac%c", 'a');
-		mac = prom_getenv(name);
-	}
-	if (!mac) {
-		random_ether_addr(default_mac);
-		mac = default_mac;
-	}
-	for (i = 0; i < 6; i++)
-		dev_addr[i] = (char2hex(mac[i * 3]) << 4) +
-			char2hex(mac[i * 3 + 1]);
-}
-
 static void __init detect_leds(void)
 {
 	char *prid, *usb_prod;
@@ -499,111 +510,150 @@ static void __init detect_leds(void)
 	}
 }
 
-static int __init ar7_register_devices(void)
+/*****************************************************************************
+ * Watchdog
+ ****************************************************************************/
+static struct resource ar7_wdt_res = {
+	.name		= "regs",
+	.flags		= IORESOURCE_MEM,
+	.start		= -1,	/* Filled at runtime */
+	.end		= -1,	/* Filled at runtime */
+};
+
+static struct platform_device ar7_wdt = {
+	.name		= "ar7_wdt",
+	.resource	= &ar7_wdt_res,
+	.num_resources	= 1,
+};
+
+/*****************************************************************************
+ * Init
+ ****************************************************************************/
+static int __init ar7_register_uarts(void)
 {
-	u16 chip_id;
-	int res;
-	u32 *bootcr, val;
 #ifdef CONFIG_SERIAL_8250
-	static struct uart_port uart_port[2] __initdata;
+	static struct uart_port uart_port __initdata;
+	struct clk *bus_clk;
+	int res;
 
-	memset(uart_port, 0, sizeof(struct uart_port) * 2);
+	memset(&uart_port, 0, sizeof(struct uart_port));
 
-	uart_port[0].type = PORT_16550A;
-	uart_port[0].line = 0;
-	uart_port[0].irq = AR7_IRQ_UART0;
-	uart_port[0].uartclk = ar7_bus_freq() / 2;
-	uart_port[0].iotype = UPIO_MEM32;
-	uart_port[0].mapbase = AR7_REGS_UART0;
-	uart_port[0].membase = ioremap(uart_port[0].mapbase, 256);
-	uart_port[0].regshift = 2;
-	res = early_serial_setup(&uart_port[0]);
+	bus_clk = clk_get(NULL, "bus");
+	if (IS_ERR(bus_clk))
+		panic("unable to get bus clk\n");
+
+	uart_port.type		= PORT_16550A;
+	uart_port.uartclk	= clk_get_rate(bus_clk) / 2;
+	uart_port.iotype	= UPIO_MEM32;
+	uart_port.regshift	= 2;
+
+	uart_port.line		= 0;
+	uart_port.irq		= AR7_IRQ_UART0;
+	uart_port.mapbase	= AR7_REGS_UART0;
+	uart_port.membase	= ioremap(uart_port.mapbase, 256);
+
+	res = early_serial_setup(&uart_port);
 	if (res)
 		return res;
 
-
 	/* Only TNETD73xx have a second serial port */
 	if (ar7_has_second_uart()) {
-		uart_port[1].type = PORT_16550A;
-		uart_port[1].line = 1;
-		uart_port[1].irq = AR7_IRQ_UART1;
-		uart_port[1].uartclk = ar7_bus_freq() / 2;
-		uart_port[1].iotype = UPIO_MEM32;
-		uart_port[1].mapbase = UR8_REGS_UART1;
-		uart_port[1].membase = ioremap(uart_port[1].mapbase, 256);
-		uart_port[1].regshift = 2;
-		res = early_serial_setup(&uart_port[1]);
+		uart_port.line		= 1;
+		uart_port.irq		= AR7_IRQ_UART1;
+		uart_port.mapbase	= UR8_REGS_UART1;
+		uart_port.membase	= ioremap(uart_port.mapbase, 256);
+
+		res = early_serial_setup(&uart_port);
 		if (res)
 			return res;
 	}
-#endif /* CONFIG_SERIAL_8250 */
+#endif
+
+	return 0;
+}
+
+static int __init ar7_register_devices(void)
+{
+	void __iomem *bootcr;
+	u32 val;
+	u16 chip_id;
+	int res;
+
+	res = ar7_register_uarts();
+	if (res)
+		pr_err("unable to setup uart(s): %d\n", res);
+
 	res = platform_device_register(&physmap_flash);
 	if (res)
-		return res;
+		pr_warning("unable to register physmap-flash: %d\n", res);
 
 	ar7_device_disable(vlynq_low_data.reset_bit);
 	res = platform_device_register(&vlynq_low);
 	if (res)
-		return res;
+		pr_warning("unable to register vlynq-low: %d\n", res);
 
 	if (ar7_has_high_vlynq()) {
 		ar7_device_disable(vlynq_high_data.reset_bit);
 		res = platform_device_register(&vlynq_high);
 		if (res)
-			return res;
+			pr_warning("unable to register vlynq-high: %d\n", res);
 	}
 
 	if (ar7_has_high_cpmac()) {
 		res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status);
-		if (res && res != -ENODEV)
-			return res;
-		cpmac_get_mac(1, cpmac_high_data.dev_addr);
-		res = platform_device_register(&cpmac_high);
-		if (res)
-			return res;
-	} else {
+		if (!res) {
+			cpmac_get_mac(1, cpmac_high_data.dev_addr);
+
+			res = platform_device_register(&cpmac_high);
+			if (res)
+				pr_warning("unable to register cpmac-high: %d\n", res);
+		} else
+			pr_warning("unable to add cpmac-high phy: %d\n", res);
+	} else
 		cpmac_low_data.phy_mask = 0xffffffff;
-	}
 
 	res = fixed_phy_add(PHY_POLL, cpmac_low.id, &fixed_phy_status);
-	if (res && res != -ENODEV)
-		return res;
-
-	cpmac_get_mac(0, cpmac_low_data.dev_addr);
-	res = platform_device_register(&cpmac_low);
-	if (res)
-		return res;
+	if (!res) {
+		cpmac_get_mac(0, cpmac_low_data.dev_addr);
+		res = platform_device_register(&cpmac_low);
+		if (res)
+			pr_warning("unable to register cpmac-low: %d\n", res);
+	} else
+		pr_warning("unable to add cpmac-low phy: %d\n", res);
 
 	detect_leds();
 	res = platform_device_register(&ar7_gpio_leds);
 	if (res)
-		return res;
+		pr_warning("unable to register leds: %d\n", res);
 
 	res = platform_device_register(&ar7_udc);
+	if (res)
+		pr_warning("unable to register usb slave: %d\n", res);
 
-	chip_id = ar7_chip_id();
-	switch (chip_id) {
-	case AR7_CHIP_7100:
-	case AR7_CHIP_7200:
-		ar7_wdt_res.start = AR7_REGS_WDT;
-		break;
-	case AR7_CHIP_7300:
-		ar7_wdt_res.start = UR8_REGS_WDT;
-		break;
-	default:
-		break;
-	}
-
-	ar7_wdt_res.end = ar7_wdt_res.start + 0x20;
-
-	bootcr = (u32 *)ioremap_nocache(AR7_REGS_DCL, 4);
-	val = *bootcr;
+	/* Register watchdog only if enabled in hardware */
+	bootcr = ioremap_nocache(AR7_REGS_DCL, 4);
+	val = readl(bootcr);
 	iounmap(bootcr);
+	if (val & AR7_WDT_HW_ENA) {
+		chip_id = ar7_chip_id();
+		switch (chip_id) {
+		case AR7_CHIP_7100:
+		case AR7_CHIP_7200:
+			ar7_wdt_res.start = AR7_REGS_WDT;
+			break;
+		case AR7_CHIP_7300:
+			ar7_wdt_res.start = UR8_REGS_WDT;
+			break;
+		default:
+			break;
+		}
 
-	/* Register watchdog only if enabled in hardware */
-	if (val & AR7_WDT_HW_ENA)
+		ar7_wdt_res.end = ar7_wdt_res.start + 0x20;
 		res = platform_device_register(&ar7_wdt);
+		if (res)
+			pr_warning("unable to register watchdog: %d\n", res);
+	}
 
-	return res;
+	return 0;
 }
 arch_initcall(ar7_register_devices);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/ar7/prom.c linux-libre-2.6.34-gnu1/arch/mips/ar7/prom.c
--- linux-libre-2.6.33-gnu1/arch/mips/ar7/prom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/ar7/prom.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,8 +32,8 @@
 #define MAX_ENTRY 80
 
 struct env_var {
-	char *name;
-	char *value;
+	char	*name;
+	char	*value;
 };
 
 static struct env_var adam2_env[MAX_ENTRY];
@@ -41,6 +41,7 @@ static struct env_var adam2_env[MAX_ENTR
 char *prom_getenv(const char *name)
 {
 	int i;
+
 	for (i = 0; (i < MAX_ENTRY) && adam2_env[i].name; i++)
 		if (!strcmp(name, adam2_env[i].name))
 			return adam2_env[i].value;
@@ -49,65 +50,50 @@ char *prom_getenv(const char *name)
 }
 EXPORT_SYMBOL(prom_getenv);
 
-char * __init prom_getcmdline(void)
-{
-	return &(arcs_cmdline[0]);
-}
-
 static void  __init ar7_init_cmdline(int argc, char *argv[])
 {
-	char *cp;
-	int actr;
-
-	actr = 1; /* Always ignore argv[0] */
+	int i;
 
-	cp = &(arcs_cmdline[0]);
-	while (actr < argc) {
-		strcpy(cp, argv[actr]);
-		cp += strlen(argv[actr]);
-		*cp++ = ' ';
-		actr++;
-	}
-	if (cp != &(arcs_cmdline[0])) {
-		/* get rid of trailing space */
-		--cp;
-		*cp = '\0';
+	for (i = 1; i < argc; i++) {
+		strlcat(arcs_cmdline, argv[i], COMMAND_LINE_SIZE);
+		if (i < (argc - 1))
+			strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
 	}
 }
 
 struct psbl_rec {
-	u32 psbl_size;
-	u32 env_base;
-	u32 env_size;
-	u32 ffs_base;
-	u32 ffs_size;
+	u32	psbl_size;
+	u32	env_base;
+	u32	env_size;
+	u32	ffs_base;
+	u32	ffs_size;
 };
 
 static __initdata char psp_env_version[] = "TIENV0.8";
 
 struct psp_env_chunk {
-	u8 num;
-	u8 ctrl;
-	u16 csum;
-	u8 len;
-	char data[11];
+	u8	num;
+	u8	ctrl;
+	u16	csum;
+	u8	len;
+	char	data[11];
 } __attribute__ ((packed));
 
 struct psp_var_map_entry {
-	u8 num;
-	char *value;
+	u8	num;
+	char	*value;
 };
 
 static struct psp_var_map_entry psp_var_map[] = {
-	{ 1, "cpufrequency" },
-	{ 2, "memsize" },
-	{ 3, "flashsize" },
-	{ 4, "modetty0" },
-	{ 5, "modetty1" },
-	{ 8, "maca" },
-	{ 9, "macb" },
-	{ 28, "sysfrequency" },
-	{ 38, "mipsfrequency" },
+	{  1,	"cpufrequency" },
+	{  2,	"memsize" },
+	{  3,	"flashsize" },
+	{  4,	"modetty0" },
+	{  5,	"modetty1" },
+	{  8,	"maca" },
+	{  9,	"macb" },
+	{ 28,	"sysfrequency" },
+	{ 38,	"mipsfrequency" },
 };
 
 /*
@@ -154,6 +140,7 @@ static char * __init lookup_psp_var_map(
 static void __init add_adam2_var(char *name, char *value)
 {
 	int i;
+
 	for (i = 0; i < MAX_ENTRY; i++) {
 		if (!adam2_env[i].name) {
 			adam2_env[i].name = name;
@@ -216,7 +203,7 @@ static void __init console_config(void)
 	char parity = '\0', bits = '\0', flow = '\0';
 	char *s, *p;
 
-	if (strstr(prom_getcmdline(), "console="))
+	if (strstr(arcs_cmdline, "console="))
 		return;
 
 	s = prom_getenv("modetty0");
@@ -250,7 +237,7 @@ static void __init console_config(void)
 	else
 		sprintf(console_string, " console=ttyS0,%d%c%c", baud, parity,
 			bits);
-	strcat(prom_getcmdline(), console_string);
+	strlcat(arcs_cmdline, console_string, COMMAND_LINE_SIZE);
 #endif
 }
 
@@ -279,4 +266,3 @@ int prom_putchar(char c)
 	serial_out(UART_TX, c);
 	return 1;
 }
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/ar7/setup.c linux-libre-2.6.34-gnu1/arch/mips/ar7/setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/ar7/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/ar7/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,8 +26,8 @@
 
 static void ar7_machine_restart(char *command)
 {
-	u32 *softres_reg = ioremap(AR7_REGS_RESET +
-					  AR7_RESET_SOFTWARE, 1);
+	u32 *softres_reg = ioremap(AR7_REGS_RESET + AR7_RESET_SOFTWARE, 1);
+
 	writel(1, softres_reg);
 }
 
@@ -41,6 +41,7 @@ static void ar7_machine_power_off(void)
 {
 	u32 *power_reg = (u32 *)ioremap(AR7_REGS_POWER, 1);
 	u32 power_state = readl(power_reg) | (3 << 30);
+
 	writel(power_state, power_reg);
 	ar7_machine_halt();
 }
@@ -49,14 +50,14 @@ const char *get_system_type(void)
 {
 	u16 chip_id = ar7_chip_id();
 	switch (chip_id) {
-	case AR7_CHIP_7300:
-		return "TI AR7 (TNETD7300)";
 	case AR7_CHIP_7100:
 		return "TI AR7 (TNETD7100)";
 	case AR7_CHIP_7200:
 		return "TI AR7 (TNETD7200)";
+	case AR7_CHIP_7300:
+		return "TI AR7 (TNETD7300)";
 	default:
-		return "TI AR7 (Unknown)";
+		return "TI AR7 (unknown)";
 	}
 }
 
@@ -70,7 +71,6 @@ console_initcall(ar7_init_console);
  * Initializes basic routines and structures pointers, memory size (as
  * given by the bios and saves the command line.
  */
-
 void __init plat_mem_setup(void)
 {
 	unsigned long io_base;
@@ -88,6 +88,5 @@ void __init plat_mem_setup(void)
 	prom_meminit();
 
 	printk(KERN_INFO "%s, ID: 0x%04x, Revision: 0x%02x\n",
-					get_system_type(),
-		ar7_chip_id(), ar7_chip_rev());
+			get_system_type(), ar7_chip_id(), ar7_chip_rev());
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/ar7/time.c linux-libre-2.6.34-gnu1/arch/mips/ar7/time.c
--- linux-libre-2.6.33-gnu1/arch/mips/ar7/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/ar7/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,11 +20,21 @@
 
 #include <linux/init.h>
 #include <linux/time.h>
+#include <linux/err.h>
+#include <linux/clk.h>
 
 #include <asm/time.h>
 #include <asm/mach-ar7/ar7.h>
 
 void __init plat_time_init(void)
 {
-	mips_hpt_frequency = ar7_cpu_freq() / 2;
+	struct clk *cpu_clk;
+
+	cpu_clk = clk_get(NULL, "cpu");
+	if (IS_ERR(cpu_clk)) {
+		printk(KERN_ERR "unable to get cpu clock\n");
+		return;
+	}
+
+	mips_hpt_frequency = clk_get_rate(cpu_clk) / 2;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/bcm47xx/gpio.c linux-libre-2.6.34-gnu1/arch/mips/bcm47xx/gpio.c
--- linux-libre-2.6.33-gnu1/arch/mips/bcm47xx/gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/bcm47xx/gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -59,4 +59,3 @@ int gpio_to_irq(unsigned gpio)
 		return -EINVAL;
 }
 EXPORT_SYMBOL_GPL(gpio_to_irq);
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/bcm47xx/prom.c linux-libre-2.6.34-gnu1/arch/mips/bcm47xx/prom.c
--- linux-libre-2.6.33-gnu1/arch/mips/bcm47xx/prom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/bcm47xx/prom.c	2010-05-16 17:17:36.000000000 -0400
@@ -163,4 +163,3 @@ void __init prom_init(void)
 void __init prom_free_prom_memory(void)
 {
 }
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/bcm47xx/setup.c linux-libre-2.6.34-gnu1/arch/mips/bcm47xx/setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/bcm47xx/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/bcm47xx/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -121,4 +121,3 @@ void __init plat_mem_setup(void)
 	_machine_halt = bcm47xx_machine_halt;
 	pm_power_off = bcm47xx_machine_halt;
 }
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/bcm47xx/wgt634u.c linux-libre-2.6.34-gnu1/arch/mips/bcm47xx/wgt634u.c
--- linux-libre-2.6.33-gnu1/arch/mips/bcm47xx/wgt634u.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/bcm47xx/wgt634u.c	2010-05-16 17:17:36.000000000 -0400
@@ -164,4 +164,3 @@ static int __init wgt634u_init(void)
 }
 
 module_init(wgt634u_init);
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/bcm63xx/boards/board_bcm963xx.c linux-libre-2.6.34-gnu1/arch/mips/bcm63xx/boards/board_bcm963xx.c
--- linux-libre-2.6.33-gnu1/arch/mips/bcm63xx/boards/board_bcm963xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/bcm63xx/boards/board_bcm963xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <asm/addrspace.h>
 #include <bcm63xx_board.h>
 #include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_uart.h>
 #include <bcm63xx_regs.h>
 #include <bcm63xx_io.h>
 #include <bcm63xx_dev_pci.h>
@@ -40,6 +41,7 @@ static struct board_info __initdata boar
 	.name				= "96338GW",
 	.expected_cpu_id		= 0x6338,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.enet0 = {
 		.force_speed_100	= 1,
@@ -82,6 +84,7 @@ static struct board_info __initdata boar
 	.name				= "96338W",
 	.expected_cpu_id		= 0x6338,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.enet0 = {
 		.force_speed_100	= 1,
@@ -126,6 +129,8 @@ static struct board_info __initdata boar
 static struct board_info __initdata board_96345gw2 = {
 	.name				= "96345GW2",
 	.expected_cpu_id		= 0x6345,
+
+	.has_uart0			= 1,
 };
 #endif
 
@@ -137,6 +142,7 @@ static struct board_info __initdata boar
 	.name				= "96348R",
 	.expected_cpu_id		= 0x6348,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_pci			= 1,
 
@@ -180,6 +186,7 @@ static struct board_info __initdata boar
 	.name				= "96348GW-10",
 	.expected_cpu_id		= 0x6348,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
@@ -239,6 +246,7 @@ static struct board_info __initdata boar
 	.name				= "96348GW-11",
 	.expected_cpu_id		= 0x6348,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
@@ -292,6 +300,7 @@ static struct board_info __initdata boar
 	.name				= "96348GW",
 	.expected_cpu_id		= 0x6348,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
@@ -349,9 +358,10 @@ static struct board_info __initdata boar
 	.name				= "F@ST2404",
 	.expected_cpu_id		= 0x6348,
 
-	.has_enet0			= 1,
-	.has_enet1			= 1,
-	.has_pci			= 1,
+	.has_uart0			= 1,
+        .has_enet0			= 1,
+        .has_enet1			= 1,
+        .has_pci			= 1,
 
 	.enet0 = {
 		.has_phy		= 1,
@@ -368,10 +378,30 @@ static struct board_info __initdata boar
 	.has_ehci0			= 1,
 };
 
+static struct board_info __initdata board_rta1025w_16 = {
+	.name				= "RTA1025W_16",
+	.expected_cpu_id		= 0x6348,
+
+	.has_enet0			= 1,
+	.has_enet1			= 1,
+	.has_pci			= 1,
+
+	.enet0 = {
+		.has_phy		= 1,
+		.use_internal_phy	= 1,
+	},
+	.enet1 = {
+		.force_speed_100	= 1,
+		.force_duplex_full	= 1,
+	},
+};
+
+
 static struct board_info __initdata board_DV201AMR = {
 	.name				= "DV201AMR",
 	.expected_cpu_id		= 0x6348,
 
+	.has_uart0			= 1,
 	.has_pci			= 1,
 	.has_ohci0			= 1,
 
@@ -391,6 +421,7 @@ static struct board_info __initdata boar
 	.name				= "96348GW-A",
 	.expected_cpu_id		= 0x6348,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
@@ -416,6 +447,7 @@ static struct board_info __initdata boar
 	.name				= "96358VW",
 	.expected_cpu_id		= 0x6358,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
@@ -467,6 +499,7 @@ static struct board_info __initdata boar
 	.name				= "96358VW2",
 	.expected_cpu_id		= 0x6358,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
@@ -514,6 +547,7 @@ static struct board_info __initdata boar
 	.name                           = "AGPF-S0",
 	.expected_cpu_id                = 0x6358,
 
+	.has_uart0			= 1,
 	.has_enet0                      = 1,
 	.has_enet1                      = 1,
 	.has_pci                        = 1,
@@ -531,6 +565,27 @@ static struct board_info __initdata boar
 	.has_ohci0 = 1,
 	.has_ehci0 = 1,
 };
+
+static struct board_info __initdata board_DWVS0 = {
+	.name				= "DWV-S0",
+	.expected_cpu_id		= 0x6358,
+
+	.has_enet0			= 1,
+	.has_enet1			= 1,
+	.has_pci			= 1,
+
+	.enet0 = {
+		.has_phy		= 1,
+		.use_internal_phy	= 1,
+	},
+
+	.enet1 = {
+		.force_speed_100	= 1,
+		.force_duplex_full	= 1,
+	},
+
+	.has_ohci0			= 1,
+};
 #endif
 
 /*
@@ -552,16 +607,88 @@ static const struct board_info __initdat
 	&board_FAST2404,
 	&board_DV201AMR,
 	&board_96348gw_a,
+	&board_rta1025w_16,
 #endif
 
 #ifdef CONFIG_BCM63XX_CPU_6358
 	&board_96358vw,
 	&board_96358vw2,
 	&board_AGPFS0,
+	&board_DWVS0,
 #endif
 };
 
 /*
+ * Register a sane SPROMv2 to make the on-board
+ * bcm4318 WLAN work
+ */
+#ifdef CONFIG_SSB_PCIHOST
+static struct ssb_sprom bcm63xx_sprom = {
+	.revision		= 0x02,
+	.board_rev		= 0x17,
+	.country_code		= 0x0,
+	.ant_available_bg 	= 0x3,
+	.pa0b0			= 0x15ae,
+	.pa0b1			= 0xfa85,
+	.pa0b2			= 0xfe8d,
+	.pa1b0			= 0xffff,
+	.pa1b1			= 0xffff,
+	.pa1b2			= 0xffff,
+	.gpio0			= 0xff,
+	.gpio1			= 0xff,
+	.gpio2			= 0xff,
+	.gpio3			= 0xff,
+	.maxpwr_bg		= 0x004c,
+	.itssi_bg		= 0x00,
+	.boardflags_lo		= 0x2848,
+	.boardflags_hi		= 0x0000,
+};
+#endif
+
+/*
+ * return board name for /proc/cpuinfo
+ */
+const char *board_get_name(void)
+{
+	return board.name;
+}
+
+/*
+ * register & return a new board mac address
+ */
+static int board_get_mac_address(u8 *mac)
+{
+	u8 *p;
+	int count;
+
+	if (mac_addr_used >= nvram.mac_addr_count) {
+		printk(KERN_ERR PFX "not enough mac address\n");
+		return -ENODEV;
+	}
+
+	memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
+	p = mac + ETH_ALEN - 1;
+	count = mac_addr_used;
+
+	while (count--) {
+		do {
+			(*p)++;
+			if (*p != 0)
+				break;
+			p--;
+		} while (p != mac);
+	}
+
+	if (p == mac) {
+		printk(KERN_ERR PFX "unable to fetch mac address\n");
+		return -ENODEV;
+	}
+
+	mac_addr_used++;
+	return 0;
+}
+
+/*
  * early init callback, read nvram data from flash and checksum it
  */
 void __init board_prom_init(void)
@@ -659,6 +786,17 @@ void __init board_prom_init(void)
 	}
 
 	bcm_gpio_writel(val, GPIO_MODE_REG);
+
+	/* Generate MAC address for WLAN and
+	 * register our SPROM */
+#ifdef CONFIG_SSB_PCIHOST
+	if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
+		memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+		memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+		if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
+			printk(KERN_ERR "failed to register fallback SPROM\n");
+	}
+#endif
 }
 
 /*
@@ -676,49 +814,6 @@ void __init board_setup(void)
 		panic("unexpected CPU for bcm963xx board");
 }
 
-/*
- * return board name for /proc/cpuinfo
- */
-const char *board_get_name(void)
-{
-	return board.name;
-}
-
-/*
- * register & return a new board mac address
- */
-static int board_get_mac_address(u8 *mac)
-{
-	u8 *p;
-	int count;
-
-	if (mac_addr_used >= nvram.mac_addr_count) {
-		printk(KERN_ERR PFX "not enough mac address\n");
-		return -ENODEV;
-	}
-
-	memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
-	p = mac + ETH_ALEN - 1;
-	count = mac_addr_used;
-
-	while (count--) {
-		do {
-			(*p)++;
-			if (*p != 0)
-				break;
-			p--;
-		} while (p != mac);
-	}
-
-	if (p == mac) {
-		printk(KERN_ERR PFX "unable to fetch mac address\n");
-		return -ENODEV;
-	}
-
-	mac_addr_used++;
-	return 0;
-}
-
 static struct mtd_partition mtd_partitions[] = {
 	{
 		.name		= "cfe",
@@ -750,33 +845,6 @@ static struct platform_device mtd_dev =
 	},
 };
 
-/*
- * Register a sane SPROMv2 to make the on-board
- * bcm4318 WLAN work
- */
-#ifdef CONFIG_SSB_PCIHOST
-static struct ssb_sprom bcm63xx_sprom = {
-	.revision		= 0x02,
-	.board_rev		= 0x17,
-	.country_code		= 0x0,
-	.ant_available_bg 	= 0x3,
-	.pa0b0			= 0x15ae,
-	.pa0b1			= 0xfa85,
-	.pa0b2			= 0xfe8d,
-	.pa1b0			= 0xffff,
-	.pa1b1			= 0xffff,
-	.pa1b2			= 0xffff,
-	.gpio0			= 0xff,
-	.gpio1			= 0xff,
-	.gpio2			= 0xff,
-	.gpio3			= 0xff,
-	.maxpwr_bg		= 0x004c,
-	.itssi_bg		= 0x00,
-	.boardflags_lo		= 0x2848,
-	.boardflags_hi		= 0x0000,
-};
-#endif
-
 static struct gpio_led_platform_data bcm63xx_led_data;
 
 static struct platform_device bcm63xx_gpio_leds = {
@@ -792,6 +860,12 @@ int __init board_register_devices(void)
 {
 	u32 val;
 
+	if (board.has_uart0)
+		bcm63xx_uart_register(0);
+
+	if (board.has_uart1)
+		bcm63xx_uart_register(1);
+
 	if (board.has_pccard)
 		bcm63xx_pcmcia_register();
 
@@ -806,17 +880,6 @@ int __init board_register_devices(void)
 	if (board.has_dsp)
 		bcm63xx_dsp_register(&board.dsp);
 
-	/* Generate MAC address for WLAN and
-	 * register our SPROM */
-#ifdef CONFIG_SSB_PCIHOST
-	if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
-		memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
-		memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
-		if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
-			printk(KERN_ERR "failed to register fallback SPROM\n");
-	}
-#endif
-
 	/* read base address of boot chip select (0) */
 	if (BCMCPU_IS_6345())
 		val = 0x1fc00000;
@@ -836,4 +899,3 @@ int __init board_register_devices(void)
 
 	return 0;
 }
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/bcm63xx/cpu.c linux-libre-2.6.34-gnu1/arch/mips/bcm63xx/cpu.c
--- linux-libre-2.6.33-gnu1/arch/mips/bcm63xx/cpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/bcm63xx/cpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@ static const unsigned long bcm96338_regs
 	[RSET_TIMER]		= BCM_6338_TIMER_BASE,
 	[RSET_WDT]		= BCM_6338_WDT_BASE,
 	[RSET_UART0]		= BCM_6338_UART0_BASE,
+	[RSET_UART1]		= BCM_6338_UART1_BASE,
 	[RSET_GPIO]		= BCM_6338_GPIO_BASE,
 	[RSET_SPI]		= BCM_6338_SPI_BASE,
 	[RSET_OHCI0]		= BCM_6338_OHCI0_BASE,
@@ -72,6 +73,7 @@ static const unsigned long bcm96345_regs
 	[RSET_TIMER]		= BCM_6345_TIMER_BASE,
 	[RSET_WDT]		= BCM_6345_WDT_BASE,
 	[RSET_UART0]		= BCM_6345_UART0_BASE,
+	[RSET_UART1]		= BCM_6345_UART1_BASE,
 	[RSET_GPIO]		= BCM_6345_GPIO_BASE,
 	[RSET_SPI]		= BCM_6345_SPI_BASE,
 	[RSET_UDC0]		= BCM_6345_UDC0_BASE,
@@ -109,6 +111,7 @@ static const unsigned long bcm96348_regs
 	[RSET_TIMER]		= BCM_6348_TIMER_BASE,
 	[RSET_WDT]		= BCM_6348_WDT_BASE,
 	[RSET_UART0]		= BCM_6348_UART0_BASE,
+	[RSET_UART1]		= BCM_6348_UART1_BASE,
 	[RSET_GPIO]		= BCM_6348_GPIO_BASE,
 	[RSET_SPI]		= BCM_6348_SPI_BASE,
 	[RSET_OHCI0]		= BCM_6348_OHCI0_BASE,
@@ -150,6 +153,7 @@ static const unsigned long bcm96358_regs
 	[RSET_TIMER]		= BCM_6358_TIMER_BASE,
 	[RSET_WDT]		= BCM_6358_WDT_BASE,
 	[RSET_UART0]		= BCM_6358_UART0_BASE,
+	[RSET_UART1]		= BCM_6358_UART1_BASE,
 	[RSET_GPIO]		= BCM_6358_GPIO_BASE,
 	[RSET_SPI]		= BCM_6358_SPI_BASE,
 	[RSET_OHCI0]		= BCM_6358_OHCI0_BASE,
@@ -170,6 +174,7 @@ static const unsigned long bcm96358_regs
 static const int bcm96358_irqs[] = {
 	[IRQ_TIMER]		= BCM_6358_TIMER_IRQ,
 	[IRQ_UART0]		= BCM_6358_UART0_IRQ,
+	[IRQ_UART1]		= BCM_6358_UART1_IRQ,
 	[IRQ_DSL]		= BCM_6358_DSL_IRQ,
 	[IRQ_ENET0]		= BCM_6358_ENET0_IRQ,
 	[IRQ_ENET1]		= BCM_6358_ENET1_IRQ,
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/bcm63xx/dev-uart.c linux-libre-2.6.34-gnu1/arch/mips/bcm63xx/dev-uart.c
--- linux-libre-2.6.33-gnu1/arch/mips/bcm63xx/dev-uart.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/bcm63xx/dev-uart.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,31 +11,65 @@
 #include <linux/platform_device.h>
 #include <bcm63xx_cpu.h>
 
-static struct resource uart_resources[] = {
+static struct resource uart0_resources[] = {
 	{
-		.start		= -1, /* filled at runtime */
-		.end		= -1, /* filled at runtime */
+		/* start & end filled at runtime */
 		.flags		= IORESOURCE_MEM,
 	},
 	{
-		.start		= -1, /* filled at runtime */
+		/* start filled at runtime */
 		.flags		= IORESOURCE_IRQ,
 	},
 };
 
-static struct platform_device bcm63xx_uart_device = {
-	.name		= "bcm63xx_uart",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(uart_resources),
-	.resource	= uart_resources,
+static struct resource uart1_resources[] = {
+	{
+		/* start & end filled at runtime */
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		/* start filled at runtime */
+		.flags		= IORESOURCE_IRQ,
+	},
 };
 
-int __init bcm63xx_uart_register(void)
+static struct platform_device bcm63xx_uart_devices[] = {
+	{
+		.name		= "bcm63xx_uart",
+		.id		= 0,
+		.num_resources	= ARRAY_SIZE(uart0_resources),
+		.resource	= uart0_resources,
+	},
+
+	{
+		.name		= "bcm63xx_uart",
+		.id		= 1,
+		.num_resources	= ARRAY_SIZE(uart1_resources),
+		.resource	= uart1_resources,
+	}
+};
+
+int __init bcm63xx_uart_register(unsigned int id)
 {
-	uart_resources[0].start = bcm63xx_regset_address(RSET_UART0);
-	uart_resources[0].end = uart_resources[0].start;
-	uart_resources[0].end += RSET_UART_SIZE - 1;
-	uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
-	return platform_device_register(&bcm63xx_uart_device);
+	if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
+		return -ENODEV;
+
+	if (id == 1 && !BCMCPU_IS_6358())
+		return -ENODEV;
+
+	if (id == 0) {
+		uart0_resources[0].start = bcm63xx_regset_address(RSET_UART0);
+		uart0_resources[0].end = uart0_resources[0].start +
+			RSET_UART_SIZE - 1;
+		uart0_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
+	}
+
+	if (id == 1) {
+		uart1_resources[0].start = bcm63xx_regset_address(RSET_UART1);
+		uart1_resources[0].end = uart1_resources[0].start +
+			RSET_UART_SIZE - 1;
+		uart1_resources[1].start = bcm63xx_get_irq_number(IRQ_UART1);
+	}
+
+	return platform_device_register(&bcm63xx_uart_devices[id]);
 }
-arch_initcall(bcm63xx_uart_register);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/bcm63xx/gpio.c linux-libre-2.6.34-gnu1/arch/mips/bcm63xx/gpio.c
--- linux-libre-2.6.33-gnu1/arch/mips/bcm63xx/gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/bcm63xx/gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -125,10 +125,10 @@ static struct gpio_chip bcm63xx_gpio_chi
 
 int __init bcm63xx_gpio_init(void)
 {
+	gpio_out_low = bcm_gpio_readl(GPIO_DATA_LO_REG);
+	gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG);
 	bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
 	pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
 
 	return gpiochip_add(&bcm63xx_gpio_chip);
 }
-
-arch_initcall(bcm63xx_gpio_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/bcm63xx/timer.c linux-libre-2.6.34-gnu1/arch/mips/bcm63xx/timer.c
--- linux-libre-2.6.33-gnu1/arch/mips/bcm63xx/timer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/bcm63xx/timer.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,8 +17,8 @@
 #include <bcm63xx_timer.h>
 #include <bcm63xx_regs.h>
 
-static DEFINE_SPINLOCK(timer_reg_lock);
-static DEFINE_SPINLOCK(timer_data_lock);
+static DEFINE_RAW_SPINLOCK(timer_reg_lock);
+static DEFINE_RAW_SPINLOCK(timer_data_lock);
 static struct clk *periph_clk;
 
 static struct timer_data {
@@ -31,23 +31,23 @@ static irqreturn_t timer_interrupt(int i
 	u32 stat;
 	int i;
 
-	spin_lock(&timer_reg_lock);
+	raw_spin_lock(&timer_reg_lock);
 	stat = bcm_timer_readl(TIMER_IRQSTAT_REG);
 	bcm_timer_writel(stat, TIMER_IRQSTAT_REG);
-	spin_unlock(&timer_reg_lock);
+	raw_spin_unlock(&timer_reg_lock);
 
 	for (i = 0; i < BCM63XX_TIMER_COUNT; i++) {
 		if (!(stat & TIMER_IRQSTAT_TIMER_CAUSE(i)))
 			continue;
 
-		spin_lock(&timer_data_lock);
+		raw_spin_lock(&timer_data_lock);
 		if (!timer_data[i].cb) {
-			spin_unlock(&timer_data_lock);
+			raw_spin_unlock(&timer_data_lock);
 			continue;
 		}
 
 		timer_data[i].cb(timer_data[i].data);
-		spin_unlock(&timer_data_lock);
+		raw_spin_unlock(&timer_data_lock);
 	}
 
 	return IRQ_HANDLED;
@@ -61,7 +61,7 @@ int bcm63xx_timer_enable(int id)
 	if (id >= BCM63XX_TIMER_COUNT)
 		return -EINVAL;
 
-	spin_lock_irqsave(&timer_reg_lock, flags);
+	raw_spin_lock_irqsave(&timer_reg_lock, flags);
 
 	reg = bcm_timer_readl(TIMER_CTLx_REG(id));
 	reg |= TIMER_CTL_ENABLE_MASK;
@@ -71,7 +71,7 @@ int bcm63xx_timer_enable(int id)
 	reg |= TIMER_IRQSTAT_TIMER_IR_EN(id);
 	bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
 
-	spin_unlock_irqrestore(&timer_reg_lock, flags);
+	raw_spin_unlock_irqrestore(&timer_reg_lock, flags);
 	return 0;
 }
 
@@ -85,7 +85,7 @@ int bcm63xx_timer_disable(int id)
 	if (id >= BCM63XX_TIMER_COUNT)
 		return -EINVAL;
 
-	spin_lock_irqsave(&timer_reg_lock, flags);
+	raw_spin_lock_irqsave(&timer_reg_lock, flags);
 
 	reg = bcm_timer_readl(TIMER_CTLx_REG(id));
 	reg &= ~TIMER_CTL_ENABLE_MASK;
@@ -95,7 +95,7 @@ int bcm63xx_timer_disable(int id)
 	reg &= ~TIMER_IRQSTAT_TIMER_IR_EN(id);
 	bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
 
-	spin_unlock_irqrestore(&timer_reg_lock, flags);
+	raw_spin_unlock_irqrestore(&timer_reg_lock, flags);
 	return 0;
 }
 
@@ -110,7 +110,7 @@ int bcm63xx_timer_register(int id, void
 		return -EINVAL;
 
 	ret = 0;
-	spin_lock_irqsave(&timer_data_lock, flags);
+	raw_spin_lock_irqsave(&timer_data_lock, flags);
 	if (timer_data[id].cb) {
 		ret = -EBUSY;
 		goto out;
@@ -120,7 +120,7 @@ int bcm63xx_timer_register(int id, void
 	timer_data[id].data = data;
 
 out:
-	spin_unlock_irqrestore(&timer_data_lock, flags);
+	raw_spin_unlock_irqrestore(&timer_data_lock, flags);
 	return ret;
 }
 
@@ -133,9 +133,9 @@ void bcm63xx_timer_unregister(int id)
 	if (id >= BCM63XX_TIMER_COUNT)
 		return;
 
-	spin_lock_irqsave(&timer_data_lock, flags);
+	raw_spin_lock_irqsave(&timer_data_lock, flags);
 	timer_data[id].cb = NULL;
-	spin_unlock_irqrestore(&timer_data_lock, flags);
+	raw_spin_unlock_irqrestore(&timer_data_lock, flags);
 }
 
 EXPORT_SYMBOL(bcm63xx_timer_unregister);
@@ -159,7 +159,7 @@ int bcm63xx_timer_set(int id, int monoto
 	if (countdown & ~TIMER_CTL_COUNTDOWN_MASK)
 		return -EINVAL;
 
-	spin_lock_irqsave(&timer_reg_lock, flags);
+	raw_spin_lock_irqsave(&timer_reg_lock, flags);
 	reg = bcm_timer_readl(TIMER_CTLx_REG(id));
 
 	if (monotonic)
@@ -171,7 +171,7 @@ int bcm63xx_timer_set(int id, int monoto
 	reg |= countdown;
 	bcm_timer_writel(reg, TIMER_CTLx_REG(id));
 
-	spin_unlock_irqrestore(&timer_reg_lock, flags);
+	raw_spin_unlock_irqrestore(&timer_reg_lock, flags);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/dbg.c linux-libre-2.6.34-gnu1/arch/mips/boot/compressed/dbg.c
--- linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/dbg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/boot/compressed/dbg.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,11 +5,11 @@
  * please select SYS_SUPPORTS_ZBOOT_UART16550 for your machine. othewise, you
  * need to implement your own putc().
  */
-
+#include <linux/compiler.h>
 #include <linux/init.h>
 #include <linux/types.h>
 
-void __attribute__ ((weak)) putc(char c)
+void __weak putc(char c)
 {
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/decompress.c linux-libre-2.6.34-gnu1/arch/mips/boot/compressed/decompress.c
--- linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/decompress.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/boot/compressed/decompress.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,8 +5,8 @@
  * Author: Matt Porter <mporter@mvista.com> Derived from
  * arch/ppc/boot/prep/misc.c
  *
- * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
- * Author: Wu Zhangjin <wuzj@lemote.com>
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin <wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/Makefile linux-libre-2.6.34-gnu1/arch/mips/boot/compressed/Makefile
--- linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/boot/compressed/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,7 @@
 # modified by Cort (cort@cs.nmt.edu)
 #
 # Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University
-# Author: Wu Zhangjin <wuzj@lemote.com>
+# Author: Wu Zhangjin <wuzhangjin@gmail.com>
 #
 
 # compressed kernel load addr: VMLINUZ_LOAD_ADDRESS > VMLINUX_LOAD_ADDRESS + VMLINUX_SIZE
@@ -27,15 +27,18 @@ BOOT_HEAP_SIZE := 0x400000
 KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//")
 
 KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \
-	-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" \
+	-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull"
 
 KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
-	-DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ ) \
-	-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE)
+	-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
+	-DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ )
 
 obj-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o
 
+ifdef CONFIG_DEBUG_ZBOOT
 obj-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
+obj-$(CONFIG_MACH_ALCHEMY)		   += $(obj)/uart-alchemy.o
+endif
 
 OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
 $(obj)/vmlinux.bin: $(KBUILD_IMAGE)
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/uart-alchemy.c linux-libre-2.6.34-gnu1/arch/mips/boot/compressed/uart-alchemy.c
--- linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/uart-alchemy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/boot/compressed/uart-alchemy.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,7 @@
+#include <asm/mach-au1x00/au1000.h>
+
+void putc(char c)
+{
+	/* all current (Jan. 2010) in-kernel boards */
+	alchemy_uart_putchar(UART0_PHYS_ADDR, c);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/dma-octeon.c linux-libre-2.6.34-gnu1/arch/mips/cavium-octeon/dma-octeon.c
--- linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/dma-octeon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/cavium-octeon/dma-octeon.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,7 @@ struct bar1_index_state {
 };
 
 #ifdef CONFIG_PCI
-static DEFINE_SPINLOCK(bar1_lock);
+static DEFINE_RAW_SPINLOCK(bar1_lock);
 static struct bar1_index_state bar1_state[32];
 #endif
 
@@ -198,7 +198,7 @@ dma_addr_t octeon_map_dma_mem(struct dev
 		start_index = 31;
 
 	/* Only one processor can access the Bar register at once */
-	spin_lock_irqsave(&bar1_lock, flags);
+	raw_spin_lock_irqsave(&bar1_lock, flags);
 
 	/* Look through Bar1 for existing mapping that will work */
 	for (index = start_index; index >= 0; index--) {
@@ -250,7 +250,7 @@ dma_addr_t octeon_map_dma_mem(struct dev
 	       (unsigned long long) physical);
 
 done_unlock:
-	spin_unlock_irqrestore(&bar1_lock, flags);
+	raw_spin_unlock_irqrestore(&bar1_lock, flags);
 done:
 	pr_debug("dma_map_single 0x%llx->0x%llx\n", physical, result);
 	return result;
@@ -324,14 +324,14 @@ void octeon_unmap_dma_mem(struct device
 		      "Attempt to unmap an invalid address (0x%llx)\n",
 		      dma_addr);
 
-	spin_lock_irqsave(&bar1_lock, flags);
+	raw_spin_lock_irqsave(&bar1_lock, flags);
 	bar1_state[index].ref_count--;
 	if (bar1_state[index].ref_count == 0)
 		octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), 0);
 	else if (unlikely(bar1_state[index].ref_count < 0))
 		panic("dma_unmap_single: Bar1[%u] reference count < 0\n",
 		      (int) index);
-	spin_unlock_irqrestore(&bar1_lock, flags);
+	raw_spin_unlock_irqrestore(&bar1_lock, flags);
 done:
 	pr_debug("dma_unmap_single 0x%llx\n", dma_addr);
 	return;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/executive/cvmx-bootmem.c linux-libre-2.6.34-gnu1/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
--- linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/executive/cvmx-bootmem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/cavium-octeon/executive/cvmx-bootmem.c	2010-05-16 17:17:36.000000000 -0400
@@ -253,7 +253,7 @@ int64_t cvmx_bootmem_phy_alloc(uint64_t
 	 * impossible requests up front. (NOP for address_min == 0)
 	 */
 	if (alignment)
-		address_min = __ALIGN_MASK(address_min, (alignment - 1));
+		address_min = ALIGN(address_min, alignment);
 
 	/*
 	 * Reject inconsistent args.  We have adjusted these, so this
@@ -291,7 +291,7 @@ int64_t cvmx_bootmem_phy_alloc(uint64_t
 		 * satisfy request.
 		 */
 		usable_base =
-		    __ALIGN_MASK(max(address_min, ent_addr), alignment - 1);
+		    ALIGN(max(address_min, ent_addr), alignment);
 		usable_max = min(address_max, ent_addr + ent_size);
 		/*
 		 * We should be able to allocate block at address
@@ -671,7 +671,7 @@ int64_t cvmx_bootmem_phy_named_block_all
 	 * coallesced when they are freed.  The alloc routine does the
 	 * same rounding up on all allocations.
 	 */
-	size = __ALIGN_MASK(size, (CVMX_BOOTMEM_ALIGNMENT_SIZE - 1));
+	size = ALIGN(size, CVMX_BOOTMEM_ALIGNMENT_SIZE);
 
 	addr_allocated = cvmx_bootmem_phy_alloc(size, min_addr, max_addr,
 						alignment,
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c linux-libre-2.6.34-gnu1/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c
--- linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c	2010-05-16 17:17:36.000000000 -0400
@@ -115,4 +115,3 @@ int cvmx_sysinfo_minimal_initialize(void
 
 	return 1;
 }
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/octeon-irq.c linux-libre-2.6.34-gnu1/arch/mips/cavium-octeon/octeon-irq.c
--- linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/octeon-irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/cavium-octeon/octeon-irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,9 +13,8 @@
 #include <asm/octeon/cvmx-pexp-defs.h>
 #include <asm/octeon/cvmx-npi-defs.h>
 
-DEFINE_RWLOCK(octeon_irq_ciu0_rwlock);
-DEFINE_RWLOCK(octeon_irq_ciu1_rwlock);
-DEFINE_SPINLOCK(octeon_irq_msi_lock);
+static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock);
+static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock);
 
 static int octeon_coreid_for_cpu(int cpu)
 {
@@ -51,9 +50,6 @@ static void octeon_irq_core_eoi(unsigned
 	 */
 	if (desc->status & IRQ_DISABLED)
 		return;
-
-	/* There is a race here.  We should fix it.  */
-
 	/*
 	 * We don't need to disable IRQs to make these atomic since
 	 * they are already disabled earlier in the low level
@@ -141,19 +137,12 @@ static void octeon_irq_ciu0_enable(unsig
 	uint64_t en0;
 	int bit = irq - OCTEON_IRQ_WORKQ0;	/* Bit 0-63 of EN0 */
 
-	/*
-	 * A read lock is used here to make sure only one core is ever
-	 * updating the CIU enable bits at a time. During an enable
-	 * the cores don't interfere with each other. During a disable
-	 * the write lock stops any enables that might cause a
-	 * problem.
-	 */
-	read_lock_irqsave(&octeon_irq_ciu0_rwlock, flags);
+	raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
 	en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
 	en0 |= 1ull << bit;
 	cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
 	cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
-	read_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags);
+	raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
 }
 
 static void octeon_irq_ciu0_disable(unsigned int irq)
@@ -162,7 +151,7 @@ static void octeon_irq_ciu0_disable(unsi
 	unsigned long flags;
 	uint64_t en0;
 	int cpu;
-	write_lock_irqsave(&octeon_irq_ciu0_rwlock, flags);
+	raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
 	for_each_online_cpu(cpu) {
 		int coreid = octeon_coreid_for_cpu(cpu);
 		en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
@@ -174,7 +163,7 @@ static void octeon_irq_ciu0_disable(unsi
 	 * of them are done.
 	 */
 	cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
-	write_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags);
+	raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
 }
 
 /*
@@ -193,7 +182,7 @@ static void octeon_irq_ciu0_enable_v2(un
  * Disable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu0_disable_v2(unsigned int irq)
+static void octeon_irq_ciu0_ack_v2(unsigned int irq)
 {
 	int index = cvmx_get_core_num() * 2;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
@@ -202,6 +191,43 @@ static void octeon_irq_ciu0_disable_v2(u
 }
 
 /*
+ * CIU timer type interrupts must be acknoleged by writing a '1' bit
+ * to their sum0 bit.
+ */
+static void octeon_irq_ciu0_timer_ack(unsigned int irq)
+{
+	int index = cvmx_get_core_num() * 2;
+	uint64_t mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+	cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask);
+}
+
+static void octeon_irq_ciu0_timer_ack_v1(unsigned int irq)
+{
+	octeon_irq_ciu0_timer_ack(irq);
+	octeon_irq_ciu0_ack(irq);
+}
+
+static void octeon_irq_ciu0_timer_ack_v2(unsigned int irq)
+{
+	octeon_irq_ciu0_timer_ack(irq);
+	octeon_irq_ciu0_ack_v2(irq);
+}
+
+/*
+ * Enable the irq on the current core for chips that have the EN*_W1{S,C}
+ * registers.
+ */
+static void octeon_irq_ciu0_eoi_v2(unsigned int irq)
+{
+	struct irq_desc *desc = irq_desc + irq;
+	int index = cvmx_get_core_num() * 2;
+	u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+
+	if ((desc->status & IRQ_DISABLED) == 0)
+		cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
+}
+
+/*
  * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
  * registers.
  */
@@ -223,7 +249,7 @@ static int octeon_irq_ciu0_set_affinity(
 	unsigned long flags;
 	int bit = irq - OCTEON_IRQ_WORKQ0;	/* Bit 0-63 of EN0 */
 
-	write_lock_irqsave(&octeon_irq_ciu0_rwlock, flags);
+	raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
 	for_each_online_cpu(cpu) {
 		int coreid = octeon_coreid_for_cpu(cpu);
 		uint64_t en0 =
@@ -239,7 +265,7 @@ static int octeon_irq_ciu0_set_affinity(
 	 * of them are done.
 	 */
 	cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
-	write_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags);
+	raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
 
 	return 0;
 }
@@ -272,8 +298,8 @@ static struct irq_chip octeon_irq_chip_c
 	.name = "CIU0",
 	.enable = octeon_irq_ciu0_enable_v2,
 	.disable = octeon_irq_ciu0_disable_all_v2,
-	.ack = octeon_irq_ciu0_disable_v2,
-	.eoi = octeon_irq_ciu0_enable_v2,
+	.ack = octeon_irq_ciu0_ack_v2,
+	.eoi = octeon_irq_ciu0_eoi_v2,
 #ifdef CONFIG_SMP
 	.set_affinity = octeon_irq_ciu0_set_affinity_v2,
 #endif
@@ -290,6 +316,28 @@ static struct irq_chip octeon_irq_chip_c
 #endif
 };
 
+static struct irq_chip octeon_irq_chip_ciu0_timer_v2 = {
+	.name = "CIU0-T",
+	.enable = octeon_irq_ciu0_enable_v2,
+	.disable = octeon_irq_ciu0_disable_all_v2,
+	.ack = octeon_irq_ciu0_timer_ack_v2,
+	.eoi = octeon_irq_ciu0_eoi_v2,
+#ifdef CONFIG_SMP
+	.set_affinity = octeon_irq_ciu0_set_affinity_v2,
+#endif
+};
+
+static struct irq_chip octeon_irq_chip_ciu0_timer = {
+	.name = "CIU0-T",
+	.enable = octeon_irq_ciu0_enable,
+	.disable = octeon_irq_ciu0_disable,
+	.ack = octeon_irq_ciu0_timer_ack_v1,
+	.eoi = octeon_irq_ciu0_eoi,
+#ifdef CONFIG_SMP
+	.set_affinity = octeon_irq_ciu0_set_affinity,
+#endif
+};
+
 
 static void octeon_irq_ciu1_ack(unsigned int irq)
 {
@@ -322,19 +370,12 @@ static void octeon_irq_ciu1_enable(unsig
 	uint64_t en1;
 	int bit = irq - OCTEON_IRQ_WDOG0;	/* Bit 0-63 of EN1 */
 
-	/*
-	 * A read lock is used here to make sure only one core is ever
-	 * updating the CIU enable bits at a time.  During an enable
-	 * the cores don't interfere with each other.  During a disable
-	 * the write lock stops any enables that might cause a
-	 * problem.
-	 */
-	read_lock_irqsave(&octeon_irq_ciu1_rwlock, flags);
+	raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
 	en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
 	en1 |= 1ull << bit;
 	cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
 	cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
-	read_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags);
+	raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
 }
 
 static void octeon_irq_ciu1_disable(unsigned int irq)
@@ -343,7 +384,7 @@ static void octeon_irq_ciu1_disable(unsi
 	unsigned long flags;
 	uint64_t en1;
 	int cpu;
-	write_lock_irqsave(&octeon_irq_ciu1_rwlock, flags);
+	raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
 	for_each_online_cpu(cpu) {
 		int coreid = octeon_coreid_for_cpu(cpu);
 		en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
@@ -355,7 +396,7 @@ static void octeon_irq_ciu1_disable(unsi
 	 * of them are done.
 	 */
 	cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
-	write_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags);
+	raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
 }
 
 /*
@@ -374,7 +415,7 @@ static void octeon_irq_ciu1_enable_v2(un
  * Disable the irq on the current core for chips that have the EN*_W1{S,C}
  * registers.
  */
-static void octeon_irq_ciu1_disable_v2(unsigned int irq)
+static void octeon_irq_ciu1_ack_v2(unsigned int irq)
 {
 	int index = cvmx_get_core_num() * 2 + 1;
 	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
@@ -383,6 +424,20 @@ static void octeon_irq_ciu1_disable_v2(u
 }
 
 /*
+ * Enable the irq on the current core for chips that have the EN*_W1{S,C}
+ * registers.
+ */
+static void octeon_irq_ciu1_eoi_v2(unsigned int irq)
+{
+	struct irq_desc *desc = irq_desc + irq;
+	int index = cvmx_get_core_num() * 2 + 1;
+	u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
+
+	if ((desc->status & IRQ_DISABLED) == 0)
+		cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+}
+
+/*
  * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
  * registers.
  */
@@ -405,7 +460,7 @@ static int octeon_irq_ciu1_set_affinity(
 	unsigned long flags;
 	int bit = irq - OCTEON_IRQ_WDOG0;	/* Bit 0-63 of EN1 */
 
-	write_lock_irqsave(&octeon_irq_ciu1_rwlock, flags);
+	raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
 	for_each_online_cpu(cpu) {
 		int coreid = octeon_coreid_for_cpu(cpu);
 		uint64_t en1 =
@@ -422,7 +477,7 @@ static int octeon_irq_ciu1_set_affinity(
 	 * of them are done.
 	 */
 	cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
-	write_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags);
+	raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
 
 	return 0;
 }
@@ -455,8 +510,8 @@ static struct irq_chip octeon_irq_chip_c
 	.name = "CIU0",
 	.enable = octeon_irq_ciu1_enable_v2,
 	.disable = octeon_irq_ciu1_disable_all_v2,
-	.ack = octeon_irq_ciu1_disable_v2,
-	.eoi = octeon_irq_ciu1_enable_v2,
+	.ack = octeon_irq_ciu1_ack_v2,
+	.eoi = octeon_irq_ciu1_eoi_v2,
 #ifdef CONFIG_SMP
 	.set_affinity = octeon_irq_ciu1_set_affinity_v2,
 #endif
@@ -475,6 +530,8 @@ static struct irq_chip octeon_irq_chip_c
 
 #ifdef CONFIG_PCI_MSI
 
+static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);
+
 static void octeon_irq_msi_ack(unsigned int irq)
 {
 	if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
@@ -515,12 +572,12 @@ static void octeon_irq_msi_enable(unsign
 		 */
 		uint64_t en;
 		unsigned long flags;
-		spin_lock_irqsave(&octeon_irq_msi_lock, flags);
+		raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
 		en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
 		en |= 1ull << (irq - OCTEON_IRQ_MSI_BIT0);
 		cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
 		cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
-		spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
+		raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
 	}
 }
 
@@ -537,12 +594,12 @@ static void octeon_irq_msi_disable(unsig
 		 */
 		uint64_t en;
 		unsigned long flags;
-		spin_lock_irqsave(&octeon_irq_msi_lock, flags);
+		raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
 		en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
 		en &= ~(1ull << (irq - OCTEON_IRQ_MSI_BIT0));
 		cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
 		cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
-		spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
+		raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
 	}
 }
 
@@ -559,6 +616,7 @@ void __init arch_init_irq(void)
 {
 	int irq;
 	struct irq_chip *chip0;
+	struct irq_chip *chip0_timer;
 	struct irq_chip *chip1;
 
 #ifdef CONFIG_SMP
@@ -574,9 +632,11 @@ void __init arch_init_irq(void)
 	    OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) ||
 	    OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X)) {
 		chip0 = &octeon_irq_chip_ciu0_v2;
+		chip0_timer = &octeon_irq_chip_ciu0_timer_v2;
 		chip1 = &octeon_irq_chip_ciu1_v2;
 	} else {
 		chip0 = &octeon_irq_chip_ciu0;
+		chip0_timer = &octeon_irq_chip_ciu0_timer;
 		chip1 = &octeon_irq_chip_ciu1;
 	}
 
@@ -590,7 +650,21 @@ void __init arch_init_irq(void)
 
 	/* 24 - 87 CIU_INT_SUM0 */
 	for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) {
-		set_irq_chip_and_handler(irq, chip0, handle_percpu_irq);
+		switch (irq) {
+		case OCTEON_IRQ_GMX_DRP0:
+		case OCTEON_IRQ_GMX_DRP1:
+		case OCTEON_IRQ_IPD_DRP:
+		case OCTEON_IRQ_KEY_ZERO:
+		case OCTEON_IRQ_TIMER0:
+		case OCTEON_IRQ_TIMER1:
+		case OCTEON_IRQ_TIMER2:
+		case OCTEON_IRQ_TIMER3:
+			set_irq_chip_and_handler(irq, chip0_timer, handle_percpu_irq);
+			break;
+		default:
+			set_irq_chip_and_handler(irq, chip0, handle_percpu_irq);
+			break;
+		}
 	}
 
 	/* 88 - 151 CIU_INT_SUM1 */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/octeon-platform.c linux-libre-2.6.34-gnu1/arch/mips/cavium-octeon/octeon-platform.c
--- linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/octeon-platform.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/cavium-octeon/octeon-platform.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
@@ -159,6 +160,90 @@ out:
 }
 device_initcall(octeon_rng_device_init);
 
+static struct i2c_board_info __initdata octeon_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("ds1337", 0x68),
+	},
+};
+
+static int __init octeon_i2c_devices_init(void)
+{
+	return i2c_register_board_info(0, octeon_i2c_devices,
+				       ARRAY_SIZE(octeon_i2c_devices));
+}
+arch_initcall(octeon_i2c_devices_init);
+
+#define OCTEON_I2C_IO_BASE 0x1180000001000ull
+#define OCTEON_I2C_IO_UNIT_OFFSET 0x200
+
+static struct octeon_i2c_data octeon_i2c_data[2];
+
+static int __init octeon_i2c_device_init(void)
+{
+	struct platform_device *pd;
+	int ret = 0;
+	int port, num_ports;
+
+	struct resource i2c_resources[] = {
+		{
+			.flags	= IORESOURCE_MEM,
+		}, {
+			.flags	= IORESOURCE_IRQ,
+		}
+	};
+
+	if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
+		num_ports = 2;
+	else
+		num_ports = 1;
+
+	for (port = 0; port < num_ports; port++) {
+		octeon_i2c_data[port].sys_freq = octeon_get_clock_rate();
+		/*FIXME: should be examined. At the moment is set for 100Khz */
+		octeon_i2c_data[port].i2c_freq = 100000;
+
+		pd = platform_device_alloc("i2c-octeon", port);
+		if (!pd) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		pd->dev.platform_data = octeon_i2c_data + port;
+
+		i2c_resources[0].start =
+			OCTEON_I2C_IO_BASE + (port * OCTEON_I2C_IO_UNIT_OFFSET);
+		i2c_resources[0].end = i2c_resources[0].start + 0x1f;
+		switch (port) {
+		case 0:
+			i2c_resources[1].start = OCTEON_IRQ_TWSI;
+			i2c_resources[1].end = OCTEON_IRQ_TWSI;
+			break;
+		case 1:
+			i2c_resources[1].start = OCTEON_IRQ_TWSI2;
+			i2c_resources[1].end = OCTEON_IRQ_TWSI2;
+			break;
+		default:
+			BUG();
+		}
+
+		ret = platform_device_add_resources(pd,
+						    i2c_resources,
+						    ARRAY_SIZE(i2c_resources));
+		if (ret)
+			goto fail;
+
+		ret = platform_device_add(pd);
+		if (ret)
+			goto fail;
+	}
+	return ret;
+fail:
+	platform_device_put(pd);
+out:
+	return ret;
+}
+device_initcall(octeon_i2c_device_init);
+
 /* Octeon SMI/MDIO interface.  */
 static int __init octeon_mdiobus_device_init(void)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/setup.c linux-libre-2.6.34-gnu1/arch/mips/cavium-octeon/setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/cavium-octeon/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,9 +45,6 @@ extern struct plat_smp_ops octeon_smp_op
 extern void pci_console_init(const char *arg);
 #endif
 
-#ifdef CONFIG_CAVIUM_RESERVE32
-extern uint64_t octeon_reserve32_memory;
-#endif
 static unsigned long long MAX_MEMORY = 512ull << 20;
 
 struct octeon_boot_descriptor *octeon_boot_desc_ptr;
@@ -186,54 +183,6 @@ void octeon_check_cpu_bist(void)
 	write_octeon_c0_dcacheerr(0);
 }
 
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-/**
- * Called on every core to setup the wired tlb entry needed
- * if CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB is set.
- *
- */
-static void octeon_hal_setup_per_cpu_reserved32(void *unused)
-{
-	/*
-	 * The config has selected to wire the reserve32 memory for all
-	 * userspace applications. We need to put a wired TLB entry in for each
-	 * 512MB of reserve32 memory. We only handle double 256MB pages here,
-	 * so reserve32 must be multiple of 512MB.
-	 */
-	uint32_t size = CONFIG_CAVIUM_RESERVE32;
-	uint32_t entrylo0 =
-		0x7 | ((octeon_reserve32_memory & ((1ul << 40) - 1)) >> 6);
-	uint32_t entrylo1 = entrylo0 + (256 << 14);
-	uint32_t entryhi = (0x80000000UL - (CONFIG_CAVIUM_RESERVE32 << 20));
-	while (size >= 512) {
-#if 0
-		pr_info("CPU%d: Adding double wired TLB entry for 0x%lx\n",
-			smp_processor_id(), entryhi);
-#endif
-		add_wired_entry(entrylo0, entrylo1, entryhi, PM_256M);
-		entrylo0 += 512 << 14;
-		entrylo1 += 512 << 14;
-		entryhi += 512 << 20;
-		size -= 512;
-	}
-}
-#endif /* CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB */
-
-/**
- * Called to release the named block which was used to made sure
- * that nobody used the memory for something else during
- * init. Now we'll free it so userspace apps can use this
- * memory region with bootmem_alloc.
- *
- * This function is called only once from prom_free_prom_memory().
- */
-void octeon_hal_setup_reserved32(void)
-{
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-	on_each_cpu(octeon_hal_setup_per_cpu_reserved32, NULL, 0, 1);
-#endif
-}
-
 /**
  * Reboot Octeon
  *
@@ -294,18 +243,6 @@ static void octeon_halt(void)
 	octeon_kill_core(NULL);
 }
 
-#if 0
-/**
- * Platform time init specifics.
- * Returns
- */
-void __init plat_time_init(void)
-{
-	/* Nothing special here, but we are required to have one */
-}
-
-#endif
-
 /**
  * Handle all the error condition interrupts that might occur.
  *
@@ -502,25 +439,13 @@ void __init prom_init(void)
 	 * memory when it is getting memory from the
 	 * bootloader. Later, after the memory allocations are
 	 * complete, the reserve32 will be freed.
-	 */
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-	if (CONFIG_CAVIUM_RESERVE32 & 0x1ff)
-		pr_err("CAVIUM_RESERVE32 isn't a multiple of 512MB. "
-		       "This is required if CAVIUM_RESERVE32_USE_WIRED_TLB "
-		       "is set\n");
-	else
-		addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
-							0, 0, 512 << 20,
-							"CAVIUM_RESERVE32", 0);
-#else
-	/*
+	 *
 	 * Allocate memory for RESERVED32 aligned on 2MB boundary. This
 	 * is in case we later use hugetlb entries with it.
 	 */
 	addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
 						0, 0, 2 << 20,
 						"CAVIUM_RESERVE32", 0);
-#endif
 	if (addr < 0)
 		pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n");
 	else
@@ -817,9 +742,4 @@ void prom_free_prom_memory(void)
 		panic("Unable to request_irq(OCTEON_IRQ_RML)\n");
 	}
 #endif
-
-	/* This call is here so that it is performed after any TLB
-	   initializations. It needs to be after these in case the
-	   CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */
-	octeon_hal_setup_reserved32();
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/smp.c linux-libre-2.6.34-gnu1/arch/mips/cavium-octeon/smp.c
--- linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/smp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/cavium-octeon/smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -279,14 +279,6 @@ static void octeon_cpu_die(unsigned int
 	uint32_t avail_coremask;
 	struct cvmx_bootmem_named_block_desc *block_desc;
 
-#ifdef CONFIG_CAVIUM_OCTEON_WATCHDOG
-	/* Disable the watchdog */
-	cvmx_ciu_wdogx_t ciu_wdog;
-	ciu_wdog.u64 = cvmx_read_csr(CVMX_CIU_WDOGX(cpu));
-	ciu_wdog.s.mode = 0;
-	cvmx_write_csr(CVMX_CIU_WDOGX(cpu), ciu_wdog.u64);
-#endif
-
 	while (per_cpu(cpu_state, cpu) != CPU_DEAD)
 		cpu_relax();
 
@@ -327,7 +319,7 @@ static void octeon_cpu_die(unsigned int
 				   avail_coremask);
 	}
 
-	pr_info("Reset core %d. Available Coremask = %x \n", coreid,
+	pr_info("Reset core %d. Available Coremask = %x\n", coreid,
 		avail_coremask);
 	cvmx_write_csr(CVMX_CIU_PP_RST, 1 << coreid);
 	cvmx_write_csr(CVMX_CIU_PP_RST, 0);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/cobalt/pci.c linux-libre-2.6.34-gnu1/arch/mips/cobalt/pci.c
--- linux-libre-2.6.33-gnu1/arch/mips/cobalt/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/cobalt/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,7 @@ static struct resource cobalt_mem_resour
 
 static struct resource cobalt_io_resource = {
 	.start	= 0x1000,
-	.end	= GT_DEF_PCI0_IO_SIZE - 1,
+	.end	= 0xffffffUL,
 	.name	= "PCI I/O",
 	.flags	= IORESOURCE_IO,
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/configs/bcm63xx_defconfig linux-libre-2.6.34-gnu1/arch/mips/configs/bcm63xx_defconfig
--- linux-libre-2.6.33-gnu1/arch/mips/configs/bcm63xx_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/configs/bcm63xx_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc6
-# Sun May 31 20:17:18 2009
+# Linux kernel version: 2.6.34-rc2
+# Tue Mar 23 10:36:32 2010
 #
 CONFIG_MIPS=y
 
@@ -9,13 +9,14 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
 CONFIG_BCM63XX=y
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
-# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SIM is not set
 # CONFIG_NEC_MARKEINS is not set
@@ -26,6 +27,7 @@ CONFIG_BCM63XX=y
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP28 is not set
@@ -45,13 +47,17 @@ CONFIG_BCM63XX=y
 # CONFIG_WR_PPMC is not set
 # CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
 # CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
 
 #
 # CPU support
 #
+CONFIG_BCM63XX_CPU_6338=y
+CONFIG_BCM63XX_CPU_6345=y
 CONFIG_BCM63XX_CPU_6348=y
 CONFIG_BCM63XX_CPU_6358=y
 CONFIG_BOARD_BCM963XX=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -69,10 +75,8 @@ CONFIG_CEVT_R4K=y
 CONFIG_CSRC_R4K_LIB=y
 CONFIG_CSRC_R4K=y
 CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-CONFIG_EARLY_PRINTK=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_SYS_HAS_EARLY_PRINTK=y
-# CONFIG_HOTPLUG_CPU is not set
 # CONFIG_NO_IOPORT is not set
 CONFIG_GENERIC_GPIO=y
 CONFIG_CPU_BIG_ENDIAN=y
@@ -85,7 +89,8 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 #
 # CPU selection
 #
-# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -128,7 +133,7 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
@@ -146,9 +151,8 @@ 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_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 # CONFIG_HIGH_RES_TIMERS is not set
@@ -170,6 +174,7 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -189,15 +194,12 @@ CONFIG_LOCALVERSION=""
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
 # CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=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
@@ -205,11 +207,11 @@ 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_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -223,6 +225,10 @@ CONFIG_BASE_FULL=y
 # CONFIG_EVENTFD is not set
 # CONFIG_SHMEM is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 # CONFIG_VM_EVENT_COUNTERS is not set
 CONFIG_PCI_QUIRKS=y
 # CONFIG_SLUB_DEBUG is not set
@@ -231,14 +237,17 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
 # CONFIG_SLOW_WORK is not set
-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -246,14 +255,41 @@ CONFIG_BLOCK=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -263,15 +299,12 @@ CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_MMU=y
 CONFIG_PCCARD=y
-# CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
 CONFIG_CARDBUS=y
 
 #
@@ -295,6 +328,7 @@ CONFIG_TRAD_SIGNALS=y
 #
 # Power management options
 #
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PM is not set
 CONFIG_NET=y
@@ -333,6 +367,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -347,6 +382,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -359,7 +395,27 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=y
+CONFIG_NL80211_TESTMODE=y
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=y
+# CONFIG_MAC80211_RC_PID is not set
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+# CONFIG_MAC80211_MESH is not set
+CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUG_MENU is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -471,6 +527,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -484,13 +541,16 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
 #
 # 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
@@ -529,6 +589,7 @@ CONFIG_MII=y
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
 # CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
@@ -541,17 +602,48 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
 CONFIG_BCM63XX_ENET=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+CONFIG_WLAN=y
+# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_ATMEL is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_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_ATH_COMMON is not set
+CONFIG_B43=y
+CONFIG_B43_PCI_AUTOSELECT=y
+CONFIG_B43_PCICORE_AUTOSELECT=y
+# CONFIG_B43_PCMCIA is not set
+CONFIG_B43_PIO=y
+# CONFIG_B43_PHY_LP is not set
+CONFIG_B43_LEDS=y
+# CONFIG_B43_DEBUG is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_IWLWIFI is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_HERMES is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_WL12XX is not set
+# CONFIG_ZD1211RW is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -574,6 +666,7 @@ CONFIG_BCM63XX_ENET=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -607,6 +700,7 @@ CONFIG_BCM63XX_ENET=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_SERIAL_BCM63XX=y
 CONFIG_SERIAL_BCM63XX_CONSOLE=y
 # CONFIG_UNIX98_PTYS is not set
@@ -629,6 +723,11 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_GPIO_SYSFS is not set
@@ -636,6 +735,8 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
@@ -644,16 +745,21 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
 
 #
 # SPI GPIO expanders:
 #
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -662,15 +768,16 @@ CONFIG_SSB_POSSIBLE=y
 #
 CONFIG_SSB=y
 CONFIG_SSB_SPROM=y
+CONFIG_SSB_BLOCKIO=y
 CONFIG_SSB_PCIHOST_POSSIBLE=y
 CONFIG_SSB_PCIHOST=y
-# CONFIG_SSB_B43_PCI_BRIDGE is not set
+CONFIG_SSB_B43_PCI_BRIDGE=y
 CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
 # CONFIG_SSB_PCMCIAHOST is not set
 # CONFIG_SSB_SILENT is not set
 # CONFIG_SSB_DEBUG is not set
 CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
-# CONFIG_SSB_DRIVER_PCICORE is not set
+CONFIG_SSB_DRIVER_PCICORE=y
 # CONFIG_SSB_DRIVER_MIPS is not set
 
 #
@@ -680,27 +787,15 @@ CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
+# CONFIG_VGA_ARB is not set
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -710,11 +805,7 @@ CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
 #
 # Display device support
 #
-CONFIG_DISPLAY_SUPPORT=y
-
-#
-# Display hardware drivers
-#
+# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -741,13 +832,14 @@ CONFIG_USB=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
-CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_HCD_SSB is not set
 CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
@@ -796,7 +888,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # 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
@@ -807,8 +898,8 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -819,7 +910,29 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_NEW_LEDS is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGER_TIMER=y
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 CONFIG_RTC_LIB=y
@@ -827,6 +940,10 @@ CONFIG_RTC_LIB=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -838,12 +955,16 @@ CONFIG_RTC_LIB=y
 # 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_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FILE_LOCKING is not set
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
@@ -875,8 +996,6 @@ 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
@@ -888,6 +1007,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -898,7 +1018,6 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 # CONFIG_NETWORK_FILESYSTEMS is not set
 
 #
@@ -906,7 +1025,46 @@ CONFIG_MISC_FILESYSTEMS=y
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 # CONFIG_DLM is not set
 
 #
@@ -918,29 +1076,23 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=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_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# 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_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_EARLY_PRINTK=y
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyS0,115200"
 # CONFIG_CMDLINE_OVERRIDE is not set
@@ -951,8 +1103,108 @@ CONFIG_CMDLINE="console=ttyS0,115200"
 # 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_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL 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
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=y
+# CONFIG_CRYPTO_HW is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/configs/bigsur_defconfig linux-libre-2.6.34-gnu1/arch/mips/configs/bigsur_defconfig
--- linux-libre-2.6.33-gnu1/arch/mips/configs/bigsur_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/configs/bigsur_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc8
-# Wed Jul  2 17:02:55 2008
+# Linux kernel version: 2.6.34-rc3
+# Sat Apr  3 16:32:11 2010
 #
 CONFIG_MIPS=y
 
@@ -9,20 +9,25 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
-# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MARKEINS is not set
+# CONFIG_NEC_MARKEINS is not set
 # CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP28 is not set
@@ -36,10 +41,13 @@ CONFIG_MIPS=y
 # CONFIG_SIBYTE_SENTOSA is not set
 CONFIG_SIBYTE_BIGSUR=y
 # CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
 # CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
 CONFIG_SIBYTE_BCM1x80=y
 CONFIG_SIBYTE_SB1xxx_SOC=y
 # CONFIG_CPU_SB1_PASS_1 is not set
@@ -48,14 +56,13 @@ CONFIG_SIBYTE_SB1xxx_SOC=y
 # CONFIG_CPU_SB1_PASS_4 is not set
 # CONFIG_CPU_SB1_PASS_2_112x is not set
 # CONFIG_CPU_SB1_PASS_3 is not set
-# CONFIG_SIMULATION is not set
 # CONFIG_SB1_CEX_ALWAYS_FATAL is not set
 # CONFIG_SB1_CERR_STALL is not set
-CONFIG_SIBYTE_CFE=y
 # CONFIG_SIBYTE_CFE_CONSOLE is not set
 # CONFIG_SIBYTE_BUS_WATCHER is not set
 # CONFIG_SIBYTE_TBPROF is not set
 CONFIG_SIBYTE_HAS_ZBUS_PROFILING=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -66,15 +73,13 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_CEVT_BCM1480=y
 CONFIG_CSRC_BCM1480=y
 CONFIG_CFE=y
 CONFIG_DMA_COHERENT=y
-CONFIG_EARLY_PRINTK=y
 CONFIG_SYS_HAS_EARLY_PRINTK=y
-# CONFIG_HOTPLUG_CPU is not set
 # CONFIG_NO_IOPORT is not set
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
@@ -88,7 +93,8 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 #
 # CPU selection
 #
-# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 # CONFIG_CPU_MIPS32_R1 is not set
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -101,6 +107,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
@@ -108,6 +115,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 CONFIG_CPU_SB1=y
+# CONFIG_CPU_CAVIUM_OCTEON is not set
 CONFIG_SYS_HAS_CPU_SB1=y
 CONFIG_WEAK_ORDERING=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
@@ -123,11 +131,13 @@ CONFIG_64BIT=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_SIBYTE_DMA_PAGEOPS is not set
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
@@ -142,18 +152,17 @@ 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=y
+CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_SMP=y
 CONFIG_SYS_SUPPORTS_SMP=y
 CONFIG_NR_CPUS_DEFAULT_4=y
 CONFIG_NR_CPUS=4
-# CONFIG_MIPS_CMP is not set
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -175,6 +184,7 @@ CONFIG_SECCOMP=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -188,6 +198,7 @@ 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=y
@@ -195,23 +206,39 @@ CONFIG_TASK_DELAY_ACCT=y
 CONFIG_TASK_XACCT=y
 CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_AUDIT=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=64
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_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=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_SYSFS_DEPRECATED_V2 is not set
 CONFIG_RELAY=y
-# CONFIG_NAMESPACES is not set
+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_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO 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
@@ -222,29 +249,36 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 # CONFIG_PCSPKR_PLATFORM 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
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -252,26 +286,52 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 CONFIG_BLOCK_COMPAT=y
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+# CONFIG_FREEZER is not set
 
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
@@ -280,8 +340,9 @@ CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 CONFIG_PCI_DEBUG=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 CONFIG_MMU=y
 CONFIG_ZONE_DMA32=y
 # CONFIG_PCCARD is not set
@@ -291,6 +352,8 @@ CONFIG_ZONE_DMA32=y
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
@@ -304,23 +367,20 @@ CONFIG_BINFMT_ELF32=y
 #
 CONFIG_PM=y
 # CONFIG_PM_DEBUG is not set
-
-#
-# Networking
-#
+# CONFIG_PM_RUNTIME is not set
 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=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -353,36 +413,6 @@ CONFIG_INET_TCP_DIAG=y
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_TCP_MD5SIG=y
-CONFIG_IP_VS=m
-# CONFIG_IP_VS_DEBUG is not set
-CONFIG_IP_VS_TAB_BITS=12
-
-#
-# IPVS transport protocol load balancing support
-#
-CONFIG_IP_VS_PROTO_TCP=y
-CONFIG_IP_VS_PROTO_UDP=y
-CONFIG_IP_VS_PROTO_ESP=y
-CONFIG_IP_VS_PROTO_AH=y
-
-#
-# IPVS scheduler
-#
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-CONFIG_IP_VS_SED=m
-CONFIG_IP_VS_NQ=m
-
-#
-# IPVS application helper
-#
-CONFIG_IP_VS_FTP=m
 CONFIG_IPV6=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
@@ -399,11 +429,13 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
 CONFIG_IPV6_SIT=m
+CONFIG_IPV6_SIT_6RD=y
 CONFIG_IPV6_NDISC_NODETYPE=y
 CONFIG_IPV6_TUNNEL=m
 CONFIG_IPV6_MULTIPLE_TABLES=y
 CONFIG_IPV6_SUBTREES=y
 # CONFIG_IPV6_MROUTE is not set
+CONFIG_NETLABEL=y
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -421,19 +453,53 @@ CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_AH_ESP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_PROTO_SCTP=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
 
 #
 # IP: Netfilter Configuration
 #
+CONFIG_NF_DEFRAG_IPV4=m
 CONFIG_NF_CONNTRACK_IPV4=m
 CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_IPTABLES=m
@@ -459,22 +525,44 @@ CONFIG_IP_NF_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
-# CONFIG_IP_DCCP is not set
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP_CCID2_DEBUG is not set
+CONFIG_IP_DCCP_CCID3=y
+# CONFIG_IP_DCCP_CCID3_DEBUG is not set
+CONFIG_IP_DCCP_CCID3_RTO=100
+CONFIG_IP_DCCP_TFRC_LIB=y
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
 # CONFIG_SCTP_HMAC_NONE is not set
-# CONFIG_SCTP_HMAC_SHA1 is not set
-CONFIG_SCTP_HMAC_MD5=y
+CONFIG_SCTP_HMAC_SHA1=y
+# CONFIG_SCTP_HMAC_MD5 is not set
+# CONFIG_RDS 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_STP=m
+CONFIG_GARP=m
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
 # CONFIG_DECNET is not set
+CONFIG_LLC=m
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
@@ -482,26 +570,47 @@ 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_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
+CONFIG_HAMRADIO=y
+
+#
+# Packet Radio protocols
+#
+CONFIG_AX25=m
+CONFIG_AX25_DAMA_SLAVE=y
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+
+#
+# AX.25 network device drivers
+#
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+CONFIG_BAYCOM_SER_FDX=m
+CONFIG_BAYCOM_SER_HDX=m
+CONFIG_YAM=m
 # 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_LIB80211 is not set
 
 #
-# Wireless
+# CFG80211 needs to be enabled for MAC80211
 #
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -513,9 +622,12 @@ CONFIG_FIB_RULES=y
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=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
@@ -530,33 +642,53 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM 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_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 CONFIG_SGI_IOC4=m
 # 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_SENSORS_TSL2550 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+CONFIG_EEPROM_LEGACY=y
+CONFIG_EEPROM_MAX6875=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_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
-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=y
-CONFIG_BLK_DEV_IDEFLOPPY=y
-# CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 CONFIG_IDE_PROC_FS=y
 
@@ -581,14 +713,13 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_AMD74XX is not set
 CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5520 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X 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=m
 # CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
@@ -600,14 +731,12 @@ CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
 CONFIG_BLK_DEV_TC86C001=m
-# CONFIG_BLK_DEV_IDE_SWARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -625,10 +754,6 @@ CONFIG_BLK_DEV_SR=m
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_CHR_DEV_SCH=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -645,27 +770,36 @@ CONFIG_SCSI_WAIT_SCAN=m
 # 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_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
+# CONFIG_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
 # 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
@@ -676,9 +810,15 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
 CONFIG_SATA_PMP=y
 # CONFIG_SATA_AHCI is not set
 CONFIG_SATA_SIL24=y
@@ -700,6 +840,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_ALI is not set
 # CONFIG_PATA_AMD is not set
 # CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
 # CONFIG_PATA_ATIIXP is not set
 # CONFIG_PATA_CMD640_PCI is not set
 # CONFIG_PATA_CMD64X is not set
@@ -715,6 +856,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -725,14 +867,16 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 CONFIG_PATA_SIL680=y
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -745,13 +889,16 @@ CONFIG_PATA_SIL680=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -774,6 +921,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
@@ -783,23 +933,33 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_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 is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # 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
@@ -811,29 +971,42 @@ CONFIG_SB1250_MAC=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
+CONFIG_MDIO=m
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
 CONFIG_CHELSIO_T3=m
+# 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=m
 # 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_QLCNIC is not set
+# CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
+CONFIG_WLAN=y
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -856,6 +1029,7 @@ CONFIG_SLIP_MODE_SLIP6=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -873,6 +1047,7 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_PCIPS2 is not set
 # CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -893,8 +1068,6 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
-# CONFIG_SX is not set
-# CONFIG_RIO is not set
 # CONFIG_STALDRV is not set
 # CONFIG_NOZOMI is not set
 
@@ -911,7 +1084,9 @@ CONFIG_SERIAL_SB1250_DUART_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE 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
@@ -923,89 +1098,99 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
 
 #
 # 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_SIBYTE=y
-# 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_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
-# CONFIG_I2C_PCA_PLATFORM is not set
 
 #
-# Miscellaneous I2C Chip support
+# I2C system bus drivers (mostly embedded / system-on-chip)
 #
-# CONFIG_DS1682 is not set
-CONFIG_EEPROM_LEGACY=y
-CONFIG_SENSORS_PCF8574=y
-# CONFIG_PCF8575 is not set
-CONFIG_SENSORS_PCF8591=y
-CONFIG_EEPROM_MAX6875=y
-# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX 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_SIBYTE=y
+# CONFIG_I2C_STUB is not set
 CONFIG_I2C_DEBUG_CORE=y
 CONFIG_I2C_DEBUG_ALGO=y
 CONFIG_I2C_DEBUG_BUS=y
-CONFIG_I2C_DEBUG_CHIP=y
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 # CONFIG_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_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1016,10 +1201,6 @@ CONFIG_SSB_POSSIBLE=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -1030,9 +1211,18 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# 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
@@ -1040,41 +1230,66 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_INFINIBAND is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
 #
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=m
 CONFIG_EXT2_FS_XATTR=y
-# CONFIG_EXT2_FS_POSIX_ACL is not set
-# CONFIG_EXT2_FS_SECURITY is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_DEFAULTS_TO_ORDERED=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_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_FS_XIP=y
+CONFIG_JBD=m
+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_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 CONFIG_QFMT_V2=m
 CONFIG_QUOTACTL=y
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1103,15 +1318,13 @@ CONFIG_NTFS_RW=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_ECRYPT_FS is not set
@@ -1120,9 +1333,12 @@ CONFIG_CONFIGFS_FS=m
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS 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
@@ -1133,16 +1349,17 @@ 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_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1205,12 +1422,18 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=2048
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS 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
@@ -1219,23 +1442,53 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_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_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_WRITECOUNT is not set
-# CONFIG_DEBUG_LIST is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_LIST=y
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_EARLY_PRINTK=y
 # CONFIG_CMDLINE_BOOL is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_SB1XXX_CORELIS is not set
@@ -1246,20 +1499,50 @@ CONFIG_DEBUG_MUTEXES=y
 #
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_NETWORK_XFRM=y
+# CONFIG_SECURITY_PATH is not set
+CONFIG_LSM_MMAP_MIN_ADDR=65536
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+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_POLICYDB_VERSION_MAX is not set
+# CONFIG_SECURITY_SMACK is not set
+# CONFIG_SECURITY_TOMOYO is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # 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_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=y
+# CONFIG_CRYPTO_PCRYPT is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
 # CONFIG_CRYPTO_TEST is not set
@@ -1276,7 +1559,7 @@ CONFIG_CRYPTO_SEQIV=m
 #
 CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_CTR=m
-# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
@@ -1287,14 +1570,20 @@ CONFIG_CRYPTO_XTS=m
 #
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
 
 #
 # Digest
 #
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_GHASH=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1325,25 +1614,36 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
-# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X 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=m
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=m
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
+CONFIG_CRC7=m
 CONFIG_LIBCRC32C=m
 CONFIG_AUDIT_GENERIC=y
-CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
-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_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/configs/db1000_defconfig linux-libre-2.6.34-gnu1/arch/mips/configs/db1000_defconfig
--- linux-libre-2.6.33-gnu1/arch/mips/configs/db1000_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/configs/db1000_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,78 +1,102 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:24 2007
+# Linux kernel version: 2.6.33
+# Fri Feb 26 08:46:14 2010
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
-CONFIG_ZONE_DMA=y
 CONFIG_MACH_ALCHEMY=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-CONFIG_MIPS_DB1000=y
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_AR7 is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
-# CONFIG_WR_PPMC is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
-# CONFIG_MARKEINS is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
 # CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
 # CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
 # CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+CONFIG_ALCHEMY_GPIOINT_AU1000=y
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+CONFIG_MIPS_DB1000=y
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_XXS1500 is not set
+CONFIG_SOC_AU1000=y
+CONFIG_SOC_AU1X00=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_TIME=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CSRC_R4K_LIB=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SOC_AU1000=y
-CONFIG_SOC_AU1X00=y
+CONFIG_IRQ_CPU=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
 
 #
 # CPU selection
 #
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -85,6 +109,7 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
@@ -92,11 +117,14 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_SUPPORTS_ZBOOT=y
 CONFIG_SYS_HAS_CPU_MIPS32_R1=y
 CONFIG_CPU_MIPS32=y
 CONFIG_CPU_MIPSR1=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
 
 #
 # Kernel type
@@ -106,184 +134,244 @@ CONFIG_32BIT=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_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_SPARSEMEM_STATIC is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
+CONFIG_HZ_100=y
 # CONFIG_HZ_128 is not set
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
 # CONFIG_HZ_1024 is not set
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
+CONFIG_HZ=100
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION="-db1000"
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
 CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_RCU is not set
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_RELAY=y
+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_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_KALLSYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
+# CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
 
 #
-# Loadable module support
+# GCOV-based kernel profiling
 #
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
+# 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_LSF is not set
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
 
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
 # CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-CONFIG_PCCARD=m
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=m
+CONFIG_PCCARD=y
+CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
+# CONFIG_PCMCIA_IOCTL is not set
 
 #
 # PC-card bridges
 #
 # CONFIG_PCMCIA_AU1X00 is not set
-
-#
-# PCI Hotplug Support
-#
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
 
 #
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 CONFIG_TRAD_SIGNALS=y
 
 #
 # Power management options
 #
-# CONFIG_PM is not set
-
-#
-# Networking
-#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
+CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=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_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
+CONFIG_IP_PNP_RARP=y
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
@@ -294,110 +382,25 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_LRO=y
+# CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
+# 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=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# Core Netfilter Configuration
-#
-CONFIG_NETFILTER_NETLINK=m
-CONFIG_NETFILTER_NETLINK_QUEUE=m
-CONFIG_NETFILTER_NETLINK_LOG=m
-CONFIG_NF_CONNTRACK_ENABLED=m
-CONFIG_NF_CONNTRACK_SUPPORT=y
-# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CT_ACCT=y
-CONFIG_NF_CONNTRACK_MARK=y
-CONFIG_NF_CONNTRACK_SECMARK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_GRE=m
-CONFIG_NF_CT_PROTO_SCTP=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 is not set
-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_XTABLES=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=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_HELPER=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_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-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_HASHLIMIT=m
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_CONNTRACK_PROC_COMPAT=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -407,27 +410,24 @@ CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
+# 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
@@ -436,25 +436,25 @@ CONFIG_WIRELESS_EXT=y
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=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
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
+# CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -467,6 +467,7 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -492,14 +493,13 @@ 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_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_ALCHEMY=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -516,174 +516,115 @@ CONFIG_MTD_ALCHEMY=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 # CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
 # CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
+# LPDDR flash memory drivers
 #
-# CONFIG_PARPORT is not set
+# CONFIG_MTD_LPDDR is not set
 
 #
-# Plug and Play support
+# UBI - Unsorted block images
 #
-# CONFIG_PNPACPI is not set
+# 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
 
 #
-# Block devices
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
 #
-# 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 is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=m
-
-#
-# Misc devices
-#
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# 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=m
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
 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
-
-#
-# PHY device support
-#
+# CONFIG_VETH is not set
 CONFIG_PHYLIB=y
 
 #
 # MII PHY device drivers
 #
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
-# CONFIG_BROADCOM_PHY is not set
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
 # CONFIG_FIXED_PHY is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
-CONFIG_MII=m
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
 CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
 
 #
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# PCMCIA network device support
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-CONFIG_PCMCIA_AXNET=m
 
 #
-# Wan interfaces
+# 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_PPP=m
-CONFIG_PPP_MULTILINK=y
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-# CONFIG_PPP_BSDCOMP is not set
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
+# CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-CONFIG_SLHC=m
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -691,16 +632,14 @@ CONFIG_SLHC=m
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
@@ -710,35 +649,33 @@ CONFIG_INPUT_EVDEV=y
 # 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 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
+# 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_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_AU1X00_GPIO is not set
 
 #
 # Serial drivers
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_CS=m
+# CONFIG_SERIAL_8250_CS is not set
 CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
@@ -750,198 +687,291 @@ CONFIG_SERIAL_8250_AU1X00=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 
 #
 # PCMCIA character devices
 #
-CONFIG_SYNCLINK_CS=m
+# 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
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
 # CONFIG_I2C is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
 
 #
-# Dallas's 1-wire bus
+# PPS support
 #
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
-# Multimedia devices
+# Sonics Silicon Backplane
 #
-# CONFIG_VIDEO_DEV is not set
+# CONFIG_SSB is not set
 
 #
-# Digital Video Broadcasting Devices
+# Multifunction device drivers
 #
-# CONFIG_DVB is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID 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
 
 #
-# Console display driver support
+# Display device support
 #
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
-# Sound
+# Console display driver support
 #
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
 # CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
 
 #
-# HID Devices
+# USB Input Devices
 #
-# CONFIG_HID is not set
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
 
 #
-# USB support
+# Special HID drivers
 #
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 # CONFIG_USB_ARCH_HAS_EHCI is not set
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Miscellaneous USB options
 #
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST 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 Gadget Support
+# USB Host Controller Drivers
 #
-# CONFIG_USB_GADGET is not set
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
 
 #
-# MMC/SD Card support
+# USB Device Class drivers
 #
-# CONFIG_MMC is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
-# LED devices
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
-# CONFIG_NEW_LEDS is not set
 
 #
-# LED drivers
+# also be needed; see USB_STORAGE Help for more info
 #
+# CONFIG_USB_LIBUSUAL is not set
 
 #
-# LED Triggers
+# USB Imaging devices
 #
+# CONFIG_USB_MDC800 is not set
 
 #
-# InfiniBand support
+# USB port drivers
 #
+# CONFIG_USB_SERIAL is not set
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# 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
 
 #
-# Real Time Clock
+# OTG and related infrastructure
 #
-# CONFIG_RTC_CLASS is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
 
 #
-# DMA Engine support
+# RTC interfaces
 #
-# CONFIG_DMA_ENGINE is not set
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
 
 #
-# DMA Clients
+# SPI RTC drivers
 #
 
 #
-# DMA Devices
+# Platform RTC drivers
 #
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
-# Auxiliary Display support
+# on-CPU RTC drivers
 #
+CONFIG_RTC_DRV_AU1XXX=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
 
 #
-# Virtualization
+# TI VLYNQ
 #
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-# CONFIG_EXT2_FS_SECURITY is not set
+# 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=y
-CONFIG_EXT3_FS_SECURITY=y
-# CONFIG_EXT4DEV_FS is not set
+# 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_FS_MBCACHE=y
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=m
-CONFIG_GENERIC_ACL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -960,74 +990,65 @@ CONFIG_GENERIC_ACL=y
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
+# CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+# CONFIG_PROC_PAGE_MONITOR is not set
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
-# CONFIG_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 is not set
-CONFIG_CRAMFS=m
+CONFIG_CRAMFS=y
+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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
-CONFIG_EXPORTFS=m
+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=m
-# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS=m
+CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
+CONFIG_NLS_CODEPAGE_437=y
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
+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
@@ -1045,10 +1066,10 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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_1250=y
 # CONFIG_NLS_CODEPAGE_1251 is not set
 # CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
+CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_ISO8859_2 is not set
 # CONFIG_NLS_ISO8859_3 is not set
 # CONFIG_NLS_ISO8859_4 is not set
@@ -1058,38 +1079,75 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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_ISO8859_15=y
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Distributed Lock Manager
-#
-CONFIG_DLM=m
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
 
 #
 # Kernel hacking
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_MUST_CHECK=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_STRIP_ASM_SYMS=y
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_CROSSCOMPILE=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
+# 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_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_EARLY_PRINTK=y
 # CONFIG_CMDLINE_BOOL is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_RUNTIME_DEBUG is not set
+CONFIG_DEBUG_ZBOOT=y
 
 #
 # Security options
@@ -1097,67 +1155,29 @@ CONFIG_CROSSCOMPILE=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=m
-CONFIG_CRC16=m
+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_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
-CONFIG_TEXTSEARCH_BM=m
-CONFIG_TEXTSEARCH_FSM=m
-CONFIG_PLIST=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.33-gnu1/arch/mips/configs/db1100_defconfig linux-libre-2.6.34-gnu1/arch/mips/configs/db1100_defconfig
--- linux-libre-2.6.33-gnu1/arch/mips/configs/db1100_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/configs/db1100_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,78 +1,102 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:24 2007
+# Linux kernel version: 2.6.33
+# Fri Feb 26 08:50:15 2010
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
-CONFIG_ZONE_DMA=y
 CONFIG_MACH_ALCHEMY=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-CONFIG_MIPS_DB1100=y
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_AR7 is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
-# CONFIG_WR_PPMC is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
-# CONFIG_MARKEINS is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
 # CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
 # CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
 # CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+CONFIG_ALCHEMY_GPIOINT_AU1000=y
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_DB1000 is not set
+CONFIG_MIPS_DB1100=y
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_XXS1500 is not set
+CONFIG_SOC_AU1100=y
+CONFIG_SOC_AU1X00=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_TIME=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CSRC_R4K_LIB=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SOC_AU1100=y
-CONFIG_SOC_AU1X00=y
+CONFIG_IRQ_CPU=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
 
 #
 # CPU selection
 #
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -85,6 +109,7 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
@@ -92,11 +117,14 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_SUPPORTS_ZBOOT=y
 CONFIG_SYS_HAS_CPU_MIPS32_R1=y
 CONFIG_CPU_MIPS32=y
 CONFIG_CPU_MIPSR1=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
 
 #
 # Kernel type
@@ -106,173 +134,242 @@ CONFIG_32BIT=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_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_SPARSEMEM_STATIC is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
+CONFIG_HZ_100=y
 # CONFIG_HZ_128 is not set
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
 # CONFIG_HZ_1024 is not set
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
+CONFIG_HZ=100
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION="-db1100"
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
 CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_RCU is not set
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_RELAY=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_SLAB=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
+# 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_HAVE_OPROFILE=y
 
 #
-# Loadable module support
+# GCOV-based kernel profiling
 #
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
+# 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_LSF is not set
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
 
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_MMU=y
+CONFIG_PCCARD=y
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+# CONFIG_PCMCIA_IOCTL is not set
 
 #
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
+# PC-card bridges
 #
+# CONFIG_PCMCIA_AU1X00 is not set
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
 
 #
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 CONFIG_TRAD_SIGNALS=y
 
 #
 # Power management options
 #
-# CONFIG_PM is not set
-
-#
-# Networking
-#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
+CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=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_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
+CONFIG_IP_PNP_RARP=y
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
@@ -283,110 +380,25 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_LRO=y
+# CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
+# 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=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# Core Netfilter Configuration
-#
-CONFIG_NETFILTER_NETLINK=m
-CONFIG_NETFILTER_NETLINK_QUEUE=m
-CONFIG_NETFILTER_NETLINK_LOG=m
-CONFIG_NF_CONNTRACK_ENABLED=m
-CONFIG_NF_CONNTRACK_SUPPORT=y
-# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CT_ACCT=y
-CONFIG_NF_CONNTRACK_MARK=y
-CONFIG_NF_CONNTRACK_SECMARK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_GRE=m
-CONFIG_NF_CT_PROTO_SCTP=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 is not set
-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_XTABLES=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=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_HELPER=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_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-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_HASHLIMIT=m
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_CONNTRACK_PROC_COMPAT=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -396,27 +408,24 @@ CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
+# 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
@@ -425,25 +434,25 @@ CONFIG_WIRELESS_EXT=y
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+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
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
+# CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -456,6 +465,7 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -481,14 +491,13 @@ 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_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_ALCHEMY=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -505,161 +514,123 @@ CONFIG_MTD_ALCHEMY=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 # CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
 # CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
+# LPDDR flash memory drivers
 #
-# CONFIG_PNPACPI is not set
+# CONFIG_MTD_LPDDR is not set
 
 #
-# Block devices
+# UBI - Unsorted block images
 #
-# 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_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=m
+# CONFIG_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=y
 
 #
-# Misc devices
+# 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_IDECS is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_IDE_TASK_IOCTL=y
+CONFIG_IDE_PROC_FS=y
 
 #
-# ATA/ATAPI/MFM/RLL support
+# IDE chipset support/bugfixes
 #
-# CONFIG_IDE is not set
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
 
 #
 # SCSI device support
 #
-CONFIG_RAID_ATTRS=m
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
 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
-
-#
-# PHY device support
-#
+# CONFIG_VETH is not set
 CONFIG_PHYLIB=y
 
 #
 # MII PHY device drivers
 #
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
-# CONFIG_BROADCOM_PHY is not set
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
 # CONFIG_FIXED_PHY is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
-CONFIG_MII=m
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
 CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
 
 #
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_NET_RADIO is not set
 
 #
-# Wan interfaces
+# 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_PPP=m
-CONFIG_PPP_MULTILINK=y
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-# CONFIG_PPP_BSDCOMP is not set
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
+# CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-CONFIG_SLHC=m
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -667,16 +638,14 @@ CONFIG_SLHC=m
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
@@ -686,34 +655,33 @@ CONFIG_INPUT_EVDEV=y
 # 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 is not set
-CONFIG_SERIO_SERPORT=y
-CONFIG_SERIO_LIBPS2=m
-CONFIG_SERIO_RAW=m
+# 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_AU1X00_GPIO is not set
 
 #
 # Serial drivers
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_CS is not set
 CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
@@ -725,78 +693,91 @@ CONFIG_SERIAL_8250_AU1X00=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-# CONFIG_RAW_DRIVER is not set
 
 #
-# TPM devices
+# 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
-
-#
-# I2C support
-#
 # CONFIG_I2C is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
 
 #
-# Dallas's 1-wire bus
+# PPS support
 #
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
-# Multimedia devices
+# Sonics Silicon Backplane
 #
-# CONFIG_VIDEO_DEV is not set
+# CONFIG_SSB is not set
 
 #
-# Digital Video Broadcasting Devices
+# Multifunction device drivers
 #
-# CONFIG_DVB is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID 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_S1D13XXX is not set
 CONFIG_FB_AU1100=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
@@ -804,9 +785,10 @@ CONFIG_FB_AU1100=y
 # 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_8x8 is not set
 CONFIG_FONT_8x16=y
 # CONFIG_FONT_6x11 is not set
 # CONFIG_FONT_7x14 is not set
@@ -816,132 +798,186 @@ CONFIG_FONT_8x16=y
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_SUN12x22 is not set
 # CONFIG_FONT_10x18 is not set
-
-#
-# Logo configuration
-#
-CONFIG_LOGO=y
-CONFIG_LOGO_LINUX_MONO=y
-CONFIG_LOGO_LINUX_VGA16=y
-CONFIG_LOGO_LINUX_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
+# CONFIG_LOGO is not set
 # CONFIG_SOUND is not set
-
-#
-# HID Devices
-#
-# CONFIG_HID is not set
-
-#
-# USB support
-#
+# 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 is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Miscellaneous USB options
 #
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST 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 Gadget Support
+# USB Host Controller Drivers
 #
-# CONFIG_USB_GADGET is not set
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
 
 #
-# MMC/SD Card support
+# USB Device Class drivers
 #
-# CONFIG_MMC is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
-# LED devices
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
-# CONFIG_NEW_LEDS is not set
 
 #
-# LED drivers
+# also be needed; see USB_STORAGE Help for more info
 #
+# CONFIG_USB_LIBUSUAL is not set
 
 #
-# LED Triggers
+# USB Imaging devices
 #
+# CONFIG_USB_MDC800 is not set
 
 #
-# InfiniBand support
+# USB port drivers
 #
+# CONFIG_USB_SERIAL is not set
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# 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
 
 #
-# Real Time Clock
+# OTG and related infrastructure
 #
-# CONFIG_RTC_CLASS is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
 
 #
-# DMA Engine support
+# RTC interfaces
 #
-# CONFIG_DMA_ENGINE is not set
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
 
 #
-# DMA Clients
+# SPI RTC drivers
 #
 
 #
-# DMA Devices
+# Platform RTC drivers
 #
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
-# Auxiliary Display support
+# on-CPU RTC drivers
 #
+CONFIG_RTC_DRV_AU1XXX=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
 
 #
-# Virtualization
+# TI VLYNQ
 #
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-# CONFIG_EXT2_FS_SECURITY is not set
+# 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=y
-CONFIG_EXT3_FS_SECURITY=y
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=m
-CONFIG_GENERIC_ACL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -960,69 +996,76 @@ CONFIG_GENERIC_ACL=y
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
+# CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+# CONFIG_PROC_PAGE_MONITOR is not set
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
-# CONFIG_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 is not set
-CONFIG_CRAMFS=m
+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=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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
-CONFIG_EXPORTFS=m
+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=m
-# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS=m
+CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_CODEPAGE_437 is not set
 # CONFIG_NLS_CODEPAGE_737 is not set
@@ -1062,34 +1105,71 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
-
-#
-# Distributed Lock Manager
-#
-CONFIG_DLM=m
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
+# 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_STRIP_ASM_SYMS=y
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_CROSSCOMPILE=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
+# 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_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_EARLY_PRINTK=y
 # CONFIG_CMDLINE_BOOL is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_RUNTIME_DEBUG is not set
+CONFIG_DEBUG_ZBOOT=y
 
 #
 # Security options
@@ -1097,67 +1177,32 @@ CONFIG_CROSSCOMPILE=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+CONFIG_SECURITYFS=y
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=m
-CONFIG_CRC16=m
+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_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
-CONFIG_TEXTSEARCH_BM=m
-CONFIG_TEXTSEARCH_FSM=m
-CONFIG_PLIST=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/configs/db1200_defconfig linux-libre-2.6.34-gnu1/arch/mips/configs/db1200_defconfig
--- linux-libre-2.6.33-gnu1/arch/mips/configs/db1200_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/configs/db1200_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,78 +1,102 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:25 2007
+# Linux kernel version: 2.6.33
+# Fri Feb 26 10:18:09 2010
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
-CONFIG_ZONE_DMA=y
 CONFIG_MACH_ALCHEMY=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-CONFIG_MIPS_DB1200=y
-# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_AR7 is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
-# CONFIG_WR_PPMC is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
-# CONFIG_MARKEINS is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
 # CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
 # CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
 # CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+CONFIG_ALCHEMY_GPIOINT_AU1000=y
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+CONFIG_MIPS_DB1200=y
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_XXS1500 is not set
+CONFIG_SOC_AU1200=y
+CONFIG_SOC_AU1X00=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_TIME=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CSRC_R4K_LIB=y
 CONFIG_DMA_COHERENT=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
 CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SOC_AU1200=y
-CONFIG_SOC_AU1X00=y
+CONFIG_IRQ_CPU=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
 
 #
 # CPU selection
 #
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -85,6 +109,7 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
@@ -92,11 +117,14 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_SUPPORTS_ZBOOT=y
 CONFIG_SYS_HAS_CPU_MIPS32_R1=y
 CONFIG_CPU_MIPS32=y
 CONFIG_CPU_MIPSR1=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
 
 #
 # Kernel type
@@ -106,180 +134,235 @@ CONFIG_32BIT=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_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_SPARSEMEM_STATIC is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
+CONFIG_HZ_100=y
 # CONFIG_HZ_128 is not set
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
 # CONFIG_HZ_1024 is not set
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
+CONFIG_HZ=100
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION="-db1200"
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
 CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_SYSFS_DEPRECATED=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_RCU is not set
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=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_CC_OPTIMIZE_FOR_SIZE 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_EXTRA_PASS is not set
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
+# CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
 
 #
-# Loadable module support
+# GCOV-based kernel profiling
 #
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
+# 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_LSF is not set
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
 
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-CONFIG_PCCARD=m
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=m
+CONFIG_PCCARD=y
+CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
+# CONFIG_PCMCIA_IOCTL is not set
 
 #
 # PC-card bridges
 #
-CONFIG_PCMCIA_AU1X00=m
-
-#
-# PCI Hotplug Support
-#
+# CONFIG_PCMCIA_AU1X00 is not set
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
 
 #
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=y
 CONFIG_TRAD_SIGNALS=y
 
 #
 # Power management options
 #
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PM is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
+CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=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_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
@@ -290,107 +373,25 @@ CONFIG_IP_FIB_HASH=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_LRO=y
+# CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
+# 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=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# Core Netfilter Configuration
-#
-# CONFIG_NETFILTER_NETLINK is not set
-CONFIG_NF_CONNTRACK_ENABLED=m
-CONFIG_NF_CONNTRACK_SUPPORT=y
-# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CT_ACCT=y
-CONFIG_NF_CONNTRACK_MARK=y
-CONFIG_NF_CONNTRACK_SECMARK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_GRE=m
-CONFIG_NF_CT_PROTO_SCTP=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 is not set
-CONFIG_NF_CONNTRACK_PPTP=m
-CONFIG_NF_CONNTRACK_SANE=m
-CONFIG_NF_CONNTRACK_SIP=m
-CONFIG_NF_CONNTRACK_TFTP=m
-CONFIG_NETFILTER_XTABLES=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=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_HELPER=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_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-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_HASHLIMIT=m
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_CONNTRACK_PROC_COMPAT=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -400,21 +401,24 @@ CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-# CONFIG_IEEE80211 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
@@ -423,25 +427,25 @@ CONFIG_NET_CLS_ROUTE=y
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+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
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -454,6 +458,7 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -479,19 +484,21 @@ 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_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_ALCHEMY=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_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -503,224 +510,134 @@ CONFIG_MTD_ALCHEMY=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 CONFIG_MTD_NAND=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_AU1550 is not set
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
-
-#
-# OneNAND Flash Device Drivers
-#
+CONFIG_MTD_NAND_PLATFORM=y
+# CONFIG_MTD_ALAUDA is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
+# LPDDR flash memory drivers
 #
-# CONFIG_PNPACPI is not set
+# CONFIG_MTD_LPDDR is not set
 
 #
-# Block devices
+# 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=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
 
 #
-# ATA/ATAPI/MFM/RLL support
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
 #
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_UB=y
+# 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=y
-CONFIG_IDE_MAX_HWIFS=4
-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_XFER_MODE=y
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
-CONFIG_BLK_DEV_IDECS=m
-# CONFIG_BLK_DEV_IDECD is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 # CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_TASK_IOCTL=y
+# CONFIG_IDE_PROC_FS is not set
 
 #
 # IDE chipset support/bugfixes
 #
-CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
 CONFIG_BLK_DEV_IDE_AU1XXX=y
 CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA=y
 # CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA is not set
-CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128
-# CONFIG_IDE_ARM 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=y
-CONFIG_SCSI_TGT=m
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=y
-# CONFIG_BLK_DEV_SR_VENDOR 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 is not set
-CONFIG_SCSI_SCAN_ASYNC=y
-
-#
-# SCSI Transports
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
 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
-
-#
-# PHY device support
-#
+# CONFIG_VETH is not set
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
-CONFIG_MII=m
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
 # CONFIG_MIPS_AU1X00_ENET is not set
-# CONFIG_SMC91X is not set
+CONFIG_SMC91X=y
 # CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
 
 #
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_NET_RADIO is not set
 
 #
-# PCMCIA network device support
+# 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
-
-#
-# Wan interfaces
-#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -728,16 +645,14 @@ CONFIG_MII=m
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
@@ -747,28 +662,26 @@ CONFIG_INPUT_EVDEV=y
 # 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 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
+# 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_AU1X00_GPIO is not set
 
 #
 # Serial drivers
@@ -776,33 +689,22 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 # CONFIG_SERIAL_8250_CS is not set
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
 # CONFIG_SERIAL_8250_EXTENDED is not set
 CONFIG_SERIAL_8250_AU1X00=y
 
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 
 #
@@ -811,223 +713,624 @@ CONFIG_LEGACY_PTY_COUNT=256
 # 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_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
 
 #
-# TPM devices
+# I2C Algorithms
 #
-# CONFIG_TCG_TPM is not set
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
 
 #
-# I2C support
+# I2C Hardware Bus support
 #
-# CONFIG_I2C is not set
 
 #
-# SPI support
+# I2C system bus drivers (mostly embedded / system-on-chip)
 #
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
+CONFIG_I2C_AU1550=y
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
 
 #
-# Dallas's 1-wire bus
+# 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_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_AU1550=y
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
 #
 # CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=y
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# Hardware Monitoring support
+# Native drivers
 #
-# CONFIG_HWMON is not set
-# 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=y
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+CONFIG_SENSORS_LM70=y
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
-# Multimedia devices
+# Sonics Silicon Backplane
 #
-# CONFIG_VIDEO_DEV is not set
+# CONFIG_SSB is not set
 
 #
-# Digital Video Broadcasting Devices
+# Multifunction device drivers
 #
-# CONFIG_DVB is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID 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_S1D13XXX is not set
 CONFIG_FB_AU1200=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_VGA_CONSOLE=y
-# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+# CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE is not set
+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=y
+# CONFIG_SOUND_OSS_CORE is not set
+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
+# CONFIG_SND_HRTIMER is not set
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_AC97_CODEC=y
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_MIPS is not set
+# CONFIG_SND_USB is not set
+# CONFIG_SND_PCMCIA is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_SOC_AU1XPSC=y
+CONFIG_SND_SOC_AU1XPSC_I2S=y
+CONFIG_SND_SOC_AU1XPSC_AC97=y
+CONFIG_SND_SOC_DB1200=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_AC97_CODEC=y
+CONFIG_SND_SOC_WM8731=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
 
 #
-# Logo configuration
+# USB Input Devices
 #
-CONFIG_LOGO=y
-CONFIG_LOGO_LINUX_MONO=y
-CONFIG_LOGO_LINUX_VGA16=y
-CONFIG_LOGO_LINUX_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
 
 #
-# Sound
+# Special HID drivers
 #
-# CONFIG_SOUND 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_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 
 #
-# HID Devices
+# Miscellaneous USB options
 #
-CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=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 support
+# USB Host Controller Drivers
 #
-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_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=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
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# 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
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
-CONFIG_USB_GADGET=m
-# CONFIG_USB_GADGET_DEBUG_FILES is not set
-# CONFIG_USB_GADGET_NET2280 is not set
-# CONFIG_USB_GADGET_PXA2XX is not set
-# CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_LH7A40X is not set
-# CONFIG_USB_GADGET_OMAP is not set
-# CONFIG_USB_GADGET_AT91 is not set
-# CONFIG_USB_GADGET_DUMMY_HCD is not set
-# CONFIG_USB_GADGET_DUALSPEED is not set
 
 #
-# MMC/SD Card support
+# also be needed; see USB_STORAGE Help for more info
+#
+# 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_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_AU1X=y
+# CONFIG_MMC_UNSAFE_RESUME is not set
 
 #
-# LED devices
+# MMC/SD/SDIO Card Drivers
 #
-# CONFIG_NEW_LEDS is not set
+CONFIG_MMC_BLOCK=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
 
 #
-# LED drivers
+# MMC/SD/SDIO Host Controller Drivers
 #
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_AU1X=y
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
 
 #
-# LED Triggers
+# LED drivers
 #
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
 
 #
-# InfiniBand support
+# LED Triggers
 #
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# iptables trigger is under Netfilter config (LED target)
 #
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
 
 #
-# Real Time Clock
+# RTC interfaces
 #
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
 
 #
-# DMA Engine support
+# I2C RTC drivers
 #
-# CONFIG_DMA_ENGINE is not set
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
-# DMA Clients
+# SPI RTC drivers
 #
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
-# DMA Devices
+# Platform RTC drivers
 #
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
-# Auxiliary Display support
+# on-CPU RTC drivers
 #
+CONFIG_RTC_DRV_AU1XXX=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
 
 #
-# Virtualization
+# TI VLYNQ
 #
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-# CONFIG_EXT2_FS_SECURITY is not set
+# 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=y
-CONFIG_EXT3_FS_SECURITY=y
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
 # CONFIG_REISERFS_FS is not set
-CONFIG_JFS_FS=y
-# CONFIG_JFS_POSIX_ACL is not set
-# CONFIG_JFS_SECURITY is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
-CONFIG_FS_POSIX_ACL=y
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
-CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
 #
-CONFIG_ISO9660_FS=m
+CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
-CONFIG_UDF_FS=m
+CONFIG_UDF_FS=y
 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 is not set
+CONFIG_VFAT_FS=y
 CONFIG_FAT_DEFAULT_CODEPAGE=437
 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
@@ -1036,21 +1339,17 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
+# CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+# CONFIG_PROC_PAGE_MONITOR is not set
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
-# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -1059,27 +1358,36 @@ CONFIG_CONFIGFS_FS=m
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
-# CONFIG_JFFS2_SUMMARY is not set
+# 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_COMPRESSION_OPTIONS=y
 CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
 CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-CONFIG_CRAMFS=m
+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
-
-#
-# Network File Systems
-#
+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_ROOT_NFS=y
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -1087,93 +1395,140 @@ CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
-CONFIG_SMB_FS=y
-# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
 #
-# CONFIG_PARTITION_ADVANCED is not set
+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
-
-#
-# Native Language Support
-#
+# 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=y
+# CONFIG_SYSV68_PARTITION is not set
 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
-
-#
-# Distributed Lock Manager
-#
-CONFIG_DLM=m
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
+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=y
+# 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=y
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+CONFIG_NLS_ISO8859_15=y
+# 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_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_MUST_CHECK=y
-# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_STRIP_ASM_SYMS=y
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_CROSSCOMPILE=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
+# 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_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_EARLY_PRINTK=y
 CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="mem=48M"
+CONFIG_CMDLINE="console=ttyS0,115200"
 # CONFIG_CMDLINE_OVERRIDE is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_RUNTIME_DEBUG is not set
+CONFIG_DEBUG_ZBOOT=y
 
 #
 # Security options
@@ -1181,67 +1536,32 @@ CONFIG_CMDLINE="mem=48M"
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=m
-CONFIG_CRYPTO_MANAGER=m
-CONFIG_CRYPTO_HMAC=m
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+CONFIG_SECURITYFS=y
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=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=y
 CONFIG_CRC32=y
-CONFIG_LIBCRC32C=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
-CONFIG_TEXTSEARCH_BM=m
-CONFIG_TEXTSEARCH_FSM=m
-CONFIG_PLIST=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/configs/db1500_defconfig linux-libre-2.6.34-gnu1/arch/mips/configs/db1500_defconfig
--- linux-libre-2.6.33-gnu1/arch/mips/configs/db1500_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/configs/db1500_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,80 +1,104 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:26 2007
+# Linux kernel version: 2.6.33
+# Fri Feb 26 08:46:33 2010
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
-CONFIG_ZONE_DMA=y
 CONFIG_MACH_ALCHEMY=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-CONFIG_MIPS_DB1500=y
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_AR7 is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
-# CONFIG_WR_PPMC is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
-# CONFIG_MARKEINS is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
 # CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
 # CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
 # CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+CONFIG_ALCHEMY_GPIOINT_AU1000=y
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1200 is not set
+CONFIG_MIPS_DB1500=y
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_XXS1500 is not set
+CONFIG_SOC_AU1500=y
+CONFIG_SOC_AU1X00=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_TIME=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CSRC_R4K_LIB=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
 CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SOC_AU1500=y
-CONFIG_SOC_AU1X00=y
+CONFIG_IRQ_CPU=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
 
 #
 # CPU selection
 #
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -87,6 +111,7 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
@@ -94,11 +119,14 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_SUPPORTS_ZBOOT=y
 CONFIG_SYS_HAS_CPU_MIPS32_R1=y
 CONFIG_CPU_MIPS32=y
 CONFIG_CPU_MIPSR1=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
 
 #
 # Kernel type
@@ -108,137 +136,207 @@ CONFIG_32BIT=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_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_SPARSEMEM_STATIC is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
-CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
+CONFIG_HZ_100=y
 # CONFIG_HZ_128 is not set
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
 # CONFIG_HZ_1024 is not set
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
+CONFIG_HZ=100
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION="-db1500"
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_RELAY=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_KALLSYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_PCI_QUIRKS=y
+# CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
+# CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
 
 #
-# Loadable module support
+# GCOV-based kernel profiling
 #
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
+# 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_LSF is not set
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
 
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCI_LEGACY is not set
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-CONFIG_PCCARD=m
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=m
+CONFIG_PCCARD=y
+CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
-CONFIG_CARDBUS=y
+# CONFIG_PCMCIA_IOCTL is not set
+# CONFIG_CARDBUS is not set
 
 #
 # PC-card bridges
@@ -246,51 +344,49 @@ CONFIG_CARDBUS=y
 # CONFIG_YENTA is not set
 # CONFIG_PD6729 is not set
 # CONFIG_I82092 is not set
-CONFIG_PCMCIA_AU1X00=m
-
-#
-# PCI Hotplug Support
-#
+# CONFIG_PCMCIA_AU1X00 is not set
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
 # CONFIG_HOTPLUG_PCI is not set
 
 #
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 CONFIG_TRAD_SIGNALS=y
 
 #
 # Power management options
 #
-# CONFIG_PM is not set
-
-#
-# Networking
-#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
+CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=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_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
+CONFIG_IP_PNP_RARP=y
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
@@ -301,110 +397,25 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_LRO=y
+# CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
+# 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=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# Core Netfilter Configuration
-#
-CONFIG_NETFILTER_NETLINK=m
-CONFIG_NETFILTER_NETLINK_QUEUE=m
-CONFIG_NETFILTER_NETLINK_LOG=m
-CONFIG_NF_CONNTRACK_ENABLED=m
-CONFIG_NF_CONNTRACK_SUPPORT=y
-# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CT_ACCT=y
-CONFIG_NF_CONNTRACK_MARK=y
-CONFIG_NF_CONNTRACK_SECMARK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_GRE=m
-CONFIG_NF_CT_PROTO_SCTP=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 is not set
-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_XTABLES=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=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_HELPER=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_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-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_HASHLIMIT=m
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_CONNTRACK_PROC_COMPAT=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -414,27 +425,24 @@ CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
+# 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
@@ -443,25 +451,25 @@ CONFIG_WIRELESS_EXT=y
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=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
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
+# CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -474,6 +482,7 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -499,14 +508,14 @@ 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_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_ALCHEMY=y
+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
 
 #
@@ -524,152 +533,152 @@ CONFIG_MTD_ALCHEMY=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 # CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
 # CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
+# LPDDR flash memory drivers
 #
-# CONFIG_PNPACPI is not set
+# CONFIG_MTD_LPDDR is not set
 
 #
-# Block devices
+# 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_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=m
-
-#
-# Misc devices
-#
-CONFIG_SGI_IOC4=m
-# CONFIG_TIFM_CORE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# 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=y
-CONFIG_IDE_MAX_HWIFS=4
-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_XFER_MODE=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECS=m
-# CONFIG_BLK_DEV_DELKIN is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+CONFIG_BLK_DEV_IDECS=y
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
 
 #
 # IDE chipset support/bugfixes
 #
 # CONFIG_IDE_GENERIC is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_IDEDMA_SFF=y
 
 #
-# SCSI device support
+# PCI IDE chipsets support
 #
-CONFIG_RAID_ATTRS=m
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_NETLINK is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_PCIBUS_ORDER is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# 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=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
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
+CONFIG_BLK_DEV_IDEDMA=y
 
 #
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
+# 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
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
 # CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
-# I2O device support
+# You can enable one or both FireWire driver stacks.
 #
-# CONFIG_I2O is not set
 
 #
-# Network device support
+# The newer stack is recommended.
 #
+# 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
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
 CONFIG_PHYLIB=y
 
 #
 # MII PHY device drivers
 #
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
-# CONFIG_BROADCOM_PHY is not set
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
 # CONFIG_FIXED_PHY is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
 CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
@@ -677,88 +686,51 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
-
-#
-# Tulip family network device support
-#
+# CONFIG_ETHOC 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 is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-CONFIG_QLA3XXX=m
-# CONFIG_ATL1 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-CONFIG_CHELSIO_T3=m
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-CONFIG_NETXEN_NIC=m
-
-#
-# Token Ring devices
-#
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_ATL2 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
+# CONFIG_WLAN is not set
 
 #
-# Wireless LAN (non-hamradio)
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_NET_RADIO is not set
 
 #
-# PCMCIA network device support
+# 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
-
-#
-# Wan interfaces
-#
 # 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 is not set
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-# CONFIG_PPP_BSDCOMP is not set
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
+# CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-CONFIG_SLHC=m
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -766,16 +738,14 @@ CONFIG_SLHC=m
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
@@ -785,33 +755,34 @@ CONFIG_INPUT_EVDEV=y
 # 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 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
+# CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
 
 #
 # Character devices
 #
-# CONFIG_VT is not set
+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_AU1X00_GPIO 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_PCI is not set
 # CONFIG_SERIAL_8250_CS is not set
 CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
@@ -825,301 +796,143 @@ 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
-
-#
-# IPMI
-#
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
 
 #
 # PCMCIA character devices
 #
-CONFIG_SYNCLINK_CS=m
+# 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
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
 
 #
-# Dallas's 1-wire bus
+# PPS support
 #
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
-# Multimedia devices
+# Sonics Silicon Backplane
 #
-# CONFIG_VIDEO_DEV is not set
+# CONFIG_SSB is not set
 
 #
-# Digital Video Broadcasting Devices
+# Multifunction device drivers
 #
-# CONFIG_DVB is not set
-# CONFIG_USB_DABUSB is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_VGA_ARB is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Sound
-#
-CONFIG_SOUND=y
-
-#
-# Advanced Linux Sound Architecture
-#
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
-CONFIG_SND_RAWMIDI=m
-CONFIG_SND_SEQUENCER=m
-CONFIG_SND_SEQ_DUMMY=m
-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 is not set
-# CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
-CONFIG_SND_AC97_CODEC=m
-# CONFIG_SND_DUMMY is not set
-CONFIG_SND_VIRMIDI=m
-CONFIG_SND_MTPAV=m
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-
-#
-# PCI devices
-#
-# 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_AZT3328 is not set
-# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_CMIPCI 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_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_VX222 is not set
-# CONFIG_SND_YMFPCI is not set
-# CONFIG_SND_AC97_POWER_SAVE is not set
-
-#
-# ALSA MIPS devices
-#
-CONFIG_SND_AU1X00=m
-
-#
-# USB devices
-#
-# CONFIG_SND_USB_AUDIO is not set
-
-#
-# PCMCIA devices
-#
-# CONFIG_SND_VXPOCKET is not set
-# CONFIG_SND_PDAUDIOCF is not set
-
-#
-# SoC audio support
-#
-# CONFIG_SND_SOC is not set
-
-#
-# Open Sound System
-#
-CONFIG_SOUND_PRIME=y
-# CONFIG_OBSOLETE_OSS is not set
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_ICH 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_AC97_BUS=m
-
-#
-# HID Devices
+# Display device support
 #
-CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
-# USB support
+# Console display driver support
 #
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
 
 #
 # Miscellaneous USB options
 #
 # CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
 # CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
 
 #
 # USB Host Controller Drivers
 #
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
 # CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD 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 enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# may also be needed; see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 # CONFIG_USB_LIBUSUAL is not set
 
 #
-# 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_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_TOUCHSCREEN is not set
-CONFIG_USB_YEALINK=m
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_GTCO is not set
-
-#
 # USB Imaging devices
 #
 # CONFIG_USB_MDC800 is not set
 
 #
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET_MII is not set
-# CONFIG_USB_USBNET is not set
-CONFIG_USB_MON=y
-
-#
 # USB port drivers
 #
-
-#
-# USB Serial Converter support
-#
 # CONFIG_USB_SERIAL is not set
 
 #
@@ -1128,7 +941,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -1136,112 +949,107 @@ CONFIG_USB_MON=y
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
-CONFIG_USB_LD=m
+# CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
+# 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
 
 #
-# MMC/SD Card support
+# 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
-
-#
-# LED devices
-#
+# CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
+# 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
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
-# CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
+# RTC interfaces
 #
-# CONFIG_DMA_ENGINE is not set
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
 
 #
-# DMA Clients
+# SPI RTC drivers
 #
 
 #
-# DMA Devices
+# Platform RTC drivers
 #
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
-# Auxiliary Display support
+# on-CPU RTC drivers
 #
+CONFIG_RTC_DRV_AU1XXX=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
 
 #
-# Virtualization
+# TI VLYNQ
 #
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-# CONFIG_EXT2_FS_SECURITY is not set
+# 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=y
-CONFIG_EXT3_FS_SECURITY=y
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=m
-CONFIG_GENERIC_ACL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1260,74 +1068,81 @@ CONFIG_GENERIC_ACL=y
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
+# CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+# CONFIG_PROC_PAGE_MONITOR is not set
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
-# CONFIG_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 is not set
-CONFIG_CRAMFS=m
+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=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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
-CONFIG_EXPORTFS=m
+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=m
-# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS=m
+CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
+CONFIG_NLS_CODEPAGE_437=y
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
+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
@@ -1345,10 +1160,10 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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_1250=y
 # CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
+CONFIG_NLS_ASCII=y
+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
@@ -1358,38 +1173,76 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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_ISO8859_15=y
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Distributed Lock Manager
-#
-CONFIG_DLM=m
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
+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=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+CONFIG_STRIP_ASM_SYMS=y
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_CROSSCOMPILE=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
+# 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_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_EARLY_PRINTK=y
 # CONFIG_CMDLINE_BOOL is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_RUNTIME_DEBUG is not set
+CONFIG_DEBUG_ZBOOT=y
 
 #
 # Security options
@@ -1397,67 +1250,32 @@ CONFIG_CROSSCOMPILE=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+CONFIG_SECURITYFS=y
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=m
-CONFIG_CRC16=m
+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_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
-CONFIG_TEXTSEARCH_BM=m
-CONFIG_TEXTSEARCH_FSM=m
-CONFIG_PLIST=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/configs/db1550_defconfig linux-libre-2.6.34-gnu1/arch/mips/configs/db1550_defconfig
--- linux-libre-2.6.33-gnu1/arch/mips/configs/db1550_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/configs/db1550_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,79 +1,103 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:27 2007
+# Linux kernel version: 2.6.33
+# Fri Feb 26 08:58:22 2010
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
-CONFIG_ZONE_DMA=y
 CONFIG_MACH_ALCHEMY=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-CONFIG_MIPS_DB1550=y
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_AR7 is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
-# CONFIG_WR_PPMC is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
-# CONFIG_MARKEINS is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
 # CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
 # CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
 # CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+CONFIG_ALCHEMY_GPIOINT_AU1000=y
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_DB1500 is not set
+CONFIG_MIPS_DB1550=y
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_XXS1500 is not set
+CONFIG_SOC_AU1550=y
+CONFIG_SOC_AU1X00=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_TIME=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CSRC_R4K_LIB=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
 CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SOC_AU1550=y
-CONFIG_SOC_AU1X00=y
+CONFIG_IRQ_CPU=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
 
 #
 # CPU selection
 #
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -86,6 +110,7 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
@@ -93,11 +118,14 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_SUPPORTS_ZBOOT=y
 CONFIG_SYS_HAS_CPU_MIPS32_R1=y
 CONFIG_CPU_MIPS32=y
 CONFIG_CPU_MIPSR1=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
 
 #
 # Kernel type
@@ -107,137 +135,205 @@ CONFIG_32BIT=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_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_SPARSEMEM_STATIC is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
-CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
+CONFIG_HZ_100=y
 # CONFIG_HZ_128 is not set
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
 # CONFIG_HZ_1024 is not set
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
+CONFIG_HZ=100
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION="-db1550"
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
 CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_RCU is not set
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_RELAY=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_PCI_QUIRKS=y
+# CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
+# CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
 
 #
-# Loadable module support
+# GCOV-based kernel profiling
 #
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
+# 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_LSF is not set
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
 
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-CONFIG_PCCARD=m
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=m
+CONFIG_PCCARD=y
+CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
-CONFIG_CARDBUS=y
+# CONFIG_PCMCIA_IOCTL is not set
+# CONFIG_CARDBUS is not set
 
 #
 # PC-card bridges
@@ -245,51 +341,49 @@ CONFIG_CARDBUS=y
 # CONFIG_YENTA is not set
 # CONFIG_PD6729 is not set
 # CONFIG_I82092 is not set
-CONFIG_PCMCIA_AU1X00=m
-
-#
-# PCI Hotplug Support
-#
+# CONFIG_PCMCIA_AU1X00 is not set
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
 # CONFIG_HOTPLUG_PCI is not set
 
 #
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 CONFIG_TRAD_SIGNALS=y
 
 #
 # Power management options
 #
-# CONFIG_PM is not set
-
-#
-# Networking
-#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
+CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=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_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
+CONFIG_IP_PNP_RARP=y
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
@@ -300,110 +394,25 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_LRO=y
+# CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
+# 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=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# Core Netfilter Configuration
-#
-CONFIG_NETFILTER_NETLINK=m
-CONFIG_NETFILTER_NETLINK_QUEUE=m
-CONFIG_NETFILTER_NETLINK_LOG=m
-CONFIG_NF_CONNTRACK_ENABLED=m
-CONFIG_NF_CONNTRACK_SUPPORT=y
-# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CT_ACCT=y
-CONFIG_NF_CONNTRACK_MARK=y
-CONFIG_NF_CONNTRACK_SECMARK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_GRE=m
-CONFIG_NF_CT_PROTO_SCTP=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 is not set
-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_XTABLES=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=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_HELPER=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_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-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_HASHLIMIT=m
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_CONNTRACK_PROC_COMPAT=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -413,27 +422,24 @@ CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
+# 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
@@ -442,25 +448,25 @@ CONFIG_WIRELESS_EXT=y
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=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
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
+# CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -473,6 +479,7 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -498,20 +505,23 @@ 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_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_ALCHEMY=y
+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_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -523,105 +533,96 @@ CONFIG_MTD_ALCHEMY=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-CONFIG_MTD_NAND=m
+CONFIG_MTD_NAND=y
 # CONFIG_MTD_NAND_VERIFY_WRITE is not set
 # CONFIG_MTD_NAND_ECC_SMC is not set
-CONFIG_MTD_NAND_IDS=m
-CONFIG_MTD_NAND_AU1550=m
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_AU1550=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_CAFE is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
-
-#
-# OneNAND Flash Device Drivers
-#
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
+# LPDDR flash memory drivers
 #
-# CONFIG_PNPACPI is not set
+# CONFIG_MTD_LPDDR is not set
 
 #
-# Block devices
+# 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_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=m
-
-#
-# Misc devices
-#
-CONFIG_SGI_IOC4=m
-# CONFIG_TIFM_CORE is not set
+# CONFIG_BLK_DEV_LOOP is not set
 
 #
-# ATA/ATAPI/MFM/RLL support
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
 #
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_UB=y
+# 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=y
-CONFIG_IDE_MAX_HWIFS=4
-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_XFER_MODE=y
+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_BLK_DEV_IDECS=m
-# CONFIG_BLK_DEV_DELKIN is not set
-# CONFIG_BLK_DEV_IDECD is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS 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_TASK_IOCTL=y
+CONFIG_IDE_PROC_FS=y
 
 #
 # IDE chipset support/bugfixes
 #
-CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_IDEDMA_SFF=y
+
+#
+# PCI IDE chipsets support
+#
 CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_IDEPCI_PCIBUS_ORDER is not set
 # CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_GENERIC is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_PCI_AUTO is not set
 # 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_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5520 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
+CONFIG_BLK_DEV_HPT366=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_IT8213=m
+# 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
@@ -631,82 +632,65 @@ CONFIG_BLK_DEV_IT8213=m
 # 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=m
-# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
 CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
 #
-CONFIG_RAID_ATTRS=m
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
 # CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
-# I2O device support
+# You can enable one or both FireWire driver stacks.
 #
-# CONFIG_I2O is not set
 
 #
-# Network device support
+# The newer stack is recommended.
 #
+# 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
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
 CONFIG_PHYLIB=y
 
 #
 # MII PHY device drivers
 #
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
-# CONFIG_BROADCOM_PHY is not set
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
 # CONFIG_FIXED_PHY is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
-CONFIG_MII=m
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
 CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
@@ -714,96 +698,53 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
-
-#
-# Tulip family network device support
-#
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC 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 is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-CONFIG_QLA3XXX=m
-# CONFIG_ATL1 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-CONFIG_CHELSIO_T3=m
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-CONFIG_NETXEN_NIC=m
-
-#
-# Token Ring devices
-#
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_ATL2 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
+# CONFIG_WLAN is not set
 
 #
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# PCMCIA network device support
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-CONFIG_PCMCIA_AXNET=m
 
 #
-# Wan interfaces
+# 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 is not set
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-# CONFIG_PPP_BSDCOMP is not set
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
+# CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-CONFIG_SLHC=m
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -811,16 +752,14 @@ CONFIG_SLHC=m
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
@@ -830,26 +769,27 @@ CONFIG_INPUT_EVDEV=y
 # 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 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
+# CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
 
 #
 # Character devices
 #
-# CONFIG_VT is not set
+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_AU1X00_GPIO is not set
+# CONFIG_NOZOMI is not set
 
 #
 # Serial drivers
@@ -866,199 +806,420 @@ CONFIG_SERIAL_8250_AU1X00=y
 #
 # 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_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
 
 #
 # PCMCIA character devices
 #
-CONFIG_SYNCLINK_CS=m
+# CONFIG_SYNCLINK_CS is not set
 # CONFIG_CARDMAN_4000 is not set
 # CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
 # CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
 
 #
-# TPM devices
+# I2C Algorithms
 #
-# CONFIG_TCG_TPM is not set
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
 
 #
-# I2C support
+# I2C Hardware Bus support
 #
-# CONFIG_I2C is not set
 
 #
-# SPI support
+# PC SMBus host controller drivers
 #
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
+# 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
 
 #
-# Dallas's 1-wire bus
+# I2C system bus drivers (mostly embedded / system-on-chip)
 #
-# CONFIG_W1 is not set
+CONFIG_I2C_AU1550=y
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
 
 #
-# Hardware Monitoring support
+# 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_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_AU1550=y
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
 #
+# CONFIG_PPS is not set
+CONFIG_ARCH_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_VID is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
-# Multimedia devices
+# Sonics Silicon Backplane
 #
-# CONFIG_VIDEO_DEV is not set
+# CONFIG_SSB is not set
 
 #
-# Digital Video Broadcasting Devices
+# Multifunction device drivers
 #
-# CONFIG_DVB is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_VGA_ARB is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# HID Devices
+# Display device support
 #
-# CONFIG_HID is not set
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
-# USB support
+# 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_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=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_PCI is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_MIPS is not set
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_PCMCIA is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_AU1XPSC=y
+# CONFIG_SND_SOC_DB1200 is not set
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Miscellaneous USB options
 #
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST 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 Gadget Support
+# USB Host Controller Drivers
 #
-# CONFIG_USB_GADGET is not set
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=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
 
 #
-# MMC/SD Card support
+# USB Device Class drivers
 #
-# CONFIG_MMC is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
-# LED devices
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
-# CONFIG_NEW_LEDS is not set
 
 #
-# LED drivers
+# also be needed; see USB_STORAGE Help for more info
 #
+# CONFIG_USB_LIBUSUAL is not set
 
 #
-# LED Triggers
+# USB Imaging devices
 #
+# CONFIG_USB_MDC800 is not set
 
 #
-# InfiniBand support
+# USB port drivers
 #
-# CONFIG_INFINIBAND is not set
+# CONFIG_USB_SERIAL is not set
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# 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
 
 #
-# Real Time Clock
+# OTG and related infrastructure
 #
-# CONFIG_RTC_CLASS is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
 
 #
-# DMA Engine support
+# RTC interfaces
 #
-# CONFIG_DMA_ENGINE is not set
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
 
 #
-# DMA Clients
+# I2C RTC drivers
 #
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
-# DMA Devices
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
 #
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
-# Auxiliary Display support
+# on-CPU RTC drivers
 #
+CONFIG_RTC_DRV_AU1XXX=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
 
 #
-# Virtualization
+# TI VLYNQ
 #
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-# CONFIG_EXT2_FS_SECURITY is not set
+# 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=y
-CONFIG_EXT3_FS_SECURITY=y
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
+# 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_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=m
-CONFIG_GENERIC_ACL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1077,75 +1238,82 @@ CONFIG_GENERIC_ACL=y
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
+# CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+# CONFIG_PROC_PAGE_MONITOR is not set
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+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 is not set
-CONFIG_CRAMFS=m
+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 is not set
+# CONFIG_JFFS2_FS_SECURITY is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_CRAMFS 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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
-CONFIG_EXPORTFS=m
+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=m
-# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS=m
+CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
+CONFIG_NLS_CODEPAGE_437=y
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
 # CONFIG_NLS_CODEPAGE_855 is not set
 # CONFIG_NLS_CODEPAGE_857 is not set
 # CONFIG_NLS_CODEPAGE_860 is not set
@@ -1162,10 +1330,10 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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_1250=y
 # CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
+CONFIG_NLS_ASCII=y
+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
@@ -1175,38 +1343,75 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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_ISO8859_15=y
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Distributed Lock Manager
-#
-CONFIG_DLM=m
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
+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=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_CROSSCOMPILE=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
+# 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_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_EARLY_PRINTK=y
 # CONFIG_CMDLINE_BOOL is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_RUNTIME_DEBUG is not set
+CONFIG_DEBUG_ZBOOT=y
 
 #
 # Security options
@@ -1214,67 +1419,32 @@ CONFIG_CROSSCOMPILE=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+CONFIG_SECURITYFS=y
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=m
-CONFIG_CRC16=m
+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_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
-CONFIG_TEXTSEARCH_BM=m
-CONFIG_TEXTSEARCH_FSM=m
-CONFIG_PLIST=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/configs/lemote2f_defconfig linux-libre-2.6.34-gnu1/arch/mips/configs/lemote2f_defconfig
--- linux-libre-2.6.33-gnu1/arch/mips/configs/lemote2f_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/configs/lemote2f_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc6
-# Mon Nov  9 23:42:42 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 13:41:09 2010
 #
 CONFIG_MIPS=y
 
@@ -27,6 +27,7 @@ CONFIG_MACH_LOONGSON=y
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP28 is not set
@@ -51,6 +52,9 @@ CONFIG_ARCH_SPARSEMEM_ENABLE=y
 # CONFIG_LEMOTE_FULOONG2E is not set
 CONFIG_LEMOTE_MACH2F=y
 CONFIG_CS5536=y
+CONFIG_CS5536_MFGPT=y
+CONFIG_LOONGSON_SUSPEND=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -63,13 +67,8 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_SCHED_OMIT_FRAME_POINTER=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_CEVT_R4K_LIB=y
-CONFIG_CEVT_R4K=y
-CONFIG_CSRC_R4K_LIB=y
-CONFIG_CSRC_R4K=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
-CONFIG_EARLY_PRINTK=y
 CONFIG_SYS_HAS_EARLY_PRINTK=y
 CONFIG_I8259=y
 # CONFIG_NO_IOPORT is not set
@@ -109,13 +108,15 @@ CONFIG_CPU_LOONGSON2F=y
 # CONFIG_CPU_SB1 is not set
 # CONFIG_CPU_CAVIUM_OCTEON is not set
 CONFIG_SYS_SUPPORTS_ZBOOT=y
-CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y
 CONFIG_CPU_LOONGSON2=y
 CONFIG_SYS_HAS_CPU_LOONGSON2F=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_CPUFREQ=y
+CONFIG_CPU_SUPPORTS_ADDRWINCFG=y
+CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED=y
 
 #
 # Kernel type
@@ -137,7 +138,6 @@ CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
 CONFIG_SYS_SUPPORTS_HIGHMEM=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
@@ -146,17 +146,11 @@ CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_SPARSEMEM=y
 CONFIG_HAVE_MEMORY_PRESENT=y
 CONFIG_SPARSEMEM_STATIC=y
-
-#
-# Memory hotplug is currently incompatible with Software Suspend
-#
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_TICK_ONESHOT=y
@@ -175,7 +169,7 @@ CONFIG_HZ=250
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
-# CONFIG_KEXEC is not set
+CONFIG_KEXEC=y
 # CONFIG_SECCOMP is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -194,9 +188,9 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
-# CONFIG_KERNEL_GZIP is not set
+CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
-CONFIG_KERNEL_LZMA=y
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -211,6 +205,7 @@ CONFIG_AUDIT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=64
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -224,7 +219,11 @@ CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -256,14 +255,18 @@ CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
-# CONFIG_PROFILING is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_SYSCALL_WRAPPERS=y
 
 #
 # GCOV-based kernel profiling
 #
-# CONFIG_SLOW_WORK is not set
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_SLOW_WORK_DEBUG is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -283,14 +286,41 @@ CONFIG_BLOCK_COMPAT=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_DEADLINE=m
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -314,7 +344,7 @@ CONFIG_MMU=y
 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_BINFMT_MISC=m
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
 CONFIG_SYSVIPC_COMPAT=y
@@ -335,9 +365,34 @@ CONFIG_SUSPEND_FREEZER=y
 CONFIG_HIBERNATION_NVS=y
 CONFIG_HIBERNATION=y
 CONFIG_PM_STD_PARTITION="/dev/hda3"
-# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_MIPS_EXTERNAL_TIMER=y
+CONFIG_MIPS_CPUFREQ=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_LOONGSON2_CPUFREQ=m
 CONFIG_NET=y
-CONFIG_COMPAT_NETLINK_MESSAGES=y
 
 #
 # Networking options
@@ -346,11 +401,12 @@ CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 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_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_ADVANCED_ROUTER=y
@@ -361,12 +417,13 @@ CONFIG_IP_MULTIPLE_TABLES=y
 CONFIG_IP_ROUTE_MULTIPATH=y
 CONFIG_IP_ROUTE_VERBOSE=y
 # CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+# CONFIG_NET_IPGRE_BROADCAST is not set
 CONFIG_IP_MROUTE=y
 CONFIG_IP_PIMSM_V1=y
 CONFIG_IP_PIMSM_V2=y
-# CONFIG_ARPD is not set
+CONFIG_ARPD=y
 CONFIG_SYN_COOKIES=y
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
@@ -399,30 +456,34 @@ CONFIG_DEFAULT_BIC=y
 # CONFIG_DEFAULT_WESTWOOD is not set
 # CONFIG_DEFAULT_RENO is not set
 CONFIG_DEFAULT_TCP_CONG="bic"
-# CONFIG_TCP_MD5SIG is not set
+CONFIG_TCP_MD5SIG=y
 CONFIG_IPV6=m
 CONFIG_IPV6_PRIVACY=y
-# CONFIG_IPV6_ROUTER_PREF is not set
+CONFIG_IPV6_ROUTER_PREF=y
+# CONFIG_IPV6_ROUTE_INFO 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_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_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_MULTIPLE_TABLES is not set
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
 # CONFIG_IPV6_MROUTE is not set
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 CONFIG_NETFILTER_ADVANCED=y
+CONFIG_BRIDGE_NETFILTER=y
 
 #
 # Core Netfilter Configuration
@@ -446,17 +507,22 @@ CONFIG_NETFILTER_ADVANCED=y
 #
 # CONFIG_IP6_NF_QUEUE is not set
 # CONFIG_IP6_NF_IPTABLES is not set
+# CONFIG_BRIDGE_NF_EBTABLES is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
 # CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
+CONFIG_STP=m
+CONFIG_BRIDGE=m
 # CONFIG_NET_DSA is not set
-# CONFIG_VLAN_8021Q 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_IPX=m
+# CONFIG_IPX_INTERN is not set
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
@@ -518,26 +584,61 @@ CONFIG_NET_SCH_FIFO=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
-# CONFIG_BT is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=m
+# CONFIG_BT_HCIBTSDIO is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+# CONFIG_BT_MRVL is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+# CONFIG_CFG80211_DEBUGFS is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
+CONFIG_CFG80211_WEXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
-# CONFIG_LIB80211 is not set
-
-#
-# CFG80211 needs to be enabled for MAC80211
-#
+CONFIG_LIB80211=m
+CONFIG_LIB80211_DEBUG=y
+CONFIG_MAC80211=m
+# CONFIG_MAC80211_RC_PID is not set
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+# CONFIG_MAC80211_MESH is not set
+CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
 # CONFIG_WIMAX is not set
 CONFIG_RFKILL=m
-# CONFIG_RFKILL_INPUT is not set
+CONFIG_RFKILL_LEDS=y
+CONFIG_RFKILL_INPUT=y
 # CONFIG_NET_9P is not set
 
 #
@@ -555,7 +656,7 @@ CONFIG_FW_LOADER=y
 CONFIG_FIRMWARE_IN_KERNEL=y
 CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
+CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
 # CONFIG_PARPORT is not set
 # CONFIG_PNP is not set
@@ -566,7 +667,12 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_CRYPTOLOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -577,19 +683,7 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_PHANTOM is not set
-# CONFIG_SGI_IOC4 is not set
-# CONFIG_TIFM_CORE is not set
-# CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_HP_ILO is not set
-# CONFIG_C2PORT is not set
-
-#
-# EEPROM support
-#
-# CONFIG_EEPROM_93CX6 is not set
-# CONFIG_CB710_CORE is not set
+# CONFIG_MISC_DEVICES is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
@@ -619,8 +713,7 @@ CONFIG_BLK_DEV_IDEDMA_SFF=y
 #
 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_GENERIC is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_AEC62XX is not set
@@ -700,7 +793,29 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
-# CONFIG_MD is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID6_PQ=m
+# CONFIG_ASYNC_RAID6_TEST is not set
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_DEBUG=y
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_LOG_USERSPACE=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_DELAY=m
+CONFIG_DM_UEVENT=y
 # CONFIG_FUSION is not set
 
 #
@@ -712,19 +827,19 @@ CONFIG_SCSI_WAIT_SCAN=m
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
 # CONFIG_IFB is not set
-# CONFIG_DUMMY is not set
+CONFIG_DUMMY=m
 # 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_TUN=m
+CONFIG_VETH=m
 # CONFIG_ARCNET is not set
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
@@ -738,6 +853,7 @@ CONFIG_MII=y
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
@@ -769,7 +885,7 @@ CONFIG_NET_PCI=y
 # CONFIG_8139CP is not set
 CONFIG_8139TOO=y
 # CONFIG_8139TOO_PIO is not set
-CONFIG_8139TOO_TUNE_TWISTER=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
@@ -795,6 +911,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 CONFIG_R8169=y
+CONFIG_R8169_VLAN=y
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
@@ -810,15 +927,31 @@ CONFIG_R8169=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-CONFIG_WLAN_PRE80211=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-CONFIG_WLAN_80211=y
-# CONFIG_LIBERTAS is not set
+# CONFIG_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_ATH_COMMON is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
 # CONFIG_HOSTAP is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_IWLWIFI is not set
+# CONFIG_IWM is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_HERMES is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_WL12XX is not set
+# CONFIG_ZD1211RW is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -831,17 +964,39 @@ CONFIG_WLAN_80211=y
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_CDC_EEM=m
+# CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_SMSC95XX is not set
+# CONFIG_USB_NET_GL620A is not set
+CONFIG_USB_NET_NET1080=m
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+CONFIG_USB_NET_CDC_SUBSET=m
+# CONFIG_USB_ALI_M5632 is not set
+# CONFIG_USB_AN2720 is not set
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+# CONFIG_USB_EPSON2888 is not set
+# CONFIG_USB_KC2190 is not set
+CONFIG_USB_NET_ZAURUS=m
 # CONFIG_USB_HSO is not set
+# CONFIG_USB_NET_INT51X1 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_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -849,8 +1004,9 @@ CONFIG_WLAN_80211=y
 # Input device support
 #
 CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
+CONFIG_INPUT_FF_MEMLESS=m
+CONFIG_INPUT_POLLDEV=m
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -884,7 +1040,7 @@ CONFIG_MOUSE_PS2_SYNAPTICS=y
 # CONFIG_MOUSE_PS2_SENTELIC is not set
 # CONFIG_MOUSE_PS2_TOUCHKIT is not set
 # CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_APPLETOUCH is not set
+CONFIG_MOUSE_APPLETOUCH=m
 # CONFIG_MOUSE_BCM5974 is not set
 # CONFIG_MOUSE_INPORT is not set
 # CONFIG_MOUSE_LOGIBM is not set
@@ -904,6 +1060,7 @@ CONFIG_SERIO_I8042=y
 # CONFIG_SERIO_PCIPS2 is not set
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -934,8 +1091,7 @@ CONFIG_SERIAL_NONSTANDARD=y
 #
 # Serial drivers
 #
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250=m
 # CONFIG_SERIAL_8250_PCI is not set
 CONFIG_SERIAL_8250_NR_UARTS=16
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
@@ -953,8 +1109,7 @@ CONFIG_SERIAL_8250_FOURPORT=y
 #
 # Non-8250 serial port support
 #
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_CORE=m
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1033,14 +1188,18 @@ CONFIG_VIDEO_MEDIA=m
 #
 # Multimedia drivers
 #
+CONFIG_IR_CORE=m
+CONFIG_VIDEO_IR=m
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_VIDEO_V4L2=m
 CONFIG_VIDEO_V4L1=m
+CONFIG_VIDEOBUF_GEN=m
+CONFIG_VIDEOBUF_VMALLOC=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_VIVI=m
 # CONFIG_VIDEO_PMS is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_CPIA2 is not set
@@ -1049,52 +1208,55 @@ CONFIG_V4L_USB_DRIVERS=y
 CONFIG_USB_VIDEO_CLASS=m
 CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
 CONFIG_USB_GSPCA=m
-# CONFIG_USB_M5602 is not set
-# CONFIG_USB_STV06XX is not set
+CONFIG_USB_M5602=m
+CONFIG_USB_STV06XX=m
 # CONFIG_USB_GL860 is not set
-# CONFIG_USB_GSPCA_CONEX is not set
-# CONFIG_USB_GSPCA_ETOMS is not set
-# CONFIG_USB_GSPCA_FINEPIX is not set
+CONFIG_USB_GSPCA_CONEX=m
+CONFIG_USB_GSPCA_ETOMS=m
+CONFIG_USB_GSPCA_FINEPIX=m
 # CONFIG_USB_GSPCA_JEILINJ is not set
-# CONFIG_USB_GSPCA_MARS is not set
-# CONFIG_USB_GSPCA_MR97310A is not set
-# CONFIG_USB_GSPCA_OV519 is not set
-# CONFIG_USB_GSPCA_OV534 is not set
-# CONFIG_USB_GSPCA_PAC207 is not set
-# CONFIG_USB_GSPCA_PAC7311 is not set
-# CONFIG_USB_GSPCA_SN9C20X is not set
-# CONFIG_USB_GSPCA_SONIXB is not set
-# CONFIG_USB_GSPCA_SONIXJ is not set
-# CONFIG_USB_GSPCA_SPCA500 is not set
-# CONFIG_USB_GSPCA_SPCA501 is not set
-# CONFIG_USB_GSPCA_SPCA505 is not set
-# CONFIG_USB_GSPCA_SPCA506 is not set
-# CONFIG_USB_GSPCA_SPCA508 is not set
-# CONFIG_USB_GSPCA_SPCA561 is not set
-# CONFIG_USB_GSPCA_SQ905 is not set
-# CONFIG_USB_GSPCA_SQ905C is not set
-# CONFIG_USB_GSPCA_STK014 is not set
-# CONFIG_USB_GSPCA_SUNPLUS is not set
-# CONFIG_USB_GSPCA_T613 is not set
-# CONFIG_USB_GSPCA_TV8532 is not set
-# CONFIG_USB_GSPCA_VC032X is not set
-# CONFIG_USB_GSPCA_ZC3XX is not set
+CONFIG_USB_GSPCA_MARS=m
+CONFIG_USB_GSPCA_MR97310A=m
+CONFIG_USB_GSPCA_OV519=m
+CONFIG_USB_GSPCA_OV534=m
+CONFIG_USB_GSPCA_PAC207=m
+# CONFIG_USB_GSPCA_PAC7302 is not set
+CONFIG_USB_GSPCA_PAC7311=m
+CONFIG_USB_GSPCA_SN9C20X=m
+CONFIG_USB_GSPCA_SN9C20X_EVDEV=y
+CONFIG_USB_GSPCA_SONIXB=m
+CONFIG_USB_GSPCA_SONIXJ=m
+CONFIG_USB_GSPCA_SPCA500=m
+CONFIG_USB_GSPCA_SPCA501=m
+CONFIG_USB_GSPCA_SPCA505=m
+CONFIG_USB_GSPCA_SPCA506=m
+CONFIG_USB_GSPCA_SPCA508=m
+CONFIG_USB_GSPCA_SPCA561=m
+CONFIG_USB_GSPCA_SQ905=m
+CONFIG_USB_GSPCA_SQ905C=m
+CONFIG_USB_GSPCA_STK014=m
+# CONFIG_USB_GSPCA_STV0680 is not set
+CONFIG_USB_GSPCA_SUNPLUS=m
+CONFIG_USB_GSPCA_T613=m
+CONFIG_USB_GSPCA_TV8532=m
+CONFIG_USB_GSPCA_VC032X=m
+CONFIG_USB_GSPCA_ZC3XX=m
 # CONFIG_VIDEO_HDPVR is not set
 # CONFIG_USB_VICAM is not set
 # CONFIG_USB_IBMCAM is not set
 # CONFIG_USB_KONICAWC is not set
 # CONFIG_USB_QUICKCAM_MESSENGER is not set
-# CONFIG_USB_ET61X251 is not set
+CONFIG_USB_ET61X251=m
 # CONFIG_USB_OV511 is not set
 # CONFIG_USB_SE401 is not set
-# CONFIG_USB_SN9C102 is not set
+CONFIG_USB_SN9C102=m
 # CONFIG_USB_STV680 is not set
-# CONFIG_USB_ZC0301 is not set
+CONFIG_USB_ZC0301=m
 # 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_USB_ZR364XX=m
+CONFIG_USB_STKWEBCAM=m
+CONFIG_USB_S2255=m
 # CONFIG_RADIO_ADAPTERS is not set
 # CONFIG_DAB is not set
 
@@ -1132,6 +1294,7 @@ CONFIG_FB_TILEBLITTING=y
 # CONFIG_FB_CYBER2000 is not set
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
+# CONFIG_FB_UVESA is not set
 # CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
@@ -1161,7 +1324,7 @@ CONFIG_FB_SIS_315=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 # CONFIG_LCD_CLASS_DEVICE is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_GENERIC=y
+CONFIG_BACKLIGHT_GENERIC=m
 
 #
 # Display device support
@@ -1193,28 +1356,44 @@ CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_LOGO_LINUX_CLUT224=y
 CONFIG_SOUND=m
-# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
-# CONFIG_SND_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_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+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_HRTIMER=m
+CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
 # CONFIG_SND_RTCTIMER is not set
 # CONFIG_SND_DYNAMIC_MINORS is not set
-# CONFIG_SND_SUPPORT_OLD_API is not set
-# CONFIG_SND_VERBOSE_PROCFS is not set
+CONFIG_SND_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_RAWMIDI_SEQ is not set
+CONFIG_SND_RAWMIDI_SEQ=m
 # CONFIG_SND_OPL3_LIB_SEQ is not set
 # CONFIG_SND_OPL4_LIB_SEQ is not set
 # CONFIG_SND_SBAWE_SEQ is not set
 # CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_MPU401_UART=m
 CONFIG_SND_AC97_CODEC=m
-# CONFIG_SND_DRIVERS is not set
+CONFIG_SND_DRIVERS=y
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+# CONFIG_SND_MTPAV is not set
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_MPU401=m
+CONFIG_SND_AC97_POWER_SAVE=y
+CONFIG_SND_AC97_POWER_SAVE_DEFAULT=10
 CONFIG_SND_PCI=y
 # CONFIG_SND_AD1889 is not set
 # CONFIG_SND_ALS300 is not set
@@ -1281,7 +1460,10 @@ CONFIG_SND_CS5535AUDIO=m
 # CONFIG_SND_VX222 is not set
 # CONFIG_SND_YMFPCI is not set
 # CONFIG_SND_MIPS is not set
-# CONFIG_SND_USB is not set
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
 # CONFIG_SND_SOC is not set
 # CONFIG_SOUND_PRIME is not set
 CONFIG_AC97_BUS=m
@@ -1299,32 +1481,41 @@ CONFIG_USB_HIDDEV=y
 #
 # Special HID drivers
 #
-# CONFIG_HID_A4TECH is not set
-# CONFIG_HID_APPLE is not set
-# CONFIG_HID_BELKIN is not set
-# CONFIG_HID_CHERRY is not set
-# CONFIG_HID_CHICONY is not set
-# CONFIG_HID_CYPRESS is not set
-# CONFIG_HID_DRAGONRISE is not set
-# CONFIG_HID_EZKEY is not set
-# CONFIG_HID_KYE is not set
-# CONFIG_HID_GYRATION is not set
-# CONFIG_HID_TWINHAN is not set
-# CONFIG_HID_KENSINGTON is not set
-# CONFIG_HID_LOGITECH is not set
-# CONFIG_HID_MICROSOFT is not set
-# CONFIG_HID_MONTEREY is not set
-# CONFIG_HID_NTRIG is not set
-# CONFIG_HID_PANTHERLORD is not set
-# CONFIG_HID_PETALYNX is not set
-# CONFIG_HID_SAMSUNG is not set
-# CONFIG_HID_SONY is not set
-# CONFIG_HID_SUNPLUS is not set
-# CONFIG_HID_GREENASIA is not set
-# CONFIG_HID_SMARTJOYPLUS is not set
-# CONFIG_HID_TOPSEED is not set
-# CONFIG_HID_THRUSTMASTER is not set
-# CONFIG_HID_ZEROPLUS is not set
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DRAGONRISE=m
+CONFIG_DRAGONRISE_FF=y
+CONFIG_HID_EZKEY=m
+CONFIG_HID_KYE=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_TWINHAN=m
+CONFIG_HID_KENSINGTON=m
+CONFIG_HID_LOGITECH=m
+CONFIG_LOGITECH_FF=y
+CONFIG_LOGIRUMBLEPAD2_FF=y
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_NTRIG=m
+CONFIG_HID_PANTHERLORD=m
+CONFIG_PANTHERLORD_FF=y
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_HID_GREENASIA=m
+CONFIG_GREENASIA_FF=y
+CONFIG_HID_SMARTJOYPLUS=m
+CONFIG_SMARTJOYPLUS_FF=y
+CONFIG_HID_TOPSEED=m
+CONFIG_HID_THRUSTMASTER=m
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_HID_WACOM=m
+CONFIG_HID_ZEROPLUS=m
+CONFIG_ZEROPLUS_FF=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1344,7 +1535,7 @@ CONFIG_USB_SUSPEND=y
 CONFIG_USB_OTG_WHITELIST=y
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 CONFIG_USB_MON=y
-# CONFIG_USB_WUSB is not set
+CONFIG_USB_WUSB=m
 # CONFIG_USB_WUSB_CBAF is not set
 
 #
@@ -1366,14 +1557,15 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=m
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
-# CONFIG_USB_WHCI_HCD is not set
-# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_WHCI_HCD=m
+CONFIG_USB_HWA_HCD=m
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
 #
 CONFIG_USB_ACM=m
-# CONFIG_USB_PRINTER is not set
+CONFIG_USB_PRINTER=m
 CONFIG_USB_WDM=m
 # CONFIG_USB_TMC is not set
 
@@ -1397,7 +1589,7 @@ CONFIG_USB_STORAGE_ALAUDA=m
 # CONFIG_USB_STORAGE_ONETOUCH is not set
 # CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
-# CONFIG_USB_LIBUSUAL is not set
+CONFIG_USB_LIBUSUAL=y
 
 #
 # USB Imaging devices
@@ -1467,7 +1659,7 @@ CONFIG_USB_SERIAL_GENERIC=y
 # 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_LED=m
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
 # CONFIG_USB_IDMOUSE is not set
@@ -1480,16 +1672,95 @@ CONFIG_USB_SERIAL_GENERIC=y
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
-# CONFIG_USB_GADGET is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+CONFIG_USB_GADGET_M66592=y
+CONFIG_USB_M66592=m
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_MULTI is not set
 
 #
 # OTG and related infrastructure
 #
 # CONFIG_NOP_USB_XCEIV is not set
-# CONFIG_UWB is not set
-# CONFIG_MMC is not set
+CONFIG_UWB=m
+CONFIG_UWB_HWA=m
+CONFIG_UWB_WHCI=m
+# CONFIG_UWB_WLP is not set
+# CONFIG_UWB_I1480U 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_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_TIFM_SD is not set
+# CONFIG_MMC_CB710 is not set
+# CONFIG_MMC_VIA_SDMMC is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_NEW_LEDS is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_IDE_DISK 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
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 # CONFIG_RTC_CLASS is not set
@@ -1504,22 +1775,18 @@ CONFIG_STAGING=y
 # CONFIG_STAGING_EXCLUDE_BUILD is not set
 # CONFIG_ET131X is not set
 # CONFIG_USB_IP_COMMON is not set
-# CONFIG_PRISM2_USB is not set
+# CONFIG_W35UND is not set
 # CONFIG_ECHO is not set
+# CONFIG_OTUS is not set
 # CONFIG_COMEDI is not set
 # CONFIG_ASUS_OLED is not set
 # CONFIG_ALTERA_PCIE_CHDMA is not set
-# CONFIG_RTL8187SE is not set
-# CONFIG_RTL8192SU is not set
+# CONFIG_R8187SE is not set
 # CONFIG_RTL8192E is not set
 # CONFIG_INPUT_MIMIO is not set
 # CONFIG_TRANZPORT is not set
 
 #
-# Android
-#
-
-#
 # Qualcomm MSM Camera And Video
 #
 
@@ -1527,7 +1794,6 @@ CONFIG_STAGING=y
 # Camera Sensor Selection
 #
 # CONFIG_INPUT_GPIO is not set
-# CONFIG_DST is not set
 # CONFIG_POHMELFS is not set
 # CONFIG_B3DFG is not set
 # CONFIG_PLAN9AUTH is not set
@@ -1544,28 +1810,55 @@ CONFIG_STAGING=y
 #
 # CONFIG_RAR_REGISTER is not set
 # CONFIG_IIO is not set
+# CONFIG_RAMZSWAP is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
 CONFIG_FB_SM7XX=y
-CONFIG_FB_SM7XX_ACCEL=y
+# CONFIG_FB_SM7XX_ACCEL is not set
 
 #
 # File systems
 #
-# CONFIG_EXT2_FS is not set
+CONFIG_EXT2_FS=m
+# 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=y
-# CONFIG_EXT4_FS is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
 CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
 CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+# CONFIG_REISERFS_FS_POSIX_ACL is not set
+# CONFIG_REISERFS_FS_SECURITY is not set
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+# CONFIG_JFS_SECURITY is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
-# CONFIG_XFS_FS is not set
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_BTRFS_FS is not set
+CONFIG_BTRFS_FS=m
+# CONFIG_BTRFS_FS_POSIX_ACL is not set
 # CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
@@ -1575,17 +1868,25 @@ CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 # CONFIG_QUOTA_NETLINK_INTERFACE is not set
 CONFIG_PRINT_QUOTA_WARNING=y
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
-# CONFIG_QFMT_V2 is not set
+CONFIG_QFMT_V2=m
 CONFIG_QUOTACTL=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
 # CONFIG_FUSE_FS is not set
 
 #
 # Caches
 #
-# CONFIG_FSCACHE is not set
+CONFIG_FSCACHE=m
+# CONFIG_FSCACHE_STATS is not set
+# CONFIG_FSCACHE_HISTOGRAM is not set
+# CONFIG_FSCACHE_DEBUG is not set
+# CONFIG_FSCACHE_OBJECT_LIST is not set
+CONFIG_CACHEFILES=m
+# CONFIG_CACHEFILES_DEBUG is not set
+# CONFIG_CACHEFILES_HISTOGRAM is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1599,11 +1900,13 @@ CONFIG_ZISOFS=y
 # DOS/FAT/NT Filesystems
 #
 CONFIG_FAT_FS=m
-# CONFIG_MSDOS_FS is not set
+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
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
 
 #
 # Pseudo filesystems
@@ -1616,23 +1919,60 @@ CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_CONFIGFS_FS=m
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_EMBEDDED=y
+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=m
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
 CONFIG_NFS_V3_ACL=y
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFSD is not set
+# CONFIG_NFS_FSCACHE is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
 CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
 CONFIG_NFS_ACL_SUPPORT=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# 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_UPCALL is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_DFS_UPCALL is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1643,45 +1983,45 @@ CONFIG_SUNRPC=m
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
 CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf-8"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
+CONFIG_NLS_DEFAULT="utf8"
+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=y
 # CONFIG_DLM is not set
 
 #
@@ -1695,125 +2035,155 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 CONFIG_STRIP_ASM_SYMS=y
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # 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_STACKTRACE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_NOP_TRACER=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_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_EARLY_PRINTK=y
 # CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
 #
-# CONFIG_KEYS is not set
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_XOR_BLOCKS=m
+CONFIG_ASYNC_CORE=m
+CONFIG_ASYNC_MEMCPY=m
+CONFIG_ASYNC_XOR=m
+CONFIG_ASYNC_PQ=m
+CONFIG_ASYNC_RAID6_RECOV=m
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+CONFIG_CRYPTO_FIPS=y
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
 CONFIG_CRYPTO_AEAD2=y
-CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER=m
 CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
 CONFIG_CRYPTO_RNG2=y
 CONFIG_CRYPTO_PCOMP=y
-CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER=m
 CONFIG_CRYPTO_MANAGER2=y
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_WORKQUEUE=y
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-# CONFIG_CRYPTO_TEST is not set
+CONFIG_CRYPTO_CRYPTD=m
+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
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_SEQIV=m
 
 #
 # Block modes
 #
-CONFIG_CRYPTO_CBC=y
-# CONFIG_CRYPTO_CTR is not set
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CTR=m
 # 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
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
 
 #
 # Hash modes
 #
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_XCBC is not set
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
 # CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_GHASH is not set
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_RMD128 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RMD256 is not set
-# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_WP512 is not set
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_GHASH=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
 
 #
 # 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
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 
 #
 # Compression
 #
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_ZLIB is not set
-# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
 
 #
 # Random Number Generation
 #
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
-# CONFIG_BINARY_PRINTF is not set
+CONFIG_BINARY_PRINTF=y
 
 #
 # Library routines
@@ -1821,14 +2191,20 @@ CONFIG_CRYPTO_HW=y
 CONFIG_BITREVERSE=y
 CONFIG_GENERIC_FIND_LAST_BIT=y
 # CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=y
 CONFIG_CRC_T10DIF=y
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=m
 CONFIG_AUDIT_GENERIC=y
-CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/configs/pb1100_defconfig linux-libre-2.6.34-gnu1/arch/mips/configs/pb1100_defconfig
--- linux-libre-2.6.33-gnu1/arch/mips/configs/pb1100_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/configs/pb1100_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,79 +1,103 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:37 2007
+# Linux kernel version: 2.6.33
+# Fri Feb 26 09:53:29 2010
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
-CONFIG_ZONE_DMA=y
 CONFIG_MACH_ALCHEMY=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-CONFIG_MIPS_PB1100=y
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_AR7 is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
-# CONFIG_WR_PPMC is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
-# CONFIG_MARKEINS is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
 # CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
 # CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
 # CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+CONFIG_ALCHEMY_GPIOINT_AU1000=y
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_MIPS_PB1100=y
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_XXS1500 is not set
+CONFIG_SOC_AU1100=y
+CONFIG_SOC_AU1X00=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_TIME=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CSRC_R4K_LIB=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SOC_AU1100=y
-CONFIG_SOC_AU1X00=y
+CONFIG_IRQ_CPU=y
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
 
 #
 # CPU selection
 #
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -86,6 +110,7 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
@@ -93,11 +118,14 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_SUPPORTS_ZBOOT=y
 CONFIG_SYS_HAS_CPU_MIPS32_R1=y
 CONFIG_CPU_MIPS32=y
 CONFIG_CPU_MIPSR1=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
 
 #
 # Kernel type
@@ -107,184 +135,244 @@ CONFIG_32BIT=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_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_SPARSEMEM_STATIC is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
+CONFIG_HZ_100=y
 # CONFIG_HZ_128 is not set
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
 # CONFIG_HZ_1024 is not set
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
+CONFIG_HZ=100
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION="-pb1100"
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
 CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_RCU is not set
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_RELAY=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
+# CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
 
 #
-# Loadable module support
+# GCOV-based kernel profiling
 #
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
+# 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_LSF is not set
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
 
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
 # CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-CONFIG_PCCARD=m
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=m
+CONFIG_PCCARD=y
+CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
+# CONFIG_PCMCIA_IOCTL is not set
 
 #
 # PC-card bridges
 #
 # CONFIG_PCMCIA_AU1X00 is not set
-
-#
-# PCI Hotplug Support
-#
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
 
 #
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 CONFIG_TRAD_SIGNALS=y
 
 #
 # Power management options
 #
-# CONFIG_PM is not set
-
-#
-# Networking
-#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=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_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
+CONFIG_IP_PNP_RARP=y
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
@@ -295,110 +383,25 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_LRO=y
+# CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
+# 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=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# Core Netfilter Configuration
-#
-CONFIG_NETFILTER_NETLINK=m
-CONFIG_NETFILTER_NETLINK_QUEUE=m
-CONFIG_NETFILTER_NETLINK_LOG=m
-CONFIG_NF_CONNTRACK_ENABLED=m
-CONFIG_NF_CONNTRACK_SUPPORT=y
-# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CT_ACCT=y
-CONFIG_NF_CONNTRACK_MARK=y
-CONFIG_NF_CONNTRACK_SECMARK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_GRE=m
-CONFIG_NF_CT_PROTO_SCTP=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 is not set
-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_XTABLES=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=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_HELPER=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_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-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_HASHLIMIT=m
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_CONNTRACK_PROC_COMPAT=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -408,27 +411,24 @@ CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
+# 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
@@ -437,25 +437,25 @@ CONFIG_WIRELESS_EXT=y
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=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
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
+# CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -468,6 +468,7 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -493,14 +494,13 @@ 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_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_ALCHEMY=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -517,166 +517,136 @@ CONFIG_MTD_ALCHEMY=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 # CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
 # CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
+# LPDDR flash memory drivers
 #
-# CONFIG_PNPACPI is not set
+# CONFIG_MTD_LPDDR is not set
 
 #
-# Block devices
+# 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
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_UB=y
 # CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=m
+# CONFIG_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=y
 
 #
-# Misc devices
+# 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_IDECS=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_IDE_TASK_IOCTL=y
+# CONFIG_IDE_PROC_FS is not set
 
 #
-# ATA/ATAPI/MFM/RLL support
+# IDE chipset support/bugfixes
 #
-# CONFIG_IDE is not set
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
 
 #
 # SCSI device support
 #
-CONFIG_RAID_ATTRS=m
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
 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
-
-#
-# PHY device support
-#
-CONFIG_PHYLIB=m
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
 
 #
 # MII PHY device drivers
 #
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
-# CONFIG_BROADCOM_PHY is not set
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
 # CONFIG_FIXED_PHY is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_MIPS_AU1X00_ENET is not set
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
 
 #
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_NET_RADIO is not set
 
 #
-# PCMCIA network device support
+# 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
-
-#
-# Wan interfaces
-#
 # CONFIG_WAN is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-# CONFIG_PPP_BSDCOMP is not set
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
+# CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-CONFIG_SLHC=m
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -684,16 +654,14 @@ CONFIG_SLHC=m
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
@@ -703,28 +671,26 @@ CONFIG_INPUT_EVDEV=y
 # 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 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
+# 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_AU1X00_GPIO is not set
 
 #
 # Serial drivers
@@ -743,198 +709,288 @@ CONFIG_SERIAL_8250_AU1X00=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 
 #
 # PCMCIA character devices
 #
-CONFIG_SYNCLINK_CS=m
+# 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
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
 # CONFIG_I2C is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
 
 #
-# Dallas's 1-wire bus
+# PPS support
 #
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
-# Multimedia devices
+# Sonics Silicon Backplane
 #
-# CONFIG_VIDEO_DEV is not set
+# CONFIG_SSB is not set
 
 #
-# Digital Video Broadcasting Devices
+# Multifunction device drivers
 #
-# CONFIG_DVB is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID 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
 
 #
-# Console display driver support
+# Display device support
 #
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
-# Sound
+# Console display driver support
 #
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
 # CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
 
 #
-# HID Devices
+# USB Input Devices
 #
-# CONFIG_HID is not set
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
 
 #
-# USB support
+# Special HID drivers
 #
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 # CONFIG_USB_ARCH_HAS_EHCI is not set
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Miscellaneous USB options
 #
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST 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 Gadget Support
+# USB Host Controller Drivers
 #
-# CONFIG_USB_GADGET is not set
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
 
 #
-# MMC/SD Card support
+# USB Device Class drivers
 #
-# CONFIG_MMC is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
-# LED devices
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
-# CONFIG_NEW_LEDS is not set
 
 #
-# LED drivers
+# also be needed; see USB_STORAGE Help for more info
 #
+# CONFIG_USB_LIBUSUAL is not set
 
 #
-# LED Triggers
+# USB Imaging devices
 #
+# CONFIG_USB_MDC800 is not set
 
 #
-# InfiniBand support
+# USB port drivers
 #
+# CONFIG_USB_SERIAL is not set
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# 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
 
 #
-# Real Time Clock
+# OTG and related infrastructure
 #
-# CONFIG_RTC_CLASS is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
 
 #
-# DMA Engine support
+# RTC interfaces
 #
-# CONFIG_DMA_ENGINE is not set
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
 
 #
-# DMA Clients
+# SPI RTC drivers
 #
 
 #
-# DMA Devices
+# Platform RTC drivers
 #
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
-# Auxiliary Display support
+# on-CPU RTC drivers
 #
+CONFIG_RTC_DRV_AU1XXX=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
 
 #
-# Virtualization
+# TI VLYNQ
 #
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-# CONFIG_EXT2_FS_SECURITY is not set
+# 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=y
-CONFIG_EXT3_FS_SECURITY=y
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
+# 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_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=m
-CONFIG_GENERIC_ACL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -953,69 +1009,76 @@ CONFIG_GENERIC_ACL=y
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
+# CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+# CONFIG_PROC_PAGE_MONITOR is not set
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
-# CONFIG_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 is not set
-CONFIG_CRAMFS=m
+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 is not set
+# CONFIG_JFFS2_FS_SECURITY is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_CRAMFS 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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
-CONFIG_EXPORTFS=m
+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=m
-# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS=m
+CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_CODEPAGE_437 is not set
 # CONFIG_NLS_CODEPAGE_737 is not set
@@ -1055,34 +1118,71 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
-
-#
-# Distributed Lock Manager
-#
-CONFIG_DLM=m
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
+# 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_STRIP_ASM_SYMS=y
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_CROSSCOMPILE=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
+# 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_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_EARLY_PRINTK=y
 # CONFIG_CMDLINE_BOOL is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_RUNTIME_DEBUG is not set
+CONFIG_DEBUG_ZBOOT=y
 
 #
 # Security options
@@ -1090,67 +1190,32 @@ CONFIG_CROSSCOMPILE=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+CONFIG_SECURITYFS=y
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=m
-CONFIG_CRC16=m
+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_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
-CONFIG_TEXTSEARCH_BM=m
-CONFIG_TEXTSEARCH_FSM=m
-CONFIG_PLIST=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/configs/pb1200_defconfig linux-libre-2.6.34-gnu1/arch/mips/configs/pb1200_defconfig
--- linux-libre-2.6.33-gnu1/arch/mips/configs/pb1200_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/configs/pb1200_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1568 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33
+# Fri Feb 26 10:23:34 2010
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+CONFIG_MACH_ALCHEMY=y
+# CONFIG_AR7 is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MACH_LOONGSON is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_POWERTV is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+CONFIG_ALCHEMY_GPIOINT_AU1000=y
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+CONFIG_MIPS_PB1200=y
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_XXS1500 is not set
+CONFIG_SOC_AU1200=y
+CONFIG_SOC_AU1X00=y
+CONFIG_LOONGSON_UART_BASE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CSRC_R4K_LIB=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_SUPPORTS_ZBOOT=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_64BIT_PHYS_ADDR=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_128 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=100
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION="-pb1200"
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_RCU is not set
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_VM_EVENT_COUNTERS is not set
+# 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_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF 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_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_MMU=y
+CONFIG_PCCARD=y
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+# CONFIG_PCMCIA_IOCTL is not set
+
+#
+# PC-card bridges
+#
+# CONFIG_PCMCIA_AU1X00 is not set
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=y
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_PM is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_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=y
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_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_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_AU1550 is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+CONFIG_MTD_NAND_PLATFORM=y
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_UB=y
+# 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=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
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_IDE_TASK_IOCTL=y
+# CONFIG_IDE_PROC_FS is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_IDE_AU1XXX=y
+CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA=y
+# CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA 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 is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_MIPS_AU1X00_ENET is not set
+CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN 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_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
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_CS is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+CONFIG_SERIAL_8250_AU1X00=y
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+
+#
+# I2C Algorithms
+#
+# 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_AU1550=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_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_AU1550=y
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=y
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+CONFIG_SENSORS_ADM1025=y
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+CONFIG_SENSORS_LM70=y
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=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_AU1200=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_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=y
+# CONFIG_SOUND_OSS_CORE is not set
+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
+# CONFIG_SND_HRTIMER is not set
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_AC97_CODEC=y
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_MIPS is not set
+# CONFIG_SND_USB is not set
+# CONFIG_SND_PCMCIA is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_SOC_AU1XPSC=y
+CONFIG_SND_SOC_AU1XPSC_I2S=y
+CONFIG_SND_SOC_AU1XPSC_AC97=y
+CONFIG_SND_SOC_DB1200=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_AC97_CODEC=y
+CONFIG_SND_SOC_WM8731=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=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_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_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=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_SDHCI is not set
+CONFIG_MMC_AU1X=y
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AU1XXX=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+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=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=y
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 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=y
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+# 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=y
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+CONFIG_NLS_ISO8859_15=y
+# 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_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=y
+CONFIG_STRIP_ASM_SYMS=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=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
+# 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_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,115200"
+# CONFIG_CMDLINE_OVERRIDE is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_RUNTIME_DEBUG is not set
+CONFIG_DEBUG_ZBOOT=y
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+CONFIG_SECURITYFS=y
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_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=y
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/configs/pb1500_defconfig linux-libre-2.6.34-gnu1/arch/mips/configs/pb1500_defconfig
--- linux-libre-2.6.33-gnu1/arch/mips/configs/pb1500_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/configs/pb1500_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,78 +1,102 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:37 2007
+# Linux kernel version: 2.6.33
+# Fri Feb 26 10:05:27 2010
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
-CONFIG_ZONE_DMA=y
 CONFIG_MACH_ALCHEMY=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-CONFIG_MIPS_PB1500=y
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_AR7 is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
-# CONFIG_WR_PPMC is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
-# CONFIG_MARKEINS is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
 # CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
 # CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
 # CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+CONFIG_ALCHEMY_GPIOINT_AU1000=y
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1200 is not set
+CONFIG_MIPS_PB1500=y
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_XXS1500 is not set
+CONFIG_SOC_AU1500=y
+CONFIG_SOC_AU1X00=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_TIME=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CSRC_R4K_LIB=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SOC_AU1500=y
-CONFIG_SOC_AU1X00=y
+CONFIG_IRQ_CPU=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
 
 #
 # CPU selection
 #
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -85,6 +109,7 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
@@ -92,11 +117,14 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_SUPPORTS_ZBOOT=y
 CONFIG_SYS_HAS_CPU_MIPS32_R1=y
 CONFIG_CPU_MIPS32=y
 CONFIG_CPU_MIPSR1=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
 
 #
 # Kernel type
@@ -106,190 +134,255 @@ CONFIG_32BIT=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_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_SPARSEMEM_STATIC is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
-CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
+CONFIG_HZ_100=y
 # CONFIG_HZ_128 is not set
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
 # CONFIG_HZ_1024 is not set
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
+CONFIG_HZ=100
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION="-pb1500"
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
 CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_RCU is not set
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_RELAY=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_PCI_QUIRKS=y
+# CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
+# CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
 
 #
-# Loadable module support
+# GCOV-based kernel profiling
 #
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
+# 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_LSF is not set
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
 
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-CONFIG_PCCARD=m
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=m
+CONFIG_PCCARD=y
+CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
 CONFIG_PCMCIA_IOCTL=y
-CONFIG_CARDBUS=y
+# CONFIG_CARDBUS is not set
 
 #
 # PC-card bridges
 #
 # CONFIG_YENTA is not set
-CONFIG_PD6729=m
+# CONFIG_PD6729 is not set
 # CONFIG_I82092 is not set
 # CONFIG_PCMCIA_AU1X00 is not set
-CONFIG_PCCARD_NONSTATIC=m
-
-#
-# PCI Hotplug Support
-#
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
 # CONFIG_HOTPLUG_PCI is not set
 
 #
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 CONFIG_TRAD_SIGNALS=y
 
 #
 # Power management options
 #
-# CONFIG_PM is not set
-
-#
-# Networking
-#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
+CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=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_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
+CONFIG_IP_PNP_RARP=y
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
@@ -300,110 +393,25 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_LRO=y
+# CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
+# 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=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# Core Netfilter Configuration
-#
-CONFIG_NETFILTER_NETLINK=m
-CONFIG_NETFILTER_NETLINK_QUEUE=m
-CONFIG_NETFILTER_NETLINK_LOG=m
-CONFIG_NF_CONNTRACK_ENABLED=m
-CONFIG_NF_CONNTRACK_SUPPORT=y
-# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CT_ACCT=y
-CONFIG_NF_CONNTRACK_MARK=y
-CONFIG_NF_CONNTRACK_SECMARK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_GRE=m
-CONFIG_NF_CT_PROTO_SCTP=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 is not set
-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_XTABLES=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=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_HELPER=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_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-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_HASHLIMIT=m
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_CONNTRACK_PROC_COMPAT=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -413,27 +421,24 @@ CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
+# 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
@@ -442,25 +447,25 @@ CONFIG_WIRELESS_EXT=y
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=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
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
+# CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -473,6 +478,7 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -498,14 +504,14 @@ 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_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_ALCHEMY=y
+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
 
 #
@@ -523,30 +529,20 @@ CONFIG_MTD_ALCHEMY=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 # CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
 # CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
+# LPDDR flash memory drivers
 #
-# CONFIG_PNPACPI is not set
+# CONFIG_MTD_LPDDR is not set
 
 #
-# Block devices
+# 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
@@ -554,67 +550,66 @@ CONFIG_MTD_ALCHEMY=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_SX8 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=m
-
-#
-# Misc devices
-#
-CONFIG_SGI_IOC4=m
-# CONFIG_TIFM_CORE is not set
 
 #
-# ATA/ATAPI/MFM/RLL support
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
 #
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_UB=y
+# 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=y
-CONFIG_IDE_MAX_HWIFS=4
-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_XFER_MODE=y
+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_BLK_DEV_IDECS=m
-# CONFIG_BLK_DEV_DELKIN is not set
-# CONFIG_BLK_DEV_IDECD is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 # CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_TASK_IOCTL=y
+CONFIG_IDE_PROC_FS=y
 
 #
 # IDE chipset support/bugfixes
 #
-CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_IDEDMA_SFF=y
+
+#
+# PCI IDE chipsets support
+#
 CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_IDEPCI_PCIBUS_ORDER is not set
 # CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_GENERIC is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_PCI_AUTO is not set
 # 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_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5520 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
 CONFIG_BLK_DEV_HPT366=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_IT8213=m
+# 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
@@ -624,82 +619,65 @@ CONFIG_BLK_DEV_IT8213=m
 # 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=m
-# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
 CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
 #
-CONFIG_RAID_ATTRS=m
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
 # CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
-# I2O device support
+# You can enable one or both FireWire driver stacks.
 #
-# CONFIG_I2O is not set
 
 #
-# Network device support
+# The newer stack is recommended.
 #
+# 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
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
 CONFIG_PHYLIB=y
 
 #
 # MII PHY device drivers
 #
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
-# CONFIG_BROADCOM_PHY is not set
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
 # CONFIG_FIXED_PHY is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
-CONFIG_MII=m
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
 CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
@@ -707,96 +685,51 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
-
-#
-# Tulip family network device support
-#
+# CONFIG_ETHOC 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 is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-CONFIG_QLA3XXX=m
-# CONFIG_ATL1 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-CONFIG_CHELSIO_T3=m
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-CONFIG_NETXEN_NIC=m
-
-#
-# Token Ring devices
-#
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_ATL2 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
+# CONFIG_WLAN is not set
 
 #
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# PCMCIA network device support
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-CONFIG_PCMCIA_AXNET=m
 
 #
-# Wan interfaces
+# 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 is not set
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-# CONFIG_PPP_BSDCOMP is not set
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
+# CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-CONFIG_SLHC=m
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -804,16 +737,14 @@ CONFIG_SLHC=m
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
@@ -823,33 +754,34 @@ CONFIG_INPUT_EVDEV=y
 # 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 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
+# CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
 
 #
 # Character devices
 #
-# CONFIG_VT is not set
+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_AU1X00_GPIO 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_PCI is not set
 # CONFIG_SERIAL_8250_CS is not set
 CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
@@ -863,282 +795,450 @@ 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
-
-#
-# IPMI
-#
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
 
 #
 # PCMCIA character devices
 #
-CONFIG_SYNCLINK_CS=m
+# 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
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
 
 #
-# Dallas's 1-wire bus
+# PPS support
 #
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
-# Hardware Monitoring support
+# Sonics Silicon Backplane
 #
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
+# CONFIG_SSB is not set
 
 #
-# Multimedia devices
+# Multifunction device drivers
 #
-# CONFIG_VIDEO_DEV is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
-# Digital Video Broadcasting Devices
+# Graphics support
 #
-# CONFIG_DVB is not set
+# CONFIG_VGA_ARB is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
 
 #
-# Graphics support
+# Frame buffer hardware drivers
 #
-# CONFIG_FIRMWARE_EDID is not set
-# CONFIG_FB is not set
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_S1D13XXX=y
+# 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_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
 
 #
-# Sound
+# 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_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
 # CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
 
 #
-# HID Devices
+# USB Input Devices
 #
-# CONFIG_HID is not set
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
 
 #
-# USB support
+# Special HID drivers
 #
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Miscellaneous USB options
 #
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_OTG_WHITELIST=y
+# 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 Gadget Support
+# USB Host Controller Drivers
 #
-# CONFIG_USB_GADGET is not set
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_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
 
 #
-# MMC/SD Card support
+# USB Device Class drivers
 #
-# CONFIG_MMC is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
-# LED devices
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
-# CONFIG_NEW_LEDS is not set
 
 #
-# LED drivers
+# also be needed; see USB_STORAGE Help for more info
 #
+# CONFIG_USB_LIBUSUAL is not set
 
 #
-# LED Triggers
+# USB Imaging devices
 #
+# CONFIG_USB_MDC800 is not set
 
 #
-# InfiniBand support
+# USB port drivers
 #
-# CONFIG_INFINIBAND is not set
+# CONFIG_USB_SERIAL is not set
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# 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
 
 #
-# Real Time Clock
+# OTG and related infrastructure
 #
-# CONFIG_RTC_CLASS is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
 
 #
-# DMA Engine support
+# RTC interfaces
 #
-# CONFIG_DMA_ENGINE is not set
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
 
 #
-# DMA Clients
+# SPI RTC drivers
 #
 
 #
-# DMA Devices
+# Platform RTC drivers
 #
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
-# Auxiliary Display support
+# on-CPU RTC drivers
 #
+CONFIG_RTC_DRV_AU1XXX=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
 
 #
-# Virtualization
+# TI VLYNQ
 #
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-# CONFIG_EXT2_FS_SECURITY is not set
+# 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=y
-CONFIG_EXT3_FS_SECURITY=y
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
+# 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_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=m
-CONFIG_GENERIC_ACL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
 #
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
+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 is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
+# CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+# CONFIG_PROC_PAGE_MONITOR is not set
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
-# CONFIG_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 is not set
-CONFIG_CRAMFS=m
+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=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=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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
-CONFIG_EXPORTFS=m
+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=m
-# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS=m
+CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
+CONFIG_NLS_CODEPAGE_437=y
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
 # CONFIG_NLS_CODEPAGE_855 is not set
 # CONFIG_NLS_CODEPAGE_857 is not set
 # CONFIG_NLS_CODEPAGE_860 is not set
@@ -1155,10 +1255,10 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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_1250=y
 # CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
+CONFIG_NLS_ASCII=y
+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
@@ -1168,38 +1268,75 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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_ISO8859_15=y
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Distributed Lock Manager
-#
-CONFIG_DLM=m
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
+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=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+CONFIG_STRIP_ASM_SYMS=y
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_CROSSCOMPILE=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
+# 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_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_EARLY_PRINTK=y
 # CONFIG_CMDLINE_BOOL is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_RUNTIME_DEBUG is not set
+CONFIG_DEBUG_ZBOOT=y
 
 #
 # Security options
@@ -1207,67 +1344,32 @@ CONFIG_CROSSCOMPILE=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+CONFIG_SECURITYFS=y
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=m
-CONFIG_CRC16=m
+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=y
 CONFIG_CRC32=y
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
-CONFIG_TEXTSEARCH_BM=m
-CONFIG_TEXTSEARCH_FSM=m
-CONFIG_PLIST=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/configs/pb1550_defconfig linux-libre-2.6.34-gnu1/arch/mips/configs/pb1550_defconfig
--- linux-libre-2.6.33-gnu1/arch/mips/configs/pb1550_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/configs/pb1550_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,79 +1,103 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:37 2007
+# Linux kernel version: 2.6.33
+# Fri Feb 26 10:06:07 2010
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
-CONFIG_ZONE_DMA=y
 CONFIG_MACH_ALCHEMY=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-CONFIG_MIPS_PB1550=y
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_AR7 is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
-# CONFIG_WR_PPMC is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
-# CONFIG_MARKEINS is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
 # CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
 # CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
 # CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+CONFIG_ALCHEMY_GPIOINT_AU1000=y
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_PB1500 is not set
+CONFIG_MIPS_PB1550=y
+# CONFIG_MIPS_XXS1500 is not set
+CONFIG_SOC_AU1550=y
+CONFIG_SOC_AU1X00=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_TIME=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CSRC_R4K_LIB=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
 CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SOC_AU1550=y
-CONFIG_SOC_AU1X00=y
+CONFIG_IRQ_CPU=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
 
 #
 # CPU selection
 #
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -86,6 +110,7 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
@@ -93,11 +118,14 @@ CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_SUPPORTS_ZBOOT=y
 CONFIG_SYS_HAS_CPU_MIPS32_R1=y
 CONFIG_CPU_MIPS32=y
 CONFIG_CPU_MIPSR1=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
 
 #
 # Kernel type
@@ -107,190 +135,255 @@ CONFIG_32BIT=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_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_SPARSEMEM_STATIC is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
-CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
+CONFIG_HZ_100=y
 # CONFIG_HZ_128 is not set
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
 # CONFIG_HZ_1024 is not set
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
+CONFIG_HZ=100
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION="-pb1550"
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
 CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_RCU is not set
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_RELAY=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_PCI_QUIRKS=y
+# CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
+# CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
 
 #
-# Loadable module support
+# GCOV-based kernel profiling
 #
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
+# 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_LSF is not set
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
 
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-CONFIG_PCCARD=m
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=m
+CONFIG_PCCARD=y
+CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
 CONFIG_PCMCIA_IOCTL=y
-CONFIG_CARDBUS=y
+# CONFIG_CARDBUS is not set
 
 #
 # PC-card bridges
 #
 # CONFIG_YENTA is not set
-CONFIG_PD6729=m
+# CONFIG_PD6729 is not set
 # CONFIG_I82092 is not set
 # CONFIG_PCMCIA_AU1X00 is not set
-CONFIG_PCCARD_NONSTATIC=m
-
-#
-# PCI Hotplug Support
-#
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
 # CONFIG_HOTPLUG_PCI is not set
 
 #
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 CONFIG_TRAD_SIGNALS=y
 
 #
 # Power management options
 #
-# CONFIG_PM is not set
-
-#
-# Networking
-#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
+CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=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_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
+CONFIG_IP_PNP_RARP=y
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
@@ -301,110 +394,25 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_LRO=y
+# CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
+# 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=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# Core Netfilter Configuration
-#
-CONFIG_NETFILTER_NETLINK=m
-CONFIG_NETFILTER_NETLINK_QUEUE=m
-CONFIG_NETFILTER_NETLINK_LOG=m
-CONFIG_NF_CONNTRACK_ENABLED=m
-CONFIG_NF_CONNTRACK_SUPPORT=y
-# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CT_ACCT=y
-CONFIG_NF_CONNTRACK_MARK=y
-CONFIG_NF_CONNTRACK_SECMARK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_GRE=m
-CONFIG_NF_CT_PROTO_SCTP=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 is not set
-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_XTABLES=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=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_HELPER=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_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-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_HASHLIMIT=m
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_CONNTRACK_PROC_COMPAT=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -414,27 +422,30 @@ CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -443,25 +454,25 @@ CONFIG_WIRELESS_EXT=y
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=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
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
+# CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -474,6 +485,7 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -499,14 +511,14 @@ 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_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_ALCHEMY=y
+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
 
 #
@@ -524,30 +536,30 @@ CONFIG_MTD_ALCHEMY=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
+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_AU1550=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
+# LPDDR flash memory drivers
 #
-# CONFIG_PNPACPI is not set
+# CONFIG_MTD_LPDDR is not set
 
 #
-# Block devices
+# 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
@@ -555,67 +567,66 @@ CONFIG_MTD_ALCHEMY=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_SX8 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=m
 
 #
-# Misc devices
-#
-CONFIG_SGI_IOC4=m
-# CONFIG_TIFM_CORE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
 #
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_UB=y
+# 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=y
-CONFIG_IDE_MAX_HWIFS=4
-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_XFER_MODE=y
+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_BLK_DEV_IDECS=m
-# CONFIG_BLK_DEV_DELKIN is not set
-# CONFIG_BLK_DEV_IDECD is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS 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_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_IDEDMA_SFF=y
+
+#
+# PCI IDE chipsets support
+#
 CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_IDEPCI_PCIBUS_ORDER is not set
 # CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_GENERIC is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_PCI_AUTO is not set
 # 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_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5520 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
 CONFIG_BLK_DEV_HPT366=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_IT8213=m
+# 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
@@ -625,82 +636,65 @@ CONFIG_BLK_DEV_IT8213=m
 # 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=m
-# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
 CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
 #
-CONFIG_RAID_ATTRS=m
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
 # CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
-# I2O device support
+# You can enable one or both FireWire driver stacks.
 #
-# CONFIG_I2O is not set
 
 #
-# Network device support
+# The newer stack is recommended.
 #
+# 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
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
 CONFIG_PHYLIB=y
 
 #
 # MII PHY device drivers
 #
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
-# CONFIG_BROADCOM_PHY is not set
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
 # CONFIG_FIXED_PHY is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
 CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
@@ -708,88 +702,51 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
-
-#
-# Tulip family network device support
-#
+# CONFIG_ETHOC 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 is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-CONFIG_QLA3XXX=m
-# CONFIG_ATL1 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-CONFIG_CHELSIO_T3=m
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-CONFIG_NETXEN_NIC=m
-
-#
-# Token Ring devices
-#
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_ATL2 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
+# CONFIG_WLAN is not set
 
 #
-# Wireless LAN (non-hamradio)
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_NET_RADIO is not set
 
 #
-# PCMCIA network device support
+# 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
-
-#
-# Wan interfaces
-#
 # 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 is not set
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-# CONFIG_PPP_BSDCOMP is not set
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
+# CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-CONFIG_SLHC=m
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -797,16 +754,14 @@ CONFIG_SLHC=m
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
@@ -816,33 +771,34 @@ CONFIG_INPUT_EVDEV=y
 # 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 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
+# CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
 
 #
 # Character devices
 #
-# CONFIG_VT is not set
+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_AU1X00_GPIO 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_PCI is not set
 # CONFIG_SERIAL_8250_CS is not set
 CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
@@ -856,282 +812,492 @@ 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
-
-#
-# IPMI
-#
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
 
 #
 # PCMCIA character devices
 #
-CONFIG_SYNCLINK_CS=m
+# CONFIG_SYNCLINK_CS is not set
 # CONFIG_CARDMAN_4000 is not set
 # CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
 # CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
 
 #
-# TPM devices
+# I2C Algorithms
 #
-# CONFIG_TCG_TPM is not set
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
 
 #
-# I2C support
+# I2C Hardware Bus support
 #
-# CONFIG_I2C is not set
 
 #
-# SPI support
+# PC SMBus host controller drivers
 #
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
+# 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
 
 #
-# Dallas's 1-wire bus
+# I2C system bus drivers (mostly embedded / system-on-chip)
 #
-# CONFIG_W1 is not set
+CONFIG_I2C_AU1550=y
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
 
 #
-# Hardware Monitoring support
+# 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_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
 #
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
-# Multimedia devices
+# Sonics Silicon Backplane
 #
-# CONFIG_VIDEO_DEV is not set
+# CONFIG_SSB is not set
 
 #
-# Digital Video Broadcasting Devices
+# Multifunction device drivers
 #
-# CONFIG_DVB is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_VGA_ARB is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Sound
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# 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_HIDRAW=y
 
 #
-# HID Devices
+# USB Input Devices
 #
-# CONFIG_HID is not set
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
 
 #
-# USB support
+# Special HID drivers
 #
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Miscellaneous USB options
 #
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=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 Gadget Support
+# USB Host Controller Drivers
 #
-# CONFIG_USB_GADGET is not set
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=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
 
 #
-# MMC/SD Card support
+# USB Device Class drivers
 #
-# CONFIG_MMC is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
-# LED devices
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
-# CONFIG_NEW_LEDS is not set
 
 #
-# LED drivers
+# also be needed; see USB_STORAGE Help for more info
 #
+# CONFIG_USB_LIBUSUAL is not set
 
 #
-# LED Triggers
+# USB Imaging devices
 #
+# CONFIG_USB_MDC800 is not set
 
 #
-# InfiniBand support
+# USB port drivers
 #
-# CONFIG_INFINIBAND is not set
+# CONFIG_USB_SERIAL is not set
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# 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
 
 #
-# Real Time Clock
+# OTG and related infrastructure
 #
-# CONFIG_RTC_CLASS is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
 
 #
-# DMA Engine support
+# RTC interfaces
 #
-# CONFIG_DMA_ENGINE is not set
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
 
 #
-# DMA Clients
+# I2C RTC drivers
 #
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
-# DMA Devices
+# SPI RTC drivers
 #
 
 #
-# Auxiliary Display support
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
 #
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AU1XXX=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
 
 #
-# Virtualization
+# TI VLYNQ
 #
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-# CONFIG_EXT2_FS_SECURITY is not set
+# 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=y
-CONFIG_EXT3_FS_SECURITY=y
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
+# 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_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=m
-CONFIG_GENERIC_ACL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
 #
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
+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 is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
+# CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+# CONFIG_PROC_PAGE_MONITOR is not set
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
-# CONFIG_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 is not set
-CONFIG_CRAMFS=m
+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=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=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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
-CONFIG_EXPORTFS=m
+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=m
-# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS=m
+CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
+CONFIG_NLS_CODEPAGE_437=y
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
 # CONFIG_NLS_CODEPAGE_855 is not set
 # CONFIG_NLS_CODEPAGE_857 is not set
 # CONFIG_NLS_CODEPAGE_860 is not set
@@ -1148,10 +1314,10 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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_1250=y
 # CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
+CONFIG_NLS_ASCII=y
+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
@@ -1161,38 +1327,75 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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_ISO8859_15=y
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Distributed Lock Manager
-#
-CONFIG_DLM=m
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
+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=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+CONFIG_STRIP_ASM_SYMS=y
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_CROSSCOMPILE=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
+# 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_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_EARLY_PRINTK=y
 # CONFIG_CMDLINE_BOOL is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_RUNTIME_DEBUG is not set
+CONFIG_DEBUG_ZBOOT=y
 
 #
 # Security options
@@ -1200,67 +1403,32 @@ CONFIG_CROSSCOMPILE=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+CONFIG_SECURITYFS=y
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=m
-CONFIG_CRC16=m
+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=y
 CONFIG_CRC32=y
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
-CONFIG_TEXTSEARCH_BM=m
-CONFIG_TEXTSEARCH_FSM=m
-CONFIG_PLIST=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/dec/kn01-berr.c linux-libre-2.6.34-gnu1/arch/mips/dec/kn01-berr.c
--- linux-libre-2.6.33-gnu1/arch/mips/dec/kn01-berr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/dec/kn01-berr.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,7 +46,7 @@
  * There is no default value -- it has to be initialized.
  */
 u16 cached_kn01_csr;
-DEFINE_SPINLOCK(kn01_lock);
+static DEFINE_RAW_SPINLOCK(kn01_lock);
 
 
 static inline void dec_kn01_be_ack(void)
@@ -54,12 +54,12 @@ static inline void dec_kn01_be_ack(void)
 	volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
 	unsigned long flags;
 
-	spin_lock_irqsave(&kn01_lock, flags);
+	raw_spin_lock_irqsave(&kn01_lock, flags);
 
 	*csr = cached_kn01_csr | KN01_CSR_MEMERR;	/* Clear bus IRQ. */
 	iob();
 
-	spin_unlock_irqrestore(&kn01_lock, flags);
+	raw_spin_unlock_irqrestore(&kn01_lock, flags);
 }
 
 static int dec_kn01_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
@@ -182,7 +182,7 @@ void __init dec_kn01_be_init(void)
 	volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
 	unsigned long flags;
 
-	spin_lock_irqsave(&kn01_lock, flags);
+	raw_spin_lock_irqsave(&kn01_lock, flags);
 
 	/* Preset write-only bits of the Control Register cache. */
 	cached_kn01_csr = *csr;
@@ -194,7 +194,7 @@ void __init dec_kn01_be_init(void)
 	*csr = cached_kn01_csr;
 	iob();
 
-	spin_unlock_irqrestore(&kn01_lock, flags);
+	raw_spin_unlock_irqrestore(&kn01_lock, flags);
 
 	/* Clear any leftover errors from the firmware. */
 	dec_kn01_be_ack();
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/dec/prom/locore.S linux-libre-2.6.34-gnu1/arch/mips/dec/prom/locore.S
--- linux-libre-2.6.33-gnu1/arch/mips/dec/prom/locore.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/dec/prom/locore.S	2010-05-16 17:17:36.000000000 -0400
@@ -27,4 +27,3 @@ NESTED(genexcept_early, 0, sp)
 	jr	k0
 	 rfe
 END(genexcept_early)
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/abi.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/abi.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/abi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/abi.h	2010-05-16 17:17:36.000000000 -0400
@@ -13,12 +13,14 @@
 #include <asm/siginfo.h>
 
 struct mips_abi {
-	int (* const setup_frame)(struct k_sigaction * ka,
+	int (* const setup_frame)(void *sig_return, struct k_sigaction *ka,
 	                          struct pt_regs *regs, int signr,
 	                          sigset_t *set);
-	int (* const setup_rt_frame)(struct k_sigaction * ka,
+	const unsigned long	signal_return_offset;
+	int (* const setup_rt_frame)(void *sig_return, struct k_sigaction *ka,
 	                       struct pt_regs *regs, int signr,
 	                       sigset_t *set, siginfo_t *info);
+	const unsigned long	rt_signal_return_offset;
 	const unsigned long	restart;
 };
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/atomic.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/atomic.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/atomic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/atomic.h	2010-05-16 17:17:36.000000000 -0400
@@ -137,7 +137,7 @@ static __inline__ int atomic_add_return(
 {
 	int result;
 
-	smp_llsc_mb();
+	smp_mb__before_llsc();
 
 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		int temp;
@@ -189,7 +189,7 @@ static __inline__ int atomic_sub_return(
 {
 	int result;
 
-	smp_llsc_mb();
+	smp_mb__before_llsc();
 
 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		int temp;
@@ -249,7 +249,7 @@ static __inline__ int atomic_sub_if_posi
 {
 	int result;
 
-	smp_llsc_mb();
+	smp_mb__before_llsc();
 
 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		int temp;
@@ -516,7 +516,7 @@ static __inline__ long atomic64_add_retu
 {
 	long result;
 
-	smp_llsc_mb();
+	smp_mb__before_llsc();
 
 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		long temp;
@@ -568,7 +568,7 @@ static __inline__ long atomic64_sub_retu
 {
 	long result;
 
-	smp_llsc_mb();
+	smp_mb__before_llsc();
 
 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		long temp;
@@ -628,7 +628,7 @@ static __inline__ long atomic64_sub_if_p
 {
 	long result;
 
-	smp_llsc_mb();
+	smp_mb__before_llsc();
 
 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		long temp;
@@ -788,9 +788,9 @@ static __inline__ int atomic64_add_unles
  * atomic*_return operations are serializing but not the non-*_return
  * versions.
  */
-#define smp_mb__before_atomic_dec()	smp_llsc_mb()
+#define smp_mb__before_atomic_dec()	smp_mb__before_llsc()
 #define smp_mb__after_atomic_dec()	smp_llsc_mb()
-#define smp_mb__before_atomic_inc()	smp_llsc_mb()
+#define smp_mb__before_atomic_inc()	smp_mb__before_llsc()
 #define smp_mb__after_atomic_inc()	smp_llsc_mb()
 
 #include <asm-generic/atomic-long.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/barrier.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/barrier.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/barrier.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/barrier.h	2010-05-16 17:17:36.000000000 -0400
@@ -88,12 +88,20 @@
 		: /* no output */		\
 		: "m" (*(int *)CKSEG1)		\
 		: "memory")
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+# define OCTEON_SYNCW_STR	".set push\n.set arch=octeon\nsyncw\nsyncw\n.set pop\n"
+# define __syncw() 	__asm__ __volatile__(OCTEON_SYNCW_STR : : : "memory")
 
-#define fast_wmb()	__sync()
-#define fast_rmb()	__sync()
-#define fast_mb()	__sync()
-#ifdef CONFIG_SGI_IP28
-#define fast_iob()				\
+# define fast_wmb()	__syncw()
+# define fast_rmb()	barrier()
+# define fast_mb()	__sync()
+# define fast_iob()	do { } while (0)
+#else /* ! CONFIG_CPU_CAVIUM_OCTEON */
+# define fast_wmb()	__sync()
+# define fast_rmb()	__sync()
+# define fast_mb()	__sync()
+# ifdef CONFIG_SGI_IP28
+#  define fast_iob()				\
 	__asm__ __volatile__(			\
 		".set	push\n\t"		\
 		".set	noreorder\n\t"		\
@@ -104,13 +112,14 @@
 		: /* no output */		\
 		: "m" (*(int *)CKSEG1ADDR(0x1fa00004)) \
 		: "memory")
-#else
-#define fast_iob()				\
+# else
+#  define fast_iob()				\
 	do {					\
 		__sync();			\
 		__fast_iob();			\
 	} while (0)
-#endif
+# endif
+#endif /* CONFIG_CPU_CAVIUM_OCTEON */
 
 #ifdef CONFIG_CPU_HAS_WB
 
@@ -131,25 +140,42 @@
 #endif /* !CONFIG_CPU_HAS_WB */
 
 #if defined(CONFIG_WEAK_ORDERING) && defined(CONFIG_SMP)
-#define __WEAK_ORDERING_MB	"       sync	\n"
+# ifdef CONFIG_CPU_CAVIUM_OCTEON
+#  define smp_mb()	__sync()
+#  define smp_rmb()	barrier()
+#  define smp_wmb()	__syncw()
+# else
+#  define smp_mb()	__asm__ __volatile__("sync" : : :"memory")
+#  define smp_rmb()	__asm__ __volatile__("sync" : : :"memory")
+#  define smp_wmb()	__asm__ __volatile__("sync" : : :"memory")
+# endif
 #else
-#define __WEAK_ORDERING_MB	"		\n"
+#define smp_mb()	barrier()
+#define smp_rmb()	barrier()
+#define smp_wmb()	barrier()
 #endif
+
 #if defined(CONFIG_WEAK_REORDERING_BEYOND_LLSC) && defined(CONFIG_SMP)
 #define __WEAK_LLSC_MB		"       sync	\n"
 #else
 #define __WEAK_LLSC_MB		"		\n"
 #endif
 
-#define smp_mb()	__asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
-#define smp_rmb()	__asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
-#define smp_wmb()	__asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
-
 #define set_mb(var, value) \
 	do { var = value; smp_mb(); } while (0)
 
 #define smp_llsc_mb()	__asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
-#define smp_llsc_rmb()	__asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
-#define smp_llsc_wmb()	__asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
+
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+#define smp_mb__before_llsc() smp_wmb()
+/* Cause previous writes to become visible on all CPUs as soon as possible */
+#define nudge_writes() __asm__ __volatile__(".set push\n\t"		\
+					    ".set arch=octeon\n\t"	\
+					    "syncw\n\t"			\
+					    ".set pop" : : : "memory")
+#else
+#define smp_mb__before_llsc() smp_llsc_mb()
+#define nudge_writes() mb()
+#endif
 
 #endif /* __ASM_BARRIER_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/bitops.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/bitops.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/bitops.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/bitops.h	2010-05-16 17:17:36.000000000 -0400
@@ -42,7 +42,7 @@
 /*
  * clear_bit() doesn't provide any barrier for the compiler.
  */
-#define smp_mb__before_clear_bit()	smp_llsc_mb()
+#define smp_mb__before_clear_bit()	smp_mb__before_llsc()
 #define smp_mb__after_clear_bit()	smp_llsc_mb()
 
 /*
@@ -258,7 +258,7 @@ static inline int test_and_set_bit(unsig
 	unsigned short bit = nr & SZLONG_MASK;
 	unsigned long res;
 
-	smp_llsc_mb();
+	smp_mb__before_llsc();
 
 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
@@ -395,7 +395,7 @@ static inline int test_and_clear_bit(uns
 	unsigned short bit = nr & SZLONG_MASK;
 	unsigned long res;
 
-	smp_llsc_mb();
+	smp_mb__before_llsc();
 
 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
@@ -485,7 +485,7 @@ static inline int test_and_change_bit(un
 	unsigned short bit = nr & SZLONG_MASK;
 	unsigned long res;
 
-	smp_llsc_mb();
+	smp_mb__before_llsc();
 
 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/cmpxchg.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/cmpxchg.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/cmpxchg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/cmpxchg.h	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,7 @@
 ({									\
 	__typeof(*(m)) __ret;						\
 									\
-	if (kernel_uses_llsc && R10000_LLSC_WAR) {				\
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {			\
 		__asm__ __volatile__(					\
 		"	.set	push				\n"	\
 		"	.set	noat				\n"	\
@@ -72,14 +72,14 @@
  */
 extern void __cmpxchg_called_with_bad_pointer(void);
 
-#define __cmpxchg(ptr, old, new, barrier)				\
+#define __cmpxchg(ptr, old, new, pre_barrier, post_barrier)		\
 ({									\
 	__typeof__(ptr) __ptr = (ptr);					\
 	__typeof__(*(ptr)) __old = (old);				\
 	__typeof__(*(ptr)) __new = (new);				\
 	__typeof__(*(ptr)) __res = 0;					\
 									\
-	barrier;							\
+	pre_barrier;							\
 									\
 	switch (sizeof(*(__ptr))) {					\
 	case 4:								\
@@ -96,13 +96,13 @@ extern void __cmpxchg_called_with_bad_po
 		break;							\
 	}								\
 									\
-	barrier;							\
+	post_barrier;							\
 									\
 	__res;								\
 })
 
-#define cmpxchg(ptr, old, new)		__cmpxchg(ptr, old, new, smp_llsc_mb())
-#define cmpxchg_local(ptr, old, new)	__cmpxchg(ptr, old, new, )
+#define cmpxchg(ptr, old, new)		__cmpxchg(ptr, old, new, smp_mb__before_llsc(), smp_llsc_mb())
+#define cmpxchg_local(ptr, old, new)	__cmpxchg(ptr, old, new, , )
 
 #define cmpxchg64(ptr, o, n)						\
   ({									\
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/compat.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/compat.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/compat.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/compat.h	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,8 @@
 #include <asm/page.h>
 #include <asm/ptrace.h>
 
-#define COMPAT_USER_HZ	100
+#define COMPAT_USER_HZ		100
+#define COMPAT_UTS_MACHINE	"mips\0\0\0"
 
 typedef u32		compat_size_t;
 typedef s32		compat_ssize_t;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/cpu-features.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/cpu-features.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/cpu-features.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/cpu-features.h	2010-05-16 17:17:36.000000000 -0400
@@ -95,6 +95,9 @@
 #ifndef cpu_has_smartmips
 #define cpu_has_smartmips      (cpu_data[0].ases & MIPS_ASE_SMARTMIPS)
 #endif
+#ifndef kernel_uses_smartmips_rixi
+#define kernel_uses_smartmips_rixi 0
+#endif
 #ifndef cpu_has_vtag_icache
 #define cpu_has_vtag_icache	(cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/cpu.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/cpu.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/cpu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/cpu.h	2010-05-16 17:17:36.000000000 -0400
@@ -224,7 +224,7 @@ enum cpu_type_enum {
 	 * MIPS64 class processors
 	 */
 	CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
-	CPU_CAVIUM_OCTEON,
+	CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS,
 
 	CPU_LAST
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/current.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/current.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/current.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/current.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,23 +1 @@
-/*
- * 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, 2002 Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
- */
-#ifndef _ASM_CURRENT_H
-#define _ASM_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_CURRENT_H */
+#include <asm-generic/current.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/dec/kn01.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/dec/kn01.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/dec/kn01.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/dec/kn01.h	2010-05-16 17:17:36.000000000 -0400
@@ -80,7 +80,6 @@
 struct pt_regs;
 
 extern u16 cached_kn01_csr;
-extern spinlock_t kn01_lock;
 
 extern void dec_kn01_be_init(void);
 extern int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/device.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/device.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/device.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/device.h	2010-05-16 17:17:36.000000000 -0400
@@ -4,4 +4,3 @@
  * This file is released under the GPLv2
  */
 #include <asm-generic/device.h>
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/elf.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/elf.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/elf.h	2010-05-16 17:17:36.000000000 -0400
@@ -310,6 +310,7 @@ do {									\
 
 #endif /* CONFIG_64BIT */
 
+struct pt_regs;
 struct task_struct;
 
 extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs);
@@ -334,14 +335,14 @@ extern int dump_task_fpu(struct task_str
 
 #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... */
+/*
+ * 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 ELF_PLATFORM  __elf_platform
+extern const char *__elf_platform;
 
 /*
  * See comments in asm-alpha/elf.h, this is the same thing
@@ -367,4 +368,8 @@ extern int dump_task_fpu(struct task_str
 #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
 #endif
 
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+struct linux_binprm;
+extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+				       int uses_interp);
 #endif /* _ASM_ELF_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/fpu_emulator.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/fpu_emulator.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/fpu_emulator.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/fpu_emulator.h	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,11 @@ struct mips_fpu_emulator_stats {
 DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
 
 #define MIPS_FPU_EMU_INC_STATS(M)					\
-	cpu_local_wrap(__local_inc(&__get_cpu_var(fpuemustats).M))
+do {									\
+	preempt_disable();						\
+	__local_inc(&__get_cpu_var(fpuemustats).M);			\
+	preempt_enable();						\
+} while (0)
 
 #else
 #define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/ftrace.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/ftrace.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/ftrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/ftrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
  * more details.
  *
  * Copyright (C) 2009 DSLab, Lanzhou University, China
- * Author: Wu Zhangjin <wuzj@lemote.com>
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  */
 
 #ifndef _ASM_MIPS_FTRACE_H
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/i8259.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/i8259.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/i8259.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/i8259.h	2010-05-16 17:17:36.000000000 -0400
@@ -35,7 +35,7 @@
 #define SLAVE_ICW4_DEFAULT	0x01
 #define PIC_ICW4_AEOI		2
 
-extern spinlock_t i8259A_lock;
+extern raw_spinlock_t i8259A_lock;
 
 extern int i8259A_irq_pending(unsigned int irq);
 extern void make_8259A_irq(unsigned int irq);
@@ -51,7 +51,7 @@ static inline int i8259_irq(void)
 {
 	int irq;
 
-	spin_lock(&i8259A_lock);
+	raw_spin_lock(&i8259A_lock);
 
 	/* Perform an interrupt acknowledge cycle on controller 1. */
 	outb(0x0C, PIC_MASTER_CMD);		/* prepare for poll */
@@ -78,7 +78,7 @@ static inline int i8259_irq(void)
 			irq = -1;
 	}
 
-	spin_unlock(&i8259A_lock);
+	raw_spin_unlock(&i8259A_lock);
 
 	return likely(irq >= 0) ? irq + I8259A_IRQ_BASE : irq;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/io.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/io.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/io.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/io.h	2010-05-16 17:17:36.000000000 -0400
@@ -447,6 +447,24 @@ __BUILDIO(q, u64)
 #define readl_relaxed			readl
 #define readq_relaxed			readq
 
+#define readb_be(addr)							\
+	__raw_readb((__force unsigned *)(addr))
+#define readw_be(addr)							\
+	be16_to_cpu(__raw_readw((__force unsigned *)(addr)))
+#define readl_be(addr)							\
+	be32_to_cpu(__raw_readl((__force unsigned *)(addr)))
+#define readq_be(addr)							\
+	be64_to_cpu(__raw_readq((__force unsigned *)(addr)))
+
+#define writeb_be(val, addr)						\
+	__raw_writeb((val), (__force unsigned *)(addr))
+#define writew_be(val, addr)						\
+	__raw_writew(cpu_to_be16((val)), (__force unsigned *)(addr))
+#define writel_be(val, addr)						\
+	__raw_writel(cpu_to_be32((val)), (__force unsigned *)(addr))
+#define writeq_be(val, addr)						\
+	__raw_writeq(cpu_to_be64((val)), (__force unsigned *)(addr))
+
 /*
  * Some code tests for these symbols
  */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/local.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/local.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/local.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/local.h	2010-05-16 17:17:36.000000000 -0400
@@ -193,29 +193,4 @@ static __inline__ long local_sub_return(
 #define __local_add(i, l)	((l)->a.counter+=(i))
 #define __local_sub(i, l)	((l)->a.counter-=(i))
 
-/* Need to disable preemption for the cpu local counters otherwise we could
-   still access a variable of a previous CPU in a non atomic 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 /* _ARCH_MIPS_LOCAL_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-ar7/ar7.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-ar7/ar7.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-ar7/ar7.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-ar7/ar7.h	2010-05-16 17:17:36.000000000 -0400
@@ -105,26 +105,9 @@ static inline u8 ar7_chip_rev(void)
 	return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) >> 16) & 0xff;
 }
 
-static inline int ar7_cpu_freq(void)
-{
-	return ar7_cpu_clock;
-}
-
-static inline int ar7_bus_freq(void)
-{
-	return ar7_bus_clock;
-}
-
-static inline int ar7_vbus_freq(void)
-{
-	return ar7_bus_clock / 2;
-}
-#define ar7_cpmac_freq ar7_vbus_freq
-
-static inline int ar7_dsp_freq(void)
-{
-	return ar7_dsp_clock;
-}
+struct clk {
+	unsigned int	rate;
+};
 
 static inline int ar7_has_high_cpmac(void)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-ar7/gpio.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-ar7/gpio.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-ar7/gpio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-ar7/gpio.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2007-2009 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
@@ -22,88 +22,18 @@
 #include <asm/mach-ar7/ar7.h>
 
 #define AR7_GPIO_MAX 32
+#define NR_BUILTIN_GPIO AR7_GPIO_MAX
 
-extern int gpio_request(unsigned gpio, const char *label);
-extern void gpio_free(unsigned gpio);
-
-/* Common GPIO layer */
-static inline int gpio_get_value(unsigned gpio)
-{
-	void __iomem *gpio_in =
-		(void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_INPUT);
-
-	return readl(gpio_in) & (1 << gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
-	void __iomem *gpio_out =
-		(void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_OUTPUT);
-	unsigned tmp;
-
-	tmp = readl(gpio_out) & ~(1 << gpio);
-	if (value)
-		tmp |= 1 << gpio;
-	writel(tmp, gpio_out);
-}
-
-static inline int gpio_direction_input(unsigned gpio)
-{
-	void __iomem *gpio_dir =
-		(void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_DIR);
-
-	if (gpio >= AR7_GPIO_MAX)
-		return -EINVAL;
-
-	writel(readl(gpio_dir) | (1 << gpio), gpio_dir);
-
-	return 0;
-}
-
-static inline int gpio_direction_output(unsigned gpio, int value)
-{
-	void __iomem *gpio_dir =
-		(void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_DIR);
-
-	if (gpio >= AR7_GPIO_MAX)
-		return -EINVAL;
-
-	gpio_set_value(gpio, value);
-	writel(readl(gpio_dir) & ~(1 << gpio), gpio_dir);
-
-	return 0;
-}
+#define gpio_to_irq(gpio)	NULL
 
-static inline int gpio_to_irq(unsigned gpio)
-{
-	return -EINVAL;
-}
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
 
-static inline int irq_to_gpio(unsigned irq)
-{
-	return -EINVAL;
-}
+#define gpio_cansleep __gpio_cansleep
 
 /* Board specific GPIO functions */
-static inline int ar7_gpio_enable(unsigned gpio)
-{
-	void __iomem *gpio_en =
-		(void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_ENABLE);
-
-	writel(readl(gpio_en) | (1 << gpio), gpio_en);
-
-	return 0;
-}
-
-static inline int ar7_gpio_disable(unsigned gpio)
-{
-	void __iomem *gpio_en =
-		(void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_ENABLE);
-
-	writel(readl(gpio_en) & ~(1 << gpio), gpio_en);
-
-	return 0;
-}
+int ar7_gpio_enable(unsigned gpio);
+int ar7_gpio_disable(unsigned gpio);
 
 #include <asm-generic/gpio.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/au1000.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/au1000.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/au1000.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/au1000.h	2010-05-16 17:17:36.000000000 -0400
@@ -130,6 +130,56 @@ static inline int au1xxx_cpu_needs_confi
 	return 0;
 }
 
+#define ALCHEMY_CPU_UNKNOWN	-1
+#define ALCHEMY_CPU_AU1000	0
+#define ALCHEMY_CPU_AU1500	1
+#define ALCHEMY_CPU_AU1100	2
+#define ALCHEMY_CPU_AU1550	3
+#define ALCHEMY_CPU_AU1200	4
+
+static inline int alchemy_get_cputype(void)
+{
+	switch (read_c0_prid() & 0xffff0000) {
+	case 0x00030000:
+		return ALCHEMY_CPU_AU1000;
+		break;
+	case 0x01030000:
+		return ALCHEMY_CPU_AU1500;
+		break;
+	case 0x02030000:
+		return ALCHEMY_CPU_AU1100;
+		break;
+	case 0x03030000:
+		return ALCHEMY_CPU_AU1550;
+		break;
+	case 0x04030000:
+	case 0x05030000:
+		return ALCHEMY_CPU_AU1200;
+		break;
+	}
+
+	return ALCHEMY_CPU_UNKNOWN;
+}
+
+static inline void alchemy_uart_putchar(u32 uart_phys, u8 c)
+{
+	void __iomem *base = (void __iomem *)KSEG1ADDR(uart_phys);
+	int timeout, i;
+
+	/* check LSR TX_EMPTY bit */
+	timeout = 0xffffff;
+	do {
+		if (__raw_readl(base + 0x1c) & 0x20)
+			break;
+		/* slow down */
+		for (i = 10000; i; i--)
+			asm volatile ("nop");
+	} while (--timeout);
+
+	__raw_writel(c, base + 0x04);	/* tx */
+	wmb();
+}
+
 /* arch/mips/au1000/common/clocks.c */
 extern void set_au1x00_speed(unsigned int new_freq);
 extern unsigned int get_au1x00_speed(void);
@@ -143,20 +193,332 @@ void au_sleep(void);
 void save_au1xxx_intctl(void);
 void restore_au1xxx_intctl(void);
 
-/*
- * Every board describes its IRQ mapping with this table.
- */
-struct au1xxx_irqmap {
-	int	im_irq;
-	int	im_type;
-	int	im_request;
+
+/* SOC Interrupt numbers */
+
+#define AU1000_INTC0_INT_BASE	(MIPS_CPU_IRQ_BASE + 8)
+#define AU1000_INTC0_INT_LAST	(AU1000_INTC0_INT_BASE + 31)
+#define AU1000_INTC1_INT_BASE	(AU1000_INTC0_INT_LAST + 1)
+#define AU1000_INTC1_INT_LAST	(AU1000_INTC1_INT_BASE + 31)
+#define AU1000_MAX_INTR 	AU1000_INTC1_INT_LAST
+
+enum soc_au1000_ints {
+	AU1000_FIRST_INT	= AU1000_INTC0_INT_BASE,
+	AU1000_UART0_INT	= AU1000_FIRST_INT,
+	AU1000_UART1_INT,
+	AU1000_UART2_INT,
+	AU1000_UART3_INT,
+	AU1000_SSI0_INT,
+	AU1000_SSI1_INT,
+	AU1000_DMA_INT_BASE,
+
+	AU1000_TOY_INT		= AU1000_FIRST_INT + 14,
+	AU1000_TOY_MATCH0_INT,
+	AU1000_TOY_MATCH1_INT,
+	AU1000_TOY_MATCH2_INT,
+	AU1000_RTC_INT,
+	AU1000_RTC_MATCH0_INT,
+	AU1000_RTC_MATCH1_INT,
+	AU1000_RTC_MATCH2_INT,
+	AU1000_IRDA_TX_INT,
+	AU1000_IRDA_RX_INT,
+	AU1000_USB_DEV_REQ_INT,
+	AU1000_USB_DEV_SUS_INT,
+	AU1000_USB_HOST_INT,
+	AU1000_ACSYNC_INT,
+	AU1000_MAC0_DMA_INT,
+	AU1000_MAC1_DMA_INT,
+	AU1000_I2S_UO_INT,
+	AU1000_AC97C_INT,
+	AU1000_GPIO0_INT,
+	AU1000_GPIO1_INT,
+	AU1000_GPIO2_INT,
+	AU1000_GPIO3_INT,
+	AU1000_GPIO4_INT,
+	AU1000_GPIO5_INT,
+	AU1000_GPIO6_INT,
+	AU1000_GPIO7_INT,
+	AU1000_GPIO8_INT,
+	AU1000_GPIO9_INT,
+	AU1000_GPIO10_INT,
+	AU1000_GPIO11_INT,
+	AU1000_GPIO12_INT,
+	AU1000_GPIO13_INT,
+	AU1000_GPIO14_INT,
+	AU1000_GPIO15_INT,
+	AU1000_GPIO16_INT,
+	AU1000_GPIO17_INT,
+	AU1000_GPIO18_INT,
+	AU1000_GPIO19_INT,
+	AU1000_GPIO20_INT,
+	AU1000_GPIO21_INT,
+	AU1000_GPIO22_INT,
+	AU1000_GPIO23_INT,
+	AU1000_GPIO24_INT,
+	AU1000_GPIO25_INT,
+	AU1000_GPIO26_INT,
+	AU1000_GPIO27_INT,
+	AU1000_GPIO28_INT,
+	AU1000_GPIO29_INT,
+	AU1000_GPIO30_INT,
+	AU1000_GPIO31_INT,
 };
 
-/* core calls this function to let boards initialize other IRQ sources */
-void board_init_irq(void);
+enum soc_au1100_ints {
+	AU1100_FIRST_INT	= AU1000_INTC0_INT_BASE,
+	AU1100_UART0_INT	= AU1100_FIRST_INT,
+	AU1100_UART1_INT,
+	AU1100_SD_INT,
+	AU1100_UART3_INT,
+	AU1100_SSI0_INT,
+	AU1100_SSI1_INT,
+	AU1100_DMA_INT_BASE,
 
-/* boards call this to register additional (GPIO) interrupts */
-void au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count);
+	AU1100_TOY_INT		= AU1100_FIRST_INT + 14,
+	AU1100_TOY_MATCH0_INT,
+	AU1100_TOY_MATCH1_INT,
+	AU1100_TOY_MATCH2_INT,
+	AU1100_RTC_INT,
+	AU1100_RTC_MATCH0_INT,
+	AU1100_RTC_MATCH1_INT,
+	AU1100_RTC_MATCH2_INT,
+	AU1100_IRDA_TX_INT,
+	AU1100_IRDA_RX_INT,
+	AU1100_USB_DEV_REQ_INT,
+	AU1100_USB_DEV_SUS_INT,
+	AU1100_USB_HOST_INT,
+	AU1100_ACSYNC_INT,
+	AU1100_MAC0_DMA_INT,
+	AU1100_GPIO208_215_INT,
+	AU1100_LCD_INT,
+	AU1100_AC97C_INT,
+	AU1100_GPIO0_INT,
+	AU1100_GPIO1_INT,
+	AU1100_GPIO2_INT,
+	AU1100_GPIO3_INT,
+	AU1100_GPIO4_INT,
+	AU1100_GPIO5_INT,
+	AU1100_GPIO6_INT,
+	AU1100_GPIO7_INT,
+	AU1100_GPIO8_INT,
+	AU1100_GPIO9_INT,
+	AU1100_GPIO10_INT,
+	AU1100_GPIO11_INT,
+	AU1100_GPIO12_INT,
+	AU1100_GPIO13_INT,
+	AU1100_GPIO14_INT,
+	AU1100_GPIO15_INT,
+	AU1100_GPIO16_INT,
+	AU1100_GPIO17_INT,
+	AU1100_GPIO18_INT,
+	AU1100_GPIO19_INT,
+	AU1100_GPIO20_INT,
+	AU1100_GPIO21_INT,
+	AU1100_GPIO22_INT,
+	AU1100_GPIO23_INT,
+	AU1100_GPIO24_INT,
+	AU1100_GPIO25_INT,
+	AU1100_GPIO26_INT,
+	AU1100_GPIO27_INT,
+	AU1100_GPIO28_INT,
+	AU1100_GPIO29_INT,
+	AU1100_GPIO30_INT,
+	AU1100_GPIO31_INT,
+};
+
+enum soc_au1500_ints {
+	AU1500_FIRST_INT	= AU1000_INTC0_INT_BASE,
+	AU1500_UART0_INT	= AU1500_FIRST_INT,
+	AU1500_PCI_INTA,
+	AU1500_PCI_INTB,
+	AU1500_UART3_INT,
+	AU1500_PCI_INTC,
+	AU1500_PCI_INTD,
+	AU1500_DMA_INT_BASE,
+
+	AU1500_TOY_INT		= AU1500_FIRST_INT + 14,
+	AU1500_TOY_MATCH0_INT,
+	AU1500_TOY_MATCH1_INT,
+	AU1500_TOY_MATCH2_INT,
+	AU1500_RTC_INT,
+	AU1500_RTC_MATCH0_INT,
+	AU1500_RTC_MATCH1_INT,
+	AU1500_RTC_MATCH2_INT,
+	AU1500_PCI_ERR_INT,
+	AU1500_RESERVED_INT,
+	AU1500_USB_DEV_REQ_INT,
+	AU1500_USB_DEV_SUS_INT,
+	AU1500_USB_HOST_INT,
+	AU1500_ACSYNC_INT,
+	AU1500_MAC0_DMA_INT,
+	AU1500_MAC1_DMA_INT,
+	AU1500_AC97C_INT	= AU1500_FIRST_INT + 31,
+	AU1500_GPIO0_INT,
+	AU1500_GPIO1_INT,
+	AU1500_GPIO2_INT,
+	AU1500_GPIO3_INT,
+	AU1500_GPIO4_INT,
+	AU1500_GPIO5_INT,
+	AU1500_GPIO6_INT,
+	AU1500_GPIO7_INT,
+	AU1500_GPIO8_INT,
+	AU1500_GPIO9_INT,
+	AU1500_GPIO10_INT,
+	AU1500_GPIO11_INT,
+	AU1500_GPIO12_INT,
+	AU1500_GPIO13_INT,
+	AU1500_GPIO14_INT,
+	AU1500_GPIO15_INT,
+	AU1500_GPIO200_INT,
+	AU1500_GPIO201_INT,
+	AU1500_GPIO202_INT,
+	AU1500_GPIO203_INT,
+	AU1500_GPIO20_INT,
+	AU1500_GPIO204_INT,
+	AU1500_GPIO205_INT,
+	AU1500_GPIO23_INT,
+	AU1500_GPIO24_INT,
+	AU1500_GPIO25_INT,
+	AU1500_GPIO26_INT,
+	AU1500_GPIO27_INT,
+	AU1500_GPIO28_INT,
+	AU1500_GPIO206_INT,
+	AU1500_GPIO207_INT,
+	AU1500_GPIO208_215_INT,
+};
+
+enum soc_au1550_ints {
+	AU1550_FIRST_INT	= AU1000_INTC0_INT_BASE,
+	AU1550_UART0_INT	= AU1550_FIRST_INT,
+	AU1550_PCI_INTA,
+	AU1550_PCI_INTB,
+	AU1550_DDMA_INT,
+	AU1550_CRYPTO_INT,
+	AU1550_PCI_INTC,
+	AU1550_PCI_INTD,
+	AU1550_PCI_RST_INT,
+	AU1550_UART1_INT,
+	AU1550_UART3_INT,
+	AU1550_PSC0_INT,
+	AU1550_PSC1_INT,
+	AU1550_PSC2_INT,
+	AU1550_PSC3_INT,
+	AU1550_TOY_INT,
+	AU1550_TOY_MATCH0_INT,
+	AU1550_TOY_MATCH1_INT,
+	AU1550_TOY_MATCH2_INT,
+	AU1550_RTC_INT,
+	AU1550_RTC_MATCH0_INT,
+	AU1550_RTC_MATCH1_INT,
+	AU1550_RTC_MATCH2_INT,
+
+	AU1550_NAND_INT		= AU1550_FIRST_INT + 23,
+	AU1550_USB_DEV_REQ_INT,
+	AU1550_USB_DEV_SUS_INT,
+	AU1550_USB_HOST_INT,
+	AU1550_MAC0_DMA_INT,
+	AU1550_MAC1_DMA_INT,
+	AU1550_GPIO0_INT	= AU1550_FIRST_INT + 32,
+	AU1550_GPIO1_INT,
+	AU1550_GPIO2_INT,
+	AU1550_GPIO3_INT,
+	AU1550_GPIO4_INT,
+	AU1550_GPIO5_INT,
+	AU1550_GPIO6_INT,
+	AU1550_GPIO7_INT,
+	AU1550_GPIO8_INT,
+	AU1550_GPIO9_INT,
+	AU1550_GPIO10_INT,
+	AU1550_GPIO11_INT,
+	AU1550_GPIO12_INT,
+	AU1550_GPIO13_INT,
+	AU1550_GPIO14_INT,
+	AU1550_GPIO15_INT,
+	AU1550_GPIO200_INT,
+	AU1550_GPIO201_205_INT,	/* Logical or of GPIO201:205 */
+	AU1550_GPIO16_INT,
+	AU1550_GPIO17_INT,
+	AU1550_GPIO20_INT,
+	AU1550_GPIO21_INT,
+	AU1550_GPIO22_INT,
+	AU1550_GPIO23_INT,
+	AU1550_GPIO24_INT,
+	AU1550_GPIO25_INT,
+	AU1550_GPIO26_INT,
+	AU1550_GPIO27_INT,
+	AU1550_GPIO28_INT,
+	AU1550_GPIO206_INT,
+	AU1550_GPIO207_INT,
+	AU1550_GPIO208_215_INT,	/* Logical or of GPIO208:215 */
+};
+
+enum soc_au1200_ints {
+	AU1200_FIRST_INT	= AU1000_INTC0_INT_BASE,
+	AU1200_UART0_INT	= AU1200_FIRST_INT,
+	AU1200_SWT_INT,
+	AU1200_SD_INT,
+	AU1200_DDMA_INT,
+	AU1200_MAE_BE_INT,
+	AU1200_GPIO200_INT,
+	AU1200_GPIO201_INT,
+	AU1200_GPIO202_INT,
+	AU1200_UART1_INT,
+	AU1200_MAE_FE_INT,
+	AU1200_PSC0_INT,
+	AU1200_PSC1_INT,
+	AU1200_AES_INT,
+	AU1200_CAMERA_INT,
+	AU1200_TOY_INT,
+	AU1200_TOY_MATCH0_INT,
+	AU1200_TOY_MATCH1_INT,
+	AU1200_TOY_MATCH2_INT,
+	AU1200_RTC_INT,
+	AU1200_RTC_MATCH0_INT,
+	AU1200_RTC_MATCH1_INT,
+	AU1200_RTC_MATCH2_INT,
+	AU1200_GPIO203_INT,
+	AU1200_NAND_INT,
+	AU1200_GPIO204_INT,
+	AU1200_GPIO205_INT,
+	AU1200_GPIO206_INT,
+	AU1200_GPIO207_INT,
+	AU1200_GPIO208_215_INT,	/* Logical OR of 208:215 */
+	AU1200_USB_INT,
+	AU1200_LCD_INT,
+	AU1200_MAE_BOTH_INT,
+	AU1200_GPIO0_INT,
+	AU1200_GPIO1_INT,
+	AU1200_GPIO2_INT,
+	AU1200_GPIO3_INT,
+	AU1200_GPIO4_INT,
+	AU1200_GPIO5_INT,
+	AU1200_GPIO6_INT,
+	AU1200_GPIO7_INT,
+	AU1200_GPIO8_INT,
+	AU1200_GPIO9_INT,
+	AU1200_GPIO10_INT,
+	AU1200_GPIO11_INT,
+	AU1200_GPIO12_INT,
+	AU1200_GPIO13_INT,
+	AU1200_GPIO14_INT,
+	AU1200_GPIO15_INT,
+	AU1200_GPIO16_INT,
+	AU1200_GPIO17_INT,
+	AU1200_GPIO18_INT,
+	AU1200_GPIO19_INT,
+	AU1200_GPIO20_INT,
+	AU1200_GPIO21_INT,
+	AU1200_GPIO22_INT,
+	AU1200_GPIO23_INT,
+	AU1200_GPIO24_INT,
+	AU1200_GPIO25_INT,
+	AU1200_GPIO26_INT,
+	AU1200_GPIO27_INT,
+	AU1200_GPIO28_INT,
+	AU1200_GPIO29_INT,
+	AU1200_GPIO30_INT,
+	AU1200_GPIO31_INT,
+};
 
 #endif /* !defined (_LANGUAGE_ASSEMBLY) */
 
@@ -549,78 +911,16 @@ void au1xxx_setup_irqmap(struct au1xxx_i
 
 #define IC1_TESTBIT		0xB1800080
 
-/* Interrupt Numbers */
+
 /* Au1000 */
 #ifdef CONFIG_SOC_AU1000
-enum soc_au1000_ints {
-	AU1000_FIRST_INT	= MIPS_CPU_IRQ_BASE + 8,
-	AU1000_UART0_INT	= AU1000_FIRST_INT,
-	AU1000_UART1_INT,				/* au1000 */
-	AU1000_UART2_INT,				/* au1000 */
-	AU1000_UART3_INT,
-	AU1000_SSI0_INT,				/* au1000 */
-	AU1000_SSI1_INT,				/* au1000 */
-	AU1000_DMA_INT_BASE,
-
-	AU1000_TOY_INT		= AU1000_FIRST_INT + 14,
-	AU1000_TOY_MATCH0_INT,
-	AU1000_TOY_MATCH1_INT,
-	AU1000_TOY_MATCH2_INT,
-	AU1000_RTC_INT,
-	AU1000_RTC_MATCH0_INT,
-	AU1000_RTC_MATCH1_INT,
-	AU1000_RTC_MATCH2_INT,
-	AU1000_IRDA_TX_INT,				/* au1000 */
-	AU1000_IRDA_RX_INT,				/* au1000 */
-	AU1000_USB_DEV_REQ_INT,
-	AU1000_USB_DEV_SUS_INT,
-	AU1000_USB_HOST_INT,
-	AU1000_ACSYNC_INT,
-	AU1000_MAC0_DMA_INT,
-	AU1000_MAC1_DMA_INT,
-	AU1000_I2S_UO_INT,				/* au1000 */
-	AU1000_AC97C_INT,
-	AU1000_GPIO_0,
-	AU1000_GPIO_1,
-	AU1000_GPIO_2,
-	AU1000_GPIO_3,
-	AU1000_GPIO_4,
-	AU1000_GPIO_5,
-	AU1000_GPIO_6,
-	AU1000_GPIO_7,
-	AU1000_GPIO_8,
-	AU1000_GPIO_9,
-	AU1000_GPIO_10,
-	AU1000_GPIO_11,
-	AU1000_GPIO_12,
-	AU1000_GPIO_13,
-	AU1000_GPIO_14,
-	AU1000_GPIO_15,
-	AU1000_GPIO_16,
-	AU1000_GPIO_17,
-	AU1000_GPIO_18,
-	AU1000_GPIO_19,
-	AU1000_GPIO_20,
-	AU1000_GPIO_21,
-	AU1000_GPIO_22,
-	AU1000_GPIO_23,
-	AU1000_GPIO_24,
-	AU1000_GPIO_25,
-	AU1000_GPIO_26,
-	AU1000_GPIO_27,
-	AU1000_GPIO_28,
-	AU1000_GPIO_29,
-	AU1000_GPIO_30,
-	AU1000_GPIO_31,
-};
 
 #define UART0_ADDR		0xB1100000
-#define UART1_ADDR		0xB1200000
-#define UART2_ADDR		0xB1300000
 #define UART3_ADDR		0xB1400000
 
 #define USB_OHCI_BASE		0x10100000	/* phys addr for ioremap */
 #define USB_HOST_CONFIG 	0xB017FFFC
+#define FOR_PLATFORM_C_USB_HOST_INT AU1000_USB_HOST_INT
 
 #define AU1000_ETH0_BASE	0xB0500000
 #define AU1000_ETH1_BASE	0xB0510000
@@ -631,78 +931,13 @@ enum soc_au1000_ints {
 
 /* Au1500 */
 #ifdef CONFIG_SOC_AU1500
-enum soc_au1500_ints {
-	AU1500_FIRST_INT	= MIPS_CPU_IRQ_BASE + 8,
-	AU1500_UART0_INT	= AU1500_FIRST_INT,
-	AU1000_PCI_INTA,				/* au1500 */
-	AU1000_PCI_INTB,				/* au1500 */
-	AU1500_UART3_INT,
-	AU1000_PCI_INTC,				/* au1500 */
-	AU1000_PCI_INTD,				/* au1500 */
-	AU1000_DMA_INT_BASE,
-
-	AU1000_TOY_INT		= AU1500_FIRST_INT + 14,
-	AU1000_TOY_MATCH0_INT,
-	AU1000_TOY_MATCH1_INT,
-	AU1000_TOY_MATCH2_INT,
-	AU1000_RTC_INT,
-	AU1000_RTC_MATCH0_INT,
-	AU1000_RTC_MATCH1_INT,
-	AU1000_RTC_MATCH2_INT,
-	AU1500_PCI_ERR_INT,
-	AU1500_RESERVED_INT,
-	AU1000_USB_DEV_REQ_INT,
-	AU1000_USB_DEV_SUS_INT,
-	AU1000_USB_HOST_INT,
-	AU1000_ACSYNC_INT,
-	AU1500_MAC0_DMA_INT,
-	AU1500_MAC1_DMA_INT,
-	AU1000_AC97C_INT	= AU1500_FIRST_INT + 31,
-	AU1000_GPIO_0,
-	AU1000_GPIO_1,
-	AU1000_GPIO_2,
-	AU1000_GPIO_3,
-	AU1000_GPIO_4,
-	AU1000_GPIO_5,
-	AU1000_GPIO_6,
-	AU1000_GPIO_7,
-	AU1000_GPIO_8,
-	AU1000_GPIO_9,
-	AU1000_GPIO_10,
-	AU1000_GPIO_11,
-	AU1000_GPIO_12,
-	AU1000_GPIO_13,
-	AU1000_GPIO_14,
-	AU1000_GPIO_15,
-	AU1500_GPIO_200,
-	AU1500_GPIO_201,
-	AU1500_GPIO_202,
-	AU1500_GPIO_203,
-	AU1500_GPIO_20,
-	AU1500_GPIO_204,
-	AU1500_GPIO_205,
-	AU1500_GPIO_23,
-	AU1500_GPIO_24,
-	AU1500_GPIO_25,
-	AU1500_GPIO_26,
-	AU1500_GPIO_27,
-	AU1500_GPIO_28,
-	AU1500_GPIO_206,
-	AU1500_GPIO_207,
-	AU1500_GPIO_208_215,
-};
-
-/* shortcuts */
-#define INTA AU1000_PCI_INTA
-#define INTB AU1000_PCI_INTB
-#define INTC AU1000_PCI_INTC
-#define INTD AU1000_PCI_INTD
 
 #define UART0_ADDR		0xB1100000
 #define UART3_ADDR		0xB1400000
 
 #define USB_OHCI_BASE		0x10100000	/* phys addr for ioremap */
 #define USB_HOST_CONFIG 	0xB017fffc
+#define FOR_PLATFORM_C_USB_HOST_INT AU1500_USB_HOST_INT
 
 #define AU1500_ETH0_BASE	0xB1500000
 #define AU1500_ETH1_BASE	0xB1510000
@@ -713,74 +948,13 @@ enum soc_au1500_ints {
 
 /* Au1100 */
 #ifdef CONFIG_SOC_AU1100
-enum soc_au1100_ints {
-	AU1100_FIRST_INT	= MIPS_CPU_IRQ_BASE + 8,
-	AU1100_UART0_INT	= AU1100_FIRST_INT,
-	AU1100_UART1_INT,
-	AU1100_SD_INT,
-	AU1100_UART3_INT,
-	AU1000_SSI0_INT,
-	AU1000_SSI1_INT,
-	AU1000_DMA_INT_BASE,
-
-	AU1000_TOY_INT		= AU1100_FIRST_INT + 14,
-	AU1000_TOY_MATCH0_INT,
-	AU1000_TOY_MATCH1_INT,
-	AU1000_TOY_MATCH2_INT,
-	AU1000_RTC_INT,
-	AU1000_RTC_MATCH0_INT,
-	AU1000_RTC_MATCH1_INT,
-	AU1000_RTC_MATCH2_INT,
-	AU1000_IRDA_TX_INT,
-	AU1000_IRDA_RX_INT,
-	AU1000_USB_DEV_REQ_INT,
-	AU1000_USB_DEV_SUS_INT,
-	AU1000_USB_HOST_INT,
-	AU1000_ACSYNC_INT,
-	AU1100_MAC0_DMA_INT,
-	AU1100_GPIO_208_215,
-	AU1100_LCD_INT,
-	AU1000_AC97C_INT,
-	AU1000_GPIO_0,
-	AU1000_GPIO_1,
-	AU1000_GPIO_2,
-	AU1000_GPIO_3,
-	AU1000_GPIO_4,
-	AU1000_GPIO_5,
-	AU1000_GPIO_6,
-	AU1000_GPIO_7,
-	AU1000_GPIO_8,
-	AU1000_GPIO_9,
-	AU1000_GPIO_10,
-	AU1000_GPIO_11,
-	AU1000_GPIO_12,
-	AU1000_GPIO_13,
-	AU1000_GPIO_14,
-	AU1000_GPIO_15,
-	AU1000_GPIO_16,
-	AU1000_GPIO_17,
-	AU1000_GPIO_18,
-	AU1000_GPIO_19,
-	AU1000_GPIO_20,
-	AU1000_GPIO_21,
-	AU1000_GPIO_22,
-	AU1000_GPIO_23,
-	AU1000_GPIO_24,
-	AU1000_GPIO_25,
-	AU1000_GPIO_26,
-	AU1000_GPIO_27,
-	AU1000_GPIO_28,
-	AU1000_GPIO_29,
-	AU1000_GPIO_30,
-	AU1000_GPIO_31,
-};
 
 #define UART0_ADDR		0xB1100000
-#define UART1_ADDR		0xB1200000
 #define UART3_ADDR		0xB1400000
 
 #define USB_OHCI_BASE		0x10100000	/* phys addr for ioremap */
 #define USB_HOST_CONFIG 	0xB017FFFC
+#define FOR_PLATFORM_C_USB_HOST_INT AU1100_USB_HOST_INT
 
 #define AU1100_ETH0_BASE	0xB0500000
 #define AU1100_MAC0_ENABLE	0xB0520000
@@ -788,87 +962,12 @@ enum soc_au1100_ints {
 #endif /* CONFIG_SOC_AU1100 */
 
 #ifdef CONFIG_SOC_AU1550
-enum soc_au1550_ints {
-	AU1550_FIRST_INT	= MIPS_CPU_IRQ_BASE + 8,
-	AU1550_UART0_INT	= AU1550_FIRST_INT,
-	AU1550_PCI_INTA,
-	AU1550_PCI_INTB,
-	AU1550_DDMA_INT,
-	AU1550_CRYPTO_INT,
-	AU1550_PCI_INTC,
-	AU1550_PCI_INTD,
-	AU1550_PCI_RST_INT,
-	AU1550_UART1_INT,
-	AU1550_UART3_INT,
-	AU1550_PSC0_INT,
-	AU1550_PSC1_INT,
-	AU1550_PSC2_INT,
-	AU1550_PSC3_INT,
-	AU1000_TOY_INT,
-	AU1000_TOY_MATCH0_INT,
-	AU1000_TOY_MATCH1_INT,
-	AU1000_TOY_MATCH2_INT,
-	AU1000_RTC_INT,
-	AU1000_RTC_MATCH0_INT,
-	AU1000_RTC_MATCH1_INT,
-	AU1000_RTC_MATCH2_INT,
-
-	AU1550_NAND_INT			= AU1550_FIRST_INT + 23,
-	AU1550_USB_DEV_REQ_INT,
-	AU1000_USB_DEV_REQ_INT		= AU1550_USB_DEV_REQ_INT,
-	AU1550_USB_DEV_SUS_INT,
-	AU1000_USB_DEV_SUS_INT		= AU1550_USB_DEV_SUS_INT,
-	AU1550_USB_HOST_INT,
-	AU1000_USB_HOST_INT		= AU1550_USB_HOST_INT,
-	AU1550_MAC0_DMA_INT,
-	AU1550_MAC1_DMA_INT,
-	AU1000_GPIO_0			= AU1550_FIRST_INT + 32,
-	AU1000_GPIO_1,
-	AU1000_GPIO_2,
-	AU1000_GPIO_3,
-	AU1000_GPIO_4,
-	AU1000_GPIO_5,
-	AU1000_GPIO_6,
-	AU1000_GPIO_7,
-	AU1000_GPIO_8,
-	AU1000_GPIO_9,
-	AU1000_GPIO_10,
-	AU1000_GPIO_11,
-	AU1000_GPIO_12,
-	AU1000_GPIO_13,
-	AU1000_GPIO_14,
-	AU1000_GPIO_15,
-	AU1550_GPIO_200,
-	AU1500_GPIO_201_205,			/* Logical or of GPIO201:205 */
-	AU1500_GPIO_16,
-	AU1500_GPIO_17,
-	AU1500_GPIO_20,
-	AU1500_GPIO_21,
-	AU1500_GPIO_22,
-	AU1500_GPIO_23,
-	AU1500_GPIO_24,
-	AU1500_GPIO_25,
-	AU1500_GPIO_26,
-	AU1500_GPIO_27,
-	AU1500_GPIO_28,
-	AU1500_GPIO_206,
-	AU1500_GPIO_207,
-	AU1500_GPIO_208_218,			/* Logical or of GPIO208:218 */
-};
-
-/* shortcuts */
-#define INTA AU1550_PCI_INTA
-#define INTB AU1550_PCI_INTB
-#define INTC AU1550_PCI_INTC
-#define INTD AU1550_PCI_INTD
-
 #define UART0_ADDR		0xB1100000
-#define UART1_ADDR		0xB1200000
-#define UART3_ADDR		0xB1400000
 
 #define USB_OHCI_BASE		0x14020000	/* phys addr for ioremap */
 #define USB_OHCI_LEN		0x00060000
 #define USB_HOST_CONFIG 	0xB4027ffc
+#define FOR_PLATFORM_C_USB_HOST_INT AU1550_USB_HOST_INT
 
 #define AU1550_ETH0_BASE	0xB0500000
 #define AU1550_ETH1_BASE	0xB0510000
@@ -877,78 +976,10 @@ enum soc_au1550_ints {
 #define NUM_ETH_INTERFACES 2
 #endif /* CONFIG_SOC_AU1550 */
 
+
 #ifdef CONFIG_SOC_AU1200
-enum soc_au1200_ints {
-	AU1200_FIRST_INT	= MIPS_CPU_IRQ_BASE + 8,
-	AU1200_UART0_INT	= AU1200_FIRST_INT,
-	AU1200_SWT_INT,
-	AU1200_SD_INT,
-	AU1200_DDMA_INT,
-	AU1200_MAE_BE_INT,
-	AU1200_GPIO_200,
-	AU1200_GPIO_201,
-	AU1200_GPIO_202,
-	AU1200_UART1_INT,
-	AU1200_MAE_FE_INT,
-	AU1200_PSC0_INT,
-	AU1200_PSC1_INT,
-	AU1200_AES_INT,
-	AU1200_CAMERA_INT,
-	AU1000_TOY_INT,
-	AU1000_TOY_MATCH0_INT,
-	AU1000_TOY_MATCH1_INT,
-	AU1000_TOY_MATCH2_INT,
-	AU1000_RTC_INT,
-	AU1000_RTC_MATCH0_INT,
-	AU1000_RTC_MATCH1_INT,
-	AU1000_RTC_MATCH2_INT,
-	AU1200_GPIO_203,
-	AU1200_NAND_INT,
-	AU1200_GPIO_204,
-	AU1200_GPIO_205,
-	AU1200_GPIO_206,
-	AU1200_GPIO_207,
-	AU1200_GPIO_208_215,			/* Logical OR of 208:215 */
-	AU1200_USB_INT,
-	AU1000_USB_HOST_INT	= AU1200_USB_INT,
-	AU1200_LCD_INT,
-	AU1200_MAE_BOTH_INT,
-	AU1000_GPIO_0,
-	AU1000_GPIO_1,
-	AU1000_GPIO_2,
-	AU1000_GPIO_3,
-	AU1000_GPIO_4,
-	AU1000_GPIO_5,
-	AU1000_GPIO_6,
-	AU1000_GPIO_7,
-	AU1000_GPIO_8,
-	AU1000_GPIO_9,
-	AU1000_GPIO_10,
-	AU1000_GPIO_11,
-	AU1000_GPIO_12,
-	AU1000_GPIO_13,
-	AU1000_GPIO_14,
-	AU1000_GPIO_15,
-	AU1000_GPIO_16,
-	AU1000_GPIO_17,
-	AU1000_GPIO_18,
-	AU1000_GPIO_19,
-	AU1000_GPIO_20,
-	AU1000_GPIO_21,
-	AU1000_GPIO_22,
-	AU1000_GPIO_23,
-	AU1000_GPIO_24,
-	AU1000_GPIO_25,
-	AU1000_GPIO_26,
-	AU1000_GPIO_27,
-	AU1000_GPIO_28,
-	AU1000_GPIO_29,
-	AU1000_GPIO_30,
-	AU1000_GPIO_31,
-};
 
 #define UART0_ADDR		0xB1100000
-#define UART1_ADDR		0xB1200000
 
 #define USB_UOC_BASE		0x14020020
 #define USB_UOC_LEN		0x20
@@ -974,15 +1005,9 @@ enum soc_au1200_ints {
 #define USBMSRMCFG_RDCOMB	30
 #define USBMSRMCFG_PFEN 	31
 
-#endif /* CONFIG_SOC_AU1200 */
-
-#define AU1000_INTC0_INT_BASE	(MIPS_CPU_IRQ_BASE + 8)
-#define AU1000_INTC0_INT_LAST	(AU1000_INTC0_INT_BASE + 31)
-#define AU1000_INTC1_INT_BASE	(AU1000_INTC0_INT_BASE + 32)
-#define AU1000_INTC1_INT_LAST	(AU1000_INTC1_INT_BASE + 31)
+#define FOR_PLATFORM_C_USB_HOST_INT AU1200_USB_INT
 
-#define AU1000_MAX_INTR 	AU1000_INTC1_INT_LAST
-#define INTX			0xFF			/* not valid */
+#endif /* CONFIG_SOC_AU1200 */
 
 /* Programmable Counters 0 and 1 */
 #define SYS_BASE		0xB1900000
@@ -1231,14 +1256,6 @@ enum soc_au1200_ints {
 #define MAC_RX_BUFF3_STATUS	0x30
 #define MAC_RX_BUFF3_ADDR	0x34
 
-/* UARTS 0-3 */
-#define UART_BASE		UART0_ADDR
-#ifdef	CONFIG_SOC_AU1200
-#define UART_DEBUG_BASE 	UART1_ADDR
-#else
-#define UART_DEBUG_BASE 	UART3_ADDR
-#endif
-
 #define UART_RX		0	/* Receive buffer */
 #define UART_TX		4	/* Transmit buffer */
 #define UART_IER	8	/* Interrupt Enable Register */
@@ -1251,84 +1268,6 @@ enum soc_au1200_ints {
 #define UART_CLK	0x28	/* Baud Rate Clock Divider */
 #define UART_MOD_CNTRL	0x100	/* Module Control */
 
-#define UART_FCR_ENABLE_FIFO	0x01 /* Enable the FIFO */
-#define UART_FCR_CLEAR_RCVR	0x02 /* Clear the RCVR FIFO */
-#define UART_FCR_CLEAR_XMIT	0x04 /* Clear the XMIT FIFO */
-#define UART_FCR_DMA_SELECT	0x08 /* For DMA applications */
-#define UART_FCR_TRIGGER_MASK	0xF0 /* Mask for the FIFO trigger range */
-#define UART_FCR_R_TRIGGER_1	0x00 /* Mask for receive trigger set at 1 */
-#define UART_FCR_R_TRIGGER_4	0x40 /* Mask for receive trigger set at 4 */
-#define UART_FCR_R_TRIGGER_8	0x80 /* Mask for receive trigger set at 8 */
-#define UART_FCR_R_TRIGGER_14   0xA0 /* Mask for receive trigger set at 14 */
-#define UART_FCR_T_TRIGGER_0	0x00 /* Mask for transmit trigger set at 0 */
-#define UART_FCR_T_TRIGGER_4	0x10 /* Mask for transmit trigger set at 4 */
-#define UART_FCR_T_TRIGGER_8    0x20 /* Mask for transmit trigger set at 8 */
-#define UART_FCR_T_TRIGGER_12	0x30 /* Mask for transmit trigger set at 12 */
-
-/*
- * These are the definitions for the Line Control Register
- */
-#define UART_LCR_SBC	0x40	/* Set break control */
-#define UART_LCR_SPAR	0x20	/* Stick parity (?) */
-#define UART_LCR_EPAR	0x10	/* Even parity select */
-#define UART_LCR_PARITY	0x08	/* Parity Enable */
-#define UART_LCR_STOP	0x04	/* Stop bits: 0=1 stop bit, 1= 2 stop bits */
-#define UART_LCR_WLEN5  0x00	/* Wordlength: 5 bits */
-#define UART_LCR_WLEN6  0x01	/* Wordlength: 6 bits */
-#define UART_LCR_WLEN7  0x02	/* Wordlength: 7 bits */
-#define UART_LCR_WLEN8  0x03	/* Wordlength: 8 bits */
-
-/*
- * These are the definitions for the Line Status Register
- */
-#define UART_LSR_TEMT	0x40	/* Transmitter empty */
-#define UART_LSR_THRE	0x20	/* Transmit-hold-register empty */
-#define UART_LSR_BI	0x10	/* Break interrupt indicator */
-#define UART_LSR_FE	0x08	/* Frame error indicator */
-#define UART_LSR_PE	0x04	/* Parity error indicator */
-#define UART_LSR_OE	0x02	/* Overrun error indicator */
-#define UART_LSR_DR	0x01	/* Receiver data ready */
-
-/*
- * These are the definitions for the Interrupt Identification Register
- */
-#define UART_IIR_NO_INT	0x01	/* No interrupts pending */
-#define UART_IIR_ID	0x06	/* Mask for the interrupt ID */
-#define UART_IIR_MSI	0x00	/* Modem status interrupt */
-#define UART_IIR_THRI	0x02	/* Transmitter holding register empty */
-#define UART_IIR_RDI	0x04	/* Receiver data interrupt */
-#define UART_IIR_RLSI	0x06	/* Receiver line status interrupt */
-
-/*
- * These are the definitions for the Interrupt Enable Register
- */
-#define UART_IER_MSI	0x08	/* Enable Modem status interrupt */
-#define UART_IER_RLSI	0x04	/* Enable receiver line status interrupt */
-#define UART_IER_THRI	0x02	/* Enable Transmitter holding register int. */
-#define UART_IER_RDI	0x01	/* Enable receiver data interrupt */
-
-/*
- * These are the definitions for the Modem Control Register
- */
-#define UART_MCR_LOOP	0x10	/* Enable loopback test mode */
-#define UART_MCR_OUT2	0x08	/* Out2 complement */
-#define UART_MCR_OUT1	0x04	/* Out1 complement */
-#define UART_MCR_RTS	0x02	/* RTS complement */
-#define UART_MCR_DTR	0x01	/* DTR complement */
-
-/*
- * These are the definitions for the Modem Status Register
- */
-#define UART_MSR_DCD	0x80	/* Data Carrier Detect */
-#define UART_MSR_RI	0x40	/* Ring Indicator */
-#define UART_MSR_DSR	0x20	/* Data Set Ready */
-#define UART_MSR_CTS	0x10	/* Clear to Send */
-#define UART_MSR_DDCD	0x08	/* Delta DCD */
-#define UART_MSR_TERI	0x04	/* Trailing edge ring indicator */
-#define UART_MSR_DDSR	0x02	/* Delta DSR */
-#define UART_MSR_DCTS	0x01	/* Delta CTS */
-#define UART_MSR_ANY_DELTA 0x0F	/* Any of the delta bits! */
-
 /* SSIO */
 #define SSI0_STATUS		0xB1600000
 #  define SSI_STATUS_BF 	(1 << 4)
@@ -1720,7 +1659,7 @@ enum soc_au1200_ints {
 #define IOPORT_RESOURCE_START	0x00001000	/* skip legacy probing */
 #define IOPORT_RESOURCE_END	0xffffffff
 #define IOMEM_RESOURCE_START	0x10000000
-#define IOMEM_RESOURCE_END	0xffffffff
+#define IOMEM_RESOURCE_END	0xfffffffffULL
 
 #else /* Au1000 and Au1100 and Au1200 */
 
@@ -1728,7 +1667,7 @@ enum soc_au1200_ints {
 #define IOPORT_RESOURCE_START	0x10000000
 #define IOPORT_RESOURCE_END	0xffffffff
 #define IOMEM_RESOURCE_START	0x10000000
-#define IOMEM_RESOURCE_END	0xffffffff
+#define IOMEM_RESOURCE_END	0xfffffffffULL
 
 #define PCI_IO_START	0
 #define PCI_IO_END	0
@@ -1739,53 +1678,4 @@ enum soc_au1200_ints {
 
 #endif
 
-#ifndef _LANGUAGE_ASSEMBLY
-typedef volatile struct {
-	/* 0x0000 */ u32 toytrim;
-	/* 0x0004 */ u32 toywrite;
-	/* 0x0008 */ u32 toymatch0;
-	/* 0x000C */ u32 toymatch1;
-	/* 0x0010 */ u32 toymatch2;
-	/* 0x0014 */ u32 cntrctrl;
-	/* 0x0018 */ u32 scratch0;
-	/* 0x001C */ u32 scratch1;
-	/* 0x0020 */ u32 freqctrl0;
-	/* 0x0024 */ u32 freqctrl1;
-	/* 0x0028 */ u32 clksrc;
-	/* 0x002C */ u32 pinfunc;
-	/* 0x0030 */ u32 reserved0;
-	/* 0x0034 */ u32 wakemsk;
-	/* 0x0038 */ u32 endian;
-	/* 0x003C */ u32 powerctrl;
-	/* 0x0040 */ u32 toyread;
-	/* 0x0044 */ u32 rtctrim;
-	/* 0x0048 */ u32 rtcwrite;
-	/* 0x004C */ u32 rtcmatch0;
-	/* 0x0050 */ u32 rtcmatch1;
-	/* 0x0054 */ u32 rtcmatch2;
-	/* 0x0058 */ u32 rtcread;
-	/* 0x005C */ u32 wakesrc;
-	/* 0x0060 */ u32 cpupll;
-	/* 0x0064 */ u32 auxpll;
-	/* 0x0068 */ u32 reserved1;
-	/* 0x006C */ u32 reserved2;
-	/* 0x0070 */ u32 reserved3;
-	/* 0x0074 */ u32 reserved4;
-	/* 0x0078 */ u32 slppwr;
-	/* 0x007C */ u32 sleep;
-	/* 0x0080 */ u32 reserved5[32];
-	/* 0x0100 */ u32 trioutrd;
-#define trioutclr trioutrd
-	/* 0x0104 */ u32 reserved6;
-	/* 0x0108 */ u32 outputrd;
-#define outputset outputrd
-	/* 0x010C */ u32 outputclr;
-	/* 0x0110 */ u32 pinstaterd;
-#define pininputen pinstaterd
-} AU1X00_SYS;
-
-static AU1X00_SYS * const sys = (AU1X00_SYS *)SYS_BASE;
-
-#endif
-
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/au1100_mmc.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/au1100_mmc.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/au1100_mmc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/au1100_mmc.h	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,7 @@ struct au1xmmc_platform_data {
 	int(*card_readonly)(void *mmc_host);
 	void(*set_power)(void *mmc_host, int state);
 	struct led_classdev *led;
+	unsigned long mask_host_caps;
 };
 
 #define SD0_BASE	0xB0600000
@@ -205,4 +206,3 @@ struct au1xmmc_platform_data {
 
 
 #endif /* __ASM_AU1100_MMC_H */
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h	2010-05-16 17:17:36.000000000 -0400
@@ -339,8 +339,8 @@ u32 au1xxx_dbdma_set_devwidth(u32 chanid
 u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries);
 
 /* Put buffers on source/destination descriptors. */
-u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags);
-u32 _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags);
+u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags);
+u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags);
 
 /* Get a buffer from the destination descriptor. */
 u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes);
@@ -363,25 +363,6 @@ void au1xxx_dbdma_suspend(void);
 void au1xxx_dbdma_resume(void);
 #endif
 
-
-/*
- * Some compatibilty macros -- needed to make changes to API
- * without breaking existing drivers.
- */
-#define au1xxx_dbdma_put_source(chanid, buf, nbytes)			\
-	_au1xxx_dbdma_put_source(chanid, buf, nbytes, DDMA_FLAGS_IE)
-#define au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags)	\
-	_au1xxx_dbdma_put_source(chanid, buf, nbytes, flags)
-#define put_source_flags(chanid, buf, nbytes, flags)			\
-	au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags)
-
-#define au1xxx_dbdma_put_dest(chanid, buf, nbytes)			\
-	_au1xxx_dbdma_put_dest(chanid, buf, nbytes, DDMA_FLAGS_IE)
-#define au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags) 	\
-	_au1xxx_dbdma_put_dest(chanid, buf, nbytes, flags)
-#define put_dest_flags(chanid, buf, nbytes, flags)			\
-	au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags)
-
 /*
  *	Flags for the put_source/put_dest functions.
  */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,17 @@
+#ifndef __AU1X00_ETH_DATA_H
+#define __AU1X00_ETH_DATA_H
+
+/* Platform specific PHY configuration passed to the MAC driver */
+struct au1000_eth_platform_data {
+	int phy_static_config;
+	int phy_search_highest_addr;
+	int phy1_search_mac0;
+	int phy_addr;
+	int phy_busid;
+	int phy_irq;
+};
+
+void __init au1xxx_override_eth_cfg(unsigned port,
+			struct au1000_eth_platform_data *eth_data);
+
+#endif /* __AU1X00_ETH_DATA_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/gpio-au1000.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/gpio-au1000.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/gpio-au1000.h	2010-05-16 17:17:36.000000000 -0400
@@ -35,15 +35,13 @@ static inline int au1000_gpio2_to_irq(in
 	return -ENXIO;
 }
 
-#ifdef CONFIG_SOC_AU1000
 static inline int au1000_irq_to_gpio(int irq)
 {
-	if ((irq >= AU1000_GPIO_0) && (irq <= AU1000_GPIO_31))
-		return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO_0) + 0;
+	if ((irq >= AU1000_GPIO0_INT) && (irq <= AU1000_GPIO31_INT))
+		return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO0_INT) + 0;
 
 	return -ENXIO;
 }
-#endif
 
 static inline int au1500_gpio1_to_irq(int gpio)
 {
@@ -71,27 +69,25 @@ static inline int au1500_gpio2_to_irq(in
 	return -ENXIO;
 }
 
-#ifdef CONFIG_SOC_AU1500
 static inline int au1500_irq_to_gpio(int irq)
 {
 	switch (irq) {
-	case AU1000_GPIO_0 ... AU1000_GPIO_15:
-	case AU1500_GPIO_20:
-	case AU1500_GPIO_23 ... AU1500_GPIO_28:
-		return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO_0) + 0;
-	case AU1500_GPIO_200 ... AU1500_GPIO_203:
-		return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO_200) + 0;
-	case AU1500_GPIO_204 ... AU1500_GPIO_205:
-		return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO_204) + 4;
-	case AU1500_GPIO_206 ... AU1500_GPIO_207:
-		return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO_206) + 6;
-	case AU1500_GPIO_208_215:
+	case AU1500_GPIO0_INT ... AU1500_GPIO15_INT:
+	case AU1500_GPIO20_INT:
+	case AU1500_GPIO23_INT ... AU1500_GPIO28_INT:
+		return ALCHEMY_GPIO1_BASE + (irq - AU1500_GPIO0_INT) + 0;
+	case AU1500_GPIO200_INT ... AU1500_GPIO203_INT:
+		return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO200_INT) + 0;
+	case AU1500_GPIO204_INT ... AU1500_GPIO205_INT:
+		return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO204_INT) + 4;
+	case AU1500_GPIO206_INT ... AU1500_GPIO207_INT:
+		return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO206_INT) + 6;
+	case AU1500_GPIO208_215_INT:
 		return ALCHEMY_GPIO2_BASE + 8;
 	}
 
 	return -ENXIO;
 }
-#endif
 
 static inline int au1100_gpio1_to_irq(int gpio)
 {
@@ -108,19 +104,17 @@ static inline int au1100_gpio2_to_irq(in
 	return -ENXIO;
 }
 
-#ifdef CONFIG_SOC_AU1100
 static inline int au1100_irq_to_gpio(int irq)
 {
 	switch (irq) {
-	case AU1000_GPIO_0 ... AU1000_GPIO_31:
-		return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO_0) + 0;
-	case AU1100_GPIO_208_215:
+	case AU1100_GPIO0_INT ... AU1100_GPIO31_INT:
+		return ALCHEMY_GPIO1_BASE + (irq - AU1100_GPIO0_INT) + 0;
+	case AU1100_GPIO208_215_INT:
 		return ALCHEMY_GPIO2_BASE + 8;
 	}
 
 	return -ENXIO;
 }
-#endif
 
 static inline int au1550_gpio1_to_irq(int gpio)
 {
@@ -149,24 +143,22 @@ static inline int au1550_gpio2_to_irq(in
 	return -ENXIO;
 }
 
-#ifdef CONFIG_SOC_AU1550
 static inline int au1550_irq_to_gpio(int irq)
 {
 	switch (irq) {
-	case AU1000_GPIO_0 ... AU1000_GPIO_15:
-		return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO_0) + 0;
-	case AU1550_GPIO_200:
-	case AU1500_GPIO_201_205:
-		return ALCHEMY_GPIO2_BASE + (irq - AU1550_GPIO_200) + 0;
-	case AU1500_GPIO_16 ... AU1500_GPIO_28:
-		return ALCHEMY_GPIO1_BASE + (irq - AU1500_GPIO_16) + 16;
-	case AU1500_GPIO_206 ... AU1500_GPIO_208_218:
-		return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO_206) + 6;
+	case AU1550_GPIO0_INT ... AU1550_GPIO15_INT:
+		return ALCHEMY_GPIO1_BASE + (irq - AU1550_GPIO0_INT) + 0;
+	case AU1550_GPIO200_INT:
+	case AU1550_GPIO201_205_INT:
+		return ALCHEMY_GPIO2_BASE + (irq - AU1550_GPIO200_INT) + 0;
+	case AU1550_GPIO16_INT ... AU1550_GPIO28_INT:
+		return ALCHEMY_GPIO1_BASE + (irq - AU1550_GPIO16_INT) + 16;
+	case AU1550_GPIO206_INT ... AU1550_GPIO208_215_INT:
+		return ALCHEMY_GPIO2_BASE + (irq - AU1550_GPIO206_INT) + 6;
 	}
 
 	return -ENXIO;
 }
-#endif
 
 static inline int au1200_gpio1_to_irq(int gpio)
 {
@@ -187,23 +179,21 @@ static inline int au1200_gpio2_to_irq(in
 	return -ENXIO;
 }
 
-#ifdef CONFIG_SOC_AU1200
 static inline int au1200_irq_to_gpio(int irq)
 {
 	switch (irq) {
-	case AU1000_GPIO_0 ... AU1000_GPIO_31:
-		return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO_0) + 0;
-	case AU1200_GPIO_200 ... AU1200_GPIO_202:
-		return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO_200) + 0;
-	case AU1200_GPIO_203:
+	case AU1200_GPIO0_INT ... AU1200_GPIO31_INT:
+		return ALCHEMY_GPIO1_BASE + (irq - AU1200_GPIO0_INT) + 0;
+	case AU1200_GPIO200_INT ... AU1200_GPIO202_INT:
+		return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO200_INT) + 0;
+	case AU1200_GPIO203_INT:
 		return ALCHEMY_GPIO2_BASE + 3;
-	case AU1200_GPIO_204 ... AU1200_GPIO_208_215:
-		return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO_204) + 4;
+	case AU1200_GPIO204_INT ... AU1200_GPIO208_215_INT:
+		return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO204_INT) + 4;
 	}
 
 	return -ENXIO;
 }
-#endif
 
 /*
  * GPIO1 block macros for common linux gpio functions.
@@ -246,19 +236,19 @@ static inline int alchemy_gpio1_is_valid
 
 static inline int alchemy_gpio1_to_irq(int gpio)
 {
-#if defined(CONFIG_SOC_AU1000)
-	return au1000_gpio1_to_irq(gpio);
-#elif defined(CONFIG_SOC_AU1100)
-	return au1100_gpio1_to_irq(gpio);
-#elif defined(CONFIG_SOC_AU1500)
-	return au1500_gpio1_to_irq(gpio);
-#elif defined(CONFIG_SOC_AU1550)
-	return au1550_gpio1_to_irq(gpio);
-#elif defined(CONFIG_SOC_AU1200)
-	return au1200_gpio1_to_irq(gpio);
-#else
+	switch (alchemy_get_cputype()) {
+	case ALCHEMY_CPU_AU1000:
+		return au1000_gpio1_to_irq(gpio);
+	case ALCHEMY_CPU_AU1100:
+		return au1100_gpio1_to_irq(gpio);
+	case ALCHEMY_CPU_AU1500:
+		return au1500_gpio1_to_irq(gpio);
+	case ALCHEMY_CPU_AU1550:
+		return au1550_gpio1_to_irq(gpio);
+	case ALCHEMY_CPU_AU1200:
+		return au1200_gpio1_to_irq(gpio);
+	}
 	return -ENXIO;
-#endif
 }
 
 /*
@@ -316,19 +306,19 @@ static inline int alchemy_gpio2_is_valid
 
 static inline int alchemy_gpio2_to_irq(int gpio)
 {
-#if defined(CONFIG_SOC_AU1000)
-	return au1000_gpio2_to_irq(gpio);
-#elif defined(CONFIG_SOC_AU1100)
-	return au1100_gpio2_to_irq(gpio);
-#elif defined(CONFIG_SOC_AU1500)
-	return au1500_gpio2_to_irq(gpio);
-#elif defined(CONFIG_SOC_AU1550)
-	return au1550_gpio2_to_irq(gpio);
-#elif defined(CONFIG_SOC_AU1200)
-	return au1200_gpio2_to_irq(gpio);
-#else
+	switch (alchemy_get_cputype()) {
+	case ALCHEMY_CPU_AU1000:
+		return au1000_gpio2_to_irq(gpio);
+	case ALCHEMY_CPU_AU1100:
+		return au1100_gpio2_to_irq(gpio);
+	case ALCHEMY_CPU_AU1500:
+		return au1500_gpio2_to_irq(gpio);
+	case ALCHEMY_CPU_AU1550:
+		return au1550_gpio2_to_irq(gpio);
+	case ALCHEMY_CPU_AU1200:
+		return au1200_gpio2_to_irq(gpio);
+	}
 	return -ENXIO;
-#endif
 }
 
 /**********************************************************************/
@@ -384,10 +374,13 @@ static inline void alchemy_gpio2_enable_
 
 	gpio2 -= ALCHEMY_GPIO2_BASE;
 
-#if defined(CONFIG_SOC_AU1100) || defined(CONFIG_SOC_AU1500)
 	/* Au1100/Au1500 have GPIO208-215 enable bits at 0..7 */
-	gpio2 -= 8;
-#endif
+	switch (alchemy_get_cputype()) {
+	case ALCHEMY_CPU_AU1100:
+	case ALCHEMY_CPU_AU1500:
+		gpio2 -= 8;
+	}
+
 	local_irq_save(flags);
 	__alchemy_gpio2_mod_int(gpio2, 1);
 	local_irq_restore(flags);
@@ -405,10 +398,13 @@ static inline void alchemy_gpio2_disable
 
 	gpio2 -= ALCHEMY_GPIO2_BASE;
 
-#if defined(CONFIG_SOC_AU1100) || defined(CONFIG_SOC_AU1500)
 	/* Au1100/Au1500 have GPIO208-215 enable bits at 0..7 */
-	gpio2 -= 8;
-#endif
+	switch (alchemy_get_cputype()) {
+	case ALCHEMY_CPU_AU1100:
+	case ALCHEMY_CPU_AU1500:
+		gpio2 -= 8;
+	}
+
 	local_irq_save(flags);
 	__alchemy_gpio2_mod_int(gpio2, 0);
 	local_irq_restore(flags);
@@ -494,19 +490,19 @@ static inline int alchemy_gpio_to_irq(in
 
 static inline int alchemy_irq_to_gpio(int irq)
 {
-#if defined(CONFIG_SOC_AU1000)
-	return au1000_irq_to_gpio(irq);
-#elif defined(CONFIG_SOC_AU1100)
-	return au1100_irq_to_gpio(irq);
-#elif defined(CONFIG_SOC_AU1500)
-	return au1500_irq_to_gpio(irq);
-#elif defined(CONFIG_SOC_AU1550)
-	return au1550_irq_to_gpio(irq);
-#elif defined(CONFIG_SOC_AU1200)
-	return au1200_irq_to_gpio(irq);
-#else
+	switch (alchemy_get_cputype()) {
+	case ALCHEMY_CPU_AU1000:
+		return au1000_irq_to_gpio(irq);
+	case ALCHEMY_CPU_AU1100:
+		return au1100_irq_to_gpio(irq);
+	case ALCHEMY_CPU_AU1500:
+		return au1500_irq_to_gpio(irq);
+	case ALCHEMY_CPU_AU1550:
+		return au1550_irq_to_gpio(irq);
+	case ALCHEMY_CPU_AU1200:
+		return au1200_irq_to_gpio(irq);
+	}
 	return -ENXIO;
-#endif
 }
 
 /**********************************************************************/
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/gpio.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/gpio.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/gpio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/gpio.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #ifndef _ALCHEMY_GPIO_H_
 #define _ALCHEMY_GPIO_H_
 
-#if defined(CONFIG_ALCHEMY_GPIO_AU1000)
+#if defined(CONFIG_ALCHEMY_GPIOINT_AU1000)
 
 #include <asm/mach-au1x00/gpio-au1000.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/ioremap.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/ioremap.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/ioremap.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/ioremap.h	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
 
 #include <linux/types.h>
 
-#ifdef CONFIG_64BIT_PHYS_ADDR
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI)
 extern phys_t __fixup_bigphys_addr(phys_t, phys_t);
 #else
 static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/prom.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/prom.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/prom.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-au1x00/prom.h	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,6 @@ extern char **prom_argv;
 extern char **prom_envp;
 
 extern void prom_init_cmdline(void);
-extern char *prom_getcmdline(void);
 extern char *prom_getenv(char *envname);
 extern int prom_get_ethernet_addr(char *ethernet_addr);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h	2010-05-16 17:17:36.000000000 -0400
@@ -85,6 +85,7 @@ enum bcm63xx_regs_set {
 	RSET_TIMER,
 	RSET_WDT,
 	RSET_UART0,
+	RSET_UART1,
 	RSET_GPIO,
 	RSET_SPI,
 	RSET_UDC0,
@@ -123,6 +124,7 @@ enum bcm63xx_regs_set {
 #define BCM_6338_TIMER_BASE		(0xfffe0200)
 #define BCM_6338_WDT_BASE		(0xfffe021c)
 #define BCM_6338_UART0_BASE		(0xfffe0300)
+#define BCM_6338_UART1_BASE		(0xdeadbeef)
 #define BCM_6338_GPIO_BASE		(0xfffe0400)
 #define BCM_6338_SPI_BASE		(0xfffe0c00)
 #define BCM_6338_UDC0_BASE		(0xdeadbeef)
@@ -153,6 +155,7 @@ enum bcm63xx_regs_set {
 #define BCM_6345_TIMER_BASE		(0xfffe0200)
 #define BCM_6345_WDT_BASE		(0xfffe021c)
 #define BCM_6345_UART0_BASE		(0xfffe0300)
+#define BCM_6345_UART1_BASE		(0xdeadbeef)
 #define BCM_6345_GPIO_BASE		(0xfffe0400)
 #define BCM_6345_SPI_BASE		(0xdeadbeef)
 #define BCM_6345_UDC0_BASE		(0xdeadbeef)
@@ -182,6 +185,7 @@ enum bcm63xx_regs_set {
 #define BCM_6348_TIMER_BASE		(0xfffe0200)
 #define BCM_6348_WDT_BASE		(0xfffe021c)
 #define BCM_6348_UART0_BASE		(0xfffe0300)
+#define BCM_6348_UART1_BASE		(0xdeadbeef)
 #define BCM_6348_GPIO_BASE		(0xfffe0400)
 #define BCM_6348_SPI_BASE		(0xfffe0c00)
 #define BCM_6348_UDC0_BASE		(0xfffe1000)
@@ -208,6 +212,7 @@ enum bcm63xx_regs_set {
 #define BCM_6358_TIMER_BASE		(0xfffe0040)
 #define BCM_6358_WDT_BASE		(0xfffe005c)
 #define BCM_6358_UART0_BASE		(0xfffe0100)
+#define BCM_6358_UART1_BASE		(0xfffe0120)
 #define BCM_6358_GPIO_BASE		(0xfffe0080)
 #define BCM_6358_SPI_BASE		(0xdeadbeef)
 #define BCM_6358_UDC0_BASE		(0xfffe0800)
@@ -246,6 +251,8 @@ static inline unsigned long bcm63xx_regs
 		return BCM_6338_WDT_BASE;
 	case RSET_UART0:
 		return BCM_6338_UART0_BASE;
+	case RSET_UART1:
+		return BCM_6338_UART1_BASE;
 	case RSET_GPIO:
 		return BCM_6338_GPIO_BASE;
 	case RSET_SPI:
@@ -292,6 +299,8 @@ static inline unsigned long bcm63xx_regs
 		return BCM_6345_WDT_BASE;
 	case RSET_UART0:
 		return BCM_6345_UART0_BASE;
+	case RSET_UART1:
+		return BCM_6345_UART1_BASE;
 	case RSET_GPIO:
 		return BCM_6345_GPIO_BASE;
 	case RSET_SPI:
@@ -338,6 +347,8 @@ static inline unsigned long bcm63xx_regs
 		return BCM_6348_WDT_BASE;
 	case RSET_UART0:
 		return BCM_6348_UART0_BASE;
+	case RSET_UART1:
+		return BCM_6348_UART1_BASE;
 	case RSET_GPIO:
 		return BCM_6348_GPIO_BASE;
 	case RSET_SPI:
@@ -384,6 +395,8 @@ static inline unsigned long bcm63xx_regs
 		return BCM_6358_WDT_BASE;
 	case RSET_UART0:
 		return BCM_6358_UART0_BASE;
+	case RSET_UART1:
+		return BCM_6358_UART1_BASE;
 	case RSET_GPIO:
 		return BCM_6358_GPIO_BASE;
 	case RSET_SPI:
@@ -429,6 +442,7 @@ static inline unsigned long bcm63xx_regs
 enum bcm63xx_irq {
 	IRQ_TIMER = 0,
 	IRQ_UART0,
+	IRQ_UART1,
 	IRQ_DSL,
 	IRQ_ENET0,
 	IRQ_ENET1,
@@ -510,6 +524,7 @@ enum bcm63xx_irq {
  */
 #define BCM_6358_TIMER_IRQ		(IRQ_INTERNAL_BASE + 0)
 #define BCM_6358_UART0_IRQ		(IRQ_INTERNAL_BASE + 2)
+#define BCM_6358_UART1_IRQ		(IRQ_INTERNAL_BASE + 3)
 #define BCM_6358_OHCI0_IRQ		(IRQ_INTERNAL_BASE + 5)
 #define BCM_6358_ENET1_IRQ		(IRQ_INTERNAL_BASE + 6)
 #define BCM_6358_ENET0_IRQ		(IRQ_INTERNAL_BASE + 8)
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_UART_H_
+#define BCM63XX_DEV_UART_H_
+
+int bcm63xx_uart_register(unsigned int id);
+
+#endif /* BCM63XX_DEV_UART_H_ */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,10 @@ static inline unsigned long bcm63xx_gpio
 	switch (bcm63xx_get_cpu_id()) {
 	case BCM6358_CPU_ID:
 		return 40;
+	case BCM6338_CPU_ID:
+		return 8;
+	case BCM6345_CPU_ID:
+		return 16;
 	case BCM6348_CPU_ID:
 	default:
 		return 37;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h	2010-05-16 17:17:36.000000000 -0400
@@ -770,4 +770,3 @@
 #define DMIPSPLLCFG_N2_MASK		(0x7 << DMIPSPLLCFG_N2_SHIFT)
 
 #endif /* BCM63XX_REGS_H_ */
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -45,6 +45,8 @@ struct board_info {
 	unsigned int	has_ohci0:1;
 	unsigned int	has_ehci0:1;
 	unsigned int	has_dsp:1;
+	unsigned int	has_uart0:1;
+	unsigned int	has_uart1:1;
 
 	/* ethernet config */
 	struct bcm63xx_enet_platform_data enet0;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,7 @@
 #define cpu_has_smartmips		0
 #define cpu_has_vtag_icache		0
 
-#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCMCPU_IS_6348) || defined(CONFIG_CPU_IS_6338) || defined(CONFIG_CPU_IS_BCM6345))
+#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCM63XX_CPU_6348) || defined(CONFIG_BCM63XX_CPU_6345) || defined(CONFIG_BCM63XX_CPU_6338))
 #define cpu_has_dc_aliases		0
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h	2010-05-16 17:17:36.000000000 -0400
@@ -58,6 +58,9 @@
 #define cpu_has_vint		0
 #define cpu_has_veic		0
 #define cpu_hwrena_impl_bits	0xc0000000
+
+#define kernel_uses_smartmips_rixi (cpu_data[0].cputype == CPU_CAVIUM_OCTEON_PLUS)
+
 #define ARCH_HAS_READ_CURRENT_TIMER 1
 #define ARCH_HAS_IRQ_PER_CPU	1
 #define ARCH_HAS_SPINLOCK_PREFETCH 1
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-db1x00/bcsr.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-db1x00/bcsr.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-db1x00/bcsr.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-db1x00/bcsr.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,238 @@
+/*
+ * bcsr.h -- Db1xxx/Pb1xxx Devboard CPLD registers ("BCSR") abstraction.
+ *
+ * All Alchemy development boards (except, of course, the weird PB1000)
+ * have a few registers in a CPLD with standardised layout; they mostly
+ * only differ in base address and bit meanings in the RESETS and BOARD
+ * registers.
+ *
+ * All data taken from the official AMD board documentation sheets.
+ */
+
+#ifndef _DB1XXX_BCSR_H_
+#define _DB1XXX_BCSR_H_
+
+
+/* BCSR base addresses on various boards. BCSR base 2 refers to the
+ * physical address of the first HEXLEDS register, which is usually
+ * a variable offset from the WHOAMI register.
+ */
+
+/* DB1000, DB1100, DB1500, PB1100, PB1500 */
+#define DB1000_BCSR_PHYS_ADDR	0x0E000000
+#define DB1000_BCSR_HEXLED_OFS	0x01000000
+
+#define DB1550_BCSR_PHYS_ADDR	0x0F000000
+#define DB1550_BCSR_HEXLED_OFS	0x00400000
+
+#define PB1550_BCSR_PHYS_ADDR	0x0F000000
+#define PB1550_BCSR_HEXLED_OFS	0x00800000
+
+#define DB1200_BCSR_PHYS_ADDR	0x19800000
+#define DB1200_BCSR_HEXLED_OFS	0x00400000
+
+#define PB1200_BCSR_PHYS_ADDR	0x0D800000
+#define PB1200_BCSR_HEXLED_OFS	0x00400000
+
+
+enum bcsr_id {
+	/* BCSR base 1 */
+	BCSR_WHOAMI	= 0,
+	BCSR_STATUS,
+	BCSR_SWITCHES,
+	BCSR_RESETS,
+	BCSR_PCMCIA,
+	BCSR_BOARD,
+	BCSR_LEDS,
+	BCSR_SYSTEM,
+	/* Au1200/1300 based boards */
+	BCSR_INTCLR,
+	BCSR_INTSET,
+	BCSR_MASKCLR,
+	BCSR_MASKSET,
+	BCSR_SIGSTAT,
+	BCSR_INTSTAT,
+
+	/* BCSR base 2 */
+	BCSR_HEXLEDS,
+	BCSR_RSVD1,
+	BCSR_HEXCLEAR,
+
+	BCSR_CNT,
+};
+
+/* register offsets, valid for all Db1xxx/Pb1xxx boards */
+#define BCSR_REG_WHOAMI		0x00
+#define BCSR_REG_STATUS		0x04
+#define BCSR_REG_SWITCHES	0x08
+#define BCSR_REG_RESETS		0x0c
+#define BCSR_REG_PCMCIA		0x10
+#define BCSR_REG_BOARD		0x14
+#define BCSR_REG_LEDS		0x18
+#define BCSR_REG_SYSTEM		0x1c
+/* Au1200/Au1300 based boards: CPLD IRQ muxer */
+#define BCSR_REG_INTCLR		0x20
+#define BCSR_REG_INTSET		0x24
+#define BCSR_REG_MASKCLR	0x28
+#define BCSR_REG_MASKSET	0x2c
+#define BCSR_REG_SIGSTAT	0x30
+#define BCSR_REG_INTSTAT	0x34
+
+/* hexled control, offset from BCSR base 2 */
+#define BCSR_REG_HEXLEDS	0x00
+#define BCSR_REG_HEXCLEAR	0x08
+
+/*
+ * Register Bits and Pieces.
+ */
+#define BCSR_WHOAMI_DCID(x)		((x) & 0xf)
+#define BCSR_WHOAMI_CPLD(x)		(((x) >> 4) & 0xf)
+#define BCSR_WHOAMI_BOARD(x)		(((x) >> 8) & 0xf)
+
+/* register "WHOAMI" bits 11:8 identify the board */
+enum bcsr_whoami_boards {
+	BCSR_WHOAMI_PB1500 = 1,
+	BCSR_WHOAMI_PB1500R2,
+	BCSR_WHOAMI_PB1100,
+	BCSR_WHOAMI_DB1000,
+	BCSR_WHOAMI_DB1100,
+	BCSR_WHOAMI_DB1500,
+	BCSR_WHOAMI_DB1550,
+	BCSR_WHOAMI_PB1550_DDR,
+	BCSR_WHOAMI_PB1550 = BCSR_WHOAMI_PB1550_DDR,
+	BCSR_WHOAMI_PB1550_SDR,
+	BCSR_WHOAMI_PB1200_DDR1,
+	BCSR_WHOAMI_PB1200 = BCSR_WHOAMI_PB1200_DDR1,
+	BCSR_WHOAMI_PB1200_DDR2,
+	BCSR_WHOAMI_DB1200,
+};
+
+/* STATUS reg.  Unless otherwise noted, they're valid on all boards.
+ * PB1200 = DB1200.
+ */
+#define BCSR_STATUS_PC0VS		0x0003
+#define BCSR_STATUS_PC1VS		0x000C
+#define BCSR_STATUS_PC0FI		0x0010
+#define BCSR_STATUS_PC1FI		0x0020
+#define BCSR_STATUS_PB1550_SWAPBOOT	0x0040
+#define BCSR_STATUS_SRAMWIDTH		0x0080
+#define BCSR_STATUS_FLASHBUSY		0x0100
+#define BCSR_STATUS_ROMBUSY		0x0400
+#define BCSR_STATUS_SD0WP		0x0400	/* DB1200 */
+#define BCSR_STATUS_SD1WP		0x0800
+#define BCSR_STATUS_USBOTGID		0x0800	/* PB/DB1550 */
+#define BCSR_STATUS_DB1000_SWAPBOOT	0x2000
+#define BCSR_STATUS_DB1200_SWAPBOOT	0x0040	/* DB1200 */
+#define BCSR_STATUS_IDECBLID		0x0200	/* DB1200 */
+#define BCSR_STATUS_DB1200_U0RXD	0x1000	/* DB1200 */
+#define BCSR_STATUS_DB1200_U1RXD	0x2000	/* DB1200 */
+#define BCSR_STATUS_FLASHDEN		0xC000
+#define BCSR_STATUS_DB1550_U0RXD	0x1000	/* DB1550 */
+#define BCSR_STATUS_DB1550_U3RXD	0x2000	/* DB1550 */
+#define BCSR_STATUS_PB1550_U0RXD	0x1000	/* PB1550 */
+#define BCSR_STATUS_PB1550_U1RXD	0x2000	/* PB1550 */
+#define BCSR_STATUS_PB1550_U3RXD	0x8000	/* PB1550 */
+
+
+/* DB/PB1000,1100,1500,1550 */
+#define BCSR_RESETS_PHY0		0x0001
+#define BCSR_RESETS_PHY1		0x0002
+#define BCSR_RESETS_DC			0x0004
+#define BCSR_RESETS_FIR_SEL		0x2000
+#define BCSR_RESETS_IRDA_MODE_MASK	0xC000
+#define BCSR_RESETS_IRDA_MODE_FULL	0x0000
+#define BCSR_RESETS_PB1550_WSCFSM	0x2000
+#define BCSR_RESETS_IRDA_MODE_OFF	0x4000
+#define BCSR_RESETS_IRDA_MODE_2_3	0x8000
+#define BCSR_RESETS_IRDA_MODE_1_3	0xC000
+#define BCSR_RESETS_DMAREQ		0x8000	/* PB1550 */
+
+#define BCSR_BOARD_PCIM66EN		0x0001
+#define BCSR_BOARD_SD0PWR		0x0040
+#define BCSR_BOARD_SD1PWR		0x0080
+#define BCSR_BOARD_PCIM33		0x0100
+#define BCSR_BOARD_PCIEXTARB		0x0200
+#define BCSR_BOARD_GPIO200RST		0x0400
+#define BCSR_BOARD_PCICLKOUT		0x0800
+#define BCSR_BOARD_PCICFG		0x1000
+#define BCSR_BOARD_SPISEL		0x4000	/* PB/DB1550 */
+#define BCSR_BOARD_SD0WP		0x4000	/* DB1100 */
+#define BCSR_BOARD_SD1WP		0x8000	/* DB1100 */
+
+
+/* DB/PB1200 */
+#define BCSR_RESETS_ETH			0x0001
+#define BCSR_RESETS_CAMERA		0x0002
+#define BCSR_RESETS_DC			0x0004
+#define BCSR_RESETS_IDE			0x0008
+#define BCSR_RESETS_TV			0x0010	/* DB1200 */
+/* Not resets but in the same register */
+#define BCSR_RESETS_PWMR1MUX		0x0800	/* DB1200 */
+#define BCSR_RESETS_PB1200_WSCFSM	0x0800	/* PB1200 */
+#define BCSR_RESETS_PSC0MUX		0x1000
+#define BCSR_RESETS_PSC1MUX		0x2000
+#define BCSR_RESETS_SPISEL		0x4000
+#define BCSR_RESETS_SD1MUX		0x8000	/* PB1200 */
+
+#define BCSR_BOARD_LCDVEE		0x0001
+#define BCSR_BOARD_LCDVDD		0x0002
+#define BCSR_BOARD_LCDBL		0x0004
+#define BCSR_BOARD_CAMSNAP		0x0010
+#define BCSR_BOARD_CAMPWR		0x0020
+#define BCSR_BOARD_SD0PWR		0x0040
+
+
+#define BCSR_SWITCHES_DIP		0x00FF
+#define BCSR_SWITCHES_DIP_1		0x0080
+#define BCSR_SWITCHES_DIP_2		0x0040
+#define BCSR_SWITCHES_DIP_3		0x0020
+#define BCSR_SWITCHES_DIP_4		0x0010
+#define BCSR_SWITCHES_DIP_5		0x0008
+#define BCSR_SWITCHES_DIP_6		0x0004
+#define BCSR_SWITCHES_DIP_7		0x0002
+#define BCSR_SWITCHES_DIP_8		0x0001
+#define BCSR_SWITCHES_ROTARY		0x0F00
+
+
+#define BCSR_PCMCIA_PC0VPP		0x0003
+#define BCSR_PCMCIA_PC0VCC		0x000C
+#define BCSR_PCMCIA_PC0DRVEN		0x0010
+#define BCSR_PCMCIA_PC0RST		0x0080
+#define BCSR_PCMCIA_PC1VPP		0x0300
+#define BCSR_PCMCIA_PC1VCC		0x0C00
+#define BCSR_PCMCIA_PC1DRVEN		0x1000
+#define BCSR_PCMCIA_PC1RST		0x8000
+
+
+#define BCSR_LEDS_DECIMALS		0x0003
+#define BCSR_LEDS_LED0			0x0100
+#define BCSR_LEDS_LED1			0x0200
+#define BCSR_LEDS_LED2			0x0400
+#define BCSR_LEDS_LED3			0x0800
+
+
+#define BCSR_SYSTEM_RESET		0x8000	/* clear to reset */
+#define BCSR_SYSTEM_PWROFF		0x4000	/* set to power off */
+#define BCSR_SYSTEM_VDDI		0x001F	/* PB1xxx boards */
+
+
+
+
+/* initialize BCSR for a board. Provide the PHYSICAL addresses of both
+ * BCSR spaces.
+ */
+void __init bcsr_init(unsigned long bcsr1_phys, unsigned long bcsr2_phys);
+
+/* read a board register */
+unsigned short bcsr_read(enum bcsr_id reg);
+
+/* write to a board register */
+void bcsr_write(enum bcsr_id reg, unsigned short val);
+
+/* modify a register. clear bits set in 'clr', set bits set in 'set' */
+void bcsr_mod(enum bcsr_id reg, unsigned short clr, unsigned short set);
+
+/* install CPLD IRQ demuxer (DB1200/PB1200) */
+void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-db1x00/db1200.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-db1x00/db1200.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-db1x00/db1200.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-db1x00/db1200.h	2010-05-16 17:17:36.000000000 -0400
@@ -25,133 +25,9 @@
 #define __ASM_DB1200_H
 
 #include <linux/types.h>
+#include <asm/mach-au1x00/au1000.h>
 #include <asm/mach-au1x00/au1xxx_psc.h>
 
-#define DBDMA_AC97_TX_CHAN	DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN	DSCR_CMD0_PSC1_RX
-#define DBDMA_I2S_TX_CHAN	DSCR_CMD0_PSC1_TX
-#define DBDMA_I2S_RX_CHAN	DSCR_CMD0_PSC1_RX
-
-/*
- * SPI and SMB are muxed on the DBAu1200 board.
- * Refer to board documentation.
- */
-#define SPI_PSC_BASE		PSC0_BASE_ADDR
-#define SMBUS_PSC_BASE		PSC0_BASE_ADDR
-/*
- * AC'97 and I2S are muxed on the DBAu1200 board.
- * Refer to board documentation.
- */
-#define AC97_PSC_BASE		PSC1_BASE_ADDR
-#define I2S_PSC_BASE		PSC1_BASE_ADDR
-
-#define BCSR_KSEG1_ADDR 	0xB9800000
-
-typedef volatile struct
-{
-	/*00*/	u16 whoami;
-		u16 reserved0;
-	/*04*/	u16 status;
-		u16 reserved1;
-	/*08*/	u16 switches;
-		u16 reserved2;
-	/*0C*/	u16 resets;
-		u16 reserved3;
-
-	/*10*/	u16 pcmcia;
-		u16 reserved4;
-	/*14*/	u16 board;
-		u16 reserved5;
-	/*18*/	u16 disk_leds;
-		u16 reserved6;
-	/*1C*/	u16 system;
-		u16 reserved7;
-
-	/*20*/	u16 intclr;
-		u16 reserved8;
-	/*24*/	u16 intset;
-		u16 reserved9;
-	/*28*/	u16 intclr_mask;
-		u16 reserved10;
-	/*2C*/	u16 intset_mask;
-		u16 reserved11;
-
-	/*30*/	u16 sig_status;
-		u16 reserved12;
-	/*34*/	u16 int_status;
-		u16 reserved13;
-	/*38*/	u16 reserved14;
-		u16 reserved15;
-	/*3C*/	u16 reserved16;
-		u16 reserved17;
-
-} BCSR;
-
-static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
-
-/*
- * Register bit definitions for the BCSRs
- */
-#define BCSR_WHOAMI_DCID	0x000F
-#define BCSR_WHOAMI_CPLD	0x00F0
-#define BCSR_WHOAMI_BOARD	0x0F00
-
-#define BCSR_STATUS_PCMCIA0VS	0x0003
-#define BCSR_STATUS_PCMCIA1VS	0x000C
-#define BCSR_STATUS_SWAPBOOT	0x0040
-#define BCSR_STATUS_FLASHBUSY	0x0100
-#define BCSR_STATUS_IDECBLID	0x0200
-#define BCSR_STATUS_SD0WP	0x0400
-#define BCSR_STATUS_U0RXD	0x1000
-#define BCSR_STATUS_U1RXD	0x2000
-
-#define BCSR_SWITCHES_OCTAL	0x00FF
-#define BCSR_SWITCHES_DIP_1	0x0080
-#define BCSR_SWITCHES_DIP_2	0x0040
-#define BCSR_SWITCHES_DIP_3	0x0020
-#define BCSR_SWITCHES_DIP_4	0x0010
-#define BCSR_SWITCHES_DIP_5	0x0008
-#define BCSR_SWITCHES_DIP_6	0x0004
-#define BCSR_SWITCHES_DIP_7	0x0002
-#define BCSR_SWITCHES_DIP_8	0x0001
-#define BCSR_SWITCHES_ROTARY	0x0F00
-
-#define BCSR_RESETS_ETH		0x0001
-#define BCSR_RESETS_CAMERA	0x0002
-#define BCSR_RESETS_DC		0x0004
-#define BCSR_RESETS_IDE		0x0008
-#define BCSR_RESETS_TV		0x0010
-/* Not resets but in the same register */
-#define BCSR_RESETS_PWMR1MUX	0x0800
-#define BCSR_RESETS_PCS0MUX	0x1000
-#define BCSR_RESETS_PCS1MUX	0x2000
-#define BCSR_RESETS_SPISEL	0x4000
-
-#define BCSR_PCMCIA_PC0VPP	0x0003
-#define BCSR_PCMCIA_PC0VCC	0x000C
-#define BCSR_PCMCIA_PC0DRVEN	0x0010
-#define BCSR_PCMCIA_PC0RST	0x0080
-#define BCSR_PCMCIA_PC1VPP	0x0300
-#define BCSR_PCMCIA_PC1VCC	0x0C00
-#define BCSR_PCMCIA_PC1DRVEN	0x1000
-#define BCSR_PCMCIA_PC1RST	0x8000
-
-#define BCSR_BOARD_LCDVEE	0x0001
-#define BCSR_BOARD_LCDVDD	0x0002
-#define BCSR_BOARD_LCDBL	0x0004
-#define BCSR_BOARD_CAMSNAP	0x0010
-#define BCSR_BOARD_CAMPWR	0x0020
-#define BCSR_BOARD_SD0PWR	0x0040
-
-#define BCSR_LEDS_DECIMALS	0x0003
-#define BCSR_LEDS_LED0		0x0100
-#define BCSR_LEDS_LED1		0x0200
-#define BCSR_LEDS_LED2		0x0400
-#define BCSR_LEDS_LED3		0x0800
-
-#define BCSR_SYSTEM_POWEROFF	0x4000
-#define BCSR_SYSTEM_RESET	0x8000
-
 /* Bit positions for the different interrupt sources */
 #define BCSR_INT_IDE		0x0001
 #define BCSR_INT_ETH		0x0002
@@ -168,17 +44,15 @@ static BCSR * const bcsr = (BCSR *)BCSR_
 #define BCSR_INT_SD0INSERT	0x1000
 #define BCSR_INT_SD0EJECT	0x2000
 
-#define SMC91C111_PHYS_ADDR	0x19000300
-#define SMC91C111_INT		DB1200_ETH_INT
-
 #define IDE_PHYS_ADDR		0x18800000
 #define IDE_REG_SHIFT		5
-#define IDE_PHYS_LEN		(16 << IDE_REG_SHIFT)
-#define IDE_INT 		DB1200_IDE_INT
 #define IDE_DDMA_REQ		DSCR_CMD0_DMA_REQ1
 #define IDE_RQSIZE		128
 
-#define NAND_PHYS_ADDR		0x20000000
+#define DB1200_IDE_PHYS_ADDR	IDE_PHYS_ADDR
+#define DB1200_IDE_PHYS_LEN	(16 << IDE_REG_SHIFT)
+#define DB1200_ETH_PHYS_ADDR	0x19000300
+#define DB1200_NAND_PHYS_ADDR	0x20000000
 
 /*
  * External Interrupts for DBAu1200 as of 8/6/2004.
@@ -188,7 +62,7 @@ static BCSR * const bcsr = (BCSR *)BCSR_
  *   Example: IDE bis pos is  = 64 - 64
  *            ETH bit pos is  = 65 - 64
  */
-enum external_pb1200_ints {
+enum external_db1200_ints {
 	DB1200_INT_BEGIN	= AU1000_MAX_INTR + 1,
 
 	DB1200_IDE_INT		= DB1200_INT_BEGIN,
@@ -209,22 +83,4 @@ enum external_pb1200_ints {
 	DB1200_INT_END		= DB1200_INT_BEGIN + 15,
 };
 
-
-/*
- * DBAu1200 specific PCMCIA defines for drivers/pcmcia/au1000_db1x00.c
- */
-#define PCMCIA_MAX_SOCK  1
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
-
-/* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP, SLOT) \
-	((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
-
-#define BOARD_PC0_INT	DB1200_PC0_INT
-#define BOARD_PC1_INT	DB1200_PC1_INT
-#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1 << (8 + (2 * SOCKET)))
-
-/* NAND chip select */
-#define NAND_CS 1
-
 #endif /* __ASM_DB1200_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-db1x00/db1x00.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-db1x00/db1x00.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-db1x00/db1x00.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-db1x00/db1x00.h	2010-05-16 17:17:36.000000000 -0400
@@ -41,111 +41,11 @@
 #define SMBUS_PSC_BASE		PSC2_BASE_ADDR
 #define I2S_PSC_BASE		PSC3_BASE_ADDR
 
-#define BCSR_KSEG1_ADDR 	0xAF000000
 #define NAND_PHYS_ADDR		0x20000000
 
-#else
-#define BCSR_KSEG1_ADDR 0xAE000000
 #endif
 
 /*
- * Overlay data structure of the DBAu1x00 board registers.
- * Registers are located at physical 0E0000xx, KSEG1 0xAE0000xx.
- */
-typedef volatile struct
-{
-	/*00*/	unsigned short whoami;
-	unsigned short reserved0;
-	/*04*/	unsigned short status;
-	unsigned short reserved1;
-	/*08*/	unsigned short switches;
-	unsigned short reserved2;
-	/*0C*/	unsigned short resets;
-	unsigned short reserved3;
-	/*10*/	unsigned short pcmcia;
-	unsigned short reserved4;
-	/*14*/	unsigned short specific;
-	unsigned short reserved5;
-	/*18*/	unsigned short leds;
-	unsigned short reserved6;
-	/*1C*/	unsigned short swreset;
-	unsigned short reserved7;
-
-} BCSR;
-
-
-/*
- * Register/mask bit definitions for the BCSRs
- */
-#define BCSR_WHOAMI_DCID		0x000F
-#define BCSR_WHOAMI_CPLD		0x00F0
-#define BCSR_WHOAMI_BOARD		0x0F00
-
-#define BCSR_STATUS_PC0VS		0x0003
-#define BCSR_STATUS_PC1VS		0x000C
-#define BCSR_STATUS_PC0FI		0x0010
-#define BCSR_STATUS_PC1FI		0x0020
-#define BCSR_STATUS_FLASHBUSY		0x0100
-#define BCSR_STATUS_ROMBUSY		0x0400
-#define BCSR_STATUS_SWAPBOOT		0x2000
-#define BCSR_STATUS_FLASHDEN		0xC000
-
-#define BCSR_SWITCHES_DIP		0x00FF
-#define BCSR_SWITCHES_DIP_1		0x0080
-#define BCSR_SWITCHES_DIP_2		0x0040
-#define BCSR_SWITCHES_DIP_3		0x0020
-#define BCSR_SWITCHES_DIP_4		0x0010
-#define BCSR_SWITCHES_DIP_5		0x0008
-#define BCSR_SWITCHES_DIP_6		0x0004
-#define BCSR_SWITCHES_DIP_7		0x0002
-#define BCSR_SWITCHES_DIP_8		0x0001
-#define BCSR_SWITCHES_ROTARY		0x0F00
-
-#define BCSR_RESETS_PHY0		0x0001
-#define BCSR_RESETS_PHY1		0x0002
-#define BCSR_RESETS_DC			0x0004
-#define BCSR_RESETS_FIR_SEL		0x2000
-#define BCSR_RESETS_IRDA_MODE_MASK	0xC000
-#define BCSR_RESETS_IRDA_MODE_FULL	0x0000
-#define BCSR_RESETS_IRDA_MODE_OFF	0x4000
-#define BCSR_RESETS_IRDA_MODE_2_3	0x8000
-#define BCSR_RESETS_IRDA_MODE_1_3	0xC000
-
-#define BCSR_PCMCIA_PC0VPP		0x0003
-#define BCSR_PCMCIA_PC0VCC		0x000C
-#define BCSR_PCMCIA_PC0DRVEN		0x0010
-#define BCSR_PCMCIA_PC0RST		0x0080
-#define BCSR_PCMCIA_PC1VPP		0x0300
-#define BCSR_PCMCIA_PC1VCC		0x0C00
-#define BCSR_PCMCIA_PC1DRVEN		0x1000
-#define BCSR_PCMCIA_PC1RST		0x8000
-
-#define BCSR_BOARD_PCIM66EN		0x0001
-#define BCSR_BOARD_SD0_PWR		0x0040
-#define BCSR_BOARD_SD1_PWR		0x0080
-#define BCSR_BOARD_PCIM33		0x0100
-#define BCSR_BOARD_GPIO200RST		0x0400
-#define BCSR_BOARD_PCICFG		0x1000
-#define BCSR_BOARD_SD0_WP		0x4000
-#define BCSR_BOARD_SD1_WP		0x8000
-
-#define BCSR_LEDS_DECIMALS		0x0003
-#define BCSR_LEDS_LED0			0x0100
-#define BCSR_LEDS_LED1			0x0200
-#define BCSR_LEDS_LED2			0x0400
-#define BCSR_LEDS_LED3			0x0800
-
-#define BCSR_SWRESET_RESET		0x0080
-
-/* PCMCIA DBAu1x00 specific defines */
-#define PCMCIA_MAX_SOCK  1
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
-
-/* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP, SLOT)\
-	((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
-
-/*
  * NAND defines
  *
  * Timing values as described in databook, * ns value stripped of the
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,7 @@
  * 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 Wu Zhangjin <wuzhangjin@gmail.com>
  * Copyright (C) 2009 Philippe Vachon <philippe@cowpig.ca>
  * Copyright (C) 2009 Zhang Le <r0bertz@gentoo.org>
  *
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  * the read/write interfaces for Virtual Support Module(VSM)
  *
  * Copyright (C) 2009 Lemote, Inc.
- * Author: Wu Zhangjin <wuzj@lemote.com>
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  */
 
 #ifndef	_CS5536_VSM_H
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/loongson.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-loongson/loongson.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/loongson.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-loongson/loongson.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,12 +1,11 @@
 /*
  * Copyright (C) 2009 Lemote, Inc.
- * Author: Wu Zhangjin <wuzj@lemote.com>
+ * Author: Wu Zhangjin <wuzhangjin@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.
- *
  */
 
 #ifndef __ASM_MACH_LOONGSON_LOONGSON_H
@@ -23,7 +22,7 @@ extern void mach_prepare_reboot(void);
 extern void mach_prepare_shutdown(void);
 
 /* environment arguments from bootloader */
-extern unsigned long bus_clock, cpu_clock_freq;
+extern unsigned long cpu_clock_freq;
 extern unsigned long memsize, highmemsize;
 
 /* loongson-specific command line, env and memory initialization */
@@ -308,7 +307,7 @@ extern unsigned long _loongson_addrwincf
  */
 #define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\
 	s##_WIN##w##_BASE = (src); \
-	s##_WIN##w##_MMAP = (src) | ADDRWIN_MAP_DST_##d; \
+	s##_WIN##w##_MMAP = (dst) | ADDRWIN_MAP_DST_##d; \
 	s##_WIN##w##_MASK = ~(size-1); \
 } while (0)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/machine.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-loongson/machine.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/machine.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-loongson/machine.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
- * Author: Wu Zhangjin <wuzj@lemote.com>
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin <wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/mem.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-loongson/mem.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/mem.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-loongson/mem.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2009 Lemote, Inc.
- * Author: Wu Zhangjin <wuzj@lemote.com>
+ * Author: Wu Zhangjin <wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/pci.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-loongson/pci.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-loongson/pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,23 +1,12 @@
 /*
  * Copyright (c) 2008 Zhang Le <r0bertz@gentoo.org>
- * Copyright (c) 2009 Wu Zhangjin <wuzj@lemote.com>
+ * Copyright (c) 2009 Wu Zhangjin <wuzhangjin@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 __ASM_MACH_LOONGSON_PCI_H_
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-pb1x00/pb1100.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-pb1x00/pb1100.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-pb1x00/pb1100.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-pb1x00/pb1100.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,85 +0,0 @@
-/*
- * Alchemy Semi Pb1100 Referrence Board
- *
- * Copyright 2001, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- *
- */
-#ifndef __ASM_PB1100_H
-#define __ASM_PB1100_H
-
-#define PB1100_IDENT		0xAE000000
-#define BOARD_STATUS_REG	0xAE000004
-#  define PB1100_ROM_SEL	(1 << 15)
-#  define PB1100_ROM_SIZ	(1 << 14)
-#  define PB1100_SWAP_BOOT	(1 << 13)
-#  define PB1100_FLASH_WP	(1 << 12)
-#  define PB1100_ROM_H_STS	(1 << 11)
-#  define PB1100_ROM_L_STS	(1 << 10)
-#  define PB1100_FLASH_H_STS	(1 << 9)
-#  define PB1100_FLASH_L_STS	(1 << 8)
-#  define PB1100_SRAM_SIZ	(1 << 7)
-#  define PB1100_TSC_BUSY	(1 << 6)
-#  define PB1100_PCMCIA_VS_MASK (3 << 4)
-#  define PB1100_RS232_CD	(1 << 3)
-#  define PB1100_RS232_CTS	(1 << 2)
-#  define PB1100_RS232_DSR	(1 << 1)
-#  define PB1100_RS232_RI	(1 << 0)
-
-#define PB1100_IRDA_RS232	0xAE00000C
-#  define PB1100_IRDA_FULL	(0 << 14)	/* full power		*/
-#  define PB1100_IRDA_SHUTDOWN	(1 << 14)
-#  define PB1100_IRDA_TT	(2 << 14)	/* 2/3 power		*/
-#  define PB1100_IRDA_OT	(3 << 14)	/* 1/3 power		*/
-#  define PB1100_IRDA_FIR	(1 << 13)
-
-#define PCMCIA_BOARD_REG	0xAE000010
-#  define PB1100_SD_WP1_RO	(1 << 15)	/* read only		*/
-#  define PB1100_SD_WP0_RO	(1 << 14)	/* read only		*/
-#  define PB1100_SD_PWR1	(1 << 11)	/* applies power to SD1 */
-#  define PB1100_SD_PWR0	(1 << 10)	/* applies power to SD0 */
-#  define PB1100_SEL_SD_CONN1	(1 << 9)
-#  define PB1100_SEL_SD_CONN0	(1 << 8)
-#  define PC_DEASSERT_RST	(1 << 7)
-#  define PC_DRV_EN		(1 << 4)
-
-#define PB1100_G_CONTROL	0xAE000014	/* graphics control	*/
-
-#define PB1100_RST_VDDI 	0xAE00001C
-#  define PB1100_SOFT_RESET	(1 << 15)	/* clear to reset the board */
-#  define PB1100_VDDI_MASK	0x1F
-
-#define PB1100_LEDS		0xAE000018
-
-/*
- * 11:8 is 4 discreet LEDs. Clearing a bit illuminates the LED.
- * 7:0  is the LED Display's decimal points.
- */
-#define PB1100_HEX_LED		0xAE000018
-
-/* PCMCIA Pb1100 specific defines */
-#define PCMCIA_MAX_SOCK  0
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
-
-/* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP) (((VCC) << 2) | ((VPP) << 0))
-
-#endif /* __ASM_PB1100_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-pb1x00/pb1200.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-pb1x00/pb1200.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-pb1x00/pb1200.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-pb1x00/pb1200.h	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #define __ASM_PB1200_H
 
 #include <linux/types.h>
+#include <asm/mach-au1x00/au1000.h>
 #include <asm/mach-au1x00/au1xxx_psc.h>
 
 #define DBDMA_AC97_TX_CHAN	DSCR_CMD0_PSC1_TX
@@ -43,113 +44,8 @@
  * Refer to board documentation.
  */
 #define AC97_PSC_BASE       PSC1_BASE_ADDR
-#define I2S_PSC_BASE		PSC1_BASE_ADDR
-
-#define BCSR_KSEG1_ADDR 0xAD800000
-
-typedef volatile struct
-{
-	/*00*/	u16 whoami;
-		u16 reserved0;
-	/*04*/	u16 status;
-		u16 reserved1;
-	/*08*/	u16 switches;
-		u16 reserved2;
-	/*0C*/	u16 resets;
-		u16 reserved3;
-
-	/*10*/	u16 pcmcia;
-		u16 reserved4;
-	/*14*/	u16 board;
-		u16 reserved5;
-	/*18*/	u16 disk_leds;
-		u16 reserved6;
-	/*1C*/	u16 system;
-		u16 reserved7;
-
-	/*20*/	u16 intclr;
-		u16 reserved8;
-	/*24*/	u16 intset;
-		u16 reserved9;
-	/*28*/	u16 intclr_mask;
-		u16 reserved10;
-	/*2C*/	u16 intset_mask;
-		u16 reserved11;
-
-	/*30*/	u16 sig_status;
-		u16 reserved12;
-	/*34*/	u16 int_status;
-		u16 reserved13;
-	/*38*/	u16 reserved14;
-		u16 reserved15;
-	/*3C*/	u16 reserved16;
-		u16 reserved17;
-
-} BCSR;
-
-static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
-
-/*
- * Register bit definitions for the BCSRs
- */
-#define BCSR_WHOAMI_DCID	0x000F
-#define BCSR_WHOAMI_CPLD	0x00F0
-#define BCSR_WHOAMI_BOARD	0x0F00
-
-#define BCSR_STATUS_PCMCIA0VS	0x0003
-#define BCSR_STATUS_PCMCIA1VS	0x000C
-#define BCSR_STATUS_SWAPBOOT	0x0040
-#define BCSR_STATUS_FLASHBUSY	0x0100
-#define BCSR_STATUS_IDECBLID	0x0200
-#define BCSR_STATUS_SD0WP	0x0400
-#define BCSR_STATUS_SD1WP	0x0800
-#define BCSR_STATUS_U0RXD	0x1000
-#define BCSR_STATUS_U1RXD	0x2000
-
-#define BCSR_SWITCHES_OCTAL	0x00FF
-#define BCSR_SWITCHES_DIP_1	0x0080
-#define BCSR_SWITCHES_DIP_2	0x0040
-#define BCSR_SWITCHES_DIP_3	0x0020
-#define BCSR_SWITCHES_DIP_4	0x0010
-#define BCSR_SWITCHES_DIP_5	0x0008
-#define BCSR_SWITCHES_DIP_6	0x0004
-#define BCSR_SWITCHES_DIP_7	0x0002
-#define BCSR_SWITCHES_DIP_8	0x0001
-#define BCSR_SWITCHES_ROTARY	0x0F00
-
-#define BCSR_RESETS_ETH		0x0001
-#define BCSR_RESETS_CAMERA	0x0002
-#define BCSR_RESETS_DC		0x0004
-#define BCSR_RESETS_IDE		0x0008
-/* not resets but in the same register */
-#define BCSR_RESETS_WSCFSM	0x0800
-#define BCSR_RESETS_PCS0MUX	0x1000
-#define BCSR_RESETS_PCS1MUX	0x2000
-#define BCSR_RESETS_SPISEL	0x4000
-#define BCSR_RESETS_SD1MUX	0x8000
-
-#define BCSR_PCMCIA_PC0VPP	0x0003
-#define BCSR_PCMCIA_PC0VCC	0x000C
-#define BCSR_PCMCIA_PC0DRVEN	0x0010
-#define BCSR_PCMCIA_PC0RST	0x0080
-#define BCSR_PCMCIA_PC1VPP	0x0300
-#define BCSR_PCMCIA_PC1VCC	0x0C00
-#define BCSR_PCMCIA_PC1DRVEN	0x1000
-#define BCSR_PCMCIA_PC1RST	0x8000
-
-#define BCSR_BOARD_LCDVEE	0x0001
-#define BCSR_BOARD_LCDVDD	0x0002
-#define BCSR_BOARD_LCDBL	0x0004
-#define BCSR_BOARD_CAMSNAP	0x0010
-#define BCSR_BOARD_CAMPWR	0x0020
-#define BCSR_BOARD_SD0PWR	0x0040
-#define BCSR_BOARD_SD1PWR	0x0080
+#define I2S_PSC_BASE	PSC1_BASE_ADDR
 
-#define BCSR_LEDS_DECIMALS	0x00FF
-#define BCSR_LEDS_LED0		0x0100
-#define BCSR_LEDS_LED1		0x0200
-#define BCSR_LEDS_LED2		0x0400
-#define BCSR_LEDS_LED3		0x0800
 
 #define BCSR_SYSTEM_VDDI	0x001F
 #define BCSR_SYSTEM_POWEROFF	0x4000
@@ -239,20 +135,6 @@ enum external_pb1200_ints {
 	PB1200_INT_END		= PB1200_INT_BEGIN + 15
 };
 
-/*
- * Pb1200 specific PCMCIA defines for drivers/pcmcia/au1000_db1x00.c
- */
-#define PCMCIA_MAX_SOCK  1
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
-
-/* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP, SLOT) \
-	((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
-
-#define BOARD_PC0_INT	PB1200_PC0_INT
-#define BOARD_PC1_INT	PB1200_PC1_INT
-#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1 << (8 + (2 * SOCKET)))
-
 /* NAND chip select */
 #define NAND_CS 1
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-pb1x00/pb1500.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-pb1x00/pb1500.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-pb1x00/pb1500.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-pb1x00/pb1500.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-/*
- * Alchemy Semi Pb1500 Referrence Board
- *
- * Copyright 2001, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- *
- */
-#ifndef __ASM_PB1500_H
-#define __ASM_PB1500_H
-
-#define IDENT_BOARD_REG 	0xAE000000
-#define BOARD_STATUS_REG	0xAE000004
-#define PCI_BOARD_REG		0xAE000010
-#define PCMCIA_BOARD_REG	0xAE000010
-#  define PC_DEASSERT_RST	      0x80
-#  define PC_DRV_EN		      0x10
-#define PB1500_G_CONTROL	0xAE000014
-#define PB1500_RST_VDDI 	0xAE00001C
-#define PB1500_LEDS		0xAE000018
-
-#define PB1500_HEX_LED		0xAF000004
-#define PB1500_HEX_LED_BLANK	0xAF000008
-
-/* PCMCIA Pb1500 specific defines */
-#define PCMCIA_MAX_SOCK  0
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
-
-/* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP) (((VCC) << 2) | ((VPP) << 0))
-
-#endif /* __ASM_PB1500_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-pb1x00/pb1550.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-pb1x00/pb1550.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-pb1x00/pb1550.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-pb1x00/pb1550.h	2010-05-16 17:17:36.000000000 -0400
@@ -40,102 +40,6 @@
 #define SMBUS_PSC_BASE		PSC2_BASE_ADDR
 #define I2S_PSC_BASE		PSC3_BASE_ADDR
 
-#define BCSR_PHYS_ADDR 0xAF000000
-
-typedef volatile struct
-{
-	/*00*/	u16 whoami;
-		u16 reserved0;
-	/*04*/	u16 status;
-		u16 reserved1;
-	/*08*/	u16 switches;
-		u16 reserved2;
-	/*0C*/	u16 resets;
-		u16 reserved3;
-	/*10*/	u16 pcmcia;
-		u16 reserved4;
-	/*14*/	u16 pci;
-		u16 reserved5;
-	/*18*/	u16 leds;
-		u16 reserved6;
-	/*1C*/	u16 system;
-		u16 reserved7;
-
-} BCSR;
-
-static BCSR * const bcsr = (BCSR *)BCSR_PHYS_ADDR;
-
-/*
- * Register bit definitions for the BCSRs
- */
-#define BCSR_WHOAMI_DCID	0x000F
-#define BCSR_WHOAMI_CPLD	0x00F0
-#define BCSR_WHOAMI_BOARD	0x0F00
-
-#define BCSR_STATUS_PCMCIA0VS	0x0003
-#define BCSR_STATUS_PCMCIA1VS	0x000C
-#define BCSR_STATUS_PCMCIA0FI	0x0010
-#define BCSR_STATUS_PCMCIA1FI	0x0020
-#define BCSR_STATUS_SWAPBOOT	0x0040
-#define BCSR_STATUS_SRAMWIDTH	0x0080
-#define BCSR_STATUS_FLASHBUSY	0x0100
-#define BCSR_STATUS_ROMBUSY	0x0200
-#define BCSR_STATUS_USBOTGID	0x0800
-#define BCSR_STATUS_U0RXD	0x1000
-#define BCSR_STATUS_U1RXD	0x2000
-#define BCSR_STATUS_U3RXD	0x8000
-
-#define BCSR_SWITCHES_OCTAL	0x00FF
-#define BCSR_SWITCHES_DIP_1	0x0080
-#define BCSR_SWITCHES_DIP_2	0x0040
-#define BCSR_SWITCHES_DIP_3	0x0020
-#define BCSR_SWITCHES_DIP_4	0x0010
-#define BCSR_SWITCHES_DIP_5	0x0008
-#define BCSR_SWITCHES_DIP_6	0x0004
-#define BCSR_SWITCHES_DIP_7	0x0002
-#define BCSR_SWITCHES_DIP_8	0x0001
-#define BCSR_SWITCHES_ROTARY	0x0F00
-
-#define BCSR_RESETS_PHY0	0x0001
-#define BCSR_RESETS_PHY1	0x0002
-#define BCSR_RESETS_DC		0x0004
-#define BCSR_RESETS_WSC		0x2000
-#define BCSR_RESETS_SPISEL	0x4000
-#define BCSR_RESETS_DMAREQ	0x8000
-
-#define BCSR_PCMCIA_PC0VPP	0x0003
-#define BCSR_PCMCIA_PC0VCC	0x000C
-#define BCSR_PCMCIA_PC0DRVEN	0x0010
-#define BCSR_PCMCIA_PC0RST	0x0080
-#define BCSR_PCMCIA_PC1VPP	0x0300
-#define BCSR_PCMCIA_PC1VCC	0x0C00
-#define BCSR_PCMCIA_PC1DRVEN	0x1000
-#define BCSR_PCMCIA_PC1RST	0x8000
-
-#define BCSR_PCI_M66EN		0x0001
-#define BCSR_PCI_M33		0x0100
-#define BCSR_PCI_EXTERNARB	0x0200
-#define BCSR_PCI_GPIO200RST	0x0400
-#define BCSR_PCI_CLKOUT		0x0800
-#define BCSR_PCI_CFGHOST	0x1000
-
-#define BCSR_LEDS_DECIMALS	0x00FF
-#define BCSR_LEDS_LED0		0x0100
-#define BCSR_LEDS_LED1		0x0200
-#define BCSR_LEDS_LED2		0x0400
-#define BCSR_LEDS_LED3		0x0800
-
-#define BCSR_SYSTEM_VDDI	0x001F
-#define BCSR_SYSTEM_POWEROFF	0x4000
-#define BCSR_SYSTEM_RESET	0x8000
-
-#define PCMCIA_MAX_SOCK  1
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
-
-/* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP, SLOT) \
-	((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
-
 #if defined(CONFIG_MTD_PB1550_BOOT) && defined(CONFIG_MTD_PB1550_USER)
 #define PB1550_BOTH_BANKS
 #elif defined(CONFIG_MTD_PB1550_BOOT) && !defined(CONFIG_MTD_PB1550_USER)
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-pnx833x/irq-mapping.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-pnx833x/irq-mapping.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-pnx833x/irq-mapping.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-pnx833x/irq-mapping.h	2010-05-16 17:17:36.000000000 -0400
@@ -123,4 +123,3 @@
 #define PNX833X_GPIO_15_INT			(PNX833X_GPIO_IRQ_BASE + 15)
 
 #endif
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/interrupts.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-powertv/interrupts.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/interrupts.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-powertv/interrupts.h	2010-05-16 17:17:36.000000000 -0400
@@ -251,4 +251,3 @@
 						 * channel 3. */
 #define irq_mpeg_d		(ibase+0) 	/* MPEG Decoder Interrupt */
 #endif	/* _ASM_MACH_POWERTV_INTERRUPTS_H_ */
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-sibyte/war.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-sibyte/war.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-sibyte/war.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mach-sibyte/war.h	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,11 @@
 #if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \
     defined(CONFIG_SB1_PASS_2_WORKAROUNDS)
 
-#define BCM1250_M3_WAR	1
+#ifndef __ASSEMBLY__
+extern int sb1250_m3_workaround_needed(void);
+#endif
+
+#define BCM1250_M3_WAR	sb1250_m3_workaround_needed()
 #define SIBYTE_1956_WAR	1
 
 #else
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mipsregs.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mipsregs.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mipsregs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mipsregs.h	2010-05-16 17:17:36.000000000 -0400
@@ -135,6 +135,12 @@
 #define FPU_CSR_COND7   0x80000000      /* $fcc7 */
 
 /*
+ * Bits 18 - 20 of the FPU Status Register will be read as 0,
+ * and should be written as zero.
+ */
+#define FPU_CSR_RSVD	0x001c0000
+
+/*
  * X the exception cause indicator
  * E the exception enable
  * S the sticky/flag bit
@@ -161,7 +167,8 @@
 #define FPU_CSR_UDF_S   0x00000008
 #define FPU_CSR_INE_S   0x00000004
 
-/* rounding mode */
+/* Bits 0 and 1 of FPU Status Register specify the rounding mode */
+#define FPU_CSR_RM	0x00000003
 #define FPU_CSR_RN      0x0     /* nearest */
 #define FPU_CSR_RZ      0x1     /* towards zero */
 #define FPU_CSR_RU      0x2     /* towards +Infinity */
@@ -251,6 +258,14 @@
 #define PL_256M		28
 
 /*
+ * PageGrain bits
+ */
+#define PG_RIE		(_ULCAST_(1) <<  31)
+#define PG_XIE		(_ULCAST_(1) <<  30)
+#define PG_ELPA		(_ULCAST_(1) <<  29)
+#define PG_ESP		(_ULCAST_(1) <<  28)
+
+/*
  * R4x00 interrupt enable / cause bits
  */
 #define IE_SW0          (_ULCAST_(1) <<  8)
@@ -576,6 +591,10 @@
 #define MIPS_CONF3_DSP		(_ULCAST_(1) << 10)
 #define MIPS_CONF3_ULRI		(_ULCAST_(1) << 13)
 
+#define MIPS_CONF4_MMUSIZEEXT	(_ULCAST_(255) << 0)
+#define MIPS_CONF4_MMUEXTDEF	(_ULCAST_(3) << 14)
+#define MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT (_ULCAST_(1) << 14)
+
 #define MIPS_CONF7_WII		(_ULCAST_(1) << 31)
 
 #define MIPS_CONF7_RPS		(_ULCAST_(1) << 2)
@@ -826,6 +845,9 @@ do {									\
 #define read_c0_pagemask()	__read_32bit_c0_register($5, 0)
 #define write_c0_pagemask(val)	__write_32bit_c0_register($5, 0, val)
 
+#define read_c0_pagegrain()	__read_32bit_c0_register($5, 1)
+#define write_c0_pagegrain(val)	__write_32bit_c0_register($5, 1, val)
+
 #define read_c0_wired()		__read_32bit_c0_register($6, 0)
 #define write_c0_wired(val)	__write_32bit_c0_register($6, 0, val)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mmu_context.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mmu_context.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mmu_context.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mmu_context.h	2010-05-16 17:17:36.000000000 -0400
@@ -104,7 +104,7 @@ extern unsigned long smtc_asid_mask;
 
 #endif
 
-#define cpu_context(cpu, mm)	((mm)->context[cpu])
+#define cpu_context(cpu, mm)	((mm)->context.asid[cpu])
 #define cpu_asid(cpu, mm)	(cpu_context((cpu), (mm)) & ASID_MASK)
 #define asid_cache(cpu)		(cpu_data[cpu].asid_cache)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/mmu.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/mmu.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/mmu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/mmu.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,9 @@
 #ifndef __ASM_MMU_H
 #define __ASM_MMU_H
 
-typedef unsigned long mm_context_t[NR_CPUS];
+typedef struct {
+	unsigned long asid[NR_CPUS];
+	void *vdso;
+} mm_context_t;
 
 #endif /* __ASM_MMU_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/msc01_ic.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/msc01_ic.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/msc01_ic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/msc01_ic.h	2010-05-16 17:17:36.000000000 -0400
@@ -145,4 +145,3 @@ extern void __init init_msc_irqs(unsigne
 extern void ll_msc_irq(void);
 
 #endif /* __ASM_MIPS_BOARDS_MSC01_IC_H */
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/nile4.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/nile4.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/nile4.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/nile4.h	2010-05-16 17:17:36.000000000 -0400
@@ -307,4 +307,3 @@ extern u8 nile4_i8259_iack(void);
 extern void nile4_dump_irq_status(void);	/* Debug */
 
 #endif
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/octeon/octeon-feature.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/octeon/octeon-feature.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/octeon/octeon-feature.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/octeon/octeon-feature.h	2010-05-16 17:17:36.000000000 -0400
@@ -99,6 +99,8 @@ static inline int octeon_has_feature(enu
 		return !cvmx_fuse_read(90);
 
 	case OCTEON_FEATURE_PCIE:
+	case OCTEON_FEATURE_MGMT_PORT:
+	case OCTEON_FEATURE_RAID:
 		return OCTEON_IS_MODEL(OCTEON_CN56XX)
 			|| OCTEON_IS_MODEL(OCTEON_CN52XX);
 
@@ -110,12 +112,6 @@ static inline int octeon_has_feature(enu
 	case OCTEON_FEATURE_TRA:
 		return !(OCTEON_IS_MODEL(OCTEON_CN30XX)
 			 || OCTEON_IS_MODEL(OCTEON_CN50XX));
-	case OCTEON_FEATURE_MGMT_PORT:
-		return OCTEON_IS_MODEL(OCTEON_CN56XX)
-			|| OCTEON_IS_MODEL(OCTEON_CN52XX);
-	case OCTEON_FEATURE_RAID:
-		return OCTEON_IS_MODEL(OCTEON_CN56XX)
-			|| OCTEON_IS_MODEL(OCTEON_CN52XX);
 	case OCTEON_FEATURE_USB:
 		return !(OCTEON_IS_MODEL(OCTEON_CN38XX)
 			 || OCTEON_IS_MODEL(OCTEON_CN58XX));
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/octeon/octeon.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/octeon/octeon.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/octeon/octeon.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/octeon/octeon.h	2010-05-16 17:17:36.000000000 -0400
@@ -213,6 +213,11 @@ struct octeon_cf_data {
 	int		dma_engine;	/* -1 for no DMA */
 };
 
+struct octeon_i2c_data {
+	unsigned int	sys_freq;
+	unsigned int	i2c_freq;
+};
+
 extern void octeon_write_lcd(const char *s);
 extern void octeon_check_cpu_bist(void);
 extern int octeon_get_boot_debug_flag(void);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/page.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/page.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/page.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/page.h	2010-05-16 17:17:36.000000000 -0400
@@ -107,18 +107,6 @@ typedef struct { unsigned long pte; } pt
 typedef struct page *pgtable_t;
 
 /*
- * For 3-level pagetables we defines these ourselves, for 2-level the
- * definitions are supplied by <asm-generic/pgtable-nopmd.h>.
- */
-#ifdef CONFIG_64BIT
-
-typedef struct { unsigned long pmd; } pmd_t;
-#define pmd_val(x)	((x).pmd)
-#define __pmd(x)	((pmd_t) { (x) } )
-
-#endif
-
-/*
  * Right now we don't support 4-level pagetables, so all pud-related
  * definitions come from <asm-generic/pgtable-nopud.h>.
  */
@@ -200,8 +188,10 @@ typedef struct { unsigned long pgprot; }
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
-#define UNCAC_ADDR(addr)	((addr) - PAGE_OFFSET + UNCAC_BASE)
-#define CAC_ADDR(addr)		((addr) - UNCAC_BASE + PAGE_OFFSET)
+#define UNCAC_ADDR(addr)	((addr) - PAGE_OFFSET + UNCAC_BASE + 	\
+								PHYS_OFFSET)
+#define CAC_ADDR(addr)		((addr) - UNCAC_BASE + PAGE_OFFSET -	\
+								PHYS_OFFSET)
 
 #include <asm-generic/memory_model.h>
 #include <asm-generic/getorder.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/param.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/param.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/param.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/param.h	2010-05-16 17:17:36.000000000 -0400
@@ -9,23 +9,8 @@
 #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	65536
 
-#ifndef NOGROUP
-#define NOGROUP		(-1)
-#endif
-
-#define MAXHOSTNAMELEN	64	/* max length of hostname */
+#include <asm-generic/param.h>
 
 #endif /* _ASM_PARAM_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/parport.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/parport.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/parport.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/parport.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,15 +1 @@
-/*
- * Copyright (C) 1999, 2000  Tim Waugh <tim@cyberelk.demon.co.uk>
- *
- * This file should only be included by drivers/parport/parport_pc.c.
- */
-#ifndef _ASM_PARPORT_H
-#define _ASM_PARPORT_H
-
-static int __devinit parport_pc_find_isa_ports(int autoirq, int autodma);
-static int __devinit parport_pc_find_nonpci_ports(int autoirq, int autodma)
-{
-	return parport_pc_find_isa_ports(autoirq, autodma);
-}
-
-#endif /* _ASM_PARPORT_H */
+#include <asm-generic/parport.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/pci.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/pci.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -102,28 +102,6 @@ struct pci_dev;
  */
 extern unsigned int PCI_DMA_BUS_IS_PHYS;
 
-#ifdef CONFIG_DMA_NEED_PCI_MAP_STATE
-
-/* pci_unmap_{single,page} is not a nop, thus... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)		__u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME)		((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)	(((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME)		((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL)	(((PTR)->LEN_NAME) = (VAL))
-
-#else /* CONFIG_DMA_NEED_PCI_MAP_STATE  */
-
-/* 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)
-
-#endif /* CONFIG_DMA_NEED_PCI_MAP_STATE  */
-
 #ifdef CONFIG_PCI
 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 					enum pci_dma_burst_strategy *strat,
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/pgalloc.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/pgalloc.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/pgalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/pgalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,7 @@ static inline void pmd_populate(struct m
  */
 extern void pmd_init(unsigned long page, unsigned long pagetable);
 
-#ifdef CONFIG_64BIT
+#ifndef __PAGETABLE_PMD_FOLDED
 
 static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
 {
@@ -104,7 +104,7 @@ do {							\
 	tlb_remove_page((tlb), pte);			\
 } while (0)
 
-#ifdef CONFIG_64BIT
+#ifndef __PAGETABLE_PMD_FOLDED
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/pgtable-32.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/pgtable-32.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/pgtable-32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/pgtable-32.h	2010-05-16 17:17:36.000000000 -0400
@@ -127,8 +127,8 @@ pfn_pte(unsigned long pfn, pgprot_t prot
 #define pte_pfn(x)		((unsigned long)((x).pte >> (PAGE_SHIFT + 2)))
 #define pfn_pte(pfn, prot)	__pte(((pfn) << (PAGE_SHIFT + 2)) | pgprot_val(prot))
 #else
-#define pte_pfn(x)		((unsigned long)((x).pte >> PAGE_SHIFT))
-#define pfn_pte(pfn, prot)	__pte(((unsigned long long)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#define pte_pfn(x)		((unsigned long)((x).pte >> _PFN_SHIFT))
+#define pfn_pte(pfn, prot)	__pte(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot))
 #endif
 #endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/pgtable-64.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/pgtable-64.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/pgtable-64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/pgtable-64.h	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,11 @@
 #include <asm/cachectl.h>
 #include <asm/fixmap.h>
 
+#ifdef CONFIG_PAGE_SIZE_64KB
+#include <asm-generic/pgtable-nopmd.h>
+#else
 #include <asm-generic/pgtable-nopud.h>
+#endif
 
 /*
  * Each address space has 2 4K pages as its page directory, giving 1024
@@ -37,13 +41,20 @@
  * fault address - VMALLOC_START.
  */
 
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#ifdef __PAGETABLE_PMD_FOLDED
+#define PGDIR_SHIFT	(PAGE_SHIFT + PAGE_SHIFT + PTE_ORDER - 3)
+#else
+
 /* PMD_SHIFT determines the size of the area a second-level page table can map */
 #define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT + PTE_ORDER - 3))
 #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 + (PAGE_SHIFT + PMD_ORDER - 3))
+#endif
 #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
@@ -92,12 +103,14 @@
 #ifdef CONFIG_PAGE_SIZE_64KB
 #define PGD_ORDER		0
 #define PUD_ORDER		aieeee_attempt_to_allocate_pud
-#define PMD_ORDER		0
+#define PMD_ORDER		aieeee_attempt_to_allocate_pmd
 #define PTE_ORDER		0
 #endif
 
 #define PTRS_PER_PGD	((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t))
+#ifndef __PAGETABLE_PMD_FOLDED
 #define PTRS_PER_PMD	((PAGE_SIZE << PMD_ORDER) / sizeof(pmd_t))
+#endif
 #define PTRS_PER_PTE	((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
 
 #if PGDIR_SIZE >= TASK_SIZE
@@ -107,9 +120,14 @@
 #endif
 #define FIRST_USER_ADDRESS	0UL
 
-#define VMALLOC_START		MAP_BASE
+/*
+ * TLB refill handlers also map the vmalloc area into xuseg.  Avoid
+ * the first couple of pages so NULL pointer dereferences will still
+ * reliably trap.
+ */
+#define VMALLOC_START		(MAP_BASE + (2 * PAGE_SIZE))
 #define VMALLOC_END	\
-	(VMALLOC_START + \
+	(MAP_BASE + \
 	 min(PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, \
 	     (1UL << cpu_vmbits)) - (1UL << 32))
 
@@ -122,15 +140,30 @@
 
 #define pte_ERROR(e) \
 	printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
+#ifndef __PAGETABLE_PMD_FOLDED
 #define pmd_ERROR(e) \
 	printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
+#endif
 #define pgd_ERROR(e) \
 	printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
 
 extern pte_t invalid_pte_table[PTRS_PER_PTE];
 extern pte_t empty_bad_page_table[PTRS_PER_PTE];
+
+
+#ifndef __PAGETABLE_PMD_FOLDED
+/*
+ * For 3-level pagetables we defines these ourselves, for 2-level the
+ * definitions are supplied by <asm-generic/pgtable-nopmd.h>.
+ */
+typedef struct { unsigned long pmd; } pmd_t;
+#define pmd_val(x)	((x).pmd)
+#define __pmd(x)	((pmd_t) { (x) } )
+
+
 extern pmd_t invalid_pmd_table[PTRS_PER_PMD];
 extern pmd_t empty_bad_pmd_table[PTRS_PER_PMD];
+#endif
 
 /*
  * Empty pgd/pmd entries point to the invalid_pte_table.
@@ -151,6 +184,7 @@ static inline void pmd_clear(pmd_t *pmdp
 {
 	pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
 }
+#ifndef __PAGETABLE_PMD_FOLDED
 
 /*
  * Empty pud entries point to the invalid_pmd_table.
@@ -174,6 +208,7 @@ static inline void pud_clear(pud_t *pudp
 {
 	pud_val(*pudp) = ((unsigned long) invalid_pmd_table);
 }
+#endif
 
 #define pte_page(x)		pfn_to_page(pte_pfn(x))
 
@@ -181,8 +216,8 @@ static inline void pud_clear(pud_t *pudp
 #define pte_pfn(x)		((unsigned long)((x).pte >> (PAGE_SHIFT + 2)))
 #define pfn_pte(pfn, prot)	__pte(((pfn) << (PAGE_SHIFT + 2)) | pgprot_val(prot))
 #else
-#define pte_pfn(x)		((unsigned long)((x).pte >> PAGE_SHIFT))
-#define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#define pte_pfn(x)		((unsigned long)((x).pte >> _PFN_SHIFT))
+#define pfn_pte(pfn, prot)	__pte(((pfn) << _PFN_SHIFT) | pgprot_val(prot))
 #endif
 
 #define __pgd_offset(address)	pgd_index(address)
@@ -198,6 +233,7 @@ static inline void pud_clear(pud_t *pudp
 /* to find an entry in a page-table-directory */
 #define pgd_offset(mm, addr)	((mm)->pgd + pgd_index(addr))
 
+#ifndef __PAGETABLE_PMD_FOLDED
 static inline unsigned long pud_page_vaddr(pud_t pud)
 {
 	return pud_val(pud);
@@ -210,6 +246,7 @@ static inline pmd_t *pmd_offset(pud_t *
 {
 	return (pmd_t *) pud_page_vaddr(*pud) + pmd_index(address);
 }
+#endif
 
 /* Find an entry in the third-level page table.. */
 #define __pte_offset(address)						\
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/pgtable-bits.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/pgtable-bits.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/pgtable-bits.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/pgtable-bits.h	2010-05-16 17:17:36.000000000 -0400
@@ -50,7 +50,7 @@
 #define _CACHE_SHIFT                3
 #define _CACHE_MASK                 (7<<3)
 
-#else
+#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 
 #define _PAGE_PRESENT               (1<<0)  /* implemented in software */
 #define _PAGE_READ                  (1<<1)  /* implemented in software */
@@ -59,8 +59,6 @@
 #define _PAGE_MODIFIED              (1<<4)  /* implemented in software */
 #define _PAGE_FILE                  (1<<4)  /* set:pagecache unset:swap */
 
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
-
 #define _PAGE_GLOBAL                (1<<8)
 #define _PAGE_VALID                 (1<<9)
 #define _PAGE_SILENT_READ           (1<<9)  /* synonym                 */
@@ -69,21 +67,113 @@
 #define _CACHE_UNCACHED             (1<<11)
 #define _CACHE_MASK                 (1<<11)
 
-#else
+#else /* 'Normal' r4K case */
+/*
+ * When using the RI/XI bit support, we have 13 bits of flags below
+ * the physical address. The RI/XI bits are placed such that a SRL 5
+ * can strip off the software bits, then a ROTR 2 can move the RI/XI
+ * into bits [63:62]. This also limits physical address to 56 bits,
+ * which is more than we need right now.
+ */
 
-#define _PAGE_R4KBUG                (1<<5)  /* workaround for r4k bug  */
-#define _PAGE_HUGE                  (1<<5)  /* huge tlb page */
-#define _PAGE_GLOBAL                (1<<6)
-#define _PAGE_VALID                 (1<<7)
-#define _PAGE_SILENT_READ           (1<<7)  /* synonym                 */
-#define _PAGE_DIRTY                 (1<<8)  /* The MIPS dirty bit      */
-#define _PAGE_SILENT_WRITE          (1<<8)
-#define _CACHE_SHIFT		    9
-#define _CACHE_MASK                 (7<<9)
+/* implemented in software */
+#define _PAGE_PRESENT_SHIFT	(0)
+#define _PAGE_PRESENT		(1 << _PAGE_PRESENT_SHIFT)
+/* implemented in software, should be unused if kernel_uses_smartmips_rixi. */
+#define _PAGE_READ_SHIFT	(kernel_uses_smartmips_rixi ? _PAGE_PRESENT_SHIFT : _PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_READ ({if (kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_READ_SHIFT; })
+/* implemented in software */
+#define _PAGE_WRITE_SHIFT	(_PAGE_READ_SHIFT + 1)
+#define _PAGE_WRITE		(1 << _PAGE_WRITE_SHIFT)
+/* implemented in software */
+#define _PAGE_ACCESSED_SHIFT	(_PAGE_WRITE_SHIFT + 1)
+#define _PAGE_ACCESSED		(1 << _PAGE_ACCESSED_SHIFT)
+/* implemented in software */
+#define _PAGE_MODIFIED_SHIFT	(_PAGE_ACCESSED_SHIFT + 1)
+#define _PAGE_MODIFIED		(1 << _PAGE_MODIFIED_SHIFT)
+/* set:pagecache unset:swap */
+#define _PAGE_FILE		(_PAGE_MODIFIED)
 
+#ifdef CONFIG_HUGETLB_PAGE
+/* huge tlb page */
+#define _PAGE_HUGE_SHIFT	(_PAGE_MODIFIED_SHIFT + 1)
+#define _PAGE_HUGE		(1 << _PAGE_HUGE_SHIFT)
+#else
+#define _PAGE_HUGE_SHIFT	(_PAGE_MODIFIED_SHIFT)
+#define _PAGE_HUGE		({BUG(); 1; })  /* Dummy value */
 #endif
+
+/* Page cannot be executed */
+#define _PAGE_NO_EXEC_SHIFT	(kernel_uses_smartmips_rixi ? _PAGE_HUGE_SHIFT + 1 : _PAGE_HUGE_SHIFT)
+#define _PAGE_NO_EXEC		({if (!kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_NO_EXEC_SHIFT; })
+
+/* Page cannot be read */
+#define _PAGE_NO_READ_SHIFT	(kernel_uses_smartmips_rixi ? _PAGE_NO_EXEC_SHIFT + 1 : _PAGE_NO_EXEC_SHIFT)
+#define _PAGE_NO_READ		({if (!kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_NO_READ_SHIFT; })
+
+#define _PAGE_GLOBAL_SHIFT	(_PAGE_NO_READ_SHIFT + 1)
+#define _PAGE_GLOBAL		(1 << _PAGE_GLOBAL_SHIFT)
+
+#define _PAGE_VALID_SHIFT	(_PAGE_GLOBAL_SHIFT + 1)
+#define _PAGE_VALID		(1 << _PAGE_VALID_SHIFT)
+/* synonym                 */
+#define _PAGE_SILENT_READ	(_PAGE_VALID)
+
+/* The MIPS dirty bit      */
+#define _PAGE_DIRTY_SHIFT	(_PAGE_VALID_SHIFT + 1)
+#define _PAGE_DIRTY		(1 << _PAGE_DIRTY_SHIFT)
+#define _PAGE_SILENT_WRITE	(_PAGE_DIRTY)
+
+#define _CACHE_SHIFT		(_PAGE_DIRTY_SHIFT + 1)
+#define _CACHE_MASK		(7 << _CACHE_SHIFT)
+
+#define _PFN_SHIFT		(PAGE_SHIFT - 12 + _CACHE_SHIFT + 3)
+
 #endif /* defined(CONFIG_64BIT_PHYS_ADDR && defined(CONFIG_CPU_MIPS32) */
 
+#ifndef _PFN_SHIFT
+#define _PFN_SHIFT                  PAGE_SHIFT
+#endif
+#define _PFN_MASK		(~((1 << (_PFN_SHIFT)) - 1))
+
+#ifndef _PAGE_NO_READ
+#define _PAGE_NO_READ ({BUG(); 0; })
+#define _PAGE_NO_READ_SHIFT ({BUG(); 0; })
+#endif
+#ifndef _PAGE_NO_EXEC
+#define _PAGE_NO_EXEC ({BUG(); 0; })
+#endif
+#ifndef _PAGE_GLOBAL_SHIFT
+#define _PAGE_GLOBAL_SHIFT ilog2(_PAGE_GLOBAL)
+#endif
+
+
+#ifndef __ASSEMBLY__
+/*
+ * pte_to_entrylo converts a page table entry (PTE) into a Mips
+ * entrylo0/1 value.
+ */
+static inline uint64_t pte_to_entrylo(unsigned long pte_val)
+{
+	if (kernel_uses_smartmips_rixi) {
+		int sa;
+#ifdef CONFIG_32BIT
+		sa = 31 - _PAGE_NO_READ_SHIFT;
+#else
+		sa = 63 - _PAGE_NO_READ_SHIFT;
+#endif
+		/*
+		 * C has no way to express that this is a DSRL
+		 * _PAGE_NO_EXEC_SHIFT followed by a ROTR 2.  Luckily
+		 * in the fast path this is done in assembly
+		 */
+		return (pte_val >> _PAGE_GLOBAL_SHIFT) |
+			((pte_val & (_PAGE_NO_EXEC | _PAGE_NO_READ)) << sa);
+	}
+
+	return pte_val >> _PAGE_GLOBAL_SHIFT;
+}
+#endif
 
 /*
  * Cache attributes
@@ -130,9 +220,9 @@
 
 #endif
 
-#define __READABLE	(_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
+#define __READABLE	(_PAGE_SILENT_READ | _PAGE_ACCESSED | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ))
 #define __WRITEABLE	(_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
 
-#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK)
+#define _PAGE_CHG_MASK  (_PFN_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK)
 
 #endif /* _ASM_PGTABLE_BITS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/pgtable.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/pgtable.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,23 +22,24 @@ struct mm_struct;
 struct vm_area_struct;
 
 #define PAGE_NONE	__pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
-#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
-				 _page_cachable_default)
-#define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_READ | \
+#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | \
 				 _page_cachable_default)
-#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_READ | \
+#define PAGE_COPY	__pgprot(_PAGE_PRESENT | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | \
+				 (kernel_uses_smartmips_rixi ?  _PAGE_NO_EXEC : 0) | _page_cachable_default)
+#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | \
 				 _page_cachable_default)
 #define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
 				 _PAGE_GLOBAL | _page_cachable_default)
-#define PAGE_USERIO	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
+#define PAGE_USERIO	__pgprot(_PAGE_PRESENT | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | _PAGE_WRITE | \
 				 _page_cachable_default)
 #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
 			__WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
 
 /*
- * MIPS can't do page protection for execute, and considers that the same like
- * read. Also, write permissions imply read permissions. This is the closest
- * we can get by reasonable means..
+ * If _PAGE_NO_EXEC is not defined, we can't do page protection for
+ * execute, and consider it to be the same as read. Also, write
+ * permissions imply read permissions. This is the closest we can get
+ * by reasonable means..
  */
 
 /*
@@ -177,7 +178,7 @@ static inline void pte_clear(struct mm_s
  */
 #define set_pmd(pmdptr, pmdval) do { *(pmdptr) = (pmdval); } while(0)
 
-#ifdef CONFIG_64BIT
+#ifndef __PAGETABLE_PMD_FOLDED
 /*
  * (puds are folded into pgds so this doesn't get actually called,
  * but the define is needed for a generic inline function.)
@@ -298,8 +299,13 @@ static inline pte_t pte_mkdirty(pte_t pt
 static inline pte_t pte_mkyoung(pte_t pte)
 {
 	pte_val(pte) |= _PAGE_ACCESSED;
-	if (pte_val(pte) & _PAGE_READ)
-		pte_val(pte) |= _PAGE_SILENT_READ;
+	if (kernel_uses_smartmips_rixi) {
+		if (!(pte_val(pte) & _PAGE_NO_READ))
+			pte_val(pte) |= _PAGE_SILENT_READ;
+	} else {
+		if (pte_val(pte) & _PAGE_READ)
+			pte_val(pte) |= _PAGE_SILENT_READ;
+	}
 	return pte;
 }
 
@@ -362,8 +368,9 @@ extern void __update_cache(struct vm_are
 	pte_t pte);
 
 static inline void update_mmu_cache(struct vm_area_struct *vma,
-	unsigned long address, pte_t pte)
+	unsigned long address, pte_t *ptep)
 {
+	pte_t pte = *ptep;
 	__update_tlb(vma, address, pte);
 	__update_cache(vma, address, pte);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h	2010-05-16 17:17:36.000000000 -0400
@@ -118,7 +118,6 @@
 #define ZSP_DUET		'D'	/* one DUET zsp engine */
 #define ZSP_TRIAD		'T'	/* two TRIAD zsp engines */
 
-extern char *prom_getcmdline(void);
 extern char *prom_getenv(char *name);
 extern void prom_init_cmdline(void);
 extern void prom_meminit(void);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/processor.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/processor.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/processor.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/processor.h	2010-05-16 17:17:36.000000000 -0400
@@ -33,13 +33,19 @@ extern void (*cpu_wait)(void);
 
 extern unsigned int vced_count, vcei_count;
 
+/*
+ * A special page (the vdso) is mapped into all processes at the very
+ * top of the virtual memory space.
+ */
+#define SPECIAL_PAGES_SIZE PAGE_SIZE
+
 #ifdef CONFIG_32BIT
 /*
  * User space process size: 2GB. This is hardcoded into a few places,
  * so don't change it unless you know what you are doing.
  */
 #define TASK_SIZE	0x7fff8000UL
-#define STACK_TOP	TASK_SIZE
+#define STACK_TOP	((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
 
 /*
  * This decides where the kernel will search for a free chunk of vm
@@ -59,7 +65,8 @@ extern unsigned int vced_count, vcei_cou
 #define TASK_SIZE32	0x7fff8000UL
 #define TASK_SIZE	0x10000000000UL
 #define STACK_TOP	\
-      (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
+	(((test_thread_flag(TIF_32BIT_ADDR) ?				\
+	   TASK_SIZE32 : TASK_SIZE) & PAGE_MASK) - SPECIAL_PAGES_SIZE)
 
 /*
  * This decides where the kernel will search for a free chunk of vm
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -142,9 +142,9 @@ extern int ptrace_set_watch_regs(struct
 
 extern asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit);
 
-extern NORET_TYPE void die(const char *, const struct pt_regs *) ATTRIB_NORET;
+extern NORET_TYPE void die(const char *, struct pt_regs *) ATTRIB_NORET;
 
-static inline void die_if_kernel(const char *str, const struct pt_regs *regs)
+static inline void die_if_kernel(const char *str, struct pt_regs *regs)
 {
 	if (unlikely(!user_mode(regs)))
 		die(str, regs);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/serial.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/serial.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/serial.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/serial.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,22 +1 @@
-/*
- * 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 by Ralf Baechle
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
- */
-#ifndef _ASM_SERIAL_H
-#define _ASM_SERIAL_H
-
-
-/*
- * This assumes you have a 1.8432 MHz clock for your UART.
- *
- * It'd be nice if someone built a serial card with a 24.576 MHz
- * clock, since the 16550A is capable of handling a top speed of 1.5
- * megabits/second; but this requires the faster clock.
- */
-#define BASE_BAUD (1843200 / 16)
-
-#endif /* _ASM_SERIAL_H */
+#include <asm-generic/serial.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/sgialib.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/sgialib.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/sgialib.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/sgialib.h	2010-05-16 17:17:36.000000000 -0400
@@ -33,14 +33,6 @@ extern int prom_flags;
 extern void prom_putchar(char c);
 extern char prom_getchar(void);
 
-/* Memory descriptor management. */
-#define PROM_MAX_PMEMBLOCKS    32
-struct prom_pmemblock {
-	LONG	base;		/* Within KSEG0 or XKPHYS. */
-	ULONG	size;		/* In bytes. */
-	ULONG	type;		/* free or prom memory */
-};
-
 /* Get next memory descriptor after CURR, returns first descriptor
  * in chain is CURR is NULL.
  */
@@ -51,7 +43,6 @@ extern struct linux_mdesc *prom_getmdesc
  * array.
  */
 extern void prom_meminit(void);
-extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem);
 
 /* PROM device tree library routines. */
 #define PROM_NULL_COMPONENT ((pcomponent *) 0)
@@ -62,20 +53,6 @@ extern pcomponent *ArcGetPeer(pcomponent
 /* Get child component of THIS. */
 extern pcomponent *ArcGetChild(pcomponent *this);
 
-/* Get parent component of CHILD. */
-extern pcomponent *prom_getparent(pcomponent *child);
-
-/* Copy component opaque data of component THIS into BUFFER
- * if component THIS has opaque data.  Returns success or
- * failure status.
- */
-extern long prom_getcdata(void *buffer, pcomponent *this);
-
-/* Other misc. component routines. */
-extern pcomponent *prom_childadd(pcomponent *this, pcomponent *tmp, void *data);
-extern long prom_delcomponent(pcomponent *this);
-extern pcomponent *prom_componentbypath(char *path);
-
 /* This is called at prom_init time to identify the
  * ARC architecture we are running on
  */
@@ -88,35 +65,13 @@ extern LONG ArcSetEnvironmentVariable(PC
 /* ARCS command line parsing. */
 extern void prom_init_cmdline(void);
 
-/* Acquiring info about the current time, etc. */
-extern struct linux_tinfo *prom_gettinfo(void);
-extern unsigned long prom_getrtime(void);
-
 /* File operations. */
-extern long prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num, unsigned long *cnt);
-extern long prom_open(char *name, enum linux_omode md, unsigned long *fd);
-extern long prom_close(unsigned long fd);
 extern LONG ArcRead(ULONG fd, PVOID buf, ULONG num, PULONG cnt);
-extern long prom_getrstatus(unsigned long fd);
 extern LONG ArcWrite(ULONG fd, PVOID buf, ULONG num, PULONG cnt);
-extern long prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm);
-extern long prom_mount(char *name, enum linux_mountops op);
-extern long prom_getfinfo(unsigned long fd, struct linux_finfo *buf);
-extern long prom_setfinfo(unsigned long fd, unsigned long flags, unsigned long msk);
-
-/* Running stand-along programs. */
-extern long prom_load(char *name, unsigned long end, unsigned long *pc, unsigned long *eaddr);
-extern long prom_invoke(unsigned long pc, unsigned long sp, long argc, char **argv, char **envp);
-extern long prom_exec(char *name, long argc, char **argv, char **envp);
 
 /* Misc. routines. */
-extern VOID prom_halt(VOID) __attribute__((noreturn));
-extern VOID prom_powerdown(VOID) __attribute__((noreturn));
-extern VOID prom_restart(VOID) __attribute__((noreturn));
 extern VOID ArcReboot(VOID) __attribute__((noreturn));
 extern VOID ArcEnterInteractiveMode(VOID) __attribute__((noreturn));
-extern long prom_cfgsave(VOID);
-extern struct linux_sysid *prom_getsysid(VOID);
 extern VOID ArcFlushAllCaches(VOID);
 extern DISPLAY_STATUS *ArcGetDisplayStatus(ULONG FileID);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/sibyte/bigsur.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/sibyte/bigsur.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/sibyte/bigsur.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/sibyte/bigsur.h	2010-05-16 17:17:36.000000000 -0400
@@ -46,4 +46,3 @@
 #endif
 
 #endif /* __ASM_SIBYTE_BIGSUR_H */
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/sibyte/sb1250_ldt.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/sibyte/sb1250_ldt.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/sibyte/sb1250_ldt.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/sibyte/sb1250_ldt.h	2010-05-16 17:17:36.000000000 -0400
@@ -420,4 +420,3 @@
 #endif /* 1250 PASS2 || 112x PASS1 */
 
 #endif
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/sn/klkernvars.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/sn/klkernvars.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/sn/klkernvars.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/sn/klkernvars.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,4 +26,3 @@ typedef struct kern_vars_s {
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_SN_KLKERNVARS_H */
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/sparsemem.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/sparsemem.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/sparsemem.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/sparsemem.h	2010-05-16 17:17:36.000000000 -0400
@@ -11,4 +11,3 @@
 
 #endif /* CONFIG_SPARSEMEM */
 #endif /* _MIPS_SPARSEMEM_H */
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/spinlock.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/spinlock.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/spinlock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/spinlock.h	2010-05-16 17:17:36.000000000 -0400
@@ -36,9 +36,9 @@
 
 static inline int arch_spin_is_locked(arch_spinlock_t *lock)
 {
-	unsigned int counters = ACCESS_ONCE(lock->lock);
+	u32 counters = ACCESS_ONCE(lock->lock);
 
-	return ((counters >> 14) ^ counters) & 0x1fff;
+	return ((counters >> 16) ^ counters) & 0xffff;
 }
 
 #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
@@ -47,9 +47,9 @@ static inline int arch_spin_is_locked(ar
 
 static inline int arch_spin_is_contended(arch_spinlock_t *lock)
 {
-	unsigned int counters = ACCESS_ONCE(lock->lock);
+	u32 counters = ACCESS_ONCE(lock->lock);
 
-	return (((counters >> 14) - counters) & 0x1fff) > 1;
+	return (((counters >> 16) - counters) & 0xffff) > 1;
 }
 #define arch_spin_is_contended	arch_spin_is_contended
 
@@ -57,6 +57,7 @@ static inline void arch_spin_lock(arch_s
 {
 	int my_ticket;
 	int tmp;
+	int inc = 0x10000;
 
 	if (R10000_LLSC_WAR) {
 		__asm__ __volatile__ (
@@ -64,25 +65,24 @@ static inline void arch_spin_lock(arch_s
 		"	.set noreorder					\n"
 		"							\n"
 		"1:	ll	%[ticket], %[ticket_ptr]		\n"
-		"	addiu	%[my_ticket], %[ticket], 0x4000		\n"
+		"	addu	%[my_ticket], %[ticket], %[inc]		\n"
 		"	sc	%[my_ticket], %[ticket_ptr]		\n"
 		"	beqzl	%[my_ticket], 1b			\n"
 		"	 nop						\n"
-		"	srl	%[my_ticket], %[ticket], 14		\n"
-		"	andi	%[my_ticket], %[my_ticket], 0x1fff	\n"
-		"	andi	%[ticket], %[ticket], 0x1fff		\n"
+		"	srl	%[my_ticket], %[ticket], 16		\n"
+		"	andi	%[ticket], %[ticket], 0xffff		\n"
+		"	andi	%[my_ticket], %[my_ticket], 0xffff	\n"
 		"	bne	%[ticket], %[my_ticket], 4f		\n"
 		"	 subu	%[ticket], %[my_ticket], %[ticket]	\n"
 		"2:							\n"
 		"	.subsection 2					\n"
-		"4:	andi	%[ticket], %[ticket], 0x1fff		\n"
+		"4:	andi	%[ticket], %[ticket], 0xffff		\n"
 		"	sll	%[ticket], 5				\n"
 		"							\n"
 		"6:	bnez	%[ticket], 6b				\n"
 		"	 subu	%[ticket], 1				\n"
 		"							\n"
-		"	lw	%[ticket], %[ticket_ptr]		\n"
-		"	andi	%[ticket], %[ticket], 0x1fff		\n"
+		"	lhu	%[ticket], %[serving_now_ptr]		\n"
 		"	beq	%[ticket], %[my_ticket], 2b		\n"
 		"	 subu	%[ticket], %[my_ticket], %[ticket]	\n"
 		"	b	4b					\n"
@@ -90,36 +90,33 @@ static inline void arch_spin_lock(arch_s
 		"	.previous					\n"
 		"	.set pop					\n"
 		: [ticket_ptr] "+m" (lock->lock),
+		  [serving_now_ptr] "+m" (lock->h.serving_now),
 		  [ticket] "=&r" (tmp),
-		  [my_ticket] "=&r" (my_ticket));
+		  [my_ticket] "=&r" (my_ticket)
+		: [inc] "r" (inc));
 	} else {
 		__asm__ __volatile__ (
 		"	.set push		# arch_spin_lock	\n"
 		"	.set noreorder					\n"
 		"							\n"
-		"	ll	%[ticket], %[ticket_ptr]		\n"
-		"1:	addiu	%[my_ticket], %[ticket], 0x4000		\n"
+		"1:	ll	%[ticket], %[ticket_ptr]		\n"
+		"	addu	%[my_ticket], %[ticket], %[inc]		\n"
 		"	sc	%[my_ticket], %[ticket_ptr]		\n"
-		"	beqz	%[my_ticket], 3f			\n"
-		"	 nop						\n"
-		"	srl	%[my_ticket], %[ticket], 14		\n"
-		"	andi	%[my_ticket], %[my_ticket], 0x1fff	\n"
-		"	andi	%[ticket], %[ticket], 0x1fff		\n"
+		"	beqz	%[my_ticket], 1b			\n"
+		"	 srl	%[my_ticket], %[ticket], 16		\n"
+		"	andi	%[ticket], %[ticket], 0xffff		\n"
+		"	andi	%[my_ticket], %[my_ticket], 0xffff	\n"
 		"	bne	%[ticket], %[my_ticket], 4f		\n"
 		"	 subu	%[ticket], %[my_ticket], %[ticket]	\n"
 		"2:							\n"
 		"	.subsection 2					\n"
-		"3:	b	1b					\n"
-		"	 ll	%[ticket], %[ticket_ptr]		\n"
-		"							\n"
 		"4:	andi	%[ticket], %[ticket], 0x1fff		\n"
 		"	sll	%[ticket], 5				\n"
 		"							\n"
 		"6:	bnez	%[ticket], 6b				\n"
 		"	 subu	%[ticket], 1				\n"
 		"							\n"
-		"	lw	%[ticket], %[ticket_ptr]		\n"
-		"	andi	%[ticket], %[ticket], 0x1fff		\n"
+		"	lhu	%[ticket], %[serving_now_ptr]		\n"
 		"	beq	%[ticket], %[my_ticket], 2b		\n"
 		"	 subu	%[ticket], %[my_ticket], %[ticket]	\n"
 		"	b	4b					\n"
@@ -127,8 +124,10 @@ static inline void arch_spin_lock(arch_s
 		"	.previous					\n"
 		"	.set pop					\n"
 		: [ticket_ptr] "+m" (lock->lock),
+		  [serving_now_ptr] "+m" (lock->h.serving_now),
 		  [ticket] "=&r" (tmp),
-		  [my_ticket] "=&r" (my_ticket));
+		  [my_ticket] "=&r" (my_ticket)
+		: [inc] "r" (inc));
 	}
 
 	smp_llsc_mb();
@@ -136,47 +135,16 @@ static inline void arch_spin_lock(arch_s
 
 static inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
-	int tmp;
-
-	smp_llsc_mb();
-
-	if (R10000_LLSC_WAR) {
-		__asm__ __volatile__ (
-		"				# arch_spin_unlock	\n"
-		"1:	ll	%[ticket], %[ticket_ptr]		\n"
-		"	addiu	%[ticket], %[ticket], 1			\n"
-		"	ori	%[ticket], %[ticket], 0x2000		\n"
-		"	xori	%[ticket], %[ticket], 0x2000		\n"
-		"	sc	%[ticket], %[ticket_ptr]		\n"
-		"	beqzl	%[ticket], 1b				\n"
-		: [ticket_ptr] "+m" (lock->lock),
-		  [ticket] "=&r" (tmp));
-	} else {
-		__asm__ __volatile__ (
-		"	.set push		# arch_spin_unlock	\n"
-		"	.set noreorder					\n"
-		"							\n"
-		"	ll	%[ticket], %[ticket_ptr]		\n"
-		"1:	addiu	%[ticket], %[ticket], 1			\n"
-		"	ori	%[ticket], %[ticket], 0x2000		\n"
-		"	xori	%[ticket], %[ticket], 0x2000		\n"
-		"	sc	%[ticket], %[ticket_ptr]		\n"
-		"	beqz	%[ticket], 2f				\n"
-		"	 nop						\n"
-		"							\n"
-		"	.subsection 2					\n"
-		"2:	b	1b					\n"
-		"	 ll	%[ticket], %[ticket_ptr]		\n"
-		"	.previous					\n"
-		"	.set pop					\n"
-		: [ticket_ptr] "+m" (lock->lock),
-		  [ticket] "=&r" (tmp));
-	}
+	unsigned int serving_now = lock->h.serving_now + 1;
+	wmb();
+	lock->h.serving_now = (u16)serving_now;
+	nudge_writes();
 }
 
 static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock)
 {
 	int tmp, tmp2, tmp3;
+	int inc = 0x10000;
 
 	if (R10000_LLSC_WAR) {
 		__asm__ __volatile__ (
@@ -184,11 +152,11 @@ static inline unsigned int arch_spin_try
 		"	.set noreorder					\n"
 		"							\n"
 		"1:	ll	%[ticket], %[ticket_ptr]		\n"
-		"	srl	%[my_ticket], %[ticket], 14		\n"
-		"	andi	%[my_ticket], %[my_ticket], 0x1fff	\n"
-		"	andi	%[now_serving], %[ticket], 0x1fff	\n"
+		"	srl	%[my_ticket], %[ticket], 16		\n"
+		"	andi	%[my_ticket], %[my_ticket], 0xffff	\n"
+		"	andi	%[now_serving], %[ticket], 0xffff	\n"
 		"	bne	%[my_ticket], %[now_serving], 3f	\n"
-		"	 addiu	%[ticket], %[ticket], 0x4000		\n"
+		"	 addu	%[ticket], %[ticket], %[inc]		\n"
 		"	sc	%[ticket], %[ticket_ptr]		\n"
 		"	beqzl	%[ticket], 1b				\n"
 		"	 li	%[ticket], 1				\n"
@@ -201,33 +169,33 @@ static inline unsigned int arch_spin_try
 		: [ticket_ptr] "+m" (lock->lock),
 		  [ticket] "=&r" (tmp),
 		  [my_ticket] "=&r" (tmp2),
-		  [now_serving] "=&r" (tmp3));
+		  [now_serving] "=&r" (tmp3)
+		: [inc] "r" (inc));
 	} else {
 		__asm__ __volatile__ (
 		"	.set push		# arch_spin_trylock	\n"
 		"	.set noreorder					\n"
 		"							\n"
-		"	ll	%[ticket], %[ticket_ptr]		\n"
-		"1:	srl	%[my_ticket], %[ticket], 14		\n"
-		"	andi	%[my_ticket], %[my_ticket], 0x1fff	\n"
-		"	andi	%[now_serving], %[ticket], 0x1fff	\n"
+		"1:	ll	%[ticket], %[ticket_ptr]		\n"
+		"	srl	%[my_ticket], %[ticket], 16		\n"
+		"	andi	%[my_ticket], %[my_ticket], 0xffff	\n"
+		"	andi	%[now_serving], %[ticket], 0xffff	\n"
 		"	bne	%[my_ticket], %[now_serving], 3f	\n"
-		"	 addiu	%[ticket], %[ticket], 0x4000		\n"
+		"	 addu	%[ticket], %[ticket], %[inc]		\n"
 		"	sc	%[ticket], %[ticket_ptr]		\n"
-		"	beqz	%[ticket], 4f				\n"
+		"	beqz	%[ticket], 1b				\n"
 		"	 li	%[ticket], 1				\n"
 		"2:							\n"
 		"	.subsection 2					\n"
 		"3:	b	2b					\n"
 		"	 li	%[ticket], 0				\n"
-		"4:	b	1b					\n"
-		"	 ll	%[ticket], %[ticket_ptr]		\n"
 		"	.previous					\n"
 		"	.set pop					\n"
 		: [ticket_ptr] "+m" (lock->lock),
 		  [ticket] "=&r" (tmp),
 		  [my_ticket] "=&r" (tmp2),
-		  [now_serving] "=&r" (tmp3));
+		  [now_serving] "=&r" (tmp3)
+		: [inc] "r" (inc));
 	}
 
 	smp_llsc_mb();
@@ -305,7 +273,7 @@ static inline void arch_read_unlock(arch
 {
 	unsigned int tmp;
 
-	smp_llsc_mb();
+	smp_mb__before_llsc();
 
 	if (R10000_LLSC_WAR) {
 		__asm__ __volatile__(
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/spinlock_types.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/spinlock_types.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/spinlock_types.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/spinlock_types.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,16 +5,28 @@
 # error "please don't include this file directly"
 #endif
 
-typedef struct {
+#include <linux/types.h>
+
+#include <asm/byteorder.h>
+
+typedef union {
 	/*
-	 * bits  0..13: serving_now
-	 * bits 14    : junk data
-	 * bits 15..28: ticket
+	 * bits  0..15 : serving_now
+	 * bits 16..31 : ticket
 	 */
-	unsigned int lock;
+	u32 lock;
+	struct {
+#ifdef __BIG_ENDIAN
+		u16 ticket;
+		u16 serving_now;
+#else
+		u16 serving_now;
+		u16 ticket;
+#endif
+	} h;
 } arch_spinlock_t;
 
-#define __ARCH_SPIN_LOCK_UNLOCKED	{ 0 }
+#define __ARCH_SPIN_LOCK_UNLOCKED	{ .lock = 0 }
 
 typedef struct {
 	volatile unsigned int lock;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/stackframe.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/stackframe.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/stackframe.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/stackframe.h	2010-05-16 17:17:36.000000000 -0400
@@ -121,6 +121,25 @@
 		.endm
 #else
 		.macro	get_saved_sp	/* Uniprocessor variation */
+#ifdef CONFIG_CPU_JUMP_WORKAROUNDS
+		/*
+		 * Clear BTB (branch target buffer), forbid RAS (return address
+		 * stack) to workaround the Out-of-order Issue in Loongson2F
+		 * via its diagnostic register.
+		 */
+		move	k0, ra
+		jal	1f
+		 nop
+1:		jal	1f
+		 nop
+1:		jal	1f
+		 nop
+1:		jal	1f
+		 nop
+1:		move	ra, k0
+		li	k0, 3
+		mtc0	k0, $22
+#endif /* CONFIG_CPU_LOONGSON2F */
 #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
 		lui	k1, %hi(kernelsp)
 #else
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/system.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/system.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/system.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -95,6 +95,8 @@ static inline unsigned long __xchg_u32(v
 {
 	__u32 retval;
 
+	smp_mb__before_llsc();
+
 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		unsigned long dummy;
 
@@ -147,6 +149,8 @@ static inline __u64 __xchg_u64(volatile
 {
 	__u64 retval;
 
+	smp_mb__before_llsc();
+
 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		unsigned long dummy;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/txx9/generic.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/txx9/generic.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/txx9/generic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/txx9/generic.h	2010-05-16 17:17:36.000000000 -0400
@@ -42,7 +42,6 @@ struct txx9_board_vec {
 };
 extern struct txx9_board_vec *txx9_board_vec;
 extern int (*txx9_irq_dispatch)(int pending);
-char *prom_getcmdline(void);
 const char *prom_getenv(const char *name);
 void txx9_wdt_init(unsigned long base);
 void txx9_wdt_now(unsigned long base);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/uasm.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/uasm.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/uasm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/uasm.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,215 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004, 2005, 2006, 2008  Thiemo Seufer
+ * Copyright (C) 2005  Maciej W. Rozycki
+ * Copyright (C) 2006  Ralf Baechle (ralf@linux-mips.org)
+ */
+
+#include <linux/types.h>
+
+#define Ip_u1u2u3(op)							\
+void __cpuinit								\
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
+
+#define Ip_u2u1u3(op)							\
+void __cpuinit								\
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
+
+#define Ip_u3u1u2(op)							\
+void __cpuinit								\
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
+
+#define Ip_u1u2s3(op)							\
+void __cpuinit								\
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
+
+#define Ip_u2s3u1(op)							\
+void __cpuinit								\
+uasm_i##op(u32 **buf, unsigned int a, signed int b, unsigned int c)
+
+#define Ip_u2u1s3(op)							\
+void __cpuinit								\
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
+
+#define Ip_u2u1msbu3(op)						\
+void __cpuinit								\
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c,	\
+	   unsigned int d)
+
+#define Ip_u1u2(op)							\
+void __cpuinit uasm_i##op(u32 **buf, unsigned int a, unsigned int b)
+
+#define Ip_u1s2(op)							\
+void __cpuinit uasm_i##op(u32 **buf, unsigned int a, signed int b)
+
+#define Ip_u1(op) void __cpuinit uasm_i##op(u32 **buf, unsigned int a)
+
+#define Ip_0(op) void __cpuinit uasm_i##op(u32 **buf)
+
+Ip_u2u1s3(_addiu);
+Ip_u3u1u2(_addu);
+Ip_u2u1u3(_andi);
+Ip_u3u1u2(_and);
+Ip_u1u2s3(_beq);
+Ip_u1u2s3(_beql);
+Ip_u1s2(_bgez);
+Ip_u1s2(_bgezl);
+Ip_u1s2(_bltz);
+Ip_u1s2(_bltzl);
+Ip_u1u2s3(_bne);
+Ip_u2s3u1(_cache);
+Ip_u1u2u3(_dmfc0);
+Ip_u1u2u3(_dmtc0);
+Ip_u2u1s3(_daddiu);
+Ip_u3u1u2(_daddu);
+Ip_u2u1u3(_dsll);
+Ip_u2u1u3(_dsll32);
+Ip_u2u1u3(_dsra);
+Ip_u2u1u3(_dsrl);
+Ip_u2u1u3(_dsrl32);
+Ip_u2u1u3(_drotr);
+Ip_u3u1u2(_dsubu);
+Ip_0(_eret);
+Ip_u1(_j);
+Ip_u1(_jal);
+Ip_u1(_jr);
+Ip_u2s3u1(_ld);
+Ip_u2s3u1(_ll);
+Ip_u2s3u1(_lld);
+Ip_u1s2(_lui);
+Ip_u2s3u1(_lw);
+Ip_u1u2u3(_mfc0);
+Ip_u1u2u3(_mtc0);
+Ip_u2u1u3(_ori);
+Ip_u3u1u2(_or);
+Ip_u2s3u1(_pref);
+Ip_0(_rfe);
+Ip_u2s3u1(_sc);
+Ip_u2s3u1(_scd);
+Ip_u2s3u1(_sd);
+Ip_u2u1u3(_sll);
+Ip_u2u1u3(_sra);
+Ip_u2u1u3(_srl);
+Ip_u2u1u3(_rotr);
+Ip_u3u1u2(_subu);
+Ip_u2s3u1(_sw);
+Ip_0(_tlbp);
+Ip_0(_tlbr);
+Ip_0(_tlbwi);
+Ip_0(_tlbwr);
+Ip_u3u1u2(_xor);
+Ip_u2u1u3(_xori);
+Ip_u2u1msbu3(_dins);
+Ip_u1(_syscall);
+
+/* Handle labels. */
+struct uasm_label {
+	u32 *addr;
+	int lab;
+};
+
+void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid);
+#ifdef CONFIG_64BIT
+int uasm_in_compat_space_p(long addr);
+#endif
+int uasm_rel_hi(long val);
+int uasm_rel_lo(long val);
+void UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr);
+void UASM_i_LA(u32 **buf, unsigned int rs, long addr);
+
+#define UASM_L_LA(lb)							\
+static inline void __cpuinit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
+{									\
+	uasm_build_label(lab, addr, label##lb);				\
+}
+
+/* convenience macros for instructions */
+#ifdef CONFIG_64BIT
+# define UASM_i_LW(buf, rs, rt, off) uasm_i_ld(buf, rs, rt, off)
+# define UASM_i_SW(buf, rs, rt, off) uasm_i_sd(buf, rs, rt, off)
+# define UASM_i_SLL(buf, rs, rt, sh) uasm_i_dsll(buf, rs, rt, sh)
+# define UASM_i_SRA(buf, rs, rt, sh) uasm_i_dsra(buf, rs, rt, sh)
+# define UASM_i_SRL(buf, rs, rt, sh) uasm_i_dsrl(buf, rs, rt, sh)
+# define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_drotr(buf, rs, rt, sh)
+# define UASM_i_MFC0(buf, rt, rd...) uasm_i_dmfc0(buf, rt, rd)
+# define UASM_i_MTC0(buf, rt, rd...) uasm_i_dmtc0(buf, rt, rd)
+# define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_daddiu(buf, rs, rt, val)
+# define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_daddu(buf, rs, rt, rd)
+# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_dsubu(buf, rs, rt, rd)
+# define UASM_i_LL(buf, rs, rt, off) uasm_i_lld(buf, rs, rt, off)
+# define UASM_i_SC(buf, rs, rt, off) uasm_i_scd(buf, rs, rt, off)
+#else
+# define UASM_i_LW(buf, rs, rt, off) uasm_i_lw(buf, rs, rt, off)
+# define UASM_i_SW(buf, rs, rt, off) uasm_i_sw(buf, rs, rt, off)
+# define UASM_i_SLL(buf, rs, rt, sh) uasm_i_sll(buf, rs, rt, sh)
+# define UASM_i_SRA(buf, rs, rt, sh) uasm_i_sra(buf, rs, rt, sh)
+# define UASM_i_SRL(buf, rs, rt, sh) uasm_i_srl(buf, rs, rt, sh)
+# define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_rotr(buf, rs, rt, sh)
+# define UASM_i_MFC0(buf, rt, rd...) uasm_i_mfc0(buf, rt, rd)
+# define UASM_i_MTC0(buf, rt, rd...) uasm_i_mtc0(buf, rt, rd)
+# define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_addiu(buf, rs, rt, val)
+# define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_addu(buf, rs, rt, rd)
+# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_subu(buf, rs, rt, rd)
+# define UASM_i_LL(buf, rs, rt, off) uasm_i_ll(buf, rs, rt, off)
+# define UASM_i_SC(buf, rs, rt, off) uasm_i_sc(buf, rs, rt, off)
+#endif
+
+#define uasm_i_b(buf, off) uasm_i_beq(buf, 0, 0, off)
+#define uasm_i_beqz(buf, rs, off) uasm_i_beq(buf, rs, 0, off)
+#define uasm_i_beqzl(buf, rs, off) uasm_i_beql(buf, rs, 0, off)
+#define uasm_i_bnez(buf, rs, off) uasm_i_bne(buf, rs, 0, off)
+#define uasm_i_bnezl(buf, rs, off) uasm_i_bnel(buf, rs, 0, off)
+#define uasm_i_move(buf, a, b) UASM_i_ADDU(buf, a, 0, b)
+#define uasm_i_nop(buf) uasm_i_sll(buf, 0, 0, 0)
+#define uasm_i_ssnop(buf) uasm_i_sll(buf, 0, 0, 1)
+#define uasm_i_ehb(buf) uasm_i_sll(buf, 0, 0, 3)
+
+static inline void uasm_i_dsrl_safe(u32 **p, unsigned int a1,
+				    unsigned int a2, unsigned int a3)
+{
+	if (a3 < 32)
+		uasm_i_dsrl(p, a1, a2, a3);
+	else
+		uasm_i_dsrl32(p, a1, a2, a3 - 32);
+}
+
+static inline void uasm_i_dsll_safe(u32 **p, unsigned int a1,
+				    unsigned int a2, unsigned int a3)
+{
+	if (a3 < 32)
+		uasm_i_dsll(p, a1, a2, a3);
+	else
+		uasm_i_dsll32(p, a1, a2, a3 - 32);
+}
+
+/* Handle relocations. */
+struct uasm_reloc {
+	u32 *addr;
+	unsigned int type;
+	int lab;
+};
+
+/* This is zero so we can use zeroed label arrays. */
+#define UASM_LABEL_INVALID 0
+
+void uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid);
+void uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab);
+void uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, long off);
+void uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, long off);
+void uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab,
+	u32 *first, u32 *end, u32 *target);
+int uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr);
+
+/* Convenience functions for labeled branches. */
+void uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void uasm_il_b(u32 **p, struct uasm_reloc **r, int lid);
+void uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1,
+		 unsigned int reg2, int lid);
+void uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/ucontext.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/ucontext.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/ucontext.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/ucontext.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,21 +1 @@
-/*
- * 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.
- *
- * Low level exception handling
- *
- * Copyright (C) 1998, 1999 by Ralf Baechle
- */
-#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 */
+#include <asm-generic/ucontext.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/unistd.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/unistd.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/unistd.h	2010-05-16 17:17:36.000000000 -0400
@@ -1004,6 +1004,7 @@
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_UTIME
@@ -1013,6 +1014,7 @@
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_UNAME
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/include/asm/vdso.h linux-libre-2.6.34-gnu1/arch/mips/include/asm/vdso.h
--- linux-libre-2.6.33-gnu1/arch/mips/include/asm/vdso.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/include/asm/vdso.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,29 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009 Cavium Networks
+ */
+
+#ifndef __ASM_VDSO_H
+#define __ASM_VDSO_H
+
+#include <linux/types.h>
+
+
+#ifdef CONFIG_32BIT
+struct mips_vdso {
+	u32 signal_trampoline[2];
+	u32 rt_signal_trampoline[2];
+};
+#else  /* !CONFIG_32BIT */
+struct mips_vdso {
+	u32 o32_signal_trampoline[2];
+	u32 o32_rt_signal_trampoline[2];
+	u32 rt_signal_trampoline[2];
+	u32 n32_rt_signal_trampoline[2];
+};
+#endif /* CONFIG_32BIT */
+
+#endif /* __ASM_VDSO_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/jazz/irq.c linux-libre-2.6.34-gnu1/arch/mips/jazz/irq.c
--- linux-libre-2.6.33-gnu1/arch/mips/jazz/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/jazz/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,17 +20,17 @@
 #include <asm/jazz.h>
 #include <asm/pgtable.h>
 
-static DEFINE_SPINLOCK(r4030_lock);
+static DEFINE_RAW_SPINLOCK(r4030_lock);
 
 static void enable_r4030_irq(unsigned int irq)
 {
 	unsigned int mask = 1 << (irq - JAZZ_IRQ_START);
 	unsigned long flags;
 
-	spin_lock_irqsave(&r4030_lock, flags);
+	raw_spin_lock_irqsave(&r4030_lock, flags);
 	mask |= r4030_read_reg16(JAZZ_IO_IRQ_ENABLE);
 	r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, mask);
-	spin_unlock_irqrestore(&r4030_lock, flags);
+	raw_spin_unlock_irqrestore(&r4030_lock, flags);
 }
 
 void disable_r4030_irq(unsigned int irq)
@@ -38,10 +38,10 @@ void disable_r4030_irq(unsigned int irq)
 	unsigned int mask = ~(1 << (irq - JAZZ_IRQ_START));
 	unsigned long flags;
 
-	spin_lock_irqsave(&r4030_lock, flags);
+	raw_spin_lock_irqsave(&r4030_lock, flags);
 	mask &= r4030_read_reg16(JAZZ_IO_IRQ_ENABLE);
 	r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, mask);
-	spin_unlock_irqrestore(&r4030_lock, flags);
+	raw_spin_unlock_irqrestore(&r4030_lock, flags);
 }
 
 static struct irq_chip r4030_irq_type = {
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/jazz/jazzdma.c linux-libre-2.6.34-gnu1/arch/mips/jazz/jazzdma.c
--- linux-libre-2.6.33-gnu1/arch/mips/jazz/jazzdma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/jazz/jazzdma.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/mm.h>
 #include <linux/bootmem.h>
 #include <linux/spinlock.h>
+#include <linux/gfp.h>
 #include <asm/mipsregs.h>
 #include <asm/jazz.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/jazz/setup.c linux-libre-2.6.34-gnu1/arch/mips/jazz/setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/jazz/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/jazz/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -76,15 +76,9 @@ void __init plat_mem_setup(void)
 
 #ifdef CONFIG_VT
 	screen_info = (struct screen_info) {
-		0, 0,		/* orig-x, orig-y */
-		0,		/* unused */
-		0,		/* orig_video_page */
-		0,		/* orig_video_mode */
-		160,		/* orig_video_cols */
-		0, 0, 0,	/* unused, ega_bx, unused */
-		64,		/* orig_video_lines */
-		0,		/* orig_video_isVGA */
-		16		/* orig_video_points */
+		.orig_video_cols	= 160,
+		.orig_video_lines	= 64,
+		.orig_video_points	= 16,
 	};
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/Kconfig linux-libre-2.6.34-gnu1/arch/mips/Kconfig
--- linux-libre-2.6.33-gnu1/arch/mips/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,7 @@ config AR7
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select SYS_SUPPORTS_ZBOOT_UART16550
-	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
 	select GCD
 	select VLYNQ
 	help
@@ -49,7 +49,7 @@ config AR7
 	  family: TNETD7100, 7200 and 7300.
 
 config BCM47XX
-	bool "BCM47XX based boards"
+	bool "Broadcom BCM47XX based boards"
 	select CEVT_R4K
 	select CSRC_R4K
 	select DMA_NONCOHERENT
@@ -180,7 +180,7 @@ config LASAT
 
 config MACH_LOONGSON
 	bool "Loongson family of machines"
-	select SYS_SUPPORTS_ZBOOT_UART16550
+	select SYS_SUPPORTS_ZBOOT
 	help
 	  This enables the support of Loongson family of machines.
 
@@ -509,6 +509,7 @@ config SIBYTE_SWARM
 	bool "Sibyte BCM91250A-SWARM"
 	select BOOT_ELF32
 	select DMA_COHERENT
+	select HAVE_PATA_PLATFORM
 	select NR_CPUS_DEFAULT_2
 	select SIBYTE_SB1250
 	select SWAP_IO_SPACE
@@ -523,6 +524,7 @@ config SIBYTE_LITTLESUR
 	depends on EXPERIMENTAL
 	select BOOT_ELF32
 	select DMA_COHERENT
+	select HAVE_PATA_PLATFORM
 	select NR_CPUS_DEFAULT_2
 	select SIBYTE_SB1250
 	select SWAP_IO_SPACE
@@ -812,9 +814,9 @@ config DMA_COHERENT
 
 config DMA_NONCOHERENT
 	bool
-	select DMA_NEED_PCI_MAP_STATE
+	select NEED_DMA_MAP_STATE
 
-config DMA_NEED_PCI_MAP_STATE
+config NEED_DMA_MAP_STATE
 	bool
 
 config SYS_HAS_EARLY_PRINTK
@@ -1295,7 +1297,6 @@ config CPU_CAVIUM_OCTEON
 	select SYS_SUPPORTS_SMP
 	select NR_CPUS_DEFAULT_16
 	select WEAK_ORDERING
-	select WEAK_REORDERING_BEYOND_LLSC
 	select CPU_SUPPORTS_HIGHMEM
 	select CPU_SUPPORTS_HUGEPAGES
 	help
@@ -1306,6 +1307,33 @@ config CPU_CAVIUM_OCTEON
 
 endchoice
 
+if CPU_LOONGSON2F
+config CPU_NOP_WORKAROUNDS
+	bool
+
+config CPU_JUMP_WORKAROUNDS
+	bool
+
+config CPU_LOONGSON2F_WORKAROUNDS
+	bool "Loongson 2F Workarounds"
+	default y
+	select CPU_NOP_WORKAROUNDS
+	select CPU_JUMP_WORKAROUNDS
+	help
+	  Loongson 2F01 / 2F02 processors have the NOP & JUMP issues which
+	  require workarounds.  Without workarounds the system may hang
+	  unexpectedly.  For more information please refer to the gas
+	  -mfix-loongson2f-nop and -mfix-loongson2f-jump options.
+
+	  Loongson 2F03 and later have fixed these issues and no workarounds
+	  are needed.  The workarounds have no significant side effect on them
+	  but may decrease the performance of the system so this option should
+	  be disabled unless the kernel is intended to be run on 2F01 or 2F02
+	  systems.
+
+	  If unsure, please say Y.
+endif # CPU_LOONGSON2F
+
 config SYS_SUPPORTS_ZBOOT
 	bool
 	select HAVE_KERNEL_GZIP
@@ -1726,6 +1754,9 @@ config SB1_PASS_2_1_WORKAROUNDS
 config 64BIT_PHYS_ADDR
 	bool
 
+config ARCH_PHYS_ADDR_T_64BIT
+       def_bool 64BIT_PHYS_ADDR
+
 config CPU_HAS_SMARTMIPS
 	depends on SYS_SUPPORTS_SMARTMIPS
 	bool "Support for the SmartMIPS ASE"
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/Kconfig.debug linux-libre-2.6.34-gnu1/arch/mips/Kconfig.debug
--- linux-libre-2.6.33-gnu1/arch/mips/Kconfig.debug	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/Kconfig.debug	2010-05-16 17:17:36.000000000 -0400
@@ -102,4 +102,30 @@ config RUNTIME_DEBUG
 	  arch/mips/include/asm/debug.h for debugging macros.
 	  If unsure, say N.
 
+config DEBUG_ZBOOT
+	bool "Enable compressed kernel support debugging"
+	depends on DEBUG_KERNEL && SYS_SUPPORTS_ZBOOT
+	default n
+	help
+	  If you want to add compressed kernel support to a new board, and the
+	  board supports uart16550 compatible serial port, please select
+	  SYS_SUPPORTS_ZBOOT_UART16550 for your board and enable this option to
+	  debug it.
+
+	  If your board doesn't support uart16550 compatible serial port, you
+	  can try to select SYS_SUPPORTS_ZBOOT and use the other methods to
+	  debug it. for example, add a new serial port support just as
+	  arch/mips/boot/compressed/uart-16550.c does.
+
+	  After the compressed kernel support works, please disable this option
+	  to reduce the kernel image size and speed up the booting procedure a
+	  little.
+
+config SPINLOCK_TEST
+	bool "Enable spinlock timing tests in debugfs"
+	depends on DEBUG_FS
+	default n
+	help
+	  Add several files to the debugfs to test spinlock speed.
+
 endmenu
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/asm-offsets.c linux-libre-2.6.34-gnu1/arch/mips/kernel/asm-offsets.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/asm-offsets.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/asm-offsets.c	2010-05-16 17:17:36.000000000 -0400
@@ -188,11 +188,15 @@ void output_mm_defines(void)
 	DEFINE(_PTE_T_SIZE, sizeof(pte_t));
 	BLANK();
 	DEFINE(_PGD_T_LOG2, PGD_T_LOG2);
+#ifndef __PAGETABLE_PMD_FOLDED
 	DEFINE(_PMD_T_LOG2, PMD_T_LOG2);
+#endif
 	DEFINE(_PTE_T_LOG2, PTE_T_LOG2);
 	BLANK();
 	DEFINE(_PGD_ORDER, PGD_ORDER);
+#ifndef __PAGETABLE_PMD_FOLDED
 	DEFINE(_PMD_ORDER, PMD_ORDER);
+#endif
 	DEFINE(_PTE_ORDER, PTE_ORDER);
 	BLANK();
 	DEFINE(_PMD_SHIFT, PMD_SHIFT);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/cevt-gt641xx.c linux-libre-2.6.34-gnu1/arch/mips/kernel/cevt-gt641xx.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/cevt-gt641xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/cevt-gt641xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,7 @@
 #include <asm/gt64120.h>
 #include <asm/time.h>
 
-static DEFINE_SPINLOCK(gt641xx_timer_lock);
+static DEFINE_RAW_SPINLOCK(gt641xx_timer_lock);
 static unsigned int gt641xx_base_clock;
 
 void gt641xx_set_base_clock(unsigned int clock)
@@ -49,7 +49,7 @@ static int gt641xx_timer0_set_next_event
 {
 	u32 ctrl;
 
-	spin_lock(&gt641xx_timer_lock);
+	raw_spin_lock(&gt641xx_timer_lock);
 
 	ctrl = GT_READ(GT_TC_CONTROL_OFS);
 	ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
@@ -58,7 +58,7 @@ static int gt641xx_timer0_set_next_event
 	GT_WRITE(GT_TC0_OFS, delta);
 	GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
 
-	spin_unlock(&gt641xx_timer_lock);
+	raw_spin_unlock(&gt641xx_timer_lock);
 
 	return 0;
 }
@@ -68,7 +68,7 @@ static void gt641xx_timer0_set_mode(enum
 {
 	u32 ctrl;
 
-	spin_lock(&gt641xx_timer_lock);
+	raw_spin_lock(&gt641xx_timer_lock);
 
 	ctrl = GT_READ(GT_TC_CONTROL_OFS);
 	ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
@@ -86,7 +86,7 @@ static void gt641xx_timer0_set_mode(enum
 
 	GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
 
-	spin_unlock(&gt641xx_timer_lock);
+	raw_spin_unlock(&gt641xx_timer_lock);
 }
 
 static void gt641xx_timer0_event_handler(struct clock_event_device *dev)
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/cpufreq/loongson2_clock.c linux-libre-2.6.34-gnu1/arch/mips/kernel/cpufreq/loongson2_clock.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/cpufreq/loongson2_clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/cpufreq/loongson2_clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -164,3 +164,7 @@ void loongson2_cpu_wait(void)
 	spin_unlock_irqrestore(&loongson2_wait_lock, flags);
 }
 EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
+
+MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
+MODULE_DESCRIPTION("cpufreq driver for Loongson 2F");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/cpu-probe.c linux-libre-2.6.34-gnu1/arch/mips/kernel/cpu-probe.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/cpu-probe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/cpu-probe.c	2010-05-16 17:17:36.000000000 -0400
@@ -162,6 +162,7 @@ void __init check_wait(void)
 	case CPU_BCM6348:
 	case CPU_BCM6358:
 	case CPU_CAVIUM_OCTEON:
+	case CPU_CAVIUM_OCTEON_PLUS:
 		cpu_wait = r4k_wait;
 		break;
 
@@ -700,6 +701,19 @@ static inline unsigned int decode_config
 	return config3 & MIPS_CONF_M;
 }
 
+static inline unsigned int decode_config4(struct cpuinfo_mips *c)
+{
+	unsigned int config4;
+
+	config4 = read_c0_config4();
+
+	if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT
+	    && cpu_has_tlb)
+		c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
+
+	return config4 & MIPS_CONF_M;
+}
+
 static void __cpuinit decode_configs(struct cpuinfo_mips *c)
 {
 	int ok;
@@ -718,6 +732,8 @@ static void __cpuinit decode_configs(str
 		ok = decode_config2(c);
 	if (ok)
 		ok = decode_config3(c);
+	if (ok)
+		ok = decode_config4(c);
 
 	mips_probe_watch_registers(c);
 }
@@ -731,9 +747,6 @@ static inline void cpu_probe_mips(struct
 		__cpu_name[cpu] = "MIPS 4Kc";
 		break;
 	case PRID_IMP_4KEC:
-		c->cputype = CPU_4KEC;
-		__cpu_name[cpu] = "MIPS 4KEc";
-		break;
 	case PRID_IMP_4KECR2:
 		c->cputype = CPU_4KEC;
 		__cpu_name[cpu] = "MIPS 4KEc";
@@ -899,12 +912,18 @@ static inline void cpu_probe_cavium(stru
 	case PRID_IMP_CAVIUM_CN38XX:
 	case PRID_IMP_CAVIUM_CN31XX:
 	case PRID_IMP_CAVIUM_CN30XX:
+		c->cputype = CPU_CAVIUM_OCTEON;
+		__cpu_name[cpu] = "Cavium Octeon";
+		goto platform;
 	case PRID_IMP_CAVIUM_CN58XX:
 	case PRID_IMP_CAVIUM_CN56XX:
 	case PRID_IMP_CAVIUM_CN50XX:
 	case PRID_IMP_CAVIUM_CN52XX:
-		c->cputype = CPU_CAVIUM_OCTEON;
-		__cpu_name[cpu] = "Cavium Octeon";
+		c->cputype = CPU_CAVIUM_OCTEON_PLUS;
+		__cpu_name[cpu] = "Cavium Octeon+";
+platform:
+		if (cpu == 0)
+			__elf_platform = "octeon";
 		break;
 	default:
 		printk(KERN_INFO "Unknown Octeon chip!\n");
@@ -914,6 +933,7 @@ static inline void cpu_probe_cavium(stru
 }
 
 const char *__cpu_name[NR_CPUS];
+const char *__elf_platform;
 
 __cpuinit void cpu_probe(void)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/ftrace.c linux-libre-2.6.34-gnu1/arch/mips/kernel/ftrace.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/ftrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/ftrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
  * Copyright (C) 2009 DSLab, Lanzhou University, China
- * Author: Wu Zhangjin <wuzj@lemote.com>
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  *
  * Thanks goes to Steven Rostedt for writing the original x86 version.
  */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/i8259.c linux-libre-2.6.34-gnu1/arch/mips/kernel/i8259.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/i8259.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/i8259.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,7 +29,7 @@
  */
 
 static int i8259A_auto_eoi = -1;
-DEFINE_SPINLOCK(i8259A_lock);
+DEFINE_RAW_SPINLOCK(i8259A_lock);
 static void disable_8259A_irq(unsigned int irq);
 static void enable_8259A_irq(unsigned int irq);
 static void mask_and_ack_8259A(unsigned int irq);
@@ -65,13 +65,13 @@ static void disable_8259A_irq(unsigned i
 
 	irq -= I8259A_IRQ_BASE;
 	mask = 1 << irq;
-	spin_lock_irqsave(&i8259A_lock, flags);
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
 	cached_irq_mask |= mask;
 	if (irq & 8)
 		outb(cached_slave_mask, PIC_SLAVE_IMR);
 	else
 		outb(cached_master_mask, PIC_MASTER_IMR);
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
 static void enable_8259A_irq(unsigned int irq)
@@ -81,13 +81,13 @@ static void enable_8259A_irq(unsigned in
 
 	irq -= I8259A_IRQ_BASE;
 	mask = ~(1 << irq);
-	spin_lock_irqsave(&i8259A_lock, flags);
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
 	cached_irq_mask &= mask;
 	if (irq & 8)
 		outb(cached_slave_mask, PIC_SLAVE_IMR);
 	else
 		outb(cached_master_mask, PIC_MASTER_IMR);
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
 int i8259A_irq_pending(unsigned int irq)
@@ -98,12 +98,12 @@ int i8259A_irq_pending(unsigned int irq)
 
 	irq -= I8259A_IRQ_BASE;
 	mask = 1 << irq;
-	spin_lock_irqsave(&i8259A_lock, flags);
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
 	if (irq < 8)
 		ret = inb(PIC_MASTER_CMD) & mask;
 	else
 		ret = inb(PIC_SLAVE_CMD) & (mask >> 8);
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 
 	return ret;
 }
@@ -151,7 +151,7 @@ static void mask_and_ack_8259A(unsigned
 
 	irq -= I8259A_IRQ_BASE;
 	irqmask = 1 << irq;
-	spin_lock_irqsave(&i8259A_lock, flags);
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
 	/*
 	 * Lightweight spurious IRQ detection. We do not want
 	 * to overdo spurious IRQ handling - it's usually a sign
@@ -183,7 +183,7 @@ handle_real_irq:
 		outb(0x60+irq, PIC_MASTER_CMD);	/* 'Specific EOI to master */
 	}
 	smtc_im_ack_irq(irq);
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 	return;
 
 spurious_8259A_irq:
@@ -264,7 +264,7 @@ static void init_8259A(int auto_eoi)
 
 	i8259A_auto_eoi = auto_eoi;
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
 
 	outb(0xff, PIC_MASTER_IMR);	/* mask all of 8259A-1 */
 	outb(0xff, PIC_SLAVE_IMR);	/* mask all of 8259A-2 */
@@ -298,7 +298,7 @@ static void init_8259A(int auto_eoi)
 	outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */
 	outb(cached_slave_mask, PIC_SLAVE_IMR);	  /* restore slave IRQ mask */
 
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/irq.c linux-libre-2.6.34-gnu1/arch/mips/kernel/irq.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/kernel_stat.h>
 #include <linux/module.h>
 #include <linux/proc_fs.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/random.h>
 #include <linux/sched.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/irq-gt641xx.c linux-libre-2.6.34-gnu1/arch/mips/kernel/irq-gt641xx.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/irq-gt641xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/irq-gt641xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,18 +27,18 @@
 
 #define GT641XX_IRQ_TO_BIT(irq)	(1U << (irq - GT641XX_IRQ_BASE))
 
-static DEFINE_SPINLOCK(gt641xx_irq_lock);
+static DEFINE_RAW_SPINLOCK(gt641xx_irq_lock);
 
 static void ack_gt641xx_irq(unsigned int irq)
 {
 	unsigned long flags;
 	u32 cause;
 
-	spin_lock_irqsave(&gt641xx_irq_lock, flags);
+	raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
 	cause = GT_READ(GT_INTRCAUSE_OFS);
 	cause &= ~GT641XX_IRQ_TO_BIT(irq);
 	GT_WRITE(GT_INTRCAUSE_OFS, cause);
-	spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
+	raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
 }
 
 static void mask_gt641xx_irq(unsigned int irq)
@@ -46,11 +46,11 @@ static void mask_gt641xx_irq(unsigned in
 	unsigned long flags;
 	u32 mask;
 
-	spin_lock_irqsave(&gt641xx_irq_lock, flags);
+	raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
 	mask = GT_READ(GT_INTRMASK_OFS);
 	mask &= ~GT641XX_IRQ_TO_BIT(irq);
 	GT_WRITE(GT_INTRMASK_OFS, mask);
-	spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
+	raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
 }
 
 static void mask_ack_gt641xx_irq(unsigned int irq)
@@ -58,7 +58,7 @@ static void mask_ack_gt641xx_irq(unsigne
 	unsigned long flags;
 	u32 cause, mask;
 
-	spin_lock_irqsave(&gt641xx_irq_lock, flags);
+	raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
 	mask = GT_READ(GT_INTRMASK_OFS);
 	mask &= ~GT641XX_IRQ_TO_BIT(irq);
 	GT_WRITE(GT_INTRMASK_OFS, mask);
@@ -66,7 +66,7 @@ static void mask_ack_gt641xx_irq(unsigne
 	cause = GT_READ(GT_INTRCAUSE_OFS);
 	cause &= ~GT641XX_IRQ_TO_BIT(irq);
 	GT_WRITE(GT_INTRCAUSE_OFS, cause);
-	spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
+	raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
 }
 
 static void unmask_gt641xx_irq(unsigned int irq)
@@ -74,11 +74,11 @@ static void unmask_gt641xx_irq(unsigned
 	unsigned long flags;
 	u32 mask;
 
-	spin_lock_irqsave(&gt641xx_irq_lock, flags);
+	raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
 	mask = GT_READ(GT_INTRMASK_OFS);
 	mask |= GT641XX_IRQ_TO_BIT(irq);
 	GT_WRITE(GT_INTRMASK_OFS, mask);
-	spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
+	raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
 }
 
 static struct irq_chip gt641xx_irq_chip = {
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/linux32.c linux-libre-2.6.34-gnu1/arch/mips/kernel/linux32.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/linux32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/linux32.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,14 +9,12 @@
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/file.h>
-#include <linux/smp_lock.h>
 #include <linux/highuid.h>
 #include <linux/resource.h>
 #include <linux/highmem.h>
 #include <linux/time.h>
 #include <linux/times.h>
 #include <linux/poll.h>
-#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/filter.h>
 #include <linux/shm.h>
@@ -35,6 +33,7 @@
 #include <linux/compat.h>
 #include <linux/vfs.h>
 #include <linux/ipc.h>
+#include <linux/slab.h>
 
 #include <net/sock.h>
 #include <net/scm.h>
@@ -250,22 +249,6 @@ SYSCALL_DEFINE5(n32_msgrcv, int, msqid,
 }
 #endif
 
-SYSCALL_DEFINE1(32_newuname, struct new_utsname __user *, name)
-{
-	int ret = 0;
-
-	down_read(&uts_sem);
-	if (copy_to_user(name, utsname(), sizeof *name))
-		ret = -EFAULT;
-	up_read(&uts_sem);
-
-	if (current->personality == PER_LINUX32 && !ret)
-		if (copy_to_user(name->machine, "mips\0\0\0", 8))
-			ret = -EFAULT;
-
-	return ret;
-}
-
 SYSCALL_DEFINE1(32_personality, unsigned long, personality)
 {
 	int ret;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/Makefile linux-libre-2.6.34-gnu1/arch/mips/kernel/Makefile
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@ extra-y		:= head.o init_task.o vmlinux.l
 
 obj-y		+= cpu-probe.o branch.o entry.o genex.o irq.o process.o \
 		   ptrace.o reset.o setup.o signal.o syscall.o \
-		   time.o topology.o traps.o unaligned.o watch.o
+		   time.o topology.o traps.o unaligned.o watch.o vdso.o
 
 ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_ftrace.o = -pg
@@ -93,6 +93,7 @@ obj-$(CONFIG_GPIO_TXX9)		+= gpio_txx9.o
 
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
+obj-$(CONFIG_SPINLOCK_TEST)	+= spinlock_test.o
 
 CFLAGS_cpu-bugs64.o	= $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/mcount.S linux-libre-2.6.34-gnu1/arch/mips/kernel/mcount.S
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/mcount.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/mcount.S	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  * more details.
  *
  * Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China
- * Author: Wu Zhangjin <wuzj@lemote.com>
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  */
 
 #include <asm/regdef.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/octeon_switch.S linux-libre-2.6.34-gnu1/arch/mips/kernel/octeon_switch.S
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/octeon_switch.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/octeon_switch.S	2010-05-16 17:17:36.000000000 -0400
@@ -500,4 +500,3 @@ done_restore:
 	 nop
 	END(octeon_mult_restore)
 	.set pop
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/process.c linux-libre-2.6.34-gnu1/arch/mips/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/mman.h>
 #include <linux/personality.h>
 #include <linux/sys.h>
@@ -64,8 +63,13 @@ void __noreturn cpu_idle(void)
 
 			smtc_idle_loop_hook();
 #endif
-			if (cpu_wait)
+
+			if (cpu_wait) {
+				/* Don't trace irqs off for idle */
+				stop_critical_timings();
 				(*cpu_wait)();
+				start_critical_timings();
+			}
 		}
 #ifdef CONFIG_HOTPLUG_CPU
 		if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) &&
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/mips/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -493,36 +493,6 @@ long arch_ptrace(struct task_struct *chi
 		ret = ptrace_setfpregs(child, (__u32 __user *) data);
 		break;
 
-	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
-	case PTRACE_CONT: { /* restart after signal. */
-		ret = -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;
-		wake_up_process(child);
-		ret = 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:
-		ret = 0;
-		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
-			break;
-		child->exit_code = SIGKILL;
-		wake_up_process(child);
-		break;
-
 	case PTRACE_GET_THREAD_AREA:
 		ret = put_user(task_thread_info(child)->tp_value,
 				(unsigned long __user *) data);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/rtlx.c linux-libre-2.6.34-gnu1/arch/mips/kernel/rtlx.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/rtlx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/rtlx.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,12 +23,10 @@
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
-#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/vmalloc.h>
 #include <linux/elf.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/moduleloader.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/scall64-n32.S linux-libre-2.6.34-gnu1/arch/mips/kernel/scall64-n32.S
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/scall64-n32.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/scall64-n32.S	2010-05-16 17:17:36.000000000 -0400
@@ -181,7 +181,7 @@ EXPORT(sysn32_call_table)
 	PTR	sys_exit
 	PTR	compat_sys_wait4
 	PTR	sys_kill			/* 6060 */
-	PTR	sys_32_newuname
+	PTR	sys_newuname
 	PTR	sys_semget
 	PTR	sys_semop
 	PTR	sys_n32_semctl
@@ -385,7 +385,7 @@ EXPORT(sysn32_call_table)
 	PTR	sys_fchmodat
 	PTR	sys_faccessat
 	PTR	compat_sys_pselect6
-	PTR	sys_ppoll			/* 6265 */
+	PTR	compat_sys_ppoll		/* 6265 */
 	PTR	sys_unshare
 	PTR	sys_splice
 	PTR	sys_sync_file_range
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/scall64-o32.S linux-libre-2.6.34-gnu1/arch/mips/kernel/scall64-o32.S
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/scall64-o32.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/scall64-o32.S	2010-05-16 17:17:36.000000000 -0400
@@ -325,7 +325,7 @@ sys_call_table:
 	PTR	sys32_sigreturn
 	PTR	sys32_clone			/* 4120 */
 	PTR	sys_setdomainname
-	PTR	sys_32_newuname
+	PTR	sys_newuname
 	PTR	sys_ni_syscall			/* sys_modify_ldt */
 	PTR	compat_sys_adjtimex
 	PTR	sys_mprotect			/* 4125 */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/signal32.c linux-libre-2.6.34-gnu1/arch/mips/kernel/signal32.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/signal32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/signal32.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <asm/system.h>
 #include <asm/fpu.h>
 #include <asm/war.h>
+#include <asm/vdso.h>
 
 #include "signal-common.h"
 
@@ -47,8 +48,6 @@ extern asmlinkage int fpu_emulator_resto
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
-#define __NR_O32_sigreturn		4119
-#define __NR_O32_rt_sigreturn		4193
 #define __NR_O32_restart_syscall        4253
 
 /* 32-bit compatibility types */
@@ -77,47 +76,20 @@ struct ucontext32 {
 	compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 };
 
-/*
- * Horribly complicated - with the bloody RM9000 workarounds enabled
- * the signal trampolines is moving to the end of the structure so we can
- * increase the alignment without breaking software compatibility.
- */
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
 struct sigframe32 {
 	u32 sf_ass[4];		/* argument save space for o32 */
-	u32 sf_code[2];		/* signal trampoline */
+	u32 sf_pad[2];		/* Was: signal trampoline */
 	struct sigcontext32 sf_sc;
 	compat_sigset_t sf_mask;
 };
 
 struct rt_sigframe32 {
 	u32 rs_ass[4];			/* argument save space for o32 */
-	u32 rs_code[2];			/* signal trampoline */
-	compat_siginfo_t rs_info;
-	struct ucontext32 rs_uc;
-};
-
-#else  /* ICACHE_REFILLS_WORKAROUND_WAR */
-
-struct sigframe32 {
-	u32 sf_ass[4];			/* argument save space for o32 */
-	u32 sf_pad[2];
-	struct sigcontext32 sf_sc;	/* hw context */
-	compat_sigset_t sf_mask;
-	u32 sf_code[8] ____cacheline_aligned;	/* signal trampoline */
-};
-
-struct rt_sigframe32 {
-	u32 rs_ass[4];			/* argument save space for o32 */
-	u32 rs_pad[2];
+	u32 rs_pad[2];			/* Was: signal trampoline */
 	compat_siginfo_t rs_info;
 	struct ucontext32 rs_uc;
-	u32 rs_code[8] __attribute__((aligned(32)));	/* signal trampoline */
 };
 
-#endif	/* !ICACHE_REFILLS_WORKAROUND_WAR */
-
 /*
  * sigcontext handlers
  */
@@ -598,8 +570,8 @@ badframe:
 	force_sig(SIGSEGV, current);
 }
 
-static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
-	int signr, sigset_t *set)
+static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
+			  struct pt_regs *regs, int signr, sigset_t *set)
 {
 	struct sigframe32 __user *frame;
 	int err = 0;
@@ -608,8 +580,6 @@ static int setup_frame_32(struct k_sigac
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 		goto give_sigsegv;
 
-	err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
-
 	err |= setup_sigcontext32(regs, &frame->sf_sc);
 	err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
 
@@ -630,7 +600,7 @@ static int setup_frame_32(struct k_sigac
 	regs->regs[ 5] = 0;
 	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
 	regs->regs[29] = (unsigned long) frame;
-	regs->regs[31] = (unsigned long) frame->sf_code;
+	regs->regs[31] = (unsigned long) sig_return;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -644,8 +614,9 @@ give_sigsegv:
 	return -EFAULT;
 }
 
-static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
-	int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
+			     struct pt_regs *regs, int signr, sigset_t *set,
+			     siginfo_t *info)
 {
 	struct rt_sigframe32 __user *frame;
 	int err = 0;
@@ -655,8 +626,6 @@ static int setup_rt_frame_32(struct k_si
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 		goto give_sigsegv;
 
-	err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
-
 	/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
 	err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
@@ -690,7 +659,7 @@ static int setup_rt_frame_32(struct k_si
 	regs->regs[ 5] = (unsigned long) &frame->rs_info;
 	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
 	regs->regs[29] = (unsigned long) frame;
-	regs->regs[31] = (unsigned long) frame->rs_code;
+	regs->regs[31] = (unsigned long) sig_return;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -709,7 +678,11 @@ give_sigsegv:
  */
 struct mips_abi mips_abi_32 = {
 	.setup_frame	= setup_frame_32,
+	.signal_return_offset =
+		offsetof(struct mips_vdso, o32_signal_trampoline),
 	.setup_rt_frame	= setup_rt_frame_32,
+	.rt_signal_return_offset =
+		offsetof(struct mips_vdso, o32_rt_signal_trampoline),
 	.restart	= __NR_O32_restart_syscall
 };
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/signal.c linux-libre-2.6.34-gnu1/arch/mips/kernel/signal.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/signal.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/signal.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <asm/ucontext.h>
 #include <asm/cpu-features.h>
 #include <asm/war.h>
+#include <asm/vdso.h>
 
 #include "signal-common.h"
 
@@ -44,47 +45,20 @@ extern asmlinkage int _restore_fp_contex
 extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
 extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
 
-/*
- * Horribly complicated - with the bloody RM9000 workarounds enabled
- * the signal trampolines is moving to the end of the structure so we can
- * increase the alignment without breaking software compatibility.
- */
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
 struct sigframe {
 	u32 sf_ass[4];		/* argument save space for o32 */
-	u32 sf_code[2];		/* signal trampoline */
+	u32 sf_pad[2];		/* Was: signal trampoline */
 	struct sigcontext sf_sc;
 	sigset_t sf_mask;
 };
 
 struct rt_sigframe {
 	u32 rs_ass[4];		/* argument save space for o32 */
-	u32 rs_code[2];		/* signal trampoline */
-	struct siginfo rs_info;
-	struct ucontext rs_uc;
-};
-
-#else
-
-struct sigframe {
-	u32 sf_ass[4];			/* argument save space for o32 */
-	u32 sf_pad[2];
-	struct sigcontext sf_sc;	/* hw context */
-	sigset_t sf_mask;
-	u32 sf_code[8] ____cacheline_aligned;	/* signal trampoline */
-};
-
-struct rt_sigframe {
-	u32 rs_ass[4];			/* argument save space for o32 */
-	u32 rs_pad[2];
+	u32 rs_pad[2];		/* Was: signal trampoline */
 	struct siginfo rs_info;
 	struct ucontext rs_uc;
-	u32 rs_code[8] ____cacheline_aligned;	/* signal trampoline */
 };
 
-#endif
-
 /*
  * Helper routines
  */
@@ -266,32 +240,6 @@ void __user *get_sigframe(struct k_sigac
 	return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
 }
 
-int install_sigtramp(unsigned int __user *tramp, unsigned int syscall)
-{
-	int err;
-
-	/*
-	 * Set up the return code ...
-	 *
-	 *         li      v0, __NR__foo_sigreturn
-	 *         syscall
-	 */
-
-	err = __put_user(0x24020000 + syscall, tramp + 0);
-	err |= __put_user(0x0000000c         , tramp + 1);
-	if (ICACHE_REFILLS_WORKAROUND_WAR) {
-		err |= __put_user(0, tramp + 2);
-		err |= __put_user(0, tramp + 3);
-		err |= __put_user(0, tramp + 4);
-		err |= __put_user(0, tramp + 5);
-		err |= __put_user(0, tramp + 6);
-		err |= __put_user(0, tramp + 7);
-	}
-	flush_cache_sigtramp((unsigned long) tramp);
-
-	return err;
-}
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
@@ -484,8 +432,8 @@ badframe:
 }
 
 #ifdef CONFIG_TRAD_SIGNALS
-static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
-	int signr, sigset_t *set)
+static int setup_frame(void *sig_return, struct k_sigaction *ka,
+		       struct pt_regs *regs, int signr, sigset_t *set)
 {
 	struct sigframe __user *frame;
 	int err = 0;
@@ -494,8 +442,6 @@ static int setup_frame(struct k_sigactio
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 		goto give_sigsegv;
 
-	err |= install_sigtramp(frame->sf_code, __NR_sigreturn);
-
 	err |= setup_sigcontext(regs, &frame->sf_sc);
 	err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
 	if (err)
@@ -515,7 +461,7 @@ static int setup_frame(struct k_sigactio
 	regs->regs[ 5] = 0;
 	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
 	regs->regs[29] = (unsigned long) frame;
-	regs->regs[31] = (unsigned long) frame->sf_code;
+	regs->regs[31] = (unsigned long) sig_return;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -529,8 +475,9 @@ give_sigsegv:
 }
 #endif
 
-static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
-	int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
+			  struct pt_regs *regs,	int signr, sigset_t *set,
+			  siginfo_t *info)
 {
 	struct rt_sigframe __user *frame;
 	int err = 0;
@@ -539,8 +486,6 @@ static int setup_rt_frame(struct k_sigac
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 		goto give_sigsegv;
 
-	err |= install_sigtramp(frame->rs_code, __NR_rt_sigreturn);
-
 	/* Create siginfo.  */
 	err |= copy_siginfo_to_user(&frame->rs_info, info);
 
@@ -573,7 +518,7 @@ static int setup_rt_frame(struct k_sigac
 	regs->regs[ 5] = (unsigned long) &frame->rs_info;
 	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
 	regs->regs[29] = (unsigned long) frame;
-	regs->regs[31] = (unsigned long) frame->rs_code;
+	regs->regs[31] = (unsigned long) sig_return;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -590,8 +535,11 @@ give_sigsegv:
 struct mips_abi mips_abi = {
 #ifdef CONFIG_TRAD_SIGNALS
 	.setup_frame	= setup_frame,
+	.signal_return_offset = offsetof(struct mips_vdso, signal_trampoline),
 #endif
 	.setup_rt_frame	= setup_rt_frame,
+	.rt_signal_return_offset =
+		offsetof(struct mips_vdso, rt_signal_trampoline),
 	.restart	= __NR_restart_syscall
 };
 
@@ -599,6 +547,8 @@ static int handle_signal(unsigned long s
 	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
 {
 	int ret;
+	struct mips_abi *abi = current->thread.abi;
+	void *vdso = current->mm->context.vdso;
 
 	switch(regs->regs[0]) {
 	case ERESTART_RESTARTBLOCK:
@@ -619,9 +569,11 @@ static int handle_signal(unsigned long s
 	regs->regs[0] = 0;		/* Don't deal with this again.  */
 
 	if (sig_uses_siginfo(ka))
-		ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
+		ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
+					  ka, regs, sig, oldset, info);
 	else
-		ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
+		ret = abi->setup_frame(vdso + abi->signal_return_offset,
+				       ka, regs, sig, oldset);
 
 	spin_lock_irq(&current->sighand->siglock);
 	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/signal-common.h linux-libre-2.6.34-gnu1/arch/mips/kernel/signal-common.h
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/signal-common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/signal-common.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,11 +26,6 @@
  */
 extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
 				 size_t frame_size);
-/*
- * install trampoline code to get back from the sig handler
- */
-extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall);
-
 /* Check and clear pending FPU exceptions in saved CSR */
 extern int fpcsr_pending(unsigned int __user *fpcsr);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/signal_n32.c linux-libre-2.6.34-gnu1/arch/mips/kernel/signal_n32.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/signal_n32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/signal_n32.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,13 +39,13 @@
 #include <asm/fpu.h>
 #include <asm/cpu-features.h>
 #include <asm/war.h>
+#include <asm/vdso.h>
 
 #include "signal-common.h"
 
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
-#define __NR_N32_rt_sigreturn		6211
 #define __NR_N32_restart_syscall	6214
 
 extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
@@ -67,27 +67,13 @@ struct ucontextn32 {
 	compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 };
 
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
-struct rt_sigframe_n32 {
-	u32 rs_ass[4];			/* argument save space for o32 */
-	u32 rs_code[2];			/* signal trampoline */
-	struct compat_siginfo rs_info;
-	struct ucontextn32 rs_uc;
-};
-
-#else  /* ICACHE_REFILLS_WORKAROUND_WAR */
-
 struct rt_sigframe_n32 {
 	u32 rs_ass[4];			/* argument save space for o32 */
-	u32 rs_pad[2];
+	u32 rs_pad[2];			/* Was: signal trampoline */
 	struct compat_siginfo rs_info;
 	struct ucontextn32 rs_uc;
-	u32 rs_code[8] ____cacheline_aligned;		/* signal trampoline */
 };
 
-#endif	/* !ICACHE_REFILLS_WORKAROUND_WAR */
-
 extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
 
 asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
@@ -173,7 +159,7 @@ badframe:
 	force_sig(SIGSEGV, current);
 }
 
-static int setup_rt_frame_n32(struct k_sigaction * ka,
+static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
 	struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
 {
 	struct rt_sigframe_n32 __user *frame;
@@ -184,8 +170,6 @@ static int setup_rt_frame_n32(struct k_s
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 		goto give_sigsegv;
 
-	install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);
-
 	/* Create siginfo.  */
 	err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
@@ -219,7 +203,7 @@ static int setup_rt_frame_n32(struct k_s
 	regs->regs[ 5] = (unsigned long) &frame->rs_info;
 	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
 	regs->regs[29] = (unsigned long) frame;
-	regs->regs[31] = (unsigned long) frame->rs_code;
+	regs->regs[31] = (unsigned long) sig_return;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -235,5 +219,7 @@ give_sigsegv:
 
 struct mips_abi mips_abi_n32 = {
 	.setup_rt_frame	= setup_rt_frame_n32,
+	.rt_signal_return_offset =
+		offsetof(struct mips_vdso, n32_rt_signal_trampoline),
 	.restart	= __NR_N32_restart_syscall
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/smtc.c linux-libre-2.6.34-gnu1/arch/mips/kernel/smtc.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/smtc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/smtc.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/module.h>
 #include <linux/ftrace.h>
+#include <linux/slab.h>
 
 #include <asm/cpu.h>
 #include <asm/processor.h>
@@ -181,7 +182,7 @@ static int vpemask[2][8] = {
 	{0, 0, 0, 0, 0, 0, 0, 1}
 };
 int tcnoprog[NR_CPUS];
-static atomic_t idle_hook_initialized = {0};
+static atomic_t idle_hook_initialized = ATOMIC_INIT(0);
 static int clock_hang_reported[NR_CPUS];
 
 #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/spinlock_test.c linux-libre-2.6.34-gnu1/arch/mips/kernel/spinlock_test.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/spinlock_test.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/spinlock_test.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,141 @@
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include <linux/hrtimer.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+
+static int ss_get(void *data, u64 *val)
+{
+	ktime_t start, finish;
+	int loops;
+	int cont;
+	DEFINE_RAW_SPINLOCK(ss_spin);
+
+	loops = 1000000;
+	cont = 1;
+
+	start = ktime_get();
+
+	while (cont) {
+		raw_spin_lock(&ss_spin);
+		loops--;
+		if (loops == 0)
+			cont = 0;
+		raw_spin_unlock(&ss_spin);
+	}
+
+	finish = ktime_get();
+
+	*val = ktime_us_delta(finish, start);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_ss, ss_get, NULL, "%llu\n");
+
+
+
+struct spin_multi_state {
+	raw_spinlock_t lock;
+	atomic_t start_wait;
+	atomic_t enter_wait;
+	atomic_t exit_wait;
+	int loops;
+};
+
+struct spin_multi_per_thread {
+	struct spin_multi_state *state;
+	ktime_t start;
+};
+
+static int multi_other(void *data)
+{
+	int loops;
+	int cont;
+	struct spin_multi_per_thread *pt = data;
+	struct spin_multi_state *s = pt->state;
+
+	loops = s->loops;
+	cont = 1;
+
+	atomic_dec(&s->enter_wait);
+
+	while (atomic_read(&s->enter_wait))
+		; /* spin */
+
+	pt->start = ktime_get();
+
+	atomic_dec(&s->start_wait);
+
+	while (atomic_read(&s->start_wait))
+		; /* spin */
+
+	while (cont) {
+		raw_spin_lock(&s->lock);
+		loops--;
+		if (loops == 0)
+			cont = 0;
+		raw_spin_unlock(&s->lock);
+	}
+
+	atomic_dec(&s->exit_wait);
+	while (atomic_read(&s->exit_wait))
+		; /* spin */
+	return 0;
+}
+
+static int multi_get(void *data, u64 *val)
+{
+	ktime_t finish;
+	struct spin_multi_state ms;
+	struct spin_multi_per_thread t1, t2;
+
+	ms.lock = __RAW_SPIN_LOCK_UNLOCKED("multi_get");
+	ms.loops = 1000000;
+
+	atomic_set(&ms.start_wait, 2);
+	atomic_set(&ms.enter_wait, 2);
+	atomic_set(&ms.exit_wait, 2);
+	t1.state = &ms;
+	t2.state = &ms;
+
+	kthread_run(multi_other, &t2, "multi_get");
+
+	multi_other(&t1);
+
+	finish = ktime_get();
+
+	*val = ktime_us_delta(finish, t1.start);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_multi, multi_get, NULL, "%llu\n");
+
+
+extern struct dentry *mips_debugfs_dir;
+static int __init spinlock_test(void)
+{
+	struct dentry *d;
+
+	if (!mips_debugfs_dir)
+		return -ENODEV;
+
+	d = debugfs_create_file("spin_single", S_IRUGO,
+				mips_debugfs_dir, NULL,
+				&fops_ss);
+	if (!d)
+		return -ENOMEM;
+
+	d = debugfs_create_file("spin_multi", S_IRUGO,
+				mips_debugfs_dir, NULL,
+				&fops_multi);
+	if (!d)
+		return -ENOMEM;
+
+	return 0;
+}
+device_initcall(spinlock_test);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/syscall.c linux-libre-2.6.34-gnu1/arch/mips/kernel/syscall.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/syscall.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/syscall.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/string.h>
 #include <linux/syscalls.h>
 #include <linux/file.h>
-#include <linux/slab.h>
 #include <linux/utsname.h>
 #include <linux/unistd.h>
 #include <linux/sem.h>
@@ -29,6 +28,7 @@
 #include <linux/module.h>
 #include <linux/ipc.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 
 #include <asm/asm.h>
 #include <asm/branch.h>
@@ -79,7 +79,11 @@ unsigned long arch_get_unmapped_area(str
 	int do_color_align;
 	unsigned long task_size;
 
-	task_size = STACK_TOP;
+#ifdef CONFIG_32BIT
+	task_size = TASK_SIZE;
+#else /* Must be CONFIG_64BIT*/
+	task_size = test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE;
+#endif
 
 	if (len > task_size)
 		return -ENOMEM;
@@ -215,48 +219,6 @@ out:
 	return error;
 }
 
-/*
- * Compacrapability ...
- */
-SYSCALL_DEFINE1(uname, struct old_utsname __user *, name)
-{
-	if (name && !copy_to_user(name, utsname(), sizeof (*name)))
-		return 0;
-	return -EFAULT;
-}
-
-/*
- * Compacrapability ...
- */
-SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
-{
-	int error;
-
-	if (!name)
-		return -EFAULT;
-	if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
-		return -EFAULT;
-
-	error = __copy_to_user(&name->sysname, &utsname()->sysname,
-			       __OLD_UTS_LEN);
-	error -= __put_user(0, name->sysname + __OLD_UTS_LEN);
-	error -= __copy_to_user(&name->nodename, &utsname()->nodename,
-				__OLD_UTS_LEN);
-	error -= __put_user(0, name->nodename + __OLD_UTS_LEN);
-	error -= __copy_to_user(&name->release, &utsname()->release,
-				__OLD_UTS_LEN);
-	error -= __put_user(0, name->release + __OLD_UTS_LEN);
-	error -= __copy_to_user(&name->version, &utsname()->version,
-				__OLD_UTS_LEN);
-	error -= __put_user(0, name->version + __OLD_UTS_LEN);
-	error -= __copy_to_user(&name->machine, &utsname()->machine,
-				__OLD_UTS_LEN);
-	error = __put_user(0, name->machine + __OLD_UTS_LEN);
-	error = error ? -EFAULT : 0;
-
-	return error;
-}
-
 SYSCALL_DEFINE1(set_thread_area, unsigned long, addr)
 {
 	struct thread_info *ti = task_thread_info(current);
@@ -407,94 +369,6 @@ _sys_sysmips(nabi_no_regargs struct pt_r
 }
 
 /*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second,
-	unsigned long, third, void __user *, ptr, long, fifth)
-{
-	int version, ret;
-
-	version = call >> 16; /* hack for backward compatibility */
-	call &= 0xffff;
-
-	switch (call) {
-	case SEMOP:
-		return sys_semtimedop(first, (struct sembuf __user *)ptr,
-		                      second, NULL);
-	case SEMTIMEDOP:
-		return sys_semtimedop(first, (struct sembuf __user *)ptr,
-				      second,
-				      (const struct timespec __user *)fifth);
-	case SEMGET:
-		return sys_semget(first, second, third);
-	case SEMCTL: {
-		union semun fourth;
-		if (!ptr)
-			return -EINVAL;
-		if (get_user(fourth.__pad, (void __user *__user *) ptr))
-			return -EFAULT;
-		return sys_semctl(first, second, third, fourth);
-	}
-
-	case MSGSND:
-		return sys_msgsnd(first, (struct msgbuf __user *) ptr,
-				  second, third);
-	case MSGRCV:
-		switch (version) {
-		case 0: {
-			struct ipc_kludge tmp;
-			if (!ptr)
-				return -EINVAL;
-
-			if (copy_from_user(&tmp,
-					   (struct ipc_kludge __user *) ptr,
-					   sizeof(tmp)))
-				return -EFAULT;
-			return sys_msgrcv(first, tmp.msgp, second,
-					  tmp.msgtyp, third);
-		}
-		default:
-			return sys_msgrcv(first,
-					  (struct msgbuf __user *) ptr,
-					  second, fifth, third);
-		}
-	case MSGGET:
-		return sys_msgget((key_t) first, second);
-	case MSGCTL:
-		return sys_msgctl(first, second,
-				  (struct msqid_ds __user *) ptr);
-
-	case SHMAT:
-		switch (version) {
-		default: {
-			unsigned long raddr;
-			ret = do_shmat(first, (char __user *) ptr, second,
-				       &raddr);
-			if (ret)
-				return ret;
-			return put_user(raddr, (unsigned long __user *) third);
-		}
-		case 1:	/* iBCS2 emulator entry point */
-			if (!segment_eq(get_fs(), get_ds()))
-				return -EINVAL;
-			return do_shmat(first, (char __user *) ptr, second,
-				        (unsigned long *) third);
-		}
-	case SHMDT:
-		return sys_shmdt((char __user *)ptr);
-	case SHMGET:
-		return sys_shmget(first, second, third);
-	case SHMCTL:
-		return sys_shmctl(first, second,
-				  (struct shmid_ds __user *) ptr);
-	default:
-		return -ENOSYS;
-	}
-}
-
-/*
  * No implemented yet ...
  */
 SYSCALL_DEFINE3(cachectl, char *, addr, int, nbytes, int, op)
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/traps.c linux-libre-2.6.34-gnu1/arch/mips/kernel/traps.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/traps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/traps.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,6 +50,7 @@
 #include <asm/types.h>
 #include <asm/stacktrace.h>
 #include <asm/irq.h>
+#include <asm/uasm.h>
 
 extern void check_wait(void);
 extern asmlinkage void r4k_wait(void);
@@ -351,9 +352,10 @@ void show_registers(const struct pt_regs
 
 static DEFINE_SPINLOCK(die_lock);
 
-void __noreturn die(const char * str, const struct pt_regs * regs)
+void __noreturn die(const char * str, struct pt_regs * regs)
 {
 	static int die_counter;
+	int sig = SIGSEGV;
 #ifdef CONFIG_MIPS_MT_SMTC
 	unsigned long dvpret = dvpe();
 #endif /* CONFIG_MIPS_MT_SMTC */
@@ -364,6 +366,10 @@ void __noreturn die(const char * str, co
 #ifdef CONFIG_MIPS_MT_SMTC
 	mips_mt_regdump(dvpret);
 #endif /* CONFIG_MIPS_MT_SMTC */
+
+	if (notify_die(DIE_OOPS, str, regs, 0, current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
+		sig = 0;
+
 	printk("%s[#%d]:\n", str, ++die_counter);
 	show_registers(regs);
 	add_taint(TAINT_DIE);
@@ -378,7 +384,7 @@ void __noreturn die(const char * str, co
 		panic("Fatal exception");
 	}
 
-	do_exit(SIGSEGV);
+	do_exit(sig);
 }
 
 extern struct exception_table_entry __start___dbe_table[];
@@ -1271,21 +1277,25 @@ unsigned long ebase;
 unsigned long exception_handlers[32];
 unsigned long vi_handlers[64];
 
-/*
- * As a side effect of the way this is implemented we're limited
- * to interrupt handlers in the address range from
- * KSEG0 <= x < KSEG0 + 256mb on the Nevada.  Oh well ...
- */
-void *set_except_vector(int n, void *addr)
+void __init *set_except_vector(int n, void *addr)
 {
 	unsigned long handler = (unsigned long) addr;
 	unsigned long old_handler = exception_handlers[n];
 
 	exception_handlers[n] = handler;
 	if (n == 0 && cpu_has_divec) {
-		*(u32 *)(ebase + 0x200) = 0x08000000 |
-					  (0x03ffffff & (handler >> 2));
-		local_flush_icache_range(ebase + 0x200, ebase + 0x204);
+		unsigned long jump_mask = ~((1 << 28) - 1);
+		u32 *buf = (u32 *)(ebase + 0x200);
+		unsigned int k0 = 26;
+		if ((handler & jump_mask) == ((ebase + 0x200) & jump_mask)) {
+			uasm_i_j(&buf, handler & ~jump_mask);
+			uasm_i_nop(&buf);
+		} else {
+			UASM_i_LA(&buf, k0, handler);
+			uasm_i_jr(&buf, k0);
+			uasm_i_nop(&buf);
+		}
+		local_flush_icache_range(ebase + 0x200, (unsigned long)buf);
 	}
 	return (void *)old_handler;
 }
@@ -1552,12 +1562,7 @@ static char panic_null_cerr[] __cpuinitd
 void __cpuinit set_uncached_handler(unsigned long offset, void *addr,
 	unsigned long size)
 {
-#ifdef CONFIG_32BIT
-	unsigned long uncached_ebase = KSEG1ADDR(ebase);
-#endif
-#ifdef CONFIG_64BIT
-	unsigned long uncached_ebase = TO_UNCAC(ebase);
-#endif
+	unsigned long uncached_ebase = CKSEG1ADDR(ebase);
 
 	if (!addr)
 		panic(panic_null_cerr);
@@ -1594,7 +1599,7 @@ void __init trap_init(void)
 		ebase = (unsigned long)
 			__alloc_bootmem(size, 1 << fls(size), 0);
 	} else {
-		ebase = CAC_BASE;
+		ebase = CKSEG0;
 		if (cpu_has_mips_r2)
 			ebase += (read_c0_ebase() & 0x3ffff000);
 	}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/vdso.c linux-libre-2.6.34-gnu1/arch/mips/kernel/vdso.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/vdso.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/vdso.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,112 @@
+/*
+ * 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, 2010 Cavium Networks, Inc.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/binfmts.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/unistd.h>
+
+#include <asm/vdso.h>
+#include <asm/uasm.h>
+
+/*
+ * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
+ */
+#define __NR_O32_sigreturn		4119
+#define __NR_O32_rt_sigreturn		4193
+#define __NR_N32_rt_sigreturn		6211
+
+static struct page *vdso_page;
+
+static void __init install_trampoline(u32 *tramp, unsigned int sigreturn)
+{
+	uasm_i_addiu(&tramp, 2, 0, sigreturn);	/* li v0, sigreturn */
+	uasm_i_syscall(&tramp, 0);
+}
+
+static int __init init_vdso(void)
+{
+	struct mips_vdso *vdso;
+
+	vdso_page = alloc_page(GFP_KERNEL);
+	if (!vdso_page)
+		panic("Cannot allocate vdso");
+
+	vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL);
+	if (!vdso)
+		panic("Cannot map vdso");
+	clear_page(vdso);
+
+	install_trampoline(vdso->rt_signal_trampoline, __NR_rt_sigreturn);
+#ifdef CONFIG_32BIT
+	install_trampoline(vdso->signal_trampoline, __NR_sigreturn);
+#else
+	install_trampoline(vdso->n32_rt_signal_trampoline,
+			   __NR_N32_rt_sigreturn);
+	install_trampoline(vdso->o32_signal_trampoline, __NR_O32_sigreturn);
+	install_trampoline(vdso->o32_rt_signal_trampoline,
+			   __NR_O32_rt_sigreturn);
+#endif
+
+	vunmap(vdso);
+
+	pr_notice("init_vdso successfull\n");
+
+	return 0;
+}
+device_initcall(init_vdso);
+
+static unsigned long vdso_addr(unsigned long start)
+{
+	return STACK_TOP;
+}
+
+int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+{
+	int ret;
+	unsigned long addr;
+	struct mm_struct *mm = current->mm;
+
+	down_write(&mm->mmap_sem);
+
+	addr = vdso_addr(mm->start_stack);
+
+	addr = get_unmapped_area(NULL, addr, PAGE_SIZE, 0, 0);
+	if (IS_ERR_VALUE(addr)) {
+		ret = addr;
+		goto up_fail;
+	}
+
+	ret = install_special_mapping(mm, addr, PAGE_SIZE,
+				      VM_READ|VM_EXEC|
+				      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
+				      VM_ALWAYSDUMP,
+				      &vdso_page);
+
+	if (ret)
+		goto up_fail;
+
+	mm->context.vdso = (void *)addr;
+
+up_fail:
+	up_write(&mm->mmap_sem);
+	return ret;
+}
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+	if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
+		return "[vdso]";
+	return NULL;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/kernel/vpe.c linux-libre-2.6.34-gnu1/arch/mips/kernel/vpe.c
--- linux-libre-2.6.33-gnu1/arch/mips/kernel/vpe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/kernel/vpe.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,7 +38,6 @@
 #include <linux/vmalloc.h>
 #include <linux/elf.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/moduleloader.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/lasat/picvue.h linux-libre-2.6.34-gnu1/arch/mips/lasat/picvue.h
--- linux-libre-2.6.33-gnu1/arch/mips/lasat/picvue.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/lasat/picvue.h	2010-05-16 17:17:36.000000000 -0400
@@ -42,4 +42,3 @@ void pvc_move(u8 cmd);
 
 void pvc_clear(void);
 void pvc_home(void);
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/lib/delay.c linux-libre-2.6.34-gnu1/arch/mips/lib/delay.c
--- linux-libre-2.6.33-gnu1/arch/mips/lib/delay.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/lib/delay.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,7 @@ EXPORT_SYMBOL(__delay);
 
 void __udelay(unsigned long us)
 {
-	unsigned int lpj = current_cpu_data.udelay_val;
+	unsigned int lpj = raw_current_cpu_data.udelay_val;
 
 	__delay((us * 0x000010c7ull * HZ * lpj) >> 32);
 }
@@ -49,7 +49,7 @@ EXPORT_SYMBOL(__udelay);
 
 void __ndelay(unsigned long ns)
 {
-	unsigned int lpj = current_cpu_data.udelay_val;
+	unsigned int lpj = raw_current_cpu_data.udelay_val;
 
 	__delay((ns * 0x00000005ull * HZ * lpj) >> 32);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/lib/libgcc.h linux-libre-2.6.34-gnu1/arch/mips/lib/libgcc.h
--- linux-libre-2.6.33-gnu1/arch/mips/lib/libgcc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/lib/libgcc.h	2010-05-16 17:17:36.000000000 -0400
@@ -17,8 +17,7 @@ struct DWstruct {
 #error I feel sick.
 #endif
 
-typedef union
-{
+typedef union {
 	struct DWstruct s;
 	long long ll;
 } DWunion;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cmdline.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cmdline.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cmdline.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cmdline.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,7 @@
  * Author: Fuxin Zhang, zhangfx@lemote.com
  *
  * Copyright (C) 2009 Lemote Inc.
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Author: Wu Zhangjin, wuzhangjin@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
@@ -21,12 +21,11 @@
 
 #include <loongson.h>
 
-int prom_argc;
-/* pmon passes arguments in 32bit pointers */
-int *_prom_argv;
-
 void __init prom_init_cmdline(void)
 {
+	int prom_argc;
+	/* pmon passes arguments in 32bit pointers */
+	int *_prom_argv;
 	int i;
 	long l;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_acc.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cs5536/cs5536_acc.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_acc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cs5536/cs5536_acc.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  * Author : jlliu, liujl@lemote.com
  *
  * Copyright (C) 2009 Lemote, Inc.
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Author: Wu Zhangjin, wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_ehci.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cs5536/cs5536_ehci.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_ehci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cs5536/cs5536_ehci.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  * Author : jlliu, liujl@lemote.com
  *
  * Copyright (C) 2009 Lemote, Inc.
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Author: Wu Zhangjin, wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_ide.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cs5536/cs5536_ide.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_ide.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cs5536/cs5536_ide.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  * Author : jlliu, liujl@lemote.com
  *
  * Copyright (C) 2009 Lemote, Inc.
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Author: Wu Zhangjin, wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_isa.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cs5536/cs5536_isa.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_isa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cs5536/cs5536_isa.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  * Author : jlliu, liujl@lemote.com
  *
  * Copyright (C) 2009 Lemote, Inc.
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Author: Wu Zhangjin, wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  * Author: Yanhua, yanh@lemote.com
  *
  * Copyright (C) 2009 Lemote Inc.
- * Author: Wu zhangjin, wuzj@lemote.com
+ * Author: Wu zhangjin, wuzhangjin@gmail.com
  *
  * Reference: AMD Geode(TM) CS5536 Companion Device Data Book
  *
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_ohci.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cs5536/cs5536_ohci.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_ohci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cs5536/cs5536_ohci.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  * Author : jlliu, liujl@lemote.com
  *
  * Copyright (C) 2009 Lemote, Inc.
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Author: Wu Zhangjin, wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_pci.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cs5536/cs5536_pci.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/cs5536/cs5536_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  * Author : jlliu, liujl@lemote.com
  *
  * Copyright (C) 2009 Lemote, Inc.
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Author: Wu Zhangjin, wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/early_printk.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/early_printk.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/early_printk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/early_printk.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  *
  *  Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
  *  Copyright (c) 2009 Lemote Inc.
- *  Author: Wu Zhangjin, wuzj@lemote.com
+ *  Author: Wu Zhangjin, wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/env.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/env.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/env.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/env.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,8 +9,8 @@
  * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
  * Author: Fuxin Zhang, zhangfx@lemote.com
  *
- * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@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
@@ -23,13 +23,10 @@
 
 #include <loongson.h>
 
-unsigned long bus_clock, cpu_clock_freq;
+unsigned long cpu_clock_freq;
 EXPORT_SYMBOL(cpu_clock_freq);
 unsigned long memsize, highmemsize;
 
-/* pmon passes arguments in 32bit pointers */
-int *_prom_envp;
-
 #define parse_even_earlier(res, option, p)				\
 do {									\
 	if (strncmp(option, (char *)p, strlen(option)) == 0)		\
@@ -39,6 +36,10 @@ do {									\
 
 void __init prom_init_env(void)
 {
+	/* pmon passes arguments in 32bit pointers */
+	int *_prom_envp;
+	unsigned long bus_clock;
+	unsigned int processor_id;
 	long l;
 
 	/* firmware arguments are initialized in head.S */
@@ -55,6 +56,22 @@ void __init prom_init_env(void)
 	}
 	if (memsize == 0)
 		memsize = 256;
+	if (bus_clock == 0)
+		bus_clock = 66000000;
+	if (cpu_clock_freq == 0) {
+		processor_id = (&current_cpu_data)->processor_id;
+		switch (processor_id & PRID_REV_MASK) {
+		case PRID_REV_LOONGSON2E:
+			cpu_clock_freq = 533080000;
+			break;
+		case PRID_REV_LOONGSON2F:
+			cpu_clock_freq = 797000000;
+			break;
+		default:
+			cpu_clock_freq = 100000000;
+			break;
+		}
+	}
 
 	pr_info("busclock=%ld, cpuclock=%ld, memsize=%ld, highmemsize=%ld\n",
 		bus_clock, cpu_clock_freq, memsize, highmemsize);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/init.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/init.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2009 Lemote Inc.
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Author: Wu Zhangjin, wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/machtype.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/machtype.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/machtype.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/machtype.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
  *
  * Copyright (c) 2009 Zhang Le <r0bertz@gentoo.org>
  *
@@ -24,7 +24,7 @@ static const char *system_types[] = {
 	[MACH_LEMOTE_FL2F]              "lemote-fuloong-2f-box",
 	[MACH_LEMOTE_ML2F7]             "lemote-mengloong-2f-7inches",
 	[MACH_LEMOTE_YL2F89]            "lemote-yeeloong-2f-8.9inches",
-	[MACH_DEXXON_GDIUM2F10]         "dexxon-gidum-2f-10inches",
+	[MACH_DEXXON_GDIUM2F10]         "dexxon-gdium-2f",
 	[MACH_LEMOTE_NAS]		"lemote-nas-2f",
 	[MACH_LEMOTE_LL2F]              "lemote-lynloong-2f",
 	[MACH_LOONGSON_END]             NULL,
@@ -35,6 +35,10 @@ const char *get_system_type(void)
 	return system_types[mips_machtype];
 }
 
+void __weak __init mach_prom_init_machtype(void)
+{
+}
+
 void __init prom_init_machtype(void)
 {
 	char *p, str[MACHTYPE_LEN];
@@ -43,8 +47,10 @@ void __init prom_init_machtype(void)
 	mips_machtype = LOONGSON_MACHTYPE;
 
 	p = strstr(arcs_cmdline, "machtype=");
-	if (!p)
+	if (!p) {
+		mach_prom_init_machtype();
 		return;
+	}
 	p += strlen("machtype=");
 	strncpy(str, p, MACHTYPE_LEN);
 	p = strstr(str, " ");
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/mem.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/mem.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/mem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/mem.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,10 +16,11 @@
 
 void __init prom_init_memory(void)
 {
-    add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
+	add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
+
+	add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize <<
+				20), BOOT_MEM_RESERVED);
 
-    add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize <<
-			    20), BOOT_MEM_RESERVED);
 #ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
 	{
 		int bit;
@@ -74,7 +75,7 @@ pgprot_t phys_mem_access_prot(struct fil
 	unsigned long end = offset + size;
 
 	if (__uncached_access(file, offset)) {
-		if (((uca_start && offset) >= uca_start) &&
+		if (uca_start && (offset >= uca_start) &&
 		    (end <= uca_end))
 			return __pgprot((pgprot_val(vma_prot) &
 					 ~_CACHE_MASK) |
@@ -95,7 +96,7 @@ static int __init find_vga_mem_init(void
 		return 0;
 
 	for_each_pci_dev(dev) {
-		if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
+		if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
 			for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
 				r = &dev->resource[idx];
 				if (!r->start && r->end)
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/platform.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/platform.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/platform.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/platform.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2009 Lemote Inc.
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Author: Wu Zhangjin, wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/pm.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/pm.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/pm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  * loongson-specific suspend support
  *
  *  Copyright (C) 2009 Lemote Inc.
- *  Author: Wu Zhangjin <wuzj@lemote.com>
+ *  Author: Wu Zhangjin <wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/reset.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/reset.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/reset.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/reset.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,8 +6,8 @@
  *
  * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
  * Author: Fuxin Zhang, zhangfx@lemote.com
- * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
- * Author: Zhangjin Wu, wuzj@lemote.com
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Zhangjin Wu, wuzhangjin@gmail.com
  */
 #include <linux/init.h>
 #include <linux/pm.h>
@@ -16,27 +16,53 @@
 
 #include <loongson.h>
 
+static inline void loongson_reboot(void)
+{
+#ifndef CONFIG_CPU_JUMP_WORKAROUNDS
+	((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
+#else
+	void (*func)(void);
+
+	func = (void *)ioremap_nocache(LOONGSON_BOOT_BASE, 4);
+
+	__asm__ __volatile__(
+	"       .set    noat                                            \n"
+	"       jr      %[func]                                         \n"
+	"       .set    at                                              \n"
+	: /* No outputs */
+	: [func] "r" (func));
+#endif
+}
+
 static void loongson_restart(char *command)
 {
 	/* do preparation for reboot */
 	mach_prepare_reboot();
 
 	/* reboot via jumping to boot base address */
-	((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
+	loongson_reboot();
 }
 
-static void loongson_halt(void)
+static void loongson_poweroff(void)
 {
 	mach_prepare_shutdown();
-	while (1)
-		;
+	unreachable();
+}
+
+static void loongson_halt(void)
+{
+	pr_notice("\n\n** You can safely turn off the power now **\n\n");
+	while (1) {
+		if (cpu_wait)
+			cpu_wait();
+	}
 }
 
 static int __init mips_reboot_setup(void)
 {
 	_machine_restart = loongson_restart;
 	_machine_halt = loongson_halt;
-	pm_power_off = loongson_halt;
+	pm_power_off = loongson_poweroff;
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/serial.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/serial.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,7 @@
  *
  * Copyright (C) 2009 Lemote, Inc.
  * Author: Yan hua (yanhua@lemote.com)
- * Author: Wu Zhangjin (wuzj@lemote.com)
+ * Author: Wu Zhangjin (wuzhangjin@gmail.com)
  */
 
 #include <linux/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/setup.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,15 +41,12 @@ void __init plat_mem_setup(void)
 	conswitchp = &vga_con;
 
 	screen_info = (struct screen_info) {
-		0, 25,		/* orig-x, orig-y */
-		    0,		/* unused */
-		    0,		/* orig-video-page */
-		    0,		/* orig-video-mode */
-		    80,		/* orig-video-cols */
-		    0, 0, 0,	/* ega_ax, ega_bx, ega_cx */
-		    25,		/* orig-video-lines */
-		    VIDEO_TYPE_VGAC,	/* orig-video-isVGA */
-		    16		/* orig-video-points */
+		.orig_x			= 0,
+		.orig_y			= 25,
+		.orig_video_cols	= 80,
+		.orig_video_lines	= 25,
+		.orig_video_isVGA	= VIDEO_TYPE_VGAC,
+		.orig_video_points	= 16,
 	};
 #elif defined(CONFIG_DUMMY_CONSOLE)
 	conswitchp = &dummy_con;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/time.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/time.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,8 +2,8 @@
  * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
  * Author: Fuxin Zhang, zhangfx@lemote.com
  *
- * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/common/uart_base.c linux-libre-2.6.34-gnu1/arch/mips/loongson/common/uart_base.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/common/uart_base.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/common/uart_base.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2009 Lemote Inc.
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Author: Wu Zhangjin, wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/fuloong-2e/reset.c linux-libre-2.6.34-gnu1/arch/mips/loongson/fuloong-2e/reset.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/fuloong-2e/reset.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/fuloong-2e/reset.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,8 +1,8 @@
 /* Board-specific reboot/shutdown routines
  * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
  *
- * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/ec_kb3310b.c linux-libre-2.6.34-gnu1/arch/mips/loongson/lemote-2f/ec_kb3310b.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/ec_kb3310b.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/lemote-2f/ec_kb3310b.c	2010-05-16 17:17:36.000000000 -0400
@@ -75,6 +75,8 @@ int ec_query_seq(unsigned char cmd)
 		udelay(EC_REG_DELAY);
 	}
 
+	spin_unlock_irqrestore(&port_access_lock, flags);
+
 	if (timeout <= 0) {
 		printk(KERN_ERR "%s: deadable error : timeout...\n", __func__);
 		ret = -EINVAL;
@@ -83,8 +85,6 @@ int ec_query_seq(unsigned char cmd)
 			   "(%x/%d)ec issued command %d status : 0x%x\n",
 			   timeout, EC_CMD_TIMEOUT - timeout, cmd, status);
 
-	spin_unlock_irqrestore(&port_access_lock, flags);
-
 	return ret;
 }
 EXPORT_SYMBOL_GPL(ec_query_seq);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/irq.c linux-libre-2.6.34-gnu1/arch/mips/loongson/lemote-2f/irq.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/lemote-2f/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,7 +38,7 @@ int mach_i8259_irq(void)
 	irq = -1;
 
 	if ((LOONGSON_INTISR & LOONGSON_INTEN) & LOONGSON_INT_BIT_INT0) {
-		spin_lock(&i8259A_lock);
+		raw_spin_lock(&i8259A_lock);
 		isr = inb(PIC_MASTER_CMD) &
 			~inb(PIC_MASTER_IMR) & ~(1 << PIC_CASCADE_IR);
 		if (!isr)
@@ -56,7 +56,7 @@ int mach_i8259_irq(void)
 			if (~inb(PIC_MASTER_ISR) & 0x80)
 				irq = -1;
 		}
-		spin_unlock(&i8259A_lock);
+		raw_spin_unlock(&i8259A_lock);
 	}
 
 	return irq;
@@ -79,7 +79,7 @@ void mach_irq_dispatch(unsigned int pend
 	if (pending & CAUSEF_IP7)
 		do_IRQ(LOONGSON_TIMER_IRQ);
 	else if (pending & CAUSEF_IP6) {	/* North Bridge, Perf counter */
-#ifdef CONFIG_OPROFILE
+#if defined(CONFIG_OPROFILE) || defined(CONFIG_OPROFILE_MODULE)
 		do_IRQ(LOONGSON2_PERFCNT_IRQ);
 #endif
 		bonito_irqdispatch();
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/machtype.c linux-libre-2.6.34-gnu1/arch/mips/loongson/lemote-2f/machtype.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/machtype.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/lemote-2f/machtype.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@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 <asm/bootinfo.h>
+
+#include <loongson.h>
+
+void __init mach_prom_init_machtype(void)
+{
+	/* We share the same kernel image file among Lemote 2F family
+	 * of machines, and provide the machtype= kernel command line
+	 * to users to indicate their machine, this command line will
+	 * be passed by the latest PMON automatically. and fortunately,
+	 * up to now, we can get the machine type from the PMON_VER=
+	 * commandline directly except the NAS machine, In the old
+	 * machines, this will help the users a lot.
+	 *
+	 * If no "machtype=" passed, get machine type from "PMON_VER=".
+	 * 	PMON_VER=LM8089		Lemote 8.9'' netbook
+	 * 	         LM8101		Lemote 10.1'' netbook
+	 * 	(The above two netbooks have the same kernel support)
+	 *	         LM6XXX		Lemote FuLoong(2F) box series
+	 *	         LM9XXX		Lemote LynLoong PC series
+	 */
+	if (strstr(arcs_cmdline, "PMON_VER=LM")) {
+		if (strstr(arcs_cmdline, "PMON_VER=LM8"))
+			mips_machtype = MACH_LEMOTE_YL2F89;
+		else if (strstr(arcs_cmdline, "PMON_VER=LM6"))
+			mips_machtype = MACH_LEMOTE_FL2F;
+		else if (strstr(arcs_cmdline, "PMON_VER=LM9"))
+			mips_machtype = MACH_LEMOTE_LL2F;
+		else
+			mips_machtype = MACH_LEMOTE_NAS;
+
+		strcat(arcs_cmdline, " machtype=");
+		strcat(arcs_cmdline, get_system_type());
+		strcat(arcs_cmdline, " ");
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/Makefile linux-libre-2.6.34-gnu1/arch/mips/loongson/lemote-2f/Makefile
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/lemote-2f/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
 # Makefile for lemote loongson2f family machines
 #
 
-obj-y += irq.o reset.o ec_kb3310b.o
+obj-y += machtype.o irq.o reset.o ec_kb3310b.o
 
 #
 # Suspend Support
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/pm.c linux-libre-2.6.34-gnu1/arch/mips/loongson/lemote-2f/pm.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/pm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/lemote-2f/pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  *  Lemote loongson2f family machines' specific suspend support
  *
  *  Copyright (C) 2009 Lemote Inc.
- *  Author: Wu Zhangjin <wuzj@lemote.com>
+ *  Author: Wu Zhangjin <wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/reset.c linux-libre-2.6.34-gnu1/arch/mips/loongson/lemote-2f/reset.c
--- linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/reset.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/loongson/lemote-2f/reset.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,7 @@
  * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
  *
  * Copyright (C) 2009 Lemote Inc.
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Author: Wu Zhangjin, wuzhangjin@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
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/Makefile linux-libre-2.6.34-gnu1/arch/mips/Makefile
--- linux-libre-2.6.33-gnu1/arch/mips/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -136,6 +136,19 @@ cflags-$(CONFIG_CPU_LOONGSON2E) += \
 	$(call cc-option,-march=loongson2e,-march=r4600)
 cflags-$(CONFIG_CPU_LOONGSON2F) += \
 	$(call cc-option,-march=loongson2f,-march=r4600)
+# enable the workarounds for loongson2f
+ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
+  ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-nop,),)
+    $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop)
+  else
+    cflags-$(CONFIG_CPU_NOP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-nop
+  endif
+  ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-jump,),)
+    $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-jump)
+  else
+    cflags-$(CONFIG_CPU_JUMP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-jump
+  endif
+endif
 
 cflags-$(CONFIG_CPU_MIPS32_R1)	+= $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
 			-Wa,-mips32 -Wa,--trap
@@ -185,6 +198,15 @@ libs-$(CONFIG_SNIPROM)		+= arch/mips/fw/
 libs-y				+= arch/mips/fw/lib/
 
 #
+# Kernel compression
+#
+ifdef SYS_SUPPORTS_ZBOOT
+COMPRESSION_FNAME		= vmlinuz
+else
+COMPRESSION_FNAME		= vmlinux
+endif
+
+#
 # Board-dependent options and extra files
 #
 
@@ -332,11 +354,11 @@ load-$(CONFIG_WR_PPMC)		+= 0xffffffff801
 #
 # Loongson family
 #
-core-$(CONFIG_MACH_LOONGSON) +=arch/mips/loongson/
+core-$(CONFIG_MACH_LOONGSON) += arch/mips/loongson/
 cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson \
                     -mno-branch-likely
-load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000
-load-$(CONFIG_LEMOTE_MACH2F) +=0xffffffff80200000
+load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000
+load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000
 
 #
 # MIPS Malta board
@@ -344,7 +366,7 @@ load-$(CONFIG_LEMOTE_MACH2F) +=0xfffffff
 core-$(CONFIG_MIPS_MALTA)	+= arch/mips/mti-malta/
 cflags-$(CONFIG_MIPS_MALTA)	+= -I$(srctree)/arch/mips/include/asm/mach-malta
 load-$(CONFIG_MIPS_MALTA)	+= 0xffffffff80100000
-all-$(CONFIG_MIPS_MALTA)	:= vmlinuz.bin
+all-$(CONFIG_MIPS_MALTA)	:= $(COMPRESSION_FNAME).bin
 
 #
 # MIPS SIM
@@ -594,7 +616,7 @@ load-$(CONFIG_SNI_RM)		+= 0xffffffff8060
 else
 load-$(CONFIG_SNI_RM)		+= 0xffffffff80030000
 endif
-all-$(CONFIG_SNI_RM)		:= vmlinuz.ecoff
+all-$(CONFIG_SNI_RM)		:= $(COMPRESSION_FNAME).ecoff
 
 #
 # Common TXx9
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/math-emu/cp1emu.c linux-libre-2.6.34-gnu1/arch/mips/math-emu/cp1emu.c
--- linux-libre-2.6.33-gnu1/arch/mips/math-emu/cp1emu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/math-emu/cp1emu.c	2010-05-16 17:17:36.000000000 -0400
@@ -78,6 +78,9 @@ DEFINE_PER_CPU(struct mips_fpu_emulator_
 #define FPCREG_RID	0	/* $0  = revision id */
 #define FPCREG_CSR	31	/* $31 = csr */
 
+/* Determine rounding mode from the RM bits of the FCSR */
+#define modeindex(v) ((v) & FPU_CSR_RM)
+
 /* Convert Mips rounding mode (0..3) to IEEE library modes. */
 static const unsigned char ieee_rm[4] = {
 	[FPU_CSR_RN] = IEEE754_RN,
@@ -384,10 +387,14 @@ static int cop1Emulate(struct pt_regs *x
 					(void *) (xcp->cp0_epc),
 					MIPSInst_RT(ir), value);
 #endif
-				value &= (FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
-				ctx->fcr31 &= ~(FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
-				/* convert to ieee library modes */
-				ctx->fcr31 |= (value & ~0x3) | ieee_rm[value & 0x3];
+
+				/*
+				 * Don't write reserved bits,
+				 * and convert to ieee library modes
+				 */
+				ctx->fcr31 = (value &
+						~(FPU_CSR_RSVD | FPU_CSR_RM)) |
+						ieee_rm[modeindex(value)];
 			}
 			if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
 				return SIGFPE;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/math-emu/ieee754d.c linux-libre-2.6.34-gnu1/arch/mips/math-emu/ieee754d.c
--- linux-libre-2.6.33-gnu1/arch/mips/math-emu/ieee754d.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/math-emu/ieee754d.c	2010-05-16 17:17:36.000000000 -0400
@@ -135,4 +135,3 @@ ieee754sp ieee754sp_dump(char *m, ieee75
 	printk("\n");
 	return x;
 }
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/math-emu/ieee754dp.c linux-libre-2.6.34-gnu1/arch/mips/math-emu/ieee754dp.c
--- linux-libre-2.6.33-gnu1/arch/mips/math-emu/ieee754dp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/math-emu/ieee754dp.c	2010-05-16 17:17:36.000000000 -0400
@@ -148,7 +148,6 @@ ieee754dp ieee754dp_format(int sn, int x
 
 			switch(ieee754_csr.rm) {
 			case IEEE754_RN:
-				return ieee754dp_zero(sn);
 			case IEEE754_RZ:
 				return ieee754dp_zero(sn);
 			case IEEE754_RU:    /* toward +Infinity */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/math-emu/ieee754sp.c linux-libre-2.6.34-gnu1/arch/mips/math-emu/ieee754sp.c
--- linux-libre-2.6.33-gnu1/arch/mips/math-emu/ieee754sp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/math-emu/ieee754sp.c	2010-05-16 17:17:36.000000000 -0400
@@ -149,7 +149,6 @@ ieee754sp ieee754sp_format(int sn, int x
 
 			switch(ieee754_csr.rm) {
 			case IEEE754_RN:
-				return ieee754sp_zero(sn);
 			case IEEE754_RZ:
 				return ieee754sp_zero(sn);
 			case IEEE754_RU:      /* toward +Infinity */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/math-emu/ieee754xcpt.c linux-libre-2.6.34-gnu1/arch/mips/math-emu/ieee754xcpt.c
--- linux-libre-2.6.33-gnu1/arch/mips/math-emu/ieee754xcpt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/math-emu/ieee754xcpt.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,4 +46,3 @@ void ieee754_xcpt(struct ieee754xctx *xc
 	printk(KERN_DEBUG "floating point exception in \"%s\", type=%s\n",
 		xcp->op, rtnames[xcp->rt]);
 }
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/mipssim/sim_int.c linux-libre-2.6.34-gnu1/arch/mips/mipssim/sim_int.c
--- linux-libre-2.6.33-gnu1/arch/mips/mipssim/sim_int.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/mipssim/sim_int.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
  */
 #include <linux/init.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <asm/mips-boards/simint.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/mm/cache.c linux-libre-2.6.34-gnu1/arch/mips/mm/cache.c
--- linux-libre-2.6.33-gnu1/arch/mips/mm/cache.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/mm/cache.c	2010-05-16 17:17:36.000000000 -0400
@@ -133,26 +133,47 @@ void __update_cache(struct vm_area_struc
 }
 
 unsigned long _page_cachable_default;
-EXPORT_SYMBOL_GPL(_page_cachable_default);
+EXPORT_SYMBOL(_page_cachable_default);
 
 static inline void setup_protection_map(void)
 {
-	protection_map[0] = PAGE_NONE;
-	protection_map[1] = PAGE_READONLY;
-	protection_map[2] = PAGE_COPY;
-	protection_map[3] = PAGE_COPY;
-	protection_map[4] = PAGE_READONLY;
-	protection_map[5] = PAGE_READONLY;
-	protection_map[6] = PAGE_COPY;
-	protection_map[7] = PAGE_COPY;
-	protection_map[8] = PAGE_NONE;
-	protection_map[9] = PAGE_READONLY;
-	protection_map[10] = PAGE_SHARED;
-	protection_map[11] = PAGE_SHARED;
-	protection_map[12] = PAGE_READONLY;
-	protection_map[13] = PAGE_READONLY;
-	protection_map[14] = PAGE_SHARED;
-	protection_map[15] = PAGE_SHARED;
+	if (kernel_uses_smartmips_rixi) {
+		protection_map[0]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
+		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
+		protection_map[2]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
+		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
+		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_READ);
+		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
+		protection_map[6]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_READ);
+		protection_map[7]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
+
+		protection_map[8]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
+		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
+		protection_map[10] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | _PAGE_NO_READ);
+		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
+		protection_map[12] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_READ);
+		protection_map[13] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
+		protection_map[14] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE  | _PAGE_NO_READ);
+		protection_map[15] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
+
+	} else {
+		protection_map[0] = PAGE_NONE;
+		protection_map[1] = PAGE_READONLY;
+		protection_map[2] = PAGE_COPY;
+		protection_map[3] = PAGE_COPY;
+		protection_map[4] = PAGE_READONLY;
+		protection_map[5] = PAGE_READONLY;
+		protection_map[6] = PAGE_COPY;
+		protection_map[7] = PAGE_COPY;
+		protection_map[8] = PAGE_NONE;
+		protection_map[9] = PAGE_READONLY;
+		protection_map[10] = PAGE_SHARED;
+		protection_map[11] = PAGE_SHARED;
+		protection_map[12] = PAGE_READONLY;
+		protection_map[13] = PAGE_READONLY;
+		protection_map[14] = PAGE_SHARED;
+		protection_map[15] = PAGE_SHARED;
+	}
 }
 
 void __cpuinit cpu_cache_init(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/mm/c-octeon.c linux-libre-2.6.34-gnu1/arch/mips/mm/c-octeon.c
--- linux-libre-2.6.33-gnu1/arch/mips/mm/c-octeon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/mm/c-octeon.c	2010-05-16 17:17:36.000000000 -0400
@@ -183,6 +183,7 @@ static void __cpuinit probe_octeon(void)
 
 	switch (c->cputype) {
 	case CPU_CAVIUM_OCTEON:
+	case CPU_CAVIUM_OCTEON_PLUS:
 		config1 = read_c0_config1();
 		c->icache.linesz = 2 << ((config1 >> 19) & 7);
 		c->icache.sets = 64 << ((config1 >> 22) & 7);
@@ -192,10 +193,10 @@ static void __cpuinit probe_octeon(void)
 			c->icache.sets * c->icache.ways * c->icache.linesz;
 		c->icache.waybit = ffs(icache_size / c->icache.ways) - 1;
 		c->dcache.linesz = 128;
-		if (OCTEON_IS_MODEL(OCTEON_CN3XXX))
-			c->dcache.sets = 1; /* CN3XXX has one Dcache set */
-		else
+		if (c->cputype == CPU_CAVIUM_OCTEON_PLUS)
 			c->dcache.sets = 2; /* CN5XXX has two Dcache sets */
+		else
+			c->dcache.sets = 1; /* CN3XXX has one Dcache set */
 		c->dcache.ways = 64;
 		dcache_size =
 			c->dcache.sets * c->dcache.ways * c->dcache.linesz;
@@ -305,4 +306,3 @@ asmlinkage void cache_parity_error_octeo
 {
 	cache_parity_error_octeon(1);
 }
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/mm/dma-default.c linux-libre-2.6.34-gnu1/arch/mips/mm/dma-default.c
--- linux-libre-2.6.33-gnu1/arch/mips/mm/dma-default.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/mm/dma-default.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/scatterlist.h>
 #include <linux/string.h>
+#include <linux/gfp.h>
 
 #include <asm/cache.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/mm/fault.c linux-libre-2.6.34-gnu1/arch/mips/mm/fault.c
--- linux-libre-2.6.33-gnu1/arch/mips/mm/fault.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/mm/fault.c	2010-05-16 17:17:36.000000000 -0400
@@ -99,8 +99,31 @@ good_area:
 		if (!(vma->vm_flags & VM_WRITE))
 			goto bad_area;
 	} else {
-		if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
-			goto bad_area;
+		if (kernel_uses_smartmips_rixi) {
+			if (address == regs->cp0_epc && !(vma->vm_flags & VM_EXEC)) {
+#if 0
+				pr_notice("Cpu%d[%s:%d:%0*lx:%ld:%0*lx] XI violation\n",
+					  raw_smp_processor_id(),
+					  current->comm, current->pid,
+					  field, address, write,
+					  field, regs->cp0_epc);
+#endif
+				goto bad_area;
+			}
+			if (!(vma->vm_flags & VM_READ)) {
+#if 0
+				pr_notice("Cpu%d[%s:%d:%0*lx:%ld:%0*lx] RI violation\n",
+					  raw_smp_processor_id(),
+					  current->comm, current->pid,
+					  field, address, write,
+					  field, regs->cp0_epc);
+#endif
+				goto bad_area;
+			}
+		} else {
+			if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
+				goto bad_area;
+		}
 	}
 
 	/*
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/mm/hugetlbpage.c linux-libre-2.6.34-gnu1/arch/mips/mm/hugetlbpage.c
--- linux-libre-2.6.33-gnu1/arch/mips/mm/hugetlbpage.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/mm/hugetlbpage.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/pagemap.h>
-#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/sysctl.h>
 #include <asm/mman.h>
@@ -97,4 +96,3 @@ follow_huge_pmd(struct mm_struct *mm, un
 		page += ((address & ~HPAGE_MASK) >> PAGE_SHIFT);
 	return page;
 }
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/mm/init.c linux-libre-2.6.34-gnu1/arch/mips/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/mips/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/proc_fs.h>
 #include <linux/pfn.h>
 #include <linux/hardirq.h>
+#include <linux/gfp.h>
 
 #include <asm/asm-offsets.h>
 #include <asm/bootinfo.h>
@@ -143,7 +144,7 @@ void *kmap_coherent(struct page *page, u
 #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
 	entrylo = pte.pte_high;
 #else
-	entrylo = pte_val(pte) >> 6;
+	entrylo = pte_to_entrylo(pte_val(pte));
 #endif
 
 	ENTER_CRITICAL(flags);
@@ -298,7 +299,7 @@ void __init fixrange_init(unsigned long
 }
 
 #ifndef CONFIG_NEED_MULTIPLE_NODES
-static int __init page_is_ram(unsigned long pagenr)
+int page_is_ram(unsigned long pagenr)
 {
 	int i;
 
@@ -477,7 +478,7 @@ unsigned long pgd_current[NR_CPUS];
  * will officially be retired.
  */
 pgd_t swapper_pg_dir[_PTRS_PER_PGD] __page_aligned(_PGD_ORDER);
-#ifdef CONFIG_64BIT
+#ifndef __PAGETABLE_PMD_FOLDED
 pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned(PMD_ORDER);
 #endif
 pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/mm/ioremap.c linux-libre-2.6.34-gnu1/arch/mips/mm/ioremap.c
--- linux-libre-2.6.33-gnu1/arch/mips/mm/ioremap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/mm/ioremap.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <asm/addrspace.h>
 #include <asm/byteorder.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <asm/cacheflush.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/mm/page.c linux-libre-2.6.34-gnu1/arch/mips/mm/page.c
--- linux-libre-2.6.33-gnu1/arch/mips/mm/page.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/mm/page.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,7 +35,7 @@
 #include <asm/sibyte/sb1250_dma.h>
 #endif
 
-#include "uasm.h"
+#include <asm/uasm.h>
 
 /* Registers used in the assembled routines. */
 #define ZERO 0
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/mm/pgtable-64.c linux-libre-2.6.34-gnu1/arch/mips/mm/pgtable-64.c
--- linux-libre-2.6.33-gnu1/arch/mips/mm/pgtable-64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/mm/pgtable-64.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,23 +15,31 @@
 void pgd_init(unsigned long page)
 {
 	unsigned long *p, *end;
+	unsigned long entry;
+
+#ifdef __PAGETABLE_PMD_FOLDED
+	entry = (unsigned long)invalid_pte_table;
+#else
+	entry = (unsigned long)invalid_pmd_table;
+#endif
 
  	p = (unsigned long *) page;
 	end = p + PTRS_PER_PGD;
 
 	while (p < end) {
-		p[0] = (unsigned long) invalid_pmd_table;
-		p[1] = (unsigned long) invalid_pmd_table;
-		p[2] = (unsigned long) invalid_pmd_table;
-		p[3] = (unsigned long) invalid_pmd_table;
-		p[4] = (unsigned long) invalid_pmd_table;
-		p[5] = (unsigned long) invalid_pmd_table;
-		p[6] = (unsigned long) invalid_pmd_table;
-		p[7] = (unsigned long) invalid_pmd_table;
+		p[0] = entry;
+		p[1] = entry;
+		p[2] = entry;
+		p[3] = entry;
+		p[4] = entry;
+		p[5] = entry;
+		p[6] = entry;
+		p[7] = entry;
 		p += 8;
 	}
 }
 
+#ifndef __PAGETABLE_PMD_FOLDED
 void pmd_init(unsigned long addr, unsigned long pagetable)
 {
 	unsigned long *p, *end;
@@ -40,17 +48,18 @@ void pmd_init(unsigned long addr, unsign
 	end = p + PTRS_PER_PMD;
 
 	while (p < end) {
-		p[0] = (unsigned long)pagetable;
-		p[1] = (unsigned long)pagetable;
-		p[2] = (unsigned long)pagetable;
-		p[3] = (unsigned long)pagetable;
-		p[4] = (unsigned long)pagetable;
-		p[5] = (unsigned long)pagetable;
-		p[6] = (unsigned long)pagetable;
-		p[7] = (unsigned long)pagetable;
+		p[0] = pagetable;
+		p[1] = pagetable;
+		p[2] = pagetable;
+		p[3] = pagetable;
+		p[4] = pagetable;
+		p[5] = pagetable;
+		p[6] = pagetable;
+		p[7] = pagetable;
 		p += 8;
 	}
 }
+#endif
 
 void __init pagetable_init(void)
 {
@@ -59,8 +68,9 @@ void __init pagetable_init(void)
 
 	/* Initialize the entire pgd.  */
 	pgd_init((unsigned long)swapper_pg_dir);
+#ifndef __PAGETABLE_PMD_FOLDED
 	pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
-
+#endif
 	pgd_base = swapper_pg_dir;
 	/*
 	 * Fixed mappings:
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/mm/tlbex.c linux-libre-2.6.34-gnu1/arch/mips/mm/tlbex.c
--- linux-libre-2.6.33-gnu1/arch/mips/mm/tlbex.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/mm/tlbex.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,8 +29,17 @@
 
 #include <asm/mmu_context.h>
 #include <asm/war.h>
+#include <asm/uasm.h>
+
+/*
+ * TLB load/store/modify handlers.
+ *
+ * Only the fastpath gets synthesized at runtime, the slowpath for
+ * do_page_fault remains normal asm.
+ */
+extern void tlb_do_page_fault_0(void);
+extern void tlb_do_page_fault_1(void);
 
-#include "uasm.h"
 
 static inline int r45k_bvahwbug(void)
 {
@@ -77,11 +86,14 @@ enum label_id {
 	label_vmalloc_done,
 	label_tlbw_hazard,
 	label_split,
+	label_tlbl_goaround1,
+	label_tlbl_goaround2,
 	label_nopage_tlbl,
 	label_nopage_tlbs,
 	label_nopage_tlbm,
 	label_smp_pgtable_change,
 	label_r3000_write_probe_fail,
+	label_large_segbits_fault,
 #ifdef CONFIG_HUGETLB_PAGE
 	label_tlb_huge_update,
 #endif
@@ -93,11 +105,14 @@ UASM_L_LA(_vmalloc)
 UASM_L_LA(_vmalloc_done)
 UASM_L_LA(_tlbw_hazard)
 UASM_L_LA(_split)
+UASM_L_LA(_tlbl_goaround1)
+UASM_L_LA(_tlbl_goaround2)
 UASM_L_LA(_nopage_tlbl)
 UASM_L_LA(_nopage_tlbs)
 UASM_L_LA(_nopage_tlbm)
 UASM_L_LA(_smp_pgtable_change)
 UASM_L_LA(_r3000_write_probe_fail)
+UASM_L_LA(_large_segbits_fault)
 #ifdef CONFIG_HUGETLB_PAGE
 UASM_L_LA(_tlb_huge_update)
 #endif
@@ -154,6 +169,10 @@ static u32 tlb_handler[128] __cpuinitdat
 static struct uasm_label labels[128] __cpuinitdata;
 static struct uasm_reloc relocs[128] __cpuinitdata;
 
+#ifdef CONFIG_64BIT
+static int check_for_high_segbits __cpuinitdata;
+#endif
+
 #ifndef CONFIG_MIPS_PGD_C0_CONTEXT
 /*
  * CONFIG_MIPS_PGD_C0_CONTEXT implies 64 bit and lack of pgd_current,
@@ -397,36 +416,60 @@ static void __cpuinit build_tlb_write_en
 	}
 }
 
-#ifdef CONFIG_HUGETLB_PAGE
-static __cpuinit void build_huge_tlb_write_entry(u32 **p,
-						 struct uasm_label **l,
-						 struct uasm_reloc **r,
-						 unsigned int tmp,
-						 enum tlb_write_entry wmode)
+static __cpuinit __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
+								  unsigned int reg)
 {
-	/* Set huge page tlb entry size */
-	uasm_i_lui(p, tmp, PM_HUGE_MASK >> 16);
-	uasm_i_ori(p, tmp, tmp, PM_HUGE_MASK & 0xffff);
-	uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+	if (kernel_uses_smartmips_rixi) {
+		UASM_i_SRL(p, reg, reg, ilog2(_PAGE_NO_EXEC));
+		UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+	} else {
+#ifdef CONFIG_64BIT_PHYS_ADDR
+		uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL));
+#else
+		UASM_i_SRL(p, reg, reg, ilog2(_PAGE_GLOBAL));
+#endif
+	}
+}
 
-	build_tlb_write_entry(p, l, r, wmode);
+#ifdef CONFIG_HUGETLB_PAGE
 
+static __cpuinit void build_restore_pagemask(u32 **p,
+					     struct uasm_reloc **r,
+					     unsigned int tmp,
+					     enum label_id lid)
+{
 	/* Reset default page size */
 	if (PM_DEFAULT_MASK >> 16) {
 		uasm_i_lui(p, tmp, PM_DEFAULT_MASK >> 16);
 		uasm_i_ori(p, tmp, tmp, PM_DEFAULT_MASK & 0xffff);
-		uasm_il_b(p, r, label_leave);
+		uasm_il_b(p, r, lid);
 		uasm_i_mtc0(p, tmp, C0_PAGEMASK);
 	} else if (PM_DEFAULT_MASK) {
 		uasm_i_ori(p, tmp, 0, PM_DEFAULT_MASK);
-		uasm_il_b(p, r, label_leave);
+		uasm_il_b(p, r, lid);
 		uasm_i_mtc0(p, tmp, C0_PAGEMASK);
 	} else {
-		uasm_il_b(p, r, label_leave);
+		uasm_il_b(p, r, lid);
 		uasm_i_mtc0(p, 0, C0_PAGEMASK);
 	}
 }
 
+static __cpuinit void build_huge_tlb_write_entry(u32 **p,
+						 struct uasm_label **l,
+						 struct uasm_reloc **r,
+						 unsigned int tmp,
+						 enum tlb_write_entry wmode)
+{
+	/* Set huge page tlb entry size */
+	uasm_i_lui(p, tmp, PM_HUGE_MASK >> 16);
+	uasm_i_ori(p, tmp, tmp, PM_HUGE_MASK & 0xffff);
+	uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+
+	build_tlb_write_entry(p, l, r, wmode);
+
+	build_restore_pagemask(p, r, tmp, label_leave);
+}
+
 /*
  * Check if Huge PTE is present, if so then jump to LABEL.
  */
@@ -460,15 +503,15 @@ static __cpuinit void build_huge_update_
 	if (!small_sequence)
 		uasm_i_lui(p, tmp, HPAGE_SIZE >> (7 + 16));
 
-	UASM_i_SRL(p, pte, pte, 6); /* convert to entrylo */
-	uasm_i_mtc0(p, pte, C0_ENTRYLO0); /* load it */
+	build_convert_pte_to_entrylo(p, pte);
+	UASM_i_MTC0(p, pte, C0_ENTRYLO0); /* load it */
 	/* convert to entrylo1 */
 	if (small_sequence)
 		UASM_i_ADDIU(p, pte, pte, HPAGE_SIZE >> 7);
 	else
 		UASM_i_ADDU(p, pte, pte, tmp);
 
-	uasm_i_mtc0(p, pte, C0_ENTRYLO1); /* load it */
+	UASM_i_MTC0(p, pte, C0_ENTRYLO1); /* load it */
 }
 
 static __cpuinit void build_huge_handler_tail(u32 **p,
@@ -505,7 +548,24 @@ build_get_pmde64(u32 **p, struct uasm_la
 	 * The vmalloc handling is not in the hotpath.
 	 */
 	uasm_i_dmfc0(p, tmp, C0_BADVADDR);
-	uasm_il_bltz(p, r, tmp, label_vmalloc);
+
+	if (check_for_high_segbits) {
+		/*
+		 * The kernel currently implicitely assumes that the
+		 * MIPS SEGBITS parameter for the processor is
+		 * (PGDIR_SHIFT+PGDIR_BITS) or less, and will never
+		 * allocate virtual addresses outside the maximum
+		 * range for SEGBITS = (PGDIR_SHIFT+PGDIR_BITS). But
+		 * that doesn't prevent user code from accessing the
+		 * higher xuseg addresses.  Here, we make sure that
+		 * everything but the lower xuseg addresses goes down
+		 * the module_alloc/vmalloc path.
+		 */
+		uasm_i_dsrl_safe(p, ptr, tmp, PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
+		uasm_il_bnez(p, r, ptr, label_vmalloc);
+	} else {
+		uasm_il_bltz(p, r, tmp, label_vmalloc);
+	}
 	/* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
 
 #ifdef CONFIG_MIPS_PGD_C0_CONTEXT
@@ -522,14 +582,14 @@ build_get_pmde64(u32 **p, struct uasm_la
 	 * SMTC uses TCBind value as "CPU" index
 	 */
 	uasm_i_mfc0(p, ptr, C0_TCBIND);
-	uasm_i_dsrl(p, ptr, ptr, 19);
+	uasm_i_dsrl_safe(p, ptr, ptr, 19);
 # else
 	/*
 	 * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
 	 * stored in CONTEXT.
 	 */
 	uasm_i_dmfc0(p, ptr, C0_CONTEXT);
-	uasm_i_dsrl(p, ptr, ptr, 23);
+	uasm_i_dsrl_safe(p, ptr, ptr, 23);
 # endif
 	UASM_i_LA_mostly(p, tmp, pgdc);
 	uasm_i_daddu(p, ptr, ptr, tmp);
@@ -542,42 +602,78 @@ build_get_pmde64(u32 **p, struct uasm_la
 
 	uasm_l_vmalloc_done(l, *p);
 
-	if (PGDIR_SHIFT - 3 < 32)		/* get pgd offset in bytes */
-		uasm_i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3);
-	else
-		uasm_i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32);
+	/* get pgd offset in bytes */
+	uasm_i_dsrl_safe(p, tmp, tmp, PGDIR_SHIFT - 3);
 
 	uasm_i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3);
 	uasm_i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */
+#ifndef __PAGETABLE_PMD_FOLDED
 	uasm_i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */
 	uasm_i_ld(p, ptr, 0, ptr); /* get pmd pointer */
-	uasm_i_dsrl(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
+	uasm_i_dsrl_safe(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
 	uasm_i_andi(p, tmp, tmp, (PTRS_PER_PMD - 1)<<3);
 	uasm_i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */
+#endif
 }
 
+enum vmalloc64_mode {not_refill, refill};
 /*
  * BVADDR is the faulting address, PTR is scratch.
  * PTR will hold the pgd for vmalloc.
  */
 static void __cpuinit
 build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
-			unsigned int bvaddr, unsigned int ptr)
+			unsigned int bvaddr, unsigned int ptr,
+			enum vmalloc64_mode mode)
 {
 	long swpd = (long)swapper_pg_dir;
+	int single_insn_swpd;
+	int did_vmalloc_branch = 0;
+
+	single_insn_swpd = uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd);
 
 	uasm_l_vmalloc(l, *p);
 
-	if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
-		uasm_il_b(p, r, label_vmalloc_done);
-		uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
-	} else {
-		UASM_i_LA_mostly(p, ptr, swpd);
-		uasm_il_b(p, r, label_vmalloc_done);
-		if (uasm_in_compat_space_p(swpd))
-			uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(swpd));
-		else
-			uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));
+	if (mode == refill && check_for_high_segbits) {
+		if (single_insn_swpd) {
+			uasm_il_bltz(p, r, bvaddr, label_vmalloc_done);
+			uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
+			did_vmalloc_branch = 1;
+			/* fall through */
+		} else {
+			uasm_il_bgez(p, r, bvaddr, label_large_segbits_fault);
+		}
+	}
+	if (!did_vmalloc_branch) {
+		if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
+			uasm_il_b(p, r, label_vmalloc_done);
+			uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
+		} else {
+			UASM_i_LA_mostly(p, ptr, swpd);
+			uasm_il_b(p, r, label_vmalloc_done);
+			if (uasm_in_compat_space_p(swpd))
+				uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(swpd));
+			else
+				uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));
+		}
+	}
+	if (mode == refill && check_for_high_segbits) {
+		uasm_l_large_segbits_fault(l, *p);
+		/*
+		 * We get here if we are an xsseg address, or if we are
+		 * an xuseg address above (PGDIR_SHIFT+PGDIR_BITS) boundary.
+		 *
+		 * Ignoring xsseg (assume disabled so would generate
+		 * (address errors?), the only remaining possibility
+		 * is the upper xuseg addresses.  On processors with
+		 * TLB_SEGBITS <= PGDIR_SHIFT+PGDIR_BITS, these
+		 * addresses would have taken an address error. We try
+		 * to mimic that here by taking a load/istream page
+		 * fault.
+		 */
+		UASM_i_LA(p, ptr, (unsigned long)tlb_do_page_fault_0);
+		uasm_i_jr(p, ptr);
+		uasm_i_nop(p);
 	}
 }
 
@@ -684,35 +780,53 @@ static void __cpuinit build_update_entri
 	if (cpu_has_64bits) {
 		uasm_i_ld(p, tmp, 0, ptep); /* get even pte */
 		uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
-		uasm_i_dsrl(p, tmp, tmp, 6); /* convert to entrylo0 */
-		uasm_i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
-		uasm_i_dsrl(p, ptep, ptep, 6); /* convert to entrylo1 */
-		uasm_i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
+		if (kernel_uses_smartmips_rixi) {
+			UASM_i_SRL(p, tmp, tmp, ilog2(_PAGE_NO_EXEC));
+			UASM_i_SRL(p, ptep, ptep, ilog2(_PAGE_NO_EXEC));
+			UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+			UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
+			UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+		} else {
+			uasm_i_dsrl_safe(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
+			UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
+			uasm_i_dsrl_safe(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */
+		}
+		UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */
 	} else {
 		int pte_off_even = sizeof(pte_t) / 2;
 		int pte_off_odd = pte_off_even + sizeof(pte_t);
 
 		/* The pte entries are pre-shifted */
 		uasm_i_lw(p, tmp, pte_off_even, ptep); /* get even pte */
-		uasm_i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
+		UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
 		uasm_i_lw(p, ptep, pte_off_odd, ptep); /* get odd pte */
-		uasm_i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
+		UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */
 	}
 #else
 	UASM_i_LW(p, tmp, 0, ptep); /* get even pte */
 	UASM_i_LW(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
 	if (r45k_bvahwbug())
 		build_tlb_probe_entry(p);
-	UASM_i_SRL(p, tmp, tmp, 6); /* convert to entrylo0 */
-	if (r4k_250MHZhwbug())
-		uasm_i_mtc0(p, 0, C0_ENTRYLO0);
-	uasm_i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
-	UASM_i_SRL(p, ptep, ptep, 6); /* convert to entrylo1 */
-	if (r45k_bvahwbug())
-		uasm_i_mfc0(p, tmp, C0_INDEX);
+	if (kernel_uses_smartmips_rixi) {
+		UASM_i_SRL(p, tmp, tmp, ilog2(_PAGE_NO_EXEC));
+		UASM_i_SRL(p, ptep, ptep, ilog2(_PAGE_NO_EXEC));
+		UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+		if (r4k_250MHZhwbug())
+			UASM_i_MTC0(p, 0, C0_ENTRYLO0);
+		UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
+		UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+	} else {
+		UASM_i_SRL(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
+		if (r4k_250MHZhwbug())
+			UASM_i_MTC0(p, 0, C0_ENTRYLO0);
+		UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
+		UASM_i_SRL(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */
+		if (r45k_bvahwbug())
+			uasm_i_mfc0(p, tmp, C0_INDEX);
+	}
 	if (r4k_250MHZhwbug())
-		uasm_i_mtc0(p, 0, C0_ENTRYLO1);
-	uasm_i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
+		UASM_i_MTC0(p, 0, C0_ENTRYLO1);
+	UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */
 #endif
 }
 
@@ -741,10 +855,15 @@ static void __cpuinit build_r4000_tlb_re
 	 * create the plain linear handler
 	 */
 	if (bcm1250_m3_war()) {
-		UASM_i_MFC0(&p, K0, C0_BADVADDR);
-		UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+		unsigned int segbits = 44;
+
+		uasm_i_dmfc0(&p, K0, C0_BADVADDR);
+		uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
 		uasm_i_xor(&p, K0, K0, K1);
-		UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+		uasm_i_dsrl_safe(&p, K1, K0, 62);
+		uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
+		uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
+		uasm_i_or(&p, K0, K0, K1);
 		uasm_il_bnez(&p, &r, K0, label_leave);
 		/* No need for uasm_i_nop */
 	}
@@ -773,7 +892,7 @@ static void __cpuinit build_r4000_tlb_re
 #endif
 
 #ifdef CONFIG_64BIT
-	build_get_pgd_vmalloc64(&p, &l, &r, K0, K1);
+	build_get_pgd_vmalloc64(&p, &l, &r, K0, K1, refill);
 #endif
 
 	/*
@@ -883,15 +1002,6 @@ static void __cpuinit build_r4000_tlb_re
 }
 
 /*
- * TLB load/store/modify handlers.
- *
- * Only the fastpath gets synthesized at runtime, the slowpath for
- * do_page_fault remains normal asm.
- */
-extern void tlb_do_page_fault_0(void);
-extern void tlb_do_page_fault_1(void);
-
-/*
  * 128 instructions for the fastpath handler is generous and should
  * never be exceeded.
  */
@@ -985,9 +1095,14 @@ static void __cpuinit
 build_pte_present(u32 **p, struct uasm_reloc **r,
 		  unsigned int pte, unsigned int ptr, enum label_id lid)
 {
-	uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
-	uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
-	uasm_il_bnez(p, r, pte, lid);
+	if (kernel_uses_smartmips_rixi) {
+		uasm_i_andi(p, pte, pte, _PAGE_PRESENT);
+		uasm_il_beqz(p, r, pte, lid);
+	} else {
+		uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+		uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+		uasm_il_bnez(p, r, pte, lid);
+	}
 	iPTE_LW(p, pte, ptr);
 }
 
@@ -1245,7 +1360,7 @@ build_r4000_tlbchange_handler_tail(u32 *
 	uasm_i_eret(p); /* return from trap */
 
 #ifdef CONFIG_64BIT
-	build_get_pgd_vmalloc64(p, l, r, tmp, ptr);
+	build_get_pgd_vmalloc64(p, l, r, tmp, ptr, not_refill);
 #endif
 }
 
@@ -1260,10 +1375,15 @@ static void __cpuinit build_r4000_tlb_lo
 	memset(relocs, 0, sizeof(relocs));
 
 	if (bcm1250_m3_war()) {
-		UASM_i_MFC0(&p, K0, C0_BADVADDR);
-		UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+		unsigned int segbits = 44;
+
+		uasm_i_dmfc0(&p, K0, C0_BADVADDR);
+		uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
 		uasm_i_xor(&p, K0, K0, K1);
-		UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+		uasm_i_dsrl_safe(&p, K1, K0, 62);
+		uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
+		uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
+		uasm_i_or(&p, K0, K0, K1);
 		uasm_il_bnez(&p, &r, K0, label_leave);
 		/* No need for uasm_i_nop */
 	}
@@ -1272,6 +1392,34 @@ static void __cpuinit build_r4000_tlb_lo
 	build_pte_present(&p, &r, K0, K1, label_nopage_tlbl);
 	if (m4kc_tlbp_war())
 		build_tlb_probe_entry(&p);
+
+	if (kernel_uses_smartmips_rixi) {
+		/*
+		 * If the page is not _PAGE_VALID, RI or XI could not
+		 * have triggered it.  Skip the expensive test..
+		 */
+		uasm_i_andi(&p, K0, K0, _PAGE_VALID);
+		uasm_il_beqz(&p, &r, K0, label_tlbl_goaround1);
+		uasm_i_nop(&p);
+
+		uasm_i_tlbr(&p);
+		/* Examine  entrylo 0 or 1 based on ptr. */
+		uasm_i_andi(&p, K0, K1, sizeof(pte_t));
+		uasm_i_beqz(&p, K0, 8);
+
+		UASM_i_MFC0(&p, K0, C0_ENTRYLO0); /* load it in the delay slot*/
+		UASM_i_MFC0(&p, K0, C0_ENTRYLO1); /* load it if ptr is odd */
+		/*
+		 * If the entryLo (now in K0) is valid (bit 1), RI or
+		 * XI must have triggered it.
+		 */
+		uasm_i_andi(&p, K0, K0, 2);
+		uasm_il_bnez(&p, &r, K0, label_nopage_tlbl);
+
+		uasm_l_tlbl_goaround1(&l, p);
+		/* Reload the PTE value */
+		iPTE_LW(&p, K0, K1);
+	}
 	build_make_valid(&p, &r, K0, K1);
 	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
 
@@ -1284,6 +1432,40 @@ static void __cpuinit build_r4000_tlb_lo
 	iPTE_LW(&p, K0, K1);
 	build_pte_present(&p, &r, K0, K1, label_nopage_tlbl);
 	build_tlb_probe_entry(&p);
+
+	if (kernel_uses_smartmips_rixi) {
+		/*
+		 * If the page is not _PAGE_VALID, RI or XI could not
+		 * have triggered it.  Skip the expensive test..
+		 */
+		uasm_i_andi(&p, K0, K0, _PAGE_VALID);
+		uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
+		uasm_i_nop(&p);
+
+		uasm_i_tlbr(&p);
+		/* Examine  entrylo 0 or 1 based on ptr. */
+		uasm_i_andi(&p, K0, K1, sizeof(pte_t));
+		uasm_i_beqz(&p, K0, 8);
+
+		UASM_i_MFC0(&p, K0, C0_ENTRYLO0); /* load it in the delay slot*/
+		UASM_i_MFC0(&p, K0, C0_ENTRYLO1); /* load it if ptr is odd */
+		/*
+		 * If the entryLo (now in K0) is valid (bit 1), RI or
+		 * XI must have triggered it.
+		 */
+		uasm_i_andi(&p, K0, K0, 2);
+		uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
+		/* Reload the PTE value */
+		iPTE_LW(&p, K0, K1);
+
+		/*
+		 * We clobbered C0_PAGEMASK, restore it.  On the other branch
+		 * it is restored in build_huge_tlb_write_entry.
+		 */
+		build_restore_pagemask(&p, &r, K0, label_nopage_tlbl);
+
+		uasm_l_tlbl_goaround2(&l, p);
+	}
 	uasm_i_ori(&p, K0, K0, (_PAGE_ACCESSED | _PAGE_VALID));
 	build_huge_handler_tail(&p, &r, &l, K0, K1);
 #endif
@@ -1402,6 +1584,10 @@ void __cpuinit build_tlb_refill_handler(
 	 */
 	static int run_once = 0;
 
+#ifdef CONFIG_64BIT
+	check_for_high_segbits = current_cpu_data.vmbits > (PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
+#endif
+
 	switch (current_cpu_type()) {
 	case CPU_R2000:
 	case CPU_R3000:
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/mm/tlb-r4k.c linux-libre-2.6.34-gnu1/arch/mips/mm/tlb-r4k.c
--- linux-libre-2.6.33-gnu1/arch/mips/mm/tlb-r4k.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/mm/tlb-r4k.c	2010-05-16 17:17:36.000000000 -0400
@@ -303,7 +303,7 @@ void __update_tlb(struct vm_area_struct
 		unsigned long lo;
 		write_c0_pagemask(PM_HUGE_MASK);
 		ptep = (pte_t *)pmdp;
-		lo = pte_val(*ptep) >> 6;
+		lo = pte_to_entrylo(pte_val(*ptep));
 		write_c0_entrylo0(lo);
 		write_c0_entrylo1(lo + (HPAGE_SIZE >> 7));
 
@@ -323,8 +323,8 @@ void __update_tlb(struct vm_area_struct
 		ptep++;
 		write_c0_entrylo1(ptep->pte_high);
 #else
-		write_c0_entrylo0(pte_val(*ptep++) >> 6);
-		write_c0_entrylo1(pte_val(*ptep) >> 6);
+		write_c0_entrylo0(pte_to_entrylo(pte_val(*ptep++)));
+		write_c0_entrylo1(pte_to_entrylo(pte_val(*ptep)));
 #endif
 		mtc0_tlbw_hazard();
 		if (idx < 0)
@@ -337,40 +337,6 @@ void __update_tlb(struct vm_area_struct
 	EXIT_CRITICAL(flags);
 }
 
-#if 0
-static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma,
-				       unsigned long address, pte_t pte)
-{
-	unsigned long flags;
-	unsigned int asid;
-	pgd_t *pgdp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-	int idx;
-
-	ENTER_CRITICAL(flags);
-	address &= (PAGE_MASK << 1);
-	asid = read_c0_entryhi() & ASID_MASK;
-	write_c0_entryhi(address | asid);
-	pgdp = pgd_offset(vma->vm_mm, address);
-	mtc0_tlbw_hazard();
-	tlb_probe();
-	tlb_probe_hazard();
-	pmdp = pmd_offset(pgdp, address);
-	idx = read_c0_index();
-	ptep = pte_offset_map(pmdp, address);
-	write_c0_entrylo0(pte_val(*ptep++) >> 6);
-	write_c0_entrylo1(pte_val(*ptep) >> 6);
-	mtc0_tlbw_hazard();
-	if (idx < 0)
-		tlb_write_random();
-	else
-		tlb_write_indexed();
-	tlbw_use_hazard();
-	EXIT_CRITICAL(flags);
-}
-#endif
-
 void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
 	unsigned long entryhi, unsigned long pagemask)
 {
@@ -447,34 +413,6 @@ out:
 	return ret;
 }
 
-static void __cpuinit probe_tlb(unsigned long config)
-{
-	struct cpuinfo_mips *c = &current_cpu_data;
-	unsigned int reg;
-
-	/*
-	 * If this isn't a MIPS32 / MIPS64 compliant CPU.  Config 1 register
-	 * is not supported, we assume R4k style.  Cpu probing already figured
-	 * out the number of tlb entries.
-	 */
-	if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY)
-		return;
-#ifdef CONFIG_MIPS_MT_SMTC
-	/*
-	 * If TLB is shared in SMTC system, total size already
-	 * has been calculated and written into cpu_data tlbsize
-	 */
-	if((smtc_status & SMTC_TLB_SHARED) == SMTC_TLB_SHARED)
-		return;
-#endif /* CONFIG_MIPS_MT_SMTC */
-
-	reg = read_c0_config1();
-	if (!((config >> 7) & 3))
-		panic("No TLB present");
-
-	c->tlbsize = ((reg >> 25) & 0x3f) + 1;
-}
-
 static int __cpuinitdata ntlb;
 static int __init set_ntlb(char *str)
 {
@@ -486,8 +424,6 @@ __setup("ntlb=", set_ntlb);
 
 void __cpuinit tlb_init(void)
 {
-	unsigned int config = read_c0_config();
-
 	/*
 	 * You should never change this register:
 	 *   - On R4600 1.7 the tlbp never hits for pages smaller than
@@ -495,13 +431,25 @@ void __cpuinit tlb_init(void)
 	 *   - The entire mm handling assumes the c0_pagemask register to
 	 *     be set to fixed-size pages.
 	 */
-	probe_tlb(config);
 	write_c0_pagemask(PM_DEFAULT_MASK);
 	write_c0_wired(0);
 	if (current_cpu_type() == CPU_R10000 ||
 	    current_cpu_type() == CPU_R12000 ||
 	    current_cpu_type() == CPU_R14000)
 		write_c0_framemask(0);
+
+	if (kernel_uses_smartmips_rixi) {
+		/*
+		 * Enable the no read, no exec bits, and enable large virtual
+		 * address.
+		 */
+		u32 pg = PG_RIE | PG_XIE;
+#ifdef CONFIG_64BIT
+		pg |= PG_ELPA;
+#endif
+		write_c0_pagegrain(pg);
+	}
+
 	temp_tlb_entry = current_cpu_data.tlbsize - 1;
 
         /* From this point on the ARC firmware is dead.  */
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/mm/uasm.c linux-libre-2.6.34-gnu1/arch/mips/mm/uasm.c
--- linux-libre-2.6.33-gnu1/arch/mips/mm/uasm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/mm/uasm.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,8 +19,7 @@
 #include <asm/inst.h>
 #include <asm/elf.h>
 #include <asm/bugs.h>
-
-#include "uasm.h"
+#include <asm/uasm.h>
 
 enum fields {
 	RS = 0x001,
@@ -32,7 +31,8 @@ enum fields {
 	BIMM = 0x040,
 	JIMM = 0x080,
 	FUNC = 0x100,
-	SET = 0x200
+	SET = 0x200,
+	SCIMM = 0x400
 };
 
 #define OP_MASK		0x3f
@@ -53,6 +53,8 @@ enum fields {
 #define FUNC_SH		0
 #define SET_MASK	0x7
 #define SET_SH		0
+#define SCIMM_MASK	0xfffff
+#define SCIMM_SH	6
 
 enum opcode {
 	insn_invalid,
@@ -62,9 +64,10 @@ enum opcode {
 	insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
 	insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal,
 	insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
-	insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
-	insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw,
-	insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori, insn_dins
+	insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
+	insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw,
+	insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
+	insn_dins, insn_syscall
 };
 
 struct insn {
@@ -117,6 +120,7 @@ static struct insn insn_table[] __cpuini
 	{ insn_lw,  M(lw_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
 	{ insn_mfc0,  M(cop0_op, mfc_op, 0, 0, 0, 0),  RT | RD | SET},
 	{ insn_mtc0,  M(cop0_op, mtc_op, 0, 0, 0, 0),  RT | RD | SET},
+	{ insn_or,  M(spec_op, 0, 0, 0, 0, or_op),  RS | RT | RD },
 	{ insn_ori,  M(ori_op, 0, 0, 0, 0, 0),  RS | RT | UIMM },
 	{ insn_pref,  M(pref_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
 	{ insn_rfe,  M(cop0_op, cop_op, 0, 0, 0, rfe_op),  0 },
@@ -126,14 +130,17 @@ static struct insn insn_table[] __cpuini
 	{ insn_sll,  M(spec_op, 0, 0, 0, 0, sll_op),  RT | RD | RE },
 	{ insn_sra,  M(spec_op, 0, 0, 0, 0, sra_op),  RT | RD | RE },
 	{ insn_srl,  M(spec_op, 0, 0, 0, 0, srl_op),  RT | RD | RE },
+	{ insn_rotr,  M(spec_op, 1, 0, 0, 0, srl_op),  RT | RD | RE },
 	{ insn_subu,  M(spec_op, 0, 0, 0, 0, subu_op),  RS | RT | RD },
 	{ insn_sw,  M(sw_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
 	{ insn_tlbp,  M(cop0_op, cop_op, 0, 0, 0, tlbp_op),  0 },
+	{ insn_tlbr,  M(cop0_op, cop_op, 0, 0, 0, tlbr_op),  0 },
 	{ insn_tlbwi,  M(cop0_op, cop_op, 0, 0, 0, tlbwi_op),  0 },
 	{ insn_tlbwr,  M(cop0_op, cop_op, 0, 0, 0, tlbwr_op),  0 },
 	{ insn_xor,  M(spec_op, 0, 0, 0, 0, xor_op),  RS | RT | RD },
 	{ insn_xori,  M(xori_op, 0, 0, 0, 0, 0),  RS | RT | UIMM },
 	{ insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
+	{ insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},
 	{ insn_invalid, 0, 0 }
 };
 
@@ -206,6 +213,14 @@ static inline __cpuinit u32 build_jimm(u
 	return (arg >> 2) & JIMM_MASK;
 }
 
+static inline __cpuinit u32 build_scimm(u32 arg)
+{
+	if (arg & ~SCIMM_MASK)
+		printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+	return (arg & SCIMM_MASK) << SCIMM_SH;
+}
+
 static inline __cpuinit u32 build_func(u32 arg)
 {
 	if (arg & ~FUNC_MASK)
@@ -264,6 +279,8 @@ static void __cpuinit build_insn(u32 **b
 		op |= build_func(va_arg(ap, u32));
 	if (ip->fields & SET)
 		op |= build_set(va_arg(ap, u32));
+	if (ip->fields & SCIMM)
+		op |= build_scimm(va_arg(ap, u32));
 	va_end(ap);
 
 	**buf = op;
@@ -371,6 +388,7 @@ I_u2s3u1(_lw)
 I_u1u2u3(_mfc0)
 I_u1u2u3(_mtc0)
 I_u2u1u3(_ori)
+I_u3u1u2(_or)
 I_u2s3u1(_pref)
 I_0(_rfe)
 I_u2s3u1(_sc)
@@ -379,14 +397,17 @@ I_u2s3u1(_sd)
 I_u2u1u3(_sll)
 I_u2u1u3(_sra)
 I_u2u1u3(_srl)
+I_u2u1u3(_rotr)
 I_u3u1u2(_subu)
 I_u2s3u1(_sw)
 I_0(_tlbp)
+I_0(_tlbr)
 I_0(_tlbwi)
 I_0(_tlbwr)
 I_u3u1u2(_xor)
 I_u2u1u3(_xori)
 I_u2u1msbu3(_dins);
+I_u1(_syscall);
 
 /* Handle labels. */
 void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/mm/uasm.h linux-libre-2.6.34-gnu1/arch/mips/mm/uasm.h
--- linux-libre-2.6.33-gnu1/arch/mips/mm/uasm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/mm/uasm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,191 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004, 2005, 2006, 2008  Thiemo Seufer
- * Copyright (C) 2005  Maciej W. Rozycki
- * Copyright (C) 2006  Ralf Baechle (ralf@linux-mips.org)
- */
-
-#include <linux/types.h>
-
-#define Ip_u1u2u3(op)							\
-void __cpuinit								\
-uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
-
-#define Ip_u2u1u3(op)							\
-void __cpuinit								\
-uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
-
-#define Ip_u3u1u2(op)							\
-void __cpuinit								\
-uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
-
-#define Ip_u1u2s3(op)							\
-void __cpuinit								\
-uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
-
-#define Ip_u2s3u1(op)							\
-void __cpuinit								\
-uasm_i##op(u32 **buf, unsigned int a, signed int b, unsigned int c)
-
-#define Ip_u2u1s3(op)							\
-void __cpuinit								\
-uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
-
-#define Ip_u2u1msbu3(op)						\
-void __cpuinit								\
-uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c,	\
-	   unsigned int d)
-
-#define Ip_u1u2(op)							\
-void __cpuinit uasm_i##op(u32 **buf, unsigned int a, unsigned int b)
-
-#define Ip_u1s2(op)							\
-void __cpuinit uasm_i##op(u32 **buf, unsigned int a, signed int b)
-
-#define Ip_u1(op) void __cpuinit uasm_i##op(u32 **buf, unsigned int a)
-
-#define Ip_0(op) void __cpuinit uasm_i##op(u32 **buf)
-
-Ip_u2u1s3(_addiu);
-Ip_u3u1u2(_addu);
-Ip_u2u1u3(_andi);
-Ip_u3u1u2(_and);
-Ip_u1u2s3(_beq);
-Ip_u1u2s3(_beql);
-Ip_u1s2(_bgez);
-Ip_u1s2(_bgezl);
-Ip_u1s2(_bltz);
-Ip_u1s2(_bltzl);
-Ip_u1u2s3(_bne);
-Ip_u2s3u1(_cache);
-Ip_u1u2u3(_dmfc0);
-Ip_u1u2u3(_dmtc0);
-Ip_u2u1s3(_daddiu);
-Ip_u3u1u2(_daddu);
-Ip_u2u1u3(_dsll);
-Ip_u2u1u3(_dsll32);
-Ip_u2u1u3(_dsra);
-Ip_u2u1u3(_dsrl);
-Ip_u2u1u3(_dsrl32);
-Ip_u2u1u3(_drotr);
-Ip_u3u1u2(_dsubu);
-Ip_0(_eret);
-Ip_u1(_j);
-Ip_u1(_jal);
-Ip_u1(_jr);
-Ip_u2s3u1(_ld);
-Ip_u2s3u1(_ll);
-Ip_u2s3u1(_lld);
-Ip_u1s2(_lui);
-Ip_u2s3u1(_lw);
-Ip_u1u2u3(_mfc0);
-Ip_u1u2u3(_mtc0);
-Ip_u2u1u3(_ori);
-Ip_u2s3u1(_pref);
-Ip_0(_rfe);
-Ip_u2s3u1(_sc);
-Ip_u2s3u1(_scd);
-Ip_u2s3u1(_sd);
-Ip_u2u1u3(_sll);
-Ip_u2u1u3(_sra);
-Ip_u2u1u3(_srl);
-Ip_u3u1u2(_subu);
-Ip_u2s3u1(_sw);
-Ip_0(_tlbp);
-Ip_0(_tlbwi);
-Ip_0(_tlbwr);
-Ip_u3u1u2(_xor);
-Ip_u2u1u3(_xori);
-Ip_u2u1msbu3(_dins);
-
-/* Handle labels. */
-struct uasm_label {
-	u32 *addr;
-	int lab;
-};
-
-void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid);
-#ifdef CONFIG_64BIT
-int uasm_in_compat_space_p(long addr);
-#endif
-int uasm_rel_hi(long val);
-int uasm_rel_lo(long val);
-void UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr);
-void UASM_i_LA(u32 **buf, unsigned int rs, long addr);
-
-#define UASM_L_LA(lb)							\
-static inline void __cpuinit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
-{									\
-	uasm_build_label(lab, addr, label##lb);				\
-}
-
-/* convenience macros for instructions */
-#ifdef CONFIG_64BIT
-# define UASM_i_LW(buf, rs, rt, off) uasm_i_ld(buf, rs, rt, off)
-# define UASM_i_SW(buf, rs, rt, off) uasm_i_sd(buf, rs, rt, off)
-# define UASM_i_SLL(buf, rs, rt, sh) uasm_i_dsll(buf, rs, rt, sh)
-# define UASM_i_SRA(buf, rs, rt, sh) uasm_i_dsra(buf, rs, rt, sh)
-# define UASM_i_SRL(buf, rs, rt, sh) uasm_i_dsrl(buf, rs, rt, sh)
-# define UASM_i_MFC0(buf, rt, rd...) uasm_i_dmfc0(buf, rt, rd)
-# define UASM_i_MTC0(buf, rt, rd...) uasm_i_dmtc0(buf, rt, rd)
-# define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_daddiu(buf, rs, rt, val)
-# define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_daddu(buf, rs, rt, rd)
-# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_dsubu(buf, rs, rt, rd)
-# define UASM_i_LL(buf, rs, rt, off) uasm_i_lld(buf, rs, rt, off)
-# define UASM_i_SC(buf, rs, rt, off) uasm_i_scd(buf, rs, rt, off)
-#else
-# define UASM_i_LW(buf, rs, rt, off) uasm_i_lw(buf, rs, rt, off)
-# define UASM_i_SW(buf, rs, rt, off) uasm_i_sw(buf, rs, rt, off)
-# define UASM_i_SLL(buf, rs, rt, sh) uasm_i_sll(buf, rs, rt, sh)
-# define UASM_i_SRA(buf, rs, rt, sh) uasm_i_sra(buf, rs, rt, sh)
-# define UASM_i_SRL(buf, rs, rt, sh) uasm_i_srl(buf, rs, rt, sh)
-# define UASM_i_MFC0(buf, rt, rd...) uasm_i_mfc0(buf, rt, rd)
-# define UASM_i_MTC0(buf, rt, rd...) uasm_i_mtc0(buf, rt, rd)
-# define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_addiu(buf, rs, rt, val)
-# define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_addu(buf, rs, rt, rd)
-# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_subu(buf, rs, rt, rd)
-# define UASM_i_LL(buf, rs, rt, off) uasm_i_ll(buf, rs, rt, off)
-# define UASM_i_SC(buf, rs, rt, off) uasm_i_sc(buf, rs, rt, off)
-#endif
-
-#define uasm_i_b(buf, off) uasm_i_beq(buf, 0, 0, off)
-#define uasm_i_beqz(buf, rs, off) uasm_i_beq(buf, rs, 0, off)
-#define uasm_i_beqzl(buf, rs, off) uasm_i_beql(buf, rs, 0, off)
-#define uasm_i_bnez(buf, rs, off) uasm_i_bne(buf, rs, 0, off)
-#define uasm_i_bnezl(buf, rs, off) uasm_i_bnel(buf, rs, 0, off)
-#define uasm_i_move(buf, a, b) UASM_i_ADDU(buf, a, 0, b)
-#define uasm_i_nop(buf) uasm_i_sll(buf, 0, 0, 0)
-#define uasm_i_ssnop(buf) uasm_i_sll(buf, 0, 0, 1)
-#define uasm_i_ehb(buf) uasm_i_sll(buf, 0, 0, 3)
-
-/* Handle relocations. */
-struct uasm_reloc {
-	u32 *addr;
-	unsigned int type;
-	int lab;
-};
-
-/* This is zero so we can use zeroed label arrays. */
-#define UASM_LABEL_INVALID 0
-
-void uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid);
-void uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab);
-void uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, long off);
-void uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, long off);
-void uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab,
-	u32 *first, u32 *end, u32 *target);
-int uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr);
-
-/* Convenience functions for labeled branches. */
-void uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
-void uasm_il_b(u32 **p, struct uasm_reloc **r, int lid);
-void uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
-void uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
-void uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1,
-		 unsigned int reg2, int lid);
-void uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
-void uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
-void uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/mti-malta/malta-int.c linux-libre-2.6.34-gnu1/arch/mips/mti-malta/malta-int.c
--- linux-libre-2.6.33-gnu1/arch/mips/mti-malta/malta-int.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/mti-malta/malta-int.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,6 @@
 #include <linux/irq.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/kernel_stat.h>
@@ -52,7 +51,7 @@ static unsigned long _msc01_biu_base;
 static unsigned long _gcmp_base;
 static unsigned int ipi_map[NR_CPUS];
 
-static DEFINE_SPINLOCK(mips_irq_lock);
+static DEFINE_RAW_SPINLOCK(mips_irq_lock);
 
 static inline int mips_pcibios_iack(void)
 {
@@ -103,7 +102,7 @@ static inline int get_int(void)
 {
 	unsigned long flags;
 	int irq;
-	spin_lock_irqsave(&mips_irq_lock, flags);
+	raw_spin_lock_irqsave(&mips_irq_lock, flags);
 
 	irq = mips_pcibios_iack();
 
@@ -113,7 +112,7 @@ static inline int get_int(void)
 	 * on an SMP system,  so leave it up to the generic code...
 	 */
 
-	spin_unlock_irqrestore(&mips_irq_lock, flags);
+	raw_spin_unlock_irqrestore(&mips_irq_lock, flags);
 
 	return irq;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx833x/common/interrupts.c linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx833x/common/interrupts.c
--- linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx833x/common/interrupts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx833x/common/interrupts.c	2010-05-16 17:17:36.000000000 -0400
@@ -156,19 +156,19 @@ static int irqflags[PNX833X_PIC_NUM_IRQ]
 #define IRQFLAG_STARTED		1
 #define IRQFLAG_DISABLED	2
 
-static DEFINE_SPINLOCK(pnx833x_irq_lock);
+static DEFINE_RAW_SPINLOCK(pnx833x_irq_lock);
 
 static unsigned int pnx833x_startup_pic_irq(unsigned int irq)
 {
 	unsigned long flags;
 	unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
 
-	spin_lock_irqsave(&pnx833x_irq_lock, flags);
+	raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
 
 	irqflags[pic_irq] = IRQFLAG_STARTED;	/* started, not disabled */
 	pnx833x_hard_enable_pic_irq(pic_irq);
 
-	spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
+	raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
 	return 0;
 }
 
@@ -177,12 +177,12 @@ static void pnx833x_shutdown_pic_irq(uns
 	unsigned long flags;
 	unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
 
-	spin_lock_irqsave(&pnx833x_irq_lock, flags);
+	raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
 
 	irqflags[pic_irq] = 0;			/* not started */
 	pnx833x_hard_disable_pic_irq(pic_irq);
 
-	spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
+	raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
 }
 
 static void pnx833x_enable_pic_irq(unsigned int irq)
@@ -190,13 +190,13 @@ static void pnx833x_enable_pic_irq(unsig
 	unsigned long flags;
 	unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
 
-	spin_lock_irqsave(&pnx833x_irq_lock, flags);
+	raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
 
 	irqflags[pic_irq] &= ~IRQFLAG_DISABLED;
 	if (irqflags[pic_irq] == IRQFLAG_STARTED)
 		pnx833x_hard_enable_pic_irq(pic_irq);
 
-	spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
+	raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
 }
 
 static void pnx833x_disable_pic_irq(unsigned int irq)
@@ -204,12 +204,12 @@ static void pnx833x_disable_pic_irq(unsi
 	unsigned long flags;
 	unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
 
-	spin_lock_irqsave(&pnx833x_irq_lock, flags);
+	raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
 
 	irqflags[pic_irq] |= IRQFLAG_DISABLED;
 	pnx833x_hard_disable_pic_irq(pic_irq);
 
-	spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
+	raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
 }
 
 static void pnx833x_ack_pic_irq(unsigned int irq)
@@ -220,15 +220,15 @@ static void pnx833x_end_pic_irq(unsigned
 {
 }
 
-static DEFINE_SPINLOCK(pnx833x_gpio_pnx833x_irq_lock);
+static DEFINE_RAW_SPINLOCK(pnx833x_gpio_pnx833x_irq_lock);
 
 static unsigned int pnx833x_startup_gpio_irq(unsigned int irq)
 {
 	int pin = irq - PNX833X_GPIO_IRQ_BASE;
 	unsigned long flags;
-	spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
+	raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
 	pnx833x_gpio_enable_irq(pin);
-	spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
+	raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
 	return 0;
 }
 
@@ -236,18 +236,18 @@ static void pnx833x_enable_gpio_irq(unsi
 {
 	int pin = irq - PNX833X_GPIO_IRQ_BASE;
 	unsigned long flags;
-	spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
+	raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
 	pnx833x_gpio_enable_irq(pin);
-	spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
+	raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
 }
 
 static void pnx833x_disable_gpio_irq(unsigned int irq)
 {
 	int pin = irq - PNX833X_GPIO_IRQ_BASE;
 	unsigned long flags;
-	spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
+	raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
 	pnx833x_gpio_disable_irq(pin);
-	spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
+	raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
 }
 
 static void pnx833x_ack_gpio_irq(unsigned int irq)
@@ -258,9 +258,9 @@ static void pnx833x_end_gpio_irq(unsigne
 {
 	int pin = irq - PNX833X_GPIO_IRQ_BASE;
 	unsigned long flags;
-	spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
+	raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
 	pnx833x_gpio_clear_irq(pin);
-	spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
+	raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
 }
 
 static int pnx833x_set_type_gpio_irq(unsigned int irq, unsigned int flow_type)
@@ -377,4 +377,3 @@ void __init plat_time_init(void)
 
 	mips_hpt_frequency *= 500000;
 }
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx833x/common/prom.c linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx833x/common/prom.c
--- linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx833x/common/prom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx833x/common/prom.c	2010-05-16 17:17:36.000000000 -0400
@@ -62,9 +62,3 @@ char __init *prom_getenv(char *envname)
 void __init prom_free_prom_memory(void)
 {
 }
-
-char * __init prom_getcmdline(void)
-{
-	return arcs_cmdline;
-}
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx833x/common/reset.c linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx833x/common/reset.c
--- linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx833x/common/reset.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx833x/common/reset.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,6 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-#include <linux/slab.h>
 #include <linux/reboot.h>
 #include <pnx833x.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx8550/common/int.c linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx8550/common/int.c
--- linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx8550/common/int.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx8550/common/int.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/random.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx8550/common/proc.c linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx8550/common/proc.c
--- linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx8550/common/proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx8550/common/proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/proc_fs.h>
 #include <linux/irq.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/random.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx8550/common/prom.c linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx8550/common/prom.c
--- linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx8550/common/prom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx8550/common/prom.c	2010-05-16 17:17:36.000000000 -0400
@@ -124,6 +124,5 @@ void prom_putchar(char c)
 	}
 }
 
-EXPORT_SYMBOL(prom_getcmdline);
 EXPORT_SYMBOL(get_ethernet_addr);
 EXPORT_SYMBOL(str2eaddr);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx8550/common/reset.c linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx8550/common/reset.c
--- linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx8550/common/reset.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx8550/common/reset.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,7 +20,8 @@
  * Reset the PNX8550 board.
  *
  */
-#include <linux/slab.h>
+#include <linux/kernel.h>
+
 #include <asm/reboot.h>
 #include <glb.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/oprofile/common.c linux-libre-2.6.34-gnu1/arch/mips/oprofile/common.c
--- linux-libre-2.6.33-gnu1/arch/mips/oprofile/common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/oprofile/common.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
  * Copyright (C) 2004, 2005 Ralf Baechle
  * Copyright (C) 2005 MIPS Technologies, Inc.
  */
+#include <linux/compiler.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/oprofile.h>
@@ -14,9 +15,9 @@
 
 #include "op_impl.h"
 
-extern struct op_mips_model op_model_mipsxx_ops __attribute__((weak));
-extern struct op_mips_model op_model_rm9000_ops __attribute__((weak));
-extern struct op_mips_model op_model_loongson2_ops __attribute__((weak));
+extern struct op_mips_model op_model_mipsxx_ops __weak;
+extern struct op_mips_model op_model_rm9000_ops __weak;
+extern struct op_mips_model op_model_loongson2_ops __weak;
 
 static struct op_mips_model *model;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/oprofile/op_model_loongson2.c linux-libre-2.6.34-gnu1/arch/mips/oprofile/op_model_loongson2.c
--- linux-libre-2.6.33-gnu1/arch/mips/oprofile/op_model_loongson2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/oprofile/op_model_loongson2.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2009 Lemote Inc.
  * Author: Yanhua <yanh@lemote.com>
- * Author: Wu Zhangjin <wuzj@lemote.com>
+ * Author: Wu Zhangjin <wuzhangjin@gmail.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
@@ -47,8 +47,6 @@ static struct loongson2_register_config
 	int cnt1_enabled, cnt2_enabled;
 } reg;
 
-DEFINE_SPINLOCK(sample_lock);
-
 static char *oprofid = "LoongsonPerf";
 static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id);
 /* Compute all of the registers in preparation for enabling profiling.  */
@@ -115,7 +113,6 @@ static irqreturn_t loongson2_perfcount_h
 	uint64_t counter, counter1, counter2;
 	struct pt_regs *regs = get_irq_regs();
 	int enabled;
-	unsigned long flags;
 
 	/*
 	 * LOONGSON2 defines two 32-bit performance counters.
@@ -125,7 +122,7 @@ static irqreturn_t loongson2_perfcount_h
 	 */
 
 	/* Check whether the irq belongs to me */
-	enabled = read_c0_perfcnt() & LOONGSON2_PERFCNT_INT_EN;
+	enabled = read_c0_perfctrl() & LOONGSON2_PERFCNT_INT_EN;
 	if (!enabled)
 		return IRQ_NONE;
 	enabled = reg.cnt1_enabled | reg.cnt2_enabled;
@@ -136,8 +133,6 @@ static irqreturn_t loongson2_perfcount_h
 	counter1 = counter & 0xffffffff;
 	counter2 = counter >> 32;
 
-	spin_lock_irqsave(&sample_lock, flags);
-
 	if (counter1 & LOONGSON2_PERFCNT_OVERFLOW) {
 		if (reg.cnt1_enabled)
 			oprofile_add_sample(regs, 0);
@@ -149,8 +144,6 @@ static irqreturn_t loongson2_perfcount_h
 		counter2 = reg.reset_counter2;
 	}
 
-	spin_unlock_irqrestore(&sample_lock, flags);
-
 	write_c0_perfcnt((counter2 << 32) | counter1);
 
 	return IRQ_HANDLED;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pci/fixup-cobalt.c linux-libre-2.6.34-gnu1/arch/mips/pci/fixup-cobalt.c
--- linux-libre-2.6.33-gnu1/arch/mips/pci/fixup-cobalt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pci/fixup-cobalt.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,6 +51,67 @@ static void qube_raq_galileo_early_fixup
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
 	 qube_raq_galileo_early_fixup);
 
+static void __devinit cobalt_legacy_ide_resource_fixup(struct pci_dev *dev,
+						       struct resource *res)
+{
+	struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
+	unsigned long offset = hose->io_offset;
+	struct resource orig = *res;
+
+	if (!(res->flags & IORESOURCE_IO) ||
+	    !(res->flags & IORESOURCE_PCI_FIXED))
+		return;
+
+	res->start -= offset;
+	res->end -= offset;
+	dev_printk(KERN_DEBUG, &dev->dev, "converted legacy %pR to bus %pR\n",
+		   &orig, res);
+}
+
+static void __devinit cobalt_legacy_ide_fixup(struct pci_dev *dev)
+{
+	u32 class;
+	u8 progif;
+
+	/*
+	 * If the IDE controller is in legacy mode, pci_setup_device() fills in
+	 * the resources with the legacy addresses that normally appear on the
+	 * PCI bus, just as if we had read them from a BAR.
+	 *
+	 * However, with the GT-64111, those legacy addresses, e.g., 0x1f0,
+	 * will never appear on the PCI bus because it converts memory accesses
+	 * in the PCI I/O region (which is never at address zero) into I/O port
+	 * accesses with no address translation.
+	 *
+	 * For example, if GT_DEF_PCI0_IO_BASE is 0x10000000, a load or store
+	 * to physical address 0x100001f0 will become a PCI access to I/O port
+	 * 0x100001f0.  There's no way to generate an access to I/O port 0x1f0,
+	 * but the VT82C586 IDE controller does respond at 0x100001f0 because
+	 * it only decodes the low 24 bits of the address.
+	 *
+	 * When this quirk runs, the pci_dev resources should contain bus
+	 * addresses, not Linux I/O port numbers, so convert legacy addresses
+	 * like 0x1f0 to bus addresses like 0x100001f0.  Later, we'll convert
+	 * them back with pcibios_fixup_bus() or pcibios_bus_to_resource().
+	 */
+	class = dev->class >> 8;
+	if (class != PCI_CLASS_STORAGE_IDE)
+		return;
+
+	pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
+	if ((progif & 1) == 0) {
+		cobalt_legacy_ide_resource_fixup(dev, &dev->resource[0]);
+		cobalt_legacy_ide_resource_fixup(dev, &dev->resource[1]);
+	}
+	if ((progif & 4) == 0) {
+		cobalt_legacy_ide_resource_fixup(dev, &dev->resource[2]);
+		cobalt_legacy_ide_resource_fixup(dev, &dev->resource[3]);
+	}
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
+	  cobalt_legacy_ide_fixup);
+
 static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
 {
 	unsigned short cfgword;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pci/fixup-lemote2f.c linux-libre-2.6.34-gnu1/arch/mips/pci/fixup-lemote2f.c
--- linux-libre-2.6.33-gnu1/arch/mips/pci/fixup-lemote2f.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pci/fixup-lemote2f.c	2010-05-16 17:17:36.000000000 -0400
@@ -131,7 +131,7 @@ static void __init loongson_cs5536_ehci_
 
 	/* Serial short detect enable */
 	_rdmsr(USB_MSR_REG(USB_CONFIG), &hi, &lo);
-	_wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 2) | (1 << 3), lo);
+	_wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 3), lo);
 
 	/* setting the USB2.0 micro frame length */
 	pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pci/ops-loongson2.c linux-libre-2.6.34-gnu1/arch/mips/pci/ops-loongson2.c
--- linux-libre-2.6.33-gnu1/arch/mips/pci/ops-loongson2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pci/ops-loongson2.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,13 +1,11 @@
 /*
- * fuloong2e specific PCI support.
- *
  * Copyright (C) 1999, 2000, 2004  MIPS Technologies, Inc.
  *	All rights reserved.
  *	Authors: Carsten Langgaard <carstenl@mips.com>
  *		 Maciej W. Rozycki <macro@mips.com>
  *
  * Copyright (C) 2009 Lemote Inc.
- * Author: Wu Zhangjin <wuzj@lemote.com>
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
@@ -182,15 +180,21 @@ struct pci_ops loongson_pci_ops = {
 };
 
 #ifdef CONFIG_CS5536
+DEFINE_RAW_SPINLOCK(msr_lock);
+
 void _rdmsr(u32 msr, u32 *hi, u32 *lo)
 {
 	struct pci_bus bus = {
 		.number = PCI_BUS_CS5536
 	};
 	u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&msr_lock, flags);
 	loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
 	loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
 	loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+	raw_spin_unlock_irqrestore(&msr_lock, flags);
 }
 EXPORT_SYMBOL(_rdmsr);
 
@@ -200,9 +204,13 @@ void _wrmsr(u32 msr, u32 hi, u32 lo)
 		.number = PCI_BUS_CS5536
 	};
 	u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&msr_lock, flags);
 	loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
 	loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
 	loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+	raw_spin_unlock_irqrestore(&msr_lock, flags);
 }
 EXPORT_SYMBOL(_wrmsr);
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pci/ops-pmcmsp.c linux-libre-2.6.34-gnu1/arch/mips/pci/ops-pmcmsp.c
--- linux-libre-2.6.33-gnu1/arch/mips/pci/ops-pmcmsp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pci/ops-pmcmsp.c	2010-05-16 17:17:36.000000000 -0400
@@ -206,7 +206,7 @@ static void pci_proc_init(void)
 }
 #endif /* CONFIG_PROC_FS && PCI_COUNTERS */
 
-DEFINE_SPINLOCK(bpci_lock);
+static DEFINE_SPINLOCK(bpci_lock);
 
 /*****************************************************************************
  *
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pci/ops-titan-ht.c linux-libre-2.6.34-gnu1/arch/mips/pci/ops-titan-ht.c
--- linux-libre-2.6.33-gnu1/arch/mips/pci/ops-titan-ht.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pci/ops-titan-ht.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <asm/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pci/pci-bcm47xx.c linux-libre-2.6.34-gnu1/arch/mips/pci/pci-bcm47xx.c
--- linux-libre-2.6.33-gnu1/arch/mips/pci/pci-bcm47xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pci/pci-bcm47xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,4 +57,3 @@ int pcibios_plat_dev_init(struct pci_dev
 	dev->irq = res;
 	return 0;
 }
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pci/pci.c linux-libre-2.6.34-gnu1/arch/mips/pci/pci.c
--- linux-libre-2.6.33-gnu1/arch/mips/pci/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pci/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,8 +49,8 @@ static int pci_initialized;
  * but we want to try to avoid allocating at 0x2900-0x2bff
  * which might have be mirrored at 0x0100-0x03ff..
  */
-void
-pcibios_align_resource(void *data, struct resource *res,
+resource_size_t
+pcibios_align_resource(void *data, const struct resource *res,
 		       resource_size_t size, resource_size_t align)
 {
 	struct pci_dev *dev = data;
@@ -73,7 +73,7 @@ pcibios_align_resource(void *data, struc
 			start = PCIBIOS_MIN_MEM + hose->mem_resource->start;
 	}
 
-	res->start = start;
+	return start;
 }
 
 static void __devinit pcibios_scanbus(struct pci_controller *hose)
@@ -251,8 +251,6 @@ static void pcibios_fixup_device_resourc
 	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
 		if (!dev->resource[i].start)
 			continue;
-		if (dev->resource[i].flags & IORESOURCE_PCI_FIXED)
-			continue;
 		if (dev->resource[i].flags & IORESOURCE_IO)
 			offset = hose->io_offset;
 		else if (dev->resource[i].flags & IORESOURCE_MEM)
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pci/pci-octeon.c linux-libre-2.6.34-gnu1/arch/mips/pci/pci-octeon.c
--- linux-libre-2.6.33-gnu1/arch/mips/pci/pci-octeon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pci/pci-octeon.c	2010-05-16 17:17:36.000000000 -0400
@@ -209,16 +209,14 @@ const char *octeon_get_pci_interrupts(vo
 	case CVMX_BOARD_TYPE_NAO38:
 		/* This is really the NAC38 */
 		return "AAAAADABAAAAAAAAAAAAAAAAAAAAAAAA";
-	case CVMX_BOARD_TYPE_THUNDER:
-		return "";
-	case CVMX_BOARD_TYPE_EBH3000:
-		return "";
 	case CVMX_BOARD_TYPE_EBH3100:
 	case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
 	case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
 		return "AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
 	case CVMX_BOARD_TYPE_BBGW_REF:
 		return "AABCD";
+	case CVMX_BOARD_TYPE_THUNDER:
+	case CVMX_BOARD_TYPE_EBH3000:
 	default:
 		return "";
 	}
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pci/pci-sb1250.c linux-libre-2.6.34-gnu1/arch/mips/pci/pci-sb1250.c
--- linux-libre-2.6.33-gnu1/arch/mips/pci/pci-sb1250.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pci/pci-sb1250.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/mm.h>
 #include <linux/console.h>
 #include <linux/tty.h>
+#include <linux/vt.h>
 
 #include <asm/io.h>
 
@@ -254,7 +255,7 @@ static int __init sb1250_pcibios_init(vo
 	 * XXX ehs: Should this happen in PCI Device mode?
 	 */
 	io_map_base = ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 1024 * 1024);
-	sb1250_controller.io_map_base = io_map_base;
+	sb1250_controller.io_map_base = (unsigned long)io_map_base;
 	set_io_port_base((unsigned long)io_map_base);
 
 #ifdef CONFIG_SIBYTE_HAS_LDT
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c linux-libre-2.6.34-gnu1/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
--- linux-libre-2.6.33-gnu1/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c	2010-05-16 17:17:36.000000000 -0400
@@ -131,4 +131,3 @@ void msp_cic_irq_dispatch(void)
 	else
 		do_IRQ(ffs(pending) + intbase - 1);
 }
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pmc-sierra/msp71xx/msp_prom.c linux-libre-2.6.34-gnu1/arch/mips/pmc-sierra/msp71xx/msp_prom.c
--- linux-libre-2.6.33-gnu1/arch/mips/pmc-sierra/msp71xx/msp_prom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pmc-sierra/msp71xx/msp_prom.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/string.h>
 #include <linux/interrupt.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
@@ -303,12 +304,6 @@ char *prom_getenv(char *env_name)
 }
 
 /* PROM commandline functions */
-char *prom_getcmdline(void)
-{
-	return &(arcs_cmdline[0]);
-}
-EXPORT_SYMBOL(prom_getcmdline);
-
 void  __init prom_init_cmdline(void)
 {
 	char *cp;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c linux-libre-2.6.34-gnu1/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
--- linux-libre-2.6.33-gnu1/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c	2010-05-16 17:17:36.000000000 -0400
@@ -127,7 +127,7 @@ static int recv_ack(void)
 
 	if (ack) {
 		do_idle();
-		printk(KERN_ERR "Error reading the Atmel 24C32/24C64 EEPROM \n");
+		printk(KERN_ERR "Error reading the Atmel 24C32/24C64 EEPROM\n");
 		return -1;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h linux-libre-2.6.34-gnu1/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
--- linux-libre-2.6.33-gnu1/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h	2010-05-16 17:17:36.000000000 -0400
@@ -65,4 +65,3 @@
 const char rts = TIOCM_RTS;
 const char dtr = TIOCM_DTR;
 int fd;
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pmc-sierra/yosemite/ht.c linux-libre-2.6.34-gnu1/arch/mips/pmc-sierra/yosemite/ht.c
--- linux-libre-2.6.33-gnu1/arch/mips/pmc-sierra/yosemite/ht.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pmc-sierra/yosemite/ht.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <asm/pci.h>
 #include <asm/io.h>
 
@@ -345,14 +344,13 @@ int pcibios_enable_device(struct pci_dev
         return pcibios_enable_resources(dev);
 }
 
-void pcibios_align_resource(void *data, struct resource *res,
-                            resource_size_t size, resource_size_t align)
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+				resource_size_t size, resource_size_t align)
 {
         struct pci_dev *dev = data;
+	resource_size_t start = res->start;
 
         if (res->flags & IORESOURCE_IO) {
-                resource_size_t start = res->start;
-
                 /* We need to avoid collisions with `mirrored' VGA ports
                    and other strange ISA hardware, so we always want the
                    addresses kilobyte aligned.  */
@@ -363,8 +361,9 @@ void pcibios_align_resource(void *data,
                 }
 
                 start = (start + 1024 - 1) & ~(1024 - 1);
-                res->start = start;
         }
+
+	return start;
 }
 
 struct pci_ops titan_pci_ops = {
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pmc-sierra/yosemite/irq.c linux-libre-2.6.34-gnu1/arch/mips/pmc-sierra/yosemite/irq.c
--- linux-libre-2.6.33-gnu1/arch/mips/pmc-sierra/yosemite/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pmc-sierra/yosemite/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,7 +37,6 @@
 #include <linux/ioport.h>
 #include <linux/irq.h>
 #include <linux/timex.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/bitops.h>
 #include <asm/bootinfo.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/pmc-sierra/yosemite/smp.c linux-libre-2.6.34-gnu1/arch/mips/pmc-sierra/yosemite/smp.c
--- linux-libre-2.6.33-gnu1/arch/mips/pmc-sierra/yosemite/smp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/pmc-sierra/yosemite/smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,7 @@
 
 #define LAUNCHSTACK_SIZE 256
 
-static __cpuinitdata DEFINE_SPINLOCK(launch_lock);
+static __cpuinitdata arch_spinlock_t launch_lock = __ARCH_SPIN_LOCK_UNLOCKED;
 
 static unsigned long secondary_sp __cpuinitdata;
 static unsigned long secondary_gp __cpuinitdata;
@@ -20,7 +20,7 @@ static void __init prom_smp_bootstrap(vo
 {
 	local_irq_disable();
 
-	while (spin_is_locked(&launch_lock));
+	while (arch_spin_is_locked(&launch_lock));
 
 	__asm__ __volatile__(
 	"	move	$sp, %0		\n"
@@ -37,7 +37,7 @@ static void __init prom_smp_bootstrap(vo
  */
 void __init prom_grab_secondary(void)
 {
-	spin_lock(&launch_lock);
+	arch_spin_lock(&launch_lock);
 
 	pmon_cpustart(1, &prom_smp_bootstrap,
 	              launchstack + LAUNCHSTACK_SIZE, 0);
@@ -138,7 +138,7 @@ static void __cpuinit yos_boot_secondary
 	secondary_sp = sp;
 	secondary_gp = gp;
 
-	spin_unlock(&launch_lock);
+	arch_spin_unlock(&launch_lock);
 }
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/power/cpu.c linux-libre-2.6.34-gnu1/arch/mips/power/cpu.c
--- linux-libre-2.6.33-gnu1/arch/mips/power/cpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/power/cpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,9 +3,9 @@
  *
  * Licensed under the GPLv2
  *
- * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Copyright (C) 2009 Lemote Inc.
  * Author: Hu Hongbing <huhb@lemote.com>
- *         Wu Zhangjin <wuzj@lemote.com>
+ *         Wu Zhangjin <wuzhangjin@gmail.com>
  */
 #include <asm/suspend.h>
 #include <asm/fpu.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/power/hibernate.S linux-libre-2.6.34-gnu1/arch/mips/power/hibernate.S
--- linux-libre-2.6.33-gnu1/arch/mips/power/hibernate.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/power/hibernate.S	2010-05-16 17:17:36.000000000 -0400
@@ -3,9 +3,9 @@
  *
  * Licensed under the GPLv2
  *
- * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Copyright (C) 2009 Lemote Inc.
  * Author: Hu Hongbing <huhb@lemote.com>
- *         Wu Zhangjin <wuzj@lemote.com>
+ *         Wu Zhangjin <wuzhangjin@gmail.com>
  */
 #include <asm/asm-offsets.h>
 #include <asm/page.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/asic_devices.c linux-libre-2.6.34-gnu1/arch/mips/powertv/asic/asic_devices.c
--- linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/asic_devices.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/powertv/asic/asic_devices.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/mm.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <asm/page.h>
 #include <linux/swap.h>
 #include <linux/highmem.h>
@@ -340,10 +341,6 @@ static void __init platform_configure_us
 
 	switch (asic) {
 	case ASIC_ZEUS:
-		fs_update(0x0000, 0x11, 0x02, 0);
-		bcm1_usb2_ctl = 0x803;
-		break;
-
 	case ASIC_CRONUS:
 	case ASIC_CRONUSLITE:
 		fs_update(0x0000, 0x11, 0x02, 0);
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/asic_int.c linux-libre-2.6.34-gnu1/arch/mips/powertv/asic/asic_int.c
--- linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/asic_int.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/powertv/asic/asic_int.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/kernel.h>
@@ -39,21 +38,21 @@
 
 #include <asm/mach-powertv/asic_regs.h>
 
-static DEFINE_SPINLOCK(asic_irq_lock);
+static DEFINE_RAW_SPINLOCK(asic_irq_lock);
 
 static inline int get_int(void)
 {
 	unsigned long flags;
 	int irq;
 
-	spin_lock_irqsave(&asic_irq_lock, flags);
+	raw_spin_lock_irqsave(&asic_irq_lock, flags);
 
 	irq = (asic_read(int_int_scan) >> 4) - 1;
 
 	if (irq == 0 || irq >= NR_IRQS)
 		irq = -1;
 
-	spin_unlock_irqrestore(&asic_irq_lock, flags);
+	raw_spin_unlock_irqrestore(&asic_irq_lock, flags);
 
 	return irq;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/powertv/powertv_setup.c linux-libre-2.6.34-gnu1/arch/mips/powertv/powertv_setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/powertv/powertv_setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/powertv/powertv_setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,14 +25,15 @@
 #include <linux/etherdevice.h>
 #include <linux/if_ether.h>
 #include <linux/ctype.h>
-
 #include <linux/cpu.h>
+#include <linux/time.h>
+
 #include <asm/bootinfo.h>
 #include <asm/irq.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/prom.h>
 #include <asm/dma.h>
-#include <linux/time.h>
+#include <asm/asm.h>
 #include <asm/traps.h>
 #include <asm/asm-offsets.h>
 #include "reset.h"
@@ -41,26 +42,21 @@
 
 /*
  * Macros for loading addresses and storing registers:
- * PTR_LA	Load the address into a register
- * LONG_S	Store the full width of the given register.
- * LONG_L	Load the full width of the given register
- * PTR_ADDIU	Add a constant value to a register used as a pointer
+ * LONG_L_	Stringified version of LONG_L for use in asm() statement
+ * LONG_S_	Stringified version of LONG_S for use in asm() statement
+ * PTR_LA_	Stringified version of PTR_LA for use in asm() statement
  * REG_SIZE	Number of 8-bit bytes in a full width register
  */
+#define LONG_L_		VAL(LONG_L) " "
+#define LONG_S_		VAL(LONG_S) " "
+#define PTR_LA_		VAL(PTR_LA) " "
+
 #ifdef CONFIG_64BIT
 #warning TODO: 64-bit code needs to be verified
-#define PTR_LA		"dla	"
-#define LONG_S		"sd	"
-#define LONG_L		"ld	"
-#define PTR_ADDIU	"daddiu	"
 #define REG_SIZE	"8"		/* In bytes */
 #endif
 
 #ifdef CONFIG_32BIT
-#define PTR_LA		"la	"
-#define LONG_S		"sw	"
-#define LONG_L		"lw	"
-#define PTR_ADDIU	"addiu	"
 #define REG_SIZE	"4"		/* In bytes */
 #endif
 
@@ -113,9 +109,9 @@ static int panic_handler(struct notifier
 		 * structure. */
 		__asm__ __volatile__ (
 			".set	noat\n"
-			LONG_S		"$at, %[at]\n"
-			LONG_S		"$2, %[v0]\n"
-			LONG_S		"$3, %[v1]\n"
+			LONG_S_		"$at, %[at]\n"
+			LONG_S_		"$2, %[v0]\n"
+			LONG_S_		"$3, %[v1]\n"
 		:
 			[at] "=m" (at),
 			[v0] "=m" (v0),
@@ -129,54 +125,54 @@ static int panic_handler(struct notifier
 			"move		$at, %[pt_regs]\n"
 
 			/* Argument registers */
-			LONG_S		"$4, " VAL(PT_R4) "($at)\n"
-			LONG_S		"$5, " VAL(PT_R5) "($at)\n"
-			LONG_S		"$6, " VAL(PT_R6) "($at)\n"
-			LONG_S		"$7, " VAL(PT_R7) "($at)\n"
+			LONG_S_		"$4, " VAL(PT_R4) "($at)\n"
+			LONG_S_		"$5, " VAL(PT_R5) "($at)\n"
+			LONG_S_		"$6, " VAL(PT_R6) "($at)\n"
+			LONG_S_		"$7, " VAL(PT_R7) "($at)\n"
 
 			/* Temporary regs */
-			LONG_S		"$8, " VAL(PT_R8) "($at)\n"
-			LONG_S		"$9, " VAL(PT_R9) "($at)\n"
-			LONG_S		"$10, " VAL(PT_R10) "($at)\n"
-			LONG_S		"$11, " VAL(PT_R11) "($at)\n"
-			LONG_S		"$12, " VAL(PT_R12) "($at)\n"
-			LONG_S		"$13, " VAL(PT_R13) "($at)\n"
-			LONG_S		"$14, " VAL(PT_R14) "($at)\n"
-			LONG_S		"$15, " VAL(PT_R15) "($at)\n"
+			LONG_S_		"$8, " VAL(PT_R8) "($at)\n"
+			LONG_S_		"$9, " VAL(PT_R9) "($at)\n"
+			LONG_S_		"$10, " VAL(PT_R10) "($at)\n"
+			LONG_S_		"$11, " VAL(PT_R11) "($at)\n"
+			LONG_S_		"$12, " VAL(PT_R12) "($at)\n"
+			LONG_S_		"$13, " VAL(PT_R13) "($at)\n"
+			LONG_S_		"$14, " VAL(PT_R14) "($at)\n"
+			LONG_S_		"$15, " VAL(PT_R15) "($at)\n"
 
 			/* "Saved" registers */
-			LONG_S		"$16, " VAL(PT_R16) "($at)\n"
-			LONG_S		"$17, " VAL(PT_R17) "($at)\n"
-			LONG_S		"$18, " VAL(PT_R18) "($at)\n"
-			LONG_S		"$19, " VAL(PT_R19) "($at)\n"
-			LONG_S		"$20, " VAL(PT_R20) "($at)\n"
-			LONG_S		"$21, " VAL(PT_R21) "($at)\n"
-			LONG_S		"$22, " VAL(PT_R22) "($at)\n"
-			LONG_S		"$23, " VAL(PT_R23) "($at)\n"
+			LONG_S_		"$16, " VAL(PT_R16) "($at)\n"
+			LONG_S_		"$17, " VAL(PT_R17) "($at)\n"
+			LONG_S_		"$18, " VAL(PT_R18) "($at)\n"
+			LONG_S_		"$19, " VAL(PT_R19) "($at)\n"
+			LONG_S_		"$20, " VAL(PT_R20) "($at)\n"
+			LONG_S_		"$21, " VAL(PT_R21) "($at)\n"
+			LONG_S_		"$22, " VAL(PT_R22) "($at)\n"
+			LONG_S_		"$23, " VAL(PT_R23) "($at)\n"
 
 			/* Add'l temp regs */
-			LONG_S		"$24, " VAL(PT_R24) "($at)\n"
-			LONG_S		"$25, " VAL(PT_R25) "($at)\n"
+			LONG_S_		"$24, " VAL(PT_R24) "($at)\n"
+			LONG_S_		"$25, " VAL(PT_R25) "($at)\n"
 
 			/* Kernel temp regs */
-			LONG_S		"$26, " VAL(PT_R26) "($at)\n"
-			LONG_S		"$27, " VAL(PT_R27) "($at)\n"
+			LONG_S_		"$26, " VAL(PT_R26) "($at)\n"
+			LONG_S_		"$27, " VAL(PT_R27) "($at)\n"
 
 			/* Global pointer, stack pointer, frame pointer and
 			 * return address */
-			LONG_S		"$gp, " VAL(PT_R28) "($at)\n"
-			LONG_S		"$sp, " VAL(PT_R29) "($at)\n"
-			LONG_S		"$fp, " VAL(PT_R30) "($at)\n"
-			LONG_S		"$ra, " VAL(PT_R31) "($at)\n"
+			LONG_S_		"$gp, " VAL(PT_R28) "($at)\n"
+			LONG_S_		"$sp, " VAL(PT_R29) "($at)\n"
+			LONG_S_		"$fp, " VAL(PT_R30) "($at)\n"
+			LONG_S_		"$ra, " VAL(PT_R31) "($at)\n"
 
 			/* Now we can get the $at and v0 registers back and
 			 * store them */
-			LONG_L		"$8, %[at]\n"
-			LONG_S		"$8, " VAL(PT_R1) "($at)\n"
-			LONG_L		"$8, %[v0]\n"
-			LONG_S		"$8, " VAL(PT_R2) "($at)\n"
-			LONG_L		"$8, %[v1]\n"
-			LONG_S		"$8, " VAL(PT_R3) "($at)\n"
+			LONG_L_		"$8, %[at]\n"
+			LONG_S_		"$8, " VAL(PT_R1) "($at)\n"
+			LONG_L_		"$8, %[v0]\n"
+			LONG_S_		"$8, " VAL(PT_R2) "($at)\n"
+			LONG_L_		"$8, %[v1]\n"
+			LONG_S_		"$8, " VAL(PT_R3) "($at)\n"
 		:
 		:
 			[at] "m" (at),
@@ -191,8 +187,8 @@ static int panic_handler(struct notifier
 		__asm__ __volatile__ (
 			".set	noat\n"
 		"1:\n"
-			PTR_LA		"$at, 1b\n"
-			LONG_S		"$at, %[cp0_epc]\n"
+			PTR_LA_		"$at, 1b\n"
+			LONG_S_		"$at, %[cp0_epc]\n"
 		:
 			[cp0_epc] "=m" (my_regs.cp0_epc)
 		:
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/rb532/irq.c linux-libre-2.6.34-gnu1/arch/mips/rb532/irq.c
--- linux-libre-2.6.33-gnu1/arch/mips/rb532/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/rb532/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,7 +36,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/timex.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/delay.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/sgi-ip22/ip22-berr.c linux-libre-2.6.34-gnu1/arch/mips/sgi-ip22/ip22-berr.c
--- linux-libre-2.6.33-gnu1/arch/mips/sgi-ip22/ip22-berr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/sgi-ip22/ip22-berr.c	2010-05-16 17:17:36.000000000 -0400
@@ -89,7 +89,7 @@ static void print_buserr(void)
 void ip22_be_interrupt(int irq)
 {
 	const int field = 2 * sizeof(unsigned long);
-	const struct pt_regs *regs = get_irq_regs();
+	struct pt_regs *regs = get_irq_regs();
 
 	save_and_clear_buserr();
 	print_buserr();
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/sgi-ip22/ip28-berr.c linux-libre-2.6.34-gnu1/arch/mips/sgi-ip22/ip28-berr.c
--- linux-libre-2.6.33-gnu1/arch/mips/sgi-ip22/ip28-berr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/sgi-ip22/ip28-berr.c	2010-05-16 17:17:36.000000000 -0400
@@ -453,7 +453,7 @@ mips_be_fatal:
 
 void ip22_be_interrupt(int irq)
 {
-	const struct pt_regs *regs = get_irq_regs();
+	struct pt_regs *regs = get_irq_regs();
 
 	count_be_interrupt++;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/sgi-ip27/ip27-irq.c linux-libre-2.6.34-gnu1/arch/mips/sgi-ip27/ip27-irq.c
--- linux-libre-2.6.33-gnu1/arch/mips/sgi-ip27/ip27-irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/sgi-ip27/ip27-irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/timex.h>
-#include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/random.h>
 #include <linux/kernel.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/sgi-ip27/ip27-klnuma.c linux-libre-2.6.34-gnu1/arch/mips/sgi-ip27/ip27-klnuma.c
--- linux-libre-2.6.33-gnu1/arch/mips/sgi-ip27/ip27-klnuma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/sgi-ip27/ip27-klnuma.c	2010-05-16 17:17:36.000000000 -0400
@@ -133,4 +133,3 @@ pfn_t node_getfirstfree(cnodeid_t cnode)
 		return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >>
 								PAGE_SHIFT);
 }
-
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/sgi-ip27/ip27-nmi.c linux-libre-2.6.34-gnu1/arch/mips/sgi-ip27/ip27-nmi.c
--- linux-libre-2.6.33-gnu1/arch/mips/sgi-ip27/ip27-nmi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/sgi-ip27/ip27-nmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,11 +17,10 @@
 #endif
 
 #define CNODEID_NONE (cnodeid_t)-1
-#define enter_panic_mode()	spin_lock(&nmi_lock)
 
 typedef unsigned long machreg_t;
 
-DEFINE_SPINLOCK(nmi_lock);
+static arch_spinlock_t nmi_lock = __ARCH_SPIN_LOCK_UNLOCKED;
 
 /*
  * Lets see what else we need to do here. Set up sp, gp?
@@ -193,9 +192,9 @@ cont_nmi_dump(void)
 	atomic_inc(&nmied_cpus);
 #endif
 	/*
-	 * Use enter_panic_mode to allow only 1 cpu to proceed
+	 * Only allow 1 cpu to proceed
 	 */
-	enter_panic_mode();
+	arch_spin_lock(&nmi_lock);
 
 #ifdef REAL_NMI_SIGNAL
 	/*
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/sgi-ip32/ip32-irq.c linux-libre-2.6.34-gnu1/arch/mips/sgi-ip32/ip32-irq.c
--- linux-libre-2.6.33-gnu1/arch/mips/sgi-ip32/ip32-irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/sgi-ip32/ip32-irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/irq.h>
 #include <linux/bitops.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/random.h>
 #include <linux/sched.h>
@@ -512,10 +511,6 @@ void __init arch_init_irq(void)
 				"level");
 			break;
 
-		case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ:
-			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_and_handler_name(irq,
@@ -523,12 +518,9 @@ void __init arch_init_irq(void)
 				"level");
 			break;
 
+		case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ:
 		case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ:
 		case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ:
-			set_irq_chip_and_handler_name(irq,
-				&crime_edge_interrupt, handle_edge_irq, "edge");
-			break;
-
 		case CRIME_VICE_IRQ:
 			set_irq_chip_and_handler_name(irq,
 				&crime_edge_interrupt, handle_edge_irq, "edge");
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/sibyte/bcm1480/irq.c linux-libre-2.6.34-gnu1/arch/mips/sibyte/bcm1480/irq.c
--- linux-libre-2.6.33-gnu1/arch/mips/sibyte/bcm1480/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/sibyte/bcm1480/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/smp.h>
 #include <linux/spinlock.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/kernel_stat.h>
 
 #include <asm/errno.h>
@@ -73,14 +72,14 @@ static struct irq_chip bcm1480_irq_type
 /* Store the CPU id (not the logical number) */
 int bcm1480_irq_owner[BCM1480_NR_IRQS];
 
-DEFINE_SPINLOCK(bcm1480_imr_lock);
+static DEFINE_RAW_SPINLOCK(bcm1480_imr_lock);
 
 void bcm1480_mask_irq(int cpu, int irq)
 {
 	unsigned long flags, hl_spacing;
 	u64 cur_ints;
 
-	spin_lock_irqsave(&bcm1480_imr_lock, flags);
+	raw_spin_lock_irqsave(&bcm1480_imr_lock, flags);
 	hl_spacing = 0;
 	if ((irq >= BCM1480_NR_IRQS_HALF) && (irq <= BCM1480_NR_IRQS)) {
 		hl_spacing = BCM1480_IMR_HL_SPACING;
@@ -89,7 +88,7 @@ void bcm1480_mask_irq(int cpu, int irq)
 	cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
 	cur_ints |= (((u64) 1) << irq);
 	____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
-	spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
+	raw_spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
 }
 
 void bcm1480_unmask_irq(int cpu, int irq)
@@ -97,7 +96,7 @@ void bcm1480_unmask_irq(int cpu, int irq
 	unsigned long flags, hl_spacing;
 	u64 cur_ints;
 
-	spin_lock_irqsave(&bcm1480_imr_lock, flags);
+	raw_spin_lock_irqsave(&bcm1480_imr_lock, flags);
 	hl_spacing = 0;
 	if ((irq >= BCM1480_NR_IRQS_HALF) && (irq <= BCM1480_NR_IRQS)) {
 		hl_spacing = BCM1480_IMR_HL_SPACING;
@@ -106,7 +105,7 @@ void bcm1480_unmask_irq(int cpu, int irq
 	cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
 	cur_ints &= ~(((u64) 1) << irq);
 	____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
-	spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
+	raw_spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
 }
 
 #ifdef CONFIG_SMP
@@ -123,7 +122,7 @@ static int bcm1480_set_affinity(unsigned
 	cpu = cpu_logical_map(i);
 
 	/* Protect against other affinity changers and IMR manipulation */
-	spin_lock_irqsave(&bcm1480_imr_lock, flags);
+	raw_spin_lock_irqsave(&bcm1480_imr_lock, flags);
 
 	/* Swizzle each CPU's IMR (but leave the IP selection alone) */
 	old_cpu = bcm1480_irq_owner[irq];
@@ -148,7 +147,7 @@ static int bcm1480_set_affinity(unsigned
 			____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
 		}
 	}
-	spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
+	raw_spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/sibyte/common/sb_tbprof.c linux-libre-2.6.34-gnu1/arch/mips/sibyte/common/sb_tbprof.c
--- linux-libre-2.6.33-gnu1/arch/mips/sibyte/common/sb_tbprof.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/sibyte/common/sb_tbprof.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,8 +27,6 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
 #include <linux/errno.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/sibyte/sb1250/irq.c linux-libre-2.6.34-gnu1/arch/mips/sibyte/sb1250/irq.c
--- linux-libre-2.6.33-gnu1/arch/mips/sibyte/sb1250/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/sibyte/sb1250/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/spinlock.h>
 #include <linux/smp.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/kernel_stat.h>
 
 #include <asm/errno.h>
@@ -72,20 +71,20 @@ static struct irq_chip sb1250_irq_type =
 /* Store the CPU id (not the logical number) */
 int sb1250_irq_owner[SB1250_NR_IRQS];
 
-DEFINE_SPINLOCK(sb1250_imr_lock);
+static DEFINE_RAW_SPINLOCK(sb1250_imr_lock);
 
 void sb1250_mask_irq(int cpu, int irq)
 {
 	unsigned long flags;
 	u64 cur_ints;
 
-	spin_lock_irqsave(&sb1250_imr_lock, flags);
+	raw_spin_lock_irqsave(&sb1250_imr_lock, flags);
 	cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
 					R_IMR_INTERRUPT_MASK));
 	cur_ints |= (((u64) 1) << irq);
 	____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
 					R_IMR_INTERRUPT_MASK));
-	spin_unlock_irqrestore(&sb1250_imr_lock, flags);
+	raw_spin_unlock_irqrestore(&sb1250_imr_lock, flags);
 }
 
 void sb1250_unmask_irq(int cpu, int irq)
@@ -93,13 +92,13 @@ void sb1250_unmask_irq(int cpu, int irq)
 	unsigned long flags;
 	u64 cur_ints;
 
-	spin_lock_irqsave(&sb1250_imr_lock, flags);
+	raw_spin_lock_irqsave(&sb1250_imr_lock, flags);
 	cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
 					R_IMR_INTERRUPT_MASK));
 	cur_ints &= ~(((u64) 1) << irq);
 	____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
 					R_IMR_INTERRUPT_MASK));
-	spin_unlock_irqrestore(&sb1250_imr_lock, flags);
+	raw_spin_unlock_irqrestore(&sb1250_imr_lock, flags);
 }
 
 #ifdef CONFIG_SMP
@@ -115,7 +114,7 @@ static int sb1250_set_affinity(unsigned
 	cpu = cpu_logical_map(i);
 
 	/* Protect against other affinity changers and IMR manipulation */
-	spin_lock_irqsave(&sb1250_imr_lock, flags);
+	raw_spin_lock_irqsave(&sb1250_imr_lock, flags);
 
 	/* Swizzle each CPU's IMR (but leave the IP selection alone) */
 	old_cpu = sb1250_irq_owner[irq];
@@ -137,7 +136,7 @@ static int sb1250_set_affinity(unsigned
 		____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
 					R_IMR_INTERRUPT_MASK));
 	}
-	spin_unlock_irqrestore(&sb1250_imr_lock, flags);
+	raw_spin_unlock_irqrestore(&sb1250_imr_lock, flags);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/sibyte/sb1250/setup.c linux-libre-2.6.34-gnu1/arch/mips/sibyte/sb1250/setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/sibyte/sb1250/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/sibyte/sb1250/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -87,6 +87,21 @@ static int __init setup_bcm1250(void)
 	return ret;
 }
 
+int sb1250_m3_workaround_needed(void)
+{
+	switch (soc_type) {
+	case K_SYS_SOC_TYPE_BCM1250:
+	case K_SYS_SOC_TYPE_BCM1250_ALT:
+	case K_SYS_SOC_TYPE_BCM1250_ALT2:
+	case K_SYS_SOC_TYPE_BCM1125:
+	case K_SYS_SOC_TYPE_BCM1125H:
+		return soc_pass < K_SYS_REVISION_BCM1250_C0;
+
+	default:
+		return 0;
+	}
+}
+
 static int __init setup_bcm112x(void)
 {
 	int ret = 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/sibyte/swarm/setup.c linux-libre-2.6.34-gnu1/arch/mips/sibyte/swarm/setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/sibyte/swarm/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/sibyte/swarm/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -145,15 +145,14 @@ void __init plat_mem_setup(void)
 
 #ifdef CONFIG_VT
 	screen_info = (struct screen_info) {
-		0, 0,           /* orig-x, orig-y */
-		0,              /* unused */
-		52,             /* orig_video_page */
-		3,              /* orig_video_mode */
-		80,             /* orig_video_cols */
-		4626, 3, 9,     /* unused, ega_bx, unused */
-		25,             /* orig_video_lines */
-		0x22,           /* orig_video_isVGA */
-		16              /* orig_video_points */
+		.orig_video_page	= 52,
+		.orig_video_mode	= 3,
+		.orig_video_cols	= 80,
+		.flags			= 12,
+		.orig_video_ega_bx	= 3,
+		.orig_video_lines	= 25,
+		.orig_video_isVGA	= 0x22,
+		.orig_video_points	= 16,
        };
        /* XXXKW for CFE, get lines/cols from environment */
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/sni/rm200.c linux-libre-2.6.34-gnu1/arch/mips/sni/rm200.c
--- linux-libre-2.6.33-gnu1/arch/mips/sni/rm200.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/sni/rm200.c	2010-05-16 17:17:36.000000000 -0400
@@ -132,7 +132,7 @@ device_initcall(snirm_setup_devinit);
  * readb/writeb to access them
  */
 
-DEFINE_SPINLOCK(sni_rm200_i8259A_lock);
+static DEFINE_RAW_SPINLOCK(sni_rm200_i8259A_lock);
 #define PIC_CMD    0x00
 #define PIC_IMR    0x01
 #define PIC_ISR    PIC_CMD
@@ -161,13 +161,13 @@ static void sni_rm200_disable_8259A_irq(
 
 	irq -= RM200_I8259A_IRQ_BASE;
 	mask = 1 << irq;
-	spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
+	raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
 	rm200_cached_irq_mask |= mask;
 	if (irq & 8)
 		writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
 	else
 		writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
-	spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
 }
 
 static void sni_rm200_enable_8259A_irq(unsigned int irq)
@@ -177,13 +177,13 @@ static void sni_rm200_enable_8259A_irq(u
 
 	irq -= RM200_I8259A_IRQ_BASE;
 	mask = ~(1 << irq);
-	spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
+	raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
 	rm200_cached_irq_mask &= mask;
 	if (irq & 8)
 		writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
 	else
 		writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
-	spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
 }
 
 static inline int sni_rm200_i8259A_irq_real(unsigned int irq)
@@ -216,7 +216,7 @@ void sni_rm200_mask_and_ack_8259A(unsign
 
 	irq -= RM200_I8259A_IRQ_BASE;
 	irqmask = 1 << irq;
-	spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
+	raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
 	/*
 	 * Lightweight spurious IRQ detection. We do not want
 	 * to overdo spurious IRQ handling - it's usually a sign
@@ -247,7 +247,7 @@ handle_real_irq:
 		writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
 		writeb(0x60+irq, rm200_pic_master + PIC_CMD);
 	}
-	spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
 	return;
 
 spurious_8259A_irq:
@@ -298,7 +298,7 @@ static inline int sni_rm200_i8259_irq(vo
 {
 	int irq;
 
-	spin_lock(&sni_rm200_i8259A_lock);
+	raw_spin_lock(&sni_rm200_i8259A_lock);
 
 	/* Perform an interrupt acknowledge cycle on controller 1. */
 	writeb(0x0C, rm200_pic_master + PIC_CMD);	/* prepare for poll */
@@ -325,7 +325,7 @@ static inline int sni_rm200_i8259_irq(vo
 			irq = -1;
 	}
 
-	spin_unlock(&sni_rm200_i8259A_lock);
+	raw_spin_unlock(&sni_rm200_i8259A_lock);
 
 	return likely(irq >= 0) ? irq + RM200_I8259A_IRQ_BASE : irq;
 }
@@ -334,7 +334,7 @@ void sni_rm200_init_8259A(void)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
+	raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
 
 	writeb(0xff, rm200_pic_master + PIC_IMR);
 	writeb(0xff, rm200_pic_slave + PIC_IMR);
@@ -352,7 +352,7 @@ void sni_rm200_init_8259A(void)
 	writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
 	writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
 
-	spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
 }
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/txx9/generic/7segled.c linux-libre-2.6.34-gnu1/arch/mips/txx9/generic/7segled.c
--- linux-libre-2.6.33-gnu1/arch/mips/txx9/generic/7segled.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/txx9/generic/7segled.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,13 +58,16 @@ static ssize_t raw_store(struct sys_devi
 static SYSDEV_ATTR(ascii, 0200, NULL, ascii_store);
 static SYSDEV_ATTR(raw, 0200, NULL, raw_store);
 
-static ssize_t map_seg7_show(struct sysdev_class *class, char *buf)
+static ssize_t map_seg7_show(struct sysdev_class *class,
+			     struct sysdev_class_attribute *attr,
+			     char *buf)
 {
 	memcpy(buf, &txx9_seg7map, sizeof(txx9_seg7map));
 	return sizeof(txx9_seg7map);
 }
 
 static ssize_t map_seg7_store(struct sysdev_class *class,
+			      struct sysdev_class_attribute *attr,
 			      const char *buf, size_t size)
 {
 	if (size != sizeof(txx9_seg7map))
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/txx9/generic/pci.c linux-libre-2.6.34-gnu1/arch/mips/txx9/generic/pci.c
--- linux-libre-2.6.33-gnu1/arch/mips/txx9/generic/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/txx9/generic/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <asm/txx9/pci.h>
 #ifdef CONFIG_TOSHIBA_FPCIB0
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/i8259.h>
 #include <asm/txx9/smsc_fdc37m81x.h>
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/txx9/generic/setup.c linux-libre-2.6.34-gnu1/arch/mips/txx9/generic/setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/txx9/generic/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/txx9/generic/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/mtd/physmap.h>
 #include <linux/leds.h>
 #include <linux/sysdev.h>
+#include <linux/slab.h>
 #include <asm/bootinfo.h>
 #include <asm/time.h>
 #include <asm/reboot.h>
@@ -399,11 +400,6 @@ const char *get_system_type(void)
 	return txx9_system_type;
 }
 
-char * __init prom_getcmdline(void)
-{
-	return &(arcs_cmdline[0]);
-}
-
 const char *__init prom_getenv(const char *name)
 {
 	const s32 *str;
@@ -961,6 +957,7 @@ void __init txx9_sramc_init(struct resou
 	if (!dev->base)
 		goto exit;
 	dev->dev.cls = &txx9_sramc_sysdev_class;
+	sysfs_bin_attr_init(&dev->bindata_attr);
 	dev->bindata_attr.attr.name = "bindata";
 	dev->bindata_attr.attr.mode = S_IRUSR | S_IWUSR;
 	dev->bindata_attr.read = txx9_sram_read;
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/txx9/generic/spi_eeprom.c linux-libre-2.6.34-gnu1/arch/mips/txx9/generic/spi_eeprom.c
--- linux-libre-2.6.33-gnu1/arch/mips/txx9/generic/spi_eeprom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/txx9/generic/spi_eeprom.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
  */
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/eeprom.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/txx9/jmr3927/setup.c linux-libre-2.6.34-gnu1/arch/mips/txx9/jmr3927/setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/txx9/jmr3927/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/txx9/jmr3927/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -67,8 +67,6 @@ static void jmr3927_board_init(void);
 
 static void __init jmr3927_mem_setup(void)
 {
-	char *argptr;
-
 	set_io_port_base(JMR3927_PORT_BASE + JMR3927_PCIIO);
 
 	_machine_restart = jmr3927_machine_restart;
@@ -97,11 +95,6 @@ static void __init jmr3927_mem_setup(voi
 	jmr3927_board_init();
 
 	tx3927_sio_init(0, 1 << 1); /* ch1: noCTS */
-#ifdef CONFIG_SERIAL_TXX9_CONSOLE
-	argptr = prom_getcmdline();
-	if (!strstr(argptr, "console="))
-		strcat(argptr, " console=ttyS1,115200");
-#endif
 }
 
 static void __init jmr3927_pci_setup(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/txx9/rbtx4927/setup.c linux-libre-2.6.34-gnu1/arch/mips/txx9/rbtx4927/setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/txx9/rbtx4927/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/txx9/rbtx4927/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -187,8 +187,6 @@ static void __init rbtx4937_clock_init(v
 
 static void __init rbtx4927_mem_setup(void)
 {
-	char *argptr;
-
 	if (TX4927_REV_PCODE() == 0x4927) {
 		rbtx4927_clock_init();
 		tx4927_setup();
@@ -213,11 +211,6 @@ static void __init rbtx4927_mem_setup(vo
 	gpio_direction_output(15, 1);
 
 	tx4927_sio_init(0, 0);
-#ifdef CONFIG_SERIAL_TXX9_CONSOLE
-	argptr = prom_getcmdline();
-	if (!strstr(argptr, "console="))
-		strcat(argptr, " console=ttyS0,38400");
-#endif
 }
 
 static void __init rbtx4927_clock_init(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/txx9/rbtx4938/setup.c linux-libre-2.6.34-gnu1/arch/mips/txx9/rbtx4938/setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/txx9/rbtx4938/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/txx9/rbtx4938/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -153,7 +153,6 @@ static void __init rbtx4938_time_init(vo
 static void __init rbtx4938_mem_setup(void)
 {
 	unsigned long long pcfg;
-	char *argptr;
 
 	if (txx9_master_clock == 0)
 		txx9_master_clock = 25000000; /* 25MHz */
@@ -168,11 +167,6 @@ static void __init rbtx4938_mem_setup(vo
 #endif
 
 	tx4938_sio_init(7372800, 0);
-#ifdef CONFIG_SERIAL_TXX9_CONSOLE
-	argptr = prom_getcmdline();
-	if (!strstr(argptr, "console="))
-		strcat(argptr, " console=ttyS0,38400");
-#endif
 
 #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61
 	pr_info("PIOSEL: disabling both ATA and NAND selection\n");
diff -druNp linux-libre-2.6.33-gnu1/arch/mips/txx9/rbtx4939/setup.c linux-libre-2.6.34-gnu1/arch/mips/txx9/rbtx4939/setup.c
--- linux-libre-2.6.33-gnu1/arch/mips/txx9/rbtx4939/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mips/txx9/rbtx4939/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/leds.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/dma-mapping.h linux-libre-2.6.34-gnu1/arch/mn10300/include/asm/dma-mapping.h
--- linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mn10300/include/asm/dma-mapping.h	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,11 @@
 #include <asm/cache.h>
 #include <asm/io.h>
 
+/*
+ * See Documentation/DMA-API.txt for the description of how the
+ * following DMA API should work.
+ */
+
 extern void *dma_alloc_coherent(struct device *dev, size_t size,
 				dma_addr_t *dma_handle, int flag);
 
@@ -26,13 +31,6 @@ extern void dma_free_coherent(struct dev
 #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)
@@ -42,14 +40,6 @@ dma_addr_t dma_map_single(struct device
 	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)
@@ -57,20 +47,6 @@ void dma_unmap_single(struct device *dev
 	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)
@@ -91,11 +67,6 @@ int dma_map_sg(struct device *dev, struc
 	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)
@@ -103,10 +74,6 @@ void dma_unmap_sg(struct device *dev, st
 	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,
@@ -123,15 +90,6 @@ void dma_unmap_page(struct device *dev,
 	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)
@@ -161,13 +119,6 @@ dma_sync_single_range_for_device(struct
 }
 
 
-/*
- * 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)
@@ -187,12 +138,6 @@ int dma_mapping_error(struct device *dev
 	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)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/pgtable.h linux-libre-2.6.34-gnu1/arch/mn10300/include/asm/pgtable.h
--- linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mn10300/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -466,7 +466,7 @@ static inline int set_kernel_exec(unsign
  * 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);
+			     unsigned long address, pte_t *ptep);
 
 #endif /* !__ASSEMBLY__ */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/mn10300/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mn10300/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -99,8 +99,6 @@ struct task_struct;
 extern void show_regs(struct pt_regs *);
 
 #define arch_has_single_step()	(1)
-extern void user_enable_single_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
 
 #endif  /*  !__ASSEMBLY  */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/unistd.h linux-libre-2.6.34-gnu1/arch/mn10300/include/asm/unistd.h
--- linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mn10300/include/asm/unistd.h	2010-05-16 17:17:36.000000000 -0400
@@ -363,6 +363,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
@@ -375,6 +376,7 @@
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_SELECT
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff -druNp linux-libre-2.6.33-gnu1/arch/mn10300/kernel/entry.S linux-libre-2.6.34-gnu1/arch/mn10300/kernel/entry.S
--- linux-libre-2.6.33-gnu1/arch/mn10300/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mn10300/kernel/entry.S	2010-05-16 17:17:36.000000000 -0400
@@ -468,7 +468,7 @@ ENTRY(sys_call_table)
 	.long sys_settimeofday
 	.long sys_getgroups16	/* 80 */
 	.long sys_setgroups16
-	.long old_select
+	.long sys_old_select
 	.long sys_symlink
 	.long sys_lstat
 	.long sys_readlink	/* 85 */
diff -druNp linux-libre-2.6.33-gnu1/arch/mn10300/kernel/process.c linux-libre-2.6.34-gnu1/arch/mn10300/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/mn10300/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mn10300/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
@@ -26,6 +25,7 @@
 #include <linux/percpu.h>
 #include <linux/err.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mn10300/kernel/setup.c linux-libre-2.6.34-gnu1/arch/mn10300/kernel/setup.c
--- linux-libre-2.6.33-gnu1/arch/mn10300/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mn10300/kernel/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/tty.h>
 #include <linux/ioport.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mn10300/kernel/sys_mn10300.c linux-libre-2.6.34-gnu1/arch/mn10300/kernel/sys_mn10300.c
--- linux-libre-2.6.33-gnu1/arch/mn10300/kernel/sys_mn10300.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mn10300/kernel/sys_mn10300.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,109 +31,3 @@ asmlinkage long old_mmap(unsigned long a
 		return -EINVAL;
 	return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
 }
-
-struct sel_arg_struct {
-	unsigned long n;
-	fd_set *inp;
-	fd_set *outp;
-	fd_set *exp;
-	struct timeval *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct __user *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	/* sys_select() does the appropriate kernel locking */
-	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage long sys_ipc(uint call, int first, int second,
-			int third, void __user *ptr, long fifth)
-{
-	int version, ret;
-
-	version = call >> 16; /* hack for backward compatibility */
-	call &= 0xffff;
-
-	switch (call) {
-	case SEMOP:
-		return sys_semtimedop(first, (struct sembuf __user *)ptr,
-				      second, NULL);
-	case SEMTIMEDOP:
-		return sys_semtimedop(first, (struct sembuf __user *)ptr,
-				      second,
-				      (const struct timespec __user *)fifth);
-	case SEMGET:
-		return sys_semget(first, second, third);
-	case SEMCTL: {
-		union semun fourth;
-		if (!ptr)
-			return -EINVAL;
-		if (get_user(fourth.__pad, (void __user * __user *) ptr))
-			return -EFAULT;
-		return sys_semctl(first, second, third, fourth);
-	}
-
-	case MSGSND:
-		return sys_msgsnd(first, (struct msgbuf __user *) ptr,
-				  second, third);
-	case MSGRCV:
-		switch (version) {
-		case 0: {
-			struct ipc_kludge tmp;
-			if (!ptr)
-				return -EINVAL;
-
-			if (copy_from_user(&tmp,
-					   (struct ipc_kludge __user *) ptr,
-					   sizeof(tmp)))
-				return -EFAULT;
-			return sys_msgrcv(first, tmp.msgp, second,
-					  tmp.msgtyp, third);
-		}
-		default:
-			return sys_msgrcv(first,
-					  (struct msgbuf __user *) ptr,
-					   second, fifth, third);
-		}
-	case MSGGET:
-		return sys_msgget((key_t) first, second);
-	case MSGCTL:
-		return sys_msgctl(first, second,
-				   (struct msqid_ds __user *) ptr);
-
-	case SHMAT:
-		switch (version) {
-		default: {
-			ulong raddr;
-			ret = do_shmat(first, (char __user *) ptr, second,
-				       &raddr);
-			if (ret)
-				return ret;
-			return put_user(raddr, (ulong *) third);
-		}
-		case 1:	/* iBCS2 emulator entry point */
-			if (!segment_eq(get_fs(), get_ds()))
-				return -EINVAL;
-			return do_shmat(first, (char __user *) ptr, second,
-					(ulong *) third);
-		}
-	case SHMDT:
-		return sys_shmdt((char __user *)ptr);
-	case SHMGET:
-		return sys_shmget(first, second, third);
-	case SHMCTL:
-		return sys_shmctl(first, second,
-				  (struct shmid_ds __user *) ptr);
-	default:
-		return -EINVAL;
-	}
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/mn10300/mm/dma-alloc.c linux-libre-2.6.34-gnu1/arch/mn10300/mm/dma-alloc.c
--- linux-libre-2.6.33-gnu1/arch/mn10300/mm/dma-alloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mn10300/mm/dma-alloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 
 static unsigned long pci_sram_allocated = 0xbc000000;
diff -druNp linux-libre-2.6.33-gnu1/arch/mn10300/mm/init.c linux-libre-2.6.34-gnu1/arch/mn10300/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/mn10300/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mn10300/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/types.h>
 #include <linux/ptrace.h>
 #include <linux/mman.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
@@ -27,6 +26,7 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 
 #include <asm/processor.h>
 #include <asm/system.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mn10300/mm/mmu-context.c linux-libre-2.6.34-gnu1/arch/mn10300/mm/mmu-context.c
--- linux-libre-2.6.33-gnu1/arch/mn10300/mm/mmu-context.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mn10300/mm/mmu-context.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,9 +51,10 @@ void flush_tlb_page(struct vm_area_struc
 /*
  * preemptively set a TLB entry
  */
-void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
 {
 	unsigned long pteu, ptel, cnx, flags;
+	pte_t pte = *ptep;
 
 	addr &= PAGE_MASK;
 	ptel = pte_val(pte) & ~(xPTEL_UNUSED1 | xPTEL_UNUSED2);
diff -druNp linux-libre-2.6.33-gnu1/arch/mn10300/mm/pgtable.c linux-libre-2.6.34-gnu1/arch/mn10300/mm/pgtable.c
--- linux-libre-2.6.33-gnu1/arch/mn10300/mm/pgtable.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mn10300/mm/pgtable.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,11 +12,11 @@
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/smp.h>
 #include <linux/highmem.h>
-#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/spinlock.h>
 #include <linux/quicklist.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/pci-asb2305.c linux-libre-2.6.34-gnu1/arch/mn10300/unit-asb2305/pci-asb2305.c
--- linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/pci-asb2305.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mn10300/unit-asb2305/pci-asb2305.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,9 +31,11 @@
  * but we want to try to avoid allocating at 0x2900-0x2bff
  * which might have be mirrored at 0x0100-0x03ff..
  */
-void pcibios_align_resource(void *data, struct resource *res,
-			    resource_size_t size, resource_size_t align)
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+				resource_size_t size, resource_size_t align)
 {
+	resource_size_t start = res->start;
+
 #if 0
 	struct pci_dev *dev = data;
 
@@ -47,14 +49,10 @@ void pcibios_align_resource(void *data,
 	       );
 #endif
 
-	if (res->flags & IORESOURCE_IO) {
-		unsigned long start = res->start;
+	if ((res->flags & IORESOURCE_IO) && (start & 0x300))
+		start = (start + 0x3ff) & ~0x3ff;
 
-		if (start & 0x300) {
-			start = (start + 0x3ff) & ~0x3ff;
-			res->start = start;
-		}
-	}
+	return start;
 }
 
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/pci.c linux-libre-2.6.34-gnu1/arch/mn10300/unit-asb2305/pci.c
--- linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mn10300/unit-asb2305/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -331,12 +331,10 @@ static int __init pci_check_direct(void)
 static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
 {
 	unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
-	struct resource *devr = &dev->resource[idx];
+	struct resource *devr = &dev->resource[idx], *busr;
 
 	if (dev->bus) {
-		for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
-			struct resource *busr = dev->bus->resource[i];
-
+		pci_bus_for_each_resource(dev->bus, busr, i) {
 			if (!busr || (busr->flags ^ devr->flags) & type_mask)
 				continue;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/pci-irq.c linux-libre-2.6.34-gnu1/arch/mn10300/unit-asb2305/pci-irq.c
--- linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/pci-irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/mn10300/unit-asb2305/pci-irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/hpux/fs.c linux-libre-2.6.34-gnu1/arch/parisc/hpux/fs.c
--- linux-libre-2.6.33-gnu1/arch/parisc/hpux/fs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/hpux/fs.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,8 +26,8 @@
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/file.h>
-#include <linux/slab.h>
 #include <linux/ptrace.h>
+#include <linux/slab.h>
 #include <asm/errno.h>
 #include <asm/uaccess.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/include/asm/cacheflush.h linux-libre-2.6.34-gnu1/arch/parisc/include/asm/cacheflush.h
--- linux-libre-2.6.33-gnu1/arch/parisc/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/include/asm/cacheflush.h	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,18 @@ void flush_cache_mm(struct mm_struct *mm
 
 #define flush_kernel_dcache_range(start,size) \
 	flush_kernel_dcache_range_asm((start), (start)+(size));
+/* vmap range flushes and invalidates.  Architecturally, we don't need
+ * the invalidate, because the CPU should refuse to speculate once an
+ * area has been flushed, so invalidate is left empty */
+static inline void flush_kernel_vmap_range(void *vaddr, int size)
+{
+	unsigned long start = (unsigned long)vaddr;
+
+	flush_kernel_dcache_range_asm(start, start + size);
+}
+static inline void invalidate_kernel_vmap_range(void *vaddr, int size)
+{
+}
 
 #define flush_cache_vmap(start, end)		flush_cache_all()
 #define flush_cache_vunmap(start, end)		flush_cache_all()
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/include/asm/compat.h linux-libre-2.6.34-gnu1/arch/parisc/include/asm/compat.h
--- linux-libre-2.6.33-gnu1/arch/parisc/include/asm/compat.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/include/asm/compat.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,8 @@
 #include <linux/sched.h>
 #include <linux/thread_info.h>
 
-#define COMPAT_USER_HZ 100
+#define COMPAT_USER_HZ 		100
+#define COMPAT_UTS_MACHINE	"parisc\0\0"
 
 typedef u32	compat_size_t;
 typedef s32	compat_ssize_t;
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/include/asm/param.h linux-libre-2.6.34-gnu1/arch/parisc/include/asm/param.h
--- linux-libre-2.6.33-gnu1/arch/parisc/include/asm/param.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/include/asm/param.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,22 +1 @@
-#ifndef _ASMPARISC_PARAM_H
-#define _ASMPARISC_PARAM_H
-
-#ifdef __KERNEL__
-#define HZ		CONFIG_HZ
-#define USER_HZ		100		/* some user API use "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
+#include <asm-generic/param.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/include/asm/pci.h linux-libre-2.6.34-gnu1/arch/parisc/include/asm/pci.h
--- linux-libre-2.6.33-gnu1/arch/parisc/include/asm/pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/include/asm/pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -183,20 +183,6 @@ struct pci_bios_ops {
 	void (*fixup_bus)(struct pci_bus *bus);
 };
 
-/* pci_unmap_{single,page} is not a nop, thus... */
-#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))
-
 /*
 ** Stuff declared in arch/parisc/kernel/pci.c
 */
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/include/asm/pgtable.h linux-libre-2.6.34-gnu1/arch/parisc/include/asm/pgtable.h
--- linux-libre-2.6.33-gnu1/arch/parisc/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -410,7 +410,7 @@ extern void paging_init (void);
 
 #define PG_dcache_dirty         PG_arch_1
 
-extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
+extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
 
 /* Encode and de-code a swap entry */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/parisc/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/parisc/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -47,13 +47,8 @@ struct pt_regs {
 
 #define task_regs(task) ((struct pt_regs *) ((char *)(task) + TASK_REGS))
 
-struct task_struct;
 #define arch_has_single_step()	1
-void user_disable_single_step(struct task_struct *task);
-void user_enable_single_step(struct task_struct *task);
-
 #define arch_has_block_step()	1
-void user_enable_block_step(struct task_struct *task);
 
 /* XXX should we use iaoq[1] or iaoq[0] ? */
 #define user_mode(regs)			(((regs)->iaoq[0] & 3) ? 1 : 0)
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/include/asm/system.h linux-libre-2.6.34-gnu1/arch/parisc/include/asm/system.h
--- linux-libre-2.6.33-gnu1/arch/parisc/include/asm/system.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/include/asm/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -160,7 +160,7 @@ static inline void set_eiem(unsigned lon
    ldcd). */
 
 #define __PA_LDCW_ALIGNMENT	4
-#define __ldcw_align(a) ((volatile unsigned int *)a)
+#define __ldcw_align(a) (&(a)->slock)
 #define __LDCW	"ldcw,co"
 
 #endif /*!CONFIG_PA20*/
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/include/asm/uaccess.h linux-libre-2.6.34-gnu1/arch/parisc/include/asm/uaccess.h
--- linux-libre-2.6.33-gnu1/arch/parisc/include/asm/uaccess.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/include/asm/uaccess.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
 #include <asm/page.h>
 #include <asm/system.h>
 #include <asm/cache.h>
+#include <asm/errno.h>
 #include <asm-generic/uaccess-unaligned.h>
 
 #define VERIFY_READ 0
@@ -234,13 +235,35 @@ extern long lstrnlen_user(const char __u
 
 unsigned long copy_to_user(void __user *dst, const void *src, unsigned long len);
 #define __copy_to_user copy_to_user
-unsigned long copy_from_user(void *dst, const void __user *src, unsigned long len);
-#define __copy_from_user copy_from_user
+unsigned long __copy_from_user(void *dst, const void __user *src, unsigned long len);
 unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned long len);
 #define __copy_in_user copy_in_user
 #define __copy_to_user_inatomic __copy_to_user
 #define __copy_from_user_inatomic __copy_from_user
 
+extern void copy_from_user_overflow(void)
+#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
+        __compiletime_error("copy_from_user() buffer size is not provably correct")
+#else
+        __compiletime_warning("copy_from_user() buffer size is not provably correct")
+#endif
+;
+
+static inline unsigned long __must_check copy_from_user(void *to,
+                                          const void __user *from,
+                                          unsigned long n)
+{
+        int sz = __compiletime_object_size(to);
+        int ret = -EFAULT;
+
+        if (likely(sz == -1 || !__builtin_constant_p(n) || sz >= n))
+                ret = __copy_from_user(to, from, n);
+        else
+                copy_from_user_overflow();
+
+        return ret;
+}
+
 struct pt_regs;
 int fixup_exception(struct pt_regs *regs);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/include/asm/unistd.h linux-libre-2.6.34-gnu1/arch/parisc/include/asm/unistd.h
--- linux-libre-2.6.33-gnu1/arch/parisc/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/include/asm/unistd.h	2010-05-16 17:17:36.000000000 -0400
@@ -811,8 +811,10 @@
 #define __NR_pwritev		(__NR_Linux + 316)
 #define __NR_rt_tgsigqueueinfo	(__NR_Linux + 317)
 #define __NR_perf_event_open	(__NR_Linux + 318)
+#define __NR_recvmmsg		(__NR_Linux + 319)
+#define __NR_accept4		(__NR_Linux + 320)
 
-#define __NR_Linux_syscalls	(__NR_perf_event_open + 1)
+#define __NR_Linux_syscalls	(__NR_accept4 + 1)
 
 
 #define __IGNORE_select		/* newselect */
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/Kconfig linux-libre-2.6.34-gnu1/arch/parisc/Kconfig
--- linux-libre-2.6.33-gnu1/arch/parisc/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -95,6 +95,9 @@ config PM
 config STACKTRACE_SUPPORT
 	def_bool y
 
+config NEED_DMA_MAP_STATE
+	def_bool y
+
 config ISA_DMA_API
 	bool
 
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/Kconfig.debug linux-libre-2.6.34-gnu1/arch/parisc/Kconfig.debug
--- linux-libre-2.6.33-gnu1/arch/parisc/Kconfig.debug	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/Kconfig.debug	2010-05-16 17:17:36.000000000 -0400
@@ -12,4 +12,18 @@ config DEBUG_RODATA
          portion of the kernel code won't be covered by a TLB anymore.
          If in doubt, say "N".
 
+config DEBUG_STRICT_USER_COPY_CHECKS
+	bool "Strict copy size checks"
+	depends on DEBUG_KERNEL && !TRACE_BRANCH_PROFILING
+	---help---
+	  Enabling this option turns a certain set of sanity checks for user
+	  copy operations into compile time failures.
+
+	  The copy_from_user() etc checks are there to help test if there
+	  are sufficient security checks on the length argument of
+	  the copy operation, by having gcc prove that the argument is
+	  within bounds.
+
+	  If unsure, or if you run an older (pre 4.4) gcc, say N.
+
 endmenu
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/kernel/cache.c linux-libre-2.6.34-gnu1/arch/parisc/kernel/cache.c
--- linux-libre-2.6.33-gnu1/arch/parisc/kernel/cache.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/kernel/cache.c	2010-05-16 17:17:36.000000000 -0400
@@ -68,9 +68,9 @@ flush_cache_all_local(void)
 EXPORT_SYMBOL(flush_cache_all_local);
 
 void
-update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
-	struct page *page = pte_page(pte);
+	struct page *page = pte_page(*ptep);
 
 	if (pfn_valid(page_to_pfn(page)) && page_mapping(page) &&
 	    test_bit(PG_dcache_dirty, &page->flags)) {
@@ -171,14 +171,14 @@ parisc_cache_init(void)
 		cache_info.ic_conf.cc_cst,
 		cache_info.ic_conf.cc_hv);
 
-	printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n",
+	printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d\n",
 		cache_info.dt_conf.tc_sh,
 		cache_info.dt_conf.tc_page,
 		cache_info.dt_conf.tc_cst,
 		cache_info.dt_conf.tc_aid,
 		cache_info.dt_conf.tc_pad1);
 
-	printk("I-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n",
+	printk("I-TLB conf: sh %d page %d cst %d aid %d pad1 %d\n",
 		cache_info.it_conf.tc_sh,
 		cache_info.it_conf.tc_page,
 		cache_info.it_conf.tc_cst,
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/kernel/module.c linux-libre-2.6.34-gnu1/arch/parisc/kernel/module.c
--- linux-libre-2.6.33-gnu1/arch/parisc/kernel/module.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/kernel/module.c	2010-05-16 17:17:36.000000000 -0400
@@ -61,6 +61,7 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/bug.h>
+#include <linux/slab.h>
 
 #include <asm/unwind.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/kernel/pci.c linux-libre-2.6.34-gnu1/arch/parisc/kernel/pci.c
--- linux-libre-2.6.33-gnu1/arch/parisc/kernel/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/kernel/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/types.h>
 
 #include <asm/io.h>
@@ -257,10 +256,10 @@ EXPORT_SYMBOL(pcibios_bus_to_resource);
  * Since we are just checking candidates, don't use any fields other
  * than res->start.
  */
-void pcibios_align_resource(void *data, struct resource *res,
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 				resource_size_t size, resource_size_t alignment)
 {
-	resource_size_t mask, align;
+	resource_size_t mask, align, start = res->start;
 
 	DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx, 0x%lx)\n",
 		pci_name(((struct pci_dev *) data)),
@@ -272,10 +271,10 @@ void pcibios_align_resource(void *data,
 
 	/* Align to largest of MIN or input size */
 	mask = max(alignment, align) - 1;
-	res->start += mask;
-	res->start &= ~mask;
+	start += mask;
+	start &= ~mask;
 
-	/* The caller updates the end field, we don't.  */
+	return start;
 }
 
 
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/kernel/pci-dma.c linux-libre-2.6.34-gnu1/arch/parisc/kernel/pci-dma.c
--- linux-libre-2.6.33-gnu1/arch/parisc/kernel/pci-dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/kernel/pci-dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,11 +18,11 @@
 */
 
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/scatterlist.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/kernel/process.c linux-libre-2.6.34-gnu1/arch/parisc/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/parisc/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,7 @@
 #include <linux/personality.h>
 #include <linux/ptrace.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/kallsyms.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/kernel/signal32.c linux-libre-2.6.34-gnu1/arch/parisc/kernel/signal32.c
--- linux-libre-2.6.33-gnu1/arch/parisc/kernel/signal32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/kernel/signal32.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
  */
 
 #include <linux/compat.h>
-#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/unistd.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/kernel/smp.c linux-libre-2.6.34-gnu1/arch/parisc/kernel/smp.c
--- linux-libre-2.6.33-gnu1/arch/parisc/kernel/smp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/kernel/smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@
 */
 #include <linux/types.h>
 #include <linux/spinlock.h>
-#include <linux/slab.h>
 
 #include <linux/kernel.h>
 #include <linux/module.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/kernel/syscall_table.S linux-libre-2.6.34-gnu1/arch/parisc/kernel/syscall_table.S
--- linux-libre-2.6.33-gnu1/arch/parisc/kernel/syscall_table.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/kernel/syscall_table.S	2010-05-16 17:17:36.000000000 -0400
@@ -127,7 +127,7 @@
 	ENTRY_SAME(socketpair)
 	ENTRY_SAME(setpgid)
 	ENTRY_SAME(send)
-	ENTRY_OURS(newuname)
+	ENTRY_SAME(newuname)
 	ENTRY_SAME(umask)		/* 60 */
 	ENTRY_SAME(chroot)
 	ENTRY_COMP(ustat)
@@ -417,6 +417,8 @@
 	ENTRY_COMP(pwritev)
 	ENTRY_COMP(rt_tgsigqueueinfo)
 	ENTRY_SAME(perf_event_open)
+	ENTRY_COMP(recvmmsg)
+	ENTRY_SAME(accept4)		/* 320 */
 
 	/* Nothing yet */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/kernel/sys_parisc.c linux-libre-2.6.34-gnu1/arch/parisc/kernel/sys_parisc.c
--- linux-libre-2.6.33-gnu1/arch/parisc/kernel/sys_parisc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/kernel/sys_parisc.c	2010-05-16 17:17:36.000000000 -0400
@@ -234,18 +234,3 @@ long parisc_personality(unsigned long pe
 
 	return err;
 }
-
-long parisc_newuname(struct new_utsname __user *name)
-{
-	int err = sys_newuname(name);
-
-#ifdef CONFIG_COMPAT
-	if (!err && personality(current->personality) == PER_LINUX32) {
-		if (__put_user(0, name->machine + 6) ||
-		    __put_user(0, name->machine + 7))
-			err = -EFAULT;
-	}
-#endif
-
-	return err;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/kernel/time.c linux-libre-2.6.34-gnu1/arch/parisc/kernel/time.c
--- linux-libre-2.6.33-gnu1/arch/parisc/kernel/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/kernel/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -250,9 +250,21 @@ static int __init rtc_init(void)
 }
 module_init(rtc_init);
 
-void __init time_init(void)
+void read_persistent_clock(struct timespec *ts)
 {
 	static struct pdc_tod tod_data;
+	if (pdc_tod_read(&tod_data) == 0) {
+		ts->tv_sec = tod_data.tod_sec;
+		ts->tv_nsec = tod_data.tod_usec * 1000;
+	} else {
+		printk(KERN_ERR "Error reading tod clock\n");
+	        ts->tv_sec = 0;
+		ts->tv_nsec = 0;
+	}
+}
+
+void __init time_init(void)
+{
 	unsigned long current_cr16_khz;
 
 	clocktick = (100 * PAGE0->mem_10msec) / HZ;
@@ -264,19 +276,4 @@ void __init time_init(void)
 	clocksource_cr16.mult = clocksource_khz2mult(current_cr16_khz,
 						clocksource_cr16.shift);
 	clocksource_register(&clocksource_cr16);
-
-	if (pdc_tod_read(&tod_data) == 0) {
-		unsigned long flags;
-
-		write_seqlock_irqsave(&xtime_lock, flags);
-		xtime.tv_sec = tod_data.tod_sec;
-		xtime.tv_nsec = tod_data.tod_usec * 1000;
-		set_normalized_timespec(&wall_to_monotonic,
-		                        -xtime.tv_sec, -xtime.tv_nsec);
-		write_sequnlock_irqrestore(&xtime_lock, flags);
-	} else {
-		printk(KERN_ERR "Error reading tod clock\n");
-	        xtime.tv_sec = 0;
-		xtime.tv_nsec = 0;
-	}
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/kernel/unaligned.c linux-libre-2.6.34-gnu1/arch/parisc/kernel/unaligned.c
--- linux-libre-2.6.33-gnu1/arch/parisc/kernel/unaligned.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/kernel/unaligned.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
+#include <linux/ratelimit.h>
 #include <asm/uaccess.h>
 
 /* #define DEBUG_UNALIGNED 1 */
@@ -446,8 +447,7 @@ static int emulate_std(struct pt_regs *r
 
 void handle_unaligned(struct pt_regs *regs)
 {
-	static unsigned long unaligned_count = 0;
-	static unsigned long last_time = 0;
+	static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5);
 	unsigned long newbase = R1(regs->iir)?regs->gr[R1(regs->iir)]:0;
 	int modify = 0;
 	int ret = ERR_NOTHANDLED;
@@ -460,14 +460,8 @@ void handle_unaligned(struct pt_regs *re
 			goto force_sigbus;
 		}
 
-		if (unaligned_count > 5 &&
-				time_after(jiffies, last_time + 5 * HZ)) {
-			unaligned_count = 0;
-			last_time = jiffies;
-		}
-
-		if (!(current->thread.flags & PARISC_UAC_NOPRINT) 
-		    && ++unaligned_count < 5) {
+		if (!(current->thread.flags & PARISC_UAC_NOPRINT) &&
+			__ratelimit(&ratelimit)) {
 			char buf[256];
 			sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n",
 				current->comm, task_pid_nr(current), regs->ior, regs->iaoq[0]);
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/lib/fixup.S linux-libre-2.6.34-gnu1/arch/parisc/lib/fixup.S
--- linux-libre-2.6.33-gnu1/arch/parisc/lib/fixup.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/lib/fixup.S	2010-05-16 17:17:36.000000000 -0400
@@ -36,8 +36,8 @@
 #endif
 	/* t2 = &__per_cpu_offset[smp_processor_id()]; */
 	LDREGX \t2(\t1),\t2 
-	addil LT%per_cpu__exception_data,%r27
-	LDREG RT%per_cpu__exception_data(%r1),\t1
+	addil LT%exception_data,%r27
+	LDREG RT%exception_data(%r1),\t1
 	/* t1 = &__get_cpu_var(exception_data) */
 	add,l \t1,\t2,\t1
 	/* t1 = t1->fault_ip */
@@ -46,8 +46,8 @@
 #else
 	.macro  get_fault_ip t1 t2
 	/* t1 = &__get_cpu_var(exception_data) */
-	addil LT%per_cpu__exception_data,%r27
-	LDREG RT%per_cpu__exception_data(%r1),\t2
+	addil LT%exception_data,%r27
+	LDREG RT%exception_data(%r1),\t2
 	/* t1 = t2->fault_ip */
 	LDREG EXCDATA_IP(\t2), \t1
 	.endm
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/lib/memcpy.c linux-libre-2.6.34-gnu1/arch/parisc/lib/memcpy.c
--- linux-libre-2.6.33-gnu1/arch/parisc/lib/memcpy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/lib/memcpy.c	2010-05-16 17:17:36.000000000 -0400
@@ -475,7 +475,8 @@ unsigned long copy_to_user(void __user *
 	return pa_memcpy((void __force *)dst, src, len);
 }
 
-unsigned long copy_from_user(void *dst, const void __user *src, unsigned long len)
+EXPORT_SYMBOL(__copy_from_user);
+unsigned long __copy_from_user(void *dst, const void __user *src, unsigned long len)
 {
 	mtsp(get_user_space(), 1);
 	mtsp(get_kernel_space(), 2);
diff -druNp linux-libre-2.6.33-gnu1/arch/parisc/mm/init.c linux-libre-2.6.34-gnu1/arch/parisc/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/parisc/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/parisc/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/pci.h>		/* for hppa_dma_ops and pcxl_dma_ops */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/arches.dts linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/arches.dts
--- linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/arches.dts	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/arches.dts	2010-05-16 17:17:36.000000000 -0400
@@ -60,6 +60,7 @@
 			d-cache-size = <32768>;
 			dcr-controller;
 			dcr-access-method = "native";
+			next-level-cache = <&L2C0>;
 		};
 	};
 
@@ -146,6 +147,13 @@
 			dcr-reg = <0x010 0x002>;
 		};
 
+		CRYPTO: crypto@180000 {
+			compatible = "amcc,ppc460gt-crypto", "amcc,ppc4xx-crypto";
+			reg = <4 0x00180000 0x80400>;
+			interrupt-parent = <&UIC0>;
+			interrupts = <0x1d 0x4>;
+		};
+
 		MAL0: mcmal {
 			compatible = "ibm,mcmal-460gt", "ibm,mcmal2";
 			dcr-reg = <0x180 0x062>;
@@ -274,6 +282,7 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
 				phy-mode = "sgmii";
 				phy-map = <0xffffffff>;
 				gpcs-address = <0x0000000a>;
@@ -302,6 +311,7 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
 				phy-mode = "sgmii";
 				phy-map = <0x00000000>;
 				gpcs-address = <0x0000000b>;
@@ -331,6 +341,8 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
+				tx-fifo-size-gige = <16384>; /* emac2&3 only */
 				phy-mode = "sgmii";
 				phy-map = <0x00000001>;
 				gpcs-address = <0x0000000C>;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/gef_ppc9a.dts linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/gef_ppc9a.dts
--- linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/gef_ppc9a.dts	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/gef_ppc9a.dts	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
- * GE Fanuc PPC9A Device Tree Source
+ * GE PPC9A Device Tree Source
  *
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -341,6 +341,22 @@
 			device_type = "open-pic";
 		};
 
+		msi@41600 {
+			compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
+			reg = <0x41600 0x80>;
+			msi-available-ranges = <0 0x100>;
+			interrupts = <
+				0xe0 0
+				0xe1 0
+				0xe2 0
+				0xe3 0
+				0xe4 0
+				0xe5 0
+				0xe6 0
+				0xe7 0>;
+			interrupt-parent = <&mpic>;
+		};
+
 		global-utilities@e0000 {
 			compatible = "fsl,mpc8641-guts";
 			reg = <0xe0000 0x1000>;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/gef_sbc310.dts linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/gef_sbc310.dts
--- linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/gef_sbc310.dts	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/gef_sbc310.dts	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
- * GE Fanuc SBC310 Device Tree Source
+ * GE SBC310 Device Tree Source
  *
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -32,6 +32,7 @@
 		serial0 = &serial0;
 		serial1 = &serial1;
 		pci0 = &pci0;
+		pci1 = &pci1;
 	};
 
 	cpus {
@@ -338,6 +339,22 @@
 			device_type = "open-pic";
 		};
 
+		msi@41600 {
+			compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
+			reg = <0x41600 0x80>;
+			msi-available-ranges = <0 0x100>;
+			interrupts = <
+				0xe0 0
+				0xe1 0
+				0xe2 0
+				0xe3 0
+				0xe4 0
+				0xe5 0
+				0xe6 0
+				0xe7 0>;
+			interrupt-parent = <&mpic>;
+		};
+
 		global-utilities@e0000 {
 			compatible = "fsl,mpc8641-guts";
 			reg = <0xe0000 0x1000>;
@@ -358,7 +375,7 @@
 		clock-frequency = <33333333>;
 		interrupt-parent = <&mpic>;
 		interrupts = <0x18 0x2>;
-		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
 		interrupt-map = <
 			0x0000 0x0 0x0 0x1 &mpic 0x0 0x2
 			0x0000 0x0 0x0 0x2 &mpic 0x1 0x2
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/gef_sbc610.dts linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/gef_sbc610.dts
--- linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/gef_sbc610.dts	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/gef_sbc610.dts	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
- * GE Fanuc SBC610 Device Tree Source
+ * GE SBC610 Device Tree Source
  *
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -75,14 +75,48 @@
 		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)
+		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,sbc610-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,sbc610-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;
+			};
+		};
 
 		nvram@3,0 {
 			device_type = "nvram";
@@ -305,6 +339,22 @@
 			device_type = "open-pic";
 		};
 
+		msi@41600 {
+			compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
+			reg = <0x41600 0x80>;
+			msi-available-ranges = <0 0x100>;
+			interrupts = <
+				0xe0 0
+				0xe1 0
+				0xe2 0
+				0xe3 0
+				0xe4 0
+				0xe5 0
+				0xe6 0
+				0xe7 0>;
+			interrupt-parent = <&mpic>;
+		};
+
 		global-utilities@e0000 {
 			compatible = "fsl,mpc8641-guts";
 			reg = <0xe0000 0x1000>;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/glacier.dts linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/glacier.dts
--- linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/glacier.dts	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/glacier.dts	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Device Tree Source for AMCC Glacier (460GT)
  *
- * Copyright 2008 DENX Software Engineering, Stefan Roese <sr@denx.de>
+ * Copyright 2008-2010 DENX Software Engineering, Stefan Roese <sr@denx.de>
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2.  This program is licensed "as is" without
@@ -42,6 +42,7 @@
 			d-cache-size = <32768>;
 			dcr-controller;
 			dcr-access-method = "native";
+			next-level-cache = <&L2C0>;
 		};
 	};
 
@@ -106,6 +107,16 @@
 		dcr-reg = <0x00c 0x002>;
 	};
 
+	L2C0: l2c {
+		compatible = "ibm,l2-cache-460gt", "ibm,l2-cache";
+		dcr-reg = <0x020 0x008		/* Internal SRAM DCR's */
+			   0x030 0x008>;	/* L2 cache DCR's */
+		cache-line-size = <32>;		/* 32 bytes */
+		cache-size = <262144>;		/* L2, 256K */
+		interrupt-parent = <&UIC1>;
+		interrupts = <11 1>;
+	};
+
 	plb {
 		compatible = "ibm,plb-460gt", "ibm,plb4";
 		#address-cells = <2>;
@@ -118,6 +129,13 @@
 			dcr-reg = <0x010 0x002>;
 		};
 
+		CRYPTO: crypto@180000 {
+			compatible = "amcc,ppc460gt-crypto", "amcc,ppc4xx-crypto";
+			reg = <4 0x00180000 0x80400>;
+			interrupt-parent = <&UIC0>;
+			interrupts = <0x1d 0x4>;
+		};
+
 		MAL0: mcmal {
 			compatible = "ibm,mcmal-460gt", "ibm,mcmal2";
 			dcr-reg = <0x180 0x062>;
@@ -186,6 +204,29 @@
 						reg = <0x03fa0000 0x00060000>;
 					};
 				};
+
+				ndfc@3,0 {
+					compatible = "ibm,ndfc";
+					reg = <0x00000003 0x00000000 0x00002000>;
+					ccr = <0x00001000>;
+					bank-settings = <0x80002222>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+
+					nand {
+						#address-cells = <1>;
+						#size-cells = <1>;
+
+						partition@0 {
+							label = "u-boot";
+							reg = <0x00000000 0x00100000>;
+						};
+						partition@100000 {
+							label = "user";
+							reg = <0x00000000 0x03f00000>;
+						};
+					};
+				};
 			};
 
 			UART0: serial@ef600300 {
@@ -237,6 +278,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 {
@@ -275,7 +330,7 @@
 
 			EMAC0: ethernet@ef600e00 {
 				device_type = "network";
-				compatible = "ibm,emac-460gt", "ibm,emac4";
+				compatible = "ibm,emac-460gt", "ibm,emac4sync";
 				interrupt-parent = <&EMAC0>;
 				interrupts = <0x0 0x1>;
 				#interrupt-cells = <1>;
@@ -283,7 +338,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0x0 &UIC2 0x10 0x4
 						 /*Wake*/   0x1 &UIC2 0x14 0x4>;
-				reg = <0xef600e00 0x00000074>;
+				reg = <0xef600e00 0x000000c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -305,7 +360,7 @@
 
 			EMAC1: ethernet@ef600f00 {
 				device_type = "network";
-				compatible = "ibm,emac-460gt", "ibm,emac4";
+				compatible = "ibm,emac-460gt", "ibm,emac4sync";
 				interrupt-parent = <&EMAC1>;
 				interrupts = <0x0 0x1>;
 				#interrupt-cells = <1>;
@@ -313,7 +368,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0x0 &UIC2 0x11 0x4
 						 /*Wake*/   0x1 &UIC2 0x15 0x4>;
-				reg = <0xef600f00 0x00000074>;
+				reg = <0xef600f00 0x000000c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
@@ -336,7 +391,7 @@
 
 			EMAC2: ethernet@ef601100 {
 				device_type = "network";
-				compatible = "ibm,emac-460gt", "ibm,emac4";
+				compatible = "ibm,emac-460gt", "ibm,emac4sync";
 				interrupt-parent = <&EMAC2>;
 				interrupts = <0x0 0x1>;
 				#interrupt-cells = <1>;
@@ -344,7 +399,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0x0 &UIC2 0x12 0x4
 						 /*Wake*/   0x1 &UIC2 0x16 0x4>;
-				reg = <0xef601100 0x00000074>;
+				reg = <0xef601100 0x000000c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <2>;
@@ -366,7 +421,7 @@
 
 			EMAC3: ethernet@ef601200 {
 				device_type = "network";
-				compatible = "ibm,emac-460gt", "ibm,emac4";
+				compatible = "ibm,emac-460gt", "ibm,emac4sync";
 				interrupt-parent = <&EMAC3>;
 				interrupts = <0x0 0x1>;
 				#interrupt-cells = <1>;
@@ -374,7 +429,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0x0 &UIC2 0x13 0x4
 						 /*Wake*/   0x1 &UIC2 0x17 0x4>;
-				reg = <0xef601200 0x00000074>;
+				reg = <0xef601200 0x000000c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <3>;
@@ -414,6 +469,7 @@
 			 * later cannot be changed
 			 */
 			ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000
+				  0x02000000 0x00000000 0x00000000 0x0000000c 0x0ee00000 0x00000000 0x00100000
 				  0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>;
 
 			/* Inbound 2GB range starting at 0 */
@@ -444,6 +500,7 @@
 			 * later cannot be changed
 			 */
 			ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000
+				  0x02000000 0x00000000 0x00000000 0x0000000f 0x00000000 0x00000000 0x00100000
 				  0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>;
 
 			/* Inbound 2GB range starting at 0 */
@@ -485,6 +542,7 @@
 			 * later cannot be changed
 			 */
 			ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000
+				  0x02000000 0x00000000 0x00000000 0x0000000f 0x00100000 0x00000000 0x00100000
 				  0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>;
 
 			/* Inbound 2GB range starting at 0 */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/katmai.dts linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/katmai.dts
--- linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/katmai.dts	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/katmai.dts	2010-05-16 17:17:36.000000000 -0400
@@ -156,7 +156,7 @@
 			compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb";
 			#address-cells = <1>;
 			#size-cells = <1>;
-			ranges = <0x00000000 0x00000004 0xe0000000 0x20000000>;
+			ranges = <0xe0000000 0x00000004 0xe0000000 0x20000000>;
 			clock-frequency = <0>; /* Filled in by zImage */
 
 			EBC0: ebc {
@@ -165,14 +165,47 @@
 				#address-cells = <2>;
 				#size-cells = <1>;
 				clock-frequency = <0>; /* Filled in by zImage */
+				/* ranges property is supplied by U-Boot */
 				interrupts = <0x5 0x1>;
 				interrupt-parent = <&UIC1>;
+
+				nor_flash@0,0 {
+					compatible = "cfi-flash";
+					bank-width = <2>;
+					reg = <0x00000000 0x00000000 0x01000000>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+					partition@0 {
+						label = "kernel";
+						reg = <0x00000000 0x001e0000>;
+					};
+					partition@1e0000 {
+						label = "dtb";
+						reg = <0x001e0000 0x00020000>;
+					};
+					partition@200000 {
+						label = "root";
+						reg = <0x00200000 0x00200000>;
+					};
+					partition@400000 {
+						label = "user";
+						reg = <0x00400000 0x00b60000>;
+					};
+					partition@f60000 {
+						label = "env";
+						reg = <0x00f60000 0x00040000>;
+					};
+					partition@fa0000 {
+						label = "u-boot";
+						reg = <0x00fa0000 0x00060000>;
+					};
+				};
 			};
 
-			UART0: serial@10000200 {
+			UART0: serial@f0000200 {
 				device_type = "serial";
 				compatible = "ns16550";
-				reg = <0x10000200 0x00000008>;
+				reg = <0xf0000200 0x00000008>;
 				virtual-reg = <0xa0000200>;
 				clock-frequency = <0>; /* Filled in by zImage */
 				current-speed = <115200>;
@@ -180,10 +213,10 @@
 				interrupts = <0x0 0x4>;
 			};
 
-			UART1: serial@10000300 {
+			UART1: serial@f0000300 {
 				device_type = "serial";
 				compatible = "ns16550";
-				reg = <0x10000300 0x00000008>;
+				reg = <0xf0000300 0x00000008>;
 				virtual-reg = <0xa0000300>;
 				clock-frequency = <0>;
 				current-speed = <0>;
@@ -192,10 +225,10 @@
 			};
 
 
-			UART2: serial@10000600 {
+			UART2: serial@f0000600 {
 				device_type = "serial";
 				compatible = "ns16550";
-				reg = <0x10000600 0x00000008>;
+				reg = <0xf0000600 0x00000008>;
 				virtual-reg = <0xa0000600>;
 				clock-frequency = <0>;
 				current-speed = <0>;
@@ -203,27 +236,27 @@
 				interrupts = <0x5 0x4>;
 			};
 
-			IIC0: i2c@10000400 {
+			IIC0: i2c@f0000400 {
 				compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
-				reg = <0x10000400 0x00000014>;
+				reg = <0xf0000400 0x00000014>;
 				interrupt-parent = <&UIC0>;
 				interrupts = <0x2 0x4>;
 			};
 
-			IIC1: i2c@10000500 {
+			IIC1: i2c@f0000500 {
 				compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
-				reg = <0x10000500 0x00000014>;
+				reg = <0xf0000500 0x00000014>;
 				interrupt-parent = <&UIC0>;
 				interrupts = <0x3 0x4>;
 			};
 
-			EMAC0: ethernet@10000800 {
+			EMAC0: ethernet@f0000800 {
 				linux,network-index = <0x0>;
 				device_type = "network";
 				compatible = "ibm,emac-440spe", "ibm,emac4";
 				interrupt-parent = <&UIC1>;
 				interrupts = <0x1c 0x4 0x1d 0x4>;
-				reg = <0x10000800 0x00000074>;
+				reg = <0xf0000800 0x00000074>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -248,11 +281,11 @@
 			primary;
 			large-inbound-windows;
 			enable-msi-hole;
-			reg = <0x0000000c 0x0ec00000   0x00000008	/* Config space access */
-			       0x00000000 0x00000000 0x00000000		/* no IACK cycles */
-			       0x0000000c 0x0ed00000   0x00000004   /* Special cycles */
-			       0x0000000c 0x0ec80000 0x00000100	/* Internal registers */
-			       0x0000000c 0x0ec80100  0x000000fc>;	/* Internal messaging registers */
+			reg = <0x0000000c 0x0ec00000 0x00000008   /* Config space access */
+			       0x00000000 0x00000000 0x00000000   /* no IACK cycles */
+			       0x0000000c 0x0ed00000 0x00000004   /* Special cycles */
+			       0x0000000c 0x0ec80000 0x00000100   /* Internal registers */
+			       0x0000000c 0x0ec80100 0x000000fc>; /* Internal messaging registers */
 
 			/* Outbound ranges, one memory and one IO,
 			 * later cannot be changed
@@ -453,6 +486,6 @@
 	};
 
 	chosen {
-		linux,stdout-path = "/plb/opb/serial@10000200";
+		linux,stdout-path = "/plb/opb/serial@f0000200";
 	};
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/kmeter1.dts linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/kmeter1.dts
--- linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/kmeter1.dts	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/kmeter1.dts	2010-05-16 17:17:36.000000000 -0400
@@ -490,7 +490,7 @@
 			compatible = "cfi-flash";
 			/*
 			 * The Intel P30 chip has 2 non-identical chips on
-			 * one die, so we need to define 2 seperate regions
+			 * one die, so we need to define 2 separate regions
 			 * that are scanned by physmap_of independantly.
 			 */
 			reg = <0 0x00000000 0x02000000
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc5121ads.dts linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/mpc5121ads.dts
--- linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc5121ads.dts	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/mpc5121ads.dts	2010-05-16 17:17:36.000000000 -0400
@@ -62,17 +62,12 @@
 		interrupt-parent = < &ipic >;
 		#address-cells = <1>;
 		#size-cells = <1>;
-		bank-width = <1>;
 		// ADS has two Hynix 512MB Nand flash chips in a single
-		// stacked package .
+		// stacked package.
 		chips = <2>;
-		nand0@0 {
-			label = "nand0";
-			reg = <0x00000000 0x02000000>; 	// first 32 MB of chip 0
-		};
-		nand1@20000000 {
-			label = "nand1";
-			reg = <0x20000000 0x02000000>; 	// first 32 MB of chip 1
+		nand@0 {
+			label = "nand";
+			reg = <0x00000000 0x40000000>;	// 512MB + 512MB
 		};
 	};
 
@@ -166,6 +161,11 @@
 			interrupt-parent = < &ipic >;
 		};
 
+		reset@e00 {	// Reset module
+			compatible = "fsl,mpc5121-reset";
+			reg = <0xe00 0x100>;
+		};
+
 		clock@f00 {	// Clock control
 			compatible = "fsl,mpc5121-clock";
 			reg = <0xf00 0x100>;
@@ -185,17 +185,15 @@
 			interrupt-parent = < &ipic >;
 		};
 
-		mscan@1300 {
+		can@1300 {
 			compatible = "fsl,mpc5121-mscan";
-			cell-index = <0>;
 			interrupts = <12 0x8>;
 			interrupt-parent = < &ipic >;
 			reg = <0x1300 0x80>;
 		};
 
-		mscan@1380 {
+		can@1380 {
 			compatible = "fsl,mpc5121-mscan";
-			cell-index = <1>;
 			interrupts = <13 0x8>;
 			interrupt-parent = < &ipic >;
 			reg = <0x1380 0x80>;
@@ -205,17 +203,31 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "fsl,mpc5121-i2c", "fsl-i2c";
-			cell-index = <0>;
 			reg = <0x1700 0x20>;
 			interrupts = <9 0x8>;
 			interrupt-parent = < &ipic >;
+			fsl,preserve-clocking;
+
+			hwmon@4a {
+				compatible = "adi,ad7414";
+				reg = <0x4a>;
+			};
+
+			eeprom@50 {
+				compatible = "at,24c32";
+				reg = <0x50>;
+			};
+
+			rtc@68 {
+				compatible = "stm,m41t62";
+				reg = <0x68>;
+			};
 		};
 
 		i2c@1720 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "fsl,mpc5121-i2c", "fsl-i2c";
-			cell-index = <1>;
 			reg = <0x1720 0x20>;
 			interrupts = <10 0x8>;
 			interrupt-parent = < &ipic >;
@@ -225,7 +237,6 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "fsl,mpc5121-i2c", "fsl-i2c";
-			cell-index = <2>;
 			reg = <0x1740 0x20>;
 			interrupts = <11 0x8>;
 			interrupt-parent = < &ipic >;
@@ -244,7 +255,7 @@
 		};
 
 		display@2100 {
-			compatible = "fsl,mpc5121-diu", "fsl-diu";
+			compatible = "fsl,mpc5121-diu";
 			reg = <0x2100 0x100>;
 			interrupts = <64 0x8>;
 			interrupt-parent = < &ipic >;
@@ -277,7 +288,7 @@
 
 		// USB1 using external ULPI PHY
 		//usb@3000 {
-		//	compatible = "fsl,mpc5121-usb2-dr", "fsl-usb2-dr";
+		//	compatible = "fsl,mpc5121-usb2-dr";
 		//	reg = <0x3000 0x1000>;
 		//	#address-cells = <1>;
 		//	#size-cells = <0>;
@@ -285,12 +296,11 @@
 		//	interrupts = <43 0x8>;
 		//	dr_mode = "otg";
 		//	phy_type = "ulpi";
-		//	port1;
 		//};
 
 		// USB0 using internal UTMI PHY
 		usb@4000 {
-			compatible = "fsl,mpc5121-usb2-dr", "fsl-usb2-dr";
+			compatible = "fsl,mpc5121-usb2-dr";
 			reg = <0x4000 0x1000>;
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -298,7 +308,8 @@
 			interrupts = <44 0x8>;
 			dr_mode = "otg";
 			phy_type = "utmi_wide";
-			port0;
+			fsl,invert-drvvbus;
+			fsl,invert-pwr-fault;
 		};
 
 		// IO control
@@ -365,7 +376,7 @@
 		};
 
 		dma@14000 {
-			compatible = "fsl,mpc5121-dma2";
+			compatible = "fsl,mpc5121-dma";
 			reg = <0x14000 0x1800>;
 			interrupts = <65 0x8>;
 			interrupt-parent = < &ipic >;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc8568mds.dts linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/mpc8568mds.dts
--- linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc8568mds.dts	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/mpc8568mds.dts	2010-05-16 17:17:36.000000000 -0400
@@ -54,9 +54,52 @@
 		reg = <0x0 0x10000000>;
 	};
 
-	bcsr@f8000000 {
-		compatible = "fsl,mpc8568mds-bcsr";
-		reg = <0xf8000000 0x8000>;
+	localbus@e0005000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,mpc8568-localbus", "fsl,pq3-localbus",
+			     "simple-bus";
+		reg = <0xe0005000 0x1000>;
+
+		ranges = <0x0 0x0 0xfe000000 0x02000000
+			  0x1 0x0 0xf8000000 0x00008000
+			  0x2 0x0 0xf0000000 0x04000000
+			  0x4 0x0 0xf8008000 0x00008000
+			  0x5 0x0 0xf8010000 0x00008000>;
+
+		nor@0,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "cfi-flash";
+			reg = <0x0 0x0 0x02000000>;
+			bank-width = <2>;
+			device-width = <2>;
+		};
+
+		bcsr@1,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8568mds-bcsr";
+			reg = <1 0 0x8000>;
+			ranges = <0 1 0 0x8000>;
+
+			bcsr5: gpio-controller@11 {
+				#gpio-cells = <2>;
+				compatible = "fsl,mpc8568mds-bcsr-gpio";
+				reg = <0x5 0x1>;
+				gpio-controller;
+			};
+		};
+
+		pib@4,0 {
+			compatible = "fsl,mpc8568mds-pib";
+			reg = <4 0 0x8000>;
+		};
+
+		pib@5,0 {
+			compatible = "fsl,mpc8568mds-pib";
+			reg = <5 0 0x8000>;
+		};
 	};
 
 	soc8568@e0000000 {
@@ -610,4 +653,20 @@
 		sleep = <&pmc 0x00080000   /* controller */
 			 &pmc 0x00040000>; /* message unit */
 	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		green {
+			gpios = <&bcsr5 1 0>;
+		};
+
+		amber {
+			gpios = <&bcsr5 2 0>;
+		};
+
+		red {
+			gpios = <&bcsr5 3 0>;
+		};
+	};
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc8569mds.dts linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/mpc8569mds.dts
--- linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc8569mds.dts	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/boot/dts/mpc8569mds.dts	2010-05-16 17:17:36.000000000 -0400
@@ -535,6 +535,7 @@
 			rx-clock-name = "none";
 			tx-clock-name = "clk12";
 			pio-handle = <&pio1>;
+			tbi-handle = <&tbi1>;
 			phy-handle = <&qe_phy0>;
 			phy-connection-type = "rgmii-id";
 		};
@@ -579,7 +580,7 @@
 				reg = <0x6>;
 				device_type = "ethernet-phy";
 			};
-			tbi-phy@11 {
+			tbi1: tbi-phy@11 {
 				reg = <0x11>;
 				device_type = "tbi-phy";
 			};
@@ -590,7 +591,7 @@
 			reg = <0x3520 0x18>;
 			compatible = "fsl,ucc-mdio";
 
-			tbi0: tbi-phy@15 {
+			tbi6: tbi-phy@15 {
 			reg = <0x15>;
 			device_type = "tbi-phy";
 			};
@@ -600,7 +601,7 @@
 			#size-cells = <0>;
 			reg = <0x3720 0x38>;
 			compatible = "fsl,ucc-mdio";
-			tbi1: tbi-phy@17 {
+			tbi8: tbi-phy@17 {
 				reg = <0x17>;
 				device_type = "tbi-phy";
 			};
@@ -617,10 +618,22 @@
 			rx-clock-name = "none";
 			tx-clock-name = "clk12";
 			pio-handle = <&pio3>;
+			tbi-handle = <&tbi3>;
 			phy-handle = <&qe_phy2>;
 			phy-connection-type = "rgmii-id";
 		};
 
+		mdio@2320 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x2320 0x18>;
+			compatible = "fsl,ucc-mdio";
+			tbi3: tbi-phy@11 {
+				reg = <0x11>;
+				device_type = "tbi-phy";
+			};
+		};
+
 		enet1: ucc@3000 {
 			device_type = "network";
 			compatible = "ucc_geth";
@@ -632,10 +645,22 @@
 			rx-clock-name = "none";
 			tx-clock-name = "clk17";
 			pio-handle = <&pio2>;
+			tbi-handle = <&tbi2>;
 			phy-handle = <&qe_phy1>;
 			phy-connection-type = "rgmii-id";
 		};
 
+		mdio@3120 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x3120 0x18>;
+			compatible = "fsl,ucc-mdio";
+			tbi2: tbi-phy@11 {
+				reg = <0x11>;
+				device_type = "tbi-phy";
+			};
+		};
+
 		enet3: ucc@3200 {
 			device_type = "network";
 			compatible = "ucc_geth";
@@ -647,10 +672,22 @@
 			rx-clock-name = "none";
 			tx-clock-name = "clk17";
 			pio-handle = <&pio4>;
+			tbi-handle = <&tbi4>;
 			phy-handle = <&qe_phy3>;
 			phy-connection-type = "rgmii-id";
 		};
 
+		mdio@3320 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x3320 0x18>;
+			compatible = "fsl,ucc-mdio";
+			tbi4: tbi-phy@11 {
+				reg = <0x11>;
+				device_type = "tbi-phy";
+			};
+		};
+
 		enet5: ucc@3400 {
 			device_type = "network";
 			compatible = "ucc_geth";
@@ -661,7 +698,7 @@
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			rx-clock-name = "none";
 			tx-clock-name = "none";
-			tbi-handle = <&tbi0>;
+			tbi-handle = <&tbi6>;
 			phy-handle = <&qe_phy5>;
 			phy-connection-type = "sgmii";
 		};
@@ -676,7 +713,7 @@
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			rx-clock-name = "none";
 			tx-clock-name = "none";
-			tbi-handle = <&tbi1>;
+			tbi-handle = <&tbi8>;
 			phy-handle = <&qe_phy7>;
 			phy-connection-type = "sgmii";
 		};
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/katmai_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/44x/katmai_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/katmai_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/44x/katmai_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc1
-# Mon Jan  4 14:55:34 2010
+# Linux kernel version: 2.6.33-rc5
+# Tue Jan 26 14:40:58 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -106,6 +106,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -442,7 +443,90 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_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
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
 CONFIG_OF_DEVICE=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
@@ -500,7 +584,7 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -763,7 +847,6 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -820,6 +903,7 @@ 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_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/cm5200_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/52xx/cm5200_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/cm5200_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/52xx/cm5200_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 14:45:07 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:34:22 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -109,6 +104,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -340,7 +336,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -517,6 +512,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -684,6 +681,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=57600
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -714,6 +712,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -754,6 +753,7 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
 # CONFIG_MPC5200_WDT is not set
 
 #
@@ -771,18 +771,20 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -813,7 +815,6 @@ CONFIG_USB=y
 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
@@ -891,7 +892,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -903,7 +903,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1009,6 +1008,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/lite5200b_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/52xx/lite5200b_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/lite5200b_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/52xx/lite5200b_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 14:45:09 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:34:24 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -95,11 +95,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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
@@ -110,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -317,6 +313,7 @@ CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_HIBERNATION is not set
 # CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
 
@@ -333,7 +330,6 @@ 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_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -360,7 +356,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -457,6 +452,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -631,6 +628,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 CONFIG_PATA_MPC52xx=y
@@ -668,7 +666,7 @@ CONFIG_PATA_MPC52xx=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -768,6 +766,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -828,6 +827,7 @@ CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -879,6 +879,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -924,18 +925,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -944,6 +948,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1062,6 +1067,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/motionpro_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/52xx/motionpro_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/motionpro_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/52xx/motionpro_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 14:45:08 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:34:23 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -109,6 +104,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -341,7 +337,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -518,6 +513,8 @@ CONFIG_MTD_ROM=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -699,6 +696,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -728,6 +726,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -773,10 +772,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_F71805F is not set
@@ -811,6 +811,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -831,6 +832,7 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
 # CONFIG_MPC5200_WDT is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -843,18 +845,20 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1050,6 +1054,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/pcm030_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/52xx/pcm030_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/pcm030_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/52xx/pcm030_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 14:45:10 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:34:25 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,11 +97,6 @@ CONFIG_RCU_FANOUT=32
 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
@@ -326,7 +321,6 @@ 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_PCCARD is not set
@@ -352,7 +346,6 @@ 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
@@ -525,6 +518,8 @@ CONFIG_MTD_PHYSMAP=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -610,6 +605,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 CONFIG_PATA_MPC52xx=m
@@ -647,7 +643,7 @@ CONFIG_PATA_MPC52xx=m
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -775,6 +771,7 @@ CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=9600
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -824,6 +821,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -870,18 +868,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -890,6 +891,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -997,7 +999,6 @@ CONFIG_USB_STORAGE=m
 # 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
@@ -1009,7 +1010,6 @@ CONFIG_USB_STORAGE=m
 # 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
 
 #
@@ -1172,6 +1172,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/tqm5200_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/52xx/tqm5200_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/tqm5200_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/52xx/tqm5200_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 14:45:09 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:34:24 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -109,6 +104,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -346,7 +342,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -524,6 +519,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -704,6 +701,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -733,6 +731,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -780,10 +779,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_F71805F is not set
@@ -818,6 +818,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -838,6 +839,7 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
 # CONFIG_MPC5200_WDT is not set
 
 #
@@ -855,18 +857,20 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -897,7 +901,6 @@ CONFIG_USB=y
 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
@@ -975,7 +978,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -987,7 +989,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1151,6 +1152,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/asp8347_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/asp8347_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/asp8347_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/asp8347_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:14 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:38 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,14 +97,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -112,6 +106,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -124,7 +119,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -325,6 +320,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -543,6 +537,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -579,6 +575,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -596,6 +593,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -788,6 +786,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -836,6 +835,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -849,15 +849,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -883,10 +877,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -923,6 +918,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -971,18 +967,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -991,6 +990,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1083,7 +1083,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # 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
@@ -1096,7 +1095,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
 
 #
@@ -1259,6 +1257,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1285,6 +1284,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/kmeter1_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/kmeter1_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/kmeter1_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/kmeter1_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:14 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:39 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -98,7 +98,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
@@ -346,7 +346,6 @@ 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
@@ -387,6 +386,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ATM is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=y
 # CONFIG_VLAN_8021Q_GVRP is not set
@@ -539,6 +539,8 @@ CONFIG_MTD_UBI_DEBUG=y
 # CONFIG_MTD_UBI_DEBUG_MSG_EBA is not set
 # CONFIG_MTD_UBI_DEBUG_MSG_WL is not set
 # CONFIG_MTD_UBI_DEBUG_MSG_IO is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -563,6 +565,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -690,6 +693,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -720,6 +724,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -732,15 +737,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -765,18 +764,20 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -805,8 +806,6 @@ CONFIG_SSB_POSSIBLE=y
 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
 
 #
 # TI VLYNQ
@@ -887,6 +886,7 @@ CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_UBIFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -911,6 +911,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -976,6 +977,7 @@ CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_HAVE_FUNCTION_TRACER=y
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:15 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:40 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ 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
@@ -362,7 +357,6 @@ 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
@@ -556,6 +550,8 @@ CONFIG_MTD_NAND_FSL_ELBC=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -593,6 +589,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -612,6 +609,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -772,6 +770,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -824,6 +823,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -836,6 +837,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -931,6 +933,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -980,6 +983,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -993,15 +997,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 # CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
@@ -1044,10 +1042,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1086,6 +1085,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1134,21 +1134,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1157,6 +1160,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1289,7 +1293,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1302,7 +1305,6 @@ CONFIG_USB_STORAGE=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=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -1341,6 +1343,7 @@ CONFIG_USB_ETH_RNDIS=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -1511,6 +1514,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1537,6 +1541,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:16 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:40 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ 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
@@ -362,7 +357,6 @@ 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
@@ -556,6 +550,8 @@ CONFIG_MTD_NAND_IDS=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -593,6 +589,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -612,6 +609,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -735,6 +733,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -837,6 +836,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -889,6 +889,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -901,6 +903,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -996,6 +999,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1045,6 +1049,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1058,15 +1063,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 # CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
@@ -1109,10 +1108,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1151,6 +1151,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1199,21 +1200,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1222,6 +1226,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1354,7 +1359,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1367,7 +1371,6 @@ CONFIG_USB_STORAGE=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=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -1406,6 +1409,7 @@ CONFIG_USB_ETH_RNDIS=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -1576,6 +1580,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1602,6 +1607,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc832x_mds_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc832x_mds_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc832x_mds_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc832x_mds_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:17 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:41 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -325,6 +320,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ 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
@@ -457,6 +451,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -492,6 +488,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -509,6 +506,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -693,6 +691,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -705,6 +705,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -790,6 +791,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -839,6 +841,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -851,15 +854,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -885,10 +882,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -925,6 +923,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -967,18 +966,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -987,6 +989,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1171,6 +1174,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1197,6 +1201,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:18 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:42 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -325,6 +320,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ 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
@@ -457,6 +451,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -494,6 +490,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -514,6 +511,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -700,6 +698,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -712,6 +712,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -808,6 +809,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -859,6 +861,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -872,15 +875,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 
@@ -922,10 +919,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -964,6 +962,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1012,21 +1011,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1035,6 +1037,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1166,7 +1169,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1179,7 +1181,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1204,8 +1205,6 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 #
 # CONFIG_MMC_SDHCI is not set
 # CONFIG_MMC_WBSD is not set
-# CONFIG_MMC_AT91 is not set
-# CONFIG_MMC_ATMELMCI is not set
 # CONFIG_MMC_TIFM_SD is not set
 CONFIG_MMC_SPI=y
 # CONFIG_MMC_CB710 is not set
@@ -1298,6 +1297,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1324,6 +1324,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc834x_itx_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc834x_itx_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc834x_itx_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc834x_itx_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:19 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:43 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ 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
@@ -540,6 +534,8 @@ CONFIG_MTD_PHYSMAP=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -577,6 +573,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -644,6 +641,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -767,6 +765,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -880,6 +879,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -892,6 +893,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -966,6 +968,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1015,6 +1018,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1028,15 +1032,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 
@@ -1095,21 +1093,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1118,6 +1119,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1222,7 +1224,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1235,7 +1236,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1399,6 +1399,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1425,6 +1426,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:20 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:44 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ 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
@@ -540,6 +534,8 @@ CONFIG_MTD_PHYSMAP=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -577,6 +573,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -596,6 +593,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -756,6 +754,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -768,6 +768,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -842,6 +843,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -891,6 +893,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -904,15 +907,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 
@@ -971,21 +968,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -994,6 +994,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1098,7 +1099,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1111,7 +1111,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1275,6 +1274,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1301,6 +1301,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc834x_mds_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc834x_mds_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc834x_mds_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc834x_mds_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:21 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:45 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -456,6 +450,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -491,6 +487,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -508,6 +505,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -580,6 +578,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -631,6 +630,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -643,6 +644,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -726,6 +728,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -774,6 +777,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -786,15 +790,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -820,10 +818,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -860,6 +859,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -902,18 +902,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -922,6 +925,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1106,6 +1110,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1132,6 +1137,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc836x_mds_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc836x_mds_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc836x_mds_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc836x_mds_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:21 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:46 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -323,6 +318,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -334,7 +330,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -360,7 +355,6 @@ 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
@@ -538,6 +532,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -573,6 +569,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -590,6 +587,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -774,6 +772,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -786,6 +786,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -871,6 +872,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -920,6 +922,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -932,15 +935,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -966,10 +963,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1006,6 +1004,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1048,18 +1047,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1068,6 +1070,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1253,6 +1256,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1279,6 +1283,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:23 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:47 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,14 +97,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -112,6 +106,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -124,7 +119,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -323,6 +318,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ 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
@@ -550,6 +544,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -587,6 +583,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -606,6 +603,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -774,6 +772,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_SERIAL_QE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -825,6 +824,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -837,15 +837,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 
@@ -876,14 +870,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -932,22 +930,27 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -956,6 +959,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1145,6 +1149,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1171,6 +1176,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc837x_mds_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc837x_mds_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc837x_mds_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc837x_mds_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:22 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:47 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -124,7 +119,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -456,6 +450,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -491,6 +487,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -508,6 +505,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -631,6 +629,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -755,6 +754,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -767,6 +768,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -851,6 +853,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -901,6 +904,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -913,15 +917,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -947,10 +945,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -987,6 +986,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1029,18 +1029,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1049,6 +1052,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1175,6 +1179,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1201,6 +1206,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:24 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:48 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -124,7 +119,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ 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
@@ -451,6 +445,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -487,6 +483,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -504,6 +501,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -626,6 +624,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -850,6 +849,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -900,6 +900,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -913,15 +914,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -947,10 +942,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -987,6 +983,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1034,18 +1031,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1054,6 +1054,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1079,6 +1080,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1094,14 +1096,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1190,7 +1197,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # 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
@@ -1203,7 +1209,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
 
 #
@@ -1297,6 +1302,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1323,6 +1329,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/sbc834x_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/sbc834x_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/sbc834x_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/83xx/sbc834x_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:25 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:49 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -322,6 +317,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -333,7 +329,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -359,7 +354,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -537,6 +531,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -573,6 +569,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -590,6 +587,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -812,6 +810,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -862,6 +861,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -875,15 +875,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -909,10 +903,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -949,6 +944,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -996,18 +992,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1016,6 +1015,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1140,7 +1140,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1153,7 +1152,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1245,6 +1243,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1271,6 +1270,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/ksi8560_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/ksi8560_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/ksi8560_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/ksi8560_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:26 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:50 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,10 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -110,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -315,6 +318,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
 # CONFIG_PCI is not set
@@ -345,7 +349,6 @@ 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
@@ -522,6 +525,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_MDIO=y
@@ -575,6 +580,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -701,6 +707,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -732,6 +739,7 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
 
 #
@@ -915,6 +923,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -937,6 +946,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1036,6 +1046,7 @@ CONFIG_DEBUG_MUTEXES=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/mpc8540_ads_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/mpc8540_ads_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/mpc8540_ads_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/mpc8540_ads_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:27 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:51 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -316,6 +315,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
 # CONFIG_PCI is not set
@@ -346,7 +346,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -443,6 +442,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -477,6 +478,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -602,6 +604,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -788,6 +791,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -810,6 +814,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/mpc8560_ads_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/mpc8560_ads_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/mpc8560_ads_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/mpc8560_ads_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:28 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:52 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -319,6 +318,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -329,7 +329,6 @@ 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=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -358,7 +357,6 @@ 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
@@ -455,6 +453,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_MDIO=y
@@ -500,6 +500,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -609,6 +610,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -621,6 +624,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -700,6 +704,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -733,7 +738,9 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
@@ -793,6 +800,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -801,6 +810,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -927,6 +937,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -949,6 +960,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:29 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:53 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -317,6 +316,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -327,7 +327,6 @@ 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
@@ -356,7 +355,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -453,6 +451,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -552,6 +552,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -657,6 +658,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -669,6 +672,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -753,6 +757,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -817,6 +822,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -825,6 +831,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -951,6 +958,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -973,6 +981,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/sbc8548_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/sbc8548_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/sbc8548_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/sbc8548_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:29 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:54 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -314,6 +313,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -324,7 +324,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -352,7 +351,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -447,6 +445,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -491,6 +491,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -596,6 +597,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -608,6 +611,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -692,6 +696,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -756,6 +761,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -764,6 +770,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -856,6 +863,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -878,6 +886,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/sbc8560_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/sbc8560_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/sbc8560_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/sbc8560_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:30 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:54 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -314,6 +313,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
 # CONFIG_PCI is not set
@@ -344,7 +344,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -441,6 +440,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -475,6 +476,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -600,6 +602,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -815,6 +818,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -837,6 +841,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/socrates_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/socrates_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/socrates_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/socrates_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:31 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:55 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -319,6 +318,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -329,7 +329,6 @@ 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
@@ -355,7 +354,6 @@ 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
@@ -554,6 +552,8 @@ CONFIG_MTD_NAND_SOCRATES=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -591,6 +591,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -610,6 +611,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -867,6 +869,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -916,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -929,15 +933,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 
@@ -979,10 +977,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1021,6 +1020,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1050,21 +1050,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1073,6 +1076,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1180,6 +1184,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 # CONFIG_HID_A4TECH is not set
 # CONFIG_HID_APPLE is not set
 # CONFIG_HID_BELKIN is not set
@@ -1194,12 +1199,16 @@ CONFIG_USB_HID=y
 # CONFIG_HID_KENSINGTON is not set
 # CONFIG_HID_LOGITECH is not set
 # CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
 # CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_QUANTA is not set
 # CONFIG_HID_SAMSUNG is not set
 # CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
 # CONFIG_HID_SUNPLUS is not set
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1307,7 +1316,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1320,7 +1328,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1491,6 +1498,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1515,6 +1523,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/stx_gp3_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/stx_gp3_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/stx_gp3_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/stx_gp3_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:32 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:56 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -324,6 +323,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -334,7 +334,6 @@ 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
@@ -363,7 +362,6 @@ 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
@@ -520,6 +518,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=m
@@ -563,6 +563,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -630,6 +631,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=m
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=m
 CONFIG_SCSI_DMA=y
@@ -817,6 +819,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -829,6 +833,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -947,6 +952,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1004,6 +1010,7 @@ CONFIG_I2C_ALGOBIT=m
 # CONFIG_I2C_MPC is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1017,15 +1024,9 @@ CONFIG_I2C_ALGOBIT=m
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1041,14 +1042,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1081,10 +1086,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1122,6 +1128,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1155,9 +1162,10 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TPS65010 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
-# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1166,6 +1174,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 CONFIG_AGP=m
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 CONFIG_DRM=m
 # CONFIG_DRM_TDFX is not set
 # CONFIG_DRM_R128 is not set
@@ -1308,6 +1317,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=m
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1333,6 +1343,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8540_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/tqm8540_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8540_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/tqm8540_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:33 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:57 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -315,6 +314,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -325,7 +325,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -351,7 +350,6 @@ 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
@@ -525,6 +523,8 @@ CONFIG_MTD_CFI_UTIL=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -560,6 +560,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -632,6 +633,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -704,6 +706,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -755,6 +758,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -767,6 +772,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -851,6 +857,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -902,6 +909,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -913,15 +921,9 @@ CONFIG_I2C_MPC=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -947,10 +949,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -987,6 +990,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1015,18 +1019,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1035,6 +1042,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1172,6 +1180,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1194,6 +1203,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8541_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/tqm8541_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8541_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/tqm8541_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:34 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:58 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -328,7 +328,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -354,7 +353,6 @@ 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
@@ -528,6 +526,8 @@ CONFIG_MTD_CFI_UTIL=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -564,6 +564,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -636,6 +637,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -708,6 +710,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -760,6 +763,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -772,6 +777,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -858,6 +864,7 @@ CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -912,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -923,15 +931,9 @@ CONFIG_I2C_MPC=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -946,14 +948,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -986,10 +992,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1027,6 +1034,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1055,19 +1063,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1076,6 +1089,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1213,6 +1227,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1235,6 +1250,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8548_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/tqm8548_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8548_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/tqm8548_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:35 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:59 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -324,6 +323,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -339,7 +339,6 @@ 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 is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -368,7 +367,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -559,6 +557,8 @@ CONFIG_MTD_NAND_FSL_UPM=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -594,6 +594,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -611,6 +612,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -716,6 +718,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -728,6 +732,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -812,6 +817,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -860,6 +866,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -872,15 +879,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -906,10 +907,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -946,6 +948,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -974,18 +977,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -994,6 +1000,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1162,6 +1169,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1184,6 +1192,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8555_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/tqm8555_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8555_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/tqm8555_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:36 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:00 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -328,7 +328,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -354,7 +353,6 @@ 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
@@ -528,6 +526,8 @@ CONFIG_MTD_CFI_UTIL=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -564,6 +564,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -636,6 +637,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -708,6 +710,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -760,6 +763,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -772,6 +777,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -858,6 +864,7 @@ CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -912,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -923,15 +931,9 @@ CONFIG_I2C_MPC=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -946,14 +948,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -986,10 +992,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1027,6 +1034,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1055,19 +1063,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1076,6 +1089,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1213,6 +1227,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1235,6 +1250,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8560_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/tqm8560_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8560_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/tqm8560_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:36 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:01 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -328,7 +328,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -354,7 +353,6 @@ 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
@@ -528,6 +526,8 @@ CONFIG_MTD_CFI_UTIL=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -564,6 +564,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -636,6 +637,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -708,6 +710,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -760,6 +763,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -772,6 +777,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -858,6 +864,7 @@ CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -912,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -923,15 +931,9 @@ CONFIG_I2C_MPC=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -946,14 +948,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -986,10 +992,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1027,6 +1034,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1055,19 +1063,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1076,6 +1089,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1213,6 +1227,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1235,6 +1250,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:37 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:01 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -69,6 +69,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -104,10 +108,8 @@ CONFIG_RCU_FANOUT=32
 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -115,6 +117,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -328,6 +331,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -343,7 +347,6 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 CONFIG_PCI_MSI=y
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -375,7 +378,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -600,6 +602,8 @@ CONFIG_MTD_NAND_FSL_UPM=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -637,6 +641,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -654,6 +659,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -777,6 +783,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -1004,6 +1011,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1053,6 +1061,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1066,15 +1075,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1090,14 +1093,19 @@ CONFIG_GPIO_SYSFS=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 CONFIG_GPIO_PCA953X=y
+# CONFIG_GPIO_PCA953X_IRQ is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1130,10 +1138,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 CONFIG_SENSORS_DS1621=y
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1171,6 +1180,7 @@ CONFIG_SENSORS_LM90=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1218,19 +1228,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1239,6 +1254,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1271,6 +1287,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 # CONFIG_HID_A4TECH is not set
 # CONFIG_HID_APPLE is not set
 # CONFIG_HID_BELKIN is not set
@@ -1285,12 +1302,16 @@ CONFIG_USB_HID=y
 # CONFIG_HID_KENSINGTON is not set
 # CONFIG_HID_LOGITECH is not set
 # CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
 # CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_QUANTA is not set
 # CONFIG_HID_SAMSUNG is not set
 # CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
 # CONFIG_HID_SUNPLUS is not set
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1386,7 +1407,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1398,7 +1418,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1423,11 +1442,11 @@ CONFIG_LEDS_GPIO_OF=y
 CONFIG_LEDS_PCA955X=y
 # CONFIG_LEDS_BD2802 is not set
 # CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
 
 #
 # LED Triggers
 #
-CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
@@ -1506,6 +1525,7 @@ CONFIG_RTC_DRV_CMOS=y
 #
 # CONFIG_RTC_DRV_GENERIC is not set
 CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
 
 #
 # DMA Devices
@@ -1614,6 +1634,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1641,6 +1662,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1851,6 +1873,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/gef_ppc9a_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/gef_ppc9a_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/86xx/gef_ppc9a_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:43 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:07 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -102,11 +102,6 @@ CONFIG_RCU_FANOUT=32
 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
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -325,6 +321,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -340,13 +337,11 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
 CONFIG_PCMCIA=y
 # CONFIG_PCMCIA_LOAD_CIS is not set
-# CONFIG_PCMCIA_IOCTL is not set
 # CONFIG_CARDBUS is not set
 
 #
@@ -382,7 +377,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -592,6 +586,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -629,6 +625,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 CONFIG_DS1682=y
 # CONFIG_C2PORT is not set
 
@@ -695,6 +692,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -819,6 +817,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -1059,6 +1058,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1116,6 +1116,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1129,15 +1130,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1152,14 +1147,18 @@ CONFIG_GPIO_SYSFS=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1192,10 +1191,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1233,6 +1233,7 @@ CONFIG_SENSORS_LM92=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1281,19 +1282,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1302,6 +1308,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1334,6 +1341,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1349,14 +1357,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1463,7 +1476,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1476,7 +1488,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1557,7 +1568,62 @@ CONFIG_RTC_DRV_RX8581=y
 #
 # TI VLYNQ
 #
-# CONFIG_STAGING is not set
+CONFIG_STAGING=y
+# CONFIG_STAGING_EXCLUDE_BUILD is not set
+# CONFIG_ET131X is not set
+# CONFIG_USB_IP_COMMON is not set
+# CONFIG_PRISM2_USB is not set
+# CONFIG_ECHO is not set
+# CONFIG_COMEDI is not set
+# CONFIG_ASUS_OLED is not set
+# CONFIG_R8187SE is not set
+# CONFIG_RTL8192SU is not set
+# CONFIG_RTL8192U is not set
+# CONFIG_RTL8192E is not set
+# CONFIG_TRANZPORT is not set
+
+#
+# Qualcomm MSM Camera And Video
+#
+
+#
+# Camera Sensor Selection
+#
+# CONFIG_INPUT_GPIO is not set
+# CONFIG_POHMELFS is not set
+# CONFIG_IDE_PHISON is not set
+# CONFIG_VT6655 is not set
+# CONFIG_VT6656 is not set
+CONFIG_VME_BUS=y
+
+#
+# VME Bridge Drivers
+#
+# CONFIG_VME_CA91CX42 is not set
+CONFIG_VME_TSI148=y
+
+#
+# VME Device Drivers
+#
+# CONFIG_VME_USER is not set
+
+#
+# VME Board Drivers
+#
+# CONFIG_VMIVME_7805 is not set
+
+#
+# RAR Register Driver
+#
+# CONFIG_RAR_REGISTER is not set
+# CONFIG_IIO is not set
+# CONFIG_RAMZSWAP is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_STRIP is not set
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+# CONFIG_DT3155 is not set
+# CONFIG_CRYSTALHD is not set
 
 #
 # File systems
@@ -1648,6 +1714,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1674,6 +1741,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1819,6 +1887,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/gef_sbc310_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/86xx/gef_sbc310_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/gef_sbc310_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/86xx/gef_sbc310_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:41 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:05 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -102,11 +102,6 @@ CONFIG_RCU_FANOUT=32
 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
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -325,6 +321,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -340,13 +337,11 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
 CONFIG_PCMCIA=y
 # CONFIG_PCMCIA_LOAD_CIS is not set
-# CONFIG_PCMCIA_IOCTL is not set
 # CONFIG_CARDBUS is not set
 
 #
@@ -382,7 +377,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -592,6 +586,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -629,6 +625,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 CONFIG_DS1682=y
 # CONFIG_C2PORT is not set
 
@@ -695,6 +692,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -1001,6 +999,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1058,6 +1057,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1071,15 +1071,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1094,14 +1088,18 @@ CONFIG_GPIO_SYSFS=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1134,10 +1132,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1175,6 +1174,7 @@ CONFIG_SENSORS_LM92=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1223,19 +1223,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1244,6 +1249,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1276,6 +1282,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1291,14 +1298,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1405,7 +1417,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1418,7 +1429,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1590,6 +1600,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1616,6 +1627,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1761,6 +1773,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/gef_sbc610_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/86xx/gef_sbc610_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/gef_sbc610_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/86xx/gef_sbc610_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:42 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:06 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -102,11 +102,6 @@ CONFIG_RCU_FANOUT=32
 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
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -265,7 +261,7 @@ CONFIG_MMIO_NVRAM=y
 #
 # Kernel options
 #
-# CONFIG_HIGHMEM is not set
+CONFIG_HIGHMEM=y
 CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
 CONFIG_HIGH_RES_TIMERS=y
@@ -326,6 +322,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -341,7 +338,6 @@ 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
@@ -369,7 +365,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -552,6 +547,7 @@ CONFIG_ATM_BR2684=m
 # CONFIG_ATM_BR2684_IPFILTER is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=m
 # CONFIG_VLAN_8021Q_GVRP is not set
@@ -651,7 +647,7 @@ CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_OF_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
 # CONFIG_MTD_AR7_PARTS is not set
 
 #
@@ -671,13 +667,9 @@ CONFIG_MTD_BLOCK=y
 # RAM/ROM/Flash chip drivers
 #
 CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
+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 is not set
+# 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
@@ -688,7 +680,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_OTP is not set
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
 # CONFIG_MTD_CFI_STAA is not set
@@ -733,6 +724,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -770,6 +763,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 CONFIG_DS1682=y
 # CONFIG_C2PORT is not set
 
@@ -787,6 +781,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -910,6 +905,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -1160,6 +1156,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1209,6 +1206,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1222,15 +1220,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1246,14 +1238,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1286,10 +1282,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1327,6 +1324,7 @@ CONFIG_SENSORS_LM92=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1375,19 +1373,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1396,6 +1399,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1428,6 +1432,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1443,14 +1448,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1557,7 +1567,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1570,7 +1579,6 @@ CONFIG_USB_STORAGE=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_ATM is not set
 # CONFIG_USB_GADGET is not set
 
@@ -1652,7 +1660,60 @@ CONFIG_RTC_DRV_RX8581=y
 #
 # TI VLYNQ
 #
-# CONFIG_STAGING is not set
+CONFIG_STAGING=y
+# CONFIG_STAGING_EXCLUDE_BUILD is not set
+# CONFIG_ET131X is not set
+# CONFIG_USB_IP_COMMON is not set
+# CONFIG_PRISM2_USB is not set
+# CONFIG_ECHO is not set
+# CONFIG_COMEDI is not set
+# CONFIG_ASUS_OLED is not set
+# CONFIG_R8187SE is not set
+# CONFIG_RTL8192SU is not set
+# CONFIG_RTL8192U is not set
+# CONFIG_RTL8192E is not set
+# CONFIG_TRANZPORT is not set
+
+#
+# Qualcomm MSM Camera And Video
+#
+
+#
+# Camera Sensor Selection
+#
+# CONFIG_INPUT_GPIO is not set
+# CONFIG_POHMELFS is not set
+# CONFIG_IDE_PHISON is not set
+# CONFIG_VT6655 is not set
+# CONFIG_VT6656 is not set
+CONFIG_VME_BUS=y
+
+#
+# VME Bridge Drivers
+#
+# CONFIG_VME_CA91CX42 is not set
+CONFIG_VME_TSI148=y
+
+#
+# VME Device Drivers
+#
+# CONFIG_VME_USER is not set
+
+#
+# VME Board Drivers
+#
+# CONFIG_VMIVME_7805 is not set
+
+#
+# RAR Register Driver
+#
+# CONFIG_RAR_REGISTER is not set
+# CONFIG_IIO is not set
+# CONFIG_RAMZSWAP is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_STRIP is not set
+# CONFIG_DT3155 is not set
+# CONFIG_CRYSTALHD is not set
 
 #
 # File systems
@@ -1729,7 +1790,18 @@ 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_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_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1756,6 +1828,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1828,7 +1901,7 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=m
+CONFIG_ZLIB_DEFLATE=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
@@ -1874,6 +1947,7 @@ CONFIG_DEBUG_PREEMPT=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=y
 # CONFIG_DEBUG_VM is not set
@@ -1963,6 +2037,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:39 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:03 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,11 +97,6 @@ CONFIG_RCU_FANOUT=32
 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
@@ -112,6 +107,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -320,6 +316,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +332,6 @@ 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
@@ -362,7 +358,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -571,6 +566,8 @@ CONFIG_MTD_NAND_FSL_ELBC=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
@@ -605,6 +602,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -670,6 +668,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -792,6 +791,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -970,6 +970,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1017,6 +1018,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1029,15 +1031,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1062,18 +1058,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1082,6 +1081,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1434,6 +1434,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1461,6 +1462,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:40 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:04 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,15 +97,11 @@ CONFIG_TREE_RCU=y
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
 # CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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
@@ -116,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -326,6 +323,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -337,7 +335,6 @@ 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
@@ -365,7 +362,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -498,6 +494,8 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -534,6 +532,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -551,6 +550,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -675,6 +675,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -799,6 +800,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -811,6 +814,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -920,6 +924,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -968,6 +973,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -981,15 +987,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1014,18 +1014,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1034,6 +1037,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1151,6 +1155,7 @@ CONFIG_SND_INTEL8X0=y
 CONFIG_SND_PPC=y
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
@@ -1170,6 +1175,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1185,14 +1191,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1300,7 +1311,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1313,7 +1323,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1475,6 +1484,7 @@ CONFIG_BEFS_FS=m
 # CONFIG_BEFS_DEBUG is not set
 CONFIG_BFS_FS=m
 CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 CONFIG_VXFS_FS=m
@@ -1506,6 +1516,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1717,6 +1728,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/sbc8641d_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/86xx/sbc8641d_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/sbc8641d_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/86xx/sbc8641d_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:38 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:02 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -101,11 +101,6 @@ CONFIG_RCU_FANOUT=32
 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
@@ -116,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -327,6 +323,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -342,7 +339,6 @@ 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 is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -369,7 +365,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -552,6 +547,7 @@ CONFIG_ATM_BR2684=m
 # CONFIG_ATM_BR2684_IPFILTER is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=m
 # CONFIG_VLAN_8021Q_GVRP is not set
@@ -733,6 +729,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -768,6 +766,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -785,6 +784,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -1024,6 +1024,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1074,6 +1075,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1086,15 +1088,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1120,10 +1116,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1160,6 +1157,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1202,18 +1200,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1222,6 +1223,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1376,6 +1378,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1408,6 +1411,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
 CONFIG_SMB_FS=m
 CONFIG_SMB_NLS_DEFAULT=y
 CONFIG_SMB_NLS_REMOTE="cp437"
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1540,6 +1544,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1618,6 +1623,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/adder875_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/adder875_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/adder875_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/adder875_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:23:58 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:22 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -91,11 +91,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -307,6 +302,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_FSL_SOC=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
@@ -336,7 +332,6 @@ 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
@@ -505,6 +500,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -516,6 +513,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -664,6 +662,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -802,6 +801,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -826,6 +826,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -924,6 +925,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/c2k_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/c2k_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/c2k_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/c2k_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:23:59 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:23 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -101,11 +101,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -121,6 +116,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -147,7 +143,6 @@ CONFIG_HAVE_PERF_EVENTS=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 # CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
@@ -158,7 +153,6 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
@@ -357,6 +351,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_PCI=y
@@ -365,7 +360,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 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
@@ -396,7 +390,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -527,6 +520,7 @@ CONFIG_IP_VS_PROTO_UDP=y
 CONFIG_IP_VS_PROTO_AH_ESP=y
 CONFIG_IP_VS_PROTO_ESP=y
 CONFIG_IP_VS_PROTO_AH=y
+# CONFIG_IP_VS_PROTO_SCTP is not set
 
 #
 # IPVS scheduler
@@ -630,6 +624,7 @@ CONFIG_ATM_BR2684=m
 # CONFIG_ATM_BR2684_IPFILTER is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=m
 # CONFIG_VLAN_8021Q_GVRP is not set
@@ -690,7 +685,6 @@ 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
@@ -833,6 +827,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=m
 CONFIG_OF_MDIO=y
@@ -867,6 +863,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=m
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=m
 CONFIG_SCSI_DMA=y
@@ -1179,6 +1176,7 @@ CONFIG_SERIAL_MPSC_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1231,6 +1229,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MV64XXX=m
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1244,15 +1243,9 @@ CONFIG_I2C_MV64XXX=m
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1278,10 +1271,11 @@ CONFIG_SENSORS_ADM1026=m
 # CONFIG_SENSORS_ADM1029 is not set
 CONFIG_SENSORS_ADM1031=m
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 CONFIG_SENSORS_DS1621=m
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1318,6 +1312,7 @@ CONFIG_SENSORS_SMSC47M1=m
 # CONFIG_SENSORS_SMSC47M192 is not set
 CONFIG_SENSORS_SMSC47B397=m
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1369,9 +1364,9 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
-# CONFIG_AB3100_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1380,6 +1375,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1413,7 +1409,6 @@ CONFIG_USB=m
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
-CONFIG_USB_SUSPEND=y
 # CONFIG_USB_OTG is not set
 CONFIG_USB_MON=m
 # CONFIG_USB_WUSB is not set
@@ -1535,6 +1530,7 @@ 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_QCAUX is not set
 # CONFIG_USB_SERIAL_QUALCOMM is not set
 # CONFIG_USB_SERIAL_SPCP8X5 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
@@ -1549,6 +1545,7 @@ CONFIG_USB_SERIAL_XIRCOM=m
 # CONFIG_USB_SERIAL_OPTION is not set
 CONFIG_USB_SERIAL_OMNINET=m
 # CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
 # CONFIG_USB_SERIAL_DEBUG is not set
 
 #
@@ -1561,7 +1558,6 @@ CONFIG_USB_EMI62=m
 CONFIG_USB_RIO500=m
 CONFIG_USB_LEGOTOWER=m
 CONFIG_USB_LCD=m
-# CONFIG_USB_BERRY_CHARGE is not set
 CONFIG_USB_LED=m
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1574,7 +1570,6 @@ CONFIG_USB_LED=m
 # CONFIG_USB_IOWARRIOR is not set
 CONFIG_USB_TEST=m
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 CONFIG_USB_ATM=m
 CONFIG_USB_SPEEDTOUCH=m
 # CONFIG_USB_CXACRU is not set
@@ -1611,6 +1606,7 @@ CONFIG_INFINIBAND_SRP=m
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
 
 #
 # DMA Devices
@@ -1714,6 +1710,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=m
 # CONFIG_SQUASHFS is not set
 CONFIG_VXFS_FS=m
@@ -1742,6 +1739,7 @@ CONFIG_SUNRPC_XPRT_RDMA=m
 CONFIG_RPCSEC_GSS_KRB5=y
 CONFIG_RPCSEC_GSS_SPKM3=m
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1817,7 +1815,7 @@ CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
 CONFIG_NLS_UTF8=m
 # CONFIG_DLM is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1833,9 +1831,11 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
@@ -1880,7 +1880,6 @@ CONFIG_DEBUG_SPINLOCK=y
 # CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_HIGHMEM=y
 CONFIG_DEBUG_BUGVERBOSE=y
@@ -1903,16 +1902,12 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # 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_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/ep8248e_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/ep8248e_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/ep8248e_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/ep8248e_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:23:59 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:24 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -298,6 +298,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
@@ -308,7 +309,6 @@ CONFIG_PCI_8260=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
@@ -335,7 +335,6 @@ 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
@@ -537,6 +536,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_MDIO=y
@@ -566,6 +567,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -671,6 +673,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -683,6 +687,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -737,6 +742,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -765,7 +771,9 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
@@ -804,6 +812,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -812,6 +822,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -869,6 +880,7 @@ CONFIG_AUTOFS4_FS=y
 #
 # Caches
 #
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/ep88xc_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/ep88xc_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/ep88xc_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/ep88xc_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:00 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:24 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -90,11 +90,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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
@@ -306,6 +301,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_FSL_SOC=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
@@ -335,7 +331,6 @@ 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
@@ -504,6 +499,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -515,6 +512,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -616,6 +614,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -753,6 +752,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -777,6 +777,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/linkstation_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/linkstation_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/linkstation_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/linkstation_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:01 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:25 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,11 +96,6 @@ CONFIG_RCU_FANOUT=32
 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
@@ -116,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -328,6 +324,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -337,7 +334,6 @@ 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
@@ -364,7 +360,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -433,6 +428,7 @@ CONFIG_NF_CONNTRACK_TFTP=m
 CONFIG_NETFILTER_XTABLES=m
 # CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
 # CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_CT 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
@@ -665,6 +661,8 @@ CONFIG_MTD_PHYSMAP=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
@@ -700,6 +698,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -717,6 +716,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -840,6 +840,7 @@ CONFIG_ATA_SFF=y
 CONFIG_PATA_IT821X=y
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -954,6 +955,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -966,6 +969,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -1082,6 +1086,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1131,6 +1136,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1144,15 +1150,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1178,10 +1178,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1218,6 +1219,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1246,18 +1248,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1266,6 +1271,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1417,6 +1423,7 @@ 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_QCAUX is not set
 # CONFIG_USB_SERIAL_QUALCOMM is not set
 # CONFIG_USB_SERIAL_SPCP8X5 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
@@ -1430,6 +1437,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=y
 # CONFIG_USB_SERIAL_OPTION is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
 # CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
 # CONFIG_USB_SERIAL_DEBUG is not set
 
 #
@@ -1442,7 +1450,6 @@ CONFIG_USB_SERIAL_FTDI_SIO=y
 # 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
@@ -1455,7 +1462,6 @@ CONFIG_USB_SERIAL_FTDI_SIO=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
 
 #
@@ -1620,6 +1626,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1651,6 +1658,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1723,9 +1731,11 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_TEXTSEARCH=y
 CONFIG_TEXTSEARCH_KMP=m
 CONFIG_HAS_IOMEM=y
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/mgcoge_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/mgcoge_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/mgcoge_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/mgcoge_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:02 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:26 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -105,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -311,6 +312,7 @@ CONFIG_ISA_DMA_API=y
 #
 # CONFIG_ISA is not set
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
@@ -321,7 +323,6 @@ CONFIG_PCI_8260=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
@@ -348,7 +349,6 @@ 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
@@ -536,6 +536,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -570,6 +572,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -704,6 +707,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -769,14 +773,9 @@ CONFIG_I2C_CPM=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
 # 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
 
 #
@@ -790,14 +789,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -829,19 +832,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -850,6 +858,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -908,6 +917,7 @@ CONFIG_AUTOFS4_FS=y
 #
 # Caches
 #
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1100,6 +1110,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/mgsuvd_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/mgsuvd_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/mgsuvd_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/mgsuvd_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:03 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:27 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -89,11 +89,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -104,6 +99,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -309,6 +305,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_FSL_SOC=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
@@ -337,7 +334,6 @@ 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
@@ -515,6 +511,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -542,6 +540,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -643,6 +642,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -801,6 +801,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -825,6 +826,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -892,6 +894,7 @@ CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc512x_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc512x_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc512x_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc512x_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1694 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc6
+# Fri Feb  5 11:48:29 2010
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_PPC_BOOK3S_32=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
+CONFIG_PPC_FPU=y
+# CONFIG_ALTIVEC is not set
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
+# CONFIG_SMP is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
+CONFIG_DEFAULT_UIMAGE=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"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=16
+# 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_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=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_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_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+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_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# Platform support
+#
+# CONFIG_PPC_CHRP is not set
+CONFIG_PPC_MPC512x=y
+CONFIG_PPC_MPC5121=y
+CONFIG_MPC5121_ADS=y
+# 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 is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
+CONFIG_IPIC=y
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+# CONFIG_QUICC_ENGINE 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 is not set
+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 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_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+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_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_FSL_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS 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_SIZE=0x00200000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP 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 is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+CONFIG_CAN_VCAN=y
+CONFIG_CAN_DEV=y
+# CONFIG_CAN_CALC_BITTIMING is not set
+CONFIG_CAN_MSCAN=y
+# CONFIG_CAN_SJA1000 is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+CONFIG_CAN_DEBUG_DEVICES=y
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# 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=y
+# 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_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_NAND_FSL_ELBC is not set
+CONFIG_MTD_NAND_MPC5121_NFC=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+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_I2C=y
+CONFIG_OF_MDIO=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_XIP=y
+# 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_AD525X_DPOT is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_FIXED_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
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMACLITE is not set
+CONFIG_FS_ENET=y
+CONFIG_FS_ENET_MPC5121_FEC=y
+CONFIG_FS_ENET_HAS_FEC=y
+CONFIG_FS_ENET_MDIO_FEC=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# 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
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# 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 is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_MPC52xx=y
+CONFIG_SERIAL_MPC52xx_CONSOLE=y
+CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+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_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+CONFIG_I2C_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
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# 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_IR_CORE=y
+CONFIG_VIDEO_IR=y
+# 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_CAPTURE_DRIVERS=y
+CONFIG_VIDEO_ADV_DEBUG=y
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+CONFIG_VIDEO_IR_I2C=y
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TDA9875 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_M52790 is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+
+#
+# RDS decoders
+#
+# CONFIG_VIDEO_SAA6588 is not set
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_ADV7180 is not set
+# CONFIG_VIDEO_BT819 is not set
+# CONFIG_VIDEO_BT856 is not set
+# CONFIG_VIDEO_BT866 is not set
+# CONFIG_VIDEO_KS0127 is not set
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_MT9V011 is not set
+# CONFIG_VIDEO_TCM825X is not set
+# CONFIG_VIDEO_SAA7110 is not set
+CONFIG_VIDEO_SAA711X=y
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_TVP514X is not set
+# CONFIG_VIDEO_TVP5150 is not set
+# CONFIG_VIDEO_VPX3220 is not set
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_CX25840 is not set
+
+#
+# MPEG video encoders
+#
+# CONFIG_VIDEO_CX2341X is not set
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_SAA7185 is not set
+# CONFIG_VIDEO_ADV7170 is not set
+# CONFIG_VIDEO_ADV7175 is not set
+# CONFIG_VIDEO_THS7303 is not set
+# CONFIG_VIDEO_ADV7343 is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_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_VIDEO_CLASS_INPUT_EVDEV=y
+CONFIG_USB_GSPCA=m
+# CONFIG_USB_M5602 is not set
+# CONFIG_USB_STV06XX is not set
+# CONFIG_USB_GL860 is not set
+# CONFIG_USB_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_ETOMS is not set
+# CONFIG_USB_GSPCA_FINEPIX is not set
+# CONFIG_USB_GSPCA_JEILINJ is not set
+# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_MR97310A is not set
+# CONFIG_USB_GSPCA_OV519 is not set
+# CONFIG_USB_GSPCA_OV534 is not set
+# CONFIG_USB_GSPCA_PAC207 is not set
+# CONFIG_USB_GSPCA_PAC7302 is not set
+# CONFIG_USB_GSPCA_PAC7311 is not set
+# CONFIG_USB_GSPCA_SN9C20X is not set
+# CONFIG_USB_GSPCA_SONIXB is not set
+# 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_STV0680 is not set
+# CONFIG_USB_GSPCA_SUNPLUS is not set
+# CONFIG_USB_GSPCA_T613 is not set
+# CONFIG_USB_GSPCA_TV8532 is not set
+# 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_ET61X251 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_ZC0301 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_I2C_SI4713 is not set
+# CONFIG_RADIO_SI4713 is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_RADIO_SI470X is not set
+# CONFIG_USB_MR800 is not set
+# CONFIG_RADIO_TEA5764 is not set
+# CONFIG_RADIO_TEF6862 is not set
+# CONFIG_DAB is not set
+
+#
+# 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_OF is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_FSL_DIU=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 is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_LOGO is not set
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+# CONFIG_DRAGONRISE_FF is not set
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# 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_HID_GREENASIA=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_SMARTJOYPLUS=y
+# CONFIG_SMARTJOYPLUS_FF is not set
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+# CONFIG_THRUSTMASTER_FF is not set
+CONFIG_HID_ZEROPLUS=y
+# 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=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON 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=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_EHCI_BIG_ENDIAN_DESC=y
+# CONFIG_XPS_USB_HCD_XILINX is not set
+CONFIG_USB_EHCI_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_ISP1362_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_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_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# 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=y
+# CONFIG_RTC_DRV_M41T80_WDT is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_GENERIC is not set
+CONFIG_RTC_DRV_MPC5121=y
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+# CONFIG_FSL_DMA is not set
+CONFIG_MPC512X_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
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT2_FS_XIP=y
+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_FS_XIP=y
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# 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 is not set
+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 is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_IRQSTACKS is not set
+# CONFIG_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_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_PPC_CLOCK=y
+CONFIG_PPC_LIB_RHEAP=y
+# CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc5200_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc5200_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc5200_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc5200_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 15:08:52 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:38:54 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,30 +96,37 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
-# CONFIG_NAMESPACES is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
-# CONFIG_RD_BZIP2 is not set
-# CONFIG_RD_LZMA is not set
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 # 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_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_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -141,6 +148,7 @@ 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
@@ -320,6 +328,7 @@ CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_HIBERNATION is not set
 # CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
 
@@ -336,7 +345,6 @@ 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_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -363,7 +371,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -454,7 +461,9 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug
 # CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_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
@@ -554,6 +563,8 @@ CONFIG_MTD_UBI_BEB_RESERVE=1
 # UBI debugging options
 #
 # CONFIG_MTD_UBI_DEBUG is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -732,6 +743,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 CONFIG_PATA_MPC52xx=y
@@ -770,7 +782,7 @@ CONFIG_PATA_PLATFORM=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -929,6 +941,7 @@ CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -981,6 +994,7 @@ CONFIG_I2C_ALGOBIT=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1010,9 +1024,9 @@ CONFIG_SPI_MASTER=y
 #
 # SPI Master Controller Drivers
 #
-# CONFIG_SPI_BITBANG is not set
-# CONFIG_SPI_GPIO is not set
-# CONFIG_SPI_MPC52xx is not set
+CONFIG_SPI_BITBANG=m
+CONFIG_SPI_GPIO=m
+CONFIG_SPI_MPC52xx=m
 CONFIG_SPI_MPC52xx_PSC=m
 # CONFIG_SPI_XILINX is not set
 # CONFIG_SPI_DESIGNWARE is not set
@@ -1036,14 +1050,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1080,10 +1098,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1123,6 +1142,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1147,6 +1167,7 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
 # CONFIG_ALIM7101_WDT is not set
 # CONFIG_MPC5200_WDT is not set
 # CONFIG_WATCHDOG_RTAS is not set
@@ -1172,22 +1193,27 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1196,6 +1222,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 CONFIG_DRM=y
 # CONFIG_DRM_TDFX is not set
 # CONFIG_DRM_R128 is not set
@@ -1309,32 +1336,46 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
-# CONFIG_HID_APPLE is not set
+CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
 CONFIG_HID_CHERRY=y
-# CONFIG_HID_CHICONY is not set
+CONFIG_HID_CHICONY=y
 CONFIG_HID_CYPRESS=y
-# CONFIG_HID_DRAGONRISE is not set
+CONFIG_HID_DRAGONRISE=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_TWINHAN is not set
-# CONFIG_HID_KENSINGTON is not set
-# CONFIG_HID_LOGITECH is not set
-# CONFIG_HID_MICROSOFT is not set
-# CONFIG_HID_MONTEREY is not set
+CONFIG_HID_KYE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
+CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
-# CONFIG_HID_PANTHERLORD is not set
-# CONFIG_HID_PETALYNX is not set
-# CONFIG_HID_SAMSUNG is not set
-# CONFIG_HID_SONY is not set
-# CONFIG_HID_SUNPLUS is not set
-# CONFIG_HID_GREENASIA is not set
-# CONFIG_HID_SMARTJOYPLUS is not set
-# CONFIG_HID_TOPSEED is not set
-# CONFIG_HID_THRUSTMASTER is not set
-# CONFIG_HID_ZEROPLUS is not set
+CONFIG_HID_ORTEK=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_SMARTJOYPLUS=y
+# CONFIG_SMARTJOYPLUS_FF is not set
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+# CONFIG_THRUSTMASTER_FF is not set
+CONFIG_HID_ZEROPLUS=y
+# CONFIG_ZEROPLUS_FF is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1349,10 +1390,7 @@ CONFIG_USB=y
 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
@@ -1433,7 +1471,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1445,7 +1482,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1636,6 +1672,7 @@ CONFIG_UBIFS_FS=m
 CONFIG_UBIFS_FS_LZO=y
 CONFIG_UBIFS_FS_ZLIB=y
 # CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1730,8 +1767,11 @@ CONFIG_CRC32=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_LZO_COMPRESS=m
-CONFIG_LZO_DECOMPRESS=m
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
@@ -1776,11 +1816,11 @@ CONFIG_SCHED_DEBUG=y
 # 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_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_MEMORY_INIT=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc7448_hpc2_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc7448_hpc2_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc7448_hpc2_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc7448_hpc2_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:04 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:28 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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
@@ -109,6 +104,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -311,6 +307,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 # CONFIG_PPC_INDIRECT_PCI is not set
 CONFIG_PCI=y
@@ -319,7 +316,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -345,7 +341,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -440,6 +435,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -484,6 +481,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -605,6 +603,7 @@ CONFIG_SATA_MV=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -696,6 +695,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -750,6 +750,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -762,6 +764,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -846,6 +849,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -910,6 +914,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -918,6 +923,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1044,6 +1050,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1066,6 +1073,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc8272_ads_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc8272_ads_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc8272_ads_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc8272_ads_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:05 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:29 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,8 +96,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -301,6 +300,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
@@ -311,7 +311,6 @@ CONFIG_PCI_8260=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
@@ -338,7 +337,6 @@ 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
@@ -540,6 +538,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_MDIO=y
@@ -569,6 +569,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -674,6 +675,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -686,6 +689,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -797,6 +801,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -825,7 +830,9 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
@@ -864,6 +871,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -872,6 +881,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -933,6 +943,7 @@ CONFIG_AUTOFS4_FS=y
 #
 # Caches
 #
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc83xx_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc83xx_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc83xx_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc83xx_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:06 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:30 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -98,14 +98,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +107,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -126,7 +121,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -331,6 +326,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -344,7 +340,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -370,7 +365,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -560,6 +554,8 @@ CONFIG_MTD_NAND_FSL_ELBC=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -597,6 +593,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -614,6 +611,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -712,7 +710,7 @@ CONFIG_ATA_SFF=y
 # 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_SIL=y
 # CONFIG_SATA_SIS is not set
 # CONFIG_SATA_ULI is not set
 # CONFIG_SATA_VIA is not set
@@ -737,6 +735,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -863,6 +862,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -875,6 +876,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -970,6 +972,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -980,8 +983,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 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
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -1022,6 +1023,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1035,15 +1037,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1058,14 +1054,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1098,10 +1098,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1139,6 +1140,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1186,19 +1188,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1207,6 +1214,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1232,6 +1240,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1247,14 +1256,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1344,7 +1358,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # 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
@@ -1357,7 +1370,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
 
 #
@@ -1372,7 +1384,65 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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=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_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_GENERIC is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
@@ -1453,6 +1523,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1479,6 +1550,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc85xx_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc85xx_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc85xx_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc85xx_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:06 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:31 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -103,14 +107,8 @@ CONFIG_RCU_FANOUT=32
 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -118,6 +116,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -334,6 +333,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -345,7 +345,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 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
@@ -376,7 +375,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -509,6 +507,8 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -546,6 +546,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -563,6 +564,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -687,6 +689,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -817,8 +820,11 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_VXGE is not set
@@ -829,6 +835,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -941,6 +948,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_SERIAL_QE=m
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -993,6 +1001,7 @@ CONFIG_I2C_CPM=m
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1006,15 +1015,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1030,14 +1033,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1069,20 +1076,25 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_UCB1400_CORE is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1091,6 +1103,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1208,6 +1221,7 @@ CONFIG_SND_INTEL8X0=y
 CONFIG_SND_PPC=y
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
@@ -1227,6 +1241,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1242,14 +1257,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1358,7 +1378,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1371,7 +1390,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1452,6 +1470,7 @@ CONFIG_RTC_DRV_CMOS=y
 #
 # CONFIG_RTC_DRV_GENERIC is not set
 CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
 
 #
 # DMA Devices
@@ -1554,6 +1573,7 @@ CONFIG_BEFS_FS=m
 # CONFIG_BEFS_DEBUG is not set
 CONFIG_BFS_FS=m
 CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 CONFIG_VXFS_FS=m
@@ -1585,6 +1605,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1730,6 +1751,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc85xx_smp_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc85xx_smp_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc85xx_smp_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc85xx_smp_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:07 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:31 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -69,6 +69,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -100,18 +104,13 @@ CONFIG_TREE_RCU=y
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
 # CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -119,6 +118,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -338,6 +338,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -349,7 +350,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 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
@@ -380,7 +380,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -513,6 +512,8 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -550,6 +551,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -567,6 +569,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -691,6 +694,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -821,8 +825,11 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_VXGE is not set
@@ -833,6 +840,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -945,6 +953,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_SERIAL_QE=m
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -997,6 +1006,7 @@ CONFIG_I2C_CPM=m
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1010,15 +1020,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1034,14 +1038,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1073,20 +1081,25 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_UCB1400_CORE is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1095,6 +1108,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1212,6 +1226,7 @@ CONFIG_SND_INTEL8X0=y
 CONFIG_SND_PPC=y
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
@@ -1231,6 +1246,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1246,14 +1262,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1362,7 +1383,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1375,7 +1395,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1456,6 +1475,7 @@ CONFIG_RTC_DRV_CMOS=y
 #
 # CONFIG_RTC_DRV_GENERIC is not set
 CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
 
 #
 # DMA Devices
@@ -1558,6 +1578,7 @@ CONFIG_BEFS_FS=m
 # CONFIG_BEFS_DEBUG is not set
 CONFIG_BFS_FS=m
 CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 CONFIG_VXFS_FS=m
@@ -1589,6 +1610,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1734,6 +1756,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1806,6 +1829,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=y
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc866_ads_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc866_ads_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc866_ads_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc866_ads_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:08 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:32 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -89,14 +89,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -305,6 +299,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_FSL_SOC=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
@@ -333,7 +328,6 @@ 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
@@ -425,6 +419,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -456,6 +452,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -607,6 +604,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -795,6 +793,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -819,6 +818,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc86xx_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc86xx_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc86xx_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc86xx_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:09 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:33 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -98,18 +98,13 @@ CONFIG_TREE_RCU=y
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
 # CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -328,6 +324,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -339,7 +336,6 @@ 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
@@ -367,7 +363,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -500,6 +495,8 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -537,6 +534,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -554,6 +552,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -678,6 +677,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -802,6 +802,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -814,6 +816,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -923,6 +926,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -972,6 +976,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -985,15 +990,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1009,14 +1008,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1048,20 +1051,25 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_UCB1400_CORE is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1070,6 +1078,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1187,6 +1196,7 @@ CONFIG_SND_INTEL8X0=y
 CONFIG_SND_PPC=y
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
@@ -1206,6 +1216,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1221,14 +1232,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1336,7 +1352,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1349,7 +1364,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1512,6 +1526,7 @@ CONFIG_BEFS_FS=m
 # CONFIG_BEFS_DEBUG is not set
 CONFIG_BFS_FS=m
 CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 CONFIG_VXFS_FS=m
@@ -1543,6 +1558,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1754,6 +1770,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc885_ads_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc885_ads_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc885_ads_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/mpc885_ads_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:10 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:34 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -90,14 +90,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -313,6 +307,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_FSL_SOC=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
@@ -342,7 +337,6 @@ 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
@@ -515,6 +509,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -526,6 +522,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -627,6 +624,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -764,6 +762,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -788,6 +787,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/ppc64_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/ppc64_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/ppc64_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/ppc64_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -137,8 +137,9 @@ CONFIG_TRACEPOINTS=y
 CONFIG_MARKERS=y
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_KPROBES is not set
+CONFIG_KPROBES=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_KRETPROBES=y
 CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
@@ -191,6 +192,7 @@ CONFIG_SCANLOG=m
 CONFIG_LPARCFG=y
 CONFIG_PPC_SMLPAR=y
 CONFIG_CMM=y
+CONFIG_DTL=y
 CONFIG_PPC_ISERIES=y
 
 #
@@ -328,9 +330,10 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 CONFIG_KEXEC=y
 # CONFIG_PHYP_DUMP is not set
 CONFIG_IRQ_ALL_CPUS=y
-# CONFIG_NUMA is not set
+CONFIG_NUMA=y
+CONFIG_NODES_SHIFT=8
+CONFIG_MAX_ACTIVE_REGIONS=256
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -339,6 +342,7 @@ CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
 CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_SPARSEMEM=y
+CONFIG_NEED_MULTIPLE_NODES=y
 CONFIG_HAVE_MEMORY_PRESENT=y
 CONFIG_SPARSEMEM_EXTREME=y
 CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
@@ -354,11 +358,12 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_NODES_SPAN_OTHER_NODES=y
 CONFIG_ARCH_MEMORY_PROBE=y
 CONFIG_PPC_HAS_HASH_64K=y
 # CONFIG_PPC_64K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=13
-# CONFIG_SCHED_SMT is not set
+CONFIG_SCHED_SMT=y
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
 CONFIG_EXTRA_TARGETS=""
@@ -790,12 +795,12 @@ CONFIG_SCSI_IPR=y
 CONFIG_SCSI_IPR_TRACE=y
 CONFIG_SCSI_IPR_DUMP=y
 # CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_QLA_FC is not set
+CONFIG_SCSI_QLA_FC=m
 # CONFIG_SCSI_QLA_ISCSI is not set
 CONFIG_SCSI_LPFC=m
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
-CONFIG_SCSI_DEBUG=m
+# 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
@@ -867,9 +872,8 @@ CONFIG_MD_AUTODETECT=y
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
-CONFIG_MD_RAID10=y
-CONFIG_MD_RAID456=y
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
 CONFIG_MD_MULTIPATH=m
 CONFIG_MD_FAULTY=m
 CONFIG_BLK_DEV_DM=y
@@ -984,7 +988,7 @@ CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
-# CONFIG_E1000E is not set
+CONFIG_E1000E=m
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
 # CONFIG_NS83820 is not set
@@ -1000,25 +1004,24 @@ CONFIG_TIGON3=y
 CONFIG_SPIDER_NET=m
 CONFIG_GELIC_NET=m
 CONFIG_GELIC_WIRELESS=y
-# CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE 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 is not set
+CONFIG_CHELSIO_T1=m
+CONFIG_CHELSIO_T3=m
 CONFIG_EHEA=m
 # CONFIG_ENIC is not set
-# CONFIG_IXGBE is not set
+CONFIG_IXGBE=m
 CONFIG_IXGB=m
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-# CONFIG_NETXEN_NIC is not set
+CONFIG_S2IO=m
+CONFIG_MYRI10GE=m
+CONFIG_NETXEN_NIC=m
 # CONFIG_NIU is not set
 CONFIG_PASEMI_MAC=y
-# CONFIG_MLX4_EN is not set
-# CONFIG_MLX4_CORE is not set
+CONFIG_MLX4_EN=m
+CONFIG_MLX4_CORE=m
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
@@ -1169,7 +1172,7 @@ CONFIG_SERIAL_TXX9=y
 CONFIG_HAS_TXX9_SERIAL=y
 CONFIG_SERIAL_TXX9_NR_UARTS=6
 CONFIG_SERIAL_TXX9_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_JSM=m
 # CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
@@ -1586,7 +1589,7 @@ 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 is not set
+CONFIG_USB_MON=m
 # CONFIG_USB_WUSB is not set
 # CONFIG_USB_WUSB_CBAF is not set
 
@@ -1686,21 +1689,22 @@ CONFIG_USB_APPLEDISPLAY=m
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 CONFIG_INFINIBAND=m
-# CONFIG_INFINIBAND_USER_MAD is not set
-# CONFIG_INFINIBAND_USER_ACCESS is not set
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_USER_MEM=y
 CONFIG_INFINIBAND_ADDR_TRANS=y
 CONFIG_INFINIBAND_MTHCA=m
 CONFIG_INFINIBAND_MTHCA_DEBUG=y
-# CONFIG_INFINIBAND_IPATH is not set
+CONFIG_INFINIBAND_IPATH=m
 CONFIG_INFINIBAND_EHCA=m
 # CONFIG_INFINIBAND_AMSO1100 is not set
-# CONFIG_MLX4_INFINIBAND is not set
+CONFIG_MLX4_INFINIBAND=m
 # CONFIG_INFINIBAND_NES is not set
 CONFIG_INFINIBAND_IPOIB=m
-# CONFIG_INFINIBAND_IPOIB_CM is not set
+CONFIG_INFINIBAND_IPOIB_CM=y
 CONFIG_INFINIBAND_IPOIB_DEBUG=y
 # CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set
-# CONFIG_INFINIBAND_SRP is not set
+CONFIG_INFINIBAND_SRP=m
 CONFIG_INFINIBAND_ISER=m
 CONFIG_EDAC=y
 
@@ -1798,7 +1802,7 @@ CONFIG_REISERFS_FS=y
 CONFIG_REISERFS_FS_XATTR=y
 CONFIG_REISERFS_FS_POSIX_ACL=y
 CONFIG_REISERFS_FS_SECURITY=y
-CONFIG_JFS_FS=y
+CONFIG_JFS_FS=m
 CONFIG_JFS_POSIX_ACL=y
 CONFIG_JFS_SECURITY=y
 # CONFIG_JFS_DEBUG is not set
@@ -1811,14 +1815,22 @@ CONFIG_XFS_POSIX_ACL=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_DEBUG is not set
 # CONFIG_GFS2_FS is not set
-# CONFIG_OCFS2_FS is not set
+CONFIG_OCFS2_FS=m
+CONFIG_OCFS2_FS_O2CB=m
+CONFIG_OCFS2_FS_STATS=y
+CONFIG_OCFS2_DEBUG_MASKLOG=y
+# CONFIG_OCFS2_DEBUG_FS is not set
+# CONFIG_OCFS2_COMPAT_JBD is not set
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_NILFS2_FS=m
 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
+CONFIG_FUSE_FS=m
 
 #
 # CD-ROM/DVD Filesystems
@@ -1851,7 +1863,7 @@ CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -2075,7 +2087,7 @@ CONFIG_XMON=y
 CONFIG_XMON_DISASSEMBLY=y
 CONFIG_DEBUGGER=y
 CONFIG_IRQSTACKS=y
-# CONFIG_VIRQ_DEBUG is not set
+CONFIG_VIRQ_DEBUG=y
 CONFIG_BOOTX_TEXT=y
 # CONFIG_PPC_EARLY_DEBUG is not set
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/pq2fads_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/pq2fads_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/pq2fads_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/pq2fads_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:11 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:35 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -105,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -304,6 +305,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
@@ -315,7 +317,6 @@ CONFIG_PCI_8260=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
@@ -342,7 +343,6 @@ 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
@@ -544,6 +544,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_MDIO=y
@@ -629,6 +631,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -734,6 +737,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -746,6 +751,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -859,6 +865,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -887,7 +894,9 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
@@ -926,6 +935,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -934,6 +945,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -996,6 +1008,7 @@ CONFIG_USB_ETH_RNDIS=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -1051,6 +1064,7 @@ CONFIG_AUTOFS4_FS=y
 #
 # Caches
 #
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/prpmc2800_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/prpmc2800_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/prpmc2800_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/prpmc2800_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:12 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:36 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,11 +97,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED 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
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -319,6 +315,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_PCI=y
@@ -327,7 +324,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -354,7 +350,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -533,6 +528,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -569,6 +566,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -640,6 +638,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -761,6 +760,7 @@ CONFIG_SATA_MV=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -854,6 +854,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -907,6 +908,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -919,6 +922,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -1016,6 +1020,7 @@ CONFIG_SERIAL_MPSC_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1065,6 +1070,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MV64XXX=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1077,15 +1083,9 @@ CONFIG_I2C_MV64XXX=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1111,10 +1111,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1151,6 +1152,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1179,18 +1181,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1199,6 +1204,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1231,6 +1237,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1247,14 +1254,19 @@ CONFIG_HID_KENSINGTON=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 CONFIG_HID_NTRIG=y
+CONFIG_HID_ORTEK=y
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 CONFIG_HID_GREENASIA=y
 # CONFIG_GREENASIA_FF is not set
@@ -1350,7 +1362,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # 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
@@ -1363,7 +1374,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=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
 
 #
@@ -1516,6 +1526,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1538,6 +1549,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1620,9 +1632,11 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/ps3_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/ps3_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/ps3_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/ps3_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc7
-# Mon Aug 24 17:38:50 2009
+# Linux kernel version: 2.6.34-rc4
+# Thu Apr 15 11:32:15 2010
 #
 CONFIG_PPC64=y
 
@@ -9,6 +9,7 @@ CONFIG_PPC64=y
 # Processor support
 #
 CONFIG_PPC_BOOK3S_64=y
+# CONFIG_PPC_BOOK3E_64 is not set
 CONFIG_PPC_BOOK3S=y
 # CONFIG_POWER4_ONLY is not set
 CONFIG_POWER3=y
@@ -35,7 +36,9 @@ CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -60,6 +63,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -86,14 +90,15 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=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=17
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
@@ -108,6 +113,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -128,21 +134,19 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
+# CONFIG_PERF_EVENTS is not set
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
-CONFIG_MARKERS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
@@ -154,12 +158,14 @@ CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
 #
 # CONFIG_GCOV_KERNEL is not set
-# CONFIG_SLOW_WORK is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_SLOW_WORK_DEBUG is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -180,14 +186,41 @@ CONFIG_BLOCK_COMPAT=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -226,7 +259,6 @@ CONFIG_PPC_CELL=y
 #
 CONFIG_SPU_FS=m
 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
@@ -267,7 +299,6 @@ CONFIG_COMPAT_BINFMT_ELF=y
 # CONFIG_HAVE_AOUT is not set
 CONFIG_BINFMT_MISC=y
 CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
-# CONFIG_IOMMU_VMERGE is not set
 CONFIG_IOMMU_HELPER=y
 # CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
@@ -276,12 +307,15 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
 # CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_SPARSE_IRQ=y
 # CONFIG_NUMA is not set
+CONFIG_MAX_ACTIVE_REGIONS=256
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -295,13 +329,12 @@ CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTPLUG_SPARSE=y
 # CONFIG_MEMORY_HOTREMOVE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 CONFIG_MIGRATION=y
 CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ARCH_MEMORY_PROBE=y
 CONFIG_PPC_HAS_HASH_64K=y
@@ -312,11 +345,15 @@ CONFIG_PPC_4K_PAGES=y
 CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_SCHED_SMT=y
 CONFIG_PROC_DEVICETREE=y
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE=""
 CONFIG_EXTRA_TARGETS=""
 CONFIG_PM=y
 CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
 # CONFIG_PM_VERBOSE is not set
+# CONFIG_HIBERNATION is not set
+# CONFIG_PM_RUNTIME is not set
 # CONFIG_SECCOMP is not set
 CONFIG_ISA_DMA_API=y
 
@@ -324,6 +361,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_PCI_CHOICE=y
 # CONFIG_PCI is not set
@@ -337,12 +375,12 @@ CONFIG_PAGE_OFFSET=0xc000000000000000
 CONFIG_KERNEL_START=0xc000000000000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_NET=y
+CONFIG_COMPAT_NETLINK_MESSAGES=y
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -392,6 +430,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -400,6 +439,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -422,7 +462,6 @@ 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
@@ -445,27 +484,30 @@ CONFIG_BT_HCIBTUSB=m
 # CONFIG_BT_HCIBPA10X is not set
 # CONFIG_BT_HCIBFUSB is not set
 # CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_BT_ATH3K is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
 CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
 # CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
 # CONFIG_CFG80211_DEBUGFS is not set
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
 # CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_LIB80211 is not set
 CONFIG_MAC80211=m
-CONFIG_MAC80211_DEFAULT_PS=y
-CONFIG_MAC80211_DEFAULT_PS_VALUE=1
-
-#
-# 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
@@ -481,6 +523,7 @@ CONFIG_MAC80211_RC_DEFAULT="pid"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -491,6 +534,8 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
@@ -498,6 +543,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
@@ -521,6 +570,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -590,31 +640,27 @@ CONFIG_MII=m
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_NETDEV_1000=y
 CONFIG_GELIC_NET=y
 CONFIG_GELIC_WIRELESS=y
-# CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE 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_WLAN=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_AR9170_USB is not set
-# CONFIG_HOSTAP is not set
+# CONFIG_ATH_COMMON is not set
 # CONFIG_B43 is not set
 # CONFIG_B43LEGACY is not set
-# CONFIG_ZD1211RW is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_P54_COMMON is not set
 # CONFIG_RT2X00 is not set
+# CONFIG_WL12XX is not set
+# CONFIG_ZD1211RW is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -632,6 +678,7 @@ 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_SMSC75XX is not set
 # CONFIG_USB_NET_SMSC95XX is not set
 # CONFIG_USB_NET_GL620A is not set
 # CONFIG_USB_NET_NET1080 is not set
@@ -666,6 +713,7 @@ CONFIG_SLHC=m
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -713,6 +761,8 @@ CONFIG_DEVKMEM=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -736,7 +786,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -842,13 +891,13 @@ CONFIG_SND_PS3=m
 CONFIG_SND_PS3_DEFAULT_START_DELAY=2000
 CONFIG_SND_USB=y
 CONFIG_SND_USB_AUDIO=m
+# CONFIG_SND_USB_UA101 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_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 CONFIG_HIDRAW=y
 
 #
@@ -867,6 +916,7 @@ CONFIG_USB_HIDDEV=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 # CONFIG_HID_A4TECH is not set
 CONFIG_HID_APPLE=m
 CONFIG_HID_BELKIN=m
@@ -877,17 +927,24 @@ CONFIG_HID_CHERRY=m
 CONFIG_HID_EZKEY=m
 # CONFIG_HID_KYE is not set
 # CONFIG_HID_GYRATION is not set
+CONFIG_HID_TWINHAN=m
 # CONFIG_HID_KENSINGTON is not set
 CONFIG_HID_LOGITECH=m
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_HID_MAGICMOUSE is not set
 CONFIG_HID_MICROSOFT=m
+# CONFIG_HID_MOSART is not set
 # CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_QUANTA is not set
 # CONFIG_HID_SAMSUNG is not set
 CONFIG_HID_SONY=m
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=m
 # CONFIG_HID_GREENASIA is not set
 CONFIG_HID_SMARTJOYPLUS=m
@@ -902,7 +959,7 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=m
 # CONFIG_USB_DEBUG is not set
-# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 
 #
 # Miscellaneous USB options
@@ -910,7 +967,6 @@ CONFIG_USB=m
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
-CONFIG_USB_SUSPEND=y
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
@@ -924,12 +980,13 @@ CONFIG_USB_MON=m
 # 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_TT_NEWSCHED=y
 CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
 # 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_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=m
 # CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
 # CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
@@ -996,7 +1053,6 @@ CONFIG_USB_STORAGE=m
 # 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
@@ -1009,7 +1065,6 @@ CONFIG_USB_STORAGE=m
 # 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
 
 #
@@ -1049,7 +1104,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1078,10 +1135,10 @@ 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_EXT4_DEBUG is not set
 CONFIG_JBD=m
 # CONFIG_JBD_DEBUG is not set
 CONFIG_JBD2=y
@@ -1094,6 +1151,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
@@ -1155,6 +1213,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1165,7 +1224,6 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1182,6 +1240,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1238,7 +1297,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
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1271,6 +1330,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=2048
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1293,6 +1353,7 @@ CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_LOCK_ALLOC=y
 CONFIG_PROVE_LOCKING=y
+# CONFIG_PROVE_RCU is not set
 CONFIG_LOCKDEP=y
 # CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_LOCKDEP=y
@@ -1309,26 +1370,27 @@ CONFIG_DEBUG_MEMORY_INIT=y
 CONFIG_DEBUG_LIST=y
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM 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_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_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
-CONFIG_TRACING=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1353,13 +1415,16 @@ CONFIG_IRQSTACKS=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD=m
@@ -1375,6 +1440,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 CONFIG_CRYPTO_GF128MUL=m
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
@@ -1403,11 +1469,13 @@ CONFIG_CRYPTO_PCBC=m
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_GHASH=m
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/pseries_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/pseries_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/pseries_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/pseries_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -159,7 +159,7 @@ CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_BLK_DEV_IO_TRACE=y
 CONFIG_BLK_DEV_BSG=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 CONFIG_BLOCK_COMPAT=y
@@ -191,6 +191,7 @@ CONFIG_SCANLOG=m
 CONFIG_LPARCFG=y
 CONFIG_PPC_SMLPAR=y
 CONFIG_CMM=y
+CONFIG_DTL=y
 # CONFIG_PPC_ISERIES is not set
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_MAPLE is not set
@@ -255,7 +256,8 @@ CONFIG_KEXEC=y
 # CONFIG_PHYP_DUMP is not set
 CONFIG_IRQ_ALL_CPUS=y
 CONFIG_NUMA=y
-CONFIG_NODES_SHIFT=4
+CONFIG_NODES_SHIFT=8
+CONFIG_MAX_ACTIVE_REGIONS=256
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_DEFAULT=y
@@ -270,7 +272,9 @@ CONFIG_HAVE_MEMORY_PRESENT=y
 CONFIG_SPARSEMEM_EXTREME=y
 CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
 CONFIG_SPARSEMEM_VMEMMAP=y
-# CONFIG_MEMORY_HOTPLUG is not set
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTPLUG_SPARSE=y
+CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
@@ -705,7 +709,7 @@ CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 CONFIG_MD_RAID10=m
-# CONFIG_MD_RAID456 is not set
+CONFIG_MD_RAID456=m
 CONFIG_MD_MULTIPATH=m
 CONFIG_MD_FAULTY=m
 CONFIG_BLK_DEV_DM=y
@@ -800,7 +804,7 @@ CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
-# CONFIG_E1000E is not set
+CONFIG_E1000E=m
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
 # CONFIG_NS83820 is not set
@@ -818,18 +822,18 @@ CONFIG_TIGON3=y
 # CONFIG_ATL1E is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T1=m
+CONFIG_CHELSIO_T3=m
 CONFIG_EHEA=y
 # CONFIG_ENIC is not set
-# CONFIG_IXGBE is not set
+CONFIG_IXGBE=m
 CONFIG_IXGB=m
 CONFIG_S2IO=m
-# CONFIG_MYRI10GE is not set
-# CONFIG_NETXEN_NIC is not set
+CONFIG_MYRI10GE=m
+CONFIG_NETXEN_NIC=m
 # CONFIG_NIU is not set
-# CONFIG_MLX4_EN is not set
-# CONFIG_MLX4_CORE is not set
+CONFIG_MLX4_EN=m
+CONFIG_MLX4_CORE=m
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
@@ -894,7 +898,7 @@ CONFIG_INPUT_MOUSEDEV=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=m
 # CONFIG_INPUT_EVBUG is not set
 
 #
@@ -1271,7 +1275,7 @@ 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_MON=m
 # CONFIG_USB_WUSB is not set
 # CONFIG_USB_WUSB_CBAF is not set
 
@@ -1311,7 +1315,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 #
 # may also be needed; see USB_STORAGE Help for more information
 #
-CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
@@ -1322,7 +1326,7 @@ CONFIG_USB_STORAGE=y
 # 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 is not set
 # CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
 # CONFIG_USB_LIBUSUAL is not set
@@ -1377,17 +1381,17 @@ CONFIG_INFINIBAND_USER_MEM=y
 CONFIG_INFINIBAND_ADDR_TRANS=y
 CONFIG_INFINIBAND_MTHCA=m
 CONFIG_INFINIBAND_MTHCA_DEBUG=y
-# CONFIG_INFINIBAND_IPATH is not set
+CONFIG_INFINIBAND_IPATH=m
 CONFIG_INFINIBAND_EHCA=m
 # CONFIG_INFINIBAND_AMSO1100 is not set
-# CONFIG_MLX4_INFINIBAND is not set
+CONFIG_MLX4_INFINIBAND=m
 # CONFIG_INFINIBAND_NES is not set
 CONFIG_INFINIBAND_IPOIB=m
-# CONFIG_INFINIBAND_IPOIB_CM is not set
+CONFIG_INFINIBAND_IPOIB_CM=y
 CONFIG_INFINIBAND_IPOIB_DEBUG=y
 # CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set
 CONFIG_INFINIBAND_SRP=m
-# CONFIG_INFINIBAND_ISER is not set
+CONFIG_INFINIBAND_ISER=m
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
@@ -1443,6 +1447,9 @@ CONFIG_OCFS2_FS_STATS=y
 CONFIG_OCFS2_DEBUG_MASKLOG=y
 # CONFIG_OCFS2_DEBUG_FS is not set
 # CONFIG_OCFS2_COMPAT_JBD is not set
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_NILFS2_FS=m
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1455,8 +1462,8 @@ CONFIG_FUSE_FS=m
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 CONFIG_UDF_FS=m
 CONFIG_UDF_NLS=y
 
@@ -1508,14 +1515,14 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
-CONFIG_NFSD=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=y
+CONFIG_EXPORTFS=m
 CONFIG_NFS_ACL_SUPPORT=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
@@ -1681,12 +1688,12 @@ CONFIG_DYNAMIC_PRINTK_DEBUG=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 CONFIG_DEBUG_STACKOVERFLOW=y
-# CONFIG_DEBUG_STACK_USAGE is not set
+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=y
 CONFIG_XMON_DISASSEMBLY=y
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/configs/storcenter_defconfig linux-libre-2.6.34-gnu1/arch/powerpc/configs/storcenter_defconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/configs/storcenter_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/configs/storcenter_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:13 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:37 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -314,6 +309,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -323,7 +319,6 @@ 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_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -349,7 +344,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=m
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -524,6 +518,8 @@ CONFIG_MTD_PHYSMAP=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
@@ -555,6 +551,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -626,6 +623,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -846,6 +844,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -895,6 +894,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -908,15 +908,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -941,18 +935,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -961,6 +958,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1071,7 +1069,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1084,7 +1081,6 @@ CONFIG_USB_STORAGE=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
 
 #
@@ -1251,6 +1247,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/asm-compat.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/asm-compat.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/asm-compat.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/asm-compat.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
 #define _ASM_POWERPC_ASM_COMPAT_H
 
 #include <asm/types.h>
+#include <asm/ppc-opcode.h>
 
 #ifdef __ASSEMBLY__
 #  define stringify_in_c(...)	__VA_ARGS__
@@ -24,9 +25,10 @@
 #define PPC_LONG	stringify_in_c(.llong)
 #define PPC_LONG_ALIGN	stringify_in_c(.balign 8)
 #define PPC_TLNEI	stringify_in_c(tdnei)
-#define PPC_LLARX	stringify_in_c(ldarx)
+#define PPC_LLARX(t, a, b, eh)	PPC_LDARX(t, a, b, eh)
 #define PPC_STLCX	stringify_in_c(stdcx.)
 #define PPC_CNTLZL	stringify_in_c(cntlzd)
+#define PPC_LR_STKOFF	16
 
 /* Move to CR, single-entry optimized version. Only available
  * on POWER4 and later.
@@ -46,10 +48,11 @@
 #define PPC_LONG	stringify_in_c(.long)
 #define PPC_LONG_ALIGN	stringify_in_c(.balign 4)
 #define PPC_TLNEI	stringify_in_c(twnei)
-#define PPC_LLARX	stringify_in_c(lwarx)
+#define PPC_LLARX(t, a, b, eh)	PPC_LWARX(t, a, b, eh)
 #define PPC_STLCX	stringify_in_c(stwcx.)
 #define PPC_CNTLZL	stringify_in_c(cntlzw)
 #define PPC_MTOCRF	stringify_in_c(mtcrf)
+#define PPC_LR_STKOFF	4
 
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/atomic.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/atomic.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/atomic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/atomic.h	2010-05-16 17:17:36.000000000 -0400
@@ -49,13 +49,13 @@ static __inline__ int atomic_add_return(
 	int t;
 
 	__asm__ __volatile__(
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	lwarx	%0,0,%2		# atomic_add_return\n\
 	add	%0,%1,%0\n"
 	PPC405_ERR77(0,%2)
 "	stwcx.	%0,0,%2 \n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	: "=&r" (t)
 	: "r" (a), "r" (&v->counter)
 	: "cc", "memory");
@@ -85,13 +85,13 @@ static __inline__ int atomic_sub_return(
 	int t;
 
 	__asm__ __volatile__(
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	lwarx	%0,0,%2		# atomic_sub_return\n\
 	subf	%0,%1,%0\n"
 	PPC405_ERR77(0,%2)
 "	stwcx.	%0,0,%2 \n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	: "=&r" (t)
 	: "r" (a), "r" (&v->counter)
 	: "cc", "memory");
@@ -119,13 +119,13 @@ static __inline__ int atomic_inc_return(
 	int t;
 
 	__asm__ __volatile__(
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	lwarx	%0,0,%1		# atomic_inc_return\n\
 	addic	%0,%0,1\n"
 	PPC405_ERR77(0,%1)
 "	stwcx.	%0,0,%1 \n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	: "=&r" (t)
 	: "r" (&v->counter)
 	: "cc", "xer", "memory");
@@ -163,13 +163,13 @@ static __inline__ int atomic_dec_return(
 	int t;
 
 	__asm__ __volatile__(
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	lwarx	%0,0,%1		# atomic_dec_return\n\
 	addic	%0,%0,-1\n"
 	PPC405_ERR77(0,%1)
 "	stwcx.	%0,0,%1\n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	: "=&r" (t)
 	: "r" (&v->counter)
 	: "cc", "xer", "memory");
@@ -194,7 +194,7 @@ static __inline__ int atomic_add_unless(
 	int t;
 
 	__asm__ __volatile__ (
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	lwarx	%0,0,%1		# atomic_add_unless\n\
 	cmpw	0,%0,%3 \n\
 	beq-	2f \n\
@@ -202,7 +202,7 @@ static __inline__ int atomic_add_unless(
 	PPC405_ERR77(0,%2)
 "	stwcx.	%0,0,%1 \n\
 	bne-	1b \n"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 "	subf	%0,%2,%0 \n\
 2:"
 	: "=&r" (t)
@@ -227,7 +227,7 @@ static __inline__ int atomic_dec_if_posi
 	int t;
 
 	__asm__ __volatile__(
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	lwarx	%0,0,%1		# atomic_dec_if_positive\n\
 	cmpwi	%0,1\n\
 	addi	%0,%0,-1\n\
@@ -235,7 +235,7 @@ static __inline__ int atomic_dec_if_posi
 	PPC405_ERR77(0,%1)
 "	stwcx.	%0,0,%1\n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	"\n\
 2:"	: "=&b" (t)
 	: "r" (&v->counter)
@@ -286,12 +286,12 @@ static __inline__ long atomic64_add_retu
 	long t;
 
 	__asm__ __volatile__(
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	ldarx	%0,0,%2		# atomic64_add_return\n\
 	add	%0,%1,%0\n\
 	stdcx.	%0,0,%2 \n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	: "=&r" (t)
 	: "r" (a), "r" (&v->counter)
 	: "cc", "memory");
@@ -320,12 +320,12 @@ static __inline__ long atomic64_sub_retu
 	long t;
 
 	__asm__ __volatile__(
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	ldarx	%0,0,%2		# atomic64_sub_return\n\
 	subf	%0,%1,%0\n\
 	stdcx.	%0,0,%2 \n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	: "=&r" (t)
 	: "r" (a), "r" (&v->counter)
 	: "cc", "memory");
@@ -352,12 +352,12 @@ static __inline__ long atomic64_inc_retu
 	long t;
 
 	__asm__ __volatile__(
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	ldarx	%0,0,%1		# atomic64_inc_return\n\
 	addic	%0,%0,1\n\
 	stdcx.	%0,0,%1 \n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	: "=&r" (t)
 	: "r" (&v->counter)
 	: "cc", "xer", "memory");
@@ -394,12 +394,12 @@ static __inline__ long atomic64_dec_retu
 	long t;
 
 	__asm__ __volatile__(
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	ldarx	%0,0,%1		# atomic64_dec_return\n\
 	addic	%0,%0,-1\n\
 	stdcx.	%0,0,%1\n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	: "=&r" (t)
 	: "r" (&v->counter)
 	: "cc", "xer", "memory");
@@ -419,13 +419,13 @@ static __inline__ long atomic64_dec_if_p
 	long t;
 
 	__asm__ __volatile__(
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	ldarx	%0,0,%1		# atomic64_dec_if_positive\n\
 	addic.	%0,%0,-1\n\
 	blt-	2f\n\
 	stdcx.	%0,0,%1\n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	"\n\
 2:"	: "=&r" (t)
 	: "r" (&v->counter)
@@ -451,14 +451,14 @@ static __inline__ int atomic64_add_unles
 	long t;
 
 	__asm__ __volatile__ (
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	ldarx	%0,0,%1		# atomic_add_unless\n\
 	cmpd	0,%0,%3 \n\
 	beq-	2f \n\
 	add	%0,%2,%0 \n"
 "	stdcx.	%0,0,%1 \n\
 	bne-	1b \n"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 "	subf	%0,%2,%0 \n\
 2:"
 	: "=&r" (t)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/bitops.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/bitops.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/bitops.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/bitops.h	2010-05-16 17:17:36.000000000 -0400
@@ -65,7 +65,7 @@ static __inline__ void fn(unsigned long
 	unsigned long *p = (unsigned long *)_p;	\
 	__asm__ __volatile__ (			\
 	prefix					\
-"1:"	PPC_LLARX "%0,0,%3\n"			\
+"1:"	PPC_LLARX(%0,0,%3,0) "\n"		\
 	stringify_in_c(op) "%0,%0,%2\n"		\
 	PPC405_ERR77(0,%3)			\
 	PPC_STLCX "%0,0,%3\n"			\
@@ -78,7 +78,7 @@ static __inline__ void fn(unsigned long
 
 DEFINE_BITOP(set_bits, or, "", "")
 DEFINE_BITOP(clear_bits, andc, "", "")
-DEFINE_BITOP(clear_bits_unlock, andc, LWSYNC_ON_SMP, "")
+DEFINE_BITOP(clear_bits_unlock, andc, PPC_RELEASE_BARRIER, "")
 DEFINE_BITOP(change_bits, xor, "", "")
 
 static __inline__ void set_bit(int nr, volatile unsigned long *addr)
@@ -103,31 +103,35 @@ static __inline__ void change_bit(int nr
 
 /* Like DEFINE_BITOP(), with changes to the arguments to 'op' and the output
  * operands. */
-#define DEFINE_TESTOP(fn, op, prefix, postfix)	\
-static __inline__ unsigned long fn(		\
-		unsigned long mask,		\
-		volatile unsigned long *_p)	\
-{						\
-	unsigned long old, t;			\
-	unsigned long *p = (unsigned long *)_p;	\
-	__asm__ __volatile__ (			\
-	prefix					\
-"1:"	PPC_LLARX "%0,0,%3\n"			\
-	stringify_in_c(op) "%1,%0,%2\n"		\
-	PPC405_ERR77(0,%3)			\
-	PPC_STLCX "%1,0,%3\n"			\
-	"bne- 1b\n"				\
-	postfix					\
-	: "=&r" (old), "=&r" (t)		\
-	: "r" (mask), "r" (p)			\
-	: "cc", "memory");			\
-	return (old & mask);			\
+#define DEFINE_TESTOP(fn, op, prefix, postfix, eh)	\
+static __inline__ unsigned long fn(			\
+		unsigned long mask,			\
+		volatile unsigned long *_p)		\
+{							\
+	unsigned long old, t;				\
+	unsigned long *p = (unsigned long *)_p;		\
+	__asm__ __volatile__ (				\
+	prefix						\
+"1:"	PPC_LLARX(%0,0,%3,eh) "\n"			\
+	stringify_in_c(op) "%1,%0,%2\n"			\
+	PPC405_ERR77(0,%3)				\
+	PPC_STLCX "%1,0,%3\n"				\
+	"bne- 1b\n"					\
+	postfix						\
+	: "=&r" (old), "=&r" (t)			\
+	: "r" (mask), "r" (p)				\
+	: "cc", "memory");				\
+	return (old & mask);				\
 }
 
-DEFINE_TESTOP(test_and_set_bits, or, LWSYNC_ON_SMP, ISYNC_ON_SMP)
-DEFINE_TESTOP(test_and_set_bits_lock, or, "", ISYNC_ON_SMP)
-DEFINE_TESTOP(test_and_clear_bits, andc, LWSYNC_ON_SMP, ISYNC_ON_SMP)
-DEFINE_TESTOP(test_and_change_bits, xor, LWSYNC_ON_SMP, ISYNC_ON_SMP)
+DEFINE_TESTOP(test_and_set_bits, or, PPC_RELEASE_BARRIER,
+	      PPC_ACQUIRE_BARRIER, 0)
+DEFINE_TESTOP(test_and_set_bits_lock, or, "",
+	      PPC_ACQUIRE_BARRIER, 1)
+DEFINE_TESTOP(test_and_clear_bits, andc, PPC_RELEASE_BARRIER,
+	      PPC_ACQUIRE_BARRIER, 0)
+DEFINE_TESTOP(test_and_change_bits, xor, PPC_RELEASE_BARRIER,
+	      PPC_ACQUIRE_BARRIER, 0)
 
 static __inline__ int test_and_set_bit(unsigned long nr,
 				       volatile unsigned long *addr)
@@ -158,7 +162,7 @@ static __inline__ int test_and_change_bi
 
 static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr)
 {
-	__asm__ __volatile__(LWSYNC_ON_SMP "" ::: "memory");
+	__asm__ __volatile__(PPC_RELEASE_BARRIER "" ::: "memory");
 	__clear_bit(nr, addr);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/compat.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/compat.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/compat.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/compat.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,8 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 
-#define COMPAT_USER_HZ	100
+#define COMPAT_USER_HZ		100
+#define COMPAT_UTS_MACHINE	"ppc\0\0"
 
 typedef u32		compat_size_t;
 typedef s32		compat_ssize_t;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/cputable.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/cputable.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/cputable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/cputable.h	2010-05-16 17:17:36.000000000 -0400
@@ -381,9 +381,9 @@ extern const char *powerpc_base_platform
 #define CPU_FTRS_GENERIC_32	(CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
 
 /* 64-bit CPUs */
-#define CPU_FTRS_POWER3	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
+#define CPU_FTRS_POWER3	(CPU_FTR_USE_TB | \
 	    CPU_FTR_IABR | CPU_FTR_PPC_LE)
-#define CPU_FTRS_RS64	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
+#define CPU_FTRS_RS64	(CPU_FTR_USE_TB | \
 	    CPU_FTR_IABR | \
 	    CPU_FTR_MMCRA | CPU_FTR_CTRL)
 #define CPU_FTRS_POWER4	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/cputime.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/cputime.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/cputime.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/cputime.h	2010-05-16 17:17:36.000000000 -0400
@@ -73,10 +73,9 @@ static inline unsigned long cputime_to_j
 static inline cputime_t cputime_to_scaled(const cputime_t ct)
 {
 	if (cpu_has_feature(CPU_FTR_SPURR) &&
-	    per_cpu(cputime_last_delta, smp_processor_id()))
-		return ct *
-			per_cpu(cputime_scaled_last_delta, smp_processor_id())/
-			per_cpu(cputime_last_delta, smp_processor_id());
+	    __get_cpu_var(cputime_last_delta))
+		return ct * __get_cpu_var(cputime_scaled_last_delta) /
+			    __get_cpu_var(cputime_last_delta);
 	return ct;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/dma-mapping.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/dma-mapping.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/dma-mapping.h	2010-05-16 17:17:36.000000000 -0400
@@ -127,9 +127,6 @@ static inline int dma_supported(struct d
 	return dma_ops->dma_supported(dev, mask);
 }
 
-/* We have our own implementation of pci_set_dma_mask() */
-#define HAVE_ARCH_PCI_SET_DMA_MASK
-
 static inline int dma_set_mask(struct device *dev, u64 dma_mask)
 {
 	struct dma_map_ops *dma_ops = get_dma_ops(dev);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/feature-fixups.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/feature-fixups.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/feature-fixups.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/feature-fixups.h	2010-05-16 17:17:36.000000000 -0400
@@ -165,7 +165,7 @@ label##2:						\
 	.pushsection sect,"a";				\
 	.align 2;					\
 label##3:					       	\
-	.long label##1b-label##3b;			\
+	FTR_ENTRY_OFFSET label##1b-label##3b;		\
 	.popsection;
 
 #endif /* __ASM_POWERPC_FEATURE_FIXUPS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/futex.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/futex.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/futex.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/futex.h	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
 
 #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
   __asm__ __volatile ( \
-	LWSYNC_ON_SMP \
+	PPC_RELEASE_BARRIER \
 "1:	lwarx	%0,0,%2\n" \
 	insn \
 	PPC405_ERR77(0, %2) \
@@ -90,14 +90,14 @@ futex_atomic_cmpxchg_inatomic(int __user
 		return -EFAULT;
 
         __asm__ __volatile__ (
-        LWSYNC_ON_SMP
+        PPC_RELEASE_BARRIER
 "1:     lwarx   %0,0,%2         # futex_atomic_cmpxchg_inatomic\n\
         cmpw    0,%0,%3\n\
         bne-    3f\n"
         PPC405_ERR77(0,%2)
 "2:     stwcx.  %4,0,%2\n\
         bne-    1b\n"
-        ISYNC_ON_SMP
+        PPC_ACQUIRE_BARRIER
 "3:	.section .fixup,\"ax\"\n\
 4:	li	%0,%5\n\
 	b	3b\n\
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/hardirq.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/hardirq.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/hardirq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/hardirq.h	2010-05-16 17:17:36.000000000 -0400
@@ -1 +1,29 @@
-#include <asm-generic/hardirq.h>
+#ifndef _ASM_POWERPC_HARDIRQ_H
+#define _ASM_POWERPC_HARDIRQ_H
+
+#include <linux/threads.h>
+#include <linux/irq.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int timer_irqs;
+	unsigned int pmu_irqs;
+	unsigned int mce_exceptions;
+	unsigned int spurious_irqs;
+} ____cacheline_aligned irq_cpustat_t;
+
+DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+
+#define __ARCH_IRQ_STAT
+
+#define local_softirq_pending()	__get_cpu_var(irq_stat).__softirq_pending
+
+static inline void ack_bad_irq(unsigned int irq)
+{
+	printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
+}
+
+extern u64 arch_irq_stat_cpu(unsigned int cpu);
+#define arch_irq_stat_cpu	arch_irq_stat_cpu
+
+#endif /* _ASM_POWERPC_HARDIRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/hw_irq.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/hw_irq.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/hw_irq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/hw_irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -130,43 +130,5 @@ static inline int irqs_disabled_flags(un
  */
 struct irq_chip;
 
-#ifdef CONFIG_PERF_EVENTS
-
-#ifdef CONFIG_PPC64
-static inline unsigned long test_perf_event_pending(void)
-{
-	unsigned long x;
-
-	asm volatile("lbz %0,%1(13)"
-		: "=r" (x)
-		: "i" (offsetof(struct paca_struct, perf_event_pending)));
-	return x;
-}
-
-static inline void set_perf_event_pending(void)
-{
-	asm volatile("stb %0,%1(13)" : :
-		"r" (1),
-		"i" (offsetof(struct paca_struct, perf_event_pending)));
-}
-
-static inline void clear_perf_event_pending(void)
-{
-	asm volatile("stb %0,%1(13)" : :
-		"r" (0),
-		"i" (offsetof(struct paca_struct, perf_event_pending)));
-}
-#endif /* CONFIG_PPC64 */
-
-#else  /* CONFIG_PERF_EVENTS */
-
-static inline unsigned long test_perf_event_pending(void)
-{
-	return 0;
-}
-
-static inline void clear_perf_event_pending(void) {}
-#endif /* CONFIG_PERF_EVENTS */
-
 #endif	/* __KERNEL__ */
 #endif	/* _ASM_POWERPC_HW_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_asm.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/kvm_asm.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_asm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/kvm_asm.h	2010-05-16 17:17:36.000000000 -0400
@@ -97,4 +97,10 @@
 #define RESUME_HOST             RESUME_FLAG_HOST
 #define RESUME_HOST_NV          (RESUME_FLAG_HOST|RESUME_FLAG_NV)
 
+#define KVM_GUEST_MODE_NONE	0
+#define KVM_GUEST_MODE_GUEST	1
+#define KVM_GUEST_MODE_SKIP	2
+
+#define KVM_INST_FETCH_FAILED	-1
+
 #endif /* __POWERPC_KVM_ASM_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_book3s_64_asm.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/kvm_book3s_64_asm.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_book3s_64_asm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/kvm_book3s_64_asm.h	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,8 @@
 #ifndef __ASM_KVM_BOOK3S_ASM_H__
 #define __ASM_KVM_BOOK3S_ASM_H__
 
+#ifdef __ASSEMBLY__
+
 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
 
 #include <asm/kvm_asm.h>
@@ -55,4 +57,20 @@ kvmppc_resume_\intno:
 
 #endif /* CONFIG_KVM_BOOK3S_64_HANDLER */
 
+#else  /*__ASSEMBLY__ */
+
+struct kvmppc_book3s_shadow_vcpu {
+	ulong gpr[14];
+	u32 cr;
+	u32 xer;
+	ulong host_r1;
+	ulong host_r2;
+	ulong handler;
+	ulong scratch0;
+	ulong scratch1;
+	ulong vmhandler;
+};
+
+#endif /*__ASSEMBLY__ */
+
 #endif /* __ASM_KVM_BOOK3S_ASM_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_book3s.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/kvm_book3s.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_book3s.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/kvm_book3s.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,7 @@
 
 #include <linux/types.h>
 #include <linux/kvm_host.h>
-#include <asm/kvm_ppc.h>
+#include <asm/kvm_book3s_64_asm.h>
 
 struct kvmppc_slb {
 	u64 esid;
@@ -33,7 +33,8 @@ struct kvmppc_slb {
 	bool Ks;
 	bool Kp;
 	bool nx;
-	bool large;
+	bool large;	/* PTEs are 16MB */
+	bool tb;	/* 1TB segment */
 	bool class;
 };
 
@@ -69,6 +70,7 @@ struct kvmppc_sid_map {
 
 struct kvmppc_vcpu_book3s {
 	struct kvm_vcpu vcpu;
+	struct kvmppc_book3s_shadow_vcpu shadow_vcpu;
 	struct kvmppc_sid_map sid_map[SID_MAP_NUM];
 	struct kvmppc_slb slb[64];
 	struct {
@@ -89,6 +91,7 @@ struct kvmppc_vcpu_book3s {
 	u64 vsid_next;
 	u64 vsid_max;
 	int context_id;
+	ulong prog_flags; /* flags to inject when giving a 700 trap */
 };
 
 #define CONTEXT_HOST		0
@@ -119,6 +122,10 @@ extern void kvmppc_set_bat(struct kvm_vc
 
 extern u32 kvmppc_trampoline_lowmem;
 extern u32 kvmppc_trampoline_enter;
+extern void kvmppc_rmcall(ulong srr0, ulong srr1);
+extern void kvmppc_load_up_fpu(void);
+extern void kvmppc_load_up_altivec(void);
+extern void kvmppc_load_up_vsx(void);
 
 static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_e500.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/kvm_e500.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_e500.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/kvm_e500.h	2010-05-16 17:17:36.000000000 -0400
@@ -52,9 +52,12 @@ struct kvmppc_vcpu_e500 {
 	u32 mas5;
 	u32 mas6;
 	u32 mas7;
+	u32 l1csr0;
 	u32 l1csr1;
 	u32 hid0;
 	u32 hid1;
+	u32 tlb0cfg;
+	u32 tlb1cfg;
 
 	struct kvm_vcpu vcpu;
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_host.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/kvm_host.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_host.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/kvm_host.h	2010-05-16 17:17:36.000000000 -0400
@@ -167,23 +167,40 @@ struct kvm_vcpu_arch {
 	ulong trampoline_lowmem;
 	ulong trampoline_enter;
 	ulong highmem_handler;
+	ulong rmcall;
 	ulong host_paca_phys;
 	struct kvmppc_mmu mmu;
 #endif
 
-	u64 fpr[32];
 	ulong gpr[32];
 
+	u64 fpr[32];
+	u32 fpscr;
+
+#ifdef CONFIG_ALTIVEC
+	vector128 vr[32];
+	vector128 vscr;
+#endif
+
+#ifdef CONFIG_VSX
+	u64 vsr[32];
+#endif
+
 	ulong pc;
-	u32 cr;
 	ulong ctr;
 	ulong lr;
+
+#ifdef CONFIG_BOOKE
 	ulong xer;
+	u32 cr;
+#endif
 
 	ulong msr;
 #ifdef CONFIG_PPC64
 	ulong shadow_msr;
+	ulong shadow_srr1;
 	ulong hflags;
+	ulong guest_owned_ext;
 #endif
 	u32 mmucr;
 	ulong sprg0;
@@ -242,6 +259,8 @@ struct kvm_vcpu_arch {
 #endif
 	ulong fault_dear;
 	ulong fault_esr;
+	ulong queued_dear;
+	ulong queued_esr;
 	gpa_t paddr_accessed;
 
 	u8 io_gpr; /* GPR used as IO source/target */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_ppc.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/kvm_ppc.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_ppc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/kvm_ppc.h	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,9 @@
 #include <linux/types.h>
 #include <linux/kvm_types.h>
 #include <linux/kvm_host.h>
+#ifdef CONFIG_PPC_BOOK3S
+#include <asm/kvm_book3s.h>
+#endif
 
 enum emulation_result {
 	EMULATE_DONE,         /* no further processing */
@@ -80,8 +83,9 @@ extern void kvmppc_core_vcpu_put(struct
 
 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);
+extern void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags);
 extern void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu);
+extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu);
 extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
                                        struct kvm_interrupt *irq);
 
@@ -95,4 +99,81 @@ extern void kvmppc_booke_exit(void);
 
 extern void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu);
 
+#ifdef CONFIG_PPC_BOOK3S
+
+/* We assume we're always acting on the current vcpu */
+
+static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val)
+{
+	if ( num < 14 ) {
+		get_paca()->shadow_vcpu.gpr[num] = val;
+		to_book3s(vcpu)->shadow_vcpu.gpr[num] = val;
+	} else
+		vcpu->arch.gpr[num] = val;
+}
+
+static inline ulong kvmppc_get_gpr(struct kvm_vcpu *vcpu, int num)
+{
+	if ( num < 14 )
+		return get_paca()->shadow_vcpu.gpr[num];
+	else
+		return vcpu->arch.gpr[num];
+}
+
+static inline void kvmppc_set_cr(struct kvm_vcpu *vcpu, u32 val)
+{
+	get_paca()->shadow_vcpu.cr = val;
+	to_book3s(vcpu)->shadow_vcpu.cr = val;
+}
+
+static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu)
+{
+	return get_paca()->shadow_vcpu.cr;
+}
+
+static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val)
+{
+	get_paca()->shadow_vcpu.xer = val;
+	to_book3s(vcpu)->shadow_vcpu.xer = val;
+}
+
+static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu)
+{
+	return get_paca()->shadow_vcpu.xer;
+}
+
+#else
+
+static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val)
+{
+	vcpu->arch.gpr[num] = val;
+}
+
+static inline ulong kvmppc_get_gpr(struct kvm_vcpu *vcpu, int num)
+{
+	return vcpu->arch.gpr[num];
+}
+
+static inline void kvmppc_set_cr(struct kvm_vcpu *vcpu, u32 val)
+{
+	vcpu->arch.cr = val;
+}
+
+static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.cr;
+}
+
+static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val)
+{
+	vcpu->arch.xer = val;
+}
+
+static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.xer;
+}
+
+#endif
+
 #endif /* __POWERPC_KVM_PPC_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/local.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/local.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/local.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/local.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,7 @@ static __inline__ long local_add_return(
 	long t;
 
 	__asm__ __volatile__(
-"1:"	PPC_LLARX	"%0,0,%2		# local_add_return\n\
+"1:"	PPC_LLARX(%0,0,%2,0) "			# local_add_return\n\
 	add	%0,%1,%0\n"
 	PPC405_ERR77(0,%2)
 	PPC_STLCX	"%0,0,%2 \n\
@@ -43,7 +43,7 @@ static __inline__ long local_sub_return(
 	long t;
 
 	__asm__ __volatile__(
-"1:"	PPC_LLARX	"%0,0,%2		# local_sub_return\n\
+"1:"	PPC_LLARX(%0,0,%2,0) "			# local_sub_return\n\
 	subf	%0,%1,%0\n"
 	PPC405_ERR77(0,%2)
 	PPC_STLCX	"%0,0,%2 \n\
@@ -60,7 +60,7 @@ static __inline__ long local_inc_return(
 	long t;
 
 	__asm__ __volatile__(
-"1:"	PPC_LLARX	"%0,0,%1		# local_inc_return\n\
+"1:"	PPC_LLARX(%0,0,%1,0) "			# local_inc_return\n\
 	addic	%0,%0,1\n"
 	PPC405_ERR77(0,%1)
 	PPC_STLCX	"%0,0,%1 \n\
@@ -87,7 +87,7 @@ static __inline__ long local_dec_return(
 	long t;
 
 	__asm__ __volatile__(
-"1:"	PPC_LLARX	"%0,0,%1		# local_dec_return\n\
+"1:"	PPC_LLARX(%0,0,%1,0) "			# local_dec_return\n\
 	addic	%0,%0,-1\n"
 	PPC405_ERR77(0,%1)
 	PPC_STLCX	"%0,0,%1\n\
@@ -117,7 +117,7 @@ static __inline__ int local_add_unless(l
 	long t;
 
 	__asm__ __volatile__ (
-"1:"	PPC_LLARX	"%0,0,%1		# local_add_unless\n\
+"1:"	PPC_LLARX(%0,0,%1,0) "			# local_add_unless\n\
 	cmpw	0,%0,%3 \n\
 	beq-	2f \n\
 	add	%0,%2,%0 \n"
@@ -147,7 +147,7 @@ static __inline__ long local_dec_if_posi
 	long t;
 
 	__asm__ __volatile__(
-"1:"	PPC_LLARX	"%0,0,%1		# local_dec_if_positive\n\
+"1:"	PPC_LLARX(%0,0,%1,0) "			# local_dec_if_positive\n\
 	cmpwi	%0,1\n\
 	addi	%0,%0,-1\n\
 	blt-	2f\n"
@@ -172,29 +172,4 @@ static __inline__ long local_dec_if_posi
 #define __local_add(i,l)	((l)->a.counter+=(i))
 #define __local_sub(i,l)	((l)->a.counter-=(i))
 
-/* Need to disable preemption for the cpu local counters otherwise we could
-   still access a variable of a previous CPU in a non atomic 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 /* _ARCH_POWERPC_LOCAL_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mpc5121.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/mpc5121.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mpc5121.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/mpc5121.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,24 @@
+/*
+ * MPC5121 Prototypes and definitions
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.
+ */
+
+#ifndef __ASM_POWERPC_MPC5121_H__
+#define __ASM_POWERPC_MPC5121_H__
+
+/* MPC512x Reset module registers */
+struct mpc512x_reset_module {
+	u32	rcwlr;	/* Reset Configuration Word Low Register */
+	u32	rcwhr;	/* Reset Configuration Word High Register */
+	u32	reserved1;
+	u32	reserved2;
+	u32	rsr;	/* Reset Status Register */
+	u32	rmr;	/* Reset Mode Register */
+	u32	rpr;	/* Reset Protection Register */
+	u32	rcr;	/* Reset Control Register */
+	u32	rcer;	/* Reset Control Enable Register */
+};
+
+#endif /* __ASM_POWERPC_MPC5121_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mpc52xx_psc.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/mpc52xx_psc.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mpc52xx_psc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/mpc52xx_psc.h	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,11 @@
 #include <asm/types.h>
 
 /* Max number of PSCs */
+#ifdef CONFIG_PPC_MPC512x
+#define MPC52xx_PSC_MAXNUM     12
+#else
 #define MPC52xx_PSC_MAXNUM	6
+#endif
 
 /* Programmable Serial Controller (PSC) status register bits */
 #define MPC52xx_PSC_SR_UNEX_RX	0x0001
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mpic.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/mpic.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mpic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/mpic.h	2010-05-16 17:17:36.000000000 -0400
@@ -289,7 +289,7 @@ struct mpic
 #ifdef CONFIG_MPIC_U3_HT_IRQS
 	/* The fixup table */
 	struct mpic_irq_fixup	*fixups;
-	spinlock_t		fixup_lock;
+	raw_spinlock_t	fixup_lock;
 #endif
 
 	/* Register access method */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mutex.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/mutex.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mutex.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/mutex.h	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,7 @@ static inline int __mutex_cmpxchg_lock(a
 	PPC405_ERR77(0,%1)
 "	stwcx.	%3,0,%1\n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	"\n\
 2:"
 	: "=&r" (t)
@@ -35,7 +35,7 @@ static inline int __mutex_dec_return_loc
 	PPC405_ERR77(0,%1)
 "	stwcx.	%0,0,%1\n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	: "=&r" (t)
 	: "r" (&v->counter)
 	: "cc", "memory");
@@ -48,7 +48,7 @@ static inline int __mutex_inc_return_unl
 	int t;
 
 	__asm__ __volatile__(
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	lwarx	%0,0,%1		# mutex unlock\n\
 	addic	%0,%0,1\n"
 	PPC405_ERR77(0,%1)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/paca.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/paca.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/paca.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/paca.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,11 +14,17 @@
 #define _ASM_POWERPC_PACA_H
 #ifdef __KERNEL__
 
+#ifdef CONFIG_PPC64
+
+#include <linux/init.h>
 #include <asm/types.h>
 #include <asm/lppaca.h>
 #include <asm/mmu.h>
 #include <asm/page.h>
 #include <asm/exception-64e.h>
+#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
+#include <asm/kvm_book3s_64_asm.h>
+#endif
 
 register struct paca_struct *local_paca asm("r13");
 
@@ -135,13 +141,26 @@ struct paca_struct {
 		u64     esid;
 		u64     vsid;
 	} kvm_slb[64];			/* guest SLB */
+	/* We use this to store guest state in */
+	struct kvmppc_book3s_shadow_vcpu shadow_vcpu;
 	u8 kvm_slb_max;			/* highest used guest slb entry */
 	u8 kvm_in_guest;		/* are we inside the guest? */
 #endif
 };
 
-extern struct paca_struct paca[];
-extern void initialise_pacas(void);
+extern struct paca_struct *paca;
+extern __initdata struct paca_struct boot_paca;
+extern void initialise_paca(struct paca_struct *new_paca, int cpu);
+
+extern void allocate_pacas(void);
+extern void free_unused_pacas(void);
+
+#else /* CONFIG_PPC64 */
+
+static inline void allocate_pacas(void) { };
+static inline void free_unused_pacas(void) { };
+
+#endif /* CONFIG_PPC64 */
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_PACA_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/page.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/page.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/page.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/page.h	2010-05-16 17:17:36.000000000 -0400
@@ -108,8 +108,21 @@ extern phys_addr_t kernstart_addr;
 #define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
-#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - MEMORY_START))
+/*
+ * On Book-E parts we need __va to parse the device tree and we can't
+ * determine MEMORY_START until then.  However we can determine PHYSICAL_START
+ * from information at hand (program counter, TLB lookup).
+ *
+ * On non-Book-E PPC64 PAGE_OFFSET and MEMORY_START are constants so use
+ * the other definitions for __va & __pa.
+ */
+#ifdef CONFIG_BOOKE
+#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) - PHYSICAL_START + KERNELBASE))
+#define __pa(x) ((unsigned long)(x) + PHYSICAL_START - KERNELBASE)
+#else
+#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + PAGE_OFFSET - MEMORY_START))
 #define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + MEMORY_START)
+#endif
 
 /*
  * Unfortunately the PLT is in the BSS in the PPC32 ELF ABI,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/param.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/param.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/param.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/param.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,22 +1 @@
-#ifndef _ASM_POWERPC_PARAM_H
-#define _ASM_POWERPC_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_POWERPC_PARAM_H */
+#include <asm-generic/param.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pci.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/pci.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -141,38 +141,6 @@ extern int pci_mmap_legacy_page_range(st
 
 #define HAVE_PCI_LEGACY	1
 
-#if defined(CONFIG_PPC64) || defined(CONFIG_NOT_COHERENT_CACHE)
-/*
- * For 64-bit kernels, pci_unmap_{single,page} is not a nop.
- * For 32-bit non-coherent kernels, pci_dma_sync_single_for_cpu() and
- * so on are not nops.
- * and thus...
- */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	\
-	dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)		\
-	__u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME)			\
-	((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)		\
-	(((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME)			\
-	((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL)		\
-	(((PTR)->LEN_NAME) = (VAL))
-
-#else /* 32-bit && coherent */
-
-/* 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)
-
-#endif /* CONFIG_PPC64 || CONFIG_NOT_COHERENT_CACHE */
-
 #ifdef CONFIG_PPC64
 
 /* The PCI address space does not equal the physical memory address
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/perf_event_fsl_emb.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/perf_event_fsl_emb.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/perf_event_fsl_emb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/perf_event_fsl_emb.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,50 @@
+/*
+ * Performance event support - Freescale embedded specific definitions.
+ *
+ * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
+ * Copyright 2010 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/types.h>
+#include <asm/hw_irq.h>
+
+#define MAX_HWEVENTS 4
+
+/* event flags */
+#define FSL_EMB_EVENT_VALID      1
+#define FSL_EMB_EVENT_RESTRICTED 2
+
+/* upper half of event flags is PMLCb */
+#define FSL_EMB_EVENT_THRESHMUL  0x0000070000000000ULL
+#define FSL_EMB_EVENT_THRESH     0x0000003f00000000ULL
+
+struct fsl_emb_pmu {
+	const char	*name;
+	int		n_counter; /* total number of counters */
+
+	/*
+	 * The number of contiguous counters starting at zero that
+	 * can hold restricted events, or zero if there are no
+	 * restricted events.
+	 *
+	 * This isn't a very flexible method of expressing constraints,
+	 * but it's very simple and is adequate for existing chips.
+	 */
+	int		n_restricted;
+
+	/* Returns event flags and PMLCb (FSL_EMB_EVENT_*) */
+	u64		(*xlate_event)(u64 event_id);
+
+	int		n_generic;
+	int		*generic_events;
+	int		(*cache_events)[PERF_COUNT_HW_CACHE_MAX]
+			       [PERF_COUNT_HW_CACHE_OP_MAX]
+			       [PERF_COUNT_HW_CACHE_RESULT_MAX];
+};
+
+int register_fsl_emb_pmu(struct fsl_emb_pmu *);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/perf_event.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/perf_event.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/perf_event.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/perf_event.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,110 +1,23 @@
 /*
- * Performance event support - PowerPC-specific definitions.
+ * Performance event support - hardware-specific disambiguation
  *
- * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
+ * For now this is a compile-time decision, but eventually it should be
+ * runtime.  This would allow multiplatform perf event support for e300 (fsl
+ * embedded perf counters) plus server/classic, and would accommodate
+ * devices other than the core which provide their own performance counters.
+ *
+ * Copyright 2010 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/types.h>
-
-#include <asm/hw_irq.h>
-
-#define MAX_HWEVENTS		8
-#define MAX_EVENT_ALTERNATIVES	8
-#define MAX_LIMITED_HWCOUNTERS	2
-
-/*
- * This struct provides the constants and functions needed to
- * describe the PMU on a particular POWER-family CPU.
- */
-struct power_pmu {
-	const char	*name;
-	int		n_counter;
-	int		max_alternatives;
-	unsigned long	add_fields;
-	unsigned long	test_adder;
-	int		(*compute_mmcr)(u64 events[], int n_ev,
-				unsigned int hwc[], unsigned long mmcr[]);
-	int		(*get_constraint)(u64 event_id, unsigned long *mskp,
-				unsigned long *valp);
-	int		(*get_alternatives)(u64 event_id, unsigned int flags,
-				u64 alt[]);
-	void		(*disable_pmc)(unsigned int pmc, unsigned long mmcr[]);
-	int		(*limited_pmc_event)(u64 event_id);
-	u32		flags;
-	int		n_generic;
-	int		*generic_events;
-	int		(*cache_events)[PERF_COUNT_HW_CACHE_MAX]
-			       [PERF_COUNT_HW_CACHE_OP_MAX]
-			       [PERF_COUNT_HW_CACHE_RESULT_MAX];
-};
-
-/*
- * Values for power_pmu.flags
- */
-#define PPMU_LIMITED_PMC5_6	1	/* PMC5/6 have limited function */
-#define PPMU_ALT_SIPR		2	/* uses alternate posn for SIPR/HV */
-
-/*
- * Values for flags to get_alternatives()
- */
-#define PPMU_LIMITED_PMC_OK	1	/* can put this on a limited PMC */
-#define PPMU_LIMITED_PMC_REQD	2	/* have to put this on a limited PMC */
-#define PPMU_ONLY_COUNT_RUN	4	/* only counting in run state */
 
-extern int register_power_pmu(struct power_pmu *);
-
-struct pt_regs;
-extern unsigned long perf_misc_flags(struct pt_regs *regs);
-extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
-
-#define PERF_EVENT_INDEX_OFFSET	1
-
-/*
- * Only override the default definitions in include/linux/perf_event.h
- * if we have hardware PMU support.
- */
 #ifdef CONFIG_PPC_PERF_CTRS
-#define perf_misc_flags(regs)	perf_misc_flags(regs)
+#include <asm/perf_event_server.h>
 #endif
 
-/*
- * The power_pmu.get_constraint function returns a 32/64-bit value and
- * a 32/64-bit mask that express the constraints between this event_id and
- * other events.
- *
- * The value and mask are divided up into (non-overlapping) bitfields
- * of three different types:
- *
- * Select field: this expresses the constraint that some set of bits
- * in MMCR* needs to be set to a specific value for this event_id.  For a
- * select field, the mask contains 1s in every bit of the field, and
- * the value contains a unique value for each possible setting of the
- * MMCR* bits.  The constraint checking code will ensure that two events
- * that set the same field in their masks have the same value in their
- * value dwords.
- *
- * Add field: this expresses the constraint that there can be at most
- * N events in a particular class.  A field of k bits can be used for
- * N <= 2^(k-1) - 1.  The mask has the most significant bit of the field
- * set (and the other bits 0), and the value has only the least significant
- * bit of the field set.  In addition, the 'add_fields' and 'test_adder'
- * in the struct power_pmu for this processor come into play.  The
- * add_fields value contains 1 in the LSB of the field, and the
- * test_adder contains 2^(k-1) - 1 - N in the field.
- *
- * NAND field: this expresses the constraint that you may not have events
- * in all of a set of classes.  (For example, on PPC970, you can't select
- * events from the FPU, ISU and IDU simultaneously, although any two are
- * possible.)  For N classes, the field is N+1 bits wide, and each class
- * is assigned one bit from the least-significant N bits.  The mask has
- * only the most-significant bit set, and the value has only the bit
- * for the event_id's class set.  The test_adder has the least significant
- * bit set in the field.
- *
- * If an event_id is not subject to the constraint expressed by a particular
- * field, then it will have 0 in both the mask and value for that field.
- */
+#ifdef CONFIG_FSL_EMB_PERF_EVENT
+#include <asm/perf_event_fsl_emb.h>
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/perf_event_server.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/perf_event_server.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/perf_event_server.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/perf_event_server.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,110 @@
+/*
+ * Performance event support - PowerPC classic/server specific definitions.
+ *
+ * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/types.h>
+#include <asm/hw_irq.h>
+
+#define MAX_HWEVENTS		8
+#define MAX_EVENT_ALTERNATIVES	8
+#define MAX_LIMITED_HWCOUNTERS	2
+
+/*
+ * This struct provides the constants and functions needed to
+ * describe the PMU on a particular POWER-family CPU.
+ */
+struct power_pmu {
+	const char	*name;
+	int		n_counter;
+	int		max_alternatives;
+	unsigned long	add_fields;
+	unsigned long	test_adder;
+	int		(*compute_mmcr)(u64 events[], int n_ev,
+				unsigned int hwc[], unsigned long mmcr[]);
+	int		(*get_constraint)(u64 event_id, unsigned long *mskp,
+				unsigned long *valp);
+	int		(*get_alternatives)(u64 event_id, unsigned int flags,
+				u64 alt[]);
+	void		(*disable_pmc)(unsigned int pmc, unsigned long mmcr[]);
+	int		(*limited_pmc_event)(u64 event_id);
+	u32		flags;
+	int		n_generic;
+	int		*generic_events;
+	int		(*cache_events)[PERF_COUNT_HW_CACHE_MAX]
+			       [PERF_COUNT_HW_CACHE_OP_MAX]
+			       [PERF_COUNT_HW_CACHE_RESULT_MAX];
+};
+
+/*
+ * Values for power_pmu.flags
+ */
+#define PPMU_LIMITED_PMC5_6	1	/* PMC5/6 have limited function */
+#define PPMU_ALT_SIPR		2	/* uses alternate posn for SIPR/HV */
+
+/*
+ * Values for flags to get_alternatives()
+ */
+#define PPMU_LIMITED_PMC_OK	1	/* can put this on a limited PMC */
+#define PPMU_LIMITED_PMC_REQD	2	/* have to put this on a limited PMC */
+#define PPMU_ONLY_COUNT_RUN	4	/* only counting in run state */
+
+extern int register_power_pmu(struct power_pmu *);
+
+struct pt_regs;
+extern unsigned long perf_misc_flags(struct pt_regs *regs);
+extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
+
+#define PERF_EVENT_INDEX_OFFSET	1
+
+/*
+ * Only override the default definitions in include/linux/perf_event.h
+ * if we have hardware PMU support.
+ */
+#ifdef CONFIG_PPC_PERF_CTRS
+#define perf_misc_flags(regs)	perf_misc_flags(regs)
+#endif
+
+/*
+ * The power_pmu.get_constraint function returns a 32/64-bit value and
+ * a 32/64-bit mask that express the constraints between this event_id and
+ * other events.
+ *
+ * The value and mask are divided up into (non-overlapping) bitfields
+ * of three different types:
+ *
+ * Select field: this expresses the constraint that some set of bits
+ * in MMCR* needs to be set to a specific value for this event_id.  For a
+ * select field, the mask contains 1s in every bit of the field, and
+ * the value contains a unique value for each possible setting of the
+ * MMCR* bits.  The constraint checking code will ensure that two events
+ * that set the same field in their masks have the same value in their
+ * value dwords.
+ *
+ * Add field: this expresses the constraint that there can be at most
+ * N events in a particular class.  A field of k bits can be used for
+ * N <= 2^(k-1) - 1.  The mask has the most significant bit of the field
+ * set (and the other bits 0), and the value has only the least significant
+ * bit of the field set.  In addition, the 'add_fields' and 'test_adder'
+ * in the struct power_pmu for this processor come into play.  The
+ * add_fields value contains 1 in the LSB of the field, and the
+ * test_adder contains 2^(k-1) - 1 - N in the field.
+ *
+ * NAND field: this expresses the constraint that you may not have events
+ * in all of a set of classes.  (For example, on PPC970, you can't select
+ * events from the FPU, ISU and IDU simultaneously, although any two are
+ * possible.)  For N classes, the field is N+1 bits wide, and each class
+ * is assigned one bit from the least-significant N bits.  The mask has
+ * only the most-significant bit set, and the value has only the bit
+ * for the event_id's class set.  The test_adder has the least significant
+ * bit set in the field.
+ *
+ * If an event_id is not subject to the constraint expressed by a particular
+ * field, then it will have 0 in both the mask and value for that field.
+ */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pgtable.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/pgtable.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -209,7 +209,7 @@ extern void paging_init(void);
  * corresponding HPTE into the hash table ahead of time, instead of
  * waiting for the inevitable extra hash-table miss exception.
  */
-extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
+extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
 
 extern int gup_hugepd(hugepd_t *hugepd, unsigned pdshift, unsigned long addr,
 		      unsigned long end, int write, struct page **pages, int *nr);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pmac_feature.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/pmac_feature.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pmac_feature.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/pmac_feature.h	2010-05-16 17:17:36.000000000 -0400
@@ -378,7 +378,7 @@ extern struct macio_chip* macio_find(str
  * Those are exported by pmac feature for internal use by arch code
  * only like the platform function callbacks, do not use directly in drivers
  */
-extern spinlock_t feature_lock;
+extern raw_spinlock_t feature_lock;
 extern struct device_node *uninorth_node;
 extern u32 __iomem *uninorth_base;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/ppc-opcode.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/ppc-opcode.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/ppc-opcode.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/ppc-opcode.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,8 +22,10 @@
 #define PPC_INST_DCBZL			0x7c2007ec
 #define PPC_INST_ISEL			0x7c00001e
 #define PPC_INST_ISEL_MASK		0xfc00003e
+#define PPC_INST_LDARX			0x7c0000a8
 #define PPC_INST_LSWI			0x7c0004aa
 #define PPC_INST_LSWX			0x7c00042a
+#define PPC_INST_LWARX			0x7c000028
 #define PPC_INST_LWSYNC			0x7c2004ac
 #define PPC_INST_LXVD2X			0x7c000698
 #define PPC_INST_MCRXR			0x7c000400
@@ -55,15 +57,31 @@
 #define __PPC_RA(a)	(((a) & 0x1f) << 16)
 #define __PPC_RB(b)	(((b) & 0x1f) << 11)
 #define __PPC_RS(s)	(((s) & 0x1f) << 21)
+#define __PPC_RT(s)	__PPC_RS(s)
 #define __PPC_XS(s)	((((s) & 0x1f) << 21) | (((s) & 0x20) >> 5))
 #define __PPC_T_TLB(t)	(((t) & 0x3) << 21)
 #define __PPC_WC(w)	(((w) & 0x3) << 21)
+/*
+ * Only use the larx hint bit on 64bit CPUs. e500v1/v2 based CPUs will treat a
+ * larx with EH set as an illegal instruction.
+ */
+#ifdef CONFIG_PPC64
+#define __PPC_EH(eh)	(((eh) & 0x1) << 0)
+#else
+#define __PPC_EH(eh)	0
+#endif
 
 /* 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_LDARX(t, a, b, eh)	stringify_in_c(.long PPC_INST_LDARX | \
+					__PPC_RT(t) | __PPC_RA(a) | \
+					__PPC_RB(b) | __PPC_EH(eh))
+#define PPC_LWARX(t, a, b, eh)	stringify_in_c(.long PPC_INST_LWARX | \
+					__PPC_RT(t) | __PPC_RA(a) | \
+					__PPC_RB(b) | __PPC_EH(eh))
 #define PPC_MSGSND(b)		stringify_in_c(.long PPC_INST_MSGSND | \
 					__PPC_RB(b))
 #define PPC_RFCI		stringify_in_c(.long PPC_INST_RFCI)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/ppc-pci.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/ppc-pci.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/ppc-pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/ppc-pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -137,6 +137,11 @@ struct device_node * find_device_pe(stru
 void eeh_sysfs_add_device(struct pci_dev *pdev);
 void eeh_sysfs_remove_device(struct pci_dev *pdev);
 
+static inline const char *eeh_pci_name(struct pci_dev *pdev) 
+{ 
+	return pdev ? pci_name(pdev) : "<null>";
+} 
+
 #endif /* CONFIG_EEH */
 
 #else /* CONFIG_PCI */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/processor.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/processor.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/processor.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/processor.h	2010-05-16 17:17:36.000000000 -0400
@@ -161,9 +161,41 @@ struct thread_struct {
 #ifdef CONFIG_PPC32
 	void		*pgdir;		/* root of page-table tree */
 #endif
-#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
-	unsigned long	dbcr0;		/* debug control register values */
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+	/*
+	 * The following help to manage the use of Debug Control Registers
+	 * om the BookE platforms.
+	 */
+	unsigned long	dbcr0;
 	unsigned long	dbcr1;
+#ifdef CONFIG_BOOKE
+	unsigned long	dbcr2;
+#endif
+	/*
+	 * The stored value of the DBSR register will be the value at the
+	 * last debug interrupt. This register can only be read from the
+	 * user (will never be written to) and has value while helping to
+	 * describe the reason for the last debug trap.  Torez
+	 */
+	unsigned long	dbsr;
+	/*
+	 * The following will contain addresses used by debug applications
+	 * to help trace and trap on particular address locations.
+	 * The bits in the Debug Control Registers above help define which
+	 * of the following registers will contain valid data and/or addresses.
+	 */
+	unsigned long	iac1;
+	unsigned long	iac2;
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+	unsigned long	iac3;
+	unsigned long	iac4;
+#endif
+	unsigned long	dac1;
+	unsigned long	dac2;
+#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
+	unsigned long	dvc1;
+	unsigned long	dvc2;
+#endif
 #endif
 	/* FP and VSX 0-31 register set */
 	double		fpr[32][TS_FPRWIDTH];
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/prom.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/prom.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/prom.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/prom.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,21 +23,8 @@
 #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)	strcasecmp((s1), (s2))
-#define of_prop_cmp(s1, s2)		strcmp((s1), (s2))
-#define of_node_cmp(s1, s2)		strcasecmp((s1), (s2))
-
-extern struct device_node *of_chosen;
-
 #define HAVE_ARCH_DEVTREE_FIXUPS
 
-/* For updating the device tree at runtime */
-extern void of_attach_node(struct device_node *);
-extern void of_detach_node(struct device_node *);
-
 #ifdef CONFIG_PPC32
 /*
  * PCI <-> OF matching functions
@@ -52,11 +39,6 @@ extern struct device_node* pci_device_to
 extern void pci_create_OF_bus_map(void);
 #endif
 
-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
  */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,12 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
 #ifndef __ASSEMBLY__
 
 struct pt_regs {
@@ -131,15 +137,8 @@ do {									      \
 } while (0)
 #endif /* __powerpc64__ */
 
-/*
- * These are defined as per linux/ptrace.h, which see.
- */
 #define arch_has_single_step()	(1)
 #define arch_has_block_step()	(!cpu_has_feature(CPU_FTR_601))
-extern void user_enable_single_step(struct task_struct *);
-extern void user_enable_block_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
-
 #define ARCH_HAS_USER_SINGLE_STEP_INFO
 
 #endif /* __ASSEMBLY__ */
@@ -294,4 +293,75 @@ extern void user_disable_single_step(str
 
 #define PTRACE_SINGLEBLOCK	0x100	/* resume execution until next branch */
 
+#define PPC_PTRACE_GETHWDBGINFO	0x89
+#define PPC_PTRACE_SETHWDEBUG	0x88
+#define PPC_PTRACE_DELHWDEBUG	0x87
+
+#ifndef __ASSEMBLY__
+
+struct ppc_debug_info {
+	uint32_t version;		/* Only version 1 exists to date */
+	uint32_t num_instruction_bps;
+	uint32_t num_data_bps;
+	uint32_t num_condition_regs;
+	uint32_t data_bp_alignment;
+	uint32_t sizeof_condition;	/* size of the DVC register */
+	uint64_t features;
+};
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * features will have bits indication whether there is support for:
+ */
+#define PPC_DEBUG_FEATURE_INSN_BP_RANGE		0x0000000000000001
+#define PPC_DEBUG_FEATURE_INSN_BP_MASK		0x0000000000000002
+#define PPC_DEBUG_FEATURE_DATA_BP_RANGE		0x0000000000000004
+#define PPC_DEBUG_FEATURE_DATA_BP_MASK		0x0000000000000008
+
+#ifndef __ASSEMBLY__
+
+struct ppc_hw_breakpoint {
+	uint32_t version;		/* currently, version must be 1 */
+	uint32_t trigger_type;		/* only some combinations allowed */
+	uint32_t addr_mode;		/* address match mode */
+	uint32_t condition_mode;	/* break/watchpoint condition flags */
+	uint64_t addr;			/* break/watchpoint address */
+	uint64_t addr2;			/* range end or mask */
+	uint64_t condition_value;	/* contents of the DVC register */
+};
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Trigger Type
+ */
+#define PPC_BREAKPOINT_TRIGGER_EXECUTE	0x00000001
+#define PPC_BREAKPOINT_TRIGGER_READ	0x00000002
+#define PPC_BREAKPOINT_TRIGGER_WRITE	0x00000004
+#define PPC_BREAKPOINT_TRIGGER_RW	\
+	(PPC_BREAKPOINT_TRIGGER_READ | PPC_BREAKPOINT_TRIGGER_WRITE)
+
+/*
+ * Address Mode
+ */
+#define PPC_BREAKPOINT_MODE_EXACT		0x00000000
+#define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE	0x00000001
+#define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE	0x00000002
+#define PPC_BREAKPOINT_MODE_MASK		0x00000003
+
+/*
+ * Condition Mode
+ */
+#define PPC_BREAKPOINT_CONDITION_MODE	0x00000003
+#define PPC_BREAKPOINT_CONDITION_NONE	0x00000000
+#define PPC_BREAKPOINT_CONDITION_AND	0x00000001
+#define PPC_BREAKPOINT_CONDITION_EXACT	PPC_BREAKPOINT_CONDITION_AND
+#define PPC_BREAKPOINT_CONDITION_OR	0x00000002
+#define PPC_BREAKPOINT_CONDITION_AND_OR	0x00000003
+#define PPC_BREAKPOINT_CONDITION_BE_ALL	0x00ff0000
+#define PPC_BREAKPOINT_CONDITION_BE_SHIFT	16
+#define PPC_BREAKPOINT_CONDITION_BE(n)	\
+	(1<<((n)+PPC_BREAKPOINT_CONDITION_BE_SHIFT))
+
 #endif /* _ASM_POWERPC_PTRACE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/reg_booke.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/reg_booke.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/reg_booke.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/reg_booke.h	2010-05-16 17:17:36.000000000 -0400
@@ -248,6 +248,8 @@
 #define DBSR_RET	0x00008000	/* Return Debug Event */
 #define DBSR_CIRPT	0x00000040	/* Critical Interrupt Taken Event */
 #define DBSR_CRET	0x00000020	/* Critical Return Debug Event */
+#define DBSR_IAC12ATS	0x00000002	/* Instr Address Compare 1/2 Toggle */
+#define DBSR_IAC34ATS	0x00000001	/* Instr Address Compare 3/4 Toggle */
 #endif
 #ifdef CONFIG_40x
 #define DBSR_IC		0x80000000	/* Instruction Completion */
@@ -313,6 +315,38 @@
 #define DBCR0_IA12T	0x00008000	/* Instr Addr 1-2 range Toggle */
 #define DBCR0_IA34T	0x00004000	/* Instr Addr 3-4 range Toggle */
 #define DBCR0_FT	0x00000001	/* Freeze Timers on debug event */
+
+#define dbcr_iac_range(task)	((task)->thread.dbcr0)
+#define DBCR_IAC12I	DBCR0_IA12			/* Range Inclusive */
+#define DBCR_IAC12X	(DBCR0_IA12 | DBCR0_IA12X)	/* Range Exclusive */
+#define DBCR_IAC12MODE	(DBCR0_IA12 | DBCR0_IA12X)	/* IAC 1-2 Mode Bits */
+#define DBCR_IAC34I	DBCR0_IA34			/* Range Inclusive */
+#define DBCR_IAC34X	(DBCR0_IA34 | DBCR0_IA34X)	/* Range Exclusive */
+#define DBCR_IAC34MODE	(DBCR0_IA34 | DBCR0_IA34X)	/* IAC 3-4 Mode Bits */
+
+/* Bit definitions related to the DBCR1. */
+#define DBCR1_DAC1R	0x80000000	/* DAC1 Read Debug Event */
+#define DBCR1_DAC2R	0x40000000	/* DAC2 Read Debug Event */
+#define DBCR1_DAC1W	0x20000000	/* DAC1 Write Debug Event */
+#define DBCR1_DAC2W	0x10000000	/* DAC2 Write Debug Event */
+
+#define dbcr_dac(task)	((task)->thread.dbcr1)
+#define DBCR_DAC1R	DBCR1_DAC1R
+#define DBCR_DAC1W	DBCR1_DAC1W
+#define DBCR_DAC2R	DBCR1_DAC2R
+#define DBCR_DAC2W	DBCR1_DAC2W
+
+/*
+ * Are there any active Debug Events represented in the
+ * Debug Control Registers?
+ */
+#define DBCR0_ACTIVE_EVENTS	(DBCR0_ICMP | DBCR0_IAC1 | DBCR0_IAC2 | \
+				 DBCR0_IAC3 | DBCR0_IAC4)
+#define DBCR1_ACTIVE_EVENTS	(DBCR1_DAC1R | DBCR1_DAC2R | \
+				 DBCR1_DAC1W | DBCR1_DAC2W)
+#define DBCR_ACTIVE_EVENTS(dbcr0, dbcr1)  (((dbcr0) & DBCR0_ACTIVE_EVENTS) || \
+					   ((dbcr1) & DBCR1_ACTIVE_EVENTS))
+
 #elif defined(CONFIG_BOOKE)
 #define DBCR0_EDM	0x80000000	/* External Debug Mode */
 #define DBCR0_IDM	0x40000000	/* Internal Debug Mode */
@@ -342,19 +376,79 @@
 #define DBCR0_CRET	0x00000020	/* Critical Return Debug Event */
 #define DBCR0_FT	0x00000001	/* Freeze Timers on debug event */
 
+#define dbcr_dac(task)	((task)->thread.dbcr0)
+#define DBCR_DAC1R	DBCR0_DAC1R
+#define DBCR_DAC1W	DBCR0_DAC1W
+#define DBCR_DAC2R	DBCR0_DAC2R
+#define DBCR_DAC2W	DBCR0_DAC2W
+
 /* Bit definitions related to the DBCR1. */
+#define DBCR1_IAC1US	0xC0000000	/* Instr Addr Cmp 1 Sup/User   */
+#define DBCR1_IAC1ER	0x30000000	/* Instr Addr Cmp 1 Eff/Real */
+#define DBCR1_IAC1ER_01	0x10000000	/* reserved */
+#define DBCR1_IAC1ER_10	0x20000000	/* Instr Addr Cmp 1 Eff/Real MSR[IS]=0 */
+#define DBCR1_IAC1ER_11	0x30000000	/* Instr Addr Cmp 1 Eff/Real MSR[IS]=1 */
+#define DBCR1_IAC2US	0x0C000000	/* Instr Addr Cmp 2 Sup/User   */
+#define DBCR1_IAC2ER	0x03000000	/* Instr Addr Cmp 2 Eff/Real */
+#define DBCR1_IAC2ER_01	0x01000000	/* reserved */
+#define DBCR1_IAC2ER_10	0x02000000	/* Instr Addr Cmp 2 Eff/Real MSR[IS]=0 */
+#define DBCR1_IAC2ER_11	0x03000000	/* Instr Addr Cmp 2 Eff/Real MSR[IS]=1 */
 #define DBCR1_IAC12M	0x00800000	/* Instr Addr 1-2 range enable */
 #define DBCR1_IAC12MX	0x00C00000	/* Instr Addr 1-2 range eXclusive */
 #define DBCR1_IAC12AT	0x00010000	/* Instr Addr 1-2 range Toggle */
+#define DBCR1_IAC3US	0x0000C000	/* Instr Addr Cmp 3 Sup/User   */
+#define DBCR1_IAC3ER	0x00003000	/* Instr Addr Cmp 3 Eff/Real */
+#define DBCR1_IAC3ER_01	0x00001000	/* reserved */
+#define DBCR1_IAC3ER_10	0x00002000	/* Instr Addr Cmp 3 Eff/Real MSR[IS]=0 */
+#define DBCR1_IAC3ER_11	0x00003000	/* Instr Addr Cmp 3 Eff/Real MSR[IS]=1 */
+#define DBCR1_IAC4US	0x00000C00	/* Instr Addr Cmp 4 Sup/User   */
+#define DBCR1_IAC4ER	0x00000300	/* Instr Addr Cmp 4 Eff/Real */
+#define DBCR1_IAC4ER_01	0x00000100	/* Instr Addr Cmp 4 Eff/Real MSR[IS]=0 */
+#define DBCR1_IAC4ER_10	0x00000200	/* Instr Addr Cmp 4 Eff/Real MSR[IS]=0 */
+#define DBCR1_IAC4ER_11	0x00000300	/* Instr Addr Cmp 4 Eff/Real MSR[IS]=1 */
 #define DBCR1_IAC34M	0x00000080	/* Instr Addr 3-4 range enable */
 #define DBCR1_IAC34MX	0x000000C0	/* Instr Addr 3-4 range eXclusive */
 #define DBCR1_IAC34AT	0x00000001	/* Instr Addr 3-4 range Toggle */
 
+#define dbcr_iac_range(task)	((task)->thread.dbcr1)
+#define DBCR_IAC12I	DBCR1_IAC12M	/* Range Inclusive */
+#define DBCR_IAC12X	DBCR1_IAC12MX	/* Range Exclusive */
+#define DBCR_IAC12MODE	DBCR1_IAC12MX	/* IAC 1-2 Mode Bits */
+#define DBCR_IAC34I	DBCR1_IAC34M	/* Range Inclusive */
+#define DBCR_IAC34X	DBCR1_IAC34MX	/* Range Exclusive */
+#define DBCR_IAC34MODE	DBCR1_IAC34MX	/* IAC 3-4 Mode Bits */
+
 /* Bit definitions related to the DBCR2. */
+#define DBCR2_DAC1US	0xC0000000	/* Data Addr Cmp 1 Sup/User   */
+#define DBCR2_DAC1ER	0x30000000	/* Data Addr Cmp 1 Eff/Real */
+#define DBCR2_DAC2US	0x0C000000	/* Data Addr Cmp 2 Sup/User   */
+#define DBCR2_DAC2ER	0x03000000	/* Data Addr Cmp 2 Eff/Real */
 #define DBCR2_DAC12M	0x00800000	/* DAC 1-2 range enable */
+#define DBCR2_DAC12MM	0x00400000	/* DAC 1-2 Mask mode*/
 #define DBCR2_DAC12MX	0x00C00000	/* DAC 1-2 range eXclusive */
+#define DBCR2_DAC12MODE	0x00C00000	/* DAC 1-2 Mode Bits */
 #define DBCR2_DAC12A	0x00200000	/* DAC 1-2 Asynchronous */
-#endif
+#define DBCR2_DVC1M	0x000C0000	/* Data Value Comp 1 Mode */
+#define DBCR2_DVC1M_SHIFT	18	/* # of bits to shift DBCR2_DVC1M */
+#define DBCR2_DVC2M	0x00030000	/* Data Value Comp 2 Mode */
+#define DBCR2_DVC2M_SHIFT	16	/* # of bits to shift DBCR2_DVC2M */
+#define DBCR2_DVC1BE	0x00000F00	/* Data Value Comp 1 Byte */
+#define DBCR2_DVC1BE_SHIFT	8	/* # of bits to shift DBCR2_DVC1BE */
+#define DBCR2_DVC2BE	0x0000000F	/* Data Value Comp 2 Byte */
+#define DBCR2_DVC2BE_SHIFT	0	/* # of bits to shift DBCR2_DVC2BE */
+
+/*
+ * Are there any active Debug Events represented in the
+ * Debug Control Registers?
+ */
+#define DBCR0_ACTIVE_EVENTS  (DBCR0_ICMP | DBCR0_IAC1 | DBCR0_IAC2 | \
+			      DBCR0_IAC3 | DBCR0_IAC4 | DBCR0_DAC1R | \
+			      DBCR0_DAC1W  | DBCR0_DAC2R | DBCR0_DAC2W)
+#define DBCR1_ACTIVE_EVENTS	0
+
+#define DBCR_ACTIVE_EVENTS(dbcr0, dbcr1)  (((dbcr0) & DBCR0_ACTIVE_EVENTS) || \
+					   ((dbcr1) & DBCR1_ACTIVE_EVENTS))
+#endif /* #elif defined(CONFIG_BOOKE) */
 
 /* Bit definitions related to the TCR. */
 #define TCR_WP(x)	(((x)&0x3)<<30)	/* WDT Period */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/reg_fsl_emb.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/reg_fsl_emb.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/reg_fsl_emb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/reg_fsl_emb.h	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,7 @@
 #define PMLCA_FCM0	0x08000000	/* Freeze when PMM==0 */
 #define PMLCA_CE	0x04000000	/* Condition Enable */
 
-#define PMLCA_EVENT_MASK 0x007f0000	/* Event field */
+#define PMLCA_EVENT_MASK 0x00ff0000	/* Event field */
 #define PMLCA_EVENT_SHIFT	16
 
 #define PMRN_PMLCB0	0x110	/* PM Local Control B0 */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/reg.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/reg.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/reg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/reg.h	2010-05-16 17:17:36.000000000 -0400
@@ -426,6 +426,10 @@
 #define   SRR1_WAKEMT		0x00280000 /* mtctrl */
 #define   SRR1_WAKEDEC		0x00180000 /* Decrementer interrupt */
 #define   SRR1_WAKETHERM	0x00100000 /* Thermal management interrupt */
+#define   SRR1_PROGFPE		0x00100000 /* Floating Point Enabled */
+#define   SRR1_PROGPRIV		0x00040000 /* Privileged instruction */
+#define   SRR1_PROGTRAP		0x00020000 /* Trap */
+#define   SRR1_PROGADDR		0x00010000 /* SRR0 contains subsequent addr */
 #define SPRN_HSRR0	0x13A	/* Save/Restore Register 0 */
 #define SPRN_HSRR1	0x13B	/* Save/Restore Register 1 */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/spinlock.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/spinlock.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/spinlock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/spinlock.h	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #endif
 #include <asm/asm-compat.h>
 #include <asm/synch.h>
+#include <asm/ppc-opcode.h>
 
 #define arch_spin_is_locked(x)		((x)->slock != 0)
 
@@ -60,13 +61,14 @@ static inline unsigned long __arch_spin_
 
 	token = LOCK_TOKEN;
 	__asm__ __volatile__(
-"1:	lwarx		%0,0,%2\n\
+"1:	" PPC_LWARX(%0,0,%2,1) "\n\
 	cmpwi		0,%0,0\n\
 	bne-		2f\n\
 	stwcx.		%1,0,%2\n\
-	bne-		1b\n\
-	isync\n\
-2:"	: "=&r" (tmp)
+	bne-		1b\n"
+	PPC_ACQUIRE_BARRIER
+"2:"
+	: "=&r" (tmp)
 	: "r" (token), "r" (&lock->slock)
 	: "cr0", "memory");
 
@@ -144,7 +146,7 @@ static inline void arch_spin_unlock(arch
 {
 	SYNC_IO;
 	__asm__ __volatile__("# arch_spin_unlock\n\t"
-				LWSYNC_ON_SMP: : :"memory");
+				PPC_RELEASE_BARRIER: : :"memory");
 	lock->slock = 0;
 }
 
@@ -186,15 +188,15 @@ static inline long __arch_read_trylock(a
 	long tmp;
 
 	__asm__ __volatile__(
-"1:	lwarx		%0,0,%1\n"
+"1:	" PPC_LWARX(%0,0,%1,1) "\n"
 	__DO_SIGN_EXTEND
 "	addic.		%0,%0,1\n\
 	ble-		2f\n"
 	PPC405_ERR77(0,%1)
 "	stwcx.		%0,0,%1\n\
-	bne-		1b\n\
-	isync\n\
-2:"	: "=&r" (tmp)
+	bne-		1b\n"
+	PPC_ACQUIRE_BARRIER
+"2:"	: "=&r" (tmp)
 	: "r" (&rw->lock)
 	: "cr0", "xer", "memory");
 
@@ -211,14 +213,14 @@ static inline long __arch_write_trylock(
 
 	token = WRLOCK_TOKEN;
 	__asm__ __volatile__(
-"1:	lwarx		%0,0,%2\n\
+"1:	" PPC_LWARX(%0,0,%2,1) "\n\
 	cmpwi		0,%0,0\n\
 	bne-		2f\n"
 	PPC405_ERR77(0,%1)
 "	stwcx.		%1,0,%2\n\
-	bne-		1b\n\
-	isync\n\
-2:"	: "=&r" (tmp)
+	bne-		1b\n"
+	PPC_ACQUIRE_BARRIER
+"2:"	: "=&r" (tmp)
 	: "r" (token), "r" (&rw->lock)
 	: "cr0", "memory");
 
@@ -269,7 +271,7 @@ static inline void arch_read_unlock(arch
 
 	__asm__ __volatile__(
 	"# read_unlock\n\t"
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	lwarx		%0,0,%1\n\
 	addic		%0,%0,-1\n"
 	PPC405_ERR77(0,%1)
@@ -283,7 +285,7 @@ static inline void arch_read_unlock(arch
 static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
 	__asm__ __volatile__("# write_unlock\n\t"
-				LWSYNC_ON_SMP: : :"memory");
+				PPC_RELEASE_BARRIER: : :"memory");
 	rw->lock = 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/synch.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/synch.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/synch.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/synch.h	2010-05-16 17:17:36.000000000 -0400
@@ -37,11 +37,15 @@ static inline void isync(void)
 #endif
 
 #ifdef CONFIG_SMP
-#define ISYNC_ON_SMP	"\n\tisync\n"
-#define LWSYNC_ON_SMP	stringify_in_c(LWSYNC) "\n"
+#define __PPC_ACQUIRE_BARRIER				\
+	START_LWSYNC_SECTION(97);			\
+	isync;						\
+	MAKE_LWSYNC_SECTION_ENTRY(97, __lwsync_fixup);
+#define PPC_ACQUIRE_BARRIER	"\n" stringify_in_c(__PPC_ACQUIRE_BARRIER)
+#define PPC_RELEASE_BARRIER	stringify_in_c(LWSYNC) "\n"
 #else
-#define ISYNC_ON_SMP
-#define LWSYNC_ON_SMP
+#define PPC_ACQUIRE_BARRIER
+#define PPC_RELEASE_BARRIER
 #endif
 
 #endif /* __KERNEL__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/syscall.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/syscall.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/syscall.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/syscall.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,7 @@ static inline void syscall_rollback(stru
 static inline long syscall_get_error(struct task_struct *task,
 				     struct pt_regs *regs)
 {
-	return (regs->ccr & 0x1000) ? -regs->gpr[3] : 0;
+	return (regs->ccr & 0x10000000) ? -regs->gpr[3] : 0;
 }
 
 static inline long syscall_get_return_value(struct task_struct *task,
@@ -44,10 +44,10 @@ static inline void syscall_set_return_va
 					    int error, long val)
 {
 	if (error) {
-		regs->ccr |= 0x1000L;
+		regs->ccr |= 0x10000000L;
 		regs->gpr[3] = -error;
 	} else {
-		regs->ccr &= ~0x1000L;
+		regs->ccr &= ~0x10000000L;
 		regs->gpr[3] = val;
 	}
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/syscalls.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/syscalls.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/syscalls.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/syscalls.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,6 @@
 #include <linux/types.h>
 #include <asm/signal.h>
 
-struct new_utsname;
 struct pt_regs;
 struct rtas_args;
 struct sigaction;
@@ -35,12 +34,9 @@ asmlinkage long sys_pipe2(int __user *fi
 asmlinkage long sys_rt_sigaction(int sig,
 		const struct sigaction __user *act,
 		struct sigaction __user *oact, size_t sigsetsize);
-asmlinkage int sys_ipc(uint call, int first, unsigned long second,
-		long third, void __user *ptr, long fifth);
 asmlinkage long ppc64_personality(unsigned long personality);
 asmlinkage int ppc_rtas(struct rtas_args __user *uargs);
 asmlinkage time_t sys64_time(time_t __user * tloc);
-asmlinkage long ppc_newuname(struct new_utsname __user * name);
 
 asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset,
 		size_t sigsetsize);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/systbl.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/systbl.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/systbl.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/systbl.h	2010-05-16 17:17:36.000000000 -0400
@@ -125,7 +125,7 @@ SYSCALL_SPU(fsync)
 SYS32ONLY(sigreturn)
 PPC_SYS(clone)
 COMPAT_SYS_SPU(setdomainname)
-PPC_SYS_SPU(newuname)
+SYSCALL_SPU(newuname)
 SYSCALL(ni_syscall)
 COMPAT_SYS_SPU(adjtimex)
 SYSCALL_SPU(mprotect)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/system.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/system.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/system.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -112,8 +112,13 @@ static inline int debugger_fault_handler
 #endif
 
 extern int set_dabr(unsigned long dabr);
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+extern void do_send_trap(struct pt_regs *regs, unsigned long address,
+			 unsigned long error_code, int signal_code, int brkpt);
+#else
 extern void do_dabr(struct pt_regs *regs, unsigned long address,
 		    unsigned long error_code);
+#endif
 extern void print_backtrace(unsigned long *);
 extern void show_regs(struct pt_regs * regs);
 extern void flush_instruction_cache(void);
@@ -232,12 +237,12 @@ __xchg_u32(volatile void *p, unsigned lo
 	unsigned long prev;
 
 	__asm__ __volatile__(
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	lwarx	%0,0,%2 \n"
 	PPC405_ERR77(0,%2)
 "	stwcx.	%3,0,%2 \n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	: "=&r" (prev), "+m" (*(volatile unsigned int *)p)
 	: "r" (p), "r" (val)
 	: "cc", "memory");
@@ -275,12 +280,12 @@ __xchg_u64(volatile void *p, unsigned lo
 	unsigned long prev;
 
 	__asm__ __volatile__(
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	ldarx	%0,0,%2 \n"
 	PPC405_ERR77(0,%2)
 "	stdcx.	%3,0,%2 \n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	: "=&r" (prev), "+m" (*(volatile unsigned long *)p)
 	: "r" (p), "r" (val)
 	: "cc", "memory");
@@ -366,14 +371,14 @@ __cmpxchg_u32(volatile unsigned int *p,
 	unsigned int prev;
 
 	__asm__ __volatile__ (
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	lwarx	%0,0,%2		# __cmpxchg_u32\n\
 	cmpw	0,%0,%3\n\
 	bne-	2f\n"
 	PPC405_ERR77(0,%2)
 "	stwcx.	%4,0,%2\n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	"\n\
 2:"
 	: "=&r" (prev), "+m" (*p)
@@ -412,13 +417,13 @@ __cmpxchg_u64(volatile unsigned long *p,
 	unsigned long prev;
 
 	__asm__ __volatile__ (
-	LWSYNC_ON_SMP
+	PPC_RELEASE_BARRIER
 "1:	ldarx	%0,0,%2		# __cmpxchg_u64\n\
 	cmpd	0,%0,%3\n\
 	bne-	2f\n\
 	stdcx.	%4,0,%2\n\
 	bne-	1b"
-	ISYNC_ON_SMP
+	PPC_ACQUIRE_BARRIER
 	"\n\
 2:"
 	: "=&r" (prev), "+m" (*p)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/topology.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/topology.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/topology.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/topology.h	2010-05-16 17:17:36.000000000 -0400
@@ -38,27 +38,33 @@ static inline int pcibus_to_node(struct
 				 cpumask_of_node(pcibus_to_node(bus)))
 
 /* sched_domains SD_NODE_INIT for PPC64 machines */
-#define SD_NODE_INIT (struct sched_domain) {		\
-	.parent			= NULL,			\
-	.child			= NULL,			\
-	.groups			= NULL,			\
-	.min_interval		= 8,			\
-	.max_interval		= 32,			\
-	.busy_factor		= 32,			\
-	.imbalance_pct		= 125,			\
-	.cache_nice_tries	= 1,			\
-	.busy_idx		= 3,			\
-	.idle_idx		= 1,			\
-	.newidle_idx		= 0,			\
-	.wake_idx		= 0,			\
-	.flags			= SD_LOAD_BALANCE	\
-				| SD_BALANCE_EXEC	\
-				| SD_BALANCE_FORK	\
-				| SD_BALANCE_NEWIDLE	\
-				| SD_SERIALIZE,		\
-	.last_balance		= jiffies,		\
-	.balance_interval	= 1,			\
-	.nr_balance_failed	= 0,			\
+#define SD_NODE_INIT (struct sched_domain) {				\
+	.min_interval		= 8,					\
+	.max_interval		= 32,					\
+	.busy_factor		= 32,					\
+	.imbalance_pct		= 125,					\
+	.cache_nice_tries	= 1,					\
+	.busy_idx		= 3,					\
+	.idle_idx		= 1,					\
+	.newidle_idx		= 0,					\
+	.wake_idx		= 0,					\
+	.forkexec_idx		= 0,					\
+									\
+	.flags			= 1*SD_LOAD_BALANCE			\
+				| 1*SD_BALANCE_NEWIDLE			\
+				| 1*SD_BALANCE_EXEC			\
+				| 1*SD_BALANCE_FORK			\
+				| 0*SD_BALANCE_WAKE			\
+				| 0*SD_WAKE_AFFINE			\
+				| 0*SD_PREFER_LOCAL			\
+				| 0*SD_SHARE_CPUPOWER			\
+				| 0*SD_POWERSAVINGS_BALANCE		\
+				| 0*SD_SHARE_PKG_RESOURCES		\
+				| 1*SD_SERIALIZE			\
+				| 0*SD_PREFER_SIBLING			\
+				,					\
+	.last_balance		= jiffies,				\
+	.balance_interval	= 1,					\
 }
 
 extern void __init dump_numa_cpu_topology(void);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/unistd.h linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/unistd.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/unistd.h	2010-05-16 17:17:36.000000000 -0400
@@ -364,6 +364,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
@@ -376,6 +377,7 @@
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_UNAME
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/Kconfig linux-libre-2.6.34-gnu1/arch/powerpc/Kconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -58,7 +58,7 @@ config IRQ_PER_CPU
 
 config NR_IRQS
 	int "Number of virtual interrupt numbers"
-	range 32 512
+	range 32 32768
 	default "512"
 	help
 	  This defines the number of virtual interrupt numbers the kernel
@@ -173,6 +173,7 @@ config PPC_OF
 
 config OF
 	def_bool y
+	select OF_FLATTREE
 
 config PPC_UDBG_16550
 	bool
@@ -240,6 +241,33 @@ config PPC_OF_PLATFORM_PCI
 config ARCH_SUPPORTS_DEBUG_PAGEALLOC
 	def_bool y
 
+config PPC_ADV_DEBUG_REGS
+	bool
+	depends on 40x || BOOKE
+	default y
+
+config PPC_ADV_DEBUG_IACS
+	int
+	depends on PPC_ADV_DEBUG_REGS
+	default 4 if 44x
+	default 2
+
+config PPC_ADV_DEBUG_DACS
+	int
+	depends on PPC_ADV_DEBUG_REGS
+	default 2
+
+config PPC_ADV_DEBUG_DVCS
+	int
+	depends on PPC_ADV_DEBUG_REGS
+	default 2 if 44x
+	default 0
+
+config PPC_ADV_DEBUG_DAC_RANGE
+	bool
+	depends on PPC_ADV_DEBUG_REGS && 44x
+	default y
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
@@ -285,19 +313,6 @@ config 8XX_MINIMAL_FPEMU
 
 	  It is recommended that you build a soft-float userspace instead.
 
-config IOMMU_VMERGE
-	bool "Enable IOMMU virtual merging"
-	depends on PPC64
-	default y
-	help
-	  Cause IO segments sent to a device for DMA to be merged virtually
-	  by the IOMMU when they happen to have been allocated contiguously.
-	  This doesn't add pressure to the IOMMU allocator. However, some
-	  drivers don't support getting large merged segments coming back
-	  from *_map_sg().
-
-	  Most drivers don't have this problem; it is safe to say Y here.
-
 config IOMMU_HELPER
 	def_bool PPC64
 
@@ -644,6 +659,9 @@ config ZONE_DMA
 	bool
 	default y
 
+config NEED_DMA_MAP_STATE
+	def_bool (PPC64 || NOT_COHERENT_CACHE)
+
 config GENERIC_ISA_DMA
 	bool
 	depends on PPC64 || POWER4 || 6xx && !CPM2
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/asm-offsets.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/asm-offsets.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/asm-offsets.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/asm-offsets.c	2010-05-16 17:17:36.000000000 -0400
@@ -133,7 +133,6 @@ int main(void)
 	DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr));
 	DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
 	DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
-	DEFINE(PACAPERFPEND, offsetof(struct paca_struct, perf_event_pending));
 	DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
 #ifdef CONFIG_PPC_MM_SLICES
 	DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct,
@@ -194,6 +193,30 @@ int main(void)
 	DEFINE(PACA_KVM_IN_GUEST, offsetof(struct paca_struct, kvm_in_guest));
 	DEFINE(PACA_KVM_SLB, offsetof(struct paca_struct, kvm_slb));
 	DEFINE(PACA_KVM_SLB_MAX, offsetof(struct paca_struct, kvm_slb_max));
+	DEFINE(PACA_KVM_CR, offsetof(struct paca_struct, shadow_vcpu.cr));
+	DEFINE(PACA_KVM_XER, offsetof(struct paca_struct, shadow_vcpu.xer));
+	DEFINE(PACA_KVM_R0, offsetof(struct paca_struct, shadow_vcpu.gpr[0]));
+	DEFINE(PACA_KVM_R1, offsetof(struct paca_struct, shadow_vcpu.gpr[1]));
+	DEFINE(PACA_KVM_R2, offsetof(struct paca_struct, shadow_vcpu.gpr[2]));
+	DEFINE(PACA_KVM_R3, offsetof(struct paca_struct, shadow_vcpu.gpr[3]));
+	DEFINE(PACA_KVM_R4, offsetof(struct paca_struct, shadow_vcpu.gpr[4]));
+	DEFINE(PACA_KVM_R5, offsetof(struct paca_struct, shadow_vcpu.gpr[5]));
+	DEFINE(PACA_KVM_R6, offsetof(struct paca_struct, shadow_vcpu.gpr[6]));
+	DEFINE(PACA_KVM_R7, offsetof(struct paca_struct, shadow_vcpu.gpr[7]));
+	DEFINE(PACA_KVM_R8, offsetof(struct paca_struct, shadow_vcpu.gpr[8]));
+	DEFINE(PACA_KVM_R9, offsetof(struct paca_struct, shadow_vcpu.gpr[9]));
+	DEFINE(PACA_KVM_R10, offsetof(struct paca_struct, shadow_vcpu.gpr[10]));
+	DEFINE(PACA_KVM_R11, offsetof(struct paca_struct, shadow_vcpu.gpr[11]));
+	DEFINE(PACA_KVM_R12, offsetof(struct paca_struct, shadow_vcpu.gpr[12]));
+	DEFINE(PACA_KVM_R13, offsetof(struct paca_struct, shadow_vcpu.gpr[13]));
+	DEFINE(PACA_KVM_HOST_R1, offsetof(struct paca_struct, shadow_vcpu.host_r1));
+	DEFINE(PACA_KVM_HOST_R2, offsetof(struct paca_struct, shadow_vcpu.host_r2));
+	DEFINE(PACA_KVM_VMHANDLER, offsetof(struct paca_struct,
+					    shadow_vcpu.vmhandler));
+	DEFINE(PACA_KVM_SCRATCH0, offsetof(struct paca_struct,
+					   shadow_vcpu.scratch0));
+	DEFINE(PACA_KVM_SCRATCH1, offsetof(struct paca_struct,
+					   shadow_vcpu.scratch1));
 #endif
 #endif /* CONFIG_PPC64 */
 
@@ -389,8 +412,6 @@ int main(void)
 	DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid));
 	DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr));
 	DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr));
-	DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr));
-	DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer));
 	DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr));
 	DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc));
 	DEFINE(VCPU_MSR, offsetof(struct kvm_vcpu, arch.msr));
@@ -411,11 +432,16 @@ int main(void)
 	DEFINE(VCPU_HOST_R2, offsetof(struct kvm_vcpu, arch.host_r2));
 	DEFINE(VCPU_HOST_MSR, offsetof(struct kvm_vcpu, arch.host_msr));
 	DEFINE(VCPU_SHADOW_MSR, offsetof(struct kvm_vcpu, arch.shadow_msr));
+	DEFINE(VCPU_SHADOW_SRR1, offsetof(struct kvm_vcpu, arch.shadow_srr1));
 	DEFINE(VCPU_TRAMPOLINE_LOWMEM, offsetof(struct kvm_vcpu, arch.trampoline_lowmem));
 	DEFINE(VCPU_TRAMPOLINE_ENTER, offsetof(struct kvm_vcpu, arch.trampoline_enter));
 	DEFINE(VCPU_HIGHMEM_HANDLER, offsetof(struct kvm_vcpu, arch.highmem_handler));
+	DEFINE(VCPU_RMCALL, offsetof(struct kvm_vcpu, arch.rmcall));
 	DEFINE(VCPU_HFLAGS, offsetof(struct kvm_vcpu, arch.hflags));
-#endif
+#else
+	DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr));
+	DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer));
+#endif /* CONFIG_PPC64 */
 #endif
 #ifdef CONFIG_44x
 	DEFINE(PGD_T_LOG2, PGD_T_LOG2);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/cacheinfo.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/cacheinfo.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/cacheinfo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/cacheinfo.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/notifier.h>
 #include <linux/of.h>
 #include <linux/percpu.h>
+#include <linux/slab.h>
 #include <asm/prom.h>
 
 #include "cacheinfo.h"
@@ -642,7 +643,7 @@ static struct kobj_attribute *cache_inde
 	&cache_assoc_attr,
 };
 
-static struct sysfs_ops cache_index_ops = {
+static const struct sysfs_ops cache_index_ops = {
 	.show = cache_index_show,
 };
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/cputable.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/cputable.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/cputable.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/cputable.c	2010-05-16 17:17:36.000000000 -0400
@@ -1808,7 +1808,7 @@ static struct cpu_spec __initdata cpu_sp
 		.icache_bsize		= 64,
 		.dcache_bsize		= 64,
 		.num_pmcs		= 4,
-		.oprofile_cpu_type	= "ppc/e500", /* xxx - galak, e500mc? */
+		.oprofile_cpu_type	= "ppc/e500mc",
 		.oprofile_type		= PPC_OPROFILE_FSL_EMB,
 		.cpu_setup		= __setup_cpu_e500mc,
 		.machine_check		= machine_check_e500,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/dma.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/dma.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-debug.h>
+#include <linux/gfp.h>
 #include <linux/lmb.h>
 #include <asm/bug.h>
 #include <asm/abs_addr.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/dma-swiotlb.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/dma-swiotlb.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/dma-swiotlb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/dma-swiotlb.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,8 @@
 /*
  * Contains routines needed to support swiotlb for ppc.
  *
- * Copyright (C) 2009 Becky Bruce, Freescale Semiconductor
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc.
+ * Author: Becky Bruce
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -70,7 +71,7 @@ static int ppc_swiotlb_bus_notify(struct
 	sd->max_direct_dma_addr = 0;
 
 	/* May need to bounce if the device can't address all of DRAM */
-	if (dma_get_mask(dev) < lmb_end_of_DRAM())
+	if ((dma_get_mask(dev) + 1) < lmb_end_of_DRAM())
 		set_dma_ops(dev, &swiotlb_dma_ops);
 
 	return NOTIFY_DONE;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/e500-pmu.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/e500-pmu.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/e500-pmu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/e500-pmu.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,129 @@
+/*
+ * Performance counter support for e500 family processors.
+ *
+ * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
+ * Copyright 2010 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/string.h>
+#include <linux/perf_event.h>
+#include <asm/reg.h>
+#include <asm/cputable.h>
+
+/*
+ * Map of generic hardware event types to hardware events
+ * Zero if unsupported
+ */
+static int e500_generic_events[] = {
+	[PERF_COUNT_HW_CPU_CYCLES] = 1,
+	[PERF_COUNT_HW_INSTRUCTIONS] = 2,
+	[PERF_COUNT_HW_CACHE_MISSES] = 41, /* Data L1 cache reloads */
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 12,
+	[PERF_COUNT_HW_BRANCH_MISSES] = 15,
+};
+
+#define C(x)	PERF_COUNT_HW_CACHE_##x
+
+/*
+ * Table of generalized cache-related events.
+ * 0 means not supported, -1 means nonsensical, other values
+ * are event codes.
+ */
+static int e500_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
+	/*
+	 * D-cache misses are not split into read/write/prefetch;
+	 * use raw event 41.
+	 */
+	[C(L1D)] = {		/* 	RESULT_ACCESS	RESULT_MISS */
+		[C(OP_READ)] = {	27,		0	},
+		[C(OP_WRITE)] = {	28,		0	},
+		[C(OP_PREFETCH)] = {	29,		0	},
+	},
+	[C(L1I)] = {		/* 	RESULT_ACCESS	RESULT_MISS */
+		[C(OP_READ)] = {	2,		60	},
+		[C(OP_WRITE)] = {	-1,		-1	},
+		[C(OP_PREFETCH)] = {	0,		0	},
+	},
+	/*
+	 * Assuming LL means L2, it's not a good match for this model.
+	 * It allocates only on L1 castout or explicit prefetch, and
+	 * does not have separate read/write events (but it does have
+	 * separate instruction/data events).
+	 */
+	[C(LL)] = {		/* 	RESULT_ACCESS	RESULT_MISS */
+		[C(OP_READ)] = {	0,		0	},
+		[C(OP_WRITE)] = {	0,		0	},
+		[C(OP_PREFETCH)] = {	0,		0	},
+	},
+	/*
+	 * There are data/instruction MMU misses, but that's a miss on
+	 * the chip's internal level-one TLB which is probably not
+	 * what the user wants.  Instead, unified level-two TLB misses
+	 * are reported here.
+	 */
+	[C(DTLB)] = {		/* 	RESULT_ACCESS	RESULT_MISS */
+		[C(OP_READ)] = {	26,		66	},
+		[C(OP_WRITE)] = {	-1,		-1	},
+		[C(OP_PREFETCH)] = {	-1,		-1	},
+	},
+	[C(BPU)] = {		/* 	RESULT_ACCESS	RESULT_MISS */
+		[C(OP_READ)] = {	12,		15 	},
+		[C(OP_WRITE)] = {	-1,		-1	},
+		[C(OP_PREFETCH)] = {	-1,		-1	},
+	},
+};
+
+static int num_events = 128;
+
+/* Upper half of event id is PMLCb, for threshold events */
+static u64 e500_xlate_event(u64 event_id)
+{
+	u32 event_low = (u32)event_id;
+	u64 ret;
+
+	if (event_low >= num_events)
+		return 0;
+
+	ret = FSL_EMB_EVENT_VALID;
+
+	if (event_low >= 76 && event_low <= 81) {
+		ret |= FSL_EMB_EVENT_RESTRICTED;
+		ret |= event_id &
+		       (FSL_EMB_EVENT_THRESHMUL | FSL_EMB_EVENT_THRESH);
+	} else if (event_id &
+	           (FSL_EMB_EVENT_THRESHMUL | FSL_EMB_EVENT_THRESH)) {
+		/* Threshold requested on non-threshold event */
+		return 0;
+	}
+
+	return ret;
+}
+
+static struct fsl_emb_pmu e500_pmu = {
+	.name			= "e500 family",
+	.n_counter		= 4,
+	.n_restricted		= 2,
+	.xlate_event		= e500_xlate_event,
+	.n_generic		= ARRAY_SIZE(e500_generic_events),
+	.generic_events		= e500_generic_events,
+	.cache_events		= &e500_cache_events,
+};
+
+static int init_e500_pmu(void)
+{
+	if (!cur_cpu_spec->oprofile_cpu_type)
+		return -ENODEV;
+
+	if (!strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/e500mc"))
+		num_events = 256;
+	else if (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/e500"))
+		return -ENODEV;
+
+	return register_fsl_emb_pmu(&e500_pmu);
+}
+
+arch_initcall(init_e500_pmu);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/entry_64.S linux-libre-2.6.34-gnu1/arch/powerpc/kernel/entry_64.S
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/entry_64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/entry_64.S	2010-05-16 17:17:36.000000000 -0400
@@ -556,15 +556,6 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_
 2:
 	TRACE_AND_RESTORE_IRQ(r5);
 
-#ifdef CONFIG_PERF_EVENTS
-	/* check paca->perf_event_pending if we're enabling ints */
-	lbz	r3,PACAPERFPEND(r13)
-	and.	r3,r3,r5
-	beq	27f
-	bl	.perf_event_do_pending
-27:
-#endif /* CONFIG_PERF_EVENTS */
-
 	/* extract EE bit and use it to restore paca->hard_enabled */
 	ld	r3,_MSR(r1)
 	rldicl	r4,r3,49,63		/* r0 = (r3 >> 15) & 1 */
@@ -791,9 +782,8 @@ _GLOBAL(enter_rtas)
 	
         li      r9,1
         rldicr  r9,r9,MSR_SF_LG,(63-MSR_SF_LG)
-	ori	r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP
+	ori	r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP|MSR_RI
 	andc	r6,r0,r9
-	ori	r6,r6,MSR_RI
 	sync				/* disable interrupts so SRR0/1 */
 	mtmsrd	r0			/* don't get trashed */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/firmware.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/firmware.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/firmware.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/firmware.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,5 +17,5 @@
 
 #include <asm/firmware.h>
 
-unsigned long powerpc_firmware_features;
+unsigned long powerpc_firmware_features __read_mostly;
 EXPORT_SYMBOL_GPL(powerpc_firmware_features);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/head_64.S linux-libre-2.6.34-gnu1/arch/powerpc/kernel/head_64.S
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/head_64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/head_64.S	2010-05-16 17:17:36.000000000 -0400
@@ -219,7 +219,8 @@ generic_secondary_common_init:
 	 * physical cpu id in r24, we need to search the pacas to find
 	 * which logical id maps to our physical one.
 	 */
-	LOAD_REG_ADDR(r13, paca)	/* Get base vaddr of paca array	 */
+	LOAD_REG_ADDR(r13, paca)	/* Load paca pointer		 */
+	ld	r13,0(r13)		/* Get base vaddr of paca array	 */
 	li	r5,0			/* logical cpu id                */
 1:	lhz	r6,PACAHWCPUID(r13)	/* Load HW procid from paca      */
 	cmpw	r6,r24			/* Compare to our id             */
@@ -536,7 +537,8 @@ _GLOBAL(pmac_secondary_start)
 	mtmsrd	r3			/* RI on */
 
 	/* Set up a paca value for this processor. */
-	LOAD_REG_ADDR(r4,paca)		/* Get base vaddr of paca array	*/
+	LOAD_REG_ADDR(r4,paca)		/* Load paca pointer		*/
+	ld	r4,0(r4)		/* Get base vaddr of paca array	*/
 	mulli	r13,r24,PACA_SIZE	/* Calculate vaddr of right paca */
 	add	r13,r13,r4		/* for this processor.		*/
 	mtspr	SPRN_SPRG_PACA,r13	/* Save vaddr of paca in an SPRG*/
@@ -614,6 +616,17 @@ _GLOBAL(start_secondary_prolog)
 	li	r3,0
 	std	r3,0(r1)		/* Zero the stack frame pointer	*/
 	bl	.start_secondary
+	b	.
+/*
+ * Reset stack pointer and call start_secondary
+ * to continue with online operation when woken up
+ * from cede in cpu offline.
+ */
+_GLOBAL(start_secondary_resume)
+	ld	r1,PACAKSAVE(r13)	/* Reload kernel stack pointer */
+	li	r3,0
+	std	r3,0(r1)		/* Zero the stack frame pointer	*/
+	bl	.start_secondary
 	b	.
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/head_fsl_booke.S linux-libre-2.6.34-gnu1/arch/powerpc/kernel/head_fsl_booke.S
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/head_fsl_booke.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/head_fsl_booke.S	2010-05-16 17:17:36.000000000 -0400
@@ -214,11 +214,11 @@ skpinv:	addi	r6,r6,1				/* Increment */
 	bl	1f		/* Find our address */
 1:	mflr	r9
 	rlwimi	r7,r9,0,20,31
-	addi	r7,r7,24
+	addi	r7,r7,(2f - 1b)
 	mtspr	SPRN_SRR0,r7
 	mtspr	SPRN_SRR1,r6
 	rfi
-
+2:
 /* 4. Clear out PIDs & Search info */
 	li	r6,0
 	mtspr   SPRN_MAS6,r6
@@ -747,9 +747,6 @@ finish_tlb_load:
 #else
 	rlwimi	r12, r11, 26, 27, 31	/* extract WIMGE from pte */
 #endif
-#ifdef CONFIG_SMP
-	ori	r12, r12, MAS2_M
-#endif
 	mtspr	SPRN_MAS2, r12
 
 #ifdef CONFIG_PTE_64BIT
@@ -887,13 +884,17 @@ KernelSPE:
 	lwz	r3,_MSR(r1)
 	oris	r3,r3,MSR_SPE@h
 	stw	r3,_MSR(r1)	/* enable use of SPE after return */
+#ifdef CONFIG_PRINTK
 	lis	r3,87f@h
 	ori	r3,r3,87f@l
 	mr	r4,r2		/* current */
 	lwz	r5,_NIP(r1)
 	bl	printk
+#endif
 	b	ret_from_except
+#ifdef CONFIG_PRINTK
 87:	.string	"SPE used in kernel  (task=%p, pc=%x)  \n"
+#endif
 	.align	4,0
 
 #endif /* CONFIG_SPE */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/ibmebus.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/ibmebus.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/ibmebus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/ibmebus.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/of.h>
+#include <linux/slab.h>
 #include <linux/of_platform.h>
 #include <asm/ibmebus.h>
 #include <asm/abs_addr.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/iommu.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/iommu.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/iommu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/iommu.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,12 +42,7 @@
 
 #define DBG(...)
 
-#ifdef CONFIG_IOMMU_VMERGE
-static int novmerge = 0;
-#else
-static int novmerge = 1;
-#endif
-
+static int novmerge;
 static int protect4gb = 1;
 
 static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned int);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/irq.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/irq.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,7 +53,6 @@
 #include <linux/bootmem.h>
 #include <linux/pci.h>
 #include <linux/debugfs.h>
-#include <linux/perf_event.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -73,8 +72,10 @@
 #define CREATE_TRACE_POINTS
 #include <asm/trace.h>
 
+DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+EXPORT_PER_CPU_SYMBOL(irq_stat);
+
 int __irq_offset_value;
-static int ppc_spurious_interrupts;
 
 #ifdef CONFIG_PPC32
 EXPORT_SYMBOL(__irq_offset_value);
@@ -143,11 +144,6 @@ notrace void raw_local_irq_restore(unsig
 	}
 #endif /* CONFIG_PPC_STD_MMU_64 */
 
-	if (test_perf_event_pending()) {
-		clear_perf_event_pending();
-		perf_event_do_pending();
-	}
-
 	/*
 	 * if (get_paca()->hard_enabled) return;
 	 * But again we need to take care that gcc gets hard_enabled directly
@@ -180,30 +176,64 @@ notrace void raw_local_irq_restore(unsig
 EXPORT_SYMBOL(raw_local_irq_restore);
 #endif /* CONFIG_PPC64 */
 
+static int show_other_interrupts(struct seq_file *p, int prec)
+{
+	int j;
+
+#if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT)
+	if (tau_initialized) {
+		seq_printf(p, "%*s: ", prec, "TAU");
+		for_each_online_cpu(j)
+			seq_printf(p, "%10u ", tau_interrupts(j));
+		seq_puts(p, "  PowerPC             Thermal Assist (cpu temp)\n");
+	}
+#endif /* CONFIG_PPC32 && CONFIG_TAU_INT */
+
+	seq_printf(p, "%*s: ", prec, "LOC");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", per_cpu(irq_stat, j).timer_irqs);
+        seq_printf(p, "  Local timer interrupts\n");
+
+	seq_printf(p, "%*s: ", prec, "SPU");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", per_cpu(irq_stat, j).spurious_irqs);
+	seq_printf(p, "  Spurious interrupts\n");
+
+	seq_printf(p, "%*s: ", prec, "CNT");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", per_cpu(irq_stat, j).pmu_irqs);
+	seq_printf(p, "  Performance monitoring interrupts\n");
+
+	seq_printf(p, "%*s: ", prec, "MCE");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", per_cpu(irq_stat, j).mce_exceptions);
+	seq_printf(p, "  Machine check exceptions\n");
+
+	return 0;
+}
+
 int show_interrupts(struct seq_file *p, void *v)
 {
-	int i = *(loff_t *)v, j;
+	unsigned long flags, any_count = 0;
+	int i = *(loff_t *) v, j, prec;
 	struct irqaction *action;
 	struct irq_desc *desc;
-	unsigned long flags;
 
+	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, prec);
+
+	/* print header */
 	if (i == 0) {
-		seq_puts(p, "           ");
+		seq_printf(p, "%*s", prec + 8, "");
 		for_each_online_cpu(j)
-			seq_printf(p, "CPU%d       ", j);
+			seq_printf(p, "CPU%-8d", j);
 		seq_putc(p, '\n');
-	} else if (i == nr_irqs) {
-#if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT)
-		if (tau_initialized){
-			seq_puts(p, "TAU: ");
-			for_each_online_cpu(j)
-				seq_printf(p, "%10u ", tau_interrupts(j));
-			seq_puts(p, "  PowerPC             Thermal Assist (cpu temp)\n");
-		}
-#endif /* CONFIG_PPC32 && CONFIG_TAU_INT*/
-		seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
-
-		return 0;
 	}
 
 	desc = irq_to_desc(i);
@@ -211,37 +241,48 @@ int show_interrupts(struct seq_file *p,
 		return 0;
 
 	raw_spin_lock_irqsave(&desc->lock, flags);
-
+	for_each_online_cpu(j)
+		any_count |= kstat_irqs_cpu(i, j);
 	action = desc->action;
-	if (!action || !action->handler)
-		goto skip;
+	if (!action && !any_count)
+		goto out;
 
-	seq_printf(p, "%3d: ", i);
-#ifdef CONFIG_SMP
+	seq_printf(p, "%*d: ", prec, i);
 	for_each_online_cpu(j)
 		seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
-#else
-	seq_printf(p, "%10u ", kstat_irqs(i));
-#endif /* CONFIG_SMP */
 
 	if (desc->chip)
-		seq_printf(p, " %s ", desc->chip->name);
+		seq_printf(p, "  %-16s", desc->chip->name);
 	else
-		seq_puts(p, "  None      ");
+		seq_printf(p, "  %-16s", "None");
+	seq_printf(p, " %-8s", (desc->status & IRQ_LEVEL) ? "Level" : "Edge");
 
-	seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge  ");
-	seq_printf(p, "    %s", action->name);
+	if (action) {
+		seq_printf(p, "     %s", action->name);
+		while ((action = action->next) != NULL)
+			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:
+out:
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
-
 	return 0;
 }
 
+/*
+ * /proc/stat helpers
+ */
+u64 arch_irq_stat_cpu(unsigned int cpu)
+{
+	u64 sum = per_cpu(irq_stat, cpu).timer_irqs;
+
+	sum += per_cpu(irq_stat, cpu).pmu_irqs;
+	sum += per_cpu(irq_stat, cpu).mce_exceptions;
+	sum += per_cpu(irq_stat, cpu).spurious_irqs;
+
+	return sum;
+}
+
 #ifdef CONFIG_HOTPLUG_CPU
 void fixup_irqs(cpumask_t map)
 {
@@ -353,8 +394,7 @@ void do_IRQ(struct pt_regs *regs)
 	if (irq != NO_IRQ && irq != NO_IRQ_IGNORE)
 		handle_one_irq(irq);
 	else if (irq != NO_IRQ_IGNORE)
-		/* That's not SMP safe ... but who cares ? */
-		ppc_spurious_interrupts++;
+		__get_cpu_var(irq_stat).spurious_irqs++;
 
 	irq_exit();
 	set_irq_regs(old_regs);
@@ -474,7 +514,7 @@ void do_softirq(void)
  */
 
 static LIST_HEAD(irq_hosts);
-static DEFINE_SPINLOCK(irq_big_lock);
+static DEFINE_RAW_SPINLOCK(irq_big_lock);
 static unsigned int revmap_trees_allocated;
 static DEFINE_MUTEX(revmap_trees_mutex);
 struct irq_map_entry irq_map[NR_IRQS];
@@ -520,14 +560,14 @@ struct irq_host *irq_alloc_host(struct d
 	if (host->ops->match == NULL)
 		host->ops->match = default_irq_host_match;
 
-	spin_lock_irqsave(&irq_big_lock, flags);
+	raw_spin_lock_irqsave(&irq_big_lock, flags);
 
 	/* If it's a legacy controller, check for duplicates and
 	 * mark it as allocated (we use irq 0 host pointer for that
 	 */
 	if (revmap_type == IRQ_HOST_MAP_LEGACY) {
 		if (irq_map[0].host != NULL) {
-			spin_unlock_irqrestore(&irq_big_lock, flags);
+			raw_spin_unlock_irqrestore(&irq_big_lock, flags);
 			/* If we are early boot, we can't free the structure,
 			 * too bad...
 			 * this will be fixed once slab is made available early
@@ -541,7 +581,7 @@ struct irq_host *irq_alloc_host(struct d
 	}
 
 	list_add(&host->link, &irq_hosts);
-	spin_unlock_irqrestore(&irq_big_lock, flags);
+	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
 
 	/* Additional setups per revmap type */
 	switch(revmap_type) {
@@ -592,13 +632,13 @@ struct irq_host *irq_find_host(struct de
 	 * the absence of a device node. This isn't a problem so far
 	 * yet though...
 	 */
-	spin_lock_irqsave(&irq_big_lock, flags);
+	raw_spin_lock_irqsave(&irq_big_lock, flags);
 	list_for_each_entry(h, &irq_hosts, link)
 		if (h->ops->match(h, node)) {
 			found = h;
 			break;
 		}
-	spin_unlock_irqrestore(&irq_big_lock, flags);
+	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
 	return found;
 }
 EXPORT_SYMBOL_GPL(irq_find_host);
@@ -967,7 +1007,7 @@ unsigned int irq_alloc_virt(struct irq_h
 	if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS))
 		return NO_IRQ;
 
-	spin_lock_irqsave(&irq_big_lock, flags);
+	raw_spin_lock_irqsave(&irq_big_lock, flags);
 
 	/* Use hint for 1 interrupt if any */
 	if (count == 1 && hint >= NUM_ISA_INTERRUPTS &&
@@ -991,7 +1031,7 @@ unsigned int irq_alloc_virt(struct irq_h
 		}
 	}
 	if (found == NO_IRQ) {
-		spin_unlock_irqrestore(&irq_big_lock, flags);
+		raw_spin_unlock_irqrestore(&irq_big_lock, flags);
 		return NO_IRQ;
 	}
  hint_found:
@@ -1000,7 +1040,7 @@ unsigned int irq_alloc_virt(struct irq_h
 		smp_wmb();
 		irq_map[i].host = host;
 	}
-	spin_unlock_irqrestore(&irq_big_lock, flags);
+	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
 	return found;
 }
 
@@ -1012,7 +1052,7 @@ void irq_free_virt(unsigned int virq, un
 	WARN_ON (virq < NUM_ISA_INTERRUPTS);
 	WARN_ON (count == 0 || (virq + count) > irq_virq_count);
 
-	spin_lock_irqsave(&irq_big_lock, flags);
+	raw_spin_lock_irqsave(&irq_big_lock, flags);
 	for (i = virq; i < (virq + count); i++) {
 		struct irq_host *host;
 
@@ -1025,7 +1065,7 @@ void irq_free_virt(unsigned int virq, un
 		smp_wmb();
 		irq_map[i].host = NULL;
 	}
-	spin_unlock_irqrestore(&irq_big_lock, flags);
+	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
 }
 
 int arch_early_irq_init(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/kgdb.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/kgdb.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/kgdb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/kgdb.c	2010-05-16 17:17:36.000000000 -0400
@@ -333,7 +333,7 @@ int kgdb_arch_handle_exception(int vecto
 		atomic_set(&kgdb_cpu_doing_single_step, -1);
 		/* set the trace bit if we're stepping */
 		if (remcom_in_buffer[0] == 's') {
-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
 			mtspr(SPRN_DBCR0,
 			      mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
 			linux_regs->msr |= MSR_DE;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/kprobes.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/kprobes.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/kprobes.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/kprobes.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,12 +31,13 @@
 #include <linux/preempt.h>
 #include <linux/module.h>
 #include <linux/kdebug.h>
+#include <linux/slab.h>
 #include <asm/cacheflush.h>
 #include <asm/sstep.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-#ifdef CONFIG_BOOKE
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
 #define MSR_SINGLESTEP	(MSR_DE)
 #else
 #define MSR_SINGLESTEP	(MSR_SE)
@@ -110,7 +111,7 @@ static void __kprobes prepare_singlestep
 	 * like Decrementer or External Interrupt */
 	regs->msr &= ~MSR_EE;
 	regs->msr |= MSR_SINGLESTEP;
-#ifdef CONFIG_BOOKE
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
 	regs->msr &= ~MSR_CE;
 	mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/legacy_serial.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/legacy_serial.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/legacy_serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/legacy_serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -469,7 +469,7 @@ static int __init serial_dev_init(void)
 		return -ENODEV;
 
 	/*
-	 * Before we register the platfrom serial devices, we need
+	 * Before we register the platform serial devices, we need
 	 * to fixup their interrupts and their IO ports.
 	 */
 	DBG("Fixing serial ports interrupts and IO ports ...\n");
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/lparcfg.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/lparcfg.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/lparcfg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/lparcfg.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/iseries/hv_lp_config.h>
 #include <asm/lppaca.h>
@@ -359,7 +360,7 @@ static void parse_system_parameter_strin
 
 	unsigned char *local_buffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
 	if (!local_buffer) {
-		printk(KERN_ERR "%s %s kmalloc failure at line %d \n",
+		printk(KERN_ERR "%s %s kmalloc failure at line %d\n",
 		       __FILE__, __func__, __LINE__);
 		return;
 	}
@@ -383,13 +384,13 @@ static void parse_system_parameter_strin
 		int idx, w_idx;
 		char *workbuffer = kzalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
 		if (!workbuffer) {
-			printk(KERN_ERR "%s %s kmalloc failure at line %d \n",
+			printk(KERN_ERR "%s %s kmalloc failure at line %d\n",
 			       __FILE__, __func__, __LINE__);
 			kfree(local_buffer);
 			return;
 		}
 #ifdef LPARCFG_DEBUG
-		printk(KERN_INFO "success calling get-system-parameter \n");
+		printk(KERN_INFO "success calling get-system-parameter\n");
 #endif
 		splpar_strlen = local_buffer[0] * 256 + local_buffer[1];
 		local_buffer += 2;	/* step over strlen value */
@@ -440,7 +441,7 @@ static int lparcfg_count_active_processo
 
 	while ((cpus_dn = of_find_node_by_type(cpus_dn, "cpu"))) {
 #ifdef LPARCFG_DEBUG
-		printk(KERN_ERR "cpus_dn %p \n", cpus_dn);
+		printk(KERN_ERR "cpus_dn %p\n", cpus_dn);
 #endif
 		count++;
 	}
@@ -725,7 +726,7 @@ static int lparcfg_data(struct seq_file
 	const unsigned int *lp_index_ptr;
 	unsigned int lp_index = 0;
 
-	seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
+	seq_printf(m, "%s %s\n", MODULE_NAME, MODULE_VERS);
 
 	rootdn = of_find_node_by_path("/");
 	if (rootdn) {
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/Makefile linux-libre-2.6.34-gnu1/arch/powerpc/kernel/Makefile
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -98,11 +98,16 @@ obj64-$(CONFIG_AUDIT)		+= compat_audit.o
 
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
-obj-$(CONFIG_PPC_PERF_CTRS)	+= perf_event.o perf_callchain.o
+obj-$(CONFIG_PERF_EVENTS)	+= perf_callchain.o
+
+obj-$(CONFIG_PPC_PERF_CTRS)	+= perf_event.o
 obj64-$(CONFIG_PPC_PERF_CTRS)	+= power4-pmu.o ppc970-pmu.o power5-pmu.o \
 				   power5+-pmu.o power6-pmu.o power7-pmu.o
 obj32-$(CONFIG_PPC_PERF_CTRS)	+= mpc7450-pmu.o
 
+obj-$(CONFIG_FSL_EMB_PERF_EVENT) += perf_event_fsl_emb.o
+obj-$(CONFIG_FSL_EMB_PERF_EVENT_E500) += e500-pmu.o
+
 obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o
 
 ifneq ($(CONFIG_PPC_INDIRECT_IO),y)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/misc.S linux-libre-2.6.34-gnu1/arch/powerpc/kernel/misc.S
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/misc.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/misc.S	2010-05-16 17:17:36.000000000 -0400
@@ -127,3 +127,29 @@ _GLOBAL(__setup_cpu_power7)
 _GLOBAL(__restore_cpu_power7)
 	/* place holder */
 	blr
+
+/*
+ * Get a minimal set of registers for our caller's nth caller.
+ * r3 = regs pointer, r5 = n.
+ *
+ * We only get R1 (stack pointer), NIP (next instruction pointer)
+ * and LR (link register).  These are all we can get in the
+ * general case without doing complicated stack unwinding, but
+ * fortunately they are enough to do a stack backtrace, which
+ * is all we need them for.
+ */
+_GLOBAL(perf_arch_fetch_caller_regs)
+	mr	r6,r1
+	cmpwi	r5,0
+	mflr	r4
+	ble	2f
+	mtctr	r5
+1:	PPC_LL	r6,0(r6)
+	bdnz	1b
+	PPC_LL	r4,PPC_LR_STKOFF(r6)
+2:	PPC_LL	r7,0(r6)
+	PPC_LL	r7,PPC_LR_STKOFF(r7)
+	PPC_STL	r6,GPR1-STACK_FRAME_OVERHEAD(r3)
+	PPC_STL	r4,_NIP-STACK_FRAME_OVERHEAD(r3)
+	PPC_STL	r7,_LINK-STACK_FRAME_OVERHEAD(r3)
+	blr
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/nvram_64.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/nvram_64.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/nvram_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/nvram_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -338,8 +338,8 @@ static int __init nvram_create_os_partit
 
 	rc = nvram_write_header(new_part);
 	if (rc <= 0) {
-		printk(KERN_ERR "nvram_create_os_partition: nvram_write_header \
-				failed (%d)\n", rc);
+		printk(KERN_ERR "nvram_create_os_partition: nvram_write_header "
+				"failed (%d)\n", rc);
 		return rc;
 	}
 
@@ -349,7 +349,7 @@ static int __init nvram_create_os_partit
 	rc = ppc_md.nvram_write((char *)&seq_init, sizeof(seq_init), &tmp_index);
 	if (rc <= 0) {
 		printk(KERN_ERR "nvram_create_os_partition: nvram_write "
-				"failed (%d)\n", rc);
+		       "failed (%d)\n", rc);
 		return rc;
 	}
 	
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/of_platform.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/of_platform.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/of_platform.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/of_platform.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #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>
@@ -214,7 +213,7 @@ 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;
+	return to_of_device(dev)->node->phandle == *ph;
 }
 
 struct of_device *of_find_device_by_phandle(phandle ph)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/paca.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/paca.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/paca.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/paca.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,11 +9,15 @@
 
 #include <linux/threads.h>
 #include <linux/module.h>
+#include <linux/lmb.h>
 
+#include <asm/firmware.h>
 #include <asm/lppaca.h>
 #include <asm/paca.h>
 #include <asm/sections.h>
 #include <asm/pgtable.h>
+#include <asm/iseries/lpar_map.h>
+#include <asm/iseries/hv_types.h>
 
 /* This symbol is provided by the linker - let it fill in the paca
  * field correctly */
@@ -70,37 +74,82 @@ struct slb_shadow slb_shadow[] __cacheli
  * processors.  The processor VPD array needs one entry per physical
  * processor (not thread).
  */
-struct paca_struct paca[NR_CPUS];
+struct paca_struct *paca;
 EXPORT_SYMBOL(paca);
 
-void __init initialise_pacas(void)
-{
-	int cpu;
+struct paca_struct boot_paca;
 
-	/* The TOC register (GPR2) points 32kB into the TOC, so that 64kB
-	 * of the TOC can be addressed using a single machine instruction.
-	 */
+void __init initialise_paca(struct paca_struct *new_paca, int cpu)
+{
+       /* The TOC register (GPR2) points 32kB into the TOC, so that 64kB
+	* of the TOC can be addressed using a single machine instruction.
+	*/
 	unsigned long kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL;
 
-	/* Can't use for_each_*_cpu, as they aren't functional yet */
-	for (cpu = 0; cpu < NR_CPUS; cpu++) {
-		struct paca_struct *new_paca = &paca[cpu];
-
 #ifdef CONFIG_PPC_BOOK3S
-		new_paca->lppaca_ptr = &lppaca[cpu];
+	new_paca->lppaca_ptr = &lppaca[cpu];
 #else
-		new_paca->kernel_pgd = swapper_pg_dir;
+	new_paca->kernel_pgd = swapper_pg_dir;
 #endif
-		new_paca->lock_token = 0x8000;
-		new_paca->paca_index = cpu;
-		new_paca->kernel_toc = kernel_toc;
-		new_paca->kernelbase = (unsigned long) _stext;
-		new_paca->kernel_msr = MSR_KERNEL;
-		new_paca->hw_cpu_id = 0xffff;
-		new_paca->__current = &init_task;
+	new_paca->lock_token = 0x8000;
+	new_paca->paca_index = cpu;
+	new_paca->kernel_toc = kernel_toc;
+	new_paca->kernelbase = (unsigned long) _stext;
+	new_paca->kernel_msr = MSR_KERNEL;
+	new_paca->hw_cpu_id = 0xffff;
+	new_paca->__current = &init_task;
 #ifdef CONFIG_PPC_STD_MMU_64
-		new_paca->slb_shadow_ptr = &slb_shadow[cpu];
+	new_paca->slb_shadow_ptr = &slb_shadow[cpu];
 #endif /* CONFIG_PPC_STD_MMU_64 */
+}
 
-	}
+static int __initdata paca_size;
+
+void __init allocate_pacas(void)
+{
+	int nr_cpus, cpu, limit;
+
+	/*
+	 * We can't take SLB misses on the paca, and we want to access them
+	 * in real mode, so allocate them within the RMA and also within
+	 * the first segment. On iSeries they must be within the area mapped
+	 * by the HV, which is HvPagesToMap * HVPAGESIZE bytes.
+	 */
+	limit = min(0x10000000ULL, lmb.rmo_size);
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		limit = min(limit, HvPagesToMap * HVPAGESIZE);
+
+	nr_cpus = NR_CPUS;
+	/* On iSeries we know we can never have more than 64 cpus */
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		nr_cpus = min(64, nr_cpus);
+
+	paca_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpus);
+
+	paca = __va(lmb_alloc_base(paca_size, PAGE_SIZE, limit));
+	memset(paca, 0, paca_size);
+
+	printk(KERN_DEBUG "Allocated %u bytes for %d pacas at %p\n",
+		paca_size, nr_cpus, paca);
+
+	/* Can't use for_each_*_cpu, as they aren't functional yet */
+	for (cpu = 0; cpu < nr_cpus; cpu++)
+		initialise_paca(&paca[cpu], cpu);
+}
+
+void __init free_unused_pacas(void)
+{
+	int new_size;
+
+	new_size = PAGE_ALIGN(sizeof(struct paca_struct) * num_possible_cpus());
+
+	if (new_size >= paca_size)
+		return;
+
+	lmb_free(__pa(paca) + new_size, paca_size - new_size);
+
+	printk(KERN_DEBUG "Freed %u bytes for unused pacas\n",
+		paca_size - new_size);
+
+	paca_size = new_size;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pci_32.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/pci_32.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pci_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/pci_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/irq.h>
 #include <linux/list.h>
 #include <linux/of.h>
+#include <linux/slab.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pci_64.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/pci_64.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pci_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/pci_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -224,7 +224,7 @@ long sys_pciconfig_iobase(long which, un
 	 * G5 machines... So when something asks for bus 0 io base
 	 * (bus 0 is HT root), we return the AGP one instead.
 	 */
-	if (in_bus == 0 && machine_is_compatible("MacRISC4")) {
+	if (in_bus == 0 && of_machine_is_compatible("MacRISC4")) {
 		struct device_node *agp;
 
 		agp = of_find_compatible_node(NULL, NULL, "u3-agp");
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pci-common.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/pci-common.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pci-common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/pci-common.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/syscalls.h>
 #include <linux/irq.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
@@ -63,21 +64,6 @@ struct dma_map_ops *get_pci_dma_ops(void
 }
 EXPORT_SYMBOL(get_pci_dma_ops);
 
-int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
-	return dma_set_mask(&dev->dev, mask);
-}
-
-int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
-	int rc;
-
-	rc = dma_set_mask(&dev->dev, mask);
-	dev->dev.coherent_dma_mask = dev->dma_mask;
-
-	return rc;
-}
-
 struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
 {
 	struct pci_controller *phb;
@@ -1047,10 +1033,8 @@ static void __devinit pcibios_fixup_brid
 
 	struct pci_dev *dev = bus->self;
 
-	for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
-		if ((res = bus->resource[i]) == NULL)
-			continue;
-		if (!res->flags)
+	pci_bus_for_each_resource(bus, res, i) {
+		if (!res || !res->flags)
 			continue;
 		if (i >= 3 && bus->self->transparent)
 			continue;
@@ -1181,21 +1165,20 @@ static int skip_isa_ioresource_align(str
  * but we want to try to avoid allocating at 0x2900-0x2bff
  * which might have be mirrored at 0x0100-0x03ff..
  */
-void pcibios_align_resource(void *data, struct resource *res,
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 				resource_size_t size, resource_size_t align)
 {
 	struct pci_dev *dev = data;
+	resource_size_t start = res->start;
 
 	if (res->flags & IORESOURCE_IO) {
-		resource_size_t start = res->start;
-
 		if (skip_isa_ioresource_align(dev))
-			return;
-		if (start & 0x300) {
+			return start;
+		if (start & 0x300)
 			start = (start + 0x3ff) & ~0x3ff;
-			res->start = start;
-		}
 	}
+
+	return start;
 }
 EXPORT_SYMBOL(pcibios_align_resource);
 
@@ -1278,9 +1261,8 @@ void pcibios_allocate_bus_resources(stru
 	pr_debug("PCI: Allocating bus resources for %04x:%02x...\n",
 		 pci_domain_nr(bus), bus->number);
 
-	for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
-		if ((res = bus->resource[i]) == NULL || !res->flags
-		    || res->start > res->end || res->parent)
+	pci_bus_for_each_resource(bus, res, i) {
+		if (!res || !res->flags || res->start > res->end || res->parent)
 			continue;
 		if (bus->parent == NULL)
 			pr = (res->flags & IORESOURCE_IO) ?
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pci_dn.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/pci_dn.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pci_dn.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/pci_dn.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/string.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pci_of_scan.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/pci_of_scan.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pci_of_scan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/pci_of_scan.c	2010-05-16 17:17:36.000000000 -0400
@@ -304,7 +304,7 @@ static void __devinit __of_scan_bus(stru
 	int reglen, devfn;
 	struct pci_dev *dev;
 
-	pr_debug("of_scan_bus(%s) bus no %d... \n",
+	pr_debug("of_scan_bus(%s) bus no %d...\n",
 		 node->full_name, bus->number);
 
 	/* Scan direct children */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/perf_callchain.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/perf_callchain.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/perf_callchain.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/perf_callchain.c	2010-05-16 17:17:36.000000000 -0400
@@ -495,9 +495,6 @@ struct perf_callchain_entry *perf_callch
 
 	entry->nr = 0;
 
-	if (current->pid == 0)		/* idle task? */
-		return entry;
-
 	if (!user_mode(regs)) {
 		perf_callchain_kernel(regs, entry);
 		if (current->mm)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/perf_event.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/perf_event.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/perf_event.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/perf_event.c	2010-05-16 17:17:36.000000000 -0400
@@ -718,10 +718,10 @@ static int collect_events(struct perf_ev
 	return n;
 }
 
-static void event_sched_in(struct perf_event *event, int cpu)
+static void event_sched_in(struct perf_event *event)
 {
 	event->state = PERF_EVENT_STATE_ACTIVE;
-	event->oncpu = cpu;
+	event->oncpu = smp_processor_id();
 	event->tstamp_running += event->ctx->time - event->tstamp_stopped;
 	if (is_software_event(event))
 		event->pmu->enable(event);
@@ -735,7 +735,7 @@ static void event_sched_in(struct perf_e
  */
 int hw_perf_group_sched_in(struct perf_event *group_leader,
 	       struct perf_cpu_context *cpuctx,
-	       struct perf_event_context *ctx, int cpu)
+	       struct perf_event_context *ctx)
 {
 	struct cpu_hw_events *cpuhw;
 	long i, n, n0;
@@ -766,10 +766,10 @@ int hw_perf_group_sched_in(struct perf_e
 		cpuhw->event[i]->hw.config = cpuhw->events[i];
 	cpuctx->active_oncpu += n;
 	n = 1;
-	event_sched_in(group_leader, cpu);
+	event_sched_in(group_leader);
 	list_for_each_entry(sub, &group_leader->sibling_list, group_entry) {
 		if (sub->state != PERF_EVENT_STATE_OFF) {
-			event_sched_in(sub, cpu);
+			event_sched_in(sub);
 			++n;
 		}
 	}
@@ -1164,10 +1164,10 @@ static void record_and_restart(struct pe
 	 * Finally record data if requested.
 	 */
 	if (record) {
-		struct perf_sample_data data = {
-			.addr	= ~0ULL,
-			.period	= event->hw.last_period,
-		};
+		struct perf_sample_data data;
+
+		perf_sample_data_init(&data, ~0ULL);
+		data.period = event->hw.last_period;
 
 		if (event->attr.sample_type & PERF_SAMPLE_ADDR)
 			perf_get_data_addr(regs, &data.addr);
@@ -1287,7 +1287,7 @@ static void perf_event_interrupt(struct
 		irq_exit();
 }
 
-void hw_perf_event_setup(int cpu)
+static void power_pmu_setup(int cpu)
 {
 	struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
 
@@ -1297,6 +1297,23 @@ void hw_perf_event_setup(int cpu)
 	cpuhw->mmcr[0] = MMCR0_FC;
 }
 
+static int __cpuinit
+power_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (long)hcpu;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+		power_pmu_setup(cpu);
+		break;
+
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
 int register_power_pmu(struct power_pmu *pmu)
 {
 	if (ppmu)
@@ -1314,5 +1331,7 @@ int register_power_pmu(struct power_pmu
 		freeze_events_kernel = MMCR0_FCHV;
 #endif /* CONFIG_PPC64 */
 
+	perf_cpu_notifier(power_pmu_notifier);
+
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/perf_event_fsl_emb.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/perf_event_fsl_emb.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/perf_event_fsl_emb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/perf_event_fsl_emb.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,654 @@
+/*
+ * Performance event support - Freescale Embedded Performance Monitor
+ *
+ * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
+ * Copyright 2010 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/sched.h>
+#include <linux/perf_event.h>
+#include <linux/percpu.h>
+#include <linux/hardirq.h>
+#include <asm/reg_fsl_emb.h>
+#include <asm/pmc.h>
+#include <asm/machdep.h>
+#include <asm/firmware.h>
+#include <asm/ptrace.h>
+
+struct cpu_hw_events {
+	int n_events;
+	int disabled;
+	u8  pmcs_enabled;
+	struct perf_event *event[MAX_HWEVENTS];
+};
+static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
+
+static struct fsl_emb_pmu *ppmu;
+
+/* Number of perf_events counting hardware events */
+static atomic_t num_events;
+/* Used to avoid races in calling reserve/release_pmc_hardware */
+static DEFINE_MUTEX(pmc_reserve_mutex);
+
+/*
+ * If interrupts were soft-disabled when a PMU interrupt occurs, treat
+ * it as an NMI.
+ */
+static inline int perf_intr_is_nmi(struct pt_regs *regs)
+{
+#ifdef __powerpc64__
+	return !regs->softe;
+#else
+	return 0;
+#endif
+}
+
+static void perf_event_interrupt(struct pt_regs *regs);
+
+/*
+ * Read one performance monitor counter (PMC).
+ */
+static unsigned long read_pmc(int idx)
+{
+	unsigned long val;
+
+	switch (idx) {
+	case 0:
+		val = mfpmr(PMRN_PMC0);
+		break;
+	case 1:
+		val = mfpmr(PMRN_PMC1);
+		break;
+	case 2:
+		val = mfpmr(PMRN_PMC2);
+		break;
+	case 3:
+		val = mfpmr(PMRN_PMC3);
+		break;
+	default:
+		printk(KERN_ERR "oops trying to read PMC%d\n", idx);
+		val = 0;
+	}
+	return val;
+}
+
+/*
+ * Write one PMC.
+ */
+static void write_pmc(int idx, unsigned long val)
+{
+	switch (idx) {
+	case 0:
+		mtpmr(PMRN_PMC0, val);
+		break;
+	case 1:
+		mtpmr(PMRN_PMC1, val);
+		break;
+	case 2:
+		mtpmr(PMRN_PMC2, val);
+		break;
+	case 3:
+		mtpmr(PMRN_PMC3, val);
+		break;
+	default:
+		printk(KERN_ERR "oops trying to write PMC%d\n", idx);
+	}
+
+	isync();
+}
+
+/*
+ * Write one local control A register
+ */
+static void write_pmlca(int idx, unsigned long val)
+{
+	switch (idx) {
+	case 0:
+		mtpmr(PMRN_PMLCA0, val);
+		break;
+	case 1:
+		mtpmr(PMRN_PMLCA1, val);
+		break;
+	case 2:
+		mtpmr(PMRN_PMLCA2, val);
+		break;
+	case 3:
+		mtpmr(PMRN_PMLCA3, val);
+		break;
+	default:
+		printk(KERN_ERR "oops trying to write PMLCA%d\n", idx);
+	}
+
+	isync();
+}
+
+/*
+ * Write one local control B register
+ */
+static void write_pmlcb(int idx, unsigned long val)
+{
+	switch (idx) {
+	case 0:
+		mtpmr(PMRN_PMLCB0, val);
+		break;
+	case 1:
+		mtpmr(PMRN_PMLCB1, val);
+		break;
+	case 2:
+		mtpmr(PMRN_PMLCB2, val);
+		break;
+	case 3:
+		mtpmr(PMRN_PMLCB3, val);
+		break;
+	default:
+		printk(KERN_ERR "oops trying to write PMLCB%d\n", idx);
+	}
+
+	isync();
+}
+
+static void fsl_emb_pmu_read(struct perf_event *event)
+{
+	s64 val, delta, prev;
+
+	/*
+	 * Performance monitor interrupts come even when interrupts
+	 * are soft-disabled, as long as interrupts are hard-enabled.
+	 * Therefore we treat them like NMIs.
+	 */
+	do {
+		prev = atomic64_read(&event->hw.prev_count);
+		barrier();
+		val = read_pmc(event->hw.idx);
+	} while (atomic64_cmpxchg(&event->hw.prev_count, prev, val) != prev);
+
+	/* The counters are only 32 bits wide */
+	delta = (val - prev) & 0xfffffffful;
+	atomic64_add(delta, &event->count);
+	atomic64_sub(delta, &event->hw.period_left);
+}
+
+/*
+ * Disable all events to prevent PMU interrupts and to allow
+ * events to be added or removed.
+ */
+void hw_perf_disable(void)
+{
+	struct cpu_hw_events *cpuhw;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	cpuhw = &__get_cpu_var(cpu_hw_events);
+
+	if (!cpuhw->disabled) {
+		cpuhw->disabled = 1;
+
+		/*
+		 * Check if we ever enabled the PMU on this cpu.
+		 */
+		if (!cpuhw->pmcs_enabled) {
+			ppc_enable_pmcs();
+			cpuhw->pmcs_enabled = 1;
+		}
+
+		if (atomic_read(&num_events)) {
+			/*
+			 * Set the 'freeze all counters' bit, and disable
+			 * interrupts.  The barrier is to make sure the
+			 * mtpmr has been executed and the PMU has frozen
+			 * the events before we return.
+			 */
+
+			mtpmr(PMRN_PMGC0, PMGC0_FAC);
+			isync();
+		}
+	}
+	local_irq_restore(flags);
+}
+
+/*
+ * Re-enable all events if disable == 0.
+ * If we were previously disabled and events were added, then
+ * put the new config on the PMU.
+ */
+void hw_perf_enable(void)
+{
+	struct cpu_hw_events *cpuhw;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	cpuhw = &__get_cpu_var(cpu_hw_events);
+	if (!cpuhw->disabled)
+		goto out;
+
+	cpuhw->disabled = 0;
+	ppc_set_pmu_inuse(cpuhw->n_events != 0);
+
+	if (cpuhw->n_events > 0) {
+		mtpmr(PMRN_PMGC0, PMGC0_PMIE | PMGC0_FCECE);
+		isync();
+	}
+
+ out:
+	local_irq_restore(flags);
+}
+
+static int collect_events(struct perf_event *group, int max_count,
+			  struct perf_event *ctrs[])
+{
+	int n = 0;
+	struct perf_event *event;
+
+	if (!is_software_event(group)) {
+		if (n >= max_count)
+			return -1;
+		ctrs[n] = group;
+		n++;
+	}
+	list_for_each_entry(event, &group->sibling_list, group_entry) {
+		if (!is_software_event(event) &&
+		    event->state != PERF_EVENT_STATE_OFF) {
+			if (n >= max_count)
+				return -1;
+			ctrs[n] = event;
+			n++;
+		}
+	}
+	return n;
+}
+
+/* perf must be disabled, context locked on entry */
+static int fsl_emb_pmu_enable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuhw;
+	int ret = -EAGAIN;
+	int num_counters = ppmu->n_counter;
+	u64 val;
+	int i;
+
+	cpuhw = &get_cpu_var(cpu_hw_events);
+
+	if (event->hw.config & FSL_EMB_EVENT_RESTRICTED)
+		num_counters = ppmu->n_restricted;
+
+	/*
+	 * Allocate counters from top-down, so that restricted-capable
+	 * counters are kept free as long as possible.
+	 */
+	for (i = num_counters - 1; i >= 0; i--) {
+		if (cpuhw->event[i])
+			continue;
+
+		break;
+	}
+
+	if (i < 0)
+		goto out;
+
+	event->hw.idx = i;
+	cpuhw->event[i] = event;
+	++cpuhw->n_events;
+
+	val = 0;
+	if (event->hw.sample_period) {
+		s64 left = atomic64_read(&event->hw.period_left);
+		if (left < 0x80000000L)
+			val = 0x80000000L - left;
+	}
+	atomic64_set(&event->hw.prev_count, val);
+	write_pmc(i, val);
+	perf_event_update_userpage(event);
+
+	write_pmlcb(i, event->hw.config >> 32);
+	write_pmlca(i, event->hw.config_base);
+
+	ret = 0;
+ out:
+	put_cpu_var(cpu_hw_events);
+	return ret;
+}
+
+/* perf must be disabled, context locked on entry */
+static void fsl_emb_pmu_disable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuhw;
+	int i = event->hw.idx;
+
+	if (i < 0)
+		goto out;
+
+	fsl_emb_pmu_read(event);
+
+	cpuhw = &get_cpu_var(cpu_hw_events);
+
+	WARN_ON(event != cpuhw->event[event->hw.idx]);
+
+	write_pmlca(i, 0);
+	write_pmlcb(i, 0);
+	write_pmc(i, 0);
+
+	cpuhw->event[i] = NULL;
+	event->hw.idx = -1;
+
+	/*
+	 * TODO: if at least one restricted event exists, and we
+	 * just freed up a non-restricted-capable counter, and
+	 * there is a restricted-capable counter occupied by
+	 * a non-restricted event, migrate that event to the
+	 * vacated counter.
+	 */
+
+	cpuhw->n_events--;
+
+ out:
+	put_cpu_var(cpu_hw_events);
+}
+
+/*
+ * Re-enable interrupts on a event after they were throttled
+ * because they were coming too fast.
+ *
+ * Context is locked on entry, but perf is not disabled.
+ */
+static void fsl_emb_pmu_unthrottle(struct perf_event *event)
+{
+	s64 val, left;
+	unsigned long flags;
+
+	if (event->hw.idx < 0 || !event->hw.sample_period)
+		return;
+	local_irq_save(flags);
+	perf_disable();
+	fsl_emb_pmu_read(event);
+	left = event->hw.sample_period;
+	event->hw.last_period = left;
+	val = 0;
+	if (left < 0x80000000L)
+		val = 0x80000000L - left;
+	write_pmc(event->hw.idx, val);
+	atomic64_set(&event->hw.prev_count, val);
+	atomic64_set(&event->hw.period_left, left);
+	perf_event_update_userpage(event);
+	perf_enable();
+	local_irq_restore(flags);
+}
+
+static struct pmu fsl_emb_pmu = {
+	.enable		= fsl_emb_pmu_enable,
+	.disable	= fsl_emb_pmu_disable,
+	.read		= fsl_emb_pmu_read,
+	.unthrottle	= fsl_emb_pmu_unthrottle,
+};
+
+/*
+ * Release the PMU if this is the last perf_event.
+ */
+static void hw_perf_event_destroy(struct perf_event *event)
+{
+	if (!atomic_add_unless(&num_events, -1, 1)) {
+		mutex_lock(&pmc_reserve_mutex);
+		if (atomic_dec_return(&num_events) == 0)
+			release_pmc_hardware();
+		mutex_unlock(&pmc_reserve_mutex);
+	}
+}
+
+/*
+ * Translate a generic cache event_id config to a raw event_id code.
+ */
+static int hw_perf_cache_event(u64 config, u64 *eventp)
+{
+	unsigned long type, op, result;
+	int ev;
+
+	if (!ppmu->cache_events)
+		return -EINVAL;
+
+	/* unpack config */
+	type = config & 0xff;
+	op = (config >> 8) & 0xff;
+	result = (config >> 16) & 0xff;
+
+	if (type >= PERF_COUNT_HW_CACHE_MAX ||
+	    op >= PERF_COUNT_HW_CACHE_OP_MAX ||
+	    result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+		return -EINVAL;
+
+	ev = (*ppmu->cache_events)[type][op][result];
+	if (ev == 0)
+		return -EOPNOTSUPP;
+	if (ev == -1)
+		return -EINVAL;
+	*eventp = ev;
+	return 0;
+}
+
+const struct pmu *hw_perf_event_init(struct perf_event *event)
+{
+	u64 ev;
+	struct perf_event *events[MAX_HWEVENTS];
+	int n;
+	int err;
+	int num_restricted;
+	int i;
+
+	switch (event->attr.type) {
+	case PERF_TYPE_HARDWARE:
+		ev = event->attr.config;
+		if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0)
+			return ERR_PTR(-EOPNOTSUPP);
+		ev = ppmu->generic_events[ev];
+		break;
+
+	case PERF_TYPE_HW_CACHE:
+		err = hw_perf_cache_event(event->attr.config, &ev);
+		if (err)
+			return ERR_PTR(err);
+		break;
+
+	case PERF_TYPE_RAW:
+		ev = event->attr.config;
+		break;
+
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+
+	event->hw.config = ppmu->xlate_event(ev);
+	if (!(event->hw.config & FSL_EMB_EVENT_VALID))
+		return ERR_PTR(-EINVAL);
+
+	/*
+	 * If this is in a group, check if it can go on with all the
+	 * other hardware events in the group.  We assume the event
+	 * hasn't been linked into its leader's sibling list at this point.
+	 */
+	n = 0;
+	if (event->group_leader != event) {
+		n = collect_events(event->group_leader,
+		                   ppmu->n_counter - 1, events);
+		if (n < 0)
+			return ERR_PTR(-EINVAL);
+	}
+
+	if (event->hw.config & FSL_EMB_EVENT_RESTRICTED) {
+		num_restricted = 0;
+		for (i = 0; i < n; i++) {
+			if (events[i]->hw.config & FSL_EMB_EVENT_RESTRICTED)
+				num_restricted++;
+		}
+
+		if (num_restricted >= ppmu->n_restricted)
+			return ERR_PTR(-EINVAL);
+	}
+
+	event->hw.idx = -1;
+
+	event->hw.config_base = PMLCA_CE | PMLCA_FCM1 |
+	                        (u32)((ev << 16) & PMLCA_EVENT_MASK);
+
+	if (event->attr.exclude_user)
+		event->hw.config_base |= PMLCA_FCU;
+	if (event->attr.exclude_kernel)
+		event->hw.config_base |= PMLCA_FCS;
+	if (event->attr.exclude_idle)
+		return ERR_PTR(-ENOTSUPP);
+
+	event->hw.last_period = event->hw.sample_period;
+	atomic64_set(&event->hw.period_left, event->hw.last_period);
+
+	/*
+	 * See if we need to reserve the PMU.
+	 * If no events are currently in use, then we have to take a
+	 * mutex to ensure that we don't race with another task doing
+	 * reserve_pmc_hardware or release_pmc_hardware.
+	 */
+	err = 0;
+	if (!atomic_inc_not_zero(&num_events)) {
+		mutex_lock(&pmc_reserve_mutex);
+		if (atomic_read(&num_events) == 0 &&
+		    reserve_pmc_hardware(perf_event_interrupt))
+			err = -EBUSY;
+		else
+			atomic_inc(&num_events);
+		mutex_unlock(&pmc_reserve_mutex);
+
+		mtpmr(PMRN_PMGC0, PMGC0_FAC);
+		isync();
+	}
+	event->destroy = hw_perf_event_destroy;
+
+	if (err)
+		return ERR_PTR(err);
+	return &fsl_emb_pmu;
+}
+
+/*
+ * A counter has overflowed; update its count and record
+ * things if requested.  Note that interrupts are hard-disabled
+ * here so there is no possibility of being interrupted.
+ */
+static void record_and_restart(struct perf_event *event, unsigned long val,
+			       struct pt_regs *regs, int nmi)
+{
+	u64 period = event->hw.sample_period;
+	s64 prev, delta, left;
+	int record = 0;
+
+	/* we don't have to worry about interrupts here */
+	prev = atomic64_read(&event->hw.prev_count);
+	delta = (val - prev) & 0xfffffffful;
+	atomic64_add(delta, &event->count);
+
+	/*
+	 * See if the total period for this event has expired,
+	 * and update for the next period.
+	 */
+	val = 0;
+	left = atomic64_read(&event->hw.period_left) - delta;
+	if (period) {
+		if (left <= 0) {
+			left += period;
+			if (left <= 0)
+				left = period;
+			record = 1;
+		}
+		if (left < 0x80000000LL)
+			val = 0x80000000LL - left;
+	}
+
+	/*
+	 * Finally record data if requested.
+	 */
+	if (record) {
+		struct perf_sample_data data = {
+			.period	= event->hw.last_period,
+		};
+
+		if (perf_event_overflow(event, nmi, &data, regs)) {
+			/*
+			 * Interrupts are coming too fast - throttle them
+			 * by setting the event to 0, so it will be
+			 * at least 2^30 cycles until the next interrupt
+			 * (assuming each event counts at most 2 counts
+			 * per cycle).
+			 */
+			val = 0;
+			left = ~0ULL >> 1;
+		}
+	}
+
+	write_pmc(event->hw.idx, val);
+	atomic64_set(&event->hw.prev_count, val);
+	atomic64_set(&event->hw.period_left, left);
+	perf_event_update_userpage(event);
+}
+
+static void perf_event_interrupt(struct pt_regs *regs)
+{
+	int i;
+	struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+	struct perf_event *event;
+	unsigned long val;
+	int found = 0;
+	int nmi;
+
+	nmi = perf_intr_is_nmi(regs);
+	if (nmi)
+		nmi_enter();
+	else
+		irq_enter();
+
+	for (i = 0; i < ppmu->n_counter; ++i) {
+		event = cpuhw->event[i];
+
+		val = read_pmc(i);
+		if ((int)val < 0) {
+			if (event) {
+				/* event has overflowed */
+				found = 1;
+				record_and_restart(event, val, regs, nmi);
+			} else {
+				/*
+				 * Disabled counter is negative,
+				 * reset it just in case.
+				 */
+				write_pmc(i, 0);
+			}
+		}
+	}
+
+	/* PMM will keep counters frozen until we return from the interrupt. */
+	mtmsr(mfmsr() | MSR_PMM);
+	mtpmr(PMRN_PMGC0, PMGC0_PMIE | PMGC0_FCECE);
+	isync();
+
+	if (nmi)
+		nmi_exit();
+	else
+		irq_exit();
+}
+
+void hw_perf_event_setup(int cpu)
+{
+	struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
+
+	memset(cpuhw, 0, sizeof(*cpuhw));
+}
+
+int register_fsl_emb_pmu(struct fsl_emb_pmu *pmu)
+{
+	if (ppmu)
+		return -EBUSY;		/* something's already registered */
+
+	ppmu = pmu;
+	pr_info("%s performance monitor hardware support registered\n",
+		pmu->name);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pmc.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/pmc.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/pmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,7 +37,7 @@ static void dummy_perf(struct pt_regs *r
 }
 
 
-static DEFINE_SPINLOCK(pmc_owner_lock);
+static DEFINE_RAW_SPINLOCK(pmc_owner_lock);
 static void *pmc_owner_caller; /* mostly for debugging */
 perf_irq_t perf_irq = dummy_perf;
 
@@ -45,7 +45,7 @@ int reserve_pmc_hardware(perf_irq_t new_
 {
 	int err = 0;
 
-	spin_lock(&pmc_owner_lock);
+	raw_spin_lock(&pmc_owner_lock);
 
 	if (pmc_owner_caller) {
 		printk(KERN_WARNING "reserve_pmc_hardware: "
@@ -59,21 +59,21 @@ int reserve_pmc_hardware(perf_irq_t new_
 	perf_irq = new_perf_irq ? new_perf_irq : dummy_perf;
 
  out:
-	spin_unlock(&pmc_owner_lock);
+	raw_spin_unlock(&pmc_owner_lock);
 	return err;
 }
 EXPORT_SYMBOL_GPL(reserve_pmc_hardware);
 
 void release_pmc_hardware(void)
 {
-	spin_lock(&pmc_owner_lock);
+	raw_spin_lock(&pmc_owner_lock);
 
 	WARN_ON(! pmc_owner_caller);
 
 	pmc_owner_caller = NULL;
 	perf_irq = dummy_perf;
 
-	spin_unlock(&pmc_owner_lock);
+	raw_spin_unlock(&pmc_owner_lock);
 }
 EXPORT_SYMBOL_GPL(release_pmc_hardware);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/ppc_ksyms.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/ppc_ksyms.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/ppc_ksyms.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/ppc_ksyms.c	2010-05-16 17:17:36.000000000 -0400
@@ -107,6 +107,7 @@ EXPORT_SYMBOL(giveup_altivec);
 #endif /* CONFIG_ALTIVEC */
 #ifdef CONFIG_VSX
 EXPORT_SYMBOL(giveup_vsx);
+EXPORT_SYMBOL_GPL(__giveup_vsx);
 #endif /* CONFIG_VSX */
 #ifdef CONFIG_SPE
 EXPORT_SYMBOL(giveup_spe);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/process.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -245,6 +245,24 @@ void discard_lazy_cpu_state(void)
 }
 #endif /* CONFIG_SMP */
 
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+void do_send_trap(struct pt_regs *regs, unsigned long address,
+		  unsigned long error_code, int signal_code, int breakpt)
+{
+	siginfo_t info;
+
+	if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
+			11, SIGSEGV) == NOTIFY_STOP)
+		return;
+
+	/* Deliver the signal to userspace */
+	info.si_signo = SIGTRAP;
+	info.si_errno = breakpt;	/* breakpoint or watchpoint id */
+	info.si_code = signal_code;
+	info.si_addr = (void __user *)address;
+	force_sig_info(SIGTRAP, &info, current);
+}
+#else	/* !CONFIG_PPC_ADV_DEBUG_REGS */
 void do_dabr(struct pt_regs *regs, unsigned long address,
 		    unsigned long error_code)
 {
@@ -257,12 +275,6 @@ void do_dabr(struct pt_regs *regs, unsig
 	if (debugger_dabr_match(regs))
 		return;
 
-	/* Clear the DAC and struct entries.  One shot trigger */
-#if defined(CONFIG_BOOKE)
-	mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~(DBSR_DAC1R | DBSR_DAC1W
-							| DBCR0_IDM));
-#endif
-
 	/* Clear the DABR */
 	set_dabr(0);
 
@@ -273,9 +285,82 @@ void do_dabr(struct pt_regs *regs, unsig
 	info.si_addr = (void __user *)address;
 	force_sig_info(SIGTRAP, &info, current);
 }
+#endif	/* CONFIG_PPC_ADV_DEBUG_REGS */
 
 static DEFINE_PER_CPU(unsigned long, current_dabr);
 
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+/*
+ * Set the debug registers back to their default "safe" values.
+ */
+static void set_debug_reg_defaults(struct thread_struct *thread)
+{
+	thread->iac1 = thread->iac2 = 0;
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+	thread->iac3 = thread->iac4 = 0;
+#endif
+	thread->dac1 = thread->dac2 = 0;
+#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
+	thread->dvc1 = thread->dvc2 = 0;
+#endif
+	thread->dbcr0 = 0;
+#ifdef CONFIG_BOOKE
+	/*
+	 * Force User/Supervisor bits to b11 (user-only MSR[PR]=1)
+	 */
+	thread->dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US |	\
+			DBCR1_IAC3US | DBCR1_IAC4US;
+	/*
+	 * Force Data Address Compare User/Supervisor bits to be User-only
+	 * (0b11 MSR[PR]=1) and set all other bits in DBCR2 register to be 0.
+	 */
+	thread->dbcr2 = DBCR2_DAC1US | DBCR2_DAC2US;
+#else
+	thread->dbcr1 = 0;
+#endif
+}
+
+static void prime_debug_regs(struct thread_struct *thread)
+{
+	mtspr(SPRN_IAC1, thread->iac1);
+	mtspr(SPRN_IAC2, thread->iac2);
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+	mtspr(SPRN_IAC3, thread->iac3);
+	mtspr(SPRN_IAC4, thread->iac4);
+#endif
+	mtspr(SPRN_DAC1, thread->dac1);
+	mtspr(SPRN_DAC2, thread->dac2);
+#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
+	mtspr(SPRN_DVC1, thread->dvc1);
+	mtspr(SPRN_DVC2, thread->dvc2);
+#endif
+	mtspr(SPRN_DBCR0, thread->dbcr0);
+	mtspr(SPRN_DBCR1, thread->dbcr1);
+#ifdef CONFIG_BOOKE
+	mtspr(SPRN_DBCR2, thread->dbcr2);
+#endif
+}
+/*
+ * Unless neither the old or new thread are making use of the
+ * debug registers, set the debug registers from the values
+ * stored in the new thread.
+ */
+static void switch_booke_debug_regs(struct thread_struct *new_thread)
+{
+	if ((current->thread.dbcr0 & DBCR0_IDM)
+		|| (new_thread->dbcr0 & DBCR0_IDM))
+			prime_debug_regs(new_thread);
+}
+#else	/* !CONFIG_PPC_ADV_DEBUG_REGS */
+static void set_debug_reg_defaults(struct thread_struct *thread)
+{
+	if (thread->dabr) {
+		thread->dabr = 0;
+		set_dabr(0);
+	}
+}
+#endif	/* CONFIG_PPC_ADV_DEBUG_REGS */
+
 int set_dabr(unsigned long dabr)
 {
 	__get_cpu_var(current_dabr) = dabr;
@@ -284,7 +369,7 @@ int set_dabr(unsigned long dabr)
 		return ppc_md.set_dabr(dabr);
 
 	/* XXX should we have a CPU_FTR_HAS_DABR ? */
-#if defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
 	mtspr(SPRN_DAC1, dabr);
 #elif defined(CONFIG_PPC_BOOK3S)
 	mtspr(SPRN_DABR, dabr);
@@ -371,10 +456,8 @@ struct task_struct *__switch_to(struct t
 
 #endif /* CONFIG_SMP */
 
-#if defined(CONFIG_BOOKE)
-	/* If new thread DAC (HW breakpoint) is the same then leave it */
-	if (new->thread.dabr)
-		set_dabr(new->thread.dabr);
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+	switch_booke_debug_regs(&new->thread);
 #else
 	if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
 		set_dabr(new->thread.dabr);
@@ -514,7 +597,7 @@ void show_regs(struct pt_regs * regs)
 	printk("  CR: %08lx  XER: %08lx\n", regs->ccr, regs->xer);
 	trap = TRAP(regs);
 	if (trap == 0x300 || trap == 0x600)
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
 		printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr);
 #else
 		printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
@@ -556,14 +639,7 @@ void flush_thread(void)
 {
 	discard_lazy_cpu_state();
 
-	if (current->thread.dabr) {
-		current->thread.dabr = 0;
-		set_dabr(0);
-
-#if defined(CONFIG_BOOKE)
-		current->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W);
-#endif
-	}
+	set_debug_reg_defaults(&current->thread);
 }
 
 void
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/proc_powerpc.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/proc_powerpc.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/proc_powerpc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/proc_powerpc.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/proc_fs.h>
-#include <linux/slab.h>
 #include <linux/kernel.h>
 
 #include <asm/machdep.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/prom.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/prom.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/prom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/prom.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,7 @@
 #include <asm/smp.h>
 #include <asm/system.h>
 #include <asm/mmu.h>
+#include <asm/paca.h>
 #include <asm/pgtable.h>
 #include <asm/pci.h>
 #include <asm/iommu.h>
@@ -61,365 +62,12 @@
 #define DBG(fmt...)
 #endif
 
-
-static int __initdata dt_root_addr_cells;
-static int __initdata dt_root_size_cells;
-
 #ifdef CONFIG_PPC64
 int __initdata iommu_is_off;
 int __initdata iommu_force_on;
 unsigned long tce_alloc_start, tce_alloc_end;
 #endif
 
-typedef u32 cell_t;
-
-#if 0
-static struct boot_param_header *initial_boot_params __initdata;
-#else
-struct boot_param_header *initial_boot_params;
-#endif
-
-extern struct device_node *allnodes;	/* temporary while merging */
-
-extern rwlock_t devtree_lock;	/* temporary while merging */
-
-/* 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 *p = np->full_name;
-			/* rebuild full path for new format */
-			if (dad && dad->parent) {
-				strcpy(p, dad->full_name);
-#ifdef DEBUG
-				if ((strlen(p) + l + 1) != allocl) {
-					DBG("%s: p: %d, l: %d, a: %d\n",
-					    pathp, (int)strlen(p), l, allocl);
-				}
-#endif
-				p += strlen(p);
-			}
-			*(p++) = '/';
-			memcpy(p, 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 == 0)
-				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("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 *p = pathp, *ps = pathp, *pa = NULL;
-		int sz;
-
-		while (*p) {
-			if ((*p) == '@')
-				pa = p;
-			if ((*p) == '/')
-				ps = p + 1;
-			p++;
-		}
-		if (pa < ps)
-			pa = p;
-		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;
-			DBG("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("Weird tag at end of node: %x\n", tag);
-		return mem;
-	}
-	*p += 4;
-	return mem;
-}
-
 static int __init early_parse_mem(char *p)
 {
 	if (!p)
@@ -446,7 +94,7 @@ static void __init move_device_tree(void
 	DBG("-> move_device_tree\n");
 
 	start = __pa(initial_boot_params);
-	size = initial_boot_params->totalsize;
+	size = be32_to_cpu(initial_boot_params->totalsize);
 
 	if ((memory_limit && (start + size) > memory_limit) ||
 			overlaps_crashkernel(start, size)) {
@@ -459,54 +107,6 @@ static void __init move_device_tree(void
 	DBG("<- move_device_tree\n");
 }
 
-/**
- * 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;
-
-	DBG(" -> 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;
-
-	DBG("  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;
-
-	DBG("  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");
-
-	DBG(" <- unflatten_device_tree()\n");
-}
-
 /*
  * ibm,pa-features is a per-cpu property that contains a string of
  * attribute descriptors, each of which has a 2 byte header plus up
@@ -763,48 +363,9 @@ static int __init early_init_dt_scan_cpu
 	return 0;
 }
 
-#ifdef CONFIG_BLK_DEV_INITRD
-static void __init early_init_dt_check_for_initrd(unsigned long node)
-{
-	unsigned long l;
-	u32 *prop;
-
-	DBG("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;
-		}
-	}
-
-	DBG("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)
+void __init early_init_dt_scan_chosen_arch(unsigned long node)
 {
 	unsigned long *lprop;
-	unsigned long l;
-	char *p;
-
-	DBG("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_PPC64
 	/* check if iommu is forced on or off */
@@ -815,17 +376,17 @@ static int __init early_init_dt_scan_cho
 #endif
 
 	/* mem=x on the command line is the preferred mechanism */
- 	lprop = of_get_flat_dt_prop(node, "linux,memory-limit", NULL);
- 	if (lprop)
- 		memory_limit = *lprop;
+	lprop = of_get_flat_dt_prop(node, "linux,memory-limit", NULL);
+	if (lprop)
+		memory_limit = *lprop;
 
 #ifdef CONFIG_PPC64
- 	lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-start", NULL);
- 	if (lprop)
- 		tce_alloc_start = *lprop;
- 	lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
- 	if (lprop)
- 		tce_alloc_end = *lprop;
+	lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-start", NULL);
+	if (lprop)
+		tce_alloc_start = *lprop;
+	lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
+	if (lprop)
+		tce_alloc_end = *lprop;
 #endif
 
 #ifdef CONFIG_KEXEC
@@ -837,51 +398,6 @@ static int __init early_init_dt_scan_cho
 	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 */
-
-	DBG("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;
-	DBG("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;
-	DBG("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);
 }
 
 #ifdef CONFIG_PPC_PSERIES
@@ -893,22 +409,22 @@ static u64 __init dt_mem_next_cell(int s
  */
 static int __init early_init_dt_scan_drconf_memory(unsigned long node)
 {
-	cell_t *dm, *ls, *usm;
+	__be32 *dm, *ls, *usm;
 	unsigned long l, n, flags;
 	u64 base, size, lmb_size;
 	unsigned int is_kexec_kdump = 0, rngs;
 
 	ls = of_get_flat_dt_prop(node, "ibm,lmb-size", &l);
-	if (ls == NULL || l < dt_root_size_cells * sizeof(cell_t))
+	if (ls == NULL || l < dt_root_size_cells * sizeof(__be32))
 		return 0;
 	lmb_size = dt_mem_next_cell(dt_root_size_cells, &ls);
 
 	dm = of_get_flat_dt_prop(node, "ibm,dynamic-memory", &l);
-	if (dm == NULL || l < sizeof(cell_t))
+	if (dm == NULL || l < sizeof(__be32))
 		return 0;
 
 	n = *dm++;	/* number of entries */
-	if (l < (n * (dt_root_addr_cells + 4) + 1) * sizeof(cell_t))
+	if (l < (n * (dt_root_addr_cells + 4) + 1) * sizeof(__be32))
 		return 0;
 
 	/* check if this is a kexec/kdump kernel. */
@@ -963,65 +479,47 @@ static int __init early_init_dt_scan_drc
 #define early_init_dt_scan_drconf_memory(node)	0
 #endif /* CONFIG_PPC_PSERIES */
 
-static int __init early_init_dt_scan_memory(unsigned long node,
-					    const char *uname, int depth, void *data)
+static int __init early_init_dt_scan_memory_ppc(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);
+	
+	return early_init_dt_scan_memory(node, uname, depth, data);
+}
 
-	/* 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 = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
-	if (reg == NULL)
-		reg = of_get_flat_dt_prop(node, "reg", &l);
-	if (reg == NULL)
-		return 0;
-
-	endp = reg + (l / sizeof(cell_t));
-
-	DBG("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;
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+#if defined(CONFIG_PPC64)
+	if (iommu_is_off) {
+		if (base >= 0x80000000ul)
+			return;
+		if ((base + size) > 0x80000000ul)
+			size = 0x80000000ul - base;
+	}
+#endif
 
-		base = dt_mem_next_cell(dt_root_addr_cells, &reg);
-		size = dt_mem_next_cell(dt_root_size_cells, &reg);
+	lmb_add(base, size);
 
-		if (size == 0)
-			continue;
-		DBG(" - %llx ,  %llx\n", (unsigned long long)base,
-		    (unsigned long long)size);
-#ifdef CONFIG_PPC64
-		if (iommu_is_off) {
-			if (base >= 0x80000000ul)
-				continue;
-			if ((base + size) > 0x80000000ul)
-				size = 0x80000000ul - base;
-		}
-#endif
-		lmb_add(base, size);
+	memstart_addr = min((u64)memstart_addr, base);
+}
 
-		memstart_addr = min((u64)memstart_addr, base);
-	}
+u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+	return lmb_alloc(size, align);
+}
 
-	return 0;
+#ifdef CONFIG_BLK_DEV_INITRD
+void __init early_init_dt_setup_initrd_arch(unsigned long start,
+		unsigned long end)
+{
+	initrd_start = (unsigned long)__va(start);
+	initrd_end = (unsigned long)__va(end);
+	initrd_below_start_ok = 1;
 }
+#endif
 
 static void __init early_reserve_mem(void)
 {
@@ -1186,7 +684,7 @@ void __init early_init_devtree(void *par
 	/* 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);
+	of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL);
 
 	/* Save command line for /proc/cmdline and then parse parameters */
 	strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
@@ -1224,6 +722,8 @@ void __init early_init_devtree(void *par
 	 * FIXME .. and the initrd too? */
 	move_device_tree();
 
+	allocate_pacas();
+
 	DBG("Scanning CPUs ...\n");
 
 	/* Retreive CPU related informations from the flat tree
@@ -1234,25 +734,6 @@ void __init early_init_devtree(void *par
 	DBG(" <- 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
@@ -1265,27 +746,6 @@ EXPORT_SYMBOL(machine_is_compatible);
  *******/
 
 /**
- *	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 != 0; 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_next_cache_node - Find a node's subsidiary cache
  *	@np:	node of type "cpu" or "cache"
  *
@@ -1316,138 +776,6 @@ struct device_node *of_find_next_cache_n
 	return NULL;
 }
 
-/**
- *	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("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);
-}
-
 #ifdef CONFIG_PPC_PSERIES
 /*
  * Fix up the uninitialized fields in a new device node:
@@ -1479,9 +807,9 @@ static int of_finish_dynamic_node(struct
 	if (machine_is(powermac))
 		return -ENODEV;
 
-	/* fix up new node's linux_phandle field */
+	/* fix up new node's phandle field */
 	if ((ibm_phandle = of_get_property(node, "ibm,phandle", NULL)))
-		node->linux_phandle = *ibm_phandle;
+		node->phandle = *ibm_phandle;
 
 out:
 	of_node_put(parent);
@@ -1520,120 +848,6 @@ static int __init prom_reconfig_setup(vo
 __initcall(prom_reconfig_setup);
 #endif
 
-/*
- * 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;
-}
-
-
 /* Find the device node for a given logical cpu number, also returns the cpu
  * local thread number (index in ibm,interrupt-server#s) if relevant and
  * asked for (non NULL)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/prom_init.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/prom_init.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/prom_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/prom_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -653,6 +653,10 @@ static void __init early_cmdline_parse(v
 #else
 #define OV5_CMO			0x00
 #endif
+#define OV5_TYPE1_AFFINITY	0x80	/* Type 1 NUMA affinity */
+
+/* Option Vector 6: IBM PAPR hints */
+#define OV6_LINUX		0x02	/* Linux is our OS */
 
 /*
  * The architecture vector has an array of PVR mask/value pairs,
@@ -665,7 +669,7 @@ static unsigned char ibm_architecture_ve
 	W(0xffffffff), W(0x0f000003),	/* all 2.06-compliant */
 	W(0xffffffff), W(0x0f000002),	/* all 2.05-compliant */
 	W(0xfffffffe), W(0x0f000001),	/* all 2.04-compliant and earlier */
-	5 - 1,				/* 5 option vectors */
+	6 - 1,				/* 6 option vectors */
 
 	/* option vector 1: processor architectures supported */
 	3 - 2,				/* length */
@@ -697,12 +701,29 @@ static unsigned char ibm_architecture_ve
 	0,				/* don't halt */
 
 	/* option vector 5: PAPR/OF options */
-	5 - 2,				/* length */
+	13 - 2,				/* length */
 	0,				/* don't ignore, don't halt */
 	OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY |
 	OV5_DONATE_DEDICATE_CPU | OV5_MSI,
 	0,
 	OV5_CMO,
+	OV5_TYPE1_AFFINITY,
+	0,
+	0,
+	0,
+	/* WARNING: The offset of the "number of cores" field below
+	 * must match by the macro below. Update the definition if
+	 * the structure layout changes.
+	 */
+#define IBM_ARCH_VEC_NRCORES_OFFSET	100
+	W(NR_CPUS),			/* number of cores supported */
+
+	/* option vector 6: IBM PAPR hints */
+	4 - 2,				/* length */
+	0,
+	0,
+	OV6_LINUX,
+
 };
 
 /* Old method - ELF header with PT_NOTE sections */
@@ -792,13 +813,70 @@ static struct fake_elf {
 	}
 };
 
+static int __init prom_count_smt_threads(void)
+{
+	phandle node;
+	char type[64];
+	unsigned int plen;
+
+	/* Pick up th first CPU node we can find */
+	for (node = 0; prom_next_node(&node); ) {
+		type[0] = 0;
+		prom_getprop(node, "device_type", type, sizeof(type));
+
+		if (strcmp(type, RELOC("cpu")))
+			continue;
+		/*
+		 * There is an entry for each smt thread, each entry being
+		 * 4 bytes long.  All cpus should have the same number of
+		 * smt threads, so return after finding the first.
+		 */
+		plen = prom_getproplen(node, "ibm,ppc-interrupt-server#s");
+		if (plen == PROM_ERROR)
+			break;
+		plen >>= 2;
+		prom_debug("Found 0x%x smt threads per core\n", (unsigned long)plen);
+
+		/* Sanity check */
+		if (plen < 1 || plen > 64) {
+			prom_printf("Threads per core 0x%x out of bounds, assuming 1\n",
+				    (unsigned long)plen);
+			return 1;
+		}
+		return plen;
+	}
+	prom_debug("No threads found, assuming 1 per core\n");
+
+	return 1;
+
+}
+
+
 static void __init prom_send_capabilities(void)
 {
 	ihandle elfloader, root;
 	prom_arg_t ret;
+	u32 *cores;
 
 	root = call_prom("open", 1, 1, ADDR("/"));
 	if (root != 0) {
+		/* We need to tell the FW about the number of cores we support.
+		 *
+		 * To do that, we count the number of threads on the first core
+		 * (we assume this is the same for all cores) and use it to
+		 * divide NR_CPUS.
+		 */
+		cores = (u32 *)PTRRELOC(&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET]);
+		if (*cores != NR_CPUS) {
+			prom_printf("WARNING ! "
+				    "ibm_architecture_vec structure inconsistent: 0x%x !\n",
+				    *cores);
+		} else {
+			*cores = NR_CPUS / prom_count_smt_threads();
+			prom_printf("Max number of cores passed to firmware: 0x%x\n",
+				    (unsigned long)*cores);
+		}
+
 		/* try calling the ibm,client-architecture-support method */
 		prom_printf("Calling ibm,client-architecture-support...");
 		if (call_prom_ret("call-method", 3, 2, &ret,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,7 +46,7 @@
 /*
  * Set of msr bits that gdb can change on behalf of a process.
  */
-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
 #define MSR_DEBUGCHANGE	0
 #else
 #define MSR_DEBUGCHANGE	(MSR_SE | MSR_BE)
@@ -703,7 +703,7 @@ void user_enable_single_step(struct task
 	struct pt_regs *regs = task->thread.regs;
 
 	if (regs != NULL) {
-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
 		task->thread.dbcr0 &= ~DBCR0_BT;
 		task->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC;
 		regs->msr |= MSR_DE;
@@ -720,7 +720,7 @@ void user_enable_block_step(struct task_
 	struct pt_regs *regs = task->thread.regs;
 
 	if (regs != NULL) {
-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
 		task->thread.dbcr0 &= ~DBCR0_IC;
 		task->thread.dbcr0 = DBCR0_IDM | DBCR0_BT;
 		regs->msr |= MSR_DE;
@@ -737,17 +737,25 @@ void user_disable_single_step(struct tas
 	struct pt_regs *regs = task->thread.regs;
 
 	if (regs != NULL) {
-#if defined(CONFIG_BOOKE)
-		/* If DAC don't clear DBCRO_IDM or MSR_DE */
-		if (task->thread.dabr)
-			task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT);
-		else {
-			task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM);
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+		/*
+		 * The logic to disable single stepping should be as
+		 * simple as turning off the Instruction Complete flag.
+		 * And, after doing so, if all debug flags are off, turn
+		 * off DBCR0(IDM) and MSR(DE) .... Torez
+		 */
+		task->thread.dbcr0 &= ~DBCR0_IC;
+		/*
+		 * Test to see if any of the DBCR_ACTIVE_EVENTS bits are set.
+		 */
+		if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0,
+					task->thread.dbcr1)) {
+			/*
+			 * All debug events were off.....
+			 */
+			task->thread.dbcr0 &= ~DBCR0_IDM;
 			regs->msr &= ~MSR_DE;
 		}
-#elif defined(CONFIG_40x)
-		task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM);
-		regs->msr &= ~MSR_DE;
 #else
 		regs->msr &= ~(MSR_SE | MSR_BE);
 #endif
@@ -769,8 +777,7 @@ int ptrace_set_debugreg(struct task_stru
 	if ((data & ~0x7UL) >= TASK_SIZE)
 		return -EIO;
 
-#ifndef CONFIG_BOOKE
-
+#ifndef CONFIG_PPC_ADV_DEBUG_REGS
 	/* For processors using DABR (i.e. 970), the bottom 3 bits are flags.
 	 *  It was assumed, on previous implementations, that 3 bits were
 	 *  passed together with the data address, fitting the design of the
@@ -789,21 +796,22 @@ int ptrace_set_debugreg(struct task_stru
 
 	/* Move contents to the DABR register */
 	task->thread.dabr = data;
-
-#endif
-#if defined(CONFIG_BOOKE)
-
+#else /* CONFIG_PPC_ADV_DEBUG_REGS */
 	/* As described above, it was assumed 3 bits were passed with the data
 	 *  address, but we will assume only the mode bits will be passed
 	 *  as to not cause alignment restrictions for DAC-based processors.
 	 */
 
 	/* DAC's hold the whole address without any mode flags */
-	task->thread.dabr = data & ~0x3UL;
+	task->thread.dac1 = data & ~0x3UL;
 
-	if (task->thread.dabr == 0) {
-		task->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W | DBCR0_IDM);
-		task->thread.regs->msr &= ~MSR_DE;
+	if (task->thread.dac1 == 0) {
+		dbcr_dac(task) &= ~(DBCR_DAC1R | DBCR_DAC1W);
+		if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0,
+					task->thread.dbcr1)) {
+			task->thread.regs->msr &= ~MSR_DE;
+			task->thread.dbcr0 &= ~DBCR0_IDM;
+		}
 		return 0;
 	}
 
@@ -814,17 +822,17 @@ int ptrace_set_debugreg(struct task_stru
 
 	/* Set the Internal Debugging flag (IDM bit 1) for the DBCR0
 	   register */
-	task->thread.dbcr0 = DBCR0_IDM;
+	task->thread.dbcr0 |= DBCR0_IDM;
 
 	/* Check for write and read flags and set DBCR0
 	   accordingly */
+	dbcr_dac(task) &= ~(DBCR_DAC1R|DBCR_DAC1W);
 	if (data & 0x1UL)
-		task->thread.dbcr0 |= DBSR_DAC1R;
+		dbcr_dac(task) |= DBCR_DAC1R;
 	if (data & 0x2UL)
-		task->thread.dbcr0 |= DBSR_DAC1W;
-
+		dbcr_dac(task) |= DBCR_DAC1W;
 	task->thread.regs->msr |= MSR_DE;
-#endif
+#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
 	return 0;
 }
 
@@ -839,6 +847,394 @@ void ptrace_disable(struct task_struct *
 	user_disable_single_step(child);
 }
 
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+static long set_intruction_bp(struct task_struct *child,
+			      struct ppc_hw_breakpoint *bp_info)
+{
+	int slot;
+	int slot1_in_use = ((child->thread.dbcr0 & DBCR0_IAC1) != 0);
+	int slot2_in_use = ((child->thread.dbcr0 & DBCR0_IAC2) != 0);
+	int slot3_in_use = ((child->thread.dbcr0 & DBCR0_IAC3) != 0);
+	int slot4_in_use = ((child->thread.dbcr0 & DBCR0_IAC4) != 0);
+
+	if (dbcr_iac_range(child) & DBCR_IAC12MODE)
+		slot2_in_use = 1;
+	if (dbcr_iac_range(child) & DBCR_IAC34MODE)
+		slot4_in_use = 1;
+
+	if (bp_info->addr >= TASK_SIZE)
+		return -EIO;
+
+	if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) {
+
+		/* Make sure range is valid. */
+		if (bp_info->addr2 >= TASK_SIZE)
+			return -EIO;
+
+		/* We need a pair of IAC regsisters */
+		if ((!slot1_in_use) && (!slot2_in_use)) {
+			slot = 1;
+			child->thread.iac1 = bp_info->addr;
+			child->thread.iac2 = bp_info->addr2;
+			child->thread.dbcr0 |= DBCR0_IAC1;
+			if (bp_info->addr_mode ==
+					PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
+				dbcr_iac_range(child) |= DBCR_IAC12X;
+			else
+				dbcr_iac_range(child) |= DBCR_IAC12I;
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+		} else if ((!slot3_in_use) && (!slot4_in_use)) {
+			slot = 3;
+			child->thread.iac3 = bp_info->addr;
+			child->thread.iac4 = bp_info->addr2;
+			child->thread.dbcr0 |= DBCR0_IAC3;
+			if (bp_info->addr_mode ==
+					PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
+				dbcr_iac_range(child) |= DBCR_IAC34X;
+			else
+				dbcr_iac_range(child) |= DBCR_IAC34I;
+#endif
+		} else
+			return -ENOSPC;
+	} else {
+		/* We only need one.  If possible leave a pair free in
+		 * case a range is needed later
+		 */
+		if (!slot1_in_use) {
+			/*
+			 * Don't use iac1 if iac1-iac2 are free and either
+			 * iac3 or iac4 (but not both) are free
+			 */
+			if (slot2_in_use || (slot3_in_use == slot4_in_use)) {
+				slot = 1;
+				child->thread.iac1 = bp_info->addr;
+				child->thread.dbcr0 |= DBCR0_IAC1;
+				goto out;
+			}
+		}
+		if (!slot2_in_use) {
+			slot = 2;
+			child->thread.iac2 = bp_info->addr;
+			child->thread.dbcr0 |= DBCR0_IAC2;
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+		} else if (!slot3_in_use) {
+			slot = 3;
+			child->thread.iac3 = bp_info->addr;
+			child->thread.dbcr0 |= DBCR0_IAC3;
+		} else if (!slot4_in_use) {
+			slot = 4;
+			child->thread.iac4 = bp_info->addr;
+			child->thread.dbcr0 |= DBCR0_IAC4;
+#endif
+		} else
+			return -ENOSPC;
+	}
+out:
+	child->thread.dbcr0 |= DBCR0_IDM;
+	child->thread.regs->msr |= MSR_DE;
+
+	return slot;
+}
+
+static int del_instruction_bp(struct task_struct *child, int slot)
+{
+	switch (slot) {
+	case 1:
+		if ((child->thread.dbcr0 & DBCR0_IAC1) == 0)
+			return -ENOENT;
+
+		if (dbcr_iac_range(child) & DBCR_IAC12MODE) {
+			/* address range - clear slots 1 & 2 */
+			child->thread.iac2 = 0;
+			dbcr_iac_range(child) &= ~DBCR_IAC12MODE;
+		}
+		child->thread.iac1 = 0;
+		child->thread.dbcr0 &= ~DBCR0_IAC1;
+		break;
+	case 2:
+		if ((child->thread.dbcr0 & DBCR0_IAC2) == 0)
+			return -ENOENT;
+
+		if (dbcr_iac_range(child) & DBCR_IAC12MODE)
+			/* used in a range */
+			return -EINVAL;
+		child->thread.iac2 = 0;
+		child->thread.dbcr0 &= ~DBCR0_IAC2;
+		break;
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+	case 3:
+		if ((child->thread.dbcr0 & DBCR0_IAC3) == 0)
+			return -ENOENT;
+
+		if (dbcr_iac_range(child) & DBCR_IAC34MODE) {
+			/* address range - clear slots 3 & 4 */
+			child->thread.iac4 = 0;
+			dbcr_iac_range(child) &= ~DBCR_IAC34MODE;
+		}
+		child->thread.iac3 = 0;
+		child->thread.dbcr0 &= ~DBCR0_IAC3;
+		break;
+	case 4:
+		if ((child->thread.dbcr0 & DBCR0_IAC4) == 0)
+			return -ENOENT;
+
+		if (dbcr_iac_range(child) & DBCR_IAC34MODE)
+			/* Used in a range */
+			return -EINVAL;
+		child->thread.iac4 = 0;
+		child->thread.dbcr0 &= ~DBCR0_IAC4;
+		break;
+#endif
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info)
+{
+	int byte_enable =
+		(bp_info->condition_mode >> PPC_BREAKPOINT_CONDITION_BE_SHIFT)
+		& 0xf;
+	int condition_mode =
+		bp_info->condition_mode & PPC_BREAKPOINT_CONDITION_MODE;
+	int slot;
+
+	if (byte_enable && (condition_mode == 0))
+		return -EINVAL;
+
+	if (bp_info->addr >= TASK_SIZE)
+		return -EIO;
+
+	if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0) {
+		slot = 1;
+		if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
+			dbcr_dac(child) |= DBCR_DAC1R;
+		if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
+			dbcr_dac(child) |= DBCR_DAC1W;
+		child->thread.dac1 = (unsigned long)bp_info->addr;
+#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
+		if (byte_enable) {
+			child->thread.dvc1 =
+				(unsigned long)bp_info->condition_value;
+			child->thread.dbcr2 |=
+				((byte_enable << DBCR2_DVC1BE_SHIFT) |
+				 (condition_mode << DBCR2_DVC1M_SHIFT));
+		}
+#endif
+#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
+	} else if (child->thread.dbcr2 & DBCR2_DAC12MODE) {
+		/* Both dac1 and dac2 are part of a range */
+		return -ENOSPC;
+#endif
+	} else if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0) {
+		slot = 2;
+		if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
+			dbcr_dac(child) |= DBCR_DAC2R;
+		if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
+			dbcr_dac(child) |= DBCR_DAC2W;
+		child->thread.dac2 = (unsigned long)bp_info->addr;
+#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
+		if (byte_enable) {
+			child->thread.dvc2 =
+				(unsigned long)bp_info->condition_value;
+			child->thread.dbcr2 |=
+				((byte_enable << DBCR2_DVC2BE_SHIFT) |
+				 (condition_mode << DBCR2_DVC2M_SHIFT));
+		}
+#endif
+	} else
+		return -ENOSPC;
+	child->thread.dbcr0 |= DBCR0_IDM;
+	child->thread.regs->msr |= MSR_DE;
+
+	return slot + 4;
+}
+
+static int del_dac(struct task_struct *child, int slot)
+{
+	if (slot == 1) {
+		if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0)
+			return -ENOENT;
+
+		child->thread.dac1 = 0;
+		dbcr_dac(child) &= ~(DBCR_DAC1R | DBCR_DAC1W);
+#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
+		if (child->thread.dbcr2 & DBCR2_DAC12MODE) {
+			child->thread.dac2 = 0;
+			child->thread.dbcr2 &= ~DBCR2_DAC12MODE;
+		}
+		child->thread.dbcr2 &= ~(DBCR2_DVC1M | DBCR2_DVC1BE);
+#endif
+#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
+		child->thread.dvc1 = 0;
+#endif
+	} else if (slot == 2) {
+		if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0)
+			return -ENOENT;
+
+#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
+		if (child->thread.dbcr2 & DBCR2_DAC12MODE)
+			/* Part of a range */
+			return -EINVAL;
+		child->thread.dbcr2 &= ~(DBCR2_DVC2M | DBCR2_DVC2BE);
+#endif
+#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
+		child->thread.dvc2 = 0;
+#endif
+		child->thread.dac2 = 0;
+		dbcr_dac(child) &= ~(DBCR_DAC2R | DBCR_DAC2W);
+	} else
+		return -EINVAL;
+
+	return 0;
+}
+#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
+
+#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
+static int set_dac_range(struct task_struct *child,
+			 struct ppc_hw_breakpoint *bp_info)
+{
+	int mode = bp_info->addr_mode & PPC_BREAKPOINT_MODE_MASK;
+
+	/* We don't allow range watchpoints to be used with DVC */
+	if (bp_info->condition_mode)
+		return -EINVAL;
+
+	/*
+	 * Best effort to verify the address range.  The user/supervisor bits
+	 * prevent trapping in kernel space, but let's fail on an obvious bad
+	 * range.  The simple test on the mask is not fool-proof, and any
+	 * exclusive range will spill over into kernel space.
+	 */
+	if (bp_info->addr >= TASK_SIZE)
+		return -EIO;
+	if (mode == PPC_BREAKPOINT_MODE_MASK) {
+		/*
+		 * dac2 is a bitmask.  Don't allow a mask that makes a
+		 * kernel space address from a valid dac1 value
+		 */
+		if (~((unsigned long)bp_info->addr2) >= TASK_SIZE)
+			return -EIO;
+	} else {
+		/*
+		 * For range breakpoints, addr2 must also be a valid address
+		 */
+		if (bp_info->addr2 >= TASK_SIZE)
+			return -EIO;
+	}
+
+	if (child->thread.dbcr0 &
+	    (DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W))
+		return -ENOSPC;
+
+	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
+		child->thread.dbcr0 |= (DBCR0_DAC1R | DBCR0_IDM);
+	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
+		child->thread.dbcr0 |= (DBCR0_DAC1W | DBCR0_IDM);
+	child->thread.dac1 = bp_info->addr;
+	child->thread.dac2 = bp_info->addr2;
+	if (mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE)
+		child->thread.dbcr2  |= DBCR2_DAC12M;
+	else if (mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
+		child->thread.dbcr2  |= DBCR2_DAC12MX;
+	else	/* PPC_BREAKPOINT_MODE_MASK */
+		child->thread.dbcr2  |= DBCR2_DAC12MM;
+	child->thread.regs->msr |= MSR_DE;
+
+	return 5;
+}
+#endif /* CONFIG_PPC_ADV_DEBUG_DAC_RANGE */
+
+static long ppc_set_hwdebug(struct task_struct *child,
+		     struct ppc_hw_breakpoint *bp_info)
+{
+	if (bp_info->version != 1)
+		return -ENOTSUPP;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+	/*
+	 * Check for invalid flags and combinations
+	 */
+	if ((bp_info->trigger_type == 0) ||
+	    (bp_info->trigger_type & ~(PPC_BREAKPOINT_TRIGGER_EXECUTE |
+				       PPC_BREAKPOINT_TRIGGER_RW)) ||
+	    (bp_info->addr_mode & ~PPC_BREAKPOINT_MODE_MASK) ||
+	    (bp_info->condition_mode &
+	     ~(PPC_BREAKPOINT_CONDITION_MODE |
+	       PPC_BREAKPOINT_CONDITION_BE_ALL)))
+		return -EINVAL;
+#if CONFIG_PPC_ADV_DEBUG_DVCS == 0
+	if (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
+		return -EINVAL;
+#endif
+
+	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_EXECUTE) {
+		if ((bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_EXECUTE) ||
+		    (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE))
+			return -EINVAL;
+		return set_intruction_bp(child, bp_info);
+	}
+	if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT)
+		return set_dac(child, bp_info);
+
+#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
+	return set_dac_range(child, bp_info);
+#else
+	return -EINVAL;
+#endif
+#else /* !CONFIG_PPC_ADV_DEBUG_DVCS */
+	/*
+	 * We only support one data breakpoint
+	 */
+	if (((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0) ||
+	    ((bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0) ||
+	    (bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_WRITE) ||
+	    (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) ||
+	    (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE))
+		return -EINVAL;
+
+	if (child->thread.dabr)
+		return -ENOSPC;
+
+	if ((unsigned long)bp_info->addr >= TASK_SIZE)
+		return -EIO;
+
+	child->thread.dabr = (unsigned long)bp_info->addr;
+
+	return 1;
+#endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */
+}
+
+static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
+{
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+	int rc;
+
+	if (data <= 4)
+		rc = del_instruction_bp(child, (int)data);
+	else
+		rc = del_dac(child, (int)data - 4);
+
+	if (!rc) {
+		if (!DBCR_ACTIVE_EVENTS(child->thread.dbcr0,
+					child->thread.dbcr1)) {
+			child->thread.dbcr0 &= ~DBCR0_IDM;
+			child->thread.regs->msr &= ~MSR_DE;
+		}
+	}
+	return rc;
+#else
+	if (data != 1)
+		return -EINVAL;
+	if (child->thread.dabr == 0)
+		return -ENOENT;
+
+	child->thread.dabr = 0;
+
+	return 0;
+#endif
+}
+
 /*
  * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls,
  * we mark them as obsolete now, they will be removed in a future version
@@ -932,13 +1328,77 @@ long arch_ptrace(struct task_struct *chi
 		break;
 	}
 
+	case PPC_PTRACE_GETHWDBGINFO: {
+		struct ppc_debug_info dbginfo;
+
+		dbginfo.version = 1;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+		dbginfo.num_instruction_bps = CONFIG_PPC_ADV_DEBUG_IACS;
+		dbginfo.num_data_bps = CONFIG_PPC_ADV_DEBUG_DACS;
+		dbginfo.num_condition_regs = CONFIG_PPC_ADV_DEBUG_DVCS;
+		dbginfo.data_bp_alignment = 4;
+		dbginfo.sizeof_condition = 4;
+		dbginfo.features = PPC_DEBUG_FEATURE_INSN_BP_RANGE |
+				   PPC_DEBUG_FEATURE_INSN_BP_MASK;
+#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
+		dbginfo.features |=
+				   PPC_DEBUG_FEATURE_DATA_BP_RANGE |
+				   PPC_DEBUG_FEATURE_DATA_BP_MASK;
+#endif
+#else /* !CONFIG_PPC_ADV_DEBUG_REGS */
+		dbginfo.num_instruction_bps = 0;
+		dbginfo.num_data_bps = 1;
+		dbginfo.num_condition_regs = 0;
+#ifdef CONFIG_PPC64
+		dbginfo.data_bp_alignment = 8;
+#else
+		dbginfo.data_bp_alignment = 4;
+#endif
+		dbginfo.sizeof_condition = 0;
+		dbginfo.features = 0;
+#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
+
+		if (!access_ok(VERIFY_WRITE, data,
+			       sizeof(struct ppc_debug_info)))
+			return -EFAULT;
+		ret = __copy_to_user((struct ppc_debug_info __user *)data,
+				     &dbginfo, sizeof(struct ppc_debug_info)) ?
+		      -EFAULT : 0;
+		break;
+	}
+
+	case PPC_PTRACE_SETHWDEBUG: {
+		struct ppc_hw_breakpoint bp_info;
+
+		if (!access_ok(VERIFY_READ, data,
+			       sizeof(struct ppc_hw_breakpoint)))
+			return -EFAULT;
+		ret = __copy_from_user(&bp_info,
+				       (struct ppc_hw_breakpoint __user *)data,
+				       sizeof(struct ppc_hw_breakpoint)) ?
+		      -EFAULT : 0;
+		if (!ret)
+			ret = ppc_set_hwdebug(child, &bp_info);
+		break;
+	}
+
+	case PPC_PTRACE_DELHWDEBUG: {
+		ret = ppc_del_hwdebug(child, addr, data);
+		break;
+	}
+
 	case PTRACE_GET_DEBUGREG: {
 		ret = -EINVAL;
 		/* We only support one DABR and no IABRS at the moment */
 		if (addr > 0)
 			break;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+		ret = put_user(child->thread.dac1,
+			       (unsigned long __user *)data);
+#else
 		ret = put_user(child->thread.dabr,
 			       (unsigned long __user *)data);
+#endif
 		break;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/rtas.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/rtas.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/rtas.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/rtas.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/completion.h>
 #include <linux/cpumask.h>
 #include <linux/lmb.h>
+#include <linux/slab.h>
 
 #include <asm/prom.h>
 #include <asm/rtas.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/rtasd.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/rtasd.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/rtasd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/rtasd.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/spinlock.h>
 #include <linux/cpu.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/rtas_flash.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/rtas_flash.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/rtas_flash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/rtas_flash.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <asm/delay.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/setup_32.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/setup_32.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/setup_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/setup_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,6 @@
 #include <asm/serial.h>
 #include <asm/udbg.h>
 #include <asm/mmu_context.h>
-#include <asm/swiotlb.h>
 
 #include "setup.h"
 
@@ -343,11 +342,6 @@ void __init setup_arch(char **cmdline_p)
 		ppc_md.setup_arch();
 	if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
 
-#ifdef CONFIG_SWIOTLB
-	if (ppc_swiotlb_enable)
-		swiotlb_init(1);
-#endif
-
 	paging_init();
 
 	/* Initialize the MMU context management stuff */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/setup_64.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/setup_64.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/setup_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/setup_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -61,7 +61,6 @@
 #include <asm/xmon.h>
 #include <asm/udbg.h>
 #include <asm/kexec.h>
-#include <asm/swiotlb.h>
 #include <asm/mmu_context.h>
 
 #include "setup.h"
@@ -144,9 +143,9 @@ early_param("smt-enabled", early_smt_ena
 #endif /* CONFIG_SMP */
 
 /* Put the paca pointer into r13 and SPRG_PACA */
-void __init setup_paca(int cpu)
+static void __init setup_paca(struct paca_struct *new_paca)
 {
-	local_paca = &paca[cpu];
+	local_paca = new_paca;
 	mtspr(SPRN_SPRG_PACA, local_paca);
 #ifdef CONFIG_PPC_BOOK3E
 	mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb);
@@ -176,14 +175,12 @@ void __init early_setup(unsigned long dt
 {
 	/* -------- printk is _NOT_ safe to use here ! ------- */
 
-	/* Fill in any unititialised pacas */
-	initialise_pacas();
-
 	/* Identify CPU type */
 	identify_cpu(0, mfspr(SPRN_PVR));
 
 	/* Assume we're on cpu 0 for now. Don't write to the paca yet! */
-	setup_paca(0);
+	initialise_paca(&boot_paca, 0);
+	setup_paca(&boot_paca);
 
 	/* Initialize lockdep early or else spinlocks will blow */
 	lockdep_init();
@@ -203,7 +200,7 @@ void __init early_setup(unsigned long dt
 	early_init_devtree(__va(dt_ptr));
 
 	/* Now we know the logical id of our boot cpu, setup the paca. */
-	setup_paca(boot_cpuid);
+	setup_paca(&paca[boot_cpuid]);
 
 	/* Fix up paca fields required for the boot cpu */
 	get_paca()->cpu_start = 1;
@@ -543,11 +540,6 @@ void __init setup_arch(char **cmdline_p)
 	if (ppc_md.setup_arch)
 		ppc_md.setup_arch();
 
-#ifdef CONFIG_SWIOTLB
-	if (ppc_swiotlb_enable)
-		swiotlb_init(1);
-#endif
-
 	paging_init();
 
 	/* Initialize the MMU context management stuff */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/setup-common.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/setup-common.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/setup-common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/setup-common.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/lmb.h>
 #include <linux/of_platform.h>
 #include <asm/io.h>
+#include <asm/paca.h>
 #include <asm/prom.h>
 #include <asm/processor.h>
 #include <asm/vdso_datapage.h>
@@ -493,6 +494,8 @@ void __init smp_setup_cpu_maps(void)
 	 * here will have to be reworked
 	 */
 	cpu_init_thread_core_maps(nthreads);
+
+	free_unused_pacas();
 }
 #endif /* CONFIG_SMP */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/signal_32.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/signal_32.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/signal_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/signal_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -1078,7 +1078,7 @@ int sys_debug_setcontext(struct ucontext
 	int i;
 	unsigned char tmp;
 	unsigned long new_msr = regs->msr;
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
 	unsigned long new_dbcr0 = current->thread.dbcr0;
 #endif
 
@@ -1087,13 +1087,17 @@ int sys_debug_setcontext(struct ucontext
 			return -EFAULT;
 		switch (op.dbg_type) {
 		case SIG_DBG_SINGLE_STEPPING:
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
 			if (op.dbg_value) {
 				new_msr |= MSR_DE;
 				new_dbcr0 |= (DBCR0_IDM | DBCR0_IC);
 			} else {
-				new_msr &= ~MSR_DE;
-				new_dbcr0 &= ~(DBCR0_IDM | DBCR0_IC);
+				new_dbcr0 &= ~DBCR0_IC;
+				if (!DBCR_ACTIVE_EVENTS(new_dbcr0,
+						current->thread.dbcr1)) {
+					new_msr &= ~MSR_DE;
+					new_dbcr0 &= ~DBCR0_IDM;
+				}
 			}
 #else
 			if (op.dbg_value)
@@ -1103,7 +1107,7 @@ int sys_debug_setcontext(struct ucontext
 #endif
 			break;
 		case SIG_DBG_BRANCH_TRACING:
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
 			return -EINVAL;
 #else
 			if (op.dbg_value)
@@ -1124,7 +1128,7 @@ int sys_debug_setcontext(struct ucontext
 	   failure is a problem, anyway, and it's very unlikely unless
 	   the user is really doing something wrong. */
 	regs->msr = new_msr;
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
 	current->thread.dbcr0 = new_dbcr0;
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/signal.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/signal.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/signal.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/signal.c	2010-05-16 17:17:36.000000000 -0400
@@ -140,17 +140,15 @@ static int do_signal_pending(sigset_t *o
 		return 0;               /* no signals delivered */
 	}
 
+#ifndef CONFIG_PPC_ADV_DEBUG_REGS
         /*
 	 * Reenable the DABR before delivering the signal to
 	 * user space. The DABR will have been cleared if it
 	 * triggered inside the kernel.
 	 */
-	if (current->thread.dabr) {
+	if (current->thread.dabr)
 		set_dabr(current->thread.dabr);
-#if defined(CONFIG_BOOKE)
-		mtspr(SPRN_DBCR0, current->thread.dbcr0);
 #endif
-	}
 
 	if (is32) {
         	if (ka.sa.sa_flags & SA_SIGINFO)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/smp-tbsync.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/smp-tbsync.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/smp-tbsync.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/smp-tbsync.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/smp.h>
 #include <linux/unistd.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/smp.h>
 #include <asm/time.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/softemu8xx.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/softemu8xx.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/softemu8xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/softemu8xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/interrupt.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/syscalls.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/syscalls.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/syscalls.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/syscalls.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,100 +42,6 @@
 #include <asm/time.h>
 #include <asm/unistd.h>
 
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-int sys_ipc(uint call, int first, unsigned long second, long third,
-	    void __user *ptr, long fifth)
-{
-	int version, ret;
-
-	version = call >> 16; /* hack for backward compatibility */
-	call &= 0xffff;
-
-	ret = -ENOSYS;
-	switch (call) {
-	case SEMOP:
-		ret = sys_semtimedop(first, (struct sembuf __user *)ptr,
-				      (unsigned)second, NULL);
-		break;
-	case SEMTIMEDOP:
-		ret = sys_semtimedop(first, (struct sembuf __user *)ptr,
-				      (unsigned)second,
-				      (const struct timespec __user *) fifth);
-		break;
-	case SEMGET:
-		ret = sys_semget (first, (int)second, third);
-		break;
-	case SEMCTL: {
-		union semun fourth;
-
-		ret = -EINVAL;
-		if (!ptr)
-			break;
-		if ((ret = get_user(fourth.__pad, (void __user * __user *)ptr)))
-			break;
-		ret = sys_semctl(first, (int)second, third, fourth);
-		break;
-	}
-	case MSGSND:
-		ret = sys_msgsnd(first, (struct msgbuf __user *)ptr,
-				 (size_t)second, third);
-		break;
-	case MSGRCV:
-		switch (version) {
-		case 0: {
-			struct ipc_kludge tmp;
-
-			ret = -EINVAL;
-			if (!ptr)
-				break;
-			if ((ret = copy_from_user(&tmp,
-						(struct ipc_kludge __user *) ptr,
-						sizeof (tmp)) ? -EFAULT : 0))
-				break;
-			ret = sys_msgrcv(first, tmp.msgp, (size_t) second,
-					  tmp.msgtyp, third);
-			break;
-		}
-		default:
-			ret = sys_msgrcv (first, (struct msgbuf __user *) ptr,
-					  (size_t)second, fifth, third);
-			break;
-		}
-		break;
-	case MSGGET:
-		ret = sys_msgget((key_t)first, (int)second);
-		break;
-	case MSGCTL:
-		ret = sys_msgctl(first, (int)second,
-				  (struct msqid_ds __user *)ptr);
-		break;
-	case SHMAT: {
-		ulong raddr;
-		ret = do_shmat(first, (char __user *)ptr, (int)second, &raddr);
-		if (ret)
-			break;
-		ret = put_user(raddr, (ulong __user *) third);
-		break;
-	}
-	case SHMDT:
-		ret = sys_shmdt((char __user *)ptr);
-		break;
-	case SHMGET:
-		ret = sys_shmget(first, (size_t)second, third);
-		break;
-	case SHMCTL:
-		ret = sys_shmctl(first, (int)second,
-				 (struct shmid_ds __user *)ptr);
-		break;
-	}
-
-	return ret;
-}
-
 static inline unsigned long do_mmap2(unsigned long addr, size_t len,
 			unsigned long prot, unsigned long flags,
 			unsigned long fd, unsigned long off, int shift)
@@ -210,76 +116,6 @@ long ppc64_personality(unsigned long per
 }
 #endif
 
-#ifdef CONFIG_PPC64
-#define OVERRIDE_MACHINE    (personality(current->personality) == PER_LINUX32)
-#else
-#define OVERRIDE_MACHINE    0
-#endif
-
-static inline int override_machine(char __user *mach)
-{
-	if (OVERRIDE_MACHINE) {
-		/* change ppc64 to ppc */
-		if (__put_user(0, mach+3) || __put_user(0, mach+4))
-			return -EFAULT;
-	}
-	return 0;
-}
-
-long ppc_newuname(struct new_utsname __user * name)
-{
-	int err = 0;
-
-	down_read(&uts_sem);
-	if (copy_to_user(name, utsname(), sizeof(*name)))
-		err = -EFAULT;
-	up_read(&uts_sem);
-	if (!err)
-		err = override_machine(name->machine);
-	return err;
-}
-
-int sys_uname(struct old_utsname __user *name)
-{
-	int err = 0;
-	
-	down_read(&uts_sem);
-	if (copy_to_user(name, utsname(), sizeof(*name)))
-		err = -EFAULT;
-	up_read(&uts_sem);
-	if (!err)
-		err = override_machine(name->machine);
-	return err;
-}
-
-int sys_olduname(struct oldold_utsname __user *name)
-{
-	int error;
-
-	if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
-		return -EFAULT;
-  
-	down_read(&uts_sem);
-	error = __copy_to_user(&name->sysname, &utsname()->sysname,
-			       __OLD_UTS_LEN);
-	error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->nodename, &utsname()->nodename,
-				__OLD_UTS_LEN);
-	error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->release, &utsname()->release,
-				__OLD_UTS_LEN);
-	error |= __put_user(0, name->release + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->version, &utsname()->version,
-				__OLD_UTS_LEN);
-	error |= __put_user(0, name->version + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->machine, &utsname()->machine,
-				__OLD_UTS_LEN);
-	error |= override_machine(name->machine);
-	up_read(&uts_sem);
-
-	return error? -EFAULT: 0;
-}
-
 long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
 		      u32 len_high, u32 len_low)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/sys_ppc32.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/sys_ppc32.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/sys_ppc32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/sys_ppc32.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@
 #include <linux/ptrace.h>
 #include <linux/elf.h>
 #include <linux/ipc.h>
+#include <linux/slab.h>
 
 #include <asm/ptrace.h>
 #include <asm/types.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/time.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/time.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -265,8 +265,8 @@ void account_system_vtime(struct task_st
 		account_system_time(tsk, 0, delta, deltascaled);
 	else
 		account_idle_time(delta);
-	per_cpu(cputime_last_delta, smp_processor_id()) = delta;
-	per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled;
+	__get_cpu_var(cputime_last_delta) = delta;
+	__get_cpu_var(cputime_scaled_last_delta) = deltascaled;
 	local_irq_restore(flags);
 }
 EXPORT_SYMBOL_GPL(account_system_vtime);
@@ -532,25 +532,60 @@ void __init iSeries_time_init_early(void
 }
 #endif /* CONFIG_PPC_ISERIES */
 
-#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_PPC32)
-DEFINE_PER_CPU(u8, perf_event_pending);
+#ifdef CONFIG_PERF_EVENTS
 
-void set_perf_event_pending(void)
+/*
+ * 64-bit uses a byte in the PACA, 32-bit uses a per-cpu variable...
+ */
+#ifdef CONFIG_PPC64
+static inline unsigned long test_perf_event_pending(void)
 {
-	get_cpu_var(perf_event_pending) = 1;
-	set_dec(1);
-	put_cpu_var(perf_event_pending);
+	unsigned long x;
+
+	asm volatile("lbz %0,%1(13)"
+		: "=r" (x)
+		: "i" (offsetof(struct paca_struct, perf_event_pending)));
+	return x;
+}
+
+static inline void set_perf_event_pending_flag(void)
+{
+	asm volatile("stb %0,%1(13)" : :
+		"r" (1),
+		"i" (offsetof(struct paca_struct, perf_event_pending)));
+}
+
+static inline void clear_perf_event_pending(void)
+{
+	asm volatile("stb %0,%1(13)" : :
+		"r" (0),
+		"i" (offsetof(struct paca_struct, perf_event_pending)));
 }
 
+#else /* 32-bit */
+
+DEFINE_PER_CPU(u8, perf_event_pending);
+
+#define set_perf_event_pending_flag()	__get_cpu_var(perf_event_pending) = 1
 #define test_perf_event_pending()	__get_cpu_var(perf_event_pending)
 #define clear_perf_event_pending()	__get_cpu_var(perf_event_pending) = 0
 
-#else  /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */
+#endif /* 32 vs 64 bit */
+
+void set_perf_event_pending(void)
+{
+	preempt_disable();
+	set_perf_event_pending_flag();
+	set_dec(1);
+	preempt_enable();
+}
+
+#else  /* CONFIG_PERF_EVENTS */
 
 #define test_perf_event_pending()	0
 #define clear_perf_event_pending()
 
-#endif /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */
+#endif /* CONFIG_PERF_EVENTS */
 
 /*
  * For iSeries shared processors, we have to let the hypervisor
@@ -575,15 +610,13 @@ void timer_interrupt(struct pt_regs * re
 
 	trace_timer_interrupt_entry(regs);
 
+	__get_cpu_var(irq_stat).timer_irqs++;
+
 	/* Ensure a positive value is written to the decrementer, or else
 	 * some CPUs will continuue to take decrementer exceptions */
 	set_dec(DECREMENTER_MAX);
 
 #ifdef CONFIG_PPC32
-	if (test_perf_event_pending()) {
-		clear_perf_event_pending();
-		perf_event_do_pending();
-	}
 	if (atomic_read(&ppc_n_lost_interrupts) != 0)
 		do_IRQ(regs);
 #endif
@@ -602,6 +635,11 @@ void timer_interrupt(struct pt_regs * re
 
 	calculate_steal_time();
 
+	if (test_perf_event_pending()) {
+		clear_perf_event_pending();
+		perf_event_do_pending();
+	}
+
 #ifdef CONFIG_PPC_ISERIES
 	if (firmware_has_feature(FW_FEATURE_ISERIES))
 		get_lppaca()->int_dword.fields.decr_int = 0;
@@ -935,8 +973,8 @@ static void register_decrementer_clockev
 	*dec = decrementer_clockevent;
 	dec->cpumask = cpumask_of(cpu);
 
-	printk(KERN_DEBUG "clockevent: %s mult[%x] shift[%d] cpu[%d]\n",
-	       dec->name, dec->mult, dec->shift, cpu);
+	printk_once(KERN_DEBUG "clockevent: %s mult[%x] shift[%d] cpu[%d]\n",
+		    dec->name, dec->mult, dec->shift, cpu);
 
 	clockevents_register_device(dec);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/traps.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/traps.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/traps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/traps.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -60,13 +59,13 @@
 #endif
 
 #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
-int (*__debugger)(struct pt_regs *regs);
-int (*__debugger_ipi)(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);
-int (*__debugger_fault_handler)(struct pt_regs *regs);
+int (*__debugger)(struct pt_regs *regs) __read_mostly;
+int (*__debugger_ipi)(struct pt_regs *regs) __read_mostly;
+int (*__debugger_bpt)(struct pt_regs *regs) __read_mostly;
+int (*__debugger_sstep)(struct pt_regs *regs) __read_mostly;
+int (*__debugger_iabr_match)(struct pt_regs *regs) __read_mostly;
+int (*__debugger_dabr_match)(struct pt_regs *regs) __read_mostly;
+int (*__debugger_fault_handler)(struct pt_regs *regs) __read_mostly;
 
 EXPORT_SYMBOL(__debugger);
 EXPORT_SYMBOL(__debugger_ipi);
@@ -102,11 +101,11 @@ static inline void pmac_backlight_unblan
 int die(const char *str, struct pt_regs *regs, long err)
 {
 	static struct {
-		spinlock_t lock;
+		raw_spinlock_t lock;
 		u32 lock_owner;
 		int lock_owner_depth;
 	} die = {
-		.lock =			__SPIN_LOCK_UNLOCKED(die.lock),
+		.lock =			__RAW_SPIN_LOCK_UNLOCKED(die.lock),
 		.lock_owner =		-1,
 		.lock_owner_depth =	0
 	};
@@ -120,7 +119,7 @@ int die(const char *str, struct pt_regs
 
 	if (die.lock_owner != raw_smp_processor_id()) {
 		console_verbose();
-		spin_lock_irqsave(&die.lock, flags);
+		raw_spin_lock_irqsave(&die.lock, flags);
 		die.lock_owner = smp_processor_id();
 		die.lock_owner_depth = 0;
 		bust_spinlocks(1);
@@ -146,6 +145,11 @@ int die(const char *str, struct pt_regs
 #endif
 		printk("%s\n", ppc_md.name ? ppc_md.name : "");
 
+		sysfs_printk_last_file();
+		if (notify_die(DIE_OOPS, str, regs, err, 255,
+			       SIGSEGV) == NOTIFY_STOP)
+			return 1;
+
 		print_modules();
 		show_regs(regs);
 	} else {
@@ -155,7 +159,7 @@ int die(const char *str, struct pt_regs
 	bust_spinlocks(0);
 	die.lock_owner = -1;
 	add_taint(TAINT_DIE);
-	spin_unlock_irqrestore(&die.lock, flags);
+	raw_spin_unlock_irqrestore(&die.lock, flags);
 
 	if (kexec_should_crash(current) ||
 		kexec_sr_activated(smp_processor_id()))
@@ -294,7 +298,7 @@ static inline int check_io_access(struct
 	return 0;
 }
 
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
 /* On 4xx, the reason for the machine check or program exception
    is in the ESR. */
 #define get_reason(regs)	((regs)->dsisr)
@@ -478,6 +482,8 @@ void machine_check_exception(struct pt_r
 {
 	int recover = 0;
 
+	__get_cpu_var(irq_stat).mce_exceptions++;
+
 	/* See if any machine dependent calls. In theory, we would want
 	 * to call the CPU first, and call the ppc_md. one if the CPU
 	 * one returns a positive number. However there is existing code
@@ -960,6 +966,8 @@ void vsx_unavailable_exception(struct pt
 
 void performance_monitor_exception(struct pt_regs *regs)
 {
+	__get_cpu_var(irq_stat).pmu_irqs++;
+
 	perf_irq(regs);
 }
 
@@ -1024,10 +1032,69 @@ void SoftwareEmulation(struct pt_regs *r
 }
 #endif /* CONFIG_8xx */
 
-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+static void handle_debug(struct pt_regs *regs, unsigned long debug_status)
+{
+	int changed = 0;
+	/*
+	 * Determine the cause of the debug event, clear the
+	 * event flags and send a trap to the handler. Torez
+	 */
+	if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
+		dbcr_dac(current) &= ~(DBCR_DAC1R | DBCR_DAC1W);
+#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
+		current->thread.dbcr2 &= ~DBCR2_DAC12MODE;
+#endif
+		do_send_trap(regs, mfspr(SPRN_DAC1), debug_status, TRAP_HWBKPT,
+			     5);
+		changed |= 0x01;
+	}  else if (debug_status & (DBSR_DAC2R | DBSR_DAC2W)) {
+		dbcr_dac(current) &= ~(DBCR_DAC2R | DBCR_DAC2W);
+		do_send_trap(regs, mfspr(SPRN_DAC2), debug_status, TRAP_HWBKPT,
+			     6);
+		changed |= 0x01;
+	}  else if (debug_status & DBSR_IAC1) {
+		current->thread.dbcr0 &= ~DBCR0_IAC1;
+		dbcr_iac_range(current) &= ~DBCR_IAC12MODE;
+		do_send_trap(regs, mfspr(SPRN_IAC1), debug_status, TRAP_HWBKPT,
+			     1);
+		changed |= 0x01;
+	}  else if (debug_status & DBSR_IAC2) {
+		current->thread.dbcr0 &= ~DBCR0_IAC2;
+		do_send_trap(regs, mfspr(SPRN_IAC2), debug_status, TRAP_HWBKPT,
+			     2);
+		changed |= 0x01;
+	}  else if (debug_status & DBSR_IAC3) {
+		current->thread.dbcr0 &= ~DBCR0_IAC3;
+		dbcr_iac_range(current) &= ~DBCR_IAC34MODE;
+		do_send_trap(regs, mfspr(SPRN_IAC3), debug_status, TRAP_HWBKPT,
+			     3);
+		changed |= 0x01;
+	}  else if (debug_status & DBSR_IAC4) {
+		current->thread.dbcr0 &= ~DBCR0_IAC4;
+		do_send_trap(regs, mfspr(SPRN_IAC4), debug_status, TRAP_HWBKPT,
+			     4);
+		changed |= 0x01;
+	}
+	/*
+	 * At the point this routine was called, the MSR(DE) was turned off.
+	 * Check all other debug flags and see if that bit needs to be turned
+	 * back on or not.
+	 */
+	if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0, current->thread.dbcr1))
+		regs->msr |= MSR_DE;
+	else
+		/* Make sure the IDM flag is off */
+		current->thread.dbcr0 &= ~DBCR0_IDM;
+
+	if (changed & 0x01)
+		mtspr(SPRN_DBCR0, current->thread.dbcr0);
+}
 
 void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
 {
+	current->thread.dbsr = debug_status;
+
 	/* Hack alert: On BookE, Branch Taken stops on the branch itself, while
 	 * on server, it stops on the target of the branch. In order to simulate
 	 * the server behaviour, we thus restart right away with a single step
@@ -1071,29 +1138,23 @@ void __kprobes DebugException(struct pt_
 		if (debugger_sstep(regs))
 			return;
 
-		if (user_mode(regs))
-			current->thread.dbcr0 &= ~(DBCR0_IC);
-
-		_exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
-	} else if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
-		regs->msr &= ~MSR_DE;
-
 		if (user_mode(regs)) {
-			current->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W |
-								DBCR0_IDM);
-		} else {
-			/* Disable DAC interupts */
-			mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~(DBSR_DAC1R |
-						DBSR_DAC1W | DBCR0_IDM));
-
-			/* Clear the DAC event */
-			mtspr(SPRN_DBSR, (DBSR_DAC1R | DBSR_DAC1W));
+			current->thread.dbcr0 &= ~DBCR0_IC;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+			if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0,
+					       current->thread.dbcr1))
+				regs->msr |= MSR_DE;
+			else
+				/* Make sure the IDM bit is off */
+				current->thread.dbcr0 &= ~DBCR0_IDM;
+#endif
 		}
-		/* Setup and send the trap to the handler */
-		do_dabr(regs, mfspr(SPRN_DAC1), debug_status);
-	}
+
+		_exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
+	} else
+		handle_debug(regs, debug_status);
 }
-#endif /* CONFIG_4xx || CONFIG_BOOKE */
+#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
 
 #if !defined(CONFIG_TAU_INT)
 void TAUException(struct pt_regs *regs)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kernel/vio.c linux-libre-2.6.34-gnu1/arch/powerpc/kernel/vio.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kernel/vio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kernel/vio.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/types.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/console.h>
 #include <linux/module.h>
 #include <linux/mm.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/44x.c linux-libre-2.6.34-gnu1/arch/powerpc/kvm/44x.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/44x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/44x.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
  */
 
 #include <linux/kvm_host.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 
 #include <asm/reg.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/44x_emulate.c linux-libre-2.6.34-gnu1/arch/powerpc/kvm/44x_emulate.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/44x_emulate.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/44x_emulate.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,13 +65,14 @@ int kvmppc_core_emulate_op(struct kvm_ru
 			 */
 			switch (dcrn) {
 			case DCRN_CPR0_CONFIG_ADDR:
-				vcpu->arch.gpr[rt] = vcpu->arch.cpr0_cfgaddr;
+				kvmppc_set_gpr(vcpu, rt, vcpu->arch.cpr0_cfgaddr);
 				break;
 			case DCRN_CPR0_CONFIG_DATA:
 				local_irq_disable();
 				mtdcr(DCRN_CPR0_CONFIG_ADDR,
 					  vcpu->arch.cpr0_cfgaddr);
-				vcpu->arch.gpr[rt] = mfdcr(DCRN_CPR0_CONFIG_DATA);
+				kvmppc_set_gpr(vcpu, rt,
+					       mfdcr(DCRN_CPR0_CONFIG_DATA));
 				local_irq_enable();
 				break;
 			default:
@@ -93,11 +94,11 @@ int kvmppc_core_emulate_op(struct kvm_ru
 			/* emulate some access in kernel */
 			switch (dcrn) {
 			case DCRN_CPR0_CONFIG_ADDR:
-				vcpu->arch.cpr0_cfgaddr = vcpu->arch.gpr[rs];
+				vcpu->arch.cpr0_cfgaddr = kvmppc_get_gpr(vcpu, rs);
 				break;
 			default:
 				run->dcr.dcrn = dcrn;
-				run->dcr.data = vcpu->arch.gpr[rs];
+				run->dcr.data = kvmppc_get_gpr(vcpu, rs);
 				run->dcr.is_write = 1;
 				vcpu->arch.dcr_needed = 1;
 				kvmppc_account_exit(vcpu, DCR_EXITS);
@@ -146,13 +147,13 @@ int kvmppc_core_emulate_mtspr(struct kvm
 
 	switch (sprn) {
 	case SPRN_PID:
-		kvmppc_set_pid(vcpu, vcpu->arch.gpr[rs]); break;
+		kvmppc_set_pid(vcpu, kvmppc_get_gpr(vcpu, rs)); break;
 	case SPRN_MMUCR:
-		vcpu->arch.mmucr = vcpu->arch.gpr[rs]; break;
+		vcpu->arch.mmucr = kvmppc_get_gpr(vcpu, rs); break;
 	case SPRN_CCR0:
-		vcpu->arch.ccr0 = vcpu->arch.gpr[rs]; break;
+		vcpu->arch.ccr0 = kvmppc_get_gpr(vcpu, rs); break;
 	case SPRN_CCR1:
-		vcpu->arch.ccr1 = vcpu->arch.gpr[rs]; break;
+		vcpu->arch.ccr1 = kvmppc_get_gpr(vcpu, rs); break;
 	default:
 		emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs);
 	}
@@ -167,13 +168,13 @@ int kvmppc_core_emulate_mfspr(struct kvm
 
 	switch (sprn) {
 	case SPRN_PID:
-		vcpu->arch.gpr[rt] = vcpu->arch.pid; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.pid); break;
 	case SPRN_MMUCR:
-		vcpu->arch.gpr[rt] = vcpu->arch.mmucr; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.mmucr); break;
 	case SPRN_CCR0:
-		vcpu->arch.gpr[rt] = vcpu->arch.ccr0; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ccr0); break;
 	case SPRN_CCR1:
-		vcpu->arch.gpr[rt] = vcpu->arch.ccr1; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ccr1); break;
 	default:
 		emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);
 	}
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/44x_tlb.c linux-libre-2.6.34-gnu1/arch/powerpc/kvm/44x_tlb.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/44x_tlb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/44x_tlb.c	2010-05-16 17:17:36.000000000 -0400
@@ -439,8 +439,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcp
 	struct kvmppc_44x_tlbe *tlbe;
 	unsigned int gtlb_index;
 
-	gtlb_index = vcpu->arch.gpr[ra];
-	if (gtlb_index > KVM44x_GUEST_TLB_SIZE) {
+	gtlb_index = kvmppc_get_gpr(vcpu, ra);
+	if (gtlb_index >= KVM44x_GUEST_TLB_SIZE) {
 		printk("%s: index %d\n", __func__, gtlb_index);
 		kvmppc_dump_vcpu(vcpu);
 		return EMULATE_FAIL;
@@ -455,15 +455,15 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcp
 	switch (ws) {
 	case PPC44x_TLB_PAGEID:
 		tlbe->tid = get_mmucr_stid(vcpu);
-		tlbe->word0 = vcpu->arch.gpr[rs];
+		tlbe->word0 = kvmppc_get_gpr(vcpu, rs);
 		break;
 
 	case PPC44x_TLB_XLAT:
-		tlbe->word1 = vcpu->arch.gpr[rs];
+		tlbe->word1 = kvmppc_get_gpr(vcpu, rs);
 		break;
 
 	case PPC44x_TLB_ATTRIB:
-		tlbe->word2 = vcpu->arch.gpr[rs];
+		tlbe->word2 = kvmppc_get_gpr(vcpu, rs);
 		break;
 
 	default:
@@ -500,18 +500,20 @@ int kvmppc_44x_emul_tlbsx(struct kvm_vcp
 	unsigned int as = get_mmucr_sts(vcpu);
 	unsigned int pid = get_mmucr_stid(vcpu);
 
-	ea = vcpu->arch.gpr[rb];
+	ea = kvmppc_get_gpr(vcpu, rb);
 	if (ra)
-		ea += vcpu->arch.gpr[ra];
+		ea += kvmppc_get_gpr(vcpu, ra);
 
 	gtlb_index = kvmppc_44x_tlb_index(vcpu, ea, pid, as);
 	if (rc) {
+		u32 cr = kvmppc_get_cr(vcpu);
+
 		if (gtlb_index < 0)
-			vcpu->arch.cr &= ~0x20000000;
+			kvmppc_set_cr(vcpu, cr & ~0x20000000);
 		else
-			vcpu->arch.cr |= 0x20000000;
+			kvmppc_set_cr(vcpu, cr | 0x20000000);
 	}
-	vcpu->arch.gpr[rt] = gtlb_index;
+	kvmppc_set_gpr(vcpu, rt, gtlb_index);
 
 	kvmppc_set_exit_type(vcpu, EMULATED_TLBSX_EXITS);
 	return EMULATE_DONE;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_emulate.c linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s_64_emulate.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_emulate.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s_64_emulate.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,11 +65,11 @@ int kvmppc_core_emulate_op(struct kvm_ru
 	case 31:
 		switch (get_xop(inst)) {
 		case OP_31_XOP_MFMSR:
-			vcpu->arch.gpr[get_rt(inst)] = vcpu->arch.msr;
+			kvmppc_set_gpr(vcpu, get_rt(inst), vcpu->arch.msr);
 			break;
 		case OP_31_XOP_MTMSRD:
 		{
-			ulong rs = vcpu->arch.gpr[get_rs(inst)];
+			ulong rs = kvmppc_get_gpr(vcpu, get_rs(inst));
 			if (inst & 0x10000) {
 				vcpu->arch.msr &= ~(MSR_RI | MSR_EE);
 				vcpu->arch.msr |= rs & (MSR_RI | MSR_EE);
@@ -78,30 +78,30 @@ int kvmppc_core_emulate_op(struct kvm_ru
 			break;
 		}
 		case OP_31_XOP_MTMSR:
-			kvmppc_set_msr(vcpu, vcpu->arch.gpr[get_rs(inst)]);
+			kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, get_rs(inst)));
 			break;
 		case OP_31_XOP_MFSRIN:
 		{
 			int srnum;
 
-			srnum = (vcpu->arch.gpr[get_rb(inst)] >> 28) & 0xf;
+			srnum = (kvmppc_get_gpr(vcpu, get_rb(inst)) >> 28) & 0xf;
 			if (vcpu->arch.mmu.mfsrin) {
 				u32 sr;
 				sr = vcpu->arch.mmu.mfsrin(vcpu, srnum);
-				vcpu->arch.gpr[get_rt(inst)] = sr;
+				kvmppc_set_gpr(vcpu, get_rt(inst), sr);
 			}
 			break;
 		}
 		case OP_31_XOP_MTSRIN:
 			vcpu->arch.mmu.mtsrin(vcpu,
-				(vcpu->arch.gpr[get_rb(inst)] >> 28) & 0xf,
-				vcpu->arch.gpr[get_rs(inst)]);
+				(kvmppc_get_gpr(vcpu, get_rb(inst)) >> 28) & 0xf,
+				kvmppc_get_gpr(vcpu, get_rs(inst)));
 			break;
 		case OP_31_XOP_TLBIE:
 		case OP_31_XOP_TLBIEL:
 		{
 			bool large = (inst & 0x00200000) ? true : false;
-			ulong addr = vcpu->arch.gpr[get_rb(inst)];
+			ulong addr = kvmppc_get_gpr(vcpu, get_rb(inst));
 			vcpu->arch.mmu.tlbie(vcpu, addr, large);
 			break;
 		}
@@ -111,14 +111,16 @@ int kvmppc_core_emulate_op(struct kvm_ru
 			if (!vcpu->arch.mmu.slbmte)
 				return EMULATE_FAIL;
 
-			vcpu->arch.mmu.slbmte(vcpu, vcpu->arch.gpr[get_rs(inst)],
-						vcpu->arch.gpr[get_rb(inst)]);
+			vcpu->arch.mmu.slbmte(vcpu,
+					kvmppc_get_gpr(vcpu, get_rs(inst)),
+					kvmppc_get_gpr(vcpu, get_rb(inst)));
 			break;
 		case OP_31_XOP_SLBIE:
 			if (!vcpu->arch.mmu.slbie)
 				return EMULATE_FAIL;
 
-			vcpu->arch.mmu.slbie(vcpu, vcpu->arch.gpr[get_rb(inst)]);
+			vcpu->arch.mmu.slbie(vcpu,
+					kvmppc_get_gpr(vcpu, get_rb(inst)));
 			break;
 		case OP_31_XOP_SLBIA:
 			if (!vcpu->arch.mmu.slbia)
@@ -132,9 +134,9 @@ int kvmppc_core_emulate_op(struct kvm_ru
 			} else {
 				ulong t, rb;
 
-				rb = vcpu->arch.gpr[get_rb(inst)];
+				rb = kvmppc_get_gpr(vcpu, get_rb(inst));
 				t = vcpu->arch.mmu.slbmfee(vcpu, rb);
-				vcpu->arch.gpr[get_rt(inst)] = t;
+				kvmppc_set_gpr(vcpu, get_rt(inst), t);
 			}
 			break;
 		case OP_31_XOP_SLBMFEV:
@@ -143,20 +145,20 @@ int kvmppc_core_emulate_op(struct kvm_ru
 			} else {
 				ulong t, rb;
 
-				rb = vcpu->arch.gpr[get_rb(inst)];
+				rb = kvmppc_get_gpr(vcpu, get_rb(inst));
 				t = vcpu->arch.mmu.slbmfev(vcpu, rb);
-				vcpu->arch.gpr[get_rt(inst)] = t;
+				kvmppc_set_gpr(vcpu, get_rt(inst), t);
 			}
 			break;
 		case OP_31_XOP_DCBZ:
 		{
-			ulong rb =  vcpu->arch.gpr[get_rb(inst)];
+			ulong rb = kvmppc_get_gpr(vcpu, get_rb(inst));
 			ulong ra = 0;
 			ulong addr;
 			u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 
 			if (get_ra(inst))
-				ra = vcpu->arch.gpr[get_ra(inst)];
+				ra = kvmppc_get_gpr(vcpu, get_ra(inst));
 
 			addr = (ra + rb) & ~31ULL;
 			if (!(vcpu->arch.msr & MSR_SF))
@@ -233,43 +235,44 @@ static void kvmppc_write_bat(struct kvm_
 int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
 {
 	int emulated = EMULATE_DONE;
+	ulong spr_val = kvmppc_get_gpr(vcpu, rs);
 
 	switch (sprn) {
 	case SPRN_SDR1:
-		to_book3s(vcpu)->sdr1 = vcpu->arch.gpr[rs];
+		to_book3s(vcpu)->sdr1 = spr_val;
 		break;
 	case SPRN_DSISR:
-		to_book3s(vcpu)->dsisr = vcpu->arch.gpr[rs];
+		to_book3s(vcpu)->dsisr = spr_val;
 		break;
 	case SPRN_DAR:
-		vcpu->arch.dear = vcpu->arch.gpr[rs];
+		vcpu->arch.dear = spr_val;
 		break;
 	case SPRN_HIOR:
-		to_book3s(vcpu)->hior = vcpu->arch.gpr[rs];
+		to_book3s(vcpu)->hior = spr_val;
 		break;
 	case SPRN_IBAT0U ... SPRN_IBAT3L:
 	case SPRN_IBAT4U ... SPRN_IBAT7L:
 	case SPRN_DBAT0U ... SPRN_DBAT3L:
 	case SPRN_DBAT4U ... SPRN_DBAT7L:
-		kvmppc_write_bat(vcpu, sprn, (u32)vcpu->arch.gpr[rs]);
+		kvmppc_write_bat(vcpu, sprn, (u32)spr_val);
 		/* BAT writes happen so rarely that we're ok to flush
 		 * everything here */
 		kvmppc_mmu_pte_flush(vcpu, 0, 0);
 		break;
 	case SPRN_HID0:
-		to_book3s(vcpu)->hid[0] = vcpu->arch.gpr[rs];
+		to_book3s(vcpu)->hid[0] = spr_val;
 		break;
 	case SPRN_HID1:
-		to_book3s(vcpu)->hid[1] = vcpu->arch.gpr[rs];
+		to_book3s(vcpu)->hid[1] = spr_val;
 		break;
 	case SPRN_HID2:
-		to_book3s(vcpu)->hid[2] = vcpu->arch.gpr[rs];
+		to_book3s(vcpu)->hid[2] = spr_val;
 		break;
 	case SPRN_HID4:
-		to_book3s(vcpu)->hid[4] = vcpu->arch.gpr[rs];
+		to_book3s(vcpu)->hid[4] = spr_val;
 		break;
 	case SPRN_HID5:
-		to_book3s(vcpu)->hid[5] = vcpu->arch.gpr[rs];
+		to_book3s(vcpu)->hid[5] = spr_val;
 		/* guest HID5 set can change is_dcbz32 */
 		if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
 		    (mfmsr() & MSR_HV))
@@ -299,38 +302,38 @@ int kvmppc_core_emulate_mfspr(struct kvm
 
 	switch (sprn) {
 	case SPRN_SDR1:
-		vcpu->arch.gpr[rt] = to_book3s(vcpu)->sdr1;
+		kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->sdr1);
 		break;
 	case SPRN_DSISR:
-		vcpu->arch.gpr[rt] = to_book3s(vcpu)->dsisr;
+		kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->dsisr);
 		break;
 	case SPRN_DAR:
-		vcpu->arch.gpr[rt] = vcpu->arch.dear;
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.dear);
 		break;
 	case SPRN_HIOR:
-		vcpu->arch.gpr[rt] = to_book3s(vcpu)->hior;
+		kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hior);
 		break;
 	case SPRN_HID0:
-		vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[0];
+		kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[0]);
 		break;
 	case SPRN_HID1:
-		vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[1];
+		kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[1]);
 		break;
 	case SPRN_HID2:
-		vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[2];
+		kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[2]);
 		break;
 	case SPRN_HID4:
-		vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[4];
+		kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[4]);
 		break;
 	case SPRN_HID5:
-		vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[5];
+		kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[5]);
 		break;
 	case SPRN_THRM1:
 	case SPRN_THRM2:
 	case SPRN_THRM3:
 	case SPRN_CTRLF:
 	case SPRN_CTRLT:
-		vcpu->arch.gpr[rt] = 0;
+		kvmppc_set_gpr(vcpu, rt, 0);
 		break;
 	default:
 		printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_exports.c linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s_64_exports.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_exports.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s_64_exports.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,3 +22,11 @@
 
 EXPORT_SYMBOL_GPL(kvmppc_trampoline_enter);
 EXPORT_SYMBOL_GPL(kvmppc_trampoline_lowmem);
+EXPORT_SYMBOL_GPL(kvmppc_rmcall);
+EXPORT_SYMBOL_GPL(kvmppc_load_up_fpu);
+#ifdef CONFIG_ALTIVEC
+EXPORT_SYMBOL_GPL(kvmppc_load_up_altivec);
+#endif
+#ifdef CONFIG_VSX
+EXPORT_SYMBOL_GPL(kvmppc_load_up_vsx);
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_interrupts.S linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s_64_interrupts.S
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_interrupts.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s_64_interrupts.S	2010-05-16 17:17:36.000000000 -0400
@@ -28,11 +28,6 @@
 #define ULONG_SIZE 8
 #define VCPU_GPR(n)     (VCPU_GPRS + (n * ULONG_SIZE))
 
-.macro mfpaca tmp_reg, src_reg, offset, vcpu_reg
-	ld	\tmp_reg, (PACA_EXMC+\offset)(r13)
-	std	\tmp_reg, VCPU_GPR(\src_reg)(\vcpu_reg)
-.endm
-
 .macro DISABLE_INTERRUPTS
        mfmsr   r0
        rldicl  r0,r0,48,1
@@ -40,6 +35,26 @@
        mtmsrd  r0,1
 .endm
 
+#define VCPU_LOAD_NVGPRS(vcpu) \
+	ld	r14, VCPU_GPR(r14)(vcpu); \
+	ld	r15, VCPU_GPR(r15)(vcpu); \
+	ld	r16, VCPU_GPR(r16)(vcpu); \
+	ld	r17, VCPU_GPR(r17)(vcpu); \
+	ld	r18, VCPU_GPR(r18)(vcpu); \
+	ld	r19, VCPU_GPR(r19)(vcpu); \
+	ld	r20, VCPU_GPR(r20)(vcpu); \
+	ld	r21, VCPU_GPR(r21)(vcpu); \
+	ld	r22, VCPU_GPR(r22)(vcpu); \
+	ld	r23, VCPU_GPR(r23)(vcpu); \
+	ld	r24, VCPU_GPR(r24)(vcpu); \
+	ld	r25, VCPU_GPR(r25)(vcpu); \
+	ld	r26, VCPU_GPR(r26)(vcpu); \
+	ld	r27, VCPU_GPR(r27)(vcpu); \
+	ld	r28, VCPU_GPR(r28)(vcpu); \
+	ld	r29, VCPU_GPR(r29)(vcpu); \
+	ld	r30, VCPU_GPR(r30)(vcpu); \
+	ld	r31, VCPU_GPR(r31)(vcpu); \
+
 /*****************************************************************************
  *                                                                           *
  *     Guest entry / exit code that is in kernel module memory (highmem)     *
@@ -67,61 +82,32 @@ kvm_start_entry:
 	SAVE_NVGPRS(r1)
 
 	/* Save LR */
-	mflr	r14
-	std	r14, _LINK(r1)
-
-/* XXX optimize non-volatile loading away */
-kvm_start_lightweight:
+	std	r0, _LINK(r1)
 
-	DISABLE_INTERRUPTS
+	/* Load non-volatile guest state from the vcpu */
+	VCPU_LOAD_NVGPRS(r4)
 
 	/* Save R1/R2 in the PACA */
-	std	r1, PACAR1(r13)
-	std	r2, (PACA_EXMC+EX_SRR0)(r13)
+	std	r1, PACA_KVM_HOST_R1(r13)
+	std	r2, PACA_KVM_HOST_R2(r13)
+
+	/* XXX swap in/out on load? */
 	ld	r3, VCPU_HIGHMEM_HANDLER(r4)
-	std	r3, PACASAVEDMSR(r13)
+	std	r3, PACA_KVM_VMHANDLER(r13)
 
-	/* Load non-volatile guest state from the vcpu */
-	ld	r14, VCPU_GPR(r14)(r4)
-	ld	r15, VCPU_GPR(r15)(r4)
-	ld	r16, VCPU_GPR(r16)(r4)
-	ld	r17, VCPU_GPR(r17)(r4)
-	ld	r18, VCPU_GPR(r18)(r4)
-	ld	r19, VCPU_GPR(r19)(r4)
-	ld	r20, VCPU_GPR(r20)(r4)
-	ld	r21, VCPU_GPR(r21)(r4)
-	ld	r22, VCPU_GPR(r22)(r4)
-	ld	r23, VCPU_GPR(r23)(r4)
-	ld	r24, VCPU_GPR(r24)(r4)
-	ld	r25, VCPU_GPR(r25)(r4)
-	ld	r26, VCPU_GPR(r26)(r4)
-	ld	r27, VCPU_GPR(r27)(r4)
-	ld	r28, VCPU_GPR(r28)(r4)
-	ld	r29, VCPU_GPR(r29)(r4)
-	ld	r30, VCPU_GPR(r30)(r4)
-	ld	r31, VCPU_GPR(r31)(r4)
+kvm_start_lightweight:
 
 	ld	r9, VCPU_PC(r4)			/* r9 = vcpu->arch.pc */
 	ld	r10, VCPU_SHADOW_MSR(r4)	/* r10 = vcpu->arch.shadow_msr */
 
-	ld	r3, VCPU_TRAMPOLINE_ENTER(r4)
-	mtsrr0	r3
-
-	LOAD_REG_IMMEDIATE(r3, MSR_KERNEL & ~(MSR_IR | MSR_DR))
-	mtsrr1	r3
-
-	/* Load guest state in the respective registers */
-	lwz	r3, VCPU_CR(r4)		/* r3 = vcpu->arch.cr */
-	stw	r3, (PACA_EXMC + EX_CCR)(r13)
-
-	ld	r3, VCPU_CTR(r4)	/* r3 = vcpu->arch.ctr */
-	mtctr	r3			/* CTR = r3 */
+	/* Load some guest state in the respective registers */
+	ld	r5, VCPU_CTR(r4)	/* r5 = vcpu->arch.ctr */
+					/* will be swapped in by rmcall */
 
 	ld	r3, VCPU_LR(r4)		/* r3 = vcpu->arch.lr */
 	mtlr	r3			/* LR = r3 */
 
-	ld	r3, VCPU_XER(r4)	/* r3 = vcpu->arch.xer */
-	std	r3, (PACA_EXMC + EX_R3)(r13)
+	DISABLE_INTERRUPTS
 
 	/* Some guests may need to have dcbz set to 32 byte length.
 	 *
@@ -141,36 +127,15 @@ kvm_start_lightweight:
 	mtspr   SPRN_HID5,r3
 
 no_dcbz32_on:
-	/*	Load guest GPRs */
-
-	ld	r3, VCPU_GPR(r9)(r4)
-	std	r3, (PACA_EXMC + EX_R9)(r13)
-	ld	r3, VCPU_GPR(r10)(r4)
-	std	r3, (PACA_EXMC + EX_R10)(r13)
-	ld	r3, VCPU_GPR(r11)(r4)
-	std	r3, (PACA_EXMC + EX_R11)(r13)
-	ld	r3, VCPU_GPR(r12)(r4)
-	std	r3, (PACA_EXMC + EX_R12)(r13)
-	ld	r3, VCPU_GPR(r13)(r4)
-	std	r3, (PACA_EXMC + EX_R13)(r13)
 
-	ld	r0, VCPU_GPR(r0)(r4)
-	ld	r1, VCPU_GPR(r1)(r4)
-	ld	r2, VCPU_GPR(r2)(r4)
-	ld	r3, VCPU_GPR(r3)(r4)
-	ld	r5, VCPU_GPR(r5)(r4)
-	ld	r6, VCPU_GPR(r6)(r4)
-	ld	r7, VCPU_GPR(r7)(r4)
-	ld	r8, VCPU_GPR(r8)(r4)
-	ld	r4, VCPU_GPR(r4)(r4)
-
-	/* This sets the Magic value for the trampoline */
+	ld	r6, VCPU_RMCALL(r4)
+	mtctr	r6
 
-	li	r11, 1
-	stb	r11, PACA_KVM_IN_GUEST(r13)
+	ld	r3, VCPU_TRAMPOLINE_ENTER(r4)
+	LOAD_REG_IMMEDIATE(r4, MSR_KERNEL & ~(MSR_IR | MSR_DR))
 
 	/* Jump to SLB patching handlder and into our guest */
-	RFI
+	bctr
 
 /*
  * This is the handler in module memory. It gets jumped at from the
@@ -184,125 +149,70 @@ kvmppc_handler_highmem:
 	/*
 	 * Register usage at this point:
 	 *
-	 * R00   = guest R13
-	 * R01   = host R1
-	 * R02   = host R2
-	 * R10   = guest PC
-	 * R11   = guest MSR
-	 * R12   = exit handler id
-	 * R13   = PACA
-	 * PACA.exmc.R9    = guest R1
-	 * PACA.exmc.R10   = guest R10
-	 * PACA.exmc.R11   = guest R11
-	 * PACA.exmc.R12   = guest R12
-	 * PACA.exmc.R13   = guest R2
-	 * PACA.exmc.DAR   = guest DAR
-	 * PACA.exmc.DSISR = guest DSISR
-	 * PACA.exmc.LR    = guest instruction
-	 * PACA.exmc.CCR   = guest CR
-	 * PACA.exmc.SRR0  = guest R0
+	 * R0         = guest last inst
+	 * R1         = host R1
+	 * R2         = host R2
+	 * R3         = guest PC
+	 * R4         = guest MSR
+	 * R5         = guest DAR
+	 * R6         = guest DSISR
+	 * R13        = PACA
+	 * PACA.KVM.* = guest *
 	 *
 	 */
 
-	std	r3, (PACA_EXMC+EX_R3)(r13)
-
-	/* save the exit id in R3 */
-	mr	r3, r12
-
-	/* R12 = vcpu */
-	ld	r12, GPR4(r1)
+	/* R7 = vcpu */
+	ld	r7, GPR4(r1)
 
 	/* Now save the guest state */
 
-	std	r0, VCPU_GPR(r13)(r12)
-	std	r4, VCPU_GPR(r4)(r12)
-	std	r5, VCPU_GPR(r5)(r12)
-	std	r6, VCPU_GPR(r6)(r12)
-	std	r7, VCPU_GPR(r7)(r12)
-	std	r8, VCPU_GPR(r8)(r12)
-	std	r9, VCPU_GPR(r9)(r12)
-
-	/* get registers from PACA */
-	mfpaca	r5, r0, EX_SRR0, r12
-	mfpaca	r5, r3, EX_R3, r12
-	mfpaca	r5, r1, EX_R9, r12
-	mfpaca	r5, r10, EX_R10, r12
-	mfpaca	r5, r11, EX_R11, r12
-	mfpaca	r5, r12, EX_R12, r12
-	mfpaca	r5, r2, EX_R13, r12
-
-	lwz	r5, (PACA_EXMC+EX_LR)(r13)
-	stw	r5, VCPU_LAST_INST(r12)
+	stw	r0, VCPU_LAST_INST(r7)
 
-	lwz	r5, (PACA_EXMC+EX_CCR)(r13)
-	stw	r5, VCPU_CR(r12)
+	std	r3, VCPU_PC(r7)
+	std	r4, VCPU_SHADOW_SRR1(r7)
+	std	r5, VCPU_FAULT_DEAR(r7)
+	std	r6, VCPU_FAULT_DSISR(r7)
 
-	ld	r5, VCPU_HFLAGS(r12)
+	ld	r5, VCPU_HFLAGS(r7)
 	rldicl.	r5, r5, 0, 63		/* CR = ((r5 & 1) == 0) */
 	beq	no_dcbz32_off
 
+	li	r4, 0
 	mfspr   r5,SPRN_HID5
-	rldimi  r5,r5,6,56
+	rldimi  r5,r4,6,56
 	mtspr   SPRN_HID5,r5
 
 no_dcbz32_off:
 
-	/* XXX maybe skip on lightweight? */
-	std	r14, VCPU_GPR(r14)(r12)
-	std	r15, VCPU_GPR(r15)(r12)
-	std	r16, VCPU_GPR(r16)(r12)
-	std	r17, VCPU_GPR(r17)(r12)
-	std	r18, VCPU_GPR(r18)(r12)
-	std	r19, VCPU_GPR(r19)(r12)
-	std	r20, VCPU_GPR(r20)(r12)
-	std	r21, VCPU_GPR(r21)(r12)
-	std	r22, VCPU_GPR(r22)(r12)
-	std	r23, VCPU_GPR(r23)(r12)
-	std	r24, VCPU_GPR(r24)(r12)
-	std	r25, VCPU_GPR(r25)(r12)
-	std	r26, VCPU_GPR(r26)(r12)
-	std	r27, VCPU_GPR(r27)(r12)
-	std	r28, VCPU_GPR(r28)(r12)
-	std	r29, VCPU_GPR(r29)(r12)
-	std	r30, VCPU_GPR(r30)(r12)
-	std	r31, VCPU_GPR(r31)(r12)
-
-	/* Restore non-volatile host registers (r14 - r31) */
-	REST_NVGPRS(r1)
-
-	/* Save guest PC (R10) */
-	std	r10, VCPU_PC(r12)
-
-	/* Save guest msr (R11) */
-	std	r11, VCPU_SHADOW_MSR(r12)
+	std	r14, VCPU_GPR(r14)(r7)
+	std	r15, VCPU_GPR(r15)(r7)
+	std	r16, VCPU_GPR(r16)(r7)
+	std	r17, VCPU_GPR(r17)(r7)
+	std	r18, VCPU_GPR(r18)(r7)
+	std	r19, VCPU_GPR(r19)(r7)
+	std	r20, VCPU_GPR(r20)(r7)
+	std	r21, VCPU_GPR(r21)(r7)
+	std	r22, VCPU_GPR(r22)(r7)
+	std	r23, VCPU_GPR(r23)(r7)
+	std	r24, VCPU_GPR(r24)(r7)
+	std	r25, VCPU_GPR(r25)(r7)
+	std	r26, VCPU_GPR(r26)(r7)
+	std	r27, VCPU_GPR(r27)(r7)
+	std	r28, VCPU_GPR(r28)(r7)
+	std	r29, VCPU_GPR(r29)(r7)
+	std	r30, VCPU_GPR(r30)(r7)
+	std	r31, VCPU_GPR(r31)(r7)
 
-	/* Save guest CTR (in R12) */
+	/* Save guest CTR */
 	mfctr	r5
-	std	r5, VCPU_CTR(r12)
+	std	r5, VCPU_CTR(r7)
 
 	/* Save guest LR */
 	mflr	r5
-	std	r5, VCPU_LR(r12)
-
-	/* Save guest XER */
-	mfxer	r5
-	std	r5, VCPU_XER(r12)
-
-	/* Save guest DAR */
-	ld	r5, (PACA_EXMC+EX_DAR)(r13)
-	std	r5, VCPU_FAULT_DEAR(r12)
-
-	/* Save guest DSISR */
-	lwz	r5, (PACA_EXMC+EX_DSISR)(r13)
-	std	r5, VCPU_FAULT_DSISR(r12)
+	std	r5, VCPU_LR(r7)
 
 	/* Restore host msr -> SRR1 */
-	ld	r7, VCPU_HOST_MSR(r12)
-	mtsrr1	r7
-
-	/* Restore host IP -> SRR0 */
-	ld	r6, VCPU_HOST_RETIP(r12)
-	mtsrr0	r6
+	ld	r6, VCPU_HOST_MSR(r7)
 
 	/*
 	 * For some interrupts, we need to call the real Linux
@@ -314,13 +224,14 @@ no_dcbz32_off:
 	 * r3 = address of interrupt handler (exit reason)
 	 */
 
-	cmpwi	r3, BOOK3S_INTERRUPT_EXTERNAL
+	cmpwi	r12, BOOK3S_INTERRUPT_EXTERNAL
 	beq	call_linux_handler
-	cmpwi	r3, BOOK3S_INTERRUPT_DECREMENTER
+	cmpwi	r12, BOOK3S_INTERRUPT_DECREMENTER
 	beq	call_linux_handler
 
-	/* Back to Interruptable Mode! (goto kvm_return_point) */
-	RFI
+	/* Back to EE=1 */
+	mtmsr	r6
+	b	kvm_return_point
 
 call_linux_handler:
 
@@ -333,16 +244,22 @@ call_linux_handler:
 	 * interrupt handler!
 	 *
 	 * R3 still contains the exit code,
-	 * R6 VCPU_HOST_RETIP and
-	 * R7 VCPU_HOST_MSR
+	 * R5 VCPU_HOST_RETIP and
+	 * R6 VCPU_HOST_MSR
 	 */
 
-	mtlr	r3
+	/* Restore host IP -> SRR0 */
+	ld	r5, VCPU_HOST_RETIP(r7)
 
-	ld	r5, VCPU_TRAMPOLINE_LOWMEM(r12)
-	mtsrr0	r5
-	LOAD_REG_IMMEDIATE(r5, MSR_KERNEL & ~(MSR_IR | MSR_DR))
-	mtsrr1	r5
+	/* XXX Better move to a safe function?
+	 *     What if we get an HTAB flush in between mtsrr0 and mtsrr1? */
+
+	mtlr	r12
+
+	ld	r4, VCPU_TRAMPOLINE_LOWMEM(r7)
+	mtsrr0	r4
+	LOAD_REG_IMMEDIATE(r3, MSR_KERNEL & ~(MSR_IR | MSR_DR))
+	mtsrr1	r3
 
 	RFI
 
@@ -351,42 +268,51 @@ kvm_return_point:
 
 	/* Jump back to lightweight entry if we're supposed to */
 	/* go back into the guest */
-	mr	r5, r3
+
+	/* Pass the exit number as 3rd argument to kvmppc_handle_exit */
+	mr	r5, r12
+
 	/* Restore r3 (kvm_run) and r4 (vcpu) */
 	REST_2GPRS(3, r1)
 	bl	KVMPPC_HANDLE_EXIT
 
-#if 0 /* XXX get lightweight exits back */
+	/* If RESUME_GUEST, get back in the loop */
 	cmpwi	r3, RESUME_GUEST
-	bne	kvm_exit_heavyweight
+	beq	kvm_loop_lightweight
 
-	/* put VCPU and KVM_RUN back into place and roll again! */
-	REST_2GPRS(3, r1)
-	b	kvm_start_lightweight
+	cmpwi	r3, RESUME_GUEST_NV
+	beq	kvm_loop_heavyweight
 
-kvm_exit_heavyweight:
-	/* Restore non-volatile host registers */
-	ld	r14, _LINK(r1)
-	mtlr	r14
-	REST_NVGPRS(r1)
+kvm_exit_loop:
 
-	addi    r1, r1, SWITCH_FRAME_SIZE
-#else
 	ld	r4, _LINK(r1)
 	mtlr	r4
 
-	cmpwi	r3, RESUME_GUEST
-	bne	kvm_exit_heavyweight
+	/* Restore non-volatile host registers (r14 - r31) */
+	REST_NVGPRS(r1)
+
+	addi    r1, r1, SWITCH_FRAME_SIZE
+	blr
+
+kvm_loop_heavyweight:
 
+	ld	r4, _LINK(r1)
+	std     r4, (16 + SWITCH_FRAME_SIZE)(r1)
+
+	/* Load vcpu and cpu_run */
 	REST_2GPRS(3, r1)
 
-	addi    r1, r1, SWITCH_FRAME_SIZE
+	/* Load non-volatile guest state from the vcpu */
+	VCPU_LOAD_NVGPRS(r4)
 
-	b	kvm_start_entry
+	/* Jump back into the beginning of this function */
+	b	kvm_start_lightweight
 
-kvm_exit_heavyweight:
+kvm_loop_lightweight:
 
-	addi    r1, r1, SWITCH_FRAME_SIZE
-#endif
+	/* We'll need the vcpu pointer */
+	REST_GPR(4, r1)
+
+	/* Jump back into the beginning of this function */
+	b	kvm_start_lightweight
 
-	blr
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_mmu.c linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s_64_mmu.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_mmu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s_64_mmu.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,7 +54,7 @@ static struct kvmppc_slb *kvmppc_mmu_boo
 		if (!vcpu_book3s->slb[i].valid)
 			continue;
 
-		if (vcpu_book3s->slb[i].large)
+		if (vcpu_book3s->slb[i].tb)
 			cmp_esid = esid_1t;
 
 		if (vcpu_book3s->slb[i].esid == cmp_esid)
@@ -65,9 +65,10 @@ static struct kvmppc_slb *kvmppc_mmu_boo
 		eaddr, esid, esid_1t);
 	for (i = 0; i < vcpu_book3s->slb_nr; i++) {
 	    if (vcpu_book3s->slb[i].vsid)
-		dprintk("  %d: %c%c %llx %llx\n", i,
+		dprintk("  %d: %c%c%c %llx %llx\n", i,
 			vcpu_book3s->slb[i].valid ? 'v' : ' ',
 			vcpu_book3s->slb[i].large ? 'l' : ' ',
+			vcpu_book3s->slb[i].tb    ? 't' : ' ',
 			vcpu_book3s->slb[i].esid,
 			vcpu_book3s->slb[i].vsid);
 	}
@@ -84,7 +85,7 @@ static u64 kvmppc_mmu_book3s_64_ea_to_vp
 	if (!slb)
 		return 0;
 
-	if (slb->large)
+	if (slb->tb)
 		return (((u64)eaddr >> 12) & 0xfffffff) |
 		       (((u64)slb->vsid) << 28);
 
@@ -309,7 +310,8 @@ static void kvmppc_mmu_book3s_64_slbmte(
 	slbe = &vcpu_book3s->slb[slb_nr];
 
 	slbe->large = (rs & SLB_VSID_L) ? 1 : 0;
-	slbe->esid  = slbe->large ? esid_1t : esid;
+	slbe->tb    = (rs & SLB_VSID_B_1T) ? 1 : 0;
+	slbe->esid  = slbe->tb ? esid_1t : esid;
 	slbe->vsid  = rs >> 12;
 	slbe->valid = (rb & SLB_ESID_V) ? 1 : 0;
 	slbe->Ks    = (rs & SLB_VSID_KS) ? 1 : 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_rmhandlers.S linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s_64_rmhandlers.S
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_rmhandlers.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s_64_rmhandlers.S	2010-05-16 17:17:36.000000000 -0400
@@ -45,36 +45,25 @@ kvmppc_trampoline_\intno:
 	 * To distinguish, we check a magic byte in the PACA
 	 */
 	mfspr	r13, SPRN_SPRG_PACA		/* r13 = PACA */
-	std	r12, (PACA_EXMC + EX_R12)(r13)
+	std	r12, PACA_KVM_SCRATCH0(r13)
 	mfcr	r12
-	stw	r12, (PACA_EXMC + EX_CCR)(r13)
+	stw	r12, PACA_KVM_SCRATCH1(r13)
 	lbz	r12, PACA_KVM_IN_GUEST(r13)
-	cmpwi	r12, 0
+	cmpwi	r12, KVM_GUEST_MODE_NONE
 	bne	..kvmppc_handler_hasmagic_\intno
 	/* No KVM guest? Then jump back to the Linux handler! */
-	lwz	r12, (PACA_EXMC + EX_CCR)(r13)
+	lwz	r12, PACA_KVM_SCRATCH1(r13)
 	mtcr	r12
-	ld	r12, (PACA_EXMC + EX_R12)(r13)
+	ld	r12, PACA_KVM_SCRATCH0(r13)
 	mfspr	r13, SPRN_SPRG_SCRATCH0		/* r13 = original r13 */
 	b	kvmppc_resume_\intno		/* Get back original handler */
 
 	/* Now we know we're handling a KVM guest */
 ..kvmppc_handler_hasmagic_\intno:
-	/* Unset guest state */
-	li	r12, 0
-	stb	r12, PACA_KVM_IN_GUEST(r13)
-
-	std	r1, (PACA_EXMC+EX_R9)(r13)
-	std	r10, (PACA_EXMC+EX_R10)(r13)
-	std	r11, (PACA_EXMC+EX_R11)(r13)
-	std	r2, (PACA_EXMC+EX_R13)(r13)
-
-	mfsrr0	r10
-	mfsrr1	r11
 
-	/* Restore R1/R2 so we can handle faults */
-	ld	r1, PACAR1(r13)
-	ld	r2, (PACA_EXMC+EX_SRR0)(r13)
+	/* Should we just skip the faulting instruction? */
+	cmpwi	r12, KVM_GUEST_MODE_SKIP
+	beq	kvmppc_handler_skip_ins
 
 	/* Let's store which interrupt we're handling */
 	li	r12, \intno
@@ -102,23 +91,107 @@ INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_AL
 INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_VSX
 
 /*
+ * Bring us back to the faulting code, but skip the
+ * faulting instruction.
+ *
+ * This is a generic exit path from the interrupt
+ * trampolines above.
+ *
+ * Input Registers:
+ *
+ * R12               = free
+ * R13               = PACA
+ * PACA.KVM.SCRATCH0 = guest R12
+ * PACA.KVM.SCRATCH1 = guest CR
+ * SPRG_SCRATCH0     = guest R13
+ *
+ */
+kvmppc_handler_skip_ins:
+
+	/* Patch the IP to the next instruction */
+	mfsrr0	r12
+	addi	r12, r12, 4
+	mtsrr0	r12
+
+	/* Clean up all state */
+	lwz	r12, PACA_KVM_SCRATCH1(r13)
+	mtcr	r12
+	ld	r12, PACA_KVM_SCRATCH0(r13)
+	mfspr	r13, SPRN_SPRG_SCRATCH0
+
+	/* And get back into the code */
+	RFI
+
+/*
  * This trampoline brings us back to a real mode handler
  *
  * Input Registers:
  *
- * R6 = SRR0
- * R7 = SRR1
+ * R5 = SRR0
+ * R6 = SRR1
  * LR = real-mode IP
  *
  */
 .global kvmppc_handler_lowmem_trampoline
 kvmppc_handler_lowmem_trampoline:
 
-	mtsrr0	r6
-	mtsrr1	r7
+	mtsrr0	r5
+	mtsrr1	r6
 	blr
 kvmppc_handler_lowmem_trampoline_end:
 
+/*
+ * Call a function in real mode
+ *
+ * Input Registers:
+ *
+ * R3 = function
+ * R4 = MSR
+ * R5 = CTR
+ *
+ */
+_GLOBAL(kvmppc_rmcall)
+	mtmsr	r4		/* Disable relocation, so mtsrr
+				   doesn't get interrupted */
+	mtctr	r5
+	mtsrr0	r3
+	mtsrr1	r4
+	RFI
+
+/*
+ * Activate current's external feature (FPU/Altivec/VSX)
+ */
+#define define_load_up(what) 				\
+							\
+_GLOBAL(kvmppc_load_up_ ## what);			\
+	subi	r1, r1, INT_FRAME_SIZE;			\
+	mflr	r3;					\
+	std	r3, _LINK(r1);				\
+	mfmsr	r4;					\
+	std	r31, GPR3(r1);				\
+	mr	r31, r4;				\
+	li	r5, MSR_DR;				\
+	oris	r5, r5, MSR_EE@h;			\
+	andc	r4, r4, r5;				\
+	mtmsr	r4;					\
+							\
+	bl	.load_up_ ## what;			\
+							\
+	mtmsr	r31;					\
+	ld	r3, _LINK(r1);				\
+	ld	r31, GPR3(r1);				\
+	addi	r1, r1, INT_FRAME_SIZE;			\
+	mtlr	r3;					\
+	blr
+
+define_load_up(fpu)
+#ifdef CONFIG_ALTIVEC
+define_load_up(altivec)
+#endif
+#ifdef CONFIG_VSX
+define_load_up(vsx)
+#endif
+
 .global kvmppc_trampoline_lowmem
 kvmppc_trampoline_lowmem:
 	.long kvmppc_handler_lowmem_trampoline - _stext
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_slb.S linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s_64_slb.S
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_slb.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s_64_slb.S	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,7 @@
 #define REBOLT_SLB_ENTRY(num) \
 	ld	r10, SHADOW_SLB_ESID(num)(r11); \
 	cmpdi	r10, 0; \
-	beq	slb_exit_skip_1; \
+	beq	slb_exit_skip_ ## num; \
 	oris	r10, r10, SLB_ESID_V@h; \
 	ld	r9, SHADOW_SLB_VSID(num)(r11); \
 	slbmte	r9, r10; \
@@ -51,23 +51,21 @@ kvmppc_handler_trampoline_enter:
 	 *
 	 * MSR = ~IR|DR
 	 * R13 = PACA
+	 * R1 = host R1
+	 * R2 = host R2
 	 * R9 = guest IP
 	 * R10 = guest MSR
-	 * R11 = free
-	 * R12 = free
-	 * PACA[PACA_EXMC + EX_R9] = guest R9
-	 * PACA[PACA_EXMC + EX_R10] = guest R10
-	 * PACA[PACA_EXMC + EX_R11] = guest R11
-	 * PACA[PACA_EXMC + EX_R12] = guest R12
-	 * PACA[PACA_EXMC + EX_R13] = guest R13
-	 * PACA[PACA_EXMC + EX_CCR] = guest CR
-	 * PACA[PACA_EXMC + EX_R3] = guest XER
+	 * all other GPRS = free
+	 * PACA[KVM_CR] = guest CR
+	 * PACA[KVM_XER] = guest XER
 	 */
 
 	mtsrr0	r9
 	mtsrr1	r10
 
-	mtspr	SPRN_SPRG_SCRATCH0, r0
+	/* Activate guest mode, so faults get handled by KVM */
+	li	r11, KVM_GUEST_MODE_GUEST
+	stb	r11, PACA_KVM_IN_GUEST(r13)
 
 	/* Remove LPAR shadow entries */
 
@@ -131,20 +129,27 @@ slb_do_enter:
 
 	/* Enter guest */
 
-	mfspr	r0, SPRN_SPRG_SCRATCH0
-
-	ld	r9, (PACA_EXMC+EX_R9)(r13)
-	ld	r10, (PACA_EXMC+EX_R10)(r13)
-	ld	r12, (PACA_EXMC+EX_R12)(r13)
+	ld	r0, (PACA_KVM_R0)(r13)
+	ld	r1, (PACA_KVM_R1)(r13)
+	ld	r2, (PACA_KVM_R2)(r13)
+	ld	r3, (PACA_KVM_R3)(r13)
+	ld	r4, (PACA_KVM_R4)(r13)
+	ld	r5, (PACA_KVM_R5)(r13)
+	ld	r6, (PACA_KVM_R6)(r13)
+	ld	r7, (PACA_KVM_R7)(r13)
+	ld	r8, (PACA_KVM_R8)(r13)
+	ld	r9, (PACA_KVM_R9)(r13)
+	ld	r10, (PACA_KVM_R10)(r13)
+	ld	r12, (PACA_KVM_R12)(r13)
 
-	lwz	r11, (PACA_EXMC+EX_CCR)(r13)
+	lwz	r11, (PACA_KVM_CR)(r13)
 	mtcr	r11
 
-	ld	r11, (PACA_EXMC+EX_R3)(r13)
+	ld	r11, (PACA_KVM_XER)(r13)
 	mtxer	r11
 
-	ld	r11, (PACA_EXMC+EX_R11)(r13)
-	ld	r13, (PACA_EXMC+EX_R13)(r13)
+	ld	r11, (PACA_KVM_R11)(r13)
+	ld	r13, (PACA_KVM_R13)(r13)
 
 	RFI
 kvmppc_handler_trampoline_enter_end:
@@ -162,28 +167,54 @@ kvmppc_handler_trampoline_exit:
 
 	/* Register usage at this point:
 	 *
-	 * SPRG_SCRATCH0 = guest R13
-	 * R01           = host R1
-	 * R02           = host R2
-	 * R10           = guest PC
-	 * R11           = guest MSR
-	 * R12           = exit handler id
-	 * R13           = PACA
-	 * PACA.exmc.CCR  = guest CR
-	 * PACA.exmc.R9  = guest R1
-	 * PACA.exmc.R10 = guest R10
-	 * PACA.exmc.R11 = guest R11
-	 * PACA.exmc.R12 = guest R12
-	 * PACA.exmc.R13 = guest R2
+	 * SPRG_SCRATCH0     = guest R13
+	 * R12               = exit handler id
+	 * R13               = PACA
+	 * PACA.KVM.SCRATCH0 = guest R12
+	 * PACA.KVM.SCRATCH1 = guest CR
 	 *
 	 */
 
 	/* Save registers */
 
-	std	r0, (PACA_EXMC+EX_SRR0)(r13)
-	std	r9, (PACA_EXMC+EX_R3)(r13)
-	std	r10, (PACA_EXMC+EX_LR)(r13)
-	std	r11, (PACA_EXMC+EX_DAR)(r13)
+	std	r0, PACA_KVM_R0(r13)
+	std	r1, PACA_KVM_R1(r13)
+	std	r2, PACA_KVM_R2(r13)
+	std	r3, PACA_KVM_R3(r13)
+	std	r4, PACA_KVM_R4(r13)
+	std	r5, PACA_KVM_R5(r13)
+	std	r6, PACA_KVM_R6(r13)
+	std	r7, PACA_KVM_R7(r13)
+	std	r8, PACA_KVM_R8(r13)
+	std	r9, PACA_KVM_R9(r13)
+	std	r10, PACA_KVM_R10(r13)
+	std	r11, PACA_KVM_R11(r13)
+
+	/* Restore R1/R2 so we can handle faults */
+	ld	r1, PACA_KVM_HOST_R1(r13)
+	ld	r2, PACA_KVM_HOST_R2(r13)
+
+	/* Save guest PC and MSR in GPRs */
+	mfsrr0	r3
+	mfsrr1	r4
+
+	/* Get scratch'ed off registers */
+	mfspr	r9, SPRN_SPRG_SCRATCH0
+	std	r9, PACA_KVM_R13(r13)
+
+	ld	r8, PACA_KVM_SCRATCH0(r13)
+	std	r8, PACA_KVM_R12(r13)
+
+	lwz	r7, PACA_KVM_SCRATCH1(r13)
+	stw	r7, PACA_KVM_CR(r13)
+
+	/* Save more register state  */
+
+	mfxer	r6
+	stw	r6, PACA_KVM_XER(r13)
+
+	mfdar	r5
+	mfdsisr	r6
 
 	/*
 	 * In order for us to easily get the last instruction,
@@ -202,17 +233,28 @@ kvmppc_handler_trampoline_exit:
 
 ld_last_inst:
 	/* Save off the guest instruction we're at */
+
+	/* Set guest mode to 'jump over instruction' so if lwz faults
+	 * we'll just continue at the next IP. */
+	li	r9, KVM_GUEST_MODE_SKIP
+	stb	r9, PACA_KVM_IN_GUEST(r13)
+
 	/*    1) enable paging for data */
 	mfmsr	r9
 	ori	r11, r9, MSR_DR			/* Enable paging for data */
 	mtmsr	r11
 	/*    2) fetch the instruction */
-	lwz	r0, 0(r10)
+	li	r0, KVM_INST_FETCH_FAILED	/* In case lwz faults */
+	lwz	r0, 0(r3)
 	/*    3) disable paging again */
 	mtmsr	r9
 
 no_ld_last_inst:
 
+	/* Unset guest mode */
+	li	r9, KVM_GUEST_MODE_NONE
+	stb	r9, PACA_KVM_IN_GUEST(r13)
+
 	/* Restore bolted entries from the shadow and fix it along the way */
 
 	/* We don't store anything in entry 0, so we don't need to take care of it */
@@ -233,29 +275,27 @@ no_ld_last_inst:
 
 slb_do_exit:
 
-	/* Restore registers */
-
-	ld	r11, (PACA_EXMC+EX_DAR)(r13)
-	ld	r10, (PACA_EXMC+EX_LR)(r13)
-	ld	r9, (PACA_EXMC+EX_R3)(r13)
-
-	/* Save last inst */
-	stw	r0, (PACA_EXMC+EX_LR)(r13)
-
-	/* Save DAR and DSISR before going to paged mode */
-	mfdar	r0
-	std	r0, (PACA_EXMC+EX_DAR)(r13)
-	mfdsisr	r0
-	stw	r0, (PACA_EXMC+EX_DSISR)(r13)
+	/* Register usage at this point:
+	 *
+	 * R0         = guest last inst
+	 * R1         = host R1
+	 * R2         = host R2
+	 * R3         = guest PC
+	 * R4         = guest MSR
+	 * R5         = guest DAR
+	 * R6         = guest DSISR
+	 * R12        = exit handler id
+	 * R13        = PACA
+	 * PACA.KVM.* = guest *
+	 *
+	 */
 
 	/* RFI into the highmem handler */
-	mfmsr	r0
-	ori	r0, r0, MSR_IR|MSR_DR|MSR_RI	/* Enable paging */
-	mtsrr1	r0
-	ld	r0, PACASAVEDMSR(r13)		/* Highmem handler address */
-	mtsrr0	r0
-
-	mfspr	r0, SPRN_SPRG_SCRATCH0
+	mfmsr	r7
+	ori	r7, r7, MSR_IR|MSR_DR|MSR_RI	/* Enable paging */
+	mtsrr1	r7
+	ld	r8, PACA_KVM_VMHANDLER(r13)	/* Highmem handler address */
+	mtsrr0	r8
 
 	RFI
 kvmppc_handler_trampoline_exit_end:
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s.c linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <asm/kvm_ppc.h>
 #include <asm/kvm_book3s.h>
 #include <asm/mmu_context.h>
+#include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/vmalloc.h>
 
@@ -33,12 +34,9 @@
 
 /* #define EXIT_DEBUG */
 /* #define EXIT_DEBUG_SIMPLE */
+/* #define DEBUG_EXT */
 
-/* Without AGGRESSIVE_DEC we only fire off a DEC interrupt when DEC turns 0.
- * When set, we retrigger a DEC interrupt after that if DEC <= 0.
- * PPC32 Linux runs faster without AGGRESSIVE_DEC, PPC64 Linux requires it. */
-
-/* #define AGGRESSIVE_DEC */
+static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr);
 
 struct kvm_stats_debugfs_item debugfs_entries[] = {
 	{ "exits",       VCPU_STAT(sum_exits) },
@@ -72,16 +70,24 @@ void kvmppc_core_load_guest_debugstate(s
 void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
 	memcpy(get_paca()->kvm_slb, to_book3s(vcpu)->slb_shadow, sizeof(get_paca()->kvm_slb));
+	memcpy(&get_paca()->shadow_vcpu, &to_book3s(vcpu)->shadow_vcpu,
+	       sizeof(get_paca()->shadow_vcpu));
 	get_paca()->kvm_slb_max = to_book3s(vcpu)->slb_shadow_max;
 }
 
 void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
 {
 	memcpy(to_book3s(vcpu)->slb_shadow, get_paca()->kvm_slb, sizeof(get_paca()->kvm_slb));
+	memcpy(&to_book3s(vcpu)->shadow_vcpu, &get_paca()->shadow_vcpu,
+	       sizeof(get_paca()->shadow_vcpu));
 	to_book3s(vcpu)->slb_shadow_max = get_paca()->kvm_slb_max;
+
+	kvmppc_giveup_ext(vcpu, MSR_FP);
+	kvmppc_giveup_ext(vcpu, MSR_VEC);
+	kvmppc_giveup_ext(vcpu, MSR_VSX);
 }
 
-#if defined(AGGRESSIVE_DEC) || defined(EXIT_DEBUG)
+#if defined(EXIT_DEBUG)
 static u32 kvmppc_get_dec(struct kvm_vcpu *vcpu)
 {
 	u64 jd = mftb() - vcpu->arch.dec_jiffies;
@@ -89,6 +95,23 @@ static u32 kvmppc_get_dec(struct kvm_vcp
 }
 #endif
 
+static void kvmppc_recalc_shadow_msr(struct kvm_vcpu *vcpu)
+{
+	vcpu->arch.shadow_msr = vcpu->arch.msr;
+	/* Guest MSR values */
+	vcpu->arch.shadow_msr &= MSR_FE0 | MSR_FE1 | MSR_SF | MSR_SE |
+				 MSR_BE | MSR_DE;
+	/* Process MSR values */
+	vcpu->arch.shadow_msr |= MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_PR |
+				 MSR_EE;
+	/* External providers the guest reserved */
+	vcpu->arch.shadow_msr |= (vcpu->arch.msr & vcpu->arch.guest_owned_ext);
+	/* 64-bit Process MSR values */
+#ifdef CONFIG_PPC_BOOK3S_64
+	vcpu->arch.shadow_msr |= MSR_ISF | MSR_HV;
+#endif
+}
+
 void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr)
 {
 	ulong old_msr = vcpu->arch.msr;
@@ -96,12 +119,10 @@ void kvmppc_set_msr(struct kvm_vcpu *vcp
 #ifdef EXIT_DEBUG
 	printk(KERN_INFO "KVM: Set MSR to 0x%llx\n", msr);
 #endif
+
 	msr &= to_book3s(vcpu)->msr_mask;
 	vcpu->arch.msr = msr;
-	vcpu->arch.shadow_msr = msr | MSR_USER32;
-	vcpu->arch.shadow_msr &= ( MSR_VEC | MSR_VSX | MSR_FP | MSR_FE0 |
-				   MSR_USER64 | MSR_SE | MSR_BE | MSR_DE |
-				   MSR_FE1);
+	kvmppc_recalc_shadow_msr(vcpu);
 
 	if (msr & (MSR_WE|MSR_POW)) {
 		if (!vcpu->arch.pending_exceptions) {
@@ -125,11 +146,10 @@ void kvmppc_inject_interrupt(struct kvm_
 	vcpu->arch.mmu.reset_msr(vcpu);
 }
 
-void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
+static int kvmppc_book3s_vec2irqprio(unsigned int vec)
 {
 	unsigned int prio;
 
-	vcpu->stat.queue_intr++;
 	switch (vec) {
 	case 0x100: prio = BOOK3S_IRQPRIO_SYSTEM_RESET;		break;
 	case 0x200: prio = BOOK3S_IRQPRIO_MACHINE_CHECK;	break;
@@ -149,15 +169,31 @@ void kvmppc_book3s_queue_irqprio(struct
 	default:    prio = BOOK3S_IRQPRIO_MAX;			break;
 	}
 
-	set_bit(prio, &vcpu->arch.pending_exceptions);
+	return prio;
+}
+
+static void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcpu,
+					  unsigned int vec)
+{
+	clear_bit(kvmppc_book3s_vec2irqprio(vec),
+		  &vcpu->arch.pending_exceptions);
+}
+
+void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
+{
+	vcpu->stat.queue_intr++;
+
+	set_bit(kvmppc_book3s_vec2irqprio(vec),
+		&vcpu->arch.pending_exceptions);
 #ifdef EXIT_DEBUG
 	printk(KERN_INFO "Queueing interrupt %x\n", vec);
 #endif
 }
 
 
-void kvmppc_core_queue_program(struct kvm_vcpu *vcpu)
+void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags)
 {
+	to_book3s(vcpu)->prog_flags = flags;
 	kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_PROGRAM);
 }
 
@@ -171,6 +207,11 @@ int kvmppc_core_pending_dec(struct kvm_v
 	return test_bit(BOOK3S_INTERRUPT_DECREMENTER >> 7, &vcpu->arch.pending_exceptions);
 }
 
+void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu)
+{
+	kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_DECREMENTER);
+}
+
 void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
                                 struct kvm_interrupt *irq)
 {
@@ -181,6 +222,7 @@ int kvmppc_book3s_irqprio_deliver(struct
 {
 	int deliver = 1;
 	int vec = 0;
+	ulong flags = 0ULL;
 
 	switch (priority) {
 	case BOOK3S_IRQPRIO_DECREMENTER:
@@ -214,6 +256,7 @@ int kvmppc_book3s_irqprio_deliver(struct
 		break;
 	case BOOK3S_IRQPRIO_PROGRAM:
 		vec = BOOK3S_INTERRUPT_PROGRAM;
+		flags = to_book3s(vcpu)->prog_flags;
 		break;
 	case BOOK3S_IRQPRIO_VSX:
 		vec = BOOK3S_INTERRUPT_VSX;
@@ -244,7 +287,7 @@ int kvmppc_book3s_irqprio_deliver(struct
 #endif
 
 	if (deliver)
-		kvmppc_inject_interrupt(vcpu, vec, 0ULL);
+		kvmppc_inject_interrupt(vcpu, vec, flags);
 
 	return deliver;
 }
@@ -254,21 +297,15 @@ void kvmppc_core_deliver_interrupts(stru
 	unsigned long *pending = &vcpu->arch.pending_exceptions;
 	unsigned int priority;
 
-	/* XXX be more clever here - no need to mftb() on every entry */
-	/* Issue DEC again if it's still active */
-#ifdef AGGRESSIVE_DEC
-	if (vcpu->arch.msr & MSR_EE)
-		if (kvmppc_get_dec(vcpu) & 0x80000000)
-			kvmppc_core_queue_dec(vcpu);
-#endif
-
 #ifdef EXIT_DEBUG
 	if (vcpu->arch.pending_exceptions)
 		printk(KERN_EMERG "KVM: Check pending: %lx\n", vcpu->arch.pending_exceptions);
 #endif
 	priority = __ffs(*pending);
 	while (priority <= (sizeof(unsigned int) * 8)) {
-		if (kvmppc_book3s_irqprio_deliver(vcpu, priority)) {
+		if (kvmppc_book3s_irqprio_deliver(vcpu, priority) &&
+		    (priority != BOOK3S_IRQPRIO_DECREMENTER)) {
+			/* DEC interrupts get cleared by mtdec */
 			clear_bit(priority, &vcpu->arch.pending_exceptions);
 			break;
 		}
@@ -503,14 +540,14 @@ int kvmppc_handle_pagefault(struct kvm_r
 		/* Page not found in guest PTE entries */
 		vcpu->arch.dear = vcpu->arch.fault_dear;
 		to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr;
-		vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x00000000f8000000ULL);
+		vcpu->arch.msr |= (vcpu->arch.shadow_srr1 & 0x00000000f8000000ULL);
 		kvmppc_book3s_queue_irqprio(vcpu, vec);
 	} else if (page_found == -EPERM) {
 		/* Storage protection */
 		vcpu->arch.dear = vcpu->arch.fault_dear;
 		to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr & ~DSISR_NOHPTE;
 		to_book3s(vcpu)->dsisr |= DSISR_PROTFAULT;
-		vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x00000000f8000000ULL);
+		vcpu->arch.msr |= (vcpu->arch.shadow_srr1 & 0x00000000f8000000ULL);
 		kvmppc_book3s_queue_irqprio(vcpu, vec);
 	} else if (page_found == -EINVAL) {
 		/* Page not found in guest SLB */
@@ -532,13 +569,122 @@ int kvmppc_handle_pagefault(struct kvm_r
 		r = kvmppc_emulate_mmio(run, vcpu);
 		if ( r == RESUME_HOST_NV )
 			r = RESUME_HOST;
-		if ( r == RESUME_GUEST_NV )
-			r = RESUME_GUEST;
 	}
 
 	return r;
 }
 
+static inline int get_fpr_index(int i)
+{
+#ifdef CONFIG_VSX
+	i *= 2;
+#endif
+	return i;
+}
+
+/* Give up external provider (FPU, Altivec, VSX) */
+static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr)
+{
+	struct thread_struct *t = &current->thread;
+	u64 *vcpu_fpr = vcpu->arch.fpr;
+	u64 *vcpu_vsx = vcpu->arch.vsr;
+	u64 *thread_fpr = (u64*)t->fpr;
+	int i;
+
+	if (!(vcpu->arch.guest_owned_ext & msr))
+		return;
+
+#ifdef DEBUG_EXT
+	printk(KERN_INFO "Giving up ext 0x%lx\n", msr);
+#endif
+
+	switch (msr) {
+	case MSR_FP:
+		giveup_fpu(current);
+		for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++)
+			vcpu_fpr[i] = thread_fpr[get_fpr_index(i)];
+
+		vcpu->arch.fpscr = t->fpscr.val;
+		break;
+	case MSR_VEC:
+#ifdef CONFIG_ALTIVEC
+		giveup_altivec(current);
+		memcpy(vcpu->arch.vr, t->vr, sizeof(vcpu->arch.vr));
+		vcpu->arch.vscr = t->vscr;
+#endif
+		break;
+	case MSR_VSX:
+#ifdef CONFIG_VSX
+		__giveup_vsx(current);
+		for (i = 0; i < ARRAY_SIZE(vcpu->arch.vsr); i++)
+			vcpu_vsx[i] = thread_fpr[get_fpr_index(i) + 1];
+#endif
+		break;
+	default:
+		BUG();
+	}
+
+	vcpu->arch.guest_owned_ext &= ~msr;
+	current->thread.regs->msr &= ~msr;
+	kvmppc_recalc_shadow_msr(vcpu);
+}
+
+/* Handle external providers (FPU, Altivec, VSX) */
+static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
+			     ulong msr)
+{
+	struct thread_struct *t = &current->thread;
+	u64 *vcpu_fpr = vcpu->arch.fpr;
+	u64 *vcpu_vsx = vcpu->arch.vsr;
+	u64 *thread_fpr = (u64*)t->fpr;
+	int i;
+
+	if (!(vcpu->arch.msr & msr)) {
+		kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+		return RESUME_GUEST;
+	}
+
+#ifdef DEBUG_EXT
+	printk(KERN_INFO "Loading up ext 0x%lx\n", msr);
+#endif
+
+	current->thread.regs->msr |= msr;
+
+	switch (msr) {
+	case MSR_FP:
+		for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++)
+			thread_fpr[get_fpr_index(i)] = vcpu_fpr[i];
+
+		t->fpscr.val = vcpu->arch.fpscr;
+		t->fpexc_mode = 0;
+		kvmppc_load_up_fpu();
+		break;
+	case MSR_VEC:
+#ifdef CONFIG_ALTIVEC
+		memcpy(t->vr, vcpu->arch.vr, sizeof(vcpu->arch.vr));
+		t->vscr = vcpu->arch.vscr;
+		t->vrsave = -1;
+		kvmppc_load_up_altivec();
+#endif
+		break;
+	case MSR_VSX:
+#ifdef CONFIG_VSX
+		for (i = 0; i < ARRAY_SIZE(vcpu->arch.vsr); i++)
+			thread_fpr[get_fpr_index(i) + 1] = vcpu_vsx[i];
+		kvmppc_load_up_vsx();
+#endif
+		break;
+	default:
+		BUG();
+	}
+
+	vcpu->arch.guest_owned_ext |= msr;
+
+	kvmppc_recalc_shadow_msr(vcpu);
+
+	return RESUME_GUEST;
+}
+
 int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                        unsigned int exit_nr)
 {
@@ -563,7 +709,7 @@ int kvmppc_handle_exit(struct kvm_run *r
 	case BOOK3S_INTERRUPT_INST_STORAGE:
 		vcpu->stat.pf_instruc++;
 		/* only care about PTEG not found errors, but leave NX alone */
-		if (vcpu->arch.shadow_msr & 0x40000000) {
+		if (vcpu->arch.shadow_srr1 & 0x40000000) {
 			r = kvmppc_handle_pagefault(run, vcpu, vcpu->arch.pc, exit_nr);
 			vcpu->stat.sp_instruc++;
 		} else if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
@@ -575,7 +721,7 @@ int kvmppc_handle_exit(struct kvm_run *r
 			 */
 			kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL);
 		} else {
-			vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x58000000);
+			vcpu->arch.msr |= vcpu->arch.shadow_srr1 & 0x58000000;
 			kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
 			kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL);
 			r = RESUME_GUEST;
@@ -621,6 +767,9 @@ int kvmppc_handle_exit(struct kvm_run *r
 	case BOOK3S_INTERRUPT_PROGRAM:
 	{
 		enum emulation_result er;
+		ulong flags;
+
+		flags = vcpu->arch.shadow_srr1 & 0x1f0000ull;
 
 		if (vcpu->arch.msr & MSR_PR) {
 #ifdef EXIT_DEBUG
@@ -628,7 +777,7 @@ int kvmppc_handle_exit(struct kvm_run *r
 #endif
 			if ((vcpu->arch.last_inst & 0xff0007ff) !=
 			    (INS_DCBZ & 0xfffffff7)) {
-				kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+				kvmppc_core_queue_program(vcpu, flags);
 				r = RESUME_GUEST;
 				break;
 			}
@@ -638,12 +787,12 @@ int kvmppc_handle_exit(struct kvm_run *r
 		er = kvmppc_emulate_instruction(run, vcpu);
 		switch (er) {
 		case EMULATE_DONE:
-			r = RESUME_GUEST;
+			r = RESUME_GUEST_NV;
 			break;
 		case EMULATE_FAIL:
 			printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n",
 			       __func__, vcpu->arch.pc, vcpu->arch.last_inst);
-			kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+			kvmppc_core_queue_program(vcpu, flags);
 			r = RESUME_GUEST;
 			break;
 		default:
@@ -653,23 +802,30 @@ int kvmppc_handle_exit(struct kvm_run *r
 	}
 	case BOOK3S_INTERRUPT_SYSCALL:
 #ifdef EXIT_DEBUG
-		printk(KERN_INFO "Syscall Nr %d\n", (int)vcpu->arch.gpr[0]);
+		printk(KERN_INFO "Syscall Nr %d\n", (int)kvmppc_get_gpr(vcpu, 0));
 #endif
 		vcpu->stat.syscall_exits++;
 		kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
 		r = RESUME_GUEST;
 		break;
-	case BOOK3S_INTERRUPT_MACHINE_CHECK:
 	case BOOK3S_INTERRUPT_FP_UNAVAIL:
-	case BOOK3S_INTERRUPT_TRACE:
+		r = kvmppc_handle_ext(vcpu, exit_nr, MSR_FP);
+		break;
 	case BOOK3S_INTERRUPT_ALTIVEC:
+		r = kvmppc_handle_ext(vcpu, exit_nr, MSR_VEC);
+		break;
 	case BOOK3S_INTERRUPT_VSX:
+		r = kvmppc_handle_ext(vcpu, exit_nr, MSR_VSX);
+		break;
+	case BOOK3S_INTERRUPT_MACHINE_CHECK:
+	case BOOK3S_INTERRUPT_TRACE:
 		kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
 		r = RESUME_GUEST;
 		break;
 	default:
 		/* Ugh - bork here! What did we get? */
-		printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | msr=0x%lx\n", exit_nr, vcpu->arch.pc, vcpu->arch.shadow_msr);
+		printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | msr=0x%lx\n",
+			exit_nr, vcpu->arch.pc, vcpu->arch.shadow_srr1);
 		r = RESUME_HOST;
 		BUG();
 		break;
@@ -712,10 +868,10 @@ int kvm_arch_vcpu_ioctl_get_regs(struct
 	int i;
 
 	regs->pc = vcpu->arch.pc;
-	regs->cr = vcpu->arch.cr;
+	regs->cr = kvmppc_get_cr(vcpu);
 	regs->ctr = vcpu->arch.ctr;
 	regs->lr = vcpu->arch.lr;
-	regs->xer = vcpu->arch.xer;
+	regs->xer = kvmppc_get_xer(vcpu);
 	regs->msr = vcpu->arch.msr;
 	regs->srr0 = vcpu->arch.srr0;
 	regs->srr1 = vcpu->arch.srr1;
@@ -729,7 +885,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct
 	regs->sprg7 = vcpu->arch.sprg6;
 
 	for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
-		regs->gpr[i] = vcpu->arch.gpr[i];
+		regs->gpr[i] = kvmppc_get_gpr(vcpu, i);
 
 	return 0;
 }
@@ -739,10 +895,10 @@ int kvm_arch_vcpu_ioctl_set_regs(struct
 	int i;
 
 	vcpu->arch.pc = regs->pc;
-	vcpu->arch.cr = regs->cr;
+	kvmppc_set_cr(vcpu, regs->cr);
 	vcpu->arch.ctr = regs->ctr;
 	vcpu->arch.lr = regs->lr;
-	vcpu->arch.xer = regs->xer;
+	kvmppc_set_xer(vcpu, regs->xer);
 	kvmppc_set_msr(vcpu, regs->msr);
 	vcpu->arch.srr0 = regs->srr0;
 	vcpu->arch.srr1 = regs->srr1;
@@ -754,8 +910,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct
 	vcpu->arch.sprg6 = regs->sprg5;
 	vcpu->arch.sprg7 = regs->sprg6;
 
-	for (i = 0; i < ARRAY_SIZE(vcpu->arch.gpr); i++)
-		vcpu->arch.gpr[i] = regs->gpr[i];
+	for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
+		kvmppc_set_gpr(vcpu, i, regs->gpr[i]);
 
 	return 0;
 }
@@ -848,9 +1004,10 @@ int kvm_vm_ioctl_get_dirty_log(struct kv
 	struct kvm_vcpu *vcpu;
 	ulong ga, ga_end;
 	int is_dirty = 0;
-	int r, n;
+	int r;
+	unsigned long n;
 
-	down_write(&kvm->slots_lock);
+	mutex_lock(&kvm->slots_lock);
 
 	r = kvm_get_dirty_log(kvm, log, &is_dirty);
 	if (r)
@@ -858,7 +1015,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kv
 
 	/* If nothing is dirty, don't bother messing with page tables. */
 	if (is_dirty) {
-		memslot = &kvm->memslots[log->slot];
+		memslot = &kvm->memslots->memslots[log->slot];
 
 		ga = memslot->base_gfn << PAGE_SHIFT;
 		ga_end = ga + (memslot->npages << PAGE_SHIFT);
@@ -866,13 +1023,13 @@ int kvm_vm_ioctl_get_dirty_log(struct kv
 		kvm_for_each_vcpu(n, vcpu, kvm)
 			kvmppc_mmu_pte_pflush(vcpu, ga, ga_end);
 
-		n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+		n = kvm_dirty_bitmap_bytes(memslot);
 		memset(memslot->dirty_bitmap, 0, n);
 	}
 
 	r = 0;
 out:
-	up_write(&kvm->slots_lock);
+	mutex_unlock(&kvm->slots_lock);
 	return r;
 }
 
@@ -910,6 +1067,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create
 	vcpu->arch.trampoline_lowmem = kvmppc_trampoline_lowmem;
 	vcpu->arch.trampoline_enter = kvmppc_trampoline_enter;
 	vcpu->arch.highmem_handler = (ulong)kvmppc_handler_highmem;
+	vcpu->arch.rmcall = *(ulong*)kvmppc_rmcall;
 
 	vcpu->arch.shadow_msr = MSR_USER64;
 
@@ -943,6 +1101,10 @@ extern int __kvmppc_vcpu_entry(struct kv
 int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 {
 	int ret;
+	struct thread_struct ext_bkp;
+	bool save_vec = current->thread.used_vr;
+	bool save_vsx = current->thread.used_vsr;
+	ulong ext_msr;
 
 	/* No need to go into the guest when all we do is going out */
 	if (signal_pending(current)) {
@@ -950,6 +1112,35 @@ int __kvmppc_vcpu_run(struct kvm_run *kv
 		return -EINTR;
 	}
 
+	/* Save FPU state in stack */
+	if (current->thread.regs->msr & MSR_FP)
+		giveup_fpu(current);
+	memcpy(ext_bkp.fpr, current->thread.fpr, sizeof(current->thread.fpr));
+	ext_bkp.fpscr = current->thread.fpscr;
+	ext_bkp.fpexc_mode = current->thread.fpexc_mode;
+
+#ifdef CONFIG_ALTIVEC
+	/* Save Altivec state in stack */
+	if (save_vec) {
+		if (current->thread.regs->msr & MSR_VEC)
+			giveup_altivec(current);
+		memcpy(ext_bkp.vr, current->thread.vr, sizeof(ext_bkp.vr));
+		ext_bkp.vscr = current->thread.vscr;
+		ext_bkp.vrsave = current->thread.vrsave;
+	}
+	ext_bkp.used_vr = current->thread.used_vr;
+#endif
+
+#ifdef CONFIG_VSX
+	/* Save VSX state in stack */
+	if (save_vsx && (current->thread.regs->msr & MSR_VSX))
+			__giveup_vsx(current);
+	ext_bkp.used_vsr = current->thread.used_vsr;
+#endif
+
+	/* Remember the MSR with disabled extensions */
+	ext_msr = current->thread.regs->msr;
+
 	/* XXX we get called with irq disabled - change that! */
 	local_irq_enable();
 
@@ -957,6 +1148,32 @@ int __kvmppc_vcpu_run(struct kvm_run *kv
 
 	local_irq_disable();
 
+	current->thread.regs->msr = ext_msr;
+
+	/* Make sure we save the guest FPU/Altivec/VSX state */
+	kvmppc_giveup_ext(vcpu, MSR_FP);
+	kvmppc_giveup_ext(vcpu, MSR_VEC);
+	kvmppc_giveup_ext(vcpu, MSR_VSX);
+
+	/* Restore FPU state from stack */
+	memcpy(current->thread.fpr, ext_bkp.fpr, sizeof(ext_bkp.fpr));
+	current->thread.fpscr = ext_bkp.fpscr;
+	current->thread.fpexc_mode = ext_bkp.fpexc_mode;
+
+#ifdef CONFIG_ALTIVEC
+	/* Restore Altivec state from stack */
+	if (save_vec && current->thread.used_vr) {
+		memcpy(current->thread.vr, ext_bkp.vr, sizeof(ext_bkp.vr));
+		current->thread.vscr = ext_bkp.vscr;
+		current->thread.vrsave= ext_bkp.vrsave;
+	}
+	current->thread.used_vr = ext_bkp.used_vr;
+#endif
+
+#ifdef CONFIG_VSX
+	current->thread.used_vsr = ext_bkp.used_vsr;
+#endif
+
 	return ret;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/booke.c linux-libre-2.6.34-gnu1/arch/powerpc/kvm/booke.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/booke.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/booke.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/kvm_host.h>
+#include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
@@ -69,10 +70,10 @@ void kvmppc_dump_vcpu(struct kvm_vcpu *v
 
 	for (i = 0; i < 32; i += 4) {
 		printk("gpr%02d: %08lx %08lx %08lx %08lx\n", i,
-		       vcpu->arch.gpr[i],
-		       vcpu->arch.gpr[i+1],
-		       vcpu->arch.gpr[i+2],
-		       vcpu->arch.gpr[i+3]);
+		       kvmppc_get_gpr(vcpu, i),
+		       kvmppc_get_gpr(vcpu, i+1),
+		       kvmppc_get_gpr(vcpu, i+2),
+		       kvmppc_get_gpr(vcpu, i+3));
 	}
 }
 
@@ -82,8 +83,32 @@ static void kvmppc_booke_queue_irqprio(s
 	set_bit(priority, &vcpu->arch.pending_exceptions);
 }
 
-void kvmppc_core_queue_program(struct kvm_vcpu *vcpu)
+static void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu,
+                                        ulong dear_flags, ulong esr_flags)
+{
+	vcpu->arch.queued_dear = dear_flags;
+	vcpu->arch.queued_esr = esr_flags;
+	kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS);
+}
+
+static void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu,
+                                           ulong dear_flags, ulong esr_flags)
+{
+	vcpu->arch.queued_dear = dear_flags;
+	vcpu->arch.queued_esr = esr_flags;
+	kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE);
+}
+
+static void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu,
+                                           ulong esr_flags)
+{
+	vcpu->arch.queued_esr = esr_flags;
+	kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE);
+}
+
+void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong esr_flags)
 {
+	vcpu->arch.queued_esr = esr_flags;
 	kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM);
 }
 
@@ -97,6 +122,11 @@ int kvmppc_core_pending_dec(struct kvm_v
 	return test_bit(BOOKE_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions);
 }
 
+void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu)
+{
+	clear_bit(BOOKE_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions);
+}
+
 void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
                                 struct kvm_interrupt *irq)
 {
@@ -109,14 +139,19 @@ static int kvmppc_booke_irqprio_deliver(
 {
 	int allowed = 0;
 	ulong msr_mask;
+	bool update_esr = false, update_dear = false;
 
 	switch (priority) {
-	case BOOKE_IRQPRIO_PROGRAM:
 	case BOOKE_IRQPRIO_DTLB_MISS:
-	case BOOKE_IRQPRIO_ITLB_MISS:
-	case BOOKE_IRQPRIO_SYSCALL:
 	case BOOKE_IRQPRIO_DATA_STORAGE:
+		update_dear = true;
+		/* fall through */
 	case BOOKE_IRQPRIO_INST_STORAGE:
+	case BOOKE_IRQPRIO_PROGRAM:
+		update_esr = true;
+		/* fall through */
+	case BOOKE_IRQPRIO_ITLB_MISS:
+	case BOOKE_IRQPRIO_SYSCALL:
 	case BOOKE_IRQPRIO_FP_UNAVAIL:
 	case BOOKE_IRQPRIO_SPE_UNAVAIL:
 	case BOOKE_IRQPRIO_SPE_FP_DATA:
@@ -151,6 +186,10 @@ static int kvmppc_booke_irqprio_deliver(
 		vcpu->arch.srr0 = vcpu->arch.pc;
 		vcpu->arch.srr1 = vcpu->arch.msr;
 		vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[priority];
+		if (update_esr == true)
+			vcpu->arch.esr = vcpu->arch.queued_esr;
+		if (update_dear == true)
+			vcpu->arch.dear = vcpu->arch.queued_dear;
 		kvmppc_set_msr(vcpu, vcpu->arch.msr & msr_mask);
 
 		clear_bit(priority, &vcpu->arch.pending_exceptions);
@@ -223,8 +262,7 @@ int kvmppc_handle_exit(struct kvm_run *r
 		if (vcpu->arch.msr & MSR_PR) {
 			/* Program traps generated by user-level software must be handled
 			 * by the guest kernel. */
-			vcpu->arch.esr = vcpu->arch.fault_esr;
-			kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM);
+			kvmppc_core_queue_program(vcpu, vcpu->arch.fault_esr);
 			r = RESUME_GUEST;
 			kvmppc_account_exit(vcpu, USR_PR_INST);
 			break;
@@ -280,16 +318,14 @@ int kvmppc_handle_exit(struct kvm_run *r
 		break;
 
 	case BOOKE_INTERRUPT_DATA_STORAGE:
-		vcpu->arch.dear = vcpu->arch.fault_dear;
-		vcpu->arch.esr = vcpu->arch.fault_esr;
-		kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE);
+		kvmppc_core_queue_data_storage(vcpu, vcpu->arch.fault_dear,
+		                               vcpu->arch.fault_esr);
 		kvmppc_account_exit(vcpu, DSI_EXITS);
 		r = RESUME_GUEST;
 		break;
 
 	case BOOKE_INTERRUPT_INST_STORAGE:
-		vcpu->arch.esr = vcpu->arch.fault_esr;
-		kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE);
+		kvmppc_core_queue_inst_storage(vcpu, vcpu->arch.fault_esr);
 		kvmppc_account_exit(vcpu, ISI_EXITS);
 		r = RESUME_GUEST;
 		break;
@@ -310,9 +346,9 @@ int kvmppc_handle_exit(struct kvm_run *r
 		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_core_queue_dtlb_miss(vcpu,
+			                            vcpu->arch.fault_dear,
+			                            vcpu->arch.fault_esr);
 			kvmppc_mmu_dtlb_miss(vcpu);
 			kvmppc_account_exit(vcpu, DTLB_REAL_MISS_EXITS);
 			r = RESUME_GUEST;
@@ -426,7 +462,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu
 {
 	vcpu->arch.pc = 0;
 	vcpu->arch.msr = 0;
-	vcpu->arch.gpr[1] = (16<<20) - 8; /* -8 for the callee-save LR slot */
+	kvmppc_set_gpr(vcpu, 1, (16<<20) - 8); /* -8 for the callee-save LR slot */
 
 	vcpu->arch.shadow_pid = 1;
 
@@ -444,10 +480,10 @@ int kvm_arch_vcpu_ioctl_get_regs(struct
 	int i;
 
 	regs->pc = vcpu->arch.pc;
-	regs->cr = vcpu->arch.cr;
+	regs->cr = kvmppc_get_cr(vcpu);
 	regs->ctr = vcpu->arch.ctr;
 	regs->lr = vcpu->arch.lr;
-	regs->xer = vcpu->arch.xer;
+	regs->xer = kvmppc_get_xer(vcpu);
 	regs->msr = vcpu->arch.msr;
 	regs->srr0 = vcpu->arch.srr0;
 	regs->srr1 = vcpu->arch.srr1;
@@ -461,7 +497,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct
 	regs->sprg7 = vcpu->arch.sprg6;
 
 	for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
-		regs->gpr[i] = vcpu->arch.gpr[i];
+		regs->gpr[i] = kvmppc_get_gpr(vcpu, i);
 
 	return 0;
 }
@@ -471,10 +507,10 @@ int kvm_arch_vcpu_ioctl_set_regs(struct
 	int i;
 
 	vcpu->arch.pc = regs->pc;
-	vcpu->arch.cr = regs->cr;
+	kvmppc_set_cr(vcpu, regs->cr);
 	vcpu->arch.ctr = regs->ctr;
 	vcpu->arch.lr = regs->lr;
-	vcpu->arch.xer = regs->xer;
+	kvmppc_set_xer(vcpu, regs->xer);
 	kvmppc_set_msr(vcpu, regs->msr);
 	vcpu->arch.srr0 = regs->srr0;
 	vcpu->arch.srr1 = regs->srr1;
@@ -486,8 +522,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct
 	vcpu->arch.sprg6 = regs->sprg5;
 	vcpu->arch.sprg7 = regs->sprg6;
 
-	for (i = 0; i < ARRAY_SIZE(vcpu->arch.gpr); i++)
-		vcpu->arch.gpr[i] = regs->gpr[i];
+	for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
+		kvmppc_set_gpr(vcpu, i, regs->gpr[i]);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/booke_emulate.c linux-libre-2.6.34-gnu1/arch/powerpc/kvm/booke_emulate.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/booke_emulate.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/booke_emulate.c	2010-05-16 17:17:36.000000000 -0400
@@ -62,20 +62,20 @@ int kvmppc_booke_emulate_op(struct kvm_r
 
 		case OP_31_XOP_MFMSR:
 			rt = get_rt(inst);
-			vcpu->arch.gpr[rt] = vcpu->arch.msr;
+			kvmppc_set_gpr(vcpu, 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]);
+			kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, 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_get_gpr(vcpu, rs) & MSR_EE);
 			kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
 			break;
 
@@ -101,22 +101,23 @@ int kvmppc_booke_emulate_op(struct kvm_r
 int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
 {
 	int emulated = EMULATE_DONE;
+	ulong spr_val = kvmppc_get_gpr(vcpu, rs);
 
 	switch (sprn) {
 	case SPRN_DEAR:
-		vcpu->arch.dear = vcpu->arch.gpr[rs]; break;
+		vcpu->arch.dear = spr_val; break;
 	case SPRN_ESR:
-		vcpu->arch.esr = vcpu->arch.gpr[rs]; break;
+		vcpu->arch.esr = spr_val; break;
 	case SPRN_DBCR0:
-		vcpu->arch.dbcr0 = vcpu->arch.gpr[rs]; break;
+		vcpu->arch.dbcr0 = spr_val; break;
 	case SPRN_DBCR1:
-		vcpu->arch.dbcr1 = vcpu->arch.gpr[rs]; break;
+		vcpu->arch.dbcr1 = spr_val; break;
 	case SPRN_DBSR:
-		vcpu->arch.dbsr &= ~vcpu->arch.gpr[rs]; break;
+		vcpu->arch.dbsr &= ~spr_val; break;
 	case SPRN_TSR:
-		vcpu->arch.tsr &= ~vcpu->arch.gpr[rs]; break;
+		vcpu->arch.tsr &= ~spr_val; break;
 	case SPRN_TCR:
-		vcpu->arch.tcr = vcpu->arch.gpr[rs];
+		vcpu->arch.tcr = spr_val;
 		kvmppc_emulate_dec(vcpu);
 		break;
 
@@ -124,64 +125,64 @@ int kvmppc_booke_emulate_mtspr(struct kv
 	 * loaded into the real SPRGs when resuming the
 	 * guest. */
 	case SPRN_SPRG4:
-		vcpu->arch.sprg4 = vcpu->arch.gpr[rs]; break;
+		vcpu->arch.sprg4 = spr_val; break;
 	case SPRN_SPRG5:
-		vcpu->arch.sprg5 = vcpu->arch.gpr[rs]; break;
+		vcpu->arch.sprg5 = spr_val; break;
 	case SPRN_SPRG6:
-		vcpu->arch.sprg6 = vcpu->arch.gpr[rs]; break;
+		vcpu->arch.sprg6 = spr_val; break;
 	case SPRN_SPRG7:
-		vcpu->arch.sprg7 = vcpu->arch.gpr[rs]; break;
+		vcpu->arch.sprg7 = spr_val; break;
 
 	case SPRN_IVPR:
-		vcpu->arch.ivpr = vcpu->arch.gpr[rs];
+		vcpu->arch.ivpr = spr_val;
 		break;
 	case SPRN_IVOR0:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = spr_val;
 		break;
 	case SPRN_IVOR1:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = spr_val;
 		break;
 	case SPRN_IVOR2:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = spr_val;
 		break;
 	case SPRN_IVOR3:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = spr_val;
 		break;
 	case SPRN_IVOR4:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = spr_val;
 		break;
 	case SPRN_IVOR5:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = spr_val;
 		break;
 	case SPRN_IVOR6:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = spr_val;
 		break;
 	case SPRN_IVOR7:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = spr_val;
 		break;
 	case SPRN_IVOR8:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = spr_val;
 		break;
 	case SPRN_IVOR9:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = spr_val;
 		break;
 	case SPRN_IVOR10:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = spr_val;
 		break;
 	case SPRN_IVOR11:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = spr_val;
 		break;
 	case SPRN_IVOR12:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = spr_val;
 		break;
 	case SPRN_IVOR13:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = spr_val;
 		break;
 	case SPRN_IVOR14:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = spr_val;
 		break;
 	case SPRN_IVOR15:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = spr_val;
 		break;
 
 	default:
@@ -197,65 +198,65 @@ int kvmppc_booke_emulate_mfspr(struct kv
 
 	switch (sprn) {
 	case SPRN_IVPR:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivpr; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivpr); break;
 	case SPRN_DEAR:
-		vcpu->arch.gpr[rt] = vcpu->arch.dear; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.dear); break;
 	case SPRN_ESR:
-		vcpu->arch.gpr[rt] = vcpu->arch.esr; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.esr); break;
 	case SPRN_DBCR0:
-		vcpu->arch.gpr[rt] = vcpu->arch.dbcr0; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.dbcr0); break;
 	case SPRN_DBCR1:
-		vcpu->arch.gpr[rt] = vcpu->arch.dbcr1; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.dbcr1); break;
 	case SPRN_DBSR:
-		vcpu->arch.gpr[rt] = vcpu->arch.dbsr; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.dbsr); break;
 
 	case SPRN_IVOR0:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL]);
 		break;
 	case SPRN_IVOR1:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK]);
 		break;
 	case SPRN_IVOR2:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE]);
 		break;
 	case SPRN_IVOR3:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE]);
 		break;
 	case SPRN_IVOR4:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL]);
 		break;
 	case SPRN_IVOR5:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT]);
 		break;
 	case SPRN_IVOR6:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM]);
 		break;
 	case SPRN_IVOR7:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL]);
 		break;
 	case SPRN_IVOR8:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL]);
 		break;
 	case SPRN_IVOR9:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL]);
 		break;
 	case SPRN_IVOR10:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER]);
 		break;
 	case SPRN_IVOR11:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_FIT]);
 		break;
 	case SPRN_IVOR12:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG]);
 		break;
 	case SPRN_IVOR13:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS]);
 		break;
 	case SPRN_IVOR14:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS]);
 		break;
 	case SPRN_IVOR15:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG]);
 		break;
 
 	default:
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/e500.c linux-libre-2.6.34-gnu1/arch/powerpc/kvm/e500.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/e500.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/e500.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
  */
 
 #include <linux/kvm_host.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 
 #include <asm/reg.h>
@@ -60,6 +61,12 @@ int kvmppc_core_vcpu_setup(struct kvm_vc
 
 	kvmppc_e500_tlb_setup(vcpu_e500);
 
+	/* Registers init */
+	vcpu->arch.pvr = mfspr(SPRN_PVR);
+
+	/* Since booke kvm only support one core, update all vcpus' PIR to 0 */
+	vcpu->vcpu_id = 0;
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/e500_emulate.c linux-libre-2.6.34-gnu1/arch/powerpc/kvm/e500_emulate.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/e500_emulate.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/e500_emulate.c	2010-05-16 17:17:36.000000000 -0400
@@ -74,54 +74,59 @@ int kvmppc_core_emulate_mtspr(struct kvm
 {
 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
 	int emulated = EMULATE_DONE;
+	ulong spr_val = kvmppc_get_gpr(vcpu, rs);
 
 	switch (sprn) {
 	case SPRN_PID:
 		vcpu_e500->pid[0] = vcpu->arch.shadow_pid =
-			vcpu->arch.pid = vcpu->arch.gpr[rs];
+			vcpu->arch.pid = spr_val;
 		break;
 	case SPRN_PID1:
-		vcpu_e500->pid[1] = vcpu->arch.gpr[rs]; break;
+		vcpu_e500->pid[1] = spr_val; break;
 	case SPRN_PID2:
-		vcpu_e500->pid[2] = vcpu->arch.gpr[rs]; break;
+		vcpu_e500->pid[2] = spr_val; break;
 	case SPRN_MAS0:
-		vcpu_e500->mas0 = vcpu->arch.gpr[rs]; break;
+		vcpu_e500->mas0 = spr_val; break;
 	case SPRN_MAS1:
-		vcpu_e500->mas1 = vcpu->arch.gpr[rs]; break;
+		vcpu_e500->mas1 = spr_val; break;
 	case SPRN_MAS2:
-		vcpu_e500->mas2 = vcpu->arch.gpr[rs]; break;
+		vcpu_e500->mas2 = spr_val; break;
 	case SPRN_MAS3:
-		vcpu_e500->mas3 = vcpu->arch.gpr[rs]; break;
+		vcpu_e500->mas3 = spr_val; break;
 	case SPRN_MAS4:
-		vcpu_e500->mas4 = vcpu->arch.gpr[rs]; break;
+		vcpu_e500->mas4 = spr_val; break;
 	case SPRN_MAS6:
-		vcpu_e500->mas6 = vcpu->arch.gpr[rs]; break;
+		vcpu_e500->mas6 = spr_val; break;
 	case SPRN_MAS7:
-		vcpu_e500->mas7 = vcpu->arch.gpr[rs]; break;
+		vcpu_e500->mas7 = spr_val; break;
+	case SPRN_L1CSR0:
+		vcpu_e500->l1csr0 = spr_val;
+		vcpu_e500->l1csr0 &= ~(L1CSR0_DCFI | L1CSR0_CLFC);
+		break;
 	case SPRN_L1CSR1:
-		vcpu_e500->l1csr1 = vcpu->arch.gpr[rs]; break;
+		vcpu_e500->l1csr1 = spr_val; break;
 	case SPRN_HID0:
-		vcpu_e500->hid0 = vcpu->arch.gpr[rs]; break;
+		vcpu_e500->hid0 = spr_val; break;
 	case SPRN_HID1:
-		vcpu_e500->hid1 = vcpu->arch.gpr[rs]; break;
+		vcpu_e500->hid1 = spr_val; break;
 
 	case SPRN_MMUCSR0:
 		emulated = kvmppc_e500_emul_mt_mmucsr0(vcpu_e500,
-				vcpu->arch.gpr[rs]);
+				spr_val);
 		break;
 
 	/* extra exceptions */
 	case SPRN_IVOR32:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = spr_val;
 		break;
 	case SPRN_IVOR33:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = spr_val;
 		break;
 	case SPRN_IVOR34:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = spr_val;
 		break;
 	case SPRN_IVOR35:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = vcpu->arch.gpr[rs];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = spr_val;
 		break;
 
 	default:
@@ -138,63 +143,57 @@ int kvmppc_core_emulate_mfspr(struct kvm
 
 	switch (sprn) {
 	case SPRN_PID:
-		vcpu->arch.gpr[rt] = vcpu_e500->pid[0]; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[0]); break;
 	case SPRN_PID1:
-		vcpu->arch.gpr[rt] = vcpu_e500->pid[1]; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[1]); break;
 	case SPRN_PID2:
-		vcpu->arch.gpr[rt] = vcpu_e500->pid[2]; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[2]); break;
 	case SPRN_MAS0:
-		vcpu->arch.gpr[rt] = vcpu_e500->mas0; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas0); break;
 	case SPRN_MAS1:
-		vcpu->arch.gpr[rt] = vcpu_e500->mas1; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas1); break;
 	case SPRN_MAS2:
-		vcpu->arch.gpr[rt] = vcpu_e500->mas2; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas2); break;
 	case SPRN_MAS3:
-		vcpu->arch.gpr[rt] = vcpu_e500->mas3; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas3); break;
 	case SPRN_MAS4:
-		vcpu->arch.gpr[rt] = vcpu_e500->mas4; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas4); break;
 	case SPRN_MAS6:
-		vcpu->arch.gpr[rt] = vcpu_e500->mas6; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas6); break;
 	case SPRN_MAS7:
-		vcpu->arch.gpr[rt] = vcpu_e500->mas7; break;
+		kvmppc_set_gpr(vcpu, 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;
-
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->tlb0cfg); 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;
-
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->tlb1cfg); break;
+	case SPRN_L1CSR0:
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->l1csr0); break;
 	case SPRN_L1CSR1:
-		vcpu->arch.gpr[rt] = vcpu_e500->l1csr1; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->l1csr1); break;
 	case SPRN_HID0:
-		vcpu->arch.gpr[rt] = vcpu_e500->hid0; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->hid0); break;
 	case SPRN_HID1:
-		vcpu->arch.gpr[rt] = vcpu_e500->hid1; break;
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->hid1); break;
 
 	case SPRN_MMUCSR0:
-		vcpu->arch.gpr[rt] = 0; break;
+		kvmppc_set_gpr(vcpu, rt, 0); break;
 
 	case SPRN_MMUCFG:
-		vcpu->arch.gpr[rt] = mfspr(SPRN_MMUCFG); break;
+		kvmppc_set_gpr(vcpu, rt, mfspr(SPRN_MMUCFG)); break;
 
 	/* extra exceptions */
 	case SPRN_IVOR32:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]);
 		break;
 	case SPRN_IVOR33:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA];
+		kvmppc_set_gpr(vcpu, 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];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND]);
 		break;
 	case SPRN_IVOR35:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
+		kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]);
 		break;
 	default:
 		emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/e500_tlb.c linux-libre-2.6.34-gnu1/arch/powerpc/kvm/e500_tlb.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/e500_tlb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/e500_tlb.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
@@ -417,7 +418,7 @@ int kvmppc_e500_emul_tlbivax(struct kvm_
 	int esel, tlbsel;
 	gva_t ea;
 
-	ea = ((ra) ? vcpu->arch.gpr[ra] : 0) + vcpu->arch.gpr[rb];
+	ea = ((ra) ? kvmppc_get_gpr(vcpu, ra) : 0) + kvmppc_get_gpr(vcpu, rb);
 
 	ia = (ea >> 2) & 0x1;
 
@@ -470,7 +471,7 @@ int kvmppc_e500_emul_tlbsx(struct kvm_vc
 	struct tlbe *gtlbe = NULL;
 	gva_t ea;
 
-	ea = vcpu->arch.gpr[rb];
+	ea = kvmppc_get_gpr(vcpu, rb);
 
 	for (tlbsel = 0; tlbsel < 2; tlbsel++) {
 		esel = kvmppc_e500_tlb_index(vcpu_e500, ea, tlbsel, pid, as);
@@ -728,6 +729,12 @@ int kvmppc_e500_tlb_init(struct kvmppc_v
 	if (vcpu_e500->shadow_pages[1] == NULL)
 		goto err_out_page0;
 
+	/* Init TLB configuration register */
+	vcpu_e500->tlb0cfg = mfspr(SPRN_TLB0CFG) & ~0xfffUL;
+	vcpu_e500->tlb0cfg |= vcpu_e500->guest_tlb_size[0];
+	vcpu_e500->tlb1cfg = mfspr(SPRN_TLB1CFG) & ~0xfffUL;
+	vcpu_e500->tlb1cfg |= vcpu_e500->guest_tlb_size[1];
+
 	return 0;
 
 err_out_page0:
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/emulate.c linux-libre-2.6.34-gnu1/arch/powerpc/kvm/emulate.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/emulate.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/emulate.c	2010-05-16 17:17:36.000000000 -0400
@@ -83,6 +83,9 @@ void kvmppc_emulate_dec(struct kvm_vcpu
 
 	pr_debug("mtDEC: %x\n", vcpu->arch.dec);
 #ifdef CONFIG_PPC64
+	/* mtdec lowers the interrupt line when positive. */
+	kvmppc_core_dequeue_dec(vcpu);
+
 	/* POWER4+ triggers a dec interrupt if the value is < 0 */
 	if (vcpu->arch.dec & 0x80000000) {
 		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
@@ -140,14 +143,18 @@ int kvmppc_emulate_instruction(struct kv
 
 	pr_debug(KERN_INFO "Emulating opcode %d / %d\n", get_op(inst), get_xop(inst));
 
+	/* Try again next time */
+	if (inst == KVM_INST_FETCH_FAILED)
+		return EMULATE_DONE;
+
 	switch (get_op(inst)) {
 	case OP_TRAP:
 #ifdef CONFIG_PPC64
 	case OP_TRAP_64:
+		kvmppc_core_queue_program(vcpu, SRR1_PROGTRAP);
 #else
-		vcpu->arch.esr |= ESR_PTR;
+		kvmppc_core_queue_program(vcpu, vcpu->arch.esr | ESR_PTR);
 #endif
-		kvmppc_core_queue_program(vcpu);
 		advance = 0;
 		break;
 
@@ -167,14 +174,14 @@ int kvmppc_emulate_instruction(struct kv
 		case OP_31_XOP_STWX:
 			rs = get_rs(inst);
 			emulated = kvmppc_handle_store(run, vcpu,
-			                               vcpu->arch.gpr[rs],
+						       kvmppc_get_gpr(vcpu, rs),
 			                               4, 1);
 			break;
 
 		case OP_31_XOP_STBX:
 			rs = get_rs(inst);
 			emulated = kvmppc_handle_store(run, vcpu,
-			                               vcpu->arch.gpr[rs],
+						       kvmppc_get_gpr(vcpu, rs),
 			                               1, 1);
 			break;
 
@@ -183,14 +190,14 @@ int kvmppc_emulate_instruction(struct kv
 			ra = get_ra(inst);
 			rb = get_rb(inst);
 
-			ea = vcpu->arch.gpr[rb];
+			ea = kvmppc_get_gpr(vcpu, rb);
 			if (ra)
-				ea += vcpu->arch.gpr[ra];
+				ea += kvmppc_get_gpr(vcpu, ra);
 
 			emulated = kvmppc_handle_store(run, vcpu,
-			                               vcpu->arch.gpr[rs],
+						       kvmppc_get_gpr(vcpu, rs),
 			                               1, 1);
-			vcpu->arch.gpr[rs] = ea;
+			kvmppc_set_gpr(vcpu, rs, ea);
 			break;
 
 		case OP_31_XOP_LHZX:
@@ -203,12 +210,12 @@ int kvmppc_emulate_instruction(struct kv
 			ra = get_ra(inst);
 			rb = get_rb(inst);
 
-			ea = vcpu->arch.gpr[rb];
+			ea = kvmppc_get_gpr(vcpu, rb);
 			if (ra)
-				ea += vcpu->arch.gpr[ra];
+				ea += kvmppc_get_gpr(vcpu, ra);
 
 			emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
-			vcpu->arch.gpr[ra] = ea;
+			kvmppc_set_gpr(vcpu, ra, ea);
 			break;
 
 		case OP_31_XOP_MFSPR:
@@ -217,47 +224,49 @@ int kvmppc_emulate_instruction(struct kv
 
 			switch (sprn) {
 			case SPRN_SRR0:
-				vcpu->arch.gpr[rt] = vcpu->arch.srr0; break;
+				kvmppc_set_gpr(vcpu, rt, vcpu->arch.srr0); break;
 			case SPRN_SRR1:
-				vcpu->arch.gpr[rt] = vcpu->arch.srr1; break;
+				kvmppc_set_gpr(vcpu, rt, vcpu->arch.srr1); break;
 			case SPRN_PVR:
-				vcpu->arch.gpr[rt] = vcpu->arch.pvr; break;
+				kvmppc_set_gpr(vcpu, rt, vcpu->arch.pvr); break;
 			case SPRN_PIR:
-				vcpu->arch.gpr[rt] = vcpu->vcpu_id; break;
+				kvmppc_set_gpr(vcpu, rt, vcpu->vcpu_id); break;
 			case SPRN_MSSSR0:
-				vcpu->arch.gpr[rt] = 0; break;
+				kvmppc_set_gpr(vcpu, rt, 0); break;
 
 			/* Note: mftb and TBRL/TBWL are user-accessible, so
 			 * the guest can always access the real TB anyways.
 			 * In fact, we probably will never see these traps. */
 			case SPRN_TBWL:
-				vcpu->arch.gpr[rt] = get_tb() >> 32; break;
+				kvmppc_set_gpr(vcpu, rt, get_tb() >> 32); break;
 			case SPRN_TBWU:
-				vcpu->arch.gpr[rt] = get_tb(); break;
+				kvmppc_set_gpr(vcpu, rt, get_tb()); break;
 
 			case SPRN_SPRG0:
-				vcpu->arch.gpr[rt] = vcpu->arch.sprg0; break;
+				kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg0); break;
 			case SPRN_SPRG1:
-				vcpu->arch.gpr[rt] = vcpu->arch.sprg1; break;
+				kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg1); break;
 			case SPRN_SPRG2:
-				vcpu->arch.gpr[rt] = vcpu->arch.sprg2; break;
+				kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg2); break;
 			case SPRN_SPRG3:
-				vcpu->arch.gpr[rt] = vcpu->arch.sprg3; break;
+				kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg3); break;
 			/* Note: SPRG4-7 are user-readable, so we don't get
 			 * a trap. */
 
 			case SPRN_DEC:
 			{
 				u64 jd = get_tb() - vcpu->arch.dec_jiffies;
-				vcpu->arch.gpr[rt] = vcpu->arch.dec - jd;
-				pr_debug(KERN_INFO "mfDEC: %x - %llx = %lx\n", vcpu->arch.dec, jd, vcpu->arch.gpr[rt]);
+				kvmppc_set_gpr(vcpu, rt, vcpu->arch.dec - jd);
+				pr_debug(KERN_INFO "mfDEC: %x - %llx = %lx\n",
+					 vcpu->arch.dec, jd,
+					 kvmppc_get_gpr(vcpu, rt));
 				break;
 			}
 			default:
 				emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, rt);
 				if (emulated == EMULATE_FAIL) {
 					printk("mfspr: unknown spr %x\n", sprn);
-					vcpu->arch.gpr[rt] = 0;
+					kvmppc_set_gpr(vcpu, rt, 0);
 				}
 				break;
 			}
@@ -269,7 +278,7 @@ int kvmppc_emulate_instruction(struct kv
 			rb = get_rb(inst);
 
 			emulated = kvmppc_handle_store(run, vcpu,
-			                               vcpu->arch.gpr[rs],
+						       kvmppc_get_gpr(vcpu, rs),
 			                               2, 1);
 			break;
 
@@ -278,14 +287,14 @@ int kvmppc_emulate_instruction(struct kv
 			ra = get_ra(inst);
 			rb = get_rb(inst);
 
-			ea = vcpu->arch.gpr[rb];
+			ea = kvmppc_get_gpr(vcpu, rb);
 			if (ra)
-				ea += vcpu->arch.gpr[ra];
+				ea += kvmppc_get_gpr(vcpu, ra);
 
 			emulated = kvmppc_handle_store(run, vcpu,
-			                               vcpu->arch.gpr[rs],
+						       kvmppc_get_gpr(vcpu, rs),
 			                               2, 1);
-			vcpu->arch.gpr[ra] = ea;
+			kvmppc_set_gpr(vcpu, ra, ea);
 			break;
 
 		case OP_31_XOP_MTSPR:
@@ -293,9 +302,9 @@ int kvmppc_emulate_instruction(struct kv
 			rs = get_rs(inst);
 			switch (sprn) {
 			case SPRN_SRR0:
-				vcpu->arch.srr0 = vcpu->arch.gpr[rs]; break;
+				vcpu->arch.srr0 = kvmppc_get_gpr(vcpu, rs); break;
 			case SPRN_SRR1:
-				vcpu->arch.srr1 = vcpu->arch.gpr[rs]; break;
+				vcpu->arch.srr1 = kvmppc_get_gpr(vcpu, rs); break;
 
 			/* XXX We need to context-switch the timebase for
 			 * watchdog and FIT. */
@@ -305,18 +314,18 @@ int kvmppc_emulate_instruction(struct kv
 			case SPRN_MSSSR0: break;
 
 			case SPRN_DEC:
-				vcpu->arch.dec = vcpu->arch.gpr[rs];
+				vcpu->arch.dec = kvmppc_get_gpr(vcpu, rs);
 				kvmppc_emulate_dec(vcpu);
 				break;
 
 			case SPRN_SPRG0:
-				vcpu->arch.sprg0 = vcpu->arch.gpr[rs]; break;
+				vcpu->arch.sprg0 = kvmppc_get_gpr(vcpu, rs); break;
 			case SPRN_SPRG1:
-				vcpu->arch.sprg1 = vcpu->arch.gpr[rs]; break;
+				vcpu->arch.sprg1 = kvmppc_get_gpr(vcpu, rs); break;
 			case SPRN_SPRG2:
-				vcpu->arch.sprg2 = vcpu->arch.gpr[rs]; break;
+				vcpu->arch.sprg2 = kvmppc_get_gpr(vcpu, rs); break;
 			case SPRN_SPRG3:
-				vcpu->arch.sprg3 = vcpu->arch.gpr[rs]; break;
+				vcpu->arch.sprg3 = kvmppc_get_gpr(vcpu, rs); break;
 
 			default:
 				emulated = kvmppc_core_emulate_mtspr(vcpu, sprn, rs);
@@ -348,7 +357,7 @@ int kvmppc_emulate_instruction(struct kv
 			rb = get_rb(inst);
 
 			emulated = kvmppc_handle_store(run, vcpu,
-			                               vcpu->arch.gpr[rs],
+						       kvmppc_get_gpr(vcpu, rs),
 			                               4, 0);
 			break;
 
@@ -363,7 +372,7 @@ int kvmppc_emulate_instruction(struct kv
 			rb = get_rb(inst);
 
 			emulated = kvmppc_handle_store(run, vcpu,
-			                               vcpu->arch.gpr[rs],
+						       kvmppc_get_gpr(vcpu, rs),
 			                               2, 0);
 			break;
 
@@ -382,7 +391,7 @@ int kvmppc_emulate_instruction(struct kv
 		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;
+		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
 		break;
 
 	case OP_LBZ:
@@ -394,35 +403,39 @@ int kvmppc_emulate_instruction(struct kv
 		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;
+		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
 		break;
 
 	case OP_STW:
 		rs = get_rs(inst);
-		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
+		emulated = kvmppc_handle_store(run, vcpu,
+					       kvmppc_get_gpr(vcpu, rs),
 		                               4, 1);
 		break;
 
 	case OP_STWU:
 		ra = get_ra(inst);
 		rs = get_rs(inst);
-		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
+		emulated = kvmppc_handle_store(run, vcpu,
+					       kvmppc_get_gpr(vcpu, rs),
 		                               4, 1);
-		vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
+		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
 		break;
 
 	case OP_STB:
 		rs = get_rs(inst);
-		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
+		emulated = kvmppc_handle_store(run, vcpu,
+					       kvmppc_get_gpr(vcpu, rs),
 		                               1, 1);
 		break;
 
 	case OP_STBU:
 		ra = get_ra(inst);
 		rs = get_rs(inst);
-		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
+		emulated = kvmppc_handle_store(run, vcpu,
+					       kvmppc_get_gpr(vcpu, rs),
 		                               1, 1);
-		vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
+		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
 		break;
 
 	case OP_LHZ:
@@ -434,21 +447,23 @@ int kvmppc_emulate_instruction(struct kv
 		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;
+		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
 		break;
 
 	case OP_STH:
 		rs = get_rs(inst);
-		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
+		emulated = kvmppc_handle_store(run, vcpu,
+					       kvmppc_get_gpr(vcpu, rs),
 		                               2, 1);
 		break;
 
 	case OP_STHU:
 		ra = get_ra(inst);
 		rs = get_rs(inst);
-		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
+		emulated = kvmppc_handle_store(run, vcpu,
+					       kvmppc_get_gpr(vcpu, rs),
 		                               2, 1);
-		vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
+		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
 		break;
 
 	default:
@@ -461,6 +476,7 @@ int kvmppc_emulate_instruction(struct kv
 			advance = 0;
 			printk(KERN_ERR "Couldn't emulate instruction 0x%08x "
 			       "(op %d xop %d)\n", inst, get_op(inst), get_xop(inst));
+			kvmppc_core_queue_program(vcpu, 0);
 		}
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/Kconfig linux-libre-2.6.34-gnu1/arch/powerpc/kvm/Kconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@ config KVM
 	bool
 	select PREEMPT_NOTIFIERS
 	select ANON_INODES
+	select KVM_MMIO
 
 config KVM_BOOK3S_64_HANDLER
 	bool
@@ -75,6 +76,7 @@ config KVM_E500
 
 	  If unsure, say N.
 
+source drivers/vhost/Kconfig
 source drivers/virtio/Kconfig
 
 endif # VIRTUALIZATION
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/kvm/powerpc.c linux-libre-2.6.34-gnu1/arch/powerpc/kvm/powerpc.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/kvm/powerpc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/kvm/powerpc.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/vmalloc.h>
 #include <linux/hrtimer.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <asm/cputable.h>
 #include <asm/uaccess.h>
 #include <asm/kvm_ppc.h>
@@ -137,6 +138,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm
 {
 	kvmppc_free_vcpus(kvm);
 	kvm_free_physmem(kvm);
+	cleanup_srcu_struct(&kvm->srcu);
 	kfree(kvm);
 }
 
@@ -165,14 +167,24 @@ long kvm_arch_dev_ioctl(struct file *fil
 	return -EINVAL;
 }
 
-int kvm_arch_set_memory_region(struct kvm *kvm,
-                               struct kvm_userspace_memory_region *mem,
-                               struct kvm_memory_slot old,
-                               int user_alloc)
+int kvm_arch_prepare_memory_region(struct kvm *kvm,
+                                   struct kvm_memory_slot *memslot,
+                                   struct kvm_memory_slot old,
+                                   struct kvm_userspace_memory_region *mem,
+                                   int user_alloc)
 {
 	return 0;
 }
 
+void kvm_arch_commit_memory_region(struct kvm *kvm,
+               struct kvm_userspace_memory_region *mem,
+               struct kvm_memory_slot old,
+               int user_alloc)
+{
+       return;
+}
+
+
 void kvm_arch_flush_shadow(struct kvm *kvm)
 {
 }
@@ -260,34 +272,35 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(
 static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu,
                                      struct kvm_run *run)
 {
-	ulong *gpr = &vcpu->arch.gpr[vcpu->arch.io_gpr];
-	*gpr = run->dcr.data;
+	kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, run->dcr.data);
 }
 
 static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu,
                                       struct kvm_run *run)
 {
-	ulong *gpr = &vcpu->arch.gpr[vcpu->arch.io_gpr];
+	ulong gpr;
 
-	if (run->mmio.len > sizeof(*gpr)) {
+	if (run->mmio.len > sizeof(gpr)) {
 		printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len);
 		return;
 	}
 
 	if (vcpu->arch.mmio_is_bigendian) {
 		switch (run->mmio.len) {
-		case 4: *gpr = *(u32 *)run->mmio.data; break;
-		case 2: *gpr = *(u16 *)run->mmio.data; break;
-		case 1: *gpr = *(u8 *)run->mmio.data; break;
+		case 4: gpr = *(u32 *)run->mmio.data; break;
+		case 2: gpr = *(u16 *)run->mmio.data; break;
+		case 1: gpr = *(u8 *)run->mmio.data; break;
 		}
 	} else {
 		/* Convert BE data from userland back to LE. */
 		switch (run->mmio.len) {
-		case 4: *gpr = ld_le32((u32 *)run->mmio.data); break;
-		case 2: *gpr = ld_le16((u16 *)run->mmio.data); break;
-		case 1: *gpr = *(u8 *)run->mmio.data; break;
+		case 4: gpr = ld_le32((u32 *)run->mmio.data); break;
+		case 2: gpr = ld_le16((u16 *)run->mmio.data); break;
+		case 1: gpr = *(u8 *)run->mmio.data; break;
 		}
 	}
+
+	kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr);
 }
 
 int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/lib/copypage_64.S linux-libre-2.6.34-gnu1/arch/powerpc/lib/copypage_64.S
--- linux-libre-2.6.33-gnu1/arch/powerpc/lib/copypage_64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/lib/copypage_64.S	2010-05-16 17:17:36.000000000 -0400
@@ -43,62 +43,62 @@ END_FTR_SECTION_IFSET(CPU_FTR_CP_USE_DCB
 	ld	r7,16(r4)
 	ldu	r8,24(r4)
 1:	std	r5,8(r3)
-	ld	r9,8(r4)
 	std	r6,16(r3)
+	ld	r9,8(r4)
 	ld	r10,16(r4)
 	std	r7,24(r3)
-	ld	r11,24(r4)
 	std	r8,32(r3)
+	ld	r11,24(r4)
 	ld	r12,32(r4)
 	std	r9,40(r3)
-	ld	r5,40(r4)
 	std	r10,48(r3)
+	ld	r5,40(r4)
 	ld	r6,48(r4)
 	std	r11,56(r3)
-	ld	r7,56(r4)
 	std	r12,64(r3)
+	ld	r7,56(r4)
 	ld	r8,64(r4)
 	std	r5,72(r3)
-	ld	r9,72(r4)
 	std	r6,80(r3)
+	ld	r9,72(r4)
 	ld	r10,80(r4)
 	std	r7,88(r3)
-	ld	r11,88(r4)
 	std	r8,96(r3)
+	ld	r11,88(r4)
 	ld	r12,96(r4)
 	std	r9,104(r3)
-	ld	r5,104(r4)
 	std	r10,112(r3)
+	ld	r5,104(r4)
 	ld	r6,112(r4)
 	std	r11,120(r3)
-	ld	r7,120(r4)
 	stdu	r12,128(r3)
+	ld	r7,120(r4)
 	ldu	r8,128(r4)
 	bdnz	1b
 
 	std	r5,8(r3)
-	ld	r9,8(r4)
 	std	r6,16(r3)
+	ld	r9,8(r4)
 	ld	r10,16(r4)
 	std	r7,24(r3)
-	ld	r11,24(r4)
 	std	r8,32(r3)
+	ld	r11,24(r4)
 	ld	r12,32(r4)
 	std	r9,40(r3)
-	ld	r5,40(r4)
 	std	r10,48(r3)
+	ld	r5,40(r4)
 	ld	r6,48(r4)
 	std	r11,56(r3)
-	ld	r7,56(r4)
 	std	r12,64(r3)
+	ld	r7,56(r4)
 	ld	r8,64(r4)
 	std	r5,72(r3)
-	ld	r9,72(r4)
 	std	r6,80(r3)
+	ld	r9,72(r4)
 	ld	r10,80(r4)
 	std	r7,88(r3)
-	ld	r11,88(r4)
 	std	r8,96(r3)
+	ld	r11,88(r4)
 	ld	r12,96(r4)
 	std	r9,104(r3)
 	std	r10,112(r3)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/lib/copyuser_64.S linux-libre-2.6.34-gnu1/arch/powerpc/lib/copyuser_64.S
--- linux-libre-2.6.33-gnu1/arch/powerpc/lib/copyuser_64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/lib/copyuser_64.S	2010-05-16 17:17:36.000000000 -0400
@@ -44,37 +44,55 @@ BEGIN_FTR_SECTION
 	andi.	r0,r4,7
 	bne	.Lsrc_unaligned
 END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
-	srdi	r7,r5,4
-20:	ld	r9,0(r4)
-	addi	r4,r4,-8
-	mtctr	r7
-	andi.	r5,r5,7
-	bf	cr7*4+0,22f
-	addi	r3,r3,8
-	addi	r4,r4,8
-	mr	r8,r9
-	blt	cr1,72f
-21:	ld	r9,8(r4)
-70:	std	r8,8(r3)
-22:	ldu	r8,16(r4)
-71:	stdu	r9,16(r3)
+	blt	cr1,.Ldo_tail		/* if < 16 bytes to copy */
+	srdi	r0,r5,5
+	cmpdi	cr1,r0,0
+20:	ld	r7,0(r4)
+220:	ld	r6,8(r4)
+	addi	r4,r4,16
+	mtctr	r0
+	andi.	r0,r5,0x10
+	beq	22f
+	addi	r3,r3,16
+	addi	r4,r4,-16
+	mr	r9,r7
+	mr	r8,r6
+	beq	cr1,72f
+21:	ld	r7,16(r4)
+221:	ld	r6,24(r4)
+	addi	r4,r4,32
+70:	std	r9,0(r3)
+270:	std	r8,8(r3)
+22:	ld	r9,0(r4)
+222:	ld	r8,8(r4)
+71:	std	r7,16(r3)
+271:	std	r6,24(r3)
+	addi	r3,r3,32
 	bdnz	21b
-72:	std	r8,8(r3)
+72:	std	r9,0(r3)
+272:	std	r8,8(r3)
+	andi.	r5,r5,0xf
 	beq+	3f
-	addi	r3,r3,16
+	addi	r4,r4,16
 .Ldo_tail:
-	bf	cr7*4+1,1f
-23:	lwz	r9,8(r4)
+	addi	r3,r3,16
+	bf	cr7*4+0,246f
+244:	ld	r9,0(r4)
+	addi	r4,r4,8
+245:	std	r9,0(r3)
+	addi	r3,r3,8
+246:	bf	cr7*4+1,1f
+23:	lwz	r9,0(r4)
 	addi	r4,r4,4
 73:	stw	r9,0(r3)
 	addi	r3,r3,4
 1:	bf	cr7*4+2,2f
-44:	lhz	r9,8(r4)
+44:	lhz	r9,0(r4)
 	addi	r4,r4,2
 74:	sth	r9,0(r3)
 	addi	r3,r3,2
 2:	bf	cr7*4+3,3f
-45:	lbz	r9,8(r4)
+45:	lbz	r9,0(r4)
 75:	stb	r9,0(r3)
 3:	li	r3,0
 	blr
@@ -220,7 +238,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_
 131:
 	addi	r3,r3,8
 120:
+320:
 122:
+322:
 124:
 125:
 126:
@@ -229,9 +249,11 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_
 129:
 133:
 	addi	r3,r3,8
-121:
 132:
 	addi	r3,r3,8
+121:
+321:
+344:
 134:
 135:
 138:
@@ -303,18 +325,22 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_
 183:
 	add	r3,r3,r7
 	b	1f
+371:
 180:
 	addi	r3,r3,8
 171:
 177:
 	addi	r3,r3,8
-170:
-172:
+370:
+372:
 176:
 178:
 	addi	r3,r3,4
 185:
 	addi	r3,r3,4
+170:
+172:
+345:
 173:
 174:
 175:
@@ -341,11 +367,19 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_
 	.section __ex_table,"a"
 	.align	3
 	.llong	20b,120b
+	.llong	220b,320b
 	.llong	21b,121b
+	.llong	221b,321b
 	.llong	70b,170b
+	.llong	270b,370b
 	.llong	22b,122b
+	.llong	222b,322b
 	.llong	71b,171b
+	.llong	271b,371b
 	.llong	72b,172b
+	.llong	272b,372b
+	.llong	244b,344b
+	.llong	245b,345b
 	.llong	23b,123b
 	.llong	73b,173b
 	.llong	44b,144b
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/lib/devres.c linux-libre-2.6.34-gnu1/arch/powerpc/lib/devres.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/lib/devres.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/lib/devres.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  */
 
 #include <linux/device.h>	/* devres_*(), devm_ioremap_release() */
+#include <linux/gfp.h>
 #include <linux/io.h>		/* ioremap_flags() */
 #include <linux/module.h>	/* EXPORT_SYMBOL() */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/lib/feature-fixups.c linux-libre-2.6.34-gnu1/arch/powerpc/lib/feature-fixups.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/lib/feature-fixups.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/lib/feature-fixups.c	2010-05-16 17:17:36.000000000 -0400
@@ -112,7 +112,8 @@ void do_feature_fixups(unsigned long val
 
 void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
 {
-	unsigned int *start, *end, *dest;
+	long *start, *end;
+	unsigned int *dest;
 
 	if (!(value & CPU_FTR_LWSYNC))
 		return ;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/40x_mmu.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/40x_mmu.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/40x_mmu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/40x_mmu.c	2010-05-16 17:17:36.000000000 -0400
@@ -84,8 +84,8 @@ void __init MMU_init_hw(void)
 	 * vectors and the kernel live in real-mode.
 	 */
 
-        mtspr(SPRN_DCCR, 0xF0000000);	/* 512 MB of data space at 0x0. */
-        mtspr(SPRN_ICCR, 0xF0000000);	/* 512 MB of instr. space at 0x0. */
+        mtspr(SPRN_DCCR, 0xFFFF0000);	/* 2GByte of data space at 0x0. */
+        mtspr(SPRN_ICCR, 0xFFFF0000);	/* 2GByte of instr. space at 0x0. */
 }
 
 #define LARGE_PAGE_SIZE_16M	(1<<24)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/dma-noncoherent.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/dma-noncoherent.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/dma-noncoherent.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/dma-noncoherent.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/fsl_booke_mmu.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/fsl_booke_mmu.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/fsl_booke_mmu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/fsl_booke_mmu.c	2010-05-16 17:17:36.000000000 -0400
@@ -116,7 +116,7 @@ void loadcam_entry(int idx)
 	mtspr(SPRN_MAS2, TLBCAM[idx].MAS2);
 	mtspr(SPRN_MAS3, TLBCAM[idx].MAS3);
 
-	if (cur_cpu_spec->cpu_features & MMU_FTR_BIG_PHYS)
+	if (mmu_has_feature(MMU_FTR_BIG_PHYS))
 		mtspr(SPRN_MAS7, TLBCAM[idx].MAS7);
 
 	asm volatile("isync;tlbwe;isync" : : : "memory");
@@ -152,18 +152,13 @@ static void settlbcam(int index, unsigne
 
 	TLBCAM[index].MAS3 = (phys & MAS3_RPN) | MAS3_SX | MAS3_SR;
 	TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_SW : 0);
-	if (cur_cpu_spec->cpu_features & MMU_FTR_BIG_PHYS)
+	if (mmu_has_feature(MMU_FTR_BIG_PHYS))
 		TLBCAM[index].MAS7 = (u64)phys >> 32;
 
-#ifndef CONFIG_KGDB /* want user access for breakpoints */
 	if (flags & _PAGE_USER) {
 	   TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
 	   TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
 	}
-#else
-	TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
-	TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
-#endif
 
 	tlbcam_addrs[index].start = virt;
 	tlbcam_addrs[index].limit = virt + size - 1;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/hash_native_64.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/hash_native_64.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/hash_native_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/hash_native_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,7 +37,7 @@
 
 #define HPTE_LOCK_BIT 3
 
-static DEFINE_SPINLOCK(native_tlbie_lock);
+static DEFINE_RAW_SPINLOCK(native_tlbie_lock);
 
 static inline void __tlbie(unsigned long va, int psize, int ssize)
 {
@@ -104,7 +104,7 @@ static inline void tlbie(unsigned long v
 	if (use_local)
 		use_local = mmu_psize_defs[psize].tlbiel;
 	if (lock_tlbie && !use_local)
-		spin_lock(&native_tlbie_lock);
+		raw_spin_lock(&native_tlbie_lock);
 	asm volatile("ptesync": : :"memory");
 	if (use_local) {
 		__tlbiel(va, psize, ssize);
@@ -114,7 +114,7 @@ static inline void tlbie(unsigned long v
 		asm volatile("eieio; tlbsync; ptesync": : :"memory");
 	}
 	if (lock_tlbie && !use_local)
-		spin_unlock(&native_tlbie_lock);
+		raw_spin_unlock(&native_tlbie_lock);
 }
 
 static inline void native_lock_hpte(struct hash_pte *hptep)
@@ -122,7 +122,7 @@ static inline void native_lock_hpte(stru
 	unsigned long *word = &hptep->v;
 
 	while (1) {
-		if (!test_and_set_bit(HPTE_LOCK_BIT, word))
+		if (!test_and_set_bit_lock(HPTE_LOCK_BIT, word))
 			break;
 		while(test_bit(HPTE_LOCK_BIT, word))
 			cpu_relax();
@@ -133,8 +133,7 @@ static inline void native_unlock_hpte(st
 {
 	unsigned long *word = &hptep->v;
 
-	asm volatile("lwsync":::"memory");
-	clear_bit(HPTE_LOCK_BIT, word);
+	clear_bit_unlock(HPTE_LOCK_BIT, word);
 }
 
 static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
@@ -434,7 +433,7 @@ static void native_hpte_clear(void)
 	/* we take the tlbie lock and hold it.  Some hardware will
 	 * deadlock if we try to tlbie from two processors at once.
 	 */
-	spin_lock(&native_tlbie_lock);
+	raw_spin_lock(&native_tlbie_lock);
 
 	slots = pteg_count * HPTES_PER_GROUP;
 
@@ -458,7 +457,7 @@ static void native_hpte_clear(void)
 	}
 
 	asm volatile("eieio; tlbsync; ptesync":::"memory");
-	spin_unlock(&native_tlbie_lock);
+	raw_spin_unlock(&native_tlbie_lock);
 	local_irq_restore(flags);
 }
 
@@ -521,7 +520,7 @@ static void native_flush_hash_range(unsi
 		int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
 
 		if (lock_tlbie)
-			spin_lock(&native_tlbie_lock);
+			raw_spin_lock(&native_tlbie_lock);
 
 		asm volatile("ptesync":::"memory");
 		for (i = 0; i < number; i++) {
@@ -536,7 +535,7 @@ static void native_flush_hash_range(unsi
 		asm volatile("eieio; tlbsync; ptesync":::"memory");
 
 		if (lock_tlbie)
-			spin_unlock(&native_tlbie_lock);
+			raw_spin_unlock(&native_tlbie_lock);
 	}
 
 	local_irq_restore(flags);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/hugetlbpage.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/hugetlbpage.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/hugetlbpage.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/hugetlbpage.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 
 #include <linux/mm.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/hugetlb.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/init_32.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/init_32.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/init_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/init_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/initrd.h>
 #include <linux/pagemap.h>
 #include <linux/lmb.h>
+#include <linux/gfp.h>
 
 #include <asm/pgalloc.h>
 #include <asm/prom.h>
@@ -47,7 +48,7 @@
 #include "mmu_decl.h"
 
 #if defined(CONFIG_KERNEL_START_BOOL) || defined(CONFIG_LOWMEM_SIZE_BOOL)
-/* The ammount of lowmem must be within 0xF0000000 - KERNELBASE. */
+/* The amount of lowmem must be within 0xF0000000 - KERNELBASE. */
 #if (CONFIG_LOWMEM_SIZE > (0xF0000000 - PAGE_OFFSET))
 #error "You must adjust CONFIG_LOWMEM_SIZE or CONFIG_START_KERNEL"
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/init_64.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/init_64.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/init_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/init_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/poison.h>
 #include <linux/lmb.h>
 #include <linux/hugetlb.h>
+#include <linux/slab.h>
 
 #include <asm/pgalloc.h>
 #include <asm/page.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/mem.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/mem.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/mem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/mem.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/gfp.h>
 #include <linux/types.h>
 #include <linux/mm.h>
 #include <linux/stddef.h>
@@ -48,6 +49,7 @@
 #include <asm/sparsemem.h>
 #include <asm/vdso.h>
 #include <asm/fixmap.h>
+#include <asm/swiotlb.h>
 
 #include "mmu_decl.h"
 
@@ -320,6 +322,11 @@ void __init mem_init(void)
 	struct page *page;
 	unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
 
+#ifdef CONFIG_SWIOTLB
+	if (ppc_swiotlb_enable)
+		swiotlb_init(1);
+#endif
+
 	num_physpages = lmb.memory.size >> PAGE_SHIFT;
 	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
 
@@ -494,13 +501,13 @@ EXPORT_SYMBOL(flush_icache_user_range);
  * This must always be called with the pte lock held.
  */
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
-		      pte_t pte)
+		      pte_t *ptep)
 {
 #ifdef CONFIG_PPC_STD_MMU
 	unsigned long access = 0, trap;
 
 	/* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */
-	if (!pte_young(pte) || address >= TASK_SIZE)
+	if (!pte_young(*ptep) || address >= TASK_SIZE)
 		return;
 
 	/* We try to figure out if we are coming from an instruction
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/mmu_context_hash64.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/mmu_context_hash64.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/mmu_context_hash64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/mmu_context_hash64.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,11 +19,12 @@
 #include <linux/spinlock.h>
 #include <linux/idr.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 
 #include <asm/mmu_context.h>
 
 static DEFINE_SPINLOCK(mmu_context_lock);
-static DEFINE_IDR(mmu_context_idr);
+static DEFINE_IDA(mmu_context_ida);
 
 /*
  * The proto-VSID space has 2^35 - 1 segments available for user mappings.
@@ -39,11 +40,11 @@ int __init_new_context(void)
 	int err;
 
 again:
-	if (!idr_pre_get(&mmu_context_idr, GFP_KERNEL))
+	if (!ida_pre_get(&mmu_context_ida, GFP_KERNEL))
 		return -ENOMEM;
 
 	spin_lock(&mmu_context_lock);
-	err = idr_get_new_above(&mmu_context_idr, NULL, 1, &index);
+	err = ida_get_new_above(&mmu_context_ida, 1, &index);
 	spin_unlock(&mmu_context_lock);
 
 	if (err == -EAGAIN)
@@ -53,7 +54,7 @@ again:
 
 	if (index > MAX_CONTEXT) {
 		spin_lock(&mmu_context_lock);
-		idr_remove(&mmu_context_idr, index);
+		ida_remove(&mmu_context_ida, index);
 		spin_unlock(&mmu_context_lock);
 		return -ENOMEM;
 	}
@@ -85,7 +86,7 @@ int init_new_context(struct task_struct
 void __destroy_context(int context_id)
 {
 	spin_lock(&mmu_context_lock);
-	idr_remove(&mmu_context_idr, context_id);
+	ida_remove(&mmu_context_ida, context_id);
 	spin_unlock(&mmu_context_lock);
 }
 EXPORT_SYMBOL_GPL(__destroy_context);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/mmu_context_nohash.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/mmu_context_nohash.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/mmu_context_nohash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/mmu_context_nohash.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,7 @@
 #include <linux/bootmem.h>
 #include <linux/notifier.h>
 #include <linux/cpu.h>
+#include <linux/slab.h>
 
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
@@ -56,7 +57,7 @@ static unsigned int next_context, nr_fre
 static unsigned long *context_map;
 static unsigned long *stale_map[NR_CPUS];
 static struct mm_struct **context_mm;
-static DEFINE_SPINLOCK(context_lock);
+static DEFINE_RAW_SPINLOCK(context_lock);
 
 #define CTX_MAP_SIZE	\
 	(sizeof(unsigned long) * (last_context / BITS_PER_LONG + 1))
@@ -121,9 +122,9 @@ static unsigned int steal_context_smp(un
 	/* This will happen if you have more CPUs than available contexts,
 	 * all we can do here is wait a bit and try again
 	 */
-	spin_unlock(&context_lock);
+	raw_spin_unlock(&context_lock);
 	cpu_relax();
-	spin_lock(&context_lock);
+	raw_spin_lock(&context_lock);
 
 	/* This will cause the caller to try again */
 	return MMU_NO_CONTEXT;
@@ -194,7 +195,7 @@ void switch_mmu_context(struct mm_struct
 	unsigned long *map;
 
 	/* No lockless fast path .. yet */
-	spin_lock(&context_lock);
+	raw_spin_lock(&context_lock);
 
 	pr_hard("[%d] activating context for mm @%p, active=%d, id=%d",
 		cpu, next, next->context.active, next->context.id);
@@ -278,7 +279,7 @@ void switch_mmu_context(struct mm_struct
 	/* Flick the MMU and release lock */
 	pr_hardcont(" -> %d\n", id);
 	set_context(id, next->pgd);
-	spin_unlock(&context_lock);
+	raw_spin_unlock(&context_lock);
 }
 
 /*
@@ -307,7 +308,7 @@ void destroy_context(struct mm_struct *m
 
 	WARN_ON(mm->context.active != 0);
 
-	spin_lock_irqsave(&context_lock, flags);
+	raw_spin_lock_irqsave(&context_lock, flags);
 	id = mm->context.id;
 	if (id != MMU_NO_CONTEXT) {
 		__clear_bit(id, context_map);
@@ -318,7 +319,7 @@ void destroy_context(struct mm_struct *m
 		context_mm[id] = NULL;
 		nr_free_contexts++;
 	}
-	spin_unlock_irqrestore(&context_lock, flags);
+	raw_spin_unlock_irqrestore(&context_lock, flags);
 }
 
 #ifdef CONFIG_SMP
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/numa.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/numa.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/numa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/numa.c	2010-05-16 17:17:36.000000000 -0400
@@ -242,10 +242,11 @@ EXPORT_SYMBOL_GPL(of_node_to_nid);
  */
 static int __init find_min_common_depth(void)
 {
-	int depth;
+	int depth, index;
 	const unsigned int *ref_points;
 	struct device_node *rtas_root;
 	unsigned int len;
+	struct device_node *options;
 
 	rtas_root = of_find_node_by_path("/rtas");
 
@@ -258,11 +259,23 @@ static int __init find_min_common_depth(
 	 * configuration (should be all 0's) and the second is for a normal
 	 * NUMA configuration.
 	 */
+	index = 1;
 	ref_points = of_get_property(rtas_root,
 			"ibm,associativity-reference-points", &len);
 
+	/*
+	 * For type 1 affinity information we want the first field
+	 */
+	options = of_find_node_by_path("/options");
+	if (options) {
+		const char *str;
+		str = of_get_property(options, "ibm,associativity-form", NULL);
+		if (str && !strcmp(str, "1"))
+                        index = 0;
+	}
+
 	if ((len >= 2 * sizeof(unsigned int)) && ref_points) {
-		depth = ref_points[1];
+		depth = ref_points[index];
 	} else {
 		dbg("NUMA: ibm,associativity-reference-points not found.\n");
 		depth = -1;
@@ -451,7 +464,7 @@ static int __cpuinit numa_setup_cpu(unsi
 	nid = of_node_to_nid_single(cpu);
 
 	if (nid < 0 || !node_online(nid))
-		nid = any_online_node(NODE_MASK_ALL);
+		nid = first_online_node;
 out:
 	map_cpu_to_node(lcpu, nid);
 
@@ -1114,7 +1127,7 @@ int hot_add_scn_to_nid(unsigned long scn
 	int nid, found = 0;
 
 	if (!numa_enabled || (min_common_depth < 0))
-		return any_online_node(NODE_MASK_ALL);
+		return first_online_node;
 
 	memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
 	if (memory) {
@@ -1125,7 +1138,7 @@ int hot_add_scn_to_nid(unsigned long scn
 	}
 
 	if (nid < 0 || !node_online(nid))
-		nid = any_online_node(NODE_MASK_ALL);
+		nid = first_online_node;
 
 	if (NODE_DATA(nid)->node_spanned_pages)
 		return nid;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/pgtable_32.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/pgtable_32.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/pgtable_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/pgtable_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/highmem.h>
 #include <linux/lmb.h>
+#include <linux/slab.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/pgtable_64.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/pgtable_64.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/pgtable_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/pgtable_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/lmb.h>
+#include <linux/slab.h>
 
 #include <asm/pgalloc.h>
 #include <asm/page.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/pgtable.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/pgtable.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/pgtable.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/pgtable.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/percpu.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/subpage-prot.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/subpage-prot.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/subpage-prot.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/subpage-prot.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/gfp.h>
-#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/tlb_low_64e.S linux-libre-2.6.34-gnu1/arch/powerpc/mm/tlb_low_64e.S
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/tlb_low_64e.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/tlb_low_64e.S	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- *  Low leve TLB miss handlers for Book3E
+ *  Low level TLB miss handlers for Book3E
  *
  *  Copyright (C) 2008-2009
  *      Ben. Herrenschmidt (benh@kernel.crashing.org), IBM Corp.
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/mm/tlb_nohash.c linux-libre-2.6.34-gnu1/arch/powerpc/mm/tlb_nohash.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/mm/tlb_nohash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/mm/tlb_nohash.c	2010-05-16 17:17:36.000000000 -0400
@@ -150,7 +150,7 @@ EXPORT_SYMBOL(local_flush_tlb_page);
  */
 #ifdef CONFIG_SMP
 
-static DEFINE_SPINLOCK(tlbivax_lock);
+static DEFINE_RAW_SPINLOCK(tlbivax_lock);
 
 static int mm_is_core_local(struct mm_struct *mm)
 {
@@ -232,10 +232,10 @@ void __flush_tlb_page(struct mm_struct *
 		if (mmu_has_feature(MMU_FTR_USE_TLBIVAX_BCAST)) {
 			int lock = mmu_has_feature(MMU_FTR_LOCK_BCAST_INVAL);
 			if (lock)
-				spin_lock(&tlbivax_lock);
+				raw_spin_lock(&tlbivax_lock);
 			_tlbivax_bcast(vmaddr, pid, tsize, ind);
 			if (lock)
-				spin_unlock(&tlbivax_lock);
+				raw_spin_unlock(&tlbivax_lock);
 			goto bail;
 		} else {
 			struct tlb_flush_param p = {
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/oprofile/cell/spu_task_sync.c linux-libre-2.6.34-gnu1/arch/powerpc/oprofile/cell/spu_task_sync.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/oprofile/cell/spu_task_sync.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/oprofile/cell/spu_task_sync.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/notifier.h>
 #include <linux/numa.h>
 #include <linux/oprofile.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include "pr_util.h"
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/oprofile/cell/vma_map.c linux-libre-2.6.34-gnu1/arch/powerpc/oprofile/cell/vma_map.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/oprofile/cell/vma_map.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/oprofile/cell/vma_map.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/string.h>
 #include <linux/uaccess.h>
 #include <linux/elf.h>
+#include <linux/slab.h>
 #include "pr_util.h"
 
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/44x/warp.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/44x/warp.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/44x/warp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/44x/warp.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/delay.h>
 #include <linux/of_gpio.h>
 #include <linux/of_i2c.h>
+#include <linux/slab.h>
 
 #include <asm/machdep.h>
 #include <asm/prom.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/512x/clock.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/512x/clock.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/512x/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/512x/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -698,8 +698,7 @@ static struct clk_interface mpc5121_clk_
 	.clk_get_parent		= NULL,
 };
 
-static int
-mpc5121_clk_init(void)
+int __init mpc5121_clk_init(void)
 {
 	struct device_node *np;
 
@@ -724,6 +723,3 @@ mpc5121_clk_init(void)
 	clk_functions = mpc5121_clk_functions;
 	return 0;
 }
-
-
-arch_initcall(mpc5121_clk_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/512x/mpc5121_ads.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/512x/mpc5121_ads.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/512x/mpc5121_ads.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/512x/mpc5121_ads.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,8 +64,9 @@ define_machine(mpc5121_ads) {
 	.name			= "MPC5121 ADS",
 	.probe			= mpc5121_ads_probe,
 	.setup_arch		= mpc5121_ads_setup_arch,
-	.init			= mpc512x_declare_of_platform_devices,
+	.init			= mpc512x_init,
 	.init_IRQ		= mpc5121_ads_init_IRQ,
 	.get_irq		= ipic_get_irq,
 	.calibrate_decr		= generic_calibrate_decr,
+	.restart		= mpc512x_restart,
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c	2010-05-16 17:17:36.000000000 -0400
@@ -79,7 +79,7 @@ cpld_unmask_irq(unsigned int irq)
 }
 
 static struct irq_chip cpld_pic = {
-	.name = " CPLD PIC ",
+	.name = "CPLD PIC",
 	.mask = cpld_mask_irq,
 	.ack = cpld_mask_irq,
 	.unmask = cpld_unmask_irq,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/512x/mpc5121_generic.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/512x/mpc5121_generic.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/512x/mpc5121_generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/512x/mpc5121_generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,8 +51,9 @@ static int __init mpc5121_generic_probe(
 define_machine(mpc5121_generic) {
 	.name			= "MPC5121 generic",
 	.probe			= mpc5121_generic_probe,
-	.init			= mpc512x_declare_of_platform_devices,
+	.init			= mpc512x_init,
 	.init_IRQ		= mpc512x_init_IRQ,
 	.get_irq		= ipic_get_irq,
 	.calibrate_decr		= generic_calibrate_decr,
+	.restart		= mpc512x_restart,
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/512x/mpc512x.h linux-libre-2.6.34-gnu1/arch/powerpc/platforms/512x/mpc512x.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/512x/mpc512x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/512x/mpc512x.h	2010-05-16 17:17:36.000000000 -0400
@@ -12,5 +12,8 @@
 #ifndef __MPC512X_H__
 #define __MPC512X_H__
 extern void __init mpc512x_init_IRQ(void);
+extern void __init mpc512x_init(void);
+extern int __init mpc5121_clk_init(void);
 void __init mpc512x_declare_of_platform_devices(void);
+extern void mpc512x_restart(char *cmd);
 #endif				/* __MPC512X_H__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/512x/mpc512x_shared.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/512x/mpc512x_shared.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/512x/mpc512x_shared.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/512x/mpc512x_shared.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,9 +21,38 @@
 #include <asm/ipic.h>
 #include <asm/prom.h>
 #include <asm/time.h>
+#include <asm/mpc5121.h>
 
 #include "mpc512x.h"
 
+static struct mpc512x_reset_module __iomem *reset_module_base;
+
+static void __init mpc512x_restart_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-reset");
+	if (!np)
+		return;
+
+	reset_module_base = of_iomap(np, 0);
+	of_node_put(np);
+}
+
+void mpc512x_restart(char *cmd)
+{
+	if (reset_module_base) {
+		/* Enable software reset "RSTE" */
+		out_be32(&reset_module_base->rpr, 0x52535445);
+		/* Set software hard reset */
+		out_be32(&reset_module_base->rcr, 0x2);
+	} else {
+		pr_err("Restart module not mapped.\n");
+	}
+	for (;;)
+		;
+}
+
 void __init mpc512x_init_IRQ(void)
 {
 	struct device_node *np;
@@ -53,8 +82,22 @@ static struct of_device_id __initdata of
 
 void __init mpc512x_declare_of_platform_devices(void)
 {
+	struct device_node *np;
+
 	if (of_platform_bus_probe(NULL, of_bus_ids, NULL))
 		printk(KERN_ERR __FILE__ ": "
 			"Error while probing of_platform bus\n");
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-nfc");
+	if (np) {
+		of_platform_device_create(np, NULL, NULL);
+		of_node_put(np);
+	}
 }
 
+void __init mpc512x_init(void)
+{
+	mpc512x_declare_of_platform_devices();
+	mpc5121_clk_init();
+	mpc512x_restart_init();
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpio.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 
 #include <linux/of.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/of_gpio.h>
 #include <linux/io.h>
 #include <linux/of_platform.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpt.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpt.c	2010-05-16 17:17:36.000000000 -0400
@@ -62,6 +62,7 @@
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/watchdog.h>
 #include <linux/miscdevice.h>
 #include <linux/uaccess.h>
@@ -553,7 +554,7 @@ static ssize_t mpc52xx_wdt_write(struct
 	return 0;
 }
 
-static struct watchdog_info mpc5200_wdt_info = {
+static const struct watchdog_info mpc5200_wdt_info = {
 	.options	= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
 	.identity	= WDT_IDENTITY,
 };
@@ -711,7 +712,11 @@ static int __devinit mpc52xx_gpt_wdt_ini
 	return 0;
 }
 
-#define mpc52xx_gpt_wdt_setup(x, y)		(0)
+static inline int mpc52xx_gpt_wdt_setup(struct mpc52xx_gpt_priv *gpt,
+					const u32 *period)
+{
+	return 0;
+}
 
 #endif	/*  CONFIG_MPC5200_WDT	*/
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c	2010-05-16 17:17:36.000000000 -0400
@@ -481,6 +481,8 @@ mpc52xx_lpbfifo_probe(struct of_device *
 	if (rc)
 		goto err_bcom_rx_irq;
 
+	lpbfifo.dma_irqs_enabled = 1;
+
 	/* Request the Bestcomm transmit (memory --> fifo) task and IRQ */
 	lpbfifo.bcom_tx_task =
 		bcom_gen_bd_tx_init(2, res.start + LPBFIFO_REG_FIFO_DATA,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/82xx/ep8248e.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/82xx/ep8248e.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/82xx/ep8248e.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/82xx/ep8248e.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/fsl_devices.h>
 #include <linux/mdio-bitbang.h>
 #include <linux/of_mdio.h>
+#include <linux/slab.h>
 #include <linux/of_platform.h>
 
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/irq.h>
 #include <linux/types.h>
 #include <linux/bootmem.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
@@ -24,7 +25,7 @@
 
 #include "pq2.h"
 
-static DEFINE_SPINLOCK(pci_pic_lock);
+static DEFINE_RAW_SPINLOCK(pci_pic_lock);
 
 struct pq2ads_pci_pic {
 	struct device_node *node;
@@ -45,12 +46,12 @@ static void pq2ads_pci_mask_irq(unsigned
 
 	if (irq != -1) {
 		unsigned long flags;
-		spin_lock_irqsave(&pci_pic_lock, flags);
+		raw_spin_lock_irqsave(&pci_pic_lock, flags);
 
 		setbits32(&priv->regs->mask, 1 << irq);
 		mb();
 
-		spin_unlock_irqrestore(&pci_pic_lock, flags);
+		raw_spin_unlock_irqrestore(&pci_pic_lock, flags);
 	}
 }
 
@@ -62,9 +63,9 @@ static void pq2ads_pci_unmask_irq(unsign
 	if (irq != -1) {
 		unsigned long flags;
 
-		spin_lock_irqsave(&pci_pic_lock, flags);
+		raw_spin_lock_irqsave(&pci_pic_lock, flags);
 		clrbits32(&priv->regs->mask, 1 << irq);
-		spin_unlock_irqrestore(&pci_pic_lock, flags);
+		raw_spin_unlock_irqrestore(&pci_pic_lock, flags);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/gpio.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
+#include <linux/slab.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/Kconfig linux-libre-2.6.34-gnu1/arch/powerpc/platforms/85xx/Kconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/85xx/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -51,7 +51,7 @@ config MPC85xx_DS
 	bool "Freescale MPC85xx DS"
 	select PPC_I8259
 	select DEFAULT_UIMAGE
-	select FSL_ULI1575
+	select FSL_ULI1575 if PCI
 	select SWIOTLB
 	help
 	  This option enables support for the MPC85xx DS (MPC8544 DS) board
@@ -60,7 +60,7 @@ config MPC85xx_RDB
 	bool "Freescale MPC85xx RDB"
 	select PPC_I8259
 	select DEFAULT_UIMAGE
-	select FSL_ULI1575
+	select FSL_ULI1575 if PCI
 	select SWIOTLB
 	help
 	  This option enables support for the MPC85xx RDB (P2020 RDB) board
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/mpc85xx_mds.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/85xx/mpc85xx_mds.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/mpc85xx_mds.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/85xx/mpc85xx_mds.c	2010-05-16 17:17:36.000000000 -0400
@@ -237,6 +237,8 @@ static void __init mpc85xx_mds_setup_arc
 		} else if (machine_is(mpc8569_mds)) {
 #define BCSR7_UCC12_GETHnRST	(0x1 << 2)
 #define BCSR8_UEM_MARVELL_RST	(0x1 << 1)
+#define BCSR_UCC_RGMII		(0x1 << 6)
+#define BCSR_UCC_RTBI		(0x1 << 5)
 			/*
 			 * U-Boot mangles interrupt polarity for Marvell PHYs,
 			 * so reset built-in and UEM Marvell PHYs, this puts
@@ -247,6 +249,28 @@ static void __init mpc85xx_mds_setup_arc
 
 			setbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST);
 			clrbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST);
+
+			for (np = NULL; (np = of_find_compatible_node(np,
+							"network",
+							"ucc_geth")) != NULL;) {
+				const unsigned int *prop;
+				int ucc_num;
+
+				prop = of_get_property(np, "cell-index", NULL);
+				if (prop == NULL)
+					continue;
+
+				ucc_num = *prop - 1;
+
+				prop = of_get_property(np, "phy-connection-type", NULL);
+				if (prop == NULL)
+					continue;
+
+				if (strcmp("rtbi", (const char *)prop) == 0)
+					clrsetbits_8(&bcsr_regs[7 + ucc_num],
+						BCSR_UCC_RGMII, BCSR_UCC_RTBI);
+			}
+
 		}
 		iounmap(bcsr_regs);
 	}
@@ -302,11 +326,14 @@ static struct of_device_id mpc85xx_ids[]
 	{ .compatible = "gianfar", },
 	{ .compatible = "fsl,rapidio-delta", },
 	{ .compatible = "fsl,mpc8548-guts", },
+	{ .compatible = "gpio-leds", },
 	{},
 };
 
 static int __init mpc85xx_publish_devices(void)
 {
+	if (machine_is(mpc8568_mds))
+		simple_gpiochip_init("fsl,mpc8568mds-bcsr-gpio");
 	if (machine_is(mpc8569_mds))
 		simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio");
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,7 +50,7 @@ static struct socrates_fpga_irq_info fpg
 
 #define socrates_fpga_irq_to_hw(virq)    ((unsigned int)irq_map[virq].hwirq)
 
-static DEFINE_SPINLOCK(socrates_fpga_pic_lock);
+static DEFINE_RAW_SPINLOCK(socrates_fpga_pic_lock);
 
 static void __iomem *socrates_fpga_pic_iobase;
 static struct irq_host *socrates_fpga_pic_irq_host;
@@ -80,9 +80,9 @@ static inline unsigned int socrates_fpga
 	if (i == 3)
 		return NO_IRQ;
 
-	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	raw_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);
+	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 	for (i = SOCRATES_FPGA_NUM_IRQS - 1; i >= 0; i--) {
 		if (cause >> (i + 16))
 			break;
@@ -116,12 +116,12 @@ static void socrates_fpga_pic_ack(unsign
 	hwirq = socrates_fpga_irq_to_hw(virq);
 
 	irq_line = fpga_irqs[hwirq].irq_line;
-	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	raw_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);
+	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 }
 
 static void socrates_fpga_pic_mask(unsigned int virq)
@@ -134,12 +134,12 @@ static void socrates_fpga_pic_mask(unsig
 	hwirq = socrates_fpga_irq_to_hw(virq);
 
 	irq_line = fpga_irqs[hwirq].irq_line;
-	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	raw_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);
+	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 }
 
 static void socrates_fpga_pic_mask_ack(unsigned int virq)
@@ -152,13 +152,13 @@ static void socrates_fpga_pic_mask_ack(u
 	hwirq = socrates_fpga_irq_to_hw(virq);
 
 	irq_line = fpga_irqs[hwirq].irq_line;
-	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	raw_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);
+	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 }
 
 static void socrates_fpga_pic_unmask(unsigned int virq)
@@ -171,12 +171,12 @@ static void socrates_fpga_pic_unmask(uns
 	hwirq = socrates_fpga_irq_to_hw(virq);
 
 	irq_line = fpga_irqs[hwirq].irq_line;
-	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	raw_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);
+	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 }
 
 static void socrates_fpga_pic_eoi(unsigned int virq)
@@ -189,12 +189,12 @@ static void socrates_fpga_pic_eoi(unsign
 	hwirq = socrates_fpga_irq_to_hw(virq);
 
 	irq_line = fpga_irqs[hwirq].irq_line;
-	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	raw_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);
+	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 }
 
 static int socrates_fpga_pic_set_type(unsigned int virq,
@@ -220,19 +220,19 @@ static int socrates_fpga_pic_set_type(un
 	default:
 		return -EINVAL;
 	}
-	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	raw_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);
+	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 	return 0;
 }
 
 static struct irq_chip socrates_fpga_pic_chip = {
-	.name		= " FPGA-PIC ",
+	.name		= "FPGA-PIC",
 	.ack		= socrates_fpga_pic_ack,
 	.mask           = socrates_fpga_pic_mask,
 	.mask_ack       = socrates_fpga_pic_mask_ack,
@@ -314,14 +314,14 @@ void socrates_fpga_pic_init(struct devic
 
 	socrates_fpga_pic_iobase = of_iomap(pic, 0);
 
-	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	raw_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);
+	raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
 
 	pr_info("FPGA PIC: Setting up Socrates FPGA PIC\n");
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/stx_gp3.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/85xx/stx_gp3.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/stx_gp3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/85xx/stx_gp3.c	2010-05-16 17:17:36.000000000 -0400
@@ -134,7 +134,7 @@ static void stx_gp3_show_cpuinfo(struct
 	pvid = mfspr(SPRN_PVR);
 	svid = mfspr(SPRN_SVR);
 
-	seq_printf(m, "Vendor\t\t: RPC Electronics STx \n");
+	seq_printf(m, "Vendor\t\t: RPC Electronics STx\n");
 	seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
 	seq_printf(m, "SVR\t\t: 0x%x\n", svid);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/xes_mpc85xx.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/85xx/xes_mpc85xx.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/xes_mpc85xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/85xx/xes_mpc85xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -80,8 +80,8 @@ static void xes_mpc85xx_configure_l2(voi
 	printk(KERN_INFO "xes_mpc85xx: Enabling L2 as cache\n");
 
 	ctl = MPC85xx_L2CTL_L2E | MPC85xx_L2CTL_L2I;
-	if (machine_is_compatible("MPC8540") ||
-	    machine_is_compatible("MPC8560"))
+	if (of_machine_is_compatible("MPC8540") ||
+	    of_machine_is_compatible("MPC8560"))
 		/*
 		 * Assume L2 SRAM is used fully for cache, so set
 		 * L2BLKSZ (bits 4:5) to match L2SIZ (bits 2:3).
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_gpio.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/86xx/gef_gpio.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/86xx/gef_gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,9 +1,9 @@
 /*
- * Driver for GE Fanuc's FPGA based GPIO pins
+ * Driver for GE FPGA based GPIO
  *
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
  *
- * 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * 2008 (c) GE Intelligent Platforms Embedded Systems, 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
@@ -26,6 +26,7 @@
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #define GEF_GPIO_DIRECT		0x00
 #define GEF_GPIO_IN		0x04
@@ -164,6 +165,6 @@ static int __init gef_gpio_init(void)
 };
 arch_initcall(gef_gpio_init);
 
-MODULE_DESCRIPTION("GE Fanuc I/O FPGA GPIO driver");
-MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com");
+MODULE_DESCRIPTION("GE I/O FPGA GPIO driver");
+MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_pic.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/86xx/gef_pic.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_pic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/86xx/gef_pic.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,9 +1,9 @@
 /*
- * Interrupt handling for GE Fanuc's FPGA based PIC
+ * Interrupt handling for GE FPGA based PIC
  *
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
  *
- * 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * 2008 (c) GE Intelligent Platforms Embedded Systems, 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
@@ -49,7 +49,7 @@
 #define gef_irq_to_hw(virq)    ((unsigned int)irq_map[virq].hwirq)
 
 
-static DEFINE_SPINLOCK(gef_pic_lock);
+static DEFINE_RAW_SPINLOCK(gef_pic_lock);
 
 static void __iomem *gef_pic_irq_reg_base;
 static struct irq_host *gef_pic_irq_host;
@@ -118,11 +118,11 @@ static void gef_pic_mask(unsigned int vi
 
 	hwirq = gef_irq_to_hw(virq);
 
-	spin_lock_irqsave(&gef_pic_lock, flags);
+	raw_spin_lock_irqsave(&gef_pic_lock, flags);
 	mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
 	mask &= ~(1 << hwirq);
 	out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask);
-	spin_unlock_irqrestore(&gef_pic_lock, flags);
+	raw_spin_unlock_irqrestore(&gef_pic_lock, flags);
 }
 
 static void gef_pic_mask_ack(unsigned int virq)
@@ -141,11 +141,11 @@ static void gef_pic_unmask(unsigned int
 
 	hwirq = gef_irq_to_hw(virq);
 
-	spin_lock_irqsave(&gef_pic_lock, flags);
+	raw_spin_lock_irqsave(&gef_pic_lock, flags);
 	mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
 	mask |= (1 << hwirq);
 	out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask);
-	spin_unlock_irqrestore(&gef_pic_lock, flags);
+	raw_spin_unlock_irqrestore(&gef_pic_lock, flags);
 }
 
 static struct irq_chip gef_pic_chip = {
@@ -199,7 +199,7 @@ void __init gef_pic_init(struct device_n
 	/* Map the devices registers into memory */
 	gef_pic_irq_reg_base = of_iomap(np, 0);
 
-	spin_lock_irqsave(&gef_pic_lock, flags);
+	raw_spin_lock_irqsave(&gef_pic_lock, flags);
 
 	/* Initialise everything as masked. */
 	out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_INTR_MASK, 0);
@@ -208,7 +208,7 @@ void __init gef_pic_init(struct device_n
 	out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_MCP_MASK, 0);
 	out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_MCP_MASK, 0);
 
-	spin_unlock_irqrestore(&gef_pic_lock, flags);
+	raw_spin_unlock_irqrestore(&gef_pic_lock, flags);
 
 	/* Map controller */
 	gef_pic_cascade_irq = irq_of_parse_and_map(np, 0);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_ppc9a.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/86xx/gef_ppc9a.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_ppc9a.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/86xx/gef_ppc9a.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,9 +1,9 @@
 /*
- * GE Fanuc PPC9A board support
+ * GE PPC9A board support
  *
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
  *
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -82,7 +82,7 @@ static void __init gef_ppc9a_setup_arch(
 	}
 #endif
 
-	printk(KERN_INFO "GE Fanuc Intelligent Platforms PPC9A 6U VME SBC\n");
+	printk(KERN_INFO "GE Intelligent Platforms PPC9A 6U VME SBC\n");
 
 #ifdef CONFIG_SMP
 	mpc86xx_smp_init();
@@ -151,7 +151,7 @@ static void gef_ppc9a_show_cpuinfo(struc
 {
 	uint svid = mfspr(SPRN_SVR);
 
-	seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
+	seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n");
 
 	seq_printf(m, "Revision\t: %u%c\n", gef_ppc9a_get_pcb_rev(),
 		('A' + gef_ppc9a_get_board_rev()));
@@ -235,7 +235,7 @@ static int __init declare_of_platform_de
 machine_device_initcall(gef_ppc9a, declare_of_platform_devices);
 
 define_machine(gef_ppc9a) {
-	.name			= "GE Fanuc PPC9A",
+	.name			= "GE PPC9A",
 	.probe			= gef_ppc9a_probe,
 	.setup_arch		= gef_ppc9a_setup_arch,
 	.init_IRQ		= gef_ppc9a_init_irq,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_sbc310.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/86xx/gef_sbc310.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_sbc310.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/86xx/gef_sbc310.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,9 +1,9 @@
 /*
- * GE Fanuc SBC310 board support
+ * GE SBC310 board support
  *
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
  *
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -82,7 +82,7 @@ static void __init gef_sbc310_setup_arch
 	}
 #endif
 
-	printk(KERN_INFO "GE Fanuc Intelligent Platforms SBC310 6U VPX SBC\n");
+	printk(KERN_INFO "GE Intelligent Platforms SBC310 6U VPX SBC\n");
 
 #ifdef CONFIG_SMP
 	mpc86xx_smp_init();
@@ -142,7 +142,7 @@ static void gef_sbc310_show_cpuinfo(stru
 {
 	uint svid = mfspr(SPRN_SVR);
 
-	seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
+	seq_printf(m, "Vendor\t\t: GE 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(),
@@ -223,7 +223,7 @@ static int __init declare_of_platform_de
 machine_device_initcall(gef_sbc310, declare_of_platform_devices);
 
 define_machine(gef_sbc310) {
-	.name			= "GE Fanuc SBC310",
+	.name			= "GE SBC310",
 	.probe			= gef_sbc310_probe,
 	.setup_arch		= gef_sbc310_setup_arch,
 	.init_IRQ		= gef_sbc310_init_irq,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_sbc610.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/86xx/gef_sbc610.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_sbc610.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/86xx/gef_sbc610.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,9 +1,9 @@
 /*
- * GE Fanuc SBC610 board support
+ * GE SBC610 board support
  *
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
  *
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -82,7 +82,7 @@ static void __init gef_sbc610_setup_arch
 	}
 #endif
 
-	printk(KERN_INFO "GE Fanuc Intelligent Platforms SBC610 6U VPX SBC\n");
+	printk(KERN_INFO "GE Intelligent Platforms SBC610 6U VPX SBC\n");
 
 #ifdef CONFIG_SMP
 	mpc86xx_smp_init();
@@ -133,7 +133,7 @@ static void gef_sbc610_show_cpuinfo(stru
 {
 	uint svid = mfspr(SPRN_SVR);
 
-	seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
+	seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n");
 
 	seq_printf(m, "Revision\t: %u%c\n", gef_sbc610_get_pcb_rev(),
 		('A' + gef_sbc610_get_board_rev() - 1));
@@ -212,7 +212,7 @@ static int __init declare_of_platform_de
 machine_device_initcall(gef_sbc610, declare_of_platform_devices);
 
 define_machine(gef_sbc610) {
-	.name			= "GE Fanuc SBC610",
+	.name			= "GE SBC610",
 	.probe			= gef_sbc610_probe,
 	.setup_arch		= gef_sbc610_setup_arch,
 	.init_IRQ		= gef_sbc610_init_irq,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/Kconfig linux-libre-2.6.34-gnu1/arch/powerpc/platforms/86xx/Kconfig
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/86xx/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,7 @@ config MPC8641_HPCN
 	bool "Freescale MPC8641 HPCN"
 	select PPC_I8259
 	select DEFAULT_UIMAGE
-	select FSL_ULI1575
+	select FSL_ULI1575 if PCI
 	select HAS_RAPIDIO
 	select SWIOTLB
 	help
@@ -28,37 +28,37 @@ config SBC8641D
 config MPC8610_HPCD
 	bool "Freescale MPC8610 HPCD"
 	select DEFAULT_UIMAGE
-	select FSL_ULI1575
+	select FSL_ULI1575 if PCI
 	help
 	  This option enables support for the MPC8610 HPCD board.
 
 config GEF_PPC9A
-	bool "GE Fanuc PPC9A"
+	bool "GE PPC9A"
 	select DEFAULT_UIMAGE
 	select MMIO_NVRAM
 	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
 	help
-	  This option enables support for GE Fanuc's PPC9A.
+	  This option enables support for the GE PPC9A.
 
 config GEF_SBC310
-	bool "GE Fanuc SBC310"
+	bool "GE SBC310"
 	select DEFAULT_UIMAGE
 	select MMIO_NVRAM
 	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
 	help
-	  This option enables support for GE Fanuc's SBC310.
+	  This option enables support for the GE SBC310.
 
 config GEF_SBC610
-	bool "GE Fanuc SBC610"
+	bool "GE SBC610"
 	select DEFAULT_UIMAGE
 	select MMIO_NVRAM
 	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
 	select HAS_RAPIDIO
 	help
-	  This option enables support for GE Fanuc's SBC610.
+	  This option enables support for the GE SBC610.
 
 endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/8xx/m8xx_setup.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/8xx/m8xx_setup.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/8xx/m8xx_setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/8xx/m8xx_setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/time.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/axon_msi.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/axon_msi.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/axon_msi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/axon_msi.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/msi.h>
 #include <linux/of_platform.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 #include <asm/dcr.h>
 #include <asm/machdep.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/beat_htab.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/beat_htab.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/beat_htab.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/beat_htab.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,7 +40,7 @@
 #define DBG_LOW(fmt...) do { } while (0)
 #endif
 
-static DEFINE_SPINLOCK(beat_htab_lock);
+static DEFINE_RAW_SPINLOCK(beat_htab_lock);
 
 static inline unsigned int beat_read_mask(unsigned hpte_group)
 {
@@ -114,18 +114,18 @@ static long beat_lpar_hpte_insert(unsign
 	if (rflags & _PAGE_NO_CACHE)
 		hpte_r &= ~_PAGE_COHERENT;
 
-	spin_lock(&beat_htab_lock);
+	raw_spin_lock(&beat_htab_lock);
 	lpar_rc = beat_read_mask(hpte_group);
 	if (lpar_rc == 0) {
 		if (!(vflags & HPTE_V_BOLTED))
 			DBG_LOW(" full\n");
-		spin_unlock(&beat_htab_lock);
+		raw_spin_unlock(&beat_htab_lock);
 		return -1;
 	}
 
 	lpar_rc = beat_insert_htab_entry(0, hpte_group, lpar_rc << 48,
 		hpte_v, hpte_r, &slot);
-	spin_unlock(&beat_htab_lock);
+	raw_spin_unlock(&beat_htab_lock);
 
 	/*
 	 * Since we try and ioremap PHBs we don't own, the pte insert
@@ -198,17 +198,17 @@ static long beat_lpar_hpte_updatepp(unsi
 		"avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ",
 		want_v & HPTE_V_AVPN, slot, psize, newpp);
 
-	spin_lock(&beat_htab_lock);
+	raw_spin_lock(&beat_htab_lock);
 	dummy0 = beat_lpar_hpte_getword0(slot);
 	if ((dummy0 & ~0x7FUL) != (want_v & ~0x7FUL)) {
 		DBG_LOW("not found !\n");
-		spin_unlock(&beat_htab_lock);
+		raw_spin_unlock(&beat_htab_lock);
 		return -1;
 	}
 
 	lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7, &dummy0,
 					&dummy1);
-	spin_unlock(&beat_htab_lock);
+	raw_spin_unlock(&beat_htab_lock);
 	if (lpar_rc != 0 || dummy0 == 0) {
 		DBG_LOW("not found !\n");
 		return -1;
@@ -262,13 +262,13 @@ static void beat_lpar_hpte_updateboltedp
 	vsid = get_kernel_vsid(ea, MMU_SEGSIZE_256M);
 	va = (vsid << 28) | (ea & 0x0fffffff);
 
-	spin_lock(&beat_htab_lock);
+	raw_spin_lock(&beat_htab_lock);
 	slot = beat_lpar_hpte_find(va, psize);
 	BUG_ON(slot == -1);
 
 	lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7,
 		&dummy0, &dummy1);
-	spin_unlock(&beat_htab_lock);
+	raw_spin_unlock(&beat_htab_lock);
 
 	BUG_ON(lpar_rc != 0);
 }
@@ -285,18 +285,18 @@ static void beat_lpar_hpte_invalidate(un
 		slot, va, psize, local);
 	want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M);
 
-	spin_lock_irqsave(&beat_htab_lock, flags);
+	raw_spin_lock_irqsave(&beat_htab_lock, flags);
 	dummy1 = beat_lpar_hpte_getword0(slot);
 
 	if ((dummy1 & ~0x7FUL) != (want_v & ~0x7FUL)) {
 		DBG_LOW("not found !\n");
-		spin_unlock_irqrestore(&beat_htab_lock, flags);
+		raw_spin_unlock_irqrestore(&beat_htab_lock, flags);
 		return;
 	}
 
 	lpar_rc = beat_write_htab_entry(0, slot, 0, 0, HPTE_V_VALID, 0,
 		&dummy1, &dummy2);
-	spin_unlock_irqrestore(&beat_htab_lock, flags);
+	raw_spin_unlock_irqrestore(&beat_htab_lock, flags);
 
 	BUG_ON(lpar_rc != 0);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/beat_interrupt.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/beat_interrupt.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/beat_interrupt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/beat_interrupt.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,7 @@
 #include "beat_wrapper.h"
 
 #define	MAX_IRQS	NR_IRQS
-static DEFINE_SPINLOCK(beatic_irq_mask_lock);
+static DEFINE_RAW_SPINLOCK(beatic_irq_mask_lock);
 static uint64_t	beatic_irq_mask_enable[(MAX_IRQS+255)/64];
 static uint64_t	beatic_irq_mask_ack[(MAX_IRQS+255)/64];
 
@@ -65,30 +65,30 @@ static void beatic_mask_irq(unsigned int
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&beatic_irq_mask_lock, flags);
+	raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
 	beatic_irq_mask_enable[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64)));
 	beatic_update_irq_mask(irq_plug);
-	spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
+	raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
 }
 
 static void beatic_unmask_irq(unsigned int irq_plug)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&beatic_irq_mask_lock, flags);
+	raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
 	beatic_irq_mask_enable[irq_plug/64] |= 1UL << (63 - (irq_plug%64));
 	beatic_update_irq_mask(irq_plug);
-	spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
+	raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
 }
 
 static void beatic_ack_irq(unsigned int irq_plug)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&beatic_irq_mask_lock, flags);
+	raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
 	beatic_irq_mask_ack[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64)));
 	beatic_update_irq_mask(irq_plug);
-	spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
+	raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
 }
 
 static void beatic_end_irq(unsigned int irq_plug)
@@ -103,14 +103,14 @@ static void beatic_end_irq(unsigned int
 
 		printk(KERN_ERR "IRQ over-downcounted, plug %d\n", irq_plug);
 	}
-	spin_lock_irqsave(&beatic_irq_mask_lock, flags);
+	raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
 	beatic_irq_mask_ack[irq_plug/64] |= 1UL << (63 - (irq_plug%64));
 	beatic_update_irq_mask(irq_plug);
-	spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
+	raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
 }
 
 static struct irq_chip beatic_pic = {
-	.name = " CELL-BEAT ",
+	.name = "CELL-BEAT",
 	.unmask = beatic_unmask_irq,
 	.mask = beatic_mask_irq,
 	.eoi = beatic_end_irq,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/cbe_powerbutton.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/cbe_powerbutton.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/cbe_powerbutton.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/cbe_powerbutton.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,7 +48,7 @@ static int __init cbe_powerbutton_init(v
 	int ret = 0;
 	struct input_dev *dev;
 
-	if (!machine_is_compatible("IBM,CBPLUS-1.0")) {
+	if (!of_machine_is_compatible("IBM,CBPLUS-1.0")) {
 		printk(KERN_ERR "%s: Not a cell blade.\n", __func__);
 		ret = -ENODEV;
 		goto out;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/celleb_pci.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/celleb_pci.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/celleb_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/celleb_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/pci_regs.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/celleb_scc_pciex.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/celleb_scc_pciex.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/celleb_scc_pciex.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/celleb_scc_pciex.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/interrupt.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/interrupt.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/interrupt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/interrupt.c	2010-05-16 17:17:36.000000000 -0400
@@ -88,7 +88,7 @@ static void iic_eoi(unsigned int irq)
 }
 
 static struct irq_chip iic_chip = {
-	.name = " CELL-IIC ",
+	.name = "CELL-IIC",
 	.mask = iic_mask,
 	.unmask = iic_unmask,
 	.eoi = iic_eoi,
@@ -133,7 +133,7 @@ static void iic_ioexc_cascade(unsigned i
 
 
 static struct irq_chip iic_ioexc_chip = {
-	.name = " CELL-IOEX",
+	.name = "CELL-IOEX",
 	.mask = iic_mask,
 	.unmask = iic_unmask,
 	.eoi = iic_ioexc_eoi,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/iommu.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/iommu.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/iommu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/iommu.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/notifier.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 #include <linux/lmb.h>
 
 #include <asm/prom.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/ras.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/ras.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/ras.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/ras.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/reboot.h>
 #include <linux/kexec.h>
@@ -255,7 +256,7 @@ static int __init cbe_sysreset_init(void
 {
 	struct cbe_pmd_regs __iomem *regs;
 
-	sysreset_hack = machine_is_compatible("IBM,CBPLUS-1.0");
+	sysreset_hack = of_machine_is_compatible("IBM,CBPLUS-1.0");
 	if (!sysreset_hack)
 		return 0;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/setup.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/setup.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/mm.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spider-pci.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spider-pci.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spider-pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spider-pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/kernel.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 
 #include <asm/ppc-pci.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spider-pic.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spider-pic.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spider-pic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spider-pic.c	2010-05-16 17:17:36.000000000 -0400
@@ -168,7 +168,7 @@ static int spider_set_irq_type(unsigned
 }
 
 static struct irq_chip spider_pic = {
-	.name = " SPIDER   ",
+	.name = "SPIDER",
 	.unmask = spider_unmask_irq,
 	.mask = spider_mask_irq,
 	.ack = spider_ack_irq,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/coredump.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spufs/coredump.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/coredump.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spufs/coredump.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/file.h>
 #include <linux/fdtable.h>
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/syscalls.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/file.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spufs/file.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/file.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spufs/file.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/poll.h>
 #include <linux/ptrace.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/time.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include <asm/spu.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/sched.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spufs/sched.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/sched.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spufs/sched.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/vmalloc.h>
 #include <linux/smp.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/syscalls.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spufs/syscalls.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/syscalls.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spufs/syscalls.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
 #include <linux/module.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spu_manage.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spu_manage.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spu_manage.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spu_manage.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/mm.h>
 #include <linux/io.h>
@@ -457,7 +456,7 @@ neighbour_spu(int cbe, struct device_nod
 			continue;
 		vic_handles = of_get_property(spu_dn, "vicinity", &lenp);
 		for (i=0; i < (lenp / sizeof(phandle)); i++) {
-			if (vic_handles[i] == target->linux_phandle)
+			if (vic_handles[i] == target->phandle)
 				return spu;
 		}
 	}
@@ -499,7 +498,7 @@ static void init_affinity_node(int cbe)
 
 			if (strcmp(name, "spe") == 0) {
 				spu = devnode_spu(cbe, vic_dn);
-				avoid_ph = last_spu_dn->linux_phandle;
+				avoid_ph = last_spu_dn->phandle;
 			} else {
 				/*
 				 * "mic-tm" and "bif0" nodes do not have
@@ -514,7 +513,7 @@ static void init_affinity_node(int cbe)
 					last_spu->has_mem_affinity = 1;
 					spu->has_mem_affinity = 1;
 				}
-				avoid_ph = vic_dn->linux_phandle;
+				avoid_ph = vic_dn->phandle;
 			}
 
 			list_add_tail(&spu->aff_list, &last_spu->aff_list);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spu_priv1_mmio.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spu_priv1_mmio.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spu_priv1_mmio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/cell/spu_priv1_mmio.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/mm.h>
 #include <linux/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/chrp/nvram.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/chrp/nvram.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/chrp/nvram.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/chrp/nvram.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <asm/uaccess.h>
 #include <asm/prom.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/chrp/setup.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/chrp/setup.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/chrp/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/chrp/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/tty.h>
 #include <linux/major.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/fsl_uli1575.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/fsl_uli1575.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/fsl_uli1575.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/fsl_uli1575.c	2010-05-16 17:17:36.000000000 -0400
@@ -222,6 +222,7 @@ static void __devinit quirk_final_uli524
 	int i;
 	u8 *dummy;
 	struct pci_bus *bus = dev->bus;
+	struct resource *res;
 	resource_size_t end = 0;
 
 	for (i = PCI_BRIDGE_RESOURCES; i < PCI_BRIDGE_RESOURCES+3; i++) {
@@ -230,13 +231,12 @@ static void __devinit quirk_final_uli524
 			end = pci_resource_end(dev, i);
 	}
 
-	for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
-		if ((bus->resource[i]) &&
-			(bus->resource[i]->flags & IORESOURCE_MEM)) {
-			if (bus->resource[i]->end == end)
-				dummy = ioremap(bus->resource[i]->start, 0x4);
+	pci_bus_for_each_resource(bus, res, i) {
+		if (res && res->flags & IORESOURCE_MEM) {
+			if (res->end == end)
+				dummy = ioremap(res->start, 0x4);
 			else
-				dummy = ioremap(bus->resource[i]->end - 3, 0x4);
+				dummy = ioremap(res->end - 3, 0x4);
 			if (dummy) {
 				in_8(dummy);
 				iounmap(dummy);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/exception.S linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/exception.S
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/exception.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/exception.S	2010-05-16 17:17:36.000000000 -0400
@@ -43,17 +43,14 @@ system_reset_iSeries:
 	LOAD_REG_ADDR(r23, alpaca)
 	li	r0,ALPACA_SIZE
 	sub	r23,r13,r23
-	divdu	r23,r23,r0		/* r23 has cpu number */
-	LOAD_REG_ADDR(r13, paca)
-	mulli	r0,r23,PACA_SIZE
-	add	r13,r13,r0
-	mtspr	SPRN_SPRG_PACA,r13	/* Save it away for the future */
-	mfmsr	r24
-	ori	r24,r24,MSR_RI
-	mtmsrd	r24			/* RI on */
-	mr	r24,r23
+	divdu	r24,r23,r0		/* r24 has cpu number */
 	cmpwi	0,r24,0			/* Are we processor 0? */
 	bne	1f
+	LOAD_REG_ADDR(r13, boot_paca)
+	mtspr	SPRN_SPRG_PACA,r13	/* Save it away for the future */
+	mfmsr	r23
+	ori	r23,r23,MSR_RI
+	mtmsrd	r23			/* RI on */
 	b	.__start_initialization_iSeries	/* Start up the first processor */
 1:	mfspr	r4,SPRN_CTRLF
 	li	r5,CTRL_RUNLATCH	/* Turn off the run light */
@@ -86,6 +83,16 @@ system_reset_iSeries:
 #endif
 
 2:
+	/* Load our paca now that it's been allocated */
+	LOAD_REG_ADDR(r13, paca)
+	ld	r13,0(r13)
+	mulli	r0,r24,PACA_SIZE
+	add	r13,r13,r0
+	mtspr	SPRN_SPRG_PACA,r13	/* Save it away for the future */
+	mfmsr	r23
+	ori	r23,r23,MSR_RI
+	mtmsrd	r23			/* RI on */
+
 	HMT_LOW
 #ifdef CONFIG_SMP
 	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/iommu.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/iommu.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/iommu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/iommu.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/list.h>
 #include <linux/pci.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <asm/iommu.h>
 #include <asm/vio.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/irq.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/irq.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -273,7 +273,7 @@ static void iseries_end_IRQ(unsigned int
 }
 
 static struct irq_chip iseries_pic = {
-	.name	= "iSeries irq controller",
+	.name		= "iSeries",
 	.startup	= iseries_startup_IRQ,
 	.shutdown	= iseries_shutdown_IRQ,
 	.unmask		= iseries_enable_IRQ,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/mf.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/mf.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/mf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/mf.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/bcd.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 
 #include <asm/time.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/pci.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/pci.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pci.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/proc.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/proc.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -85,7 +85,7 @@ static int proc_titantod_show(struct seq
 
 		seq_printf(m, "  titan elapsed = %lu uSec\n", titan_usec);
 		seq_printf(m, "  tb elapsed    = %lu ticks\n", tb_ticks);
-		seq_printf(m, "  titan jiffies = %lu.%04lu \n", titan_jiffies,
+		seq_printf(m, "  titan jiffies = %lu.%04lu\n", titan_jiffies,
 			   titan_jiff_rem_usec);
 		seq_printf(m, "  tb jiffies    = %lu.%04lu\n", tb_jiffies,
 			   tb_jiff_rem_usec);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/setup.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/setup.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -256,7 +256,7 @@ static unsigned long iSeries_process_mai
 		mem_blocks = iSeries_process_Condor_mainstore_vpd(mb_array,
 				max_entries);
 
-	printk("Mainstore_VPD: numMemoryBlocks = %ld \n", mem_blocks);
+	printk("Mainstore_VPD: numMemoryBlocks = %ld\n", mem_blocks);
 	for (i = 0; i < mem_blocks; ++i) {
 		printk("Mainstore_VPD: block %3ld logical chunks %016lx - %016lx\n"
 		       "                             abs chunks %016lx - %016lx\n",
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/vio.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/vio.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/vio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/vio.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,7 @@
  */
 #include <linux/of.h>
 #include <linux/init.h>
-#include <linux/gfp.h>
+#include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/proc_fs.h>
 #include <linux/module.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/viopath.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/viopath.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/viopath.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/iseries/viopath.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
  */
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/vmalloc.h>
 #include <linux/string.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/Kconfig.cputype linux-libre-2.6.34-gnu1/arch/powerpc/platforms/Kconfig.cputype
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/Kconfig.cputype	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/Kconfig.cputype	2010-05-16 17:17:36.000000000 -0400
@@ -144,6 +144,16 @@ config FSL_EMB_PERFMON
 	  and some e300 cores (c3 and c4).  Select this only if your
 	  core supports the Embedded Performance Monitor APU
 
+config FSL_EMB_PERF_EVENT
+	bool
+	depends on FSL_EMB_PERFMON && PERF_EVENTS && !PPC_PERF_CTRS
+	default y
+
+config FSL_EMB_PERF_EVENT_E500
+	bool
+	depends on FSL_EMB_PERF_EVENT && E500
+	default y
+
 config 4xx
 	bool
 	depends on 40x || 44x
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/maple/setup.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/maple/setup.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/maple/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/maple/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/tty.h>
 #include <linux/string.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pasemi/cpufreq.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pasemi/cpufreq.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pasemi/cpufreq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pasemi/cpufreq.c	2010-05-16 17:17:36.000000000 -0400
@@ -304,8 +304,8 @@ static struct cpufreq_driver pas_cpufreq
 
 static int __init pas_cpufreq_init(void)
 {
-	if (!machine_is_compatible("PA6T-1682M") &&
-	    !machine_is_compatible("pasemi,pwrficient"))
+	if (!of_machine_is_compatible("PA6T-1682M") &&
+	    !of_machine_is_compatible("pasemi,pwrficient"))
 		return -ENODEV;
 
 	return cpufreq_register_driver(&pas_cpufreq_driver);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pasemi/dma_lib.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pasemi/dma_lib.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pasemi/dma_lib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pasemi/dma_lib.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/of.h>
 
 #include <asm/pasemi_dma.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pasemi/gpio_mdio.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pasemi/gpio_mdio.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pasemi/gpio_mdio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pasemi/gpio_mdio.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pasemi/setup.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pasemi/setup.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pasemi/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pasemi/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/console.h>
 #include <linux/pci.h>
 #include <linux/of_platform.h>
+#include <linux/gfp.h>
 
 #include <asm/prom.h>
 #include <asm/system.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/bootx_init.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/bootx_init.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/bootx_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/bootx_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -539,7 +539,7 @@ void __init bootx_init(unsigned long r3,
 		if (model
 		    && (strcmp(model, "iMac,1") == 0
 			|| strcmp(model, "PowerMac1,1") == 0)) {
-			bootx_printf("iMac,1 detected, shutting down USB \n");
+			bootx_printf("iMac,1 detected, shutting down USB\n");
 			out_le32((unsigned __iomem *)0x80880008, 1);	/* XXX */
 		}
 	}
@@ -554,7 +554,7 @@ void __init bootx_init(unsigned long r3,
 	} else
 		space = bi->totalParamsSize;
 
-	bootx_printf("Total space used by parameters & ramdisk: 0x%x \n", space);
+	bootx_printf("Total space used by parameters & ramdisk: 0x%x\n", space);
 
 	/* New BootX will have flushed all TLBs and enters kernel with
 	 * MMU switched OFF, so this should not be useful anymore.
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/cpufreq_32.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/cpufreq_32.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/cpufreq_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/cpufreq_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@
 #include <linux/sched.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
-#include <linux/slab.h>
 #include <linux/cpufreq.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
@@ -657,31 +656,31 @@ static int __init pmac_cpufreq_setup(voi
 	cur_freq = (*value) / 1000;
 
 	/*  Check for 7447A based MacRISC3 */
-	if (machine_is_compatible("MacRISC3") &&
+	if (of_machine_is_compatible("MacRISC3") &&
 	    of_get_property(cpunode, "dynamic-power-step", NULL) &&
 	    PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {
 		pmac_cpufreq_init_7447A(cpunode);
 	/* Check for other MacRISC3 machines */
-	} else if (machine_is_compatible("PowerBook3,4") ||
-		   machine_is_compatible("PowerBook3,5") ||
-		   machine_is_compatible("MacRISC3")) {
+	} else if (of_machine_is_compatible("PowerBook3,4") ||
+		   of_machine_is_compatible("PowerBook3,5") ||
+		   of_machine_is_compatible("MacRISC3")) {
 		pmac_cpufreq_init_MacRISC3(cpunode);
 	/* Else check for iBook2 500/600 */
-	} else if (machine_is_compatible("PowerBook4,1")) {
+	} else if (of_machine_is_compatible("PowerBook4,1")) {
 		hi_freq = cur_freq;
 		low_freq = 400000;
 		set_speed_proc = pmu_set_cpu_speed;
 		is_pmu_based = 1;
 	}
 	/* Else check for TiPb 550 */
-	else if (machine_is_compatible("PowerBook3,3") && cur_freq == 550000) {
+	else if (of_machine_is_compatible("PowerBook3,3") && cur_freq == 550000) {
 		hi_freq = cur_freq;
 		low_freq = 500000;
 		set_speed_proc = pmu_set_cpu_speed;
 		is_pmu_based = 1;
 	}
 	/* Else check for TiPb 400 & 500 */
-	else if (machine_is_compatible("PowerBook3,2")) {
+	else if (of_machine_is_compatible("PowerBook3,2")) {
 		/* We only know about the 400 MHz and the 500Mhz model
 		 * they both have 300 MHz as low frequency
 		 */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/cpufreq_64.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/cpufreq_64.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/cpufreq_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/cpufreq_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/cpufreq.h>
 #include <linux/init.h>
 #include <linux/completion.h>
@@ -398,11 +397,11 @@ static int __init g5_neo2_cpufreq_init(s
 	int rc = -ENODEV;
 
 	/* Check supported platforms */
-	if (machine_is_compatible("PowerMac8,1") ||
-	    machine_is_compatible("PowerMac8,2") ||
-	    machine_is_compatible("PowerMac9,1"))
+	if (of_machine_is_compatible("PowerMac8,1") ||
+	    of_machine_is_compatible("PowerMac8,2") ||
+	    of_machine_is_compatible("PowerMac9,1"))
 		use_volts_smu = 1;
-	else if (machine_is_compatible("PowerMac11,2"))
+	else if (of_machine_is_compatible("PowerMac11,2"))
 		use_volts_vdnap = 1;
 	else
 		return -ENODEV;
@@ -729,9 +728,9 @@ static int __init g5_cpufreq_init(void)
 		return -ENODEV;
 	}
 
-	if (machine_is_compatible("PowerMac7,2") ||
-	    machine_is_compatible("PowerMac7,3") ||
-	    machine_is_compatible("RackMac3,1"))
+	if (of_machine_is_compatible("PowerMac7,2") ||
+	    of_machine_is_compatible("PowerMac7,3") ||
+	    of_machine_is_compatible("RackMac3,1"))
 		rc = g5_pm72_cpufreq_init(cpus);
 #ifdef CONFIG_PMAC_SMU
 	else
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/feature.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/feature.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/feature.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/feature.c	2010-05-16 17:17:36.000000000 -0400
@@ -59,10 +59,10 @@ extern struct device_node *k2_skiplist[2
  * We use a single global lock to protect accesses. Each driver has
  * to take care of its own locking
  */
-DEFINE_SPINLOCK(feature_lock);
+DEFINE_RAW_SPINLOCK(feature_lock);
 
-#define LOCK(flags)	spin_lock_irqsave(&feature_lock, flags);
-#define UNLOCK(flags)	spin_unlock_irqrestore(&feature_lock, flags);
+#define LOCK(flags)	raw_spin_lock_irqsave(&feature_lock, flags);
+#define UNLOCK(flags)	raw_spin_unlock_irqrestore(&feature_lock, flags);
 
 
 /*
@@ -2426,7 +2426,7 @@ static int __init probe_motherboard(void
 	    }
 	}
 	for(i=0; i<ARRAY_SIZE(pmac_mb_defs); i++) {
-	    if (machine_is_compatible(pmac_mb_defs[i].model_string)) {
+	    if (of_machine_is_compatible(pmac_mb_defs[i].model_string)) {
 		pmac_mb = pmac_mb_defs[i];
 		goto found;
 	    }
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/low_i2c.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/low_i2c.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/low_i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/low_i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,7 @@
 #include <linux/timer.h>
 #include <linux/mutex.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <asm/keylargo.h>
 #include <asm/uninorth.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/nvram.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/nvram.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/nvram.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/nvram.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
 #include <linux/string.h>
 #include <linux/nvram.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/adb.h>
@@ -80,7 +79,7 @@ static int is_core_99;
 static int core99_bank = 0;
 static int nvram_partitions[3];
 // XXX Turn that into a sem
-static DEFINE_SPINLOCK(nv_lock);
+static DEFINE_RAW_SPINLOCK(nv_lock);
 
 static int (*core99_write_bank)(int bank, u8* datas);
 static int (*core99_erase_bank)(int bank);
@@ -165,10 +164,10 @@ static unsigned char indirect_nvram_read
 	unsigned char val;
 	unsigned long flags;
 
-	spin_lock_irqsave(&nv_lock, flags);
+	raw_spin_lock_irqsave(&nv_lock, flags);
 	out_8(nvram_addr, addr >> 5);
 	val = in_8(&nvram_data[(addr & 0x1f) << 4]);
-	spin_unlock_irqrestore(&nv_lock, flags);
+	raw_spin_unlock_irqrestore(&nv_lock, flags);
 
 	return val;
 }
@@ -177,10 +176,10 @@ static void indirect_nvram_write_byte(in
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&nv_lock, flags);
+	raw_spin_lock_irqsave(&nv_lock, flags);
 	out_8(nvram_addr, addr >> 5);
 	out_8(&nvram_data[(addr & 0x1f) << 4], val);
-	spin_unlock_irqrestore(&nv_lock, flags);
+	raw_spin_unlock_irqrestore(&nv_lock, flags);
 }
 
 
@@ -481,7 +480,7 @@ static void core99_nvram_sync(void)
 	if (!is_core_99 || !nvram_data || !nvram_image)
 		return;
 
-	spin_lock_irqsave(&nv_lock, flags);
+	raw_spin_lock_irqsave(&nv_lock, flags);
 	if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
 		NVRAM_SIZE))
 		goto bail;
@@ -503,7 +502,7 @@ static void core99_nvram_sync(void)
 		if (core99_write_bank(core99_bank, nvram_image))
 			printk("nvram: Error writing bank %d\n", core99_bank);
  bail:
-	spin_unlock_irqrestore(&nv_lock, flags);
+	raw_spin_unlock_irqrestore(&nv_lock, flags);
 
 #ifdef DEBUG
        	mdelay(2000);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/pfunc_base.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/pfunc_base.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/pfunc_base.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/pfunc_base.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,13 +50,13 @@ static int macio_do_gpio_write(PMF_STD_A
 		value = ~value;
 
 	/* Toggle the GPIO */
-	spin_lock_irqsave(&feature_lock, flags);
+	raw_spin_lock_irqsave(&feature_lock, flags);
 	tmp = readb(addr);
 	tmp = (tmp & ~mask) | (value & mask);
 	DBG("Do write 0x%02x to GPIO %s (%p)\n",
 	    tmp, func->node->full_name, addr);
 	writeb(tmp, addr);
-	spin_unlock_irqrestore(&feature_lock, flags);
+	raw_spin_unlock_irqrestore(&feature_lock, flags);
 
 	return 0;
 }
@@ -145,9 +145,9 @@ static int macio_do_write_reg32(PMF_STD_
 	struct macio_chip *macio = func->driver_data;
 	unsigned long flags;
 
-	spin_lock_irqsave(&feature_lock, flags);
+	raw_spin_lock_irqsave(&feature_lock, flags);
 	MACIO_OUT32(offset, (MACIO_IN32(offset) & ~mask) | (value & mask));
-	spin_unlock_irqrestore(&feature_lock, flags);
+	raw_spin_unlock_irqrestore(&feature_lock, flags);
 	return 0;
 }
 
@@ -168,9 +168,9 @@ static int macio_do_write_reg8(PMF_STD_A
 	struct macio_chip *macio = func->driver_data;
 	unsigned long flags;
 
-	spin_lock_irqsave(&feature_lock, flags);
+	raw_spin_lock_irqsave(&feature_lock, flags);
 	MACIO_OUT8(offset, (MACIO_IN8(offset) & ~mask) | (value & mask));
-	spin_unlock_irqrestore(&feature_lock, flags);
+	raw_spin_unlock_irqrestore(&feature_lock, flags);
 	return 0;
 }
 
@@ -223,12 +223,12 @@ static int macio_do_write_reg32_slm(PMF_
 	if (args == NULL || args->count == 0)
 		return -EINVAL;
 
-	spin_lock_irqsave(&feature_lock, flags);
+	raw_spin_lock_irqsave(&feature_lock, flags);
 	tmp = MACIO_IN32(offset);
 	val = args->u[0].v << shift;
 	tmp = (tmp & ~mask) | (val & mask);
 	MACIO_OUT32(offset, tmp);
-	spin_unlock_irqrestore(&feature_lock, flags);
+	raw_spin_unlock_irqrestore(&feature_lock, flags);
 	return 0;
 }
 
@@ -243,12 +243,12 @@ static int macio_do_write_reg8_slm(PMF_S
 	if (args == NULL || args->count == 0)
 		return -EINVAL;
 
-	spin_lock_irqsave(&feature_lock, flags);
+	raw_spin_lock_irqsave(&feature_lock, flags);
 	tmp = MACIO_IN8(offset);
 	val = args->u[0].v << shift;
 	tmp = (tmp & ~mask) | (val & mask);
 	MACIO_OUT8(offset, tmp);
-	spin_unlock_irqrestore(&feature_lock, flags);
+	raw_spin_unlock_irqrestore(&feature_lock, flags);
 	return 0;
 }
 
@@ -278,12 +278,12 @@ static int unin_do_write_reg32(PMF_STD_A
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&feature_lock, flags);
+	raw_spin_lock_irqsave(&feature_lock, flags);
 	/* This is fairly bogus in darwin, but it should work for our needs
 	 * implemeted that way:
 	 */
 	UN_OUT(offset, (UN_IN(offset) & ~mask) | (value & mask));
-	spin_unlock_irqrestore(&feature_lock, flags);
+	raw_spin_unlock_irqrestore(&feature_lock, flags);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/pfunc_core.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/pfunc_core.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/pfunc_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/pfunc_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 
@@ -842,7 +843,7 @@ struct pmf_function *__pmf_find_function
 	list_for_each_entry(func, &dev->functions, link) {
 		if (name && strcmp(name, func->name))
 			continue;
-		if (func->phandle && target->node != func->phandle)
+		if (func->phandle && target->phandle != func->phandle)
 			continue;
 		if ((func->flags & flags) == 0)
 			continue;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/pic.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/pic.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/pic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/pic.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,7 +57,7 @@ static int max_irqs;
 static int max_real_irqs;
 static u32 level_mask[4];
 
-static DEFINE_SPINLOCK(pmac_pic_lock);
+static DEFINE_RAW_SPINLOCK(pmac_pic_lock);
 
 #define NR_MASK_WORDS	((NR_IRQS + 31) / 32)
 static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
@@ -85,7 +85,7 @@ static void pmac_mask_and_ack_irq(unsign
         int i = src >> 5;
         unsigned long flags;
 
-	spin_lock_irqsave(&pmac_pic_lock, flags);
+	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
         __clear_bit(src, ppc_cached_irq_mask);
         if (__test_and_clear_bit(src, ppc_lost_interrupts))
                 atomic_dec(&ppc_n_lost_interrupts);
@@ -97,7 +97,7 @@ static void pmac_mask_and_ack_irq(unsign
                 mb();
         } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
                 != (ppc_cached_irq_mask[i] & bit));
-	spin_unlock_irqrestore(&pmac_pic_lock, flags);
+	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 }
 
 static void pmac_ack_irq(unsigned int virq)
@@ -107,12 +107,12 @@ static void pmac_ack_irq(unsigned int vi
         int i = src >> 5;
         unsigned long flags;
 
-  	spin_lock_irqsave(&pmac_pic_lock, flags);
+	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
 	if (__test_and_clear_bit(src, ppc_lost_interrupts))
                 atomic_dec(&ppc_n_lost_interrupts);
         out_le32(&pmac_irq_hw[i]->ack, bit);
         (void)in_le32(&pmac_irq_hw[i]->ack);
-	spin_unlock_irqrestore(&pmac_pic_lock, flags);
+	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 }
 
 static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
@@ -152,12 +152,12 @@ static unsigned int pmac_startup_irq(uns
         unsigned long bit = 1UL << (src & 0x1f);
         int i = src >> 5;
 
-	spin_lock_irqsave(&pmac_pic_lock, flags);
+	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
 	if ((irq_to_desc(virq)->status & IRQ_LEVEL) == 0)
 		out_le32(&pmac_irq_hw[i]->ack, bit);
         __set_bit(src, ppc_cached_irq_mask);
         __pmac_set_irq_mask(src, 0);
-	spin_unlock_irqrestore(&pmac_pic_lock, flags);
+	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 
 	return 0;
 }
@@ -167,10 +167,10 @@ static void pmac_mask_irq(unsigned int v
 	unsigned long flags;
 	unsigned int src = irq_map[virq].hwirq;
 
-  	spin_lock_irqsave(&pmac_pic_lock, flags);
+	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
         __clear_bit(src, ppc_cached_irq_mask);
         __pmac_set_irq_mask(src, 1);
-  	spin_unlock_irqrestore(&pmac_pic_lock, flags);
+	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 }
 
 static void pmac_unmask_irq(unsigned int virq)
@@ -178,24 +178,24 @@ static void pmac_unmask_irq(unsigned int
 	unsigned long flags;
 	unsigned int src = irq_map[virq].hwirq;
 
-	spin_lock_irqsave(&pmac_pic_lock, flags);
+	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
 	__set_bit(src, ppc_cached_irq_mask);
         __pmac_set_irq_mask(src, 0);
-  	spin_unlock_irqrestore(&pmac_pic_lock, flags);
+	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 }
 
 static int pmac_retrigger(unsigned int virq)
 {
 	unsigned long flags;
 
-  	spin_lock_irqsave(&pmac_pic_lock, flags);
+	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
 	__pmac_retrigger(irq_map[virq].hwirq);
-  	spin_unlock_irqrestore(&pmac_pic_lock, flags);
+	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 	return 1;
 }
 
 static struct irq_chip pmac_pic = {
-	.name		= " PMAC-PIC ",
+	.name		= "PMAC-PIC",
 	.startup	= pmac_startup_irq,
 	.mask		= pmac_mask_irq,
 	.ack		= pmac_ack_irq,
@@ -210,7 +210,7 @@ static irqreturn_t gatwick_action(int cp
 	int irq, bits;
 	int rc = IRQ_NONE;
 
-  	spin_lock_irqsave(&pmac_pic_lock, flags);
+	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
 	for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) {
 		int i = irq >> 5;
 		bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
@@ -220,12 +220,12 @@ static irqreturn_t gatwick_action(int cp
 		if (bits == 0)
 			continue;
 		irq += __ilog2(bits);
-		spin_unlock_irqrestore(&pmac_pic_lock, flags);
+		raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 		generic_handle_irq(irq);
-		spin_lock_irqsave(&pmac_pic_lock, flags);
+		raw_spin_lock_irqsave(&pmac_pic_lock, flags);
 		rc = IRQ_HANDLED;
 	}
-  	spin_unlock_irqrestore(&pmac_pic_lock, flags);
+	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 	return rc;
 }
 
@@ -244,7 +244,7 @@ static unsigned int pmac_pic_get_irq(voi
 		return NO_IRQ_IGNORE;	/* ignore, already handled */
         }
 #endif /* CONFIG_SMP */
-  	spin_lock_irqsave(&pmac_pic_lock, flags);
+	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
 	for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
 		int i = irq >> 5;
 		bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
@@ -256,7 +256,7 @@ static unsigned int pmac_pic_get_irq(voi
 		irq += __ilog2(bits);
 		break;
 	}
-  	spin_unlock_irqrestore(&pmac_pic_lock, flags);
+	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 	if (unlikely(irq < 0))
 		return NO_IRQ;
 	return irq_linear_revmap(pmac_pic_host, irq);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/setup.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/setup.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/tty.h>
 #include <linux/string.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/smp.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/smp.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/smp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -693,9 +693,9 @@ static void __init smp_core99_setup(int
 #ifdef CONFIG_PPC64
 
 	/* i2c based HW sync on some G5s */
-	if (machine_is_compatible("PowerMac7,2") ||
-	    machine_is_compatible("PowerMac7,3") ||
-	    machine_is_compatible("RackMac3,1"))
+	if (of_machine_is_compatible("PowerMac7,2") ||
+	    of_machine_is_compatible("PowerMac7,3") ||
+	    of_machine_is_compatible("RackMac3,1"))
 		smp_core99_setup_i2c_hwsync(ncpus);
 
 	/* pfunc based HW sync on recent G5s */
@@ -713,7 +713,7 @@ static void __init smp_core99_setup(int
 #else /* CONFIG_PPC64 */
 
 	/* GPIO based HW sync on ppc32 Core99 */
-	if (pmac_tb_freeze == NULL && !machine_is_compatible("MacRISC4")) {
+	if (pmac_tb_freeze == NULL && !of_machine_is_compatible("MacRISC4")) {
 		struct device_node *cpu;
 		const u32 *tbprop = NULL;
 
@@ -750,7 +750,7 @@ static void __init smp_core99_setup(int
 #endif
 
 	/* 32 bits SMP can't NAP */
-	if (!machine_is_compatible("MacRISC4"))
+	if (!of_machine_is_compatible("MacRISC4"))
 		powersave_nap = 0;
 }
 
@@ -852,7 +852,7 @@ static void __devinit smp_core99_setup_c
 		/* If we didn't start the second CPU, we must take
 		 * it off the bus
 		 */
-		if (machine_is_compatible("MacRISC4") &&
+		if (of_machine_is_compatible("MacRISC4") &&
 		    num_online_cpus() < 2)		
 			g5_phy_disable_cpu1();
 #endif /* CONFIG_PPC64 */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/time.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/time.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -317,9 +317,9 @@ void __init pmac_calibrate_decr(void)
 	 * calibration. That's better since the VIA itself seems
 	 * to be slightly off. --BenH
 	 */
-	if (!machine_is_compatible("MacRISC2") &&
-	    !machine_is_compatible("MacRISC3") &&
-	    !machine_is_compatible("MacRISC4"))
+	if (!of_machine_is_compatible("MacRISC2") &&
+	    !of_machine_is_compatible("MacRISC3") &&
+	    !of_machine_is_compatible("MacRISC4"))
 		if (via_calibrate_decr())
 			return;
 
@@ -328,7 +328,7 @@ void __init pmac_calibrate_decr(void)
 	 * probably implement calibration based on the KL timer on these
 	 * machines anyway... -BenH
 	 */
-	if (machine_is_compatible("PowerMac3,5"))
+	if (of_machine_is_compatible("PowerMac3,5"))
 		if (via_calibrate_decr())
 			return;
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/udbg_scc.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/udbg_scc.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/udbg_scc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/powermac/udbg_scc.c	2010-05-16 17:17:36.000000000 -0400
@@ -132,9 +132,9 @@ void udbg_scc_init(int force_scc)
 		scc_inittab[1] = in_8(sccc);
 		out_8(sccc, 12);
 		scc_inittab[3] = in_8(sccc);
-	} else if (machine_is_compatible("RackMac1,1")
-		   || machine_is_compatible("RackMac1,2")
-		   || machine_is_compatible("MacRISC4")) {
+	} else if (of_machine_is_compatible("RackMac1,1")
+		   || of_machine_is_compatible("RackMac1,2")
+		   || of_machine_is_compatible("MacRISC4")) {
 		/* Xserves and G5s default to 57600 */
 		scc_inittab[1] = 0;
 		scc_inittab[3] = 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/ps3/device-init.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/ps3/device-init.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/ps3/device-init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/ps3/device-init.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/kthread.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/reboot.h>
 
 #include <asm/firmware.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/ps3/mm.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/ps3/mm.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/ps3/mm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/ps3/mm.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/memory_hotplug.h>
 #include <linux/lmb.h>
+#include <linux/slab.h>
 
 #include <asm/cell-regs.h>
 #include <asm/firmware.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/ps3/os-area.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/ps3/os-area.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/ps3/os-area.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/ps3/os-area.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/ctype.h>
 #include <linux/lmb.h>
 #include <linux/of.h>
+#include <linux/slab.h>
 
 #include <asm/prom.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/ps3/spu.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/ps3/spu.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/ps3/spu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/ps3/spu.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/mmzone.h>
 #include <linux/io.h>
 #include <linux/mm.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/ps3/system-bus.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/ps3/system-bus.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/ps3/system-bus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/ps3/system-bus.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <asm/udbg.h>
 #include <asm/lv1call.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/cmm.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/cmm.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/cmm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/cmm.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/kthread.h>
 #include <linux/module.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/dlpar.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/dlpar.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/dlpar.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/dlpar.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
 #include <linux/cpu.h>
+#include <linux/slab.h>
 #include "offline_states.h"
 
 #include <asm/prom.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/dtl.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/dtl.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/dtl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/dtl.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/debugfs.h>
 #include <asm/smp.h>
 #include <asm/system.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/eeh.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/eeh.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/eeh.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/eeh.c	2010-05-16 17:17:36.000000000 -0400
@@ -100,7 +100,7 @@ int eeh_subsystem_enabled;
 EXPORT_SYMBOL(eeh_subsystem_enabled);
 
 /* Lock to avoid races due to multiple reports of an error */
-static DEFINE_SPINLOCK(confirm_error_lock);
+static DEFINE_RAW_SPINLOCK(confirm_error_lock);
 
 /* Buffer for reporting slot-error-detail rtas calls. Its here
  * in BSS, and not dynamically alloced, so that it ends up in
@@ -436,7 +436,7 @@ static void __eeh_clear_slot(struct devi
 void eeh_clear_slot (struct device_node *dn, int mode_flag)
 {
 	unsigned long flags;
-	spin_lock_irqsave(&confirm_error_lock, flags);
+	raw_spin_lock_irqsave(&confirm_error_lock, flags);
 	
 	dn = find_device_pe (dn);
 	
@@ -447,7 +447,7 @@ void eeh_clear_slot (struct device_node
 	PCI_DN(dn)->eeh_mode &= ~mode_flag;
 	PCI_DN(dn)->eeh_check_count = 0;
 	__eeh_clear_slot(dn, mode_flag);
-	spin_unlock_irqrestore(&confirm_error_lock, flags);
+	raw_spin_unlock_irqrestore(&confirm_error_lock, flags);
 }
 
 /**
@@ -491,7 +491,7 @@ int eeh_dn_check_failure(struct device_n
 	    pdn->eeh_mode & EEH_MODE_NOCHECK) {
 		ignored_check++;
 		pr_debug("EEH: Ignored check (%x) for %s %s\n",
-			 pdn->eeh_mode, pci_name (dev), dn->full_name);
+			 pdn->eeh_mode, eeh_pci_name(dev), dn->full_name);
 		return 0;
 	}
 
@@ -506,7 +506,7 @@ int eeh_dn_check_failure(struct device_n
 	 * in one slot might report errors simultaneously, and we
 	 * only want one error recovery routine running.
 	 */
-	spin_lock_irqsave(&confirm_error_lock, flags);
+	raw_spin_lock_irqsave(&confirm_error_lock, flags);
 	rc = 1;
 	if (pdn->eeh_mode & EEH_MODE_ISOLATED) {
 		pdn->eeh_check_count ++;
@@ -515,7 +515,7 @@ int eeh_dn_check_failure(struct device_n
 			printk (KERN_ERR "EEH: %d reads ignored for recovering device at "
 				"location=%s driver=%s pci addr=%s\n",
 				pdn->eeh_check_count, location,
-				dev->driver->name, pci_name(dev));
+				dev->driver->name, eeh_pci_name(dev));
 			printk (KERN_ERR "EEH: Might be infinite loop in %s driver\n",
 				dev->driver->name);
 			dump_stack();
@@ -575,7 +575,7 @@ int eeh_dn_check_failure(struct device_n
 	 * with other functions on this device, and functions under
 	 * bridges. */
 	eeh_mark_slot (dn, EEH_MODE_ISOLATED);
-	spin_unlock_irqrestore(&confirm_error_lock, flags);
+	raw_spin_unlock_irqrestore(&confirm_error_lock, flags);
 
 	eeh_send_failure_event (dn, dev);
 
@@ -586,7 +586,7 @@ int eeh_dn_check_failure(struct device_n
 	return 1;
 
 dn_unlock:
-	spin_unlock_irqrestore(&confirm_error_lock, flags);
+	raw_spin_unlock_irqrestore(&confirm_error_lock, flags);
 	return rc;
 }
 
@@ -1064,7 +1064,7 @@ void __init eeh_init(void)
 	struct device_node *phb, *np;
 	struct eeh_early_enable_info info;
 
-	spin_lock_init(&confirm_error_lock);
+	raw_spin_lock_init(&confirm_error_lock);
 	spin_lock_init(&slot_errbuf_lock);
 
 	np = of_find_node_by_path("/rtas");
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/eeh_cache.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/eeh_cache.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/eeh_cache.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/eeh_cache.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/list.h>
 #include <linux/pci.h>
 #include <linux/rbtree.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <asm/atomic.h>
 #include <asm/pci-bridge.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/eeh_driver.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/eeh_driver.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/eeh_driver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/eeh_driver.c	2010-05-16 17:17:36.000000000 -0400
@@ -337,7 +337,7 @@ struct pci_dn * handle_eeh_events (struc
 		location = location ? location : "unknown";
 		printk(KERN_ERR "EEH: Error: Cannot find partition endpoint "
 		                "for location=%s pci addr=%s\n",
-		        location, pci_name(event->dev));
+		        location, eeh_pci_name(event->dev));
 		return NULL;
 	}
 
@@ -368,7 +368,7 @@ struct pci_dn * handle_eeh_events (struc
 		pci_str = pci_name (frozen_pdn->pcidev);
 		drv_str = pcid_name (frozen_pdn->pcidev);
 	} else {
-		pci_str = pci_name (event->dev);
+		pci_str = eeh_pci_name(event->dev);
 		drv_str = pcid_name (event->dev);
 	}
 	
@@ -478,9 +478,9 @@ excess_failures:
 	 * due to actual, failed cards.
 	 */
 	printk(KERN_ERR
-	   "EEH: PCI device at location=%s driver=%s pci addr=%s \n"
+	   "EEH: PCI device at location=%s driver=%s pci addr=%s\n"
 		"has failed %d times in the last hour "
-		"and has been permanently disabled. \n"
+		"and has been permanently disabled.\n"
 		"Please try reseating this device or replacing it.\n",
 		location, drv_str, pci_str, frozen_pdn->eeh_freeze_count);
 	goto perm_error;
@@ -488,7 +488,7 @@ excess_failures:
 hard_fail:
 	printk(KERN_ERR
 	   "EEH: Unable to recover from failure of PCI device "
-	   "at location=%s driver=%s pci addr=%s \n"
+	   "at location=%s driver=%s pci addr=%s\n"
 	   "Please try reseating this device or replacing it.\n",
 		location, drv_str, pci_str);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/eeh_event.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/eeh_event.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/eeh_event.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/eeh_event.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <asm/eeh_event.h>
 #include <asm/ppc-pci.h>
@@ -80,7 +81,7 @@ static int eeh_event_handler(void * dumm
 	eeh_mark_slot(event->dn, EEH_MODE_RECOVERING);
 
 	printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
-	       pci_name(event->dev));
+	       eeh_pci_name(event->dev));
 
 	pdn = handle_eeh_events(event);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/hotplug-cpu.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/hotplug-cpu.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/hotplug-cpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/hotplug-cpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -122,44 +122,32 @@ static void pseries_mach_cpu_die(void)
 		if (!get_lppaca()->shared_proc)
 			get_lppaca()->donate_dedicated_cpu = 1;
 
-		printk(KERN_INFO
-			"cpu %u (hwid %u) ceding for offline with hint %d\n",
-			cpu, hwcpu, cede_latency_hint);
 		while (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
 			extended_cede_processor(cede_latency_hint);
-			printk(KERN_INFO "cpu %u (hwid %u) returned from cede.\n",
-				cpu, hwcpu);
-			printk(KERN_INFO
-			"Decrementer value = %x Timebase value = %llx\n",
-			get_dec(), get_tb());
 		}
 
-		printk(KERN_INFO "cpu %u (hwid %u) got prodded to go online\n",
-			cpu, hwcpu);
-
 		if (!get_lppaca()->shared_proc)
 			get_lppaca()->donate_dedicated_cpu = 0;
 		get_lppaca()->idle = 0;
-	}
 
-	if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
-		unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
+		if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
+			unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
 
-		/*
-		 * NOTE: Calling start_secondary() here for now to
-		 * start new context.
-		 * However, need to do it cleanly by resetting the
-		 * stack pointer.
-		 */
-		start_secondary();
+			/*
+			 * Call to start_secondary_resume() will not return.
+			 * Kernel stack will be reset and start_secondary()
+			 * will be called to continue the online operation.
+			 */
+			start_secondary_resume();
+		}
+	}
 
-	} else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
+	/* Requested state is CPU_STATE_OFFLINE at this point */
+	WARN_ON(get_preferred_offline_state(cpu) != CPU_STATE_OFFLINE);
 
-		set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
-		unregister_slb_shadow(hard_smp_processor_id(),
-					__pa(get_slb_shadow()));
-		rtas_stop_self();
-	}
+	set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
+	unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
+	rtas_stop_self();
 
 	/* Should never get here... */
 	BUG();
@@ -387,24 +375,12 @@ static char cede_parameters[CEDE_LATENCY
 
 static int parse_cede_parameters(void)
 {
-	int call_status;
-
 	memset(cede_parameters, 0, CEDE_LATENCY_PARAM_MAX_LENGTH);
-	call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
-				NULL,
-				CEDE_LATENCY_TOKEN,
-				__pa(cede_parameters),
-				CEDE_LATENCY_PARAM_MAX_LENGTH);
-
-	if (call_status != 0)
-		printk(KERN_INFO "CEDE_LATENCY: \
-			%s %s Error calling get-system-parameter(0x%x)\n",
-			__FILE__, __func__, call_status);
-	else
-		printk(KERN_INFO "CEDE_LATENCY: \
-			get-system-parameter successful.\n");
-
-	return call_status;
+	return rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
+			 NULL,
+			 CEDE_LATENCY_TOKEN,
+			 __pa(cede_parameters),
+			 CEDE_LATENCY_PARAM_MAX_LENGTH);
 }
 
 static int __init pseries_cpu_hotplug_init(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/hotplug-memory.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/hotplug-memory.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/hotplug-memory.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/hotplug-memory.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <linux/of.h>
 #include <linux/lmb.h>
+#include <linux/vmalloc.h>
 #include <asm/firmware.h>
 #include <asm/machdep.h>
 #include <asm/pSeries_reconfig.h>
@@ -54,6 +55,12 @@ static int pseries_remove_lmb(unsigned l
 	 */
 	start = (unsigned long)__va(base);
 	ret = remove_section_mapping(start, start + lmb_size);
+
+	/* Ensure all vmalloc mappings are flushed in case they also
+	 * hit that section of memory
+	 */
+	vm_unmap_aliases();
+
 	return ret;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/hvCall_inst.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/hvCall_inst.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/hvCall_inst.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/hvCall_inst.c	2010-05-16 17:17:36.000000000 -0400
@@ -124,8 +124,8 @@ static void probe_hcall_exit(unsigned lo
 
 	h = &__get_cpu_var(hcall_stats)[opcode / 4];
 	h->num_calls++;
-	h->tb_total = mftb() - h->tb_start;
-	h->purr_total = mfspr(SPRN_PURR) - h->purr_start;
+	h->tb_total += mftb() - h->tb_start;
+	h->purr_total += mfspr(SPRN_PURR) - h->purr_start;
 
 	put_cpu_var(hcall_stats);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/nvram.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/nvram.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/nvram.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/nvram.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <asm/uaccess.h>
 #include <asm/nvram.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/offline_states.h linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/offline_states.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/offline_states.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/offline_states.h	2010-05-16 17:17:36.000000000 -0400
@@ -9,10 +9,31 @@ enum cpu_state_vals {
 	CPU_MAX_OFFLINE_STATES
 };
 
+#ifdef CONFIG_HOTPLUG_CPU
 extern enum cpu_state_vals get_cpu_current_state(int cpu);
 extern void set_cpu_current_state(int cpu, enum cpu_state_vals state);
-extern enum cpu_state_vals get_preferred_offline_state(int cpu);
 extern void set_preferred_offline_state(int cpu, enum cpu_state_vals state);
 extern void set_default_offline_state(int cpu);
+#else
+static inline enum cpu_state_vals get_cpu_current_state(int cpu)
+{
+	return CPU_STATE_ONLINE;
+}
+
+static inline void set_cpu_current_state(int cpu, enum cpu_state_vals state)
+{
+}
+
+static inline void set_preferred_offline_state(int cpu, enum cpu_state_vals state)
+{
+}
+
+static inline void set_default_offline_state(int cpu)
+{
+}
+#endif
+
+extern enum cpu_state_vals get_preferred_offline_state(int cpu);
 extern int start_secondary(void);
+extern void start_secondary_resume(void);
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/pci_dlpar.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/pci_dlpar.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/pci_dlpar.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/pci_dlpar.c	2010-05-16 17:17:36.000000000 -0400
@@ -165,7 +165,7 @@ int remove_phb_dynamic(struct pci_contro
 	struct resource *res;
 	int rc, i;
 
-	pr_debug("PCI: Removing PHB %04x:%02x... \n",
+	pr_debug("PCI: Removing PHB %04x:%02x...\n",
 		 pci_domain_nr(b), b->number);
 
 	/* We cannot to remove a root bus that has children */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/phyp_dump.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/phyp_dump.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/phyp_dump.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/phyp_dump.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
  *
  */
 
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/kobject.h>
 #include <linux/mm.h>
@@ -150,7 +151,7 @@ static void print_dump_header(const stru
 	printk(KERN_INFO "Max auto time= %d\n", ph->maxtime_to_auto);
 
 	/*set cpu state and hpte states as well scratch pad area */
-	printk(KERN_INFO " CPU AREA \n");
+	printk(KERN_INFO " CPU AREA\n");
 	printk(KERN_INFO "cpu dump_flags =%d\n", ph->cpu_data.dump_flags);
 	printk(KERN_INFO "cpu source_type =%d\n", ph->cpu_data.source_type);
 	printk(KERN_INFO "cpu error_flags =%d\n", ph->cpu_data.error_flags);
@@ -161,7 +162,7 @@ static void print_dump_header(const stru
 	printk(KERN_INFO "cpu length_copied =%llx\n",
 		ph->cpu_data.length_copied);
 
-	printk(KERN_INFO " HPTE AREA \n");
+	printk(KERN_INFO " HPTE AREA\n");
 	printk(KERN_INFO "HPTE dump_flags =%d\n", ph->hpte_data.dump_flags);
 	printk(KERN_INFO "HPTE source_type =%d\n", ph->hpte_data.source_type);
 	printk(KERN_INFO "HPTE error_flags =%d\n", ph->hpte_data.error_flags);
@@ -172,7 +173,7 @@ static void print_dump_header(const stru
 	printk(KERN_INFO "HPTE length_copied =%llx\n",
 		ph->hpte_data.length_copied);
 
-	printk(KERN_INFO " SRSD AREA \n");
+	printk(KERN_INFO " SRSD AREA\n");
 	printk(KERN_INFO "SRSD dump_flags =%d\n", ph->kernel_data.dump_flags);
 	printk(KERN_INFO "SRSD source_type =%d\n", ph->kernel_data.source_type);
 	printk(KERN_INFO "SRSD error_flags =%d\n", ph->kernel_data.error_flags);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h	2010-05-16 17:17:36.000000000 -0400
@@ -259,12 +259,12 @@ static inline long plpar_ipi(unsigned lo
 	return plpar_hcall_norets(H_IPI, servernum, mfrr);
 }
 
-static inline long plpar_xirr(unsigned long *xirr_ret)
+static inline long plpar_xirr(unsigned long *xirr_ret, unsigned char cppr)
 {
 	long rc;
 	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
 
-	rc = plpar_hcall(H_XIRR, retbuf);
+	rc = plpar_hcall(H_XIRR, retbuf, cppr);
 
 	*xirr_ret = retbuf[0];
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/ras.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/ras.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/ras.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/ras.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,6 @@
 #include <linux/interrupt.h>
 #include <linux/timex.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/random.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/reconfig.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/reconfig.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/reconfig.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/reconfig.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/kref.h>
 #include <linux/notifier.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 
 #include <asm/prom.h>
 #include <asm/machdep.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/scanlog.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/scanlog.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/scanlog.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/scanlog.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/rtas.h>
 #include <asm/prom.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/setup.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/setup.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/mm.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/tty.h>
 #include <linux/major.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/smp.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/smp.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/smp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -144,8 +144,8 @@ static void __devinit smp_pSeries_kick_c
 		hcpuid = get_hard_smp_processor_id(nr);
 		rc = plpar_hcall_norets(H_PROD, hcpuid);
 		if (rc != H_SUCCESS)
-			printk(KERN_ERR "Error: Prod to wake up processor %d\
-						Ret= %ld\n", nr, rc);
+			printk(KERN_ERR "Error: Prod to wake up processor %d "
+						"Ret= %ld\n", nr, rc);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/xics.c linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/xics.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/xics.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/xics.c	2010-05-16 17:17:36.000000000 -0400
@@ -120,14 +120,14 @@ static inline void direct_qirr_info(int
 
 /* LPAR low level accessors */
 
-static inline unsigned int lpar_xirr_info_get(void)
+static inline unsigned int lpar_xirr_info_get(unsigned char cppr)
 {
 	unsigned long lpar_rc;
 	unsigned long return_value;
 
-	lpar_rc = plpar_xirr(&return_value);
+	lpar_rc = plpar_xirr(&return_value, cppr);
 	if (lpar_rc != H_SUCCESS)
-		panic(" bad return code xirr - rc = %lx \n", lpar_rc);
+		panic(" bad return code xirr - rc = %lx\n", lpar_rc);
 	return (unsigned int)return_value;
 }
 
@@ -331,7 +331,8 @@ static unsigned int xics_get_irq_direct(
 
 static unsigned int xics_get_irq_lpar(void)
 {
-	unsigned int xirr = lpar_xirr_info_get();
+	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
+	unsigned int xirr = lpar_xirr_info_get(os_cppr->stack[os_cppr->index]);
 	unsigned int vec = xics_xirr_vector(xirr);
 	unsigned int irq;
 
@@ -424,7 +425,7 @@ static int xics_set_affinity(unsigned in
 }
 
 static struct irq_chip xics_pic_direct = {
-	.name = " XICS     ",
+	.name = "XICS",
 	.startup = xics_startup,
 	.mask = xics_mask_irq,
 	.unmask = xics_unmask_irq,
@@ -433,7 +434,7 @@ static struct irq_chip xics_pic_direct =
 };
 
 static struct irq_chip xics_pic_lpar = {
-	.name = " XICS     ",
+	.name = "XICS",
 	.startup = xics_startup,
 	.mask = xics_mask_irq,
 	.unmask = xics_unmask_irq,
@@ -510,15 +511,13 @@ static void __init xics_init_host(void)
 /*
  * XICS only has a single IPI, so encode the messages per CPU
  */
-struct xics_ipi_struct {
-        unsigned long value;
-	} ____cacheline_aligned;
-
-static struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
+static DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message);
 
 static inline void smp_xics_do_message(int cpu, int msg)
 {
-	set_bit(msg, &xics_ipi_message[cpu].value);
+	unsigned long *tgt = &per_cpu(xics_ipi_message, cpu);
+
+	set_bit(msg, tgt);
 	mb();
 	if (firmware_has_feature(FW_FEATURE_LPAR))
 		lpar_qirr_info(cpu, IPI_PRIORITY);
@@ -544,25 +543,23 @@ void smp_xics_message_pass(int target, i
 
 static irqreturn_t xics_ipi_dispatch(int cpu)
 {
+	unsigned long *tgt = &per_cpu(xics_ipi_message, cpu);
+
 	WARN_ON(cpu_is_offline(cpu));
 
 	mb();	/* order mmio clearing qirr */
-	while (xics_ipi_message[cpu].value) {
-		if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION,
-				       &xics_ipi_message[cpu].value)) {
+	while (*tgt) {
+		if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, tgt)) {
 			smp_message_recv(PPC_MSG_CALL_FUNCTION);
 		}
-		if (test_and_clear_bit(PPC_MSG_RESCHEDULE,
-				       &xics_ipi_message[cpu].value)) {
+		if (test_and_clear_bit(PPC_MSG_RESCHEDULE, tgt)) {
 			smp_message_recv(PPC_MSG_RESCHEDULE);
 		}
-		if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE,
-				       &xics_ipi_message[cpu].value)) {
+		if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, tgt)) {
 			smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE);
 		}
 #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
-		if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK,
-				       &xics_ipi_message[cpu].value)) {
+		if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, tgt)) {
 			smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
 		}
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm1.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/cpm1.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/cpm1.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/8xx_immap.h>
@@ -77,7 +78,7 @@ static void cpm_end_irq(unsigned int irq
 }
 
 static struct irq_chip cpm_pic = {
-	.name = " CPM PIC ",
+	.name = "CPM PIC",
 	.mask = cpm_mask_irq,
 	.unmask = cpm_unmask_irq,
 	.eoi = cpm_end_irq,
@@ -485,9 +486,6 @@ int cpm1_clk_setup(enum cpm_clk_target t
 		return -EINVAL;
 	}
 
-	if (reg == &mpc8xx_immr->im_cpm.cp_sicr && mode == CPM_CLK_RX)
-		shift += 3;
-
 	for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
 		if (clk_map[i][0] == target && clk_map[i][1] == clock) {
 			bits = clk_map[i][2];
@@ -502,6 +500,17 @@ int cpm1_clk_setup(enum cpm_clk_target t
 
 	bits <<= shift;
 	mask <<= shift;
+
+	if (reg == &mpc8xx_immr->im_cpm.cp_sicr) {
+		if (mode == CPM_CLK_RTX) {
+			bits |= bits << 3;
+			mask |= mask << 3;
+		} else if (mode == CPM_CLK_RX) {
+			bits <<= 3;
+			mask <<= 3;
+		}
+	}
+
 	out_be32(reg, (in_be32(reg) & ~mask) | bits);
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm2.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/cpm2.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/cpm2.c	2010-05-16 17:17:36.000000000 -0400
@@ -244,9 +244,6 @@ int cpm2_clk_setup(enum cpm_clk_target t
 		return -EINVAL;
 	}
 
-	if (mode == CPM_CLK_RX)
-		shift += 3;
-
 	for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
 		if (clk_map[i][0] == target && clk_map[i][1] == clock) {
 			bits = clk_map[i][2];
@@ -259,6 +256,14 @@ int cpm2_clk_setup(enum cpm_clk_target t
 	bits <<= shift;
 	mask <<= shift;
 
+	if (mode == CPM_CLK_RTX) {
+		bits |= bits << 3;
+		mask |= mask << 3;
+	} else if (mode == CPM_CLK_RX) {
+		bits <<= 3;
+		mask <<= 3;
+	}
+
 	out_be32(reg, (in_be32(reg) & ~mask) | bits);
 
 	cpm2_unmap(im_cpmux);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm2_pic.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/cpm2_pic.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm2_pic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/cpm2_pic.c	2010-05-16 17:17:36.000000000 -0400
@@ -198,7 +198,7 @@ err_sense:
 }
 
 static struct irq_chip cpm2_pic = {
-	.name = " CPM2 SIU ",
+	.name = "CPM2 SIU",
 	.mask = cpm2_mask_irq,
 	.unmask = cpm2_unmask_irq,
 	.ack = cpm2_ack,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm2_pic.h linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/cpm2_pic.h
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm2_pic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/cpm2_pic.h	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,6 @@
 
 extern unsigned int cpm2_get_irq(void);
 
-extern void cpm2_pic_init(struct device_node*);
+extern void cpm2_pic_init(struct device_node *);
 
 #endif /* _PPC_KERNEL_CPM2_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm_common.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/cpm_common.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm_common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/cpm_common.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/of_device.h>
 #include <linux/spinlock.h>
 #include <linux/of.h>
+#include <linux/slab.h>
 
 #include <asm/udbg.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/dart_iommu.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/dart_iommu.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/dart_iommu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/dart_iommu.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,7 +29,6 @@
 
 #include <linux/init.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
@@ -38,6 +37,7 @@
 #include <linux/vmalloc.h>
 #include <linux/suspend.h>
 #include <linux/lmb.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/iommu.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_gtm.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/fsl_gtm.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_gtm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/fsl_gtm.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/spinlock.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include <asm/fsl_gtm.h>
 
 #define GTCFR_STP(x)		((x) & 1 ? 1 << 5 : 1 << 1)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_msi.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/fsl_msi.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_msi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/fsl_msi.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/bootmem.h>
 #include <linux/msi.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/of_platform.h>
 #include <sysdev/fsl_soc.h>
 #include <asm/prom.h>
@@ -47,7 +48,7 @@ static struct irq_chip fsl_msi_chip = {
 	.mask		= mask_msi_irq,
 	.unmask		= unmask_msi_irq,
 	.ack		= fsl_msi_end_irq,
-	.name	= " FSL-MSI  ",
+	.name		= "FSL-MSI",
 };
 
 static int fsl_msi_host_map(struct irq_host *h, unsigned int virq,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_pci.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/fsl_pci.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/fsl_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/bootmem.h>
 #include <linux/lmb.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_rio.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/fsl_rio.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_rio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/fsl_rio.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/rio_drv.h>
 #include <linux/of_platform.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/grackle.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/grackle.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/grackle.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/grackle.c	2010-05-16 17:17:36.000000000 -0400
@@ -56,9 +56,9 @@ static inline void grackle_set_loop_snoo
 void __init setup_grackle(struct pci_controller *hose)
 {
 	setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0);
-	if (machine_is_compatible("PowerMac1,1"))
+	if (of_machine_is_compatible("PowerMac1,1"))
 		ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
-	if (machine_is_compatible("AAPL,PowerBook1998"))
+	if (of_machine_is_compatible("AAPL,PowerBook1998"))
 		grackle_set_loop_snoop(hose, 1);
 #if 0	/* Disabled for now, HW problems ??? */
 	grackle_set_stg(hose, 1);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/i8259.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/i8259.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/i8259.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/i8259.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,7 @@ static unsigned char cached_8259[2] = {
 #define cached_A1 (cached_8259[0])
 #define cached_21 (cached_8259[1])
 
-static DEFINE_SPINLOCK(i8259_lock);
+static DEFINE_RAW_SPINLOCK(i8259_lock);
 
 static struct irq_host *i8259_host;
 
@@ -42,7 +42,7 @@ unsigned int i8259_irq(void)
 	if (pci_intack)
 		irq = readb(pci_intack);
 	else {
-		spin_lock(&i8259_lock);
+		raw_spin_lock(&i8259_lock);
 		lock = 1;
 
 		/* Perform an interrupt acknowledge cycle on controller 1. */
@@ -74,7 +74,7 @@ unsigned int i8259_irq(void)
 		irq = NO_IRQ;
 
 	if (lock)
-		spin_unlock(&i8259_lock);
+		raw_spin_unlock(&i8259_lock);
 	return irq;
 }
 
@@ -82,7 +82,7 @@ static void i8259_mask_and_ack_irq(unsig
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&i8259_lock, flags);
+	raw_spin_lock_irqsave(&i8259_lock, flags);
 	if (irq_nr > 7) {
 		cached_A1 |= 1 << (irq_nr-8);
 		inb(0xA1); 	/* DUMMY */
@@ -95,7 +95,7 @@ static void i8259_mask_and_ack_irq(unsig
 		outb(cached_21, 0x21);
 		outb(0x20, 0x20);	/* Non-specific EOI */
 	}
-	spin_unlock_irqrestore(&i8259_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259_lock, flags);
 }
 
 static void i8259_set_irq_mask(int irq_nr)
@@ -110,13 +110,13 @@ static void i8259_mask_irq(unsigned int
 
 	pr_debug("i8259_mask_irq(%d)\n", irq_nr);
 
-	spin_lock_irqsave(&i8259_lock, flags);
+	raw_spin_lock_irqsave(&i8259_lock, flags);
 	if (irq_nr < 8)
 		cached_21 |= 1 << irq_nr;
 	else
 		cached_A1 |= 1 << (irq_nr-8);
 	i8259_set_irq_mask(irq_nr);
-	spin_unlock_irqrestore(&i8259_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259_lock, flags);
 }
 
 static void i8259_unmask_irq(unsigned int irq_nr)
@@ -125,17 +125,17 @@ static void i8259_unmask_irq(unsigned in
 
 	pr_debug("i8259_unmask_irq(%d)\n", irq_nr);
 
-	spin_lock_irqsave(&i8259_lock, flags);
+	raw_spin_lock_irqsave(&i8259_lock, flags);
 	if (irq_nr < 8)
 		cached_21 &= ~(1 << irq_nr);
 	else
 		cached_A1 &= ~(1 << (irq_nr-8));
 	i8259_set_irq_mask(irq_nr);
-	spin_unlock_irqrestore(&i8259_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259_lock, flags);
 }
 
 static struct irq_chip i8259_pic = {
-	.name		= " i8259    ",
+	.name		= "i8259",
 	.mask		= i8259_mask_irq,
 	.disable	= i8259_mask_irq,
 	.unmask		= i8259_unmask_irq,
@@ -241,7 +241,7 @@ void i8259_init(struct device_node *node
 	unsigned long flags;
 
 	/* initialize the controller */
-	spin_lock_irqsave(&i8259_lock, flags);
+	raw_spin_lock_irqsave(&i8259_lock, flags);
 
 	/* Mask all first */
 	outb(0xff, 0xA1);
@@ -273,7 +273,7 @@ void i8259_init(struct device_node *node
 	outb(cached_A1, 0xA1);
 	outb(cached_21, 0x21);
 
-	spin_unlock_irqrestore(&i8259_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259_lock, flags);
 
 	/* create a legacy host */
 	i8259_host = irq_alloc_host(node, IRQ_HOST_MAP_LEGACY,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/ipic.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/ipic.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/ipic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/ipic.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,7 @@
 
 static struct ipic * primary_ipic;
 static struct irq_chip ipic_level_irq_chip, ipic_edge_irq_chip;
-static DEFINE_SPINLOCK(ipic_lock);
+static DEFINE_RAW_SPINLOCK(ipic_lock);
 
 static struct ipic_info ipic_info[] = {
 	[1] = {
@@ -530,13 +530,13 @@ static void ipic_unmask_irq(unsigned int
 	unsigned long flags;
 	u32 temp;
 
-	spin_lock_irqsave(&ipic_lock, flags);
+	raw_spin_lock_irqsave(&ipic_lock, flags);
 
 	temp = ipic_read(ipic->regs, ipic_info[src].mask);
 	temp |= (1 << (31 - ipic_info[src].bit));
 	ipic_write(ipic->regs, ipic_info[src].mask, temp);
 
-	spin_unlock_irqrestore(&ipic_lock, flags);
+	raw_spin_unlock_irqrestore(&ipic_lock, flags);
 }
 
 static void ipic_mask_irq(unsigned int virq)
@@ -546,7 +546,7 @@ static void ipic_mask_irq(unsigned int v
 	unsigned long flags;
 	u32 temp;
 
-	spin_lock_irqsave(&ipic_lock, flags);
+	raw_spin_lock_irqsave(&ipic_lock, flags);
 
 	temp = ipic_read(ipic->regs, ipic_info[src].mask);
 	temp &= ~(1 << (31 - ipic_info[src].bit));
@@ -556,7 +556,7 @@ static void ipic_mask_irq(unsigned int v
 	 * for nearly all cases. */
 	mb();
 
-	spin_unlock_irqrestore(&ipic_lock, flags);
+	raw_spin_unlock_irqrestore(&ipic_lock, flags);
 }
 
 static void ipic_ack_irq(unsigned int virq)
@@ -566,7 +566,7 @@ static void ipic_ack_irq(unsigned int vi
 	unsigned long flags;
 	u32 temp;
 
-	spin_lock_irqsave(&ipic_lock, flags);
+	raw_spin_lock_irqsave(&ipic_lock, flags);
 
 	temp = 1 << (31 - ipic_info[src].bit);
 	ipic_write(ipic->regs, ipic_info[src].ack, temp);
@@ -575,7 +575,7 @@ static void ipic_ack_irq(unsigned int vi
 	 * for nearly all cases. */
 	mb();
 
-	spin_unlock_irqrestore(&ipic_lock, flags);
+	raw_spin_unlock_irqrestore(&ipic_lock, flags);
 }
 
 static void ipic_mask_irq_and_ack(unsigned int virq)
@@ -585,7 +585,7 @@ static void ipic_mask_irq_and_ack(unsign
 	unsigned long flags;
 	u32 temp;
 
-	spin_lock_irqsave(&ipic_lock, flags);
+	raw_spin_lock_irqsave(&ipic_lock, flags);
 
 	temp = ipic_read(ipic->regs, ipic_info[src].mask);
 	temp &= ~(1 << (31 - ipic_info[src].bit));
@@ -598,7 +598,7 @@ static void ipic_mask_irq_and_ack(unsign
 	 * for nearly all cases. */
 	mb();
 
-	spin_unlock_irqrestore(&ipic_lock, flags);
+	raw_spin_unlock_irqrestore(&ipic_lock, flags);
 }
 
 static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
@@ -660,7 +660,7 @@ static int ipic_set_irq_type(unsigned in
 
 /* level interrupts and edge interrupts have different ack operations */
 static struct irq_chip ipic_level_irq_chip = {
-	.name		= " IPIC  ",
+	.name		= "IPIC",
 	.unmask		= ipic_unmask_irq,
 	.mask		= ipic_mask_irq,
 	.mask_ack	= ipic_mask_irq,
@@ -668,7 +668,7 @@ static struct irq_chip ipic_level_irq_ch
 };
 
 static struct irq_chip ipic_edge_irq_chip = {
-	.name		= " IPIC  ",
+	.name		= "IPIC",
 	.unmask		= ipic_unmask_irq,
 	.mask		= ipic_mask_irq,
 	.mask_ack	= ipic_mask_irq_and_ack,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpc8xx_pic.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/mpc8xx_pic.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpc8xx_pic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/mpc8xx_pic.c	2010-05-16 17:17:36.000000000 -0400
@@ -94,7 +94,7 @@ static int mpc8xx_set_irq_type(unsigned
 }
 
 static struct irq_chip mpc8xx_pic = {
-	.name = " MPC8XX SIU ",
+	.name = "MPC8XX SIU",
 	.unmask = mpc8xx_unmask_irq,
 	.mask = mpc8xx_mask_irq,
 	.ack = mpc8xx_ack,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpc8xxx_gpio.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/mpc8xxx_gpio.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpc8xxx_gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/mpc8xxx_gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #define MPC8XXX_GPIO_PINS	32
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpic.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/mpic.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/mpic.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/bootmem.h>
 #include <linux/spinlock.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include <asm/ptrace.h>
 #include <asm/signal.h>
@@ -46,7 +47,7 @@
 
 static struct mpic *mpics;
 static struct mpic *mpic_primary;
-static DEFINE_SPINLOCK(mpic_lock);
+static DEFINE_RAW_SPINLOCK(mpic_lock);
 
 #ifdef CONFIG_PPC32	/* XXX for now */
 #ifdef CONFIG_IRQ_ALL_CPUS
@@ -347,10 +348,10 @@ static inline void mpic_ht_end_irq(struc
 		unsigned int mask = 1U << (fixup->index & 0x1f);
 		writel(mask, fixup->applebase + soff);
 	} else {
-		spin_lock(&mpic->fixup_lock);
+		raw_spin_lock(&mpic->fixup_lock);
 		writeb(0x11 + 2 * fixup->index, fixup->base + 2);
 		writel(fixup->data, fixup->base + 4);
-		spin_unlock(&mpic->fixup_lock);
+		raw_spin_unlock(&mpic->fixup_lock);
 	}
 }
 
@@ -366,7 +367,7 @@ static void mpic_startup_ht_interrupt(st
 
 	DBG("startup_ht_interrupt(0x%x, 0x%x) index: %d\n",
 	    source, irqflags, fixup->index);
-	spin_lock_irqsave(&mpic->fixup_lock, flags);
+	raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
 	/* Enable and configure */
 	writeb(0x10 + 2 * fixup->index, fixup->base + 2);
 	tmp = readl(fixup->base + 4);
@@ -374,7 +375,7 @@ static void mpic_startup_ht_interrupt(st
 	if (irqflags & IRQ_LEVEL)
 		tmp |= 0x22;
 	writel(tmp, fixup->base + 4);
-	spin_unlock_irqrestore(&mpic->fixup_lock, flags);
+	raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags);
 
 #ifdef CONFIG_PM
 	/* use the lowest bit inverted to the actual HW,
@@ -396,12 +397,12 @@ static void mpic_shutdown_ht_interrupt(s
 	DBG("shutdown_ht_interrupt(0x%x, 0x%x)\n", source, irqflags);
 
 	/* Disable */
-	spin_lock_irqsave(&mpic->fixup_lock, flags);
+	raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
 	writeb(0x10 + 2 * fixup->index, fixup->base + 2);
 	tmp = readl(fixup->base + 4);
 	tmp |= 1;
 	writel(tmp, fixup->base + 4);
-	spin_unlock_irqrestore(&mpic->fixup_lock, flags);
+	raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags);
 
 #ifdef CONFIG_PM
 	/* use the lowest bit inverted to the actual HW,
@@ -515,7 +516,7 @@ static void __init mpic_scan_ht_pics(str
 	BUG_ON(mpic->fixups == NULL);
 
 	/* Init spinlock */
-	spin_lock_init(&mpic->fixup_lock);
+	raw_spin_lock_init(&mpic->fixup_lock);
 
 	/* Map U3 config space. We assume all IO-APICs are on the primary bus
 	 * so we only need to map 64kB.
@@ -573,12 +574,12 @@ static int irq_choose_cpu(const cpumask_
 
 	if (cpumask_equal(mask, cpu_all_mask)) {
 		static int irq_rover;
-		static DEFINE_SPINLOCK(irq_rover_lock);
+		static DEFINE_RAW_SPINLOCK(irq_rover_lock);
 		unsigned long flags;
 
 		/* Round-robin distribution... */
 	do_round_robin:
-		spin_lock_irqsave(&irq_rover_lock, flags);
+		raw_spin_lock_irqsave(&irq_rover_lock, flags);
 
 		while (!cpu_online(irq_rover)) {
 			if (++irq_rover >= NR_CPUS)
@@ -590,7 +591,7 @@ static int irq_choose_cpu(const cpumask_
 				irq_rover = 0;
 		} while (!cpu_online(irq_rover));
 
-		spin_unlock_irqrestore(&irq_rover_lock, flags);
+		raw_spin_unlock_irqrestore(&irq_rover_lock, flags);
 	} else {
 		cpuid = cpumask_first_and(mask, cpu_online_mask);
 		if (cpuid >= nr_cpu_ids)
@@ -1368,14 +1369,14 @@ void __init mpic_set_serial_int(struct m
 	unsigned long flags;
 	u32 v;
 
-	spin_lock_irqsave(&mpic_lock, flags);
+	raw_spin_lock_irqsave(&mpic_lock, flags);
 	v = mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1);
 	if (enable)
 		v |= MPIC_GREG_GLOBAL_CONF_1_SIE;
 	else
 		v &= ~MPIC_GREG_GLOBAL_CONF_1_SIE;
 	mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1, v);
-	spin_unlock_irqrestore(&mpic_lock, flags);
+	raw_spin_unlock_irqrestore(&mpic_lock, flags);
 }
 
 void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
@@ -1388,7 +1389,7 @@ void mpic_irq_set_priority(unsigned int
 	if (!mpic)
 		return;
 
-	spin_lock_irqsave(&mpic_lock, flags);
+	raw_spin_lock_irqsave(&mpic_lock, flags);
 	if (mpic_is_ipi(mpic, irq)) {
 		reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) &
 			~MPIC_VECPRI_PRIORITY_MASK;
@@ -1400,7 +1401,7 @@ void mpic_irq_set_priority(unsigned int
 		mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
 			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
 	}
-	spin_unlock_irqrestore(&mpic_lock, flags);
+	raw_spin_unlock_irqrestore(&mpic_lock, flags);
 }
 
 void mpic_setup_this_cpu(void)
@@ -1415,7 +1416,7 @@ void mpic_setup_this_cpu(void)
 
 	DBG("%s: setup_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
 
-	spin_lock_irqsave(&mpic_lock, flags);
+	raw_spin_lock_irqsave(&mpic_lock, flags);
 
  	/* let the mpic know we want intrs. default affinity is 0xffffffff
 	 * until changed via /proc. That's how it's done on x86. If we want
@@ -1431,7 +1432,7 @@ void mpic_setup_this_cpu(void)
 	/* Set current processor priority to 0 */
 	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
 
-	spin_unlock_irqrestore(&mpic_lock, flags);
+	raw_spin_unlock_irqrestore(&mpic_lock, flags);
 #endif /* CONFIG_SMP */
 }
 
@@ -1460,7 +1461,7 @@ void mpic_teardown_this_cpu(int secondar
 	BUG_ON(mpic == NULL);
 
 	DBG("%s: teardown_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
-	spin_lock_irqsave(&mpic_lock, flags);
+	raw_spin_lock_irqsave(&mpic_lock, flags);
 
 	/* let the mpic know we don't want intrs.  */
 	for (i = 0; i < mpic->num_sources ; i++)
@@ -1474,7 +1475,7 @@ void mpic_teardown_this_cpu(int secondar
 	 */
 	mpic_eoi(mpic);
 
-	spin_unlock_irqrestore(&mpic_lock, flags);
+	raw_spin_unlock_irqrestore(&mpic_lock, flags);
 }
 
 
@@ -1575,7 +1576,7 @@ void mpic_request_ipis(void)
 	int i;
 	BUG_ON(mpic == NULL);
 
-	printk(KERN_INFO "mpic: requesting IPIs ... \n");
+	printk(KERN_INFO "mpic: requesting IPIs...\n");
 
 	for (i = 0; i < 4; i++) {
 		unsigned int vipi = irq_create_mapping(mpic->irqhost,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpic_pasemi_msi.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/mpic_pasemi_msi.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpic_pasemi_msi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/mpic_pasemi_msi.c	2010-05-16 17:17:36.000000000 -0400
@@ -60,7 +60,7 @@ static struct irq_chip mpic_pasemi_msi_c
 	.eoi		= mpic_end_irq,
 	.set_type	= mpic_set_irq_type,
 	.set_affinity	= mpic_set_affinity,
-	.name		= "PASEMI-MSI ",
+	.name		= "PASEMI-MSI",
 };
 
 static int pasemi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/msi_bitmap.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/msi_bitmap.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/msi_bitmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/msi_bitmap.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/bitmap.h>
 #include <asm/msi_bitmap.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mv64x60_dev.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/mv64x60_dev.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mv64x60_dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/mv64x60_dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/mv643xx.h>
 #include <linux/platform_device.h>
 #include <linux/of_platform.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/prom.h>
 
@@ -189,6 +190,7 @@ static int __init mv64x60_mpsc_device_se
 	pdev = platform_device_alloc(MPSC_CTLR_NAME, port_number);
 	if (!pdev)
 		return -ENOMEM;
+	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
 	err = platform_device_add_resources(pdev, r, 5);
 	if (err)
@@ -302,6 +304,7 @@ static int __init mv64x60_eth_device_set
 	if (!pdev)
 		return -ENOMEM;
 
+	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 	err = platform_device_add_resources(pdev, r, 1);
 	if (err)
 		goto error;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/of_rtc.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/of_rtc.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/of_rtc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/of_rtc.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/of.h>
 #include <linux/init.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 
 static __initdata struct {
 	const char *compatible;
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/pmi.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/pmi.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/pmi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/pmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
  */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/ppc4xx_gpio.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/ppc4xx_gpio.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/ppc4xx_gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/ppc4xx_gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/of_gpio.h>
 #include <linux/gpio.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 
 #define GPIO_MASK(gpio)		(0x80000000 >> (gpio))
 #define GPIO_MASK2(gpio)	(0xc0000000 >> ((gpio) * 2))
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/ppc4xx_pci.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/ppc4xx_pci.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/ppc4xx_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/ppc4xx_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/of.h>
 #include <linux/bootmem.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/pci-bridge.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/ppc4xx_soc.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/ppc4xx_soc.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/ppc4xx_soc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/ppc4xx_soc.c	2010-05-16 17:17:36.000000000 -0400
@@ -174,7 +174,8 @@ static int __init ppc4xx_l2c_probe(void)
 		| L2C_CFG_CPIM | L2C_CFG_TPIM | L2C_CFG_LIM | L2C_CFG_SMCM;
 
 	/* Check for 460EX/GT special handling */
-	if (of_device_is_compatible(np, "ibm,l2-cache-460ex"))
+	if (of_device_is_compatible(np, "ibm,l2-cache-460ex") ||
+	    of_device_is_compatible(np, "ibm,l2-cache-460gt"))
 		r |= L2C_CFG_RDBW;
 
 	mtdcr(dcrbase_l2c + DCRN_L2C0_CFG, r);
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/qe_lib/gpio.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/qe_lib/gpio.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/qe_lib/gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/qe_lib/gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 #include <asm/qe.h>
 
 struct qe_gpio_chip {
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/qe_lib/qe_ic.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/qe_lib/qe_ic.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/qe_lib/qe_ic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/qe_lib/qe_ic.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,7 @@
 
 #include "qe_ic.h"
 
-static DEFINE_SPINLOCK(qe_ic_lock);
+static DEFINE_RAW_SPINLOCK(qe_ic_lock);
 
 static struct qe_ic_info qe_ic_info[] = {
 	[1] = {
@@ -201,13 +201,13 @@ static void qe_ic_unmask_irq(unsigned in
 	unsigned long flags;
 	u32 temp;
 
-	spin_lock_irqsave(&qe_ic_lock, flags);
+	raw_spin_lock_irqsave(&qe_ic_lock, flags);
 
 	temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
 	qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
 		    temp | qe_ic_info[src].mask);
 
-	spin_unlock_irqrestore(&qe_ic_lock, flags);
+	raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
 }
 
 static void qe_ic_mask_irq(unsigned int virq)
@@ -217,7 +217,7 @@ static void qe_ic_mask_irq(unsigned int
 	unsigned long flags;
 	u32 temp;
 
-	spin_lock_irqsave(&qe_ic_lock, flags);
+	raw_spin_lock_irqsave(&qe_ic_lock, flags);
 
 	temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
 	qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
@@ -233,11 +233,11 @@ static void qe_ic_mask_irq(unsigned int
 	 */
 	mb();
 
-	spin_unlock_irqrestore(&qe_ic_lock, flags);
+	raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
 }
 
 static struct irq_chip qe_ic_irq_chip = {
-	.name = " QEIC  ",
+	.name = "QEIC",
 	.unmask = qe_ic_unmask_irq,
 	.mask = qe_ic_mask_irq,
 	.mask_ack = qe_ic_mask_irq,
@@ -256,7 +256,7 @@ static int qe_ic_host_map(struct irq_hos
 	struct irq_chip *chip;
 
 	if (qe_ic_info[hw].mask == 0) {
-		printk(KERN_ERR "Can't map reserved IRQ \n");
+		printk(KERN_ERR "Can't map reserved IRQ\n");
 		return -EINVAL;
 	}
 	/* Default chip */
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/qe_lib/qe_io.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/qe_lib/qe_io.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/qe_lib/qe_io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/qe_lib/qe_io.c	2010-05-16 17:17:36.000000000 -0400
@@ -157,13 +157,13 @@ int par_io_of_config(struct device_node
 	const unsigned int *pio_map;
 
 	if (par_io == NULL) {
-		printk(KERN_ERR "par_io not initialized \n");
+		printk(KERN_ERR "par_io not initialized\n");
 		return -1;
 	}
 
 	ph = of_get_property(np, "pio-handle", NULL);
 	if (ph == NULL) {
-		printk(KERN_ERR "pio-handle not available \n");
+		printk(KERN_ERR "pio-handle not available\n");
 		return -1;
 	}
 
@@ -171,12 +171,12 @@ int par_io_of_config(struct device_node
 
 	pio_map = of_get_property(pio, "pio-map", &pio_map_len);
 	if (pio_map == NULL) {
-		printk(KERN_ERR "pio-map is not set! \n");
+		printk(KERN_ERR "pio-map is not set!\n");
 		return -1;
 	}
 	pio_map_len /= sizeof(unsigned int);
 	if ((pio_map_len % 6) != 0) {
-		printk(KERN_ERR "pio-map format wrong! \n");
+		printk(KERN_ERR "pio-map format wrong!\n");
 		return -1;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/qe_lib/ucc.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/qe_lib/ucc.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/qe_lib/ucc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/qe_lib/ucc.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/stddef.h>
 #include <linux/spinlock.h>
 #include <linux/module.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/simple_gpio.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/simple_gpio.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/simple_gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/simple_gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 #include <asm/prom.h>
 #include "simple_gpio.h"
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/tsi108_pci.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/tsi108_pci.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/tsi108_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/tsi108_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/uic.c linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/uic.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/uic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/uic.c	2010-05-16 17:17:36.000000000 -0400
@@ -177,7 +177,7 @@ static int uic_set_irq_type(unsigned int
 }
 
 static struct irq_chip uic_irq_chip = {
-	.name		= " UIC  ",
+	.name		= "UIC",
 	.unmask		= uic_unmask_irq,
 	.mask		= uic_mask_irq,
  	.mask_ack	= uic_mask_ack_irq,
diff -druNp linux-libre-2.6.33-gnu1/arch/powerpc/xmon/xmon.c linux-libre-2.6.34-gnu1/arch/powerpc/xmon/xmon.c
--- linux-libre-2.6.33-gnu1/arch/powerpc/xmon/xmon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/powerpc/xmon/xmon.c	2010-05-16 17:17:36.000000000 -0400
@@ -61,7 +61,7 @@ static int xmon_owner;
 static int xmon_gate;
 #endif /* CONFIG_SMP */
 
-static unsigned long in_xmon = 0;
+static unsigned long in_xmon __read_mostly = 0;
 
 static unsigned long adrs;
 static int size = 1;
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/appldata/appldata_mem.c linux-libre-2.6.34-gnu1/arch/s390/appldata/appldata_mem.c
--- linux-libre-2.6.33-gnu1/arch/s390/appldata/appldata_mem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/appldata/appldata_mem.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/kernel_stat.h>
 #include <linux/pagemap.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/appldata/appldata_net_sum.c linux-libre-2.6.34-gnu1/arch/s390/appldata/appldata_net_sum.c
--- linux-libre-2.6.33-gnu1/arch/s390/appldata/appldata_net_sum.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/appldata/appldata_net_sum.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/kernel_stat.h>
 #include <linux/netdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/boot/compressed/head31.S linux-libre-2.6.34-gnu1/arch/s390/boot/compressed/head31.S
--- linux-libre-2.6.33-gnu1/arch/s390/boot/compressed/head31.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/boot/compressed/head31.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,51 @@
+/*
+ * Startup glue code to uncompress the kernel
+ *
+ * Copyright IBM Corp. 2010
+ *
+ *   Author(s):	Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/init.h>
+#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
+#include <asm/page.h>
+#include "sizes.h"
+
+__HEAD
+	.globl	startup_continue
+startup_continue:
+	basr	%r13,0			# get base
+.LPG1:
+	# setup stack
+	l	%r15,.Lstack-.LPG1(%r13)
+	ahi	%r15,-96
+	l	%r1,.Ldecompress-.LPG1(%r13)
+	basr	%r14,%r1
+	# setup registers for memory mover & branch to target
+	lr	%r4,%r2
+	l	%r2,.Loffset-.LPG1(%r13)
+	la	%r4,0(%r2,%r4)
+	l	%r3,.Lmvsize-.LPG1(%r13)
+	lr	%r5,%r3
+	# move the memory mover someplace safe
+	la	%r1,0x200
+	mvc	0(mover_end-mover,%r1),mover-.LPG1(%r13)
+	# decompress image is started at 0x11000
+	lr	%r6,%r2
+	br	%r1
+mover:
+	mvcle	%r2,%r4,0
+	jo	mover
+	br	%r6
+mover_end:
+
+	.align	8
+.Lstack:
+	.long	0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
+.Ldecompress:
+	.long	decompress_kernel
+.Loffset:
+	.long	0x11000
+.Lmvsize:
+	.long	SZ__bss_start
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/boot/compressed/head64.S linux-libre-2.6.34-gnu1/arch/s390/boot/compressed/head64.S
--- linux-libre-2.6.33-gnu1/arch/s390/boot/compressed/head64.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/boot/compressed/head64.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ * Startup glue code to uncompress the kernel
+ *
+ * Copyright IBM Corp. 2010
+ *
+ *   Author(s):	Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/init.h>
+#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
+#include <asm/page.h>
+#include "sizes.h"
+
+__HEAD
+	.globl	startup_continue
+startup_continue:
+	basr	%r13,0			# get base
+.LPG1:
+	# setup stack
+	lg	%r15,.Lstack-.LPG1(%r13)
+	aghi	%r15,-160
+	brasl	%r14,decompress_kernel
+	# setup registers for memory mover & branch to target
+	lgr	%r4,%r2
+	lg	%r2,.Loffset-.LPG1(%r13)
+	la	%r4,0(%r2,%r4)
+	lg	%r3,.Lmvsize-.LPG1(%r13)
+	lgr	%r5,%r3
+	# move the memory mover someplace safe
+	la	%r1,0x200
+	mvc	0(mover_end-mover,%r1),mover-.LPG1(%r13)
+	# decompress image is started at 0x11000
+	lgr	%r6,%r2
+	br	%r1
+mover:
+	mvcle	%r2,%r4,0
+	jo	mover
+	br	%r6
+mover_end:
+
+	.align	8
+.Lstack:
+	.quad	0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
+.Loffset:
+	.quad	0x11000
+.Lmvsize:
+	.quad	SZ__bss_start
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/boot/compressed/Makefile linux-libre-2.6.34-gnu1/arch/s390/boot/compressed/Makefile
--- linux-libre-2.6.33-gnu1/arch/s390/boot/compressed/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/boot/compressed/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,60 @@
+#
+# linux/arch/s390/boot/compressed/Makefile
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+BITS := $(if $(CONFIG_64BIT),64,31)
+
+targets	:= vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
+	   vmlinux.bin.lzma misc.o piggy.o sizes.h head$(BITS).o
+
+KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
+KBUILD_CFLAGS += $(cflags-y)
+KBUILD_CFLAGS += $(call cc-option,-mpacked-stack)
+KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
+
+GCOV_PROFILE := n
+
+OBJECTS := $(addprefix $(objtree)/arch/s390/kernel/, head.o sclp.o ebcdic.o)
+OBJECTS += $(obj)/head$(BITS).o $(obj)/misc.o $(obj)/piggy.o
+
+LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup -T
+$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS)
+	$(call if_changed,ld)
+	@:
+
+sed-sizes := -e 's/^\([0-9a-fA-F]*\) . \(__bss_start\|_end\)$$/\#define SZ\2 0x\1/p'
+
+quiet_cmd_sizes = GEN $@
+      cmd_sizes = $(NM) $< | sed -n $(sed-sizes) > $@
+
+$(obj)/sizes.h: vmlinux
+	$(call if_changed,sizes)
+
+AFLAGS_head$(BITS).o += -I$(obj)
+$(obj)/head$(BITS).o: $(obj)/sizes.h
+
+CFLAGS_misc.o += -I$(obj)
+$(obj)/misc.o: $(obj)/sizes.h
+
+OBJCOPYFLAGS_vmlinux.bin :=  -R .comment -S
+$(obj)/vmlinux.bin: vmlinux
+	$(call if_changed,objcopy)
+
+vmlinux.bin.all-y := $(obj)/vmlinux.bin
+
+suffix-$(CONFIG_KERNEL_GZIP)  := gz
+suffix-$(CONFIG_KERNEL_BZIP2) := bz2
+suffix-$(CONFIG_KERNEL_LZMA)  := lzma
+
+$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y)
+	$(call if_changed,gzip)
+$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y)
+	$(call if_changed,bzip2)
+$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y)
+	$(call if_changed,lzma)
+
+LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y)
+	$(call if_changed,ld)
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/boot/compressed/misc.c linux-libre-2.6.34-gnu1/arch/s390/boot/compressed/misc.c
--- linux-libre-2.6.33-gnu1/arch/s390/boot/compressed/misc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/boot/compressed/misc.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,158 @@
+/*
+ * Definitions and wrapper functions for kernel decompressor
+ *
+ * Copyright IBM Corp. 2010
+ *
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/ipl.h>
+#include "sizes.h"
+
+/*
+ * gzip declarations
+ */
+#define STATIC static
+
+#undef memset
+#undef memcpy
+#undef memmove
+#define memzero(s, n) memset((s), 0, (n))
+
+/* Symbols defined by linker scripts */
+extern char input_data[];
+extern int input_len;
+extern char _text, _end;
+extern char _bss, _ebss;
+
+static void error(char *m);
+
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#ifdef CONFIG_HAVE_KERNEL_BZIP2
+#define HEAP_SIZE	0x400000
+#else
+#define HEAP_SIZE	0x10000
+#endif
+
+#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
+
+extern _sclp_print_early(const char *);
+
+int puts(const char *s)
+{
+	_sclp_print_early(s);
+	return 0;
+}
+
+void *memset(void *s, int c, size_t n)
+{
+	char *xs;
+
+	if (c == 0)
+		return __builtin_memset(s, 0, n);
+
+	xs = (char *) s;
+	if (n > 0)
+		do {
+			*xs++ = c;
+		} while (--n > 0);
+	return s;
+}
+
+void *memcpy(void *__dest, __const void *__src, size_t __n)
+{
+	return __builtin_memcpy(__dest, __src, __n);
+}
+
+void *memmove(void *__dest, __const void *__src, size_t __n)
+{
+	char *d;
+	const char *s;
+
+	if (__dest <= __src)
+		return __builtin_memcpy(__dest, __src, __n);
+	d = __dest + __n;
+	s = __src + __n;
+	while (__n--)
+		*--d = *--s;
+	return __dest;
+}
+
+static void error(char *x)
+{
+	unsigned long long psw = 0x000a0000deadbeefULL;
+
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted");
+
+	asm volatile("lpsw %0" : : "Q" (psw));
+}
+
+/*
+ * Safe guard the ipl parameter block against a memory area that will be
+ * overwritten. The validity check for the ipl parameter block is complex
+ * (see cio_get_iplinfo and ipl_save_parameters) but if the pointer to
+ * the ipl parameter block intersects with the passed memory area we can
+ * safely assume that we can read from that memory. In that case just copy
+ * the memory to IPL_PARMBLOCK_ORIGIN even if there is no ipl parameter
+ * block.
+ */
+static void check_ipl_parmblock(void *start, unsigned long size)
+{
+	void *src, *dst;
+
+	src = (void *)(unsigned long) S390_lowcore.ipl_parmblock_ptr;
+	if (src + PAGE_SIZE <= start || src >= start + size)
+		return;
+	dst = (void *) IPL_PARMBLOCK_ORIGIN;
+	memmove(dst, src, PAGE_SIZE);
+	S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN;
+}
+
+unsigned long decompress_kernel(void)
+{
+	unsigned long output_addr;
+	unsigned char *output;
+
+	check_ipl_parmblock((void *) 0, (unsigned long) output + SZ__bss_start);
+	memset(&_bss, 0, &_ebss - &_bss);
+	free_mem_ptr = (unsigned long)&_end;
+	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+	output = (unsigned char *) ((free_mem_end_ptr + 4095UL) & -4096UL);
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	/*
+	 * Move the initrd right behind the end of the decompressed
+	 * kernel image.
+	 */
+	if (INITRD_START && INITRD_SIZE &&
+	    INITRD_START < (unsigned long) output + SZ__bss_start) {
+		check_ipl_parmblock(output + SZ__bss_start,
+				    INITRD_START + INITRD_SIZE);
+		memmove(output + SZ__bss_start,
+			(void *) INITRD_START, INITRD_SIZE);
+		INITRD_START = (unsigned long) output + SZ__bss_start;
+	}
+#endif
+
+	puts("Uncompressing Linux... ");
+	decompress(input_data, input_len, NULL, NULL, output, NULL, error);
+	puts("Ok, booting the kernel.\n");
+	return (unsigned long) output;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/boot/compressed/vmlinux.lds.S linux-libre-2.6.34-gnu1/arch/s390/boot/compressed/vmlinux.lds.S
--- linux-libre-2.6.33-gnu1/arch/s390/boot/compressed/vmlinux.lds.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/boot/compressed/vmlinux.lds.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,55 @@
+#include <asm-generic/vmlinux.lds.h>
+
+#ifdef CONFIG_64BIT
+OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
+OUTPUT_ARCH(s390:64-bit)
+#else
+OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
+OUTPUT_ARCH(s390)
+#endif
+
+ENTRY(startup)
+
+SECTIONS
+{
+	/* Be careful parts of head_64.S assume startup_32 is at
+	 * address 0.
+	 */
+	. = 0;
+	.head.text : {
+		_head = . ;
+		HEAD_TEXT
+		_ehead = . ;
+	}
+	.rodata.compressed : {
+		*(.rodata.compressed)
+	}
+	.text :	{
+		_text = .;	/* Text */
+		*(.text)
+		*(.text.*)
+		_etext = . ;
+	}
+	.rodata : {
+		_rodata = . ;
+		*(.rodata)	 /* read-only data */
+		*(.rodata.*)
+		_erodata = . ;
+	}
+	.data :	{
+		_data = . ;
+		*(.data)
+		*(.data.*)
+		_edata = . ;
+	}
+	. = ALIGN(256);
+	.bss : {
+		_bss = . ;
+		*(.bss)
+		*(.bss.*)
+		*(COMMON)
+		. = ALIGN(8);	/* For convenience during zeroing */
+		_ebss = .;
+	}
+	_end = .;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/boot/compressed/vmlinux.scr linux-libre-2.6.34-gnu1/arch/s390/boot/compressed/vmlinux.scr
--- linux-libre-2.6.33-gnu1/arch/s390/boot/compressed/vmlinux.scr	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/boot/compressed/vmlinux.scr	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,10 @@
+SECTIONS
+{
+  .rodata.compressed : {
+	input_len = .;
+	LONG(input_data_end - input_data) input_data = .;
+	*(.data)
+	output_len = . - 4;
+	input_data_end = .;
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/boot/Makefile linux-libre-2.6.34-gnu1/arch/s390/boot/Makefile
--- linux-libre-2.6.33-gnu1/arch/s390/boot/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/boot/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -9,10 +9,18 @@ COMPILE_VERSION := __linux_compile_versi
 EXTRA_CFLAGS  := -DCOMPILE_VERSION=$(COMPILE_VERSION) -gstabs -I.
 
 targets := image
+targets += bzImage
+subdir- := compressed
 
 $(obj)/image: vmlinux FORCE
 	$(call if_changed,objcopy)
 
+$(obj)/bzImage: $(obj)/compressed/vmlinux FORCE
+	$(call if_changed,objcopy)
+
+$(obj)/compressed/vmlinux: FORCE
+	$(Q)$(MAKE) $(build)=$(obj)/compressed $@
+
 install: $(CONFIGURE) $(obj)/image
 	sh -x  $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/image \
 	      System.map Kerntypes "$(INSTALL_PATH)"
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/crypto/aes_s390.c linux-libre-2.6.34-gnu1/arch/s390/crypto/aes_s390.c
--- linux-libre-2.6.33-gnu1/arch/s390/crypto/aes_s390.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/crypto/aes_s390.c	2010-05-16 17:17:36.000000000 -0400
@@ -78,14 +78,14 @@ static int setkey_fallback_cip(struct cr
 	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
 	int ret;
 
-	sctx->fallback.blk->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
-	sctx->fallback.blk->base.crt_flags |= (tfm->crt_flags &
+	sctx->fallback.cip->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
+	sctx->fallback.cip->base.crt_flags |= (tfm->crt_flags &
 			CRYPTO_TFM_REQ_MASK);
 
 	ret = crypto_cipher_setkey(sctx->fallback.cip, in_key, key_len);
 	if (ret) {
 		tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
-		tfm->crt_flags |= (sctx->fallback.blk->base.crt_flags &
+		tfm->crt_flags |= (sctx->fallback.cip->base.crt_flags &
 				CRYPTO_TFM_RES_MASK);
 	}
 	return ret;
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/crypto/prng.c linux-libre-2.6.34-gnu1/arch/s390/crypto/prng.c
--- linux-libre-2.6.33-gnu1/arch/s390/crypto/prng.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/crypto/prng.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <asm/debug.h>
 #include <asm/uaccess.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/crypto/sha_common.c linux-libre-2.6.34-gnu1/arch/s390/crypto/sha_common.c
--- linux-libre-2.6.33-gnu1/arch/s390/crypto/sha_common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/crypto/sha_common.c	2010-05-16 17:17:36.000000000 -0400
@@ -79,7 +79,7 @@ int s390_sha_final(struct shash_desc *de
 	memset(ctx->buf + index, 0x00, end - index - 8);
 
 	/*
-	 * Append message length. Well, SHA-512 wants a 128 bit lenght value,
+	 * Append message length. Well, SHA-512 wants a 128 bit length value,
 	 * nevertheless we use u64, should be enough for now...
 	 */
 	bits = ctx->count * 8;
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/defconfig linux-libre-2.6.34-gnu1/arch/s390/defconfig
--- linux-libre-2.6.33-gnu1/arch/s390/defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 09:03:07 2010
+# Linux kernel version: 2.6.34-rc3
+# Fri Apr  9 09:57:10 2010
 #
 CONFIG_SCHED_MC=y
 CONFIG_MMU=y
@@ -17,6 +17,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
 CONFIG_NO_IOMEM=y
 CONFIG_NO_DMA=y
 CONFIG_GENERIC_LOCKBREAK=y
@@ -36,6 +37,13 @@ CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -55,15 +63,11 @@ CONFIG_TREE_RCU=y
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=64
 # CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
 # CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 CONFIG_CGROUPS=y
 # CONFIG_CGROUP_DEBUG is not set
 CONFIG_CGROUP_NS=y
@@ -72,6 +76,7 @@ CONFIG_CGROUP_NS=y
 # CONFIG_CPUSETS is not set
 # CONFIG_CGROUP_CPUACCT is not set
 # CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -86,6 +91,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -119,6 +125,7 @@ CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
+CONFIG_TRACEPOINTS=y
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
 CONFIG_HAVE_SYSCALL_WRAPPERS=y
@@ -127,6 +134,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
 CONFIG_HAVE_DEFAULT_NO_SPIN_MUTEXES=y
 
 #
@@ -239,6 +247,7 @@ CONFIG_64BIT=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=32
 CONFIG_HOTPLUG_CPU=y
+# CONFIG_SCHED_BOOK is not set
 CONFIG_COMPAT=y
 CONFIG_SYSVIPC_COMPAT=y
 CONFIG_AUDIT_ARCH=y
@@ -338,13 +347,13 @@ CONFIG_PM_SLEEP=y
 CONFIG_HIBERNATION=y
 CONFIG_PM_STD_PARTITION=""
 # CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=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
@@ -522,6 +531,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_CAN=m
 CONFIG_CAN_RAW=m
 CONFIG_CAN_BCM=m
@@ -598,6 +608,7 @@ CONFIG_MISC_DEVICES=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 # CONFIG_SCSI_DMA is not set
@@ -856,6 +867,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -884,6 +896,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -945,6 +958,7 @@ CONFIG_DEBUG_MUTEXES=y
 # CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
@@ -966,12 +980,17 @@ CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
 # 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_FUNCTION_TRACE_MCOUNT_TEST=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
@@ -988,10 +1007,15 @@ CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_KPROBE_EVENT=y
+# CONFIG_RING_BUFFER_BENCHMARK is not set
 # CONFIG_DYNAMIC_DEBUG is not set
 CONFIG_SAMPLES=y
+# CONFIG_SAMPLE_TRACEPOINTS is not set
+# CONFIG_SAMPLE_TRACE_EVENTS is not set
 # CONFIG_SAMPLE_KOBJECT is not set
 # CONFIG_SAMPLE_KPROBES is not set
+# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
 
 #
 # Security options
@@ -1025,6 +1049,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 CONFIG_CRYPTO_GF128MUL=m
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
@@ -1112,7 +1137,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
+CONFIG_BINARY_PRINTF=y
 
 #
 # Library routines
@@ -1129,14 +1154,16 @@ CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_LZO_COMPRESS=m
-CONFIG_LZO_DECOMPRESS=m
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_NLATTR=y
 CONFIG_HAVE_KVM=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM=m
+# CONFIG_VHOST_NET is not set
 CONFIG_VIRTIO=y
 CONFIG_VIRTIO_RING=y
 CONFIG_VIRTIO_BALLOON=m
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/hypfs/hypfs_diag.c linux-libre-2.6.34-gnu1/arch/s390/hypfs/hypfs_diag.c
--- linux-libre-2.6.33-gnu1/arch/s390/hypfs/hypfs_diag.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/hypfs/hypfs_diag.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 
 #include <linux/types.h>
 #include <linux/errno.h>
-#include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
@@ -488,7 +487,7 @@ out:
 
 static int diag224(void *ptr)
 {
-	int rc = -ENOTSUPP;
+	int rc = -EOPNOTSUPP;
 
 	asm volatile(
 		"	diag	%1,%2,0x224\n"
@@ -507,7 +506,7 @@ static int diag224_get_name_table(void)
 		return -ENOMEM;
 	if (diag224(diag224_cpu_names)) {
 		kfree(diag224_cpu_names);
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 	}
 	EBCASC(diag224_cpu_names + 16, (*diag224_cpu_names + 1) * 16);
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/hypfs/inode.c linux-libre-2.6.34-gnu1/arch/s390/hypfs/inode.c
--- linux-libre-2.6.33-gnu1/arch/s390/hypfs/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/hypfs/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,8 +14,8 @@
 #include <linux/fs.h>
 #include <linux/namei.h>
 #include <linux/vfs.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
-#include <linux/gfp.h>
 #include <linux/time.h>
 #include <linux/parser.h>
 #include <linux/sysfs.h>
@@ -288,46 +288,30 @@ static int hypfs_fill_super(struct super
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = HYPFS_MAGIC;
 	sb->s_op = &hypfs_s_ops;
-	if (hypfs_parse_options(data, sb)) {
-		rc = -EINVAL;
-		goto err_alloc;
-	}
+	if (hypfs_parse_options(data, sb))
+		return -EINVAL;
 	root_inode = hypfs_make_inode(sb, S_IFDIR | 0755);
-	if (!root_inode) {
-		rc = -ENOMEM;
-		goto err_alloc;
-	}
+	if (!root_inode)
+		return -ENOMEM;
 	root_inode->i_op = &simple_dir_inode_operations;
 	root_inode->i_fop = &simple_dir_operations;
-	root_dentry = d_alloc_root(root_inode);
+	sb->s_root = root_dentry = d_alloc_root(root_inode);
 	if (!root_dentry) {
 		iput(root_inode);
-		rc = -ENOMEM;
-		goto err_alloc;
+		return -ENOMEM;
 	}
 	if (MACHINE_IS_VM)
 		rc = hypfs_vm_create_files(sb, root_dentry);
 	else
 		rc = hypfs_diag_create_files(sb, root_dentry);
 	if (rc)
-		goto err_tree;
+		return rc;
 	sbi->update_file = hypfs_create_update_file(sb, root_dentry);
-	if (IS_ERR(sbi->update_file)) {
-		rc = PTR_ERR(sbi->update_file);
-		goto err_tree;
-	}
+	if (IS_ERR(sbi->update_file))
+		return PTR_ERR(sbi->update_file);
 	hypfs_update_update(sb);
-	sb->s_root = root_dentry;
 	pr_info("Hypervisor filesystem mounted\n");
 	return 0;
-
-err_tree:
-	hypfs_delete_tree(root_dentry);
-	d_genocide(root_dentry);
-	dput(root_dentry);
-err_alloc:
-	kfree(sbi);
-	return rc;
 }
 
 static int hypfs_get_super(struct file_system_type *fst, int flags,
@@ -340,12 +324,12 @@ static void hypfs_kill_super(struct supe
 {
 	struct hypfs_sb_info *sb_info = sb->s_fs_info;
 
-	if (sb->s_root) {
+	if (sb->s_root)
 		hypfs_delete_tree(sb->s_root);
+	if (sb_info->update_file)
 		hypfs_remove(sb_info->update_file);
-		kfree(sb->s_fs_info);
-		sb->s_fs_info = NULL;
-	}
+	kfree(sb->s_fs_info);
+	sb->s_fs_info = NULL;
 	kill_litter_super(sb);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/atomic.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/atomic.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/atomic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/atomic.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,8 +18,6 @@
 
 #define ATOMIC_INIT(i)  { (i) }
 
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
-
 #define __CS_LOOP(ptr, op_val, op_string) ({				\
 	int old_val, new_val;						\
 	asm volatile(							\
@@ -35,26 +33,6 @@
 	new_val;							\
 })
 
-#else /* __GNUC__ */
-
-#define __CS_LOOP(ptr, op_val, op_string) ({				\
-	int old_val, new_val;						\
-	asm volatile(							\
-		"	l	%0,0(%3)\n"				\
-		"0:	lr	%1,%0\n"				\
-		op_string "	%1,%4\n"				\
-		"	cs	%0,%1,0(%3)\n"				\
-		"	jl	0b"					\
-		: "=&d" (old_val), "=&d" (new_val),			\
-		  "=m" (((atomic_t *)(ptr))->counter)			\
-		: "a" (ptr), "d" (op_val),				\
-		  "m" (((atomic_t *)(ptr))->counter)			\
-		: "cc", "memory");					\
-	new_val;							\
-})
-
-#endif /* __GNUC__ */
-
 static inline int atomic_read(const atomic_t *v)
 {
 	barrier();
@@ -101,19 +79,11 @@ static inline void atomic_set_mask(unsig
 
 static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
 {
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
 	asm volatile(
 		"	cs	%0,%2,%1"
 		: "+d" (old), "=Q" (v->counter)
 		: "d" (new), "Q" (v->counter)
 		: "cc", "memory");
-#else /* __GNUC__ */
-	asm volatile(
-		"	cs	%0,%3,0(%2)"
-		: "+d" (old), "=m" (v->counter)
-		: "a" (v), "d" (new), "m" (v->counter)
-		: "cc", "memory");
-#endif /* __GNUC__ */
 	return old;
 }
 
@@ -140,8 +110,6 @@ static inline int atomic_add_unless(atom
 
 #ifdef CONFIG_64BIT
 
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
-
 #define __CSG_LOOP(ptr, op_val, op_string) ({				\
 	long long old_val, new_val;					\
 	asm volatile(							\
@@ -157,26 +125,6 @@ static inline int atomic_add_unless(atom
 	new_val;							\
 })
 
-#else /* __GNUC__ */
-
-#define __CSG_LOOP(ptr, op_val, op_string) ({				\
-	long long old_val, new_val;					\
-	asm volatile(							\
-		"	lg	%0,0(%3)\n"				\
-		"0:	lgr	%1,%0\n"				\
-		op_string "	%1,%4\n"				\
-		"	csg	%0,%1,0(%3)\n"				\
-		"	jl	0b"					\
-		: "=&d" (old_val), "=&d" (new_val),			\
-		  "=m" (((atomic_t *)(ptr))->counter)			\
-		: "a" (ptr), "d" (op_val),				\
-		  "m" (((atomic_t *)(ptr))->counter)			\
-		: "cc", "memory");					\
-	new_val;							\
-})
-
-#endif /* __GNUC__ */
-
 static inline long long atomic64_read(const atomic64_t *v)
 {
 	barrier();
@@ -214,19 +162,11 @@ static inline void atomic64_set_mask(uns
 static inline long long atomic64_cmpxchg(atomic64_t *v,
 					     long long old, long long new)
 {
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
 	asm volatile(
 		"	csg	%0,%2,%1"
 		: "+d" (old), "=Q" (v->counter)
 		: "d" (new), "Q" (v->counter)
 		: "cc", "memory");
-#else /* __GNUC__ */
-	asm volatile(
-		"	csg	%0,%3,0(%2)"
-		: "+d" (old), "=m" (v->counter)
-		: "a" (v), "d" (new), "m" (v->counter)
-		: "cc", "memory");
-#endif /* __GNUC__ */
 	return old;
 }
 
@@ -243,10 +183,8 @@ static inline long long atomic64_read(co
 	register_pair rp;
 
 	asm volatile(
-		"	lm	%0,%N0,0(%1)"
-		: "=&d" (rp)
-		: "a" (&v->counter), "m" (v->counter)
-		);
+		"	lm	%0,%N0,%1"
+		: "=&d" (rp) : "Q" (v->counter)	);
 	return rp.pair;
 }
 
@@ -255,10 +193,8 @@ static inline void atomic64_set(atomic64
 	register_pair rp = {.pair = i};
 
 	asm volatile(
-		"	stm	%1,%N1,0(%2)"
-		: "=m" (v->counter)
-		: "d" (rp), "a" (&v->counter)
-		);
+		"	stm	%1,%N1,%0"
+		: "=Q" (v->counter) : "d" (rp) );
 }
 
 static inline long long atomic64_xchg(atomic64_t *v, long long new)
@@ -267,11 +203,11 @@ static inline long long atomic64_xchg(at
 	register_pair rp_old;
 
 	asm volatile(
-		"	lm	%0,%N0,0(%2)\n"
-		"0:	cds	%0,%3,0(%2)\n"
+		"	lm	%0,%N0,%1\n"
+		"0:	cds	%0,%2,%1\n"
 		"	jl	0b\n"
-		: "=&d" (rp_old), "+m" (v->counter)
-		: "a" (&v->counter), "d" (rp_new)
+		: "=&d" (rp_old), "=Q" (v->counter)
+		: "d" (rp_new), "Q" (v->counter)
 		: "cc");
 	return rp_old.pair;
 }
@@ -283,9 +219,9 @@ static inline long long atomic64_cmpxchg
 	register_pair rp_new = {.pair = new};
 
 	asm volatile(
-		"	cds	%0,%3,0(%2)"
-		: "+&d" (rp_old), "+m" (v->counter)
-		: "a" (&v->counter), "d" (rp_new)
+		"	cds	%0,%2,%1"
+		: "+&d" (rp_old), "=Q" (v->counter)
+		: "d" (rp_new), "Q" (v->counter)
 		: "cc");
 	return rp_old.pair;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/bitops.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/bitops.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/bitops.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/bitops.h	2010-05-16 17:17:36.000000000 -0400
@@ -71,8 +71,6 @@ extern const char _sb_findmap[];
 #define __BITOPS_AND		"nr"
 #define __BITOPS_XOR		"xr"
 
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
-
 #define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string)	\
 	asm volatile(						\
 		"	l	%0,%2\n"			\
@@ -85,22 +83,6 @@ extern const char _sb_findmap[];
 		: "d" (__val), "Q" (*(unsigned long *) __addr)	\
 		: "cc");
 
-#else /* __GNUC__ */
-
-#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string)	\
-	asm volatile(						\
-		"	l	%0,0(%4)\n"			\
-		"0:	lr	%1,%0\n"			\
-		__op_string "	%1,%3\n"			\
-		"	cs	%0,%1,0(%4)\n"			\
-		"	jl	0b"				\
-		: "=&d" (__old), "=&d" (__new),			\
-		  "=m" (*(unsigned long *) __addr)		\
-		: "d" (__val), "a" (__addr),			\
-		  "m" (*(unsigned long *) __addr) : "cc");
-
-#endif /* __GNUC__ */
-
 #else /* __s390x__ */
 
 #define __BITOPS_ALIGN		7
@@ -109,8 +91,6 @@ extern const char _sb_findmap[];
 #define __BITOPS_AND		"ngr"
 #define __BITOPS_XOR		"xgr"
 
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
-
 #define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string)	\
 	asm volatile(						\
 		"	lg	%0,%2\n"			\
@@ -123,23 +103,6 @@ extern const char _sb_findmap[];
 		: "d" (__val), "Q" (*(unsigned long *) __addr)	\
 		: "cc");
 
-#else /* __GNUC__ */
-
-#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string)	\
-	asm volatile(						\
-		"	lg	%0,0(%4)\n"			\
-		"0:	lgr	%1,%0\n"			\
-		__op_string "	%1,%3\n"			\
-		"	csg	%0,%1,0(%4)\n"			\
-		"	jl	0b"				\
-		: "=&d" (__old), "=&d" (__new),			\
-		  "=m" (*(unsigned long *) __addr)		\
-		: "d" (__val), "a" (__addr),			\
-		  "m" (*(unsigned long *) __addr) : "cc");
-
-
-#endif /* __GNUC__ */
-
 #endif /* __s390x__ */
 
 #define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE)
@@ -261,9 +224,8 @@ static inline void __set_bit(unsigned lo
 
 	addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
 	asm volatile(
-		"	oc	0(1,%1),0(%2)"
-		: "=m" (*(char *) addr) : "a" (addr),
-		  "a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" );
+		"	oc	%O0(1,%R0),%1"
+		: "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" );
 }
 
 static inline void 
@@ -290,9 +252,8 @@ __clear_bit(unsigned long nr, volatile u
 
 	addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
 	asm volatile(
-		"	nc	0(1,%1),0(%2)"
-		: "=m" (*(char *) addr)	: "a" (addr),
-		  "a" (_ni_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc");
+		"	nc	%O0(1,%R0),%1"
+		: "=Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7]) : "cc" );
 }
 
 static inline void 
@@ -318,9 +279,8 @@ static inline void __change_bit(unsigned
 
 	addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
 	asm volatile(
-		"	xc	0(1,%1),0(%2)"
-		:  "=m" (*(char *) addr) : "a" (addr),
-		   "a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" );
+		"	xc	%O0(1,%R0),%1"
+		: "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" );
 }
 
 static inline void 
@@ -349,10 +309,9 @@ test_and_set_bit_simple(unsigned long nr
 	addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
 	ch = *(unsigned char *) addr;
 	asm volatile(
-		"	oc	0(1,%1),0(%2)"
-		: "=m" (*(char *) addr)
-		: "a" (addr), "a" (_oi_bitmap + (nr & 7)),
-		  "m" (*(char *) addr) : "cc", "memory");
+		"	oc	%O0(1,%R0),%1"
+		: "=Q" (*(char *) addr)	: "Q" (_oi_bitmap[nr & 7])
+		: "cc", "memory");
 	return (ch >> (nr & 7)) & 1;
 }
 #define __test_and_set_bit(X,Y)		test_and_set_bit_simple(X,Y)
@@ -369,10 +328,9 @@ test_and_clear_bit_simple(unsigned long
 	addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
 	ch = *(unsigned char *) addr;
 	asm volatile(
-		"	nc	0(1,%1),0(%2)"
-		: "=m" (*(char *) addr)
-		: "a" (addr), "a" (_ni_bitmap + (nr & 7)),
-		  "m" (*(char *) addr) : "cc", "memory");
+		"	nc	%O0(1,%R0),%1"
+		: "=Q" (*(char *) addr)	: "Q" (_ni_bitmap[nr & 7])
+		: "cc", "memory");
 	return (ch >> (nr & 7)) & 1;
 }
 #define __test_and_clear_bit(X,Y)	test_and_clear_bit_simple(X,Y)
@@ -389,10 +347,9 @@ test_and_change_bit_simple(unsigned long
 	addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
 	ch = *(unsigned char *) addr;
 	asm volatile(
-		"	xc	0(1,%1),0(%2)"
-		: "=m" (*(char *) addr)
-		: "a" (addr), "a" (_oi_bitmap + (nr & 7)),
-		  "m" (*(char *) addr) : "cc", "memory");
+		"	xc	%O0(1,%R0),%1"
+		: "=Q" (*(char *) addr)	: "Q" (_oi_bitmap[nr & 7])
+		: "cc", "memory");
 	return (ch >> (nr & 7)) & 1;
 }
 #define __test_and_change_bit(X,Y)	test_and_change_bit_simple(X,Y)
@@ -591,11 +548,11 @@ static inline unsigned long __load_ulong
 	p = (unsigned long *)((unsigned long) p + offset);
 #ifndef __s390x__
 	asm volatile(
-		"	ic	%0,0(%1)\n"
-		"	icm	%0,2,1(%1)\n"
-		"	icm	%0,4,2(%1)\n"
-		"	icm	%0,8,3(%1)"
-		: "=&d" (word) : "a" (p), "m" (*p) : "cc");
+		"	ic	%0,%O1(%R1)\n"
+		"	icm	%0,2,%O1+1(%R1)\n"
+		"	icm	%0,4,%O1+2(%R1)\n"
+		"	icm	%0,8,%O1+3(%R1)"
+		: "=&d" (word) : "Q" (*p) : "cc");
 #else
 	asm volatile(
 		"	lrvg	%0,%1"
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/bug.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/bug.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/bug.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/bug.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,12 +5,6 @@
 
 #ifdef CONFIG_BUG
 
-#ifdef CONFIG_64BIT
-#define S390_LONG ".quad"
-#else
-#define S390_LONG ".long"
-#endif
-
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 
 #define __EMIT_BUG(x) do {					\
@@ -21,7 +15,7 @@
 		"2:	.asciz	\""__FILE__"\"\n"		\
 		".previous\n"					\
 		".section __bug_table,\"a\"\n"			\
-		"3:\t"	S390_LONG "\t1b,2b\n"			\
+		"3:	.long	1b-3b,2b-3b\n"			\
 		"	.short	%0,%1\n"			\
 		"	.org	3b+%2\n"			\
 		".previous\n"					\
@@ -37,7 +31,7 @@
 		"0:	j	0b+2\n"			\
 		"1:\n"					\
 		".section __bug_table,\"a\"\n"		\
-		"2:\t"	S390_LONG "\t1b\n"		\
+		"2:	.long	1b-2b\n"		\
 		"	.short	%0\n"			\
 		"	.org	2b+%1\n"		\
 		".previous\n"				\
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/cio.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/cio.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/cio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/cio.h	2010-05-16 17:17:36.000000000 -0400
@@ -20,7 +20,7 @@
 /**
  * struct ccw1 - channel command word
  * @cmd_code: command code
- * @flags: flags, like IDA adressing, etc.
+ * @flags: flags, like IDA addressing, etc.
  * @count: byte count
  * @cda: data address
  *
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/compat.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/compat.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/compat.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/compat.h	2010-05-16 17:17:36.000000000 -0400
@@ -35,7 +35,8 @@
 
 extern long psw32_user_bits;
 
-#define COMPAT_USER_HZ	100
+#define COMPAT_USER_HZ		100
+#define COMPAT_UTS_MACHINE	"s390\0\0\0\0"
 
 typedef u32		compat_size_t;
 typedef s32		compat_ssize_t;
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/crw.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/crw.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/crw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/crw.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@ typedef void (*crw_handler_t)(struct crw
 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);
+void crw_wait_for_channel_report(void);
 
 #define NR_RSCS 16
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/etr.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/etr.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/etr.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/etr.h	2010-05-16 17:17:36.000000000 -0400
@@ -145,11 +145,11 @@ static inline int etr_setr(struct etr_ea
 	int rc = -ENOSYS;
 
 	asm volatile(
-		"	.insn	s,0xb2160000,0(%2)\n"
+		"	.insn	s,0xb2160000,%1\n"
 		"0:	la	%0,0\n"
 		"1:\n"
 		EX_TABLE(0b,1b)
-		: "+d" (rc) : "m" (*ctrl), "a" (ctrl));
+		: "+d" (rc) : "Q" (*ctrl));
 	return rc;
 }
 
@@ -159,11 +159,11 @@ static inline int etr_stetr(struct etr_a
 	int rc = -ENOSYS;
 
 	asm volatile(
-		"	.insn	s,0xb2170000,0(%2)\n"
+		"	.insn	s,0xb2170000,%1\n"
 		"0:	la	%0,0\n"
 		"1:\n"
 		EX_TABLE(0b,1b)
-		: "+d" (rc) : "m" (*aib), "a" (aib));
+		: "+d" (rc) : "Q" (*aib));
 	return rc;
 }
 
@@ -174,11 +174,11 @@ static inline int etr_steai(struct etr_a
 	int rc = -ENOSYS;
 
 	asm volatile(
-		"	.insn	s,0xb2b30000,0(%2)\n"
+		"	.insn	s,0xb2b30000,%1\n"
 		"0:	la	%0,0\n"
 		"1:\n"
 		EX_TABLE(0b,1b)
-		: "+d" (rc) : "m" (*aib), "a" (aib), "d" (reg0));
+		: "+d" (rc) : "Q" (*aib), "d" (reg0));
 	return rc;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/irqflags.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/irqflags.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/irqflags.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/irqflags.h	2010-05-16 17:17:36.000000000 -0400
@@ -8,8 +8,6 @@
 
 #include <linux/types.h>
 
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
-
 /* store then or system mask. */
 #define __raw_local_irq_stosm(__or)					\
 ({									\
@@ -36,40 +34,6 @@
 	asm volatile("ssm   %0" : : "Q" (__mask) : "memory");		\
 })
 
-#else /* __GNUC__ */
-
-/* store then or system mask. */
-#define __raw_local_irq_stosm(__or)					\
-({									\
-	unsigned long __mask;						\
-	asm volatile(							\
-		"	stosm	0(%1),%2"				\
-		: "=m" (__mask)						\
-		: "a" (&__mask), "i" (__or) : "memory");		\
-	__mask;								\
-})
-
-/* store then and system mask. */
-#define __raw_local_irq_stnsm(__and)					\
-({									\
-	unsigned long __mask;						\
-	asm volatile(							\
-		"	stnsm	0(%1),%2"				\
-		: "=m" (__mask)						\
-		: "a" (&__mask), "i" (__and) : "memory");		\
-	__mask;								\
-})
-
-/* set system mask. */
-#define __raw_local_irq_ssm(__mask)					\
-({									\
-	asm volatile(							\
-		"	ssm	0(%0)"					\
-		: : "a" (&__mask), "m" (__mask) : "memory");		\
-})
-
-#endif /* __GNUC__ */
-
 /* interrupt control.. */
 static inline unsigned long raw_local_irq_enable(void)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/lowcore.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/lowcore.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/lowcore.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/lowcore.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,141 +1,16 @@
 /*
- *  include/asm-s390/lowcore.h
- *
- *  S390 version
- *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Hartmut Penner (hp@de.ibm.com),
- *               Martin Schwidefsky (schwidefsky@de.ibm.com),
- *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ *    Copyright IBM Corp. 1999,2010
+ *    Author(s): Hartmut Penner <hp@de.ibm.com>,
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *		 Denis Joseph Barrow,
  */
 
 #ifndef _ASM_S390_LOWCORE_H
 #define _ASM_S390_LOWCORE_H
 
-#define __LC_IPL_PARMBLOCK_PTR		0x0014
-#define __LC_EXT_PARAMS			0x0080
-#define __LC_CPU_ADDRESS		0x0084
-#define __LC_EXT_INT_CODE		0x0086
-
-#define __LC_SVC_ILC			0x0088
-#define __LC_SVC_INT_CODE		0x008a
-#define __LC_PGM_ILC			0x008c
-#define __LC_PGM_INT_CODE		0x008e
-
-#define __LC_PER_ATMID			0x0096
-#define __LC_PER_ADDRESS		0x0098
-#define __LC_PER_ACCESS_ID		0x00a1
-#define __LC_AR_MODE_ID			0x00a3
-
-#define __LC_SUBCHANNEL_ID		0x00b8
-#define __LC_SUBCHANNEL_NR		0x00ba
-#define __LC_IO_INT_PARM		0x00bc
-#define __LC_IO_INT_WORD		0x00c0
-#define __LC_STFL_FAC_LIST		0x00c8
-#define __LC_MCCK_CODE			0x00e8
-
-#define __LC_DUMP_REIPL			0x0e00
-
-#ifndef __s390x__
-#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_FTRACE_FUNC		0x02dc
-#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_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_RESTART_PSW		0x01a0
-#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_FTRACE_FUNC		0x0360
-#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_PSW_SAVE_AREA		0x1300
-#define __LC_PREFIX_SAVE_AREA		0x1318
-#define __LC_FP_CREG_SAVE_AREA		0x131c
-#define __LC_TODREG_SAVE_AREA		0x1324
-#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
-#endif /* __s390x__ */
-
-#ifndef __ASSEMBLY__
-
-#include <asm/cpu.h>
-#include <asm/ptrace.h>
 #include <linux/types.h>
+#include <asm/ptrace.h>
+#include <asm/cpu.h>
 
 void restart_int_handler(void);
 void ext_int_handler(void);
@@ -144,7 +19,12 @@ void pgm_check_handler(void);
 void mcck_int_handler(void);
 void io_int_handler(void);
 
-struct save_area_s390 {
+#ifdef CONFIG_32BIT
+
+#define LC_ORDER 0
+#define LC_PAGES 1
+
+struct save_area {
 	u32	ext_save;
 	u64	timer;
 	u64	clk_cmp;
@@ -156,54 +36,13 @@ struct save_area_s390 {
 	u64	fp_regs[4];
 	u32	gp_regs[16];
 	u32	ctrl_regs[16];
-}  __attribute__((packed));
-
-struct save_area_s390x {
-	u64	fp_regs[16];
-	u64	gp_regs[16];
-	u8	psw[16];
-	u8	pad1[8];
-	u32	pref_reg;
-	u32	fp_ctrl_reg;
-	u8	pad2[4];
-	u32	tod_reg;
-	u64	timer;
-	u64	clk_cmp;
-	u8	pad3[8];
-	u32	acc_regs[16];
-	u64	ctrl_regs[16];
-}  __attribute__((packed));
-
-union save_area {
-	struct save_area_s390	s390;
-	struct save_area_s390x	s390x;
-};
-
-#define SAVE_AREA_BASE_S390	0xd4
-#define SAVE_AREA_BASE_S390X	0x1200
-
-#ifndef __s390x__
-#define SAVE_AREA_SIZE sizeof(struct save_area_s390)
-#define SAVE_AREA_BASE SAVE_AREA_BASE_S390
-#else
-#define SAVE_AREA_SIZE sizeof(struct save_area_s390x)
-#define SAVE_AREA_BASE SAVE_AREA_BASE_S390X
-#endif
-
-#ifndef __s390x__
-#define LC_ORDER 0
-#else
-#define LC_ORDER 1
-#endif
-
-#define LC_PAGES (1UL << LC_ORDER)
+} __packed;
 
-struct _lowcore
-{
-#ifndef __s390x__
-	/* 0x0000 - 0x01ff: defined by architecture */
+struct _lowcore {
 	psw_t	restart_psw;			/* 0x0000 */
-	__u32	ccw2[4];			/* 0x0008 */
+	psw_t	restart_old_psw;		/* 0x0008 */
+	__u8	pad_0x0010[0x0014-0x0010];	/* 0x0010 */
+	__u32	ipl_parmblock_ptr;		/* 0x0014 */
 	psw_t	external_old_psw;		/* 0x0018 */
 	psw_t	svc_old_psw;			/* 0x0020 */
 	psw_t	program_old_psw;		/* 0x0028 */
@@ -229,7 +68,9 @@ struct _lowcore
 	__u32	monitor_code;			/* 0x009c */
 	__u8	exc_access_id;			/* 0x00a0 */
 	__u8	per_access_id;			/* 0x00a1 */
-	__u8	pad_0x00a2[0x00b8-0x00a2];	/* 0x00a2 */
+	__u8	op_access_id;			/* 0x00a2 */
+	__u8	ar_access_id;			/* 0x00a3 */
+	__u8	pad_0x00a4[0x00b8-0x00a4];	/* 0x00a4 */
 	__u16	subchannel_id;			/* 0x00b8 */
 	__u16	subchannel_nr;			/* 0x00ba */
 	__u32	io_int_parm;			/* 0x00bc */
@@ -245,8 +86,9 @@ struct _lowcore
 	__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	psw_save_area;			/* 0x0100 */
+	__u32	prefixreg_save_area;		/* 0x0108 */
+	__u8	pad_0x010c[0x0120-0x010c];	/* 0x010c */
 
 	/* CPU register save area: defined by architecture */
 	__u32	access_regs_save_area[16];	/* 0x0120 */
@@ -310,10 +152,32 @@ struct _lowcore
 
 	/* Align to the top 1k of prefix area */
 	__u8	pad_0x0e08[0x1000-0x0e08];	/* 0x0e08 */
-#else /* !__s390x__ */
-	/* 0x0000 - 0x01ff: defined by architecture */
-	__u32	ccw1[2];			/* 0x0000 */
-	__u32	ccw2[4];			/* 0x0008 */
+} __packed;
+
+#else /* CONFIG_32BIT */
+
+#define LC_ORDER 1
+#define LC_PAGES 2
+
+struct save_area {
+	u64	fp_regs[16];
+	u64	gp_regs[16];
+	u8	psw[16];
+	u8	pad1[8];
+	u32	pref_reg;
+	u32	fp_ctrl_reg;
+	u8	pad2[4];
+	u32	tod_reg;
+	u64	timer;
+	u64	clk_cmp;
+	u8	pad3[8];
+	u32	acc_regs[16];
+	u64	ctrl_regs[16];
+} __packed;
+
+struct _lowcore {
+	__u8	pad_0x0000[0x0014-0x0000];	/* 0x0000 */
+	__u32	ipl_parmblock_ptr;		/* 0x0014 */
 	__u8	pad_0x0018[0x0080-0x0018];	/* 0x0018 */
 	__u32	ext_params;			/* 0x0080 */
 	__u16	cpu_addr;			/* 0x0084 */
@@ -344,7 +208,9 @@ struct _lowcore
 	__u8	pad_0x00f0[0x00f4-0x00f0];	/* 0x00f0 */
 	__u32	external_damage_code;		/* 0x00f4 */
 	addr_t	failing_storage_address;	/* 0x00f8 */
-	__u8	pad_0x0100[0x0120-0x0100];	/* 0x0100 */
+	__u8	pad_0x0100[0x0110-0x0100];	/* 0x0100 */
+	__u64	breaking_event_addr;		/* 0x0110 */
+	__u8	pad_0x0118[0x0120-0x0118];	/* 0x0118 */
 	psw_t	restart_old_psw;		/* 0x0120 */
 	psw_t	external_old_psw;		/* 0x0130 */
 	psw_t	svc_old_psw;			/* 0x0140 */
@@ -425,7 +291,7 @@ struct _lowcore
 	/* 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 */
+	psw_t	psw_save_area;			/* 0x1300 */
 	__u8	pad_0x1310[0x1318-0x1310];	/* 0x1310 */
 	__u32	prefixreg_save_area;		/* 0x1318 */
 	__u32	fpt_creg_save_area;		/* 0x131c */
@@ -439,10 +305,12 @@ struct _lowcore
 
 	/* align to the top of the prefix area */
 	__u8	pad_0x1400[0x2000-0x1400];	/* 0x1400 */
-#endif /* !__s390x__ */
-} __attribute__((packed)); /* End structure*/
+} __packed;
+
+#endif /* CONFIG_32BIT */
 
 #define S390_lowcore (*((struct _lowcore *) 0))
+
 extern struct _lowcore *lowcore_ptr[];
 
 static inline void set_prefix(__u32 address)
@@ -458,6 +326,4 @@ static inline __u32 store_prefix(void)
 	return address;
 }
 
-#endif
-
-#endif
+#endif /* _ASM_S390_LOWCORE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/page.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/page.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/page.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/page.h	2010-05-16 17:17:36.000000000 -0400
@@ -107,9 +107,6 @@ typedef pte_t *pgtable_t;
 #define __pgd(x)        ((pgd_t) { (x) } )
 #define __pgprot(x)     ((pgprot_t) { (x) } )
 
-/* default storage key used for all pages */
-extern unsigned int default_storage_key;
-
 static inline void
 page_set_storage_key(unsigned long addr, unsigned int skey)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/pgtable.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/pgtable.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -43,7 +43,7 @@ extern void vmem_map_init(void);
  * The S390 doesn't have any external MMU info: the kernel page
  * tables contain all the necessary information.
  */
-#define update_mmu_cache(vma, address, pte)     do { } while (0)
+#define update_mmu_cache(vma, address, ptep)     do { } while (0)
 
 /*
  * ZERO_PAGE is a global shared page that is always zero: used
@@ -105,7 +105,7 @@ extern char empty_zero_page[PAGE_SIZE];
 #ifndef __ASSEMBLY__
 /*
  * The vmalloc area will always be on the topmost area of the kernel
- * mapping. We reserve 96MB (31bit) / 1GB (64bit) for vmalloc,
+ * mapping. We reserve 96MB (31bit) / 128GB (64bit) for vmalloc,
  * which should be enough for any sane case.
  * By putting vmalloc at the top, we maximise the gap between physical
  * memory and vmalloc to catch misplaced memory accesses. As a side
@@ -120,8 +120,8 @@ extern unsigned long VMALLOC_START;
 #define VMALLOC_END	0x7e000000UL
 #define VMEM_MAP_END	0x80000000UL
 #else /* __s390x__ */
-#define VMALLOC_SIZE	(1UL << 30)
-#define VMALLOC_END	0x3e040000000UL
+#define VMALLOC_SIZE	(128UL << 30)
+#define VMALLOC_END	0x3e000000000UL
 #define VMEM_MAP_END	0x40000000000UL
 #endif /* __s390x__ */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/processor.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/processor.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/processor.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/processor.h	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,7 @@
 
 static inline void get_cpu_id(struct cpuid *ptr)
 {
-	asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr));
+	asm volatile("stidp %0" : "=Q" (*ptr));
 }
 
 extern void s390_adjust_jiffies(void);
@@ -184,9 +184,9 @@ static inline void psw_set_key(unsigned
 static inline void __load_psw(psw_t psw)
 {
 #ifndef __s390x__
-	asm volatile("lpsw  0(%0)" : : "a" (&psw), "m" (psw) : "cc");
+	asm volatile("lpsw  %0" : : "Q" (psw) : "cc");
 #else
-	asm volatile("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc");
+	asm volatile("lpswe %0" : : "Q" (psw) : "cc");
 #endif
 }
 
@@ -206,17 +206,17 @@ static inline void __load_psw_mask (unsi
 	asm volatile(
 		"	basr	%0,0\n"
 		"0:	ahi	%0,1f-0b\n"
-		"	st	%0,4(%1)\n"
-		"	lpsw	0(%1)\n"
+		"	st	%0,%O1+4(%R1)\n"
+		"	lpsw	%1\n"
 		"1:"
-		: "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc");
+		: "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc");
 #else /* __s390x__ */
 	asm volatile(
 		"	larl	%0,1f\n"
-		"	stg	%0,8(%1)\n"
-		"	lpswe	0(%1)\n"
+		"	stg	%0,%O1+8(%R1)\n"
+		"	lpswe	%1\n"
 		"1:"
-		: "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc");
+		: "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc");
 #endif /* __s390x__ */
 }
  
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -489,16 +489,24 @@ struct user_regs_struct
  * These are defined as per linux/ptrace.h, which see.
  */
 #define arch_has_single_step()	(1)
-struct task_struct;
-extern void user_enable_single_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
+extern void show_regs(struct pt_regs * regs);
 
 #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
 #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
 #define user_stack_pointer(regs)((regs)->gprs[15])
 #define regs_return_value(regs)((regs)->gprs[2])
 #define profile_pc(regs) instruction_pointer(regs)
-extern void show_regs(struct pt_regs * regs);
+
+int regs_query_register_offset(const char *name);
+const char *regs_query_register_name(unsigned int offset);
+unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset);
+unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n);
+
+static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
+{
+	return regs->gprs[15] & PSW_ADDR_INSN;
+}
+
 #endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/qdio.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/qdio.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/qdio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/qdio.h	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,8 @@
 #include <asm/cio.h>
 #include <asm/ccwdev.h>
 
-#define QDIO_MAX_QUEUES_PER_IRQ		32
+/* only use 4 queues to save some cachelines */
+#define QDIO_MAX_QUEUES_PER_IRQ		4
 #define QDIO_MAX_BUFFERS_PER_Q		128
 #define QDIO_MAX_BUFFERS_MASK		(QDIO_MAX_BUFFERS_PER_Q - 1)
 #define QDIO_MAX_ELEMENTS_PER_BUFFER	16
@@ -320,11 +321,6 @@ typedef void qdio_handler_t(struct ccw_d
 #define QDIO_ERROR_ACTIVATE_CHECK_CONDITION	0x40
 #define QDIO_ERROR_SLSB_STATE			0x80
 
-/* for qdio_initialize */
-#define QDIO_INBOUND_0COPY_SBALS		0x01
-#define QDIO_OUTBOUND_0COPY_SBALS		0x02
-#define QDIO_USE_OUTBOUND_PCIS			0x04
-
 /* for qdio_cleanup */
 #define QDIO_FLAG_CLEANUP_USING_CLEAR		0x01
 #define QDIO_FLAG_CLEANUP_USING_HALT		0x02
@@ -343,7 +339,6 @@ typedef void qdio_handler_t(struct ccw_d
  * @input_handler: handler to be called for input queues
  * @output_handler: handler to be called for output queues
  * @int_parm: interruption parameter
- * @flags: initialization flags
  * @input_sbal_addr_array:  address of no_input_qs * 128 pointers
  * @output_sbal_addr_array: address of no_output_qs * 128 pointers
  */
@@ -360,7 +355,6 @@ struct qdio_initialize {
 	qdio_handler_t *input_handler;
 	qdio_handler_t *output_handler;
 	unsigned long int_parm;
-	unsigned long flags;
 	void **input_sbal_addr_array;
 	void **output_sbal_addr_array;
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/rwsem.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/rwsem.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/rwsem.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/rwsem.h	2010-05-16 17:17:36.000000000 -0400
@@ -124,21 +124,21 @@ static inline void __down_read(struct rw
 
 	asm volatile(
 #ifndef __s390x__
-		"	l	%0,0(%3)\n"
+		"	l	%0,%2\n"
 		"0:	lr	%1,%0\n"
-		"	ahi	%1,%5\n"
-		"	cs	%0,%1,0(%3)\n"
+		"	ahi	%1,%4\n"
+		"	cs	%0,%1,%2\n"
 		"	jl	0b"
 #else /* __s390x__ */
-		"	lg	%0,0(%3)\n"
+		"	lg	%0,%2\n"
 		"0:	lgr	%1,%0\n"
-		"	aghi	%1,%5\n"
-		"	csg	%0,%1,0(%3)\n"
+		"	aghi	%1,%4\n"
+		"	csg	%0,%1,%2\n"
 		"	jl	0b"
 #endif /* __s390x__ */
-		: "=&d" (old), "=&d" (new), "=m" (sem->count)
-		: "a" (&sem->count), "m" (sem->count),
-		  "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory");
+		: "=&d" (old), "=&d" (new), "=Q" (sem->count)
+		: "Q" (sem->count), "i" (RWSEM_ACTIVE_READ_BIAS)
+		: "cc", "memory");
 	if (old < 0)
 		rwsem_down_read_failed(sem);
 }
@@ -152,25 +152,25 @@ static inline int __down_read_trylock(st
 
 	asm volatile(
 #ifndef __s390x__
-		"	l	%0,0(%3)\n"
+		"	l	%0,%2\n"
 		"0:	ltr	%1,%0\n"
 		"	jm	1f\n"
-		"	ahi	%1,%5\n"
-		"	cs	%0,%1,0(%3)\n"
+		"	ahi	%1,%4\n"
+		"	cs	%0,%1,%2\n"
 		"	jl	0b\n"
 		"1:"
 #else /* __s390x__ */
-		"	lg	%0,0(%3)\n"
+		"	lg	%0,%2\n"
 		"0:	ltgr	%1,%0\n"
 		"	jm	1f\n"
-		"	aghi	%1,%5\n"
-		"	csg	%0,%1,0(%3)\n"
+		"	aghi	%1,%4\n"
+		"	csg	%0,%1,%2\n"
 		"	jl	0b\n"
 		"1:"
 #endif /* __s390x__ */
-		: "=&d" (old), "=&d" (new), "=m" (sem->count)
-		: "a" (&sem->count), "m" (sem->count),
-		  "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory");
+		: "=&d" (old), "=&d" (new), "=Q" (sem->count)
+		: "Q" (sem->count), "i" (RWSEM_ACTIVE_READ_BIAS)
+		: "cc", "memory");
 	return old >= 0 ? 1 : 0;
 }
 
@@ -184,20 +184,20 @@ static inline void __down_write_nested(s
 	tmp = RWSEM_ACTIVE_WRITE_BIAS;
 	asm volatile(
 #ifndef __s390x__
-		"	l	%0,0(%3)\n"
+		"	l	%0,%2\n"
 		"0:	lr	%1,%0\n"
-		"	a	%1,%5\n"
-		"	cs	%0,%1,0(%3)\n"
+		"	a	%1,%4\n"
+		"	cs	%0,%1,%2\n"
 		"	jl	0b"
 #else /* __s390x__ */
-		"	lg	%0,0(%3)\n"
+		"	lg	%0,%2\n"
 		"0:	lgr	%1,%0\n"
-		"	ag	%1,%5\n"
-		"	csg	%0,%1,0(%3)\n"
+		"	ag	%1,%4\n"
+		"	csg	%0,%1,%2\n"
 		"	jl	0b"
 #endif /* __s390x__ */
-		: "=&d" (old), "=&d" (new), "=m" (sem->count)
-		: "a" (&sem->count), "m" (sem->count), "m" (tmp)
+		: "=&d" (old), "=&d" (new), "=Q" (sem->count)
+		: "Q" (sem->count), "m" (tmp)
 		: "cc", "memory");
 	if (old != 0)
 		rwsem_down_write_failed(sem);
@@ -217,22 +217,22 @@ static inline int __down_write_trylock(s
 
 	asm volatile(
 #ifndef __s390x__
-		"	l	%0,0(%2)\n"
+		"	l	%0,%1\n"
 		"0:	ltr	%0,%0\n"
 		"	jnz	1f\n"
-		"	cs	%0,%4,0(%2)\n"
+		"	cs	%0,%3,%1\n"
 		"	jl	0b\n"
 #else /* __s390x__ */
-		"	lg	%0,0(%2)\n"
+		"	lg	%0,%1\n"
 		"0:	ltgr	%0,%0\n"
 		"	jnz	1f\n"
-		"	csg	%0,%4,0(%2)\n"
+		"	csg	%0,%3,%1\n"
 		"	jl	0b\n"
 #endif /* __s390x__ */
 		"1:"
-		: "=&d" (old), "=m" (sem->count)
-		: "a" (&sem->count), "m" (sem->count),
-		  "d" (RWSEM_ACTIVE_WRITE_BIAS) : "cc", "memory");
+		: "=&d" (old), "=Q" (sem->count)
+		: "Q" (sem->count), "d" (RWSEM_ACTIVE_WRITE_BIAS)
+		: "cc", "memory");
 	return (old == RWSEM_UNLOCKED_VALUE) ? 1 : 0;
 }
 
@@ -245,21 +245,20 @@ static inline void __up_read(struct rw_s
 
 	asm volatile(
 #ifndef __s390x__
-		"	l	%0,0(%3)\n"
+		"	l	%0,%2\n"
 		"0:	lr	%1,%0\n"
-		"	ahi	%1,%5\n"
-		"	cs	%0,%1,0(%3)\n"
+		"	ahi	%1,%4\n"
+		"	cs	%0,%1,%2\n"
 		"	jl	0b"
 #else /* __s390x__ */
-		"	lg	%0,0(%3)\n"
+		"	lg	%0,%2\n"
 		"0:	lgr	%1,%0\n"
-		"	aghi	%1,%5\n"
-		"	csg	%0,%1,0(%3)\n"
+		"	aghi	%1,%4\n"
+		"	csg	%0,%1,%2\n"
 		"	jl	0b"
 #endif /* __s390x__ */
-		: "=&d" (old), "=&d" (new), "=m" (sem->count)
-		: "a" (&sem->count), "m" (sem->count),
-		  "i" (-RWSEM_ACTIVE_READ_BIAS)
+		: "=&d" (old), "=&d" (new), "=Q" (sem->count)
+		: "Q" (sem->count), "i" (-RWSEM_ACTIVE_READ_BIAS)
 		: "cc", "memory");
 	if (new < 0)
 		if ((new & RWSEM_ACTIVE_MASK) == 0)
@@ -276,20 +275,20 @@ static inline void __up_write(struct rw_
 	tmp = -RWSEM_ACTIVE_WRITE_BIAS;
 	asm volatile(
 #ifndef __s390x__
-		"	l	%0,0(%3)\n"
+		"	l	%0,%2\n"
 		"0:	lr	%1,%0\n"
-		"	a	%1,%5\n"
-		"	cs	%0,%1,0(%3)\n"
+		"	a	%1,%4\n"
+		"	cs	%0,%1,%2\n"
 		"	jl	0b"
 #else /* __s390x__ */
-		"	lg	%0,0(%3)\n"
+		"	lg	%0,%2\n"
 		"0:	lgr	%1,%0\n"
-		"	ag	%1,%5\n"
-		"	csg	%0,%1,0(%3)\n"
+		"	ag	%1,%4\n"
+		"	csg	%0,%1,%2\n"
 		"	jl	0b"
 #endif /* __s390x__ */
-		: "=&d" (old), "=&d" (new), "=m" (sem->count)
-		: "a" (&sem->count), "m" (sem->count), "m" (tmp)
+		: "=&d" (old), "=&d" (new), "=Q" (sem->count)
+		: "Q" (sem->count), "m" (tmp)
 		: "cc", "memory");
 	if (new < 0)
 		if ((new & RWSEM_ACTIVE_MASK) == 0)
@@ -306,20 +305,20 @@ static inline void __downgrade_write(str
 	tmp = -RWSEM_WAITING_BIAS;
 	asm volatile(
 #ifndef __s390x__
-		"	l	%0,0(%3)\n"
+		"	l	%0,%2\n"
 		"0:	lr	%1,%0\n"
-		"	a	%1,%5\n"
-		"	cs	%0,%1,0(%3)\n"
+		"	a	%1,%4\n"
+		"	cs	%0,%1,%2\n"
 		"	jl	0b"
 #else /* __s390x__ */
-		"	lg	%0,0(%3)\n"
+		"	lg	%0,%2\n"
 		"0:	lgr	%1,%0\n"
-		"	ag	%1,%5\n"
-		"	csg	%0,%1,0(%3)\n"
+		"	ag	%1,%4\n"
+		"	csg	%0,%1,%2\n"
 		"	jl	0b"
 #endif /* __s390x__ */
-		: "=&d" (old), "=&d" (new), "=m" (sem->count)
-		: "a" (&sem->count), "m" (sem->count), "m" (tmp)
+		: "=&d" (old), "=&d" (new), "=Q" (sem->count)
+		: "Q" (sem->count), "m" (tmp)
 		: "cc", "memory");
 	if (new > 1)
 		rwsem_downgrade_wake(sem);
@@ -334,20 +333,20 @@ static inline void rwsem_atomic_add(long
 
 	asm volatile(
 #ifndef __s390x__
-		"	l	%0,0(%3)\n"
+		"	l	%0,%2\n"
 		"0:	lr	%1,%0\n"
-		"	ar	%1,%5\n"
-		"	cs	%0,%1,0(%3)\n"
+		"	ar	%1,%4\n"
+		"	cs	%0,%1,%2\n"
 		"	jl	0b"
 #else /* __s390x__ */
-		"	lg	%0,0(%3)\n"
+		"	lg	%0,%2\n"
 		"0:	lgr	%1,%0\n"
-		"	agr	%1,%5\n"
-		"	csg	%0,%1,0(%3)\n"
+		"	agr	%1,%4\n"
+		"	csg	%0,%1,%2\n"
 		"	jl	0b"
 #endif /* __s390x__ */
-		: "=&d" (old), "=&d" (new), "=m" (sem->count)
-		: "a" (&sem->count), "m" (sem->count), "d" (delta)
+		: "=&d" (old), "=&d" (new), "=Q" (sem->count)
+		: "Q" (sem->count), "d" (delta)
 		: "cc", "memory");
 }
 
@@ -360,20 +359,20 @@ static inline long rwsem_atomic_update(l
 
 	asm volatile(
 #ifndef __s390x__
-		"	l	%0,0(%3)\n"
+		"	l	%0,%2\n"
 		"0:	lr	%1,%0\n"
-		"	ar	%1,%5\n"
-		"	cs	%0,%1,0(%3)\n"
+		"	ar	%1,%4\n"
+		"	cs	%0,%1,%2\n"
 		"	jl	0b"
 #else /* __s390x__ */
-		"	lg	%0,0(%3)\n"
+		"	lg	%0,%2\n"
 		"0:	lgr	%1,%0\n"
-		"	agr	%1,%5\n"
-		"	csg	%0,%1,0(%3)\n"
+		"	agr	%1,%4\n"
+		"	csg	%0,%1,%2\n"
 		"	jl	0b"
 #endif /* __s390x__ */
-		: "=&d" (old), "=&d" (new), "=m" (sem->count)
-		: "a" (&sem->count), "m" (sem->count), "d" (delta)
+		: "=&d" (old), "=&d" (new), "=Q" (sem->count)
+		: "Q" (sem->count), "d" (delta)
 		: "cc", "memory");
 	return new;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/setup.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/setup.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/setup.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/setup.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,14 +14,14 @@
 
 #ifdef __KERNEL__
 
-#include <asm/lowcore.h>
-#include <asm/types.h>
-
 #define PARMAREA		0x10400
 #define MEMORY_CHUNKS		256
 
 #ifndef __ASSEMBLY__
 
+#include <asm/lowcore.h>
+#include <asm/types.h>
+
 #ifndef __s390x__
 #define IPL_DEVICE        (*(unsigned long *)  (0x10404))
 #define INITRD_START      (*(unsigned long *)  (0x1040C))
@@ -71,9 +71,12 @@ extern unsigned int user_mode;
 #define MACHINE_FLAG_KVM	(1UL << 9)
 #define MACHINE_FLAG_HPAGE	(1UL << 10)
 #define MACHINE_FLAG_PFMF	(1UL << 11)
+#define MACHINE_FLAG_LPAR	(1UL << 12)
 
 #define MACHINE_IS_VM		(S390_lowcore.machine_flags & MACHINE_FLAG_VM)
 #define MACHINE_IS_KVM		(S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
+#define MACHINE_IS_LPAR		(S390_lowcore.machine_flags & MACHINE_FLAG_LPAR)
+
 #define MACHINE_HAS_DIAG9C	(S390_lowcore.machine_flags & MACHINE_FLAG_DIAG9C)
 
 #ifndef __s390x__
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/sigp.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/sigp.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/sigp.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/sigp.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,24 +1,19 @@
 /*
- *  include/asm-s390/sigp.h
- *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
- *               Martin Schwidefsky (schwidefsky@de.ibm.com)
- *               Heiko Carstens (heiko.carstens@de.ibm.com)
+ *  Routines and structures for signalling other processors.
  *
- *  sigp.h by D.J. Barrow (c) IBM 1999
- *  contains routines / structures for signalling other S/390 processors in an
- *  SMP configuration.
+ *    Copyright IBM Corp. 1999,2010
+ *    Author(s): Denis Joseph Barrow,
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *		 Heiko Carstens <heiko.carstens@de.ibm.com>,
  */
 
-#ifndef __SIGP__
-#define __SIGP__
+#ifndef __ASM_SIGP_H
+#define __ASM_SIGP_H
 
 #include <asm/system.h>
 
-/* get real cpu address from logical cpu number */
-extern int __cpu_logical_map[];
+/* Get real cpu address from logical cpu number. */
+extern unsigned short __cpu_logical_map[];
 
 static inline int cpu_logical_map(int cpu)
 {
@@ -29,107 +24,108 @@ static inline int cpu_logical_map(int cp
 #endif
 }
 
-typedef enum
-{
-	sigp_unassigned=0x0,
-	sigp_sense,
-	sigp_external_call,
-	sigp_emergency_signal,
-	sigp_start,
-	sigp_stop,
-	sigp_restart,
-	sigp_unassigned1,
-	sigp_unassigned2,
-	sigp_stop_and_store_status,
-	sigp_unassigned3,
-	sigp_initial_cpu_reset,
-	sigp_cpu_reset,
-	sigp_set_prefix,
-	sigp_store_status_at_address,
-	sigp_store_extended_status_at_address
-} sigp_order_code;
-
-typedef __u32 sigp_status_word;
-
-typedef enum
-{
-        sigp_order_code_accepted=0,
-	sigp_status_stored,
-	sigp_busy,
-	sigp_not_operational
-} sigp_ccode;
+enum {
+	sigp_sense = 1,
+	sigp_external_call = 2,
+	sigp_emergency_signal = 3,
+	sigp_start = 4,
+	sigp_stop = 5,
+	sigp_restart = 6,
+	sigp_stop_and_store_status = 9,
+	sigp_initial_cpu_reset = 11,
+	sigp_cpu_reset = 12,
+	sigp_set_prefix = 13,
+	sigp_store_status_at_address = 14,
+	sigp_store_extended_status_at_address = 15,
+	sigp_set_architecture = 18,
+	sigp_conditional_emergency_signal = 19,
+	sigp_sense_running = 21,
+};
 
+enum {
+	sigp_order_code_accepted = 0,
+	sigp_status_stored = 1,
+	sigp_busy = 2,
+	sigp_not_operational = 3,
+};
 
 /*
- * Definitions for the external call
+ * Definitions for external call.
  */
-
-/* 'Bit' signals, asynchronous */
-typedef enum
-{
-	ec_schedule=0,
+enum {
+	ec_schedule = 0,
 	ec_call_function,
 	ec_call_function_single,
-	ec_bit_last
-} ec_bit_sig;
+};
 
 /*
- * Signal processor
+ * Signal processor.
  */
-static inline sigp_ccode
-signal_processor(__u16 cpu_addr, sigp_order_code order_code)
+static inline int raw_sigp(u16 cpu, int order)
 {
 	register unsigned long reg1 asm ("1") = 0;
-	sigp_ccode ccode;
+	int ccode;
 
 	asm volatile(
 		"	sigp	%1,%2,0(%3)\n"
 		"	ipm	%0\n"
 		"	srl	%0,28\n"
 		:	"=d"	(ccode)
-		: "d" (reg1), "d" (cpu_logical_map(cpu_addr)),
-		  "a" (order_code) : "cc" , "memory");
+		: "d" (reg1), "d" (cpu),
+		  "a" (order) : "cc" , "memory");
 	return ccode;
 }
 
 /*
- * Signal processor with parameter
+ * Signal processor with parameter.
  */
-static inline sigp_ccode
-signal_processor_p(__u32 parameter, __u16 cpu_addr, sigp_order_code order_code)
+static inline int raw_sigp_p(u32 parameter, u16 cpu, int order)
 {
 	register unsigned int reg1 asm ("1") = parameter;
-	sigp_ccode ccode;
+	int ccode;
 
 	asm volatile(
 		"	sigp	%1,%2,0(%3)\n"
 		"	ipm	%0\n"
 		"	srl	%0,28\n"
 		: "=d" (ccode)
-		: "d" (reg1), "d" (cpu_logical_map(cpu_addr)),
-		  "a" (order_code) : "cc" , "memory");
+		: "d" (reg1), "d" (cpu),
+		  "a" (order) : "cc" , "memory");
 	return ccode;
 }
 
 /*
- * Signal processor with parameter and return status
+ * Signal processor with parameter and return status.
  */
-static inline sigp_ccode
-signal_processor_ps(__u32 *statusptr, __u32 parameter, __u16 cpu_addr,
-		    sigp_order_code order_code)
+static inline int raw_sigp_ps(u32 *status, u32 parm, u16 cpu, int order)
 {
-	register unsigned int reg1 asm ("1") = parameter;
-	sigp_ccode ccode;
+	register unsigned int reg1 asm ("1") = parm;
+	int ccode;
 
 	asm volatile(
 		"	sigp	%1,%2,0(%3)\n"
 		"	ipm	%0\n"
 		"	srl	%0,28\n"
 		: "=d" (ccode), "+d" (reg1)
-		: "d" (cpu_logical_map(cpu_addr)), "a" (order_code)
+		: "d" (cpu), "a" (order)
 		: "cc" , "memory");
-	*statusptr = reg1;
+	*status = reg1;
 	return ccode;
 }
 
-#endif /* __SIGP__ */
+static inline int sigp(int cpu, int order)
+{
+	return raw_sigp(cpu_logical_map(cpu), order);
+}
+
+static inline int sigp_p(u32 parameter, int cpu, int order)
+{
+	return raw_sigp_p(parameter, cpu_logical_map(cpu), order);
+}
+
+static inline int sigp_ps(u32 *status, u32 parm, int cpu, int order)
+{
+	return raw_sigp_ps(status, parm, cpu_logical_map(cpu), order);
+}
+
+#endif /* __ASM_SIGP_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/smp.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/smp.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/smp.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/smp.h	2010-05-16 17:17:36.000000000 -0400
@@ -29,7 +29,43 @@ extern int smp_cpu_polarization[];
 extern void arch_send_call_function_single_ipi(int cpu);
 extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
 
-extern union save_area *zfcpdump_save_areas[NR_CPUS + 1];
+extern struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
+
+extern void smp_switch_to_ipl_cpu(void (*func)(void *), void *);
+extern void smp_switch_to_cpu(void (*)(void *), void *, unsigned long sp,
+			      int from, int to);
+extern void smp_restart_cpu(void);
+
+/*
+ * returns 1 if (virtual) cpu is scheduled
+ * returns 0 otherwise
+ */
+static inline int smp_vcpu_scheduled(int cpu)
+{
+	u32 status;
+
+	switch (sigp_ps(&status, 0, cpu, sigp_sense_running)) {
+	case sigp_status_stored:
+		/* Check for running status */
+		if (status & 0x400)
+			return 0;
+		break;
+	case sigp_not_operational:
+		return 0;
+	default:
+		break;
+	}
+	return 1;
+}
+
+#else /* CONFIG_SMP */
+
+static inline void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
+{
+	func(data);
+}
+
+#define smp_vcpu_scheduled	(1)
 
 #endif /* CONFIG_SMP */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/spinlock.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/spinlock.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/spinlock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/spinlock.h	2010-05-16 17:17:36.000000000 -0400
@@ -13,8 +13,6 @@
 
 #include <linux/smp.h>
 
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
-
 static inline int
 _raw_compare_and_swap(volatile unsigned int *lock,
 		      unsigned int old, unsigned int new)
@@ -27,22 +25,6 @@ _raw_compare_and_swap(volatile unsigned
 	return old;
 }
 
-#else /* __GNUC__ */
-
-static inline int
-_raw_compare_and_swap(volatile unsigned int *lock,
-		      unsigned int old, unsigned int new)
-{
-	asm volatile(
-		"	cs	%0,%3,0(%4)"
-		: "=d" (old), "=m" (*lock)
-		: "0" (old), "d" (new), "a" (lock), "m" (*lock)
-		: "cc", "memory" );
-	return old;
-}
-
-#endif /* __GNUC__ */
-
 /*
  * Simple spin lock operations.  There are two variants, one clears IRQ's
  * on the local processor, one does not.
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/swab.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/swab.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/swab.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/swab.h	2010-05-16 17:17:36.000000000 -0400
@@ -47,11 +47,11 @@ static inline __u32 __arch_swab32p(const
 	
 	asm volatile(
 #ifndef __s390x__
-		"	icm	%0,8,3(%1)\n"
-		"	icm	%0,4,2(%1)\n"
-		"	icm	%0,2,1(%1)\n"
-		"	ic	%0,0(%1)"
-		: "=&d" (result) : "a" (x), "m" (*x) : "cc");
+		"	icm	%0,8,%O1+3(%R1)\n"
+		"	icm	%0,4,%O1+2(%R1)\n"
+		"	icm	%0,2,%O1+1(%R1)\n"
+		"	ic	%0,%1"
+		: "=&d" (result) : "Q" (*x) : "cc");
 #else /* __s390x__ */
 		"	lrv	%0,%1"
 		: "=d" (result) : "m" (*x));
@@ -77,9 +77,9 @@ static inline __u16 __arch_swab16p(const
 	
 	asm volatile(
 #ifndef __s390x__
-		"	icm	%0,2,1(%1)\n"
-		"	ic	%0,0(%1)\n"
-		: "=&d" (result) : "a" (x), "m" (*x) : "cc");
+		"	icm	%0,2,%O+1(%R1)\n"
+		"	ic	%0,%1\n"
+		: "=&d" (result) : "Q" (*x) : "cc");
 #else /* __s390x__ */
 		"	lrvh	%0,%1"
 		: "=d" (result) : "m" (*x));
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/syscall.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/syscall.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/syscall.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/syscall.h	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,13 @@
 #include <linux/sched.h>
 #include <asm/ptrace.h>
 
+/*
+ * The syscall table always contains 32 bit pointers since we know that the
+ * address of the function to be called is (way) below 4GB.  So the "int"
+ * type here is what we want [need] for both 32 bit and 64 bit systems.
+ */
+extern const unsigned int sys_call_table[];
+
 static inline long syscall_get_nr(struct task_struct *task,
 				  struct pt_regs *regs)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/sysinfo.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/sysinfo.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/sysinfo.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/sysinfo.h	2010-05-16 17:17:36.000000000 -0400
@@ -87,7 +87,8 @@ struct sysinfo_2_2_2 {
 
 struct sysinfo_3_2_2 {
 	char reserved_0[31];
-	unsigned char count;
+	unsigned char :4;
+	unsigned char count:4;
 	struct {
 		char reserved_0[4];
 		unsigned short cpus_total;
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/system.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/system.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/system.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,65 +24,65 @@ extern struct task_struct *__switch_to(v
 static inline void save_fp_regs(s390_fp_regs *fpregs)
 {
 	asm volatile(
-		"	std	0,8(%1)\n"
-		"	std	2,24(%1)\n"
-		"	std	4,40(%1)\n"
-		"	std	6,56(%1)"
-		: "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory");
+		"	std	0,%O0+8(%R0)\n"
+		"	std	2,%O0+24(%R0)\n"
+		"	std	4,%O0+40(%R0)\n"
+		"	std	6,%O0+56(%R0)"
+		: "=Q" (*fpregs) : "Q" (*fpregs));
 	if (!MACHINE_HAS_IEEE)
 		return;
 	asm volatile(
-		"	stfpc	0(%1)\n"
-		"	std	1,16(%1)\n"
-		"	std	3,32(%1)\n"
-		"	std	5,48(%1)\n"
-		"	std	7,64(%1)\n"
-		"	std	8,72(%1)\n"
-		"	std	9,80(%1)\n"
-		"	std	10,88(%1)\n"
-		"	std	11,96(%1)\n"
-		"	std	12,104(%1)\n"
-		"	std	13,112(%1)\n"
-		"	std	14,120(%1)\n"
-		"	std	15,128(%1)\n"
-		: "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory");
+		"	stfpc	%0\n"
+		"	std	1,%O0+16(%R0)\n"
+		"	std	3,%O0+32(%R0)\n"
+		"	std	5,%O0+48(%R0)\n"
+		"	std	7,%O0+64(%R0)\n"
+		"	std	8,%O0+72(%R0)\n"
+		"	std	9,%O0+80(%R0)\n"
+		"	std	10,%O0+88(%R0)\n"
+		"	std	11,%O0+96(%R0)\n"
+		"	std	12,%O0+104(%R0)\n"
+		"	std	13,%O0+112(%R0)\n"
+		"	std	14,%O0+120(%R0)\n"
+		"	std	15,%O0+128(%R0)\n"
+		: "=Q" (*fpregs) : "Q" (*fpregs));
 }
 
 static inline void restore_fp_regs(s390_fp_regs *fpregs)
 {
 	asm volatile(
-		"	ld	0,8(%0)\n"
-		"	ld	2,24(%0)\n"
-		"	ld	4,40(%0)\n"
-		"	ld	6,56(%0)"
-		: : "a" (fpregs), "m" (*fpregs));
+		"	ld	0,%O0+8(%R0)\n"
+		"	ld	2,%O0+24(%R0)\n"
+		"	ld	4,%O0+40(%R0)\n"
+		"	ld	6,%O0+56(%R0)"
+		: : "Q" (*fpregs));
 	if (!MACHINE_HAS_IEEE)
 		return;
 	asm volatile(
-		"	lfpc	0(%0)\n"
-		"	ld	1,16(%0)\n"
-		"	ld	3,32(%0)\n"
-		"	ld	5,48(%0)\n"
-		"	ld	7,64(%0)\n"
-		"	ld	8,72(%0)\n"
-		"	ld	9,80(%0)\n"
-		"	ld	10,88(%0)\n"
-		"	ld	11,96(%0)\n"
-		"	ld	12,104(%0)\n"
-		"	ld	13,112(%0)\n"
-		"	ld	14,120(%0)\n"
-		"	ld	15,128(%0)\n"
-		: : "a" (fpregs), "m" (*fpregs));
+		"	lfpc	%0\n"
+		"	ld	1,%O0+16(%R0)\n"
+		"	ld	3,%O0+32(%R0)\n"
+		"	ld	5,%O0+48(%R0)\n"
+		"	ld	7,%O0+64(%R0)\n"
+		"	ld	8,%O0+72(%R0)\n"
+		"	ld	9,%O0+80(%R0)\n"
+		"	ld	10,%O0+88(%R0)\n"
+		"	ld	11,%O0+96(%R0)\n"
+		"	ld	12,%O0+104(%R0)\n"
+		"	ld	13,%O0+112(%R0)\n"
+		"	ld	14,%O0+120(%R0)\n"
+		"	ld	15,%O0+128(%R0)\n"
+		: : "Q" (*fpregs));
 }
 
 static inline void save_access_regs(unsigned int *acrs)
 {
-	asm volatile("stam 0,15,0(%0)" : : "a" (acrs) : "memory");
+	asm volatile("stam 0,15,%0" : "=Q" (*acrs));
 }
 
 static inline void restore_access_regs(unsigned int *acrs)
 {
-	asm volatile("lam 0,15,0(%0)" : : "a" (acrs));
+	asm volatile("lam 0,15,%0" : : "Q" (*acrs));
 }
 
 #define switch_to(prev,next,last) do {					     \
@@ -110,6 +110,7 @@ extern void pfault_fini(void);
 #endif /* CONFIG_PFAULT */
 
 extern void cmma_init(void);
+extern int memcpy_real(void *, void *, size_t);
 
 #define finish_arch_switch(prev) do {					     \
 	set_fs(current->thread.mm_segment);				     \
@@ -139,48 +140,48 @@ static inline unsigned long __xchg(unsig
 		shift = (3 ^ (addr & 3)) << 3;
 		addr ^= addr & 3;
 		asm volatile(
-			"	l	%0,0(%4)\n"
+			"	l	%0,%4\n"
 			"0:	lr	0,%0\n"
 			"	nr	0,%3\n"
 			"	or	0,%2\n"
-			"	cs	%0,0,0(%4)\n"
+			"	cs	%0,0,%4\n"
 			"	jl	0b\n"
-			: "=&d" (old), "=m" (*(int *) addr)
-			: "d" (x << shift), "d" (~(255 << shift)), "a" (addr),
-			  "m" (*(int *) addr) : "memory", "cc", "0");
+			: "=&d" (old), "=Q" (*(int *) addr)
+			: "d" (x << shift), "d" (~(255 << shift)),
+			  "Q" (*(int *) addr) : "memory", "cc", "0");
 		return old >> shift;
 	case 2:
 		addr = (unsigned long) ptr;
 		shift = (2 ^ (addr & 2)) << 3;
 		addr ^= addr & 2;
 		asm volatile(
-			"	l	%0,0(%4)\n"
+			"	l	%0,%4\n"
 			"0:	lr	0,%0\n"
 			"	nr	0,%3\n"
 			"	or	0,%2\n"
-			"	cs	%0,0,0(%4)\n"
+			"	cs	%0,0,%4\n"
 			"	jl	0b\n"
-			: "=&d" (old), "=m" (*(int *) addr)
-			: "d" (x << shift), "d" (~(65535 << shift)), "a" (addr),
-			  "m" (*(int *) addr) : "memory", "cc", "0");
+			: "=&d" (old), "=Q" (*(int *) addr)
+			: "d" (x << shift), "d" (~(65535 << shift)),
+			  "Q" (*(int *) addr) : "memory", "cc", "0");
 		return old >> shift;
 	case 4:
 		asm volatile(
-			"	l	%0,0(%3)\n"
-			"0:	cs	%0,%2,0(%3)\n"
+			"	l	%0,%3\n"
+			"0:	cs	%0,%2,%3\n"
 			"	jl	0b\n"
-			: "=&d" (old), "=m" (*(int *) ptr)
-			: "d" (x), "a" (ptr), "m" (*(int *) ptr)
+			: "=&d" (old), "=Q" (*(int *) ptr)
+			: "d" (x), "Q" (*(int *) ptr)
 			: "memory", "cc");
 		return old;
 #ifdef __s390x__
 	case 8:
 		asm volatile(
-			"	lg	%0,0(%3)\n"
-			"0:	csg	%0,%2,0(%3)\n"
+			"	lg	%0,%3\n"
+			"0:	csg	%0,%2,%3\n"
 			"	jl	0b\n"
 			: "=&d" (old), "=m" (*(long *) ptr)
-			: "d" (x), "a" (ptr), "m" (*(long *) ptr)
+			: "d" (x), "Q" (*(long *) ptr)
 			: "memory", "cc");
 		return old;
 #endif /* __s390x__ */
@@ -215,20 +216,20 @@ __cmpxchg(volatile void *ptr, unsigned l
 		shift = (3 ^ (addr & 3)) << 3;
 		addr ^= addr & 3;
 		asm volatile(
-			"	l	%0,0(%4)\n"
+			"	l	%0,%2\n"
 			"0:	nr	%0,%5\n"
 			"	lr	%1,%0\n"
-			"	or	%0,%2\n"
-			"	or	%1,%3\n"
-			"	cs	%0,%1,0(%4)\n"
+			"	or	%0,%3\n"
+			"	or	%1,%4\n"
+			"	cs	%0,%1,%2\n"
 			"	jnl	1f\n"
 			"	xr	%1,%0\n"
 			"	nr	%1,%5\n"
 			"	jnz	0b\n"
 			"1:"
-			: "=&d" (prev), "=&d" (tmp)
-			: "d" (old << shift), "d" (new << shift), "a" (ptr),
-			  "d" (~(255 << shift))
+			: "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr)
+			: "d" (old << shift), "d" (new << shift),
+			  "d" (~(255 << shift)), "Q" (*(int *) ptr)
 			: "memory", "cc");
 		return prev >> shift;
 	case 2:
@@ -236,33 +237,35 @@ __cmpxchg(volatile void *ptr, unsigned l
 		shift = (2 ^ (addr & 2)) << 3;
 		addr ^= addr & 2;
 		asm volatile(
-			"	l	%0,0(%4)\n"
+			"	l	%0,%2\n"
 			"0:	nr	%0,%5\n"
 			"	lr	%1,%0\n"
-			"	or	%0,%2\n"
-			"	or	%1,%3\n"
-			"	cs	%0,%1,0(%4)\n"
+			"	or	%0,%3\n"
+			"	or	%1,%4\n"
+			"	cs	%0,%1,%2\n"
 			"	jnl	1f\n"
 			"	xr	%1,%0\n"
 			"	nr	%1,%5\n"
 			"	jnz	0b\n"
 			"1:"
-			: "=&d" (prev), "=&d" (tmp)
-			: "d" (old << shift), "d" (new << shift), "a" (ptr),
-			  "d" (~(65535 << shift))
+			: "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr)
+			: "d" (old << shift), "d" (new << shift),
+			  "d" (~(65535 << shift)), "Q" (*(int *) ptr)
 			: "memory", "cc");
 		return prev >> shift;
 	case 4:
 		asm volatile(
-			"	cs	%0,%2,0(%3)\n"
-			: "=&d" (prev) : "0" (old), "d" (new), "a" (ptr)
+			"	cs	%0,%3,%1\n"
+			: "=&d" (prev), "=Q" (*(int *) ptr)
+			: "0" (old), "d" (new), "Q" (*(int *) ptr)
 			: "memory", "cc");
 		return prev;
 #ifdef __s390x__
 	case 8:
 		asm volatile(
-			"	csg	%0,%2,0(%3)\n"
-			: "=&d" (prev) : "0" (old), "d" (new), "a" (ptr)
+			"	csg	%0,%3,%1\n"
+			: "=&d" (prev), "=Q" (*(long *) ptr)
+			: "0" (old), "d" (new), "Q" (*(long *) ptr)
 			: "memory", "cc");
 		return prev;
 #endif /* __s390x__ */
@@ -302,17 +305,17 @@ __cmpxchg(volatile void *ptr, unsigned l
 #define __ctl_load(array, low, high) ({				\
 	typedef struct { char _[sizeof(array)]; } addrtype;	\
 	asm volatile(						\
-		"	lctlg	%1,%2,0(%0)\n"			\
-		: : "a" (&array), "i" (low), "i" (high),	\
-		    "m" (*(addrtype *)(&array)));		\
+		"	lctlg	%1,%2,%0\n"			\
+		: : "Q" (*(addrtype *)(&array)),		\
+		    "i" (low), "i" (high));			\
 	})
 
 #define __ctl_store(array, low, high) ({			\
 	typedef struct { char _[sizeof(array)]; } addrtype;	\
 	asm volatile(						\
-		"	stctg	%2,%3,0(%1)\n"			\
-		: "=m" (*(addrtype *)(&array))			\
-		: "a" (&array), "i" (low), "i" (high));		\
+		"	stctg	%1,%2,%0\n"			\
+		: "=Q" (*(addrtype *)(&array))			\
+		: "i" (low), "i" (high));			\
 	})
 
 #else /* __s390x__ */
@@ -320,17 +323,17 @@ __cmpxchg(volatile void *ptr, unsigned l
 #define __ctl_load(array, low, high) ({				\
 	typedef struct { char _[sizeof(array)]; } addrtype;	\
 	asm volatile(						\
-		"	lctl	%1,%2,0(%0)\n"			\
-		: : "a" (&array), "i" (low), "i" (high),	\
-		    "m" (*(addrtype *)(&array)));		\
+		"	lctl	%1,%2,%0\n"			\
+		: : "Q" (*(addrtype *)(&array)),		\
+		    "i" (low), "i" (high));			\
 })
 
 #define __ctl_store(array, low, high) ({			\
 	typedef struct { char _[sizeof(array)]; } addrtype;	\
 	asm volatile(						\
-		"	stctl	%2,%3,0(%1)\n"			\
-		: "=m" (*(addrtype *)(&array))			\
-		: "a" (&array), "i" (low), "i" (high));		\
+		"	stctl	%1,%2,%0\n"			\
+		: "=Q" (*(addrtype *)(&array))			\
+		: "i" (low), "i" (high));			\
 	})
 
 #endif /* __s390x__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/thread_info.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/thread_info.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/thread_info.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/thread_info.h	2010-05-16 17:17:36.000000000 -0400
@@ -73,7 +73,7 @@ struct thread_info {
 /* how to get the thread information struct from C */
 static inline struct thread_info *current_thread_info(void)
 {
-	return (struct thread_info *)((*(unsigned long *) __LC_KERNEL_STACK)-THREAD_SIZE);
+	return (struct thread_info *)(S390_lowcore.kernel_stack - THREAD_SIZE);
 }
 
 #define THREAD_SIZE_ORDER THREAD_ORDER
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/timex.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/timex.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/timex.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/timex.h	2010-05-16 17:17:36.000000000 -0400
@@ -20,10 +20,10 @@ static inline int set_clock(__u64 time)
 	int cc;
 
 	asm volatile(
-		"   sck   0(%2)\n"
+		"   sck   %1\n"
 		"   ipm   %0\n"
 		"   srl   %0,28\n"
-		: "=d" (cc) : "m" (time), "a" (&time) : "cc");
+		: "=d" (cc) : "Q" (time) : "cc");
 	return cc;
 }
 
@@ -32,21 +32,21 @@ static inline int store_clock(__u64 *tim
 	int cc;
 
 	asm volatile(
-		"   stck  0(%2)\n"
+		"   stck  %1\n"
 		"   ipm   %0\n"
 		"   srl   %0,28\n"
-		: "=d" (cc), "=m" (*time) : "a" (time) : "cc");
+		: "=d" (cc), "=Q" (*time) : : "cc");
 	return cc;
 }
 
 static inline void set_clock_comparator(__u64 time)
 {
-	asm volatile("sckc 0(%1)" : : "m" (time), "a" (&time));
+	asm volatile("sckc %0" : : "Q" (time));
 }
 
 static inline void store_clock_comparator(__u64 *time)
 {
-	asm volatile("stckc 0(%1)" : "=m" (*time) : "a" (time));
+	asm volatile("stckc %0" : "=Q" (*time));
 }
 
 #define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
@@ -57,11 +57,7 @@ static inline unsigned long long get_clo
 {
 	unsigned long long clk;
 
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
 	asm volatile("stck %0" : "=Q" (clk) : : "cc");
-#else /* __GNUC__ */
-	asm volatile("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc");
-#endif /* __GNUC__ */
 	return clk;
 }
 
@@ -69,13 +65,7 @@ static inline unsigned long long get_clo
 {
 	unsigned char clk[16];
 
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
 	asm volatile("stcke %0" : "=Q" (clk) : : "cc");
-#else /* __GNUC__ */
-	asm volatile("stcke 0(%1)" : "=m" (clk)
-				   : "a" (clk) : "cc");
-#endif /* __GNUC__ */
-
 	return *((unsigned long long *)&clk[1]);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/uaccess.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/uaccess.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/uaccess.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/uaccess.h	2010-05-16 17:17:36.000000000 -0400
@@ -265,6 +265,12 @@ __copy_from_user(void *to, const void __
 		return uaccess.copy_from_user(n, from, to);
 }
 
+extern void copy_from_user_overflow(void)
+#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
+__compiletime_warning("copy_from_user() buffer size is not provably correct")
+#endif
+;
+
 /**
  * copy_from_user: - Copy a block of data from user space.
  * @to:   Destination address, in kernel space.
@@ -284,7 +290,13 @@ __copy_from_user(void *to, const void __
 static inline unsigned long __must_check
 copy_from_user(void *to, const void __user *from, unsigned long n)
 {
+	unsigned int sz = __compiletime_object_size(to);
+
 	might_fault();
+	if (unlikely(sz != -1 && sz < n)) {
+		copy_from_user_overflow();
+		return n;
+	}
 	if (access_ok(VERIFY_READ, from, n))
 		n = __copy_from_user(to, from, n);
 	else
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/unistd.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/unistd.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/unistd.h	2010-05-16 17:17:36.000000000 -0400
@@ -392,6 +392,7 @@
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_MMAP
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/include/asm/vdso.h linux-libre-2.6.34-gnu1/arch/s390/include/asm/vdso.h
--- linux-libre-2.6.33-gnu1/arch/s390/include/asm/vdso.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/include/asm/vdso.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,7 @@
 #define VDSO32_LBASE	0
 #define VDSO64_LBASE	0
 
-#define VDSO_VERSION_STRING	LINUX_2.6.26
+#define VDSO_VERSION_STRING	LINUX_2.6.29
 
 #ifndef __ASSEMBLY__
 
@@ -29,6 +29,7 @@ struct vdso_data {
 	__u32 tz_minuteswest;		/* Minutes west of Greenwich	0x30 */
 	__u32 tz_dsttime;		/* Type of dst correction	0x34 */
 	__u32 ectg_available;
+	__u32 ntp_mult;			/* NTP adjusted multiplier	0x3C */
 };
 
 struct vdso_per_cpu_data {
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/Kconfig linux-libre-2.6.34-gnu1/arch/s390/Kconfig
--- linux-libre-2.6.33-gnu1/arch/s390/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -54,6 +54,9 @@ config GENERIC_BUG
 	depends on BUG
 	default y
 
+config GENERIC_BUG_RELATIVE_POINTERS
+	def_bool y
+
 config NO_IOMEM
 	def_bool y
 
@@ -87,6 +90,7 @@ config S390
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_FUNCTION_GRAPH_TRACER
+	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_DEFAULT_NO_SPIN_MUTEXES
 	select HAVE_OPROFILE
 	select HAVE_KPROBES
@@ -95,6 +99,9 @@ config S390
 	select HAVE_ARCH_TRACEHOOK
 	select INIT_ALL_POSSIBLE
 	select HAVE_PERF_EVENTS
+	select HAVE_KERNEL_GZIP
+	select HAVE_KERNEL_BZIP2
+	select HAVE_KERNEL_LZMA
 	select ARCH_INLINE_SPIN_TRYLOCK
 	select ARCH_INLINE_SPIN_TRYLOCK_BH
 	select ARCH_INLINE_SPIN_LOCK
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/Kconfig.debug linux-libre-2.6.34-gnu1/arch/s390/Kconfig.debug
--- linux-libre-2.6.33-gnu1/arch/s390/Kconfig.debug	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/Kconfig.debug	2010-05-16 17:17:36.000000000 -0400
@@ -6,4 +6,17 @@ config TRACE_IRQFLAGS_SUPPORT
 
 source "lib/Kconfig.debug"
 
+config DEBUG_STRICT_USER_COPY_CHECKS
+	bool "Strict user copy size checks"
+	---help---
+	  Enabling this option turns a certain set of sanity checks for user
+	  copy operations into compile time warnings.
+
+	  The copy_from_user() etc checks are there to help test if there
+	  are sufficient security checks on the length argument of
+	  the copy operation, by having gcc prove that the argument is
+	  within bounds.
+
+	  If unsure, or if you run an older (pre 4.4) gcc, say N.
+
 endmenu
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/asm-offsets.c linux-libre-2.6.34-gnu1/arch/s390/kernel/asm-offsets.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/asm-offsets.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/asm-offsets.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,18 +4,27 @@
  * and format the required data.
  */
 
-#include <linux/sched.h>
+#define ASM_OFFSETS_C
+
 #include <linux/kbuild.h>
+#include <linux/sched.h>
 #include <asm/vdso.h>
 #include <asm/sigp.h>
 
+/*
+ * Make sure that the compiler is new enough. We want a compiler that
+ * is known to work with the "Q" assembler constraint.
+ */
+#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
+#error Your compiler is too old; please use version 3.3.3 or newer
+#endif
+
 int main(void)
 {
 	DEFINE(__THREAD_info, offsetof(struct task_struct, stack));
 	DEFINE(__THREAD_ksp, offsetof(struct task_struct, thread.ksp));
 	DEFINE(__THREAD_per, offsetof(struct task_struct, thread.per_info));
-	DEFINE(__THREAD_mm_segment,
-	       offsetof(struct task_struct, thread.mm_segment));
+	DEFINE(__THREAD_mm_segment, offsetof(struct task_struct, thread.mm_segment));
 	BLANK();
 	DEFINE(__TASK_pid, offsetof(struct task_struct, pid));
 	BLANK();
@@ -52,18 +61,95 @@ int main(void)
 	DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
 	DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
 	DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
-	DEFINE(__VDSO_ECTG_BASE,
-	       offsetof(struct vdso_per_cpu_data, ectg_timer_base));
-	DEFINE(__VDSO_ECTG_USER,
-	       offsetof(struct vdso_per_cpu_data, ectg_user_time));
+	DEFINE(__VDSO_NTP_MULT, offsetof(struct vdso_data, ntp_mult));
+	DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base));
+	DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time));
 	/* constants used by the vdso */
 	DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
 	DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
 	DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
+	BLANK();
 	/* constants for SIGP */
 	DEFINE(__SIGP_STOP, sigp_stop);
 	DEFINE(__SIGP_RESTART, sigp_restart);
 	DEFINE(__SIGP_SENSE, sigp_sense);
 	DEFINE(__SIGP_INITIAL_CPU_RESET, sigp_initial_cpu_reset);
+	BLANK();
+	/* lowcore offsets */
+	DEFINE(__LC_EXT_PARAMS, offsetof(struct _lowcore, ext_params));
+	DEFINE(__LC_CPU_ADDRESS, offsetof(struct _lowcore, cpu_addr));
+	DEFINE(__LC_EXT_INT_CODE, offsetof(struct _lowcore, ext_int_code));
+	DEFINE(__LC_SVC_ILC, offsetof(struct _lowcore, svc_ilc));
+	DEFINE(__LC_SVC_INT_CODE, offsetof(struct _lowcore, svc_code));
+	DEFINE(__LC_PGM_ILC, offsetof(struct _lowcore, pgm_ilc));
+	DEFINE(__LC_PGM_INT_CODE, offsetof(struct _lowcore, pgm_code));
+	DEFINE(__LC_PER_ATMID, offsetof(struct _lowcore, per_perc_atmid));
+	DEFINE(__LC_PER_ADDRESS, offsetof(struct _lowcore, per_address));
+	DEFINE(__LC_PER_ACCESS_ID, offsetof(struct _lowcore, per_access_id));
+	DEFINE(__LC_AR_MODE_ID, offsetof(struct _lowcore, ar_access_id));
+	DEFINE(__LC_SUBCHANNEL_ID, offsetof(struct _lowcore, subchannel_id));
+	DEFINE(__LC_SUBCHANNEL_NR, offsetof(struct _lowcore, subchannel_nr));
+	DEFINE(__LC_IO_INT_PARM, offsetof(struct _lowcore, io_int_parm));
+	DEFINE(__LC_IO_INT_WORD, offsetof(struct _lowcore, io_int_word));
+	DEFINE(__LC_STFL_FAC_LIST, offsetof(struct _lowcore, stfl_fac_list));
+	DEFINE(__LC_MCCK_CODE, offsetof(struct _lowcore, mcck_interruption_code));
+	DEFINE(__LC_DUMP_REIPL, offsetof(struct _lowcore, ipib));
+	BLANK();
+	DEFINE(__LC_RST_NEW_PSW, offsetof(struct _lowcore, restart_psw));
+	DEFINE(__LC_RST_OLD_PSW, offsetof(struct _lowcore, restart_old_psw));
+	DEFINE(__LC_EXT_OLD_PSW, offsetof(struct _lowcore, external_old_psw));
+	DEFINE(__LC_SVC_OLD_PSW, offsetof(struct _lowcore, svc_old_psw));
+	DEFINE(__LC_PGM_OLD_PSW, offsetof(struct _lowcore, program_old_psw));
+	DEFINE(__LC_MCK_OLD_PSW, offsetof(struct _lowcore, mcck_old_psw));
+	DEFINE(__LC_IO_OLD_PSW, offsetof(struct _lowcore, io_old_psw));
+	DEFINE(__LC_EXT_NEW_PSW, offsetof(struct _lowcore, external_new_psw));
+	DEFINE(__LC_SVC_NEW_PSW, offsetof(struct _lowcore, svc_new_psw));
+	DEFINE(__LC_PGM_NEW_PSW, offsetof(struct _lowcore, program_new_psw));
+	DEFINE(__LC_MCK_NEW_PSW, offsetof(struct _lowcore, mcck_new_psw));
+	DEFINE(__LC_IO_NEW_PSW, offsetof(struct _lowcore, io_new_psw));
+	DEFINE(__LC_SAVE_AREA, offsetof(struct _lowcore, save_area));
+	DEFINE(__LC_RETURN_PSW, offsetof(struct _lowcore, return_psw));
+	DEFINE(__LC_RETURN_MCCK_PSW, offsetof(struct _lowcore, return_mcck_psw));
+	DEFINE(__LC_SYNC_ENTER_TIMER, offsetof(struct _lowcore, sync_enter_timer));
+	DEFINE(__LC_ASYNC_ENTER_TIMER, offsetof(struct _lowcore, async_enter_timer));
+	DEFINE(__LC_EXIT_TIMER, offsetof(struct _lowcore, exit_timer));
+	DEFINE(__LC_USER_TIMER, offsetof(struct _lowcore, user_timer));
+	DEFINE(__LC_SYSTEM_TIMER, offsetof(struct _lowcore, system_timer));
+	DEFINE(__LC_STEAL_TIMER, offsetof(struct _lowcore, steal_timer));
+	DEFINE(__LC_LAST_UPDATE_TIMER, offsetof(struct _lowcore, last_update_timer));
+	DEFINE(__LC_LAST_UPDATE_CLOCK, offsetof(struct _lowcore, last_update_clock));
+	DEFINE(__LC_CURRENT, offsetof(struct _lowcore, current_task));
+	DEFINE(__LC_THREAD_INFO, offsetof(struct _lowcore, thread_info));
+	DEFINE(__LC_KERNEL_STACK, offsetof(struct _lowcore, kernel_stack));
+	DEFINE(__LC_ASYNC_STACK, offsetof(struct _lowcore, async_stack));
+	DEFINE(__LC_PANIC_STACK, offsetof(struct _lowcore, panic_stack));
+	DEFINE(__LC_KERNEL_ASCE, offsetof(struct _lowcore, kernel_asce));
+	DEFINE(__LC_USER_ASCE, offsetof(struct _lowcore, user_asce));
+	DEFINE(__LC_USER_EXEC_ASCE, offsetof(struct _lowcore, user_exec_asce));
+	DEFINE(__LC_CPUID, offsetof(struct _lowcore, cpu_id));
+	DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock));
+	DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags));
+	DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func));
+	DEFINE(__LC_IRB, offsetof(struct _lowcore, irb));
+	DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area));
+	DEFINE(__LC_CLOCK_COMP_SAVE_AREA, offsetof(struct _lowcore, clock_comp_save_area));
+	DEFINE(__LC_PSW_SAVE_AREA, offsetof(struct _lowcore, psw_save_area));
+	DEFINE(__LC_PREFIX_SAVE_AREA, offsetof(struct _lowcore, prefixreg_save_area));
+	DEFINE(__LC_AREGS_SAVE_AREA, offsetof(struct _lowcore, access_regs_save_area));
+	DEFINE(__LC_FPREGS_SAVE_AREA, offsetof(struct _lowcore, floating_pt_save_area));
+	DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area));
+	DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area));
+#ifdef CONFIG_32BIT
+	DEFINE(__LC_PFAULT_INTPARM, offsetof(struct _lowcore, ext_params));
+	DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr));
+#else /* CONFIG_32BIT */
+	DEFINE(__LC_PFAULT_INTPARM, offsetof(struct _lowcore, ext_params2));
+	DEFINE(__LC_EXT_PARAMS2, offsetof(struct _lowcore, ext_params2));
+	DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, floating_pt_save_area));
+	DEFINE(__LC_PASTE, offsetof(struct _lowcore, paste));
+	DEFINE(__LC_FP_CREG_SAVE_AREA, offsetof(struct _lowcore, fpt_creg_save_area));
+	DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr));
+	DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data));
+#endif /* CONFIG_32BIT */
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/base.S linux-libre-2.6.34-gnu1/arch/s390/kernel/base.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/base.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/base.S	2010-05-16 17:17:36.000000000 -0400
@@ -6,8 +6,8 @@
  *		 Michael Holzheu <holzheu@de.ibm.com>
  */
 
+#include <asm/asm-offsets.h>
 #include <asm/ptrace.h>
-#include <asm/lowcore.h>
 
 #ifdef CONFIG_64BIT
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/compat_linux.c linux-libre-2.6.34-gnu1/arch/s390/kernel/compat_linux.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/compat_linux.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/compat_linux.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,7 +29,6 @@
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
-#include <linux/slab.h>
 #include <linux/uio.h>
 #include <linux/quota.h>
 #include <linux/module.h>
@@ -52,6 +51,7 @@
 #include <linux/ptrace.h>
 #include <linux/fadvise.h>
 #include <linux/ipc.h>
+#include <linux/slab.h>
 
 #include <asm/types.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/compat_wrapper.S linux-libre-2.6.34-gnu1/arch/s390/kernel/compat_wrapper.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/compat_wrapper.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/compat_wrapper.S	2010-05-16 17:17:36.000000000 -0400
@@ -547,7 +547,7 @@ sys32_setdomainname_wrapper:
 	.globl	sys32_newuname_wrapper
 sys32_newuname_wrapper:
 	llgtr	%r2,%r2			# struct new_utsname *
-	jg	sys_s390_newuname	# branch to system call
+	jg	sys_newuname		# branch to system call
 
 	.globl	compat_sys_adjtimex_wrapper
 compat_sys_adjtimex_wrapper:
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/dis.c linux-libre-2.6.34-gnu1/arch/s390/kernel/dis.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/dis.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/dis.c	2010-05-16 17:17:36.000000000 -0400
@@ -86,10 +86,17 @@ enum {
 	U4_12,	/* 4 bit unsigned value starting at 12 */
 	U4_16,	/* 4 bit unsigned value starting at 16 */
 	U4_20,	/* 4 bit unsigned value starting at 20 */
+	U4_32,	/* 4 bit unsigned value starting at 32 */
 	U8_8,	/* 8 bit unsigned value starting at 8 */
 	U8_16,	/* 8 bit unsigned value starting at 16 */
+	U8_24,	/* 8 bit unsigned value starting at 24 */
+	U8_32,	/* 8 bit unsigned value starting at 32 */
+	I8_8,	/* 8 bit signed value starting at 8 */
+	I8_32,	/* 8 bit signed value starting at 32 */
 	I16_16,	/* 16 bit signed value starting at 16 */
+	I16_32,	/* 32 bit signed value starting at 16 */
 	U16_16,	/* 16 bit unsigned value starting at 16 */
+	U16_32,	/* 32 bit unsigned value starting at 16 */
 	J16_16,	/* PC relative jump offset at 16 */
 	J32_16,	/* PC relative long offset at 16 */
 	I32_16,	/* 32 bit signed value starting at 16 */
@@ -104,21 +111,37 @@ enum {
  */
 enum {
 	INSTR_INVALID,
-	INSTR_E, INSTR_RIE_RRP, INSTR_RIL_RI, INSTR_RIL_RP, INSTR_RIL_RU,
-	INSTR_RIL_UP, INSTR_RI_RI, INSTR_RI_RP, INSTR_RI_RU, INSTR_RI_UP,
+	INSTR_E,
+	INSTR_RIE_R0IU, INSTR_RIE_R0UU, INSTR_RIE_RRP, INSTR_RIE_RRPU,
+	INSTR_RIE_RRUUU, INSTR_RIE_RUPI, INSTR_RIE_RUPU,
+	INSTR_RIL_RI, INSTR_RIL_RP, INSTR_RIL_RU, INSTR_RIL_UP,
+	INSTR_RIS_R0RDU, INSTR_RIS_R0UU, INSTR_RIS_RURDI, INSTR_RIS_RURDU,
+	INSTR_RI_RI, INSTR_RI_RP, INSTR_RI_RU, INSTR_RI_UP,
 	INSTR_RRE_00, INSTR_RRE_0R, INSTR_RRE_AA, INSTR_RRE_AR, INSTR_RRE_F0,
-	INSTR_RRE_FF, INSTR_RRE_R0, INSTR_RRE_RA, INSTR_RRE_RF, INSTR_RRE_RR,
-	INSTR_RRE_RR_OPT, INSTR_RRF_F0FF, INSTR_RRF_FUFF, INSTR_RRF_M0RR,
-	INSTR_RRF_R0RR, INSTR_RRF_RURR, INSTR_RRF_U0FF, INSTR_RRF_U0RF,
+	INSTR_RRE_FF, INSTR_RRE_FR, INSTR_RRE_R0, INSTR_RRE_RA, INSTR_RRE_RF,
+	INSTR_RRE_RR, INSTR_RRE_RR_OPT,
+	INSTR_RRF_0UFF, INSTR_RRF_F0FF, INSTR_RRF_F0FF2, INSTR_RRF_F0FR,
+	INSTR_RRF_FFRU, INSTR_RRF_FUFF, INSTR_RRF_M0RR, INSTR_RRF_R0RR,
+	INSTR_RRF_RURR, INSTR_RRF_U0FF, INSTR_RRF_U0RF, INSTR_RRF_U0RR,
+	INSTR_RRF_UUFF, INSTR_RRR_F0FF, INSTR_RRS_RRRDU,
 	INSTR_RR_FF, INSTR_RR_R0, INSTR_RR_RR, INSTR_RR_U0, INSTR_RR_UR,
-	INSTR_RSE_CCRD, INSTR_RSE_RRRD, INSTR_RSE_RURD, INSTR_RSI_RRP,
-	INSTR_RSL_R0RD, INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD,
-	INSTR_RSY_RURD, INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD,
-	INSTR_RS_RRRD, INSTR_RS_RURD, INSTR_RXE_FRRD, INSTR_RXE_RRRD,
-	INSTR_RXF_FRRDF, INSTR_RXY_FRRD, INSTR_RXY_RRRD, INSTR_RX_FRRD,
-	INSTR_RX_RRRD, INSTR_RX_URRD, INSTR_SIY_URD, INSTR_SI_URD,
-	INSTR_SSE_RDRD, INSTR_SSF_RRDRD, INSTR_SS_L0RDRD, INSTR_SS_LIRDRD,
-	INSTR_SS_LLRDRD, INSTR_SS_RRRDRD, INSTR_SS_RRRDRD2, INSTR_SS_RRRDRD3,
+	INSTR_RSE_CCRD, INSTR_RSE_RRRD, INSTR_RSE_RURD,
+	INSTR_RSI_RRP,
+	INSTR_RSL_R0RD,
+	INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD, INSTR_RSY_RURD,
+	INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD, INSTR_RS_RRRD,
+	INSTR_RS_RURD,
+	INSTR_RXE_FRRD, INSTR_RXE_RRRD,
+	INSTR_RXF_FRRDF,
+	INSTR_RXY_FRRD, INSTR_RXY_RRRD, INSTR_RXY_URRD,
+	INSTR_RX_FRRD, INSTR_RX_RRRD, INSTR_RX_URRD,
+	INSTR_SIL_RDI, INSTR_SIL_RDU,
+	INSTR_SIY_IRD, INSTR_SIY_URD,
+	INSTR_SI_URD,
+	INSTR_SSE_RDRD,
+	INSTR_SSF_RRDRD,
+	INSTR_SS_L0RDRD, INSTR_SS_LIRDRD, INSTR_SS_LLRDRD, INSTR_SS_RRRDRD,
+	INSTR_SS_RRRDRD2, INSTR_SS_RRRDRD3,
 	INSTR_S_00, INSTR_S_RD,
 };
 
@@ -129,7 +152,7 @@ struct operand {
 };
 
 struct insn {
-	const char name[5];
+	const char name[6];
 	unsigned char opfrag;
 	unsigned char format;
 };
@@ -170,11 +193,16 @@ static const struct operand operands[] =
 	[U4_12]  = {  4, 12, 0 },
 	[U4_16]  = {  4, 16, 0 },
 	[U4_20]  = {  4, 20, 0 },
+	[U4_32]  = {  4, 32, 0 },
 	[U8_8]	 = {  8,  8, 0 },
 	[U8_16]  = {  8, 16, 0 },
+	[U8_24]  = {  8, 24, 0 },
+	[U8_32]  = {  8, 32, 0 },
 	[I16_16] = { 16, 16, OPERAND_SIGNED },
 	[U16_16] = { 16, 16, 0 },
+	[U16_32] = { 16, 32, 0 },
 	[J16_16] = { 16, 16, OPERAND_PCREL },
+	[I16_32] = { 16, 32, OPERAND_SIGNED },
 	[J32_16] = { 32, 16, OPERAND_PCREL },
 	[I32_16] = { 32, 16, OPERAND_SIGNED },
 	[U32_16] = { 32, 16, 0 },
@@ -183,82 +211,93 @@ static const struct operand operands[] =
 };
 
 static const unsigned char formats[][7] = {
-	[INSTR_E]	  = { 0xff, 0,0,0,0,0,0 },	       /* e.g. pr    */
-	[INSTR_RIE_RRP]	  = { 0xff, R_8,R_12,J16_16,0,0,0 },   /* e.g. brxhg */
-	[INSTR_RIL_RP]	  = { 0x0f, R_8,J32_16,0,0,0,0 },      /* e.g. brasl */
-	[INSTR_RIL_UP]	  = { 0x0f, U4_8,J32_16,0,0,0,0 },     /* e.g. brcl  */
-	[INSTR_RIL_RI]	  = { 0x0f, R_8,I32_16,0,0,0,0 },      /* e.g. afi   */
-	[INSTR_RIL_RU]	  = { 0x0f, R_8,U32_16,0,0,0,0 },      /* e.g. alfi  */
-	[INSTR_RI_RI]	  = { 0x0f, R_8,I16_16,0,0,0,0 },      /* e.g. ahi   */
-	[INSTR_RI_RP]	  = { 0x0f, R_8,J16_16,0,0,0,0 },      /* e.g. brct  */
-	[INSTR_RI_RU]	  = { 0x0f, R_8,U16_16,0,0,0,0 },      /* e.g. tml   */
-	[INSTR_RI_UP]	  = { 0x0f, U4_8,J16_16,0,0,0,0 },     /* e.g. brc   */
-	[INSTR_RRE_00]	  = { 0xff, 0,0,0,0,0,0 },	       /* e.g. palb  */
-	[INSTR_RRE_0R]	  = { 0xff, R_28,0,0,0,0,0 },	       /* e.g. tb    */
-	[INSTR_RRE_AA]	  = { 0xff, A_24,A_28,0,0,0,0 },       /* e.g. cpya  */
-	[INSTR_RRE_AR]	  = { 0xff, A_24,R_28,0,0,0,0 },       /* e.g. sar   */
-	[INSTR_RRE_F0]	  = { 0xff, F_24,0,0,0,0,0 },	       /* e.g. sqer  */
-	[INSTR_RRE_FF]	  = { 0xff, F_24,F_28,0,0,0,0 },       /* e.g. debr  */
-	[INSTR_RRE_R0]	  = { 0xff, R_24,0,0,0,0,0 },	       /* e.g. ipm   */
-	[INSTR_RRE_RA]	  = { 0xff, R_24,A_28,0,0,0,0 },       /* e.g. ear   */
-	[INSTR_RRE_RF]	  = { 0xff, R_24,F_28,0,0,0,0 },       /* e.g. cefbr */
-	[INSTR_RRE_RR]	  = { 0xff, R_24,R_28,0,0,0,0 },       /* e.g. lura  */
-	[INSTR_RRE_RR_OPT]= { 0xff, R_24,RO_28,0,0,0,0 },      /* efpc, sfpc */
-	[INSTR_RRF_F0FF]  = { 0xff, F_16,F_24,F_28,0,0,0 },    /* e.g. madbr */
-	[INSTR_RRF_FUFF]  = { 0xff, F_24,F_16,F_28,U4_20,0,0 },/* e.g. didbr */
-	[INSTR_RRF_RURR]  = { 0xff, R_24,R_28,R_16,U4_20,0,0 },/* e.g. .insn */
-	[INSTR_RRF_R0RR]  = { 0xff, R_24,R_16,R_28,0,0,0 },    /* e.g. idte  */
-	[INSTR_RRF_U0FF]  = { 0xff, F_24,U4_16,F_28,0,0,0 },   /* e.g. fixr  */
-	[INSTR_RRF_U0RF]  = { 0xff, R_24,U4_16,F_28,0,0,0 },   /* e.g. cfebr */
-	[INSTR_RRF_M0RR]  = { 0xff, R_24,R_28,M_16,0,0,0 },    /* e.g. sske  */
-	[INSTR_RR_FF]	  = { 0xff, F_8,F_12,0,0,0,0 },        /* e.g. adr   */
-	[INSTR_RR_R0]	  = { 0xff, R_8, 0,0,0,0,0 },	       /* e.g. spm   */
-	[INSTR_RR_RR]	  = { 0xff, R_8,R_12,0,0,0,0 },        /* e.g. lr    */
-	[INSTR_RR_U0]	  = { 0xff, U8_8, 0,0,0,0,0 },	       /* e.g. svc   */
-	[INSTR_RR_UR]	  = { 0xff, U4_8,R_12,0,0,0,0 },       /* e.g. bcr   */
-	[INSTR_RSE_RRRD]  = { 0xff, R_8,R_12,D_20,B_16,0,0 },  /* e.g. lmh   */
-	[INSTR_RSE_CCRD]  = { 0xff, C_8,C_12,D_20,B_16,0,0 },  /* e.g. lmh   */
-	[INSTR_RSE_RURD]  = { 0xff, R_8,U4_12,D_20,B_16,0,0 }, /* e.g. icmh  */
-	[INSTR_RSL_R0RD]  = { 0xff, R_8,D_20,B_16,0,0,0 },     /* e.g. tp    */
-	[INSTR_RSI_RRP]	  = { 0xff, R_8,R_12,J16_16,0,0,0 },   /* e.g. brxh  */
-	[INSTR_RSY_RRRD]  = { 0xff, R_8,R_12,D20_20,B_16,0,0 },/* e.g. stmy  */
+	[INSTR_E]	  = { 0xff, 0,0,0,0,0,0 },
+	[INSTR_RIE_R0UU]  = { 0xff, R_8,U16_16,U4_32,0,0,0 },
+	[INSTR_RIE_RRPU]  = { 0xff, R_8,R_12,U4_32,J16_16,0,0 },
+	[INSTR_RIE_RRP]	  = { 0xff, R_8,R_12,J16_16,0,0,0 },
+	[INSTR_RIE_RRUUU] = { 0xff, R_8,R_12,U8_16,U8_24,U8_32,0 },
+	[INSTR_RIE_RUPI]  = { 0xff, R_8,I8_32,U4_12,J16_16,0,0 },
+	[INSTR_RIL_RI]	  = { 0x0f, R_8,I32_16,0,0,0,0 },
+	[INSTR_RIL_RP]	  = { 0x0f, R_8,J32_16,0,0,0,0 },
+	[INSTR_RIL_RU]	  = { 0x0f, R_8,U32_16,0,0,0,0 },
+	[INSTR_RIL_UP]	  = { 0x0f, U4_8,J32_16,0,0,0,0 },
+	[INSTR_RIS_R0RDU] = { 0xff, R_8,U8_32,D_20,B_16,0,0 },
+	[INSTR_RIS_RURDI] = { 0xff, R_8,I8_32,U4_12,D_20,B_16,0 },
+	[INSTR_RIS_RURDU] = { 0xff, R_8,U8_32,U4_12,D_20,B_16,0 },
+	[INSTR_RI_RI]	  = { 0x0f, R_8,I16_16,0,0,0,0 },
+	[INSTR_RI_RP]	  = { 0x0f, R_8,J16_16,0,0,0,0 },
+	[INSTR_RI_RU]	  = { 0x0f, R_8,U16_16,0,0,0,0 },
+	[INSTR_RI_UP]	  = { 0x0f, U4_8,J16_16,0,0,0,0 },
+	[INSTR_RRE_00]	  = { 0xff, 0,0,0,0,0,0 },
+	[INSTR_RRE_0R]	  = { 0xff, R_28,0,0,0,0,0 },
+	[INSTR_RRE_AA]	  = { 0xff, A_24,A_28,0,0,0,0 },
+	[INSTR_RRE_AR]	  = { 0xff, A_24,R_28,0,0,0,0 },
+	[INSTR_RRE_F0]	  = { 0xff, F_24,0,0,0,0,0 },
+	[INSTR_RRE_FF]	  = { 0xff, F_24,F_28,0,0,0,0 },
+	[INSTR_RRE_FR]	  = { 0xff, F_24,R_28,0,0,0,0 },
+	[INSTR_RRE_R0]	  = { 0xff, R_24,0,0,0,0,0 },
+	[INSTR_RRE_RA]	  = { 0xff, R_24,A_28,0,0,0,0 },
+	[INSTR_RRE_RF]	  = { 0xff, R_24,F_28,0,0,0,0 },
+	[INSTR_RRE_RR]	  = { 0xff, R_24,R_28,0,0,0,0 },
+	[INSTR_RRE_RR_OPT]= { 0xff, R_24,RO_28,0,0,0,0 },
+	[INSTR_RRF_0UFF]  = { 0xff, F_24,F_28,U4_20,0,0,0 },
+	[INSTR_RRF_F0FF2] = { 0xff, F_24,F_16,F_28,0,0,0 },
+	[INSTR_RRF_F0FF]  = { 0xff, F_16,F_24,F_28,0,0,0 },
+	[INSTR_RRF_F0FR]  = { 0xff, F_24,F_16,R_28,0,0,0 },
+	[INSTR_RRF_FFRU]  = { 0xff, F_24,F_16,R_28,U4_20,0,0 },
+	[INSTR_RRF_FUFF]  = { 0xff, F_24,F_16,F_28,U4_20,0,0 },
+	[INSTR_RRF_M0RR]  = { 0xff, R_24,R_28,M_16,0,0,0 },
+	[INSTR_RRF_R0RR]  = { 0xff, R_24,R_16,R_28,0,0,0 },
+	[INSTR_RRF_RURR]  = { 0xff, R_24,R_28,R_16,U4_20,0,0 },
+	[INSTR_RRF_U0FF]  = { 0xff, F_24,U4_16,F_28,0,0,0 },
+	[INSTR_RRF_U0RF]  = { 0xff, R_24,U4_16,F_28,0,0,0 },
+	[INSTR_RRF_U0RR]  = { 0xff, R_24,R_28,U4_16,0,0,0 },
+	[INSTR_RRF_UUFF]  = { 0xff, F_24,U4_16,F_28,U4_20,0,0 },
+	[INSTR_RRR_F0FF]  = { 0xff, F_24,F_28,F_16,0,0,0 },
+	[INSTR_RRS_RRRDU] = { 0xff, R_8,R_12,U4_32,D_20,B_16,0 },
+	[INSTR_RR_FF]	  = { 0xff, F_8,F_12,0,0,0,0 },
+	[INSTR_RR_R0]	  = { 0xff, R_8, 0,0,0,0,0 },
+	[INSTR_RR_RR]	  = { 0xff, R_8,R_12,0,0,0,0 },
+	[INSTR_RR_U0]	  = { 0xff, U8_8, 0,0,0,0,0 },
+	[INSTR_RR_UR]	  = { 0xff, U4_8,R_12,0,0,0,0 },
+	[INSTR_RSE_CCRD]  = { 0xff, C_8,C_12,D_20,B_16,0,0 },
+	[INSTR_RSE_RRRD]  = { 0xff, R_8,R_12,D_20,B_16,0,0 },
+	[INSTR_RSE_RURD]  = { 0xff, R_8,U4_12,D_20,B_16,0,0 },
+	[INSTR_RSI_RRP]	  = { 0xff, R_8,R_12,J16_16,0,0,0 },
+	[INSTR_RSL_R0RD]  = { 0xff, D_20,L4_8,B_16,0,0,0 },
+	[INSTR_RSY_AARD]  = { 0xff, A_8,A_12,D20_20,B_16,0,0 },
+	[INSTR_RSY_CCRD]  = { 0xff, C_8,C_12,D20_20,B_16,0,0 },
+	[INSTR_RSY_RRRD]  = { 0xff, R_8,R_12,D20_20,B_16,0,0 },
 	[INSTR_RSY_RURD]  = { 0xff, R_8,U4_12,D20_20,B_16,0,0 },
-							       /* e.g. icmh  */
-	[INSTR_RSY_AARD]  = { 0xff, A_8,A_12,D20_20,B_16,0,0 },/* e.g. lamy  */
-	[INSTR_RSY_CCRD]  = { 0xff, C_8,C_12,D20_20,B_16,0,0 },/* e.g. lamy  */
-	[INSTR_RS_AARD]	  = { 0xff, A_8,A_12,D_20,B_16,0,0 },  /* e.g. lam   */
-	[INSTR_RS_CCRD]	  = { 0xff, C_8,C_12,D_20,B_16,0,0 },  /* e.g. lctl  */
-	[INSTR_RS_R0RD]	  = { 0xff, R_8,D_20,B_16,0,0,0 },     /* e.g. sll   */
-	[INSTR_RS_RRRD]	  = { 0xff, R_8,R_12,D_20,B_16,0,0 },  /* e.g. cs    */
-	[INSTR_RS_RURD]	  = { 0xff, R_8,U4_12,D_20,B_16,0,0 }, /* e.g. icm   */
-	[INSTR_RXE_FRRD]  = { 0xff, F_8,D_20,X_12,B_16,0,0 },  /* e.g. axbr  */
-	[INSTR_RXE_RRRD]  = { 0xff, R_8,D_20,X_12,B_16,0,0 },  /* e.g. lg    */
+	[INSTR_RS_AARD]	  = { 0xff, A_8,A_12,D_20,B_16,0,0 },
+	[INSTR_RS_CCRD]	  = { 0xff, C_8,C_12,D_20,B_16,0,0 },
+	[INSTR_RS_R0RD]	  = { 0xff, R_8,D_20,B_16,0,0,0 },
+	[INSTR_RS_RRRD]	  = { 0xff, R_8,R_12,D_20,B_16,0,0 },
+	[INSTR_RS_RURD]	  = { 0xff, R_8,U4_12,D_20,B_16,0,0 },
+	[INSTR_RXE_FRRD]  = { 0xff, F_8,D_20,X_12,B_16,0,0 },
+	[INSTR_RXE_RRRD]  = { 0xff, R_8,D_20,X_12,B_16,0,0 },
 	[INSTR_RXF_FRRDF] = { 0xff, F_32,F_8,D_20,X_12,B_16,0 },
-							       /* e.g. madb  */
-	[INSTR_RXY_RRRD]  = { 0xff, R_8,D20_20,X_12,B_16,0,0 },/* e.g. ly    */
-	[INSTR_RXY_FRRD]  = { 0xff, F_8,D20_20,X_12,B_16,0,0 },/* e.g. ley   */
-	[INSTR_RX_FRRD]	  = { 0xff, F_8,D_20,X_12,B_16,0,0 },  /* e.g. ae    */
-	[INSTR_RX_RRRD]	  = { 0xff, R_8,D_20,X_12,B_16,0,0 },  /* e.g. l     */
-	[INSTR_RX_URRD]	  = { 0xff, U4_8,D_20,X_12,B_16,0,0 }, /* e.g. bc    */
-	[INSTR_SI_URD]	  = { 0xff, D_20,B_16,U8_8,0,0,0 },    /* e.g. cli   */
-	[INSTR_SIY_URD]	  = { 0xff, D20_20,B_16,U8_8,0,0,0 },  /* e.g. tmy   */
-	[INSTR_SSE_RDRD]  = { 0xff, D_20,B_16,D_36,B_32,0,0 }, /* e.g. mvsdk */
+	[INSTR_RXY_FRRD]  = { 0xff, F_8,D20_20,X_12,B_16,0,0 },
+	[INSTR_RXY_RRRD]  = { 0xff, R_8,D20_20,X_12,B_16,0,0 },
+	[INSTR_RXY_URRD]  = { 0xff, U4_8,D20_20,X_12,B_16,0,0 },
+	[INSTR_RX_FRRD]	  = { 0xff, F_8,D_20,X_12,B_16,0,0 },
+	[INSTR_RX_RRRD]	  = { 0xff, R_8,D_20,X_12,B_16,0,0 },
+	[INSTR_RX_URRD]	  = { 0xff, U4_8,D_20,X_12,B_16,0,0 },
+	[INSTR_SIL_RDI]   = { 0xff, D_20,B_16,I16_32,0,0,0 },
+	[INSTR_SIL_RDU]   = { 0xff, D_20,B_16,U16_32,0,0,0 },
+	[INSTR_SIY_IRD]   = { 0xff, D20_20,B_16,I8_8,0,0,0 },
+	[INSTR_SIY_URD]	  = { 0xff, D20_20,B_16,U8_8,0,0,0 },
+	[INSTR_SI_URD]	  = { 0xff, D_20,B_16,U8_8,0,0,0 },
+	[INSTR_SSE_RDRD]  = { 0xff, D_20,B_16,D_36,B_32,0,0 },
+	[INSTR_SSF_RRDRD] = { 0x00, D_20,B_16,D_36,B_32,R_8,0 },
 	[INSTR_SS_L0RDRD] = { 0xff, D_20,L8_8,B_16,D_36,B_32,0 },
-							       /* e.g. mvc   */
 	[INSTR_SS_LIRDRD] = { 0xff, D_20,L4_8,B_16,D_36,B_32,U4_12 },
-							       /* e.g. srp   */
 	[INSTR_SS_LLRDRD] = { 0xff, D_20,L4_8,B_16,D_36,L4_12,B_32 },
-							       /* e.g. pack  */
-	[INSTR_SS_RRRDRD] = { 0xff, D_20,R_8,B_16,D_36,B_32,R_12 },
-							       /* e.g. mvck  */
 	[INSTR_SS_RRRDRD2]= { 0xff, R_8,D_20,B_16,R_12,D_36,B_32 },
-							       /* e.g. plo   */
 	[INSTR_SS_RRRDRD3]= { 0xff, R_8,R_12,D_20,B_16,D_36,B_32 },
-							       /* e.g. lmd   */
-	[INSTR_S_00]	  = { 0xff, 0,0,0,0,0,0 },	       /* e.g. hsch  */
-	[INSTR_S_RD]	  = { 0xff, D_20,B_16,0,0,0,0 },       /* e.g. lpsw  */
-	[INSTR_SSF_RRDRD] = { 0x00, D_20,B_16,D_36,B_32,R_8,0 },
-							       /* e.g. mvcos */
+	[INSTR_SS_RRRDRD] = { 0xff, D_20,R_8,B_16,D_36,B_32,R_12 },
+	[INSTR_S_00]	  = { 0xff, 0,0,0,0,0,0 },
+	[INSTR_S_RD]	  = { 0xff, D_20,B_16,0,0,0,0 },
 };
 
 static struct insn opcode[] = {
@@ -454,6 +493,8 @@ static struct insn opcode[] = {
 static struct insn opcode_01[] = {
 #ifdef CONFIG_64BIT
 	{ "sam64", 0x0e, INSTR_E },
+	{ "pfpo", 0x0a, INSTR_E },
+	{ "ptff", 0x04, INSTR_E },
 #endif
 	{ "pr", 0x01, INSTR_E },
 	{ "upt", 0x02, INSTR_E },
@@ -519,6 +560,8 @@ static struct insn opcode_b2[] = {
 	{ "cutfu", 0xa7, INSTR_RRF_M0RR },
 	{ "stfle", 0xb0, INSTR_S_RD },
 	{ "lpswe", 0xb2, INSTR_S_RD },
+	{ "srnmt", 0xb9, INSTR_S_RD },
+	{ "lfas", 0xbd, INSTR_S_RD },
 #endif
 	{ "stidp", 0x02, INSTR_S_RD },
 	{ "sck", 0x04, INSTR_S_RD },
@@ -589,7 +632,6 @@ static struct insn opcode_b2[] = {
 	{ "clst", 0x5d, INSTR_RRE_RR },
 	{ "srst", 0x5e, INSTR_RRE_RR },
 	{ "cmpsc", 0x63, INSTR_RRE_RR },
-	{ "cmpsc", 0x63, INSTR_RRE_RR },
 	{ "siga", 0x74, INSTR_S_RD },
 	{ "xsch", 0x76, INSTR_S_00 },
 	{ "rp", 0x77, INSTR_S_RD },
@@ -630,6 +672,57 @@ static struct insn opcode_b3[] = {
 	{ "cger", 0xc8, INSTR_RRF_U0RF },
 	{ "cgdr", 0xc9, INSTR_RRF_U0RF },
 	{ "cgxr", 0xca, INSTR_RRF_U0RF },
+	{ "lpdfr", 0x70, INSTR_RRE_FF },
+	{ "lndfr", 0x71, INSTR_RRE_FF },
+	{ "cpsdr", 0x72, INSTR_RRF_F0FF2 },
+	{ "lcdfr", 0x73, INSTR_RRE_FF },
+	{ "ldgr", 0xc1, INSTR_RRE_FR },
+	{ "lgdr", 0xcd, INSTR_RRE_RF },
+	{ "adtr", 0xd2, INSTR_RRR_F0FF },
+	{ "axtr", 0xda, INSTR_RRR_F0FF },
+	{ "cdtr", 0xe4, INSTR_RRE_FF },
+	{ "cxtr", 0xec, INSTR_RRE_FF },
+	{ "kdtr", 0xe0, INSTR_RRE_FF },
+	{ "kxtr", 0xe8, INSTR_RRE_FF },
+	{ "cedtr", 0xf4, INSTR_RRE_FF },
+	{ "cextr", 0xfc, INSTR_RRE_FF },
+	{ "cdgtr", 0xf1, INSTR_RRE_FR },
+	{ "cxgtr", 0xf9, INSTR_RRE_FR },
+	{ "cdstr", 0xf3, INSTR_RRE_FR },
+	{ "cxstr", 0xfb, INSTR_RRE_FR },
+	{ "cdutr", 0xf2, INSTR_RRE_FR },
+	{ "cxutr", 0xfa, INSTR_RRE_FR },
+	{ "cgdtr", 0xe1, INSTR_RRF_U0RF },
+	{ "cgxtr", 0xe9, INSTR_RRF_U0RF },
+	{ "csdtr", 0xe3, INSTR_RRE_RF },
+	{ "csxtr", 0xeb, INSTR_RRE_RF },
+	{ "cudtr", 0xe2, INSTR_RRE_RF },
+	{ "cuxtr", 0xea, INSTR_RRE_RF },
+	{ "ddtr", 0xd1, INSTR_RRR_F0FF },
+	{ "dxtr", 0xd9, INSTR_RRR_F0FF },
+	{ "eedtr", 0xe5, INSTR_RRE_RF },
+	{ "eextr", 0xed, INSTR_RRE_RF },
+	{ "esdtr", 0xe7, INSTR_RRE_RF },
+	{ "esxtr", 0xef, INSTR_RRE_RF },
+	{ "iedtr", 0xf6, INSTR_RRF_F0FR },
+	{ "iextr", 0xfe, INSTR_RRF_F0FR },
+	{ "ltdtr", 0xd6, INSTR_RRE_FF },
+	{ "ltxtr", 0xde, INSTR_RRE_FF },
+	{ "fidtr", 0xd7, INSTR_RRF_UUFF },
+	{ "fixtr", 0xdf, INSTR_RRF_UUFF },
+	{ "ldetr", 0xd4, INSTR_RRF_0UFF },
+	{ "lxdtr", 0xdc, INSTR_RRF_0UFF },
+	{ "ledtr", 0xd5, INSTR_RRF_UUFF },
+	{ "ldxtr", 0xdd, INSTR_RRF_UUFF },
+	{ "mdtr", 0xd0, INSTR_RRR_F0FF },
+	{ "mxtr", 0xd8, INSTR_RRR_F0FF },
+	{ "qadtr", 0xf5, INSTR_RRF_FUFF },
+	{ "qaxtr", 0xfd, INSTR_RRF_FUFF },
+	{ "rrdtr", 0xf7, INSTR_RRF_FFRU },
+	{ "rrxtr", 0xff, INSTR_RRF_FFRU },
+	{ "sfasr", 0x85, INSTR_RRE_R0 },
+	{ "sdtr", 0xd3, INSTR_RRR_F0FF },
+	{ "sxtr", 0xdb, INSTR_RRR_F0FF },
 #endif
 	{ "lpebr", 0x00, INSTR_RRE_FF },
 	{ "lnebr", 0x01, INSTR_RRE_FF },
@@ -780,6 +873,14 @@ static struct insn opcode_b9[] = {
 	{ "cu24", 0xb1, INSTR_RRF_M0RR },
 	{ "cu41", 0xb2, INSTR_RRF_M0RR },
 	{ "cu42", 0xb3, INSTR_RRF_M0RR },
+	{ "crt", 0x72, INSTR_RRF_U0RR },
+	{ "cgrt", 0x60, INSTR_RRF_U0RR },
+	{ "clrt", 0x73, INSTR_RRF_U0RR },
+	{ "clgrt", 0x61, INSTR_RRF_U0RR },
+	{ "ptf", 0xa2, INSTR_RRE_R0 },
+	{ "pfmf", 0xaf, INSTR_RRE_RR },
+	{ "trte", 0xbf, INSTR_RRF_M0RR },
+	{ "trtre", 0xbd, INSTR_RRF_M0RR },
 #endif
 	{ "kmac", 0x1e, INSTR_RRE_RR },
 	{ "lrvr", 0x1f, INSTR_RRE_RR },
@@ -835,6 +936,43 @@ static struct insn opcode_c2[] = {
 	{ "cfi", 0x0d, INSTR_RIL_RI },
 	{ "clgfi", 0x0e, INSTR_RIL_RU },
 	{ "clfi", 0x0f, INSTR_RIL_RU },
+	{ "msfi", 0x01, INSTR_RIL_RI },
+	{ "msgfi", 0x00, INSTR_RIL_RI },
+#endif
+	{ "", 0, INSTR_INVALID }
+};
+
+static struct insn opcode_c4[] = {
+#ifdef CONFIG_64BIT
+	{ "lrl", 0x0d, INSTR_RIL_RP },
+	{ "lgrl", 0x08, INSTR_RIL_RP },
+	{ "lgfrl", 0x0c, INSTR_RIL_RP },
+	{ "lhrl", 0x05, INSTR_RIL_RP },
+	{ "lghrl", 0x04, INSTR_RIL_RP },
+	{ "llgfrl", 0x0e, INSTR_RIL_RP },
+	{ "llhrl", 0x02, INSTR_RIL_RP },
+	{ "llghrl", 0x06, INSTR_RIL_RP },
+	{ "strl", 0x0f, INSTR_RIL_RP },
+	{ "stgrl", 0x0b, INSTR_RIL_RP },
+	{ "sthrl", 0x07, INSTR_RIL_RP },
+#endif
+	{ "", 0, INSTR_INVALID }
+};
+
+static struct insn opcode_c6[] = {
+#ifdef CONFIG_64BIT
+	{ "crl", 0x0d, INSTR_RIL_RP },
+	{ "cgrl", 0x08, INSTR_RIL_RP },
+	{ "cgfrl", 0x0c, INSTR_RIL_RP },
+	{ "chrl", 0x05, INSTR_RIL_RP },
+	{ "cghrl", 0x04, INSTR_RIL_RP },
+	{ "clrl", 0x0f, INSTR_RIL_RP },
+	{ "clgrl", 0x0a, INSTR_RIL_RP },
+	{ "clgfrl", 0x0e, INSTR_RIL_RP },
+	{ "clhrl", 0x07, INSTR_RIL_RP },
+	{ "clghrl", 0x06, INSTR_RIL_RP },
+	{ "pfdrl", 0x02, INSTR_RIL_UP },
+	{ "exrl", 0x00, INSTR_RIL_RP },
 #endif
 	{ "", 0, INSTR_INVALID }
 };
@@ -842,6 +980,8 @@ static struct insn opcode_c2[] = {
 static struct insn opcode_c8[] = {
 #ifdef CONFIG_64BIT
 	{ "mvcos", 0x00, INSTR_SSF_RRDRD },
+	{ "ectg", 0x01, INSTR_SSF_RRDRD },
+	{ "csst", 0x02, INSTR_SSF_RRDRD },
 #endif
 	{ "", 0, INSTR_INVALID }
 };
@@ -917,6 +1057,12 @@ static struct insn opcode_e3[] = {
 	{ "llgh", 0x91, INSTR_RXY_RRRD },
 	{ "llc", 0x94, INSTR_RXY_RRRD },
 	{ "llh", 0x95, INSTR_RXY_RRRD },
+	{ "cgh", 0x34, INSTR_RXY_RRRD },
+	{ "laey", 0x75, INSTR_RXY_RRRD },
+	{ "ltgf", 0x32, INSTR_RXY_RRRD },
+	{ "mfy", 0x5c, INSTR_RXY_RRRD },
+	{ "mhy", 0x7c, INSTR_RXY_RRRD },
+	{ "pfd", 0x36, INSTR_RXY_URRD },
 #endif
 	{ "lrv", 0x1e, INSTR_RXY_RRRD },
 	{ "lrvh", 0x1f, INSTR_RXY_RRRD },
@@ -931,6 +1077,15 @@ static struct insn opcode_e3[] = {
 static struct insn opcode_e5[] = {
 #ifdef CONFIG_64BIT
 	{ "strag", 0x02, INSTR_SSE_RDRD },
+	{ "chhsi", 0x54, INSTR_SIL_RDI },
+	{ "chsi", 0x5c, INSTR_SIL_RDI },
+	{ "cghsi", 0x58, INSTR_SIL_RDI },
+	{ "clhhsi", 0x55, INSTR_SIL_RDU },
+	{ "clfhsi", 0x5d, INSTR_SIL_RDU },
+	{ "clghsi", 0x59, INSTR_SIL_RDU },
+	{ "mvhhi", 0x44, INSTR_SIL_RDI },
+	{ "mvhi", 0x4c, INSTR_SIL_RDI },
+	{ "mvghi", 0x48, INSTR_SIL_RDI },
 #endif
 	{ "lasp", 0x00, INSTR_SSE_RDRD },
 	{ "tprot", 0x01, INSTR_SSE_RDRD },
@@ -977,6 +1132,11 @@ static struct insn opcode_eb[] = {
 	{ "lmy", 0x98, INSTR_RSY_RRRD },
 	{ "lamy", 0x9a, INSTR_RSY_AARD },
 	{ "stamy", 0x9b, INSTR_RSY_AARD },
+	{ "asi", 0x6a, INSTR_SIY_IRD },
+	{ "agsi", 0x7a, INSTR_SIY_IRD },
+	{ "alsi", 0x6e, INSTR_SIY_IRD },
+	{ "algsi", 0x7e, INSTR_SIY_IRD },
+	{ "ecag", 0x4c, INSTR_RSY_RRRD },
 #endif
 	{ "rll", 0x1d, INSTR_RSY_RRRD },
 	{ "mvclu", 0x8e, INSTR_RSY_RRRD },
@@ -988,6 +1148,30 @@ static struct insn opcode_ec[] = {
 #ifdef CONFIG_64BIT
 	{ "brxhg", 0x44, INSTR_RIE_RRP },
 	{ "brxlg", 0x45, INSTR_RIE_RRP },
+	{ "crb", 0xf6, INSTR_RRS_RRRDU },
+	{ "cgrb", 0xe4, INSTR_RRS_RRRDU },
+	{ "crj", 0x76, INSTR_RIE_RRPU },
+	{ "cgrj", 0x64, INSTR_RIE_RRPU },
+	{ "cib", 0xfe, INSTR_RIS_RURDI },
+	{ "cgib", 0xfc, INSTR_RIS_RURDI },
+	{ "cij", 0x7e, INSTR_RIE_RUPI },
+	{ "cgij", 0x7c, INSTR_RIE_RUPI },
+	{ "cit", 0x72, INSTR_RIE_R0IU },
+	{ "cgit", 0x70, INSTR_RIE_R0IU },
+	{ "clrb", 0xf7, INSTR_RRS_RRRDU },
+	{ "clgrb", 0xe5, INSTR_RRS_RRRDU },
+	{ "clrj", 0x77, INSTR_RIE_RRPU },
+	{ "clgrj", 0x65, INSTR_RIE_RRPU },
+	{ "clib", 0xff, INSTR_RIS_RURDU },
+	{ "clgib", 0xfd, INSTR_RIS_RURDU },
+	{ "clij", 0x7f, INSTR_RIE_RUPU },
+	{ "clgij", 0x7d, INSTR_RIE_RUPU },
+	{ "clfit", 0x73, INSTR_RIE_R0UU },
+	{ "clgit", 0x71, INSTR_RIE_R0UU },
+	{ "rnsbg", 0x54, INSTR_RIE_RRUUU },
+	{ "rxsbg", 0x57, INSTR_RIE_RRUUU },
+	{ "rosbg", 0x56, INSTR_RIE_RRUUU },
+	{ "risbg", 0x55, INSTR_RIE_RRUUU },
 #endif
 	{ "", 0, INSTR_INVALID }
 };
@@ -1004,6 +1188,16 @@ static struct insn opcode_ed[] = {
 	{ "ldy", 0x65, INSTR_RXY_FRRD },
 	{ "stey", 0x66, INSTR_RXY_FRRD },
 	{ "stdy", 0x67, INSTR_RXY_FRRD },
+	{ "sldt", 0x40, INSTR_RXF_FRRDF },
+	{ "slxt", 0x48, INSTR_RXF_FRRDF },
+	{ "srdt", 0x41, INSTR_RXF_FRRDF },
+	{ "srxt", 0x49, INSTR_RXF_FRRDF },
+	{ "tdcet", 0x50, INSTR_RXE_FRRD },
+	{ "tdcdt", 0x54, INSTR_RXE_FRRD },
+	{ "tdcxt", 0x58, INSTR_RXE_FRRD },
+	{ "tdget", 0x51, INSTR_RXE_FRRD },
+	{ "tdgdt", 0x55, INSTR_RXE_FRRD },
+	{ "tdgxt", 0x59, INSTR_RXE_FRRD },
 #endif
 	{ "ldeb", 0x04, INSTR_RXE_FRRD },
 	{ "lxdb", 0x05, INSTR_RXE_FRRD },
@@ -1037,6 +1231,7 @@ static struct insn opcode_ed[] = {
 	{ "mae", 0x2e, INSTR_RXF_FRRDF },
 	{ "mse", 0x2f, INSTR_RXF_FRRDF },
 	{ "sqe", 0x34, INSTR_RXE_FRRD },
+	{ "sqd", 0x35, INSTR_RXE_FRRD },
 	{ "mee", 0x37, INSTR_RXE_FRRD },
 	{ "mad", 0x3e, INSTR_RXF_FRRDF },
 	{ "msd", 0x3f, INSTR_RXF_FRRDF },
@@ -1117,6 +1312,12 @@ static struct insn *find_insn(unsigned c
 	case 0xc2:
 		table = opcode_c2;
 		break;
+	case 0xc4:
+		table = opcode_c4;
+		break;
+	case 0xc6:
+		table = opcode_c6;
+		break;
 	case 0xc8:
 		table = opcode_c8;
 		break;
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/early.c linux-libre-2.6.34-gnu1/arch/s390/kernel/early.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/early.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/early.c	2010-05-16 17:17:36.000000000 -0400
@@ -82,7 +82,8 @@ asm(
 	"	lm	6,15,24(15)\n"
 #endif
 	"	br	14\n"
-	"	.size	savesys_ipl_nss, .-savesys_ipl_nss\n");
+	"	.size	savesys_ipl_nss, .-savesys_ipl_nss\n"
+	"	.previous\n");
 
 static __initdata char upper_command_line[COMMAND_LINE_SIZE];
 
@@ -214,10 +215,13 @@ static __initdata struct sysinfo_3_2_2 v
 
 static noinline __init void detect_machine_type(void)
 {
-	/* No VM information? Looks like LPAR */
-	if (stsi(&vmms, 3, 2, 2) == -ENOSYS)
+	/* Check current-configuration-level */
+	if ((stsi(NULL, 0, 0, 0) >> 28) <= 2) {
+		S390_lowcore.machine_flags |= MACHINE_FLAG_LPAR;
 		return;
-	if (!vmms.count)
+	}
+	/* Get virtual-machine cpu information. */
+	if (stsi(&vmms, 3, 2, 2) == -ENOSYS || !vmms.count)
 		return;
 
 	/* Running under KVM? If not we assume z/VM */
@@ -402,8 +406,19 @@ static void __init append_to_cmdline(siz
 
 static void __init setup_boot_command_line(void)
 {
+	int i;
+
+	/* convert arch command line to ascii */
+	for (i = 0; i < ARCH_COMMAND_LINE_SIZE; i++)
+		if (COMMAND_LINE[i] & 0x80)
+			break;
+	if (i < ARCH_COMMAND_LINE_SIZE)
+		EBCASC(COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
+	COMMAND_LINE[ARCH_COMMAND_LINE_SIZE-1] = 0;
+
 	/* copy arch command line */
-	strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
+	strlcpy(boot_command_line, strstrip(COMMAND_LINE),
+		ARCH_COMMAND_LINE_SIZE);
 
 	/* append IPL PARM data to the boot command line */
 	if (MACHINE_IS_VM)
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/entry64.S linux-libre-2.6.34-gnu1/arch/s390/kernel/entry64.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/entry64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/entry64.S	2010-05-16 17:17:36.000000000 -0400
@@ -9,11 +9,9 @@
  *		 Heiko Carstens <heiko.carstens@de.ibm.com>
  */
 
-#include <linux/sys.h>
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/cache.h>
-#include <asm/lowcore.h>
 #include <asm/errno.h>
 #include <asm/ptrace.h>
 #include <asm/thread_info.h>
@@ -948,7 +946,7 @@ cleanup_critical:
 	clc	8(8,%r12),BASED(cleanup_table_io_work_loop)
 	jl	0f
 	clc	8(8,%r12),BASED(cleanup_table_io_work_loop+8)
-	jl	cleanup_io_return
+	jl	cleanup_io_work_loop
 0:
 	br	%r14
 
@@ -1023,6 +1021,12 @@ cleanup_sysc_leave_insn:
 
 cleanup_io_return:
 	mvc	__LC_RETURN_PSW(8),0(%r12)
+	mvc	__LC_RETURN_PSW+8(8),BASED(cleanup_table_io_return)
+	la	%r12,__LC_RETURN_PSW
+	br	%r14
+
+cleanup_io_work_loop:
+	mvc	__LC_RETURN_PSW(8),0(%r12)
 	mvc	__LC_RETURN_PSW+8(8),BASED(cleanup_table_io_work_loop)
 	la	%r12,__LC_RETURN_PSW
 	br	%r14
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/entry.h linux-libre-2.6.34-gnu1/arch/s390/kernel/entry.h
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/entry.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/entry.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,17 +24,13 @@ int __cpuinit start_secondary(void *cpuv
 void __init startup_init(void);
 void die(const char * str, struct pt_regs * regs, long err);
 
-struct new_utsname;
-struct mmap_arg_struct;
+struct s390_mmap_arg_struct;
 struct fadvise64_64_args;
 struct old_sigaction;
-struct sel_arg_struct;
 
-long sys_mmap2(struct mmap_arg_struct __user  *arg);
-long sys_s390_old_mmap(struct mmap_arg_struct __user *arg);
-long sys_ipc(uint call, int first, unsigned long second,
+long sys_mmap2(struct s390_mmap_arg_struct __user  *arg);
+long sys_s390_ipc(uint call, int first, unsigned long second,
 	     unsigned long third, void __user *ptr);
-long sys_s390_newuname(struct new_utsname __user *name);
 long sys_s390_personality(unsigned long personality);
 long sys_s390_fadvise64(int fd, u32 offset_high, u32 offset_low,
 		    size_t len, int advice);
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/entry.S linux-libre-2.6.34-gnu1/arch/s390/kernel/entry.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/entry.S	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/cache.h>
-#include <asm/lowcore.h>
 #include <asm/errno.h>
 #include <asm/ptrace.h>
 #include <asm/thread_info.h>
@@ -965,7 +964,7 @@ cleanup_critical:
 	clc	4(4,%r12),BASED(cleanup_table_io_work_loop)
 	bl	BASED(0f)
 	clc	4(4,%r12),BASED(cleanup_table_io_work_loop+4)
-	bl	BASED(cleanup_io_return)
+	bl	BASED(cleanup_io_work_loop)
 0:
 	br	%r14
 
@@ -1040,6 +1039,12 @@ cleanup_sysc_leave_insn:
 
 cleanup_io_return:
 	mvc	__LC_RETURN_PSW(4),0(%r12)
+	mvc	__LC_RETURN_PSW+4(4),BASED(cleanup_table_io_return)
+	la	%r12,__LC_RETURN_PSW
+	br	%r14
+
+cleanup_io_work_loop:
+	mvc	__LC_RETURN_PSW(4),0(%r12)
 	mvc	__LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop)
 	la	%r12,__LC_RETURN_PSW
 	br	%r14
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/ftrace.c linux-libre-2.6.34-gnu1/arch/s390/kernel/ftrace.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/ftrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/ftrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <trace/syscall.h>
-#include <asm/lowcore.h>
+#include <asm/asm-offsets.h>
 
 #ifdef CONFIG_DYNAMIC_FTRACE
 
@@ -200,13 +200,3 @@ out:
 	return parent;
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
-
-#ifdef CONFIG_FTRACE_SYSCALLS
-
-extern unsigned int sys_call_table[];
-
-unsigned long __init arch_syscall_addr(int nr)
-{
-	return (unsigned long)sys_call_table[nr];
-}
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/head31.S linux-libre-2.6.34-gnu1/arch/s390/kernel/head31.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/head31.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/head31.S	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * arch/s390/kernel/head31.S
  *
- * Copyright (C) IBM Corp. 2005,2006
+ * Copyright (C) IBM Corp. 2005,2010
  *
  *   Author(s):	Hartmut Penner <hp@de.ibm.com>
  *		Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -10,13 +10,19 @@
  *
  */
 
-	.org	0x11000
+#include <linux/init.h>
+#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
+#include <asm/page.h>
 
+__HEAD
+	.globl	startup_continue
 startup_continue:
 	basr	%r13,0			# get base
 .LPG1:
 
-	mvi	__LC_AR_MODE_ID,0	# set ESA flag (mode 0)
+	l	%r1,.Lbase_cc-.LPG1(%r13)
+	mvc	0(8,%r1),__LC_LAST_UPDATE_CLOCK
 	lctl	%c0,%c15,.Lctl-.LPG1(%r13) # load control registers
 	l	%r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
 					# move IPL device to lowcore
@@ -69,12 +75,14 @@ startup_continue:
 .Lduald:.rept	8
 	.long	0x80000000,0,0,0	# invalid access-list entries
 	.endr
+.Lbase_cc:
+	.long	sched_clock_base_cc
 
-	.org	0x12000
 	.globl	_ehead
 _ehead:
+
 #ifdef CONFIG_SHARED_KERNEL
-	.org	0x100000
+	.org	0x100000 - 0x11000	# head.o ends at 0x11000
 #endif
 
 #
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/head64.S linux-libre-2.6.34-gnu1/arch/s390/kernel/head64.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/head64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/head64.S	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * arch/s390/kernel/head64.S
  *
- * Copyright (C) IBM Corp. 1999,2006
+ * Copyright (C) IBM Corp. 1999,2010
  *
  *   Author(s):	Hartmut Penner <hp@de.ibm.com>
  *		Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -10,81 +10,17 @@
  *
  */
 
-	.org	0x11000
+#include <linux/init.h>
+#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
+#include <asm/page.h>
 
+__HEAD
+	.globl	startup_continue
 startup_continue:
-	basr	%r13,0			# get base
-.LPG1:	sll	%r13,1			# remove high order bit
-	srl	%r13,1
-
-#ifdef CONFIG_ZFCPDUMP
-
-	# check if we have been ipled using zfcp dump:
-
-	tm	0xb9,0x01		# test if subchannel is enabled
-	jno	.nodump			# subchannel disabled
-	l	%r1,0xb8
-	la	%r5,.Lipl_schib-.LPG1(%r13)
-	stsch	0(%r5)			# get schib of subchannel
-	jne	.nodump			# schib not available
-	tm	5(%r5),0x01		# devno valid?
-	jno	.nodump
-	tm	4(%r5),0x80		# qdio capable device?
-	jno	.nodump
-	l	%r2,20(%r0)		# address of ipl parameter block
-	lhi	%r3,0
-	ic	%r3,0x148(%r2)		# get opt field
-	chi	%r3,0x20		# load with dump?
-	jne	.nodump
-
-	# store all prefix registers in case of load with dump:
-
-	la	%r7,0			# base register for 0 page
-	la	%r8,0			# first cpu
-	l	%r11,.Lpref_arr_ptr-.LPG1(%r13)	# address of prefix array
-	ahi	%r11,4			# skip boot cpu
-	lr	%r12,%r11
-	ahi	%r12,(CONFIG_NR_CPUS*4)	# end of prefix array
-	stap	.Lcurrent_cpu+2-.LPG1(%r13)	# store current cpu addr
-1:
-	cl	%r8,.Lcurrent_cpu-.LPG1(%r13)	# is ipl cpu ?
-	je	4f				# if yes get next cpu
-2:
-	lr	%r9,%r7
-	sigp	%r9,%r8,0x9		# stop & store status of cpu
-	brc	8,3f			# accepted
-	brc	4,4f			# status stored: next cpu
-	brc	2,2b			# busy: 	 try again
-	brc	1,4f			# not op:	 next cpu
-3:
-	mvc	0(4,%r11),264(%r7)	# copy prefix register to prefix array
-	ahi	%r11,4			# next element in prefix array
-	clr	%r11,%r12
-	je	5f			# no more space in prefix array
-4:
-	ahi	%r8,1			# next cpu (r8 += 1)
-	chi	%r8,MAX_CPU_ADDRESS	# is last possible cpu ?
-	jle	1b			# jump if not last cpu
-5:
-	lhi	%r1,2			# mode 2 = esame (dump)
-	j	6f
-	.align 4
-.Lipl_schib:
-	.rept 13
-	.long 0
-	.endr
-.nodump:
-	lhi	%r1,1			# mode 1 = esame (normal ipl)
-6:
-#else
-	lhi	%r1,1			# mode 1 = esame (normal ipl)
-#endif /* CONFIG_ZFCPDUMP */
-	mvi	__LC_AR_MODE_ID,1	# set esame flag
-	slr	%r0,%r0 		# set cpuid to zero
-	sigp	%r1,%r0,0x12		# switch to esame mode
-	sam64				# switch to 64 bit mode
-	llgfr	%r13,%r13		# clear high-order half of base reg
-	lmh	%r0,%r15,.Lzero64-.LPG1(%r13)	# clear high-order half
+	larl	%r1,sched_clock_base_cc
+	mvc	0(8,%r1),__LC_LAST_UPDATE_CLOCK
+	larl	%r13,.LPG1		# get base
 	lctlg	%c0,%c15,.Lctl-.LPG1(%r13)	# load control registers
 	lg	%r12,.Lparmaddr-.LPG1(%r13)	# pointer to parameter area
 					# move IPL device to lowcore
@@ -108,6 +44,7 @@ startup_continue:
 	lpswe	.Lentry-.LPG1(13)	# jump to _stext in primary-space,
 					# virtual and never return ...
 	.align	16
+.LPG1:
 .Lentry:.quad	0x0000000180000000,_stext
 .Lctl:	.quad	0x04350002		# cr0: various things
 	.quad	0			# cr1: primary space segment table
@@ -129,13 +66,6 @@ startup_continue:
 .L4malign:.quad 0xffffffffffc00000
 .Lscan2g:.quad	0x80000000 + 0x20000 - 8	# 2GB + 128K - 8
 .Lnop:	.long	0x07000700
-.Lzero64:.fill	16,4,0x0
-#ifdef CONFIG_ZFCPDUMP
-.Lcurrent_cpu:
-	.long 0x0
-.Lpref_arr_ptr:
-	.long zfcpdump_prefix_array
-#endif /* CONFIG_ZFCPDUMP */
 .Lparmaddr:
 	.quad	PARMAREA
 	.align	64
@@ -146,11 +76,11 @@ startup_continue:
 	.long	0x80000000,0,0,0	# invalid access-list entries
 	.endr
 
-	.org	0x12000
 	.globl	_ehead
 _ehead:
+
 #ifdef CONFIG_SHARED_KERNEL
-	.org	0x100000
+	.org	0x100000 - 0x11000	# head.o ends at 0x11000
 #endif
 
 #
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/head.S linux-libre-2.6.34-gnu1/arch/s390/kernel/head.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/head.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/head.S	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright IBM Corp. 1999,2009
+ * Copyright IBM Corp. 1999,2010
  *
  *    Author(s): Hartmut Penner <hp@de.ibm.com>
  *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -22,12 +22,9 @@
  */
 
 #include <linux/init.h>
-#include <asm/setup.h>
-#include <asm/lowcore.h>
 #include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
 #include <asm/page.h>
-#include <asm/cpu.h>
 
 #ifdef CONFIG_64BIT
 #define ARCH_OFFSET	4
@@ -288,19 +285,7 @@ iplstart:
 	bz	.Lagain1		# skip dateset trailer
 	la	%r5,0(%r4,%r2)
 	lr	%r3,%r2
-.Lidebc:
-	tm	0(%r5),0x80		# high order bit set ?
-	bo	.Ldocv			#  yes -> convert from EBCDIC
-	ahi	%r5,-1
-	bct	%r3,.Lidebc
-	b	.Lnocv
-.Ldocv:
-	l	%r3,.Lcvtab
-	tr	0(256,%r4),0(%r3)	# convert parameters to ascii
-	tr	256(256,%r4),0(%r3)
-	tr	512(256,%r4),0(%r3)
-	tr	768(122,%r4),0(%r3)
-.Lnocv: la	%r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
+	la	%r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
 	mvc	0(256,%r3),0(%r4)
 	mvc	256(256,%r3),256(%r4)
 	mvc	512(256,%r3),512(%r4)
@@ -384,7 +369,6 @@ iplstart:
 .Linitrd:.long _end + 0x400000		# default address of initrd
 .Lparm:	.long  PARMAREA
 .Lstartup: .long startup
-.Lcvtab:.long	_ebcasc 		# ebcdic to ascii table
 .Lreset:.byte	0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
 	.byte	0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
 	.byte	0xc8,0xd6,0xd3,0xc4	# "change rdr all keep nohold"
@@ -417,13 +401,10 @@ start:
 .sk8x8:
 	mvc	0(240,%r8),0(%r9)	# copy iplparms into buffer
 .gotr:
-	l	%r10,.tbl		# EBCDIC to ASCII table
-	tr	0(240,%r8),0(%r10)
 	slr	%r0,%r0
 	st	%r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
 	st	%r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
 	j	startup 		# continue with startup
-.tbl:	.long	_ebcasc			# translate table
 .cmd:	.long	COMMAND_LINE		# address of command line buffer
 .parm:	.long	PARMAREA
 .lowcase:
@@ -467,16 +448,15 @@ start:
 # or linload or SALIPL
 #
 	.org	0x10000
-startup:basr	%r13,0			# get base
+	.globl	startup
+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)
+	stck	__LC_LAST_UPDATE_CLOCK
+	spt	5f-.LPG0(%r13)
+	mvc	__LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
 #ifndef CONFIG_MARCH_G5
 	# check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
 	xc	__LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
@@ -494,7 +474,6 @@ startup:basr	%r13,0			# get base
 	cl	%r0,2f+12-.LPG0(%r13)
 	je	3f
 1:	l	%r15,.Lstack-.LPG0(%r13)
-	ahi	%r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
 	ahi	%r15,-96
 	la	%r2,.Lals_string-.LPG0(%r13)
 	l	%r3,.Lsclp_print-.LPG0(%r13)
@@ -505,7 +484,7 @@ startup:basr	%r13,0			# get base
 .Lsclp_print:
 	.long	_sclp_print_early
 .Lstack:
-	.long	init_thread_union
+	.long	0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
 	.align 16
 2:	.long	0x000a0000,0x8badcccc
 #if defined(CONFIG_64BIT)
@@ -532,13 +511,25 @@ startup:basr	%r13,0			# get base
 3:
 #endif
 
+#ifdef CONFIG_64BIT
+	mvi	__LC_AR_MODE_ID,1	# set esame flag
+	slr	%r0,%r0 		# set cpuid to zero
+	lhi	%r1,2			# mode 2 = esame (dump)
+	sigp	%r1,%r0,0x12		# switch to esame mode
+	sam64				# switch to 64 bit mode
+	larl	%r13,4f
+	lmh	%r0,%r15,0(%r13)	# clear high-order half
+	jg	startup_continue
+4:	.fill	16,4,0x0
+#else
+	mvi	__LC_AR_MODE_ID,0	# set ESA flag (mode 0)
 	l	%r13,4f-.LPG0(%r13)
 	b	0(%r13)
-	.align	4
+	.align	8
 4:	.long	startup_continue
-5:	.long	sched_clock_base_cc
+#endif
 	.align	8
-6:	.long	0x7fffffff,0xffffffff
+5:	.long	0x7fffffff,0xffffffff
 
 #
 # params at 10400 (setup.h)
@@ -552,8 +543,4 @@ startup:basr	%r13,0			# get base
 	.byte	"root=/dev/ram0 ro"
 	.byte	0
 
-#ifdef CONFIG_64BIT
-#include "head64.S"
-#else
-#include "head31.S"
-#endif
+	.org	0x11000
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/ipl.c linux-libre-2.6.34-gnu1/arch/s390/kernel/ipl.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/ipl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/ipl.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/reboot.h>
 #include <linux/ctype.h>
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <asm/ipl.h>
 #include <asm/smp.h>
 #include <asm/setup.h>
@@ -553,7 +554,7 @@ out:
 	return rc;
 }
 
-static void ipl_run(struct shutdown_trigger *trigger)
+static void __ipl_run(void *unused)
 {
 	diag308(DIAG308_IPL, NULL);
 	if (MACHINE_IS_VM)
@@ -562,6 +563,11 @@ static void ipl_run(struct shutdown_trig
 		reipl_ccw_dev(&ipl_info.data.ccw.dev_id);
 }
 
+static void ipl_run(struct shutdown_trigger *trigger)
+{
+	smp_switch_to_ipl_cpu(__ipl_run, NULL);
+}
+
 static int __init ipl_init(void)
 {
 	int rc;
@@ -1039,7 +1045,7 @@ static void get_ipl_string(char *dst, st
 		sprintf(dst + pos, " PARM %s", vmparm);
 }
 
-static void reipl_run(struct shutdown_trigger *trigger)
+static void __reipl_run(void *unused)
 {
 	struct ccw_dev_id devid;
 	static char buf[128];
@@ -1087,6 +1093,11 @@ static void reipl_run(struct shutdown_tr
 	disabled_wait((unsigned long) __builtin_return_address(0));
 }
 
+static void reipl_run(struct shutdown_trigger *trigger)
+{
+	smp_switch_to_ipl_cpu(__reipl_run, NULL);
+}
+
 static void reipl_block_ccw_init(struct ipl_parameter_block *ipb)
 {
 	ipb->hdr.len = IPL_PARM_BLK_CCW_LEN;
@@ -1369,20 +1380,18 @@ static struct kobj_attribute dump_type_a
 
 static struct kset *dump_kset;
 
-static void dump_run(struct shutdown_trigger *trigger)
+static void __dump_run(void *unused)
 {
 	struct ccw_dev_id devid;
 	static char buf[100];
 
 	switch (dump_method) {
 	case DUMP_METHOD_CCW_CIO:
-		smp_send_stop();
 		devid.devno = dump_block_ccw->ipl_info.ccw.devno;
 		devid.ssid  = 0;
 		reipl_ccw_dev(&devid);
 		break;
 	case DUMP_METHOD_CCW_VM:
-		smp_send_stop();
 		sprintf(buf, "STORE STATUS");
 		__cpcmd(buf, NULL, 0, NULL);
 		sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
@@ -1396,10 +1405,17 @@ static void dump_run(struct shutdown_tri
 		diag308(DIAG308_SET, dump_block_fcp);
 		diag308(DIAG308_DUMP, NULL);
 		break;
-	case DUMP_METHOD_NONE:
-		return;
+	default:
+		break;
 	}
-	printk(KERN_EMERG "Dump failed!\n");
+}
+
+static void dump_run(struct shutdown_trigger *trigger)
+{
+	if (dump_method == DUMP_METHOD_NONE)
+		return;
+	smp_send_stop();
+	smp_switch_to_ipl_cpu(__dump_run, NULL);
 }
 
 static int __init dump_ccw_init(void)
@@ -1577,7 +1593,7 @@ static void vmcmd_run(struct shutdown_tr
 static int vmcmd_init(void)
 {
 	if (!MACHINE_IS_VM)
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 	vmcmd_kset = kset_create_and_add("vmcmd", NULL, firmware_kobj);
 	if (!vmcmd_kset)
 		return -ENOMEM;
@@ -1595,7 +1611,7 @@ static void stop_run(struct shutdown_tri
 {
 	if (strcmp(trigger->name, ON_PANIC_STR) == 0)
 		disabled_wait((unsigned long) __builtin_return_address(0));
-	while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy)
+	while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
 		cpu_relax();
 	for (;;);
 }
@@ -1902,7 +1918,6 @@ void __init ipl_update_parameters(void)
 void __init ipl_save_parameters(void)
 {
 	struct cio_iplinfo iplinfo;
-	unsigned int *ipl_ptr;
 	void *src, *dst;
 
 	if (cio_get_iplinfo(&iplinfo))
@@ -1913,11 +1928,10 @@ void __init ipl_save_parameters(void)
 	if (!iplinfo.is_qdio)
 		return;
 	ipl_flags |= IPL_PARMBLOCK_VALID;
-	ipl_ptr = (unsigned int *)__LC_IPL_PARMBLOCK_PTR;
-	src = (void *)(unsigned long)*ipl_ptr;
+	src = (void *)(unsigned long)S390_lowcore.ipl_parmblock_ptr;
 	dst = (void *)IPL_PARMBLOCK_ORIGIN;
 	memmove(dst, src, PAGE_SIZE);
-	*ipl_ptr = IPL_PARMBLOCK_ORIGIN;
+	S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN;
 }
 
 static LIST_HEAD(rcall);
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/kprobes.c linux-libre-2.6.34-gnu1/arch/s390/kernel/kprobes.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/kprobes.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/kprobes.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <asm/cacheflush.h>
 #include <asm/sections.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/machine_kexec.c linux-libre-2.6.34-gnu1/arch/s390/kernel/machine_kexec.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/machine_kexec.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/machine_kexec.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,11 +54,11 @@ void machine_shutdown(void)
 {
 }
 
-void machine_kexec(struct kimage *image)
+static void __machine_kexec(void *data)
 {
 	relocate_kernel_t data_mover;
+	struct kimage *image = data;
 
-	smp_send_stop();
 	pfault_fini();
 	s390_reset_system();
 
@@ -68,3 +68,9 @@ void machine_kexec(struct kimage *image)
 	(*data_mover)(&image->head, image->start);
 	for (;;);
 }
+
+void machine_kexec(struct kimage *image)
+{
+	smp_send_stop();
+	smp_switch_to_ipl_cpu(__machine_kexec, image);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/Makefile linux-libre-2.6.34-gnu1/arch/s390/kernel/Makefile
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -29,9 +29,12 @@ obj-y	+= $(if $(CONFIG_64BIT),entry64.o,
 obj-y	+= $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
 
 extra-y				+= head.o init_task.o vmlinux.lds
+extra-y				+= $(if $(CONFIG_64BIT),head64.o,head31.o)
 
 obj-$(CONFIG_MODULES)		+= s390_ksyms.o module.o
 obj-$(CONFIG_SMP)		+= smp.o topology.o
+obj-$(CONFIG_SMP)		+= $(if $(CONFIG_64BIT),switch_cpu64.o, \
+							switch_cpu.o)
 obj-$(CONFIG_HIBERNATION)	+= suspend.o swsusp_asm64.o
 obj-$(CONFIG_AUDIT)		+= audit.o
 compat-obj-$(CONFIG_AUDIT)	+= compat_audit.o
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/process.c linux-libre-2.6.34-gnu1/arch/s390/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,9 +16,9 @@
 #include <linux/fs.h>
 #include <linux/smp.h>
 #include <linux/stddef.h>
+#include <linux/slab.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/user.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/s390/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -640,7 +640,7 @@ long compat_arch_ptrace(struct task_stru
 
 asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 {
-	long ret;
+	long ret = 0;
 
 	/* Do the secure computing check first. */
 	secure_computing(regs->gprs[2]);
@@ -649,7 +649,6 @@ asmlinkage long do_syscall_trace_enter(s
 	 * The sysc_tracesys code in entry.S stored the system
 	 * call number to gprs[2].
 	 */
-	ret = regs->gprs[2];
 	if (test_thread_flag(TIF_SYSCALL_TRACE) &&
 	    (tracehook_report_syscall_entry(regs) ||
 	     regs->gprs[2] >= NR_syscalls)) {
@@ -671,7 +670,7 @@ asmlinkage long do_syscall_trace_enter(s
 				    regs->gprs[2], regs->orig_gpr2,
 				    regs->gprs[3], regs->gprs[4],
 				    regs->gprs[5]);
-	return ret;
+	return ret ?: regs->gprs[2];
 }
 
 asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
@@ -992,3 +991,61 @@ const struct user_regset_view *task_user
 #endif
 	return &user_s390_view;
 }
+
+static const char *gpr_names[NUM_GPRS] = {
+	"r0", "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
+	"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+};
+
+unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset)
+{
+	if (offset >= NUM_GPRS)
+		return 0;
+	return regs->gprs[offset];
+}
+
+int regs_query_register_offset(const char *name)
+{
+	unsigned long offset;
+
+	if (!name || *name != 'r')
+		return -EINVAL;
+	if (strict_strtoul(name + 1, 10, &offset))
+		return -EINVAL;
+	if (offset >= NUM_GPRS)
+		return -EINVAL;
+	return offset;
+}
+
+const char *regs_query_register_name(unsigned int offset)
+{
+	if (offset >= NUM_GPRS)
+		return NULL;
+	return gpr_names[offset];
+}
+
+static int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
+{
+	unsigned long ksp = kernel_stack_pointer(regs);
+
+	return (addr & ~(THREAD_SIZE - 1)) == (ksp & ~(THREAD_SIZE - 1));
+}
+
+/**
+ * regs_get_kernel_stack_nth() - get Nth entry of the stack
+ * @regs:pt_regs which contains kernel stack pointer.
+ * @n:stack entry number.
+ *
+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
+ * is specifined by @regs. If the @n th entry is NOT in the kernel stack,
+ * this returns 0.
+ */
+unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
+{
+	unsigned long addr;
+
+	addr = kernel_stack_pointer(regs) + n * sizeof(long);
+	if (!regs_within_kernel_stack(regs, addr))
+		return 0;
+	return *(unsigned long *)addr;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/reipl64.S linux-libre-2.6.34-gnu1/arch/s390/kernel/reipl64.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/reipl64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/reipl64.S	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
  *		 Denis Joseph Barrow,
  */
 
-#include <asm/lowcore.h>
+#include <asm/asm-offsets.h>
 
 #
 # do_reipl_asm
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/reipl.S linux-libre-2.6.34-gnu1/arch/s390/kernel/reipl.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/reipl.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/reipl.S	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *    Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com)
  */
 
-#include <asm/lowcore.h>
+#include <asm/asm-offsets.h>
 
 #
 # do_reipl_asm
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/sclp.S linux-libre-2.6.34-gnu1/arch/s390/kernel/sclp.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/sclp.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/sclp.S	2010-05-16 17:17:36.000000000 -0400
@@ -9,8 +9,10 @@
  */
 
 LC_EXT_NEW_PSW		= 0x58			# addr of ext int handler
+LC_EXT_NEW_PSW_64	= 0x1b0			# addr of ext int handler 64 bit
 LC_EXT_INT_PARAM	= 0x80			# addr of ext int parameter
 LC_EXT_INT_CODE		= 0x86			# addr of ext int code
+LC_AR_MODE_ID		= 0xa3
 
 #
 # Subroutine which waits synchronously until either an external interruption
@@ -30,8 +32,16 @@ _sclp_wait_int:
 .LbaseS1:
 	ahi	%r15,-96			# create stack frame
 	la	%r8,LC_EXT_NEW_PSW		# register int handler
-	mvc	.LoldpswS1-.LbaseS1(8,%r13),0(%r8)
-	mvc	0(8,%r8),.LextpswS1-.LbaseS1(%r13)
+	la	%r9,.LextpswS1-.LbaseS1(%r13)
+#ifdef CONFIG_64BIT
+	tm	LC_AR_MODE_ID,1
+	jno	.Lesa1
+	la	%r8,LC_EXT_NEW_PSW_64		# register int handler 64 bit
+	la	%r9,.LextpswS1_64-.LbaseS1(%r13)
+.Lesa1:
+#endif
+	mvc	.LoldpswS1-.LbaseS1(16,%r13),0(%r8)
+	mvc	0(16,%r8),0(%r9)
 	lhi	%r6,0x0200			# cr mask for ext int (cr0.54)
 	ltr	%r2,%r2
 	jz	.LsetctS1
@@ -64,15 +74,19 @@ _sclp_wait_int:
 .LtimeoutS1:
 	lctl	%c0,%c0,.LctlS1-.LbaseS1(%r13)	# restore interrupt setting
 	# restore old handler
-	mvc	0(8,%r8),.LoldpswS1-.LbaseS1(%r13)
+	mvc	0(16,%r8),.LoldpswS1-.LbaseS1(%r13)
 	lm	%r6,%r15,120(%r15)		# restore registers
 	br	%r14				# return to caller
 
 	.align	8
 .LoldpswS1:
-	.long	0, 0				# old ext int PSW
+	.long	0, 0, 0, 0			# old ext int PSW
 .LextpswS1:
 	.long	0x00080000, 0x80000000+.LwaitS1	# PSW to handle ext int
+#ifdef CONFIG_64BIT
+.LextpswS1_64:
+	.quad	0x0000000180000000, .LwaitS1	# PSW to handle ext int, 64 bit
+#endif
 .LwaitpswS1:
 	.long	0x010a0000, 0x00000000+.LloopS1	# PSW to wait for ext int
 .LtimeS1:
@@ -221,7 +235,7 @@ _sclp_print:
 	lh	%r9,0(%r8)			# update sccb length
 	ar	%r9,%r6
 	sth	%r9,0(%r8)
-	ar	%r7,%r6				# update current mto adress
+	ar	%r7,%r6				# update current mto address
 	ltr	%r0,%r0				# more characters?
 	jnz	.LinitmtoS4
 	l	%r2,.LwritedataS4-.LbaseS4(%r13)# write data
@@ -250,6 +264,13 @@ _sclp_print:
 _sclp_print_early:
 	stm	%r6,%r15,24(%r15)		# save registers
 	ahi	%r15,-96			# create stack frame
+#ifdef CONFIG_64BIT
+	tm	LC_AR_MODE_ID,1
+	jno	.Lesa2
+	ahi	%r15,-80
+	stmh	%r6,%r15,96(%r15)		# store upper register halves
+.Lesa2:
+#endif
 	lr	%r10,%r2			# save string pointer
 	lhi	%r2,0
 	bras	%r14,_sclp_setup		# enable console
@@ -262,6 +283,13 @@ _sclp_print_early:
 	lhi	%r2,1
 	bras	%r14,_sclp_setup		# disable console
 .LendS5:
+#ifdef CONFIG_64BIT
+	tm	LC_AR_MODE_ID,1
+	jno	.Lesa3
+	lmh	%r6,%r15,96(%r15)		# store upper register halves
+	ahi	%r15,80
+.Lesa3:
+#endif
 	lm	%r6,%r15,120(%r15)		# restore registers
 	br	%r14
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/setup.c linux-libre-2.6.34-gnu1/arch/s390/kernel/setup.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/tty.h>
 #include <linux/ioport.h>
@@ -396,15 +395,12 @@ static void __init
 setup_lowcore(void)
 {
 	struct _lowcore *lc;
-	int lc_pages;
 
 	/*
 	 * Setup lowcore for boot cpu
 	 */
-	lc_pages = sizeof(void *) == 8 ? 2 : 1;
-	lc = (struct _lowcore *)
-		__alloc_bootmem(lc_pages * PAGE_SIZE, lc_pages * PAGE_SIZE, 0);
-	memset(lc, 0, lc_pages * PAGE_SIZE);
+	BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096);
+	lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
 	lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
 	lc->restart_psw.addr =
 		PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
@@ -436,7 +432,7 @@ setup_lowcore(void)
 #ifndef CONFIG_64BIT
 	if (MACHINE_HAS_IEEE) {
 		lc->extended_save_area_addr = (__u32)
-			__alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0);
+			__alloc_bootmem_low(PAGE_SIZE, PAGE_SIZE, 0);
 		/* enable extended save area */
 		__ctl_set_bit(14, 29);
 	}
@@ -804,7 +800,7 @@ setup_arch(char **cmdline_p)
 	if (MACHINE_IS_VM)
 		pr_info("Linux is running as a z/VM "
 			"guest operating system in 31-bit mode\n");
-	else
+	else if (MACHINE_IS_LPAR)
 		pr_info("Linux is running natively in 31-bit mode\n");
 	if (MACHINE_HAS_IEEE)
 		pr_info("The hardware system has IEEE compatible "
@@ -818,7 +814,7 @@ setup_arch(char **cmdline_p)
 			"guest operating system in 64-bit mode\n");
 	else if (MACHINE_IS_KVM)
 		pr_info("Linux is running under KVM in 64-bit mode\n");
-	else
+	else if (MACHINE_IS_LPAR)
 		pr_info("Linux is running natively in 64-bit mode\n");
 #endif /* CONFIG_64BIT */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/smp.c linux-libre-2.6.34-gnu1/arch/s390/kernel/smp.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/smp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,8 @@
 #include <linux/cpu.h>
 #include <linux/timex.h>
 #include <linux/bootmem.h>
+#include <linux/slab.h>
+#include <asm/asm-offsets.h>
 #include <asm/ipl.h>
 #include <asm/setup.h>
 #include <asm/sigp.h>
@@ -53,7 +55,7 @@
 #include "entry.h"
 
 /* logical cpu to cpu address */
-int __cpu_logical_map[NR_CPUS];
+unsigned short __cpu_logical_map[NR_CPUS];
 
 static struct task_struct *current_set[NR_CPUS];
 
@@ -72,13 +74,13 @@ static int cpu_management;
 
 static DEFINE_PER_CPU(struct cpu, cpu_devices);
 
-static void smp_ext_bitcall(int, ec_bit_sig);
+static void smp_ext_bitcall(int, int);
 
-static int cpu_stopped(int cpu)
+static int raw_cpu_stopped(int cpu)
 {
-	__u32 status;
+	u32 status;
 
-	switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) {
+	switch (raw_sigp_ps(&status, 0, cpu, sigp_sense)) {
 	case sigp_status_stored:
 		/* Check for stopped and check stop state */
 		if (status & 0x50)
@@ -90,6 +92,44 @@ static int cpu_stopped(int cpu)
 	return 0;
 }
 
+static inline int cpu_stopped(int cpu)
+{
+	return raw_cpu_stopped(cpu_logical_map(cpu));
+}
+
+void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
+{
+	struct _lowcore *lc, *current_lc;
+	struct stack_frame *sf;
+	struct pt_regs *regs;
+	unsigned long sp;
+
+	if (smp_processor_id() == 0)
+		func(data);
+	__load_psw_mask(PSW_BASE_BITS | PSW_DEFAULT_KEY);
+	/* Disable lowcore protection */
+	__ctl_clear_bit(0, 28);
+	current_lc = lowcore_ptr[smp_processor_id()];
+	lc = lowcore_ptr[0];
+	if (!lc)
+		lc = current_lc;
+	lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+	lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) smp_restart_cpu;
+	if (!cpu_online(0))
+		smp_switch_to_cpu(func, data, 0, stap(), __cpu_logical_map[0]);
+	while (sigp(0, sigp_stop_and_store_status) == sigp_busy)
+		cpu_relax();
+	sp = lc->panic_stack;
+	sp -= sizeof(struct pt_regs);
+	regs = (struct pt_regs *) sp;
+	memcpy(&regs->gprs, &current_lc->gpregs_save_area, sizeof(regs->gprs));
+	regs->psw = lc->psw_save_area;
+	sp -= STACK_FRAME_OVERHEAD;
+	sf = (struct stack_frame *) sp;
+	sf->back_chain = regs->gprs[15];
+	smp_switch_to_cpu(func, data, sp, stap(), __cpu_logical_map[0]);
+}
+
 void smp_send_stop(void)
 {
 	int cpu, rc;
@@ -103,7 +143,7 @@ void smp_send_stop(void)
 		if (cpu == smp_processor_id())
 			continue;
 		do {
-			rc = signal_processor(cpu, sigp_stop);
+			rc = sigp(cpu, sigp_stop);
 		} while (rc == sigp_busy);
 
 		while (!cpu_stopped(cpu))
@@ -139,13 +179,13 @@ static void do_ext_call_interrupt(__u16
  * Send an external call sigp to another cpu and return without waiting
  * for its completion.
  */
-static void smp_ext_bitcall(int cpu, ec_bit_sig sig)
+static void smp_ext_bitcall(int cpu, int sig)
 {
 	/*
 	 * Set signaling bit in lowcore of target cpu and kick it
 	 */
 	set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast);
-	while (signal_processor(cpu, sigp_emergency_signal) == sigp_busy)
+	while (sigp(cpu, sigp_emergency_signal) == sigp_busy)
 		udelay(10);
 }
 
@@ -239,24 +279,8 @@ void smp_ctl_clear_bit(int cr, int bit)
 }
 EXPORT_SYMBOL(smp_ctl_clear_bit);
 
-/*
- * In early ipl state a temp. logically cpu number is needed, so the sigp
- * functions can be used to sense other cpus. Since NR_CPUS is >= 2 on
- * CONFIG_SMP and the ipl cpu is logical cpu 0, it must be 1.
- */
-#define CPU_INIT_NO	1
-
 #ifdef CONFIG_ZFCPDUMP
 
-/*
- * zfcpdump_prefix_array holds prefix registers for the following scenario:
- * 64 bit zfcpdump kernel and 31 bit kernel which is to be dumped. We have to
- * save its prefix registers, since they get lost, when switching from 31 bit
- * to 64 bit.
- */
-unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \
-	__attribute__((__section__(".data")));
-
 static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
 {
 	if (ipl_info.type != IPL_TYPE_FCP_DUMP)
@@ -266,21 +290,15 @@ static void __init smp_get_save_area(uns
 			   "the dump\n", cpu, NR_CPUS - 1);
 		return;
 	}
-	zfcpdump_save_areas[cpu] = kmalloc(sizeof(union save_area), GFP_KERNEL);
-	__cpu_logical_map[CPU_INIT_NO] = (__u16) phy_cpu;
-	while (signal_processor(CPU_INIT_NO, sigp_stop_and_store_status) ==
-	       sigp_busy)
+	zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL);
+	while (raw_sigp(phy_cpu, sigp_stop_and_store_status) == sigp_busy)
 		cpu_relax();
-	memcpy(zfcpdump_save_areas[cpu],
-	       (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
-	       SAVE_AREA_SIZE);
-#ifdef CONFIG_64BIT
-	/* copy original prefix register */
-	zfcpdump_save_areas[cpu]->s390x.pref_reg = zfcpdump_prefix_array[cpu];
-#endif
+	memcpy_real(zfcpdump_save_areas[cpu],
+		    (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
+		    sizeof(struct save_area));
 }
 
-union save_area *zfcpdump_save_areas[NR_CPUS + 1];
+struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
 EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
 
 #else
@@ -389,8 +407,7 @@ static void __init smp_detect_cpus(void)
 		for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) {
 			if (cpu == boot_cpu_addr)
 				continue;
-			__cpu_logical_map[CPU_INIT_NO] = cpu;
-			if (!cpu_stopped(CPU_INIT_NO))
+			if (!raw_cpu_stopped(cpu))
 				continue;
 			smp_get_save_area(c_cpus, cpu);
 			c_cpus++;
@@ -413,8 +430,7 @@ static void __init smp_detect_cpus(void)
 		cpu_addr = info->cpu[cpu].address;
 		if (cpu_addr == boot_cpu_addr)
 			continue;
-		__cpu_logical_map[CPU_INIT_NO] = cpu_addr;
-		if (!cpu_stopped(CPU_INIT_NO)) {
+		if (!raw_cpu_stopped(cpu_addr)) {
 			s_cpus++;
 			continue;
 		}
@@ -533,18 +549,18 @@ static void smp_free_lowcore(int cpu)
 /* Upping and downing of CPUs */
 int __cpuinit __cpu_up(unsigned int cpu)
 {
-	struct task_struct *idle;
 	struct _lowcore *cpu_lowcore;
+	struct task_struct *idle;
 	struct stack_frame *sf;
-	sigp_ccode ccode;
 	u32 lowcore;
+	int ccode;
 
 	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);
+		ccode = sigp(cpu, sigp_initial_cpu_reset);
 		if (ccode == sigp_busy)
 			udelay(10);
 		if (ccode == sigp_not_operational)
@@ -552,7 +568,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
 	} while (ccode == sigp_busy);
 
 	lowcore = (u32)(unsigned long)lowcore_ptr[cpu];
-	while (signal_processor_p(lowcore, cpu, sigp_set_prefix) == sigp_busy)
+	while (sigp_p(lowcore, cpu, sigp_set_prefix) == sigp_busy)
 		udelay(10);
 
 	idle = current_set[cpu];
@@ -578,7 +594,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
 	cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func;
 	eieio();
 
-	while (signal_processor(cpu, sigp_restart) == sigp_busy)
+	while (sigp(cpu, sigp_restart) == sigp_busy)
 		udelay(10);
 
 	while (!cpu_online(cpu))
@@ -640,7 +656,7 @@ void __cpu_die(unsigned int cpu)
 	/* Wait until target cpu is down */
 	while (!cpu_stopped(cpu))
 		cpu_relax();
-	while (signal_processor_p(0, cpu, sigp_set_prefix) == sigp_busy)
+	while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy)
 		udelay(10);
 	smp_free_lowcore(cpu);
 	pr_info("Processor %d stopped\n", cpu);
@@ -649,7 +665,7 @@ void __cpu_die(unsigned int cpu)
 void cpu_die(void)
 {
 	idle_task_exit();
-	while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy)
+	while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
 		cpu_relax();
 	for (;;);
 }
@@ -765,7 +781,8 @@ static ssize_t cpu_configure_store(struc
 	get_online_cpus();
 	mutex_lock(&smp_cpu_state_mutex);
 	rc = -EBUSY;
-	if (cpu_online(cpu))
+	/* disallow configuration changes of online cpus and cpu 0 */
+	if (cpu_online(cpu) || cpu == 0)
 		goto out;
 	rc = 0;
 	switch (val) {
@@ -1004,7 +1021,9 @@ out:
 	return rc;
 }
 
-static ssize_t __ref rescan_store(struct sysdev_class *class, const char *buf,
+static ssize_t __ref rescan_store(struct sysdev_class *class,
+				  struct sysdev_class_attribute *attr,
+				  const char *buf,
 				  size_t count)
 {
 	int rc;
@@ -1015,7 +1034,9 @@ static ssize_t __ref rescan_store(struct
 static SYSDEV_CLASS_ATTR(rescan, 0200, NULL, rescan_store);
 #endif /* CONFIG_HOTPLUG_CPU */
 
-static ssize_t dispatching_show(struct sysdev_class *class, char *buf)
+static ssize_t dispatching_show(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr,
+				char *buf)
 {
 	ssize_t count;
 
@@ -1025,7 +1046,9 @@ static ssize_t dispatching_show(struct s
 	return count;
 }
 
-static ssize_t dispatching_store(struct sysdev_class *dev, const char *buf,
+static ssize_t dispatching_store(struct sysdev_class *dev,
+				 struct sysdev_class_attribute *attr,
+				 const char *buf,
 				 size_t count)
 {
 	int val, rc;
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/switch_cpu64.S linux-libre-2.6.34-gnu1/arch/s390/kernel/switch_cpu64.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/switch_cpu64.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/switch_cpu64.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,51 @@
+/*
+ * 64-bit switch cpu code
+ *
+ * Copyright IBM Corp. 2009
+ *
+ */
+
+#include <asm/asm-offsets.h>
+#include <asm/ptrace.h>
+
+# smp_switch_to_cpu switches to destination cpu and executes the passed function
+# Parameter: %r2 - function to call
+#	     %r3 - function parameter
+#	     %r4 - stack poiner
+#	     %r5 - current cpu
+#	     %r6 - destination cpu
+
+	.section .text
+	.align 4
+	.globl smp_switch_to_cpu
+smp_switch_to_cpu:
+	stmg	%r6,%r15,__SF_GPRS(%r15)
+	lgr	%r1,%r15
+	aghi	%r15,-STACK_FRAME_OVERHEAD
+	stg	%r1,__SF_BACKCHAIN(%r15)
+	larl	%r1,.gprregs
+	stmg	%r0,%r15,0(%r1)
+1:	sigp	%r0,%r6,__SIGP_RESTART	/* start destination CPU */
+	brc	2,1b			/* busy, try again */
+2:	sigp	%r0,%r5,__SIGP_STOP	/* stop current CPU */
+	brc	2,2b			/* busy, try again */
+3:	j	3b
+
+	.globl	smp_restart_cpu
+smp_restart_cpu:
+	larl	%r1,.gprregs
+	lmg	%r0,%r15,0(%r1)
+1:	sigp	%r0,%r5,__SIGP_SENSE	/* Wait for calling CPU */
+	brc	10,1b			/* busy, accepted (status 0), running */
+	tmll	%r0,0x40		/* Test if calling CPU is stopped */
+	jz	1b
+	ltgr	%r4,%r4			/* New stack ? */
+	jz	1f
+	lgr	%r15,%r4
+1:	basr	%r14,%r2
+
+	.section .data,"aw",@progbits
+.gprregs:
+	.rept	16
+	.quad	0
+	.endr
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/switch_cpu.S linux-libre-2.6.34-gnu1/arch/s390/kernel/switch_cpu.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/switch_cpu.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/switch_cpu.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,58 @@
+/*
+ * 31-bit switch cpu code
+ *
+ * Copyright IBM Corp. 2009
+ *
+ */
+
+#include <asm/asm-offsets.h>
+#include <asm/ptrace.h>
+
+# smp_switch_to_cpu switches to destination cpu and executes the passed function
+# Parameter: %r2 - function to call
+#	     %r3 - function parameter
+#	     %r4 - stack poiner
+#	     %r5 - current cpu
+#	     %r6 - destination cpu
+
+	.section .text
+	.align 4
+	.globl smp_switch_to_cpu
+smp_switch_to_cpu:
+	stm	%r6,%r15,__SF_GPRS(%r15)
+	lr	%r1,%r15
+	ahi	%r15,-STACK_FRAME_OVERHEAD
+	st	%r1,__SF_BACKCHAIN(%r15)
+	basr	%r13,0
+0:	la	%r1,.gprregs_addr-0b(%r13)
+	l	%r1,0(%r1)
+	stm	%r0,%r15,0(%r1)
+1:	sigp	%r0,%r6,__SIGP_RESTART	/* start destination CPU */
+	brc	2,1b			/* busy, try again */
+2:	sigp	%r0,%r5,__SIGP_STOP	/* stop current CPU */
+	brc	2,2b			/* busy, try again */
+3:	j	3b
+
+	.globl	smp_restart_cpu
+smp_restart_cpu:
+	basr	%r13,0
+0:	la	%r1,.gprregs_addr-0b(%r13)
+	l	%r1,0(%r1)
+	lm	%r0,%r15,0(%r1)
+1:	sigp	%r0,%r5,__SIGP_SENSE	/* Wait for calling CPU */
+	brc	10,1b			/* busy, accepted (status 0), running */
+	tmll	%r0,0x40		/* Test if calling CPU is stopped */
+	jz	1b
+	ltr	%r4,%r4			/* New stack ? */
+	jz	1f
+	lr	%r15,%r4
+1:	basr	%r14,%r2
+
+.gprregs_addr:
+	.long	.gprregs
+
+	.section .data,"aw",@progbits
+.gprregs:
+	.rept	16
+	.long	0
+	.endr
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/swsusp_asm64.S linux-libre-2.6.34-gnu1/arch/s390/kernel/swsusp_asm64.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/swsusp_asm64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/swsusp_asm64.S	2010-05-16 17:17:36.000000000 -0400
@@ -176,7 +176,7 @@ pgm_check_entry:
 	cgr	%r1,%r2
 	je	restore_registers		/* r1 = r2 -> nothing to do */
 	larl	%r4,.Lrestart_suspend_psw	/* Set new restart PSW */
-	mvc	__LC_RESTART_PSW(16,%r0),0(%r4)
+	mvc	__LC_RST_NEW_PSW(16,%r0),0(%r4)
 3:
 	sigp	%r9,%r1,__SIGP_INITIAL_CPU_RESET
 	brc	8,4f	/* accepted */
@@ -256,6 +256,9 @@ restore_registers:
 	lghi	%r2,0
 	brasl	%r14,arch_set_page_states
 
+	/* Reinitialize the channel subsystem */
+	brasl	%r14,channel_subsystem_reinit
+
 	/* Return 0 */
 	lmg	%r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15)
 	lghi	%r2,0
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/syscalls.S linux-libre-2.6.34-gnu1/arch/s390/kernel/syscalls.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/syscalls.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/syscalls.S	2010-05-16 17:17:36.000000000 -0400
@@ -98,7 +98,7 @@ SYSCALL(sys_uselib,sys_uselib,sys32_usel
 SYSCALL(sys_swapon,sys_swapon,sys32_swapon_wrapper)
 SYSCALL(sys_reboot,sys_reboot,sys32_reboot_wrapper)
 SYSCALL(sys_ni_syscall,sys_ni_syscall,old32_readdir_wrapper)	/* old readdir syscall */
-SYSCALL(sys_s390_old_mmap,sys_s390_old_mmap,old32_mmap_wrapper)	/* 90 */
+SYSCALL(sys_old_mmap,sys_old_mmap,old32_mmap_wrapper)		/* 90 */
 SYSCALL(sys_munmap,sys_munmap,sys32_munmap_wrapper)
 SYSCALL(sys_truncate,sys_truncate,sys32_truncate_wrapper)
 SYSCALL(sys_ftruncate,sys_ftruncate,sys32_ftruncate_wrapper)
@@ -125,12 +125,12 @@ NI_SYSCALL							/* vm86old for i386 */
 SYSCALL(sys_wait4,sys_wait4,compat_sys_wait4_wrapper)
 SYSCALL(sys_swapoff,sys_swapoff,sys32_swapoff_wrapper)		/* 115 */
 SYSCALL(sys_sysinfo,sys_sysinfo,compat_sys_sysinfo_wrapper)
-SYSCALL(sys_ipc,sys_ipc,sys32_ipc_wrapper)
+SYSCALL(sys_s390_ipc,sys_s390_ipc,sys32_ipc_wrapper)
 SYSCALL(sys_fsync,sys_fsync,sys32_fsync_wrapper)
 SYSCALL(sys_sigreturn,sys_sigreturn,sys32_sigreturn)
 SYSCALL(sys_clone,sys_clone,sys_clone_wrapper)			/* 120 */
 SYSCALL(sys_setdomainname,sys_setdomainname,sys32_setdomainname_wrapper)
-SYSCALL(sys_newuname,sys_s390_newuname,sys32_newuname_wrapper)
+SYSCALL(sys_newuname,sys_newuname,sys32_newuname_wrapper)
 NI_SYSCALL							/* modify_ldt for i386 */
 SYSCALL(sys_adjtimex,sys_adjtimex,compat_sys_adjtimex_wrapper)
 SYSCALL(sys_mprotect,sys_mprotect,sys32_mprotect_wrapper)	/* 125 */
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/sysinfo.c linux-libre-2.6.34-gnu1/arch/s390/kernel/sysinfo.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/sysinfo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/sysinfo.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/ebcdic.h>
 #include <asm/sysinfo.h>
 #include <asm/cpcmd.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/sys_s390.c linux-libre-2.6.34-gnu1/arch/s390/kernel/sys_s390.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/sys_s390.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/sys_s390.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,13 +33,12 @@
 #include "entry.h"
 
 /*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. Linux for S/390 isn't able to handle more than 5
- * system call parameters, so these system calls used a memory
- * block for parameter passing..
+ * Perform the mmap() system call. Linux for S/390 isn't able to handle more
+ * than 5 system call parameters, so this system call uses a memory block
+ * for parameter passing.
  */
 
-struct mmap_arg_struct {
+struct s390_mmap_arg_struct {
 	unsigned long addr;
 	unsigned long len;
 	unsigned long prot;
@@ -48,9 +47,9 @@ struct mmap_arg_struct {
 	unsigned long offset;
 };
 
-SYSCALL_DEFINE1(mmap2, struct mmap_arg_struct __user *, arg)
+SYSCALL_DEFINE1(mmap2, struct s390_mmap_arg_struct __user *, arg)
 {
-	struct mmap_arg_struct a;
+	struct s390_mmap_arg_struct a;
 	int error = -EFAULT;
 
 	if (copy_from_user(&a, arg, sizeof(a)))
@@ -60,29 +59,12 @@ out:
 	return error;
 }
 
-SYSCALL_DEFINE1(s390_old_mmap, struct mmap_arg_struct __user *, arg)
-{
-	struct mmap_arg_struct a;
-	long error = -EFAULT;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		goto out;
-
-	error = -EINVAL;
-	if (a.offset & ~PAGE_MASK)
-		goto out;
-
-	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-out:
-	return error;
-}
-
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  *
  * This is really horribly ugly.
  */
-SYSCALL_DEFINE5(ipc, uint, call, int, first, unsigned long, second,
+SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second,
 		unsigned long, third, void __user *, ptr)
 {
         struct ipc_kludge tmp;
@@ -149,17 +131,6 @@ SYSCALL_DEFINE5(ipc, uint, call, int, fi
 }
 
 #ifdef CONFIG_64BIT
-SYSCALL_DEFINE1(s390_newuname, struct new_utsname __user *, name)
-{
-	int ret = sys_newuname(name);
-
-	if (personality(current->personality) == PER_LINUX32 && !ret) {
-		ret = copy_to_user(name->machine, "s390\0\0\0\0", 8);
-		if (ret) ret = -EFAULT;
-	}
-	return ret;
-}
-
 SYSCALL_DEFINE1(s390_personality, unsigned long, personality)
 {
 	int ret;
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/time.c linux-libre-2.6.34-gnu1/arch/s390/kernel/time.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/notifier.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 #include <asm/delay.h>
 #include <asm/s390_ext.h>
@@ -51,14 +52,6 @@
 #define USECS_PER_JIFFY     ((unsigned long) 1000000/HZ)
 #define CLK_TICKS_PER_JIFFY ((unsigned long) USECS_PER_JIFFY << 12)
 
-/*
- * Create a small time difference between the timer interrupts
- * on the different cpus to avoid lock contention.
- */
-#define CPU_DEVIATION       (smp_processor_id() << 12)
-
-#define TICK_SIZE tick
-
 u64 sched_clock_base_cc = -1;	/* Force to data section. */
 EXPORT_SYMBOL_GPL(sched_clock_base_cc);
 
@@ -81,15 +74,15 @@ unsigned long long monotonic_clock(void)
 }
 EXPORT_SYMBOL(monotonic_clock);
 
-void tod_to_timeval(__u64 todval, struct timespec *xtime)
+void tod_to_timeval(__u64 todval, struct timespec *xt)
 {
 	unsigned long long sec;
 
 	sec = todval >> 12;
 	do_div(sec, 1000000);
-	xtime->tv_sec = sec;
+	xt->tv_sec = sec;
 	todval -= (sec * 1000000) << 12;
-	xtime->tv_nsec = ((todval * 1000) >> 12);
+	xt->tv_nsec = ((todval * 1000) >> 12);
 }
 EXPORT_SYMBOL(tod_to_timeval);
 
@@ -224,10 +217,11 @@ void update_vsyscall(struct timespec *wa
 	++vdso_data->tb_update_count;
 	smp_wmb();
 	vdso_data->xtime_tod_stamp = clock->cycle_last;
-	vdso_data->xtime_clock_sec = xtime.tv_sec;
-	vdso_data->xtime_clock_nsec = xtime.tv_nsec;
+	vdso_data->xtime_clock_sec = wall_time->tv_sec;
+	vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
 	vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
 	vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
+	vdso_data->ntp_mult = mult;
 	smp_wmb();
 	++vdso_data->tb_update_count;
 }
@@ -1124,14 +1118,18 @@ static struct sys_device etr_port1_dev =
 /*
  * ETR class attributes
  */
-static ssize_t etr_stepping_port_show(struct sysdev_class *class, char *buf)
+static ssize_t etr_stepping_port_show(struct sysdev_class *class,
+					struct sysdev_class_attribute *attr,
+					char *buf)
 {
 	return sprintf(buf, "%i\n", etr_port0.esw.p);
 }
 
 static SYSDEV_CLASS_ATTR(stepping_port, 0400, etr_stepping_port_show, NULL);
 
-static ssize_t etr_stepping_mode_show(struct sysdev_class *class, char *buf)
+static ssize_t etr_stepping_mode_show(struct sysdev_class *class,
+				      	struct sysdev_class_attribute *attr,
+					char *buf)
 {
 	char *mode_str;
 
@@ -1592,7 +1590,9 @@ static struct sysdev_class stp_sysclass
 	.name	= "stp",
 };
 
-static ssize_t stp_ctn_id_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_ctn_id_show(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr,
+				char *buf)
 {
 	if (!stp_online)
 		return -ENODATA;
@@ -1602,7 +1602,9 @@ static ssize_t stp_ctn_id_show(struct sy
 
 static SYSDEV_CLASS_ATTR(ctn_id, 0400, stp_ctn_id_show, NULL);
 
-static ssize_t stp_ctn_type_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_ctn_type_show(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr,
+				char *buf)
 {
 	if (!stp_online)
 		return -ENODATA;
@@ -1611,7 +1613,9 @@ static ssize_t stp_ctn_type_show(struct
 
 static SYSDEV_CLASS_ATTR(ctn_type, 0400, stp_ctn_type_show, NULL);
 
-static ssize_t stp_dst_offset_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_dst_offset_show(struct sysdev_class *class,
+				   struct sysdev_class_attribute *attr,
+				   char *buf)
 {
 	if (!stp_online || !(stp_info.vbits & 0x2000))
 		return -ENODATA;
@@ -1620,7 +1624,9 @@ static ssize_t stp_dst_offset_show(struc
 
 static SYSDEV_CLASS_ATTR(dst_offset, 0400, stp_dst_offset_show, NULL);
 
-static ssize_t stp_leap_seconds_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_leap_seconds_show(struct sysdev_class *class,
+					struct sysdev_class_attribute *attr,
+					char *buf)
 {
 	if (!stp_online || !(stp_info.vbits & 0x8000))
 		return -ENODATA;
@@ -1629,7 +1635,9 @@ static ssize_t stp_leap_seconds_show(str
 
 static SYSDEV_CLASS_ATTR(leap_seconds, 0400, stp_leap_seconds_show, NULL);
 
-static ssize_t stp_stratum_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_stratum_show(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr,
+				char *buf)
 {
 	if (!stp_online)
 		return -ENODATA;
@@ -1638,7 +1646,9 @@ static ssize_t stp_stratum_show(struct s
 
 static SYSDEV_CLASS_ATTR(stratum, 0400, stp_stratum_show, NULL);
 
-static ssize_t stp_time_offset_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_time_offset_show(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr,
+				char *buf)
 {
 	if (!stp_online || !(stp_info.vbits & 0x0800))
 		return -ENODATA;
@@ -1647,7 +1657,9 @@ static ssize_t stp_time_offset_show(stru
 
 static SYSDEV_CLASS_ATTR(time_offset, 0400, stp_time_offset_show, NULL);
 
-static ssize_t stp_time_zone_offset_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_time_zone_offset_show(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr,
+				char *buf)
 {
 	if (!stp_online || !(stp_info.vbits & 0x4000))
 		return -ENODATA;
@@ -1657,7 +1669,9 @@ static ssize_t stp_time_zone_offset_show
 static SYSDEV_CLASS_ATTR(time_zone_offset, 0400,
 			 stp_time_zone_offset_show, NULL);
 
-static ssize_t stp_timing_mode_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_timing_mode_show(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr,
+				char *buf)
 {
 	if (!stp_online)
 		return -ENODATA;
@@ -1666,7 +1680,9 @@ static ssize_t stp_timing_mode_show(stru
 
 static SYSDEV_CLASS_ATTR(timing_mode, 0400, stp_timing_mode_show, NULL);
 
-static ssize_t stp_timing_state_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_timing_state_show(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr,
+				char *buf)
 {
 	if (!stp_online)
 		return -ENODATA;
@@ -1675,12 +1691,15 @@ static ssize_t stp_timing_state_show(str
 
 static SYSDEV_CLASS_ATTR(timing_state, 0400, stp_timing_state_show, NULL);
 
-static ssize_t stp_online_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_online_show(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr,
+				char *buf)
 {
 	return sprintf(buf, "%i\n", stp_online);
 }
 
 static ssize_t stp_online_store(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr,
 				const char *buf, size_t count)
 {
 	unsigned int value;
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/topology.c linux-libre-2.6.34-gnu1/arch/s390/kernel/topology.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/topology.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/topology.c	2010-05-16 17:17:36.000000000 -0400
@@ -165,10 +165,11 @@ static void tl_to_cores(struct tl_info *
 		default:
 			clear_cores();
 			machine_has_topology = 0;
-			return;
+			goto out;
 		}
 		tle = next_tle(tle);
 	}
+out:
 	spin_unlock_irq(&topology_lock);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/vdso32/clock_gettime.S linux-libre-2.6.34-gnu1/arch/s390/kernel/vdso32/clock_gettime.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/vdso32/clock_gettime.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/vdso32/clock_gettime.S	2010-05-16 17:17:36.000000000 -0400
@@ -38,13 +38,13 @@ __kernel_clock_gettime:
 	sl	%r1,__VDSO_XTIME_STAMP+4(%r5)
 	brc	3,2f
 	ahi	%r0,-1
-2:	mhi	%r0,1000			/* cyc2ns(clock,cycle_delta) */
+2:	ms	%r0,__VDSO_NTP_MULT(%r5)	/* cyc2ns(clock,cycle_delta) */
 	lr	%r2,%r0
-	lhi	%r0,1000
+	l	%r0,__VDSO_NTP_MULT(%r5)
 	ltr	%r1,%r1
 	mr	%r0,%r0
 	jnm	3f
-	ahi	%r0,1000
+	a	%r0,__VDSO_NTP_MULT(%r5)
 3:	alr	%r0,%r2
 	srdl	%r0,12
 	al	%r0,__VDSO_XTIME_NSEC(%r5)	/*  + xtime */
@@ -86,13 +86,13 @@ __kernel_clock_gettime:
 	sl	%r1,__VDSO_XTIME_STAMP+4(%r5)
 	brc	3,12f
 	ahi	%r0,-1
-12:	mhi	%r0,1000			/* cyc2ns(clock,cycle_delta) */
+12:	ms	%r0,__VDSO_NTP_MULT(%r5)	/* cyc2ns(clock,cycle_delta) */
 	lr	%r2,%r0
-	lhi	%r0,1000
+	l	%r0,__VDSO_NTP_MULT(%r5)
 	ltr	%r1,%r1
 	mr	%r0,%r0
 	jnm	13f
-	ahi	%r0,1000
+	a	%r0,__VDSO_NTP_MULT(%r5)
 13:	alr	%r0,%r2
 	srdl	%r0,12
 	al	%r0,__VDSO_XTIME_NSEC(%r5)	/*  + xtime */
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/vdso32/gettimeofday.S linux-libre-2.6.34-gnu1/arch/s390/kernel/vdso32/gettimeofday.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/vdso32/gettimeofday.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/vdso32/gettimeofday.S	2010-05-16 17:17:36.000000000 -0400
@@ -35,13 +35,13 @@ __kernel_gettimeofday:
 	sl	%r1,__VDSO_XTIME_STAMP+4(%r5)
 	brc	3,3f
 	ahi	%r0,-1
-3:	mhi	%r0,1000			/* cyc2ns(clock,cycle_delta) */
+3:	ms	%r0,__VDSO_NTP_MULT(%r5)	/* cyc2ns(clock,cycle_delta) */
 	st	%r0,24(%r15)
-	lhi	%r0,1000
+	l	%r0,__VDSO_NTP_MULT(%r5)
 	ltr	%r1,%r1
 	mr	%r0,%r0
 	jnm	4f
-	ahi	%r0,1000
+	a	%r0,__VDSO_NTP_MULT(%r5)
 4:	al	%r0,24(%r15)
 	srdl	%r0,12
 	al	%r0,__VDSO_XTIME_NSEC(%r5)	/*  + xtime */
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/vdso64/clock_gettime.S linux-libre-2.6.34-gnu1/arch/s390/kernel/vdso64/clock_gettime.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/vdso64/clock_gettime.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/vdso64/clock_gettime.S	2010-05-16 17:17:36.000000000 -0400
@@ -36,7 +36,7 @@ __kernel_clock_gettime:
 	stck	48(%r15)			/* Store TOD clock */
 	lg	%r1,48(%r15)
 	sg	%r1,__VDSO_XTIME_STAMP(%r5)	/* TOD - cycle_last */
-	mghi	%r1,1000
+	msgf	%r1,__VDSO_NTP_MULT(%r5)	/*  * NTP adjustment */
 	srlg	%r1,%r1,12			/* cyc2ns(clock,cycle_delta) */
 	alg	%r1,__VDSO_XTIME_NSEC(%r5)	/*  + xtime */
 	lg	%r0,__VDSO_XTIME_SEC(%r5)
@@ -64,7 +64,7 @@ __kernel_clock_gettime:
 	stck	48(%r15)			/* Store TOD clock */
 	lg	%r1,48(%r15)
 	sg	%r1,__VDSO_XTIME_STAMP(%r5)	/* TOD - cycle_last */
-	mghi	%r1,1000
+	msgf	%r1,__VDSO_NTP_MULT(%r5)	/*  * NTP adjustment */
 	srlg	%r1,%r1,12			/* cyc2ns(clock,cycle_delta) */
 	alg	%r1,__VDSO_XTIME_NSEC(%r5)	/*  + xtime */
 	lg	%r0,__VDSO_XTIME_SEC(%r5)
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/vdso64/gettimeofday.S linux-libre-2.6.34-gnu1/arch/s390/kernel/vdso64/gettimeofday.S
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/vdso64/gettimeofday.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/vdso64/gettimeofday.S	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,7 @@ __kernel_gettimeofday:
 	stck	48(%r15)			/* Store TOD clock */
 	lg	%r1,48(%r15)
 	sg	%r1,__VDSO_XTIME_STAMP(%r5)	/* TOD - cycle_last */
-	mghi	%r1,1000
+	msgf	%r1,__VDSO_NTP_MULT(%r5)	/*  * NTP adjustment */
 	srlg	%r1,%r1,12			/* cyc2ns(clock,cycle_delta) */
 	alg	%r1,__VDSO_XTIME_NSEC(%r5)	/*  + xtime.tv_nsec */
 	lg	%r0,__VDSO_XTIME_SEC(%r5)	/* xtime.tv_sec */
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kernel/vdso.c linux-libre-2.6.34-gnu1/arch/s390/kernel/vdso.c
--- linux-libre-2.6.33-gnu1/arch/s390/kernel/vdso.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kernel/vdso.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/security.h>
 #include <linux/bootmem.h>
 #include <linux/compat.h>
+#include <asm/asm-offsets.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/processor.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kvm/diag.c linux-libre-2.6.34-gnu1/arch/s390/kvm/diag.c
--- linux-libre-2.6.33-gnu1/arch/s390/kvm/diag.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kvm/diag.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,7 @@ static int __diag_ipl_functions(struct k
 		vcpu->run->s390_reset_flags = 0;
 		break;
 	default:
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 	}
 
 	atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
@@ -62,6 +62,6 @@ int kvm_s390_handle_diag(struct kvm_vcpu
 	case 0x308:
 		return __diag_ipl_functions(vcpu);
 	default:
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 	}
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kvm/intercept.c linux-libre-2.6.34-gnu1/arch/s390/kvm/intercept.c
--- linux-libre-2.6.33-gnu1/arch/s390/kvm/intercept.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kvm/intercept.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,7 @@ static int handle_lctlg(struct kvm_vcpu
 
 	vcpu->stat.instruction_lctlg++;
 	if ((vcpu->arch.sie_block->ipb & 0xff) != 0x2f)
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 
 	useraddr = disp2;
 	if (base2)
@@ -138,7 +138,7 @@ static int handle_stop(struct kvm_vcpu *
 		rc = __kvm_s390_vcpu_store_status(vcpu,
 						  KVM_S390_STORE_STATUS_NOADDR);
 		if (rc >= 0)
-			rc = -ENOTSUPP;
+			rc = -EOPNOTSUPP;
 	}
 
 	if (vcpu->arch.local_int.action_bits & ACTION_RELOADVCPU_ON_STOP) {
@@ -150,7 +150,7 @@ static int handle_stop(struct kvm_vcpu *
 	if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) {
 		vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP;
 		VCPU_EVENT(vcpu, 3, "%s", "cpu stopped");
-		rc = -ENOTSUPP;
+		rc = -EOPNOTSUPP;
 	}
 
 	spin_unlock_bh(&vcpu->arch.local_int.lock);
@@ -171,9 +171,9 @@ static int handle_validity(struct kvm_vc
 			 2*PAGE_SIZE);
 		if (rc)
 			/* user will receive sigsegv, exit to user */
-			rc = -ENOTSUPP;
+			rc = -EOPNOTSUPP;
 	} else
-		rc = -ENOTSUPP;
+		rc = -EOPNOTSUPP;
 
 	if (rc)
 		VCPU_EVENT(vcpu, 2, "unhandled validity intercept code %d",
@@ -189,7 +189,7 @@ static int handle_instruction(struct kvm
 	handler = instruction_handlers[vcpu->arch.sie_block->ipa >> 8];
 	if (handler)
 		return handler(vcpu);
-	return -ENOTSUPP;
+	return -EOPNOTSUPP;
 }
 
 static int handle_prog(struct kvm_vcpu *vcpu)
@@ -206,7 +206,7 @@ static int handle_instruction_and_prog(s
 	rc = handle_instruction(vcpu);
 	rc2 = handle_prog(vcpu);
 
-	if (rc == -ENOTSUPP)
+	if (rc == -EOPNOTSUPP)
 		vcpu->arch.sie_block->icptcode = 0x04;
 	if (rc)
 		return rc;
@@ -231,9 +231,9 @@ int kvm_handle_sie_intercept(struct kvm_
 	u8 code = vcpu->arch.sie_block->icptcode;
 
 	if (code & 3 || (code >> 2) >= ARRAY_SIZE(intercept_funcs))
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 	func = intercept_funcs[code >> 2];
 	if (func)
 		return func(vcpu);
-	return -ENOTSUPP;
+	return -EOPNOTSUPP;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kvm/interrupt.c linux-libre-2.6.34-gnu1/arch/s390/kvm/interrupt.c
--- linux-libre-2.6.33-gnu1/arch/s390/kvm/interrupt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kvm/interrupt.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,12 +10,13 @@
  *    Author(s): Carsten Otte <cotte@de.ibm.com>
  */
 
-#include <asm/lowcore.h>
-#include <asm/uaccess.h>
-#include <linux/hrtimer.h>
 #include <linux/interrupt.h>
 #include <linux/kvm_host.h>
+#include <linux/hrtimer.h>
 #include <linux/signal.h>
+#include <linux/slab.h>
+#include <asm/asm-offsets.h>
+#include <asm/uaccess.h>
 #include "kvm-s390.h"
 #include "gaccess.h"
 
@@ -187,8 +188,8 @@ static void __do_deliver_interrupt(struc
 		if (rc == -EFAULT)
 			exception = 1;
 
-		rc = put_guest_u64(vcpu, __LC_PFAULT_INTPARM,
-			inti->ext.ext_params2);
+		rc = put_guest_u64(vcpu, __LC_EXT_PARAMS2,
+				   inti->ext.ext_params2);
 		if (rc == -EFAULT)
 			exception = 1;
 		break;
@@ -342,7 +343,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu
 	if (psw_interrupts_disabled(vcpu)) {
 		VCPU_EVENT(vcpu, 3, "%s", "disabled wait");
 		__unset_cpu_idle(vcpu);
-		return -ENOTSUPP; /* disabled wait */
+		return -EOPNOTSUPP; /* disabled wait */
 	}
 
 	if (psw_extint_disabled(vcpu) ||
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kvm/Kconfig linux-libre-2.6.34-gnu1/arch/s390/kvm/Kconfig
--- linux-libre-2.6.33-gnu1/arch/s390/kvm/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kvm/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@ config KVM
 
 # OK, it's a little counter-intuitive to do this, but it puts it neatly under
 # the virtualization menu.
+source drivers/vhost/Kconfig
 source drivers/virtio/Kconfig
 
 endif # VIRTUALIZATION
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kvm/kvm-s390.c linux-libre-2.6.34-gnu1/arch/s390/kvm/kvm-s390.c
--- linux-libre-2.6.33-gnu1/arch/s390/kvm/kvm-s390.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kvm/kvm-s390.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/timer.h>
+#include <asm/asm-offsets.h>
 #include <asm/lowcore.h>
 #include <asm/pgtable.h>
 #include <asm/nmi.h>
@@ -241,6 +242,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm
 	kvm_free_physmem(kvm);
 	free_page((unsigned long)(kvm->arch.sca));
 	debug_unregister(kvm->arch.dbf);
+	cleanup_srcu_struct(&kvm->srcu);
 	kfree(kvm);
 }
 
@@ -543,7 +545,7 @@ rerun_vcpu:
 		rc = -EINTR;
 	}
 
-	if (rc == -ENOTSUPP) {
+	if (rc == -EOPNOTSUPP) {
 		/* intercept cannot be handled in-kernel, prepare kvm-run */
 		kvm_run->exit_reason         = KVM_EXIT_S390_SIEIC;
 		kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
@@ -603,45 +605,45 @@ int __kvm_s390_vcpu_store_status(struct
 	} else
 		prefix = 0;
 
-	if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, fp_regs),
+	if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
 			vcpu->arch.guest_fpregs.fprs, 128, prefix))
 		return -EFAULT;
 
-	if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, gp_regs),
+	if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
 			vcpu->arch.guest_gprs, 128, prefix))
 		return -EFAULT;
 
-	if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, psw),
+	if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
 			&vcpu->arch.sie_block->gpsw, 16, prefix))
 		return -EFAULT;
 
-	if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, pref_reg),
+	if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
 			&vcpu->arch.sie_block->prefix, 4, prefix))
 		return -EFAULT;
 
 	if (__guestcopy(vcpu,
-			addr + offsetof(struct save_area_s390x, fp_ctrl_reg),
+			addr + offsetof(struct save_area, fp_ctrl_reg),
 			&vcpu->arch.guest_fpregs.fpc, 4, prefix))
 		return -EFAULT;
 
-	if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, tod_reg),
+	if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
 			&vcpu->arch.sie_block->todpr, 4, prefix))
 		return -EFAULT;
 
-	if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, timer),
+	if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
 			&vcpu->arch.sie_block->cputm, 8, prefix))
 		return -EFAULT;
 
-	if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, clk_cmp),
+	if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
 			&vcpu->arch.sie_block->ckc, 8, prefix))
 		return -EFAULT;
 
-	if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, acc_regs),
+	if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
 			&vcpu->arch.guest_acrs, 64, prefix))
 		return -EFAULT;
 
 	if (__guestcopy(vcpu,
-			addr + offsetof(struct save_area_s390x, ctrl_regs),
+			addr + offsetof(struct save_area, ctrl_regs),
 			&vcpu->arch.sie_block->gcr, 128, prefix))
 		return -EFAULT;
 	return 0;
@@ -689,14 +691,12 @@ long kvm_arch_vcpu_ioctl(struct file *fi
 }
 
 /* Section: memory related */
-int kvm_arch_set_memory_region(struct kvm *kvm,
-				struct kvm_userspace_memory_region *mem,
-				struct kvm_memory_slot old,
-				int user_alloc)
+int kvm_arch_prepare_memory_region(struct kvm *kvm,
+				   struct kvm_memory_slot *memslot,
+				   struct kvm_memory_slot old,
+				   struct kvm_userspace_memory_region *mem,
+				   int user_alloc)
 {
-	int i;
-	struct kvm_vcpu *vcpu;
-
 	/* A few sanity checks. We can have exactly one memory slot which has
 	   to start at guest virtual zero and which has to be located at a
 	   page boundary in userland and which has to end at a page boundary.
@@ -719,14 +719,23 @@ int kvm_arch_set_memory_region(struct kv
 	if (!user_alloc)
 		return -EINVAL;
 
+	return 0;
+}
+
+void kvm_arch_commit_memory_region(struct kvm *kvm,
+				struct kvm_userspace_memory_region *mem,
+				struct kvm_memory_slot old,
+				int user_alloc)
+{
+	int i;
+	struct kvm_vcpu *vcpu;
+
 	/* request update of sie control block for all available vcpus */
 	kvm_for_each_vcpu(i, vcpu, kvm) {
 		if (test_and_set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
 			continue;
 		kvm_s390_inject_sigp_stop(vcpu, ACTION_RELOADVCPU_ON_STOP);
 	}
-
-	return 0;
 }
 
 void kvm_arch_flush_shadow(struct kvm *kvm)
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kvm/kvm-s390.h linux-libre-2.6.34-gnu1/arch/s390/kvm/kvm-s390.h
--- linux-libre-2.6.33-gnu1/arch/s390/kvm/kvm-s390.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kvm/kvm-s390.h	2010-05-16 17:17:36.000000000 -0400
@@ -67,10 +67,14 @@ static inline long kvm_s390_vcpu_get_mem
 
 static inline void kvm_s390_vcpu_set_mem(struct kvm_vcpu *vcpu)
 {
+	int idx;
 	struct kvm_memory_slot *mem;
+	struct kvm_memslots *memslots;
 
-	down_read(&vcpu->kvm->slots_lock);
-	mem = &vcpu->kvm->memslots[0];
+	idx = srcu_read_lock(&vcpu->kvm->srcu);
+	memslots = rcu_dereference(vcpu->kvm->memslots);
+
+	mem = &memslots->memslots[0];
 
 	vcpu->arch.sie_block->gmsor = mem->userspace_addr;
 	vcpu->arch.sie_block->gmslm =
@@ -78,7 +82,7 @@ static inline void kvm_s390_vcpu_set_mem
 		(mem->npages << PAGE_SHIFT) +
 		VIRTIODESCSPACE - 1ul;
 
-	up_read(&vcpu->kvm->slots_lock);
+	srcu_read_unlock(&vcpu->kvm->srcu, idx);
 }
 
 /* implemented in priv.c */
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kvm/priv.c linux-libre-2.6.34-gnu1/arch/s390/kvm/priv.c
--- linux-libre-2.6.33-gnu1/arch/s390/kvm/priv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kvm/priv.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
  */
 
 #include <linux/kvm.h>
+#include <linux/gfp.h>
 #include <linux/errno.h>
 #include <asm/current.h>
 #include <asm/debug.h>
@@ -323,5 +324,5 @@ int kvm_s390_handle_b2(struct kvm_vcpu *
 		else
 			return handler(vcpu);
 	}
-	return -ENOTSUPP;
+	return -EOPNOTSUPP;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/kvm/sigp.c linux-libre-2.6.34-gnu1/arch/s390/kvm/sigp.c
--- linux-libre-2.6.33-gnu1/arch/s390/kvm/sigp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/kvm/sigp.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
+#include <linux/slab.h>
 #include "gaccess.h"
 #include "kvm-s390.h"
 
@@ -172,7 +173,7 @@ static int __sigp_set_arch(struct kvm_vc
 		rc = 0; /* order accepted */
 		break;
 	default:
-		rc = -ENOTSUPP;
+		rc = -EOPNOTSUPP;
 	}
 	return rc;
 }
@@ -293,7 +294,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu
 		vcpu->stat.instruction_sigp_restart++;
 		/* user space must know about restart */
 	default:
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 	}
 
 	if (rc < 0)
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/lib/Makefile linux-libre-2.6.34-gnu1/arch/s390/lib/Makefile
--- linux-libre-2.6.33-gnu1/arch/s390/lib/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/lib/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
 #
 
 lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
+obj-y += usercopy.o
 obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o
 lib-$(CONFIG_64BIT) += uaccess_mvcos.o
 lib-$(CONFIG_SMP) += spinlock.o
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/lib/spinlock.c linux-libre-2.6.34-gnu1/arch/s390/lib/spinlock.c
--- linux-libre-2.6.33-gnu1/arch/s390/lib/spinlock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/lib/spinlock.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,16 +43,24 @@ void arch_spin_lock_wait(arch_spinlock_t
 {
 	int count = spin_retry;
 	unsigned int cpu = ~smp_processor_id();
+	unsigned int owner;
 
 	while (1) {
-		if (count-- <= 0) {
-			unsigned int owner = lp->owner_cpu;
-			if (owner != 0)
-				_raw_yield_cpu(~owner);
-			count = spin_retry;
+		owner = lp->owner_cpu;
+		if (!owner || smp_vcpu_scheduled(~owner)) {
+			for (count = spin_retry; count > 0; count--) {
+				if (arch_spin_is_locked(lp))
+					continue;
+				if (_raw_compare_and_swap(&lp->owner_cpu, 0,
+							  cpu) == 0)
+					return;
+			}
+			if (MACHINE_IS_LPAR)
+				continue;
 		}
-		if (arch_spin_is_locked(lp))
-			continue;
+		owner = lp->owner_cpu;
+		if (owner)
+			_raw_yield_cpu(~owner);
 		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
 			return;
 	}
@@ -63,17 +71,27 @@ void arch_spin_lock_wait_flags(arch_spin
 {
 	int count = spin_retry;
 	unsigned int cpu = ~smp_processor_id();
+	unsigned int owner;
 
 	local_irq_restore(flags);
 	while (1) {
-		if (count-- <= 0) {
-			unsigned int owner = lp->owner_cpu;
-			if (owner != 0)
-				_raw_yield_cpu(~owner);
-			count = spin_retry;
+		owner = lp->owner_cpu;
+		if (!owner || smp_vcpu_scheduled(~owner)) {
+			for (count = spin_retry; count > 0; count--) {
+				if (arch_spin_is_locked(lp))
+					continue;
+				local_irq_disable();
+				if (_raw_compare_and_swap(&lp->owner_cpu, 0,
+							  cpu) == 0)
+					return;
+				local_irq_restore(flags);
+			}
+			if (MACHINE_IS_LPAR)
+				continue;
 		}
-		if (arch_spin_is_locked(lp))
-			continue;
+		owner = lp->owner_cpu;
+		if (owner)
+			_raw_yield_cpu(~owner);
 		local_irq_disable();
 		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
 			return;
@@ -100,8 +118,11 @@ EXPORT_SYMBOL(arch_spin_trylock_retry);
 void arch_spin_relax(arch_spinlock_t *lock)
 {
 	unsigned int cpu = lock->owner_cpu;
-	if (cpu != 0)
-		_raw_yield_cpu(~cpu);
+	if (cpu != 0) {
+		if (MACHINE_IS_VM || MACHINE_IS_KVM ||
+		    !smp_vcpu_scheduled(~cpu))
+			_raw_yield_cpu(~cpu);
+	}
 }
 EXPORT_SYMBOL(arch_spin_relax);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/lib/usercopy.c linux-libre-2.6.34-gnu1/arch/s390/lib/usercopy.c
--- linux-libre-2.6.33-gnu1/arch/s390/lib/usercopy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/lib/usercopy.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,8 @@
+#include <linux/module.h>
+#include <linux/bug.h>
+
+void copy_from_user_overflow(void)
+{
+	WARN(1, "Buffer overflow detected!\n");
+}
+EXPORT_SYMBOL(copy_from_user_overflow);
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/Makefile linux-libre-2.6.34-gnu1/arch/s390/Makefile
--- linux-libre-2.6.33-gnu1/arch/s390/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #
 
 ifndef CONFIG_64BIT
+LD_BFD		:= elf32-s390
 LDFLAGS		:= -m elf_s390
 KBUILD_CFLAGS	+= -m31
 KBUILD_AFLAGS	+= -m31
@@ -21,6 +22,7 @@ UTS_MACHINE	:= s390
 STACK_SIZE	:= 8192
 CHECKFLAGS	+= -D__s390__ -msize-long
 else
+LD_BFD		:= elf64-s390
 LDFLAGS		:= -m elf64_s390
 MODFLAGS	+= -fpic -D__PIC__
 KBUILD_CFLAGS	+= -m64
@@ -30,6 +32,8 @@ STACK_SIZE	:= 16384
 CHECKFLAGS	+= -D__s390__ -D__s390x__
 endif
 
+export LD_BFD
+
 cflags-$(CONFIG_MARCH_G5)   += $(call cc-option,-march=g5)
 cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900)
 cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990)
@@ -85,7 +89,9 @@ KBUILD_AFLAGS	+= $(aflags-y)
 OBJCOPYFLAGS	:= -O binary
 LDFLAGS_vmlinux := -e start
 
-head-y		:= arch/s390/kernel/head.o arch/s390/kernel/init_task.o
+head-y		:= arch/s390/kernel/head.o
+head-y		+= arch/s390/kernel/$(if $(CONFIG_64BIT),head64.o,head31.o)
+head-y		+= arch/s390/kernel/init_task.o
 
 core-y		+= arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \
 		   arch/s390/appldata/ arch/s390/hypfs/ arch/s390/kvm/
@@ -99,12 +105,12 @@ drivers-$(CONFIG_OPROFILE)	+= arch/s390/
 
 boot		:= arch/s390/boot
 
-all: image
+all: image bzImage
 
 install: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $@
 
-image: vmlinux
+image bzImage: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
 zfcpdump:
@@ -116,4 +122,5 @@ archclean:
 # Don't use tabs in echo arguments
 define archhelp
   echo  '* image           - Kernel image for IPL ($(boot)/image)'
+  echo	'* bzImage         - Compressed kernel image for IPL ($(boot)/bzImage)'
 endef
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/mm/cmm.c linux-libre-2.6.34-gnu1/arch/s390/mm/cmm.c
--- linux-libre-2.6.33-gnu1/arch/s390/mm/cmm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/mm/cmm.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/sysctl.h>
 #include <linux/ctype.h>
@@ -374,7 +375,7 @@ static struct ctl_table cmm_dir_table[]
 #ifdef CONFIG_CMM_IUCV
 #define SMSG_PREFIX "CMM"
 static void
-cmm_smsg_target(char *from, char *msg)
+cmm_smsg_target(const char *from, char *msg)
 {
 	long nr, seconds;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/mm/extmem.c linux-libre-2.6.34-gnu1/arch/s390/mm/extmem.c
--- linux-libre-2.6.33-gnu1/arch/s390/mm/extmem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/mm/extmem.c	2010-05-16 17:17:36.000000000 -0400
@@ -309,7 +309,7 @@ query_segment_type (struct dcss_segment
 	}
 #endif
 	if (qout->segcnt > 6) {
-		rc = -ENOTSUPP;
+		rc = -EOPNOTSUPP;
 		goto out_free;
 	}
 
@@ -324,11 +324,11 @@ query_segment_type (struct dcss_segment
 		for (i=0; i<qout->segcnt; i++) {
 			if (((qout->range[i].start & 0xff) != SEG_TYPE_EW) &&
 			    ((qout->range[i].start & 0xff) != SEG_TYPE_EN)) {
-				rc = -ENOTSUPP;
+				rc = -EOPNOTSUPP;
 				goto out_free;
 			}
 			if (start != qout->range[i].start >> PAGE_SHIFT) {
-				rc = -ENOTSUPP;
+				rc = -EOPNOTSUPP;
 				goto out_free;
 			}
 			start = (qout->range[i].end >> PAGE_SHIFT) + 1;
@@ -357,7 +357,7 @@ query_segment_type (struct dcss_segment
  * -ENOSYS  : we are not running on VM
  * -EIO     : could not perform query diagnose
  * -ENOENT  : no such segment
- * -ENOTSUPP: multi-part segment cannot be used with linux
+ * -EOPNOTSUPP: multi-part segment cannot be used with linux
  * -ENOMEM  : out of memory
  * 0 .. 6   : type of segment as defined in include/asm-s390/extmem.h
  */
@@ -515,7 +515,7 @@ __segment_load (char *name, int do_nonsh
  * -ENOSYS  : we are not running on VM
  * -EIO     : could not perform query or load diagnose
  * -ENOENT  : no such segment
- * -ENOTSUPP: multi-part segment cannot be used with linux
+ * -EOPNOTSUPP: multi-part segment cannot be used with linux
  * -ENOSPC  : segment cannot be used (overlaps with storage)
  * -EBUSY   : segment can temporarily not be used (overlaps with dcss)
  * -ERANGE  : segment cannot be used (exceeds kernel mapping range)
@@ -742,7 +742,7 @@ void segment_warning(int rc, char *seg_n
 		pr_err("Loading or querying DCSS %s resulted in a "
 		       "hardware error\n", seg_name);
 		break;
-	case -ENOTSUPP:
+	case -EOPNOTSUPP:
 		pr_err("DCSS %s has multiple page ranges and cannot be "
 		       "loaded or queried\n", seg_name);
 		break;
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/mm/fault.c linux-libre-2.6.34-gnu1/arch/s390/mm/fault.c
--- linux-libre-2.6.33-gnu1/arch/s390/mm/fault.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/mm/fault.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/kprobes.h>
 #include <linux/uaccess.h>
 #include <linux/hugetlb.h>
+#include <asm/asm-offsets.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #include <asm/s390_ext.h>
@@ -59,15 +60,13 @@ static inline int notify_page_fault(stru
 {
 	int ret = 0;
 
-#ifdef CONFIG_KPROBES
 	/* kprobe_running() needs smp_processor_id() */
-	if (!user_mode(regs)) {
+	if (kprobes_built_in() && !user_mode(regs)) {
 		preempt_disable();
 		if (kprobe_running() && kprobe_fault_handler(regs, 14))
 			ret = 1;
 		preempt_enable();
 	}
-#endif
 	return ret;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/mm/init.c linux-libre-2.6.34-gnu1/arch/s390/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/s390/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/pfn.h>
 #include <linux/poison.h>
 #include <linux/initrd.h>
+#include <linux/gfp.h>
 #include <asm/processor.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -143,33 +144,34 @@ void kernel_map_pages(struct page *page,
 }
 #endif
 
-void free_initmem(void)
+void free_init_pages(char *what, unsigned long begin, unsigned long end)
 {
-        unsigned long addr;
+	unsigned long addr = begin;
 
-        addr = (unsigned long)(&__init_begin);
-        for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
+	if (begin >= end)
+		return;
+	for (; 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);
+		memset((void *)(addr & PAGE_MASK), POISON_FREE_INITMEM,
+		       PAGE_SIZE);
 		free_page(addr);
 		totalram_pages++;
-        }
-        printk ("Freeing unused kernel memory: %ldk freed\n",
-		((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10);
+	}
+	printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
+}
+
+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)
 {
-        if (start < end)
-                printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
-        for (; start < end; start += PAGE_SIZE) {
-                ClearPageReserved(virt_to_page(start));
-                init_page_count(virt_to_page(start));
-                free_page(start);
-                totalram_pages++;
-        }
+	free_init_pages("initrd memory", start, end);
 }
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/mm/maccess.c linux-libre-2.6.34-gnu1/arch/s390/mm/maccess.c
--- linux-libre-2.6.33-gnu1/arch/s390/mm/maccess.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/mm/maccess.c	2010-05-16 17:17:36.000000000 -0400
@@ -59,3 +59,29 @@ long probe_kernel_write(void *dst, void
 	}
 	return copied < 0 ? -EFAULT : 0;
 }
+
+int memcpy_real(void *dest, void *src, size_t count)
+{
+	register unsigned long _dest asm("2") = (unsigned long) dest;
+	register unsigned long _len1 asm("3") = (unsigned long) count;
+	register unsigned long _src  asm("4") = (unsigned long) src;
+	register unsigned long _len2 asm("5") = (unsigned long) count;
+	unsigned long flags;
+	int rc = -EFAULT;
+
+	if (!count)
+		return 0;
+	flags = __raw_local_irq_stnsm(0xf8UL);
+	asm volatile (
+		"0:	mvcle	%1,%2,0x0\n"
+		"1:	jo	0b\n"
+		"	lhi	%0,0x0\n"
+		"2:\n"
+		EX_TABLE(1b,2b)
+		: "+d" (rc), "+d" (_dest), "+d" (_src), "+d" (_len1),
+		  "+d" (_len2), "=m" (*((long *) dest))
+		: "m" (*((long *) src))
+		: "cc", "memory");
+	__raw_local_irq_ssm(flags);
+	return rc;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/mm/page-states.c linux-libre-2.6.34-gnu1/arch/s390/mm/page-states.c
--- linux-libre-2.6.33-gnu1/arch/s390/mm/page-states.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/mm/page-states.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/mm.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 
 #define ESSA_SET_STABLE		1
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/mm/pgtable.c linux-libre-2.6.34-gnu1/arch/s390/mm/pgtable.c
--- linux-libre-2.6.33-gnu1/arch/s390/mm/pgtable.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/mm/pgtable.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,11 +6,11 @@
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/smp.h>
 #include <linux/highmem.h>
-#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/spinlock.h>
 #include <linux/module.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/s390/mm/vmem.c linux-libre-2.6.34-gnu1/arch/s390/mm/vmem.c
--- linux-libre-2.6.33-gnu1/arch/s390/mm/vmem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/s390/mm/vmem.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/list.h>
 #include <linux/hugetlb.h>
+#include <linux/slab.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/setup.h>
@@ -70,12 +71,8 @@ static pte_t __ref *vmem_pte_alloc(void)
 		pte = alloc_bootmem(PTRS_PER_PTE * sizeof(pte_t));
 	if (!pte)
 		return NULL;
-	if (MACHINE_HAS_HPAGE)
-		clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY | _PAGE_CO,
-			    PTRS_PER_PTE * sizeof(pte_t));
-	else
-		clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY,
-			    PTRS_PER_PTE * sizeof(pte_t));
+	clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY,
+		    PTRS_PER_PTE * sizeof(pte_t));
 	return pte;
 }
 
@@ -116,8 +113,7 @@ static int vmem_add_mem(unsigned long st
 		if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) &&
 		    (address + HPAGE_SIZE <= start + size) &&
 		    (address >= HPAGE_SIZE)) {
-			pte_val(pte) |= _SEGMENT_ENTRY_LARGE |
-					_SEGMENT_ENTRY_CO;
+			pte_val(pte) |= _SEGMENT_ENTRY_LARGE;
 			pmd_val(*pm_dir) = pte_val(pte);
 			address += HPAGE_SIZE - PAGE_SIZE;
 			continue;
diff -druNp linux-libre-2.6.33-gnu1/arch/score/include/asm/pgtable.h linux-libre-2.6.34-gnu1/arch/score/include/asm/pgtable.h
--- linux-libre-2.6.33-gnu1/arch/score/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/score/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -272,8 +272,9 @@ extern void __update_cache(struct vm_are
 	unsigned long address,	pte_t pte);
 
 static inline void update_mmu_cache(struct vm_area_struct *vma,
-	unsigned long address, pte_t pte)
+	unsigned long address, pte_t *ptep)
 {
+	pte_t pte = *ptep;
 	__update_tlb(vma, address, pte);
 	__update_cache(vma, address, pte);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/score/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/score/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/score/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/score/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -90,8 +90,7 @@ extern int read_tsk_short(struct task_st
 			 unsigned short *);
 
 #define arch_has_single_step()	(1)
-extern void user_enable_single_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_SCORE_PTRACE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/score/kernel/sys_score.c linux-libre-2.6.34-gnu1/arch/score/kernel/sys_score.c
--- linux-libre-2.6.33-gnu1/arch/score/kernel/sys_score.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/score/kernel/sys_score.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/unistd.h>
 #include <linux/syscalls.h>
 #include <asm/syscalls.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/score/mm/init.c linux-libre-2.6.34-gnu1/arch/score/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/score/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/score/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/errno.h>
 #include <linux/bootmem.h>
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
@@ -59,7 +60,7 @@ static unsigned long setup_zero_page(voi
 }
 
 #ifndef CONFIG_NEED_MULTIPLE_NODES
-static int __init page_is_ram(unsigned long pagenr)
+int page_is_ram(unsigned long pagenr)
 {
 	if (pagenr >= min_low_pfn && pagenr < max_low_pfn)
 		return 1;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/board-magicpanelr2.c linux-libre-2.6.34-gnu1/arch/sh/boards/board-magicpanelr2.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/board-magicpanelr2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/board-magicpanelr2.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,7 @@
 #include <asm/heartbeat.h>
 #include <cpu/sh7720.h>
 
-#define LAN9115_READY	(ctrl_inl(0xA8000084UL) & 0x00000001UL)
+#define LAN9115_READY	(__raw_readl(0xA8000084UL) & 0x00000001UL)
 
 /* Prefer cmdline over RedBoot */
 static const char *probes[] = { "cmdlinepart", "RedBoot", NULL };
@@ -60,33 +60,33 @@ static void __init setup_chip_select(voi
 {
 	/* CS2: LAN (0x08000000 - 0x0bffffff) */
 	/* no idle cycles, normal space, 8 bit data bus */
-	ctrl_outl(0x36db0400, CS2BCR);
+	__raw_writel(0x36db0400, CS2BCR);
 	/* (SW:1.5 WR:3 HW:1.5), ext. wait */
-	ctrl_outl(0x000003c0, CS2WCR);
+	__raw_writel(0x000003c0, CS2WCR);
 
 	/* CS4: CAN1 (0xb0000000 - 0xb3ffffff) */
 	/* no idle cycles, normal space, 8 bit data bus */
-	ctrl_outl(0x00000200, CS4BCR);
+	__raw_writel(0x00000200, CS4BCR);
 	/* (SW:1.5 WR:3 HW:1.5), ext. wait */
-	ctrl_outl(0x00100981, CS4WCR);
+	__raw_writel(0x00100981, CS4WCR);
 
 	/* CS5a: CAN2 (0xb4000000 - 0xb5ffffff) */
 	/* no idle cycles, normal space, 8 bit data bus */
-	ctrl_outl(0x00000200, CS5ABCR);
+	__raw_writel(0x00000200, CS5ABCR);
 	/* (SW:1.5 WR:3 HW:1.5), ext. wait */
-	ctrl_outl(0x00100981, CS5AWCR);
+	__raw_writel(0x00100981, CS5AWCR);
 
 	/* CS5b: CAN3 (0xb6000000 - 0xb7ffffff) */
 	/* no idle cycles, normal space, 8 bit data bus */
-	ctrl_outl(0x00000200, CS5BBCR);
+	__raw_writel(0x00000200, CS5BBCR);
 	/* (SW:1.5 WR:3 HW:1.5), ext. wait */
-	ctrl_outl(0x00100981, CS5BWCR);
+	__raw_writel(0x00100981, CS5BWCR);
 
 	/* CS6a: Rotary (0xb8000000 - 0xb9ffffff) */
 	/* no idle cycles, normal space, 8 bit data bus */
-	ctrl_outl(0x00000200, CS6ABCR);
+	__raw_writel(0x00000200, CS6ABCR);
 	/* (SW:1.5 WR:3 HW:1.5), no ext. wait */
-	ctrl_outl(0x001009C1, CS6AWCR);
+	__raw_writel(0x001009C1, CS6AWCR);
 }
 
 static void __init setup_port_multiplexing(void)
@@ -94,71 +94,71 @@ static void __init setup_port_multiplexi
 	/* A7 GPO(LED8);     A6 GPO(LED7);     A5 GPO(LED6);	  A4 GPO(LED5);
 	 * A3 GPO(LED4);     A2 GPO(LED3);     A1 GPO(LED2);	  A0 GPO(LED1);
 	 */
-	ctrl_outw(0x5555, PORT_PACR);	/* 01 01 01 01 01 01 01 01 */
+	__raw_writew(0x5555, PORT_PACR);	/* 01 01 01 01 01 01 01 01 */
 
 	/* B7 GPO(RST4);   B6 GPO(RST3);  B5 GPO(RST2);    B4 GPO(RST1);
 	 * B3 GPO(PB3);	   B2 GPO(PB2);	  B1 GPO(PB1);	   B0 GPO(PB0);
 	 */
-	ctrl_outw(0x5555, PORT_PBCR);	/* 01 01 01 01 01 01 01 01 */
+	__raw_writew(0x5555, PORT_PBCR);	/* 01 01 01 01 01 01 01 01 */
 
 	/* C7 GPO(PC7);	  C6 GPO(PC6);	  C5 GPO(PC5);	   C4 GPO(PC4);
 	 * C3 LCD_DATA3;  C2 LCD_DATA2;   C1 LCD_DATA1;	   C0 LCD_DATA0;
 	 */
-	ctrl_outw(0x5500, PORT_PCCR);	/* 01 01 01 01 00 00 00 00 */
+	__raw_writew(0x5500, PORT_PCCR);	/* 01 01 01 01 00 00 00 00 */
 
 	/* D7 GPO(PD7);	D6 GPO(PD6);	D5 GPO(PD5);	   D4 GPO(PD4);
 	 * D3 GPO(PD3);	D2 GPO(PD2);	D1 GPO(PD1);	   D0 GPO(PD0);
 	 */
-	ctrl_outw(0x5555, PORT_PDCR);	/* 01 01 01 01 01 01 01 01 */
+	__raw_writew(0x5555, PORT_PDCR);	/* 01 01 01 01 01 01 01 01 */
 
 	/* E7 (x);	  E6 GPI(nu);	 E5 GPI(nu);	  E4 LCD_M_DISP;
 	 * E3 LCD_CL1;	  E2 LCD_CL2;	 E1 LCD_DON;	  E0 LCD_FLM;
 	 */
-	ctrl_outw(0x3C00, PORT_PECR);	/* 00 11 11 00 00 00 00 00 */
+	__raw_writew(0x3C00, PORT_PECR);	/* 00 11 11 00 00 00 00 00 */
 
 	/* F7 (x);	     F6 DA1(VLCD);     F5 DA0(nc);	  F4 AN3;
 	 * F3 AN2(MID_AD);   F2 AN1(EARTH_AD); F1 AN0(TEMP);	  F0 GPI+(nc);
 	 */
-	ctrl_outw(0x0002, PORT_PFCR);	/* 00 00 00 00 00 00 00 10 */
+	__raw_writew(0x0002, PORT_PFCR);	/* 00 00 00 00 00 00 00 10 */
 
 	/* G7 (x);	  G6 IRQ5(TOUCH_BUSY); G5 IRQ4(TOUCH_IRQ); G4 GPI(KEY2);
 	 * G3 GPI(KEY1);  G2 GPO(LED11);	G1 GPO(LED10);     G0 GPO(LED9);
 	 */
-	ctrl_outw(0x03D5, PORT_PGCR);	/* 00 00 00 11 11 01 01 01 */
+	__raw_writew(0x03D5, PORT_PGCR);	/* 00 00 00 11 11 01 01 01 */
 
 	/* H7 (x);	      H6 /RAS(BRAS);	  H5 /CAS(BCAS); H4 CKE(BCKE);
 	 * H3 GPO(EARTH_OFF); H2 GPO(EARTH_TEST); H1 USB2_PWR;	 H0 USB1_PWR;
 	 */
-	ctrl_outw(0x0050, PORT_PHCR);	/* 00 00 00 00 01 01 00 00 */
+	__raw_writew(0x0050, PORT_PHCR);	/* 00 00 00 00 01 01 00 00 */
 
 	/* J7 (x);	  J6 AUDCK;	   J5 ASEBRKAK;	    J4 AUDATA3;
 	 * J3 AUDATA2;	  J2 AUDATA1;	   J1 AUDATA0;	    J0 AUDSYNC;
 	 */
-	ctrl_outw(0x0000, PORT_PJCR);	/* 00 00 00 00 00 00 00 00 */
+	__raw_writew(0x0000, PORT_PJCR);	/* 00 00 00 00 00 00 00 00 */
 
 	/* K7 (x);	    K6 (x);	     K5 (x);	   K4 (x);
 	 * K3 PINT7(/PWR2); K2 PINT6(/PWR1); K1 PINT5(nu); K0 PINT4(FLASH_READY)
 	 */
-	ctrl_outw(0x00FF, PORT_PKCR);	/* 00 00 00 00 11 11 11 11 */
+	__raw_writew(0x00FF, PORT_PKCR);	/* 00 00 00 00 11 11 11 11 */
 
 	/* L7 TRST;	   L6 TMS;	     L5 TDO;		  L4 TDI;
 	 * L3 TCK;	   L2 (x);	     L1 (x);		  L0 (x);
 	 */
-	ctrl_outw(0x0000, PORT_PLCR);	/* 00 00 00 00 00 00 00 00 */
+	__raw_writew(0x0000, PORT_PLCR);	/* 00 00 00 00 00 00 00 00 */
 
 	/* M7 GPO(CURRENT_SINK);    M6 GPO(PWR_SWITCH);     M5 GPO(LAN_SPEED);
 	 * M4 GPO(LAN_RESET);       M3 GPO(BUZZER);	    M2 GPO(LCD_BL);
 	 * M1 CS5B(CAN3_CS);	    M0 GPI+(nc);
 	 */
-	ctrl_outw(0x5552, PORT_PMCR);	   /* 01 01 01 01 01 01 00 10 */
+	__raw_writew(0x5552, PORT_PMCR);	   /* 01 01 01 01 01 01 00 10 */
 
 	/* CURRENT_SINK=off,	PWR_SWITCH=off, LAN_SPEED=100MBit,
 	 * LAN_RESET=off,	BUZZER=off,	LCD_BL=off
 	 */
 #if CONFIG_SH_MAGIC_PANEL_R2_VERSION == 2
-	ctrl_outb(0x30, PORT_PMDR);
+	__raw_writeb(0x30, PORT_PMDR);
 #elif CONFIG_SH_MAGIC_PANEL_R2_VERSION == 3
-	ctrl_outb(0xF0, PORT_PMDR);
+	__raw_writeb(0xF0, PORT_PMDR);
 #else
 #error Unknown revision of PLATFORM_MP_R2
 #endif
@@ -167,8 +167,8 @@ static void __init setup_port_multiplexi
 	 * P4 GPO(nu);	       P3 IRQ3(LAN_IRQ);  P2 IRQ2(CAN3_IRQ);
 	 * P1 IRQ1(CAN2_IRQ);  P0 IRQ0(CAN1_IRQ)
 	 */
-	ctrl_outw(0x0100, PORT_PPCR);	/* 00 00 00 01 00 00 00 00 */
-	ctrl_outb(0x10, PORT_PPDR);
+	__raw_writew(0x0100, PORT_PPCR);	/* 00 00 00 01 00 00 00 00 */
+	__raw_writeb(0x10, PORT_PPDR);
 
 	/* R7 A25;	     R6 A24;	     R5 A23;		  R4 A22;
 	 * R3 A21;	     R2 A20;	     R1 A19;		  R0 A0;
@@ -185,22 +185,22 @@ static void __init setup_port_multiplexi
 	/* S7 (x);		S6 (x);        S5 (x);	     S4 GPO(EEPROM_CS2);
 	 * S3 GPO(EEPROM_CS1);  S2 SIOF0_TXD;  S1 SIOF0_RXD; S0 SIOF0_SCK;
 	 */
-	ctrl_outw(0x0140, PORT_PSCR);	/* 00 00 00 01 01 00 00 00 */
+	__raw_writew(0x0140, PORT_PSCR);	/* 00 00 00 01 01 00 00 00 */
 
 	/* T7 (x);	   T6 (x);	  T5 (x);	  T4 COM1_CTS;
 	 * T3 COM1_RTS;	   T2 COM1_TXD;	  T1 COM1_RXD;	  T0 GPO(WDOG)
 	 */
-	ctrl_outw(0x0001, PORT_PTCR);	/* 00 00 00 00 00 00 00 01 */
+	__raw_writew(0x0001, PORT_PTCR);	/* 00 00 00 00 00 00 00 01 */
 
 	/* U7 (x);	     U6 (x);	   U5 (x);	  U4 GPI+(/AC_FAULT);
 	 * U3 GPO(TOUCH_CS); U2 TOUCH_TXD; U1 TOUCH_RXD;  U0 TOUCH_SCK;
 	 */
-	ctrl_outw(0x0240, PORT_PUCR);	/* 00 00 00 10 01 00 00 00 */
+	__raw_writew(0x0240, PORT_PUCR);	/* 00 00 00 10 01 00 00 00 */
 
 	/* V7 (x);	  V6 (x);	V5 (x);		  V4 GPO(MID2);
 	 * V3 GPO(MID1);  V2 CARD_TxD;	V1 CARD_RxD;	  V0 GPI+(/BAT_FAULT);
 	 */
-	ctrl_outw(0x0142, PORT_PVCR);	/* 00 00 00 01 01 00 00 10 */
+	__raw_writew(0x0142, PORT_PVCR);	/* 00 00 00 01 01 00 00 10 */
 }
 
 static void __init mpr2_setup(char **cmdline_p)
@@ -209,24 +209,24 @@ static void __init mpr2_setup(char **cmd
 	 * /PCC_CD1, /PCC_CD2,  PCC_BVD1, PCC_BVD2,
 	 * /IOIS16,  IRQ4,	IRQ5,	  USB1d_SUSPEND
 	 */
-	ctrl_outw(0xAABC, PORT_PSELA);
+	__raw_writew(0xAABC, PORT_PSELA);
 	/* set Pin Select Register B:
 	 * /SCIF0_RTS, /SCIF0_CTS, LCD_VCPWC,
 	 * LCD_VEPWC,  IIC_SDA,    IIC_SCL, Reserved
 	 */
-	ctrl_outw(0x3C00, PORT_PSELB);
+	__raw_writew(0x3C00, PORT_PSELB);
 	/* set Pin Select Register C:
 	 * SIOF1_SCK, SIOF1_RxD, SCIF1_RxD, SCIF1_TxD, Reserved
 	 */
-	ctrl_outw(0x0000, PORT_PSELC);
+	__raw_writew(0x0000, PORT_PSELC);
 	/* set Pin Select Register D: Reserved, SIOF1_TxD, Reserved, SIOF1_MCLK,
 	 * Reserved, SIOF1_SYNC, Reserved, SCIF1_SCK, Reserved
 	 */
-	ctrl_outw(0x0000, PORT_PSELD);
+	__raw_writew(0x0000, PORT_PSELD);
 	/* set USB TxRx Control: Reserved, DRV, Reserved, USB_TRANS, USB_SEL */
-	ctrl_outw(0x0101, PORT_UTRCTL);
+	__raw_writew(0x0101, PORT_UTRCTL);
 	/* set USB Clock Control: USSCS, USSTB, Reserved (HighByte always A5) */
-	ctrl_outw(0xA5C0, PORT_UCLKCR_W);
+	__raw_writew(0xA5C0, PORT_UCLKCR_W);
 
 	setup_chip_select();
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/board-polaris.c linux-libre-2.6.34-gnu1/arch/sh/boards/board-polaris.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/board-polaris.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/board-polaris.c	2010-05-16 17:17:36.000000000 -0400
@@ -59,15 +59,12 @@ static unsigned char heartbeat_bit_pos[]
 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 resource heartbeat_resource = {
+	.start	= PORT_PCDR,
+	.end	= PORT_PCDR,
+	.flags	= IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
 };
 
 static struct platform_device heartbeat_device = {
@@ -76,8 +73,8 @@ static struct platform_device heartbeat_
 	.dev	= {
 		.platform_data	= &heartbeat_data,
 	},
-	.num_resources	= ARRAY_SIZE(heartbeat_resources),
-	.resource	= heartbeat_resources,
+	.num_resources	= 1,
+	.resource	= &heartbeat_resource,
 };
 
 static struct platform_device *polaris_devices[] __initdata = {
@@ -92,15 +89,15 @@ static int __init polaris_initialise(voi
 	printk(KERN_INFO "Configuring Polaris external bus\n");
 
 	/* Configure area 5 with 2 wait states */
-	wcr = ctrl_inw(WCR2);
+	wcr = __raw_readw(WCR2);
 	wcr &= (~AREA5_WAIT_CTRL);
 	wcr |= (WAIT_STATES_10 << 10);
-	ctrl_outw(wcr, WCR2);
+	__raw_writew(wcr, WCR2);
 
 	/* Configure area 5 for 32-bit access */
-	bcr_mask = ctrl_inw(BCR2);
+	bcr_mask = __raw_readw(BCR2);
 	bcr_mask |= 1 << 10;
-	ctrl_outw(bcr_mask, BCR2);
+	__raw_writew(bcr_mask, BCR2);
 
 	return platform_add_devices(polaris_devices,
 				    ARRAY_SIZE(polaris_devices));
@@ -131,13 +128,13 @@ static struct ipr_desc ipr_irq_desc = {
 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);
+	__raw_writew(0, BCR_ILCRA);
+	__raw_writew(0, BCR_ILCRB);
+	__raw_writew(0, BCR_ILCRC);
+	__raw_writew(0, BCR_ILCRD);
+	__raw_writew(0, BCR_ILCRE);
+	__raw_writew(0, BCR_ILCRF);
+	__raw_writew(0, BCR_ILCRG);
 
 	register_ipr_controller(&ipr_irq_desc);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/board-sh7785lcr.c linux-libre-2.6.34-gnu1/arch/sh/boards/board-sh7785lcr.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/board-sh7785lcr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/board-sh7785lcr.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/i2c-algo-pca.h>
 #include <linux/usb/r8a66597.h>
 #include <linux/irq.h>
+#include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/errno.h>
 #include <mach/sh7785lcr.h>
@@ -32,26 +33,17 @@
  * NOTE: This board has 2 physical memory maps.
  *	 Please look at include/asm-sh/sh7785lcr.h or hardware manual.
  */
-static struct resource heartbeat_resources[] = {
-	[0] = {
-		.start	= PLD_LEDCR,
-		.end	= PLD_LEDCR,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct heartbeat_data heartbeat_data = {
-	.regsize = 8,
+static struct resource heartbeat_resource = {
+	.start	= PLD_LEDCR,
+	.end	= PLD_LEDCR,
+	.flags	= IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
 };
 
 static struct platform_device heartbeat_device = {
 	.name		= "heartbeat",
 	.id		= -1,
-	.dev	= {
-		.platform_data	= &heartbeat_data,
-	},
-	.num_resources	= ARRAY_SIZE(heartbeat_resources),
-	.resource	= heartbeat_resources,
+	.num_resources	= 1,
+	.resource	= &heartbeat_resource,
 };
 
 static struct mtd_partition nor_flash_partitions[] = {
@@ -341,8 +333,14 @@ static void __init sh7785lcr_setup(char
 	pm_power_off = sh7785lcr_power_off;
 
 	/* sm501 DRAM configuration */
-	sm501_reg = (void __iomem *)0xb3e00000 + SM501_DRAM_CONTROL;
-	writel(0x000307c2, sm501_reg);
+	sm501_reg = ioremap_nocache(SM107_REG_ADDR, SM501_DRAM_CONTROL);
+	if (!sm501_reg) {
+		printk(KERN_ERR "%s: ioremap error.\n", __func__);
+		return;
+	}
+
+	writel(0x000307c2, sm501_reg + SM501_DRAM_CONTROL);
+	iounmap(sm501_reg);
 }
 
 /* Return the board specific boot mode pin configuration */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/board-shmin.c linux-libre-2.6.34-gnu1/arch/sh/boards/board-shmin.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/board-shmin.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/board-shmin.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,8 +17,8 @@
 
 static void __init init_shmin_irq(void)
 {
-	ctrl_outw(0x2a00, PFC_PHCR);	// IRQ0-3=IRQ
-	ctrl_outw(0x0aaa, INTC_ICR1);	// IRQ0-3=IRQ-mode,Low-active.
+	__raw_writew(0x2a00, PFC_PHCR);	// IRQ0-3=IRQ
+	__raw_writew(0x0aaa, INTC_ICR1);	// IRQ0-3=IRQ-mode,Low-active.
 	plat_irq_setup_pins(IRQ_MODE_IRQ);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/board-titan.c linux-libre-2.6.34-gnu1/arch/sh/boards/board-titan.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/board-titan.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/board-titan.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,24 @@
+/*
+ * arch/sh/boards/titan/setup.c - Setup for Titan
+ *
+ *  Copyright (C) 2006  Jamie Lenehan
+ *
+ * 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 <mach/titan.h>
+#include <asm/io.h>
+
+static void __init init_titan_irq(void)
+{
+	/* enable individual interrupt mode for externals */
+	plat_irq_setup_pins(IRQ_MODE_IRQ);
+}
+
+static struct sh_machine_vector mv_titan __initmv = {
+	.mv_name	= "Titan",
+	.mv_init_irq	= init_titan_irq,
+};
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/board-urquell.c linux-libre-2.6.34-gnu1/arch/sh/boards/board-urquell.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/board-urquell.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/board-urquell.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  * Renesas Technology Corp. SH7786 Urquell Support.
  *
  * Copyright (C) 2008  Kuninori Morimoto <morimoto.kuninori@renesas.com>
- * Copyright (C) 2009  Paul Mundt
+ * Copyright (C) 2009, 2010  Paul Mundt
  *
  * Based on board-sh7785lcr.c
  * Copyright (C) 2008  Yoshihiro Shimoda
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/gpio.h>
 #include <linux/irq.h>
+#include <linux/clk.h>
 #include <mach/urquell.h>
 #include <cpu/sh7786.h>
 #include <asm/heartbeat.h>
@@ -50,26 +51,17 @@
  */
 
 /* 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 resource heartbeat_resource = {
+	.start	= BOARDREG(SLEDR),
+	.end	= BOARDREG(SLEDR),
+	.flags	= IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
 };
 
 static struct platform_device heartbeat_device = {
 	.name		= "heartbeat",
 	.id		= -1,
-	.dev	= {
-		.platform_data	= &heartbeat_data,
-	},
-	.num_resources	= ARRAY_SIZE(heartbeat_resources),
-	.resource	= heartbeat_resources,
+	.num_resources	= 1,
+	.resource	= &heartbeat_resource,
 };
 
 /* LAN91C111 */
@@ -184,6 +176,27 @@ static int urquell_mode_pins(void)
 	return __raw_readw(UBOARDREG(MDSWMR));
 }
 
+static int urquell_clk_init(void)
+{
+	struct clk *clk;
+	int ret;
+
+	/*
+	 * Only handle the EXTAL case, anyone interfacing a crystal
+	 * resonator will need to provide their own input clock.
+	 */
+	if (test_mode_pin(MODE_PIN9))
+		return -EINVAL;
+
+	clk = clk_get(NULL, "extal");
+	if (!clk || IS_ERR(clk))
+		return PTR_ERR(clk);
+	ret = clk_set_rate(clk, 33333333);
+	clk_put(clk);
+
+	return ret;
+}
+
 /* Initialize the board */
 static void __init urquell_setup(char **cmdline_p)
 {
@@ -200,4 +213,5 @@ static struct sh_machine_vector mv_urque
 	.mv_setup	= urquell_setup,
 	.mv_init_irq	= urquell_init_irq,
 	.mv_mode_pins	= urquell_mode_pins,
+	.mv_clk_init	= urquell_clk_init,
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/Kconfig linux-libre-2.6.34-gnu1/arch/sh/boards/Kconfig
--- linux-libre-2.6.33-gnu1/arch/sh/boards/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -150,6 +150,14 @@ config SH_SDK7780
 	  Select SDK7780 if configuring for a Renesas SH7780 SDK7780R3
 	  evaluation board.
 
+config SH_SDK7786
+	bool "SDK7786"
+	depends on CPU_SUBTYPE_SH7786
+	select SYS_SUPPORTS_PCI
+	help
+	  Select SDK7786 if configuring for a Renesas Technology Europe
+	  SH7786-65nm board.
+
 config SH_HIGHLANDER
 	bool "Highlander"
 	depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ap325rxa/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-ap325rxa/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ap325rxa/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-ap325rxa/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -159,21 +159,21 @@ static void ap320_wvga_power_on(void *bo
 	msleep(100);
 
 	/* ASD AP-320/325 LCD ON */
-	ctrl_outw(FPGA_LCDREG_VAL, FPGA_LCDREG);
+	__raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG);
 
 	/* backlight */
 	gpio_set_value(GPIO_PTS3, 0);
-	ctrl_outw(0x100, FPGA_BKLREG);
+	__raw_writew(0x100, FPGA_BKLREG);
 }
 
 static void ap320_wvga_power_off(void *board_data)
 {
 	/* backlight */
-	ctrl_outw(0, FPGA_BKLREG);
+	__raw_writew(0, FPGA_BKLREG);
 	gpio_set_value(GPIO_PTS3, 1);
 
 	/* ASD AP-320/325 LCD OFF */
-	ctrl_outw(0, FPGA_LCDREG);
+	__raw_writew(0, FPGA_LCDREG);
 }
 
 static struct sh_mobile_lcdc_info lcdc_info = {
@@ -420,7 +420,7 @@ static struct resource sdhi0_cn3_resourc
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= 101,
+		.start	= 100,
 		.flags  = IORESOURCE_IRQ,
 	},
 };
@@ -443,7 +443,7 @@ static struct resource sdhi1_cn7_resourc
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= 24,
+		.start	= 23,
 		.flags  = IORESOURCE_IRQ,
 	},
 };
@@ -471,8 +471,8 @@ static struct i2c_board_info ap325rxa_i2
 };
 
 static struct ov772x_camera_info ov7725_info = {
-	.buswidth	= SOCAM_DATAWIDTH_8,
-	.flags		= OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
+	.flags		= OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP | \
+			  OV772X_FLAG_8BIT,
 	.edgectrl	= OV772X_AUTO_EDGECTRL(0xf, 0),
 };
 
@@ -595,7 +595,7 @@ static int __init ap325rxa_devices_setup
 	gpio_request(GPIO_PTZ4, NULL);
 	gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
 
-	ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
+	__raw_writew(__raw_readw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
 
 	/* FLCTL */
 	gpio_request(GPIO_FN_FCE, NULL);
@@ -613,9 +613,9 @@ static int __init ap325rxa_devices_setup
 	gpio_request(GPIO_FN_FWE, NULL);
 	gpio_request(GPIO_FN_FRB, NULL);
 
-	ctrl_outw(0, PORT_HIZCRC);
-	ctrl_outw(0xFFFF, PORT_DRVCRA);
-	ctrl_outw(0xFFFF, PORT_DRVCRB);
+	__raw_writew(0, PORT_HIZCRC);
+	__raw_writew(0xFFFF, PORT_DRVCRA);
+	__raw_writew(0xFFFF, PORT_DRVCRB);
 
 	platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-cayman/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-cayman/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-cayman/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-cayman/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -66,9 +66,9 @@ static void enable_cayman_irq(unsigned i
 	reg = EPLD_MASK_BASE + ((irq / 8) << 2);
 	bit = 1<<(irq % 8);
 	local_irq_save(flags);
-	mask = ctrl_inl(reg);
+	mask = __raw_readl(reg);
 	mask |= bit;
-	ctrl_outl(mask, reg);
+	__raw_writel(mask, reg);
 	local_irq_restore(flags);
 }
 
@@ -83,9 +83,9 @@ void disable_cayman_irq(unsigned int irq
 	reg = EPLD_MASK_BASE + ((irq / 8) << 2);
 	bit = 1<<(irq % 8);
 	local_irq_save(flags);
-	mask = ctrl_inl(reg);
+	mask = __raw_readl(reg);
 	mask &= ~bit;
-	ctrl_outl(mask, reg);
+	__raw_writel(mask, reg);
 	local_irq_restore(flags);
 }
 
@@ -109,8 +109,8 @@ int cayman_irq_demux(int evt)
 		unsigned long status;
 		int i;
 
-		status = ctrl_inl(EPLD_STATUS_BASE) &
-			 ctrl_inl(EPLD_MASK_BASE) & 0xff;
+		status = __raw_readl(EPLD_STATUS_BASE) &
+			 __raw_readl(EPLD_MASK_BASE) & 0xff;
 		if (status == 0) {
 			irq = -1;
 		} else {
@@ -126,8 +126,8 @@ int cayman_irq_demux(int evt)
 		unsigned long status;
 		int i;
 
-		status = ctrl_inl(EPLD_STATUS_BASE + 3 * sizeof(u32)) &
-			 ctrl_inl(EPLD_MASK_BASE + 3 * sizeof(u32)) & 0xff;
+		status = __raw_readl(EPLD_STATUS_BASE + 3 * sizeof(u32)) &
+			 __raw_readl(EPLD_MASK_BASE + 3 * sizeof(u32)) & 0xff;
 		if (status == 0) {
 			irq = -1;
 		} else {
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-dreamcast/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-dreamcast/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-dreamcast/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-dreamcast/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -135,3 +135,30 @@ int systemasic_irq_demux(int irq)
 	/* Not reached */
 	return irq;
 }
+
+void systemasic_irq_init(void)
+{
+	int i, nid = cpu_to_node(boot_cpu_data);
+
+	/* Assign all virtual IRQs to the System ASIC int. handler */
+	for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) {
+		unsigned int irq;
+
+		irq = create_irq_nr(i, nid);
+		if (unlikely(irq == 0)) {
+			pr_err("%s: failed hooking irq %d for systemasic\n",
+			       __func__, i);
+			return;
+		}
+
+		if (unlikely(irq != i)) {
+			pr_err("%s: got irq %d but wanted %d, bailing.\n",
+			       __func__, irq, i);
+			destroy_irq(irq);
+			return;
+		}
+
+		set_irq_chip_and_handler(i, &systemasic_int,
+					 handle_level_irq);
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-dreamcast/rtc.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-dreamcast/rtc.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-dreamcast/rtc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-dreamcast/rtc.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,11 +35,11 @@ static void aica_rtc_gettimeofday(struct
 	unsigned long val1, val2;
 
 	do {
-		val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
-			(ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+		val1 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+			(__raw_readl(AICA_RTC_SECS_L) & 0xffff);
 
-		val2 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
-			(ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+		val2 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+			(__raw_readl(AICA_RTC_SECS_L) & 0xffff);
 	} while (val1 != val2);
 
 	ts->tv_sec = val1 - TWENTY_YEARS;
@@ -60,14 +60,14 @@ static int aica_rtc_settimeofday(const t
 	unsigned long adj = secs + TWENTY_YEARS;
 
 	do {
-		ctrl_outl((adj & 0xffff0000) >> 16, AICA_RTC_SECS_H);
-		ctrl_outl((adj & 0xffff), AICA_RTC_SECS_L);
+		__raw_writel((adj & 0xffff0000) >> 16, AICA_RTC_SECS_H);
+		__raw_writel((adj & 0xffff), AICA_RTC_SECS_L);
 
-		val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
-			(ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+		val1 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+			(__raw_readl(AICA_RTC_SECS_L) & 0xffff);
 
-		val2 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
-			(ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+		val2 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+			(__raw_readl(AICA_RTC_SECS_L) & 0xffff);
 	} while (val1 != val2);
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-dreamcast/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-dreamcast/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-dreamcast/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-dreamcast/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,25 +28,8 @@
 #include <asm/machvec.h>
 #include <mach/sysasic.h>
 
-extern struct irq_chip systemasic_int;
-extern void aica_time_init(void);
-extern int systemasic_irq_demux(int);
-
 static void __init dreamcast_setup(char **cmdline_p)
 {
-	int i;
-
-	/* Mask all hardware events */
-	/* XXX */
-
-	/* Acknowledge any previous events */
-	/* XXX */
-
-	/* Assign all virtual IRQs to the System ASIC int. handler */
-	for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
-		set_irq_chip_and_handler(i, &systemasic_int,
-					 handle_level_irq);
-
 	board_time_init = aica_time_init;
 }
 
@@ -54,4 +37,5 @@ static struct sh_machine_vector mv_dream
 	.mv_name		= "Sega Dreamcast",
 	.mv_setup		= dreamcast_setup,
 	.mv_irq_demux		= systemasic_irq_demux,
+	.mv_init_irq		= systemasic_irq_init,
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ecovec24/sdram.S linux-libre-2.6.34-gnu1/arch/sh/boards/mach-ecovec24/sdram.S
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ecovec24/sdram.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-ecovec24/sdram.S	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,10 @@ ENTRY(ecovec24_sdram_enter_end)
 	.balign 4
 ENTRY(ecovec24_sdram_leave_start)
 
+	mov.l	@(SH_SLEEP_MODE, r5), r0
+	tst	#SUSP_SH_RSTANDBY, r0
+	bf	resume_rstandby
+
 	/* DBSC: put memory in auto-refresh mode */
 
 	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
@@ -49,4 +53,59 @@ ENTRY(ecovec24_sdram_leave_start)
 	rts
 	 nop
 
+resume_rstandby:
+
+	/* DBSC: re-initialize and put in auto-refresh */
+
+	ED 0xFD000108, 0x00000181 /* DBPDCNT0 */
+	ED 0xFD000020, 0x015B0002 /* DBCONF */
+	ED 0xFD000030, 0x03071502 /* DBTR0 */
+	ED 0xFD000034, 0x02020102 /* DBTR1 */
+	ED 0xFD000038, 0x01090405 /* DBTR2 */
+	ED 0xFD00003C, 0x00000002 /* DBTR3 */
+	ED 0xFD000008, 0x00000005 /* DBKIND */
+	ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	ED 0xFD000018, 0x00000001 /* DBCKECNT */
+
+	mov	#100,r0
+WAIT_400NS:
+	dt	r0
+	bf	WAIT_400NS
+
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000060, 0x00020000 /* DBMRCNT (EMR2) */
+	ED 0xFD000060, 0x00030000 /* DBMRCNT (EMR3) */
+	ED 0xFD000060, 0x00010004 /* DBMRCNT (EMR) */
+	ED 0xFD000060, 0x00000532 /* DBMRCNT (MRS) */
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000060, 0x00000432 /* DBMRCNT (MRS) */
+	ED 0xFD000060, 0x000103c0 /* DBMRCNT (EMR) */
+	ED 0xFD000060, 0x00010040 /* DBMRCNT (EMR) */
+
+	mov	#100,r0
+WAIT_400NS_2:
+	dt	r0
+	bf	WAIT_400NS_2
+
+	ED 0xFD000010, 0x00000001 /* DBEN */
+	ED 0xFD000044, 0x0000050f /* DBRFPDN1 */
+	ED 0xFD000048, 0x236800e6 /* DBRFPDN2 */
+
+	mov.l	DUMMY,r0
+	mov.l	@r0, r1 /* force single dummy read */
+
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000108, 0x00000080 /* DBPDCNT0 */
+	ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+	.balign 4
+DUMMY:	.long	0xac400000
+
 ENTRY(ecovec24_sdram_leave_end)
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ecovec24/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-ecovec24/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ecovec24/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-ecovec24/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,18 +64,16 @@
 
 /* Heartbeat */
 static unsigned char led_pos[] = { 0, 1, 2, 3 };
+
 static struct heartbeat_data heartbeat_data = {
-	.regsize = 8,
 	.nr_bits = 4,
 	.bit_pos = led_pos,
 };
 
-static struct resource heartbeat_resources[] = {
-	[0] = {
-		.start  = 0xA405012C, /* PTG */
-		.end    = 0xA405012E - 1,
-		.flags  = IORESOURCE_MEM,
-	},
+static struct resource heartbeat_resource = {
+	.start  = 0xA405012C, /* PTG */
+	.end    = 0xA405012E - 1,
+	.flags  = IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
 };
 
 static struct platform_device heartbeat_device = {
@@ -84,8 +82,8 @@ static struct platform_device heartbeat_
 	.dev = {
 		.platform_data = &heartbeat_data,
 	},
-	.num_resources  = ARRAY_SIZE(heartbeat_resources),
-	.resource       = heartbeat_resources,
+	.num_resources  = 1,
+	.resource       = &heartbeat_resource,
 };
 
 /* MTD */
@@ -455,7 +453,7 @@ static struct resource sdhi0_resources[]
 		.flags  = IORESOURCE_MEM,
 	},
 	[1] = {
-		.start  = 101,
+		.start  = 100,
 		.flags  = IORESOURCE_IRQ,
 	},
 };
@@ -491,7 +489,7 @@ static struct resource sdhi1_resources[]
 		.flags  = IORESOURCE_MEM,
 	},
 	[1] = {
-		.start  = 24,
+		.start  = 23,
 		.flags  = IORESOURCE_IRQ,
 	},
 };
@@ -698,13 +696,13 @@ static struct platform_device camera_dev
 #define FCLKBCR		0xa415000c
 static void fsimck_init(struct clk *clk)
 {
-	u32 status = ctrl_inl(clk->enable_reg);
+	u32 status = __raw_readl(clk->enable_reg);
 
 	/* use external clock */
 	status &= ~0x000000ff;
 	status |= 0x00000080;
 
-	ctrl_outl(status, clk->enable_reg);
+	__raw_writel(status, clk->enable_reg);
 }
 
 static struct clk_ops fsimck_clk_ops = {
@@ -753,6 +751,26 @@ static struct platform_device fsi_device
 	},
 };
 
+/* IrDA */
+static struct resource irda_resources[] = {
+	[0] = {
+		.name	= "IrDA",
+		.start  = 0xA45D0000,
+		.end    = 0xA45D0049,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 20,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device irda_device = {
+	.name           = "sh_sir",
+	.num_resources  = ARRAY_SIZE(irda_resources),
+	.resource       = irda_resources,
+};
+
 static struct platform_device *ecovec_devices[] __initdata = {
 	&heartbeat_device,
 	&nor_flash_device,
@@ -773,8 +791,10 @@ static struct platform_device *ecovec_de
 	&camera_devices[1],
 	&camera_devices[2],
 	&fsi_device,
+	&irda_device,
 };
 
+#ifdef CONFIG_I2C
 #define EEPROM_ADDR 0x50
 static u8 mac_read(struct i2c_adapter *a, u8 command)
 {
@@ -816,7 +836,15 @@ static void __init sh_eth_init(struct sh
 		pd->mac_addr[i] = mac_read(a, 0x10 + i);
 		msleep(10);
 	}
+
+	i2c_put_adapter(a);
 }
+#else
+static void __init sh_eth_init(struct sh_eth_plat_data *pd)
+{
+	pr_err("unable to read sh_eth MAC address\n");
+}
+#endif
 
 #define PORT_HIZA 0xA4050158
 #define IODRIVEA  0xA405018A
@@ -831,7 +859,8 @@ static int __init arch_setup(void)
 	struct clk *clk;
 
 	/* register board specific self-refresh code */
-	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
+	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF |
+					SUSP_SH_RSTANDBY,
 					&ecovec24_sdram_enter_start,
 					&ecovec24_sdram_enter_end,
 					&ecovec24_sdram_leave_start,
@@ -855,7 +884,7 @@ static int __init arch_setup(void)
 	gpio_direction_output(GPIO_PTG1, 0);
 	gpio_direction_output(GPIO_PTG2, 0);
 	gpio_direction_output(GPIO_PTG3, 0);
-	ctrl_outw((ctrl_inw(PORT_HIZA) & ~(0x1 << 1)) , PORT_HIZA);
+	__raw_writew((__raw_readw(PORT_HIZA) & ~(0x1 << 1)) , PORT_HIZA);
 
 	/* enable SH-Eth */
 	gpio_request(GPIO_PTA1, NULL);
@@ -875,16 +904,16 @@ static int __init arch_setup(void)
 	gpio_request(GPIO_FN_LNKSTA,       NULL);
 
 	/* enable USB */
-	ctrl_outw(0x0000, 0xA4D80000);
-	ctrl_outw(0x0000, 0xA4D90000);
+	__raw_writew(0x0000, 0xA4D80000);
+	__raw_writew(0x0000, 0xA4D90000);
 	gpio_request(GPIO_PTB3,  NULL);
 	gpio_request(GPIO_PTB4,  NULL);
 	gpio_request(GPIO_PTB5,  NULL);
 	gpio_direction_input(GPIO_PTB3);
 	gpio_direction_output(GPIO_PTB4, 0);
 	gpio_direction_output(GPIO_PTB5, 0);
-	ctrl_outw(0x0600, 0xa40501d4);
-	ctrl_outw(0x0600, 0xa4050192);
+	__raw_writew(0x0600, 0xa40501d4);
+	__raw_writew(0x0600, 0xa4050192);
 
 	if (gpio_get_value(GPIO_PTB3)) {
 		printk(KERN_INFO "USB1 function is selected\n");
@@ -925,7 +954,7 @@ static int __init arch_setup(void)
 	gpio_request(GPIO_FN_LCDVSYN,  NULL);
 	gpio_request(GPIO_FN_LCDDON,   NULL);
 	gpio_request(GPIO_FN_LCDLCLK,  NULL);
-	ctrl_outw((ctrl_inw(PORT_HIZA) & ~0x0001), PORT_HIZA);
+	__raw_writew((__raw_readw(PORT_HIZA) & ~0x0001), PORT_HIZA);
 
 	gpio_request(GPIO_PTE6, NULL);
 	gpio_request(GPIO_PTU1, NULL);
@@ -937,7 +966,7 @@ static int __init arch_setup(void)
 	gpio_direction_output(GPIO_PTA2, 0);
 
 	/* I/O buffer drive ability is high */
-	ctrl_outw((ctrl_inw(IODRIVEA) & ~0x00c0) | 0x0080 , IODRIVEA);
+	__raw_writew((__raw_readw(IODRIVEA) & ~0x00c0) | 0x0080 , IODRIVEA);
 
 	if (gpio_get_value(GPIO_PTE6)) {
 		/* DVI */
@@ -1069,7 +1098,7 @@ static int __init arch_setup(void)
 	gpio_direction_output(GPIO_PTB7, 0);
 
 	/* I/O buffer drive ability is high for SDHI1 */
-	ctrl_outw((ctrl_inw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA);
+	__raw_writew((__raw_readw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA);
 #else
 	/* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */
 	gpio_request(GPIO_FN_MSIOF0_TXD, NULL);
@@ -1107,6 +1136,11 @@ static int __init arch_setup(void)
 	gpio_request(GPIO_FN_FSIOBLRCK,  NULL);
 	gpio_request(GPIO_FN_CLKAUDIOBO, NULL);
 
+	/* set SPU2 clock to 83.4 MHz */
+	clk = clk_get(NULL, "spu_clk");
+	clk_set_rate(clk, clk_round_rate(clk, 83333333));
+	clk_put(clk);
+
 	/* change parent of FSI B */
 	clk = clk_get(NULL, "fsib_clk");
 	clk_register(&fsimckb_clk);
@@ -1123,6 +1157,17 @@ static int __init arch_setup(void)
 	gpio_request(GPIO_FN_INTC_IRQ1, NULL);
 	gpio_direction_input(GPIO_FN_INTC_IRQ1);
 
+	/* set VPU clock to 166 MHz */
+	clk = clk_get(NULL, "vpu_clk");
+	clk_set_rate(clk, clk_round_rate(clk, 166000000));
+	clk_put(clk);
+
+	/* enable IrDA */
+	gpio_request(GPIO_FN_IRDA_OUT, NULL);
+	gpio_request(GPIO_FN_IRDA_IN,  NULL);
+	gpio_request(GPIO_PTU5, NULL);
+	gpio_direction_output(GPIO_PTU5, 0);
+
 	/* enable I2C device */
 	i2c_register_board_info(0, i2c0_devices,
 				ARRAY_SIZE(i2c0_devices));
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-highlander/irq-r7780mp.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-highlander/irq-r7780mp.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-highlander/irq-r7780mp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-highlander/irq-r7780mp.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,7 +64,7 @@ static DECLARE_INTC_DESC(intc_desc, "r77
 
 unsigned char * __init highlander_plat_irq_setup(void)
 {
-	if ((ctrl_inw(0xa4000700) & 0xf000) == 0x2000) {
+	if ((__raw_readw(0xa4000700) & 0xf000) == 0x2000) {
 		printk(KERN_INFO "Using r7780mp interrupt controller.\n");
 		register_intc_controller(&intc_desc);
 		return irl2irq;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-highlander/irq-r7780rp.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-highlander/irq-r7780rp.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-highlander/irq-r7780rp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-highlander/irq-r7780rp.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,7 +57,7 @@ static DECLARE_INTC_DESC(intc_desc, "r77
 
 unsigned char * __init highlander_plat_irq_setup(void)
 {
-	if (ctrl_inw(0xa5000600)) {
+	if (__raw_readw(0xa5000600)) {
 		printk(KERN_INFO "Using r7780rp interrupt controller.\n");
 		register_intc_controller(&intc_desc);
 		return irl2irq;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-highlander/irq-r7785rp.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-highlander/irq-r7785rp.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-highlander/irq-r7785rp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-highlander/irq-r7785rp.c	2010-05-16 17:17:36.000000000 -0400
@@ -66,20 +66,20 @@ static DECLARE_INTC_DESC(intc_desc, "r77
 
 unsigned char * __init highlander_plat_irq_setup(void)
 {
-	if ((ctrl_inw(0xa4000158) & 0xf000) != 0x1000)
+	if ((__raw_readw(0xa4000158) & 0xf000) != 0x1000)
 		return NULL;
 
 	printk(KERN_INFO "Using r7785rp interrupt controller.\n");
 
-	ctrl_outw(0x0000, PA_IRLSSR1);	/* FPGA IRLSSR1(CF_CD clear) */
+	__raw_writew(0x0000, PA_IRLSSR1);	/* FPGA IRLSSR1(CF_CD clear) */
 
 	/* Setup the FPGA IRL */
-	ctrl_outw(0x0000, PA_IRLPRA);	/* FPGA IRLA */
-	ctrl_outw(0xe598, PA_IRLPRB);	/* FPGA IRLB */
-	ctrl_outw(0x7060, PA_IRLPRC);	/* FPGA IRLC */
-	ctrl_outw(0x0000, PA_IRLPRD);	/* FPGA IRLD */
-	ctrl_outw(0x4321, PA_IRLPRE);	/* FPGA IRLE */
-	ctrl_outw(0xdcba, PA_IRLPRF);	/* FPGA IRLF */
+	__raw_writew(0x0000, PA_IRLPRA);	/* FPGA IRLA */
+	__raw_writew(0xe598, PA_IRLPRB);	/* FPGA IRLB */
+	__raw_writew(0x7060, PA_IRLPRC);	/* FPGA IRLC */
+	__raw_writew(0x0000, PA_IRLPRD);	/* FPGA IRLD */
+	__raw_writew(0x4321, PA_IRLPRE);	/* FPGA IRLE */
+	__raw_writew(0xdcba, PA_IRLPRF);	/* FPGA IRLF */
 
 	register_intc_controller(&intc_desc);
 	return irl2irq;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-highlander/psw.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-highlander/psw.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-highlander/psw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-highlander/psw.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,7 @@ static irqreturn_t psw_irq_handler(int i
 	unsigned int l, mask;
 	int ret = 0;
 
-	l = ctrl_inw(PA_DBSW);
+	l = __raw_readw(PA_DBSW);
 
 	/* Nothing to do if there's no state change */
 	if (psw->state) {
@@ -45,7 +45,7 @@ static irqreturn_t psw_irq_handler(int i
 out:
 	/* Clear the switch IRQs */
 	l |= (0x7 << 12);
-	ctrl_outw(l, PA_DBSW);
+	__raw_writew(l, PA_DBSW);
 
 	return IRQ_RETVAL(ret);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-highlander/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-highlander/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-highlander/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-highlander/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -311,13 +311,13 @@ device_initcall(r7780rp_devices_setup);
  */
 static int ivdr_clk_enable(struct clk *clk)
 {
-	ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << IVDR_CK_ON), PA_IVDRCTL);
+	__raw_writew(__raw_readw(PA_IVDRCTL) | (1 << IVDR_CK_ON), PA_IVDRCTL);
 	return 0;
 }
 
 static void ivdr_clk_disable(struct clk *clk)
 {
-	ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL);
+	__raw_writew(__raw_readw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL);
 }
 
 static struct clk_ops ivdr_clk_ops = {
@@ -337,7 +337,7 @@ static struct clk *r7780rp_clocks[] = {
 static void r7780rp_power_off(void)
 {
 	if (mach_is_r7780mp() || mach_is_r7785rp())
-		ctrl_outw(0x0001, PA_POFF);
+		__raw_writew(0x0001, PA_POFF);
 }
 
 /*
@@ -345,7 +345,7 @@ static void r7780rp_power_off(void)
  */
 static void __init highlander_setup(char **cmdline_p)
 {
-	u16 ver = ctrl_inw(PA_VERREG);
+	u16 ver = __raw_readw(PA_VERREG);
 	int i;
 
 	printk(KERN_INFO "Renesas Solutions Highlander %s support.\n",
@@ -370,12 +370,12 @@ static void __init highlander_setup(char
 		clk_enable(clk);
 	}
 
-	ctrl_outw(0x0000, PA_OBLED);	/* Clear LED. */
+	__raw_writew(0x0000, PA_OBLED);	/* Clear LED. */
 
 	if (mach_is_r7780rp())
-		ctrl_outw(0x0001, PA_SDPOW);	/* SD Power ON */
+		__raw_writew(0x0001, PA_SDPOW);	/* SD Power ON */
 
-	ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x01, PA_IVDRCTL);	/* Si13112 */
+	__raw_writew(__raw_readw(PA_IVDRCTL) | 0x01, PA_IVDRCTL);	/* Si13112 */
 
 	pm_power_off = r7780rp_power_off;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-hp6xx/hp6xx_apm.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-hp6xx/hp6xx_apm.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-hp6xx/hp6xx_apm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-hp6xx/hp6xx_apm.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,7 +53,7 @@ static void hp6x0_apm_get_power_status(s
 	info->ac_line_status = (battery > HP680_BATTERY_AC_ON) ?
 			 APM_AC_ONLINE : APM_AC_OFFLINE;
 
-	pgdr = ctrl_inb(PGDR);
+	pgdr = __raw_readb(PGDR);
 	if (pgdr & PGDR_MAIN_BATTERY_OUT) {
 		info->battery_status	= APM_BATTERY_STATUS_NOT_PRESENT;
 		info->battery_flag	= 0x80;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-hp6xx/pm.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-hp6xx/pm.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-hp6xx/pm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-hp6xx/pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,17 +53,17 @@ static void pm_enter(void)
 	sh_wdt_write_cnt(0);
 
 	/* disable PLL1 */
-	frqcr = ctrl_inw(FRQCR);
+	frqcr = __raw_readw(FRQCR);
 	frqcr &= ~(FRQCR_PLLEN | FRQCR_PSTBY);
-	ctrl_outw(frqcr, FRQCR);
+	__raw_writew(frqcr, FRQCR);
 
 	/* enable standby */
-	stbcr = ctrl_inb(STBCR);
-	ctrl_outb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR);
+	stbcr = __raw_readb(STBCR);
+	__raw_writeb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR);
 
 	/* set self-refresh */
-	mcr = ctrl_inw(MCR);
-	ctrl_outw(mcr & ~MCR_RFSH, MCR);
+	mcr = __raw_readw(MCR);
+	__raw_writew(mcr & ~MCR_RFSH, MCR);
 
 	/* set interrupt handler */
 	asm volatile("stc vbr, %0" : "=r" (vbr_old));
@@ -73,8 +73,8 @@ static void pm_enter(void)
 	       &wakeup_start, &wakeup_end - &wakeup_start);
 	asm volatile("ldc %0, vbr" : : "r" (vbr_new));
 
-	ctrl_outw(0, RTCNT);
-	ctrl_outw(mcr | MCR_RFSH | MCR_RMODE, MCR);
+	__raw_writew(0, RTCNT);
+	__raw_writew(mcr | MCR_RFSH | MCR_RMODE, MCR);
 
 	cpu_sleep();
 
@@ -83,14 +83,14 @@ static void pm_enter(void)
 	free_page(vbr_new);
 
 	/* enable PLL1 */
-	frqcr = ctrl_inw(FRQCR);
+	frqcr = __raw_readw(FRQCR);
 	frqcr |= FRQCR_PSTBY;
-	ctrl_outw(frqcr, FRQCR);
+	__raw_writew(frqcr, FRQCR);
 	udelay(50);
 	frqcr |= FRQCR_PLLEN;
-	ctrl_outw(frqcr, FRQCR);
+	__raw_writew(frqcr, FRQCR);
 
-	ctrl_outb(stbcr, STBCR);
+	__raw_writeb(stbcr, STBCR);
 
 	clear_bl_bit();
 }
@@ -115,21 +115,21 @@ static int hp6x0_pm_enter(suspend_state_
 	outw(hd64461_stbcr, HD64461_STBCR);
 #endif
 
-	ctrl_outb(0x1f, DACR);
+	__raw_writeb(0x1f, DACR);
 
-	stbcr = ctrl_inb(STBCR);
-	ctrl_outb(0x01, STBCR);
+	stbcr = __raw_readb(STBCR);
+	__raw_writeb(0x01, STBCR);
 
-	stbcr2 = ctrl_inb(STBCR2);
-	ctrl_outb(0x7f , STBCR2);
+	stbcr2 = __raw_readb(STBCR2);
+	__raw_writeb(0x7f , STBCR2);
 
 	outw(0xf07f, HD64461_SCPUCR);
 
 	pm_enter();
 
 	outw(0, HD64461_SCPUCR);
-	ctrl_outb(stbcr, STBCR);
-	ctrl_outb(stbcr2, STBCR2);
+	__raw_writeb(stbcr, STBCR);
+	__raw_writeb(stbcr2, STBCR2);
 
 #ifdef CONFIG_HD64461_ENABLER
 	hd64461_stbcr = inw(HD64461_STBCR);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-hp6xx/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-hp6xx/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-hp6xx/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-hp6xx/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -149,19 +149,19 @@ static void __init hp6xx_setup(char **cm
 
 	sh_dac_output(0, DAC_SPEAKER_VOLUME);
 	sh_dac_disable(DAC_SPEAKER_VOLUME);
-	v8 = ctrl_inb(DACR);
+	v8 = __raw_readb(DACR);
 	v8 &= ~DACR_DAE;
-	ctrl_outb(v8,DACR);
+	__raw_writeb(v8,DACR);
 
-	v8 = ctrl_inb(SCPDR);
+	v8 = __raw_readb(SCPDR);
 	v8 |= SCPDR_TS_SCAN_X | SCPDR_TS_SCAN_Y;
 	v8 &= ~SCPDR_TS_SCAN_ENABLE;
-	ctrl_outb(v8, SCPDR);
+	__raw_writeb(v8, SCPDR);
 
-	v = ctrl_inw(SCPCR);
+	v = __raw_readw(SCPCR);
 	v &= ~SCPCR_TS_MASK;
 	v |= SCPCR_TS_ENABLE;
-	ctrl_outw(v, SCPCR);
+	__raw_writew(v, SCPCR);
 }
 device_initcall(hp6xx_devices_setup);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-kfr2r09/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-kfr2r09/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-kfr2r09/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-kfr2r09/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -282,7 +282,7 @@ static int camera_power(struct device *d
 		 * use 1.8 V for VccQ_VIO
 		 * use 2.85V for VccQ_SR
 		 */
-		ctrl_outw((ctrl_inw(DRVCRB) & ~0x0003) | 0x0001, DRVCRB);
+		__raw_writew((__raw_readw(DRVCRB) & ~0x0003) | 0x0001, DRVCRB);
 
 		/* reset clear */
 		ret = gpio_request(GPIO_PTB4, NULL);
@@ -351,7 +351,7 @@ static struct resource kfr2r09_sh_sdhi0_
 		.flags  = IORESOURCE_MEM,
 	},
 	[1] = {
-		.start  = 101,
+		.start  = 100,
 		.flags  = IORESOURCE_IRQ,
 	},
 };
@@ -492,13 +492,13 @@ static int kfr2r09_usb0_gadget_setup(voi
 	if (kfr2r09_usb0_gadget_i2c_setup() != 0)
 		return -ENODEV; /* unable to configure using i2c */
 
-	ctrl_outw((ctrl_inw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
+	__raw_writew((__raw_readw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
 	gpio_request(GPIO_FN_PDSTATUS, NULL); /* R-standby disables USB clock */
 	gpio_request(GPIO_PTV6, NULL); /* USBCLK_ON */
 	gpio_direction_output(GPIO_PTV6, 1); /* USBCLK_ON = H */
 	msleep(20); /* wait 20ms to let the clock settle */
 	clk_enable(clk_get(NULL, "usb0"));
-	ctrl_outw(0x0600, 0xa40501d4);
+	__raw_writew(0x0600, 0xa40501d4);
 
 	return 0;
 }
@@ -526,12 +526,12 @@ static int __init kfr2r09_devices_setup(
 	gpio_direction_output(GPIO_PTG3, 1); /* HPON_ON = H */
 
 	/* setup NOR flash at CS0 */
-	ctrl_outl(0x36db0400, BSC_CS0BCR);
-	ctrl_outl(0x00000500, BSC_CS0WCR);
+	__raw_writel(0x36db0400, BSC_CS0BCR);
+	__raw_writel(0x00000500, BSC_CS0WCR);
 
 	/* setup NAND flash at CS4 */
-	ctrl_outl(0x36db0400, BSC_CS4BCR);
-	ctrl_outl(0x00000500, BSC_CS4WCR);
+	__raw_writel(0x36db0400, BSC_CS4BCR);
+	__raw_writel(0x00000500, BSC_CS4WCR);
 
 	/* setup KEYSC pins */
 	gpio_request(GPIO_FN_KEYOUT0, NULL);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-landisk/gio.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-landisk/gio.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-landisk/gio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-landisk/gio.c	2010-05-16 17:17:36.000000000 -0400
@@ -76,39 +76,39 @@ static long gio_ioctl(struct file *filp,
 		break;
 
 	case GIODRV_IOCSGIODATA1:	/* write byte */
-		ctrl_outb((unsigned char)(0x0ff & data), addr);
+		__raw_writeb((unsigned char)(0x0ff & data), addr);
 		break;
 
 	case GIODRV_IOCSGIODATA2:	/* write word */
 		if (addr & 0x01) {
 			return -EFAULT;
 		}
-		ctrl_outw((unsigned short int)(0x0ffff & data), addr);
+		__raw_writew((unsigned short int)(0x0ffff & data), addr);
 		break;
 
 	case GIODRV_IOCSGIODATA4:	/* write long */
 		if (addr & 0x03) {
 			return -EFAULT;
 		}
-		ctrl_outl(data, addr);
+		__raw_writel(data, addr);
 		break;
 
 	case GIODRV_IOCGGIODATA1:	/* read byte */
-		data = ctrl_inb(addr);
+		data = __raw_readb(addr);
 		break;
 
 	case GIODRV_IOCGGIODATA2:	/* read word */
 		if (addr & 0x01) {
 			return -EFAULT;
 		}
-		data = ctrl_inw(addr);
+		data = __raw_readw(addr);
 		break;
 
 	case GIODRV_IOCGGIODATA4:	/* read long */
 		if (addr & 0x03) {
 			return -EFAULT;
 		}
-		data = ctrl_inl(addr);
+		data = __raw_readl(addr);
 		break;
 	default:
 		return -EFAULT;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-landisk/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-landisk/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-landisk/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-landisk/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,14 +22,14 @@ static void disable_landisk_irq(unsigned
 {
 	unsigned char mask = 0xff ^ (0x01 << (irq - 5));
 
-	ctrl_outb(ctrl_inb(PA_IMASK) & mask, PA_IMASK);
+	__raw_writeb(__raw_readb(PA_IMASK) & mask, PA_IMASK);
 }
 
 static void enable_landisk_irq(unsigned int irq)
 {
 	unsigned char value = (0x01 << (irq - 5));
 
-	ctrl_outb(ctrl_inb(PA_IMASK) | value, PA_IMASK);
+	__raw_writeb(__raw_readb(PA_IMASK) | value, PA_IMASK);
 }
 
 static struct irq_chip landisk_irq_chip __read_mostly = {
@@ -52,5 +52,5 @@ void __init init_landisk_IRQ(void)
 					      handle_level_irq, "level");
 		enable_landisk_irq(i);
 	}
-	ctrl_outb(0x00, PA_PWRINT_CLR);
+	__raw_writeb(0x00, PA_PWRINT_CLR);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-landisk/psw.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-landisk/psw.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-landisk/psw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-landisk/psw.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,7 @@ static irqreturn_t psw_irq_handler(int i
 	unsigned int sw_value;
 	int ret = 0;
 
-	sw_value = (0x0ff & (~ctrl_inb(PA_STATUS)));
+	sw_value = (0x0ff & (~__raw_readb(PA_STATUS)));
 
 	/* Nothing to do if there's no state change */
 	if (psw->state) {
@@ -42,7 +42,7 @@ static irqreturn_t psw_irq_handler(int i
 
 out:
 	/* Clear the switch IRQs */
-	ctrl_outb(0x00, PA_PWRINT_CLR);
+	__raw_writeb(0x00, PA_PWRINT_CLR);
 
 	return IRQ_RETVAL(ret);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-landisk/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-landisk/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-landisk/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-landisk/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,7 @@ void init_landisk_IRQ(void);
 
 static void landisk_power_off(void)
 {
-        ctrl_outb(0x01, PA_SHUTDOWN);
+        __raw_writeb(0x01, PA_SHUTDOWN);
 }
 
 static struct resource cf_ide_resources[3];
@@ -63,7 +63,7 @@ static int __init landisk_devices_setup(
 	/* open I/O area window */
 	paddrbase = virt_to_phys((void *)PA_AREA5_IO);
 	prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
-	cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
+	cf_ide_base = ioremap_prot(paddrbase, PAGE_SIZE, pgprot_val(prot));
 	if (!cf_ide_base) {
 		printk("allocate_cf_area : can't open CF I/O window!\n");
 		return -ENOMEM;
@@ -88,7 +88,7 @@ __initcall(landisk_devices_setup);
 static void __init landisk_setup(char **cmdline_p)
 {
         /* LED ON */
-	ctrl_outb(ctrl_inb(PA_LED) | 0x03, PA_LED);
+	__raw_writeb(__raw_readb(PA_LED) | 0x03, PA_LED);
 
 	printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n");
 	pm_power_off = landisk_power_off;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-lboxre2/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-lboxre2/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-lboxre2/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-lboxre2/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -56,8 +56,8 @@ static int __init lboxre2_devices_setup(
 	/* open I/O area window */
 	paddrbase = virt_to_phys((void*)PA_AREA5_IO);
 	psize = PAGE_SIZE;
-	prot = PAGE_KERNEL_PCC( 1 , _PAGE_PCC_IO16);
-	cf0_io_base = (u32)p3_ioremap(paddrbase, psize, prot.pgprot);
+	prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
+	cf0_io_base = (u32)ioremap_prot(paddrbase, psize, pgprot_val(prot));
 	if (!cf0_io_base) {
 		printk(KERN_ERR "%s : can't open CF I/O window!\n" , __func__ );
 		return -ENOMEM;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-microdev/io.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-microdev/io.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-microdev/io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-microdev/io.c	2010-05-16 17:17:36.000000000 -0400
@@ -141,10 +141,10 @@ static inline void delay(void)
 #if defined(CONFIG_PCI)
 	/* System board present, just make a dummy SRAM access.  (CS0 will be
 	   mapped to PCI memory, probably good to avoid it.) */
-	ctrl_inw(0xa6800000);
+	__raw_readw(0xa6800000);
 #else
 	/* CS0 will be mapped to flash, ROM etc so safe to access it. */
-	ctrl_inw(0xa0000000);
+	__raw_readw(0xa0000000);
 #endif
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-microdev/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-microdev/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-microdev/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-microdev/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -88,7 +88,7 @@ static void disable_microdev_irq(unsigne
 	fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
 
 	/* disable interrupts on the FPGA INTC register */
-	ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);
+	__raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);
 }
 
 static void enable_microdev_irq(unsigned int irq)
@@ -107,13 +107,13 @@ static void enable_microdev_irq(unsigned
 	priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq);
 
 	/* set priority for the interrupt */
-	priorities = ctrl_inl(priorityReg);
+	priorities = __raw_readl(priorityReg);
 	priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq);
 	priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri);
-	ctrl_outl(priorities, priorityReg);
+	__raw_writel(priorities, priorityReg);
 
 	/* enable interrupts on the FPGA INTC register */
-	ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);
+	__raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);
 }
 
 /* This function sets the desired irq handler to be a MicroDev type */
@@ -134,7 +134,7 @@ extern void __init init_microdev_irq(voi
 	int i;
 
 	/* disable interrupts on the FPGA INTC register */
-	ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG);
+	__raw_writel(~0ul, MICRODEV_FPGA_INTDSB_REG);
 
 	for (i = 0; i < NUM_EXTERNAL_IRQS; i++)
 		make_microdev_irq(i);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-migor/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-migor/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-migor/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-migor/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -397,7 +397,7 @@ static struct resource sdhi_cn9_resource
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= 101,
+		.start	= 100,
 		.flags  = IORESOURCE_IRQ,
 	},
 };
@@ -419,6 +419,9 @@ static struct i2c_board_info migor_i2c_d
 		I2C_BOARD_INFO("migor_ts", 0x51),
 		.irq = 38, /* IRQ6 */
 	},
+	{
+		I2C_BOARD_INFO("wm8978", 0x1a),
+	},
 };
 
 static struct i2c_board_info migor_i2c_camera[] = {
@@ -431,7 +434,7 @@ static struct i2c_board_info migor_i2c_c
 };
 
 static struct ov772x_camera_info ov7725_info = {
-	.buswidth	= SOCAM_DATAWIDTH_8,
+	.flags		= OV772X_FLAG_8BIT,
 };
 
 static struct soc_camera_link ov7725_link = {
@@ -496,28 +499,16 @@ static int __init migor_devices_setup(vo
 					&migor_sdram_enter_end,
 					&migor_sdram_leave_start,
 					&migor_sdram_leave_end);
-#ifdef CONFIG_PM
 	/* Let D11 LED show STATUS0 */
 	gpio_request(GPIO_FN_STATUS0, NULL);
 
 	/* 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);
-	gpio_export(GPIO_PTJ7, 0);
-
-	/* Lit D12 LED */
-	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);
-	ctrl_outl(0x00003400, BSC_CS4BCR);
-	ctrl_outl(0x00110080, BSC_CS4WCR);
+	__raw_writel(0x00003400, BSC_CS4BCR);
+	__raw_writel(0x00110080, BSC_CS4WCR);
 
 	/* KEYSC */
 	gpio_request(GPIO_FN_KEYOUT0, NULL);
@@ -533,7 +524,7 @@ static int __init migor_devices_setup(vo
 
 	/* NAND Flash */
 	gpio_request(GPIO_FN_CS6A_CE2B, NULL);
-	ctrl_outl((ctrl_inl(BSC_CS6ABCR) & ~0x0600) | 0x0200, BSC_CS6ABCR);
+	__raw_writel((__raw_readl(BSC_CS6ABCR) & ~0x0600) | 0x0200, BSC_CS6ABCR);
 	gpio_request(GPIO_PTA1, NULL);
 	gpio_direction_input(GPIO_PTA1);
 
@@ -627,10 +618,23 @@ static int __init migor_devices_setup(vo
 #else
 	gpio_direction_output(GPIO_PTT0, 1);
 #endif
-	ctrl_outw(ctrl_inw(PORT_MSELCRB) | 0x2000, PORT_MSELCRB); /* D15->D8 */
+	__raw_writew(__raw_readw(PORT_MSELCRB) | 0x2000, PORT_MSELCRB); /* D15->D8 */
 
 	platform_resource_setup_memory(&migor_ceu_device, "ceu", 4 << 20);
 
+	/* SIU: Port B */
+	gpio_request(GPIO_FN_SIUBOLR, NULL);
+	gpio_request(GPIO_FN_SIUBOBT, NULL);
+	gpio_request(GPIO_FN_SIUBISLD, NULL);
+	gpio_request(GPIO_FN_SIUBOSLD, NULL);
+	gpio_request(GPIO_FN_SIUMCKB, NULL);
+
+	/*
+	 * The original driver sets SIUB OLR/OBT, ILR/IBT, and SIUA OLR/OBT to
+	 * output. Need only SIUB, set to output for master mode (table 34.2)
+	 */
+	__raw_writew(__raw_readw(PORT_MSELCRA) | 1, PORT_MSELCRA);
+
 	i2c_register_board_info(0, migor_i2c_devices,
 				ARRAY_SIZE(migor_i2c_devices));
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-r2d/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-r2d/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-r2d/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-r2d/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -129,7 +129,7 @@ void __init init_rts7751r2d_IRQ(void)
 {
 	struct intc_desc *d;
 
-	switch (ctrl_inw(PA_VERREG) & 0xf0) {
+	switch (__raw_readw(PA_VERREG) & 0xf0) {
 #ifdef CONFIG_RTS7751R2D_PLUS
 	case 0x10:
 		printk(KERN_INFO "Using R2D-PLUS interrupt controller.\n");
@@ -147,7 +147,7 @@ void __init init_rts7751r2d_IRQ(void)
 #endif
 	default:
 		printk(KERN_INFO "Unknown R2D interrupt controller 0x%04x\n",
-		       ctrl_inw(PA_VERREG));
+		       __raw_readw(PA_VERREG));
 		return;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-r2d/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-r2d/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-r2d/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-r2d/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -70,7 +70,7 @@ static struct spi_board_info spi_bus[] =
 static void r2d_chip_select(struct sh_spi_info *spi, int cs, int state)
 {
 	BUG_ON(cs != 0);  /* Single Epson RTC-9701JE attached on CS0 */
-	ctrl_outw(state == BITBANG_CS_ACTIVE, PA_RTCCE);
+	__raw_writew(state == BITBANG_CS_ACTIVE, PA_RTCCE);
 }
 
 static struct sh_spi_info spi_info = {
@@ -262,7 +262,7 @@ __initcall(rts7751r2d_devices_setup);
 
 static void rts7751r2d_power_off(void)
 {
-	ctrl_outw(0x0001, PA_POWOFF);
+	__raw_writew(0x0001, PA_POWOFF);
 }
 
 /*
@@ -271,14 +271,14 @@ static void rts7751r2d_power_off(void)
 static void __init rts7751r2d_setup(char **cmdline_p)
 {
 	void __iomem *sm501_reg;
-	u16 ver = ctrl_inw(PA_VERREG);
+	u16 ver = __raw_readw(PA_VERREG);
 
 	printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n");
 
 	printk(KERN_INFO "FPGA version:%d (revision:%d)\n",
 					(ver >> 4) & 0xf, ver & 0xf);
 
-	ctrl_outw(0x0000, PA_OUTPORT);
+	__raw_writew(0x0000, PA_OUTPORT);
 	pm_power_off = rts7751r2d_power_off;
 
 	/* sm501 dram configuration:
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-rsk/devices-rsk7203.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-rsk/devices-rsk7203.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-rsk/devices-rsk7203.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-rsk/devices-rsk7203.c	2010-05-16 17:17:36.000000000 -0400
@@ -96,7 +96,7 @@ static int __init rsk7203_devices_setup(
 	gpio_request(GPIO_FN_RXD0, NULL);
 
 	/* Setup LAN9118: CS1 in 16-bit Big Endian Mode, IRQ0 at Port B */
-	ctrl_outl(0x36db0400, 0xfffc0008); /* CS1BCR */
+	__raw_writel(0x36db0400, 0xfffc0008); /* CS1BCR */
 	gpio_request(GPIO_FN_IRQ0_PB, NULL);
 
 	return platform_add_devices(rsk7203_devices,
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sdk7780/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sdk7780/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sdk7780/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sdk7780/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,9 +37,9 @@ void __init init_sdk7780_IRQ(void)
 {
 	printk(KERN_INFO "Using SDK7780 interrupt controller.\n");
 
-	ctrl_outw(0xFFFF, FPGA_IRQ0MR);
+	__raw_writew(0xFFFF, FPGA_IRQ0MR);
 	/* Setup IRL 0-3 */
-	ctrl_outw(0x0003, FPGA_IMSR);
+	__raw_writew(0x0003, FPGA_IMSR);
 	plat_irq_setup_pins(IRQ_MODE_IRL3210);
 
 	register_intc_controller(&fpga_intc_desc);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sdk7780/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sdk7780/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sdk7780/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sdk7780/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,27 +20,18 @@
 
 #define GPIO_PECR        0xFFEA0008
 
-//* Heartbeat */
-static struct heartbeat_data heartbeat_data = {
-	.regsize = 16,
-};
-
-static struct resource heartbeat_resources[] = {
-	[0] = {
-		.start  = PA_LED,
-		.end    = PA_LED,
-		.flags  = IORESOURCE_MEM,
-	},
+/* Heartbeat */
+static struct resource heartbeat_resource = {
+	.start  = PA_LED,
+	.end    = PA_LED,
+	.flags  = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
 };
 
 static struct platform_device heartbeat_device = {
 	.name           = "heartbeat",
 	.id             = -1,
-	.dev = {
-		.platform_data = &heartbeat_data,
-	},
-	.num_resources  = ARRAY_SIZE(heartbeat_resources),
-	.resource       = heartbeat_resources,
+	.num_resources  = 1,
+	.resource       = &heartbeat_resource,
 };
 
 /* SMC91x */
@@ -83,8 +74,8 @@ device_initcall(sdk7780_devices_setup);
 
 static void __init sdk7780_setup(char **cmdline_p)
 {
-	u16 ver = ctrl_inw(FPGA_FPVERR);
-	u16 dateStamp = ctrl_inw(FPGA_FPDATER);
+	u16 ver = __raw_readw(FPGA_FPVERR);
+	u16 dateStamp = __raw_readw(FPGA_FPDATER);
 
 	printk(KERN_INFO "Renesas Technology Europe SDK7780 support.\n");
 	printk(KERN_INFO "Board version: %d (revision %d), "
@@ -94,7 +85,7 @@ static void __init sdk7780_setup(char **
 			 dateStamp);
 
 	/* Setup pin mux'ing for PCIC */
-	ctrl_outw(0x0000, GPIO_PECR);
+	__raw_writew(0x0000, GPIO_PECR);
 }
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sdk7786/fpga.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sdk7786/fpga.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sdk7786/fpga.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sdk7786/fpga.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,72 @@
+/*
+ * SDK7786 FPGA Support.
+ *
+ * Copyright (C) 2010  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/io.h>
+#include <linux/bcd.h>
+#include <mach/fpga.h>
+#include <asm/sizes.h>
+
+#define FPGA_REGS_OFFSET	0x03fff800
+#define FPGA_REGS_SIZE		0x490
+
+/*
+ * The FPGA can be mapped in any of the generally available areas,
+ * so we attempt to scan for it using the fixed SRSTR read magic.
+ *
+ * Once the FPGA is located, the rest of the mapping data for the other
+ * components can be determined dynamically from its section mapping
+ * registers.
+ */
+static void __iomem *sdk7786_fpga_probe(void)
+{
+	unsigned long area;
+	void __iomem *base;
+
+	/*
+	 * Iterate over all of the areas where the FPGA could be mapped.
+	 * The possible range is anywhere from area 0 through 6, area 7
+	 * is reserved.
+	 */
+	for (area = PA_AREA0; area < PA_AREA7; area += SZ_64M) {
+		base = ioremap_nocache(area + FPGA_REGS_OFFSET, FPGA_REGS_SIZE);
+		if (!base) {
+			/* Failed to remap this area, move along. */
+			continue;
+		}
+
+		if (ioread16(base + SRSTR) == SRSTR_MAGIC)
+			return base;	/* Found it! */
+
+		iounmap(base);
+	}
+
+	return NULL;
+}
+
+void __iomem *sdk7786_fpga_base;
+
+void __init sdk7786_fpga_init(void)
+{
+	u16 version, date;
+
+	sdk7786_fpga_base = sdk7786_fpga_probe();
+	if (unlikely(!sdk7786_fpga_base)) {
+		panic("FPGA detection failed.\n");
+		return;
+	}
+
+	version = fpga_read_reg(FPGAVR);
+	date = fpga_read_reg(FPGADR);
+
+	pr_info("\tFPGA version:\t%d.%d (built on %d/%d/%d)\n",
+		bcd2bin(version >> 8) & 0xf, bcd2bin(version & 0xf),
+		((date >> 12) & 0xf) + 2000,
+		(date >> 8) & 0xf, bcd2bin(date & 0xff));
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sdk7786/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sdk7786/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sdk7786/irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sdk7786/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ * SDK7786 FPGA IRQ Controller Support.
+ *
+ * Copyright (C) 2010  Matt Fleming
+ * Copyright (C) 2010  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/irq.h>
+#include <mach/fpga.h>
+#include <mach/irq.h>
+
+enum {
+	ATA_IRQ_BIT		= 1,
+	SPI_BUSY_BIT		= 2,
+	LIRQ5_BIT		= 3,
+	LIRQ6_BIT		= 4,
+	LIRQ7_BIT		= 5,
+	LIRQ8_BIT		= 6,
+	KEY_IRQ_BIT		= 7,
+	PEN_IRQ_BIT		= 8,
+	ETH_IRQ_BIT		= 9,
+	RTC_ALARM_BIT		= 10,
+	CRYSTAL_FAIL_BIT	= 12,
+	ETH_PME_BIT		= 14,
+};
+
+void __init sdk7786_init_irq(void)
+{
+	unsigned int tmp;
+
+	/* Enable priority encoding for all IRLs */
+	fpga_write_reg(fpga_read_reg(INTMSR) | 0x0303, INTMSR);
+
+	/* Clear FPGA interrupt status registers */
+	fpga_write_reg(0x0000, INTASR);
+	fpga_write_reg(0x0000, INTBSR);
+
+	/* Unmask FPGA interrupts */
+	tmp = fpga_read_reg(INTAMR);
+	tmp &= ~(1 << ETH_IRQ_BIT);
+	fpga_write_reg(tmp, INTAMR);
+
+	plat_irq_setup_pins(IRQ_MODE_IRL7654_MASK);
+	plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sdk7786/Makefile linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sdk7786/Makefile
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sdk7786/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sdk7786/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1 @@
+obj-y	:= setup.o fpga.o irq.o
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sdk7786/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sdk7786/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sdk7786/setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sdk7786/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,189 @@
+/*
+ * Renesas Technology Europe SDK7786 Support.
+ *
+ * Copyright (C) 2010  Matt Fleming
+ * Copyright (C) 2010  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/platform_device.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <mach/fpga.h>
+#include <mach/irq.h>
+#include <asm/machvec.h>
+#include <asm/heartbeat.h>
+#include <asm/sizes.h>
+#include <asm/reboot.h>
+
+static struct resource heartbeat_resource = {
+	.start		= 0x07fff8b0,
+	.end		= 0x07fff8b0 + sizeof(u16) - 1,
+	.flags		= IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
+};
+
+static struct platform_device heartbeat_device = {
+	.name		= "heartbeat",
+	.id		= -1,
+	.num_resources	= 1,
+	.resource	= &heartbeat_resource,
+};
+
+static struct resource smsc911x_resources[] = {
+	[0] = {
+		.name		= "smsc911x-memory",
+		.start		= 0x07ffff00,
+		.end		= 0x07ffff00 + SZ_256 - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.name		= "smsc911x-irq",
+		.start		= evt2irq(0x2c0),
+		.end		= evt2irq(0x2c0),
+		.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		= -1,
+	.num_resources	= ARRAY_SIZE(smsc911x_resources),
+	.resource	= smsc911x_resources,
+	.dev = {
+		.platform_data = &smsc911x_config,
+	},
+};
+
+static struct resource smbus_fpga_resource = {
+	.start		= 0x07fff9e0,
+	.end		= 0x07fff9e0 + SZ_32 - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device smbus_fpga_device = {
+	.name		= "i2c-sdk7786",
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= &smbus_fpga_resource,
+};
+
+static struct resource smbus_pcie_resource = {
+	.start		= 0x07fffc30,
+	.end		= 0x07fffc30 + SZ_32 - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device smbus_pcie_device = {
+	.name		= "i2c-sdk7786",
+	.id		= 1,
+	.num_resources	= 1,
+	.resource	= &smbus_pcie_resource,
+};
+
+static struct i2c_board_info __initdata sdk7786_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("max6900", 0x68),
+	},
+};
+
+static struct platform_device *sh7786_devices[] __initdata = {
+	&heartbeat_device,
+	&smsc911x_device,
+	&smbus_fpga_device,
+	&smbus_pcie_device,
+};
+
+static int sdk7786_i2c_setup(void)
+{
+	unsigned int tmp;
+
+	/*
+	 * Hand over I2C control to the FPGA.
+	 */
+	tmp = fpga_read_reg(SBCR);
+	tmp &= ~SCBR_I2CCEN;
+	tmp |= SCBR_I2CMEN;
+	fpga_write_reg(tmp, SBCR);
+
+	return i2c_register_board_info(0, sdk7786_i2c_devices,
+				       ARRAY_SIZE(sdk7786_i2c_devices));
+}
+
+static int __init sdk7786_devices_setup(void)
+{
+	int ret;
+
+	ret = platform_add_devices(sh7786_devices, ARRAY_SIZE(sh7786_devices));
+	if (unlikely(ret != 0))
+		return ret;
+
+	return sdk7786_i2c_setup();
+}
+__initcall(sdk7786_devices_setup);
+
+static int sdk7786_mode_pins(void)
+{
+	return fpga_read_reg(MODSWR);
+}
+
+static int sdk7786_clk_init(void)
+{
+	struct clk *clk;
+	int ret;
+
+	/*
+	 * Only handle the EXTAL case, anyone interfacing a crystal
+	 * resonator will need to provide their own input clock.
+	 */
+	if (test_mode_pin(MODE_PIN9))
+		return -EINVAL;
+
+	clk = clk_get(NULL, "extal");
+	if (!clk || IS_ERR(clk))
+		return PTR_ERR(clk);
+	ret = clk_set_rate(clk, 33333333);
+	clk_put(clk);
+
+	return ret;
+}
+
+static void sdk7786_restart(char *cmd)
+{
+	fpga_write_reg(0xa5a5, SRSTR);
+}
+
+/* Initialize the board */
+static void __init sdk7786_setup(char **cmdline_p)
+{
+	pr_info("Renesas Technology Europe SDK7786 support:\n");
+
+	sdk7786_fpga_init();
+
+	pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf);
+
+	machine_ops.restart = sdk7786_restart;
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_sdk7786 __initmv = {
+	.mv_name		= "SDK7786",
+	.mv_setup		= sdk7786_setup,
+	.mv_mode_pins		= sdk7786_mode_pins,
+	.mv_clk_init		= sdk7786_clk_init,
+	.mv_init_irq		= sdk7786_init_irq,
+};
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7206/io.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7206/io.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7206/io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7206/io.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,7 @@
 
 static inline void delay(void)
 {
-	ctrl_inw(0x20000000);  /* P2 ROM Area */
+	__raw_readw(0x20000000);  /* P2 ROM Area */
 }
 
 /* MS7750 requires special versions of in*, out* routines, since
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7206/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7206/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7206/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7206/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,12 +32,12 @@ static void disable_se7206_irq(unsigned
 	unsigned short msk0,msk1;
 
 	/* Set the priority in IPR to 0 */
-	val = ctrl_inw(INTC_IPR01);
+	val = __raw_readw(INTC_IPR01);
 	val &= mask;
-	ctrl_outw(val, INTC_IPR01);
+	__raw_writew(val, INTC_IPR01);
 	/* FPGA mask set */
-	msk0 = ctrl_inw(INTMSK0);
-	msk1 = ctrl_inw(INTMSK1);
+	msk0 = __raw_readw(INTMSK0);
+	msk1 = __raw_readw(INTMSK1);
 
 	switch (irq) {
 	case IRQ0_IRQ:
@@ -51,8 +51,8 @@ static void disable_se7206_irq(unsigned
 		msk1 |= 0x00ff;
 		break;
 	}
-	ctrl_outw(msk0, INTMSK0);
-	ctrl_outw(msk1, INTMSK1);
+	__raw_writew(msk0, INTMSK0);
+	__raw_writew(msk1, INTMSK1);
 }
 
 static void enable_se7206_irq(unsigned int irq)
@@ -62,13 +62,13 @@ static void enable_se7206_irq(unsigned i
 	unsigned short msk0,msk1;
 
 	/* Set priority in IPR back to original value */
-	val = ctrl_inw(INTC_IPR01);
+	val = __raw_readw(INTC_IPR01);
 	val |= value;
-	ctrl_outw(val, INTC_IPR01);
+	__raw_writew(val, INTC_IPR01);
 
 	/* FPGA mask reset */
-	msk0 = ctrl_inw(INTMSK0);
-	msk1 = ctrl_inw(INTMSK1);
+	msk0 = __raw_readw(INTMSK0);
+	msk1 = __raw_readw(INTMSK1);
 
 	switch (irq) {
 	case IRQ0_IRQ:
@@ -82,19 +82,20 @@ static void enable_se7206_irq(unsigned i
 		msk1 &= ~0x00ff;
 		break;
 	}
-	ctrl_outw(msk0, INTMSK0);
-	ctrl_outw(msk1, INTMSK1);
+	__raw_writew(msk0, INTMSK0);
+	__raw_writew(msk1, INTMSK1);
 }
 
 static void eoi_se7206_irq(unsigned int irq)
 {
 	unsigned short sts0,sts1;
+	struct irq_desc *desc = irq_to_desc(irq);
 
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
 		enable_se7206_irq(irq);
 	/* FPGA isr clear */
-	sts0 = ctrl_inw(INTSTS0);
-	sts1 = ctrl_inw(INTSTS1);
+	sts0 = __raw_readw(INTSTS0);
+	sts1 = __raw_readw(INTSTS1);
 
 	switch (irq) {
 	case IRQ0_IRQ:
@@ -108,8 +109,8 @@ static void eoi_se7206_irq(unsigned int
 		sts1 &= ~0x00ff;
 		break;
 	}
-	ctrl_outw(sts0, INTSTS0);
-	ctrl_outw(sts1, INTSTS1);
+	__raw_writew(sts0, INTSTS0);
+	__raw_writew(sts1, INTSTS1);
 }
 
 static struct irq_chip se7206_irq_chip __read_mostly = {
@@ -136,11 +137,11 @@ void __init init_se7206_IRQ(void)
 	make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */
 	make_se7206_irq(IRQ1_IRQ); /* ATA */
 	make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */
-	ctrl_outw(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */
+	__raw_writew(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */
 
 	/* FPGA System register setup*/
-	ctrl_outw(0x0000,INTSTS0); /* Clear INTSTS0 */
-	ctrl_outw(0x0000,INTSTS1); /* Clear INTSTS1 */
+	__raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */
+	__raw_writew(0x0000,INTSTS1); /* Clear INTSTS1 */
 	/* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */
-	ctrl_outw(0x0001,INTSEL);
+	__raw_writew(0x0001,INTSEL);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7206/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7206/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7206/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7206/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,15 +50,12 @@ static unsigned char heartbeat_bit_pos[]
 static struct heartbeat_data heartbeat_data = {
 	.bit_pos	= heartbeat_bit_pos,
 	.nr_bits	= ARRAY_SIZE(heartbeat_bit_pos),
-	.regsize	= 32,
 };
 
-static struct resource heartbeat_resources[] = {
-	[0] = {
-		.start	= PA_LED,
-		.end	= PA_LED,
-		.flags	= IORESOURCE_MEM,
-	},
+static struct resource heartbeat_resource = {
+	.start	= PA_LED,
+	.end	= PA_LED,
+	.flags	= IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
 };
 
 static struct platform_device heartbeat_device = {
@@ -67,8 +64,8 @@ static struct platform_device heartbeat_
 	.dev	= {
 		.platform_data	= &heartbeat_data,
 	},
-	.num_resources	= ARRAY_SIZE(heartbeat_resources),
-	.resource	= heartbeat_resources,
+	.num_resources	= 1,
+	.resource	= &heartbeat_resource,
 };
 
 static struct platform_device *se7206_devices[] __initdata = {
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7343/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7343/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7343/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7343/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,16 +16,18 @@
 #include <linux/io.h>
 #include <mach-se/mach/se7343.h>
 
+unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, };
+
 static void disable_se7343_irq(unsigned int irq)
 {
-	unsigned int bit = irq - SE7343_FPGA_IRQ_BASE;
-	ctrl_outw(ctrl_inw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK);
+	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+	__raw_writew(__raw_readw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK);
 }
 
 static void enable_se7343_irq(unsigned int irq)
 {
-	unsigned int bit = irq - SE7343_FPGA_IRQ_BASE;
-	ctrl_outw(ctrl_inw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK);
+	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
+	__raw_writew(__raw_readw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK);
 }
 
 static struct irq_chip se7343_irq_chip __read_mostly = {
@@ -37,19 +39,16 @@ static struct irq_chip se7343_irq_chip _
 
 static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
-	unsigned short intv = ctrl_inw(PA_CPLD_ST);
-	struct irq_desc *ext_desc;
-	unsigned int ext_irq = SE7343_FPGA_IRQ_BASE;
+	unsigned short intv = __raw_readw(PA_CPLD_ST);
+	unsigned int ext_irq = 0;
 
 	intv &= (1 << SE7343_FPGA_IRQ_NR) - 1;
 
-	while (intv) {
-		if (intv & 1) {
-			ext_desc = irq_desc + ext_irq;
-			handle_level_irq(ext_irq, ext_desc);
-		}
-		intv >>= 1;
-		ext_irq++;
+	for (; intv; intv >>= 1, ext_irq++) {
+		if (!(intv & 1))
+			continue;
+
+		generic_handle_irq(se7343_fpga_irq[ext_irq]);
 	}
 }
 
@@ -58,16 +57,24 @@ static void se7343_irq_demux(unsigned in
  */
 void __init init_7343se_IRQ(void)
 {
-	int i;
+	int i, irq;
 
-	ctrl_outw(0, PA_CPLD_IMSK);	/* disable all irqs */
-	ctrl_outw(0x2000, 0xb03fffec);	/* mrshpc irq enable */
+	__raw_writew(0, PA_CPLD_IMSK);	/* disable all irqs */
+	__raw_writew(0x2000, 0xb03fffec);	/* mrshpc irq enable */
 
-	for (i = 0; i < SE7343_FPGA_IRQ_NR; i++)
-		set_irq_chip_and_handler_name(SE7343_FPGA_IRQ_BASE + i,
+	for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) {
+		irq = create_irq();
+		if (irq < 0)
+			return;
+		se7343_fpga_irq[i] = irq;
+
+		set_irq_chip_and_handler_name(se7343_fpga_irq[i],
 					      &se7343_irq_chip,
 					      handle_level_irq, "level");
 
+		set_irq_chip_data(se7343_fpga_irq[i], (void *)i);
+	}
+
 	set_irq_chained_handler(IRQ0_IRQ, se7343_irq_demux);
 	set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
 	set_irq_chained_handler(IRQ1_IRQ, se7343_irq_demux);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7343/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7343/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7343/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7343/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,26 +11,17 @@
 #include <asm/irq.h>
 #include <asm/io.h>
 
-static struct resource heartbeat_resources[] = {
-	[0] = {
-		.start	= PA_LED,
-		.end	= PA_LED,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct heartbeat_data heartbeat_data = {
-	.regsize = 16,
+static struct resource heartbeat_resource = {
+	.start	= PA_LED,
+	.end	= PA_LED,
+	.flags	= IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
 };
 
 static struct platform_device heartbeat_device = {
 	.name		= "heartbeat",
 	.id		= -1,
-	.dev = {
-		.platform_data = &heartbeat_data,
-	},
-	.num_resources	= ARRAY_SIZE(heartbeat_resources),
-	.resource	= heartbeat_resources,
+	.num_resources	= 1,
+	.resource	= &heartbeat_resource,
 };
 
 static struct mtd_partition nor_flash_partitions[] = {
@@ -82,7 +73,6 @@ static struct plat_serial8250_port seria
 		.mapbase	= 0x16000000,
 		.regshift	= 1,
 		.flags		= ST16C2550C_FLAGS,
-		.irq		= UARTA_IRQ,
 		.uartclk	= 7372800,
 	},
 	[1] = {
@@ -90,7 +80,6 @@ static struct plat_serial8250_port seria
 		.mapbase	= 0x17000000,
 		.regshift	= 1,
 		.flags		= ST16C2550C_FLAGS,
-		.irq		= UARTB_IRQ,
 		.uartclk	= 7372800,
 	},
 	{ },
@@ -121,7 +110,7 @@ static struct resource usb_resources[] =
 		.flags  = IORESOURCE_MEM,
 	},
 	[2] = {
-		.start  = USB_IRQ,
+		/* Filled in later */
 		.flags  = IORESOURCE_IRQ,
 	},
 };
@@ -138,8 +127,8 @@ static struct isp116x_platform_data usb_
 static struct platform_device usb_device = {
 	.name			= "isp116x-hcd",
 	.id			= -1,
-	.num_resources  	= ARRAY_SIZE(usb_resources),
-	.resource       	= usb_resources,
+	.num_resources		= ARRAY_SIZE(usb_resources),
+	.resource		= usb_resources,
 	.dev			= {
 		.platform_data	= &usb_platform_data,
 	},
@@ -155,6 +144,13 @@ static struct platform_device *sh7343se_
 
 static int __init sh7343se_devices_setup(void)
 {
+	/* Wire-up dynamic vectors */
+	serial_platform_data[0].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTA];
+	serial_platform_data[1].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTB];
+
+	usb_resources[2].start = usb_resources[2].end =
+		se7343_fpga_irq[SE7343_FPGA_IRQ_USB];
+
 	return platform_add_devices(sh7343se_platform_devices,
 				    ARRAY_SIZE(sh7343se_platform_devices));
 }
@@ -165,10 +161,10 @@ device_initcall(sh7343se_devices_setup);
  */
 static void __init sh7343se_setup(char **cmdline_p)
 {
-	ctrl_outw(0xf900, FPGA_OUT);	/* FPGA */
+	__raw_writew(0xf900, FPGA_OUT);	/* FPGA */
 
-	ctrl_outw(0x0002, PORT_PECR);	/* PORT E 1 = IRQ5 */
-	ctrl_outw(0x0020, PORT_PSELD);
+	__raw_writew(0x0002, PORT_PECR);	/* PORT E 1 = IRQ5 */
+	__raw_writew(0x0020, PORT_PSELD);
 
 	printk(KERN_INFO "MS7343CP01 Setup...done\n");
 }
@@ -179,6 +175,5 @@ static void __init sh7343se_setup(char *
 static struct sh_machine_vector mv_7343se __initmv = {
 	.mv_name = "SolutionEngine 7343",
 	.mv_setup = sh7343se_setup,
-	.mv_nr_irqs = SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_NR,
 	.mv_init_irq = init_7343se_IRQ,
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/770x/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/770x/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/770x/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/770x/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -96,13 +96,13 @@ static struct ipr_desc ipr_irq_desc = {
 void __init init_se_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);
+	__raw_writew(0, BCR_ILCRA);
+	__raw_writew(0, BCR_ILCRB);
+	__raw_writew(0, BCR_ILCRC);
+	__raw_writew(0, BCR_ILCRD);
+	__raw_writew(0, BCR_ILCRE);
+	__raw_writew(0, BCR_ILCRF);
+	__raw_writew(0, BCR_ILCRG);
 
 	register_ipr_controller(&ipr_irq_desc);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/770x/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/770x/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/770x/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/770x/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -93,15 +93,12 @@ static unsigned char heartbeat_bit_pos[]
 static struct heartbeat_data heartbeat_data = {
 	.bit_pos	= heartbeat_bit_pos,
 	.nr_bits	= ARRAY_SIZE(heartbeat_bit_pos),
-	.regsize	= 16,
 };
 
-static struct resource heartbeat_resources[] = {
-	[0] = {
-		.start	= PA_LED,
-		.end	= PA_LED,
-		.flags	= IORESOURCE_MEM,
-	},
+static struct resource heartbeat_resource = {
+	.start	= PA_LED,
+	.end	= PA_LED,
+	.flags	= IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
 };
 
 static struct platform_device heartbeat_device = {
@@ -110,8 +107,8 @@ static struct platform_device heartbeat_
 	.dev	= {
 		.platform_data	= &heartbeat_data,
 	},
-	.num_resources	= ARRAY_SIZE(heartbeat_resources),
-	.resource	= heartbeat_resources,
+	.num_resources	= 1,
+	.resource	= &heartbeat_resource,
 };
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7710) ||\
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7721/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7721/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7721/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7721/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,7 +38,7 @@ static DECLARE_INTC_DESC(intc_desc, "SE7
 void __init init_se7721_IRQ(void)
 {
 	/* PPCR */
-	ctrl_outw(ctrl_inw(0xa4050118) & ~0x00ff, 0xa4050118);
+	__raw_writew(__raw_readw(0xa4050118) & ~0x00ff, 0xa4050118);
 
 	register_intc_controller(&intc_desc);
 	intc_set_priority(MRSHPC_IRQ0, 0xf - MRSHPC_IRQ0);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7721/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7721/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7721/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7721/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,15 +23,12 @@ static unsigned char heartbeat_bit_pos[]
 static struct heartbeat_data heartbeat_data = {
 	.bit_pos	= heartbeat_bit_pos,
 	.nr_bits	= ARRAY_SIZE(heartbeat_bit_pos),
-	.regsize	= 16,
 };
 
-static struct resource heartbeat_resources[] = {
-	[0] = {
-		.start	= PA_LED,
-		.end	= PA_LED,
-		.flags	= IORESOURCE_MEM,
-	},
+static struct resource heartbeat_resource = {
+	.start	= PA_LED,
+	.end	= PA_LED,
+	.flags	= IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
 };
 
 static struct platform_device heartbeat_device = {
@@ -40,8 +37,8 @@ static struct platform_device heartbeat_
 	.dev	= {
 		.platform_data	= &heartbeat_data,
 	},
-	.num_resources	= ARRAY_SIZE(heartbeat_resources),
-	.resource	= heartbeat_resources,
+	.num_resources	= 1,
+	.resource	= &heartbeat_resource,
 };
 
 static struct resource cf_ide_resources[] = {
@@ -83,10 +80,10 @@ device_initcall(se7721_devices_setup);
 static void __init se7721_setup(char **cmdline_p)
 {
 	/* for USB */
-	ctrl_outw(0x0000, 0xA405010C);	/* PGCR */
-	ctrl_outw(0x0000, 0xA405010E);	/* PHCR */
-	ctrl_outw(0x00AA, 0xA4050118);	/* PPCR */
-	ctrl_outw(0x0000, 0xA4050124);	/* PSELA */
+	__raw_writew(0x0000, 0xA405010C);	/* PGCR */
+	__raw_writew(0x0000, 0xA405010E);	/* PHCR */
+	__raw_writew(0x00AA, 0xA4050118);	/* PPCR */
+	__raw_writew(0x0000, 0xA4050124);	/* PSELA */
 }
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7722/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7722/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7722/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7722/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,13 +21,13 @@ unsigned int se7722_fpga_irq[SE7722_FPGA
 static void disable_se7722_irq(unsigned int irq)
 {
 	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
-	ctrl_outw(ctrl_inw(IRQ01_MASK) | 1 << bit, IRQ01_MASK);
+	__raw_writew(__raw_readw(IRQ01_MASK) | 1 << bit, IRQ01_MASK);
 }
 
 static void enable_se7722_irq(unsigned int irq)
 {
 	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
-	ctrl_outw(ctrl_inw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK);
+	__raw_writew(__raw_readw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK);
 }
 
 static struct irq_chip se7722_irq_chip __read_mostly = {
@@ -39,7 +39,7 @@ static struct irq_chip se7722_irq_chip _
 
 static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
-	unsigned short intv = ctrl_inw(IRQ01_STS);
+	unsigned short intv = __raw_readw(IRQ01_STS);
 	unsigned int ext_irq = 0;
 
 	intv &= (1 << SE7722_FPGA_IRQ_NR) - 1;
@@ -59,8 +59,8 @@ void __init init_se7722_IRQ(void)
 {
 	int i, irq;
 
-	ctrl_outw(0, IRQ01_MASK);       /* disable all irqs */
-	ctrl_outw(0x2000, 0xb03fffec);  /* mrshpc irq enable */
+	__raw_writew(0, IRQ01_MASK);       /* disable all irqs */
+	__raw_writew(0x2000, 0xb03fffec);  /* mrshpc irq enable */
 
 	for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) {
 		irq = create_irq();
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7722/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7722/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7722/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7722/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,26 +25,17 @@
 #include <cpu/sh7722.h>
 
 /* Heartbeat */
-static struct heartbeat_data heartbeat_data = {
-	.regsize = 16,
-};
-
-static struct resource heartbeat_resources[] = {
-	[0] = {
-		.start  = PA_LED,
-		.end    = PA_LED,
-		.flags  = IORESOURCE_MEM,
-	},
+static struct resource heartbeat_resource = {
+	.start  = PA_LED,
+	.end    = PA_LED,
+	.flags  = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
 };
 
 static struct platform_device heartbeat_device = {
 	.name           = "heartbeat",
 	.id             = -1,
-	.dev = {
-		.platform_data = &heartbeat_data,
-	},
-	.num_resources  = ARRAY_SIZE(heartbeat_resources),
-	.resource       = heartbeat_resources,
+	.num_resources  = 1,
+	.resource       = &heartbeat_resource,
 };
 
 /* SMC91x */
@@ -165,32 +156,32 @@ device_initcall(se7722_devices_setup);
 
 static void __init se7722_setup(char **cmdline_p)
 {
-	ctrl_outw(0x010D, FPGA_OUT);    /* FPGA */
+	__raw_writew(0x010D, FPGA_OUT);    /* FPGA */
 
-	ctrl_outw(0x0000, PORT_PECR);   /* PORT E 1 = IRQ5 ,E 0 = BS */
-	ctrl_outw(0x1000, PORT_PJCR);   /* PORT J 1 = IRQ1,J 0 =IRQ0 */
+	__raw_writew(0x0000, PORT_PECR);   /* PORT E 1 = IRQ5 ,E 0 = BS */
+	__raw_writew(0x1000, PORT_PJCR);   /* PORT J 1 = IRQ1,J 0 =IRQ0 */
 
 	/* LCDC I/O */
-	ctrl_outw(0x0020, PORT_PSELD);
+	__raw_writew(0x0020, PORT_PSELD);
 
 	/* SIOF1*/
-	ctrl_outw(0x0003, PORT_PSELB);
-	ctrl_outw(0xe000, PORT_PSELC);
-	ctrl_outw(0x0000, PORT_PKCR);
+	__raw_writew(0x0003, PORT_PSELB);
+	__raw_writew(0xe000, PORT_PSELC);
+	__raw_writew(0x0000, PORT_PKCR);
 
 	/* LCDC */
-	ctrl_outw(0x4020, PORT_PHCR);
-	ctrl_outw(0x0000, PORT_PLCR);
-	ctrl_outw(0x0000, PORT_PMCR);
-	ctrl_outw(0x0002, PORT_PRCR);
-	ctrl_outw(0x0000, PORT_PXCR);   /* LCDC,CS6A */
+	__raw_writew(0x4020, PORT_PHCR);
+	__raw_writew(0x0000, PORT_PLCR);
+	__raw_writew(0x0000, PORT_PMCR);
+	__raw_writew(0x0002, PORT_PRCR);
+	__raw_writew(0x0000, PORT_PXCR);   /* LCDC,CS6A */
 
 	/* KEYSC */
-	ctrl_outw(0x0A10, PORT_PSELA); /* BS,SHHID2 */
-	ctrl_outw(0x0000, PORT_PYCR);
-	ctrl_outw(0x0000, PORT_PZCR);
-	ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x4000, PORT_HIZCRA);
-	ctrl_outw(ctrl_inw(PORT_HIZCRC) & ~0xc000, PORT_HIZCRC);
+	__raw_writew(0x0A10, PORT_PSELA); /* BS,SHHID2 */
+	__raw_writew(0x0000, PORT_PYCR);
+	__raw_writew(0x0000, PORT_PZCR);
+	__raw_writew(__raw_readw(PORT_HIZCRA) & ~0x4000, PORT_HIZCRA);
+	__raw_writew(__raw_readw(PORT_HIZCRC) & ~0xc000, PORT_HIZCRC);
 }
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7724/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7724/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7724/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7724/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -72,14 +72,14 @@ static void disable_se7724_irq(unsigned
 {
 	struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
 	unsigned int bit = irq - set.base;
-	ctrl_outw(ctrl_inw(set.mraddr) | 0x0001 << bit, set.mraddr);
+	__raw_writew(__raw_readw(set.mraddr) | 0x0001 << bit, set.mraddr);
 }
 
 static void enable_se7724_irq(unsigned int irq)
 {
 	struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
 	unsigned int bit = irq - set.base;
-	ctrl_outw(ctrl_inw(set.mraddr) & ~(0x0001 << bit), set.mraddr);
+	__raw_writew(__raw_readw(set.mraddr) & ~(0x0001 << bit), set.mraddr);
 }
 
 static struct irq_chip se7724_irq_chip __read_mostly = {
@@ -92,19 +92,16 @@ static struct irq_chip se7724_irq_chip _
 static void se7724_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
 	struct fpga_irq set = get_fpga_irq(irq);
-	unsigned short intv = ctrl_inw(set.sraddr);
-	struct irq_desc *ext_desc;
+	unsigned short intv = __raw_readw(set.sraddr);
 	unsigned int ext_irq = set.base;
 
 	intv &= set.mask;
 
-	while (intv) {
-		if (intv & 0x0001) {
-			ext_desc = irq_desc + ext_irq;
-			handle_level_irq(ext_irq, ext_desc);
-		}
-		intv >>= 1;
-		ext_irq++;
+	for (; intv; intv >>= 1, ext_irq++) {
+		if (!(intv & 1))
+			continue;
+
+		generic_handle_irq(ext_irq);
 	}
 }
 
@@ -113,20 +110,39 @@ static void se7724_irq_demux(unsigned in
  */
 void __init init_se7724_IRQ(void)
 {
-	int i;
+	int i, nid = cpu_to_node(boot_cpu_data);
 
-	ctrl_outw(0xffff, IRQ0_MR);  /* mask all */
-	ctrl_outw(0xffff, IRQ1_MR);  /* mask all */
-	ctrl_outw(0xffff, IRQ2_MR);  /* mask all */
-	ctrl_outw(0x0000, IRQ0_SR);  /* clear irq */
-	ctrl_outw(0x0000, IRQ1_SR);  /* clear irq */
-	ctrl_outw(0x0000, IRQ2_SR);  /* clear irq */
-	ctrl_outw(0x002a, IRQ_MODE); /* set irq type */
+	__raw_writew(0xffff, IRQ0_MR);  /* mask all */
+	__raw_writew(0xffff, IRQ1_MR);  /* mask all */
+	__raw_writew(0xffff, IRQ2_MR);  /* mask all */
+	__raw_writew(0x0000, IRQ0_SR);  /* clear irq */
+	__raw_writew(0x0000, IRQ1_SR);  /* clear irq */
+	__raw_writew(0x0000, IRQ2_SR);  /* clear irq */
+	__raw_writew(0x002a, IRQ_MODE); /* set irq type */
 
-	for (i = 0; i < SE7724_FPGA_IRQ_NR; i++)
-		set_irq_chip_and_handler_name(SE7724_FPGA_IRQ_BASE + i,
+	for (i = 0; i < SE7724_FPGA_IRQ_NR; i++) {
+		int irq, wanted;
+
+		wanted = SE7724_FPGA_IRQ_BASE + i;
+
+		irq = create_irq_nr(wanted, nid);
+		if (unlikely(irq == 0)) {
+			pr_err("%s: failed hooking irq %d for FPGA\n",
+			       __func__, wanted);
+			return;
+		}
+
+		if (unlikely(irq != wanted)) {
+			pr_err("%s: got irq %d but wanted %d, bailing.\n",
+			       __func__, irq, wanted);
+			destroy_irq(irq);
+			return;
+		}
+
+		set_irq_chip_and_handler_name(irq,
 					      &se7724_irq_chip,
 					      handle_level_irq, "level");
+	}
 
 	set_irq_chained_handler(IRQ0_IRQ, se7724_irq_demux);
 	set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7724/sdram.S linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7724/sdram.S
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7724/sdram.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7724/sdram.S	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,10 @@ ENTRY(ms7724se_sdram_leave_start)
 
 	/* DBSC: put memory in auto-refresh mode */
 
+	mov.l	@(SH_SLEEP_MODE, r5), r0
+	tst	#SUSP_SH_RSTANDBY, r0
+	bf	resume_rstandby
+
 	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
 	WAIT 1
 	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
@@ -49,4 +53,79 @@ ENTRY(ms7724se_sdram_leave_start)
 	rts
 	 nop
 
+resume_rstandby:
+
+	/* CPG: setup clocks before restarting external memory */
+
+	ED 0xA4150024, 0x00004000 /* PLLCR */
+
+	mov.l	FRQCRA,r0
+	mov.l	@r0,r3
+	mov.l	KICK,r1
+	or	r1, r3
+	mov.l	r3, @r0
+
+	mov.l	LSTATS,r0
+	mov	#1,r1
+WAIT_LSTATS:
+	mov.l	@r0,r3
+	tst	r1,r3
+	bf	WAIT_LSTATS
+
+	/* DBSC: re-initialize and put in auto-refresh */
+
+	ED 0xFD000108, 0x00000181 /* DBPDCNT0 */
+	ED 0xFD000020, 0x015B0002 /* DBCONF */
+	ED 0xFD000030, 0x03071502 /* DBTR0 */
+	ED 0xFD000034, 0x02020102 /* DBTR1 */
+	ED 0xFD000038, 0x01090405 /* DBTR2 */
+	ED 0xFD00003C, 0x00000002 /* DBTR3 */
+	ED 0xFD000008, 0x00000005 /* DBKIND */
+	ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	ED 0xFD000018, 0x00000001 /* DBCKECNT */
+
+	mov	#100,r0
+WAIT_400NS:
+	dt	r0
+	bf	WAIT_400NS
+
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000060, 0x00020000 /* DBMRCNT (EMR2) */
+	ED 0xFD000060, 0x00030000 /* DBMRCNT (EMR3) */
+	ED 0xFD000060, 0x00010004 /* DBMRCNT (EMR) */
+	ED 0xFD000060, 0x00000532 /* DBMRCNT (MRS) */
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000060, 0x00000432 /* DBMRCNT (MRS) */
+	ED 0xFD000060, 0x000103c0 /* DBMRCNT (EMR) */
+	ED 0xFD000060, 0x00010040 /* DBMRCNT (EMR) */
+
+	mov	#100,r0
+WAIT_400NS_2:
+	dt	r0
+	bf	WAIT_400NS_2
+
+	ED 0xFD000010, 0x00000001 /* DBEN */
+	ED 0xFD000044, 0x0000050f /* DBRFPDN1 */
+	ED 0xFD000048, 0x236800e6 /* DBRFPDN2 */
+
+	mov.l	DUMMY,r0
+	mov.l	@r0, r1 /* force single dummy read */
+
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000108, 0x00000080 /* DBPDCNT0 */
+	ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+	.balign 4
+DUMMY:	.long	0xac400000
+FRQCRA:	.long	0xa4150000
+KICK:	.long	0x80000000
+LSTATS:	.long	0xa4150060
+
 ENTRY(ms7724se_sdram_leave_end)
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7724/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7724/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7724/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7724/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,27 +52,25 @@
  * and change SW41 to use 720p
  */
 
-/* Heartbeat */
-static struct heartbeat_data heartbeat_data = {
-	.regsize = 16,
-};
+/*
+ * about sound
+ *
+ * This setup.c supports FSI slave mode.
+ * Please change J20, J21, J22 pin to 1-2 connection.
+ */
 
-static struct resource heartbeat_resources[] = {
-	[0] = {
-		.start  = PA_LED,
-		.end    = PA_LED,
-		.flags  = IORESOURCE_MEM,
-	},
+/* Heartbeat */
+static struct resource heartbeat_resource = {
+	.start  = PA_LED,
+	.end    = PA_LED,
+	.flags  = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
 };
 
 static struct platform_device heartbeat_device = {
 	.name           = "heartbeat",
 	.id             = -1,
-	.dev = {
-		.platform_data = &heartbeat_data,
-	},
-	.num_resources  = ARRAY_SIZE(heartbeat_resources),
-	.resource       = heartbeat_resources,
+	.num_resources  = 1,
+	.resource       = &heartbeat_resource,
 };
 
 /* LAN91C111 */
@@ -265,12 +263,12 @@ static struct platform_device ceu1_devic
 #define FCLKACR		0xa4150008
 static void fsimck_init(struct clk *clk)
 {
-	u32 status = ctrl_inl(clk->enable_reg);
+	u32 status = __raw_readl(clk->enable_reg);
 
 	/* use external clock */
 	status &= ~0x000000ff;
 	status |= 0x00000080;
-	ctrl_outl(status, clk->enable_reg);
+	__raw_writel(status, clk->enable_reg);
 }
 
 static struct clk_ops fsimck_clk_ops = {
@@ -285,6 +283,7 @@ static struct clk fsimcka_clk = {
 	.rate		= 0, /* unknown */
 };
 
+/* change J20, J21, J22 pin to 1-2 connection to use slave mode */
 struct sh_fsi_platform_info fsi_info = {
 	.porta_flags = SH_FSI_BRS_INV |
 		       SH_FSI_OUT_SLAVE_MODE |
@@ -322,7 +321,7 @@ static struct platform_device fsi_device
 /* KEYSC in SoC (Needs SW33-2 set to ON) */
 static struct sh_keysc_info keysc_info = {
 	.mode = SH_KEYSC_MODE_1,
-	.scan_timing = 10,
+	.scan_timing = 3,
 	.delay = 50,
 	.keycodes = {
 		KEY_1, KEY_2, KEY_3, KEY_4, KEY_5,
@@ -460,7 +459,7 @@ static struct resource sdhi0_cn7_resourc
 		.flags  = IORESOURCE_MEM,
 	},
 	[1] = {
-		.start  = 101,
+		.start  = 100,
 		.flags  = IORESOURCE_IRQ,
 	},
 };
@@ -483,7 +482,7 @@ static struct resource sdhi1_cn8_resourc
 		.flags  = IORESOURCE_MEM,
 	},
 	[1] = {
-		.start  = 24,
+		.start  = 23,
 		.flags  = IORESOURCE_IRQ,
 	},
 };
@@ -498,6 +497,26 @@ static struct platform_device sdhi1_cn8_
 	},
 };
 
+/* IrDA */
+static struct resource irda_resources[] = {
+	[0] = {
+		.name	= "IrDA",
+		.start  = 0xA45D0000,
+		.end    = 0xA45D0049,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 20,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device irda_device = {
+	.name           = "sh_sir",
+	.num_resources  = ARRAY_SIZE(irda_resources),
+	.resource       = irda_resources,
+};
+
 static struct platform_device *ms7724se_devices[] __initdata = {
 	&heartbeat_device,
 	&smc91x_eth_device,
@@ -512,6 +531,7 @@ static struct platform_device *ms7724se_
 	&fsi_device,
 	&sdhi0_cn7_device,
 	&sdhi1_cn8_device,
+	&irda_device,
 };
 
 /* I2C device */
@@ -531,7 +551,7 @@ static int __init sh_eth_is_eeprom_ready
 	int t = 10000;
 
 	while (t--) {
-		if (!ctrl_inw(EEPROM_STAT))
+		if (!__raw_readw(EEPROM_STAT))
 			return 1;
 		udelay(1);
 	}
@@ -551,13 +571,13 @@ static void __init sh_eth_init(void)
 
 	/* read MAC addr from EEPROM */
 	for (i = 0 ; i < 3 ; i++) {
-		ctrl_outw(0x0, EEPROM_OP); /* read */
-		ctrl_outw(i*2, EEPROM_ADR);
-		ctrl_outw(0x1, EEPROM_STRT);
+		__raw_writew(0x0, EEPROM_OP); /* read */
+		__raw_writew(i*2, EEPROM_ADR);
+		__raw_writew(0x1, EEPROM_STRT);
 		if (!sh_eth_is_eeprom_ready())
 			return;
 
-		mac = ctrl_inw(EEPROM_DATA);
+		mac = __raw_readw(EEPROM_DATA);
 		sh_eth_plat.mac_addr[i << 1] = mac & 0xff;
 		sh_eth_plat.mac_addr[(i << 1) + 1] = mac >> 8;
 	}
@@ -594,28 +614,29 @@ arch_initcall(arch_setup);
 
 static int __init devices_setup(void)
 {
-	u16 sw = ctrl_inw(SW4140); /* select camera, monitor */
-	struct clk *fsia_clk;
+	u16 sw = __raw_readw(SW4140); /* select camera, monitor */
+	struct clk *clk;
 
 	/* register board specific self-refresh code */
-	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
+	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF |
+					SUSP_SH_RSTANDBY,
 					&ms7724se_sdram_enter_start,
 					&ms7724se_sdram_enter_end,
 					&ms7724se_sdram_leave_start,
 					&ms7724se_sdram_leave_end);
 	/* Reset Release */
-	ctrl_outw(ctrl_inw(FPGA_OUT) &
+	__raw_writew(__raw_readw(FPGA_OUT) &
 		  ~((1 << 1)  | /* LAN */
 		    (1 << 6)  | /* VIDEO DAC */
 		    (1 << 7)  | /* AK4643 */
+		    (1 << 8)  | /* IrDA */
 		    (1 << 12) | /* USB0 */
 		    (1 << 14)), /* RMII */
 		  FPGA_OUT);
 
 	/* turn on USB clocks, use external clock */
-	ctrl_outw((ctrl_inw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
+	__raw_writew((__raw_readw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
 
-#ifdef CONFIG_PM
 	/* Let LED9 show STATUS2 */
 	gpio_request(GPIO_FN_STATUS2, NULL);
 
@@ -624,28 +645,12 @@ static int __init devices_setup(void)
 
 	/* Lit LED11 show PDSTATUS */
 	gpio_request(GPIO_FN_PDSTATUS, NULL);
-#else
-	/* Lit LED9 */
-	gpio_request(GPIO_PTJ6, NULL);
-	gpio_direction_output(GPIO_PTJ6, 1);
-	gpio_export(GPIO_PTJ6, 0);
-
-	/* Lit LED10 */
-	gpio_request(GPIO_PTJ5, NULL);
-	gpio_direction_output(GPIO_PTJ5, 1);
-	gpio_export(GPIO_PTJ5, 0);
-
-	/* Lit LED11 */
-	gpio_request(GPIO_PTJ7, NULL);
-	gpio_direction_output(GPIO_PTJ7, 1);
-	gpio_export(GPIO_PTJ7, 0);
-#endif
 
 	/* enable USB0 port */
-	ctrl_outw(0x0600, 0xa40501d4);
+	__raw_writew(0x0600, 0xa40501d4);
 
 	/* enable USB1 port */
-	ctrl_outw(0x0600, 0xa4050192);
+	__raw_writew(0x0600, 0xa4050192);
 
 	/* enable IRQ 0,1,2 */
 	gpio_request(GPIO_FN_INTC_IRQ0, NULL);
@@ -693,7 +698,7 @@ static int __init devices_setup(void)
 	gpio_request(GPIO_FN_LCDVCPWC, NULL);
 	gpio_request(GPIO_FN_LCDRD,    NULL);
 	gpio_request(GPIO_FN_LCDLCLK,  NULL);
-	ctrl_outw((ctrl_inw(PORT_HIZA) & ~0x0001), PORT_HIZA);
+	__raw_writew((__raw_readw(PORT_HIZA) & ~0x0001), PORT_HIZA);
 
 	/* enable CEU0 */
 	gpio_request(GPIO_FN_VIO0_D15, NULL);
@@ -764,13 +769,18 @@ static int __init devices_setup(void)
 	gpio_request(GPIO_FN_CLKAUDIOBO, NULL);
 	gpio_request(GPIO_FN_FSIIASD,    NULL);
 
+	/* set SPU2 clock to 83.4 MHz */
+	clk = clk_get(NULL, "spu_clk");
+	clk_set_rate(clk, clk_round_rate(clk, 83333333));
+	clk_put(clk);
+
 	/* change parent of FSI A */
-	fsia_clk = clk_get(NULL, "fsia_clk");
+	clk = clk_get(NULL, "fsia_clk");
 	clk_register(&fsimcka_clk);
-	clk_set_parent(fsia_clk, &fsimcka_clk);
-	clk_set_rate(fsia_clk, 11000);
+	clk_set_parent(clk, &fsimcka_clk);
+	clk_set_rate(clk, 11000);
 	clk_set_rate(&fsimcka_clk, 11000);
-	clk_put(fsia_clk);
+	clk_put(clk);
 
 	/* SDHI0 connected to cn7 */
 	gpio_request(GPIO_FN_SDHI0CD, NULL);
@@ -792,6 +802,10 @@ static int __init devices_setup(void)
 	gpio_request(GPIO_FN_SDHI1CMD, NULL);
 	gpio_request(GPIO_FN_SDHI1CLK, NULL);
 
+	/* enable IrDA */
+	gpio_request(GPIO_FN_IRDA_OUT, NULL);
+	gpio_request(GPIO_FN_IRDA_IN,  NULL);
+
 	/*
 	 * enable SH-Eth
 	 *
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7780/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7780/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7780/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7780/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,30 +24,30 @@
 void __init init_se7780_IRQ(void)
 {
 	/* enable all interrupt at FPGA */
-	ctrl_outw(0, FPGA_INTMSK1);
+	__raw_writew(0, FPGA_INTMSK1);
 	/* mask SM501 interrupt */
-	ctrl_outw((ctrl_inw(FPGA_INTMSK1) | 0x0002), FPGA_INTMSK1);
+	__raw_writew((__raw_readw(FPGA_INTMSK1) | 0x0002), FPGA_INTMSK1);
 	/* enable all interrupt at FPGA */
-	ctrl_outw(0, FPGA_INTMSK2);
+	__raw_writew(0, FPGA_INTMSK2);
 
 	/* set FPGA INTSEL register */
 	/* FPGA + 0x06 */
-	ctrl_outw( ((IRQPIN_SM501 << IRQPOS_SM501) |
+	__raw_writew( ((IRQPIN_SM501 << IRQPOS_SM501) |
 		(IRQPIN_SMC91CX << IRQPOS_SMC91CX)), FPGA_INTSEL1);
 
 	/* FPGA + 0x08 */
-	ctrl_outw(((IRQPIN_EXTINT4 << IRQPOS_EXTINT4) |
+	__raw_writew(((IRQPIN_EXTINT4 << IRQPOS_EXTINT4) |
 		(IRQPIN_EXTINT3 << IRQPOS_EXTINT3) |
 		(IRQPIN_EXTINT2 << IRQPOS_EXTINT2) |
 		(IRQPIN_EXTINT1 << IRQPOS_EXTINT1)), FPGA_INTSEL2);
 
 	/* FPGA + 0x0A */
-	ctrl_outw((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3);
+	__raw_writew((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3);
 
 	plat_irq_setup_pins(IRQ_MODE_IRQ); /* install handlers for IRQ0-7 */
 
 	/* ICR1: detect low level(for 2ndcut) */
-	ctrl_outl(0xAAAA0000, INTC_ICR1);
+	__raw_writel(0xAAAA0000, INTC_ICR1);
 
 	/*
 	 * FPGA PCISEL register initialize
@@ -63,6 +63,6 @@ void __init init_se7780_IRQ(void)
 	 *  INTD || INTD  | INTC  |  --   | INTA
 	 *  -------------------------------------
 	 */
-	ctrl_outw(0x0013, FPGA_PCI_INTSEL1);
-	ctrl_outw(0xE402, FPGA_PCI_INTSEL2);
+	__raw_writew(0x0013, FPGA_PCI_INTSEL1);
+	__raw_writew(0xE402, FPGA_PCI_INTSEL2);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7780/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7780/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7780/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-se/7780/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,26 +17,17 @@
 #include <asm/heartbeat.h>
 
 /* Heartbeat */
-static struct heartbeat_data heartbeat_data = {
-	.regsize = 16,
-};
-
-static struct resource heartbeat_resources[] = {
-	[0] = {
-		.start  = PA_LED,
-		.end    = PA_LED,
-		.flags  = IORESOURCE_MEM,
-	},
+static struct resource heartbeat_resource = {
+	.start  = PA_LED,
+	.end    = PA_LED,
+	.flags  = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
 };
 
 static struct platform_device heartbeat_device = {
 	.name           = "heartbeat",
 	.id             = -1,
-	.dev = {
-		.platform_data = &heartbeat_data,
-	},
-	.num_resources  = ARRAY_SIZE(heartbeat_resources),
-	.resource       = heartbeat_resources,
+	.num_resources  = 1,
+	.resource       = &heartbeat_resource,
 };
 
 /* SMC91x */
@@ -84,14 +75,14 @@ device_initcall(se7780_devices_setup);
 static void __init se7780_setup(char **cmdline_p)
 {
 	/* "SH-Linux" on LED Display */
-	ctrl_outw( 'S' , PA_LED_DISP + (DISP_SEL0_ADDR << 1) );
-	ctrl_outw( 'H' , PA_LED_DISP + (DISP_SEL1_ADDR << 1) );
-	ctrl_outw( '-' , PA_LED_DISP + (DISP_SEL2_ADDR << 1) );
-	ctrl_outw( 'L' , PA_LED_DISP + (DISP_SEL3_ADDR << 1) );
-	ctrl_outw( 'i' , PA_LED_DISP + (DISP_SEL4_ADDR << 1) );
-	ctrl_outw( 'n' , PA_LED_DISP + (DISP_SEL5_ADDR << 1) );
-	ctrl_outw( 'u' , PA_LED_DISP + (DISP_SEL6_ADDR << 1) );
-	ctrl_outw( 'x' , PA_LED_DISP + (DISP_SEL7_ADDR << 1) );
+	__raw_writew( 'S' , PA_LED_DISP + (DISP_SEL0_ADDR << 1) );
+	__raw_writew( 'H' , PA_LED_DISP + (DISP_SEL1_ADDR << 1) );
+	__raw_writew( '-' , PA_LED_DISP + (DISP_SEL2_ADDR << 1) );
+	__raw_writew( 'L' , PA_LED_DISP + (DISP_SEL3_ADDR << 1) );
+	__raw_writew( 'i' , PA_LED_DISP + (DISP_SEL4_ADDR << 1) );
+	__raw_writew( 'n' , PA_LED_DISP + (DISP_SEL5_ADDR << 1) );
+	__raw_writew( 'u' , PA_LED_DISP + (DISP_SEL6_ADDR << 1) );
+	__raw_writew( 'x' , PA_LED_DISP + (DISP_SEL7_ADDR << 1) );
 
 	printk(KERN_INFO "Hitachi UL Solutions Engine 7780SE03 support.\n");
 
@@ -102,15 +93,15 @@ static void __init se7780_setup(char **c
 	 *   REQ2/GNT2 -> Serial ATA
 	 *   REQ3/GNT3 -> PCI slot
 	 */
-	ctrl_outw(0x0213, FPGA_REQSEL);
+	__raw_writew(0x0213, FPGA_REQSEL);
 
 	/* GPIO setting */
-	ctrl_outw(0x0000, GPIO_PECR);
-	ctrl_outw(ctrl_inw(GPIO_PHCR)&0xfff3, GPIO_PHCR);
-	ctrl_outw(0x0c00, GPIO_PMSELR);
+	__raw_writew(0x0000, GPIO_PECR);
+	__raw_writew(__raw_readw(GPIO_PHCR)&0xfff3, GPIO_PHCR);
+	__raw_writew(0x0c00, GPIO_PMSELR);
 
 	/* iVDR Power ON */
-	ctrl_outw(0x0001, FPGA_IVDRPW);
+	__raw_writew(0x0001, FPGA_IVDRPW);
 }
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sh03/rtc.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sh03/rtc.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sh03/rtc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sh03/rtc.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,15 +44,15 @@ unsigned long get_cmos_time(void)
 	spin_lock(&sh03_rtc_lock);
  again:
 	do {
-		sec  = (ctrl_inb(RTC_SEC1) & 0xf) + (ctrl_inb(RTC_SEC10) & 0x7) * 10;
-		min  = (ctrl_inb(RTC_MIN1) & 0xf) + (ctrl_inb(RTC_MIN10) & 0xf) * 10;
-		hour = (ctrl_inb(RTC_HOU1) & 0xf) + (ctrl_inb(RTC_HOU10) & 0xf) * 10;
-		day  = (ctrl_inb(RTC_DAY1) & 0xf) + (ctrl_inb(RTC_DAY10) & 0xf) * 10;
-		mon  = (ctrl_inb(RTC_MON1) & 0xf) + (ctrl_inb(RTC_MON10) & 0xf) * 10;
-		year = (ctrl_inb(RTC_YEA1) & 0xf) + (ctrl_inb(RTC_YEA10) & 0xf) * 10
-		     + (ctrl_inb(RTC_YEA100 ) & 0xf) * 100
-		     + (ctrl_inb(RTC_YEA1000) & 0xf) * 1000;
-	} while (sec != (ctrl_inb(RTC_SEC1) & 0xf) + (ctrl_inb(RTC_SEC10) & 0x7) * 10);
+		sec  = (__raw_readb(RTC_SEC1) & 0xf) + (__raw_readb(RTC_SEC10) & 0x7) * 10;
+		min  = (__raw_readb(RTC_MIN1) & 0xf) + (__raw_readb(RTC_MIN10) & 0xf) * 10;
+		hour = (__raw_readb(RTC_HOU1) & 0xf) + (__raw_readb(RTC_HOU10) & 0xf) * 10;
+		day  = (__raw_readb(RTC_DAY1) & 0xf) + (__raw_readb(RTC_DAY10) & 0xf) * 10;
+		mon  = (__raw_readb(RTC_MON1) & 0xf) + (__raw_readb(RTC_MON10) & 0xf) * 10;
+		year = (__raw_readb(RTC_YEA1) & 0xf) + (__raw_readb(RTC_YEA10) & 0xf) * 10
+		     + (__raw_readb(RTC_YEA100 ) & 0xf) * 100
+		     + (__raw_readb(RTC_YEA1000) & 0xf) * 1000;
+	} while (sec != (__raw_readb(RTC_SEC1) & 0xf) + (__raw_readb(RTC_SEC10) & 0x7) * 10);
 	if (year == 0 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
 	    hour > 23 || min > 59 || sec > 59) {
 		printk(KERN_ERR
@@ -60,16 +60,16 @@ unsigned long get_cmos_time(void)
 		printk("year=%d, mon=%d, day=%d, hour=%d, min=%d, sec=%d\n",
 		       year, mon, day, hour, min, sec);
 
-		ctrl_outb(0, RTC_SEC1); ctrl_outb(0, RTC_SEC10);
-		ctrl_outb(0, RTC_MIN1); ctrl_outb(0, RTC_MIN10);
-		ctrl_outb(0, RTC_HOU1); ctrl_outb(0, RTC_HOU10);
-		ctrl_outb(6, RTC_WEE1);
-		ctrl_outb(1, RTC_DAY1); ctrl_outb(0, RTC_DAY10);
-		ctrl_outb(1, RTC_MON1); ctrl_outb(0, RTC_MON10);
-		ctrl_outb(0, RTC_YEA1); ctrl_outb(0, RTC_YEA10);
-		ctrl_outb(0, RTC_YEA100);
-		ctrl_outb(2, RTC_YEA1000);
-		ctrl_outb(0, RTC_CTL);
+		__raw_writeb(0, RTC_SEC1); __raw_writeb(0, RTC_SEC10);
+		__raw_writeb(0, RTC_MIN1); __raw_writeb(0, RTC_MIN10);
+		__raw_writeb(0, RTC_HOU1); __raw_writeb(0, RTC_HOU10);
+		__raw_writeb(6, RTC_WEE1);
+		__raw_writeb(1, RTC_DAY1); __raw_writeb(0, RTC_DAY10);
+		__raw_writeb(1, RTC_MON1); __raw_writeb(0, RTC_MON10);
+		__raw_writeb(0, RTC_YEA1); __raw_writeb(0, RTC_YEA10);
+		__raw_writeb(0, RTC_YEA100);
+		__raw_writeb(2, RTC_YEA1000);
+		__raw_writeb(0, RTC_CTL);
 		goto again;
 	}
 
@@ -93,9 +93,9 @@ static int set_rtc_mmss(unsigned long no
 	/* gets recalled with irq locally disabled */
 	spin_lock(&sh03_rtc_lock);
 	for (i = 0 ; i < 1000000 ; i++)	/* may take up to 1 second... */
-		if (!(ctrl_inb(RTC_CTL) & RTC_BUSY))
+		if (!(__raw_readb(RTC_CTL) & RTC_BUSY))
 			break;
-	cmos_minutes = (ctrl_inb(RTC_MIN1) & 0xf) + (ctrl_inb(RTC_MIN10) & 0xf) * 10;
+	cmos_minutes = (__raw_readb(RTC_MIN1) & 0xf) + (__raw_readb(RTC_MIN10) & 0xf) * 10;
 	real_seconds = nowtime % 60;
 	real_minutes = nowtime / 60;
 	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
@@ -103,10 +103,10 @@ static int set_rtc_mmss(unsigned long no
 	real_minutes %= 60;
 
 	if (abs(real_minutes - cmos_minutes) < 30) {
-		ctrl_outb(real_seconds % 10, RTC_SEC1);
-		ctrl_outb(real_seconds / 10, RTC_SEC10);
-		ctrl_outb(real_minutes % 10, RTC_MIN1);
-		ctrl_outb(real_minutes / 10, RTC_MIN10);
+		__raw_writeb(real_seconds % 10, RTC_SEC1);
+		__raw_writeb(real_seconds / 10, RTC_SEC10);
+		__raw_writeb(real_minutes % 10, RTC_MIN1);
+		__raw_writeb(real_minutes / 10, RTC_MIN10);
 	} else {
 		printk(KERN_WARNING
 		       "set_rtc_mmss: can't update from %d to %d\n",
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sh03/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sh03/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sh03/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sh03/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -82,7 +82,7 @@ static int __init sh03_devices_setup(voi
 	/* open I/O area window */
 	paddrbase = virt_to_phys((void *)PA_AREA5_IO);
 	prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
-	cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
+	cf_ide_base = ioremap_prot(paddrbase, PAGE_SIZE, pgprot_val(prot));
 	if (!cf_ide_base) {
 		printk("allocate_cf_area : can't open CF I/O window!\n");
 		return -ENOMEM;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sh7763rdp/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sh7763rdp/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sh7763rdp/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sh7763rdp/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,18 +28,18 @@
 void __init init_sh7763rdp_IRQ(void)
 {
 	/* GPIO enabled */
-	ctrl_outl(1 << 25, INTC_INT2MSKCR);
+	__raw_writel(1 << 25, INTC_INT2MSKCR);
 
 	/* enable GPIO interrupts */
-	ctrl_outl((ctrl_inl(INTC_INT2PRI7) & 0xFF00FFFF) | 0x000F0000,
+	__raw_writel((__raw_readl(INTC_INT2PRI7) & 0xFF00FFFF) | 0x000F0000,
 		  INTC_INT2PRI7);
 
 	/* USBH enabled */
-	ctrl_outl(1 << 17, INTC_INT2MSKCR1);
+	__raw_writel(1 << 17, INTC_INT2MSKCR1);
 
 	/* GETHER enabled */
-	ctrl_outl(1 << 16, INTC_INT2MSKCR1);
+	__raw_writel(1 << 16, INTC_INT2MSKCR1);
 
 	/* DMAC enabled */
-	ctrl_outl(1 << 8, INTC_INT2MSKCR);
+	__raw_writel(1 << 8, INTC_INT2MSKCR);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sh7763rdp/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sh7763rdp/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-sh7763rdp/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-sh7763rdp/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -158,50 +158,50 @@ device_initcall(sh7763rdp_devices_setup)
 static void __init sh7763rdp_setup(char **cmdline_p)
 {
 	/* Board version check */
-	if (ctrl_inw(CPLD_BOARD_ID_ERV_REG) == 0xECB1)
+	if (__raw_readw(CPLD_BOARD_ID_ERV_REG) == 0xECB1)
 		printk(KERN_INFO "RTE Standard Configuration\n");
 	else
 		printk(KERN_INFO "RTA Standard Configuration\n");
 
 	/* USB pin select bits (clear bit 5-2 to 0) */
-	ctrl_outw((ctrl_inw(PORT_PSEL2) & 0xFFC3), PORT_PSEL2);
+	__raw_writew((__raw_readw(PORT_PSEL2) & 0xFFC3), PORT_PSEL2);
 	/* USBH setup port I controls to other (clear bits 4-9 to 0) */
-	ctrl_outw(ctrl_inw(PORT_PICR) & 0xFC0F, PORT_PICR);
+	__raw_writew(__raw_readw(PORT_PICR) & 0xFC0F, PORT_PICR);
 
 	/* Select USB Host controller */
-	ctrl_outw(0x00, USB_USBHSC);
+	__raw_writew(0x00, USB_USBHSC);
 
 	/* For LCD */
 	/* set PTJ7-1, bits 15-2 of PJCR to 0 */
-	ctrl_outw(ctrl_inw(PORT_PJCR) & 0x0003, PORT_PJCR);
+	__raw_writew(__raw_readw(PORT_PJCR) & 0x0003, PORT_PJCR);
 	/* set PTI5, bits 11-10 of PICR to 0 */
-	ctrl_outw(ctrl_inw(PORT_PICR) & 0xF3FF, PORT_PICR);
-	ctrl_outw(0, PORT_PKCR);
-	ctrl_outw(0, PORT_PLCR);
+	__raw_writew(__raw_readw(PORT_PICR) & 0xF3FF, PORT_PICR);
+	__raw_writew(0, PORT_PKCR);
+	__raw_writew(0, PORT_PLCR);
 	/* set PSEL2 bits 14-8, 5-4, of PSEL2 to 0 */
-	ctrl_outw((ctrl_inw(PORT_PSEL2) & 0x00C0), PORT_PSEL2);
+	__raw_writew((__raw_readw(PORT_PSEL2) & 0x00C0), PORT_PSEL2);
 	/* set PSEL3 bits 14-12, 6-4, 2-0 of PSEL3 to 0 */
-	ctrl_outw((ctrl_inw(PORT_PSEL3) & 0x0700), PORT_PSEL3);
+	__raw_writew((__raw_readw(PORT_PSEL3) & 0x0700), PORT_PSEL3);
 
 	/* For HAC */
 	/* bit3-0  0100:HAC & SSI1 enable */
-	ctrl_outw((ctrl_inw(PORT_PSEL1) & 0xFFF0) | 0x0004, PORT_PSEL1);
+	__raw_writew((__raw_readw(PORT_PSEL1) & 0xFFF0) | 0x0004, PORT_PSEL1);
 	/* bit14      1:SSI_HAC_CLK enable */
-	ctrl_outw(ctrl_inw(PORT_PSEL4) | 0x4000, PORT_PSEL4);
+	__raw_writew(__raw_readw(PORT_PSEL4) | 0x4000, PORT_PSEL4);
 
 	/* SH-Ether */
-	ctrl_outw((ctrl_inw(PORT_PSEL1) & ~0xff00) | 0x2400, PORT_PSEL1);
-	ctrl_outw(0x0, PORT_PFCR);
-	ctrl_outw(0x0, PORT_PFCR);
-	ctrl_outw(0x0, PORT_PFCR);
+	__raw_writew((__raw_readw(PORT_PSEL1) & ~0xff00) | 0x2400, PORT_PSEL1);
+	__raw_writew(0x0, PORT_PFCR);
+	__raw_writew(0x0, PORT_PFCR);
+	__raw_writew(0x0, PORT_PFCR);
 
 	/* MMC */
 	/*selects SCIF and MMC other functions */
-	ctrl_outw(0x0001, PORT_PSEL0);
+	__raw_writew(0x0001, PORT_PSEL0);
 	/* MMC clock operates */
-	ctrl_outl(ctrl_inl(MSTPCR1) & ~0x8, MSTPCR1);
-	ctrl_outw(ctrl_inw(PORT_PACR) & ~0x3000, PORT_PACR);
-	ctrl_outw(ctrl_inw(PORT_PCCR) & ~0xCFC3, PORT_PCCR);
+	__raw_writel(__raw_readl(MSTPCR1) & ~0x8, MSTPCR1);
+	__raw_writew(__raw_readw(PORT_PACR) & ~0x3000, PORT_PACR);
+	__raw_writew(__raw_readw(PORT_PCCR) & ~0xCFC3, PORT_PCCR);
 }
 
 static struct sh_machine_vector mv_sh7763rdp __initmv = {
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-snapgear/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-snapgear/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-snapgear/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-snapgear/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,7 @@
 
 static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id)
 {
-	(void)ctrl_inb(0xb8000000);	/* dummy read */
+	(void)__raw_readb(0xb8000000);	/* dummy read */
 
 	printk("SnapGear: erase switch interrupt!\n");
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-systemh/irq.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-systemh/irq.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-systemh/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-systemh/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,13 +41,13 @@ static void disable_systemh_irq(unsigned
 		unsigned long val, mask = 0x01 << 1;
 
 		/* Clear the "irq"th bit in the mask and set it in the request */
-		val = ctrl_inl((unsigned long)systemh_irq_mask_register);
+		val = __raw_readl((unsigned long)systemh_irq_mask_register);
 		val &= ~mask;
-		ctrl_outl(val, (unsigned long)systemh_irq_mask_register);
+		__raw_writel(val, (unsigned long)systemh_irq_mask_register);
 
-		val = ctrl_inl((unsigned long)systemh_irq_request_register);
+		val = __raw_readl((unsigned long)systemh_irq_request_register);
 		val |= mask;
-		ctrl_outl(val, (unsigned long)systemh_irq_request_register);
+		__raw_writel(val, (unsigned long)systemh_irq_request_register);
 	}
 }
 
@@ -57,9 +57,9 @@ static void enable_systemh_irq(unsigned
 		unsigned long val, mask = 0x01 << 1;
 
 		/* Set "irq"th bit in the mask register */
-		val = ctrl_inl((unsigned long)systemh_irq_mask_register);
+		val = __raw_readl((unsigned long)systemh_irq_mask_register);
 		val |= mask;
-		ctrl_outl(val, (unsigned long)systemh_irq_mask_register);
+		__raw_writel(val, (unsigned long)systemh_irq_mask_register);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-titan/io.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-titan/io.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-titan/io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-titan/io.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,108 +0,0 @@
-/*
- *	I/O routines for Titan
- */
-#include <linux/pci.h>
-#include <asm/machvec.h>
-#include <asm/addrspace.h>
-#include <mach/titan.h>
-#include <asm/io.h>
-
-static inline unsigned int port2adr(unsigned int port)
-{
-        maybebadio((unsigned long)port);
-        return port;
-}
-
-u8 titan_inb(unsigned long port)
-{
-        if (PXSEG(port))
-                return ctrl_inb(port);
-        return ctrl_inw(port2adr(port)) & 0xff;
-}
-
-u8 titan_inb_p(unsigned long port)
-{
-        u8 v;
-
-        if (PXSEG(port))
-                v = ctrl_inb(port);
-        else
-                v = ctrl_inw(port2adr(port)) & 0xff;
-        ctrl_delay();
-        return v;
-}
-
-u16 titan_inw(unsigned long port)
-{
-        if (PXSEG(port))
-                return ctrl_inw(port);
-        else if (port >= 0x2000)
-                return ctrl_inw(port2adr(port));
-        else
-                maybebadio(port);
-        return 0;
-}
-
-u32 titan_inl(unsigned long port)
-{
-        if (PXSEG(port))
-                return ctrl_inl(port);
-        else if (port >= 0x2000)
-                return ctrl_inw(port2adr(port));
-        else
-                maybebadio(port);
-        return 0;
-}
-
-void titan_outb(u8 value, unsigned long port)
-{
-        if (PXSEG(port))
-                ctrl_outb(value, port);
-        else
-                ctrl_outw(value, port2adr(port));
-}
-
-void titan_outb_p(u8 value, unsigned long port)
-{
-        if (PXSEG(port))
-                ctrl_outb(value, port);
-        else
-                ctrl_outw(value, port2adr(port));
-        ctrl_delay();
-}
-
-void titan_outw(u16 value, unsigned long port)
-{
-        if (PXSEG(port))
-                ctrl_outw(value, port);
-        else if (port >= 0x2000)
-                ctrl_outw(value, port2adr(port));
-        else
-                maybebadio(port);
-}
-
-void titan_outl(u32 value, unsigned long port)
-{
-        if (PXSEG(port))
-                ctrl_outl(value, port);
-        else
-                maybebadio(port);
-}
-
-void titan_insl(unsigned long port, void *dst, unsigned long count)
-{
-        maybebadio(port);
-}
-
-void titan_outsl(unsigned long port, const void *src, unsigned long count)
-{
-        maybebadio(port);
-}
-
-void __iomem *titan_ioport_map(unsigned long port, unsigned int size)
-{
-	if (PXSEG(port))
-		return (void __iomem *)port;
-
-	return (void __iomem *)port2adr(port);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-titan/Makefile linux-libre-2.6.34-gnu1/arch/sh/boards/mach-titan/Makefile
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-titan/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-titan/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,5 +0,0 @@
-#
-# Makefile for the Nimble Microsystems TITAN specific parts of the kernel
-#
-
-obj-y	 := setup.o io.o
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-titan/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-titan/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-titan/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-titan/setup.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,44 +0,0 @@
-/*
- * arch/sh/boards/titan/setup.c - Setup for Titan
- *
- *  Copyright (C) 2006  Jamie Lenehan
- *
- * 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 <mach/titan.h>
-#include <asm/io.h>
-
-static void __init init_titan_irq(void)
-{
-	/* enable individual interrupt mode for externals */
-	plat_irq_setup_pins(IRQ_MODE_IRQ);
-}
-
-static struct sh_machine_vector mv_titan __initmv = {
-	.mv_name =	"Titan",
-
-	.mv_inb =	titan_inb,
-	.mv_inw =	titan_inw,
-	.mv_inl =	titan_inl,
-	.mv_outb =	titan_outb,
-	.mv_outw =	titan_outw,
-	.mv_outl =	titan_outl,
-
-	.mv_inb_p =	titan_inb_p,
-	.mv_inw_p =	titan_inw,
-	.mv_inl_p =	titan_inl,
-	.mv_outb_p =	titan_outb_p,
-	.mv_outw_p =	titan_outw,
-	.mv_outl_p =	titan_outl,
-
-	.mv_insl =	titan_insl,
-	.mv_outsl =	titan_outsl,
-
-	.mv_ioport_map = titan_ioport_map,
-
-	.mv_init_irq =	init_titan_irq,
-};
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-x3proto/ilsel.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-x3proto/ilsel.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-x3proto/ilsel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-x3proto/ilsel.c	2010-05-16 17:17:36.000000000 -0400
@@ -70,10 +70,10 @@ static void __ilsel_enable(ilsel_source_
 	pr_debug("%s: bit#%d: addr - 0x%08lx (shift %d, set %d)\n",
 		 __func__, bit, addr, shift, set);
 
-	tmp = ctrl_inw(addr);
+	tmp = __raw_readw(addr);
 	tmp &= ~(0xf << shift);
 	tmp |= set << shift;
-	ctrl_outw(tmp, addr);
+	__raw_writew(tmp, addr);
 }
 
 /**
@@ -142,9 +142,9 @@ void ilsel_disable(unsigned int irq)
 
 	addr = mk_ilsel_addr(irq);
 
-	tmp = ctrl_inw(addr);
+	tmp = __raw_readw(addr);
 	tmp &= ~(0xf << mk_ilsel_shift(irq));
-	ctrl_outw(tmp, addr);
+	__raw_writew(tmp, addr);
 
 	clear_bit(irq, &ilsel_level_map);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/mach-x3proto/setup.c linux-libre-2.6.34-gnu1/arch/sh/boards/mach-x3proto/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/boards/mach-x3proto/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/mach-x3proto/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -149,7 +149,7 @@ static void __init x3proto_init_irq(void
 	plat_irq_setup_pins(IRQ_MODE_IRL3210);
 
 	/* Set ICR0.LVLMODE */
-	ctrl_outl(ctrl_inl(0xfe410000) | (1 << 21), 0xfe410000);
+	__raw_writel(__raw_readl(0xfe410000) | (1 << 21), 0xfe410000);
 }
 
 static struct sh_machine_vector mv_x3proto __initmv = {
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boards/Makefile linux-libre-2.6.34-gnu1/arch/sh/boards/Makefile
--- linux-libre-2.6.33-gnu1/arch/sh/boards/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boards/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -8,3 +8,4 @@ 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
+obj-$(CONFIG_SH_TITAN)		+= board-titan.o
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boot/compressed/cache.c linux-libre-2.6.34-gnu1/arch/sh/boot/compressed/cache.c
--- linux-libre-2.6.33-gnu1/arch/sh/boot/compressed/cache.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boot/compressed/cache.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@ int cache_control(unsigned int command)
 
 	for (i = 0; i < (32 * 1024); i += 32) {
 		(void)*p;
-		p += (32 / sizeof (int));
+		p += (32 / sizeof(int));
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boot/compressed/Makefile linux-libre-2.6.34-gnu1/arch/sh/boot/compressed/Makefile
--- linux-libre-2.6.33-gnu1/arch/sh/boot/compressed/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boot/compressed/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -6,14 +6,11 @@
 
 targets		:= vmlinux vmlinux.bin vmlinux.bin.gz \
 		   vmlinux.bin.bz2 vmlinux.bin.lzma \
+		   vmlinux.bin.lzo \
 		   head_$(BITS).o misc.o piggy.o
 
 OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o
 
-ifdef CONFIG_SH_STANDARD_BIOS
-OBJECTS += $(obj)/../../kernel/sh_bios.o
-endif
-
 #
 # IMAGE_OFFSET is the load offset of the compression loader
 #
@@ -47,6 +44,8 @@ $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.al
 	$(call if_changed,bzip2)
 $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
 	$(call if_changed,lzma)
+$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE
+	$(call if_changed,lzo)
 
 OBJCOPYFLAGS += -R .empty_zero_page
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boot/compressed/misc.c linux-libre-2.6.34-gnu1/arch/sh/boot/compressed/misc.c
--- linux-libre-2.6.33-gnu1/arch/sh/boot/compressed/misc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boot/compressed/misc.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
 #include <asm/uaccess.h>
 #include <asm/addrspace.h>
 #include <asm/page.h>
-#include <asm/sh_bios.h>
 
 /*
  * gzip declarations
@@ -62,29 +61,15 @@ static unsigned long free_mem_end_ptr;
 #include "../../../../lib/decompress_unlzma.c"
 #endif
 
-#ifdef CONFIG_SH_STANDARD_BIOS
-size_t strlen(const char *s)
-{
-	int i = 0;
-
-	while (*s++)
-		i++;
-	return i;
-}
+#ifdef CONFIG_KERNEL_LZO
+#include "../../../../lib/decompress_unlzo.c"
+#endif
 
 int puts(const char *s)
 {
-	int len = strlen(s);
-	sh_bios_console_write(s, len);
-	return len;
-}
-#else
-int puts(const char *s)
-{
 	/* This should be updated to use the sh-sci routines */
 	return 0;
 }
-#endif
 
 void* memset(void* s, int c, size_t n)
 {
@@ -132,7 +117,7 @@ void decompress_kernel(void)
 	output_addr = (CONFIG_MEMORY_START + 0x2000);
 #else
 	output_addr = __pa((unsigned long)&_text+PAGE_SIZE);
-#ifdef CONFIG_29BIT
+#if defined(CONFIG_29BIT)
 	output_addr |= P2SEG;
 #endif
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/boot/Makefile linux-libre-2.6.34-gnu1/arch/sh/boot/Makefile
--- linux-libre-2.6.33-gnu1/arch/sh/boot/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/boot/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -21,12 +21,15 @@ CONFIG_ZERO_PAGE_OFFSET	?= 0x00001000
 CONFIG_ENTRY_OFFSET	?= 0x00001000
 
 suffix-y := bin
-suffix-$(CONFIG_KERNEL_GZIP)  := gz
-suffix-$(CONFIG_KERNEL_BZIP2) := bz2
-suffix-$(CONFIG_KERNEL_LZMA)  := lzma
+suffix-$(CONFIG_KERNEL_GZIP)	:= gz
+suffix-$(CONFIG_KERNEL_BZIP2)	:= bz2
+suffix-$(CONFIG_KERNEL_LZMA)	:= lzma
+suffix-$(CONFIG_KERNEL_LZO)	:= lzo
 
-targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz uImage.bz2 uImage.lzma uImage.bin
-extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma
+targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz \
+	   uImage.bz2 uImage.lzma uImage.lzo uImage.bin
+extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
+	   vmlinux.bin.lzo
 subdir- := compressed romimage
 
 $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
@@ -43,15 +46,8 @@ $(obj)/romImage: $(obj)/romimage/vmlinux
 $(obj)/romimage/vmlinux: $(obj)/zImage FORCE
 	$(Q)$(MAKE) $(build)=$(obj)/romimage $@
 
-KERNEL_MEMORY := 0x00000000
-ifeq ($(CONFIG_PMB_FIXED),y)
-KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
+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)  + \
@@ -80,6 +76,9 @@ $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.b
 $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,lzma)
 
+$(obj)/vmlinux.bin.lzo: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,lzo)
+
 $(obj)/uImage.bz2: $(obj)/vmlinux.bin.bz2
 	$(call if_changed,uimage,bzip2)
 
@@ -89,6 +88,9 @@ $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz
 $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma
 	$(call if_changed,uimage,lzma)
 
+$(obj)/uImage.lzo: $(obj)/vmlinux.bin.lzo
+	$(call if_changed,uimage,lzo)
+
 $(obj)/uImage.bin: $(obj)/vmlinux.bin
 	$(call if_changed,uimage,none)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/cchips/hd6446x/hd64461.c linux-libre-2.6.34-gnu1/arch/sh/cchips/hd6446x/hd64461.c
--- linux-libre-2.6.33-gnu1/arch/sh/cchips/hd6446x/hd64461.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/cchips/hd6446x/hd64461.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,25 +55,22 @@ static struct irq_chip hd64461_irq_chip
 
 static void hd64461_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
-	unsigned short intv = ctrl_inw(HD64461_NIRR);
-	struct irq_desc *ext_desc;
+	unsigned short intv = __raw_readw(HD64461_NIRR);
 	unsigned int ext_irq = HD64461_IRQBASE;
 
 	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++;
+	for (; intv; intv >>= 1, ext_irq++) {
+		if (!(intv & 1))
+			continue;
+
+		generic_handle_irq(ext_irq);
 	}
 }
 
 int __init setup_hd64461(void)
 {
-	int i;
+	int i, nid = cpu_to_node(boot_cpu_data);
 
 	if (!MACH_HD64461)
 		return 0;
@@ -90,9 +87,26 @@ int __init setup_hd64461(void)
 	__raw_writew(0xffff, HD64461_NIMR);
 
 	/*  IRQ 80 -> 95 belongs to HD64461  */
-	for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++)
+	for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) {
+		unsigned int irq;
+
+		irq = create_irq_nr(i, nid);
+		if (unlikely(irq == 0)) {
+			pr_err("%s: failed hooking irq %d for HD64461\n",
+			       __func__, i);
+			return -EBUSY;
+		}
+
+		if (unlikely(irq != i)) {
+			pr_err("%s: got irq %d but wanted %d, bailing.\n",
+			       __func__, irq, i);
+			destroy_irq(irq);
+			return -EINVAL;
+		}
+
 		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);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/configs/ecovec24_defconfig linux-libre-2.6.34-gnu1/arch/sh/configs/ecovec24_defconfig
--- linux-libre-2.6.33-gnu1/arch/sh/configs/ecovec24_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/configs/ecovec24_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:20:36 2010
+# Linux kernel version: 2.6.34-rc2
+# Mon Mar 29 02:21:58 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ 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_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -47,9 +48,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -71,14 +74,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -107,7 +104,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -116,13 +113,13 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -234,12 +231,12 @@ CONFIG_CPU_SUBTYPE_SH7724=y
 CONFIG_QUICKLIST=y
 CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
-CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_FORCE_MAX_ZONEORDER=12
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x10000000
 CONFIG_29BIT=y
-# CONFIG_PMB_ENABLE is not set
-# CONFIG_X2TLB is not set
+# CONFIG_PMB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -247,6 +244,8 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -262,7 +261,7 @@ 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_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -337,7 +336,6 @@ CONFIG_SECCOMP=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -347,7 +345,7 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
 CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_CMDLINE_OVERWRITE=y
 # CONFIG_CMDLINE_EXTEND is not set
-CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 root=/dev/nfs ip=dhcp mem=120M memchunk.vpu=4m"
+CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 root=/dev/nfs ip=dhcp mem=248M memchunk.vpu=8m memchunk.veu0=4m"
 
 #
 # Bus options
@@ -373,6 +371,7 @@ CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_HIBERNATION is not set
 CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 # CONFIG_CPU_IDLE is not set
 CONFIG_NET=y
 
@@ -380,7 +379,6 @@ 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
@@ -445,7 +443,45 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
-# CONFIG_IRDA is not set
+CONFIG_IRDA=y
+
+#
+# IrDA protocols
+#
+# CONFIG_IRLAN is not set
+# CONFIG_IRCOMM is not set
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+
+#
+# Dongle support
+#
+CONFIG_SH_SIR=y
+# 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_MCS_FIR is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
@@ -556,6 +592,7 @@ CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_NANDSIM is not set
 # CONFIG_MTD_NAND_PLATFORM is not set
 # CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_NAND_SH_FLCTL is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
@@ -597,6 +634,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -616,6 +654,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -768,7 +807,29 @@ CONFIG_KEYBOARD_SH_KEYSC=y
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 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_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+CONFIG_TOUCHSCREEN_TSC2007=y
+# CONFIG_TOUCHSCREEN_W90X900 is not set
 # CONFIG_INPUT_MISC is not set
 
 #
@@ -802,10 +863,10 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
 # CONFIG_HW_RANDOM_TIMERIOMEM is not set
@@ -830,6 +891,7 @@ CONFIG_I2C_HELPER_AUTO=y
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_SH_MOBILE=y
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -843,15 +905,9 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 
@@ -882,13 +938,16 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -919,23 +978,26 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
-# CONFIG_MFD_CORE is not set
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_SH_MOBILE_SDHI is not set
+CONFIG_MFD_SH_MOBILE_SDHI=y
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 CONFIG_MEDIA_SUPPORT=y
@@ -985,10 +1047,10 @@ CONFIG_SOC_CAMERA=y
 # CONFIG_SOC_CAMERA_MT9M001 is not set
 # CONFIG_SOC_CAMERA_MT9M111 is not set
 # CONFIG_SOC_CAMERA_MT9T031 is not set
-# CONFIG_SOC_CAMERA_MT9T112 is not set
+CONFIG_SOC_CAMERA_MT9T112=y
 # CONFIG_SOC_CAMERA_MT9V022 is not set
 # CONFIG_SOC_CAMERA_RJ54N1 is not set
-# CONFIG_SOC_CAMERA_TW9910 is not set
+CONFIG_SOC_CAMERA_TW9910=y
 # CONFIG_SOC_CAMERA_PLATFORM is not set
 # CONFIG_SOC_CAMERA_OV772X is not set
 # CONFIG_SOC_CAMERA_OV9640 is not set
@@ -1001,6 +1063,7 @@ CONFIG_RADIO_ADAPTERS=y
 # CONFIG_RADIO_SI470X is not set
 # CONFIG_USB_MR800 is not set
 # CONFIG_RADIO_TEA5764 is not set
+# CONFIG_RADIO_SAA7706H is not set
 # CONFIG_RADIO_TEF6862 is not set
 # CONFIG_DAB is not set
 
@@ -1034,6 +1097,7 @@ CONFIG_FB_DEFERRED_IO=y
 #
 # CONFIG_FB_S1D13XXX is not set
 CONFIG_FB_SH_MOBILE_LCDC=y
+# CONFIG_FB_TMIO is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
@@ -1062,7 +1126,46 @@ CONFIG_LOGO=y
 # CONFIG_LOGO_SUPERH_MONO is not set
 # CONFIG_LOGO_SUPERH_VGA16 is not set
 CONFIG_LOGO_SUPERH_CLUT224=y
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND_SEQ_DUMMY=y
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_SEQUENCER_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_SUPERH=y
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+
+#
+# SoC Audio support for SuperH
+#
+CONFIG_SND_SOC_SH4_FSI=y
+# CONFIG_SND_FSI_AK4642 is not set
+CONFIG_SND_FSI_DA7210=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_DA7210=y
+# CONFIG_SOUND_PRIME is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HIDRAW is not set
@@ -1077,6 +1180,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 # CONFIG_HID_A4TECH is not set
 # CONFIG_HID_APPLE is not set
 # CONFIG_HID_BELKIN is not set
@@ -1091,12 +1195,16 @@ CONFIG_USB_HID=y
 # CONFIG_HID_KENSINGTON is not set
 # CONFIG_HID_LOGITECH is not set
 # CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
 # CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_QUANTA is not set
 # CONFIG_HID_SAMSUNG is not set
 # CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
 # CONFIG_HID_SUNPLUS is not set
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1136,6 +1244,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_SL811_HCD is not set
 CONFIG_USB_R8A66597_HCD=y
 # CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
@@ -1188,7 +1297,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1200,8 +1308,45 @@ CONFIG_USB_STORAGE=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
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+CONFIG_USB_GADGET_R8A66597=y
+CONFIG_USB_R8A66597=y
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
+# CONFIG_USB_G_MULTI is not set
 
 #
 # OTG and related infrastructure
@@ -1224,10 +1369,8 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_AT91 is not set
-# CONFIG_MMC_ATMELMCI is not set
 CONFIG_MMC_SPI=y
-# CONFIG_MMC_TMIO is not set
+CONFIG_MMC_TMIO=y
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -1253,10 +1396,10 @@ CONFIG_RTC_INTF_DEV=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_RS5C372=y
 # CONFIG_RTC_DRV_ISL1208 is not set
 # CONFIG_RTC_DRV_X1205 is not set
-CONFIG_RTC_DRV_PCF8563=y
+# CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
 # CONFIG_RTC_DRV_BQ32K is not set
@@ -1303,8 +1446,6 @@ CONFIG_RTC_DRV_PCF8563=y
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 CONFIG_UIO_PDRV_GENIRQ=y
-# CONFIG_UIO_SMX is not set
-# CONFIG_UIO_SERCOS3 is not set
 
 #
 # TI VLYNQ
@@ -1390,6 +1531,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_UBIFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1418,6 +1560,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1487,6 +1630,7 @@ CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_HAVE_FUNCTION_TRACER=y
@@ -1618,7 +1762,7 @@ CONFIG_CRYPTO_HW=y
 #
 CONFIG_BITREVERSE=y
 CONFIG_GENERIC_FIND_LAST_BIT=y
-# CONFIG_CRC_CCITT is not set
+CONFIG_CRC_CCITT=y
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=y
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/configs/rts7751r2d1_defconfig linux-libre-2.6.34-gnu1/arch/sh/configs/rts7751r2d1_defconfig
--- linux-libre-2.6.33-gnu1/arch/sh/configs/rts7751r2d1_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/configs/rts7751r2d1_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -877,7 +877,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 # CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=1
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/configs/rts7751r2dplus_defconfig linux-libre-2.6.34-gnu1/arch/sh/configs/rts7751r2dplus_defconfig
--- linux-libre-2.6.33-gnu1/arch/sh/configs/rts7751r2dplus_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/configs/rts7751r2dplus_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -963,7 +963,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 # CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=1
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/configs/sdk7786_defconfig linux-libre-2.6.34-gnu1/arch/sh/configs/sdk7786_defconfig
--- linux-libre-2.6.33-gnu1/arch/sh/configs/sdk7786_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/configs/sdk7786_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1754 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc7
+# Tue Feb  9 15:27:06 2010
+#
+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
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=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_HUGETLBFS=y
+CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_PCI=y
+CONFIG_SYS_SUPPORTS_TMU=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_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_COHERENT=y
+# CONFIG_DMA_NONCOHERENT is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# 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_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+CONFIG_RCU_TRACE=y
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+CONFIG_TREE_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_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_MEM_RES_CTLR=y
+# CONFIG_CGROUP_MEM_RES_CTLR_SWAP is not set
+CONFIG_MM_OWNER=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+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 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_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_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+CONFIG_EVENT_PROFILE=y
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+# CONFIG_OPROFILE is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+CONFIG_BLK_CGROUP=y
+# CONFIG_DEBUG_BLK_CGROUP is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_CFQ_GROUP_IOSCHED=y
+# CONFIG_DEBUG_CFQ_IOSCHED is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# 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_SH7724 is not set
+# CONFIG_CPU_SUBTYPE_SH7757 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
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_MEMORY_START=0x60000000
+CONFIG_MEMORY_SIZE=0x20000000
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB=y
+# CONFIG_PMB_LEGACY is not set
+CONFIG_X2TLB=y
+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_ARCH_MEMORY_PROBE=y
+CONFIG_IOREMAP_FIXED=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_HUGETLB_PAGE_SIZE_64K is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256K is not set
+CONFIG_HUGETLB_PAGE_SIZE_1MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_512MB is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTPLUG_SPARSE=y
+CONFIG_MEMORY_HOTREMOVE=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=1
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+
+#
+# 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_SDK7786=y
+# CONFIG_SH_URQUELL is not set
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TIMER_TMU=y
+CONFIG_SH_CLK_CPG=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_SH_CPU_FREQ=y
+
+#
+# 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=y
+# CONFIG_SMP 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_ENTRY_OFFSET=0x00001000
+CONFIG_CMDLINE_OVERWRITE=y
+# CONFIG_CMDLINE_EXTEND is not set
+CONFIG_CMDLINE="console=ttySC1,115200 earlyprintk=sh-sci.1,115200 root=/dev/sda1 nmi_debug=state,debounce rootdelay=10"
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+# CONFIG_PCIE_ECRC is not set
+CONFIG_PCIEAER_INJECT=y
+CONFIG_PCIEASPM=y
+CONFIG_PCIEASPM_DEBUG=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 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=y
+
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_VERBOSE=y
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=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=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 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_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_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
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+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_AD525X_DPOT is not set
+# 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_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_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_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
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_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_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_SATA_PMP=y
+# CONFIG_SATA_AHCI is not set
+CONFIG_SATA_SIL24=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 is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+CONFIG_PATA_PLATFORM=y
+# CONFIG_PATA_SCH is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_STNIC 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=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_ATL2 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+CONFIG_WLAN=y
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_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_VMXNET3 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
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_SH_KEYSC is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=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_ALTERA_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 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+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 is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+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_DESIGNWARE 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 is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_SH_MSIOF is not set
+# CONFIG_SPI_SH_SCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SH_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_MFD_SH_MOBILE_SDHI is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+CONFIG_VGA_ARB=y
+# 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_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS 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
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD 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_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 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=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+CONFIG_USB_GADGET_M66592=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_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_MULTI is not set
+
+#
+# OTG and related infrastructure
+#
+# 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=y
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SH=y
+# CONFIG_RTC_DRV_GENERIC is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=m
+# CONFIG_UIO_CIF is not set
+# CONFIG_UIO_PDRV is not set
+# CONFIG_UIO_PDRV_GENIRQ is not set
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_AEC is not set
+# CONFIG_UIO_SERCOS3 is not set
+# CONFIG_UIO_PCI_GENERIC is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_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=y
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# 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_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_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_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+CONFIG_DEBUG_VM=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_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=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_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_FTRACE_SYSCALLS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+CONFIG_KSYM_TRACER=y
+# CONFIG_PROFILE_KSYM_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG 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_STACK_DEBUG is not set
+CONFIG_DEBUG_STACK_USAGE=y
+# CONFIG_4KSTACKS is not set
+CONFIG_DUMP_CODE=y
+CONFIG_DWARF_UNWINDER=y
+# CONFIG_SH_NO_BSS_INIT is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=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 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_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/dma/dma-api.c linux-libre-2.6.34-gnu1/arch/sh/drivers/dma/dma-api.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/dma/dma-api.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/dma/dma-api.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/dma.h>
 
 DEFINE_SPINLOCK(dma_spin_lock);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/dma/dmabrg.c linux-libre-2.6.34-gnu1/arch/sh/drivers/dma/dmabrg.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/dma/dmabrg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/dma/dmabrg.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <asm/dma.h>
 #include <asm/dmabrg.h>
 #include <asm/io.h>
@@ -86,8 +87,8 @@ static irqreturn_t dmabrg_irq(int irq, v
 	unsigned long dcr;
 	unsigned int i;
 
-	dcr = ctrl_inl(DMABRGCR);
-	ctrl_outl(dcr & ~0x00ff0003, DMABRGCR);	/* ack all */
+	dcr = __raw_readl(DMABRGCR);
+	__raw_writel(dcr & ~0x00ff0003, DMABRGCR);	/* ack all */
 	dcr &= dcr >> 8;	/* ignore masked */
 
 	/* USB stuff, get it out of the way first */
@@ -109,17 +110,17 @@ static irqreturn_t dmabrg_irq(int irq, v
 static void dmabrg_disable_irq(unsigned int dmairq)
 {
 	unsigned long dcr;
-	dcr = ctrl_inl(DMABRGCR);
+	dcr = __raw_readl(DMABRGCR);
 	dcr &= ~(1 << ((dmairq > 1) ? dmairq + 22 : dmairq + 8));
-	ctrl_outl(dcr, DMABRGCR);
+	__raw_writel(dcr, DMABRGCR);
 }
 
 static void dmabrg_enable_irq(unsigned int dmairq)
 {
 	unsigned long dcr;
-	dcr = ctrl_inl(DMABRGCR);
+	dcr = __raw_readl(DMABRGCR);
 	dcr |= (1 << ((dmairq > 1) ? dmairq + 22 : dmairq + 8));
-	ctrl_outl(dcr, DMABRGCR);
+	__raw_writel(dcr, DMABRGCR);
 }
 
 int dmabrg_request_irq(unsigned int dmairq, void(*handler)(void*),
@@ -165,13 +166,13 @@ static int __init dmabrg_init(void)
 		printk(KERN_INFO "DMABRG: DMAC ch0 not reserved!\n");
 #endif
 
-	ctrl_outl(0, DMABRGCR);
-	ctrl_outl(0, DMACHCR0);
-	ctrl_outl(0x94000000, DMARSRA);	/* enable DMABRG in DMAC 0 */
+	__raw_writel(0, DMABRGCR);
+	__raw_writel(0, DMACHCR0);
+	__raw_writel(0x94000000, DMARSRA);	/* enable DMABRG in DMAC 0 */
 
 	/* enable DMABRG mode, enable the DMAC */
-	or = ctrl_inl(DMAOR);
-	ctrl_outl(or | DMAOR_BRG | DMAOR_DMEN, DMAOR);
+	or = __raw_readl(DMAOR);
+	__raw_writel(or | DMAOR_BRG | DMAOR_DMEN, DMAOR);
 
 	ret = request_irq(DMABRGI0, dmabrg_irq, IRQF_DISABLED,
 			"DMABRG USB address error", NULL);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/dma/dma-pvr2.c linux-libre-2.6.34-gnu1/arch/sh/drivers/dma/dma-pvr2.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/dma/dma-pvr2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/dma/dma-pvr2.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,10 +40,10 @@ static irqreturn_t pvr2_dma_interrupt(in
 
 static int pvr2_request_dma(struct dma_channel *chan)
 {
-	if (ctrl_inl(PVR2_DMA_MODE) != 0)
+	if (__raw_readl(PVR2_DMA_MODE) != 0)
 		return -EBUSY;
 
-	ctrl_outl(0, PVR2_DMA_LMMODE0);
+	__raw_writel(0, PVR2_DMA_LMMODE0);
 
 	return 0;
 }
@@ -60,9 +60,9 @@ static int pvr2_xfer_dma(struct dma_chan
 
 	xfer_complete = 0;
 
-	ctrl_outl(chan->dar, PVR2_DMA_ADDR);
-	ctrl_outl(chan->count, PVR2_DMA_COUNT);
-	ctrl_outl(chan->mode & DMA_MODE_MASK, PVR2_DMA_MODE);
+	__raw_writel(chan->dar, PVR2_DMA_ADDR);
+	__raw_writel(chan->count, PVR2_DMA_COUNT);
+	__raw_writel(chan->mode & DMA_MODE_MASK, PVR2_DMA_MODE);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/dma/dma-sh.c linux-libre-2.6.34-gnu1/arch/sh/drivers/dma/dma-sh.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/dma/dma-sh.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/dma/dma-sh.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,11 +52,14 @@ static inline unsigned int get_dmte_irq(
  *
  * iterations to complete the transfer.
  */
+static unsigned int ts_shift[] = TS_SHIFT;
 static inline unsigned int calc_xmit_shift(struct dma_channel *chan)
 {
-	u32 chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
+	u32 chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR);
+	int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) |
+		((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT);
 
-	return ts_shift[(chcr & CHCR_TS_MASK)>>CHCR_TS_SHIFT];
+	return ts_shift[cnt];
 }
 
 /*
@@ -70,13 +73,13 @@ static irqreturn_t dma_tei(int irq, void
 	struct dma_channel *chan = dev_id;
 	u32 chcr;
 
-	chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
+	chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR);
 
 	if (!(chcr & CHCR_TE))
 		return IRQ_NONE;
 
 	chcr &= ~(CHCR_IE | CHCR_DE);
-	ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
+	__raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR));
 
 	wake_up(&chan->wait_queue);
 
@@ -115,7 +118,7 @@ sh_dmac_configure_channel(struct dma_cha
 		chan->flags &= ~DMA_TEI_CAPABLE;
 	}
 
-	ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
+	__raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR));
 
 	chan->flags |= DMA_CONFIGURED;
 	return 0;
@@ -126,13 +129,13 @@ static void sh_dmac_enable_dma(struct dm
 	int irq;
 	u32 chcr;
 
-	chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
+	chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR);
 	chcr |= CHCR_DE;
 
 	if (chan->flags & DMA_TEI_CAPABLE)
 		chcr |= CHCR_IE;
 
-	ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
+	__raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR));
 
 	if (chan->flags & DMA_TEI_CAPABLE) {
 		irq = get_dmte_irq(chan->chan);
@@ -150,9 +153,9 @@ static void sh_dmac_disable_dma(struct d
 		disable_irq(irq);
 	}
 
-	chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
+	chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR);
 	chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE);
-	ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
+	__raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR));
 }
 
 static int sh_dmac_xfer_dma(struct dma_channel *chan)
@@ -183,12 +186,12 @@ static int sh_dmac_xfer_dma(struct dma_c
 	 */
 	if (chan->sar || (mach_is_dreamcast() &&
 			  chan->chan == PVR2_CASCADE_CHAN))
-		ctrl_outl(chan->sar, (dma_base_addr[chan->chan]+SAR));
+		__raw_writel(chan->sar, (dma_base_addr[chan->chan]+SAR));
 	if (chan->dar || (mach_is_dreamcast() &&
 			  chan->chan == PVR2_CASCADE_CHAN))
-		ctrl_outl(chan->dar, (dma_base_addr[chan->chan] + DAR));
+		__raw_writel(chan->dar, (dma_base_addr[chan->chan] + DAR));
 
-	ctrl_outl(chan->count >> calc_xmit_shift(chan),
+	__raw_writel(chan->count >> calc_xmit_shift(chan),
 		(dma_base_addr[chan->chan] + TCR));
 
 	sh_dmac_enable_dma(chan);
@@ -198,10 +201,10 @@ static int sh_dmac_xfer_dma(struct dma_c
 
 static int sh_dmac_get_dma_residue(struct dma_channel *chan)
 {
-	if (!(ctrl_inl(dma_base_addr[chan->chan] + CHCR) & CHCR_DE))
+	if (!(__raw_readl(dma_base_addr[chan->chan] + CHCR) & CHCR_DE))
 		return 0;
 
-	return ctrl_inl(dma_base_addr[chan->chan] + TCR)
+	return __raw_readl(dma_base_addr[chan->chan] + TCR)
 		 << calc_xmit_shift(chan);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/heartbeat.c linux-libre-2.6.34-gnu1/arch/sh/drivers/heartbeat.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/heartbeat.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/heartbeat.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Generic heartbeat driver for regular LED banks
  *
- * Copyright (C) 2007  Paul Mundt
+ * Copyright (C) 2007 - 2010  Paul Mundt
  *
  * Most SH reference boards include a number of individual LEDs that can
  * be independently controlled (either via a pre-defined hardware
@@ -24,10 +24,11 @@
 #include <linux/sched.h>
 #include <linux/timer.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <asm/heartbeat.h>
 
 #define DRV_NAME "heartbeat"
-#define DRV_VERSION "0.1.1"
+#define DRV_VERSION "0.1.2"
 
 static unsigned char default_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
 
@@ -98,7 +99,7 @@ static int heartbeat_drv_probe(struct pl
 			return -ENOMEM;
 	}
 
-	hd->base = ioremap_nocache(res->start, res->end - res->start + 1);
+	hd->base = ioremap_nocache(res->start, resource_size(res));
 	if (unlikely(!hd->base)) {
 		dev_err(&pdev->dev, "ioremap failed\n");
 
@@ -117,8 +118,20 @@ static int heartbeat_drv_probe(struct pl
 	for (i = 0; i < hd->nr_bits; i++)
 		hd->mask |= (1 << hd->bit_pos[i]);
 
-	if (!hd->regsize)
-		hd->regsize = 8;	/* default access size */
+	if (!hd->regsize) {
+		switch (res->flags & IORESOURCE_MEM_TYPE_MASK) {
+		case IORESOURCE_MEM_32BIT:
+			hd->regsize = 32;
+			break;
+		case IORESOURCE_MEM_16BIT:
+			hd->regsize = 16;
+			break;
+		case IORESOURCE_MEM_8BIT:
+		default:
+			hd->regsize = 8;
+			break;
+		}
+	}
 
 	setup_timer(&hd->timer, heartbeat_timer, (unsigned long)hd);
 	platform_set_drvdata(pdev, hd);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/common.c linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/common.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/common.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/common.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,162 @@
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/kernel.h>
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+static struct pci_dev *fake_pci_dev(struct pci_channel *hose,
+	int top_bus, int busnr, int devfn)
+{
+	static struct pci_dev dev;
+	static struct pci_bus bus;
+
+	dev.bus = &bus;
+	dev.sysdata = hose;
+	dev.devfn = devfn;
+	bus.number = busnr;
+	bus.sysdata = hose;
+	bus.ops = hose->pci_ops;
+
+	if(busnr != top_bus)
+		/* Fake a parent bus structure. */
+		bus.parent = &bus;
+	else
+		bus.parent = NULL;
+
+	return &dev;
+}
+
+#define EARLY_PCI_OP(rw, size, type)					\
+int __init early_##rw##_config_##size(struct pci_channel *hose,		\
+	int top_bus, int bus, int devfn, int offset, type value)	\
+{									\
+	return pci_##rw##_config_##size(				\
+		fake_pci_dev(hose, top_bus, bus, devfn),		\
+		offset, value);						\
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
+
+int __init pci_is_66mhz_capable(struct pci_channel *hose,
+				int top_bus, int current_bus)
+{
+	u32 pci_devfn;
+	unsigned short vid;
+	int cap66 = -1;
+	u16 stat;
+
+	printk(KERN_INFO "PCI: Checking 66MHz capabilities...\n");
+
+	for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
+		if (PCI_FUNC(pci_devfn))
+			continue;
+		if (early_read_config_word(hose, top_bus, current_bus,
+					   pci_devfn, PCI_VENDOR_ID, &vid) !=
+		    PCIBIOS_SUCCESSFUL)
+			continue;
+		if (vid == 0xffff)
+			continue;
+
+		/* check 66MHz capability */
+		if (cap66 < 0)
+			cap66 = 1;
+		if (cap66) {
+			early_read_config_word(hose, top_bus, current_bus,
+					       pci_devfn, PCI_STATUS, &stat);
+			if (!(stat & PCI_STATUS_66MHZ)) {
+				printk(KERN_DEBUG
+				       "PCI: %02x:%02x not 66MHz capable.\n",
+				       current_bus, pci_devfn);
+				cap66 = 0;
+				break;
+			}
+		}
+	}
+
+	return cap66 > 0;
+}
+
+static void pcibios_enable_err(unsigned long __data)
+{
+	struct pci_channel *hose = (struct pci_channel *)__data;
+
+	del_timer(&hose->err_timer);
+	printk(KERN_DEBUG "PCI: re-enabling error IRQ.\n");
+	enable_irq(hose->err_irq);
+}
+
+static void pcibios_enable_serr(unsigned long __data)
+{
+	struct pci_channel *hose = (struct pci_channel *)__data;
+
+	del_timer(&hose->serr_timer);
+	printk(KERN_DEBUG "PCI: re-enabling system error IRQ.\n");
+	enable_irq(hose->serr_irq);
+}
+
+void pcibios_enable_timers(struct pci_channel *hose)
+{
+	if (hose->err_irq) {
+		init_timer(&hose->err_timer);
+		hose->err_timer.data = (unsigned long)hose;
+		hose->err_timer.function = pcibios_enable_err;
+	}
+
+	if (hose->serr_irq) {
+		init_timer(&hose->serr_timer);
+		hose->serr_timer.data = (unsigned long)hose;
+		hose->serr_timer.function = pcibios_enable_serr;
+	}
+}
+
+/*
+ * A simple handler for the regular PCI status errors, called from IRQ
+ * context.
+ */
+unsigned int pcibios_handle_status_errors(unsigned long addr,
+					  unsigned int status,
+					  struct pci_channel *hose)
+{
+	unsigned int cmd = 0;
+
+	if (status & PCI_STATUS_REC_MASTER_ABORT) {
+		printk(KERN_DEBUG "PCI: master abort, pc=0x%08lx\n", addr);
+		cmd |= PCI_STATUS_REC_MASTER_ABORT;
+	}
+
+	if (status & PCI_STATUS_REC_TARGET_ABORT) {
+		printk(KERN_DEBUG "PCI: target abort: ");
+		pcibios_report_status(PCI_STATUS_REC_TARGET_ABORT |
+				      PCI_STATUS_SIG_TARGET_ABORT |
+				      PCI_STATUS_REC_MASTER_ABORT, 1);
+		printk("\n");
+
+		cmd |= PCI_STATUS_REC_TARGET_ABORT;
+	}
+
+	if (status & (PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY)) {
+		printk(KERN_DEBUG "PCI: parity error detected: ");
+		pcibios_report_status(PCI_STATUS_PARITY |
+				      PCI_STATUS_DETECTED_PARITY, 1);
+		printk("\n");
+
+		cmd |= PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY;
+
+		/* Now back off of the IRQ for awhile */
+		if (hose->err_irq) {
+			disable_irq_nosync(hose->err_irq);
+			hose->err_timer.expires = jiffies + HZ;
+			add_timer(&hose->err_timer);
+		}
+	}
+
+	return cmd;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/fixups-dreamcast.c linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/fixups-dreamcast.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/fixups-dreamcast.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/fixups-dreamcast.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,7 @@ static void __init gapspci_fixup_resourc
 		/*
 		 * We also assume that dev->devfn == 0
 		 */
-		dev->resource[1].start	= p->io_resource->start  + 0x100;
+		dev->resource[1].start	= p->resources[0].start  + 0x100;
 		dev->resource[1].end	= dev->resource[1].start + 0x200 - 1;
 
 		/*
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/fixups-r7780rp.c linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/fixups-r7780rp.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/fixups-r7780rp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/fixups-r7780rp.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,15 +22,3 @@ int __init pcibios_map_platform_irq(stru
 {
 	return irq_tab[slot];
 }
-
-int pci_fixup_pcic(struct pci_channel *chan)
-{
-	pci_write_reg(chan, 0x000043ff, SH4_PCIINTM);
-	pci_write_reg(chan, 0x00000000, SH7780_PCIIBAR);
-	pci_write_reg(chan, 0x08000000, SH7780_PCICSCR0);
-	pci_write_reg(chan, 0x0000001b, SH7780_PCICSAR0);
-	pci_write_reg(chan, 0xfd000000, SH7780_PCICSCR1);
-	pci_write_reg(chan, 0x0000000f, SH7780_PCICSAR1);
-
-	return 0;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/fixups-rts7751r2d.c linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/fixups-rts7751r2d.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/fixups-rts7751r2d.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/fixups-rts7751r2d.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,7 +43,7 @@ int pci_fixup_pcic(struct pci_channel *c
 {
 	unsigned long bcr1, mcr;
 
-	bcr1 = ctrl_inl(SH7751_BCR1);
+	bcr1 = __raw_readl(SH7751_BCR1);
 	bcr1 |= 0x40080000;	/* Enable Bit 19 BREQEN, set PCIC to slave */
 	pci_write_reg(chan, bcr1, SH4_PCIBCR1);
 
@@ -54,7 +54,7 @@ int pci_fixup_pcic(struct pci_channel *c
 	pci_write_reg(chan, 0xfb900047, SH7751_PCICONF1);
 	pci_write_reg(chan, 0xab000001, SH7751_PCICONF4);
 
-	mcr = ctrl_inl(SH7751_MCR);
+	mcr = __raw_readl(SH7751_MCR);
 	mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
 	pci_write_reg(chan, mcr, SH4_PCIMCR);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/fixups-sdk7780.c linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/fixups-sdk7780.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/fixups-sdk7780.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/fixups-sdk7780.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,22 +31,3 @@ int __init pcibios_map_platform_irq(stru
 {
        return sdk7780_irq_tab[pin-1][slot];
 }
-int pci_fixup_pcic(struct pci_channel *chan)
-{
-	/* Enable all interrupts, so we know what to fix */
-	pci_write_reg(chan, 0x0000C3FF, SH7780_PCIIMR);
-
-	/* Set up standard PCI config registers */
-	pci_write_reg(chan, 0x08000000, SH7780_PCIMBAR0);	/* PCI */
-	pci_write_reg(chan, 0x08000000, SH4_PCILAR0);	/* SHwy */
-	pci_write_reg(chan, 0x07F00001, SH4_PCILSR0);	/* size 128M w/ MBAR */
-
-	pci_write_reg(chan, 0x00000000, SH7780_PCIMBAR1);
-	pci_write_reg(chan, 0x00000000, SH4_PCILAR1);
-	pci_write_reg(chan, 0x00000000, SH4_PCILSR1);
-
-	pci_write_reg(chan, 0xAB000801, SH7780_PCIIBAR);
-	pci_write_reg(chan, 0xA5000C01, SH4_PCICR);
-
-	return 0;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/fixups-se7751.c linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/fixups-se7751.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/fixups-se7751.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/fixups-se7751.c	2010-05-16 17:17:36.000000000 -0400
@@ -97,12 +97,12 @@ int pci_fixup_pcic(struct pci_channel *c
 	* meaning all calls go straight through... use BUG_ON to
 	* catch erroneous assumption.
 	*/
-	BUG_ON(chan->mem_resource->start != SH7751_PCI_MEMORY_BASE);
+	BUG_ON(chan->resources[1].start != SH7751_PCI_MEMORY_BASE);
 
-	PCIC_WRITE(SH7751_PCIMBR, chan->mem_resource->start);
+	PCIC_WRITE(SH7751_PCIMBR, chan->resources[1].start);
 
 	/* Set IOBR for window containing area specified in pci.h */
-	PCIC_WRITE(SH7751_PCIIOBR, (chan->io_resource->start & SH7751_PCIIOBR_MASK));
+	PCIC_WRITE(SH7751_PCIIOBR, (chan->resources[0].start & SH7751_PCIIOBR_MASK));
 
 	/* All done, may as well say so... */
 	printk("SH7751 PCI: Finished initialization of the PCI controller\n");
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/Makefile linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/Makefile
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,14 +1,14 @@
 #
 # Makefile for the PCI specific kernel interface routines under Linux.
 #
-obj-y					+= pci.o
+obj-y					+= common.o pci.o
 
 obj-$(CONFIG_CPU_SUBTYPE_SH7751)	+= pci-sh7751.o ops-sh4.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7751R)	+= pci-sh7751.o ops-sh4.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7763)	+= pci-sh7780.o ops-sh4.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7780)	+= pci-sh7780.o ops-sh4.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7785)	+= pci-sh7780.o ops-sh4.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7786)	+= ops-sh7786.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7786)	+= pcie-sh7786.o ops-sh7786.o
 obj-$(CONFIG_CPU_SH5)			+= pci-sh5.o ops-sh5.o
 
 obj-$(CONFIG_SH_DREAMCAST)		+= ops-dreamcast.o fixups-dreamcast.o \
@@ -25,4 +25,3 @@ obj-$(CONFIG_SH_TITAN)			+= fixups-titan
 obj-$(CONFIG_SH_LANDISK)		+= fixups-landisk.o
 obj-$(CONFIG_SH_LBOX_RE2)		+= fixups-rts7751r2d.o
 obj-$(CONFIG_SH_CAYMAN)			+= fixups-cayman.o
-obj-$(CONFIG_SH_URQUELL)		+= pcie-sh7786.o
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/ops-sh4.c linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/ops-sh4.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/ops-sh4.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/ops-sh4.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,7 @@
  * Direct access to PCI hardware...
  */
 #define CONFIG_CMD(bus, devfn, where) \
-	(P1SEG | (bus->number << 16) | (devfn << 8) | (where & ~3))
+	(0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
 
 static DEFINE_SPINLOCK(sh4_pci_lock);
 
@@ -102,34 +102,6 @@ struct pci_ops sh4_pci_ops = {
 	.write		= sh4_pci_write,
 };
 
-/*
- * Not really related to pci_ops, but it's common and not worth shoving
- * somewhere else for now..
- */
-int __init sh4_pci_check_direct(struct pci_channel *chan)
-{
-	/*
-	 * Check if configuration works.
-	 */
-	unsigned int tmp = pci_read_reg(chan, SH4_PCIPAR);
-
-	pci_write_reg(chan, P1SEG, SH4_PCIPAR);
-
-	if (pci_read_reg(chan, SH4_PCIPAR) == P1SEG) {
-		pci_write_reg(chan, tmp, SH4_PCIPAR);
-		printk(KERN_INFO "PCI: Using configuration type 1\n");
-		request_region(chan->reg_base + SH4_PCIPAR, 8,
-			       "PCI conf1");
-		return 0;
-	}
-
-	pci_write_reg(chan, tmp, SH4_PCIPAR);
-
-	printk(KERN_ERR "PCI: %s failed\n", __func__);
-
-	return -EINVAL;
-}
-
 int __attribute__((weak)) pci_fixup_pcic(struct pci_channel *chan)
 {
 	/* Nothing to do. */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci.c linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,15 +33,22 @@ static int pci_initialized;
 static void __devinit pcibios_scanbus(struct pci_channel *hose)
 {
 	static int next_busno;
+	static int need_domain_info;
 	struct pci_bus *bus;
 
 	bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
+	hose->bus = bus;
+
+	need_domain_info = need_domain_info || hose->index;
+	hose->need_domain_info = need_domain_info;
 	if (bus) {
 		next_busno = bus->subordinate + 1;
 		/* Don't allow 8-bit bus number overflow inside the hose -
 		   reserve some space for bridges. */
-		if (next_busno > 224)
+		if (next_busno > 224) {
 			next_busno = 0;
+			need_domain_info = 1;
+		}
 
 		pci_bus_size_bridges(bus);
 		pci_bus_assign_resources(bus);
@@ -51,10 +58,21 @@ static void __devinit pcibios_scanbus(st
 
 static DEFINE_MUTEX(pci_scan_mutex);
 
-void __devinit register_pci_controller(struct pci_channel *hose)
+int __devinit register_pci_controller(struct pci_channel *hose)
 {
-	request_resource(&iomem_resource, hose->mem_resource);
-	request_resource(&ioport_resource, hose->io_resource);
+	int i;
+
+	for (i = 0; i < hose->nr_resources; i++) {
+		struct resource *res = hose->resources + i;
+
+		if (res->flags & IORESOURCE_IO) {
+			if (request_resource(&ioport_resource, res) < 0)
+				goto out;
+		} else {
+			if (request_resource(&iomem_resource, res) < 0)
+				goto out;
+		}
+	}
 
 	*hose_tail = hose;
 	hose_tail = &hose->next;
@@ -68,6 +86,11 @@ void __devinit register_pci_controller(s
 	}
 
 	/*
+	 * Setup the ERR/PERR and SERR timers, if available.
+	 */
+	pcibios_enable_timers(hose);
+
+	/*
 	 * Scan the bus if it is register after the PCI subsystem
 	 * initialization.
 	 */
@@ -76,6 +99,15 @@ void __devinit register_pci_controller(s
 		pcibios_scanbus(hose);
 		mutex_unlock(&pci_scan_mutex);
 	}
+
+	return 0;
+
+out:
+	for (--i; i >= 0; i--)
+		release_resource(&hose->resources[i]);
+
+	printk(KERN_WARNING "Skipping PCI bus scan due to resource conflict\n");
+	return -1;
 }
 
 static int __init pcibios_init(void)
@@ -127,11 +159,13 @@ void __devinit pcibios_fixup_bus(struct
 {
 	struct pci_dev *dev = bus->self;
 	struct list_head *ln;
-	struct pci_channel *chan = bus->sysdata;
+	struct pci_channel *hose = bus->sysdata;
 
 	if (!dev) {
-		bus->resource[0] = chan->io_resource;
-		bus->resource[1] = chan->mem_resource;
+		int i;
+
+		for (i = 0; i < hose->nr_resources; i++)
+			bus->resource[i] = hose->resources + i;
 	}
 
 	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
@@ -148,34 +182,29 @@ void __devinit pcibios_fixup_bus(struct
  * addresses to be allocated in the 0x000-0x0ff region
  * modulo 0x400.
  */
-void pcibios_align_resource(void *data, struct resource *res,
-			    resource_size_t size, resource_size_t align)
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+				resource_size_t size, resource_size_t align)
 {
 	struct pci_dev *dev = data;
-	struct pci_channel *chan = dev->sysdata;
+	struct pci_channel *hose = dev->sysdata;
 	resource_size_t start = res->start;
 
 	if (res->flags & IORESOURCE_IO) {
-		if (start < PCIBIOS_MIN_IO + chan->io_resource->start)
-			start = PCIBIOS_MIN_IO + chan->io_resource->start;
+		if (start < PCIBIOS_MIN_IO + hose->resources[0].start)
+			start = PCIBIOS_MIN_IO + hose->resources[0].start;
 
 		/*
                  * Put everything into 0x00-0xff region modulo 0x400.
 		 */
-		if (start & 0x300) {
+		if (start & 0x300)
 			start = (start + 0x3ff) & ~0x3ff;
-			res->start = start;
-		}
-	} else if (res->flags & IORESOURCE_MEM) {
-		if (start < PCIBIOS_MIN_MEM + chan->mem_resource->start)
-			start = PCIBIOS_MIN_MEM + chan->mem_resource->start;
 	}
 
-	res->start = start;
+	return start;
 }
 
 void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			 struct resource *res)
+			     struct resource *res)
 {
 	struct pci_channel *hose = dev->sysdata;
 	unsigned long offset = 0;
@@ -189,9 +218,8 @@ void pcibios_resource_to_bus(struct pci_
 	region->end = res->end - offset;
 }
 
-void __devinit
-pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			struct pci_bus_region *region)
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			     struct pci_bus_region *region)
 {
 	struct pci_channel *hose = dev->sysdata;
 	unsigned long offset = 0;
@@ -274,6 +302,86 @@ char * __devinit pcibios_setup(char *str
 	return str;
 }
 
+static void __init
+pcibios_bus_report_status_early(struct pci_channel *hose,
+				int top_bus, int current_bus,
+				unsigned int status_mask, int warn)
+{
+	unsigned int pci_devfn;
+	u16 status;
+	int ret;
+
+	for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
+		if (PCI_FUNC(pci_devfn))
+			continue;
+		ret = early_read_config_word(hose, top_bus, current_bus,
+					     pci_devfn, PCI_STATUS, &status);
+		if (ret != PCIBIOS_SUCCESSFUL)
+			continue;
+		if (status == 0xffff)
+			continue;
+
+		early_write_config_word(hose, top_bus, current_bus,
+					pci_devfn, PCI_STATUS,
+					status & status_mask);
+		if (warn)
+			printk("(%02x:%02x: %04X) ", current_bus,
+			       pci_devfn, status);
+	}
+}
+
+/*
+ * We can't use pci_find_device() here since we are
+ * called from interrupt context.
+ */
+static void __init_refok
+pcibios_bus_report_status(struct pci_bus *bus, unsigned int status_mask,
+			  int warn)
+{
+	struct pci_dev *dev;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		u16 status;
+
+		/*
+		 * ignore host bridge - we handle
+		 * that separately
+		 */
+		if (dev->bus->number == 0 && dev->devfn == 0)
+			continue;
+
+		pci_read_config_word(dev, PCI_STATUS, &status);
+		if (status == 0xffff)
+			continue;
+
+		if ((status & status_mask) == 0)
+			continue;
+
+		/* clear the status errors */
+		pci_write_config_word(dev, PCI_STATUS, status & status_mask);
+
+		if (warn)
+			printk("(%s: %04X) ", pci_name(dev), status);
+	}
+
+	list_for_each_entry(dev, &bus->devices, bus_list)
+		if (dev->subordinate)
+			pcibios_bus_report_status(dev->subordinate, status_mask, warn);
+}
+
+void __init_refok pcibios_report_status(unsigned int status_mask, int warn)
+{
+	struct pci_channel *hose;
+
+	for (hose = hose_head; hose; hose = hose->next) {
+		if (unlikely(!hose->bus))
+			pcibios_bus_report_status_early(hose, hose_head->index,
+					hose->index, status_mask, warn);
+		else
+			pcibios_bus_report_status(hose->bus, status_mask, warn);
+	}
+}
+
 int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 			enum pci_mmap_state mmap_state, int write_combine)
 {
@@ -302,9 +410,15 @@ static void __iomem *ioport_map_pci(stru
 {
 	struct pci_channel *chan = dev->sysdata;
 
-	if (!chan->io_map_base)
+	if (unlikely(!chan->io_map_base)) {
 		chan->io_map_base = generic_io_base;
 
+		if (pci_domains_supported)
+			panic("To avoid data corruption io_map_base MUST be "
+			      "set with multiple PCI domains.");
+	}
+
+
 	return (void __iomem *)(chan->io_map_base + port);
 }
 
@@ -321,20 +435,9 @@ void __iomem *pci_iomap(struct pci_dev *
 
 	if (flags & IORESOURCE_IO)
 		return ioport_map_pci(dev, start, len);
-
-	/*
-	 * Presently the IORESOURCE_MEM case is a bit special, most
-	 * SH7751 style PCI controllers have PCI memory at a fixed
-	 * location in the address space where no remapping is desired.
-	 * With the IORESOURCE_MEM case more care has to be taken
-	 * to inhibit page table mapping for legacy cores, but this is
-	 * punted off to __ioremap().
-	 *					-- PFM.
-	 */
 	if (flags & IORESOURCE_MEM) {
 		if (flags & IORESOURCE_CACHEABLE)
 			return ioremap(start, len);
-
 		return ioremap_nocache(start, len);
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci-dreamcast.c linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci-dreamcast.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci-dreamcast.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci-dreamcast.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,25 +25,25 @@
 #include <asm/irq.h>
 #include <mach/pci.h>
 
-static struct resource gapspci_io_resource = {
-	.name	= "GAPSPCI IO",
-	.start	= GAPSPCI_BBA_CONFIG,
-	.end	= GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1,
-	.flags	= IORESOURCE_IO,
-};
-
-static struct resource gapspci_mem_resource = {
-	.name	= "GAPSPCI mem",
-	.start	= GAPSPCI_DMA_BASE,
-	.end	= GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1,
-	.flags	= IORESOURCE_MEM,
+static struct resource gapspci_resources[] = {
+	{
+		.name	= "GAPSPCI IO",
+		.start	= GAPSPCI_BBA_CONFIG,
+		.end	= GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1,
+		.flags	= IORESOURCE_IO,
+	},  {
+		.name	= "GAPSPCI mem",
+		.start	= GAPSPCI_DMA_BASE,
+		.end	= GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
 };
 
 static struct pci_channel dreamcast_pci_controller = {
 	.pci_ops	= &gapspci_pci_ops,
-	.io_resource	= &gapspci_io_resource,
+	.resources	= gapspci_resources,
+	.nr_resources	= ARRAY_SIZE(gapspci_resources),
 	.io_offset	= 0x00000000,
-	.mem_resource	= &gapspci_mem_resource,
 	.mem_offset	= 0x00000000,
 };
 
@@ -95,8 +95,6 @@ static int __init gapspci_init(void)
 	outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
 	outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
 
-	register_pci_controller(&dreamcast_pci_controller);
-
-	return 0;
+	return register_pci_controller(&dreamcast_pci_controller);
 }
 arch_initcall(gapspci_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pcie-sh7786.c linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pcie-sh7786.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pcie-sh7786.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pcie-sh7786.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Low-Level PCI Express Support for the SH7786
  *
- *  Copyright (C) 2009  Paul Mundt
+ *  Copyright (C) 2009 - 2010  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
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include "pcie-sh7786.h"
 #include <asm/sizes.h>
 
@@ -30,60 +31,84 @@ static struct sh7786_pcie_hwops {
 	int (*port_init_hw)(struct sh7786_pcie_port *port);
 } *sh7786_pcie_hwops;
 
-static struct resource sh7786_pci_32bit_mem_resources[] = {
+static struct resource sh7786_pci0_resources[] = {
 	{
-		.name	= "pci0_mem",
-		.start	= SH4A_PCIMEM_BASEA,
-		.end	= SH4A_PCIMEM_BASEA + SZ_64M - 1,
-		.flags	= IORESOURCE_MEM,
+		.name	= "PCIe0 IO",
+		.start	= 0xfd000000,
+		.end	= 0xfd000000 + SZ_8M - 1,
+		.flags	= IORESOURCE_IO,
 	}, {
-		.name	= "pci1_mem",
-		.start	= SH4A_PCIMEM_BASEA1,
-		.end	= SH4A_PCIMEM_BASEA1 + SZ_64M - 1,
-		.flags	= IORESOURCE_MEM,
+		.name	= "PCIe0 MEM 0",
+		.start	= 0xc0000000,
+		.end	= 0xc0000000 + SZ_512M - 1,
+		.flags	= IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
 	}, {
-		.name	= "pci2_mem",
-		.start	= SH4A_PCIMEM_BASEA2,
-		.end	= SH4A_PCIMEM_BASEA2 + SZ_64M - 1,
+		.name	= "PCIe0 MEM 1",
+		.start	= 0x10000000,
+		.end	= 0x10000000 + SZ_64M - 1,
 		.flags	= IORESOURCE_MEM,
+	}, {
+		.name	= "PCIe0 MEM 2",
+		.start	= 0xfe100000,
+		.end	= 0xfe100000 + SZ_1M - 1,
 	},
 };
 
-static struct resource sh7786_pci_29bit_mem_resource = {
-	.start	= SH4A_PCIMEM_BASE,
-	.end	= SH4A_PCIMEM_BASE + SZ_64M - 1,
-	.flags	= IORESOURCE_MEM,
+static struct resource sh7786_pci1_resources[] = {
+	{
+		.name	= "PCIe1 IO",
+		.start	= 0xfd800000,
+		.end	= 0xfd800000 + SZ_8M - 1,
+		.flags	= IORESOURCE_IO,
+	}, {
+		.name	= "PCIe1 MEM 0",
+		.start	= 0xa0000000,
+		.end	= 0xa0000000 + SZ_512M - 1,
+		.flags	= IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+	}, {
+		.name	= "PCIe1 MEM 1",
+		.start	= 0x30000000,
+		.end	= 0x30000000 + SZ_256M - 1,
+		.flags	= IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+	}, {
+		.name	= "PCIe1 MEM 2",
+		.start	= 0xfe300000,
+		.end	= 0xfe300000 + SZ_1M - 1,
+	},
 };
 
-static struct resource sh7786_pci_io_resources[] = {
+static struct resource sh7786_pci2_resources[] = {
 	{
-		.name	= "pci0_io",
-		.start	= SH4A_PCIIO_BASE,
-		.end	= SH4A_PCIIO_BASE + SZ_8M - 1,
-		.flags	= IORESOURCE_IO,
+		.name	= "PCIe2 IO",
+		.start	= 0xfc800000,
+		.end	= 0xfc800000 + SZ_4M - 1,
 	}, {
-		.name	= "pci1_io",
-		.start	= SH4A_PCIIO_BASE1,
-		.end	= SH4A_PCIIO_BASE1 + SZ_8M - 1,
-		.flags	= IORESOURCE_IO,
+		.name	= "PCIe2 MEM 0",
+		.start	= 0x80000000,
+		.end	= 0x80000000 + SZ_512M - 1,
+		.flags	= IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
 	}, {
-		.name	= "pci2_io",
-		.start	= SH4A_PCIIO_BASE2,
-		.end	= SH4A_PCIIO_BASE2 + SZ_4M - 1,
-		.flags	= IORESOURCE_IO,
+		.name	= "PCIe2 MEM 1",
+		.start	= 0x20000000,
+		.end	= 0x20000000 + SZ_256M - 1,
+		.flags	= IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+	}, {
+		.name	= "PCIe2 MEM 2",
+		.start	= 0xfcd00000,
+		.end	= 0xfcd00000 + SZ_1M - 1,
 	},
 };
 
 extern struct pci_ops sh7786_pci_ops;
 
-#define DEFINE_CONTROLLER(start, idx)				\
-{								\
-	.pci_ops	= &sh7786_pci_ops,			\
-	.reg_base	= start,				\
-	/* mem_resource filled in at probe time */		\
-	.mem_offset	= 0,					\
-	.io_resource	= &sh7786_pci_io_resources[idx],	\
-	.io_offset	= 0,					\
+#define DEFINE_CONTROLLER(start, idx)					\
+{									\
+	.pci_ops	= &sh7786_pci_ops,				\
+	.resources	= sh7786_pci##idx##_resources,			\
+	.nr_resources	= ARRAY_SIZE(sh7786_pci##idx##_resources),	\
+	.reg_base	= start,					\
+	.mem_offset	= 0,						\
+	.io_offset	= 0,						\
 }
 
 static struct pci_channel sh7786_pci_channels[] = {
@@ -180,7 +205,9 @@ static int pcie_init(struct sh7786_pcie_
 {
 	struct pci_channel *chan = port->hose;
 	unsigned int data;
-	int ret;
+	phys_addr_t memphys;
+	size_t memsize;
+	int ret, i;
 
 	/* Begin initialization */
 	pci_write_reg(chan, 0, SH4A_PCIETCTLR);
@@ -203,15 +230,24 @@ static int pcie_init(struct sh7786_pcie_
 	data |= PCI_CAP_ID_EXP;
 	pci_write_reg(chan, data, SH4A_PCIEEXPCAP0);
 
-	/* Enable x4 link width and extended sync. */
+	/* Enable data link layer active state reporting */
+	pci_write_reg(chan, PCI_EXP_LNKCAP_DLLLARC, SH4A_PCIEEXPCAP3);
+
+	/* Enable extended sync and ASPM L0s support */
 	data = pci_read_reg(chan, SH4A_PCIEEXPCAP4);
-	data &= ~(PCI_EXP_LNKSTA_NLW << 16);
-	data |= (1 << 22) | PCI_EXP_LNKCTL_ES;
+	data &= ~PCI_EXP_LNKCTL_ASPMC;
+	data |= PCI_EXP_LNKCTL_ES | 1;
 	pci_write_reg(chan, data, SH4A_PCIEEXPCAP4);
 
+	/* Write out the physical slot number */
+	data = pci_read_reg(chan, SH4A_PCIEEXPCAP5);
+	data &= ~PCI_EXP_SLTCAP_PSN;
+	data |= (port->index + 1) << 19;
+	pci_write_reg(chan, data, SH4A_PCIEEXPCAP5);
+
 	/* Set the completion timer timeout to the maximum 32ms. */
 	data = pci_read_reg(chan, SH4A_PCIETLCTLR);
-	data &= ~0xffff;
+	data &= ~0x3f00;
 	data |= 0x32 << 8;
 	pci_write_reg(chan, data, SH4A_PCIETLCTLR);
 
@@ -224,6 +260,33 @@ static int pcie_init(struct sh7786_pcie_
 	data |= (0xff << 16);
 	pci_write_reg(chan, data, SH4A_PCIEMACCTLR);
 
+	memphys = __pa(memory_start);
+	memsize = roundup_pow_of_two(memory_end - memory_start);
+
+	/*
+	 * If there's more than 512MB of memory, we need to roll over to
+	 * LAR1/LAMR1.
+	 */
+	if (memsize > SZ_512M) {
+		__raw_writel(memphys + SZ_512M, chan->reg_base + SH4A_PCIELAR1);
+		__raw_writel(((memsize - SZ_512M) - SZ_256) | 1,
+			     chan->reg_base + SH4A_PCIELAMR1);
+		memsize = SZ_512M;
+	} else {
+		/*
+		 * Otherwise just zero it out and disable it.
+		 */
+		__raw_writel(0, chan->reg_base + SH4A_PCIELAR1);
+		__raw_writel(0, chan->reg_base + SH4A_PCIELAMR1);
+	}
+
+	/*
+	 * LAR0/LAMR0 covers up to the first 512MB, which is enough to
+	 * cover all of lowmem on most platforms.
+	 */
+	__raw_writel(memphys, chan->reg_base + SH4A_PCIELAR0);
+	__raw_writel((memsize - SZ_256) | 1, chan->reg_base + SH4A_PCIELAMR0);
+
 	/* Finish initialization */
 	data = pci_read_reg(chan, SH4A_PCIETCTLR);
 	data |= 0x1;
@@ -243,10 +306,14 @@ static int pcie_init(struct sh7786_pcie_
 	if (unlikely(ret != 0))
 		return -ENODEV;
 
-	pci_write_reg(chan, 0x00100007, SH4A_PCIEPCICONF1);
+	data = pci_read_reg(chan, SH4A_PCIEPCICONF1);
+	data &= ~(PCI_STATUS_DEVSEL_MASK << 16);
+	data |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+		(PCI_STATUS_CAP_LIST | PCI_STATUS_DEVSEL_FAST) << 16;
+	pci_write_reg(chan, data, SH4A_PCIEPCICONF1);
+
 	pci_write_reg(chan, 0x80888000, SH4A_PCIETXVC0DCTLR);
 	pci_write_reg(chan, 0x00222000, SH4A_PCIERXVC0DCTLR);
-	pci_write_reg(chan, 0x000050A0, SH4A_PCIEEXPCAP2);
 
 	wmb();
 
@@ -254,15 +321,32 @@ static int pcie_init(struct sh7786_pcie_
 	printk(KERN_NOTICE "PCI: PCIe#%d link width %d\n",
 	       port->index, (data >> 20) & 0x3f);
 
-	pci_write_reg(chan, 0x007c0000, SH4A_PCIEPAMR0);
-	pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH0);
-	pci_write_reg(chan, 0x00000000, SH4A_PCIEPARL0);
-	pci_write_reg(chan, 0x80000100, SH4A_PCIEPTCTLR0);
 
-	pci_write_reg(chan, 0x03fc0000, SH4A_PCIEPAMR2);
-	pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH2);
-	pci_write_reg(chan, 0x00000000, SH4A_PCIEPARL2);
-	pci_write_reg(chan, 0x80000000, SH4A_PCIEPTCTLR2);
+	for (i = 0; i < chan->nr_resources; i++) {
+		struct resource *res = chan->resources + i;
+		resource_size_t size;
+		u32 enable_mask;
+
+		pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(i));
+
+		size = resource_size(res);
+
+		/*
+		 * The PAMR mask is calculated in units of 256kB, which
+		 * keeps things pretty simple.
+		 */
+		__raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18,
+			     chan->reg_base + SH4A_PCIEPAMR(i));
+
+		pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH(i));
+		pci_write_reg(chan, 0x00000000, SH4A_PCIEPARL(i));
+
+		enable_mask = MASK_PARE;
+		if (res->flags & IORESOURCE_IO)
+			enable_mask |= MASK_SPC;
+
+		pci_write_reg(chan, enable_mask, SH4A_PCIEPTCTLR(i));
+	}
 
 	return 0;
 }
@@ -296,9 +380,7 @@ static int __devinit sh7786_pcie_init_hw
 	if (unlikely(ret < 0))
 		return ret;
 
-	register_pci_controller(port->hose);
-
-	return 0;
+	return register_pci_controller(port->hose);
 }
 
 static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = {
@@ -332,17 +414,7 @@ static int __init sh7786_pcie_init(void)
 
 		port->index		= i;
 		port->hose		= sh7786_pci_channels + i;
-		port->hose->io_map_base	= port->hose->io_resource->start;
-
-		/*
-		 * Check if we are booting in 29 or 32-bit mode
-		 *
-		 * 32-bit mode provides each controller with its own
-		 * memory window, while 29-bit mode uses a shared one.
-		 */
-		port->hose->mem_resource = test_mode_pin(MODE_PIN10) ?
-			&sh7786_pci_32bit_mem_resources[i] :
-			&sh7786_pci_29bit_mem_resource;
+		port->hose->io_map_base	= port->hose->resources[0].start;
 
 		ret |= sh7786_pcie_hwops->port_init_hw(port);
 	}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pcie-sh7786.h linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pcie-sh7786.h
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pcie-sh7786.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pcie-sh7786.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,47 +30,9 @@
  * for other(Max Payload Size=4096B,PCIIO_SIZE=8M)
  */
 
-/* PCI0-0: PCI I/O space */
-#define SH4A_PCIIO_BASE		0xFD000000	/* PCI I/O for controller 0 */
-#define SH4A_PCIIO_BASE1	0xFD800000	/* PCI I/O for controller 1 (Rev1.14)*/
-#define SH4A_PCIIO_BASE2	0xFC800000	/* PCI I/O for controller 2 (Rev1.171)*/
-
-#define SH4A_PCIIO_SIZE64	0x00010000	/* PLX allows only 64K */
-#define SH4A_PCIIO_SIZE		0x00800000	/* 8M */
-#define SH4A_PCIIO_SIZE2	0x00400000	/* 4M (Rev1.171)*/
-
-/* PCI0-1: PCI memory space 29-bit address */
-#define SH4A_PCIMEM_BASE	0x10000000
-#define SH4A_PCIMEM_SIZE	0x04000000	/* 64M */
-
-/* PCI0-2: PCI memory space 32-bit address */
-#define SH4A_PCIMEM_BASEA	0xC0000000	/*  for controller 0 */
-#define SH4A_PCIMEM_BASEA1	0xA0000000	/*  for controller 1 (Rev1.14)*/
-#define SH4A_PCIMEM_BASEA2	0x80000000	/*  for controller 2 (Rev1.171)*/
-#define SH4A_PCIMEM_SIZEA	0x20000000	/* 512M */
-
 /* PCI0: PCI memory target transfer 32-bit address translation value(Rev1.11T)*/
 #define SH4A_PCIBMSTR_TRANSLATION	0x20000000
 
-#define SH4A_PCI_DEVICE_ID		0x0002
-#define SH4A_PCI_VENDOR_ID		0x1912
-
-// PCI compatible 000-03f
-#define PCI_CMD		0x004
-#define PCI_RID		0x008
-#define PCI_IBAR	0x010
-#define PCI_MBAR0	0x014
-#define PCI_MBAR1	0x018
-
-/* PCI power management/MSI/capablity 040-0ff */
-/* PCIE extended 100-fff */
-
-/* SH7786 device identification */	// Rev1.171
-#define SH4A_PVR		(0xFF000030)
-#define SH4A_PVR_SHX3		(0x10400000)
-#define SH4A_PRR		(0xFF000044)
-#define SH4A_PRR_SH7786		(0x00000400)	// Rev1.171
-
 /*	SPVCR0		*/
 #define	SH4A_PCIEVCR0		(0x000000)	/* R - 0x0000 0000 32 */
 #define		BITS_TOP_MB	(24)
@@ -350,23 +312,23 @@
 #define	SH4A_PCIECSAR5		(0x0202B4)	/* R/W R/W 0x0000 0000 32 */
 #define	SH4A_PCIESTCTLR5	(0x0202B8)	/* R/W R/W 0x0000 0000 32 */
 
-/*	PCIEPARL0	*/
-#define	SH4A_PCIEPARL0		(0x020400)	/* R/W R/W 0x0000 0000 32 */
+/*	PCIEPARL	*/
+#define	SH4A_PCIEPARL(x)	(0x020400 + ((x) * 0x20)) /* R/W R/W 0x0000 0000 32 */
 #define		BITS_PAL	(18)
 #define		MASK_PAL	(0x3fff<<BITS_PAL)
 
-/*	PCIEPARH0	*/
-#define	SH4A_PCIEPARH0		(0x020404)	/* R/W R/W 0x0000 0000 32 */
+/*	PCIEPARH	*/
+#define	SH4A_PCIEPARH(x)	(0x020404 + ((x) * 0x20)) /* R/W R/W 0x0000 0000 32 */
 #define		BITS_PAH	(0)
 #define		MASK_PAH	(0xffffffff<<BITS_PAH)
 
-/*	PCIEPAMR0	 */
-#define	SH4A_PCIEPAMR0		(0x020408)	/* R/W R/W 0x0000 0000 32 */
+/*	PCIEPAMR	 */
+#define	SH4A_PCIEPAMR(x)	(0x020408 + ((x) * 0x20)) /* R/W R/W 0x0000 0000 32 */
 #define		BITS_PAM	(18)
 #define		MASK_PAM	(0x3fff<<BITS_PAM)
 
-/*	PCIEPTCTLR0	*/
-#define	SH4A_PCIEPTCTLR0	(0x02040C)	/* R/W R/W 0x0000 0000 32 */
+/*	PCIEPTCTLR	*/
+#define SH4A_PCIEPTCTLR(x)	(0x02040C + ((x) * 0x20))
 #define		BITS_PARE	(31)
 #define		MASK_PARE	(0x1<<BITS_PARE)
 #define		BITS_TC		(20)
@@ -378,26 +340,6 @@
 #define		BITS_SPC	(8)
 #define		MASK_SPC	(0x1<<BITS_SPC)
 
-#define	SH4A_PCIEPARL1		(0x020420)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPARH1		(0x020424)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPAMR1		(0x020428)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPTCTLR1	(0x02042C)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPARL2		(0x020440)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPARH2		(0x020444)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPAMR2		(0x020448)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPTCTLR2	(0x02044C)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPARL3		(0x020460)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPARH3		(0x020464)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPAMR3		(0x020468)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPTCTLR3	(0x02046C)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPARL4		(0x020480)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPARH4		(0x020484)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPAMR4		(0x020488)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPTCTLR4	(0x02048C)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPARL5		(0x0204A0)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPARH5		(0x0204A4)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPAMR5		(0x0204A8)	/* R/W R/W 0x0000 0000 32 */
-#define	SH4A_PCIEPTCTLR5	(0x0204AC)	/* R/W R/W 0x0000 0000 32 */
 #define	SH4A_PCIEDMAOR		(0x021000)	/* R/W R/W 0x0000 0000 32 */
 #define	SH4A_PCIEDMSAR0		(0x021100)	/* R/W R/W 0x0000 0000 32 */
 #define	SH4A_PCIEDMSAHR0	(0x021104)	/* R/W R/W 0x0000 0000 32 */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci-sh4.h linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci-sh4.h
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci-sh4.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci-sh4.h	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,17 @@
   #define SH4_PCIINT_MWPD	  0x00000002	/* Master Write PERR Detect */
   #define SH4_PCIINT_MRPD	  0x00000001	/* Master Read PERR Detect */
 #define SH4_PCIINTM		0x118		/* PCI Interrupt Mask */
+  #define SH4_PCIINTM_TTADIM	  BIT(14)	/* Target-target abort interrupt */
+  #define SH4_PCIINTM_TMTOIM	  BIT(9)	/* Target retry timeout */
+  #define SH4_PCIINTM_MDEIM	  BIT(8)	/* Master function disable error */
+  #define SH4_PCIINTM_APEDIM	  BIT(7)	/* Address parity error detection */
+  #define SH4_PCIINTM_SDIM	  BIT(6)	/* SERR detection */
+  #define SH4_PCIINTM_DPEITWM	  BIT(5)	/* Data parity error for target write */
+  #define SH4_PCIINTM_PEDITRM	  BIT(4)	/* PERR detection for target read */
+  #define SH4_PCIINTM_TADIMM	  BIT(3)	/* Target abort for master */
+  #define SH4_PCIINTM_MADIMM	  BIT(2)	/* Master abort for master */
+  #define SH4_PCIINTM_MWPDIM	  BIT(1)	/* Master write data parity error */
+  #define SH4_PCIINTM_MRDPEIM	  BIT(0)	/* Master read data parity error */
 #define SH4_PCIALR		0x11C		/* Error Address Register */
 #define SH4_PCICLR		0x120		/* Error Command/Data */
   #define SH4_PCICLR_MPIO	  0x80000000
@@ -61,7 +72,7 @@
 #define SH4_PCIAINT		0x130		/* Arbiter Interrupt Register */
   #define SH4_PCIAINT_MBKN	  0x00002000	/* Master Broken Interrupt */
   #define SH4_PCIAINT_TBTO	  0x00001000	/* Target Bus Time Out */
-  #define SH4_PCIAINT_MBTO	  0x00001000	/* Master Bus Time Out */
+  #define SH4_PCIAINT_MBTO	  0x00000800	/* Master Bus Time Out */
   #define SH4_PCIAINT_TABT	  0x00000008	/* Target Abort */
   #define SH4_PCIAINT_MABT	  0x00000004	/* Master Abort */
   #define SH4_PCIAINT_RDPE	  0x00000002	/* Read Data Parity Error */
@@ -151,7 +162,6 @@
 
 /* arch/sh/kernel/drivers/pci/ops-sh4.c */
 extern struct pci_ops sh4_pci_ops;
-int sh4_pci_check_direct(struct pci_channel *chan);
 int pci_fixup_pcic(struct pci_channel *chan);
 
 struct sh4_pci_address_space {
@@ -167,13 +177,13 @@ struct sh4_pci_address_map {
 static inline void pci_write_reg(struct pci_channel *chan,
 				 unsigned long val, unsigned long reg)
 {
-	ctrl_outl(val, chan->reg_base + reg);
+	__raw_writel(val, chan->reg_base + reg);
 }
 
 static inline unsigned long pci_read_reg(struct pci_channel *chan,
 					 unsigned long reg)
 {
-	return ctrl_inl(chan->reg_base + reg);
+	return __raw_readl(chan->reg_base + reg);
 }
 
 #endif /* __PCI_SH4_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci-sh5.c linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci-sh5.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci-sh5.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci-sh5.c	2010-05-16 17:17:36.000000000 -0400
@@ -89,14 +89,13 @@ static irqreturn_t pcish5_serr_irq(int i
 	return IRQ_NONE;
 }
 
-static struct resource sh5_io_resource = { /* place holder */ };
-static struct resource sh5_mem_resource = { /* place holder */ };
+static struct resource sh5_pci_resources[2];
 
 static struct pci_channel sh5pci_controller = {
 	.pci_ops		= &sh5_pci_ops,
-	.mem_resource		= &sh5_mem_resource,
+	.resources		= sh5_pci_resources,
+	.nr_resources		= ARRAY_SIZE(sh5_pci_resources),
 	.mem_offset		= 0x00000000,
-	.io_resource		= &sh5_io_resource,
 	.io_offset		= 0x00000000,
 };
 
@@ -210,14 +209,12 @@ static int __init sh5pci_init(void)
         SH5PCI_WRITE(AINTM, ~0);
         SH5PCI_WRITE(PINTM, ~0);
 
-	sh5_io_resource.start = PCI_IO_AREA;
-	sh5_io_resource.end = PCI_IO_AREA + 0x10000;
-
-	sh5_mem_resource.start = memStart;
-	sh5_mem_resource.end = memStart + memSize;
+	sh5_pci_resources[0].start = PCI_IO_AREA;
+	sh5_pci_resources[0].end = PCI_IO_AREA + 0x10000;
 
-	register_pci_controller(&sh5pci_controller);
+	sh5_pci_resources[1].start = memStart;
+	sh5_pci_resources[1].end = memStart + memSize;
 
-	return 0;
+	return register_pci_controller(&sh5pci_controller);
 }
 arch_initcall(sh5pci_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci-sh5.h linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci-sh5.h
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci-sh5.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci-sh5.h	2010-05-16 17:17:36.000000000 -0400
@@ -86,14 +86,14 @@ extern unsigned long pcicr_virt;
 /* #define PCISH5_VCR_REG(x)                ( SH5PCI_VCR_BASE (PCISH5_VCR_##x)) */
 
 /* Write I/O functions */
-#define SH5PCI_WRITE(reg,val)        ctrl_outl((u32)(val),PCISH5_ICR_REG(reg))
-#define SH5PCI_WRITE_SHORT(reg,val)  ctrl_outw((u16)(val),PCISH5_ICR_REG(reg))
-#define SH5PCI_WRITE_BYTE(reg,val)   ctrl_outb((u8)(val),PCISH5_ICR_REG(reg))
+#define SH5PCI_WRITE(reg,val)        __raw_writel((u32)(val),PCISH5_ICR_REG(reg))
+#define SH5PCI_WRITE_SHORT(reg,val)  __raw_writew((u16)(val),PCISH5_ICR_REG(reg))
+#define SH5PCI_WRITE_BYTE(reg,val)   __raw_writeb((u8)(val),PCISH5_ICR_REG(reg))
 
 /* Read I/O functions */
-#define SH5PCI_READ(reg)             ctrl_inl(PCISH5_ICR_REG(reg))
-#define SH5PCI_READ_SHORT(reg)       ctrl_inw(PCISH5_ICR_REG(reg))
-#define SH5PCI_READ_BYTE(reg)        ctrl_inb(PCISH5_ICR_REG(reg))
+#define SH5PCI_READ(reg)             __raw_readl(PCISH5_ICR_REG(reg))
+#define SH5PCI_READ_SHORT(reg)       __raw_readw(PCISH5_ICR_REG(reg))
+#define SH5PCI_READ_BYTE(reg)        __raw_readb(PCISH5_ICR_REG(reg))
 
 /* Set PCI config bits */
 #define SET_CONFIG_BITS(bus,devfn,where)  ((((bus) << 16) | ((devfn) << 8) | ((where) & ~3)) | 0x80000000)
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci-sh7751.c linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci-sh7751.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci-sh7751.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci-sh7751.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/io.h>
 #include "pci-sh4.h"
 #include <asm/addrspace.h>
+#include <asm/sizes.h>
 
 static int __init __area_sdram_check(struct pci_channel *chan,
 				     unsigned int area)
@@ -44,25 +45,25 @@ static int __init __area_sdram_check(str
 	return 1;
 }
 
-static struct resource sh7751_io_resource = {
-	.name	= "SH7751_IO",
-	.start	= SH7751_PCI_IO_BASE,
-	.end	= SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
-	.flags	= IORESOURCE_IO
-};
-
-static struct resource sh7751_mem_resource = {
-	.name	= "SH7751_mem",
-	.start	= SH7751_PCI_MEMORY_BASE,
-	.end	= SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
-	.flags	= IORESOURCE_MEM
+static struct resource sh7751_pci_resources[] = {
+	{
+		.name	= "SH7751_IO",
+		.start	= 0x1000,
+		.end	= SZ_4M - 1,
+		.flags	= IORESOURCE_IO
+	}, {
+		.name	= "SH7751_mem",
+		.start	= SH7751_PCI_MEMORY_BASE,
+		.end	= SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
+		.flags	= IORESOURCE_MEM
+	},
 };
 
 static struct pci_channel sh7751_pci_controller = {
 	.pci_ops	= &sh4_pci_ops,
-	.mem_resource	= &sh7751_mem_resource,
+	.resources	= sh7751_pci_resources,
+	.nr_resources	= ARRAY_SIZE(sh7751_pci_resources),
 	.mem_offset	= 0x00000000,
-	.io_resource	= &sh7751_io_resource,
 	.io_offset	= 0x00000000,
 	.io_map_base	= SH7751_PCI_IO_BASE,
 };
@@ -79,7 +80,6 @@ static int __init sh7751_pci_init(void)
 	struct pci_channel *chan = &sh7751_pci_controller;
 	unsigned int id;
 	u32 word, reg;
-	int ret;
 
 	printk(KERN_NOTICE "PCI: Starting intialization.\n");
 
@@ -93,13 +93,10 @@ static int __init sh7751_pci_init(void)
 		return -ENODEV;
 	}
 
-	if ((ret = sh4_pci_check_direct(chan)) != 0)
-		return ret;
-
 	/* Set the BCR's to enable PCI access */
-	reg = ctrl_inl(SH7751_BCR1);
+	reg = __raw_readl(SH7751_BCR1);
 	reg |= 0x80000;
-	ctrl_outl(reg, SH7751_BCR1);
+	__raw_writel(reg, SH7751_BCR1);
 
 	/* Turn the clocks back on (not done in reset)*/
 	pci_write_reg(chan, 0, SH4_PCICLKR);
@@ -132,13 +129,13 @@ static int __init sh7751_pci_init(void)
 	/* Set the local 16MB PCI memory space window to
 	 * the lowest PCI mapped address
 	 */
-	word = chan->mem_resource->start & SH4_PCIMBR_MASK;
+	word = chan->resources[1].start & SH4_PCIMBR_MASK;
 	pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word);
 	pci_write_reg(chan, word , SH4_PCIMBR);
 
 	/* Make sure the MSB's of IO window are set to access PCI space
 	 * correctly */
-	word = chan->io_resource->start & SH4_PCIIOBR_MASK;
+	word = chan->resources[0].start & SH4_PCIIOBR_MASK;
 	pr_debug("PCI: Setting upper bits of IO window to 0x%x\n", word);
 	pci_write_reg(chan, word, SH4_PCIIOBR);
 
@@ -159,13 +156,13 @@ static int __init sh7751_pci_init(void)
 		return -1;
 
 	/* configure the wait control registers */
-	word = ctrl_inl(SH7751_WCR1);
+	word = __raw_readl(SH7751_WCR1);
 	pci_write_reg(chan, word, SH4_PCIWCR1);
-	word = ctrl_inl(SH7751_WCR2);
+	word = __raw_readl(SH7751_WCR2);
 	pci_write_reg(chan, word, SH4_PCIWCR2);
-	word = ctrl_inl(SH7751_WCR3);
+	word = __raw_readl(SH7751_WCR3);
 	pci_write_reg(chan, word, SH4_PCIWCR3);
-	word = ctrl_inl(SH7751_MCR);
+	word = __raw_readl(SH7751_MCR);
 	pci_write_reg(chan, word, SH4_PCIMCR);
 
 	/* NOTE: I'm ignoring the PCI error IRQs for now..
@@ -180,8 +177,6 @@ static int __init sh7751_pci_init(void)
 	word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM;
 	pci_write_reg(chan, word, SH4_PCICR);
 
-	register_pci_controller(chan);
-
-	return 0;
+	return register_pci_controller(chan);
 }
 arch_initcall(sh7751_pci_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci-sh7780.c linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci-sh7780.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci-sh7780.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci-sh7780.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Low-Level PCI Support for the SH7780
  *
- *  Copyright (C) 2005 - 2009  Paul Mundt
+ *  Copyright (C) 2005 - 2010  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
@@ -11,52 +11,240 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/irq.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
+#include <linux/log2.h>
 #include "pci-sh4.h"
+#include <asm/mmu.h>
+#include <asm/sizes.h>
 
-static struct resource sh7785_io_resource = {
-	.name	= "SH7785_IO",
-	.start	= SH7780_PCI_IO_BASE,
-	.end	= SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1,
-	.flags	= IORESOURCE_IO
-};
-
-static struct resource sh7785_mem_resource = {
-	.name	= "SH7785_mem",
-	.start	= SH7780_PCI_MEMORY_BASE,
-	.end	= SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
-	.flags	= IORESOURCE_MEM
+static struct resource sh7785_pci_resources[] = {
+	{
+		.name	= "PCI IO",
+		.start	= 0x1000,
+		.end	= SZ_4M - 1,
+		.flags	= IORESOURCE_IO,
+	}, {
+		.name	= "PCI MEM 0",
+		.start	= 0xfd000000,
+		.end	= 0xfd000000 + SZ_16M - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.name	= "PCI MEM 1",
+		.start	= 0x10000000,
+		.end	= 0x10000000 + SZ_64M - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		/*
+		 * 32-bit only resources must be last.
+		 */
+		.name	= "PCI MEM 2",
+		.start	= 0xc0000000,
+		.end	= 0xc0000000 + SZ_512M - 1,
+		.flags	= IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+	},
 };
 
 static struct pci_channel sh7780_pci_controller = {
 	.pci_ops	= &sh4_pci_ops,
-	.mem_resource	= &sh7785_mem_resource,
-	.mem_offset	= 0x00000000,
-	.io_resource	= &sh7785_io_resource,
-	.io_offset	= 0x00000000,
-	.io_map_base	= SH7780_PCI_IO_BASE,
+	.resources	= sh7785_pci_resources,
+	.nr_resources	= ARRAY_SIZE(sh7785_pci_resources),
+	.io_offset	= 0,
+	.mem_offset	= 0,
+	.io_map_base	= 0xfe200000,
+	.serr_irq	= evt2irq(0xa00),
+	.err_irq	= evt2irq(0xaa0),
 };
 
-static struct sh4_pci_address_map sh7780_pci_map = {
-	.window0	= {
-#if defined(CONFIG_32BIT)
-		.base	= SH7780_32BIT_DDR_BASE_ADDR,
-		.size	= 0x40000000,
-#else
-		.base	= SH7780_CS0_BASE_ADDR,
-		.size	= 0x20000000,
-#endif
-	},
+struct pci_errors {
+	unsigned int	mask;
+	const char	*str;
+} pci_arbiter_errors[] = {
+	{ SH4_PCIAINT_MBKN,	"master broken" },
+	{ SH4_PCIAINT_TBTO,	"target bus time out" },
+	{ SH4_PCIAINT_MBTO,	"master bus time out" },
+	{ SH4_PCIAINT_TABT,	"target abort" },
+	{ SH4_PCIAINT_MABT,	"master abort" },
+	{ SH4_PCIAINT_RDPE,	"read data parity error" },
+	{ SH4_PCIAINT_WDPE,	"write data parity error" },
+}, pci_interrupt_errors[] = {
+	{ SH4_PCIINT_MLCK,	"master lock error" },
+	{ SH4_PCIINT_TABT,	"target-target abort" },
+	{ SH4_PCIINT_TRET,	"target retry time out" },
+	{ SH4_PCIINT_MFDE,	"master function disable erorr" },
+	{ SH4_PCIINT_PRTY,	"address parity error" },
+	{ SH4_PCIINT_SERR,	"SERR" },
+	{ SH4_PCIINT_TWDP,	"data parity error for target write" },
+	{ SH4_PCIINT_TRDP,	"PERR detected for target read" },
+	{ SH4_PCIINT_MTABT,	"target abort for master" },
+	{ SH4_PCIINT_MMABT,	"master abort for master" },
+	{ SH4_PCIINT_MWPD,	"master write data parity error" },
+	{ SH4_PCIINT_MRPD,	"master read data parity error" },
 };
 
+static irqreturn_t sh7780_pci_err_irq(int irq, void *dev_id)
+{
+	struct pci_channel *hose = dev_id;
+	unsigned long addr;
+	unsigned int status;
+	unsigned int cmd;
+	int i;
+
+	addr = __raw_readl(hose->reg_base + SH4_PCIALR);
+
+	/*
+	 * Handle status errors.
+	 */
+	status = __raw_readw(hose->reg_base + PCI_STATUS);
+	if (status & (PCI_STATUS_PARITY |
+		      PCI_STATUS_DETECTED_PARITY |
+		      PCI_STATUS_SIG_TARGET_ABORT |
+		      PCI_STATUS_REC_TARGET_ABORT |
+		      PCI_STATUS_REC_MASTER_ABORT)) {
+		cmd = pcibios_handle_status_errors(addr, status, hose);
+		if (likely(cmd))
+			__raw_writew(cmd, hose->reg_base + PCI_STATUS);
+	}
+
+	/*
+	 * Handle arbiter errors.
+	 */
+	status = __raw_readl(hose->reg_base + SH4_PCIAINT);
+	for (i = cmd = 0; i < ARRAY_SIZE(pci_arbiter_errors); i++) {
+		if (status & pci_arbiter_errors[i].mask) {
+			printk(KERN_DEBUG "PCI: %s, addr=%08lx\n",
+			       pci_arbiter_errors[i].str, addr);
+			cmd |= pci_arbiter_errors[i].mask;
+		}
+	}
+	__raw_writel(cmd, hose->reg_base + SH4_PCIAINT);
+
+	/*
+	 * Handle the remaining PCI errors.
+	 */
+	status = __raw_readl(hose->reg_base + SH4_PCIINT);
+	for (i = cmd = 0; i < ARRAY_SIZE(pci_interrupt_errors); i++) {
+		if (status & pci_interrupt_errors[i].mask) {
+			printk(KERN_DEBUG "PCI: %s, addr=%08lx\n",
+			       pci_interrupt_errors[i].str, addr);
+			cmd |= pci_interrupt_errors[i].mask;
+		}
+	}
+	__raw_writel(cmd, hose->reg_base + SH4_PCIINT);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t sh7780_pci_serr_irq(int irq, void *dev_id)
+{
+	struct pci_channel *hose = dev_id;
+
+	printk(KERN_DEBUG "PCI: system error received: ");
+	pcibios_report_status(PCI_STATUS_SIG_SYSTEM_ERROR, 1);
+	printk("\n");
+
+	/* Deassert SERR */
+	__raw_writel(SH4_PCIINTM_SDIM, hose->reg_base + SH4_PCIINTM);
+
+	/* Back off the IRQ for awhile */
+	disable_irq_nosync(irq);
+	hose->serr_timer.expires = jiffies + HZ;
+	add_timer(&hose->serr_timer);
+
+	return IRQ_HANDLED;
+}
+
+static int __init sh7780_pci_setup_irqs(struct pci_channel *hose)
+{
+	int ret;
+
+	/* Clear out PCI arbiter IRQs */
+	__raw_writel(0, hose->reg_base + SH4_PCIAINT);
+
+	/* Clear all error conditions */
+	__raw_writew(PCI_STATUS_DETECTED_PARITY  | \
+		     PCI_STATUS_SIG_SYSTEM_ERROR | \
+		     PCI_STATUS_REC_MASTER_ABORT | \
+		     PCI_STATUS_REC_TARGET_ABORT | \
+		     PCI_STATUS_SIG_TARGET_ABORT | \
+		     PCI_STATUS_PARITY, hose->reg_base + PCI_STATUS);
+
+	ret = request_irq(hose->serr_irq, sh7780_pci_serr_irq, IRQF_DISABLED,
+			  "PCI SERR interrupt", hose);
+	if (unlikely(ret)) {
+		printk(KERN_ERR "PCI: Failed hooking SERR IRQ\n");
+		return ret;
+	}
+
+	/*
+	 * The PCI ERR IRQ needs to be IRQF_SHARED since all of the power
+	 * down IRQ vectors are routed through the ERR IRQ vector. We
+	 * only request_irq() once as there is only a single masking
+	 * source for multiple events.
+	 */
+	ret = request_irq(hose->err_irq, sh7780_pci_err_irq, IRQF_SHARED,
+			  "PCI ERR interrupt", hose);
+	if (unlikely(ret)) {
+		free_irq(hose->serr_irq, hose);
+		return ret;
+	}
+
+	/* Unmask all of the arbiter IRQs. */
+	__raw_writel(SH4_PCIAINT_MBKN | SH4_PCIAINT_TBTO | SH4_PCIAINT_MBTO | \
+		     SH4_PCIAINT_TABT | SH4_PCIAINT_MABT | SH4_PCIAINT_RDPE | \
+		     SH4_PCIAINT_WDPE, hose->reg_base + SH4_PCIAINTM);
+
+	/* Unmask all of the PCI IRQs */
+	__raw_writel(SH4_PCIINTM_TTADIM  | SH4_PCIINTM_TMTOIM  | \
+		     SH4_PCIINTM_MDEIM   | SH4_PCIINTM_APEDIM  | \
+		     SH4_PCIINTM_SDIM    | SH4_PCIINTM_DPEITWM | \
+		     SH4_PCIINTM_PEDITRM | SH4_PCIINTM_TADIMM  | \
+		     SH4_PCIINTM_MADIMM  | SH4_PCIINTM_MWPDIM  | \
+		     SH4_PCIINTM_MRDPEIM, hose->reg_base + SH4_PCIINTM);
+
+	return ret;
+}
+
+static inline void __init sh7780_pci_teardown_irqs(struct pci_channel *hose)
+{
+	free_irq(hose->err_irq, hose);
+	free_irq(hose->serr_irq, hose);
+}
+
+static void __init sh7780_pci66_init(struct pci_channel *hose)
+{
+	unsigned int tmp;
+
+	if (!pci_is_66mhz_capable(hose, 0, 0))
+		return;
+
+	/* Enable register access */
+	tmp = __raw_readl(hose->reg_base + SH4_PCICR);
+	tmp |= SH4_PCICR_PREFIX;
+	__raw_writel(tmp, hose->reg_base + SH4_PCICR);
+
+	/* Enable 66MHz operation */
+	tmp = __raw_readw(hose->reg_base + PCI_STATUS);
+	tmp |= PCI_STATUS_66MHZ;
+	__raw_writew(tmp, hose->reg_base + PCI_STATUS);
+
+	/* Done */
+	tmp = __raw_readl(hose->reg_base + SH4_PCICR);
+	tmp |= SH4_PCICR_PREFIX | SH4_PCICR_CFIN;
+	__raw_writel(tmp, hose->reg_base + SH4_PCICR);
+}
+
 static int __init sh7780_pci_init(void)
 {
 	struct pci_channel *chan = &sh7780_pci_controller;
+	phys_addr_t memphys;
+	size_t memsize;
 	unsigned int id;
-	const char *type = NULL;
-	int ret;
-	u32 word;
+	const char *type;
+	int ret, i;
 
 	printk(KERN_NOTICE "PCI: Starting intialization.\n");
 
@@ -65,17 +253,28 @@ static int __init sh7780_pci_init(void)
 	/* Enable CPU access to the PCIC registers. */
 	__raw_writel(PCIECR_ENBL, PCIECR);
 
-	id = __raw_readw(chan->reg_base + SH7780_PCIVID);
-	if (id != SH7780_VENDOR_ID) {
+	/* Reset */
+	__raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_PRST,
+		     chan->reg_base + SH4_PCICR);
+
+	/*
+	 * Wait for it to come back up. The spec says to allow for up to
+	 * 1 second after toggling the reset pin, but in practice 100ms
+	 * is more than enough.
+	 */
+	mdelay(100);
+
+	id = __raw_readw(chan->reg_base + PCI_VENDOR_ID);
+	if (id != PCI_VENDOR_ID_RENESAS) {
 		printk(KERN_ERR "PCI: Unknown vendor ID 0x%04x.\n", id);
 		return -ENODEV;
 	}
 
-	id = __raw_readw(chan->reg_base + SH7780_PCIDID);
-	type = (id == SH7763_DEVICE_ID)	? "SH7763" :
-	       (id == SH7780_DEVICE_ID) ? "SH7780" :
-	       (id == SH7781_DEVICE_ID) ? "SH7781" :
-	       (id == SH7785_DEVICE_ID) ? "SH7785" :
+	id = __raw_readw(chan->reg_base + PCI_DEVICE_ID);
+	type = (id == PCI_DEVICE_ID_RENESAS_SH7763) ? "SH7763" :
+	       (id == PCI_DEVICE_ID_RENESAS_SH7780) ? "SH7780" :
+	       (id == PCI_DEVICE_ID_RENESAS_SH7781) ? "SH7781" :
+	       (id == PCI_DEVICE_ID_RENESAS_SH7785) ? "SH7785" :
 					  NULL;
 	if (unlikely(!type)) {
 		printk(KERN_ERR "PCI: Found an unsupported Renesas host "
@@ -85,62 +284,119 @@ static int __init sh7780_pci_init(void)
 
 	printk(KERN_NOTICE "PCI: Found a Renesas %s host "
 	       "controller, revision %d.\n", type,
-	       __raw_readb(chan->reg_base + SH7780_PCIRID));
+	       __raw_readb(chan->reg_base + PCI_REVISION_ID));
 
-	if ((ret = sh4_pci_check_direct(chan)) != 0)
+	/*
+	 * Now throw it in to register initialization mode and
+	 * start the real work.
+	 */
+	__raw_writel(SH4_PCICR_PREFIX, chan->reg_base + SH4_PCICR);
+
+	memphys = __pa(memory_start);
+	memsize = roundup_pow_of_two(memory_end - memory_start);
+
+	/*
+	 * If there's more than 512MB of memory, we need to roll over to
+	 * LAR1/LSR1.
+	 */
+	if (memsize > SZ_512M) {
+		__raw_writel(memphys + SZ_512M, chan->reg_base + SH4_PCILAR1);
+		__raw_writel((((memsize - SZ_512M) - SZ_1M) & 0x1ff00000) | 1,
+			     chan->reg_base + SH4_PCILSR1);
+		memsize = SZ_512M;
+	} else {
+		/*
+		 * Otherwise just zero it out and disable it.
+		 */
+		__raw_writel(0, chan->reg_base + SH4_PCILAR1);
+		__raw_writel(0, chan->reg_base + SH4_PCILSR1);
+	}
+
+	/*
+	 * LAR0/LSR0 covers up to the first 512MB, which is enough to
+	 * cover all of lowmem on most platforms.
+	 */
+	__raw_writel(memphys, chan->reg_base + SH4_PCILAR0);
+	__raw_writel(((memsize - SZ_1M) & 0x1ff00000) | 1,
+		     chan->reg_base + SH4_PCILSR0);
+
+	/*
+	 * Hook up the ERR and SERR IRQs.
+	 */
+	ret = sh7780_pci_setup_irqs(chan);
+	if (unlikely(ret))
 		return ret;
 
 	/*
-	 * Set the class and sub-class codes.
+	 * Disable the cache snoop controller for non-coherent DMA.
 	 */
-	__raw_writeb(PCI_CLASS_BRIDGE_HOST >> 8,
-		     chan->reg_base + SH7780_PCIBCC);
-	__raw_writeb(PCI_CLASS_BRIDGE_HOST & 0xff,
-		     chan->reg_base + SH7780_PCISUB);
+	__raw_writel(0, chan->reg_base + SH7780_PCICSCR0);
+	__raw_writel(0, chan->reg_base + SH7780_PCICSAR0);
+	__raw_writel(0, chan->reg_base + SH7780_PCICSCR1);
+	__raw_writel(0, chan->reg_base + SH7780_PCICSAR1);
 
 	/*
-	 * Set IO and Mem windows to local address
-	 * Make PCI and local address the same for easy 1 to 1 mapping
+	 * Setup the memory BARs
 	 */
-	pci_write_reg(chan, sh7780_pci_map.window0.size - 0xfffff, SH4_PCILSR0);
-	/* Set the values on window 0 PCI config registers */
-	pci_write_reg(chan, sh7780_pci_map.window0.base, SH4_PCILAR0);
-	pci_write_reg(chan, sh7780_pci_map.window0.base, SH7780_PCIMBAR0);
+	for (i = 1; i < chan->nr_resources; i++) {
+		struct resource *res = chan->resources + i;
+		resource_size_t size;
 
-	pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM);
+		if (unlikely(res->flags & IORESOURCE_IO))
+			continue;
 
-	/* Set up standard PCI config registers */
-	__raw_writew(0xFB00, chan->reg_base + SH7780_PCISTATUS);
-	__raw_writew(0x0047, chan->reg_base + SH7780_PCICMD);
-	__raw_writew(0x1912, chan->reg_base + SH7780_PCISVID);
-	__raw_writew(0x0001, chan->reg_base + SH7780_PCISID);
+		/*
+		 * Make sure we're in the right physical addressing mode
+		 * for dealing with the resource.
+		 */
+		if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode()) {
+			chan->nr_resources--;
+			continue;
+		}
 
-	__raw_writeb(0x00, chan->reg_base + SH7780_PCIPIF);
+		size = resource_size(res);
 
-	/* Apply any last-minute PCIC fixups */
-	pci_fixup_pcic(chan);
+		/*
+		 * The MBMR mask is calculated in units of 256kB, which
+		 * keeps things pretty simple.
+		 */
+		__raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18,
+			     chan->reg_base + SH7780_PCIMBMR(i - 1));
+		__raw_writel(res->start, chan->reg_base + SH7780_PCIMBR(i - 1));
+	}
 
-	pci_write_reg(chan, 0xfd000000, SH7780_PCIMBR0);
-	pci_write_reg(chan, 0x00fc0000, SH7780_PCIMBMR0);
+	/*
+	 * And I/O.
+	 */
+	__raw_writel(0, chan->reg_base + PCI_BASE_ADDRESS_0);
+	__raw_writel(0, chan->reg_base + SH7780_PCIIOBR);
+	__raw_writel(0, chan->reg_base + SH7780_PCIIOBMR);
 
-#ifdef CONFIG_32BIT
-	pci_write_reg(chan, 0xc0000000, SH7780_PCIMBR2);
-	pci_write_reg(chan, 0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2);
-#endif
+	__raw_writew(PCI_COMMAND_SERR   | PCI_COMMAND_WAIT   | \
+		     PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | \
+		     PCI_COMMAND_MEMORY, chan->reg_base + PCI_COMMAND);
 
-	/* Set IOBR for windows containing area specified in pci.h */
-	pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE-1),
-		      SH7780_PCIIOBR);
-	pci_write_reg(chan, ((SH7780_PCI_IO_SIZE-1) & (7<<18)),
-		      SH7780_PCIIOBMR);
+	/*
+	 * Initialization mode complete, release the control register and
+	 * enable round robin mode to stop device overruns/starvation.
+	 */
+	__raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO,
+		     chan->reg_base + SH4_PCICR);
 
-	/* SH7780 init done, set central function init complete */
-	/* use round robin mode to stop a device starving/overruning */
-	word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO;
-	pci_write_reg(chan, word, SH4_PCICR);
+	ret = register_pci_controller(chan);
+	if (unlikely(ret))
+		goto err;
 
-	register_pci_controller(chan);
+	sh7780_pci66_init(chan);
+
+	printk(KERN_NOTICE "PCI: Running at %dMHz.\n",
+	       (__raw_readw(chan->reg_base + PCI_STATUS) & PCI_STATUS_66MHZ) ?
+	       66 : 33);
 
 	return 0;
+
+err:
+	sh7780_pci_teardown_irqs(chan);
+	return ret;
 }
 arch_initcall(sh7780_pci_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci-sh7780.h linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci-sh7780.h
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/pci-sh7780.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/pci/pci-sh7780.h	2010-05-16 17:17:36.000000000 -0400
@@ -12,12 +12,11 @@
 #ifndef _PCI_SH7780_H_
 #define _PCI_SH7780_H_
 
-/* Platform Specific Values */
-#define SH7780_VENDOR_ID	0x1912
-#define SH7781_DEVICE_ID	0x0001
-#define SH7780_DEVICE_ID	0x0002
-#define SH7763_DEVICE_ID	0x0004
-#define SH7785_DEVICE_ID	0x0007
+#define PCI_VENDOR_ID_RENESAS		0x1912
+#define PCI_DEVICE_ID_RENESAS_SH7781	0x0001
+#define PCI_DEVICE_ID_RENESAS_SH7780	0x0002
+#define PCI_DEVICE_ID_RENESAS_SH7763	0x0004
+#define PCI_DEVICE_ID_RENESAS_SH7785	0x0007
 
 /* SH7780 Control Registers */
 #define	PCIECR			0xFE000008
@@ -27,44 +26,9 @@
 #define SH7780_PCI_CONFIG_BASE	0xFD000000	/* Config space base addr */
 #define SH7780_PCI_CONFIG_SIZE	0x01000000	/* Config space size */
 
-#define SH7780_PCI_MEMORY_BASE	0xFD000000	/* Memory space base addr */
-#define SH7780_PCI_MEM_SIZE	0x01000000	/* Size of Memory window */
-
-#define SH7780_PCI_IO_BASE	0xFE200000	/* IO space base address */
-#define SH7780_PCI_IO_SIZE	0x00400000	/* Size of IO window */
-
 #define SH7780_PCIREG_BASE	0xFE040000	/* PCI regs base address */
 
 /* SH7780 PCI Config Registers */
-#define SH7780_PCIVID		0x000		/* Vendor ID */
-#define SH7780_PCIDID		0x002		/* Device ID */
-#define SH7780_PCICMD		0x004		/* Command */
-#define SH7780_PCISTATUS	0x006		/* Status */
-#define SH7780_PCIRID		0x008		/* Revision ID */
-#define SH7780_PCIPIF		0x009		/* Program Interface */
-#define SH7780_PCISUB		0x00a		/* Sub class code */
-#define SH7780_PCIBCC		0x00b		/* Base class code */
-#define SH7780_PCICLS		0x00c		/* Cache line size */
-#define SH7780_PCILTM		0x00d		/* latency timer */
-#define SH7780_PCIHDR		0x00e		/* Header type */
-#define SH7780_PCIBIST		0x00f		/* BIST */
-#define SH7780_PCIIBAR		0x010		/* IO Base address */
-#define SH7780_PCIMBAR0		0x014		/* Memory base address0 */
-#define SH7780_PCIMBAR1		0x018		/* Memory base address1 */
-#define SH7780_PCISVID		0x02c		/* Sub system vendor ID */
-#define SH7780_PCISID		0x02e		/* Sub system ID */
-#define SH7780_PCICP		0x034
-#define SH7780_PCIINTLINE	0x03c		/* Interrupt line */
-#define SH7780_PCIINTPIN	0x03d		/* Interrupt pin */
-#define SH7780_PCIMINGNT	0x03e		/* Minumum grand */
-#define SH7780_PCIMAXLAT	0x03f		/* Maxmum latency */
-#define SH7780_PCICID		0x040
-#define SH7780_PCINIP		0x041
-#define SH7780_PCIPMC		0x042
-#define SH7780_PCIPMCSR		0x044
-#define SH7780_PCIPMCSR_BSE	0x046
-#define SH7780_PCICDD		0x047
-
 #define SH7780_PCIIR		0x114		/* PCI Interrupt Register */
 #define SH7780_PCIIMR		0x118		/* PCI Interrupt Mask Register */
 #define SH7780_PCIAIR		0x11C		/* Error Address Register */
@@ -76,10 +40,8 @@
 #define SH7780_PCIPINT		0x1CC		/* Power Mgmnt Int. Register */
 #define SH7780_PCIPINTM		0x1D0		/* Power Mgmnt Mask Register */
 
-#define SH7780_PCIMBR0		0x1E0
-#define SH7780_PCIMBMR0		0x1E4
-#define SH7780_PCIMBR2		0x1F0
-#define SH7780_PCIMBMR2		0x1F4
+#define SH7780_PCIMBR(x)	(0x1E0 + ((x) * 8))
+#define SH7780_PCIMBMR(x)	(0x1E4 + ((x) * 8))
 #define SH7780_PCIIOBR		0x1F8
 #define SH7780_PCIIOBMR		0x1FC
 #define SH7780_PCICSCR0		0x210		/* Cache Snoop1 Cnt. Register */
@@ -87,16 +49,4 @@
 #define SH7780_PCICSAR0		0x218	/* Cache Snoop1 Addr. Register */
 #define SH7780_PCICSAR1		0x21C	/* Cache Snoop2 Addr. Register */
 
-/* General Memory Config Addresses */
-#define SH7780_CS0_BASE_ADDR	0x0
-#define SH7780_MEM_REGION_SIZE	0x04000000
-#define SH7780_CS1_BASE_ADDR	(SH7780_CS0_BASE_ADDR + SH7780_MEM_REGION_SIZE)
-#define SH7780_CS2_BASE_ADDR	(SH7780_CS1_BASE_ADDR + SH7780_MEM_REGION_SIZE)
-#define SH7780_CS3_BASE_ADDR	(SH7780_CS2_BASE_ADDR + SH7780_MEM_REGION_SIZE)
-#define SH7780_CS4_BASE_ADDR	(SH7780_CS3_BASE_ADDR + SH7780_MEM_REGION_SIZE)
-#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
-
 #endif /* _PCI_SH7780_H_ */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/push-switch.c linux-libre-2.6.34-gnu1/arch/sh/drivers/push-switch.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/push-switch.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/push-switch.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  * for more details.
  */
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/drivers/superhyway/ops-sh4-202.c linux-libre-2.6.34-gnu1/arch/sh/drivers/superhyway/ops-sh4-202.c
--- linux-libre-2.6.33-gnu1/arch/sh/drivers/superhyway/ops-sh4-202.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/drivers/superhyway/ops-sh4-202.c	2010-05-16 17:17:36.000000000 -0400
@@ -134,8 +134,8 @@ static int sh4202_read_vcr(unsigned long
 	 *
 	 * Do not trust the documentation, for it is evil.
 	 */
-	vcrh = ctrl_inl(base);
-	vcrl = ctrl_inl(base + sizeof(u32));
+	vcrh = __raw_readl(base);
+	vcrl = __raw_readl(base + sizeof(u32));
 
 	tmp = ((u64)vcrh << 32) | vcrl;
 	memcpy(vcr, &tmp, sizeof(u64));
@@ -147,8 +147,8 @@ static int sh4202_write_vcr(unsigned lon
 {
 	u64 tmp = *(u64 *)&vcr;
 
-	ctrl_outl((tmp >> 32) & 0xffffffff, base);
-	ctrl_outl(tmp & 0xffffffff, base + sizeof(u32));
+	__raw_writel((tmp >> 32) & 0xffffffff, base);
+	__raw_writel(tmp & 0xffffffff, base + sizeof(u32));
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/addrspace.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/addrspace.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/addrspace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/addrspace.h	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,7 @@
 /* Returns the privileged segment base of a given address  */
 #define PXSEG(a)	(((unsigned long)(a)) & 0xe0000000)
 
-#if defined(CONFIG_29BIT) || defined(CONFIG_PMB_FIXED)
+#ifdef CONFIG_29BIT
 /*
  * Map an address to a certain privileged segment
  */
@@ -40,7 +40,15 @@
 	((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P3SEG))
 #define P4SEGADDR(a)	\
 	((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P4SEG))
-#endif /* 29BIT || PMB_FIXED */
+#else
+/*
+ * These will never work in 32-bit, don't even bother.
+ */
+#define P1SEGADDR(a)	__futile_remapping_attempt
+#define P2SEGADDR(a)	__futile_remapping_attempt
+#define P3SEGADDR(a)	__futile_remapping_attempt
+#define P4SEGADDR(a)	__futile_remapping_attempt
+#endif
 #endif /* P1SEG */
 
 /* Check if an address can be reached in 29 bits */
@@ -57,11 +65,5 @@
 #define P3_ADDR_MAX		P4SEG
 #endif
 
-#ifndef __ASSEMBLY__
-#ifdef CONFIG_PMB
-extern int __in_29bit_mode(void);
-#endif /* CONFIG_PMB */
-#endif /* __ASSEMBLY__ */
-
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_ADDRSPACE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/alignment.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/alignment.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/alignment.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/alignment.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,21 @@
+#ifndef __ASM_SH_ALIGNMENT_H
+#define __ASM_SH_ALIGNMENT_H
+
+#include <linux/types.h>
+
+extern void inc_unaligned_byte_access(void);
+extern void inc_unaligned_word_access(void);
+extern void inc_unaligned_dword_access(void);
+extern void inc_unaligned_multi_access(void);
+extern void inc_unaligned_user_access(void);
+extern void inc_unaligned_kernel_access(void);
+
+#define UM_WARN		(1 << 0)
+#define UM_FIXUP	(1 << 1)
+#define UM_SIGNAL	(1 << 2)
+
+extern unsigned int unaligned_user_action(void);
+
+extern void unaligned_fixups_notify(struct task_struct *, insn_size_t, struct pt_regs *);
+
+#endif /* __ASM_SH_ALIGNMENT_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/atomic-grb.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/atomic-grb.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/atomic-grb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/atomic-grb.h	2010-05-16 17:17:36.000000000 -0400
@@ -120,50 +120,4 @@ static inline void atomic_set_mask(unsig
 		: "memory" , "r0", "r1");
 }
 
-static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
-{
-	int ret;
-
-	__asm__ __volatile__ (
-		"   .align 2		\n\t"
-		"   mova     1f,  r0	\n\t"
-		"   nop			\n\t"
-		"   mov     r15,  r1	\n\t"
-		"   mov    #-8,  r15	\n\t"
-		"   mov.l   @%1,  %0	\n\t"
-		"   cmp/eq   %2,  %0	\n\t"
-		"   bf	     1f		\n\t"
-		"   mov.l    %3, @%1	\n\t"
-		"1: mov      r1,  r15	\n\t"
-		: "=&r" (ret)
-		: "r" (v), "r" (old), "r" (new)
-		: "memory" , "r0", "r1" , "t");
-
-	return ret;
-}
-
-static inline int atomic_add_unless(atomic_t *v, int a, int u)
-{
-	int ret;
-	unsigned long tmp;
-
-	__asm__ __volatile__ (
-		"   .align 2		\n\t"
-		"   mova    1f,   r0	\n\t"
-		"   nop			\n\t"
-		"   mov    r15,   r1	\n\t"
-		"   mov    #-12,  r15	\n\t"
-		"   mov.l  @%2,   %1	\n\t"
-		"   mov	    %1,   %0    \n\t"
-		"   cmp/eq  %4,   %0	\n\t"
-		"   bt/s    1f		\n\t"
-		"    add    %3,   %1	\n\t"
-		"   mov.l   %1,  @%2	\n\t"
-		"1: mov     r1,   r15	\n\t"
-		: "=&r" (ret), "=&r" (tmp)
-		: "r" (v), "r" (a), "r" (u)
-		: "memory" , "r0", "r1" , "t");
-
-	return ret != u;
-}
 #endif /* __ASM_SH_ATOMIC_GRB_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/atomic.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/atomic.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/atomic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/atomic.h	2010-05-16 17:17:36.000000000 -0400
@@ -25,58 +25,43 @@
 #endif
 
 #define atomic_add_negative(a, v)	(atomic_add_return((a), (v)) < 0)
+#define atomic_dec_return(v)		atomic_sub_return(1, (v))
+#define atomic_inc_return(v)		atomic_add_return(1, (v))
+#define atomic_inc_and_test(v)		(atomic_inc_return(v) == 0)
+#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_not_zero(v)		atomic_add_unless((v), 1, 0)
 
-#define atomic_dec_return(v) atomic_sub_return(1,(v))
-#define atomic_inc_return(v) atomic_add_return(1,(v))
+#define atomic_inc(v)			atomic_add(1, (v))
+#define atomic_dec(v)			atomic_sub(1, (v))
 
-/*
- * atomic_inc_and_test - increment and test
+#define atomic_xchg(v, new)		(xchg(&((v)->counter), new))
+#define atomic_cmpxchg(v, o, n)		(cmpxchg(&((v)->counter), (o), (n)))
+
+/**
+ * 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 increments @v by 1
- * and returns true if the result is zero, or false for all
- * other cases.
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
  */
-#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
-
-#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(v) atomic_add(1,(v))
-#define atomic_dec(v) atomic_sub(1,(v))
-
-#if !defined(CONFIG_GUSA_RB) && !defined(CONFIG_CPU_SH4A)
-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 ret;
-	unsigned long flags;
-
-	local_irq_save(flags);
-	ret = v->counter;
-	if (ret != u)
-		v->counter += a;
-	local_irq_restore(flags);
+	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 ret != u;
+	return c != (u);
 }
-#endif /* !CONFIG_GUSA_RB && !CONFIG_CPU_SH4A */
-
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
 
 #define smp_mb__before_atomic_dec()	smp_mb()
 #define smp_mb__after_atomic_dec()	smp_mb()
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/atomic-llsc.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/atomic-llsc.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/atomic-llsc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/atomic-llsc.h	2010-05-16 17:17:36.000000000 -0400
@@ -104,31 +104,4 @@ static inline void atomic_set_mask(unsig
 	: "t");
 }
 
-#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
-
-/**
- * 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);
-}
-
 #endif /* __ASM_SH_ATOMIC_LLSC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/cacheflush.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/cacheflush.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/cacheflush.h	2010-05-16 17:17:36.000000000 -0400
@@ -63,6 +63,14 @@ static inline void flush_anon_page(struc
 	if (boot_cpu_data.dcache.n_aliases && PageAnon(page))
 		__flush_anon_page(page, vmaddr);
 }
+static inline void flush_kernel_vmap_range(void *addr, int size)
+{
+	__flush_wback_region(addr, size);
+}
+static inline void invalidate_kernel_vmap_range(void *addr, int size)
+{
+	__flush_invalidate_region(addr, size);
+}
 
 #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
 static inline void flush_kernel_dcache_page(struct page *page)
@@ -78,8 +86,8 @@ extern void copy_from_user_page(struct v
 	struct page *page, unsigned long vaddr, void *dst, const void *src,
 	unsigned long len);
 
-#define flush_cache_vmap(start, end)		flush_cache_all()
-#define flush_cache_vunmap(start, end)		flush_cache_all()
+#define flush_cache_vmap(start, end)		local_flush_cache_all(NULL)
+#define flush_cache_vunmap(start, end)		local_flush_cache_all(NULL)
 
 #define flush_dcache_mmap_lock(mapping)		do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)	do { } while (0)
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/clock.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/clock.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/clock.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/clock.h	2010-05-16 17:17:36.000000000 -0400
@@ -146,8 +146,17 @@ int sh_clk_mstp32_register(struct clk *c
 	.flags = _flags,						\
 }
 
+struct clk_div4_table {
+	struct clk_div_mult_table *div_mult_table;
+	void (*kick)(struct clk *clk);
+};
+
 int sh_clk_div4_register(struct clk *clks, int nr,
-			 struct clk_div_mult_table *table);
+			 struct clk_div4_table *table);
+int sh_clk_div4_enable_register(struct clk *clks, int nr,
+			 struct clk_div4_table *table);
+int sh_clk_div4_reparent_register(struct clk *clks, int nr,
+			 struct clk_div4_table *table);
 
 #define SH_CLK_DIV6(_name, _parent, _reg, _flags)	\
 {							\
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/cmpxchg-grb.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/cmpxchg-grb.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/cmpxchg-grb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/cmpxchg-grb.h	2010-05-16 17:17:36.000000000 -0400
@@ -57,11 +57,10 @@ static inline unsigned long __cmpxchg_u3
 		"   mov.l  @%1,   %0      \n\t" /* load  old value */
 		"   cmp/eq  %0,   %2      \n\t"
 		"   bf            1f      \n\t" /* if not equal */
-		"   mov.l   %2,   @%1     \n\t" /* store new value */
+		"   mov.l   %3,   @%1     \n\t" /* store new value */
 		"1: mov     r1,   r15     \n\t" /* LOGOUT */
-		: "=&r" (retval),
-		  "+r"  (m)
-		: "r"   (new)
+		: "=&r" (retval)
+		:  "r"  (m), "r"  (old), "r"  (new)
 		: "memory" , "r0", "r1", "t");
 
 	return retval;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/dmaengine.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/dmaengine.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/dmaengine.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/dmaengine.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,93 @@
+/*
+ * Header for the new SH dmaengine driver
+ *
+ * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef ASM_DMAENGINE_H
+#define ASM_DMAENGINE_H
+
+#include <linux/dmaengine.h>
+#include <linux/list.h>
+
+#include <asm/dma-register.h>
+
+#define SH_DMAC_MAX_CHANNELS	6
+
+enum sh_dmae_slave_chan_id {
+	SHDMA_SLAVE_SCIF0_TX,
+	SHDMA_SLAVE_SCIF0_RX,
+	SHDMA_SLAVE_SCIF1_TX,
+	SHDMA_SLAVE_SCIF1_RX,
+	SHDMA_SLAVE_SCIF2_TX,
+	SHDMA_SLAVE_SCIF2_RX,
+	SHDMA_SLAVE_SCIF3_TX,
+	SHDMA_SLAVE_SCIF3_RX,
+	SHDMA_SLAVE_SCIF4_TX,
+	SHDMA_SLAVE_SCIF4_RX,
+	SHDMA_SLAVE_SCIF5_TX,
+	SHDMA_SLAVE_SCIF5_RX,
+	SHDMA_SLAVE_SIUA_TX,
+	SHDMA_SLAVE_SIUA_RX,
+	SHDMA_SLAVE_SIUB_TX,
+	SHDMA_SLAVE_SIUB_RX,
+	SHDMA_SLAVE_NUMBER,	/* Must stay last */
+};
+
+struct sh_dmae_slave_config {
+	enum sh_dmae_slave_chan_id	slave_id;
+	dma_addr_t			addr;
+	u32				chcr;
+	char				mid_rid;
+};
+
+struct sh_dmae_channel {
+	unsigned int	offset;
+	unsigned int	dmars;
+	unsigned int	dmars_bit;
+};
+
+struct sh_dmae_pdata {
+	struct sh_dmae_slave_config *slave;
+	int slave_num;
+	struct sh_dmae_channel *channel;
+	int channel_num;
+	unsigned int ts_low_shift;
+	unsigned int ts_low_mask;
+	unsigned int ts_high_shift;
+	unsigned int ts_high_mask;
+	unsigned int *ts_shift;
+	int ts_shift_num;
+	u16 dmaor_init;
+};
+
+struct device;
+
+/* Used by slave DMA clients to request DMA to/from a specific peripheral */
+struct sh_dmae_slave {
+	enum sh_dmae_slave_chan_id	slave_id; /* Set by the platform */
+	struct device			*dma_dev; /* Set by the platform */
+	struct sh_dmae_slave_config	*config;  /* Set by the driver */
+};
+
+struct sh_dmae_regs {
+	u32 sar; /* SAR / source address */
+	u32 dar; /* DAR / destination address */
+	u32 tcr; /* TCR / transfer count */
+};
+
+struct sh_desc {
+	struct sh_dmae_regs hw;
+	struct list_head node;
+	struct dma_async_tx_descriptor async_tx;
+	enum dma_data_direction direction;
+	dma_cookie_t cookie;
+	size_t partial;
+	int chunks;
+	int mark;
+};
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/dma-mapping.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/dma-mapping.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/dma-mapping.h	2010-05-16 17:17:36.000000000 -0400
@@ -89,8 +89,6 @@ static inline void dma_free_coherent(str
 {
 	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;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/dma-register.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/dma-register.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/dma-register.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/dma-register.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,51 @@
+/*
+ * Common header for the legacy SH DMA driver and the new dmaengine driver
+ *
+ * extracted from 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_REGISTER_H
+#define DMA_REGISTER_H
+
+/* DMA register */
+#define SAR	0x00
+#define DAR	0x04
+#define TCR	0x08
+#define CHCR	0x0C
+#define DMAOR	0x40
+
+/* DMAOR definitions */
+#define DMAOR_AE	0x00000004
+#define DMAOR_NMIF	0x00000002
+#define DMAOR_DME	0x00000001
+
+/* 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 DM_FIX	0x0000c000
+#define SM_INC	0x00001000
+#define SM_DEC	0x00002000
+#define SM_FIX	0x00003000
+#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
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/dma-sh.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/dma-sh.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/dma-sh.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/dma-sh.h	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,8 @@
 #ifndef __DMA_SH_H
 #define __DMA_SH_H
 
-#include <asm/dma.h>
+#include <asm/dma-register.h>
+#include <cpu/dma-register.h>
 #include <cpu/dma.h>
 
 /* DMAOR contorl: The DMAOR access size is different by CPU.*/
@@ -20,14 +21,14 @@
     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))
+    (n ? __raw_readw(SH_DMAC_BASE1 + DMAOR) \
+	: __raw_readw(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))
+    (n ? __raw_writew(data, SH_DMAC_BASE1 + DMAOR) \
+    : __raw_writew(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)
+#define dmaor_read_reg(n) __raw_readw(SH_DMAC_BASE0 + DMAOR)
+#define dmaor_write_reg(n, data) __raw_writew(data, SH_DMAC_BASE0 + DMAOR)
 #endif
 
 static int dmte_irq_map[] __maybe_unused = {
@@ -53,37 +54,11 @@ static int dmte_irq_map[] __maybe_unused
 #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)
+#define RS_DUAL	(DM_INC | SM_INC | 0x400 | TS_INDEX2VAL(XMIT_SZ_32BIT))
 
 /* DMA base address */
 static u32 dma_base_addr[] __maybe_unused = {
@@ -109,24 +84,4 @@ static u32 dma_base_addr[] __maybe_unuse
 #endif
 };
 
-/* DMA register */
-#define SAR     0x00
-#define DAR     0x04
-#define TCR     0x08
-#define CHCR    0x0C
-#define DMAOR	0x40
-
-/*
- * for dma engine
- *
- * SuperH DMA mode
- */
-#define SHDMA_MIX_IRQ	(1 << 1)
-#define SHDMA_DMAOR1	(1 << 2)
-#define SHDMA_DMAE1		(1 << 3)
-
-struct sh_dmae_pdata {
-	unsigned int mode;
-};
-
 #endif /* __DMA_SH_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/dwarf.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/dwarf.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/dwarf.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/dwarf.h	2010-05-16 17:17:36.000000000 -0400
@@ -243,16 +243,13 @@ struct dwarf_cie {
 
 	unsigned long cie_pointer;
 
-	struct list_head link;
-
 	unsigned long flags;
 #define DWARF_CIE_Z_AUGMENTATION	(1 << 0)
 
-	/*
-	 * 'mod' will be non-NULL if this CIE came from a module's
-	 * .eh_frame section.
-	 */
-	struct module *mod;
+	/* linked-list entry if this CIE is from a module */
+	struct list_head link;
+
+	struct rb_node node;
 };
 
 /**
@@ -266,13 +263,11 @@ struct dwarf_fde {
 	unsigned long address_range;
 	unsigned char *instructions;
 	unsigned char *end;
+
+	/* linked-list entry if this FDE is from a module */
 	struct list_head link;
 
-	/*
-	 * 'mod' will be non-NULL if this FDE came from a module's
-	 * .eh_frame section.
-	 */
-	struct module *mod;
+	struct rb_node node;
 };
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/elf.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/elf.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/elf.h	2010-05-16 17:17:36.000000000 -0400
@@ -211,7 +211,9 @@ extern void __kernel_vsyscall;
 
 #define VSYSCALL_AUX_ENT					\
 	if (vdso_enabled)					\
-		NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE);
+		NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE);	\
+	else							\
+		NEW_AUX_ENT(AT_IGNORE, 0);
 #else
 #define VSYSCALL_AUX_ENT
 #endif /* CONFIG_VSYSCALL */
@@ -219,7 +221,7 @@ extern void __kernel_vsyscall;
 #ifdef CONFIG_SH_FPU
 #define FPU_AUX_ENT	NEW_AUX_ENT(AT_FPUCW, FPSCR_INIT)
 #else
-#define FPU_AUX_ENT
+#define FPU_AUX_ENT	NEW_AUX_ENT(AT_IGNORE, 0)
 #endif
 
 extern int l1i_cache_shape, l1d_cache_shape, l2_cache_shape;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/fixmap.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/fixmap.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/fixmap.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/fixmap.h	2010-05-16 17:17:36.000000000 -0400
@@ -55,16 +55,29 @@ enum fixed_addresses {
 #define FIX_N_COLOURS 8
 	FIX_CMAP_BEGIN,
 	FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS) - 1,
-	FIX_UNCACHED,
+
 #ifdef CONFIG_HIGHMEM
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
 	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
 #endif
+
+#ifdef CONFIG_IOREMAP_FIXED
+	/*
+	 * FIX_IOREMAP entries are useful for mapping physical address
+	 * space before ioremap() is useable, e.g. really early in boot
+	 * before kmalloc() is working.
+	 */
+#define FIX_N_IOREMAPS	32
+	FIX_IOREMAP_BEGIN,
+	FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS,
+#endif
+
 	__end_of_fixed_addresses
 };
 
 extern void __set_fixmap(enum fixed_addresses idx,
 			 unsigned long phys, pgprot_t flags);
+extern void __clear_fixmap(enum fixed_addresses idx, pgprot_t flags);
 
 #define set_fixmap(idx, phys) \
 		__set_fixmap(idx, phys, PAGE_KERNEL)
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/fpu.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/fpu.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/fpu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/fpu.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,8 +2,8 @@
 #define __ASM_SH_FPU_H
 
 #ifndef __ASSEMBLY__
-#include <linux/preempt.h>
-#include <asm/ptrace.h>
+
+struct task_struct;
 
 #ifdef CONFIG_SH_FPU
 static inline void release_fpu(struct pt_regs *regs)
@@ -16,22 +16,23 @@ static inline void grab_fpu(struct pt_re
 	regs->sr &= ~SR_FD;
 }
 
-struct task_struct;
-
 extern void save_fpu(struct task_struct *__tsk);
-void fpu_state_restore(struct pt_regs *regs);
+extern void restore_fpu(struct task_struct *__tsk);
+extern void fpu_state_restore(struct pt_regs *regs);
+extern void __fpu_state_restore(void);
 #else
-
-#define save_fpu(tsk)		do { } while (0)
-#define release_fpu(regs)	do { } while (0)
-#define grab_fpu(regs)		do { } while (0)
-#define fpu_state_restore(regs)	do { } while (0)
-
+#define save_fpu(tsk)			do { } while (0)
+#define restore_fpu(tsk)		do { } while (0)
+#define release_fpu(regs)		do { } while (0)
+#define grab_fpu(regs)			do { } while (0)
+#define fpu_state_restore(regs)		do { } while (0)
+#define __fpu_state_restore(regs)	do { } while (0)
 #endif
 
 struct user_regset;
 
 extern int do_fpu_inst(unsigned short, struct pt_regs *);
+extern int init_fpu(struct task_struct *);
 
 extern int fpregs_get(struct task_struct *target,
 		      const struct user_regset *regset,
@@ -65,18 +66,6 @@ static inline void clear_fpu(struct task
 	preempt_enable();
 }
 
-static inline int init_fpu(struct task_struct *tsk)
-{
-	if (tsk_used_math(tsk)) {
-		if ((boot_cpu_data.flags & CPU_HAS_FPU) && tsk == current)
-			unlazy_fpu(tsk, task_pt_regs(tsk));
-		return 0;
-	}
-
-	set_stopped_child_used_math(tsk);
-	return 0;
-}
-
 #endif /* __ASSEMBLY__ */
 
 #endif /* __ASM_SH_FPU_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/hw_breakpoint.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/hw_breakpoint.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/hw_breakpoint.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/hw_breakpoint.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,67 @@
+#ifndef __ASM_SH_HW_BREAKPOINT_H
+#define __ASM_SH_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#define __ARCH_HW_BREAKPOINT_H
+
+#include <linux/kdebug.h>
+#include <linux/types.h>
+
+struct arch_hw_breakpoint {
+	char		*name; /* Contains name of the symbol to set bkpt */
+	unsigned long	address;
+	u16		len;
+	u16		type;
+};
+
+enum {
+	SH_BREAKPOINT_READ	= (1 << 1),
+	SH_BREAKPOINT_WRITE	= (1 << 2),
+	SH_BREAKPOINT_RW	= SH_BREAKPOINT_READ | SH_BREAKPOINT_WRITE,
+
+	SH_BREAKPOINT_LEN_1	= (1 << 12),
+	SH_BREAKPOINT_LEN_2	= (1 << 13),
+	SH_BREAKPOINT_LEN_4	= SH_BREAKPOINT_LEN_1 | SH_BREAKPOINT_LEN_2,
+	SH_BREAKPOINT_LEN_8	= (1 << 14),
+};
+
+struct sh_ubc {
+	const char	*name;
+	unsigned int	num_events;
+	unsigned int	trap_nr;
+	void		(*enable)(struct arch_hw_breakpoint *, int);
+	void		(*disable)(struct arch_hw_breakpoint *, int);
+	void		(*enable_all)(unsigned long);
+	void		(*disable_all)(void);
+	unsigned long	(*active_mask)(void);
+	unsigned long	(*triggered_mask)(void);
+	void		(*clear_triggered_mask)(unsigned long);
+	struct clk	*clk;	/* optional interface clock / MSTP bit */
+};
+
+struct perf_event;
+struct task_struct;
+struct pmu;
+
+/* Maximum number of UBC channels */
+#define HBP_NUM		2
+
+/* arch/sh/kernel/hw_breakpoint.c */
+extern int arch_check_va_in_userspace(unsigned long va, u16 hbp_len);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp,
+					 struct task_struct *tsk);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+					   unsigned long val, void *data);
+
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+void hw_breakpoint_pmu_unthrottle(struct perf_event *bp);
+
+extern void arch_fill_perf_breakpoint(struct perf_event *bp);
+extern int register_sh_ubc(struct sh_ubc *);
+
+extern struct pmu perf_ops_bp;
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_SH_HW_BREAKPOINT_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/io.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/io.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/io.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/io.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  * for old compat code for I/O offseting to SuperIOs, all of which are
  * better handled through the machvec ioport mapping routines these days.
  */
+#include <linux/errno.h>
 #include <asm/cache.h>
 #include <asm/system.h>
 #include <asm/addrspace.h>
@@ -79,16 +80,51 @@
 #define writel(v,a)		({ __raw_writel((v),(a)); mb(); })
 #define writeq(v,a)		({ __raw_writeq((v),(a)); mb(); })
 
-/* SuperH on-chip I/O functions */
-#define ctrl_inb		__raw_readb
-#define ctrl_inw		__raw_readw
-#define ctrl_inl		__raw_readl
-#define ctrl_inq		__raw_readq
+/*
+ * Legacy SuperH on-chip I/O functions
+ *
+ * These are all deprecated, all new (and especially cross-platform) code
+ * should be using the __raw_xxx() routines directly.
+ */
+static inline u8 __deprecated ctrl_inb(unsigned long addr)
+{
+	return __raw_readb(addr);
+}
 
-#define ctrl_outb		__raw_writeb
-#define ctrl_outw		__raw_writew
-#define ctrl_outl		__raw_writel
-#define ctrl_outq		__raw_writeq
+static inline u16 __deprecated ctrl_inw(unsigned long addr)
+{
+	return __raw_readw(addr);
+}
+
+static inline u32 __deprecated ctrl_inl(unsigned long addr)
+{
+	return __raw_readl(addr);
+}
+
+static inline u64 __deprecated ctrl_inq(unsigned long addr)
+{
+	return __raw_readq(addr);
+}
+
+static inline void __deprecated ctrl_outb(u8 v, unsigned long addr)
+{
+	__raw_writeb(v, addr);
+}
+
+static inline void __deprecated ctrl_outw(u16 v, unsigned long addr)
+{
+	__raw_writew(v, addr);
+}
+
+static inline void __deprecated ctrl_outl(u32 v, unsigned long addr)
+{
+	__raw_writel(v, addr);
+}
+
+static inline void __deprecated ctrl_outq(u64 v, unsigned long addr)
+{
+	__raw_writeq(v, addr);
+}
 
 extern unsigned long generic_io_base;
 
@@ -97,6 +133,28 @@ static inline void ctrl_delay(void)
 	__raw_readw(generic_io_base);
 }
 
+#define __BUILD_UNCACHED_IO(bwlq, type)					\
+static inline type read##bwlq##_uncached(unsigned long addr)		\
+{									\
+	type ret;							\
+	jump_to_uncached();						\
+	ret = __raw_read##bwlq(addr);					\
+	back_to_cached();						\
+	return ret;							\
+}									\
+									\
+static inline void write##bwlq##_uncached(type v, unsigned long addr)	\
+{									\
+	jump_to_uncached();						\
+	__raw_write##bwlq(v, addr);					\
+	back_to_cached();						\
+}
+
+__BUILD_UNCACHED_IO(b, u8)
+__BUILD_UNCACHED_IO(w, u16)
+__BUILD_UNCACHED_IO(l, u32)
+__BUILD_UNCACHED_IO(q, u64)
+
 #define __BUILD_MEMORY_STRING(bwlq, type)				\
 									\
 static inline void __raw_writes##bwlq(volatile void __iomem *mem,	\
@@ -233,29 +291,22 @@ unsigned long long poke_real_address_q(u
  * doesn't exist, so everything must go through page tables.
  */
 #ifdef CONFIG_MMU
-void __iomem *__ioremap_caller(unsigned long offset, unsigned long size,
-			       unsigned long flags, void *caller);
+void __iomem *__ioremap_caller(phys_addr_t offset, unsigned long size,
+			       pgprot_t prot, void *caller);
 void __iounmap(void __iomem *addr);
 
 static inline void __iomem *
-__ioremap(unsigned long offset, unsigned long size, unsigned long flags)
+__ioremap(phys_addr_t offset, unsigned long size, pgprot_t prot)
 {
-	return __ioremap_caller(offset, size, flags, __builtin_return_address(0));
+	return __ioremap_caller(offset, size, prot, __builtin_return_address(0));
 }
 
 static inline void __iomem *
-__ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
+__ioremap_29bit(phys_addr_t offset, unsigned long size, pgprot_t prot)
 {
-#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB)
-	unsigned long last_addr = offset + size - 1;
-#endif
-	void __iomem *ret;
-
-	ret = __ioremap_trapped(offset, size);
-	if (ret)
-		return ret;
+#ifdef CONFIG_29BIT
+	phys_addr_t last_addr = offset + size - 1;
 
-#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB)
 	/*
 	 * For P1 and P2 space this is trivial, as everything is already
 	 * mapped. Uncached access for P1 addresses are done through P2.
@@ -263,7 +314,7 @@ __ioremap_mode(unsigned long offset, uns
 	 * mapping must be done by the PMB or by using page tables.
 	 */
 	if (likely(PXSEG(offset) < P3SEG && PXSEG(last_addr) < P3SEG)) {
-		if (unlikely(flags & _PAGE_CACHABLE))
+		if (unlikely(pgprot_val(prot) & _PAGE_CACHABLE))
 			return (void __iomem *)P1SEGADDR(offset);
 
 		return (void __iomem *)P2SEGADDR(offset);
@@ -274,26 +325,67 @@ __ioremap_mode(unsigned long offset, uns
 		return (void __iomem *)P4SEGADDR(offset);
 #endif
 
-	return __ioremap(offset, size, flags);
+	return NULL;
+}
+
+static inline void __iomem *
+__ioremap_mode(phys_addr_t offset, unsigned long size, pgprot_t prot)
+{
+	void __iomem *ret;
+
+	ret = __ioremap_trapped(offset, size);
+	if (ret)
+		return ret;
+
+	ret = __ioremap_29bit(offset, size, prot);
+	if (ret)
+		return ret;
+
+	return __ioremap(offset, size, prot);
 }
 #else
-#define __ioremap(offset, size, flags)		((void __iomem *)(offset))
-#define __ioremap_mode(offset, size, flags)	((void __iomem *)(offset))
+#define __ioremap(offset, size, prot)		((void __iomem *)(offset))
+#define __ioremap_mode(offset, size, prot)	((void __iomem *)(offset))
 #define __iounmap(addr)				do { } while (0)
 #endif /* CONFIG_MMU */
 
-#define ioremap(offset, size)				\
-	__ioremap_mode((offset), (size), 0)
-#define ioremap_nocache(offset, size)			\
-	__ioremap_mode((offset), (size), 0)
-#define ioremap_cache(offset, size)			\
-	__ioremap_mode((offset), (size), _PAGE_CACHABLE)
-#define p3_ioremap(offset, size, flags)			\
-	__ioremap((offset), (size), (flags))
-#define ioremap_prot(offset, size, flags)		\
-	__ioremap_mode((offset), (size), (flags))
-#define iounmap(addr)					\
-	__iounmap((addr))
+static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
+{
+	return __ioremap_mode(offset, size, PAGE_KERNEL_NOCACHE);
+}
+
+static inline void __iomem *
+ioremap_cache(phys_addr_t offset, unsigned long size)
+{
+	return __ioremap_mode(offset, size, PAGE_KERNEL);
+}
+
+#ifdef CONFIG_HAVE_IOREMAP_PROT
+static inline void __iomem *
+ioremap_prot(phys_addr_t offset, unsigned long size, unsigned long flags)
+{
+	return __ioremap_mode(offset, size, __pgprot(flags));
+}
+#endif
+
+#ifdef CONFIG_IOREMAP_FIXED
+extern void __iomem *ioremap_fixed(phys_addr_t, unsigned long, pgprot_t);
+extern int iounmap_fixed(void __iomem *);
+extern void ioremap_fixed_init(void);
+#else
+static inline void __iomem *
+ioremap_fixed(phys_addr_t phys_addr, unsigned long size, pgprot_t prot)
+{
+	BUG();
+	return NULL;
+}
+
+static inline void ioremap_fixed_init(void) { }
+static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
+#endif
+
+#define ioremap_nocache	ioremap
+#define iounmap		__iounmap
 
 #define maybebadio(port) \
 	printk(KERN_ERR "bad PC-like io %s:%u for port 0x%lx at 0x%08x\n", \
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/Kbuild linux-libre-2.6.34-gnu1/arch/sh/include/asm/Kbuild
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/Kbuild	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/Kbuild	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,8 @@
 include include/asm-generic/Kbuild.asm
 
-header-y += cachectl.h cpu-features.h
+header-y += cachectl.h
+header-y += cpu-features.h
+header-y += hw_breakpoint.h
 
 unifdef-y += unistd_32.h
 unifdef-y += unistd_64.h
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/kdebug.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/kdebug.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/kdebug.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/kdebug.h	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,8 @@ enum die_val {
 	DIE_TRAP,
 	DIE_NMI,
 	DIE_OOPS,
+	DIE_BREAKPOINT,
+	DIE_SSTEP,
 };
 
 #endif /* __ASM_SH_KDEBUG_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/mmu_context_32.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/mmu_context_32.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/mmu_context_32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/mmu_context_32.h	2010-05-16 17:17:36.000000000 -0400
@@ -49,11 +49,11 @@ static inline unsigned long get_asid(voi
 /* MMU_TTB is used for optimizing the fault handling. */
 static inline void set_TTB(pgd_t *pgd)
 {
-	ctrl_outl((unsigned long)pgd, MMU_TTB);
+	__raw_writel((unsigned long)pgd, MMU_TTB);
 }
 
 static inline pgd_t *get_TTB(void)
 {
-	return (pgd_t *)ctrl_inl(MMU_TTB);
+	return (pgd_t *)__raw_readl(MMU_TTB);
 }
 #endif /* __ASM_SH_MMU_CONTEXT_32_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/mmu_context.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/mmu_context.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/mmu_context.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/mmu_context.h	2010-05-16 17:17:36.000000000 -0400
@@ -158,7 +158,7 @@ static inline void enable_mmu(void)
 	unsigned int cpu = smp_processor_id();
 
 	/* Enable MMU */
-	ctrl_outl(MMU_CONTROL_INIT, MMUCR);
+	__raw_writel(MMU_CONTROL_INIT, MMUCR);
 	ctrl_barrier();
 
 	if (asid_cache(cpu) == NO_CONTEXT)
@@ -171,9 +171,9 @@ static inline void disable_mmu(void)
 {
 	unsigned long cr;
 
-	cr = ctrl_inl(MMUCR);
+	cr = __raw_readl(MMUCR);
 	cr &= ~MMU_CONTROL_INIT;
-	ctrl_outl(cr, MMUCR);
+	__raw_writel(cr, MMUCR);
 
 	ctrl_barrier();
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/mmu.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/mmu.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/mmu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/mmu.h	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,9 @@
 
 #define PMB_ADDR		0xf6100000
 #define PMB_DATA		0xf7100000
-#define PMB_ENTRY_MAX		16
+
+#define NR_PMB_ENTRIES		16
+
 #define PMB_E_MASK		0x0000000f
 #define PMB_E_SHIFT		8
 
@@ -25,11 +27,15 @@
 #define PMB_C			0x00000008
 #define PMB_WT			0x00000001
 #define PMB_UB			0x00000200
+#define PMB_CACHE_MASK		(PMB_C | PMB_WT | PMB_UB)
 #define PMB_V			0x00000100
 
 #define PMB_NO_ENTRY		(-1)
 
 #ifndef __ASSEMBLY__
+#include <linux/errno.h>
+#include <linux/threads.h>
+#include <asm/page.h>
 
 /* Default "unsigned long" context */
 typedef unsigned long mm_context_id_t[NR_CPUS];
@@ -47,29 +53,54 @@ typedef struct {
 #endif
 } mm_context_t;
 
-struct pmb_entry;
+#ifdef CONFIG_PMB
+/* arch/sh/mm/pmb.c */
+bool __in_29bit_mode(void);
 
-struct pmb_entry {
-	unsigned long vpn;
-	unsigned long ppn;
-	unsigned long flags;
+void pmb_init(void);
+int pmb_bolt_mapping(unsigned long virt, phys_addr_t phys,
+		     unsigned long size, pgprot_t prot);
+void __iomem *pmb_remap_caller(phys_addr_t phys, unsigned long size,
+			       pgprot_t prot, void *caller);
+int pmb_unmap(void __iomem *addr);
 
-	/*
-	 * 0 .. NR_PMB_ENTRIES for specific entry selection, or
-	 * PMB_NO_ENTRY to search for a free one
-	 */
-	int entry;
+#else
 
-	struct pmb_entry *next;
-	/* Adjacent entry link for contiguous multi-entry mappings */
-	struct pmb_entry *link;
-};
+static inline int
+pmb_bolt_mapping(unsigned long virt, phys_addr_t phys,
+		 unsigned long size, pgprot_t prot)
+{
+	return -EINVAL;
+}
+
+static inline void __iomem *
+pmb_remap_caller(phys_addr_t phys, unsigned long size,
+		 pgprot_t prot, void *caller)
+{
+	return NULL;
+}
+
+static inline int pmb_unmap(void __iomem *addr)
+{
+	return -EINVAL;
+}
+
+#define pmb_init(addr)		do { } while (0)
+
+#ifdef CONFIG_29BIT
+#define __in_29bit_mode()	(1)
+#else
+#define __in_29bit_mode()	(0)
+#endif
+
+#endif /* CONFIG_PMB */
+
+static inline void __iomem *
+pmb_remap(phys_addr_t phys, unsigned long size, pgprot_t prot)
+{
+	return pmb_remap_caller(phys, size, prot, __builtin_return_address(0));
+}
 
-/* arch/sh/mm/pmb.c */
-long pmb_remap(unsigned long virt, unsigned long phys,
-	       unsigned long size, unsigned long flags);
-void pmb_unmap(unsigned long addr);
-int pmb_init(void);
 #endif /* __ASSEMBLY__ */
 
 #endif /* __MMU_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/module.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/module.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/module.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/module.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,22 @@
 #ifndef _ASM_SH_MODULE_H
 #define _ASM_SH_MODULE_H
 
-#include <asm-generic/module.h>
+struct mod_arch_specific {
+#ifdef CONFIG_DWARF_UNWINDER
+	struct list_head fde_list;
+	struct list_head cie_list;
+#endif
+};
+
+#ifdef CONFIG_64BIT
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Sym Elf64_Sym
+#define Elf_Ehdr Elf64_Ehdr
+#else
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+#endif
 
 #ifdef CONFIG_CPU_LITTLE_ENDIAN
 # ifdef CONFIG_CPU_SH2
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/page.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/page.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/page.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/page.h	2010-05-16 17:17:36.000000000 -0400
@@ -45,6 +45,7 @@
 #endif
 
 #ifndef __ASSEMBLY__
+#include <asm/uncached.h>
 
 extern unsigned long shm_align_mask;
 extern unsigned long max_low_pfn, min_low_pfn;
@@ -56,7 +57,6 @@ pages_do_alias(unsigned long addr1, unsi
 	return (addr1 ^ addr2) & shm_align_mask;
 }
 
-
 #define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
 extern void copy_page(void *to, void *from);
 
@@ -88,7 +88,7 @@ typedef struct { unsigned long pgd; } pg
 #define __pte(x)	((pte_t) { (x) } )
 #else
 typedef struct { unsigned long long pte_low; } pte_t;
-typedef struct { unsigned long pgprot; } pgprot_t;
+typedef struct { unsigned long long pgprot; } pgprot_t;
 typedef struct { unsigned long pgd; } pgd_t;
 #define pte_val(x)	((x).pte_low)
 #define __pte(x)	((pte_t) { (x) } )
@@ -127,12 +127,7 @@ 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.
  */
-#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)
+#ifdef CONFIG_PMB
 #define __pa(x)	((unsigned long)(x)-PAGE_OFFSET+__MEMORY_START)
 #define __va(x)	((void *)((unsigned long)(x)+PAGE_OFFSET-__MEMORY_START))
 #else
@@ -140,6 +135,14 @@ typedef struct page *pgtable_t;
 #define __va(x)	((void *)((unsigned long)(x)+PAGE_OFFSET))
 #endif
 
+#ifdef CONFIG_UNCACHED_MAPPING
+#define UNCAC_ADDR(addr)	((addr) - PAGE_OFFSET + uncached_start)
+#define CAC_ADDR(addr)		((addr) - uncached_start + PAGE_OFFSET)
+#else
+#define UNCAC_ADDR(addr)	((addr))
+#define CAC_ADDR(addr)		((addr))
+#endif
+
 #define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
 #define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/pci.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/pci.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -15,20 +15,49 @@
  */
 struct pci_channel {
 	struct pci_channel	*next;
+	struct pci_bus		*bus;
 
 	struct pci_ops		*pci_ops;
-	struct resource		*io_resource;
-	struct resource		*mem_resource;
+
+	struct resource		*resources;
+	unsigned int		nr_resources;
 
 	unsigned long		io_offset;
 	unsigned long		mem_offset;
 
 	unsigned long		reg_base;
-
 	unsigned long		io_map_base;
+
+	unsigned int		index;
+	unsigned int		need_domain_info;
+
+	/* Optional error handling */
+	struct timer_list	err_timer, serr_timer;
+	unsigned int		err_irq, serr_irq;
 };
 
-extern void register_pci_controller(struct pci_channel *hose);
+/* arch/sh/drivers/pci/pci.c */
+extern int register_pci_controller(struct pci_channel *hose);
+extern void pcibios_report_status(unsigned int status_mask, int warn);
+
+/* arch/sh/drivers/pci/common.c */
+extern int early_read_config_byte(struct pci_channel *hose, int top_bus,
+				  int bus, int devfn, int offset, u8 *value);
+extern int early_read_config_word(struct pci_channel *hose, int top_bus,
+				  int bus, int devfn, int offset, u16 *value);
+extern int early_read_config_dword(struct pci_channel *hose, int top_bus,
+				   int bus, int devfn, int offset, u32 *value);
+extern int early_write_config_byte(struct pci_channel *hose, int top_bus,
+				   int bus, int devfn, int offset, u8 value);
+extern int early_write_config_word(struct pci_channel *hose, int top_bus,
+				   int bus, int devfn, int offset, u16 value);
+extern int early_write_config_dword(struct pci_channel *hose, int top_bus,
+				    int bus, int devfn, int offset, u32 value);
+extern void pcibios_enable_timers(struct pci_channel *hose);
+extern unsigned int pcibios_handle_status_errors(unsigned long addr,
+				 unsigned int status, struct pci_channel *hose);
+extern int pci_is_66mhz_capable(struct pci_channel *hose,
+				int top_bus, int current_bus);
 
 extern unsigned long PCIBIOS_MIN_IO, PCIBIOS_MIN_MEM;
 
@@ -54,25 +83,6 @@ static inline void pcibios_penalize_isa_
  */
 #define PCI_DMA_BUS_IS_PHYS	(dma_ops->is_phys)
 
-/* pci_unmap_{single,page} being a nop depends upon the
- * configuration.
- */
-#ifdef CONFIG_DMA_NONCOHERENT
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)		__u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME)		((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)	(((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME)		((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL)	(((PTR)->LEN_NAME) = (VAL))
-#else
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
-#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)
-#endif
-
 #ifdef CONFIG_PCI
 /*
  * None of the SH PCI controllers support MWI, it is always treated as a
@@ -99,20 +109,6 @@ static inline void pci_dma_burst_advice(
 }
 #endif
 
-#ifdef CONFIG_SUPERH32
-/*
- * If we're on an SH7751 or SH7780 PCI controller, PCI memory is mapped
- * at the end of the address space in a special non-translatable area.
- */
-#define PCI_MEM_FIXED_START	0xfd000000
-#define PCI_MEM_FIXED_END	(PCI_MEM_FIXED_START + 0x01000000)
-
-#define is_pci_memory_fixed_range(s, e)	\
-	((s) >= PCI_MEM_FIXED_START && (e) < PCI_MEM_FIXED_END)
-#else
-#define is_pci_memory_fixed_range(s, e)	(0)
-#endif
-
 /* Board-specific fixup routines. */
 int pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin);
 
@@ -122,6 +118,14 @@ extern void pcibios_resource_to_bus(stru
 extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
 				    struct pci_bus_region *region);
 
+#define pci_domain_nr(bus) ((struct pci_channel *)(bus)->sysdata)->index
+
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+	struct pci_channel *hose = bus->sysdata;
+	return hose->need_domain_info;
+}
+
 /* Chances are this interrupt is wired PC-style ...  */
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgalloc.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/pgalloc.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/pgalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -4,8 +4,16 @@
 #include <linux/quicklist.h>
 #include <asm/page.h>
 
-#define QUICK_PGD 0	/* We preserve special mappings over free */
-#define QUICK_PT 1	/* Other page table pages that are zero on free */
+#define QUICK_PT 0	/* Other page table pages that are zero on free */
+
+extern pgd_t *pgd_alloc(struct mm_struct *);
+extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
+
+#if PAGETABLE_LEVELS > 2
+extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd);
+extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address);
+extern void pmd_free(struct mm_struct *mm, pmd_t *pmd);
+#endif
 
 static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
 				       pte_t *pte)
@@ -20,28 +28,9 @@ static inline void pmd_populate(struct m
 }
 #define pmd_pgtable(pmd) pmd_page(pmd)
 
-static inline void pgd_ctor(void *x)
-{
-	pgd_t *pgd = x;
-
-	memcpy(pgd + USER_PTRS_PER_PGD,
-	       swapper_pg_dir + USER_PTRS_PER_PGD,
-	       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
-}
-
 /*
  * Allocate and free page tables.
  */
-static inline pgd_t *pgd_alloc(struct mm_struct *mm)
-{
-	return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor);
-}
-
-static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{
-	quicklist_free(QUICK_PGD, NULL, pgd);
-}
-
 static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
 					  unsigned long address)
 {
@@ -81,7 +70,6 @@ do {							\
 
 static inline void check_pgt_cache(void)
 {
-	quicklist_trim(QUICK_PGD, NULL, 25, 16);
 	quicklist_trim(QUICK_PT, NULL, 25, 16);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgtable-2level.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/pgtable-2level.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgtable-2level.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/pgtable-2level.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,23 @@
+#ifndef __ASM_SH_PGTABLE_2LEVEL_H
+#define __ASM_SH_PGTABLE_2LEVEL_H
+
+#include <asm-generic/pgtable-nopmd.h>
+
+/*
+ * traditional two-level paging structure
+ */
+#define PAGETABLE_LEVELS	2
+
+/* PTE bits */
+#define PTE_MAGNITUDE		2	/* 32-bit PTEs */
+
+#define PTE_SHIFT		PAGE_SHIFT
+#define PTE_BITS		(PTE_SHIFT - PTE_MAGNITUDE)
+
+/* PGD bits */
+#define PGDIR_SHIFT		(PTE_SHIFT + PTE_BITS)
+
+#define PTRS_PER_PGD		(PAGE_SIZE / (1 << PTE_MAGNITUDE))
+#define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
+
+#endif /* __ASM_SH_PGTABLE_2LEVEL_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgtable_32.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/pgtable_32.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgtable_32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/pgtable_32.h	2010-05-16 17:17:36.000000000 -0400
@@ -71,6 +71,8 @@
 #define _PAGE_EXT_KERN_WRITE	0x1000	/* EPR4-bit: Kernel space writable */
 #define _PAGE_EXT_KERN_READ	0x2000	/* EPR5-bit: Kernel space readable */
 
+#define _PAGE_EXT_WIRED		0x4000	/* software: Wire TLB entry */
+
 /* Wrapper for extended mode pgprot twiddling */
 #define _PAGE_EXT(x)		((unsigned long long)(x) << 32)
 
@@ -141,12 +143,14 @@ static inline unsigned long copy_ptea_at
 # elif defined(CONFIG_HUGETLB_PAGE_SIZE_64MB)
 #  define _PAGE_SZHUGE	(_PAGE_EXT_ESZ2 | _PAGE_EXT_ESZ3)
 # endif
+# define _PAGE_WIRED	(_PAGE_EXT(_PAGE_EXT_WIRED))
 #else
 # if defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
 #  define _PAGE_SZHUGE	(_PAGE_SZ1)
 # elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB)
 #  define _PAGE_SZHUGE	(_PAGE_SZ0 | _PAGE_SZ1)
 # endif
+# define _PAGE_WIRED	(0)
 #endif
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgtable-3level.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/pgtable-3level.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgtable-3level.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/pgtable-3level.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,56 @@
+#ifndef __ASM_SH_PGTABLE_3LEVEL_H
+#define __ASM_SH_PGTABLE_3LEVEL_H
+
+#include <asm-generic/pgtable-nopud.h>
+
+/*
+ * Some cores need a 3-level page table layout, for example when using
+ * 64-bit PTEs and 4K pages.
+ */
+#define PAGETABLE_LEVELS	3
+
+#define PTE_MAGNITUDE		3	/* 64-bit PTEs on SH-X2 TLB */
+
+/* PGD bits */
+#define PGDIR_SHIFT		30
+
+#define PTRS_PER_PGD		4
+#define USER_PTRS_PER_PGD	2
+
+/* PMD bits */
+#define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT - PTE_MAGNITUDE))
+#define PMD_SIZE	(1UL << PMD_SHIFT)
+#define PMD_MASK	(~(PMD_SIZE-1))
+
+#define PTRS_PER_PMD	((1 << PGDIR_SHIFT) / PMD_SIZE)
+
+#define pmd_ERROR(e) \
+	printk("%s:%d: bad pmd %016llx.\n", __FILE__, __LINE__, pmd_val(e))
+
+typedef struct { unsigned long long pmd; } pmd_t;
+#define pmd_val(x)	((x).pmd)
+#define __pmd(x)	((pmd_t) { (x) } )
+
+static inline unsigned long pud_page_vaddr(pud_t pud)
+{
+	return pud_val(pud);
+}
+
+#define pmd_index(address)	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
+{
+	return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address);
+}
+
+#define pud_none(x)	(!pud_val(x))
+#define pud_present(x)	(pud_val(x))
+#define pud_clear(xp)	do { set_pud(xp, __pud(0)); } while (0)
+#define	pud_bad(x)	(pud_val(x) & ~PAGE_MASK)
+
+/*
+ * (puds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pud(pudptr, pudval) do { *(pudptr) = (pudval); } while(0)
+
+#endif /* __ASM_SH_PGTABLE_3LEVEL_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgtable_64.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/pgtable_64.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgtable_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/pgtable_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -43,11 +43,6 @@ static __inline__ void set_pte(pte_t *pt
 }
 #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
 
-static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep)
-{
-	pmd_val(*pmdp) = (unsigned long) ptep;
-}
-
 /*
  * PGD defines. Top level.
  */
@@ -128,8 +123,21 @@ static __inline__ void pmd_set(pmd_t *pm
 #define _PAGE_DIRTY	0x400  /* software: page accessed in write */
 #define _PAGE_ACCESSED	0x800  /* software: page referenced */
 
+/* Wrapper for extended mode pgprot twiddling */
+#define _PAGE_EXT(x)		((unsigned long long)(x) << 32)
+
+/*
+ * We can use the sign-extended bits in the PTEL to get 32 bits of
+ * software flags. This works for now because no implementations uses
+ * anything above the PPN field.
+ */
+#define _PAGE_WIRED	_PAGE_EXT(0x001) /* software: wire the tlb entry */
+
+#define _PAGE_CLEAR_FLAGS	(_PAGE_PRESENT | _PAGE_FILE | _PAGE_SHARED | \
+				 _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_WIRED)
+
 /* Mask which drops software flags */
-#define _PAGE_FLAGS_HARDWARE_MASK	0xfffffffffffff3dbLL
+#define _PAGE_FLAGS_HARDWARE_MASK	(NEFF_MASK & ~(_PAGE_CLEAR_FLAGS))
 
 /*
  * HugeTLB support
@@ -203,12 +211,6 @@ static __inline__ void pmd_set(pmd_t *pm
 #define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~_PAGE_CACHABLE)
 
 /*
- * Handling allocation failures during page table setup.
- */
-extern void __handle_bad_pmd_kernel(pmd_t * pmd);
-#define __handle_bad_pmd(x)	__handle_bad_pmd_kernel(x)
-
-/*
  * PTE level access routines.
  *
  * Note1:
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgtable.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/pgtable.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,11 @@
 #ifndef __ASM_SH_PGTABLE_H
 #define __ASM_SH_PGTABLE_H
 
-#include <asm-generic/pgtable-nopmd.h>
+#ifdef CONFIG_X2TLB
+#include <asm/pgtable-3level.h>
+#else
+#include <asm/pgtable-2level.h>
+#endif
 #include <asm/page.h>
 
 #ifndef __ASSEMBLY__
@@ -51,28 +55,12 @@ static inline unsigned long long neff_si
 #define	NPHYS_SIGN	(1LL << (NPHYS - 1))
 #define	NPHYS_MASK	(-1LL << NPHYS)
 
-/*
- * traditional two-level paging structure
- */
-/* PTE bits */
-#if defined(CONFIG_X2TLB) || defined(CONFIG_SUPERH64)
-# define PTE_MAGNITUDE	3	/* 64-bit PTEs on extended mode SH-X2 TLB */
-#else
-# define PTE_MAGNITUDE	2	/* 32-bit PTEs */
-#endif
-#define PTE_SHIFT	PAGE_SHIFT
-#define PTE_BITS	(PTE_SHIFT - PTE_MAGNITUDE)
-
-/* PGD bits */
-#define PGDIR_SHIFT	(PTE_SHIFT + PTE_BITS)
 #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
 /* Entries per level */
 #define PTRS_PER_PTE	(PAGE_SIZE / (1 << PTE_MAGNITUDE))
-#define PTRS_PER_PGD	(PAGE_SIZE / sizeof(pgd_t))
 
-#define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
 #define FIRST_USER_ADDRESS	0
 
 #define PHYS_ADDR_MASK29		0x1fffffff
@@ -153,9 +141,9 @@ typedef pte_t *pte_addr_t;
 #define pte_pfn(x)		((unsigned long)(((x).pte_low >> PAGE_SHIFT)))
 
 /*
- * No page table caches to initialise
+ * Initialise the page table caches
  */
-#define pgtable_cache_init()	do { } while (0)
+extern void pgtable_cache_init(void);
 
 struct vm_area_struct;
 
@@ -165,8 +153,9 @@ extern void __update_tlb(struct vm_area_
 			 unsigned long address, pte_t pte);
 
 static inline void
-update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
+	pte_t pte = *ptep;
 	__update_cache(vma, address, pte);
 	__update_tlb(vma, address, pte);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/processor_32.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/processor_32.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/processor_32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/processor_32.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <asm/page.h>
 #include <asm/types.h>
 #include <asm/ptrace.h>
+#include <asm/hw_breakpoint.h>
 
 /*
  * Default implementation of macro that returns current
@@ -90,9 +91,9 @@ struct sh_fpu_soft_struct {
 	unsigned long entry_pc;
 };
 
-union sh_fpu_union {
-	struct sh_fpu_hard_struct hard;
-	struct sh_fpu_soft_struct soft;
+union thread_xstate {
+	struct sh_fpu_hard_struct hardfpu;
+	struct sh_fpu_soft_struct softfpu;
 };
 
 struct thread_struct {
@@ -100,38 +101,30 @@ struct thread_struct {
 	unsigned long sp;
 	unsigned long pc;
 
-	/* Hardware debugging registers */
-	unsigned long ubc_pc;
+	/* Various thread flags, see SH_THREAD_xxx */
+	unsigned long flags;
 
-	/* floating point info */
-	union sh_fpu_union fpu;
+	/* Save middle states of ptrace breakpoints */
+	struct perf_event *ptrace_bps[HBP_NUM];
 
 #ifdef CONFIG_SH_DSP
 	/* Dsp status information */
 	struct sh_dsp_struct dsp_status;
 #endif
-};
 
-/* Count of active tasks with UBC settings */
-extern int ubc_usercnt;
+	/* Extended processor state */
+	union thread_xstate *xstate;
+};
 
 #define INIT_THREAD  {						\
 	.sp = sizeof(init_stack) + (long) &init_stack,		\
+	.flags = 0,						\
 }
 
-/*
- * Do necessary setup to start up a newly executed thread.
- */
-#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
-
 /* Forward declaration, a strange C thing */
 struct task_struct;
-struct mm_struct;
+
+extern void start_thread(struct pt_regs *regs, unsigned long new_pc, unsigned long new_sp);
 
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/processor_64.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/processor_64.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/processor_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/processor_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -87,26 +87,31 @@ struct sh_fpu_hard_struct {
 	/* long status; * software status information */
 };
 
-#if 0
 /* Dummy fpu emulator  */
 struct sh_fpu_soft_struct {
-	unsigned long long fp_regs[32];
+	unsigned long fp_regs[64];
 	unsigned int fpscr;
 	unsigned char lookahead;
 	unsigned long entry_pc;
 };
-#endif
 
-union sh_fpu_union {
-	struct sh_fpu_hard_struct hard;
-	/* 'hard' itself only produces 32 bit alignment, yet we need
-	   to access it using 64 bit load/store as well. */
+union thread_xstate {
+	struct sh_fpu_hard_struct hardfpu;
+	struct sh_fpu_soft_struct softfpu;
+	/*
+	 * The structure definitions only produce 32 bit alignment, yet we need
+	 * to access them using 64 bit load/store as well.
+	 */
 	unsigned long long alignment_dummy;
 };
 
 struct thread_struct {
 	unsigned long sp;
 	unsigned long pc;
+
+	/* Various thread flags, see SH_THREAD_xxx */
+	unsigned long flags;
+
 	/* This stores the address of the pt_regs built during a context
 	   switch, or of the register save area built for a kernel mode
 	   exception.  It is used for backtracing the stack of a sleeping task
@@ -122,7 +127,7 @@ struct thread_struct {
 	/* Hardware debugging registers may come here */
 
 	/* floating point info */
-	union sh_fpu_union fpu;
+	union thread_xstate *xstate;
 };
 
 #define INIT_MMAP \
@@ -137,7 +142,7 @@ struct thread_struct {
 	.trap_no	= 0,			\
 	.error_code	= 0,			\
 	.address	= 0,			\
-	.fpu		= { { { 0, } }, }	\
+	.flags		= 0,			\
 }
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/processor.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/processor.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/processor.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/processor.h	2010-05-16 17:17:36.000000000 -0400
@@ -98,13 +98,34 @@ extern struct sh_cpuinfo cpu_data[];
 
 /* Forward decl */
 struct seq_operations;
+struct task_struct;
 
 extern struct pt_regs fake_swapper_regs;
 
+/* arch/sh/kernel/process.c */
+extern unsigned int xstate_size;
+extern void free_thread_xstate(struct task_struct *);
+extern struct kmem_cache *task_xstate_cachep;
+
+/* arch/sh/mm/alignment.c */
+extern int get_unalign_ctl(struct task_struct *, unsigned long addr);
+extern int set_unalign_ctl(struct task_struct *, unsigned int val);
+
+#define GET_UNALIGN_CTL(tsk, addr)	get_unalign_ctl((tsk), (addr))
+#define SET_UNALIGN_CTL(tsk, val)	set_unalign_ctl((tsk), (val))
+
+/* arch/sh/mm/init.c */
+extern unsigned int mem_init_done;
+
 /* arch/sh/kernel/setup.c */
 const char *get_cpu_subtype(struct sh_cpuinfo *c);
 extern const struct seq_operations cpuinfo_op;
 
+/* thread_struct flags */
+#define SH_THREAD_UAC_NOPRINT	(1 << 0)
+#define SH_THREAD_UAC_SIGBUS	(1 << 1)
+#define SH_THREAD_UAC_MASK	(SH_THREAD_UAC_NOPRINT | SH_THREAD_UAC_SIGBUS)
+
 /* processor boot mode configuration */
 #define MODE_PIN0 (1 << 0)
 #define MODE_PIN1 (1 << 1)
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -102,13 +102,15 @@ struct pt_dspregs {
 #define	PTRACE_GETDSPREGS	55	/* DSP registers */
 #define	PTRACE_SETDSPREGS	56
 
-#define PT_TEXT_END_ADDR 	240
-#define PT_TEXT_ADDR 		244	/* &(struct user)->start_code */
-#define PT_DATA_ADDR 		248	/* &(struct user)->start_data */
+#define PT_TEXT_END_ADDR	240
+#define PT_TEXT_ADDR		244	/* &(struct user)->start_code */
+#define PT_DATA_ADDR		248	/* &(struct user)->start_data */
 #define PT_TEXT_LEN		252
 
 #ifdef __KERNEL__
 #include <asm/addrspace.h>
+#include <asm/page.h>
+#include <asm/system.h>
 
 #define user_mode(regs)			(((regs)->sr & 0x40000000)==0)
 #define instruction_pointer(regs)	((unsigned long)(regs)->pc)
@@ -121,8 +123,12 @@ extern void show_regs(struct pt_regs *);
 struct task_struct;
 
 #define arch_has_single_step()	(1)
-extern void user_enable_single_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
+
+struct perf_event;
+struct perf_sample_data;
+
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+		      struct perf_sample_data *data, struct pt_regs *regs);
 
 #define task_pt_regs(task) \
 	((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE) - 1)
@@ -131,10 +137,8 @@ static inline unsigned long profile_pc(s
 {
 	unsigned long pc = instruction_pointer(regs);
 
-#ifdef P2SEG
-	if (pc >= P2SEG && pc < P3SEG)
-		pc -= 0x20000000;
-#endif
+	if (virt_addr_uncached(pc))
+		return CAC_ADDR(pc);
 
 	return pc;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/reboot.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/reboot.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/reboot.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/reboot.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,21 @@
+#ifndef __ASM_SH_REBOOT_H
+#define __ASM_SH_REBOOT_H
+
+#include <linux/kdebug.h>
+
+struct pt_regs;
+
+struct machine_ops {
+	void (*restart)(char *cmd);
+	void (*halt)(void);
+	void (*power_off)(void);
+	void (*shutdown)(void);
+	void (*crash_shutdown)(struct pt_regs *);
+};
+
+extern struct machine_ops machine_ops;
+
+/* arch/sh/kernel/machine_kexec.c */
+void native_machine_crash_shutdown(struct pt_regs *regs);
+
+#endif /* __ASM_SH_REBOOT_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/setup.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/setup.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/setup.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/setup.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@
 /* ... */
 #define COMMAND_LINE ((char *) (PARAM+0x100))
 
-int setup_early_printk(char *);
 void sh_mv_setup(void);
 
 #endif /* __KERNEL__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/sh_bios.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/sh_bios.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/sh_bios.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/sh_bios.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,18 +1,27 @@
 #ifndef __ASM_SH_BIOS_H
 #define __ASM_SH_BIOS_H
 
+#ifdef CONFIG_SH_STANDARD_BIOS
+
 /*
  * Copyright (C) 2000 Greg Banks, Mitch Davis
  * C API to interface to the standard LinuxSH BIOS
  * usually from within the early stages of kernel boot.
  */
-
-
 extern void sh_bios_console_write(const char *buf, unsigned int len);
-extern void sh_bios_char_out(char ch);
 extern void sh_bios_gdb_detach(void);
 
 extern void sh_bios_get_node_addr(unsigned char *node_addr);
 extern void sh_bios_shutdown(unsigned int how);
 
+extern void sh_bios_vbr_init(void);
+extern void sh_bios_vbr_reload(void);
+
+#else
+
+static inline void sh_bios_vbr_init(void) { }
+static inline void sh_bios_vbr_reload(void) { }
+
+#endif /* CONFIG_SH_STANDARD_BIOS */
+
 #endif /* __ASM_SH_BIOS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/siu.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/siu.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/siu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/siu.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,26 @@
+/*
+ * platform header for the SIU ASoC driver
+ *
+ * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef ASM_SIU_H
+#define ASM_SIU_H
+
+#include <asm/dmaengine.h>
+
+struct device;
+
+struct siu_platform {
+	struct device *dma_dev;
+	enum sh_dmae_slave_chan_id dma_slave_tx_a;
+	enum sh_dmae_slave_chan_id dma_slave_rx_a;
+	enum sh_dmae_slave_chan_id dma_slave_tx_b;
+	enum sh_dmae_slave_chan_id dma_slave_rx_b;
+};
+
+#endif /* ASM_SIU_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/suspend.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/suspend.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/suspend.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/suspend.h	2010-05-16 17:17:36.000000000 -0400
@@ -92,5 +92,6 @@ extern unsigned long sh_mobile_sleep_sup
 #define SUSP_SH_USTANDBY	(1 << 3) /* SH-Mobile U-standby mode */
 #define SUSP_SH_SF		(1 << 4) /* Enable self-refresh */
 #define SUSP_SH_MMU		(1 << 5) /* Save/restore MMU and cache */
+#define SUSP_SH_REGS		(1 << 6) /* Save/restore registers */
 
 #endif /* _ASM_SH_SUSPEND_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/syscall.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/syscall.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/syscall.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/syscall.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,8 @@
 #ifndef __ASM_SH_SYSCALL_H
 #define __ASM_SH_SYSCALL_H
 
+extern const unsigned long sys_call_table[];
+
 #ifdef CONFIG_SUPERH32
 # include "syscall_32.h"
 #else
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/syscalls.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/syscalls.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/syscalls.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/syscalls.h	2010-05-16 17:17:36.000000000 -0400
@@ -3,17 +3,12 @@
 
 #ifdef __KERNEL__
 
-struct old_utsname;
-
 asmlinkage int old_mmap(unsigned long addr, unsigned long len,
 			unsigned long prot, unsigned long flags,
 			int fd, unsigned long off);
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
 			  unsigned long prot, unsigned long flags,
 			  unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_ipc(uint call, int first, int second,
-		       int third, void __user *ptr, long fifth);
-asmlinkage int sys_uname(struct old_utsname __user *name);
 
 #ifdef CONFIG_SUPERH32
 # include "syscalls_32.h"
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/system_32.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/system_32.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/system_32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/system_32.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
 #define __ASM_SH_SYSTEM_32_H
 
 #include <linux/types.h>
+#include <asm/mmu.h>
 
 #ifdef CONFIG_SH_DSP
 
@@ -144,9 +145,6 @@ do {								\
 		__restore_dsp(prev);				\
 } while (0)
 
-#define __uses_jump_to_uncached \
-	noinline __attribute__ ((__section__ (".uncached.text")))
-
 /*
  * Jump to uncached area.
  * When handling TLB or caches, we need to do it from an uncached area.
@@ -216,6 +214,17 @@ static inline reg_size_t register_align(
 int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
 			    struct mem_access *ma, int);
 
+static inline void trigger_address_error(void)
+{
+	if (__in_29bit_mode())
+		__asm__ __volatile__ (
+			"ldc %0, sr\n\t"
+			"mov.l @%1, %0"
+			:
+			: "r" (0x10000000), "r" (0x80000001)
+		);
+}
+
 asmlinkage void do_address_error(struct pt_regs *regs,
 				 unsigned long writeaccess,
 				 unsigned long address);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/system_64.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/system_64.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/system_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/system_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 /*
  *	switch_to() should switch tasks to task nr n, first
  */
+struct thread_struct;
 struct task_struct *sh64_switch_to(struct task_struct *prev,
 				   struct thread_struct *prev_thread,
 				   struct task_struct *next,
@@ -33,8 +34,6 @@ do {								\
 			      &next->thread);			\
 } while (0)
 
-#define __uses_jump_to_uncached
-
 #define jump_to_uncached()	do { } while (0)
 #define back_to_cached()	do { } while (0)
 
@@ -48,6 +47,13 @@ static inline reg_size_t register_align(
 	return (unsigned long long)(signed long long)(signed long)val;
 }
 
+extern void phys_stext(void);
+
+static inline void trigger_address_error(void)
+{
+	phys_stext();
+}
+
 #define SR_BL_LL	0x0000000010000000LL
 
 static inline void set_bl_bit(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/system.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/system.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/system.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
 #include <linux/compiler.h>
 #include <linux/linkage.h>
 #include <asm/types.h>
-#include <asm/ptrace.h>
 
 #define AT_VECTOR_SIZE_ARCH 5 /* entries in ARCH_DLINFO */
 
@@ -32,7 +31,7 @@
 #define mb()		__asm__ __volatile__ ("synco": : :"memory")
 #define rmb()		mb()
 #define wmb()		__asm__ __volatile__ ("synco": : :"memory")
-#define ctrl_barrier()	__icbi(0xa8000000)
+#define ctrl_barrier()	__icbi(PAGE_OFFSET)
 #define read_barrier_depends()	do { } while(0)
 #else
 #define mb()		__asm__ __volatile__ ("": : :"memory")
@@ -114,6 +113,8 @@ static inline unsigned long __cmpxchg(vo
 				    (unsigned long)_n_, sizeof(*(ptr))); \
   })
 
+struct pt_regs;
+
 extern void die(const char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn));
 void free_initmem(void);
 void free_initrd_mem(unsigned long start, unsigned long end);
@@ -137,14 +138,14 @@ extern unsigned int instruction_size(uns
 #endif
 
 extern unsigned long cached_to_uncached;
+extern unsigned long uncached_size;
 
 extern struct dentry *sh_debugfs_root;
 
 void per_cpu_trap_init(void);
 void default_idle(void);
 void cpu_idle_wait(void);
-
-asmlinkage void break_point_trap(void);
+void stop_this_cpu(void *);
 
 #ifdef CONFIG_SUPERH32
 #define BUILD_TRAP_HANDLER(name)					\
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/thread_info.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/thread_info.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/thread_info.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/thread_info.h	2010-05-16 17:17:36.000000000 -0400
@@ -93,14 +93,16 @@ static inline struct thread_info *curren
 
 #define THREAD_SIZE_ORDER	(THREAD_SHIFT - PAGE_SHIFT)
 
-#else /* THREAD_SHIFT < PAGE_SHIFT */
-
-#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
+#endif
 
 extern struct thread_info *alloc_thread_info(struct task_struct *tsk);
 extern void free_thread_info(struct thread_info *ti);
+extern void arch_task_cache_init(void);
+#define arch_task_cache_init arch_task_cache_init
+extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
+extern void init_thread_xstate(void);
 
-#endif /* THREAD_SHIFT < PAGE_SHIFT */
+#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
 
 #endif /* __ASSEMBLY__ */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/tlb.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/tlb.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/tlb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/tlb.h	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #ifdef CONFIG_MMU
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
 
 /*
  * TLB handling.  This allows us to remove pages from the page
@@ -97,6 +98,22 @@ tlb_end_vma(struct mmu_gather *tlb, stru
 
 #define tlb_migrate_finish(mm)		do { } while (0)
 
+#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SUPERH64)
+extern void tlb_wire_entry(struct vm_area_struct *, unsigned long, pte_t);
+extern void tlb_unwire_entry(void);
+#else
+static inline void tlb_wire_entry(struct vm_area_struct *vma ,
+				  unsigned long addr, pte_t pte)
+{
+	BUG();
+}
+
+static inline void tlb_unwire_entry(void)
+{
+	BUG();
+}
+#endif
+
 #else /* CONFIG_MMU */
 
 #define tlb_start_vma(tlb, vma)				do { } while (0)
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/topology.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/topology.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/topology.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/topology.h	2010-05-16 17:17:36.000000000 -0400
@@ -35,7 +35,7 @@
 
 #define pcibus_to_node(bus)	((void)(bus), -1)
 #define cpumask_of_pcibus(bus)	(pcibus_to_node(bus) == -1 ? \
-					CPU_MASK_ALL_PTR : \
+					cpu_all_mask : \
 					cpumask_of_node(pcibus_to_node(bus)))
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/ubc.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/ubc.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/ubc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/ubc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,64 +0,0 @@
-/*
- * include/asm-sh/ubc.h
- *
- * Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2002, 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 __ASM_SH_UBC_H
-#define __ASM_SH_UBC_H
-#ifdef __KERNEL__
-
-#include <cpu/ubc.h>
-
-/* User Break Controller */
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
-#define UBC_TYPE_SH7729	(current_cpu_data.type == CPU_SH7729)
-#else
-#define UBC_TYPE_SH7729	0
-#endif
-
-#define BAMR_ASID		(1 << 2)
-#define BAMR_NONE		0
-#define BAMR_10			0x1
-#define BAMR_12			0x2
-#define BAMR_ALL		0x3
-#define BAMR_16			0x8
-#define BAMR_20			0x9
-
-#define BBR_INST		(1 << 4)
-#define BBR_DATA		(2 << 4)
-#define BBR_READ		(1 << 2)
-#define BBR_WRITE		(2 << 2)
-#define BBR_BYTE		0x1
-#define BBR_HALF		0x2
-#define BBR_LONG		0x3
-#define BBR_QUAD		(1 << 6)	/* SH7750 */
-#define BBR_CPU			(1 << 6)	/* SH7709A,SH7729 */
-#define BBR_DMA			(2 << 6)	/* SH7709A,SH7729 */
-
-#define BRCR_CMFA		(1 << 15)
-#define BRCR_CMFB		(1 << 14)
-
-#if defined CONFIG_CPU_SH2A
-#define BRCR_CMFCA		(1 << 15)
-#define BRCR_CMFCB		(1 << 14)
-#define BRCR_CMFDA		(1 << 13)
-#define BRCR_CMFDB		(1 << 12)
-#define BRCR_PCBB		(1 << 6)	/* 1: after execution */
-#define BRCR_PCBA		(1 << 5)	/* 1: after execution */
-#define BRCR_PCTE		0
-#else
-#define BRCR_PCTE		(1 << 11)
-#define BRCR_PCBA		(1 << 10)	/* 1: after execution */
-#define BRCR_DBEB		(1 << 7)
-#define BRCR_PCBB		(1 << 6)
-#define BRCR_SEQ		(1 << 3)
-#define BRCR_UBDE		(1 << 0)
-#endif
-
-#endif /* __KERNEL__ */
-#endif /* __ASM_SH_UBC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/uncached.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/uncached.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/uncached.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/uncached.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,18 @@
+#ifndef __ASM_SH_UNCACHED_H
+#define __ASM_SH_UNCACHED_H
+
+#include <linux/bug.h>
+
+#ifdef CONFIG_UNCACHED_MAPPING
+extern unsigned long uncached_start, uncached_end;
+
+extern int virt_addr_uncached(unsigned long kaddr);
+extern void uncached_init(void);
+extern void uncached_resize(unsigned long size);
+#else
+#define virt_addr_uncached(kaddr)	(0)
+#define uncached_init()			do { } while (0)
+#define uncached_resize(size)		BUG()
+#endif
+
+#endif /* __ASM_SH_UNCACHED_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/unistd_32.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/unistd_32.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/unistd_32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/unistd_32.h	2010-05-16 17:17:36.000000000 -0400
@@ -358,6 +358,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
@@ -370,6 +371,7 @@
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_UNAME
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/unistd_64.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/unistd_64.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/unistd_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/unistd_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -398,6 +398,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
@@ -410,6 +411,7 @@
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_UNAME
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/vmlinux.lds.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/vmlinux.lds.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/vmlinux.lds.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/vmlinux.lds.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,4 +14,12 @@
 #define DWARF_EH_FRAME
 #endif
 
+#ifdef CONFIG_SUPERH64
+#define EXTRA_TEXT		\
+	*(.text64)		\
+	*(.text..SHmedia32)
+#else
+#define EXTRA_TEXT
+#endif
+
 #endif /* __ASM_SH_VMLINUX_LDS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/asm/watchdog.h linux-libre-2.6.34-gnu1/arch/sh/include/asm/watchdog.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/asm/watchdog.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/asm/watchdog.h	2010-05-16 17:17:36.000000000 -0400
@@ -70,7 +70,7 @@
  */
 static inline __u32 sh_wdt_read_cnt(void)
 {
-	return ctrl_inl(WTCNT_R);
+	return __raw_readl(WTCNT_R);
 }
 
 /**
@@ -82,7 +82,7 @@ static inline __u32 sh_wdt_read_cnt(void
  */
 static inline void sh_wdt_write_cnt(__u32 val)
 {
-	ctrl_outl((WTCNT_HIGH << 24) | (__u32)val, WTCNT);
+	__raw_writel((WTCNT_HIGH << 24) | (__u32)val, WTCNT);
 }
 
 /**
@@ -94,7 +94,7 @@ static inline void sh_wdt_write_cnt(__u3
  */
 static inline void sh_wdt_write_bst(__u32 val)
 {
-	ctrl_outl((WTBST_HIGH << 24) | (__u32)val, WTBST);
+	__raw_writel((WTBST_HIGH << 24) | (__u32)val, WTBST);
 }
 /**
  * 	sh_wdt_read_csr - Read from Control/Status Register
@@ -103,7 +103,7 @@ static inline void sh_wdt_write_bst(__u3
  */
 static inline __u32 sh_wdt_read_csr(void)
 {
-	return ctrl_inl(WTCSR_R);
+	return __raw_readl(WTCSR_R);
 }
 
 /**
@@ -115,7 +115,7 @@ static inline __u32 sh_wdt_read_csr(void
  */
 static inline void sh_wdt_write_csr(__u32 val)
 {
-	ctrl_outl((WTCSR_HIGH << 24) | (__u32)val, WTCSR);
+	__raw_writel((WTCSR_HIGH << 24) | (__u32)val, WTCSR);
 }
 #else
 /**
@@ -124,7 +124,7 @@ static inline void sh_wdt_write_csr(__u3
  */
 static inline __u8 sh_wdt_read_cnt(void)
 {
-	return ctrl_inb(WTCNT_R);
+	return __raw_readb(WTCNT_R);
 }
 
 /**
@@ -136,7 +136,7 @@ static inline __u8 sh_wdt_read_cnt(void)
  */
 static inline void sh_wdt_write_cnt(__u8 val)
 {
-	ctrl_outw((WTCNT_HIGH << 8) | (__u16)val, WTCNT);
+	__raw_writew((WTCNT_HIGH << 8) | (__u16)val, WTCNT);
 }
 
 /**
@@ -146,7 +146,7 @@ static inline void sh_wdt_write_cnt(__u8
  */
 static inline __u8 sh_wdt_read_csr(void)
 {
-	return ctrl_inb(WTCSR_R);
+	return __raw_readb(WTCSR_R);
 }
 
 /**
@@ -158,7 +158,7 @@ static inline __u8 sh_wdt_read_csr(void)
  */
 static inline void sh_wdt_write_csr(__u8 val)
 {
-	ctrl_outw((WTCSR_HIGH << 8) | (__u16)val, WTCSR);
+	__raw_writew((WTCSR_HIGH << 8) | (__u16)val, WTCSR);
 }
 #endif /* CONFIG_CPU_SUBTYPE_SH7785 || CONFIG_CPU_SUBTYPE_SH7780 */
 #endif /* __KERNEL__ */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh2/cpu/ubc.h linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh2/cpu/ubc.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh2/cpu/ubc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh2/cpu/ubc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,32 +0,0 @@
-/*
- * include/asm-sh/cpu-sh2/ubc.h
- *
- * 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 __ASM_CPU_SH2_UBC_H
-#define __ASM_CPU_SH2_UBC_H
-
-#define UBC_BARA                0xffffff40
-#define UBC_BAMRA               0xffffff44
-#define UBC_BBRA                0xffffff48
-#define UBC_BARB                0xffffff60
-#define UBC_BAMRB               0xffffff64
-#define UBC_BBRB                0xffffff68
-#define UBC_BDRB                0xffffff70
-#define UBC_BDMRB               0xffffff74
-#define UBC_BRCR                0xffffff78
-
-/*
- * We don't have any ASID changes to make in the UBC on the SH-2.
- *
- * Make these purposely invalid to track misuse.
- */
-#define UBC_BASRA		0x00000000
-#define UBC_BASRB		0x00000000
-
-#endif /* __ASM_CPU_SH2_UBC_H */
-
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh2/cpu/watchdog.h linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh2/cpu/watchdog.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh2/cpu/watchdog.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh2/cpu/watchdog.h	2010-05-16 17:17:36.000000000 -0400
@@ -44,7 +44,7 @@ static inline __u8 sh_wdt_read_rstcsr(vo
 	/*
 	 * Same read/write brain-damage as for WTCNT here..
 	 */
-	return ctrl_inb(RSTCSR_R);
+	return __raw_readb(RSTCSR_R);
 }
 
 /**
@@ -62,7 +62,7 @@ static inline void sh_wdt_write_rstcsr(_
 	 * we can't presently touch the WOVF bit, since the upper byte
 	 * has to be swapped for this. So just leave it alone..
 	 */
-	ctrl_outw((WTCNT_HIGH << 8) | (__u16)val, RSTCSR);
+	__raw_writeb((WTCNT_HIGH << 8) | (__u16)val, RSTCSR);
 }
 
 #endif /* __ASM_CPU_SH2_WATCHDOG_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh3/cpu/dac.h linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh3/cpu/dac.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh3/cpu/dac.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh3/cpu/dac.h	2010-05-16 17:17:36.000000000 -0400
@@ -17,25 +17,25 @@
 static __inline__ void sh_dac_enable(int channel)
 {
 	unsigned char v;
-	v = ctrl_inb(DACR);
+	v = __raw_readb(DACR);
 	if(channel) v |= DACR_DAOE1;
 	else v |= DACR_DAOE0;
-	ctrl_outb(v,DACR);
+	__raw_writeb(v,DACR);
 }
 
 static __inline__ void sh_dac_disable(int channel)
 {
 	unsigned char v;
-	v = ctrl_inb(DACR);
+	v = __raw_readb(DACR);
 	if(channel) v &= ~DACR_DAOE1;
 	else v &= ~DACR_DAOE0;
-	ctrl_outb(v,DACR);
+	__raw_writeb(v,DACR);
 }
 
 static __inline__ void sh_dac_output(u8 value, int channel)
 {
-	if(channel) ctrl_outb(value,DADR1);
-	else ctrl_outb(value,DADR0);
+	if(channel) __raw_writeb(value,DADR1);
+	else __raw_writeb(value,DADR0);
 }
 
 #endif /* __ASM_CPU_SH3_DAC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh3/cpu/dma.h linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh3/cpu/dma.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh3/cpu/dma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh3/cpu/dma.h	2010-05-16 17:17:36.000000000 -0400
@@ -20,27 +20,4 @@
 #define TS_32		0x00000010
 #define TS_128		0x00000018
 
-#define CHCR_TS_MASK	0x18
-#define CHCR_TS_SHIFT	3
-
-#define DMAOR_INIT	DMAOR_DME
-
-/*
- * The SuperH DMAC supports a number of transmit sizes, we list them here,
- * with their respective values as they appear in the CHCR registers.
- */
-enum {
-	XMIT_SZ_8BIT,
-	XMIT_SZ_16BIT,
-	XMIT_SZ_32BIT,
-	XMIT_SZ_128BIT,
-};
-
-static unsigned int ts_shift[] __maybe_unused = {
-	[XMIT_SZ_8BIT]		= 0,
-	[XMIT_SZ_16BIT]		= 1,
-	[XMIT_SZ_32BIT]		= 2,
-	[XMIT_SZ_128BIT]	= 4,
-};
-
 #endif /* __ASM_CPU_SH3_DMA_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh3/cpu/dma-register.h linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh3/cpu/dma-register.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh3/cpu/dma-register.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh3/cpu/dma-register.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,41 @@
+/*
+ * SH3 CPU-specific DMA definitions, used by both DMA drivers
+ *
+ * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef CPU_DMA_REGISTER_H
+#define CPU_DMA_REGISTER_H
+
+#define CHCR_TS_LOW_MASK	0x18
+#define CHCR_TS_LOW_SHIFT	3
+#define CHCR_TS_HIGH_MASK	0
+#define CHCR_TS_HIGH_SHIFT	0
+
+#define DMAOR_INIT	DMAOR_DME
+
+/*
+ * The SuperH DMAC supports a number of transmit sizes, we list them here,
+ * with their respective values as they appear in the CHCR registers.
+ */
+enum {
+	XMIT_SZ_8BIT,
+	XMIT_SZ_16BIT,
+	XMIT_SZ_32BIT,
+	XMIT_SZ_128BIT,
+};
+
+/* log2(size / 8) - used to calculate number of transfers */
+#define TS_SHIFT {			\
+	[XMIT_SZ_8BIT]		= 0,	\
+	[XMIT_SZ_16BIT]		= 1,	\
+	[XMIT_SZ_32BIT]		= 2,	\
+	[XMIT_SZ_128BIT]	= 4,	\
+}
+
+#define TS_INDEX2VAL(i)	(((i) & 3) << CHCR_TS_LOW_SHIFT)
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh3/cpu/ubc.h linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh3/cpu/ubc.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh3/cpu/ubc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh3/cpu/ubc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,42 +0,0 @@
-/*
- * include/asm-sh/cpu-sh3/ubc.h
- *
- * Copyright (C) 1999 Niibe Yutaka
- * 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 __ASM_CPU_SH3_UBC_H
-#define __ASM_CPU_SH3_UBC_H
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7710) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721)
-#define UBC_BARA		0xa4ffffb0
-#define UBC_BAMRA		0xa4ffffb4
-#define UBC_BBRA		0xa4ffffb8
-#define UBC_BASRA		0xffffffe4
-#define UBC_BARB		0xa4ffffa0
-#define UBC_BAMRB		0xa4ffffa4
-#define UBC_BBRB		0xa4ffffa8
-#define UBC_BASRB		0xffffffe8
-#define UBC_BDRB		0xa4ffff90
-#define UBC_BDMRB		0xa4ffff94
-#define UBC_BRCR		0xa4ffff98
-#else
-#define UBC_BARA                0xffffffb0
-#define UBC_BAMRA               0xffffffb4
-#define UBC_BBRA                0xffffffb8
-#define UBC_BASRA               0xffffffe4
-#define UBC_BARB                0xffffffa0
-#define UBC_BAMRB               0xffffffa4
-#define UBC_BBRB                0xffffffa8
-#define UBC_BASRB               0xffffffe8
-#define UBC_BDRB                0xffffff90
-#define UBC_BDMRB               0xffffff94
-#define UBC_BRCR                0xffffff98
-#endif
-
-#endif /* __ASM_CPU_SH3_UBC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/addrspace.h linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/addrspace.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/addrspace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/addrspace.h	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,15 @@
 #define P4SEG_TLB_DATA	0xf7000000
 #define P4SEG_REG_BASE	0xff000000
 
+#define PA_AREA0	0x00000000
+#define PA_AREA1	0x04000000
+#define PA_AREA2	0x08000000
+#define PA_AREA3	0x0c000000
+#define PA_AREA4	0x10000000
+#define PA_AREA5	0x14000000
+#define PA_AREA6	0x18000000
+#define PA_AREA7	0x1c000000
+
 #define PA_AREA5_IO	0xb4000000	/* Area 5 IO Memory */
 #define PA_AREA6_IO	0xb8000000	/* Area 6 IO Memory */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/dma.h linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/dma.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/dma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/dma.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,11 +5,8 @@
 
 #ifdef CONFIG_CPU_SH4A
 
-#define DMAOR_INIT	(DMAOR_DME)
-#define CHCR_TS_MASK	0x18
-#define CHCR_TS_SHIFT	3
-
 #include <cpu/dma-sh4a.h>
+
 #else /* CONFIG_CPU_SH4A */
 /*
  * SH7750/SH7751/SH7760
@@ -19,7 +16,6 @@
 #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 */
@@ -29,35 +25,8 @@
 #define TS_32		0x00000030
 #define TS_64		0x00000000
 
-#define CHCR_TS_MASK	0x70
-#define CHCR_TS_SHIFT	4
-
 #define DMAOR_COD	0x00000008
 
-/*
- * 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_64BIT,
-	XMIT_SZ_8BIT,
-	XMIT_SZ_16BIT,
-	XMIT_SZ_32BIT,
-	XMIT_SZ_256BIT,
-};
-
-/*
- * The DMA count is defined as the number of bytes to transfer.
- */
-static unsigned int ts_shift[] __maybe_unused = {
-	[XMIT_SZ_64BIT]		= 3,
-	[XMIT_SZ_8BIT]		= 0,
-	[XMIT_SZ_16BIT]		= 1,
-	[XMIT_SZ_32BIT]		= 2,
-	[XMIT_SZ_256BIT]	= 5,
-};
 #endif
 
 #endif /* __ASM_CPU_SH4_DMA_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/dma-register.h linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/dma-register.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/dma-register.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/dma-register.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,112 @@
+/*
+ * SH4 CPU-specific DMA definitions, used by both DMA drivers
+ *
+ * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef CPU_DMA_REGISTER_H
+#define CPU_DMA_REGISTER_H
+
+/* SH7751/7760/7780 DMA IRQ sources */
+
+#ifdef CONFIG_CPU_SH4A
+
+#define DMAOR_INIT	DMAOR_DME
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7343) || \
+	defined(CONFIG_CPU_SUBTYPE_SH7730)
+#define CHCR_TS_LOW_MASK	0x00000018
+#define CHCR_TS_LOW_SHIFT	3
+#define CHCR_TS_HIGH_MASK	0
+#define CHCR_TS_HIGH_SHIFT	0
+#elif defined(CONFIG_CPU_SUBTYPE_SH7722) || \
+	defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define CHCR_TS_LOW_MASK	0x00000018
+#define CHCR_TS_LOW_SHIFT	3
+#define CHCR_TS_HIGH_MASK	0x00300000
+#define CHCR_TS_HIGH_SHIFT	(20 - 2)	/* 2 bits for shifted low TS */
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
+	defined(CONFIG_CPU_SUBTYPE_SH7764)
+#define CHCR_TS_LOW_MASK	0x00000018
+#define CHCR_TS_LOW_SHIFT	3
+#define CHCR_TS_HIGH_MASK	0
+#define CHCR_TS_HIGH_SHIFT	0
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+#define CHCR_TS_LOW_MASK	0x00000018
+#define CHCR_TS_LOW_SHIFT	3
+#define CHCR_TS_HIGH_MASK	0
+#define CHCR_TS_HIGH_SHIFT	0
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
+#define CHCR_TS_LOW_MASK	0x00000018
+#define CHCR_TS_LOW_SHIFT	3
+#define CHCR_TS_HIGH_MASK	0
+#define CHCR_TS_HIGH_SHIFT	0
+#else /* SH7785 */
+#define CHCR_TS_LOW_MASK	0x00000018
+#define CHCR_TS_LOW_SHIFT	3
+#define CHCR_TS_HIGH_MASK	0
+#define CHCR_TS_HIGH_SHIFT	0
+#endif
+
+/* Transmit sizes and respective CHCR register values */
+enum {
+	XMIT_SZ_8BIT		= 0,
+	XMIT_SZ_16BIT		= 1,
+	XMIT_SZ_32BIT		= 2,
+	XMIT_SZ_64BIT		= 7,
+	XMIT_SZ_128BIT		= 3,
+	XMIT_SZ_256BIT		= 4,
+	XMIT_SZ_128BIT_BLK	= 0xb,
+	XMIT_SZ_256BIT_BLK	= 0xc,
+};
+
+/* log2(size / 8) - used to calculate number of transfers */
+#define TS_SHIFT {			\
+	[XMIT_SZ_8BIT]		= 0,	\
+	[XMIT_SZ_16BIT]		= 1,	\
+	[XMIT_SZ_32BIT]		= 2,	\
+	[XMIT_SZ_64BIT]		= 3,	\
+	[XMIT_SZ_128BIT]	= 4,	\
+	[XMIT_SZ_256BIT]	= 5,	\
+	[XMIT_SZ_128BIT_BLK]	= 4,	\
+	[XMIT_SZ_256BIT_BLK]	= 5,	\
+}
+
+#define TS_INDEX2VAL(i)	((((i) & 3) << CHCR_TS_LOW_SHIFT) | \
+			 (((i) & 0xc) << CHCR_TS_HIGH_SHIFT))
+
+#else /* CONFIG_CPU_SH4A */
+
+#define DMAOR_INIT	(0x8000 | DMAOR_DME)
+
+#define CHCR_TS_LOW_MASK	0x70
+#define CHCR_TS_LOW_SHIFT	4
+#define CHCR_TS_HIGH_MASK	0
+#define CHCR_TS_HIGH_SHIFT	0
+
+/* Transmit sizes and respective CHCR register values */
+enum {
+	XMIT_SZ_8BIT	= 1,
+	XMIT_SZ_16BIT	= 2,
+	XMIT_SZ_32BIT	= 3,
+	XMIT_SZ_64BIT	= 0,
+	XMIT_SZ_256BIT	= 4,
+};
+
+/* log2(size / 8) - used to calculate number of transfers */
+#define TS_SHIFT {			\
+	[XMIT_SZ_8BIT]		= 0,	\
+	[XMIT_SZ_16BIT]		= 1,	\
+	[XMIT_SZ_32BIT]		= 2,	\
+	[XMIT_SZ_64BIT]		= 3,	\
+	[XMIT_SZ_256BIT]	= 5,	\
+}
+
+#define TS_INDEX2VAL(i)	(((i) & 7) << CHCR_TS_LOW_SHIFT)
+
+#endif /* CONFIG_CPU_SH4A */
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,22 +2,26 @@
 #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
+#define SH_DMARS_BASE0	0xFE009000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
+#define DMTE0_IRQ	48
+#define DMTE4_IRQ	76
+#define DMAE0_IRQ	78	/* DMA Error IRQ*/
+#define SH_DMAC_BASE0	0xFE008020
+#define SH_DMARS_BASE0	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) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define SH_DMARS_BASE0	0xFF609000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
 #define DMTE0_IRQ	48	/* DMAC0A*/
 #define DMTE4_IRQ	76	/* DMAC0B */
 #define DMTE6_IRQ	40
@@ -29,7 +33,21 @@
 #define DMAE1_IRQ	74	/* DMA Error IRQ*/
 #define SH_DMAC_BASE0	0xFE008020
 #define SH_DMAC_BASE1	0xFDC08020
-#define SH_DMARS_BASE	0xFDC09000
+#define SH_DMARS_BASE0	0xFDC09000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define DMTE0_IRQ	48	/* DMAC0A*/
+#define DMTE4_IRQ	76	/* DMAC0B */
+#define DMTE6_IRQ	40
+#define DMTE8_IRQ	42	/* DMAC1A */
+#define DMTE9_IRQ	43
+#define DMTE10_IRQ	72	/* DMAC1B */
+#define DMTE11_IRQ	73
+#define DMAE0_IRQ	78	/* DMA Error IRQ*/
+#define DMAE1_IRQ	74	/* DMA Error IRQ*/
+#define SH_DMAC_BASE0	0xFE008020
+#define SH_DMAC_BASE1	0xFDC08020
+#define SH_DMARS_BASE0	0xFE009000
+#define SH_DMARS_BASE1	0xFDC09000
 #elif defined(CONFIG_CPU_SUBTYPE_SH7780)
 #define DMTE0_IRQ	34
 #define DMTE4_IRQ	44
@@ -41,7 +59,7 @@
 #define DMAE0_IRQ	38	/* DMA Error IRQ */
 #define SH_DMAC_BASE0	0xFC808020
 #define SH_DMAC_BASE1	0xFC818020
-#define SH_DMARS_BASE	0xFC809000
+#define SH_DMARS_BASE0	0xFC809000
 #else /* SH7785 */
 #define DMTE0_IRQ	33
 #define DMTE4_IRQ	37
@@ -54,42 +72,12 @@
 #define DMAE1_IRQ	58	/* DMA Error IRQ1 */
 #define SH_DMAC_BASE0	0xFC808020
 #define SH_DMAC_BASE1	0xFCC08020
-#define SH_DMARS_BASE	0xFC809000
+#define SH_DMARS_BASE0	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,
-};
+#define REQ_HE		0x000000C0
+#define REQ_H		0x00000080
+#define REQ_LE		0x00000040
+#define TM_BURST	0x00000020
 
 #endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/mmu_context.h linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/mmu_context.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/mmu_context.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/mmu_context.h	2010-05-16 17:17:36.000000000 -0400
@@ -19,12 +19,20 @@
 
 #define MMUCR		0xFF000010	/* MMU Control Register */
 
+#define MMU_ITLB_ADDRESS_ARRAY  0xF2000000
+#define MMU_ITLB_ADDRESS_ARRAY2	0xF2800000
 #define MMU_UTLB_ADDRESS_ARRAY	0xF6000000
 #define MMU_UTLB_ADDRESS_ARRAY2	0xF6800000
 #define MMU_PAGE_ASSOC_BIT	0x80
 
 #define MMUCR_TI		(1<<2)
 
+#define MMUCR_URB		0x00FC0000
+#define MMUCR_URB_SHIFT		18
+#define MMUCR_URB_NENTRIES	64
+#define MMUCR_URC		0x0000FC00
+#define MMUCR_URC_SHIFT		10
+
 #if defined(CONFIG_32BIT) && defined(CONFIG_CPU_SUBTYPE_ST40)
 #define MMUCR_SE		(1 << 4)
 #else
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/sq.h linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/sq.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/sq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/sq.h	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #define __ASM_CPU_SH4_SQ_H
 
 #include <asm/addrspace.h>
+#include <asm/page.h>
 
 /*
  * Store queues range from e0000000-e3fffffc, allowing approx. 64MB to be
@@ -28,7 +29,7 @@
 
 /* arch/sh/kernel/cpu/sh4/sq.c */
 unsigned long sq_remap(unsigned long phys, unsigned int size,
-		       const char *name, unsigned long flags);
+		       const char *name, pgprot_t prot);
 void sq_unmap(unsigned long vaddr);
 void sq_flush_range(unsigned long start, unsigned int len);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/ubc.h linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/ubc.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/ubc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/ubc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,64 +0,0 @@
-/*
- * include/asm-sh/cpu-sh4/ubc.h
- *
- * Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2003 Paul Mundt
- * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC
- *
- * 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_CPU_SH4_UBC_H
-#define __ASM_CPU_SH4_UBC_H
-
-#if defined(CONFIG_CPU_SH4A)
-#define UBC_CBR0		0xff200000
-#define UBC_CRR0		0xff200004
-#define UBC_CAR0		0xff200008
-#define UBC_CAMR0		0xff20000c
-#define UBC_CBR1		0xff200020
-#define UBC_CRR1		0xff200024
-#define UBC_CAR1		0xff200028
-#define UBC_CAMR1		0xff20002c
-#define UBC_CDR1		0xff200030
-#define UBC_CDMR1		0xff200034
-#define UBC_CETR1		0xff200038
-#define UBC_CCMFR		0xff200600
-#define UBC_CBCR		0xff200620
-
-/* CBR	*/
-#define UBC_CBR_AIE		(0x01<<30)
-#define UBC_CBR_ID_INST		(0x01<<4)
-#define UBC_CBR_RW_READ		(0x01<<1)
-#define UBC_CBR_CE		(0x01)
-
-#define	UBC_CBR_AIV_MASK	(0x00FF0000)
-#define	UBC_CBR_AIV_SHIFT	(16)
-#define UBC_CBR_AIV_SET(asid)	(((asid)<<UBC_CBR_AIV_SHIFT) & UBC_CBR_AIV_MASK)
-
-#define UBC_CBR_INIT		0x20000000
-
-/* CRR	*/
-#define UBC_CRR_RES		(0x01<<13)
-#define UBC_CRR_PCB		(0x01<<1)
-#define UBC_CRR_BIE		(0x01)
-
-#define UBC_CRR_INIT		0x00002000
-
-#else	/* CONFIG_CPU_SH4 */
-#define UBC_BARA		0xff200000
-#define UBC_BAMRA		0xff200004
-#define UBC_BBRA		0xff200008
-#define UBC_BASRA		0xff000014
-#define UBC_BARB		0xff20000c
-#define UBC_BAMRB		0xff200010
-#define UBC_BBRB		0xff200014
-#define UBC_BASRB		0xff000018
-#define UBC_BDRB		0xff200018
-#define UBC_BDMRB		0xff20001c
-#define UBC_BRCR		0xff200020
-#endif	/* CONFIG_CPU_SH4 */
-
-#endif /* __ASM_CPU_SH4_UBC_H */
-
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/watchdog.h linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/watchdog.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/watchdog.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/cpu-sh4/cpu/watchdog.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,12 @@
 #define WTCNT		0xffcc0000 /*WDTST*/
 #define WTST		WTCNT
 #define WTBST		0xffcc0008 /*WDTBST*/
+/* Register definitions */
+#elif	defined(CONFIG_CPU_SUBTYPE_SH7722) || \
+	defined(CONFIG_CPU_SUBTYPE_SH7723) || \
+	defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define WTCNT		0xa4520000
+#define WTCSR		0xa4520004
 #else
 /* Register definitions */
 #define WTCNT		0xffc00008
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/mach-common/mach/magicpanelr2.h linux-libre-2.6.34-gnu1/arch/sh/include/mach-common/mach/magicpanelr2.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/mach-common/mach/magicpanelr2.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/mach-common/mach/magicpanelr2.h	2010-05-16 17:17:36.000000000 -0400
@@ -19,12 +19,12 @@
 #include <asm/io_generic.h>
 
 
-#define SETBITS_OUTB(mask, reg)   ctrl_outb(ctrl_inb(reg) | mask, reg)
-#define SETBITS_OUTW(mask, reg)   ctrl_outw(ctrl_inw(reg) | mask, reg)
-#define SETBITS_OUTL(mask, reg)   ctrl_outl(ctrl_inl(reg) | mask, reg)
-#define CLRBITS_OUTB(mask, reg)   ctrl_outb(ctrl_inb(reg) & ~mask, reg)
-#define CLRBITS_OUTW(mask, reg)   ctrl_outw(ctrl_inw(reg) & ~mask, reg)
-#define CLRBITS_OUTL(mask, reg)   ctrl_outl(ctrl_inl(reg) & ~mask, reg)
+#define SETBITS_OUTB(mask, reg)   __raw_writeb(__raw_readb(reg) | mask, reg)
+#define SETBITS_OUTW(mask, reg)   __raw_writew(__raw_readw(reg) | mask, reg)
+#define SETBITS_OUTL(mask, reg)   __raw_writel(__raw_readl(reg) | mask, reg)
+#define CLRBITS_OUTB(mask, reg)   __raw_writeb(__raw_readb(reg) & ~mask, reg)
+#define CLRBITS_OUTW(mask, reg)   __raw_writew(__raw_readw(reg) & ~mask, reg)
+#define CLRBITS_OUTL(mask, reg)   __raw_writel(__raw_readl(reg) & ~mask, reg)
 
 
 #define PA_LED          PORT_PADR      /* LED */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/mach-dreamcast/mach/sysasic.h linux-libre-2.6.34-gnu1/arch/sh/include/mach-dreamcast/mach/sysasic.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/mach-dreamcast/mach/sysasic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/mach-dreamcast/mach/sysasic.h	2010-05-16 17:17:36.000000000 -0400
@@ -39,5 +39,10 @@
 
 #define HW_EVENT_IRQ_MAX (HW_EVENT_IRQ_BASE + 95)
 
+/* arch/sh/boards/mach-dreamcast/irq.c */
+extern int systemasic_irq_demux(int);
+extern void systemasic_irq_init(void);
+extern void aica_time_init(void);
+
 #endif /* __ASM_SH_DREAMCAST_SYSASIC_H */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/mach-migor/mach/migor.h linux-libre-2.6.34-gnu1/arch/sh/include/mach-migor/mach/migor.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/mach-migor/mach/migor.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/mach-migor/mach/migor.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 #ifndef __ASM_SH_MIGOR_H
 #define __ASM_SH_MIGOR_H
 
+#define PORT_MSELCRA 0xa4050180
 #define PORT_MSELCRB 0xa4050182
 #define BSC_CS4BCR 0xfec10010
 #define BSC_CS6ABCR 0xfec1001c
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/mach-sdk7786/mach/fpga.h linux-libre-2.6.34-gnu1/arch/sh/include/mach-sdk7786/mach/fpga.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/mach-sdk7786/mach/fpga.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/mach-sdk7786/mach/fpga.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,114 @@
+#ifndef __MACH_SDK7786_FPGA_H
+#define __MACH_SDK7786_FPGA_H
+
+#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+
+#define SRSTR		0x000
+#define  SRSTR_MAGIC	0x1971	/* Fixed magical read value */
+
+#define INTASR		0x010
+#define INTAMR		0x020
+#define MODSWR		0x030
+#define INTTESTR	0x040
+#define SYSSR		0x050
+#define NRGPR		0x060
+#define NMISR		0x070
+
+#define NMIMR		0x080
+#define  NMIMR_MAN_NMIM	BIT(0)	/* Manual NMI mask */
+#define  NMIMR_AUX_NMIM	BIT(1)	/* Auxiliary NMI mask */
+
+#define INTBSR		0x090
+#define INTBMR		0x0a0
+#define USRLEDR		0x0b0
+#define MAPSWR		0x0c0
+#define FPGAVR		0x0d0
+#define FPGADR		0x0e0
+#define PCBRR		0x0f0
+#define RSR		0x100
+#define EXTASR		0x110
+#define SPCAR		0x120
+#define INTMSR		0x130
+#define PCIECR		0x140
+#define FAER		0x150
+#define USRGPIR		0x160
+/* 0x170 reserved */
+#define LCLASR		0x180
+
+#define SBCR		0x190
+#define  SCBR_I2CMEN	BIT(0)	/* FPGA I2C master enable */
+#define  SCBR_I2CCEN	BIT(1)	/* CPU I2C master enable */
+
+#define PWRCR		0x1a0
+#define SPCBR		0x1b0
+#define SPICR		0x1c0
+#define SPIDR		0x1d0
+#define I2CCR		0x1e0
+#define I2CDR		0x1f0
+#define FPGACR		0x200
+#define IASELR1		0x210
+#define IASELR2		0x220
+#define IASELR3		0x230
+#define IASELR4		0x240
+#define IASELR5		0x250
+#define IASELR6		0x260
+#define IASELR7		0x270
+#define IASELR8		0x280
+#define IASELR9		0x290
+#define IASELR10	0x2a0
+#define IASELR11	0x2b0
+#define IASELR12	0x2c0
+#define IASELR13	0x2d0
+#define IASELR14	0x2e0
+#define IASELR15	0x2f0
+/* 0x300 reserved */
+#define IBSELR1		0x310
+#define IBSELR2		0x320
+#define IBSELR3		0x330
+#define IBSELR4		0x340
+#define IBSELR5		0x350
+#define IBSELR6		0x360
+#define IBSELR7		0x370
+#define IBSELR8		0x380
+#define IBSELR9		0x390
+#define IBSELR10	0x3a0
+#define IBSELR11	0x3b0
+#define IBSELR12	0x3c0
+#define IBSELR13	0x3d0
+#define IBSELR14	0x3e0
+#define IBSELR15	0x3f0
+#define USRACR		0x400
+#define BEEPR		0x410
+#define USRLCDR		0x420
+#define SMBCR		0x430
+#define SMBDR		0x440
+#define USBCR		0x450
+#define AMSR		0x460
+#define ACCR		0x470
+#define SDIFCR		0x480
+
+/* arch/sh/boards/mach-sdk7786/fpga.c */
+extern void __iomem *sdk7786_fpga_base;
+extern void sdk7786_fpga_init(void);
+
+#define SDK7786_FPGA_REGADDR(reg)	(sdk7786_fpga_base + (reg))
+
+/*
+ * A convenience wrapper from register offset to internal I2C address,
+ * when the FPGA is in I2C slave mode.
+ */
+#define SDK7786_FPGA_I2CADDR(reg)	((reg) >> 3)
+
+static inline u16 fpga_read_reg(unsigned int reg)
+{
+	return ioread16(sdk7786_fpga_base + reg);
+}
+
+static inline void fpga_write_reg(u16 val, unsigned int reg)
+{
+	iowrite16(val, sdk7786_fpga_base + reg);
+}
+
+#endif /* __MACH_SDK7786_FPGA_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/mach-sdk7786/mach/irq.h linux-libre-2.6.34-gnu1/arch/sh/include/mach-sdk7786/mach/irq.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/mach-sdk7786/mach/irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/mach-sdk7786/mach/irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,7 @@
+#ifndef __MACH_SDK7786_IRQ_H
+#define __MACH_SDK7786_IRQ_H
+
+/* arch/sh/boards/mach-sdk7786/irq.c */
+extern void sdk7786_init_irq(void);
+
+#endif /* __MACH_SDK7786_IRQ_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/include/mach-se/mach/se7343.h linux-libre-2.6.34-gnu1/arch/sh/include/mach-se/mach/se7343.h
--- linux-libre-2.6.33-gnu1/arch/sh/include/mach-se/mach/se7343.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/include/mach-se/mach/se7343.h	2010-05-16 17:17:36.000000000 -0400
@@ -94,26 +94,26 @@
 
 #define PORT_DRVCR	0xA4050180
 
-#define PORT_PADR  	0xA4050120
-#define PORT_PBDR  	0xA4050122
-#define PORT_PCDR  	0xA4050124
-#define PORT_PDDR  	0xA4050126
-#define PORT_PEDR  	0xA4050128
-#define PORT_PFDR  	0xA405012A
-#define PORT_PGDR  	0xA405012C
-#define PORT_PHDR  	0xA405012E
-#define PORT_PJDR  	0xA4050130
-#define PORT_PKDR  	0xA4050132
-#define PORT_PLDR  	0xA4050134
-#define PORT_PMDR  	0xA4050136
-#define PORT_PNDR  	0xA4050138
-#define PORT_PQDR  	0xA405013A
-#define PORT_PRDR  	0xA405013C
-#define PORT_PTDR  	0xA4050160
-#define PORT_PUDR  	0xA4050162
-#define PORT_PVDR  	0xA4050164
-#define PORT_PWDR  	0xA4050166
-#define PORT_PYDR  	0xA4050168
+#define PORT_PADR	0xA4050120
+#define PORT_PBDR	0xA4050122
+#define PORT_PCDR	0xA4050124
+#define PORT_PDDR	0xA4050126
+#define PORT_PEDR	0xA4050128
+#define PORT_PFDR	0xA405012A
+#define PORT_PGDR	0xA405012C
+#define PORT_PHDR	0xA405012E
+#define PORT_PJDR	0xA4050130
+#define PORT_PKDR	0xA4050132
+#define PORT_PLDR	0xA4050134
+#define PORT_PMDR	0xA4050136
+#define PORT_PNDR	0xA4050138
+#define PORT_PQDR	0xA405013A
+#define PORT_PRDR	0xA405013C
+#define PORT_PTDR	0xA4050160
+#define PORT_PUDR	0xA4050162
+#define PORT_PVDR	0xA4050164
+#define PORT_PWDR	0xA4050166
+#define PORT_PYDR	0xA4050168
 
 #define FPGA_IN		0xb1400000
 #define FPGA_OUT	0xb1400002
@@ -133,18 +133,10 @@
 #define SE7343_FPGA_IRQ_UARTB	11
 
 #define SE7343_FPGA_IRQ_NR	12
-#define SE7343_FPGA_IRQ_BASE	120
-
-#define MRSHPC_IRQ3    	(SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC3)
-#define MRSHPC_IRQ2    	(SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC2)
-#define MRSHPC_IRQ1    	(SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC1)
-#define MRSHPC_IRQ0    	(SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC0)
-#define SMC_IRQ		(SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_SMC)
-#define USB_IRQ		(SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_USB)
-#define UARTA_IRQ	(SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTA)
-#define UARTB_IRQ	(SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTB)
 
 /* arch/sh/boards/se/7343/irq.c */
+extern unsigned int se7343_fpga_irq[];
+
 void init_7343se_IRQ(void);
 
 #endif  /* __ASM_SH_HITACHI_SE7343_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/Kconfig linux-libre-2.6.34-gnu1/arch/sh/Kconfig
--- linux-libre-2.6.33-gnu1/arch/sh/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@ config SUPERH
 	select HAVE_LMB
 	select HAVE_OPROFILE
 	select HAVE_GENERIC_DMA_COHERENT
-	select HAVE_IOREMAP_PROT if MMU
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_DMA_API_DEBUG
 	select HAVE_DMA_ATTRS
@@ -22,6 +21,7 @@ config SUPERH
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_BZIP2
 	select HAVE_KERNEL_LZMA
+	select HAVE_KERNEL_LZO
 	select HAVE_SYSCALL_TRACEPOINTS
 	select RTC_LIB
 	select GENERIC_ATOMIC64
@@ -35,6 +35,7 @@ config SUPERH32
 	def_bool ARCH = "sh"
 	select HAVE_KPROBES
 	select HAVE_KRETPROBES
+	select HAVE_IOREMAP_PROT if MMU && !X2TLB
 	select HAVE_FUNCTION_TRACER
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_DYNAMIC_FTRACE
@@ -42,6 +43,8 @@ config SUPERH32
 	select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_ARCH_KGDB
+	select HAVE_HW_BREAKPOINT
+	select PERF_EVENTS if HAVE_HW_BREAKPOINT
 	select ARCH_HIBERNATION_POSSIBLE if MMU
 
 config SUPERH64
@@ -78,11 +81,12 @@ config GENERIC_HARDIRQS
 config GENERIC_HARDIRQS_NO__DO_IRQ
 	def_bool y
 
-config GENERIC_IRQ_PROBE
+config IRQ_PER_CPU
 	def_bool y
 
-config IRQ_PER_CPU
+config SPARSE_IRQ
 	def_bool y
+	depends on SUPERH32
 
 config GENERIC_GPIO
 	def_bool n
@@ -179,6 +183,9 @@ config DMA_COHERENT
 config DMA_NONCOHERENT
 	def_bool !DMA_COHERENT
 
+config NEED_DMA_MAP_STATE
+	def_bool DMA_NONCOHERENT
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
@@ -548,8 +555,7 @@ config SH_PCLK_FREQ
 			      CPU_SUBTYPE_SH7203 || \
 			      CPU_SUBTYPE_SH7206 || \
 			      CPU_SUBTYPE_SH7263 || \
-			      CPU_SUBTYPE_MXG    || \
-			      CPU_SUBTYPE_SH7786
+			      CPU_SUBTYPE_MXG
 	default "60000000" if CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R
 	default "66000000" if CPU_SUBTYPE_SH4_202
 	default "50000000"
@@ -563,7 +569,8 @@ config SH_CLK_CPG
 
 config SH_CLK_CPG_LEGACY
 	depends on SH_CLK_CPG
-	def_bool y if !CPU_SUBTYPE_SH7785 && !ARCH_SHMOBILE
+	def_bool y if !CPU_SUBTYPE_SH7785 && !ARCH_SHMOBILE && \
+		      !CPU_SUBTYPE_SH7786
 
 config SH_CLK_MD
 	int "CPU Mode Pin Setting"
@@ -725,18 +732,6 @@ config GUSA_RB
 	  LLSC, this should be more efficient than the other alternative of
 	  disabling interrupts around the atomic sequence.
 
-config SPARSE_IRQ
-	bool "Support sparse irq numbering"
-	depends on EXPERIMENTAL
-	help
-	  This enables support for sparse irqs. This is useful in general
-	  as most CPUs have a fairly sparse array of IRQ vectors, which
-	  the irq_desc then maps directly on to. Systems with a high
-	  number of off-chip IRQs will want to treat this as
-	  experimental until they have been independently verified.
-
-	  If you don't know what to do here, say N.
-
 endmenu
 
 menu "Boot options"
@@ -822,11 +817,15 @@ config MAPLE
 config PCI
 	bool "PCI support"
 	depends on SYS_SUPPORTS_PCI
+	select PCI_DOMAINS
 	help
 	  Find out whether you have a PCI motherboard. PCI is the name of a
 	  bus system, i.e. the way the CPU talks to the other stuff inside
 	  your box. If you have PCI, say Y, otherwise N.
 
+config PCI_DOMAINS
+	bool
+
 source "drivers/pci/pcie/Kconfig"
 
 source "drivers/pci/Kconfig"
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/Kconfig.cpu linux-libre-2.6.34-gnu1/arch/sh/Kconfig.cpu
--- linux-libre-2.6.33-gnu1/arch/sh/Kconfig.cpu	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/Kconfig.cpu	2010-05-16 17:17:36.000000000 -0400
@@ -68,7 +68,8 @@ config SH_STORE_QUEUES
 
 config SPECULATIVE_EXECUTION
 	bool "Speculative subroutine return"
-	depends on CPU_SUBTYPE_SH7780 && EXPERIMENTAL
+	depends on EXPERIMENTAL
+	depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 || CPU_SUBTYPE_SH7786
 	help
 	  This enables support for a speculative instruction fetch for
 	  subroutine return. There are various pitfalls associated with
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/adc.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/adc.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/adc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/adc.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,19 +18,19 @@ int adc_single(unsigned int channel)
 
 	off = (channel & 0x03) << 2;
 
-	csr = ctrl_inb(ADCSR);
+	csr = __raw_readb(ADCSR);
 	csr = channel | ADCSR_ADST | ADCSR_CKS;
-	ctrl_outb(csr, ADCSR);
+	__raw_writeb(csr, ADCSR);
 
 	do {
-		csr = ctrl_inb(ADCSR);
+		csr = __raw_readb(ADCSR);
 	} while ((csr & ADCSR_ADF) == 0);
 
 	csr &= ~(ADCSR_ADF | ADCSR_ADST);
-	ctrl_outb(csr, ADCSR);
+	__raw_writeb(csr, ADCSR);
 
-	return (((ctrl_inb(ADDRAH + off) << 8) |
-		ctrl_inb(ADDRAL + off)) >> 6);
+	return (((__raw_readb(ADDRAH + off) << 8) |
+		__raw_readb(ADDRAL + off)) >> 6);
 }
 
 EXPORT_SYMBOL(adc_single);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/clock.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/clock.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -404,7 +404,7 @@ EXPORT_SYMBOL_GPL(clk_round_rate);
  *  If an entry has a device ID, it must match
  *  If an entry has a connection ID, it must match
  * Then we take the most specific entry - with the following
- * order of precidence: dev+con > dev only > con only.
+ * order of precedence: dev+con > dev only > con only.
  */
 static struct clk *clk_find(const char *dev_id, const char *con_id)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/clock-cpg.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/clock-cpg.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/clock-cpg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/clock-cpg.c	2010-05-16 17:17:36.000000000 -0400
@@ -149,7 +149,8 @@ int __init sh_clk_div6_register(struct c
 
 static unsigned long sh_clk_div4_recalc(struct clk *clk)
 {
-	struct clk_div_mult_table *table = clk->priv;
+	struct clk_div4_table *d4t = clk->priv;
+	struct clk_div_mult_table *table = d4t->div_mult_table;
 	unsigned int idx;
 
 	clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
@@ -160,17 +161,90 @@ static unsigned long sh_clk_div4_recalc(
 	return clk->freq_table[idx].frequency;
 }
 
+static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
+{
+	struct clk_div4_table *d4t = clk->priv;
+	struct clk_div_mult_table *table = d4t->div_mult_table;
+	u32 value;
+	int ret;
+
+	if (!strcmp("pll_clk", parent->name))
+		value = __raw_readl(clk->enable_reg) & ~(1 << 7);
+	else
+		value = __raw_readl(clk->enable_reg) | (1 << 7);
+
+	ret = clk_reparent(clk, parent);
+	if (ret < 0)
+		return ret;
+
+	__raw_writel(value, clk->enable_reg);
+
+	/* Rebiuld the frequency table */
+	clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
+			     table, &clk->arch_flags);
+
+	return 0;
+}
+
+static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id)
+{
+	struct clk_div4_table *d4t = clk->priv;
+	unsigned long value;
+	int idx = clk_rate_table_find(clk, clk->freq_table, rate);
+	if (idx < 0)
+		return idx;
+
+	value = __raw_readl(clk->enable_reg);
+	value &= ~(0xf << clk->enable_bit);
+	value |= (idx << clk->enable_bit);
+	__raw_writel(value, clk->enable_reg);
+
+	if (d4t->kick)
+		d4t->kick(clk);
+
+	return 0;
+}
+
+static int sh_clk_div4_enable(struct clk *clk)
+{
+	__raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg);
+	return 0;
+}
+
+static void sh_clk_div4_disable(struct clk *clk)
+{
+	__raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg);
+}
+
 static struct clk_ops sh_clk_div4_clk_ops = {
 	.recalc		= sh_clk_div4_recalc,
+	.set_rate	= sh_clk_div4_set_rate,
 	.round_rate	= sh_clk_div_round_rate,
 };
 
-int __init sh_clk_div4_register(struct clk *clks, int nr,
-				struct clk_div_mult_table *table)
+static struct clk_ops sh_clk_div4_enable_clk_ops = {
+	.recalc		= sh_clk_div4_recalc,
+	.set_rate	= sh_clk_div4_set_rate,
+	.round_rate	= sh_clk_div_round_rate,
+	.enable		= sh_clk_div4_enable,
+	.disable	= sh_clk_div4_disable,
+};
+
+static struct clk_ops sh_clk_div4_reparent_clk_ops = {
+	.recalc		= sh_clk_div4_recalc,
+	.set_rate	= sh_clk_div4_set_rate,
+	.round_rate	= sh_clk_div_round_rate,
+	.enable		= sh_clk_div4_enable,
+	.disable	= sh_clk_div4_disable,
+	.set_parent	= sh_clk_div4_set_parent,
+};
+
+static int __init sh_clk_div4_register_ops(struct clk *clks, int nr,
+			struct clk_div4_table *table, struct clk_ops *ops)
 {
 	struct clk *clkp;
 	void *freq_table;
-	int nr_divs = table->nr_divisors;
+	int nr_divs = table->div_mult_table->nr_divisors;
 	int freq_table_size = sizeof(struct cpufreq_frequency_table);
 	int ret = 0;
 	int k;
@@ -185,7 +259,7 @@ int __init sh_clk_div4_register(struct c
 	for (k = 0; !ret && (k < nr); k++) {
 		clkp = clks + k;
 
-		clkp->ops = &sh_clk_div4_clk_ops;
+		clkp->ops = ops;
 		clkp->id = -1;
 		clkp->priv = table;
 
@@ -198,6 +272,26 @@ int __init sh_clk_div4_register(struct c
 	return ret;
 }
 
+int __init sh_clk_div4_register(struct clk *clks, int nr,
+				struct clk_div4_table *table)
+{
+	return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_clk_ops);
+}
+
+int __init sh_clk_div4_enable_register(struct clk *clks, int nr,
+				struct clk_div4_table *table)
+{
+	return sh_clk_div4_register_ops(clks, nr, table,
+					&sh_clk_div4_enable_clk_ops);
+}
+
+int __init sh_clk_div4_reparent_register(struct clk *clks, int nr,
+				struct clk_div4_table *table)
+{
+	return sh_clk_div4_register_ops(clks, nr, table,
+					&sh_clk_div4_reparent_clk_ops);
+}
+
 #ifdef CONFIG_SH_CLK_CPG_LEGACY
 static struct clk master_clk = {
 	.name		= "master_clk",
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/fpu.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/fpu.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/fpu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/fpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,85 @@
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <asm/processor.h>
+#include <asm/fpu.h>
+
+int init_fpu(struct task_struct *tsk)
+{
+	if (tsk_used_math(tsk)) {
+		if ((boot_cpu_data.flags & CPU_HAS_FPU) && tsk == current)
+			unlazy_fpu(tsk, task_pt_regs(tsk));
+		return 0;
+	}
+
+	/*
+	 * Memory allocation at the first usage of the FPU and other state.
+	 */
+	if (!tsk->thread.xstate) {
+		tsk->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
+						      GFP_KERNEL);
+		if (!tsk->thread.xstate)
+			return -ENOMEM;
+	}
+
+	if (boot_cpu_data.flags & CPU_HAS_FPU) {
+		struct sh_fpu_hard_struct *fp = &tsk->thread.xstate->hardfpu;
+		memset(fp, 0, xstate_size);
+		fp->fpscr = FPSCR_INIT;
+	} else {
+		struct sh_fpu_soft_struct *fp = &tsk->thread.xstate->softfpu;
+		memset(fp, 0, xstate_size);
+		fp->fpscr = FPSCR_INIT;
+	}
+
+	set_stopped_child_used_math(tsk);
+	return 0;
+}
+
+#ifdef CONFIG_SH_FPU
+void __fpu_state_restore(void)
+{
+	struct task_struct *tsk = current;
+
+	restore_fpu(tsk);
+
+	task_thread_info(tsk)->status |= TS_USEDFPU;
+	tsk->fpu_counter++;
+}
+
+void fpu_state_restore(struct pt_regs *regs)
+{
+	struct task_struct *tsk = current;
+
+	if (unlikely(!user_mode(regs))) {
+		printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
+		BUG();
+		return;
+	}
+
+	if (!tsk_used_math(tsk)) {
+		local_irq_enable();
+		/*
+		 * does a slab alloc which can sleep
+		 */
+		if (init_fpu(tsk)) {
+			/*
+			 * ran out of memory!
+			 */
+			do_group_exit(SIGKILL);
+			return;
+		}
+		local_irq_disable();
+	}
+
+	grab_fpu(regs);
+
+	__fpu_state_restore();
+}
+
+BUILD_TRAP_HANDLER(fpu_state_restore)
+{
+	TRAP_HANDLER_DECL;
+
+	fpu_state_restore(regs);
+}
+#endif /* CONFIG_SH_FPU */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/hwblk.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/hwblk.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/hwblk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/hwblk.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,5 @@
 #include <linux/clk.h>
 #include <linux/compiler.h>
-#include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/spinlock.h>
 #include <asm/suspend.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/init.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/init.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,22 +24,32 @@
 #include <asm/elf.h>
 #include <asm/io.h>
 #include <asm/smp.h>
-#ifdef CONFIG_SUPERH32
-#include <asm/ubc.h>
+#include <asm/sh_bios.h>
+
+#ifdef CONFIG_SH_FPU
+#define cpu_has_fpu	1
+#else
+#define cpu_has_fpu	0
+#endif
+
+#ifdef CONFIG_SH_DSP
+#define cpu_has_dsp	1
+#else
+#define cpu_has_dsp	0
 #endif
 
 /*
  * Generic wrapper for command line arguments to disable on-chip
  * peripherals (nofpu, nodsp, and so forth).
  */
-#define onchip_setup(x)				\
-static int x##_disabled __initdata = 0;		\
-						\
-static int __init x##_setup(char *opts)		\
-{						\
-	x##_disabled = 1;			\
-	return 1;				\
-}						\
+#define onchip_setup(x)					\
+static int x##_disabled __initdata = !cpu_has_##x;	\
+							\
+static int __init x##_setup(char *opts)			\
+{							\
+	x##_disabled = 1;				\
+	return 1;					\
+}							\
 __setup("no" __stringify(x), x##_setup);
 
 onchip_setup(fpu);
@@ -52,10 +62,10 @@ onchip_setup(dsp);
 static void __init speculative_execution_init(void)
 {
 	/* Clear RABD */
-	ctrl_outl(ctrl_inl(CPUOPM) & ~CPUOPM_RABD, CPUOPM);
+	__raw_writel(__raw_readl(CPUOPM) & ~CPUOPM_RABD, CPUOPM);
 
 	/* Flush the update */
-	(void)ctrl_inl(CPUOPM);
+	(void)__raw_readl(CPUOPM);
 	ctrl_barrier();
 }
 #else
@@ -89,7 +99,7 @@ static void __init expmask_init(void)
 #endif
 
 /* 2nd-level cache init */
-void __uses_jump_to_uncached __attribute__ ((weak)) l2_cache_init(void)
+void __attribute__ ((weak)) l2_cache_init(void)
 {
 }
 
@@ -97,12 +107,12 @@ void __uses_jump_to_uncached __attribute
  * Generic first-level cache init
  */
 #ifdef CONFIG_SUPERH32
-static void __uses_jump_to_uncached cache_init(void)
+static void cache_init(void)
 {
 	unsigned long ccr, flags;
 
 	jump_to_uncached();
-	ccr = ctrl_inl(CCR);
+	ccr = __raw_readl(CCR);
 
 	/*
 	 * At this point we don't know whether the cache is enabled or not - a
@@ -146,7 +156,7 @@ static void __uses_jump_to_uncached cach
 			for (addr = addrstart;
 			     addr < addrstart + waysize;
 			     addr += current_cpu_data.dcache.linesz)
-				ctrl_outl(0, addr);
+				__raw_writel(0, addr);
 
 			addrstart += current_cpu_data.dcache.way_incr;
 		} while (--ways);
@@ -179,7 +189,7 @@ static void __uses_jump_to_uncached cach
 
 	l2_cache_init();
 
-	ctrl_outl(flags, CCR);
+	__raw_writel(flags, CCR);
 	back_to_cached();
 }
 #else
@@ -207,6 +217,18 @@ static void detect_cache_shape(void)
 		l2_cache_shape = -1; /* No S-cache */
 }
 
+static void __init fpu_init(void)
+{
+	/* Disable the FPU */
+	if (fpu_disabled && (current_cpu_data.flags & CPU_HAS_FPU)) {
+		printk("FPU Disabled\n");
+		current_cpu_data.flags &= ~CPU_HAS_FPU;
+	}
+
+	disable_fpu();
+	clear_used_math();
+}
+
 #ifdef CONFIG_SH_DSP
 static void __init release_dsp(void)
 {
@@ -244,28 +266,35 @@ static void __init dsp_init(void)
 	if (sr & SR_DSP)
 		current_cpu_data.flags |= CPU_HAS_DSP;
 
+	/* Disable the DSP */
+	if (dsp_disabled && (current_cpu_data.flags & CPU_HAS_DSP)) {
+		printk("DSP Disabled\n");
+		current_cpu_data.flags &= ~CPU_HAS_DSP;
+	}
+
 	/* Now that we've determined the DSP status, clear the DSP bit. */
 	release_dsp();
 }
+#else
+static inline void __init dsp_init(void) { }
 #endif /* CONFIG_SH_DSP */
 
 /**
  * sh_cpu_init
  *
- * This is our initial entry point for each CPU, and is invoked on the boot
- * CPU prior to calling start_kernel(). For SMP, a combination of this and
- * start_secondary() will bring up each processor to a ready state prior
- * to hand forking the idle loop.
+ * This is our initial entry point for each CPU, and is invoked on the
+ * boot CPU prior to calling start_kernel(). For SMP, a combination of
+ * this and start_secondary() will bring up each processor to a ready
+ * state prior to hand forking the idle loop.
  *
- * We do all of the basic processor init here, including setting up the
- * caches, FPU, DSP, kicking the UBC, etc. By the time start_kernel() is
- * hit (and subsequently platform_setup()) things like determining the
- * CPU subtype and initial configuration will all be done.
+ * We do all of the basic processor init here, including setting up
+ * the caches, FPU, DSP, etc. By the time start_kernel() is hit (and
+ * subsequently platform_setup()) things like determining the CPU
+ * subtype and initial configuration will all be done.
  *
  * Each processor family is still responsible for doing its own probing
  * and cache configuration in detect_cpu_and_cache_system().
  */
-
 asmlinkage void __init sh_cpu_init(void)
 {
 	current_thread_info()->cpu = hard_smp_processor_id();
@@ -302,18 +331,8 @@ asmlinkage void __init sh_cpu_init(void)
 		detect_cache_shape();
 	}
 
-	/* Disable the FPU */
-	if (fpu_disabled) {
-		printk("FPU Disabled\n");
-		current_cpu_data.flags &= ~CPU_HAS_FPU;
-	}
-
-	/* FPU initialization */
-	disable_fpu();
-	if ((current_cpu_data.flags & CPU_HAS_FPU)) {
-		current_thread_info()->status &= ~TS_USEDFPU;
-		clear_used_math();
-	}
+	fpu_init();
+	dsp_init();
 
 	/*
 	 * Initialize the per-CPU ASID cache very early, since the
@@ -321,18 +340,24 @@ asmlinkage void __init sh_cpu_init(void)
 	 */
 	current_cpu_data.asid_cache = NO_CONTEXT;
 
-#ifdef CONFIG_SH_DSP
-	/* Probe for DSP */
-	dsp_init();
-
-	/* Disable the DSP */
-	if (dsp_disabled) {
-		printk("DSP Disabled\n");
-		current_cpu_data.flags &= ~CPU_HAS_DSP;
-		release_dsp();
-	}
-#endif
-
 	speculative_execution_init();
 	expmask_init();
+
+	/* Do the rest of the boot processor setup */
+	if (raw_smp_processor_id() == 0) {
+		/* Save off the BIOS VBR, if there is one */
+		sh_bios_vbr_init();
+
+		/*
+		 * Setup VBR for boot CPU. Secondary CPUs do this through
+		 * start_secondary().
+		 */
+		per_cpu_trap_init();
+
+		/*
+		 * Boot processor to setup the FP and extended state
+		 * context info.
+		 */
+		init_thread_xstate();
+	}
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/irq/intc-sh5.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/irq/intc-sh5.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/irq/intc-sh5.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/irq/intc-sh5.c	2010-05-16 17:17:36.000000000 -0400
@@ -123,7 +123,7 @@ static void enable_intc_irq(unsigned int
 		bitmask = 1 << (irq - 32);
 	}
 
-	ctrl_outl(bitmask, reg);
+	__raw_writel(bitmask, reg);
 }
 
 static void disable_intc_irq(unsigned int irq)
@@ -139,7 +139,7 @@ static void disable_intc_irq(unsigned in
 		bitmask = 1 << (irq - 32);
 	}
 
-	ctrl_outl(bitmask, reg);
+	__raw_writel(bitmask, reg);
 }
 
 static void mask_and_ack_intc(unsigned int irq)
@@ -170,11 +170,11 @@ void __init plat_irq_setup(void)
 
 
 	/* Disable all interrupts and set all priorities to 0 to avoid trouble */
-	ctrl_outl(-1, INTC_INTDSB_0);
-	ctrl_outl(-1, INTC_INTDSB_1);
+	__raw_writel(-1, INTC_INTDSB_0);
+	__raw_writel(-1, INTC_INTDSB_1);
 
 	for (reg = INTC_INTPRI_0, i = 0; i < INTC_INTPRI_PREGS; i++, reg += 8)
-		ctrl_outl( NO_PRIORITY, reg);
+		__raw_writel( NO_PRIORITY, reg);
 
 
 #ifdef CONFIG_SH_CAYMAN
@@ -199,7 +199,7 @@ void __init plat_irq_setup(void)
 			reg = INTC_ICR_SET;
 			i = IRQ_IRL0;
 		}
-		ctrl_outl(INTC_ICR_IRLM, reg);
+		__raw_writel(INTC_ICR_IRLM, reg);
 
 		/* Set interrupt priorities according to platform description */
 		for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) {
@@ -207,7 +207,7 @@ void __init plat_irq_setup(void)
 				((i % INTC_INTPRI_PPREG) * 4);
 			if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) {
 				/* Upon the 7th, set Priority Register */
-				ctrl_outl(data, reg);
+				__raw_writel(data, reg);
 				data = 0;
 				reg += 8;
 			}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/Makefile linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/Makefile
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -17,5 +17,7 @@ obj-$(CONFIG_ARCH_SHMOBILE)	+= shmobile/
 
 obj-$(CONFIG_SH_ADC)		+= adc.o
 obj-$(CONFIG_SH_CLK_CPG)	+= clock-cpg.o
+obj-$(CONFIG_SH_FPU)		+= fpu.o
+obj-$(CONFIG_SH_FPU_EMU)	+= fpu.o
 
 obj-y	+= irq/ init.o clock.o hwblk.o
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2/clock-sh7619.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh2/clock-sh7619.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2/clock-sh7619.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh2/clock-sh7619.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,7 @@ static const int pfc_divisors[] = {1,2,0
 
 static void master_clk_init(struct clk *clk)
 {
-	clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 7];
+	clk->rate *= PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 7];
 }
 
 static struct clk_ops sh7619_master_clk_ops = {
@@ -40,7 +40,7 @@ static struct clk_ops sh7619_master_clk_
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(FREQCR) & 0x0007);
+	int idx = (__raw_readw(FREQCR) & 0x0007);
 	return clk->parent->rate / pfc_divisors[idx];
 }
 
@@ -50,7 +50,7 @@ static struct clk_ops sh7619_module_clk_
 
 static unsigned long bus_clk_recalc(struct clk *clk)
 {
-	return clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 7];
+	return clk->parent->rate / pll1rate[(__raw_readw(FREQCR) >> 8) & 7];
 }
 
 static struct clk_ops sh7619_bus_clk_ops = {
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/clock-sh7201.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/clock-sh7201.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh2a/clock-sh7201.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,7 @@ static const int pfc_divisors[]={1,2,3,4
 
 static void master_clk_init(struct clk *clk)
 {
-	return 10000000 * PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
+	return 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
 }
 
 static struct clk_ops sh7201_master_clk_ops = {
@@ -43,7 +43,7 @@ static struct clk_ops sh7201_master_clk_
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(FREQCR) & 0x0007);
+	int idx = (__raw_readw(FREQCR) & 0x0007);
 	return clk->parent->rate / pfc_divisors[idx];
 }
 
@@ -53,7 +53,7 @@ static struct clk_ops sh7201_module_clk_
 
 static unsigned long bus_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(FREQCR) & 0x0007);
+	int idx = (__raw_readw(FREQCR) & 0x0007);
 	return clk->parent->rate / pfc_divisors[idx];
 }
 
@@ -63,7 +63,7 @@ static struct clk_ops sh7201_bus_clk_ops
 
 static unsigned long cpu_clk_recalc(struct clk *clk)
 {
-	int idx = ((ctrl_inw(FREQCR) >> 4) & 0x0007);
+	int idx = ((__raw_readw(FREQCR) >> 4) & 0x0007);
 	return clk->parent->rate / ifc_divisors[idx];
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/clock-sh7203.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/clock-sh7203.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh2a/clock-sh7203.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,7 @@ static const int pfc_divisors[]={1,2,3,4
 
 static void master_clk_init(struct clk *clk)
 {
-	clk->rate *= pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0003] * PLL2 ;
+	clk->rate *= pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0003] * PLL2 ;
 }
 
 static struct clk_ops sh7203_master_clk_ops = {
@@ -48,7 +48,7 @@ static struct clk_ops sh7203_master_clk_
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(FREQCR) & 0x0007);
+	int idx = (__raw_readw(FREQCR) & 0x0007);
 	return clk->parent->rate / pfc_divisors[idx];
 }
 
@@ -58,7 +58,7 @@ static struct clk_ops sh7203_module_clk_
 
 static unsigned long bus_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(FREQCR) & 0x0007);
+	int idx = (__raw_readw(FREQCR) & 0x0007);
 	return clk->parent->rate / pfc_divisors[idx-2];
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/clock-sh7206.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/clock-sh7206.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh2a/clock-sh7206.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,7 @@ static const int pfc_divisors[]={1,2,3,4
 
 static void master_clk_init(struct clk *clk)
 {
-	clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
+	clk->rate *= PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
 }
 
 static struct clk_ops sh7206_master_clk_ops = {
@@ -43,7 +43,7 @@ static struct clk_ops sh7206_master_clk_
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(FREQCR) & 0x0007);
+	int idx = (__raw_readw(FREQCR) & 0x0007);
 	return clk->parent->rate / pfc_divisors[idx];
 }
 
@@ -53,7 +53,7 @@ static struct clk_ops sh7206_module_clk_
 
 static unsigned long bus_clk_recalc(struct clk *clk)
 {
-	return clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
+	return clk->parent->rate / pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
 }
 
 static struct clk_ops sh7206_bus_clk_ops = {
@@ -62,7 +62,7 @@ static struct clk_ops sh7206_bus_clk_ops
 
 static unsigned long cpu_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(FREQCR) & 0x0007);
+	int idx = (__raw_readw(FREQCR) & 0x0007);
 	return clk->parent->rate / ifc_divisors[idx];
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/fpu.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh2a/fpu.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/fpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh2a/fpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,8 +26,7 @@
 /*
  * Save FPU registers onto task structure.
  */
-void
-save_fpu(struct task_struct *tsk)
+void save_fpu(struct task_struct *tsk)
 {
 	unsigned long dummy;
 
@@ -52,7 +51,7 @@ save_fpu(struct task_struct *tsk)
 		     "fmov.s	fr0, @-%0\n\t"
 		     "lds	%3, fpscr\n\t"
 		     : "=r" (dummy)
-		     : "0" ((char *)(&tsk->thread.fpu.hard.status)),
+		     : "0" ((char *)(&tsk->thread.xstate->hardfpu.status)),
 		       "r" (FPSCR_RCHG),
 		       "r" (FPSCR_INIT)
 		     : "memory");
@@ -60,8 +59,7 @@ save_fpu(struct task_struct *tsk)
 	disable_fpu();
 }
 
-static void
-restore_fpu(struct task_struct *tsk)
+void restore_fpu(struct task_struct *tsk)
 {
 	unsigned long dummy;
 
@@ -85,45 +83,12 @@ restore_fpu(struct task_struct *tsk)
 		     "lds.l	@%0+, fpscr\n\t"
 		     "lds.l	@%0+, fpul\n\t"
 		     : "=r" (dummy)
-		     : "0" (&tsk->thread.fpu), "r" (FPSCR_RCHG)
+		     : "0" (tsk->thread.xstate), "r" (FPSCR_RCHG)
 		     : "memory");
 	disable_fpu();
 }
 
 /*
- * Load the FPU with signalling NANS.  This bit pattern we're using
- * has the property that no matter wether considered as single or as
- * double precission represents signaling NANS.
- */
-
-static void
-fpu_init(void)
-{
-	enable_fpu();
-	asm volatile("lds	%0, fpul\n\t"
-		     "fsts	fpul, fr0\n\t"
-		     "fsts	fpul, fr1\n\t"
-		     "fsts	fpul, fr2\n\t"
-		     "fsts	fpul, fr3\n\t"
-		     "fsts	fpul, fr4\n\t"
-		     "fsts	fpul, fr5\n\t"
-		     "fsts	fpul, fr6\n\t"
-		     "fsts	fpul, fr7\n\t"
-		     "fsts	fpul, fr8\n\t"
-		     "fsts	fpul, fr9\n\t"
-		     "fsts	fpul, fr10\n\t"
-		     "fsts	fpul, fr11\n\t"
-		     "fsts	fpul, fr12\n\t"
-		     "fsts	fpul, fr13\n\t"
-		     "fsts	fpul, fr14\n\t"
-		     "fsts	fpul, fr15\n\t"
-		     "lds	%2, fpscr\n\t"
-		     : /* no output */
-		     : "r" (0), "r" (FPSCR_RCHG), "r" (FPSCR_INIT));
-	disable_fpu();
-}
-
-/*
  *	Emulate arithmetic ops on denormalized number for some FPU insns.
  */
 
@@ -490,9 +455,9 @@ ieee_fpe_handler (struct pt_regs *regs)
 	if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */
 		struct task_struct *tsk = current;
 
-		if ((tsk->thread.fpu.hard.fpscr & FPSCR_FPU_ERROR)) {
+		if ((tsk->thread.xstate->hardfpu.fpscr & FPSCR_FPU_ERROR)) {
 			/* FPU error */
-			denormal_to_double (&tsk->thread.fpu.hard,
+			denormal_to_double (&tsk->thread.xstate->hardfpu,
 					    (finsn >> 8) & 0xf);
 		} else
 			return 0;
@@ -507,9 +472,9 @@ ieee_fpe_handler (struct pt_regs *regs)
 
 		n = (finsn >> 8) & 0xf;
 		m = (finsn >> 4) & 0xf;
-		hx = tsk->thread.fpu.hard.fp_regs[n];
-		hy = tsk->thread.fpu.hard.fp_regs[m];
-		fpscr = tsk->thread.fpu.hard.fpscr;
+		hx = tsk->thread.xstate->hardfpu.fp_regs[n];
+		hy = tsk->thread.xstate->hardfpu.fp_regs[m];
+		fpscr = tsk->thread.xstate->hardfpu.fpscr;
 		prec = fpscr & (1 << 19);
 
 		if ((fpscr & FPSCR_FPU_ERROR)
@@ -519,15 +484,15 @@ ieee_fpe_handler (struct pt_regs *regs)
 
 			/* FPU error because of denormal */
 			llx = ((long long) hx << 32)
-			       | tsk->thread.fpu.hard.fp_regs[n+1];
+			       | tsk->thread.xstate->hardfpu.fp_regs[n+1];
 			lly = ((long long) hy << 32)
-			       | tsk->thread.fpu.hard.fp_regs[m+1];
+			       | tsk->thread.xstate->hardfpu.fp_regs[m+1];
 			if ((hx & 0x7fffffff) >= 0x00100000)
 				llx = denormal_muld(lly, llx);
 			else
 				llx = denormal_muld(llx, lly);
-			tsk->thread.fpu.hard.fp_regs[n] = llx >> 32;
-			tsk->thread.fpu.hard.fp_regs[n+1] = llx & 0xffffffff;
+			tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
+			tsk->thread.xstate->hardfpu.fp_regs[n+1] = llx & 0xffffffff;
 		} else if ((fpscr & FPSCR_FPU_ERROR)
 		     && (!prec && ((hx & 0x7fffffff) < 0x00800000
 				   || (hy & 0x7fffffff) < 0x00800000))) {
@@ -536,7 +501,7 @@ ieee_fpe_handler (struct pt_regs *regs)
 				hx = denormal_mulf(hy, hx);
 			else
 				hx = denormal_mulf(hx, hy);
-			tsk->thread.fpu.hard.fp_regs[n] = hx;
+			tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
 		} else
 			return 0;
 
@@ -550,9 +515,9 @@ ieee_fpe_handler (struct pt_regs *regs)
 
 		n = (finsn >> 8) & 0xf;
 		m = (finsn >> 4) & 0xf;
-		hx = tsk->thread.fpu.hard.fp_regs[n];
-		hy = tsk->thread.fpu.hard.fp_regs[m];
-		fpscr = tsk->thread.fpu.hard.fpscr;
+		hx = tsk->thread.xstate->hardfpu.fp_regs[n];
+		hy = tsk->thread.xstate->hardfpu.fp_regs[m];
+		fpscr = tsk->thread.xstate->hardfpu.fpscr;
 		prec = fpscr & (1 << 19);
 
 		if ((fpscr & FPSCR_FPU_ERROR)
@@ -562,15 +527,15 @@ ieee_fpe_handler (struct pt_regs *regs)
 
 			/* FPU error because of denormal */
 			llx = ((long long) hx << 32)
-			       | tsk->thread.fpu.hard.fp_regs[n+1];
+			       | tsk->thread.xstate->hardfpu.fp_regs[n+1];
 			lly = ((long long) hy << 32)
-			       | tsk->thread.fpu.hard.fp_regs[m+1];
+			       | tsk->thread.xstate->hardfpu.fp_regs[m+1];
 			if ((finsn & 0xf00f) == 0xf000)
 				llx = denormal_addd(llx, lly);
 			else
 				llx = denormal_addd(llx, lly ^ (1LL << 63));
-			tsk->thread.fpu.hard.fp_regs[n] = llx >> 32;
-			tsk->thread.fpu.hard.fp_regs[n+1] = llx & 0xffffffff;
+			tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
+			tsk->thread.xstate->hardfpu.fp_regs[n+1] = llx & 0xffffffff;
 		} else if ((fpscr & FPSCR_FPU_ERROR)
 		     && (!prec && ((hx & 0x7fffffff) < 0x00800000
 				   || (hy & 0x7fffffff) < 0x00800000))) {
@@ -579,7 +544,7 @@ ieee_fpe_handler (struct pt_regs *regs)
 				hx = denormal_addf(hx, hy);
 			else
 				hx = denormal_addf(hx, hy ^ 0x80000000);
-			tsk->thread.fpu.hard.fp_regs[n] = hx;
+			tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
 		} else
 			return 0;
 
@@ -597,7 +562,7 @@ BUILD_TRAP_HANDLER(fpu_error)
 
 	__unlazy_fpu(tsk, regs);
 	if (ieee_fpe_handler(regs)) {
-		tsk->thread.fpu.hard.fpscr &=
+		tsk->thread.xstate->hardfpu.fpscr &=
 			~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
 		grab_fpu(regs);
 		restore_fpu(tsk);
@@ -607,33 +572,3 @@ BUILD_TRAP_HANDLER(fpu_error)
 
 	force_sig(SIGFPE, tsk);
 }
-
-void fpu_state_restore(struct pt_regs *regs)
-{
-	struct task_struct *tsk = current;
-
-	grab_fpu(regs);
-	if (unlikely(!user_mode(regs))) {
-		printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
-		BUG();
-		return;
-	}
-
-	if (likely(used_math())) {
-		/* Using the FPU again.  */
-		restore_fpu(tsk);
-	} else	{
-		/* First time FPU user.  */
-		fpu_init();
-		set_used_math();
-	}
-	task_thread_info(tsk)->status |= TS_USEDFPU;
-	tsk->fpu_counter++;
-}
-
-BUILD_TRAP_HANDLER(fpu_state_restore)
-{
-	TRAP_HANDLER_DECL;
-
-	fpu_state_restore(regs);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/clock-sh3.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/clock-sh3.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/clock-sh3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/clock-sh3.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,7 @@ static int pfc_divisors[]    = { 1, 2, 3
 
 static void master_clk_init(struct clk *clk)
 {
-	int frqcr = ctrl_inw(FRQCR);
+	int frqcr = __raw_readw(FRQCR);
 	int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
 
 	clk->rate *= pfc_divisors[idx];
@@ -40,7 +40,7 @@ static struct clk_ops sh3_master_clk_ops
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int frqcr = ctrl_inw(FRQCR);
+	int frqcr = __raw_readw(FRQCR);
 	int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
 
 	return clk->parent->rate / pfc_divisors[idx];
@@ -52,7 +52,7 @@ static struct clk_ops sh3_module_clk_ops
 
 static unsigned long bus_clk_recalc(struct clk *clk)
 {
-	int frqcr = ctrl_inw(FRQCR);
+	int frqcr = __raw_readw(FRQCR);
 	int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4);
 
 	return clk->parent->rate / stc_multipliers[idx];
@@ -64,7 +64,7 @@ static struct clk_ops sh3_bus_clk_ops =
 
 static unsigned long cpu_clk_recalc(struct clk *clk)
 {
-	int frqcr = ctrl_inw(FRQCR);
+	int frqcr = __raw_readw(FRQCR);
 	int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2);
 
 	return clk->parent->rate / ifc_divisors[idx];
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7705.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7705.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7705.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7705.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,7 @@ static int pfc_divisors[]    = { 1, 2, 3
 
 static void master_clk_init(struct clk *clk)
 {
-	clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0003];
+	clk->rate *= pfc_divisors[__raw_readw(FRQCR) & 0x0003];
 }
 
 static struct clk_ops sh7705_master_clk_ops = {
@@ -41,7 +41,7 @@ static struct clk_ops sh7705_master_clk_
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int idx = ctrl_inw(FRQCR) & 0x0003;
+	int idx = __raw_readw(FRQCR) & 0x0003;
 	return clk->parent->rate / pfc_divisors[idx];
 }
 
@@ -51,7 +51,7 @@ static struct clk_ops sh7705_module_clk_
 
 static unsigned long bus_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(FRQCR) & 0x0300) >> 8;
+	int idx = (__raw_readw(FRQCR) & 0x0300) >> 8;
 	return clk->parent->rate / stc_multipliers[idx];
 }
 
@@ -61,7 +61,7 @@ static struct clk_ops sh7705_bus_clk_ops
 
 static unsigned long cpu_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(FRQCR) & 0x0030) >> 4;
+	int idx = (__raw_readw(FRQCR) & 0x0030) >> 4;
 	return clk->parent->rate / ifc_divisors[idx];
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7706.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7706.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7706.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7706.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,7 @@ static int pfc_divisors[]    = { 1, 2, 4
 
 static void master_clk_init(struct clk *clk)
 {
-	int frqcr = ctrl_inw(FRQCR);
+	int frqcr = __raw_readw(FRQCR);
 	int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
 
 	clk->rate *= pfc_divisors[idx];
@@ -36,7 +36,7 @@ static struct clk_ops sh7706_master_clk_
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int frqcr = ctrl_inw(FRQCR);
+	int frqcr = __raw_readw(FRQCR);
 	int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
 
 	return clk->parent->rate / pfc_divisors[idx];
@@ -48,7 +48,7 @@ static struct clk_ops sh7706_module_clk_
 
 static unsigned long bus_clk_recalc(struct clk *clk)
 {
-	int frqcr = ctrl_inw(FRQCR);
+	int frqcr = __raw_readw(FRQCR);
 	int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4);
 
 	return clk->parent->rate / stc_multipliers[idx];
@@ -60,7 +60,7 @@ static struct clk_ops sh7706_bus_clk_ops
 
 static unsigned long cpu_clk_recalc(struct clk *clk)
 {
-	int frqcr = ctrl_inw(FRQCR);
+	int frqcr = __raw_readw(FRQCR);
 	int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2);
 
 	return clk->parent->rate / ifc_divisors[idx];
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7709.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7709.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7709.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7709.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,7 @@ static int pfc_divisors[]    = { 1, 2, 4
 
 static void master_clk_init(struct clk *clk)
 {
-	int frqcr = ctrl_inw(FRQCR);
+	int frqcr = __raw_readw(FRQCR);
 	int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
 
 	clk->rate *= pfc_divisors[idx];
@@ -36,7 +36,7 @@ static struct clk_ops sh7709_master_clk_
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int frqcr = ctrl_inw(FRQCR);
+	int frqcr = __raw_readw(FRQCR);
 	int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
 
 	return clk->parent->rate / pfc_divisors[idx];
@@ -48,7 +48,7 @@ static struct clk_ops sh7709_module_clk_
 
 static unsigned long bus_clk_recalc(struct clk *clk)
 {
-	int frqcr = ctrl_inw(FRQCR);
+	int frqcr = __raw_readw(FRQCR);
 	int idx = (frqcr & 0x0080) ?
 		((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4) : 1;
 
@@ -61,7 +61,7 @@ static struct clk_ops sh7709_bus_clk_ops
 
 static unsigned long cpu_clk_recalc(struct clk *clk)
 {
-	int frqcr = ctrl_inw(FRQCR);
+	int frqcr = __raw_readw(FRQCR);
 	int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2);
 
 	return clk->parent->rate / ifc_divisors[idx];
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7710.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7710.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7710.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7710.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,7 @@ static int md_table[] = { 1, 2, 3, 4, 6,
 
 static void master_clk_init(struct clk *clk)
 {
-	clk->rate *= md_table[ctrl_inw(FRQCR) & 0x0007];
+	clk->rate *= md_table[__raw_readw(FRQCR) & 0x0007];
 }
 
 static struct clk_ops sh7710_master_clk_ops = {
@@ -35,7 +35,7 @@ static struct clk_ops sh7710_master_clk_
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(FRQCR) & 0x0007);
+	int idx = (__raw_readw(FRQCR) & 0x0007);
 	return clk->parent->rate / md_table[idx];
 }
 
@@ -45,7 +45,7 @@ static struct clk_ops sh7710_module_clk_
 
 static unsigned long bus_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(FRQCR) & 0x0700) >> 8;
+	int idx = (__raw_readw(FRQCR) & 0x0700) >> 8;
 	return clk->parent->rate / md_table[idx];
 }
 
@@ -55,7 +55,7 @@ static struct clk_ops sh7710_bus_clk_ops
 
 static unsigned long cpu_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(FRQCR) & 0x0070) >> 4;
+	int idx = (__raw_readw(FRQCR) & 0x0070) >> 4;
 	return clk->parent->rate / md_table[idx];
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7712.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7712.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7712.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/clock-sh7712.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,7 @@ static int divisors[]    = { 1, 2, 3, 4,
 
 static void master_clk_init(struct clk *clk)
 {
-	int frqcr = ctrl_inw(FRQCR);
+	int frqcr = __raw_readw(FRQCR);
 	int idx = (frqcr & 0x0300) >> 8;
 
 	clk->rate *= multipliers[idx];
@@ -35,7 +35,7 @@ static struct clk_ops sh7712_master_clk_
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int frqcr = ctrl_inw(FRQCR);
+	int frqcr = __raw_readw(FRQCR);
 	int idx = frqcr & 0x0007;
 
 	return clk->parent->rate / divisors[idx];
@@ -47,7 +47,7 @@ static struct clk_ops sh7712_module_clk_
 
 static unsigned long cpu_clk_recalc(struct clk *clk)
 {
-	int frqcr = ctrl_inw(FRQCR);
+	int frqcr = __raw_readw(FRQCR);
 	int idx = (frqcr & 0x0030) >> 4;
 
 	return clk->parent->rate / divisors[idx];
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/ex.S linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/ex.S
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/ex.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/ex.S	2010-05-16 17:17:36.000000000 -0400
@@ -49,7 +49,7 @@ ENTRY(exception_handling_table)
 	.long	exception_error	! reserved_instruction (filled by trap_init) /* 180 */
 	.long	exception_error	! illegal_slot_instruction (filled by trap_init) /*1A0*/
 	.long	nmi_trap_handler	/* 1C0 */	! Allow trap to debugger
-	.long	break_point_trap	/* 1E0 */
+	.long	breakpoint_trap_handler	/* 1E0 */
 
 	/*
 	 * Pad the remainder of the table out, exceptions residing in far
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/probe.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/probe.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/probe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/probe.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,7 @@
 #include <asm/cache.h>
 #include <asm/io.h>
 
-int __uses_jump_to_uncached detect_cpu_and_cache_system(void)
+int detect_cpu_and_cache_system(void)
 {
 	unsigned long addr0, addr1, data0, data1, data2, data3;
 
@@ -30,23 +30,23 @@ int __uses_jump_to_uncached detect_cpu_a
 	addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12);
 
 	/* First, write back & invalidate */
-	data0  = ctrl_inl(addr0);
-	ctrl_outl(data0&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr0);
-	data1  = ctrl_inl(addr1);
-	ctrl_outl(data1&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr1);
+	data0  = __raw_readl(addr0);
+	__raw_writel(data0&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr0);
+	data1  = __raw_readl(addr1);
+	__raw_writel(data1&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr1);
 
 	/* Next, check if there's shadow or not */
-	data0 = ctrl_inl(addr0);
+	data0 = __raw_readl(addr0);
 	data0 ^= SH_CACHE_VALID;
-	ctrl_outl(data0, addr0);
-	data1 = ctrl_inl(addr1);
+	__raw_writel(data0, addr0);
+	data1 = __raw_readl(addr1);
 	data2 = data1 ^ SH_CACHE_VALID;
-	ctrl_outl(data2, addr1);
-	data3 = ctrl_inl(addr0);
+	__raw_writel(data2, addr1);
+	data3 = __raw_readl(addr0);
 
 	/* Lastly, invaliate them. */
-	ctrl_outl(data0&~SH_CACHE_VALID, addr0);
-	ctrl_outl(data2&~SH_CACHE_VALID, addr1);
+	__raw_writel(data0&~SH_CACHE_VALID, addr0);
+	__raw_writel(data2&~SH_CACHE_VALID, addr1);
 
 	back_to_cached();
 
@@ -94,9 +94,9 @@ int __uses_jump_to_uncached detect_cpu_a
 		boot_cpu_data.dcache.way_incr	= (1 << 13);
 		boot_cpu_data.dcache.entry_mask	= 0x1ff0;
 		boot_cpu_data.dcache.sets	= 512;
-		ctrl_outl(CCR_CACHE_32KB, CCR3_REG);
+		__raw_writel(CCR_CACHE_32KB, CCR3_REG);
 #else
-		ctrl_outl(CCR_CACHE_16KB, CCR3_REG);
+		__raw_writel(CCR_CACHE_16KB, CCR3_REG);
 #endif
 #endif
 	}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/setup-sh3.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/setup-sh3.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/setup-sh3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh3/setup-sh3.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,7 +58,7 @@ static DECLARE_INTC_DESC_ACK(intc_desc_i
 void __init plat_irq_setup_pins(int mode)
 {
 	if (mode == IRQ_MODE_IRQ) {
-		ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1);
+		__raw_writew(__raw_readw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1);
 		register_intc_controller(&intc_desc_irq0123);
 		return;
 	}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/clock-sh4-202.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/clock-sh4-202.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/clock-sh4-202.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,7 @@ static int frqcr3_values[]   = { 0, 1, 2
 
 static unsigned long emi_clk_recalc(struct clk *clk)
 {
-	int idx = ctrl_inl(CPG2_FRQCR3) & 0x0007;
+	int idx = __raw_readl(CPG2_FRQCR3) & 0x0007;
 	return clk->parent->rate / frqcr3_divisors[idx];
 }
 
@@ -52,7 +52,7 @@ static struct clk sh4202_emi_clk = {
 
 static unsigned long femi_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inl(CPG2_FRQCR3) >> 3) & 0x0007;
+	int idx = (__raw_readl(CPG2_FRQCR3) >> 3) & 0x0007;
 	return clk->parent->rate / frqcr3_divisors[idx];
 }
 
@@ -92,7 +92,7 @@ static void shoc_clk_init(struct clk *cl
 
 static unsigned long shoc_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inl(CPG2_FRQCR3) >> 6) & 0x0007;
+	int idx = (__raw_readl(CPG2_FRQCR3) >> 6) & 0x0007;
 	return clk->parent->rate / frqcr3_divisors[idx];
 }
 
@@ -122,10 +122,10 @@ static int shoc_clk_set_rate(struct clk
 
 	tmp = frqcr3_lookup(clk, rate);
 
-	frqcr3 = ctrl_inl(CPG2_FRQCR3);
+	frqcr3 = __raw_readl(CPG2_FRQCR3);
 	frqcr3 &= ~(0x0007 << 6);
 	frqcr3 |= tmp << 6;
-	ctrl_outl(frqcr3, CPG2_FRQCR3);
+	__raw_writel(frqcr3, CPG2_FRQCR3);
 
 	clk->rate = clk->parent->rate / frqcr3_divisors[tmp];
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/clock-sh4.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/clock-sh4.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/clock-sh4.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/clock-sh4.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,7 @@ static int pfc_divisors[] = { 2, 3, 4, 6
 
 static void master_clk_init(struct clk *clk)
 {
-	clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0007];
+	clk->rate *= pfc_divisors[__raw_readw(FRQCR) & 0x0007];
 }
 
 static struct clk_ops sh4_master_clk_ops = {
@@ -37,7 +37,7 @@ static struct clk_ops sh4_master_clk_ops
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(FRQCR) & 0x0007);
+	int idx = (__raw_readw(FRQCR) & 0x0007);
 	return clk->parent->rate / pfc_divisors[idx];
 }
 
@@ -47,7 +47,7 @@ static struct clk_ops sh4_module_clk_ops
 
 static unsigned long bus_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(FRQCR) >> 3) & 0x0007;
+	int idx = (__raw_readw(FRQCR) >> 3) & 0x0007;
 	return clk->parent->rate / bfc_divisors[idx];
 }
 
@@ -57,7 +57,7 @@ static struct clk_ops sh4_bus_clk_ops =
 
 static unsigned long cpu_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(FRQCR) >> 6) & 0x0007;
+	int idx = (__raw_readw(FRQCR) >> 6) & 0x0007;
 	return clk->parent->rate / ifc_divisors[idx];
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/fpu.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/fpu.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/fpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/fpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -85,14 +85,14 @@ void save_fpu(struct task_struct *tsk)
 		      "fmov.s	fr1, @-%0\n\t"
 		      "fmov.s	fr0, @-%0\n\t"
 		      "lds	%3, fpscr\n\t":"=r" (dummy)
-		      :"0"((char *)(&tsk->thread.fpu.hard.status)),
+		      :"0"((char *)(&tsk->thread.xstate->hardfpu.status)),
 		      "r"(FPSCR_RCHG), "r"(FPSCR_INIT)
 		      :"memory");
 
 	disable_fpu();
 }
 
-static void restore_fpu(struct task_struct *tsk)
+void restore_fpu(struct task_struct *tsk)
 {
 	unsigned long dummy;
 
@@ -135,62 +135,11 @@ static void restore_fpu(struct task_stru
 		      "lds.l	@%0+, fpscr\n\t"
 		      "lds.l	@%0+, fpul\n\t"
 		      :"=r" (dummy)
-		      :"0"(&tsk->thread.fpu), "r"(FPSCR_RCHG)
+		      :"0" (tsk->thread.xstate), "r" (FPSCR_RCHG)
 		      :"memory");
 	disable_fpu();
 }
 
-/*
- * Load the FPU with signalling NANS.  This bit pattern we're using
- * has the property that no matter wether considered as single or as
- * double precision represents signaling NANS.
- */
-
-static void fpu_init(void)
-{
-	enable_fpu();
-	asm volatile (	"lds	%0, fpul\n\t"
-			"lds	%1, fpscr\n\t"
-			"fsts	fpul, fr0\n\t"
-			"fsts	fpul, fr1\n\t"
-			"fsts	fpul, fr2\n\t"
-			"fsts	fpul, fr3\n\t"
-			"fsts	fpul, fr4\n\t"
-			"fsts	fpul, fr5\n\t"
-			"fsts	fpul, fr6\n\t"
-			"fsts	fpul, fr7\n\t"
-			"fsts	fpul, fr8\n\t"
-			"fsts	fpul, fr9\n\t"
-			"fsts	fpul, fr10\n\t"
-			"fsts	fpul, fr11\n\t"
-			"fsts	fpul, fr12\n\t"
-			"fsts	fpul, fr13\n\t"
-			"fsts	fpul, fr14\n\t"
-			"fsts	fpul, fr15\n\t"
-			"frchg\n\t"
-			"fsts	fpul, fr0\n\t"
-			"fsts	fpul, fr1\n\t"
-			"fsts	fpul, fr2\n\t"
-			"fsts	fpul, fr3\n\t"
-			"fsts	fpul, fr4\n\t"
-			"fsts	fpul, fr5\n\t"
-			"fsts	fpul, fr6\n\t"
-			"fsts	fpul, fr7\n\t"
-			"fsts	fpul, fr8\n\t"
-			"fsts	fpul, fr9\n\t"
-			"fsts	fpul, fr10\n\t"
-			"fsts	fpul, fr11\n\t"
-			"fsts	fpul, fr12\n\t"
-			"fsts	fpul, fr13\n\t"
-			"fsts	fpul, fr14\n\t"
-			"fsts	fpul, fr15\n\t"
-			"frchg\n\t"
-			"lds	%2, fpscr\n\t"
-			:	/* no output */
-			:"r" (0), "r"(FPSCR_RCHG), "r"(FPSCR_INIT));
-	disable_fpu();
-}
-
 /**
  *      denormal_to_double - Given denormalized float number,
  *                           store double float
@@ -282,9 +231,9 @@ static int ieee_fpe_handler(struct pt_re
 		/* fcnvsd */
 		struct task_struct *tsk = current;
 
-		if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR))
+		if ((tsk->thread.xstate->hardfpu.fpscr & FPSCR_CAUSE_ERROR))
 			/* FPU error */
-			denormal_to_double(&tsk->thread.fpu.hard,
+			denormal_to_double(&tsk->thread.xstate->hardfpu,
 					   (finsn >> 8) & 0xf);
 		else
 			return 0;
@@ -300,9 +249,9 @@ static int ieee_fpe_handler(struct pt_re
 
 		n = (finsn >> 8) & 0xf;
 		m = (finsn >> 4) & 0xf;
-		hx = tsk->thread.fpu.hard.fp_regs[n];
-		hy = tsk->thread.fpu.hard.fp_regs[m];
-		fpscr = tsk->thread.fpu.hard.fpscr;
+		hx = tsk->thread.xstate->hardfpu.fp_regs[n];
+		hy = tsk->thread.xstate->hardfpu.fp_regs[m];
+		fpscr = tsk->thread.xstate->hardfpu.fpscr;
 		prec = fpscr & FPSCR_DBL_PRECISION;
 
 		if ((fpscr & FPSCR_CAUSE_ERROR)
@@ -312,18 +261,18 @@ static int ieee_fpe_handler(struct pt_re
 
 			/* FPU error because of denormal (doubles) */
 			llx = ((long long)hx << 32)
-			    | tsk->thread.fpu.hard.fp_regs[n + 1];
+			    | tsk->thread.xstate->hardfpu.fp_regs[n + 1];
 			lly = ((long long)hy << 32)
-			    | tsk->thread.fpu.hard.fp_regs[m + 1];
+			    | tsk->thread.xstate->hardfpu.fp_regs[m + 1];
 			llx = float64_mul(llx, lly);
-			tsk->thread.fpu.hard.fp_regs[n] = llx >> 32;
-			tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff;
+			tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
+			tsk->thread.xstate->hardfpu.fp_regs[n + 1] = llx & 0xffffffff;
 		} else if ((fpscr & FPSCR_CAUSE_ERROR)
 			   && (!prec && ((hx & 0x7fffffff) < 0x00800000
 					 || (hy & 0x7fffffff) < 0x00800000))) {
 			/* FPU error because of denormal (floats) */
 			hx = float32_mul(hx, hy);
-			tsk->thread.fpu.hard.fp_regs[n] = hx;
+			tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
 		} else
 			return 0;
 
@@ -338,9 +287,9 @@ static int ieee_fpe_handler(struct pt_re
 
 		n = (finsn >> 8) & 0xf;
 		m = (finsn >> 4) & 0xf;
-		hx = tsk->thread.fpu.hard.fp_regs[n];
-		hy = tsk->thread.fpu.hard.fp_regs[m];
-		fpscr = tsk->thread.fpu.hard.fpscr;
+		hx = tsk->thread.xstate->hardfpu.fp_regs[n];
+		hy = tsk->thread.xstate->hardfpu.fp_regs[m];
+		fpscr = tsk->thread.xstate->hardfpu.fpscr;
 		prec = fpscr & FPSCR_DBL_PRECISION;
 
 		if ((fpscr & FPSCR_CAUSE_ERROR)
@@ -350,15 +299,15 @@ static int ieee_fpe_handler(struct pt_re
 
 			/* FPU error because of denormal (doubles) */
 			llx = ((long long)hx << 32)
-			    | tsk->thread.fpu.hard.fp_regs[n + 1];
+			    | tsk->thread.xstate->hardfpu.fp_regs[n + 1];
 			lly = ((long long)hy << 32)
-			    | tsk->thread.fpu.hard.fp_regs[m + 1];
+			    | tsk->thread.xstate->hardfpu.fp_regs[m + 1];
 			if ((finsn & 0xf00f) == 0xf000)
 				llx = float64_add(llx, lly);
 			else
 				llx = float64_sub(llx, lly);
-			tsk->thread.fpu.hard.fp_regs[n] = llx >> 32;
-			tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff;
+			tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
+			tsk->thread.xstate->hardfpu.fp_regs[n + 1] = llx & 0xffffffff;
 		} else if ((fpscr & FPSCR_CAUSE_ERROR)
 			   && (!prec && ((hx & 0x7fffffff) < 0x00800000
 					 || (hy & 0x7fffffff) < 0x00800000))) {
@@ -367,7 +316,7 @@ static int ieee_fpe_handler(struct pt_re
 				hx = float32_add(hx, hy);
 			else
 				hx = float32_sub(hx, hy);
-			tsk->thread.fpu.hard.fp_regs[n] = hx;
+			tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
 		} else
 			return 0;
 
@@ -382,9 +331,9 @@ static int ieee_fpe_handler(struct pt_re
 
 		n = (finsn >> 8) & 0xf;
 		m = (finsn >> 4) & 0xf;
-		hx = tsk->thread.fpu.hard.fp_regs[n];
-		hy = tsk->thread.fpu.hard.fp_regs[m];
-		fpscr = tsk->thread.fpu.hard.fpscr;
+		hx = tsk->thread.xstate->hardfpu.fp_regs[n];
+		hy = tsk->thread.xstate->hardfpu.fp_regs[m];
+		fpscr = tsk->thread.xstate->hardfpu.fpscr;
 		prec = fpscr & FPSCR_DBL_PRECISION;
 
 		if ((fpscr & FPSCR_CAUSE_ERROR)
@@ -394,20 +343,20 @@ static int ieee_fpe_handler(struct pt_re
 
 			/* FPU error because of denormal (doubles) */
 			llx = ((long long)hx << 32)
-			    | tsk->thread.fpu.hard.fp_regs[n + 1];
+			    | tsk->thread.xstate->hardfpu.fp_regs[n + 1];
 			lly = ((long long)hy << 32)
-			    | tsk->thread.fpu.hard.fp_regs[m + 1];
+			    | tsk->thread.xstate->hardfpu.fp_regs[m + 1];
 
 			llx = float64_div(llx, lly);
 
-			tsk->thread.fpu.hard.fp_regs[n] = llx >> 32;
-			tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff;
+			tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
+			tsk->thread.xstate->hardfpu.fp_regs[n + 1] = llx & 0xffffffff;
 		} else if ((fpscr & FPSCR_CAUSE_ERROR)
 			   && (!prec && ((hx & 0x7fffffff) < 0x00800000
 					 || (hy & 0x7fffffff) < 0x00800000))) {
 			/* FPU error because of denormal (floats) */
 			hx = float32_div(hx, hy);
-			tsk->thread.fpu.hard.fp_regs[n] = hx;
+			tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
 		} else
 			return 0;
 
@@ -420,17 +369,17 @@ static int ieee_fpe_handler(struct pt_re
 		unsigned int hx;
 
 		m = (finsn >> 8) & 0x7;
-		hx = tsk->thread.fpu.hard.fp_regs[m];
+		hx = tsk->thread.xstate->hardfpu.fp_regs[m];
 
-		if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR)
+		if ((tsk->thread.xstate->hardfpu.fpscr & FPSCR_CAUSE_ERROR)
 			&& ((hx & 0x7fffffff) < 0x00100000)) {
 			/* subnormal double to float conversion */
 			long long llx;
 
-			llx = ((long long)tsk->thread.fpu.hard.fp_regs[m] << 32)
-			    | tsk->thread.fpu.hard.fp_regs[m + 1];
+			llx = ((long long)tsk->thread.xstate->hardfpu.fp_regs[m] << 32)
+			    | tsk->thread.xstate->hardfpu.fp_regs[m + 1];
 
-			tsk->thread.fpu.hard.fpul = float64_to_float32(llx);
+			tsk->thread.xstate->hardfpu.fpul = float64_to_float32(llx);
 		} else
 			return 0;
 
@@ -449,7 +398,7 @@ void float_raise(unsigned int flags)
 int float_rounding_mode(void)
 {
 	struct task_struct *tsk = current;
-	int roundingMode = FPSCR_ROUNDING_MODE(tsk->thread.fpu.hard.fpscr);
+	int roundingMode = FPSCR_ROUNDING_MODE(tsk->thread.xstate->hardfpu.fpscr);
 	return roundingMode;
 }
 
@@ -461,16 +410,16 @@ BUILD_TRAP_HANDLER(fpu_error)
 	__unlazy_fpu(tsk, regs);
 	fpu_exception_flags = 0;
 	if (ieee_fpe_handler(regs)) {
-		tsk->thread.fpu.hard.fpscr &=
+		tsk->thread.xstate->hardfpu.fpscr &=
 		    ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
-		tsk->thread.fpu.hard.fpscr |= fpu_exception_flags;
+		tsk->thread.xstate->hardfpu.fpscr |= fpu_exception_flags;
 		/* Set the FPSCR flag as well as cause bits - simply
 		 * replicate the cause */
-		tsk->thread.fpu.hard.fpscr |= (fpu_exception_flags >> 10);
+		tsk->thread.xstate->hardfpu.fpscr |= (fpu_exception_flags >> 10);
 		grab_fpu(regs);
 		restore_fpu(tsk);
 		task_thread_info(tsk)->status |= TS_USEDFPU;
-		if ((((tsk->thread.fpu.hard.fpscr & FPSCR_ENABLE_MASK) >> 7) &
+		if ((((tsk->thread.xstate->hardfpu.fpscr & FPSCR_ENABLE_MASK) >> 7) &
 		     (fpu_exception_flags >> 2)) == 0) {
 			return;
 		}
@@ -478,33 +427,3 @@ BUILD_TRAP_HANDLER(fpu_error)
 
 	force_sig(SIGFPE, tsk);
 }
-
-void fpu_state_restore(struct pt_regs *regs)
-{
-	struct task_struct *tsk = current;
-
-	grab_fpu(regs);
-	if (unlikely(!user_mode(regs))) {
-		printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
-		BUG();
-		return;
-	}
-
-	if (likely(used_math())) {
-		/* Using the FPU again.  */
-		restore_fpu(tsk);
-	} else {
-		/* First time FPU user.  */
-		fpu_init();
-		set_used_math();
-	}
-	task_thread_info(tsk)->status |= TS_USEDFPU;
-	tsk->fpu_counter++;
-}
-
-BUILD_TRAP_HANDLER(fpu_state_restore)
-{
-	TRAP_HANDLER_DECL;
-
-	fpu_state_restore(regs);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/probe.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/probe.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/probe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/probe.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,9 +28,9 @@ int __init detect_cpu_and_cache_system(v
 		[9] = (1 << 16)
 	};
 
-	pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffffff;
-	prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff;
-	cvr = (ctrl_inl(CCN_CVR));
+	pvr = (__raw_readl(CCN_PVR) >> 8) & 0xffffff;
+	prr = (__raw_readl(CCN_PRR) >> 4) & 0xff;
+	cvr = (__raw_readl(CCN_CVR));
 
 	/*
 	 * Setup some sane SH-4 defaults for the icache
@@ -71,11 +71,11 @@ int __init detect_cpu_and_cache_system(v
 		boot_cpu_data.dcache.ways = 4;
 	} else {
 		/* And some SH-4 defaults.. */
-		boot_cpu_data.flags |= CPU_HAS_PTEA;
+		boot_cpu_data.flags |= CPU_HAS_PTEA | CPU_HAS_FPU;
 		boot_cpu_data.family = CPU_FAMILY_SH4;
 	}
 
-	/* FPU detection works for everyone */
+	/* FPU detection works for almost everyone */
 	if ((cvr & 0x20000000))
 		boot_cpu_data.flags |= CPU_HAS_FPU;
 
@@ -124,6 +124,7 @@ int __init detect_cpu_and_cache_system(v
 		boot_cpu_data.type = CPU_SH7785;
 		break;
 	case 0x4004:
+	case 0x4005:
 		boot_cpu_data.type = CPU_SH7786;
 		boot_cpu_data.flags |= CPU_HAS_PTEAEX | CPU_HAS_L2_CACHE;
 		break;
@@ -160,6 +161,7 @@ int __init detect_cpu_and_cache_system(v
 		break;
 	case 0x700:
 		boot_cpu_data.type = CPU_SH4_501;
+		boot_cpu_data.flags &= ~CPU_HAS_FPU;
 		boot_cpu_data.icache.ways = 2;
 		boot_cpu_data.dcache.ways = 2;
 		break;
@@ -227,7 +229,7 @@ int __init detect_cpu_and_cache_system(v
 			 * Size calculation is much more sensible
 			 * than it is for the L1.
 			 *
-			 * Sizes are 128KB, 258KB, 512KB, and 1MB.
+			 * Sizes are 128KB, 256KB, 512KB, and 1MB.
 			 */
 			size = (cvr & 0xf) << 17;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/setup-sh4-202.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/setup-sh4-202.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/setup-sh4-202.c	2010-05-16 17:17:36.000000000 -0400
@@ -198,7 +198,7 @@ void __init plat_irq_setup_pins(int mode
 {
 	switch (mode) {
 	case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */
-		ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
+		__raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
 		register_intc_controller(&intc_desc_irlm);
 		break;
 	default:
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7750.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7750.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7750.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7750.c	2010-05-16 17:17:36.000000000 -0400
@@ -442,7 +442,7 @@ void __init plat_irq_setup_pins(int mode
 
 	switch (mode) {
 	case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */
-		ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
+		__raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
 		register_intc_controller(&intc_desc_irlm);
 		break;
 	default:
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7760.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7760.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7760.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7760.c	2010-05-16 17:17:36.000000000 -0400
@@ -319,7 +319,7 @@ void __init plat_irq_setup_pins(int mode
 {
 	switch (mode) {
 	case IRQ_MODE_IRQ:
-		ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
+		__raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
 		register_intc_controller(&intc_desc_irq);
 		break;
 	default:
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/sq.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/sq.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/sq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4/sq.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,9 +43,9 @@ static unsigned long *sq_bitmap;
 
 #define store_queue_barrier()			\
 do {						\
-	(void)ctrl_inl(P4SEG_STORE_QUE);	\
-	ctrl_outl(0, P4SEG_STORE_QUE + 0);	\
-	ctrl_outl(0, P4SEG_STORE_QUE + 8);	\
+	(void)__raw_readl(P4SEG_STORE_QUE);	\
+	__raw_writel(0, P4SEG_STORE_QUE + 0);	\
+	__raw_writel(0, P4SEG_STORE_QUE + 8);	\
 } while (0);
 
 /**
@@ -100,7 +100,7 @@ static inline void sq_mapping_list_del(s
 	spin_unlock_irq(&sq_mapping_lock);
 }
 
-static int __sq_remap(struct sq_mapping *map, unsigned long flags)
+static int __sq_remap(struct sq_mapping *map, pgprot_t prot)
 {
 #if defined(CONFIG_MMU)
 	struct vm_struct *vma;
@@ -113,7 +113,7 @@ static int __sq_remap(struct sq_mapping
 
 	if (ioremap_page_range((unsigned long)vma->addr,
 			       (unsigned long)vma->addr + map->size,
-			       vma->phys_addr, __pgprot(flags))) {
+			       vma->phys_addr, prot)) {
 		vunmap(vma->addr);
 		return -EAGAIN;
 	}
@@ -123,8 +123,8 @@ static int __sq_remap(struct sq_mapping
 	 * straightforward, as we can just load up each queue's QACR with
 	 * the physical address appropriately masked.
 	 */
-	ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR0);
-	ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR1);
+	__raw_writel(((map->addr >> 26) << 2) & 0x1c, SQ_QACR0);
+	__raw_writel(((map->addr >> 26) << 2) & 0x1c, SQ_QACR1);
 #endif
 
 	return 0;
@@ -135,14 +135,14 @@ static int __sq_remap(struct sq_mapping
  * @phys: Physical address of mapping.
  * @size: Length of mapping.
  * @name: User invoking mapping.
- * @flags: Protection flags.
+ * @prot: Protection bits.
  *
  * Remaps the physical address @phys through the next available store queue
  * address of @size length. @name is logged at boot time as well as through
  * the sysfs interface.
  */
 unsigned long sq_remap(unsigned long phys, unsigned int size,
-		       const char *name, unsigned long flags)
+		       const char *name, pgprot_t prot)
 {
 	struct sq_mapping *map;
 	unsigned long end;
@@ -177,7 +177,7 @@ unsigned long sq_remap(unsigned long phy
 
 	map->sq_addr = P4SEG_STORE_QUE + (page << PAGE_SHIFT);
 
-	ret = __sq_remap(map, pgprot_val(PAGE_KERNEL_NOCACHE) | flags);
+	ret = __sq_remap(map, prot);
 	if (unlikely(ret != 0))
 		goto out;
 
@@ -309,8 +309,7 @@ static ssize_t mapping_store(const char
 		return -EIO;
 
 	if (likely(len)) {
-		int ret = sq_remap(base, len, "Userspace",
-				   pgprot_val(PAGE_SHARED));
+		int ret = sq_remap(base, len, "Userspace", PAGE_SHARED);
 		if (ret < 0)
 			return ret;
 	} else
@@ -327,7 +326,7 @@ static struct attribute *sq_sysfs_attrs[
 	NULL,
 };
 
-static struct sysfs_ops sq_sysfs_ops = {
+static const struct sysfs_ops sq_sysfs_ops = {
 	.show	= sq_sysfs_show,
 	.store	= sq_sysfs_store,
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7343.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7343.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7343.c	2010-05-16 17:17:36.000000000 -0400
@@ -107,13 +107,17 @@ struct clk *main_clks[] = {
 static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
 static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
 
-static struct clk_div_mult_table div4_table = {
+static struct clk_div_mult_table div4_div_mult_table = {
 	.divisors = divisors,
 	.nr_divisors = ARRAY_SIZE(divisors),
 	.multipliers = multipliers,
 	.nr_multipliers = ARRAY_SIZE(multipliers),
 };
 
+static struct clk_div4_table div4_table = {
+	.div_mult_table = &div4_div_mult_table,
+};
+
 enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
        DIV4_SIUA, DIV4_SIUB, DIV4_NR };
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7366.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7366.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7366.c	2010-05-16 17:17:36.000000000 -0400
@@ -110,13 +110,17 @@ struct clk *main_clks[] = {
 static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
 static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
 
-static struct clk_div_mult_table div4_table = {
+static struct clk_div_mult_table div4_div_mult_table = {
 	.divisors = divisors,
 	.nr_divisors = ARRAY_SIZE(divisors),
 	.multipliers = multipliers,
 	.nr_multipliers = ARRAY_SIZE(multipliers),
 };
 
+static struct clk_div4_table div4_table = {
+	.div_mult_table = &div4_div_mult_table,
+};
+
 enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
        DIV4_SIUA, DIV4_SIUB, DIV4_NR };
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7722.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7722.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7722.c	2010-05-16 17:17:36.000000000 -0400
@@ -110,19 +110,22 @@ struct clk *main_clks[] = {
 static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
 static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
 
-static struct clk_div_mult_table div4_table = {
+static struct clk_div_mult_table div4_div_mult_table = {
 	.divisors = divisors,
 	.nr_divisors = ARRAY_SIZE(divisors),
 	.multipliers = multipliers,
 	.nr_multipliers = ARRAY_SIZE(multipliers),
 };
 
-enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
-       DIV4_SIUA, DIV4_SIUB, DIV4_IRDA, DIV4_NR };
+static struct clk_div4_table div4_table = {
+	.div_mult_table = &div4_div_mult_table,
+};
 
 #define DIV4(_str, _reg, _bit, _mask, _flags) \
   SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags)
 
+enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_NR };
+
 struct clk div4_clks[DIV4_NR] = {
 	[DIV4_I] = DIV4("cpu_clk", FRQCR, 20, 0x1fef, CLK_ENABLE_ON_INIT),
 	[DIV4_U] = DIV4("umem_clk", FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT),
@@ -130,9 +133,19 @@ struct clk div4_clks[DIV4_NR] = {
 	[DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT),
 	[DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT),
 	[DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x1fff, 0),
+};
+
+enum { DIV4_IRDA, DIV4_ENABLE_NR };
+
+struct clk div4_enable_clks[DIV4_ENABLE_NR] = {
+	[DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x1fff, 0),
+};
+
+enum { DIV4_SIUA, DIV4_SIUB, DIV4_REPARENT_NR };
+
+struct clk div4_reparent_clks[DIV4_REPARENT_NR] = {
 	[DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x1fff, 0),
 	[DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x1fff, 0),
-	[DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x1fff, 0),
 };
 
 struct clk div6_clks[] = {
@@ -189,6 +202,14 @@ int __init arch_clk_init(void)
 		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
 
 	if (!ret)
+		ret = sh_clk_div4_enable_register(div4_enable_clks,
+					DIV4_ENABLE_NR, &div4_table);
+
+	if (!ret)
+		ret = sh_clk_div4_reparent_register(div4_reparent_clks,
+					DIV4_REPARENT_NR, &div4_table);
+
+	if (!ret)
 		ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
 
 	if (!ret)
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7723.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7723.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7723.c	2010-05-16 17:17:36.000000000 -0400
@@ -110,15 +110,18 @@ struct clk *main_clks[] = {
 static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
 static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
 
-static struct clk_div_mult_table div4_table = {
+static struct clk_div_mult_table div4_div_mult_table = {
 	.divisors = divisors,
 	.nr_divisors = ARRAY_SIZE(divisors),
 	.multipliers = multipliers,
 	.nr_multipliers = ARRAY_SIZE(multipliers),
 };
 
-enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
-       DIV4_SIUA, DIV4_SIUB, DIV4_IRDA, DIV4_NR };
+static struct clk_div4_table div4_table = {
+	.div_mult_table = &div4_div_mult_table,
+};
+
+enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_NR };
 
 #define DIV4(_str, _reg, _bit, _mask, _flags) \
   SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags)
@@ -130,11 +133,20 @@ struct clk div4_clks[DIV4_NR] = {
 	[DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x0dbf, CLK_ENABLE_ON_INIT),
 	[DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x0db4, CLK_ENABLE_ON_INIT),
 	[DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x0dbf, 0),
-	[DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x0dbf, 0),
-	[DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x0dbf, 0),
+};
+
+enum { DIV4_IRDA, DIV4_ENABLE_NR };
+
+struct clk div4_enable_clks[DIV4_ENABLE_NR] = {
 	[DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x0dbf, 0),
 };
 
+enum { DIV4_SIUA, DIV4_SIUB, DIV4_REPARENT_NR };
+
+struct clk div4_reparent_clks[DIV4_REPARENT_NR] = {
+	[DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x0dbf, 0),
+	[DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x0dbf, 0),
+};
 struct clk div6_clks[] = {
 	SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0),
 };
@@ -216,6 +228,14 @@ int __init arch_clk_init(void)
 		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
 
 	if (!ret)
+		ret = sh_clk_div4_enable_register(div4_enable_clks,
+					DIV4_ENABLE_NR, &div4_table);
+
+	if (!ret)
+		ret = sh_clk_div4_reparent_register(div4_reparent_clks,
+					DIV4_REPARENT_NR, &div4_table);
+
+	if (!ret)
 		ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
 
 	if (!ret)
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7724.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7724.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7724.c	2010-05-16 17:17:36.000000000 -0400
@@ -127,13 +127,28 @@ struct clk *main_clks[] = {
 	&div3_clk,
 };
 
+static void div4_kick(struct clk *clk)
+{
+	unsigned long value;
+
+	/* set KICK bit in FRQCRA to update hardware setting */
+	value = __raw_readl(FRQCRA);
+	value |= (1 << 31);
+	__raw_writel(value, FRQCRA);
+}
+
 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 0, 24, 32, 36, 48, 0, 72 };
 
-static struct clk_div_mult_table div4_table = {
+static struct clk_div_mult_table div4_div_mult_table = {
 	.divisors = divisors,
 	.nr_divisors = ARRAY_SIZE(divisors),
 };
 
+static struct clk_div4_table div4_table = {
+	.div_mult_table = &div4_div_mult_table,
+	.kick = div4_kick,
+};
+
 enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_P, DIV4_M1, DIV4_NR };
 
 #define DIV4(_str, _reg, _bit, _mask, _flags) \
@@ -144,7 +159,7 @@ struct clk div4_clks[DIV4_NR] = {
 	[DIV4_SH] = DIV4("shyway_clk", FRQCRA, 12, 0x2f7c, CLK_ENABLE_ON_INIT),
 	[DIV4_B] = DIV4("bus_clk", FRQCRA, 8, 0x2f7c, CLK_ENABLE_ON_INIT),
 	[DIV4_P] = DIV4("peripheral_clk", FRQCRA, 0, 0x2f7c, 0),
-	[DIV4_M1] = DIV4("vpu_clk", FRQCRB, 4, 0x2f7c, 0),
+	[DIV4_M1] = DIV4("vpu_clk", FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT),
 };
 
 struct clk div6_clks[] = {
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7757.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7757.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7757.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,7 +35,7 @@ static struct clk_ops sh7757_master_clk_
 
 static void module_clk_recalc(struct clk *clk)
 {
-	int idx = ctrl_inl(FRQCR) & 0x0000000f;
+	int idx = __raw_readl(FRQCR) & 0x0000000f;
 	clk->rate = clk->parent->rate / p1fc_divisors[idx];
 }
 
@@ -45,7 +45,7 @@ static struct clk_ops sh7757_module_clk_
 
 static void bus_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inl(FRQCR) >> 8) & 0x0000000f;
+	int idx = (__raw_readl(FRQCR) >> 8) & 0x0000000f;
 	clk->rate = clk->parent->rate / bfc_divisors[idx];
 }
 
@@ -55,7 +55,7 @@ static struct clk_ops sh7757_bus_clk_ops
 
 static void cpu_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inl(FRQCR) >> 20) & 0x0000000f;
+	int idx = (__raw_readl(FRQCR) >> 20) & 0x0000000f;
 	clk->rate = clk->parent->rate / ifc_divisors[idx];
 }
 
@@ -78,7 +78,7 @@ void __init arch_init_clk_ops(struct clk
 
 static void shyway_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inl(FRQCR) >> 12) & 0x0000000f;
+	int idx = (__raw_readl(FRQCR) >> 12) & 0x0000000f;
 	clk->rate = clk->parent->rate / sfc_divisors[idx];
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7763.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7763.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7763.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,7 @@ static int cfc_divisors[] = { 1, 1, 4, 1
 
 static void master_clk_init(struct clk *clk)
 {
-	clk->rate *= p0fc_divisors[(ctrl_inl(FRQCR) >> 4) & 0x07];
+	clk->rate *= p0fc_divisors[(__raw_readl(FRQCR) >> 4) & 0x07];
 }
 
 static struct clk_ops sh7763_master_clk_ops = {
@@ -31,7 +31,7 @@ static struct clk_ops sh7763_master_clk_
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int idx = ((ctrl_inl(FRQCR) >> 4) & 0x07);
+	int idx = ((__raw_readl(FRQCR) >> 4) & 0x07);
 	return clk->parent->rate / p0fc_divisors[idx];
 }
 
@@ -41,7 +41,7 @@ static struct clk_ops sh7763_module_clk_
 
 static unsigned long bus_clk_recalc(struct clk *clk)
 {
-	int idx = ((ctrl_inl(FRQCR) >> 16) & 0x07);
+	int idx = ((__raw_readl(FRQCR) >> 16) & 0x07);
 	return clk->parent->rate / bfc_divisors[idx];
 }
 
@@ -68,7 +68,7 @@ void __init arch_init_clk_ops(struct clk
 
 static unsigned long shyway_clk_recalc(struct clk *clk)
 {
-	int idx = ((ctrl_inl(FRQCR) >> 20) & 0x07);
+	int idx = ((__raw_readl(FRQCR) >> 20) & 0x07);
 	return clk->parent->rate / cfc_divisors[idx];
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7770.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7770.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7770.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7770.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,7 @@ static int pfc_divisors[] = { 1, 8, 1,10
 
 static void master_clk_init(struct clk *clk)
 {
-	clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> 28) & 0x000f];
+	clk->rate *= pfc_divisors[(__raw_readl(FRQCR) >> 28) & 0x000f];
 }
 
 static struct clk_ops sh7770_master_clk_ops = {
@@ -30,7 +30,7 @@ static struct clk_ops sh7770_master_clk_
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int idx = ((ctrl_inl(FRQCR) >> 28) & 0x000f);
+	int idx = ((__raw_readl(FRQCR) >> 28) & 0x000f);
 	return clk->parent->rate / pfc_divisors[idx];
 }
 
@@ -40,7 +40,7 @@ static struct clk_ops sh7770_module_clk_
 
 static unsigned long bus_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inl(FRQCR) & 0x000f);
+	int idx = (__raw_readl(FRQCR) & 0x000f);
 	return clk->parent->rate / bfc_divisors[idx];
 }
 
@@ -50,7 +50,7 @@ static struct clk_ops sh7770_bus_clk_ops
 
 static unsigned long cpu_clk_recalc(struct clk *clk)
 {
-	int idx = ((ctrl_inl(FRQCR) >> 24) & 0x000f);
+	int idx = ((__raw_readl(FRQCR) >> 24) & 0x000f);
 	return clk->parent->rate / ifc_divisors[idx];
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7780.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7780.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7780.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,7 @@ static int cfc_divisors[] = { 1, 1, 4, 1
 
 static void master_clk_init(struct clk *clk)
 {
-	clk->rate *= pfc_divisors[ctrl_inl(FRQCR) & 0x0003];
+	clk->rate *= pfc_divisors[__raw_readl(FRQCR) & 0x0003];
 }
 
 static struct clk_ops sh7780_master_clk_ops = {
@@ -31,7 +31,7 @@ static struct clk_ops sh7780_master_clk_
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inl(FRQCR) & 0x0003);
+	int idx = (__raw_readl(FRQCR) & 0x0003);
 	return clk->parent->rate / pfc_divisors[idx];
 }
 
@@ -41,7 +41,7 @@ static struct clk_ops sh7780_module_clk_
 
 static unsigned long bus_clk_recalc(struct clk *clk)
 {
-	int idx = ((ctrl_inl(FRQCR) >> 16) & 0x0007);
+	int idx = ((__raw_readl(FRQCR) >> 16) & 0x0007);
 	return clk->parent->rate / bfc_divisors[idx];
 }
 
@@ -51,7 +51,7 @@ static struct clk_ops sh7780_bus_clk_ops
 
 static unsigned long cpu_clk_recalc(struct clk *clk)
 {
-	int idx = ((ctrl_inl(FRQCR) >> 24) & 0x0001);
+	int idx = ((__raw_readl(FRQCR) >> 24) & 0x0001);
 	return clk->parent->rate / ifc_divisors[idx];
 }
 
@@ -74,7 +74,7 @@ void __init arch_init_clk_ops(struct clk
 
 static unsigned long shyway_clk_recalc(struct clk *clk)
 {
-	int idx = ((ctrl_inl(FRQCR) >> 20) & 0x0007);
+	int idx = ((__raw_readl(FRQCR) >> 20) & 0x0007);
 	return clk->parent->rate / cfc_divisors[idx];
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7785.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7785.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7785.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,11 +57,15 @@ static struct clk *clks[] = {
 static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18,
 			       24, 32, 36, 48 };
 
-static struct clk_div_mult_table div4_table = {
+static struct clk_div_mult_table div4_div_mult_table = {
 	.divisors = div2,
 	.nr_divisors = ARRAY_SIZE(div2),
 };
 
+static struct clk_div4_table div4_table = {
+	.div_mult_table = &div4_div_mult_table,
+};
+
 enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_GA,
 	DIV4_DU, DIV4_P, DIV4_NR };
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7786.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7786.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7786.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,11 +3,7 @@
  *
  * 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
+ *  Copyright (C) 2010  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
@@ -15,127 +11,127 @@
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.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,
+/*
+ * Default rate for the root input clock, reset this with clk_set_rate()
+ * from the platform code.
+ */
+static struct clk extal_clk = {
+	.name		= "extal",
+	.id		= -1,
+	.rate		= 33333333,
 };
 
-static unsigned long module_clk_recalc(struct clk *clk)
+static unsigned long pll_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inl(FRQMR1) & 0x000f);
-	return clk->parent->rate / pfc_divisors[idx];
-}
+	int multiplier;
 
-static struct clk_ops sh7786_module_clk_ops = {
-	.recalc		= module_clk_recalc,
-};
+	/*
+	 * Clock modes 0, 1, and 2 use an x64 multiplier against PLL1,
+	 * while modes 3, 4, and 5 use an x32.
+	 */
+	multiplier = (sh_mv.mv_mode_pins() & 0xf) < 3 ? 64 : 32;
 
-static unsigned long bus_clk_recalc(struct clk *clk)
-{
-	int idx = ((ctrl_inl(FRQMR1) >> 16) & 0x000f);
-	return clk->parent->rate / bfc_divisors[idx];
+	return clk->parent->rate * multiplier;
 }
 
-static struct clk_ops sh7786_bus_clk_ops = {
-	.recalc		= bus_clk_recalc,
+static struct clk_ops pll_clk_ops = {
+	.recalc		= pll_recalc,
 };
 
-static unsigned long cpu_clk_recalc(struct clk *clk)
-{
-	int idx = ((ctrl_inl(FRQMR1) >> 28) & 0x0003);
-	return clk->parent->rate / ifc_divisors[idx];
-}
-
-static struct clk_ops sh7786_cpu_clk_ops = {
-	.recalc		= cpu_clk_recalc,
+static struct clk pll_clk = {
+	.name		= "pll_clk",
+	.id		= -1,
+	.ops		= &pll_clk_ops,
+	.parent		= &extal_clk,
+	.flags		= CLK_ENABLE_ON_INIT,
 };
 
-static struct clk_ops *sh7786_clk_ops[] = {
-	&sh7786_master_clk_ops,
-	&sh7786_module_clk_ops,
-	&sh7786_bus_clk_ops,
-	&sh7786_cpu_clk_ops,
+static struct clk *clks[] = {
+	&extal_clk,
+	&pll_clk,
 };
 
-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 unsigned long shyway_clk_recalc(struct clk *clk)
-{
-	int idx = ((ctrl_inl(FRQMR1) >> 20) & 0x0003);
-	return clk->parent->rate / sfc_divisors[idx];
-}
+static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18,
+			       24, 32, 36, 48 };
 
-static struct clk_ops sh7786_shyway_clk_ops = {
-	.recalc		= shyway_clk_recalc,
+static struct clk_div_mult_table div4_div_mult_table = {
+	.divisors = div2,
+	.nr_divisors = ARRAY_SIZE(div2),
 };
 
-static struct clk sh7786_shyway_clk = {
-	.name		= "shyway_clk",
-	.flags		= CLK_ENABLE_ON_INIT,
-	.ops		= &sh7786_shyway_clk_ops,
+static struct clk_div4_table div4_table = {
+	.div_mult_table = &div4_div_mult_table,
 };
 
-static unsigned long ddr_clk_recalc(struct clk *clk)
-{
-	int idx = ((ctrl_inl(FRQMR1) >> 12) & 0x0003);
-	return clk->parent->rate / mfc_divisors[idx];
-}
+enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_DU, DIV4_P, DIV4_NR };
 
-static struct clk_ops sh7786_ddr_clk_ops = {
-	.recalc		= ddr_clk_recalc,
-};
+#define DIV4(_str, _bit, _mask, _flags) \
+  SH_CLK_DIV4(_str, &pll_clk, FRQMR1, _bit, _mask, _flags)
 
-static struct clk sh7786_ddr_clk = {
-	.name		= "ddr_clk",
-	.flags		= CLK_ENABLE_ON_INIT,
-	.ops		= &sh7786_ddr_clk_ops,
+struct clk div4_clks[DIV4_NR] = {
+	[DIV4_P] = DIV4("peripheral_clk", 0, 0x0b40, 0),
+	[DIV4_DU] = DIV4("du_clk", 4, 0x0010, 0),
+	[DIV4_DDR] = DIV4("ddr_clk", 12, 0x0002, CLK_ENABLE_ON_INIT),
+	[DIV4_B] = DIV4("bus_clk", 16, 0x0360, CLK_ENABLE_ON_INIT),
+	[DIV4_SH] = DIV4("shyway_clk", 20, 0x0002, CLK_ENABLE_ON_INIT),
+	[DIV4_I] = DIV4("cpu_clk", 28, 0x0006, CLK_ENABLE_ON_INIT),
 };
 
-/*
- * 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,
+#define MSTPCR0		0xffc40030
+#define MSTPCR1		0xffc40034
+
+static struct clk mstp_clks[] = {
+	/* MSTPCR0 */
+	SH_CLK_MSTP32("scif_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0),
+	SH_CLK_MSTP32("scif_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0),
+	SH_CLK_MSTP32("scif_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0),
+	SH_CLK_MSTP32("scif_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0),
+	SH_CLK_MSTP32("scif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0),
+	SH_CLK_MSTP32("scif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0),
+	SH_CLK_MSTP32("ssi_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 23, 0),
+	SH_CLK_MSTP32("ssi_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 22, 0),
+	SH_CLK_MSTP32("ssi_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 21, 0),
+	SH_CLK_MSTP32("ssi_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 20, 0),
+	SH_CLK_MSTP32("hac_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 17, 0),
+	SH_CLK_MSTP32("hac_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 16, 0),
+	SH_CLK_MSTP32("i2c_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 15, 0),
+	SH_CLK_MSTP32("i2c_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 14, 0),
+	SH_CLK_MSTP32("tmu9_11_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 11, 0),
+	SH_CLK_MSTP32("tmu678_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 10, 0),
+	SH_CLK_MSTP32("tmu345_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 9, 0),
+	SH_CLK_MSTP32("tmu012_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 8, 0),
+	SH_CLK_MSTP32("sdif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 5, 0),
+	SH_CLK_MSTP32("sdif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 4, 0),
+	SH_CLK_MSTP32("hspi_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 2, 0),
+
+	/* MSTPCR1 */
+	SH_CLK_MSTP32("usb_fck", -1, NULL, MSTPCR1, 12, 0),
+	SH_CLK_MSTP32("pcie_fck", 2, NULL, MSTPCR1, 10, 0),
+	SH_CLK_MSTP32("pcie_fck", 1, NULL, MSTPCR1, 9, 0),
+	SH_CLK_MSTP32("pcie_fck", 0, NULL, MSTPCR1, 8, 0),
+	SH_CLK_MSTP32("dmac_11_6_fck", -1, NULL, MSTPCR1, 5, 0),
+	SH_CLK_MSTP32("dmac_5_0_fck", -1, NULL, MSTPCR1, 4, 0),
+	SH_CLK_MSTP32("du_fck", -1, NULL, MSTPCR1, 3, 0),
+	SH_CLK_MSTP32("ether_fck", -1, NULL, MSTPCR1, 2, 0),
 };
 
 int __init arch_clk_init(void)
 {
-	struct clk *clk;
 	int i, ret = 0;
 
-	cpg_clk_init();
-
-	clk = clk_get(NULL, "master_clk");
-	for (i = 0; i < ARRAY_SIZE(sh7786_onchip_clocks); i++) {
-		struct clk *clkp = sh7786_onchip_clocks[i];
-
-		clkp->parent = clk;
-		ret |= clk_register(clkp);
-	}
+	for (i = 0; i < ARRAY_SIZE(clks); i++)
+		ret |= clk_register(clks[i]);
 
-	clk_put(clk);
+	if (!ret)
+		ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
+					   &div4_table);
+	if (!ret)
+		ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
 
 	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-shx3.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-shx3.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-shx3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/clock-shx3.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,7 @@ static int cfc_divisors[] = { 1, 1, 4, 6
 
 static void master_clk_init(struct clk *clk)
 {
-	clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK];
+	clk->rate *= pfc_divisors[(__raw_readl(FRQCR) >> PFC_POS) & PFC_MSK];
 }
 
 static struct clk_ops shx3_master_clk_ops = {
@@ -42,7 +42,7 @@ static struct clk_ops shx3_master_clk_op
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int idx = ((ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK);
+	int idx = ((__raw_readl(FRQCR) >> PFC_POS) & PFC_MSK);
 	return clk->parent->rate / pfc_divisors[idx];
 }
 
@@ -52,7 +52,7 @@ static struct clk_ops shx3_module_clk_op
 
 static unsigned long bus_clk_recalc(struct clk *clk)
 {
-	int idx = ((ctrl_inl(FRQCR) >> BFC_POS) & BFC_MSK);
+	int idx = ((__raw_readl(FRQCR) >> BFC_POS) & BFC_MSK);
 	return clk->parent->rate / bfc_divisors[idx];
 }
 
@@ -62,7 +62,7 @@ static struct clk_ops shx3_bus_clk_ops =
 
 static unsigned long cpu_clk_recalc(struct clk *clk)
 {
-	int idx = ((ctrl_inl(FRQCR) >> IFC_POS) & IFC_MSK);
+	int idx = ((__raw_readl(FRQCR) >> IFC_POS) & IFC_MSK);
 	return clk->parent->rate / ifc_divisors[idx];
 }
 
@@ -85,7 +85,7 @@ void __init arch_init_clk_ops(struct clk
 
 static unsigned long shyway_clk_recalc(struct clk *clk)
 {
-	int idx = ((ctrl_inl(FRQCR) >> CFC_POS) & CFC_MSK);
+	int idx = ((__raw_readl(FRQCR) >> CFC_POS) & CFC_MSK);
 	return clk->parent->rate / cfc_divisors[idx];
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/Makefile linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/Makefile
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,8 @@ pinmux-$(CONFIG_CPU_SUBTYPE_SH7757)	:= p
 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)
-obj-$(CONFIG_GENERIC_GPIO)	+= $(pinmux-y)
-obj-$(CONFIG_PERF_EVENTS)	+= perf_event.o
+obj-y					+= $(clock-y)
+obj-$(CONFIG_SMP)			+= $(smp-y)
+obj-$(CONFIG_GENERIC_GPIO)		+= $(pinmux-y)
+obj-$(CONFIG_PERF_EVENTS)		+= perf_event.o
+obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= ubc.o
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c	2010-05-16 17:17:36.000000000 -0400
@@ -278,6 +278,7 @@ enum {
 	HIZA8_LCDC, HIZA8_HIZ,
 	HIZA7_LCDC, HIZA7_HIZ,
 	HIZA6_LCDC, HIZA6_HIZ,
+	HIZB4_SIUA, HIZB4_HIZ,
 	HIZB1_VIO, HIZB1_HIZ,
 	HIZB0_VIO, HIZB0_HIZ,
 	HIZC15_IRQ7, HIZC15_HIZ,
@@ -546,7 +547,7 @@ static pinmux_enum_t pinmux_data[] = {
 	PINMUX_DATA(VIO_VD2_MARK, PSE3_VIO, MSELB9_VIO2,
 		    HIZB0_VIO, FOE_VIO_VD2),
 	PINMUX_DATA(VIO_HD2_MARK, PSE3_VIO, MSELB9_VIO2,
-		    HIZB1_VIO, HIZB1_VIO, FCE_VIO_HD2),
+		    HIZB1_VIO, FCE_VIO_HD2),
 	PINMUX_DATA(VIO_CLK2_MARK, PSE3_VIO, MSELB9_VIO2,
 		    HIZB1_VIO, FRB_VIO_CLK2),
 
@@ -658,14 +659,14 @@ static pinmux_enum_t pinmux_data[] = {
 	PINMUX_DATA(SDHICLK_MARK, SDHICLK),
 
 	/* SIU - Port A */
-	PINMUX_DATA(SIUAOLR_MARK, PSC13_SIUAOLR, SIUAOLR_SIOF1_SYNC),
-	PINMUX_DATA(SIUAOBT_MARK, PSC14_SIUAOBT, SIUAOBT_SIOF1_SCK),
-	PINMUX_DATA(SIUAISLD_MARK, PSC15_SIUAISLD, SIUAISLD_SIOF1_RXD),
-	PINMUX_DATA(SIUAILR_MARK, PSC11_SIUAILR, SIUAILR_SIOF1_SS2),
-	PINMUX_DATA(SIUAIBT_MARK, PSC12_SIUAIBT, SIUAIBT_SIOF1_SS1),
-	PINMUX_DATA(SIUAOSLD_MARK, PSB0_SIUAOSLD, SIUAOSLD_SIOF1_TXD),
-	PINMUX_DATA(SIUMCKA_MARK, PSE11_SIUMCKA_SIOF1_MCK, PSB1_SIUMCKA, PTK0),
-	PINMUX_DATA(SIUFCKA_MARK, PSE11_SIUFCKA, PTK0),
+	PINMUX_DATA(SIUAOLR_MARK, PSC13_SIUAOLR, HIZB4_SIUA, SIUAOLR_SIOF1_SYNC),
+	PINMUX_DATA(SIUAOBT_MARK, PSC14_SIUAOBT, HIZB4_SIUA, SIUAOBT_SIOF1_SCK),
+	PINMUX_DATA(SIUAISLD_MARK, PSC15_SIUAISLD, HIZB4_SIUA, SIUAISLD_SIOF1_RXD),
+	PINMUX_DATA(SIUAILR_MARK, PSC11_SIUAILR, HIZB4_SIUA, SIUAILR_SIOF1_SS2),
+	PINMUX_DATA(SIUAIBT_MARK, PSC12_SIUAIBT, HIZB4_SIUA, SIUAIBT_SIOF1_SS1),
+	PINMUX_DATA(SIUAOSLD_MARK, PSB0_SIUAOSLD, HIZB4_SIUA, SIUAOSLD_SIOF1_TXD),
+	PINMUX_DATA(SIUMCKA_MARK, PSE11_SIUMCKA_SIOF1_MCK, HIZB4_SIUA, PSB1_SIUMCKA, PTK0),
+	PINMUX_DATA(SIUFCKA_MARK, PSE11_SIUFCKA, HIZB4_SIUA, PTK0),
 
 	/* SIU - Port B */
 	PINMUX_DATA(SIUBOLR_MARK, PSB11_SIUBOLR, SIOSTRB1_SIUBOLR),
@@ -1612,7 +1613,7 @@ static struct pinmux_cfg_reg pinmux_conf
 		0, 0,
 		0, 0,
 		0, 0,
-		0, 0,
+		HIZB4_SIUA, HIZB4_HIZ,
 		0, 0,
 		0, 0,
 		HIZB1_VIO, HIZB1_HIZ,
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7722.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7722.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7722.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,19 +7,167 @@
  * 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/mm.h>
+#include <linux/platform_device.h>
 #include <linux/serial.h>
 #include <linux/serial_sci.h>
-#include <linux/mm.h>
+#include <linux/sh_timer.h>
 #include <linux/uio_driver.h>
 #include <linux/usb/m66592.h>
-#include <linux/sh_timer.h>
+
 #include <asm/clock.h>
+#include <asm/dmaengine.h>
 #include <asm/mmzone.h>
-#include <asm/dma-sh.h>
+#include <asm/siu.h>
+
+#include <cpu/dma-register.h>
 #include <cpu/sh7722.h>
 
+static struct sh_dmae_slave_config sh7722_dmae_slaves[] = {
+	{
+		.slave_id	= SHDMA_SLAVE_SCIF0_TX,
+		.addr		= 0xffe0000c,
+		.chcr		= DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+		.mid_rid	= 0x21,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF0_RX,
+		.addr		= 0xffe00014,
+		.chcr		= DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+		.mid_rid	= 0x22,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF1_TX,
+		.addr		= 0xffe1000c,
+		.chcr		= DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+		.mid_rid	= 0x25,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF1_RX,
+		.addr		= 0xffe10014,
+		.chcr		= DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+		.mid_rid	= 0x26,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF2_TX,
+		.addr		= 0xffe2000c,
+		.chcr		= DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+		.mid_rid	= 0x29,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF2_RX,
+		.addr		= 0xffe20014,
+		.chcr		= DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+		.mid_rid	= 0x2a,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SIUA_TX,
+		.addr		= 0xa454c098,
+		.chcr		= DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+		.mid_rid	= 0xb1,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SIUA_RX,
+		.addr		= 0xa454c090,
+		.chcr		= DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+		.mid_rid	= 0xb2,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SIUB_TX,
+		.addr		= 0xa454c09c,
+		.chcr		= DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+		.mid_rid	= 0xb5,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SIUB_RX,
+		.addr		= 0xa454c094,
+		.chcr		= DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+		.mid_rid	= 0xb6,
+	},
+};
+
+static struct sh_dmae_channel sh7722_dmae_channels[] = {
+	{
+		.offset = 0,
+		.dmars = 0,
+		.dmars_bit = 0,
+	}, {
+		.offset = 0x10,
+		.dmars = 0,
+		.dmars_bit = 8,
+	}, {
+		.offset = 0x20,
+		.dmars = 4,
+		.dmars_bit = 0,
+	}, {
+		.offset = 0x30,
+		.dmars = 4,
+		.dmars_bit = 8,
+	}, {
+		.offset = 0x50,
+		.dmars = 8,
+		.dmars_bit = 0,
+	}, {
+		.offset = 0x60,
+		.dmars = 8,
+		.dmars_bit = 8,
+	}
+};
+
+static unsigned int ts_shift[] = TS_SHIFT;
+
+static struct sh_dmae_pdata dma_platform_data = {
+	.slave		= sh7722_dmae_slaves,
+	.slave_num	= ARRAY_SIZE(sh7722_dmae_slaves),
+	.channel	= sh7722_dmae_channels,
+	.channel_num	= ARRAY_SIZE(sh7722_dmae_channels),
+	.ts_low_shift	= CHCR_TS_LOW_SHIFT,
+	.ts_low_mask	= CHCR_TS_LOW_MASK,
+	.ts_high_shift	= CHCR_TS_HIGH_SHIFT,
+	.ts_high_mask	= CHCR_TS_HIGH_MASK,
+	.ts_shift	= ts_shift,
+	.ts_shift_num	= ARRAY_SIZE(ts_shift),
+	.dmaor_init	= DMAOR_INIT,
+};
+
+static struct resource sh7722_dmae_resources[] = {
+	[0] = {
+		/* Channel registers and DMAOR */
+		.start	= 0xfe008020,
+		.end	= 0xfe00808f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		/* DMARSx */
+		.start	= 0xfe009000,
+		.end	= 0xfe00900b,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		/* DMA error IRQ */
+		.start	= 78,
+		.end	= 78,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		/* IRQ for channels 0-3 */
+		.start	= 48,
+		.end	= 51,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		/* IRQ for channels 4-5 */
+		.start	= 76,
+		.end	= 77,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device dma_device = {
+	.name		= "sh-dma-engine",
+	.id		= -1,
+	.resource	= sh7722_dmae_resources,
+	.num_resources	= ARRAY_SIZE(sh7722_dmae_resources),
+	.dev		= {
+		.platform_data	= &dma_platform_data,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_DMAC,
+	},
+};
+
 /* Serial */
 static struct plat_sci_port scif0_platform_data = {
 	.mapbase        = 0xffe00000,
@@ -388,15 +536,36 @@ static struct platform_device tmu2_devic
 	},
 };
 
-static struct sh_dmae_pdata dma_platform_data = {
-	.mode = 0,
+static struct siu_platform siu_platform_data = {
+	.dma_dev	= &dma_device.dev,
+	.dma_slave_tx_a	= SHDMA_SLAVE_SIUA_TX,
+	.dma_slave_rx_a	= SHDMA_SLAVE_SIUA_RX,
+	.dma_slave_tx_b	= SHDMA_SLAVE_SIUB_TX,
+	.dma_slave_rx_b	= SHDMA_SLAVE_SIUB_RX,
 };
 
-static struct platform_device dma_device = {
-	.name		= "sh-dma-engine",
+static struct resource siu_resources[] = {
+	[0] = {
+		.start	= 0xa4540000,
+		.end	= 0xa454c10f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 108,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device siu_device = {
+	.name		= "sh_siu",
 	.id		= -1,
-	.dev		= {
-		.platform_data	= &dma_platform_data,
+	.dev = {
+		.platform_data	= &siu_platform_data,
+	},
+	.resource	= siu_resources,
+	.num_resources	= ARRAY_SIZE(siu_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_SIU,
 	},
 };
 
@@ -414,6 +583,7 @@ static struct platform_device *sh7722_de
 	&vpu_device,
 	&veu_device,
 	&jpu_device,
+	&siu_device,
 	&dma_device,
 };
 
@@ -446,6 +616,8 @@ void __init plat_early_device_setup(void
 
 enum {
 	UNUSED=0,
+	ENABLED,
+	DISABLED,
 
 	/* interrupt sources */
 	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
@@ -461,7 +633,6 @@ enum {
 	SCIF0, SCIF1, SCIF2, SIOF0, SIOF1, SIO,
 	FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
 	I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI,
-	SDHI0, SDHI1, SDHI2, SDHI3,
 	CMT, TSIF, SIU, TWODG,
 	TMU0, TMU1, TMU2,
 	IRDA, JPU, LCDC,
@@ -494,8 +665,8 @@ static struct intc_vect vectors[] __init
 	INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0),
 	INTC_VECT(I2C_ALI, 0xe00), INTC_VECT(I2C_TACKI, 0xe20),
 	INTC_VECT(I2C_WAITI, 0xe40), INTC_VECT(I2C_DTEI, 0xe60),
-	INTC_VECT(SDHI0, 0xe80), INTC_VECT(SDHI1, 0xea0),
-	INTC_VECT(SDHI2, 0xec0), INTC_VECT(SDHI3, 0xee0),
+	INTC_VECT(SDHI, 0xe80), INTC_VECT(SDHI, 0xea0),
+	INTC_VECT(SDHI, 0xec0), INTC_VECT(SDHI, 0xee0),
 	INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20),
 	INTC_VECT(SIU, 0xf80), INTC_VECT(TWODG, 0xfa0),
 	INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
@@ -513,7 +684,6 @@ static struct intc_group groups[] __init
 	INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLENDI,
 		   FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
 	INTC_GROUP(I2C, I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI),
-	INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3),
 };
 
 static struct intc_mask_reg mask_registers[] __initdata = {
@@ -535,7 +705,7 @@ static struct intc_mask_reg mask_registe
 	  { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI,
 	    FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } },
 	{ 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */
-	  { SDHI3, SDHI2, SDHI1, SDHI0, 0, 0, TWODG, SIU } },
+	  { DISABLED, DISABLED, ENABLED, ENABLED, 0, 0, TWODG, SIU } },
 	{ 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */
 	  { 0, 0, 0, CMT, 0, USB_USBI1, USB_USBI0, } },
 	{ 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */
@@ -573,9 +743,13 @@ static struct intc_mask_reg ack_register
 	  { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
 };
 
-static DECLARE_INTC_DESC_ACK(intc_desc, "sh7722", vectors, groups,
-			     mask_registers, prio_registers, sense_registers,
-			     ack_registers);
+static struct intc_desc intc_desc __initdata = {
+	.name = "sh7722",
+	.force_enable = ENABLED,
+	.force_disable = DISABLED,
+	.hw = INTC_HW_DESC(vectors, groups, mask_registers,
+			   prio_registers, sense_registers, ack_registers),
+};
 
 void __init plat_irq_setup(void)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7723.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7723.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7723.c	2010-05-16 17:17:36.000000000 -0400
@@ -592,14 +592,17 @@ void __init plat_early_device_setup(void
 #define RAMCR_CACHE_L2FC	0x0002
 #define RAMCR_CACHE_L2E		0x0001
 #define L2_CACHE_ENABLE		(RAMCR_CACHE_L2E|RAMCR_CACHE_L2FC)
-void __uses_jump_to_uncached l2_cache_init(void)
+
+void l2_cache_init(void)
 {
 	/* Enable L2 cache */
-	ctrl_outl(L2_CACHE_ENABLE, RAMCR);
+	__raw_writel(L2_CACHE_ENABLE, RAMCR);
 }
 
 enum {
 	UNUSED=0,
+	ENABLED,
+	DISABLED,
 
 	/* interrupt sources */
 	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
@@ -622,7 +625,6 @@ enum {
 	SCIFA_SCIFA1,
 	FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I,
 	I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI,
-	SDHI0_SDHII0,SDHI0_SDHII1,SDHI0_SDHII2,
 	CMT_CMTI,
 	TSIF_TSIFI,
 	SIU_SIUI,
@@ -630,7 +632,6 @@ enum {
 	TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2,
 	IRDA_IRDAI,
 	ATAPI_ATAPII,
-	SDHI1_SDHII0,SDHI1_SDHII1,SDHI1_SDHII2,
 	VEU2H1_VEU2HI,
 	LCDC_LCDCI,
 	TMU1_TUNI0,TMU1_TUNI1,TMU1_TUNI2,
@@ -701,9 +702,9 @@ static struct intc_vect vectors[] __init
 	INTC_VECT(I2C_WAITI,0xE40),
 	INTC_VECT(I2C_DTEI,0xE60),
 
-	INTC_VECT(SDHI0_SDHII0,0xE80),
-	INTC_VECT(SDHI0_SDHII1,0xEA0),
-	INTC_VECT(SDHI0_SDHII2,0xEC0),
+	INTC_VECT(SDHI0, 0xE80),
+	INTC_VECT(SDHI0, 0xEA0),
+	INTC_VECT(SDHI0, 0xEC0),
 
 	INTC_VECT(CMT_CMTI,0xF00),
 	INTC_VECT(TSIF_TSIFI,0xF20),
@@ -717,9 +718,9 @@ static struct intc_vect vectors[] __init
 	INTC_VECT(IRDA_IRDAI,0x480),
 	INTC_VECT(ATAPI_ATAPII,0x4A0),
 
-	INTC_VECT(SDHI1_SDHII0,0x4E0),
-	INTC_VECT(SDHI1_SDHII1,0x500),
-	INTC_VECT(SDHI1_SDHII2,0x520),
+	INTC_VECT(SDHI1, 0x4E0),
+	INTC_VECT(SDHI1, 0x500),
+	INTC_VECT(SDHI1, 0x520),
 
 	INTC_VECT(VEU2H1_VEU2HI,0x560),
 	INTC_VECT(LCDC_LCDCI,0x580),
@@ -738,15 +739,14 @@ static struct intc_group groups[] __init
 	INTC_GROUP(FLCTL,FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I),
 	INTC_GROUP(I2C,I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI),
 	INTC_GROUP(_2DG, _2DG_TRI,_2DG_INI,_2DG_CEI),
-	INTC_GROUP(SDHI1, SDHI1_SDHII0,SDHI1_SDHII1,SDHI1_SDHII2),
 	INTC_GROUP(RTC, RTC_ATI,RTC_PRI,RTC_CUI),
 	INTC_GROUP(DMAC1B, DMAC1B_DEI4,DMAC1B_DEI5,DMAC1B_DADERR),
-	INTC_GROUP(SDHI0,SDHI0_SDHII0,SDHI0_SDHII1,SDHI0_SDHII2),
 };
 
 static struct intc_mask_reg mask_registers[] __initdata = {
 	{ 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */
-	  { 0,  TMU1_TUNI2,TMU1_TUNI1,TMU1_TUNI0,0,SDHI1_SDHII2,SDHI1_SDHII1,SDHI1_SDHII0} },
+	  { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0,
+	    0, DISABLED, ENABLED, ENABLED } },
 	{ 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */
 	  { VIO_VOUI, VIO_VEU2HI,VIO_BEUI,VIO_CEUI,DMAC0A_DEI3,DMAC0A_DEI2,DMAC0A_DEI1,DMAC0A_DEI0 } },
 	{ 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */
@@ -763,7 +763,8 @@ static struct intc_mask_reg mask_registe
 	  { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI,
 	    FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
 	{ 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */
-	  { 0,SDHI0_SDHII2,SDHI0_SDHII1,SDHI0_SDHII0,0,0,SCIFA_SCIFA2,SIU_SIUI } },
+	  { 0, DISABLED, ENABLED, ENABLED,
+	    0, 0, SCIFA_SCIFA2, SIU_SIUI } },
 	{ 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */
 	  { 0, 0, 0, CMT_CMTI, 0, 0, USB_USI0,0 } },
 	{ 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */
@@ -803,9 +804,13 @@ static struct intc_mask_reg ack_register
 	  { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
 };
 
-static DECLARE_INTC_DESC_ACK(intc_desc, "sh7723", vectors, groups,
-			     mask_registers, prio_registers, sense_registers,
-			     ack_registers);
+static struct intc_desc intc_desc __initdata = {
+	.name = "sh7723",
+	.force_enable = ENABLED,
+	.force_disable = DISABLED,
+	.hw = INTC_HW_DESC(vectors, groups, mask_registers,
+			   prio_registers, sense_registers, ack_registers),
+};
 
 void __init plat_irq_setup(void)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7724.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7724.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7724.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,22 +21,189 @@
 #include <linux/sh_timer.h>
 #include <linux/io.h>
 #include <linux/notifier.h>
+
 #include <asm/suspend.h>
 #include <asm/clock.h>
-#include <asm/dma-sh.h>
+#include <asm/dmaengine.h>
 #include <asm/mmzone.h>
+
+#include <cpu/dma-register.h>
 #include <cpu/sh7724.h>
 
 /* DMA */
-static struct sh_dmae_pdata dma_platform_data = {
-	.mode = SHDMA_DMAOR1,
+static struct sh_dmae_channel sh7724_dmae0_channels[] = {
+	{
+		.offset = 0,
+		.dmars = 0,
+		.dmars_bit = 0,
+	}, {
+		.offset = 0x10,
+		.dmars = 0,
+		.dmars_bit = 8,
+	}, {
+		.offset = 0x20,
+		.dmars = 4,
+		.dmars_bit = 0,
+	}, {
+		.offset = 0x30,
+		.dmars = 4,
+		.dmars_bit = 8,
+	}, {
+		.offset = 0x50,
+		.dmars = 8,
+		.dmars_bit = 0,
+	}, {
+		.offset = 0x60,
+		.dmars = 8,
+		.dmars_bit = 8,
+	}
 };
 
-static struct platform_device dma_device = {
-	.name	= "sh-dma-engine",
-	.id		= -1,
-	.dev	= {
-		.platform_data	= &dma_platform_data,
+static struct sh_dmae_channel sh7724_dmae1_channels[] = {
+	{
+		.offset = 0,
+		.dmars = 0,
+		.dmars_bit = 0,
+	}, {
+		.offset = 0x10,
+		.dmars = 0,
+		.dmars_bit = 8,
+	}, {
+		.offset = 0x20,
+		.dmars = 4,
+		.dmars_bit = 0,
+	}, {
+		.offset = 0x30,
+		.dmars = 4,
+		.dmars_bit = 8,
+	}, {
+		.offset = 0x50,
+		.dmars = 8,
+		.dmars_bit = 0,
+	}, {
+		.offset = 0x60,
+		.dmars = 8,
+		.dmars_bit = 8,
+	}
+};
+
+static unsigned int ts_shift[] = TS_SHIFT;
+
+static struct sh_dmae_pdata dma0_platform_data = {
+	.channel	= sh7724_dmae0_channels,
+	.channel_num	= ARRAY_SIZE(sh7724_dmae0_channels),
+	.ts_low_shift	= CHCR_TS_LOW_SHIFT,
+	.ts_low_mask	= CHCR_TS_LOW_MASK,
+	.ts_high_shift	= CHCR_TS_HIGH_SHIFT,
+	.ts_high_mask	= CHCR_TS_HIGH_MASK,
+	.ts_shift	= ts_shift,
+	.ts_shift_num	= ARRAY_SIZE(ts_shift),
+	.dmaor_init	= DMAOR_INIT,
+};
+
+static struct sh_dmae_pdata dma1_platform_data = {
+	.channel	= sh7724_dmae1_channels,
+	.channel_num	= ARRAY_SIZE(sh7724_dmae1_channels),
+	.ts_low_shift	= CHCR_TS_LOW_SHIFT,
+	.ts_low_mask	= CHCR_TS_LOW_MASK,
+	.ts_high_shift	= CHCR_TS_HIGH_SHIFT,
+	.ts_high_mask	= CHCR_TS_HIGH_MASK,
+	.ts_shift	= ts_shift,
+	.ts_shift_num	= ARRAY_SIZE(ts_shift),
+	.dmaor_init	= DMAOR_INIT,
+};
+
+/* Resource order important! */
+static struct resource sh7724_dmae0_resources[] = {
+	{
+		/* Channel registers and DMAOR */
+		.start	= 0xfe008020,
+		.end	= 0xfe00808f,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		/* DMARSx */
+		.start	= 0xfe009000,
+		.end	= 0xfe00900b,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		/* DMA error IRQ */
+		.start	= 78,
+		.end	= 78,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		/* IRQ for channels 0-3 */
+		.start	= 48,
+		.end	= 51,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		/* IRQ for channels 4-5 */
+		.start	= 76,
+		.end	= 77,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+/* Resource order important! */
+static struct resource sh7724_dmae1_resources[] = {
+	{
+		/* Channel registers and DMAOR */
+		.start	= 0xfdc08020,
+		.end	= 0xfdc0808f,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		/* DMARSx */
+		.start	= 0xfdc09000,
+		.end	= 0xfdc0900b,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		/* DMA error IRQ */
+		.start	= 74,
+		.end	= 74,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		/* IRQ for channels 0-3 */
+		.start	= 40,
+		.end	= 43,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		/* IRQ for channels 4-5 */
+		.start	= 72,
+		.end	= 73,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dma0_device = {
+	.name		= "sh-dma-engine",
+	.id		= 0,
+	.resource	= sh7724_dmae0_resources,
+	.num_resources	= ARRAY_SIZE(sh7724_dmae0_resources),
+	.dev		= {
+		.platform_data	= &dma0_platform_data,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_DMAC0,
+	},
+};
+
+static struct platform_device dma1_device = {
+	.name		= "sh-dma-engine",
+	.id		= 1,
+	.resource	= sh7724_dmae1_resources,
+	.num_resources	= ARRAY_SIZE(sh7724_dmae1_resources),
+	.dev		= {
+		.platform_data	= &dma1_platform_data,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_DMAC1,
 	},
 };
 
@@ -663,7 +830,8 @@ static struct platform_device *sh7724_de
 	&tmu3_device,
 	&tmu4_device,
 	&tmu5_device,
-	&dma_device,
+	&dma0_device,
+	&dma1_device,
 	&rtc_device,
 	&iic0_device,
 	&iic1_device,
@@ -714,14 +882,17 @@ void __init plat_early_device_setup(void
 #define RAMCR_CACHE_L2FC	0x0002
 #define RAMCR_CACHE_L2E		0x0001
 #define L2_CACHE_ENABLE		(RAMCR_CACHE_L2E|RAMCR_CACHE_L2FC)
-void __uses_jump_to_uncached l2_cache_init(void)
+
+void l2_cache_init(void)
 {
 	/* Enable L2 cache */
-	ctrl_outl(L2_CACHE_ENABLE, RAMCR);
+	__raw_writel(L2_CACHE_ENABLE, RAMCR);
 }
 
 enum {
 	UNUSED = 0,
+	ENABLED,
+	DISABLED,
 
 	/* interrupt sources */
 	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
@@ -750,14 +921,12 @@ enum {
 	ETHI,
 	I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI,
 	I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI,
-	SDHI0_SDHII0, SDHI0_SDHII1, SDHI0_SDHII2, SDHI0_SDHII3,
 	CMT,
 	TSIF,
 	FSI,
 	SCIFA5,
 	TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2,
 	IRDA,
-	SDHI1_SDHII0, SDHI1_SDHII1, SDHI1_SDHII2,
 	JPU,
 	_2DDMAC,
 	MMC_MMC2I, MMC_MMC3I,
@@ -839,10 +1008,10 @@ static struct intc_vect vectors[] __init
 	INTC_VECT(I2C0_WAITI, 0xE40),
 	INTC_VECT(I2C0_DTEI, 0xE60),
 
-	INTC_VECT(SDHI0_SDHII0, 0xE80),
-	INTC_VECT(SDHI0_SDHII1, 0xEA0),
-	INTC_VECT(SDHI0_SDHII2, 0xEC0),
-	INTC_VECT(SDHI0_SDHII3, 0xEE0),
+	INTC_VECT(SDHI0, 0xE80),
+	INTC_VECT(SDHI0, 0xEA0),
+	INTC_VECT(SDHI0, 0xEC0),
+	INTC_VECT(SDHI0, 0xEE0),
 
 	INTC_VECT(CMT,    0xF00),
 	INTC_VECT(TSIF,   0xF20),
@@ -855,9 +1024,9 @@ static struct intc_vect vectors[] __init
 
 	INTC_VECT(IRDA,    0x480),
 
-	INTC_VECT(SDHI1_SDHII0, 0x4E0),
-	INTC_VECT(SDHI1_SDHII1, 0x500),
-	INTC_VECT(SDHI1_SDHII2, 0x520),
+	INTC_VECT(SDHI1, 0x4E0),
+	INTC_VECT(SDHI1, 0x500),
+	INTC_VECT(SDHI1, 0x520),
 
 	INTC_VECT(JPU, 0x560),
 	INTC_VECT(_2DDMAC, 0x4A0),
@@ -883,8 +1052,6 @@ static struct intc_group groups[] __init
 	INTC_GROUP(DMAC0B, DMAC0B_DEI4, DMAC0B_DEI5, DMAC0B_DADERR),
 	INTC_GROUP(I2C0, I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI),
 	INTC_GROUP(I2C1, I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI),
-	INTC_GROUP(SDHI0, SDHI0_SDHII0, SDHI0_SDHII1, SDHI0_SDHII2, SDHI0_SDHII3),
-	INTC_GROUP(SDHI1, SDHI1_SDHII0, SDHI1_SDHII1, SDHI1_SDHII2),
 	INTC_GROUP(SPU, SPU_SPUI0, SPU_SPUI1),
 	INTC_GROUP(MMCIF, MMC_MMC2I, MMC_MMC3I),
 };
@@ -892,7 +1059,7 @@ static struct intc_group groups[] __init
 static struct intc_mask_reg mask_registers[] __initdata = {
 	{ 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */
 	  { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0,
-	    0, SDHI1_SDHII2, SDHI1_SDHII1, SDHI1_SDHII0 } },
+	    0, DISABLED, ENABLED, ENABLED } },
 	{ 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */
 	  { VIO_VOU, VIO_VEU1, VIO_BEU0, VIO_CEU0,
 	    DMAC0A_DEI3, DMAC0A_DEI2, DMAC0A_DEI1, DMAC0A_DEI0 } },
@@ -914,7 +1081,7 @@ static struct intc_mask_reg mask_registe
 	  { I2C0_DTEI, I2C0_WAITI, I2C0_TACKI, I2C0_ALI,
 	    I2C1_DTEI, I2C1_WAITI, I2C1_TACKI, I2C1_ALI } },
 	{ 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */
-	  { SDHI0_SDHII3, SDHI0_SDHII2, SDHI0_SDHII1, SDHI0_SDHII0,
+	  { DISABLED, DISABLED, ENABLED, ENABLED,
 	    0, 0, SCIFA5, FSI } },
 	{ 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */
 	  { 0, 0, 0, CMT, 0, USB1, USB0, 0 } },
@@ -961,9 +1128,13 @@ static struct intc_mask_reg ack_register
 	  { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
 };
 
-static DECLARE_INTC_DESC_ACK(intc_desc, "sh7724", vectors, groups,
-			     mask_registers, prio_registers, sense_registers,
-			     ack_registers);
+static struct intc_desc intc_desc __initdata = {
+	.name = "sh7724",
+	.force_enable = ENABLED,
+	.force_disable = DISABLED,
+	.hw = INTC_HW_DESC(vectors, groups, mask_registers,
+			   prio_registers, sense_registers, ack_registers),
+};
 
 void __init plat_irq_setup(void)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7757.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7757.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7757.c	2010-05-16 17:17:36.000000000 -0400
@@ -487,17 +487,17 @@ static DECLARE_INTC_DESC(intc_desc_irl45
 void __init plat_irq_setup(void)
 {
 	/* disable IRQ3-0 + IRQ7-4 */
-	ctrl_outl(0xff000000, INTC_INTMSK0);
+	__raw_writel(0xff000000, INTC_INTMSK0);
 
 	/* disable IRL3-0 + IRL7-4 */
-	ctrl_outl(0xc0000000, INTC_INTMSK1);
-	ctrl_outl(0xfffefffe, INTC_INTMSK2);
+	__raw_writel(0xc0000000, INTC_INTMSK1);
+	__raw_writel(0xfffefffe, INTC_INTMSK2);
 
 	/* select IRL mode for IRL3-0 + IRL7-4 */
-	ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
+	__raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
 
 	/* disable holding function, ie enable "SH-4 Mode" */
-	ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0);
+	__raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
 
 	register_intc_controller(&intc_desc);
 }
@@ -507,32 +507,32 @@ 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);
+		__raw_writel(__raw_readl(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);
+		__raw_writel(__raw_readl(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);
+		__raw_writel(0x40000000, INTC_INTMSKCLR1);
+		__raw_writel(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);
+		__raw_writel(0x80000000, INTC_INTMSKCLR1);
+		__raw_writel(0xfffe0000, INTC_INTMSKCLR2);
 		break;
 	case IRQ_MODE_IRL7654_MASK:
 		/* enable IRL7-4 and mask using cpu intc controller */
-		ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+		__raw_writel(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);
+		__raw_writel(0x80000000, INTC_INTMSKCLR1);
 		register_intc_controller(&intc_desc_irl0123);
 		break;
 	default:
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7763.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7763.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7763.c	2010-05-16 17:17:36.000000000 -0400
@@ -538,11 +538,11 @@ static DECLARE_INTC_DESC(intc_irl3210_de
 void __init plat_irq_setup(void)
 {
 	/* disable IRQ7-0 */
-	ctrl_outl(0xff000000, INTC_INTMSK0);
+	__raw_writel(0xff000000, INTC_INTMSK0);
 
 	/* disable IRL3-0 + IRL7-4 */
-	ctrl_outl(0xc0000000, INTC_INTMSK1);
-	ctrl_outl(0xfffefffe, INTC_INTMSK2);
+	__raw_writel(0xc0000000, INTC_INTMSK1);
+	__raw_writel(0xfffefffe, INTC_INTMSK2);
 
 	register_intc_controller(&intc_desc);
 }
@@ -552,27 +552,27 @@ void __init plat_irq_setup_pins(int mode
 	switch (mode) {
 	case IRQ_MODE_IRQ:
 		/* select IRQ mode for IRL3-0 + IRL7-4 */
-		ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
+		__raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
 		register_intc_controller(&intc_irq_desc);
 		break;
 	case IRQ_MODE_IRL7654:
 		/* enable IRL7-4 but don't provide any masking */
-		ctrl_outl(0x40000000, INTC_INTMSKCLR1);
-		ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
+		__raw_writel(0x40000000, INTC_INTMSKCLR1);
+		__raw_writel(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);
+		__raw_writel(0x80000000, INTC_INTMSKCLR1);
+		__raw_writel(0xfffe0000, INTC_INTMSKCLR2);
 		break;
 	case IRQ_MODE_IRL7654_MASK:
 		/* enable IRL7-4 and mask using cpu intc controller */
-		ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+		__raw_writel(0x40000000, INTC_INTMSKCLR1);
 		register_intc_controller(&intc_irl7654_desc);
 		break;
 	case IRQ_MODE_IRL3210_MASK:
 		/* enable IRL0-3 and mask using cpu intc controller */
-		ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+		__raw_writel(0x80000000, INTC_INTMSKCLR1);
 		register_intc_controller(&intc_irl3210_desc);
 		break;
 	default:
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7770.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7770.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7770.c	2010-05-16 17:17:36.000000000 -0400
@@ -694,17 +694,17 @@ static DECLARE_INTC_DESC(intc_irl3210_de
 void __init plat_irq_setup(void)
 {
 	/* disable IRQ7-0 */
-	ctrl_outl(0xff000000, INTC_INTMSK0);
+	__raw_writel(0xff000000, INTC_INTMSK0);
 
 	/* disable IRL3-0 + IRL7-4 */
-	ctrl_outl(0xc0000000, INTC_INTMSK1);
-	ctrl_outl(0xfffefffe, INTC_INTMSK2);
+	__raw_writel(0xc0000000, INTC_INTMSK1);
+	__raw_writel(0xfffefffe, INTC_INTMSK2);
 
 	/* select IRL mode for IRL3-0 + IRL7-4 */
-	ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
+	__raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
 
 	/* disable holding function, ie enable "SH-4 Mode" */
-	ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0);
+	__raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
 
 	register_intc_controller(&intc_desc);
 }
@@ -714,27 +714,27 @@ void __init plat_irq_setup_pins(int mode
 	switch (mode) {
 	case IRQ_MODE_IRQ:
 		/* select IRQ mode for IRL3-0 + IRL7-4 */
-		ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
+		__raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
 		register_intc_controller(&intc_irq_desc);
 		break;
 	case IRQ_MODE_IRL7654:
 		/* enable IRL7-4 but don't provide any masking */
-		ctrl_outl(0x40000000, INTC_INTMSKCLR1);
-		ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
+		__raw_writel(0x40000000, INTC_INTMSKCLR1);
+		__raw_writel(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);
+		__raw_writel(0x80000000, INTC_INTMSKCLR1);
+		__raw_writel(0xfffe0000, INTC_INTMSKCLR2);
 		break;
 	case IRQ_MODE_IRL7654_MASK:
 		/* enable IRL7-4 and mask using cpu intc controller */
-		ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+		__raw_writel(0x40000000, INTC_INTMSKCLR1);
 		register_intc_controller(&intc_irl7654_desc);
 		break;
 	case IRQ_MODE_IRL3210_MASK:
 		/* enable IRL0-3 and mask using cpu intc controller */
-		ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+		__raw_writel(0x80000000, INTC_INTMSKCLR1);
 		register_intc_controller(&intc_irl3210_desc);
 		break;
 	default:
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7780.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7780.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7780.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,10 @@
 #include <linux/io.h>
 #include <linux/serial_sci.h>
 #include <linux/sh_timer.h>
-#include <asm/dma-sh.h>
+
+#include <asm/dmaengine.h>
+
+#include <cpu/dma-register.h>
 
 static struct plat_sci_port scif0_platform_data = {
 	.mapbase	= 0xffe00000,
@@ -247,15 +250,131 @@ static struct platform_device rtc_device
 	.resource	= rtc_resources,
 };
 
-static struct sh_dmae_pdata dma_platform_data = {
-	.mode = (SHDMA_MIX_IRQ | SHDMA_DMAOR1),
+/* DMA */
+static struct sh_dmae_channel sh7780_dmae0_channels[] = {
+	{
+		.offset = 0,
+		.dmars = 0,
+		.dmars_bit = 0,
+	}, {
+		.offset = 0x10,
+		.dmars = 0,
+		.dmars_bit = 8,
+	}, {
+		.offset = 0x20,
+		.dmars = 4,
+		.dmars_bit = 0,
+	}, {
+		.offset = 0x30,
+		.dmars = 4,
+		.dmars_bit = 8,
+	}, {
+		.offset = 0x50,
+		.dmars = 8,
+		.dmars_bit = 0,
+	}, {
+		.offset = 0x60,
+		.dmars = 8,
+		.dmars_bit = 8,
+	}
 };
 
-static struct platform_device dma_device = {
+static struct sh_dmae_channel sh7780_dmae1_channels[] = {
+	{
+		.offset = 0,
+	}, {
+		.offset = 0x10,
+	}, {
+		.offset = 0x20,
+	}, {
+		.offset = 0x30,
+	}, {
+		.offset = 0x50,
+	}, {
+		.offset = 0x60,
+	}
+};
+
+static unsigned int ts_shift[] = TS_SHIFT;
+
+static struct sh_dmae_pdata dma0_platform_data = {
+	.channel	= sh7780_dmae0_channels,
+	.channel_num	= ARRAY_SIZE(sh7780_dmae0_channels),
+	.ts_low_shift	= CHCR_TS_LOW_SHIFT,
+	.ts_low_mask	= CHCR_TS_LOW_MASK,
+	.ts_high_shift	= CHCR_TS_HIGH_SHIFT,
+	.ts_high_mask	= CHCR_TS_HIGH_MASK,
+	.ts_shift	= ts_shift,
+	.ts_shift_num	= ARRAY_SIZE(ts_shift),
+	.dmaor_init	= DMAOR_INIT,
+};
+
+static struct sh_dmae_pdata dma1_platform_data = {
+	.channel	= sh7780_dmae1_channels,
+	.channel_num	= ARRAY_SIZE(sh7780_dmae1_channels),
+	.ts_low_shift	= CHCR_TS_LOW_SHIFT,
+	.ts_low_mask	= CHCR_TS_LOW_MASK,
+	.ts_high_shift	= CHCR_TS_HIGH_SHIFT,
+	.ts_high_mask	= CHCR_TS_HIGH_MASK,
+	.ts_shift	= ts_shift,
+	.ts_shift_num	= ARRAY_SIZE(ts_shift),
+	.dmaor_init	= DMAOR_INIT,
+};
+
+static struct resource sh7780_dmae0_resources[] = {
+	[0] = {
+		/* Channel registers and DMAOR */
+		.start	= 0xfc808020,
+		.end	= 0xfc80808f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		/* DMARSx */
+		.start	= 0xfc809000,
+		.end	= 0xfc80900b,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		/* Real DMA error IRQ is 38, and channel IRQs are 34-37, 44-45 */
+		.start	= 34,
+		.end	= 34,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
+	},
+};
+
+static struct resource sh7780_dmae1_resources[] = {
+	[0] = {
+		/* Channel registers and DMAOR */
+		.start	= 0xfc818020,
+		.end	= 0xfc81808f,
+		.flags	= IORESOURCE_MEM,
+	},
+	/* DMAC1 has no DMARS */
+	{
+		/* Real DMA error IRQ is 38, and channel IRQs are 46-47, 92-95 */
+		.start	= 46,
+		.end	= 46,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
+	},
+};
+
+static struct platform_device dma0_device = {
 	.name           = "sh-dma-engine",
-	.id             = -1,
+	.id             = 0,
+	.resource	= sh7780_dmae0_resources,
+	.num_resources	= ARRAY_SIZE(sh7780_dmae0_resources),
 	.dev            = {
-		.platform_data  = &dma_platform_data,
+		.platform_data	= &dma0_platform_data,
+	},
+};
+
+static struct platform_device dma1_device = {
+	.name		= "sh-dma-engine",
+	.id		= 1,
+	.resource	= sh7780_dmae1_resources,
+	.num_resources	= ARRAY_SIZE(sh7780_dmae1_resources),
+	.dev		= {
+		.platform_data	= &dma1_platform_data,
 	},
 };
 
@@ -269,7 +388,8 @@ static struct platform_device *sh7780_de
 	&tmu4_device,
 	&tmu5_device,
 	&rtc_device,
-	&dma_device,
+	&dma0_device,
+	&dma1_device,
 };
 
 static int __init sh7780_devices_setup(void)
@@ -461,17 +581,17 @@ static DECLARE_INTC_DESC(intc_irl3210_de
 void __init plat_irq_setup(void)
 {
 	/* disable IRQ7-0 */
-	ctrl_outl(0xff000000, INTC_INTMSK0);
+	__raw_writel(0xff000000, INTC_INTMSK0);
 
 	/* disable IRL3-0 + IRL7-4 */
-	ctrl_outl(0xc0000000, INTC_INTMSK1);
-	ctrl_outl(0xfffefffe, INTC_INTMSK2);
+	__raw_writel(0xc0000000, INTC_INTMSK1);
+	__raw_writel(0xfffefffe, INTC_INTMSK2);
 
 	/* select IRL mode for IRL3-0 + IRL7-4 */
-	ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
+	__raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
 
 	/* disable holding function, ie enable "SH-4 Mode" */
-	ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0);
+	__raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
 
 	register_intc_controller(&intc_desc);
 }
@@ -481,27 +601,27 @@ void __init plat_irq_setup_pins(int mode
 	switch (mode) {
 	case IRQ_MODE_IRQ:
 		/* select IRQ mode for IRL3-0 + IRL7-4 */
-		ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
+		__raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
 		register_intc_controller(&intc_irq_desc);
 		break;
 	case IRQ_MODE_IRL7654:
 		/* enable IRL7-4 but don't provide any masking */
-		ctrl_outl(0x40000000, INTC_INTMSKCLR1);
-		ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
+		__raw_writel(0x40000000, INTC_INTMSKCLR1);
+		__raw_writel(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);
+		__raw_writel(0x80000000, INTC_INTMSKCLR1);
+		__raw_writel(0xfffe0000, INTC_INTMSKCLR2);
 		break;
 	case IRQ_MODE_IRL7654_MASK:
 		/* enable IRL7-4 and mask using cpu intc controller */
-		ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+		__raw_writel(0x40000000, INTC_INTMSKCLR1);
 		register_intc_controller(&intc_irl7654_desc);
 		break;
 	case IRQ_MODE_IRL3210_MASK:
 		/* enable IRL0-3 and mask using cpu intc controller */
-		ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+		__raw_writel(0x80000000, INTC_INTMSKCLR1);
 		register_intc_controller(&intc_irl3210_desc);
 		break;
 	default:
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7785.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7785.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7785.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,9 +14,12 @@
 #include <linux/io.h>
 #include <linux/mm.h>
 #include <linux/sh_timer.h>
-#include <asm/dma-sh.h>
+
+#include <asm/dmaengine.h>
 #include <asm/mmzone.h>
 
+#include <cpu/dma-register.h>
+
 static struct plat_sci_port scif0_platform_data = {
 	.mapbase	= 0xffea0000,
 	.flags		= UPF_BOOT_AUTOCONF,
@@ -295,15 +298,131 @@ static struct platform_device tmu5_devic
 	.num_resources	= ARRAY_SIZE(tmu5_resources),
 };
 
-static struct sh_dmae_pdata dma_platform_data = {
-	.mode = (SHDMA_MIX_IRQ | SHDMA_DMAOR1),
+/* DMA */
+static struct sh_dmae_channel sh7785_dmae0_channels[] = {
+	{
+		.offset = 0,
+		.dmars = 0,
+		.dmars_bit = 0,
+	}, {
+		.offset = 0x10,
+		.dmars = 0,
+		.dmars_bit = 8,
+	}, {
+		.offset = 0x20,
+		.dmars = 4,
+		.dmars_bit = 0,
+	}, {
+		.offset = 0x30,
+		.dmars = 4,
+		.dmars_bit = 8,
+	}, {
+		.offset = 0x50,
+		.dmars = 8,
+		.dmars_bit = 0,
+	}, {
+		.offset = 0x60,
+		.dmars = 8,
+		.dmars_bit = 8,
+	}
 };
 
-static struct platform_device dma_device = {
+static struct sh_dmae_channel sh7785_dmae1_channels[] = {
+	{
+		.offset = 0,
+	}, {
+		.offset = 0x10,
+	}, {
+		.offset = 0x20,
+	}, {
+		.offset = 0x30,
+	}, {
+		.offset = 0x50,
+	}, {
+		.offset = 0x60,
+	}
+};
+
+static unsigned int ts_shift[] = TS_SHIFT;
+
+static struct sh_dmae_pdata dma0_platform_data = {
+	.channel	= sh7785_dmae0_channels,
+	.channel_num	= ARRAY_SIZE(sh7785_dmae0_channels),
+	.ts_low_shift	= CHCR_TS_LOW_SHIFT,
+	.ts_low_mask	= CHCR_TS_LOW_MASK,
+	.ts_high_shift	= CHCR_TS_HIGH_SHIFT,
+	.ts_high_mask	= CHCR_TS_HIGH_MASK,
+	.ts_shift	= ts_shift,
+	.ts_shift_num	= ARRAY_SIZE(ts_shift),
+	.dmaor_init	= DMAOR_INIT,
+};
+
+static struct sh_dmae_pdata dma1_platform_data = {
+	.channel	= sh7785_dmae1_channels,
+	.channel_num	= ARRAY_SIZE(sh7785_dmae1_channels),
+	.ts_low_shift	= CHCR_TS_LOW_SHIFT,
+	.ts_low_mask	= CHCR_TS_LOW_MASK,
+	.ts_high_shift	= CHCR_TS_HIGH_SHIFT,
+	.ts_high_mask	= CHCR_TS_HIGH_MASK,
+	.ts_shift	= ts_shift,
+	.ts_shift_num	= ARRAY_SIZE(ts_shift),
+	.dmaor_init	= DMAOR_INIT,
+};
+
+static struct resource sh7785_dmae0_resources[] = {
+	[0] = {
+		/* Channel registers and DMAOR */
+		.start	= 0xfc808020,
+		.end	= 0xfc80808f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		/* DMARSx */
+		.start	= 0xfc809000,
+		.end	= 0xfc80900b,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		/* Real DMA error IRQ is 39, and channel IRQs are 33-38 */
+		.start	= 33,
+		.end	= 33,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
+	},
+};
+
+static struct resource sh7785_dmae1_resources[] = {
+	[0] = {
+		/* Channel registers and DMAOR */
+		.start	= 0xfcc08020,
+		.end	= 0xfcc0808f,
+		.flags	= IORESOURCE_MEM,
+	},
+	/* DMAC1 has no DMARS */
+	{
+		/* Real DMA error IRQ is 58, and channel IRQs are 52-57 */
+		.start	= 52,
+		.end	= 52,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
+	},
+};
+
+static struct platform_device dma0_device = {
 	.name           = "sh-dma-engine",
-	.id             = -1,
+	.id             = 0,
+	.resource	= sh7785_dmae0_resources,
+	.num_resources	= ARRAY_SIZE(sh7785_dmae0_resources),
 	.dev            = {
-		.platform_data  = &dma_platform_data,
+		.platform_data	= &dma0_platform_data,
+	},
+};
+
+static struct platform_device dma1_device = {
+	.name		= "sh-dma-engine",
+	.id		= 1,
+	.resource	= sh7785_dmae1_resources,
+	.num_resources	= ARRAY_SIZE(sh7785_dmae1_resources),
+	.dev		= {
+		.platform_data	= &dma1_platform_data,
 	},
 };
 
@@ -320,7 +439,8 @@ static struct platform_device *sh7785_de
 	&tmu3_device,
 	&tmu4_device,
 	&tmu5_device,
-	&dma_device,
+	&dma0_device,
+	&dma1_device,
 };
 
 static int __init sh7785_devices_setup(void)
@@ -541,17 +661,17 @@ static DECLARE_INTC_DESC(intc_desc_irl45
 void __init plat_irq_setup(void)
 {
 	/* disable IRQ3-0 + IRQ7-4 */
-	ctrl_outl(0xff000000, INTC_INTMSK0);
+	__raw_writel(0xff000000, INTC_INTMSK0);
 
 	/* disable IRL3-0 + IRL7-4 */
-	ctrl_outl(0xc0000000, INTC_INTMSK1);
-	ctrl_outl(0xfffefffe, INTC_INTMSK2);
+	__raw_writel(0xc0000000, INTC_INTMSK1);
+	__raw_writel(0xfffefffe, INTC_INTMSK2);
 
 	/* select IRL mode for IRL3-0 + IRL7-4 */
-	ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
+	__raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
 
 	/* disable holding function, ie enable "SH-4 Mode" */
-	ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0);
+	__raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
 
 	register_intc_controller(&intc_desc);
 }
@@ -561,32 +681,32 @@ 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);
+		__raw_writel(__raw_readl(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);
+		__raw_writel(__raw_readl(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);
+		__raw_writel(0x40000000, INTC_INTMSKCLR1);
+		__raw_writel(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);
+		__raw_writel(0x80000000, INTC_INTMSKCLR1);
+		__raw_writel(0xfffe0000, INTC_INTMSKCLR2);
 		break;
 	case IRQ_MODE_IRL7654_MASK:
 		/* enable IRL7-4 and mask using cpu intc controller */
-		ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+		__raw_writel(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);
+		__raw_writel(0x80000000, INTC_INTMSKCLR1);
 		register_intc_controller(&intc_desc_irl0123);
 		break;
 	default:
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7786.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7786.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7786.c	2010-05-16 17:17:36.000000000 -0400
@@ -867,14 +867,14 @@ static DECLARE_INTC_DESC(intc_desc_irl45
 void __init plat_irq_setup(void)
 {
 	/* disable IRQ3-0 + IRQ7-4 */
-	ctrl_outl(0xff000000, INTC_INTMSK0);
+	__raw_writel(0xff000000, INTC_INTMSK0);
 
 	/* disable IRL3-0 + IRL7-4 */
-	ctrl_outl(0xc0000000, INTC_INTMSK1);
-	ctrl_outl(0xfffefffe, INTC_INTMSK2);
+	__raw_writel(0xc0000000, INTC_INTMSK1);
+	__raw_writel(0xfffefffe, INTC_INTMSK2);
 
 	/* select IRL mode for IRL3-0 + IRL7-4 */
-	ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
+	__raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
 
 	register_intc_controller(&intc_desc);
 }
@@ -884,32 +884,32 @@ 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);
+		__raw_writel(__raw_readl(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);
+		__raw_writel(__raw_readl(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);
+		__raw_writel(0x40000000, INTC_INTMSKCLR1);
+		__raw_writel(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);
+		__raw_writel(0x80000000, INTC_INTMSKCLR1);
+		__raw_writel(0xfffe0000, INTC_INTMSKCLR2);
 		break;
 	case IRQ_MODE_IRL7654_MASK:
 		/* enable IRL7-4 and mask using cpu intc controller */
-		ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+		__raw_writel(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);
+		__raw_writel(0x80000000, INTC_INTMSKCLR1);
 		register_intc_controller(&intc_desc_irl0123);
 		break;
 	default:
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/smp-shx3.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/smp-shx3.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/smp-shx3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/smp-shx3.c	2010-05-16 17:17:36.000000000 -0400
@@ -78,7 +78,10 @@ void __init plat_prepare_cpus(unsigned i
 
 void plat_start_cpu(unsigned int cpu, unsigned long entry_point)
 {
-	__raw_writel(entry_point, RESET_REG(cpu));
+	if (__in_29bit_mode())
+		__raw_writel(entry_point, RESET_REG(cpu));
+	else
+		__raw_writel(virt_to_phys(entry_point), RESET_REG(cpu));
 
 	if (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP))
 		__raw_writel(STBCR_MSTP, STBCR_REG(cpu));
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/ubc.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/ubc.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/ubc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh4a/ubc.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,133 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/ubc.c
+ *
+ * On-chip UBC support for SH-4A CPUs.
+ *
+ * Copyright (C) 2009 - 2010  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/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <asm/hw_breakpoint.h>
+
+#define UBC_CBR(idx)	(0xff200000 + (0x20 * idx))
+#define UBC_CRR(idx)	(0xff200004 + (0x20 * idx))
+#define UBC_CAR(idx)	(0xff200008 + (0x20 * idx))
+#define UBC_CAMR(idx)	(0xff20000c + (0x20 * idx))
+
+#define UBC_CCMFR	0xff200600
+#define UBC_CBCR	0xff200620
+
+/* CRR */
+#define UBC_CRR_PCB	(1 << 1)
+#define UBC_CRR_BIE	(1 << 0)
+
+/* CBR */
+#define UBC_CBR_CE	(1 << 0)
+
+static struct sh_ubc sh4a_ubc;
+
+static void sh4a_ubc_enable(struct arch_hw_breakpoint *info, int idx)
+{
+	__raw_writel(UBC_CBR_CE | info->len | info->type, UBC_CBR(idx));
+	__raw_writel(info->address, UBC_CAR(idx));
+}
+
+static void sh4a_ubc_disable(struct arch_hw_breakpoint *info, int idx)
+{
+	__raw_writel(0, UBC_CBR(idx));
+	__raw_writel(0, UBC_CAR(idx));
+}
+
+static void sh4a_ubc_enable_all(unsigned long mask)
+{
+	int i;
+
+	for (i = 0; i < sh4a_ubc.num_events; i++)
+		if (mask & (1 << i))
+			__raw_writel(__raw_readl(UBC_CBR(i)) | UBC_CBR_CE,
+				     UBC_CBR(i));
+}
+
+static void sh4a_ubc_disable_all(void)
+{
+	int i;
+
+	for (i = 0; i < sh4a_ubc.num_events; i++)
+		__raw_writel(__raw_readl(UBC_CBR(i)) & ~UBC_CBR_CE,
+			     UBC_CBR(i));
+}
+
+static unsigned long sh4a_ubc_active_mask(void)
+{
+	unsigned long active = 0;
+	int i;
+
+	for (i = 0; i < sh4a_ubc.num_events; i++)
+		if (__raw_readl(UBC_CBR(i)) & UBC_CBR_CE)
+			active |= (1 << i);
+
+	return active;
+}
+
+static unsigned long sh4a_ubc_triggered_mask(void)
+{
+	return __raw_readl(UBC_CCMFR);
+}
+
+static void sh4a_ubc_clear_triggered_mask(unsigned long mask)
+{
+	__raw_writel(__raw_readl(UBC_CCMFR) & ~mask, UBC_CCMFR);
+}
+
+static struct sh_ubc sh4a_ubc = {
+	.name			= "SH-4A",
+	.num_events		= 2,
+	.trap_nr		= 0x1e0,
+	.enable			= sh4a_ubc_enable,
+	.disable		= sh4a_ubc_disable,
+	.enable_all		= sh4a_ubc_enable_all,
+	.disable_all		= sh4a_ubc_disable_all,
+	.active_mask		= sh4a_ubc_active_mask,
+	.triggered_mask		= sh4a_ubc_triggered_mask,
+	.clear_triggered_mask	= sh4a_ubc_clear_triggered_mask,
+};
+
+static int __init sh4a_ubc_init(void)
+{
+	struct clk *ubc_iclk = clk_get(NULL, "ubc0");
+	int i;
+
+	/*
+	 * The UBC MSTP bit is optional, as not all platforms will have
+	 * it. Just ignore it if we can't find it.
+	 */
+	if (IS_ERR(ubc_iclk))
+		ubc_iclk = NULL;
+
+	clk_enable(ubc_iclk);
+
+	__raw_writel(0, UBC_CBCR);
+
+	for (i = 0; i < sh4a_ubc.num_events; i++) {
+		__raw_writel(0, UBC_CAMR(i));
+		__raw_writel(0, UBC_CBR(i));
+
+		__raw_writel(UBC_CRR_BIE | UBC_CRR_PCB, UBC_CRR(i));
+
+		/* dummy read for write posting */
+		(void)__raw_readl(UBC_CRR(i));
+	}
+
+	clk_disable(ubc_iclk);
+
+	sh4a_ubc.clk = ubc_iclk;
+
+	return register_sh_ubc(&sh4a_ubc);
+}
+arch_initcall(sh4a_ubc_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh5/clock-sh5.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh5/clock-sh5.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh5/clock-sh5.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh5/clock-sh5.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,7 @@ static unsigned long cprc_base;
 
 static void master_clk_init(struct clk *clk)
 {
-	int idx = (ctrl_inl(cprc_base + 0x00) >> 6) & 0x0007;
+	int idx = (__raw_readl(cprc_base + 0x00) >> 6) & 0x0007;
 	clk->rate *= ifc_table[idx];
 }
 
@@ -34,7 +34,7 @@ static struct clk_ops sh5_master_clk_ops
 
 static unsigned long module_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(cprc_base) >> 12) & 0x0007;
+	int idx = (__raw_readw(cprc_base) >> 12) & 0x0007;
 	return clk->parent->rate / ifc_table[idx];
 }
 
@@ -44,7 +44,7 @@ static struct clk_ops sh5_module_clk_ops
 
 static unsigned long bus_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(cprc_base) >> 3) & 0x0007;
+	int idx = (__raw_readw(cprc_base) >> 3) & 0x0007;
 	return clk->parent->rate / ifc_table[idx];
 }
 
@@ -54,7 +54,7 @@ static struct clk_ops sh5_bus_clk_ops =
 
 static unsigned long cpu_clk_recalc(struct clk *clk)
 {
-	int idx = (ctrl_inw(cprc_base) & 0x0007);
+	int idx = (__raw_readw(cprc_base) & 0x0007);
 	return clk->parent->rate / ifc_table[idx];
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh5/entry.S linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh5/entry.S
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh5/entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh5/entry.S	2010-05-16 17:17:36.000000000 -0400
@@ -187,7 +187,7 @@ trap_jtable:
 	.rept 6
 		.long do_exception_error	/* 0x880 - 0x920 */
 	.endr
-	.long	do_software_break_point	/* 0x940 */
+	.long	breakpoint_trap_handler	/* 0x940 */
 	.long	do_exception_error		/* 0x960 */
 	.long	do_single_step		/* 0x980 */
 
@@ -1124,7 +1124,7 @@ fpu_error_or_IRQA:
 	pta	its_IRQ, tr0
 	beqi/l	r4, EVENT_INTERRUPT, tr0
 #ifdef CONFIG_SH_FPU
-	movi	do_fpu_state_restore, r6
+	movi	fpu_state_restore_trap_handler, r6
 #else
 	movi	do_exception_error, r6
 #endif
@@ -1135,7 +1135,7 @@ fpu_error_or_IRQB:
 	pta	its_IRQ, tr0
 	beqi/l	r4, EVENT_INTERRUPT, tr0
 #ifdef CONFIG_SH_FPU
-	movi	do_fpu_state_restore, r6
+	movi	fpu_state_restore_trap_handler, r6
 #else
 	movi	do_exception_error, r6
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh5/fpu.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh5/fpu.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh5/fpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/sh5/fpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,24 +15,6 @@
 #include <linux/sched.h>
 #include <linux/signal.h>
 #include <asm/processor.h>
-#include <asm/user.h>
-#include <asm/io.h>
-#include <asm/fpu.h>
-
-/*
- * Initially load the FPU with signalling NANS.  This bit pattern
- * has the property that no matter whether considered as single or as
- * double precision, it still represents a signalling NAN.
- */
-#define sNAN64		0xFFFFFFFFFFFFFFFFULL
-#define sNAN32		0xFFFFFFFFUL
-
-static union sh_fpu_union init_fpuregs = {
-	.hard = {
-		.fp_regs = { [0 ... 63] = sNAN32 },
-		.fpscr = FPSCR_INIT
-	}
-};
 
 void save_fpu(struct task_struct *tsk)
 {
@@ -72,12 +54,11 @@ void save_fpu(struct task_struct *tsk)
 		     "fgetscr   fr63\n\t"
 		     "fst.s     %0, (32*8), fr63\n\t"
 		: /* no output */
-		: "r" (&tsk->thread.fpu.hard)
+		: "r" (&tsk->thread.xstate->hardfpu)
 		: "memory");
 }
 
-static inline void
-fpload(struct sh_fpu_hard_struct *fpregs)
+void restore_fpu(struct task_struct *tsk)
 {
 	asm volatile("fld.p     %0, (0*8), fp0\n\t"
 		     "fld.p     %0, (1*8), fp2\n\t"
@@ -116,16 +97,11 @@ fpload(struct sh_fpu_hard_struct *fpregs
 
 		     "fld.p     %0, (31*8), fp62\n\t"
 		: /* no output */
-		: "r" (fpregs) );
-}
-
-void fpinit(struct sh_fpu_hard_struct *fpregs)
-{
-	*fpregs = init_fpuregs.hard;
+		: "r" (&tsk->thread.xstate->hardfpu)
+		: "memory");
 }
 
-asmlinkage void
-do_fpu_error(unsigned long ex, struct pt_regs *regs)
+asmlinkage void do_fpu_error(unsigned long ex, struct pt_regs *regs)
 {
 	struct task_struct *tsk = current;
 
@@ -133,35 +109,6 @@ do_fpu_error(unsigned long ex, struct pt
 
 	tsk->thread.trap_no = 11;
 	tsk->thread.error_code = 0;
-	force_sig(SIGFPE, tsk);
-}
-
-
-asmlinkage void
-do_fpu_state_restore(unsigned long ex, struct pt_regs *regs)
-{
-	void die(const char *str, struct pt_regs *regs, long err);
-
-	if (! user_mode(regs))
-		die("FPU used in kernel", regs, ex);
-
-	regs->sr &= ~SR_FD;
-
-	if (last_task_used_math == current)
-		return;
-
-	enable_fpu();
-	if (last_task_used_math != NULL)
-		/* Other processes fpu state, save away */
-		save_fpu(last_task_used_math);
 
-        last_task_used_math = current;
-        if (used_math()) {
-                fpload(&current->thread.fpu.hard);
-        } else {
-		/* First time FPU user.  */
-		fpload(&init_fpuregs.hard);
-                set_used_math();
-        }
-	disable_fpu();
+	force_sig(SIGFPE, tsk);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/shmobile/pm.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/shmobile/pm.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/shmobile/pm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/shmobile/pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,8 @@ ATOMIC_NOTIFIER_HEAD(sh_mobile_post_slee
 #define SUSP_MODE_SLEEP		(SUSP_SH_SLEEP)
 #define SUSP_MODE_SLEEP_SF	(SUSP_SH_SLEEP | SUSP_SH_SF)
 #define SUSP_MODE_STANDBY_SF	(SUSP_SH_STANDBY | SUSP_SH_SF)
-#define SUSP_MODE_RSTANDBY	(SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_SF)
+#define SUSP_MODE_RSTANDBY_SF \
+	(SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_REGS | SUSP_SH_SF)
  /*
   * U-standby mode is unsupported since it needs bootloader hacks
   */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/shmobile/sleep.S linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/shmobile/sleep.S
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/shmobile/sleep.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpu/shmobile/sleep.S	2010-05-16 17:17:36.000000000 -0400
@@ -48,8 +48,48 @@ ENTRY(sh_mobile_sleep_enter_start)
 	stc	sr, r0
 	mov.l	r0, @(SH_SLEEP_SR, r5)
 
-	/* save sp */
+	/* save general purpose registers to stack if needed */
+	mov.l	@(SH_SLEEP_MODE, r5), r0
+	tst	#SUSP_SH_REGS, r0
+	bt	skip_regs_save
+
+	sts.l	pr, @-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
+
+	/* make sure bank0 is selected, save low registers */
+	mov.l	rb_bit, r9
+	not	r9, r9
+	bsr	set_sr
+	 mov	#0, r10
+
+	bsr	save_low_regs
+	 nop
+
+	/* switch to bank 1, save low registers */
+	mov.l	rb_bit, r10
+	bsr	set_sr
+	 mov	#-1, r9
+
+	bsr	save_low_regs
+	 nop
+
+	/* switch back to bank 0 */
+	mov.l	rb_bit, r9
+	not	r9, r9
+	bsr	set_sr
+	 mov	#0, r10
+
+skip_regs_save:
+
+	/* save sp, also set to internal ram */
 	mov.l	r15, @(SH_SLEEP_SP, r5)
+	mov	r5, r15
 
 	/* save stbcr */
 	bsr     save_register
@@ -60,7 +100,7 @@ ENTRY(sh_mobile_sleep_enter_start)
 	tst	#SUSP_SH_MMU, r0
 	bt	skip_mmu_save_disable
 
-       /* save mmu state */
+	/* save mmu state */
 	bsr	save_register
 	 mov	#SH_SLEEP_REG_PTEH, r0
 
@@ -177,6 +217,29 @@ get_register:
 	mov.l	@(r0, r5), r0
 	rts
 	 nop
+
+set_sr:
+	stc	sr, r8
+	and	r9, r8
+	or	r10, r8
+	ldc	r8, sr
+	rts
+	 nop
+
+save_low_regs:
+	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
+	rts
+	 mov.l	r0, @-r15
+
+	.balign 4
+rb_bit:	.long	0x20000000 ! RB=1
+
 ENTRY(sh_mobile_sleep_enter_end)
 
 	.balign 4
@@ -270,6 +333,40 @@ skip_restore_sf:
 	icbi	@r0
 
 skip_restore_mmu:
+
+	/* restore general purpose registers if needed */
+	mov.l	@(SH_SLEEP_MODE, r5), r0
+	tst	#SUSP_SH_REGS, r0
+	bt	skip_restore_regs
+
+	/* switch to bank 1, restore low registers */
+	mov.l	_rb_bit, r10
+	bsr	_set_sr
+	 mov	#-1, r9
+
+	bsr	restore_low_regs
+	 nop
+
+	/* switch to bank0, restore low registers */
+	mov.l	_rb_bit, r9
+	not	r9, r9
+	bsr	_set_sr
+	 mov	#0, r10
+
+	bsr	restore_low_regs
+	 nop
+
+	/* restore the rest of the registers */
+	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
+	lds.l	@r15+, pr
+
+skip_restore_regs:
 	rte
 	 nop
 
@@ -283,6 +380,26 @@ restore_register:
 	rts
 	 nop
 
+_set_sr:
+	stc	sr, r8
+	and	r9, r8
+	or	r10, r8
+	ldc	r8, sr
+	rts
+	 nop
+
+restore_low_regs:
+	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
+	rts
+	 mov.l	@r15+, r7
+
 	.balign 4
+_rb_bit:	.long	0x20000000 ! RB=1
 1:	.long	~0x7ff
 ENTRY(sh_mobile_sleep_resume_end)
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/cpufreq.c linux-libre-2.6.34-gnu1/arch/sh/kernel/cpufreq.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/cpufreq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/cpufreq.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,7 +48,7 @@ static int sh_cpufreq_target(struct cpuf
 		return -ENODEV;
 
 	cpus_allowed = current->cpus_allowed;
-	set_cpus_allowed(current, cpumask_of_cpu(cpu));
+	set_cpus_allowed_ptr(current, cpumask_of(cpu));
 
 	BUG_ON(smp_processor_id() != cpu);
 
@@ -66,7 +66,7 @@ static int sh_cpufreq_target(struct cpuf
 	freqs.flags	= 0;
 
 	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-	set_cpus_allowed(current, cpus_allowed);
+	set_cpus_allowed_ptr(current, &cpus_allowed);
 	clk_set_rate(cpuclk, freq);
 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/debugtraps.S linux-libre-2.6.34-gnu1/arch/sh/kernel/debugtraps.S
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/debugtraps.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/debugtraps.S	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/linkage.h>
 
 #if !defined(CONFIG_KGDB)
-#define breakpoint_trap_handler		debug_trap_handler
 #define singlestep_trap_handler		debug_trap_handler
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/dwarf.c linux-libre-2.6.34-gnu1/arch/sh/kernel/dwarf.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/dwarf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/dwarf.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/mm.h>
 #include <linux/elf.h>
 #include <linux/ftrace.h>
+#include <linux/slab.h>
 #include <asm/dwarf.h>
 #include <asm/unwinder.h>
 #include <asm/sections.h>
@@ -39,10 +40,10 @@ static mempool_t *dwarf_frame_pool;
 static struct kmem_cache *dwarf_reg_cachep;
 static mempool_t *dwarf_reg_pool;
 
-static LIST_HEAD(dwarf_cie_list);
+static struct rb_root cie_root;
 static DEFINE_SPINLOCK(dwarf_cie_lock);
 
-static LIST_HEAD(dwarf_fde_list);
+static struct rb_root fde_root;
 static DEFINE_SPINLOCK(dwarf_fde_lock);
 
 static struct dwarf_cie *cached_cie;
@@ -301,7 +302,8 @@ static inline int dwarf_entry_len(char *
  */
 static struct dwarf_cie *dwarf_lookup_cie(unsigned long cie_ptr)
 {
-	struct dwarf_cie *cie;
+	struct rb_node **rb_node = &cie_root.rb_node;
+	struct dwarf_cie *cie = NULL;
 	unsigned long flags;
 
 	spin_lock_irqsave(&dwarf_cie_lock, flags);
@@ -315,16 +317,24 @@ static struct dwarf_cie *dwarf_lookup_ci
 		goto out;
 	}
 
-	list_for_each_entry(cie, &dwarf_cie_list, link) {
-		if (cie->cie_pointer == cie_ptr) {
-			cached_cie = cie;
-			break;
+	while (*rb_node) {
+		struct dwarf_cie *cie_tmp;
+
+		cie_tmp = rb_entry(*rb_node, struct dwarf_cie, node);
+		BUG_ON(!cie_tmp);
+
+		if (cie_ptr == cie_tmp->cie_pointer) {
+			cie = cie_tmp;
+			cached_cie = cie_tmp;
+			goto out;
+		} else {
+			if (cie_ptr < cie_tmp->cie_pointer)
+				rb_node = &(*rb_node)->rb_left;
+			else
+				rb_node = &(*rb_node)->rb_right;
 		}
 	}
 
-	/* Couldn't find the entry in the list. */
-	if (&cie->link == &dwarf_cie_list)
-		cie = NULL;
 out:
 	spin_unlock_irqrestore(&dwarf_cie_lock, flags);
 	return cie;
@@ -336,25 +346,34 @@ out:
  */
 struct dwarf_fde *dwarf_lookup_fde(unsigned long pc)
 {
-	struct dwarf_fde *fde;
+	struct rb_node **rb_node = &fde_root.rb_node;
+	struct dwarf_fde *fde = NULL;
 	unsigned long flags;
 
 	spin_lock_irqsave(&dwarf_fde_lock, flags);
 
-	list_for_each_entry(fde, &dwarf_fde_list, link) {
-		unsigned long start, end;
+	while (*rb_node) {
+		struct dwarf_fde *fde_tmp;
+		unsigned long tmp_start, tmp_end;
 
-		start = fde->initial_location;
-		end = fde->initial_location + fde->address_range;
+		fde_tmp = rb_entry(*rb_node, struct dwarf_fde, node);
+		BUG_ON(!fde_tmp);
 
-		if (pc >= start && pc < end)
-			break;
-	}
+		tmp_start = fde_tmp->initial_location;
+		tmp_end = fde_tmp->initial_location + fde_tmp->address_range;
 
-	/* Couldn't find the entry in the list. */
-	if (&fde->link == &dwarf_fde_list)
-		fde = NULL;
+		if (pc < tmp_start) {
+			rb_node = &(*rb_node)->rb_left;
+		} else {
+			if (pc < tmp_end) {
+				fde = fde_tmp;
+				goto out;
+			} else
+				rb_node = &(*rb_node)->rb_right;
+		}
+	}
 
+out:
 	spin_unlock_irqrestore(&dwarf_fde_lock, flags);
 
 	return fde;
@@ -552,8 +571,8 @@ extern void ret_from_irq(void);
  *	on the callstack. Each of the lower (older) stack frames are
  *	linked via the "prev" member.
  */
-struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
-					struct dwarf_frame *prev)
+struct dwarf_frame *dwarf_unwind_stack(unsigned long pc,
+				       struct dwarf_frame *prev)
 {
 	struct dwarf_frame *frame;
 	struct dwarf_cie *cie;
@@ -708,6 +727,8 @@ bail:
 static int dwarf_parse_cie(void *entry, void *p, unsigned long len,
 			   unsigned char *end, struct module *mod)
 {
+	struct rb_node **rb_node = &cie_root.rb_node;
+	struct rb_node *parent = *rb_node;
 	struct dwarf_cie *cie;
 	unsigned long flags;
 	int count;
@@ -802,11 +823,30 @@ static int dwarf_parse_cie(void *entry,
 	cie->initial_instructions = p;
 	cie->instructions_end = end;
 
-	cie->mod = mod;
-
 	/* Add to list */
 	spin_lock_irqsave(&dwarf_cie_lock, flags);
-	list_add_tail(&cie->link, &dwarf_cie_list);
+
+	while (*rb_node) {
+		struct dwarf_cie *cie_tmp;
+
+		cie_tmp = rb_entry(*rb_node, struct dwarf_cie, node);
+
+		parent = *rb_node;
+
+		if (cie->cie_pointer < cie_tmp->cie_pointer)
+			rb_node = &parent->rb_left;
+		else if (cie->cie_pointer >= cie_tmp->cie_pointer)
+			rb_node = &parent->rb_right;
+		else
+			WARN_ON(1);
+	}
+
+	rb_link_node(&cie->node, parent, rb_node);
+	rb_insert_color(&cie->node, &cie_root);
+
+	if (mod != NULL)
+		list_add_tail(&cie->link, &mod->arch.cie_list);
+
 	spin_unlock_irqrestore(&dwarf_cie_lock, flags);
 
 	return 0;
@@ -816,6 +856,8 @@ static int dwarf_parse_fde(void *entry,
 			   void *start, unsigned long len,
 			   unsigned char *end, struct module *mod)
 {
+	struct rb_node **rb_node = &fde_root.rb_node;
+	struct rb_node *parent = *rb_node;
 	struct dwarf_fde *fde;
 	struct dwarf_cie *cie;
 	unsigned long flags;
@@ -863,11 +905,38 @@ static int dwarf_parse_fde(void *entry,
 	fde->instructions = p;
 	fde->end = end;
 
-	fde->mod = mod;
-
 	/* Add to list. */
 	spin_lock_irqsave(&dwarf_fde_lock, flags);
-	list_add_tail(&fde->link, &dwarf_fde_list);
+
+	while (*rb_node) {
+		struct dwarf_fde *fde_tmp;
+		unsigned long tmp_start, tmp_end;
+		unsigned long start, end;
+
+		fde_tmp = rb_entry(*rb_node, struct dwarf_fde, node);
+
+		start = fde->initial_location;
+		end = fde->initial_location + fde->address_range;
+
+		tmp_start = fde_tmp->initial_location;
+		tmp_end = fde_tmp->initial_location + fde_tmp->address_range;
+
+		parent = *rb_node;
+
+		if (start < tmp_start)
+			rb_node = &parent->rb_left;
+		else if (start >= tmp_end)
+			rb_node = &parent->rb_right;
+		else
+			WARN_ON(1);
+	}
+
+	rb_link_node(&fde->node, parent, rb_node);
+	rb_insert_color(&fde->node, &fde_root);
+
+	if (mod != NULL)
+		list_add_tail(&fde->link, &mod->arch.fde_list);
+
 	spin_unlock_irqrestore(&dwarf_fde_lock, flags);
 
 	return 0;
@@ -912,19 +981,29 @@ static struct unwinder dwarf_unwinder =
 
 static void dwarf_unwinder_cleanup(void)
 {
-	struct dwarf_cie *cie, *cie_tmp;
-	struct dwarf_fde *fde, *fde_tmp;
+	struct rb_node **fde_rb_node = &fde_root.rb_node;
+	struct rb_node **cie_rb_node = &cie_root.rb_node;
 
 	/*
 	 * Deallocate all the memory allocated for the DWARF unwinder.
 	 * Traverse all the FDE/CIE lists and remove and free all the
 	 * memory associated with those data structures.
 	 */
-	list_for_each_entry_safe(cie, cie_tmp, &dwarf_cie_list, link)
-		kfree(cie);
+	while (*fde_rb_node) {
+		struct dwarf_fde *fde;
 
-	list_for_each_entry_safe(fde, fde_tmp, &dwarf_fde_list, link)
+		fde = rb_entry(*fde_rb_node, struct dwarf_fde, node);
+		rb_erase(*fde_rb_node, &fde_root);
 		kfree(fde);
+	}
+
+	while (*cie_rb_node) {
+		struct dwarf_cie *cie;
+
+		cie = rb_entry(*cie_rb_node, struct dwarf_cie, node);
+		rb_erase(*cie_rb_node, &cie_root);
+		kfree(cie);
+	}
 
 	kmem_cache_destroy(dwarf_reg_cachep);
 	kmem_cache_destroy(dwarf_frame_cachep);
@@ -1024,6 +1103,8 @@ int module_dwarf_finalize(const Elf_Ehdr
 
 	/* Did we find the .eh_frame section? */
 	if (i != hdr->e_shnum) {
+		INIT_LIST_HEAD(&me->arch.cie_list);
+		INIT_LIST_HEAD(&me->arch.fde_list);
 		err = dwarf_parse_section((char *)start, (char *)end, me);
 		if (err) {
 			printk(KERN_WARNING "%s: failed to parse DWARF info\n",
@@ -1044,38 +1125,26 @@ int module_dwarf_finalize(const Elf_Ehdr
  */
 void module_dwarf_cleanup(struct module *mod)
 {
-	struct dwarf_fde *fde;
-	struct dwarf_cie *cie;
+	struct dwarf_fde *fde, *ftmp;
+	struct dwarf_cie *cie, *ctmp;
 	unsigned long flags;
 
 	spin_lock_irqsave(&dwarf_cie_lock, flags);
 
-again_cie:
-	list_for_each_entry(cie, &dwarf_cie_list, link) {
-		if (cie->mod == mod)
-			break;
-	}
-
-	if (&cie->link != &dwarf_cie_list) {
+	list_for_each_entry_safe(cie, ctmp, &mod->arch.cie_list, link) {
 		list_del(&cie->link);
+		rb_erase(&cie->node, &cie_root);
 		kfree(cie);
-		goto again_cie;
 	}
 
 	spin_unlock_irqrestore(&dwarf_cie_lock, flags);
 
 	spin_lock_irqsave(&dwarf_fde_lock, flags);
 
-again_fde:
-	list_for_each_entry(fde, &dwarf_fde_list, link) {
-		if (fde->mod == mod)
-			break;
-	}
-
-	if (&fde->link != &dwarf_fde_list) {
+	list_for_each_entry_safe(fde, ftmp, &mod->arch.fde_list, link) {
 		list_del(&fde->link);
+		rb_erase(&fde->node, &fde_root);
 		kfree(fde);
-		goto again_fde;
 	}
 
 	spin_unlock_irqrestore(&dwarf_fde_lock, flags);
@@ -1094,8 +1163,6 @@ again_fde:
 static int __init dwarf_unwinder_init(void)
 {
 	int err;
-	INIT_LIST_HEAD(&dwarf_cie_list);
-	INIT_LIST_HEAD(&dwarf_fde_list);
 
 	dwarf_frame_cachep = kmem_cache_create("dwarf_frames",
 			sizeof(struct dwarf_frame), 0,
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/early_printk.c linux-libre-2.6.34-gnu1/arch/sh/kernel/early_printk.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/early_printk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/early_printk.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,85 +0,0 @@
-/*
- * arch/sh/kernel/early_printk.c
- *
- *  Copyright (C) 1999, 2000  Niibe Yutaka
- *  Copyright (C) 2002  M. R. Brown
- *  Copyright (C) 2004 - 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/console.h>
-#include <linux/tty.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-
-#include <asm/sh_bios.h>
-
-/*
- *	Print a string through the BIOS
- */
-static void sh_console_write(struct console *co, const char *s,
-				 unsigned count)
-{
-	sh_bios_console_write(s, count);
-}
-
-/*
- *	Setup initial baud/bits/parity. We do two things here:
- *	- construct a cflag setting for the first rs_open()
- *	- initialize the serial port
- *	Return non-zero if we didn't find a serial port.
- */
-static int __init sh_console_setup(struct console *co, char *options)
-{
-	int	cflag = CREAD | HUPCL | CLOCAL;
-
-	/*
-	 *	Now construct a cflag setting.
-	 *	TODO: this is a totally bogus cflag, as we have
-	 *	no idea what serial settings the BIOS is using, or
-	 *	even if its using the serial port at all.
-	 */
-	cflag |= B115200 | CS8 | /*no parity*/0;
-
-	co->cflag = cflag;
-
-	return 0;
-}
-
-static struct console bios_console = {
-	.name		= "bios",
-	.write		= sh_console_write,
-	.setup		= sh_console_setup,
-	.flags		= CON_PRINTBUFFER,
-	.index		= -1,
-};
-
-static struct console *early_console;
-
-static int __init setup_early_printk(char *buf)
-{
-	int keep_early = 0;
-
-	if (!buf)
-		return 0;
-
-	if (strstr(buf, "keep"))
-		keep_early = 1;
-
-	if (!strncmp(buf, "bios", 4))
-		early_console = &bios_console;
-
-	if (likely(early_console)) {
-		if (keep_early)
-			early_console->flags &= ~CON_BOOT;
-		else
-			early_console->flags |= CON_BOOT;
-		register_console(early_console);
-	}
-
-	return 0;
-}
-early_param("earlyprintk", setup_early_printk);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/ftrace.c linux-libre-2.6.34-gnu1/arch/sh/kernel/ftrace.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/ftrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/ftrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -399,12 +399,3 @@ void prepare_ftrace_return(unsigned long
 	}
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
-
-#ifdef CONFIG_FTRACE_SYSCALLS
-extern unsigned long *sys_call_table;
-
-unsigned long __init arch_syscall_addr(int nr)
-{
-	return (unsigned long)sys_call_table[nr];
-}
-#endif /* CONFIG_FTRACE_SYSCALLS */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/head_32.S linux-libre-2.6.34-gnu1/arch/sh/kernel/head_32.S
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/head_32.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/head_32.S	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
  *  arch/sh/kernel/head.S
  *
  *  Copyright (C) 1999, 2000  Niibe Yutaka & Kaz Kojima
+ *  Copyright (C) 2010  Matt Fleming
  *
  * 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
@@ -13,6 +14,8 @@
 #include <linux/init.h>
 #include <linux/linkage.h>
 #include <asm/thread_info.h>
+#include <asm/mmu.h>
+#include <cpu/mmu_context.h>
 
 #ifdef CONFIG_CPU_SH4A
 #define SYNCO()		synco
@@ -33,7 +36,7 @@ ENTRY(empty_zero_page)
 	.long	1		/* LOADER_TYPE */
 	.long	0x00000000	/* INITRD_START */
 	.long	0x00000000	/* INITRD_SIZE */
-#if defined(CONFIG_32BIT) && defined(CONFIG_PMB_FIXED)
+#ifdef CONFIG_32BIT
 	.long	0x53453f00 + 32	/* "SE?" = 32 bit */
 #else
 	.long	0x53453f00 + 29	/* "SE?" = 29 bit */
@@ -82,6 +85,209 @@ ENTRY(_stext)
 	ldc	r0, r7_bank	! ... and initial thread_info
 #endif
 
+#ifdef CONFIG_PMB
+/*
+ * Reconfigure the initial PMB mappings setup by the hardware.
+ *
+ * When we boot in 32-bit MMU mode there are 2 PMB entries already
+ * setup for us.
+ *
+ * Entry       VPN	   PPN	    V	SZ	C	UB	WT
+ * ---------------------------------------------------------------
+ *   0	    0x80000000 0x00000000   1  512MB	1	0	1
+ *   1	    0xA0000000 0x00000000   1  512MB	0	0	0
+ *
+ * But we reprogram them here because we want complete control over
+ * our address space and the initial mappings may not map PAGE_OFFSET
+ * to __MEMORY_START (or even map all of our RAM).
+ *
+ * Once we've setup cached and uncached mappings we clear the rest of the
+ * PMB entries. This clearing also deals with the fact that PMB entries
+ * can persist across reboots. The PMB could have been left in any state
+ * when the reboot occurred, so to be safe we clear all entries and start
+ * with with a clean slate.
+ *
+ * The uncached mapping is constructed using the smallest possible
+ * mapping with a single unbufferable page. Only the kernel text needs to
+ * be covered via the uncached mapping so that certain functions can be
+ * run uncached.
+ *
+ * Drivers and the like that have previously abused the 1:1 identity
+ * mapping are unsupported in 32-bit mode and must specify their caching
+ * preference when page tables are constructed.
+ *
+ * This frees up the P2 space for more nefarious purposes.
+ *
+ * Register utilization is as follows:
+ *
+ *	r0 = PMB_DATA data field
+ *	r1 = PMB_DATA address field
+ *	r2 = PMB_ADDR data field
+ *	r3 = PMB_ADDR address field
+ *	r4 = PMB_E_SHIFT
+ *	r5 = remaining amount of RAM to map
+ *	r6 = PMB mapping size we're trying to use
+ *	r7 = cached_to_uncached
+ *	r8 = scratch register
+ *	r9 = scratch register
+ *	r10 = number of PMB entries we've setup
+ */
+
+	mov.l	.LMMUCR, r1	/* Flush the TLB */
+	mov.l	@r1, r0
+	or	#MMUCR_TI, r0
+	mov.l	r0, @r1
+
+	mov.l	.LMEMORY_SIZE, r5
+
+	mov	#PMB_E_SHIFT, r0
+	mov	#0x1, r4
+	shld	r0, r4
+
+	mov.l	.LFIRST_DATA_ENTRY, r0
+	mov.l	.LPMB_DATA, r1
+	mov.l	.LFIRST_ADDR_ENTRY, r2
+	mov.l	.LPMB_ADDR, r3
+
+	/*
+	 * First we need to walk the PMB and figure out if there are any
+	 * existing mappings that match the initial mappings VPN/PPN.
+	 * If these have already been established by the bootloader, we
+	 * don't bother setting up new entries here, and let the late PMB
+	 * initialization take care of things instead.
+	 *
+	 * Note that we may need to coalesce and merge entries in order
+	 * to reclaim more available PMB slots, which is much more than
+	 * we want to do at this early stage.
+	 */
+	mov	#0, r10
+	mov	#NR_PMB_ENTRIES, r9
+
+	mov	r1, r7		/* temporary PMB_DATA iter */
+
+.Lvalidate_existing_mappings:
+
+	mov.l	@r7, r8
+	and	r0, r8
+	cmp/eq	r0, r8		/* Check for valid __MEMORY_START mappings */
+	bt	.Lpmb_done
+
+	add	#1, r10		/* Increment the loop counter */
+	cmp/eq	r9, r10
+	bf/s	.Lvalidate_existing_mappings
+	 add	r4, r7		/* Increment to the next PMB_DATA entry */
+
+	/*
+	 * If we've fallen through, continue with setting up the initial
+	 * mappings.
+	 */
+
+	mov	r5, r7		/* cached_to_uncached */
+	mov	#0, r10
+
+#ifdef CONFIG_UNCACHED_MAPPING
+	/*
+	 * Uncached mapping
+	 */
+	mov	#(PMB_SZ_16M >> 2), r9
+	shll2	r9
+
+	mov	#(PMB_UB >> 8), r8
+	shll8	r8
+
+	or	r0, r8
+	or	r9, r8
+	mov.l	r8, @r1
+	mov	r2, r8
+	add	r7, r8
+	mov.l	r8, @r3
+
+	add	r4, r1
+	add	r4, r3
+	add	#1, r10
+#endif
+
+/*
+ * Iterate over all of the available sizes from largest to
+ * smallest for constructing the cached mapping.
+ */
+#define __PMB_ITER_BY_SIZE(size)			\
+.L##size:						\
+	mov	#(size >> 4), r6;			\
+	shll16	r6;					\
+	shll8	r6;					\
+							\
+	cmp/hi	r5, r6;					\
+	bt	9999f;					\
+							\
+	mov	#(PMB_SZ_##size##M >> 2), r9;		\
+	shll2	r9;					\
+							\
+	/*						\
+	 * Cached mapping				\
+	 */						\
+	mov	#PMB_C, r8;				\
+	or	r0, r8;					\
+	or	r9, r8;					\
+	mov.l	r8, @r1;				\
+	mov.l	r2, @r3;				\
+							\
+	/* Increment to the next PMB_DATA entry */	\
+	add	r4, r1;					\
+	/* Increment to the next PMB_ADDR entry */	\
+	add	r4, r3;					\
+	/* Increment number of PMB entries */		\
+	add	#1, r10;				\
+							\
+	sub	r6, r5;					\
+	add	r6, r0;					\
+	add	r6, r2;					\
+							\
+	bra	.L##size;				\
+9999:
+
+	__PMB_ITER_BY_SIZE(512)
+	__PMB_ITER_BY_SIZE(128)
+	__PMB_ITER_BY_SIZE(64)
+	__PMB_ITER_BY_SIZE(16)
+
+#ifdef CONFIG_UNCACHED_MAPPING
+	/*
+	 * Now that we can access it, update cached_to_uncached and
+	 * uncached_size.
+	 */
+	mov.l	.Lcached_to_uncached, r0
+	mov.l	r7, @r0
+
+	mov.l	.Luncached_size, r0
+	mov	#1, r7
+	shll16	r7
+	shll8	r7
+	mov.l	r7, @r0
+#endif
+
+	/*
+	 * Clear the remaining PMB entries.
+	 *
+	 * r3 = entry to begin clearing from
+	 * r10 = number of entries we've setup so far
+	 */
+	mov	#0, r1
+	mov	#NR_PMB_ENTRIES, r0
+
+.Lagain:
+	mov.l	r1, @r3		/* Clear PMB_ADDR entry */
+	add	#1, r10		/* Increment the loop counter */
+	cmp/eq	r0, r10
+	bf/s	.Lagain
+	 add	r4, r3		/* Increment to the next PMB_ADDR entry */
+
+	mov.l	6f, r0
+	icbi	@r0
+
+.Lpmb_done:
+#endif /* CONFIG_PMB */
+
 #ifndef CONFIG_SH_NO_BSS_INIT
 	/*
 	 * Don't clear BSS if running on slow platforms such as an RTL simulation,
@@ -131,3 +337,16 @@ ENTRY(stack_start)
 5:	.long	start_kernel
 6:	.long	sh_cpu_init
 7:	.long	init_thread_union
+
+#ifdef CONFIG_PMB
+.LPMB_ADDR:		.long	PMB_ADDR
+.LPMB_DATA:		.long	PMB_DATA
+.LFIRST_ADDR_ENTRY:	.long	PAGE_OFFSET | PMB_V
+.LFIRST_DATA_ENTRY:	.long	__MEMORY_START | PMB_V
+.LMMUCR:		.long	MMUCR
+.LMEMORY_SIZE:		.long	__MEMORY_SIZE
+#ifdef CONFIG_UNCACHED_MAPPING
+.Lcached_to_uncached:	.long	cached_to_uncached
+.Luncached_size:	.long	uncached_size
+#endif
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/head_64.S linux-libre-2.6.34-gnu1/arch/sh/kernel/head_64.S
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/head_64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/head_64.S	2010-05-16 17:17:36.000000000 -0400
@@ -220,7 +220,6 @@ clear_DTLB:
 	add.l	r22, r63, r22		/* Sign extend */
 	putcfg	r21, 0, r22		/* Set MMUDR[0].PTEH */
 
-#ifdef CONFIG_EARLY_PRINTK
 	/*
 	 * Setup a DTLB translation for SCIF phys.
 	 */
@@ -231,7 +230,6 @@ clear_DTLB:
 	movi    0xfa03, r22	/* 0xfa030000, fixed SCIF virt */
 	shori   0x0003, r22
 	putcfg  r21, 0, r22	/* PTEH last */
-#endif
 
 	/*
 	 * Set cache behaviours.
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/hw_breakpoint.c linux-libre-2.6.34-gnu1/arch/sh/kernel/hw_breakpoint.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/hw_breakpoint.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/hw_breakpoint.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,445 @@
+/*
+ * arch/sh/kernel/hw_breakpoint.c
+ *
+ * Unified kernel/user-space hardware breakpoint facility for the on-chip UBC.
+ *
+ * Copyright (C) 2009 - 2010  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/perf_event.h>
+#include <linux/hw_breakpoint.h>
+#include <linux/percpu.h>
+#include <linux/kallsyms.h>
+#include <linux/notifier.h>
+#include <linux/kprobes.h>
+#include <linux/kdebug.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <asm/hw_breakpoint.h>
+#include <asm/mmu_context.h>
+#include <asm/ptrace.h>
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for each cpus
+ */
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM]);
+
+/*
+ * A dummy placeholder for early accesses until the CPUs get a chance to
+ * register their UBCs later in the boot process.
+ */
+static struct sh_ubc ubc_dummy = { .num_events = 0 };
+
+static struct sh_ubc *sh_ubc __read_mostly = &ubc_dummy;
+
+/*
+ * Install a perf counter breakpoint.
+ *
+ * We seek a free UBC channel and use it for this breakpoint.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+	int i;
+
+	for (i = 0; i < sh_ubc->num_events; i++) {
+		struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
+
+		if (!*slot) {
+			*slot = bp;
+			break;
+		}
+	}
+
+	if (WARN_ONCE(i == sh_ubc->num_events, "Can't find any breakpoint slot"))
+		return -EBUSY;
+
+	clk_enable(sh_ubc->clk);
+	sh_ubc->enable(info, i);
+
+	return 0;
+}
+
+/*
+ * Uninstall the breakpoint contained in the given counter.
+ *
+ * First we search the debug address register it uses and then we disable
+ * it.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+void arch_uninstall_hw_breakpoint(struct perf_event *bp)
+{
+	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+	int i;
+
+	for (i = 0; i < sh_ubc->num_events; i++) {
+		struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
+
+		if (*slot == bp) {
+			*slot = NULL;
+			break;
+		}
+	}
+
+	if (WARN_ONCE(i == sh_ubc->num_events, "Can't find any breakpoint slot"))
+		return;
+
+	sh_ubc->disable(info, i);
+	clk_disable(sh_ubc->clk);
+}
+
+static int get_hbp_len(u16 hbp_len)
+{
+	unsigned int len_in_bytes = 0;
+
+	switch (hbp_len) {
+	case SH_BREAKPOINT_LEN_1:
+		len_in_bytes = 1;
+		break;
+	case SH_BREAKPOINT_LEN_2:
+		len_in_bytes = 2;
+		break;
+	case SH_BREAKPOINT_LEN_4:
+		len_in_bytes = 4;
+		break;
+	case SH_BREAKPOINT_LEN_8:
+		len_in_bytes = 8;
+		break;
+	}
+	return len_in_bytes;
+}
+
+/*
+ * Check for virtual address in user space.
+ */
+int arch_check_va_in_userspace(unsigned long va, u16 hbp_len)
+{
+	unsigned int len;
+
+	len = get_hbp_len(hbp_len);
+
+	return (va <= TASK_SIZE - len);
+}
+
+/*
+ * Check for virtual address in kernel space.
+ */
+static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
+{
+	unsigned int len;
+
+	len = get_hbp_len(hbp_len);
+
+	return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
+}
+
+int arch_bp_generic_fields(int sh_len, int sh_type,
+			   int *gen_len, int *gen_type)
+{
+	/* Len */
+	switch (sh_len) {
+	case SH_BREAKPOINT_LEN_1:
+		*gen_len = HW_BREAKPOINT_LEN_1;
+		break;
+	case SH_BREAKPOINT_LEN_2:
+		*gen_len = HW_BREAKPOINT_LEN_2;
+		break;
+	case SH_BREAKPOINT_LEN_4:
+		*gen_len = HW_BREAKPOINT_LEN_4;
+		break;
+	case SH_BREAKPOINT_LEN_8:
+		*gen_len = HW_BREAKPOINT_LEN_8;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Type */
+	switch (sh_type) {
+	case SH_BREAKPOINT_READ:
+		*gen_type = HW_BREAKPOINT_R;
+	case SH_BREAKPOINT_WRITE:
+		*gen_type = HW_BREAKPOINT_W;
+		break;
+	case SH_BREAKPOINT_RW:
+		*gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int arch_build_bp_info(struct perf_event *bp)
+{
+	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+	info->address = bp->attr.bp_addr;
+
+	/* Len */
+	switch (bp->attr.bp_len) {
+	case HW_BREAKPOINT_LEN_1:
+		info->len = SH_BREAKPOINT_LEN_1;
+		break;
+	case HW_BREAKPOINT_LEN_2:
+		info->len = SH_BREAKPOINT_LEN_2;
+		break;
+	case HW_BREAKPOINT_LEN_4:
+		info->len = SH_BREAKPOINT_LEN_4;
+		break;
+	case HW_BREAKPOINT_LEN_8:
+		info->len = SH_BREAKPOINT_LEN_8;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Type */
+	switch (bp->attr.bp_type) {
+	case HW_BREAKPOINT_R:
+		info->type = SH_BREAKPOINT_READ;
+		break;
+	case HW_BREAKPOINT_W:
+		info->type = SH_BREAKPOINT_WRITE;
+		break;
+	case HW_BREAKPOINT_W | HW_BREAKPOINT_R:
+		info->type = SH_BREAKPOINT_RW;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * Validate the arch-specific HW Breakpoint register settings
+ */
+int arch_validate_hwbkpt_settings(struct perf_event *bp,
+				  struct task_struct *tsk)
+{
+	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+	unsigned int align;
+	int ret;
+
+	ret = arch_build_bp_info(bp);
+	if (ret)
+		return ret;
+
+	ret = -EINVAL;
+
+	switch (info->len) {
+	case SH_BREAKPOINT_LEN_1:
+		align = 0;
+		break;
+	case SH_BREAKPOINT_LEN_2:
+		align = 1;
+		break;
+	case SH_BREAKPOINT_LEN_4:
+		align = 3;
+		break;
+	case SH_BREAKPOINT_LEN_8:
+		align = 7;
+		break;
+	default:
+		return ret;
+	}
+
+	/*
+	 * For kernel-addresses, either the address or symbol name can be
+	 * specified.
+	 */
+	if (info->name)
+		info->address = (unsigned long)kallsyms_lookup_name(info->name);
+
+	/*
+	 * Check that the low-order bits of the address are appropriate
+	 * for the alignment implied by len.
+	 */
+	if (info->address & align)
+		return -EINVAL;
+
+	/* Check that the virtual address is in the proper range */
+	if (tsk) {
+		if (!arch_check_va_in_userspace(info->address, info->len))
+			return -EFAULT;
+	} else {
+		if (!arch_check_va_in_kernelspace(info->address, info->len))
+			return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*
+ * Release the user breakpoints used by ptrace
+ */
+void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
+{
+	int i;
+	struct thread_struct *t = &tsk->thread;
+
+	for (i = 0; i < sh_ubc->num_events; i++) {
+		unregister_hw_breakpoint(t->ptrace_bps[i]);
+		t->ptrace_bps[i] = NULL;
+	}
+}
+
+static int __kprobes hw_breakpoint_handler(struct die_args *args)
+{
+	int cpu, i, rc = NOTIFY_STOP;
+	struct perf_event *bp;
+	unsigned int cmf, resume_mask;
+
+	/*
+	 * Do an early return if none of the channels triggered.
+	 */
+	cmf = sh_ubc->triggered_mask();
+	if (unlikely(!cmf))
+		return NOTIFY_DONE;
+
+	/*
+	 * By default, resume all of the active channels.
+	 */
+	resume_mask = sh_ubc->active_mask();
+
+	/*
+	 * Disable breakpoints during exception handling.
+	 */
+	sh_ubc->disable_all();
+
+	cpu = get_cpu();
+	for (i = 0; i < sh_ubc->num_events; i++) {
+		unsigned long event_mask = (1 << i);
+
+		if (likely(!(cmf & event_mask)))
+			continue;
+
+		/*
+		 * The counter may be concurrently released but that can only
+		 * occur from a call_rcu() path. We can then safely fetch
+		 * the breakpoint, use its callback, touch its counter
+		 * while we are in an rcu_read_lock() path.
+		 */
+		rcu_read_lock();
+
+		bp = per_cpu(bp_per_reg[i], cpu);
+		if (bp)
+			rc = NOTIFY_DONE;
+
+		/*
+		 * Reset the condition match flag to denote completion of
+		 * exception handling.
+		 */
+		sh_ubc->clear_triggered_mask(event_mask);
+
+		/*
+		 * bp can be NULL due to concurrent perf counter
+		 * removing.
+		 */
+		if (!bp) {
+			rcu_read_unlock();
+			break;
+		}
+
+		/*
+		 * Don't restore the channel if the breakpoint is from
+		 * ptrace, as it always operates in one-shot mode.
+		 */
+		if (bp->overflow_handler == ptrace_triggered)
+			resume_mask &= ~(1 << i);
+
+		perf_bp_event(bp, args->regs);
+
+		/* Deliver the signal to userspace */
+		if (arch_check_va_in_userspace(bp->attr.bp_addr,
+					       bp->attr.bp_len)) {
+			siginfo_t info;
+
+			info.si_signo = args->signr;
+			info.si_errno = notifier_to_errno(rc);
+			info.si_code = TRAP_HWBKPT;
+
+			force_sig_info(args->signr, &info, current);
+		}
+
+		rcu_read_unlock();
+	}
+
+	if (cmf == 0)
+		rc = NOTIFY_DONE;
+
+	sh_ubc->enable_all(resume_mask);
+
+	put_cpu();
+
+	return rc;
+}
+
+BUILD_TRAP_HANDLER(breakpoint)
+{
+	unsigned long ex = lookup_exception_vector();
+	TRAP_HANDLER_DECL;
+
+	notify_die(DIE_BREAKPOINT, "breakpoint", regs, 0, ex, SIGTRAP);
+}
+
+/*
+ * Handle debug exception notifications.
+ */
+int __kprobes hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+				    unsigned long val, void *data)
+{
+	struct die_args *args = data;
+
+	if (val != DIE_BREAKPOINT)
+		return NOTIFY_DONE;
+
+	/*
+	 * If the breakpoint hasn't been triggered by the UBC, it's
+	 * probably from a debugger, so don't do anything more here.
+	 *
+	 * This also permits the UBC interface clock to remain off for
+	 * non-UBC breakpoints, as we don't need to check the triggered
+	 * or active channel masks.
+	 */
+	if (args->trapnr != sh_ubc->trap_nr)
+		return NOTIFY_DONE;
+
+	return hw_breakpoint_handler(data);
+}
+
+void hw_breakpoint_pmu_read(struct perf_event *bp)
+{
+	/* TODO */
+}
+
+void hw_breakpoint_pmu_unthrottle(struct perf_event *bp)
+{
+	/* TODO */
+}
+
+int register_sh_ubc(struct sh_ubc *ubc)
+{
+	/* Bail if it's already assigned */
+	if (sh_ubc != &ubc_dummy)
+		return -EBUSY;
+	sh_ubc = ubc;
+
+	pr_info("HW Breakpoints: %s UBC support registered\n", ubc->name);
+
+	WARN_ON(ubc->num_events > HBP_NUM);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/idle.c linux-libre-2.6.34-gnu1/arch/sh/kernel/idle.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/idle.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/idle.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,10 +20,9 @@
 #include <asm/system.h>
 #include <asm/atomic.h>
 
-static int hlt_counter;
 void (*pm_idle)(void) = NULL;
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
+
+static int hlt_counter;
 
 static int __init nohlt_setup(char *__unused)
 {
@@ -113,7 +112,7 @@ void cpu_idle(void)
 	}
 }
 
-void __cpuinit select_idle_routine(void)
+void __init select_idle_routine(void)
 {
 	/*
 	 * If a platform has set its own idle routine, leave it alone.
@@ -131,6 +130,15 @@ static void do_nothing(void *unused)
 {
 }
 
+void stop_this_cpu(void *unused)
+{
+	local_irq_disable();
+	cpu_clear(smp_processor_id(), cpu_online_map);
+
+	for (;;)
+		cpu_sleep();
+}
+
 /*
  * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
  * pm_idle and update to new pm_idle value. Required while changing pm_idle
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/io_trapped.c linux-libre-2.6.34-gnu1/arch/sh/kernel/io_trapped.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/io_trapped.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/io_trapped.c	2010-05-16 17:17:36.000000000 -0400
@@ -184,31 +184,31 @@ static unsigned long long copy_word(unsi
 
 	switch (src_len) {
 	case 1:
-		tmp = ctrl_inb(src_addr);
+		tmp = __raw_readb(src_addr);
 		break;
 	case 2:
-		tmp = ctrl_inw(src_addr);
+		tmp = __raw_readw(src_addr);
 		break;
 	case 4:
-		tmp = ctrl_inl(src_addr);
+		tmp = __raw_readl(src_addr);
 		break;
 	case 8:
-		tmp = ctrl_inq(src_addr);
+		tmp = __raw_readq(src_addr);
 		break;
 	}
 
 	switch (dst_len) {
 	case 1:
-		ctrl_outb(tmp, dst_addr);
+		__raw_writeb(tmp, dst_addr);
 		break;
 	case 2:
-		ctrl_outw(tmp, dst_addr);
+		__raw_writew(tmp, dst_addr);
 		break;
 	case 4:
-		ctrl_outl(tmp, dst_addr);
+		__raw_writel(tmp, dst_addr);
 		break;
 	case 8:
-		ctrl_outq(tmp, dst_addr);
+		__raw_writeq(tmp, dst_addr);
 		break;
 	}
 
@@ -271,6 +271,8 @@ int handle_trapped_io(struct pt_regs *re
 	insn_size_t instruction;
 	int tmp;
 
+	if (trapped_io_disable)
+		return 0;
 	if (!lookup_tiop(address))
 		return 0;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/kgdb.c linux-libre-2.6.34-gnu1/arch/sh/kernel/kgdb.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/kgdb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/kgdb.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * SuperH KGDB support
  *
- * Copyright (C) 2008  Paul Mundt
+ * Copyright (C) 2008 - 2009  Paul Mundt
  *
  * Single stepping taken from the old stub by Henry Bell and Jeremy Siegel.
  *
@@ -251,24 +251,60 @@ BUILD_TRAP_HANDLER(singlestep)
 	local_irq_restore(flags);
 }
 
+static int __kgdb_notify(struct die_args *args, unsigned long cmd)
+{
+	int ret;
 
-BUILD_TRAP_HANDLER(breakpoint)
+	switch (cmd) {
+	case DIE_BREAKPOINT:
+		/*
+		 * This means a user thread is single stepping
+		 * a system call which should be ignored
+		 */
+		if (test_thread_flag(TIF_SINGLESTEP))
+			return NOTIFY_DONE;
+
+		ret = kgdb_handle_exception(args->trapnr & 0xff, args->signr,
+					    args->err, args->regs);
+		if (ret)
+			return NOTIFY_DONE;
+
+		break;
+	}
+
+	return NOTIFY_STOP;
+}
+
+static int
+kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
 {
 	unsigned long flags;
-	TRAP_HANDLER_DECL;
+	int ret;
 
 	local_irq_save(flags);
-	kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs);
+	ret = __kgdb_notify(ptr, cmd);
 	local_irq_restore(flags);
+
+	return ret;
 }
 
+static struct notifier_block kgdb_notifier = {
+	.notifier_call	= kgdb_notify,
+
+	/*
+	 * Lowest-prio notifier priority, we want to be notified last:
+	 */
+	.priority	= -INT_MAX,
+};
+
 int kgdb_arch_init(void)
 {
-	return 0;
+	return register_die_notifier(&kgdb_notifier);
 }
 
 void kgdb_arch_exit(void)
 {
+	unregister_die_notifier(&kgdb_notifier);
 }
 
 struct kgdb_arch arch_kgdb_ops = {
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/kprobes.c linux-libre-2.6.34-gnu1/arch/sh/kernel/kprobes.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/kprobes.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/kprobes.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/ptrace.h>
 #include <linux/preempt.h>
 #include <linux/kdebug.h>
+#include <linux/slab.h>
 #include <asm/cacheflush.h>
 #include <asm/uaccess.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/machine_kexec.c linux-libre-2.6.34-gnu1/arch/sh/kernel/machine_kexec.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/machine_kexec.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/machine_kexec.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,8 @@
 #include <asm/mmu_context.h>
 #include <asm/io.h>
 #include <asm/cacheflush.h>
+#include <asm/sh_bios.h>
+#include <asm/reboot.h>
 
 typedef void (*relocate_new_kernel_t)(unsigned long indirection_page,
 				      unsigned long reboot_code_buffer,
@@ -28,15 +30,11 @@ typedef void (*relocate_new_kernel_t)(un
 
 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)
-{
-}
-
-void machine_crash_shutdown(struct pt_regs *regs)
+void native_machine_crash_shutdown(struct pt_regs *regs)
 {
+	/* Nothing to do for UP, but definitely broken for SMP.. */
 }
 
 /*
@@ -117,11 +115,7 @@ void machine_kexec(struct kimage *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
+	sh_bios_vbr_reload();
 
 	/* now call it */
 	rnk = (relocate_new_kernel_t) reboot_code_buffer;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/Makefile linux-libre-2.6.34-gnu1/arch/sh/kernel/Makefile
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -13,8 +13,9 @@ CFLAGS_REMOVE_return_address.o = -pg
 
 obj-y	:= debugtraps.o dma-nommu.o dumpstack.o 			\
 	   idle.o io.o io_generic.o irq.o				\
-	   irq_$(BITS).o machvec.o nmi_debug.o process_$(BITS).o 	\
-	   ptrace_$(BITS).o return_address.o				\
+	   irq_$(BITS).o machvec.o nmi_debug.o process.o		\
+	   process_$(BITS).o ptrace_$(BITS).o				\
+	   reboot.o return_address.o					\
 	   setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o		\
 	   syscalls_$(BITS).o time.o topology.o traps.o			\
 	   traps_$(BITS).o unwinder.o
@@ -22,7 +23,7 @@ obj-y	:= debugtraps.o dma-nommu.o dumpst
 obj-y				+= cpu/
 obj-$(CONFIG_VSYSCALL)		+= vsyscall/
 obj-$(CONFIG_SMP)		+= smp.o
-obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o early_printk.o
+obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o
 obj-$(CONFIG_KGDB)		+= kgdb.o
 obj-$(CONFIG_SH_CPU_FREQ)	+= cpufreq.o
 obj-$(CONFIG_MODULES)		+= sh_ksyms_$(BITS).o module.o
@@ -39,6 +40,7 @@ obj-$(CONFIG_HIBERNATION)	+= swsusp.o
 obj-$(CONFIG_DWARF_UNWINDER)	+= dwarf.o
 obj-$(CONFIG_PERF_EVENTS)	+= perf_event.o perf_callchain.o
 
+obj-$(CONFIG_HAVE_HW_BREAKPOINT)		+= hw_breakpoint.o
 obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)	+= localtimer.o
 
 EXTRA_CFLAGS += -Werror
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/perf_callchain.c linux-libre-2.6.34-gnu1/arch/sh/kernel/perf_callchain.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/perf_callchain.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/perf_callchain.c	2010-05-16 17:17:36.000000000 -0400
@@ -68,9 +68,6 @@ perf_do_callchain(struct pt_regs *regs,
 
 	is_user = user_mode(regs);
 
-	if (!current || current->pid == 0)
-		return;
-
 	if (is_user && current->state != TASK_RUNNING)
 		return;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/perf_event.c linux-libre-2.6.34-gnu1/arch/sh/kernel/perf_event.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/perf_event.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/perf_event.c	2010-05-16 17:17:36.000000000 -0400
@@ -275,13 +275,30 @@ const struct pmu *hw_perf_event_init(str
 	return &pmu;
 }
 
-void hw_perf_event_setup(int cpu)
+static void sh_pmu_setup(int cpu)
 {
 	struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
 
 	memset(cpuhw, 0, sizeof(struct cpu_hw_events));
 }
 
+static int __cpuinit
+sh_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (long)hcpu;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+		sh_pmu_setup(cpu);
+		break;
+
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
 void hw_perf_enable(void)
 {
 	if (!sh_pmu_initialized())
@@ -298,7 +315,7 @@ void hw_perf_disable(void)
 	sh_pmu->disable_all();
 }
 
-int register_sh_pmu(struct sh_pmu *pmu)
+int __cpuinit register_sh_pmu(struct sh_pmu *pmu)
 {
 	if (sh_pmu)
 		return -EBUSY;
@@ -308,5 +325,6 @@ int register_sh_pmu(struct sh_pmu *pmu)
 
 	WARN_ON(pmu->num_events > MAX_HWEVENTS);
 
+	perf_cpu_notifier(sh_pmu_notifier);
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/process_32.c linux-libre-2.6.34-gnu1/arch/sh/kernel/process_32.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/process_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/process_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,66 +15,17 @@
  */
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/elfcore.h>
-#include <linux/pm.h>
 #include <linux/kallsyms.h>
-#include <linux/kexec.h>
-#include <linux/kdebug.h>
-#include <linux/tick.h>
-#include <linux/reboot.h>
 #include <linux/fs.h>
 #include <linux/ftrace.h>
-#include <linux/preempt.h>
+#include <linux/hw_breakpoint.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
-#include <asm/pgalloc.h>
 #include <asm/system.h>
-#include <asm/ubc.h>
 #include <asm/fpu.h>
 #include <asm/syscalls.h>
-#include <asm/watchdog.h>
-
-int ubc_usercnt = 0;
-
-#ifdef CONFIG_32BIT
-static void watchdog_trigger_immediate(void)
-{
-	sh_wdt_write_cnt(0xFF);
-	sh_wdt_write_csr(0xC2);
-}
-
-void machine_restart(char * __unused)
-{
-	local_irq_disable();
-
-	/* Use watchdog timer to trigger reset */
-	watchdog_trigger_immediate();
-
-	while (1)
-		cpu_sleep();
-}
-#else
-void machine_restart(char * __unused)
-{
-	/* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
-	asm volatile("ldc %0, sr\n\t"
-		     "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001));
-}
-#endif
-
-void machine_halt(void)
-{
-	local_irq_disable();
-
-	while (1)
-		cpu_sleep();
-}
-
-void machine_power_off(void)
-{
-	if (pm_power_off)
-		pm_power_off();
-}
 
 void show_regs(struct pt_regs * regs)
 {
@@ -91,7 +42,7 @@ void show_regs(struct pt_regs * regs)
 	printk("PC  : %08lx SP  : %08lx SR  : %08lx ",
 	       regs->pc, regs->regs[15], regs->sr);
 #ifdef CONFIG_MMU
-	printk("TEA : %08x\n", ctrl_inl(MMU_TEA));
+	printk("TEA : %08x\n", __raw_readl(MMU_TEA));
 #else
 	printk("\n");
 #endif
@@ -147,21 +98,34 @@ int kernel_thread(int (*fn)(void *), voi
 }
 EXPORT_SYMBOL(kernel_thread);
 
+void start_thread(struct pt_regs *regs, unsigned long new_pc,
+		  unsigned long new_sp)
+{
+	set_fs(USER_DS);
+
+	regs->pr = 0;
+	regs->sr = SR_FD;
+	regs->pc = new_pc;
+	regs->regs[15] = new_sp;
+
+	free_thread_xstate(current);
+}
+EXPORT_SYMBOL(start_thread);
+
 /*
  * Free current thread data structures etc..
  */
 void exit_thread(void)
 {
-	if (current->thread.ubc_pc) {
-		current->thread.ubc_pc = 0;
-		ubc_usercnt -= 1;
-	}
 }
 
 void flush_thread(void)
 {
-#if defined(CONFIG_SH_FPU)
 	struct task_struct *tsk = current;
+
+	flush_ptrace_hw_breakpoint(tsk);
+
+#if defined(CONFIG_SH_FPU)
 	/* Forget lazy FPU state */
 	clear_fpu(tsk, task_pt_regs(tsk));
 	clear_used_math();
@@ -209,11 +173,10 @@ int copy_thread(unsigned long clone_flag
 {
 	struct thread_info *ti = task_thread_info(p);
 	struct pt_regs *childregs;
+
 #if defined(CONFIG_SH_DSP)
 	struct task_struct *tsk = current;
-#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);
@@ -244,53 +207,11 @@ int copy_thread(unsigned long clone_flag
 	p->thread.sp = (unsigned long) childregs;
 	p->thread.pc = (unsigned long) ret_from_fork;
 
-	p->thread.ubc_pc = 0;
+	memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
 
 	return 0;
 }
 
-/* Tracing by user break controller.  */
-static void ubc_set_tracing(int asid, unsigned long pc)
-{
-#if defined(CONFIG_CPU_SH4A)
-	unsigned long val;
-
-	val = (UBC_CBR_ID_INST | UBC_CBR_RW_READ | UBC_CBR_CE);
-	val |= (UBC_CBR_AIE | UBC_CBR_AIV_SET(asid));
-
-	ctrl_outl(val, UBC_CBR0);
-	ctrl_outl(pc,  UBC_CAR0);
-	ctrl_outl(0x0, UBC_CAMR0);
-	ctrl_outl(0x0, UBC_CBCR);
-
-	val = (UBC_CRR_RES | UBC_CRR_PCB | UBC_CRR_BIE);
-	ctrl_outl(val, UBC_CRR0);
-
-	/* Read UBC register that we wrote last, for checking update */
-	val = ctrl_inl(UBC_CRR0);
-
-#else	/* CONFIG_CPU_SH4A */
-	ctrl_outl(pc, UBC_BARA);
-
-#ifdef CONFIG_MMU
-	ctrl_outb(asid, UBC_BASRA);
-#endif
-
-	ctrl_outl(0, UBC_BAMRA);
-
-	if (current_cpu_data.type == CPU_SH7729 ||
-	    current_cpu_data.type == CPU_SH7710 ||
-	    current_cpu_data.type == CPU_SH7712 ||
-	    current_cpu_data.type == CPU_SH7203){
-		ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
-		ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR);
-	} else {
-		ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA);
-		ctrl_outw(BRCR_PCBA, UBC_BRCR);
-	}
-#endif	/* CONFIG_CPU_SH4A */
-}
-
 /*
  *	switch_to(x,y) should switch tasks from x to y.
  *
@@ -304,7 +225,7 @@ __switch_to(struct task_struct *prev, st
 
 	/* we're going to use this soon, after a few expensive things */
 	if (next->fpu_counter > 5)
-		prefetch(&next_t->fpu.hard);
+		prefetch(next_t->xstate);
 
 #ifdef CONFIG_MMU
 	/*
@@ -316,32 +237,13 @@ __switch_to(struct task_struct *prev, st
 		     : "r" (task_thread_info(next)));
 #endif
 
-	/* If no tasks are using the UBC, we're done */
-	if (ubc_usercnt == 0)
-		/* If no tasks are using the UBC, we're done */;
-	else if (next->thread.ubc_pc && next->mm) {
-		int asid = 0;
-#ifdef CONFIG_MMU
-		asid |= cpu_asid(smp_processor_id(), next->mm);
-#endif
-		ubc_set_tracing(asid, next->thread.ubc_pc);
-	} else {
-#if defined(CONFIG_CPU_SH4A)
-		ctrl_outl(UBC_CBR_INIT, UBC_CBR0);
-		ctrl_outl(UBC_CRR_INIT, UBC_CRR0);
-#else
-		ctrl_outw(0, UBC_BBRA);
-		ctrl_outw(0, UBC_BBRB);
-#endif
-	}
-
 	/*
 	 * If the task has used fpu the last 5 timeslices, just do a full
 	 * restore of the math state immediately to avoid the trap; the
 	 * chances of needing FPU soon are obviously high now
 	 */
 	if (next->fpu_counter > 5)
-		fpu_state_restore(task_pt_regs(next));
+		__fpu_state_restore();
 
 	return prev;
 }
@@ -434,20 +336,3 @@ unsigned long get_wchan(struct task_stru
 
 	return pc;
 }
-
-asmlinkage void break_point_trap(void)
-{
-	/* Clear tracing.  */
-#if defined(CONFIG_CPU_SH4A)
-	ctrl_outl(UBC_CBR_INIT, UBC_CBR0);
-	ctrl_outl(UBC_CRR_INIT, UBC_CRR0);
-#else
-	ctrl_outw(0, UBC_BBRA);
-	ctrl_outw(0, UBC_BBRB);
-	ctrl_outl(0, UBC_BRCR);
-#endif
-	current->thread.ubc_pc = 0;
-	ubc_usercnt -= 1;
-
-	force_sig(SIGTRAP, current);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/process_64.c linux-libre-2.6.34-gnu1/arch/sh/kernel/process_64.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/process_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/process_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/fs.h>
 #include <linux/ptrace.h>
 #include <linux/reboot.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/io.h>
@@ -32,30 +33,7 @@
 
 struct task_struct *last_task_used_math = NULL;
 
-void machine_restart(char * __unused)
-{
-	extern void phys_stext(void);
-
-	phys_stext();
-}
-
-void machine_halt(void)
-{
-	for (;;);
-}
-
-void machine_power_off(void)
-{
-	__asm__ __volatile__ (
-		"sleep\n\t"
-		"synci\n\t"
-		"nop;nop;nop;nop\n\t"
-	);
-
-	panic("Unexpected wakeup!\n");
-}
-
-void show_regs(struct pt_regs * regs)
+void show_regs(struct pt_regs *regs)
 {
 	unsigned long long ah, al, bh, bl, ch, cl;
 
@@ -410,7 +388,7 @@ int dump_fpu(struct pt_regs *regs, elf_f
 			regs->sr |= SR_FD;
 		}
 
-		memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu));
+		memcpy(fpu, &tsk->thread.xstate->hardfpu, sizeof(*fpu));
 	}
 
 	return fpvalid;
@@ -527,13 +505,6 @@ out:
 	return error;
 }
 
-/*
- * These bracket the sleeping functions..
- */
-extern void interruptible_sleep_on(wait_queue_head_t *q);
-
-#define mid_sched	((unsigned long) interruptible_sleep_on)
-
 #ifdef CONFIG_FRAME_POINTER
 static int in_sh64_switch_to(unsigned long pc)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/process.c linux-libre-2.6.34-gnu1/arch/sh/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/process.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,101 @@
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+
+struct kmem_cache *task_xstate_cachep = NULL;
+unsigned int xstate_size;
+
+int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
+{
+	*dst = *src;
+
+	if (src->thread.xstate) {
+		dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
+						      GFP_KERNEL);
+		if (!dst->thread.xstate)
+			return -ENOMEM;
+		memcpy(dst->thread.xstate, src->thread.xstate, xstate_size);
+	}
+
+	return 0;
+}
+
+void free_thread_xstate(struct task_struct *tsk)
+{
+	if (tsk->thread.xstate) {
+		kmem_cache_free(task_xstate_cachep, tsk->thread.xstate);
+		tsk->thread.xstate = NULL;
+	}
+}
+
+#if THREAD_SHIFT < PAGE_SHIFT
+static struct kmem_cache *thread_info_cache;
+
+struct thread_info *alloc_thread_info(struct task_struct *tsk)
+{
+	struct thread_info *ti;
+
+	ti = kmem_cache_alloc(thread_info_cache, GFP_KERNEL);
+	if (unlikely(ti == NULL))
+		return NULL;
+#ifdef CONFIG_DEBUG_STACK_USAGE
+	memset(ti, 0, THREAD_SIZE);
+#endif
+	return ti;
+}
+
+void free_thread_info(struct thread_info *ti)
+{
+	free_thread_xstate(ti->task);
+	kmem_cache_free(thread_info_cache, ti);
+}
+
+void thread_info_cache_init(void)
+{
+	thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE,
+					      THREAD_SIZE, SLAB_PANIC, NULL);
+}
+#else
+struct thread_info *alloc_thread_info(struct task_struct *tsk)
+{
+#ifdef CONFIG_DEBUG_STACK_USAGE
+	gfp_t mask = GFP_KERNEL | __GFP_ZERO;
+#else
+	gfp_t mask = GFP_KERNEL;
+#endif
+	return (struct thread_info *)__get_free_pages(mask, THREAD_SIZE_ORDER);
+}
+
+void free_thread_info(struct thread_info *ti)
+{
+	free_thread_xstate(ti->task);
+	free_pages((unsigned long)ti, THREAD_SIZE_ORDER);
+}
+#endif /* THREAD_SHIFT < PAGE_SHIFT */
+
+void arch_task_cache_init(void)
+{
+	if (!xstate_size)
+		return;
+
+	task_xstate_cachep = kmem_cache_create("task_xstate", xstate_size,
+					       __alignof__(union thread_xstate),
+					       SLAB_PANIC | SLAB_NOTRACK, NULL);
+}
+
+#ifdef CONFIG_SH_FPU_EMU
+# define HAVE_SOFTFP	1
+#else
+# define HAVE_SOFTFP	0
+#endif
+
+void init_thread_xstate(void)
+{
+	if (boot_cpu_data.flags & CPU_HAS_FPU)
+		xstate_size = sizeof(struct sh_fpu_hard_struct);
+	else if (HAVE_SOFTFP)
+		xstate_size = sizeof(struct sh_fpu_soft_struct);
+	else
+		xstate_size = 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/ptrace_32.c linux-libre-2.6.34-gnu1/arch/sh/kernel/ptrace_32.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/ptrace_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/ptrace_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  * SuperH process tracing
  *
  * Copyright (C) 1999, 2000  Kaz Kojima & Niibe Yutaka
- * Copyright (C) 2002 - 2008  Paul Mundt
+ * Copyright (C) 2002 - 2009  Paul Mundt
  *
  * Audit support by Yuichi Nakamura <ynakam@hitachisoft.jp>
  *
@@ -17,7 +17,6 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
-#include <linux/slab.h>
 #include <linux/security.h>
 #include <linux/signal.h>
 #include <linux/io.h>
@@ -26,6 +25,7 @@
 #include <linux/tracehook.h>
 #include <linux/elf.h>
 #include <linux/regset.h>
+#include <linux/hw_breakpoint.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
@@ -63,33 +63,64 @@ static inline int put_stack_long(struct
 	return 0;
 }
 
-void user_enable_single_step(struct task_struct *child)
+void ptrace_triggered(struct perf_event *bp, int nmi,
+		      struct perf_sample_data *data, struct pt_regs *regs)
 {
-	/* Next scheduling will set up UBC */
-	if (child->thread.ubc_pc == 0)
-		ubc_usercnt += 1;
+	struct perf_event_attr attr;
 
-	child->thread.ubc_pc = get_stack_long(child,
-				offsetof(struct pt_regs, pc));
+	/*
+	 * Disable the breakpoint request here since ptrace has defined a
+	 * one-shot behaviour for breakpoint exceptions.
+	 */
+	attr = bp->attr;
+	attr.disabled = true;
+	modify_user_hw_breakpoint(bp, &attr);
+}
+
+static int set_single_step(struct task_struct *tsk, unsigned long addr)
+{
+	struct thread_struct *thread = &tsk->thread;
+	struct perf_event *bp;
+	struct perf_event_attr attr;
+
+	bp = thread->ptrace_bps[0];
+	if (!bp) {
+		hw_breakpoint_init(&attr);
+
+		attr.bp_addr = addr;
+		attr.bp_len = HW_BREAKPOINT_LEN_2;
+		attr.bp_type = HW_BREAKPOINT_R;
+
+		bp = register_user_hw_breakpoint(&attr, ptrace_triggered, tsk);
+		if (IS_ERR(bp))
+			return PTR_ERR(bp);
+
+		thread->ptrace_bps[0] = bp;
+	} else {
+		int err;
+
+		attr = bp->attr;
+		attr.bp_addr = addr;
+		err = modify_user_hw_breakpoint(bp, &attr);
+		if (unlikely(err))
+			return err;
+	}
+
+	return 0;
+}
+
+void user_enable_single_step(struct task_struct *child)
+{
+	unsigned long pc = get_stack_long(child, offsetof(struct pt_regs, pc));
 
 	set_tsk_thread_flag(child, TIF_SINGLESTEP);
+
+	set_single_step(child, pc);
 }
 
 void user_disable_single_step(struct task_struct *child)
 {
 	clear_tsk_thread_flag(child, TIF_SINGLESTEP);
-
-	/*
-	 * Ensure the UBC is not programmed at the next context switch.
-	 *
-	 * Normally this is not needed but there are sequences such as
-	 * singlestep, signal delivery, and continue that leave the
-	 * ubc_pc non-zero leading to spurious SIGTRAPs.
-	 */
-	if (child->thread.ubc_pc != 0) {
-		ubc_usercnt -= 1;
-		child->thread.ubc_pc = 0;
-	}
 }
 
 /*
@@ -163,10 +194,10 @@ int fpregs_get(struct task_struct *targe
 
 	if ((boot_cpu_data.flags & CPU_HAS_FPU))
 		return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-					   &target->thread.fpu.hard, 0, -1);
+					   &target->thread.xstate->hardfpu, 0, -1);
 
 	return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-				   &target->thread.fpu.soft, 0, -1);
+				   &target->thread.xstate->softfpu, 0, -1);
 }
 
 static int fpregs_set(struct task_struct *target,
@@ -184,10 +215,10 @@ static int fpregs_set(struct task_struct
 
 	if ((boot_cpu_data.flags & CPU_HAS_FPU))
 		return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-					  &target->thread.fpu.hard, 0, -1);
+					  &target->thread.xstate->hardfpu, 0, -1);
 
 	return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-				  &target->thread.fpu.soft, 0, -1);
+				  &target->thread.xstate->softfpu, 0, -1);
 }
 
 static int fpregs_active(struct task_struct *target,
@@ -333,7 +364,7 @@ long arch_ptrace(struct task_struct *chi
 				else
 					tmp = 0;
 			} else
-				tmp = ((long *)&child->thread.fpu)
+				tmp = ((long *)child->thread.xstate)
 					[(addr - (long)&dummy->fpu) >> 2];
 		} else if (addr == (long) &dummy->u_fpvalid)
 			tmp = !!tsk_used_math(child);
@@ -362,7 +393,7 @@ long arch_ptrace(struct task_struct *chi
 		else if (addr >= (long) &dummy->fpu &&
 			 addr < (long) &dummy->u_fpvalid) {
 			set_stopped_child_used_math(child);
-			((long *)&child->thread.fpu)
+			((long *)child->thread.xstate)
 				[(addr - (long)&dummy->fpu) >> 2] = data;
 			ret = 0;
 		} else if (addr == (long) &dummy->u_fpvalid) {
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/ptrace_64.c linux-libre-2.6.34-gnu1/arch/sh/kernel/ptrace_64.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/ptrace_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/ptrace_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -88,7 +88,7 @@ get_fpu_long(struct task_struct *task, u
 		regs->sr |= SR_FD;
 	}
 
-	tmp = ((long *)&task->thread.fpu)[addr / sizeof(unsigned long)];
+	tmp = ((long *)task->thread.xstate)[addr / sizeof(unsigned long)];
 	return tmp;
 }
 
@@ -114,8 +114,7 @@ put_fpu_long(struct task_struct *task, u
 	regs = (struct pt_regs*)((unsigned char *)task + THREAD_SIZE) - 1;
 
 	if (!tsk_used_math(task)) {
-		fpinit(&task->thread.fpu.hard);
-		set_stopped_child_used_math(task);
+		init_fpu(task);
 	} else if (last_task_used_math == task) {
 		enable_fpu();
 		save_fpu(task);
@@ -124,7 +123,7 @@ put_fpu_long(struct task_struct *task, u
 		regs->sr |= SR_FD;
 	}
 
-	((long *)&task->thread.fpu)[addr / sizeof(unsigned long)] = data;
+	((long *)task->thread.xstate)[addr / sizeof(unsigned long)] = data;
 	return 0;
 }
 
@@ -226,7 +225,7 @@ int fpregs_get(struct task_struct *targe
 		return ret;
 
 	return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-				   &target->thread.fpu.hard, 0, -1);
+				   &target->thread.xstate->hardfpu, 0, -1);
 }
 
 static int fpregs_set(struct task_struct *target,
@@ -243,7 +242,7 @@ static int fpregs_set(struct task_struct
 	set_stopped_child_used_math(target);
 
 	return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-				  &target->thread.fpu.hard, 0, -1);
+				  &target->thread.xstate->hardfpu, 0, -1);
 }
 
 static int fpregs_active(struct task_struct *target,
@@ -486,9 +485,10 @@ asmlinkage void do_single_step(unsigned
 }
 
 /* Called with interrupts disabled */
-asmlinkage void do_software_break_point(unsigned long long vec,
-					struct pt_regs *regs)
+BUILD_TRAP_HANDLER(breakpoint)
 {
+	TRAP_HANDLER_DECL;
+
 	/* We need to forward step the PC, to counteract the backstep done
 	   in signal.c. */
 	local_irq_enable();
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/reboot.c linux-libre-2.6.34-gnu1/arch/sh/kernel/reboot.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/reboot.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/reboot.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,98 @@
+#include <linux/pm.h>
+#include <linux/kexec.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/module.h>
+#ifdef CONFIG_SUPERH32
+#include <asm/watchdog.h>
+#endif
+#include <asm/addrspace.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
+
+#ifdef CONFIG_SUPERH32
+static void watchdog_trigger_immediate(void)
+{
+	sh_wdt_write_cnt(0xFF);
+	sh_wdt_write_csr(0xC2);
+}
+#endif
+
+static void native_machine_restart(char * __unused)
+{
+	local_irq_disable();
+
+	/* Address error with SR.BL=1 first. */
+	trigger_address_error();
+
+#ifdef CONFIG_SUPERH32
+	/* If that fails or is unsupported, go for the watchdog next. */
+	watchdog_trigger_immediate();
+#endif
+
+	/*
+	 * Give up and sleep.
+	 */
+	while (1)
+		cpu_sleep();
+}
+
+static void native_machine_shutdown(void)
+{
+	smp_send_stop();
+}
+
+static void native_machine_power_off(void)
+{
+	if (pm_power_off)
+		pm_power_off();
+}
+
+static void native_machine_halt(void)
+{
+	/* stop other cpus */
+	machine_shutdown();
+
+	/* stop this cpu */
+	stop_this_cpu(NULL);
+}
+
+struct machine_ops machine_ops = {
+	.power_off	= native_machine_power_off,
+	.shutdown	= native_machine_shutdown,
+	.restart	= native_machine_restart,
+	.halt		= native_machine_halt,
+#ifdef CONFIG_KEXEC
+	.crash_shutdown = native_machine_crash_shutdown,
+#endif
+};
+
+void machine_power_off(void)
+{
+	machine_ops.power_off();
+}
+
+void machine_shutdown(void)
+{
+	machine_ops.shutdown();
+}
+
+void machine_restart(char *cmd)
+{
+	machine_ops.restart(cmd);
+}
+
+void machine_halt(void)
+{
+	machine_ops.halt();
+}
+
+#ifdef CONFIG_KEXEC
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+	machine_ops.crash_shutdown(regs);
+}
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/return_address.c linux-libre-2.6.34-gnu1/arch/sh/kernel/return_address.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/return_address.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/return_address.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  * for more details.
  */
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <asm/dwarf.h>
 
 #ifdef CONFIG_DWARF_UNWINDER
@@ -52,3 +53,5 @@ void *return_address(unsigned int depth)
 }
 
 #endif
+
+EXPORT_SYMBOL_GPL(return_address);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/setup.c linux-libre-2.6.34-gnu1/arch/sh/kernel/setup.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -421,6 +421,8 @@ void __init setup_arch(char **cmdline_p)
 
 	parse_early_param();
 
+	uncached_init();
+
 	plat_early_device_setup();
 
 	/* Let earlyprintk output early console messages */
@@ -441,7 +443,7 @@ void __init setup_arch(char **cmdline_p)
 
 	nodes_clear(node_online_map);
 
-	/* Setup bootmem with available RAM */
+	pmb_init();
 	lmb_init();
 	setup_memory();
 	sparse_init();
@@ -449,17 +451,14 @@ void __init setup_arch(char **cmdline_p)
 #ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
 #endif
+	paging_init();
+
+	ioremap_fixed_init();
 
 	/* Perform the machine specific initialisation */
 	if (likely(sh_mv.mv_setup))
 		sh_mv.mv_setup(cmdline_p);
 
-	paging_init();
-
-#ifdef CONFIG_PMB_ENABLE
-	pmb_init();
-#endif
-
 #ifdef CONFIG_SMP
 	plat_smp_setup();
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/sh_bios.c linux-libre-2.6.34-gnu1/arch/sh/kernel/sh_bios.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/sh_bios.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/sh_bios.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,19 +1,30 @@
 /*
- *  linux/arch/sh/kernel/sh_bios.c
  *  C interface for trapping into the standard LinuxSH BIOS.
  *
  *  Copyright (C) 2000 Greg Banks, Mitch Davis
+ *  Copyright (C) 1999, 2000  Niibe Yutaka
+ *  Copyright (C) 2002  M. R. Brown
+ *  Copyright (C) 2004 - 2010  Paul Mundt
  *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  */
 #include <linux/module.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/delay.h>
 #include <asm/sh_bios.h>
 
 #define BIOS_CALL_CONSOLE_WRITE		0
 #define BIOS_CALL_ETH_NODE_ADDR		10
 #define BIOS_CALL_SHUTDOWN		11
-#define BIOS_CALL_CHAR_OUT		0x1f	/* TODO: hack */
 #define BIOS_CALL_GDB_DETACH		0xff
 
+void *gdb_vbr_vector = NULL;
+
 static inline long sh_bios_call(long func, long arg0, long arg1, long arg2,
 				    long arg3)
 {
@@ -23,6 +34,9 @@ static inline long sh_bios_call(long fun
 	register long r6 __asm__("r6") = arg2;
 	register long r7 __asm__("r7") = arg3;
 
+	if (!gdb_vbr_vector)
+		return -ENOSYS;
+
 	__asm__ __volatile__("trapa	#0x3f":"=z"(r0)
 			     :"0"(r0), "r"(r4), "r"(r5), "r"(r6), "r"(r7)
 			     :"memory");
@@ -34,11 +48,6 @@ void sh_bios_console_write(const char *b
 	sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0);
 }
 
-void sh_bios_char_out(char ch)
-{
-	sh_bios_call(BIOS_CALL_CHAR_OUT, ch, 0, 0, 0);
-}
-
 void sh_bios_gdb_detach(void)
 {
 	sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0);
@@ -55,3 +64,109 @@ void sh_bios_shutdown(unsigned int how)
 {
 	sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0);
 }
+
+/*
+ * Read the old value of the VBR register to initialise the vector
+ * through which debug and BIOS traps are delegated by the Linux trap
+ * handler.
+ */
+void sh_bios_vbr_init(void)
+{
+	unsigned long vbr;
+
+	if (unlikely(gdb_vbr_vector))
+		return;
+
+	__asm__ __volatile__ ("stc vbr, %0" : "=r" (vbr));
+
+	if (vbr) {
+		gdb_vbr_vector = (void *)(vbr + 0x100);
+		printk(KERN_NOTICE "Setting GDB trap vector to %p\n",
+		       gdb_vbr_vector);
+	} else
+		printk(KERN_NOTICE "SH-BIOS not detected\n");
+}
+
+/**
+ * sh_bios_vbr_reload - Re-load the system VBR from the BIOS vector.
+ *
+ * This can be used by save/restore code to reinitialize the system VBR
+ * from the fixed BIOS VBR. A no-op if no BIOS VBR is known.
+ */
+void sh_bios_vbr_reload(void)
+{
+	if (gdb_vbr_vector)
+		__asm__ __volatile__ (
+			"ldc %0, vbr"
+			:
+			: "r" (((unsigned long) gdb_vbr_vector) - 0x100)
+			: "memory"
+		);
+}
+
+/*
+ *	Print a string through the BIOS
+ */
+static void sh_console_write(struct console *co, const char *s,
+				 unsigned count)
+{
+	sh_bios_console_write(s, count);
+}
+
+/*
+ *	Setup initial baud/bits/parity. We do two things here:
+ *	- construct a cflag setting for the first rs_open()
+ *	- initialize the serial port
+ *	Return non-zero if we didn't find a serial port.
+ */
+static int __init sh_console_setup(struct console *co, char *options)
+{
+	int	cflag = CREAD | HUPCL | CLOCAL;
+
+	/*
+	 *	Now construct a cflag setting.
+	 *	TODO: this is a totally bogus cflag, as we have
+	 *	no idea what serial settings the BIOS is using, or
+	 *	even if its using the serial port at all.
+	 */
+	cflag |= B115200 | CS8 | /*no parity*/0;
+
+	co->cflag = cflag;
+
+	return 0;
+}
+
+static struct console bios_console = {
+	.name		= "bios",
+	.write		= sh_console_write,
+	.setup		= sh_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+};
+
+static struct console *early_console;
+
+static int __init setup_early_printk(char *buf)
+{
+	int keep_early = 0;
+
+	if (!buf)
+		return 0;
+
+	if (strstr(buf, "keep"))
+		keep_early = 1;
+
+	if (!strncmp(buf, "bios", 4))
+		early_console = &bios_console;
+
+	if (likely(early_console)) {
+		if (keep_early)
+			early_console->flags &= ~CON_BOOT;
+		else
+			early_console->flags |= CON_BOOT;
+		register_console(early_console);
+	}
+
+	return 0;
+}
+early_param("earlyprintk", setup_early_printk);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/signal_32.c linux-libre-2.6.34-gnu1/arch/sh/kernel/signal_32.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/signal_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/signal_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -150,7 +150,7 @@ static inline int restore_sigcontext_fpu
 		return 0;
 
 	set_used_math();
-	return __copy_from_user(&tsk->thread.fpu.hard, &sc->sc_fpregs[0],
+	return __copy_from_user(&tsk->thread.xstate->hardfpu, &sc->sc_fpregs[0],
 				sizeof(long)*(16*2+2));
 }
 
@@ -175,7 +175,7 @@ static inline int save_sigcontext_fpu(st
 	clear_used_math();
 
 	unlazy_fpu(tsk, regs);
-	return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.fpu.hard,
+	return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.xstate->hardfpu,
 			      sizeof(long)*(16*2+2));
 }
 #endif /* CONFIG_SH_FPU */
@@ -528,7 +528,7 @@ handle_syscall_restart(unsigned long sav
 		/* fallthrough */
 		case -ERESTARTNOINTR:
 			regs->regs[0] = save_r0;
-			regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
+			regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
 			break;
 	}
 }
@@ -626,9 +626,9 @@ no_signal:
 		    regs->regs[0] == -ERESTARTSYS ||
 		    regs->regs[0] == -ERESTARTNOINTR) {
 			regs->regs[0] = save_r0;
-			regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
+			regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
 		} else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) {
-			regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
+			regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
 			regs->regs[3] = __NR_restart_syscall;
 		}
 	}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/signal_64.c linux-libre-2.6.34-gnu1/arch/sh/kernel/signal_64.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/signal_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/signal_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -297,7 +297,7 @@ restore_sigcontext_fpu(struct pt_regs *r
 		regs->sr |= SR_FD;
 	}
 
-	err |= __copy_from_user(&current->thread.fpu.hard, &sc->sc_fpregs[0],
+	err |= __copy_from_user(&current->thread.xstate->hardfpu, &sc->sc_fpregs[0],
 				(sizeof(long long) * 32) + (sizeof(int) * 1));
 
 	return err;
@@ -322,7 +322,7 @@ setup_sigcontext_fpu(struct pt_regs *reg
 		regs->sr |= SR_FD;
 	}
 
-	err |= __copy_to_user(&sc->sc_fpregs[0], &current->thread.fpu.hard,
+	err |= __copy_to_user(&sc->sc_fpregs[0], &current->thread.xstate->hardfpu,
 			      (sizeof(long long) * 32) + (sizeof(int) * 1));
 	clear_used_math();
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/smp.c linux-libre-2.6.34-gnu1/arch/sh/kernel/smp.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/smp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -69,6 +69,7 @@ asmlinkage void __cpuinit start_secondar
 	unsigned int cpu;
 	struct mm_struct *mm = &init_mm;
 
+	enable_mmu();
 	atomic_inc(&mm->mm_count);
 	atomic_inc(&mm->mm_users);
 	current->active_mm = mm;
@@ -161,15 +162,6 @@ void smp_send_reschedule(int cpu)
 	plat_send_ipi(cpu, SMP_MSG_RESCHEDULE);
 }
 
-static void stop_this_cpu(void *unused)
-{
-	cpu_clear(smp_processor_id(), cpu_online_map);
-	local_irq_disable();
-
-	for (;;)
-		cpu_relax();
-}
-
 void smp_send_stop(void)
 {
 	smp_call_function(stop_this_cpu, 0, 0);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/sys_sh.c linux-libre-2.6.34-gnu1/arch/sh/kernel/sys_sh.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/sys_sh.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/sys_sh.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,110 +53,6 @@ asmlinkage long sys_mmap2(unsigned long
 	return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
 }
 
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage int sys_ipc(uint call, int first, int second,
-		       int third, void __user *ptr, long fifth)
-{
-	int version, ret;
-
-	version = call >> 16; /* hack for backward compatibility */
-	call &= 0xffff;
-
-	if (call <= SEMTIMEDOP)
-		switch (call) {
-		case SEMOP:
-			return sys_semtimedop(first,
-					      (struct sembuf __user *)ptr,
-					      second, NULL);
-		case SEMTIMEDOP:
-			return sys_semtimedop(first,
-				(struct sembuf __user *)ptr, second,
-			        (const struct timespec __user *)fifth);
-		case SEMGET:
-			return sys_semget (first, second, third);
-		case SEMCTL: {
-			union semun fourth;
-			if (!ptr)
-				return -EINVAL;
-			if (get_user(fourth.__pad, (void __user * __user *) ptr))
-				return -EFAULT;
-			return sys_semctl (first, second, third, fourth);
-			}
-		default:
-			return -EINVAL;
-		}
-
-	if (call <= MSGCTL)
-		switch (call) {
-		case MSGSND:
-			return sys_msgsnd (first, (struct msgbuf __user *) ptr,
-					  second, third);
-		case MSGRCV:
-			switch (version) {
-			case 0:
-			{
-				struct ipc_kludge tmp;
-
-				if (!ptr)
-					return -EINVAL;
-
-				if (copy_from_user(&tmp,
-					(struct ipc_kludge __user *) ptr,
-						   sizeof (tmp)))
-					return -EFAULT;
-
-				return sys_msgrcv (first, tmp.msgp, second,
-						   tmp.msgtyp, third);
-			}
-			default:
-				return sys_msgrcv (first,
-						   (struct msgbuf __user *) ptr,
-						   second, fifth, third);
-			}
-		case MSGGET:
-			return sys_msgget ((key_t) first, second);
-		case MSGCTL:
-			return sys_msgctl (first, second,
-					   (struct msqid_ds __user *) ptr);
-		default:
-			return -EINVAL;
-		}
-	if (call <= SHMCTL)
-		switch (call) {
-		case SHMAT:
-			switch (version) {
-			default: {
-				ulong raddr;
-				ret = do_shmat (first, (char __user *) ptr,
-						 second, &raddr);
-				if (ret)
-					return ret;
-				return put_user (raddr, (ulong __user *) third);
-			}
-			case 1:	/* iBCS2 emulator entry point */
-				if (!segment_eq(get_fs(), get_ds()))
-					return -EINVAL;
-				return do_shmat (first, (char __user *) ptr,
-						  second, (ulong *) third);
-			}
-		case SHMDT:
-			return sys_shmdt ((char __user *)ptr);
-		case SHMGET:
-			return sys_shmget (first, second, third);
-		case SHMCTL:
-			return sys_shmctl (first, second,
-					   (struct shmid_ds __user *) ptr);
-		default:
-			return -EINVAL;
-		}
-
-	return -EINVAL;
-}
-
 /* sys_cacheflush -- flush (part of) the processor cache.  */
 asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, int op)
 {
@@ -197,14 +93,3 @@ asmlinkage int sys_cacheflush(unsigned l
 	up_read(&current->mm->mmap_sem);
 	return 0;
 }
-
-asmlinkage int sys_uname(struct old_utsname __user *name)
-{
-	int err;
-	if (!name)
-		return -EFAULT;
-	down_read(&uts_sem);
-	err = copy_to_user(name, utsname(), sizeof(*name));
-	up_read(&uts_sem);
-	return err?-EFAULT:0;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/time.c linux-libre-2.6.34-gnu1/arch/sh/kernel/time.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,12 +39,12 @@ static int null_rtc_set_time(const time_
 void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
 int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
 
-#ifdef CONFIG_GENERIC_CMOS_UPDATE
 void read_persistent_clock(struct timespec *ts)
 {
 	rtc_sh_get_time(ts);
 }
 
+#ifdef CONFIG_GENERIC_CMOS_UPDATE
 int update_persistent_clock(struct timespec now)
 {
 	return rtc_sh_set_time(now.tv_sec);
@@ -113,9 +113,5 @@ void __init time_init(void)
 	hwblk_init();
 	clk_init();
 
-	rtc_sh_get_time(&xtime);
-	set_normalized_timespec(&wall_to_monotonic,
-				-xtime.tv_sec, -xtime.tv_nsec);
-
 	late_time_init = sh_late_time_init;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/traps_32.c linux-libre-2.6.34-gnu1/arch/sh/kernel/traps_32.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/traps_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/traps_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,11 +24,10 @@
 #include <linux/kdebug.h>
 #include <linux/kexec.h>
 #include <linux/limits.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
 #include <linux/sysfs.h>
+#include <linux/uaccess.h>
 #include <asm/system.h>
-#include <asm/uaccess.h>
+#include <asm/alignment.h>
 #include <asm/fpu.h>
 #include <asm/kprobes.h>
 
@@ -47,73 +46,6 @@
 #define TRAP_ILLEGAL_SLOT_INST	13
 #endif
 
-static unsigned long se_user;
-static unsigned long se_sys;
-static unsigned long se_half;
-static unsigned long se_word;
-static unsigned long se_dword;
-static unsigned long se_multi;
-/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not
-   valid! */
-static int se_usermode = 3;
-/* 0: no warning 1: print a warning message, disabled by default */
-static int se_kernmode_warn;
-
-#ifdef CONFIG_PROC_FS
-static const char *se_usermode_action[] = {
-	"ignored",
-	"warn",
-	"fixup",
-	"fixup+warn",
-	"signal",
-	"signal+warn"
-};
-
-static int alignment_proc_show(struct seq_file *m, void *v)
-{
-	seq_printf(m, "User:\t\t%lu\n", se_user);
-	seq_printf(m, "System:\t\t%lu\n", se_sys);
-	seq_printf(m, "Half:\t\t%lu\n", se_half);
-	seq_printf(m, "Word:\t\t%lu\n", se_word);
-	seq_printf(m, "DWord:\t\t%lu\n", se_dword);
-	seq_printf(m, "Multi:\t\t%lu\n", se_multi);
-	seq_printf(m, "User faults:\t%i (%s)\n", se_usermode,
-			se_usermode_action[se_usermode]);
-	seq_printf(m, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn,
-			se_kernmode_warn ? "+warn" : "");
-	return 0;
-}
-
-static int alignment_proc_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, alignment_proc_show, NULL);
-}
-
-static ssize_t alignment_proc_write(struct file *file,
-		const char __user *buffer, size_t count, loff_t *pos)
-{
-	int *data = PDE(file->f_path.dentry->d_inode)->data;
-	char mode;
-
-	if (count > 0) {
-		if (get_user(mode, buffer))
-			return -EFAULT;
-		if (mode >= '0' && mode <= '5')
-			*data = mode - '0';
-	}
-	return count;
-}
-
-static const struct file_operations alignment_proc_fops = {
-	.owner		= THIS_MODULE,
-	.open		= alignment_proc_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-	.write		= alignment_proc_write,
-};
-#endif
-
 static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
 {
 	unsigned long p;
@@ -265,10 +197,10 @@ static int handle_unaligned_ins(insn_siz
 	count = 1<<(instruction&3);
 
 	switch (count) {
-	case 1: se_half  += 1; break;
-	case 2: se_word  += 1; break;
-	case 4: se_dword += 1; break;
-	case 8: se_multi += 1; break; /* ??? */
+	case 1: inc_unaligned_byte_access(); break;
+	case 2: inc_unaligned_word_access(); break;
+	case 4: inc_unaligned_dword_access(); break;
+	case 8: inc_unaligned_multi_access(); break;
 	}
 
 	ret = -EFAULT;
@@ -452,18 +384,8 @@ int handle_unaligned_access(insn_size_t
 	rm = regs->regs[index];
 
 	/* shout about fixups */
-	if (!expected) {
-		if (user_mode(regs) && (se_usermode & 1) && printk_ratelimit())
-			pr_notice("Fixing up unaligned userspace access "
-				  "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
-				  current->comm, task_pid_nr(current),
-				  (void *)regs->pc, instruction);
-		else if (se_kernmode_warn && printk_ratelimit())
-			pr_notice("Fixing up unaligned kernel access "
-				  "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
-				  current->comm, task_pid_nr(current),
-				  (void *)regs->pc, instruction);
-	}
+	if (!expected)
+		unaligned_fixups_notify(current, instruction, regs);
 
 	ret = -EFAULT;
 	switch (instruction&0xF000) {
@@ -616,10 +538,10 @@ asmlinkage void do_address_error(struct
 
 	if (user_mode(regs)) {
 		int si_code = BUS_ADRERR;
+		unsigned int user_action;
 
 		local_irq_enable();
-
-		se_user += 1;
+		inc_unaligned_user_access();
 
 		set_fs(USER_DS);
 		if (copy_from_user(&instruction, (insn_size_t *)(regs->pc & ~1),
@@ -630,16 +552,12 @@ asmlinkage void do_address_error(struct
 		set_fs(oldfs);
 
 		/* shout about userspace fixups */
-		if (se_usermode & 1)
-			printk(KERN_NOTICE "Unaligned userspace access "
-			       "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
-			       current->comm, current->pid, (void *)regs->pc,
-			       instruction);
+		unaligned_fixups_notify(current, instruction, regs);
 
-		if (se_usermode & 2)
+		user_action = unaligned_user_action();
+		if (user_action & UM_FIXUP)
 			goto fixup;
-
-		if (se_usermode & 4)
+		if (user_action & UM_SIGNAL)
 			goto uspace_segv;
 		else {
 			/* ignore */
@@ -659,7 +577,7 @@ fixup:
 					      &user_mem_access, 0);
 		set_fs(oldfs);
 
-		if (tmp==0)
+		if (tmp == 0)
 			return; /* sorted */
 uspace_segv:
 		printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned "
@@ -672,7 +590,7 @@ uspace_segv:
 		info.si_addr = (void __user *)address;
 		force_sig_info(SIGBUS, &info, current);
 	} else {
-		se_sys += 1;
+		inc_unaligned_kernel_access();
 
 		if (regs->pc & 1)
 			die("unaligned program counter", regs, error_code);
@@ -687,11 +605,7 @@ uspace_segv:
 			die("insn faulting in do_address_error", regs, 0);
 		}
 
-		if (se_kernmode_warn)
-			printk(KERN_NOTICE "Unaligned kernel access "
-			       "on behalf of \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
-			       current->comm, current->pid, (void *)regs->pc,
-			       instruction);
+		unaligned_fixups_notify(current, instruction, regs);
 
 		handle_unaligned_access(instruction, regs,
 					&user_mem_access, 0);
@@ -876,35 +790,10 @@ asmlinkage void do_exception_error(unsig
 	die_if_kernel("exception", regs, ex);
 }
 
-#if defined(CONFIG_SH_STANDARD_BIOS)
-void *gdb_vbr_vector;
-
-static inline void __init gdb_vbr_init(void)
-{
-	register unsigned long vbr;
-
-	/*
-	 * Read the old value of the VBR register to initialise
-	 * the vector through which debug and BIOS traps are
-	 * delegated by the Linux trap handler.
-	 */
-	asm volatile("stc vbr, %0" : "=r" (vbr));
-
-	gdb_vbr_vector = (void *)(vbr + 0x100);
-	printk("Setting GDB trap vector to 0x%08lx\n",
-	       (unsigned long)gdb_vbr_vector);
-}
-#endif
-
 void __cpuinit per_cpu_trap_init(void)
 {
 	extern void *vbr_base;
 
-#ifdef CONFIG_SH_STANDARD_BIOS
-	if (raw_smp_processor_id() == 0)
-		gdb_vbr_init();
-#endif
-
 	/* NOTE: The VBR value should be at P1
 	   (or P2, virtural "fixed" address space).
 	   It's definitely should not in physical address.  */
@@ -956,11 +845,8 @@ void __init trap_init(void)
 #endif
 
 #ifdef TRAP_UBC
-	set_exception_table_vec(TRAP_UBC, break_point_trap);
+	set_exception_table_vec(TRAP_UBC, breakpoint_trap_handler);
 #endif
-
-	/* Setup VBR for boot cpu */
-	per_cpu_trap_init();
 }
 
 void show_stack(struct task_struct *tsk, unsigned long *sp)
@@ -985,34 +871,3 @@ void dump_stack(void)
 	show_stack(NULL, NULL);
 }
 EXPORT_SYMBOL(dump_stack);
-
-#ifdef CONFIG_PROC_FS
-/*
- * This needs to be done after sysctl_init, otherwise sys/ will be
- * overwritten.  Actually, this shouldn't be in sys/ at all since
- * it isn't a sysctl, and it doesn't contain sysctl information.
- * We now locate it in /proc/cpu/alignment instead.
- */
-static int __init alignment_init(void)
-{
-	struct proc_dir_entry *dir, *res;
-
-	dir = proc_mkdir("cpu", NULL);
-	if (!dir)
-		return -ENOMEM;
-
-	res = proc_create_data("alignment", S_IWUSR | S_IRUGO, dir,
-			       &alignment_proc_fops, &se_usermode);
-	if (!res)
-		return -ENOMEM;
-
-        res = proc_create_data("kernel_alignment", S_IWUSR | S_IRUGO, dir,
-			       &alignment_proc_fops, &se_kernmode_warn);
-        if (!res)
-                return -ENOMEM;
-
-	return 0;
-}
-
-fs_initcall(alignment_init);
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/traps_64.c linux-libre-2.6.34-gnu1/arch/sh/kernel/traps_64.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/traps_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/traps_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -611,19 +611,19 @@ static int misaligned_fpu_load(struct pt
 
 		switch (width_shift) {
 		case 2:
-			current->thread.fpu.hard.fp_regs[destreg] = buflo;
+			current->thread.xstate->hardfpu.fp_regs[destreg] = buflo;
 			break;
 		case 3:
 			if (do_paired_load) {
-				current->thread.fpu.hard.fp_regs[destreg] = buflo;
-				current->thread.fpu.hard.fp_regs[destreg+1] = bufhi;
+				current->thread.xstate->hardfpu.fp_regs[destreg] = buflo;
+				current->thread.xstate->hardfpu.fp_regs[destreg+1] = bufhi;
 			} else {
 #if defined(CONFIG_CPU_LITTLE_ENDIAN)
-				current->thread.fpu.hard.fp_regs[destreg] = bufhi;
-				current->thread.fpu.hard.fp_regs[destreg+1] = buflo;
+				current->thread.xstate->hardfpu.fp_regs[destreg] = bufhi;
+				current->thread.xstate->hardfpu.fp_regs[destreg+1] = buflo;
 #else
-				current->thread.fpu.hard.fp_regs[destreg] = buflo;
-				current->thread.fpu.hard.fp_regs[destreg+1] = bufhi;
+				current->thread.xstate->hardfpu.fp_regs[destreg] = buflo;
+				current->thread.xstate->hardfpu.fp_regs[destreg+1] = bufhi;
 #endif
 			}
 			break;
@@ -681,19 +681,19 @@ static int misaligned_fpu_store(struct p
 
 		switch (width_shift) {
 		case 2:
-			buflo = current->thread.fpu.hard.fp_regs[srcreg];
+			buflo = current->thread.xstate->hardfpu.fp_regs[srcreg];
 			break;
 		case 3:
 			if (do_paired_load) {
-				buflo = current->thread.fpu.hard.fp_regs[srcreg];
-				bufhi = current->thread.fpu.hard.fp_regs[srcreg+1];
+				buflo = current->thread.xstate->hardfpu.fp_regs[srcreg];
+				bufhi = current->thread.xstate->hardfpu.fp_regs[srcreg+1];
 			} else {
 #if defined(CONFIG_CPU_LITTLE_ENDIAN)
-				bufhi = current->thread.fpu.hard.fp_regs[srcreg];
-				buflo = current->thread.fpu.hard.fp_regs[srcreg+1];
+				bufhi = current->thread.xstate->hardfpu.fp_regs[srcreg];
+				buflo = current->thread.xstate->hardfpu.fp_regs[srcreg+1];
 #else
-				buflo = current->thread.fpu.hard.fp_regs[srcreg];
-				bufhi = current->thread.fpu.hard.fp_regs[srcreg+1];
+				buflo = current->thread.xstate->hardfpu.fp_regs[srcreg];
+				bufhi = current->thread.xstate->hardfpu.fp_regs[srcreg+1];
 #endif
 			}
 			break;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/traps.c linux-libre-2.6.34-gnu1/arch/sh/kernel/traps.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/traps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/traps.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,7 +58,7 @@ BUILD_TRAP_HANDLER(debug)
 	TRAP_HANDLER_DECL;
 
 	/* Rewind */
-	regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
+	regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
 
 	if (notify_die(DIE_TRAP, "debug trap", regs, 0, vec & 0xff,
 		       SIGTRAP) == NOTIFY_STOP)
@@ -75,7 +75,7 @@ BUILD_TRAP_HANDLER(bug)
 	TRAP_HANDLER_DECL;
 
 	/* Rewind */
-	regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
+	regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
 
 	if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff,
 		       SIGTRAP) == NOTIFY_STOP)
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/vmlinux.lds.S linux-libre-2.6.34-gnu1/arch/sh/kernel/vmlinux.lds.S
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/vmlinux.lds.S	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,7 @@
  * Written by Niibe Yutaka and Paul Mundt
  */
 #ifdef CONFIG_SUPERH64
-#define LOAD_OFFSET	CONFIG_PAGE_OFFSET
+#define LOAD_OFFSET	PAGE_OFFSET
 OUTPUT_ARCH(sh:sh5)
 #else
 #define LOAD_OFFSET	0
@@ -14,17 +14,16 @@ OUTPUT_ARCH(sh)
 #include <asm/cache.h>
 #include <asm/vmlinux.lds.h>
 
+#ifdef CONFIG_PMB
+ #define MEMORY_OFFSET	0
+#else
+ #define MEMORY_OFFSET	__MEMORY_START
+#endif
+
 ENTRY(_start)
 SECTIONS
 {
-#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;
-#endif
+	. = PAGE_OFFSET + MEMORY_OFFSET + CONFIG_ZERO_PAGE_OFFSET;
 
 	_text = .;		/* Text and read-only data */
 
@@ -35,12 +34,7 @@ SECTIONS
 	.text : AT(ADDR(.text) - LOAD_OFFSET) {
 		HEAD_TEXT
 		TEXT_TEXT
-
-#ifdef CONFIG_SUPERH64
-		*(.text64)
-		*(.text..SHmedia32)
-#endif
-
+		EXTRA_TEXT
 		SCHED_TEXT
 		LOCK_TEXT
 		KPROBES_TEXT
@@ -51,24 +45,12 @@ SECTIONS
 	} = 0x0009
 
 	EXCEPTION_TABLE(16)
-
 	NOTES
-	RO_DATA(PAGE_SIZE)
-
-	/*
-	 * Code which must be executed uncached and the associated data
-	 */
-	. = ALIGN(PAGE_SIZE);
-	.uncached : AT(ADDR(.uncached) - LOAD_OFFSET) {
-		__uncached_start = .;
-		*(.uncached.text)
-		*(.uncached.data)
-		__uncached_end = .;
-	}
 
+	_sdata = .;
+	RO_DATA(PAGE_SIZE)
 	RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
-
-	_edata = .;			/* End of data section */
+	_edata = .;
 
 	DWARF_EH_FRAME
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/kernel/vsyscall/vsyscall.c linux-libre-2.6.34-gnu1/arch/sh/kernel/vsyscall/vsyscall.c
--- linux-libre-2.6.33-gnu1/arch/sh/kernel/vsyscall/vsyscall.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/kernel/vsyscall/vsyscall.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,6 @@
  * for more details.
  */
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/gfp.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/lib/libgcc.h linux-libre-2.6.34-gnu1/arch/sh/lib/libgcc.h
--- linux-libre-2.6.33-gnu1/arch/sh/lib/libgcc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/lib/libgcc.h	2010-05-16 17:17:36.000000000 -0400
@@ -17,8 +17,7 @@ struct DWstruct {
 #error I feel sick.
 #endif
 
-typedef union
-{
+typedef union {
 	struct DWstruct s;
 	long long ll;
 } DWunion;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/Makefile linux-libre-2.6.34-gnu1/arch/sh/Makefile
--- linux-libre-2.6.33-gnu1/arch/sh/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -83,6 +83,7 @@ defaultimage-$(CONFIG_SH_AP325RXA)		:= u
 defaultimage-$(CONFIG_SH_7724_SOLUTION_ENGINE)	:= uImage
 defaultimage-$(CONFIG_SH_7206_SOLUTION_ENGINE)	:= vmlinux
 defaultimage-$(CONFIG_SH_7619_SOLUTION_ENGINE)	:= vmlinux
+defaultimage-$(CONFIG_SH_SDK7786)		:= vmlinux.bin
 
 # Set some sensible Kbuild defaults
 KBUILD_IMAGE		:= $(defaultimage-y)
@@ -143,11 +144,11 @@ machdir-$(CONFIG_SH_AP325RXA)			+= mach-
 machdir-$(CONFIG_SH_KFR2R09)			+= mach-kfr2r09
 machdir-$(CONFIG_SH_ECOVEC)			+= mach-ecovec24
 machdir-$(CONFIG_SH_SDK7780)			+= mach-sdk7780
+machdir-$(CONFIG_SH_SDK7786)			+= mach-sdk7786
 machdir-$(CONFIG_SH_X3PROTO)			+= mach-x3proto
 machdir-$(CONFIG_SH_SH7763RDP)			+= mach-sh7763rdp
 machdir-$(CONFIG_SH_SH4202_MICRODEV)		+= mach-microdev
 machdir-$(CONFIG_SH_LANDISK)			+= mach-landisk
-machdir-$(CONFIG_SH_TITAN)			+= mach-titan
 machdir-$(CONFIG_SH_LBOX_RE2)			+= mach-lboxre2
 machdir-$(CONFIG_SH_CAYMAN)			+= mach-cayman
 machdir-$(CONFIG_SH_RSK)			+= mach-rsk
@@ -203,8 +204,9 @@ endif
 libs-$(CONFIG_SUPERH32)		:= arch/sh/lib/	$(libs-y)
 libs-$(CONFIG_SUPERH64)		:= arch/sh/lib64/ $(libs-y)
 
-BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec uImage.bin \
-	       zImage vmlinux.srec romImage
+BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.lzo \
+	       uImage.srec uImage.bin zImage vmlinux.bin vmlinux.srec \
+	       romImage
 PHONY += $(BOOT_TARGETS)
 
 all: $(KBUILD_IMAGE)
@@ -225,10 +227,12 @@ define archhelp
 	@echo '  zImage 	           - Compressed kernel image'
 	@echo '  romImage	           - Compressed ROM image, if supported'
 	@echo '  vmlinux.srec	           - Create an ELF S-record'
+	@echo '  vmlinux.bin	           - Create an uncompressed binary image'
 	@echo '* uImage  	           - Alias to bootable U-Boot image'
 	@echo '  uImage.srec	           - Create an S-record for U-Boot'
 	@echo '  uImage.bin	           - Kernel-only image for U-Boot (bin)'
 	@echo '* uImage.gz	           - Kernel-only image for U-Boot (gzip)'
 	@echo '  uImage.bz2	           - Kernel-only image for U-Boot (bzip2)'
 	@echo '  uImage.lzma	           - Kernel-only image for U-Boot (lzma)'
+	@echo '  uImage.lzo	           - Kernel-only image for U-Boot (lzo)'
 endef
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/math-emu/math.c linux-libre-2.6.34-gnu1/arch/sh/math-emu/math.c
--- linux-libre-2.6.33-gnu1/arch/sh/math-emu/math.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/math-emu/math.c	2010-05-16 17:17:36.000000000 -0400
@@ -471,10 +471,10 @@ static int fpu_emulate(u16 code, struct
  *	denormal_to_double - Given denormalized float number,
  *	                     store double float
  *
- *	@fpu: Pointer to sh_fpu_hard structure
+ *	@fpu: Pointer to sh_fpu_soft structure
  *	@n: Index to FP register
  */
-static void denormal_to_double(struct sh_fpu_hard_struct *fpu, int n)
+static void denormal_to_double(struct sh_fpu_soft_struct *fpu, int n)
 {
 	unsigned long du, dl;
 	unsigned long x = fpu->fpul;
@@ -552,11 +552,11 @@ static int ieee_fpe_handler(struct pt_re
 	if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */
 		struct task_struct *tsk = current;
 
-		if ((tsk->thread.fpu.hard.fpscr & (1 << 17))) {
+		if ((tsk->thread.xstate->softfpu.fpscr & (1 << 17))) {
 			/* FPU error */
-			denormal_to_double (&tsk->thread.fpu.hard,
+			denormal_to_double (&tsk->thread.xstate->softfpu,
 					    (finsn >> 8) & 0xf);
-			tsk->thread.fpu.hard.fpscr &=
+			tsk->thread.xstate->softfpu.fpscr &=
 				~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
 			task_thread_info(tsk)->status |= TS_USEDFPU;
 		} else {
@@ -617,7 +617,7 @@ static void fpu_init(struct sh_fpu_soft_
 int do_fpu_inst(unsigned short inst, struct pt_regs *regs)
 {
 	struct task_struct *tsk = current;
-	struct sh_fpu_soft_struct *fpu = &(tsk->thread.fpu.soft);
+	struct sh_fpu_soft_struct *fpu = &(tsk->thread.xstate->softfpu);
 
 	if (!(task_thread_info(tsk)->status & TS_USEDFPU)) {
 		/* initialize once. */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/alignment.c linux-libre-2.6.34-gnu1/arch/sh/mm/alignment.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/alignment.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/alignment.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,189 @@
+/*
+ * Alignment access counters and corresponding user-space interfaces.
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Copyright (C) 2009 - 2010 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include <linux/uaccess.h>
+#include <asm/alignment.h>
+#include <asm/processor.h>
+
+static unsigned long se_user;
+static unsigned long se_sys;
+static unsigned long se_half;
+static unsigned long se_word;
+static unsigned long se_dword;
+static unsigned long se_multi;
+/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not
+   valid! */
+static int se_usermode = UM_WARN | UM_FIXUP;
+/* 0: no warning 1: print a warning message, disabled by default */
+static int se_kernmode_warn;
+
+core_param(alignment, se_usermode, int, 0600);
+
+void inc_unaligned_byte_access(void)
+{
+	se_half++;
+}
+
+void inc_unaligned_word_access(void)
+{
+	se_word++;
+}
+
+void inc_unaligned_dword_access(void)
+{
+	se_dword++;
+}
+
+void inc_unaligned_multi_access(void)
+{
+	se_multi++;
+}
+
+void inc_unaligned_user_access(void)
+{
+	se_user++;
+}
+
+void inc_unaligned_kernel_access(void)
+{
+	se_sys++;
+}
+
+/*
+ * This defaults to the global policy which can be set from the command
+ * line, while processes can overload their preferences via prctl().
+ */
+unsigned int unaligned_user_action(void)
+{
+	unsigned int action = se_usermode;
+
+	if (current->thread.flags & SH_THREAD_UAC_SIGBUS) {
+		action &= ~UM_FIXUP;
+		action |= UM_SIGNAL;
+	}
+
+	if (current->thread.flags & SH_THREAD_UAC_NOPRINT)
+		action &= ~UM_WARN;
+
+	return action;
+}
+
+int get_unalign_ctl(struct task_struct *tsk, unsigned long addr)
+{
+	return put_user(tsk->thread.flags & SH_THREAD_UAC_MASK,
+			(unsigned int __user *)addr);
+}
+
+int set_unalign_ctl(struct task_struct *tsk, unsigned int val)
+{
+	tsk->thread.flags = (tsk->thread.flags & ~SH_THREAD_UAC_MASK) |
+			    (val & SH_THREAD_UAC_MASK);
+	return 0;
+}
+
+void unaligned_fixups_notify(struct task_struct *tsk, insn_size_t insn,
+			     struct pt_regs *regs)
+{
+	if (user_mode(regs) && (se_usermode & UM_WARN) && printk_ratelimit())
+		pr_notice("Fixing up unaligned userspace access "
+			  "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+			  tsk->comm, task_pid_nr(tsk),
+			  (void *)instruction_pointer(regs), insn);
+	else if (se_kernmode_warn && printk_ratelimit())
+		pr_notice("Fixing up unaligned kernel access "
+			  "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+			  tsk->comm, task_pid_nr(tsk),
+			  (void *)instruction_pointer(regs), insn);
+}
+
+static const char *se_usermode_action[] = {
+	"ignored",
+	"warn",
+	"fixup",
+	"fixup+warn",
+	"signal",
+	"signal+warn"
+};
+
+static int alignment_proc_show(struct seq_file *m, void *v)
+{
+	seq_printf(m, "User:\t\t%lu\n", se_user);
+	seq_printf(m, "System:\t\t%lu\n", se_sys);
+	seq_printf(m, "Half:\t\t%lu\n", se_half);
+	seq_printf(m, "Word:\t\t%lu\n", se_word);
+	seq_printf(m, "DWord:\t\t%lu\n", se_dword);
+	seq_printf(m, "Multi:\t\t%lu\n", se_multi);
+	seq_printf(m, "User faults:\t%i (%s)\n", se_usermode,
+			se_usermode_action[se_usermode]);
+	seq_printf(m, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn,
+			se_kernmode_warn ? "+warn" : "");
+	return 0;
+}
+
+static int alignment_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, alignment_proc_show, NULL);
+}
+
+static ssize_t alignment_proc_write(struct file *file,
+		const char __user *buffer, size_t count, loff_t *pos)
+{
+	int *data = PDE(file->f_path.dentry->d_inode)->data;
+	char mode;
+
+	if (count > 0) {
+		if (get_user(mode, buffer))
+			return -EFAULT;
+		if (mode >= '0' && mode <= '5')
+			*data = mode - '0';
+	}
+	return count;
+}
+
+static const struct file_operations alignment_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= alignment_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= alignment_proc_write,
+};
+
+/*
+ * This needs to be done after sysctl_init, otherwise sys/ will be
+ * overwritten.  Actually, this shouldn't be in sys/ at all since
+ * it isn't a sysctl, and it doesn't contain sysctl information.
+ * We now locate it in /proc/cpu/alignment instead.
+ */
+static int __init alignment_init(void)
+{
+	struct proc_dir_entry *dir, *res;
+
+	dir = proc_mkdir("cpu", NULL);
+	if (!dir)
+		return -ENOMEM;
+
+	res = proc_create_data("alignment", S_IWUSR | S_IRUGO, dir,
+			       &alignment_proc_fops, &se_usermode);
+	if (!res)
+		return -ENOMEM;
+
+        res = proc_create_data("kernel_alignment", S_IWUSR | S_IRUGO, dir,
+			       &alignment_proc_fops, &se_kernmode_warn);
+        if (!res)
+                return -ENOMEM;
+
+	return 0;
+}
+fs_initcall(alignment_init);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/cache.c linux-libre-2.6.34-gnu1/arch/sh/mm/cache.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/cache.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/cache.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  * arch/sh/mm/cache.c
  *
  * Copyright (C) 1999, 2000, 2002  Niibe Yutaka
- * Copyright (C) 2002 - 2009  Paul Mundt
+ * Copyright (C) 2002 - 2010  Paul Mundt
  *
  * Released under the terms of the GNU GPL v2.0.
  */
@@ -41,8 +41,17 @@ static inline void cacheop_on_each_cpu(v
                                    int wait)
 {
 	preempt_disable();
-	smp_call_function(func, info, wait);
+
+	/*
+	 * It's possible that this gets called early on when IRQs are
+	 * still disabled due to ioremapping by the boot CPU, so don't
+	 * even attempt IPIs unless there are other CPUs online.
+	 */
+	if (num_online_cpus() > 1)
+		smp_call_function(func, info, wait);
+
 	func(info);
+
 	preempt_enable();
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/cache-debugfs.c linux-libre-2.6.34-gnu1/arch/sh/mm/cache-debugfs.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/cache-debugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/cache-debugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,8 +22,7 @@ enum cache_type {
 	CACHE_TYPE_UNIFIED,
 };
 
-static int __uses_jump_to_uncached cache_seq_show(struct seq_file *file,
-						  void *iter)
+static int cache_seq_show(struct seq_file *file, void *iter)
 {
 	unsigned int cache_type = (unsigned int)file->private;
 	struct cache_info *cache;
@@ -37,7 +36,7 @@ static int __uses_jump_to_uncached cache
 	 */
 	jump_to_uncached();
 
-	ccr = ctrl_inl(CCR);
+	ccr = __raw_readl(CCR);
 	if ((ccr & CCR_CACHE_ENABLE) == 0) {
 		back_to_cached();
 
@@ -90,7 +89,7 @@ static int __uses_jump_to_uncached cache
 		for (addr = addrstart, line = 0;
 		     addr < addrstart + waysize;
 		     addr += cache->linesz, line++) {
-			unsigned long data = ctrl_inl(addr);
+			unsigned long data = __raw_readl(addr);
 
 			/* Check the V bit, ignore invalid cachelines */
 			if ((data & 1) == 0)
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh2a.c linux-libre-2.6.34-gnu1/arch/sh/mm/cache-sh2a.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh2a.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/cache-sh2a.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,10 +32,10 @@ static void sh2a__flush_wback_region(voi
 		unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0);
 		int way;
 		for (way = 0; way < 4; way++) {
-			unsigned long data =  ctrl_inl(addr | (way << 11));
+			unsigned long data =  __raw_readl(addr | (way << 11));
 			if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
 				data &= ~SH_CACHE_UPDATED;
-				ctrl_outl(data, addr | (way << 11));
+				__raw_writel(data, addr | (way << 11));
 			}
 		}
 	}
@@ -58,7 +58,7 @@ static void sh2a__flush_purge_region(voi
 	jump_to_uncached();
 
 	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
-		ctrl_outl((v & CACHE_PHYSADDR_MASK),
+		__raw_writel((v & CACHE_PHYSADDR_MASK),
 			  CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
 	}
 	back_to_cached();
@@ -78,17 +78,17 @@ static void sh2a__flush_invalidate_regio
 	jump_to_uncached();
 
 #ifdef CONFIG_CACHE_WRITEBACK
-	ctrl_outl(ctrl_inl(CCR) | CCR_OCACHE_INVALIDATE, CCR);
+	__raw_writel(__raw_readl(CCR) | CCR_OCACHE_INVALIDATE, CCR);
 	/* I-cache invalidate */
 	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
-		ctrl_outl((v & CACHE_PHYSADDR_MASK),
+		__raw_writel((v & CACHE_PHYSADDR_MASK),
 			  CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
 	}
 #else
 	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
-		ctrl_outl((v & CACHE_PHYSADDR_MASK),
+		__raw_writel((v & CACHE_PHYSADDR_MASK),
 			  CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
-		ctrl_outl((v & CACHE_PHYSADDR_MASK),
+		__raw_writel((v & CACHE_PHYSADDR_MASK),
 			  CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
 	}
 #endif
@@ -115,14 +115,14 @@ static void sh2a_flush_icache_range(void
 		int way;
 		/* O-Cache writeback */
 		for (way = 0; way < 4; way++) {
-			unsigned long data =  ctrl_inl(CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
+			unsigned long data =  __raw_readl(CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
 			if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
 				data &= ~SH_CACHE_UPDATED;
-				ctrl_outl(data, CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
+				__raw_writel(data, CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
 			}
 		}
 		/* I-Cache invalidate */
-		ctrl_outl(addr,
+		__raw_writel(addr,
 			  CACHE_IC_ADDRESS_ARRAY | addr | 0x00000008);
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh2.c linux-libre-2.6.34-gnu1/arch/sh/mm/cache-sh2.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/cache-sh2.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,10 +28,10 @@ static void sh2__flush_wback_region(void
 		unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0);
 		int way;
 		for (way = 0; way < 4; way++) {
-			unsigned long data =  ctrl_inl(addr | (way << 12));
+			unsigned long data =  __raw_readl(addr | (way << 12));
 			if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
 				data &= ~SH_CACHE_UPDATED;
-				ctrl_outl(data, addr | (way << 12));
+				__raw_writel(data, addr | (way << 12));
 			}
 		}
 	}
@@ -47,7 +47,7 @@ static void sh2__flush_purge_region(void
 		& ~(L1_CACHE_BYTES-1);
 
 	for (v = begin; v < end; v+=L1_CACHE_BYTES)
-		ctrl_outl((v & CACHE_PHYSADDR_MASK),
+		__raw_writel((v & CACHE_PHYSADDR_MASK),
 			  CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
 }
 
@@ -63,9 +63,9 @@ static void sh2__flush_invalidate_region
 	local_irq_save(flags);
 	jump_to_uncached();
 
-	ccr = ctrl_inl(CCR);
+	ccr = __raw_readl(CCR);
 	ccr |= CCR_CACHE_INVALIDATE;
-	ctrl_outl(ccr, CCR);
+	__raw_writel(ccr, CCR);
 
 	back_to_cached();
 	local_irq_restore(flags);
@@ -78,7 +78,7 @@ static void sh2__flush_invalidate_region
 		& ~(L1_CACHE_BYTES-1);
 
 	for (v = begin; v < end; v+=L1_CACHE_BYTES)
-		ctrl_outl((v & CACHE_PHYSADDR_MASK),
+		__raw_writel((v & CACHE_PHYSADDR_MASK),
 			  CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
 #endif
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh3.c linux-libre-2.6.34-gnu1/arch/sh/mm/cache-sh3.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/cache-sh3.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,12 +50,12 @@ static void sh3__flush_wback_region(void
 			p = __pa(v);
 			addr = addrstart | (v & current_cpu_data.dcache.entry_mask);
 			local_irq_save(flags);
-			data = ctrl_inl(addr);
+			data = __raw_readl(addr);
 
 			if ((data & CACHE_PHYSADDR_MASK) ==
 			    (p & CACHE_PHYSADDR_MASK)) {
 				data &= ~SH_CACHE_UPDATED;
-				ctrl_outl(data, addr);
+				__raw_writel(data, addr);
 				local_irq_restore(flags);
 				break;
 			}
@@ -86,7 +86,7 @@ static void sh3__flush_purge_region(void
 		data = (v & 0xfffffc00); /* _Virtual_ address, ~U, ~V */
 		addr = CACHE_OC_ADDRESS_ARRAY |
 			(v & current_cpu_data.dcache.entry_mask) | SH_CACHE_ASSOC;
-		ctrl_outl(data, addr);
+		__raw_writel(data, addr);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh4.c linux-libre-2.6.34-gnu1/arch/sh/mm/cache-sh4.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh4.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/cache-sh4.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,7 +36,7 @@ static void __flush_cache_one(unsigned l
  * Called from kernel/module.c:sys_init_module and routine for a.out format,
  * signal handler code and kprobes code
  */
-static void __uses_jump_to_uncached sh4_flush_icache_range(void *args)
+static void sh4_flush_icache_range(void *args)
 {
 	struct flusher_data *data = args;
 	unsigned long start, end;
@@ -109,6 +109,7 @@ static inline void flush_cache_one(unsig
 static void sh4_flush_dcache_page(void *arg)
 {
 	struct page *page = arg;
+	unsigned long addr = (unsigned long)page_address(page);
 #ifndef CONFIG_SMP
 	struct address_space *mapping = page_mapping(page);
 
@@ -116,22 +117,14 @@ static void sh4_flush_dcache_page(void *
 		set_bit(PG_dcache_dirty, &page->flags);
 	else
 #endif
-	{
-		unsigned long phys = page_to_phys(page);
-		unsigned long addr = CACHE_OC_ADDRESS_ARRAY;
-		int i, n;
-
-		/* Loop all the D-cache */
-		n = boot_cpu_data.dcache.n_aliases;
-		for (i = 0; i < n; i++, addr += PAGE_SIZE)
-			flush_cache_one(addr, phys);
-	}
+		flush_cache_one(CACHE_OC_ADDRESS_ARRAY |
+				(addr & shm_align_mask), page_to_phys(page));
 
 	wmb();
 }
 
 /* TODO: Selective icache invalidation through IC address array.. */
-static void __uses_jump_to_uncached flush_icache_all(void)
+static void flush_icache_all(void)
 {
 	unsigned long flags, ccr;
 
@@ -139,9 +132,9 @@ static void __uses_jump_to_uncached flus
 	jump_to_uncached();
 
 	/* Flush I-cache */
-	ccr = ctrl_inl(CCR);
+	ccr = __raw_readl(CCR);
 	ccr |= CCR_CACHE_ICI;
-	ctrl_outl(ccr, CCR);
+	__raw_writel(ccr, CCR);
 
 	/*
 	 * back_to_cached() will take care of the barrier for us, don't add
@@ -384,9 +377,9 @@ extern void __weak sh4__flush_region_ini
 void __init sh4_cache_init(void)
 {
 	printk("PVR=%08x CVR=%08x PRR=%08x\n",
-		ctrl_inl(CCN_PVR),
-		ctrl_inl(CCN_CVR),
-		ctrl_inl(CCN_PRR));
+		__raw_readl(CCN_PVR),
+		__raw_readl(CCN_CVR),
+		__raw_readl(CCN_PRR));
 
 	local_flush_icache_range	= sh4_flush_icache_range;
 	local_flush_dcache_page		= sh4_flush_dcache_page;
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh7705.c linux-libre-2.6.34-gnu1/arch/sh/mm/cache-sh7705.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh7705.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/cache-sh7705.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,10 +48,10 @@ static inline void cache_wback_all(void)
 			unsigned long data;
 			int v = SH_CACHE_UPDATED | SH_CACHE_VALID;
 
-			data = ctrl_inl(addr);
+			data = __raw_readl(addr);
 
 			if ((data & v) == v)
-				ctrl_outl(data & ~v, addr);
+				__raw_writel(data & ~v, addr);
 
 		}
 
@@ -78,7 +78,7 @@ static void sh7705_flush_icache_range(vo
 /*
  * Writeback&Invalidate the D-cache of the page
  */
-static void __uses_jump_to_uncached __flush_dcache_page(unsigned long phys)
+static void __flush_dcache_page(unsigned long phys)
 {
 	unsigned long ways, waysize, addrstart;
 	unsigned long flags;
@@ -115,10 +115,10 @@ static void __uses_jump_to_uncached __fl
 		     addr += current_cpu_data.dcache.linesz) {
 			unsigned long data;
 
-			data = ctrl_inl(addr) & (0x1ffffC00 | SH_CACHE_VALID);
+			data = __raw_readl(addr) & (0x1ffffC00 | SH_CACHE_VALID);
 		        if (data == phys) {
 				data &= ~(SH_CACHE_VALID | SH_CACHE_UPDATED);
-				ctrl_outl(data, addr);
+				__raw_writel(data, addr);
 			}
 		}
 
@@ -144,7 +144,7 @@ static void sh7705_flush_dcache_page(voi
 		__flush_dcache_page(__pa(page_address(page)));
 }
 
-static void __uses_jump_to_uncached sh7705_flush_cache_all(void *args)
+static void sh7705_flush_cache_all(void *args)
 {
 	unsigned long flags;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/consistent.c linux-libre-2.6.34-gnu1/arch/sh/mm/consistent.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/consistent.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/consistent.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/dma-debug.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <asm/cacheflush.h>
 #include <asm/addrspace.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/fault_32.c linux-libre-2.6.34-gnu1/arch/sh/mm/fault_32.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/fault_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/fault_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,6 +53,9 @@ static inline pmd_t *vmalloc_sync_one(pg
 	if (!pud_present(*pud_k))
 		return NULL;
 
+	if (!pud_present(*pud))
+	    set_pud(pud, *pud_k);
+
 	pmd = pmd_offset(pud, address);
 	pmd_k = pmd_offset(pud_k, address);
 	if (!pmd_present(*pmd_k))
@@ -371,7 +374,7 @@ handle_tlbmiss(struct pt_regs *regs, uns
 		local_flush_tlb_one(get_asid(), address & PAGE_MASK);
 #endif
 
-	update_mmu_cache(NULL, address, entry);
+	update_mmu_cache(NULL, address, pte);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/hugetlbpage.c linux-libre-2.6.34-gnu1/arch/sh/mm/hugetlbpage.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/hugetlbpage.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/hugetlbpage.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/pagemap.h>
-#include <linux/slab.h>
 #include <linux/sysctl.h>
 
 #include <asm/mman.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/init.c linux-libre-2.6.34-gnu1/arch/sh/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/bootmem.h>
 #include <linux/proc_fs.h>
 #include <linux/pagemap.h>
@@ -21,25 +22,13 @@
 #include <asm/cacheflush.h>
 #include <asm/sections.h>
 #include <asm/cache.h>
+#include <asm/sizes.h>
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 pgd_t swapper_pg_dir[PTRS_PER_PGD];
 
-#ifdef CONFIG_SUPERH32
-/*
- * Handle trivial transitions between cached and uncached
- * segments, making use of the 1:1 mapping relationship in
- * 512MB lowmem.
- *
- * This is the offset of the uncached section from its cached alias.
- * Default value only valid in 29 bit mode, in 32bit mode will be
- * overridden in pmb_init.
- */
-unsigned long cached_to_uncached = P2SEG - P1SEG;
-#endif
-
 #ifdef CONFIG_MMU
-static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
+static pte_t *__get_pte_phys(unsigned long addr)
 {
 	pgd_t *pgd;
 	pud_t *pud;
@@ -49,22 +38,30 @@ static void set_pte_phys(unsigned long a
 	pgd = pgd_offset_k(addr);
 	if (pgd_none(*pgd)) {
 		pgd_ERROR(*pgd);
-		return;
+		return NULL;
 	}
 
 	pud = pud_alloc(NULL, pgd, addr);
 	if (unlikely(!pud)) {
 		pud_ERROR(*pud);
-		return;
+		return NULL;
 	}
 
 	pmd = pmd_alloc(NULL, pud, addr);
 	if (unlikely(!pmd)) {
 		pmd_ERROR(*pmd);
-		return;
+		return NULL;
 	}
 
 	pte = pte_offset_kernel(pmd, addr);
+	return pte;
+}
+
+static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
+{
+	pte_t *pte;
+
+	pte = __get_pte_phys(addr);
 	if (!pte_none(*pte)) {
 		pte_ERROR(*pte);
 		return;
@@ -72,23 +69,24 @@ static void set_pte_phys(unsigned long a
 
 	set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot));
 	local_flush_tlb_one(get_asid(), addr);
+
+	if (pgprot_val(prot) & _PAGE_WIRED)
+		tlb_wire_entry(NULL, addr, *pte);
+}
+
+static void clear_pte_phys(unsigned long addr, pgprot_t prot)
+{
+	pte_t *pte;
+
+	pte = __get_pte_phys(addr);
+
+	if (pgprot_val(prot) & _PAGE_WIRED)
+		tlb_unwire_entry();
+
+	set_pte(pte, pfn_pte(0, __pgprot(0)));
+	local_flush_tlb_one(get_asid(), addr);
 }
 
-/*
- * As a performance optimization, other platforms preserve the fixmap mapping
- * across a context switch, we don't presently do this, but this could be done
- * in a similar fashion as to the wired TLB interface that sh64 uses (by way
- * of the memory mapped UTLB configuration) -- this unfortunately forces us to
- * give up a TLB entry for each mapping we want to preserve. While this may be
- * viable for a small number of fixmaps, it's not particularly useful for
- * everything and needs to be carefully evaluated. (ie, we may want this for
- * the vsyscall page).
- *
- * XXX: Perhaps add a _PAGE_WIRED flag or something similar that we can pass
- * in at __set_fixmap() time to determine the appropriate behavior to follow.
- *
- *					 -- PFM.
- */
 void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
 {
 	unsigned long address = __fix_to_virt(idx);
@@ -101,6 +99,18 @@ void __set_fixmap(enum fixed_addresses i
 	set_pte_phys(address, phys, prot);
 }
 
+void __clear_fixmap(enum fixed_addresses idx, pgprot_t prot)
+{
+	unsigned long address = __fix_to_virt(idx);
+
+	if (idx >= __end_of_fixed_addresses) {
+		BUG();
+		return;
+	}
+
+	clear_pte_phys(address, prot);
+}
+
 void __init page_table_range_init(unsigned long start, unsigned long end,
 					 pgd_t *pgd_base)
 {
@@ -120,7 +130,13 @@ void __init page_table_range_init(unsign
 	for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
 		pud = (pud_t *)pgd;
 		for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
+#ifdef __PAGETABLE_PMD_FOLDED
 			pmd = (pmd_t *)pud;
+#else
+			pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
+			pud_populate(&init_mm, pud, pmd);
+			pmd += k;
+#endif
 			for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
 				if (pmd_none(*pmd)) {
 					pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
@@ -182,9 +198,6 @@ void __init paging_init(void)
 	}
 
 	free_area_init_nodes(max_zone_pfns);
-
-	/* Set up the uncached fixmap */
-	set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start));
 }
 
 /*
@@ -195,6 +208,8 @@ static void __init iommu_init(void)
 	no_iommu_init();
 }
 
+unsigned int mem_init_done = 0;
+
 void __init mem_init(void)
 {
 	int codesize, datasize, initsize;
@@ -231,6 +246,8 @@ void __init mem_init(void)
 	memset(empty_zero_page, 0, PAGE_SIZE);
 	__flush_wback_region(empty_zero_page, PAGE_SIZE);
 
+	vsyscall_init();
+
 	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
 	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
 	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
@@ -243,8 +260,48 @@ void __init mem_init(void)
 		datasize >> 10,
 		initsize >> 10);
 
-	/* Initialize the vDSO */
-	vsyscall_init();
+	printk(KERN_INFO "virtual kernel memory layout:\n"
+		"    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
+#ifdef CONFIG_HIGHMEM
+		"    pkmap   : 0x%08lx - 0x%08lx   (%4ld kB)\n"
+#endif
+		"    vmalloc : 0x%08lx - 0x%08lx   (%4ld MB)\n"
+		"    lowmem  : 0x%08lx - 0x%08lx   (%4ld MB) (cached)\n"
+#ifdef CONFIG_UNCACHED_MAPPING
+		"            : 0x%08lx - 0x%08lx   (%4ld MB) (uncached)\n"
+#endif
+		"      .init : 0x%08lx - 0x%08lx   (%4ld kB)\n"
+		"      .data : 0x%08lx - 0x%08lx   (%4ld kB)\n"
+		"      .text : 0x%08lx - 0x%08lx   (%4ld kB)\n",
+		FIXADDR_START, FIXADDR_TOP,
+		(FIXADDR_TOP - FIXADDR_START) >> 10,
+
+#ifdef CONFIG_HIGHMEM
+		PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE,
+		(LAST_PKMAP*PAGE_SIZE) >> 10,
+#endif
+
+		(unsigned long)VMALLOC_START, VMALLOC_END,
+		(VMALLOC_END - VMALLOC_START) >> 20,
+
+		(unsigned long)memory_start, (unsigned long)high_memory,
+		((unsigned long)high_memory - (unsigned long)memory_start) >> 20,
+
+#ifdef CONFIG_UNCACHED_MAPPING
+		uncached_start, uncached_end, uncached_size >> 20,
+#endif
+
+		(unsigned long)&__init_begin, (unsigned long)&__init_end,
+		((unsigned long)&__init_end -
+		 (unsigned long)&__init_begin) >> 10,
+
+		(unsigned long)&_etext, (unsigned long)&_edata,
+		((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
+
+		(unsigned long)&_text, (unsigned long)&_etext,
+		((unsigned long)&_etext - (unsigned long)&_text) >> 10);
+
+	mem_init_done = 1;
 }
 
 void free_initmem(void)
@@ -277,35 +334,6 @@ void free_initrd_mem(unsigned long start
 }
 #endif
 
-#if THREAD_SHIFT < PAGE_SHIFT
-static struct kmem_cache *thread_info_cache;
-
-struct thread_info *alloc_thread_info(struct task_struct *tsk)
-{
-	struct thread_info *ti;
-
-	ti = kmem_cache_alloc(thread_info_cache, GFP_KERNEL);
-	if (unlikely(ti == NULL))
-		return NULL;
-#ifdef CONFIG_DEBUG_STACK_USAGE
-	memset(ti, 0, THREAD_SIZE);
-#endif
-	return ti;
-}
-
-void free_thread_info(struct thread_info *ti)
-{
-	kmem_cache_free(thread_info_cache, ti);
-}
-
-void thread_info_cache_init(void)
-{
-	thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE,
-					      THREAD_SIZE, 0, NULL);
-	BUG_ON(thread_info_cache == NULL);
-}
-#endif /* THREAD_SHIFT < PAGE_SHIFT */
-
 #ifdef CONFIG_MEMORY_HOTPLUG
 int arch_add_memory(int nid, u64 start, u64 size)
 {
@@ -336,10 +364,3 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to
 #endif
 
 #endif /* CONFIG_MEMORY_HOTPLUG */
-
-#ifdef CONFIG_PMB
-int __in_29bit_mode(void)
-{
-	return !(ctrl_inl(PMB_PASCR) & PASCR_SE);
-}
-#endif /* CONFIG_PMB */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/ioremap_32.c linux-libre-2.6.34-gnu1/arch/sh/mm/ioremap_32.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/ioremap_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/ioremap_32.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,145 +0,0 @@
-/*
- * arch/sh/mm/ioremap.c
- *
- * Re-map IO memory to kernel address space so that we can access it.
- * This is needed for high PCI addresses that aren't mapped in the
- * 640k-1MB IO memory area on PC's
- *
- * (C) Copyright 1995 1996 Linus Torvalds
- * (C) Copyright 2005, 2006 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/vmalloc.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/pci.h>
-#include <linux/io.h>
-#include <asm/page.h>
-#include <asm/pgalloc.h>
-#include <asm/addrspace.h>
-#include <asm/cacheflush.h>
-#include <asm/tlbflush.h>
-#include <asm/mmu.h>
-
-/*
- * Remap an arbitrary physical address space into the kernel virtual
- * address space. Needed when the kernel wants to access high addresses
- * directly.
- *
- * NOTE! We need to allow non-page-aligned mappings too: we will obviously
- * have to convert them into an offset in a page-aligned mapping, but the
- * caller shouldn't need to know that small detail.
- */
-void __iomem *__ioremap_caller(unsigned long phys_addr, unsigned long size,
-			       unsigned long flags, void *caller)
-{
-	struct vm_struct *area;
-	unsigned long offset, last_addr, addr, orig_addr;
-	pgprot_t pgprot;
-
-	/* Don't allow wraparound or zero size */
-	last_addr = phys_addr + size - 1;
-	if (!size || last_addr < phys_addr)
-		return NULL;
-
-	/*
-	 * If we're in the fixed PCI memory range, mapping through page
-	 * tables is not only pointless, but also fundamentally broken.
-	 * Just return the physical address instead.
-	 *
-	 * For boards that map a small PCI memory aperture somewhere in
-	 * P1/P2 space, ioremap() will already do the right thing,
-	 * and we'll never get this far.
-	 */
-	if (is_pci_memory_fixed_range(phys_addr, size))
-		return (void __iomem *)phys_addr;
-
-	/*
-	 * Mappings have to be page-aligned
-	 */
-	offset = phys_addr & ~PAGE_MASK;
-	phys_addr &= PAGE_MASK;
-	size = PAGE_ALIGN(last_addr+1) - phys_addr;
-
-	/*
-	 * Ok, go for it..
-	 */
-	area = get_vm_area_caller(size, VM_IOREMAP, caller);
-	if (!area)
-		return NULL;
-	area->phys_addr = phys_addr;
-	orig_addr = addr = (unsigned long)area->addr;
-
-#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
-	 * remaining after a PMB mapping due to the size not being
-	 * perfectly aligned on a PMB size boundary) are then mapped
-	 * through the UTLB using conventional page tables.
-	 *
-	 * PMB entries are all pre-faulted.
-	 */
-	if (unlikely(phys_addr >= P1SEG)) {
-		unsigned long mapped = pmb_remap(addr, phys_addr, size, flags);
-
-		if (likely(mapped)) {
-			addr		+= mapped;
-			phys_addr	+= mapped;
-			size		-= mapped;
-		}
-	}
-#endif
-
-	pgprot = __pgprot(pgprot_val(PAGE_KERNEL_NOCACHE) | flags);
-	if (likely(size))
-		if (ioremap_page_range(addr, addr + size, phys_addr, pgprot)) {
-			vunmap((void *)orig_addr);
-			return NULL;
-		}
-
-	return (void __iomem *)(offset + (char *)orig_addr);
-}
-EXPORT_SYMBOL(__ioremap_caller);
-
-void __iounmap(void __iomem *addr)
-{
-	unsigned long vaddr = (unsigned long __force)addr;
-	unsigned long seg = PXSEG(vaddr);
-	struct vm_struct *p;
-
-	if (seg < P3SEG || vaddr >= P3_ADDR_MAX)
-		return;
-	if (is_pci_memory_fixed_range(vaddr, 0))
-		return;
-
-#ifdef CONFIG_PMB
-	/*
-	 * Purge any PMB entries that may have been established for this
-	 * mapping, then proceed with conventional VMA teardown.
-	 *
-	 * XXX: Note that due to the way that remove_vm_area() does
-	 * matching of the resultant VMA, we aren't able to fast-forward
-	 * the address past the PMB space until the end of the VMA where
-	 * the page tables reside. As such, unmap_vm_area() will be
-	 * forced to linearly scan over the area until it finds the page
-	 * tables where PTEs that need to be unmapped actually reside,
-	 * which is far from optimal. Perhaps we need to use a separate
-	 * VMA for the PMB mappings?
-	 *					-- PFM.
-	 */
-	pmb_unmap(vaddr);
-#endif
-
-	p = remove_vm_area((void *)(vaddr & PAGE_MASK));
-	if (!p) {
-		printk(KERN_ERR "%s: bad address %p\n", __func__, addr);
-		return;
-	}
-
-	kfree(p);
-}
-EXPORT_SYMBOL(__iounmap);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/ioremap_64.c linux-libre-2.6.34-gnu1/arch/sh/mm/ioremap_64.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/ioremap_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/ioremap_64.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,326 +0,0 @@
-/*
- * arch/sh/mm/ioremap_64.c
- *
- * Copyright (C) 2000, 2001  Paolo Alberelli
- * Copyright (C) 2003 - 2007  Paul Mundt
- *
- * Mostly derived from arch/sh/mm/ioremap.c which, in turn is mostly
- * derived from arch/i386/mm/ioremap.c .
- *
- *   (C) Copyright 1995 1996 Linus Torvalds
- *
- * 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/vmalloc.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/io.h>
-#include <linux/bootmem.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <asm/page.h>
-#include <asm/pgalloc.h>
-#include <asm/addrspace.h>
-#include <asm/cacheflush.h>
-#include <asm/tlbflush.h>
-#include <asm/mmu.h>
-
-static struct resource shmedia_iomap = {
-	.name	= "shmedia_iomap",
-	.start	= IOBASE_VADDR + PAGE_SIZE,
-	.end	= IOBASE_END - 1,
-};
-
-static void shmedia_mapioaddr(unsigned long pa, unsigned long va,
-			      unsigned long flags);
-static void shmedia_unmapioaddr(unsigned long vaddr);
-static void __iomem *shmedia_ioremap(struct resource *res, u32 pa,
-				     int sz, unsigned long flags);
-
-/*
- * We have the same problem as the SPARC, so lets have the same comment:
- * Our mini-allocator...
- * Boy this is gross! We need it because we must map I/O for
- * timers and interrupt controller before the kmalloc is available.
- */
-
-#define XNMLN  15
-#define XNRES  10
-
-struct xresource {
-	struct resource xres;   /* Must be first */
-	int xflag;              /* 1 == used */
-	char xname[XNMLN+1];
-};
-
-static struct xresource xresv[XNRES];
-
-static struct xresource *xres_alloc(void)
-{
-	struct xresource *xrp;
-	int n;
-
-	xrp = xresv;
-	for (n = 0; n < XNRES; n++) {
-		if (xrp->xflag == 0) {
-			xrp->xflag = 1;
-			return xrp;
-		}
-		xrp++;
-	}
-	return NULL;
-}
-
-static void xres_free(struct xresource *xrp)
-{
-	xrp->xflag = 0;
-}
-
-static struct resource *shmedia_find_resource(struct resource *root,
-					      unsigned long vaddr)
-{
-	struct resource *res;
-
-	for (res = root->child; res; res = res->sibling)
-		if (res->start <= vaddr && res->end >= vaddr)
-			return res;
-
-	return NULL;
-}
-
-static void __iomem *shmedia_alloc_io(unsigned long phys, unsigned long size,
-				      const char *name, unsigned long flags)
-{
-	struct xresource *xres;
-	struct resource *res;
-	char *tack;
-	int tlen;
-
-	if (name == NULL)
-		name = "???";
-
-	xres = xres_alloc();
-	if (xres != 0) {
-		tack = xres->xname;
-		res = &xres->xres;
-	} else {
-		printk_once(KERN_NOTICE "%s: done with statics, "
-			       "switching to kmalloc\n", __func__);
-		tlen = strlen(name);
-		tack = kmalloc(sizeof(struct resource) + tlen + 1, GFP_KERNEL);
-		if (!tack)
-			return NULL;
-		memset(tack, 0, sizeof(struct resource));
-		res = (struct resource *) tack;
-		tack += sizeof(struct resource);
-	}
-
-	strncpy(tack, name, XNMLN);
-	tack[XNMLN] = 0;
-	res->name = tack;
-
-	return shmedia_ioremap(res, phys, size, flags);
-}
-
-static void __iomem *shmedia_ioremap(struct resource *res, u32 pa, int sz,
-				     unsigned long flags)
-{
-	unsigned long offset = ((unsigned long) pa) & (~PAGE_MASK);
-	unsigned long round_sz = (offset + sz + PAGE_SIZE-1) & PAGE_MASK;
-	unsigned long va;
-	unsigned int psz;
-
-	if (allocate_resource(&shmedia_iomap, res, round_sz,
-			      shmedia_iomap.start, shmedia_iomap.end,
-			      PAGE_SIZE, NULL, NULL) != 0) {
-		panic("alloc_io_res(%s): cannot occupy\n",
-		      (res->name != NULL) ? res->name : "???");
-	}
-
-	va = res->start;
-	pa &= PAGE_MASK;
-
-	psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE;
-
-	for (psz = res->end - res->start + 1; psz != 0; psz -= PAGE_SIZE) {
-		shmedia_mapioaddr(pa, va, flags);
-		va += PAGE_SIZE;
-		pa += PAGE_SIZE;
-	}
-
-	return (void __iomem *)(unsigned long)(res->start + offset);
-}
-
-static void shmedia_free_io(struct resource *res)
-{
-	unsigned long len = res->end - res->start + 1;
-
-	BUG_ON((len & (PAGE_SIZE - 1)) != 0);
-
-	while (len) {
-		len -= PAGE_SIZE;
-		shmedia_unmapioaddr(res->start + len);
-	}
-
-	release_resource(res);
-}
-
-static __init_refok void *sh64_get_page(void)
-{
-	void *page;
-
-	if (slab_is_available())
-		page = (void *)get_zeroed_page(GFP_KERNEL);
-	else
-		page = alloc_bootmem_pages(PAGE_SIZE);
-
-	if (!page || ((unsigned long)page & ~PAGE_MASK))
-		panic("sh64_get_page: Out of memory already?\n");
-
-	return page;
-}
-
-static void shmedia_mapioaddr(unsigned long pa, unsigned long va,
-			      unsigned long flags)
-{
-	pgd_t *pgdp;
-	pud_t *pudp;
-	pmd_t *pmdp;
-	pte_t *ptep, pte;
-	pgprot_t prot;
-
-	pr_debug("shmedia_mapiopage pa %08lx va %08lx\n",  pa, va);
-
-	if (!flags)
-		flags = 1; /* 1 = CB0-1 device */
-
-	pgdp = pgd_offset_k(va);
-	if (pgd_none(*pgdp) || !pgd_present(*pgdp)) {
-		pudp = (pud_t *)sh64_get_page();
-		set_pgd(pgdp, __pgd((unsigned long)pudp | _KERNPG_TABLE));
-	}
-
-	pudp = pud_offset(pgdp, va);
-	if (pud_none(*pudp) || !pud_present(*pudp)) {
-		pmdp = (pmd_t *)sh64_get_page();
-		set_pud(pudp, __pud((unsigned long)pmdp | _KERNPG_TABLE));
-	}
-
-	pmdp = pmd_offset(pudp, va);
-	if (pmd_none(*pmdp) || !pmd_present(*pmdp)) {
-		ptep = (pte_t *)sh64_get_page();
-		set_pmd(pmdp, __pmd((unsigned long)ptep + _PAGE_TABLE));
-	}
-
-	prot = __pgprot(_PAGE_PRESENT | _PAGE_READ     | _PAGE_WRITE  |
-			_PAGE_DIRTY   | _PAGE_ACCESSED | _PAGE_SHARED | flags);
-
-	pte = pfn_pte(pa >> PAGE_SHIFT, prot);
-	ptep = pte_offset_kernel(pmdp, va);
-
-	if (!pte_none(*ptep) &&
-	    pte_val(*ptep) != pte_val(pte))
-		pte_ERROR(*ptep);
-
-	set_pte(ptep, pte);
-
-	flush_tlb_kernel_range(va, PAGE_SIZE);
-}
-
-static void shmedia_unmapioaddr(unsigned long vaddr)
-{
-	pgd_t *pgdp;
-	pud_t *pudp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	pgdp = pgd_offset_k(vaddr);
-	if (pgd_none(*pgdp) || pgd_bad(*pgdp))
-		return;
-
-	pudp = pud_offset(pgdp, vaddr);
-	if (pud_none(*pudp) || pud_bad(*pudp))
-		return;
-
-	pmdp = pmd_offset(pudp, vaddr);
-	if (pmd_none(*pmdp) || pmd_bad(*pmdp))
-		return;
-
-	ptep = pte_offset_kernel(pmdp, vaddr);
-
-	if (pte_none(*ptep) || !pte_present(*ptep))
-		return;
-
-	clear_page((void *)ptep);
-	pte_clear(&init_mm, vaddr, ptep);
-}
-
-void __iomem *__ioremap_caller(unsigned long offset, unsigned long size,
-			       unsigned long flags, void *caller)
-{
-	char name[14];
-
-	sprintf(name, "phys_%08x", (u32)offset);
-	return shmedia_alloc_io(offset, size, name, flags);
-}
-EXPORT_SYMBOL(__ioremap_caller);
-
-void __iounmap(void __iomem *virtual)
-{
-	unsigned long vaddr = (unsigned long)virtual & PAGE_MASK;
-	struct resource *res;
-	unsigned int psz;
-
-	res = shmedia_find_resource(&shmedia_iomap, vaddr);
-	if (!res) {
-		printk(KERN_ERR "%s: Failed to free 0x%08lx\n",
-		       __func__, vaddr);
-		return;
-	}
-
-	psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE;
-
-	shmedia_free_io(res);
-
-	if ((char *)res >= (char *)xresv &&
-	    (char *)res <  (char *)&xresv[XNRES]) {
-		xres_free((struct xresource *)res);
-	} else {
-		kfree(res);
-	}
-}
-EXPORT_SYMBOL(__iounmap);
-
-static int
-ioremap_proc_info(char *buf, char **start, off_t fpos, int length, int *eof,
-		  void *data)
-{
-	char *p = buf, *e = buf + length;
-	struct resource *r;
-	const char *nm;
-
-	for (r = ((struct resource *)data)->child; r != NULL; r = r->sibling) {
-		if (p + 32 >= e)        /* Better than nothing */
-			break;
-		nm = r->name;
-		if (nm == NULL)
-			nm = "???";
-
-		p += sprintf(p, "%08lx-%08lx: %s\n",
-			     (unsigned long)r->start,
-			     (unsigned long)r->end, nm);
-	}
-
-	return p-buf;
-}
-
-static int __init register_proc_onchip(void)
-{
-	create_proc_read_entry("io_map", 0, 0, ioremap_proc_info,
-			       &shmedia_iomap);
-	return 0;
-}
-late_initcall(register_proc_onchip);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/ioremap.c linux-libre-2.6.34-gnu1/arch/sh/mm/ioremap.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/ioremap.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/ioremap.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,137 @@
+/*
+ * arch/sh/mm/ioremap.c
+ *
+ * (C) Copyright 1995 1996 Linus Torvalds
+ * (C) Copyright 2005 - 2010  Paul Mundt
+ *
+ * Re-map IO memory to kernel address space so that we can access it.
+ * This is needed for high PCI addresses that aren't mapped in the
+ * 640k-1MB IO memory area on PC's
+ *
+ * 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/vmalloc.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/addrspace.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu.h>
+
+/*
+ * Remap an arbitrary physical address space into the kernel virtual
+ * address space. Needed when the kernel wants to access high addresses
+ * directly.
+ *
+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+ * have to convert them into an offset in a page-aligned mapping, but the
+ * caller shouldn't need to know that small detail.
+ */
+void __iomem * __init_refok
+__ioremap_caller(phys_addr_t phys_addr, unsigned long size,
+		 pgprot_t pgprot, void *caller)
+{
+	struct vm_struct *area;
+	unsigned long offset, last_addr, addr, orig_addr;
+	void __iomem *mapped;
+
+	/* Don't allow wraparound or zero size */
+	last_addr = phys_addr + size - 1;
+	if (!size || last_addr < phys_addr)
+		return NULL;
+
+	/*
+	 * If we can't yet use the regular approach, go the fixmap route.
+	 */
+	if (!mem_init_done)
+		return ioremap_fixed(phys_addr, size, pgprot);
+
+	/*
+	 * First try to remap through the PMB.
+	 * PMB entries are all pre-faulted.
+	 */
+	mapped = pmb_remap_caller(phys_addr, size, pgprot, caller);
+	if (mapped && !IS_ERR(mapped))
+		return mapped;
+
+	/*
+	 * Mappings have to be page-aligned
+	 */
+	offset = phys_addr & ~PAGE_MASK;
+	phys_addr &= PAGE_MASK;
+	size = PAGE_ALIGN(last_addr+1) - phys_addr;
+
+	/*
+	 * Ok, go for it..
+	 */
+	area = get_vm_area_caller(size, VM_IOREMAP, caller);
+	if (!area)
+		return NULL;
+	area->phys_addr = phys_addr;
+	orig_addr = addr = (unsigned long)area->addr;
+
+	if (ioremap_page_range(addr, addr + size, phys_addr, pgprot)) {
+		vunmap((void *)orig_addr);
+		return NULL;
+	}
+
+	return (void __iomem *)(offset + (char *)orig_addr);
+}
+EXPORT_SYMBOL(__ioremap_caller);
+
+/*
+ * Simple checks for non-translatable mappings.
+ */
+static inline int iomapping_nontranslatable(unsigned long offset)
+{
+#ifdef CONFIG_29BIT
+	/*
+	 * In 29-bit mode this includes the fixed P1/P2 areas, as well as
+	 * parts of P3.
+	 */
+	if (PXSEG(offset) < P3SEG || offset >= P3_ADDR_MAX)
+		return 1;
+#endif
+
+	return 0;
+}
+
+void __iounmap(void __iomem *addr)
+{
+	unsigned long vaddr = (unsigned long __force)addr;
+	struct vm_struct *p;
+
+	/*
+	 * Nothing to do if there is no translatable mapping.
+	 */
+	if (iomapping_nontranslatable(vaddr))
+		return;
+
+	/*
+	 * There's no VMA if it's from an early fixed mapping.
+	 */
+	if (iounmap_fixed(addr) == 0)
+		return;
+
+	/*
+	 * If the PMB handled it, there's nothing else to do.
+	 */
+	if (pmb_unmap(addr) == 0)
+		return;
+
+	p = remove_vm_area((void *)(vaddr & PAGE_MASK));
+	if (!p) {
+		printk(KERN_ERR "%s: bad address %p\n", __func__, addr);
+		return;
+	}
+
+	kfree(p);
+}
+EXPORT_SYMBOL(__iounmap);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/ioremap_fixed.c linux-libre-2.6.34-gnu1/arch/sh/mm/ioremap_fixed.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/ioremap_fixed.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/ioremap_fixed.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,134 @@
+/*
+ * Re-map IO memory to kernel address space so that we can access it.
+ *
+ * These functions should only be used when it is necessary to map a
+ * physical address space into the kernel address space before ioremap()
+ * can be used, e.g. early in boot before paging_init().
+ *
+ * Copyright (C) 2009  Matt Fleming
+ */
+
+#include <linux/vmalloc.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <linux/bootmem.h>
+#include <linux/proc_fs.h>
+#include <asm/fixmap.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/addrspace.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu.h>
+#include <asm/mmu_context.h>
+
+struct ioremap_map {
+	void __iomem *addr;
+	unsigned long size;
+	unsigned long fixmap_addr;
+};
+
+static struct ioremap_map ioremap_maps[FIX_N_IOREMAPS];
+
+void __init ioremap_fixed_init(void)
+{
+	struct ioremap_map *map;
+	int i;
+
+	for (i = 0; i < FIX_N_IOREMAPS; i++) {
+		map = &ioremap_maps[i];
+		map->fixmap_addr = __fix_to_virt(FIX_IOREMAP_BEGIN + i);
+	}
+}
+
+void __init __iomem *
+ioremap_fixed(phys_addr_t phys_addr, unsigned long size, pgprot_t prot)
+{
+	enum fixed_addresses idx0, idx;
+	struct ioremap_map *map;
+	unsigned int nrpages;
+	unsigned long offset;
+	int i, slot;
+
+	/*
+	 * Mappings have to be page-aligned
+	 */
+	offset = phys_addr & ~PAGE_MASK;
+	phys_addr &= PAGE_MASK;
+	size = PAGE_ALIGN(phys_addr + size) - phys_addr;
+
+	slot = -1;
+	for (i = 0; i < FIX_N_IOREMAPS; i++) {
+		map = &ioremap_maps[i];
+		if (!map->addr) {
+			map->size = size;
+			slot = i;
+			break;
+		}
+	}
+
+	if (slot < 0)
+		return NULL;
+
+	/*
+	 * Mappings have to fit in the FIX_IOREMAP area.
+	 */
+	nrpages = size >> PAGE_SHIFT;
+	if (nrpages > FIX_N_IOREMAPS)
+		return NULL;
+
+	/*
+	 * Ok, go for it..
+	 */
+	idx0 = FIX_IOREMAP_BEGIN + slot;
+	idx = idx0;
+	while (nrpages > 0) {
+		pgprot_val(prot) |= _PAGE_WIRED;
+		__set_fixmap(idx, phys_addr, prot);
+		phys_addr += PAGE_SIZE;
+		idx++;
+		--nrpages;
+	}
+
+	map->addr = (void __iomem *)(offset + map->fixmap_addr);
+	return map->addr;
+}
+
+int iounmap_fixed(void __iomem *addr)
+{
+	enum fixed_addresses idx;
+	struct ioremap_map *map;
+	unsigned int nrpages;
+	int i, slot;
+
+	slot = -1;
+	for (i = 0; i < FIX_N_IOREMAPS; i++) {
+		map = &ioremap_maps[i];
+		if (map->addr == addr) {
+			slot = i;
+			break;
+		}
+	}
+
+	/*
+	 * If we don't match, it's not for us.
+	 */
+	if (slot < 0)
+		return -EINVAL;
+
+	nrpages = map->size >> PAGE_SHIFT;
+
+	idx = FIX_IOREMAP_BEGIN + slot + nrpages - 1;
+	while (nrpages > 0) {
+		__clear_fixmap(idx, __pgprot(_PAGE_WIRED));
+		--idx;
+		--nrpages;
+	}
+
+	map->size = 0;
+	map->addr = NULL;
+
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/Kconfig linux-libre-2.6.34-gnu1/arch/sh/mm/Kconfig
--- linux-libre-2.6.33-gnu1/arch/sh/mm/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -75,52 +75,25 @@ config MEMORY_SIZE
 config 29BIT
 	def_bool !32BIT
 	depends on SUPERH32
+	select UNCACHED_MAPPING
 
 config 32BIT
 	bool
 	default y if CPU_SH5
 
-config PMB_ENABLE
-	bool "Support 32-bit physical addressing through PMB"
-	depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP
-	help
-	  If you say Y here, physical addressing will be extended to
-	  32-bits through the SH-4A PMB. If this is not set, legacy
-	  29-bit physical addressing will be used.
-
-choice
-	prompt "PMB handling type"
-	depends on PMB_ENABLE
-	default PMB_FIXED
-
 config PMB
-	bool "PMB"
+	bool "Support 32-bit physical addressing through PMB"
 	depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP
+	select 32BIT
+	select UNCACHED_MAPPING
 	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_SH4A && !CPU_SH4AL_DSP
-	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
-	help
-	  Selecting this option will enable the extended mode of the SH-X2
-	  TLB. For legacy SH-X behaviour and interoperability, say N. For
-	  all of the fun new features and a willingless to submit bug reports,
-	  say Y.
+	def_bool y
+	depends on (CPU_SHX2 || CPU_SHX3) && MMU
 
 config VSYSCALL
 	bool "Support vsyscall page"
@@ -188,14 +161,19 @@ config ARCH_MEMORY_PROBE
 	def_bool y
 	depends on MEMORY_HOTPLUG
 
+config IOREMAP_FIXED
+       def_bool y
+       depends on X2TLB || SUPERH64
+
+config UNCACHED_MAPPING
+	bool
+
 choice
 	prompt "Kernel page size"
-	default PAGE_SIZE_8KB if X2TLB
 	default PAGE_SIZE_4KB
 
 config PAGE_SIZE_4KB
 	bool "4kB"
-	depends on !MMU || !X2TLB
 	help
 	  This is the default page size used by all SuperH CPUs.
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/Makefile linux-libre-2.6.34-gnu1/arch/sh/mm/Makefile
--- linux-libre-2.6.33-gnu1/arch/sh/mm/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
 # Makefile for the Linux SuperH-specific parts of the memory manager.
 #
 
-obj-y			:= cache.o init.o consistent.o mmap.o
+obj-y			:= alignment.o cache.o init.o consistent.o mmap.o
 
 cacheops-$(CONFIG_CPU_SH2)		:= cache-sh2.o
 cacheops-$(CONFIG_CPU_SH2A)		:= cache-sh2a.o
@@ -15,7 +15,7 @@ obj-y			+= $(cacheops-y)
 
 mmu-y			:= nommu.o extable_32.o
 mmu-$(CONFIG_MMU)	:= extable_$(BITS).o fault_$(BITS).o \
-			   ioremap_$(BITS).o kmap.o tlbflush_$(BITS).o
+			   ioremap.o kmap.o pgtable.o tlbflush_$(BITS).o
 
 obj-y			+= $(mmu-y)
 obj-$(CONFIG_DEBUG_FS)	+= asids-debugfs.o
@@ -26,15 +26,17 @@ endif
 
 ifdef CONFIG_MMU
 tlb-$(CONFIG_CPU_SH3)		:= tlb-sh3.o
-tlb-$(CONFIG_CPU_SH4)		:= tlb-sh4.o
+tlb-$(CONFIG_CPU_SH4)		:= tlb-sh4.o tlb-urb.o
 tlb-$(CONFIG_CPU_SH5)		:= tlb-sh5.o
-tlb-$(CONFIG_CPU_HAS_PTEAEX)	:= tlb-pteaex.o
+tlb-$(CONFIG_CPU_HAS_PTEAEX)	:= tlb-pteaex.o tlb-urb.o
 obj-y				+= $(tlb-y)
 endif
 
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
-obj-$(CONFIG_PMB_ENABLE)	+= pmb.o
+obj-$(CONFIG_PMB)		+= pmb.o
 obj-$(CONFIG_NUMA)		+= numa.o
+obj-$(CONFIG_IOREMAP_FIXED)	+= ioremap_fixed.o
+obj-$(CONFIG_UNCACHED_MAPPING)	+= uncached.o
 
 # Special flags for fault_64.o.  This puts restrictions on the number of
 # caller-save registers that the compiler can target when building this file.
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/nommu.c linux-libre-2.6.34-gnu1/arch/sh/mm/nommu.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/nommu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/nommu.c	2010-05-16 17:17:36.000000000 -0400
@@ -94,3 +94,7 @@ void __init page_table_range_init(unsign
 void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
 {
 }
+
+void pgtable_cache_init(void)
+{
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/numa.c linux-libre-2.6.34-gnu1/arch/sh/mm/numa.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/numa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/numa.c	2010-05-16 17:17:36.000000000 -0400
@@ -74,6 +74,9 @@ void __init setup_bootmem_node(int nid,
 	start_pfn = start >> PAGE_SHIFT;
 	end_pfn = end >> PAGE_SHIFT;
 
+	pmb_bolt_mapping((unsigned long)__va(start), start, end - start,
+			 PAGE_KERNEL);
+
 	lmb_add(start, end - start);
 
 	__add_active_range(nid, start_pfn, end_pfn);
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/pgtable.c linux-libre-2.6.34-gnu1/arch/sh/mm/pgtable.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/pgtable.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/pgtable.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,57 @@
+#include <linux/mm.h>
+#include <linux/slab.h>
+
+#define PGALLOC_GFP GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO
+
+static struct kmem_cache *pgd_cachep;
+#if PAGETABLE_LEVELS > 2
+static struct kmem_cache *pmd_cachep;
+#endif
+
+void pgd_ctor(void *x)
+{
+	pgd_t *pgd = x;
+
+	memcpy(pgd + USER_PTRS_PER_PGD,
+	       swapper_pg_dir + USER_PTRS_PER_PGD,
+	       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+}
+
+void pgtable_cache_init(void)
+{
+	pgd_cachep = kmem_cache_create("pgd_cache",
+				       PTRS_PER_PGD * (1<<PTE_MAGNITUDE),
+				       PAGE_SIZE, SLAB_PANIC, pgd_ctor);
+#if PAGETABLE_LEVELS > 2
+	pmd_cachep = kmem_cache_create("pmd_cache",
+				       PTRS_PER_PMD * (1<<PTE_MAGNITUDE),
+				       PAGE_SIZE, SLAB_PANIC, NULL);
+#endif
+}
+
+pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+	return kmem_cache_alloc(pgd_cachep, PGALLOC_GFP);
+}
+
+void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+	kmem_cache_free(pgd_cachep, pgd);
+}
+
+#if PAGETABLE_LEVELS > 2
+void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+{
+	set_pud(pud, __pud((unsigned long)pmd));
+}
+
+pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+	return kmem_cache_alloc(pmd_cachep, PGALLOC_GFP);
+}
+
+void pmd_free(struct mm_struct *mm, pmd_t *pmd)
+{
+	kmem_cache_free(pmd_cachep, pmd);
+}
+#endif /* PAGETABLE_LEVELS > 2 */
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/pmb.c linux-libre-2.6.34-gnu1/arch/sh/mm/pmb.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/pmb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/pmb.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,11 +3,8 @@
  *
  * Privileged Space Mapping Buffer (PMB) Support.
  *
- * Copyright (C) 2005, 2006, 2007 Paul Mundt
- *
- * P1/P2 Section mapping definitions from map32.h, which was:
- *
- *	Copyright 2003 (c) Lineo Solutions,Inc.
+ * Copyright (C) 2005 - 2010  Paul Mundt
+ * Copyright (C) 2010  Matt Fleming
  *
  * 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,53 +15,221 @@
 #include <linux/sysdev.h>
 #include <linux/cpu.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/bitops.h>
 #include <linux/debugfs.h>
 #include <linux/fs.h>
 #include <linux/seq_file.h>
 #include <linux/err.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/vmalloc.h>
+#include <asm/cacheflush.h>
+#include <asm/sizes.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
+#include <asm/page.h>
 #include <asm/mmu.h>
-#include <asm/io.h>
 #include <asm/mmu_context.h>
 
-#define NR_PMB_ENTRIES	16
+struct pmb_entry;
 
-static void __pmb_unmap(struct pmb_entry *);
+struct pmb_entry {
+	unsigned long vpn;
+	unsigned long ppn;
+	unsigned long flags;
+	unsigned long size;
+
+	spinlock_t lock;
 
+	/*
+	 * 0 .. NR_PMB_ENTRIES for specific entry selection, or
+	 * PMB_NO_ENTRY to search for a free one
+	 */
+	int entry;
+
+	/* Adjacent entry link for contiguous multi-entry mappings */
+	struct pmb_entry *link;
+};
+
+static struct {
+	unsigned long size;
+	int flag;
+} pmb_sizes[] = {
+	{ .size	= SZ_512M, .flag = PMB_SZ_512M, },
+	{ .size = SZ_128M, .flag = PMB_SZ_128M, },
+	{ .size = SZ_64M,  .flag = PMB_SZ_64M,  },
+	{ .size = SZ_16M,  .flag = PMB_SZ_16M,  },
+};
+
+static void pmb_unmap_entry(struct pmb_entry *, int depth);
+
+static DEFINE_RWLOCK(pmb_rwlock);
 static struct pmb_entry pmb_entry_list[NR_PMB_ENTRIES];
-static unsigned long pmb_map;
+static DECLARE_BITMAP(pmb_map, NR_PMB_ENTRIES);
 
-static inline unsigned long mk_pmb_entry(unsigned int entry)
+static unsigned int pmb_iomapping_enabled;
+
+static __always_inline unsigned long mk_pmb_entry(unsigned int entry)
 {
 	return (entry & PMB_E_MASK) << PMB_E_SHIFT;
 }
 
-static inline unsigned long mk_pmb_addr(unsigned int entry)
+static __always_inline unsigned long mk_pmb_addr(unsigned int entry)
 {
 	return mk_pmb_entry(entry) | PMB_ADDR;
 }
 
-static inline unsigned long mk_pmb_data(unsigned int entry)
+static __always_inline unsigned long mk_pmb_data(unsigned int entry)
 {
 	return mk_pmb_entry(entry) | PMB_DATA;
 }
 
-static int pmb_alloc_entry(void)
+static __always_inline unsigned int pmb_ppn_in_range(unsigned long ppn)
 {
-	unsigned int pos;
+	return ppn >= __pa(memory_start) && ppn < __pa(memory_end);
+}
 
-repeat:
-	pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES);
+/*
+ * Ensure that the PMB entries match our cache configuration.
+ *
+ * When we are in 32-bit address extended mode, CCR.CB becomes
+ * invalid, so care must be taken to manually adjust cacheable
+ * translations.
+ */
+static __always_inline unsigned long pmb_cache_flags(void)
+{
+	unsigned long flags = 0;
 
-	if (unlikely(pos > NR_PMB_ENTRIES))
-		return -ENOSPC;
+#if defined(CONFIG_CACHE_OFF)
+	flags |= PMB_WT | PMB_UB;
+#elif defined(CONFIG_CACHE_WRITETHROUGH)
+	flags |= PMB_C | PMB_WT | PMB_UB;
+#elif defined(CONFIG_CACHE_WRITEBACK)
+	flags |= PMB_C;
+#endif
 
-	if (test_and_set_bit(pos, &pmb_map))
-		goto repeat;
+	return flags;
+}
+
+/*
+ * Convert typical pgprot value to the PMB equivalent
+ */
+static inline unsigned long pgprot_to_pmb_flags(pgprot_t prot)
+{
+	unsigned long pmb_flags = 0;
+	u64 flags = pgprot_val(prot);
+
+	if (flags & _PAGE_CACHABLE)
+		pmb_flags |= PMB_C;
+	if (flags & _PAGE_WT)
+		pmb_flags |= PMB_WT | PMB_UB;
+
+	return pmb_flags;
+}
+
+static inline bool pmb_can_merge(struct pmb_entry *a, struct pmb_entry *b)
+{
+	return (b->vpn == (a->vpn + a->size)) &&
+	       (b->ppn == (a->ppn + a->size)) &&
+	       (b->flags == a->flags);
+}
+
+static bool pmb_mapping_exists(unsigned long vaddr, phys_addr_t phys,
+			       unsigned long size)
+{
+	int i;
+
+	read_lock(&pmb_rwlock);
+
+	for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
+		struct pmb_entry *pmbe, *iter;
+		unsigned long span;
+
+		if (!test_bit(i, pmb_map))
+			continue;
+
+		pmbe = &pmb_entry_list[i];
+
+		/*
+		 * See if VPN and PPN are bounded by an existing mapping.
+		 */
+		if ((vaddr < pmbe->vpn) || (vaddr >= (pmbe->vpn + pmbe->size)))
+			continue;
+		if ((phys < pmbe->ppn) || (phys >= (pmbe->ppn + pmbe->size)))
+			continue;
+
+		/*
+		 * Now see if we're in range of a simple mapping.
+		 */
+		if (size <= pmbe->size) {
+			read_unlock(&pmb_rwlock);
+			return true;
+		}
+
+		span = pmbe->size;
+
+		/*
+		 * Finally for sizes that involve compound mappings, walk
+		 * the chain.
+		 */
+		for (iter = pmbe->link; iter; iter = iter->link)
+			span += iter->size;
+
+		/*
+		 * Nothing else to do if the range requirements are met.
+		 */
+		if (size <= span) {
+			read_unlock(&pmb_rwlock);
+			return true;
+		}
+	}
+
+	read_unlock(&pmb_rwlock);
+	return false;
+}
+
+static bool pmb_size_valid(unsigned long size)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++)
+		if (pmb_sizes[i].size == size)
+			return true;
+
+	return false;
+}
+
+static inline bool pmb_addr_valid(unsigned long addr, unsigned long size)
+{
+	return (addr >= P1SEG && (addr + size - 1) < P3SEG);
+}
+
+static inline bool pmb_prot_valid(pgprot_t prot)
+{
+	return (pgprot_val(prot) & _PAGE_USER) == 0;
+}
+
+static int pmb_size_to_flags(unsigned long size)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++)
+		if (pmb_sizes[i].size == size)
+			return pmb_sizes[i].flag;
+
+	return 0;
+}
+
+static int pmb_alloc_entry(void)
+{
+	int pos;
+
+	pos = find_first_zero_bit(pmb_map, NR_PMB_ENTRIES);
+	if (pos >= 0 && pos < NR_PMB_ENTRIES)
+		__set_bit(pos, pmb_map);
+	else
+		pos = -ENOSPC;
 
 	return pos;
 }
@@ -73,21 +238,34 @@ static struct pmb_entry *pmb_alloc(unsig
 				   unsigned long flags, int entry)
 {
 	struct pmb_entry *pmbe;
+	unsigned long irqflags;
+	void *ret = NULL;
 	int pos;
 
+	write_lock_irqsave(&pmb_rwlock, irqflags);
+
 	if (entry == PMB_NO_ENTRY) {
 		pos = pmb_alloc_entry();
-		if (pos < 0)
-			return ERR_PTR(pos);
+		if (unlikely(pos < 0)) {
+			ret = ERR_PTR(pos);
+			goto out;
+		}
 	} else {
-		if (test_bit(entry, &pmb_map))
-			return ERR_PTR(-ENOSPC);
+		if (__test_and_set_bit(entry, pmb_map)) {
+			ret = ERR_PTR(-ENOSPC);
+			goto out;
+		}
+
 		pos = entry;
 	}
 
+	write_unlock_irqrestore(&pmb_rwlock, irqflags);
+
 	pmbe = &pmb_entry_list[pos];
-	if (!pmbe)
-		return ERR_PTR(-ENOMEM);
+
+	memset(pmbe, 0, sizeof(struct pmb_entry));
+
+	spin_lock_init(&pmbe->lock);
 
 	pmbe->vpn	= vpn;
 	pmbe->ppn	= ppn;
@@ -95,169 +273,219 @@ static struct pmb_entry *pmb_alloc(unsig
 	pmbe->entry	= pos;
 
 	return pmbe;
+
+out:
+	write_unlock_irqrestore(&pmb_rwlock, irqflags);
+	return ret;
 }
 
 static void pmb_free(struct pmb_entry *pmbe)
 {
-	int pos = pmbe->entry;
-
-	pmbe->vpn	= 0;
-	pmbe->ppn	= 0;
-	pmbe->flags	= 0;
-	pmbe->entry	= 0;
+	__clear_bit(pmbe->entry, pmb_map);
 
-	clear_bit(pos, &pmb_map);
+	pmbe->entry	= PMB_NO_ENTRY;
+	pmbe->link	= NULL;
 }
 
 /*
- * Must be in P2 for __set_pmb_entry()
+ * Must be run uncached.
  */
-static void __set_pmb_entry(unsigned long vpn, unsigned long ppn,
-			    unsigned long flags, int pos)
+static void __set_pmb_entry(struct pmb_entry *pmbe)
 {
-	ctrl_outl(vpn | PMB_V, mk_pmb_addr(pos));
-
-#ifdef CONFIG_CACHE_WRITETHROUGH
-	/*
-	 * When we are in 32-bit address extended mode, CCR.CB becomes
-	 * invalid, so care must be taken to manually adjust cacheable
-	 * translations.
-	 */
-	if (likely(flags & PMB_C))
-		flags |= PMB_WT;
-#endif
+	unsigned long addr, data;
 
-	ctrl_outl(ppn | flags | PMB_V, mk_pmb_data(pos));
-}
+	addr = mk_pmb_addr(pmbe->entry);
+	data = mk_pmb_data(pmbe->entry);
 
-static void __uses_jump_to_uncached set_pmb_entry(struct pmb_entry *pmbe)
-{
 	jump_to_uncached();
-	__set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, pmbe->entry);
+
+	/* Set V-bit */
+	__raw_writel(pmbe->vpn | PMB_V, addr);
+	__raw_writel(pmbe->ppn | pmbe->flags | PMB_V, data);
+
 	back_to_cached();
 }
 
-static void __uses_jump_to_uncached clear_pmb_entry(struct pmb_entry *pmbe)
+static void __clear_pmb_entry(struct pmb_entry *pmbe)
 {
-	unsigned int entry = pmbe->entry;
-	unsigned long addr;
+	unsigned long addr, data;
+	unsigned long addr_val, data_val;
 
-	if (unlikely(entry >= NR_PMB_ENTRIES))
-		return;
+	addr = mk_pmb_addr(pmbe->entry);
+	data = mk_pmb_data(pmbe->entry);
 
-	jump_to_uncached();
+	addr_val = __raw_readl(addr);
+	data_val = __raw_readl(data);
 
 	/* Clear V-bit */
-	addr = mk_pmb_addr(entry);
-	ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr);
-
-	addr = mk_pmb_data(entry);
-	ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr);
-
-	back_to_cached();
+	writel_uncached(addr_val & ~PMB_V, addr);
+	writel_uncached(data_val & ~PMB_V, data);
 }
 
+#ifdef CONFIG_PM
+static void set_pmb_entry(struct pmb_entry *pmbe)
+{
+	unsigned long flags;
 
-static struct {
-	unsigned long size;
-	int flag;
-} pmb_sizes[] = {
-	{ .size	= 0x20000000, .flag = PMB_SZ_512M, },
-	{ .size = 0x08000000, .flag = PMB_SZ_128M, },
-	{ .size = 0x04000000, .flag = PMB_SZ_64M,  },
-	{ .size = 0x01000000, .flag = PMB_SZ_16M,  },
-};
+	spin_lock_irqsave(&pmbe->lock, flags);
+	__set_pmb_entry(pmbe);
+	spin_unlock_irqrestore(&pmbe->lock, flags);
+}
+#endif /* CONFIG_PM */
 
-long pmb_remap(unsigned long vaddr, unsigned long phys,
-	       unsigned long size, unsigned long flags)
+int pmb_bolt_mapping(unsigned long vaddr, phys_addr_t phys,
+		     unsigned long size, pgprot_t prot)
 {
 	struct pmb_entry *pmbp, *pmbe;
-	unsigned long wanted;
-	int pmb_flags, i;
-	long err;
+	unsigned long orig_addr, orig_size;
+	unsigned long flags, pmb_flags;
+	int i, mapped;
 
-	/* Convert typical pgprot value to the PMB equivalent */
-	if (flags & _PAGE_CACHABLE) {
-		if (flags & _PAGE_WT)
-			pmb_flags = PMB_WT;
-		else
-			pmb_flags = PMB_C;
-	} else
-		pmb_flags = PMB_WT | PMB_UB;
+	if (!pmb_addr_valid(vaddr, size))
+		return -EFAULT;
+	if (pmb_mapping_exists(vaddr, phys, size))
+		return 0;
 
+	orig_addr = vaddr;
+	orig_size = size;
+
+	flush_tlb_kernel_range(vaddr, vaddr + size);
+
+	pmb_flags = pgprot_to_pmb_flags(prot);
 	pmbp = NULL;
-	wanted = size;
 
-again:
-	for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) {
-		if (size < pmb_sizes[i].size)
-			continue;
+	do {
+		for (i = mapped = 0; i < ARRAY_SIZE(pmb_sizes); i++) {
+			if (size < pmb_sizes[i].size)
+				continue;
 
-		pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag,
-				 PMB_NO_ENTRY);
-		if (IS_ERR(pmbe)) {
-			err = PTR_ERR(pmbe);
-			goto out;
+			pmbe = pmb_alloc(vaddr, phys, pmb_flags |
+					 pmb_sizes[i].flag, PMB_NO_ENTRY);
+			if (IS_ERR(pmbe)) {
+				pmb_unmap_entry(pmbp, mapped);
+				return PTR_ERR(pmbe);
+			}
+
+			spin_lock_irqsave(&pmbe->lock, flags);
+
+			pmbe->size = pmb_sizes[i].size;
+
+			__set_pmb_entry(pmbe);
+
+			phys	+= pmbe->size;
+			vaddr	+= pmbe->size;
+			size	-= pmbe->size;
+
+			/*
+			 * Link adjacent entries that span multiple PMB
+			 * entries for easier tear-down.
+			 */
+			if (likely(pmbp)) {
+				spin_lock(&pmbp->lock);
+				pmbp->link = pmbe;
+				spin_unlock(&pmbp->lock);
+			}
+
+			pmbp = pmbe;
+
+			/*
+			 * Instead of trying smaller sizes on every
+			 * iteration (even if we succeed in allocating
+			 * space), try using pmb_sizes[i].size again.
+			 */
+			i--;
+			mapped++;
+
+			spin_unlock_irqrestore(&pmbe->lock, flags);
 		}
+	} while (size >= SZ_16M);
 
-		set_pmb_entry(pmbe);
+	flush_cache_vmap(orig_addr, orig_addr + orig_size);
 
-		phys	+= pmb_sizes[i].size;
-		vaddr	+= pmb_sizes[i].size;
-		size	-= pmb_sizes[i].size;
+	return 0;
+}
 
-		/*
-		 * Link adjacent entries that span multiple PMB entries
-		 * for easier tear-down.
-		 */
-		if (likely(pmbp))
-			pmbp->link = pmbe;
+void __iomem *pmb_remap_caller(phys_addr_t phys, unsigned long size,
+			       pgprot_t prot, void *caller)
+{
+	unsigned long vaddr;
+	phys_addr_t offset, last_addr;
+	phys_addr_t align_mask;
+	unsigned long aligned;
+	struct vm_struct *area;
+	int i, ret;
 
-		pmbp = pmbe;
+	if (!pmb_iomapping_enabled)
+		return NULL;
 
-		/*
-		 * Instead of trying smaller sizes on every iteration
-		 * (even if we succeed in allocating space), try using
-		 * pmb_sizes[i].size again.
-		 */
-		i--;
-	}
+	/*
+	 * Small mappings need to go through the TLB.
+	 */
+	if (size < SZ_16M)
+		return ERR_PTR(-EINVAL);
+	if (!pmb_prot_valid(prot))
+		return ERR_PTR(-EINVAL);
 
-	if (size >= 0x1000000)
-		goto again;
+	for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++)
+		if (size >= pmb_sizes[i].size)
+			break;
 
-	return wanted - size;
+	last_addr = phys + size;
+	align_mask = ~(pmb_sizes[i].size - 1);
+	offset = phys & ~align_mask;
+	phys &= align_mask;
+	aligned = ALIGN(last_addr, pmb_sizes[i].size) - phys;
 
-out:
-	if (pmbp)
-		__pmb_unmap(pmbp);
+	/*
+	 * XXX: This should really start from uncached_end, but this
+	 * causes the MMU to reset, so for now we restrict it to the
+	 * 0xb000...0xc000 range.
+	 */
+	area = __get_vm_area_caller(aligned, VM_IOREMAP, 0xb0000000,
+				    P3SEG, caller);
+	if (!area)
+		return NULL;
 
-	return err;
+	area->phys_addr = phys;
+	vaddr = (unsigned long)area->addr;
+
+	ret = pmb_bolt_mapping(vaddr, phys, size, prot);
+	if (unlikely(ret != 0))
+		return ERR_PTR(ret);
+
+	return (void __iomem *)(offset + (char *)vaddr);
 }
 
-void pmb_unmap(unsigned long addr)
+int pmb_unmap(void __iomem *addr)
 {
 	struct pmb_entry *pmbe = NULL;
-	int i;
+	unsigned long vaddr = (unsigned long __force)addr;
+	int i, found = 0;
+
+	read_lock(&pmb_rwlock);
 
 	for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
-		if (test_bit(i, &pmb_map)) {
+		if (test_bit(i, pmb_map)) {
 			pmbe = &pmb_entry_list[i];
-			if (pmbe->vpn == addr)
+			if (pmbe->vpn == vaddr) {
+				found = 1;
 				break;
+			}
 		}
 	}
 
-	if (unlikely(!pmbe))
-		return;
+	read_unlock(&pmb_rwlock);
 
-	__pmb_unmap(pmbe);
+	if (found) {
+		pmb_unmap_entry(pmbe, NR_PMB_ENTRIES);
+		return 0;
+	}
+
+	return -EINVAL;
 }
 
-static void __pmb_unmap(struct pmb_entry *pmbe)
+static void __pmb_unmap_entry(struct pmb_entry *pmbe, int depth)
 {
-	BUG_ON(!test_bit(pmbe->entry, &pmb_map));
-
 	do {
 		struct pmb_entry *pmblink = pmbe;
 
@@ -268,102 +496,321 @@ static void __pmb_unmap(struct pmb_entry
 		 * this entry in pmb_alloc() (even if we haven't filled
 		 * it yet).
 		 *
-		 * Therefore, calling clear_pmb_entry() is safe as no
+		 * Therefore, calling __clear_pmb_entry() is safe as no
 		 * other mapping can be using that slot.
 		 */
-		clear_pmb_entry(pmbe);
+		__clear_pmb_entry(pmbe);
+
+		flush_cache_vunmap(pmbe->vpn, pmbe->vpn + pmbe->size);
 
 		pmbe = pmblink->link;
 
 		pmb_free(pmblink);
-	} while (pmbe);
+	} while (pmbe && --depth);
 }
 
-#ifdef CONFIG_PMB
-int __uses_jump_to_uncached pmb_init(void)
+static void pmb_unmap_entry(struct pmb_entry *pmbe, int depth)
 {
-	unsigned int i;
-	long size, ret;
+	unsigned long flags;
 
-	jump_to_uncached();
+	if (unlikely(!pmbe))
+		return;
+
+	write_lock_irqsave(&pmb_rwlock, flags);
+	__pmb_unmap_entry(pmbe, depth);
+	write_unlock_irqrestore(&pmb_rwlock, flags);
+}
+
+static void __init pmb_notify(void)
+{
+	int i;
+
+	pr_info("PMB: boot mappings:\n");
+
+	read_lock(&pmb_rwlock);
+
+	for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
+		struct pmb_entry *pmbe;
+
+		if (!test_bit(i, pmb_map))
+			continue;
+
+		pmbe = &pmb_entry_list[i];
+
+		pr_info("       0x%08lx -> 0x%08lx [ %4ldMB %2scached ]\n",
+			pmbe->vpn >> PAGE_SHIFT, pmbe->ppn >> PAGE_SHIFT,
+			pmbe->size >> 20, (pmbe->flags & PMB_C) ? "" : "un");
+	}
+
+	read_unlock(&pmb_rwlock);
+}
+
+/*
+ * Sync our software copy of the PMB mappings with those in hardware. The
+ * mappings in the hardware PMB were either set up by the bootloader or
+ * very early on by the kernel.
+ */
+static void __init pmb_synchronize(void)
+{
+	struct pmb_entry *pmbp = NULL;
+	int i, j;
 
 	/*
-	 * Insert PMB entries for the P1 and P2 areas so that, after
-	 * we've switched the MMU to 32-bit mode, the semantics of P1
-	 * and P2 are the same as in 29-bit mode, e.g.
+	 * Run through the initial boot mappings, log the established
+	 * ones, and blow away anything that falls outside of the valid
+	 * PPN range. Specifically, we only care about existing mappings
+	 * that impact the cached/uncached sections.
 	 *
-	 *	P1 - provides a cached window onto physical memory
-	 *	P2 - provides an uncached window onto physical memory
+	 * Note that touching these can be a bit of a minefield; the boot
+	 * loader can establish multi-page mappings with the same caching
+	 * attributes, so we need to ensure that we aren't modifying a
+	 * mapping that we're presently executing from, or may execute
+	 * from in the case of straddling page boundaries.
+	 *
+	 * In the future we will have to tidy up after the boot loader by
+	 * jumping between the cached and uncached mappings and tearing
+	 * down alternating mappings while executing from the other.
 	 */
-	size = __MEMORY_START + __MEMORY_SIZE;
+	for (i = 0; i < NR_PMB_ENTRIES; i++) {
+		unsigned long addr, data;
+		unsigned long addr_val, data_val;
+		unsigned long ppn, vpn, flags;
+		unsigned long irqflags;
+		unsigned int size;
+		struct pmb_entry *pmbe;
 
-	ret = pmb_remap(P1SEG, 0x00000000, size, PMB_C);
-	BUG_ON(ret != size);
+		addr = mk_pmb_addr(i);
+		data = mk_pmb_data(i);
 
-	ret = pmb_remap(P2SEG, 0x00000000, size, PMB_WT | PMB_UB);
-	BUG_ON(ret != size);
+		addr_val = __raw_readl(addr);
+		data_val = __raw_readl(data);
 
-	ctrl_outl(0, PMB_IRMCR);
+		/*
+		 * Skip over any bogus entries
+		 */
+		if (!(data_val & PMB_V) || !(addr_val & PMB_V))
+			continue;
 
-	/* PMB.SE and UB[7] */
-	ctrl_outl(PASCR_SE | (1 << 7), PMB_PASCR);
+		ppn = data_val & PMB_PFN_MASK;
+		vpn = addr_val & PMB_PFN_MASK;
 
-	/* Flush out the TLB */
-	i =  ctrl_inl(MMUCR);
-	i |= MMUCR_TI;
-	ctrl_outl(i, MMUCR);
+		/*
+		 * Only preserve in-range mappings.
+		 */
+		if (!pmb_ppn_in_range(ppn)) {
+			/*
+			 * Invalidate anything out of bounds.
+			 */
+			writel_uncached(addr_val & ~PMB_V, addr);
+			writel_uncached(data_val & ~PMB_V, data);
+			continue;
+		}
 
-	back_to_cached();
+		/*
+		 * Update the caching attributes if necessary
+		 */
+		if (data_val & PMB_C) {
+			data_val &= ~PMB_CACHE_MASK;
+			data_val |= pmb_cache_flags();
 
-	return 0;
+			writel_uncached(data_val, data);
+		}
+
+		size = data_val & PMB_SZ_MASK;
+		flags = size | (data_val & PMB_CACHE_MASK);
+
+		pmbe = pmb_alloc(vpn, ppn, flags, i);
+		if (IS_ERR(pmbe)) {
+			WARN_ON_ONCE(1);
+			continue;
+		}
+
+		spin_lock_irqsave(&pmbe->lock, irqflags);
+
+		for (j = 0; j < ARRAY_SIZE(pmb_sizes); j++)
+			if (pmb_sizes[j].flag == size)
+				pmbe->size = pmb_sizes[j].size;
+
+		if (pmbp) {
+			spin_lock(&pmbp->lock);
+
+			/*
+			 * Compare the previous entry against the current one to
+			 * see if the entries span a contiguous mapping. If so,
+			 * setup the entry links accordingly. Compound mappings
+			 * are later coalesced.
+			 */
+			if (pmb_can_merge(pmbp, pmbe))
+				pmbp->link = pmbe;
+
+			spin_unlock(&pmbp->lock);
+		}
+
+		pmbp = pmbe;
+
+		spin_unlock_irqrestore(&pmbe->lock, irqflags);
+	}
 }
-#else
-int __uses_jump_to_uncached pmb_init(void)
+
+static void __init pmb_merge(struct pmb_entry *head)
 {
+	unsigned long span, newsize;
+	struct pmb_entry *tail;
+	int i = 1, depth = 0;
+
+	span = newsize = head->size;
+
+	tail = head->link;
+	while (tail) {
+		span += tail->size;
+
+		if (pmb_size_valid(span)) {
+			newsize = span;
+			depth = i;
+		}
+
+		/* This is the end of the line.. */
+		if (!tail->link)
+			break;
+
+		tail = tail->link;
+		i++;
+	}
+
+	/*
+	 * The merged page size must be valid.
+	 */
+	if (!pmb_size_valid(newsize))
+		return;
+
+	head->flags &= ~PMB_SZ_MASK;
+	head->flags |= pmb_size_to_flags(newsize);
+
+	head->size = newsize;
+
+	__pmb_unmap_entry(head->link, depth);
+	__set_pmb_entry(head);
+}
+
+static void __init pmb_coalesce(void)
+{
+	unsigned long flags;
 	int i;
-	unsigned long addr, data;
 
-	jump_to_uncached();
+	write_lock_irqsave(&pmb_rwlock, flags);
 
-	for (i = 0; i < PMB_ENTRY_MAX; i++) {
+	for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
 		struct pmb_entry *pmbe;
-		unsigned long vpn, ppn, flags;
 
-		addr = PMB_DATA + (i << PMB_E_SHIFT);
-		data = ctrl_inl(addr);
-		if (!(data & PMB_V))
+		if (!test_bit(i, pmb_map))
 			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);
+		pmbe = &pmb_entry_list[i];
 
-		ppn = data & PMB_PFN_MASK;
+		/*
+		 * We're only interested in compound mappings
+		 */
+		if (!pmbe->link)
+			continue;
 
-		flags = data & (PMB_C | PMB_WT | PMB_UB);
-		flags |= data & PMB_SZ_MASK;
+		/*
+		 * Nothing to do if it already uses the largest possible
+		 * page size.
+		 */
+		if (pmbe->size == SZ_512M)
+			continue;
 
-		addr = PMB_ADDR + (i << PMB_E_SHIFT);
-		data = ctrl_inl(addr);
+		pmb_merge(pmbe);
+	}
 
-		vpn = data & PMB_PFN_MASK;
+	write_unlock_irqrestore(&pmb_rwlock, flags);
+}
 
-		pmbe = pmb_alloc(vpn, ppn, flags, i);
-		WARN_ON(IS_ERR(pmbe));
+#ifdef CONFIG_UNCACHED_MAPPING
+static void __init pmb_resize(void)
+{
+	int i;
+
+	/*
+	 * If the uncached mapping was constructed by the kernel, it will
+	 * already be a reasonable size.
+	 */
+	if (uncached_size == SZ_16M)
+		return;
+
+	read_lock(&pmb_rwlock);
+
+	for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
+		struct pmb_entry *pmbe;
+		unsigned long flags;
+
+		if (!test_bit(i, pmb_map))
+			continue;
+
+		pmbe = &pmb_entry_list[i];
+
+		if (pmbe->vpn != uncached_start)
+			continue;
+
+		/*
+		 * Found it, now resize it.
+		 */
+		spin_lock_irqsave(&pmbe->lock, flags);
+
+		pmbe->size = SZ_16M;
+		pmbe->flags &= ~PMB_SZ_MASK;
+		pmbe->flags |= pmb_size_to_flags(pmbe->size);
+
+		uncached_resize(pmbe->size);
+
+		__set_pmb_entry(pmbe);
+
+		spin_unlock_irqrestore(&pmbe->lock, flags);
 	}
 
-	back_to_cached();
+	read_lock(&pmb_rwlock);
+}
+#endif
+
+static int __init early_pmb(char *p)
+{
+	if (!p)
+		return 0;
+
+	if (strstr(p, "iomap"))
+		pmb_iomapping_enabled = 1;
 
 	return 0;
 }
-#endif /* CONFIG_PMB */
+early_param("pmb", early_pmb);
+
+void __init pmb_init(void)
+{
+	/* Synchronize software state */
+	pmb_synchronize();
+
+	/* Attempt to combine compound mappings */
+	pmb_coalesce();
+
+#ifdef CONFIG_UNCACHED_MAPPING
+	/* Resize initial mappings, if necessary */
+	pmb_resize();
+#endif
+
+	/* Log them */
+	pmb_notify();
+
+	writel_uncached(0, PMB_IRMCR);
+
+	/* Flush out the TLB */
+	local_flush_tlb_all();
+	ctrl_barrier();
+}
+
+bool __in_29bit_mode(void)
+{
+        return (__raw_readl(PMB_PASCR) & PASCR_SE) == 0;
+}
 
 static int pmb_seq_show(struct seq_file *file, void *iter)
 {
@@ -378,8 +825,8 @@ static int pmb_seq_show(struct seq_file
 		unsigned int size;
 		char *sz_str = NULL;
 
-		addr = ctrl_inl(mk_pmb_addr(i));
-		data = ctrl_inl(mk_pmb_data(i));
+		addr = __raw_readl(mk_pmb_addr(i));
+		data = __raw_readl(mk_pmb_data(i));
 
 		size = data & PMB_SZ_MASK;
 		sz_str = (size == PMB_SZ_16M)  ? " 16MB":
@@ -425,7 +872,7 @@ static int __init pmb_debugfs_init(void)
 
 	return 0;
 }
-postcore_initcall(pmb_debugfs_init);
+subsys_initcall(pmb_debugfs_init);
 
 #ifdef CONFIG_PM
 static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state)
@@ -437,14 +884,21 @@ static int pmb_sysdev_suspend(struct sys
 	if (state.event == PM_EVENT_ON &&
 	    prev_state.event == PM_EVENT_FREEZE) {
 		struct pmb_entry *pmbe;
+
+		read_lock(&pmb_rwlock);
+
 		for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
-			if (test_bit(i, &pmb_map)) {
+			if (test_bit(i, pmb_map)) {
 				pmbe = &pmb_entry_list[i];
 				set_pmb_entry(pmbe);
 			}
 		}
+
+		read_unlock(&pmb_rwlock);
 	}
+
 	prev_state = state;
+
 	return 0;
 }
 
@@ -462,6 +916,5 @@ 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.33-gnu1/arch/sh/mm/tlbflush_32.c linux-libre-2.6.34-gnu1/arch/sh/mm/tlbflush_32.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/tlbflush_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/tlbflush_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -119,22 +119,3 @@ void local_flush_tlb_mm(struct mm_struct
 		local_irq_restore(flags);
 	}
 }
-
-void local_flush_tlb_all(void)
-{
-	unsigned long flags, status;
-
-	/*
-	 * Flush all the TLB.
-	 *
-	 * Write to the MMU control register's bit:
-	 *	TF-bit for SH-3, TI-bit for SH-4.
-	 *      It's same position, bit #2.
-	 */
-	local_irq_save(flags);
-	status = ctrl_inl(MMUCR);
-	status |= 0x04;
-	ctrl_outl(status, MMUCR);
-	ctrl_barrier();
-	local_irq_restore(flags);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/tlbflush_64.c linux-libre-2.6.34-gnu1/arch/sh/mm/tlbflush_64.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/tlbflush_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/tlbflush_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,7 +36,7 @@ extern void die(const char *,struct pt_r
 
 static inline void print_prots(pgprot_t prot)
 {
-	printk("prot is 0x%08lx\n",pgprot_val(prot));
+	printk("prot is 0x%016llx\n",pgprot_val(prot));
 
 	printk("%s %s %s %s %s\n",PPROT(_PAGE_SHARED),PPROT(_PAGE_READ),
 	       PPROT(_PAGE_EXECUTE),PPROT(_PAGE_WRITE),PPROT(_PAGE_USER));
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/tlb-pteaex.c linux-libre-2.6.34-gnu1/arch/sh/mm/tlb-pteaex.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/tlb-pteaex.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/tlb-pteaex.c	2010-05-16 17:17:36.000000000 -0400
@@ -68,11 +68,40 @@ void __update_tlb(struct vm_area_struct
  * 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)
+void 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);
+	__raw_writel(page, MMU_ITLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT);
+	__raw_writel(asid, MMU_ITLB_ADDRESS_ARRAY2 | MMU_PAGE_ASSOC_BIT);
 	back_to_cached();
 }
+
+void local_flush_tlb_all(void)
+{
+	unsigned long flags, status;
+	int i;
+
+	/*
+	 * Flush all the TLB.
+	 */
+	local_irq_save(flags);
+	jump_to_uncached();
+
+	status = __raw_readl(MMUCR);
+	status = ((status & MMUCR_URB) >> MMUCR_URB_SHIFT);
+
+	if (status == 0)
+		status = MMUCR_URB_NENTRIES;
+
+	for (i = 0; i < status; i++)
+		__raw_writel(0x0, MMU_UTLB_ADDRESS_ARRAY | (i << 8));
+
+	for (i = 0; i < 4; i++)
+		__raw_writel(0x0, MMU_ITLB_ADDRESS_ARRAY | (i << 8));
+
+	back_to_cached();
+	ctrl_barrier();
+	local_irq_restore(flags);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/tlb-sh3.c linux-libre-2.6.34-gnu1/arch/sh/mm/tlb-sh3.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/tlb-sh3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/tlb-sh3.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,14 +41,14 @@ void __update_tlb(struct vm_area_struct
 
 	/* Set PTEH register */
 	vpn = (address & MMU_VPN_MASK) | get_asid();
-	ctrl_outl(vpn, MMU_PTEH);
+	__raw_writel(vpn, MMU_PTEH);
 
 	pteval = pte_val(pte);
 
 	/* Set PTEL register */
 	pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
 	/* conveniently, we want all the software flags to be 0 anyway */
-	ctrl_outl(pteval, MMU_PTEL);
+	__raw_writel(pteval, MMU_PTEL);
 
 	/* Load the TLB */
 	asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
@@ -75,5 +75,24 @@ void local_flush_tlb_one(unsigned long a
 	}
 
 	for (i = 0; i < ways; i++)
-		ctrl_outl(data, addr + (i << 8));
+		__raw_writel(data, addr + (i << 8));
+}
+
+void local_flush_tlb_all(void)
+{
+	unsigned long flags, status;
+
+	/*
+	 * Flush all the TLB.
+	 *
+	 * Write to the MMU control register's bit:
+	 *	TF-bit for SH-3, TI-bit for SH-4.
+	 *      It's same position, bit #2.
+	 */
+	local_irq_save(flags);
+	status = __raw_readl(MMUCR);
+	status |= 0x04;
+	__raw_writel(status, MMUCR);
+	ctrl_barrier();
+	local_irq_restore(flags);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/tlb-sh4.c linux-libre-2.6.34-gnu1/arch/sh/mm/tlb-sh4.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/tlb-sh4.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/tlb-sh4.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,7 +29,7 @@ void __update_tlb(struct vm_area_struct
 
 	/* Set PTEH register */
 	vpn = (address & MMU_VPN_MASK) | get_asid();
-	ctrl_outl(vpn, MMU_PTEH);
+	__raw_writel(vpn, MMU_PTEH);
 
 	pteval = pte.pte_low;
 
@@ -41,13 +41,13 @@ void __update_tlb(struct vm_area_struct
 	 * the protection bits (with the exception of the compat-mode SZ
 	 * and PR bits, which are cleared) being written out in PTEL.
 	 */
-	ctrl_outl(pte.pte_high, MMU_PTEA);
+	__raw_writel(pte.pte_high, MMU_PTEA);
 #else
 	if (cpu_data->flags & CPU_HAS_PTEA) {
 		/* The last 3 bits and the first one of pteval contains
 		 * the PTEA timing control and space attribute bits
 		 */
-		ctrl_outl(copy_ptea_attributes(pteval), MMU_PTEA);
+		__raw_writel(copy_ptea_attributes(pteval), MMU_PTEA);
 	}
 #endif
 
@@ -57,15 +57,14 @@ void __update_tlb(struct vm_area_struct
 	pteval |= _PAGE_WT;
 #endif
 	/* conveniently, we want all the software flags to be 0 anyway */
-	ctrl_outl(pteval, MMU_PTEL);
+	__raw_writel(pteval, MMU_PTEL);
 
 	/* Load the TLB */
 	asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
 	local_irq_restore(flags);
 }
 
-void __uses_jump_to_uncached local_flush_tlb_one(unsigned long asid,
-						 unsigned long page)
+void local_flush_tlb_one(unsigned long asid, unsigned long page)
 {
 	unsigned long addr, data;
 
@@ -78,6 +77,34 @@ void __uses_jump_to_uncached local_flush
 	addr = MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT;
 	data = page | asid; /* VALID bit is off */
 	jump_to_uncached();
-	ctrl_outl(data, addr);
+	__raw_writel(data, addr);
 	back_to_cached();
 }
+
+void local_flush_tlb_all(void)
+{
+	unsigned long flags, status;
+	int i;
+
+	/*
+	 * Flush all the TLB.
+	 */
+	local_irq_save(flags);
+	jump_to_uncached();
+
+	status = __raw_readl(MMUCR);
+	status = ((status & MMUCR_URB) >> MMUCR_URB_SHIFT);
+
+	if (status == 0)
+		status = MMUCR_URB_NENTRIES;
+
+	for (i = 0; i < status; i++)
+		__raw_writel(0x0, MMU_UTLB_ADDRESS_ARRAY | (i << 8));
+
+	for (i = 0; i < 4; i++)
+		__raw_writel(0x0, MMU_ITLB_ADDRESS_ARRAY | (i << 8));
+
+	back_to_cached();
+	ctrl_barrier();
+	local_irq_restore(flags);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/tlb-sh5.c linux-libre-2.6.34-gnu1/arch/sh/mm/tlb-sh5.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/tlb-sh5.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/tlb-sh5.c	2010-05-16 17:17:36.000000000 -0400
@@ -143,3 +143,42 @@ void sh64_setup_tlb_slot(unsigned long l
  */
 void sh64_teardown_tlb_slot(unsigned long long config_addr)
 	__attribute__ ((alias("__flush_tlb_slot")));
+
+static int dtlb_entry;
+static unsigned long long dtlb_entries[64];
+
+void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
+{
+	unsigned long long entry;
+	unsigned long paddr, flags;
+
+	BUG_ON(dtlb_entry == ARRAY_SIZE(dtlb_entries));
+
+	local_irq_save(flags);
+
+	entry = sh64_get_wired_dtlb_entry();
+	dtlb_entries[dtlb_entry++] = entry;
+
+	paddr = pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK;
+	paddr &= ~PAGE_MASK;
+
+	sh64_setup_tlb_slot(entry, addr, get_asid(), paddr);
+
+	local_irq_restore(flags);
+}
+
+void tlb_unwire_entry(void)
+{
+	unsigned long long entry;
+	unsigned long flags;
+
+	BUG_ON(!dtlb_entry);
+
+	local_irq_save(flags);
+	entry = dtlb_entries[dtlb_entry--];
+
+	sh64_teardown_tlb_slot(entry);
+	sh64_put_wired_dtlb_entry(entry);
+
+	local_irq_restore(flags);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/tlb-urb.c linux-libre-2.6.34-gnu1/arch/sh/mm/tlb-urb.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/tlb-urb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/tlb-urb.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,93 @@
+/*
+ * arch/sh/mm/tlb-urb.c
+ *
+ * TLB entry wiring helpers for URB-equipped parts.
+ *
+ * Copyright (C) 2010  Matt Fleming
+ *
+ * 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/io.h>
+#include <asm/tlb.h>
+#include <asm/mmu_context.h>
+
+/*
+ * Load the entry for 'addr' into the TLB and wire the entry.
+ */
+void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
+{
+	unsigned long status, flags;
+	int urb;
+
+	local_irq_save(flags);
+
+	status = __raw_readl(MMUCR);
+	urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT;
+	status &= ~MMUCR_URC;
+
+	/*
+	 * Make sure we're not trying to wire the last TLB entry slot.
+	 */
+	BUG_ON(!--urb);
+
+	urb = urb % MMUCR_URB_NENTRIES;
+
+	/*
+	 * Insert this entry into the highest non-wired TLB slot (via
+	 * the URC field).
+	 */
+	status |= (urb << MMUCR_URC_SHIFT);
+	__raw_writel(status, MMUCR);
+	ctrl_barrier();
+
+	/* Load the entry into the TLB */
+	__update_tlb(vma, addr, pte);
+
+	/* ... and wire it up. */
+	status = __raw_readl(MMUCR);
+
+	status &= ~MMUCR_URB;
+	status |= (urb << MMUCR_URB_SHIFT);
+
+	__raw_writel(status, MMUCR);
+	ctrl_barrier();
+
+	local_irq_restore(flags);
+}
+
+/*
+ * Unwire the last wired TLB entry.
+ *
+ * It should also be noted that it is not possible to wire and unwire
+ * TLB entries in an arbitrary order. If you wire TLB entry N, followed
+ * by entry N+1, you must unwire entry N+1 first, then entry N. In this
+ * respect, it works like a stack or LIFO queue.
+ */
+void tlb_unwire_entry(void)
+{
+	unsigned long status, flags;
+	int urb;
+
+	local_irq_save(flags);
+
+	status = __raw_readl(MMUCR);
+	urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT;
+	status &= ~MMUCR_URB;
+
+	/*
+	 * Make sure we're not trying to unwire a TLB entry when none
+	 * have been wired.
+	 */
+	BUG_ON(urb++ == MMUCR_URB_NENTRIES);
+
+	urb = urb % MMUCR_URB_NENTRIES;
+
+	status |= (urb << MMUCR_URB_SHIFT);
+	__raw_writel(status, MMUCR);
+	ctrl_barrier();
+
+	local_irq_restore(flags);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/mm/uncached.c linux-libre-2.6.34-gnu1/arch/sh/mm/uncached.c
--- linux-libre-2.6.33-gnu1/arch/sh/mm/uncached.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/mm/uncached.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,43 @@
+#include <linux/init.h>
+#include <linux/module.h>
+#include <asm/sizes.h>
+#include <asm/page.h>
+#include <asm/addrspace.h>
+
+/*
+ * This is the offset of the uncached section from its cached alias.
+ *
+ * Legacy platforms handle trivial transitions between cached and
+ * uncached segments by making use of the 1:1 mapping relationship in
+ * 512MB lowmem, others via a special uncached mapping.
+ *
+ * Default value only valid in 29 bit mode, in 32bit mode this will be
+ * updated by the early PMB initialization code.
+ */
+unsigned long cached_to_uncached = SZ_512M;
+unsigned long uncached_size = SZ_512M;
+unsigned long uncached_start, uncached_end;
+EXPORT_SYMBOL(uncached_start);
+EXPORT_SYMBOL(uncached_end);
+
+int virt_addr_uncached(unsigned long kaddr)
+{
+	return (kaddr >= uncached_start) && (kaddr < uncached_end);
+}
+EXPORT_SYMBOL(virt_addr_uncached);
+
+void __init uncached_init(void)
+{
+#ifdef CONFIG_29BIT
+	uncached_start = P2SEG;
+#else
+	uncached_start = memory_end;
+#endif
+	uncached_end = uncached_start + uncached_size;
+}
+
+void __init uncached_resize(unsigned long size)
+{
+	uncached_size = size;
+	uncached_end = uncached_start + uncached_size;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/sh/tools/mach-types linux-libre-2.6.34-gnu1/arch/sh/tools/mach-types
--- linux-libre-2.6.33-gnu1/arch/sh/tools/mach-types	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sh/tools/mach-types	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@ DREAMCAST		SH_DREAMCAST
 SNAPGEAR		SH_SECUREEDGE5410
 EDOSK7705		SH_EDOSK7705
 EDOSK7760		SH_EDOSK7760
+SDK7786			SH_SDK7786
 SH4202_MICRODEV		SH_SH4202_MICRODEV
 SH03			SH_SH03
 LANDISK			SH_LANDISK
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/configs/sparc32_defconfig linux-libre-2.6.34-gnu1/arch/sparc/configs/sparc32_defconfig
--- linux-libre-2.6.33-gnu1/arch/sparc/configs/sparc32_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/configs/sparc32_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan 11 23:20:31 2010
+# Linux kernel version: 2.6.33
+# Wed Mar  3 02:52:23 2010
 #
 # CONFIG_64BIT is not set
 CONFIG_SPARC=y
@@ -9,6 +9,8 @@ CONFIG_SPARC32=y
 # CONFIG_SPARC64 is not set
 CONFIG_ARCH_DEFCONFIG="arch/sparc/configs/sparc32_defconfig"
 CONFIG_BITS=32
+CONFIG_GENERIC_TIME=y
+CONFIG_ARCH_USES_GETTIMEOFFSET=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_MMU=y
 CONFIG_HIGHMEM=y
@@ -48,11 +50,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=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
@@ -68,6 +65,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -211,7 +209,6 @@ CONFIG_SBUSCHAR=y
 CONFIG_PCI=y
 CONFIG_PCI_SYSCALL=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -232,7 +229,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -379,11 +375,13 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
 # EEPROM support
 #
+# CONFIG_EEPROM_AT25 is not set
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
@@ -507,7 +505,9 @@ CONFIG_SUNQE=m
 # 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_GRETH is not set
 # CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
@@ -521,6 +521,7 @@ CONFIG_SUNQE=m
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
 # CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
@@ -563,6 +564,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -665,6 +667,7 @@ CONFIG_DEVKMEM=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_SUNCORE=y
 CONFIG_SERIAL_SUNZILOG=y
 CONFIG_SERIAL_SUNZILOG_CONSOLE=y
@@ -689,7 +692,23 @@ CONFIG_HW_RANDOM=m
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
 # CONFIG_I2C 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=m
+CONFIG_SPI_XILINX=m
+CONFIG_SPI_XILINX_PLTFM=m
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
 
 #
 # PPS support
@@ -706,10 +725,13 @@ CONFIG_HWMON=y
 #
 # Native drivers
 #
+# CONFIG_SENSORS_ADCXX is not set
 # CONFIG_SENSORS_I5K_AMB is not set
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_F71882FG is not set
 # CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_MAX1111 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
@@ -720,6 +742,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_THERMAL is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
@@ -736,6 +759,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -743,6 +768,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
@@ -808,6 +834,14 @@ CONFIG_RTC_INTF_DEV=y
 #
 # SPI RTC drivers
 #
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -1180,9 +1214,11 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/configs/sparc64_defconfig linux-libre-2.6.34-gnu1/arch/sparc/configs/sparc64_defconfig
--- linux-libre-2.6.33-gnu1/arch/sparc/configs/sparc64_defconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/configs/sparc64_defconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Jan 20 16:31:47 2010
+# Linux kernel version: 2.6.34-rc3
+# Sat Apr  3 15:49:56 2010
 #
 CONFIG_64BIT=y
 CONFIG_SPARC=y
@@ -23,6 +23,7 @@ CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
 CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_MMU=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_OF=y
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -55,14 +56,10 @@ CONFIG_TREE_RCU=y
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=64
 # CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=18
-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=y
@@ -77,6 +74,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -105,7 +103,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 CONFIG_PERF_COUNTERS=y
 # CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
@@ -266,7 +263,6 @@ CONFIG_PCI_DOMAINS=y
 CONFIG_PCI_SYSCALL=y
 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
@@ -290,7 +286,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -425,10 +420,6 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
-
-#
-# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
-#
 # CONFIG_BLK_DEV_DRBD is not set
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
@@ -449,6 +440,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -521,6 +513,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -677,6 +670,7 @@ CONFIG_SUNGEM=m
 CONFIG_SUNVNET=m
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_ETHOC is not set
+# CONFIG_GRETH is not set
 # CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
@@ -691,6 +685,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 # CONFIG_E100 is not set
@@ -741,6 +736,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_VXGE is not set
@@ -751,6 +747,7 @@ CONFIG_NIU=m
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -894,6 +891,7 @@ CONFIG_SERIAL_SUNHV=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -941,6 +939,7 @@ CONFIG_I2C_ALGOBIT=y
 #
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -954,15 +953,9 @@ CONFIG_I2C_ALGOBIT=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -988,10 +981,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1028,6 +1022,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1057,18 +1052,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1076,6 +1074,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1117,6 +1116,7 @@ CONFIG_FB_FFB=y
 # CONFIG_FB_LEO is not set
 CONFIG_FB_XVR500=y
 CONFIG_FB_XVR2500=y
+CONFIG_FB_XVR1000=y
 # CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
@@ -1279,6 +1279,7 @@ CONFIG_SND_ALI5451=m
 # CONFIG_SND_YMFPCI is not set
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_CAIAQ is not set
 CONFIG_SND_SPARC=y
 # CONFIG_SND_SUN_AMD7930 is not set
@@ -1301,6 +1302,7 @@ CONFIG_USB_HIDDEV=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1317,14 +1319,19 @@ CONFIG_HID_KENSINGTON=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 CONFIG_HID_NTRIG=y
+CONFIG_HID_ORTEK=y
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 CONFIG_HID_GREENASIA=y
 # CONFIG_GREENASIA_FF is not set
@@ -1427,7 +1434,6 @@ CONFIG_USB_STORAGE=m
 # 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
@@ -1440,7 +1446,6 @@ CONFIG_USB_STORAGE=m
 # 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
 
 #
@@ -1607,6 +1612,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1621,6 +1627,7 @@ CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1807,6 +1814,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 CONFIG_CRYPTO_GF128MUL=m
 CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=y
@@ -1904,9 +1912,11 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/compat.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/compat.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/compat.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/compat.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,8 @@
  */
 #include <linux/types.h>
 
-#define COMPAT_USER_HZ	100
+#define COMPAT_USER_HZ		100
+#define COMPAT_UTS_MACHINE	"sparc\0\0"
 
 typedef u32		compat_size_t;
 typedef s32		compat_ssize_t;
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/cpudata_64.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/cpudata_64.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/cpudata_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/cpudata_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ typedef struct {
 	unsigned int	__nmi_count;
 	unsigned long	clock_tick;	/* %tick's per second */
 	unsigned long	__pad;
-	unsigned int	__pad1;
+	unsigned int	irq0_irqs;
 	unsigned int	__pad2;
 
 	/* Dcache line 2, rarely used */
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/dma-mapping.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/dma-mapping.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/dma-mapping.h	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,6 @@
 #define DMA_ERROR_CODE	(~(dma_addr_t)0x0)
 
 extern int dma_supported(struct device *dev, u64 mask);
-extern int dma_set_mask(struct device *dev, u64 dma_mask);
 
 #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)
@@ -62,4 +61,17 @@ static inline int dma_get_cache_alignmen
 	return (1 << INTERNODE_CACHE_SHIFT);
 }
 
+static inline int dma_set_mask(struct device *dev, u64 mask)
+{
+#ifdef CONFIG_PCI
+	if (dev->bus == &pci_bus_type) {
+		if (!dev->dma_mask || !dma_supported(dev, mask))
+			return -EINVAL;
+		*dev->dma_mask = mask;
+		return 0;
+	}
+#endif
+	return -EINVAL;
+}
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/fbio.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/fbio.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/fbio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/fbio.h	2010-05-16 17:17:36.000000000 -0400
@@ -173,7 +173,7 @@ struct mdi_cfginfo {
 	int     mdi_ncluts;     /* Number of implemented CLUTs in this MDI */
         int     mdi_type;       /* FBTYPE name */
         int     mdi_height;     /* height */
-        int     mdi_width;      /* widht */
+        int     mdi_width;      /* width */
         int     mdi_size;       /* available ram */
         int     mdi_mode;       /* 8bpp, 16bpp or 32bpp */
         int     mdi_pixfreq;    /* pixel clock (from PROM) */
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/io_32.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/io_32.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/io_32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/io_32.h	2010-05-16 17:17:36.000000000 -0400
@@ -249,10 +249,14 @@ extern void iounmap(volatile void __iome
 
 #define ioread8(X)			readb(X)
 #define ioread16(X)			readw(X)
+#define ioread16be(X)			__raw_readw(X)
 #define ioread32(X)			readl(X)
+#define ioread32be(X)			__raw_readl(X)
 #define iowrite8(val,X)			writeb(val,X)
 #define iowrite16(val,X)		writew(val,X)
+#define iowrite16be(val,X)		__raw_writew(val,X)
 #define iowrite32(val,X)		writel(val,X)
+#define iowrite32be(val,X)		__raw_writel(val,X)
 
 static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/io_64.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/io_64.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/io_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/io_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -468,10 +468,14 @@ static inline void iounmap(volatile void
 
 #define ioread8(X)			readb(X)
 #define ioread16(X)			readw(X)
+#define ioread16be(X)			__raw_readw(X)
 #define ioread32(X)			readl(X)
+#define ioread32be(X)			__raw_readl(X)
 #define iowrite8(val,X)			writeb(val,X)
 #define iowrite16(val,X)		writew(val,X)
+#define iowrite16be(val,X)		__raw_writew(val,X)
 #define iowrite32(val,X)		writel(val,X)
+#define iowrite32be(val,X)		__raw_writel(val,X)
 
 /* Create a virtual mapping cookie for an IO port range */
 extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/irqflags_64.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/irqflags_64.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/irqflags_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/irqflags_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -76,9 +76,26 @@ static inline int raw_irqs_disabled(void
  */
 static inline unsigned long __raw_local_irq_save(void)
 {
-	unsigned long flags = __raw_local_save_flags();
+	unsigned long flags, tmp;
 
-	raw_local_irq_disable();
+	/* Disable interrupts to PIL_NORMAL_MAX unless we already
+	 * are using PIL_NMI, in which case PIL_NMI is retained.
+	 *
+	 * The only values we ever program into the %pil are 0,
+	 * PIL_NORMAL_MAX and PIL_NMI.
+	 *
+	 * Since PIL_NMI is the largest %pil value and all bits are
+	 * set in it (0xf), it doesn't matter what PIL_NORMAL_MAX
+	 * actually is.
+	 */
+	__asm__ __volatile__(
+		"rdpr	%%pil, %0\n\t"
+		"or	%0, %2, %1\n\t"
+		"wrpr	%1, 0x0, %%pil"
+		: "=r" (flags), "=r" (tmp)
+		: "i" (PIL_NORMAL_MAX)
+		: "memory"
+	);
 
 	return flags;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/pci_32.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/pci_32.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/pci_32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/pci_32.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,20 +32,6 @@ static inline void pcibios_penalize_isa_
 
 struct pci_dev;
 
-/* pci_unmap_{single,page} is not a nop, thus... */
-#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_PCI
 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 					enum pci_dma_burst_strategy *strat,
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/pci_64.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/pci_64.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/pci_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/pci_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,20 +32,6 @@ static inline void pcibios_penalize_isa_
  */
 #define PCI_DMA_BUS_IS_PHYS	(0)
 
-/* pci_unmap_{single,page} is not a nop, thus... */
-#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))
-
 /* PCI IOMMU mapping bypass support. */
 
 /* PCI 64-bit addressing works for all slots on all controller
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/perfctr.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/perfctr.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/perfctr.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/perfctr.h	2010-05-16 17:17:36.000000000 -0400
@@ -10,8 +10,8 @@
  * from enumeration below.  The meaning of further arguments
  * are determined by the operation code.
  *
- * int sys_perfctr(int opcode, unsigned long arg0,
- *                 unsigned long arg1, unsigned long arg2)
+ * NOTE: This system call is no longer provided, use the perf_events
+ *       infrastructure.
  *
  * Pointers which are passed by the user are pointers to 64-bit
  * integers.
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/pgtable_32.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/pgtable_32.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/pgtable_32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/pgtable_32.h	2010-05-16 17:17:36.000000000 -0400
@@ -330,9 +330,9 @@ BTFIXUPDEF_CALL(void, mmu_info, struct s
 #define FAULT_CODE_WRITE    0x2
 #define FAULT_CODE_USER     0x4
 
-BTFIXUPDEF_CALL(void, update_mmu_cache, struct vm_area_struct *, unsigned long, pte_t)
+BTFIXUPDEF_CALL(void, update_mmu_cache, struct vm_area_struct *, unsigned long, pte_t *)
 
-#define update_mmu_cache(vma,addr,pte) BTFIXUP_CALL(update_mmu_cache)(vma,addr,pte)
+#define update_mmu_cache(vma,addr,ptep) BTFIXUP_CALL(update_mmu_cache)(vma,addr,ptep)
 
 BTFIXUPDEF_CALL(void, sparc_mapiorange, unsigned int, unsigned long,
     unsigned long, unsigned int)
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/pgtable_64.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/pgtable_64.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/pgtable_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/pgtable_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -706,7 +706,7 @@ extern unsigned long find_ecache_flush_s
 #define mmu_unlockarea(vaddr, len)		do { } while(0)
 
 struct vm_area_struct;
-extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
+extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
 
 /* Encode and de-code a swap entry */
 #define __swp_type(entry)	(((entry).val >> PAGE_SHIFT) & 0xffUL)
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/scatterlist.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/scatterlist.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/scatterlist.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/scatterlist.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,27 +1,8 @@
 #ifndef _SPARC_SCATTERLIST_H
 #define _SPARC_SCATTERLIST_H
 
-#include <asm/page.h>
-#include <asm/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;
-	__u32		dma_length;
-};
-
-#define sg_dma_address(sg)	((sg)->dma_address)
 #define sg_dma_len(sg)     	((sg)->dma_length)
 
-#define ISA_DMA_THRESHOLD	(~0UL)
-
-#define ARCH_HAS_SG_CHAIN
+#include <asm-generic/scatterlist.h>
 
 #endif /* !(_SPARC_SCATTERLIST_H) */
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/stat.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/stat.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/stat.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/stat.h	2010-05-16 17:17:36.000000000 -0400
@@ -53,8 +53,8 @@ struct stat {
 	ino_t		st_ino;
 	mode_t		st_mode;
 	short		st_nlink;
-	uid16_t		st_uid;
-	gid16_t		st_gid;
+	unsigned short	st_uid;
+	unsigned short	st_gid;
 	unsigned short	st_rdev;
 	off_t		st_size;
 	time_t		st_atime;
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/syscall.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/syscall.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/syscall.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/syscall.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,13 @@
 #include <linux/sched.h>
 #include <asm/ptrace.h>
 
+/*
+ * The syscall table always contains 32 bit pointers since we know that the
+ * address of the function to be called is (way) below 4GB.  So the "int"
+ * type here is what we want [need] for both 32 bit and 64 bit systems.
+ */
+extern const unsigned int sys_call_table[];
+
 /* The system call number is given by the user in %g1 */
 static inline long syscall_get_nr(struct task_struct *task,
 				  struct pt_regs *regs)
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/system_64.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/system_64.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/system_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/system_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -143,15 +143,7 @@ do {						\
 	 * and 2 stores in this critical code path.  -DaveM
 	 */
 #define switch_to(prev, next, last)					\
-do {	if (test_thread_flag(TIF_PERFCTR)) {				\
-		unsigned long __tmp;					\
-		read_pcr(__tmp);					\
-		current_thread_info()->pcr_reg = __tmp;			\
-		read_pic(__tmp);					\
-		current_thread_info()->kernel_cntd0 += (unsigned int)(__tmp);\
-		current_thread_info()->kernel_cntd1 += ((__tmp) >> 32);	\
-	}								\
-	flush_tlb_pending();						\
+do {	flush_tlb_pending();						\
 	save_and_clear_fpu();						\
 	/* If you are tempted to conditionalize the following */	\
 	/* so that ASI is only written if it changes, think again. */	\
@@ -197,11 +189,6 @@ do {	if (test_thread_flag(TIF_PERFCTR))
 	        "l1", "l2", "l3", "l4", "l5", "l6", "l7",		\
 	  "i0", "i1", "i2", "i3", "i4", "i5",				\
 	  "o0", "o1", "o2", "o3", "o4", "o5",       "o7");		\
-	/* If you fuck with this, update ret_from_syscall code too. */	\
-	if (test_thread_flag(TIF_PERFCTR)) {				\
-		write_pcr(current_thread_info()->pcr_reg);		\
-		reset_pic();						\
-	}								\
 } while(0)
 
 static inline unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val)
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/thread_info_64.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/thread_info_64.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/thread_info_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/thread_info_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -58,11 +58,6 @@ struct thread_info {
 	unsigned long		gsr[7];
 	unsigned long		xfsr[7];
 
-	__u64			__user *user_cntd0;
-	__u64			__user *user_cntd1;
-	__u64			kernel_cntd0, kernel_cntd1;
-	__u64			pcr_reg;
-
 	struct restart_block	restart_block;
 
 	struct pt_regs		*kern_una_regs;
@@ -96,15 +91,10 @@ struct thread_info {
 #define TI_RWIN_SPTRS	0x000003c8
 #define TI_GSR		0x00000400
 #define TI_XFSR		0x00000438
-#define TI_USER_CNTD0	0x00000470
-#define TI_USER_CNTD1	0x00000478
-#define TI_KERN_CNTD0	0x00000480
-#define TI_KERN_CNTD1	0x00000488
-#define TI_PCR		0x00000490
-#define TI_RESTART_BLOCK 0x00000498
-#define TI_KUNA_REGS	0x000004c8
-#define TI_KUNA_INSN	0x000004d0
-#define TI_FPREGS	0x00000500
+#define TI_RESTART_BLOCK 0x00000470
+#define TI_KUNA_REGS	0x000004a0
+#define TI_KUNA_INSN	0x000004a8
+#define TI_FPREGS	0x000004c0
 
 /* We embed this in the uppermost byte of thread_info->flags */
 #define FAULT_CODE_WRITE	0x01	/* Write access, implies D-TLB	   */
@@ -121,7 +111,7 @@ struct thread_info {
 #define THREAD_SHIFT PAGE_SHIFT
 #endif /* PAGE_SHIFT == 13 */
 
-#define PREEMPT_ACTIVE		0x4000000
+#define PREEMPT_ACTIVE		0x10000000
 
 /*
  * macros/functions for gaining access to the thread information structure
@@ -199,7 +189,7 @@ register struct thread_info *current_thr
  *
  * On trap return we need to test several values:
  *
- * user:	need_resched, notify_resume, sigpending, wsaved, perfctr
+ * user:	need_resched, notify_resume, sigpending, wsaved
  * kernel:	fpdepth
  *
  * So to check for work in the kernel case we simply load the fpdepth
@@ -220,7 +210,7 @@ register struct thread_info *current_thr
 #define TIF_NOTIFY_RESUME	1	/* callback before returning to user */
 #define TIF_SIGPENDING		2	/* signal pending */
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
-#define TIF_PERFCTR		4	/* performance counters active */
+/* flag bit 4 is available */
 #define TIF_UNALIGNED		5	/* allowed to do unaligned accesses */
 /* flag bit 6 is available */
 #define TIF_32BIT		7	/* 32-bit binary */
@@ -241,7 +231,6 @@ register struct thread_info *current_thr
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
-#define _TIF_PERFCTR		(1<<TIF_PERFCTR)
 #define _TIF_UNALIGNED		(1<<TIF_UNALIGNED)
 #define _TIF_32BIT		(1<<TIF_32BIT)
 #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
@@ -252,7 +241,7 @@ register struct thread_info *current_thr
 
 #define _TIF_USER_WORK_MASK	((0xff << TI_FLAG_WSAVED_SHIFT) | \
 				 _TIF_DO_NOTIFY_RESUME_MASK | \
-				 _TIF_NEED_RESCHED | _TIF_PERFCTR)
+				 _TIF_NEED_RESCHED)
 #define _TIF_DO_NOTIFY_RESUME_MASK	(_TIF_NOTIFY_RESUME | _TIF_SIGPENDING)
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/include/asm/unistd.h linux-libre-2.6.34-gnu1/arch/sparc/include/asm/unistd.h
--- linux-libre-2.6.33-gnu1/arch/sparc/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/include/asm/unistd.h	2010-05-16 17:17:36.000000000 -0400
@@ -432,7 +432,9 @@
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
-#ifndef __32bit_syscall_numbers__
+#ifdef __32bit_syscall_numbers__
+#define __ARCH_WANT_SYS_IPC
+#else
 #define __ARCH_WANT_COMPAT_SYS_TIME
 #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/Kconfig linux-libre-2.6.34-gnu1/arch/sparc/Kconfig
--- linux-libre-2.6.33-gnu1/arch/sparc/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,9 @@ config SPARC64
 	def_bool 64BIT
 	select ARCH_SUPPORTS_MSI
 	select HAVE_FUNCTION_TRACER
+	select HAVE_FUNCTION_GRAPH_TRACER
+	select HAVE_FUNCTION_GRAPH_FP_TEST
+	select HAVE_FUNCTION_TRACE_MCOUNT_TEST
 	select HAVE_KRETPROBES
 	select HAVE_KPROBES
 	select HAVE_LMB
@@ -127,6 +130,9 @@ config ZONE_DMA
 	bool
 	default y if SPARC32
 
+config NEED_DMA_MAP_STATE
+	def_bool y
+
 config GENERIC_ISA_DMA
 	bool
 	default y if SPARC32
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/Kconfig.debug linux-libre-2.6.34-gnu1/arch/sparc/Kconfig.debug
--- linux-libre-2.6.33-gnu1/arch/sparc/Kconfig.debug	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/Kconfig.debug	2010-05-16 17:17:36.000000000 -0400
@@ -19,13 +19,10 @@ config DEBUG_DCFLUSH
 	bool "D-cache flush debugging"
 	depends on SPARC64 && DEBUG_KERNEL
 
-config STACK_DEBUG
-	bool "Stack Overflow Detection Support"
-
 config MCOUNT
 	bool
 	depends on SPARC64
-	depends on STACK_DEBUG || FUNCTION_TRACER
+	depends on FUNCTION_TRACER
 	default y
 
 config FRAME_POINTER
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/central.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/central.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/central.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/central.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
 
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/of_device.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/cpumap.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/cpumap.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/cpumap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/cpumap.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/cpumask.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/devices.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/devices.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/devices.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/devices.c	2010-05-16 17:17:36.000000000 -0400
@@ -59,7 +59,7 @@ static int __cpu_find_by(int (*compare)(
 
 	cur_inst = 0;
 	for_each_node_by_type(dp, "cpu") {
-		int err = check_cpu_node(dp->node, &cur_inst,
+		int err = check_cpu_node(dp->phandle, &cur_inst,
 					 compare, compare_arg,
 					 prom_node, mid);
 		if (!err) {
@@ -143,6 +143,4 @@ void __init device_scan(void)
 
 	if (ARCH_SUN4C)
 		sun4c_probe_memerr_reg();
-
-	return;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/entry.h linux-libre-2.6.34-gnu1/arch/sparc/kernel/entry.h
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/entry.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/entry.h	2010-05-16 17:17:36.000000000 -0400
@@ -48,7 +48,6 @@ extern void __init boot_cpu_id_too_large
 extern unsigned int dcache_parity_tl1_occurred;
 extern unsigned int icache_parity_tl1_occurred;
 
-extern asmlinkage void update_perfctrs(void);
 extern asmlinkage void sparc_breakpoint(struct pt_regs *regs);
 extern void timer_interrupt(int irq, struct pt_regs *regs);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/ftrace.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/ftrace.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/ftrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/ftrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,7 @@ static const u32 ftrace_nop = 0x01000000
 
 static u32 ftrace_call_replace(unsigned long ip, unsigned long addr)
 {
-	static u32 call;
+	u32 call;
 	s32 off;
 
 	off = ((s32)addr - (s32)ip);
@@ -92,13 +92,60 @@ int __init ftrace_dyn_arch_init(void *da
 }
 #endif
 
-#ifdef CONFIG_FTRACE_SYSCALLS
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
 
-extern unsigned int sys_call_table[];
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern void ftrace_graph_call(void);
 
-unsigned long __init arch_syscall_addr(int nr)
+int ftrace_enable_ftrace_graph_caller(void)
 {
-	return (unsigned long)sys_call_table[nr];
+	unsigned long ip = (unsigned long)(&ftrace_graph_call);
+	u32 old, new;
+
+	old = *(u32 *) &ftrace_graph_call;
+	new = ftrace_call_replace(ip, (unsigned long) &ftrace_graph_caller);
+	return ftrace_modify_code(ip, old, new);
 }
 
-#endif
+int ftrace_disable_ftrace_graph_caller(void)
+{
+	unsigned long ip = (unsigned long)(&ftrace_graph_call);
+	u32 old, new;
+
+	old = *(u32 *) &ftrace_graph_call;
+	new = ftrace_call_replace(ip, (unsigned long) &ftrace_stub);
+
+	return ftrace_modify_code(ip, old, new);
+}
+
+#endif /* !CONFIG_DYNAMIC_FTRACE */
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+unsigned long prepare_ftrace_return(unsigned long parent,
+				    unsigned long self_addr,
+				    unsigned long frame_pointer)
+{
+	unsigned long return_hooker = (unsigned long) &return_to_handler;
+	struct ftrace_graph_ent trace;
+
+	if (unlikely(atomic_read(&current->tracing_graph_pause)))
+		return parent + 8UL;
+
+	if (ftrace_push_return_trace(parent, self_addr, &trace.depth,
+				     frame_pointer) == -EBUSY)
+		return parent + 8UL;
+
+	trace.func = self_addr;
+
+	/* Only trace if the calling function expects to */
+	if (!ftrace_graph_entry(&trace)) {
+		current->curr_ret_stack--;
+		return parent + 8UL;
+	}
+
+	return return_hooker;
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/helpers.S linux-libre-2.6.34-gnu1/arch/sparc/kernel/helpers.S
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/helpers.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/helpers.S	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,81 @@ stack_trace_flush:
 	 nop
 	.size		stack_trace_flush,.-stack_trace_flush
 
+#ifdef CONFIG_PERF_EVENTS
+	.globl		perf_arch_fetch_caller_regs
+	.type		perf_arch_fetch_caller_regs,#function
+perf_arch_fetch_caller_regs:
+	/* We always read the %pstate into %o5 since we will use
+	 * that to construct a fake %tstate to store into the regs.
+	 */
+	rdpr		%pstate, %o5
+	brz,pn		%o2, 50f
+	 mov		%o2, %g7
+
+	/* Turn off interrupts while we walk around the register
+	 * window by hand.
+	 */
+	wrpr		%o5, PSTATE_IE, %pstate
+
+	/* The %canrestore tells us how many register windows are
+	 * still live in the chip above us, past that we have to
+	 * walk the frame as saved on the stack.   We stash away
+	 * the %cwp in %g1 so we can return back to the original
+	 * register window.
+	 */
+	rdpr		%cwp, %g1
+	rdpr		%canrestore, %g2
+	sub		%g1, 1, %g3
+
+	/* We have the skip count in %g7, if it hits zero then
+	 * %fp/%i7 are the registers we need.  Otherwise if our
+	 * %canrestore count maintained in %g2 hits zero we have
+	 * to start traversing the stack.
+	 */
+10:	brz,pn		%g2, 4f
+	 sub		%g2, 1, %g2
+	wrpr		%g3, %cwp
+	subcc		%g7, 1, %g7
+	bne,pt		%xcc, 10b
+	 sub		%g3, 1, %g3
+
+	/* We found the values we need in the cpu's register
+	 * windows.
+	 */
+	mov		%fp, %g3
+	ba,pt		%xcc, 3f
+	 mov		%i7, %g2
+
+50:	mov		%fp, %g3
+	ba,pt		%xcc, 2f
+	 mov		%i7, %g2
+
+	/* We hit the end of the valid register windows in the
+	 * cpu, start traversing the stack frame.
+	 */
+4:	mov		%fp, %g3
+
+20:	ldx		[%g3 + STACK_BIAS + RW_V9_I7], %g2
+	subcc		%g7, 1, %g7
+	bne,pn		%xcc, 20b
+	 ldx		[%g3 + STACK_BIAS + RW_V9_I6], %g3
+
+	/* Restore the current register window position and
+	 * re-enable interrupts.
+	 */
+3:	wrpr		%g1, %cwp
+	wrpr		%o5, %pstate
+
+2:	stx		%g3, [%o0 + PT_V9_FP]
+	sllx		%o5, 8, %o5
+	stx		%o5, [%o0 + PT_V9_TSTATE]
+	stx		%g2, [%o0 + PT_V9_TPC]
+	add		%g2, 4, %g2
+	retl
+	 stx		%g2, [%o0 + PT_V9_TNPC]
+	.size		perf_arch_fetch_caller_regs,.-perf_arch_fetch_caller_regs
+#endif /* CONFIG_PERF_EVENTS */
+
 #ifdef CONFIG_SMP
 	.globl		hard_smp_processor_id
 	.type		hard_smp_processor_id,#function
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/hvapi.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/hvapi.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/hvapi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/hvapi.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 
 #include <asm/hypervisor.h>
 #include <asm/oplib.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/iommu.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/iommu.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/iommu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/iommu.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
@@ -862,13 +863,3 @@ int dma_supported(struct device *dev, u6
 	return 0;
 }
 EXPORT_SYMBOL(dma_supported);
-
-int dma_set_mask(struct device *dev, u64 dma_mask)
-{
-#ifdef CONFIG_PCI
-	if (dev->bus == &pci_bus_type)
-		return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
-#endif
-	return -EINVAL;
-}
-EXPORT_SYMBOL(dma_set_mask);
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/ioport.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/ioport.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/ioport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/ioport.c	2010-05-16 17:17:36.000000000 -0400
@@ -676,17 +676,6 @@ int dma_supported(struct device *dev, u6
 }
 EXPORT_SYMBOL(dma_supported);
 
-int dma_set_mask(struct device *dev, u64 dma_mask)
-{
-#ifdef CONFIG_PCI
-	if (dev->bus == &pci_bus_type)
-		return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
-#endif
-	return -EOPNOTSUPP;
-}
-EXPORT_SYMBOL(dma_set_mask);
-
-
 #ifdef CONFIG_PROC_FS
 
 static int sparc_io_proc_show(struct seq_file *m, void *v)
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/irq_64.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/irq_64.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/irq_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/irq_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,7 +20,9 @@
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/ftrace.h>
 #include <linux/irq.h>
+#include <linux/kmemleak.h>
 
 #include <asm/ptrace.h>
 #include <asm/processor.h>
@@ -45,6 +47,7 @@
 
 #include "entry.h"
 #include "cpumap.h"
+#include "kstack.h"
 
 #define NUM_IVECS	(IMAP_INR + 1)
 
@@ -647,6 +650,14 @@ unsigned int sun4v_build_virq(u32 devhan
 	bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC);
 	if (unlikely(!bucket))
 		return 0;
+
+	/* The only reference we store to the IRQ bucket is
+	 * by physical address which kmemleak can't see, tell
+	 * it that this object explicitly is not a leak and
+	 * should be scanned.
+	 */
+	kmemleak_not_leak(bucket);
+
 	__flush_dcache_range((unsigned long) bucket,
 			     ((unsigned long) bucket +
 			      sizeof(struct ino_bucket)));
@@ -703,25 +714,7 @@ void ack_bad_irq(unsigned int virt_irq)
 void *hardirq_stack[NR_CPUS];
 void *softirq_stack[NR_CPUS];
 
-static __attribute__((always_inline)) void *set_hardirq_stack(void)
-{
-	void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
-
-	__asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
-	if (orig_sp < sp ||
-	    orig_sp > (sp + THREAD_SIZE)) {
-		sp += THREAD_SIZE - 192 - STACK_BIAS;
-		__asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
-	}
-
-	return orig_sp;
-}
-static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
-{
-	__asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
-}
-
-void handler_irq(int irq, struct pt_regs *regs)
+void __irq_entry handler_irq(int irq, struct pt_regs *regs)
 {
 	unsigned long pstate, bucket_pa;
 	struct pt_regs *old_regs;
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/kgdb_64.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/kgdb_64.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/kgdb_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/kgdb_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
 
 #include <linux/kgdb.h>
 #include <linux/kdebug.h>
+#include <linux/ftrace.h>
 
 #include <asm/kdebug.h>
 #include <asm/ptrace.h>
@@ -108,7 +109,7 @@ void gdb_regs_to_pt_regs(unsigned long *
 }
 
 #ifdef CONFIG_SMP
-void smp_kgdb_capture_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_kgdb_capture_client(int irq, struct pt_regs *regs)
 {
 	unsigned long flags;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/kprobes.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/kprobes.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/kprobes.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/kprobes.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
 #include <linux/kprobes.h>
 #include <linux/module.h>
 #include <linux/kdebug.h>
+#include <linux/slab.h>
 #include <asm/signal.h>
 #include <asm/cacheflush.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/kstack.h linux-libre-2.6.34-gnu1/arch/sparc/kernel/kstack.h
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/kstack.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/kstack.h	2010-05-16 17:17:36.000000000 -0400
@@ -61,4 +61,23 @@ check_magic:
 
 }
 
+static inline __attribute__((always_inline)) void *set_hardirq_stack(void)
+{
+	void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
+
+	__asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
+	if (orig_sp < sp ||
+	    orig_sp > (sp + THREAD_SIZE)) {
+		sp += THREAD_SIZE - 192 - STACK_BIAS;
+		__asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
+	}
+
+	return orig_sp;
+}
+
+static inline __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
+{
+	__asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
+}
+
 #endif /* _KSTACK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/led.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/led.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/led.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/led.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/jiffies.h>
 #include <linux/timer.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/leon_kernel.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/leon_kernel.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/leon_kernel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/leon_kernel.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,6 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/mutex.h>
-#include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/interrupt.h>
@@ -124,7 +123,7 @@ void __init leon_init_timers(irq_handler
 
 		if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) &
 		      (1<<LEON3_GPTIMER_SEPIRQ))) {
-			prom_printf("irq timer not configured with seperate irqs \n");
+			prom_printf("irq timer not configured with separate irqs\n");
 			BUG();
 		}
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/leon_smp.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/leon_smp.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/leon_smp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/leon_smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/profile.h>
 #include <linux/pm.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
@@ -177,7 +178,7 @@ void __init leon_boot_cpus(void)
 	int nrcpu = leon_smp_nrcpus();
 	int me = smp_processor_id();
 
-	printk(KERN_INFO "%d:(%d:%d) cpus mpirq at 0x%x \n", (unsigned int)me,
+	printk(KERN_INFO "%d:(%d:%d) cpus mpirq at 0x%x\n", (unsigned int)me,
 	       (unsigned int)nrcpu, (unsigned int)NR_CPUS,
 	       (unsigned int)&(leon3_irqctrl_regs->mpstatus));
 
@@ -226,7 +227,7 @@ int __cpuinit leon_boot_one_cpu(int i)
 			break;
 		udelay(200);
 	}
-	printk(KERN_INFO "Started CPU %d \n", (unsigned int)i);
+	printk(KERN_INFO "Started CPU %d\n", (unsigned int)i);
 
 	if (!(cpu_callin_map[i])) {
 		printk(KERN_ERR "Processor %d is stuck.\n", i);
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/Makefile linux-libre-2.6.34-gnu1/arch/sparc/kernel/Makefile
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,14 @@ extra-y     += init_task.o
 CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS)
 extra-y              += vmlinux.lds
 
+ifdef CONFIG_FUNCTION_TRACER
+# Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_ftrace.o := -pg
+CFLAGS_REMOVE_time_$(BITS).o := -pg
+CFLAGS_REMOVE_perf_event.o := -pg
+CFLAGS_REMOVE_pcr.o := -pg
+endif
+
 obj-$(CONFIG_SPARC32)   += entry.o wof.o wuf.o
 obj-$(CONFIG_SPARC32)   += etrap_32.o
 obj-$(CONFIG_SPARC32)   += rtrap_32.o
@@ -85,7 +93,7 @@ obj-$(CONFIG_KGDB)        += kgdb_$(BITS
 
 
 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
-CFLAGS_REMOVE_ftrace.o := -pg
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
 
 obj-$(CONFIG_EARLYFB) += btext.o
 obj-$(CONFIG_STACKTRACE)     += stacktrace.o
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/module.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/module.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/module.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/module.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,9 +9,9 @@
 #include <linux/elf.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 
 #include <asm/processor.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/nmi.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/nmi.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/nmi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/nmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,9 +21,10 @@
 
 #include <asm/perf_event.h>
 #include <asm/ptrace.h>
-#include <asm/local.h>
 #include <asm/pcr.h>
 
+#include "kstack.h"
+
 /* We don't have a real NMI on sparc64, but we can fake one
  * up using profiling counter overflow interrupts and interrupt
  * levels.
@@ -93,7 +94,7 @@ static void die_nmi(const char *str, str
 notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
 {
 	unsigned int sum, touched = 0;
-	int cpu = smp_processor_id();
+	void *orig_sp;
 
 	clear_softint(1 << irq);
 
@@ -101,31 +102,35 @@ notrace __kprobes void perfctr_irq(int i
 
 	nmi_enter();
 
+	orig_sp = set_hardirq_stack();
+
 	if (notify_die(DIE_NMI, "nmi", regs, 0,
 		       pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
 		touched = 1;
 	else
 		pcr_ops->write(PCR_PIC_PRIV);
 
-	sum = kstat_irqs_cpu(0, cpu);
+	sum = local_cpu_data().irq0_irqs;
 	if (__get_cpu_var(nmi_touch)) {
 		__get_cpu_var(nmi_touch) = 0;
 		touched = 1;
 	}
 	if (!touched && __get_cpu_var(last_irq_sum) == sum) {
-		__this_cpu_inc(per_cpu_var(alert_counter));
-		if (__this_cpu_read(per_cpu_var(alert_counter)) == 30 * nmi_hz)
+		__this_cpu_inc(alert_counter);
+		if (__this_cpu_read(alert_counter) == 30 * nmi_hz)
 			die_nmi("BUG: NMI Watchdog detected LOCKUP",
 				regs, panic_on_timeout);
 	} else {
 		__get_cpu_var(last_irq_sum) = sum;
-		__this_cpu_write(per_cpu_var(alert_counter), 0);
+		__this_cpu_write(alert_counter, 0);
 	}
 	if (__get_cpu_var(wd_enabled)) {
 		write_pic(picl_value(nmi_hz));
 		pcr_ops->write(pcr_enable);
 	}
 
+	restore_hardirq_stack(orig_sp);
+
 	nmi_exit();
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/of_device_32.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/of_device_32.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/of_device_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/of_device_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -433,7 +433,7 @@ build_resources:
 	if (!parent)
 		dev_set_name(&op->dev, "root");
 	else
-		dev_set_name(&op->dev, "%08x", dp->node);
+		dev_set_name(&op->dev, "%08x", dp->phandle);
 
 	if (of_device_register(op)) {
 		printk("%s: Could not register of device.\n",
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/of_device_64.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/of_device_64.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/of_device_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/of_device_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -676,7 +676,7 @@ static struct of_device * __init scan_on
 	if (!parent)
 		dev_set_name(&op->dev, "root");
 	else
-		dev_set_name(&op->dev, "%08x", dp->node);
+		dev_set_name(&op->dev, "%08x", dp->phandle);
 
 	if (of_device_register(op)) {
 		printk("%s: Could not register of device.\n",
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/of_device_common.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/of_device_common.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/of_device_common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/of_device_common.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/irq.h>
 #include <linux/of_device.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/pci.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/pci.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -722,9 +722,10 @@ void pcibios_update_irq(struct pci_dev *
 {
 }
 
-void pcibios_align_resource(void *data, struct resource *res,
-			    resource_size_t size, resource_size_t align)
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+				resource_size_t size, resource_size_t align)
 {
+	return res->start;
 }
 
 int pcibios_enable_device(struct pci_dev *dev, int mask)
@@ -1094,3 +1095,78 @@ static int __init pcibios_init(void)
 	return 0;
 }
 subsys_initcall(pcibios_init);
+
+#ifdef CONFIG_SYSFS
+static void __devinit pci_bus_slot_names(struct device_node *node,
+					 struct pci_bus *bus)
+{
+	const struct pci_slot_names {
+		u32	slot_mask;
+		char	names[0];
+	} *prop;
+	const char *sp;
+	int len, i;
+	u32 mask;
+
+	prop = of_get_property(node, "slot-names", &len);
+	if (!prop)
+		return;
+
+	mask = prop->slot_mask;
+	sp = prop->names;
+
+	if (ofpci_verbose)
+		printk("PCI: Making slots for [%s] mask[0x%02x]\n",
+		       node->full_name, mask);
+
+	i = 0;
+	while (mask) {
+		struct pci_slot *pci_slot;
+		u32 this_bit = 1 << i;
+
+		if (!(mask & this_bit)) {
+			i++;
+			continue;
+		}
+
+		if (ofpci_verbose)
+			printk("PCI: Making slot [%s]\n", sp);
+
+		pci_slot = pci_create_slot(bus, i, sp, NULL);
+		if (IS_ERR(pci_slot))
+			printk(KERN_ERR "PCI: pci_create_slot returned %ld\n",
+			       PTR_ERR(pci_slot));
+
+		sp += strlen(sp) + 1;
+		mask &= ~this_bit;
+		i++;
+	}
+}
+
+static int __init of_pci_slot_init(void)
+{
+	struct pci_bus *pbus = NULL;
+
+	while ((pbus = pci_find_next_bus(pbus)) != NULL) {
+		struct device_node *node;
+
+		if (pbus->self) {
+			struct dev_archdata *sd = pbus->self->sysdata;
+
+			/* PCI->PCI bridge */
+			node = sd->prom_node;
+		} else {
+			struct pci_pbm_info *pbm = pbus->sysdata;
+
+			/* Host PCI controller */
+			node = pbm->op->node;
+		}
+
+		pci_bus_slot_names(node, pbus);
+	}
+
+	return 0;
+}
+
+module_init(of_pci_slot_init);
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/pcic.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/pcic.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/pcic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/pcic.c	2010-05-16 17:17:36.000000000 -0400
@@ -585,8 +585,6 @@ pcic_fill_irq(struct linux_pcic *pcic, s
 			writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_LO);
 		}
  	}
-
-	return;
 }
 
 /*
@@ -768,9 +766,10 @@ char * __devinit pcibios_setup(char *str
 	return str;
 }
 
-void pcibios_align_resource(void *data, struct resource *res,
-			    resource_size_t size, resource_size_t align)
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+				resource_size_t size, resource_size_t align)
 {
+	return res->start;
 }
 
 int pcibios_enable_device(struct pci_dev *pdev, int mask)
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/pci_common.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/pci_common.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/pci_common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/pci_common.c	2010-05-16 17:17:36.000000000 -0400
@@ -371,14 +371,19 @@ static void pci_register_iommu_region(st
 		struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL);
 
 		if (!rp) {
-			prom_printf("Cannot allocate IOMMU resource.\n");
-			prom_halt();
+			pr_info("%s: Cannot allocate IOMMU resource.\n",
+				pbm->name);
+			return;
 		}
 		rp->name = "IOMMU";
 		rp->start = pbm->mem_space.start + (unsigned long) vdma[0];
 		rp->end = rp->start + (unsigned long) vdma[1] - 1UL;
 		rp->flags = IORESOURCE_BUSY;
-		request_resource(&pbm->mem_space, rp);
+		if (request_resource(&pbm->mem_space, rp)) {
+			pr_info("%s: Unable to request IOMMU resource.\n",
+				pbm->name);
+			kfree(rp);
+		}
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/pci_msi.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/pci_msi.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/pci_msi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/pci_msi.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/irq.h>
 
 #include "pci_impl.h"
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/pcr.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/pcr.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/pcr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/pcr.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 #include <linux/irq.h>
 
 #include <linux/perf_event.h>
+#include <linux/ftrace.h>
 
 #include <asm/pil.h>
 #include <asm/pcr.h>
@@ -34,7 +35,7 @@ unsigned int picl_shift;
  * Therefore in such situations we defer the work by signalling
  * a lower level cpu IRQ.
  */
-void deferred_pcr_work_irq(int irq, struct pt_regs *regs)
+void __irq_entry deferred_pcr_work_irq(int irq, struct pt_regs *regs)
 {
 	struct pt_regs *old_regs;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/perf_event.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/perf_event.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/perf_event.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/perf_event.c	2010-05-16 17:17:36.000000000 -0400
@@ -980,10 +980,10 @@ static int collect_events(struct perf_ev
 	return n;
 }
 
-static void event_sched_in(struct perf_event *event, int cpu)
+static void event_sched_in(struct perf_event *event)
 {
 	event->state = PERF_EVENT_STATE_ACTIVE;
-	event->oncpu = cpu;
+	event->oncpu = smp_processor_id();
 	event->tstamp_running += event->ctx->time - event->tstamp_stopped;
 	if (is_software_event(event))
 		event->pmu->enable(event);
@@ -991,7 +991,7 @@ static void event_sched_in(struct perf_e
 
 int hw_perf_group_sched_in(struct perf_event *group_leader,
 			   struct perf_cpu_context *cpuctx,
-			   struct perf_event_context *ctx, int cpu)
+			   struct perf_event_context *ctx)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	struct perf_event *sub;
@@ -1015,10 +1015,10 @@ int hw_perf_group_sched_in(struct perf_e
 
 	cpuctx->active_oncpu += n;
 	n = 1;
-	event_sched_in(group_leader, cpu);
+	event_sched_in(group_leader);
 	list_for_each_entry(sub, &group_leader->sibling_list, group_entry) {
 		if (sub->state != PERF_EVENT_STATE_OFF) {
-			event_sched_in(sub, cpu);
+			event_sched_in(sub);
 			n++;
 		}
 	}
@@ -1189,7 +1189,7 @@ static int __kprobes perf_event_nmi_hand
 
 	regs = args->regs;
 
-	data.addr = 0;
+	perf_sample_data_init(&data, 0);
 
 	cpuc = &__get_cpu_var(cpu_hw_events);
 
@@ -1337,7 +1337,7 @@ static void perf_callchain_user_32(struc
 	callchain_store(entry, PERF_CONTEXT_USER);
 	callchain_store(entry, regs->tpc);
 
-	ufp = regs->u_regs[UREG_I6];
+	ufp = regs->u_regs[UREG_I6] & 0xffffffffUL;
 	do {
 		struct sparc_stackf32 *usf, sf;
 		unsigned long pc;
@@ -1353,7 +1353,7 @@ static void perf_callchain_user_32(struc
 }
 
 /* Like powerpc we can't get PMU interrupts within the PMU handler,
- * so no need for seperate NMI and IRQ chains as on x86.
+ * so no need for separate NMI and IRQ chains as on x86.
  */
 static DEFINE_PER_CPU(struct perf_callchain_entry, callchain);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/process_32.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/process_32.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/process_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/process_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,13 +17,13 @@
 #include <linux/mm.h>
 #include <linux/stddef.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/smp.h>
 #include <linux/reboot.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include <asm/auxio.h>
 #include <asm/oplib.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/process_64.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/process_64.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/process_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/process_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -352,12 +352,6 @@ void exit_thread(void)
 		else
 			t->utraps[0]--;
 	}
-
-	if (test_and_clear_thread_flag(TIF_PERFCTR)) {
-		t->user_cntd0 = t->user_cntd1 = NULL;
-		t->pcr_reg = 0;
-		write_pcr(0);
-	}
 }
 
 void flush_thread(void)
@@ -371,13 +365,6 @@ void flush_thread(void)
 
 	set_thread_wsaved(0);
 
-	/* Turn off performance counters if on. */
-	if (test_and_clear_thread_flag(TIF_PERFCTR)) {
-		t->user_cntd0 = t->user_cntd1 = NULL;
-		t->pcr_reg = 0;
-		write_pcr(0);
-	}
-
 	/* Clear FPU register state. */
 	t->fpsaved[0] = 0;
 	
@@ -591,16 +578,6 @@ int copy_thread(unsigned long clone_flag
 		t->kregs->u_regs[UREG_FP] =
 		  ((unsigned long) child_sf) - STACK_BIAS;
 
-		/* Special case, if we are spawning a kernel thread from
-		 * a userspace task (usermode helper, NFS or similar), we
-		 * must disable performance counters in the child because
-		 * the address space and protection realm are changing.
-		 */
-		if (t->flags & _TIF_PERFCTR) {
-			t->user_cntd0 = t->user_cntd1 = NULL;
-			t->pcr_reg = 0;
-			t->flags &= ~_TIF_PERFCTR;
-		}
 		t->flags |= ((long)ASI_P << TI_FLAG_CURRENT_DS_SHIFT);
 		t->kregs->u_regs[UREG_G6] = (unsigned long) t;
 		t->kregs->u_regs[UREG_G4] = (unsigned long) t->task;
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/prom_common.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/prom_common.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/prom_common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/prom_common.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,18 +37,6 @@ EXPORT_SYMBOL(of_console_path);
 char *of_console_options;
 EXPORT_SYMBOL(of_console_options);
 
-struct device_node *of_find_node_by_phandle(phandle handle)
-{
-	struct device_node *np;
-
-	for (np = allnodes; np; np = np->allnext)
-		if (np->node == handle)
-			break;
-
-	return np;
-}
-EXPORT_SYMBOL(of_find_node_by_phandle);
-
 int of_getintprop_default(struct device_node *np, const char *name, int def)
 {
 	struct property *prop;
@@ -89,7 +77,7 @@ int of_set_property(struct device_node *
 			void *old_val = prop->value;
 			int ret;
 
-			ret = prom_setprop(dp->node, name, val, len);
+			ret = prom_setprop(dp->phandle, name, val, len);
 
 			err = -EINVAL;
 			if (ret >= 0) {
@@ -236,7 +224,7 @@ static struct device_node * __init prom_
 
 	dp->name = get_one_property(node, "name");
 	dp->type = get_one_property(node, "device_type");
-	dp->node = node;
+	dp->phandle = node;
 
 	dp->properties = build_prop_list(node);
 
@@ -313,7 +301,7 @@ void __init prom_build_devicetree(void)
 
 	nextp = &allnodes->allnext;
 	allnodes->child = prom_build_tree(allnodes,
-					  prom_getchild(allnodes->node),
+					  prom_getchild(allnodes->phandle),
 					  &nextp);
 	of_console_init();
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/prom.h linux-libre-2.6.34-gnu1/arch/sparc/kernel/prom.h
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/prom.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/prom.h	2010-05-16 17:17:36.000000000 -0400
@@ -4,9 +4,6 @@
 #include <linux/spinlock.h>
 #include <asm/prom.h>
 
-extern struct device_node *allnodes;	/* temporary while merging */
-extern rwlock_t devtree_lock;	/* temporary while merging */
-
 extern void * prom_early_alloc(unsigned long size);
 extern void irq_trans_init(struct device_node *dp);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/ptrace_32.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/ptrace_32.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/ptrace_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/ptrace_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,6 +65,7 @@ static int genregs32_get(struct task_str
 			*k++ = regs->u_regs[pos++];
 
 		reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
+		reg_window -= 16;
 		for (; count > 0 && pos < 32; count--) {
 			if (get_user(*k++, &reg_window[pos++]))
 				return -EFAULT;
@@ -76,6 +77,7 @@ static int genregs32_get(struct task_str
 		}
 
 		reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
+		reg_window -= 16;
 		for (; count > 0 && pos < 32; count--) {
 			if (get_user(reg, &reg_window[pos++]) ||
 			    put_user(reg, u++))
@@ -141,6 +143,7 @@ static int genregs32_set(struct task_str
 			regs->u_regs[pos++] = *k++;
 
 		reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
+		reg_window -= 16;
 		for (; count > 0 && pos < 32; count--) {
 			if (put_user(*k++, &reg_window[pos++]))
 				return -EFAULT;
@@ -153,6 +156,7 @@ static int genregs32_set(struct task_str
 		}
 
 		reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
+		reg_window -= 16;
 		for (; count > 0 && pos < 32; count--) {
 			if (get_user(reg, u++) ||
 			    put_user(reg, &reg_window[pos++]))
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/ptrace_64.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/ptrace_64.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/ptrace_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/ptrace_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -492,6 +492,7 @@ static int genregs32_get(struct task_str
 			*k++ = regs->u_regs[pos++];
 
 		reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
+		reg_window -= 16;
 		if (target == current) {
 			for (; count > 0 && pos < 32; count--) {
 				if (get_user(*k++, &reg_window[pos++]))
@@ -516,6 +517,7 @@ static int genregs32_get(struct task_str
 		}
 
 		reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
+		reg_window -= 16;
 		if (target == current) {
 			for (; count > 0 && pos < 32; count--) {
 				if (get_user(reg, &reg_window[pos++]) ||
@@ -599,6 +601,7 @@ static int genregs32_set(struct task_str
 			regs->u_regs[pos++] = *k++;
 
 		reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
+		reg_window -= 16;
 		if (target == current) {
 			for (; count > 0 && pos < 32; count--) {
 				if (put_user(*k++, &reg_window[pos++]))
@@ -625,6 +628,7 @@ static int genregs32_set(struct task_str
 		}
 
 		reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
+		reg_window -= 16;
 		if (target == current) {
 			for (; count > 0 && pos < 32; count--) {
 				if (get_user(reg, u++) ||
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/rtrap_64.S linux-libre-2.6.34-gnu1/arch/sparc/kernel/rtrap_64.S
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/rtrap_64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/rtrap_64.S	2010-05-16 17:17:36.000000000 -0400
@@ -65,48 +65,6 @@ __handle_user_windows:
 		ba,pt			%xcc, __handle_user_windows_continue
 
 		 andn			%l1, %l4, %l1
-__handle_perfctrs:
-		call			update_perfctrs
-		 wrpr			%g0, RTRAP_PSTATE, %pstate
-		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
-		ldub			[%g6 + TI_WSAVED], %o2
-		brz,pt			%o2, 1f
-		 nop
-		/* Redo userwin+sched+sig checks */
-		call			fault_in_user_windows
-
-		 wrpr			%g0, RTRAP_PSTATE, %pstate
-		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
-		ldx			[%g6 + TI_FLAGS], %l0
-		andcc			%l0, _TIF_NEED_RESCHED, %g0
-		be,pt			%xcc, 1f
-
-		 nop
-		call			schedule
-		 wrpr			%g0, RTRAP_PSTATE, %pstate
-		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
-		ldx			[%g6 + TI_FLAGS], %l0
-1:		andcc			%l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0
-
-		be,pt			%xcc, __handle_perfctrs_continue
-		 sethi			%hi(TSTATE_PEF), %o0
-		mov			%l5, %o1
-		add			%sp, PTREGS_OFF, %o0
-		mov			%l0, %o2
-		call			do_notify_resume
-
-		 wrpr			%g0, RTRAP_PSTATE, %pstate
-		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
-		/* Signal delivery can modify pt_regs tstate, so we must
-		 * reload it.
-		 */
-		ldx			[%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
-		sethi			%hi(0xf << 20), %l4
-		and			%l1, %l4, %l4
-		andn			%l1, %l4, %l1
-		ba,pt			%xcc, __handle_perfctrs_continue
-
-		 sethi			%hi(TSTATE_PEF), %o0
 __handle_userfpu:
 		rd			%fprs, %l5
 		andcc			%l5, FPRS_FEF, %g0
@@ -149,11 +107,11 @@ rtrap_nmi:	ldx			[%sp + PTREGS_OFF + PT_
 rtrap_irq:
 rtrap:
 #ifndef CONFIG_SMP
-		sethi			%hi(per_cpu____cpu_data), %l0
-		lduw			[%l0 + %lo(per_cpu____cpu_data)], %l1
+		sethi			%hi(__cpu_data), %l0
+		lduw			[%l0 + %lo(__cpu_data)], %l1
 #else
-		sethi			%hi(per_cpu____cpu_data), %l0
-		or			%l0, %lo(per_cpu____cpu_data), %l0
+		sethi			%hi(__cpu_data), %l0
+		or			%l0, %lo(__cpu_data), %l0
 		lduw			[%l0 + %g5], %l1
 #endif
 		cmp			%l1, 0
@@ -172,7 +130,17 @@ rtrap_xcall:
 		 nop
 		call			trace_hardirqs_on
 		 nop
-		wrpr			%l4, %pil
+		/* Do not actually set the %pil here.  We will do that
+		 * below after we clear PSTATE_IE in the %pstate register.
+		 * If we re-enable interrupts here, we can recurse down
+		 * the hardirq stack potentially endlessly, causing a
+		 * stack overflow.
+		 *
+		 * It is tempting to put this test and trace_hardirqs_on
+		 * call at the 'rt_continue' label, but that will not work
+		 * as that path hits unconditionally and we do not want to
+		 * execute this in NMI return paths, for example.
+		 */
 #endif
 rtrap_no_irq_enable:
 		andcc			%l1, TSTATE_PRIV, %l3
@@ -191,9 +159,9 @@ rtrap_no_irq_enable:
 		 * take until the next local IRQ before the signal/resched
 		 * event would be handled.
 		 *
-		 * This also means that if we have to deal with performance
-		 * counters or user windows, we have to redo all of these
-		 * sched+signal checks with IRQs disabled.
+		 * This also means that if we have to deal with user
+		 * windows, we have to redo all of these sched+signal checks
+		 * with IRQs disabled.
 		 */
 to_user:	wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
 		wrpr			0, %pil
@@ -214,12 +182,8 @@ __handle_signal_continue:
 		brnz,pn			%o2, __handle_user_windows
 		 nop
 __handle_user_windows_continue:
-		ldx			[%g6 + TI_FLAGS], %l5
-		andcc			%l5, _TIF_PERFCTR, %g0
 		sethi			%hi(TSTATE_PEF), %o0
-		bne,pn			%xcc, __handle_perfctrs
-__handle_perfctrs_continue:
-		 andcc			%l1, %o0, %g0
+		andcc			%l1, %o0, %g0
 
 		/* This fpdepth clear is necessary for non-syscall rtraps only */
 user_nowork:
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/setup_32.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/setup_32.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/setup_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/setup_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -95,8 +95,6 @@ static void prom_sync_me(void)
 			     "nop\n\t"
 			     "nop\n\t" : : "r" (prom_tbr));
 	local_irq_restore(flags);
-
-	return;
 }
 
 static unsigned int boot_flags __initdata = 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/setup_64.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/setup_64.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/setup_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/setup_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <asm/smp.h>
 #include <linux/user.h>
 #include <linux/screen_info.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/smp_64.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/smp_64.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/smp_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/smp_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,9 @@
 #include <linux/profile.h>
 #include <linux/bootmem.h>
 #include <linux/vmalloc.h>
+#include <linux/ftrace.h>
 #include <linux/cpu.h>
+#include <linux/slab.h>
 
 #include <asm/head.h>
 #include <asm/ptrace.h>
@@ -370,7 +372,7 @@ static int __cpuinit smp_boot_one_cpu(un
 	} else {
 		struct device_node *dp = of_find_node_by_cpuid(cpu);
 
-		prom_startcpu(dp->node, entry, cookie);
+		prom_startcpu(dp->phandle, entry, cookie);
 	}
 
 	for (timeout = 0; timeout < 50000; timeout++) {
@@ -822,13 +824,13 @@ void arch_send_call_function_single_ipi(
 		      &cpumask_of_cpu(cpu));
 }
 
-void smp_call_function_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs)
 {
 	clear_softint(1 << irq);
 	generic_smp_call_function_interrupt();
 }
 
-void smp_call_function_single_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs)
 {
 	clear_softint(1 << irq);
 	generic_smp_call_function_single_interrupt();
@@ -964,7 +966,7 @@ void flush_dcache_page_all(struct mm_str
 	put_cpu();
 }
 
-void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
 {
 	struct mm_struct *mm;
 	unsigned long flags;
@@ -1148,7 +1150,7 @@ void smp_release(void)
  */
 extern void prom_world(int);
 
-void smp_penguin_jailcell(int irq, struct pt_regs *regs)
+void __irq_entry smp_penguin_jailcell(int irq, struct pt_regs *regs)
 {
 	clear_softint(1 << irq);
 
@@ -1364,7 +1366,7 @@ void smp_send_reschedule(int cpu)
 		      &cpumask_of_cpu(cpu));
 }
 
-void smp_receive_signal_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs)
 {
 	clear_softint(1 << irq);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/sun4c_irq.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/sun4c_irq.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/sun4c_irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/sun4c_irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/sched.h>
 #include <linux/ptrace.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/sun4d_smp.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/sun4d_smp.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/sun4d_smp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/sun4d_smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -194,7 +194,7 @@ int __cpuinit smp4d_boot_one_cpu(int i)
 			smp_penguin_ctable.reg_size = 0;
 
 			/* whirrr, whirrr, whirrrrrrrrr... */
-			SMP_PRINTK(("Starting CPU %d at %p \n", i, entry));
+			SMP_PRINTK(("Starting CPU %d at %p\n", i, entry));
 			local_flush_cache_all();
 			prom_startcpu(cpu_node,
 				      &smp_penguin_ctable, 0, (char *)entry);
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/sun4m_irq.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/sun4m_irq.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/sun4m_irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/sun4m_irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/ptrace.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/of.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/sys32.S linux-libre-2.6.34-gnu1/arch/sparc/kernel/sys32.S
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/sys32.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/sys32.S	2010-05-16 17:17:36.000000000 -0400
@@ -51,7 +51,6 @@ SIGN1(sys32_exit_group, sys_exit_group,
 SIGN1(sys32_wait4, compat_sys_wait4, %o2)
 SIGN1(sys32_creat, sys_creat, %o1)
 SIGN1(sys32_mknod, sys_mknod, %o1)
-SIGN1(sys32_perfctr, sys_perfctr, %o0)
 SIGN1(sys32_umount, sys_umount, %o1)
 SIGN1(sys32_signal, sys_signal, %o0)
 SIGN1(sys32_access, sys_access, %o1)
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/syscalls.S linux-libre-2.6.34-gnu1/arch/sparc/kernel/syscalls.S
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/syscalls.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/syscalls.S	2010-05-16 17:17:36.000000000 -0400
@@ -110,31 +110,12 @@ sys_clone:
 
 	.globl	ret_from_syscall
 ret_from_syscall:
-	/* Clear current_thread_info()->new_child, and
-	 * check performance counter stuff too.
-	 */
+	/* Clear current_thread_info()->new_child. */
 	stb	%g0, [%g6 + TI_NEW_CHILD]
 	ldx	[%g6 + TI_FLAGS], %l0
 	call	schedule_tail
 	 mov	%g7, %o0
-	andcc	%l0, _TIF_PERFCTR, %g0
-	be,pt	%icc, 1f
-	 nop
-	ldx	[%g6 + TI_PCR], %o7
-	wr	%g0, %o7, %pcr
-
-	/* Blackbird errata workaround.  See commentary in
-	 * smp.c:smp_percpu_timer_interrupt() for more
-	 * information.
-	 */
-	ba,pt	%xcc, 99f
-	 nop
-
-	.align	64
-99:	wr	%g0, %g0, %pic
-	rd	%pic, %g0
-
-1:	ba,pt	%xcc, ret_sys_call
+	ba,pt	%xcc, ret_sys_call
 	 ldx	[%sp + PTREGS_OFF + PT_V9_I0], %o0
 
 	.globl	sparc_exit
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/sysfs.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/sysfs.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -107,12 +107,12 @@ static unsigned long run_on_cpu(unsigned
 	unsigned long ret;
 
 	/* should return -EINVAL to userspace */
-	if (set_cpus_allowed(current, cpumask_of_cpu(cpu)))
+	if (set_cpus_allowed_ptr(current, cpumask_of(cpu)))
 		return 0;
 
 	ret = func(arg);
 
-	set_cpus_allowed(current, old_affinity);
+	set_cpus_allowed_ptr(current, &old_affinity);
 
 	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/sys_sparc_32.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/sys_sparc_32.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/sys_sparc_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/sys_sparc_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -98,119 +98,6 @@ out:
 	return error;
 }
 
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-
-asmlinkage int sys_ipc (uint call, int first, int second, int third, void __user *ptr, long fifth)
-{
-	int version, err;
-
-	version = call >> 16; /* hack for backward compatibility */
-	call &= 0xffff;
-
-	if (call <= SEMCTL)
-		switch (call) {
-		case SEMOP:
-			err = sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL);
-			goto out;
-		case SEMTIMEDOP:
-			err = sys_semtimedop (first, (struct sembuf __user *)ptr, second, (const struct timespec __user *) fifth);
-			goto out;
-		case SEMGET:
-			err = sys_semget (first, second, third);
-			goto out;
-		case SEMCTL: {
-			union semun fourth;
-			err = -EINVAL;
-			if (!ptr)
-				goto out;
-			err = -EFAULT;
-			if (get_user(fourth.__pad,
-				     (void __user * __user *)ptr))
-				goto out;
-			err = sys_semctl (first, second, third, fourth);
-			goto out;
-			}
-		default:
-			err = -ENOSYS;
-			goto out;
-		}
-	if (call <= MSGCTL) 
-		switch (call) {
-		case MSGSND:
-			err = sys_msgsnd (first, (struct msgbuf __user *) ptr, 
-					  second, third);
-			goto out;
-		case MSGRCV:
-			switch (version) {
-			case 0: {
-				struct ipc_kludge tmp;
-				err = -EINVAL;
-				if (!ptr)
-					goto out;
-				err = -EFAULT;
-				if (copy_from_user(&tmp, (struct ipc_kludge __user *) ptr, sizeof (tmp)))
-					goto out;
-				err = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
-				goto out;
-				}
-			case 1: default:
-				err = sys_msgrcv (first,
-						  (struct msgbuf __user *) ptr,
-						  second, fifth, third);
-				goto out;
-			}
-		case MSGGET:
-			err = sys_msgget ((key_t) first, second);
-			goto out;
-		case MSGCTL:
-			err = sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
-			goto out;
-		default:
-			err = -ENOSYS;
-			goto out;
-		}
-	if (call <= SHMCTL) 
-		switch (call) {
-		case SHMAT:
-			switch (version) {
-			case 0: default: {
-				ulong raddr;
-				err = do_shmat (first, (char __user *) ptr, second, &raddr);
-				if (err)
-					goto out;
-				err = -EFAULT;
-				if (put_user (raddr, (ulong __user *) third))
-					goto out;
-				err = 0;
-				goto out;
-				}
-			case 1:	/* iBCS2 emulator entry point */
-				err = -EINVAL;
-				goto out;
-			}
-		case SHMDT: 
-			err = sys_shmdt ((char __user *)ptr);
-			goto out;
-		case SHMGET:
-			err = sys_shmget (first, second, third);
-			goto out;
-		case SHMCTL:
-			err = sys_shmctl (first, second, (struct shmid_ds __user *) ptr);
-			goto out;
-		default:
-			err = -ENOSYS;
-			goto out;
-		}
-	else
-		err = -ENOSYS;
-out:
-	return err;
-}
-
 int sparc_mmap_check(unsigned long addr, unsigned long len)
 {
 	if (ARCH_SUN4C &&
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/sys_sparc32.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/sys_sparc32.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/sys_sparc32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/sys_sparc32.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
-#include <linux/slab.h>
 #include <linux/uio.h>
 #include <linux/nfs_fs.h>
 #include <linux/quota.h>
@@ -43,8 +42,8 @@
 #include <linux/security.h>
 #include <linux/compat.h>
 #include <linux/vfs.h>
-#include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/ptrace.h>
+#include <linux/slab.h>
 
 #include <asm/types.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/sys_sparc_64.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/sys_sparc_64.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/sys_sparc_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/sys_sparc_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,6 @@
 
 #include <asm/uaccess.h>
 #include <asm/utrap.h>
-#include <asm/perfctr.h>
 #include <asm/unistd.h>
 
 #include "entry.h"
@@ -427,7 +426,7 @@ out:
  * This is really horribly ugly.
  */
 
-SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
+SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second,
 		unsigned long, third, void __user *, ptr, long, fifth)
 {
 	long err;
@@ -511,17 +510,6 @@ out:
 	return err;
 }
 
-SYSCALL_DEFINE1(sparc64_newuname, struct new_utsname __user *, name)
-{
-	int ret = sys_newuname(name);
-	
-	if (current->personality == PER_LINUX32 && !ret) {
-		ret = (copy_to_user(name->machine, "sparc\0\0", 8)
-		       ? -EFAULT : 0);
-	}
-	return ret;
-}
-
 SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality)
 {
 	int ret;
@@ -766,109 +754,6 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig,
 	return ret;
 }
 
-/* Invoked by rtrap code to update performance counters in
- * user space.
- */
-asmlinkage void update_perfctrs(void)
-{
-	unsigned long pic, tmp;
-
-	read_pic(pic);
-	tmp = (current_thread_info()->kernel_cntd0 += (unsigned int)pic);
-	__put_user(tmp, current_thread_info()->user_cntd0);
-	tmp = (current_thread_info()->kernel_cntd1 += (pic >> 32));
-	__put_user(tmp, current_thread_info()->user_cntd1);
-	reset_pic();
-}
-
-SYSCALL_DEFINE4(perfctr, int, opcode, unsigned long, arg0,
-		unsigned long, arg1, unsigned long, arg2)
-{
-	int err = 0;
-
-	switch(opcode) {
-	case PERFCTR_ON:
-		current_thread_info()->pcr_reg = arg2;
-		current_thread_info()->user_cntd0 = (u64 __user *) arg0;
-		current_thread_info()->user_cntd1 = (u64 __user *) arg1;
-		current_thread_info()->kernel_cntd0 =
-			current_thread_info()->kernel_cntd1 = 0;
-		write_pcr(arg2);
-		reset_pic();
-		set_thread_flag(TIF_PERFCTR);
-		break;
-
-	case PERFCTR_OFF:
-		err = -EINVAL;
-		if (test_thread_flag(TIF_PERFCTR)) {
-			current_thread_info()->user_cntd0 =
-				current_thread_info()->user_cntd1 = NULL;
-			current_thread_info()->pcr_reg = 0;
-			write_pcr(0);
-			clear_thread_flag(TIF_PERFCTR);
-			err = 0;
-		}
-		break;
-
-	case PERFCTR_READ: {
-		unsigned long pic, tmp;
-
-		if (!test_thread_flag(TIF_PERFCTR)) {
-			err = -EINVAL;
-			break;
-		}
-		read_pic(pic);
-		tmp = (current_thread_info()->kernel_cntd0 += (unsigned int)pic);
-		err |= __put_user(tmp, current_thread_info()->user_cntd0);
-		tmp = (current_thread_info()->kernel_cntd1 += (pic >> 32));
-		err |= __put_user(tmp, current_thread_info()->user_cntd1);
-		reset_pic();
-		break;
-	}
-
-	case PERFCTR_CLRPIC:
-		if (!test_thread_flag(TIF_PERFCTR)) {
-			err = -EINVAL;
-			break;
-		}
-		current_thread_info()->kernel_cntd0 =
-			current_thread_info()->kernel_cntd1 = 0;
-		reset_pic();
-		break;
-
-	case PERFCTR_SETPCR: {
-		u64 __user *user_pcr = (u64 __user *)arg0;
-
-		if (!test_thread_flag(TIF_PERFCTR)) {
-			err = -EINVAL;
-			break;
-		}
-		err |= __get_user(current_thread_info()->pcr_reg, user_pcr);
-		write_pcr(current_thread_info()->pcr_reg);
-		current_thread_info()->kernel_cntd0 =
-			current_thread_info()->kernel_cntd1 = 0;
-		reset_pic();
-		break;
-	}
-
-	case PERFCTR_GETPCR: {
-		u64 __user *user_pcr = (u64 __user *)arg0;
-
-		if (!test_thread_flag(TIF_PERFCTR)) {
-			err = -EINVAL;
-			break;
-		}
-		err |= __put_user(current_thread_info()->pcr_reg, user_pcr);
-		break;
-	}
-
-	default:
-		err = -EINVAL;
-		break;
-	};
-	return err;
-}
-
 /*
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/systbls_64.S linux-libre-2.6.34-gnu1/arch/sparc/kernel/systbls_64.S
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/systbls_64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/systbls_64.S	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,7 @@ sys_call_table32:
 /*0*/	.word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write
 /*5*/	.word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link
 /*10*/  .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod
-/*15*/	.word sys_chmod, sys_lchown16, sys_brk, sys32_perfctr, sys32_lseek
+/*15*/	.word sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys32_lseek
 /*20*/	.word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
 /*25*/	.word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause
 /*30*/	.word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice
@@ -55,7 +55,7 @@ sys_call_table32:
 /*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
-	.word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sys_sparc64_newuname
+	.word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sys_newuname
 /*190*/	.word sys32_init_module, sys_sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl
 	.word sys32_epoll_wait, sys32_ioprio_set, sys_getppid, sys32_sigaction, sys_sgetmask
 /*200*/	.word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir
@@ -96,7 +96,7 @@ sys_call_table:
 /*0*/	.word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write
 /*5*/	.word sys_open, sys_close, sys_wait4, sys_creat, sys_link
 /*10*/  .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod
-/*15*/	.word sys_chmod, sys_lchown, sys_brk, sys_perfctr, sys_lseek
+/*15*/	.word sys_chmod, sys_lchown, sys_brk, sys_nis_syscall, sys_lseek
 /*20*/	.word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid
 /*25*/	.word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall
 /*30*/	.word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice
@@ -130,13 +130,13 @@ sys_call_table:
 /*170*/	.word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
 	.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
 /*180*/	.word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall
-	.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_sparc64_newuname
+	.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname
 /*190*/	.word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl
 	.word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask
 /*200*/	.word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
 	.word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64
 /*210*/	.word sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo
-	.word sys_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex
+	.word sys_sparc_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex
 /*220*/	.word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid
 	.word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid
 /*230*/	.word sys_select, sys_nis_syscall, sys_splice, sys_stime, sys_statfs64
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/systbls.h linux-libre-2.6.34-gnu1/arch/sparc/kernel/systbls.h
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/systbls.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/systbls.h	2010-05-16 17:17:36.000000000 -0400
@@ -6,15 +6,12 @@
 #include <asm/utrap.h>
 #include <asm/signal.h>
 
-struct new_utsname;
-
 extern asmlinkage unsigned long sys_getpagesize(void);
 extern asmlinkage long sparc_pipe(struct pt_regs *regs);
-extern asmlinkage long sys_ipc(unsigned int call, int first,
+extern asmlinkage long sys_sparc_ipc(unsigned int call, int first,
 			       unsigned long second,
 			       unsigned long third,
 			       void __user *ptr, long fifth);
-extern asmlinkage long sparc64_newuname(struct new_utsname __user *name);
 extern asmlinkage long sparc64_personality(unsigned long personality);
 extern asmlinkage long sys64_munmap(unsigned long addr, size_t len);
 extern asmlinkage unsigned long sys64_mremap(unsigned long addr,
@@ -36,8 +33,6 @@ extern asmlinkage long sys_rt_sigaction(
 					struct sigaction __user *oact,
 					void __user *restorer,
 					size_t sigsetsize);
-extern asmlinkage long sys_perfctr(int opcode, unsigned long arg0,
-				   unsigned long arg1, unsigned long arg2);
 
 extern asmlinkage void sparc64_set_context(struct pt_regs *regs);
 extern asmlinkage void sparc64_get_context(struct pt_regs *regs);
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/time_64.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/time_64.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/time_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/time_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/clocksource.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/ftrace.h>
 
 #include <asm/oplib.h>
 #include <asm/timer.h>
@@ -717,7 +718,7 @@ static struct clock_event_device sparc64
 };
 static DEFINE_PER_CPU(struct clock_event_device, sparc64_events);
 
-void timer_interrupt(int irq, struct pt_regs *regs)
+void __irq_entry timer_interrupt(int irq, struct pt_regs *regs)
 {
 	struct pt_regs *old_regs = set_irq_regs(regs);
 	unsigned long tick_mask = tick_ops->softint_mask;
@@ -728,6 +729,7 @@ void timer_interrupt(int irq, struct pt_
 
 	irq_enter();
 
+	local_cpu_data().irq0_irqs++;
 	kstat_incr_irqs_this_cpu(0, irq_to_desc(0));
 
 	if (unlikely(!evt->event_handler)) {
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/traps_64.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/traps_64.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/traps_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/traps_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/kdebug.h>
+#include <linux/gfp.h>
 
 #include <asm/smp.h>
 #include <asm/delay.h>
@@ -2202,27 +2203,6 @@ void dump_stack(void)
 
 EXPORT_SYMBOL(dump_stack);
 
-static inline int is_kernel_stack(struct task_struct *task,
-				  struct reg_window *rw)
-{
-	unsigned long rw_addr = (unsigned long) rw;
-	unsigned long thread_base, thread_end;
-
-	if (rw_addr < PAGE_OFFSET) {
-		if (task != &init_task)
-			return 0;
-	}
-
-	thread_base = (unsigned long) task_stack_page(task);
-	thread_end = thread_base + sizeof(union thread_union);
-	if (rw_addr >= thread_base &&
-	    rw_addr < thread_end &&
-	    !(rw_addr & 0x7UL))
-		return 1;
-
-	return 0;
-}
-
 static inline struct reg_window *kernel_stack_up(struct reg_window *rw)
 {
 	unsigned long fp = rw->ins[6];
@@ -2251,6 +2231,7 @@ void die_if_kernel(char *str, struct pt_
 	show_regs(regs);
 	add_taint(TAINT_DIE);
 	if (regs->tstate & TSTATE_PRIV) {
+		struct thread_info *tp = current_thread_info();
 		struct reg_window *rw = (struct reg_window *)
 			(regs->u_regs[UREG_FP] + STACK_BIAS);
 
@@ -2258,8 +2239,8 @@ void die_if_kernel(char *str, struct pt_
 		 * find some badly aligned kernel stack.
 		 */
 		while (rw &&
-		       count++ < 30&&
-		       is_kernel_stack(current, rw)) {
+		       count++ < 30 &&
+		       kstack_valid(tp, (unsigned long) rw)) {
 			printk("Caller[%016lx]: %pS\n", rw->ins[7],
 			       (void *) rw->ins[7]);
 
@@ -2548,15 +2529,6 @@ void __init trap_init(void)
 					       rwbuf_stkptrs) ||
 		     TI_GSR != offsetof(struct thread_info, gsr) ||
 		     TI_XFSR != offsetof(struct thread_info, xfsr) ||
-		     TI_USER_CNTD0 != offsetof(struct thread_info,
-					       user_cntd0) ||
-		     TI_USER_CNTD1 != offsetof(struct thread_info,
-					       user_cntd1) ||
-		     TI_KERN_CNTD0 != offsetof(struct thread_info,
-					       kernel_cntd0) ||
-		     TI_KERN_CNTD1 != offsetof(struct thread_info,
-					       kernel_cntd1) ||
-		     TI_PCR != offsetof(struct thread_info, pcr_reg) ||
 		     TI_PRE_COUNT != offsetof(struct thread_info,
 					      preempt_count) ||
 		     TI_NEW_CHILD != offsetof(struct thread_info, new_child) ||
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/unaligned_64.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/unaligned_64.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/unaligned_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/unaligned_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/smp.h>
 #include <linux/bitops.h>
 #include <linux/perf_event.h>
+#include <linux/ratelimit.h>
 #include <asm/fpumacro.h>
 
 enum direction {
@@ -49,7 +50,7 @@ static inline enum direction decode_dire
 }
 
 /* 16 = double-word, 8 = extra-word, 4 = word, 2 = half-word */
-static inline int decode_access_size(unsigned int insn)
+static inline int decode_access_size(struct pt_regs *regs, unsigned int insn)
 {
 	unsigned int tmp;
 
@@ -65,7 +66,7 @@ static inline int decode_access_size(uns
 		return 2;
 	else {
 		printk("Impossible unaligned trap. insn=%08x\n", insn);
-		die_if_kernel("Byte sized unaligned access?!?!", current_thread_info()->kregs);
+		die_if_kernel("Byte sized unaligned access?!?!", regs);
 
 		/* GCC should never warn that control reaches the end
 		 * of this function without returning a value because
@@ -274,13 +275,9 @@ static void kernel_mna_trap_fault(int fi
 
 static void log_unaligned(struct pt_regs *regs)
 {
-	static unsigned long count, last_time;
+	static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5);
 
-	if (time_after(jiffies, last_time + 5 * HZ))
-		count = 0;
-	if (count < 5) {
-		last_time = jiffies;
-		count++;
+	if (__ratelimit(&ratelimit)) {
 		printk("Kernel unaligned access at TPC[%lx] %pS\n",
 		       regs->tpc, (void *) regs->tpc);
 	}
@@ -289,7 +286,7 @@ static void log_unaligned(struct pt_regs
 asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
 {
 	enum direction dir = decode_direction(insn);
-	int size = decode_access_size(insn);
+	int size = decode_access_size(regs, insn);
 	int orig_asi, asi;
 
 	current_thread_info()->kern_una_regs = regs;
@@ -636,7 +633,6 @@ daex:
 		return;
 	}
 	advance(regs);
-	return;
 }
 
 void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr)
@@ -685,5 +681,4 @@ daex:
 		return;
 	}
 	advance(regs);
-	return;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/us2e_cpufreq.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/us2e_cpufreq.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/us2e_cpufreq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/us2e_cpufreq.c	2010-05-16 17:17:36.000000000 -0400
@@ -238,12 +238,12 @@ static unsigned int us2e_freq_get(unsign
 		return 0;
 
 	cpus_allowed = current->cpus_allowed;
-	set_cpus_allowed(current, cpumask_of_cpu(cpu));
+	set_cpus_allowed_ptr(current, cpumask_of(cpu));
 
 	clock_tick = sparc64_get_clock_tick(cpu) / 1000;
 	estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
 
-	set_cpus_allowed(current, cpus_allowed);
+	set_cpus_allowed_ptr(current, &cpus_allowed);
 
 	return clock_tick / estar_to_divisor(estar);
 }
@@ -259,7 +259,7 @@ static void us2e_set_cpu_divider_index(u
 		return;
 
 	cpus_allowed = current->cpus_allowed;
-	set_cpus_allowed(current, cpumask_of_cpu(cpu));
+	set_cpus_allowed_ptr(current, cpumask_of(cpu));
 
 	new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000;
 	new_bits = index_to_estar_mode(index);
@@ -281,7 +281,7 @@ static void us2e_set_cpu_divider_index(u
 
 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
-	set_cpus_allowed(current, cpus_allowed);
+	set_cpus_allowed_ptr(current, &cpus_allowed);
 }
 
 static int us2e_freq_target(struct cpufreq_policy *policy,
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/us3_cpufreq.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/us3_cpufreq.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/us3_cpufreq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/us3_cpufreq.c	2010-05-16 17:17:36.000000000 -0400
@@ -86,12 +86,12 @@ static unsigned int us3_freq_get(unsigne
 		return 0;
 
 	cpus_allowed = current->cpus_allowed;
-	set_cpus_allowed(current, cpumask_of_cpu(cpu));
+	set_cpus_allowed_ptr(current, cpumask_of(cpu));
 
 	reg = read_safari_cfg();
 	ret = get_current_freq(cpu, reg);
 
-	set_cpus_allowed(current, cpus_allowed);
+	set_cpus_allowed_ptr(current, &cpus_allowed);
 
 	return ret;
 }
@@ -106,7 +106,7 @@ static void us3_set_cpu_divider_index(un
 		return;
 
 	cpus_allowed = current->cpus_allowed;
-	set_cpus_allowed(current, cpumask_of_cpu(cpu));
+	set_cpus_allowed_ptr(current, cpumask_of(cpu));
 
 	new_freq = sparc64_get_clock_tick(cpu) / 1000;
 	switch (index) {
@@ -140,7 +140,7 @@ static void us3_set_cpu_divider_index(un
 
 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
-	set_cpus_allowed(current, cpus_allowed);
+	set_cpus_allowed_ptr(current, &cpus_allowed);
 }
 
 static int us3_freq_target(struct cpufreq_policy *policy,
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/vio.c linux-libre-2.6.34-gnu1/arch/sparc/kernel/vio.c
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/vio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/vio.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/irq.h>
 #include <linux/init.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/kernel/vmlinux.lds.S linux-libre-2.6.34-gnu1/arch/sparc/kernel/vmlinux.lds.S
--- linux-libre-2.6.33-gnu1/arch/sparc/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/kernel/vmlinux.lds.S	2010-05-16 17:17:36.000000000 -0400
@@ -46,11 +46,16 @@ SECTIONS
 		SCHED_TEXT
 		LOCK_TEXT
 		KPROBES_TEXT
+		IRQENTRY_TEXT
 		*(.gnu.warning)
 	} = 0
 	_etext = .;
 
 	RO_DATA(PAGE_SIZE)
+
+	/* Start of data section */
+	_sdata = .;
+
 	.data1 : {
 		*(.data1)
 	}
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/lib/mcount.S linux-libre-2.6.34-gnu1/arch/sparc/lib/mcount.S
--- linux-libre-2.6.33-gnu1/arch/sparc/lib/mcount.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/lib/mcount.S	2010-05-16 17:17:36.000000000 -0400
@@ -7,26 +7,11 @@
 
 #include <linux/linkage.h>
 
-#include <asm/ptrace.h>
-#include <asm/thread_info.h>
-
 /*
  * This is the main variant and is called by C code.  GCC's -pg option
  * automatically instruments every C function with a call to this.
  */
 
-#ifdef CONFIG_STACK_DEBUG
-
-#define OVSTACKSIZE	4096		/* lets hope this is enough */
-
-	.data
-	.align		8
-panicstring:
-	.asciz		"Stack overflow\n"
-	.align		8
-ovstack:
-	.skip		OVSTACKSIZE
-#endif
 	.text
 	.align		32
 	.globl		_mcount
@@ -35,84 +20,48 @@ ovstack:
 	.type		mcount,#function
 _mcount:
 mcount:
-#ifdef CONFIG_STACK_DEBUG
-	/*
-	 * Check whether %sp is dangerously low.
-	 */
-	ldub		[%g6 + TI_FPDEPTH], %g1
-	srl		%g1, 1, %g3
-	add		%g3, 1, %g3
-	sllx		%g3, 8, %g3			! each fpregs frame is 256b
-	add		%g3, 192, %g3
-	add		%g6, %g3, %g3			! where does task_struct+frame end?
-	sub		%g3, STACK_BIAS, %g3
-	cmp		%sp, %g3
-	bg,pt		%xcc, 1f
-	 nop
-	lduh		[%g6 + TI_CPU], %g1
-	sethi		%hi(hardirq_stack), %g3
-	or		%g3, %lo(hardirq_stack), %g3
-	sllx		%g1, 3, %g1
-	ldx		[%g3 + %g1], %g7
-	sub		%g7, STACK_BIAS, %g7
-	cmp		%sp, %g7
-	bleu,pt		%xcc, 2f
-	 sethi		%hi(THREAD_SIZE), %g3
-	add		%g7, %g3, %g7
-	cmp		%sp, %g7
-	blu,pn		%xcc, 1f
-2:	 sethi		%hi(softirq_stack), %g3
-	or		%g3, %lo(softirq_stack), %g3
-	ldx		[%g3 + %g1], %g7
-	sub		%g7, STACK_BIAS, %g7
-	cmp		%sp, %g7
-	bleu,pt		%xcc, 3f
-	 sethi		%hi(THREAD_SIZE), %g3
-	add		%g7, %g3, %g7
-	cmp		%sp, %g7
-	blu,pn		%xcc, 1f
-	 nop
-	/* If we are already on ovstack, don't hop onto it
-	 * again, we are already trying to output the stack overflow
-	 * message.
-	 */
-3:	sethi		%hi(ovstack), %g7		! cant move to panic stack fast enough
-	 or		%g7, %lo(ovstack), %g7
-	add		%g7, OVSTACKSIZE, %g3
-	sub		%g3, STACK_BIAS + 192, %g3
-	sub		%g7, STACK_BIAS, %g7
-	cmp		%sp, %g7
-	blu,pn		%xcc, 2f
-	 cmp		%sp, %g3
-	bleu,pn		%xcc, 1f
-	 nop
-2:	mov		%g3, %sp
-	sethi		%hi(panicstring), %g3
-	call		prom_printf
-	 or		%g3, %lo(panicstring), %o0
-	call		prom_halt
-	 nop
-1:
-#endif
 #ifdef CONFIG_FUNCTION_TRACER
 #ifdef CONFIG_DYNAMIC_FTRACE
-	mov		%o7, %o0
-	.globl		mcount_call
-mcount_call:
-	call		ftrace_stub
-	 mov		%o0, %o7
+	/* Do nothing, the retl/nop below is all we need.  */
 #else
-	sethi		%hi(ftrace_trace_function), %g1
+	sethi		%hi(function_trace_stop), %g1
+	lduw		[%g1 + %lo(function_trace_stop)], %g2
+	brnz,pn		%g2, 2f
+	 sethi		%hi(ftrace_trace_function), %g1
 	sethi		%hi(ftrace_stub), %g2
 	ldx		[%g1 + %lo(ftrace_trace_function)], %g1
 	or		%g2, %lo(ftrace_stub), %g2
 	cmp		%g1, %g2
 	be,pn		%icc, 1f
-	 mov		%i7, %o1
-	jmpl		%g1, %g0
-	 mov		%o7, %o0
+	 mov		%i7, %g3
+	save		%sp, -176, %sp
+	mov		%g3, %o1
+	jmpl		%g1, %o7
+	 mov		%i7, %o0
+	ret
+	 restore
 	/* not reached */
 1:
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	sethi		%hi(ftrace_graph_return), %g1
+	ldx		[%g1 + %lo(ftrace_graph_return)], %g3
+	cmp		%g2, %g3
+	bne,pn		%xcc, 5f
+	 sethi		%hi(ftrace_graph_entry_stub), %g2
+	sethi		%hi(ftrace_graph_entry), %g1
+	or		%g2, %lo(ftrace_graph_entry_stub), %g2
+	ldx		[%g1 + %lo(ftrace_graph_entry)], %g1
+	cmp		%g1, %g2
+	be,pt		%xcc, 2f
+	 nop
+5:	mov		%i7, %g2
+	mov		%fp, %g3
+	save		%sp, -176, %sp
+	mov		%g2, %l0
+	ba,pt		%xcc, ftrace_graph_caller
+	 mov		%g3, %l1
+#endif
+2:
 #endif
 #endif
 	retl
@@ -131,14 +80,50 @@ ftrace_stub:
 	.globl		ftrace_caller
 	.type		ftrace_caller,#function
 ftrace_caller:
-	mov		%i7, %o1
-	mov		%o7, %o0
+	sethi		%hi(function_trace_stop), %g1
+	mov		%i7, %g2
+	lduw		[%g1 + %lo(function_trace_stop)], %g1
+	brnz,pn		%g1, ftrace_stub
+	 mov		%fp, %g3
+	save		%sp, -176, %sp
+	mov		%g2, %o1
+	mov		%g2, %l0
+	mov		%g3, %l1
 	.globl		ftrace_call
 ftrace_call:
 	call		ftrace_stub
-	 mov		%o0, %o7
-	retl
+	 mov		%i7, %o0
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	.globl		ftrace_graph_call
+ftrace_graph_call:
+	call		ftrace_stub
 	 nop
+#endif
+	ret
+	 restore
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	.size		ftrace_graph_call,.-ftrace_graph_call
+#endif
+	.size		ftrace_call,.-ftrace_call
 	.size		ftrace_caller,.-ftrace_caller
 #endif
 #endif
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ENTRY(ftrace_graph_caller)
+	mov		%l0, %o0
+	mov		%i7, %o1
+	call		prepare_ftrace_return
+	 mov		%l1, %o2
+	ret
+	 restore	%o0, -8, %i7
+END(ftrace_graph_caller)
+
+ENTRY(return_to_handler)
+	save		%sp, -176, %sp
+	call		ftrace_return_to_handler
+	 mov		%fp, %o0
+	jmpl		%o0 + 8, %g0
+	 restore
+END(return_to_handler)
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/mm/fault_32.c linux-libre-2.6.34-gnu1/arch/sparc/mm/fault_32.c
--- linux-libre-2.6.33-gnu1/arch/sparc/mm/fault_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/mm/fault_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,8 @@
 
 extern int prom_node_root;
 
+int show_unhandled_signals = 1;
+
 /* At boot time we determine these two values necessary for setting
  * up the segment maps and page table entries (pte's).
  */
@@ -149,6 +151,45 @@ asmlinkage int lookup_fault(unsigned lon
 	return 0;
 }
 
+static inline void
+show_signal_msg(struct pt_regs *regs, int sig, int code,
+		unsigned long address, struct task_struct *tsk)
+{
+	if (!unhandled_signal(tsk, sig))
+		return;
+
+	if (!printk_ratelimit())
+		return;
+
+	printk("%s%s[%d]: segfault at %lx ip %p (rpc %p) sp %p error %x",
+	       task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
+	       tsk->comm, task_pid_nr(tsk), address,
+	       (void *)regs->pc, (void *)regs->u_regs[UREG_I7],
+	       (void *)regs->u_regs[UREG_FP], code);
+
+	print_vma_addr(KERN_CONT " in ", regs->pc);
+
+	printk(KERN_CONT "\n");
+}
+
+static void __do_fault_siginfo(int code, int sig, struct pt_regs *regs,
+			       unsigned long addr)
+{
+	siginfo_t info;
+
+	info.si_signo = sig;
+	info.si_code = code;
+	info.si_errno = 0;
+	info.si_addr = (void __user *) addr;
+	info.si_trapno = 0;
+
+	if (unlikely(show_unhandled_signals))
+		show_signal_msg(regs, sig, info.si_code,
+				addr, current);
+
+	force_sig_info (sig, &info, current);
+}
+
 extern unsigned long safe_compute_effective_address(struct pt_regs *,
 						    unsigned int);
 
@@ -168,6 +209,14 @@ static unsigned long compute_si_addr(str
 	return safe_compute_effective_address(regs, insn);
 }
 
+static noinline void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
+				      int text_fault)
+{
+	unsigned long addr = compute_si_addr(regs, text_fault);
+
+	__do_fault_siginfo(code, sig, regs, addr);
+}
+
 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
 			       unsigned long address)
 {
@@ -176,9 +225,8 @@ asmlinkage void do_sparc_fault(struct pt
 	struct mm_struct *mm = tsk->mm;
 	unsigned int fixup;
 	unsigned long g2;
-	siginfo_t info;
 	int from_user = !(regs->psr & PSR_PS);
-	int fault;
+	int fault, code;
 
 	if(text_fault)
 		address = regs->pc;
@@ -195,7 +243,7 @@ asmlinkage void do_sparc_fault(struct pt
 	if (!ARCH_SUN4C && address >= TASK_SIZE)
 		goto vmalloc_fault;
 
-	info.si_code = SEGV_MAPERR;
+	code = SEGV_MAPERR;
 
 	/*
 	 * If we're in an interrupt or have no user
@@ -229,7 +277,7 @@ asmlinkage void do_sparc_fault(struct pt
 	 * we can handle it..
 	 */
 good_area:
-	info.si_code = SEGV_ACCERR;
+	code = SEGV_ACCERR;
 	if(write) {
 		if(!(vma->vm_flags & VM_WRITE))
 			goto bad_area;
@@ -273,18 +321,8 @@ bad_area:
 
 bad_area_nosemaphore:
 	/* User mode accesses just cause a SIGSEGV */
-	if(from_user) {
-#if 0
-		printk("Fault whee %s [%d]: segfaults at %08lx pc=%08lx\n",
-		       tsk->comm, tsk->pid, address, regs->pc);
-#endif
-		info.si_signo = SIGSEGV;
-		info.si_errno = 0;
-		/* info.si_code set above to make clear whether
-		   this was a SEGV_MAPERR or SEGV_ACCERR fault.  */
-		info.si_addr = (void __user *)compute_si_addr(regs, text_fault);
-		info.si_trapno = 0;
-		force_sig_info (SIGSEGV, &info, tsk);
+	if (from_user) {
+		do_fault_siginfo(code, SIGSEGV, regs, text_fault);
 		return;
 	}
 
@@ -335,12 +373,7 @@ out_of_memory:
 
 do_sigbus:
 	up_read(&mm->mmap_sem);
-	info.si_signo = SIGBUS;
-	info.si_errno = 0;
-	info.si_code = BUS_ADRERR;
-	info.si_addr = (void __user *) compute_si_addr(regs, text_fault);
-	info.si_trapno = 0;
-	force_sig_info (SIGBUS, &info, tsk);
+	do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, text_fault);
 	if (!from_user)
 		goto no_context;
 
@@ -378,7 +411,7 @@ asmlinkage void do_sun4c_fault(struct pt
 			       unsigned long address)
 {
 	extern void sun4c_update_mmu_cache(struct vm_area_struct *,
-					   unsigned long,pte_t);
+					   unsigned long,pte_t *);
 	extern pte_t *sun4c_pte_offset_kernel(pmd_t *,unsigned long);
 	struct task_struct *tsk = current;
 	struct mm_struct *mm = tsk->mm;
@@ -455,7 +488,7 @@ asmlinkage void do_sun4c_fault(struct pt
 		 *       on the CPU and doing a shrink_mmap() on this vma.
 		 */
 		sun4c_update_mmu_cache (find_vma(current->mm, address), address,
-					*ptep);
+					ptep);
 	else
 		do_sparc_fault(regs, text_fault, write, address);
 }
@@ -466,14 +499,10 @@ static void force_user_fault(unsigned lo
 	struct vm_area_struct *vma;
 	struct task_struct *tsk = current;
 	struct mm_struct *mm = tsk->mm;
-	siginfo_t info;
+	int code;
 
-	info.si_code = SEGV_MAPERR;
+	code = SEGV_MAPERR;
 
-#if 0
-	printk("wf<pid=%d,wr=%d,addr=%08lx>\n",
-	       tsk->pid, write, address);
-#endif
 	down_read(&mm->mmap_sem);
 	vma = find_vma(mm, address);
 	if(!vma)
@@ -485,7 +514,7 @@ static void force_user_fault(unsigned lo
 	if(expand_stack(vma, address))
 		goto bad_area;
 good_area:
-	info.si_code = SEGV_ACCERR;
+	code = SEGV_ACCERR;
 	if(write) {
 		if(!(vma->vm_flags & VM_WRITE))
 			goto bad_area;
@@ -502,27 +531,12 @@ good_area:
 	return;
 bad_area:
 	up_read(&mm->mmap_sem);
-#if 0
-	printk("Window whee %s [%d]: segfaults at %08lx\n",
-	       tsk->comm, tsk->pid, address);
-#endif
-	info.si_signo = SIGSEGV;
-	info.si_errno = 0;
-	/* info.si_code set above to make clear whether
-	   this was a SEGV_MAPERR or SEGV_ACCERR fault.  */
-	info.si_addr = (void __user *) address;
-	info.si_trapno = 0;
-	force_sig_info (SIGSEGV, &info, tsk);
+	__do_fault_siginfo(code, SIGSEGV, tsk->thread.kregs, address);
 	return;
 
 do_sigbus:
 	up_read(&mm->mmap_sem);
-	info.si_signo = SIGBUS;
-	info.si_errno = 0;
-	info.si_code = BUS_ADRERR;
-	info.si_addr = (void __user *) address;
-	info.si_trapno = 0;
-	force_sig_info (SIGBUS, &info, tsk);
+	__do_fault_siginfo(BUS_ADRERR, SIGBUS, tsk->thread.kregs, address);
 }
 
 void window_overflow_fault(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/mm/fault_64.c linux-libre-2.6.34-gnu1/arch/sparc/mm/fault_64.c
--- linux-libre-2.6.33-gnu1/arch/sparc/mm/fault_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/mm/fault_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,8 @@
 #include <asm/sections.h>
 #include <asm/mmu_context.h>
 
+int show_unhandled_signals = 1;
+
 static inline __kprobes int notify_page_fault(struct pt_regs *regs)
 {
 	int ret = 0;
@@ -128,22 +130,48 @@ outret:
 	return insn;
 }
 
+static inline void
+show_signal_msg(struct pt_regs *regs, int sig, int code,
+		unsigned long address, struct task_struct *tsk)
+{
+	if (!unhandled_signal(tsk, sig))
+		return;
+
+	if (!printk_ratelimit())
+		return;
+
+	printk("%s%s[%d]: segfault at %lx ip %p (rpc %p) sp %p error %x",
+	       task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
+	       tsk->comm, task_pid_nr(tsk), address,
+	       (void *)regs->tpc, (void *)regs->u_regs[UREG_I7],
+	       (void *)regs->u_regs[UREG_FP], code);
+
+	print_vma_addr(KERN_CONT " in ", regs->tpc);
+
+	printk(KERN_CONT "\n");
+}
+
 extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int);
 
 static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
 			     unsigned int insn, int fault_code)
 {
+	unsigned long addr;
 	siginfo_t info;
 
 	info.si_code = code;
 	info.si_signo = sig;
 	info.si_errno = 0;
 	if (fault_code & FAULT_CODE_ITLB)
-		info.si_addr = (void __user *) regs->tpc;
+		addr = regs->tpc;
 	else
-		info.si_addr = (void __user *)
-			compute_effective_address(regs, insn, 0);
+		addr = compute_effective_address(regs, insn, 0);
+	info.si_addr = (void __user *) addr;
 	info.si_trapno = 0;
+
+	if (unlikely(show_unhandled_signals))
+		show_signal_msg(regs, sig, code, addr, current);
+
 	force_sig_info(sig, &info, current);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/mm/hugetlbpage.c linux-libre-2.6.34-gnu1/arch/sparc/mm/hugetlbpage.c
--- linux-libre-2.6.33-gnu1/arch/sparc/mm/hugetlbpage.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/mm/hugetlbpage.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/pagemap.h>
-#include <linux/slab.h>
 #include <linux/sysctl.h>
 
 #include <asm/mman.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/mm/init_32.c linux-libre-2.6.34-gnu1/arch/sparc/mm/init_32.c
--- linux-libre-2.6.33-gnu1/arch/sparc/mm/init_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/mm/init_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/bootmem.h>
 #include <linux/pagemap.h>
 #include <linux/poison.h>
+#include <linux/gfp.h>
 
 #include <asm/sections.h>
 #include <asm/system.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/mm/init_64.c linux-libre-2.6.34-gnu1/arch/sparc/mm/init_64.c
--- linux-libre-2.6.33-gnu1/arch/sparc/mm/init_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/mm/init_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/bootmem.h>
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
-#include <linux/slab.h>
 #include <linux/initrd.h>
 #include <linux/swap.h>
 #include <linux/pagemap.h>
@@ -26,6 +25,7 @@
 #include <linux/percpu.h>
 #include <linux/lmb.h>
 #include <linux/mmzone.h>
+#include <linux/gfp.h>
 
 #include <asm/head.h>
 #include <asm/system.h>
@@ -289,12 +289,13 @@ static void flush_dcache(unsigned long p
 	}
 }
 
-void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
 	struct mm_struct *mm;
 	struct tsb *tsb;
 	unsigned long tag, flags;
 	unsigned long tsb_index, tsb_hash_shift;
+	pte_t pte = *ptep;
 
 	if (tlb_type != hypervisor) {
 		unsigned long pfn = pte_pfn(pte);
@@ -2116,7 +2117,7 @@ int __meminit vmemmap_populate(struct pa
 			       "node=%d entry=%lu/%lu\n", start, block, nr,
 			       node,
 			       addr >> VMEMMAP_CHUNK_SHIFT,
-			       VMEMMAP_SIZE >> VMEMMAP_CHUNK_SHIFT);
+			       VMEMMAP_SIZE);
 		}
 	}
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/mm/nosun4c.c linux-libre-2.6.34-gnu1/arch/sparc/mm/nosun4c.c
--- linux-libre-2.6.33-gnu1/arch/sparc/mm/nosun4c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/mm/nosun4c.c	2010-05-16 17:17:36.000000000 -0400
@@ -62,7 +62,7 @@ pte_t *sun4c_pte_offset_kernel(pmd_t *di
 	return NULL;
 }
 
-void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/mm/srmmu.c linux-libre-2.6.34-gnu1/arch/sparc/mm/srmmu.c
--- linux-libre-2.6.33-gnu1/arch/sparc/mm/srmmu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/mm/srmmu.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
 
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
@@ -20,6 +19,7 @@
 #include <linux/seq_file.h>
 #include <linux/kdebug.h>
 #include <linux/log2.h>
+#include <linux/gfp.h>
 
 #include <asm/bitext.h>
 #include <asm/page.h>
@@ -694,7 +694,7 @@ extern void tsunami_setup_blockops(void)
  * The following code is a deadwood that may be necessary when
  * we start to make precise page flushes again. --zaitcev
  */
-static void swift_update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t pte)
+static void swift_update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t *ptep)
 {
 #if 0
 	static unsigned long last;
@@ -703,10 +703,10 @@ static void swift_update_mmu_cache(struc
 
 	if (address == last) {
 		val = srmmu_hwprobe(address);
-		if (val != 0 && pte_val(pte) != val) {
+		if (val != 0 && pte_val(*ptep) != val) {
 			printk("swift_update_mmu_cache: "
 			    "addr %lx put %08x probed %08x from %p\n",
-			    address, pte_val(pte), val,
+			    address, pte_val(*ptep), val,
 			    __builtin_return_address(0));
 			srmmu_flush_whole_tlb();
 		}
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/mm/sun4c.c linux-libre-2.6.34-gnu1/arch/sparc/mm/sun4c.c
--- linux-libre-2.6.33-gnu1/arch/sparc/mm/sun4c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/mm/sun4c.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
 #include <linux/fs.h>
@@ -1887,7 +1888,7 @@ static void sun4c_check_pgt_cache(int lo
 /* An experiment, turn off by default for now... -DaveM */
 #define SUN4C_PRELOAD_PSEG
 
-void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
 	unsigned long flags;
 	int pseg;
@@ -1929,7 +1930,7 @@ void sun4c_update_mmu_cache(struct vm_ar
 			start += PAGE_SIZE;
 		}
 #ifndef SUN4C_PRELOAD_PSEG
-		sun4c_put_pte(address, pte_val(pte));
+		sun4c_put_pte(address, pte_val(*ptep));
 #endif
 		local_irq_restore(flags);
 		return;
@@ -1940,7 +1941,7 @@ void sun4c_update_mmu_cache(struct vm_ar
 		add_lru(entry);
 	}
 
-	sun4c_put_pte(address, pte_val(pte));
+	sun4c_put_pte(address, pte_val(*ptep));
 	local_irq_restore(flags);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/mm/tsb.c linux-libre-2.6.34-gnu1/arch/sparc/mm/tsb.c
--- linux-libre-2.6.33-gnu1/arch/sparc/mm/tsb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/mm/tsb.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
 
 #include <linux/kernel.h>
 #include <linux/preempt.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <asm/page.h>
 #include <asm/tlbflush.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/prom/console_32.c linux-libre-2.6.34-gnu1/arch/sparc/prom/console_32.c
--- linux-libre-2.6.33-gnu1/arch/sparc/prom/console_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/prom/console_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -94,5 +94,4 @@ void
 prom_putchar(char c)
 {
 	while(prom_nbputchar(c) == -1) ;
-	return;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/prom/console_64.c linux-libre-2.6.34-gnu1/arch/sparc/prom/console_64.c
--- linux-libre-2.6.33-gnu1/arch/sparc/prom/console_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/prom/console_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -62,7 +62,6 @@ void
 prom_putchar(char c)
 {
 	prom_nbputchar(c);
-	return;
 }
 
 void
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/prom/devmap.c linux-libre-2.6.34-gnu1/arch/sparc/prom/devmap.c
--- linux-libre-2.6.33-gnu1/arch/sparc/prom/devmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/prom/devmap.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,5 +50,4 @@ prom_unmapio(char *vaddr, unsigned int n
 	(*(romvec->pv_v2devops.v2_dumb_munmap))(vaddr, num_bytes);
 	restore_current();
 	spin_unlock_irqrestore(&prom_lock, flags);
-	return;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/prom/devops_32.c linux-libre-2.6.34-gnu1/arch/sparc/prom/devops_32.c
--- linux-libre-2.6.33-gnu1/arch/sparc/prom/devops_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/prom/devops_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -84,6 +84,4 @@ prom_seek(int dhandle, unsigned int seek
 	};
 	restore_current();
 	spin_unlock_irqrestore(&prom_lock, flags);
-
-	return;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/prom/init_32.c linux-libre-2.6.34-gnu1/arch/sparc/prom/init_32.c
--- linux-libre-2.6.33-gnu1/arch/sparc/prom/init_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/prom/init_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -75,5 +75,4 @@ void __init prom_init(struct linux_romve
 	       romvec->pv_romvers, prom_rev);
 
 	/* Initialization successful. */
-	return;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/prom/p1275.c linux-libre-2.6.34-gnu1/arch/sparc/prom/p1275.c
--- linux-libre-2.6.33-gnu1/arch/sparc/prom/p1275.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/prom/p1275.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,10 +32,9 @@ extern void prom_cif_interface(void);
 extern void prom_cif_callback(void);
 
 /*
- * This provides SMP safety on the p1275buf. prom_callback() drops this lock
- * to allow recursuve acquisition.
+ * This provides SMP safety on the p1275buf.
  */
-DEFINE_SPINLOCK(prom_entry_lock);
+DEFINE_RAW_SPINLOCK(prom_entry_lock);
 
 long p1275_cmd(const char *service, long fmt, ...)
 {
@@ -47,7 +46,9 @@ long p1275_cmd(const char *service, long
 	
 	p = p1275buf.prom_buffer;
 
-	spin_lock_irqsave(&prom_entry_lock, flags);
+	raw_local_save_flags(flags);
+	raw_local_irq_restore(PIL_NMI);
+	raw_spin_lock(&prom_entry_lock);
 
 	p1275buf.prom_args[0] = (unsigned long)p;		/* service */
 	strcpy (p, service);
@@ -139,7 +140,8 @@ long p1275_cmd(const char *service, long
 	va_end(list);
 	x = p1275buf.prom_args [nargs + 3];
 
-	spin_unlock_irqrestore(&prom_entry_lock, flags);
+	raw_spin_unlock(&prom_entry_lock);
+	raw_local_irq_restore(flags);
 
 	return x;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/prom/palloc.c linux-libre-2.6.34-gnu1/arch/sparc/prom/palloc.c
--- linux-libre-2.6.33-gnu1/arch/sparc/prom/palloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/prom/palloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,5 +40,4 @@ prom_free(char *vaddr, unsigned int num_
 {
 	if((prom_vers == PROM_V0) || (num_bytes == 0x0)) return;
 	(*(romvec->pv_v2devops.v2_dumb_mem_free))(vaddr, num_bytes);
-	return;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/prom/ranges.c linux-libre-2.6.34-gnu1/arch/sparc/prom/ranges.c
--- linux-libre-2.6.33-gnu1/arch/sparc/prom/ranges.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/prom/ranges.c	2010-05-16 17:17:36.000000000 -0400
@@ -87,8 +87,6 @@ void __init prom_ranges_init(void)
 
 	if(num_obio_ranges)
 		prom_printf("PROMLIB: obio_ranges %d\n", num_obio_ranges);
-
-	return;
 }
 
 void
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/prom/segment.c linux-libre-2.6.34-gnu1/arch/sparc/prom/segment.c
--- linux-libre-2.6.33-gnu1/arch/sparc/prom/segment.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/prom/segment.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,5 +25,4 @@ prom_putsegment(int ctx, unsigned long v
 	(*(romvec->pv_setctxt))(ctx, (char *) vaddr, segment);
 	restore_current();
 	spin_unlock_irqrestore(&prom_lock, flags);
-	return;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/prom/tree_32.c linux-libre-2.6.34-gnu1/arch/sparc/prom/tree_32.c
--- linux-libre-2.6.33-gnu1/arch/sparc/prom/tree_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/prom/tree_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -173,7 +173,6 @@ void prom_getstring(int node, char *prop
 	len = prom_getproperty(node, prop, user_buf, ubuf_size);
 	if(len != -1) return;
 	user_buf[0] = 0;
-	return;
 }
 EXPORT_SYMBOL(prom_getstring);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/sparc/prom/tree_64.c linux-libre-2.6.34-gnu1/arch/sparc/prom/tree_64.c
--- linux-libre-2.6.33-gnu1/arch/sparc/prom/tree_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/sparc/prom/tree_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -154,7 +154,6 @@ void prom_getstring(int node, const char
 	len = prom_getproperty(node, prop, user_buf, ubuf_size);
 	if(len != -1) return;
 	user_buf[0] = 0;
-	return;
 }
 EXPORT_SYMBOL(prom_getstring);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/um/drivers/line.c linux-libre-2.6.34-gnu1/arch/um/drivers/line.c
--- linux-libre-2.6.33-gnu1/arch/um/drivers/line.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/drivers/line.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
 #include "linux/irqreturn.h"
 #include "linux/kd.h"
 #include "linux/sched.h"
+#include "linux/slab.h"
 #include "chan_kern.h"
 #include "irq_kern.h"
 #include "irq_user.h"
@@ -18,10 +19,10 @@ static irqreturn_t line_interrupt(int ir
 {
 	struct chan *chan = data;
 	struct line *line = chan->line;
-	struct tty_struct *tty = line->tty;
+	struct tty_struct *tty;
 
 	if (line)
-		chan_interrupt(&line->chan_list, &line->task, tty, irq);
+		chan_interrupt(&line->chan_list, &line->task, line->tty, irq);
 	return IRQ_HANDLED;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/um/drivers/mconsole_kern.c linux-libre-2.6.34-gnu1/arch/um/drivers/mconsole_kern.c
--- linux-libre-2.6.33-gnu1/arch/um/drivers/mconsole_kern.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/drivers/mconsole_kern.c	2010-05-16 17:17:36.000000000 -0400
@@ -140,7 +140,7 @@ void mconsole_proc(struct mc_request *re
 		goto out;
 	}
 
-	err = may_open(&nd.path, MAY_READ, FMODE_READ);
+	err = may_open(&nd.path, MAY_READ, O_RDONLY);
 	if (result) {
 		mconsole_reply(req, "Failed to open file", 1, 0);
 		path_put(&nd.path);
diff -druNp linux-libre-2.6.33-gnu1/arch/um/drivers/net_kern.c linux-libre-2.6.34-gnu1/arch/um/drivers/net_kern.c
--- linux-libre-2.6.33-gnu1/arch/um/drivers/net_kern.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/drivers/net_kern.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include "init.h"
 #include "irq_kern.h"
diff -druNp linux-libre-2.6.33-gnu1/arch/um/drivers/port_kern.c linux-libre-2.6.34-gnu1/arch/um/drivers/port_kern.c
--- linux-libre-2.6.33-gnu1/arch/um/drivers/port_kern.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/drivers/port_kern.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
 #include "linux/interrupt.h"
 #include "linux/list.h"
 #include "linux/mutex.h"
+#include "linux/slab.h"
 #include "linux/workqueue.h"
 #include "asm/atomic.h"
 #include "init.h"
diff -druNp linux-libre-2.6.33-gnu1/arch/um/drivers/ubd_kern.c linux-libre-2.6.34-gnu1/arch/um/drivers/ubd_kern.c
--- linux-libre-2.6.33-gnu1/arch/um/drivers/ubd_kern.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/drivers/ubd_kern.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include "linux/ctype.h"
 #include "linux/capability.h"
 #include "linux/mm.h"
+#include "linux/slab.h"
 #include "linux/vmalloc.h"
 #include "linux/blkpg.h"
 #include "linux/genhd.h"
@@ -747,7 +748,7 @@ static int ubd_open_dev(struct ubd *ubd_
 	ubd_dev->fd = fd;
 
 	if(ubd_dev->cow.file != NULL){
-		blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long));
+		blk_queue_max_hw_sectors(ubd_dev->queue, 8 * sizeof(long));
 
 		err = -ENOMEM;
 		ubd_dev->cow.bitmap = vmalloc(ubd_dev->cow.bitmap_len);
@@ -849,7 +850,7 @@ 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);
+	blk_queue_max_segments(ubd_dev->queue, MAX_SG);
 	err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]);
 	if(err){
 		*error_out = "Failed to register device";
diff -druNp linux-libre-2.6.33-gnu1/arch/um/.gitignore linux-libre-2.6.34-gnu1/arch/um/.gitignore
--- linux-libre-2.6.33-gnu1/arch/um/.gitignore	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/.gitignore	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,3 @@
+kernel/config.c
+kernel/config.tmp
+kernel/vmlinux.lds
diff -druNp linux-libre-2.6.33-gnu1/arch/um/include/asm/dma-mapping.h linux-libre-2.6.34-gnu1/arch/um/include/asm/dma-mapping.h
--- linux-libre-2.6.33-gnu1/arch/um/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/include/asm/dma-mapping.h	2010-05-16 17:17:36.000000000 -0400
@@ -104,14 +104,6 @@ dma_get_cache_alignment(void)
 }
 
 static inline void
-dma_sync_single_range(struct device *dev, dma_addr_t dma_handle,
-		      unsigned long offset, size_t size,
-		      enum dma_data_direction direction)
-{
-	BUG();
-}
-
-static inline void
 dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 	       enum dma_data_direction direction)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/um/include/asm/pgtable.h linux-libre-2.6.34-gnu1/arch/um/include/asm/pgtable.h
--- linux-libre-2.6.33-gnu1/arch/um/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -345,7 +345,7 @@ static inline pte_t pte_modify(pte_t pte
 struct mm_struct;
 extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
 
-#define update_mmu_cache(vma,address,pte) do ; while (0)
+#define update_mmu_cache(vma,address,ptep) do ; while (0)
 
 /* Encode and de-code a swap entry */
 #define __swp_type(x)			(((x).val >> 4) & 0x3f)
diff -druNp linux-libre-2.6.33-gnu1/arch/um/include/asm/ptrace-generic.h linux-libre-2.6.34-gnu1/arch/um/include/asm/ptrace-generic.h
--- linux-libre-2.6.33-gnu1/arch/um/include/asm/ptrace-generic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/include/asm/ptrace-generic.h	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,8 @@ struct pt_regs {
 	struct uml_pt_regs regs;
 };
 
+#define arch_has_single_step()	(1)
+
 #define EMPTY_REGS { .regs = EMPTY_UML_PT_REGS }
 
 #define PT_REGS_IP(r) UPT_IP(&(r)->regs)
diff -druNp linux-libre-2.6.33-gnu1/arch/um/kernel/exec.c linux-libre-2.6.34-gnu1/arch/um/kernel/exec.c
--- linux-libre-2.6.33-gnu1/arch/um/kernel/exec.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/kernel/exec.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 #include "linux/smp_lock.h"
 #include "linux/ptrace.h"
 #include "linux/sched.h"
+#include "linux/slab.h"
 #include "asm/current.h"
 #include "asm/processor.h"
 #include "asm/uaccess.h"
diff -druNp linux-libre-2.6.33-gnu1/arch/um/kernel/irq.c linux-libre-2.6.34-gnu1/arch/um/kernel/irq.c
--- linux-libre-2.6.33-gnu1/arch/um/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/kernel/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include "linux/module.h"
 #include "linux/sched.h"
 #include "linux/seq_file.h"
+#include "linux/slab.h"
 #include "as-layout.h"
 #include "kern_util.h"
 #include "os.h"
diff -druNp linux-libre-2.6.33-gnu1/arch/um/kernel/mem.c linux-libre-2.6.34-gnu1/arch/um/kernel/mem.c
--- linux-libre-2.6.33-gnu1/arch/um/kernel/mem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/kernel/mem.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,10 +5,10 @@
 
 #include <linux/stddef.h>
 #include <linux/bootmem.h>
-#include <linux/gfp.h>
 #include <linux/highmem.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
+#include <linux/slab.h>
 #include <asm/fixmap.h>
 #include <asm/page.h>
 #include "as-layout.h"
diff -druNp linux-libre-2.6.33-gnu1/arch/um/kernel/process.c linux-libre-2.6.34-gnu1/arch/um/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/um/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,13 +7,13 @@
 #include <linux/stddef.h>
 #include <linux/err.h>
 #include <linux/hardirq.h>
-#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/personality.h>
 #include <linux/proc_fs.h>
 #include <linux/ptrace.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/tick.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/um/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/um/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/um/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,16 +12,25 @@
 #endif
 #include "skas_ptrace.h"
 
-static inline void set_singlestepping(struct task_struct *child, int on)
+
+
+void user_enable_single_step(struct task_struct *child)
 {
-	if (on)
-		child->ptrace |= PT_DTRACE;
-	else
-		child->ptrace &= ~PT_DTRACE;
+	child->ptrace |= PT_DTRACE;
 	child->thread.singlestep_syscall = 0;
 
 #ifdef SUBARCH_SET_SINGLESTEPPING
-	SUBARCH_SET_SINGLESTEPPING(child, on);
+	SUBARCH_SET_SINGLESTEPPING(child, 1);
+#endif
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+	child->ptrace &= ~PT_DTRACE;
+	child->thread.singlestep_syscall = 0;
+
+#ifdef SUBARCH_SET_SINGLESTEPPING
+	SUBARCH_SET_SINGLESTEPPING(child, 0);
 #endif
 }
 
@@ -30,7 +39,7 @@ static inline void set_singlestepping(st
  */
 void ptrace_disable(struct task_struct *child)
 {
-	set_singlestepping(child,0);
+	user_disable_single_step(child);
 }
 
 extern int peek_user(struct task_struct * child, long addr, long data);
@@ -69,53 +78,6 @@ long arch_ptrace(struct task_struct *chi
 		ret = -EIO;
 		break;
 
-	/* continue and stop at next (return from) syscall */
-	case PTRACE_SYSCALL:
-	/* restart after signal. */
-	case PTRACE_CONT: {
-		ret = -EIO;
-		if (!valid_signal(data))
-			break;
-
-		set_singlestepping(child, 0);
-		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;
-		wake_up_process(child);
-		ret = 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: {
-		ret = 0;
-		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
-			break;
-
-		set_singlestepping(child, 0);
-		child->exit_code = SIGKILL;
-		wake_up_process(child);
-		break;
-	}
-
-	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
-		ret = -EIO;
-		if (!valid_signal(data))
-			break;
-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		set_singlestepping(child, 1);
-		child->exit_code = data;
-		/* give it a chance to run. */
-		wake_up_process(child);
-		ret = 0;
-		break;
-	}
-
 #ifdef PTRACE_GETREGS
 	case PTRACE_GETREGS: { /* Get all gp regs from the child. */
 		if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) {
diff -druNp linux-libre-2.6.33-gnu1/arch/um/kernel/reboot.c linux-libre-2.6.34-gnu1/arch/um/kernel/reboot.c
--- linux-libre-2.6.33-gnu1/arch/um/kernel/reboot.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/kernel/reboot.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
  */
 
 #include "linux/sched.h"
+#include "linux/slab.h"
 #include "kern_util.h"
 #include "os.h"
 #include "skas.h"
diff -druNp linux-libre-2.6.33-gnu1/arch/um/kernel/skas/mmu.c linux-libre-2.6.34-gnu1/arch/um/kernel/skas/mmu.c
--- linux-libre-2.6.33-gnu1/arch/um/kernel/skas/mmu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/kernel/skas/mmu.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
 
 #include "linux/mm.h"
 #include "linux/sched.h"
+#include "linux/slab.h"
 #include "asm/pgalloc.h"
 #include "asm/pgtable.h"
 #include "as-layout.h"
diff -druNp linux-libre-2.6.33-gnu1/arch/um/kernel/syscall.c linux-libre-2.6.34-gnu1/arch/um/kernel/syscall.c
--- linux-libre-2.6.33-gnu1/arch/um/kernel/syscall.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/kernel/syscall.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,51 +51,6 @@ long old_mmap(unsigned long addr, unsign
 	return err;
 }
 
-long sys_uname(struct old_utsname __user * name)
-{
-	long err;
-	if (!name)
-		return -EFAULT;
-	down_read(&uts_sem);
-	err = copy_to_user(name, utsname(), sizeof (*name));
-	up_read(&uts_sem);
-	return err?-EFAULT:0;
-}
-
-long sys_olduname(struct oldold_utsname __user * name)
-{
-	long error;
-
-	if (!name)
-		return -EFAULT;
-	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
-		return -EFAULT;
-
-	down_read(&uts_sem);
-
-	error = __copy_to_user(&name->sysname, &utsname()->sysname,
-			       __OLD_UTS_LEN);
-	error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->nodename, &utsname()->nodename,
-				__OLD_UTS_LEN);
-	error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->release, &utsname()->release,
-				__OLD_UTS_LEN);
-	error |= __put_user(0, name->release + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->version, &utsname()->version,
-				__OLD_UTS_LEN);
-	error |= __put_user(0, name->version + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->machine, &utsname()->machine,
-				__OLD_UTS_LEN);
-	error |= __put_user(0, name->machine + __OLD_UTS_LEN);
-
-	up_read(&uts_sem);
-
-	error = error ? -EFAULT : 0;
-
-	return error;
-}
-
 int kernel_execve(const char *filename, char *const argv[], char *const envp[])
 {
 	mm_segment_t fs;
diff -druNp linux-libre-2.6.33-gnu1/arch/um/sys-i386/asm/elf.h linux-libre-2.6.34-gnu1/arch/um/sys-i386/asm/elf.h
--- linux-libre-2.6.33-gnu1/arch/um/sys-i386/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/sys-i386/asm/elf.h	2010-05-16 17:17:36.000000000 -0400
@@ -116,47 +116,4 @@ do {								\
 	}							\
 } while (0)
 
-/*
- * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
- * extra segments containing the vsyscall DSO contents.  Dumping its
- * contents makes post-mortem fully interpretable later without matching up
- * the same kernel and hardware config to see what PC values meant.
- * Dumping its extra ELF program headers includes all the other information
- * a debugger needs to easily find how the vsyscall DSO was being used.
- */
-#define ELF_CORE_EXTRA_PHDRS						      \
-	(vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0 )
-
-#define ELF_CORE_WRITE_EXTRA_PHDRS					      \
-if ( vsyscall_ehdr ) {							      \
-	const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr;    \
-	const struct elf_phdr *const phdrp =				      \
-		(const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);   \
-	int i;								      \
-	Elf32_Off ofs = 0;						      \
-	for (i = 0; i < ehdrp->e_phnum; ++i) {				      \
-		struct elf_phdr phdr = phdrp[i];			      \
-		if (phdr.p_type == PT_LOAD) {				      \
-			ofs = phdr.p_offset = offset;			      \
-			offset += phdr.p_filesz;			      \
-		}							      \
-		else							      \
-			phdr.p_offset += ofs;				      \
-		phdr.p_paddr = 0; /* match other core phdrs */		      \
-		DUMP_WRITE(&phdr, sizeof(phdr));			      \
-	}								      \
-}
-#define ELF_CORE_WRITE_EXTRA_DATA					      \
-if ( vsyscall_ehdr ) {							      \
-	const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr;    \
-	const struct elf_phdr *const phdrp =				      \
-		(const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);   \
-	int i;								      \
-	for (i = 0; i < ehdrp->e_phnum; ++i) {				      \
-		if (phdrp[i].p_type == PT_LOAD)				      \
-			DUMP_WRITE((void *) phdrp[i].p_vaddr,		      \
-				   phdrp[i].p_filesz);			      \
-	}								      \
-}
-
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/um/sys-i386/elfcore.c linux-libre-2.6.34-gnu1/arch/um/sys-i386/elfcore.c
--- linux-libre-2.6.33-gnu1/arch/um/sys-i386/elfcore.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/sys-i386/elfcore.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,83 @@
+#include <linux/elf.h>
+#include <linux/coredump.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+
+#include <asm/elf.h>
+
+
+Elf32_Half elf_core_extra_phdrs(void)
+{
+	return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0;
+}
+
+int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
+			       unsigned long limit)
+{
+	if ( vsyscall_ehdr ) {
+		const struct elfhdr *const ehdrp =
+			(struct elfhdr *) vsyscall_ehdr;
+		const struct elf_phdr *const phdrp =
+			(const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
+		int i;
+		Elf32_Off ofs = 0;
+
+		for (i = 0; i < ehdrp->e_phnum; ++i) {
+			struct elf_phdr phdr = phdrp[i];
+
+			if (phdr.p_type == PT_LOAD) {
+				ofs = phdr.p_offset = offset;
+				offset += phdr.p_filesz;
+			} else {
+				phdr.p_offset += ofs;
+			}
+			phdr.p_paddr = 0; /* match other core phdrs */
+			*size += sizeof(phdr);
+			if (*size > limit
+			    || !dump_write(file, &phdr, sizeof(phdr)))
+				return 0;
+		}
+	}
+	return 1;
+}
+
+int elf_core_write_extra_data(struct file *file, size_t *size,
+			      unsigned long limit)
+{
+	if ( vsyscall_ehdr ) {
+		const struct elfhdr *const ehdrp =
+			(struct elfhdr *) vsyscall_ehdr;
+		const struct elf_phdr *const phdrp =
+			(const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
+		int i;
+
+		for (i = 0; i < ehdrp->e_phnum; ++i) {
+			if (phdrp[i].p_type == PT_LOAD) {
+				void *addr = (void *) phdrp[i].p_vaddr;
+				size_t filesz = phdrp[i].p_filesz;
+
+				*size += filesz;
+				if (*size > limit
+				    || !dump_write(file, addr, filesz))
+					return 0;
+			}
+		}
+	}
+	return 1;
+}
+
+size_t elf_core_extra_data_size(void)
+{
+	if ( vsyscall_ehdr ) {
+		const struct elfhdr *const ehdrp =
+			(struct elfhdr *)vsyscall_ehdr;
+		const struct elf_phdr *const phdrp =
+			(const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
+		int i;
+
+		for (i = 0; i < ehdrp->e_phnum; ++i)
+			if (phdrp[i].p_type == PT_LOAD)
+				return (size_t) phdrp[i].p_filesz;
+	}
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/um/sys-i386/ldt.c linux-libre-2.6.34-gnu1/arch/um/sys-i386/ldt.c
--- linux-libre-2.6.33-gnu1/arch/um/sys-i386/ldt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/sys-i386/ldt.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
 
 #include <linux/mm.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/unistd.h>
 #include "os.h"
 #include "proc_mm.h"
diff -druNp linux-libre-2.6.33-gnu1/arch/um/sys-i386/Makefile linux-libre-2.6.34-gnu1/arch/um/sys-i386/Makefile
--- linux-libre-2.6.33-gnu1/arch/um/sys-i386/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/sys-i386/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,8 @@ obj-y = bug.o bugs.o checksum.o delay.o
 	ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \
 	sys_call_table.o tls.o
 
+obj-$(CONFIG_BINFMT_ELF) += elfcore.o
+
 subarch-obj-y = lib/semaphore_32.o lib/string_32.o
 subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
 subarch-obj-$(CONFIG_MODULES) += kernel/module.o
diff -druNp linux-libre-2.6.33-gnu1/arch/um/sys-i386/shared/sysdep/syscalls.h linux-libre-2.6.34-gnu1/arch/um/sys-i386/shared/sysdep/syscalls.h
--- linux-libre-2.6.33-gnu1/arch/um/sys-i386/shared/sysdep/syscalls.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/sys-i386/shared/sysdep/syscalls.h	2010-05-16 17:17:36.000000000 -0400
@@ -13,8 +13,6 @@ typedef long syscall_handler_t(struct pt
  */
 extern syscall_handler_t sys_rt_sigaction;
 
-extern syscall_handler_t old_mmap_i386;
-
 extern syscall_handler_t *sys_call_table[];
 
 #define EXECUTE_SYSCALL(syscall, regs) \
diff -druNp linux-libre-2.6.33-gnu1/arch/um/sys-i386/syscalls.c linux-libre-2.6.34-gnu1/arch/um/sys-i386/syscalls.c
--- linux-libre-2.6.33-gnu1/arch/um/sys-i386/syscalls.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/sys-i386/syscalls.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,57 +12,6 @@
 #include "asm/unistd.h"
 
 /*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. Linux/i386 didn't use to be able to handle more than
- * 4 system call parameters, so these system calls used a memory
- * block for parameter passing..
- */
-
-struct mmap_arg_struct {
-	unsigned long addr;
-	unsigned long len;
-	unsigned long prot;
-	unsigned long flags;
-	unsigned long fd;
-	unsigned long offset;
-};
-
-extern int old_mmap(unsigned long addr, unsigned long len,
-		    unsigned long prot, unsigned long flags,
-		    unsigned long fd, unsigned long offset);
-
-long old_mmap_i386(struct mmap_arg_struct __user *arg)
-{
-	struct mmap_arg_struct a;
-	int err = -EFAULT;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		goto out;
-
-	err = old_mmap(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
- out:
-	return err;
-}
-
-struct sel_arg_struct {
-	unsigned long n;
-	fd_set __user *inp;
-	fd_set __user *outp;
-	fd_set __user *exp;
-	struct timeval __user *tvp;
-};
-
-long old_select(struct sel_arg_struct __user *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	/* sys_select() does the appropriate kernel locking */
-	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
-/*
  * The prototype on i386 is:
  *
  *     int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr)
@@ -85,92 +34,6 @@ long sys_clone(unsigned long clone_flags
 	return ret;
 }
 
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-long sys_ipc (uint call, int first, int second,
-	     int third, void __user *ptr, long fifth)
-{
-	int version, ret;
-
-	version = call >> 16; /* hack for backward compatibility */
-	call &= 0xffff;
-
-	switch (call) {
-	case SEMOP:
-		return sys_semtimedop(first, (struct sembuf __user *) ptr,
-				      second, NULL);
-	case SEMTIMEDOP:
-		return sys_semtimedop(first, (struct sembuf __user *) ptr,
-				      second,
-				      (const struct timespec __user *) fifth);
-	case SEMGET:
-		return sys_semget (first, second, third);
-	case SEMCTL: {
-		union semun fourth;
-		if (!ptr)
-			return -EINVAL;
-		if (get_user(fourth.__pad, (void __user * __user *) ptr))
-			return -EFAULT;
-		return sys_semctl (first, second, third, fourth);
-	}
-
-	case MSGSND:
-		return sys_msgsnd (first, (struct msgbuf *) ptr,
-				   second, third);
-	case MSGRCV:
-		switch (version) {
-		case 0: {
-			struct ipc_kludge tmp;
-			if (!ptr)
-				return -EINVAL;
-
-			if (copy_from_user(&tmp,
-					   (struct ipc_kludge *) ptr,
-					   sizeof (tmp)))
-				return -EFAULT;
-			return sys_msgrcv (first, tmp.msgp, second,
-					   tmp.msgtyp, third);
-		}
-		default:
-		        panic("msgrcv with version != 0");
-			return sys_msgrcv (first,
-					   (struct msgbuf *) ptr,
-					   second, fifth, third);
-		}
-	case MSGGET:
-		return sys_msgget ((key_t) first, second);
-	case MSGCTL:
-		return sys_msgctl (first, second, (struct msqid_ds *) ptr);
-
-	case SHMAT:
-		switch (version) {
-		default: {
-			ulong raddr;
-			ret = do_shmat (first, (char *) ptr, second, &raddr);
-			if (ret)
-				return ret;
-			return put_user (raddr, (ulong *) third);
-		}
-		case 1:	/* iBCS2 emulator entry point */
-			if (!segment_eq(get_fs(), get_ds()))
-				return -EINVAL;
-			return do_shmat (first, (char *) ptr, second, (ulong *) third);
-		}
-	case SHMDT:
-		return sys_shmdt ((char *)ptr);
-	case SHMGET:
-		return sys_shmget (first, second, third);
-	case SHMCTL:
-		return sys_shmctl (first, second,
-				   (struct shmid_ds *) ptr);
-	default:
-		return -ENOSYS;
-	}
-}
-
 long sys_sigaction(int sig, const struct old_sigaction __user *act,
 			 struct old_sigaction __user *oact)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/um/sys-i386/sys_call_table.S linux-libre-2.6.34-gnu1/arch/um/sys-i386/sys_call_table.S
--- linux-libre-2.6.33-gnu1/arch/um/sys-i386/sys_call_table.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/sys-i386/sys_call_table.S	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,7 @@
 #define sys_vm86old sys_ni_syscall
 #define sys_vm86 sys_ni_syscall
 
-#define old_mmap old_mmap_i386
+#define old_mmap sys_old_mmap
 
 #define ptregs_fork sys_fork
 #define ptregs_execve sys_execve
diff -druNp linux-libre-2.6.33-gnu1/arch/um/sys-x86_64/Makefile linux-libre-2.6.34-gnu1/arch/um/sys-x86_64/Makefile
--- linux-libre-2.6.33-gnu1/arch/um/sys-x86_64/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/sys-x86_64/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,8 @@ obj-y = bug.o bugs.o delay.o fault.o ldt
 	setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \
 	sysrq.o ksyms.o tls.o
 
-subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o
+subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o \
+		lib/rwsem_64.o
 subarch-obj-$(CONFIG_MODULES) += kernel/module.o
 
 ldt-y = ../sys-i386/ldt.o
diff -druNp linux-libre-2.6.33-gnu1/arch/um/sys-x86_64/syscalls.c linux-libre-2.6.34-gnu1/arch/um/sys-x86_64/syscalls.c
--- linux-libre-2.6.33-gnu1/arch/um/sys-x86_64/syscalls.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/sys-x86_64/syscalls.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,20 +12,6 @@
 #include "asm/uaccess.h"
 #include "os.h"
 
-asmlinkage long sys_uname64(struct new_utsname __user * name)
-{
-	int err;
-
-	down_read(&uts_sem);
-	err = copy_to_user(name, utsname(), sizeof (*name));
-	up_read(&uts_sem);
-
-	if (personality(current->personality) == PER_LINUX32)
-		err |= copy_to_user(&name->machine, "i686", 5);
-
-	return err ? -EFAULT : 0;
-}
-
 long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
 {
 	unsigned long *ptr = addr, tmp;
diff -druNp linux-libre-2.6.33-gnu1/arch/um/sys-x86_64/syscall_table.c linux-libre-2.6.34-gnu1/arch/um/sys-x86_64/syscall_table.c
--- linux-libre-2.6.33-gnu1/arch/um/sys-x86_64/syscall_table.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/um/sys-x86_64/syscall_table.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,11 +26,6 @@
 
 /* On UML we call it this way ("old" means it's not mmap2) */
 #define sys_mmap old_mmap
-/*
- * On x86-64 sys_uname is actually sys_newuname plus a compatibility trick.
- * See arch/x86_64/kernel/sys_x86_64.c
- */
-#define sys_uname sys_uname64
 
 #define stub_clone sys_clone
 #define stub_fork sys_fork
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/boot/compressed/misc.c linux-libre-2.6.34-gnu1/arch/x86/boot/compressed/misc.c
--- linux-libre-2.6.33-gnu1/arch/x86/boot/compressed/misc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/boot/compressed/misc.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,11 +19,6 @@
 #define _ASM_X86_DESC_H 1
 #endif
 
-#ifdef CONFIG_X86_64
-#define _LINUX_STRING_H_ 1
-#define __LINUX_BITMAP_H 1
-#endif
-
 #include <linux/linkage.h>
 #include <linux/screen_info.h>
 #include <linux/elf.h>
@@ -131,8 +126,8 @@ static void error(char *m);
 static struct boot_params *real_mode;		/* Pointer to real-mode data */
 static int quiet;
 
-static void *memset(void *s, int c, unsigned n);
-void *memcpy(void *dest, const void *src, unsigned n);
+void *memset(void *s, int c, size_t n);
+void *memcpy(void *dest, const void *src, size_t n);
 
 static void __putstr(int, const char *);
 #define putstr(__x)  __putstr(0, __x)
@@ -185,11 +180,9 @@ static void __putstr(int error, const ch
 		return;
 #endif
 
-#ifdef CONFIG_X86_32
 	if (real_mode->screen_info.orig_video_mode == 0 &&
 	    lines == 0 && cols == 0)
 		return;
-#endif
 
 	x = real_mode->screen_info.orig_x;
 	y = real_mode->screen_info.orig_y;
@@ -223,7 +216,7 @@ static void __putstr(int error, const ch
 	outb(0xff & (pos >> 1), vidport+1);
 }
 
-static void *memset(void *s, int c, unsigned n)
+void *memset(void *s, int c, size_t n)
 {
 	int i;
 	char *ss = s;
@@ -233,7 +226,7 @@ static void *memset(void *s, int c, unsi
 	return s;
 }
 
-void *memcpy(void *dest, const void *src, unsigned n)
+void *memcpy(void *dest, const void *src, size_t n)
 {
 	int i;
 	const char *s = src;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/boot/mkcpustr.c linux-libre-2.6.34-gnu1/arch/x86/boot/mkcpustr.c
--- linux-libre-2.6.33-gnu1/arch/x86/boot/mkcpustr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/boot/mkcpustr.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,7 @@ int main(void)
 	int i, j;
 	const char *str;
 
-	printf("static const char x86_cap_strs[] = \n");
+	printf("static const char x86_cap_strs[] =\n");
 
 	for (i = 0; i < NCAPINTS; i++) {
 		for (j = 0; j < 32; j++) {
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/boot/video.c linux-libre-2.6.34-gnu1/arch/x86/boot/video.c
--- linux-libre-2.6.33-gnu1/arch/x86/boot/video.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/boot/video.c	2010-05-16 17:17:36.000000000 -0400
@@ -298,11 +298,18 @@ static void restore_screen(void)
 	}
 
 	/* Restore cursor position */
+	if (saved.curx >= xs)
+		saved.curx = xs-1;
+	if (saved.cury >= ys)
+		saved.cury = ys-1;
+
 	initregs(&ireg);
 	ireg.ah = 0x02;		/* Set cursor position */
 	ireg.dh = saved.cury;
 	ireg.dl = saved.curx;
 	intcall(0x10, &ireg, NULL);
+
+	store_cursor_position();
 }
 
 void set_video(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/boot/video-vga.c linux-libre-2.6.34-gnu1/arch/x86/boot/video-vga.c
--- linux-libre-2.6.33-gnu1/arch/x86/boot/video-vga.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/boot/video-vga.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,22 +42,15 @@ static u8 vga_set_basic_mode(void)
 {
 	struct biosregs ireg, oreg;
 	u16 ax;
-	u8 rows;
 	u8 mode;
 
 	initregs(&ireg);
 
+	/* Query current mode */
 	ax = 0x0f00;
 	intcall(0x10, &ireg, &oreg);
 	mode = oreg.al;
 
-	set_fs(0);
-	rows = rdfs8(0x484);	/* rows minus one */
-
-	if ((oreg.ax == 0x5003 || oreg.ax == 0x5007) &&
-	    (rows == 0 || rows == 24))
-		return mode;
-
 	if (mode != 3 && mode != 7)
 		mode = 3;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/crypto/fpu.c linux-libre-2.6.34-gnu1/arch/x86/crypto/fpu.c
--- linux-libre-2.6.33-gnu1/arch/x86/crypto/fpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/crypto/fpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/i387.h>
 
 struct crypto_fpu_ctx {
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/crypto/twofish-i586-asm_32.S linux-libre-2.6.34-gnu1/arch/x86/crypto/twofish-i586-asm_32.S
--- linux-libre-2.6.33-gnu1/arch/x86/crypto/twofish-i586-asm_32.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/crypto/twofish-i586-asm_32.S	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,7 @@
 
 #include <asm/asm-offsets.h>
 
-/* return adress at 0 */
+/* return address at 0 */
 
 #define in_blk    12  /* input byte array address parameter*/
 #define out_blk   8  /* output byte array address parameter*/
@@ -230,8 +230,8 @@ twofish_enc_blk:
 	push    %edi
 
 	mov	tfm + 16(%esp),	%ebp	/* abuse the base pointer: set new base bointer to the crypto tfm */
-	add	$crypto_tfm_ctx_offset, %ebp	/* ctx adress */
-	mov     in_blk+16(%esp),%edi	/* input adress in edi */
+	add	$crypto_tfm_ctx_offset, %ebp	/* ctx address */
+	mov     in_blk+16(%esp),%edi	/* input address in edi */
 
 	mov	(%edi),		%eax
 	mov	b_offset(%edi),	%ebx
@@ -286,8 +286,8 @@ twofish_dec_blk:
 
 
 	mov	tfm + 16(%esp),	%ebp	/* abuse the base pointer: set new base bointer to the crypto tfm */
-	add	$crypto_tfm_ctx_offset, %ebp	/* ctx adress */
-	mov     in_blk+16(%esp),%edi	/* input adress in edi */
+	add	$crypto_tfm_ctx_offset, %ebp	/* ctx address */
+	mov     in_blk+16(%esp),%edi	/* input address in edi */
 
 	mov	(%edi),		%eax
 	mov	b_offset(%edi),	%ebx
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/crypto/twofish-x86_64-asm_64.S linux-libre-2.6.34-gnu1/arch/x86/crypto/twofish-x86_64-asm_64.S
--- linux-libre-2.6.33-gnu1/arch/x86/crypto/twofish-x86_64-asm_64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/crypto/twofish-x86_64-asm_64.S	2010-05-16 17:17:36.000000000 -0400
@@ -221,11 +221,11 @@
 twofish_enc_blk:
 	pushq    R1
 
-	/* %rdi contains the crypto tfm adress */
-	/* %rsi contains the output adress */
-	/* %rdx contains the input adress */
-	add	$crypto_tfm_ctx_offset, %rdi	/* set ctx adress */
-	/* ctx adress is moved to free one non-rex register
+	/* %rdi contains the crypto tfm address */
+	/* %rsi contains the output address */
+	/* %rdx contains the input address */
+	add	$crypto_tfm_ctx_offset, %rdi	/* set ctx address */
+	/* ctx address is moved to free one non-rex register
 	as target for the 8bit high operations */
 	mov	%rdi,		%r11
 
@@ -274,11 +274,11 @@ twofish_enc_blk:
 twofish_dec_blk:
 	pushq    R1
 
-	/* %rdi contains the crypto tfm adress */
-	/* %rsi contains the output adress */
-	/* %rdx contains the input adress */
-	add	$crypto_tfm_ctx_offset, %rdi	/* set ctx adress */
-	/* ctx adress is moved to free one non-rex register
+	/* %rdi contains the crypto tfm address */
+	/* %rsi contains the output address */
+	/* %rdx contains the input address */
+	add	$crypto_tfm_ctx_offset, %rdi	/* set ctx address */
+	/* ctx address is moved to free one non-rex register
 	as target for the 8bit high operations */
 	mov	%rdi,		%r11
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/ia32/ia32_aout.c linux-libre-2.6.34-gnu1/arch/x86/ia32/ia32_aout.c
--- linux-libre-2.6.33-gnu1/arch/x86/ia32/ia32_aout.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/ia32/ia32_aout.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
-#include <linux/slab.h>
 #include <linux/binfmts.h>
 #include <linux/personality.h>
 #include <linux/init.h>
@@ -297,7 +296,7 @@ static int load_aout_binary(struct linux
 	 * size limits imposed on them by creating programs with large
 	 * arrays in the data or bss.
 	 */
-	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
+	rlim = rlimit(RLIMIT_DATA);
 	if (rlim >= RLIM_INFINITY)
 		rlim = ~0;
 	if (ex.a_data + ex.a_bss > rlim)
@@ -327,7 +326,6 @@ static int load_aout_binary(struct linux
 	current->mm->free_area_cache = TASK_UNMAPPED_BASE;
 	current->mm->cached_hole_size = 0;
 
-	current->mm->mmap = NULL;
 	install_exec_creds(bprm);
 	current->flags &= ~PF_FORKNOEXEC;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/ia32/ia32entry.S linux-libre-2.6.34-gnu1/arch/x86/ia32/ia32entry.S
--- linux-libre-2.6.33-gnu1/arch/x86/ia32/ia32entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/ia32/ia32entry.S	2010-05-16 17:17:36.000000000 -0400
@@ -563,7 +563,7 @@ ia32_sys_call_table:
 	.quad quiet_ni_syscall			/* old mpx syscall holder */
 	.quad sys_setpgid
 	.quad quiet_ni_syscall			/* old ulimit syscall holder */
-	.quad sys32_olduname
+	.quad sys_olduname
 	.quad sys_umask		/* 60 */
 	.quad sys_chroot
 	.quad compat_sys_ustat
@@ -586,7 +586,7 @@ ia32_sys_call_table:
 	.quad compat_sys_settimeofday
 	.quad sys_getgroups16	/* 80 */
 	.quad sys_setgroups16
-	.quad sys32_old_select
+	.quad compat_sys_old_select
 	.quad sys_symlink
 	.quad sys_lstat
 	.quad sys_readlink		/* 85 */
@@ -613,7 +613,7 @@ ia32_sys_call_table:
 	.quad compat_sys_newstat
 	.quad compat_sys_newlstat
 	.quad compat_sys_newfstat
-	.quad sys32_uname
+	.quad sys_uname
 	.quad stub32_iopl		/* 110 */
 	.quad sys_vhangup
 	.quad quiet_ni_syscall	/* old "idle" system call */
@@ -626,7 +626,7 @@ ia32_sys_call_table:
 	.quad stub32_sigreturn
 	.quad stub32_clone		/* 120 */
 	.quad sys_setdomainname
-	.quad sys_uname
+	.quad sys_newuname
 	.quad sys_modify_ldt
 	.quad compat_sys_adjtimex
 	.quad sys32_mprotect		/* 125 */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/ia32/sys_ia32.c linux-libre-2.6.34-gnu1/arch/x86/ia32/sys_ia32.c
--- linux-libre-2.6.33-gnu1/arch/x86/ia32/sys_ia32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/ia32/sys_ia32.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/ptrace.h>
 #include <linux/highuid.h>
 #include <linux/sysctl.h>
+#include <linux/slab.h>
 #include <asm/mman.h>
 #include <asm/types.h>
 #include <asm/uaccess.h>
@@ -143,7 +144,7 @@ asmlinkage long sys32_fstatat(unsigned i
  * block for parameter passing..
  */
 
-struct mmap_arg_struct {
+struct mmap_arg_struct32 {
 	unsigned int addr;
 	unsigned int len;
 	unsigned int prot;
@@ -152,9 +153,9 @@ struct mmap_arg_struct {
 	unsigned int offset;
 };
 
-asmlinkage long sys32_mmap(struct mmap_arg_struct __user *arg)
+asmlinkage long sys32_mmap(struct mmap_arg_struct32 __user *arg)
 {
-	struct mmap_arg_struct a;
+	struct mmap_arg_struct32 a;
 
 	if (copy_from_user(&a, arg, sizeof(a)))
 		return -EFAULT;
@@ -332,24 +333,6 @@ asmlinkage long sys32_alarm(unsigned int
 	return alarm_setitimer(seconds);
 }
 
-struct sel_arg_struct {
-	unsigned int n;
-	unsigned int inp;
-	unsigned int outp;
-	unsigned int exp;
-	unsigned int tvp;
-};
-
-asmlinkage long sys32_old_select(struct sel_arg_struct __user *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
-				 compat_ptr(a.exp), compat_ptr(a.tvp));
-}
-
 asmlinkage long sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr,
 			      int options)
 {
@@ -466,58 +449,6 @@ asmlinkage long sys32_sendfile(int out_f
 	return ret;
 }
 
-asmlinkage long sys32_olduname(struct oldold_utsname __user *name)
-{
-	char *arch = "x86_64";
-	int err;
-
-	if (!name)
-		return -EFAULT;
-	if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
-		return -EFAULT;
-
-	down_read(&uts_sem);
-
-	err = __copy_to_user(&name->sysname, &utsname()->sysname,
-			     __OLD_UTS_LEN);
-	err |= __put_user(0, name->sysname+__OLD_UTS_LEN);
-	err |= __copy_to_user(&name->nodename, &utsname()->nodename,
-			      __OLD_UTS_LEN);
-	err |= __put_user(0, name->nodename+__OLD_UTS_LEN);
-	err |= __copy_to_user(&name->release, &utsname()->release,
-			      __OLD_UTS_LEN);
-	err |= __put_user(0, name->release+__OLD_UTS_LEN);
-	err |= __copy_to_user(&name->version, &utsname()->version,
-			      __OLD_UTS_LEN);
-	err |= __put_user(0, name->version+__OLD_UTS_LEN);
-
-	if (personality(current->personality) == PER_LINUX32)
-		arch = "i686";
-
-	err |= __copy_to_user(&name->machine, arch, strlen(arch) + 1);
-
-	up_read(&uts_sem);
-
-	err = err ? -EFAULT : 0;
-
-	return err;
-}
-
-long sys32_uname(struct old_utsname __user *name)
-{
-	int err;
-
-	if (!name)
-		return -EFAULT;
-	down_read(&uts_sem);
-	err = copy_to_user(name, utsname(), sizeof(*name));
-	up_read(&uts_sem);
-	if (personality(current->personality) == PER_LINUX32)
-		err |= copy_to_user(&name->machine, "i686", 5);
-
-	return err ? -EFAULT : 0;
-}
-
 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.33-gnu1/arch/x86/include/asm/alternative.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/alternative.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/alternative.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/alternative.h	2010-05-16 17:17:36.000000000 -0400
@@ -65,12 +65,17 @@ extern void alternatives_smp_module_add(
 					void *text, void *text_end);
 extern void alternatives_smp_module_del(struct module *mod);
 extern void alternatives_smp_switch(int smp);
+extern int alternatives_text_reserved(void *start, void *end);
 #else
 static inline void alternatives_smp_module_add(struct module *mod, char *name,
 					       void *locks, void *locks_end,
 					       void *text, void *text_end) {}
 static inline void alternatives_smp_module_del(struct module *mod) {}
 static inline void alternatives_smp_switch(int smp) {}
+static inline int alternatives_text_reserved(void *start, void *end)
+{
+	return 0;
+}
 #endif	/* CONFIG_SMP */
 
 /* alternative assembly primitive: */
@@ -125,11 +130,16 @@ static inline void alternatives_smp_swit
 	asm volatile (ALTERNATIVE(oldinstr, newinstr, feature)		\
 		: output : "i" (0), ## input)
 
+/* Like alternative_io, but for replacing a direct call with another one. */
+#define alternative_call(oldfunc, newfunc, feature, output, input...)	\
+	asm volatile (ALTERNATIVE("call %P[old]", "call %P[new]", feature) \
+		: output : [old] "i" (oldfunc), [new] "i" (newfunc), ## input)
+
 /*
  * use this macro(s) if you need more than one output parameter
  * in alternative_io
  */
-#define ASM_OUTPUT2(a, b) a, b
+#define ASM_OUTPUT2(a...) a
 
 struct paravirt_patch_site;
 #ifdef CONFIG_PARAVIRT
@@ -155,10 +165,12 @@ static inline void apply_paravirt(struct
  * invalid instruction possible) or if the instructions are changed from a
  * consistent state to another consistent state atomically.
  * More care must be taken when modifying code in the SMP case because of
- * Intel's errata.
+ * Intel's errata. text_poke_smp() takes care that errata, but still
+ * doesn't support NMI/MCE handler code modifying.
  * On the local CPU you need to be protected again NMI or MCE handlers seeing an
  * inconsistent instruction while you patch.
  */
 extern void *text_poke(void *addr, const void *opcode, size_t len);
+extern void *text_poke_smp(void *addr, const void *opcode, size_t len);
 
 #endif /* _ASM_X86_ALTERNATIVE_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/amd_iommu_types.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/amd_iommu_types.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/amd_iommu_types.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/amd_iommu_types.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #define _ASM_X86_AMD_IOMMU_TYPES_H
 
 #include <linux/types.h>
+#include <linux/mutex.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
 
@@ -140,6 +141,7 @@
 
 /* constants to configure the command buffer */
 #define CMD_BUFFER_SIZE    8192
+#define CMD_BUFFER_UNINITIALIZED 1
 #define CMD_BUFFER_ENTRIES 512
 #define MMIO_CMD_SIZE_SHIFT 56
 #define MMIO_CMD_SIZE_512 (0x9ULL << MMIO_CMD_SIZE_SHIFT)
@@ -237,6 +239,7 @@ struct protection_domain {
 	struct list_head list;  /* for list of all protection domains */
 	struct list_head dev_list; /* List of all devices in this domain */
 	spinlock_t lock;	/* mostly used to lock the page table*/
+	struct mutex api_lock;	/* protect page tables in the iommu-api path */
 	u16 id;			/* the domain id written to the device table */
 	int mode;		/* paging mode (0-6 levels) */
 	u64 *pt_root;		/* page table root pointer */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/apb_timer.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/apb_timer.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/apb_timer.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/apb_timer.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,70 @@
+/*
+ * apb_timer.h: Driver for Langwell APB timer based on Synopsis DesignWare
+ *
+ * (C) Copyright 2009 Intel Corporation
+ * Author: Jacob Pan (jacob.jun.pan@intel.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ *
+ * Note:
+ */
+
+#ifndef ASM_X86_APBT_H
+#define ASM_X86_APBT_H
+#include <linux/sfi.h>
+
+#ifdef CONFIG_APB_TIMER
+
+/* Langwell DW APB timer registers */
+#define APBTMR_N_LOAD_COUNT    0x00
+#define APBTMR_N_CURRENT_VALUE 0x04
+#define APBTMR_N_CONTROL       0x08
+#define APBTMR_N_EOI           0x0c
+#define APBTMR_N_INT_STATUS    0x10
+
+#define APBTMRS_INT_STATUS     0xa0
+#define APBTMRS_EOI            0xa4
+#define APBTMRS_RAW_INT_STATUS 0xa8
+#define APBTMRS_COMP_VERSION   0xac
+#define APBTMRS_REG_SIZE       0x14
+
+/* register bits */
+#define APBTMR_CONTROL_ENABLE  (1<<0)
+#define APBTMR_CONTROL_MODE_PERIODIC   (1<<1) /*1: periodic 0:free running */
+#define APBTMR_CONTROL_INT     (1<<2)
+
+/* default memory mapped register base */
+#define LNW_SCU_ADDR           0xFF100000
+#define LNW_EXT_TIMER_OFFSET   0x1B800
+#define APBT_DEFAULT_BASE      (LNW_SCU_ADDR+LNW_EXT_TIMER_OFFSET)
+#define LNW_EXT_TIMER_PGOFFSET         0x800
+
+/* APBT clock speed range from PCLK to fabric base, 25-100MHz */
+#define APBT_MAX_FREQ          50
+#define APBT_MIN_FREQ          1
+#define APBT_MMAP_SIZE         1024
+
+#define APBT_DEV_USED  1
+
+extern void apbt_time_init(void);
+extern struct clock_event_device *global_clock_event;
+extern unsigned long apbt_quick_calibrate(void);
+extern int arch_setup_apbt_irqs(int irq, int trigger, int mask, int cpu);
+extern void apbt_setup_secondary_clock(void);
+extern unsigned int boot_cpu_id;
+extern int disable_apbt_percpu;
+
+extern struct sfi_timer_table_entry *sfi_get_mtmr(int hint);
+extern void sfi_free_mtmr(struct sfi_timer_table_entry *mtmr);
+extern int sfi_mtimer_num;
+
+#else /* CONFIG_APB_TIMER */
+
+static inline unsigned long apbt_quick_calibrate(void) {return 0; }
+static inline void apbt_time_init(void) {return 0; }
+
+#endif
+#endif /* ASM_X86_APBT_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/atomic_32.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/atomic_32.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/atomic_32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/atomic_32.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,415 +0,0 @@
-#ifndef _ASM_X86_ATOMIC_32_H
-#define _ASM_X86_ATOMIC_32_H
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <asm/processor.h>
-#include <asm/cmpxchg.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.
- */
-static inline int atomic_read(const atomic_t *v)
-{
-	return v->counter;
-}
-
-/**
- * atomic_set - set atomic variable
- * @v: pointer of type atomic_t
- * @i: required value
- *
- * Atomically sets the value of @v to @i.
- */
-static inline void atomic_set(atomic_t *v, int i)
-{
-	v->counter = i;
-}
-
-/**
- * atomic_add - add integer to atomic variable
- * @i: integer value to add
- * @v: pointer of type atomic_t
- *
- * Atomically adds @i to @v.
- */
-static inline void atomic_add(int i, atomic_t *v)
-{
-	asm volatile(LOCK_PREFIX "addl %1,%0"
-		     : "+m" (v->counter)
-		     : "ir" (i));
-}
-
-/**
- * atomic_sub - subtract integer from atomic variable
- * @i: integer value to subtract
- * @v: pointer of type atomic_t
- *
- * Atomically subtracts @i from @v.
- */
-static inline void atomic_sub(int i, atomic_t *v)
-{
-	asm volatile(LOCK_PREFIX "subl %1,%0"
-		     : "+m" (v->counter)
-		     : "ir" (i));
-}
-
-/**
- * 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.
- */
-static inline int atomic_sub_and_test(int i, atomic_t *v)
-{
-	unsigned char c;
-
-	asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
-		     : "+m" (v->counter), "=qm" (c)
-		     : "ir" (i) : "memory");
-	return c;
-}
-
-/**
- * atomic_inc - increment atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically increments @v by 1.
- */
-static inline void atomic_inc(atomic_t *v)
-{
-	asm volatile(LOCK_PREFIX "incl %0"
-		     : "+m" (v->counter));
-}
-
-/**
- * atomic_dec - decrement atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically decrements @v by 1.
- */
-static inline void atomic_dec(atomic_t *v)
-{
-	asm volatile(LOCK_PREFIX "decl %0"
-		     : "+m" (v->counter));
-}
-
-/**
- * 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.
- */
-static inline int atomic_dec_and_test(atomic_t *v)
-{
-	unsigned char c;
-
-	asm volatile(LOCK_PREFIX "decl %0; sete %1"
-		     : "+m" (v->counter), "=qm" (c)
-		     : : "memory");
-	return c != 0;
-}
-
-/**
- * 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.
- */
-static inline int atomic_inc_and_test(atomic_t *v)
-{
-	unsigned char c;
-
-	asm volatile(LOCK_PREFIX "incl %0; sete %1"
-		     : "+m" (v->counter), "=qm" (c)
-		     : : "memory");
-	return c != 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.
- */
-static inline int atomic_add_negative(int i, atomic_t *v)
-{
-	unsigned char c;
-
-	asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
-		     : "+m" (v->counter), "=qm" (c)
-		     : "ir" (i) : "memory");
-	return c;
-}
-
-/**
- * atomic_add_return - add integer and return
- * @v: pointer of type atomic_t
- * @i: integer value to add
- *
- * Atomically adds @i to @v and returns @i + @v
- */
-static inline int atomic_add_return(int i, atomic_t *v)
-{
-	int __i;
-#ifdef CONFIG_M386
-	unsigned long flags;
-	if (unlikely(boot_cpu_data.x86 <= 3))
-		goto no_xadd;
-#endif
-	/* Modern 486+ processor */
-	__i = i;
-	asm volatile(LOCK_PREFIX "xaddl %0, %1"
-		     : "+r" (i), "+m" (v->counter)
-		     : : "memory");
-	return i + __i;
-
-#ifdef CONFIG_M386
-no_xadd: /* Legacy 386 processor */
-	local_irq_save(flags);
-	__i = atomic_read(v);
-	atomic_set(v, i + __i);
-	local_irq_restore(flags);
-	return i + __i;
-#endif
-}
-
-/**
- * atomic_sub_return - subtract integer and return
- * @v: pointer of type atomic_t
- * @i: integer value to subtract
- *
- * Atomically subtracts @i from @v and returns @v - @i
- */
-static inline int atomic_sub_return(int i, atomic_t *v)
-{
-	return atomic_add_return(-i, v);
-}
-
-static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
-{
-	return cmpxchg(&v->counter, old, new);
-}
-
-static inline int atomic_xchg(atomic_t *v, int new)
-{
-	return xchg(&v->counter, new);
-}
-
-/**
- * atomic_add_unless - add unless the number is already 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 @v was not already @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)
-
-#define atomic_inc_return(v)  (atomic_add_return(1, v))
-#define atomic_dec_return(v)  (atomic_sub_return(1, v))
-
-/* These are x86-specific, used by some header files */
-#define atomic_clear_mask(mask, addr)				\
-	asm volatile(LOCK_PREFIX "andl %0,%1"			\
-		     : : "r" (~(mask)), "m" (*(addr)) : "memory")
-
-#define atomic_set_mask(mask, addr)				\
-	asm volatile(LOCK_PREFIX "orl %0,%1"				\
-		     : : "r" (mask), "m" (*(addr)) : "memory")
-
-/* Atomic operations are already serializing on x86 */
-#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()
-
-/* An 64bit atomic type */
-
-typedef struct {
-	u64 __aligned(8) counter;
-} atomic64_t;
-
-#define ATOMIC64_INIT(val)	{ (val) }
-
-extern u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val);
-
-/**
- * atomic64_xchg - xchg atomic64 variable
- * @ptr:      pointer to type atomic64_t
- * @new_val:  value to assign
- *
- * Atomically xchgs the value of @ptr to @new_val and returns
- * the old value.
- */
-extern u64 atomic64_xchg(atomic64_t *ptr, u64 new_val);
-
-/**
- * atomic64_set - set atomic64 variable
- * @ptr:      pointer to type atomic64_t
- * @new_val:  value to assign
- *
- * Atomically sets the value of @ptr to @new_val.
- */
-extern void atomic64_set(atomic64_t *ptr, u64 new_val);
-
-/**
- * atomic64_read - read atomic64 variable
- * @ptr:      pointer to type atomic64_t
- *
- * Atomically reads the value of @ptr and returns it.
- */
-static inline u64 atomic64_read(atomic64_t *ptr)
-{
-	u64 res;
-
-	/*
-	 * Note, we inline this atomic64_t primitive because
-	 * it only clobbers EAX/EDX and leaves the others
-	 * untouched. We also (somewhat subtly) rely on the
-	 * fact that cmpxchg8b returns the current 64-bit value
-	 * of the memory location we are touching:
-	 */
-	asm volatile(
-		"mov %%ebx, %%eax\n\t"
-		"mov %%ecx, %%edx\n\t"
-		LOCK_PREFIX "cmpxchg8b %1\n"
-			: "=&A" (res)
-			: "m" (*ptr)
-		);
-
-	return res;
-}
-
-extern u64 atomic64_read(atomic64_t *ptr);
-
-/**
- * atomic64_add_return - add and return
- * @delta: integer value to add
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically adds @delta to @ptr and returns @delta + *@ptr
- */
-extern u64 atomic64_add_return(u64 delta, atomic64_t *ptr);
-
-/*
- * Other variants with different arithmetic operators:
- */
-extern u64 atomic64_sub_return(u64 delta, atomic64_t *ptr);
-extern u64 atomic64_inc_return(atomic64_t *ptr);
-extern u64 atomic64_dec_return(atomic64_t *ptr);
-
-/**
- * atomic64_add - add integer to atomic64 variable
- * @delta: integer value to add
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically adds @delta to @ptr.
- */
-extern void atomic64_add(u64 delta, atomic64_t *ptr);
-
-/**
- * atomic64_sub - subtract the atomic64 variable
- * @delta: integer value to subtract
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically subtracts @delta from @ptr.
- */
-extern void atomic64_sub(u64 delta, atomic64_t *ptr);
-
-/**
- * atomic64_sub_and_test - subtract value from variable and test result
- * @delta: integer value to subtract
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically subtracts @delta from @ptr and returns
- * true if the result is zero, or false for all
- * other cases.
- */
-extern int atomic64_sub_and_test(u64 delta, atomic64_t *ptr);
-
-/**
- * atomic64_inc - increment atomic64 variable
- * @ptr: pointer to type atomic64_t
- *
- * Atomically increments @ptr by 1.
- */
-extern void atomic64_inc(atomic64_t *ptr);
-
-/**
- * atomic64_dec - decrement atomic64 variable
- * @ptr: pointer to type atomic64_t
- *
- * Atomically decrements @ptr by 1.
- */
-extern void atomic64_dec(atomic64_t *ptr);
-
-/**
- * atomic64_dec_and_test - decrement and test
- * @ptr: pointer to type atomic64_t
- *
- * Atomically decrements @ptr by 1 and
- * returns true if the result is 0, or false for all other
- * cases.
- */
-extern int atomic64_dec_and_test(atomic64_t *ptr);
-
-/**
- * atomic64_inc_and_test - increment and test
- * @ptr: pointer to type atomic64_t
- *
- * Atomically increments @ptr by 1
- * and returns true if the result is zero, or false for all
- * other cases.
- */
-extern int atomic64_inc_and_test(atomic64_t *ptr);
-
-/**
- * atomic64_add_negative - add and test if negative
- * @delta: integer value to add
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically adds @delta to @ptr and returns true
- * if the result is negative, or false when
- * result is greater than or equal to zero.
- */
-extern int atomic64_add_negative(u64 delta, atomic64_t *ptr);
-
-#include <asm-generic/atomic-long.h>
-#endif /* _ASM_X86_ATOMIC_32_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/atomic64_32.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/atomic64_32.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/atomic64_32.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/atomic64_32.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,160 @@
+#ifndef _ASM_X86_ATOMIC64_32_H
+#define _ASM_X86_ATOMIC64_32_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <asm/processor.h>
+//#include <asm/cmpxchg.h>
+
+/* An 64bit atomic type */
+
+typedef struct {
+	u64 __aligned(8) counter;
+} atomic64_t;
+
+#define ATOMIC64_INIT(val)	{ (val) }
+
+extern u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val);
+
+/**
+ * atomic64_xchg - xchg atomic64 variable
+ * @ptr:      pointer to type atomic64_t
+ * @new_val:  value to assign
+ *
+ * Atomically xchgs the value of @ptr to @new_val and returns
+ * the old value.
+ */
+extern u64 atomic64_xchg(atomic64_t *ptr, u64 new_val);
+
+/**
+ * atomic64_set - set atomic64 variable
+ * @ptr:      pointer to type atomic64_t
+ * @new_val:  value to assign
+ *
+ * Atomically sets the value of @ptr to @new_val.
+ */
+extern void atomic64_set(atomic64_t *ptr, u64 new_val);
+
+/**
+ * atomic64_read - read atomic64 variable
+ * @ptr:      pointer to type atomic64_t
+ *
+ * Atomically reads the value of @ptr and returns it.
+ */
+static inline u64 atomic64_read(atomic64_t *ptr)
+{
+	u64 res;
+
+	/*
+	 * Note, we inline this atomic64_t primitive because
+	 * it only clobbers EAX/EDX and leaves the others
+	 * untouched. We also (somewhat subtly) rely on the
+	 * fact that cmpxchg8b returns the current 64-bit value
+	 * of the memory location we are touching:
+	 */
+	asm volatile(
+		"mov %%ebx, %%eax\n\t"
+		"mov %%ecx, %%edx\n\t"
+		LOCK_PREFIX "cmpxchg8b %1\n"
+			: "=&A" (res)
+			: "m" (*ptr)
+		);
+
+	return res;
+}
+
+extern u64 atomic64_read(atomic64_t *ptr);
+
+/**
+ * atomic64_add_return - add and return
+ * @delta: integer value to add
+ * @ptr:   pointer to type atomic64_t
+ *
+ * Atomically adds @delta to @ptr and returns @delta + *@ptr
+ */
+extern u64 atomic64_add_return(u64 delta, atomic64_t *ptr);
+
+/*
+ * Other variants with different arithmetic operators:
+ */
+extern u64 atomic64_sub_return(u64 delta, atomic64_t *ptr);
+extern u64 atomic64_inc_return(atomic64_t *ptr);
+extern u64 atomic64_dec_return(atomic64_t *ptr);
+
+/**
+ * atomic64_add - add integer to atomic64 variable
+ * @delta: integer value to add
+ * @ptr:   pointer to type atomic64_t
+ *
+ * Atomically adds @delta to @ptr.
+ */
+extern void atomic64_add(u64 delta, atomic64_t *ptr);
+
+/**
+ * atomic64_sub - subtract the atomic64 variable
+ * @delta: integer value to subtract
+ * @ptr:   pointer to type atomic64_t
+ *
+ * Atomically subtracts @delta from @ptr.
+ */
+extern void atomic64_sub(u64 delta, atomic64_t *ptr);
+
+/**
+ * atomic64_sub_and_test - subtract value from variable and test result
+ * @delta: integer value to subtract
+ * @ptr:   pointer to type atomic64_t
+ *
+ * Atomically subtracts @delta from @ptr and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+extern int atomic64_sub_and_test(u64 delta, atomic64_t *ptr);
+
+/**
+ * atomic64_inc - increment atomic64 variable
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically increments @ptr by 1.
+ */
+extern void atomic64_inc(atomic64_t *ptr);
+
+/**
+ * atomic64_dec - decrement atomic64 variable
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically decrements @ptr by 1.
+ */
+extern void atomic64_dec(atomic64_t *ptr);
+
+/**
+ * atomic64_dec_and_test - decrement and test
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically decrements @ptr by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+extern int atomic64_dec_and_test(atomic64_t *ptr);
+
+/**
+ * atomic64_inc_and_test - increment and test
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically increments @ptr by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+extern int atomic64_inc_and_test(atomic64_t *ptr);
+
+/**
+ * atomic64_add_negative - add and test if negative
+ * @delta: integer value to add
+ * @ptr:   pointer to type atomic64_t
+ *
+ * Atomically adds @delta to @ptr and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+extern int atomic64_add_negative(u64 delta, atomic64_t *ptr);
+
+#endif /* _ASM_X86_ATOMIC64_32_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/atomic64_64.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/atomic64_64.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/atomic64_64.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/atomic64_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,224 @@
+#ifndef _ASM_X86_ATOMIC64_64_H
+#define _ASM_X86_ATOMIC64_64_H
+
+#include <linux/types.h>
+#include <asm/alternative.h>
+#include <asm/cmpxchg.h>
+
+/* The 64-bit atomic type */
+
+#define ATOMIC64_INIT(i)	{ (i) }
+
+/**
+ * atomic64_read - read atomic64 variable
+ * @v: pointer of type atomic64_t
+ *
+ * Atomically reads the value of @v.
+ * Doesn't imply a read memory barrier.
+ */
+static inline long atomic64_read(const atomic64_t *v)
+{
+	return v->counter;
+}
+
+/**
+ * atomic64_set - set atomic64 variable
+ * @v: pointer to type atomic64_t
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i.
+ */
+static inline void atomic64_set(atomic64_t *v, long i)
+{
+	v->counter = i;
+}
+
+/**
+ * atomic64_add - add integer to atomic64 variable
+ * @i: integer value to add
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically adds @i to @v.
+ */
+static inline void atomic64_add(long i, atomic64_t *v)
+{
+	asm volatile(LOCK_PREFIX "addq %1,%0"
+		     : "=m" (v->counter)
+		     : "er" (i), "m" (v->counter));
+}
+
+/**
+ * atomic64_sub - subtract the atomic64 variable
+ * @i: integer value to subtract
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically subtracts @i from @v.
+ */
+static inline void atomic64_sub(long i, atomic64_t *v)
+{
+	asm volatile(LOCK_PREFIX "subq %1,%0"
+		     : "=m" (v->counter)
+		     : "er" (i), "m" (v->counter));
+}
+
+/**
+ * atomic64_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically subtracts @i from @v and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+static inline int atomic64_sub_and_test(long i, atomic64_t *v)
+{
+	unsigned char c;
+
+	asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
+		     : "=m" (v->counter), "=qm" (c)
+		     : "er" (i), "m" (v->counter) : "memory");
+	return c;
+}
+
+/**
+ * atomic64_inc - increment atomic64 variable
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically increments @v by 1.
+ */
+static inline void atomic64_inc(atomic64_t *v)
+{
+	asm volatile(LOCK_PREFIX "incq %0"
+		     : "=m" (v->counter)
+		     : "m" (v->counter));
+}
+
+/**
+ * atomic64_dec - decrement atomic64 variable
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically decrements @v by 1.
+ */
+static inline void atomic64_dec(atomic64_t *v)
+{
+	asm volatile(LOCK_PREFIX "decq %0"
+		     : "=m" (v->counter)
+		     : "m" (v->counter));
+}
+
+/**
+ * atomic64_dec_and_test - decrement and test
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically decrements @v by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+static inline int atomic64_dec_and_test(atomic64_t *v)
+{
+	unsigned char c;
+
+	asm volatile(LOCK_PREFIX "decq %0; sete %1"
+		     : "=m" (v->counter), "=qm" (c)
+		     : "m" (v->counter) : "memory");
+	return c != 0;
+}
+
+/**
+ * atomic64_inc_and_test - increment and test
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+static inline int atomic64_inc_and_test(atomic64_t *v)
+{
+	unsigned char c;
+
+	asm volatile(LOCK_PREFIX "incq %0; sete %1"
+		     : "=m" (v->counter), "=qm" (c)
+		     : "m" (v->counter) : "memory");
+	return c != 0;
+}
+
+/**
+ * atomic64_add_negative - add and test if negative
+ * @i: integer value to add
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically adds @i to @v and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+static inline int atomic64_add_negative(long i, atomic64_t *v)
+{
+	unsigned char c;
+
+	asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
+		     : "=m" (v->counter), "=qm" (c)
+		     : "er" (i), "m" (v->counter) : "memory");
+	return c;
+}
+
+/**
+ * atomic64_add_return - add and return
+ * @i: integer value to add
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically adds @i to @v and returns @i + @v
+ */
+static inline long atomic64_add_return(long i, atomic64_t *v)
+{
+	long __i = i;
+	asm volatile(LOCK_PREFIX "xaddq %0, %1;"
+		     : "+r" (i), "+m" (v->counter)
+		     : : "memory");
+	return i + __i;
+}
+
+static inline long atomic64_sub_return(long i, atomic64_t *v)
+{
+	return atomic64_add_return(-i, v);
+}
+
+#define atomic64_inc_return(v)  (atomic64_add_return(1, (v)))
+#define atomic64_dec_return(v)  (atomic64_sub_return(1, (v)))
+
+static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new)
+{
+	return cmpxchg(&v->counter, old, new);
+}
+
+static inline long atomic64_xchg(atomic64_t *v, long new)
+{
+	return xchg(&v->counter, new);
+}
+
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_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 atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+	long c, old;
+	c = atomic64_read(v);
+	for (;;) {
+		if (unlikely(c == (u)))
+			break;
+		old = atomic64_cmpxchg((v), c, c + (a));
+		if (likely(old == c))
+			break;
+		c = old;
+	}
+	return c != (u);
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
+#endif /* _ASM_X86_ATOMIC64_64_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/atomic_64.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/atomic_64.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/atomic_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/atomic_64.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,485 +0,0 @@
-#ifndef _ASM_X86_ATOMIC_64_H
-#define _ASM_X86_ATOMIC_64_H
-
-#include <linux/types.h>
-#include <asm/alternative.h>
-#include <asm/cmpxchg.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.
- */
-static inline int atomic_read(const atomic_t *v)
-{
-	return v->counter;
-}
-
-/**
- * atomic_set - set atomic variable
- * @v: pointer of type atomic_t
- * @i: required value
- *
- * Atomically sets the value of @v to @i.
- */
-static inline void atomic_set(atomic_t *v, int i)
-{
-	v->counter = i;
-}
-
-/**
- * atomic_add - add integer to atomic variable
- * @i: integer value to add
- * @v: pointer of type atomic_t
- *
- * Atomically adds @i to @v.
- */
-static inline void atomic_add(int i, atomic_t *v)
-{
-	asm volatile(LOCK_PREFIX "addl %1,%0"
-		     : "=m" (v->counter)
-		     : "ir" (i), "m" (v->counter));
-}
-
-/**
- * atomic_sub - subtract the atomic variable
- * @i: integer value to subtract
- * @v: pointer of type atomic_t
- *
- * Atomically subtracts @i from @v.
- */
-static inline void atomic_sub(int i, atomic_t *v)
-{
-	asm volatile(LOCK_PREFIX "subl %1,%0"
-		     : "=m" (v->counter)
-		     : "ir" (i), "m" (v->counter));
-}
-
-/**
- * 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.
- */
-static inline int atomic_sub_and_test(int i, atomic_t *v)
-{
-	unsigned char c;
-
-	asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
-		     : "=m" (v->counter), "=qm" (c)
-		     : "ir" (i), "m" (v->counter) : "memory");
-	return c;
-}
-
-/**
- * atomic_inc - increment atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically increments @v by 1.
- */
-static inline void atomic_inc(atomic_t *v)
-{
-	asm volatile(LOCK_PREFIX "incl %0"
-		     : "=m" (v->counter)
-		     : "m" (v->counter));
-}
-
-/**
- * atomic_dec - decrement atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically decrements @v by 1.
- */
-static inline void atomic_dec(atomic_t *v)
-{
-	asm volatile(LOCK_PREFIX "decl %0"
-		     : "=m" (v->counter)
-		     : "m" (v->counter));
-}
-
-/**
- * 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.
- */
-static inline int atomic_dec_and_test(atomic_t *v)
-{
-	unsigned char c;
-
-	asm volatile(LOCK_PREFIX "decl %0; sete %1"
-		     : "=m" (v->counter), "=qm" (c)
-		     : "m" (v->counter) : "memory");
-	return c != 0;
-}
-
-/**
- * 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.
- */
-static inline int atomic_inc_and_test(atomic_t *v)
-{
-	unsigned char c;
-
-	asm volatile(LOCK_PREFIX "incl %0; sete %1"
-		     : "=m" (v->counter), "=qm" (c)
-		     : "m" (v->counter) : "memory");
-	return c != 0;
-}
-
-/**
- * atomic_add_negative - add and test if negative
- * @i: integer value to add
- * @v: pointer of type atomic_t
- *
- * Atomically adds @i to @v and returns true
- * if the result is negative, or false when
- * result is greater than or equal to zero.
- */
-static inline int atomic_add_negative(int i, atomic_t *v)
-{
-	unsigned char c;
-
-	asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
-		     : "=m" (v->counter), "=qm" (c)
-		     : "ir" (i), "m" (v->counter) : "memory");
-	return c;
-}
-
-/**
- * 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)
-{
-	int __i = i;
-	asm volatile(LOCK_PREFIX "xaddl %0, %1"
-		     : "+r" (i), "+m" (v->counter)
-		     : : "memory");
-	return i + __i;
-}
-
-static inline int atomic_sub_return(int i, atomic_t *v)
-{
-	return atomic_add_return(-i, v);
-}
-
-#define atomic_inc_return(v)  (atomic_add_return(1, v))
-#define atomic_dec_return(v)  (atomic_sub_return(1, v))
-
-/* The 64-bit atomic type */
-
-#define ATOMIC64_INIT(i)	{ (i) }
-
-/**
- * atomic64_read - read atomic64 variable
- * @v: pointer of type atomic64_t
- *
- * Atomically reads the value of @v.
- * Doesn't imply a read memory barrier.
- */
-static inline long atomic64_read(const atomic64_t *v)
-{
-	return v->counter;
-}
-
-/**
- * atomic64_set - set atomic64 variable
- * @v: pointer to type atomic64_t
- * @i: required value
- *
- * Atomically sets the value of @v to @i.
- */
-static inline void atomic64_set(atomic64_t *v, long i)
-{
-	v->counter = i;
-}
-
-/**
- * atomic64_add - add integer to atomic64 variable
- * @i: integer value to add
- * @v: pointer to type atomic64_t
- *
- * Atomically adds @i to @v.
- */
-static inline void atomic64_add(long i, atomic64_t *v)
-{
-	asm volatile(LOCK_PREFIX "addq %1,%0"
-		     : "=m" (v->counter)
-		     : "er" (i), "m" (v->counter));
-}
-
-/**
- * atomic64_sub - subtract the atomic64 variable
- * @i: integer value to subtract
- * @v: pointer to type atomic64_t
- *
- * Atomically subtracts @i from @v.
- */
-static inline void atomic64_sub(long i, atomic64_t *v)
-{
-	asm volatile(LOCK_PREFIX "subq %1,%0"
-		     : "=m" (v->counter)
-		     : "er" (i), "m" (v->counter));
-}
-
-/**
- * atomic64_sub_and_test - subtract value from variable and test result
- * @i: integer value to subtract
- * @v: pointer to type atomic64_t
- *
- * Atomically subtracts @i from @v and returns
- * true if the result is zero, or false for all
- * other cases.
- */
-static inline int atomic64_sub_and_test(long i, atomic64_t *v)
-{
-	unsigned char c;
-
-	asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
-		     : "=m" (v->counter), "=qm" (c)
-		     : "er" (i), "m" (v->counter) : "memory");
-	return c;
-}
-
-/**
- * atomic64_inc - increment atomic64 variable
- * @v: pointer to type atomic64_t
- *
- * Atomically increments @v by 1.
- */
-static inline void atomic64_inc(atomic64_t *v)
-{
-	asm volatile(LOCK_PREFIX "incq %0"
-		     : "=m" (v->counter)
-		     : "m" (v->counter));
-}
-
-/**
- * atomic64_dec - decrement atomic64 variable
- * @v: pointer to type atomic64_t
- *
- * Atomically decrements @v by 1.
- */
-static inline void atomic64_dec(atomic64_t *v)
-{
-	asm volatile(LOCK_PREFIX "decq %0"
-		     : "=m" (v->counter)
-		     : "m" (v->counter));
-}
-
-/**
- * atomic64_dec_and_test - decrement and test
- * @v: pointer to type atomic64_t
- *
- * Atomically decrements @v by 1 and
- * returns true if the result is 0, or false for all other
- * cases.
- */
-static inline int atomic64_dec_and_test(atomic64_t *v)
-{
-	unsigned char c;
-
-	asm volatile(LOCK_PREFIX "decq %0; sete %1"
-		     : "=m" (v->counter), "=qm" (c)
-		     : "m" (v->counter) : "memory");
-	return c != 0;
-}
-
-/**
- * atomic64_inc_and_test - increment and test
- * @v: pointer to type atomic64_t
- *
- * Atomically increments @v by 1
- * and returns true if the result is zero, or false for all
- * other cases.
- */
-static inline int atomic64_inc_and_test(atomic64_t *v)
-{
-	unsigned char c;
-
-	asm volatile(LOCK_PREFIX "incq %0; sete %1"
-		     : "=m" (v->counter), "=qm" (c)
-		     : "m" (v->counter) : "memory");
-	return c != 0;
-}
-
-/**
- * atomic64_add_negative - add and test if negative
- * @i: integer value to add
- * @v: pointer to type atomic64_t
- *
- * Atomically adds @i to @v and returns true
- * if the result is negative, or false when
- * result is greater than or equal to zero.
- */
-static inline int atomic64_add_negative(long i, atomic64_t *v)
-{
-	unsigned char c;
-
-	asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
-		     : "=m" (v->counter), "=qm" (c)
-		     : "er" (i), "m" (v->counter) : "memory");
-	return c;
-}
-
-/**
- * atomic64_add_return - add and return
- * @i: integer value to add
- * @v: pointer to type atomic64_t
- *
- * Atomically adds @i to @v and returns @i + @v
- */
-static inline long atomic64_add_return(long i, atomic64_t *v)
-{
-	long __i = i;
-	asm volatile(LOCK_PREFIX "xaddq %0, %1;"
-		     : "+r" (i), "+m" (v->counter)
-		     : : "memory");
-	return i + __i;
-}
-
-static inline long atomic64_sub_return(long i, atomic64_t *v)
-{
-	return atomic64_add_return(-i, v);
-}
-
-#define atomic64_inc_return(v)  (atomic64_add_return(1, (v)))
-#define atomic64_dec_return(v)  (atomic64_sub_return(1, (v)))
-
-static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new)
-{
-	return cmpxchg(&v->counter, old, new);
-}
-
-static inline long atomic64_xchg(atomic64_t *v, long new)
-{
-	return xchg(&v->counter, new);
-}
-
-static inline long atomic_cmpxchg(atomic_t *v, int old, int new)
-{
-	return cmpxchg(&v->counter, old, new);
-}
-
-static inline long atomic_xchg(atomic_t *v, int new)
-{
-	return 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)
-
-/**
- * atomic64_add_unless - add unless the number is a given value
- * @v: pointer of type atomic64_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 atomic64_add_unless(atomic64_t *v, long a, long u)
-{
-	long c, old;
-	c = atomic64_read(v);
-	for (;;) {
-		if (unlikely(c == (u)))
-			break;
-		old = atomic64_cmpxchg((v), c, c + (a));
-		if (likely(old == c))
-			break;
-		c = old;
-	}
-	return c != (u);
-}
-
-/**
- * atomic_inc_short - increment of a short integer
- * @v: pointer to type int
- *
- * Atomically adds 1 to @v
- * Returns the new value of @u
- */
-static inline short int atomic_inc_short(short int *v)
-{
-	asm(LOCK_PREFIX "addw $1, %0" : "+m" (*v));
-	return *v;
-}
-
-/**
- * atomic_or_long - OR of two long integers
- * @v1: pointer to type unsigned long
- * @v2: pointer to type unsigned long
- *
- * Atomically ORs @v1 and @v2
- * Returns the result of the OR
- */
-static inline void atomic_or_long(unsigned long *v1, unsigned long v2)
-{
-	asm(LOCK_PREFIX "orq %1, %0" : "+m" (*v1) : "r" (v2));
-}
-
-#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
-
-/* These are x86-specific, used by some header files */
-#define atomic_clear_mask(mask, addr)					\
-	asm volatile(LOCK_PREFIX "andl %0,%1"				\
-		     : : "r" (~(mask)), "m" (*(addr)) : "memory")
-
-#define atomic_set_mask(mask, addr)					\
-	asm volatile(LOCK_PREFIX "orl %0,%1"				\
-		     : : "r" ((unsigned)(mask)), "m" (*(addr))		\
-		     : "memory")
-
-/* Atomic operations are already serializing on x86 */
-#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-long.h>
-#endif /* _ASM_X86_ATOMIC_64_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/atomic.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/atomic.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/atomic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/atomic.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,300 @@
+#ifndef _ASM_X86_ATOMIC_H
+#define _ASM_X86_ATOMIC_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <asm/processor.h>
+#include <asm/alternative.h>
+#include <asm/cmpxchg.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.
+ */
+static inline int atomic_read(const atomic_t *v)
+{
+	return v->counter;
+}
+
+/**
+ * atomic_set - set atomic variable
+ * @v: pointer of type atomic_t
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i.
+ */
+static inline void atomic_set(atomic_t *v, int i)
+{
+	v->counter = i;
+}
+
+/**
+ * atomic_add - add integer to atomic variable
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v.
+ */
+static inline void atomic_add(int i, atomic_t *v)
+{
+	asm volatile(LOCK_PREFIX "addl %1,%0"
+		     : "+m" (v->counter)
+		     : "ir" (i));
+}
+
+/**
+ * atomic_sub - subtract integer from atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v.
+ */
+static inline void atomic_sub(int i, atomic_t *v)
+{
+	asm volatile(LOCK_PREFIX "subl %1,%0"
+		     : "+m" (v->counter)
+		     : "ir" (i));
+}
+
+/**
+ * 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.
+ */
+static inline int atomic_sub_and_test(int i, atomic_t *v)
+{
+	unsigned char c;
+
+	asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
+		     : "+m" (v->counter), "=qm" (c)
+		     : "ir" (i) : "memory");
+	return c;
+}
+
+/**
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1.
+ */
+static inline void atomic_inc(atomic_t *v)
+{
+	asm volatile(LOCK_PREFIX "incl %0"
+		     : "+m" (v->counter));
+}
+
+/**
+ * atomic_dec - decrement atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1.
+ */
+static inline void atomic_dec(atomic_t *v)
+{
+	asm volatile(LOCK_PREFIX "decl %0"
+		     : "+m" (v->counter));
+}
+
+/**
+ * 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.
+ */
+static inline int atomic_dec_and_test(atomic_t *v)
+{
+	unsigned char c;
+
+	asm volatile(LOCK_PREFIX "decl %0; sete %1"
+		     : "+m" (v->counter), "=qm" (c)
+		     : : "memory");
+	return c != 0;
+}
+
+/**
+ * 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.
+ */
+static inline int atomic_inc_and_test(atomic_t *v)
+{
+	unsigned char c;
+
+	asm volatile(LOCK_PREFIX "incl %0; sete %1"
+		     : "+m" (v->counter), "=qm" (c)
+		     : : "memory");
+	return c != 0;
+}
+
+/**
+ * atomic_add_negative - add and test if negative
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+static inline int atomic_add_negative(int i, atomic_t *v)
+{
+	unsigned char c;
+
+	asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
+		     : "+m" (v->counter), "=qm" (c)
+		     : "ir" (i) : "memory");
+	return c;
+}
+
+/**
+ * atomic_add_return - add integer 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)
+{
+	int __i;
+#ifdef CONFIG_M386
+	unsigned long flags;
+	if (unlikely(boot_cpu_data.x86 <= 3))
+		goto no_xadd;
+#endif
+	/* Modern 486+ processor */
+	__i = i;
+	asm volatile(LOCK_PREFIX "xaddl %0, %1"
+		     : "+r" (i), "+m" (v->counter)
+		     : : "memory");
+	return i + __i;
+
+#ifdef CONFIG_M386
+no_xadd: /* Legacy 386 processor */
+	raw_local_irq_save(flags);
+	__i = atomic_read(v);
+	atomic_set(v, i + __i);
+	raw_local_irq_restore(flags);
+	return i + __i;
+#endif
+}
+
+/**
+ * atomic_sub_return - subtract integer and return
+ * @v: pointer of type atomic_t
+ * @i: integer value to subtract
+ *
+ * Atomically subtracts @i from @v and returns @v - @i
+ */
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+	return atomic_add_return(-i, v);
+}
+
+#define atomic_inc_return(v)  (atomic_add_return(1, v))
+#define atomic_dec_return(v)  (atomic_sub_return(1, v))
+
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+	return cmpxchg(&v->counter, old, new);
+}
+
+static inline int atomic_xchg(atomic_t *v, int new)
+{
+	return xchg(&v->counter, new);
+}
+
+/**
+ * atomic_add_unless - add unless the number is already 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 @v was not already @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)
+
+/**
+ * atomic_inc_short - increment of a short integer
+ * @v: pointer to type int
+ *
+ * Atomically adds 1 to @v
+ * Returns the new value of @u
+ */
+static inline short int atomic_inc_short(short int *v)
+{
+	asm(LOCK_PREFIX "addw $1, %0" : "+m" (*v));
+	return *v;
+}
+
+#ifdef CONFIG_X86_64
+/**
+ * atomic_or_long - OR of two long integers
+ * @v1: pointer to type unsigned long
+ * @v2: pointer to type unsigned long
+ *
+ * Atomically ORs @v1 and @v2
+ * Returns the result of the OR
+ */
+static inline void atomic_or_long(unsigned long *v1, unsigned long v2)
+{
+	asm(LOCK_PREFIX "orq %1, %0" : "+m" (*v1) : "r" (v2));
+}
+#endif
+
+/* These are x86-specific, used by some header files */
+#define atomic_clear_mask(mask, addr)				\
+	asm volatile(LOCK_PREFIX "andl %0,%1"			\
+		     : : "r" (~(mask)), "m" (*(addr)) : "memory")
+
+#define atomic_set_mask(mask, addr)				\
+	asm volatile(LOCK_PREFIX "orl %0,%1"			\
+		     : : "r" ((unsigned)(mask)), "m" (*(addr))	\
+		     : "memory")
+
+/* Atomic operations are already serializing on x86 */
+#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()
+
 #ifdef CONFIG_X86_32
-# include "atomic_32.h"
+# include "atomic64_32.h"
 #else
-# include "atomic_64.h"
+# include "atomic64_64.h"
 #endif
+
+#include <asm-generic/atomic-long.h>
+#endif /* _ASM_X86_ATOMIC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/compat.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/compat.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/compat.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/compat.h	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,8 @@
 #include <linux/sched.h>
 #include <asm/user32.h>
 
-#define COMPAT_USER_HZ	100
+#define COMPAT_USER_HZ		100
+#define COMPAT_UTS_MACHINE	"i686\0\0"
 
 typedef u32		compat_size_t;
 typedef s32		compat_ssize_t;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/cpufeature.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/cpufeature.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/cpufeature.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/cpufeature.h	2010-05-16 17:17:36.000000000 -0400
@@ -168,6 +168,10 @@
 #define X86_FEATURE_FLEXPRIORITY (8*32+ 2) /* Intel FlexPriority */
 #define X86_FEATURE_EPT         (8*32+ 3) /* Intel Extended Page Table */
 #define X86_FEATURE_VPID        (8*32+ 4) /* Intel Virtual Processor ID */
+#define X86_FEATURE_NPT		(8*32+5)  /* AMD Nested Page Table support */
+#define X86_FEATURE_LBRV	(8*32+6)  /* AMD LBR Virtualization support */
+#define X86_FEATURE_SVML	(8*32+7)  /* "svm_lock" AMD SVM locking MSR */
+#define X86_FEATURE_NRIPS	(8*32+8)  /* "nrip_save" AMD SVM next_rip save */
 
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/debugreg.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/debugreg.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/debugreg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/debugreg.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,9 @@
    which debugging register was responsible for the trap.  The other bits
    are either reserved or not of interest to us. */
 
+/* Define reserved bits in DR6 which are always set to 1 */
+#define DR6_RESERVED	(0xFFFF0FF0)
+
 #define DR_TRAP0	(0x1)		/* db0 */
 #define DR_TRAP1	(0x2)		/* db1 */
 #define DR_TRAP2	(0x4)		/* db2 */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/e820.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/e820.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/e820.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/e820.h	2010-05-16 17:17:36.000000000 -0400
@@ -111,11 +111,8 @@ extern unsigned long end_user_pfn;
 
 extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align);
 extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align);
-extern void reserve_early(u64 start, u64 end, char *name);
-extern void reserve_early_overlap_ok(u64 start, u64 end, char *name);
-extern void free_early(u64 start, u64 end);
-extern void early_res_to_bootmem(u64 start, u64 end);
 extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
+#include <linux/early_res.h>
 
 extern unsigned long e820_end_of_ram_pfn(void);
 extern unsigned long e820_end_of_low_ram_pfn(void);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/fb.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/fb.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/fb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/fb.h	2010-05-16 17:17:36.000000000 -0400
@@ -12,10 +12,6 @@ static inline void fb_pgprotect(struct f
 		pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
 }
 
-#ifdef CONFIG_X86_32
 extern int fb_is_primary_device(struct fb_info *info);
-#else
-static inline int fb_is_primary_device(struct fb_info *info) { return 0; }
-#endif
 
 #endif /* _ASM_X86_FB_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/fixmap.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/fixmap.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/fixmap.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/fixmap.h	2010-05-16 17:17:36.000000000 -0400
@@ -82,6 +82,9 @@ enum fixed_addresses {
 #endif
 	FIX_DBGP_BASE,
 	FIX_EARLYCON_MEM_BASE,
+#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
+	FIX_OHCI1394_BASE,
+#endif
 #ifdef CONFIG_X86_LOCAL_APIC
 	FIX_APIC_BASE,	/* local (CPU) APIC) -- required for SMP or not */
 #endif
@@ -118,17 +121,20 @@ enum 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:
+	 * If necessary 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_PROVIDE_OHCI1394_DMA_INIT
-	FIX_OHCI1394_BASE,
-#endif
+#define TOTAL_FIX_BTMAPS	(NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
+	FIX_BTMAP_END =
+	 (__end_of_permanent_fixed_addresses ^
+	  (__end_of_permanent_fixed_addresses + TOTAL_FIX_BTMAPS - 1)) &
+	 -PTRS_PER_PTE
+	 ? __end_of_permanent_fixed_addresses + TOTAL_FIX_BTMAPS -
+	   (__end_of_permanent_fixed_addresses & (TOTAL_FIX_BTMAPS - 1))
+	 : __end_of_permanent_fixed_addresses,
+	FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1,
 #ifdef CONFIG_X86_32
 	FIX_WP_TEST,
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/highmem.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/highmem.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/highmem.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/highmem.h	2010-05-16 17:17:36.000000000 -0400
@@ -66,10 +66,6 @@ void *kmap_atomic_pfn(unsigned long pfn,
 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
-#define kmap_atomic_pte(page, type)	kmap_atomic(page, type)
-#endif
-
 #define flush_cache_kmaps()	do { } while (0)
 
 extern void add_highpages_with_active_regions(int nid, unsigned long start_pfn,
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/hw_breakpoint.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/hw_breakpoint.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/hw_breakpoint.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/hw_breakpoint.h	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
  * (display/resolving)
  */
 struct arch_hw_breakpoint {
-	char		*name; /* Contains name of the symbol to set bkpt */
 	unsigned long	address;
 	u8		len;
 	u8		type;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/hw_irq.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/hw_irq.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/hw_irq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/hw_irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -53,13 +53,6 @@ extern void threshold_interrupt(void);
 extern void call_function_interrupt(void);
 extern void call_function_single_interrupt(void);
 
-/* PIC specific functions */
-extern void disable_8259A_irq(unsigned int irq);
-extern void enable_8259A_irq(unsigned int irq);
-extern int i8259A_irq_pending(unsigned int irq);
-extern void make_8259A_irq(unsigned int irq);
-extern void init_8259A(int aeoi);
-
 /* IOAPIC */
 #define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs))
 extern unsigned long io_apic_irqs;
@@ -140,6 +133,7 @@ extern void (*__initconst interrupt[NR_V
 
 typedef int vector_irq_t[NR_VECTORS];
 DECLARE_PER_CPU(vector_irq_t, vector_irq);
+extern void setup_vector_irq(int cpu);
 
 #ifdef CONFIG_X86_IO_APIC
 extern void lock_vector_lock(void);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/hyperv.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/hyperv.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/hyperv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/hyperv.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,186 @@
+#ifndef _ASM_X86_KVM_HYPERV_H
+#define _ASM_X86_KVM_HYPERV_H
+
+#include <linux/types.h>
+
+/*
+ * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
+ * is set by CPUID(HvCpuIdFunctionVersionAndFeatures).
+ */
+#define HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS	0x40000000
+#define HYPERV_CPUID_INTERFACE			0x40000001
+#define HYPERV_CPUID_VERSION			0x40000002
+#define HYPERV_CPUID_FEATURES			0x40000003
+#define HYPERV_CPUID_ENLIGHTMENT_INFO		0x40000004
+#define HYPERV_CPUID_IMPLEMENT_LIMITS		0x40000005
+
+/*
+ * Feature identification. EAX indicates which features are available
+ * to the partition based upon the current partition privileges.
+ */
+
+/* VP Runtime (HV_X64_MSR_VP_RUNTIME) available */
+#define HV_X64_MSR_VP_RUNTIME_AVAILABLE		(1 << 0)
+/* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/
+#define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE	(1 << 1)
+/*
+ * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM
+ * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available
+ */
+#define HV_X64_MSR_SYNIC_AVAILABLE		(1 << 2)
+/*
+ * Synthetic Timer MSRs (HV_X64_MSR_STIMER0_CONFIG through
+ * HV_X64_MSR_STIMER3_COUNT) available
+ */
+#define HV_X64_MSR_SYNTIMER_AVAILABLE		(1 << 3)
+/*
+ * APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR)
+ * are available
+ */
+#define HV_X64_MSR_APIC_ACCESS_AVAILABLE	(1 << 4)
+/* Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL) available*/
+#define HV_X64_MSR_HYPERCALL_AVAILABLE		(1 << 5)
+/* Access virtual processor index MSR (HV_X64_MSR_VP_INDEX) available*/
+#define HV_X64_MSR_VP_INDEX_AVAILABLE		(1 << 6)
+/* Virtual system reset MSR (HV_X64_MSR_RESET) is available*/
+#define HV_X64_MSR_RESET_AVAILABLE		(1 << 7)
+ /*
+  * Access statistics pages MSRs (HV_X64_MSR_STATS_PARTITION_RETAIL_PAGE,
+  * HV_X64_MSR_STATS_PARTITION_INTERNAL_PAGE, HV_X64_MSR_STATS_VP_RETAIL_PAGE,
+  * HV_X64_MSR_STATS_VP_INTERNAL_PAGE) available
+  */
+#define HV_X64_MSR_STAT_PAGES_AVAILABLE		(1 << 8)
+
+/*
+ * Feature identification: EBX indicates which flags were specified at
+ * partition creation. The format is the same as the partition creation
+ * flag structure defined in section Partition Creation Flags.
+ */
+#define HV_X64_CREATE_PARTITIONS		(1 << 0)
+#define HV_X64_ACCESS_PARTITION_ID		(1 << 1)
+#define HV_X64_ACCESS_MEMORY_POOL		(1 << 2)
+#define HV_X64_ADJUST_MESSAGE_BUFFERS		(1 << 3)
+#define HV_X64_POST_MESSAGES			(1 << 4)
+#define HV_X64_SIGNAL_EVENTS			(1 << 5)
+#define HV_X64_CREATE_PORT			(1 << 6)
+#define HV_X64_CONNECT_PORT			(1 << 7)
+#define HV_X64_ACCESS_STATS			(1 << 8)
+#define HV_X64_DEBUGGING			(1 << 11)
+#define HV_X64_CPU_POWER_MANAGEMENT		(1 << 12)
+#define HV_X64_CONFIGURE_PROFILER		(1 << 13)
+
+/*
+ * Feature identification. EDX indicates which miscellaneous features
+ * are available to the partition.
+ */
+/* The MWAIT instruction is available (per section MONITOR / MWAIT) */
+#define HV_X64_MWAIT_AVAILABLE				(1 << 0)
+/* Guest debugging support is available */
+#define HV_X64_GUEST_DEBUGGING_AVAILABLE		(1 << 1)
+/* Performance Monitor support is available*/
+#define HV_X64_PERF_MONITOR_AVAILABLE			(1 << 2)
+/* Support for physical CPU dynamic partitioning events is available*/
+#define HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE	(1 << 3)
+/*
+ * Support for passing hypercall input parameter block via XMM
+ * registers is available
+ */
+#define HV_X64_HYPERCALL_PARAMS_XMM_AVAILABLE		(1 << 4)
+/* Support for a virtual guest idle state is available */
+#define HV_X64_GUEST_IDLE_STATE_AVAILABLE		(1 << 5)
+
+/*
+ * Implementation recommendations. Indicates which behaviors the hypervisor
+ * recommends the OS implement for optimal performance.
+ */
+ /*
+  * Recommend using hypercall for address space switches rather
+  * than MOV to CR3 instruction
+  */
+#define HV_X64_MWAIT_RECOMMENDED		(1 << 0)
+/* Recommend using hypercall for local TLB flushes rather
+ * than INVLPG or MOV to CR3 instructions */
+#define HV_X64_LOCAL_TLB_FLUSH_RECOMMENDED	(1 << 1)
+/*
+ * Recommend using hypercall for remote TLB flushes rather
+ * than inter-processor interrupts
+ */
+#define HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED	(1 << 2)
+/*
+ * Recommend using MSRs for accessing APIC registers
+ * EOI, ICR and TPR rather than their memory-mapped counterparts
+ */
+#define HV_X64_APIC_ACCESS_RECOMMENDED		(1 << 3)
+/* Recommend using the hypervisor-provided MSR to initiate a system RESET */
+#define HV_X64_SYSTEM_RESET_RECOMMENDED		(1 << 4)
+/*
+ * Recommend using relaxed timing for this partition. If used,
+ * the VM should disable any watchdog timeouts that rely on the
+ * timely delivery of external interrupts
+ */
+#define HV_X64_RELAXED_TIMING_RECOMMENDED	(1 << 5)
+
+/* MSR used to identify the guest OS. */
+#define HV_X64_MSR_GUEST_OS_ID			0x40000000
+
+/* MSR used to setup pages used to communicate with the hypervisor. */
+#define HV_X64_MSR_HYPERCALL			0x40000001
+
+/* MSR used to provide vcpu index */
+#define HV_X64_MSR_VP_INDEX			0x40000002
+
+/* Define the virtual APIC registers */
+#define HV_X64_MSR_EOI				0x40000070
+#define HV_X64_MSR_ICR				0x40000071
+#define HV_X64_MSR_TPR				0x40000072
+#define HV_X64_MSR_APIC_ASSIST_PAGE		0x40000073
+
+/* Define synthetic interrupt controller model specific registers. */
+#define HV_X64_MSR_SCONTROL			0x40000080
+#define HV_X64_MSR_SVERSION			0x40000081
+#define HV_X64_MSR_SIEFP			0x40000082
+#define HV_X64_MSR_SIMP				0x40000083
+#define HV_X64_MSR_EOM				0x40000084
+#define HV_X64_MSR_SINT0			0x40000090
+#define HV_X64_MSR_SINT1			0x40000091
+#define HV_X64_MSR_SINT2			0x40000092
+#define HV_X64_MSR_SINT3			0x40000093
+#define HV_X64_MSR_SINT4			0x40000094
+#define HV_X64_MSR_SINT5			0x40000095
+#define HV_X64_MSR_SINT6			0x40000096
+#define HV_X64_MSR_SINT7			0x40000097
+#define HV_X64_MSR_SINT8			0x40000098
+#define HV_X64_MSR_SINT9			0x40000099
+#define HV_X64_MSR_SINT10			0x4000009A
+#define HV_X64_MSR_SINT11			0x4000009B
+#define HV_X64_MSR_SINT12			0x4000009C
+#define HV_X64_MSR_SINT13			0x4000009D
+#define HV_X64_MSR_SINT14			0x4000009E
+#define HV_X64_MSR_SINT15			0x4000009F
+
+
+#define HV_X64_MSR_HYPERCALL_ENABLE		0x00000001
+#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT	12
+#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK	\
+		(~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
+
+/* Declare the various hypercall operations. */
+#define HV_X64_HV_NOTIFY_LONG_SPIN_WAIT		0x0008
+
+#define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE		0x00000001
+#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT	12
+#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_MASK	\
+		(~((1ull << HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT) - 1))
+
+#define HV_PROCESSOR_POWER_STATE_C0		0
+#define HV_PROCESSOR_POWER_STATE_C1		1
+#define HV_PROCESSOR_POWER_STATE_C2		2
+#define HV_PROCESSOR_POWER_STATE_C3		3
+
+/* hypercall status code */
+#define HV_STATUS_SUCCESS			0
+#define HV_STATUS_INVALID_HYPERCALL_CODE	2
+#define HV_STATUS_INVALID_HYPERCALL_INPUT	3
+#define HV_STATUS_INVALID_ALIGNMENT		4
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/i387.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/i387.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/i387.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/i387.h	2010-05-16 17:17:36.000000000 -0400
@@ -33,8 +33,16 @@ extern void init_thread_xstate(void);
 extern int dump_fpu(struct pt_regs *, struct user_i387_struct *);
 
 extern user_regset_active_fn fpregs_active, xfpregs_active;
-extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get;
-extern user_regset_set_fn fpregs_set, xfpregs_set, fpregs_soft_set;
+extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get,
+				xstateregs_get;
+extern user_regset_set_fn fpregs_set, xfpregs_set, fpregs_soft_set,
+				 xstateregs_set;
+
+/*
+ * xstateregs_active == fpregs_active. Please refer to the comment
+ * at the definition of fpregs_active.
+ */
+#define xstateregs_active	fpregs_active
 
 extern struct _fpx_sw_bytes fx_sw_reserved;
 #ifdef CONFIG_IA32_EMULATION
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/i8259.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/i8259.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/i8259.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/i8259.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,12 +24,7 @@ extern unsigned int cached_irq_mask;
 #define SLAVE_ICW4_DEFAULT	0x01
 #define PIC_ICW4_AEOI		2
 
-extern spinlock_t i8259A_lock;
-
-extern void init_8259A(int auto_eoi);
-extern void enable_8259A_irq(unsigned int irq);
-extern void disable_8259A_irq(unsigned int irq);
-extern unsigned int startup_8259A_irq(unsigned int irq);
+extern raw_spinlock_t i8259A_lock;
 
 /* the PIC may need a careful delay on some platforms, hence specific calls */
 static inline unsigned char inb_pic(unsigned int port)
@@ -57,7 +52,17 @@ static inline void outb_pic(unsigned cha
 
 extern struct irq_chip i8259A_chip;
 
-extern void mask_8259A(void);
-extern void unmask_8259A(void);
+struct legacy_pic {
+	int nr_legacy_irqs;
+	struct irq_chip *chip;
+	void (*mask_all)(void);
+	void (*restore_mask)(void);
+	void (*init)(int auto_eoi);
+	int (*irq_pending)(unsigned int irq);
+	void (*make_irq)(unsigned int irq);
+};
+
+extern struct legacy_pic *legacy_pic;
+extern struct legacy_pic null_legacy_pic;
 
 #endif /* _ASM_X86_I8259_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/io_32.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/io_32.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/io_32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/io_32.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,196 +0,0 @@
-#ifndef _ASM_X86_IO_32_H
-#define _ASM_X86_IO_32_H
-
-#include <linux/string.h>
-#include <linux/compiler.h>
-
-/*
- * This file contains the definitions for the x86 IO instructions
- * inb/inw/inl/outb/outw/outl and the "string versions" of the same
- * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
- * versions of the single-IO instructions (inb_p/inw_p/..).
- *
- * This file is not meant to be obfuscating: it's just complicated
- * to (a) handle it all in a way that makes gcc able to optimize it
- * as well as possible and (b) trying to avoid writing the same thing
- * over and over again with slight variations and possibly making a
- * mistake somewhere.
- */
-
-/*
- * Thanks to James van Artsdalen for a better timing-fix than
- * the two short jumps: using outb's to a nonexistent port seems
- * to guarantee better timings even on fast machines.
- *
- * On the other hand, I'd like to be sure of a non-existent port:
- * I feel a bit unsafe about using 0x80 (should be safe, though)
- *
- *		Linus
- */
-
- /*
-  *  Bit simplified and optimized by Jan Hubicka
-  *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999.
-  *
-  *  isa_memset_io, isa_memcpy_fromio, isa_memcpy_toio added,
-  *  isa_read[wl] and isa_write[wl] fixed
-  *  - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-  */
-
-#define XQUAD_PORTIO_BASE 0xfe400000
-#define XQUAD_PORTIO_QUAD 0x40000  /* 256k per quad. */
-
-#ifdef __KERNEL__
-
-#include <asm-generic/iomap.h>
-
-#include <linux/vmalloc.h>
-
-/*
- * Convert a virtual cached pointer to an uncached pointer
- */
-#define xlate_dev_kmem_ptr(p)	p
-
-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, (const void __force *)src, count);
-}
-
-static inline void
-memcpy_toio(volatile void __iomem *dst, const void *src, int count)
-{
-	__memcpy((void __force *)dst, src, count);
-}
-
-/*
- * ISA space is 'always mapped' on a typical x86 system, no need to
- * explicitly ioremap() it. The fact that the ISA IO space is mapped
- * to PAGE_OFFSET is pure coincidence - it does not mean ISA values
- * are physical addresses. The following constant pointer can be
- * used as the IO-area pointer (it can be iounmapped as well, so the
- * analogy with PCI is quite large):
- */
-#define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET))
-
-/*
- *	Cache management
- *
- *	This needed for two cases
- *	1. Out of order aware processors
- *	2. Accidentally out of order processors (PPro errata #51)
- */
-
-#if defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)
-
-static inline void flush_write_buffers(void)
-{
-	asm volatile("lock; addl $0,0(%%esp)": : :"memory");
-}
-
-#else
-
-#define flush_write_buffers() do { } while (0)
-
-#endif
-
-#endif /* __KERNEL__ */
-
-extern void native_io_delay(void);
-
-extern int io_delay_type;
-extern void io_delay_init(void);
-
-#if defined(CONFIG_PARAVIRT)
-#include <asm/paravirt.h>
-#else
-
-static inline void slow_down_io(void)
-{
-	native_io_delay();
-#ifdef REALLY_SLOW_IO
-	native_io_delay();
-	native_io_delay();
-	native_io_delay();
-#endif
-}
-
-#endif
-
-#define __BUILDIO(bwl, bw, type)				\
-static inline void out##bwl(unsigned type value, int port)	\
-{								\
-	out##bwl##_local(value, port);				\
-}								\
-								\
-static inline unsigned type in##bwl(int port)			\
-{								\
-	return in##bwl##_local(port);				\
-}
-
-#define BUILDIO(bwl, bw, type)						\
-static inline void out##bwl##_local(unsigned type value, int port)	\
-{									\
-	asm volatile("out" #bwl " %" #bw "0, %w1"		\
-		     : : "a"(value), "Nd"(port));			\
-}									\
-									\
-static inline unsigned type in##bwl##_local(int port)			\
-{									\
-	unsigned type value;						\
-	asm volatile("in" #bwl " %w1, %" #bw "0"		\
-		     : "=a"(value) : "Nd"(port));			\
-	return value;							\
-}									\
-									\
-static inline void out##bwl##_local_p(unsigned type value, int port)	\
-{									\
-	out##bwl##_local(value, port);					\
-	slow_down_io();							\
-}									\
-									\
-static inline unsigned type in##bwl##_local_p(int port)			\
-{									\
-	unsigned type value = in##bwl##_local(port);			\
-	slow_down_io();							\
-	return value;							\
-}									\
-									\
-__BUILDIO(bwl, bw, type)						\
-									\
-static inline void out##bwl##_p(unsigned type value, int port)		\
-{									\
-	out##bwl(value, port);						\
-	slow_down_io();							\
-}									\
-									\
-static inline unsigned type in##bwl##_p(int port)			\
-{									\
-	unsigned type value = in##bwl(port);				\
-	slow_down_io();							\
-	return value;							\
-}									\
-									\
-static inline void outs##bwl(int port, const void *addr, unsigned long count) \
-{									\
-	asm volatile("rep; outs" #bwl					\
-		     : "+S"(addr), "+c"(count) : "d"(port));		\
-}									\
-									\
-static inline void ins##bwl(int port, void *addr, unsigned long count)	\
-{									\
-	asm volatile("rep; ins" #bwl					\
-		     : "+D"(addr), "+c"(count) : "d"(port));		\
-}
-
-BUILDIO(b, b, char)
-BUILDIO(w, w, short)
-BUILDIO(l, , int)
-
-#endif /* _ASM_X86_IO_32_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/io_64.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/io_64.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/io_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/io_64.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,181 +0,0 @@
-#ifndef _ASM_X86_IO_64_H
-#define _ASM_X86_IO_64_H
-
-
-/*
- * This file contains the definitions for the x86 IO instructions
- * inb/inw/inl/outb/outw/outl and the "string versions" of the same
- * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
- * versions of the single-IO instructions (inb_p/inw_p/..).
- *
- * This file is not meant to be obfuscating: it's just complicated
- * to (a) handle it all in a way that makes gcc able to optimize it
- * as well as possible and (b) trying to avoid writing the same thing
- * over and over again with slight variations and possibly making a
- * mistake somewhere.
- */
-
-/*
- * Thanks to James van Artsdalen for a better timing-fix than
- * the two short jumps: using outb's to a nonexistent port seems
- * to guarantee better timings even on fast machines.
- *
- * On the other hand, I'd like to be sure of a non-existent port:
- * I feel a bit unsafe about using 0x80 (should be safe, though)
- *
- *		Linus
- */
-
- /*
-  *  Bit simplified and optimized by Jan Hubicka
-  *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999.
-  *
-  *  isa_memset_io, isa_memcpy_fromio, isa_memcpy_toio added,
-  *  isa_read[wl] and isa_write[wl] fixed
-  *  - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-  */
-
-extern void native_io_delay(void);
-
-extern int io_delay_type;
-extern void io_delay_init(void);
-
-#if defined(CONFIG_PARAVIRT)
-#include <asm/paravirt.h>
-#else
-
-static inline void slow_down_io(void)
-{
-	native_io_delay();
-#ifdef REALLY_SLOW_IO
-	native_io_delay();
-	native_io_delay();
-	native_io_delay();
-#endif
-}
-#endif
-
-/*
- * Talk about misusing macros..
- */
-#define __OUT1(s, x)							\
-static inline void out##s(unsigned x value, unsigned short port) {
-
-#define __OUT2(s, s1, s2)				\
-asm volatile ("out" #s " %" s1 "0,%" s2 "1"
-
-#ifndef REALLY_SLOW_IO
-#define REALLY_SLOW_IO
-#define UNSET_REALLY_SLOW_IO
-#endif
-
-#define __OUT(s, s1, x)							\
-	__OUT1(s, x) __OUT2(s, s1, "w") : : "a" (value), "Nd" (port));	\
-	}								\
-	__OUT1(s##_p, x) __OUT2(s, s1, "w") : : "a" (value), "Nd" (port)); \
-	slow_down_io();							\
-}
-
-#define __IN1(s)							\
-static inline RETURN_TYPE in##s(unsigned short port)			\
-{									\
-	RETURN_TYPE _v;
-
-#define __IN2(s, s1, s2)						\
-	asm volatile ("in" #s " %" s2 "1,%" s1 "0"
-
-#define __IN(s, s1, i...)						\
-	__IN1(s) __IN2(s, s1, "w") : "=a" (_v) : "Nd" (port), ##i);	\
-	return _v;							\
-	}								\
-	__IN1(s##_p) __IN2(s, s1, "w") : "=a" (_v) : "Nd" (port), ##i);	\
-	slow_down_io(); \
-	return _v; }
-
-#ifdef UNSET_REALLY_SLOW_IO
-#undef REALLY_SLOW_IO
-#endif
-
-#define __INS(s)							\
-static inline void ins##s(unsigned short port, void *addr,		\
-			  unsigned long count)				\
-{									\
-	asm volatile ("rep ; ins" #s					\
-		      : "=D" (addr), "=c" (count)			\
-		      : "d" (port), "0" (addr), "1" (count));		\
-}
-
-#define __OUTS(s)							\
-static inline void outs##s(unsigned short port, const void *addr,	\
-			   unsigned long count)				\
-{									\
-	asm volatile ("rep ; outs" #s					\
-		      : "=S" (addr), "=c" (count)			\
-		      : "d" (port), "0" (addr), "1" (count));		\
-}
-
-#define RETURN_TYPE unsigned char
-__IN(b, "")
-#undef RETURN_TYPE
-#define RETURN_TYPE unsigned short
-__IN(w, "")
-#undef RETURN_TYPE
-#define RETURN_TYPE unsigned int
-__IN(l, "")
-#undef RETURN_TYPE
-
-__OUT(b, "b", char)
-__OUT(w, "w", short)
-__OUT(l, , int)
-
-__INS(b)
-__INS(w)
-__INS(l)
-
-__OUTS(b)
-__OUTS(w)
-__OUTS(l)
-
-#if defined(__KERNEL__) && defined(__x86_64__)
-
-#include <linux/vmalloc.h>
-
-#include <asm-generic/iomap.h>
-
-void __memcpy_fromio(void *, unsigned long, unsigned);
-void __memcpy_toio(unsigned long, const void *, unsigned);
-
-static inline void memcpy_fromio(void *to, const volatile void __iomem *from,
-				 unsigned len)
-{
-	__memcpy_fromio(to, (unsigned long)from, len);
-}
-
-static inline void memcpy_toio(volatile void __iomem *to, const void *from,
-			       unsigned len)
-{
-	__memcpy_toio((unsigned long)to, from, len);
-}
-
-void memset_io(volatile void __iomem *a, int b, size_t c);
-
-/*
- * ISA space is 'always mapped' on a typical x86 system, no need to
- * explicitly ioremap() it. The fact that the ISA IO space is mapped
- * to PAGE_OFFSET is pure coincidence - it does not mean ISA values
- * are physical addresses. The following constant pointer can be
- * used as the IO-area pointer (it can be iounmapped as well, so the
- * analogy with PCI is quite large):
- */
-#define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET))
-
-#define flush_write_buffers()
-
-/*
- * Convert a virtual cached pointer to an uncached pointer
- */
-#define xlate_dev_kmem_ptr(p)	p
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_X86_IO_64_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/io_apic.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/io_apic.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/io_apic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/io_apic.h	2010-05-16 17:17:36.000000000 -0400
@@ -143,8 +143,6 @@ extern int noioapicreroute;
 /* 1 if the timer IRQ uses the '8259A Virtual Wire' mode */
 extern int timer_through_8259;
 
-extern void io_apic_disable_legacy(void);
-
 /*
  * If we use the IO-APIC for IRQ routing, disable automatic
  * assignment of PCI IRQ's.
@@ -160,6 +158,7 @@ extern int io_apic_get_redir_entries(int
 struct io_apic_irq_attr;
 extern int io_apic_set_pci_routing(struct device *dev, int irq,
 		 struct io_apic_irq_attr *irq_attr);
+void setup_IO_APIC_irq_extra(u32 gsi);
 extern int (*ioapic_renumber_irq)(int ioapic, int irq);
 extern void ioapic_init_mappings(void);
 extern void ioapic_insert_resources(void);
@@ -188,6 +187,7 @@ extern struct mp_ioapic_gsi  mp_gsi_rout
 int mp_find_ioapic(int gsi);
 int mp_find_ioapic_pin(int ioapic, int gsi);
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
+extern void __init pre_init_apic_IRQ0(void);
 
 #else  /* !CONFIG_X86_IO_APIC */
 
@@ -197,7 +197,11 @@ static const int timer_through_8259 = 0;
 static inline void ioapic_init_mappings(void)	{ }
 static inline void ioapic_insert_resources(void) { }
 static inline void probe_nr_irqs_gsi(void)	{ }
+static inline int mp_find_ioapic(int gsi) { return 0; }
 
+struct io_apic_irq_attr;
+static inline int io_apic_set_pci_routing(struct device *dev, int irq,
+		 struct io_apic_irq_attr *irq_attr) { return 0; }
 #endif
 
 #endif /* _ASM_X86_IO_APIC_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/io.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/io.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/io.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/io.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,8 +1,42 @@
 #ifndef _ASM_X86_IO_H
 #define _ASM_X86_IO_H
 
+/*
+ * This file contains the definitions for the x86 IO instructions
+ * inb/inw/inl/outb/outw/outl and the "string versions" of the same
+ * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
+ * versions of the single-IO instructions (inb_p/inw_p/..).
+ *
+ * This file is not meant to be obfuscating: it's just complicated
+ * to (a) handle it all in a way that makes gcc able to optimize it
+ * as well as possible and (b) trying to avoid writing the same thing
+ * over and over again with slight variations and possibly making a
+ * mistake somewhere.
+ */
+
+/*
+ * Thanks to James van Artsdalen for a better timing-fix than
+ * the two short jumps: using outb's to a nonexistent port seems
+ * to guarantee better timings even on fast machines.
+ *
+ * On the other hand, I'd like to be sure of a non-existent port:
+ * I feel a bit unsafe about using 0x80 (should be safe, though)
+ *
+ *		Linus
+ */
+
+ /*
+  *  Bit simplified and optimized by Jan Hubicka
+  *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999.
+  *
+  *  isa_memset_io, isa_memcpy_fromio, isa_memcpy_toio added,
+  *  isa_read[wl] and isa_write[wl] fixed
+  *  - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+  */
+
 #define ARCH_HAS_IOREMAP_WC
 
+#include <linux/string.h>
 #include <linux/compiler.h>
 #include <asm-generic/int-ll64.h>
 #include <asm/page.h>
@@ -173,11 +207,126 @@ static inline void __iomem *ioremap(reso
 extern void iounmap(volatile void __iomem *addr);
 
 
-#ifdef CONFIG_X86_32
-# include "io_32.h"
+#ifdef __KERNEL__
+
+#include <asm-generic/iomap.h>
+
+#include <linux/vmalloc.h>
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p)	p
+
+static inline void
+memset_io(volatile void __iomem *addr, unsigned char val, size_t count)
+{
+	memset((void __force *)addr, val, count);
+}
+
+static inline void
+memcpy_fromio(void *dst, const volatile void __iomem *src, size_t count)
+{
+	memcpy(dst, (const void __force *)src, count);
+}
+
+static inline void
+memcpy_toio(volatile void __iomem *dst, const void *src, size_t count)
+{
+	memcpy((void __force *)dst, src, count);
+}
+
+/*
+ * ISA space is 'always mapped' on a typical x86 system, no need to
+ * explicitly ioremap() it. The fact that the ISA IO space is mapped
+ * to PAGE_OFFSET is pure coincidence - it does not mean ISA values
+ * are physical addresses. The following constant pointer can be
+ * used as the IO-area pointer (it can be iounmapped as well, so the
+ * analogy with PCI is quite large):
+ */
+#define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET))
+
+/*
+ *	Cache management
+ *
+ *	This needed for two cases
+ *	1. Out of order aware processors
+ *	2. Accidentally out of order processors (PPro errata #51)
+ */
+
+static inline void flush_write_buffers(void)
+{
+#if defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)
+	asm volatile("lock; addl $0,0(%%esp)": : :"memory");
+#endif
+}
+
+#endif /* __KERNEL__ */
+
+extern void native_io_delay(void);
+
+extern int io_delay_type;
+extern void io_delay_init(void);
+
+#if defined(CONFIG_PARAVIRT)
+#include <asm/paravirt.h>
 #else
-# include "io_64.h"
+
+static inline void slow_down_io(void)
+{
+	native_io_delay();
+#ifdef REALLY_SLOW_IO
+	native_io_delay();
+	native_io_delay();
+	native_io_delay();
 #endif
+}
+
+#endif
+
+#define BUILDIO(bwl, bw, type)						\
+static inline void out##bwl(unsigned type value, int port)		\
+{									\
+	asm volatile("out" #bwl " %" #bw "0, %w1"			\
+		     : : "a"(value), "Nd"(port));			\
+}									\
+									\
+static inline unsigned type in##bwl(int port)				\
+{									\
+	unsigned type value;						\
+	asm volatile("in" #bwl " %w1, %" #bw "0"			\
+		     : "=a"(value) : "Nd"(port));			\
+	return value;							\
+}									\
+									\
+static inline void out##bwl##_p(unsigned type value, int port)		\
+{									\
+	out##bwl(value, port);						\
+	slow_down_io();							\
+}									\
+									\
+static inline unsigned type in##bwl##_p(int port)			\
+{									\
+	unsigned type value = in##bwl(port);				\
+	slow_down_io();							\
+	return value;							\
+}									\
+									\
+static inline void outs##bwl(int port, const void *addr, unsigned long count) \
+{									\
+	asm volatile("rep; outs" #bwl					\
+		     : "+S"(addr), "+c"(count) : "d"(port));		\
+}									\
+									\
+static inline void ins##bwl(int port, void *addr, unsigned long count)	\
+{									\
+	asm volatile("rep; ins" #bwl					\
+		     : "+D"(addr), "+c"(count) : "d"(port));		\
+}
+
+BUILDIO(b, b, char)
+BUILDIO(w, w, short)
+BUILDIO(l, , int)
 
 extern void *xlate_dev_mem_ptr(unsigned long phys);
 extern void unxlate_dev_mem_ptr(unsigned long phys, void *addr);
@@ -198,6 +347,7 @@ extern void __iomem *early_ioremap(resou
 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 fixup_early_ioremap(void);
 
 #define IO_SPACE_LIMIT 0xffff
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/irq_vectors.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/irq_vectors.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/irq_vectors.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/irq_vectors.h	2010-05-16 17:17:36.000000000 -0400
@@ -28,28 +28,33 @@
 #define MCE_VECTOR			0x12
 
 /*
- * IDT vectors usable for external interrupt sources start
- * at 0x20:
+ * IDT vectors usable for external interrupt sources start at 0x20.
+ * (0x80 is the syscall vector, 0x30-0x3f are for ISA)
  */
 #define FIRST_EXTERNAL_VECTOR		0x20
-
-#ifdef CONFIG_X86_32
-# define SYSCALL_VECTOR			0x80
-# define IA32_SYSCALL_VECTOR		0x80
-#else
-# define IA32_SYSCALL_VECTOR		0x80
-#endif
+/*
+ * We start allocating at 0x21 to spread out vectors evenly between
+ * priority levels. (0x80 is the syscall vector)
+ */
+#define VECTOR_OFFSET_START		1
 
 /*
- * Reserve the lowest usable priority level 0x20 - 0x2f for triggering
- * cleanup after irq migration.
+ * Reserve the lowest usable vector (and hence lowest priority)  0x20 for
+ * triggering cleanup after irq migration. 0x21-0x2f will still be used
+ * for device interrupts.
  */
 #define IRQ_MOVE_CLEANUP_VECTOR		FIRST_EXTERNAL_VECTOR
 
+#define IA32_SYSCALL_VECTOR		0x80
+#ifdef CONFIG_X86_32
+# define SYSCALL_VECTOR			0x80
+#endif
+
 /*
  * Vectors 0x30-0x3f are used for ISA interrupts.
+ *   round up to the next 16-vector boundary
  */
-#define IRQ0_VECTOR			(FIRST_EXTERNAL_VECTOR + 0x10)
+#define IRQ0_VECTOR			((FIRST_EXTERNAL_VECTOR + 16) & ~15)
 
 #define IRQ1_VECTOR			(IRQ0_VECTOR +  1)
 #define IRQ2_VECTOR			(IRQ0_VECTOR +  2)
@@ -120,13 +125,6 @@
  */
 #define MCE_SELF_VECTOR			0xeb
 
-/*
- * 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
@@ -154,21 +152,21 @@ static inline int invalid_vm86_irq(int i
 
 #define NR_IRQS_LEGACY			  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 CPU_VECTOR_LIMIT		(64 * NR_CPUS)
 #  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
+#  define CPU_VECTOR_LIMIT		(32 * NR_CPUS)
+#  define NR_IRQS					\
+	(CPU_VECTOR_LIMIT < IO_APIC_VECTOR_LIMIT ?	\
+		(NR_VECTORS + CPU_VECTOR_LIMIT)  :	\
+		(NR_VECTORS + IO_APIC_VECTOR_LIMIT))
 # endif
 #else /* !CONFIG_X86_IO_APIC: */
 # define NR_IRQS			NR_IRQS_LEGACY
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/k8.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/k8.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/k8.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/k8.h	2010-05-16 17:17:36.000000000 -0400
@@ -16,11 +16,16 @@ extern int k8_numa_init(unsigned long st
 extern int k8_scan_nodes(void);
 
 #ifdef CONFIG_K8_NB
+extern int num_k8_northbridges;
+
 static inline struct pci_dev *node_to_k8_nb_misc(int node)
 {
 	return (node < num_k8_northbridges) ? k8_northbridges[node] : NULL;
 }
+
 #else
+#define num_k8_northbridges 0
+
 static inline struct pci_dev *node_to_k8_nb_misc(int node)
 {
 	return NULL;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/Kbuild linux-libre-2.6.34-gnu1/arch/x86/include/asm/Kbuild
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/Kbuild	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/Kbuild	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@ header-y += sigcontext32.h
 header-y += ucontext.h
 header-y += processor-flags.h
 header-y += hw_breakpoint.h
+header-y += hyperv.h
 
 unifdef-y += e820.h
 unifdef-y += ist.h
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/kprobes.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/kprobes.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/kprobes.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/kprobes.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,10 @@ struct kprobe;
 
 typedef u8 kprobe_opcode_t;
 #define BREAKPOINT_INSTRUCTION	0xcc
-#define RELATIVEJUMP_INSTRUCTION 0xe9
+#define RELATIVEJUMP_OPCODE 0xe9
+#define RELATIVEJUMP_SIZE 5
+#define RELATIVECALL_OPCODE 0xe8
+#define RELATIVE_ADDR_SIZE 4
 #define MAX_INSN_SIZE 16
 #define MAX_STACK_SIZE 64
 #define MIN_STACK_SIZE(ADDR)					       \
@@ -44,6 +47,17 @@ typedef u8 kprobe_opcode_t;
 
 #define flush_insn_slot(p)	do { } while (0)
 
+/* optinsn template addresses */
+extern kprobe_opcode_t optprobe_template_entry;
+extern kprobe_opcode_t optprobe_template_val;
+extern kprobe_opcode_t optprobe_template_call;
+extern kprobe_opcode_t optprobe_template_end;
+#define MAX_OPTIMIZED_LENGTH (MAX_INSN_SIZE + RELATIVE_ADDR_SIZE)
+#define MAX_OPTINSN_SIZE 				\
+	(((unsigned long)&optprobe_template_end -	\
+	  (unsigned long)&optprobe_template_entry) +	\
+	 MAX_OPTIMIZED_LENGTH + RELATIVEJUMP_SIZE)
+
 extern const int kretprobe_blacklist_size;
 
 void arch_remove_kprobe(struct kprobe *p);
@@ -64,6 +78,21 @@ struct arch_specific_insn {
 	int boostable;
 };
 
+struct arch_optimized_insn {
+	/* copy of the original instructions */
+	kprobe_opcode_t copied_insn[RELATIVE_ADDR_SIZE];
+	/* detour code buffer */
+	kprobe_opcode_t *insn;
+	/* the size of instructions copied to detour code buffer */
+	size_t size;
+};
+
+/* Return true (!0) if optinsn is prepared for optimization. */
+static inline int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
+{
+	return optinsn->size;
+}
+
 struct prev_kprobe {
 	struct kprobe *kp;
 	unsigned long status;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/kvm_emulate.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/kvm_emulate.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/kvm_emulate.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/kvm_emulate.h	2010-05-16 17:17:36.000000000 -0400
@@ -54,13 +54,23 @@ struct x86_emulate_ctxt;
 struct x86_emulate_ops {
 	/*
 	 * read_std: Read bytes of standard (non-emulated/special) memory.
-	 *           Used for instruction fetch, stack operations, and others.
+	 *           Used for descriptor reading.
 	 *  @addr:  [IN ] Linear address from which to read.
 	 *  @val:   [OUT] Value read from memory, zero-extended to 'u_long'.
 	 *  @bytes: [IN ] Number of bytes to read from memory.
 	 */
 	int (*read_std)(unsigned long addr, void *val,
-			unsigned int bytes, struct kvm_vcpu *vcpu);
+			unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error);
+
+	/*
+	 * fetch: Read bytes of standard (non-emulated/special) memory.
+	 *        Used for instruction fetch.
+	 *  @addr:  [IN ] Linear address from which to read.
+	 *  @val:   [OUT] Value read from memory, zero-extended to 'u_long'.
+	 *  @bytes: [IN ] Number of bytes to read from memory.
+	 */
+	int (*fetch)(unsigned long addr, void *val,
+			unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error);
 
 	/*
 	 * read_emulated: Read bytes from emulated/special memory area.
@@ -74,7 +84,7 @@ struct x86_emulate_ops {
 			     struct kvm_vcpu *vcpu);
 
 	/*
-	 * write_emulated: Read bytes from emulated/special memory area.
+	 * write_emulated: Write bytes to emulated/special memory area.
 	 *  @addr:  [IN ] Linear address to which to write.
 	 *  @val:   [IN ] Value to write to memory (low-order bytes used as
 	 *                required).
@@ -168,6 +178,7 @@ struct x86_emulate_ctxt {
 
 /* Execution mode, passed to the emulator. */
 #define X86EMUL_MODE_REAL     0	/* Real mode.             */
+#define X86EMUL_MODE_VM86     1	/* Virtual 8086 mode.     */
 #define X86EMUL_MODE_PROT16   2	/* 16-bit protected mode. */
 #define X86EMUL_MODE_PROT32   4	/* 32-bit protected mode. */
 #define X86EMUL_MODE_PROT64   8	/* 64-bit (long) mode.    */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/kvm_host.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/kvm_host.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/kvm_host.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/kvm_host.h	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,7 @@
 #include <asm/mtrr.h>
 #include <asm/msr-index.h>
 
-#define KVM_MAX_VCPUS 16
+#define KVM_MAX_VCPUS 64
 #define KVM_MEMORY_SLOTS 32
 /* memory slots that does not exposed to userspace */
 #define KVM_PRIVATE_MEM_SLOTS 4
@@ -38,19 +38,6 @@
 #define CR3_L_MODE_RESERVED_BITS (CR3_NONPAE_RESERVED_BITS |	\
 				  0xFFFFFF0000000000ULL)
 
-#define KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST				\
-	(X86_CR0_WP | X86_CR0_NE | X86_CR0_NW | X86_CR0_CD)
-#define KVM_GUEST_CR0_MASK						\
-	(KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
-#define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST				\
-	(X86_CR0_WP | X86_CR0_NE | X86_CR0_TS | X86_CR0_MP)
-#define KVM_VM_CR0_ALWAYS_ON						\
-	(KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
-#define KVM_GUEST_CR4_MASK						\
-	(X86_CR4_VME | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_PGE | X86_CR4_VMXE)
-#define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE)
-#define KVM_RMODE_VM_CR4_ALWAYS_ON (X86_CR4_VME | X86_CR4_PAE | X86_CR4_VMXE)
-
 #define INVALID_PAGE (~(hpa_t)0)
 #define UNMAPPED_GVA (~(gpa_t)0)
 
@@ -256,7 +243,8 @@ struct kvm_mmu {
 	void (*new_cr3)(struct kvm_vcpu *vcpu);
 	int (*page_fault)(struct kvm_vcpu *vcpu, gva_t gva, u32 err);
 	void (*free)(struct kvm_vcpu *vcpu);
-	gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva);
+	gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva, u32 access,
+			    u32 *error);
 	void (*prefetch_page)(struct kvm_vcpu *vcpu,
 			      struct kvm_mmu_page *page);
 	int (*sync_page)(struct kvm_vcpu *vcpu,
@@ -282,13 +270,15 @@ struct kvm_vcpu_arch {
 	u32 regs_dirty;
 
 	unsigned long cr0;
+	unsigned long cr0_guest_owned_bits;
 	unsigned long cr2;
 	unsigned long cr3;
 	unsigned long cr4;
+	unsigned long cr4_guest_owned_bits;
 	unsigned long cr8;
 	u32 hflags;
 	u64 pdptrs[4]; /* pae */
-	u64 shadow_efer;
+	u64 efer;
 	u64 apic_base;
 	struct kvm_lapic *apic;    /* kernel irqchip context */
 	int32_t apic_arb_prio;
@@ -374,17 +364,27 @@ struct kvm_vcpu_arch {
 	/* used for guest single stepping over the given code position */
 	u16 singlestep_cs;
 	unsigned long singlestep_rip;
+	/* fields used by HYPER-V emulation */
+	u64 hv_vapic;
 };
 
 struct kvm_mem_alias {
 	gfn_t base_gfn;
 	unsigned long npages;
 	gfn_t target_gfn;
+#define KVM_ALIAS_INVALID     1UL
+	unsigned long flags;
 };
 
-struct kvm_arch{
-	int naliases;
+#define KVM_ARCH_HAS_UNALIAS_INSTANTIATION
+
+struct kvm_mem_aliases {
 	struct kvm_mem_alias aliases[KVM_ALIAS_SLOTS];
+	int naliases;
+};
+
+struct kvm_arch {
+	struct kvm_mem_aliases *aliases;
 
 	unsigned int n_free_mmu_pages;
 	unsigned int n_requested_mmu_pages;
@@ -416,6 +416,10 @@ struct kvm_arch{
 	s64 kvmclock_offset;
 
 	struct kvm_xen_hvm_config xen_hvm_config;
+
+	/* fields used by HYPER-V emulation */
+	u64 hv_guest_os_id;
+	u64 hv_hypercall;
 };
 
 struct kvm_vm_stat {
@@ -471,6 +475,7 @@ struct kvm_x86_ops {
 	int (*hardware_setup)(void);               /* __init */
 	void (*hardware_unsetup)(void);            /* __exit */
 	bool (*cpu_has_accelerated_tpr)(void);
+	void (*cpuid_update)(struct kvm_vcpu *vcpu);
 
 	/* Create, but do not attach this VCPU */
 	struct kvm_vcpu *(*vcpu_create)(struct kvm *kvm, unsigned id);
@@ -492,6 +497,7 @@ struct kvm_x86_ops {
 	void (*set_segment)(struct kvm_vcpu *vcpu,
 			    struct kvm_segment *var, int seg);
 	void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l);
+	void (*decache_cr0_guest_bits)(struct kvm_vcpu *vcpu);
 	void (*decache_cr4_guest_bits)(struct kvm_vcpu *vcpu);
 	void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0);
 	void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3);
@@ -501,12 +507,13 @@ struct kvm_x86_ops {
 	void (*set_idt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt);
 	void (*get_gdt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt);
 	void (*set_gdt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt);
-	unsigned long (*get_dr)(struct kvm_vcpu *vcpu, int dr);
-	void (*set_dr)(struct kvm_vcpu *vcpu, int dr, unsigned long value,
-		       int *exception);
+	int (*get_dr)(struct kvm_vcpu *vcpu, int dr, unsigned long *dest);
+	int (*set_dr)(struct kvm_vcpu *vcpu, int dr, unsigned long value);
 	void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg);
 	unsigned long (*get_rflags)(struct kvm_vcpu *vcpu);
 	void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
+	void (*fpu_activate)(struct kvm_vcpu *vcpu);
+	void (*fpu_deactivate)(struct kvm_vcpu *vcpu);
 
 	void (*tlb_flush)(struct kvm_vcpu *vcpu);
 
@@ -531,7 +538,8 @@ struct kvm_x86_ops {
 	int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
 	int (*get_tdp_level)(void);
 	u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio);
-	bool (*gb_page_enable)(void);
+	int (*get_lpage_level)(void);
+	bool (*rdtscp_supported)(void);
 
 	const struct trace_print_flags *exit_reasons_str;
 };
@@ -606,8 +614,7 @@ int emulator_set_dr(struct x86_emulate_c
 		    unsigned long value);
 
 void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg);
-int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
-				int type_bits, int seg);
+int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg);
 
 int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason);
 
@@ -653,6 +660,10 @@ void __kvm_mmu_free_some_pages(struct kv
 int kvm_mmu_load(struct kvm_vcpu *vcpu);
 void kvm_mmu_unload(struct kvm_vcpu *vcpu);
 void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu);
+gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u32 *error);
+gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva, u32 *error);
+gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, u32 *error);
+gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, u32 *error);
 
 int kvm_emulate_hypercall(struct kvm_vcpu *vcpu);
 
@@ -666,6 +677,7 @@ void kvm_disable_tdp(void);
 
 int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3);
 int complete_pio(struct kvm_vcpu *vcpu);
+bool kvm_check_iopl(struct kvm_vcpu *vcpu);
 
 struct kvm_memory_slot *gfn_to_memslot_unaliased(struct kvm *kvm, gfn_t gfn);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/kvm_para.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/kvm_para.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/kvm_para.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/kvm_para.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
 #define _ASM_X86_KVM_PARA_H
 
 #include <linux/types.h>
+#include <asm/hyperv.h>
 
 /* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx.  It
  * should be used to determine that a VM is running under KVM.
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/lguest_hcall.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/lguest_hcall.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/lguest_hcall.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/lguest_hcall.h	2010-05-16 17:17:36.000000000 -0400
@@ -28,22 +28,39 @@
 
 #ifndef __ASSEMBLY__
 #include <asm/hw_irq.h>
-#include <asm/kvm_para.h>
 
 /*G:030
  * 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.
  *
- * We use the KVM hypercall mechanism, though completely different hypercall
- * numbers. Seventeen hypercalls are available: the hypercall number is put in
- * the %eax register, and the arguments (when required) are placed in %ebx,
- * %ecx, %edx and %esi.  If a return value makes sense, it's returned in %eax.
+ * Our hypercall mechanism uses the highest unused trap code (traps 32 and
+ * above are used by real hardware interrupts).  Seventeen hypercalls are
+ * available: the hypercall number is put in the %eax register, and the
+ * arguments (when required) are placed in %ebx, %ecx, %edx and %esi.
+ * 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,
+      unsigned long arg4)
+{
+	/* "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, %ebx, %ecx, %edx & %esi */
+		     : "a"(call), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4)
+		       /* "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 */
 #define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32)
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/local.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/local.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/local.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/local.h	2010-05-16 17:17:36.000000000 -0400
@@ -195,41 +195,4 @@ static inline long local_sub_return(long
 #define __local_add(i, l)	local_add((i), (l))
 #define __local_sub(i, l)	local_sub((i), (l))
 
-/* 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.
- *
- * X86_64: This could be done better if we moved the per cpu data directly
- * after GS.
- */
-
-/* Need to disable preemption for the cpu local counters otherwise we could
-   still access a variable of a previous CPU in a non atomic 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 /* _ASM_X86_LOCAL_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/mmzone_64.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/mmzone_64.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/mmzone_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/mmzone_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -39,11 +39,5 @@ static inline __attribute__((pure)) int
 #define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
 #define node_end_pfn(nid)       (NODE_DATA(nid)->node_start_pfn +	\
 				 NODE_DATA(nid)->node_spanned_pages)
-
-#ifdef CONFIG_NUMA_EMU
-#define FAKE_NODE_MIN_SIZE	(64 * 1024 * 1024)
-#define FAKE_NODE_MIN_HASH_MASK	(~(FAKE_NODE_MIN_SIZE - 1UL))
-#endif
-
 #endif
 #endif /* _ASM_X86_MMZONE_64_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/mrst.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/mrst.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/mrst.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/mrst.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,19 @@
+/*
+ * mrst.h: Intel Moorestown platform specific setup code
+ *
+ * (C) Copyright 2009 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+#ifndef _ASM_X86_MRST_H
+#define _ASM_X86_MRST_H
+extern int pci_mrst_init(void);
+int __init sfi_parse_mrtc(struct sfi_table_header *table);
+
+#define SFI_MTMR_MAX_NUM 8
+#define SFI_MRTC_MAX	8
+
+#endif /* _ASM_X86_MRST_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/msr-index.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/msr-index.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/msr-index.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/msr-index.h	2010-05-16 17:17:36.000000000 -0400
@@ -105,6 +105,8 @@
 #define MSR_AMD64_PATCH_LEVEL		0x0000008b
 #define MSR_AMD64_NB_CFG		0xc001001f
 #define MSR_AMD64_PATCH_LOADER		0xc0010020
+#define MSR_AMD64_OSVW_ID_LENGTH	0xc0010140
+#define MSR_AMD64_OSVW_STATUS		0xc0010141
 #define MSR_AMD64_IBSFETCHCTL		0xc0011030
 #define MSR_AMD64_IBSFETCHLINAD		0xc0011031
 #define MSR_AMD64_IBSFETCHPHYSAD	0xc0011032
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/nmi.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/nmi.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/nmi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/nmi.h	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@ extern void die_nmi(char *str, struct pt
 extern int check_nmi_watchdog(void);
 extern int nmi_watchdog_enabled;
 extern int avail_to_resrv_perfctr_nmi_bit(unsigned int);
-extern int avail_to_resrv_perfctr_nmi(unsigned int);
 extern int reserve_perfctr_nmi(unsigned int);
 extern void release_perfctr_nmi(unsigned int);
 extern int reserve_evntsel_nmi(unsigned int);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/numa_64.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/numa_64.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/numa_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/numa_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,11 @@ extern void __cpuinit numa_set_node(int
 extern void __cpuinit numa_clear_node(int cpu);
 extern void __cpuinit numa_add_cpu(int cpu);
 extern void __cpuinit numa_remove_cpu(int cpu);
+
+#ifdef CONFIG_NUMA_EMU
+#define FAKE_NODE_MIN_SIZE	((u64)64 << 20)
+#define FAKE_NODE_MIN_HASH_MASK	(~(FAKE_NODE_MIN_SIZE - 1UL))
+#endif /* CONFIG_NUMA_EMU */
 #else
 static inline void init_cpu_to_node(void)		{ }
 static inline void numa_set_node(int cpu, int node)	{ }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/numaq.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/numaq.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/numaq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/numaq.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,9 +30,14 @@
 
 extern int found_numaq;
 extern int get_memcfg_numaq(void);
+extern int pci_numaq_init(void);
 
 extern void *xquad_portio;
 
+#define XQUAD_PORTIO_BASE 0xfe400000
+#define XQUAD_PORTIO_QUAD 0x40000  /* 256k per quad. */
+#define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port)
+
 /*
  * SYS_CFG_DATA_PRIV_ADDR, struct eachquadmem, and struct sys_cfg_data are the
  */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/olpc.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/olpc.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/olpc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/olpc.h	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@ struct olpc_platform_t {
 
 #define OLPC_F_PRESENT		0x01
 #define OLPC_F_DCON		0x02
-#define OLPC_F_VSA		0x04
 
 #ifdef CONFIG_OLPC
 
@@ -51,18 +50,6 @@ static inline int olpc_has_dcon(void)
 }
 
 /*
- * The VSA is software from AMD that typical Geode bioses will include.
- * It is used to emulate the PCI bus, VGA, etc.  OLPC's Open Firmware does
- * not include the VSA; instead, PCI is emulated by the kernel.
- *
- * The VSA is described further in arch/x86/pci/olpc.c.
- */
-static inline int olpc_has_vsa(void)
-{
-	return (olpc_platform_info.flags & OLPC_F_VSA) ? 1 : 0;
-}
-
-/*
  * The "Mass Production" version of OLPC's XO is identified as being model
  * C2.  During the prototype phase, the following models (in chronological
  * order) were created: A1, B1, B2, B3, B4, C1.  The A1 through B2 models
@@ -87,13 +74,10 @@ static inline int olpc_has_dcon(void)
 	return 0;
 }
 
-static inline int olpc_has_vsa(void)
-{
-	return 0;
-}
-
 #endif
 
+extern int pci_olpc_init(void);
+
 /* EC related functions */
 
 extern int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen,
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/page_types.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/page_types.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/page_types.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/page_types.h	2010-05-16 17:17:36.000000000 -0400
@@ -40,7 +40,6 @@
 
 #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;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/paravirt.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/paravirt.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/paravirt.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/paravirt.h	2010-05-16 17:17:36.000000000 -0400
@@ -435,15 +435,6 @@ static inline void paravirt_release_pud(
 	PVOP_VCALL1(pv_mmu_ops.release_pud, pfn);
 }
 
-#ifdef CONFIG_HIGHPTE
-static inline void *kmap_atomic_pte(struct page *page, enum km_type type)
-{
-	unsigned long ret;
-	ret = PVOP_CALL2(unsigned long, pv_mmu_ops.kmap_atomic_pte, page, type);
-	return (void *)ret;
-}
-#endif
-
 static inline void pte_update(struct mm_struct *mm, unsigned long addr,
 			      pte_t *ptep)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/paravirt_types.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/paravirt_types.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/paravirt_types.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/paravirt_types.h	2010-05-16 17:17:36.000000000 -0400
@@ -304,10 +304,6 @@ struct pv_mmu_ops {
 #endif	/* PAGETABLE_LEVELS == 4 */
 #endif	/* PAGETABLE_LEVELS >= 3 */
 
-#ifdef CONFIG_HIGHPTE
-	void *(*kmap_atomic_pte)(struct page *page, enum km_type type);
-#endif
-
 	struct pv_lazy_ops lazy_mode;
 
 	/* dom0 ops */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/pci_64.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/pci_64.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/pci_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/pci_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,8 +22,6 @@ extern int (*pci_config_read)(int seg, i
 extern int (*pci_config_write)(int seg, int bus, int dev, int fn,
 			       int reg, int len, u32 value);
 
-extern void dma32_reserve_bootmem(void);
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_X86_PCI_64_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/pci.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/pci.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -45,8 +45,15 @@ static inline int pci_proc_domain(struct
 
 #ifdef CONFIG_PCI
 extern unsigned int pcibios_assign_all_busses(void);
+extern int pci_legacy_init(void);
+# ifdef CONFIG_ACPI
+#  define x86_default_pci_init pci_acpi_init
+# else
+#  define x86_default_pci_init pci_legacy_init
+# endif
 #else
-#define pcibios_assign_all_busses()	0
+# define pcibios_assign_all_busses()	0
+# define x86_default_pci_init		NULL
 #endif
 
 extern unsigned long pci_mem_start;
@@ -90,40 +97,14 @@ extern void pci_iommu_alloc(void);
 
 #define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
 
-#if defined(CONFIG_X86_64) || defined(CONFIG_DMAR) || 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))
-
-#else
-
-#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
 
+void dma32_reserve_bootmem(void);
+
 /* implement the pci_ DMA API in terms of the generic device dma_ one */
 #include <asm-generic/pci-dma-compat.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/pci_x86.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/pci_x86.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/pci_x86.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/pci_x86.h	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #define PCI_CHECK_ENABLE_AMD_MMCONF	0x20000
 #define PCI_HAS_IO_ECS		0x40000
 #define PCI_NOASSIGN_ROMS	0x80000
+#define PCI_ROOT_NO_CRS		0x100000
 
 extern unsigned int pci_probe;
 extern unsigned long pirq_table_addr;
@@ -82,7 +83,6 @@ struct irq_routing_table {
 
 extern unsigned int pcibios_irq_mask;
 
-extern int pcibios_scanned;
 extern spinlock_t pci_config_lock;
 
 extern int (*pcibios_enable_irq)(struct pci_dev *dev);
@@ -105,16 +105,15 @@ extern bool port_cf9_safe;
 extern int pci_direct_probe(void);
 extern void pci_direct_init(int type);
 extern void pci_pcbios_init(void);
-extern int pci_olpc_init(void);
 extern void __init dmi_check_pciprobe(void);
 extern void __init dmi_check_skip_isa_align(void);
 
 /* some common used subsys_initcalls */
 extern int __init pci_acpi_init(void);
-extern int __init pcibios_irq_init(void);
-extern int __init pci_visws_init(void);
-extern int __init pci_numaq_init(void);
+extern void __init pcibios_irq_init(void);
 extern int __init pcibios_init(void);
+extern int pci_legacy_init(void);
+extern void pcibios_fixup_irqs(void);
 
 /* pci-mmconfig.c */
 
@@ -182,3 +181,17 @@ static inline void mmio_config_writel(vo
 {
 	asm volatile("movl %%eax,(%1)" : : "a" (val), "r" (pos) : "memory");
 }
+
+#ifdef CONFIG_PCI
+# ifdef CONFIG_ACPI
+#  define x86_default_pci_init		pci_acpi_init
+# else
+#  define x86_default_pci_init		pci_legacy_init
+# endif
+# define x86_default_pci_init_irq	pcibios_irq_init
+# define x86_default_pci_fixup_irqs	pcibios_fixup_irqs
+#else
+# define x86_default_pci_init		NULL
+# define x86_default_pci_init_irq	NULL
+# define x86_default_pci_fixup_irqs	NULL
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/percpu.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/percpu.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/percpu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/percpu.h	2010-05-16 17:17:36.000000000 -0400
@@ -25,19 +25,18 @@
  */
 #ifdef CONFIG_SMP
 #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)	%__percpu_seg:per_cpu__##var
+	__percpu_mov_op %__percpu_seg:this_cpu_off, reg;		\
+	lea var(reg), reg
+#define PER_CPU_VAR(var)	%__percpu_seg:var
 #else /* ! SMP */
-#define PER_CPU(var, reg)						\
-	__percpu_mov_op $per_cpu__##var, reg
-#define PER_CPU_VAR(var)	per_cpu__##var
+#define PER_CPU(var, reg)	__percpu_mov_op $var, reg
+#define PER_CPU_VAR(var)	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
+#define INIT_PER_CPU_VAR(var)  var
 #endif
 
 #else /* ...!ASSEMBLY */
@@ -60,12 +59,12 @@
  * There also must be an entry in vmlinux_64.lds.S
  */
 #define DECLARE_INIT_PER_CPU(var) \
-       extern typeof(per_cpu_var(var)) init_per_cpu_var(var)
+       extern typeof(var) init_per_cpu_var(var)
 
 #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)
+#define init_per_cpu_var(var)  var
 #endif
 
 /* For arch-specific code, we can use direct single-insn ops (they
@@ -104,6 +103,64 @@ do {							\
 	}						\
 } while (0)
 
+/*
+ * Generate a percpu add to memory instruction and optimize code
+ * if a one is added or subtracted.
+ */
+#define percpu_add_op(var, val)						\
+do {									\
+	typedef typeof(var) pao_T__;					\
+	const int pao_ID__ = (__builtin_constant_p(val) &&		\
+			      ((val) == 1 || (val) == -1)) ? (val) : 0;	\
+	if (0) {							\
+		pao_T__ pao_tmp__;					\
+		pao_tmp__ = (val);					\
+	}								\
+	switch (sizeof(var)) {						\
+	case 1:								\
+		if (pao_ID__ == 1)					\
+			asm("incb "__percpu_arg(0) : "+m" (var));	\
+		else if (pao_ID__ == -1)				\
+			asm("decb "__percpu_arg(0) : "+m" (var));	\
+		else							\
+			asm("addb %1, "__percpu_arg(0)			\
+			    : "+m" (var)				\
+			    : "qi" ((pao_T__)(val)));			\
+		break;							\
+	case 2:								\
+		if (pao_ID__ == 1)					\
+			asm("incw "__percpu_arg(0) : "+m" (var));	\
+		else if (pao_ID__ == -1)				\
+			asm("decw "__percpu_arg(0) : "+m" (var));	\
+		else							\
+			asm("addw %1, "__percpu_arg(0)			\
+			    : "+m" (var)				\
+			    : "ri" ((pao_T__)(val)));			\
+		break;							\
+	case 4:								\
+		if (pao_ID__ == 1)					\
+			asm("incl "__percpu_arg(0) : "+m" (var));	\
+		else if (pao_ID__ == -1)				\
+			asm("decl "__percpu_arg(0) : "+m" (var));	\
+		else							\
+			asm("addl %1, "__percpu_arg(0)			\
+			    : "+m" (var)				\
+			    : "ri" ((pao_T__)(val)));			\
+		break;							\
+	case 8:								\
+		if (pao_ID__ == 1)					\
+			asm("incq "__percpu_arg(0) : "+m" (var));	\
+		else if (pao_ID__ == -1)				\
+			asm("decq "__percpu_arg(0) : "+m" (var));	\
+		else							\
+			asm("addq %1, "__percpu_arg(0)			\
+			    : "+m" (var)				\
+			    : "re" ((pao_T__)(val)));			\
+		break;							\
+	default: __bad_percpu_size();					\
+	}								\
+} while (0)
+
 #define percpu_from_op(op, var, constraint)		\
 ({							\
 	typeof(var) pfo_ret__;				\
@@ -142,16 +199,14 @@ do {							\
  * per-thread variables implemented as per-cpu variables and thus
  * stable for the duration of the respective task.
  */
-#define percpu_read(var)	percpu_from_op("mov", per_cpu__##var,	\
-					       "m" (per_cpu__##var))
-#define percpu_read_stable(var)	percpu_from_op("mov", per_cpu__##var,	\
-					       "p" (&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)
+#define percpu_read(var)		percpu_from_op("mov", var, "m" (var))
+#define percpu_read_stable(var)		percpu_from_op("mov", var, "p" (&(var)))
+#define percpu_write(var, val)		percpu_to_op("mov", var, val)
+#define percpu_add(var, val)		percpu_add_op(var, val)
+#define percpu_sub(var, val)		percpu_add_op(var, -(val))
+#define percpu_and(var, val)		percpu_to_op("and", var, val)
+#define percpu_or(var, val)		percpu_to_op("or", var, val)
+#define percpu_xor(var, val)		percpu_to_op("xor", var, val)
 
 #define __this_cpu_read_1(pcp)		percpu_from_op("mov", (pcp), "m"(pcp))
 #define __this_cpu_read_2(pcp)		percpu_from_op("mov", (pcp), "m"(pcp))
@@ -160,9 +215,9 @@ do {							\
 #define __this_cpu_write_1(pcp, val)	percpu_to_op("mov", (pcp), val)
 #define __this_cpu_write_2(pcp, val)	percpu_to_op("mov", (pcp), val)
 #define __this_cpu_write_4(pcp, val)	percpu_to_op("mov", (pcp), val)
-#define __this_cpu_add_1(pcp, val)	percpu_to_op("add", (pcp), val)
-#define __this_cpu_add_2(pcp, val)	percpu_to_op("add", (pcp), val)
-#define __this_cpu_add_4(pcp, val)	percpu_to_op("add", (pcp), val)
+#define __this_cpu_add_1(pcp, val)	percpu_add_op((pcp), val)
+#define __this_cpu_add_2(pcp, val)	percpu_add_op((pcp), val)
+#define __this_cpu_add_4(pcp, val)	percpu_add_op((pcp), val)
 #define __this_cpu_and_1(pcp, val)	percpu_to_op("and", (pcp), val)
 #define __this_cpu_and_2(pcp, val)	percpu_to_op("and", (pcp), val)
 #define __this_cpu_and_4(pcp, val)	percpu_to_op("and", (pcp), val)
@@ -179,9 +234,9 @@ do {							\
 #define this_cpu_write_1(pcp, val)	percpu_to_op("mov", (pcp), val)
 #define this_cpu_write_2(pcp, val)	percpu_to_op("mov", (pcp), val)
 #define this_cpu_write_4(pcp, val)	percpu_to_op("mov", (pcp), val)
-#define this_cpu_add_1(pcp, val)	percpu_to_op("add", (pcp), val)
-#define this_cpu_add_2(pcp, val)	percpu_to_op("add", (pcp), val)
-#define this_cpu_add_4(pcp, val)	percpu_to_op("add", (pcp), val)
+#define this_cpu_add_1(pcp, val)	percpu_add_op((pcp), val)
+#define this_cpu_add_2(pcp, val)	percpu_add_op((pcp), val)
+#define this_cpu_add_4(pcp, val)	percpu_add_op((pcp), val)
 #define this_cpu_and_1(pcp, val)	percpu_to_op("and", (pcp), val)
 #define this_cpu_and_2(pcp, val)	percpu_to_op("and", (pcp), val)
 #define this_cpu_and_4(pcp, val)	percpu_to_op("and", (pcp), val)
@@ -192,9 +247,9 @@ do {							\
 #define this_cpu_xor_2(pcp, val)	percpu_to_op("xor", (pcp), val)
 #define this_cpu_xor_4(pcp, val)	percpu_to_op("xor", (pcp), val)
 
-#define irqsafe_cpu_add_1(pcp, val)	percpu_to_op("add", (pcp), val)
-#define irqsafe_cpu_add_2(pcp, val)	percpu_to_op("add", (pcp), val)
-#define irqsafe_cpu_add_4(pcp, val)	percpu_to_op("add", (pcp), val)
+#define irqsafe_cpu_add_1(pcp, val)	percpu_add_op((pcp), val)
+#define irqsafe_cpu_add_2(pcp, val)	percpu_add_op((pcp), val)
+#define irqsafe_cpu_add_4(pcp, val)	percpu_add_op((pcp), val)
 #define irqsafe_cpu_and_1(pcp, val)	percpu_to_op("and", (pcp), val)
 #define irqsafe_cpu_and_2(pcp, val)	percpu_to_op("and", (pcp), val)
 #define irqsafe_cpu_and_4(pcp, val)	percpu_to_op("and", (pcp), val)
@@ -212,19 +267,19 @@ do {							\
 #ifdef CONFIG_X86_64
 #define __this_cpu_read_8(pcp)		percpu_from_op("mov", (pcp), "m"(pcp))
 #define __this_cpu_write_8(pcp, val)	percpu_to_op("mov", (pcp), val)
-#define __this_cpu_add_8(pcp, val)	percpu_to_op("add", (pcp), val)
+#define __this_cpu_add_8(pcp, val)	percpu_add_op((pcp), val)
 #define __this_cpu_and_8(pcp, val)	percpu_to_op("and", (pcp), val)
 #define __this_cpu_or_8(pcp, val)	percpu_to_op("or", (pcp), val)
 #define __this_cpu_xor_8(pcp, val)	percpu_to_op("xor", (pcp), val)
 
 #define this_cpu_read_8(pcp)		percpu_from_op("mov", (pcp), "m"(pcp))
 #define this_cpu_write_8(pcp, val)	percpu_to_op("mov", (pcp), val)
-#define this_cpu_add_8(pcp, val)	percpu_to_op("add", (pcp), val)
+#define this_cpu_add_8(pcp, val)	percpu_add_op((pcp), val)
 #define this_cpu_and_8(pcp, val)	percpu_to_op("and", (pcp), val)
 #define this_cpu_or_8(pcp, val)		percpu_to_op("or", (pcp), val)
 #define this_cpu_xor_8(pcp, val)	percpu_to_op("xor", (pcp), val)
 
-#define irqsafe_cpu_add_8(pcp, val)	percpu_to_op("add", (pcp), val)
+#define irqsafe_cpu_add_8(pcp, val)	percpu_add_op((pcp), val)
 #define irqsafe_cpu_and_8(pcp, val)	percpu_to_op("and", (pcp), val)
 #define irqsafe_cpu_or_8(pcp, val)	percpu_to_op("or", (pcp), val)
 #define irqsafe_cpu_xor_8(pcp, val)	percpu_to_op("xor", (pcp), val)
@@ -236,7 +291,7 @@ do {							\
 ({									\
 	int old__;							\
 	asm volatile("btr %2,"__percpu_arg(1)"\n\tsbbl %0,%0"		\
-		     : "=r" (old__), "+m" (per_cpu__##var)		\
+		     : "=r" (old__), "+m" (var)				\
 		     : "dIr" (bit));					\
 	old__;								\
 })
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/perf_event.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/perf_event.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/perf_event.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/perf_event.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,7 @@
 #define MSR_ARCH_PERFMON_EVENTSEL0			     0x186
 #define MSR_ARCH_PERFMON_EVENTSEL1			     0x187
 
-#define ARCH_PERFMON_EVENTSEL0_ENABLE			  (1 << 22)
+#define ARCH_PERFMON_EVENTSEL_ENABLE			  (1 << 22)
 #define ARCH_PERFMON_EVENTSEL_ANY			  (1 << 21)
 #define ARCH_PERFMON_EVENTSEL_INT			  (1 << 20)
 #define ARCH_PERFMON_EVENTSEL_OS			  (1 << 17)
@@ -27,7 +27,14 @@
 /*
  * Includes eventsel and unit mask as well:
  */
-#define ARCH_PERFMON_EVENT_MASK				    0xffff
+
+
+#define INTEL_ARCH_EVTSEL_MASK		0x000000FFULL
+#define INTEL_ARCH_UNIT_MASK		0x0000FF00ULL
+#define INTEL_ARCH_EDGE_MASK		0x00040000ULL
+#define INTEL_ARCH_INV_MASK		0x00800000ULL
+#define INTEL_ARCH_CNT_MASK		0xFF000000ULL
+#define INTEL_ARCH_EVENT_MASK	(INTEL_ARCH_UNIT_MASK|INTEL_ARCH_EVTSEL_MASK)
 
 /*
  * filter mask to validate fixed counter events.
@@ -38,7 +45,12 @@
  *  The other filters are supported by fixed counters.
  *  The any-thread option is supported starting with v3.
  */
-#define ARCH_PERFMON_EVENT_FILTER_MASK			0xff840000
+#define INTEL_ARCH_FIXED_MASK \
+	(INTEL_ARCH_CNT_MASK| \
+	 INTEL_ARCH_INV_MASK| \
+	 INTEL_ARCH_EDGE_MASK|\
+	 INTEL_ARCH_UNIT_MASK|\
+	 INTEL_ARCH_EVENT_MASK)
 
 #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL		      0x3c
 #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK		(0x00 << 8)
@@ -105,6 +117,18 @@ union cpuid10_edx {
  */
 #define X86_PMC_IDX_FIXED_BTS				(X86_PMC_IDX_FIXED + 16)
 
+/* IbsFetchCtl bits/masks */
+#define IBS_FETCH_RAND_EN		(1ULL<<57)
+#define IBS_FETCH_VAL			(1ULL<<49)
+#define IBS_FETCH_ENABLE		(1ULL<<48)
+#define IBS_FETCH_CNT			0xFFFF0000ULL
+#define IBS_FETCH_MAX_CNT		0x0000FFFFULL
+
+/* IbsOpCtl bits */
+#define IBS_OP_CNT_CTL			(1ULL<<19)
+#define IBS_OP_VAL			(1ULL<<18)
+#define IBS_OP_ENABLE			(1ULL<<17)
+#define IBS_OP_MAX_CNT			0x0000FFFFULL
 
 #ifdef CONFIG_PERF_EVENTS
 extern void init_hw_perf_events(void);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/pgalloc.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/pgalloc.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/pgalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/pgalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,11 @@ static inline void paravirt_release_pud(
 #endif
 
 /*
+ * Flags to use when allocating a user page table page.
+ */
+extern gfp_t __userpte_alloc_gfp;
+
+/*
  * Allocate and free page tables.
  */
 extern pgd_t *pgd_alloc(struct mm_struct *);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/pgtable_32.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/pgtable_32.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/pgtable_32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/pgtable_32.h	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <asm/paravirt.h>
 
 #include <linux/bitops.h>
-#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
 
@@ -54,10 +53,10 @@ extern void set_pmd_pfn(unsigned long, u
 	 in_irq() ? KM_IRQ_PTE :	\
 	 KM_PTE0)
 #define pte_offset_map(dir, address)					\
-	((pte_t *)kmap_atomic_pte(pmd_page(*(dir)), __KM_PTE) +		\
+	((pte_t *)kmap_atomic(pmd_page(*(dir)), __KM_PTE) +		\
 	 pte_index((address)))
 #define pte_offset_map_nested(dir, address)				\
-	((pte_t *)kmap_atomic_pte(pmd_page(*(dir)), KM_PTE1) +		\
+	((pte_t *)kmap_atomic(pmd_page(*(dir)), KM_PTE1) +		\
 	 pte_index((address)))
 #define pte_unmap(pte) kunmap_atomic((pte), __KM_PTE)
 #define pte_unmap_nested(pte) kunmap_atomic((pte), KM_PTE1)
@@ -80,7 +79,7 @@ do {						\
  * The i386 doesn't have any external MMU info: the kernel page
  * tables contain all the necessary information.
  */
-#define update_mmu_cache(vma, address, pte) do { } while (0)
+#define update_mmu_cache(vma, address, ptep) do { } while (0)
 
 #endif /* !__ASSEMBLY__ */
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/pgtable_64.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/pgtable_64.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/pgtable_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/pgtable_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -129,7 +129,7 @@ static inline int pgd_large(pgd_t pgd) {
 #define pte_unmap(pte) /* NOP */
 #define pte_unmap_nested(pte) /* NOP */
 
-#define update_mmu_cache(vma, address, pte) do { } while (0)
+#define update_mmu_cache(vma, address, ptep) do { } while (0)
 
 /* Encode and de-code a swap entry */
 #if _PAGE_BIT_FILE < _PAGE_BIT_PROTNONE
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/proto.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/proto.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/proto.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/proto.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,14 +23,4 @@ extern int reboot_force;
 
 long do_arch_prctl(struct task_struct *task, int code, unsigned long addr);
 
-/*
- * This looks more complex than it should be. But we need to
- * get the type for the ~ right in round_down (it needs to be
- * as wide as the result!), and we want to evaluate the macro
- * arguments just once each.
- */
-#define __round_mask(x,y) ((__typeof__(x))((y)-1))
-#define round_up(x,y) ((((x)-1) | __round_mask(x,y))+1)
-#define round_down(x,y) ((x) & ~__round_mask(x,y))
-
 #endif /* _ASM_X86_PROTO_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -274,18 +274,7 @@ static inline unsigned long regs_get_ker
 		return 0;
 }
 
-/* Get Nth argument at function call */
-extern unsigned long regs_get_argument_nth(struct pt_regs *regs,
-					   unsigned int n);
-
-/*
- * These are defined as per linux/ptrace.h, which see.
- */
 #define arch_has_single_step()	(1)
-extern void user_enable_single_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
-
-extern void user_enable_block_step(struct task_struct *);
 #ifdef CONFIG_X86_DEBUGCTLMSR
 #define arch_has_block_step()	(1)
 #else
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/rwsem.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/rwsem.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/rwsem.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/rwsem.h	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/lockdep.h>
+#include <asm/asm.h>
 
 struct rwsem_waiter;
 
@@ -55,17 +56,28 @@ extern asmregparm struct rw_semaphore *
 
 /*
  * the semaphore definition
+ *
+ * The bias values and the counter type limits the number of
+ * potential readers/writers to 32767 for 32 bits and 2147483647
+ * for 64 bits.
  */
 
-#define RWSEM_UNLOCKED_VALUE		0x00000000
-#define RWSEM_ACTIVE_BIAS		0x00000001
-#define RWSEM_ACTIVE_MASK		0x0000ffff
-#define RWSEM_WAITING_BIAS		(-0x00010000)
+#ifdef CONFIG_X86_64
+# define RWSEM_ACTIVE_MASK		0xffffffffL
+#else
+# define RWSEM_ACTIVE_MASK		0x0000ffffL
+#endif
+
+#define RWSEM_UNLOCKED_VALUE		0x00000000L
+#define RWSEM_ACTIVE_BIAS		0x00000001L
+#define RWSEM_WAITING_BIAS		(-RWSEM_ACTIVE_MASK-1)
 #define RWSEM_ACTIVE_READ_BIAS		RWSEM_ACTIVE_BIAS
 #define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
 
+typedef signed long rwsem_count_t;
+
 struct rw_semaphore {
-	signed long		count;
+	rwsem_count_t		count;
 	spinlock_t		wait_lock;
 	struct list_head	wait_list;
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -105,7 +117,7 @@ do {								\
 static inline void __down_read(struct rw_semaphore *sem)
 {
 	asm volatile("# beginning down_read\n\t"
-		     LOCK_PREFIX "  incl      (%%eax)\n\t"
+		     LOCK_PREFIX _ASM_INC "(%1)\n\t"
 		     /* adds 0x00000001, returns the old value */
 		     "  jns        1f\n"
 		     "  call call_rwsem_down_read_failed\n"
@@ -121,14 +133,14 @@ static inline void __down_read(struct rw
  */
 static inline int __down_read_trylock(struct rw_semaphore *sem)
 {
-	__s32 result, tmp;
+	rwsem_count_t result, tmp;
 	asm volatile("# beginning __down_read_trylock\n\t"
-		     "  movl      %0,%1\n\t"
+		     "  mov          %0,%1\n\t"
 		     "1:\n\t"
-		     "  movl	     %1,%2\n\t"
-		     "  addl      %3,%2\n\t"
+		     "  mov          %1,%2\n\t"
+		     "  add          %3,%2\n\t"
 		     "  jle	     2f\n\t"
-		     LOCK_PREFIX "  cmpxchgl  %2,%0\n\t"
+		     LOCK_PREFIX "  cmpxchg  %2,%0\n\t"
 		     "  jnz	     1b\n\t"
 		     "2:\n\t"
 		     "# ending __down_read_trylock\n\t"
@@ -143,13 +155,13 @@ static inline int __down_read_trylock(st
  */
 static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
 {
-	int tmp;
+	rwsem_count_t tmp;
 
 	tmp = RWSEM_ACTIVE_WRITE_BIAS;
 	asm volatile("# beginning down_write\n\t"
-		     LOCK_PREFIX "  xadd      %%edx,(%%eax)\n\t"
+		     LOCK_PREFIX "  xadd      %1,(%2)\n\t"
 		     /* subtract 0x0000ffff, returns the old value */
-		     "  testl     %%edx,%%edx\n\t"
+		     "  test      %1,%1\n\t"
 		     /* was the count 0 before? */
 		     "  jz        1f\n"
 		     "  call call_rwsem_down_write_failed\n"
@@ -170,9 +182,9 @@ static inline void __down_write(struct r
  */
 static inline int __down_write_trylock(struct rw_semaphore *sem)
 {
-	signed long ret = cmpxchg(&sem->count,
-				  RWSEM_UNLOCKED_VALUE,
-				  RWSEM_ACTIVE_WRITE_BIAS);
+	rwsem_count_t ret = cmpxchg(&sem->count,
+				    RWSEM_UNLOCKED_VALUE,
+				    RWSEM_ACTIVE_WRITE_BIAS);
 	if (ret == RWSEM_UNLOCKED_VALUE)
 		return 1;
 	return 0;
@@ -183,9 +195,9 @@ static inline int __down_write_trylock(s
  */
 static inline void __up_read(struct rw_semaphore *sem)
 {
-	__s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
+	rwsem_count_t tmp = -RWSEM_ACTIVE_READ_BIAS;
 	asm volatile("# beginning __up_read\n\t"
-		     LOCK_PREFIX "  xadd      %%edx,(%%eax)\n\t"
+		     LOCK_PREFIX "  xadd      %1,(%2)\n\t"
 		     /* subtracts 1, returns the old value */
 		     "  jns        1f\n\t"
 		     "  call call_rwsem_wake\n"
@@ -201,18 +213,18 @@ static inline void __up_read(struct rw_s
  */
 static inline void __up_write(struct rw_semaphore *sem)
 {
+	rwsem_count_t tmp;
 	asm volatile("# beginning __up_write\n\t"
-		     "  movl      %2,%%edx\n\t"
-		     LOCK_PREFIX "  xaddl     %%edx,(%%eax)\n\t"
+		     LOCK_PREFIX "  xadd      %1,(%2)\n\t"
 		     /* tries to transition
 			0xffff0001 -> 0x00000000 */
 		     "  jz       1f\n"
 		     "  call call_rwsem_wake\n"
 		     "1:\n\t"
 		     "# ending __up_write\n"
-		     : "+m" (sem->count)
-		     : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS)
-		     : "memory", "cc", "edx");
+		     : "+m" (sem->count), "=d" (tmp)
+		     : "a" (sem), "1" (-RWSEM_ACTIVE_WRITE_BIAS)
+		     : "memory", "cc");
 }
 
 /*
@@ -221,33 +233,38 @@ static inline void __up_write(struct rw_
 static inline void __downgrade_write(struct rw_semaphore *sem)
 {
 	asm volatile("# beginning __downgrade_write\n\t"
-		     LOCK_PREFIX "  addl      %2,(%%eax)\n\t"
-		     /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
+		     LOCK_PREFIX _ASM_ADD "%2,(%1)\n\t"
+		     /*
+		      * transitions 0xZZZZ0001 -> 0xYYYY0001 (i386)
+		      *     0xZZZZZZZZ00000001 -> 0xYYYYYYYY00000001 (x86_64)
+		      */
 		     "  jns       1f\n\t"
 		     "  call call_rwsem_downgrade_wake\n"
 		     "1:\n\t"
 		     "# ending __downgrade_write\n"
 		     : "+m" (sem->count)
-		     : "a" (sem), "i" (-RWSEM_WAITING_BIAS)
+		     : "a" (sem), "er" (-RWSEM_WAITING_BIAS)
 		     : "memory", "cc");
 }
 
 /*
  * implement atomic add functionality
  */
-static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
+static inline void rwsem_atomic_add(rwsem_count_t delta,
+				    struct rw_semaphore *sem)
 {
-	asm volatile(LOCK_PREFIX "addl %1,%0"
+	asm volatile(LOCK_PREFIX _ASM_ADD "%1,%0"
 		     : "+m" (sem->count)
-		     : "ir" (delta));
+		     : "er" (delta));
 }
 
 /*
  * implement exchange and add functionality
  */
-static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
+static inline rwsem_count_t rwsem_atomic_update(rwsem_count_t delta,
+						struct rw_semaphore *sem)
 {
-	int tmp = delta;
+	rwsem_count_t tmp = delta;
 
 	asm volatile(LOCK_PREFIX "xadd %0,%1"
 		     : "+r" (tmp), "+m" (sem->count)
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/setup.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/setup.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/setup.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/setup.h	2010-05-16 17:17:36.000000000 -0400
@@ -37,10 +37,8 @@ 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 unsigned long saved_video_mode;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/smp.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/smp.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/smp.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/smp.h	2010-05-16 17:17:36.000000000 -0400
@@ -135,6 +135,8 @@ int native_cpu_disable(void);
 void native_cpu_die(unsigned int cpu);
 void native_play_dead(void);
 void play_dead_common(void);
+void wbinvd_on_cpu(int cpu);
+int wbinvd_on_all_cpus(void);
 
 void native_send_call_func_ipi(const struct cpumask *mask);
 void native_send_call_func_single_ipi(int cpu);
@@ -147,6 +149,13 @@ static inline int num_booting_cpus(void)
 {
 	return cpumask_weight(cpu_callout_mask);
 }
+#else /* !CONFIG_SMP */
+#define wbinvd_on_cpu(cpu)     wbinvd()
+static inline int wbinvd_on_all_cpus(void)
+{
+	wbinvd();
+	return 0;
+}
 #endif /* CONFIG_SMP */
 
 extern unsigned disabled_cpus __cpuinitdata;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/stacktrace.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/stacktrace.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/stacktrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/stacktrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -3,8 +3,6 @@
 
 extern int kstack_depth_to_print;
 
-int x86_is_stack_id(int id, char *name);
-
 struct thread_info;
 struct stacktrace_ops;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/svm.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/svm.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/svm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/svm.h	2010-05-16 17:17:36.000000000 -0400
@@ -313,7 +313,7 @@ struct __attribute__ ((__packed__)) vmcb
 
 #define SVM_EXIT_ERR		-1
 
-#define SVM_CR0_SELECTIVE_MASK (1 << 3 | 1) /* TS and MP */
+#define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP)
 
 #define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda"
 #define SVM_VMRUN  ".byte 0x0f, 0x01, 0xd8"
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/syscall.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/syscall.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/syscall.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/syscall.h	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,8 @@
 #include <linux/sched.h>
 #include <linux/err.h>
 
+extern const unsigned long sys_call_table[];
+
 /*
  * Only the low 32 bits of orig_ax are meaningful, so we return int.
  * This importantly ignores the high bits on 64-bit, so comparisons
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/syscalls.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/syscalls.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/syscalls.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/syscalls.h	2010-05-16 17:17:36.000000000 -0400
@@ -50,18 +50,6 @@ asmlinkage int sys_sigaction(int, const
 			     struct old_sigaction __user *);
 unsigned long sys_sigreturn(struct pt_regs *);
 
-/* kernel/sys_i386_32.c */
-struct mmap_arg_struct;
-struct sel_arg_struct;
-struct oldold_utsname;
-struct old_utsname;
-
-asmlinkage int old_mmap(struct mmap_arg_struct __user *);
-asmlinkage int old_select(struct sel_arg_struct __user *);
-asmlinkage int sys_ipc(uint, int, int, int, void __user *, long);
-asmlinkage int sys_uname(struct old_utsname __user *);
-asmlinkage int sys_olduname(struct oldold_utsname __user *);
-
 /* kernel/vm86_32.c */
 int sys_vm86old(struct vm86_struct __user *, struct pt_regs *);
 int sys_vm86(unsigned long, unsigned long, struct pt_regs *);
@@ -73,11 +61,8 @@ int sys_vm86(unsigned long, unsigned lon
 long sys_arch_prctl(int, unsigned long);
 
 /* kernel/sys_x86_64.c */
-struct new_utsname;
-
 asmlinkage long sys_mmap(unsigned long, unsigned long, unsigned long,
 			 unsigned long, unsigned long, unsigned long);
-asmlinkage long sys_uname(struct new_utsname __user *);
 
 #endif /* CONFIG_X86_32 */
 #endif /* _ASM_X86_SYSCALLS_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/sys_ia32.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/sys_ia32.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/sys_ia32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/sys_ia32.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,8 +26,8 @@ asmlinkage long sys32_lstat64(char __use
 asmlinkage long sys32_fstat64(unsigned int, struct stat64 __user *);
 asmlinkage long sys32_fstatat(unsigned int, char __user *,
 			      struct stat64 __user *, int);
-struct mmap_arg_struct;
-asmlinkage long sys32_mmap(struct mmap_arg_struct __user *);
+struct mmap_arg_struct32;
+asmlinkage long sys32_mmap(struct mmap_arg_struct32 __user *);
 asmlinkage long sys32_mprotect(unsigned long, size_t, unsigned long);
 
 struct sigaction32;
@@ -40,8 +40,6 @@ asmlinkage long sys32_rt_sigprocmask(int
 				     compat_sigset_t __user *, unsigned int);
 asmlinkage long sys32_alarm(unsigned int);
 
-struct sel_arg_struct;
-asmlinkage long sys32_old_select(struct sel_arg_struct __user *);
 asmlinkage long sys32_waitpid(compat_pid_t, unsigned int *, int);
 asmlinkage long sys32_sysfs(int, u32, u32);
 
@@ -56,11 +54,6 @@ asmlinkage long sys32_pwrite(unsigned in
 asmlinkage long sys32_personality(unsigned long);
 asmlinkage long sys32_sendfile(int, int, compat_off_t __user *, s32);
 
-struct oldold_utsname;
-struct old_utsname;
-asmlinkage long sys32_olduname(struct oldold_utsname __user *);
-long sys32_uname(struct old_utsname __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.33-gnu1/arch/x86/include/asm/system.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/system.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/system.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/system.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,7 @@ extern void show_regs_common(void);
 	"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.canary))
+	, [stack_canary] "=m" (stack_canary.canary)
 #define __switch_canary_iparam						\
 	, [task_canary] "i" (offsetof(struct task_struct, stack_canary))
 #else	/* CC_STACKPROTECTOR */
@@ -114,7 +114,7 @@ do {									\
 	"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))
+	, [gs_canary] "=m" (irq_stack_union.stack_canary)
 #define __switch_canary_iparam						  \
 	, [task_canary] "i" (offsetof(struct task_struct, stack_canary))
 #else	/* CC_STACKPROTECTOR */
@@ -133,7 +133,7 @@ do {									\
 	     __switch_canary						  \
 	     "movq %P[thread_info](%%rsi),%%r8\n\t"			  \
 	     "movq %%rax,%%rdi\n\t" 					  \
-	     "testl  %[_tif_fork],%P[ti_flags](%%r8)\n\t"	  \
+	     "testl  %[_tif_fork],%P[ti_flags](%%r8)\n\t"		  \
 	     "jnz   ret_from_fork\n\t"					  \
 	     RESTORE_CONTEXT						  \
 	     : "=a" (last)					  	  \
@@ -143,7 +143,7 @@ do {									\
 	       [ti_flags] "i" (offsetof(struct thread_info, flags)),	  \
 	       [_tif_fork] "i" (_TIF_FORK),			  	  \
 	       [thread_info] "i" (offsetof(struct task_struct, stack)),   \
-	       [current_task] "m" (per_cpu_var(current_task))		  \
+	       [current_task] "m" (current_task)			  \
 	       __switch_canary_iparam					  \
 	     : "memory", "cc" __EXTRA_CLOBBER)
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/uaccess_64.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/uaccess_64.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/uaccess_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/uaccess_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,8 @@
 #include <linux/errno.h>
 #include <linux/prefetch.h>
 #include <linux/lockdep.h>
+#include <asm/alternative.h>
+#include <asm/cpufeature.h>
 #include <asm/page.h>
 
 /*
@@ -16,7 +18,24 @@
 
 /* Handles exceptions in both to and from, but doesn't do access_ok */
 __must_check unsigned long
-copy_user_generic(void *to, const void *from, unsigned len);
+copy_user_generic_string(void *to, const void *from, unsigned len);
+__must_check unsigned long
+copy_user_generic_unrolled(void *to, const void *from, unsigned len);
+
+static __always_inline __must_check unsigned long
+copy_user_generic(void *to, const void *from, unsigned len)
+{
+	unsigned ret;
+
+	alternative_call(copy_user_generic_unrolled,
+			 copy_user_generic_string,
+			 X86_FEATURE_REP_GOOD,
+			 ASM_OUTPUT2("=a" (ret), "=D" (to), "=S" (from),
+				     "=d" (len)),
+			 "1" (to), "2" (from), "3" (len)
+			 : "memory", "rcx", "r8", "r9", "r10", "r11");
+	return ret;
+}
 
 __must_check unsigned long
 _copy_to_user(void __user *to, const void *from, unsigned len);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/unistd_32.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/unistd_32.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/unistd_32.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/unistd_32.h	2010-05-16 17:17:36.000000000 -0400
@@ -354,6 +354,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
@@ -366,6 +367,9 @@
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_UNAME
+#define __ARCH_WANT_SYS_OLD_MMAP
+#define __ARCH_WANT_SYS_OLD_SELECT
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/unistd_64.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/unistd_64.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/unistd_64.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/unistd_64.h	2010-05-16 17:17:36.000000000 -0400
@@ -146,7 +146,7 @@ __SYSCALL(__NR_wait4, sys_wait4)
 #define __NR_kill				62
 __SYSCALL(__NR_kill, sys_kill)
 #define __NR_uname				63
-__SYSCALL(__NR_uname, sys_uname)
+__SYSCALL(__NR_uname, sys_newuname)
 
 #define __NR_semget				64
 __SYSCALL(__NR_semget, sys_semget)
@@ -680,6 +680,7 @@ __SYSCALL(__NR_recvmmsg, sys_recvmmsg)
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_UNAME
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/user.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/user.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/user.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/user.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,63 @@
+#ifndef _ASM_X86_USER_H
+#define _ASM_X86_USER_H
+
 #ifdef CONFIG_X86_32
 # include "user_32.h"
 #else
 # include "user_64.h"
 #endif
+
+#include <asm/types.h>
+
+struct user_ymmh_regs {
+	/* 16 * 16 bytes for each YMMH-reg */
+	__u32 ymmh_space[64];
+};
+
+struct user_xsave_hdr {
+	__u64 xstate_bv;
+	__u64 reserved1[2];
+	__u64 reserved2[5];
+};
+
+/*
+ * The structure layout of user_xstateregs, used for exporting the
+ * extended register state through ptrace and core-dump (NT_X86_XSTATE note)
+ * interfaces will be same as the memory layout of xsave used by the processor
+ * (except for the bytes 464..511, which can be used by the software) and hence
+ * the size of this structure varies depending on the features supported by the
+ * processor and OS. The size of the structure that users need to use can be
+ * obtained by doing:
+ *     cpuid_count(0xd, 0, &eax, &ptrace_xstateregs_struct_size, &ecx, &edx);
+ * i.e., cpuid.(eax=0xd,ecx=0).ebx will be the size that user (debuggers, etc.)
+ * need to use.
+ *
+ * For now, only the first 8 bytes of the software usable bytes[464..471] will
+ * be used and will be set to OS enabled xstate mask (which is same as the
+ * 64bit mask returned by the xgetbv's xCR0).  Users (analyzing core dump
+ * remotely, etc.) can use this mask as well as the mask saved in the
+ * xstate_hdr bytes and interpret what states the processor/OS supports
+ * and what states are in modified/initialized conditions for the
+ * particular process/thread.
+ *
+ * Also when the user modifies certain state FP/SSE/etc through the
+ * ptrace interface, they must ensure that the xsave_hdr.xstate_bv
+ * bytes[512..519] of the memory layout are updated correspondingly.
+ * i.e., for example when FP state is modified to a non-init state,
+ * xsave_hdr.xstate_bv's bit 0 must be set to '1', when SSE is modified to
+ * non-init state, xsave_hdr.xstate_bv's bit 1 must to be set to '1', etc.
+ */
+#define USER_XSTATE_FX_SW_WORDS 6
+#define USER_XSTATE_XCR0_WORD	0
+
+struct user_xstateregs {
+	struct {
+		__u64 fpx_space[58];
+		__u64 xstate_fx_sw[USER_XSTATE_FX_SW_WORDS];
+	} i387;
+	struct user_xsave_hdr xsave_hdr;
+	struct user_ymmh_regs ymmh;
+	/* further processor state extensions go here */
+};
+
+#endif /* _ASM_X86_USER_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/uv/bios.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/uv/bios.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/uv/bios.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/uv/bios.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,8 +18,8 @@
  *  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) 2008 Silicon Graphics, Inc.  All Rights Reserved.
- *  Copyright (c) Russ Anderson
+ *  Copyright (c) 2008-2009 Silicon Graphics, Inc.  All Rights Reserved.
+ *  Copyright (c) Russ Anderson <rja@sgi.com>
  */
 
 #include <linux/rtc.h>
@@ -36,7 +36,8 @@ enum uv_bios_cmd {
 	UV_BIOS_WATCHLIST_ALLOC,
 	UV_BIOS_WATCHLIST_FREE,
 	UV_BIOS_MEMPROTECT,
-	UV_BIOS_GET_PARTITION_ADDR
+	UV_BIOS_GET_PARTITION_ADDR,
+	UV_BIOS_SET_LEGACY_VGA_TARGET
 };
 
 /*
@@ -89,13 +90,14 @@ extern s64 uv_bios_call(enum uv_bios_cmd
 extern s64 uv_bios_call_irqsave(enum uv_bios_cmd, u64, u64, u64, u64, u64);
 extern s64 uv_bios_call_reentrant(enum uv_bios_cmd, u64, u64, u64, u64, u64);
 
-extern s64 uv_bios_get_sn_info(int, int *, long *, long *, long *);
+extern s64 uv_bios_get_sn_info(int, int *, long *, long *, long *, long *);
 extern s64 uv_bios_freq_base(u64, u64 *);
 extern int uv_bios_mq_watchlist_alloc(unsigned long, unsigned int,
 					unsigned long *);
 extern int uv_bios_mq_watchlist_free(int, int);
 extern s64 uv_bios_change_memprotect(u64, u64, enum uv_memprotect);
 extern s64 uv_bios_reserved_page_pa(u64, u64 *, u64 *, u64 *);
+extern int uv_bios_set_legacy_vga_target(bool decode, int domain, int bus);
 
 extern void uv_bios_init(void);
 
@@ -104,6 +106,7 @@ extern int uv_type;
 extern long sn_partition_id;
 extern long sn_coherency_id;
 extern long sn_region_size;
+extern long system_serial_number;
 #define partition_coherence_id()	(sn_coherency_id)
 
 extern struct kobject *sgi_uv_kobj;	/* /sys/firmware/sgi_uv */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/uv/uv.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/uv/uv.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/uv/uv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/uv/uv.h	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@ struct mm_struct;
 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_nmi_init(void);
 extern void uv_system_init(void);
 extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
 						 struct mm_struct *mm,
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/uv/uv_hub.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/uv/uv_hub.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/uv/uv_hub.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/uv/uv_hub.h	2010-05-16 17:17:36.000000000 -0400
@@ -329,7 +329,8 @@ static inline unsigned long uv_read_glob
  */
 static inline unsigned long uv_global_gru_mmr_address(int pnode, unsigned long offset)
 {
-	return UV_GLOBAL_GRU_MMR_BASE | offset | (pnode << uv_hub_info->m_val);
+	return UV_GLOBAL_GRU_MMR_BASE | offset |
+		((unsigned long)pnode << uv_hub_info->m_val);
 }
 
 static inline void uv_write_global_mmr8(int pnode, unsigned long offset, unsigned char val)
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/visws/cobalt.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/visws/cobalt.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/visws/cobalt.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/visws/cobalt.h	2010-05-16 17:17:36.000000000 -0400
@@ -122,4 +122,6 @@ extern char visws_board_type;
 
 extern char visws_board_rev;
 
+extern int pci_visws_init(void);
+
 #endif /* _ASM_X86_VISWS_COBALT_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/vmx.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/vmx.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/vmx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/vmx.h	2010-05-16 17:17:36.000000000 -0400
@@ -53,6 +53,7 @@
  */
 #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
 #define SECONDARY_EXEC_ENABLE_EPT               0x00000002
+#define SECONDARY_EXEC_RDTSCP			0x00000008
 #define SECONDARY_EXEC_ENABLE_VPID              0x00000020
 #define SECONDARY_EXEC_WBINVD_EXITING		0x00000040
 #define SECONDARY_EXEC_UNRESTRICTED_GUEST	0x00000080
@@ -251,6 +252,7 @@ enum vmcs_field {
 #define EXIT_REASON_MSR_READ            31
 #define EXIT_REASON_MSR_WRITE           32
 #define EXIT_REASON_MWAIT_INSTRUCTION   36
+#define EXIT_REASON_MONITOR_INSTRUCTION 39
 #define EXIT_REASON_PAUSE_INSTRUCTION   40
 #define EXIT_REASON_MCE_DURING_VMENTRY	 41
 #define EXIT_REASON_TPR_BELOW_THRESHOLD 43
@@ -362,6 +364,7 @@ enum vmcs_field {
 #define VMX_EPTP_UC_BIT				(1ull << 8)
 #define VMX_EPTP_WB_BIT				(1ull << 14)
 #define VMX_EPT_2MB_PAGE_BIT			(1ull << 16)
+#define VMX_EPT_1GB_PAGE_BIT			(1ull << 17)
 #define VMX_EPT_EXTENT_INDIVIDUAL_BIT		(1ull << 24)
 #define VMX_EPT_EXTENT_CONTEXT_BIT		(1ull << 25)
 #define VMX_EPT_EXTENT_GLOBAL_BIT		(1ull << 26)
@@ -374,7 +377,7 @@ enum vmcs_field {
 #define VMX_EPT_READABLE_MASK			0x1ull
 #define VMX_EPT_WRITABLE_MASK			0x2ull
 #define VMX_EPT_EXECUTABLE_MASK			0x4ull
-#define VMX_EPT_IGMT_BIT    			(1ull << 6)
+#define VMX_EPT_IPAT_BIT    			(1ull << 6)
 
 #define VMX_EPT_IDENTITY_PAGETABLE_ADDR		0xfffbc000ul
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/x86_init.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/x86_init.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/x86_init.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/x86_init.h	2010-05-16 17:17:36.000000000 -0400
@@ -99,6 +99,20 @@ struct x86_init_iommu {
 };
 
 /**
+ * struct x86_init_pci - platform specific pci init functions
+ * @arch_init:			platform specific pci arch init call
+ * @init:			platform specific pci subsystem init
+ * @init_irq:			platform specific pci irq init
+ * @fixup_irqs:			platform specific pci irq fixup
+ */
+struct x86_init_pci {
+	int (*arch_init)(void);
+	int (*init)(void);
+	void (*init_irq)(void);
+	void (*fixup_irqs)(void);
+};
+
+/**
  * struct x86_init_ops - functions for platform specific setup
  *
  */
@@ -110,6 +124,7 @@ struct x86_init_ops {
 	struct x86_init_paging		paging;
 	struct x86_init_timers		timers;
 	struct x86_init_iommu		iommu;
+	struct x86_init_pci		pci;
 };
 
 /**
@@ -126,6 +141,7 @@ struct x86_cpuinit_ops {
  * @get_wallclock:		get time from HW clock like RTC etc.
  * @set_wallclock:		set time back to HW clock
  * @is_untracked_pat_range	exclude from PAT logic
+ * @nmi_init			enable NMI on cpus
  */
 struct x86_platform_ops {
 	unsigned long (*calibrate_tsc)(void);
@@ -133,6 +149,7 @@ struct x86_platform_ops {
 	int (*set_wallclock)(unsigned long nowtime);
 	void (*iommu_shutdown)(void);
 	bool (*is_untracked_pat_range)(u64 start, u64 end);
+	void (*nmi_init)(void);
 };
 
 extern struct x86_init_ops x86_init;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/include/asm/xsave.h linux-libre-2.6.34-gnu1/arch/x86/include/asm/xsave.h
--- linux-libre-2.6.33-gnu1/arch/x86/include/asm/xsave.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/include/asm/xsave.h	2010-05-16 17:17:36.000000000 -0400
@@ -27,9 +27,11 @@
 extern unsigned int xstate_size;
 extern u64 pcntxt_mask;
 extern struct xsave_struct *init_xstate_buf;
+extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS];
 
 extern void xsave_cntxt_init(void);
 extern void xsave_init(void);
+extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask);
 extern int init_fpu(struct task_struct *child);
 extern int check_for_xstate(struct i387_fxsave_struct __user *buf,
 			    void __user *fpstate,
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/Kconfig linux-libre-2.6.34-gnu1/arch/x86/Kconfig
--- linux-libre-2.6.33-gnu1/arch/x86/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@ config X86
 	select ARCH_WANT_FRAME_POINTERS
 	select HAVE_DMA_ATTRS
 	select HAVE_KRETPROBES
+	select HAVE_OPTPROBES
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_FUNCTION_TRACER
@@ -45,6 +46,7 @@ config X86
 	select HAVE_GENERIC_DMA_COHERENT if X86_32
 	select HAVE_EFFICIENT_UNALIGNED_ACCESS
 	select USER_STACKTRACE_SUPPORT
+	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_DMA_API_DEBUG
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_BZIP2
@@ -100,6 +102,9 @@ config ZONE_DMA
 config SBUS
 	bool
 
+config NEED_DMA_MAP_STATE
+       def_bool (X86_64 || DMAR || DMA_API_DEBUG)
+
 config GENERIC_ISA_DMA
 	def_bool y
 
@@ -183,6 +188,9 @@ config ARCH_SUPPORTS_OPTIMIZED_INLINING
 config ARCH_SUPPORTS_DEBUG_PAGEALLOC
 	def_bool y
 
+config HAVE_EARLY_RES
+	def_bool y
+
 config HAVE_INTEL_TXT
 	def_bool y
 	depends on EXPERIMENTAL && DMAR && ACPI
@@ -388,8 +396,12 @@ config X86_ELAN
 
 config X86_MRST
        bool "Moorestown MID platform"
+	depends on PCI
+	depends on PCI_GOANY
 	depends on X86_32
 	depends on X86_EXTENDED_PLATFORM
+	depends on X86_IO_APIC
+	select APB_TIMER
 	---help---
 	  Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin
 	  Internet Device(MID) platform. Moorestown consists of two chips:
@@ -424,6 +436,7 @@ config X86_32_NON_STANDARD
 config X86_NUMAQ
 	bool "NUMAQ (IBM/Sequent)"
 	depends on X86_32_NON_STANDARD
+	depends on PCI
 	select NUMA
 	select X86_MPPARSE
 	---help---
@@ -568,6 +581,18 @@ config PARAVIRT_DEBUG
 	  Enable to debug paravirt_ops internals.  Specifically, BUG if
 	  a paravirt_op is missing when it is called.
 
+config NO_BOOTMEM
+	default y
+	bool "Disable Bootmem code"
+	---help---
+	  Use early_res directly instead of bootmem before slab is ready.
+		- allocator (buddy) [generic]
+		- early allocator (bootmem) [generic]
+		- very early allocator (reserve_early*()) [x86]
+		- very very early allocator (early brk model) [x86]
+	  So reduce one layer between early allocator to final allocator
+
+
 config MEMTEST
 	bool "Memtest"
 	---help---
@@ -612,6 +637,16 @@ config HPET_EMULATE_RTC
 	def_bool y
 	depends on HPET_TIMER && (RTC=y || RTC=m || RTC_DRV_CMOS=m || RTC_DRV_CMOS=y)
 
+config APB_TIMER
+       def_bool y if MRST
+       prompt "Langwell APB Timer Support" if X86_MRST
+       help
+         APB timer is the replacement for 8254, HPET on X86 MID platforms.
+         The APBT provides a stable time base on SMP
+         systems, unlike the TSC, but it is more expensive to access,
+         as it is off-chip. APB timers are always running regardless of CPU
+         C states, they are used as per CPU clockevent device when possible.
+
 # Mark as embedded because too many people got it wrong.
 # The code disables itself when not needed.
 config DMI
@@ -627,7 +662,7 @@ config GART_IOMMU
 	bool "GART IOMMU support" if EMBEDDED
 	default y
 	select SWIOTLB
-	depends on X86_64 && PCI
+	depends on X86_64 && PCI && K8_NB
 	---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,
@@ -1181,8 +1216,8 @@ config NUMA_EMU
 
 config NODES_SHIFT
 	int "Maximum NUMA Nodes (as a power of 2)" if !MAXSMP
-	range 1 9
-	default "9" if MAXSMP
+	range 1 10
+	default "10" if MAXSMP
 	default "6" if X86_64
 	default "4" if X86_NUMAQ
 	default "3"
@@ -2026,7 +2061,7 @@ endif # X86_32
 
 config K8_NB
 	def_bool y
-	depends on AGP_AMD64 || (X86_64 && (GART_IOMMU || (PCI && NUMA)))
+	depends on CPU_SUP_AMD && PCI
 
 source "drivers/pcmcia/Kconfig"
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/Kconfig.cpu linux-libre-2.6.34-gnu1/arch/x86/Kconfig.cpu
--- linux-libre-2.6.33-gnu1/arch/x86/Kconfig.cpu	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/Kconfig.cpu	2010-05-16 17:17:36.000000000 -0400
@@ -319,7 +319,7 @@ config X86_L1_CACHE_SHIFT
 
 config X86_XADD
 	def_bool y
-	depends on X86_32 && !M386
+	depends on X86_64 || !M386
 
 config X86_PPRO_FENCE
 	bool "PentiumPro memory ordering errata workaround"
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/acpi/boot.c linux-libre-2.6.34-gnu1/arch/x86/kernel/acpi/boot.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/acpi/boot.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/acpi/boot.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,10 +31,12 @@
 #include <linux/module.h>
 #include <linux/dmi.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <linux/bootmem.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
 
+#include <asm/pci_x86.h>
 #include <asm/pgtable.h>
 #include <asm/io_apic.h>
 #include <asm/apic.h>
@@ -49,6 +51,7 @@ EXPORT_SYMBOL(acpi_disabled);
 
 #ifdef	CONFIG_X86_64
 # include <asm/proto.h>
+# include <asm/numa_64.h>
 #endif				/* X86 */
 
 #define BAD_MADT_ENTRY(entry, end) (					    \
@@ -446,6 +449,12 @@ void __init acpi_pic_sci_set_trigger(uns
 int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 {
 	*irq = gsi;
+
+#ifdef CONFIG_X86_IO_APIC
+	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
+		setup_IO_APIC_irq_extra(gsi);
+#endif
+
 	return 0;
 }
 
@@ -473,7 +482,8 @@ int acpi_register_gsi(struct device *dev
 		plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
 	}
 #endif
-	acpi_gsi_to_irq(plat_gsi, &irq);
+	irq = plat_gsi;
+
 	return irq;
 }
 
@@ -481,6 +491,26 @@ int acpi_register_gsi(struct device *dev
  *  ACPI based hotplug support for CPU
  */
 #ifdef CONFIG_ACPI_HOTPLUG_CPU
+#include <acpi/processor.h>
+
+static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
+{
+#ifdef CONFIG_ACPI_NUMA
+	int nid;
+
+	nid = acpi_get_node(handle);
+	if (nid == -1 || !node_online(nid))
+		return;
+#ifdef CONFIG_X86_64
+	apicid_to_node[physid] = nid;
+	numa_set_node(cpu, nid);
+#else /* CONFIG_X86_32 */
+	apicid_2_node[physid] = nid;
+	cpu_to_node_map[cpu] = nid;
+#endif
+
+#endif
+}
 
 static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu)
 {
@@ -539,7 +569,10 @@ static int __cpuinit _acpi_map_lsapic(ac
 		goto free_new_map;
 	}
 
+	acpi_processor_set_pdc(handle);
+
 	cpu = cpumask_first(new_map);
+	acpi_map_cpu2node(handle, cpu, physid);
 
 	*pcpu = cpu;
 	retval = 0;
@@ -1264,23 +1297,6 @@ static int __init dmi_disable_acpi(const
 }
 
 /*
- * Limit ACPI to CPU enumeration for HT
- */
-static int __init force_acpi_ht(const struct dmi_system_id *d)
-{
-	if (!acpi_force) {
-		printk(KERN_NOTICE "%s detected: force use of acpi=ht\n",
-		       d->ident);
-		disable_acpi();
-		acpi_ht = 1;
-	} else {
-		printk(KERN_NOTICE
-		       "Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
-	}
-	return 0;
-}
-
-/*
  * Force ignoring BIOS IRQ0 pin2 override
  */
 static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d)
@@ -1316,82 +1332,6 @@ static struct dmi_system_id __initdata a
 	 },
 
 	/*
-	 * Boxes that need acpi=ht
-	 */
-	{
-	 .callback = force_acpi_ht,
-	 .ident = "FSC Primergy T850",
-	 .matches = {
-		     DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-		     DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
-		     },
-	 },
-	{
-	 .callback = force_acpi_ht,
-	 .ident = "HP VISUALIZE NT Workstation",
-	 .matches = {
-		     DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
-		     DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
-		     },
-	 },
-	{
-	 .callback = force_acpi_ht,
-	 .ident = "Compaq Workstation W8000",
-	 .matches = {
-		     DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
-		     DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
-		     },
-	 },
-	{
-	 .callback = force_acpi_ht,
-	 .ident = "ASUS CUR-DLS",
-	 .matches = {
-		     DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-		     DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"),
-		     },
-	 },
-	{
-	 .callback = force_acpi_ht,
-	 .ident = "ABIT i440BX-W83977",
-	 .matches = {
-		     DMI_MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
-		     DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
-		     },
-	 },
-	{
-	 .callback = force_acpi_ht,
-	 .ident = "IBM Bladecenter",
-	 .matches = {
-		     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
-		     DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
-		     },
-	 },
-	{
-	 .callback = force_acpi_ht,
-	 .ident = "IBM eServer xSeries 360",
-	 .matches = {
-		     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
-		     DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
-		     },
-	 },
-	{
-	 .callback = force_acpi_ht,
-	 .ident = "IBM eserver xSeries 330",
-	 .matches = {
-		     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
-		     DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
-		     },
-	 },
-	{
-	 .callback = force_acpi_ht,
-	 .ident = "IBM eserver xSeries 440",
-	 .matches = {
-		     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
-		     DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
-		     },
-	 },
-
-	/*
 	 * Boxes that need ACPI PCI IRQ routing disabled
 	 */
 	{
@@ -1596,6 +1536,9 @@ int __init acpi_boot_init(void)
 
 	acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet);
 
+	if (!acpi_noirq)
+		x86_init.pci.init = pci_acpi_init;
+
 	return 0;
 }
 
@@ -1620,8 +1563,10 @@ static int __init parse_acpi(char *arg)
 	}
 	/* Limit ACPI just to boot-time to enable HT */
 	else if (strcmp(arg, "ht") == 0) {
-		if (!acpi_force)
+		if (!acpi_force) {
+			printk(KERN_WARNING "acpi=ht will be removed in Linux-2.6.35\n");
 			disable_acpi();
+		}
 		acpi_ht = 1;
 	}
 	/* acpi=rsdt use RSDT instead of XSDT */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/alternative.c linux-libre-2.6.34-gnu1/arch/x86/kernel/alternative.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/alternative.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/alternative.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,8 @@
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/memory.h>
+#include <linux/stop_machine.h>
+#include <linux/slab.h>
 #include <asm/alternative.h>
 #include <asm/sections.h>
 #include <asm/pgtable.h>
@@ -205,7 +207,7 @@ void __init_or_module apply_alternatives
 					 struct alt_instr *end)
 {
 	struct alt_instr *a;
-	char insnbuf[MAX_PATCH_LEN];
+	u8 insnbuf[MAX_PATCH_LEN];
 
 	DPRINTK("%s: alt table %p -> %p\n", __func__, start, end);
 	for (a = start; a < end; a++) {
@@ -223,6 +225,8 @@ void __init_or_module apply_alternatives
 		}
 #endif
 		memcpy(insnbuf, a->replacement, a->replacementlen);
+		if (*insnbuf == 0xe8 && a->replacementlen == 5)
+		    *(s32 *)(insnbuf + 1) += a->replacement - a->instr;
 		add_nops(insnbuf + a->replacementlen,
 			 a->instrlen - a->replacementlen);
 		text_poke_early(instr, insnbuf, a->instrlen);
@@ -390,6 +394,24 @@ void alternatives_smp_switch(int smp)
 	mutex_unlock(&smp_alt);
 }
 
+/* Return 1 if the address range is reserved for smp-alternatives */
+int alternatives_text_reserved(void *start, void *end)
+{
+	struct smp_alt_module *mod;
+	u8 **ptr;
+	u8 *text_start = start;
+	u8 *text_end = end;
+
+	list_for_each_entry(mod, &smp_alt_modules, next) {
+		if (mod->text > text_end || mod->text_end < text_start)
+			continue;
+		for (ptr = mod->locks; ptr < mod->locks_end; ptr++)
+			if (text_start <= *ptr && text_end >= *ptr)
+				return 1;
+	}
+
+	return 0;
+}
 #endif
 
 #ifdef CONFIG_PARAVIRT
@@ -552,3 +574,62 @@ void *__kprobes text_poke(void *addr, co
 	local_irq_restore(flags);
 	return addr;
 }
+
+/*
+ * Cross-modifying kernel text with stop_machine().
+ * This code originally comes from immediate value.
+ */
+static atomic_t stop_machine_first;
+static int wrote_text;
+
+struct text_poke_params {
+	void *addr;
+	const void *opcode;
+	size_t len;
+};
+
+static int __kprobes stop_machine_text_poke(void *data)
+{
+	struct text_poke_params *tpp = data;
+
+	if (atomic_dec_and_test(&stop_machine_first)) {
+		text_poke(tpp->addr, tpp->opcode, tpp->len);
+		smp_wmb();	/* Make sure other cpus see that this has run */
+		wrote_text = 1;
+	} else {
+		while (!wrote_text)
+			cpu_relax();
+		smp_mb();	/* Load wrote_text before following execution */
+	}
+
+	flush_icache_range((unsigned long)tpp->addr,
+			   (unsigned long)tpp->addr + tpp->len);
+	return 0;
+}
+
+/**
+ * text_poke_smp - Update instructions on a live kernel on SMP
+ * @addr: address to modify
+ * @opcode: source of the copy
+ * @len: length to copy
+ *
+ * Modify multi-byte instruction by using stop_machine() on SMP. This allows
+ * user to poke/set multi-byte text on SMP. Only non-NMI/MCE code modifying
+ * should be allowed, since stop_machine() does _not_ protect code against
+ * NMI and MCE.
+ *
+ * Note: Must be called under get_online_cpus() and text_mutex.
+ */
+void *__kprobes text_poke_smp(void *addr, const void *opcode, size_t len)
+{
+	struct text_poke_params tpp;
+
+	tpp.addr = addr;
+	tpp.opcode = opcode;
+	tpp.len = len;
+	atomic_set(&stop_machine_first, 1);
+	wrote_text = 0;
+	stop_machine(stop_machine_text_poke, (void *)&tpp, NULL);
+	return addr;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/amd_iommu.c linux-libre-2.6.34-gnu1/arch/x86/kernel/amd_iommu.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/amd_iommu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/amd_iommu.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,8 +18,8 @@
  */
 
 #include <linux/pci.h>
-#include <linux/gfp.h>
 #include <linux/bitmap.h>
+#include <linux/slab.h>
 #include <linux/debugfs.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
@@ -118,7 +118,7 @@ static bool check_device(struct device *
 		return false;
 
 	/* No device or no PCI device */
-	if (!dev || dev->bus != &pci_bus_type)
+	if (dev->bus != &pci_bus_type)
 		return false;
 
 	devid = get_device_id(dev);
@@ -392,6 +392,7 @@ static int __iommu_queue_command(struct
 	u32 tail, head;
 	u8 *target;
 
+	WARN_ON(iommu->cmd_buf_size & CMD_BUFFER_UNINITIALIZED);
 	tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
 	target = iommu->cmd_buf + tail;
 	memcpy_toio(target, cmd, sizeof(*cmd));
@@ -2186,7 +2187,7 @@ static void prealloc_protection_domains(
 	struct dma_ops_domain *dma_dom;
 	u16 devid;
 
-	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	for_each_pci_dev(dev) {
 
 		/* Do we handle this device? */
 		if (!check_device(&dev->dev))
@@ -2298,7 +2299,7 @@ static void cleanup_domain(struct protec
 	list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) {
 		struct device *dev = dev_data->dev;
 
-		do_detach(dev);
+		__detach_device(dev);
 		atomic_set(&dev_data->bind, 0);
 	}
 
@@ -2327,6 +2328,7 @@ static struct protection_domain *protect
 		return NULL;
 
 	spin_lock_init(&domain->lock);
+	mutex_init(&domain->api_lock);
 	domain->id = domain_id_alloc();
 	if (!domain->id)
 		goto out_err;
@@ -2379,9 +2381,7 @@ static void amd_iommu_domain_destroy(str
 
 	free_pagetable(domain);
 
-	domain_id_free(domain->id);
-
-	kfree(domain);
+	protection_domain_free(domain);
 
 	dom->priv = NULL;
 }
@@ -2456,6 +2456,8 @@ static int amd_iommu_map_range(struct io
 	iova  &= PAGE_MASK;
 	paddr &= PAGE_MASK;
 
+	mutex_lock(&domain->api_lock);
+
 	for (i = 0; i < npages; ++i) {
 		ret = iommu_map_page(domain, iova, paddr, prot, PM_MAP_4k);
 		if (ret)
@@ -2465,6 +2467,8 @@ static int amd_iommu_map_range(struct io
 		paddr += PAGE_SIZE;
 	}
 
+	mutex_unlock(&domain->api_lock);
+
 	return 0;
 }
 
@@ -2477,12 +2481,16 @@ static void amd_iommu_unmap_range(struct
 
 	iova  &= PAGE_MASK;
 
+	mutex_lock(&domain->api_lock);
+
 	for (i = 0; i < npages; ++i) {
 		iommu_unmap_page(domain, iova, PM_MAP_4k);
 		iova  += PAGE_SIZE;
 	}
 
 	iommu_flush_tlb_pde(domain);
+
+	mutex_unlock(&domain->api_lock);
 }
 
 static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/amd_iommu_init.c linux-libre-2.6.34-gnu1/arch/x86/kernel/amd_iommu_init.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/amd_iommu_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/amd_iommu_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,8 +19,8 @@
 
 #include <linux/pci.h>
 #include <linux/acpi.h>
-#include <linux/gfp.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/sysdev.h>
 #include <linux/interrupt.h>
 #include <linux/msi.h>
@@ -138,9 +138,9 @@ int amd_iommus_present;
 bool amd_iommu_np_cache __read_mostly;
 
 /*
- * Set to true if ACPI table parsing and hardware intialization went properly
+ * The ACPI table parsing functions set this variable on an error
  */
-static bool amd_iommu_initialized;
+static int __initdata amd_iommu_init_err;
 
 /*
  * List of protection domains - used during resume
@@ -391,9 +391,11 @@ static int __init find_last_devid_acpi(s
 	 */
 	for (i = 0; i < table->length; ++i)
 		checksum += p[i];
-	if (checksum != 0)
+	if (checksum != 0) {
 		/* ACPI table corrupt */
-		return -ENODEV;
+		amd_iommu_init_err = -ENODEV;
+		return 0;
+	}
 
 	p += IVRS_HEADER_LENGTH;
 
@@ -436,7 +438,7 @@ static u8 * __init alloc_command_buffer(
 	if (cmd_buf == NULL)
 		return NULL;
 
-	iommu->cmd_buf_size = CMD_BUFFER_SIZE;
+	iommu->cmd_buf_size = CMD_BUFFER_SIZE | CMD_BUFFER_UNINITIALIZED;
 
 	return cmd_buf;
 }
@@ -472,12 +474,13 @@ static void iommu_enable_command_buffer(
 		    &entry, sizeof(entry));
 
 	amd_iommu_reset_cmd_buffer(iommu);
+	iommu->cmd_buf_size &= ~(CMD_BUFFER_UNINITIALIZED);
 }
 
 static void __init free_command_buffer(struct amd_iommu *iommu)
 {
 	free_pages((unsigned long)iommu->cmd_buf,
-		   get_order(iommu->cmd_buf_size));
+		   get_order(iommu->cmd_buf_size & ~(CMD_BUFFER_UNINITIALIZED)));
 }
 
 /* allocates the memory where the IOMMU will log its events to */
@@ -920,11 +923,16 @@ static int __init init_iommu_all(struct
 				    h->mmio_phys);
 
 			iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL);
-			if (iommu == NULL)
-				return -ENOMEM;
+			if (iommu == NULL) {
+				amd_iommu_init_err = -ENOMEM;
+				return 0;
+			}
+
 			ret = init_iommu_one(iommu, h);
-			if (ret)
-				return ret;
+			if (ret) {
+				amd_iommu_init_err = ret;
+				return 0;
+			}
 			break;
 		default:
 			break;
@@ -934,8 +942,6 @@ static int __init init_iommu_all(struct
 	}
 	WARN_ON(p != end);
 
-	amd_iommu_initialized = true;
-
 	return 0;
 }
 
@@ -1211,6 +1217,10 @@ static int __init amd_iommu_init(void)
 	if (acpi_table_parse("IVRS", find_last_devid_acpi) != 0)
 		return -ENODEV;
 
+	ret = amd_iommu_init_err;
+	if (ret)
+		goto out;
+
 	dev_table_size     = tbl_size(DEV_TABLE_ENTRY_SIZE);
 	alias_table_size   = tbl_size(ALIAS_TABLE_ENTRY_SIZE);
 	rlookup_table_size = tbl_size(RLOOKUP_TABLE_ENTRY_SIZE);
@@ -1270,12 +1280,19 @@ static int __init amd_iommu_init(void)
 	if (acpi_table_parse("IVRS", init_iommu_all) != 0)
 		goto free;
 
-	if (!amd_iommu_initialized)
+	if (amd_iommu_init_err) {
+		ret = amd_iommu_init_err;
 		goto free;
+	}
 
 	if (acpi_table_parse("IVRS", init_memory_definitions) != 0)
 		goto free;
 
+	if (amd_iommu_init_err) {
+		ret = amd_iommu_init_err;
+		goto free;
+	}
+
 	ret = sysdev_class_register(&amd_iommu_sysdev_class);
 	if (ret)
 		goto free;
@@ -1288,6 +1305,8 @@ static int __init amd_iommu_init(void)
 	if (ret)
 		goto free;
 
+	enable_iommus();
+
 	if (iommu_pass_through)
 		ret = amd_iommu_init_passthrough();
 	else
@@ -1300,8 +1319,6 @@ static int __init amd_iommu_init(void)
 
 	amd_iommu_init_notifier();
 
-	enable_iommus();
-
 	if (iommu_pass_through)
 		goto out;
 
@@ -1315,6 +1332,7 @@ out:
 	return ret;
 
 free:
+	disable_iommus();
 
 	amd_iommu_uninit_devices();
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/apb_timer.c linux-libre-2.6.34-gnu1/arch/x86/kernel/apb_timer.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/apb_timer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/apb_timer.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,785 @@
+/*
+ * apb_timer.c: Driver for Langwell APB timers
+ *
+ * (C) Copyright 2009 Intel Corporation
+ * Author: Jacob Pan (jacob.jun.pan@intel.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ *
+ * Note:
+ * Langwell is the south complex of Intel Moorestown MID platform. There are
+ * eight external timers in total that can be used by the operating system.
+ * The timer information, such as frequency and addresses, is provided to the
+ * OS via SFI tables.
+ * Timer interrupts are routed via FW/HW emulated IOAPIC independently via
+ * individual redirection table entries (RTE).
+ * Unlike HPET, there is no master counter, therefore one of the timers are
+ * used as clocksource. The overall allocation looks like:
+ *  - timer 0 - NR_CPUs for per cpu timer
+ *  - one timer for clocksource
+ *  - one timer for watchdog driver.
+ * It is also worth notice that APB timer does not support true one-shot mode,
+ * free-running mode will be used here to emulate one-shot mode.
+ * APB timer can also be used as broadcast timer along with per cpu local APIC
+ * timer, but by default APB timer has higher rating than local APIC timers.
+ */
+
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/slab.h>
+#include <linux/pm.h>
+#include <linux/pci.h>
+#include <linux/sfi.h>
+#include <linux/interrupt.h>
+#include <linux/cpu.h>
+#include <linux/irq.h>
+
+#include <asm/fixmap.h>
+#include <asm/apb_timer.h>
+
+#define APBT_MASK			CLOCKSOURCE_MASK(32)
+#define APBT_SHIFT			22
+#define APBT_CLOCKEVENT_RATING		150
+#define APBT_CLOCKSOURCE_RATING		250
+#define APBT_MIN_DELTA_USEC		200
+
+#define EVT_TO_APBT_DEV(evt) container_of(evt, struct apbt_dev, evt)
+#define APBT_CLOCKEVENT0_NUM   (0)
+#define APBT_CLOCKEVENT1_NUM   (1)
+#define APBT_CLOCKSOURCE_NUM   (2)
+
+static unsigned long apbt_address;
+static int apb_timer_block_enabled;
+static void __iomem *apbt_virt_address;
+static int phy_cs_timer_id;
+
+/*
+ * Common DW APB timer info
+ */
+static uint64_t apbt_freq;
+
+static void apbt_set_mode(enum clock_event_mode mode,
+			  struct clock_event_device *evt);
+static int apbt_next_event(unsigned long delta,
+			   struct clock_event_device *evt);
+static cycle_t apbt_read_clocksource(struct clocksource *cs);
+static void apbt_restart_clocksource(struct clocksource *cs);
+
+struct apbt_dev {
+	struct clock_event_device evt;
+	unsigned int num;
+	int cpu;
+	unsigned int irq;
+	unsigned int tick;
+	unsigned int count;
+	unsigned int flags;
+	char name[10];
+};
+
+int disable_apbt_percpu __cpuinitdata;
+
+static DEFINE_PER_CPU(struct apbt_dev, cpu_apbt_dev);
+
+#ifdef CONFIG_SMP
+static unsigned int apbt_num_timers_used;
+static struct apbt_dev *apbt_devs;
+#endif
+
+static	inline unsigned long apbt_readl_reg(unsigned long a)
+{
+	return readl(apbt_virt_address + a);
+}
+
+static inline void apbt_writel_reg(unsigned long d, unsigned long a)
+{
+	writel(d, apbt_virt_address + a);
+}
+
+static inline unsigned long apbt_readl(int n, unsigned long a)
+{
+	return readl(apbt_virt_address + a + n * APBTMRS_REG_SIZE);
+}
+
+static inline void apbt_writel(int n, unsigned long d, unsigned long a)
+{
+	writel(d, apbt_virt_address + a + n * APBTMRS_REG_SIZE);
+}
+
+static inline void apbt_set_mapping(void)
+{
+	struct sfi_timer_table_entry *mtmr;
+
+	if (apbt_virt_address) {
+		pr_debug("APBT base already mapped\n");
+		return;
+	}
+	mtmr = sfi_get_mtmr(APBT_CLOCKEVENT0_NUM);
+	if (mtmr == NULL) {
+		printk(KERN_ERR "Failed to get MTMR %d from SFI\n",
+		       APBT_CLOCKEVENT0_NUM);
+		return;
+	}
+	apbt_address = (unsigned long)mtmr->phys_addr;
+	if (!apbt_address) {
+		printk(KERN_WARNING "No timer base from SFI, use default\n");
+		apbt_address = APBT_DEFAULT_BASE;
+	}
+	apbt_virt_address = ioremap_nocache(apbt_address, APBT_MMAP_SIZE);
+	if (apbt_virt_address) {
+		pr_debug("Mapped APBT physical addr %p at virtual addr %p\n",\
+			 (void *)apbt_address, (void *)apbt_virt_address);
+	} else {
+		pr_debug("Failed mapping APBT phy address at %p\n",\
+			 (void *)apbt_address);
+		goto panic_noapbt;
+	}
+	apbt_freq = mtmr->freq_hz / USEC_PER_SEC;
+	sfi_free_mtmr(mtmr);
+
+	/* Now figure out the physical timer id for clocksource device */
+	mtmr = sfi_get_mtmr(APBT_CLOCKSOURCE_NUM);
+	if (mtmr == NULL)
+		goto panic_noapbt;
+
+	/* Now figure out the physical timer id */
+	phy_cs_timer_id = (unsigned int)(mtmr->phys_addr & 0xff)
+		/ APBTMRS_REG_SIZE;
+	pr_debug("Use timer %d for clocksource\n", phy_cs_timer_id);
+	return;
+
+panic_noapbt:
+	panic("Failed to setup APB system timer\n");
+
+}
+
+static inline void apbt_clear_mapping(void)
+{
+	iounmap(apbt_virt_address);
+	apbt_virt_address = NULL;
+}
+
+/*
+ * APBT timer interrupt enable / disable
+ */
+static inline int is_apbt_capable(void)
+{
+	return apbt_virt_address ? 1 : 0;
+}
+
+static struct clocksource clocksource_apbt = {
+	.name		= "apbt",
+	.rating		= APBT_CLOCKSOURCE_RATING,
+	.read		= apbt_read_clocksource,
+	.mask		= APBT_MASK,
+	.shift		= APBT_SHIFT,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+	.resume		= apbt_restart_clocksource,
+};
+
+/* boot APB clock event device */
+static struct clock_event_device apbt_clockevent = {
+	.name		= "apbt0",
+	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_mode	= apbt_set_mode,
+	.set_next_event = apbt_next_event,
+	.shift		= APBT_SHIFT,
+	.irq		= 0,
+	.rating		= APBT_CLOCKEVENT_RATING,
+};
+
+/*
+ * if user does not want to use per CPU apb timer, just give it a lower rating
+ * than local apic timer and skip the late per cpu timer init.
+ */
+static inline int __init setup_x86_mrst_timer(char *arg)
+{
+	if (!arg)
+		return -EINVAL;
+
+	if (strcmp("apbt_only", arg) == 0)
+		disable_apbt_percpu = 0;
+	else if (strcmp("lapic_and_apbt", arg) == 0)
+		disable_apbt_percpu = 1;
+	else {
+		pr_warning("X86 MRST timer option %s not recognised"
+			   " use x86_mrst_timer=apbt_only or lapic_and_apbt\n",
+			   arg);
+		return -EINVAL;
+	}
+	return 0;
+}
+__setup("x86_mrst_timer=", setup_x86_mrst_timer);
+
+/*
+ * start count down from 0xffff_ffff. this is done by toggling the enable bit
+ * then load initial load count to ~0.
+ */
+static void apbt_start_counter(int n)
+{
+	unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
+
+	ctrl &= ~APBTMR_CONTROL_ENABLE;
+	apbt_writel(n, ctrl, APBTMR_N_CONTROL);
+	apbt_writel(n, ~0, APBTMR_N_LOAD_COUNT);
+	/* enable, mask interrupt */
+	ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
+	ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT);
+	apbt_writel(n, ctrl, APBTMR_N_CONTROL);
+	/* read it once to get cached counter value initialized */
+	apbt_read_clocksource(&clocksource_apbt);
+}
+
+static irqreturn_t apbt_interrupt_handler(int irq, void *data)
+{
+	struct apbt_dev *dev = (struct apbt_dev *)data;
+	struct clock_event_device *aevt = &dev->evt;
+
+	if (!aevt->event_handler) {
+		printk(KERN_INFO "Spurious APBT timer interrupt on %d\n",
+		       dev->num);
+		return IRQ_NONE;
+	}
+	aevt->event_handler(aevt);
+	return IRQ_HANDLED;
+}
+
+static void apbt_restart_clocksource(struct clocksource *cs)
+{
+	apbt_start_counter(phy_cs_timer_id);
+}
+
+/* Setup IRQ routing via IOAPIC */
+#ifdef CONFIG_SMP
+static void apbt_setup_irq(struct apbt_dev *adev)
+{
+	struct irq_chip *chip;
+	struct irq_desc *desc;
+
+	/* timer0 irq has been setup early */
+	if (adev->irq == 0)
+		return;
+	desc = irq_to_desc(adev->irq);
+	chip = get_irq_chip(adev->irq);
+	disable_irq(adev->irq);
+	desc->status |= IRQ_MOVE_PCNTXT;
+	irq_set_affinity(adev->irq, cpumask_of(adev->cpu));
+	/* APB timer irqs are set up as mp_irqs, timer is edge triggerred */
+	set_irq_chip_and_handler_name(adev->irq, chip, handle_edge_irq, "edge");
+	enable_irq(adev->irq);
+	if (system_state == SYSTEM_BOOTING)
+		if (request_irq(adev->irq, apbt_interrupt_handler,
+				IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
+				adev->name, adev)) {
+			printk(KERN_ERR "Failed request IRQ for APBT%d\n",
+			       adev->num);
+		}
+}
+#endif
+
+static void apbt_enable_int(int n)
+{
+	unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
+	/* clear pending intr */
+	apbt_readl(n, APBTMR_N_EOI);
+	ctrl &= ~APBTMR_CONTROL_INT;
+	apbt_writel(n, ctrl, APBTMR_N_CONTROL);
+}
+
+static void apbt_disable_int(int n)
+{
+	unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
+
+	ctrl |= APBTMR_CONTROL_INT;
+	apbt_writel(n, ctrl, APBTMR_N_CONTROL);
+}
+
+
+static int __init apbt_clockevent_register(void)
+{
+	struct sfi_timer_table_entry *mtmr;
+	struct apbt_dev *adev = &__get_cpu_var(cpu_apbt_dev);
+
+	mtmr = sfi_get_mtmr(APBT_CLOCKEVENT0_NUM);
+	if (mtmr == NULL) {
+		printk(KERN_ERR "Failed to get MTMR %d from SFI\n",
+		       APBT_CLOCKEVENT0_NUM);
+		return -ENODEV;
+	}
+
+	/*
+	 * We need to calculate the scaled math multiplication factor for
+	 * nanosecond to apbt tick conversion.
+	 * mult = (nsec/cycle)*2^APBT_SHIFT
+	 */
+	apbt_clockevent.mult = div_sc((unsigned long) mtmr->freq_hz
+				      , NSEC_PER_SEC, APBT_SHIFT);
+
+	/* Calculate the min / max delta */
+	apbt_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
+							   &apbt_clockevent);
+	apbt_clockevent.min_delta_ns = clockevent_delta2ns(
+		APBT_MIN_DELTA_USEC*apbt_freq,
+		&apbt_clockevent);
+	/*
+	 * Start apbt with the boot cpu mask and make it
+	 * global if not used for per cpu timer.
+	 */
+	apbt_clockevent.cpumask = cpumask_of(smp_processor_id());
+	adev->num = smp_processor_id();
+	memcpy(&adev->evt, &apbt_clockevent, sizeof(struct clock_event_device));
+
+	if (disable_apbt_percpu) {
+		apbt_clockevent.rating = APBT_CLOCKEVENT_RATING - 100;
+		global_clock_event = &adev->evt;
+		printk(KERN_DEBUG "%s clockevent registered as global\n",
+		       global_clock_event->name);
+	}
+
+	if (request_irq(apbt_clockevent.irq, apbt_interrupt_handler,
+			IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
+			apbt_clockevent.name, adev)) {
+		printk(KERN_ERR "Failed request IRQ for APBT%d\n",
+		       apbt_clockevent.irq);
+	}
+
+	clockevents_register_device(&adev->evt);
+	/* Start APBT 0 interrupts */
+	apbt_enable_int(APBT_CLOCKEVENT0_NUM);
+
+	sfi_free_mtmr(mtmr);
+	return 0;
+}
+
+#ifdef CONFIG_SMP
+/* Should be called with per cpu */
+void apbt_setup_secondary_clock(void)
+{
+	struct apbt_dev *adev;
+	struct clock_event_device *aevt;
+	int cpu;
+
+	/* Don't register boot CPU clockevent */
+	cpu = smp_processor_id();
+	if (cpu == boot_cpu_id)
+		return;
+	/*
+	 * We need to calculate the scaled math multiplication factor for
+	 * nanosecond to apbt tick conversion.
+	 * mult = (nsec/cycle)*2^APBT_SHIFT
+	 */
+	printk(KERN_INFO "Init per CPU clockevent %d\n", cpu);
+	adev = &per_cpu(cpu_apbt_dev, cpu);
+	aevt = &adev->evt;
+
+	memcpy(aevt, &apbt_clockevent, sizeof(*aevt));
+	aevt->cpumask = cpumask_of(cpu);
+	aevt->name = adev->name;
+	aevt->mode = CLOCK_EVT_MODE_UNUSED;
+
+	printk(KERN_INFO "Registering CPU %d clockevent device %s, mask %08x\n",
+	       cpu, aevt->name, *(u32 *)aevt->cpumask);
+
+	apbt_setup_irq(adev);
+
+	clockevents_register_device(aevt);
+
+	apbt_enable_int(cpu);
+
+	return;
+}
+
+/*
+ * this notify handler process CPU hotplug events. in case of S0i3, nonboot
+ * cpus are disabled/enabled frequently, for performance reasons, we keep the
+ * per cpu timer irq registered so that we do need to do free_irq/request_irq.
+ *
+ * TODO: it might be more reliable to directly disable percpu clockevent device
+ * without the notifier chain. currently, cpu 0 may get interrupts from other
+ * cpu timers during the offline process due to the ordering of notification.
+ * the extra interrupt is harmless.
+ */
+static int apbt_cpuhp_notify(struct notifier_block *n,
+			     unsigned long action, void *hcpu)
+{
+	unsigned long cpu = (unsigned long)hcpu;
+	struct apbt_dev *adev = &per_cpu(cpu_apbt_dev, cpu);
+
+	switch (action & 0xf) {
+	case CPU_DEAD:
+		apbt_disable_int(cpu);
+		if (system_state == SYSTEM_RUNNING)
+			pr_debug("skipping APBT CPU %lu offline\n", cpu);
+		else if (adev) {
+			pr_debug("APBT clockevent for cpu %lu offline\n", cpu);
+			free_irq(adev->irq, adev);
+		}
+		break;
+	default:
+		pr_debug(KERN_INFO "APBT notified %lu, no action\n", action);
+	}
+	return NOTIFY_OK;
+}
+
+static __init int apbt_late_init(void)
+{
+	if (disable_apbt_percpu || !apb_timer_block_enabled)
+		return 0;
+	/* This notifier should be called after workqueue is ready */
+	hotcpu_notifier(apbt_cpuhp_notify, -20);
+	return 0;
+}
+fs_initcall(apbt_late_init);
+#else
+
+void apbt_setup_secondary_clock(void) {}
+
+#endif /* CONFIG_SMP */
+
+static void apbt_set_mode(enum clock_event_mode mode,
+			  struct clock_event_device *evt)
+{
+	unsigned long ctrl;
+	uint64_t delta;
+	int timer_num;
+	struct apbt_dev *adev = EVT_TO_APBT_DEV(evt);
+
+	timer_num = adev->num;
+	pr_debug("%s CPU %d timer %d mode=%d\n",
+		 __func__, first_cpu(*evt->cpumask), timer_num, mode);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * apbt_clockevent.mult;
+		delta >>= apbt_clockevent.shift;
+		ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
+		ctrl |= APBTMR_CONTROL_MODE_PERIODIC;
+		apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+		/*
+		 * DW APB p. 46, have to disable timer before load counter,
+		 * may cause sync problem.
+		 */
+		ctrl &= ~APBTMR_CONTROL_ENABLE;
+		apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+		udelay(1);
+		pr_debug("Setting clock period %d for HZ %d\n", (int)delta, HZ);
+		apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT);
+		ctrl |= APBTMR_CONTROL_ENABLE;
+		apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+		break;
+		/* APB timer does not have one-shot mode, use free running mode */
+	case CLOCK_EVT_MODE_ONESHOT:
+		ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
+		/*
+		 * set free running mode, this mode will let timer reload max
+		 * timeout which will give time (3min on 25MHz clock) to rearm
+		 * the next event, therefore emulate the one-shot mode.
+		 */
+		ctrl &= ~APBTMR_CONTROL_ENABLE;
+		ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
+
+		apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+		/* write again to set free running mode */
+		apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+
+		/*
+		 * DW APB p. 46, load counter with all 1s before starting free
+		 * running mode.
+		 */
+		apbt_writel(timer_num, ~0, APBTMR_N_LOAD_COUNT);
+		ctrl &= ~APBTMR_CONTROL_INT;
+		ctrl |= APBTMR_CONTROL_ENABLE;
+		apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+		break;
+
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		apbt_disable_int(timer_num);
+		ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
+		ctrl &= ~APBTMR_CONTROL_ENABLE;
+		apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+		break;
+
+	case CLOCK_EVT_MODE_RESUME:
+		apbt_enable_int(timer_num);
+		break;
+	}
+}
+
+static int apbt_next_event(unsigned long delta,
+			   struct clock_event_device *evt)
+{
+	unsigned long ctrl;
+	int timer_num;
+
+	struct apbt_dev *adev = EVT_TO_APBT_DEV(evt);
+
+	timer_num = adev->num;
+	/* Disable timer */
+	ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
+	ctrl &= ~APBTMR_CONTROL_ENABLE;
+	apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+	/* write new count */
+	apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT);
+	ctrl |= APBTMR_CONTROL_ENABLE;
+	apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+	return 0;
+}
+
+/*
+ * APB timer clock is not in sync with pclk on Langwell, which translates to
+ * unreliable read value caused by sampling error. the error does not add up
+ * overtime and only happens when sampling a 0 as a 1 by mistake. so the time
+ * would go backwards. the following code is trying to prevent time traveling
+ * backwards. little bit paranoid.
+ */
+static cycle_t apbt_read_clocksource(struct clocksource *cs)
+{
+	unsigned long t0, t1, t2;
+	static unsigned long last_read;
+
+bad_count:
+	t1 = apbt_readl(phy_cs_timer_id,
+			APBTMR_N_CURRENT_VALUE);
+	t2 = apbt_readl(phy_cs_timer_id,
+			APBTMR_N_CURRENT_VALUE);
+	if (unlikely(t1 < t2)) {
+		pr_debug("APBT: read current count error %lx:%lx:%lx\n",
+			 t1, t2, t2 - t1);
+		goto bad_count;
+	}
+	/*
+	 * check against cached last read, makes sure time does not go back.
+	 * it could be a normal rollover but we will do tripple check anyway
+	 */
+	if (unlikely(t2 > last_read)) {
+		/* check if we have a normal rollover */
+		unsigned long raw_intr_status =
+			apbt_readl_reg(APBTMRS_RAW_INT_STATUS);
+		/*
+		 * cs timer interrupt is masked but raw intr bit is set if
+		 * rollover occurs. then we read EOI reg to clear it.
+		 */
+		if (raw_intr_status & (1 << phy_cs_timer_id)) {
+			apbt_readl(phy_cs_timer_id, APBTMR_N_EOI);
+			goto out;
+		}
+		pr_debug("APB CS going back %lx:%lx:%lx ",
+			 t2, last_read, t2 - last_read);
+bad_count_x3:
+		pr_debug(KERN_INFO "tripple check enforced\n");
+		t0 = apbt_readl(phy_cs_timer_id,
+				APBTMR_N_CURRENT_VALUE);
+		udelay(1);
+		t1 = apbt_readl(phy_cs_timer_id,
+				APBTMR_N_CURRENT_VALUE);
+		udelay(1);
+		t2 = apbt_readl(phy_cs_timer_id,
+				APBTMR_N_CURRENT_VALUE);
+		if ((t2 > t1) || (t1 > t0)) {
+			printk(KERN_ERR "Error: APB CS tripple check failed\n");
+			goto bad_count_x3;
+		}
+	}
+out:
+	last_read = t2;
+	return (cycle_t)~t2;
+}
+
+static int apbt_clocksource_register(void)
+{
+	u64 start, now;
+	cycle_t t1;
+
+	/* Start the counter, use timer 2 as source, timer 0/1 for event */
+	apbt_start_counter(phy_cs_timer_id);
+
+	/* Verify whether apbt counter works */
+	t1 = apbt_read_clocksource(&clocksource_apbt);
+	rdtscll(start);
+
+	/*
+	 * We don't know the TSC frequency yet, but waiting for
+	 * 200000 TSC cycles is safe:
+	 * 4 GHz == 50us
+	 * 1 GHz == 200us
+	 */
+	do {
+		rep_nop();
+		rdtscll(now);
+	} while ((now - start) < 200000UL);
+
+	/* APBT is the only always on clocksource, it has to work! */
+	if (t1 == apbt_read_clocksource(&clocksource_apbt))
+		panic("APBT counter not counting. APBT disabled\n");
+
+	/*
+	 * initialize and register APBT clocksource
+	 * convert that to ns/clock cycle
+	 * mult = (ns/c) * 2^APBT_SHIFT
+	 */
+	clocksource_apbt.mult = div_sc(MSEC_PER_SEC,
+				       (unsigned long) apbt_freq, APBT_SHIFT);
+	clocksource_register(&clocksource_apbt);
+
+	return 0;
+}
+
+/*
+ * Early setup the APBT timer, only use timer 0 for booting then switch to
+ * per CPU timer if possible.
+ * returns 1 if per cpu apbt is setup
+ * returns 0 if no per cpu apbt is chosen
+ * panic if set up failed, this is the only platform timer on Moorestown.
+ */
+void __init apbt_time_init(void)
+{
+#ifdef CONFIG_SMP
+	int i;
+	struct sfi_timer_table_entry *p_mtmr;
+	unsigned int percpu_timer;
+	struct apbt_dev *adev;
+#endif
+
+	if (apb_timer_block_enabled)
+		return;
+	apbt_set_mapping();
+	if (apbt_virt_address) {
+		pr_debug("Found APBT version 0x%lx\n",\
+			 apbt_readl_reg(APBTMRS_COMP_VERSION));
+	} else
+		goto out_noapbt;
+	/*
+	 * Read the frequency and check for a sane value, for ESL model
+	 * we extend the possible clock range to allow time scaling.
+	 */
+
+	if (apbt_freq < APBT_MIN_FREQ || apbt_freq > APBT_MAX_FREQ) {
+		pr_debug("APBT has invalid freq 0x%llx\n", apbt_freq);
+		goto out_noapbt;
+	}
+	if (apbt_clocksource_register()) {
+		pr_debug("APBT has failed to register clocksource\n");
+		goto out_noapbt;
+	}
+	if (!apbt_clockevent_register())
+		apb_timer_block_enabled = 1;
+	else {
+		pr_debug("APBT has failed to register clockevent\n");
+		goto out_noapbt;
+	}
+#ifdef CONFIG_SMP
+	/* kernel cmdline disable apb timer, so we will use lapic timers */
+	if (disable_apbt_percpu) {
+		printk(KERN_INFO "apbt: disabled per cpu timer\n");
+		return;
+	}
+	pr_debug("%s: %d CPUs online\n", __func__, num_online_cpus());
+	if (num_possible_cpus() <= sfi_mtimer_num) {
+		percpu_timer = 1;
+		apbt_num_timers_used = num_possible_cpus();
+	} else {
+		percpu_timer = 0;
+		apbt_num_timers_used = 1;
+		adev = &per_cpu(cpu_apbt_dev, 0);
+		adev->flags &= ~APBT_DEV_USED;
+	}
+	pr_debug("%s: %d APB timers used\n", __func__, apbt_num_timers_used);
+
+	/* here we set up per CPU timer data structure */
+	apbt_devs = kzalloc(sizeof(struct apbt_dev) * apbt_num_timers_used,
+			    GFP_KERNEL);
+	if (!apbt_devs) {
+		printk(KERN_ERR "Failed to allocate APB timer devices\n");
+		return;
+	}
+	for (i = 0; i < apbt_num_timers_used; i++) {
+		adev = &per_cpu(cpu_apbt_dev, i);
+		adev->num = i;
+		adev->cpu = i;
+		p_mtmr = sfi_get_mtmr(i);
+		if (p_mtmr) {
+			adev->tick = p_mtmr->freq_hz;
+			adev->irq = p_mtmr->irq;
+		} else
+			printk(KERN_ERR "Failed to get timer for cpu %d\n", i);
+		adev->count = 0;
+		sprintf(adev->name, "apbt%d", i);
+	}
+#endif
+
+	return;
+
+out_noapbt:
+	apbt_clear_mapping();
+	apb_timer_block_enabled = 0;
+	panic("failed to enable APB timer\n");
+}
+
+static inline void apbt_disable(int n)
+{
+	if (is_apbt_capable()) {
+		unsigned long ctrl =  apbt_readl(n, APBTMR_N_CONTROL);
+		ctrl &= ~APBTMR_CONTROL_ENABLE;
+		apbt_writel(n, ctrl, APBTMR_N_CONTROL);
+	}
+}
+
+/* called before apb_timer_enable, use early map */
+unsigned long apbt_quick_calibrate()
+{
+	int i, scale;
+	u64 old, new;
+	cycle_t t1, t2;
+	unsigned long khz = 0;
+	u32 loop, shift;
+
+	apbt_set_mapping();
+	apbt_start_counter(phy_cs_timer_id);
+
+	/* check if the timer can count down, otherwise return */
+	old = apbt_read_clocksource(&clocksource_apbt);
+	i = 10000;
+	while (--i) {
+		if (old != apbt_read_clocksource(&clocksource_apbt))
+			break;
+	}
+	if (!i)
+		goto failed;
+
+	/* count 16 ms */
+	loop = (apbt_freq * 1000) << 4;
+
+	/* restart the timer to ensure it won't get to 0 in the calibration */
+	apbt_start_counter(phy_cs_timer_id);
+
+	old = apbt_read_clocksource(&clocksource_apbt);
+	old += loop;
+
+	t1 = __native_read_tsc();
+
+	do {
+		new = apbt_read_clocksource(&clocksource_apbt);
+	} while (new < old);
+
+	t2 = __native_read_tsc();
+
+	shift = 5;
+	if (unlikely(loop >> shift == 0)) {
+		printk(KERN_INFO
+		       "APBT TSC calibration failed, not enough resolution\n");
+		return 0;
+	}
+	scale = (int)div_u64((t2 - t1), loop >> shift);
+	khz = (scale * apbt_freq * 1000) >> shift;
+	printk(KERN_INFO "TSC freq calculated by APB timer is %lu khz\n", khz);
+	return khz;
+failed:
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/aperture_64.c linux-libre-2.6.34-gnu1/arch/x86/kernel/aperture_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/aperture_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/aperture_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,6 @@
 #include <asm/x86_init.h>
 
 int gart_iommu_aperture;
-EXPORT_SYMBOL_GPL(gart_iommu_aperture);
 int gart_iommu_aperture_disabled __initdata;
 int gart_iommu_aperture_allowed __initdata;
 
@@ -394,6 +393,7 @@ void __init gart_iommu_hole_init(void)
 	for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
 		int bus;
 		int dev_base, dev_limit;
+		u32 ctl;
 
 		bus = bus_dev_ranges[i].bus;
 		dev_base = bus_dev_ranges[i].dev_base;
@@ -407,7 +407,19 @@ void __init gart_iommu_hole_init(void)
 			gart_iommu_aperture = 1;
 			x86_init.iommu.iommu_init = gart_iommu_init;
 
-			aper_order = (read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL) >> 1) & 7;
+			ctl = read_pci_config(bus, slot, 3,
+					      AMD64_GARTAPERTURECTL);
+
+			/*
+			 * Before we do anything else disable the GART. It may
+			 * still be enabled if we boot into a crash-kernel here.
+			 * Reconfiguring the GART while it is enabled could have
+			 * unknown side-effects.
+			 */
+			ctl &= ~GARTEN;
+			write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl);
+
+			aper_order = (ctl >> 1) & 7;
 			aper_size = (32 * 1024 * 1024) << aper_order;
 			aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff;
 			aper_base <<= 25;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/apic.c linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/apic.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/apic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/apic.c	2010-05-16 17:17:36.000000000 -0400
@@ -581,7 +581,7 @@ calibrate_by_pmtimer(long deltapm, long
 		res = (((u64)(*deltatsc)) * pm_100ms);
 		do_div(res, deltapm);
 		apic_printk(APIC_VERBOSE, "TSC delta adjusted to "
-					  "PM-Timer: %lu (%ld) \n",
+					  "PM-Timer: %lu (%ld)\n",
 					(unsigned long)res, *deltatsc);
 		*deltatsc = (long)res;
 	}
@@ -1390,7 +1390,7 @@ void __init enable_IR_x2apic(void)
 	}
 
 	local_irq_save(flags);
-	mask_8259A();
+	legacy_pic->mask_all();
 	mask_IO_APIC_setup(ioapic_entries);
 
 	if (dmar_table_init_ret)
@@ -1422,7 +1422,7 @@ void __init enable_IR_x2apic(void)
 nox2apic:
 	if (!ret) /* IR enabling failed */
 		restore_IO_APIC_setup(ioapic_entries);
-	unmask_8259A();
+	legacy_pic->restore_mask();
 	local_irq_restore(flags);
 
 out:
@@ -1640,8 +1640,10 @@ int __init APIC_init_uniprocessor(void)
 	}
 #endif
 
+#ifndef CONFIG_SMP
 	enable_IR_x2apic();
 	default_setup_apic_routing();
+#endif
 
 	verify_local_APIC();
 	connect_bsp_APIC();
@@ -2018,7 +2020,7 @@ static int lapic_resume(struct sys_devic
 		}
 
 		mask_IO_APIC_setup(ioapic_entries);
-		mask_8259A();
+		legacy_pic->mask_all();
 	}
 
 	if (x2apic_mode)
@@ -2062,7 +2064,7 @@ static int lapic_resume(struct sys_devic
 
 	if (intr_remapping_enabled) {
 		reenable_intr_remapping(x2apic_mode);
-		unmask_8259A();
+		legacy_pic->restore_mask();
 		restore_IO_APIC_setup(ioapic_entries);
 		free_ioapic_entries(ioapic_entries);
 	}
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/apic_flat_64.c linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/apic_flat_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/apic_flat_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/apic_flat_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -223,7 +223,7 @@ struct apic apic_flat =  {
 };
 
 /*
- * Physflat mode is used when there are more than 8 CPUs on a AMD system.
+ * Physflat mode is used when there are more than 8 CPUs on a system.
  * We cannot use logical delivery in this case because the mask
  * overflows, so use physical mode.
  */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/es7000_32.c linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/es7000_32.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/es7000_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/es7000_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/errno.h>
 #include <linux/acpi.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/nmi.h>
 #include <linux/smp.h>
 #include <linux/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/io_apic.c linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/io_apic.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/io_apic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/io_apic.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/freezer.h>
 #include <linux/kthread.h>
 #include <linux/jiffies.h>	/* time_after() */
+#include <linux/slab.h>
 #ifdef CONFIG_ACPI
 #include <acpi/acpi_bus.h>
 #endif
@@ -73,8 +74,8 @@
  */
 int sis_apic_bug = -1;
 
-static DEFINE_SPINLOCK(ioapic_lock);
-static DEFINE_SPINLOCK(vector_lock);
+static DEFINE_RAW_SPINLOCK(ioapic_lock);
+static DEFINE_RAW_SPINLOCK(vector_lock);
 
 /*
  * # of IRQ routing registers
@@ -94,8 +95,6 @@ struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCE
 /* # of MP IRQ source entries */
 int mp_irq_entries;
 
-/* Number of legacy interrupts */
-static int nr_legacy_irqs __read_mostly = NR_IRQS_LEGACY;
 /* GSI interrupts */
 static int nr_irqs_gsi = NR_IRQS_LEGACY;
 
@@ -140,33 +139,10 @@ static struct irq_pin_list *get_one_free
 
 /* 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[] = {
+static struct irq_cfg irq_cfgx[NR_IRQS_LEGACY];
 #else
-static struct irq_cfg irq_cfgx[NR_IRQS] = {
+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, },
-};
-
-void __init io_apic_disable_legacy(void)
-{
-	nr_legacy_irqs = 0;
-	nr_irqs_gsi = 0;
-}
 
 int __init arch_early_irq_init(void)
 {
@@ -176,6 +152,11 @@ int __init arch_early_irq_init(void)
 	int node;
 	int i;
 
+	if (!legacy_pic->nr_legacy_irqs) {
+		nr_irqs_gsi = 0;
+		io_apic_irqs = ~0UL;
+	}
+
 	cfg = irq_cfgx;
 	count = ARRAY_SIZE(irq_cfgx);
 	node= cpu_to_node(boot_cpu_id);
@@ -185,8 +166,14 @@ int __init arch_early_irq_init(void)
 		desc->chip_data = &cfg[i];
 		zalloc_cpumask_var_node(&cfg[i].domain, GFP_NOWAIT, node);
 		zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_NOWAIT, node);
-		if (i < nr_legacy_irqs)
-			cpumask_setall(cfg[i].domain);
+		/*
+		 * For legacy IRQ's, start with assigning irq0 to irq15 to
+		 * IRQ0_VECTOR to IRQ15_VECTOR on cpu 0.
+		 */
+		if (i < legacy_pic->nr_legacy_irqs) {
+			cfg[i].vector = IRQ0_VECTOR + i;
+			cpumask_set_cpu(0, cfg[i].domain);
+		}
 	}
 
 	return 0;
@@ -406,7 +393,7 @@ static bool io_apic_level_ack_pending(st
 	struct irq_pin_list *entry;
 	unsigned long flags;
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	for_each_irq_pin(entry, cfg->irq_2_pin) {
 		unsigned int reg;
 		int pin;
@@ -415,11 +402,11 @@ static bool io_apic_level_ack_pending(st
 		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);
+			raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 			return true;
 		}
 	}
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	return false;
 }
@@ -433,10 +420,10 @@ static struct IO_APIC_route_entry ioapic
 {
 	union entry_union eu;
 	unsigned long flags;
-	spin_lock_irqsave(&ioapic_lock, flags);
+	raw_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);
+	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 	return eu.entry;
 }
 
@@ -459,9 +446,9 @@ __ioapic_write_entry(int apic, int pin,
 void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
 {
 	unsigned long flags;
-	spin_lock_irqsave(&ioapic_lock, flags);
+	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	__ioapic_write_entry(apic, pin, e);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
 /*
@@ -474,10 +461,10 @@ static void ioapic_mask_entry(int apic,
 	unsigned long flags;
 	union entry_union eu = { .entry.mask = 1 };
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	raw_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);
+	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
 /*
@@ -604,9 +591,9 @@ static void mask_IO_APIC_irq_desc(struct
 
 	BUG_ON(!cfg);
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	__mask_IO_APIC_irq(cfg);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
 static void unmask_IO_APIC_irq_desc(struct irq_desc *desc)
@@ -614,9 +601,9 @@ static void unmask_IO_APIC_irq_desc(stru
 	struct irq_cfg *cfg = desc->chip_data;
 	unsigned long flags;
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	__unmask_IO_APIC_irq(cfg);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
 static void mask_IO_APIC_irq(unsigned int irq)
@@ -865,7 +852,7 @@ static int __init find_isa_irq_apic(int
  */
 static int EISA_ELCR(unsigned int irq)
 {
-	if (irq < nr_legacy_irqs) {
+	if (irq < legacy_pic->nr_legacy_irqs) {
 		unsigned int port = 0x4d0 + (irq >> 3);
 		return (inb(port) >> (irq & 7)) & 1;
 	}
@@ -1140,12 +1127,12 @@ void lock_vector_lock(void)
 	/* Used to the online set of cpus does not change
 	 * during assign_irq_vector.
 	 */
-	spin_lock(&vector_lock);
+	raw_spin_lock(&vector_lock);
 }
 
 void unlock_vector_lock(void)
 {
-	spin_unlock(&vector_lock);
+	raw_spin_unlock(&vector_lock);
 }
 
 static int
@@ -1162,7 +1149,8 @@ __assign_irq_vector(int irq, struct irq_
 	 * 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;
+	static int current_vector = FIRST_EXTERNAL_VECTOR + VECTOR_OFFSET_START;
+	static int current_offset = VECTOR_OFFSET_START % 8;
 	unsigned int old_vector;
 	int cpu, err;
 	cpumask_var_t tmp_mask;
@@ -1198,7 +1186,7 @@ next:
 		if (vector >= first_system_vector) {
 			/* If out of vectors on large boxen, must share them. */
 			offset = (offset + 1) % 8;
-			vector = FIRST_DEVICE_VECTOR + offset;
+			vector = FIRST_EXTERNAL_VECTOR + offset;
 		}
 		if (unlikely(current_vector == vector))
 			continue;
@@ -1232,9 +1220,9 @@ int assign_irq_vector(int irq, struct ir
 	int err;
 	unsigned long flags;
 
-	spin_lock_irqsave(&vector_lock, flags);
+	raw_spin_lock_irqsave(&vector_lock, flags);
 	err = __assign_irq_vector(irq, cfg, mask);
-	spin_unlock_irqrestore(&vector_lock, flags);
+	raw_spin_unlock_irqrestore(&vector_lock, flags);
 	return err;
 }
 
@@ -1268,14 +1256,27 @@ static void __clear_irq_vector(int irq,
 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;
 
+	/*
+	 * vector_lock will make sure that we don't run into irq vector
+	 * assignments that might be happening on another cpu in parallel,
+	 * while we setup our initial vector to irq mappings.
+	 */
+	raw_spin_lock(&vector_lock);
 	/* Mark the inuse vectors */
 	for_each_irq_desc(irq, desc) {
 		cfg = desc->chip_data;
+
+		/*
+		 * If it is a legacy IRQ handled by the legacy PIC, this cpu
+		 * will be part of the irq_cfg's domain.
+		 */
+		if (irq < legacy_pic->nr_legacy_irqs && !IO_APIC_IRQ(irq))
+			cpumask_set_cpu(cpu, cfg->domain);
+
 		if (!cpumask_test_cpu(cpu, cfg->domain))
 			continue;
 		vector = cfg->vector;
@@ -1291,6 +1292,7 @@ void __setup_vector_irq(int cpu)
 		if (!cpumask_test_cpu(cpu, cfg->domain))
 			per_cpu(vector_irq, cpu)[vector] = -1;
 	}
+	raw_spin_unlock(&vector_lock);
 }
 
 static struct irq_chip ioapic_chip;
@@ -1440,6 +1442,14 @@ static void setup_IO_APIC_irq(int apic_i
 
 	cfg = desc->chip_data;
 
+	/*
+	 * For legacy irqs, cfg->domain starts with cpu 0 for legacy
+	 * controllers like 8259. Now that IO-APIC can handle this irq, update
+	 * the cfg->domain.
+	 */
+	if (irq < legacy_pic->nr_legacy_irqs && cpumask_test_cpu(0, cfg->domain))
+		apic->vector_allocation_domain(0, cfg->domain);
+
 	if (assign_irq_vector(irq, cfg, apic->target_cpus()))
 		return;
 
@@ -1461,8 +1471,8 @@ static void setup_IO_APIC_irq(int apic_i
 	}
 
 	ioapic_register_intr(irq, desc, trigger);
-	if (irq < nr_legacy_irqs)
-		disable_8259A_irq(irq);
+	if (irq < legacy_pic->nr_legacy_irqs)
+		legacy_pic->chip->mask(irq);
 
 	ioapic_write_entry(apic_id, pin, entry);
 }
@@ -1473,7 +1483,7 @@ static struct {
 
 static void __init setup_IO_APIC_irqs(void)
 {
-	int apic_id = 0, pin, idx, irq;
+	int apic_id, pin, idx, irq;
 	int notcon = 0;
 	struct irq_desc *desc;
 	struct irq_cfg *cfg;
@@ -1481,14 +1491,7 @@ static void __init setup_IO_APIC_irqs(vo
 
 	apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
 
-#ifdef CONFIG_ACPI
-	if (!acpi_disabled && acpi_ioapic) {
-		apic_id = mp_find_ioapic(0);
-		if (apic_id < 0)
-			apic_id = 0;
-	}
-#endif
-
+	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) {
@@ -1510,6 +1513,9 @@ static void __init setup_IO_APIC_irqs(vo
 
 		irq = pin_2_irq(idx, apic_id, pin);
 
+		if ((apic_id > 0) && (irq > 16))
+			continue;
+
 		/*
 		 * Skip the timer IRQ if there's a quirk handler
 		 * installed and if it returns 1:
@@ -1539,6 +1545,56 @@ static void __init setup_IO_APIC_irqs(vo
 }
 
 /*
+ * for the gsit that is not in first ioapic
+ * but could not use acpi_register_gsi()
+ * like some special sci in IBM x3330
+ */
+void setup_IO_APIC_irq_extra(u32 gsi)
+{
+	int apic_id = 0, pin, idx, irq;
+	int node = cpu_to_node(boot_cpu_id);
+	struct irq_desc *desc;
+	struct irq_cfg *cfg;
+
+	/*
+	 * Convert 'gsi' to 'ioapic.pin'.
+	 */
+	apic_id = mp_find_ioapic(gsi);
+	if (apic_id < 0)
+		return;
+
+	pin = mp_find_ioapic_pin(apic_id, gsi);
+	idx = find_irq_entry(apic_id, pin, mp_INT);
+	if (idx == -1)
+		return;
+
+	irq = pin_2_irq(idx, apic_id, pin);
+#ifdef CONFIG_SPARSE_IRQ
+	desc = irq_to_desc(irq);
+	if (desc)
+		return;
+#endif
+	desc = irq_to_desc_alloc_node(irq, node);
+	if (!desc) {
+		printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+		return;
+	}
+
+	cfg = desc->chip_data;
+	add_pin_to_irq_node(cfg, node, apic_id, pin);
+
+	if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) {
+		pr_debug("Pin %d-%d already programmed\n",
+			 mp_ioapics[apic_id].apicid, pin);
+		return;
+	}
+	set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
+
+	setup_IO_APIC_irq(apic_id, pin, irq, desc,
+			irq_trigger(idx), irq_polarity(idx));
+}
+
+/*
  * 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,
@@ -1601,14 +1657,14 @@ __apicdebuginit(void) print_IO_APIC(void
 
 	for (apic = 0; apic < nr_ioapics; apic++) {
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	raw_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);
+	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	printk("\n");
 	printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].apicid);
@@ -1647,7 +1703,7 @@ __apicdebuginit(void) print_IO_APIC(void
 	printk(KERN_DEBUG ".... IRQ redirection table:\n");
 
 	printk(KERN_DEBUG " NR Dst Mask Trig IRR Pol"
-			  " Stat Dmod Deli Vect:   \n");
+			  " Stat Dmod Deli Vect:\n");
 
 	for (i = 0; i <= reg_01.bits.entries; i++) {
 		struct IO_APIC_route_entry entry;
@@ -1825,12 +1881,12 @@ __apicdebuginit(void) print_PIC(void)
 	unsigned int v;
 	unsigned long flags;
 
-	if (!nr_legacy_irqs)
+	if (!legacy_pic->nr_legacy_irqs)
 		return;
 
 	printk(KERN_DEBUG "\nprinting PIC contents\n");
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
 
 	v = inb(0xa1) << 8 | inb(0x21);
 	printk(KERN_DEBUG "... PIC  IMR: %04x\n", v);
@@ -1844,7 +1900,7 @@ __apicdebuginit(void) print_PIC(void)
 	outb(0x0a,0xa0);
 	outb(0x0a,0x20);
 
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 
 	printk(KERN_DEBUG "... PIC  ISR: %04x\n", v);
 
@@ -1903,13 +1959,13 @@ void __init enable_IO_APIC(void)
 	 * The number of IO-APIC IRQ registers (== #pins):
 	 */
 	for (apic = 0; apic < nr_ioapics; apic++) {
-		spin_lock_irqsave(&ioapic_lock, flags);
+		raw_spin_lock_irqsave(&ioapic_lock, flags);
 		reg_01.raw = io_apic_read(apic, 1);
-		spin_unlock_irqrestore(&ioapic_lock, flags);
+		raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 		nr_ioapic_registers[apic] = reg_01.bits.entries+1;
 	}
 
-	if (!nr_legacy_irqs)
+	if (!legacy_pic->nr_legacy_irqs)
 		return;
 
 	for(apic = 0; apic < nr_ioapics; apic++) {
@@ -1966,7 +2022,7 @@ void disable_IO_APIC(void)
 	 */
 	clear_IO_APIC();
 
-	if (!nr_legacy_irqs)
+	if (!legacy_pic->nr_legacy_irqs)
 		return;
 
 	/*
@@ -2045,9 +2101,9 @@ void __init setup_ioapic_ids_from_mpc(vo
 	for (apic_id = 0; apic_id < nr_ioapics; apic_id++) {
 
 		/* Read the register 0 value */
-		spin_lock_irqsave(&ioapic_lock, flags);
+		raw_spin_lock_irqsave(&ioapic_lock, flags);
 		reg_00.raw = io_apic_read(apic_id, 0);
-		spin_unlock_irqrestore(&ioapic_lock, flags);
+		raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
 		old_id = mp_ioapics[apic_id].apicid;
 
@@ -2106,16 +2162,16 @@ void __init setup_ioapic_ids_from_mpc(vo
 			mp_ioapics[apic_id].apicid);
 
 		reg_00.bits.ID = mp_ioapics[apic_id].apicid;
-		spin_lock_irqsave(&ioapic_lock, flags);
+		raw_spin_lock_irqsave(&ioapic_lock, flags);
 		io_apic_write(apic_id, 0, reg_00.raw);
-		spin_unlock_irqrestore(&ioapic_lock, flags);
+		raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
 		/*
 		 * Sanity check
 		 */
-		spin_lock_irqsave(&ioapic_lock, flags);
+		raw_spin_lock_irqsave(&ioapic_lock, flags);
 		reg_00.raw = io_apic_read(apic_id, 0);
-		spin_unlock_irqrestore(&ioapic_lock, flags);
+		raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 		if (reg_00.bits.ID != mp_ioapics[apic_id].apicid)
 			printk("could not set ID!\n");
 		else
@@ -2198,15 +2254,15 @@ static unsigned int startup_ioapic_irq(u
 	unsigned long flags;
 	struct irq_cfg *cfg;
 
-	spin_lock_irqsave(&ioapic_lock, flags);
-	if (irq < nr_legacy_irqs) {
-		disable_8259A_irq(irq);
-		if (i8259A_irq_pending(irq))
+	raw_spin_lock_irqsave(&ioapic_lock, flags);
+	if (irq < legacy_pic->nr_legacy_irqs) {
+		legacy_pic->chip->mask(irq);
+		if (legacy_pic->irq_pending(irq))
 			was_pending = 1;
 	}
 	cfg = irq_cfg(irq);
 	__unmask_IO_APIC_irq(cfg);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	return was_pending;
 }
@@ -2217,9 +2273,9 @@ static int ioapic_retrigger_irq(unsigned
 	struct irq_cfg *cfg = irq_cfg(irq);
 	unsigned long flags;
 
-	spin_lock_irqsave(&vector_lock, flags);
+	raw_spin_lock_irqsave(&vector_lock, flags);
 	apic->send_IPI_mask(cpumask_of(cpumask_first(cfg->domain)), cfg->vector);
-	spin_unlock_irqrestore(&vector_lock, flags);
+	raw_spin_unlock_irqrestore(&vector_lock, flags);
 
 	return 1;
 }
@@ -2312,14 +2368,14 @@ set_ioapic_affinity_irq_desc(struct irq_
 	irq = desc->irq;
 	cfg = desc->chip_data;
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	ret = set_desc_affinity(desc, mask, &dest);
 	if (!ret) {
 		/* Only the high 8 bits are valid. */
 		dest = SET_APIC_LOGICAL_ID(dest);
 		__target_IO_APIC_irq(irq, dest, cfg);
 	}
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	return ret;
 }
@@ -2489,6 +2545,9 @@ void irq_force_complete_move(int irq)
 	struct irq_desc *desc = irq_to_desc(irq);
 	struct irq_cfg *cfg = desc->chip_data;
 
+	if (!cfg)
+		return;
+
 	__irq_complete_move(&desc, cfg->vector);
 }
 #else
@@ -2554,9 +2613,9 @@ static void eoi_ioapic_irq(struct irq_de
 	irq = desc->irq;
 	cfg = desc->chip_data;
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	__eoi_ioapic_irq(irq, cfg);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
 static void ack_apic_level(unsigned int irq)
@@ -2734,8 +2793,8 @@ static inline void init_IO_APIC_traps(vo
 			 * so default to an old-fashioned 8259
 			 * interrupt if we can..
 			 */
-			if (irq < nr_legacy_irqs)
-				make_8259A_irq(irq);
+			if (irq < legacy_pic->nr_legacy_irqs)
+				legacy_pic->make_irq(irq);
 			else
 				/* Strange. Oh, well.. */
 				desc->chip = &no_irq_chip;
@@ -2892,7 +2951,7 @@ static inline void __init check_timer(vo
 	/*
 	 * get/set the timer IRQ vector:
 	 */
-	disable_8259A_irq(0);
+	legacy_pic->chip->mask(0);
 	assign_irq_vector(0, cfg, apic->target_cpus());
 
 	/*
@@ -2905,7 +2964,7 @@ static inline void __init check_timer(vo
 	 * automatically.
 	 */
 	apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
-	init_8259A(1);
+	legacy_pic->init(1);
 #ifdef CONFIG_X86_32
 	{
 		unsigned int ver;
@@ -2964,7 +3023,7 @@ static inline void __init check_timer(vo
 		if (timer_irq_works()) {
 			if (nmi_watchdog == NMI_IO_APIC) {
 				setup_nmi();
-				enable_8259A_irq(0);
+				legacy_pic->chip->unmask(0);
 			}
 			if (disable_timer_pin_1 > 0)
 				clear_IO_APIC_pin(0, pin1);
@@ -2987,14 +3046,14 @@ static inline void __init check_timer(vo
 		 */
 		replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2);
 		setup_timer_IRQ0_pin(apic2, pin2, cfg->vector);
-		enable_8259A_irq(0);
+		legacy_pic->chip->unmask(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);
+				legacy_pic->chip->mask(0);
 				setup_nmi();
-				enable_8259A_irq(0);
+				legacy_pic->chip->unmask(0);
 			}
 			goto out;
 		}
@@ -3002,7 +3061,7 @@ static inline void __init check_timer(vo
 		 * Cleanup, just in case ...
 		 */
 		local_irq_disable();
-		disable_8259A_irq(0);
+		legacy_pic->chip->mask(0);
 		clear_IO_APIC_pin(apic2, pin2);
 		apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
 	}
@@ -3021,22 +3080,22 @@ static inline void __init check_timer(vo
 
 	lapic_register_intr(0, desc);
 	apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector);	/* Fixed mode */
-	enable_8259A_irq(0);
+	legacy_pic->chip->unmask(0);
 
 	if (timer_irq_works()) {
 		apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
 		goto out;
 	}
 	local_irq_disable();
-	disable_8259A_irq(0);
+	legacy_pic->chip->mask(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);
+	legacy_pic->init(0);
+	legacy_pic->make_irq(0);
 	apic_write(APIC_LVT0, APIC_DM_EXTINT);
 
 	unlock_ExtINT_logic();
@@ -3078,7 +3137,7 @@ void __init setup_IO_APIC(void)
 	/*
 	 * calling enable_IO_APIC() is moved to setup_local_APIC for BP
 	 */
-	io_apic_irqs = nr_legacy_irqs ? ~PIC_IRQS : ~0UL;
+	io_apic_irqs = legacy_pic->nr_legacy_irqs ? ~PIC_IRQS : ~0UL;
 
 	apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
 	/*
@@ -3089,7 +3148,7 @@ void __init setup_IO_APIC(void)
 	sync_Arb_IDs();
 	setup_IO_APIC_irqs();
 	init_IO_APIC_traps();
-	if (nr_legacy_irqs)
+	if (legacy_pic->nr_legacy_irqs)
 		check_timer();
 }
 
@@ -3138,13 +3197,13 @@ static int ioapic_resume(struct sys_devi
 	data = container_of(dev, struct sysfs_ioapic_data, dev);
 	entry = data->entry;
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	raw_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);
+	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]);
 
@@ -3207,7 +3266,7 @@ unsigned int create_irq_nr(unsigned int
 	if (irq_want < nr_irqs_gsi)
 		irq_want = nr_irqs_gsi;
 
-	spin_lock_irqsave(&vector_lock, flags);
+	raw_spin_lock_irqsave(&vector_lock, flags);
 	for (new = irq_want; new < nr_irqs; new++) {
 		desc_new = irq_to_desc_alloc_node(new, node);
 		if (!desc_new) {
@@ -3226,14 +3285,11 @@ unsigned int create_irq_nr(unsigned int
 			irq = new;
 		break;
 	}
-	spin_unlock_irqrestore(&vector_lock, flags);
+	raw_spin_unlock_irqrestore(&vector_lock, flags);
+
+	if (irq > 0)
+		dynamic_irq_init_keep_chip_data(irq);
 
-	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;
 }
 
@@ -3255,20 +3311,13 @@ int create_irq(void)
 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 */
-	desc->chip_data = cfg;
+	dynamic_irq_cleanup_keep_chip_data(irq);
 
 	free_irte(irq);
-	spin_lock_irqsave(&vector_lock, flags);
-	__clear_irq_vector(irq, cfg);
-	spin_unlock_irqrestore(&vector_lock, flags);
+	raw_spin_lock_irqsave(&vector_lock, flags);
+	__clear_irq_vector(irq, get_irq_chip_data(irq));
+	raw_spin_unlock_irqrestore(&vector_lock, flags);
 }
 
 /*
@@ -3805,9 +3854,9 @@ int __init io_apic_get_redir_entries (in
 	union IO_APIC_reg_01	reg_01;
 	unsigned long flags;
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	reg_01.raw = io_apic_read(ioapic, 1);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	return reg_01.bits.entries;
 }
@@ -3890,7 +3939,7 @@ static int __io_apic_set_pci_routing(str
 	/*
 	 * IRQs < 16 are already in the irq_2_pin[] map
 	 */
-	if (irq >= nr_legacy_irqs) {
+	if (irq >= legacy_pic->nr_legacy_irqs) {
 		cfg = desc->chip_data;
 		if (add_pin_to_irq_node_nopanic(cfg, node, ioapic, pin)) {
 			printk(KERN_INFO "can not add pin %d for irq %d\n",
@@ -3969,9 +4018,9 @@ int __init io_apic_get_unique_id(int ioa
 	if (physids_empty(apic_id_map))
 		apic->ioapic_phys_id_map(&phys_cpu_present_map, &apic_id_map);
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	reg_00.raw = io_apic_read(ioapic, 0);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	if (apic_id >= get_physical_broadcast()) {
 		printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
@@ -4005,10 +4054,10 @@ int __init io_apic_get_unique_id(int ioa
 	if (reg_00.bits.ID != apic_id) {
 		reg_00.bits.ID = apic_id;
 
-		spin_lock_irqsave(&ioapic_lock, flags);
+		raw_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);
+		raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
 		/* Sanity check */
 		if (reg_00.bits.ID != apic_id) {
@@ -4029,9 +4078,9 @@ int __init io_apic_get_version(int ioapi
 	union IO_APIC_reg_01	reg_01;
 	unsigned long flags;
 
-	spin_lock_irqsave(&ioapic_lock, flags);
+	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	reg_01.raw = io_apic_read(ioapic, 1);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
+	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	return reg_01.bits.version;
 }
@@ -4063,27 +4112,23 @@ int acpi_get_override_irq(int bus_irq, i
 #ifdef CONFIG_SMP
 void __init setup_ioapic_dest(void)
 {
-	int pin, ioapic = 0, irq, irq_entry;
+	int pin, ioapic, irq, irq_entry;
 	struct irq_desc *desc;
 	const struct cpumask *mask;
 
 	if (skip_ioapic_setup == 1)
 		return;
 
-#ifdef CONFIG_ACPI
-	if (!acpi_disabled && acpi_ioapic) {
-		ioapic = mp_find_ioapic(0);
-		if (ioapic < 0)
-			ioapic = 0;
-	}
-#endif
-
+	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);
 
+		if ((ioapic > 0) && (irq > 16))
+			continue;
+
 		desc = irq_to_desc(irq);
 
 		/*
@@ -4268,3 +4313,24 @@ void __init mp_register_ioapic(int id, u
 
 	nr_ioapics++;
 }
+
+/* Enable IOAPIC early just for system timer */
+void __init pre_init_apic_IRQ0(void)
+{
+	struct irq_cfg *cfg;
+	struct irq_desc *desc;
+
+	printk(KERN_INFO "Early APIC setup for system timer0\n");
+#ifndef CONFIG_SMP
+	phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
+#endif
+	desc = irq_to_desc_alloc_node(0, 0);
+
+	setup_local_APIC();
+
+	cfg = irq_cfg(0);
+	add_pin_to_irq_node(cfg, 0, 0, 0);
+	set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge");
+
+	setup_IO_APIC_irq(0, 0, 0, desc, 0, 0);
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/nmi.c linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/nmi.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/nmi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/nmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/sysdev.h>
 #include <linux/sysctl.h>
 #include <linux/percpu.h>
@@ -177,7 +178,7 @@ int __init check_nmi_watchdog(void)
 error:
 	if (nmi_watchdog == NMI_IO_APIC) {
 		if (!timer_through_8259)
-			disable_8259A_irq(0);
+			legacy_pic->chip->mask(0);
 		on_each_cpu(__acpi_nmi_disable, NULL, 1);
 	}
 
@@ -416,13 +417,13 @@ nmi_watchdog_tick(struct pt_regs *regs,
 
 	/* We can be called before check_nmi_watchdog, hence NULL check. */
 	if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) {
-		static DEFINE_SPINLOCK(lock);	/* Serialise the printks */
+		static DEFINE_RAW_SPINLOCK(lock); /* Serialise the printks */
 
-		spin_lock(&lock);
+		raw_spin_lock(&lock);
 		printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu);
 		show_regs(regs);
 		dump_stack();
-		spin_unlock(&lock);
+		raw_spin_unlock(&lock);
 		cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
 
 		rc = 1;
@@ -438,8 +439,8 @@ nmi_watchdog_tick(struct pt_regs *regs,
 		 * Ayiee, looks like this CPU is stuck ...
 		 * wait a few IRQs (5 seconds) before doing the oops ...
 		 */
-		__this_cpu_inc(per_cpu_var(alert_counter));
-		if (__this_cpu_read(per_cpu_var(alert_counter)) == 5 * nmi_hz)
+		__this_cpu_inc(alert_counter);
+		if (__this_cpu_read(alert_counter) == 5 * nmi_hz)
 			/*
 			 * die_nmi will return ONLY if NOTIFY_STOP happens..
 			 */
@@ -447,7 +448,7 @@ nmi_watchdog_tick(struct pt_regs *regs,
 				regs, panic_on_timeout);
 	} else {
 		__get_cpu_var(last_irq_sum) = sum;
-		__this_cpu_write(per_cpu_var(alert_counter), 0);
+		__this_cpu_write(alert_counter, 0);
 	}
 
 	/* see if the nmi watchdog went off */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/numaq_32.c linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/numaq_32.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/numaq_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/numaq_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -225,7 +225,7 @@ static void __init smp_read_mpc_oem(stru
 
 	mpc_record = 0;
 	printk(KERN_INFO
-		"Found an OEM MPC table at %8p - parsing it ... \n", oemtable);
+		"Found an OEM MPC table at %8p - parsing it...\n", oemtable);
 
 	if (memcmp(oemtable->signature, MPC_OEM_SIGNATURE, 4)) {
 		printk(KERN_WARNING
@@ -277,6 +277,7 @@ static __init void early_check_numaq(voi
 		x86_init.mpparse.mpc_oem_pci_bus = mpc_oem_pci_bus;
 		x86_init.mpparse.mpc_oem_bus_info = mpc_oem_bus_info;
 		x86_init.timers.tsc_pre_init = numaq_tsc_init;
+		x86_init.pci.init = pci_numaq_init;
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * SGI UV APIC functions (note: not an Intel compatible APIC)
  *
- * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2007-2009 Silicon Graphics, Inc. All rights reserved.
  */
 #include <linux/cpumask.h>
 #include <linux/hardirq.h>
@@ -17,9 +17,12 @@
 #include <linux/ctype.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <linux/cpu.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/pci.h>
+#include <linux/kdebug.h>
 
 #include <asm/uv/uv_mmrs.h>
 #include <asm/uv/uv_hub.h>
@@ -34,10 +37,13 @@
 
 DEFINE_PER_CPU(int, x2apic_extra_bits);
 
+#define PR_DEVEL(fmt, args...)	pr_devel("%s: " fmt, __func__, args)
+
 static enum uv_system_type uv_system_type;
 static u64 gru_start_paddr, gru_end_paddr;
 int uv_min_hub_revision_id;
 EXPORT_SYMBOL_GPL(uv_min_hub_revision_id);
+static DEFINE_SPINLOCK(uv_nmi_lock);
 
 static inline bool is_GRU_range(u64 start, u64 end)
 {
@@ -71,6 +77,7 @@ static int __init uv_acpi_madt_oem_check
 	if (!strcmp(oem_id, "SGI")) {
 		nodeid = early_get_nodeid();
 		x86_platform.is_untracked_pat_range =  uv_is_untracked_pat_range;
+		x86_platform.nmi_init = uv_nmi_init;
 		if (!strcmp(oem_table_id, "UVL"))
 			uv_system_type = UV_LEGACY_APIC;
 		else if (!strcmp(oem_table_id, "UVX"))
@@ -114,11 +121,9 @@ 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);
+	return cpu_online_mask;
 }
 
 static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask)
@@ -482,7 +487,7 @@ static void uv_heartbeat(unsigned long i
 
 static void __cpuinit uv_heartbeat_enable(int cpu)
 {
-	if (!uv_cpu_hub_info(cpu)->scir.enabled) {
+	while (!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);
@@ -490,11 +495,10 @@ static void __cpuinit uv_heartbeat_enabl
 		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);
+		/* also ensure that boot cpu is enabled */
+		cpu = 0;
+	}
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -553,6 +557,30 @@ late_initcall(uv_init_heartbeat);
 
 #endif /* !CONFIG_HOTPLUG_CPU */
 
+/* Direct Legacy VGA I/O traffic to designated IOH */
+int uv_set_vga_state(struct pci_dev *pdev, bool decode,
+		      unsigned int command_bits, bool change_bridge)
+{
+	int domain, bus, rc;
+
+	PR_DEVEL("devfn %x decode %d cmd %x chg_brdg %d\n",
+			pdev->devfn, decode, command_bits, change_bridge);
+
+	if (!change_bridge)
+		return 0;
+
+	if ((command_bits & PCI_COMMAND_IO) == 0)
+		return 0;
+
+	domain = pci_domain_nr(pdev->bus);
+	bus = pdev->bus->number;
+
+	rc = uv_bios_set_legacy_vga_target(decode, domain, bus);
+	PR_DEVEL("vga decode %d %x:%x, rc: %d\n", decode, domain, bus, rc);
+
+	return rc;
+}
+
 /*
  * Called on each cpu to initialize the per_cpu UV data area.
  * FIXME: hotplug not supported yet
@@ -569,6 +597,46 @@ void __cpuinit uv_cpu_init(void)
 		set_x2apic_extra_bits(uv_hub_info->pnode);
 }
 
+/*
+ * When NMI is received, print a stack trace.
+ */
+int uv_handle_nmi(struct notifier_block *self, unsigned long reason, void *data)
+{
+	if (reason != DIE_NMI_IPI)
+		return NOTIFY_OK;
+	/*
+	 * Use a lock so only one cpu prints at a time
+	 * to prevent intermixed output.
+	 */
+	spin_lock(&uv_nmi_lock);
+	pr_info("NMI stack dump cpu %u:\n", smp_processor_id());
+	dump_stack();
+	spin_unlock(&uv_nmi_lock);
+
+	return NOTIFY_STOP;
+}
+
+static struct notifier_block uv_dump_stack_nmi_nb = {
+	.notifier_call	= uv_handle_nmi
+};
+
+void uv_register_nmi_notifier(void)
+{
+	if (register_die_notifier(&uv_dump_stack_nmi_nb))
+		printk(KERN_WARNING "UV NMI handler failed to register\n");
+}
+
+void uv_nmi_init(void)
+{
+	unsigned int value;
+
+	/*
+	 * Unmask NMI on all cpus
+	 */
+	value = apic_read(APIC_LVT1) | APIC_DM_NMI;
+	value &= ~APIC_LVT_MASKED;
+	apic_write(APIC_LVT1, value);
+}
 
 void __init uv_system_init(void)
 {
@@ -634,8 +702,8 @@ void __init uv_system_init(void)
 	}
 
 	uv_bios_init();
-	uv_bios_get_sn_info(0, &uv_type, &sn_partition_id,
-			    &sn_coherency_id, &sn_region_size);
+	uv_bios_get_sn_info(0, &uv_type, &sn_partition_id, &sn_coherency_id,
+			    &sn_region_size, &system_serial_number);
 	uv_rtc_init();
 
 	for_each_present_cpu(cpu) {
@@ -690,5 +758,9 @@ void __init uv_system_init(void)
 
 	uv_cpu_init();
 	uv_scir_register_cpu_notifier();
+	uv_register_nmi_notifier();
 	proc_mkdir("sgi_uv", NULL);
+
+	/* register Legacy VGA I/O redirection handler */
+	pci_register_set_vga_state(uv_set_vga_state);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/apm_32.c linux-libre-2.6.34-gnu1/arch/x86/kernel/apm_32.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/apm_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/apm_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -1992,8 +1992,8 @@ static int __init apm_is_horked_d850md(c
 		apm_info.disabled = 1;
 		printk(KERN_INFO "%s machine detected. "
 		       "Disabling APM.\n", d->ident);
-		printk(KERN_INFO "This bug is fixed in bios P15 which is available for \n");
-		printk(KERN_INFO "download from support.intel.com \n");
+		printk(KERN_INFO "This bug is fixed in bios P15 which is available for\n");
+		printk(KERN_INFO "download from support.intel.com\n");
 	}
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/bios_uv.c linux-libre-2.6.34-gnu1/arch/x86/kernel/bios_uv.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/bios_uv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/bios_uv.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,8 +15,8 @@
  *  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) 2008 Silicon Graphics, Inc.  All Rights Reserved.
- *  Copyright (c) Russ Anderson
+ *  Copyright (c) 2008-2009 Silicon Graphics, Inc.  All Rights Reserved.
+ *  Copyright (c) Russ Anderson <rja@sgi.com>
  */
 
 #include <linux/efi.h>
@@ -30,6 +30,7 @@ static struct uv_systab uv_systab;
 s64 uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
 {
 	struct uv_systab *tab = &uv_systab;
+	s64 ret;
 
 	if (!tab->function)
 		/*
@@ -37,9 +38,11 @@ s64 uv_bios_call(enum uv_bios_cmd which,
 		 */
 		return BIOS_STATUS_UNIMPLEMENTED;
 
-	return efi_call6((void *)__va(tab->function),
-					(u64)which, a1, a2, a3, a4, a5);
+	ret = efi_call6((void *)__va(tab->function), (u64)which,
+			a1, a2, a3, a4, a5);
+	return ret;
 }
+EXPORT_SYMBOL_GPL(uv_bios_call);
 
 s64 uv_bios_call_irqsave(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3,
 					u64 a4, u64 a5)
@@ -73,11 +76,14 @@ long sn_coherency_id;
 EXPORT_SYMBOL_GPL(sn_coherency_id);
 long sn_region_size;
 EXPORT_SYMBOL_GPL(sn_region_size);
+long system_serial_number;
+EXPORT_SYMBOL_GPL(system_serial_number);
 int uv_type;
+EXPORT_SYMBOL_GPL(uv_type);
 
 
 s64 uv_bios_get_sn_info(int fc, int *uvtype, long *partid, long *coher,
-		long *region)
+		long *region, long *ssn)
 {
 	s64 ret;
 	u64 v0, v1;
@@ -97,8 +103,11 @@ s64 uv_bios_get_sn_info(int fc, int *uvt
 		*coher = part.coherence_id;
 	if (region)
 		*region = part.region_size;
+	if (ssn)
+		*ssn = v1;
 	return ret;
 }
+EXPORT_SYMBOL_GPL(uv_bios_get_sn_info);
 
 int
 uv_bios_mq_watchlist_alloc(unsigned long addr, unsigned int mq_size,
@@ -154,6 +163,25 @@ s64 uv_bios_freq_base(u64 clock_type, u6
 }
 EXPORT_SYMBOL_GPL(uv_bios_freq_base);
 
+/*
+ * uv_bios_set_legacy_vga_target - Set Legacy VGA I/O Target
+ * @decode: true to enable target, false to disable target
+ * @domain: PCI domain number
+ * @bus: PCI bus number
+ *
+ * Returns:
+ *    0: Success
+ *    -EINVAL: Invalid domain or bus number
+ *    -ENOSYS: Capability not available
+ *    -EBUSY: Legacy VGA I/O cannot be retargeted at this time
+ */
+int uv_bios_set_legacy_vga_target(bool decode, int domain, int bus)
+{
+	return uv_bios_call(UV_BIOS_SET_LEGACY_VGA_TARGET,
+				(u64)decode, (u64)domain, (u64)bus, 0, 0);
+}
+EXPORT_SYMBOL_GPL(uv_bios_set_legacy_vga_target);
+
 
 #ifdef CONFIG_EFI
 void uv_bios_init(void)
@@ -185,4 +213,3 @@ void uv_bios_init(void)
 
 void uv_bios_init(void) { }
 #endif
-
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/bootflag.c linux-libre-2.6.34-gnu1/arch/x86/kernel/bootflag.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/bootflag.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/bootflag.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/acpi.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/addon_cpuid_features.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/addon_cpuid_features.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/addon_cpuid_features.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/addon_cpuid_features.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,10 @@ void __cpuinit init_scattered_cpuid_feat
 	static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
 		{ X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
 		{ X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006 },
+		{ X86_FEATURE_NPT,   CR_EDX, 0, 0x8000000a },
+		{ X86_FEATURE_LBRV,  CR_EDX, 1, 0x8000000a },
+		{ X86_FEATURE_SVML,  CR_EDX, 2, 0x8000000a },
+		{ X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a },
 		{ 0, 0, 0, 0 }
 	};
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/cpufreq.h>
 #include <linux/compiler.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 #include <trace/events/power.h>
 
 #include <linux/acpi.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/elanfreq.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/elanfreq.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/elanfreq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/elanfreq.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,7 +20,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/cpufreq.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c	2010-05-16 17:17:36.000000000 -0400
@@ -80,6 +80,7 @@
 #include <linux/cpufreq.h>
 #include <linux/pci.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 
 #include <asm/processor-cyrix.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/Kconfig linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/Kconfig
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,20 @@ if CPU_FREQ
 
 comment "CPUFreq processor drivers"
 
+config X86_PCC_CPUFREQ
+	tristate "Processor Clocking Control interface driver"
+	depends on ACPI && ACPI_PROCESSOR
+	help
+	  This driver adds support for the PCC interface.
+
+	  For details, take a look at:
+	  <file:Documentation/cpu-freq/pcc-cpufreq.txt>.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pcc-cpufreq.
+
+	  If in doubt, say N.
+
 config X86_ACPI_CPUFREQ
 	tristate "ACPI Processor P-States driver"
 	select CPU_FREQ_TABLE
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/longrun.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/longrun.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/longrun.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/longrun.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/cpufreq.h>
 #include <linux/timex.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/Makefile linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/Makefile
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_X86_POWERNOW_K8)		+= powernow-k8.o
 obj-$(CONFIG_X86_ACPI_CPUFREQ)		+= acpi-cpufreq.o
+obj-$(CONFIG_X86_PCC_CPUFREQ)		+= pcc-cpufreq.o
 obj-$(CONFIG_X86_POWERNOW_K6)		+= powernow-k6.o
 obj-$(CONFIG_X86_POWERNOW_K7)		+= powernow-k7.o
 obj-$(CONFIG_X86_LONGHAUL)		+= longhaul.o
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,6 @@
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <linux/cpufreq.h>
-#include <linux/slab.h>
 #include <linux/cpumask.h>
 #include <linux/timex.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,621 @@
+/*
+ *  pcc-cpufreq.c - Processor Clocking Control firmware cpufreq interface
+ *
+ *  Copyright (C) 2009 Red Hat, Matthew Garrett <mjg@redhat.com>
+ *  Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ *	Nagananda Chumbalkar <nagananda.chumbalkar@hp.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or NON
+ *  INFRINGEMENT. See the GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/compiler.h>
+#include <linux/slab.h>
+
+#include <linux/acpi.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+
+#include <acpi/processor.h>
+
+#define PCC_VERSION 	"1.00.00"
+#define POLL_LOOPS 	300
+
+#define CMD_COMPLETE 	0x1
+#define CMD_GET_FREQ 	0x0
+#define CMD_SET_FREQ 	0x1
+
+#define BUF_SZ		4
+
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER,	\
+					     "pcc-cpufreq", msg)
+
+struct pcc_register_resource {
+	u8 descriptor;
+	u16 length;
+	u8 space_id;
+	u8 bit_width;
+	u8 bit_offset;
+	u8 access_size;
+	u64 address;
+} __attribute__ ((packed));
+
+struct pcc_memory_resource {
+	u8 descriptor;
+	u16 length;
+	u8 space_id;
+	u8 resource_usage;
+	u8 type_specific;
+	u64 granularity;
+	u64 minimum;
+	u64 maximum;
+	u64 translation_offset;
+	u64 address_length;
+} __attribute__ ((packed));
+
+static struct cpufreq_driver pcc_cpufreq_driver;
+
+struct pcc_header {
+	u32 signature;
+	u16 length;
+	u8 major;
+	u8 minor;
+	u32 features;
+	u16 command;
+	u16 status;
+	u32 latency;
+	u32 minimum_time;
+	u32 maximum_time;
+	u32 nominal;
+	u32 throttled_frequency;
+	u32 minimum_frequency;
+};
+
+static void __iomem *pcch_virt_addr;
+static struct pcc_header __iomem *pcch_hdr;
+
+static DEFINE_SPINLOCK(pcc_lock);
+
+static struct acpi_generic_address doorbell;
+
+static u64 doorbell_preserve;
+static u64 doorbell_write;
+
+static u8 OSC_UUID[16] = {0x63, 0x9B, 0x2C, 0x9F, 0x70, 0x91, 0x49, 0x1f,
+			  0xBB, 0x4F, 0xA5, 0x98, 0x2F, 0xA1, 0xB5, 0x46};
+
+struct pcc_cpu {
+	u32 input_offset;
+	u32 output_offset;
+};
+
+static struct pcc_cpu *pcc_cpu_info;
+
+static int pcc_cpufreq_verify(struct cpufreq_policy *policy)
+{
+	cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+				     policy->cpuinfo.max_freq);
+	return 0;
+}
+
+static inline void pcc_cmd(void)
+{
+	u64 doorbell_value;
+	int i;
+
+	acpi_read(&doorbell_value, &doorbell);
+	acpi_write((doorbell_value & doorbell_preserve) | doorbell_write,
+		   &doorbell);
+
+	for (i = 0; i < POLL_LOOPS; i++) {
+		if (ioread16(&pcch_hdr->status) & CMD_COMPLETE)
+			break;
+	}
+}
+
+static inline void pcc_clear_mapping(void)
+{
+	if (pcch_virt_addr)
+		iounmap(pcch_virt_addr);
+	pcch_virt_addr = NULL;
+}
+
+static unsigned int pcc_get_freq(unsigned int cpu)
+{
+	struct pcc_cpu *pcc_cpu_data;
+	unsigned int curr_freq;
+	unsigned int freq_limit;
+	u16 status;
+	u32 input_buffer;
+	u32 output_buffer;
+
+	spin_lock(&pcc_lock);
+
+	dprintk("get: get_freq for CPU %d\n", cpu);
+	pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
+
+	input_buffer = 0x1;
+	iowrite32(input_buffer,
+			(pcch_virt_addr + pcc_cpu_data->input_offset));
+	iowrite16(CMD_GET_FREQ, &pcch_hdr->command);
+
+	pcc_cmd();
+
+	output_buffer =
+		ioread32(pcch_virt_addr + pcc_cpu_data->output_offset);
+
+	/* Clear the input buffer - we are done with the current command */
+	memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
+
+	status = ioread16(&pcch_hdr->status);
+	if (status != CMD_COMPLETE) {
+		dprintk("get: FAILED: for CPU %d, status is %d\n",
+			cpu, status);
+		goto cmd_incomplete;
+	}
+	iowrite16(0, &pcch_hdr->status);
+	curr_freq = (((ioread32(&pcch_hdr->nominal) * (output_buffer & 0xff))
+			/ 100) * 1000);
+
+	dprintk("get: SUCCESS: (virtual) output_offset for cpu %d is "
+		"0x%x, contains a value of: 0x%x. Speed is: %d MHz\n",
+		cpu, (pcch_virt_addr + pcc_cpu_data->output_offset),
+		output_buffer, curr_freq);
+
+	freq_limit = (output_buffer >> 8) & 0xff;
+	if (freq_limit != 0xff) {
+		dprintk("get: frequency for cpu %d is being temporarily"
+			" capped at %d\n", cpu, curr_freq);
+	}
+
+	spin_unlock(&pcc_lock);
+	return curr_freq;
+
+cmd_incomplete:
+	iowrite16(0, &pcch_hdr->status);
+	spin_unlock(&pcc_lock);
+	return -EINVAL;
+}
+
+static int pcc_cpufreq_target(struct cpufreq_policy *policy,
+			      unsigned int target_freq,
+			      unsigned int relation)
+{
+	struct pcc_cpu *pcc_cpu_data;
+	struct cpufreq_freqs freqs;
+	u16 status;
+	u32 input_buffer;
+	int cpu;
+
+	spin_lock(&pcc_lock);
+	cpu = policy->cpu;
+	pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
+
+	dprintk("target: CPU %d should go to target freq: %d "
+		"(virtual) input_offset is 0x%x\n",
+		cpu, target_freq,
+		(pcch_virt_addr + pcc_cpu_data->input_offset));
+
+	freqs.new = target_freq;
+	freqs.cpu = cpu;
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	input_buffer = 0x1 | (((target_freq * 100)
+			       / (ioread32(&pcch_hdr->nominal) * 1000)) << 8);
+	iowrite32(input_buffer,
+			(pcch_virt_addr + pcc_cpu_data->input_offset));
+	iowrite16(CMD_SET_FREQ, &pcch_hdr->command);
+
+	pcc_cmd();
+
+	/* Clear the input buffer - we are done with the current command */
+	memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
+
+	status = ioread16(&pcch_hdr->status);
+	if (status != CMD_COMPLETE) {
+		dprintk("target: FAILED for cpu %d, with status: 0x%x\n",
+			cpu, status);
+		goto cmd_incomplete;
+	}
+	iowrite16(0, &pcch_hdr->status);
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+	dprintk("target: was SUCCESSFUL for cpu %d\n", cpu);
+	spin_unlock(&pcc_lock);
+
+	return 0;
+
+cmd_incomplete:
+	iowrite16(0, &pcch_hdr->status);
+	spin_unlock(&pcc_lock);
+	return -EINVAL;
+}
+
+static int pcc_get_offset(int cpu)
+{
+	acpi_status status;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object *pccp, *offset;
+	struct pcc_cpu *pcc_cpu_data;
+	struct acpi_processor *pr;
+	int ret = 0;
+
+	pr = per_cpu(processors, cpu);
+	pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
+
+	status = acpi_evaluate_object(pr->handle, "PCCP", NULL, &buffer);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	pccp = buffer.pointer;
+	if (!pccp || pccp->type != ACPI_TYPE_PACKAGE) {
+		ret = -ENODEV;
+		goto out_free;
+	};
+
+	offset = &(pccp->package.elements[0]);
+	if (!offset || offset->type != ACPI_TYPE_INTEGER) {
+		ret = -ENODEV;
+		goto out_free;
+	}
+
+	pcc_cpu_data->input_offset = offset->integer.value;
+
+	offset = &(pccp->package.elements[1]);
+	if (!offset || offset->type != ACPI_TYPE_INTEGER) {
+		ret = -ENODEV;
+		goto out_free;
+	}
+
+	pcc_cpu_data->output_offset = offset->integer.value;
+
+	memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
+	memset_io((pcch_virt_addr + pcc_cpu_data->output_offset), 0, BUF_SZ);
+
+	dprintk("pcc_get_offset: for CPU %d: pcc_cpu_data "
+		"input_offset: 0x%x, pcc_cpu_data output_offset: 0x%x\n",
+		cpu, pcc_cpu_data->input_offset, pcc_cpu_data->output_offset);
+out_free:
+	kfree(buffer.pointer);
+	return ret;
+}
+
+static int __init pcc_cpufreq_do_osc(acpi_handle *handle)
+{
+	acpi_status status;
+	struct acpi_object_list input;
+	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object in_params[4];
+	union acpi_object *out_obj;
+	u32 capabilities[2];
+	u32 errors;
+	u32 supported;
+	int ret = 0;
+
+	input.count = 4;
+	input.pointer = in_params;
+	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      = 2;
+	in_params[3].type               = ACPI_TYPE_BUFFER;
+	in_params[3].buffer.length      = 8;
+	in_params[3].buffer.pointer     = (u8 *)&capabilities;
+
+	capabilities[0] = OSC_QUERY_ENABLE;
+	capabilities[1] = 0x1;
+
+	status = acpi_evaluate_object(*handle, "_OSC", &input, &output);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	if (!output.length)
+		return -ENODEV;
+
+	out_obj = output.pointer;
+	if (out_obj->type != ACPI_TYPE_BUFFER) {
+		ret = -ENODEV;
+		goto out_free;
+	}
+
+	errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
+	if (errors) {
+		ret = -ENODEV;
+		goto out_free;
+	}
+
+	supported = *((u32 *)(out_obj->buffer.pointer + 4));
+	if (!(supported & 0x1)) {
+		ret = -ENODEV;
+		goto out_free;
+	}
+
+	kfree(output.pointer);
+	capabilities[0] = 0x0;
+	capabilities[1] = 0x1;
+
+	status = acpi_evaluate_object(*handle, "_OSC", &input, &output);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	if (!output.length)
+		return -ENODEV;
+
+	out_obj = output.pointer;
+	if (out_obj->type != ACPI_TYPE_BUFFER) {
+		ret = -ENODEV;
+		goto out_free;
+	}
+
+	errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
+	if (errors) {
+		ret = -ENODEV;
+		goto out_free;
+	}
+
+	supported = *((u32 *)(out_obj->buffer.pointer + 4));
+	if (!(supported & 0x1)) {
+		ret = -ENODEV;
+		goto out_free;
+	}
+
+out_free:
+	kfree(output.pointer);
+	return ret;
+}
+
+static int __init pcc_cpufreq_probe(void)
+{
+	acpi_status status;
+	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct pcc_memory_resource *mem_resource;
+	struct pcc_register_resource *reg_resource;
+	union acpi_object *out_obj, *member;
+	acpi_handle handle, osc_handle;
+	int ret = 0;
+
+	status = acpi_get_handle(NULL, "\\_SB", &handle);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	status = acpi_get_handle(handle, "_OSC", &osc_handle);
+	if (ACPI_SUCCESS(status)) {
+		ret = pcc_cpufreq_do_osc(&osc_handle);
+		if (ret)
+			dprintk("probe: _OSC evaluation did not succeed\n");
+		/* Firmware's use of _OSC is optional */
+		ret = 0;
+	}
+
+	status = acpi_evaluate_object(handle, "PCCH", NULL, &output);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	out_obj = output.pointer;
+	if (out_obj->type != ACPI_TYPE_PACKAGE) {
+		ret = -ENODEV;
+		goto out_free;
+	}
+
+	member = &out_obj->package.elements[0];
+	if (member->type != ACPI_TYPE_BUFFER) {
+		ret = -ENODEV;
+		goto out_free;
+	}
+
+	mem_resource = (struct pcc_memory_resource *)member->buffer.pointer;
+
+	dprintk("probe: mem_resource descriptor: 0x%x,"
+		" length: %d, space_id: %d, resource_usage: %d,"
+		" type_specific: %d, granularity: 0x%llx,"
+		" minimum: 0x%llx, maximum: 0x%llx,"
+		" translation_offset: 0x%llx, address_length: 0x%llx\n",
+		mem_resource->descriptor, mem_resource->length,
+		mem_resource->space_id, mem_resource->resource_usage,
+		mem_resource->type_specific, mem_resource->granularity,
+		mem_resource->minimum, mem_resource->maximum,
+		mem_resource->translation_offset,
+		mem_resource->address_length);
+
+	if (mem_resource->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+		ret = -ENODEV;
+		goto out_free;
+	}
+
+	pcch_virt_addr = ioremap_nocache(mem_resource->minimum,
+					mem_resource->address_length);
+	if (pcch_virt_addr == NULL) {
+		dprintk("probe: could not map shared mem region\n");
+		goto out_free;
+	}
+	pcch_hdr = pcch_virt_addr;
+
+	dprintk("probe: PCCH header (virtual) addr: 0x%p\n", pcch_hdr);
+	dprintk("probe: PCCH header is at physical address: 0x%llx,"
+		" signature: 0x%x, length: %d bytes, major: %d, minor: %d,"
+		" supported features: 0x%x, command field: 0x%x,"
+		" status field: 0x%x, nominal latency: %d us\n",
+		mem_resource->minimum, ioread32(&pcch_hdr->signature),
+		ioread16(&pcch_hdr->length), ioread8(&pcch_hdr->major),
+		ioread8(&pcch_hdr->minor), ioread32(&pcch_hdr->features),
+		ioread16(&pcch_hdr->command), ioread16(&pcch_hdr->status),
+		ioread32(&pcch_hdr->latency));
+
+	dprintk("probe: min time between commands: %d us,"
+		" max time between commands: %d us,"
+		" nominal CPU frequency: %d MHz,"
+		" minimum CPU frequency: %d MHz,"
+		" minimum CPU frequency without throttling: %d MHz\n",
+		ioread32(&pcch_hdr->minimum_time),
+		ioread32(&pcch_hdr->maximum_time),
+		ioread32(&pcch_hdr->nominal),
+		ioread32(&pcch_hdr->throttled_frequency),
+		ioread32(&pcch_hdr->minimum_frequency));
+
+	member = &out_obj->package.elements[1];
+	if (member->type != ACPI_TYPE_BUFFER) {
+		ret = -ENODEV;
+		goto pcch_free;
+	}
+
+	reg_resource = (struct pcc_register_resource *)member->buffer.pointer;
+
+	doorbell.space_id = reg_resource->space_id;
+	doorbell.bit_width = reg_resource->bit_width;
+	doorbell.bit_offset = reg_resource->bit_offset;
+	doorbell.access_width = 64;
+	doorbell.address = reg_resource->address;
+
+	dprintk("probe: doorbell: space_id is %d, bit_width is %d, "
+		"bit_offset is %d, access_width is %d, address is 0x%llx\n",
+		doorbell.space_id, doorbell.bit_width, doorbell.bit_offset,
+		doorbell.access_width, reg_resource->address);
+
+	member = &out_obj->package.elements[2];
+	if (member->type != ACPI_TYPE_INTEGER) {
+		ret = -ENODEV;
+		goto pcch_free;
+	}
+
+	doorbell_preserve = member->integer.value;
+
+	member = &out_obj->package.elements[3];
+	if (member->type != ACPI_TYPE_INTEGER) {
+		ret = -ENODEV;
+		goto pcch_free;
+	}
+
+	doorbell_write = member->integer.value;
+
+	dprintk("probe: doorbell_preserve: 0x%llx,"
+		" doorbell_write: 0x%llx\n",
+		doorbell_preserve, doorbell_write);
+
+	pcc_cpu_info = alloc_percpu(struct pcc_cpu);
+	if (!pcc_cpu_info) {
+		ret = -ENOMEM;
+		goto pcch_free;
+	}
+
+	printk(KERN_DEBUG "pcc-cpufreq: (v%s) driver loaded with frequency"
+	       " limits: %d MHz, %d MHz\n", PCC_VERSION,
+	       ioread32(&pcch_hdr->minimum_frequency),
+	       ioread32(&pcch_hdr->nominal));
+	kfree(output.pointer);
+	return ret;
+pcch_free:
+	pcc_clear_mapping();
+out_free:
+	kfree(output.pointer);
+	return ret;
+}
+
+static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+	unsigned int cpu = policy->cpu;
+	unsigned int result = 0;
+
+	if (!pcch_virt_addr) {
+		result = -1;
+		goto pcch_null;
+	}
+
+	result = pcc_get_offset(cpu);
+	if (result) {
+		dprintk("init: PCCP evaluation failed\n");
+		goto free;
+	}
+
+	policy->max = policy->cpuinfo.max_freq =
+		ioread32(&pcch_hdr->nominal) * 1000;
+	policy->min = policy->cpuinfo.min_freq =
+		ioread32(&pcch_hdr->minimum_frequency) * 1000;
+	policy->cur = pcc_get_freq(cpu);
+
+	dprintk("init: policy->max is %d, policy->min is %d\n",
+		policy->max, policy->min);
+
+	return 0;
+free:
+	pcc_clear_mapping();
+	free_percpu(pcc_cpu_info);
+pcch_null:
+	return result;
+}
+
+static int pcc_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+{
+	return 0;
+}
+
+static struct cpufreq_driver pcc_cpufreq_driver = {
+	.flags = CPUFREQ_CONST_LOOPS,
+	.get = pcc_get_freq,
+	.verify = pcc_cpufreq_verify,
+	.target = pcc_cpufreq_target,
+	.init = pcc_cpufreq_cpu_init,
+	.exit = pcc_cpufreq_cpu_exit,
+	.name = "pcc-cpufreq",
+	.owner = THIS_MODULE,
+};
+
+static int __init pcc_cpufreq_init(void)
+{
+	int ret;
+
+	if (acpi_disabled)
+		return 0;
+
+	ret = pcc_cpufreq_probe();
+	if (ret) {
+		dprintk("pcc_cpufreq_init: PCCH evaluation failed\n");
+		return ret;
+	}
+
+	ret = cpufreq_register_driver(&pcc_cpufreq_driver);
+
+	return ret;
+}
+
+static void __exit pcc_cpufreq_exit(void)
+{
+	cpufreq_unregister_driver(&pcc_cpufreq_driver);
+
+	pcc_clear_mapping();
+
+	free_percpu(pcc_cpu_info);
+}
+
+MODULE_AUTHOR("Matthew Garrett, Naga Chumbalkar");
+MODULE_VERSION(PCC_VERSION);
+MODULE_DESCRIPTION("Processor Clocking Control interface driver");
+MODULE_LICENSE("GPL");
+
+late_initcall(pcc_cpufreq_init);
+module_exit(pcc_cpufreq_exit);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k6.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k6.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k6.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/timex.h>
 #include <linux/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c	2010-05-16 17:17:36.000000000 -0400
@@ -806,7 +806,7 @@ static int find_psb_table(struct powerno
 static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data,
 		unsigned int index)
 {
-	acpi_integer control;
+	u64 control;
 
 	if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE))
 		return;
@@ -824,7 +824,7 @@ static int powernow_k8_cpu_init_acpi(str
 {
 	struct cpufreq_frequency_table *powernow_table;
 	int ret_val = -ENODEV;
-	acpi_integer control, status;
+	u64 control, status;
 
 	if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) {
 		dprintk("register performance failed: bad ACPI data\n");
@@ -929,7 +929,8 @@ static int fill_powernow_table_pstate(st
 		powernow_table[i].index = index;
 
 		/* Frequency may be rounded for these */
-		if (boot_cpu_data.x86 == 0x10 || boot_cpu_data.x86 == 0x11) {
+		if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)
+				 || boot_cpu_data.x86 == 0x11) {
 			powernow_table[i].frequency =
 				freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7);
 		} else
@@ -948,7 +949,7 @@ static int fill_powernow_table_fidvid(st
 		u32 fid;
 		u32 vid;
 		u32 freq, index;
-		acpi_integer status, control;
+		u64 status, control;
 
 		if (data->exttype) {
 			status =  data->acpi_data.states[i].status;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/sched.h>	/* current */
 #include <linux/delay.h>
 #include <linux/compiler.h>
+#include <linux/gfp.h>
 
 #include <asm/msr.h>
 #include <asm/processor.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/sched.h>
 
 #include "speedstep-lib.h"
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
-#include <linux/slab.h>
 
 #include <asm/msr.h>
 #include <asm/tsc.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <asm/ist.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/intel.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/intel.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/intel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/intel.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,27 @@ static void __cpuinit early_init_intel(s
 		(c->x86 == 0x6 && c->x86_model >= 0x0e))
 		set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
 
+	/*
+	 * Atom erratum AAE44/AAF40/AAG38/AAH41:
+	 *
+	 * A race condition between speculative fetches and invalidating
+	 * a large page.  This is worked around in microcode, but we
+	 * need the microcode to have already been loaded... so if it is
+	 * not, recommend a BIOS update and disable large pages.
+	 */
+	if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_mask <= 2) {
+		u32 ucode, junk;
+
+		wrmsr(MSR_IA32_UCODE_REV, 0, 0);
+		sync_core();
+		rdmsr(MSR_IA32_UCODE_REV, junk, ucode);
+
+		if (ucode < 0x20e) {
+			printk(KERN_WARNING "Atom PSE erratum detected, BIOS microcode update recommended\n");
+			clear_cpu_cap(c, X86_FEATURE_PSE);
+		}
+	}
+
 #ifdef CONFIG_X86_64
 	set_cpu_cap(c, X86_FEATURE_SYSENTER32);
 #else
@@ -70,7 +91,8 @@ static void __cpuinit early_init_intel(s
 	if (c->x86_power & (1 << 8)) {
 		set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
 		set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
-		sched_clock_stable = 1;
+		if (!check_tsc_unstable())
+			sched_clock_stable = 1;
 	}
 
 	/*
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/intel_cacheinfo.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/intel_cacheinfo.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/intel_cacheinfo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/intel_cacheinfo.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <asm/processor.h>
 #include <linux/smp.h>
 #include <asm/k8.h>
+#include <asm/smp.h>
 
 #define LVL_1_INST	1
 #define LVL_1_DATA	2
@@ -31,6 +32,8 @@ struct _cache_table {
 	short size;
 };
 
+#define MB(x)	((x) * 1024)
+
 /* All the cache descriptor types we care about (no TLB or
    trace cache entries) */
 
@@ -44,9 +47,9 @@ static const struct _cache_table __cpuin
 	{ 0x0d, LVL_1_DATA, 16 },	/* 4-way set assoc, 64 byte line size */
 	{ 0x21, LVL_2,      256 },	/* 8-way set assoc, 64 byte line size */
 	{ 0x22, LVL_3,      512 },	/* 4-way set assoc, sectored cache, 64 byte line size */
-	{ 0x23, LVL_3,      1024 },	/* 8-way set assoc, sectored cache, 64 byte line size */
-	{ 0x25, LVL_3,      2048 },	/* 8-way set assoc, sectored cache, 64 byte line size */
-	{ 0x29, LVL_3,      4096 },	/* 8-way set assoc, sectored cache, 64 byte line size */
+	{ 0x23, LVL_3,      MB(1) },	/* 8-way set assoc, sectored cache, 64 byte line size */
+	{ 0x25, LVL_3,      MB(2) },	/* 8-way set assoc, sectored cache, 64 byte line size */
+	{ 0x29, LVL_3,      MB(4) },	/* 8-way set assoc, sectored cache, 64 byte line size */
 	{ 0x2c, LVL_1_DATA, 32 },	/* 8-way set assoc, 64 byte line size */
 	{ 0x30, LVL_1_INST, 32 },	/* 8-way set assoc, 64 byte line size */
 	{ 0x39, LVL_2,      128 },	/* 4-way set assoc, sectored cache, 64 byte line size */
@@ -59,16 +62,16 @@ static const struct _cache_table __cpuin
 	{ 0x41, LVL_2,      128 },	/* 4-way set assoc, 32 byte line size */
 	{ 0x42, LVL_2,      256 },	/* 4-way set assoc, 32 byte line size */
 	{ 0x43, LVL_2,      512 },	/* 4-way set assoc, 32 byte line size */
-	{ 0x44, LVL_2,      1024 },	/* 4-way set assoc, 32 byte line size */
-	{ 0x45, LVL_2,      2048 },	/* 4-way set assoc, 32 byte line size */
-	{ 0x46, LVL_3,      4096 },	/* 4-way set assoc, 64 byte line size */
-	{ 0x47, LVL_3,      8192 },	/* 8-way set assoc, 64 byte line size */
-	{ 0x49, LVL_3,      4096 },	/* 16-way set assoc, 64 byte line size */
-	{ 0x4a, LVL_3,      6144 },	/* 12-way set assoc, 64 byte line size */
-	{ 0x4b, LVL_3,      8192 },	/* 16-way set assoc, 64 byte line size */
-	{ 0x4c, LVL_3,     12288 },	/* 12-way set assoc, 64 byte line size */
-	{ 0x4d, LVL_3,     16384 },	/* 16-way set assoc, 64 byte line size */
-	{ 0x4e, LVL_2,      6144 },	/* 24-way set assoc, 64 byte line size */
+	{ 0x44, LVL_2,      MB(1) },	/* 4-way set assoc, 32 byte line size */
+	{ 0x45, LVL_2,      MB(2) },	/* 4-way set assoc, 32 byte line size */
+	{ 0x46, LVL_3,      MB(4) },	/* 4-way set assoc, 64 byte line size */
+	{ 0x47, LVL_3,      MB(8) },	/* 8-way set assoc, 64 byte line size */
+	{ 0x49, LVL_3,      MB(4) },	/* 16-way set assoc, 64 byte line size */
+	{ 0x4a, LVL_3,      MB(6) },	/* 12-way set assoc, 64 byte line size */
+	{ 0x4b, LVL_3,      MB(8) },	/* 16-way set assoc, 64 byte line size */
+	{ 0x4c, LVL_3,      MB(12) },	/* 12-way set assoc, 64 byte line size */
+	{ 0x4d, LVL_3,      MB(16) },	/* 16-way set assoc, 64 byte line size */
+	{ 0x4e, LVL_2,      MB(6) },	/* 24-way set assoc, 64 byte line size */
 	{ 0x60, LVL_1_DATA, 16 },	/* 8-way set assoc, sectored cache, 64 byte line size */
 	{ 0x66, LVL_1_DATA, 8 },	/* 4-way set assoc, sectored cache, 64 byte line size */
 	{ 0x67, LVL_1_DATA, 16 },	/* 4-way set assoc, sectored cache, 64 byte line size */
@@ -77,34 +80,34 @@ static const struct _cache_table __cpuin
 	{ 0x71, LVL_TRACE,  16 },	/* 8-way set assoc */
 	{ 0x72, LVL_TRACE,  32 },	/* 8-way set assoc */
 	{ 0x73, LVL_TRACE,  64 },	/* 8-way set assoc */
-	{ 0x78, LVL_2,    1024 },	/* 4-way set assoc, 64 byte line size */
-	{ 0x79, LVL_2,     128 },	/* 8-way set assoc, sectored cache, 64 byte line size */
-	{ 0x7a, LVL_2,     256 },	/* 8-way set assoc, sectored cache, 64 byte line size */
-	{ 0x7b, LVL_2,     512 },	/* 8-way set assoc, sectored cache, 64 byte line size */
-	{ 0x7c, LVL_2,    1024 },	/* 8-way set assoc, sectored cache, 64 byte line size */
-	{ 0x7d, LVL_2,    2048 },	/* 8-way set assoc, 64 byte line size */
-	{ 0x7f, LVL_2,     512 },	/* 2-way set assoc, 64 byte line size */
-	{ 0x82, LVL_2,     256 },	/* 8-way set assoc, 32 byte line size */
-	{ 0x83, LVL_2,     512 },	/* 8-way set assoc, 32 byte line size */
-	{ 0x84, LVL_2,    1024 },	/* 8-way set assoc, 32 byte line size */
-	{ 0x85, LVL_2,    2048 },	/* 8-way set assoc, 32 byte line size */
-	{ 0x86, LVL_2,     512 },	/* 4-way set assoc, 64 byte line size */
-	{ 0x87, LVL_2,    1024 },	/* 8-way set assoc, 64 byte line size */
-	{ 0xd0, LVL_3,     512 },	/* 4-way set assoc, 64 byte line size */
-	{ 0xd1, LVL_3,    1024 },	/* 4-way set assoc, 64 byte line size */
-	{ 0xd2, LVL_3,    2048 },	/* 4-way set assoc, 64 byte line size */
-	{ 0xd6, LVL_3,    1024 },	/* 8-way set assoc, 64 byte line size */
-	{ 0xd7, LVL_3,    2048 },	/* 8-way set assoc, 64 byte line size */
-	{ 0xd8, LVL_3,    4096 },	/* 12-way set assoc, 64 byte line size */
-	{ 0xdc, LVL_3,    2048 },	/* 12-way set assoc, 64 byte line size */
-	{ 0xdd, LVL_3,    4096 },	/* 12-way set assoc, 64 byte line size */
-	{ 0xde, LVL_3,    8192 },	/* 12-way set assoc, 64 byte line size */
-	{ 0xe2, LVL_3,    2048 },	/* 16-way set assoc, 64 byte line size */
-	{ 0xe3, LVL_3,    4096 },	/* 16-way set assoc, 64 byte line size */
-	{ 0xe4, LVL_3,    8192 },	/* 16-way set assoc, 64 byte line size */
-	{ 0xea, LVL_3,    12288 },	/* 24-way set assoc, 64 byte line size */
-	{ 0xeb, LVL_3,    18432 },	/* 24-way set assoc, 64 byte line size */
-	{ 0xec, LVL_3,    24576 },	/* 24-way set assoc, 64 byte line size */
+	{ 0x78, LVL_2,      MB(1) },	/* 4-way set assoc, 64 byte line size */
+	{ 0x79, LVL_2,      128 },	/* 8-way set assoc, sectored cache, 64 byte line size */
+	{ 0x7a, LVL_2,      256 },	/* 8-way set assoc, sectored cache, 64 byte line size */
+	{ 0x7b, LVL_2,      512 },	/* 8-way set assoc, sectored cache, 64 byte line size */
+	{ 0x7c, LVL_2,      MB(1) },	/* 8-way set assoc, sectored cache, 64 byte line size */
+	{ 0x7d, LVL_2,      MB(2) },	/* 8-way set assoc, 64 byte line size */
+	{ 0x7f, LVL_2,      512 },	/* 2-way set assoc, 64 byte line size */
+	{ 0x82, LVL_2,      256 },	/* 8-way set assoc, 32 byte line size */
+	{ 0x83, LVL_2,      512 },	/* 8-way set assoc, 32 byte line size */
+	{ 0x84, LVL_2,      MB(1) },	/* 8-way set assoc, 32 byte line size */
+	{ 0x85, LVL_2,      MB(2) },	/* 8-way set assoc, 32 byte line size */
+	{ 0x86, LVL_2,      512 },	/* 4-way set assoc, 64 byte line size */
+	{ 0x87, LVL_2,      MB(1) },	/* 8-way set assoc, 64 byte line size */
+	{ 0xd0, LVL_3,      512 },	/* 4-way set assoc, 64 byte line size */
+	{ 0xd1, LVL_3,      MB(1) },	/* 4-way set assoc, 64 byte line size */
+	{ 0xd2, LVL_3,      MB(2) },	/* 4-way set assoc, 64 byte line size */
+	{ 0xd6, LVL_3,      MB(1) },	/* 8-way set assoc, 64 byte line size */
+	{ 0xd7, LVL_3,      MB(2) },	/* 8-way set assoc, 64 byte line size */
+	{ 0xd8, LVL_3,      MB(4) },	/* 12-way set assoc, 64 byte line size */
+	{ 0xdc, LVL_3,      MB(2) },	/* 12-way set assoc, 64 byte line size */
+	{ 0xdd, LVL_3,      MB(4) },	/* 12-way set assoc, 64 byte line size */
+	{ 0xde, LVL_3,      MB(8) },	/* 12-way set assoc, 64 byte line size */
+	{ 0xe2, LVL_3,      MB(2) },	/* 16-way set assoc, 64 byte line size */
+	{ 0xe3, LVL_3,      MB(4) },	/* 16-way set assoc, 64 byte line size */
+	{ 0xe4, LVL_3,      MB(8) },	/* 16-way set assoc, 64 byte line size */
+	{ 0xea, LVL_3,      MB(12) },	/* 24-way set assoc, 64 byte line size */
+	{ 0xeb, LVL_3,      MB(18) },	/* 24-way set assoc, 64 byte line size */
+	{ 0xec, LVL_3,      MB(24) },	/* 24-way set assoc, 64 byte line size */
 	{ 0x00, 0, 0}
 };
 
@@ -150,7 +153,8 @@ struct _cpuid4_info {
 	union _cpuid4_leaf_ebx ebx;
 	union _cpuid4_leaf_ecx ecx;
 	unsigned long size;
-	unsigned long can_disable;
+	bool can_disable;
+	unsigned int l3_indices;
 	DECLARE_BITMAP(shared_cpu_map, NR_CPUS);
 };
 
@@ -160,7 +164,8 @@ struct _cpuid4_info_regs {
 	union _cpuid4_leaf_ebx ebx;
 	union _cpuid4_leaf_ecx ecx;
 	unsigned long size;
-	unsigned long can_disable;
+	bool can_disable;
+	unsigned int l3_indices;
 };
 
 unsigned short			num_cache_leaves;
@@ -290,6 +295,36 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_
 		(ebx->split.ways_of_associativity + 1) - 1;
 }
 
+struct _cache_attr {
+	struct attribute attr;
+	ssize_t (*show)(struct _cpuid4_info *, char *);
+	ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
+};
+
+#ifdef CONFIG_CPU_SUP_AMD
+static unsigned int __cpuinit amd_calc_l3_indices(void)
+{
+	/*
+	 * We're called over smp_call_function_single() and therefore
+	 * are on the correct cpu.
+	 */
+	int cpu = smp_processor_id();
+	int node = cpu_to_node(cpu);
+	struct pci_dev *dev = node_to_k8_nb_misc(node);
+	unsigned int sc0, sc1, sc2, sc3;
+	u32 val = 0;
+
+	pci_read_config_dword(dev, 0x1C4, &val);
+
+	/* calculate subcache sizes */
+	sc0 = !(val & BIT(0));
+	sc1 = !(val & BIT(4));
+	sc2 = !(val & BIT(8))  + !(val & BIT(9));
+	sc3 = !(val & BIT(12)) + !(val & BIT(13));
+
+	return (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1;
+}
+
 static void __cpuinit
 amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
 {
@@ -299,13 +334,108 @@ amd_check_l3_disable(int index, struct _
 	if (boot_cpu_data.x86 == 0x11)
 		return;
 
-	/* see erratum #382 */
-	if ((boot_cpu_data.x86 == 0x10) && (boot_cpu_data.x86_model < 0x8))
+	/* see errata #382 and #388 */
+	if ((boot_cpu_data.x86 == 0x10) &&
+	    ((boot_cpu_data.x86_model < 0x8) ||
+	     (boot_cpu_data.x86_mask  < 0x1)))
 		return;
 
-	this_leaf->can_disable = 1;
+	/* not in virtualized environments */
+	if (num_k8_northbridges == 0)
+		return;
+
+	this_leaf->can_disable = true;
+	this_leaf->l3_indices  = amd_calc_l3_indices();
+}
+
+static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
+				  unsigned int index)
+{
+	int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
+	int node = amd_get_nb_id(cpu);
+	struct pci_dev *dev = node_to_k8_nb_misc(node);
+	unsigned int reg = 0;
+
+	if (!this_leaf->can_disable)
+		return -EINVAL;
+
+	if (!dev)
+		return -EINVAL;
+
+	pci_read_config_dword(dev, 0x1BC + index * 4, &reg);
+	return sprintf(buf, "0x%08x\n", reg);
+}
+
+#define SHOW_CACHE_DISABLE(index)					\
+static ssize_t								\
+show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf)	\
+{									\
+	return show_cache_disable(this_leaf, buf, index);		\
+}
+SHOW_CACHE_DISABLE(0)
+SHOW_CACHE_DISABLE(1)
+
+static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
+	const char *buf, size_t count, unsigned int index)
+{
+	int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
+	int node = amd_get_nb_id(cpu);
+	struct pci_dev *dev = node_to_k8_nb_misc(node);
+	unsigned long val = 0;
+
+#define SUBCACHE_MASK	(3UL << 20)
+#define SUBCACHE_INDEX	0xfff
+
+	if (!this_leaf->can_disable)
+		return -EINVAL;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (!dev)
+		return -EINVAL;
+
+	if (strict_strtoul(buf, 10, &val) < 0)
+		return -EINVAL;
+
+	/* do not allow writes outside of allowed bits */
+	if ((val & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) ||
+	    ((val & SUBCACHE_INDEX) > this_leaf->l3_indices))
+		return -EINVAL;
+
+	val |= BIT(30);
+	pci_write_config_dword(dev, 0x1BC + index * 4, val);
+	/*
+	 * We need to WBINVD on a core on the node containing the L3 cache which
+	 * indices we disable therefore a simple wbinvd() is not sufficient.
+	 */
+	wbinvd_on_cpu(cpu);
+	pci_write_config_dword(dev, 0x1BC + index * 4, val | BIT(31));
+	return count;
 }
 
+#define STORE_CACHE_DISABLE(index)					\
+static ssize_t								\
+store_cache_disable_##index(struct _cpuid4_info *this_leaf,		\
+			    const char *buf, size_t count)		\
+{									\
+	return store_cache_disable(this_leaf, buf, count, index);	\
+}
+STORE_CACHE_DISABLE(0)
+STORE_CACHE_DISABLE(1)
+
+static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644,
+		show_cache_disable_0, store_cache_disable_0);
+static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
+		show_cache_disable_1, store_cache_disable_1);
+
+#else	/* CONFIG_CPU_SUP_AMD */
+static void __cpuinit
+amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
+{
+};
+#endif /* CONFIG_CPU_SUP_AMD */
+
 static int
 __cpuinit cpuid4_cache_lookup_regs(int index,
 				   struct _cpuid4_info_regs *this_leaf)
@@ -711,82 +841,6 @@ static ssize_t show_type(struct _cpuid4_
 #define to_object(k)	container_of(k, struct _index_kobject, kobj)
 #define to_attr(a)	container_of(a, struct _cache_attr, attr)
 
-static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
-				  unsigned int index)
-{
-	int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
-	int node = cpu_to_node(cpu);
-	struct pci_dev *dev = node_to_k8_nb_misc(node);
-	unsigned int reg = 0;
-
-	if (!this_leaf->can_disable)
-		return -EINVAL;
-
-	if (!dev)
-		return -EINVAL;
-
-	pci_read_config_dword(dev, 0x1BC + index * 4, &reg);
-	return sprintf(buf, "%x\n", reg);
-}
-
-#define SHOW_CACHE_DISABLE(index)					\
-static ssize_t								\
-show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf)  	\
-{									\
-	return show_cache_disable(this_leaf, buf, index);		\
-}
-SHOW_CACHE_DISABLE(0)
-SHOW_CACHE_DISABLE(1)
-
-static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
-	const char *buf, size_t count, unsigned int index)
-{
-	int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
-	int node = cpu_to_node(cpu);
-	struct pci_dev *dev = node_to_k8_nb_misc(node);
-	unsigned long val = 0;
-	unsigned int scrubber = 0;
-
-	if (!this_leaf->can_disable)
-		return -EINVAL;
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	if (!dev)
-		return -EINVAL;
-
-	if (strict_strtoul(buf, 10, &val) < 0)
-		return -EINVAL;
-
-	val |= 0xc0000000;
-
-	pci_read_config_dword(dev, 0x58, &scrubber);
-	scrubber &= ~0x1f000000;
-	pci_write_config_dword(dev, 0x58, scrubber);
-
-	pci_write_config_dword(dev, 0x1BC + index * 4, val & ~0x40000000);
-	wbinvd();
-	pci_write_config_dword(dev, 0x1BC + index * 4, val);
-	return count;
-}
-
-#define STORE_CACHE_DISABLE(index)					\
-static ssize_t								\
-store_cache_disable_##index(struct _cpuid4_info *this_leaf,	     	\
-			    const char *buf, size_t count)		\
-{									\
-	return store_cache_disable(this_leaf, buf, count, index);	\
-}
-STORE_CACHE_DISABLE(0)
-STORE_CACHE_DISABLE(1)
-
-struct _cache_attr {
-	struct attribute attr;
-	ssize_t (*show)(struct _cpuid4_info *, char *);
-	ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
-};
-
 #define define_one_ro(_name) \
 static struct _cache_attr _name = \
 	__ATTR(_name, 0444, show_##_name, NULL)
@@ -801,23 +855,28 @@ define_one_ro(size);
 define_one_ro(shared_cpu_map);
 define_one_ro(shared_cpu_list);
 
-static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644,
-		show_cache_disable_0, store_cache_disable_0);
-static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
-		show_cache_disable_1, store_cache_disable_1);
+#define DEFAULT_SYSFS_CACHE_ATTRS	\
+	&type.attr,			\
+	&level.attr,			\
+	&coherency_line_size.attr,	\
+	&physical_line_partition.attr,	\
+	&ways_of_associativity.attr,	\
+	&number_of_sets.attr,		\
+	&size.attr,			\
+	&shared_cpu_map.attr,		\
+	&shared_cpu_list.attr
 
 static struct attribute *default_attrs[] = {
-	&type.attr,
-	&level.attr,
-	&coherency_line_size.attr,
-	&physical_line_partition.attr,
-	&ways_of_associativity.attr,
-	&number_of_sets.attr,
-	&size.attr,
-	&shared_cpu_map.attr,
-	&shared_cpu_list.attr,
+	DEFAULT_SYSFS_CACHE_ATTRS,
+	NULL
+};
+
+static struct attribute *default_l3_attrs[] = {
+	DEFAULT_SYSFS_CACHE_ATTRS,
+#ifdef CONFIG_CPU_SUP_AMD
 	&cache_disable_0.attr,
 	&cache_disable_1.attr,
+#endif
 	NULL
 };
 
@@ -848,7 +907,7 @@ static ssize_t store(struct kobject *kob
 	return ret;
 }
 
-static struct sysfs_ops sysfs_ops = {
+static const struct sysfs_ops sysfs_ops = {
 	.show   = show,
 	.store  = store,
 };
@@ -908,6 +967,7 @@ static int __cpuinit cache_add_dev(struc
 	unsigned int cpu = sys_dev->id;
 	unsigned long i, j;
 	struct _index_kobject *this_object;
+	struct _cpuid4_info   *this_leaf;
 	int retval;
 
 	retval = cpuid4_cache_sysfs_init(cpu);
@@ -926,6 +986,14 @@ static int __cpuinit cache_add_dev(struc
 		this_object = INDEX_KOBJECT_PTR(cpu, i);
 		this_object->cpu = cpu;
 		this_object->index = i;
+
+		this_leaf = CPUID4_INFO_IDX(cpu, i);
+
+		if (this_leaf->can_disable)
+			ktype_cache.default_attrs = default_l3_attrs;
+		else
+			ktype_cache.default_attrs = default_attrs;
+
 		retval = kobject_init_and_add(&(this_object->kobj),
 					      &ktype_cache,
 					      per_cpu(ici_cache_kobject, cpu),
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mcheck/mce_amd.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mcheck/mce_amd.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mcheck/mce_amd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mcheck/mce_amd.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/cpu.h>
 #include <linux/smp.h>
@@ -388,7 +389,7 @@ static ssize_t store(struct kobject *kob
 	return ret;
 }
 
-static struct sysfs_ops threshold_ops = {
+static const struct sysfs_ops threshold_ops = {
 	.show			= show,
 	.store			= store,
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mcheck/mce.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mcheck/mce.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mcheck/mce.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mcheck/mce.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/sched.h>
 #include <linux/sysfs.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/poll.h>
@@ -46,6 +47,13 @@
 
 #include "mce-internal.h"
 
+static DEFINE_MUTEX(mce_read_mutex);
+
+#define rcu_dereference_check_mce(p) \
+	rcu_dereference_check((p), \
+			      rcu_read_lock_sched_held() || \
+			      lockdep_is_held(&mce_read_mutex))
+
 #define CREATE_TRACE_POINTS
 #include <trace/events/mce.h>
 
@@ -158,7 +166,7 @@ void mce_log(struct mce *mce)
 	mce->finished = 0;
 	wmb();
 	for (;;) {
-		entry = rcu_dereference(mcelog.next);
+		entry = rcu_dereference_check_mce(mcelog.next);
 		for (;;) {
 			/*
 			 * When the buffer fills up discard new entries.
@@ -1485,8 +1493,6 @@ static void collect_tscs(void *data)
 	rdtscll(cpu_tsc[smp_processor_id()]);
 }
 
-static DEFINE_MUTEX(mce_read_mutex);
-
 static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize,
 			loff_t *off)
 {
@@ -1500,7 +1506,7 @@ static ssize_t mce_read(struct file *fil
 		return -ENOMEM;
 
 	mutex_lock(&mce_read_mutex);
-	next = rcu_dereference(mcelog.next);
+	next = rcu_dereference_check_mce(mcelog.next);
 
 	/* Only supports full reads right now */
 	if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) {
@@ -1565,7 +1571,7 @@ timeout:
 static unsigned int mce_poll(struct file *file, poll_table *wait)
 {
 	poll_wait(file, &mce_wait, wait);
-	if (rcu_dereference(mcelog.next))
+	if (rcu_dereference_check_mce(mcelog.next))
 		return POLLIN | POLLRDNORM;
 	return 0;
 }
@@ -2044,6 +2050,7 @@ static __init void mce_init_banks(void)
 		struct mce_bank *b = &mce_banks[i];
 		struct sysdev_attribute *a = &b->attr;
 
+		sysfs_attr_init(&a->attr);
 		a->attr.name	= b->attrname;
 		snprintf(b->attrname, ATTR_LEN, "bank%d", i);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mcheck/mce-inject.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mcheck/mce-inject.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mcheck/mce-inject.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mcheck/mce-inject.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/kdebug.h>
 #include <linux/cpu.h>
 #include <linux/sched.h>
+#include <linux/gfp.h>
 #include <asm/mce.h>
 #include <asm/apic.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mcheck/mce_intel.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mcheck/mce_intel.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mcheck/mce_intel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mcheck/mce_intel.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
  * Author: Andi Kleen
  */
 
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/percpu.h>
@@ -95,7 +96,7 @@ static void cmci_discover(int banks, int
 
 		/* Already owned by someone else? */
 		if (val & CMCI_EN) {
-			if (test_and_clear_bit(i, owned) || boot)
+			if (test_and_clear_bit(i, owned) && !boot)
 				print_update("SHD", &hdr, i);
 			__clear_bit(i, __get_cpu_var(mce_poll_banks));
 			continue;
@@ -107,7 +108,7 @@ static void cmci_discover(int banks, int
 
 		/* Did the enable bit stick? -- the bank supports CMCI */
 		if (val & CMCI_EN) {
-			if (!test_and_set_bit(i, owned) || boot)
+			if (!test_and_set_bit(i, owned) && !boot)
 				print_update("CMCI", &hdr, i);
 			__clear_bit(i, __get_cpu_var(mce_poll_banks));
 		} else {
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/amd.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/amd.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/amd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/amd.c	2010-05-16 17:17:36.000000000 -0400
@@ -108,7 +108,7 @@ amd_validate_add_page(unsigned long base
 	return 0;
 }
 
-static struct mtrr_ops amd_mtrr_ops = {
+static const struct mtrr_ops amd_mtrr_ops = {
 	.vendor            = X86_VENDOR_AMD,
 	.set               = amd_set_mtrr,
 	.get               = amd_get_mtrr,
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/centaur.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/centaur.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/centaur.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/centaur.c	2010-05-16 17:17:36.000000000 -0400
@@ -110,7 +110,7 @@ centaur_validate_add_page(unsigned long
 	return 0;
 }
 
-static struct mtrr_ops centaur_mtrr_ops = {
+static const struct mtrr_ops centaur_mtrr_ops = {
 	.vendor            = X86_VENDOR_CENTAUR,
 	.set               = centaur_set_mcr,
 	.get               = centaur_get_mcr,
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,10 +22,10 @@
 #include <linux/pci.h>
 #include <linux/smp.h>
 #include <linux/cpu.h>
-#include <linux/sort.h>
 #include <linux/mutex.h>
 #include <linux/uaccess.h>
 #include <linux/kvm_para.h>
+#include <linux/range.h>
 
 #include <asm/processor.h>
 #include <asm/e820.h>
@@ -34,11 +34,6 @@
 
 #include "mtrr.h"
 
-struct res_range {
-	unsigned long	start;
-	unsigned long	end;
-};
-
 struct var_mtrr_range_state {
 	unsigned long	base_pfn;
 	unsigned long	size_pfn;
@@ -56,7 +51,7 @@ struct var_mtrr_state {
 /* Should be related to MTRR_VAR_RANGES nums */
 #define RANGE_NUM				256
 
-static struct res_range __initdata		range[RANGE_NUM];
+static struct range __initdata		range[RANGE_NUM];
 static int __initdata				nr_range;
 
 static struct var_mtrr_range_state __initdata	range_state[RANGE_NUM];
@@ -64,152 +59,11 @@ static struct var_mtrr_range_state __ini
 static int __initdata debug_print;
 #define Dprintk(x...) do { if (debug_print) printk(KERN_DEBUG x); } while (0)
 
-
-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 it: */
-	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;
-}
-
-static int __init clean_sort_range(struct res_range *range, int az)
-{
-	int i, j, k = az - 1, nr_range = 0;
-
-	for (i = 0; i < k; i++) {
-		if (range[i].end)
-			continue;
-		for (j = k; j > i; j--) {
-			if (range[j].end) {
-				k = j;
-				break;
-			}
-		}
-		if (j == i)
-			break;
-		range[i].start = range[k].start;
-		range[i].end   = range[k].end;
-		range[k].start = 0;
-		range[k].end   = 0;
-		k--;
-	}
-	/* count it */
-	for (i = 0; i < az; i++) {
-		if (!range[i].end) {
-			nr_range = i;
-			break;
-		}
-	}
-
-	/* sort them */
-	sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
-
-	return nr_range;
-}
-
 #define BIOS_BUG_MSG KERN_WARNING \
 	"WARNING: BIOS bug: VAR MTRR %d contains strange UC entry under 1M, check with your system vendor!\n"
 
 static int __init
-x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
+x86_get_mtrr_mem_range(struct range *range, int nr_range,
 		       unsigned long extra_remove_base,
 		       unsigned long extra_remove_size)
 {
@@ -223,14 +77,14 @@ x86_get_mtrr_mem_range(struct res_range
 			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);
+		nr_range = add_range_with_merge(range, RANGE_NUM, nr_range,
+						base, base + size);
 	}
 	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);
+			printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
+				 range[i].start, range[i].end);
 	}
 
 	/* Take out UC ranges: */
@@ -252,19 +106,19 @@ x86_get_mtrr_mem_range(struct res_range
 			size -= (1<<(20-PAGE_SHIFT)) - base;
 			base = 1<<(20-PAGE_SHIFT);
 		}
-		subtract_range(range, base, base + size - 1);
+		subtract_range(range, RANGE_NUM, base, base + size);
 	}
 	if (extra_remove_size)
-		subtract_range(range, extra_remove_base,
-				 extra_remove_base + extra_remove_size  - 1);
+		subtract_range(range, RANGE_NUM, extra_remove_base,
+				 extra_remove_base + extra_remove_size);
 
 	if  (debug_print) {
 		printk(KERN_DEBUG "After UC checking\n");
 		for (i = 0; i < RANGE_NUM; i++) {
 			if (!range[i].end)
 				continue;
-			printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
-				 range[i].start, range[i].end + 1);
+			printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
+				 range[i].start, range[i].end);
 		}
 	}
 
@@ -273,26 +127,22 @@ x86_get_mtrr_mem_range(struct res_range
 	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);
+			printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
+				 range[i].start, range[i].end);
 	}
 
-	/* clear those is not used */
-	for (i = nr_range; i < RANGE_NUM; i++)
-		memset(&range[i], 0, sizeof(range[i]));
-
 	return nr_range;
 }
 
 #ifdef CONFIG_MTRR_SANITIZER
 
-static unsigned long __init sum_ranges(struct res_range *range, int nr_range)
+static unsigned long __init sum_ranges(struct range *range, int nr_range)
 {
 	unsigned long sum = 0;
 	int i;
 
 	for (i = 0; i < nr_range; i++)
-		sum += range[i].end + 1 - range[i].start;
+		sum += range[i].end - range[i].start;
 
 	return sum;
 }
@@ -621,7 +471,7 @@ static int __init parse_mtrr_spare_reg(c
 early_param("mtrr_spare_reg_nr", parse_mtrr_spare_reg);
 
 static int __init
-x86_setup_var_mtrrs(struct res_range *range, int nr_range,
+x86_setup_var_mtrrs(struct range *range, int nr_range,
 		    u64 chunk_size, u64 gran_size)
 {
 	struct var_mtrr_state var_state;
@@ -639,7 +489,7 @@ x86_setup_var_mtrrs(struct res_range *ra
 	/* Write the range: */
 	for (i = 0; i < nr_range; i++) {
 		set_var_mtrr_range(&var_state, range[i].start,
-				   range[i].end - range[i].start + 1);
+				   range[i].end - range[i].start);
 	}
 
 	/* Write the last range: */
@@ -742,7 +592,7 @@ mtrr_calc_range_state(u64 chunk_size, u6
 		      unsigned long x_remove_base,
 		      unsigned long x_remove_size, int i)
 {
-	static struct res_range range_new[RANGE_NUM];
+	static struct range range_new[RANGE_NUM];
 	unsigned long range_sums_new;
 	static int nr_range_new;
 	int num_reg;
@@ -869,10 +719,10 @@ int __init mtrr_cleanup(unsigned address
 	 * [0, 1M) should always be covered by var mtrr with WB
 	 * and fixed mtrrs should take effect before var mtrr for it:
 	 */
-	nr_range = add_range_with_merge(range, nr_range, 0,
-					(1ULL<<(20 - PAGE_SHIFT)) - 1);
+	nr_range = add_range_with_merge(range, RANGE_NUM, nr_range, 0,
+					1ULL<<(20 - PAGE_SHIFT));
 	/* Sort the ranges: */
-	sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
+	sort_range(range, nr_range);
 
 	range_sums = sum_ranges(range, nr_range);
 	printk(KERN_INFO "total RAM covered: %ldM\n",
@@ -1089,9 +939,9 @@ int __init mtrr_trim_uncached_memory(uns
 	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;
+		range[nr_range].end = mtrr_tom2 >> PAGE_SHIFT;
+		if (highest_pfn < range[nr_range].end)
+			highest_pfn = range[nr_range].end;
 		nr_range++;
 	}
 	nr_range = x86_get_mtrr_mem_range(range, nr_range, 0, 0);
@@ -1103,15 +953,15 @@ int __init mtrr_trim_uncached_memory(uns
 
 	/* 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,
+		if (range[i].end < range[i+1].start)
+			total_trim_size += real_trim_memory(range[i].end,
 							    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,
+	if (range[i].end < end_pfn)
+		total_trim_size += real_trim_memory(range[i].end,
 							 end_pfn);
 
 	if (total_trim_size) {
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/cyrix.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/cyrix.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/cyrix.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/cyrix.c	2010-05-16 17:17:36.000000000 -0400
@@ -265,7 +265,7 @@ static void cyrix_set_all(void)
 	post_set();
 }
 
-static struct mtrr_ops cyrix_mtrr_ops = {
+static const struct mtrr_ops cyrix_mtrr_ops = {
 	.vendor            = X86_VENDOR_CYRIX,
 	.set_all	   = cyrix_set_all,
 	.set               = cyrix_set_arr,
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/generic.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/generic.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/mm.h>
 
@@ -464,7 +463,7 @@ static void generic_get_mtrr(unsigned in
 		tmp |= ~((1<<(hi - 1)) - 1);
 
 		if (tmp != mask_lo) {
-			WARN_ONCE(1, KERN_INFO "mtrr: your BIOS has set up an incorrect mask, fixing it up.\n");
+			printk(KERN_WARNING "mtrr: your BIOS has configured an incorrect mask, fixing it.\n");
 			mask_lo = tmp;
 		}
 	}
@@ -570,7 +569,7 @@ static unsigned long set_mtrr_state(void
 
 
 static unsigned long cr4;
-static DEFINE_SPINLOCK(set_atomicity_lock);
+static DEFINE_RAW_SPINLOCK(set_atomicity_lock);
 
 /*
  * Since we are disabling the cache don't allow any interrupts,
@@ -590,7 +589,7 @@ static void prepare_set(void) __acquires
 	 * changes to the way the kernel boots
 	 */
 
-	spin_lock(&set_atomicity_lock);
+	raw_spin_lock(&set_atomicity_lock);
 
 	/* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */
 	cr0 = read_cr0() | X86_CR0_CD;
@@ -627,7 +626,7 @@ static void post_set(void) __releases(se
 	/* Restore value of CR4 */
 	if (cpu_has_pge)
 		write_cr4(cr4);
-	spin_unlock(&set_atomicity_lock);
+	raw_spin_unlock(&set_atomicity_lock);
 }
 
 static void generic_set_all(void)
@@ -752,7 +751,7 @@ int positive_have_wrcomb(void)
 /*
  * Generic structure...
  */
-struct mtrr_ops generic_mtrr_ops = {
+const struct mtrr_ops generic_mtrr_ops = {
 	.use_intel_if		= 1,
 	.set_all		= generic_set_all,
 	.get			= generic_get_mtrr,
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/if.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/if.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/if.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/if.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
 #include <linux/module.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #define LINE_SIZE 80
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/main.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/main.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/main.c	2010-05-16 17:17:36.000000000 -0400
@@ -60,14 +60,14 @@ static DEFINE_MUTEX(mtrr_mutex);
 u64 size_or_mask, size_and_mask;
 static bool mtrr_aps_delayed_init;
 
-static struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM];
+static const struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM];
 
-struct mtrr_ops *mtrr_if;
+const struct mtrr_ops *mtrr_if;
 
 static void set_mtrr(unsigned int reg, unsigned long base,
 		     unsigned long size, mtrr_type type);
 
-void set_mtrr_ops(struct mtrr_ops *ops)
+void set_mtrr_ops(const struct mtrr_ops *ops)
 {
 	if (ops->vendor && ops->vendor < X86_VENDOR_NUM)
 		mtrr_ops[ops->vendor] = ops;
@@ -145,6 +145,7 @@ struct set_mtrr_data {
 
 /**
  * ipi_handler - Synchronisation handler. Executed by "other" CPUs.
+ * @info: pointer to mtrr configuration data
  *
  * Returns nothing.
  */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/Makefile linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/Makefile
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,3 +1,3 @@
-obj-y		:= main.o if.o generic.o state.o cleanup.o
+obj-y		:= main.o if.o generic.o cleanup.o
 obj-$(CONFIG_X86_32) += amd.o cyrix.o centaur.o
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/mtrr.h linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/mtrr.h
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/mtrr.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/mtrr.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,7 @@ extern int generic_get_free_region(unsig
 extern int generic_validate_add_page(unsigned long base, unsigned long size,
 				     unsigned int type);
 
-extern struct mtrr_ops generic_mtrr_ops;
+extern const struct mtrr_ops generic_mtrr_ops;
 
 extern int positive_have_wrcomb(void);
 
@@ -53,10 +53,10 @@ void fill_mtrr_var_range(unsigned int in
 		u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi);
 void get_mtrr_state(void);
 
-extern void set_mtrr_ops(struct mtrr_ops *ops);
+extern void set_mtrr_ops(const struct mtrr_ops *ops);
 
 extern u64 size_or_mask, size_and_mask;
-extern struct mtrr_ops *mtrr_if;
+extern const struct mtrr_ops *mtrr_if;
 
 #define is_cpu(vnd)	(mtrr_if && mtrr_if->vendor == X86_VENDOR_##vnd)
 #define use_intel()	(mtrr_if && mtrr_if->use_intel_if == 1)
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/state.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/state.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/state.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/state.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,94 +0,0 @@
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/mm.h>
-
-#include <asm/processor-cyrix.h>
-#include <asm/processor-flags.h>
-#include <asm/mtrr.h>
-#include <asm/msr.h>
-
-#include "mtrr.h"
-
-/* Put the processor into a state where MTRRs can be safely set */
-void set_mtrr_prepare_save(struct set_mtrr_context *ctxt)
-{
-	unsigned int cr0;
-
-	/* Disable interrupts locally */
-	local_irq_save(ctxt->flags);
-
-	if (use_intel() || is_cpu(CYRIX)) {
-
-		/* Save value of CR4 and clear Page Global Enable (bit 7) */
-		if (cpu_has_pge) {
-			ctxt->cr4val = read_cr4();
-			write_cr4(ctxt->cr4val & ~X86_CR4_PGE);
-		}
-
-		/*
-		 * Disable and flush caches. Note that wbinvd flushes the TLBs
-		 * as a side-effect
-		 */
-		cr0 = read_cr0() | X86_CR0_CD;
-		wbinvd();
-		write_cr0(cr0);
-		wbinvd();
-
-		if (use_intel()) {
-			/* Save MTRR state */
-			rdmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi);
-		} else {
-			/*
-			 * Cyrix ARRs -
-			 * everything else were excluded at the top
-			 */
-			ctxt->ccr3 = getCx86(CX86_CCR3);
-		}
-	}
-}
-
-void set_mtrr_cache_disable(struct set_mtrr_context *ctxt)
-{
-	if (use_intel()) {
-		/* Disable MTRRs, and set the default type to uncached */
-		mtrr_wrmsr(MSR_MTRRdefType, ctxt->deftype_lo & 0xf300UL,
-		      ctxt->deftype_hi);
-	} else {
-		if (is_cpu(CYRIX)) {
-			/* Cyrix ARRs - everything else were excluded at the top */
-			setCx86(CX86_CCR3, (ctxt->ccr3 & 0x0f) | 0x10);
-		}
-	}
-}
-
-/* Restore the processor after a set_mtrr_prepare */
-void set_mtrr_done(struct set_mtrr_context *ctxt)
-{
-	if (use_intel() || is_cpu(CYRIX)) {
-
-		/* Flush caches and TLBs */
-		wbinvd();
-
-		/* Restore MTRRdefType */
-		if (use_intel()) {
-			/* Intel (P6) standard MTRRs */
-			mtrr_wrmsr(MSR_MTRRdefType, ctxt->deftype_lo,
-				   ctxt->deftype_hi);
-		} else {
-			/*
-			 * Cyrix ARRs -
-			 * everything else was excluded at the top
-			 */
-			setCx86(CX86_CCR3, ctxt->ccr3);
-		}
-
-		/* Enable caches */
-		write_cr0(read_cr0() & 0xbfffffff);
-
-		/* Restore value of CR4 */
-		if (cpu_has_pge)
-			write_cr4(ctxt->cr4val);
-	}
-	/* Re-enable interrupts locally (if enabled previously) */
-	local_irq_restore(ctxt->flags);
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/perfctr-watchdog.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perfctr-watchdog.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/perfctr-watchdog.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perfctr-watchdog.c	2010-05-16 17:17:36.000000000 -0400
@@ -115,17 +115,6 @@ int avail_to_resrv_perfctr_nmi_bit(unsig
 
 	return !test_bit(counter, perfctr_nmi_owner);
 }
-
-/* checks the an msr for availability */
-int avail_to_resrv_perfctr_nmi(unsigned int msr)
-{
-	unsigned int counter;
-
-	counter = nmi_perfctr_msr_to_bit(msr);
-	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
-
-	return !test_bit(counter, perfctr_nmi_owner);
-}
 EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit);
 
 int reserve_perfctr_nmi(unsigned int msr)
@@ -691,7 +680,7 @@ static int setup_intel_arch_watchdog(uns
 	cpu_nmi_set_wd_enabled();
 
 	apic_write(APIC_LVTPC, APIC_DM_NMI);
-	evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+	evntsel |= ARCH_PERFMON_EVENTSEL_ENABLE;
 	wrmsr(evntsel_msr, evntsel, 0);
 	intel_arch_wd_ops.checkbit = 1ULL << (eax.split.bit_width - 1);
 	return 1;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/perf_event_amd.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perf_event_amd.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/perf_event_amd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perf_event_amd.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,422 @@
+#ifdef CONFIG_CPU_SUP_AMD
+
+static DEFINE_RAW_SPINLOCK(amd_nb_lock);
+
+static __initconst u64 amd_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses        */
+		[ C(RESULT_MISS)   ] = 0x0041, /* Data Cache Misses          */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0142, /* Data Cache Refills :system */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0267, /* Data Prefetcher :attempts  */
+		[ C(RESULT_MISS)   ] = 0x0167, /* Data Prefetcher :cancelled */
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0080, /* Instruction cache fetches  */
+		[ C(RESULT_MISS)   ] = 0x0081, /* Instruction cache misses   */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x014B, /* Prefetch Instructions :Load */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x037D, /* Requests to L2 Cache :IC+DC */
+		[ C(RESULT_MISS)   ] = 0x037E, /* L2 Cache Misses : IC+DC     */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x017F, /* L2 Fill/Writeback           */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses        */
+		[ C(RESULT_MISS)   ] = 0x0046, /* L1 DTLB and L2 DLTB Miss   */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0080, /* Instruction fecthes        */
+		[ C(RESULT_MISS)   ] = 0x0085, /* Instr. fetch ITLB misses   */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c2, /* Retired Branch Instr.      */
+		[ C(RESULT_MISS)   ] = 0x00c3, /* Retired Mispredicted BI    */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+/*
+ * AMD Performance Monitor K7 and later.
+ */
+static const u64 amd_perfmon_event_map[] =
+{
+  [PERF_COUNT_HW_CPU_CYCLES]		= 0x0076,
+  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
+  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0080,
+  [PERF_COUNT_HW_CACHE_MISSES]		= 0x0081,
+  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
+  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
+};
+
+static u64 amd_pmu_event_map(int hw_event)
+{
+	return amd_perfmon_event_map[hw_event];
+}
+
+static u64 amd_pmu_raw_event(u64 hw_event)
+{
+#define K7_EVNTSEL_EVENT_MASK	0xF000000FFULL
+#define K7_EVNTSEL_UNIT_MASK	0x00000FF00ULL
+#define K7_EVNTSEL_EDGE_MASK	0x000040000ULL
+#define K7_EVNTSEL_INV_MASK	0x000800000ULL
+#define K7_EVNTSEL_REG_MASK	0x0FF000000ULL
+
+#define K7_EVNTSEL_MASK			\
+	(K7_EVNTSEL_EVENT_MASK |	\
+	 K7_EVNTSEL_UNIT_MASK  |	\
+	 K7_EVNTSEL_EDGE_MASK  |	\
+	 K7_EVNTSEL_INV_MASK   |	\
+	 K7_EVNTSEL_REG_MASK)
+
+	return hw_event & K7_EVNTSEL_MASK;
+}
+
+/*
+ * AMD64 events are detected based on their event codes.
+ */
+static inline int amd_is_nb_event(struct hw_perf_event *hwc)
+{
+	return (hwc->config & 0xe0) == 0xe0;
+}
+
+static inline int amd_has_nb(struct cpu_hw_events *cpuc)
+{
+	struct amd_nb *nb = cpuc->amd_nb;
+
+	return nb && nb->nb_id != -1;
+}
+
+static void amd_put_event_constraints(struct cpu_hw_events *cpuc,
+				      struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct amd_nb *nb = cpuc->amd_nb;
+	int i;
+
+	/*
+	 * only care about NB events
+	 */
+	if (!(amd_has_nb(cpuc) && amd_is_nb_event(hwc)))
+		return;
+
+	/*
+	 * need to scan whole list because event may not have
+	 * been assigned during scheduling
+	 *
+	 * no race condition possible because event can only
+	 * be removed on one CPU at a time AND PMU is disabled
+	 * when we come here
+	 */
+	for (i = 0; i < x86_pmu.num_events; i++) {
+		if (nb->owners[i] == event) {
+			cmpxchg(nb->owners+i, event, NULL);
+			break;
+		}
+	}
+}
+
+ /*
+  * AMD64 NorthBridge events need special treatment because
+  * counter access needs to be synchronized across all cores
+  * of a package. Refer to BKDG section 3.12
+  *
+  * NB events are events measuring L3 cache, Hypertransport
+  * traffic. They are identified by an event code >= 0xe00.
+  * They measure events on the NorthBride which is shared
+  * by all cores on a package. NB events are counted on a
+  * shared set of counters. When a NB event is programmed
+  * in a counter, the data actually comes from a shared
+  * counter. Thus, access to those counters needs to be
+  * synchronized.
+  *
+  * We implement the synchronization such that no two cores
+  * can be measuring NB events using the same counters. Thus,
+  * we maintain a per-NB allocation table. The available slot
+  * is propagated using the event_constraint structure.
+  *
+  * We provide only one choice for each NB event based on
+  * the fact that only NB events have restrictions. Consequently,
+  * if a counter is available, there is a guarantee the NB event
+  * will be assigned to it. If no slot is available, an empty
+  * constraint is returned and scheduling will eventually fail
+  * for this event.
+  *
+  * Note that all cores attached the same NB compete for the same
+  * counters to host NB events, this is why we use atomic ops. Some
+  * multi-chip CPUs may have more than one NB.
+  *
+  * Given that resources are allocated (cmpxchg), they must be
+  * eventually freed for others to use. This is accomplished by
+  * calling amd_put_event_constraints().
+  *
+  * Non NB events are not impacted by this restriction.
+  */
+static struct event_constraint *
+amd_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct amd_nb *nb = cpuc->amd_nb;
+	struct perf_event *old = NULL;
+	int max = x86_pmu.num_events;
+	int i, j, k = -1;
+
+	/*
+	 * if not NB event or no NB, then no constraints
+	 */
+	if (!(amd_has_nb(cpuc) && amd_is_nb_event(hwc)))
+		return &unconstrained;
+
+	/*
+	 * detect if already present, if so reuse
+	 *
+	 * cannot merge with actual allocation
+	 * because of possible holes
+	 *
+	 * event can already be present yet not assigned (in hwc->idx)
+	 * because of successive calls to x86_schedule_events() from
+	 * hw_perf_group_sched_in() without hw_perf_enable()
+	 */
+	for (i = 0; i < max; i++) {
+		/*
+		 * keep track of first free slot
+		 */
+		if (k == -1 && !nb->owners[i])
+			k = i;
+
+		/* already present, reuse */
+		if (nb->owners[i] == event)
+			goto done;
+	}
+	/*
+	 * not present, so grab a new slot
+	 * starting either at:
+	 */
+	if (hwc->idx != -1) {
+		/* previous assignment */
+		i = hwc->idx;
+	} else if (k != -1) {
+		/* start from free slot found */
+		i = k;
+	} else {
+		/*
+		 * event not found, no slot found in
+		 * first pass, try again from the
+		 * beginning
+		 */
+		i = 0;
+	}
+	j = i;
+	do {
+		old = cmpxchg(nb->owners+i, NULL, event);
+		if (!old)
+			break;
+		if (++i == max)
+			i = 0;
+	} while (i != j);
+done:
+	if (!old)
+		return &nb->event_constraints[i];
+
+	return &emptyconstraint;
+}
+
+static struct amd_nb *amd_alloc_nb(int cpu, int nb_id)
+{
+	struct amd_nb *nb;
+	int i;
+
+	nb = kmalloc(sizeof(struct amd_nb), GFP_KERNEL);
+	if (!nb)
+		return NULL;
+
+	memset(nb, 0, sizeof(*nb));
+	nb->nb_id = nb_id;
+
+	/*
+	 * initialize all possible NB constraints
+	 */
+	for (i = 0; i < x86_pmu.num_events; i++) {
+		__set_bit(i, nb->event_constraints[i].idxmsk);
+		nb->event_constraints[i].weight = 1;
+	}
+	return nb;
+}
+
+static int amd_pmu_cpu_prepare(int cpu)
+{
+	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+
+	WARN_ON_ONCE(cpuc->amd_nb);
+
+	if (boot_cpu_data.x86_max_cores < 2)
+		return NOTIFY_OK;
+
+	cpuc->amd_nb = amd_alloc_nb(cpu, -1);
+	if (!cpuc->amd_nb)
+		return NOTIFY_BAD;
+
+	return NOTIFY_OK;
+}
+
+static void amd_pmu_cpu_starting(int cpu)
+{
+	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+	struct amd_nb *nb;
+	int i, nb_id;
+
+	if (boot_cpu_data.x86_max_cores < 2)
+		return;
+
+	nb_id = amd_get_nb_id(cpu);
+	WARN_ON_ONCE(nb_id == BAD_APICID);
+
+	raw_spin_lock(&amd_nb_lock);
+
+	for_each_online_cpu(i) {
+		nb = per_cpu(cpu_hw_events, i).amd_nb;
+		if (WARN_ON_ONCE(!nb))
+			continue;
+
+		if (nb->nb_id == nb_id) {
+			kfree(cpuc->amd_nb);
+			cpuc->amd_nb = nb;
+			break;
+		}
+	}
+
+	cpuc->amd_nb->nb_id = nb_id;
+	cpuc->amd_nb->refcnt++;
+
+	raw_spin_unlock(&amd_nb_lock);
+}
+
+static void amd_pmu_cpu_dead(int cpu)
+{
+	struct cpu_hw_events *cpuhw;
+
+	if (boot_cpu_data.x86_max_cores < 2)
+		return;
+
+	cpuhw = &per_cpu(cpu_hw_events, cpu);
+
+	raw_spin_lock(&amd_nb_lock);
+
+	if (cpuhw->amd_nb) {
+		struct amd_nb *nb = cpuhw->amd_nb;
+
+		if (nb->nb_id == -1 || --nb->refcnt == 0)
+			kfree(nb);
+
+		cpuhw->amd_nb = NULL;
+	}
+
+	raw_spin_unlock(&amd_nb_lock);
+}
+
+static __initconst struct x86_pmu amd_pmu = {
+	.name			= "AMD",
+	.handle_irq		= x86_pmu_handle_irq,
+	.disable_all		= x86_pmu_disable_all,
+	.enable_all		= x86_pmu_enable_all,
+	.enable			= x86_pmu_enable_event,
+	.disable		= x86_pmu_disable_event,
+	.eventsel		= MSR_K7_EVNTSEL0,
+	.perfctr		= MSR_K7_PERFCTR0,
+	.event_map		= amd_pmu_event_map,
+	.raw_event		= amd_pmu_raw_event,
+	.max_events		= ARRAY_SIZE(amd_perfmon_event_map),
+	.num_events		= 4,
+	.event_bits		= 48,
+	.event_mask		= (1ULL << 48) - 1,
+	.apic			= 1,
+	/* use highest bit to detect overflow */
+	.max_period		= (1ULL << 47) - 1,
+	.get_event_constraints	= amd_get_event_constraints,
+	.put_event_constraints	= amd_put_event_constraints,
+
+	.cpu_prepare		= amd_pmu_cpu_prepare,
+	.cpu_starting		= amd_pmu_cpu_starting,
+	.cpu_dead		= amd_pmu_cpu_dead,
+};
+
+static __init int amd_pmu_init(void)
+{
+	/* Performance-monitoring supported from K7 and later: */
+	if (boot_cpu_data.x86 < 6)
+		return -ENODEV;
+
+	x86_pmu = amd_pmu;
+
+	/* Events are common for all AMDs */
+	memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
+	       sizeof(hw_cache_event_ids));
+
+	return 0;
+}
+
+#else /* CONFIG_CPU_SUP_AMD */
+
+static int amd_pmu_init(void)
+{
+	return 0;
+}
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/perf_event.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perf_event.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/perf_event.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perf_event.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
  *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
  *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
  *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
+ *  Copyright (C) 2009 Google, Inc., Stephane Eranian
  *
  *  For licencing details see kernel-base/COPYING
  */
@@ -20,12 +21,15 @@
 #include <linux/kdebug.h>
 #include <linux/sched.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/cpu.h>
+#include <linux/bitops.h>
 
 #include <asm/apic.h>
 #include <asm/stacktrace.h>
 #include <asm/nmi.h>
+#include <asm/compat.h>
 
 static u64 perf_event_mask __read_mostly;
 
@@ -68,26 +72,59 @@ struct debug_store {
 	u64	pebs_event_reset[MAX_PEBS_EVENTS];
 };
 
+struct event_constraint {
+	union {
+		unsigned long	idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+		u64		idxmsk64;
+	};
+	u64	code;
+	u64	cmask;
+	int	weight;
+};
+
+struct amd_nb {
+	int nb_id;  /* NorthBridge id */
+	int refcnt; /* reference count */
+	struct perf_event *owners[X86_PMC_IDX_MAX];
+	struct event_constraint event_constraints[X86_PMC_IDX_MAX];
+};
+
 struct cpu_hw_events {
-	struct perf_event	*events[X86_PMC_IDX_MAX];
-	unsigned long		used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+	struct perf_event	*events[X86_PMC_IDX_MAX]; /* in counter order */
 	unsigned long		active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
 	unsigned long		interrupts;
 	int			enabled;
 	struct debug_store	*ds;
-};
 
-struct event_constraint {
-	unsigned long	idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
-	int		code;
+	int			n_events;
+	int			n_added;
+	int			assign[X86_PMC_IDX_MAX]; /* event to counter assignment */
+	u64			tags[X86_PMC_IDX_MAX];
+	struct perf_event	*event_list[X86_PMC_IDX_MAX]; /* in enabled order */
+	struct amd_nb		*amd_nb;
 };
 
-#define EVENT_CONSTRAINT(c, m) { .code = (c), .idxmsk[0] = (m) }
-#define EVENT_CONSTRAINT_END  { .code = 0, .idxmsk[0] = 0 }
+#define __EVENT_CONSTRAINT(c, n, m, w) {\
+	{ .idxmsk64 = (n) },		\
+	.code = (c),			\
+	.cmask = (m),			\
+	.weight = (w),			\
+}
 
-#define for_each_event_constraint(e, c) \
-	for ((e) = (c); (e)->idxmsk[0]; (e)++)
+#define EVENT_CONSTRAINT(c, n, m)	\
+	__EVENT_CONSTRAINT(c, n, m, HWEIGHT(n))
 
+#define INTEL_EVENT_CONSTRAINT(c, n)	\
+	EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVTSEL_MASK)
+
+#define FIXED_EVENT_CONSTRAINT(c, n)	\
+	EVENT_CONSTRAINT(c, (1ULL << (32+n)), INTEL_ARCH_FIXED_MASK)
+
+#define EVENT_CONSTRAINT_END		\
+	EVENT_CONSTRAINT(0, 0, 0)
+
+#define for_each_event_constraint(e, c)	\
+	for ((e) = (c); (e)->cmask; (e)++)
 
 /*
  * struct x86_pmu - generic x86 pmu
@@ -98,8 +135,8 @@ struct x86_pmu {
 	int		(*handle_irq)(struct pt_regs *);
 	void		(*disable_all)(void);
 	void		(*enable_all)(void);
-	void		(*enable)(struct hw_perf_event *, int);
-	void		(*disable)(struct hw_perf_event *, int);
+	void		(*enable)(struct perf_event *);
+	void		(*disable)(struct perf_event *);
 	unsigned	eventsel;
 	unsigned	perfctr;
 	u64		(*event_map)(int);
@@ -114,121 +151,28 @@ struct x86_pmu {
 	u64		intel_ctrl;
 	void		(*enable_bts)(u64 config);
 	void		(*disable_bts)(void);
-	int		(*get_event_idx)(struct cpu_hw_events *cpuc,
-					 struct hw_perf_event *hwc);
-};
-
-static struct x86_pmu x86_pmu __read_mostly;
-
-static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
-	.enabled = 1,
-};
 
-static const struct event_constraint *event_constraints;
-
-/*
- * Not sure about some of these
- */
-static const u64 p6_perfmon_event_map[] =
-{
-  [PERF_COUNT_HW_CPU_CYCLES]		= 0x0079,
-  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
-  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0f2e,
-  [PERF_COUNT_HW_CACHE_MISSES]		= 0x012e,
-  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
-  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
-  [PERF_COUNT_HW_BUS_CYCLES]		= 0x0062,
-};
-
-static u64 p6_pmu_event_map(int hw_event)
-{
-	return p6_perfmon_event_map[hw_event];
-}
-
-/*
- * Event setting that is specified not to count anything.
- * We use this to effectively disable a counter.
- *
- * L2_RQSTS with 0 MESI unit mask.
- */
-#define P6_NOP_EVENT			0x0000002EULL
-
-static u64 p6_pmu_raw_event(u64 hw_event)
-{
-#define P6_EVNTSEL_EVENT_MASK		0x000000FFULL
-#define P6_EVNTSEL_UNIT_MASK		0x0000FF00ULL
-#define P6_EVNTSEL_EDGE_MASK		0x00040000ULL
-#define P6_EVNTSEL_INV_MASK		0x00800000ULL
-#define P6_EVNTSEL_REG_MASK		0xFF000000ULL
-
-#define P6_EVNTSEL_MASK			\
-	(P6_EVNTSEL_EVENT_MASK |	\
-	 P6_EVNTSEL_UNIT_MASK  |	\
-	 P6_EVNTSEL_EDGE_MASK  |	\
-	 P6_EVNTSEL_INV_MASK   |	\
-	 P6_EVNTSEL_REG_MASK)
-
-	return hw_event & P6_EVNTSEL_MASK;
-}
+	struct event_constraint *
+			(*get_event_constraints)(struct cpu_hw_events *cpuc,
+						 struct perf_event *event);
 
-static const struct event_constraint intel_p6_event_constraints[] =
-{
-	EVENT_CONSTRAINT(0xc1, 0x1),	/* FLOPS */
-	EVENT_CONSTRAINT(0x10, 0x1),	/* FP_COMP_OPS_EXE */
-	EVENT_CONSTRAINT(0x11, 0x1),	/* FP_ASSIST */
-	EVENT_CONSTRAINT(0x12, 0x2),	/* MUL */
-	EVENT_CONSTRAINT(0x13, 0x2),	/* DIV */
-	EVENT_CONSTRAINT(0x14, 0x1),	/* CYCLES_DIV_BUSY */
-	EVENT_CONSTRAINT_END
-};
+	void		(*put_event_constraints)(struct cpu_hw_events *cpuc,
+						 struct perf_event *event);
+	struct event_constraint *event_constraints;
 
-/*
- * Intel PerfMon v3. Used on Core2 and later.
- */
-static const u64 intel_perfmon_event_map[] =
-{
-  [PERF_COUNT_HW_CPU_CYCLES]		= 0x003c,
-  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
-  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x4f2e,
-  [PERF_COUNT_HW_CACHE_MISSES]		= 0x412e,
-  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
-  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
-  [PERF_COUNT_HW_BUS_CYCLES]		= 0x013c,
+	int		(*cpu_prepare)(int cpu);
+	void		(*cpu_starting)(int cpu);
+	void		(*cpu_dying)(int cpu);
+	void		(*cpu_dead)(int cpu);
 };
 
-static const struct event_constraint intel_core_event_constraints[] =
-{
-	EVENT_CONSTRAINT(0x10, 0x1),	/* FP_COMP_OPS_EXE */
-	EVENT_CONSTRAINT(0x11, 0x2),	/* FP_ASSIST */
-	EVENT_CONSTRAINT(0x12, 0x2),	/* MUL */
-	EVENT_CONSTRAINT(0x13, 0x2),	/* DIV */
-	EVENT_CONSTRAINT(0x14, 0x1),	/* CYCLES_DIV_BUSY */
-	EVENT_CONSTRAINT(0x18, 0x1),	/* IDLE_DURING_DIV */
-	EVENT_CONSTRAINT(0x19, 0x2),	/* DELAYED_BYPASS */
-	EVENT_CONSTRAINT(0xa1, 0x1),	/* RS_UOPS_DISPATCH_CYCLES */
-	EVENT_CONSTRAINT(0xcb, 0x1),	/* MEM_LOAD_RETIRED */
-	EVENT_CONSTRAINT_END
-};
+static struct x86_pmu x86_pmu __read_mostly;
 
-static const struct event_constraint intel_nehalem_event_constraints[] =
-{
-	EVENT_CONSTRAINT(0x40, 0x3),	/* L1D_CACHE_LD */
-	EVENT_CONSTRAINT(0x41, 0x3),	/* L1D_CACHE_ST */
-	EVENT_CONSTRAINT(0x42, 0x3),	/* L1D_CACHE_LOCK */
-	EVENT_CONSTRAINT(0x43, 0x3),	/* L1D_ALL_REF */
-	EVENT_CONSTRAINT(0x4e, 0x3),	/* L1D_PREFETCH */
-	EVENT_CONSTRAINT(0x4c, 0x3),	/* LOAD_HIT_PRE */
-	EVENT_CONSTRAINT(0x51, 0x3),	/* L1D */
-	EVENT_CONSTRAINT(0x52, 0x3),	/* L1D_CACHE_PREFETCH_LOCK_FB_HIT */
-	EVENT_CONSTRAINT(0x53, 0x3),	/* L1D_CACHE_LOCK_FB_HIT */
-	EVENT_CONSTRAINT(0xc5, 0x3),	/* CACHE_LOCK_CYCLES */
-	EVENT_CONSTRAINT_END
+static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
+	.enabled = 1,
 };
 
-static u64 intel_pmu_event_map(int hw_event)
-{
-	return intel_perfmon_event_map[hw_event];
-}
+static int x86_perf_event_set_period(struct perf_event *event);
 
 /*
  * Generalized hw caching related hw_event table, filled
@@ -245,435 +189,18 @@ static u64 __read_mostly hw_cache_event_
 				[PERF_COUNT_HW_CACHE_OP_MAX]
 				[PERF_COUNT_HW_CACHE_RESULT_MAX];
 
-static __initconst u64 nehalem_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI            */
-		[ C(RESULT_MISS)   ] = 0x0140, /* L1D_CACHE_LD.I_STATE         */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI            */
-		[ C(RESULT_MISS)   ] = 0x0141, /* L1D_CACHE_ST.I_STATE         */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS        */
-		[ C(RESULT_MISS)   ] = 0x024e, /* L1D_PREFETCH.MISS            */
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                    */
-		[ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                   */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0324, /* L2_RQSTS.LOADS               */
-		[ C(RESULT_MISS)   ] = 0x0224, /* L2_RQSTS.LD_MISS             */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0c24, /* L2_RQSTS.RFOS                */
-		[ C(RESULT_MISS)   ] = 0x0824, /* L2_RQSTS.RFO_MISS            */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x4f2e, /* LLC Reference                */
-		[ C(RESULT_MISS)   ] = 0x412e, /* LLC Misses                   */
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI   (alias)  */
-		[ C(RESULT_MISS)   ] = 0x0108, /* DTLB_LOAD_MISSES.ANY         */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI   (alias)  */
-		[ C(RESULT_MISS)   ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS  */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P           */
-		[ C(RESULT_MISS)   ] = 0x20c8, /* ITLB_MISS_RETIRED            */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
-		[ C(RESULT_MISS)   ] = 0x03e8, /* BPU_CLEARS.ANY               */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
-};
-
-static __initconst u64 core2_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI          */
-		[ C(RESULT_MISS)   ] = 0x0140, /* L1D_CACHE_LD.I_STATE       */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI          */
-		[ C(RESULT_MISS)   ] = 0x0141, /* L1D_CACHE_ST.I_STATE       */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x104e, /* L1D_PREFETCH.REQUESTS      */
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0080, /* L1I.READS                  */
-		[ C(RESULT_MISS)   ] = 0x0081, /* L1I.MISSES                 */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI                 */
-		[ C(RESULT_MISS)   ] = 0x4129, /* L2_LD.ISTATE               */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI                 */
-		[ C(RESULT_MISS)   ] = 0x412A, /* L2_ST.ISTATE               */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI  (alias) */
-		[ C(RESULT_MISS)   ] = 0x0208, /* DTLB_MISSES.MISS_LD        */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI  (alias) */
-		[ C(RESULT_MISS)   ] = 0x0808, /* DTLB_MISSES.MISS_ST        */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P         */
-		[ C(RESULT_MISS)   ] = 0x1282, /* ITLBMISSES                 */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY        */
-		[ C(RESULT_MISS)   ] = 0x00c5, /* BP_INST_RETIRED.MISPRED    */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
-};
-
-static __initconst u64 atom_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE.LD               */
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE.ST               */
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                  */
-		[ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                 */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI                 */
-		[ C(RESULT_MISS)   ] = 0x4129, /* L2_LD.ISTATE               */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI                 */
-		[ C(RESULT_MISS)   ] = 0x412A, /* L2_ST.ISTATE               */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE_LD.MESI  (alias) */
-		[ C(RESULT_MISS)   ] = 0x0508, /* DTLB_MISSES.MISS_LD        */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE_ST.MESI  (alias) */
-		[ C(RESULT_MISS)   ] = 0x0608, /* DTLB_MISSES.MISS_ST        */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P         */
-		[ C(RESULT_MISS)   ] = 0x0282, /* ITLB.MISSES                */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY        */
-		[ C(RESULT_MISS)   ] = 0x00c5, /* BP_INST_RETIRED.MISPRED    */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
-};
-
-static u64 intel_pmu_raw_event(u64 hw_event)
-{
-#define CORE_EVNTSEL_EVENT_MASK		0x000000FFULL
-#define CORE_EVNTSEL_UNIT_MASK		0x0000FF00ULL
-#define CORE_EVNTSEL_EDGE_MASK		0x00040000ULL
-#define CORE_EVNTSEL_INV_MASK		0x00800000ULL
-#define CORE_EVNTSEL_REG_MASK		0xFF000000ULL
-
-#define CORE_EVNTSEL_MASK		\
-	(CORE_EVNTSEL_EVENT_MASK |	\
-	 CORE_EVNTSEL_UNIT_MASK  |	\
-	 CORE_EVNTSEL_EDGE_MASK  |	\
-	 CORE_EVNTSEL_INV_MASK  |	\
-	 CORE_EVNTSEL_REG_MASK)
-
-	return hw_event & CORE_EVNTSEL_MASK;
-}
-
-static __initconst u64 amd_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses        */
-		[ C(RESULT_MISS)   ] = 0x0041, /* Data Cache Misses          */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0142, /* Data Cache Refills :system */
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0267, /* Data Prefetcher :attempts  */
-		[ C(RESULT_MISS)   ] = 0x0167, /* Data Prefetcher :cancelled */
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0080, /* Instruction cache fetches  */
-		[ C(RESULT_MISS)   ] = 0x0081, /* Instruction cache misses   */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x014B, /* Prefetch Instructions :Load */
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x037D, /* Requests to L2 Cache :IC+DC */
-		[ C(RESULT_MISS)   ] = 0x037E, /* L2 Cache Misses : IC+DC     */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x017F, /* L2 Fill/Writeback           */
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses        */
-		[ C(RESULT_MISS)   ] = 0x0046, /* L1 DTLB and L2 DLTB Miss   */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0080, /* Instruction fecthes        */
-		[ C(RESULT_MISS)   ] = 0x0085, /* Instr. fetch ITLB misses   */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c2, /* Retired Branch Instr.      */
-		[ C(RESULT_MISS)   ] = 0x00c3, /* Retired Mispredicted BI    */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
-};
-
-/*
- * AMD Performance Monitor K7 and later.
- */
-static const u64 amd_perfmon_event_map[] =
-{
-  [PERF_COUNT_HW_CPU_CYCLES]		= 0x0076,
-  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
-  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0080,
-  [PERF_COUNT_HW_CACHE_MISSES]		= 0x0081,
-  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
-  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
-};
-
-static u64 amd_pmu_event_map(int hw_event)
-{
-	return amd_perfmon_event_map[hw_event];
-}
-
-static u64 amd_pmu_raw_event(u64 hw_event)
-{
-#define K7_EVNTSEL_EVENT_MASK	0x7000000FFULL
-#define K7_EVNTSEL_UNIT_MASK	0x00000FF00ULL
-#define K7_EVNTSEL_EDGE_MASK	0x000040000ULL
-#define K7_EVNTSEL_INV_MASK	0x000800000ULL
-#define K7_EVNTSEL_REG_MASK	0x0FF000000ULL
-
-#define K7_EVNTSEL_MASK			\
-	(K7_EVNTSEL_EVENT_MASK |	\
-	 K7_EVNTSEL_UNIT_MASK  |	\
-	 K7_EVNTSEL_EDGE_MASK  |	\
-	 K7_EVNTSEL_INV_MASK   |	\
-	 K7_EVNTSEL_REG_MASK)
-
-	return hw_event & K7_EVNTSEL_MASK;
-}
-
 /*
  * Propagate event elapsed time into the generic event.
  * Can only be executed on the CPU where the event is active.
  * Returns the delta events processed.
  */
 static u64
-x86_perf_event_update(struct perf_event *event,
-			struct hw_perf_event *hwc, int idx)
+x86_perf_event_update(struct perf_event *event)
 {
+	struct hw_perf_event *hwc = &event->hw;
 	int shift = 64 - x86_pmu.event_bits;
 	u64 prev_raw_count, new_raw_count;
+	int idx = hwc->idx;
 	s64 delta;
 
 	if (idx == X86_PMC_IDX_FIXED_BTS)
@@ -773,7 +300,7 @@ static inline bool bts_available(void)
 	return x86_pmu.enable_bts != NULL;
 }
 
-static inline void init_debug_store_on_cpu(int cpu)
+static void init_debug_store_on_cpu(int cpu)
 {
 	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
 
@@ -785,7 +312,7 @@ static inline void init_debug_store_on_c
 		     (u32)((u64)(unsigned long)ds >> 32));
 }
 
-static inline void fini_debug_store_on_cpu(int cpu)
+static void fini_debug_store_on_cpu(int cpu)
 {
 	if (!per_cpu(cpu_hw_events, cpu).ds)
 		return;
@@ -914,42 +441,6 @@ set_ext_hw_attr(struct hw_perf_event *hw
 	return 0;
 }
 
-static void intel_pmu_enable_bts(u64 config)
-{
-	unsigned long debugctlmsr;
-
-	debugctlmsr = get_debugctlmsr();
-
-	debugctlmsr |= X86_DEBUGCTL_TR;
-	debugctlmsr |= X86_DEBUGCTL_BTS;
-	debugctlmsr |= X86_DEBUGCTL_BTINT;
-
-	if (!(config & ARCH_PERFMON_EVENTSEL_OS))
-		debugctlmsr |= X86_DEBUGCTL_BTS_OFF_OS;
-
-	if (!(config & ARCH_PERFMON_EVENTSEL_USR))
-		debugctlmsr |= X86_DEBUGCTL_BTS_OFF_USR;
-
-	update_debugctlmsr(debugctlmsr);
-}
-
-static void intel_pmu_disable_bts(void)
-{
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	unsigned long debugctlmsr;
-
-	if (!cpuc->ds)
-		return;
-
-	debugctlmsr = get_debugctlmsr();
-
-	debugctlmsr &=
-		~(X86_DEBUGCTL_TR | X86_DEBUGCTL_BTS | X86_DEBUGCTL_BTINT |
-		  X86_DEBUGCTL_BTS_OFF_OS | X86_DEBUGCTL_BTS_OFF_USR);
-
-	update_debugctlmsr(debugctlmsr);
-}
-
 /*
  * Setup the hardware configuration for a given attr_type
  */
@@ -988,6 +479,8 @@ static int __hw_perf_event_init(struct p
 	hwc->config = ARCH_PERFMON_EVENTSEL_INT;
 
 	hwc->idx = -1;
+	hwc->last_cpu = -1;
+	hwc->last_tag = ~0ULL;
 
 	/*
 	 * Count user and OS events unless requested not to.
@@ -1017,6 +510,9 @@ static int __hw_perf_event_init(struct p
 	 */
 	if (attr->type == PERF_TYPE_RAW) {
 		hwc->config |= x86_pmu.raw_event(attr->config);
+		if ((hwc->config & ARCH_PERFMON_EVENTSEL_ANY) &&
+		    perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
+			return -EACCES;
 		return 0;
 	}
 
@@ -1056,216 +552,314 @@ static int __hw_perf_event_init(struct p
 	return 0;
 }
 
-static void p6_pmu_disable_all(void)
+static void x86_pmu_disable_all(void)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	u64 val;
-
-	if (!cpuc->enabled)
-		return;
+	int idx;
 
-	cpuc->enabled = 0;
-	barrier();
+	for (idx = 0; idx < x86_pmu.num_events; idx++) {
+		u64 val;
 
-	/* p6 only has one enable register */
-	rdmsrl(MSR_P6_EVNTSEL0, val);
-	val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
-	wrmsrl(MSR_P6_EVNTSEL0, val);
+		if (!test_bit(idx, cpuc->active_mask))
+			continue;
+		rdmsrl(x86_pmu.eventsel + idx, val);
+		if (!(val & ARCH_PERFMON_EVENTSEL_ENABLE))
+			continue;
+		val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
+		wrmsrl(x86_pmu.eventsel + idx, val);
+	}
 }
 
-static void intel_pmu_disable_all(void)
+void hw_perf_disable(void)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 
+	if (!x86_pmu_initialized())
+		return;
+
 	if (!cpuc->enabled)
 		return;
 
+	cpuc->n_added = 0;
 	cpuc->enabled = 0;
 	barrier();
 
-	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
-
-	if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask))
-		intel_pmu_disable_bts();
+	x86_pmu.disable_all();
 }
 
-static void amd_pmu_disable_all(void)
+static void x86_pmu_enable_all(void)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	int idx;
 
-	if (!cpuc->enabled)
-		return;
-
-	cpuc->enabled = 0;
-	/*
-	 * ensure we write the disable before we start disabling the
-	 * events proper, so that amd_pmu_enable_event() does the
-	 * right thing.
-	 */
-	barrier();
-
 	for (idx = 0; idx < x86_pmu.num_events; idx++) {
+		struct perf_event *event = cpuc->events[idx];
 		u64 val;
 
 		if (!test_bit(idx, cpuc->active_mask))
 			continue;
-		rdmsrl(MSR_K7_EVNTSEL0 + idx, val);
-		if (!(val & ARCH_PERFMON_EVENTSEL0_ENABLE))
-			continue;
-		val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
-		wrmsrl(MSR_K7_EVNTSEL0 + idx, val);
+
+		val = event->hw.config;
+		val |= ARCH_PERFMON_EVENTSEL_ENABLE;
+		wrmsrl(x86_pmu.eventsel + idx, val);
 	}
 }
 
-void hw_perf_disable(void)
+static const struct pmu pmu;
+
+static inline int is_x86_event(struct perf_event *event)
 {
-	if (!x86_pmu_initialized())
-		return;
-	return x86_pmu.disable_all();
+	return event->pmu == &pmu;
 }
 
-static void p6_pmu_enable_all(void)
+static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
 {
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	unsigned long val;
+	struct event_constraint *c, *constraints[X86_PMC_IDX_MAX];
+	unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+	int i, j, w, wmax, num = 0;
+	struct hw_perf_event *hwc;
 
-	if (cpuc->enabled)
-		return;
+	bitmap_zero(used_mask, X86_PMC_IDX_MAX);
 
-	cpuc->enabled = 1;
-	barrier();
+	for (i = 0; i < n; i++) {
+		c = x86_pmu.get_event_constraints(cpuc, cpuc->event_list[i]);
+		constraints[i] = c;
+	}
 
-	/* p6 only has one enable register */
-	rdmsrl(MSR_P6_EVNTSEL0, val);
-	val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
-	wrmsrl(MSR_P6_EVNTSEL0, val);
-}
+	/*
+	 * fastpath, try to reuse previous register
+	 */
+	for (i = 0; i < n; i++) {
+		hwc = &cpuc->event_list[i]->hw;
+		c = constraints[i];
 
-static void intel_pmu_enable_all(void)
-{
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+		/* never assigned */
+		if (hwc->idx == -1)
+			break;
 
-	if (cpuc->enabled)
-		return;
+		/* constraint still honored */
+		if (!test_bit(hwc->idx, c->idxmsk))
+			break;
 
-	cpuc->enabled = 1;
-	barrier();
+		/* not already used */
+		if (test_bit(hwc->idx, used_mask))
+			break;
 
-	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl);
+		__set_bit(hwc->idx, used_mask);
+		if (assign)
+			assign[i] = hwc->idx;
+	}
+	if (i == n)
+		goto done;
 
-	if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
-		struct perf_event *event =
-			cpuc->events[X86_PMC_IDX_FIXED_BTS];
+	/*
+	 * begin slow path
+	 */
 
-		if (WARN_ON_ONCE(!event))
-			return;
+	bitmap_zero(used_mask, X86_PMC_IDX_MAX);
 
-		intel_pmu_enable_bts(event->hw.config);
+	/*
+	 * weight = number of possible counters
+	 *
+	 * 1    = most constrained, only works on one counter
+	 * wmax = least constrained, works on any counter
+	 *
+	 * assign events to counters starting with most
+	 * constrained events.
+	 */
+	wmax = x86_pmu.num_events;
+
+	/*
+	 * when fixed event counters are present,
+	 * wmax is incremented by 1 to account
+	 * for one more choice
+	 */
+	if (x86_pmu.num_events_fixed)
+		wmax++;
+
+	for (w = 1, num = n; num && w <= wmax; w++) {
+		/* for each event */
+		for (i = 0; num && i < n; i++) {
+			c = constraints[i];
+			hwc = &cpuc->event_list[i]->hw;
+
+			if (c->weight != w)
+				continue;
+
+			for_each_set_bit(j, c->idxmsk, X86_PMC_IDX_MAX) {
+				if (!test_bit(j, used_mask))
+					break;
+			}
+
+			if (j == X86_PMC_IDX_MAX)
+				break;
+
+			__set_bit(j, used_mask);
+
+			if (assign)
+				assign[i] = j;
+			num--;
+		}
 	}
+done:
+	/*
+	 * scheduling failed or is just a simulation,
+	 * free resources if necessary
+	 */
+	if (!assign || num) {
+		for (i = 0; i < n; i++) {
+			if (x86_pmu.put_event_constraints)
+				x86_pmu.put_event_constraints(cpuc, cpuc->event_list[i]);
+		}
+	}
+	return num ? -ENOSPC : 0;
 }
 
-static void amd_pmu_enable_all(void)
+/*
+ * dogrp: true if must collect siblings events (group)
+ * returns total number of events and error code
+ */
+static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader, bool dogrp)
 {
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	int idx;
+	struct perf_event *event;
+	int n, max_count;
 
-	if (cpuc->enabled)
-		return;
+	max_count = x86_pmu.num_events + x86_pmu.num_events_fixed;
 
-	cpuc->enabled = 1;
-	barrier();
+	/* current number of events already accepted */
+	n = cpuc->n_events;
 
-	for (idx = 0; idx < x86_pmu.num_events; idx++) {
-		struct perf_event *event = cpuc->events[idx];
-		u64 val;
+	if (is_x86_event(leader)) {
+		if (n >= max_count)
+			return -ENOSPC;
+		cpuc->event_list[n] = leader;
+		n++;
+	}
+	if (!dogrp)
+		return n;
 
-		if (!test_bit(idx, cpuc->active_mask))
+	list_for_each_entry(event, &leader->sibling_list, group_entry) {
+		if (!is_x86_event(event) ||
+		    event->state <= PERF_EVENT_STATE_OFF)
 			continue;
 
-		val = event->hw.config;
-		val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
-		wrmsrl(MSR_K7_EVNTSEL0 + idx, val);
-	}
-}
+		if (n >= max_count)
+			return -ENOSPC;
 
-void hw_perf_enable(void)
-{
-	if (!x86_pmu_initialized())
-		return;
-	x86_pmu.enable_all();
+		cpuc->event_list[n] = event;
+		n++;
+	}
+	return n;
 }
 
-static inline u64 intel_pmu_get_status(void)
+static inline void x86_assign_hw_event(struct perf_event *event,
+				struct cpu_hw_events *cpuc, int i)
 {
-	u64 status;
+	struct hw_perf_event *hwc = &event->hw;
 
-	rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
+	hwc->idx = cpuc->assign[i];
+	hwc->last_cpu = smp_processor_id();
+	hwc->last_tag = ++cpuc->tags[i];
 
-	return status;
+	if (hwc->idx == X86_PMC_IDX_FIXED_BTS) {
+		hwc->config_base = 0;
+		hwc->event_base	= 0;
+	} else if (hwc->idx >= X86_PMC_IDX_FIXED) {
+		hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
+		/*
+		 * We set it so that event_base + idx in wrmsr/rdmsr maps to
+		 * MSR_ARCH_PERFMON_FIXED_CTR0 ... CTR2:
+		 */
+		hwc->event_base =
+			MSR_ARCH_PERFMON_FIXED_CTR0 - X86_PMC_IDX_FIXED;
+	} else {
+		hwc->config_base = x86_pmu.eventsel;
+		hwc->event_base  = x86_pmu.perfctr;
+	}
 }
 
-static inline void intel_pmu_ack_status(u64 ack)
+static inline int match_prev_assignment(struct hw_perf_event *hwc,
+					struct cpu_hw_events *cpuc,
+					int i)
 {
-	wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
+	return hwc->idx == cpuc->assign[i] &&
+		hwc->last_cpu == smp_processor_id() &&
+		hwc->last_tag == cpuc->tags[i];
 }
 
-static inline void x86_pmu_enable_event(struct hw_perf_event *hwc, int idx)
-{
-	(void)checking_wrmsrl(hwc->config_base + idx,
-			      hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE);
-}
+static int x86_pmu_start(struct perf_event *event);
+static void x86_pmu_stop(struct perf_event *event);
 
-static inline void x86_pmu_disable_event(struct hw_perf_event *hwc, int idx)
+void hw_perf_enable(void)
 {
-	(void)checking_wrmsrl(hwc->config_base + idx, hwc->config);
-}
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct perf_event *event;
+	struct hw_perf_event *hwc;
+	int i;
 
-static inline void
-intel_pmu_disable_fixed(struct hw_perf_event *hwc, int __idx)
-{
-	int idx = __idx - X86_PMC_IDX_FIXED;
-	u64 ctrl_val, mask;
+	if (!x86_pmu_initialized())
+		return;
 
-	mask = 0xfULL << (idx * 4);
+	if (cpuc->enabled)
+		return;
 
-	rdmsrl(hwc->config_base, ctrl_val);
-	ctrl_val &= ~mask;
-	(void)checking_wrmsrl(hwc->config_base, ctrl_val);
-}
+	if (cpuc->n_added) {
+		int n_running = cpuc->n_events - cpuc->n_added;
+		/*
+		 * apply assignment obtained either from
+		 * hw_perf_group_sched_in() or x86_pmu_enable()
+		 *
+		 * step1: save events moving to new counters
+		 * step2: reprogram moved events into new counters
+		 */
+		for (i = 0; i < n_running; i++) {
+			event = cpuc->event_list[i];
+			hwc = &event->hw;
 
-static inline void
-p6_pmu_disable_event(struct hw_perf_event *hwc, int idx)
-{
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	u64 val = P6_NOP_EVENT;
+			/*
+			 * we can avoid reprogramming counter if:
+			 * - assigned same counter as last time
+			 * - running on same CPU as last time
+			 * - no other event has used the counter since
+			 */
+			if (hwc->idx == -1 ||
+			    match_prev_assignment(hwc, cpuc, i))
+				continue;
 
-	if (cpuc->enabled)
-		val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+			x86_pmu_stop(event);
+		}
 
-	(void)checking_wrmsrl(hwc->config_base + idx, val);
-}
+		for (i = 0; i < cpuc->n_events; i++) {
+			event = cpuc->event_list[i];
+			hwc = &event->hw;
 
-static inline void
-intel_pmu_disable_event(struct hw_perf_event *hwc, int idx)
-{
-	if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
-		intel_pmu_disable_bts();
-		return;
-	}
+			if (!match_prev_assignment(hwc, cpuc, i))
+				x86_assign_hw_event(event, cpuc, i);
+			else if (i < n_running)
+				continue;
 
-	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
-		intel_pmu_disable_fixed(hwc, idx);
-		return;
+			x86_pmu_start(event);
+		}
+		cpuc->n_added = 0;
+		perf_events_lapic_init();
 	}
 
-	x86_pmu_disable_event(hwc, idx);
+	cpuc->enabled = 1;
+	barrier();
+
+	x86_pmu.enable_all();
 }
 
-static inline void
-amd_pmu_disable_event(struct hw_perf_event *hwc, int idx)
+static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc)
 {
-	x86_pmu_disable_event(hwc, idx);
+	(void)checking_wrmsrl(hwc->config_base + hwc->idx,
+			      hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE);
+}
+
+static inline void x86_pmu_disable_event(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	(void)checking_wrmsrl(hwc->config_base + hwc->idx, hwc->config);
 }
 
 static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left);
@@ -1275,12 +869,12 @@ static DEFINE_PER_CPU(u64 [X86_PMC_IDX_M
  * To be called with the event disabled in hw:
  */
 static int
-x86_perf_event_set_period(struct perf_event *event,
-			     struct hw_perf_event *hwc, int idx)
+x86_perf_event_set_period(struct perf_event *event)
 {
+	struct hw_perf_event *hwc = &event->hw;
 	s64 left = atomic64_read(&hwc->period_left);
 	s64 period = hwc->sample_period;
-	int err, ret = 0;
+	int err, ret = 0, idx = hwc->idx;
 
 	if (idx == X86_PMC_IDX_FIXED_BTS)
 		return 0;
@@ -1326,219 +920,63 @@ x86_perf_event_set_period(struct perf_ev
 	return ret;
 }
 
-static inline void
-intel_pmu_enable_fixed(struct hw_perf_event *hwc, int __idx)
-{
-	int idx = __idx - X86_PMC_IDX_FIXED;
-	u64 ctrl_val, bits, mask;
-	int err;
-
-	/*
-	 * Enable IRQ generation (0x8),
-	 * and enable ring-3 counting (0x2) and ring-0 counting (0x1)
-	 * if requested:
-	 */
-	bits = 0x8ULL;
-	if (hwc->config & ARCH_PERFMON_EVENTSEL_USR)
-		bits |= 0x2;
-	if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
-		bits |= 0x1;
-
-	/*
-	 * ANY bit is supported in v3 and up
-	 */
-	if (x86_pmu.version > 2 && hwc->config & ARCH_PERFMON_EVENTSEL_ANY)
-		bits |= 0x4;
-
-	bits <<= (idx * 4);
-	mask = 0xfULL << (idx * 4);
-
-	rdmsrl(hwc->config_base, ctrl_val);
-	ctrl_val &= ~mask;
-	ctrl_val |= bits;
-	err = checking_wrmsrl(hwc->config_base, ctrl_val);
-}
-
-static void p6_pmu_enable_event(struct hw_perf_event *hwc, int idx)
+static void x86_pmu_enable_event(struct perf_event *event)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	u64 val;
-
-	val = hwc->config;
 	if (cpuc->enabled)
-		val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
-
-	(void)checking_wrmsrl(hwc->config_base + idx, val);
-}
-
-
-static void intel_pmu_enable_event(struct hw_perf_event *hwc, int idx)
-{
-	if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
-		if (!__get_cpu_var(cpu_hw_events).enabled)
-			return;
-
-		intel_pmu_enable_bts(hwc->config);
-		return;
-	}
-
-	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
-		intel_pmu_enable_fixed(hwc, idx);
-		return;
-	}
-
-	x86_pmu_enable_event(hwc, idx);
+		__x86_pmu_enable_event(&event->hw);
 }
 
-static void amd_pmu_enable_event(struct hw_perf_event *hwc, int idx)
+/*
+ * activate a single event
+ *
+ * The event is added to the group of enabled events
+ * but only if it can be scehduled with existing events.
+ *
+ * Called with PMU disabled. If successful and return value 1,
+ * then guaranteed to call perf_enable() and hw_perf_enable()
+ */
+static int x86_pmu_enable(struct perf_event *event)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc;
+	int assign[X86_PMC_IDX_MAX];
+	int n, n0, ret;
 
-	if (cpuc->enabled)
-		x86_pmu_enable_event(hwc, idx);
-}
-
-static int fixed_mode_idx(struct hw_perf_event *hwc)
-{
-	unsigned int hw_event;
-
-	hw_event = hwc->config & ARCH_PERFMON_EVENT_MASK;
-
-	if (unlikely((hw_event ==
-		      x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS)) &&
-		     (hwc->sample_period == 1)))
-		return X86_PMC_IDX_FIXED_BTS;
+	hwc = &event->hw;
 
-	if (!x86_pmu.num_events_fixed)
-		return -1;
+	n0 = cpuc->n_events;
+	n = collect_events(cpuc, event, false);
+	if (n < 0)
+		return n;
 
+	ret = x86_schedule_events(cpuc, n, assign);
+	if (ret)
+		return ret;
 	/*
-	 * fixed counters do not take all possible filters
+	 * copy new assignment, now we know it is possible
+	 * will be used by hw_perf_enable()
 	 */
-	if (hwc->config & ARCH_PERFMON_EVENT_FILTER_MASK)
-		return -1;
-
-	if (unlikely(hw_event == x86_pmu.event_map(PERF_COUNT_HW_INSTRUCTIONS)))
-		return X86_PMC_IDX_FIXED_INSTRUCTIONS;
-	if (unlikely(hw_event == x86_pmu.event_map(PERF_COUNT_HW_CPU_CYCLES)))
-		return X86_PMC_IDX_FIXED_CPU_CYCLES;
-	if (unlikely(hw_event == x86_pmu.event_map(PERF_COUNT_HW_BUS_CYCLES)))
-		return X86_PMC_IDX_FIXED_BUS_CYCLES;
-
-	return -1;
-}
-
-/*
- * generic counter allocator: get next free counter
- */
-static int
-gen_get_event_idx(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc)
-{
-	int idx;
-
-	idx = find_first_zero_bit(cpuc->used_mask, x86_pmu.num_events);
-	return idx == x86_pmu.num_events ? -1 : idx;
-}
-
-/*
- * intel-specific counter allocator: check event constraints
- */
-static int
-intel_get_event_idx(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc)
-{
-	const struct event_constraint *event_constraint;
-	int i, code;
-
-	if (!event_constraints)
-		goto skip;
-
-	code = hwc->config & CORE_EVNTSEL_EVENT_MASK;
-
-	for_each_event_constraint(event_constraint, event_constraints) {
-		if (code == event_constraint->code) {
-			for_each_bit(i, event_constraint->idxmsk, X86_PMC_IDX_MAX) {
-				if (!test_and_set_bit(i, cpuc->used_mask))
-					return i;
-			}
-			return -1;
-		}
-	}
-skip:
-	return gen_get_event_idx(cpuc, hwc);
-}
-
-static int
-x86_schedule_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc)
-{
-	int idx;
-
-	idx = fixed_mode_idx(hwc);
-	if (idx == X86_PMC_IDX_FIXED_BTS) {
-		/* BTS is already occupied. */
-		if (test_and_set_bit(idx, cpuc->used_mask))
-			return -EAGAIN;
-
-		hwc->config_base	= 0;
-		hwc->event_base		= 0;
-		hwc->idx		= idx;
-	} else if (idx >= 0) {
-		/*
-		 * Try to get the fixed event, if that is already taken
-		 * then try to get a generic event:
-		 */
-		if (test_and_set_bit(idx, cpuc->used_mask))
-			goto try_generic;
-
-		hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
-		/*
-		 * We set it so that event_base + idx in wrmsr/rdmsr maps to
-		 * MSR_ARCH_PERFMON_FIXED_CTR0 ... CTR2:
-		 */
-		hwc->event_base =
-			MSR_ARCH_PERFMON_FIXED_CTR0 - X86_PMC_IDX_FIXED;
-		hwc->idx = idx;
-	} else {
-		idx = hwc->idx;
-		/* Try to get the previous generic event again */
-		if (idx == -1 || test_and_set_bit(idx, cpuc->used_mask)) {
-try_generic:
-			idx = x86_pmu.get_event_idx(cpuc, hwc);
-			if (idx == -1)
-				return -EAGAIN;
+	memcpy(cpuc->assign, assign, n*sizeof(int));
 
-			set_bit(idx, cpuc->used_mask);
-			hwc->idx = idx;
-		}
-		hwc->config_base = x86_pmu.eventsel;
-		hwc->event_base  = x86_pmu.perfctr;
-	}
+	cpuc->n_events = n;
+	cpuc->n_added += n - n0;
 
-	return idx;
+	return 0;
 }
 
-/*
- * Find a PMC slot for the freshly enabled / scheduled in event:
- */
-static int x86_pmu_enable(struct perf_event *event)
+static int x86_pmu_start(struct perf_event *event)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	struct hw_perf_event *hwc = &event->hw;
-	int idx;
-
-	idx = x86_schedule_event(cpuc, hwc);
-	if (idx < 0)
-		return idx;
-
-	perf_events_lapic_init();
+	int idx = event->hw.idx;
 
-	x86_pmu.disable(hwc, idx);
+	if (idx == -1)
+		return -EAGAIN;
 
+	x86_perf_event_set_period(event);
 	cpuc->events[idx] = event;
-	set_bit(idx, cpuc->active_mask);
-
-	x86_perf_event_set_period(event, hwc, idx);
-	x86_pmu.enable(hwc, idx);
-
+	__set_bit(idx, cpuc->active_mask);
+	x86_pmu.enable(event);
 	perf_event_update_userpage(event);
 
 	return 0;
@@ -1546,14 +984,8 @@ static int x86_pmu_enable(struct perf_ev
 
 static void x86_pmu_unthrottle(struct perf_event *event)
 {
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	struct hw_perf_event *hwc = &event->hw;
-
-	if (WARN_ON_ONCE(hwc->idx >= X86_PMC_IDX_MAX ||
-				cpuc->events[hwc->idx] != event))
-		return;
-
-	x86_pmu.enable(hwc, hwc->idx);
+	int ret = x86_pmu_start(event);
+	WARN_ON_ONCE(ret);
 }
 
 void perf_event_print_debug(void)
@@ -1583,7 +1015,7 @@ void perf_event_print_debug(void)
 		pr_info("CPU#%d: overflow:   %016llx\n", cpu, overflow);
 		pr_info("CPU#%d: fixed:      %016llx\n", cpu, fixed);
 	}
-	pr_info("CPU#%d: used:       %016llx\n", cpu, *(u64 *)cpuc->used_mask);
+	pr_info("CPU#%d: active:       %016llx\n", cpu, *(u64 *)cpuc->active_mask);
 
 	for (idx = 0; idx < x86_pmu.num_events; idx++) {
 		rdmsrl(x86_pmu.eventsel + idx, pmc_ctrl);
@@ -1607,257 +1039,50 @@ void perf_event_print_debug(void)
 	local_irq_restore(flags);
 }
 
-static void intel_pmu_drain_bts_buffer(struct cpu_hw_events *cpuc)
-{
-	struct debug_store *ds = cpuc->ds;
-	struct bts_record {
-		u64	from;
-		u64	to;
-		u64	flags;
-	};
-	struct perf_event *event = cpuc->events[X86_PMC_IDX_FIXED_BTS];
-	struct bts_record *at, *top;
-	struct perf_output_handle handle;
-	struct perf_event_header header;
-	struct perf_sample_data data;
-	struct pt_regs regs;
-
-	if (!event)
-		return;
-
-	if (!ds)
-		return;
-
-	at  = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
-	top = (struct bts_record *)(unsigned long)ds->bts_index;
-
-	if (top <= at)
-		return;
-
-	ds->bts_index = ds->bts_buffer_base;
-
-
-	data.period	= event->hw.last_period;
-	data.addr	= 0;
-	data.raw	= NULL;
-	regs.ip		= 0;
-
-	/*
-	 * Prepare a generic sample, i.e. fill in the invariant fields.
-	 * We will overwrite the from and to address before we output
-	 * the sample.
-	 */
-	perf_prepare_sample(&header, &data, event, &regs);
-
-	if (perf_output_begin(&handle, event,
-			      header.size * (top - at), 1, 1))
-		return;
-
-	for (; at < top; at++) {
-		data.ip		= at->from;
-		data.addr	= at->to;
-
-		perf_output_sample(&handle, &header, &data, event);
-	}
-
-	perf_output_end(&handle);
-
-	/* There's new data available. */
-	event->hw.interrupts++;
-	event->pending_kill = POLL_IN;
-}
-
-static void x86_pmu_disable(struct perf_event *event)
+static void x86_pmu_stop(struct perf_event *event)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	struct hw_perf_event *hwc = &event->hw;
 	int idx = hwc->idx;
 
-	/*
-	 * Must be done before we disable, otherwise the nmi handler
-	 * could reenable again:
-	 */
-	clear_bit(idx, cpuc->active_mask);
-	x86_pmu.disable(hwc, idx);
+	if (!__test_and_clear_bit(idx, cpuc->active_mask))
+		return;
 
-	/*
-	 * Make sure the cleared pointer becomes visible before we
-	 * (potentially) free the event:
-	 */
-	barrier();
+	x86_pmu.disable(event);
 
 	/*
 	 * Drain the remaining delta count out of a event
 	 * that we are disabling:
 	 */
-	x86_perf_event_update(event, hwc, idx);
-
-	/* Drain the remaining BTS records. */
-	if (unlikely(idx == X86_PMC_IDX_FIXED_BTS))
-		intel_pmu_drain_bts_buffer(cpuc);
+	x86_perf_event_update(event);
 
 	cpuc->events[idx] = NULL;
-	clear_bit(idx, cpuc->used_mask);
-
-	perf_event_update_userpage(event);
-}
-
-/*
- * Save and restart an expired event. Called by NMI contexts,
- * so it has to be careful about preempting normal event ops:
- */
-static int intel_pmu_save_and_restart(struct perf_event *event)
-{
-	struct hw_perf_event *hwc = &event->hw;
-	int idx = hwc->idx;
-	int ret;
-
-	x86_perf_event_update(event, hwc, idx);
-	ret = x86_perf_event_set_period(event, hwc, idx);
-
-	if (event->state == PERF_EVENT_STATE_ACTIVE)
-		intel_pmu_enable_event(hwc, idx);
-
-	return ret;
-}
-
-static void intel_pmu_reset(void)
-{
-	struct debug_store *ds = __get_cpu_var(cpu_hw_events).ds;
-	unsigned long flags;
-	int idx;
-
-	if (!x86_pmu.num_events)
-		return;
-
-	local_irq_save(flags);
-
-	printk("clearing PMU state on CPU#%d\n", smp_processor_id());
-
-	for (idx = 0; idx < x86_pmu.num_events; idx++) {
-		checking_wrmsrl(x86_pmu.eventsel + idx, 0ull);
-		checking_wrmsrl(x86_pmu.perfctr  + idx, 0ull);
-	}
-	for (idx = 0; idx < x86_pmu.num_events_fixed; idx++) {
-		checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
-	}
-	if (ds)
-		ds->bts_index = ds->bts_buffer_base;
-
-	local_irq_restore(flags);
 }
 
-static int p6_pmu_handle_irq(struct pt_regs *regs)
-{
-	struct perf_sample_data data;
-	struct cpu_hw_events *cpuc;
-	struct perf_event *event;
-	struct hw_perf_event *hwc;
-	int idx, handled = 0;
-	u64 val;
-
-	data.addr = 0;
-	data.raw = NULL;
-
-	cpuc = &__get_cpu_var(cpu_hw_events);
-
-	for (idx = 0; idx < x86_pmu.num_events; idx++) {
-		if (!test_bit(idx, cpuc->active_mask))
-			continue;
-
-		event = cpuc->events[idx];
-		hwc = &event->hw;
-
-		val = x86_perf_event_update(event, hwc, idx);
-		if (val & (1ULL << (x86_pmu.event_bits - 1)))
-			continue;
-
-		/*
-		 * event overflow
-		 */
-		handled		= 1;
-		data.period	= event->hw.last_period;
-
-		if (!x86_perf_event_set_period(event, hwc, idx))
-			continue;
-
-		if (perf_event_overflow(event, 1, &data, regs))
-			p6_pmu_disable_event(hwc, idx);
-	}
-
-	if (handled)
-		inc_irq_stat(apic_perf_irqs);
-
-	return handled;
-}
-
-/*
- * This handler is triggered by the local APIC, so the APIC IRQ handling
- * rules apply:
- */
-static int intel_pmu_handle_irq(struct pt_regs *regs)
+static void x86_pmu_disable(struct perf_event *event)
 {
-	struct perf_sample_data data;
-	struct cpu_hw_events *cpuc;
-	int bit, loops;
-	u64 ack, status;
-
-	data.addr = 0;
-	data.raw = NULL;
-
-	cpuc = &__get_cpu_var(cpu_hw_events);
-
-	perf_disable();
-	intel_pmu_drain_bts_buffer(cpuc);
-	status = intel_pmu_get_status();
-	if (!status) {
-		perf_enable();
-		return 0;
-	}
-
-	loops = 0;
-again:
-	if (++loops > 100) {
-		WARN_ONCE(1, "perfevents: irq loop stuck!\n");
-		perf_event_print_debug();
-		intel_pmu_reset();
-		perf_enable();
-		return 1;
-	}
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	int i;
 
-	inc_irq_stat(apic_perf_irqs);
-	ack = status;
-	for_each_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
-		struct perf_event *event = cpuc->events[bit];
+	x86_pmu_stop(event);
 
-		clear_bit(bit, (unsigned long *) &status);
-		if (!test_bit(bit, cpuc->active_mask))
-			continue;
+	for (i = 0; i < cpuc->n_events; i++) {
+		if (event == cpuc->event_list[i]) {
 
-		if (!intel_pmu_save_and_restart(event))
-			continue;
+			if (x86_pmu.put_event_constraints)
+				x86_pmu.put_event_constraints(cpuc, event);
 
-		data.period = event->hw.last_period;
+			while (++i < cpuc->n_events)
+				cpuc->event_list[i-1] = cpuc->event_list[i];
 
-		if (perf_event_overflow(event, 1, &data, regs))
-			intel_pmu_disable_event(&event->hw, bit);
+			--cpuc->n_events;
+			break;
+		}
 	}
-
-	intel_pmu_ack_status(ack);
-
-	/*
-	 * Repeat if there is more work to be done:
-	 */
-	status = intel_pmu_get_status();
-	if (status)
-		goto again;
-
-	perf_enable();
-
-	return 1;
+	perf_event_update_userpage(event);
 }
 
-static int amd_pmu_handle_irq(struct pt_regs *regs)
+static int x86_pmu_handle_irq(struct pt_regs *regs)
 {
 	struct perf_sample_data data;
 	struct cpu_hw_events *cpuc;
@@ -1866,8 +1091,7 @@ static int amd_pmu_handle_irq(struct pt_
 	int idx, handled = 0;
 	u64 val;
 
-	data.addr = 0;
-	data.raw = NULL;
+	perf_sample_data_init(&data, 0);
 
 	cpuc = &__get_cpu_var(cpu_hw_events);
 
@@ -1878,7 +1102,7 @@ static int amd_pmu_handle_irq(struct pt_
 		event = cpuc->events[idx];
 		hwc = &event->hw;
 
-		val = x86_perf_event_update(event, hwc, idx);
+		val = x86_perf_event_update(event);
 		if (val & (1ULL << (x86_pmu.event_bits - 1)))
 			continue;
 
@@ -1888,11 +1112,11 @@ static int amd_pmu_handle_irq(struct pt_
 		handled		= 1;
 		data.period	= event->hw.last_period;
 
-		if (!x86_perf_event_set_period(event, hwc, idx))
+		if (!x86_perf_event_set_period(event))
 			continue;
 
 		if (perf_event_overflow(event, 1, &data, regs))
-			amd_pmu_disable_event(hwc, idx);
+			x86_pmu_stop(event);
 	}
 
 	if (handled)
@@ -1975,193 +1199,171 @@ static __read_mostly struct notifier_blo
 	.priority		= 1
 };
 
-static __initconst struct x86_pmu p6_pmu = {
-	.name			= "p6",
-	.handle_irq		= p6_pmu_handle_irq,
-	.disable_all		= p6_pmu_disable_all,
-	.enable_all		= p6_pmu_enable_all,
-	.enable			= p6_pmu_enable_event,
-	.disable		= p6_pmu_disable_event,
-	.eventsel		= MSR_P6_EVNTSEL0,
-	.perfctr		= MSR_P6_PERFCTR0,
-	.event_map		= p6_pmu_event_map,
-	.raw_event		= p6_pmu_raw_event,
-	.max_events		= ARRAY_SIZE(p6_perfmon_event_map),
-	.apic			= 1,
-	.max_period		= (1ULL << 31) - 1,
-	.version		= 0,
-	.num_events		= 2,
-	/*
-	 * Events have 40 bits implemented. However they are designed such
-	 * that bits [32-39] are sign extensions of bit 31. As such the
-	 * effective width of a event for P6-like PMU is 32 bits only.
-	 *
-	 * See IA-32 Intel Architecture Software developer manual Vol 3B
-	 */
-	.event_bits		= 32,
-	.event_mask		= (1ULL << 32) - 1,
-	.get_event_idx		= intel_get_event_idx,
-};
+static struct event_constraint unconstrained;
+static struct event_constraint emptyconstraint;
 
-static __initconst struct x86_pmu intel_pmu = {
-	.name			= "Intel",
-	.handle_irq		= intel_pmu_handle_irq,
-	.disable_all		= intel_pmu_disable_all,
-	.enable_all		= intel_pmu_enable_all,
-	.enable			= intel_pmu_enable_event,
-	.disable		= intel_pmu_disable_event,
-	.eventsel		= MSR_ARCH_PERFMON_EVENTSEL0,
-	.perfctr		= MSR_ARCH_PERFMON_PERFCTR0,
-	.event_map		= intel_pmu_event_map,
-	.raw_event		= intel_pmu_raw_event,
-	.max_events		= ARRAY_SIZE(intel_perfmon_event_map),
-	.apic			= 1,
-	/*
-	 * Intel PMCs cannot be accessed sanely above 32 bit width,
-	 * so we install an artificial 1<<31 period regardless of
-	 * the generic event period:
-	 */
-	.max_period		= (1ULL << 31) - 1,
-	.enable_bts		= intel_pmu_enable_bts,
-	.disable_bts		= intel_pmu_disable_bts,
-	.get_event_idx		= intel_get_event_idx,
-};
+static struct event_constraint *
+x86_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
+{
+	struct event_constraint *c;
 
-static __initconst struct x86_pmu amd_pmu = {
-	.name			= "AMD",
-	.handle_irq		= amd_pmu_handle_irq,
-	.disable_all		= amd_pmu_disable_all,
-	.enable_all		= amd_pmu_enable_all,
-	.enable			= amd_pmu_enable_event,
-	.disable		= amd_pmu_disable_event,
-	.eventsel		= MSR_K7_EVNTSEL0,
-	.perfctr		= MSR_K7_PERFCTR0,
-	.event_map		= amd_pmu_event_map,
-	.raw_event		= amd_pmu_raw_event,
-	.max_events		= ARRAY_SIZE(amd_perfmon_event_map),
-	.num_events		= 4,
-	.event_bits		= 48,
-	.event_mask		= (1ULL << 48) - 1,
-	.apic			= 1,
-	/* use highest bit to detect overflow */
-	.max_period		= (1ULL << 47) - 1,
-	.get_event_idx		= gen_get_event_idx,
-};
+	if (x86_pmu.event_constraints) {
+		for_each_event_constraint(c, x86_pmu.event_constraints) {
+			if ((event->hw.config & c->cmask) == c->code)
+				return c;
+		}
+	}
 
-static __init int p6_pmu_init(void)
+	return &unconstrained;
+}
+
+static int x86_event_sched_in(struct perf_event *event,
+			  struct perf_cpu_context *cpuctx)
 {
-	switch (boot_cpu_data.x86_model) {
-	case 1:
-	case 3:  /* Pentium Pro */
-	case 5:
-	case 6:  /* Pentium II */
-	case 7:
-	case 8:
-	case 11: /* Pentium III */
-		event_constraints = intel_p6_event_constraints;
-		break;
-	case 9:
-	case 13:
-		/* Pentium M */
-		event_constraints = intel_p6_event_constraints;
-		break;
-	default:
-		pr_cont("unsupported p6 CPU model %d ",
-			boot_cpu_data.x86_model);
-		return -ENODEV;
-	}
+	int ret = 0;
 
-	x86_pmu = p6_pmu;
+	event->state = PERF_EVENT_STATE_ACTIVE;
+	event->oncpu = smp_processor_id();
+	event->tstamp_running += event->ctx->time - event->tstamp_stopped;
 
-	return 0;
+	if (!is_x86_event(event))
+		ret = event->pmu->enable(event);
+
+	if (!ret && !is_software_event(event))
+		cpuctx->active_oncpu++;
+
+	if (!ret && event->attr.exclusive)
+		cpuctx->exclusive = 1;
+
+	return ret;
 }
 
-static __init int intel_pmu_init(void)
+static void x86_event_sched_out(struct perf_event *event,
+			    struct perf_cpu_context *cpuctx)
 {
-	union cpuid10_edx edx;
-	union cpuid10_eax eax;
-	unsigned int unused;
-	unsigned int ebx;
-	int version;
+	event->state = PERF_EVENT_STATE_INACTIVE;
+	event->oncpu = -1;
 
-	if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
-		/* check for P6 processor family */
-	   if (boot_cpu_data.x86 == 6) {
-		return p6_pmu_init();
-	   } else {
-		return -ENODEV;
-	   }
-	}
+	if (!is_x86_event(event))
+		event->pmu->disable(event);
 
-	/*
-	 * Check whether the Architectural PerfMon supports
-	 * Branch Misses Retired hw_event or not.
-	 */
-	cpuid(10, &eax.full, &ebx, &unused, &edx.full);
-	if (eax.split.mask_length <= ARCH_PERFMON_BRANCH_MISSES_RETIRED)
-		return -ENODEV;
+	event->tstamp_running -= event->ctx->time - event->tstamp_stopped;
 
-	version = eax.split.version_id;
-	if (version < 2)
-		return -ENODEV;
+	if (!is_software_event(event))
+		cpuctx->active_oncpu--;
 
-	x86_pmu				= intel_pmu;
-	x86_pmu.version			= version;
-	x86_pmu.num_events		= eax.split.num_events;
-	x86_pmu.event_bits		= eax.split.bit_width;
-	x86_pmu.event_mask		= (1ULL << eax.split.bit_width) - 1;
+	if (event->attr.exclusive || !cpuctx->active_oncpu)
+		cpuctx->exclusive = 0;
+}
 
+/*
+ * Called to enable a whole group of events.
+ * Returns 1 if the group was enabled, or -EAGAIN if it could not be.
+ * Assumes the caller has disabled interrupts and has
+ * frozen the PMU with hw_perf_save_disable.
+ *
+ * called with PMU disabled. If successful and return value 1,
+ * then guaranteed to call perf_enable() and hw_perf_enable()
+ */
+int hw_perf_group_sched_in(struct perf_event *leader,
+	       struct perf_cpu_context *cpuctx,
+	       struct perf_event_context *ctx)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct perf_event *sub;
+	int assign[X86_PMC_IDX_MAX];
+	int n0, n1, ret;
+
+	/* n0 = total number of events */
+	n0 = collect_events(cpuc, leader, true);
+	if (n0 < 0)
+		return n0;
+
+	ret = x86_schedule_events(cpuc, n0, assign);
+	if (ret)
+		return ret;
+
+	ret = x86_event_sched_in(leader, cpuctx);
+	if (ret)
+		return ret;
+
+	n1 = 1;
+	list_for_each_entry(sub, &leader->sibling_list, group_entry) {
+		if (sub->state > PERF_EVENT_STATE_OFF) {
+			ret = x86_event_sched_in(sub, cpuctx);
+			if (ret)
+				goto undo;
+			++n1;
+		}
+	}
 	/*
-	 * Quirk: v2 perfmon does not report fixed-purpose events, so
-	 * assume at least 3 events:
+	 * copy new assignment, now we know it is possible
+	 * will be used by hw_perf_enable()
 	 */
-	x86_pmu.num_events_fixed	= max((int)edx.split.num_events_fixed, 3);
+	memcpy(cpuc->assign, assign, n0*sizeof(int));
+
+	cpuc->n_events  = n0;
+	cpuc->n_added  += n1;
+	ctx->nr_active += n1;
 
 	/*
-	 * Install the hw-cache-events table:
+	 * 1 means successful and events are active
+	 * This is not quite true because we defer
+	 * actual activation until hw_perf_enable() but
+	 * this way we* ensure caller won't try to enable
+	 * individual events
 	 */
-	switch (boot_cpu_data.x86_model) {
-	case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
-	case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
-	case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */
-	case 29: /* six-core 45 nm xeon "Dunnington" */
-		memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
-		       sizeof(hw_cache_event_ids));
+	return 1;
+undo:
+	x86_event_sched_out(leader, cpuctx);
+	n0  = 1;
+	list_for_each_entry(sub, &leader->sibling_list, group_entry) {
+		if (sub->state == PERF_EVENT_STATE_ACTIVE) {
+			x86_event_sched_out(sub, cpuctx);
+			if (++n0 == n1)
+				break;
+		}
+	}
+	return ret;
+}
 
-		pr_cont("Core2 events, ");
-		event_constraints = intel_core_event_constraints;
-		break;
-	default:
-	case 26:
-		memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
-		       sizeof(hw_cache_event_ids));
+#include "perf_event_amd.c"
+#include "perf_event_p6.c"
+#include "perf_event_intel.c"
 
-		event_constraints = intel_nehalem_event_constraints;
-		pr_cont("Nehalem/Corei7 events, ");
+static int __cpuinit
+x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (long)hcpu;
+	int ret = NOTIFY_OK;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+		if (x86_pmu.cpu_prepare)
+			ret = x86_pmu.cpu_prepare(cpu);
 		break;
-	case 28:
-		memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
-		       sizeof(hw_cache_event_ids));
 
-		pr_cont("Atom events, ");
+	case CPU_STARTING:
+		if (x86_pmu.cpu_starting)
+			x86_pmu.cpu_starting(cpu);
 		break;
-	}
-	return 0;
-}
 
-static __init int amd_pmu_init(void)
-{
-	/* Performance-monitoring supported from K7 and later: */
-	if (boot_cpu_data.x86 < 6)
-		return -ENODEV;
+	case CPU_DYING:
+		if (x86_pmu.cpu_dying)
+			x86_pmu.cpu_dying(cpu);
+		break;
 
-	x86_pmu = amd_pmu;
+	case CPU_UP_CANCELED:
+	case CPU_DEAD:
+		if (x86_pmu.cpu_dead)
+			x86_pmu.cpu_dead(cpu);
+		break;
 
-	/* Events are common for all AMDs */
-	memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
-	       sizeof(hw_cache_event_ids));
+	default:
+		break;
+	}
 
-	return 0;
+	return ret;
 }
 
 static void __init pmu_check_apic(void)
@@ -2176,6 +1378,7 @@ static void __init pmu_check_apic(void)
 
 void __init init_hw_perf_events(void)
 {
+	struct event_constraint *c;
 	int err;
 
 	pr_info("Performance Events: ");
@@ -2220,6 +1423,20 @@ void __init init_hw_perf_events(void)
 	perf_events_lapic_init();
 	register_die_notifier(&perf_event_nmi_notifier);
 
+	unconstrained = (struct event_constraint)
+		__EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_events) - 1,
+				   0, x86_pmu.num_events);
+
+	if (x86_pmu.event_constraints) {
+		for_each_event_constraint(c, x86_pmu.event_constraints) {
+			if (c->cmask != INTEL_ARCH_FIXED_MASK)
+				continue;
+
+			c->idxmsk64 |= (1ULL << x86_pmu.num_events) - 1;
+			c->weight += x86_pmu.num_events;
+		}
+	}
+
 	pr_info("... version:                %d\n",     x86_pmu.version);
 	pr_info("... bit width:              %d\n",     x86_pmu.event_bits);
 	pr_info("... generic registers:      %d\n",     x86_pmu.num_events);
@@ -2227,60 +1444,91 @@ void __init init_hw_perf_events(void)
 	pr_info("... max period:             %016Lx\n", x86_pmu.max_period);
 	pr_info("... fixed-purpose events:   %d\n",     x86_pmu.num_events_fixed);
 	pr_info("... event mask:             %016Lx\n", perf_event_mask);
+
+	perf_cpu_notifier(x86_pmu_notifier);
 }
 
 static inline void x86_pmu_read(struct perf_event *event)
 {
-	x86_perf_event_update(event, &event->hw, event->hw.idx);
+	x86_perf_event_update(event);
 }
 
 static const struct pmu pmu = {
 	.enable		= x86_pmu_enable,
 	.disable	= x86_pmu_disable,
+	.start		= x86_pmu_start,
+	.stop		= x86_pmu_stop,
 	.read		= x86_pmu_read,
 	.unthrottle	= x86_pmu_unthrottle,
 };
 
-static int
-validate_event(struct cpu_hw_events *cpuc, struct perf_event *event)
-{
-	struct hw_perf_event fake_event = event->hw;
-
-	if (event->pmu && event->pmu != &pmu)
-		return 0;
-
-	return x86_schedule_event(cpuc, &fake_event) >= 0;
-}
-
+/*
+ * validate a single event group
+ *
+ * validation include:
+ *	- check events are compatible which each other
+ *	- events do not compete for the same counter
+ *	- number of events <= number of counters
+ *
+ * validation ensures the group can be loaded onto the
+ * PMU if it was the only group available.
+ */
 static int validate_group(struct perf_event *event)
 {
-	struct perf_event *sibling, *leader = event->group_leader;
-	struct cpu_hw_events fake_pmu;
+	struct perf_event *leader = event->group_leader;
+	struct cpu_hw_events *fake_cpuc;
+	int ret, n;
 
-	memset(&fake_pmu, 0, sizeof(fake_pmu));
+	ret = -ENOMEM;
+	fake_cpuc = kmalloc(sizeof(*fake_cpuc), GFP_KERNEL | __GFP_ZERO);
+	if (!fake_cpuc)
+		goto out;
 
-	if (!validate_event(&fake_pmu, leader))
-		return -ENOSPC;
+	/*
+	 * the event is not yet connected with its
+	 * siblings therefore we must first collect
+	 * existing siblings, then add the new event
+	 * before we can simulate the scheduling
+	 */
+	ret = -ENOSPC;
+	n = collect_events(fake_cpuc, leader, true);
+	if (n < 0)
+		goto out_free;
 
-	list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
-		if (!validate_event(&fake_pmu, sibling))
-			return -ENOSPC;
-	}
+	fake_cpuc->n_events = n;
+	n = collect_events(fake_cpuc, event, false);
+	if (n < 0)
+		goto out_free;
 
-	if (!validate_event(&fake_pmu, event))
-		return -ENOSPC;
+	fake_cpuc->n_events = n;
 
-	return 0;
+	ret = x86_schedule_events(fake_cpuc, n, NULL);
+
+out_free:
+	kfree(fake_cpuc);
+out:
+	return ret;
 }
 
 const struct pmu *hw_perf_event_init(struct perf_event *event)
 {
+	const struct pmu *tmp;
 	int err;
 
 	err = __hw_perf_event_init(event);
 	if (!err) {
+		/*
+		 * we temporarily connect event to its pmu
+		 * such that validate_group() can classify
+		 * it as an x86 event using is_x86_event()
+		 */
+		tmp = event->pmu;
+		event->pmu = &pmu;
+
 		if (event->group_leader != event)
 			err = validate_group(event);
+
+		event->pmu = tmp;
 	}
 	if (err) {
 		if (event->destroy)
@@ -2304,7 +1552,6 @@ void callchain_store(struct perf_callcha
 
 static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry);
 static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_nmi_entry);
-static DEFINE_PER_CPU(int, in_ignored_frame);
 
 
 static void
@@ -2320,10 +1567,6 @@ static void backtrace_warning(void *data
 
 static int backtrace_stack(void *data, char *name)
 {
-	per_cpu(in_ignored_frame, smp_processor_id()) =
-			x86_is_stack_id(NMI_STACK, name) ||
-			x86_is_stack_id(DEBUG_STACK, name);
-
 	return 0;
 }
 
@@ -2331,9 +1574,6 @@ static void backtrace_address(void *data
 {
 	struct perf_callchain_entry *entry = data;
 
-	if (per_cpu(in_ignored_frame, smp_processor_id()))
-		return;
-
 	if (reliable)
 		callchain_store(entry, addr);
 }
@@ -2392,14 +1632,42 @@ copy_from_user_nmi(void *to, const void
 	return len;
 }
 
-static int copy_stack_frame(const void __user *fp, struct stack_frame *frame)
+#ifdef CONFIG_COMPAT
+static inline int
+perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
 {
-	unsigned long bytes;
+	/* 32-bit process in 64-bit kernel. */
+	struct stack_frame_ia32 frame;
+	const void __user *fp;
 
-	bytes = copy_from_user_nmi(frame, fp, sizeof(*frame));
+	if (!test_thread_flag(TIF_IA32))
+		return 0;
 
-	return bytes == sizeof(*frame);
+	fp = compat_ptr(regs->bp);
+	while (entry->nr < PERF_MAX_STACK_DEPTH) {
+		unsigned long bytes;
+		frame.next_frame     = 0;
+		frame.return_address = 0;
+
+		bytes = copy_from_user_nmi(&frame, fp, sizeof(frame));
+		if (bytes != sizeof(frame))
+			break;
+
+		if (fp < compat_ptr(regs->sp))
+			break;
+
+		callchain_store(entry, frame.return_address);
+		fp = compat_ptr(frame.next_frame);
+	}
+	return 1;
+}
+#else
+static inline int
+perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
+{
+    return 0;
 }
+#endif
 
 static void
 perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry)
@@ -2415,11 +1683,16 @@ perf_callchain_user(struct pt_regs *regs
 	callchain_store(entry, PERF_CONTEXT_USER);
 	callchain_store(entry, regs->ip);
 
+	if (perf_callchain_user32(regs, entry))
+		return;
+
 	while (entry->nr < PERF_MAX_STACK_DEPTH) {
+		unsigned long bytes;
 		frame.next_frame	     = NULL;
 		frame.return_address = 0;
 
-		if (!copy_stack_frame(fp, &frame))
+		bytes = copy_from_user_nmi(&frame, fp, sizeof(frame));
+		if (bytes != sizeof(frame))
 			break;
 
 		if ((unsigned long)fp < regs->sp)
@@ -2440,9 +1713,6 @@ perf_do_callchain(struct pt_regs *regs,
 
 	is_user = user_mode(regs);
 
-	if (!current || current->pid == 0)
-		return;
-
 	if (is_user && current->state != TASK_RUNNING)
 		return;
 
@@ -2469,7 +1739,14 @@ struct perf_callchain_entry *perf_callch
 	return entry;
 }
 
-void hw_perf_event_setup_online(int cpu)
+void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip)
 {
-	init_debug_store_on_cpu(cpu);
+	regs->ip = ip;
+	/*
+	 * perf_arch_fetch_caller_regs adds another call, we need to increment
+	 * the skip level
+	 */
+	regs->bp = rewind_frame_pointer(skip + 1);
+	regs->cs = __KERNEL_CS;
+	local_save_flags(regs->flags);
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/perf_event_intel.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perf_event_intel.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/perf_event_intel.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perf_event_intel.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,980 @@
+#ifdef CONFIG_CPU_SUP_INTEL
+
+/*
+ * Intel PerfMon, used on Core and later.
+ */
+static const u64 intel_perfmon_event_map[] =
+{
+  [PERF_COUNT_HW_CPU_CYCLES]		= 0x003c,
+  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
+  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x4f2e,
+  [PERF_COUNT_HW_CACHE_MISSES]		= 0x412e,
+  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
+  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
+  [PERF_COUNT_HW_BUS_CYCLES]		= 0x013c,
+};
+
+static struct event_constraint intel_core_event_constraints[] =
+{
+	INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
+	INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
+	INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
+	INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
+	INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
+	INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FP_COMP_INSTR_RET */
+	EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_core2_event_constraints[] =
+{
+	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+	/*
+	 * Core2 has Fixed Counter 2 listed as CPU_CLK_UNHALTED.REF and event
+	 * 0x013c as CPU_CLK_UNHALTED.BUS and specifies there is a fixed
+	 * ratio between these counters.
+	 */
+	/* FIXED_EVENT_CONSTRAINT(0x013c, 2),  CPU_CLK_UNHALTED.REF */
+	INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */
+	INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
+	INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
+	INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
+	INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
+	INTEL_EVENT_CONSTRAINT(0x18, 0x1), /* IDLE_DURING_DIV */
+	INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
+	INTEL_EVENT_CONSTRAINT(0xa1, 0x1), /* RS_UOPS_DISPATCH_CYCLES */
+	INTEL_EVENT_CONSTRAINT(0xc9, 0x1), /* ITLB_MISS_RETIRED (T30-9) */
+	INTEL_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED */
+	EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_nehalem_event_constraints[] =
+{
+	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+	/* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */
+	INTEL_EVENT_CONSTRAINT(0x40, 0x3), /* L1D_CACHE_LD */
+	INTEL_EVENT_CONSTRAINT(0x41, 0x3), /* L1D_CACHE_ST */
+	INTEL_EVENT_CONSTRAINT(0x42, 0x3), /* L1D_CACHE_LOCK */
+	INTEL_EVENT_CONSTRAINT(0x43, 0x3), /* L1D_ALL_REF */
+	INTEL_EVENT_CONSTRAINT(0x48, 0x3), /* L1D_PEND_MISS */
+	INTEL_EVENT_CONSTRAINT(0x4e, 0x3), /* L1D_PREFETCH */
+	INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
+	INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
+	EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_westmere_event_constraints[] =
+{
+	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+	/* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */
+	INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
+	INTEL_EVENT_CONSTRAINT(0x60, 0x1), /* OFFCORE_REQUESTS_OUTSTANDING */
+	INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
+	EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_gen_event_constraints[] =
+{
+	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+	/* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */
+	EVENT_CONSTRAINT_END
+};
+
+static u64 intel_pmu_event_map(int hw_event)
+{
+	return intel_perfmon_event_map[hw_event];
+}
+
+static __initconst u64 westmere_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS       */
+		[ C(RESULT_MISS)   ] = 0x0151, /* L1D.REPL                     */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES      */
+		[ C(RESULT_MISS)   ] = 0x0251, /* L1D.M_REPL                   */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS        */
+		[ C(RESULT_MISS)   ] = 0x024e, /* L1D_PREFETCH.MISS            */
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                    */
+		[ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                   */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0324, /* L2_RQSTS.LOADS               */
+		[ C(RESULT_MISS)   ] = 0x0224, /* L2_RQSTS.LD_MISS             */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0c24, /* L2_RQSTS.RFOS                */
+		[ C(RESULT_MISS)   ] = 0x0824, /* L2_RQSTS.RFO_MISS            */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x4f2e, /* LLC Reference                */
+		[ C(RESULT_MISS)   ] = 0x412e, /* LLC Misses                   */
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS       */
+		[ C(RESULT_MISS)   ] = 0x0108, /* DTLB_LOAD_MISSES.ANY         */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES      */
+		[ C(RESULT_MISS)   ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS  */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P           */
+		[ C(RESULT_MISS)   ] = 0x0185, /* ITLB_MISSES.ANY              */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
+		[ C(RESULT_MISS)   ] = 0x03e8, /* BPU_CLEARS.ANY               */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+static __initconst u64 nehalem_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI            */
+		[ C(RESULT_MISS)   ] = 0x0140, /* L1D_CACHE_LD.I_STATE         */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI            */
+		[ C(RESULT_MISS)   ] = 0x0141, /* L1D_CACHE_ST.I_STATE         */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS        */
+		[ C(RESULT_MISS)   ] = 0x024e, /* L1D_PREFETCH.MISS            */
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                    */
+		[ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                   */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0324, /* L2_RQSTS.LOADS               */
+		[ C(RESULT_MISS)   ] = 0x0224, /* L2_RQSTS.LD_MISS             */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0c24, /* L2_RQSTS.RFOS                */
+		[ C(RESULT_MISS)   ] = 0x0824, /* L2_RQSTS.RFO_MISS            */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x4f2e, /* LLC Reference                */
+		[ C(RESULT_MISS)   ] = 0x412e, /* LLC Misses                   */
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI   (alias)  */
+		[ C(RESULT_MISS)   ] = 0x0108, /* DTLB_LOAD_MISSES.ANY         */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI   (alias)  */
+		[ C(RESULT_MISS)   ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS  */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P           */
+		[ C(RESULT_MISS)   ] = 0x20c8, /* ITLB_MISS_RETIRED            */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
+		[ C(RESULT_MISS)   ] = 0x03e8, /* BPU_CLEARS.ANY               */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+static __initconst u64 core2_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI          */
+		[ C(RESULT_MISS)   ] = 0x0140, /* L1D_CACHE_LD.I_STATE       */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI          */
+		[ C(RESULT_MISS)   ] = 0x0141, /* L1D_CACHE_ST.I_STATE       */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x104e, /* L1D_PREFETCH.REQUESTS      */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0080, /* L1I.READS                  */
+		[ C(RESULT_MISS)   ] = 0x0081, /* L1I.MISSES                 */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI                 */
+		[ C(RESULT_MISS)   ] = 0x4129, /* L2_LD.ISTATE               */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI                 */
+		[ C(RESULT_MISS)   ] = 0x412A, /* L2_ST.ISTATE               */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI  (alias) */
+		[ C(RESULT_MISS)   ] = 0x0208, /* DTLB_MISSES.MISS_LD        */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI  (alias) */
+		[ C(RESULT_MISS)   ] = 0x0808, /* DTLB_MISSES.MISS_ST        */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P         */
+		[ C(RESULT_MISS)   ] = 0x1282, /* ITLBMISSES                 */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY        */
+		[ C(RESULT_MISS)   ] = 0x00c5, /* BP_INST_RETIRED.MISPRED    */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+static __initconst u64 atom_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE.LD               */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE.ST               */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                  */
+		[ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                 */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI                 */
+		[ C(RESULT_MISS)   ] = 0x4129, /* L2_LD.ISTATE               */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI                 */
+		[ C(RESULT_MISS)   ] = 0x412A, /* L2_ST.ISTATE               */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE_LD.MESI  (alias) */
+		[ C(RESULT_MISS)   ] = 0x0508, /* DTLB_MISSES.MISS_LD        */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE_ST.MESI  (alias) */
+		[ C(RESULT_MISS)   ] = 0x0608, /* DTLB_MISSES.MISS_ST        */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P         */
+		[ C(RESULT_MISS)   ] = 0x0282, /* ITLB.MISSES                */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY        */
+		[ C(RESULT_MISS)   ] = 0x00c5, /* BP_INST_RETIRED.MISPRED    */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+static u64 intel_pmu_raw_event(u64 hw_event)
+{
+#define CORE_EVNTSEL_EVENT_MASK		0x000000FFULL
+#define CORE_EVNTSEL_UNIT_MASK		0x0000FF00ULL
+#define CORE_EVNTSEL_EDGE_MASK		0x00040000ULL
+#define CORE_EVNTSEL_INV_MASK		0x00800000ULL
+#define CORE_EVNTSEL_REG_MASK		0xFF000000ULL
+
+#define CORE_EVNTSEL_MASK		\
+	(INTEL_ARCH_EVTSEL_MASK |	\
+	 INTEL_ARCH_UNIT_MASK   |	\
+	 INTEL_ARCH_EDGE_MASK   |	\
+	 INTEL_ARCH_INV_MASK    |	\
+	 INTEL_ARCH_CNT_MASK)
+
+	return hw_event & CORE_EVNTSEL_MASK;
+}
+
+static void intel_pmu_enable_bts(u64 config)
+{
+	unsigned long debugctlmsr;
+
+	debugctlmsr = get_debugctlmsr();
+
+	debugctlmsr |= X86_DEBUGCTL_TR;
+	debugctlmsr |= X86_DEBUGCTL_BTS;
+	debugctlmsr |= X86_DEBUGCTL_BTINT;
+
+	if (!(config & ARCH_PERFMON_EVENTSEL_OS))
+		debugctlmsr |= X86_DEBUGCTL_BTS_OFF_OS;
+
+	if (!(config & ARCH_PERFMON_EVENTSEL_USR))
+		debugctlmsr |= X86_DEBUGCTL_BTS_OFF_USR;
+
+	update_debugctlmsr(debugctlmsr);
+}
+
+static void intel_pmu_disable_bts(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	unsigned long debugctlmsr;
+
+	if (!cpuc->ds)
+		return;
+
+	debugctlmsr = get_debugctlmsr();
+
+	debugctlmsr &=
+		~(X86_DEBUGCTL_TR | X86_DEBUGCTL_BTS | X86_DEBUGCTL_BTINT |
+		  X86_DEBUGCTL_BTS_OFF_OS | X86_DEBUGCTL_BTS_OFF_USR);
+
+	update_debugctlmsr(debugctlmsr);
+}
+
+static void intel_pmu_disable_all(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
+
+	if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask))
+		intel_pmu_disable_bts();
+}
+
+static void intel_pmu_enable_all(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl);
+
+	if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
+		struct perf_event *event =
+			cpuc->events[X86_PMC_IDX_FIXED_BTS];
+
+		if (WARN_ON_ONCE(!event))
+			return;
+
+		intel_pmu_enable_bts(event->hw.config);
+	}
+}
+
+static inline u64 intel_pmu_get_status(void)
+{
+	u64 status;
+
+	rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
+
+	return status;
+}
+
+static inline void intel_pmu_ack_status(u64 ack)
+{
+	wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
+}
+
+static inline void
+intel_pmu_disable_fixed(struct hw_perf_event *hwc)
+{
+	int idx = hwc->idx - X86_PMC_IDX_FIXED;
+	u64 ctrl_val, mask;
+
+	mask = 0xfULL << (idx * 4);
+
+	rdmsrl(hwc->config_base, ctrl_val);
+	ctrl_val &= ~mask;
+	(void)checking_wrmsrl(hwc->config_base, ctrl_val);
+}
+
+static void intel_pmu_drain_bts_buffer(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct debug_store *ds = cpuc->ds;
+	struct bts_record {
+		u64	from;
+		u64	to;
+		u64	flags;
+	};
+	struct perf_event *event = cpuc->events[X86_PMC_IDX_FIXED_BTS];
+	struct bts_record *at, *top;
+	struct perf_output_handle handle;
+	struct perf_event_header header;
+	struct perf_sample_data data;
+	struct pt_regs regs;
+
+	if (!event)
+		return;
+
+	if (!ds)
+		return;
+
+	at  = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
+	top = (struct bts_record *)(unsigned long)ds->bts_index;
+
+	if (top <= at)
+		return;
+
+	ds->bts_index = ds->bts_buffer_base;
+
+	perf_sample_data_init(&data, 0);
+
+	data.period	= event->hw.last_period;
+	regs.ip		= 0;
+
+	/*
+	 * Prepare a generic sample, i.e. fill in the invariant fields.
+	 * We will overwrite the from and to address before we output
+	 * the sample.
+	 */
+	perf_prepare_sample(&header, &data, event, &regs);
+
+	if (perf_output_begin(&handle, event,
+			      header.size * (top - at), 1, 1))
+		return;
+
+	for (; at < top; at++) {
+		data.ip		= at->from;
+		data.addr	= at->to;
+
+		perf_output_sample(&handle, &header, &data, event);
+	}
+
+	perf_output_end(&handle);
+
+	/* There's new data available. */
+	event->hw.interrupts++;
+	event->pending_kill = POLL_IN;
+}
+
+static inline void
+intel_pmu_disable_event(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) {
+		intel_pmu_disable_bts();
+		intel_pmu_drain_bts_buffer();
+		return;
+	}
+
+	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
+		intel_pmu_disable_fixed(hwc);
+		return;
+	}
+
+	x86_pmu_disable_event(event);
+}
+
+static inline void
+intel_pmu_enable_fixed(struct hw_perf_event *hwc)
+{
+	int idx = hwc->idx - X86_PMC_IDX_FIXED;
+	u64 ctrl_val, bits, mask;
+	int err;
+
+	/*
+	 * Enable IRQ generation (0x8),
+	 * and enable ring-3 counting (0x2) and ring-0 counting (0x1)
+	 * if requested:
+	 */
+	bits = 0x8ULL;
+	if (hwc->config & ARCH_PERFMON_EVENTSEL_USR)
+		bits |= 0x2;
+	if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
+		bits |= 0x1;
+
+	/*
+	 * ANY bit is supported in v3 and up
+	 */
+	if (x86_pmu.version > 2 && hwc->config & ARCH_PERFMON_EVENTSEL_ANY)
+		bits |= 0x4;
+
+	bits <<= (idx * 4);
+	mask = 0xfULL << (idx * 4);
+
+	rdmsrl(hwc->config_base, ctrl_val);
+	ctrl_val &= ~mask;
+	ctrl_val |= bits;
+	err = checking_wrmsrl(hwc->config_base, ctrl_val);
+}
+
+static void intel_pmu_enable_event(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) {
+		if (!__get_cpu_var(cpu_hw_events).enabled)
+			return;
+
+		intel_pmu_enable_bts(hwc->config);
+		return;
+	}
+
+	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
+		intel_pmu_enable_fixed(hwc);
+		return;
+	}
+
+	__x86_pmu_enable_event(hwc);
+}
+
+/*
+ * Save and restart an expired event. Called by NMI contexts,
+ * so it has to be careful about preempting normal event ops:
+ */
+static int intel_pmu_save_and_restart(struct perf_event *event)
+{
+	x86_perf_event_update(event);
+	return x86_perf_event_set_period(event);
+}
+
+static void intel_pmu_reset(void)
+{
+	struct debug_store *ds = __get_cpu_var(cpu_hw_events).ds;
+	unsigned long flags;
+	int idx;
+
+	if (!x86_pmu.num_events)
+		return;
+
+	local_irq_save(flags);
+
+	printk("clearing PMU state on CPU#%d\n", smp_processor_id());
+
+	for (idx = 0; idx < x86_pmu.num_events; idx++) {
+		checking_wrmsrl(x86_pmu.eventsel + idx, 0ull);
+		checking_wrmsrl(x86_pmu.perfctr  + idx, 0ull);
+	}
+	for (idx = 0; idx < x86_pmu.num_events_fixed; idx++) {
+		checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
+	}
+	if (ds)
+		ds->bts_index = ds->bts_buffer_base;
+
+	local_irq_restore(flags);
+}
+
+/*
+ * This handler is triggered by the local APIC, so the APIC IRQ handling
+ * rules apply:
+ */
+static int intel_pmu_handle_irq(struct pt_regs *regs)
+{
+	struct perf_sample_data data;
+	struct cpu_hw_events *cpuc;
+	int bit, loops;
+	u64 ack, status;
+
+	perf_sample_data_init(&data, 0);
+
+	cpuc = &__get_cpu_var(cpu_hw_events);
+
+	intel_pmu_disable_all();
+	intel_pmu_drain_bts_buffer();
+	status = intel_pmu_get_status();
+	if (!status) {
+		intel_pmu_enable_all();
+		return 0;
+	}
+
+	loops = 0;
+again:
+	if (++loops > 100) {
+		WARN_ONCE(1, "perfevents: irq loop stuck!\n");
+		perf_event_print_debug();
+		intel_pmu_reset();
+		goto done;
+	}
+
+	inc_irq_stat(apic_perf_irqs);
+	ack = status;
+	for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
+		struct perf_event *event = cpuc->events[bit];
+
+		if (!test_bit(bit, cpuc->active_mask))
+			continue;
+
+		if (!intel_pmu_save_and_restart(event))
+			continue;
+
+		data.period = event->hw.last_period;
+
+		if (perf_event_overflow(event, 1, &data, regs))
+			x86_pmu_stop(event);
+	}
+
+	intel_pmu_ack_status(ack);
+
+	/*
+	 * Repeat if there is more work to be done:
+	 */
+	status = intel_pmu_get_status();
+	if (status)
+		goto again;
+
+done:
+	intel_pmu_enable_all();
+	return 1;
+}
+
+static struct event_constraint bts_constraint =
+	EVENT_CONSTRAINT(0, 1ULL << X86_PMC_IDX_FIXED_BTS, 0);
+
+static struct event_constraint *
+intel_special_constraints(struct perf_event *event)
+{
+	unsigned int hw_event;
+
+	hw_event = event->hw.config & INTEL_ARCH_EVENT_MASK;
+
+	if (unlikely((hw_event ==
+		      x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS)) &&
+		     (event->hw.sample_period == 1))) {
+
+		return &bts_constraint;
+	}
+	return NULL;
+}
+
+static struct event_constraint *
+intel_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
+{
+	struct event_constraint *c;
+
+	c = intel_special_constraints(event);
+	if (c)
+		return c;
+
+	return x86_get_event_constraints(cpuc, event);
+}
+
+static __initconst struct x86_pmu core_pmu = {
+	.name			= "core",
+	.handle_irq		= x86_pmu_handle_irq,
+	.disable_all		= x86_pmu_disable_all,
+	.enable_all		= x86_pmu_enable_all,
+	.enable			= x86_pmu_enable_event,
+	.disable		= x86_pmu_disable_event,
+	.eventsel		= MSR_ARCH_PERFMON_EVENTSEL0,
+	.perfctr		= MSR_ARCH_PERFMON_PERFCTR0,
+	.event_map		= intel_pmu_event_map,
+	.raw_event		= intel_pmu_raw_event,
+	.max_events		= ARRAY_SIZE(intel_perfmon_event_map),
+	.apic			= 1,
+	/*
+	 * Intel PMCs cannot be accessed sanely above 32 bit width,
+	 * so we install an artificial 1<<31 period regardless of
+	 * the generic event period:
+	 */
+	.max_period		= (1ULL << 31) - 1,
+	.get_event_constraints	= intel_get_event_constraints,
+	.event_constraints	= intel_core_event_constraints,
+};
+
+static __initconst struct x86_pmu intel_pmu = {
+	.name			= "Intel",
+	.handle_irq		= intel_pmu_handle_irq,
+	.disable_all		= intel_pmu_disable_all,
+	.enable_all		= intel_pmu_enable_all,
+	.enable			= intel_pmu_enable_event,
+	.disable		= intel_pmu_disable_event,
+	.eventsel		= MSR_ARCH_PERFMON_EVENTSEL0,
+	.perfctr		= MSR_ARCH_PERFMON_PERFCTR0,
+	.event_map		= intel_pmu_event_map,
+	.raw_event		= intel_pmu_raw_event,
+	.max_events		= ARRAY_SIZE(intel_perfmon_event_map),
+	.apic			= 1,
+	/*
+	 * Intel PMCs cannot be accessed sanely above 32 bit width,
+	 * so we install an artificial 1<<31 period regardless of
+	 * the generic event period:
+	 */
+	.max_period		= (1ULL << 31) - 1,
+	.enable_bts		= intel_pmu_enable_bts,
+	.disable_bts		= intel_pmu_disable_bts,
+	.get_event_constraints	= intel_get_event_constraints,
+
+	.cpu_starting		= init_debug_store_on_cpu,
+	.cpu_dying		= fini_debug_store_on_cpu,
+};
+
+static __init int intel_pmu_init(void)
+{
+	union cpuid10_edx edx;
+	union cpuid10_eax eax;
+	unsigned int unused;
+	unsigned int ebx;
+	int version;
+
+	if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
+		/* check for P6 processor family */
+	   if (boot_cpu_data.x86 == 6) {
+		return p6_pmu_init();
+	   } else {
+		return -ENODEV;
+	   }
+	}
+
+	/*
+	 * Check whether the Architectural PerfMon supports
+	 * Branch Misses Retired hw_event or not.
+	 */
+	cpuid(10, &eax.full, &ebx, &unused, &edx.full);
+	if (eax.split.mask_length <= ARCH_PERFMON_BRANCH_MISSES_RETIRED)
+		return -ENODEV;
+
+	version = eax.split.version_id;
+	if (version < 2)
+		x86_pmu = core_pmu;
+	else
+		x86_pmu = intel_pmu;
+
+	x86_pmu.version			= version;
+	x86_pmu.num_events		= eax.split.num_events;
+	x86_pmu.event_bits		= eax.split.bit_width;
+	x86_pmu.event_mask		= (1ULL << eax.split.bit_width) - 1;
+
+	/*
+	 * Quirk: v2 perfmon does not report fixed-purpose events, so
+	 * assume at least 3 events:
+	 */
+	if (version > 1)
+		x86_pmu.num_events_fixed = max((int)edx.split.num_events_fixed, 3);
+
+	/*
+	 * Install the hw-cache-events table:
+	 */
+	switch (boot_cpu_data.x86_model) {
+	case 14: /* 65 nm core solo/duo, "Yonah" */
+		pr_cont("Core events, ");
+		break;
+
+	case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
+	case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
+	case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */
+	case 29: /* six-core 45 nm xeon "Dunnington" */
+		memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
+		       sizeof(hw_cache_event_ids));
+
+		x86_pmu.event_constraints = intel_core2_event_constraints;
+		pr_cont("Core2 events, ");
+		break;
+
+	case 26: /* 45 nm nehalem, "Bloomfield" */
+	case 30: /* 45 nm nehalem, "Lynnfield" */
+	case 46: /* 45 nm nehalem-ex, "Beckton" */
+		memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
+		       sizeof(hw_cache_event_ids));
+
+		x86_pmu.event_constraints = intel_nehalem_event_constraints;
+		pr_cont("Nehalem/Corei7 events, ");
+		break;
+	case 28: /* Atom */
+		memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
+		       sizeof(hw_cache_event_ids));
+
+		x86_pmu.event_constraints = intel_gen_event_constraints;
+		pr_cont("Atom events, ");
+		break;
+
+	case 37: /* 32 nm nehalem, "Clarkdale" */
+	case 44: /* 32 nm nehalem, "Gulftown" */
+		memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids,
+		       sizeof(hw_cache_event_ids));
+
+		x86_pmu.event_constraints = intel_westmere_event_constraints;
+		pr_cont("Westmere events, ");
+		break;
+
+	default:
+		/*
+		 * default constraints for v2 and up
+		 */
+		x86_pmu.event_constraints = intel_gen_event_constraints;
+		pr_cont("generic architected perfmon, ");
+	}
+	return 0;
+}
+
+#else /* CONFIG_CPU_SUP_INTEL */
+
+static int intel_pmu_init(void)
+{
+	return 0;
+}
+
+#endif /* CONFIG_CPU_SUP_INTEL */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/perf_event_p6.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perf_event_p6.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/perf_event_p6.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perf_event_p6.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,159 @@
+#ifdef CONFIG_CPU_SUP_INTEL
+
+/*
+ * Not sure about some of these
+ */
+static const u64 p6_perfmon_event_map[] =
+{
+  [PERF_COUNT_HW_CPU_CYCLES]		= 0x0079,
+  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
+  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0f2e,
+  [PERF_COUNT_HW_CACHE_MISSES]		= 0x012e,
+  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
+  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
+  [PERF_COUNT_HW_BUS_CYCLES]		= 0x0062,
+};
+
+static u64 p6_pmu_event_map(int hw_event)
+{
+	return p6_perfmon_event_map[hw_event];
+}
+
+/*
+ * Event setting that is specified not to count anything.
+ * We use this to effectively disable a counter.
+ *
+ * L2_RQSTS with 0 MESI unit mask.
+ */
+#define P6_NOP_EVENT			0x0000002EULL
+
+static u64 p6_pmu_raw_event(u64 hw_event)
+{
+#define P6_EVNTSEL_EVENT_MASK		0x000000FFULL
+#define P6_EVNTSEL_UNIT_MASK		0x0000FF00ULL
+#define P6_EVNTSEL_EDGE_MASK		0x00040000ULL
+#define P6_EVNTSEL_INV_MASK		0x00800000ULL
+#define P6_EVNTSEL_REG_MASK		0xFF000000ULL
+
+#define P6_EVNTSEL_MASK			\
+	(P6_EVNTSEL_EVENT_MASK |	\
+	 P6_EVNTSEL_UNIT_MASK  |	\
+	 P6_EVNTSEL_EDGE_MASK  |	\
+	 P6_EVNTSEL_INV_MASK   |	\
+	 P6_EVNTSEL_REG_MASK)
+
+	return hw_event & P6_EVNTSEL_MASK;
+}
+
+static struct event_constraint p6_event_constraints[] =
+{
+	INTEL_EVENT_CONSTRAINT(0xc1, 0x1),	/* FLOPS */
+	INTEL_EVENT_CONSTRAINT(0x10, 0x1),	/* FP_COMP_OPS_EXE */
+	INTEL_EVENT_CONSTRAINT(0x11, 0x1),	/* FP_ASSIST */
+	INTEL_EVENT_CONSTRAINT(0x12, 0x2),	/* MUL */
+	INTEL_EVENT_CONSTRAINT(0x13, 0x2),	/* DIV */
+	INTEL_EVENT_CONSTRAINT(0x14, 0x1),	/* CYCLES_DIV_BUSY */
+	EVENT_CONSTRAINT_END
+};
+
+static void p6_pmu_disable_all(void)
+{
+	u64 val;
+
+	/* p6 only has one enable register */
+	rdmsrl(MSR_P6_EVNTSEL0, val);
+	val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
+	wrmsrl(MSR_P6_EVNTSEL0, val);
+}
+
+static void p6_pmu_enable_all(void)
+{
+	unsigned long val;
+
+	/* p6 only has one enable register */
+	rdmsrl(MSR_P6_EVNTSEL0, val);
+	val |= ARCH_PERFMON_EVENTSEL_ENABLE;
+	wrmsrl(MSR_P6_EVNTSEL0, val);
+}
+
+static inline void
+p6_pmu_disable_event(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	u64 val = P6_NOP_EVENT;
+
+	if (cpuc->enabled)
+		val |= ARCH_PERFMON_EVENTSEL_ENABLE;
+
+	(void)checking_wrmsrl(hwc->config_base + hwc->idx, val);
+}
+
+static void p6_pmu_enable_event(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	u64 val;
+
+	val = hwc->config;
+	if (cpuc->enabled)
+		val |= ARCH_PERFMON_EVENTSEL_ENABLE;
+
+	(void)checking_wrmsrl(hwc->config_base + hwc->idx, val);
+}
+
+static __initconst struct x86_pmu p6_pmu = {
+	.name			= "p6",
+	.handle_irq		= x86_pmu_handle_irq,
+	.disable_all		= p6_pmu_disable_all,
+	.enable_all		= p6_pmu_enable_all,
+	.enable			= p6_pmu_enable_event,
+	.disable		= p6_pmu_disable_event,
+	.eventsel		= MSR_P6_EVNTSEL0,
+	.perfctr		= MSR_P6_PERFCTR0,
+	.event_map		= p6_pmu_event_map,
+	.raw_event		= p6_pmu_raw_event,
+	.max_events		= ARRAY_SIZE(p6_perfmon_event_map),
+	.apic			= 1,
+	.max_period		= (1ULL << 31) - 1,
+	.version		= 0,
+	.num_events		= 2,
+	/*
+	 * Events have 40 bits implemented. However they are designed such
+	 * that bits [32-39] are sign extensions of bit 31. As such the
+	 * effective width of a event for P6-like PMU is 32 bits only.
+	 *
+	 * See IA-32 Intel Architecture Software developer manual Vol 3B
+	 */
+	.event_bits		= 32,
+	.event_mask		= (1ULL << 32) - 1,
+	.get_event_constraints	= x86_get_event_constraints,
+	.event_constraints	= p6_event_constraints,
+};
+
+static __init int p6_pmu_init(void)
+{
+	switch (boot_cpu_data.x86_model) {
+	case 1:
+	case 3:  /* Pentium Pro */
+	case 5:
+	case 6:  /* Pentium II */
+	case 7:
+	case 8:
+	case 11: /* Pentium III */
+	case 9:
+	case 13:
+		/* Pentium M */
+		break;
+	default:
+		pr_cont("unsupported p6 CPU model %d ",
+			boot_cpu_data.x86_model);
+		return -ENODEV;
+	}
+
+	x86_pmu = p6_pmu;
+
+	return 0;
+}
+
+#endif /* CONFIG_CPU_SUP_INTEL */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/vmware.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/vmware.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/vmware.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/vmware.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  */
 
 #include <linux/dmi.h>
+#include <linux/module.h>
 #include <asm/div64.h>
 #include <asm/vmware.h>
 #include <asm/x86_init.h>
@@ -101,6 +102,7 @@ int vmware_platform(void)
 
 	return 0;
 }
+EXPORT_SYMBOL(vmware_platform);
 
 /*
  * VMware hypervisor takes care of exporting a reliable TSC to the guest.
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/cpuid.c linux-libre-2.6.34-gnu1/arch/x86/kernel/cpuid.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/cpuid.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/cpuid.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/cpu.h>
 #include <linux/notifier.h>
 #include <linux/uaccess.h>
+#include <linux/gfp.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/crash.c linux-libre-2.6.34-gnu1/arch/x86/kernel/crash.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/crash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/crash.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,6 @@
 #include <asm/cpu.h>
 #include <asm/reboot.h>
 #include <asm/virtext.h>
-#include <asm/x86_init.h>
 
 #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
 
@@ -103,10 +102,5 @@ void native_machine_crash_shutdown(struc
 #ifdef CONFIG_HPET_TIMER
 	hpet_disable();
 #endif
-
-#ifdef CONFIG_X86_64
-	x86_platform.iommu_shutdown();
-#endif
-
 	crash_save_cpu(regs, safe_smp_processor_id());
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/crash_dump_32.c linux-libre-2.6.34-gnu1/arch/x86/kernel/crash_dump_32.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/crash_dump_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/crash_dump_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
  *	Copyright (C) IBM Corporation, 2004. All rights reserved
  */
 
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/highmem.h>
 #include <linux/crash_dump.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/dumpstack_32.c linux-libre-2.6.34-gnu1/arch/x86/kernel/dumpstack_32.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/dumpstack_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/dumpstack_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,11 +18,6 @@
 
 #include "dumpstack.h"
 
-/* Just a stub for now */
-int x86_is_stack_id(int id, char *name)
-{
-	return 0;
-}
 
 void dump_trace(struct task_struct *task, struct pt_regs *regs,
 		unsigned long *stack, unsigned long bp,
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/dumpstack_64.c linux-libre-2.6.34-gnu1/arch/x86/kernel/dumpstack_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/dumpstack_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/dumpstack_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,11 +33,6 @@ static char x86_stack_ids[][8] = {
 #endif
 };
 
-int x86_is_stack_id(int id, char *name)
-{
-	return x86_stack_ids[id - 1] == name;
-}
-
 static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
 					 unsigned *usedp, char **idp)
 {
@@ -125,9 +120,15 @@ fixup_bp_irq_link(unsigned long bp, unsi
 {
 #ifdef CONFIG_FRAME_POINTER
 	struct stack_frame *frame = (struct stack_frame *)bp;
+	unsigned long next;
 
-	if (!in_irq_stack(stack, irq_stack, irq_stack_end))
-		return (unsigned long)frame->next_frame;
+	if (!in_irq_stack(stack, irq_stack, irq_stack_end)) {
+		if (!probe_kernel_address(&frame->next_frame, next))
+			return next;
+		else
+			WARN_ONCE(1, "Perf: bad frame pointer = %p in "
+				  "callchain\n", &frame->next_frame);
+	}
 #endif
 	return bp;
 }
@@ -207,7 +208,7 @@ void dump_trace(struct task_struct *task
 			if (in_irq_stack(stack, irq_stack, irq_stack_end)) {
 				if (ops->stack(data, "IRQ") < 0)
 					break;
-				bp = print_context_stack(tinfo, stack, bp,
+				bp = ops->walk_stack(tinfo, stack, bp,
 					ops, data, irq_stack_end, &graph);
 				/*
 				 * We link to the next stack (which would be
@@ -228,7 +229,7 @@ void dump_trace(struct task_struct *task
 	/*
 	 * This handles the process stack:
 	 */
-	bp = print_context_stack(tinfo, stack, bp, ops, data, NULL, &graph);
+	bp = ops->walk_stack(tinfo, stack, bp, ops, data, NULL, &graph);
 	put_cpu();
 }
 EXPORT_SYMBOL(dump_trace);
@@ -291,6 +292,7 @@ void show_registers(struct pt_regs *regs
 
 	sp = regs->sp;
 	printk("CPU %d ", cpu);
+	print_modules();
 	__show_regs(regs, 1);
 	printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
 		cur->comm, cur->pid, task_thread_info(cur), cur);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/dumpstack.h linux-libre-2.6.34-gnu1/arch/x86/kernel/dumpstack.h
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/dumpstack.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/dumpstack.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,8 @@
 #define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :)
 #endif
 
+#include <linux/uaccess.h>
+
 extern void
 show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
 		unsigned long *stack, unsigned long bp, char *log_lvl);
@@ -29,4 +31,26 @@ struct stack_frame {
 	struct stack_frame *next_frame;
 	unsigned long return_address;
 };
+
+struct stack_frame_ia32 {
+    u32 next_frame;
+    u32 return_address;
+};
+
+static inline unsigned long rewind_frame_pointer(int n)
+{
+	struct stack_frame *frame;
+
+	get_bp(frame);
+
+#ifdef CONFIG_FRAME_POINTER
+	while (n--) {
+		if (probe_kernel_address(&frame->next_frame, frame))
+			break;
+	}
 #endif
+
+	return (unsigned long)frame;
+}
+
+#endif /* DUMPSTACK_H */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/e820.c linux-libre-2.6.34-gnu1/arch/x86/kernel/e820.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/e820.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/e820.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,21 +12,13 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/kexec.h>
-#include <linux/module.h>
-#include <linux/mm.h>
 #include <linux/pfn.h>
 #include <linux/suspend.h>
 #include <linux/firmware-map.h>
 
-#include <asm/pgtable.h>
-#include <asm/page.h>
 #include <asm/e820.h>
 #include <asm/proto.h>
 #include <asm/setup.h>
-#include <asm/trampoline.h>
 
 /*
  * The e820 map is the map that gets modified e.g. with command line parameters
@@ -517,31 +509,55 @@ u64 __init e820_remove_range(u64 start,
 			     int checktype)
 {
 	int i;
+	u64 end;
 	u64 real_removed_size = 0;
 
 	if (size > (ULLONG_MAX - start))
 		size = ULLONG_MAX - start;
 
+	end = start + size;
+	printk(KERN_DEBUG "e820 remove range: %016Lx - %016Lx ",
+		       (unsigned long long) start,
+		       (unsigned long long) end);
+	if (checktype)
+		e820_print_type(old_type);
+	printk(KERN_CONT "\n");
+
 	for (i = 0; i < e820.nr_map; i++) {
 		struct e820entry *ei = &e820.map[i];
 		u64 final_start, final_end;
+		u64 ei_end;
 
 		if (checktype && ei->type != old_type)
 			continue;
+
+		ei_end = ei->addr + ei->size;
 		/* totally covered? */
-		if (ei->addr >= start &&
-		    (ei->addr + ei->size) <= (start + size)) {
+		if (ei->addr >= start && ei_end <= end) {
 			real_removed_size += ei->size;
 			memset(ei, 0, sizeof(struct e820entry));
 			continue;
 		}
+
+		/* new range is totally covered? */
+		if (ei->addr < start && ei_end > end) {
+			e820_add_region(end, ei_end - end, ei->type);
+			ei->size = start - ei->addr;
+			real_removed_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;
 		real_removed_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;
@@ -722,319 +738,44 @@ core_initcall(e820_mark_nvs_memory);
 #endif
 
 /*
- * Early reserved memory areas.
- */
-#define MAX_EARLY_RES 32
-
-struct early_res {
-	u64 start, end;
-	char name[16];
-	char overlap_ok;
-};
-static struct early_res early_res[MAX_EARLY_RES] __initdata = {
-	{ 0, PAGE_SIZE, "BIOS data page", 1 },	/* BIOS data page */
-#if defined(CONFIG_X86_32) && defined(CONFIG_X86_TRAMPOLINE)
-	/*
-	 * But first pinch a few for the stack/trampoline stuff
-	 * FIXME: Don't need the extra page at 4K, but need to fix
-	 * trampoline before removing it. (see the GDT stuff)
-	 */
-	{ PAGE_SIZE, PAGE_SIZE + PAGE_SIZE, "EX TRAMPOLINE", 1 },
-#endif
-
-	{}
-};
-
-static int __init find_overlapped_early(u64 start, u64 end)
-{
-	int i;
-	struct early_res *r;
-
-	for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
-		r = &early_res[i];
-		if (end > r->start && start < r->end)
-			break;
-	}
-
-	return i;
-}
-
-/*
- * Drop the i-th range from the early reservation map,
- * by copying any higher ranges down one over it, and
- * clearing what had been the last slot.
- */
-static void __init drop_range(int i)
-{
-	int j;
-
-	for (j = i + 1; j < MAX_EARLY_RES && early_res[j].end; j++)
-		;
-
-	memmove(&early_res[i], &early_res[i + 1],
-	       (j - 1 - i) * sizeof(struct early_res));
-
-	early_res[j - 1].end = 0;
-}
-
-/*
- * Split any existing ranges that:
- *  1) are marked 'overlap_ok', and
- *  2) overlap with the stated range [start, end)
- * into whatever portion (if any) of the existing range is entirely
- * below or entirely above the stated range.  Drop the portion
- * of the existing range that overlaps with the stated range,
- * which will allow the caller of this routine to then add that
- * stated range without conflicting with any existing range.
+ * Find a free area with specified alignment in a specific range.
  */
-static void __init drop_overlaps_that_are_ok(u64 start, u64 end)
+u64 __init find_e820_area(u64 start, u64 end, u64 size, u64 align)
 {
 	int i;
-	struct early_res *r;
-	u64 lower_start, lower_end;
-	u64 upper_start, upper_end;
-	char name[16];
 
-	for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
-		r = &early_res[i];
+	for (i = 0; i < e820.nr_map; i++) {
+		struct e820entry *ei = &e820.map[i];
+		u64 addr;
+		u64 ei_start, ei_last;
 
-		/* Continue past non-overlapping ranges */
-		if (end <= r->start || start >= r->end)
+		if (ei->type != E820_RAM)
 			continue;
 
-		/*
-		 * Leave non-ok overlaps as is; let caller
-		 * panic "Overlapping early reservations"
-		 * when it hits this overlap.
-		 */
-		if (!r->overlap_ok)
-			return;
-
-		/*
-		 * We have an ok overlap.  We will drop it from the early
-		 * reservation map, and add back in any non-overlapping
-		 * portions (lower or upper) as separate, overlap_ok,
-		 * non-overlapping ranges.
-		 */
-
-		/* 1. Note any non-overlapping (lower or upper) ranges. */
-		strncpy(name, r->name, sizeof(name) - 1);
-
-		lower_start = lower_end = 0;
-		upper_start = upper_end = 0;
-		if (r->start < start) {
-		 	lower_start = r->start;
-			lower_end = start;
-		}
-		if (r->end > end) {
-			upper_start = end;
-			upper_end = r->end;
-		}
-
-		/* 2. Drop the original ok overlapping range */
-		drop_range(i);
-
-		i--;		/* resume for-loop on copied down entry */
-
-		/* 3. Add back in any non-overlapping ranges. */
-		if (lower_end)
-			reserve_early_overlap_ok(lower_start, lower_end, name);
-		if (upper_end)
-			reserve_early_overlap_ok(upper_start, upper_end, name);
-	}
-}
-
-static void __init __reserve_early(u64 start, u64 end, char *name,
-						int overlap_ok)
-{
-	int i;
-	struct early_res *r;
-
-	i = find_overlapped_early(start, end);
-	if (i >= MAX_EARLY_RES)
-		panic("Too many early reservations");
-	r = &early_res[i];
-	if (r->end)
-		panic("Overlapping early reservations "
-		      "%llx-%llx %s to %llx-%llx %s\n",
-		      start, end - 1, name?name:"", r->start,
-		      r->end - 1, r->name);
-	r->start = start;
-	r->end = end;
-	r->overlap_ok = overlap_ok;
-	if (name)
-		strncpy(r->name, name, sizeof(r->name) - 1);
-}
-
-/*
- * A few early reservtations come here.
- *
- * The 'overlap_ok' in the name of this routine does -not- mean it
- * is ok for these reservations to overlap an earlier reservation.
- * Rather it means that it is ok for subsequent reservations to
- * overlap this one.
- *
- * Use this entry point to reserve early ranges when you are doing
- * so out of "Paranoia", reserving perhaps more memory than you need,
- * just in case, and don't mind a subsequent overlapping reservation
- * that is known to be needed.
- *
- * The drop_overlaps_that_are_ok() call here isn't really needed.
- * It would be needed if we had two colliding 'overlap_ok'
- * reservations, so that the second such would not panic on the
- * overlap with the first.  We don't have any such as of this
- * writing, but might as well tolerate such if it happens in
- * the future.
- */
-void __init reserve_early_overlap_ok(u64 start, u64 end, char *name)
-{
-	drop_overlaps_that_are_ok(start, end);
-	__reserve_early(start, end, name, 1);
-}
-
-/*
- * Most early reservations come here.
- *
- * We first have drop_overlaps_that_are_ok() drop any pre-existing
- * 'overlap_ok' ranges, so that we can then reserve this memory
- * range without risk of panic'ing on an overlapping overlap_ok
- * early reservation.
- */
-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);
-}
-
-void __init free_early(u64 start, u64 end)
-{
-	struct early_res *r;
-	int i;
-
-	i = find_overlapped_early(start, end);
-	r = &early_res[i];
-	if (i >= MAX_EARLY_RES || r->end != end || r->start != start)
-		panic("free_early on not reserved area: %llx-%llx!",
-			 start, end - 1);
-
-	drop_range(i);
-}
-
-void __init early_res_to_bootmem(u64 start, u64 end)
-{
-	int i, count;
-	u64 final_start, final_end;
-
-	count  = 0;
-	for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++)
-		count++;
-
-	printk(KERN_INFO "(%d early reservations) ==> bootmem [%010llx - %010llx]\n",
-			 count, start, end);
-	for (i = 0; i < count; i++) {
-		struct early_res *r = &early_res[i];
-		printk(KERN_INFO "  #%d [%010llx - %010llx] %16s", i,
-			r->start, r->end, r->name);
-		final_start = max(start, r->start);
-		final_end = min(end, r->end);
-		if (final_start >= final_end) {
-			printk(KERN_CONT "\n");
-			continue;
-		}
-		printk(KERN_CONT " ==> [%010llx - %010llx]\n",
-			final_start, final_end);
-		reserve_bootmem_generic(final_start, final_end - final_start,
-				BOOTMEM_DEFAULT);
-	}
-}
+		ei_last = ei->addr + ei->size;
+		ei_start = ei->addr;
+		addr = find_early_area(ei_start, ei_last, start, end,
+					 size, align);
 
-/* Check for already reserved areas */
-static inline int __init bad_addr(u64 *addrp, u64 size, u64 align)
-{
-	int i;
-	u64 addr = *addrp;
-	int changed = 0;
-	struct early_res *r;
-again:
-	i = find_overlapped_early(addr, addr + size);
-	r = &early_res[i];
-	if (i < MAX_EARLY_RES && r->end) {
-		*addrp = addr = round_up(r->end, align);
-		changed = 1;
-		goto again;
+		if (addr != -1ULL)
+			return addr;
 	}
-	return changed;
+	return -1ULL;
 }
 
-/* Check for already reserved areas */
-static inline int __init bad_addr_size(u64 *addrp, u64 *sizep, u64 align)
+u64 __init find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align)
 {
-	int i;
-	u64 addr = *addrp, last;
-	u64 size = *sizep;
-	int changed = 0;
-again:
-	last = addr + size;
-	for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
-		struct early_res *r = &early_res[i];
-		if (last > r->start && addr < r->start) {
-			size = r->start - addr;
-			changed = 1;
-			goto again;
-		}
-		if (last > r->end && addr < r->end) {
-			addr = round_up(r->end, align);
-			size = last - addr;
-			changed = 1;
-			goto again;
-		}
-		if (last <= r->end && addr >= r->start) {
-			(*sizep)++;
-			return 0;
-		}
-	}
-	if (changed) {
-		*addrp = addr;
-		*sizep = size;
-	}
-	return changed;
+	return find_e820_area(start, end, size, align);
 }
 
-/*
- * Find a free area with specified alignment in a specific range.
- */
-u64 __init find_e820_area(u64 start, u64 end, u64 size, u64 align)
+u64 __init get_max_mapped(void)
 {
-	int i;
+	u64 end = max_pfn_mapped;
 
-	for (i = 0; i < e820.nr_map; i++) {
-		struct e820entry *ei = &e820.map[i];
-		u64 addr, last;
-		u64 ei_last;
+	end <<= PAGE_SHIFT;
 
-		if (ei->type != E820_RAM)
-			continue;
-		addr = round_up(ei->addr, align);
-		ei_last = ei->addr + ei->size;
-		if (addr < start)
-			addr = round_up(start, align);
-		if (addr >= ei_last)
-			continue;
-		while (bad_addr(&addr, size, align) && addr+size <= ei_last)
-			;
-		last = addr + size;
-		if (last > ei_last)
-			continue;
-		if (last > end)
-			continue;
-		return addr;
-	}
-	return -1ULL;
+	return end;
 }
-
 /*
  * Find next free range after *start
  */
@@ -1044,25 +785,19 @@ u64 __init find_e820_area_size(u64 start
 
 	for (i = 0; i < e820.nr_map; i++) {
 		struct e820entry *ei = &e820.map[i];
-		u64 addr, last;
-		u64 ei_last;
+		u64 addr;
+		u64 ei_start, ei_last;
 
 		if (ei->type != E820_RAM)
 			continue;
-		addr = round_up(ei->addr, align);
+
 		ei_last = ei->addr + ei->size;
-		if (addr < start)
-			addr = round_up(start, align);
-		if (addr >= ei_last)
-			continue;
-		*sizep = ei_last - addr;
-		while (bad_addr_size(&addr, sizep, align) &&
-			addr + *sizep <= ei_last)
-			;
-		last = addr + *sizep;
-		if (last > ei_last)
-			continue;
-		return addr;
+		ei_start = ei->addr;
+		addr = find_early_area_size(ei_start, ei_last, start,
+					 sizep, align);
+
+		if (addr != -1ULL)
+			return addr;
 	}
 
 	return -1ULL;
@@ -1421,6 +1156,8 @@ void __init e820_reserve_resources_late(
 			end = MAX_RESOURCE_SIZE;
 		if (start >= end)
 			continue;
+		printk(KERN_DEBUG "reserve RAM buffer: %016llx - %016llx ",
+			       start, end);
 		reserve_region_with_split(&iomem_resource, start, end,
 					  "RAM buffer");
 	}
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/efi.c linux-libre-2.6.34-gnu1/arch/x86/kernel/efi.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/efi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/efi.c	2010-05-16 17:17:36.000000000 -0400
@@ -362,7 +362,7 @@ void __init efi_init(void)
 		printk(KERN_ERR PFX "Could not map the firmware vendor!\n");
 	early_iounmap(tmp, 2);
 
-	printk(KERN_INFO "EFI v%u.%.02u by %s \n",
+	printk(KERN_INFO "EFI v%u.%.02u by %s\n",
 	       efi.systab->hdr.revision >> 16,
 	       efi.systab->hdr.revision & 0xffff, vendor);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/ftrace.c linux-libre-2.6.34-gnu1/arch/x86/kernel/ftrace.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/ftrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/ftrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,14 +30,32 @@
 
 #ifdef CONFIG_DYNAMIC_FTRACE
 
+/*
+ * modifying_code is set to notify NMIs that they need to use
+ * memory barriers when entering or exiting. But we don't want
+ * to burden NMIs with unnecessary memory barriers when code
+ * modification is not being done (which is most of the time).
+ *
+ * A mutex is already held when ftrace_arch_code_modify_prepare
+ * and post_process are called. No locks need to be taken here.
+ *
+ * Stop machine will make sure currently running NMIs are done
+ * and new NMIs will see the updated variable before we need
+ * to worry about NMIs doing memory barriers.
+ */
+static int modifying_code __read_mostly;
+static DEFINE_PER_CPU(int, save_modifying_code);
+
 int ftrace_arch_code_modify_prepare(void)
 {
 	set_kernel_text_rw();
+	modifying_code = 1;
 	return 0;
 }
 
 int ftrace_arch_code_modify_post_process(void)
 {
+	modifying_code = 0;
 	set_kernel_text_ro();
 	return 0;
 }
@@ -149,6 +167,11 @@ static void ftrace_mod_code(void)
 
 void ftrace_nmi_enter(void)
 {
+	__get_cpu_var(save_modifying_code) = modifying_code;
+
+	if (!__get_cpu_var(save_modifying_code))
+		return;
+
 	if (atomic_inc_return(&nmi_running) & MOD_CODE_WRITE_FLAG) {
 		smp_rmb();
 		ftrace_mod_code();
@@ -160,6 +183,9 @@ void ftrace_nmi_enter(void)
 
 void ftrace_nmi_exit(void)
 {
+	if (!__get_cpu_var(save_modifying_code))
+		return;
+
 	/* Finish all executions before clearing nmi_running */
 	smp_mb();
 	atomic_dec(&nmi_running);
@@ -484,13 +510,3 @@ void prepare_ftrace_return(unsigned long
 	}
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
-
-#ifdef CONFIG_FTRACE_SYSCALLS
-
-extern unsigned long *sys_call_table;
-
-unsigned long __init arch_syscall_addr(int nr)
-{
-	return (unsigned long)(&sys_call_table)[nr];
-}
-#endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/head32.c linux-libre-2.6.34-gnu1/arch/x86/kernel/head32.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/head32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/head32.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
 
 #include <linux/init.h>
 #include <linux/start_kernel.h>
+#include <linux/mm.h>
 
 #include <asm/setup.h>
 #include <asm/sections.h>
@@ -29,14 +30,25 @@ static void __init i386_default_early_se
 
 void __init i386_start_kernel(void)
 {
+#ifdef CONFIG_X86_TRAMPOLINE
+	/*
+	 * But first pinch a few for the stack/trampoline stuff
+	 * FIXME: Don't need the extra page at 4K, but need to fix
+	 * trampoline before removing it. (see the GDT stuff)
+	 */
+	reserve_early_overlap_ok(PAGE_SIZE, PAGE_SIZE + PAGE_SIZE,
+					 "EX TRAMPOLINE");
+#endif
+
 	reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* Reserve INITRD */
 	if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
+		/* Assume only end is not page aligned */
 		u64 ramdisk_image = boot_params.hdr.ramdisk_image;
 		u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
-		u64 ramdisk_end   = ramdisk_image + ramdisk_size;
+		u64 ramdisk_end   = PAGE_ALIGN(ramdisk_image + ramdisk_size);
 		reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
 	}
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/head_32.S linux-libre-2.6.34-gnu1/arch/x86/kernel/head_32.S
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/head_32.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/head_32.S	2010-05-16 17:17:36.000000000 -0400
@@ -442,8 +442,8 @@ is386:	movl $2,%ecx		# set MP
 	 */
 	cmpb $0,ready
 	jne 1f
-	movl $per_cpu__gdt_page,%eax
-	movl $per_cpu__stack_canary,%ecx
+	movl $gdt_page,%eax
+	movl $stack_canary,%ecx
 	movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
 	shrl $16, %ecx
 	movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
@@ -706,7 +706,7 @@ idt_descr:
 	.word 0				# 32 bit align gdt_desc.address
 ENTRY(early_gdt_descr)
 	.word GDT_ENTRIES*8-1
-	.long per_cpu__gdt_page		/* Overwritten for secondary CPUs */
+	.long gdt_page			/* Overwritten for secondary CPUs */
 
 /*
  * The boot_gdt must mirror the equivalent in setup.S and is
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/head64.c linux-libre-2.6.34-gnu1/arch/x86/kernel/head64.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/head64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/head64.c	2010-05-16 17:17:36.000000000 -0400
@@ -103,9 +103,10 @@ void __init x86_64_start_reservations(ch
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* Reserve INITRD */
 	if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
+		/* Assume only end is not page aligned */
 		unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
 		unsigned long ramdisk_size  = boot_params.hdr.ramdisk_size;
-		unsigned long ramdisk_end   = ramdisk_image + ramdisk_size;
+		unsigned long ramdisk_end   = PAGE_ALIGN(ramdisk_image + ramdisk_size);
 		reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
 	}
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/head_64.S linux-libre-2.6.34-gnu1/arch/x86/kernel/head_64.S
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/head_64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/head_64.S	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,7 @@
 #define GET_CR2_INTO_RCX movq %cr2, %rcx
 #endif
 
-/* we are not able to switch in one step to the final KERNEL ADRESS SPACE
+/* we are not able to switch in one step to the final KERNEL ADDRESS SPACE
  * because we need identity-mapped pages.
  *
  */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/hpet.c linux-libre-2.6.34-gnu1/arch/x86/kernel/hpet.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/hpet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/hpet.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
 #include <linux/sysdev.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/hpet.h>
 #include <linux/init.h>
 #include <linux/cpu.h>
@@ -266,7 +267,7 @@ static void hpet_resume_device(void)
 	force_hpet_resume();
 }
 
-static void hpet_resume_counter(void)
+static void hpet_resume_counter(struct clocksource *cs)
 {
 	hpet_resume_device();
 	hpet_restart_counter();
@@ -399,9 +400,15 @@ static int hpet_next_event(unsigned long
 	 * then we might have a real hardware problem. We can not do
 	 * much about it here, but at least alert the user/admin with
 	 * a prominent warning.
+	 * An erratum on some chipsets (ICH9,..), results in comparator read
+	 * immediately following a write returning old value. Workaround
+	 * for this is to read this value second time, when first
+	 * read returns old value.
 	 */
-	WARN_ONCE(hpet_readl(HPET_Tn_CMP(timer)) != cnt,
+	if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) {
+		WARN_ONCE(hpet_readl(HPET_Tn_CMP(timer)) != cnt,
 		  KERN_WARNING "hpet: compare register read back failed.\n");
+	}
 
 	return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
 }
@@ -1143,6 +1150,7 @@ int hpet_set_periodic_freq(unsigned long
 		do_div(clc, freq);
 		clc >>= hpet_clockevent.shift;
 		hpet_pie_delta = clc;
+		hpet_pie_limit = 0;
 	}
 	return 1;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/hw_breakpoint.c linux-libre-2.6.34-gnu1/arch/x86/kernel/hw_breakpoint.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/hw_breakpoint.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/hw_breakpoint.c	2010-05-16 17:17:36.000000000 -0400
@@ -344,13 +344,6 @@ int arch_validate_hwbkpt_settings(struct
 	}
 
 	/*
-	 * For kernel-addresses, either the address or symbol name can be
-	 * specified.
-	 */
-	if (info->name)
-		info->address = (unsigned long)
-				kallsyms_lookup_name(info->name);
-	/*
 	 * Check that the low-order bits of the address are appropriate
 	 * for the alignment implied by len.
 	 */
@@ -486,8 +479,6 @@ static int __kprobes hw_breakpoint_handl
 		rcu_read_lock();
 
 		bp = per_cpu(bp_per_reg[i], cpu);
-		if (bp)
-			rc = NOTIFY_DONE;
 		/*
 		 * Reset the 'i'th TRAP bit in dr6 to denote completion of
 		 * exception handling
@@ -506,7 +497,13 @@ static int __kprobes hw_breakpoint_handl
 
 		rcu_read_unlock();
 	}
-	if (dr6 & (~DR_TRAP_BITS))
+	/*
+	 * Further processing in do_debug() is needed for a) user-space
+	 * breakpoints (to generate signals) and b) when the system has
+	 * taken exception due to multiple causes
+	 */
+	if ((current->thread.debugreg6 & DR_TRAP_BITS) ||
+	    (dr6 & (~DR_TRAP_BITS)))
 		rc = NOTIFY_DONE;
 
 	set_debugreg(dr7, 7);
@@ -531,8 +528,3 @@ void hw_breakpoint_pmu_read(struct perf_
 {
 	/* TODO */
 }
-
-void hw_breakpoint_pmu_unthrottle(struct perf_event *bp)
-{
-	/* TODO */
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/i387.c linux-libre-2.6.34-gnu1/arch/x86/kernel/i387.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/i387.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/i387.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 #include <linux/module.h>
 #include <linux/regset.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <asm/sigcontext.h>
 #include <asm/processor.h>
@@ -164,6 +165,11 @@ int init_fpu(struct task_struct *tsk)
 	return 0;
 }
 
+/*
+ * The xstateregs_active() routine is the same as the fpregs_active() routine,
+ * as the "regset->n" for the xstate regset will be updated based on the feature
+ * capabilites supported by the xsave.
+ */
 int fpregs_active(struct task_struct *target, const struct user_regset *regset)
 {
 	return tsk_used_math(target) ? regset->n : 0;
@@ -204,8 +210,6 @@ int xfpregs_set(struct task_struct *targ
 	if (ret)
 		return ret;
 
-	set_stopped_child_used_math(target);
-
 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
 				 &target->thread.xstate->fxsave, 0, -1);
 
@@ -224,6 +228,68 @@ int xfpregs_set(struct task_struct *targ
 	return ret;
 }
 
+int xstateregs_get(struct task_struct *target, const struct user_regset *regset,
+		unsigned int pos, unsigned int count,
+		void *kbuf, void __user *ubuf)
+{
+	int ret;
+
+	if (!cpu_has_xsave)
+		return -ENODEV;
+
+	ret = init_fpu(target);
+	if (ret)
+		return ret;
+
+	/*
+	 * Copy the 48bytes defined by the software first into the xstate
+	 * memory layout in the thread struct, so that we can copy the entire
+	 * xstateregs to the user using one user_regset_copyout().
+	 */
+	memcpy(&target->thread.xstate->fxsave.sw_reserved,
+	       xstate_fx_sw_bytes, sizeof(xstate_fx_sw_bytes));
+
+	/*
+	 * Copy the xstate memory layout.
+	 */
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				  &target->thread.xstate->xsave, 0, -1);
+	return ret;
+}
+
+int xstateregs_set(struct task_struct *target, const struct user_regset *regset,
+		  unsigned int pos, unsigned int count,
+		  const void *kbuf, const void __user *ubuf)
+{
+	int ret;
+	struct xsave_hdr_struct *xsave_hdr;
+
+	if (!cpu_has_xsave)
+		return -ENODEV;
+
+	ret = init_fpu(target);
+	if (ret)
+		return ret;
+
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				 &target->thread.xstate->xsave, 0, -1);
+
+	/*
+	 * mxcsr reserved bits must be masked to zero for security reasons.
+	 */
+	target->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask;
+
+	xsave_hdr = &target->thread.xstate->xsave.xsave_hdr;
+
+	xsave_hdr->xstate_bv &= pcntxt_mask;
+	/*
+	 * These bits must be zero.
+	 */
+	xsave_hdr->reserved1[0] = xsave_hdr->reserved1[1] = 0;
+
+	return ret;
+}
+
 #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
 
 /*
@@ -404,8 +470,6 @@ int fpregs_set(struct task_struct *targe
 	if (ret)
 		return ret;
 
-	set_stopped_child_used_math(target);
-
 	if (!HAVE_HWFP)
 		return fpregs_soft_set(target, regset, pos, count, kbuf, ubuf);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/i8259.c linux-libre-2.6.34-gnu1/arch/x86/kernel/i8259.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/i8259.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/i8259.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,6 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
@@ -32,8 +31,14 @@
  */
 
 static int i8259A_auto_eoi;
-DEFINE_SPINLOCK(i8259A_lock);
+DEFINE_RAW_SPINLOCK(i8259A_lock);
 static void mask_and_ack_8259A(unsigned int);
+static void mask_8259A(void);
+static void unmask_8259A(void);
+static void disable_8259A_irq(unsigned int irq);
+static void enable_8259A_irq(unsigned int irq);
+static void init_8259A(int auto_eoi);
+static int i8259A_irq_pending(unsigned int irq);
 
 struct irq_chip i8259A_chip = {
 	.name		= "XT-PIC",
@@ -63,51 +68,51 @@ unsigned int cached_irq_mask = 0xffff;
  */
 unsigned long io_apic_irqs;
 
-void disable_8259A_irq(unsigned int irq)
+static void disable_8259A_irq(unsigned int irq)
 {
 	unsigned int mask = 1 << irq;
 	unsigned long flags;
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
 	cached_irq_mask |= mask;
 	if (irq & 8)
 		outb(cached_slave_mask, PIC_SLAVE_IMR);
 	else
 		outb(cached_master_mask, PIC_MASTER_IMR);
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
-void enable_8259A_irq(unsigned int irq)
+static void enable_8259A_irq(unsigned int irq)
 {
 	unsigned int mask = ~(1 << irq);
 	unsigned long flags;
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
 	cached_irq_mask &= mask;
 	if (irq & 8)
 		outb(cached_slave_mask, PIC_SLAVE_IMR);
 	else
 		outb(cached_master_mask, PIC_MASTER_IMR);
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
-int i8259A_irq_pending(unsigned int irq)
+static int i8259A_irq_pending(unsigned int irq)
 {
 	unsigned int mask = 1<<irq;
 	unsigned long flags;
 	int ret;
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
 	if (irq < 8)
 		ret = inb(PIC_MASTER_CMD) & mask;
 	else
 		ret = inb(PIC_SLAVE_CMD) & (mask >> 8);
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 
 	return ret;
 }
 
-void make_8259A_irq(unsigned int irq)
+static void make_8259A_irq(unsigned int irq)
 {
 	disable_irq_nosync(irq);
 	io_apic_irqs &= ~(1<<irq);
@@ -150,7 +155,7 @@ static void mask_and_ack_8259A(unsigned
 	unsigned int irqmask = 1 << irq;
 	unsigned long flags;
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
 	/*
 	 * Lightweight spurious IRQ detection. We do not want
 	 * to overdo spurious IRQ handling - it's usually a sign
@@ -183,7 +188,7 @@ handle_real_irq:
 		outb(cached_master_mask, PIC_MASTER_IMR);
 		outb(0x60+irq, PIC_MASTER_CMD);	/* 'Specific EOI to master */
 	}
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 	return;
 
 spurious_8259A_irq:
@@ -281,37 +286,37 @@ static int __init i8259A_init_sysfs(void
 
 device_initcall(i8259A_init_sysfs);
 
-void mask_8259A(void)
+static void mask_8259A(void)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
 
 	outb(0xff, PIC_MASTER_IMR);	/* mask all of 8259A-1 */
 	outb(0xff, PIC_SLAVE_IMR);	/* mask all of 8259A-2 */
 
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
-void unmask_8259A(void)
+static void unmask_8259A(void)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
 
 	outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */
 	outb(cached_slave_mask, PIC_SLAVE_IMR);	  /* restore slave IRQ mask */
 
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
-void init_8259A(int auto_eoi)
+static void init_8259A(int auto_eoi)
 {
 	unsigned long flags;
 
 	i8259A_auto_eoi = auto_eoi;
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
 
 	outb(0xff, PIC_MASTER_IMR);	/* mask all of 8259A-1 */
 	outb(0xff, PIC_SLAVE_IMR);	/* mask all of 8259A-2 */
@@ -356,5 +361,49 @@ void init_8259A(int auto_eoi)
 	outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */
 	outb(cached_slave_mask, PIC_SLAVE_IMR);	  /* restore slave IRQ mask */
 
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
+
+/*
+ * make i8259 a driver so that we can select pic functions at run time. the goal
+ * is to make x86 binary compatible among pc compatible and non-pc compatible
+ * platforms, such as x86 MID.
+ */
+
+static void legacy_pic_noop(void) { };
+static void legacy_pic_uint_noop(unsigned int unused) { };
+static void legacy_pic_int_noop(int unused) { };
+
+static struct irq_chip dummy_pic_chip  = {
+	.name = "dummy pic",
+	.mask = legacy_pic_uint_noop,
+	.unmask = legacy_pic_uint_noop,
+	.disable = legacy_pic_uint_noop,
+	.mask_ack = legacy_pic_uint_noop,
+};
+static int legacy_pic_irq_pending_noop(unsigned int irq)
+{
+	return 0;
+}
+
+struct legacy_pic null_legacy_pic = {
+	.nr_legacy_irqs = 0,
+	.chip = &dummy_pic_chip,
+	.mask_all = legacy_pic_noop,
+	.restore_mask = legacy_pic_noop,
+	.init = legacy_pic_int_noop,
+	.irq_pending = legacy_pic_irq_pending_noop,
+	.make_irq = legacy_pic_uint_noop,
+};
+
+struct legacy_pic default_legacy_pic = {
+	.nr_legacy_irqs = NR_IRQS_LEGACY,
+	.chip  = &i8259A_chip,
+	.mask_all  = mask_8259A,
+	.restore_mask = unmask_8259A,
+	.init = init_8259A,
+	.irq_pending = i8259A_irq_pending,
+	.make_irq = make_8259A_irq,
+};
+
+struct legacy_pic *legacy_pic = &default_legacy_pic;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/irqinit.c linux-libre-2.6.34-gnu1/arch/x86/kernel/irqinit.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/irqinit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/irqinit.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,6 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/kprobes.h>
 #include <linux/init.h>
@@ -84,24 +83,7 @@ static struct irqaction irq2 = {
 };
 
 DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
-	[0 ... IRQ0_VECTOR - 1] = -1,
-	[IRQ0_VECTOR] = 0,
-	[IRQ1_VECTOR] = 1,
-	[IRQ2_VECTOR] = 2,
-	[IRQ3_VECTOR] = 3,
-	[IRQ4_VECTOR] = 4,
-	[IRQ5_VECTOR] = 5,
-	[IRQ6_VECTOR] = 6,
-	[IRQ7_VECTOR] = 7,
-	[IRQ8_VECTOR] = 8,
-	[IRQ9_VECTOR] = 9,
-	[IRQ10_VECTOR] = 10,
-	[IRQ11_VECTOR] = 11,
-	[IRQ12_VECTOR] = 12,
-	[IRQ13_VECTOR] = 13,
-	[IRQ14_VECTOR] = 14,
-	[IRQ15_VECTOR] = 15,
-	[IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
+	[0 ... NR_VECTORS - 1] = -1,
 };
 
 int vector_used_by_percpu_irq(unsigned int vector)
@@ -123,12 +105,12 @@ void __init init_ISA_irqs(void)
 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
 	init_bsp_APIC();
 #endif
-	init_8259A(0);
+	legacy_pic->init(0);
 
 	/*
 	 * 16 old-style INTA-cycle interrupts:
 	 */
-	for (i = 0; i < NR_IRQS_LEGACY; i++) {
+	for (i = 0; i < legacy_pic->nr_legacy_irqs; i++) {
 		struct irq_desc *desc = irq_to_desc(i);
 
 		desc->status = IRQ_DISABLED;
@@ -142,9 +124,44 @@ void __init init_ISA_irqs(void)
 
 void __init init_IRQ(void)
 {
+	int i;
+
+	/*
+	 * On cpu 0, Assign IRQ0_VECTOR..IRQ15_VECTOR's to IRQ 0..15.
+	 * If these IRQ's are handled by legacy interrupt-controllers like PIC,
+	 * then this configuration will likely be static after the boot. If
+	 * these IRQ's are handled by more mordern controllers like IO-APIC,
+	 * then this vector space can be freed and re-used dynamically as the
+	 * irq's migrate etc.
+	 */
+	for (i = 0; i < legacy_pic->nr_legacy_irqs; i++)
+		per_cpu(vector_irq, 0)[IRQ0_VECTOR + i] = i;
+
 	x86_init.irqs.intr_init();
 }
 
+/*
+ * Setup the vector to irq mappings.
+ */
+void setup_vector_irq(int cpu)
+{
+#ifndef CONFIG_X86_IO_APIC
+	int irq;
+
+	/*
+	 * On most of the platforms, legacy PIC delivers the interrupts on the
+	 * boot cpu. But there are certain platforms where PIC interrupts are
+	 * delivered to multiple cpu's. If the legacy IRQ is handled by the
+	 * legacy PIC, for the new cpu that is coming online, setup the static
+	 * legacy vector to irq mapping:
+	 */
+	for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
+		per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
+#endif
+
+	__setup_vector_irq(cpu);
+}
+
 static void __init smp_intr_init(void)
 {
 #ifdef CONFIG_SMP
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/k8.c linux-libre-2.6.34-gnu1/arch/x86/kernel/k8.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/k8.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/k8.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,8 +2,8 @@
  * Shared support code for AMD K8 northbridges and derivates.
  * Copyright 2006 Andi Kleen, SUSE Labs. Subject to GPLv2.
  */
-#include <linux/gfp.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/module.h>
@@ -121,3 +121,17 @@ void k8_flush_garts(void)
 }
 EXPORT_SYMBOL_GPL(k8_flush_garts);
 
+static __init int init_k8_nbs(void)
+{
+	int err = 0;
+
+	err = cache_k8_northbridges();
+
+	if (err < 0)
+		printk(KERN_NOTICE "K8 NB: Cannot enumerate AMD northbridges.\n");
+
+	return err;
+}
+
+/* This has to go after the PCI subsystem */
+fs_initcall(init_k8_nbs);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/kdebugfs.c linux-libre-2.6.34-gnu1/arch/x86/kernel/kdebugfs.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/kdebugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/kdebugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/stat.h>
 #include <linux/io.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/kgdb.c linux-libre-2.6.34-gnu1/arch/x86/kernel/kgdb.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/kgdb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/kgdb.c	2010-05-16 17:17:36.000000000 -0400
@@ -618,8 +618,8 @@ int kgdb_arch_init(void)
 	 * portion of kgdb because this operation requires mutexs to
 	 * complete.
 	 */
+	hw_breakpoint_init(&attr);
 	attr.bp_addr = (unsigned long)kgdb_arch_init;
-	attr.type = PERF_TYPE_BREAKPOINT;
 	attr.bp_len = HW_BREAKPOINT_LEN_1;
 	attr.bp_type = HW_BREAKPOINT_W;
 	attr.disabled = 1;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/kprobes.c linux-libre-2.6.34-gnu1/arch/x86/kernel/kprobes.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/kprobes.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/kprobes.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,7 @@
 #include <linux/module.h>
 #include <linux/kdebug.h>
 #include <linux/kallsyms.h>
+#include <linux/ftrace.h>
 
 #include <asm/cacheflush.h>
 #include <asm/desc.h>
@@ -106,16 +107,22 @@ struct kretprobe_blackpoint kretprobe_bl
 };
 const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
 
-/* Insert a jump instruction at address 'from', which jumps to address 'to'.*/
-static void __kprobes set_jmp_op(void *from, void *to)
+static void __kprobes __synthesize_relative_insn(void *from, void *to, u8 op)
 {
-	struct __arch_jmp_op {
-		char op;
+	struct __arch_relative_insn {
+		u8 op;
 		s32 raddr;
-	} __attribute__((packed)) * jop;
-	jop = (struct __arch_jmp_op *)from;
-	jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
-	jop->op = RELATIVEJUMP_INSTRUCTION;
+	} __attribute__((packed)) *insn;
+
+	insn = (struct __arch_relative_insn *)from;
+	insn->raddr = (s32)((long)(to) - ((long)(from) + 5));
+	insn->op = op;
+}
+
+/* Insert a jump instruction at address 'from', which jumps to address 'to'.*/
+static void __kprobes synthesize_reljump(void *from, void *to)
+{
+	__synthesize_relative_insn(from, to, RELATIVEJUMP_OPCODE);
 }
 
 /*
@@ -202,7 +209,7 @@ static int recover_probed_instruction(kp
 	/*
 	 *  Basically, kp->ainsn.insn has an original instruction.
 	 *  However, RIP-relative instruction can not do single-stepping
-	 *  at different place, fix_riprel() tweaks the displacement of
+	 *  at different place, __copy_instruction() tweaks the displacement of
 	 *  that instruction. In that case, we can't recover the instruction
 	 *  from the kp->ainsn.insn.
 	 *
@@ -284,21 +291,37 @@ static int __kprobes is_IF_modifier(kpro
 }
 
 /*
- * Adjust the displacement if the instruction uses the %rip-relative
- * addressing mode.
+ * Copy an instruction and adjust the displacement if the instruction
+ * uses the %rip-relative addressing mode.
  * If it does, Return the address of the 32-bit displacement word.
  * If not, return null.
  * Only applicable to 64-bit x86.
  */
-static void __kprobes fix_riprel(struct kprobe *p)
+static int __kprobes __copy_instruction(u8 *dest, u8 *src, int recover)
 {
-#ifdef CONFIG_X86_64
 	struct insn insn;
-	kernel_insn_init(&insn, p->ainsn.insn);
+	int ret;
+	kprobe_opcode_t buf[MAX_INSN_SIZE];
 
+	kernel_insn_init(&insn, src);
+	if (recover) {
+		insn_get_opcode(&insn);
+		if (insn.opcode.bytes[0] == BREAKPOINT_INSTRUCTION) {
+			ret = recover_probed_instruction(buf,
+							 (unsigned long)src);
+			if (ret)
+				return 0;
+			kernel_insn_init(&insn, buf);
+		}
+	}
+	insn_get_length(&insn);
+	memcpy(dest, insn.kaddr, insn.length);
+
+#ifdef CONFIG_X86_64
 	if (insn_rip_relative(&insn)) {
 		s64 newdisp;
 		u8 *disp;
+		kernel_insn_init(&insn, dest);
 		insn_get_displacement(&insn);
 		/*
 		 * The copied instruction uses the %rip-relative addressing
@@ -312,20 +335,23 @@ static void __kprobes fix_riprel(struct
 		 * extension of the original signed 32-bit displacement would
 		 * have given.
 		 */
-		newdisp = (u8 *) p->addr + (s64) insn.displacement.value -
-			  (u8 *) p->ainsn.insn;
+		newdisp = (u8 *) src + (s64) insn.displacement.value -
+			  (u8 *) dest;
 		BUG_ON((s64) (s32) newdisp != newdisp); /* Sanity check.  */
-		disp = (u8 *) p->ainsn.insn + insn_offset_displacement(&insn);
+		disp = (u8 *) dest + insn_offset_displacement(&insn);
 		*(s32 *) disp = (s32) newdisp;
 	}
 #endif
+	return insn.length;
 }
 
 static void __kprobes arch_copy_kprobe(struct kprobe *p)
 {
-	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
-
-	fix_riprel(p);
+	/*
+	 * Copy an instruction without recovering int3, because it will be
+	 * put by another subsystem.
+	 */
+	__copy_instruction(p->ainsn.insn, p->addr, 0);
 
 	if (can_boost(p->addr))
 		p->ainsn.boostable = 0;
@@ -337,6 +363,9 @@ static void __kprobes arch_copy_kprobe(s
 
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
+	if (alternatives_text_reserved(p->addr, p->addr))
+		return -EINVAL;
+
 	if (!can_probe((unsigned long)p->addr))
 		return -EILSEQ;
 	/* insn: must be on special executable page on x86. */
@@ -403,18 +432,6 @@ static void __kprobes restore_btf(void)
 		update_debugctlmsr(current->thread.debugctlmsr);
 }
 
-static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
-{
-	clear_btf();
-	regs->flags |= X86_EFLAGS_TF;
-	regs->flags &= ~X86_EFLAGS_IF;
-	/* single step inline if the instruction is an int3 */
-	if (p->opcode == BREAKPOINT_INSTRUCTION)
-		regs->ip = (unsigned long)p->addr;
-	else
-		regs->ip = (unsigned long)p->ainsn.insn;
-}
-
 void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
 				      struct pt_regs *regs)
 {
@@ -426,20 +443,50 @@ void __kprobes arch_prepare_kretprobe(st
 	*sara = (unsigned long) &kretprobe_trampoline;
 }
 
+#ifdef CONFIG_OPTPROBES
+static int  __kprobes setup_detour_execution(struct kprobe *p,
+					     struct pt_regs *regs,
+					     int reenter);
+#else
+#define setup_detour_execution(p, regs, reenter) (0)
+#endif
+
 static void __kprobes setup_singlestep(struct kprobe *p, struct pt_regs *regs,
-				       struct kprobe_ctlblk *kcb)
+				       struct kprobe_ctlblk *kcb, int reenter)
 {
-#if !defined(CONFIG_PREEMPT) || defined(CONFIG_FREEZER)
+	if (setup_detour_execution(p, regs, reenter))
+		return;
+
+#if !defined(CONFIG_PREEMPT)
 	if (p->ainsn.boostable == 1 && !p->post_handler) {
 		/* Boost up -- we can execute copied instructions directly */
-		reset_current_kprobe();
+		if (!reenter)
+			reset_current_kprobe();
+		/*
+		 * Reentering boosted probe doesn't reset current_kprobe,
+		 * nor set current_kprobe, because it doesn't use single
+		 * stepping.
+		 */
 		regs->ip = (unsigned long)p->ainsn.insn;
 		preempt_enable_no_resched();
 		return;
 	}
 #endif
-	prepare_singlestep(p, regs);
-	kcb->kprobe_status = KPROBE_HIT_SS;
+	if (reenter) {
+		save_previous_kprobe(kcb);
+		set_current_kprobe(p, regs, kcb);
+		kcb->kprobe_status = KPROBE_REENTER;
+	} else
+		kcb->kprobe_status = KPROBE_HIT_SS;
+	/* Prepare real single stepping */
+	clear_btf();
+	regs->flags |= X86_EFLAGS_TF;
+	regs->flags &= ~X86_EFLAGS_IF;
+	/* single step inline if the instruction is an int3 */
+	if (p->opcode == BREAKPOINT_INSTRUCTION)
+		regs->ip = (unsigned long)p->addr;
+	else
+		regs->ip = (unsigned long)p->ainsn.insn;
 }
 
 /*
@@ -453,11 +500,8 @@ static int __kprobes reenter_kprobe(stru
 	switch (kcb->kprobe_status) {
 	case KPROBE_HIT_SSDONE:
 	case KPROBE_HIT_ACTIVE:
-		save_previous_kprobe(kcb);
-		set_current_kprobe(p, regs, kcb);
 		kprobes_inc_nmissed_count(p);
-		prepare_singlestep(p, regs);
-		kcb->kprobe_status = KPROBE_REENTER;
+		setup_singlestep(p, regs, kcb, 1);
 		break;
 	case KPROBE_HIT_SS:
 		/* A probe has been hit in the codepath leading up to, or just
@@ -490,20 +534,6 @@ static int __kprobes kprobe_handler(stru
 	struct kprobe_ctlblk *kcb;
 
 	addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
-	if (*addr != BREAKPOINT_INSTRUCTION) {
-		/*
-		 * The breakpoint instruction was removed right
-		 * after we hit it.  Another cpu has removed
-		 * either a probepoint or a debugger breakpoint
-		 * at this address.  In either case, no further
-		 * handling of this interrupt is appropriate.
-		 * Back up over the (now missing) int3 and run
-		 * the original instruction.
-		 */
-		regs->ip = (unsigned long)addr;
-		return 1;
-	}
-
 	/*
 	 * We don't want to be preempted for the entire
 	 * duration of kprobe processing. We conditionally
@@ -532,13 +562,26 @@ static int __kprobes kprobe_handler(stru
 			 * more here.
 			 */
 			if (!p->pre_handler || !p->pre_handler(p, regs))
-				setup_singlestep(p, regs, kcb);
+				setup_singlestep(p, regs, kcb, 0);
 			return 1;
 		}
+	} else if (*addr != BREAKPOINT_INSTRUCTION) {
+		/*
+		 * The breakpoint instruction was removed right
+		 * after we hit it.  Another cpu has removed
+		 * either a probepoint or a debugger breakpoint
+		 * at this address.  In either case, no further
+		 * handling of this interrupt is appropriate.
+		 * Back up over the (now missing) int3 and run
+		 * the original instruction.
+		 */
+		regs->ip = (unsigned long)addr;
+		preempt_enable_no_resched();
+		return 1;
 	} else if (kprobe_running()) {
 		p = __get_cpu_var(current_kprobe);
 		if (p->break_handler && p->break_handler(p, regs)) {
-			setup_singlestep(p, regs, kcb);
+			setup_singlestep(p, regs, kcb, 0);
 			return 1;
 		}
 	} /* else: not a kprobe fault; let the kernel handle it */
@@ -547,6 +590,69 @@ static int __kprobes kprobe_handler(stru
 	return 0;
 }
 
+#ifdef CONFIG_X86_64
+#define SAVE_REGS_STRING		\
+	/* Skip cs, ip, orig_ax. */	\
+	"	subq $24, %rsp\n"	\
+	"	pushq %rdi\n"		\
+	"	pushq %rsi\n"		\
+	"	pushq %rdx\n"		\
+	"	pushq %rcx\n"		\
+	"	pushq %rax\n"		\
+	"	pushq %r8\n"		\
+	"	pushq %r9\n"		\
+	"	pushq %r10\n"		\
+	"	pushq %r11\n"		\
+	"	pushq %rbx\n"		\
+	"	pushq %rbp\n"		\
+	"	pushq %r12\n"		\
+	"	pushq %r13\n"		\
+	"	pushq %r14\n"		\
+	"	pushq %r15\n"
+#define RESTORE_REGS_STRING		\
+	"	popq %r15\n"		\
+	"	popq %r14\n"		\
+	"	popq %r13\n"		\
+	"	popq %r12\n"		\
+	"	popq %rbp\n"		\
+	"	popq %rbx\n"		\
+	"	popq %r11\n"		\
+	"	popq %r10\n"		\
+	"	popq %r9\n"		\
+	"	popq %r8\n"		\
+	"	popq %rax\n"		\
+	"	popq %rcx\n"		\
+	"	popq %rdx\n"		\
+	"	popq %rsi\n"		\
+	"	popq %rdi\n"		\
+	/* Skip orig_ax, ip, cs */	\
+	"	addq $24, %rsp\n"
+#else
+#define SAVE_REGS_STRING		\
+	/* Skip cs, ip, orig_ax and gs. */	\
+	"	subl $16, %esp\n"	\
+	"	pushl %fs\n"		\
+	"	pushl %ds\n"		\
+	"	pushl %es\n"		\
+	"	pushl %eax\n"		\
+	"	pushl %ebp\n"		\
+	"	pushl %edi\n"		\
+	"	pushl %esi\n"		\
+	"	pushl %edx\n"		\
+	"	pushl %ecx\n"		\
+	"	pushl %ebx\n"
+#define RESTORE_REGS_STRING		\
+	"	popl %ebx\n"		\
+	"	popl %ecx\n"		\
+	"	popl %edx\n"		\
+	"	popl %esi\n"		\
+	"	popl %edi\n"		\
+	"	popl %ebp\n"		\
+	"	popl %eax\n"		\
+	/* Skip ds, es, fs, gs, orig_ax, and ip. Note: don't pop cs here*/\
+	"	addl $24, %esp\n"
+#endif
+
 /*
  * When a retprobed function returns, this code saves registers and
  * calls trampoline_handler() runs, which calls the kretprobe's handler.
@@ -560,65 +666,16 @@ static void __used __kprobes kretprobe_t
 			/* We don't bother saving the ss register */
 			"	pushq %rsp\n"
 			"	pushfq\n"
-			/*
-			 * Skip cs, ip, orig_ax.
-			 * trampoline_handler() will plug in these values
-			 */
-			"	subq $24, %rsp\n"
-			"	pushq %rdi\n"
-			"	pushq %rsi\n"
-			"	pushq %rdx\n"
-			"	pushq %rcx\n"
-			"	pushq %rax\n"
-			"	pushq %r8\n"
-			"	pushq %r9\n"
-			"	pushq %r10\n"
-			"	pushq %r11\n"
-			"	pushq %rbx\n"
-			"	pushq %rbp\n"
-			"	pushq %r12\n"
-			"	pushq %r13\n"
-			"	pushq %r14\n"
-			"	pushq %r15\n"
+			SAVE_REGS_STRING
 			"	movq %rsp, %rdi\n"
 			"	call trampoline_handler\n"
 			/* Replace saved sp with true return address. */
 			"	movq %rax, 152(%rsp)\n"
-			"	popq %r15\n"
-			"	popq %r14\n"
-			"	popq %r13\n"
-			"	popq %r12\n"
-			"	popq %rbp\n"
-			"	popq %rbx\n"
-			"	popq %r11\n"
-			"	popq %r10\n"
-			"	popq %r9\n"
-			"	popq %r8\n"
-			"	popq %rax\n"
-			"	popq %rcx\n"
-			"	popq %rdx\n"
-			"	popq %rsi\n"
-			"	popq %rdi\n"
-			/* Skip orig_ax, ip, cs */
-			"	addq $24, %rsp\n"
+			RESTORE_REGS_STRING
 			"	popfq\n"
 #else
 			"	pushf\n"
-			/*
-			 * Skip cs, ip, orig_ax and gs.
-			 * trampoline_handler() will plug in these values
-			 */
-			"	subl $16, %esp\n"
-			"	pushl %fs\n"
-			"	pushl %es\n"
-			"	pushl %ds\n"
-			"	pushl %eax\n"
-			"	pushl %ebp\n"
-			"	pushl %edi\n"
-			"	pushl %esi\n"
-			"	pushl %edx\n"
-			"	pushl %ecx\n"
-			"	pushl %ebx\n"
+			SAVE_REGS_STRING
 			"	movl %esp, %eax\n"
 			"	call trampoline_handler\n"
 			/* Move flags to cs */
@@ -626,15 +683,7 @@ static void __used __kprobes kretprobe_t
 			"	movl %edx, 52(%esp)\n"
 			/* Replace saved flags with true return address. */
 			"	movl %eax, 56(%esp)\n"
-			"	popl %ebx\n"
-			"	popl %ecx\n"
-			"	popl %edx\n"
-			"	popl %esi\n"
-			"	popl %edi\n"
-			"	popl %ebp\n"
-			"	popl %eax\n"
-			/* Skip ds, es, fs, gs, orig_ax and ip */
-			"	addl $24, %esp\n"
+			RESTORE_REGS_STRING
 			"	popf\n"
 #endif
 			"	ret\n");
@@ -802,8 +851,8 @@ static void __kprobes resume_execution(s
 			 * These instructions can be executed directly if it
 			 * jumps back to correct address.
 			 */
-			set_jmp_op((void *)regs->ip,
-				   (void *)orig_ip + (regs->ip - copy_ip));
+			synthesize_reljump((void *)regs->ip,
+				(void *)orig_ip + (regs->ip - copy_ip));
 			p->ainsn.boostable = 1;
 		} else {
 			p->ainsn.boostable = -1;
@@ -1030,6 +1079,358 @@ int __kprobes longjmp_break_handler(stru
 	return 0;
 }
 
+
+#ifdef CONFIG_OPTPROBES
+
+/* Insert a call instruction at address 'from', which calls address 'to'.*/
+static void __kprobes synthesize_relcall(void *from, void *to)
+{
+	__synthesize_relative_insn(from, to, RELATIVECALL_OPCODE);
+}
+
+/* Insert a move instruction which sets a pointer to eax/rdi (1st arg). */
+static void __kprobes synthesize_set_arg1(kprobe_opcode_t *addr,
+					  unsigned long val)
+{
+#ifdef CONFIG_X86_64
+	*addr++ = 0x48;
+	*addr++ = 0xbf;
+#else
+	*addr++ = 0xb8;
+#endif
+	*(unsigned long *)addr = val;
+}
+
+void __kprobes kprobes_optinsn_template_holder(void)
+{
+	asm volatile (
+			".global optprobe_template_entry\n"
+			"optprobe_template_entry: \n"
+#ifdef CONFIG_X86_64
+			/* We don't bother saving the ss register */
+			"	pushq %rsp\n"
+			"	pushfq\n"
+			SAVE_REGS_STRING
+			"	movq %rsp, %rsi\n"
+			".global optprobe_template_val\n"
+			"optprobe_template_val: \n"
+			ASM_NOP5
+			ASM_NOP5
+			".global optprobe_template_call\n"
+			"optprobe_template_call: \n"
+			ASM_NOP5
+			/* Move flags to rsp */
+			"	movq 144(%rsp), %rdx\n"
+			"	movq %rdx, 152(%rsp)\n"
+			RESTORE_REGS_STRING
+			/* Skip flags entry */
+			"	addq $8, %rsp\n"
+			"	popfq\n"
+#else /* CONFIG_X86_32 */
+			"	pushf\n"
+			SAVE_REGS_STRING
+			"	movl %esp, %edx\n"
+			".global optprobe_template_val\n"
+			"optprobe_template_val: \n"
+			ASM_NOP5
+			".global optprobe_template_call\n"
+			"optprobe_template_call: \n"
+			ASM_NOP5
+			RESTORE_REGS_STRING
+			"	addl $4, %esp\n"	/* skip cs */
+			"	popf\n"
+#endif
+			".global optprobe_template_end\n"
+			"optprobe_template_end: \n");
+}
+
+#define TMPL_MOVE_IDX \
+	((long)&optprobe_template_val - (long)&optprobe_template_entry)
+#define TMPL_CALL_IDX \
+	((long)&optprobe_template_call - (long)&optprobe_template_entry)
+#define TMPL_END_IDX \
+	((long)&optprobe_template_end - (long)&optprobe_template_entry)
+
+#define INT3_SIZE sizeof(kprobe_opcode_t)
+
+/* Optimized kprobe call back function: called from optinsn */
+static void __kprobes optimized_callback(struct optimized_kprobe *op,
+					 struct pt_regs *regs)
+{
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	preempt_disable();
+	if (kprobe_running()) {
+		kprobes_inc_nmissed_count(&op->kp);
+	} else {
+		/* Save skipped registers */
+#ifdef CONFIG_X86_64
+		regs->cs = __KERNEL_CS;
+#else
+		regs->cs = __KERNEL_CS | get_kernel_rpl();
+		regs->gs = 0;
+#endif
+		regs->ip = (unsigned long)op->kp.addr + INT3_SIZE;
+		regs->orig_ax = ~0UL;
+
+		__get_cpu_var(current_kprobe) = &op->kp;
+		kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+		opt_pre_handler(&op->kp, regs);
+		__get_cpu_var(current_kprobe) = NULL;
+	}
+	preempt_enable_no_resched();
+}
+
+static int __kprobes copy_optimized_instructions(u8 *dest, u8 *src)
+{
+	int len = 0, ret;
+
+	while (len < RELATIVEJUMP_SIZE) {
+		ret = __copy_instruction(dest + len, src + len, 1);
+		if (!ret || !can_boost(dest + len))
+			return -EINVAL;
+		len += ret;
+	}
+	/* Check whether the address range is reserved */
+	if (ftrace_text_reserved(src, src + len - 1) ||
+	    alternatives_text_reserved(src, src + len - 1))
+		return -EBUSY;
+
+	return len;
+}
+
+/* Check whether insn is indirect jump */
+static int __kprobes insn_is_indirect_jump(struct insn *insn)
+{
+	return ((insn->opcode.bytes[0] == 0xff &&
+		(X86_MODRM_REG(insn->modrm.value) & 6) == 4) || /* Jump */
+		insn->opcode.bytes[0] == 0xea);	/* Segment based jump */
+}
+
+/* Check whether insn jumps into specified address range */
+static int insn_jump_into_range(struct insn *insn, unsigned long start, int len)
+{
+	unsigned long target = 0;
+
+	switch (insn->opcode.bytes[0]) {
+	case 0xe0:	/* loopne */
+	case 0xe1:	/* loope */
+	case 0xe2:	/* loop */
+	case 0xe3:	/* jcxz */
+	case 0xe9:	/* near relative jump */
+	case 0xeb:	/* short relative jump */
+		break;
+	case 0x0f:
+		if ((insn->opcode.bytes[1] & 0xf0) == 0x80) /* jcc near */
+			break;
+		return 0;
+	default:
+		if ((insn->opcode.bytes[0] & 0xf0) == 0x70) /* jcc short */
+			break;
+		return 0;
+	}
+	target = (unsigned long)insn->next_byte + insn->immediate.value;
+
+	return (start <= target && target <= start + len);
+}
+
+/* Decode whole function to ensure any instructions don't jump into target */
+static int __kprobes can_optimize(unsigned long paddr)
+{
+	int ret;
+	unsigned long addr, size = 0, offset = 0;
+	struct insn insn;
+	kprobe_opcode_t buf[MAX_INSN_SIZE];
+	/* Dummy buffers for lookup_symbol_attrs */
+	static char __dummy_buf[KSYM_NAME_LEN];
+
+	/* Lookup symbol including addr */
+	if (!kallsyms_lookup(paddr, &size, &offset, NULL, __dummy_buf))
+		return 0;
+
+	/* Check there is enough space for a relative jump. */
+	if (size - offset < RELATIVEJUMP_SIZE)
+		return 0;
+
+	/* Decode instructions */
+	addr = paddr - offset;
+	while (addr < paddr - offset + size) { /* Decode until function end */
+		if (search_exception_tables(addr))
+			/*
+			 * Since some fixup code will jumps into this function,
+			 * we can't optimize kprobe in this function.
+			 */
+			return 0;
+		kernel_insn_init(&insn, (void *)addr);
+		insn_get_opcode(&insn);
+		if (insn.opcode.bytes[0] == BREAKPOINT_INSTRUCTION) {
+			ret = recover_probed_instruction(buf, addr);
+			if (ret)
+				return 0;
+			kernel_insn_init(&insn, buf);
+		}
+		insn_get_length(&insn);
+		/* Recover address */
+		insn.kaddr = (void *)addr;
+		insn.next_byte = (void *)(addr + insn.length);
+		/* Check any instructions don't jump into target */
+		if (insn_is_indirect_jump(&insn) ||
+		    insn_jump_into_range(&insn, paddr + INT3_SIZE,
+					 RELATIVE_ADDR_SIZE))
+			return 0;
+		addr += insn.length;
+	}
+
+	return 1;
+}
+
+/* Check optimized_kprobe can actually be optimized. */
+int __kprobes arch_check_optimized_kprobe(struct optimized_kprobe *op)
+{
+	int i;
+	struct kprobe *p;
+
+	for (i = 1; i < op->optinsn.size; i++) {
+		p = get_kprobe(op->kp.addr + i);
+		if (p && !kprobe_disabled(p))
+			return -EEXIST;
+	}
+
+	return 0;
+}
+
+/* Check the addr is within the optimized instructions. */
+int __kprobes arch_within_optimized_kprobe(struct optimized_kprobe *op,
+					   unsigned long addr)
+{
+	return ((unsigned long)op->kp.addr <= addr &&
+		(unsigned long)op->kp.addr + op->optinsn.size > addr);
+}
+
+/* Free optimized instruction slot */
+static __kprobes
+void __arch_remove_optimized_kprobe(struct optimized_kprobe *op, int dirty)
+{
+	if (op->optinsn.insn) {
+		free_optinsn_slot(op->optinsn.insn, dirty);
+		op->optinsn.insn = NULL;
+		op->optinsn.size = 0;
+	}
+}
+
+void __kprobes arch_remove_optimized_kprobe(struct optimized_kprobe *op)
+{
+	__arch_remove_optimized_kprobe(op, 1);
+}
+
+/*
+ * Copy replacing target instructions
+ * Target instructions MUST be relocatable (checked inside)
+ */
+int __kprobes arch_prepare_optimized_kprobe(struct optimized_kprobe *op)
+{
+	u8 *buf;
+	int ret;
+	long rel;
+
+	if (!can_optimize((unsigned long)op->kp.addr))
+		return -EILSEQ;
+
+	op->optinsn.insn = get_optinsn_slot();
+	if (!op->optinsn.insn)
+		return -ENOMEM;
+
+	/*
+	 * Verify if the address gap is in 2GB range, because this uses
+	 * a relative jump.
+	 */
+	rel = (long)op->optinsn.insn - (long)op->kp.addr + RELATIVEJUMP_SIZE;
+	if (abs(rel) > 0x7fffffff)
+		return -ERANGE;
+
+	buf = (u8 *)op->optinsn.insn;
+
+	/* Copy instructions into the out-of-line buffer */
+	ret = copy_optimized_instructions(buf + TMPL_END_IDX, op->kp.addr);
+	if (ret < 0) {
+		__arch_remove_optimized_kprobe(op, 0);
+		return ret;
+	}
+	op->optinsn.size = ret;
+
+	/* Copy arch-dep-instance from template */
+	memcpy(buf, &optprobe_template_entry, TMPL_END_IDX);
+
+	/* Set probe information */
+	synthesize_set_arg1(buf + TMPL_MOVE_IDX, (unsigned long)op);
+
+	/* Set probe function call */
+	synthesize_relcall(buf + TMPL_CALL_IDX, optimized_callback);
+
+	/* Set returning jmp instruction at the tail of out-of-line buffer */
+	synthesize_reljump(buf + TMPL_END_IDX + op->optinsn.size,
+			   (u8 *)op->kp.addr + op->optinsn.size);
+
+	flush_icache_range((unsigned long) buf,
+			   (unsigned long) buf + TMPL_END_IDX +
+			   op->optinsn.size + RELATIVEJUMP_SIZE);
+	return 0;
+}
+
+/* Replace a breakpoint (int3) with a relative jump.  */
+int __kprobes arch_optimize_kprobe(struct optimized_kprobe *op)
+{
+	unsigned char jmp_code[RELATIVEJUMP_SIZE];
+	s32 rel = (s32)((long)op->optinsn.insn -
+			((long)op->kp.addr + RELATIVEJUMP_SIZE));
+
+	/* Backup instructions which will be replaced by jump address */
+	memcpy(op->optinsn.copied_insn, op->kp.addr + INT3_SIZE,
+	       RELATIVE_ADDR_SIZE);
+
+	jmp_code[0] = RELATIVEJUMP_OPCODE;
+	*(s32 *)(&jmp_code[1]) = rel;
+
+	/*
+	 * text_poke_smp doesn't support NMI/MCE code modifying.
+	 * However, since kprobes itself also doesn't support NMI/MCE
+	 * code probing, it's not a problem.
+	 */
+	text_poke_smp(op->kp.addr, jmp_code, RELATIVEJUMP_SIZE);
+	return 0;
+}
+
+/* Replace a relative jump with a breakpoint (int3).  */
+void __kprobes arch_unoptimize_kprobe(struct optimized_kprobe *op)
+{
+	u8 buf[RELATIVEJUMP_SIZE];
+
+	/* Set int3 to first byte for kprobes */
+	buf[0] = BREAKPOINT_INSTRUCTION;
+	memcpy(buf + 1, op->optinsn.copied_insn, RELATIVE_ADDR_SIZE);
+	text_poke_smp(op->kp.addr, buf, RELATIVEJUMP_SIZE);
+}
+
+static int  __kprobes setup_detour_execution(struct kprobe *p,
+					     struct pt_regs *regs,
+					     int reenter)
+{
+	struct optimized_kprobe *op;
+
+	if (p->flags & KPROBE_FLAG_OPTIMIZED) {
+		/* This kprobe is really able to run optimized path. */
+		op = container_of(p, struct optimized_kprobe, kp);
+		/* Detour through copied instructions */
+		regs->ip = (unsigned long)op->optinsn.insn + TMPL_END_IDX;
+		if (!reenter)
+			reset_current_kprobe();
+		preempt_enable_no_resched();
+		return 1;
+	}
+	return 0;
+}
+#endif
+
 int __init arch_init_kprobes(void)
 {
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/ldt.c linux-libre-2.6.34-gnu1/arch/x86/kernel/ldt.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/ldt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/ldt.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/mm.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/machine_kexec_64.c linux-libre-2.6.34-gnu1/arch/x86/kernel/machine_kexec_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/machine_kexec_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/machine_kexec_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/mm.h>
 #include <linux/kexec.h>
 #include <linux/string.h>
+#include <linux/gfp.h>
 #include <linux/reboot.h>
 #include <linux/numa.h>
 #include <linux/ftrace.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/Makefile linux-libre-2.6.34-gnu1/arch/x86/kernel/Makefile
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -87,6 +87,7 @@ obj-$(CONFIG_VM86)		+= vm86_32.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 
 obj-$(CONFIG_HPET_TIMER) 	+= hpet.o
+obj-$(CONFIG_APB_TIMER)		+= apb_timer.o
 
 obj-$(CONFIG_K8_NB)		+= k8.o
 obj-$(CONFIG_DEBUG_RODATA_TEST)	+= test_rodata.o
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/mca_32.c linux-libre-2.6.34-gnu1/arch/x86/kernel/mca_32.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/mca_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/mca_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/kernel.h>
 #include <linux/mca.h>
 #include <linux/kprobes.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <linux/proc_fs.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/microcode_intel.c linux-libre-2.6.34-gnu1/arch/x86/kernel/microcode_intel.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/microcode_intel.c	2013-05-03 12:02:43.000000000 -0400
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/microcode_intel.c	2013-05-03 09:43:46.000000000 -0400
@@ -328,7 +328,7 @@ static int apply_microcode(int cpu)
 		       cpu_num, mc_intel->hdr.rev);
 		return -1;
 	}
-	pr_info("CPU%d updated to revision 0x%x, date = %04x-%02x-%02x \n",
+	pr_info("CPU%d updated to revision 0x%x, date = %04x-%02x-%02x\n",
 		cpu_num, val[1],
 		mc_intel->hdr.date & 0xffff,
 		mc_intel->hdr.date >> 24,
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/mmconf-fam10h_64.c linux-libre-2.6.34-gnu1/arch/x86/kernel/mmconf-fam10h_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/mmconf-fam10h_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/mmconf-fam10h_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,8 @@
 #include <linux/string.h>
 #include <linux/pci.h>
 #include <linux/dmi.h>
+#include <linux/range.h>
+
 #include <asm/pci-direct.h>
 #include <linux/sort.h>
 #include <asm/io.h>
@@ -30,11 +32,6 @@ static struct pci_hostbridge_probe pci_p
 	{ 0xff, 0, PCI_VENDOR_ID_AMD, 0x1200 },
 };
 
-struct range {
-	u64 start;
-	u64 end;
-};
-
 static int __cpuinit cmp_range(const void *x1, const void *x2)
 {
 	const struct range *r1 = x1;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/module.c linux-libre-2.6.34-gnu1/arch/x86/kernel/module.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/module.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/module.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/bug.h>
 #include <linux/mm.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/page.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/mpparse.c linux-libre-2.6.34-gnu1/arch/x86/kernel/mpparse.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/mpparse.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/mpparse.c	2010-05-16 17:17:36.000000000 -0400
@@ -664,7 +664,7 @@ static void __init smp_reserve_memory(st
 {
 	unsigned long size = get_mpc_size(mpf->physptr);
 
-	reserve_early(mpf->physptr, mpf->physptr+size, "MP-table mpc");
+	reserve_early_overlap_ok(mpf->physptr, mpf->physptr+size, "MP-table mpc");
 }
 
 static int __init smp_scan_config(unsigned long base, unsigned long length)
@@ -693,7 +693,7 @@ static int __init smp_scan_config(unsign
 			       mpf, (u64)virt_to_phys(mpf));
 
 			mem = virt_to_phys(mpf);
-			reserve_early(mem, mem + sizeof(*mpf), "MP-table mpf");
+			reserve_early_overlap_ok(mem, mem + sizeof(*mpf), "MP-table mpf");
 			if (mpf->physptr)
 				smp_reserve_memory(mpf);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/mrst.c linux-libre-2.6.34-gnu1/arch/x86/kernel/mrst.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/mrst.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/mrst.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,8 +10,211 @@
  * of the License.
  */
 #include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sfi.h>
+#include <linux/irq.h>
+#include <linux/module.h>
 
 #include <asm/setup.h>
+#include <asm/mpspec_def.h>
+#include <asm/hw_irq.h>
+#include <asm/apic.h>
+#include <asm/io_apic.h>
+#include <asm/mrst.h>
+#include <asm/io.h>
+#include <asm/i8259.h>
+#include <asm/apb_timer.h>
+
+static u32 sfi_mtimer_usage[SFI_MTMR_MAX_NUM];
+static struct sfi_timer_table_entry sfi_mtimer_array[SFI_MTMR_MAX_NUM];
+int sfi_mtimer_num;
+
+struct sfi_rtc_table_entry sfi_mrtc_array[SFI_MRTC_MAX];
+EXPORT_SYMBOL_GPL(sfi_mrtc_array);
+int sfi_mrtc_num;
+
+static inline void assign_to_mp_irq(struct mpc_intsrc *m,
+				    struct mpc_intsrc *mp_irq)
+{
+	memcpy(mp_irq, m, sizeof(struct mpc_intsrc));
+}
+
+static inline int mp_irq_cmp(struct mpc_intsrc *mp_irq,
+				struct mpc_intsrc *m)
+{
+	return memcmp(mp_irq, m, sizeof(struct mpc_intsrc));
+}
+
+static void save_mp_irq(struct mpc_intsrc *m)
+{
+	int i;
+
+	for (i = 0; i < mp_irq_entries; i++) {
+		if (!mp_irq_cmp(&mp_irqs[i], m))
+			return;
+	}
+
+	assign_to_mp_irq(m, &mp_irqs[mp_irq_entries]);
+	if (++mp_irq_entries == MAX_IRQ_SOURCES)
+		panic("Max # of irq sources exceeded!!\n");
+}
+
+/* parse all the mtimer info to a static mtimer array */
+static int __init sfi_parse_mtmr(struct sfi_table_header *table)
+{
+	struct sfi_table_simple *sb;
+	struct sfi_timer_table_entry *pentry;
+	struct mpc_intsrc mp_irq;
+	int totallen;
+
+	sb = (struct sfi_table_simple *)table;
+	if (!sfi_mtimer_num) {
+		sfi_mtimer_num = SFI_GET_NUM_ENTRIES(sb,
+					struct sfi_timer_table_entry);
+		pentry = (struct sfi_timer_table_entry *) sb->pentry;
+		totallen = sfi_mtimer_num * sizeof(*pentry);
+		memcpy(sfi_mtimer_array, pentry, totallen);
+	}
+
+	printk(KERN_INFO "SFI: MTIMER info (num = %d):\n", sfi_mtimer_num);
+	pentry = sfi_mtimer_array;
+	for (totallen = 0; totallen < sfi_mtimer_num; totallen++, pentry++) {
+		printk(KERN_INFO "timer[%d]: paddr = 0x%08x, freq = %dHz,"
+			" irq = %d\n", totallen, (u32)pentry->phys_addr,
+			pentry->freq_hz, pentry->irq);
+			if (!pentry->irq)
+				continue;
+			mp_irq.type = MP_IOAPIC;
+			mp_irq.irqtype = mp_INT;
+/* triggering mode edge bit 2-3, active high polarity bit 0-1 */
+			mp_irq.irqflag = 5;
+			mp_irq.srcbus = 0;
+			mp_irq.srcbusirq = pentry->irq;	/* IRQ */
+			mp_irq.dstapic = MP_APIC_ALL;
+			mp_irq.dstirq = pentry->irq;
+			save_mp_irq(&mp_irq);
+	}
+
+	return 0;
+}
+
+struct sfi_timer_table_entry *sfi_get_mtmr(int hint)
+{
+	int i;
+	if (hint < sfi_mtimer_num) {
+		if (!sfi_mtimer_usage[hint]) {
+			pr_debug("hint taken for timer %d irq %d\n",\
+				hint, sfi_mtimer_array[hint].irq);
+			sfi_mtimer_usage[hint] = 1;
+			return &sfi_mtimer_array[hint];
+		}
+	}
+	/* take the first timer available */
+	for (i = 0; i < sfi_mtimer_num;) {
+		if (!sfi_mtimer_usage[i]) {
+			sfi_mtimer_usage[i] = 1;
+			return &sfi_mtimer_array[i];
+		}
+		i++;
+	}
+	return NULL;
+}
+
+void sfi_free_mtmr(struct sfi_timer_table_entry *mtmr)
+{
+	int i;
+	for (i = 0; i < sfi_mtimer_num;) {
+		if (mtmr->irq == sfi_mtimer_array[i].irq) {
+			sfi_mtimer_usage[i] = 0;
+			return;
+		}
+		i++;
+	}
+}
+
+/* parse all the mrtc info to a global mrtc array */
+int __init sfi_parse_mrtc(struct sfi_table_header *table)
+{
+	struct sfi_table_simple *sb;
+	struct sfi_rtc_table_entry *pentry;
+	struct mpc_intsrc mp_irq;
+
+	int totallen;
+
+	sb = (struct sfi_table_simple *)table;
+	if (!sfi_mrtc_num) {
+		sfi_mrtc_num = SFI_GET_NUM_ENTRIES(sb,
+						struct sfi_rtc_table_entry);
+		pentry = (struct sfi_rtc_table_entry *)sb->pentry;
+		totallen = sfi_mrtc_num * sizeof(*pentry);
+		memcpy(sfi_mrtc_array, pentry, totallen);
+	}
+
+	printk(KERN_INFO "SFI: RTC info (num = %d):\n", sfi_mrtc_num);
+	pentry = sfi_mrtc_array;
+	for (totallen = 0; totallen < sfi_mrtc_num; totallen++, pentry++) {
+		printk(KERN_INFO "RTC[%d]: paddr = 0x%08x, irq = %d\n",
+			totallen, (u32)pentry->phys_addr, pentry->irq);
+		mp_irq.type = MP_IOAPIC;
+		mp_irq.irqtype = mp_INT;
+		mp_irq.irqflag = 0;
+		mp_irq.srcbus = 0;
+		mp_irq.srcbusirq = pentry->irq;	/* IRQ */
+		mp_irq.dstapic = MP_APIC_ALL;
+		mp_irq.dstirq = pentry->irq;
+		save_mp_irq(&mp_irq);
+	}
+	return 0;
+}
+
+/*
+ * the secondary clock in Moorestown can be APBT or LAPIC clock, default to
+ * APBT but cmdline option can also override it.
+ */
+static void __cpuinit mrst_setup_secondary_clock(void)
+{
+	/* restore default lapic clock if disabled by cmdline */
+	if (disable_apbt_percpu)
+		return setup_secondary_APIC_clock();
+	apbt_setup_secondary_clock();
+}
+
+static unsigned long __init mrst_calibrate_tsc(void)
+{
+	unsigned long flags, fast_calibrate;
+
+	local_irq_save(flags);
+	fast_calibrate = apbt_quick_calibrate();
+	local_irq_restore(flags);
+
+	if (fast_calibrate)
+		return fast_calibrate;
+
+	return 0;
+}
+
+void __init mrst_time_init(void)
+{
+	sfi_table_parse(SFI_SIG_MTMR, NULL, NULL, sfi_parse_mtmr);
+	pre_init_apic_IRQ0();
+	apbt_time_init();
+}
+
+void __init mrst_rtc_init(void)
+{
+	sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc);
+}
+
+/*
+ * if we use per cpu apb timer, the bootclock already setup. if we use lapic
+ * timer and one apbt timer for broadcast, we need to set up lapic boot clock.
+ */
+static void __init mrst_setup_boot_clock(void)
+{
+	pr_info("%s: per cpu apbt flag %d \n", __func__, disable_apbt_percpu);
+	if (disable_apbt_percpu)
+		setup_boot_APIC_clock();
+};
 
 /*
  * Moorestown specific x86_init function overrides and early setup
@@ -21,4 +224,17 @@ void __init x86_mrst_early_setup(void)
 {
 	x86_init.resources.probe_roms = x86_init_noop;
 	x86_init.resources.reserve_resources = x86_init_noop;
+
+	x86_init.timers.timer_init = mrst_time_init;
+	x86_init.timers.setup_percpu_clockev = mrst_setup_boot_clock;
+
+	x86_init.irqs.pre_vector_init = x86_init_noop;
+
+	x86_cpuinit.setup_percpu_clockev = mrst_setup_secondary_clock;
+
+	x86_platform.calibrate_tsc = mrst_calibrate_tsc;
+	x86_init.pci.init = pci_mrst_init;
+	x86_init.pci.fixup_irqs = x86_init_noop;
+
+	legacy_pic = &null_legacy_pic;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/msr.c linux-libre-2.6.34-gnu1/arch/x86/kernel/msr.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/msr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/msr.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/cpu.h>
 #include <linux/notifier.h>
 #include <linux/uaccess.h>
+#include <linux/gfp.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/olpc.c linux-libre-2.6.34-gnu1/arch/x86/kernel/olpc.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/olpc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/olpc.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,9 @@
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/string.h>
+
 #include <asm/geode.h>
+#include <asm/setup.h>
 #include <asm/olpc.h>
 
 #ifdef CONFIG_OPEN_FIRMWARE
@@ -243,9 +245,11 @@ static int __init olpc_init(void)
 	olpc_ec_cmd(EC_FIRMWARE_REV, NULL, 0,
 			(unsigned char *) &olpc_platform_info.ecver, 1);
 
-	/* check to see if the VSA exists */
-	if (cs5535_has_vsa2())
-		olpc_platform_info.flags |= OLPC_F_VSA;
+#ifdef CONFIG_PCI_OLPC
+	/* If the VSA exists let it emulate PCI, if not emulate in kernel */
+	if (!cs5535_has_vsa2())
+		x86_init.pci.arch_init = pci_olpc_init;
+#endif
 
 	printk(KERN_INFO "OLPC board revision %s%X (EC=%x)\n",
 			((olpc_platform_info.boardrev & 0xf) < 8) ? "pre" : "",
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/paravirt.c linux-libre-2.6.34-gnu1/arch/x86/kernel/paravirt.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/paravirt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/paravirt.c	2010-05-16 17:17:36.000000000 -0400
@@ -428,10 +428,6 @@ struct pv_mmu_ops pv_mmu_ops = {
 	.ptep_modify_prot_start = __ptep_modify_prot_start,
 	.ptep_modify_prot_commit = __ptep_modify_prot_commit,
 
-#ifdef CONFIG_HIGHPTE
-	.kmap_atomic_pte = kmap_atomic,
-#endif
-
 #if PAGETABLE_LEVELS >= 3
 #ifdef CONFIG_X86_PAE
 	.set_pte_atomic = native_set_pte_atomic,
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-calgary_64.c linux-libre-2.6.34-gnu1/arch/x86/kernel/pci-calgary_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-calgary_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/pci-calgary_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -1309,7 +1309,7 @@ static void calgary_init_bitmap_from_tce
 /*
  * get_tce_space_from_tar():
  * Function for kdump case. Get the tce tables from first kernel
- * by reading the contents of the base adress register of calgary iommu
+ * by reading the contents of the base address register of calgary iommu
  */
 static void __init get_tce_space_from_tar(void)
 {
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-dma.c linux-libre-2.6.34-gnu1/arch/x86/kernel/pci-dma.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/pci-dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
 #include <linux/dma-debug.h>
 #include <linux/dmar.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/kmemleak.h>
 
@@ -38,7 +39,7 @@ int iommu_detected __read_mostly = 0;
  * This variable becomes 1 if iommu=pt is passed on the kernel command line.
  * If this variable is 1, IOMMU implementations do no DMA translation for
  * devices and allow every device to access to whole physical memory. This is
- * useful if a user want to use an IOMMU only for KVM device assignment to
+ * useful if a user wants to use an IOMMU only for KVM device assignment to
  * guests and not for driver dma translation.
  */
 int iommu_pass_through __read_mostly;
@@ -65,7 +66,7 @@ int dma_set_mask(struct device *dev, u64
 }
 EXPORT_SYMBOL(dma_set_mask);
 
-#ifdef CONFIG_X86_64
+#if defined(CONFIG_X86_64) && !defined(CONFIG_NUMA)
 static __initdata void *dma32_bootmem_ptr;
 static unsigned long dma32_bootmem_size __initdata = (128ULL<<20);
 
@@ -116,14 +117,21 @@ static void __init dma32_free_bootmem(vo
 	dma32_bootmem_ptr = NULL;
 	dma32_bootmem_size = 0;
 }
+#else
+void __init dma32_reserve_bootmem(void)
+{
+}
+static void __init dma32_free_bootmem(void)
+{
+}
+
 #endif
 
 void __init pci_iommu_alloc(void)
 {
-#ifdef CONFIG_X86_64
 	/* free the range so iommu could get some range less than 4G */
 	dma32_free_bootmem();
-#endif
+
 	if (pci_swiotlb_detect())
 		goto out;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-gart_64.c linux-libre-2.6.34-gnu1/arch/x86/kernel/pci-gart_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-gart_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/pci-gart_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/iommu-helper.h>
 #include <linux/sysdev.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 #include <asm/atomic.h>
 #include <asm/mtrr.h>
 #include <asm/pgtable.h>
@@ -564,6 +565,9 @@ static void enable_gart_translations(voi
 
 		enable_gart_translation(dev, __pa(agp_gatt_table));
 	}
+
+	/* Flush the GART-TLB to remove stale entries */
+	k8_flush_garts();
 }
 
 /*
@@ -735,7 +739,7 @@ int __init gart_iommu_init(void)
 	unsigned long scratch;
 	long i;
 
-	if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0)
+	if (num_k8_northbridges == 0)
 		return 0;
 
 #ifndef CONFIG_AGP_AMD64
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-nommu.c linux-libre-2.6.34-gnu1/arch/x86/kernel/pci-nommu.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-nommu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/pci-nommu.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
 #include <linux/scatterlist.h>
 #include <linux/string.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/mm.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/process_32.c linux-libre-2.6.34-gnu1/arch/x86/kernel/process_32.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/process_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/process_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -174,12 +174,6 @@ void __show_regs(struct pt_regs *regs, i
 			d6, d7);
 }
 
-void show_regs(struct pt_regs *regs)
-{
-	show_registers(regs);
-	show_trace(NULL, regs, &regs->sp, regs->bp);
-}
-
 void release_thread(struct task_struct *dead_task)
 {
 	BUG_ON(dead_task->mm);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/process_64.c linux-libre-2.6.34-gnu1/arch/x86/kernel/process_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/process_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/process_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -211,12 +211,6 @@ void __show_regs(struct pt_regs *regs, i
 	printk(KERN_DEFAULT "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7);
 }
 
-void show_regs(struct pt_regs *regs)
-{
-	show_registers(regs);
-	show_trace(NULL, regs, (void *)(regs + 1), regs->bp);
-}
-
 void release_thread(struct task_struct *dead_task)
 {
 	if (dead_task->mm) {
@@ -282,12 +276,12 @@ int copy_thread(unsigned long clone_flag
 
 	set_tsk_thread_flag(p, TIF_FORK);
 
-	p->thread.fs = me->thread.fs;
-	p->thread.gs = me->thread.gs;
 	p->thread.io_bitmap_ptr = NULL;
 
 	savesegment(gs, p->thread.gsindex);
+	p->thread.gs = p->thread.gsindex ? 0 : me->thread.gs;
 	savesegment(fs, p->thread.fsindex);
+	p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs;
 	savesegment(es, p->thread.es);
 	savesegment(ds, p->thread.ds);
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/process.c linux-libre-2.6.34-gnu1/arch/x86/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -92,6 +92,13 @@ void exit_thread(void)
 	}
 }
 
+void show_regs(struct pt_regs *regs)
+{
+	show_registers(regs);
+	show_trace(NULL, regs, (unsigned long *)kernel_stack_pointer(regs),
+		   regs->bp);
+}
+
 void show_regs_common(void)
 {
 	const char *board, *product;
@@ -519,21 +526,39 @@ static int __cpuinit mwait_usable(const
 }
 
 /*
- * Check for AMD CPUs, which have potentially C1E support
+ * Check for AMD CPUs, where APIC timer interrupt does not wake up CPU from C1e.
+ * For more information see
+ * - Erratum #400 for NPT family 0xf and family 0x10 CPUs
+ * - Erratum #365 for family 0x11 (not affected because C1e not in use)
  */
 static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
 {
+	u64 val;
 	if (c->x86_vendor != X86_VENDOR_AMD)
-		return 0;
-
-	if (c->x86 < 0x0F)
-		return 0;
+		goto no_c1e_idle;
 
 	/* Family 0x0f models < rev F do not have C1E */
-	if (c->x86 == 0x0f && c->x86_model < 0x40)
-		return 0;
+	if (c->x86 == 0x0F && c->x86_model >= 0x40)
+		return 1;
 
-	return 1;
+	if (c->x86 == 0x10) {
+		/*
+		 * check OSVW bit for CPUs that are not affected
+		 * by erratum #400
+		 */
+		if (cpu_has(c, X86_FEATURE_OSVW)) {
+			rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val);
+			if (val >= 2) {
+				rdmsrl(MSR_AMD64_OSVW_STATUS, val);
+				if (!(val & BIT(1)))
+					goto no_c1e_idle;
+			}
+		}
+		return 1;
+	}
+
+no_c1e_idle:
+	return 0;
 }
 
 static cpumask_var_t c1e_mask;
@@ -600,7 +625,7 @@ void __cpuinit select_idle_routine(const
 {
 #ifdef CONFIG_SMP
 	if (pm_idle == poll_idle && smp_num_siblings > 1) {
-		printk(KERN_WARNING "WARNING: polling idle and HT enabled,"
+		printk_once(KERN_WARNING "WARNING: polling idle and HT enabled,"
 			" performance may degrade.\n");
 	}
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/x86/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/mm.h>
 #include <linux/smp.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/ptrace.h>
 #include <linux/regset.h>
 #include <linux/tracehook.h>
@@ -48,6 +49,7 @@ enum x86_regset {
 	REGSET_FP,
 	REGSET_XFP,
 	REGSET_IOPERM64 = REGSET_XFP,
+	REGSET_XSTATE,
 	REGSET_TLS,
 	REGSET_IOPERM32,
 };
@@ -140,30 +142,6 @@ static const int arg_offs_table[] = {
 #endif
 };
 
-/**
- * regs_get_argument_nth() - get Nth argument at function call
- * @regs:	pt_regs which contains registers at function entry.
- * @n:		argument number.
- *
- * regs_get_argument_nth() returns @n th argument of a function call.
- * Since usually the kernel stack will be changed right after function entry,
- * you must use this at function entry. If the @n th entry is NOT in the
- * kernel stack or pt_regs, this returns 0.
- */
-unsigned long regs_get_argument_nth(struct pt_regs *regs, unsigned int n)
-{
-	if (n < ARRAY_SIZE(arg_offs_table))
-		return *(unsigned long *)((char *)regs + arg_offs_table[n]);
-	else {
-		/*
-		 * The typical case: arg n is on the stack.
-		 * (Note: stack[0] = return address, so skip it)
-		 */
-		n -= ARRAY_SIZE(arg_offs_table);
-		return regs_get_kernel_stack_nth(regs, 1 + n);
-	}
-}
-
 /*
  * does not yet catch signals sent when the child dies.
  * in exit.c or in signal.c.
@@ -604,7 +582,7 @@ ptrace_modify_breakpoint(struct perf_eve
 	struct perf_event_attr attr;
 
 	/*
-	 * We shoud have at least an inactive breakpoint at this
+	 * We should have at least an inactive breakpoint at this
 	 * slot. It means the user is writing dr7 without having
 	 * written the address register first
 	 */
@@ -1587,7 +1565,7 @@ long compat_arch_ptrace(struct task_stru
 
 #ifdef CONFIG_X86_64
 
-static const struct user_regset x86_64_regsets[] = {
+static struct user_regset x86_64_regsets[] __read_mostly = {
 	[REGSET_GENERAL] = {
 		.core_note_type = NT_PRSTATUS,
 		.n = sizeof(struct user_regs_struct) / sizeof(long),
@@ -1600,6 +1578,12 @@ static const struct user_regset x86_64_r
 		.size = sizeof(long), .align = sizeof(long),
 		.active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set
 	},
+	[REGSET_XSTATE] = {
+		.core_note_type = NT_X86_XSTATE,
+		.size = sizeof(u64), .align = sizeof(u64),
+		.active = xstateregs_active, .get = xstateregs_get,
+		.set = xstateregs_set
+	},
 	[REGSET_IOPERM64] = {
 		.core_note_type = NT_386_IOPERM,
 		.n = IO_BITMAP_LONGS,
@@ -1625,7 +1609,7 @@ static const struct user_regset_view use
 #endif	/* CONFIG_X86_64 */
 
 #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
-static const struct user_regset x86_32_regsets[] = {
+static struct user_regset x86_32_regsets[] __read_mostly = {
 	[REGSET_GENERAL] = {
 		.core_note_type = NT_PRSTATUS,
 		.n = sizeof(struct user_regs_struct32) / sizeof(u32),
@@ -1644,6 +1628,12 @@ static const struct user_regset x86_32_r
 		.size = sizeof(u32), .align = sizeof(u32),
 		.active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set
 	},
+	[REGSET_XSTATE] = {
+		.core_note_type = NT_X86_XSTATE,
+		.size = sizeof(u64), .align = sizeof(u64),
+		.active = xstateregs_active, .get = xstateregs_get,
+		.set = xstateregs_set
+	},
 	[REGSET_TLS] = {
 		.core_note_type = NT_386_TLS,
 		.n = GDT_ENTRY_TLS_ENTRIES, .bias = GDT_ENTRY_TLS_MIN,
@@ -1666,6 +1656,23 @@ static const struct user_regset_view use
 };
 #endif
 
+/*
+ * This represents bytes 464..511 in the memory layout exported through
+ * the REGSET_XSTATE interface.
+ */
+u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS];
+
+void update_regset_xstate_info(unsigned int size, u64 xstate_mask)
+{
+#ifdef CONFIG_X86_64
+	x86_64_regsets[REGSET_XSTATE].n = size / sizeof(u64);
+#endif
+#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
+	x86_32_regsets[REGSET_XSTATE].n = size / sizeof(u64);
+#endif
+	xstate_fx_sw_bytes[USER_XSTATE_XCR0_WORD] = xstate_mask;
+}
+
 const struct user_regset_view *task_user_regset_view(struct task_struct *task)
 {
 #ifdef CONFIG_IA32_EMULATION
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/reboot.c linux-libre-2.6.34-gnu1/arch/x86/kernel/reboot.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/reboot.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/reboot.c	2010-05-16 17:17:36.000000000 -0400
@@ -461,6 +461,14 @@ static struct dmi_system_id __initdata p
 			DMI_MATCH(DMI_PRODUCT_NAME, "Macmini3,1"),
 		},
 	},
+	{	/* Handle problems with rebooting on the iMac9,1. */
+		.callback = set_pci_reboot,
+		.ident = "Apple iMac9,1",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"),
+		},
+	},
 	{ }
 };
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/setup.c linux-libre-2.6.34-gnu1/arch/x86/kernel/setup.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,7 +55,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/delay.h>
 
@@ -121,7 +120,9 @@
 unsigned long max_low_pfn_mapped;
 unsigned long max_pfn_mapped;
 
+#ifdef CONFIG_DMI
 RESERVE_BRK(dmi_alloc, 65536);
+#endif
 
 unsigned int boot_cpu_id __read_mostly;
 
@@ -312,16 +313,17 @@ static void __init reserve_brk(void)
 #define MAX_MAP_CHUNK	(NR_FIX_BTMAPS << PAGE_SHIFT)
 static void __init relocate_initrd(void)
 {
-
+	/* Assume only end is not page aligned */
 	u64 ramdisk_image = boot_params.hdr.ramdisk_image;
 	u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
+	u64 area_size     = PAGE_ALIGN(ramdisk_size);
 	u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
 	u64 ramdisk_here;
 	unsigned long slop, clen, mapaddr;
 	char *p, *q;
 
 	/* We need to move the initrd down into lowmem */
-	ramdisk_here = find_e820_area(0, end_of_lowmem, ramdisk_size,
+	ramdisk_here = find_e820_area(0, end_of_lowmem, area_size,
 					 PAGE_SIZE);
 
 	if (ramdisk_here == -1ULL)
@@ -330,7 +332,7 @@ static void __init relocate_initrd(void)
 
 	/* Note: this includes all the lowmem currently occupied by
 	   the initrd, we rely on that fact to keep the data intact. */
-	reserve_early(ramdisk_here, ramdisk_here + ramdisk_size,
+	reserve_early(ramdisk_here, ramdisk_here + area_size,
 			 "NEW RAMDISK");
 	initrd_start = ramdisk_here + PAGE_OFFSET;
 	initrd_end   = initrd_start + ramdisk_size;
@@ -374,9 +376,10 @@ static void __init relocate_initrd(void)
 
 static void __init reserve_initrd(void)
 {
+	/* Assume only end is not page aligned */
 	u64 ramdisk_image = boot_params.hdr.ramdisk_image;
 	u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
-	u64 ramdisk_end   = ramdisk_image + ramdisk_size;
+	u64 ramdisk_end   = PAGE_ALIGN(ramdisk_image + ramdisk_size);
 	u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
 
 	if (!boot_params.hdr.type_of_loader ||
@@ -604,6 +607,16 @@ static int __init setup_elfcorehdr(char
 early_param("elfcorehdr", setup_elfcorehdr);
 #endif
 
+static __init void reserve_ibft_region(void)
+{
+	unsigned long addr, size = 0;
+
+	addr = find_ibft_region(&size);
+
+	if (size)
+		reserve_early_overlap_ok(addr, addr + size, "ibft");
+}
+
 #ifdef CONFIG_X86_RESERVE_LOW_64K
 static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
 {
@@ -667,6 +680,23 @@ static struct dmi_system_id __initdata b
 	{}
 };
 
+static void __init trim_bios_range(void)
+{
+	/*
+	 * A special case is the first 4Kb of memory;
+	 * This is a BIOS owned area, not kernel ram, but generally
+	 * not listed as such in the E820 table.
+	 */
+	e820_update_range(0, PAGE_SIZE, E820_RAM, E820_RESERVED);
+	/*
+	 * special case: Some BIOSen report the PC BIOS
+	 * area (640->1Mb) as ram even though it is not.
+	 * take them out.
+	 */
+	e820_remove_range(BIOS_BEGIN, BIOS_END - BIOS_BEGIN, E820_RAM, 1);
+	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+}
+
 /*
  * Determine if we were loaded by an EFI loader.  If so, then we have also been
  * passed the efi memmap, systab, etc., so we should use these data structures
@@ -830,7 +860,7 @@ void __init setup_arch(char **cmdline_p)
 	insert_resource(&iomem_resource, &data_resource);
 	insert_resource(&iomem_resource, &bss_resource);
 
-
+	trim_bios_range();
 #ifdef CONFIG_X86_32
 	if (ppro_with_ram_bug()) {
 		e820_update_range(0x70000000ULL, 0x40000ULL, E820_RAM,
@@ -889,6 +919,8 @@ void __init setup_arch(char **cmdline_p)
 	 */
 	find_smp_config();
 
+	reserve_ibft_region();
+
 	reserve_trampoline_memory();
 
 #ifdef CONFIG_ACPI_SLEEP
@@ -950,17 +982,11 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
 	initmem_init(0, max_pfn, acpi, k8);
-
-#ifdef CONFIG_X86_64
-	/*
-	 * dma32_reserve_bootmem() allocates bootmem which may conflict
-	 * with the crashkernel command line, so do that after
-	 * reserve_crashkernel()
-	 */
-	dma32_reserve_bootmem();
+#ifndef CONFIG_NO_BOOTMEM
+	early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT);
 #endif
 
-	reserve_ibft_region();
+	dma32_reserve_bootmem();
 
 #ifdef CONFIG_KVM_CLOCK
 	kvmclock_init();
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/setup_percpu.c linux-libre-2.6.34-gnu1/arch/x86/kernel/setup_percpu.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/setup_percpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/setup_percpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -137,7 +137,13 @@ static void * __init pcpu_fc_alloc(unsig
 
 static void __init pcpu_fc_free(void *ptr, size_t size)
 {
+#ifdef CONFIG_NO_BOOTMEM
+	u64 start = __pa(ptr);
+	u64 end = start + size;
+	free_early_partial(start, end);
+#else
 	free_bootmem(__pa(ptr), size);
+#endif
 }
 
 static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/smpboot.c linux-libre-2.6.34-gnu1/arch/x86/kernel/smpboot.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/smpboot.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/smpboot.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,6 +48,8 @@
 #include <linux/err.h>
 #include <linux/nmi.h>
 #include <linux/tboot.h>
+#include <linux/stackprotector.h>
+#include <linux/gfp.h>
 
 #include <asm/acpi.h>
 #include <asm/desc.h>
@@ -67,6 +69,7 @@
 #include <linux/mc146818rtc.h>
 
 #include <asm/smpboot_hooks.h>
+#include <asm/i8259.h>
 
 #ifdef CONFIG_X86_32
 u8 apicid_2_node[MAX_APICID];
@@ -240,7 +243,10 @@ static void __cpuinit smp_callin(void)
 	end_local_APIC_setup();
 	map_cpu_to_logical_apicid();
 
-	notify_cpu_starting(cpuid);
+	/*
+	 * Need to setup vector mappings before we enable interrupts.
+	 */
+	setup_vector_irq(smp_processor_id());
 	/*
 	 * Get our bogomips.
 	 *
@@ -257,6 +263,8 @@ static void __cpuinit smp_callin(void)
 	 */
 	smp_store_cpu_info(cpuid);
 
+	notify_cpu_starting(cpuid);
+
 	/*
 	 * Allow the master to continue.
 	 */
@@ -286,9 +294,9 @@ notrace static void __cpuinit start_seco
 	check_tsc_sync_target();
 
 	if (nmi_watchdog == NMI_IO_APIC) {
-		disable_8259A_irq(0);
+		legacy_pic->chip->mask(0);
 		enable_NMI_through_LVT0();
-		enable_8259A_irq(0);
+		legacy_pic->chip->unmask(0);
 	}
 
 #ifdef CONFIG_X86_32
@@ -315,15 +323,18 @@ notrace static void __cpuinit start_seco
 	 */
 	ipi_call_lock();
 	lock_vector_lock();
-	__setup_vector_irq(smp_processor_id());
 	set_cpu_online(smp_processor_id(), true);
 	unlock_vector_lock();
 	ipi_call_unlock();
 	per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
+	x86_platform.nmi_init();
 
 	/* enable local interrupts */
 	local_irq_enable();
 
+	/* to prevent fake stack check failure in clock setup */
+	boot_init_stack_canary();
+
 	x86_cpuinit.setup_percpu_clockev();
 
 	wmb();
@@ -1211,11 +1222,12 @@ __init void prefill_possible_map(void)
 
 	total_cpus = max_t(int, possible, num_processors + disabled_cpus);
 
-	if (possible > CONFIG_NR_CPUS) {
+	/* nr_cpu_ids could be reduced via nr_cpus= */
+	if (possible > nr_cpu_ids) {
 		printk(KERN_WARNING
 			"%d Processors exceeds NR_CPUS limit of %d\n",
-			possible, CONFIG_NR_CPUS);
-		possible = CONFIG_NR_CPUS;
+			possible, nr_cpu_ids);
+		possible = nr_cpu_ids;
 	}
 
 	printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n",
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/smp.c linux-libre-2.6.34-gnu1/arch/x86/kernel/smp.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/smp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/cache.h>
 #include <linux/interrupt.h>
 #include <linux/cpu.h>
+#include <linux/gfp.h>
 
 #include <asm/mtrr.h>
 #include <asm/tlbflush.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/syscall_table_32.S linux-libre-2.6.34-gnu1/arch/x86/kernel/syscall_table_32.S
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/syscall_table_32.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/syscall_table_32.S	2010-05-16 17:17:36.000000000 -0400
@@ -81,7 +81,7 @@ ENTRY(sys_call_table)
 	.long sys_settimeofday
 	.long sys_getgroups16	/* 80 */
 	.long sys_setgroups16
-	.long old_select
+	.long sys_old_select
 	.long sys_symlink
 	.long sys_lstat
 	.long sys_readlink	/* 85 */
@@ -89,7 +89,7 @@ ENTRY(sys_call_table)
 	.long sys_swapon
 	.long sys_reboot
 	.long sys_old_readdir
-	.long old_mmap		/* 90 */
+	.long sys_old_mmap	/* 90 */
 	.long sys_munmap
 	.long sys_truncate
 	.long sys_ftruncate
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/sys_i386_32.c linux-libre-2.6.34-gnu1/arch/x86/kernel/sys_i386_32.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/sys_i386_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/sys_i386_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,191 +25,6 @@
 #include <asm/syscalls.h>
 
 /*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. Linux/i386 didn't use to be able to handle more than
- * 4 system call parameters, so these system calls used a memory
- * block for parameter passing..
- */
-
-struct mmap_arg_struct {
-	unsigned long addr;
-	unsigned long len;
-	unsigned long prot;
-	unsigned long flags;
-	unsigned long fd;
-	unsigned long offset;
-};
-
-asmlinkage int old_mmap(struct mmap_arg_struct __user *arg)
-{
-	struct mmap_arg_struct a;
-	int err = -EFAULT;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		goto out;
-
-	err = -EINVAL;
-	if (a.offset & ~PAGE_MASK)
-		goto out;
-
-	err = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags,
-			a.fd, a.offset >> PAGE_SHIFT);
-out:
-	return err;
-}
-
-
-struct sel_arg_struct {
-	unsigned long n;
-	fd_set __user *inp, *outp, *exp;
-	struct timeval __user *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct __user *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	/* sys_select() does the appropriate kernel locking */
-	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage int sys_ipc(uint call, int first, int second,
-			int third, void __user *ptr, long fifth)
-{
-	int version, ret;
-
-	version = call >> 16; /* hack for backward compatibility */
-	call &= 0xffff;
-
-	switch (call) {
-	case SEMOP:
-		return sys_semtimedop(first, (struct sembuf __user *)ptr, second, NULL);
-	case SEMTIMEDOP:
-		return sys_semtimedop(first, (struct sembuf __user *)ptr, second,
-					(const struct timespec __user *)fifth);
-
-	case SEMGET:
-		return sys_semget(first, second, third);
-	case SEMCTL: {
-		union semun fourth;
-		if (!ptr)
-			return -EINVAL;
-		if (get_user(fourth.__pad, (void __user * __user *) ptr))
-			return -EFAULT;
-		return sys_semctl(first, second, third, fourth);
-	}
-
-	case MSGSND:
-		return sys_msgsnd(first, (struct msgbuf __user *) ptr,
-				   second, third);
-	case MSGRCV:
-		switch (version) {
-		case 0: {
-			struct ipc_kludge tmp;
-			if (!ptr)
-				return -EINVAL;
-
-			if (copy_from_user(&tmp,
-					   (struct ipc_kludge __user *) ptr,
-					   sizeof(tmp)))
-				return -EFAULT;
-			return sys_msgrcv(first, tmp.msgp, second,
-					   tmp.msgtyp, third);
-		}
-		default:
-			return sys_msgrcv(first,
-					   (struct msgbuf __user *) ptr,
-					   second, fifth, third);
-		}
-	case MSGGET:
-		return sys_msgget((key_t) first, second);
-	case MSGCTL:
-		return sys_msgctl(first, second, (struct msqid_ds __user *) ptr);
-
-	case SHMAT:
-		switch (version) {
-		default: {
-			ulong raddr;
-			ret = do_shmat(first, (char __user *) ptr, second, &raddr);
-			if (ret)
-				return ret;
-			return put_user(raddr, (ulong __user *) third);
-		}
-		case 1:	/* iBCS2 emulator entry point */
-			if (!segment_eq(get_fs(), get_ds()))
-				return -EINVAL;
-			/* The "(ulong *) third" is valid _only_ because of the kernel segment thing */
-			return do_shmat(first, (char __user *) ptr, second, (ulong *) third);
-		}
-	case SHMDT:
-		return sys_shmdt((char __user *)ptr);
-	case SHMGET:
-		return sys_shmget(first, second, third);
-	case SHMCTL:
-		return sys_shmctl(first, second,
-				   (struct shmid_ds __user *) ptr);
-	default:
-		return -ENOSYS;
-	}
-}
-
-/*
- * Old cruft
- */
-asmlinkage int sys_uname(struct old_utsname __user *name)
-{
-	int err;
-	if (!name)
-		return -EFAULT;
-	down_read(&uts_sem);
-	err = copy_to_user(name, utsname(), sizeof(*name));
-	up_read(&uts_sem);
-	return err? -EFAULT:0;
-}
-
-asmlinkage int sys_olduname(struct oldold_utsname __user *name)
-{
-	int error;
-
-	if (!name)
-		return -EFAULT;
-	if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
-		return -EFAULT;
-
-	down_read(&uts_sem);
-
-	error = __copy_to_user(&name->sysname, &utsname()->sysname,
-			       __OLD_UTS_LEN);
-	error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->nodename, &utsname()->nodename,
-				__OLD_UTS_LEN);
-	error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->release, &utsname()->release,
-				__OLD_UTS_LEN);
-	error |= __put_user(0, name->release + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->version, &utsname()->version,
-				__OLD_UTS_LEN);
-	error |= __put_user(0, name->version + __OLD_UTS_LEN);
-	error |= __copy_to_user(&name->machine, &utsname()->machine,
-				__OLD_UTS_LEN);
-	error |= __put_user(0, name->machine + __OLD_UTS_LEN);
-
-	up_read(&uts_sem);
-
-	error = error ? -EFAULT : 0;
-
-	return error;
-}
-
-
-/*
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
  */
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/sys_x86_64.c linux-libre-2.6.34-gnu1/arch/x86/kernel/sys_x86_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/sys_x86_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/sys_x86_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -209,15 +209,3 @@ bottomup:
 
 	return addr;
 }
-
-
-SYSCALL_DEFINE1(uname, struct new_utsname __user *, name)
-{
-	int err;
-	down_read(&uts_sem);
-	err = copy_to_user(name, utsname(), sizeof(*name));
-	up_read(&uts_sem);
-	if (personality(current->personality) == PER_LINUX32)
-		err |= copy_to_user(&name->machine, "i686", 5);
-	return err ? -EFAULT : 0;
-}
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/time.c linux-libre-2.6.34-gnu1/arch/x86/kernel/time.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -70,11 +70,11 @@ static irqreturn_t timer_interrupt(int i
 		 * manually to deassert NMI lines for the watchdog if run
 		 * on an 82489DX-based system.
 		 */
-		spin_lock(&i8259A_lock);
+		raw_spin_lock(&i8259A_lock);
 		outb(0x0c, PIC_MASTER_OCW3);
 		/* Ack the IRQ; AEOI will end it automatically. */
 		inb(PIC_MASTER_POLL);
-		spin_unlock(&i8259A_lock);
+		raw_spin_unlock(&i8259A_lock);
 	}
 
 	global_clock_event->event_handler(global_clock_event);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/tlb_uv.c linux-libre-2.6.34-gnu1/arch/x86/kernel/tlb_uv.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/tlb_uv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/tlb_uv.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/seq_file.h>
 #include <linux/proc_fs.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include <asm/mmu_context.h>
 #include <asm/uv/uv.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/traps.c linux-libre-2.6.34-gnu1/arch/x86/kernel/traps.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/traps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/traps.c	2010-05-16 17:17:36.000000000 -0400
@@ -534,6 +534,9 @@ dotraplinkage void __kprobes do_debug(st
 
 	get_debugreg(dr6, 6);
 
+	/* Filter out all the reserved bits which are preset to 1 */
+	dr6 &= ~DR6_RESERVED;
+
 	/* Catch kmemcheck conditions first of all! */
 	if ((dr6 & DR_STEP) && kmemcheck_trap(regs))
 		return;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/tsc.c linux-libre-2.6.34-gnu1/arch/x86/kernel/tsc.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/tsc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/tsc.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,7 +50,7 @@ u64 native_sched_clock(void)
 	 *   unstable. We do this because unlike Time Of Day,
 	 *   the scheduler clock tolerates small errors and it's
 	 *   very important for it to be as fast as the platform
-	 *   can achive it. )
+	 *   can achieve it. )
 	 */
 	if (unlikely(tsc_disabled)) {
 		/* No locking but a rare wrong value is not a big deal: */
@@ -740,7 +740,7 @@ static cycle_t __vsyscall_fn vread_tsc(v
 }
 #endif
 
-static void resume_tsc(void)
+static void resume_tsc(struct clocksource *cs)
 {
 	clocksource_tsc.cycle_last = 0;
 }
@@ -806,7 +806,7 @@ static void __init check_system_tsc_reli
 	unsigned long res_low, res_high;
 
 	rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high);
-	/* Geode_LX - the OLPC CPU has a possibly a very reliable TSC */
+	/* Geode_LX - the OLPC CPU has a very reliable TSC */
 	if (res_low & RTSC_SUSP)
 		tsc_clocksource_reliable = 1;
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/uv_irq.c linux-libre-2.6.34-gnu1/arch/x86/kernel/uv_irq.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/uv_irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/uv_irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 
 #include <linux/module.h>
 #include <linux/rbtree.h>
+#include <linux/slab.h>
 #include <linux/irq.h>
 
 #include <asm/apic.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/uv_sysfs.c linux-libre-2.6.34-gnu1/arch/x86/kernel/uv_sysfs.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/uv_sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/uv_sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,19 +54,19 @@ static int __init sgi_uv_sysfs_init(void
 	if (!sgi_uv_kobj)
 		sgi_uv_kobj = kobject_create_and_add("sgi_uv", firmware_kobj);
 	if (!sgi_uv_kobj) {
-		printk(KERN_WARNING "kobject_create_and_add sgi_uv failed \n");
+		printk(KERN_WARNING "kobject_create_and_add sgi_uv failed\n");
 		return -EINVAL;
 	}
 
 	ret = sysfs_create_file(sgi_uv_kobj, &partition_id_attr.attr);
 	if (ret) {
-		printk(KERN_WARNING "sysfs_create_file partition_id failed \n");
+		printk(KERN_WARNING "sysfs_create_file partition_id failed\n");
 		return ret;
 	}
 
 	ret = sysfs_create_file(sgi_uv_kobj, &coherence_id_attr.attr);
 	if (ret) {
-		printk(KERN_WARNING "sysfs_create_file coherence_id failed \n");
+		printk(KERN_WARNING "sysfs_create_file coherence_id failed\n");
 		return ret;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/uv_time.c linux-libre-2.6.34-gnu1/arch/x86/kernel/uv_time.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/uv_time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/uv_time.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  *  Copyright (c) Dimitri Sivanich
  */
 #include <linux/clockchips.h>
+#include <linux/slab.h>
 
 #include <asm/uv/uv_mmrs.h>
 #include <asm/uv/uv_hub.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/visws_quirks.c linux-libre-2.6.34-gnu1/arch/x86/kernel/visws_quirks.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/visws_quirks.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/visws_quirks.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,11 +49,6 @@ extern int no_broadcast;
 char visws_board_type	= -1;
 char visws_board_rev	= -1;
 
-int is_visws_box(void)
-{
-	return visws_board_type >= 0;
-}
-
 static void __init visws_time_init(void)
 {
 	printk(KERN_INFO "Starting Cobalt Timer system clock\n");
@@ -242,6 +237,8 @@ void __init visws_early_detect(void)
 	x86_init.irqs.pre_vector_init = visws_pre_intr_init;
 	x86_init.irqs.trap_init = visws_trap_init;
 	x86_init.timers.timer_init = visws_time_init;
+	x86_init.pci.init = pci_visws_init;
+	x86_init.pci.init_irq = x86_init_noop;
 
 	/*
 	 * Install reboot quirks:
@@ -508,7 +505,7 @@ static struct irq_chip cobalt_irq_type =
  */
 static unsigned int startup_piix4_master_irq(unsigned int irq)
 {
-	init_8259A(0);
+	legacy_pic->init(0);
 
 	return startup_cobalt_irq(irq);
 }
@@ -532,9 +529,6 @@ static struct irq_chip piix4_master_irq_
 
 static struct irq_chip piix4_virtual_irq_type = {
 	.name =		"PIIX4-virtual",
-	.shutdown =	disable_8259A_irq,
-	.enable =	enable_8259A_irq,
-	.disable =	disable_8259A_irq,
 };
 
 
@@ -559,7 +553,7 @@ static irqreturn_t piix4_master_intr(int
 	struct irq_desc *desc;
 	unsigned long flags;
 
-	spin_lock_irqsave(&i8259A_lock, flags);
+	raw_spin_lock_irqsave(&i8259A_lock, flags);
 
 	/* Find out what's interrupting in the PIIX4 master 8259 */
 	outb(0x0c, 0x20);		/* OCW3 Poll command */
@@ -596,7 +590,7 @@ static irqreturn_t piix4_master_intr(int
 		outb(0x60 + realirq, 0x20);
 	}
 
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 
 	desc = irq_to_desc(realirq);
 
@@ -609,12 +603,12 @@ static irqreturn_t piix4_master_intr(int
 		handle_IRQ_event(realirq, desc->action);
 
 	if (!(desc->status & IRQ_DISABLED))
-		enable_8259A_irq(realirq);
+		legacy_pic->chip->unmask(realirq);
 
 	return IRQ_HANDLED;
 
 out_unlock:
-	spin_unlock_irqrestore(&i8259A_lock, flags);
+	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 	return IRQ_NONE;
 }
 
@@ -628,6 +622,12 @@ static struct irqaction cascade_action =
 	.name =		"cascade",
 };
 
+static inline void set_piix4_virtual_irq_type(void)
+{
+	piix4_virtual_irq_type.shutdown = i8259A_chip.mask;
+	piix4_virtual_irq_type.enable =	i8259A_chip.unmask;
+	piix4_virtual_irq_type.disable = i8259A_chip.mask;
+}
 
 void init_VISWS_APIC_irqs(void)
 {
@@ -653,6 +653,7 @@ void init_VISWS_APIC_irqs(void)
 			desc->chip = &piix4_master_irq_type;
 		}
 		else if (i < CO_IRQ_APIC0) {
+			set_piix4_virtual_irq_type();
 			desc->chip = &piix4_virtual_irq_type;
 		}
 		else if (IS_CO_APIC(i)) {
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/vmi_32.c linux-libre-2.6.34-gnu1/arch/x86/kernel/vmi_32.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/vmi_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/vmi_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,11 +28,13 @@
 #include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/sched.h>
+#include <linux/gfp.h>
 #include <asm/vmi.h>
 #include <asm/io.h>
 #include <asm/fixmap.h>
 #include <asm/apicdef.h>
 #include <asm/apic.h>
+#include <asm/pgalloc.h>
 #include <asm/processor.h>
 #include <asm/timer.h>
 #include <asm/vmi_time.h>
@@ -266,30 +268,6 @@ static void vmi_nop(void)
 {
 }
 
-#ifdef CONFIG_HIGHPTE
-static void *vmi_kmap_atomic_pte(struct page *page, enum km_type type)
-{
-	void *va = kmap_atomic(page, type);
-
-	/*
-	 * Internally, the VMI ROM must map virtual addresses to physical
-	 * addresses for processing MMU updates.  By the time MMU updates
-	 * are issued, this information is typically already lost.
-	 * Fortunately, the VMI provides a cache of mapping slots for active
-	 * page tables.
-	 *
-	 * We use slot zero for the linear mapping of physical memory, and
-	 * in HIGHPTE kernels, slot 1 and 2 for KM_PTE0 and KM_PTE1.
-	 *
-	 *  args:                 SLOT                 VA    COUNT PFN
-	 */
-	BUG_ON(type != KM_PTE0 && type != KM_PTE1);
-	vmi_ops.set_linear_mapping((type - KM_PTE0)+1, va, 1, page_to_pfn(page));
-
-	return va;
-}
-#endif
-
 static void vmi_allocate_pte(struct mm_struct *mm, unsigned long pfn)
 {
 	vmi_ops.allocate_page(pfn, VMI_PAGE_L1, 0, 0, 0);
@@ -640,6 +618,12 @@ static inline int __init activate_vmi(vo
 	u64 reloc;
 	const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
 
+	/*
+	 * Prevent page tables from being allocated in highmem, even if
+	 * CONFIG_HIGHPTE is enabled.
+	 */
+	__userpte_alloc_gfp &= ~__GFP_HIGHMEM;
+
 	if (call_vrom_func(vmi_rom, vmi_init) != 0) {
 		printk(KERN_ERR "VMI ROM failed to initialize!");
 		return 0;
@@ -778,10 +762,6 @@ static inline int __init activate_vmi(vo
 
 	/* Set linear is needed in all cases */
 	vmi_ops.set_linear_mapping = vmi_get_function(VMI_CALL_SetLinearMapping);
-#ifdef CONFIG_HIGHPTE
-	if (vmi_ops.set_linear_mapping)
-		pv_mmu_ops.kmap_atomic_pte = vmi_kmap_atomic_pte;
-#endif
 
 	/*
 	 * These MUST always be patched.  Don't support indirect jumps
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/vmiclock_32.c linux-libre-2.6.34-gnu1/arch/x86/kernel/vmiclock_32.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/vmiclock_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/vmiclock_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -79,11 +79,7 @@ unsigned long vmi_tsc_khz(void)
 
 static inline unsigned int vmi_get_timer_vector(void)
 {
-#ifdef CONFIG_X86_IO_APIC
-	return FIRST_DEVICE_VECTOR;
-#else
-	return FIRST_EXTERNAL_VECTOR;
-#endif
+	return IRQ0_VECTOR;
 }
 
 /** vmi clockchip */
@@ -171,7 +167,7 @@ static int vmi_timer_next_event(unsigned
 {
 	/* Unfortunately, set_next_event interface only passes relative
 	 * expiry, but we want absolute expiry.  It'd be better if were
-	 * were passed an aboslute expiry, since a bunch of time may
+	 * were passed an absolute expiry, since a bunch of time may
 	 * have been stolen between the time the delta is computed and
 	 * when we set the alarm below. */
 	cycle_t now = vmi_timer_ops.get_cycle_counter(vmi_counter(VMI_ONESHOT));
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/vmlinux.lds.S linux-libre-2.6.34-gnu1/arch/x86/kernel/vmlinux.lds.S
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/vmlinux.lds.S	2010-05-16 17:17:36.000000000 -0400
@@ -291,8 +291,8 @@ SECTIONS
 	.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
 		__smp_locks = .;
 		*(.smp_locks)
-		__smp_locks_end = .;
 		. = ALIGN(PAGE_SIZE);
+		__smp_locks_end = .;
 	}
 
 #ifdef CONFIG_X86_64
@@ -341,7 +341,7 @@ SECTIONS
  * 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
+#define INIT_PER_CPU(x) init_per_cpu__##x = x + __per_cpu_load
 INIT_PER_CPU(gdt_page);
 INIT_PER_CPU(irq_stack_union);
 
@@ -352,7 +352,7 @@ INIT_PER_CPU(irq_stack_union);
 	   "kernel image bigger than KERNEL_IMAGE_SIZE");
 
 #ifdef CONFIG_SMP
-. = ASSERT((per_cpu__irq_stack_union == 0),
+. = ASSERT((irq_stack_union == 0),
            "irq_stack_union is not at start of per-cpu area");
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/vsyscall_64.c linux-libre-2.6.34-gnu1/arch/x86/kernel/vsyscall_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/vsyscall_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/vsyscall_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -301,7 +301,8 @@ static int __init vsyscall_init(void)
 	register_sysctl_table(kernel_root_table2);
 #endif
 	on_each_cpu(cpu_vsyscall_init, NULL, 1);
-	hotcpu_notifier(cpu_vsyscall_notifier, 0);
+	/* notifier priority > KVM */
+	hotcpu_notifier(cpu_vsyscall_notifier, 30);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/x8664_ksyms_64.c linux-libre-2.6.34-gnu1/arch/x86/kernel/x8664_ksyms_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/x8664_ksyms_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/x8664_ksyms_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,8 @@ EXPORT_SYMBOL(__put_user_2);
 EXPORT_SYMBOL(__put_user_4);
 EXPORT_SYMBOL(__put_user_8);
 
-EXPORT_SYMBOL(copy_user_generic);
+EXPORT_SYMBOL(copy_user_generic_string);
+EXPORT_SYMBOL(copy_user_generic_unrolled);
 EXPORT_SYMBOL(__copy_user_nocache);
 EXPORT_SYMBOL(_copy_from_user);
 EXPORT_SYMBOL(_copy_to_user);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/x86_init.c linux-libre-2.6.34-gnu1/arch/x86/kernel/x86_init.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/x86_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/x86_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,9 +4,11 @@
  *  For licencing details see kernel-base/COPYING
  */
 #include <linux/init.h>
+#include <linux/ioport.h>
 
 #include <asm/bios_ebda.h>
 #include <asm/paravirt.h>
+#include <asm/pci_x86.h>
 #include <asm/mpspec.h>
 #include <asm/setup.h>
 #include <asm/apic.h>
@@ -70,16 +72,25 @@ struct x86_init_ops x86_init __initdata
 	.iommu = {
 		.iommu_init		= iommu_init_noop,
 	},
+
+	.pci = {
+		.init			= x86_default_pci_init,
+		.init_irq		= x86_default_pci_init_irq,
+		.fixup_irqs		= x86_default_pci_fixup_irqs,
+	},
 };
 
 struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = {
 	.setup_percpu_clockev		= setup_secondary_APIC_clock,
 };
 
+static void default_nmi_init(void) { };
+
 struct x86_platform_ops x86_platform = {
 	.calibrate_tsc			= native_calibrate_tsc,
 	.get_wallclock			= mach_get_cmos_time,
 	.set_wallclock			= mach_set_rtc_mmss,
 	.iommu_shutdown			= iommu_shutdown_noop,
 	.is_untracked_pat_range		= is_ISA_range,
+	.nmi_init			= default_nmi_init
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kernel/xsave.c linux-libre-2.6.34-gnu1/arch/x86/kernel/xsave.c
--- linux-libre-2.6.33-gnu1/arch/x86/kernel/xsave.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kernel/xsave.c	2010-05-16 17:17:36.000000000 -0400
@@ -337,6 +337,7 @@ void __ref xsave_cntxt_init(void)
 	cpuid_count(0xd, 0, &eax, &ebx, &ecx, &edx);
 	xstate_size = ebx;
 
+	update_regset_xstate_info(xstate_size, pcntxt_mask);
 	prepare_fx_sw_frame();
 
 	setup_xstate_init();
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/emulate.c linux-libre-2.6.34-gnu1/arch/x86/kvm/emulate.c
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/emulate.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/emulate.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,7 @@
 #include <linux/module.h>
 #include <asm/kvm_emulate.h>
 
-#include "mmu.h"		/* for is_long_mode() */
+#include "x86.h"
 
 /*
  * Opcode effective-address decode tables.
@@ -76,6 +76,8 @@
 #define GroupDual   (1<<15)     /* Alternate decoding of mod == 3 */
 #define GroupMask   0xff        /* Group number stored in bits 0:7 */
 /* Misc flags */
+#define Lock        (1<<26) /* lock prefix is allowed for the instruction */
+#define Priv        (1<<27) /* instruction generates #GP if current CPL != 0 */
 #define No64	    (1<<28)
 /* Source 2 operand type */
 #define Src2None    (0<<29)
@@ -88,39 +90,40 @@
 enum {
 	Group1_80, Group1_81, Group1_82, Group1_83,
 	Group1A, Group3_Byte, Group3, Group4, Group5, Group7,
+	Group8, Group9,
 };
 
 static u32 opcode_table[256] = {
 	/* 0x00 - 0x07 */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
 	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
 	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
 	ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
 	/* 0x08 - 0x0F */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
 	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
 	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
 	ImplicitOps | Stack | No64, 0,
 	/* 0x10 - 0x17 */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
 	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
 	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
 	ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
 	/* 0x18 - 0x1F */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
 	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
 	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
 	ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
 	/* 0x20 - 0x27 */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
 	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
 	DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0,
 	/* 0x28 - 0x2F */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
 	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
 	0, 0, 0, 0,
 	/* 0x30 - 0x37 */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
 	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
 	0, 0, 0, 0,
 	/* 0x38 - 0x3F */
@@ -156,7 +159,7 @@ static u32 opcode_table[256] = {
 	Group | Group1_80, Group | Group1_81,
 	Group | Group1_82, Group | Group1_83,
 	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
 	/* 0x88 - 0x8F */
 	ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov,
 	ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
@@ -210,7 +213,7 @@ static u32 opcode_table[256] = {
 	SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
 	/* 0xF0 - 0xF7 */
 	0, 0, 0, 0,
-	ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3,
+	ImplicitOps | Priv, ImplicitOps, Group | Group3_Byte, Group | Group3,
 	/* 0xF8 - 0xFF */
 	ImplicitOps, 0, ImplicitOps, ImplicitOps,
 	ImplicitOps, ImplicitOps, Group | Group4, Group | Group5,
@@ -218,16 +221,20 @@ static u32 opcode_table[256] = {
 
 static u32 twobyte_table[256] = {
 	/* 0x00 - 0x0F */
-	0, Group | GroupDual | Group7, 0, 0, 0, ImplicitOps, ImplicitOps, 0,
-	ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0,
+	0, Group | GroupDual | Group7, 0, 0,
+	0, ImplicitOps, ImplicitOps | Priv, 0,
+	ImplicitOps | Priv, ImplicitOps | Priv, 0, 0,
+	0, ImplicitOps | ModRM, 0, 0,
 	/* 0x10 - 0x1F */
 	0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0,
 	/* 0x20 - 0x2F */
-	ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0,
+	ModRM | ImplicitOps | Priv, ModRM | Priv,
+	ModRM | ImplicitOps | Priv, ModRM | Priv,
+	0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	/* 0x30 - 0x3F */
-	ImplicitOps, 0, ImplicitOps, 0,
-	ImplicitOps, ImplicitOps, 0, 0,
+	ImplicitOps | Priv, 0, ImplicitOps | Priv, 0,
+	ImplicitOps, ImplicitOps | Priv, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	/* 0x40 - 0x47 */
 	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
@@ -257,21 +264,23 @@ static u32 twobyte_table[256] = {
 	DstMem | SrcReg | Src2CL | ModRM, 0, 0,
 	/* 0xA8 - 0xAF */
 	ImplicitOps | Stack, ImplicitOps | Stack,
-	0, DstMem | SrcReg | ModRM | BitOp,
+	0, DstMem | SrcReg | ModRM | BitOp | Lock,
 	DstMem | SrcReg | Src2ImmByte | ModRM,
 	DstMem | SrcReg | Src2CL | ModRM,
 	ModRM, 0,
 	/* 0xB0 - 0xB7 */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 0,
-	    DstMem | SrcReg | ModRM | BitOp,
+	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
+	0, DstMem | SrcReg | ModRM | BitOp | Lock,
 	0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
 	    DstReg | SrcMem16 | ModRM | Mov,
 	/* 0xB8 - 0xBF */
-	0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM | BitOp,
+	0, 0,
+	Group | Group8, DstMem | SrcReg | ModRM | BitOp | Lock,
 	0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
 	    DstReg | SrcMem16 | ModRM | Mov,
 	/* 0xC0 - 0xCF */
-	0, 0, 0, DstMem | SrcReg | ModRM | Mov, 0, 0, 0, ImplicitOps | ModRM,
+	0, 0, 0, DstMem | SrcReg | ModRM | Mov,
+	0, 0, 0, Group | GroupDual | Group9,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	/* 0xD0 - 0xDF */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -283,25 +292,41 @@ static u32 twobyte_table[256] = {
 
 static u32 group_table[] = {
 	[Group1_80*8] =
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
+	ByteOp | DstMem | SrcImm | ModRM | Lock,
+	ByteOp | DstMem | SrcImm | ModRM | Lock,
+	ByteOp | DstMem | SrcImm | ModRM | Lock,
+	ByteOp | DstMem | SrcImm | ModRM | Lock,
+	ByteOp | DstMem | SrcImm | ModRM | Lock,
+	ByteOp | DstMem | SrcImm | ModRM | Lock,
+	ByteOp | DstMem | SrcImm | ModRM | Lock,
+	ByteOp | DstMem | SrcImm | ModRM,
 	[Group1_81*8] =
-	DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
-	DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
-	DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
-	DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
+	DstMem | SrcImm | ModRM | Lock,
+	DstMem | SrcImm | ModRM | Lock,
+	DstMem | SrcImm | ModRM | Lock,
+	DstMem | SrcImm | ModRM | Lock,
+	DstMem | SrcImm | ModRM | Lock,
+	DstMem | SrcImm | ModRM | Lock,
+	DstMem | SrcImm | ModRM | Lock,
+	DstMem | SrcImm | ModRM,
 	[Group1_82*8] =
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
+	ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
+	ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
+	ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
+	ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
+	ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
+	ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
+	ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
+	ByteOp | DstMem | SrcImm | ModRM | No64,
 	[Group1_83*8] =
-	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
-	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
-	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
-	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
+	DstMem | SrcImmByte | ModRM | Lock,
+	DstMem | SrcImmByte | ModRM | Lock,
+	DstMem | SrcImmByte | ModRM | Lock,
+	DstMem | SrcImmByte | ModRM | Lock,
+	DstMem | SrcImmByte | ModRM | Lock,
+	DstMem | SrcImmByte | ModRM | Lock,
+	DstMem | SrcImmByte | ModRM | Lock,
+	DstMem | SrcImmByte | ModRM,
 	[Group1A*8] =
 	DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0,
 	[Group3_Byte*8] =
@@ -320,24 +345,39 @@ static u32 group_table[] = {
 	SrcMem | ModRM | Stack, 0,
 	SrcMem | ModRM | Stack, 0, SrcMem | ModRM | Stack, 0,
 	[Group7*8] =
-	0, 0, ModRM | SrcMem, ModRM | SrcMem,
+	0, 0, ModRM | SrcMem | Priv, ModRM | SrcMem | Priv,
 	SrcNone | ModRM | DstMem | Mov, 0,
-	SrcMem16 | ModRM | Mov, SrcMem | ModRM | ByteOp,
+	SrcMem16 | ModRM | Mov | Priv, SrcMem | ModRM | ByteOp | Priv,
+	[Group8*8] =
+	0, 0, 0, 0,
+	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM | Lock,
+	DstMem | SrcImmByte | ModRM | Lock, DstMem | SrcImmByte | ModRM | Lock,
+	[Group9*8] =
+	0, ImplicitOps | ModRM | Lock, 0, 0, 0, 0, 0, 0,
 };
 
 static u32 group2_table[] = {
 	[Group7*8] =
-	SrcNone | ModRM, 0, 0, SrcNone | ModRM,
+	SrcNone | ModRM | Priv, 0, 0, SrcNone | ModRM,
 	SrcNone | ModRM | DstMem | Mov, 0,
 	SrcMem16 | ModRM | Mov, 0,
+	[Group9*8] =
+	0, 0, 0, 0, 0, 0, 0, 0,
 };
 
 /* EFLAGS bit definitions. */
+#define EFLG_ID (1<<21)
+#define EFLG_VIP (1<<20)
+#define EFLG_VIF (1<<19)
+#define EFLG_AC (1<<18)
 #define EFLG_VM (1<<17)
 #define EFLG_RF (1<<16)
+#define EFLG_IOPL (3<<12)
+#define EFLG_NT (1<<14)
 #define EFLG_OF (1<<11)
 #define EFLG_DF (1<<10)
 #define EFLG_IF (1<<9)
+#define EFLG_TF (1<<8)
 #define EFLG_SF (1<<7)
 #define EFLG_ZF (1<<6)
 #define EFLG_AF (1<<4)
@@ -606,7 +646,7 @@ static int do_fetch_insn_byte(struct x86
 
 	if (linear < fc->start || linear >= fc->end) {
 		size = min(15UL, PAGE_SIZE - offset_in_page(linear));
-		rc = ops->read_std(linear, fc->data, size, ctxt->vcpu);
+		rc = ops->fetch(linear, fc->data, size, ctxt->vcpu, NULL);
 		if (rc)
 			return rc;
 		fc->start = linear;
@@ -661,11 +701,11 @@ static int read_descriptor(struct x86_em
 		op_bytes = 3;
 	*address = 0;
 	rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2,
-			   ctxt->vcpu);
+			   ctxt->vcpu, NULL);
 	if (rc)
 		return rc;
 	rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes,
-			   ctxt->vcpu);
+			   ctxt->vcpu, NULL);
 	return rc;
 }
 
@@ -889,6 +929,7 @@ x86_decode_insn(struct x86_emulate_ctxt
 
 	switch (mode) {
 	case X86EMUL_MODE_REAL:
+	case X86EMUL_MODE_VM86:
 	case X86EMUL_MODE_PROT16:
 		def_op_bytes = def_ad_bytes = 2;
 		break;
@@ -975,7 +1016,7 @@ done_prefixes:
 	}
 
 	if (mode == X86EMUL_MODE_PROT64 && (c->d & No64)) {
-		kvm_report_emulation_failure(ctxt->vcpu, "invalid x86/64 instruction");;
+		kvm_report_emulation_failure(ctxt->vcpu, "invalid x86/64 instruction");
 		return -1;
 	}
 
@@ -1196,13 +1237,56 @@ static int emulate_pop(struct x86_emulat
 	rc = ops->read_emulated(register_address(c, ss_base(ctxt),
 						 c->regs[VCPU_REGS_RSP]),
 				dest, len, ctxt->vcpu);
-	if (rc != 0)
+	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
 	register_address_increment(c, &c->regs[VCPU_REGS_RSP], len);
 	return rc;
 }
 
+static int emulate_popf(struct x86_emulate_ctxt *ctxt,
+		       struct x86_emulate_ops *ops,
+		       void *dest, int len)
+{
+	int rc;
+	unsigned long val, change_mask;
+	int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
+	int cpl = kvm_x86_ops->get_cpl(ctxt->vcpu);
+
+	rc = emulate_pop(ctxt, ops, &val, len);
+	if (rc != X86EMUL_CONTINUE)
+		return rc;
+
+	change_mask = EFLG_CF | EFLG_PF | EFLG_AF | EFLG_ZF | EFLG_SF | EFLG_OF
+		| EFLG_TF | EFLG_DF | EFLG_NT | EFLG_RF | EFLG_AC | EFLG_ID;
+
+	switch(ctxt->mode) {
+	case X86EMUL_MODE_PROT64:
+	case X86EMUL_MODE_PROT32:
+	case X86EMUL_MODE_PROT16:
+		if (cpl == 0)
+			change_mask |= EFLG_IOPL;
+		if (cpl <= iopl)
+			change_mask |= EFLG_IF;
+		break;
+	case X86EMUL_MODE_VM86:
+		if (iopl < 3) {
+			kvm_inject_gp(ctxt->vcpu, 0);
+			return X86EMUL_PROPAGATE_FAULT;
+		}
+		change_mask |= EFLG_IF;
+		break;
+	default: /* real mode */
+		change_mask |= (EFLG_IOPL | EFLG_IF);
+		break;
+	}
+
+	*(unsigned long *)dest =
+		(ctxt->eflags & ~change_mask) | (val & change_mask);
+
+	return rc;
+}
+
 static void emulate_push_sreg(struct x86_emulate_ctxt *ctxt, int seg)
 {
 	struct decode_cache *c = &ctxt->decode;
@@ -1225,7 +1309,7 @@ static int emulate_pop_sreg(struct x86_e
 	if (rc != 0)
 		return rc;
 
-	rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, 1, seg);
+	rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, seg);
 	return rc;
 }
 
@@ -1370,7 +1454,7 @@ static inline int emulate_grp9(struct x8
 	int rc;
 
 	rc = ops->read_emulated(memop, &old, 8, ctxt->vcpu);
-	if (rc != 0)
+	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
 	if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) ||
@@ -1385,7 +1469,7 @@ static inline int emulate_grp9(struct x8
 		       (u32) c->regs[VCPU_REGS_RBX];
 
 		rc = ops->cmpxchg_emulated(memop, &old, &new, 8, ctxt->vcpu);
-		if (rc != 0)
+		if (rc != X86EMUL_CONTINUE)
 			return rc;
 		ctxt->eflags |= EFLG_ZF;
 	}
@@ -1407,7 +1491,7 @@ static int emulate_ret_far(struct x86_em
 	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);
+	rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, VCPU_SREG_CS);
 	return rc;
 }
 
@@ -1451,7 +1535,7 @@ static inline int writeback(struct x86_e
 					&c->dst.val,
 					c->dst.bytes,
 					ctxt->vcpu);
-		if (rc != 0)
+		if (rc != X86EMUL_CONTINUE)
 			return rc;
 		break;
 	case OP_NONE:
@@ -1514,9 +1598,8 @@ emulate_syscall(struct x86_emulate_ctxt
 	u64 msr_data;
 
 	/* syscall is not available in real mode */
-	if (c->lock_prefix || ctxt->mode == X86EMUL_MODE_REAL
-		|| !(ctxt->vcpu->arch.cr0 & X86_CR0_PE))
-		return -1;
+	if (ctxt->mode == X86EMUL_MODE_REAL || ctxt->mode == X86EMUL_MODE_VM86)
+		return X86EMUL_UNHANDLEABLE;
 
 	setup_syscalls_segments(ctxt, &cs, &ss);
 
@@ -1553,7 +1636,7 @@ emulate_syscall(struct x86_emulate_ctxt
 		ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF);
 	}
 
-	return 0;
+	return X86EMUL_CONTINUE;
 }
 
 static int
@@ -1563,22 +1646,17 @@ emulate_sysenter(struct x86_emulate_ctxt
 	struct kvm_segment cs, ss;
 	u64 msr_data;
 
-	/* inject #UD if LOCK prefix is used */
-	if (c->lock_prefix)
-		return -1;
-
-	/* inject #GP if in real mode or paging is disabled */
-	if (ctxt->mode == X86EMUL_MODE_REAL ||
-		!(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) {
+	/* inject #GP if in real mode */
+	if (ctxt->mode == X86EMUL_MODE_REAL) {
 		kvm_inject_gp(ctxt->vcpu, 0);
-		return -1;
+		return X86EMUL_UNHANDLEABLE;
 	}
 
 	/* XXX sysenter/sysexit have not been tested in 64bit mode.
 	* Therefore, we inject an #UD.
 	*/
 	if (ctxt->mode == X86EMUL_MODE_PROT64)
-		return -1;
+		return X86EMUL_UNHANDLEABLE;
 
 	setup_syscalls_segments(ctxt, &cs, &ss);
 
@@ -1587,13 +1665,13 @@ emulate_sysenter(struct x86_emulate_ctxt
 	case X86EMUL_MODE_PROT32:
 		if ((msr_data & 0xfffc) == 0x0) {
 			kvm_inject_gp(ctxt->vcpu, 0);
-			return -1;
+			return X86EMUL_PROPAGATE_FAULT;
 		}
 		break;
 	case X86EMUL_MODE_PROT64:
 		if (msr_data == 0x0) {
 			kvm_inject_gp(ctxt->vcpu, 0);
-			return -1;
+			return X86EMUL_PROPAGATE_FAULT;
 		}
 		break;
 	}
@@ -1618,7 +1696,7 @@ emulate_sysenter(struct x86_emulate_ctxt
 	kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_ESP, &msr_data);
 	c->regs[VCPU_REGS_RSP] = msr_data;
 
-	return 0;
+	return X86EMUL_CONTINUE;
 }
 
 static int
@@ -1629,21 +1707,11 @@ emulate_sysexit(struct x86_emulate_ctxt
 	u64 msr_data;
 	int usermode;
 
-	/* inject #UD if LOCK prefix is used */
-	if (c->lock_prefix)
-		return -1;
-
-	/* inject #GP if in real mode or paging is disabled */
-	if (ctxt->mode == X86EMUL_MODE_REAL
-		|| !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) {
-		kvm_inject_gp(ctxt->vcpu, 0);
-		return -1;
-	}
-
-	/* sysexit must be called from CPL 0 */
-	if (kvm_x86_ops->get_cpl(ctxt->vcpu) != 0) {
+	/* inject #GP if in real mode or Virtual 8086 mode */
+	if (ctxt->mode == X86EMUL_MODE_REAL ||
+	    ctxt->mode == X86EMUL_MODE_VM86) {
 		kvm_inject_gp(ctxt->vcpu, 0);
-		return -1;
+		return X86EMUL_UNHANDLEABLE;
 	}
 
 	setup_syscalls_segments(ctxt, &cs, &ss);
@@ -1661,7 +1729,7 @@ emulate_sysexit(struct x86_emulate_ctxt
 		cs.selector = (u16)(msr_data + 16);
 		if ((msr_data & 0xfffc) == 0x0) {
 			kvm_inject_gp(ctxt->vcpu, 0);
-			return -1;
+			return X86EMUL_PROPAGATE_FAULT;
 		}
 		ss.selector = (u16)(msr_data + 24);
 		break;
@@ -1669,7 +1737,7 @@ emulate_sysexit(struct x86_emulate_ctxt
 		cs.selector = (u16)(msr_data + 32);
 		if (msr_data == 0x0) {
 			kvm_inject_gp(ctxt->vcpu, 0);
-			return -1;
+			return X86EMUL_PROPAGATE_FAULT;
 		}
 		ss.selector = cs.selector + 8;
 		cs.db = 0;
@@ -1685,7 +1753,58 @@ emulate_sysexit(struct x86_emulate_ctxt
 	c->eip = ctxt->vcpu->arch.regs[VCPU_REGS_RDX];
 	c->regs[VCPU_REGS_RSP] = ctxt->vcpu->arch.regs[VCPU_REGS_RCX];
 
-	return 0;
+	return X86EMUL_CONTINUE;
+}
+
+static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt)
+{
+	int iopl;
+	if (ctxt->mode == X86EMUL_MODE_REAL)
+		return false;
+	if (ctxt->mode == X86EMUL_MODE_VM86)
+		return true;
+	iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
+	return kvm_x86_ops->get_cpl(ctxt->vcpu) > iopl;
+}
+
+static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt,
+					    struct x86_emulate_ops *ops,
+					    u16 port, u16 len)
+{
+	struct kvm_segment tr_seg;
+	int r;
+	u16 io_bitmap_ptr;
+	u8 perm, bit_idx = port & 0x7;
+	unsigned mask = (1 << len) - 1;
+
+	kvm_get_segment(ctxt->vcpu, &tr_seg, VCPU_SREG_TR);
+	if (tr_seg.unusable)
+		return false;
+	if (tr_seg.limit < 103)
+		return false;
+	r = ops->read_std(tr_seg.base + 102, &io_bitmap_ptr, 2, ctxt->vcpu,
+			  NULL);
+	if (r != X86EMUL_CONTINUE)
+		return false;
+	if (io_bitmap_ptr + port/8 > tr_seg.limit)
+		return false;
+	r = ops->read_std(tr_seg.base + io_bitmap_ptr + port/8, &perm, 1,
+			  ctxt->vcpu, NULL);
+	if (r != X86EMUL_CONTINUE)
+		return false;
+	if ((perm >> bit_idx) & mask)
+		return false;
+	return true;
+}
+
+static bool emulator_io_permited(struct x86_emulate_ctxt *ctxt,
+				 struct x86_emulate_ops *ops,
+				 u16 port, u16 len)
+{
+	if (emulator_bad_iopl(ctxt))
+		if (!emulator_io_port_access_allowed(ctxt, ops, port, len))
+			return false;
+	return true;
 }
 
 int
@@ -1709,6 +1828,18 @@ x86_emulate_insn(struct x86_emulate_ctxt
 	memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
 	saved_eip = c->eip;
 
+	/* LOCK prefix is allowed only with some instructions */
+	if (c->lock_prefix && !(c->d & Lock)) {
+		kvm_queue_exception(ctxt->vcpu, UD_VECTOR);
+		goto done;
+	}
+
+	/* Privileged instruction can be executed only in CPL=0 */
+	if ((c->d & Priv) && kvm_x86_ops->get_cpl(ctxt->vcpu)) {
+		kvm_inject_gp(ctxt->vcpu, 0);
+		goto done;
+	}
+
 	if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs))
 		memop = c->modrm_ea;
 
@@ -1749,7 +1880,7 @@ x86_emulate_insn(struct x86_emulate_ctxt
 					&c->src.val,
 					c->src.bytes,
 					ctxt->vcpu);
-		if (rc != 0)
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		c->src.orig_val = c->src.val;
 	}
@@ -1768,12 +1899,15 @@ x86_emulate_insn(struct x86_emulate_ctxt
 			c->dst.ptr = (void *)c->dst.ptr +
 						   (c->src.val & mask) / 8;
 		}
-		if (!(c->d & Mov) &&
-				   /* optimisation - avoid slow emulated read */
-		    ((rc = ops->read_emulated((unsigned long)c->dst.ptr,
-					   &c->dst.val,
-					  c->dst.bytes, ctxt->vcpu)) != 0))
-			goto done;
+		if (!(c->d & Mov)) {
+			/* optimisation - avoid slow emulated read */
+			rc = ops->read_emulated((unsigned long)c->dst.ptr,
+						&c->dst.val,
+						c->dst.bytes,
+						ctxt->vcpu);
+			if (rc != X86EMUL_CONTINUE)
+				goto done;
+		}
 	}
 	c->dst.orig_val = c->dst.val;
 
@@ -1876,7 +2010,12 @@ special_insn:
 		break;
 	case 0x6c:		/* insb */
 	case 0x6d:		/* insw/insd */
-		 if (kvm_emulate_pio_string(ctxt->vcpu,
+		if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX],
+					  (c->d & ByteOp) ? 1 : c->op_bytes)) {
+			kvm_inject_gp(ctxt->vcpu, 0);
+			goto done;
+		}
+		if (kvm_emulate_pio_string(ctxt->vcpu,
 				1,
 				(c->d & ByteOp) ? 1 : c->op_bytes,
 				c->rep_prefix ?
@@ -1892,6 +2031,11 @@ special_insn:
 		return 0;
 	case 0x6e:		/* outsb */
 	case 0x6f:		/* outsw/outsd */
+		if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX],
+					  (c->d & ByteOp) ? 1 : c->op_bytes)) {
+			kvm_inject_gp(ctxt->vcpu, 0);
+			goto done;
+		}
 		if (kvm_emulate_pio_string(ctxt->vcpu,
 				0,
 				(c->d & ByteOp) ? 1 : c->op_bytes,
@@ -1978,25 +2122,19 @@ special_insn:
 		break;
 	case 0x8e: { /* mov seg, r/m16 */
 		uint16_t sel;
-		int type_bits;
-		int err;
 
 		sel = c->src.val;
-		if (c->modrm_reg == VCPU_SREG_SS)
-			toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS);
 
-		if (c->modrm_reg <= 5) {
-			type_bits = (c->modrm_reg == 1) ? 9 : 1;
-			err = kvm_load_segment_descriptor(ctxt->vcpu, sel,
-							  type_bits, c->modrm_reg);
-		} else {
-			printk(KERN_INFO "Invalid segreg in modrm byte 0x%02x\n",
-					c->modrm);
-			goto cannot_emulate;
+		if (c->modrm_reg == VCPU_SREG_CS ||
+		    c->modrm_reg > VCPU_SREG_GS) {
+			kvm_queue_exception(ctxt->vcpu, UD_VECTOR);
+			goto done;
 		}
 
-		if (err < 0)
-			goto cannot_emulate;
+		if (c->modrm_reg == VCPU_SREG_SS)
+			toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS);
+
+		rc = kvm_load_segment_descriptor(ctxt->vcpu, sel, c->modrm_reg);
 
 		c->dst.type = OP_NONE;  /* Disable writeback. */
 		break;
@@ -2025,7 +2163,10 @@ special_insn:
 		c->dst.type = OP_REG;
 		c->dst.ptr = (unsigned long *) &ctxt->eflags;
 		c->dst.bytes = c->op_bytes;
-		goto pop_instruction;
+		rc = emulate_popf(ctxt, ops, &c->dst.val, c->op_bytes);
+		if (rc != X86EMUL_CONTINUE)
+			goto done;
+		break;
 	case 0xa0 ... 0xa1:	/* mov */
 		c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
 		c->dst.val = c->src.val;
@@ -2039,11 +2180,12 @@ special_insn:
 		c->dst.ptr = (unsigned long *)register_address(c,
 						   es_base(ctxt),
 						   c->regs[VCPU_REGS_RDI]);
-		if ((rc = ops->read_emulated(register_address(c,
-					   seg_override_base(ctxt, c),
-					c->regs[VCPU_REGS_RSI]),
+		rc = ops->read_emulated(register_address(c,
+						seg_override_base(ctxt, c),
+						c->regs[VCPU_REGS_RSI]),
 					&c->dst.val,
-					c->dst.bytes, ctxt->vcpu)) != 0)
+					c->dst.bytes, ctxt->vcpu);
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		register_address_increment(c, &c->regs[VCPU_REGS_RSI],
 				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
@@ -2058,10 +2200,11 @@ special_insn:
 		c->src.ptr = (unsigned long *)register_address(c,
 				       seg_override_base(ctxt, c),
 						   c->regs[VCPU_REGS_RSI]);
-		if ((rc = ops->read_emulated((unsigned long)c->src.ptr,
-						&c->src.val,
-						c->src.bytes,
-						ctxt->vcpu)) != 0)
+		rc = ops->read_emulated((unsigned long)c->src.ptr,
+					&c->src.val,
+					c->src.bytes,
+					ctxt->vcpu);
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 
 		c->dst.type = OP_NONE; /* Disable writeback. */
@@ -2069,10 +2212,11 @@ special_insn:
 		c->dst.ptr = (unsigned long *)register_address(c,
 						   es_base(ctxt),
 						   c->regs[VCPU_REGS_RDI]);
-		if ((rc = ops->read_emulated((unsigned long)c->dst.ptr,
-						&c->dst.val,
-						c->dst.bytes,
-						ctxt->vcpu)) != 0)
+		rc = ops->read_emulated((unsigned long)c->dst.ptr,
+					&c->dst.val,
+					c->dst.bytes,
+					ctxt->vcpu);
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 
 		DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.ptr, c->dst.ptr);
@@ -2102,12 +2246,13 @@ special_insn:
 		c->dst.type = OP_REG;
 		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
 		c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
-		if ((rc = ops->read_emulated(register_address(c,
-						 seg_override_base(ctxt, c),
-						 c->regs[VCPU_REGS_RSI]),
-						 &c->dst.val,
-						 c->dst.bytes,
-						 ctxt->vcpu)) != 0)
+		rc = ops->read_emulated(register_address(c,
+						seg_override_base(ctxt, c),
+						c->regs[VCPU_REGS_RSI]),
+					&c->dst.val,
+					c->dst.bytes,
+					ctxt->vcpu);
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		register_address_increment(c, &c->regs[VCPU_REGS_RSI],
 				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
@@ -2163,11 +2308,9 @@ special_insn:
 	case 0xe9: /* jmp rel */
 		goto jmp;
 	case 0xea: /* jmp far */
-		if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val, 9,
-					VCPU_SREG_CS) < 0) {
-			DPRINTF("jmp far: Failed to load CS descriptor\n");
-			goto cannot_emulate;
-		}
+		if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val,
+						VCPU_SREG_CS))
+			goto done;
 
 		c->eip = c->src.val;
 		break;
@@ -2185,7 +2328,13 @@ special_insn:
 	case 0xef: /* out (e/r)ax,dx */
 		port = c->regs[VCPU_REGS_RDX];
 		io_dir_in = 0;
-	do_io:	if (kvm_emulate_pio(ctxt->vcpu, io_dir_in,
+	do_io:
+		if (!emulator_io_permited(ctxt, ops, port,
+					  (c->d & ByteOp) ? 1 : c->op_bytes)) {
+			kvm_inject_gp(ctxt->vcpu, 0);
+			goto done;
+		}
+		if (kvm_emulate_pio(ctxt->vcpu, io_dir_in,
 				   (c->d & ByteOp) ? 1 : c->op_bytes,
 				   port) != 0) {
 			c->eip = saved_eip;
@@ -2210,13 +2359,21 @@ special_insn:
 		c->dst.type = OP_NONE;	/* Disable writeback. */
 		break;
 	case 0xfa: /* cli */
-		ctxt->eflags &= ~X86_EFLAGS_IF;
-		c->dst.type = OP_NONE;	/* Disable writeback. */
+		if (emulator_bad_iopl(ctxt))
+			kvm_inject_gp(ctxt->vcpu, 0);
+		else {
+			ctxt->eflags &= ~X86_EFLAGS_IF;
+			c->dst.type = OP_NONE;	/* Disable writeback. */
+		}
 		break;
 	case 0xfb: /* sti */
-		toggle_interruptibility(ctxt, X86_SHADOW_INT_STI);
-		ctxt->eflags |= X86_EFLAGS_IF;
-		c->dst.type = OP_NONE;	/* Disable writeback. */
+		if (emulator_bad_iopl(ctxt))
+			kvm_inject_gp(ctxt->vcpu, 0);
+		else {
+			toggle_interruptibility(ctxt, X86_SHADOW_INT_STI);
+			ctxt->eflags |= X86_EFLAGS_IF;
+			c->dst.type = OP_NONE;	/* Disable writeback. */
+		}
 		break;
 	case 0xfc: /* cld */
 		ctxt->eflags &= ~EFLG_DF;
@@ -2319,8 +2476,9 @@ twobyte_insn:
 		}
 		break;
 	case 0x05: 		/* syscall */
-		if (emulate_syscall(ctxt) == -1)
-			goto cannot_emulate;
+		rc = emulate_syscall(ctxt);
+		if (rc != X86EMUL_CONTINUE)
+			goto done;
 		else
 			goto writeback;
 		break;
@@ -2391,14 +2549,16 @@ twobyte_insn:
 		c->dst.type = OP_NONE;
 		break;
 	case 0x34:		/* sysenter */
-		if (emulate_sysenter(ctxt) == -1)
-			goto cannot_emulate;
+		rc = emulate_sysenter(ctxt);
+		if (rc != X86EMUL_CONTINUE)
+			goto done;
 		else
 			goto writeback;
 		break;
 	case 0x35:		/* sysexit */
-		if (emulate_sysexit(ctxt) == -1)
-			goto cannot_emulate;
+		rc = emulate_sysexit(ctxt);
+		if (rc != X86EMUL_CONTINUE)
+			goto done;
 		else
 			goto writeback;
 		break;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/i8254.c linux-libre-2.6.34-gnu1/arch/x86/kvm/i8254.c
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/i8254.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/i8254.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #define pr_fmt(fmt) "pit: " fmt
 
 #include <linux/kvm_host.h>
+#include <linux/slab.h>
 
 #include "irq.h"
 #include "i8254.h"
@@ -242,11 +243,11 @@ static void kvm_pit_ack_irq(struct kvm_i
 {
 	struct kvm_kpit_state *ps = container_of(kian, struct kvm_kpit_state,
 						 irq_ack_notifier);
-	spin_lock(&ps->inject_lock);
+	raw_spin_lock(&ps->inject_lock);
 	if (atomic_dec_return(&ps->pit_timer.pending) < 0)
 		atomic_inc(&ps->pit_timer.pending);
 	ps->irq_ack = 1;
-	spin_unlock(&ps->inject_lock);
+	raw_spin_unlock(&ps->inject_lock);
 }
 
 void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
@@ -605,7 +606,7 @@ static const struct kvm_io_device_ops sp
 	.write    = speaker_ioport_write,
 };
 
-/* Caller must have writers lock on slots_lock */
+/* Caller must hold slots_lock */
 struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
 {
 	struct kvm_pit *pit;
@@ -624,7 +625,7 @@ struct kvm_pit *kvm_create_pit(struct kv
 
 	mutex_init(&pit->pit_state.lock);
 	mutex_lock(&pit->pit_state.lock);
-	spin_lock_init(&pit->pit_state.inject_lock);
+	raw_spin_lock_init(&pit->pit_state.inject_lock);
 
 	kvm->arch.vpit = pit;
 	pit->kvm = kvm;
@@ -645,13 +646,13 @@ struct kvm_pit *kvm_create_pit(struct kv
 	kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
 
 	kvm_iodevice_init(&pit->dev, &pit_dev_ops);
-	ret = __kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev);
+	ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, &pit->dev);
 	if (ret < 0)
 		goto fail;
 
 	if (flags & KVM_PIT_SPEAKER_DUMMY) {
 		kvm_iodevice_init(&pit->speaker_dev, &speaker_dev_ops);
-		ret = __kvm_io_bus_register_dev(&kvm->pio_bus,
+		ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS,
 						&pit->speaker_dev);
 		if (ret < 0)
 			goto fail_unregister;
@@ -660,11 +661,12 @@ struct kvm_pit *kvm_create_pit(struct kv
 	return pit;
 
 fail_unregister:
-	__kvm_io_bus_unregister_dev(&kvm->pio_bus, &pit->dev);
+	kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &pit->dev);
 
 fail:
-	if (pit->irq_source_id >= 0)
-		kvm_free_irq_source_id(kvm, pit->irq_source_id);
+	kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
+	kvm_unregister_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier);
+	kvm_free_irq_source_id(kvm, pit->irq_source_id);
 
 	kfree(pit);
 	return NULL;
@@ -723,12 +725,12 @@ void kvm_inject_pit_timer_irqs(struct kv
 		/* Try to inject pending interrupts when
 		 * last one has been acked.
 		 */
-		spin_lock(&ps->inject_lock);
+		raw_spin_lock(&ps->inject_lock);
 		if (atomic_read(&ps->pit_timer.pending) && ps->irq_ack) {
 			ps->irq_ack = 0;
 			inject = 1;
 		}
-		spin_unlock(&ps->inject_lock);
+		raw_spin_unlock(&ps->inject_lock);
 		if (inject)
 			__inject_pit_timer_intr(kvm);
 	}
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/i8254.h linux-libre-2.6.34-gnu1/arch/x86/kvm/i8254.h
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/i8254.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/i8254.h	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,7 @@ struct kvm_kpit_state {
 	u32    speaker_data_on;
 	struct mutex lock;
 	struct kvm_pit *pit;
-	spinlock_t inject_lock;
+	raw_spinlock_t inject_lock;
 	unsigned long irq_ack;
 	struct kvm_irq_ack_notifier irq_ack_notifier;
 };
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/i8259.c linux-libre-2.6.34-gnu1/arch/x86/kvm/i8259.c
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/i8259.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/i8259.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
  *   Port from Qemu.
  */
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/bitops.h>
 #include "irq.h"
 
@@ -44,18 +45,19 @@ static void pic_clear_isr(struct kvm_kpi
 	 * Other interrupt may be delivered to PIC while lock is dropped but
 	 * it should be safe since PIC state is already updated at this stage.
 	 */
-	spin_unlock(&s->pics_state->lock);
+	raw_spin_unlock(&s->pics_state->lock);
 	kvm_notify_acked_irq(s->pics_state->kvm, SELECT_PIC(irq), irq);
-	spin_lock(&s->pics_state->lock);
+	raw_spin_lock(&s->pics_state->lock);
 }
 
 void kvm_pic_clear_isr_ack(struct kvm *kvm)
 {
 	struct kvm_pic *s = pic_irqchip(kvm);
-	spin_lock(&s->lock);
+
+	raw_spin_lock(&s->lock);
 	s->pics[0].isr_ack = 0xff;
 	s->pics[1].isr_ack = 0xff;
-	spin_unlock(&s->lock);
+	raw_spin_unlock(&s->lock);
 }
 
 /*
@@ -156,9 +158,9 @@ static void pic_update_irq(struct kvm_pi
 
 void kvm_pic_update_irq(struct kvm_pic *s)
 {
-	spin_lock(&s->lock);
+	raw_spin_lock(&s->lock);
 	pic_update_irq(s);
-	spin_unlock(&s->lock);
+	raw_spin_unlock(&s->lock);
 }
 
 int kvm_pic_set_irq(void *opaque, int irq, int level)
@@ -166,14 +168,14 @@ int kvm_pic_set_irq(void *opaque, int ir
 	struct kvm_pic *s = opaque;
 	int ret = -1;
 
-	spin_lock(&s->lock);
+	raw_spin_lock(&s->lock);
 	if (irq >= 0 && irq < PIC_NUM_PINS) {
 		ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
 		pic_update_irq(s);
 		trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr,
 				      s->pics[irq >> 3].imr, ret == 0);
 	}
-	spin_unlock(&s->lock);
+	raw_spin_unlock(&s->lock);
 
 	return ret;
 }
@@ -203,7 +205,7 @@ int kvm_pic_read_irq(struct kvm *kvm)
 	int irq, irq2, intno;
 	struct kvm_pic *s = pic_irqchip(kvm);
 
-	spin_lock(&s->lock);
+	raw_spin_lock(&s->lock);
 	irq = pic_get_irq(&s->pics[0]);
 	if (irq >= 0) {
 		pic_intack(&s->pics[0], irq);
@@ -228,7 +230,7 @@ int kvm_pic_read_irq(struct kvm *kvm)
 		intno = s->pics[0].irq_base + irq;
 	}
 	pic_update_irq(s);
-	spin_unlock(&s->lock);
+	raw_spin_unlock(&s->lock);
 
 	return intno;
 }
@@ -442,7 +444,7 @@ static int picdev_write(struct kvm_io_de
 			printk(KERN_ERR "PIC: non byte write\n");
 		return 0;
 	}
-	spin_lock(&s->lock);
+	raw_spin_lock(&s->lock);
 	switch (addr) {
 	case 0x20:
 	case 0x21:
@@ -455,7 +457,7 @@ static int picdev_write(struct kvm_io_de
 		elcr_ioport_write(&s->pics[addr & 1], addr, data);
 		break;
 	}
-	spin_unlock(&s->lock);
+	raw_spin_unlock(&s->lock);
 	return 0;
 }
 
@@ -472,7 +474,7 @@ static int picdev_read(struct kvm_io_dev
 			printk(KERN_ERR "PIC: non byte read\n");
 		return 0;
 	}
-	spin_lock(&s->lock);
+	raw_spin_lock(&s->lock);
 	switch (addr) {
 	case 0x20:
 	case 0x21:
@@ -486,7 +488,7 @@ static int picdev_read(struct kvm_io_dev
 		break;
 	}
 	*(unsigned char *)val = data;
-	spin_unlock(&s->lock);
+	raw_spin_unlock(&s->lock);
 	return 0;
 }
 
@@ -520,7 +522,7 @@ struct kvm_pic *kvm_create_pic(struct kv
 	s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL);
 	if (!s)
 		return NULL;
-	spin_lock_init(&s->lock);
+	raw_spin_lock_init(&s->lock);
 	s->kvm = kvm;
 	s->pics[0].elcr_mask = 0xf8;
 	s->pics[1].elcr_mask = 0xde;
@@ -533,7 +535,9 @@ struct kvm_pic *kvm_create_pic(struct kv
 	 * Initialize PIO device
 	 */
 	kvm_iodevice_init(&s->dev, &picdev_ops);
-	ret = kvm_io_bus_register_dev(kvm, &kvm->pio_bus, &s->dev);
+	mutex_lock(&kvm->slots_lock);
+	ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, &s->dev);
+	mutex_unlock(&kvm->slots_lock);
 	if (ret < 0) {
 		kfree(s);
 		return NULL;
@@ -541,3 +545,14 @@ struct kvm_pic *kvm_create_pic(struct kv
 
 	return s;
 }
+
+void kvm_destroy_pic(struct kvm *kvm)
+{
+	struct kvm_pic *vpic = kvm->arch.vpic;
+
+	if (vpic) {
+		kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &vpic->dev);
+		kvm->arch.vpic = NULL;
+		kfree(vpic);
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/irq.h linux-libre-2.6.34-gnu1/arch/x86/kvm/irq.h
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/irq.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/irq.h	2010-05-16 17:17:36.000000000 -0400
@@ -62,7 +62,7 @@ struct kvm_kpic_state {
 };
 
 struct kvm_pic {
-	spinlock_t lock;
+	raw_spinlock_t lock;
 	unsigned pending_acks;
 	struct kvm *kvm;
 	struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */
@@ -75,6 +75,7 @@ struct kvm_pic {
 };
 
 struct kvm_pic *kvm_create_pic(struct kvm *kvm);
+void kvm_destroy_pic(struct kvm *kvm);
 int kvm_pic_read_irq(struct kvm *kvm);
 void kvm_pic_update_irq(struct kvm_pic *s);
 void kvm_pic_clear_isr_ack(struct kvm *kvm);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/Kconfig linux-libre-2.6.34-gnu1/arch/x86/kvm/Kconfig
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@ config KVM
 	select HAVE_KVM_EVENTFD
 	select KVM_APIC_ARCHITECTURE
 	select USER_RETURN_NOTIFIER
+	select KVM_MMIO
 	---help---
 	  Support hosting fully virtualized guest machines using hardware
 	  virtualization extensions.  You will need a fairly recent
@@ -65,6 +66,7 @@ config KVM_AMD
 
 # OK, it's a little counter-intuitive to do this, but it puts it neatly under
 # the virtualization menu.
+source drivers/vhost/Kconfig
 source drivers/lguest/Kconfig
 source drivers/virtio/Kconfig
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/kvm_cache_regs.h linux-libre-2.6.34-gnu1/arch/x86/kvm/kvm_cache_regs.h
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/kvm_cache_regs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/kvm_cache_regs.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,11 @@
 #ifndef ASM_KVM_CACHE_REGS_H
 #define ASM_KVM_CACHE_REGS_H
 
+#define KVM_POSSIBLE_CR0_GUEST_BITS X86_CR0_TS
+#define KVM_POSSIBLE_CR4_GUEST_BITS				  \
+	(X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR  \
+	 | X86_CR4_OSXMMEXCPT | X86_CR4_PGE)
+
 static inline unsigned long kvm_register_read(struct kvm_vcpu *vcpu,
 					      enum kvm_reg reg)
 {
@@ -38,4 +43,30 @@ static inline u64 kvm_pdptr_read(struct
 	return vcpu->arch.pdptrs[index];
 }
 
+static inline ulong kvm_read_cr0_bits(struct kvm_vcpu *vcpu, ulong mask)
+{
+	ulong tmask = mask & KVM_POSSIBLE_CR0_GUEST_BITS;
+	if (tmask & vcpu->arch.cr0_guest_owned_bits)
+		kvm_x86_ops->decache_cr0_guest_bits(vcpu);
+	return vcpu->arch.cr0 & mask;
+}
+
+static inline ulong kvm_read_cr0(struct kvm_vcpu *vcpu)
+{
+	return kvm_read_cr0_bits(vcpu, ~0UL);
+}
+
+static inline ulong kvm_read_cr4_bits(struct kvm_vcpu *vcpu, ulong mask)
+{
+	ulong tmask = mask & KVM_POSSIBLE_CR4_GUEST_BITS;
+	if (tmask & vcpu->arch.cr4_guest_owned_bits)
+		kvm_x86_ops->decache_cr4_guest_bits(vcpu);
+	return vcpu->arch.cr4 & mask;
+}
+
+static inline ulong kvm_read_cr4(struct kvm_vcpu *vcpu)
+{
+	return kvm_read_cr4_bits(vcpu, ~0UL);
+}
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/lapic.c linux-libre-2.6.34-gnu1/arch/x86/kvm/lapic.c
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/lapic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/lapic.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/math64.h>
+#include <linux/slab.h>
 #include <asm/processor.h>
 #include <asm/msr.h>
 #include <asm/page.h>
@@ -1243,6 +1244,37 @@ int kvm_x2apic_msr_read(struct kvm_vcpu
 		apic_reg_read(apic, APIC_ICR2, 4, &high);
 
 	*data = (((u64)high) << 32) | low;
+
+	return 0;
+}
+
+int kvm_hv_vapic_msr_write(struct kvm_vcpu *vcpu, u32 reg, u64 data)
+{
+	struct kvm_lapic *apic = vcpu->arch.apic;
+
+	if (!irqchip_in_kernel(vcpu->kvm))
+		return 1;
+
+	/* if this is ICR write vector before command */
+	if (reg == APIC_ICR)
+		apic_reg_write(apic, APIC_ICR2, (u32)(data >> 32));
+	return apic_reg_write(apic, reg, (u32)data);
+}
+
+int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 reg, u64 *data)
+{
+	struct kvm_lapic *apic = vcpu->arch.apic;
+	u32 low, high = 0;
+
+	if (!irqchip_in_kernel(vcpu->kvm))
+		return 1;
+
+	if (apic_reg_read(apic, reg, 4, &low))
+		return 1;
+	if (reg == APIC_ICR)
+		apic_reg_read(apic, APIC_ICR2, 4, &high);
+
+	*data = (((u64)high) << 32) | low;
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/lapic.h linux-libre-2.6.34-gnu1/arch/x86/kvm/lapic.h
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/lapic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/lapic.h	2010-05-16 17:17:36.000000000 -0400
@@ -48,4 +48,12 @@ void kvm_lapic_sync_to_vapic(struct kvm_
 
 int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data);
 int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data);
+
+int kvm_hv_vapic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data);
+int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data);
+
+static inline bool kvm_hv_vapic_assist_page_enabled(struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.hv_vapic & HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE;
+}
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/mmu.c linux-libre-2.6.34-gnu1/arch/x86/kvm/mmu.c
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/mmu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/mmu.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
  */
 
 #include "mmu.h"
+#include "x86.h"
 #include "kvm_cache_regs.h"
 
 #include <linux/kvm_host.h>
@@ -29,6 +30,8 @@
 #include <linux/swap.h>
 #include <linux/hugetlb.h>
 #include <linux/compiler.h>
+#include <linux/srcu.h>
+#include <linux/slab.h>
 
 #include <asm/page.h>
 #include <asm/cmpxchg.h>
@@ -136,16 +139,6 @@ module_param(oos_shadow, bool, 0644);
 #define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK \
 			| PT64_NX_MASK)
 
-#define PFERR_PRESENT_MASK (1U << 0)
-#define PFERR_WRITE_MASK (1U << 1)
-#define PFERR_USER_MASK (1U << 2)
-#define PFERR_RSVD_MASK (1U << 3)
-#define PFERR_FETCH_MASK (1U << 4)
-
-#define PT_PDPE_LEVEL 3
-#define PT_DIRECTORY_LEVEL 2
-#define PT_PAGE_TABLE_LEVEL 1
-
 #define RMAP_EXT 4
 
 #define ACC_EXEC_MASK    1
@@ -153,6 +146,9 @@ module_param(oos_shadow, bool, 0644);
 #define ACC_USER_MASK    PT_USER_MASK
 #define ACC_ALL          (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK)
 
+#include <trace/events/kvm.h>
+
+#undef TRACE_INCLUDE_FILE
 #define CREATE_TRACE_POINTS
 #include "mmutrace.h"
 
@@ -229,7 +225,7 @@ EXPORT_SYMBOL_GPL(kvm_mmu_set_mask_ptes)
 
 static int is_write_protection(struct kvm_vcpu *vcpu)
 {
-	return vcpu->arch.cr0 & X86_CR0_WP;
+	return kvm_read_cr0_bits(vcpu, X86_CR0_WP);
 }
 
 static int is_cpuid_PSE36(void)
@@ -239,7 +235,7 @@ static int is_cpuid_PSE36(void)
 
 static int is_nx(struct kvm_vcpu *vcpu)
 {
-	return vcpu->arch.shadow_efer & EFER_NX;
+	return vcpu->arch.efer & EFER_NX;
 }
 
 static int is_shadow_present_pte(u64 pte)
@@ -253,7 +249,7 @@ static int is_large_pte(u64 pte)
 	return pte & PT_PAGE_SIZE_MASK;
 }
 
-static int is_writeble_pte(unsigned long pte)
+static int is_writable_pte(unsigned long pte)
 {
 	return pte & PT_WRITABLE_MASK;
 }
@@ -470,24 +466,10 @@ static int has_wrprotected_page(struct k
 
 static int host_mapping_level(struct kvm *kvm, gfn_t gfn)
 {
-	unsigned long page_size = PAGE_SIZE;
-	struct vm_area_struct *vma;
-	unsigned long addr;
+	unsigned long page_size;
 	int i, ret = 0;
 
-	addr = gfn_to_hva(kvm, gfn);
-	if (kvm_is_error_hva(addr))
-		return PT_PAGE_TABLE_LEVEL;
-
-	down_read(&current->mm->mmap_sem);
-	vma = find_vma(current->mm, addr);
-	if (!vma)
-		goto out;
-
-	page_size = vma_kernel_pagesize(vma);
-
-out:
-	up_read(&current->mm->mmap_sem);
+	page_size = kvm_host_page_size(kvm, gfn);
 
 	for (i = PT_PAGE_TABLE_LEVEL;
 	     i < (PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES); ++i) {
@@ -503,8 +485,7 @@ out:
 static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
 {
 	struct kvm_memory_slot *slot;
-	int host_level;
-	int level = PT_PAGE_TABLE_LEVEL;
+	int host_level, level, max_level;
 
 	slot = gfn_to_memslot(vcpu->kvm, large_gfn);
 	if (slot && slot->dirty_bitmap)
@@ -515,7 +496,10 @@ static int mapping_level(struct kvm_vcpu
 	if (host_level == PT_PAGE_TABLE_LEVEL)
 		return host_level;
 
-	for (level = PT_DIRECTORY_LEVEL; level <= host_level; ++level)
+	max_level = kvm_x86_ops->get_lpage_level() < host_level ?
+		kvm_x86_ops->get_lpage_level() : host_level;
+
+	for (level = PT_DIRECTORY_LEVEL; level <= max_level; ++level)
 		if (has_wrprotected_page(vcpu->kvm, large_gfn, level))
 			break;
 
@@ -633,7 +617,7 @@ static void rmap_remove(struct kvm *kvm,
 	pfn = spte_to_pfn(*spte);
 	if (*spte & shadow_accessed_mask)
 		kvm_set_pfn_accessed(pfn);
-	if (is_writeble_pte(*spte))
+	if (is_writable_pte(*spte))
 		kvm_set_pfn_dirty(pfn);
 	rmapp = gfn_to_rmap(kvm, sp->gfns[spte - sp->spt], sp->role.level);
 	if (!*rmapp) {
@@ -662,6 +646,7 @@ static void rmap_remove(struct kvm *kvm,
 			prev_desc = desc;
 			desc = desc->more;
 		}
+		pr_err("rmap_remove: %p %llx many->many\n", spte, *spte);
 		BUG();
 	}
 }
@@ -708,7 +693,7 @@ static int rmap_write_protect(struct kvm
 		BUG_ON(!spte);
 		BUG_ON(!(*spte & PT_PRESENT_MASK));
 		rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte);
-		if (is_writeble_pte(*spte)) {
+		if (is_writable_pte(*spte)) {
 			__set_spte(spte, *spte & ~PT_WRITABLE_MASK);
 			write_protected = 1;
 		}
@@ -732,7 +717,7 @@ static int rmap_write_protect(struct kvm
 			BUG_ON(!(*spte & PT_PRESENT_MASK));
 			BUG_ON((*spte & (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK)) != (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK));
 			pgprintk("rmap_write_protect(large): spte %p %llx %lld\n", spte, *spte, gfn);
-			if (is_writeble_pte(*spte)) {
+			if (is_writable_pte(*spte)) {
 				rmap_remove(kvm, spte);
 				--kvm->stat.lpages;
 				__set_spte(spte, shadow_trap_nonpresent_pte);
@@ -787,7 +772,7 @@ static int kvm_set_pte_rmapp(struct kvm
 
 			new_spte &= ~PT_WRITABLE_MASK;
 			new_spte &= ~SPTE_HOST_WRITEABLE;
-			if (is_writeble_pte(*spte))
+			if (is_writable_pte(*spte))
 				kvm_set_pfn_dirty(spte_to_pfn(*spte));
 			__set_spte(spte, new_spte);
 			spte = rmap_next(kvm, rmapp, spte);
@@ -805,35 +790,32 @@ static int kvm_handle_hva(struct kvm *kv
 					 unsigned long data))
 {
 	int i, j;
+	int ret;
 	int retval = 0;
+	struct kvm_memslots *slots;
 
-	/*
-	 * If mmap_sem isn't taken, we can look the memslots with only
-	 * the mmu_lock by skipping over the slots with userspace_addr == 0.
-	 */
-	for (i = 0; i < kvm->nmemslots; i++) {
-		struct kvm_memory_slot *memslot = &kvm->memslots[i];
+	slots = rcu_dereference(kvm->memslots);
+
+	for (i = 0; i < slots->nmemslots; i++) {
+		struct kvm_memory_slot *memslot = &slots->memslots[i];
 		unsigned long start = memslot->userspace_addr;
 		unsigned long end;
 
-		/* mmu_lock protects userspace_addr */
-		if (!start)
-			continue;
-
 		end = start + (memslot->npages << PAGE_SHIFT);
 		if (hva >= start && hva < end) {
 			gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT;
 
-			retval |= handler(kvm, &memslot->rmap[gfn_offset],
-					  data);
+			ret = handler(kvm, &memslot->rmap[gfn_offset], data);
 
 			for (j = 0; j < KVM_NR_PAGE_SIZES - 1; ++j) {
 				int idx = gfn_offset;
 				idx /= KVM_PAGES_PER_HPAGE(PT_DIRECTORY_LEVEL + j);
-				retval |= handler(kvm,
+				ret |= handler(kvm,
 					&memslot->lpage_info[j][idx].rmap_pde,
 					data);
 			}
+			trace_kvm_age_page(hva, memslot, ret);
+			retval |= ret;
 		}
 	}
 
@@ -856,9 +838,15 @@ static int kvm_age_rmapp(struct kvm *kvm
 	u64 *spte;
 	int young = 0;
 
-	/* always return old for EPT */
+	/*
+	 * Emulate the accessed bit for EPT, by checking if this page has
+	 * an EPT mapping, and clearing it if it does. On the next access,
+	 * a new EPT mapping will be established.
+	 * This has some overhead, but not as much as the cost of swapping
+	 * out actively used pages or breaking up actively used hugepages.
+	 */
 	if (!shadow_accessed_mask)
-		return 0;
+		return kvm_unmap_rmapp(kvm, rmapp, data);
 
 	spte = rmap_next(kvm, rmapp, NULL);
 	while (spte) {
@@ -1502,8 +1490,8 @@ static int mmu_zap_unsync_children(struc
 		for_each_sp(pages, sp, parents, i) {
 			kvm_mmu_zap_page(kvm, sp);
 			mmu_pages_clear_parents(&parents);
+			zapped++;
 		}
-		zapped += pages.nr;
 		kvm_mmu_pages_init(parent, &parents, &pages);
 	}
 
@@ -1554,14 +1542,16 @@ void kvm_mmu_change_mmu_pages(struct kvm
 	 */
 
 	if (used_pages > kvm_nr_mmu_pages) {
-		while (used_pages > kvm_nr_mmu_pages) {
+		while (used_pages > kvm_nr_mmu_pages &&
+			!list_empty(&kvm->arch.active_mmu_pages)) {
 			struct kvm_mmu_page *page;
 
 			page = container_of(kvm->arch.active_mmu_pages.prev,
 					    struct kvm_mmu_page, link);
-			kvm_mmu_zap_page(kvm, page);
+			used_pages -= kvm_mmu_zap_page(kvm, page);
 			used_pages--;
 		}
+		kvm_nr_mmu_pages = used_pages;
 		kvm->arch.n_free_mmu_pages = 0;
 	}
 	else
@@ -1608,14 +1598,15 @@ static void mmu_unshadow(struct kvm *kvm
 		    && !sp->role.invalid) {
 			pgprintk("%s: zap %lx %x\n",
 				 __func__, gfn, sp->role.word);
-			kvm_mmu_zap_page(kvm, sp);
+			if (kvm_mmu_zap_page(kvm, sp))
+				nn = bucket->first;
 		}
 	}
 }
 
 static void page_header_update_slot(struct kvm *kvm, void *pte, gfn_t gfn)
 {
-	int slot = memslot_id(kvm, gfn_to_memslot(kvm, gfn));
+	int slot = memslot_id(kvm, gfn);
 	struct kvm_mmu_page *sp = page_header(__pa(pte));
 
 	__set_bit(slot, sp->slot_bitmap);
@@ -1639,7 +1630,7 @@ struct page *gva_to_page(struct kvm_vcpu
 {
 	struct page *page;
 
-	gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva);
+	gpa_t gpa = kvm_mmu_gva_to_gpa_read(vcpu, gva, NULL);
 
 	if (gpa == UNMAPPED_GVA)
 		return NULL;
@@ -1852,7 +1843,7 @@ static int set_spte(struct kvm_vcpu *vcp
 		 * is responsibility of mmu_get_page / kvm_sync_page.
 		 * Same reasoning can be applied to dirty page accounting.
 		 */
-		if (!can_unsync && is_writeble_pte(*sptep))
+		if (!can_unsync && is_writable_pte(*sptep))
 			goto set_pte;
 
 		if (mmu_need_write_protect(vcpu, gfn, can_unsync)) {
@@ -1860,7 +1851,7 @@ static int set_spte(struct kvm_vcpu *vcp
 				 __func__, gfn);
 			ret = 1;
 			pte_access &= ~ACC_WRITE_MASK;
-			if (is_writeble_pte(spte))
+			if (is_writable_pte(spte))
 				spte &= ~PT_WRITABLE_MASK;
 		}
 	}
@@ -1881,7 +1872,7 @@ static void mmu_set_spte(struct kvm_vcpu
 			 bool reset_host_protection)
 {
 	int was_rmapped = 0;
-	int was_writeble = is_writeble_pte(*sptep);
+	int was_writable = is_writable_pte(*sptep);
 	int rmap_count;
 
 	pgprintk("%s: spte %llx access %x write_fault %d"
@@ -1932,7 +1923,7 @@ static void mmu_set_spte(struct kvm_vcpu
 		if (rmap_count > RMAP_RECYCLE_THRESHOLD)
 			rmap_recycle(vcpu, sptep, gfn);
 	} else {
-		if (was_writeble)
+		if (was_writable)
 			kvm_release_pfn_dirty(pfn);
 		else
 			kvm_release_pfn_clean(pfn);
@@ -2162,8 +2153,11 @@ void kvm_mmu_sync_roots(struct kvm_vcpu
 	spin_unlock(&vcpu->kvm->mmu_lock);
 }
 
-static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr)
+static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr,
+				  u32 access, u32 *error)
 {
+	if (error)
+		*error = 0;
 	return vaddr;
 }
 
@@ -2747,7 +2741,7 @@ int kvm_mmu_unprotect_page_virt(struct k
 	if (tdp_enabled)
 		return 0;
 
-	gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva);
+	gpa = kvm_mmu_gva_to_gpa_read(vcpu, gva, NULL);
 
 	spin_lock(&vcpu->kvm->mmu_lock);
 	r = kvm_mmu_unprotect_page(vcpu->kvm, gpa >> PAGE_SHIFT);
@@ -2847,16 +2841,13 @@ static int alloc_mmu_pages(struct kvm_vc
 	 */
 	page = alloc_page(GFP_KERNEL | __GFP_DMA32);
 	if (!page)
-		goto error_1;
+		return -ENOMEM;
+
 	vcpu->arch.mmu.pae_root = page_address(page);
 	for (i = 0; i < 4; ++i)
 		vcpu->arch.mmu.pae_root[i] = INVALID_PAGE;
 
 	return 0;
-
-error_1:
-	free_mmu_pages(vcpu);
-	return -ENOMEM;
 }
 
 int kvm_mmu_create(struct kvm_vcpu *vcpu)
@@ -2936,10 +2927,9 @@ static int mmu_shrink(int nr_to_scan, gf
 	spin_lock(&kvm_lock);
 
 	list_for_each_entry(kvm, &vm_list, vm_list) {
-		int npages;
+		int npages, idx;
 
-		if (!down_read_trylock(&kvm->slots_lock))
-			continue;
+		idx = srcu_read_lock(&kvm->srcu);
 		spin_lock(&kvm->mmu_lock);
 		npages = kvm->arch.n_alloc_mmu_pages -
 			 kvm->arch.n_free_mmu_pages;
@@ -2952,7 +2942,7 @@ static int mmu_shrink(int nr_to_scan, gf
 		nr_to_scan--;
 
 		spin_unlock(&kvm->mmu_lock);
-		up_read(&kvm->slots_lock);
+		srcu_read_unlock(&kvm->srcu, idx);
 	}
 	if (kvm_freed)
 		list_move_tail(&kvm_freed->vm_list, &vm_list);
@@ -3019,9 +3009,11 @@ unsigned int kvm_mmu_calculate_mmu_pages
 	int i;
 	unsigned int nr_mmu_pages;
 	unsigned int  nr_pages = 0;
+	struct kvm_memslots *slots;
 
-	for (i = 0; i < kvm->nmemslots; i++)
-		nr_pages += kvm->memslots[i].npages;
+	slots = rcu_dereference(kvm->memslots);
+	for (i = 0; i < slots->nmemslots; i++)
+		nr_pages += slots->memslots[i].npages;
 
 	nr_mmu_pages = nr_pages * KVM_PERMILLE_MMU_PAGES / 1000;
 	nr_mmu_pages = max(nr_mmu_pages,
@@ -3246,7 +3238,7 @@ static void audit_mappings_page(struct k
 		if (is_shadow_present_pte(ent) && !is_last_spte(ent, level))
 			audit_mappings_page(vcpu, ent, va, level - 1);
 		else {
-			gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, va);
+			gpa_t gpa = kvm_mmu_gva_to_gpa_read(vcpu, va, NULL);
 			gfn_t gfn = gpa >> PAGE_SHIFT;
 			pfn_t pfn = gfn_to_pfn(vcpu->kvm, gfn);
 			hpa_t hpa = (hpa_t)pfn << PAGE_SHIFT;
@@ -3291,10 +3283,12 @@ static void audit_mappings(struct kvm_vc
 static int count_rmaps(struct kvm_vcpu *vcpu)
 {
 	int nmaps = 0;
-	int i, j, k;
+	int i, j, k, idx;
 
+	idx = srcu_read_lock(&kvm->srcu);
+	slots = rcu_dereference(kvm->memslots);
 	for (i = 0; i < KVM_MEMORY_SLOTS; ++i) {
-		struct kvm_memory_slot *m = &vcpu->kvm->memslots[i];
+		struct kvm_memory_slot *m = &slots->memslots[i];
 		struct kvm_rmap_desc *d;
 
 		for (j = 0; j < m->npages; ++j) {
@@ -3317,6 +3311,7 @@ static int count_rmaps(struct kvm_vcpu *
 			}
 		}
 	}
+	srcu_read_unlock(&kvm->srcu, idx);
 	return nmaps;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/mmu.h linux-libre-2.6.34-gnu1/arch/x86/kvm/mmu.h
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/mmu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/mmu.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
 #define __KVM_X86_MMU_H
 
 #include <linux/kvm_host.h>
+#include "kvm_cache_regs.h"
 
 #define PT64_PT_BITS 9
 #define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS)
@@ -37,6 +38,16 @@
 #define PT32_ROOT_LEVEL 2
 #define PT32E_ROOT_LEVEL 3
 
+#define PT_PDPE_LEVEL 3
+#define PT_DIRECTORY_LEVEL 2
+#define PT_PAGE_TABLE_LEVEL 1
+
+#define PFERR_PRESENT_MASK (1U << 0)
+#define PFERR_WRITE_MASK (1U << 1)
+#define PFERR_USER_MASK (1U << 2)
+#define PFERR_RSVD_MASK (1U << 3)
+#define PFERR_FETCH_MASK (1U << 4)
+
 int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]);
 
 static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
@@ -53,30 +64,6 @@ static inline int kvm_mmu_reload(struct
 	return kvm_mmu_load(vcpu);
 }
 
-static inline int is_long_mode(struct kvm_vcpu *vcpu)
-{
-#ifdef CONFIG_X86_64
-	return vcpu->arch.shadow_efer & EFER_LMA;
-#else
-	return 0;
-#endif
-}
-
-static inline int is_pae(struct kvm_vcpu *vcpu)
-{
-	return vcpu->arch.cr4 & X86_CR4_PAE;
-}
-
-static inline int is_pse(struct kvm_vcpu *vcpu)
-{
-	return vcpu->arch.cr4 & X86_CR4_PSE;
-}
-
-static inline int is_paging(struct kvm_vcpu *vcpu)
-{
-	return vcpu->arch.cr0 & X86_CR0_PG;
-}
-
 static inline int is_present_gpte(unsigned long pte)
 {
 	return pte & PT_PRESENT_MASK;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/paging_tmpl.h linux-libre-2.6.34-gnu1/arch/x86/kvm/paging_tmpl.h
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/paging_tmpl.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/paging_tmpl.h	2010-05-16 17:17:36.000000000 -0400
@@ -162,7 +162,7 @@ walk:
 		if (rsvd_fault)
 			goto access_error;
 
-		if (write_fault && !is_writeble_pte(pte))
+		if (write_fault && !is_writable_pte(pte))
 			if (user_fault || is_write_protection(vcpu))
 				goto access_error;
 
@@ -490,18 +490,23 @@ static void FNAME(invlpg)(struct kvm_vcp
 	spin_unlock(&vcpu->kvm->mmu_lock);
 }
 
-static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr)
+static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access,
+			       u32 *error)
 {
 	struct guest_walker walker;
 	gpa_t gpa = UNMAPPED_GVA;
 	int r;
 
-	r = FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0, 0);
+	r = FNAME(walk_addr)(&walker, vcpu, vaddr,
+			     !!(access & PFERR_WRITE_MASK),
+			     !!(access & PFERR_USER_MASK),
+			     !!(access & PFERR_FETCH_MASK));
 
 	if (r) {
 		gpa = gfn_to_gpa(walker.gfn);
 		gpa |= vaddr & ~PAGE_MASK;
-	}
+	} else if (error)
+		*error = walker.error_code;
 
 	return gpa;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/svm.c linux-libre-2.6.34-gnu1/arch/x86/kvm/svm.c
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/svm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/svm.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/highmem.h>
 #include <linux/sched.h>
 #include <linux/ftrace_event.h>
+#include <linux/slab.h>
 
 #include <asm/desc.h>
 
@@ -231,7 +232,7 @@ static void svm_set_efer(struct kvm_vcpu
 		efer &= ~EFER_LME;
 
 	to_svm(vcpu)->vmcb->save.efer = efer | EFER_SVME;
-	vcpu->arch.shadow_efer = efer;
+	vcpu->arch.efer = efer;
 }
 
 static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
@@ -540,6 +541,8 @@ static void init_vmcb(struct vcpu_svm *s
 	struct vmcb_control_area *control = &svm->vmcb->control;
 	struct vmcb_save_area *save = &svm->vmcb->save;
 
+	svm->vcpu.fpu_active = 1;
+
 	control->intercept_cr_read = 	INTERCEPT_CR0_MASK |
 					INTERCEPT_CR3_MASK |
 					INTERCEPT_CR4_MASK;
@@ -552,13 +555,19 @@ static void init_vmcb(struct vcpu_svm *s
 	control->intercept_dr_read = 	INTERCEPT_DR0_MASK |
 					INTERCEPT_DR1_MASK |
 					INTERCEPT_DR2_MASK |
-					INTERCEPT_DR3_MASK;
+					INTERCEPT_DR3_MASK |
+					INTERCEPT_DR4_MASK |
+					INTERCEPT_DR5_MASK |
+					INTERCEPT_DR6_MASK |
+					INTERCEPT_DR7_MASK;
 
 	control->intercept_dr_write = 	INTERCEPT_DR0_MASK |
 					INTERCEPT_DR1_MASK |
 					INTERCEPT_DR2_MASK |
 					INTERCEPT_DR3_MASK |
+					INTERCEPT_DR4_MASK |
 					INTERCEPT_DR5_MASK |
+					INTERCEPT_DR6_MASK |
 					INTERCEPT_DR7_MASK;
 
 	control->intercept_exceptions = (1 << PF_VECTOR) |
@@ -569,6 +578,7 @@ static void init_vmcb(struct vcpu_svm *s
 	control->intercept = 	(1ULL << INTERCEPT_INTR) |
 				(1ULL << INTERCEPT_NMI) |
 				(1ULL << INTERCEPT_SMI) |
+				(1ULL << INTERCEPT_SELECTIVE_CR0) |
 				(1ULL << INTERCEPT_CPUID) |
 				(1ULL << INTERCEPT_INVD) |
 				(1ULL << INTERCEPT_HLT) |
@@ -641,10 +651,8 @@ static void init_vmcb(struct vcpu_svm *s
 		control->intercept &= ~((1ULL << INTERCEPT_TASK_SWITCH) |
 					(1ULL << INTERCEPT_INVLPG));
 		control->intercept_exceptions &= ~(1 << PF_VECTOR);
-		control->intercept_cr_read &= ~(INTERCEPT_CR0_MASK|
-						INTERCEPT_CR3_MASK);
-		control->intercept_cr_write &= ~(INTERCEPT_CR0_MASK|
-						 INTERCEPT_CR3_MASK);
+		control->intercept_cr_read &= ~INTERCEPT_CR3_MASK;
+		control->intercept_cr_write &= ~INTERCEPT_CR3_MASK;
 		save->g_pat = 0x0007040600070406ULL;
 		save->cr3 = 0;
 		save->cr4 = 0;
@@ -698,29 +706,28 @@ static struct kvm_vcpu *svm_create_vcpu(
 	if (err)
 		goto free_svm;
 
+	err = -ENOMEM;
 	page = alloc_page(GFP_KERNEL);
-	if (!page) {
-		err = -ENOMEM;
+	if (!page)
 		goto uninit;
-	}
 
-	err = -ENOMEM;
 	msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
 	if (!msrpm_pages)
-		goto uninit;
+		goto free_page1;
 
 	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);
+		goto free_page2;
 
 	hsave_page = alloc_page(GFP_KERNEL);
 	if (!hsave_page)
-		goto uninit;
+		goto free_page3;
+
 	svm->nested.hsave = page_address(hsave_page);
 
+	svm->msrpm = page_address(msrpm_pages);
+	svm_vcpu_init_msrpm(svm->msrpm);
+
 	svm->nested.msrpm = page_address(nested_msrpm_pages);
 
 	svm->vmcb = page_address(page);
@@ -730,13 +737,18 @@ static struct kvm_vcpu *svm_create_vcpu(
 	init_vmcb(svm);
 
 	fx_init(&svm->vcpu);
-	svm->vcpu.fpu_active = 1;
 	svm->vcpu.arch.apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
 	if (kvm_vcpu_is_bsp(&svm->vcpu))
 		svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP;
 
 	return &svm->vcpu;
 
+free_page3:
+	__free_pages(nested_msrpm_pages, MSRPM_ALLOC_ORDER);
+free_page2:
+	__free_pages(msrpm_pages, MSRPM_ALLOC_ORDER);
+free_page1:
+	__free_page(page);
 uninit:
 	kvm_vcpu_uninit(&svm->vcpu);
 free_svm:
@@ -765,14 +777,16 @@ static void svm_vcpu_load(struct kvm_vcp
 	if (unlikely(cpu != vcpu->cpu)) {
 		u64 delta;
 
-		/*
-		 * Make sure that the guest sees a monotonically
-		 * increasing TSC.
-		 */
-		delta = vcpu->arch.host_tsc - native_read_tsc();
-		svm->vmcb->control.tsc_offset += delta;
-		if (is_nested(svm))
-			svm->nested.hsave->control.tsc_offset += delta;
+		if (check_tsc_unstable()) {
+			/*
+			 * Make sure that the guest sees a monotonically
+			 * increasing TSC.
+			 */
+			delta = vcpu->arch.host_tsc - native_read_tsc();
+			svm->vmcb->control.tsc_offset += delta;
+			if (is_nested(svm))
+				svm->nested.hsave->control.tsc_offset += delta;
+		}
 		vcpu->cpu = cpu;
 		kvm_migrate_timers(vcpu);
 		svm->asid_generation = 0;
@@ -954,42 +968,59 @@ static void svm_set_gdt(struct kvm_vcpu
 	svm->vmcb->save.gdtr.base = dt->base ;
 }
 
+static void svm_decache_cr0_guest_bits(struct kvm_vcpu *vcpu)
+{
+}
+
 static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
 {
 }
 
+static void update_cr0_intercept(struct vcpu_svm *svm)
+{
+	ulong gcr0 = svm->vcpu.arch.cr0;
+	u64 *hcr0 = &svm->vmcb->save.cr0;
+
+	if (!svm->vcpu.fpu_active)
+		*hcr0 |= SVM_CR0_SELECTIVE_MASK;
+	else
+		*hcr0 = (*hcr0 & ~SVM_CR0_SELECTIVE_MASK)
+			| (gcr0 & SVM_CR0_SELECTIVE_MASK);
+
+
+	if (gcr0 == *hcr0 && svm->vcpu.fpu_active) {
+		svm->vmcb->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK;
+		svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK;
+	} else {
+		svm->vmcb->control.intercept_cr_read |= INTERCEPT_CR0_MASK;
+		svm->vmcb->control.intercept_cr_write |= INTERCEPT_CR0_MASK;
+	}
+}
+
 static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
 #ifdef CONFIG_X86_64
-	if (vcpu->arch.shadow_efer & EFER_LME) {
+	if (vcpu->arch.efer & EFER_LME) {
 		if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) {
-			vcpu->arch.shadow_efer |= EFER_LMA;
+			vcpu->arch.efer |= EFER_LMA;
 			svm->vmcb->save.efer |= EFER_LMA | EFER_LME;
 		}
 
 		if (is_paging(vcpu) && !(cr0 & X86_CR0_PG)) {
-			vcpu->arch.shadow_efer &= ~EFER_LMA;
+			vcpu->arch.efer &= ~EFER_LMA;
 			svm->vmcb->save.efer &= ~(EFER_LMA | EFER_LME);
 		}
 	}
 #endif
-	if (npt_enabled)
-		goto set;
+	vcpu->arch.cr0 = cr0;
 
-	if ((vcpu->arch.cr0 & X86_CR0_TS) && !(cr0 & X86_CR0_TS)) {
-		svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
-		vcpu->fpu_active = 1;
-	}
+	if (!npt_enabled)
+		cr0 |= X86_CR0_PG | X86_CR0_WP;
 
-	vcpu->arch.cr0 = cr0;
-	cr0 |= X86_CR0_PG | X86_CR0_WP;
-	if (!vcpu->fpu_active) {
-		svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR);
+	if (!vcpu->fpu_active)
 		cr0 |= X86_CR0_TS;
-	}
-set:
 	/*
 	 * re-enable caching here because the QEMU bios
 	 * does not do it - this results in some delay at
@@ -997,6 +1028,7 @@ set:
 	 */
 	cr0 &= ~(X86_CR0_CD | X86_CR0_NW);
 	svm->vmcb->save.cr0 = cr0;
+	update_cr0_intercept(svm);
 }
 
 static void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
@@ -1102,76 +1134,70 @@ static void new_asid(struct vcpu_svm *sv
 	svm->vmcb->control.asid = sd->next_asid++;
 }
 
-static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr)
+static int svm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *dest)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
-	unsigned long val;
 
 	switch (dr) {
 	case 0 ... 3:
-		val = vcpu->arch.db[dr];
+		*dest = vcpu->arch.db[dr];
 		break;
+	case 4:
+		if (kvm_read_cr4_bits(vcpu, X86_CR4_DE))
+			return EMULATE_FAIL; /* will re-inject UD */
+		/* fall through */
 	case 6:
 		if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
-			val = vcpu->arch.dr6;
+			*dest = vcpu->arch.dr6;
 		else
-			val = svm->vmcb->save.dr6;
+			*dest = svm->vmcb->save.dr6;
 		break;
+	case 5:
+		if (kvm_read_cr4_bits(vcpu, X86_CR4_DE))
+			return EMULATE_FAIL; /* will re-inject UD */
+		/* fall through */
 	case 7:
 		if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
-			val = vcpu->arch.dr7;
+			*dest = vcpu->arch.dr7;
 		else
-			val = svm->vmcb->save.dr7;
+			*dest = svm->vmcb->save.dr7;
 		break;
-	default:
-		val = 0;
 	}
 
-	return val;
+	return EMULATE_DONE;
 }
 
-static void svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value,
-		       int *exception)
+static int svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
-	*exception = 0;
-
 	switch (dr) {
 	case 0 ... 3:
 		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)
-			*exception = UD_VECTOR;
-		return;
+		break;
+	case 4:
+		if (kvm_read_cr4_bits(vcpu, X86_CR4_DE))
+			return EMULATE_FAIL; /* will re-inject UD */
+		/* fall through */
 	case 6:
-		if (value & 0xffffffff00000000ULL) {
-			*exception = GP_VECTOR;
-			return;
-		}
 		vcpu->arch.dr6 = (value & DR6_VOLATILE) | DR6_FIXED_1;
-		return;
+		break;
+	case 5:
+		if (kvm_read_cr4_bits(vcpu, X86_CR4_DE))
+			return EMULATE_FAIL; /* will re-inject UD */
+		/* fall through */
 	case 7:
-		if (value & 0xffffffff00000000ULL) {
-			*exception = GP_VECTOR;
-			return;
-		}
 		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;
-		return;
+		break;
 	}
+
+	return EMULATE_DONE;
 }
 
 static int pf_interception(struct vcpu_svm *svm)
@@ -1239,13 +1265,17 @@ static int ud_interception(struct vcpu_s
 	return 1;
 }
 
-static int nm_interception(struct vcpu_svm *svm)
+static void svm_fpu_activate(struct kvm_vcpu *vcpu)
 {
+	struct vcpu_svm *svm = to_svm(vcpu);
 	svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
-	if (!(svm->vcpu.arch.cr0 & X86_CR0_TS))
-		svm->vmcb->save.cr0 &= ~X86_CR0_TS;
 	svm->vcpu.fpu_active = 1;
+	update_cr0_intercept(svm);
+}
 
+static int nm_interception(struct vcpu_svm *svm)
+{
+	svm_fpu_activate(&svm->vcpu);
 	return 1;
 }
 
@@ -1337,7 +1367,7 @@ static int vmmcall_interception(struct v
 
 static int nested_svm_check_permissions(struct vcpu_svm *svm)
 {
-	if (!(svm->vcpu.arch.shadow_efer & EFER_SVME)
+	if (!(svm->vcpu.arch.efer & EFER_SVME)
 	    || !is_paging(&svm->vcpu)) {
 		kvm_queue_exception(&svm->vcpu, UD_VECTOR);
 		return 1;
@@ -1740,8 +1770,8 @@ static bool nested_svm_vmrun(struct vcpu
 	hsave->save.ds     = vmcb->save.ds;
 	hsave->save.gdtr   = vmcb->save.gdtr;
 	hsave->save.idtr   = vmcb->save.idtr;
-	hsave->save.efer   = svm->vcpu.arch.shadow_efer;
-	hsave->save.cr0    = svm->vcpu.arch.cr0;
+	hsave->save.efer   = svm->vcpu.arch.efer;
+	hsave->save.cr0    = kvm_read_cr0(&svm->vcpu);
 	hsave->save.cr4    = svm->vcpu.arch.cr4;
 	hsave->save.rflags = vmcb->save.rflags;
 	hsave->save.rip    = svm->next_rip;
@@ -2037,7 +2067,7 @@ static int cpuid_interception(struct vcp
 static int iret_interception(struct vcpu_svm *svm)
 {
 	++svm->vcpu.stat.nmi_window_exits;
-	svm->vmcb->control.intercept &= ~(1UL << INTERCEPT_IRET);
+	svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_IRET);
 	svm->vcpu.arch.hflags |= HF_IRET_MASK;
 	return 1;
 }
@@ -2153,9 +2183,10 @@ static int rdmsr_interception(struct vcp
 	u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX];
 	u64 data;
 
-	if (svm_get_msr(&svm->vcpu, ecx, &data))
+	if (svm_get_msr(&svm->vcpu, ecx, &data)) {
+		trace_kvm_msr_read_ex(ecx);
 		kvm_inject_gp(&svm->vcpu, 0);
-	else {
+	} else {
 		trace_kvm_msr_read(ecx, data);
 
 		svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff;
@@ -2247,13 +2278,15 @@ static int wrmsr_interception(struct vcp
 	u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u)
 		| ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32);
 
-	trace_kvm_msr_write(ecx, data);
 
 	svm->next_rip = kvm_rip_read(&svm->vcpu) + 2;
-	if (svm_set_msr(&svm->vcpu, ecx, data))
+	if (svm_set_msr(&svm->vcpu, ecx, data)) {
+		trace_kvm_msr_write_ex(ecx, data);
 		kvm_inject_gp(&svm->vcpu, 0);
-	else
+	} else {
+		trace_kvm_msr_write(ecx, data);
 		skip_emulated_instruction(&svm->vcpu);
+	}
 	return 1;
 }
 
@@ -2297,7 +2330,7 @@ static int (*svm_exit_handlers[])(struct
 	[SVM_EXIT_READ_CR3]           		= emulate_on_interception,
 	[SVM_EXIT_READ_CR4]           		= emulate_on_interception,
 	[SVM_EXIT_READ_CR8]           		= emulate_on_interception,
-	/* for now: */
+	[SVM_EXIT_CR0_SEL_WRITE]		= emulate_on_interception,
 	[SVM_EXIT_WRITE_CR0]          		= emulate_on_interception,
 	[SVM_EXIT_WRITE_CR3]          		= emulate_on_interception,
 	[SVM_EXIT_WRITE_CR4]          		= emulate_on_interception,
@@ -2306,11 +2339,17 @@ static int (*svm_exit_handlers[])(struct
 	[SVM_EXIT_READ_DR1]			= emulate_on_interception,
 	[SVM_EXIT_READ_DR2]			= emulate_on_interception,
 	[SVM_EXIT_READ_DR3]			= emulate_on_interception,
+	[SVM_EXIT_READ_DR4]			= emulate_on_interception,
+	[SVM_EXIT_READ_DR5]			= emulate_on_interception,
+	[SVM_EXIT_READ_DR6]			= emulate_on_interception,
+	[SVM_EXIT_READ_DR7]			= emulate_on_interception,
 	[SVM_EXIT_WRITE_DR0]			= emulate_on_interception,
 	[SVM_EXIT_WRITE_DR1]			= emulate_on_interception,
 	[SVM_EXIT_WRITE_DR2]			= emulate_on_interception,
 	[SVM_EXIT_WRITE_DR3]			= emulate_on_interception,
+	[SVM_EXIT_WRITE_DR4]			= emulate_on_interception,
 	[SVM_EXIT_WRITE_DR5]			= emulate_on_interception,
+	[SVM_EXIT_WRITE_DR6]			= 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,
@@ -2383,20 +2422,10 @@ static int handle_exit(struct kvm_vcpu *
 
 	svm_complete_interrupts(svm);
 
-	if (npt_enabled) {
-		int mmu_reload = 0;
-		if ((vcpu->arch.cr0 ^ svm->vmcb->save.cr0) & X86_CR0_PG) {
-			svm_set_cr0(vcpu, svm->vmcb->save.cr0);
-			mmu_reload = 1;
-		}
+	if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR0_MASK))
 		vcpu->arch.cr0 = svm->vmcb->save.cr0;
+	if (npt_enabled)
 		vcpu->arch.cr3 = svm->vmcb->save.cr3;
-		if (mmu_reload) {
-			kvm_mmu_reset_context(vcpu);
-			kvm_mmu_load(vcpu);
-		}
-	}
-
 
 	if (svm->vmcb->control.exit_code == SVM_EXIT_ERR) {
 		kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
@@ -2450,7 +2479,7 @@ static void svm_inject_nmi(struct kvm_vc
 
 	svm->vmcb->control.event_inj = SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_NMI;
 	vcpu->arch.hflags |= HF_NMI_MASK;
-	svm->vmcb->control.intercept |= (1UL << INTERCEPT_IRET);
+	svm->vmcb->control.intercept |= (1ULL << INTERCEPT_IRET);
 	++vcpu->stat.nmi_injections;
 }
 
@@ -2510,10 +2539,10 @@ static void svm_set_nmi_mask(struct kvm_
 
 	if (masked) {
 		svm->vcpu.arch.hflags |= HF_NMI_MASK;
-		svm->vmcb->control.intercept |= (1UL << INTERCEPT_IRET);
+		svm->vmcb->control.intercept |= (1ULL << INTERCEPT_IRET);
 	} else {
 		svm->vcpu.arch.hflags &= ~HF_NMI_MASK;
-		svm->vmcb->control.intercept &= ~(1UL << INTERCEPT_IRET);
+		svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_IRET);
 	}
 }
 
@@ -2798,12 +2827,6 @@ static void svm_set_cr3(struct kvm_vcpu
 
 	svm->vmcb->save.cr3 = root;
 	force_new_asid(vcpu);
-
-	if (vcpu->fpu_active) {
-		svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR);
-		svm->vmcb->save.cr0 |= X86_CR0_TS;
-		vcpu->fpu_active = 0;
-	}
 }
 
 static int is_disabled(void)
@@ -2852,6 +2875,10 @@ static u64 svm_get_mt_mask(struct kvm_vc
 	return 0;
 }
 
+static void svm_cpuid_update(struct kvm_vcpu *vcpu)
+{
+}
+
 static const struct trace_print_flags svm_exit_reasons_str[] = {
 	{ SVM_EXIT_READ_CR0,           		"read_cr0" },
 	{ SVM_EXIT_READ_CR3,	      		"read_cr3" },
@@ -2905,9 +2932,22 @@ static const struct trace_print_flags sv
 	{ -1, NULL }
 };
 
-static bool svm_gb_page_enable(void)
+static int svm_get_lpage_level(void)
 {
-	return true;
+	return PT_PDPE_LEVEL;
+}
+
+static bool svm_rdtscp_supported(void)
+{
+	return false;
+}
+
+static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
+{
+	struct vcpu_svm *svm = to_svm(vcpu);
+
+	update_cr0_intercept(svm);
+	svm->vmcb->control.intercept_exceptions |= 1 << NM_VECTOR;
 }
 
 static struct kvm_x86_ops svm_x86_ops = {
@@ -2936,6 +2976,7 @@ static struct kvm_x86_ops svm_x86_ops =
 	.set_segment = svm_set_segment,
 	.get_cpl = svm_get_cpl,
 	.get_cs_db_l_bits = kvm_get_cs_db_l_bits,
+	.decache_cr0_guest_bits = svm_decache_cr0_guest_bits,
 	.decache_cr4_guest_bits = svm_decache_cr4_guest_bits,
 	.set_cr0 = svm_set_cr0,
 	.set_cr3 = svm_set_cr3,
@@ -2950,6 +2991,8 @@ static struct kvm_x86_ops svm_x86_ops =
 	.cache_reg = svm_cache_reg,
 	.get_rflags = svm_get_rflags,
 	.set_rflags = svm_set_rflags,
+	.fpu_activate = svm_fpu_activate,
+	.fpu_deactivate = svm_fpu_deactivate,
 
 	.tlb_flush = svm_flush_tlb,
 
@@ -2975,7 +3018,11 @@ static struct kvm_x86_ops svm_x86_ops =
 	.get_mt_mask = svm_get_mt_mask,
 
 	.exit_reasons_str = svm_exit_reasons_str,
-	.gb_page_enable = svm_gb_page_enable,
+	.get_lpage_level = svm_get_lpage_level,
+
+	.cpuid_update = svm_cpuid_update,
+
+	.rdtscp_supported = svm_rdtscp_supported,
 };
 
 static int __init svm_init(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/trace.h linux-libre-2.6.34-gnu1/arch/x86/kvm/trace.h
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/trace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/trace.h	2010-05-16 17:17:36.000000000 -0400
@@ -56,6 +56,38 @@ TRACE_EVENT(kvm_hypercall,
 );
 
 /*
+ * Tracepoint for hypercall.
+ */
+TRACE_EVENT(kvm_hv_hypercall,
+	TP_PROTO(__u16 code, bool fast, __u16 rep_cnt, __u16 rep_idx,
+		 __u64 ingpa, __u64 outgpa),
+	TP_ARGS(code, fast, rep_cnt, rep_idx, ingpa, outgpa),
+
+	TP_STRUCT__entry(
+		__field(	__u16, 		code		)
+		__field(	bool,		fast		)
+		__field(	__u16,		rep_cnt		)
+		__field(	__u16,		rep_idx		)
+		__field(	__u64,		ingpa		)
+		__field(	__u64,		outgpa		)
+	),
+
+	TP_fast_assign(
+		__entry->code		= code;
+		__entry->fast		= fast;
+		__entry->rep_cnt	= rep_cnt;
+		__entry->rep_idx	= rep_idx;
+		__entry->ingpa		= ingpa;
+		__entry->outgpa		= outgpa;
+	),
+
+	TP_printk("code 0x%x %s cnt 0x%x idx 0x%x in 0x%llx out 0x%llx",
+		  __entry->code, __entry->fast ? "fast" : "slow",
+		  __entry->rep_cnt, __entry->rep_idx,  __entry->ingpa,
+		  __entry->outgpa)
+);
+
+/*
  * Tracepoint for PIO.
  */
 TRACE_EVENT(kvm_pio,
@@ -214,28 +246,33 @@ TRACE_EVENT(kvm_page_fault,
  * Tracepoint for guest MSR access.
  */
 TRACE_EVENT(kvm_msr,
-	TP_PROTO(unsigned int rw, unsigned int ecx, unsigned long data),
-	TP_ARGS(rw, ecx, data),
+	TP_PROTO(unsigned write, u32 ecx, u64 data, bool exception),
+	TP_ARGS(write, ecx, data, exception),
 
 	TP_STRUCT__entry(
-		__field(	unsigned int,	rw		)
-		__field(	unsigned int,	ecx		)
-		__field(	unsigned long,	data		)
+		__field(	unsigned,	write		)
+		__field(	u32,		ecx		)
+		__field(	u64,		data		)
+		__field(	u8,		exception	)
 	),
 
 	TP_fast_assign(
-		__entry->rw		= rw;
+		__entry->write		= write;
 		__entry->ecx		= ecx;
 		__entry->data		= data;
+		__entry->exception	= exception;
 	),
 
-	TP_printk("msr_%s %x = 0x%lx",
-		  __entry->rw ? "write" : "read",
-		  __entry->ecx, __entry->data)
+	TP_printk("msr_%s %x = 0x%llx%s",
+		  __entry->write ? "write" : "read",
+		  __entry->ecx, __entry->data,
+		  __entry->exception ? " (#GP)" : "")
 );
 
-#define trace_kvm_msr_read(ecx, data)		trace_kvm_msr(0, ecx, data)
-#define trace_kvm_msr_write(ecx, data)		trace_kvm_msr(1, ecx, data)
+#define trace_kvm_msr_read(ecx, data)      trace_kvm_msr(0, ecx, data, false)
+#define trace_kvm_msr_write(ecx, data)     trace_kvm_msr(1, ecx, data, false)
+#define trace_kvm_msr_read_ex(ecx)         trace_kvm_msr(0, ecx, 0, true)
+#define trace_kvm_msr_write_ex(ecx, data)  trace_kvm_msr(1, ecx, data, true)
 
 /*
  * Tracepoint for guest CR access.
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/vmx.c linux-libre-2.6.34-gnu1/arch/x86/kvm/vmx.c
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/vmx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/vmx.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/sched.h>
 #include <linux/moduleparam.h>
 #include <linux/ftrace_event.h>
+#include <linux/slab.h>
 #include "kvm_cache_regs.h"
 #include "x86.h"
 
@@ -61,6 +62,23 @@ module_param_named(unrestricted_guest,
 static int __read_mostly emulate_invalid_guest_state = 0;
 module_param(emulate_invalid_guest_state, bool, S_IRUGO);
 
+#define KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST				\
+	(X86_CR0_WP | X86_CR0_NE | X86_CR0_NW | X86_CR0_CD)
+#define KVM_GUEST_CR0_MASK						\
+	(KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
+#define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST				\
+	(X86_CR0_WP | X86_CR0_NE)
+#define KVM_VM_CR0_ALWAYS_ON						\
+	(KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
+#define KVM_CR4_GUEST_OWNED_BITS				      \
+	(X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR      \
+	 | X86_CR4_OSXMMEXCPT)
+
+#define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE)
+#define KVM_RMODE_VM_CR4_ALWAYS_ON (X86_CR4_VME | X86_CR4_PAE | X86_CR4_VMXE)
+
+#define RMODE_GUEST_OWNED_EFLAGS_BITS (~(X86_EFLAGS_IOPL | X86_EFLAGS_VM))
+
 /*
  * These 2 parameters are used to config the controls for Pause-Loop Exiting:
  * ple_gap:    upper bound on the amount of time between two successive
@@ -115,7 +133,7 @@ struct vcpu_vmx {
 	} host_state;
 	struct {
 		int vm86_active;
-		u8 save_iopl;
+		ulong save_rflags;
 		struct kvm_save_segment {
 			u16 selector;
 			unsigned long base;
@@ -136,6 +154,8 @@ struct vcpu_vmx {
 	ktime_t entry_time;
 	s64 vnmi_blocked_time;
 	u32 exit_reason;
+
+	bool rdtscp_enabled;
 };
 
 static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
@@ -210,7 +230,7 @@ static const u32 vmx_msr_index[] = {
 #ifdef CONFIG_X86_64
 	MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR,
 #endif
-	MSR_EFER, MSR_K6_STAR,
+	MSR_EFER, MSR_TSC_AUX, MSR_K6_STAR,
 };
 #define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index)
 
@@ -301,6 +321,11 @@ static inline bool cpu_has_vmx_ept_2m_pa
 	return !!(vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT);
 }
 
+static inline bool cpu_has_vmx_ept_1g_page(void)
+{
+	return !!(vmx_capability.ept & VMX_EPT_1GB_PAGE_BIT);
+}
+
 static inline int cpu_has_vmx_invept_individual_addr(void)
 {
 	return !!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT);
@@ -336,9 +361,7 @@ static inline int cpu_has_vmx_ple(void)
 
 static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm)
 {
-	return flexpriority_enabled &&
-		(cpu_has_vmx_virtualize_apic_accesses()) &&
-		(irqchip_in_kernel(kvm));
+	return flexpriority_enabled && irqchip_in_kernel(kvm);
 }
 
 static inline int cpu_has_vmx_vpid(void)
@@ -347,6 +370,12 @@ static inline int cpu_has_vmx_vpid(void)
 		SECONDARY_EXEC_ENABLE_VPID;
 }
 
+static inline int cpu_has_vmx_rdtscp(void)
+{
+	return vmcs_config.cpu_based_2nd_exec_ctrl &
+		SECONDARY_EXEC_RDTSCP;
+}
+
 static inline int cpu_has_virtual_nmis(void)
 {
 	return vmcs_config.pin_based_exec_ctrl & PIN_BASED_VIRTUAL_NMIS;
@@ -551,22 +580,18 @@ static void update_exception_bitmap(stru
 {
 	u32 eb;
 
-	eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR);
-	if (!vcpu->fpu_active)
-		eb |= 1u << NM_VECTOR;
-	/*
-	 * Unconditionally intercept #DB so we can maintain dr6 without
-	 * reading it every exit.
-	 */
-	eb |= 1u << DB_VECTOR;
-	if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) {
-		if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
-			eb |= 1u << BP_VECTOR;
-	}
+	eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR) |
+	     (1u << NM_VECTOR) | (1u << DB_VECTOR);
+	if ((vcpu->guest_debug &
+	     (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) ==
+	    (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP))
+		eb |= 1u << BP_VECTOR;
 	if (to_vmx(vcpu)->rmode.vm86_active)
 		eb = ~0;
 	if (enable_ept)
 		eb &= ~(1u << PF_VECTOR); /* bypass_guest_pf = 0 */
+	if (vcpu->fpu_active)
+		eb &= ~(1u << NM_VECTOR);
 	vmcs_write32(EXCEPTION_BITMAP, eb);
 }
 
@@ -589,7 +614,7 @@ static bool update_transition_efer(struc
 	u64 guest_efer;
 	u64 ignore_bits;
 
-	guest_efer = vmx->vcpu.arch.shadow_efer;
+	guest_efer = vmx->vcpu.arch.efer;
 
 	/*
 	 * NX is emulated; LMA and LME handled by hardware; SCE meaninless
@@ -767,38 +792,51 @@ static void vmx_vcpu_put(struct kvm_vcpu
 
 static void vmx_fpu_activate(struct kvm_vcpu *vcpu)
 {
+	ulong cr0;
+
 	if (vcpu->fpu_active)
 		return;
 	vcpu->fpu_active = 1;
-	vmcs_clear_bits(GUEST_CR0, X86_CR0_TS);
-	if (vcpu->arch.cr0 & X86_CR0_TS)
-		vmcs_set_bits(GUEST_CR0, X86_CR0_TS);
+	cr0 = vmcs_readl(GUEST_CR0);
+	cr0 &= ~(X86_CR0_TS | X86_CR0_MP);
+	cr0 |= kvm_read_cr0_bits(vcpu, X86_CR0_TS | X86_CR0_MP);
+	vmcs_writel(GUEST_CR0, cr0);
 	update_exception_bitmap(vcpu);
+	vcpu->arch.cr0_guest_owned_bits = X86_CR0_TS;
+	vmcs_writel(CR0_GUEST_HOST_MASK, ~vcpu->arch.cr0_guest_owned_bits);
 }
 
+static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu);
+
 static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu)
 {
-	if (!vcpu->fpu_active)
-		return;
-	vcpu->fpu_active = 0;
-	vmcs_set_bits(GUEST_CR0, X86_CR0_TS);
+	vmx_decache_cr0_guest_bits(vcpu);
+	vmcs_set_bits(GUEST_CR0, X86_CR0_TS | X86_CR0_MP);
 	update_exception_bitmap(vcpu);
+	vcpu->arch.cr0_guest_owned_bits = 0;
+	vmcs_writel(CR0_GUEST_HOST_MASK, ~vcpu->arch.cr0_guest_owned_bits);
+	vmcs_writel(CR0_READ_SHADOW, vcpu->arch.cr0);
 }
 
 static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
 {
-	unsigned long rflags;
+	unsigned long rflags, save_rflags;
 
 	rflags = vmcs_readl(GUEST_RFLAGS);
-	if (to_vmx(vcpu)->rmode.vm86_active)
-		rflags &= ~(unsigned long)(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
+	if (to_vmx(vcpu)->rmode.vm86_active) {
+		rflags &= RMODE_GUEST_OWNED_EFLAGS_BITS;
+		save_rflags = to_vmx(vcpu)->rmode.save_rflags;
+		rflags |= save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS;
+	}
 	return rflags;
 }
 
 static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
 {
-	if (to_vmx(vcpu)->rmode.vm86_active)
+	if (to_vmx(vcpu)->rmode.vm86_active) {
+		to_vmx(vcpu)->rmode.save_rflags = rflags;
 		rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
+	}
 	vmcs_writel(GUEST_RFLAGS, rflags);
 }
 
@@ -878,6 +916,11 @@ static void vmx_queue_exception(struct k
 	vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
 }
 
+static bool vmx_rdtscp_supported(void)
+{
+	return cpu_has_vmx_rdtscp();
+}
+
 /*
  * Swap MSR entry in host/guest MSR entry array.
  */
@@ -913,12 +956,15 @@ static void setup_msrs(struct vcpu_vmx *
 		index = __find_msr_index(vmx, MSR_CSTAR);
 		if (index >= 0)
 			move_msr_up(vmx, index, save_nmsrs++);
+		index = __find_msr_index(vmx, MSR_TSC_AUX);
+		if (index >= 0 && vmx->rdtscp_enabled)
+			move_msr_up(vmx, index, save_nmsrs++);
 		/*
 		 * MSR_K6_STAR is only needed on long mode guests, and only
 		 * if efer.sce is enabled.
 		 */
 		index = __find_msr_index(vmx, MSR_K6_STAR);
-		if ((index >= 0) && (vmx->vcpu.arch.shadow_efer & EFER_SCE))
+		if ((index >= 0) && (vmx->vcpu.arch.efer & EFER_SCE))
 			move_msr_up(vmx, index, save_nmsrs++);
 	}
 #endif
@@ -1002,6 +1048,10 @@ static int vmx_get_msr(struct kvm_vcpu *
 	case MSR_IA32_SYSENTER_ESP:
 		data = vmcs_readl(GUEST_SYSENTER_ESP);
 		break;
+	case MSR_TSC_AUX:
+		if (!to_vmx(vcpu)->rdtscp_enabled)
+			return 1;
+		/* Otherwise falls through */
 	default:
 		vmx_load_host_state(to_vmx(vcpu));
 		msr = find_msr_entry(to_vmx(vcpu), msr_index);
@@ -1065,7 +1115,15 @@ static int vmx_set_msr(struct kvm_vcpu *
 			vcpu->arch.pat = data;
 			break;
 		}
-		/* Otherwise falls through to kvm_set_msr_common */
+		ret = kvm_set_msr_common(vcpu, msr_index, data);
+		break;
+	case MSR_TSC_AUX:
+		if (!vmx->rdtscp_enabled)
+			return 1;
+		/* Check reserved bit, higher 32 bits should be zero */
+		if ((data >> 32) != 0)
+			return 1;
+		/* Otherwise falls through */
 	default:
 		msr = find_msr_entry(vmx, msr_index);
 		if (msr) {
@@ -1224,6 +1282,8 @@ static __init int setup_vmcs_config(stru
 	      CPU_BASED_USE_IO_BITMAPS |
 	      CPU_BASED_MOV_DR_EXITING |
 	      CPU_BASED_USE_TSC_OFFSETING |
+	      CPU_BASED_MWAIT_EXITING |
+	      CPU_BASED_MONITOR_EXITING |
 	      CPU_BASED_INVLPG_EXITING;
 	opt = CPU_BASED_TPR_SHADOW |
 	      CPU_BASED_USE_MSR_BITMAPS |
@@ -1243,7 +1303,8 @@ static __init int setup_vmcs_config(stru
 			SECONDARY_EXEC_ENABLE_VPID |
 			SECONDARY_EXEC_ENABLE_EPT |
 			SECONDARY_EXEC_UNRESTRICTED_GUEST |
-			SECONDARY_EXEC_PAUSE_LOOP_EXITING;
+			SECONDARY_EXEC_PAUSE_LOOP_EXITING |
+			SECONDARY_EXEC_RDTSCP;
 		if (adjust_vmx_controls(min2, opt2,
 					MSR_IA32_VMX_PROCBASED_CTLS2,
 					&_cpu_based_2nd_exec_control) < 0)
@@ -1429,8 +1490,8 @@ static void enter_pmode(struct kvm_vcpu
 	vmcs_write32(GUEST_TR_AR_BYTES, vmx->rmode.tr.ar);
 
 	flags = vmcs_readl(GUEST_RFLAGS);
-	flags &= ~(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
-	flags |= (vmx->rmode.save_iopl << IOPL_SHIFT);
+	flags &= RMODE_GUEST_OWNED_EFLAGS_BITS;
+	flags |= vmx->rmode.save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS;
 	vmcs_writel(GUEST_RFLAGS, flags);
 
 	vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) |
@@ -1457,8 +1518,12 @@ static void enter_pmode(struct kvm_vcpu
 static gva_t rmode_tss_base(struct kvm *kvm)
 {
 	if (!kvm->arch.tss_addr) {
-		gfn_t base_gfn = kvm->memslots[0].base_gfn +
-				 kvm->memslots[0].npages - 3;
+		struct kvm_memslots *slots;
+		gfn_t base_gfn;
+
+		slots = rcu_dereference(kvm->memslots);
+		base_gfn = kvm->memslots->memslots[0].base_gfn +
+				 kvm->memslots->memslots[0].npages - 3;
 		return base_gfn << PAGE_SHIFT;
 	}
 	return kvm->arch.tss_addr;
@@ -1499,8 +1564,7 @@ static void enter_rmode(struct kvm_vcpu
 	vmcs_write32(GUEST_TR_AR_BYTES, 0x008b);
 
 	flags = vmcs_readl(GUEST_RFLAGS);
-	vmx->rmode.save_iopl
-		= (flags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
+	vmx->rmode.save_rflags = flags;
 
 	flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
 
@@ -1544,9 +1608,7 @@ static void vmx_set_efer(struct kvm_vcpu
 	 * of this msr depends on is_long_mode().
 	 */
 	vmx_load_host_state(to_vmx(vcpu));
-	vcpu->arch.shadow_efer = efer;
-	if (!msr)
-		return;
+	vcpu->arch.efer = efer;
 	if (efer & EFER_LMA) {
 		vmcs_write32(VM_ENTRY_CONTROLS,
 			     vmcs_read32(VM_ENTRY_CONTROLS) |
@@ -1576,13 +1638,13 @@ static void enter_lmode(struct kvm_vcpu
 			     (guest_tr_ar & ~AR_TYPE_MASK)
 			     | AR_TYPE_BUSY_64_TSS);
 	}
-	vcpu->arch.shadow_efer |= EFER_LMA;
-	vmx_set_efer(vcpu, vcpu->arch.shadow_efer);
+	vcpu->arch.efer |= EFER_LMA;
+	vmx_set_efer(vcpu, vcpu->arch.efer);
 }
 
 static void exit_lmode(struct kvm_vcpu *vcpu)
 {
-	vcpu->arch.shadow_efer &= ~EFER_LMA;
+	vcpu->arch.efer &= ~EFER_LMA;
 
 	vmcs_write32(VM_ENTRY_CONTROLS,
 		     vmcs_read32(VM_ENTRY_CONTROLS)
@@ -1598,10 +1660,20 @@ static void vmx_flush_tlb(struct kvm_vcp
 		ept_sync_context(construct_eptp(vcpu->arch.mmu.root_hpa));
 }
 
+static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu)
+{
+	ulong cr0_guest_owned_bits = vcpu->arch.cr0_guest_owned_bits;
+
+	vcpu->arch.cr0 &= ~cr0_guest_owned_bits;
+	vcpu->arch.cr0 |= vmcs_readl(GUEST_CR0) & cr0_guest_owned_bits;
+}
+
 static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
 {
-	vcpu->arch.cr4 &= KVM_GUEST_CR4_MASK;
-	vcpu->arch.cr4 |= vmcs_readl(GUEST_CR4) & ~KVM_GUEST_CR4_MASK;
+	ulong cr4_guest_owned_bits = vcpu->arch.cr4_guest_owned_bits;
+
+	vcpu->arch.cr4 &= ~cr4_guest_owned_bits;
+	vcpu->arch.cr4 |= vmcs_readl(GUEST_CR4) & cr4_guest_owned_bits;
 }
 
 static void ept_load_pdptrs(struct kvm_vcpu *vcpu)
@@ -1646,7 +1718,7 @@ static void ept_update_paging_mode_cr0(u
 			     (CPU_BASED_CR3_LOAD_EXITING |
 			      CPU_BASED_CR3_STORE_EXITING));
 		vcpu->arch.cr0 = cr0;
-		vmx_set_cr4(vcpu, vcpu->arch.cr4);
+		vmx_set_cr4(vcpu, kvm_read_cr4(vcpu));
 	} else if (!is_paging(vcpu)) {
 		/* From nonpaging to paging */
 		vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
@@ -1654,23 +1726,13 @@ static void ept_update_paging_mode_cr0(u
 			     ~(CPU_BASED_CR3_LOAD_EXITING |
 			       CPU_BASED_CR3_STORE_EXITING));
 		vcpu->arch.cr0 = cr0;
-		vmx_set_cr4(vcpu, vcpu->arch.cr4);
+		vmx_set_cr4(vcpu, kvm_read_cr4(vcpu));
 	}
 
 	if (!(cr0 & X86_CR0_WP))
 		*hw_cr0 &= ~X86_CR0_WP;
 }
 
-static void ept_update_paging_mode_cr4(unsigned long *hw_cr4,
-					struct kvm_vcpu *vcpu)
-{
-	if (!is_paging(vcpu)) {
-		*hw_cr4 &= ~X86_CR4_PAE;
-		*hw_cr4 |= X86_CR4_PSE;
-	} else if (!(vcpu->arch.cr4 & X86_CR4_PAE))
-		*hw_cr4 &= ~X86_CR4_PAE;
-}
-
 static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -1682,8 +1744,6 @@ static void vmx_set_cr0(struct kvm_vcpu
 	else
 		hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON;
 
-	vmx_fpu_deactivate(vcpu);
-
 	if (vmx->rmode.vm86_active && (cr0 & X86_CR0_PE))
 		enter_pmode(vcpu);
 
@@ -1691,7 +1751,7 @@ static void vmx_set_cr0(struct kvm_vcpu
 		enter_rmode(vcpu);
 
 #ifdef CONFIG_X86_64
-	if (vcpu->arch.shadow_efer & EFER_LME) {
+	if (vcpu->arch.efer & EFER_LME) {
 		if (!is_paging(vcpu) && (cr0 & X86_CR0_PG))
 			enter_lmode(vcpu);
 		if (is_paging(vcpu) && !(cr0 & X86_CR0_PG))
@@ -1702,12 +1762,12 @@ static void vmx_set_cr0(struct kvm_vcpu
 	if (enable_ept)
 		ept_update_paging_mode_cr0(&hw_cr0, cr0, vcpu);
 
+	if (!vcpu->fpu_active)
+		hw_cr0 |= X86_CR0_TS | X86_CR0_MP;
+
 	vmcs_writel(CR0_READ_SHADOW, cr0);
 	vmcs_writel(GUEST_CR0, hw_cr0);
 	vcpu->arch.cr0 = cr0;
-
-	if (!(cr0 & X86_CR0_TS) || !(cr0 & X86_CR0_PE))
-		vmx_fpu_activate(vcpu);
 }
 
 static u64 construct_eptp(unsigned long root_hpa)
@@ -1738,8 +1798,6 @@ static void vmx_set_cr3(struct kvm_vcpu
 
 	vmx_flush_tlb(vcpu);
 	vmcs_writel(GUEST_CR3, guest_cr3);
-	if (vcpu->arch.cr0 & X86_CR0_PE)
-		vmx_fpu_deactivate(vcpu);
 }
 
 static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
@@ -1748,8 +1806,14 @@ static void vmx_set_cr4(struct kvm_vcpu
 		    KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON);
 
 	vcpu->arch.cr4 = cr4;
-	if (enable_ept)
-		ept_update_paging_mode_cr4(&hw_cr4, vcpu);
+	if (enable_ept) {
+		if (!is_paging(vcpu)) {
+			hw_cr4 &= ~X86_CR4_PAE;
+			hw_cr4 |= X86_CR4_PSE;
+		} else if (!(cr4 & X86_CR4_PAE)) {
+			hw_cr4 &= ~X86_CR4_PAE;
+		}
+	}
 
 	vmcs_writel(CR4_READ_SHADOW, cr4);
 	vmcs_writel(GUEST_CR4, hw_cr4);
@@ -1787,7 +1851,7 @@ static void vmx_get_segment(struct kvm_v
 
 static int vmx_get_cpl(struct kvm_vcpu *vcpu)
 {
-	if (!(vcpu->arch.cr0 & X86_CR0_PE)) /* if real mode */
+	if (!is_protmode(vcpu))
 		return 0;
 
 	if (vmx_get_rflags(vcpu) & X86_EFLAGS_VM) /* if virtual 8086 */
@@ -2042,7 +2106,7 @@ static bool cs_ss_rpl_check(struct kvm_v
 static bool guest_state_valid(struct kvm_vcpu *vcpu)
 {
 	/* real mode guest state checks */
-	if (!(vcpu->arch.cr0 & X86_CR0_PE)) {
+	if (!is_protmode(vcpu)) {
 		if (!rmode_segment_valid(vcpu, VCPU_SREG_CS))
 			return false;
 		if (!rmode_segment_valid(vcpu, VCPU_SREG_SS))
@@ -2175,7 +2239,7 @@ static int alloc_apic_access_page(struct
 	struct kvm_userspace_memory_region kvm_userspace_mem;
 	int r = 0;
 
-	down_write(&kvm->slots_lock);
+	mutex_lock(&kvm->slots_lock);
 	if (kvm->arch.apic_access_page)
 		goto out;
 	kvm_userspace_mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT;
@@ -2188,7 +2252,7 @@ static int alloc_apic_access_page(struct
 
 	kvm->arch.apic_access_page = gfn_to_page(kvm, 0xfee00);
 out:
-	up_write(&kvm->slots_lock);
+	mutex_unlock(&kvm->slots_lock);
 	return r;
 }
 
@@ -2197,7 +2261,7 @@ static int alloc_identity_pagetable(stru
 	struct kvm_userspace_memory_region kvm_userspace_mem;
 	int r = 0;
 
-	down_write(&kvm->slots_lock);
+	mutex_lock(&kvm->slots_lock);
 	if (kvm->arch.ept_identity_pagetable)
 		goto out;
 	kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT;
@@ -2212,7 +2276,7 @@ static int alloc_identity_pagetable(stru
 	kvm->arch.ept_identity_pagetable = gfn_to_page(kvm,
 			kvm->arch.ept_identity_map_addr >> PAGE_SHIFT);
 out:
-	up_write(&kvm->slots_lock);
+	mutex_unlock(&kvm->slots_lock);
 	return r;
 }
 
@@ -2384,14 +2448,12 @@ static int vmx_vcpu_setup(struct vcpu_vm
 	for (i = 0; i < NR_VMX_MSR; ++i) {
 		u32 index = vmx_msr_index[i];
 		u32 data_low, data_high;
-		u64 data;
 		int j = vmx->nmsrs;
 
 		if (rdmsr_safe(index, &data_low, &data_high) < 0)
 			continue;
 		if (wrmsr_safe(index, data_low, data_high) < 0)
 			continue;
-		data = data_low | ((u64)data_high << 32);
 		vmx->guest_msrs[j].index = i;
 		vmx->guest_msrs[j].data = 0;
 		vmx->guest_msrs[j].mask = -1ull;
@@ -2404,7 +2466,10 @@ static int vmx_vcpu_setup(struct vcpu_vm
 	vmcs_write32(VM_ENTRY_CONTROLS, vmcs_config.vmentry_ctrl);
 
 	vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL);
-	vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK);
+	vmx->vcpu.arch.cr4_guest_owned_bits = KVM_CR4_GUEST_OWNED_BITS;
+	if (enable_ept)
+		vmx->vcpu.arch.cr4_guest_owned_bits |= X86_CR4_PGE;
+	vmcs_writel(CR4_GUEST_HOST_MASK, ~vmx->vcpu.arch.cr4_guest_owned_bits);
 
 	tsc_base = vmx->vcpu.kvm->arch.vm_init_tsc;
 	rdtscll(tsc_this);
@@ -2429,10 +2494,10 @@ static int vmx_vcpu_reset(struct kvm_vcp
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	u64 msr;
-	int ret;
+	int ret, idx;
 
 	vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP));
-	down_read(&vcpu->kvm->slots_lock);
+	idx = srcu_read_lock(&vcpu->kvm->srcu);
 	if (!init_rmode(vmx->vcpu.kvm)) {
 		ret = -ENOMEM;
 		goto out;
@@ -2526,7 +2591,7 @@ static int vmx_vcpu_reset(struct kvm_vcp
 		vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid);
 
 	vmx->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET;
-	vmx_set_cr0(&vmx->vcpu, vmx->vcpu.arch.cr0); /* enter rmode */
+	vmx_set_cr0(&vmx->vcpu, kvm_read_cr0(vcpu)); /* enter rmode */
 	vmx_set_cr4(&vmx->vcpu, 0);
 	vmx_set_efer(&vmx->vcpu, 0);
 	vmx_fpu_activate(&vmx->vcpu);
@@ -2540,7 +2605,7 @@ static int vmx_vcpu_reset(struct kvm_vcp
 	vmx->emulation_required = 0;
 
 out:
-	up_read(&vcpu->kvm->slots_lock);
+	srcu_read_unlock(&vcpu->kvm->srcu, idx);
 	return ret;
 }
 
@@ -2638,8 +2703,7 @@ static int vmx_nmi_allowed(struct kvm_vc
 		return 0;
 
 	return	!(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
-			(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS |
-				GUEST_INTR_STATE_NMI));
+			(GUEST_INTR_STATE_MOV_SS | GUEST_INTR_STATE_NMI));
 }
 
 static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu)
@@ -2717,6 +2781,12 @@ static int handle_rmode_exception(struct
 		kvm_queue_exception(vcpu, vec);
 		return 1;
 	case BP_VECTOR:
+		/*
+		 * Update instruction length as we may reinject the exception
+		 * from user space while in guest debugging mode.
+		 */
+		to_vmx(vcpu)->vcpu.arch.event_exit_inst_len =
+			vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
 		if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
 			return 0;
 		/* fall through */
@@ -2839,6 +2909,13 @@ static int handle_exception(struct kvm_v
 		kvm_run->debug.arch.dr7 = vmcs_readl(GUEST_DR7);
 		/* fall through */
 	case BP_VECTOR:
+		/*
+		 * Update instruction length as we may reinject #BP from
+		 * user space while in guest debugging mode. Reading it for
+		 * #DB as well causes no harm, it is not used in that case.
+		 */
+		vmx->vcpu.arch.event_exit_inst_len =
+			vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
 		kvm_run->exit_reason = KVM_EXIT_DEBUG;
 		kvm_run->debug.arch.pc = vmcs_readl(GUEST_CS_BASE) + rip;
 		kvm_run->debug.arch.exception = ex_no;
@@ -2940,11 +3017,10 @@ static int handle_cr(struct kvm_vcpu *vc
 		};
 		break;
 	case 2: /* clts */
-		vmx_fpu_deactivate(vcpu);
-		vcpu->arch.cr0 &= ~X86_CR0_TS;
-		vmcs_writel(CR0_READ_SHADOW, vcpu->arch.cr0);
-		vmx_fpu_activate(vcpu);
+		vmx_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~X86_CR0_TS));
+		trace_kvm_cr_write(0, kvm_read_cr0(vcpu));
 		skip_emulated_instruction(vcpu);
+		vmx_fpu_activate(vcpu);
 		return 1;
 	case 1: /*mov from cr*/
 		switch (cr) {
@@ -2962,7 +3038,9 @@ static int handle_cr(struct kvm_vcpu *vc
 		}
 		break;
 	case 3: /* lmsw */
-		kvm_lmsw(vcpu, (exit_qualification >> LMSW_SOURCE_DATA_SHIFT) & 0x0f);
+		val = (exit_qualification >> LMSW_SOURCE_DATA_SHIFT) & 0x0f;
+		trace_kvm_cr_write(0, (kvm_read_cr0(vcpu) & ~0xful) | val);
+		kvm_lmsw(vcpu, val);
 
 		skip_emulated_instruction(vcpu);
 		return 1;
@@ -2975,12 +3053,22 @@ static int handle_cr(struct kvm_vcpu *vc
 	return 0;
 }
 
+static int check_dr_alias(struct kvm_vcpu *vcpu)
+{
+	if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) {
+		kvm_queue_exception(vcpu, UD_VECTOR);
+		return -1;
+	}
+	return 0;
+}
+
 static int handle_dr(struct kvm_vcpu *vcpu)
 {
 	unsigned long exit_qualification;
 	unsigned long val;
 	int dr, reg;
 
+	/* Do not handle if the CPL > 0, will trigger GP on re-entry */
 	if (!kvm_require_cpl(vcpu, 0))
 		return 1;
 	dr = vmcs_readl(GUEST_DR7);
@@ -3016,14 +3104,20 @@ static int handle_dr(struct kvm_vcpu *vc
 		case 0 ... 3:
 			val = vcpu->arch.db[dr];
 			break;
+		case 4:
+			if (check_dr_alias(vcpu) < 0)
+				return 1;
+			/* fall through */
 		case 6:
 			val = vcpu->arch.dr6;
 			break;
-		case 7:
+		case 5:
+			if (check_dr_alias(vcpu) < 0)
+				return 1;
+			/* fall through */
+		default: /* 7 */
 			val = vcpu->arch.dr7;
 			break;
-		default:
-			val = 0;
 		}
 		kvm_register_write(vcpu, reg, val);
 	} else {
@@ -3034,21 +3128,25 @@ static int handle_dr(struct kvm_vcpu *vc
 			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 4:
+			if (check_dr_alias(vcpu) < 0)
+				return 1;
+			/* fall through */
 		case 6:
 			if (val & 0xffffffff00000000ULL) {
-				kvm_queue_exception(vcpu, GP_VECTOR);
-				break;
+				kvm_inject_gp(vcpu, 0);
+				return 1;
 			}
 			vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1;
 			break;
-		case 7:
+		case 5:
+			if (check_dr_alias(vcpu) < 0)
+				return 1;
+			/* fall through */
+		default: /* 7 */
 			if (val & 0xffffffff00000000ULL) {
-				kvm_queue_exception(vcpu, GP_VECTOR);
-				break;
+				kvm_inject_gp(vcpu, 0);
+				return 1;
 			}
 			vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1;
 			if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) {
@@ -3075,6 +3173,7 @@ static int handle_rdmsr(struct kvm_vcpu
 	u64 data;
 
 	if (vmx_get_msr(vcpu, ecx, &data)) {
+		trace_kvm_msr_read_ex(ecx);
 		kvm_inject_gp(vcpu, 0);
 		return 1;
 	}
@@ -3094,13 +3193,13 @@ static int handle_wrmsr(struct kvm_vcpu
 	u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u)
 		| ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32);
 
-	trace_kvm_msr_write(ecx, data);
-
 	if (vmx_set_msr(vcpu, ecx, data) != 0) {
+		trace_kvm_msr_write_ex(ecx, data);
 		kvm_inject_gp(vcpu, 0);
 		return 1;
 	}
 
+	trace_kvm_msr_write(ecx, data);
 	skip_emulated_instruction(vcpu);
 	return 1;
 }
@@ -3385,7 +3484,6 @@ static int handle_invalid_guest_state(st
 		}
 
 		if (err != EMULATE_DONE) {
-			kvm_report_emulation_failure(vcpu, "emulation failure");
 			vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
 			vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
 			vcpu->run->internal.ndata = 0;
@@ -3416,6 +3514,12 @@ static int handle_pause(struct kvm_vcpu
 	return 1;
 }
 
+static int handle_invalid_op(struct kvm_vcpu *vcpu)
+{
+	kvm_queue_exception(vcpu, UD_VECTOR);
+	return 1;
+}
+
 /*
  * The exit handlers return 1 if the exit was handled fully and guest execution
  * may resume.  Otherwise they set the kvm_run parameter to indicate what needs
@@ -3453,6 +3557,8 @@ static int (*kvm_vmx_exit_handlers[])(st
 	[EXIT_REASON_EPT_VIOLATION]	      = handle_ept_violation,
 	[EXIT_REASON_EPT_MISCONFIG]           = handle_ept_misconfig,
 	[EXIT_REASON_PAUSE_INSTRUCTION]       = handle_pause,
+	[EXIT_REASON_MWAIT_INSTRUCTION]	      = handle_invalid_op,
+	[EXIT_REASON_MONITOR_INSTRUCTION]     = handle_invalid_op,
 };
 
 static const int kvm_vmx_max_exit_handlers =
@@ -3686,9 +3792,6 @@ static void vmx_vcpu_run(struct kvm_vcpu
 	 */
 	vmcs_writel(HOST_CR0, read_cr0());
 
-	if (vcpu->arch.switch_db_regs)
-		set_debugreg(vcpu->arch.dr6, 6);
-
 	asm(
 		/* Store host registers */
 		"push %%"R"dx; push %%"R"bp;"
@@ -3789,9 +3892,6 @@ static void vmx_vcpu_run(struct kvm_vcpu
 				  | (1 << VCPU_EXREG_PDPTR));
 	vcpu->arch.regs_dirty = 0;
 
-	if (vcpu->arch.switch_db_regs)
-		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);
@@ -3920,7 +4020,7 @@ static u64 vmx_get_mt_mask(struct kvm_vc
 	 *   b. VT-d with snooping control feature: snooping control feature of
 	 *	VT-d engine can guarantee the cache correctness. Just set it
 	 *	to WB to keep consistent with host. So the same as item 3.
-	 * 3. EPT without VT-d: always map as WB and set IGMT=1 to keep
+	 * 3. EPT without VT-d: always map as WB and set IPAT=1 to keep
 	 *    consistent with host MTRR
 	 */
 	if (is_mmio)
@@ -3931,37 +4031,88 @@ static u64 vmx_get_mt_mask(struct kvm_vc
 		      VMX_EPT_MT_EPTE_SHIFT;
 	else
 		ret = (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT)
-			| VMX_EPT_IGMT_BIT;
+			| VMX_EPT_IPAT_BIT;
 
 	return ret;
 }
 
+#define _ER(x) { EXIT_REASON_##x, #x }
+
 static const struct trace_print_flags vmx_exit_reasons_str[] = {
-	{ EXIT_REASON_EXCEPTION_NMI,           "exception" },
-	{ EXIT_REASON_EXTERNAL_INTERRUPT,      "ext_irq" },
-	{ EXIT_REASON_TRIPLE_FAULT,            "triple_fault" },
-	{ EXIT_REASON_NMI_WINDOW,              "nmi_window" },
-	{ EXIT_REASON_IO_INSTRUCTION,          "io_instruction" },
-	{ EXIT_REASON_CR_ACCESS,               "cr_access" },
-	{ EXIT_REASON_DR_ACCESS,               "dr_access" },
-	{ EXIT_REASON_CPUID,                   "cpuid" },
-	{ EXIT_REASON_MSR_READ,                "rdmsr" },
-	{ EXIT_REASON_MSR_WRITE,               "wrmsr" },
-	{ EXIT_REASON_PENDING_INTERRUPT,       "interrupt_window" },
-	{ EXIT_REASON_HLT,                     "halt" },
-	{ EXIT_REASON_INVLPG,                  "invlpg" },
-	{ EXIT_REASON_VMCALL,                  "hypercall" },
-	{ EXIT_REASON_TPR_BELOW_THRESHOLD,     "tpr_below_thres" },
-	{ EXIT_REASON_APIC_ACCESS,             "apic_access" },
-	{ EXIT_REASON_WBINVD,                  "wbinvd" },
-	{ EXIT_REASON_TASK_SWITCH,             "task_switch" },
-	{ EXIT_REASON_EPT_VIOLATION,           "ept_violation" },
+	_ER(EXCEPTION_NMI),
+	_ER(EXTERNAL_INTERRUPT),
+	_ER(TRIPLE_FAULT),
+	_ER(PENDING_INTERRUPT),
+	_ER(NMI_WINDOW),
+	_ER(TASK_SWITCH),
+	_ER(CPUID),
+	_ER(HLT),
+	_ER(INVLPG),
+	_ER(RDPMC),
+	_ER(RDTSC),
+	_ER(VMCALL),
+	_ER(VMCLEAR),
+	_ER(VMLAUNCH),
+	_ER(VMPTRLD),
+	_ER(VMPTRST),
+	_ER(VMREAD),
+	_ER(VMRESUME),
+	_ER(VMWRITE),
+	_ER(VMOFF),
+	_ER(VMON),
+	_ER(CR_ACCESS),
+	_ER(DR_ACCESS),
+	_ER(IO_INSTRUCTION),
+	_ER(MSR_READ),
+	_ER(MSR_WRITE),
+	_ER(MWAIT_INSTRUCTION),
+	_ER(MONITOR_INSTRUCTION),
+	_ER(PAUSE_INSTRUCTION),
+	_ER(MCE_DURING_VMENTRY),
+	_ER(TPR_BELOW_THRESHOLD),
+	_ER(APIC_ACCESS),
+	_ER(EPT_VIOLATION),
+	_ER(EPT_MISCONFIG),
+	_ER(WBINVD),
 	{ -1, NULL }
 };
 
-static bool vmx_gb_page_enable(void)
+#undef _ER
+
+static int vmx_get_lpage_level(void)
 {
-	return false;
+	if (enable_ept && !cpu_has_vmx_ept_1g_page())
+		return PT_DIRECTORY_LEVEL;
+	else
+		/* For shadow and EPT supported 1GB page */
+		return PT_PDPE_LEVEL;
+}
+
+static inline u32 bit(int bitno)
+{
+	return 1 << (bitno & 31);
+}
+
+static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
+{
+	struct kvm_cpuid_entry2 *best;
+	struct vcpu_vmx *vmx = to_vmx(vcpu);
+	u32 exec_control;
+
+	vmx->rdtscp_enabled = false;
+	if (vmx_rdtscp_supported()) {
+		exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
+		if (exec_control & SECONDARY_EXEC_RDTSCP) {
+			best = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
+			if (best && (best->edx & bit(X86_FEATURE_RDTSCP)))
+				vmx->rdtscp_enabled = true;
+			else {
+				exec_control &= ~SECONDARY_EXEC_RDTSCP;
+				vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
+						exec_control);
+			}
+		}
+	}
 }
 
 static struct kvm_x86_ops vmx_x86_ops = {
@@ -3990,6 +4141,7 @@ static struct kvm_x86_ops vmx_x86_ops =
 	.set_segment = vmx_set_segment,
 	.get_cpl = vmx_get_cpl,
 	.get_cs_db_l_bits = vmx_get_cs_db_l_bits,
+	.decache_cr0_guest_bits = vmx_decache_cr0_guest_bits,
 	.decache_cr4_guest_bits = vmx_decache_cr4_guest_bits,
 	.set_cr0 = vmx_set_cr0,
 	.set_cr3 = vmx_set_cr3,
@@ -4002,6 +4154,8 @@ static struct kvm_x86_ops vmx_x86_ops =
 	.cache_reg = vmx_cache_reg,
 	.get_rflags = vmx_get_rflags,
 	.set_rflags = vmx_set_rflags,
+	.fpu_activate = vmx_fpu_activate,
+	.fpu_deactivate = vmx_fpu_deactivate,
 
 	.tlb_flush = vmx_flush_tlb,
 
@@ -4027,7 +4181,11 @@ static struct kvm_x86_ops vmx_x86_ops =
 	.get_mt_mask = vmx_get_mt_mask,
 
 	.exit_reasons_str = vmx_exit_reasons_str,
-	.gb_page_enable = vmx_gb_page_enable,
+	.get_lpage_level = vmx_get_lpage_level,
+
+	.cpuid_update = vmx_cpuid_update,
+
+	.rdtscp_supported = vmx_rdtscp_supported,
 };
 
 static int __init vmx_init(void)
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/x86.c linux-libre-2.6.34-gnu1/arch/x86/kvm/x86.c
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/x86.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/x86.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,8 @@
 #include <linux/intel-iommu.h>
 #include <linux/cpufreq.h>
 #include <linux/user-return-notifier.h>
+#include <linux/srcu.h>
+#include <linux/slab.h>
 #include <trace/events/kvm.h>
 #undef TRACE_INCLUDE_FILE
 #define CREATE_TRACE_POINTS
@@ -93,16 +95,16 @@ module_param_named(ignore_msrs, ignore_m
 
 struct kvm_shared_msrs_global {
 	int nr;
-	struct kvm_shared_msr {
-		u32 msr;
-		u64 value;
-	} msrs[KVM_NR_SHARED_MSRS];
+	u32 msrs[KVM_NR_SHARED_MSRS];
 };
 
 struct kvm_shared_msrs {
 	struct user_return_notifier urn;
 	bool registered;
-	u64 current_value[KVM_NR_SHARED_MSRS];
+	struct kvm_shared_msr_values {
+		u64 host;
+		u64 curr;
+	} values[KVM_NR_SHARED_MSRS];
 };
 
 static struct kvm_shared_msrs_global __read_mostly shared_msrs_global;
@@ -147,53 +149,64 @@ struct kvm_stats_debugfs_item debugfs_en
 static void kvm_on_user_return(struct user_return_notifier *urn)
 {
 	unsigned slot;
-	struct kvm_shared_msr *global;
 	struct kvm_shared_msrs *locals
 		= container_of(urn, struct kvm_shared_msrs, urn);
+	struct kvm_shared_msr_values *values;
 
 	for (slot = 0; slot < shared_msrs_global.nr; ++slot) {
-		global = &shared_msrs_global.msrs[slot];
-		if (global->value != locals->current_value[slot]) {
-			wrmsrl(global->msr, global->value);
-			locals->current_value[slot] = global->value;
+		values = &locals->values[slot];
+		if (values->host != values->curr) {
+			wrmsrl(shared_msrs_global.msrs[slot], values->host);
+			values->curr = values->host;
 		}
 	}
 	locals->registered = false;
 	user_return_notifier_unregister(urn);
 }
 
-void kvm_define_shared_msr(unsigned slot, u32 msr)
+static void shared_msr_update(unsigned slot, u32 msr)
 {
-	int cpu;
+	struct kvm_shared_msrs *smsr;
 	u64 value;
 
+	smsr = &__get_cpu_var(shared_msrs);
+	/* only read, and nobody should modify it at this time,
+	 * so don't need lock */
+	if (slot >= shared_msrs_global.nr) {
+		printk(KERN_ERR "kvm: invalid MSR slot!");
+		return;
+	}
+	rdmsrl_safe(msr, &value);
+	smsr->values[slot].host = value;
+	smsr->values[slot].curr = value;
+}
+
+void kvm_define_shared_msr(unsigned slot, u32 msr)
+{
 	if (slot >= shared_msrs_global.nr)
 		shared_msrs_global.nr = slot + 1;
-	shared_msrs_global.msrs[slot].msr = msr;
-	rdmsrl_safe(msr, &value);
-	shared_msrs_global.msrs[slot].value = value;
-	for_each_online_cpu(cpu)
-		per_cpu(shared_msrs, cpu).current_value[slot] = value;
+	shared_msrs_global.msrs[slot] = msr;
+	/* we need ensured the shared_msr_global have been updated */
+	smp_wmb();
 }
 EXPORT_SYMBOL_GPL(kvm_define_shared_msr);
 
 static void kvm_shared_msr_cpu_online(void)
 {
 	unsigned i;
-	struct kvm_shared_msrs *locals = &__get_cpu_var(shared_msrs);
 
 	for (i = 0; i < shared_msrs_global.nr; ++i)
-		locals->current_value[i] = shared_msrs_global.msrs[i].value;
+		shared_msr_update(i, shared_msrs_global.msrs[i]);
 }
 
 void kvm_set_shared_msr(unsigned slot, u64 value, u64 mask)
 {
 	struct kvm_shared_msrs *smsr = &__get_cpu_var(shared_msrs);
 
-	if (((value ^ smsr->current_value[slot]) & mask) == 0)
+	if (((value ^ smsr->values[slot].curr) & mask) == 0)
 		return;
-	smsr->current_value[slot] = value;
-	wrmsrl(shared_msrs_global.msrs[slot].msr, value);
+	smsr->values[slot].curr = value;
+	wrmsrl(shared_msrs_global.msrs[slot], value);
 	if (!smsr->registered) {
 		smsr->urn.on_user_return = kvm_on_user_return;
 		user_return_notifier_register(&smsr->urn);
@@ -257,12 +270,68 @@ void kvm_set_apic_base(struct kvm_vcpu *
 }
 EXPORT_SYMBOL_GPL(kvm_set_apic_base);
 
+#define EXCPT_BENIGN		0
+#define EXCPT_CONTRIBUTORY	1
+#define EXCPT_PF		2
+
+static int exception_class(int vector)
+{
+	switch (vector) {
+	case PF_VECTOR:
+		return EXCPT_PF;
+	case DE_VECTOR:
+	case TS_VECTOR:
+	case NP_VECTOR:
+	case SS_VECTOR:
+	case GP_VECTOR:
+		return EXCPT_CONTRIBUTORY;
+	default:
+		break;
+	}
+	return EXCPT_BENIGN;
+}
+
+static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
+		unsigned nr, bool has_error, u32 error_code)
+{
+	u32 prev_nr;
+	int class1, class2;
+
+	if (!vcpu->arch.exception.pending) {
+	queue:
+		vcpu->arch.exception.pending = true;
+		vcpu->arch.exception.has_error_code = has_error;
+		vcpu->arch.exception.nr = nr;
+		vcpu->arch.exception.error_code = error_code;
+		return;
+	}
+
+	/* to check exception */
+	prev_nr = vcpu->arch.exception.nr;
+	if (prev_nr == DF_VECTOR) {
+		/* triple fault -> shutdown */
+		set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
+		return;
+	}
+	class1 = exception_class(prev_nr);
+	class2 = exception_class(nr);
+	if ((class1 == EXCPT_CONTRIBUTORY && class2 == EXCPT_CONTRIBUTORY)
+		|| (class1 == EXCPT_PF && class2 != EXCPT_BENIGN)) {
+		/* generate double fault per SDM Table 5-5 */
+		vcpu->arch.exception.pending = true;
+		vcpu->arch.exception.has_error_code = true;
+		vcpu->arch.exception.nr = DF_VECTOR;
+		vcpu->arch.exception.error_code = 0;
+	} else
+		/* replace previous exception with a new one in a hope
+		   that instruction re-execution will regenerate lost
+		   exception */
+		goto queue;
+}
+
 void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr)
 {
-	WARN_ON(vcpu->arch.exception.pending);
-	vcpu->arch.exception.pending = true;
-	vcpu->arch.exception.has_error_code = false;
-	vcpu->arch.exception.nr = nr;
+	kvm_multiple_exception(vcpu, nr, false, 0);
 }
 EXPORT_SYMBOL_GPL(kvm_queue_exception);
 
@@ -270,25 +339,6 @@ void kvm_inject_page_fault(struct kvm_vc
 			   u32 error_code)
 {
 	++vcpu->stat.pf_guest;
-
-	if (vcpu->arch.exception.pending) {
-		switch(vcpu->arch.exception.nr) {
-		case DF_VECTOR:
-			/* triple fault -> shutdown */
-			set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
-			return;
-		case PF_VECTOR:
-			vcpu->arch.exception.nr = DF_VECTOR;
-			vcpu->arch.exception.error_code = 0;
-			return;
-		default:
-			/* replace previous exception with a new one in a hope
-			   that instruction re-execution will regenerate lost
-			   exception */
-			vcpu->arch.exception.pending = false;
-			break;
-		}
-	}
 	vcpu->arch.cr2 = addr;
 	kvm_queue_exception_e(vcpu, PF_VECTOR, error_code);
 }
@@ -301,11 +351,7 @@ EXPORT_SYMBOL_GPL(kvm_inject_nmi);
 
 void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code)
 {
-	WARN_ON(vcpu->arch.exception.pending);
-	vcpu->arch.exception.pending = true;
-	vcpu->arch.exception.has_error_code = true;
-	vcpu->arch.exception.nr = nr;
-	vcpu->arch.exception.error_code = error_code;
+	kvm_multiple_exception(vcpu, nr, true, error_code);
 }
 EXPORT_SYMBOL_GPL(kvm_queue_exception_e);
 
@@ -383,41 +429,38 @@ out:
 
 void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 {
-	if (cr0 & CR0_RESERVED_BITS) {
-		printk(KERN_DEBUG "set_cr0: 0x%lx #GP, reserved bits 0x%lx\n",
-		       cr0, vcpu->arch.cr0);
+	cr0 |= X86_CR0_ET;
+
+#ifdef CONFIG_X86_64
+	if (cr0 & 0xffffffff00000000UL) {
 		kvm_inject_gp(vcpu, 0);
 		return;
 	}
+#endif
+
+	cr0 &= ~CR0_RESERVED_BITS;
 
 	if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) {
-		printk(KERN_DEBUG "set_cr0: #GP, CD == 0 && NW == 1\n");
 		kvm_inject_gp(vcpu, 0);
 		return;
 	}
 
 	if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) {
-		printk(KERN_DEBUG "set_cr0: #GP, set PG flag "
-		       "and a clear PE flag\n");
 		kvm_inject_gp(vcpu, 0);
 		return;
 	}
 
 	if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) {
 #ifdef CONFIG_X86_64
-		if ((vcpu->arch.shadow_efer & EFER_LME)) {
+		if ((vcpu->arch.efer & EFER_LME)) {
 			int cs_db, cs_l;
 
 			if (!is_pae(vcpu)) {
-				printk(KERN_DEBUG "set_cr0: #GP, start paging "
-				       "in long mode while PAE is disabled\n");
 				kvm_inject_gp(vcpu, 0);
 				return;
 			}
 			kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
 			if (cs_l) {
-				printk(KERN_DEBUG "set_cr0: #GP, start paging "
-				       "in long mode while CS.L == 1\n");
 				kvm_inject_gp(vcpu, 0);
 				return;
 
@@ -425,8 +468,6 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu,
 		} else
 #endif
 		if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.cr3)) {
-			printk(KERN_DEBUG "set_cr0: #GP, pdptrs "
-			       "reserved bits\n");
 			kvm_inject_gp(vcpu, 0);
 			return;
 		}
@@ -443,38 +484,33 @@ EXPORT_SYMBOL_GPL(kvm_set_cr0);
 
 void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw)
 {
-	kvm_set_cr0(vcpu, (vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f));
+	kvm_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~0x0ful) | (msw & 0x0f));
 }
 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 old_cr4 = kvm_read_cr4(vcpu);
 	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);
 		return;
 	}
 
 	if (is_long_mode(vcpu)) {
 		if (!(cr4 & X86_CR4_PAE)) {
-			printk(KERN_DEBUG "set_cr4: #GP, clearing PAE while "
-			       "in long mode\n");
 			kvm_inject_gp(vcpu, 0);
 			return;
 		}
 	} 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);
 		return;
 	}
 
 	if (cr4 & X86_CR4_VMXE) {
-		printk(KERN_DEBUG "set_cr4: #GP, setting VMXE\n");
 		kvm_inject_gp(vcpu, 0);
 		return;
 	}
@@ -495,21 +531,16 @@ void kvm_set_cr3(struct kvm_vcpu *vcpu,
 
 	if (is_long_mode(vcpu)) {
 		if (cr3 & CR3_L_MODE_RESERVED_BITS) {
-			printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n");
 			kvm_inject_gp(vcpu, 0);
 			return;
 		}
 	} else {
 		if (is_pae(vcpu)) {
 			if (cr3 & CR3_PAE_RESERVED_BITS) {
-				printk(KERN_DEBUG
-				       "set_cr3: #GP, reserved bits\n");
 				kvm_inject_gp(vcpu, 0);
 				return;
 			}
 			if (is_paging(vcpu) && !load_pdptrs(vcpu, cr3)) {
-				printk(KERN_DEBUG "set_cr3: #GP, pdptrs "
-				       "reserved bits\n");
 				kvm_inject_gp(vcpu, 0);
 				return;
 			}
@@ -541,7 +572,6 @@ EXPORT_SYMBOL_GPL(kvm_set_cr3);
 void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
 {
 	if (cr8 & CR8_RESERVED_BITS) {
-		printk(KERN_DEBUG "set_cr8: #GP, reserved bits 0x%lx\n", cr8);
 		kvm_inject_gp(vcpu, 0);
 		return;
 	}
@@ -575,9 +605,11 @@ static inline u32 bit(int bitno)
  * kvm-specific. Those are put in the beginning of the list.
  */
 
-#define KVM_SAVE_MSRS_BEGIN	2
+#define KVM_SAVE_MSRS_BEGIN	5
 static u32 msrs_to_save[] = {
 	MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
+	HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL,
+	HV_X64_MSR_APIC_ASSIST_PAGE,
 	MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
 	MSR_K6_STAR,
 #ifdef CONFIG_X86_64
@@ -595,15 +627,12 @@ static u32 emulated_msrs[] = {
 static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
 {
 	if (efer & efer_reserved_bits) {
-		printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n",
-		       efer);
 		kvm_inject_gp(vcpu, 0);
 		return;
 	}
 
 	if (is_paging(vcpu)
-	    && (vcpu->arch.shadow_efer & EFER_LME) != (efer & EFER_LME)) {
-		printk(KERN_DEBUG "set_efer: #GP, change LME while paging\n");
+	    && (vcpu->arch.efer & EFER_LME) != (efer & EFER_LME)) {
 		kvm_inject_gp(vcpu, 0);
 		return;
 	}
@@ -613,7 +642,6 @@ static void set_efer(struct kvm_vcpu *vc
 
 		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;
 		}
@@ -624,7 +652,6 @@ static void set_efer(struct kvm_vcpu *vc
 
 		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;
 		}
@@ -633,9 +660,9 @@ static void set_efer(struct kvm_vcpu *vc
 	kvm_x86_ops->set_efer(vcpu, efer);
 
 	efer &= ~EFER_LMA;
-	efer |= vcpu->arch.shadow_efer & EFER_LMA;
+	efer |= vcpu->arch.efer & EFER_LMA;
 
-	vcpu->arch.shadow_efer = efer;
+	vcpu->arch.efer = efer;
 
 	vcpu->arch.mmu.base_role.nxe = (efer & EFER_NX) && !tdp_enabled;
 	kvm_mmu_reset_context(vcpu);
@@ -913,9 +940,13 @@ static int set_msr_mce(struct kvm_vcpu *
 		if (msr >= MSR_IA32_MC0_CTL &&
 		    msr < MSR_IA32_MC0_CTL + 4 * bank_num) {
 			u32 offset = msr - MSR_IA32_MC0_CTL;
-			/* only 0 or all 1s can be written to IA32_MCi_CTL */
+			/* only 0 or all 1s can be written to IA32_MCi_CTL
+			 * some Linux kernels though clear bit 10 in bank 4 to
+			 * workaround a BIOS/GART TBL issue on AMD K8s, ignore
+			 * this to avoid an uncatched #GP in the guest
+			 */
 			if ((offset & 0x3) == 0 &&
-			    data != 0 && data != ~(u64)0)
+			    data != 0 && (data | (1 << 10)) != ~(u64)0)
 				return -1;
 			vcpu->arch.mce_banks[offset] = data;
 			break;
@@ -957,6 +988,100 @@ out:
 	return r;
 }
 
+static bool kvm_hv_hypercall_enabled(struct kvm *kvm)
+{
+	return kvm->arch.hv_hypercall & HV_X64_MSR_HYPERCALL_ENABLE;
+}
+
+static bool kvm_hv_msr_partition_wide(u32 msr)
+{
+	bool r = false;
+	switch (msr) {
+	case HV_X64_MSR_GUEST_OS_ID:
+	case HV_X64_MSR_HYPERCALL:
+		r = true;
+		break;
+	}
+
+	return r;
+}
+
+static int set_msr_hyperv_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+{
+	struct kvm *kvm = vcpu->kvm;
+
+	switch (msr) {
+	case HV_X64_MSR_GUEST_OS_ID:
+		kvm->arch.hv_guest_os_id = data;
+		/* setting guest os id to zero disables hypercall page */
+		if (!kvm->arch.hv_guest_os_id)
+			kvm->arch.hv_hypercall &= ~HV_X64_MSR_HYPERCALL_ENABLE;
+		break;
+	case HV_X64_MSR_HYPERCALL: {
+		u64 gfn;
+		unsigned long addr;
+		u8 instructions[4];
+
+		/* if guest os id is not set hypercall should remain disabled */
+		if (!kvm->arch.hv_guest_os_id)
+			break;
+		if (!(data & HV_X64_MSR_HYPERCALL_ENABLE)) {
+			kvm->arch.hv_hypercall = data;
+			break;
+		}
+		gfn = data >> HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT;
+		addr = gfn_to_hva(kvm, gfn);
+		if (kvm_is_error_hva(addr))
+			return 1;
+		kvm_x86_ops->patch_hypercall(vcpu, instructions);
+		((unsigned char *)instructions)[3] = 0xc3; /* ret */
+		if (copy_to_user((void __user *)addr, instructions, 4))
+			return 1;
+		kvm->arch.hv_hypercall = data;
+		break;
+	}
+	default:
+		pr_unimpl(vcpu, "HYPER-V unimplemented wrmsr: 0x%x "
+			  "data 0x%llx\n", msr, data);
+		return 1;
+	}
+	return 0;
+}
+
+static int set_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+{
+	switch (msr) {
+	case HV_X64_MSR_APIC_ASSIST_PAGE: {
+		unsigned long addr;
+
+		if (!(data & HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE)) {
+			vcpu->arch.hv_vapic = data;
+			break;
+		}
+		addr = gfn_to_hva(vcpu->kvm, data >>
+				  HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT);
+		if (kvm_is_error_hva(addr))
+			return 1;
+		if (clear_user((void __user *)addr, PAGE_SIZE))
+			return 1;
+		vcpu->arch.hv_vapic = data;
+		break;
+	}
+	case HV_X64_MSR_EOI:
+		return kvm_hv_vapic_msr_write(vcpu, APIC_EOI, data);
+	case HV_X64_MSR_ICR:
+		return kvm_hv_vapic_msr_write(vcpu, APIC_ICR, data);
+	case HV_X64_MSR_TPR:
+		return kvm_hv_vapic_msr_write(vcpu, APIC_TASKPRI, data);
+	default:
+		pr_unimpl(vcpu, "HYPER-V unimplemented wrmsr: 0x%x "
+			  "data 0x%llx\n", msr, data);
+		return 1;
+	}
+
+	return 0;
+}
+
 int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
 {
 	switch (msr) {
@@ -1071,6 +1196,16 @@ int kvm_set_msr_common(struct kvm_vcpu *
 		pr_unimpl(vcpu, "unimplemented perfctr wrmsr: "
 			"0x%x data 0x%llx\n", msr, data);
 		break;
+	case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
+		if (kvm_hv_msr_partition_wide(msr)) {
+			int r;
+			mutex_lock(&vcpu->kvm->lock);
+			r = set_msr_hyperv_pw(vcpu, msr, data);
+			mutex_unlock(&vcpu->kvm->lock);
+			return r;
+		} else
+			return set_msr_hyperv(vcpu, msr, data);
+		break;
 	default:
 		if (msr && (msr == vcpu->kvm->arch.xen_hvm_config.msr))
 			return xen_hvm_config(vcpu, data);
@@ -1170,6 +1305,54 @@ static int get_msr_mce(struct kvm_vcpu *
 	return 0;
 }
 
+static int get_msr_hyperv_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
+{
+	u64 data = 0;
+	struct kvm *kvm = vcpu->kvm;
+
+	switch (msr) {
+	case HV_X64_MSR_GUEST_OS_ID:
+		data = kvm->arch.hv_guest_os_id;
+		break;
+	case HV_X64_MSR_HYPERCALL:
+		data = kvm->arch.hv_hypercall;
+		break;
+	default:
+		pr_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
+		return 1;
+	}
+
+	*pdata = data;
+	return 0;
+}
+
+static int get_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
+{
+	u64 data = 0;
+
+	switch (msr) {
+	case HV_X64_MSR_VP_INDEX: {
+		int r;
+		struct kvm_vcpu *v;
+		kvm_for_each_vcpu(r, v, vcpu->kvm)
+			if (v == vcpu)
+				data = r;
+		break;
+	}
+	case HV_X64_MSR_EOI:
+		return kvm_hv_vapic_msr_read(vcpu, APIC_EOI, pdata);
+	case HV_X64_MSR_ICR:
+		return kvm_hv_vapic_msr_read(vcpu, APIC_ICR, pdata);
+	case HV_X64_MSR_TPR:
+		return kvm_hv_vapic_msr_read(vcpu, APIC_TASKPRI, pdata);
+	default:
+		pr_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
+		return 1;
+	}
+	*pdata = data;
+	return 0;
+}
+
 int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
 {
 	u64 data;
@@ -1221,7 +1404,7 @@ int kvm_get_msr_common(struct kvm_vcpu *
 		data |= (((uint64_t)4ULL) << 40);
 		break;
 	case MSR_EFER:
-		data = vcpu->arch.shadow_efer;
+		data = vcpu->arch.efer;
 		break;
 	case MSR_KVM_WALL_CLOCK:
 		data = vcpu->kvm->arch.wall_clock;
@@ -1236,6 +1419,16 @@ int kvm_get_msr_common(struct kvm_vcpu *
 	case MSR_IA32_MCG_STATUS:
 	case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1:
 		return get_msr_mce(vcpu, msr, pdata);
+	case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
+		if (kvm_hv_msr_partition_wide(msr)) {
+			int r;
+			mutex_lock(&vcpu->kvm->lock);
+			r = get_msr_hyperv_pw(vcpu, msr, pdata);
+			mutex_unlock(&vcpu->kvm->lock);
+			return r;
+		} else
+			return get_msr_hyperv(vcpu, msr, pdata);
+		break;
 	default:
 		if (!ignore_msrs) {
 			pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr);
@@ -1261,15 +1454,15 @@ static int __msr_io(struct kvm_vcpu *vcp
 		    int (*do_msr)(struct kvm_vcpu *vcpu,
 				  unsigned index, u64 *data))
 {
-	int i;
+	int i, idx;
 
 	vcpu_load(vcpu);
 
-	down_read(&vcpu->kvm->slots_lock);
+	idx = srcu_read_lock(&vcpu->kvm->srcu);
 	for (i = 0; i < msrs->nmsrs; ++i)
 		if (do_msr(vcpu, entries[i].index, &entries[i].data))
 			break;
-	up_read(&vcpu->kvm->slots_lock);
+	srcu_read_unlock(&vcpu->kvm->srcu, idx);
 
 	vcpu_put(vcpu);
 
@@ -1351,6 +1544,11 @@ int kvm_dev_ioctl_check_extension(long e
 	case KVM_CAP_XEN_HVM:
 	case KVM_CAP_ADJUST_CLOCK:
 	case KVM_CAP_VCPU_EVENTS:
+	case KVM_CAP_HYPERV:
+	case KVM_CAP_HYPERV_VAPIC:
+	case KVM_CAP_HYPERV_SPIN:
+	case KVM_CAP_PCI_SEGMENT:
+	case KVM_CAP_X86_ROBUST_SINGLESTEP:
 		r = 1;
 		break;
 	case KVM_CAP_COALESCED_MMIO:
@@ -1464,8 +1662,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
-	kvm_x86_ops->vcpu_put(vcpu);
 	kvm_put_guest_fpu(vcpu);
+	kvm_x86_ops->vcpu_put(vcpu);
 }
 
 static int is_efer_nx(void)
@@ -1514,6 +1712,7 @@ static int kvm_vcpu_ioctl_set_cpuid(stru
 	if (copy_from_user(cpuid_entries, entries,
 			   cpuid->nent * sizeof(struct kvm_cpuid_entry)))
 		goto out_free;
+	vcpu_load(vcpu);
 	for (i = 0; i < cpuid->nent; i++) {
 		vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function;
 		vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax;
@@ -1530,6 +1729,8 @@ static int kvm_vcpu_ioctl_set_cpuid(stru
 	cpuid_fix_nx_cap(vcpu);
 	r = 0;
 	kvm_apic_set_version(vcpu);
+	kvm_x86_ops->cpuid_update(vcpu);
+	vcpu_put(vcpu);
 
 out_free:
 	vfree(cpuid_entries);
@@ -1550,8 +1751,11 @@ static int kvm_vcpu_ioctl_set_cpuid2(str
 	if (copy_from_user(&vcpu->arch.cpuid_entries, entries,
 			   cpuid->nent * sizeof(struct kvm_cpuid_entry2)))
 		goto out;
+	vcpu_load(vcpu);
 	vcpu->arch.cpuid_nent = cpuid->nent;
 	kvm_apic_set_version(vcpu);
+	kvm_x86_ops->cpuid_update(vcpu);
+	vcpu_put(vcpu);
 	return 0;
 
 out:
@@ -1594,12 +1798,15 @@ static void do_cpuid_ent(struct kvm_cpui
 			 u32 index, int *nent, int maxnent)
 {
 	unsigned f_nx = is_efer_nx() ? F(NX) : 0;
-	unsigned f_gbpages = kvm_x86_ops->gb_page_enable() ? F(GBPAGES) : 0;
 #ifdef CONFIG_X86_64
+	unsigned f_gbpages = (kvm_x86_ops->get_lpage_level() == PT_PDPE_LEVEL)
+				? F(GBPAGES) : 0;
 	unsigned f_lm = F(LM);
 #else
+	unsigned f_gbpages = 0;
 	unsigned f_lm = 0;
 #endif
+	unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0;
 
 	/* cpuid 1.edx */
 	const u32 kvm_supported_word0_x86_features =
@@ -1619,7 +1826,7 @@ static void do_cpuid_ent(struct kvm_cpui
 		F(MTRR) | F(PGE) | F(MCA) | F(CMOV) |
 		F(PAT) | F(PSE36) | 0 /* Reserved */ |
 		f_nx | 0 /* Reserved */ | F(MMXEXT) | F(MMX) |
-		F(FXSR) | F(FXSR_OPT) | f_gbpages | 0 /* RDTSCP */ |
+		F(FXSR) | F(FXSR_OPT) | f_gbpages | f_rdtscp |
 		0 /* Reserved */ | f_lm | F(3DNOWEXT) | F(3DNOW);
 	/* cpuid 1.ecx */
 	const u32 kvm_supported_word4_x86_features =
@@ -1866,7 +2073,7 @@ static int kvm_vcpu_ioctl_x86_set_mce(st
 		return 0;
 	if (mce->status & MCI_STATUS_UC) {
 		if ((vcpu->arch.mcg_status & MCG_STATUS_MCIP) ||
-		    !(vcpu->arch.cr4 & X86_CR4_MCE)) {
+		    !kvm_read_cr4_bits(vcpu, X86_CR4_MCE)) {
 			printk(KERN_DEBUG "kvm: set_mce: "
 			       "injects mce exception while "
 			       "previous one is in progress!\n");
@@ -2160,14 +2367,14 @@ static int kvm_vm_ioctl_set_nr_mmu_pages
 	if (kvm_nr_mmu_pages < KVM_MIN_ALLOC_MMU_PAGES)
 		return -EINVAL;
 
-	down_write(&kvm->slots_lock);
+	mutex_lock(&kvm->slots_lock);
 	spin_lock(&kvm->mmu_lock);
 
 	kvm_mmu_change_mmu_pages(kvm, kvm_nr_mmu_pages);
 	kvm->arch.n_requested_mmu_pages = kvm_nr_mmu_pages;
 
 	spin_unlock(&kvm->mmu_lock);
-	up_write(&kvm->slots_lock);
+	mutex_unlock(&kvm->slots_lock);
 	return 0;
 }
 
@@ -2176,13 +2383,35 @@ static int kvm_vm_ioctl_get_nr_mmu_pages
 	return kvm->arch.n_alloc_mmu_pages;
 }
 
+gfn_t unalias_gfn_instantiation(struct kvm *kvm, gfn_t gfn)
+{
+	int i;
+	struct kvm_mem_alias *alias;
+	struct kvm_mem_aliases *aliases;
+
+	aliases = rcu_dereference(kvm->arch.aliases);
+
+	for (i = 0; i < aliases->naliases; ++i) {
+		alias = &aliases->aliases[i];
+		if (alias->flags & KVM_ALIAS_INVALID)
+			continue;
+		if (gfn >= alias->base_gfn
+		    && gfn < alias->base_gfn + alias->npages)
+			return alias->target_gfn + gfn - alias->base_gfn;
+	}
+	return gfn;
+}
+
 gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
 {
 	int i;
 	struct kvm_mem_alias *alias;
+	struct kvm_mem_aliases *aliases;
 
-	for (i = 0; i < kvm->arch.naliases; ++i) {
-		alias = &kvm->arch.aliases[i];
+	aliases = rcu_dereference(kvm->arch.aliases);
+
+	for (i = 0; i < aliases->naliases; ++i) {
+		alias = &aliases->aliases[i];
 		if (gfn >= alias->base_gfn
 		    && gfn < alias->base_gfn + alias->npages)
 			return alias->target_gfn + gfn - alias->base_gfn;
@@ -2200,6 +2429,7 @@ static int kvm_vm_ioctl_set_memory_alias
 {
 	int r, n;
 	struct kvm_mem_alias *p;
+	struct kvm_mem_aliases *aliases, *old_aliases;
 
 	r = -EINVAL;
 	/* General sanity checks */
@@ -2216,26 +2446,48 @@ static int kvm_vm_ioctl_set_memory_alias
 	    < alias->target_phys_addr)
 		goto out;
 
-	down_write(&kvm->slots_lock);
-	spin_lock(&kvm->mmu_lock);
+	r = -ENOMEM;
+	aliases = kzalloc(sizeof(struct kvm_mem_aliases), GFP_KERNEL);
+	if (!aliases)
+		goto out;
 
-	p = &kvm->arch.aliases[alias->slot];
+	mutex_lock(&kvm->slots_lock);
+
+	/* invalidate any gfn reference in case of deletion/shrinking */
+	memcpy(aliases, kvm->arch.aliases, sizeof(struct kvm_mem_aliases));
+	aliases->aliases[alias->slot].flags |= KVM_ALIAS_INVALID;
+	old_aliases = kvm->arch.aliases;
+	rcu_assign_pointer(kvm->arch.aliases, aliases);
+	synchronize_srcu_expedited(&kvm->srcu);
+	kvm_mmu_zap_all(kvm);
+	kfree(old_aliases);
+
+	r = -ENOMEM;
+	aliases = kzalloc(sizeof(struct kvm_mem_aliases), GFP_KERNEL);
+	if (!aliases)
+		goto out_unlock;
+
+	memcpy(aliases, kvm->arch.aliases, sizeof(struct kvm_mem_aliases));
+
+	p = &aliases->aliases[alias->slot];
 	p->base_gfn = alias->guest_phys_addr >> PAGE_SHIFT;
 	p->npages = alias->memory_size >> PAGE_SHIFT;
 	p->target_gfn = alias->target_phys_addr >> PAGE_SHIFT;
+	p->flags &= ~(KVM_ALIAS_INVALID);
 
 	for (n = KVM_ALIAS_SLOTS; n > 0; --n)
-		if (kvm->arch.aliases[n - 1].npages)
+		if (aliases->aliases[n - 1].npages)
 			break;
-	kvm->arch.naliases = n;
-
-	spin_unlock(&kvm->mmu_lock);
-	kvm_mmu_zap_all(kvm);
-
-	up_write(&kvm->slots_lock);
+	aliases->naliases = n;
 
-	return 0;
+	old_aliases = kvm->arch.aliases;
+	rcu_assign_pointer(kvm->arch.aliases, aliases);
+	synchronize_srcu_expedited(&kvm->srcu);
+	kfree(old_aliases);
+	r = 0;
 
+out_unlock:
+	mutex_unlock(&kvm->slots_lock);
 out:
 	return r;
 }
@@ -2273,18 +2525,18 @@ static int kvm_vm_ioctl_set_irqchip(stru
 	r = 0;
 	switch (chip->chip_id) {
 	case KVM_IRQCHIP_PIC_MASTER:
-		spin_lock(&pic_irqchip(kvm)->lock);
+		raw_spin_lock(&pic_irqchip(kvm)->lock);
 		memcpy(&pic_irqchip(kvm)->pics[0],
 			&chip->chip.pic,
 			sizeof(struct kvm_pic_state));
-		spin_unlock(&pic_irqchip(kvm)->lock);
+		raw_spin_unlock(&pic_irqchip(kvm)->lock);
 		break;
 	case KVM_IRQCHIP_PIC_SLAVE:
-		spin_lock(&pic_irqchip(kvm)->lock);
+		raw_spin_lock(&pic_irqchip(kvm)->lock);
 		memcpy(&pic_irqchip(kvm)->pics[1],
 			&chip->chip.pic,
 			sizeof(struct kvm_pic_state));
-		spin_unlock(&pic_irqchip(kvm)->lock);
+		raw_spin_unlock(&pic_irqchip(kvm)->lock);
 		break;
 	case KVM_IRQCHIP_IOAPIC:
 		r = kvm_set_ioapic(kvm, &chip->chip.ioapic);
@@ -2364,29 +2616,63 @@ static int kvm_vm_ioctl_reinject(struct
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 				      struct kvm_dirty_log *log)
 {
-	int r;
-	int n;
+	int r, i;
 	struct kvm_memory_slot *memslot;
-	int is_dirty = 0;
+	unsigned long n;
+	unsigned long is_dirty = 0;
+	unsigned long *dirty_bitmap = NULL;
 
-	down_write(&kvm->slots_lock);
+	mutex_lock(&kvm->slots_lock);
 
-	r = kvm_get_dirty_log(kvm, log, &is_dirty);
-	if (r)
+	r = -EINVAL;
+	if (log->slot >= KVM_MEMORY_SLOTS)
 		goto out;
 
+	memslot = &kvm->memslots->memslots[log->slot];
+	r = -ENOENT;
+	if (!memslot->dirty_bitmap)
+		goto out;
+
+	n = kvm_dirty_bitmap_bytes(memslot);
+
+	r = -ENOMEM;
+	dirty_bitmap = vmalloc(n);
+	if (!dirty_bitmap)
+		goto out;
+	memset(dirty_bitmap, 0, n);
+
+	for (i = 0; !is_dirty && i < n/sizeof(long); i++)
+		is_dirty = memslot->dirty_bitmap[i];
+
 	/* If nothing is dirty, don't bother messing with page tables. */
 	if (is_dirty) {
+		struct kvm_memslots *slots, *old_slots;
+
 		spin_lock(&kvm->mmu_lock);
 		kvm_mmu_slot_remove_write_access(kvm, log->slot);
 		spin_unlock(&kvm->mmu_lock);
-		memslot = &kvm->memslots[log->slot];
-		n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
-		memset(memslot->dirty_bitmap, 0, n);
+
+		slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
+		if (!slots)
+			goto out_free;
+
+		memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
+		slots->memslots[log->slot].dirty_bitmap = dirty_bitmap;
+
+		old_slots = kvm->memslots;
+		rcu_assign_pointer(kvm->memslots, slots);
+		synchronize_srcu_expedited(&kvm->srcu);
+		dirty_bitmap = old_slots->memslots[log->slot].dirty_bitmap;
+		kfree(old_slots);
 	}
+
 	r = 0;
+	if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n))
+		r = -EFAULT;
+out_free:
+	vfree(dirty_bitmap);
 out:
-	up_write(&kvm->slots_lock);
+	mutex_unlock(&kvm->slots_lock);
 	return r;
 }
 
@@ -2469,6 +2755,8 @@ long kvm_arch_vm_ioctl(struct file *filp
 		if (vpic) {
 			r = kvm_ioapic_init(kvm);
 			if (r) {
+				kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS,
+							  &vpic->dev);
 				kfree(vpic);
 				goto create_irqchip_unlock;
 			}
@@ -2480,10 +2768,8 @@ long kvm_arch_vm_ioctl(struct file *filp
 		r = kvm_setup_default_irq_routing(kvm);
 		if (r) {
 			mutex_lock(&kvm->irq_lock);
-			kfree(kvm->arch.vpic);
-			kfree(kvm->arch.vioapic);
-			kvm->arch.vpic = NULL;
-			kvm->arch.vioapic = NULL;
+			kvm_ioapic_destroy(kvm);
+			kvm_destroy_pic(kvm);
 			mutex_unlock(&kvm->irq_lock);
 		}
 	create_irqchip_unlock:
@@ -2499,7 +2785,7 @@ long kvm_arch_vm_ioctl(struct file *filp
 				   sizeof(struct kvm_pit_config)))
 			goto out;
 	create_pit:
-		down_write(&kvm->slots_lock);
+		mutex_lock(&kvm->slots_lock);
 		r = -EEXIST;
 		if (kvm->arch.vpit)
 			goto create_pit_unlock;
@@ -2508,7 +2794,7 @@ long kvm_arch_vm_ioctl(struct file *filp
 		if (kvm->arch.vpit)
 			r = 0;
 	create_pit_unlock:
-		up_write(&kvm->slots_lock);
+		mutex_unlock(&kvm->slots_lock);
 		break;
 	case KVM_IRQ_LINE_STATUS:
 	case KVM_IRQ_LINE: {
@@ -2725,7 +3011,7 @@ static int vcpu_mmio_write(struct kvm_vc
 	    !kvm_iodevice_write(&vcpu->arch.apic->dev, addr, len, v))
 		return 0;
 
-	return kvm_io_bus_write(&vcpu->kvm->mmio_bus, addr, len, v);
+	return kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, addr, len, v);
 }
 
 static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v)
@@ -2734,17 +3020,44 @@ static int vcpu_mmio_read(struct kvm_vcp
 	    !kvm_iodevice_read(&vcpu->arch.apic->dev, addr, len, v))
 		return 0;
 
-	return kvm_io_bus_read(&vcpu->kvm->mmio_bus, addr, len, v);
+	return kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, addr, len, v);
 }
 
-static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes,
-			       struct kvm_vcpu *vcpu)
+gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u32 *error)
+{
+	u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
+	return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, access, error);
+}
+
+ gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva, u32 *error)
+{
+	u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
+	access |= PFERR_FETCH_MASK;
+	return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, access, error);
+}
+
+gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, u32 *error)
+{
+	u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
+	access |= PFERR_WRITE_MASK;
+	return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, access, error);
+}
+
+/* uses this to access any guest's mapped memory without checking CPL */
+gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, u32 *error)
+{
+	return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, 0, error);
+}
+
+static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes,
+				      struct kvm_vcpu *vcpu, u32 access,
+				      u32 *error)
 {
 	void *data = val;
 	int r = X86EMUL_CONTINUE;
 
 	while (bytes) {
-		gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+		gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr, access, error);
 		unsigned offset = addr & (PAGE_SIZE-1);
 		unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset);
 		int ret;
@@ -2767,14 +3080,37 @@ out:
 	return r;
 }
 
+/* used for instruction fetching */
+static int kvm_fetch_guest_virt(gva_t addr, void *val, unsigned int bytes,
+				struct kvm_vcpu *vcpu, u32 *error)
+{
+	u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
+	return kvm_read_guest_virt_helper(addr, val, bytes, vcpu,
+					  access | PFERR_FETCH_MASK, error);
+}
+
+static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes,
+			       struct kvm_vcpu *vcpu, u32 *error)
+{
+	u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
+	return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access,
+					  error);
+}
+
+static int kvm_read_guest_virt_system(gva_t addr, void *val, unsigned int bytes,
+			       struct kvm_vcpu *vcpu, u32 *error)
+{
+	return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, error);
+}
+
 static int kvm_write_guest_virt(gva_t addr, void *val, unsigned int bytes,
-				struct kvm_vcpu *vcpu)
+				struct kvm_vcpu *vcpu, u32 *error)
 {
 	void *data = val;
 	int r = X86EMUL_CONTINUE;
 
 	while (bytes) {
-		gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+		gpa_t gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, error);
 		unsigned offset = addr & (PAGE_SIZE-1);
 		unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset);
 		int ret;
@@ -2804,6 +3140,7 @@ static int emulator_read_emulated(unsign
 				  struct kvm_vcpu *vcpu)
 {
 	gpa_t                 gpa;
+	u32 error_code;
 
 	if (vcpu->mmio_read_completed) {
 		memcpy(val, vcpu->mmio_data, bytes);
@@ -2813,17 +3150,20 @@ static int emulator_read_emulated(unsign
 		return X86EMUL_CONTINUE;
 	}
 
-	gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+	gpa = kvm_mmu_gva_to_gpa_read(vcpu, addr, &error_code);
+
+	if (gpa == UNMAPPED_GVA) {
+		kvm_inject_page_fault(vcpu, addr, error_code);
+		return X86EMUL_PROPAGATE_FAULT;
+	}
 
 	/* For APIC access vmexit */
 	if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
 		goto mmio;
 
-	if (kvm_read_guest_virt(addr, val, bytes, vcpu)
+	if (kvm_read_guest_virt(addr, val, bytes, vcpu, NULL)
 				== X86EMUL_CONTINUE)
 		return X86EMUL_CONTINUE;
-	if (gpa == UNMAPPED_GVA)
-		return X86EMUL_PROPAGATE_FAULT;
 
 mmio:
 	/*
@@ -2862,11 +3202,12 @@ static int emulator_write_emulated_onepa
 					   struct kvm_vcpu *vcpu)
 {
 	gpa_t                 gpa;
+	u32 error_code;
 
-	gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+	gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, &error_code);
 
 	if (gpa == UNMAPPED_GVA) {
-		kvm_inject_page_fault(vcpu, addr, 2);
+		kvm_inject_page_fault(vcpu, addr, error_code);
 		return X86EMUL_PROPAGATE_FAULT;
 	}
 
@@ -2930,7 +3271,7 @@ static int emulator_cmpxchg_emulated(uns
 		char *kaddr;
 		u64 val;
 
-		gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+		gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, NULL);
 
 		if (gpa == UNMAPPED_GVA ||
 		   (gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
@@ -2967,35 +3308,21 @@ int emulate_invlpg(struct kvm_vcpu *vcpu
 
 int emulate_clts(struct kvm_vcpu *vcpu)
 {
-	kvm_x86_ops->set_cr0(vcpu, vcpu->arch.cr0 & ~X86_CR0_TS);
+	kvm_x86_ops->set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~X86_CR0_TS));
+	kvm_x86_ops->fpu_activate(vcpu);
 	return X86EMUL_CONTINUE;
 }
 
 int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest)
 {
-	struct kvm_vcpu *vcpu = ctxt->vcpu;
-
-	switch (dr) {
-	case 0 ... 3:
-		*dest = kvm_x86_ops->get_dr(vcpu, dr);
-		return X86EMUL_CONTINUE;
-	default:
-		pr_unimpl(vcpu, "%s: unexpected dr %u\n", __func__, dr);
-		return X86EMUL_UNHANDLEABLE;
-	}
+	return kvm_x86_ops->get_dr(ctxt->vcpu, dr, dest);
 }
 
 int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value)
 {
 	unsigned long mask = (ctxt->mode == X86EMUL_MODE_PROT64) ? ~0ULL : ~0U;
-	int exception;
 
-	kvm_x86_ops->set_dr(ctxt->vcpu, dr, value & mask, &exception);
-	if (exception) {
-		/* FIXME: better handling */
-		return X86EMUL_UNHANDLEABLE;
-	}
-	return X86EMUL_CONTINUE;
+	return kvm_x86_ops->set_dr(ctxt->vcpu, dr, value & mask);
 }
 
 void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
@@ -3009,7 +3336,7 @@ void kvm_report_emulation_failure(struct
 
 	rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS);
 
-	kvm_read_guest_virt(rip_linear, (void *)opcodes, 4, vcpu);
+	kvm_read_guest_virt(rip_linear, (void *)opcodes, 4, vcpu, NULL);
 
 	printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n",
 	       context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]);
@@ -3017,7 +3344,8 @@ void kvm_report_emulation_failure(struct
 EXPORT_SYMBOL_GPL(kvm_report_emulation_failure);
 
 static struct x86_emulate_ops emulate_ops = {
-	.read_std            = kvm_read_guest_virt,
+	.read_std            = kvm_read_guest_virt_system,
+	.fetch               = kvm_fetch_guest_virt,
 	.read_emulated       = emulator_read_emulated,
 	.write_emulated      = emulator_write_emulated,
 	.cmpxchg_emulated    = emulator_cmpxchg_emulated,
@@ -3060,8 +3388,9 @@ int emulate_instruction(struct kvm_vcpu
 		vcpu->arch.emulate_ctxt.vcpu = vcpu;
 		vcpu->arch.emulate_ctxt.eflags = kvm_get_rflags(vcpu);
 		vcpu->arch.emulate_ctxt.mode =
+			(!is_protmode(vcpu)) ? X86EMUL_MODE_REAL :
 			(vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM)
-			? X86EMUL_MODE_REAL : cs_l
+			? X86EMUL_MODE_VM86 : cs_l
 			? X86EMUL_MODE_PROT64 :	cs_db
 			? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
 
@@ -3153,12 +3482,17 @@ static int pio_copy_data(struct kvm_vcpu
 	gva_t q = vcpu->arch.pio.guest_gva;
 	unsigned bytes;
 	int ret;
+	u32 error_code;
 
 	bytes = vcpu->arch.pio.size * vcpu->arch.pio.cur_count;
 	if (vcpu->arch.pio.in)
-		ret = kvm_write_guest_virt(q, p, bytes, vcpu);
+		ret = kvm_write_guest_virt(q, p, bytes, vcpu, &error_code);
 	else
-		ret = kvm_read_guest_virt(q, p, bytes, vcpu);
+		ret = kvm_read_guest_virt(q, p, bytes, vcpu, &error_code);
+
+	if (ret == X86EMUL_PROPAGATE_FAULT)
+		kvm_inject_page_fault(vcpu, q, error_code);
+
 	return ret;
 }
 
@@ -3179,7 +3513,7 @@ int complete_pio(struct kvm_vcpu *vcpu)
 		if (io->in) {
 			r = pio_copy_data(vcpu);
 			if (r)
-				return r;
+				goto out;
 		}
 
 		delta = 1;
@@ -3206,7 +3540,7 @@ int complete_pio(struct kvm_vcpu *vcpu)
 			kvm_register_write(vcpu, VCPU_REGS_RSI, val);
 		}
 	}
-
+out:
 	io->count -= io->cur_count;
 	io->cur_count = 0;
 
@@ -3219,11 +3553,12 @@ static int kernel_pio(struct kvm_vcpu *v
 	int r;
 
 	if (vcpu->arch.pio.in)
-		r = kvm_io_bus_read(&vcpu->kvm->pio_bus, vcpu->arch.pio.port,
+		r = kvm_io_bus_read(vcpu->kvm, KVM_PIO_BUS, vcpu->arch.pio.port,
 				    vcpu->arch.pio.size, pd);
 	else
-		r = kvm_io_bus_write(&vcpu->kvm->pio_bus, vcpu->arch.pio.port,
-				     vcpu->arch.pio.size, pd);
+		r = kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS,
+				     vcpu->arch.pio.port, vcpu->arch.pio.size,
+				     pd);
 	return r;
 }
 
@@ -3234,7 +3569,7 @@ static int pio_string_write(struct kvm_v
 	int i, r = 0;
 
 	for (i = 0; i < io->cur_count; i++) {
-		if (kvm_io_bus_write(&vcpu->kvm->pio_bus,
+		if (kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS,
 				     io->port, io->size, pd)) {
 			r = -EOPNOTSUPP;
 			break;
@@ -3248,6 +3583,8 @@ int kvm_emulate_pio(struct kvm_vcpu *vcp
 {
 	unsigned long val;
 
+	trace_kvm_pio(!in, port, size, 1);
+
 	vcpu->run->exit_reason = KVM_EXIT_IO;
 	vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
 	vcpu->run->io.size = vcpu->arch.pio.size = size;
@@ -3259,11 +3596,10 @@ int kvm_emulate_pio(struct kvm_vcpu *vcp
 	vcpu->arch.pio.down = 0;
 	vcpu->arch.pio.rep = 0;
 
-	trace_kvm_pio(vcpu->run->io.direction == KVM_EXIT_IO_OUT, port,
-		      size, 1);
-
-	val = kvm_register_read(vcpu, VCPU_REGS_RAX);
-	memcpy(vcpu->arch.pio_data, &val, 4);
+	if (!vcpu->arch.pio.in) {
+		val = kvm_register_read(vcpu, VCPU_REGS_RAX);
+		memcpy(vcpu->arch.pio_data, &val, 4);
+	}
 
 	if (!kernel_pio(vcpu, vcpu->arch.pio_data)) {
 		complete_pio(vcpu);
@@ -3280,6 +3616,8 @@ int kvm_emulate_pio_string(struct kvm_vc
 	unsigned now, in_page;
 	int ret = 0;
 
+	trace_kvm_pio(!in, port, size, count);
+
 	vcpu->run->exit_reason = KVM_EXIT_IO;
 	vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
 	vcpu->run->io.size = vcpu->arch.pio.size = size;
@@ -3291,9 +3629,6 @@ int kvm_emulate_pio_string(struct kvm_vc
 	vcpu->arch.pio.down = down;
 	vcpu->arch.pio.rep = rep;
 
-	trace_kvm_pio(vcpu->run->io.direction == KVM_EXIT_IO_OUT, port,
-		      size, count);
-
 	if (!count) {
 		kvm_x86_ops->skip_emulated_instruction(vcpu);
 		return 1;
@@ -3325,10 +3660,8 @@ int kvm_emulate_pio_string(struct kvm_vc
 	if (!vcpu->arch.pio.in) {
 		/* string PIO write */
 		ret = pio_copy_data(vcpu);
-		if (ret == X86EMUL_PROPAGATE_FAULT) {
-			kvm_inject_gp(vcpu, 0);
+		if (ret == X86EMUL_PROPAGATE_FAULT)
 			return 1;
-		}
 		if (ret == 0 && !pio_string_write(vcpu)) {
 			complete_pio(vcpu);
 			if (vcpu->arch.pio.count == 0)
@@ -3487,11 +3820,76 @@ static inline gpa_t hc_gpa(struct kvm_vc
 		return a0 | ((gpa_t)a1 << 32);
 }
 
+int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
+{
+	u64 param, ingpa, outgpa, ret;
+	uint16_t code, rep_idx, rep_cnt, res = HV_STATUS_SUCCESS, rep_done = 0;
+	bool fast, longmode;
+	int cs_db, cs_l;
+
+	/*
+	 * hypercall generates UD from non zero cpl and real mode
+	 * per HYPER-V spec
+	 */
+	if (kvm_x86_ops->get_cpl(vcpu) != 0 || !is_protmode(vcpu)) {
+		kvm_queue_exception(vcpu, UD_VECTOR);
+		return 0;
+	}
+
+	kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
+	longmode = is_long_mode(vcpu) && cs_l == 1;
+
+	if (!longmode) {
+		param = ((u64)kvm_register_read(vcpu, VCPU_REGS_RDX) << 32) |
+			(kvm_register_read(vcpu, VCPU_REGS_RAX) & 0xffffffff);
+		ingpa = ((u64)kvm_register_read(vcpu, VCPU_REGS_RBX) << 32) |
+			(kvm_register_read(vcpu, VCPU_REGS_RCX) & 0xffffffff);
+		outgpa = ((u64)kvm_register_read(vcpu, VCPU_REGS_RDI) << 32) |
+			(kvm_register_read(vcpu, VCPU_REGS_RSI) & 0xffffffff);
+	}
+#ifdef CONFIG_X86_64
+	else {
+		param = kvm_register_read(vcpu, VCPU_REGS_RCX);
+		ingpa = kvm_register_read(vcpu, VCPU_REGS_RDX);
+		outgpa = kvm_register_read(vcpu, VCPU_REGS_R8);
+	}
+#endif
+
+	code = param & 0xffff;
+	fast = (param >> 16) & 0x1;
+	rep_cnt = (param >> 32) & 0xfff;
+	rep_idx = (param >> 48) & 0xfff;
+
+	trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
+
+	switch (code) {
+	case HV_X64_HV_NOTIFY_LONG_SPIN_WAIT:
+		kvm_vcpu_on_spin(vcpu);
+		break;
+	default:
+		res = HV_STATUS_INVALID_HYPERCALL_CODE;
+		break;
+	}
+
+	ret = res | (((u64)rep_done & 0xfff) << 32);
+	if (longmode) {
+		kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
+	} else {
+		kvm_register_write(vcpu, VCPU_REGS_RDX, ret >> 32);
+		kvm_register_write(vcpu, VCPU_REGS_RAX, ret & 0xffffffff);
+	}
+
+	return 1;
+}
+
 int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
 {
 	unsigned long nr, a0, a1, a2, a3, ret;
 	int r = 1;
 
+	if (kvm_hv_hypercall_enabled(vcpu->kvm))
+		return kvm_hv_hypercall(vcpu);
+
 	nr = kvm_register_read(vcpu, VCPU_REGS_RAX);
 	a0 = kvm_register_read(vcpu, VCPU_REGS_RBX);
 	a1 = kvm_register_read(vcpu, VCPU_REGS_RCX);
@@ -3534,10 +3932,8 @@ EXPORT_SYMBOL_GPL(kvm_emulate_hypercall)
 int kvm_fix_hypercall(struct kvm_vcpu *vcpu)
 {
 	char instruction[3];
-	int ret = 0;
 	unsigned long rip = kvm_rip_read(vcpu);
 
-
 	/*
 	 * Blow out the MMU to ensure that no other VCPU has an active mapping
 	 * to ensure that the updated hypercall appears atomically across all
@@ -3546,11 +3942,8 @@ int kvm_fix_hypercall(struct kvm_vcpu *v
 	kvm_mmu_zap_all(vcpu->kvm);
 
 	kvm_x86_ops->patch_hypercall(vcpu, instruction);
-	if (emulator_write_emulated(rip, instruction, 3, vcpu)
-	    != X86EMUL_CONTINUE)
-		ret = -EFAULT;
 
-	return ret;
+	return emulator_write_emulated(rip, instruction, 3, vcpu);
 }
 
 static u64 mk_cr_64(u64 curr_cr, u32 new_val)
@@ -3583,10 +3976,9 @@ unsigned long realmode_get_cr(struct kvm
 {
 	unsigned long value;
 
-	kvm_x86_ops->decache_cr4_guest_bits(vcpu);
 	switch (cr) {
 	case 0:
-		value = vcpu->arch.cr0;
+		value = kvm_read_cr0(vcpu);
 		break;
 	case 2:
 		value = vcpu->arch.cr2;
@@ -3595,7 +3987,7 @@ unsigned long realmode_get_cr(struct kvm
 		value = vcpu->arch.cr3;
 		break;
 	case 4:
-		value = vcpu->arch.cr4;
+		value = kvm_read_cr4(vcpu);
 		break;
 	case 8:
 		value = kvm_get_cr8(vcpu);
@@ -3613,7 +4005,7 @@ void realmode_set_cr(struct kvm_vcpu *vc
 {
 	switch (cr) {
 	case 0:
-		kvm_set_cr0(vcpu, mk_cr_64(vcpu->arch.cr0, val));
+		kvm_set_cr0(vcpu, mk_cr_64(kvm_read_cr0(vcpu), val));
 		*rflags = kvm_get_rflags(vcpu);
 		break;
 	case 2:
@@ -3623,7 +4015,7 @@ void realmode_set_cr(struct kvm_vcpu *vc
 		kvm_set_cr3(vcpu, val);
 		break;
 	case 4:
-		kvm_set_cr4(vcpu, mk_cr_64(vcpu->arch.cr4, val));
+		kvm_set_cr4(vcpu, mk_cr_64(kvm_read_cr4(vcpu), val));
 		break;
 	case 8:
 		kvm_set_cr8(vcpu, val & 0xfUL);
@@ -3690,6 +4082,7 @@ struct kvm_cpuid_entry2 *kvm_find_cpuid_
 	}
 	return best;
 }
+EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry);
 
 int cpuid_maxphyaddr(struct kvm_vcpu *vcpu)
 {
@@ -3773,14 +4166,15 @@ static void vapic_enter(struct kvm_vcpu
 static void vapic_exit(struct kvm_vcpu *vcpu)
 {
 	struct kvm_lapic *apic = vcpu->arch.apic;
+	int idx;
 
 	if (!apic || !apic->vapic_addr)
 		return;
 
-	down_read(&vcpu->kvm->slots_lock);
+	idx = srcu_read_lock(&vcpu->kvm->srcu);
 	kvm_release_page_dirty(apic->vapic_page);
 	mark_page_dirty(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
-	up_read(&vcpu->kvm->slots_lock);
+	srcu_read_unlock(&vcpu->kvm->srcu, idx);
 }
 
 static void update_cr8_intercept(struct kvm_vcpu *vcpu)
@@ -3876,12 +4270,17 @@ static int vcpu_enter_guest(struct kvm_v
 			r = 0;
 			goto out;
 		}
+		if (test_and_clear_bit(KVM_REQ_DEACTIVATE_FPU, &vcpu->requests)) {
+			vcpu->fpu_active = 0;
+			kvm_x86_ops->fpu_deactivate(vcpu);
+		}
 	}
 
 	preempt_disable();
 
 	kvm_x86_ops->prepare_guest_switch(vcpu);
-	kvm_load_guest_fpu(vcpu);
+	if (vcpu->fpu_active)
+		kvm_load_guest_fpu(vcpu);
 
 	local_irq_disable();
 
@@ -3909,7 +4308,7 @@ static int vcpu_enter_guest(struct kvm_v
 		kvm_lapic_sync_to_vapic(vcpu);
 	}
 
-	up_read(&vcpu->kvm->slots_lock);
+	srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
 
 	kvm_guest_enter();
 
@@ -3951,7 +4350,7 @@ static int vcpu_enter_guest(struct kvm_v
 
 	preempt_enable();
 
-	down_read(&vcpu->kvm->slots_lock);
+	vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
 
 	/*
 	 * Profile KVM exit RIPs:
@@ -3973,6 +4372,7 @@ out:
 static int __vcpu_run(struct kvm_vcpu *vcpu)
 {
 	int r;
+	struct kvm *kvm = vcpu->kvm;
 
 	if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED)) {
 		pr_debug("vcpu %d received sipi with vector # %x\n",
@@ -3984,7 +4384,7 @@ static int __vcpu_run(struct kvm_vcpu *v
 		vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
 	}
 
-	down_read(&vcpu->kvm->slots_lock);
+	vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
 	vapic_enter(vcpu);
 
 	r = 1;
@@ -3992,9 +4392,9 @@ static int __vcpu_run(struct kvm_vcpu *v
 		if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE)
 			r = vcpu_enter_guest(vcpu);
 		else {
-			up_read(&vcpu->kvm->slots_lock);
+			srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
 			kvm_vcpu_block(vcpu);
-			down_read(&vcpu->kvm->slots_lock);
+			vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
 			if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests))
 			{
 				switch(vcpu->arch.mp_state) {
@@ -4029,13 +4429,13 @@ static int __vcpu_run(struct kvm_vcpu *v
 			++vcpu->stat.signal_exits;
 		}
 		if (need_resched()) {
-			up_read(&vcpu->kvm->slots_lock);
+			srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
 			kvm_resched(vcpu);
-			down_read(&vcpu->kvm->slots_lock);
+			vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
 		}
 	}
 
-	up_read(&vcpu->kvm->slots_lock);
+	srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
 	post_kvm_run_save(vcpu);
 
 	vapic_exit(vcpu);
@@ -4065,7 +4465,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v
 		kvm_set_cr8(vcpu, kvm_run->cr8);
 
 	if (vcpu->arch.pio.cur_count) {
+		vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
 		r = complete_pio(vcpu);
+		srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
 		if (r)
 			goto out;
 	}
@@ -4074,10 +4476,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v
 		vcpu->mmio_read_completed = 1;
 		vcpu->mmio_needed = 0;
 
-		down_read(&vcpu->kvm->slots_lock);
+		vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
 		r = emulate_instruction(vcpu, vcpu->arch.mmio_fault_cr2, 0,
 					EMULTYPE_NO_DECODE);
-		up_read(&vcpu->kvm->slots_lock);
+		srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
 		if (r == EMULATE_DO_MMIO) {
 			/*
 			 * Read-modify-write.  Back to userspace.
@@ -4204,13 +4606,12 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct
 	sregs->gdt.limit = dt.limit;
 	sregs->gdt.base = dt.base;
 
-	kvm_x86_ops->decache_cr4_guest_bits(vcpu);
-	sregs->cr0 = vcpu->arch.cr0;
+	sregs->cr0 = kvm_read_cr0(vcpu);
 	sregs->cr2 = vcpu->arch.cr2;
 	sregs->cr3 = vcpu->arch.cr3;
-	sregs->cr4 = vcpu->arch.cr4;
+	sregs->cr4 = kvm_read_cr4(vcpu);
 	sregs->cr8 = kvm_get_cr8(vcpu);
-	sregs->efer = vcpu->arch.shadow_efer;
+	sregs->efer = vcpu->arch.efer;
 	sregs->apic_base = kvm_get_apic_base(vcpu);
 
 	memset(sregs->interrupt_bitmap, 0, sizeof sregs->interrupt_bitmap);
@@ -4298,14 +4699,23 @@ static int load_guest_segment_descriptor
 {
 	struct descriptor_table dtable;
 	u16 index = selector >> 3;
+	int ret;
+	u32 err;
+	gva_t addr;
 
 	get_segment_descriptor_dtable(vcpu, selector, &dtable);
 
 	if (dtable.limit < index * 8 + 7) {
 		kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc);
-		return 1;
+		return X86EMUL_PROPAGATE_FAULT;
 	}
-	return kvm_read_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu);
+	addr = dtable.base + index * 8;
+	ret = kvm_read_guest_virt_system(addr, seg_desc, sizeof(*seg_desc),
+					 vcpu,  &err);
+	if (ret == X86EMUL_PROPAGATE_FAULT)
+		kvm_inject_page_fault(vcpu, addr, err);
+
+       return ret;
 }
 
 /* allowed just for 8 bytes segments */
@@ -4319,15 +4729,23 @@ static int save_guest_segment_descriptor
 
 	if (dtable.limit < index * 8 + 7)
 		return 1;
-	return kvm_write_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu);
+	return kvm_write_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu, NULL);
 }
 
-static gpa_t get_tss_base_addr(struct kvm_vcpu *vcpu,
+static gpa_t get_tss_base_addr_write(struct kvm_vcpu *vcpu,
+			       struct desc_struct *seg_desc)
+{
+	u32 base_addr = get_desc_base(seg_desc);
+
+	return kvm_mmu_gva_to_gpa_write(vcpu, base_addr, NULL);
+}
+
+static gpa_t get_tss_base_addr_read(struct kvm_vcpu *vcpu,
 			     struct desc_struct *seg_desc)
 {
 	u32 base_addr = get_desc_base(seg_desc);
 
-	return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr);
+	return kvm_mmu_gva_to_gpa_read(vcpu, base_addr, NULL);
 }
 
 static u16 get_segment_selector(struct kvm_vcpu *vcpu, int seg)
@@ -4338,18 +4756,6 @@ static u16 get_segment_selector(struct k
 	return kvm_seg.selector;
 }
 
-static int load_segment_descriptor_to_kvm_desct(struct kvm_vcpu *vcpu,
-						u16 selector,
-						struct kvm_segment *kvm_seg)
-{
-	struct desc_struct seg_desc;
-
-	if (load_guest_segment_descriptor(vcpu, selector, &seg_desc))
-		return 1;
-	seg_desct_to_kvm_desct(&seg_desc, selector, kvm_seg);
-	return 0;
-}
-
 static int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int seg)
 {
 	struct kvm_segment segvar = {
@@ -4367,7 +4773,7 @@ static int kvm_load_realmode_segment(str
 		.unusable = 0,
 	};
 	kvm_x86_ops->set_segment(vcpu, &segvar, seg);
-	return 0;
+	return X86EMUL_CONTINUE;
 }
 
 static int is_vm86_segment(struct kvm_vcpu *vcpu, int seg)
@@ -4377,24 +4783,112 @@ static int is_vm86_segment(struct kvm_vc
 		(kvm_get_rflags(vcpu) & X86_EFLAGS_VM);
 }
 
-int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
-				int type_bits, int seg)
+int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg)
 {
 	struct kvm_segment kvm_seg;
+	struct desc_struct seg_desc;
+	u8 dpl, rpl, cpl;
+	unsigned err_vec = GP_VECTOR;
+	u32 err_code = 0;
+	bool null_selector = !(selector & ~0x3); /* 0000-0003 are null */
+	int ret;
 
-	if (is_vm86_segment(vcpu, seg) || !(vcpu->arch.cr0 & X86_CR0_PE))
+	if (is_vm86_segment(vcpu, seg) || !is_protmode(vcpu))
 		return kvm_load_realmode_segment(vcpu, selector, seg);
-	if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg))
-		return 1;
-	kvm_seg.type |= type_bits;
 
-	if (seg != VCPU_SREG_SS && seg != VCPU_SREG_CS &&
-	    seg != VCPU_SREG_LDTR)
-		if (!kvm_seg.s)
-			kvm_seg.unusable = 1;
+	/* NULL selector is not valid for TR, CS and SS */
+	if ((seg == VCPU_SREG_CS || seg == VCPU_SREG_SS || seg == VCPU_SREG_TR)
+	    && null_selector)
+		goto exception;
+
+	/* TR should be in GDT only */
+	if (seg == VCPU_SREG_TR && (selector & (1 << 2)))
+		goto exception;
+
+	ret = load_guest_segment_descriptor(vcpu, selector, &seg_desc);
+	if (ret)
+		return ret;
+
+	seg_desct_to_kvm_desct(&seg_desc, selector, &kvm_seg);
+
+	if (null_selector) { /* for NULL selector skip all following checks */
+		kvm_seg.unusable = 1;
+		goto load;
+	}
+
+	err_code = selector & 0xfffc;
+	err_vec = GP_VECTOR;
+
+	/* can't load system descriptor into segment selecor */
+	if (seg <= VCPU_SREG_GS && !kvm_seg.s)
+		goto exception;
+
+	if (!kvm_seg.present) {
+		err_vec = (seg == VCPU_SREG_SS) ? SS_VECTOR : NP_VECTOR;
+		goto exception;
+	}
 
+	rpl = selector & 3;
+	dpl = kvm_seg.dpl;
+	cpl = kvm_x86_ops->get_cpl(vcpu);
+
+	switch (seg) {
+	case VCPU_SREG_SS:
+		/*
+		 * segment is not a writable data segment or segment
+		 * selector's RPL != CPL or segment selector's RPL != CPL
+		 */
+		if (rpl != cpl || (kvm_seg.type & 0xa) != 0x2 || dpl != cpl)
+			goto exception;
+		break;
+	case VCPU_SREG_CS:
+		if (!(kvm_seg.type & 8))
+			goto exception;
+
+		if (kvm_seg.type & 4) {
+			/* conforming */
+			if (dpl > cpl)
+				goto exception;
+		} else {
+			/* nonconforming */
+			if (rpl > cpl || dpl != cpl)
+				goto exception;
+		}
+		/* CS(RPL) <- CPL */
+		selector = (selector & 0xfffc) | cpl;
+            break;
+	case VCPU_SREG_TR:
+		if (kvm_seg.s || (kvm_seg.type != 1 && kvm_seg.type != 9))
+			goto exception;
+		break;
+	case VCPU_SREG_LDTR:
+		if (kvm_seg.s || kvm_seg.type != 2)
+			goto exception;
+		break;
+	default: /*  DS, ES, FS, or GS */
+		/*
+		 * segment is not a data or readable code segment or
+		 * ((segment is a data or nonconforming code segment)
+		 * and (both RPL and CPL > DPL))
+		 */
+		if ((kvm_seg.type & 0xa) == 0x8 ||
+		    (((kvm_seg.type & 0xc) != 0xc) && (rpl > dpl && cpl > dpl)))
+			goto exception;
+		break;
+	}
+
+	if (!kvm_seg.unusable && kvm_seg.s) {
+		/* mark segment as accessed */
+		kvm_seg.type |= 1;
+		seg_desc.type |= 1;
+		save_guest_segment_descriptor(vcpu, selector, &seg_desc);
+	}
+load:
 	kvm_set_segment(vcpu, &kvm_seg, seg);
-	return 0;
+	return X86EMUL_CONTINUE;
+exception:
+	kvm_queue_exception_e(vcpu, err_vec, err_code);
+	return X86EMUL_PROPAGATE_FAULT;
 }
 
 static void save_state_to_tss32(struct kvm_vcpu *vcpu,
@@ -4420,6 +4914,14 @@ static void save_state_to_tss32(struct k
 	tss->ldt_selector = get_segment_selector(vcpu, VCPU_SREG_LDTR);
 }
 
+static void kvm_load_segment_selector(struct kvm_vcpu *vcpu, u16 sel, int seg)
+{
+	struct kvm_segment kvm_seg;
+	kvm_get_segment(vcpu, &kvm_seg, seg);
+	kvm_seg.selector = sel;
+	kvm_set_segment(vcpu, &kvm_seg, seg);
+}
+
 static int load_state_from_tss32(struct kvm_vcpu *vcpu,
 				  struct tss_segment_32 *tss)
 {
@@ -4437,25 +4939,41 @@ static int load_state_from_tss32(struct
 	kvm_register_write(vcpu, VCPU_REGS_RSI, tss->esi);
 	kvm_register_write(vcpu, VCPU_REGS_RDI, tss->edi);
 
-	if (kvm_load_segment_descriptor(vcpu, tss->ldt_selector, 0, VCPU_SREG_LDTR))
+	/*
+	 * SDM says that segment selectors are loaded before segment
+	 * descriptors
+	 */
+	kvm_load_segment_selector(vcpu, tss->ldt_selector, VCPU_SREG_LDTR);
+	kvm_load_segment_selector(vcpu, tss->es, VCPU_SREG_ES);
+	kvm_load_segment_selector(vcpu, tss->cs, VCPU_SREG_CS);
+	kvm_load_segment_selector(vcpu, tss->ss, VCPU_SREG_SS);
+	kvm_load_segment_selector(vcpu, tss->ds, VCPU_SREG_DS);
+	kvm_load_segment_selector(vcpu, tss->fs, VCPU_SREG_FS);
+	kvm_load_segment_selector(vcpu, tss->gs, VCPU_SREG_GS);
+
+	/*
+	 * Now load segment descriptors. If fault happenes at this stage
+	 * it is handled in a context of new task
+	 */
+	if (kvm_load_segment_descriptor(vcpu, tss->ldt_selector, VCPU_SREG_LDTR))
 		return 1;
 
-	if (kvm_load_segment_descriptor(vcpu, tss->es, 1, VCPU_SREG_ES))
+	if (kvm_load_segment_descriptor(vcpu, tss->es, VCPU_SREG_ES))
 		return 1;
 
-	if (kvm_load_segment_descriptor(vcpu, tss->cs, 9, VCPU_SREG_CS))
+	if (kvm_load_segment_descriptor(vcpu, tss->cs, VCPU_SREG_CS))
 		return 1;
 
-	if (kvm_load_segment_descriptor(vcpu, tss->ss, 1, VCPU_SREG_SS))
+	if (kvm_load_segment_descriptor(vcpu, tss->ss, VCPU_SREG_SS))
 		return 1;
 
-	if (kvm_load_segment_descriptor(vcpu, tss->ds, 1, VCPU_SREG_DS))
+	if (kvm_load_segment_descriptor(vcpu, tss->ds, VCPU_SREG_DS))
 		return 1;
 
-	if (kvm_load_segment_descriptor(vcpu, tss->fs, 1, VCPU_SREG_FS))
+	if (kvm_load_segment_descriptor(vcpu, tss->fs, VCPU_SREG_FS))
 		return 1;
 
-	if (kvm_load_segment_descriptor(vcpu, tss->gs, 1, VCPU_SREG_GS))
+	if (kvm_load_segment_descriptor(vcpu, tss->gs, VCPU_SREG_GS))
 		return 1;
 	return 0;
 }
@@ -4495,19 +5013,33 @@ static int load_state_from_tss16(struct
 	kvm_register_write(vcpu, VCPU_REGS_RSI, tss->si);
 	kvm_register_write(vcpu, VCPU_REGS_RDI, tss->di);
 
-	if (kvm_load_segment_descriptor(vcpu, tss->ldt, 0, VCPU_SREG_LDTR))
+	/*
+	 * SDM says that segment selectors are loaded before segment
+	 * descriptors
+	 */
+	kvm_load_segment_selector(vcpu, tss->ldt, VCPU_SREG_LDTR);
+	kvm_load_segment_selector(vcpu, tss->es, VCPU_SREG_ES);
+	kvm_load_segment_selector(vcpu, tss->cs, VCPU_SREG_CS);
+	kvm_load_segment_selector(vcpu, tss->ss, VCPU_SREG_SS);
+	kvm_load_segment_selector(vcpu, tss->ds, VCPU_SREG_DS);
+
+	/*
+	 * Now load segment descriptors. If fault happenes at this stage
+	 * it is handled in a context of new task
+	 */
+	if (kvm_load_segment_descriptor(vcpu, tss->ldt, VCPU_SREG_LDTR))
 		return 1;
 
-	if (kvm_load_segment_descriptor(vcpu, tss->es, 1, VCPU_SREG_ES))
+	if (kvm_load_segment_descriptor(vcpu, tss->es, VCPU_SREG_ES))
 		return 1;
 
-	if (kvm_load_segment_descriptor(vcpu, tss->cs, 9, VCPU_SREG_CS))
+	if (kvm_load_segment_descriptor(vcpu, tss->cs, VCPU_SREG_CS))
 		return 1;
 
-	if (kvm_load_segment_descriptor(vcpu, tss->ss, 1, VCPU_SREG_SS))
+	if (kvm_load_segment_descriptor(vcpu, tss->ss, VCPU_SREG_SS))
 		return 1;
 
-	if (kvm_load_segment_descriptor(vcpu, tss->ds, 1, VCPU_SREG_DS))
+	if (kvm_load_segment_descriptor(vcpu, tss->ds, VCPU_SREG_DS))
 		return 1;
 	return 0;
 }
@@ -4529,7 +5061,7 @@ static int kvm_task_switch_16(struct kvm
 			    sizeof tss_segment_16))
 		goto out;
 
-	if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc),
+	if (kvm_read_guest(vcpu->kvm, get_tss_base_addr_read(vcpu, nseg_desc),
 			   &tss_segment_16, sizeof tss_segment_16))
 		goto out;
 
@@ -4537,7 +5069,7 @@ static int kvm_task_switch_16(struct kvm
 		tss_segment_16.prev_task_link = old_tss_sel;
 
 		if (kvm_write_guest(vcpu->kvm,
-				    get_tss_base_addr(vcpu, nseg_desc),
+				    get_tss_base_addr_write(vcpu, nseg_desc),
 				    &tss_segment_16.prev_task_link,
 				    sizeof tss_segment_16.prev_task_link))
 			goto out;
@@ -4568,7 +5100,7 @@ static int kvm_task_switch_32(struct kvm
 			    sizeof tss_segment_32))
 		goto out;
 
-	if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc),
+	if (kvm_read_guest(vcpu->kvm, get_tss_base_addr_read(vcpu, nseg_desc),
 			   &tss_segment_32, sizeof tss_segment_32))
 		goto out;
 
@@ -4576,7 +5108,7 @@ static int kvm_task_switch_32(struct kvm
 		tss_segment_32.prev_task_link = old_tss_sel;
 
 		if (kvm_write_guest(vcpu->kvm,
-				    get_tss_base_addr(vcpu, nseg_desc),
+				    get_tss_base_addr_write(vcpu, nseg_desc),
 				    &tss_segment_32.prev_task_link,
 				    sizeof tss_segment_32.prev_task_link))
 			goto out;
@@ -4598,8 +5130,9 @@ int kvm_task_switch(struct kvm_vcpu *vcp
 	int ret = 0;
 	u32 old_tss_base = get_segment_base(vcpu, VCPU_SREG_TR);
 	u16 old_tss_sel = get_segment_selector(vcpu, VCPU_SREG_TR);
+	u32 desc_limit;
 
-	old_tss_base = vcpu->arch.mmu.gva_to_gpa(vcpu, old_tss_base);
+	old_tss_base = kvm_mmu_gva_to_gpa_write(vcpu, old_tss_base, NULL);
 
 	/* FIXME: Handle errors. Failure to read either TSS or their
 	 * descriptors should generate a pagefault.
@@ -4620,7 +5153,10 @@ int kvm_task_switch(struct kvm_vcpu *vcp
 		}
 	}
 
-	if (!nseg_desc.p || get_desc_limit(&nseg_desc) < 0x67) {
+	desc_limit = get_desc_limit(&nseg_desc);
+	if (!nseg_desc.p ||
+	    ((desc_limit < 0x67 && (nseg_desc.type & 8)) ||
+	     desc_limit < 0x2b)) {
 		kvm_queue_exception_e(vcpu, TS_VECTOR, tss_selector & 0xfffc);
 		return 1;
 	}
@@ -4658,7 +5194,7 @@ int kvm_task_switch(struct kvm_vcpu *vcp
 					      &nseg_desc);
 	}
 
-	kvm_x86_ops->set_cr0(vcpu, vcpu->arch.cr0 | X86_CR0_TS);
+	kvm_x86_ops->set_cr0(vcpu, kvm_read_cr0(vcpu) | X86_CR0_TS);
 	seg_desct_to_kvm_desct(&nseg_desc, tss_selector, &tr_seg);
 	tr_seg.type = 11;
 	kvm_set_segment(vcpu, &tr_seg, VCPU_SREG_TR);
@@ -4689,17 +5225,15 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct
 
 	kvm_set_cr8(vcpu, sregs->cr8);
 
-	mmu_reset_needed |= vcpu->arch.shadow_efer != sregs->efer;
+	mmu_reset_needed |= vcpu->arch.efer != sregs->efer;
 	kvm_x86_ops->set_efer(vcpu, sregs->efer);
 	kvm_set_apic_base(vcpu, sregs->apic_base);
 
-	kvm_x86_ops->decache_cr4_guest_bits(vcpu);
-
-	mmu_reset_needed |= vcpu->arch.cr0 != sregs->cr0;
+	mmu_reset_needed |= kvm_read_cr0(vcpu) != sregs->cr0;
 	kvm_x86_ops->set_cr0(vcpu, sregs->cr0);
 	vcpu->arch.cr0 = sregs->cr0;
 
-	mmu_reset_needed |= vcpu->arch.cr4 != sregs->cr4;
+	mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4;
 	kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
 	if (!is_long_mode(vcpu) && is_pae(vcpu)) {
 		load_pdptrs(vcpu, vcpu->arch.cr3);
@@ -4734,7 +5268,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct
 	/* Older userspace won't unhalt the vcpu on reset. */
 	if (kvm_vcpu_is_bsp(vcpu) && kvm_rip_read(vcpu) == 0xfff0 &&
 	    sregs->cs.selector == 0xf000 && sregs->cs.base == 0xffff0000 &&
-	    !(vcpu->arch.cr0 & X86_CR0_PE))
+	    !is_protmode(vcpu))
 		vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
 
 	vcpu_put(vcpu);
@@ -4832,11 +5366,12 @@ int kvm_arch_vcpu_ioctl_translate(struct
 {
 	unsigned long vaddr = tr->linear_address;
 	gpa_t gpa;
+	int idx;
 
 	vcpu_load(vcpu);
-	down_read(&vcpu->kvm->slots_lock);
-	gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, vaddr);
-	up_read(&vcpu->kvm->slots_lock);
+	idx = srcu_read_lock(&vcpu->kvm->srcu);
+	gpa = kvm_mmu_gva_to_gpa_system(vcpu, vaddr, NULL);
+	srcu_read_unlock(&vcpu->kvm->srcu, idx);
 	tr->physical_address = gpa;
 	tr->valid = gpa != UNMAPPED_GVA;
 	tr->writeable = 1;
@@ -4917,14 +5452,14 @@ EXPORT_SYMBOL_GPL(fx_init);
 
 void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
 {
-	if (!vcpu->fpu_active || vcpu->guest_fpu_loaded)
+	if (vcpu->guest_fpu_loaded)
 		return;
 
 	vcpu->guest_fpu_loaded = 1;
 	kvm_fx_save(&vcpu->arch.host_fx_image);
 	kvm_fx_restore(&vcpu->arch.guest_fx_image);
+	trace_kvm_fpu(1);
 }
-EXPORT_SYMBOL_GPL(kvm_load_guest_fpu);
 
 void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
 {
@@ -4935,8 +5470,9 @@ void kvm_put_guest_fpu(struct kvm_vcpu *
 	kvm_fx_save(&vcpu->arch.guest_fx_image);
 	kvm_fx_restore(&vcpu->arch.host_fx_image);
 	++vcpu->stat.fpu_reload;
+	set_bit(KVM_REQ_DEACTIVATE_FPU, &vcpu->requests);
+	trace_kvm_fpu(0);
 }
-EXPORT_SYMBOL_GPL(kvm_put_guest_fpu);
 
 void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
 {
@@ -5088,11 +5624,13 @@ fail:
 
 void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
 {
+	int idx;
+
 	kfree(vcpu->arch.mce_banks);
 	kvm_free_lapic(vcpu);
-	down_read(&vcpu->kvm->slots_lock);
+	idx = srcu_read_lock(&vcpu->kvm->srcu);
 	kvm_mmu_destroy(vcpu);
-	up_read(&vcpu->kvm->slots_lock);
+	srcu_read_unlock(&vcpu->kvm->srcu, idx);
 	free_page((unsigned long)vcpu->arch.pio_data);
 }
 
@@ -5103,6 +5641,12 @@ struct  kvm *kvm_arch_create_vm(void)
 	if (!kvm)
 		return ERR_PTR(-ENOMEM);
 
+	kvm->arch.aliases = kzalloc(sizeof(struct kvm_mem_aliases), GFP_KERNEL);
+	if (!kvm->arch.aliases) {
+		kfree(kvm);
+		return ERR_PTR(-ENOMEM);
+	}
+
 	INIT_LIST_HEAD(&kvm->arch.active_mmu_pages);
 	INIT_LIST_HEAD(&kvm->arch.assigned_dev_head);
 
@@ -5159,16 +5703,18 @@ void kvm_arch_destroy_vm(struct kvm *kvm
 		put_page(kvm->arch.apic_access_page);
 	if (kvm->arch.ept_identity_pagetable)
 		put_page(kvm->arch.ept_identity_pagetable);
+	cleanup_srcu_struct(&kvm->srcu);
+	kfree(kvm->arch.aliases);
 	kfree(kvm);
 }
 
-int kvm_arch_set_memory_region(struct kvm *kvm,
-				struct kvm_userspace_memory_region *mem,
+int kvm_arch_prepare_memory_region(struct kvm *kvm,
+				struct kvm_memory_slot *memslot,
 				struct kvm_memory_slot old,
+				struct kvm_userspace_memory_region *mem,
 				int user_alloc)
 {
-	int npages = mem->memory_size >> PAGE_SHIFT;
-	struct kvm_memory_slot *memslot = &kvm->memslots[mem->slot];
+	int npages = memslot->npages;
 
 	/*To keep backward compatibility with older userspace,
 	 *x86 needs to hanlde !user_alloc case.
@@ -5188,26 +5734,35 @@ int kvm_arch_set_memory_region(struct kv
 			if (IS_ERR((void *)userspace_addr))
 				return PTR_ERR((void *)userspace_addr);
 
-			/* set userspace_addr atomically for kvm_hva_to_rmapp */
-			spin_lock(&kvm->mmu_lock);
 			memslot->userspace_addr = userspace_addr;
-			spin_unlock(&kvm->mmu_lock);
-		} else {
-			if (!old.user_alloc && old.rmap) {
-				int ret;
-
-				down_write(&current->mm->mmap_sem);
-				ret = do_munmap(current->mm, old.userspace_addr,
-						old.npages * PAGE_SIZE);
-				up_write(&current->mm->mmap_sem);
-				if (ret < 0)
-					printk(KERN_WARNING
-				       "kvm_vm_ioctl_set_memory_region: "
-				       "failed to munmap memory\n");
-			}
 		}
 	}
 
+
+	return 0;
+}
+
+void kvm_arch_commit_memory_region(struct kvm *kvm,
+				struct kvm_userspace_memory_region *mem,
+				struct kvm_memory_slot old,
+				int user_alloc)
+{
+
+	int npages = mem->memory_size >> PAGE_SHIFT;
+
+	if (!user_alloc && !old.user_alloc && old.rmap && !npages) {
+		int ret;
+
+		down_write(&current->mm->mmap_sem);
+		ret = do_munmap(current->mm, old.userspace_addr,
+				old.npages * PAGE_SIZE);
+		up_write(&current->mm->mmap_sem);
+		if (ret < 0)
+			printk(KERN_WARNING
+			       "kvm_vm_ioctl_set_memory_region: "
+			       "failed to munmap memory\n");
+	}
+
 	spin_lock(&kvm->mmu_lock);
 	if (!kvm->arch.n_requested_mmu_pages) {
 		unsigned int nr_mmu_pages = kvm_mmu_calculate_mmu_pages(kvm);
@@ -5216,8 +5771,6 @@ int kvm_arch_set_memory_region(struct kv
 
 	kvm_mmu_slot_remove_write_access(kvm, mem->slot);
 	spin_unlock(&kvm->mmu_lock);
-
-	return 0;
 }
 
 void kvm_arch_flush_shadow(struct kvm *kvm)
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/kvm/x86.h linux-libre-2.6.34-gnu1/arch/x86/kvm/x86.h
--- linux-libre-2.6.33-gnu1/arch/x86/kvm/x86.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/kvm/x86.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
 #define ARCH_X86_KVM_X86_H
 
 #include <linux/kvm_host.h>
+#include "kvm_cache_regs.h"
 
 static inline void kvm_clear_exception_queue(struct kvm_vcpu *vcpu)
 {
@@ -35,4 +36,33 @@ static inline bool kvm_exception_is_soft
 struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
                                              u32 function, u32 index);
 
+static inline bool is_protmode(struct kvm_vcpu *vcpu)
+{
+	return kvm_read_cr0_bits(vcpu, X86_CR0_PE);
+}
+
+static inline int is_long_mode(struct kvm_vcpu *vcpu)
+{
+#ifdef CONFIG_X86_64
+	return vcpu->arch.efer & EFER_LMA;
+#else
+	return 0;
+#endif
+}
+
+static inline int is_pae(struct kvm_vcpu *vcpu)
+{
+	return kvm_read_cr4_bits(vcpu, X86_CR4_PAE);
+}
+
+static inline int is_pse(struct kvm_vcpu *vcpu)
+{
+	return kvm_read_cr4_bits(vcpu, X86_CR4_PSE);
+}
+
+static inline int is_paging(struct kvm_vcpu *vcpu)
+{
+	return kvm_read_cr0_bits(vcpu, X86_CR0_PG);
+}
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/lguest/boot.c linux-libre-2.6.34-gnu1/arch/x86/lguest/boot.c
--- linux-libre-2.6.33-gnu1/arch/x86/lguest/boot.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/lguest/boot.c	2010-05-16 17:17:36.000000000 -0400
@@ -115,7 +115,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. */
-		kvm_hypercall4(call, arg1, arg2, arg3, arg4);
+		hcall(call, arg1, arg2, arg3, arg4);
 	} else {
 		lguest_data.hcalls[next_call].arg0 = call;
 		lguest_data.hcalls[next_call].arg1 = arg1;
@@ -145,46 +145,45 @@ 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_hcall1(unsigned long call,
-		       unsigned long arg1)
+static void lazy_hcall1(unsigned long call, unsigned long arg1)
 {
 	if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-		kvm_hypercall1(call, arg1);
+		hcall(call, arg1, 0, 0, 0);
 	else
 		async_hcall(call, arg1, 0, 0, 0);
 }
 
 /* You can imagine what lazy_hcall2, 3 and 4 look like. :*/
 static void lazy_hcall2(unsigned long call,
-		       unsigned long arg1,
-		       unsigned long arg2)
+			unsigned long arg1,
+			unsigned long arg2)
 {
 	if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-		kvm_hypercall2(call, arg1, arg2);
+		hcall(call, arg1, arg2, 0, 0);
 	else
 		async_hcall(call, arg1, arg2, 0, 0);
 }
 
 static void lazy_hcall3(unsigned long call,
-		       unsigned long arg1,
-		       unsigned long arg2,
-		       unsigned long arg3)
+			unsigned long arg1,
+			unsigned long arg2,
+			unsigned long arg3)
 {
 	if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-		kvm_hypercall3(call, arg1, arg2, arg3);
+		hcall(call, arg1, arg2, arg3, 0);
 	else
 		async_hcall(call, arg1, arg2, arg3, 0);
 }
 
 #ifdef CONFIG_X86_PAE
 static void lazy_hcall4(unsigned long call,
-		       unsigned long arg1,
-		       unsigned long arg2,
-		       unsigned long arg3,
-		       unsigned long arg4)
+			unsigned long arg1,
+			unsigned long arg2,
+			unsigned long arg3,
+			unsigned long arg4)
 {
 	if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-		kvm_hypercall4(call, arg1, arg2, arg3, arg4);
+		hcall(call, arg1, arg2, arg3, arg4);
 	else
 		async_hcall(call, arg1, arg2, arg3, arg4);
 }
@@ -196,13 +195,13 @@ static void lazy_hcall4(unsigned long ca
 :*/
 static void lguest_leave_lazy_mmu_mode(void)
 {
-	kvm_hypercall0(LHCALL_FLUSH_ASYNC);
+	hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0);
 	paravirt_leave_lazy_mmu();
 }
 
 static void lguest_end_context_switch(struct task_struct *next)
 {
-	kvm_hypercall0(LHCALL_FLUSH_ASYNC);
+	hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0);
 	paravirt_end_context_switch(next);
 }
 
@@ -286,7 +285,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. */
-	kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]);
+	hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1], 0);
 }
 
 /*
@@ -300,7 +299,7 @@ static void lguest_load_idt(const struct
 	struct desc_struct *idt = (void *)desc->address;
 
 	for (i = 0; i < (desc->size+1)/8; i++)
-		kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b);
+		hcall(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b, 0);
 }
 
 /*
@@ -321,7 +320,7 @@ static void lguest_load_gdt(const struct
 	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);
+		hcall(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b, 0);
 }
 
 /*
@@ -334,8 +333,8 @@ static void lguest_write_gdt_entry(struc
 {
 	native_write_gdt_entry(dt, entrynum, desc, type);
 	/* Tell Host about this new entry. */
-	kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, entrynum,
-		       dt[entrynum].a, dt[entrynum].b);
+	hcall(LHCALL_LOAD_GDT_ENTRY, entrynum,
+	      dt[entrynum].a, dt[entrynum].b, 0);
 }
 
 /*
@@ -931,7 +930,7 @@ static int lguest_clockevent_set_next_ev
 	}
 
 	/* Please wake us this far in the future. */
-	kvm_hypercall1(LHCALL_SET_CLOCKEVENT, delta);
+	hcall(LHCALL_SET_CLOCKEVENT, delta, 0, 0, 0);
 	return 0;
 }
 
@@ -942,7 +941,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. */
-		kvm_hypercall0(LHCALL_SET_CLOCKEVENT);
+		hcall(LHCALL_SET_CLOCKEVENT, 0, 0, 0, 0);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 		/* This is what we expect. */
@@ -1100,7 +1099,7 @@ static void set_lguest_basic_apic_ops(vo
 /* STOP!  Until an interrupt comes in. */
 static void lguest_safe_halt(void)
 {
-	kvm_hypercall0(LHCALL_HALT);
+	hcall(LHCALL_HALT, 0, 0, 0, 0);
 }
 
 /*
@@ -1112,8 +1111,8 @@ static void lguest_safe_halt(void)
  */
 static void lguest_power_off(void)
 {
-	kvm_hypercall2(LHCALL_SHUTDOWN, __pa("Power down"),
-					LGUEST_SHUTDOWN_POWEROFF);
+	hcall(LHCALL_SHUTDOWN, __pa("Power down"),
+	      LGUEST_SHUTDOWN_POWEROFF, 0, 0);
 }
 
 /*
@@ -1123,7 +1122,7 @@ static void lguest_power_off(void)
  */
 static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p)
 {
-	kvm_hypercall2(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF);
+	hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0, 0);
 	/* The hcall won't return, but to keep gcc happy, we're "done". */
 	return NOTIFY_DONE;
 }
@@ -1162,7 +1161,7 @@ static __init int early_put_chars(u32 vt
 		len = sizeof(scratch) - 1;
 	scratch[len] = '\0';
 	memcpy(scratch, buf, len);
-	kvm_hypercall1(LHCALL_NOTIFY, __pa(scratch));
+	hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0, 0);
 
 	/* This routine returns the number of bytes actually written. */
 	return len;
@@ -1174,7 +1173,7 @@ static __init int early_put_chars(u32 vt
  */
 static void lguest_restart(char *reason)
 {
-	kvm_hypercall2(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART);
+	hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0, 0);
 }
 
 /*G:050
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/lguest/i386_head.S linux-libre-2.6.34-gnu1/arch/x86/lguest/i386_head.S
--- linux-libre-2.6.33-gnu1/arch/x86/lguest/i386_head.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/lguest/i386_head.S	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,7 @@ ENTRY(lguest_entry)
 	 */
 	movl $LHCALL_LGUEST_INIT, %eax
 	movl $lguest_data - __PAGE_OFFSET, %ebx
-	.byte 0x0f,0x01,0xc1 /* KVM_HYPERCALL */
+	int $LGUEST_TRAP_ENTRY
 
 	/* Set up the initial stack so we can run C code. */
 	movl $(init_thread_union+THREAD_SIZE),%esp
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/lib/cache-smp.c linux-libre-2.6.34-gnu1/arch/x86/lib/cache-smp.c
--- linux-libre-2.6.33-gnu1/arch/x86/lib/cache-smp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/lib/cache-smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,19 @@
+#include <linux/smp.h>
+#include <linux/module.h>
+
+static void __wbinvd(void *dummy)
+{
+	wbinvd();
+}
+
+void wbinvd_on_cpu(int cpu)
+{
+	smp_call_function_single(cpu, __wbinvd, NULL, 1);
+}
+EXPORT_SYMBOL(wbinvd_on_cpu);
+
+int wbinvd_on_all_cpus(void)
+{
+	return on_each_cpu(__wbinvd, NULL, 1);
+}
+EXPORT_SYMBOL(wbinvd_on_all_cpus);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/lib/copy_user_64.S linux-libre-2.6.34-gnu1/arch/x86/lib/copy_user_64.S
--- linux-libre-2.6.33-gnu1/arch/x86/lib/copy_user_64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/lib/copy_user_64.S	2010-05-16 17:17:36.000000000 -0400
@@ -90,12 +90,6 @@ ENTRY(_copy_from_user)
 	CFI_ENDPROC
 ENDPROC(_copy_from_user)
 
-ENTRY(copy_user_generic)
-	CFI_STARTPROC
-	ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
-	CFI_ENDPROC
-ENDPROC(copy_user_generic)
-
 	.section .fixup,"ax"
 	/* must zero dest */
 ENTRY(bad_from_user)
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/lib/io_64.c linux-libre-2.6.34-gnu1/arch/x86/lib/io_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/lib/io_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/lib/io_64.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-#include <linux/string.h>
-#include <linux/module.h>
-#include <asm/io.h>
-
-void __memcpy_toio(unsigned long dst, const void *src, unsigned len)
-{
-	__inline_memcpy((void *)dst, src, len);
-}
-EXPORT_SYMBOL(__memcpy_toio);
-
-void __memcpy_fromio(void *dst, unsigned long src, unsigned len)
-{
-	__inline_memcpy(dst, (const void *)src, len);
-}
-EXPORT_SYMBOL(__memcpy_fromio);
-
-void memset_io(volatile void __iomem *a, int b, size_t c)
-{
-	/*
-	 * TODO: memset can mangle the IO patterns quite a bit.
-	 * perhaps it would be better to use a dumb one:
-	 */
-	memset((void *)a, b, c);
-}
-EXPORT_SYMBOL(memset_io);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/lib/Makefile linux-libre-2.6.34-gnu1/arch/x86/lib/Makefile
--- linux-libre-2.6.33-gnu1/arch/x86/lib/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/lib/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,7 @@ $(obj)/inat.o: $(obj)/inat-tables.c
 
 clean-files := inat-tables.c
 
-obj-$(CONFIG_SMP) += msr-smp.o
+obj-$(CONFIG_SMP) += msr-smp.o cache-smp.o
 
 lib-y := delay.o
 lib-y += thunk_$(BITS).o
@@ -34,9 +34,10 @@ ifneq ($(CONFIG_X86_CMPXCHG64),y)
 endif
         lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o
 else
-        obj-y += io_64.o iomap_copy_64.o
+        obj-y += iomap_copy_64.o
         lib-y += csum-partial_64.o csum-copy_64.o csum-wrappers_64.o
         lib-y += thunk_64.o clear_page_64.o copy_page_64.o
         lib-y += memmove_64.o memset_64.o
         lib-y += copy_user_64.o rwlock_64.o copy_user_nocache_64.o
+	lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem_64.o
 endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/lib/memcpy_64.S linux-libre-2.6.34-gnu1/arch/x86/lib/memcpy_64.S
--- linux-libre-2.6.33-gnu1/arch/x86/lib/memcpy_64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/lib/memcpy_64.S	2010-05-16 17:17:36.000000000 -0400
@@ -20,12 +20,11 @@
 /*
  * memcpy_c() - fast string ops (REP MOVSQ) based variant.
  *
- * Calls to this get patched into the kernel image via the
+ * This gets patched over the unrolled variant (below) via the
  * alternative instructions framework:
  */
-	ALIGN
-memcpy_c:
-	CFI_STARTPROC
+	.section .altinstr_replacement, "ax", @progbits
+.Lmemcpy_c:
 	movq %rdi, %rax
 
 	movl %edx, %ecx
@@ -35,8 +34,8 @@ memcpy_c:
 	movl %edx, %ecx
 	rep movsb
 	ret
-	CFI_ENDPROC
-ENDPROC(memcpy_c)
+.Lmemcpy_e:
+	.previous
 
 ENTRY(__memcpy)
 ENTRY(memcpy)
@@ -128,16 +127,10 @@ ENDPROC(__memcpy)
 	 * It is also a lot simpler. Use this when possible:
 	 */
 
-	.section .altinstr_replacement, "ax"
-1:	.byte 0xeb				/* jmp <disp8> */
-	.byte (memcpy_c - memcpy) - (2f - 1b)	/* offset */
-2:
-	.previous
-
 	.section .altinstructions, "a"
 	.align 8
 	.quad memcpy
-	.quad 1b
+	.quad .Lmemcpy_c
 	.byte X86_FEATURE_REP_GOOD
 
 	/*
@@ -145,6 +138,6 @@ ENDPROC(__memcpy)
 	 * so it is silly to overwrite itself with nops - reboot is the
 	 * only outcome...
 	 */
-	.byte 2b - 1b
-	.byte 2b - 1b
+	.byte .Lmemcpy_e - .Lmemcpy_c
+	.byte .Lmemcpy_e - .Lmemcpy_c
 	.previous
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/lib/memset_64.S linux-libre-2.6.34-gnu1/arch/x86/lib/memset_64.S
--- linux-libre-2.6.33-gnu1/arch/x86/lib/memset_64.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/lib/memset_64.S	2010-05-16 17:17:36.000000000 -0400
@@ -12,9 +12,8 @@
  * 
  * rax   original destination
  */	
-	ALIGN
-memset_c:
-	CFI_STARTPROC
+	.section .altinstr_replacement, "ax", @progbits
+.Lmemset_c:
 	movq %rdi,%r9
 	movl %edx,%r8d
 	andl $7,%r8d
@@ -29,8 +28,8 @@ memset_c:
 	rep stosb
 	movq %r9,%rax
 	ret
-	CFI_ENDPROC
-ENDPROC(memset_c)
+.Lmemset_e:
+	.previous
 
 ENTRY(memset)
 ENTRY(__memset)
@@ -118,16 +117,11 @@ ENDPROC(__memset)
 
 #include <asm/cpufeature.h>
 
-	.section .altinstr_replacement,"ax"
-1:	.byte 0xeb				/* jmp <disp8> */
-	.byte (memset_c - memset) - (2f - 1b)	/* offset */
-2:
-	.previous
 	.section .altinstructions,"a"
 	.align 8
 	.quad memset
-	.quad 1b
+	.quad .Lmemset_c
 	.byte X86_FEATURE_REP_GOOD
 	.byte .Lfinal - memset
-	.byte 2b - 1b
+	.byte .Lmemset_e - .Lmemset_c
 	.previous
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/lib/rwsem_64.S linux-libre-2.6.34-gnu1/arch/x86/lib/rwsem_64.S
--- linux-libre-2.6.33-gnu1/arch/x86/lib/rwsem_64.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/lib/rwsem_64.S	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,81 @@
+/*
+ * x86-64 rwsem wrappers
+ *
+ * This interfaces the inline asm code to the slow-path
+ * C routines. We need to save the call-clobbered regs
+ * that the asm does not mark as clobbered, and move the
+ * argument from %rax to %rdi.
+ *
+ * NOTE! We don't need to save %rax, because the functions
+ * will always return the semaphore pointer in %rax (which
+ * is also the input argument to these helpers)
+ *
+ * The following can clobber %rdx because the asm clobbers it:
+ *   call_rwsem_down_write_failed
+ *   call_rwsem_wake
+ * but %rdi, %rsi, %rcx, %r8-r11 always need saving.
+ */
+
+#include <linux/linkage.h>
+#include <asm/rwlock.h>
+#include <asm/alternative-asm.h>
+#include <asm/frame.h>
+#include <asm/dwarf2.h>
+
+#define save_common_regs \
+	pushq %rdi; \
+	pushq %rsi; \
+	pushq %rcx; \
+	pushq %r8; \
+	pushq %r9; \
+	pushq %r10; \
+	pushq %r11
+
+#define restore_common_regs \
+	popq %r11; \
+	popq %r10; \
+	popq %r9; \
+	popq %r8; \
+	popq %rcx; \
+	popq %rsi; \
+	popq %rdi
+
+/* Fix up special calling conventions */
+ENTRY(call_rwsem_down_read_failed)
+	save_common_regs
+	pushq %rdx
+	movq %rax,%rdi
+	call rwsem_down_read_failed
+	popq %rdx
+	restore_common_regs
+	ret
+	ENDPROC(call_rwsem_down_read_failed)
+
+ENTRY(call_rwsem_down_write_failed)
+	save_common_regs
+	movq %rax,%rdi
+	call rwsem_down_write_failed
+	restore_common_regs
+	ret
+	ENDPROC(call_rwsem_down_write_failed)
+
+ENTRY(call_rwsem_wake)
+	decl %edx	/* do nothing if still outstanding active readers */
+	jnz 1f
+	save_common_regs
+	movq %rax,%rdi
+	call rwsem_wake
+	restore_common_regs
+1:	ret
+	ENDPROC(call_rwsem_wake)
+
+/* Fix up special calling conventions */
+ENTRY(call_rwsem_downgrade_wake)
+	save_common_regs
+	pushq %rdx
+	movq %rax,%rdi
+	call rwsem_downgrade_wake
+	popq %rdx
+	restore_common_regs
+	ret
+	ENDPROC(call_rwsem_downgrade_wake)
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/Makefile linux-libre-2.6.34-gnu1/arch/x86/Makefile
--- linux-libre-2.6.33-gnu1/arch/x86/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -135,9 +135,7 @@ drivers-$(CONFIG_OPROFILE) += arch/x86/o
 # suspend and hibernation support
 drivers-$(CONFIG_PM) += arch/x86/power/
 
-ifeq ($(CONFIG_X86_32),y)
 drivers-$(CONFIG_FB) += arch/x86/video/
-endif
 
 ####
 # boot loader support. Several targets are kept for legacy purposes
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/hugetlbpage.c linux-libre-2.6.34-gnu1/arch/x86/mm/hugetlbpage.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/hugetlbpage.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/hugetlbpage.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,6 @@
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/pagemap.h>
-#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/sysctl.h>
 #include <asm/mman.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/init_32.c linux-libre-2.6.34-gnu1/arch/x86/mm/init_32.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/init_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/init_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,11 +25,11 @@
 #include <linux/pfn.h>
 #include <linux/poison.h>
 #include <linux/bootmem.h>
-#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/memory_hotplug.h>
 #include <linux/initrd.h>
 #include <linux/cpumask.h>
+#include <linux/gfp.h>
 
 #include <asm/asm.h>
 #include <asm/bios_ebda.h>
@@ -241,6 +241,7 @@ kernel_physical_mapping_init(unsigned lo
 			     unsigned long page_size_mask)
 {
 	int use_pse = page_size_mask == (1<<PG_LEVEL_2M);
+	unsigned long last_map_addr = end;
 	unsigned long start_pfn, end_pfn;
 	pgd_t *pgd_base = swapper_pg_dir;
 	int pgd_idx, pmd_idx, pte_ofs;
@@ -341,9 +342,10 @@ repeat:
 					prot = PAGE_KERNEL_EXEC;
 
 				pages_4k++;
-				if (mapping_iter == 1)
+				if (mapping_iter == 1) {
 					set_pte(pte, pfn_pte(pfn, init_prot));
-				else
+					last_map_addr = (pfn << PAGE_SHIFT) + PAGE_SIZE;
+				} else
 					set_pte(pte, pfn_pte(pfn, prot));
 			}
 		}
@@ -368,7 +370,7 @@ repeat:
 		mapping_iter = 2;
 		goto repeat;
 	}
-	return 0;
+	return last_map_addr;
 }
 
 pte_t *kmap_pte;
@@ -748,6 +750,7 @@ static void __init zone_sizes_init(void)
 	free_area_init_nodes(max_zone_pfns);
 }
 
+#ifndef CONFIG_NO_BOOTMEM
 static unsigned long __init setup_node_bootmem(int nodeid,
 				 unsigned long start_pfn,
 				 unsigned long end_pfn,
@@ -764,13 +767,14 @@ static unsigned long __init setup_node_b
 	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;
 }
+#endif
 
 void __init setup_bootmem_allocator(void)
 {
+#ifndef CONFIG_NO_BOOTMEM
 	int nodeid;
 	unsigned long bootmap_size, bootmap;
 	/*
@@ -782,11 +786,13 @@ void __init setup_bootmem_allocator(void
 	if (bootmap == -1L)
 		panic("Cannot find bootmem map of size %ld\n", bootmap_size);
 	reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP");
+#endif
 
 	printk(KERN_INFO "  mapped low ram: 0 - %08lx\n",
 		 max_pfn_mapped<<PAGE_SHIFT);
 	printk(KERN_INFO "  low ram: 0 - %08lx\n", max_low_pfn<<PAGE_SHIFT);
 
+#ifndef CONFIG_NO_BOOTMEM
 	for_each_online_node(nodeid) {
 		 unsigned long start_pfn, end_pfn;
 
@@ -804,6 +810,7 @@ void __init setup_bootmem_allocator(void
 		bootmap = setup_node_bootmem(nodeid, start_pfn, end_pfn,
 						 bootmap);
 	}
+#endif
 
 	after_bootmem = 1;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/init_64.c linux-libre-2.6.34-gnu1/arch/x86/mm/init_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/init_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/init_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/memory_hotplug.h>
 #include <linux/nmi.h>
+#include <linux/gfp.h>
 
 #include <asm/processor.h>
 #include <asm/bios_ebda.h>
@@ -572,6 +573,7 @@ kernel_physical_mapping_init(unsigned lo
 void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,
 				int acpi, int k8)
 {
+#ifndef CONFIG_NO_BOOTMEM
 	unsigned long bootmap_size, bootmap;
 
 	bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
@@ -579,13 +581,15 @@ void __init initmem_init(unsigned long s
 				 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,
 					 0, end_pfn);
 	e820_register_active_regions(0, start_pfn, end_pfn);
 	free_bootmem_with_active_regions(0, end_pfn);
-	early_res_to_bootmem(0, end_pfn<<PAGE_SHIFT);
-	reserve_bootmem(bootmap, bootmap_size, BOOTMEM_DEFAULT);
+#else
+	e820_register_active_regions(0, start_pfn, end_pfn);
+#endif
 }
 #endif
 
@@ -974,7 +978,7 @@ vmemmap_populate(struct page *start_page
 			if (pmd_none(*pmd)) {
 				pte_t entry;
 
-				p = vmemmap_alloc_block(PMD_SIZE, node);
+				p = vmemmap_alloc_block_buf(PMD_SIZE, node);
 				if (!p)
 					return -ENOMEM;
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/init.c linux-libre-2.6.34-gnu1/arch/x86/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,3 +1,4 @@
+#include <linux/gfp.h>
 #include <linux/initrd.h>
 #include <linux/ioport.h>
 #include <linux/swap.h>
@@ -266,16 +267,9 @@ unsigned long __init_refok init_memory_m
 	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();
@@ -338,11 +332,23 @@ int devmem_is_allowed(unsigned long page
 
 void free_init_pages(char *what, unsigned long begin, unsigned long end)
 {
-	unsigned long addr = begin;
+	unsigned long addr;
+	unsigned long begin_aligned, end_aligned;
 
-	if (addr >= end)
+	/* Make sure boundaries are page aligned */
+	begin_aligned = PAGE_ALIGN(begin);
+	end_aligned   = end & PAGE_MASK;
+
+	if (WARN_ON(begin_aligned != begin || end_aligned != end)) {
+		begin = begin_aligned;
+		end   = end_aligned;
+	}
+
+	if (begin >= end)
 		return;
 
+	addr = begin;
+
 	/*
 	 * If debugging page accesses then do not free this memory but
 	 * mark them not present - any buggy init-section access will
@@ -350,7 +356,7 @@ void free_init_pages(char *what, unsigne
 	 */
 #ifdef CONFIG_DEBUG_PAGEALLOC
 	printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
-		begin, PAGE_ALIGN(end));
+		begin, end);
 	set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
 #else
 	/*
@@ -365,8 +371,7 @@ void free_init_pages(char *what, unsigne
 	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);
+		memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
 		free_page(addr);
 		totalram_pages++;
 	}
@@ -383,6 +388,15 @@ void free_initmem(void)
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_init_pages("initrd memory", start, end);
+	/*
+	 * end could be not aligned, and We can not align that,
+	 * decompresser could be confused by aligned initrd_end
+	 * We already reserve the end partial page before in
+	 *   - i386_start_kernel()
+	 *   - x86_64_start_kernel()
+	 *   - relocate_initrd()
+	 * So here We can do PAGE_ALIGN() safely to get partial page to be freed
+	 */
+	free_init_pages("initrd memory", start, PAGE_ALIGN(end));
 }
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/ioremap.c linux-libre-2.6.34-gnu1/arch/x86/mm/ioremap.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/ioremap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/ioremap.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,43 +24,6 @@
 
 #include "physaddr.h"
 
-int page_is_ram(unsigned long pagenr)
-{
-	resource_size_t addr, end;
-	int i;
-
-	/*
-	 * A special case is the first 4Kb of memory;
-	 * This is a BIOS owned area, not kernel ram, but generally
-	 * not listed as such in the E820 table.
-	 */
-	if (pagenr == 0)
-		return 0;
-
-	/*
-	 * Second special case: Some BIOSen report the PC BIOS
-	 * area (640->1Mb) as ram even though it is not.
-	 */
-	if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
-		    pagenr < (BIOS_END >> PAGE_SHIFT))
-		return 0;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		/*
-		 * Not usable memory:
-		 */
-		if (e820.map[i].type != E820_RAM)
-			continue;
-		addr = (e820.map[i].addr + PAGE_SIZE-1) >> PAGE_SHIFT;
-		end = (e820.map[i].addr + e820.map[i].size) >> PAGE_SHIFT;
-
-
-		if ((pagenr >= addr) && (pagenr < end))
-			return 1;
-	}
-	return 0;
-}
-
 /*
  * Fix up the linear direct mapping of the kernel to avoid cache attribute
  * conflicts.
@@ -422,6 +385,10 @@ void __init early_ioremap_init(void)
 	 * The boot-ioremap range spans multiple pmds, for which
 	 * we are not prepared:
 	 */
+#define __FIXADDR_TOP (-PAGE_SIZE)
+	BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT)
+		     != (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT));
+#undef __FIXADDR_TOP
 	if (pmd != early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END))) {
 		WARN_ON(1);
 		printk(KERN_WARNING "pmd %p != %p\n",
@@ -481,6 +448,20 @@ 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;
 
+void __init fixup_early_ioremap(void)
+{
+	int i;
+
+	for (i = 0; i < FIX_BTMAPS_SLOTS; i++) {
+		if (prev_map[i]) {
+			WARN_ON(1);
+			break;
+		}
+	}
+
+	early_ioremap_init();
+}
+
 static int __init check_early_ioremap_leak(void)
 {
 	int count = 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/kmemcheck/kmemcheck.c linux-libre-2.6.34-gnu1/arch/x86/mm/kmemcheck/kmemcheck.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/kmemcheck/kmemcheck.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/kmemcheck/kmemcheck.c	2010-05-16 17:17:36.000000000 -0400
@@ -337,7 +337,7 @@ bool kmemcheck_is_obj_initialized(unsign
 	if (!shadow)
 		return true;
 
-	status = kmemcheck_shadow_test(shadow, size);
+	status = kmemcheck_shadow_test_all(shadow, size);
 
 	return status == KMEMCHECK_SHADOW_INITIALIZED;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/kmemcheck/shadow.c linux-libre-2.6.34-gnu1/arch/x86/mm/kmemcheck/shadow.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/kmemcheck/shadow.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/kmemcheck/shadow.c	2010-05-16 17:17:36.000000000 -0400
@@ -125,12 +125,12 @@ void kmemcheck_mark_initialized_pages(st
 
 enum kmemcheck_shadow kmemcheck_shadow_test(void *shadow, unsigned int size)
 {
+#ifdef CONFIG_KMEMCHECK_PARTIAL_OK
 	uint8_t *x;
 	unsigned int i;
 
 	x = shadow;
 
-#ifdef CONFIG_KMEMCHECK_PARTIAL_OK
 	/*
 	 * Make sure _some_ bytes are initialized. Gcc frequently generates
 	 * code to access neighboring bytes.
@@ -139,13 +139,25 @@ enum kmemcheck_shadow kmemcheck_shadow_t
 		if (x[i] == KMEMCHECK_SHADOW_INITIALIZED)
 			return x[i];
 	}
+
+	return x[0];
 #else
+	return kmemcheck_shadow_test_all(shadow, size);
+#endif
+}
+
+enum kmemcheck_shadow kmemcheck_shadow_test_all(void *shadow, unsigned int size)
+{
+	uint8_t *x;
+	unsigned int i;
+
+	x = shadow;
+
 	/* All bytes must be initialized. */
 	for (i = 0; i < size; ++i) {
 		if (x[i] != KMEMCHECK_SHADOW_INITIALIZED)
 			return x[i];
 	}
-#endif
 
 	return x[0];
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/kmemcheck/shadow.h linux-libre-2.6.34-gnu1/arch/x86/mm/kmemcheck/shadow.h
--- linux-libre-2.6.33-gnu1/arch/x86/mm/kmemcheck/shadow.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/kmemcheck/shadow.h	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,8 @@ enum kmemcheck_shadow {
 void *kmemcheck_shadow_lookup(unsigned long address);
 
 enum kmemcheck_shadow kmemcheck_shadow_test(void *shadow, unsigned int size);
+enum kmemcheck_shadow kmemcheck_shadow_test_all(void *shadow,
+						unsigned int size);
 void kmemcheck_shadow_set(void *shadow, unsigned int size);
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/kmmio.c linux-libre-2.6.34-gnu1/arch/x86/mm/kmmio.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/kmmio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/kmmio.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/kdebug.h>
 #include <linux/mutex.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 #include <linux/errno.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/mmap.c linux-libre-2.6.34-gnu1/arch/x86/mm/mmap.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/mmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/mmap.c	2010-05-16 17:17:36.000000000 -0400
@@ -71,7 +71,7 @@ static int mmap_is_legacy(void)
 	if (current->personality & ADDR_COMPAT_LAYOUT)
 		return 1;
 
-	if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
+	if (rlimit(RLIMIT_STACK) == RLIM_INFINITY)
 		return 1;
 
 	return sysctl_legacy_va_layout;
@@ -96,7 +96,7 @@ static unsigned long mmap_rnd(void)
 
 static unsigned long mmap_base(void)
 {
-	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
+	unsigned long gap = rlimit(RLIMIT_STACK);
 
 	if (gap < MIN_GAP)
 		gap = MIN_GAP;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/mmio-mod.c linux-libre-2.6.34-gnu1/arch/x86/mm/mmio-mod.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/mmio-mod.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/mmio-mod.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 
 #include <linux/module.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/version.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/numa_32.c linux-libre-2.6.34-gnu1/arch/x86/mm/numa_32.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/numa_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/numa_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -418,7 +418,10 @@ void __init initmem_init(unsigned long s
 
 	for_each_online_node(nid) {
 		memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
+		NODE_DATA(nid)->node_id = nid;
+#ifndef CONFIG_NO_BOOTMEM
 		NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
+#endif
 	}
 
 	setup_bootmem_allocator();
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/numa_64.c linux-libre-2.6.34-gnu1/arch/x86/mm/numa_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/numa_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/numa_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -163,30 +163,48 @@ static void * __init early_node_mem(int
 				    unsigned long end, unsigned long size,
 				    unsigned long align)
 {
-	unsigned long mem = find_e820_area(start, end, size, align);
-	void *ptr;
+	unsigned long mem;
 
+	/*
+	 * put it on high as possible
+	 * something will go with NODE_DATA
+	 */
+	if (start < (MAX_DMA_PFN<<PAGE_SHIFT))
+		start = MAX_DMA_PFN<<PAGE_SHIFT;
+	if (start < (MAX_DMA32_PFN<<PAGE_SHIFT) &&
+	    end > (MAX_DMA32_PFN<<PAGE_SHIFT))
+		start = MAX_DMA32_PFN<<PAGE_SHIFT;
+	mem = find_e820_area(start, end, size, align);
 	if (mem != -1L)
 		return __va(mem);
 
-	ptr = __alloc_bootmem_nopanic(size, align, __pa(MAX_DMA_ADDRESS));
-	if (ptr == NULL) {
-		printk(KERN_ERR "Cannot find %lu bytes in node %d\n",
+	/* extend the search scope */
+	end = max_pfn_mapped << PAGE_SHIFT;
+	if (end > (MAX_DMA32_PFN<<PAGE_SHIFT))
+		start = MAX_DMA32_PFN<<PAGE_SHIFT;
+	else
+		start = MAX_DMA_PFN<<PAGE_SHIFT;
+	mem = find_e820_area(start, end, size, align);
+	if (mem != -1L)
+		return __va(mem);
+
+	printk(KERN_ERR "Cannot find %lu bytes in node %d\n",
 		       size, nodeid);
-		return NULL;
-	}
-	return ptr;
+
+	return NULL;
 }
 
 /* Initialize bootmem allocator for a node */
 void __init
 setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
 {
-	unsigned long start_pfn, last_pfn, bootmap_pages, bootmap_size;
+	unsigned long start_pfn, last_pfn, nodedata_phys;
 	const int pgdat_size = roundup(sizeof(pg_data_t), PAGE_SIZE);
-	unsigned long bootmap_start, nodedata_phys;
-	void *bootmap;
 	int nid;
+#ifndef CONFIG_NO_BOOTMEM
+	unsigned long bootmap_start, bootmap_pages, bootmap_size;
+	void *bootmap;
+#endif
 
 	if (!end)
 		return;
@@ -200,7 +218,7 @@ setup_node_bootmem(int nodeid, unsigned
 
 	start = roundup(start, ZONE_ALIGN);
 
-	printk(KERN_INFO "Bootmem setup node %d %016lx-%016lx\n", nodeid,
+	printk(KERN_INFO "Initmem setup node %d %016lx-%016lx\n", nodeid,
 	       start, end);
 
 	start_pfn = start >> PAGE_SHIFT;
@@ -211,14 +229,21 @@ setup_node_bootmem(int nodeid, unsigned
 	if (node_data[nodeid] == NULL)
 		return;
 	nodedata_phys = __pa(node_data[nodeid]);
+	reserve_early(nodedata_phys, nodedata_phys + pgdat_size, "NODE_DATA");
 	printk(KERN_INFO "  NODE_DATA [%016lx - %016lx]\n", nodedata_phys,
 		nodedata_phys + pgdat_size - 1);
+	nid = phys_to_nid(nodedata_phys);
+	if (nid != nodeid)
+		printk(KERN_INFO "    NODE_DATA(%d) on node %d\n", nodeid, nid);
 
 	memset(NODE_DATA(nodeid), 0, sizeof(pg_data_t));
-	NODE_DATA(nodeid)->bdata = &bootmem_node_data[nodeid];
+	NODE_DATA(nodeid)->node_id = nodeid;
 	NODE_DATA(nodeid)->node_start_pfn = start_pfn;
 	NODE_DATA(nodeid)->node_spanned_pages = last_pfn - start_pfn;
 
+#ifndef CONFIG_NO_BOOTMEM
+	NODE_DATA(nodeid)->bdata = &bootmem_node_data[nodeid];
+
 	/*
 	 * Find a place for the bootmem map
 	 * nodedata_phys could be on other nodes by alloc_bootmem,
@@ -227,11 +252,7 @@ setup_node_bootmem(int nodeid, unsigned
 	 * of alloc_bootmem, that could clash with reserved range
 	 */
 	bootmap_pages = bootmem_bootmap_pages(last_pfn - start_pfn);
-	nid = phys_to_nid(nodedata_phys);
-	if (nid == nodeid)
-		bootmap_start = roundup(nodedata_phys + pgdat_size, PAGE_SIZE);
-	else
-		bootmap_start = roundup(start, PAGE_SIZE);
+	bootmap_start = roundup(nodedata_phys + pgdat_size, PAGE_SIZE);
 	/*
 	 * SMP_CACHE_BYTES could be enough, but init_bootmem_node like
 	 * to use that to align to PAGE_SIZE
@@ -239,18 +260,13 @@ setup_node_bootmem(int nodeid, unsigned
 	bootmap = early_node_mem(nodeid, bootmap_start, end,
 				 bootmap_pages<<PAGE_SHIFT, PAGE_SIZE);
 	if (bootmap == NULL)  {
-		if (nodedata_phys < start || nodedata_phys >= end) {
-			/*
-			 * only need to free it if it is from other node
-			 * bootmem
-			 */
-			if (nid != nodeid)
-				free_bootmem(nodedata_phys, pgdat_size);
-		}
+		free_early(nodedata_phys, nodedata_phys + pgdat_size);
 		node_data[nodeid] = NULL;
 		return;
 	}
 	bootmap_start = __pa(bootmap);
+	reserve_early(bootmap_start, bootmap_start+(bootmap_pages<<PAGE_SHIFT),
+			"BOOTMAP");
 
 	bootmap_size = init_bootmem_node(NODE_DATA(nodeid),
 					 bootmap_start >> PAGE_SHIFT,
@@ -259,31 +275,12 @@ setup_node_bootmem(int nodeid, unsigned
 	printk(KERN_INFO "  bootmap [%016lx -  %016lx] pages %lx\n",
 		 bootmap_start, bootmap_start + bootmap_size - 1,
 		 bootmap_pages);
-
-	free_bootmem_with_active_regions(nodeid, end);
-
-	/*
-	 * convert early reserve to bootmem reserve earlier
-	 * otherwise early_node_mem could use early reserved mem
-	 * on previous node
-	 */
-	early_res_to_bootmem(start, end);
-
-	/*
-	 * in some case early_node_mem could use alloc_bootmem
-	 * to get range on other node, don't reserve that again
-	 */
-	if (nid != nodeid)
-		printk(KERN_INFO "    NODE_DATA(%d) on node %d\n", nodeid, nid);
-	else
-		reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys,
-					pgdat_size, BOOTMEM_DEFAULT);
 	nid = phys_to_nid(bootmap_start);
 	if (nid != nodeid)
 		printk(KERN_INFO "    bootmap(%d) on node %d\n", nodeid, nid);
-	else
-		reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start,
-				 bootmap_pages<<PAGE_SHIFT, BOOTMEM_DEFAULT);
+
+	free_bootmem_with_active_regions(nodeid, end);
+#endif
 
 	node_set_online(nodeid);
 }
@@ -427,7 +424,7 @@ static int __init split_nodes_interleave
 	 * Calculate the number of big nodes that can be allocated as a result
 	 * of consolidating the remainder.
 	 */
-	big = ((size & ~FAKE_NODE_MIN_HASH_MASK) & nr_nodes) /
+	big = ((size & ~FAKE_NODE_MIN_HASH_MASK) * nr_nodes) /
 		FAKE_NODE_MIN_SIZE;
 
 	size &= FAKE_NODE_MIN_HASH_MASK;
@@ -502,77 +499,99 @@ static int __init split_nodes_interleave
 }
 
 /*
- * Splits num_nodes nodes up equally starting at node_start.  The return value
- * is the number of nodes split up and addr is adjusted to be at the end of the
- * last node allocated.
+ * Returns the end address of a node so that there is at least `size' amount of
+ * non-reserved memory or `max_addr' is reached.
  */
-static int __init split_nodes_equally(u64 *addr, u64 max_addr, int node_start,
-				      int num_nodes)
+static u64 __init find_end_of_node(u64 start, u64 max_addr, u64 size)
 {
-	unsigned int big;
-	u64 size;
-	int i;
-
-	if (num_nodes <= 0)
-		return -1;
-	if (num_nodes > MAX_NUMNODES)
-		num_nodes = MAX_NUMNODES;
-	size = (max_addr - *addr - e820_hole_size(*addr, max_addr)) /
-	       num_nodes;
-	/*
-	 * Calculate the number of big nodes that can be allocated as a result
-	 * of consolidating the leftovers.
-	 */
-	big = ((size & ~FAKE_NODE_MIN_HASH_MASK) * num_nodes) /
-	      FAKE_NODE_MIN_SIZE;
-
-	/* Round down to nearest FAKE_NODE_MIN_SIZE. */
-	size &= FAKE_NODE_MIN_HASH_MASK;
-	if (!size) {
-		printk(KERN_ERR "Not enough memory for each node.  "
-		       "NUMA emulation disabled.\n");
-		return -1;
-	}
-
-	for (i = node_start; i < num_nodes + node_start; i++) {
-		u64 end = *addr + size;
+	u64 end = start + size;
 
-		if (i < big)
-			end += FAKE_NODE_MIN_SIZE;
-		/*
-		 * The final node can have the remaining system RAM.  Other
-		 * nodes receive roughly the same amount of available pages.
-		 */
-		if (i == num_nodes + node_start - 1)
+	while (end - start - e820_hole_size(start, end) < size) {
+		end += FAKE_NODE_MIN_SIZE;
+		if (end > max_addr) {
 			end = max_addr;
-		else
-			while (end - *addr - e820_hole_size(*addr, end) <
-			       size) {
-				end += FAKE_NODE_MIN_SIZE;
-				if (end > max_addr) {
-					end = max_addr;
-					break;
-				}
-			}
-		if (setup_node_range(i, addr, end - *addr, max_addr) < 0)
 			break;
+		}
 	}
-	return i - node_start + 1;
+	return end;
 }
 
 /*
- * Splits the remaining system RAM into chunks of size.  The remaining memory is
- * always assigned to a final node and can be asymmetric.  Returns the number of
- * nodes split.
+ * Sets up fake nodes of `size' interleaved over physical nodes ranging from
+ * `addr' to `max_addr'.  The return value is the number of nodes allocated.
  */
-static int __init split_nodes_by_size(u64 *addr, u64 max_addr, int node_start,
-				      u64 size)
+static int __init split_nodes_size_interleave(u64 addr, u64 max_addr, u64 size)
 {
-	int i = node_start;
-	size = (size << 20) & FAKE_NODE_MIN_HASH_MASK;
-	while (!setup_node_range(i++, addr, size, max_addr))
-		;
-	return i - node_start;
+	nodemask_t physnode_mask = NODE_MASK_NONE;
+	u64 min_size;
+	int ret = 0;
+	int i;
+
+	if (!size)
+		return -1;
+	/*
+	 * The limit on emulated nodes is MAX_NUMNODES, so the size per node is
+	 * increased accordingly if the requested size is too small.  This
+	 * creates a uniform distribution of node sizes across the entire
+	 * machine (but not necessarily over physical nodes).
+	 */
+	min_size = (max_addr - addr - e820_hole_size(addr, max_addr)) /
+						MAX_NUMNODES;
+	min_size = max(min_size, FAKE_NODE_MIN_SIZE);
+	if ((min_size & FAKE_NODE_MIN_HASH_MASK) < min_size)
+		min_size = (min_size + FAKE_NODE_MIN_SIZE) &
+						FAKE_NODE_MIN_HASH_MASK;
+	if (size < min_size) {
+		pr_err("Fake node size %LuMB too small, increasing to %LuMB\n",
+			size >> 20, min_size >> 20);
+		size = min_size;
+	}
+	size &= FAKE_NODE_MIN_HASH_MASK;
+
+	for (i = 0; i < MAX_NUMNODES; i++)
+		if (physnodes[i].start != physnodes[i].end)
+			node_set(i, physnode_mask);
+	/*
+	 * Fill physical nodes with fake nodes of size until there is no memory
+	 * left on any of them.
+	 */
+	while (nodes_weight(physnode_mask)) {
+		for_each_node_mask(i, physnode_mask) {
+			u64 dma32_end = MAX_DMA32_PFN << PAGE_SHIFT;
+			u64 end;
+
+			end = find_end_of_node(physnodes[i].start,
+						physnodes[i].end, size);
+			/*
+			 * If there won't be at least FAKE_NODE_MIN_SIZE of
+			 * non-reserved memory in ZONE_DMA32 for the next node,
+			 * this one must extend to the boundary.
+			 */
+			if (end < dma32_end && dma32_end - end -
+			    e820_hole_size(end, dma32_end) < FAKE_NODE_MIN_SIZE)
+				end = dma32_end;
+
+			/*
+			 * If there won't be enough non-reserved memory for the
+			 * next node, this one must extend to the end of the
+			 * physical node.
+			 */
+			if (physnodes[i].end - end -
+			    e820_hole_size(end, physnodes[i].end) < size)
+				end = physnodes[i].end;
+
+			/*
+			 * Setup the fake node that will be allocated as bootmem
+			 * later.  If setup_node_range() returns non-zero, there
+			 * is no more memory available on this physical node.
+			 */
+			if (setup_node_range(ret++, &physnodes[i].start,
+						end - physnodes[i].start,
+						physnodes[i].end) < 0)
+				node_clear(i, physnode_mask);
+		}
+	}
+	return ret;
 }
 
 /*
@@ -582,87 +601,32 @@ static int __init split_nodes_by_size(u6
 static int __init numa_emulation(unsigned long start_pfn,
 			unsigned long last_pfn, int acpi, int k8)
 {
-	u64 size, addr = start_pfn << PAGE_SHIFT;
+	u64 addr = start_pfn << PAGE_SHIFT;
 	u64 max_addr = last_pfn << PAGE_SHIFT;
-	int num_nodes = 0, num = 0, coeff_flag, coeff = -1, i;
 	int num_phys_nodes;
+	int num_nodes;
+	int i;
 
 	num_phys_nodes = setup_physnodes(addr, max_addr, acpi, k8);
 	/*
-	 * If the numa=fake command-line is just a single number N, split the
-	 * system RAM into N fake nodes.
+	 * If the numa=fake command-line contains a 'M' or 'G', it represents
+	 * the fixed node size.  Otherwise, if it is just a single number N,
+	 * split the system RAM into N fake nodes.
 	 */
-	if (!strchr(cmdline, '*') && !strchr(cmdline, ',')) {
-		long n = simple_strtol(cmdline, NULL, 0);
+	if (strchr(cmdline, 'M') || strchr(cmdline, 'G')) {
+		u64 size;
 
-		num_nodes = split_nodes_interleave(addr, max_addr,
-							num_phys_nodes, n);
-		if (num_nodes < 0)
-			return num_nodes;
-		goto out;
-	}
+		size = memparse(cmdline, &cmdline);
+		num_nodes = split_nodes_size_interleave(addr, max_addr, size);
+	} else {
+		unsigned long n;
 
-	/* Parse the command line. */
-	for (coeff_flag = 0; ; cmdline++) {
-		if (*cmdline && isdigit(*cmdline)) {
-			num = num * 10 + *cmdline - '0';
-			continue;
-		}
-		if (*cmdline == '*') {
-			if (num > 0)
-				coeff = num;
-			coeff_flag = 1;
-		}
-		if (!*cmdline || *cmdline == ',') {
-			if (!coeff_flag)
-				coeff = 1;
-			/*
-			 * Round down to the nearest FAKE_NODE_MIN_SIZE.
-			 * Command-line coefficients are in megabytes.
-			 */
-			size = ((u64)num << 20) & FAKE_NODE_MIN_HASH_MASK;
-			if (size)
-				for (i = 0; i < coeff; i++, num_nodes++)
-					if (setup_node_range(num_nodes, &addr,
-						size, max_addr) < 0)
-						goto done;
-			if (!*cmdline)
-				break;
-			coeff_flag = 0;
-			coeff = -1;
-		}
-		num = 0;
-	}
-done:
-	if (!num_nodes)
-		return -1;
-	/* Fill remainder of system RAM, if appropriate. */
-	if (addr < max_addr) {
-		if (coeff_flag && coeff < 0) {
-			/* Split remaining nodes into num-sized chunks */
-			num_nodes += split_nodes_by_size(&addr, max_addr,
-							 num_nodes, num);
-			goto out;
-		}
-		switch (*(cmdline - 1)) {
-		case '*':
-			/* Split remaining nodes into coeff chunks */
-			if (coeff <= 0)
-				break;
-			num_nodes += split_nodes_equally(&addr, max_addr,
-							 num_nodes, coeff);
-			break;
-		case ',':
-			/* Do not allocate remaining system RAM */
-			break;
-		default:
-			/* Give one final node */
-			setup_node_range(num_nodes, &addr, max_addr - addr,
-					 max_addr);
-			num_nodes++;
-		}
+		n = simple_strtoul(cmdline, NULL, 0);
+		num_nodes = split_nodes_interleave(addr, max_addr, num_phys_nodes, n);
 	}
-out:
+
+	if (num_nodes < 0)
+		return num_nodes;
 	memnode_shift = compute_hash_shift(nodes, num_nodes, NULL);
 	if (memnode_shift < 0) {
 		memnode_shift = 0;
@@ -742,6 +706,10 @@ unsigned long __init numa_free_all_bootm
 	for_each_online_node(i)
 		pages += free_all_bootmem_node(NODE_DATA(i));
 
+#ifdef CONFIG_NO_BOOTMEM
+	pages += free_all_memory_core_early(MAX_NUMNODES);
+#endif
+
 	return pages;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/pageattr.c linux-libre-2.6.34-gnu1/arch/x86/mm/pageattr.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/pageattr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/pageattr.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,13 +6,13 @@
 #include <linux/bootmem.h>
 #include <linux/module.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
 #include <linux/pfn.h>
 #include <linux/percpu.h>
+#include <linux/gfp.h>
 
 #include <asm/e820.h>
 #include <asm/processor.h>
@@ -291,8 +291,29 @@ static inline pgprot_t static_protection
 	 */
 	if (kernel_set_to_readonly &&
 	    within(address, (unsigned long)_text,
-		   (unsigned long)__end_rodata_hpage_align))
-		pgprot_val(forbidden) |= _PAGE_RW;
+		   (unsigned long)__end_rodata_hpage_align)) {
+		unsigned int level;
+
+		/*
+		 * Don't enforce the !RW mapping for the kernel text mapping,
+		 * if the current mapping is already using small page mapping.
+		 * No need to work hard to preserve large page mappings in this
+		 * case.
+		 *
+		 * This also fixes the Linux Xen paravirt guest boot failure
+		 * (because of unexpected read-only mappings for kernel identity
+		 * mappings). In this paravirt guest case, the kernel text
+		 * mapping and the kernel identity mapping share the same
+		 * page-table pages. Thus we can't really use different
+		 * protections for the kernel text and identity mappings. Also,
+		 * these shared mappings are made of small page mappings.
+		 * Thus this don't enforce !RW mapping for small page kernel
+		 * text mapping logic will help Linux Xen parvirt guest boot
+		 * aswell.
+		 */
+		if (lookup_address(address, &level) && (level != PG_LEVEL_4K))
+			pgprot_val(forbidden) |= _PAGE_RW;
+	}
 #endif
 
 	prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/pat.c linux-libre-2.6.34-gnu1/arch/x86/mm/pat.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/pat.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/pat.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,7 @@
 #include <linux/debugfs.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/gfp.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/fs.h>
 #include <linux/rbtree.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/pgtable_32.c linux-libre-2.6.34-gnu1/arch/x86/mm/pgtable_32.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/pgtable_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/pgtable_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,6 @@
 #include <linux/swap.h>
 #include <linux/smp.h>
 #include <linux/highmem.h>
-#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/spinlock.h>
 #include <linux/module.h>
@@ -19,6 +18,7 @@
 #include <asm/e820.h>
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
+#include <asm/io.h>
 
 unsigned int __VMALLOC_RESERVE = 128 << 20;
 
@@ -129,6 +129,7 @@ static int __init parse_reservetop(char
 
 	address = memparse(arg, &arg);
 	reserve_top_address(address);
+	fixup_early_ioremap();
 	return 0;
 }
 early_param("reservetop", parse_reservetop);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/pgtable.c linux-libre-2.6.34-gnu1/arch/x86/mm/pgtable.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/pgtable.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/pgtable.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,5 @@
 #include <linux/mm.h>
+#include <linux/gfp.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/tlb.h>
@@ -6,6 +7,14 @@
 
 #define PGALLOC_GFP GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO
 
+#ifdef CONFIG_HIGHPTE
+#define PGALLOC_USER_GFP __GFP_HIGHMEM
+#else
+#define PGALLOC_USER_GFP 0
+#endif
+
+gfp_t __userpte_alloc_gfp = PGALLOC_GFP | PGALLOC_USER_GFP;
+
 pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
 	return (pte_t *)__get_free_page(PGALLOC_GFP);
@@ -15,16 +24,29 @@ pgtable_t pte_alloc_one(struct mm_struct
 {
 	struct page *pte;
 
-#ifdef CONFIG_HIGHPTE
-	pte = alloc_pages(PGALLOC_GFP | __GFP_HIGHMEM, 0);
-#else
-	pte = alloc_pages(PGALLOC_GFP, 0);
-#endif
+	pte = alloc_pages(__userpte_alloc_gfp, 0);
 	if (pte)
 		pgtable_page_ctor(pte);
 	return pte;
 }
 
+static int __init setup_userpte(char *arg)
+{
+	if (!arg)
+		return -EINVAL;
+
+	/*
+	 * "userpte=nohigh" disables allocation of user pagetables in
+	 * high memory.
+	 */
+	if (strcmp(arg, "nohigh") == 0)
+		__userpte_alloc_gfp &= ~__GFP_HIGHMEM;
+	else
+		return -EINVAL;
+	return 0;
+}
+early_param("userpte", setup_userpte);
+
 void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
 {
 	pgtable_page_dtor(pte);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/srat_64.c linux-libre-2.6.34-gnu1/arch/x86/mm/srat_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/srat_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/srat_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -461,7 +461,8 @@ void __init acpi_fake_nodes(const struct
 		 * node, it must now point to the fake node ID.
 		 */
 		for (j = 0; j < MAX_LOCAL_APIC; j++)
-			if (apicid_to_node[j] == nid)
+			if (apicid_to_node[j] == nid &&
+			    fake_apicid_to_node[j] == NUMA_NO_NODE)
 				fake_apicid_to_node[j] = i;
 	}
 	for (i = 0; i < num_nodes; i++)
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/mm/tlb.c linux-libre-2.6.34-gnu1/arch/x86/mm/tlb.c
--- linux-libre-2.6.33-gnu1/arch/x86/mm/tlb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/mm/tlb.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,7 @@ union smp_flush_state {
 	struct {
 		struct mm_struct *flush_mm;
 		unsigned long flush_va;
-		spinlock_t tlbstate_lock;
+		raw_spinlock_t tlbstate_lock;
 		DECLARE_BITMAP(flush_cpumask, NR_CPUS);
 	};
 	char pad[INTERNODE_CACHE_BYTES];
@@ -181,7 +181,7 @@ static void flush_tlb_others_ipi(const s
 	 * 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);
+	raw_spin_lock(&f->tlbstate_lock);
 
 	f->flush_mm = mm;
 	f->flush_va = va;
@@ -199,7 +199,7 @@ static void flush_tlb_others_ipi(const s
 
 	f->flush_mm = NULL;
 	f->flush_va = 0;
-	spin_unlock(&f->tlbstate_lock);
+	raw_spin_unlock(&f->tlbstate_lock);
 }
 
 void native_flush_tlb_others(const struct cpumask *cpumask,
@@ -223,7 +223,7 @@ 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);
+		raw_spin_lock_init(&flush_state[i].tlbstate_lock);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/oprofile/nmi_int.c linux-libre-2.6.34-gnu1/arch/x86/oprofile/nmi_int.c
--- linux-libre-2.6.33-gnu1/arch/x86/oprofile/nmi_int.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/oprofile/nmi_int.c	2010-05-16 17:17:36.000000000 -0400
@@ -159,7 +159,7 @@ static int nmi_setup_mux(void)
 
 	for_each_possible_cpu(i) {
 		per_cpu(cpu_msrs, i).multiplex =
-			kmalloc(multiplex_size, GFP_KERNEL);
+			kzalloc(multiplex_size, GFP_KERNEL);
 		if (!per_cpu(cpu_msrs, i).multiplex)
 			return 0;
 	}
@@ -179,7 +179,6 @@ static void nmi_cpu_setup_mux(int cpu, s
 		if (counter_config[i].enabled) {
 			multiplex[i].saved = -(u64)counter_config[i].count;
 		} else {
-			multiplex[i].addr  = 0;
 			multiplex[i].saved = 0;
 		}
 	}
@@ -189,25 +188,27 @@ static void nmi_cpu_setup_mux(int cpu, s
 
 static void nmi_cpu_save_mpx_registers(struct op_msrs *msrs)
 {
+	struct op_msr *counters = msrs->counters;
 	struct op_msr *multiplex = msrs->multiplex;
 	int i;
 
 	for (i = 0; i < model->num_counters; ++i) {
 		int virt = op_x86_phys_to_virt(i);
-		if (multiplex[virt].addr)
-			rdmsrl(multiplex[virt].addr, multiplex[virt].saved);
+		if (counters[i].addr)
+			rdmsrl(counters[i].addr, multiplex[virt].saved);
 	}
 }
 
 static void nmi_cpu_restore_mpx_registers(struct op_msrs *msrs)
 {
+	struct op_msr *counters = msrs->counters;
 	struct op_msr *multiplex = msrs->multiplex;
 	int i;
 
 	for (i = 0; i < model->num_counters; ++i) {
 		int virt = op_x86_phys_to_virt(i);
-		if (multiplex[virt].addr)
-			wrmsrl(multiplex[virt].addr, multiplex[virt].saved);
+		if (counters[i].addr)
+			wrmsrl(counters[i].addr, multiplex[virt].saved);
 	}
 }
 
@@ -303,11 +304,11 @@ static int allocate_msrs(void)
 
 	int i;
 	for_each_possible_cpu(i) {
-		per_cpu(cpu_msrs, i).counters = kmalloc(counters_size,
+		per_cpu(cpu_msrs, i).counters = kzalloc(counters_size,
 							GFP_KERNEL);
 		if (!per_cpu(cpu_msrs, i).counters)
 			return 0;
-		per_cpu(cpu_msrs, i).controls = kmalloc(controls_size,
+		per_cpu(cpu_msrs, i).controls = kzalloc(controls_size,
 							GFP_KERNEL);
 		if (!per_cpu(cpu_msrs, i).controls)
 			return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/oprofile/op_model_amd.c linux-libre-2.6.34-gnu1/arch/x86/oprofile/op_model_amd.c
--- linux-libre-2.6.33-gnu1/arch/x86/oprofile/op_model_amd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/oprofile/op_model_amd.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,9 @@
 #include <asm/ptrace.h>
 #include <asm/msr.h>
 #include <asm/nmi.h>
+#include <asm/apic.h>
+#include <asm/processor.h>
+#include <asm/cpufeature.h>
 
 #include "op_x86_model.h"
 #include "op_counter.h"
@@ -43,23 +46,10 @@
 
 static unsigned long reset_value[NUM_VIRT_COUNTERS];
 
-#ifdef CONFIG_OPROFILE_IBS
-
-/* IbsFetchCtl bits/masks */
-#define IBS_FETCH_RAND_EN		(1ULL<<57)
-#define IBS_FETCH_VAL			(1ULL<<49)
-#define IBS_FETCH_ENABLE		(1ULL<<48)
-#define IBS_FETCH_CNT_MASK		0xFFFF0000ULL
-
-/*IbsOpCtl bits */
-#define IBS_OP_CNT_CTL			(1ULL<<19)
-#define IBS_OP_VAL			(1ULL<<18)
-#define IBS_OP_ENABLE			(1ULL<<17)
-
 #define IBS_FETCH_SIZE			6
 #define IBS_OP_SIZE			12
 
-static int has_ibs;	/* AMD Family10h and later */
+static u32 ibs_caps;
 
 struct op_ibs_config {
 	unsigned long op_enabled;
@@ -71,24 +61,52 @@ struct op_ibs_config {
 };
 
 static struct op_ibs_config ibs_config;
+static u64 ibs_op_ctl;
 
-#endif
+/*
+ * IBS cpuid feature detection
+ */
 
-#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
+#define IBS_CPUID_FEATURES      0x8000001b
 
-static void op_mux_fill_in_addresses(struct op_msrs * const msrs)
+/*
+ * Same bit mask as for IBS cpuid feature flags (Fn8000_001B_EAX), but
+ * bit 0 is used to indicate the existence of IBS.
+ */
+#define IBS_CAPS_AVAIL			(1LL<<0)
+#define IBS_CAPS_RDWROPCNT		(1LL<<3)
+#define IBS_CAPS_OPCNT			(1LL<<4)
+
+/*
+ * IBS randomization macros
+ */
+#define IBS_RANDOM_BITS			12
+#define IBS_RANDOM_MASK			((1ULL << IBS_RANDOM_BITS) - 1)
+#define IBS_RANDOM_MAXCNT_OFFSET	(1ULL << (IBS_RANDOM_BITS - 5))
+
+static u32 get_ibs_caps(void)
 {
-	int i;
+	u32 ibs_caps;
+	unsigned int max_level;
 
-	for (i = 0; i < NUM_VIRT_COUNTERS; i++) {
-		int hw_counter = op_x86_virt_to_phys(i);
-		if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i))
-			msrs->multiplex[i].addr = MSR_K7_PERFCTR0 + hw_counter;
-		else
-			msrs->multiplex[i].addr = 0;
-	}
+	if (!boot_cpu_has(X86_FEATURE_IBS))
+		return 0;
+
+	/* check IBS cpuid feature flags */
+	max_level = cpuid_eax(0x80000000);
+	if (max_level < IBS_CPUID_FEATURES)
+		return IBS_CAPS_AVAIL;
+
+	ibs_caps = cpuid_eax(IBS_CPUID_FEATURES);
+	if (!(ibs_caps & IBS_CAPS_AVAIL))
+		/* cpuid flags not valid */
+		return IBS_CAPS_AVAIL;
+
+	return ibs_caps;
 }
 
+#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
+
 static void op_mux_switch_ctrl(struct op_x86_model_spec const *model,
 			       struct op_msrs const * const msrs)
 {
@@ -98,7 +116,7 @@ static void op_mux_switch_ctrl(struct op
 	/* enable active counters */
 	for (i = 0; i < NUM_COUNTERS; ++i) {
 		int virt = op_x86_phys_to_virt(i);
-		if (!counter_config[virt].enabled)
+		if (!reset_value[virt])
 			continue;
 		rdmsrl(msrs->controls[i].addr, val);
 		val &= model->reserved;
@@ -107,10 +125,6 @@ static void op_mux_switch_ctrl(struct op
 	}
 }
 
-#else
-
-static inline void op_mux_fill_in_addresses(struct op_msrs * const msrs) { }
-
 #endif
 
 /* functions for op_amd_spec */
@@ -122,18 +136,12 @@ static void op_amd_fill_in_addresses(str
 	for (i = 0; i < NUM_COUNTERS; i++) {
 		if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i))
 			msrs->counters[i].addr = MSR_K7_PERFCTR0 + i;
-		else
-			msrs->counters[i].addr = 0;
 	}
 
 	for (i = 0; i < NUM_CONTROLS; i++) {
 		if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i))
 			msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i;
-		else
-			msrs->controls[i].addr = 0;
 	}
-
-	op_mux_fill_in_addresses(msrs);
 }
 
 static void op_amd_setup_ctrs(struct op_x86_model_spec const *model,
@@ -144,7 +152,8 @@ static void op_amd_setup_ctrs(struct op_
 
 	/* setup reset_value */
 	for (i = 0; i < NUM_VIRT_COUNTERS; ++i) {
-		if (counter_config[i].enabled)
+		if (counter_config[i].enabled
+		    && msrs->counters[op_x86_virt_to_phys(i)].addr)
 			reset_value[i] = counter_config[i].count;
 		else
 			reset_value[i] = 0;
@@ -152,9 +161,18 @@ static void op_amd_setup_ctrs(struct op_
 
 	/* clear all counters */
 	for (i = 0; i < NUM_CONTROLS; ++i) {
-		if (unlikely(!msrs->controls[i].addr))
+		if (unlikely(!msrs->controls[i].addr)) {
+			if (counter_config[i].enabled && !smp_processor_id())
+				/*
+				 * counter is reserved, this is on all
+				 * cpus, so report only for cpu #0
+				 */
+				op_x86_warn_reserved(i);
 			continue;
+		}
 		rdmsrl(msrs->controls[i].addr, val);
+		if (val & ARCH_PERFMON_EVENTSEL_ENABLE)
+			op_x86_warn_in_use(i);
 		val &= model->reserved;
 		wrmsrl(msrs->controls[i].addr, val);
 	}
@@ -169,9 +187,7 @@ static void op_amd_setup_ctrs(struct op_
 	/* enable active counters */
 	for (i = 0; i < NUM_COUNTERS; ++i) {
 		int virt = op_x86_phys_to_virt(i);
-		if (!counter_config[virt].enabled)
-			continue;
-		if (!msrs->counters[i].addr)
+		if (!reset_value[virt])
 			continue;
 
 		/* setup counter registers */
@@ -185,7 +201,60 @@ static void op_amd_setup_ctrs(struct op_
 	}
 }
 
-#ifdef CONFIG_OPROFILE_IBS
+/*
+ * 16-bit Linear Feedback Shift Register (LFSR)
+ *
+ *                       16   14   13    11
+ * Feedback polynomial = X  + X  + X  +  X  + 1
+ */
+static unsigned int lfsr_random(void)
+{
+	static unsigned int lfsr_value = 0xF00D;
+	unsigned int bit;
+
+	/* Compute next bit to shift in */
+	bit = ((lfsr_value >> 0) ^
+	       (lfsr_value >> 2) ^
+	       (lfsr_value >> 3) ^
+	       (lfsr_value >> 5)) & 0x0001;
+
+	/* Advance to next register value */
+	lfsr_value = (lfsr_value >> 1) | (bit << 15);
+
+	return lfsr_value;
+}
+
+/*
+ * IBS software randomization
+ *
+ * The IBS periodic op counter is randomized in software. The lower 12
+ * bits of the 20 bit counter are randomized. IbsOpCurCnt is
+ * initialized with a 12 bit random value.
+ */
+static inline u64 op_amd_randomize_ibs_op(u64 val)
+{
+	unsigned int random = lfsr_random();
+
+	if (!(ibs_caps & IBS_CAPS_RDWROPCNT))
+		/*
+		 * Work around if the hw can not write to IbsOpCurCnt
+		 *
+		 * Randomize the lower 8 bits of the 16 bit
+		 * IbsOpMaxCnt [15:0] value in the range of -128 to
+		 * +127 by adding/subtracting an offset to the
+		 * maximum count (IbsOpMaxCnt).
+		 *
+		 * To avoid over or underflows and protect upper bits
+		 * starting at bit 16, the initial value for
+		 * IbsOpMaxCnt must fit in the range from 0x0081 to
+		 * 0xff80.
+		 */
+		val += (s8)(random >> 4);
+	else
+		val |= (u64)(random & IBS_RANDOM_MASK) << 32;
+
+	return val;
+}
 
 static inline void
 op_amd_handle_ibs(struct pt_regs * const regs,
@@ -194,7 +263,7 @@ op_amd_handle_ibs(struct pt_regs * const
 	u64 val, ctl;
 	struct op_entry entry;
 
-	if (!has_ibs)
+	if (!ibs_caps)
 		return;
 
 	if (ibs_config.fetch_enabled) {
@@ -210,7 +279,7 @@ op_amd_handle_ibs(struct pt_regs * const
 			oprofile_write_commit(&entry);
 
 			/* reenable the IRQ */
-			ctl &= ~(IBS_FETCH_VAL | IBS_FETCH_CNT_MASK);
+			ctl &= ~(IBS_FETCH_VAL | IBS_FETCH_CNT);
 			ctl |= IBS_FETCH_ENABLE;
 			wrmsrl(MSR_AMD64_IBSFETCHCTL, ctl);
 		}
@@ -236,8 +305,7 @@ op_amd_handle_ibs(struct pt_regs * const
 			oprofile_write_commit(&entry);
 
 			/* reenable the IRQ */
-			ctl &= ~IBS_OP_VAL & 0xFFFFFFFF;
-			ctl |= IBS_OP_ENABLE;
+			ctl = op_amd_randomize_ibs_op(ibs_op_ctl);
 			wrmsrl(MSR_AMD64_IBSOPCTL, ctl);
 		}
 	}
@@ -246,41 +314,57 @@ op_amd_handle_ibs(struct pt_regs * const
 static inline void op_amd_start_ibs(void)
 {
 	u64 val;
-	if (has_ibs && ibs_config.fetch_enabled) {
-		val = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF;
+
+	if (!ibs_caps)
+		return;
+
+	if (ibs_config.fetch_enabled) {
+		val = (ibs_config.max_cnt_fetch >> 4) & IBS_FETCH_MAX_CNT;
 		val |= ibs_config.rand_en ? IBS_FETCH_RAND_EN : 0;
 		val |= IBS_FETCH_ENABLE;
 		wrmsrl(MSR_AMD64_IBSFETCHCTL, val);
 	}
 
-	if (has_ibs && ibs_config.op_enabled) {
-		val = (ibs_config.max_cnt_op >> 4) & 0xFFFF;
-		val |= ibs_config.dispatched_ops ? IBS_OP_CNT_CTL : 0;
-		val |= IBS_OP_ENABLE;
+	if (ibs_config.op_enabled) {
+		ibs_op_ctl = ibs_config.max_cnt_op >> 4;
+		if (!(ibs_caps & IBS_CAPS_RDWROPCNT)) {
+			/*
+			 * IbsOpCurCnt not supported.  See
+			 * op_amd_randomize_ibs_op() for details.
+			 */
+			ibs_op_ctl = clamp(ibs_op_ctl, 0x0081ULL, 0xFF80ULL);
+		} else {
+			/*
+			 * The start value is randomized with a
+			 * positive offset, we need to compensate it
+			 * with the half of the randomized range. Also
+			 * avoid underflows.
+			 */
+			ibs_op_ctl = min(ibs_op_ctl + IBS_RANDOM_MAXCNT_OFFSET,
+					 IBS_OP_MAX_CNT);
+		}
+		if (ibs_caps & IBS_CAPS_OPCNT && ibs_config.dispatched_ops)
+			ibs_op_ctl |= IBS_OP_CNT_CTL;
+		ibs_op_ctl |= IBS_OP_ENABLE;
+		val = op_amd_randomize_ibs_op(ibs_op_ctl);
 		wrmsrl(MSR_AMD64_IBSOPCTL, val);
 	}
 }
 
 static void op_amd_stop_ibs(void)
 {
-	if (has_ibs && ibs_config.fetch_enabled)
+	if (!ibs_caps)
+		return;
+
+	if (ibs_config.fetch_enabled)
 		/* clear max count and enable */
 		wrmsrl(MSR_AMD64_IBSFETCHCTL, 0);
 
-	if (has_ibs && ibs_config.op_enabled)
+	if (ibs_config.op_enabled)
 		/* clear max count and enable */
 		wrmsrl(MSR_AMD64_IBSOPCTL, 0);
 }
 
-#else
-
-static inline void op_amd_handle_ibs(struct pt_regs * const regs,
-				    struct op_msrs const * const msrs) { }
-static inline void op_amd_start_ibs(void) { }
-static inline void op_amd_stop_ibs(void) { }
-
-#endif
-
 static int op_amd_check_ctrs(struct pt_regs * const regs,
 			     struct op_msrs const * const msrs)
 {
@@ -314,7 +398,7 @@ static void op_amd_start(struct op_msrs
 		if (!reset_value[op_x86_phys_to_virt(i)])
 			continue;
 		rdmsrl(msrs->controls[i].addr, val);
-		val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+		val |= ARCH_PERFMON_EVENTSEL_ENABLE;
 		wrmsrl(msrs->controls[i].addr, val);
 	}
 
@@ -334,7 +418,7 @@ static void op_amd_stop(struct op_msrs c
 		if (!reset_value[op_x86_phys_to_virt(i)])
 			continue;
 		rdmsrl(msrs->controls[i].addr, val);
-		val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
+		val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
 		wrmsrl(msrs->controls[i].addr, val);
 	}
 
@@ -355,8 +439,6 @@ static void op_amd_shutdown(struct op_ms
 	}
 }
 
-#ifdef CONFIG_OPROFILE_IBS
-
 static u8 ibs_eilvt_off;
 
 static inline void apic_init_ibs_nmi_per_cpu(void *arg)
@@ -405,45 +487,36 @@ static int init_ibs_nmi(void)
 		return 1;
 	}
 
-#ifdef CONFIG_NUMA
-	/* Sanity check */
-	/* Works only for 64bit with proper numa implementation. */
-	if (nodes != num_possible_nodes()) {
-		printk(KERN_DEBUG "Failed to setup CPU node(s) for IBS, "
-			"found: %d, expected %d",
-			nodes, num_possible_nodes());
-		return 1;
-	}
-#endif
 	return 0;
 }
 
 /* uninitialize the APIC for the IBS interrupts if needed */
 static void clear_ibs_nmi(void)
 {
-	if (has_ibs)
+	if (ibs_caps)
 		on_each_cpu(apic_clear_ibs_nmi_per_cpu, NULL, 1);
 }
 
 /* initialize the APIC for the IBS interrupts if available */
 static void ibs_init(void)
 {
-	has_ibs = boot_cpu_has(X86_FEATURE_IBS);
+	ibs_caps = get_ibs_caps();
 
-	if (!has_ibs)
+	if (!ibs_caps)
 		return;
 
 	if (init_ibs_nmi()) {
-		has_ibs = 0;
+		ibs_caps = 0;
 		return;
 	}
 
-	printk(KERN_INFO "oprofile: AMD IBS detected\n");
+	printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n",
+	       (unsigned)ibs_caps);
 }
 
 static void ibs_exit(void)
 {
-	if (!has_ibs)
+	if (!ibs_caps)
 		return;
 
 	clear_ibs_nmi();
@@ -463,7 +536,7 @@ static int setup_ibs_files(struct super_
 	if (ret)
 		return ret;
 
-	if (!has_ibs)
+	if (!ibs_caps)
 		return ret;
 
 	/* model specific files */
@@ -473,7 +546,7 @@ static int setup_ibs_files(struct super_
 	ibs_config.fetch_enabled = 0;
 	ibs_config.max_cnt_op = 250000;
 	ibs_config.op_enabled = 0;
-	ibs_config.dispatched_ops = 1;
+	ibs_config.dispatched_ops = 0;
 
 	dir = oprofilefs_mkdir(sb, root, "ibs_fetch");
 	oprofilefs_create_ulong(sb, dir, "enable",
@@ -488,8 +561,9 @@ static int setup_ibs_files(struct super_
 				&ibs_config.op_enabled);
 	oprofilefs_create_ulong(sb, dir, "max_count",
 				&ibs_config.max_cnt_op);
-	oprofilefs_create_ulong(sb, dir, "dispatched_ops",
-				&ibs_config.dispatched_ops);
+	if (ibs_caps & IBS_CAPS_OPCNT)
+		oprofilefs_create_ulong(sb, dir, "dispatched_ops",
+					&ibs_config.dispatched_ops);
 
 	return 0;
 }
@@ -507,19 +581,6 @@ static void op_amd_exit(void)
 	ibs_exit();
 }
 
-#else
-
-/* no IBS support */
-
-static int op_amd_init(struct oprofile_operations *ops)
-{
-	return 0;
-}
-
-static void op_amd_exit(void) {}
-
-#endif /* CONFIG_OPROFILE_IBS */
-
 struct op_x86_model_spec op_amd_spec = {
 	.num_counters		= NUM_COUNTERS,
 	.num_controls		= NUM_CONTROLS,
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/oprofile/op_model_p4.c linux-libre-2.6.34-gnu1/arch/x86/oprofile/op_model_p4.c
--- linux-libre-2.6.33-gnu1/arch/x86/oprofile/op_model_p4.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/oprofile/op_model_p4.c	2010-05-16 17:17:36.000000000 -0400
@@ -394,12 +394,6 @@ static void p4_fill_in_addresses(struct
 	setup_num_counters();
 	stag = get_stagger();
 
-	/* initialize some registers */
-	for (i = 0; i < num_counters; ++i)
-		msrs->counters[i].addr = 0;
-	for (i = 0; i < num_controls; ++i)
-		msrs->controls[i].addr = 0;
-
 	/* the counter & cccr registers we pay attention to */
 	for (i = 0; i < num_counters; ++i) {
 		addr = p4_counters[VIRT_CTR(stag, i)].counter_address;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/oprofile/op_model_ppro.c linux-libre-2.6.34-gnu1/arch/x86/oprofile/op_model_ppro.c
--- linux-libre-2.6.33-gnu1/arch/x86/oprofile/op_model_ppro.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/oprofile/op_model_ppro.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,15 +37,11 @@ static void ppro_fill_in_addresses(struc
 	for (i = 0; i < num_counters; i++) {
 		if (reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i))
 			msrs->counters[i].addr = MSR_P6_PERFCTR0 + i;
-		else
-			msrs->counters[i].addr = 0;
 	}
 
 	for (i = 0; i < num_counters; i++) {
 		if (reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i))
 			msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i;
-		else
-			msrs->controls[i].addr = 0;
 	}
 }
 
@@ -57,7 +53,7 @@ static void ppro_setup_ctrs(struct op_x8
 	int i;
 
 	if (!reset_value) {
-		reset_value = kmalloc(sizeof(reset_value[0]) * num_counters,
+		reset_value = kzalloc(sizeof(reset_value[0]) * num_counters,
 					GFP_ATOMIC);
 		if (!reset_value)
 			return;
@@ -82,9 +78,18 @@ static void ppro_setup_ctrs(struct op_x8
 
 	/* clear all counters */
 	for (i = 0; i < num_counters; ++i) {
-		if (unlikely(!msrs->controls[i].addr))
+		if (unlikely(!msrs->controls[i].addr)) {
+			if (counter_config[i].enabled && !smp_processor_id())
+				/*
+				 * counter is reserved, this is on all
+				 * cpus, so report only for cpu #0
+				 */
+				op_x86_warn_reserved(i);
 			continue;
+		}
 		rdmsrl(msrs->controls[i].addr, val);
+		if (val & ARCH_PERFMON_EVENTSEL_ENABLE)
+			op_x86_warn_in_use(i);
 		val &= model->reserved;
 		wrmsrl(msrs->controls[i].addr, val);
 	}
@@ -161,7 +166,7 @@ static void ppro_start(struct op_msrs co
 	for (i = 0; i < num_counters; ++i) {
 		if (reset_value[i]) {
 			rdmsrl(msrs->controls[i].addr, val);
-			val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+			val |= ARCH_PERFMON_EVENTSEL_ENABLE;
 			wrmsrl(msrs->controls[i].addr, val);
 		}
 	}
@@ -179,7 +184,7 @@ static void ppro_stop(struct op_msrs con
 		if (!reset_value[i])
 			continue;
 		rdmsrl(msrs->controls[i].addr, val);
-		val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
+		val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
 		wrmsrl(msrs->controls[i].addr, val);
 	}
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/oprofile/op_x86_model.h linux-libre-2.6.34-gnu1/arch/x86/oprofile/op_x86_model.h
--- linux-libre-2.6.33-gnu1/arch/x86/oprofile/op_x86_model.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/oprofile/op_x86_model.h	2010-05-16 17:17:36.000000000 -0400
@@ -57,6 +57,26 @@ struct op_x86_model_spec {
 
 struct op_counter_config;
 
+static inline void op_x86_warn_in_use(int counter)
+{
+	/*
+	 * The warning indicates an already running counter. If
+	 * oprofile doesn't collect data, then try using a different
+	 * performance counter on your platform to monitor the desired
+	 * event. Delete counter #%d from the desired event by editing
+	 * the /usr/share/oprofile/%s/<cpu>/events file. If the event
+	 * cannot be monitored by any other counter, contact your
+	 * hardware or BIOS vendor.
+	 */
+	pr_warning("oprofile: counter #%d on cpu #%d may already be used\n",
+		   counter, smp_processor_id());
+}
+
+static inline void op_x86_warn_reserved(int counter)
+{
+	pr_warning("oprofile: counter #%d is already reserved\n", counter);
+}
+
 extern u64 op_x86_get_ctrl(struct op_x86_model_spec const *model,
 			   struct op_counter_config *counter_config);
 extern int op_x86_phys_to_virt(int phys);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/acpi.c linux-libre-2.6.34-gnu1/arch/x86/pci/acpi.c
--- linux-libre-2.6.33-gnu1/arch/x86/pci/acpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/acpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 #include <asm/numa.h>
 #include <asm/pci_x86.h>
 
@@ -15,19 +16,94 @@ struct pci_root_info {
 	int busnum;
 };
 
+static bool pci_use_crs = true;
+
+static int __init set_use_crs(const struct dmi_system_id *id)
+{
+	pci_use_crs = true;
+	return 0;
+}
+
+static const struct dmi_system_id pci_use_crs_table[] __initconst = {
+	/* http://bugzilla.kernel.org/show_bug.cgi?id=14183 */
+	{
+		.callback = set_use_crs,
+		.ident = "IBM System x3800",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
+		},
+	},
+	{}
+};
+
+void __init pci_acpi_crs_quirks(void)
+{
+	int year;
+
+	if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year < 2008)
+		pci_use_crs = false;
+
+	dmi_check_system(pci_use_crs_table);
+
+	/*
+	 * If the user specifies "pci=use_crs" or "pci=nocrs" explicitly, that
+	 * takes precedence over anything we figured out above.
+	 */
+	if (pci_probe & PCI_ROOT_NO_CRS)
+		pci_use_crs = false;
+	else if (pci_probe & PCI_USE__CRS)
+		pci_use_crs = true;
+
+	printk(KERN_INFO "PCI: %s host bridge windows from ACPI; "
+	       "if necessary, use \"pci=%s\" and report a bug\n",
+	       pci_use_crs ? "Using" : "Ignoring",
+	       pci_use_crs ? "nocrs" : "use_crs");
+}
+
 static acpi_status
 resource_to_addr(struct acpi_resource *resource,
 			struct acpi_resource_address64 *addr)
 {
 	acpi_status status;
+	struct acpi_resource_memory24 *memory24;
+	struct acpi_resource_memory32 *memory32;
+	struct acpi_resource_fixed_memory32 *fixed_memory32;
 
-	status = acpi_resource_to_address64(resource, addr);
-	if (ACPI_SUCCESS(status) &&
-	    (addr->resource_type == ACPI_MEMORY_RANGE ||
-	    addr->resource_type == ACPI_IO_RANGE) &&
-	    addr->address_length > 0 &&
-	    addr->producer_consumer == ACPI_PRODUCER) {
+	memset(addr, 0, sizeof(*addr));
+	switch (resource->type) {
+	case ACPI_RESOURCE_TYPE_MEMORY24:
+		memory24 = &resource->data.memory24;
+		addr->resource_type = ACPI_MEMORY_RANGE;
+		addr->minimum = memory24->minimum;
+		addr->address_length = memory24->address_length;
+		addr->maximum = addr->minimum + addr->address_length - 1;
 		return AE_OK;
+	case ACPI_RESOURCE_TYPE_MEMORY32:
+		memory32 = &resource->data.memory32;
+		addr->resource_type = ACPI_MEMORY_RANGE;
+		addr->minimum = memory32->minimum;
+		addr->address_length = memory32->address_length;
+		addr->maximum = addr->minimum + addr->address_length - 1;
+		return AE_OK;
+	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+		fixed_memory32 = &resource->data.fixed_memory32;
+		addr->resource_type = ACPI_MEMORY_RANGE;
+		addr->minimum = fixed_memory32->address;
+		addr->address_length = fixed_memory32->address_length;
+		addr->maximum = addr->minimum + addr->address_length - 1;
+		return AE_OK;
+	case ACPI_RESOURCE_TYPE_ADDRESS16:
+	case ACPI_RESOURCE_TYPE_ADDRESS32:
+	case ACPI_RESOURCE_TYPE_ADDRESS64:
+		status = acpi_resource_to_address64(resource, addr);
+		if (ACPI_SUCCESS(status) &&
+		    (addr->resource_type == ACPI_MEMORY_RANGE ||
+		    addr->resource_type == ACPI_IO_RANGE) &&
+		    addr->address_length > 0) {
+			return AE_OK;
+		}
+		break;
 	}
 	return AE_ERROR;
 }
@@ -45,44 +121,6 @@ count_resource(struct acpi_resource *acp
 	return AE_OK;
 }
 
-static int
-bus_has_transparent_bridge(struct pci_bus *bus)
-{
-	struct pci_dev *dev;
-
-	list_for_each_entry(dev, &bus->devices, bus_list) {
-		u16 class = dev->class >> 8;
-
-		if (class == PCI_CLASS_BRIDGE_PCI && dev->transparent)
-			return true;
-	}
-	return false;
-}
-
-static void
-align_resource(struct acpi_device *bridge, struct resource *res)
-{
-	int align = (res->flags & IORESOURCE_MEM) ? 16 : 4;
-
-	/*
-	 * Host bridge windows are not BARs, but the decoders on the PCI side
-	 * that claim this address space have starting alignment and length
-	 * constraints, so fix any obvious BIOS goofs.
-	 */
-	if (!IS_ALIGNED(res->start, align)) {
-		dev_printk(KERN_DEBUG, &bridge->dev,
-			   "host bridge window %pR invalid; "
-			   "aligning start to %d-byte boundary\n", res, align);
-		res->start &= ~(align - 1);
-	}
-	if (!IS_ALIGNED(res->end + 1, align)) {
-		dev_printk(KERN_DEBUG, &bridge->dev,
-			   "host bridge window %pR invalid; "
-			   "aligning end to %d-byte boundary\n", res, align);
-		res->end = ALIGN(res->end, align) - 1;
-	}
-}
-
 static acpi_status
 setup_resource(struct acpi_resource *acpi_res, void *data)
 {
@@ -91,13 +129,9 @@ setup_resource(struct acpi_resource *acp
 	struct acpi_resource_address64 addr;
 	acpi_status status;
 	unsigned long flags;
-	struct resource *root;
-	int max_root_bus_resources = PCI_BUS_NUM_RESOURCES;
+	struct resource *root, *conflict;
 	u64 start, end;
 
-	if (bus_has_transparent_bridge(info->bus))
-		max_root_bus_resources -= 3;
-
 	status = resource_to_addr(acpi_res, &addr);
 	if (!ACPI_SUCCESS(status))
 		return AE_OK;
@@ -114,16 +148,7 @@ setup_resource(struct acpi_resource *acp
 		return AE_OK;
 
 	start = addr.minimum + addr.translation_offset;
-	end = start + addr.address_length - 1;
-	if (info->res_num >= max_root_bus_resources) {
-		if (pci_probe & PCI_USE__CRS)
-			printk(KERN_WARNING "PCI: Failed to allocate "
-			       "0x%lx-0x%lx from %s for %s due to _CRS "
-			       "returning more than %d resource descriptors\n",
-			       (unsigned long) start, (unsigned long) end,
-			       root->name, info->name, max_root_bus_resources);
-		return AE_OK;
-	}
+	end = addr.maximum + addr.translation_offset;
 
 	res = &info->res[info->res_num];
 	res->name = info->name;
@@ -131,19 +156,21 @@ setup_resource(struct acpi_resource *acp
 	res->start = start;
 	res->end = end;
 	res->child = NULL;
-	align_resource(info->bridge, res);
 
-	if (!(pci_probe & PCI_USE__CRS)) {
+	if (!pci_use_crs) {
 		dev_printk(KERN_DEBUG, &info->bridge->dev,
 			   "host bridge window %pR (ignored)\n", res);
 		return AE_OK;
 	}
 
-	if (insert_resource(root, res)) {
+	conflict = insert_resource_conflict(root, res);
+	if (conflict) {
 		dev_err(&info->bridge->dev,
-			"can't allocate host bridge window %pR\n", res);
+			"address space collision: host bridge window %pR "
+			"conflicts with %s %pR\n",
+			res, conflict->name, conflict);
 	} else {
-		info->bus->resource[info->res_num] = res;
+		pci_bus_add_resource(info->bus, res, 0);
 		info->res_num++;
 		if (addr.translation_offset)
 			dev_info(&info->bridge->dev, "host bridge window %pR "
@@ -164,10 +191,8 @@ get_current_resources(struct acpi_device
 	struct pci_root_info info;
 	size_t size;
 
-	if (!(pci_probe & PCI_USE__CRS))
-		dev_info(&device->dev,
-			 "ignoring host bridge windows from ACPI; "
-			 "boot with \"pci=use_crs\" to use them\n");
+	if (pci_use_crs)
+		pci_bus_remove_resources(bus);
 
 	info.bridge = device;
 	info.bus = bus;
@@ -282,17 +307,14 @@ int __init pci_acpi_init(void)
 {
 	struct pci_dev *dev = NULL;
 
-	if (pcibios_scanned)
-		return 0;
-
 	if (acpi_noirq)
-		return 0;
+		return -ENODEV;
 
 	printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
 	acpi_irq_penalty_init();
-	pcibios_scanned++;
 	pcibios_enable_irq = acpi_pci_irq_enable;
 	pcibios_disable_irq = acpi_pci_irq_disable;
+	x86_init.pci.init_irq = x86_init_noop;
 
 	if (pci_routeirq) {
 		/*
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/amd_bus.c linux-libre-2.6.34-gnu1/arch/x86/pci/amd_bus.c
--- linux-libre-2.6.33-gnu1/arch/x86/pci/amd_bus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/amd_bus.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,11 +2,11 @@
 #include <linux/pci.h>
 #include <linux/topology.h>
 #include <linux/cpu.h>
+#include <linux/range.h>
+
 #include <asm/pci_x86.h>
 
-#ifdef CONFIG_X86_64
 #include <asm/pci-direct.h>
-#endif
 
 #include "bus_numa.h"
 
@@ -15,60 +15,6 @@
  * also get peer root bus resource for io,mmio
  */
 
-#ifdef CONFIG_X86_64
-
-#define RANGE_NUM 16
-
-struct res_range {
-	size_t start;
-	size_t end;
-};
-
-static void __init update_range(struct res_range *range, size_t start,
-				size_t end)
-{
-	int i;
-	int 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;
-		}
-	}
-}
-
 struct pci_hostbridge_probe {
 	u32 bus;
 	u32 slot;
@@ -111,6 +57,8 @@ static void __init get_pci_mmcfg_amd_fam
 	fam10h_mmconf_end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
 }
 
+#define RANGE_NUM 16
+
 /**
  * early_fill_mp_bus_to_node()
  * called before pcibios_scan_root and pci_scan_bus
@@ -130,16 +78,17 @@ static int __init early_fill_mp_bus_info
 	struct pci_root_info *info;
 	u32 reg;
 	struct resource *res;
-	size_t start;
-	size_t end;
-	struct res_range range[RANGE_NUM];
+	u64 start;
+	u64 end;
+	struct range range[RANGE_NUM];
 	u64 val;
 	u32 address;
+	bool found;
 
 	if (!early_pci_allowed())
 		return -1;
 
-	found_all_numa_early = 0;
+	found = false;
 	for (i = 0; i < ARRAY_SIZE(pci_probes); i++) {
 		u32 id;
 		u16 device;
@@ -153,12 +102,12 @@ static int __init early_fill_mp_bus_info
 		device = (id>>16) & 0xffff;
 		if (pci_probes[i].vendor == vendor &&
 		    pci_probes[i].device == device) {
-			found_all_numa_early = 1;
+			found = true;
 			break;
 		}
 	}
 
-	if (!found_all_numa_early)
+	if (!found)
 		return 0;
 
 	pci_root_num = 0;
@@ -196,7 +145,7 @@ static int __init early_fill_mp_bus_info
 	def_link = (reg >> 8) & 0x03;
 
 	memset(range, 0, sizeof(range));
-	range[0].end = 0xffff;
+	add_range(range, RANGE_NUM, 0, 0, 0xffff + 1);
 	/* io port resource */
 	for (i = 0; i < 4; i++) {
 		reg = read_pci_config(bus, slot, 1, 0xc0 + (i << 3));
@@ -220,13 +169,13 @@ static int __init early_fill_mp_bus_info
 
 		info = &pci_root_info[j];
 		printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n",
-		       node, link, (u64)start, (u64)end);
+		       node, link, start, end);
 
 		/* kernel only handle 16 bit only */
 		if (end > 0xffff)
 			end = 0xffff;
 		update_res(info, start, end, IORESOURCE_IO, 1);
-		update_range(range, start, end);
+		subtract_range(range, RANGE_NUM, start, end + 1);
 	}
 	/* add left over io port range to def node/link, [0, 0xffff] */
 	/* find the position */
@@ -241,29 +190,32 @@ static int __init early_fill_mp_bus_info
 			if (!range[i].end)
 				continue;
 
-			update_res(info, range[i].start, range[i].end,
+			update_res(info, range[i].start, range[i].end - 1,
 				   IORESOURCE_IO, 1);
 		}
 	}
 
 	memset(range, 0, sizeof(range));
 	/* 0xfd00000000-0xffffffffff for HT */
-	range[0].end = (0xfdULL<<32) - 1;
+	end = cap_resource((0xfdULL<<32) - 1);
+	end++;
+	add_range(range, RANGE_NUM, 0, 0, end);
 
 	/* need to take out [0, TOM) for RAM*/
 	address = MSR_K8_TOP_MEM1;
 	rdmsrl(address, val);
 	end = (val & 0xffffff800000ULL);
-	printk(KERN_INFO "TOM: %016lx aka %ldM\n", end, end>>20);
+	printk(KERN_INFO "TOM: %016llx aka %lldM\n", end, end>>20);
 	if (end < (1ULL<<32))
-		update_range(range, 0, end - 1);
+		subtract_range(range, RANGE_NUM, 0, end);
 
 	/* get mmconfig */
 	get_pci_mmcfg_amd_fam10h_range();
 	/* need to take out mmconf range */
 	if (fam10h_mmconf_end) {
 		printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", fam10h_mmconf_start, fam10h_mmconf_end);
-		update_range(range, fam10h_mmconf_start, fam10h_mmconf_end);
+		subtract_range(range, RANGE_NUM, fam10h_mmconf_start,
+				 fam10h_mmconf_end + 1);
 	}
 
 	/* mmio resource */
@@ -293,7 +245,7 @@ static int __init early_fill_mp_bus_info
 		info = &pci_root_info[j];
 
 		printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]",
-		       node, link, (u64)start, (u64)end);
+		       node, link, start, end);
 		/*
 		 * some sick allocation would have range overlap with fam10h
 		 * mmconf range, so need to update start and end.
@@ -318,14 +270,15 @@ static int __init early_fill_mp_bus_info
 				/* we got a hole */
 				endx = fam10h_mmconf_start - 1;
 				update_res(info, start, endx, IORESOURCE_MEM, 0);
-				update_range(range, start, endx);
-				printk(KERN_CONT " ==> [%llx, %llx]", (u64)start, endx);
+				subtract_range(range, RANGE_NUM, start,
+						 endx + 1);
+				printk(KERN_CONT " ==> [%llx, %llx]", start, endx);
 				start = fam10h_mmconf_end + 1;
 				changed = 1;
 			}
 			if (changed) {
 				if (start <= end) {
-					printk(KERN_CONT " %s [%llx, %llx]", endx?"and":"==>", (u64)start, (u64)end);
+					printk(KERN_CONT " %s [%llx, %llx]", endx ? "and" : "==>", start, end);
 				} else {
 					printk(KERN_CONT "%s\n", endx?"":" ==> none");
 					continue;
@@ -333,8 +286,9 @@ static int __init early_fill_mp_bus_info
 			}
 		}
 
-		update_res(info, start, end, IORESOURCE_MEM, 1);
-		update_range(range, start, end);
+		update_res(info, cap_resource(start), cap_resource(end),
+				 IORESOURCE_MEM, 1);
+		subtract_range(range, RANGE_NUM, start, end + 1);
 		printk(KERN_CONT "\n");
 	}
 
@@ -348,8 +302,8 @@ static int __init early_fill_mp_bus_info
 		address = MSR_K8_TOP_MEM2;
 		rdmsrl(address, val);
 		end = (val & 0xffffff800000ULL);
-		printk(KERN_INFO "TOM2: %016lx aka %ldM\n", end, end>>20);
-		update_range(range, 1ULL<<32, end - 1);
+		printk(KERN_INFO "TOM2: %016llx aka %lldM\n", end, end>>20);
+		subtract_range(range, RANGE_NUM, 1ULL<<32, end);
 	}
 
 	/*
@@ -368,7 +322,8 @@ static int __init early_fill_mp_bus_info
 			if (!range[i].end)
 				continue;
 
-			update_res(info, range[i].start, range[i].end,
+			update_res(info, cap_resource(range[i].start),
+				   cap_resource(range[i].end - 1),
 				   IORESOURCE_MEM, 1);
 		}
 	}
@@ -384,24 +339,14 @@ static int __init early_fill_mp_bus_info
 		       info->bus_min, info->bus_max, info->node, info->link);
 		for (j = 0; j < res_num; j++) {
 			res = &info->res[j];
-			printk(KERN_DEBUG "bus: %02x index %x %s: [%llx, %llx]\n",
-			       busnum, j,
-			       (res->flags & IORESOURCE_IO)?"io port":"mmio",
-			       res->start, res->end);
+			printk(KERN_DEBUG "bus: %02x index %x %pR\n",
+				       busnum, j, res);
 		}
 	}
 
 	return 0;
 }
 
-#else  /* !CONFIG_X86_64 */
-
-static int __init early_fill_mp_bus_info(void) { return 0; }
-
-#endif /* !CONFIG_X86_64 */
-
-/* common 32/64 bit code */
-
 #define ENABLE_CF8_EXT_CFG      (1ULL << 46)
 
 static void enable_pci_io_ecs(void *unused)
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/bus_numa.c linux-libre-2.6.34-gnu1/arch/x86/pci/bus_numa.c
--- linux-libre-2.6.33-gnu1/arch/x86/pci/bus_numa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/bus_numa.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,11 +1,11 @@
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/range.h>
 
 #include "bus_numa.h"
 
 int pci_root_num;
 struct pci_root_info pci_root_info[PCI_ROOT_NR];
-int found_all_numa_early;
 
 void x86_pci_root_bus_res_quirks(struct pci_bus *b)
 {
@@ -21,10 +21,6 @@ void x86_pci_root_bus_res_quirks(struct
 	if (!pci_root_num)
 		return;
 
-	/* for amd, if only one root bus, don't need to do anything */
-	if (pci_root_num < 2 && found_all_numa_early)
-		return;
-
 	for (i = 0; i < pci_root_num; i++) {
 		if (pci_root_info[i].bus_min == b->number)
 			break;
@@ -36,13 +32,14 @@ void x86_pci_root_bus_res_quirks(struct
 	printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n",
 			b->number);
 
+	pci_bus_remove_resources(b);
 	info = &pci_root_info[i];
 	for (j = 0; j < info->res_num; j++) {
 		struct resource *res;
 		struct resource *root;
 
 		res = &info->res[j];
-		b->resource[j] = res;
+		pci_bus_add_resource(b, res, 0);
 		if (res->flags & IORESOURCE_IO)
 			root = &ioport_resource;
 		else
@@ -51,8 +48,8 @@ void x86_pci_root_bus_res_quirks(struct
 	}
 }
 
-void __devinit update_res(struct pci_root_info *info, size_t start,
-			      size_t end, unsigned long flags, int merge)
+void __devinit update_res(struct pci_root_info *info, resource_size_t start,
+			  resource_size_t end, unsigned long flags, int merge)
 {
 	int i;
 	struct resource *res;
@@ -60,25 +57,28 @@ void __devinit update_res(struct pci_roo
 	if (start > end)
 		return;
 
+	if (start == MAX_RESOURCE)
+		return;
+
 	if (!merge)
 		goto addit;
 
 	/* try to merge it with old one */
 	for (i = 0; i < info->res_num; i++) {
-		size_t final_start, final_end;
-		size_t common_start, common_end;
+		resource_size_t final_start, final_end;
+		resource_size_t common_start, common_end;
 
 		res = &info->res[i];
 		if (res->flags != flags)
 			continue;
 
-		common_start = max((size_t)res->start, start);
-		common_end = min((size_t)res->end, end);
+		common_start = max(res->start, start);
+		common_end = min(res->end, end);
 		if (common_start > common_end + 1)
 			continue;
 
-		final_start = min((size_t)res->start, start);
-		final_end = max((size_t)res->end, end);
+		final_start = min(res->start, start);
+		final_end = max(res->end, end);
 
 		res->start = final_start;
 		res->end = final_end;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/bus_numa.h linux-libre-2.6.34-gnu1/arch/x86/pci/bus_numa.h
--- linux-libre-2.6.33-gnu1/arch/x86/pci/bus_numa.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/bus_numa.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,9 +1,8 @@
-#ifdef CONFIG_X86_64
-
+#ifndef __BUS_NUMA_H
+#define __BUS_NUMA_H
 /*
  * sub bus (transparent) will use entres from 3 to store extra from
- * root, so need to make sure we have enough slot there, Should we
- * increase PCI_BUS_NUM_RESOURCES?
+ * root, so need to make sure we have enough slot there.
  */
 #define RES_NUM 16
 struct pci_root_info {
@@ -20,8 +19,7 @@ struct pci_root_info {
 #define PCI_ROOT_NR 4
 extern int pci_root_num;
 extern struct pci_root_info pci_root_info[PCI_ROOT_NR];
-extern int found_all_numa_early;
 
-extern void update_res(struct pci_root_info *info, size_t start,
-			      size_t end, unsigned long flags, int merge);
+extern void update_res(struct pci_root_info *info, resource_size_t start,
+		      resource_size_t end, unsigned long flags, int merge);
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/common.c linux-libre-2.6.34-gnu1/arch/x86/pci/common.c
--- linux-libre-2.6.33-gnu1/arch/x86/pci/common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/common.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 
 #include <asm/acpi.h>
 #include <asm/segment.h>
@@ -72,12 +73,6 @@ struct pci_ops pci_root_ops = {
 };
 
 /*
- * legacy, numa, and acpi all want to call pcibios_scan_root
- * from their initcalls. This flag prevents that.
- */
-int pcibios_scanned;
-
-/*
  * This interrupt-safe spinlock protects all accesses to PCI
  * configuration space.
  */
@@ -520,6 +515,9 @@ char * __devinit  pcibios_setup(char *st
 	} else if (!strcmp(str, "use_crs")) {
 		pci_probe |= PCI_USE__CRS;
 		return NULL;
+	} else if (!strcmp(str, "nocrs")) {
+		pci_probe |= PCI_ROOT_NO_CRS;
+		return NULL;
 	} else if (!strcmp(str, "earlydump")) {
 		pci_early_dump_regs = 1;
 		return NULL;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/i386.c linux-libre-2.6.34-gnu1/arch/x86/pci/i386.c
--- linux-libre-2.6.33-gnu1/arch/x86/pci/i386.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/i386.c	2010-05-16 17:17:36.000000000 -0400
@@ -60,22 +60,23 @@ skip_isa_ioresource_align(struct pci_dev
  * but we want to try to avoid allocating at 0x2900-0x2bff
  * which might have be mirrored at 0x0100-0x03ff..
  */
-void
-pcibios_align_resource(void *data, struct resource *res,
+resource_size_t
+pcibios_align_resource(void *data, const struct resource *res,
 			resource_size_t size, resource_size_t align)
 {
 	struct pci_dev *dev = data;
+	resource_size_t start = res->start;
 
 	if (res->flags & IORESOURCE_IO) {
-		resource_size_t start = res->start;
-
 		if (skip_isa_ioresource_align(dev))
-			return;
-		if (start & 0x300) {
+			return start;
+		if (start & 0x300)
 			start = (start + 0x3ff) & ~0x3ff;
-			res->start = start;
-		}
+	} else if (res->flags & IORESOURCE_MEM) {
+		if (start < BIOS_END)
+			start = BIOS_END;
 	}
+	return start;
 }
 EXPORT_SYMBOL(pcibios_align_resource);
 
@@ -129,9 +130,6 @@ static void __init pcibios_allocate_bus_
 					continue;
 				if (!r->start ||
 				    pci_claim_resource(dev, idx) < 0) {
-					dev_info(&dev->dev,
-						 "can't reserve window %pR\n",
-						 r);
 					/*
 					 * Something is wrong with the region.
 					 * Invalidate the resource to prevent
@@ -183,8 +181,6 @@ static void __init pcibios_allocate_reso
 					"BAR %d: reserving %pr (d=%d, p=%d)\n",
 					idx, r, disabled, pass);
 				if (pci_claim_resource(dev, idx) < 0) {
-					dev_info(&dev->dev,
-						 "can't reserve %pR\n", r);
 					/* We'll assign a new address later */
 					r->end -= r->start;
 					r->start = 0;
@@ -257,10 +253,6 @@ 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.
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/init.c linux-libre-2.6.34-gnu1/arch/x86/pci/init.c
--- linux-libre-2.6.33-gnu1/arch/x86/pci/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <asm/pci_x86.h>
+#include <asm/x86_init.h>
 
 /* arch_initcall has too random ordering, so call the initializers
    in the right sequence from here. */
@@ -15,10 +16,9 @@ static __init int pci_arch_init(void)
 	if (!(pci_probe & PCI_PROBE_NOEARLY))
 		pci_mmcfg_early_init();
 
-#ifdef CONFIG_PCI_OLPC
-	if (!pci_olpc_init())
-		return 0;	/* skip additional checks if it's an XO */
-#endif
+	if (x86_init.pci.arch_init && !x86_init.pci.arch_init())
+		return 0;
+
 #ifdef CONFIG_PCI_BIOS
 	pci_pcbios_init();
 #endif
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/irq.c linux-libre-2.6.34-gnu1/arch/x86/pci/irq.c
--- linux-libre-2.6.33-gnu1/arch/x86/pci/irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,6 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/dmi.h>
 #include <linux/io.h>
@@ -53,7 +52,7 @@ struct irq_router_handler {
 	int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device);
 };
 
-int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
+int (*pcibios_enable_irq)(struct pci_dev *dev) = pirq_enable_irq;
 void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL;
 
 /*
@@ -590,6 +589,8 @@ static __init int intel_router_probe(str
 	case PCI_DEVICE_ID_INTEL_ICH10_1:
 	case PCI_DEVICE_ID_INTEL_ICH10_2:
 	case PCI_DEVICE_ID_INTEL_ICH10_3:
+	case PCI_DEVICE_ID_INTEL_CPT_LPC1:
+	case PCI_DEVICE_ID_INTEL_CPT_LPC2:
 		r->name = "PIIX/ICH";
 		r->get = pirq_piix_get;
 		r->set = pirq_piix_set;
@@ -1016,7 +1017,7 @@ static int pcibios_lookup_irq(struct pci
 	return 1;
 }
 
-static void __init pcibios_fixup_irqs(void)
+void __init pcibios_fixup_irqs(void)
 {
 	struct pci_dev *dev = NULL;
 	u8 pin;
@@ -1110,12 +1111,12 @@ static struct dmi_system_id __initdata p
 	{ }
 };
 
-int __init pcibios_irq_init(void)
+void __init pcibios_irq_init(void)
 {
 	DBG(KERN_DEBUG "PCI: IRQ init\n");
 
-	if (pcibios_enable_irq || raw_pci_ops == NULL)
-		return 0;
+	if (raw_pci_ops == NULL)
+		return;
 
 	dmi_check_system(pciirq_dmi_table);
 
@@ -1142,9 +1143,7 @@ int __init pcibios_irq_init(void)
 			pirq_table = NULL;
 	}
 
-	pcibios_enable_irq = pirq_enable_irq;
-
-	pcibios_fixup_irqs();
+	x86_init.pci.fixup_irqs();
 
 	if (io_apic_assign_pci_irqs && pci_routeirq) {
 		struct pci_dev *dev = NULL;
@@ -1157,8 +1156,6 @@ int __init pcibios_irq_init(void)
 		for_each_pci_dev(dev)
 			pirq_enable_irq(dev);
 	}
-
-	return 0;
 }
 
 static void pirq_penalize_isa_irq(int irq, int active)
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/legacy.c linux-libre-2.6.34-gnu1/arch/x86/pci/legacy.c
--- linux-libre-2.6.33-gnu1/arch/x86/pci/legacy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/legacy.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,16 +35,13 @@ static void __devinit pcibios_fixup_peer
 	}
 }
 
-static int __init pci_legacy_init(void)
+int __init pci_legacy_init(void)
 {
 	if (!raw_pci_ops) {
 		printk("PCI: System does not support PCI\n");
 		return 0;
 	}
 
-	if (pcibios_scanned++)
-		return 0;
-
 	printk("PCI: Probing PCI hardware\n");
 	pci_root_bus = pcibios_scan_root(0);
 	if (pci_root_bus)
@@ -55,18 +52,15 @@ static int __init pci_legacy_init(void)
 
 int __init pci_subsys_init(void)
 {
-#ifdef CONFIG_X86_NUMAQ
-	pci_numaq_init();
-#endif
-#ifdef CONFIG_ACPI
-	pci_acpi_init();
-#endif
-#ifdef CONFIG_X86_VISWS
-	pci_visws_init();
-#endif
-	pci_legacy_init();
+	/*
+	 * The init function returns an non zero value when
+	 * pci_legacy_init should be invoked.
+	 */
+	if (x86_init.pci.init())
+		pci_legacy_init();
+
 	pcibios_fixup_peer_bridges();
-	pcibios_irq_init();
+	x86_init.pci.init_irq();
 	pcibios_init();
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/Makefile linux-libre-2.6.34-gnu1/arch/x86/pci/Makefile
--- linux-libre-2.6.33-gnu1/arch/x86/pci/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -13,9 +13,10 @@ obj-$(CONFIG_X86_VISWS)		+= visws.o
 
 obj-$(CONFIG_X86_NUMAQ)		+= numaq_32.o
 
+obj-$(CONFIG_X86_MRST)		+= mrst.o
+
 obj-y				+= common.o early.o
-obj-y				+= amd_bus.o
-obj-$(CONFIG_X86_64)		+= bus_numa.o
+obj-y				+= amd_bus.o bus_numa.o
 
 ifeq ($(CONFIG_PCI_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/mmconfig-shared.c linux-libre-2.6.34-gnu1/arch/x86/pci/mmconfig-shared.c
--- linux-libre-2.6.33-gnu1/arch/x86/pci/mmconfig-shared.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/mmconfig-shared.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/sfi_acpi.h>
 #include <linux/bitmap.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 #include <asm/acpi.h>
@@ -303,22 +304,17 @@ static void __init pci_mmcfg_check_end_b
 {
 	struct pci_mmcfg_region *cfg, *cfgx;
 
-	/* last one*/
-	cfg = list_entry(pci_mmcfg_list.prev, typeof(*cfg), list);
-	if (cfg)
-		if (cfg->end_bus < cfg->start_bus)
-			cfg->end_bus = 255;
-
-	if (list_is_singular(&pci_mmcfg_list))
-		return;
-
-	/* don't overlap please */
+	/* Fixup overlaps */
 	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
 		if (cfg->end_bus < cfg->start_bus)
 			cfg->end_bus = 255;
 
+		/* Don't access the list head ! */
+		if (cfg->list.next == &pci_mmcfg_list)
+			break;
+
 		cfgx = list_entry(cfg->list.next, typeof(*cfg), list);
-		if (cfg != cfgx && cfg->end_bus >= cfgx->start_bus)
+		if (cfg->end_bus >= cfgx->start_bus)
 			cfg->end_bus = cfgx->start_bus - 1;
 	}
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/mrst.c linux-libre-2.6.34-gnu1/arch/x86/pci/mrst.c
--- linux-libre-2.6.33-gnu1/arch/x86/pci/mrst.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/mrst.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,266 @@
+/*
+ * Moorestown PCI support
+ *   Copyright (c) 2008 Intel Corporation
+ *     Jesse Barnes <jesse.barnes@intel.com>
+ *
+ * Moorestown has an interesting PCI implementation:
+ *   - configuration space is memory mapped (as defined by MCFG)
+ *   - Lincroft devices also have a real, type 1 configuration space
+ *   - Early Lincroft silicon has a type 1 access bug that will cause
+ *     a hang if non-existent devices are accessed
+ *   - some devices have the "fixed BAR" capability, which means
+ *     they can't be relocated or modified; check for that during
+ *     BAR sizing
+ *
+ * So, we use the MCFG space for all reads and writes, but also send
+ * Lincroft writes to type 1 space.  But only read/write if the device
+ * actually exists, otherwise return all 1s for reads and bit bucket
+ * the writes.
+ */
+
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/dmi.h>
+
+#include <asm/acpi.h>
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/pci_x86.h>
+#include <asm/hw_irq.h>
+#include <asm/io_apic.h>
+
+#define PCIE_CAP_OFFSET	0x100
+
+/* Fixed BAR fields */
+#define PCIE_VNDR_CAP_ID_FIXED_BAR 0x00	/* Fixed BAR (TBD) */
+#define PCI_FIXED_BAR_0_SIZE	0x04
+#define PCI_FIXED_BAR_1_SIZE	0x08
+#define PCI_FIXED_BAR_2_SIZE	0x0c
+#define PCI_FIXED_BAR_3_SIZE	0x10
+#define PCI_FIXED_BAR_4_SIZE	0x14
+#define PCI_FIXED_BAR_5_SIZE	0x1c
+
+/**
+ * fixed_bar_cap - return the offset of the fixed BAR cap if found
+ * @bus: PCI bus
+ * @devfn: device in question
+ *
+ * Look for the fixed BAR cap on @bus and @devfn, returning its offset
+ * if found or 0 otherwise.
+ */
+static int fixed_bar_cap(struct pci_bus *bus, unsigned int devfn)
+{
+	int pos;
+	u32 pcie_cap = 0, cap_data;
+
+	pos = PCIE_CAP_OFFSET;
+
+	if (!raw_pci_ext_ops)
+		return 0;
+
+	while (pos) {
+		if (raw_pci_ext_ops->read(pci_domain_nr(bus), bus->number,
+					  devfn, pos, 4, &pcie_cap))
+			return 0;
+
+		if (pcie_cap == 0xffffffff)
+			return 0;
+
+		if (PCI_EXT_CAP_ID(pcie_cap) == PCI_EXT_CAP_ID_VNDR) {
+			raw_pci_ext_ops->read(pci_domain_nr(bus), bus->number,
+					      devfn, pos + 4, 4, &cap_data);
+			if ((cap_data & 0xffff) == PCIE_VNDR_CAP_ID_FIXED_BAR)
+				return pos;
+		}
+
+		pos = pcie_cap >> 20;
+	}
+
+	return 0;
+}
+
+static int pci_device_update_fixed(struct pci_bus *bus, unsigned int devfn,
+				   int reg, int len, u32 val, int offset)
+{
+	u32 size;
+	unsigned int domain, busnum;
+	int bar = (reg - PCI_BASE_ADDRESS_0) >> 2;
+
+	domain = pci_domain_nr(bus);
+	busnum = bus->number;
+
+	if (val == ~0 && len == 4) {
+		unsigned long decode;
+
+		raw_pci_ext_ops->read(domain, busnum, devfn,
+			       offset + 8 + (bar * 4), 4, &size);
+
+		/* Turn the size into a decode pattern for the sizing code */
+		if (size) {
+			decode = size - 1;
+			decode |= decode >> 1;
+			decode |= decode >> 2;
+			decode |= decode >> 4;
+			decode |= decode >> 8;
+			decode |= decode >> 16;
+			decode++;
+			decode = ~(decode - 1);
+		} else {
+			decode = ~0;
+		}
+
+		/*
+		 * If val is all ones, the core code is trying to size the reg,
+		 * so update the mmconfig space with the real size.
+		 *
+		 * Note: this assumes the fixed size we got is a power of two.
+		 */
+		return raw_pci_ext_ops->write(domain, busnum, devfn, reg, 4,
+				       decode);
+	}
+
+	/* This is some other kind of BAR write, so just do it. */
+	return raw_pci_ext_ops->write(domain, busnum, devfn, reg, len, val);
+}
+
+/**
+ * type1_access_ok - check whether to use type 1
+ * @bus: bus number
+ * @devfn: device & function in question
+ *
+ * If the bus is on a Lincroft chip and it exists, or is not on a Lincroft at
+ * all, the we can go ahead with any reads & writes.  If it's on a Lincroft,
+ * but doesn't exist, avoid the access altogether to keep the chip from
+ * hanging.
+ */
+static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg)
+{
+	/* This is a workaround for A0 LNC bug where PCI status register does
+	 * not have new CAP bit set. can not be written by SW either.
+	 *
+	 * PCI header type in real LNC indicates a single function device, this
+	 * will prevent probing other devices under the same function in PCI
+	 * shim. Therefore, use the header type in shim instead.
+	 */
+	if (reg >= 0x100 || reg == PCI_STATUS || reg == PCI_HEADER_TYPE)
+		return 0;
+	if (bus == 0 && (devfn == PCI_DEVFN(2, 0) || devfn == PCI_DEVFN(0, 0)))
+		return 1;
+	return 0; /* langwell on others */
+}
+
+static int pci_read(struct pci_bus *bus, unsigned int devfn, int where,
+		    int size, u32 *value)
+{
+	if (type1_access_ok(bus->number, devfn, where))
+		return pci_direct_conf1.read(pci_domain_nr(bus), bus->number,
+					devfn, where, size, value);
+	return raw_pci_ext_ops->read(pci_domain_nr(bus), bus->number,
+			      devfn, where, size, value);
+}
+
+static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
+		     int size, u32 value)
+{
+	int offset;
+
+	/* On MRST, there is no PCI ROM BAR, this will cause a subsequent read
+	 * to ROM BAR return 0 then being ignored.
+	 */
+	if (where == PCI_ROM_ADDRESS)
+		return 0;
+
+	/*
+	 * Devices with fixed BARs need special handling:
+	 *   - BAR sizing code will save, write ~0, read size, restore
+	 *   - so writes to fixed BARs need special handling
+	 *   - other writes to fixed BAR devices should go through mmconfig
+	 */
+	offset = fixed_bar_cap(bus, devfn);
+	if (offset &&
+	    (where >= PCI_BASE_ADDRESS_0 && where <= PCI_BASE_ADDRESS_5)) {
+		return pci_device_update_fixed(bus, devfn, where, size, value,
+					       offset);
+	}
+
+	/*
+	 * On Moorestown update both real & mmconfig space
+	 * Note: early Lincroft silicon can't handle type 1 accesses to
+	 *       non-existent devices, so just eat the write in that case.
+	 */
+	if (type1_access_ok(bus->number, devfn, where))
+		return pci_direct_conf1.write(pci_domain_nr(bus), bus->number,
+					      devfn, where, size, value);
+	return raw_pci_ext_ops->write(pci_domain_nr(bus), bus->number, devfn,
+			       where, size, value);
+}
+
+static int mrst_pci_irq_enable(struct pci_dev *dev)
+{
+	u8 pin;
+	struct io_apic_irq_attr irq_attr;
+
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+
+	/* MRST only have IOAPIC, the PCI irq lines are 1:1 mapped to
+	 * IOAPIC RTE entries, so we just enable RTE for the device.
+	 */
+	irq_attr.ioapic = mp_find_ioapic(dev->irq);
+	irq_attr.ioapic_pin = dev->irq;
+	irq_attr.trigger = 1; /* level */
+	irq_attr.polarity = 1; /* active low */
+	io_apic_set_pci_routing(&dev->dev, dev->irq, &irq_attr);
+
+	return 0;
+}
+
+struct pci_ops pci_mrst_ops = {
+	.read = pci_read,
+	.write = pci_write,
+};
+
+/**
+ * pci_mrst_init - installs pci_mrst_ops
+ *
+ * Moorestown has an interesting PCI implementation (see above).
+ * Called when the early platform detection installs it.
+ */
+int __init pci_mrst_init(void)
+{
+	printk(KERN_INFO "Moorestown platform detected, using MRST PCI ops\n");
+	pci_mmcfg_late_init();
+	pcibios_enable_irq = mrst_pci_irq_enable;
+	pci_root_ops = pci_mrst_ops;
+	/* Continue with standard init */
+	return 1;
+}
+
+/*
+ * Langwell devices reside at fixed offsets, don't try to move them.
+ */
+static void __devinit pci_fixed_bar_fixup(struct pci_dev *dev)
+{
+	unsigned long offset;
+	u32 size;
+	int i;
+
+	/* Must have extended configuration space */
+	if (dev->cfg_size < PCIE_CAP_OFFSET + 4)
+		return;
+
+	/* Fixup the BAR sizes for fixed BAR devices and make them unmoveable */
+	offset = fixed_bar_cap(dev->bus, dev->devfn);
+	if (!offset || PCI_DEVFN(2, 0) == dev->devfn ||
+	    PCI_DEVFN(2, 2) == dev->devfn)
+		return;
+
+	for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+		pci_read_config_dword(dev, offset + 8 + (i * 4), &size);
+		dev->resource[i].end = dev->resource[i].start + size - 1;
+		dev->resource[i].flags |= IORESOURCE_PCI_FIXED;
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixed_bar_fixup);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/numaq_32.c linux-libre-2.6.34-gnu1/arch/x86/pci/numaq_32.c
--- linux-libre-2.6.33-gnu1/arch/x86/pci/numaq_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/numaq_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,9 +8,7 @@
 #include <asm/apic.h>
 #include <asm/mpspec.h>
 #include <asm/pci_x86.h>
-
-#define XQUAD_PORTIO_BASE 0xfe400000
-#define XQUAD_PORTIO_QUAD 0x40000  /* 256k per quad. */
+#include <asm/numaq.h>
 
 #define BUS2QUAD(global) (mp_bus_id_to_node[global])
 
@@ -18,8 +16,6 @@
 
 #define QUADLOCAL2BUS(quad,local) (quad_local_to_mp_bus_id[quad][local])
 
-#define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port)
-
 #define PCI_CONF1_MQ_ADDRESS(bus, devfn, reg) \
 	(0x80000000 | (BUS2LOCAL(bus) << 16) | (devfn << 8) | (reg & ~3))
 
@@ -152,14 +148,8 @@ int __init pci_numaq_init(void)
 {
 	int quad;
 
-	if (!found_numaq)
-		return 0;
-
 	raw_pci_ops = &pci_direct_conf1_mq;
 
-	if (pcibios_scanned++)
-		return 0;
-
 	pci_root_bus = pcibios_scan_root(0);
 	if (pci_root_bus)
 		pci_bus_add_devices(pci_root_bus);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/olpc.c linux-libre-2.6.34-gnu1/arch/x86/pci/olpc.c
--- linux-libre-2.6.33-gnu1/arch/x86/pci/olpc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/olpc.c	2010-05-16 17:17:36.000000000 -0400
@@ -304,9 +304,6 @@ static struct pci_raw_ops pci_olpc_conf
 
 int __init pci_olpc_init(void)
 {
-	if (!machine_is_olpc() || olpc_has_vsa())
-		return -ENODEV;
-
 	printk(KERN_INFO "PCI: Using configuration type OLPC\n");
 	raw_pci_ops = &pci_olpc_conf;
 	is_lx = is_geode_lx();
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/pcbios.c linux-libre-2.6.34-gnu1/arch/x86/pci/pcbios.c
--- linux-libre-2.6.33-gnu1/arch/x86/pci/pcbios.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/pcbios.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
 
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/uaccess.h>
 #include <asm/pci_x86.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/pci/visws.c linux-libre-2.6.34-gnu1/arch/x86/pci/visws.c
--- linux-libre-2.6.33-gnu1/arch/x86/pci/visws.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/pci/visws.c	2010-05-16 17:17:36.000000000 -0400
@@ -69,9 +69,6 @@ void __init pcibios_update_irq(struct pc
 
 int __init pci_visws_init(void)
 {
-	if (!is_visws_box())
-		return -1;
-
 	pcibios_enable_irq = &pci_visws_enable_irq;
 	pcibios_disable_irq = &pci_visws_disable_irq;
 
@@ -90,5 +87,6 @@ int __init pci_visws_init(void)
 	pci_scan_bus_with_sysdata(pci_bus1);
 	pci_fixup_irqs(pci_common_swizzle, visws_map_irq);
 	pcibios_resource_survey();
-	return 0;
+	/* Request bus scan */
+	return 1;
 }
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/power/hibernate_32.c linux-libre-2.6.34-gnu1/arch/x86/power/hibernate_32.c
--- linux-libre-2.6.33-gnu1/arch/x86/power/hibernate_32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/power/hibernate_32.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
  * Copyright (c) 2006 Rafael J. Wysocki <rjw@sisk.pl>
  */
 
+#include <linux/gfp.h>
 #include <linux/suspend.h>
 #include <linux/bootmem.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/power/hibernate_64.c linux-libre-2.6.34-gnu1/arch/x86/power/hibernate_64.c
--- linux-libre-2.6.33-gnu1/arch/x86/power/hibernate_64.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/power/hibernate_64.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
  */
 
+#include <linux/gfp.h>
 #include <linux/smp.h>
 #include <linux/suspend.h>
 #include <asm/proto.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/power/hibernate_asm_32.S linux-libre-2.6.34-gnu1/arch/x86/power/hibernate_asm_32.S
--- linux-libre-2.6.33-gnu1/arch/x86/power/hibernate_asm_32.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/power/hibernate_asm_32.S	2010-05-16 17:17:36.000000000 -0400
@@ -27,10 +27,17 @@ ENTRY(swsusp_arch_suspend)
 	ret
 
 ENTRY(restore_image)
+	movl	mmu_cr4_features, %ecx
 	movl	resume_pg_dir, %eax
 	subl	$__PAGE_OFFSET, %eax
 	movl	%eax, %cr3
 
+	jecxz	1f	# cr4 Pentium and higher, skip if zero
+	andl	$~(X86_CR4_PGE), %ecx
+	movl	%ecx, %cr4;  # turn off PGE
+	movl	%cr3, %eax;  # flush TLB
+	movl	%eax, %cr3
+1:
 	movl	restore_pblist, %edx
 	.p2align 4,,7
 
@@ -54,16 +61,8 @@ done:
 	movl	$swapper_pg_dir, %eax
 	subl	$__PAGE_OFFSET, %eax
 	movl	%eax, %cr3
-	/* Flush TLB, including "global" things (vmalloc) */
 	movl	mmu_cr4_features, %ecx
 	jecxz	1f	# cr4 Pentium and higher, skip if zero
-	movl	%ecx, %edx
-	andl	$~(X86_CR4_PGE), %edx
-	movl	%edx, %cr4;  # turn off PGE
-1:
-	movl	%cr3, %eax;  # flush TLB
-	movl	%eax, %cr3
-	jecxz	1f	# cr4 Pentium and higher, skip if zero
 	movl	%ecx, %cr4;  # turn PGE back on
 1:
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/tools/test_get_len.c linux-libre-2.6.34-gnu1/arch/x86/tools/test_get_len.c
--- linux-libre-2.6.33-gnu1/arch/x86/tools/test_get_len.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/tools/test_get_len.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,7 +43,7 @@ static int x86_64;
 static void usage(void)
 {
 	fprintf(stderr, "Usage: objdump -d a.out | awk -f distill.awk |"
-		" %s [-y|-n] [-v] \n", prog);
+		" %s [-y|-n] [-v]\n", prog);
 	fprintf(stderr, "\t-y	64bit mode\n");
 	fprintf(stderr, "\t-n	32bit mode\n");
 	fprintf(stderr, "\t-v	verbose mode\n");
@@ -69,7 +69,7 @@ static void dump_field(FILE *fp, const c
 
 static void dump_insn(FILE *fp, struct insn *insn)
 {
-	fprintf(fp, "Instruction = { \n");
+	fprintf(fp, "Instruction = {\n");
 	dump_field(fp, "prefixes", "\t",	&insn->prefixes);
 	dump_field(fp, "rex_prefix", "\t",	&insn->rex_prefix);
 	dump_field(fp, "vex_prefix", "\t",	&insn->vex_prefix);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/vdso/vma.c linux-libre-2.6.34-gnu1/arch/x86/vdso/vma.c
--- linux-libre-2.6.33-gnu1/arch/x86/vdso/vma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/vdso/vma.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
 #include <linux/mm.h>
 #include <linux/err.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/random.h>
 #include <linux/elf.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/xen/debugfs.c linux-libre-2.6.34-gnu1/arch/x86/xen/debugfs.c
--- linux-libre-2.6.33-gnu1/arch/x86/xen/debugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/xen/debugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,6 @@
 #include <linux/init.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 
 #include "debugfs.h"
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/xen/enlighten.c linux-libre-2.6.34-gnu1/arch/x86/xen/enlighten.c
--- linux-libre-2.6.33-gnu1/arch/x86/xen/enlighten.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/xen/enlighten.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/highmem.h>
 #include <linux/console.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 
 #include <xen/xen.h>
 #include <xen/interface/xen.h>
@@ -50,6 +51,7 @@
 #include <asm/traps.h>
 #include <asm/setup.h>
 #include <asm/desc.h>
+#include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 #include <asm/reboot.h>
@@ -1094,6 +1096,12 @@ asmlinkage void __init xen_start_kernel(
 
 	__supported_pte_mask |= _PAGE_IOMAP;
 
+	/*
+	 * Prevent page tables from being allocated in highmem, even
+	 * if CONFIG_HIGHPTE is enabled.
+	 */
+	__userpte_alloc_gfp &= ~__GFP_HIGHMEM;
+
 	/* Work out if we support NX */
 	x86_configure_nx();
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/xen/mmu.c linux-libre-2.6.34-gnu1/arch/x86/xen/mmu.c
--- linux-libre-2.6.33-gnu1/arch/x86/xen/mmu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/xen/mmu.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,7 @@
 #include <linux/debugfs.h>
 #include <linux/bug.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
@@ -1427,23 +1428,6 @@ static void xen_pgd_free(struct mm_struc
 #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)
 {
@@ -1902,10 +1886,6 @@ static const struct pv_mmu_ops xen_mmu_o
 	.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
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/xen/smp.c linux-libre-2.6.34-gnu1/arch/x86/xen/smp.c
--- linux-libre-2.6.33-gnu1/arch/x86/xen/smp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/xen/smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
  */
 #include <linux/sched.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/smp.h>
 
 #include <asm/paravirt.h>
@@ -361,7 +362,7 @@ static void xen_cpu_die(unsigned int cpu
 		alternatives_smp_switch(0);
 }
 
-static void __cpuinit xen_play_dead(void) /* used only with CPU_HOTPLUG */
+static void __cpuinit xen_play_dead(void) /* used only with HOTPLUG_CPU */
 {
 	play_dead_common();
 	HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/xen/spinlock.c linux-libre-2.6.34-gnu1/arch/x86/xen/spinlock.c
--- linux-libre-2.6.33-gnu1/arch/x86/xen/spinlock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/xen/spinlock.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
 #include <linux/spinlock.h>
 #include <linux/debugfs.h>
 #include <linux/log2.h>
+#include <linux/gfp.h>
 
 #include <asm/paravirt.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/xen/time.c linux-libre-2.6.34-gnu1/arch/x86/xen/time.c
--- linux-libre-2.6.33-gnu1/arch/x86/xen/time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/xen/time.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/clockchips.h>
 #include <linux/kernel_stat.h>
 #include <linux/math64.h>
+#include <linux/gfp.h>
 
 #include <asm/pvclock.h>
 #include <asm/xen/hypervisor.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/x86/xen/xen-asm_32.S linux-libre-2.6.34-gnu1/arch/x86/xen/xen-asm_32.S
--- linux-libre-2.6.33-gnu1/arch/x86/xen/xen-asm_32.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/x86/xen/xen-asm_32.S	2010-05-16 17:17:36.000000000 -0400
@@ -90,9 +90,9 @@ ENTRY(xen_iret)
 	GET_THREAD_INFO(%eax)
 	movl TI_cpu(%eax), %eax
 	movl __per_cpu_offset(,%eax,4), %eax
-	mov per_cpu__xen_vcpu(%eax), %eax
+	mov xen_vcpu(%eax), %eax
 #else
-	movl per_cpu__xen_vcpu, %eax
+	movl xen_vcpu, %eax
 #endif
 
 	/* check IF state we're restoring */
diff -druNp linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/pci.h linux-libre-2.6.34-gnu1/arch/xtensa/include/asm/pci.h
--- linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/xtensa/include/asm/pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -56,14 +56,6 @@ struct pci_dev;
 
 #define PCI_DMA_BUS_IS_PHYS	(1)
 
-/* pci_unmap_{page,single} is a no-op, 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_ubnmap_len(PTR, LEN_NAME)		(0)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL)	do { } while (0)
-
 /* Map a range of PCI memory or I/O space for a device into user space */
 int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
                         enum pci_mmap_state mmap_state, int write_combine);
diff -druNp linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/pgtable.h linux-libre-2.6.34-gnu1/arch/xtensa/include/asm/pgtable.h
--- linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/xtensa/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -394,7 +394,7 @@ ptep_set_wrprotect(struct mm_struct *mm,
 #define kern_addr_valid(addr)	(1)
 
 extern  void update_mmu_cache(struct vm_area_struct * vma,
-			      unsigned long address, pte_t pte);
+			      unsigned long address, pte_t *ptep);
 
 /*
  * remap a physical page `pfn' of size `size' with page protection `prot'
diff -druNp linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/ptrace.h linux-libre-2.6.34-gnu1/arch/xtensa/include/asm/ptrace.h
--- linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/xtensa/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -113,6 +113,7 @@ struct pt_regs {
 
 #include <variant/core.h>
 
+# define arch_has_single_step()	(1)
 # define task_pt_regs(tsk) ((struct pt_regs*) \
   (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1)
 # define user_mode(regs) (((regs)->ps & 0x00000020)!=0)
diff -druNp linux-libre-2.6.33-gnu1/arch/xtensa/kernel/entry.S linux-libre-2.6.34-gnu1/arch/xtensa/kernel/entry.S
--- linux-libre-2.6.33-gnu1/arch/xtensa/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/xtensa/kernel/entry.S	2010-05-16 17:17:36.000000000 -0400
@@ -104,7 +104,7 @@
  *   excsave has been restored, and
  *   stack pointer (a1) has been set.
  *
- * Note: _user_exception might be at an odd adress. Don't use call0..call12
+ * Note: _user_exception might be at an odd address. Don't use call0..call12
  */
 
 ENTRY(user_exception)
@@ -244,7 +244,7 @@ _user_exception:
  *   excsave has been restored, and
  *   stack pointer (a1) has been set.
  *
- * Note: _kernel_exception might be at an odd adress. Don't use call0..call12
+ * Note: _kernel_exception might be at an odd address. Don't use call0..call12
  */
 
 ENTRY(kernel_exception)
diff -druNp linux-libre-2.6.33-gnu1/arch/xtensa/kernel/pci.c linux-libre-2.6.34-gnu1/arch/xtensa/kernel/pci.c
--- linux-libre-2.6.33-gnu1/arch/xtensa/kernel/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/xtensa/kernel/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -69,26 +69,25 @@ static int pci_bus_count;
  * but we want to try to avoid allocating at 0x2900-0x2bff
  * which might have be mirrored at 0x0100-0x03ff..
  */
-void
-pcibios_align_resource(void *data, struct resource *res, resource_size_t size,
-    		       resource_size_t align)
+resource_size_t
+pcibios_align_resource(void *data, const struct resource *res,
+		       resource_size_t size, resource_size_t align)
 {
 	struct pci_dev *dev = data;
+	resource_size_t start = res->start;
 
 	if (res->flags & IORESOURCE_IO) {
-		resource_size_t start = res->start;
-
 		if (size > 0x100) {
 			printk(KERN_ERR "PCI: I/O Region %s/%d too large"
 			       " (%ld bytes)\n", pci_name(dev),
 			       dev->resource - res, size);
 		}
 
-		if (start & 0x300) {
+		if (start & 0x300)
 			start = (start + 0x3ff) & ~0x3ff;
-			res->start = start;
-		}
 	}
+
+	return start;
 }
 
 int
diff -druNp linux-libre-2.6.33-gnu1/arch/xtensa/kernel/pci-dma.c linux-libre-2.6.34-gnu1/arch/xtensa/kernel/pci-dma.c
--- linux-libre-2.6.33-gnu1/arch/xtensa/kernel/pci-dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/xtensa/kernel/pci-dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 #include <asm/cacheflush.h>
 
diff -druNp linux-libre-2.6.33-gnu1/arch/xtensa/kernel/process.c linux-libre-2.6.34-gnu1/arch/xtensa/kernel/process.c
--- linux-libre-2.6.33-gnu1/arch/xtensa/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/xtensa/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/elf.h>
 #include <linux/init.h>
 #include <linux/prctl.h>
@@ -31,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/mqueue.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/xtensa/kernel/ptrace.c linux-libre-2.6.34-gnu1/arch/xtensa/kernel/ptrace.c
--- linux-libre-2.6.33-gnu1/arch/xtensa/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/xtensa/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,17 @@
 #include <asm/elf.h>
 #include <asm/coprocessor.h>
 
+
+void user_enable_single_step(struct task_struct *child)
+{
+	child->ptrace |= PT_SINGLESTEP;
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+	child->ptrace &= ~PT_SINGLESTEP;
+}
+
 /*
  * Called by kernel/ptrace.c when detaching to disable single stepping.
  */
@@ -268,51 +279,6 @@ long arch_ptrace(struct task_struct *chi
 		ret = ptrace_pokeusr(child, addr, data);
 		break;
 
-	/* continue and stop at next (return from) syscall */
-
-	case PTRACE_SYSCALL:
-	case PTRACE_CONT: /* restart after signal. */
-	{
-		ret = -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;
-		/* Make sure the single step bit is not set. */
-		child->ptrace &= ~PT_SINGLESTEP;
-		wake_up_process(child);
-		ret = 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:
-		ret = 0;
-		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
-			break;
-		child->exit_code = SIGKILL;
-		child->ptrace &= ~PT_SINGLESTEP;
-		wake_up_process(child);
-		break;
-
-	case PTRACE_SINGLESTEP:
-		ret = -EIO;
-		if (!valid_signal(data))
-			break;
-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		child->ptrace |= PT_SINGLESTEP;
-		child->exit_code = data;
-		wake_up_process(child);
-		ret = 0;
-		break;
-
 	case PTRACE_GETREGS:
 		ret = ptrace_getregs(child, (void __user *) data);
 		break;
diff -druNp linux-libre-2.6.33-gnu1/arch/xtensa/mm/cache.c linux-libre-2.6.34-gnu1/arch/xtensa/mm/cache.c
--- linux-libre-2.6.33-gnu1/arch/xtensa/mm/cache.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/xtensa/mm/cache.c	2010-05-16 17:17:36.000000000 -0400
@@ -147,9 +147,9 @@ void flush_cache_page(struct vm_area_str
 #endif
 
 void
-update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t pte)
+update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
 {
-	unsigned long pfn = pte_pfn(pte);
+	unsigned long pfn = pte_pfn(*ptep);
 	struct page *page;
 
 	if (!pfn_valid(pfn))
diff -druNp linux-libre-2.6.33-gnu1/arch/xtensa/mm/init.c linux-libre-2.6.34-gnu1/arch/xtensa/mm/init.c
--- linux-libre-2.6.33-gnu1/arch/xtensa/mm/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/xtensa/mm/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,11 +18,11 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 #include <linux/swap.h>
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 
 #include <asm/bootparam.h>
 #include <asm/page.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/xtensa/platforms/iss/console.c linux-libre-2.6.34-gnu1/arch/xtensa/platforms/iss/console.c
--- linux-libre-2.6.33-gnu1/arch/xtensa/platforms/iss/console.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/xtensa/platforms/iss/console.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
 #include <linux/sched.h>
 #include <linux/console.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/major.h>
 #include <linux/param.h>
diff -druNp linux-libre-2.6.33-gnu1/arch/xtensa/platforms/iss/network.c linux-libre-2.6.34-gnu1/arch/xtensa/platforms/iss/network.c
--- linux-libre-2.6.33-gnu1/arch/xtensa/platforms/iss/network.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/arch/xtensa/platforms/iss/network.c	2010-05-16 17:17:36.000000000 -0400
@@ -560,7 +560,7 @@ static void iss_net_set_multicast_list(s
 #if 0
 	if (dev->flags & IFF_PROMISC)
 		return;
-	else if (dev->mc_count)
+	else if (!netdev_mc_empty(dev))
 		dev->flags |= IFF_ALLMULTI;
 	else
 		dev->flags &= ~IFF_ALLMULTI;
diff -druNp linux-libre-2.6.33-gnu1/block/blk-barrier.c linux-libre-2.6.34-gnu1/block/blk-barrier.c
--- linux-libre-2.6.33-gnu1/block/blk-barrier.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/blk-barrier.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
 #include <linux/module.h>
 #include <linux/bio.h>
 #include <linux/blkdev.h>
+#include <linux/gfp.h>
 
 #include "blk.h"
 
diff -druNp linux-libre-2.6.33-gnu1/block/blk-cgroup.c linux-libre-2.6.34-gnu1/block/blk-cgroup.c
--- linux-libre-2.6.33-gnu1/block/blk-cgroup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/blk-cgroup.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/kdev_t.h>
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include "blk-cgroup.h"
 
 static DEFINE_SPINLOCK(blkio_list_lock);
@@ -23,19 +24,30 @@ static LIST_HEAD(blkio_list);
 struct blkio_cgroup blkio_root_cgroup = { .weight = 2*BLKIO_WEIGHT_DEFAULT };
 EXPORT_SYMBOL_GPL(blkio_root_cgroup);
 
-bool blkiocg_css_tryget(struct blkio_cgroup *blkcg)
-{
-	if (!css_tryget(&blkcg->css))
-		return false;
-	return true;
-}
-EXPORT_SYMBOL_GPL(blkiocg_css_tryget);
+static struct cgroup_subsys_state *blkiocg_create(struct cgroup_subsys *,
+						  struct cgroup *);
+static int blkiocg_can_attach(struct cgroup_subsys *, struct cgroup *,
+			      struct task_struct *, bool);
+static void blkiocg_attach(struct cgroup_subsys *, struct cgroup *,
+			   struct cgroup *, struct task_struct *, bool);
+static void blkiocg_destroy(struct cgroup_subsys *, struct cgroup *);
+static int blkiocg_populate(struct cgroup_subsys *, struct cgroup *);
 
-void blkiocg_css_put(struct blkio_cgroup *blkcg)
-{
-	css_put(&blkcg->css);
-}
-EXPORT_SYMBOL_GPL(blkiocg_css_put);
+struct cgroup_subsys blkio_subsys = {
+	.name = "blkio",
+	.create = blkiocg_create,
+	.can_attach = blkiocg_can_attach,
+	.attach = blkiocg_attach,
+	.destroy = blkiocg_destroy,
+	.populate = blkiocg_populate,
+#ifdef CONFIG_BLK_CGROUP
+	/* note: blkio_subsys_id is otherwise defined in blk-cgroup.h */
+	.subsys_id = blkio_subsys_id,
+#endif
+	.use_id = 1,
+	.module = THIS_MODULE,
+};
+EXPORT_SYMBOL_GPL(blkio_subsys);
 
 struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup)
 {
@@ -267,22 +279,23 @@ remove_entry:
 done:
 	free_css_id(&blkio_subsys, &blkcg->css);
 	rcu_read_unlock();
-	kfree(blkcg);
+	if (blkcg != &blkio_root_cgroup)
+		kfree(blkcg);
 }
 
 static struct cgroup_subsys_state *
 blkiocg_create(struct cgroup_subsys *subsys, struct cgroup *cgroup)
 {
-	struct blkio_cgroup *blkcg, *parent_blkcg;
+	struct blkio_cgroup *blkcg;
+	struct cgroup *parent = cgroup->parent;
 
-	if (!cgroup->parent) {
+	if (!parent) {
 		blkcg = &blkio_root_cgroup;
 		goto done;
 	}
 
 	/* Currently we do not support hierarchy deeper than two level (0,1) */
-	parent_blkcg = cgroup_to_blkio_cgroup(cgroup->parent);
-	if (css_depth(&parent_blkcg->css) > 0)
+	if (parent != cgroup->top_cgroup)
 		return ERR_PTR(-EINVAL);
 
 	blkcg = kzalloc(sizeof(*blkcg), GFP_KERNEL);
@@ -333,17 +346,6 @@ static void blkiocg_attach(struct cgroup
 	task_unlock(tsk);
 }
 
-struct cgroup_subsys blkio_subsys = {
-	.name = "blkio",
-	.create = blkiocg_create,
-	.can_attach = blkiocg_can_attach,
-	.attach = blkiocg_attach,
-	.destroy = blkiocg_destroy,
-	.populate = blkiocg_populate,
-	.subsys_id = blkio_subsys_id,
-	.use_id = 1,
-};
-
 void blkio_policy_register(struct blkio_policy_type *blkiop)
 {
 	spin_lock(&blkio_list_lock);
@@ -359,3 +361,17 @@ void blkio_policy_unregister(struct blki
 	spin_unlock(&blkio_list_lock);
 }
 EXPORT_SYMBOL_GPL(blkio_policy_unregister);
+
+static int __init init_cgroup_blkio(void)
+{
+	return cgroup_load_subsys(&blkio_subsys);
+}
+
+static void __exit exit_cgroup_blkio(void)
+{
+	cgroup_unload_subsys(&blkio_subsys);
+}
+
+module_init(init_cgroup_blkio);
+module_exit(exit_cgroup_blkio);
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/block/blk-cgroup.h linux-libre-2.6.34-gnu1/block/blk-cgroup.h
--- linux-libre-2.6.33-gnu1/block/blk-cgroup.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/blk-cgroup.h	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,13 @@
 
 #include <linux/cgroup.h>
 
-#ifdef CONFIG_BLK_CGROUP
+#if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
+
+#ifndef CONFIG_BLK_CGROUP
+/* When blk-cgroup is a module, its subsys_id isn't a compile-time constant */
+extern struct cgroup_subsys blkio_subsys;
+#define blkio_subsys_id blkio_subsys.subsys_id
+#endif
 
 struct blkio_cgroup {
 	struct cgroup_subsys_state css;
@@ -43,9 +49,6 @@ struct blkio_group {
 	unsigned long sectors;
 };
 
-extern bool blkiocg_css_tryget(struct blkio_cgroup *blkcg);
-extern void blkiocg_css_put(struct blkio_cgroup *blkcg);
-
 typedef void (blkio_unlink_group_fn) (void *key, struct blkio_group *blkg);
 typedef void (blkio_update_group_weight_fn) (struct blkio_group *blkg,
 						unsigned int weight);
@@ -94,7 +97,7 @@ static inline void blkiocg_update_blkio_
 			struct blkio_group *blkg, unsigned long dequeue) {}
 #endif
 
-#ifdef CONFIG_BLK_CGROUP
+#if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
 extern struct blkio_cgroup blkio_root_cgroup;
 extern struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup);
 extern void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
diff -druNp linux-libre-2.6.33-gnu1/block/blk-core.c linux-libre-2.6.34-gnu1/block/blk-core.c
--- linux-libre-2.6.33-gnu1/block/blk-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/blk-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -1490,9 +1490,9 @@ end_io:
 /*
  * We only want one ->make_request_fn to be active at a time,
  * else stack usage with stacked devices could be a problem.
- * So use current->bio_{list,tail} to keep a list of requests
+ * So use current->bio_list to keep a list of requests
  * submited by a make_request_fn function.
- * current->bio_tail is also used as a flag to say if
+ * current->bio_list is also used as a flag to say if
  * generic_make_request is currently active in this task or not.
  * If it is NULL, then no make_request is active.  If it is non-NULL,
  * then a make_request is active, and new requests should be added
@@ -1500,11 +1500,11 @@ end_io:
  */
 void generic_make_request(struct bio *bio)
 {
-	if (current->bio_tail) {
+	struct bio_list bio_list_on_stack;
+
+	if (current->bio_list) {
 		/* make_request is active */
-		*(current->bio_tail) = bio;
-		bio->bi_next = NULL;
-		current->bio_tail = &bio->bi_next;
+		bio_list_add(current->bio_list, bio);
 		return;
 	}
 	/* following loop may be a bit non-obvious, and so deserves some
@@ -1512,30 +1512,27 @@ void generic_make_request(struct bio *bi
 	 * Before entering the loop, bio->bi_next is NULL (as all callers
 	 * ensure that) so we have a list with a single bio.
 	 * We pretend that we have just taken it off a longer list, so
-	 * we assign bio_list to the next (which is NULL) and bio_tail
-	 * to &bio_list, thus initialising the bio_list of new bios to be
+	 * we assign bio_list to a pointer to the bio_list_on_stack,
+	 * thus initialising the bio_list of new bios to be
 	 * added.  __generic_make_request may indeed add some more bios
 	 * through a recursive call to generic_make_request.  If it
 	 * did, we find a non-NULL value in bio_list and re-enter the loop
 	 * from the top.  In this case we really did just take the bio
-	 * of the top of the list (no pretending) and so fixup bio_list and
-	 * bio_tail or bi_next, and call into __generic_make_request again.
+	 * of the top of the list (no pretending) and so remove it from
+	 * bio_list, and call into __generic_make_request again.
 	 *
 	 * The loop was structured like this to make only one call to
 	 * __generic_make_request (which is important as it is large and
 	 * inlined) and to keep the structure simple.
 	 */
 	BUG_ON(bio->bi_next);
+	bio_list_init(&bio_list_on_stack);
+	current->bio_list = &bio_list_on_stack;
 	do {
-		current->bio_list = bio->bi_next;
-		if (bio->bi_next == NULL)
-			current->bio_tail = &current->bio_list;
-		else
-			bio->bi_next = NULL;
 		__generic_make_request(bio);
-		bio = current->bio_list;
+		bio = bio_list_pop(current->bio_list);
 	} while (bio);
-	current->bio_tail = NULL; /* deactivate */
+	current->bio_list = NULL; /* deactivate */
 }
 EXPORT_SYMBOL(generic_make_request);
 
@@ -1617,8 +1614,7 @@ int blk_rq_check_limits(struct request_q
 	 * limitation.
 	 */
 	blk_recalc_rq_segments(rq);
-	if (rq->nr_phys_segments > queue_max_phys_segments(q) ||
-	    rq->nr_phys_segments > queue_max_hw_segments(q)) {
+	if (rq->nr_phys_segments > queue_max_segments(q)) {
 		printk(KERN_ERR "%s: over max segments limit.\n", __func__);
 		return -EIO;
 	}
diff -druNp linux-libre-2.6.33-gnu1/block/blk-integrity.c linux-libre-2.6.34-gnu1/block/blk-integrity.c
--- linux-libre-2.6.33-gnu1/block/blk-integrity.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/blk-integrity.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/mempool.h>
 #include <linux/bio.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 #include "blk.h"
 
@@ -278,7 +279,7 @@ static struct attribute *integrity_attrs
 	NULL,
 };
 
-static struct sysfs_ops integrity_ops = {
+static const struct sysfs_ops integrity_ops = {
 	.show	= &integrity_attr_show,
 	.store	= &integrity_attr_store,
 };
diff -druNp linux-libre-2.6.33-gnu1/block/blk-ioc.c linux-libre-2.6.34-gnu1/block/blk-ioc.c
--- linux-libre-2.6.33-gnu1/block/blk-ioc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/blk-ioc.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
 #include <linux/bio.h>
 #include <linux/blkdev.h>
 #include <linux/bootmem.h>	/* for max_pfn/max_low_pfn */
+#include <linux/slab.h>
 
 #include "blk.h"
 
@@ -91,7 +92,7 @@ struct io_context *alloc_io_context(gfp_
 		spin_lock_init(&ret->lock);
 		ret->ioprio_changed = 0;
 		ret->ioprio = 0;
-		ret->last_waited = jiffies; /* doesn't matter... */
+		ret->last_waited = 0; /* doesn't matter... */
 		ret->nr_batch_requests = 0; /* because this is 0 */
 		INIT_RADIX_TREE(&ret->radix_root, GFP_ATOMIC | __GFP_HIGH);
 		INIT_HLIST_HEAD(&ret->cic_list);
diff -druNp linux-libre-2.6.33-gnu1/block/blk-merge.c linux-libre-2.6.34-gnu1/block/blk-merge.c
--- linux-libre-2.6.33-gnu1/block/blk-merge.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/blk-merge.c	2010-05-16 17:17:36.000000000 -0400
@@ -206,8 +206,7 @@ static inline int ll_new_hw_segment(stru
 {
 	int nr_phys_segs = bio_phys_segments(q, bio);
 
-	if (req->nr_phys_segments + nr_phys_segs > queue_max_hw_segments(q) ||
-	    req->nr_phys_segments + nr_phys_segs > queue_max_phys_segments(q)) {
+	if (req->nr_phys_segments + nr_phys_segs > queue_max_segments(q)) {
 		req->cmd_flags |= REQ_NOMERGE;
 		if (req == q->last_merge)
 			q->last_merge = NULL;
@@ -300,10 +299,7 @@ static int ll_merge_requests_fn(struct r
 		total_phys_segments--;
 	}
 
-	if (total_phys_segments > queue_max_phys_segments(q))
-		return 0;
-
-	if (total_phys_segments > queue_max_hw_segments(q))
+	if (total_phys_segments > queue_max_segments(q))
 		return 0;
 
 	/* Merge is OK... */
diff -druNp linux-libre-2.6.33-gnu1/block/blk-settings.c linux-libre-2.6.34-gnu1/block/blk-settings.c
--- linux-libre-2.6.33-gnu1/block/blk-settings.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/blk-settings.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,9 @@
 #include <linux/blkdev.h>
 #include <linux/bootmem.h>	/* for max_pfn/max_low_pfn */
 #include <linux/gcd.h>
+#include <linux/lcm.h>
 #include <linux/jiffies.h>
+#include <linux/gfp.h>
 
 #include "blk.h"
 
@@ -91,10 +93,9 @@ EXPORT_SYMBOL_GPL(blk_queue_lld_busy);
  */
 void blk_set_default_limits(struct queue_limits *lim)
 {
-	lim->max_phys_segments = MAX_PHYS_SEGMENTS;
-	lim->max_hw_segments = MAX_HW_SEGMENTS;
+	lim->max_segments = BLK_MAX_SEGMENTS;
 	lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK;
-	lim->max_segment_size = MAX_SEGMENT_SIZE;
+	lim->max_segment_size = BLK_MAX_SEGMENT_SIZE;
 	lim->max_sectors = BLK_DEF_MAX_SECTORS;
 	lim->max_hw_sectors = INT_MAX;
 	lim->max_discard_sectors = 0;
@@ -154,7 +155,7 @@ void blk_queue_make_request(struct reque
 	q->unplug_timer.data = (unsigned long)q;
 
 	blk_set_default_limits(&q->limits);
-	blk_queue_max_sectors(q, SAFE_MAX_SECTORS);
+	blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS);
 
 	/*
 	 * If the caller didn't supply a lock, fall back to our embedded
@@ -210,37 +211,32 @@ void blk_queue_bounce_limit(struct reque
 EXPORT_SYMBOL(blk_queue_bounce_limit);
 
 /**
- * blk_queue_max_sectors - set max sectors for a request for this queue
+ * blk_queue_max_hw_sectors - set max sectors for a request for this queue
  * @q:  the request queue for the device
- * @max_sectors:  max sectors in the usual 512b unit
+ * @max_hw_sectors:  max hardware sectors in the usual 512b unit
  *
  * Description:
- *    Enables a low level driver to set an upper limit on the size of
- *    received requests.
+ *    Enables a low level driver to set a hard upper limit,
+ *    max_hw_sectors, on the size of requests.  max_hw_sectors is set by
+ *    the device driver based upon the combined capabilities of I/O
+ *    controller and storage device.
+ *
+ *    max_sectors is a soft limit imposed by the block layer for
+ *    filesystem type requests.  This value can be overridden on a
+ *    per-device basis in /sys/block/<device>/queue/max_sectors_kb.
+ *    The soft limit can not exceed max_hw_sectors.
  **/
-void blk_queue_max_sectors(struct request_queue *q, unsigned int max_sectors)
+void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors)
 {
-	if ((max_sectors << 9) < PAGE_CACHE_SIZE) {
-		max_sectors = 1 << (PAGE_CACHE_SHIFT - 9);
+	if ((max_hw_sectors << 9) < PAGE_CACHE_SIZE) {
+		max_hw_sectors = 1 << (PAGE_CACHE_SHIFT - 9);
 		printk(KERN_INFO "%s: set to minimum %d\n",
-		       __func__, max_sectors);
-	}
-
-	if (BLK_DEF_MAX_SECTORS > max_sectors)
-		q->limits.max_hw_sectors = q->limits.max_sectors = max_sectors;
-	else {
-		q->limits.max_sectors = BLK_DEF_MAX_SECTORS;
-		q->limits.max_hw_sectors = max_sectors;
+		       __func__, max_hw_sectors);
 	}
-}
-EXPORT_SYMBOL(blk_queue_max_sectors);
 
-void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_sectors)
-{
-	if (BLK_DEF_MAX_SECTORS > max_sectors)
-		q->limits.max_hw_sectors = BLK_DEF_MAX_SECTORS;
-	else
-		q->limits.max_hw_sectors = max_sectors;
+	q->limits.max_hw_sectors = max_hw_sectors;
+	q->limits.max_sectors = min_t(unsigned int, max_hw_sectors,
+				      BLK_DEF_MAX_SECTORS);
 }
 EXPORT_SYMBOL(blk_queue_max_hw_sectors);
 
@@ -257,41 +253,15 @@ void blk_queue_max_discard_sectors(struc
 EXPORT_SYMBOL(blk_queue_max_discard_sectors);
 
 /**
- * blk_queue_max_phys_segments - set max phys segments for a request for this queue
- * @q:  the request queue for the device
- * @max_segments:  max number of segments
- *
- * Description:
- *    Enables a low level driver to set an upper limit on the number of
- *    physical data segments in a request.  This would be the largest sized
- *    scatter list the driver could handle.
- **/
-void blk_queue_max_phys_segments(struct request_queue *q,
-				 unsigned short max_segments)
-{
-	if (!max_segments) {
-		max_segments = 1;
-		printk(KERN_INFO "%s: set to minimum %d\n",
-		       __func__, max_segments);
-	}
-
-	q->limits.max_phys_segments = max_segments;
-}
-EXPORT_SYMBOL(blk_queue_max_phys_segments);
-
-/**
- * blk_queue_max_hw_segments - set max hw segments for a request for this queue
+ * blk_queue_max_segments - set max hw segments for a request for this queue
  * @q:  the request queue for the device
  * @max_segments:  max number of segments
  *
  * Description:
  *    Enables a low level driver to set an upper limit on the number of
- *    hw data segments in a request.  This would be the largest number of
- *    address/length pairs the host adapter can actually give at once
- *    to the device.
+ *    hw data segments in a request.
  **/
-void blk_queue_max_hw_segments(struct request_queue *q,
-			       unsigned short max_segments)
+void blk_queue_max_segments(struct request_queue *q, unsigned short max_segments)
 {
 	if (!max_segments) {
 		max_segments = 1;
@@ -299,9 +269,9 @@ void blk_queue_max_hw_segments(struct re
 		       __func__, max_segments);
 	}
 
-	q->limits.max_hw_segments = max_segments;
+	q->limits.max_segments = max_segments;
 }
-EXPORT_SYMBOL(blk_queue_max_hw_segments);
+EXPORT_SYMBOL(blk_queue_max_segments);
 
 /**
  * blk_queue_max_segment_size - set max segment size for blk_rq_map_sg
@@ -493,21 +463,11 @@ void blk_queue_stack_limits(struct reque
 }
 EXPORT_SYMBOL(blk_queue_stack_limits);
 
-static unsigned int lcm(unsigned int a, unsigned int b)
-{
-	if (a && b)
-		return (a * b) / gcd(a, b);
-	else if (b)
-		return b;
-
-	return a;
-}
-
 /**
  * blk_stack_limits - adjust queue_limits for stacked devices
  * @t:	the stacking driver limits (top device)
  * @b:  the underlying queue limits (bottom, component device)
- * @offset:  offset to beginning of data within component device
+ * @start:  first data sector within component device
  *
  * Description:
  *    This function is used by stacking drivers like MD and DM to ensure
@@ -525,10 +485,9 @@ static unsigned int lcm(unsigned int a,
  *    the alignment_offset is undefined.
  */
 int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
-		     sector_t offset)
+		     sector_t start)
 {
-	sector_t alignment;
-	unsigned int top, bottom, ret = 0;
+	unsigned int top, bottom, alignment, ret = 0;
 
 	t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors);
 	t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors);
@@ -537,18 +496,14 @@ int blk_stack_limits(struct queue_limits
 	t->seg_boundary_mask = min_not_zero(t->seg_boundary_mask,
 					    b->seg_boundary_mask);
 
-	t->max_phys_segments = min_not_zero(t->max_phys_segments,
-					    b->max_phys_segments);
-
-	t->max_hw_segments = min_not_zero(t->max_hw_segments,
-					  b->max_hw_segments);
+	t->max_segments = min_not_zero(t->max_segments, b->max_segments);
 
 	t->max_segment_size = min_not_zero(t->max_segment_size,
 					   b->max_segment_size);
 
 	t->misaligned |= b->misaligned;
 
-	alignment = queue_limit_alignment_offset(b, offset);
+	alignment = queue_limit_alignment_offset(b, start);
 
 	/* Bottom device has different alignment.  Check that it is
 	 * compatible with the current top alignment.
@@ -611,11 +566,7 @@ int blk_stack_limits(struct queue_limits
 
 	/* Discard alignment and granularity */
 	if (b->discard_granularity) {
-		unsigned int granularity = b->discard_granularity;
-		offset &= granularity - 1;
-
-		alignment = (granularity + b->discard_alignment - offset)
-			& (granularity - 1);
+		alignment = queue_limit_discard_alignment(b, start);
 
 		if (t->discard_granularity != 0 &&
 		    t->discard_alignment != alignment) {
@@ -657,7 +608,7 @@ int bdev_stack_limits(struct queue_limit
 
 	start += get_start_sect(bdev);
 
-	return blk_stack_limits(t, &bq->limits, start << 9);
+	return blk_stack_limits(t, &bq->limits, start);
 }
 EXPORT_SYMBOL(bdev_stack_limits);
 
@@ -668,9 +619,8 @@ EXPORT_SYMBOL(bdev_stack_limits);
  * @offset:  offset to beginning of data within component device
  *
  * Description:
- *    Merges the limits for two queues.  Returns 0 if alignment
- *    didn't change.  Returns -1 if adding the bottom device caused
- *    misalignment.
+ *    Merges the limits for a top level gendisk and a bottom level
+ *    block_device.
  */
 void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
 		       sector_t offset)
@@ -678,9 +628,7 @@ void disk_stack_limits(struct gendisk *d
 	struct request_queue *t = disk->queue;
 	struct request_queue *b = bdev_get_queue(bdev);
 
-	offset += get_start_sect(bdev) << 9;
-
-	if (blk_stack_limits(&t->limits, &b->limits, offset) < 0) {
+	if (bdev_stack_limits(&t->limits, bdev, offset >> 9) < 0) {
 		char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE];
 
 		disk_name(disk, 0, top);
@@ -752,22 +700,19 @@ EXPORT_SYMBOL(blk_queue_update_dma_pad);
  * does is adjust the queue so that the buf is always appended
  * silently to the scatterlist.
  *
- * Note: This routine adjusts max_hw_segments to make room for
- * appending the drain buffer.  If you call
- * blk_queue_max_hw_segments() or blk_queue_max_phys_segments() after
- * calling this routine, you must set the limit to one fewer than your
- * device can support otherwise there won't be room for the drain
- * buffer.
+ * Note: This routine adjusts max_hw_segments to make room for appending
+ * the drain buffer.  If you call blk_queue_max_segments() after calling
+ * this routine, you must set the limit to one fewer than your device
+ * can support otherwise there won't be room for the drain buffer.
  */
 int blk_queue_dma_drain(struct request_queue *q,
 			       dma_drain_needed_fn *dma_drain_needed,
 			       void *buf, unsigned int size)
 {
-	if (queue_max_hw_segments(q) < 2 || queue_max_phys_segments(q) < 2)
+	if (queue_max_segments(q) < 2)
 		return -EINVAL;
 	/* make room for appending the drain */
-	blk_queue_max_hw_segments(q, queue_max_hw_segments(q) - 1);
-	blk_queue_max_phys_segments(q, queue_max_phys_segments(q) - 1);
+	blk_queue_max_segments(q, queue_max_segments(q) - 1);
 	q->dma_drain_needed = dma_drain_needed;
 	q->dma_drain_buffer = buf;
 	q->dma_drain_size = size;
diff -druNp linux-libre-2.6.33-gnu1/block/blk-sysfs.c linux-libre-2.6.34-gnu1/block/blk-sysfs.c
--- linux-libre-2.6.33-gnu1/block/blk-sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/blk-sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
  * Functions related to sysfs handling
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/bio.h>
 #include <linux/blkdev.h>
@@ -106,6 +107,19 @@ static ssize_t queue_max_sectors_show(st
 	return queue_var_show(max_sectors_kb, (page));
 }
 
+static ssize_t queue_max_segments_show(struct request_queue *q, char *page)
+{
+	return queue_var_show(queue_max_segments(q), (page));
+}
+
+static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page)
+{
+	if (test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
+		return queue_var_show(queue_max_segment_size(q), (page));
+
+	return queue_var_show(PAGE_CACHE_SIZE, (page));
+}
+
 static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page)
 {
 	return queue_var_show(queue_logical_block_size(q), page);
@@ -189,7 +203,8 @@ static ssize_t queue_nonrot_store(struct
 
 static ssize_t queue_nomerges_show(struct request_queue *q, char *page)
 {
-	return queue_var_show(blk_queue_nomerges(q), page);
+	return queue_var_show((blk_queue_nomerges(q) << 1) |
+			       blk_queue_noxmerges(q), page);
 }
 
 static ssize_t queue_nomerges_store(struct request_queue *q, const char *page,
@@ -199,10 +214,12 @@ static ssize_t queue_nomerges_store(stru
 	ssize_t ret = queue_var_store(&nm, page, count);
 
 	spin_lock_irq(q->queue_lock);
-	if (nm)
+	queue_flag_clear(QUEUE_FLAG_NOMERGES, q);
+	queue_flag_clear(QUEUE_FLAG_NOXMERGES, q);
+	if (nm == 2)
 		queue_flag_set(QUEUE_FLAG_NOMERGES, q);
-	else
-		queue_flag_clear(QUEUE_FLAG_NOMERGES, q);
+	else if (nm)
+		queue_flag_set(QUEUE_FLAG_NOXMERGES, q);
 	spin_unlock_irq(q->queue_lock);
 
 	return ret;
@@ -277,6 +294,16 @@ static struct queue_sysfs_entry queue_ma
 	.show = queue_max_hw_sectors_show,
 };
 
+static struct queue_sysfs_entry queue_max_segments_entry = {
+	.attr = {.name = "max_segments", .mode = S_IRUGO },
+	.show = queue_max_segments_show,
+};
+
+static struct queue_sysfs_entry queue_max_segment_size_entry = {
+	.attr = {.name = "max_segment_size", .mode = S_IRUGO },
+	.show = queue_max_segment_size_show,
+};
+
 static struct queue_sysfs_entry queue_iosched_entry = {
 	.attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR },
 	.show = elv_iosched_show,
@@ -352,6 +379,8 @@ static struct attribute *default_attrs[]
 	&queue_ra_entry.attr,
 	&queue_max_hw_sectors_entry.attr,
 	&queue_max_sectors_entry.attr,
+	&queue_max_segments_entry.attr,
+	&queue_max_segment_size_entry.attr,
 	&queue_iosched_entry.attr,
 	&queue_hw_sector_size_entry.attr,
 	&queue_logical_block_size_entry.attr,
@@ -447,7 +476,7 @@ static void blk_release_queue(struct kob
 	kmem_cache_free(blk_requestq_cachep, q);
 }
 
-static struct sysfs_ops queue_sysfs_ops = {
+static const struct sysfs_ops queue_sysfs_ops = {
 	.show	= queue_attr_show,
 	.store	= queue_attr_store,
 };
diff -druNp linux-libre-2.6.33-gnu1/block/blk-tag.c linux-libre-2.6.34-gnu1/block/blk-tag.c
--- linux-libre-2.6.33-gnu1/block/blk-tag.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/blk-tag.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
 #include <linux/module.h>
 #include <linux/bio.h>
 #include <linux/blkdev.h>
+#include <linux/slab.h>
 
 #include "blk.h"
 
diff -druNp linux-libre-2.6.33-gnu1/block/blk-timeout.c linux-libre-2.6.34-gnu1/block/blk-timeout.c
--- linux-libre-2.6.33-gnu1/block/blk-timeout.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/blk-timeout.c	2010-05-16 17:17:36.000000000 -0400
@@ -109,6 +109,7 @@ void blk_rq_timed_out_timer(unsigned lon
 	struct request_queue *q = (struct request_queue *) data;
 	unsigned long flags, next = 0;
 	struct request *rq, *tmp;
+	int next_set = 0;
 
 	spin_lock_irqsave(q->queue_lock, flags);
 
@@ -122,16 +123,13 @@ void blk_rq_timed_out_timer(unsigned lon
 			if (blk_mark_rq_complete(rq))
 				continue;
 			blk_rq_timed_out(rq);
-		} else if (!next || time_after(next, rq->deadline))
+		} else if (!next_set || time_after(next, rq->deadline)) {
 			next = rq->deadline;
+			next_set = 1;
+		}
 	}
 
-	/*
-	 * next can never be 0 here with the list non-empty, since we always
-	 * bump ->deadline to 1 so we can detect if the timer was ever added
-	 * or not. See comment in blk_add_timer()
-	 */
-	if (next)
+	if (next_set)
 		mod_timer(&q->timeout, round_jiffies_up(next));
 
 	spin_unlock_irqrestore(q->queue_lock, flags);
diff -druNp linux-libre-2.6.33-gnu1/block/bsg.c linux-libre-2.6.34-gnu1/block/bsg.c
--- linux-libre-2.6.33-gnu1/block/bsg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/bsg.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/idr.h>
 #include <linux/bsg.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_ioctl.h>
@@ -260,7 +261,7 @@ bsg_map_hdr(struct bsg_device *bd, struc
 		return ERR_PTR(ret);
 
 	/*
-	 * map scatter-gather elements seperately and string them to request
+	 * map scatter-gather elements separately and string them to request
 	 */
 	rq = blk_get_request(q, rw, GFP_KERNEL);
 	if (!rq)
diff -druNp linux-libre-2.6.33-gnu1/block/cfq-iosched.c linux-libre-2.6.34-gnu1/block/cfq-iosched.c
--- linux-libre-2.6.33-gnu1/block/cfq-iosched.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/cfq-iosched.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
  *  Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  */
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/elevator.h>
 #include <linux/jiffies.h>
@@ -19,7 +20,7 @@
  * tunables
  */
 /* max queue in one round of service */
-static const int cfq_quantum = 4;
+static const int cfq_quantum = 8;
 static const int cfq_fifo_expire[2] = { HZ / 4, HZ / 8 };
 /* maximum backwards seek, in KiB */
 static const int cfq_back_max = 16 * 1024;
@@ -46,8 +47,10 @@ static const int cfq_hist_divisor = 4;
 #define CFQ_HW_QUEUE_MIN	(5)
 #define CFQ_SERVICE_SHIFT       12
 
-#define CFQQ_SEEK_THR		8 * 1024
-#define CFQQ_SEEKY(cfqq)	((cfqq)->seek_mean > CFQQ_SEEK_THR)
+#define CFQQ_SEEK_THR		(sector_t)(8 * 100)
+#define CFQQ_CLOSE_THR		(sector_t)(8 * 1024)
+#define CFQQ_SECT_THR_NONROT	(sector_t)(2 * 32)
+#define CFQQ_SEEKY(cfqq)	(hweight32(cfqq->seek_history) > 32/8)
 
 #define RQ_CIC(rq)		\
 	((struct cfq_io_context *) (rq)->elevator_private)
@@ -77,11 +80,12 @@ struct cfq_rb_root {
 	struct rb_root rb;
 	struct rb_node *left;
 	unsigned count;
+	unsigned total_weight;
 	u64 min_vdisktime;
 	struct rb_node *active;
-	unsigned total_weight;
 };
-#define CFQ_RB_ROOT	(struct cfq_rb_root) { RB_ROOT, NULL, 0, 0, }
+#define CFQ_RB_ROOT	(struct cfq_rb_root) { .rb = RB_ROOT, .left = NULL, \
+			.count = 0, .min_vdisktime = 0, }
 
 /*
  * Per process-grouping structure
@@ -115,11 +119,11 @@ struct cfq_queue {
 	/* time when queue got scheduled in to dispatch first request. */
 	unsigned long dispatch_start;
 	unsigned int allocated_slice;
+	unsigned int slice_dispatch;
 	/* time when first request from queue completed and slice started. */
 	unsigned long slice_start;
 	unsigned long slice_end;
 	long slice_resid;
-	unsigned int slice_dispatch;
 
 	/* pending metadata requests */
 	int meta_pending;
@@ -130,13 +134,11 @@ struct cfq_queue {
 	unsigned short ioprio, org_ioprio;
 	unsigned short ioprio_class, org_ioprio_class;
 
-	unsigned int seek_samples;
-	u64 seek_total;
-	sector_t seek_mean;
-	sector_t last_request_pos;
-
 	pid_t pid;
 
+	u32 seek_history;
+	sector_t last_request_pos;
+
 	struct cfq_rb_root *service_tree;
 	struct cfq_queue *new_cfqq;
 	struct cfq_group *cfqg;
@@ -223,8 +225,8 @@ struct cfq_data {
 
 	unsigned int busy_queues;
 
-	int rq_in_driver[2];
-	int sync_flight;
+	int rq_in_driver;
+	int rq_in_flight[2];
 
 	/*
 	 * queue-depth detection
@@ -417,11 +419,6 @@ static struct cfq_queue *cfq_get_queue(s
 static struct cfq_io_context *cfq_cic_lookup(struct cfq_data *,
 						struct io_context *);
 
-static inline int rq_in_driver(struct cfq_data *cfqd)
-{
-	return cfqd->rq_in_driver[0] + cfqd->rq_in_driver[1];
-}
-
 static inline struct cfq_queue *cic_to_cfqq(struct cfq_io_context *cic,
 					    bool is_sync)
 {
@@ -951,11 +948,12 @@ cfq_find_alloc_cfqg(struct cfq_data *cfq
 	struct backing_dev_info *bdi = &cfqd->queue->backing_dev_info;
 	unsigned int major, minor;
 
-	/* Do we need to take this reference */
-	if (!blkiocg_css_tryget(blkcg))
-		return NULL;;
-
 	cfqg = cfqg_of_blkg(blkiocg_lookup_group(blkcg, key));
+	if (cfqg && !cfqg->blkg.dev && bdi->dev && dev_name(bdi->dev)) {
+		sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
+		cfqg->blkg.dev = MKDEV(major, minor);
+		goto done;
+	}
 	if (cfqg || !create)
 		goto done;
 
@@ -985,7 +983,6 @@ cfq_find_alloc_cfqg(struct cfq_data *cfq
 	hlist_add_head(&cfqg->cfqd_node, &cfqd->cfqg_list);
 
 done:
-	blkiocg_css_put(blkcg);
 	return cfqg;
 }
 
@@ -1420,9 +1417,9 @@ static void cfq_activate_request(struct
 {
 	struct cfq_data *cfqd = q->elevator->elevator_data;
 
-	cfqd->rq_in_driver[rq_is_sync(rq)]++;
+	cfqd->rq_in_driver++;
 	cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "activate rq, drv=%d",
-						rq_in_driver(cfqd));
+						cfqd->rq_in_driver);
 
 	cfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq);
 }
@@ -1430,12 +1427,11 @@ static void cfq_activate_request(struct
 static void cfq_deactivate_request(struct request_queue *q, struct request *rq)
 {
 	struct cfq_data *cfqd = q->elevator->elevator_data;
-	const int sync = rq_is_sync(rq);
 
-	WARN_ON(!cfqd->rq_in_driver[sync]);
-	cfqd->rq_in_driver[sync]--;
+	WARN_ON(!cfqd->rq_in_driver);
+	cfqd->rq_in_driver--;
 	cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "deactivate rq, drv=%d",
-						rq_in_driver(cfqd));
+						cfqd->rq_in_driver);
 }
 
 static void cfq_remove_request(struct request *rq)
@@ -1528,7 +1524,8 @@ static void __cfq_set_active_queue(struc
 				   struct cfq_queue *cfqq)
 {
 	if (cfqq) {
-		cfq_log_cfqq(cfqd, cfqq, "set_active");
+		cfq_log_cfqq(cfqd, cfqq, "set_active wl_prio:%d wl_type:%d",
+				cfqd->serving_prio, cfqd->serving_type);
 		cfqq->slice_start = 0;
 		cfqq->dispatch_start = jiffies;
 		cfqq->allocated_slice = 0;
@@ -1671,18 +1668,9 @@ static inline sector_t cfq_dist_from_las
 }
 
 static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq,
-			       struct request *rq, bool for_preempt)
+			       struct request *rq)
 {
-	sector_t sdist = cfqq->seek_mean;
-
-	if (!sample_valid(cfqq->seek_samples))
-		sdist = CFQQ_SEEK_THR;
-
-	/* if seek_mean is big, using it as close criteria is meaningless */
-	if (sdist > CFQQ_SEEK_THR && !for_preempt)
-		sdist = CFQQ_SEEK_THR;
-
-	return cfq_dist_from_last(cfqd, rq) <= sdist;
+	return cfq_dist_from_last(cfqd, rq) <= CFQQ_CLOSE_THR;
 }
 
 static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
@@ -1709,7 +1697,7 @@ static struct cfq_queue *cfqq_close(stru
 	 * will contain the closest sector.
 	 */
 	__cfqq = rb_entry(parent, struct cfq_queue, p_node);
-	if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false))
+	if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq))
 		return __cfqq;
 
 	if (blk_rq_pos(__cfqq->next_rq) < sector)
@@ -1720,7 +1708,7 @@ static struct cfq_queue *cfqq_close(stru
 		return NULL;
 
 	__cfqq = rb_entry(node, struct cfq_queue, p_node);
-	if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false))
+	if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq))
 		return __cfqq;
 
 	return NULL;
@@ -1741,6 +1729,8 @@ static struct cfq_queue *cfq_close_coope
 {
 	struct cfq_queue *cfqq;
 
+	if (cfq_class_idle(cur_cfqq))
+		return NULL;
 	if (!cfq_cfqq_sync(cur_cfqq))
 		return NULL;
 	if (CFQQ_SEEKY(cur_cfqq))
@@ -1807,7 +1797,11 @@ static bool cfq_should_idle(struct cfq_d
 	 * Otherwise, we do only if they are the last ones
 	 * in their service tree.
 	 */
-	return service_tree->count == 1 && cfq_cfqq_sync(cfqq);
+	if (service_tree->count == 1 && cfq_cfqq_sync(cfqq))
+		return 1;
+	cfq_log_cfqq(cfqd, cfqq, "Not idling. st->count:%d",
+			service_tree->count);
+	return 0;
 }
 
 static void cfq_arm_slice_timer(struct cfq_data *cfqd)
@@ -1852,8 +1846,11 @@ static void cfq_arm_slice_timer(struct c
 	 * time slice.
 	 */
 	if (sample_valid(cic->ttime_samples) &&
-	    (cfqq->slice_end - jiffies < cic->ttime_mean))
+	    (cfqq->slice_end - jiffies < cic->ttime_mean)) {
+		cfq_log_cfqq(cfqd, cfqq, "Not idling. think_time:%d",
+				cic->ttime_mean);
 		return;
+	}
 
 	cfq_mark_cfqq_wait_request(cfqq);
 
@@ -1878,8 +1875,7 @@ static void cfq_dispatch_insert(struct r
 	cfqq->dispatched++;
 	elv_dispatch_sort(q, rq);
 
-	if (cfq_cfqq_sync(cfqq))
-		cfqd->sync_flight++;
+	cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]++;
 	cfqq->nr_sectors += blk_rq_sectors(rq);
 }
 
@@ -2062,6 +2058,7 @@ static void choose_service_tree(struct c
 		slice = max(slice, 2 * cfqd->cfq_slice_idle);
 
 	slice = max_t(unsigned, slice, CFQ_MIN_TT);
+	cfq_log(cfqd, "workload slice:%d", slice);
 	cfqd->workload_expires = jiffies + slice;
 	cfqd->noidle_tree_requires_idle = false;
 }
@@ -2209,16 +2206,32 @@ static int cfq_forced_dispatch(struct cf
 	struct cfq_queue *cfqq;
 	int dispatched = 0;
 
-	while ((cfqq = cfq_get_next_queue_forced(cfqd)) != NULL)
+	/* Expire the timeslice of the current active queue first */
+	cfq_slice_expired(cfqd, 0);
+	while ((cfqq = cfq_get_next_queue_forced(cfqd)) != NULL) {
+		__cfq_set_active_queue(cfqd, cfqq);
 		dispatched += __cfq_forced_dispatch_cfqq(cfqq);
+	}
 
-	cfq_slice_expired(cfqd, 0);
 	BUG_ON(cfqd->busy_queues);
 
 	cfq_log(cfqd, "forced_dispatch=%d", dispatched);
 	return dispatched;
 }
 
+static inline bool cfq_slice_used_soon(struct cfq_data *cfqd,
+	struct cfq_queue *cfqq)
+{
+	/* the queue hasn't finished any request, can't estimate */
+	if (cfq_cfqq_slice_new(cfqq))
+		return 1;
+	if (time_after(jiffies + cfqd->cfq_slice_idle * cfqq->dispatched,
+		cfqq->slice_end))
+		return 1;
+
+	return 0;
+}
+
 static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
 	unsigned int max_dispatch;
@@ -2226,16 +2239,16 @@ static bool cfq_may_dispatch(struct cfq_
 	/*
 	 * Drain async requests before we start sync IO
 	 */
-	if (cfq_should_idle(cfqd, cfqq) && cfqd->rq_in_driver[BLK_RW_ASYNC])
+	if (cfq_should_idle(cfqd, cfqq) && cfqd->rq_in_flight[BLK_RW_ASYNC])
 		return false;
 
 	/*
 	 * If this is an async queue and we have sync IO in flight, let it wait
 	 */
-	if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq))
+	if (cfqd->rq_in_flight[BLK_RW_SYNC] && !cfq_cfqq_sync(cfqq))
 		return false;
 
-	max_dispatch = cfqd->cfq_quantum;
+	max_dispatch = max_t(unsigned int, cfqd->cfq_quantum / 2, 1);
 	if (cfq_class_idle(cfqq))
 		max_dispatch = 1;
 
@@ -2252,13 +2265,22 @@ static bool cfq_may_dispatch(struct cfq_
 		/*
 		 * We have other queues, don't allow more IO from this one
 		 */
-		if (cfqd->busy_queues > 1)
+		if (cfqd->busy_queues > 1 && cfq_slice_used_soon(cfqd, cfqq))
 			return false;
 
 		/*
 		 * Sole queue user, no limit
 		 */
-		max_dispatch = -1;
+		if (cfqd->busy_queues == 1)
+			max_dispatch = -1;
+		else
+			/*
+			 * Normally we start throttling cfqq when cfq_quantum/2
+			 * requests have been dispatched. But we can drive
+			 * deeper queue depths at the beginning of slice
+			 * subjected to upper limit of cfq_quantum.
+			 * */
+			max_dispatch = cfqd->cfq_quantum;
 	}
 
 	/*
@@ -2980,30 +3002,20 @@ static void
 cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_queue *cfqq,
 		       struct request *rq)
 {
-	sector_t sdist;
-	u64 total;
-
-	if (!cfqq->last_request_pos)
-		sdist = 0;
-	else if (cfqq->last_request_pos < blk_rq_pos(rq))
-		sdist = blk_rq_pos(rq) - cfqq->last_request_pos;
-	else
-		sdist = cfqq->last_request_pos - blk_rq_pos(rq);
+	sector_t sdist = 0;
+	sector_t n_sec = blk_rq_sectors(rq);
+	if (cfqq->last_request_pos) {
+		if (cfqq->last_request_pos < blk_rq_pos(rq))
+			sdist = blk_rq_pos(rq) - cfqq->last_request_pos;
+		else
+			sdist = cfqq->last_request_pos - blk_rq_pos(rq);
+	}
 
-	/*
-	 * Don't allow the seek distance to get too large from the
-	 * odd fragment, pagein, etc
-	 */
-	if (cfqq->seek_samples <= 60) /* second&third seek */
-		sdist = min(sdist, (cfqq->seek_mean * 4) + 2*1024*1024);
+	cfqq->seek_history <<= 1;
+	if (blk_queue_nonrot(cfqd->queue))
+		cfqq->seek_history |= (n_sec < CFQQ_SECT_THR_NONROT);
 	else
-		sdist = min(sdist, (cfqq->seek_mean * 4) + 2*1024*64);
-
-	cfqq->seek_samples = (7*cfqq->seek_samples + 256) / 8;
-	cfqq->seek_total = (7*cfqq->seek_total + (u64)256*sdist) / 8;
-	total = cfqq->seek_total + (cfqq->seek_samples/2);
-	do_div(total, cfqq->seek_samples);
-	cfqq->seek_mean = (sector_t)total;
+		cfqq->seek_history |= (sdist > CFQQ_SEEK_THR);
 }
 
 /*
@@ -3028,8 +3040,7 @@ cfq_update_idle_window(struct cfq_data *
 		cfq_mark_cfqq_deep(cfqq);
 
 	if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle ||
-	    (!cfq_cfqq_deep(cfqq) && sample_valid(cfqq->seek_samples)
-	     && CFQQ_SEEKY(cfqq)))
+	    (!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq)))
 		enable_idle = 0;
 	else if (sample_valid(cic->ttime_samples)) {
 		if (cic->ttime_mean > cfqd->cfq_slice_idle)
@@ -3113,7 +3124,7 @@ cfq_should_preempt(struct cfq_data *cfqd
 	 * if this request is as-good as one we would expect from the
 	 * current cfqq, let it preempt
 	 */
-	if (cfq_rq_close(cfqd, cfqq, rq, true))
+	if (cfq_rq_close(cfqd, cfqq, rq))
 		return true;
 
 	return false;
@@ -3215,14 +3226,14 @@ static void cfq_update_hw_tag(struct cfq
 {
 	struct cfq_queue *cfqq = cfqd->active_queue;
 
-	if (rq_in_driver(cfqd) > cfqd->hw_tag_est_depth)
-		cfqd->hw_tag_est_depth = rq_in_driver(cfqd);
+	if (cfqd->rq_in_driver > cfqd->hw_tag_est_depth)
+		cfqd->hw_tag_est_depth = cfqd->rq_in_driver;
 
 	if (cfqd->hw_tag == 1)
 		return;
 
 	if (cfqd->rq_queued <= CFQ_HW_QUEUE_MIN &&
-	    rq_in_driver(cfqd) <= CFQ_HW_QUEUE_MIN)
+	    cfqd->rq_in_driver <= CFQ_HW_QUEUE_MIN)
 		return;
 
 	/*
@@ -3232,7 +3243,7 @@ static void cfq_update_hw_tag(struct cfq
 	 */
 	if (cfqq && cfq_cfqq_idle_window(cfqq) &&
 	    cfqq->dispatched + cfqq->queued[0] + cfqq->queued[1] <
-	    CFQ_HW_QUEUE_MIN && rq_in_driver(cfqd) < CFQ_HW_QUEUE_MIN)
+	    CFQ_HW_QUEUE_MIN && cfqd->rq_in_driver < CFQ_HW_QUEUE_MIN)
 		return;
 
 	if (cfqd->hw_tag_samples++ < 50)
@@ -3285,13 +3296,12 @@ static void cfq_completed_request(struct
 
 	cfq_update_hw_tag(cfqd);
 
-	WARN_ON(!cfqd->rq_in_driver[sync]);
+	WARN_ON(!cfqd->rq_in_driver);
 	WARN_ON(!cfqq->dispatched);
-	cfqd->rq_in_driver[sync]--;
+	cfqd->rq_in_driver--;
 	cfqq->dispatched--;
 
-	if (cfq_cfqq_sync(cfqq))
-		cfqd->sync_flight--;
+	cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]--;
 
 	if (sync) {
 		RQ_CIC(rq)->last_end_request = now;
@@ -3318,6 +3328,7 @@ static void cfq_completed_request(struct
 		if (cfq_should_wait_busy(cfqd, cfqq)) {
 			cfqq->slice_end = jiffies + cfqd->cfq_slice_idle;
 			cfq_mark_cfqq_wait_busy(cfqq);
+			cfq_log_cfqq(cfqd, cfqq, "will busy wait");
 		}
 
 		/*
@@ -3345,7 +3356,7 @@ static void cfq_completed_request(struct
 		}
 	}
 
-	if (!rq_in_driver(cfqd))
+	if (!cfqd->rq_in_driver)
 		cfq_schedule_dispatch(cfqd);
 }
 
@@ -3683,8 +3694,10 @@ static void *cfq_init_queue(struct reque
 	 * to make sure that cfq_put_cfqg() does not try to kfree root group
 	 */
 	atomic_set(&cfqg->ref, 1);
+	rcu_read_lock();
 	blkiocg_add_blkio_group(&blkio_root_cgroup, &cfqg->blkg, (void *)cfqd,
 					0);
+	rcu_read_unlock();
 #endif
 	/*
 	 * Not strictly needed (since RB_ROOT just clears the node and we
diff -druNp linux-libre-2.6.33-gnu1/block/compat_ioctl.c linux-libre-2.6.34-gnu1/block/compat_ioctl.c
--- linux-libre-2.6.33-gnu1/block/compat_ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/compat_ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
 #include <linux/elevator.h>
 #include <linux/fd.h>
 #include <linux/hdreg.h>
+#include <linux/slab.h>
 #include <linux/syscalls.h>
 #include <linux/smp_lock.h>
 #include <linux/types.h>
diff -druNp linux-libre-2.6.33-gnu1/block/elevator.c linux-libre-2.6.34-gnu1/block/elevator.c
--- linux-libre-2.6.33-gnu1/block/elevator.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/elevator.c	2010-05-16 17:17:36.000000000 -0400
@@ -154,7 +154,7 @@ static struct elevator_type *elevator_ge
 
 		spin_unlock(&elv_list_lock);
 
-		sprintf(elv, "%s-iosched", name);
+		snprintf(elv, sizeof(elv), "%s-iosched", name);
 
 		request_module("%s", elv);
 		spin_lock(&elv_list_lock);
@@ -474,6 +474,15 @@ int elv_merge(struct request_queue *q, s
 	int ret;
 
 	/*
+	 * Levels of merges:
+	 * 	nomerges:  No merges at all attempted
+	 * 	noxmerges: Only simple one-hit cache try
+	 * 	merges:	   All merge tries attempted
+	 */
+	if (blk_queue_nomerges(q))
+		return ELEVATOR_NO_MERGE;
+
+	/*
 	 * First try one-hit cache.
 	 */
 	if (q->last_merge) {
@@ -484,7 +493,7 @@ int elv_merge(struct request_queue *q, s
 		}
 	}
 
-	if (blk_queue_nomerges(q))
+	if (blk_queue_noxmerges(q))
 		return ELEVATOR_NO_MERGE;
 
 	/*
@@ -883,7 +892,7 @@ elv_attr_store(struct kobject *kobj, str
 	return error;
 }
 
-static struct sysfs_ops elv_sysfs_ops = {
+static const struct sysfs_ops elv_sysfs_ops = {
 	.show	= elv_attr_show,
 	.store	= elv_attr_store,
 };
diff -druNp linux-libre-2.6.33-gnu1/block/ioctl.c linux-libre-2.6.34-gnu1/block/ioctl.c
--- linux-libre-2.6.33-gnu1/block/ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,6 @@
 #include <linux/capability.h>
 #include <linux/blkdev.h>
+#include <linux/gfp.h>
 #include <linux/blkpg.h>
 #include <linux/hdreg.h>
 #include <linux/backing-dev.h>
diff -druNp linux-libre-2.6.33-gnu1/block/Kconfig linux-libre-2.6.34-gnu1/block/Kconfig
--- linux-libre-2.6.33-gnu1/block/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -78,8 +78,9 @@ config BLK_DEV_INTEGRITY
 	Protection.  If in doubt, say N.
 
 config BLK_CGROUP
-	bool
+	tristate "Block cgroup support"
 	depends on CGROUPS
+	depends on CFQ_GROUP_IOSCHED
 	default n
 	---help---
 	Generic block IO controller cgroup interface. This is the common
diff -druNp linux-libre-2.6.33-gnu1/block/Kconfig.iosched linux-libre-2.6.34-gnu1/block/Kconfig.iosched
--- linux-libre-2.6.33-gnu1/block/Kconfig.iosched	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/Kconfig.iosched	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@ config IOSCHED_DEADLINE
 
 config IOSCHED_CFQ
 	tristate "CFQ I/O scheduler"
+	select BLK_CGROUP if CFQ_GROUP_IOSCHED
 	default y
 	---help---
 	  The CFQ I/O scheduler tries to distribute bandwidth equally
@@ -35,7 +36,6 @@ config IOSCHED_CFQ
 config CFQ_GROUP_IOSCHED
 	bool "CFQ Group Scheduling support"
 	depends on IOSCHED_CFQ && CGROUPS
-	select BLK_CGROUP
 	default n
 	---help---
 	  Enable group IO scheduling in CFQ.
diff -druNp linux-libre-2.6.33-gnu1/block/noop-iosched.c linux-libre-2.6.34-gnu1/block/noop-iosched.c
--- linux-libre-2.6.33-gnu1/block/noop-iosched.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/block/noop-iosched.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
 #include <linux/elevator.h>
 #include <linux/bio.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 struct noop_data {
diff -druNp linux-libre-2.6.33-gnu1/crypto/ablkcipher.c linux-libre-2.6.34-gnu1/crypto/ablkcipher.c
--- linux-libre-2.6.33-gnu1/crypto/ablkcipher.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/ablkcipher.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * Asynchronous block chaining cipher operations.
- * 
+ *
  * This is the asynchronous version of blkcipher.c indicating completion
  * via a callback.
  *
@@ -8,7 +8,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; either version 2 of the License, or (at your option) 
+ * Software Foundation; either version 2 of the License, or (at your option)
  * any later version.
  *
  */
diff -druNp linux-libre-2.6.33-gnu1/crypto/aead.c linux-libre-2.6.34-gnu1/crypto/aead.c
--- linux-libre-2.6.33-gnu1/crypto/aead.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/aead.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,13 +1,13 @@
 /*
  * AEAD: Authenticated Encryption with Associated Data
- * 
+ *
  * This file provides API support for AEAD algorithms.
  *
  * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option) 
+ * Software Foundation; either version 2 of the License, or (at your option)
  * any later version.
  *
  */
diff -druNp linux-libre-2.6.33-gnu1/crypto/aes_generic.c linux-libre-2.6.34-gnu1/crypto/aes_generic.c
--- linux-libre-2.6.33-gnu1/crypto/aes_generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/aes_generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,4 @@
-/* 
+/*
  * Cryptographic API.
  *
  * AES Cipher Algorithm.
@@ -1127,7 +1127,7 @@ EXPORT_SYMBOL_GPL(crypto_il_tab);
 
 #define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
 
-#define imix_col(y,x)	do {		\
+#define imix_col(y, x)	do {		\
 	u	= star_x(x);		\
 	v	= star_x(u);		\
 	w	= star_x(v);		\
diff -druNp linux-libre-2.6.33-gnu1/crypto/ahash.c linux-libre-2.6.34-gnu1/crypto/ahash.c
--- linux-libre-2.6.33-gnu1/crypto/ahash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/ahash.c	2010-05-16 17:17:36.000000000 -0400
@@ -78,7 +78,6 @@ int crypto_hash_walk_done(struct crypto_
 	walk->data -= walk->offset;
 
 	if (nbytes && walk->offset & alignmask && !err) {
-		walk->offset += alignmask - 1;
 		walk->offset = ALIGN(walk->offset, alignmask + 1);
 		walk->data += walk->offset;
 
diff -druNp linux-libre-2.6.33-gnu1/crypto/algapi.c linux-libre-2.6.34-gnu1/crypto/algapi.c
--- linux-libre-2.6.33-gnu1/crypto/algapi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/algapi.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/rtnetlink.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
 #include "internal.h"
@@ -230,7 +231,7 @@ static struct crypto_larval *__crypto_re
 	list_add(&alg->cra_list, &crypto_alg_list);
 	list_add(&larval->alg.cra_list, &crypto_alg_list);
 
-out:	
+out:
 	return larval;
 
 free_larval:
@@ -388,7 +389,7 @@ int crypto_unregister_alg(struct crypto_
 {
 	int ret;
 	LIST_HEAD(list);
-	
+
 	down_write(&crypto_alg_sem);
 	ret = crypto_remove_alg(alg, &list);
 	up_write(&crypto_alg_sem);
diff -druNp linux-libre-2.6.33-gnu1/crypto/algboss.c linux-libre-2.6.34-gnu1/crypto/algboss.c
--- linux-libre-2.6.33-gnu1/crypto/algboss.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/algboss.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/notifier.h>
 #include <linux/rtnetlink.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
 #include "internal.h"
diff -druNp linux-libre-2.6.33-gnu1/crypto/anubis.c linux-libre-2.6.34-gnu1/crypto/anubis.c
--- linux-libre-2.6.33-gnu1/crypto/anubis.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/anubis.c	2010-05-16 17:17:36.000000000 -0400
@@ -469,14 +469,13 @@ static int anubis_setkey(struct crypto_t
 	u32 kappa[ANUBIS_MAX_N];
 	u32 inter[ANUBIS_MAX_N];
 
-	switch (key_len)
-	{
+	switch (key_len) {
 		case 16: case 20: case 24: case 28:
 		case 32: case 36: case 40:
 			break;
 		default:
 			*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
-			return - EINVAL;
+			return -EINVAL;
 	}
 
 	ctx->key_len = key_len * 8;
@@ -530,23 +529,24 @@ static int anubis_setkey(struct crypto_t
 		/*
 		 * compute kappa^{r+1} from kappa^r:
 		 */
-		if (r == R) {
+		if (r == R)
 			break;
-		}
 		for (i = 0; i < N; i++) {
 			int j = i;
 			inter[i]  = T0[(kappa[j--] >> 24)       ];
-			if (j < 0) j = N - 1;
+			if (j < 0)
+				j = N - 1;
 			inter[i] ^= T1[(kappa[j--] >> 16) & 0xff];
-			if (j < 0) j = N - 1;
+			if (j < 0)
+				j = N - 1;
 			inter[i] ^= T2[(kappa[j--] >>  8) & 0xff];
-			if (j < 0) j = N - 1;
+			if (j < 0)
+				j = N - 1;
 			inter[i] ^= T3[(kappa[j  ]      ) & 0xff];
 		}
 		kappa[0] = inter[0] ^ rc[r];
-		for (i = 1; i < N; i++) {
+		for (i = 1; i < N; i++)
 			kappa[i] = inter[i];
-		}
 	}
 
 	/*
@@ -690,7 +690,7 @@ static struct crypto_alg anubis_alg = {
 static int __init anubis_mod_init(void)
 {
 	int ret = 0;
-	
+
 	ret = crypto_register_alg(&anubis_alg);
 	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/crypto/api.c linux-libre-2.6.34-gnu1/crypto/api.c
--- linux-libre-2.6.33-gnu1/crypto/api.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/api.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,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; either version 2 of the License, or (at your option) 
+ * Software Foundation; either version 2 of the License, or (at your option)
  * any later version.
  *
  */
@@ -288,11 +288,11 @@ static int crypto_init_ops(struct crypto
 
 	case CRYPTO_ALG_TYPE_COMPRESS:
 		return crypto_init_compress_ops(tfm);
-	
+
 	default:
 		break;
 	}
-	
+
 	BUG();
 	return -EINVAL;
 }
@@ -315,10 +315,9 @@ static void crypto_exit_ops(struct crypt
 	case CRYPTO_ALG_TYPE_COMPRESS:
 		crypto_exit_compress_ops(tfm);
 		break;
-	
+
 	default:
 		BUG();
-		
 	}
 }
 
@@ -593,12 +592,12 @@ int crypto_has_alg(const char *name, u32
 {
 	int ret = 0;
 	struct crypto_alg *alg = crypto_alg_mod_lookup(name, type, mask);
-	
+
 	if (!IS_ERR(alg)) {
 		crypto_mod_put(alg);
 		ret = 1;
 	}
-	
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(crypto_has_alg);
diff -druNp linux-libre-2.6.33-gnu1/crypto/async_tx/async_pq.c linux-libre-2.6.34-gnu1/crypto/async_tx/async_pq.c
--- linux-libre-2.6.33-gnu1/crypto/async_tx/async_pq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/async_tx/async_pq.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/raid/pq.h>
 #include <linux/async_tx.h>
+#include <linux/gfp.h>
 
 /**
  * pq_scribble_page - space to hold throwaway P or Q buffer for
diff -druNp linux-libre-2.6.33-gnu1/crypto/async_tx/async_raid6_recov.c linux-libre-2.6.34-gnu1/crypto/async_tx/async_raid6_recov.c
--- linux-libre-2.6.33-gnu1/crypto/async_tx/async_raid6_recov.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/async_tx/async_raid6_recov.c	2010-05-16 17:17:36.000000000 -0400
@@ -324,6 +324,7 @@ struct dma_async_tx_descriptor *
 async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
 			struct page **blocks, struct async_submit_ctl *submit)
 {
+	void *scribble = submit->scribble;
 	int non_zero_srcs, i;
 
 	BUG_ON(faila == failb);
@@ -332,11 +333,13 @@ async_raid6_2data_recov(int disks, size_
 
 	pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes);
 
-	/* we need to preserve the contents of 'blocks' for the async
-	 * case, so punt to synchronous if a scribble buffer is not available
+	/* if a dma resource is not available or a scribble buffer is not
+	 * available punt to the synchronous path.  In the 'dma not
+	 * available' case be sure to use the scribble buffer to
+	 * preserve the content of 'blocks' as the caller intended.
 	 */
-	if (!submit->scribble) {
-		void **ptrs = (void **) blocks;
+	if (!async_dma_find_channel(DMA_PQ) || !scribble) {
+		void **ptrs = scribble ? scribble : (void **) blocks;
 
 		async_tx_quiesce(&submit->depend_tx);
 		for (i = 0; i < disks; i++)
@@ -406,11 +409,13 @@ async_raid6_datap_recov(int disks, size_
 
 	pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes);
 
-	/* we need to preserve the contents of 'blocks' for the async
-	 * case, so punt to synchronous if a scribble buffer is not available
+	/* if a dma resource is not available or a scribble buffer is not
+	 * available punt to the synchronous path.  In the 'dma not
+	 * available' case be sure to use the scribble buffer to
+	 * preserve the content of 'blocks' as the caller intended.
 	 */
-	if (!scribble) {
-		void **ptrs = (void **) blocks;
+	if (!async_dma_find_channel(DMA_PQ) || !scribble) {
+		void **ptrs = scribble ? scribble : (void **) blocks;
 
 		async_tx_quiesce(&submit->depend_tx);
 		for (i = 0; i < disks; i++)
diff -druNp linux-libre-2.6.33-gnu1/crypto/async_tx/raid6test.c linux-libre-2.6.34-gnu1/crypto/async_tx/raid6test.c
--- linux-libre-2.6.33-gnu1/crypto/async_tx/raid6test.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/async_tx/raid6test.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  *
  */
 #include <linux/async_tx.h>
+#include <linux/gfp.h>
 #include <linux/random.h>
 
 #undef pr
diff -druNp linux-libre-2.6.33-gnu1/crypto/authenc.c linux-libre-2.6.34-gnu1/crypto/authenc.c
--- linux-libre-2.6.33-gnu1/crypto/authenc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/authenc.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,12 @@ struct authenc_request_ctx {
 	char tail[];
 };
 
+static void authenc_request_complete(struct aead_request *req, int err)
+{
+	if (err != -EINPROGRESS)
+		aead_request_complete(req, err);
+}
+
 static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
 				 unsigned int keylen)
 {
@@ -142,7 +148,7 @@ static void authenc_geniv_ahash_update_d
 				 crypto_aead_authsize(authenc), 1);
 
 out:
-	aead_request_complete(req, err);
+	authenc_request_complete(req, err);
 }
 
 static void authenc_geniv_ahash_done(struct crypto_async_request *areq, int err)
@@ -194,7 +200,7 @@ static void authenc_verify_ahash_update_
 	scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
 				 authsize, 0);
 
-	err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG: 0;
+	err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
 	if (err)
 		goto out;
 
@@ -208,7 +214,7 @@ static void authenc_verify_ahash_update_
 	err = crypto_ablkcipher_decrypt(abreq);
 
 out:
-	aead_request_complete(req, err);
+	authenc_request_complete(req, err);
 }
 
 static void authenc_verify_ahash_done(struct crypto_async_request *areq,
@@ -231,7 +237,7 @@ static void authenc_verify_ahash_done(st
 	scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
 				 authsize, 0);
 
-	err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG: 0;
+	err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
 	if (err)
 		goto out;
 
@@ -245,7 +251,7 @@ static void authenc_verify_ahash_done(st
 	err = crypto_ablkcipher_decrypt(abreq);
 
 out:
-	aead_request_complete(req, err);
+	authenc_request_complete(req, err);
 }
 
 static u8 *crypto_authenc_ahash_fb(struct aead_request *req, unsigned int flags)
@@ -379,18 +385,20 @@ static void crypto_authenc_encrypt_done(
 		err = crypto_authenc_genicv(areq, iv, 0);
 	}
 
-	aead_request_complete(areq, err);
+	authenc_request_complete(areq, err);
 }
 
 static int crypto_authenc_encrypt(struct aead_request *req)
 {
 	struct crypto_aead *authenc = crypto_aead_reqtfm(req);
 	struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
-	struct ablkcipher_request *abreq = aead_request_ctx(req);
+	struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
 	struct crypto_ablkcipher *enc = ctx->enc;
 	struct scatterlist *dst = req->dst;
 	unsigned int cryptlen = req->cryptlen;
-	u8 *iv = (u8 *)(abreq + 1) + crypto_ablkcipher_reqsize(enc);
+	struct ablkcipher_request *abreq = (void *)(areq_ctx->tail
+						    + ctx->reqoff);
+	u8 *iv = (u8 *)abreq - crypto_ablkcipher_ivsize(enc);
 	int err;
 
 	ablkcipher_request_set_tfm(abreq, enc);
@@ -418,7 +426,7 @@ static void crypto_authenc_givencrypt_do
 		err = crypto_authenc_genicv(areq, greq->giv, 0);
 	}
 
-	aead_request_complete(areq, err);
+	authenc_request_complete(areq, err);
 }
 
 static int crypto_authenc_givencrypt(struct aead_givcrypt_request *req)
@@ -454,7 +462,7 @@ static int crypto_authenc_verify(struct
 	unsigned int authsize;
 
 	areq_ctx->complete = authenc_verify_ahash_done;
-	areq_ctx->complete = authenc_verify_ahash_update_done;
+	areq_ctx->update_complete = authenc_verify_ahash_update_done;
 
 	ohash = authenc_ahash_fn(req, CRYPTO_TFM_REQ_MAY_SLEEP);
 	if (IS_ERR(ohash))
@@ -464,7 +472,7 @@ static int crypto_authenc_verify(struct
 	ihash = ohash + authsize;
 	scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
 				 authsize, 0);
-	return memcmp(ihash, ohash, authsize) ? -EBADMSG: 0;
+	return memcmp(ihash, ohash, authsize) ? -EBADMSG : 0;
 }
 
 static int crypto_authenc_iverify(struct aead_request *req, u8 *iv,
@@ -546,10 +554,6 @@ static int crypto_authenc_init_tfm(struc
 	if (IS_ERR(auth))
 		return PTR_ERR(auth);
 
-	ctx->reqoff = ALIGN(2 * crypto_ahash_digestsize(auth) +
-			    crypto_ahash_alignmask(auth),
-			    crypto_ahash_alignmask(auth) + 1);
-
 	enc = crypto_spawn_skcipher(&ictx->enc);
 	err = PTR_ERR(enc);
 	if (IS_ERR(enc))
@@ -557,14 +561,19 @@ static int crypto_authenc_init_tfm(struc
 
 	ctx->auth = auth;
 	ctx->enc = enc;
-	
-	tfm->crt_aead.reqsize = max_t(unsigned int,
-				crypto_ahash_reqsize(auth) + ctx->reqoff +
-				sizeof(struct authenc_request_ctx) +
-				sizeof(struct ahash_request), 
+
+	ctx->reqoff = ALIGN(2 * crypto_ahash_digestsize(auth) +
+			    crypto_ahash_alignmask(auth),
+			    crypto_ahash_alignmask(auth) + 1) +
+		      crypto_ablkcipher_ivsize(enc);
+
+	tfm->crt_aead.reqsize = sizeof(struct authenc_request_ctx) +
+				ctx->reqoff +
+				max_t(unsigned int,
+				crypto_ahash_reqsize(auth) +
+				sizeof(struct ahash_request),
 				sizeof(struct skcipher_givcrypt_request) +
-				crypto_ablkcipher_reqsize(enc) +
-				crypto_ablkcipher_ivsize(enc));
+				crypto_ablkcipher_reqsize(enc));
 
 	return 0;
 
diff -druNp linux-libre-2.6.33-gnu1/crypto/blowfish.c linux-libre-2.6.34-gnu1/crypto/blowfish.c
--- linux-libre-2.6.33-gnu1/crypto/blowfish.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/blowfish.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,4 @@
-/* 
+/*
  * Cryptographic API.
  *
  * Blowfish Cipher Algorithm, by Bruce Schneier.
@@ -299,7 +299,7 @@ static const u32 bf_sbox[256 * 4] = {
 	0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
 };
 
-/* 
+/*
  * Round loop unrolling macros, S is a pointer to a S-Box array
  * organized in 4 unsigned longs at a row.
  */
@@ -315,7 +315,7 @@ static const u32 bf_sbox[256 * 4] = {
 
 /*
  * The blowfish encipher, processes 64-bit blocks.
- * NOTE: This function MUSTN'T respect endianess 
+ * NOTE: This function MUSTN'T respect endianess
  */
 static void encrypt_block(struct bf_ctx *bctx, u32 *dst, u32 *src)
 {
@@ -395,7 +395,7 @@ static void bf_decrypt(struct crypto_tfm
 	out_blk[1] = cpu_to_be32(yl);
 }
 
-/* 
+/*
  * Calculates the blowfish S and P boxes for encryption and decryption.
  */
 static int bf_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
@@ -417,10 +417,10 @@ static int bf_setkey(struct crypto_tfm *
 
 	/* Actual subkey generation */
 	for (j = 0, i = 0; i < 16 + 2; i++) {
-		temp = (((u32 )key[j] << 24) |
-			((u32 )key[(j + 1) % keylen] << 16) |
-			((u32 )key[(j + 2) % keylen] << 8) |
-			((u32 )key[(j + 3) % keylen]));
+		temp = (((u32)key[j] << 24) |
+			((u32)key[(j + 1) % keylen] << 16) |
+			((u32)key[(j + 2) % keylen] << 8) |
+			((u32)key[(j + 3) % keylen]));
 
 		P[i] = P[i] ^ temp;
 		j = (j + 4) % keylen;
@@ -444,7 +444,7 @@ static int bf_setkey(struct crypto_tfm *
 			S[count + 1] = data[1];
 		}
 	}
-	
+
 	/* Bruce says not to bother with the weak key check. */
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/crypto/camellia.c linux-libre-2.6.34-gnu1/crypto/camellia.c
--- linux-libre-2.6.33-gnu1/crypto/camellia.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/camellia.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,271 +39,271 @@
 #include <asm/unaligned.h>
 
 static const u32 camellia_sp1110[256] = {
-	0x70707000,0x82828200,0x2c2c2c00,0xececec00,
-	0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
-	0xe4e4e400,0x85858500,0x57575700,0x35353500,
-	0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
-	0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
-	0x45454500,0x19191900,0xa5a5a500,0x21212100,
-	0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
-	0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
-	0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
-	0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
-	0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
-	0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
-	0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
-	0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
-	0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
-	0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
-	0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
-	0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
-	0x74747400,0x12121200,0x2b2b2b00,0x20202000,
-	0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
-	0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
-	0x34343400,0x7e7e7e00,0x76767600,0x05050500,
-	0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
-	0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
-	0x14141400,0x58585800,0x3a3a3a00,0x61616100,
-	0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
-	0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
-	0x53535300,0x18181800,0xf2f2f200,0x22222200,
-	0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
-	0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
-	0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
-	0x60606000,0xfcfcfc00,0x69696900,0x50505000,
-	0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
-	0xa1a1a100,0x89898900,0x62626200,0x97979700,
-	0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
-	0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
-	0x10101000,0xc4c4c400,0x00000000,0x48484800,
-	0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
-	0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
-	0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
-	0x87878700,0x5c5c5c00,0x83838300,0x02020200,
-	0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
-	0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
-	0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
-	0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
-	0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
-	0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
-	0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
-	0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
-	0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
-	0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
-	0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
-	0x78787800,0x98989800,0x06060600,0x6a6a6a00,
-	0xe7e7e700,0x46464600,0x71717100,0xbababa00,
-	0xd4d4d400,0x25252500,0xababab00,0x42424200,
-	0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
-	0x72727200,0x07070700,0xb9b9b900,0x55555500,
-	0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
-	0x36363600,0x49494900,0x2a2a2a00,0x68686800,
-	0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
-	0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
-	0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
-	0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
-	0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
+	0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00,
+	0xb3b3b300, 0x27272700, 0xc0c0c000, 0xe5e5e500,
+	0xe4e4e400, 0x85858500, 0x57575700, 0x35353500,
+	0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100,
+	0x23232300, 0xefefef00, 0x6b6b6b00, 0x93939300,
+	0x45454500, 0x19191900, 0xa5a5a500, 0x21212100,
+	0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00,
+	0x1d1d1d00, 0x65656500, 0x92929200, 0xbdbdbd00,
+	0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00,
+	0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00,
+	0x3e3e3e00, 0x30303000, 0xdcdcdc00, 0x5f5f5f00,
+	0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00,
+	0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00,
+	0xd5d5d500, 0x47474700, 0x5d5d5d00, 0x3d3d3d00,
+	0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600,
+	0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00,
+	0x8b8b8b00, 0x0d0d0d00, 0x9a9a9a00, 0x66666600,
+	0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00,
+	0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000,
+	0xf0f0f000, 0xb1b1b100, 0x84848400, 0x99999900,
+	0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200,
+	0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500,
+	0x6d6d6d00, 0xb7b7b700, 0xa9a9a900, 0x31313100,
+	0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700,
+	0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100,
+	0xdedede00, 0x1b1b1b00, 0x11111100, 0x1c1c1c00,
+	0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600,
+	0x53535300, 0x18181800, 0xf2f2f200, 0x22222200,
+	0xfefefe00, 0x44444400, 0xcfcfcf00, 0xb2b2b200,
+	0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100,
+	0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800,
+	0x60606000, 0xfcfcfc00, 0x69696900, 0x50505000,
+	0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00,
+	0xa1a1a100, 0x89898900, 0x62626200, 0x97979700,
+	0x54545400, 0x5b5b5b00, 0x1e1e1e00, 0x95959500,
+	0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200,
+	0x10101000, 0xc4c4c400, 0x00000000, 0x48484800,
+	0xa3a3a300, 0xf7f7f700, 0x75757500, 0xdbdbdb00,
+	0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00,
+	0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400,
+	0x87878700, 0x5c5c5c00, 0x83838300, 0x02020200,
+	0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300,
+	0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300,
+	0x9d9d9d00, 0x7f7f7f00, 0xbfbfbf00, 0xe2e2e200,
+	0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600,
+	0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00,
+	0x81818100, 0x96969600, 0x6f6f6f00, 0x4b4b4b00,
+	0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00,
+	0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00,
+	0x9f9f9f00, 0x6e6e6e00, 0xbcbcbc00, 0x8e8e8e00,
+	0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600,
+	0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900,
+	0x78787800, 0x98989800, 0x06060600, 0x6a6a6a00,
+	0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00,
+	0xd4d4d400, 0x25252500, 0xababab00, 0x42424200,
+	0x88888800, 0xa2a2a200, 0x8d8d8d00, 0xfafafa00,
+	0x72727200, 0x07070700, 0xb9b9b900, 0x55555500,
+	0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00,
+	0x36363600, 0x49494900, 0x2a2a2a00, 0x68686800,
+	0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400,
+	0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00,
+	0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100,
+	0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400,
+	0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00,
 };
 
 static const u32 camellia_sp0222[256] = {
-	0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
-	0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
-	0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
-	0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
-	0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
-	0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
-	0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
-	0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
-	0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
-	0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
-	0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
-	0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
-	0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
-	0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
-	0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
-	0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
-	0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
-	0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
-	0x00e8e8e8,0x00242424,0x00565656,0x00404040,
-	0x00e1e1e1,0x00636363,0x00090909,0x00333333,
-	0x00bfbfbf,0x00989898,0x00979797,0x00858585,
-	0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
-	0x00dadada,0x006f6f6f,0x00535353,0x00626262,
-	0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
-	0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
-	0x00bdbdbd,0x00363636,0x00222222,0x00383838,
-	0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
-	0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
-	0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
-	0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
-	0x00484848,0x00101010,0x00d1d1d1,0x00515151,
-	0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
-	0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
-	0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
-	0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
-	0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
-	0x00202020,0x00898989,0x00000000,0x00909090,
-	0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
-	0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
-	0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
-	0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
-	0x009b9b9b,0x00949494,0x00212121,0x00666666,
-	0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
-	0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
-	0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
-	0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
-	0x00030303,0x002d2d2d,0x00dedede,0x00969696,
-	0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
-	0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
-	0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
-	0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
-	0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
-	0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
-	0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
-	0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
-	0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
-	0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
-	0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
-	0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
-	0x00787878,0x00707070,0x00e3e3e3,0x00494949,
-	0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
-	0x00777777,0x00939393,0x00868686,0x00838383,
-	0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
-	0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
+	0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9,
+	0x00676767, 0x004e4e4e, 0x00818181, 0x00cbcbcb,
+	0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a,
+	0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282,
+	0x00464646, 0x00dfdfdf, 0x00d6d6d6, 0x00272727,
+	0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242,
+	0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c,
+	0x003a3a3a, 0x00cacaca, 0x00252525, 0x007b7b7b,
+	0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f,
+	0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d,
+	0x007c7c7c, 0x00606060, 0x00b9b9b9, 0x00bebebe,
+	0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434,
+	0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595,
+	0x00ababab, 0x008e8e8e, 0x00bababa, 0x007a7a7a,
+	0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad,
+	0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a,
+	0x00171717, 0x001a1a1a, 0x00353535, 0x00cccccc,
+	0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a,
+	0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040,
+	0x00e1e1e1, 0x00636363, 0x00090909, 0x00333333,
+	0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585,
+	0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a,
+	0x00dadada, 0x006f6f6f, 0x00535353, 0x00626262,
+	0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf,
+	0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2,
+	0x00bdbdbd, 0x00363636, 0x00222222, 0x00383838,
+	0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c,
+	0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444,
+	0x00fdfdfd, 0x00888888, 0x009f9f9f, 0x00656565,
+	0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323,
+	0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151,
+	0x00c0c0c0, 0x00f9f9f9, 0x00d2d2d2, 0x00a0a0a0,
+	0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa,
+	0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f,
+	0x00a8a8a8, 0x00b6b6b6, 0x003c3c3c, 0x002b2b2b,
+	0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5,
+	0x00202020, 0x00898989, 0x00000000, 0x00909090,
+	0x00474747, 0x00efefef, 0x00eaeaea, 0x00b7b7b7,
+	0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5,
+	0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929,
+	0x000f0f0f, 0x00b8b8b8, 0x00070707, 0x00040404,
+	0x009b9b9b, 0x00949494, 0x00212121, 0x00666666,
+	0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7,
+	0x003b3b3b, 0x00fefefe, 0x007f7f7f, 0x00c5c5c5,
+	0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c,
+	0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676,
+	0x00030303, 0x002d2d2d, 0x00dedede, 0x00969696,
+	0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c,
+	0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919,
+	0x003f3f3f, 0x00dcdcdc, 0x00797979, 0x001d1d1d,
+	0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d,
+	0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2,
+	0x00f0f0f0, 0x00313131, 0x000c0c0c, 0x00d4d4d4,
+	0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575,
+	0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484,
+	0x00111111, 0x00454545, 0x001b1b1b, 0x00f5f5f5,
+	0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa,
+	0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414,
+	0x006c6c6c, 0x00929292, 0x00545454, 0x00d0d0d0,
+	0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949,
+	0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6,
+	0x00777777, 0x00939393, 0x00868686, 0x00838383,
+	0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9,
+	0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d,
 };
 
 static const u32 camellia_sp3033[256] = {
-	0x38003838,0x41004141,0x16001616,0x76007676,
-	0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
-	0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
-	0x75007575,0x06000606,0x57005757,0xa000a0a0,
-	0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
-	0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
-	0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
-	0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
-	0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
-	0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
-	0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
-	0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
-	0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
-	0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
-	0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
-	0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
-	0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
-	0xfd00fdfd,0x66006666,0x58005858,0x96009696,
-	0x3a003a3a,0x09000909,0x95009595,0x10001010,
-	0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
-	0xef00efef,0x26002626,0xe500e5e5,0x61006161,
-	0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
-	0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
-	0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
-	0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
-	0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
-	0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
-	0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
-	0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
-	0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
-	0x12001212,0x04000404,0x74007474,0x54005454,
-	0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
-	0x55005555,0x68006868,0x50005050,0xbe00bebe,
-	0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
-	0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
-	0x70007070,0xff00ffff,0x32003232,0x69006969,
-	0x08000808,0x62006262,0x00000000,0x24002424,
-	0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
-	0x45004545,0x81008181,0x73007373,0x6d006d6d,
-	0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
-	0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
-	0xe600e6e6,0x25002525,0x48004848,0x99009999,
-	0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
-	0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
-	0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
-	0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
-	0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
-	0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
-	0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
-	0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
-	0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
-	0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
-	0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
-	0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
-	0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
-	0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
-	0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
-	0x7c007c7c,0x77007777,0x56005656,0x05000505,
-	0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
-	0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
-	0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
-	0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
-	0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
-	0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
+	0x38003838, 0x41004141, 0x16001616, 0x76007676,
+	0xd900d9d9, 0x93009393, 0x60006060, 0xf200f2f2,
+	0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a,
+	0x75007575, 0x06000606, 0x57005757, 0xa000a0a0,
+	0x91009191, 0xf700f7f7, 0xb500b5b5, 0xc900c9c9,
+	0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090,
+	0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727,
+	0x8e008e8e, 0xb200b2b2, 0x49004949, 0xde00dede,
+	0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7,
+	0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767,
+	0x1f001f1f, 0x18001818, 0x6e006e6e, 0xaf00afaf,
+	0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d,
+	0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565,
+	0xea00eaea, 0xa300a3a3, 0xae00aeae, 0x9e009e9e,
+	0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b,
+	0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6,
+	0xc500c5c5, 0x86008686, 0x4d004d4d, 0x33003333,
+	0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696,
+	0x3a003a3a, 0x09000909, 0x95009595, 0x10001010,
+	0x78007878, 0xd800d8d8, 0x42004242, 0xcc00cccc,
+	0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161,
+	0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282,
+	0xb600b6b6, 0xdb00dbdb, 0xd400d4d4, 0x98009898,
+	0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb,
+	0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0,
+	0x6f006f6f, 0x8d008d8d, 0x88008888, 0x0e000e0e,
+	0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b,
+	0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111,
+	0x7f007f7f, 0x22002222, 0xe700e7e7, 0x59005959,
+	0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8,
+	0x12001212, 0x04000404, 0x74007474, 0x54005454,
+	0x30003030, 0x7e007e7e, 0xb400b4b4, 0x28002828,
+	0x55005555, 0x68006868, 0x50005050, 0xbe00bebe,
+	0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb,
+	0x2a002a2a, 0xad00adad, 0x0f000f0f, 0xca00caca,
+	0x70007070, 0xff00ffff, 0x32003232, 0x69006969,
+	0x08000808, 0x62006262, 0x00000000, 0x24002424,
+	0xd100d1d1, 0xfb00fbfb, 0xba00baba, 0xed00eded,
+	0x45004545, 0x81008181, 0x73007373, 0x6d006d6d,
+	0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a,
+	0xc300c3c3, 0x2e002e2e, 0xc100c1c1, 0x01000101,
+	0xe600e6e6, 0x25002525, 0x48004848, 0x99009999,
+	0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9,
+	0xce00cece, 0xbf00bfbf, 0xdf00dfdf, 0x71007171,
+	0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313,
+	0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d,
+	0xc000c0c0, 0x4b004b4b, 0xb700b7b7, 0xa500a5a5,
+	0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717,
+	0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646,
+	0xcf00cfcf, 0x37003737, 0x5e005e5e, 0x47004747,
+	0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b,
+	0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac,
+	0x3c003c3c, 0x4c004c4c, 0x03000303, 0x35003535,
+	0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d,
+	0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121,
+	0x44004444, 0x51005151, 0xc600c6c6, 0x7d007d7d,
+	0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa,
+	0x7c007c7c, 0x77007777, 0x56005656, 0x05000505,
+	0x1b001b1b, 0xa400a4a4, 0x15001515, 0x34003434,
+	0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252,
+	0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd,
+	0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0,
+	0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a,
+	0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f,
 };
 
 static const u32 camellia_sp4404[256] = {
-	0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
-	0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
-	0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
-	0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
-	0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
-	0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
-	0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
-	0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
-	0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
-	0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
-	0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
-	0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
-	0x14140014,0x3a3a003a,0xdede00de,0x11110011,
-	0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
-	0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
-	0x24240024,0xe8e800e8,0x60600060,0x69690069,
-	0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
-	0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
-	0x10100010,0x00000000,0xa3a300a3,0x75750075,
-	0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
-	0x87870087,0x83830083,0xcdcd00cd,0x90900090,
-	0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
-	0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
-	0x81810081,0x6f6f006f,0x13130013,0x63630063,
-	0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
-	0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
-	0x78780078,0x06060006,0xe7e700e7,0x71710071,
-	0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
-	0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
-	0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
-	0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
-	0x15150015,0xadad00ad,0x77770077,0x80800080,
-	0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
-	0x85850085,0x35350035,0x0c0c000c,0x41410041,
-	0xefef00ef,0x93930093,0x19190019,0x21210021,
-	0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
-	0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
-	0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
-	0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
-	0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
-	0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
-	0x12120012,0x20200020,0xb1b100b1,0x99990099,
-	0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
-	0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
-	0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
-	0x0f0f000f,0x16160016,0x18180018,0x22220022,
-	0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
-	0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
-	0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
-	0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
-	0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
-	0x03030003,0xdada00da,0x3f3f003f,0x94940094,
-	0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
-	0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
-	0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
-	0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
-	0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
-	0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
-	0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
-	0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
-	0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
-	0x49490049,0x68680068,0x38380038,0xa4a400a4,
-	0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
-	0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
+	0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0,
+	0xe4e400e4, 0x57570057, 0xeaea00ea, 0xaeae00ae,
+	0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5,
+	0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092,
+	0x86860086, 0xafaf00af, 0x7c7c007c, 0x1f1f001f,
+	0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b,
+	0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d,
+	0xd9d900d9, 0x5a5a005a, 0x51510051, 0x6c6c006c,
+	0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0,
+	0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084,
+	0xdfdf00df, 0xcbcb00cb, 0x34340034, 0x76760076,
+	0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004,
+	0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011,
+	0x32320032, 0x9c9c009c, 0x53530053, 0xf2f200f2,
+	0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a,
+	0x24240024, 0xe8e800e8, 0x60600060, 0x69690069,
+	0xaaaa00aa, 0xa0a000a0, 0xa1a100a1, 0x62620062,
+	0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064,
+	0x10100010, 0x00000000, 0xa3a300a3, 0x75750075,
+	0x8a8a008a, 0xe6e600e6, 0x09090009, 0xdddd00dd,
+	0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090,
+	0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf,
+	0x52520052, 0xd8d800d8, 0xc8c800c8, 0xc6c600c6,
+	0x81810081, 0x6f6f006f, 0x13130013, 0x63630063,
+	0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc,
+	0x29290029, 0xf9f900f9, 0x2f2f002f, 0xb4b400b4,
+	0x78780078, 0x06060006, 0xe7e700e7, 0x71710071,
+	0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d,
+	0x72720072, 0xb9b900b9, 0xf8f800f8, 0xacac00ac,
+	0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1,
+	0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043,
+	0x15150015, 0xadad00ad, 0x77770077, 0x80800080,
+	0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5,
+	0x85850085, 0x35350035, 0x0c0c000c, 0x41410041,
+	0xefef00ef, 0x93930093, 0x19190019, 0x21210021,
+	0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd,
+	0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce,
+	0x30300030, 0x5f5f005f, 0xc5c500c5, 0x1a1a001a,
+	0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d,
+	0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d,
+	0x0d0d000d, 0x66660066, 0xcccc00cc, 0x2d2d002d,
+	0x12120012, 0x20200020, 0xb1b100b1, 0x99990099,
+	0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005,
+	0xb7b700b7, 0x31310031, 0x17170017, 0xd7d700d7,
+	0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c,
+	0x0f0f000f, 0x16160016, 0x18180018, 0x22220022,
+	0x44440044, 0xb2b200b2, 0xb5b500b5, 0x91910091,
+	0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050,
+	0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097,
+	0x5b5b005b, 0x95950095, 0xffff00ff, 0xd2d200d2,
+	0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db,
+	0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094,
+	0x5c5c005c, 0x02020002, 0x4a4a004a, 0x33330033,
+	0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2,
+	0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b,
+	0x96960096, 0x4b4b004b, 0xbebe00be, 0x2e2e002e,
+	0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e,
+	0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059,
+	0x98980098, 0x6a6a006a, 0x46460046, 0xbaba00ba,
+	0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa,
+	0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a,
+	0x49490049, 0x68680068, 0x38380038, 0xa4a400a4,
+	0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1,
+	0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e,
 };
 
 
@@ -344,7 +344,7 @@ static const u32 camellia_sp4404[256] =
 	lr = (lr << bits) + (rl >> (32 - bits));	\
 	rl = (rl << bits) + (rr >> (32 - bits));	\
 	rr = (rr << bits) + (w0 >> (32 - bits));	\
-    } while(0)
+    } while (0)
 
 #define ROLDQo32(ll, lr, rl, rr, w0, w1, bits)		\
     do {						\
@@ -354,7 +354,7 @@ static const u32 camellia_sp4404[256] =
 	lr = (rl << (bits - 32)) + (rr >> (64 - bits));	\
 	rl = (rr << (bits - 32)) + (w0 >> (64 - bits));	\
 	rr = (w0 << (bits - 32)) + (w1 >> (64 - bits));	\
-    } while(0)
+    } while (0)
 
 #define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)	\
     do {							\
@@ -373,7 +373,7 @@ static const u32 camellia_sp4404[256] =
 	yl ^= yr;						\
 	yr = ror32(yr, 8);					\
 	yr ^= yl;						\
-    } while(0)
+    } while (0)
 
 #define SUBKEY_L(INDEX) (subkey[(INDEX)*2])
 #define SUBKEY_R(INDEX) (subkey[(INDEX)*2 + 1])
@@ -835,7 +835,7 @@ static void camellia_setup256(const unsi
 static void camellia_setup192(const unsigned char *key, u32 *subkey)
 {
 	unsigned char kk[32];
-	u32 krll, krlr, krrl,krrr;
+	u32 krll, krlr, krrl, krrr;
 
 	memcpy(kk, key, 24);
 	memcpy((unsigned char *)&krll, key+16, 4);
@@ -865,7 +865,7 @@ static void camellia_setup192(const unsi
 	t1 |= lr;							\
 	ll ^= t1;							\
 	rr ^= rol32(t3, 1);						\
-    } while(0)
+    } while (0)
 
 #define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir)		\
     do {								\
@@ -881,12 +881,12 @@ static void camellia_setup192(const unsi
 	ir ^= il ^ kr;							\
 	yl ^= ir;							\
 	yr ^= ror32(il, 8) ^ ir;						\
-    } while(0)
+    } while (0)
 
 /* max = 24: 128bit encrypt, max = 32: 256bit encrypt */
 static void camellia_do_encrypt(const u32 *subkey, u32 *io, unsigned max)
 {
-	u32 il,ir,t0,t1;               /* temporary variables */
+	u32 il, ir, t0, t1;            /* temporary variables */
 
 	/* pre whitening but absorb kw2 */
 	io[0] ^= SUBKEY_L(0);
@@ -894,30 +894,30 @@ static void camellia_do_encrypt(const u3
 
 	/* main iteration */
 #define ROUNDS(i) do { \
-	CAMELLIA_ROUNDSM(io[0],io[1], \
-			 SUBKEY_L(i + 2),SUBKEY_R(i + 2), \
-			 io[2],io[3],il,ir); \
-	CAMELLIA_ROUNDSM(io[2],io[3], \
-			 SUBKEY_L(i + 3),SUBKEY_R(i + 3), \
-			 io[0],io[1],il,ir); \
-	CAMELLIA_ROUNDSM(io[0],io[1], \
-			 SUBKEY_L(i + 4),SUBKEY_R(i + 4), \
-			 io[2],io[3],il,ir); \
-	CAMELLIA_ROUNDSM(io[2],io[3], \
-			 SUBKEY_L(i + 5),SUBKEY_R(i + 5), \
-			 io[0],io[1],il,ir); \
-	CAMELLIA_ROUNDSM(io[0],io[1], \
-			 SUBKEY_L(i + 6),SUBKEY_R(i + 6), \
-			 io[2],io[3],il,ir); \
-	CAMELLIA_ROUNDSM(io[2],io[3], \
-			 SUBKEY_L(i + 7),SUBKEY_R(i + 7), \
-			 io[0],io[1],il,ir); \
+	CAMELLIA_ROUNDSM(io[0], io[1], \
+			 SUBKEY_L(i + 2), SUBKEY_R(i + 2), \
+			 io[2], io[3], il, ir); \
+	CAMELLIA_ROUNDSM(io[2], io[3], \
+			 SUBKEY_L(i + 3), SUBKEY_R(i + 3), \
+			 io[0], io[1], il, ir); \
+	CAMELLIA_ROUNDSM(io[0], io[1], \
+			 SUBKEY_L(i + 4), SUBKEY_R(i + 4), \
+			 io[2], io[3], il, ir); \
+	CAMELLIA_ROUNDSM(io[2], io[3], \
+			 SUBKEY_L(i + 5), SUBKEY_R(i + 5), \
+			 io[0], io[1], il, ir); \
+	CAMELLIA_ROUNDSM(io[0], io[1], \
+			 SUBKEY_L(i + 6), SUBKEY_R(i + 6), \
+			 io[2], io[3], il, ir); \
+	CAMELLIA_ROUNDSM(io[2], io[3], \
+			 SUBKEY_L(i + 7), SUBKEY_R(i + 7), \
+			 io[0], io[1], il, ir); \
 } while (0)
 #define FLS(i) do { \
-	CAMELLIA_FLS(io[0],io[1],io[2],io[3], \
-		     SUBKEY_L(i + 0),SUBKEY_R(i + 0), \
-		     SUBKEY_L(i + 1),SUBKEY_R(i + 1), \
-		     t0,t1,il,ir); \
+	CAMELLIA_FLS(io[0], io[1], io[2], io[3], \
+		     SUBKEY_L(i + 0), SUBKEY_R(i + 0), \
+		     SUBKEY_L(i + 1), SUBKEY_R(i + 1), \
+		     t0, t1, il, ir); \
 } while (0)
 
 	ROUNDS(0);
@@ -941,7 +941,7 @@ static void camellia_do_encrypt(const u3
 
 static void camellia_do_decrypt(const u32 *subkey, u32 *io, unsigned i)
 {
-	u32 il,ir,t0,t1;               /* temporary variables */
+	u32 il, ir, t0, t1;            /* temporary variables */
 
 	/* pre whitening but absorb kw2 */
 	io[0] ^= SUBKEY_L(i);
@@ -949,30 +949,30 @@ static void camellia_do_decrypt(const u3
 
 	/* main iteration */
 #define ROUNDS(i) do { \
-	CAMELLIA_ROUNDSM(io[0],io[1], \
-			 SUBKEY_L(i + 7),SUBKEY_R(i + 7), \
-			 io[2],io[3],il,ir); \
-	CAMELLIA_ROUNDSM(io[2],io[3], \
-			 SUBKEY_L(i + 6),SUBKEY_R(i + 6), \
-			 io[0],io[1],il,ir); \
-	CAMELLIA_ROUNDSM(io[0],io[1], \
-			 SUBKEY_L(i + 5),SUBKEY_R(i + 5), \
-			 io[2],io[3],il,ir); \
-	CAMELLIA_ROUNDSM(io[2],io[3], \
-			 SUBKEY_L(i + 4),SUBKEY_R(i + 4), \
-			 io[0],io[1],il,ir); \
-	CAMELLIA_ROUNDSM(io[0],io[1], \
-			 SUBKEY_L(i + 3),SUBKEY_R(i + 3), \
-			 io[2],io[3],il,ir); \
-	CAMELLIA_ROUNDSM(io[2],io[3], \
-			 SUBKEY_L(i + 2),SUBKEY_R(i + 2), \
-			 io[0],io[1],il,ir); \
+	CAMELLIA_ROUNDSM(io[0], io[1], \
+			 SUBKEY_L(i + 7), SUBKEY_R(i + 7), \
+			 io[2], io[3], il, ir); \
+	CAMELLIA_ROUNDSM(io[2], io[3], \
+			 SUBKEY_L(i + 6), SUBKEY_R(i + 6), \
+			 io[0], io[1], il, ir); \
+	CAMELLIA_ROUNDSM(io[0], io[1], \
+			 SUBKEY_L(i + 5), SUBKEY_R(i + 5), \
+			 io[2], io[3], il, ir); \
+	CAMELLIA_ROUNDSM(io[2], io[3], \
+			 SUBKEY_L(i + 4), SUBKEY_R(i + 4), \
+			 io[0], io[1], il, ir); \
+	CAMELLIA_ROUNDSM(io[0], io[1], \
+			 SUBKEY_L(i + 3), SUBKEY_R(i + 3), \
+			 io[2], io[3], il, ir); \
+	CAMELLIA_ROUNDSM(io[2], io[3], \
+			 SUBKEY_L(i + 2), SUBKEY_R(i + 2), \
+			 io[0], io[1], il, ir); \
 } while (0)
 #define FLS(i) do { \
-	CAMELLIA_FLS(io[0],io[1],io[2],io[3], \
-		     SUBKEY_L(i + 1),SUBKEY_R(i + 1), \
-		     SUBKEY_L(i + 0),SUBKEY_R(i + 0), \
-		     t0,t1,il,ir); \
+	CAMELLIA_FLS(io[0], io[1], io[2], io[3], \
+		     SUBKEY_L(i + 1), SUBKEY_R(i + 1), \
+		     SUBKEY_L(i + 0), SUBKEY_R(i + 0), \
+		     t0, t1, il, ir); \
 } while (0)
 
 	if (i == 32) {
diff -druNp linux-libre-2.6.33-gnu1/crypto/cast5.c linux-libre-2.6.34-gnu1/crypto/cast5.c
--- linux-libre-2.6.33-gnu1/crypto/cast5.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/cast5.c	2010-05-16 17:17:36.000000000 -0400
@@ -569,12 +569,12 @@ static const u32 sb8[256] = {
 	0xeaee6801, 0x8db2a283, 0xea8bf59e
 };
 
-#define F1(D,m,r)  (  (I = ((m) + (D))), (I=rol32(I,(r))),   \
-    (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) )
-#define F2(D,m,r)  (  (I = ((m) ^ (D))), (I=rol32(I,(r))),   \
-    (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) )
-#define F3(D,m,r)  (  (I = ((m) - (D))), (I=rol32(I,(r))),   \
-    (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
+#define F1(D, m, r)  ((I = ((m) + (D))), (I = rol32(I, (r))),   \
+    (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]))
+#define F2(D, m, r)  ((I = ((m) ^ (D))), (I = rol32(I, (r))),   \
+    (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]))
+#define F3(D, m, r)  ((I = ((m) - (D))), (I = rol32(I, (r))),   \
+    (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]))
 
 
 static void cast5_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
@@ -694,7 +694,7 @@ static void cast5_decrypt(struct crypto_
 	dst[1] = cpu_to_be32(l);
 }
 
-static void key_schedule(u32 * x, u32 * z, u32 * k)
+static void key_schedule(u32 *x, u32 *z, u32 *k)
 {
 
 #define xi(i)   ((x[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
diff -druNp linux-libre-2.6.33-gnu1/crypto/cast6.c linux-libre-2.6.34-gnu1/crypto/cast6.c
--- linux-libre-2.6.33-gnu1/crypto/cast6.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/cast6.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
  * under the terms of 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
@@ -35,12 +35,12 @@ struct cast6_ctx {
 	u8 Kr[12][4];
 };
 
-#define F1(D,r,m)  (  (I = ((m) + (D))), (I=rol32(I,(r))),   \
-    (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) )
-#define F2(D,r,m)  (  (I = ((m) ^ (D))), (I=rol32(I,(r))),   \
-    (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) )
-#define F3(D,r,m)  (  (I = ((m) - (D))), (I=rol32(I,(r))),   \
-    (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
+#define F1(D, r, m)  ((I = ((m) + (D))), (I = rol32(I, (r))),   \
+    (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]))
+#define F2(D, r, m)  ((I = ((m) ^ (D))), (I = rol32(I, (r))),   \
+    (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]))
+#define F3(D, r, m)  ((I = ((m) - (D))), (I = rol32(I, (r))),   \
+    (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]))
 
 static const u32 s1[256] = {
 	0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f,
@@ -312,7 +312,7 @@ static const u32 s4[256] = {
 
 static const u32 Tm[24][8] = {
 	{ 0x5a827999, 0xc95c653a, 0x383650db, 0xa7103c7c, 0x15ea281d,
-		0x84c413be, 0xf39dff5f, 0x6277eb00 } , 
+		0x84c413be, 0xf39dff5f, 0x6277eb00 } ,
 	{ 0xd151d6a1, 0x402bc242, 0xaf05ade3, 0x1ddf9984, 0x8cb98525,
 		0xfb9370c6, 0x6a6d5c67, 0xd9474808 } ,
 	{ 0x482133a9, 0xb6fb1f4a, 0x25d50aeb, 0x94aef68c, 0x0388e22d,
@@ -369,7 +369,8 @@ static const u8 Tr[4][8] = {
 };
 
 /* forward octave */
-static void W(u32 *key, unsigned int i) {
+static void W(u32 *key, unsigned int i)
+{
 	u32 I;
 	key[6] ^= F1(key[7], Tr[i % 4][0], Tm[i][0]);
 	key[5] ^= F2(key[6], Tr[i % 4][1], Tm[i][1]);
@@ -377,7 +378,7 @@ static void W(u32 *key, unsigned int i)
 	key[3] ^= F1(key[4], Tr[i % 4][3], Tm[i][3]);
 	key[2] ^= F2(key[3], Tr[i % 4][4], Tm[i][4]);
 	key[1] ^= F3(key[2], Tr[i % 4][5], Tm[i][5]);
-	key[0] ^= F1(key[1], Tr[i % 4][6], Tm[i][6]);	
+	key[0] ^= F1(key[1], Tr[i % 4][6], Tm[i][6]);
 	key[7] ^= F2(key[0], Tr[i % 4][7], Tm[i][7]);
 }
 
@@ -393,11 +394,11 @@ static int cast6_setkey(struct crypto_tf
 	if (key_len % 4 != 0) {
 		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
 		return -EINVAL;
-	}	
+	}
+
+	memset(p_key, 0, 32);
+	memcpy(p_key, in_key, key_len);
 
-	memset (p_key, 0, 32);
-	memcpy (p_key, in_key, key_len);
-	
 	key[0] = be32_to_cpu(p_key[0]);		/* A */
 	key[1] = be32_to_cpu(p_key[1]);		/* B */
 	key[2] = be32_to_cpu(p_key[2]);		/* C */
@@ -406,18 +407,16 @@ static int cast6_setkey(struct crypto_tf
 	key[5] = be32_to_cpu(p_key[5]);		/* F */
 	key[6] = be32_to_cpu(p_key[6]);		/* G */
 	key[7] = be32_to_cpu(p_key[7]);		/* H */
-	
-
 
 	for (i = 0; i < 12; i++) {
-		W (key, 2 * i);
-		W (key, 2 * i + 1);
-		
+		W(key, 2 * i);
+		W(key, 2 * i + 1);
+
 		c->Kr[i][0] = key[0] & 0x1f;
 		c->Kr[i][1] = key[2] & 0x1f;
 		c->Kr[i][2] = key[4] & 0x1f;
 		c->Kr[i][3] = key[6] & 0x1f;
-		
+
 		c->Km[i][0] = key[7];
 		c->Km[i][1] = key[5];
 		c->Km[i][2] = key[3];
@@ -428,21 +427,23 @@ static int cast6_setkey(struct crypto_tf
 }
 
 /*forward quad round*/
-static void Q (u32 * block, u8 * Kr, u32 * Km) {
+static void Q(u32 *block, u8 *Kr, u32 *Km)
+{
 	u32 I;
 	block[2] ^= F1(block[3], Kr[0], Km[0]);
 	block[1] ^= F2(block[2], Kr[1], Km[1]);
 	block[0] ^= F3(block[1], Kr[2], Km[2]);
-	block[3] ^= F1(block[0], Kr[3], Km[3]);		
+	block[3] ^= F1(block[0], Kr[3], Km[3]);
 }
 
 /*reverse quad round*/
-static void QBAR (u32 * block, u8 * Kr, u32 * Km) {
+static void QBAR(u32 *block, u8 *Kr, u32 *Km)
+{
 	u32 I;
-        block[3] ^= F1(block[0], Kr[3], Km[3]);
-        block[0] ^= F3(block[1], Kr[2], Km[2]);
-        block[1] ^= F2(block[2], Kr[1], Km[1]);
-        block[2] ^= F1(block[3], Kr[0], Km[0]);
+	block[3] ^= F1(block[0], Kr[3], Km[3]);
+	block[0] ^= F3(block[1], Kr[2], Km[2]);
+	block[1] ^= F2(block[2], Kr[1], Km[1]);
+	block[2] ^= F1(block[3], Kr[0], Km[0]);
 }
 
 static void cast6_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
@@ -451,64 +452,65 @@ static void cast6_encrypt(struct crypto_
 	const __be32 *src = (const __be32 *)inbuf;
 	__be32 *dst = (__be32 *)outbuf;
 	u32 block[4];
-	u32 * Km; 
-	u8 * Kr;
+	u32 *Km;
+	u8 *Kr;
 
 	block[0] = be32_to_cpu(src[0]);
 	block[1] = be32_to_cpu(src[1]);
 	block[2] = be32_to_cpu(src[2]);
 	block[3] = be32_to_cpu(src[3]);
 
-	Km = c->Km[0]; Kr = c->Kr[0]; Q (block, Kr, Km);
-	Km = c->Km[1]; Kr = c->Kr[1]; Q (block, Kr, Km);
-	Km = c->Km[2]; Kr = c->Kr[2]; Q (block, Kr, Km);
-	Km = c->Km[3]; Kr = c->Kr[3]; Q (block, Kr, Km);
-	Km = c->Km[4]; Kr = c->Kr[4]; Q (block, Kr, Km);
-	Km = c->Km[5]; Kr = c->Kr[5]; Q (block, Kr, Km);
-	Km = c->Km[6]; Kr = c->Kr[6]; QBAR (block, Kr, Km);
-	Km = c->Km[7]; Kr = c->Kr[7]; QBAR (block, Kr, Km);
-	Km = c->Km[8]; Kr = c->Kr[8]; QBAR (block, Kr, Km);
-	Km = c->Km[9]; Kr = c->Kr[9]; QBAR (block, Kr, Km);
-	Km = c->Km[10]; Kr = c->Kr[10]; QBAR (block, Kr, Km);
-	Km = c->Km[11]; Kr = c->Kr[11]; QBAR (block, Kr, Km);
+	Km = c->Km[0]; Kr = c->Kr[0]; Q(block, Kr, Km);
+	Km = c->Km[1]; Kr = c->Kr[1]; Q(block, Kr, Km);
+	Km = c->Km[2]; Kr = c->Kr[2]; Q(block, Kr, Km);
+	Km = c->Km[3]; Kr = c->Kr[3]; Q(block, Kr, Km);
+	Km = c->Km[4]; Kr = c->Kr[4]; Q(block, Kr, Km);
+	Km = c->Km[5]; Kr = c->Kr[5]; Q(block, Kr, Km);
+	Km = c->Km[6]; Kr = c->Kr[6]; QBAR(block, Kr, Km);
+	Km = c->Km[7]; Kr = c->Kr[7]; QBAR(block, Kr, Km);
+	Km = c->Km[8]; Kr = c->Kr[8]; QBAR(block, Kr, Km);
+	Km = c->Km[9]; Kr = c->Kr[9]; QBAR(block, Kr, Km);
+	Km = c->Km[10]; Kr = c->Kr[10]; QBAR(block, Kr, Km);
+	Km = c->Km[11]; Kr = c->Kr[11]; QBAR(block, Kr, Km);
 
 	dst[0] = cpu_to_be32(block[0]);
 	dst[1] = cpu_to_be32(block[1]);
 	dst[2] = cpu_to_be32(block[2]);
 	dst[3] = cpu_to_be32(block[3]);
-}	
+}
 
-static void cast6_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf) {
-	struct cast6_ctx * c = crypto_tfm_ctx(tfm);
+static void cast6_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
+{
+	struct cast6_ctx *c = crypto_tfm_ctx(tfm);
 	const __be32 *src = (const __be32 *)inbuf;
 	__be32 *dst = (__be32 *)outbuf;
 	u32 block[4];
-	u32 * Km; 
-	u8 * Kr;
+	u32 *Km;
+	u8 *Kr;
 
 	block[0] = be32_to_cpu(src[0]);
 	block[1] = be32_to_cpu(src[1]);
 	block[2] = be32_to_cpu(src[2]);
 	block[3] = be32_to_cpu(src[3]);
 
-	Km = c->Km[11]; Kr = c->Kr[11]; Q (block, Kr, Km);
-	Km = c->Km[10]; Kr = c->Kr[10]; Q (block, Kr, Km);
-	Km = c->Km[9]; Kr = c->Kr[9]; Q (block, Kr, Km);
-	Km = c->Km[8]; Kr = c->Kr[8]; Q (block, Kr, Km);
-	Km = c->Km[7]; Kr = c->Kr[7]; Q (block, Kr, Km);
-	Km = c->Km[6]; Kr = c->Kr[6]; Q (block, Kr, Km);
-	Km = c->Km[5]; Kr = c->Kr[5]; QBAR (block, Kr, Km);
-	Km = c->Km[4]; Kr = c->Kr[4]; QBAR (block, Kr, Km);
-	Km = c->Km[3]; Kr = c->Kr[3]; QBAR (block, Kr, Km);
-	Km = c->Km[2]; Kr = c->Kr[2]; QBAR (block, Kr, Km);
-	Km = c->Km[1]; Kr = c->Kr[1]; QBAR (block, Kr, Km);
-	Km = c->Km[0]; Kr = c->Kr[0]; QBAR (block, Kr, Km);
-	
+	Km = c->Km[11]; Kr = c->Kr[11]; Q(block, Kr, Km);
+	Km = c->Km[10]; Kr = c->Kr[10]; Q(block, Kr, Km);
+	Km = c->Km[9]; Kr = c->Kr[9]; Q(block, Kr, Km);
+	Km = c->Km[8]; Kr = c->Kr[8]; Q(block, Kr, Km);
+	Km = c->Km[7]; Kr = c->Kr[7]; Q(block, Kr, Km);
+	Km = c->Km[6]; Kr = c->Kr[6]; Q(block, Kr, Km);
+	Km = c->Km[5]; Kr = c->Kr[5]; QBAR(block, Kr, Km);
+	Km = c->Km[4]; Kr = c->Kr[4]; QBAR(block, Kr, Km);
+	Km = c->Km[3]; Kr = c->Kr[3]; QBAR(block, Kr, Km);
+	Km = c->Km[2]; Kr = c->Kr[2]; QBAR(block, Kr, Km);
+	Km = c->Km[1]; Kr = c->Kr[1]; QBAR(block, Kr, Km);
+	Km = c->Km[0]; Kr = c->Kr[0]; QBAR(block, Kr, Km);
+
 	dst[0] = cpu_to_be32(block[0]);
 	dst[1] = cpu_to_be32(block[1]);
 	dst[2] = cpu_to_be32(block[2]);
 	dst[3] = cpu_to_be32(block[3]);
-}	
+}
 
 static struct crypto_alg alg = {
 	.cra_name = "cast6",
diff -druNp linux-libre-2.6.33-gnu1/crypto/cipher.c linux-libre-2.6.34-gnu1/crypto/cipher.c
--- linux-libre-2.6.33-gnu1/crypto/cipher.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/cipher.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,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; either version 2 of the License, or (at your option) 
+ * Software Foundation; either version 2 of the License, or (at your option)
  * any later version.
  *
  */
diff -druNp linux-libre-2.6.33-gnu1/crypto/compress.c linux-libre-2.6.34-gnu1/crypto/compress.c
--- linux-libre-2.6.33-gnu1/crypto/compress.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/compress.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,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; either version 2 of the License, or (at your option) 
+ * Software Foundation; either version 2 of the License, or (at your option)
  * any later version.
  *
  */
@@ -39,7 +39,7 @@ int crypto_init_compress_ops(struct cryp
 
 	ops->cot_compress = crypto_compress;
 	ops->cot_decompress = crypto_decompress;
-	
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/crypto/crc32c.c linux-libre-2.6.34-gnu1/crypto/crc32c.c
--- linux-libre-2.6.33-gnu1/crypto/crc32c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/crc32c.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,4 @@
-/* 
+/*
  * Cryptographic API.
  *
  * CRC32C chksum
@@ -30,7 +30,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; either version 2 of the License, or (at your option) 
+ * Software Foundation; either version 2 of the License, or (at your option)
  * any later version.
  *
  */
@@ -142,7 +142,7 @@ static u32 crc32c(u32 crc, const u8 *dat
 }
 
 /*
- * Steps through buffer one byte at at time, calculates reflected 
+ * Steps through buffer one byte at at time, calculates reflected
  * crc using table.
  */
 
diff -druNp linux-libre-2.6.33-gnu1/crypto/cryptd.c linux-libre-2.6.34-gnu1/crypto/cryptd.c
--- linux-libre-2.6.33-gnu1/crypto/cryptd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/cryptd.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,7 @@ struct cryptd_cpu_queue {
 };
 
 struct cryptd_queue {
-	struct cryptd_cpu_queue *cpu_queue;
+	struct cryptd_cpu_queue __percpu *cpu_queue;
 };
 
 struct cryptd_instance_ctx {
diff -druNp linux-libre-2.6.33-gnu1/crypto/crypto_null.c linux-libre-2.6.34-gnu1/crypto/crypto_null.c
--- linux-libre-2.6.33-gnu1/crypto/crypto_null.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/crypto_null.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,11 +1,11 @@
-/* 
+/*
  * Cryptographic API.
  *
  * Null algorithms, aka Much Ado About Nothing.
  *
  * These are needed for IPsec, and may be useful in general for
  * testing & debugging.
- * 
+ *
  * The null cipher is compliant with RFC2410.
  *
  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
@@ -163,7 +163,7 @@ MODULE_ALIAS("cipher_null");
 static int __init crypto_null_mod_init(void)
 {
 	int ret = 0;
-	
+
 	ret = crypto_register_alg(&cipher_null);
 	if (ret < 0)
 		goto out;
@@ -180,7 +180,7 @@ static int __init crypto_null_mod_init(v
 	if (ret < 0)
 		goto out_unregister_digest;
 
-out:	
+out:
 	return ret;
 
 out_unregister_digest:
diff -druNp linux-libre-2.6.33-gnu1/crypto/deflate.c linux-libre-2.6.34-gnu1/crypto/deflate.c
--- linux-libre-2.6.33-gnu1/crypto/deflate.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/deflate.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,14 +1,14 @@
-/* 
+/*
  * Cryptographic API.
  *
  * Deflate algorithm (RFC 1951), implemented here primarily for use
  * by IPCOMP (RFC 3173 & RFC 2394).
  *
  * 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) 
+ * 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
@@ -49,7 +49,7 @@ static int deflate_comp_init(struct defl
 	struct z_stream_s *stream = &ctx->comp_stream;
 
 	stream->workspace = vmalloc(zlib_deflate_workspacesize());
-	if (!stream->workspace ) {
+	if (!stream->workspace) {
 		ret = -ENOMEM;
 		goto out;
 	}
@@ -61,7 +61,7 @@ static int deflate_comp_init(struct defl
 		ret = -EINVAL;
 		goto out_free;
 	}
-out:	
+out:
 	return ret;
 out_free:
 	vfree(stream->workspace);
@@ -74,7 +74,7 @@ static int deflate_decomp_init(struct de
 	struct z_stream_s *stream = &ctx->decomp_stream;
 
 	stream->workspace = kzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
-	if (!stream->workspace ) {
+	if (!stream->workspace) {
 		ret = -ENOMEM;
 		goto out;
 	}
@@ -106,7 +106,7 @@ static int deflate_init(struct crypto_tf
 {
 	struct deflate_ctx *ctx = crypto_tfm_ctx(tfm);
 	int ret;
-	
+
 	ret = deflate_comp_init(ctx);
 	if (ret)
 		goto out;
@@ -153,11 +153,11 @@ static int deflate_compress(struct crypt
 out:
 	return ret;
 }
- 
+
 static int deflate_decompress(struct crypto_tfm *tfm, const u8 *src,
 			      unsigned int slen, u8 *dst, unsigned int *dlen)
 {
-	
+
 	int ret = 0;
 	struct deflate_ctx *dctx = crypto_tfm_ctx(tfm);
 	struct z_stream_s *stream = &dctx->decomp_stream;
@@ -182,7 +182,7 @@ static int deflate_decompress(struct cry
 	if (ret == Z_OK && !stream->avail_in && stream->avail_out) {
 		u8 zerostuff = 0;
 		stream->next_in = &zerostuff;
-		stream->avail_in = 1; 
+		stream->avail_in = 1;
 		ret = zlib_inflate(stream, Z_FINISH);
 	}
 	if (ret != Z_STREAM_END) {
diff -druNp linux-libre-2.6.33-gnu1/crypto/des_generic.c linux-libre-2.6.34-gnu1/crypto/des_generic.c
--- linux-libre-2.6.33-gnu1/crypto/des_generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/des_generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -869,8 +869,7 @@ static int des3_ede_setkey(struct crypto
 
 	if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
 		     !((K[2] ^ K[4]) | (K[3] ^ K[5]))) &&
-		     (*flags & CRYPTO_TFM_REQ_WEAK_KEY))
-	{
+		     (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
 		*flags |= CRYPTO_TFM_RES_WEAK_KEY;
 		return -EINVAL;
 	}
diff -druNp linux-libre-2.6.33-gnu1/crypto/ecb.c linux-libre-2.6.34-gnu1/crypto/ecb.c
--- linux-libre-2.6.33-gnu1/crypto/ecb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/ecb.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,7 +55,7 @@ static int crypto_ecb_crypt(struct blkci
 
 		do {
 			fn(crypto_cipher_tfm(tfm), wdst, wsrc);
-	
+
 			wsrc += bsize;
 			wdst += bsize;
 		} while ((nbytes -= bsize) >= bsize);
diff -druNp linux-libre-2.6.33-gnu1/crypto/fcrypt.c linux-libre-2.6.34-gnu1/crypto/fcrypt.c
--- linux-libre-2.6.33-gnu1/crypto/fcrypt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/fcrypt.c	2010-05-16 17:17:36.000000000 -0400
@@ -60,13 +60,13 @@ do {								\
 	u32 t = lo & ((1 << n) - 1);				\
 	lo = (lo >> n) | ((hi & ((1 << n) - 1)) << (32 - n));	\
 	hi = (hi >> n) | (t << (24-n));				\
-} while(0)
+} while (0)
 
 /* Rotate right one 64 bit number as a 56 bit number */
 #define ror56_64(k, n)						\
 do {								\
 	k = (k >> n) | ((k & ((1 << n) - 1)) << (56 - n));	\
-} while(0)
+} while (0)
 
 /*
  * Sboxes for Feistel network derived from
@@ -228,7 +228,7 @@ do {									\
 	union lc4 { __be32 l; u8 c[4]; } u;				\
 	u.l = sched ^ R;						\
 	L ^= sbox0[u.c[0]] ^ sbox1[u.c[1]] ^ sbox2[u.c[2]] ^ sbox3[u.c[3]]; \
-} while(0)
+} while (0)
 
 /*
  * encryptor
diff -druNp linux-libre-2.6.33-gnu1/crypto/gcm.c linux-libre-2.6.34-gnu1/crypto/gcm.c
--- linux-libre-2.6.33-gnu1/crypto/gcm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/gcm.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,19 @@ struct crypto_rfc4106_ctx {
 	u8 nonce[4];
 };
 
+struct crypto_rfc4543_ctx {
+	struct crypto_aead *child;
+	u8 nonce[4];
+};
+
+struct crypto_rfc4543_req_ctx {
+	u8 auth_tag[16];
+	struct scatterlist cipher[1];
+	struct scatterlist payload[2];
+	struct scatterlist assoc[2];
+	struct aead_request subreq;
+};
+
 struct crypto_gcm_ghash_ctx {
 	unsigned int cryptlen;
 	struct scatterlist *src;
@@ -1047,6 +1060,272 @@ static struct crypto_template crypto_rfc
 	.module = THIS_MODULE,
 };
 
+static inline struct crypto_rfc4543_req_ctx *crypto_rfc4543_reqctx(
+	struct aead_request *req)
+{
+	unsigned long align = crypto_aead_alignmask(crypto_aead_reqtfm(req));
+
+	return (void *)PTR_ALIGN((u8 *)aead_request_ctx(req), align + 1);
+}
+
+static int crypto_rfc4543_setkey(struct crypto_aead *parent, const u8 *key,
+				 unsigned int keylen)
+{
+	struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(parent);
+	struct crypto_aead *child = ctx->child;
+	int err;
+
+	if (keylen < 4)
+		return -EINVAL;
+
+	keylen -= 4;
+	memcpy(ctx->nonce, key + keylen, 4);
+
+	crypto_aead_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+	crypto_aead_set_flags(child, crypto_aead_get_flags(parent) &
+				     CRYPTO_TFM_REQ_MASK);
+	err = crypto_aead_setkey(child, key, keylen);
+	crypto_aead_set_flags(parent, crypto_aead_get_flags(child) &
+				      CRYPTO_TFM_RES_MASK);
+
+	return err;
+}
+
+static int crypto_rfc4543_setauthsize(struct crypto_aead *parent,
+				      unsigned int authsize)
+{
+	struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(parent);
+
+	if (authsize != 16)
+		return -EINVAL;
+
+	return crypto_aead_setauthsize(ctx->child, authsize);
+}
+
+/* this is the same as crypto_authenc_chain */
+static void crypto_rfc4543_chain(struct scatterlist *head,
+				 struct scatterlist *sg, int chain)
+{
+	if (chain) {
+		head->length += sg->length;
+		sg = scatterwalk_sg_next(sg);
+	}
+
+	if (sg)
+		scatterwalk_sg_chain(head, 2, sg);
+	else
+		sg_mark_end(head);
+}
+
+static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req,
+						 int enc)
+{
+	struct crypto_aead *aead = crypto_aead_reqtfm(req);
+	struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(aead);
+	struct crypto_rfc4543_req_ctx *rctx = crypto_rfc4543_reqctx(req);
+	struct aead_request *subreq = &rctx->subreq;
+	struct scatterlist *dst = req->dst;
+	struct scatterlist *cipher = rctx->cipher;
+	struct scatterlist *payload = rctx->payload;
+	struct scatterlist *assoc = rctx->assoc;
+	unsigned int authsize = crypto_aead_authsize(aead);
+	unsigned int assoclen = req->assoclen;
+	struct page *dstp;
+	u8 *vdst;
+	u8 *iv = PTR_ALIGN((u8 *)(rctx + 1) + crypto_aead_reqsize(ctx->child),
+			   crypto_aead_alignmask(ctx->child) + 1);
+
+	memcpy(iv, ctx->nonce, 4);
+	memcpy(iv + 4, req->iv, 8);
+
+	/* construct cipher/plaintext */
+	if (enc)
+		memset(rctx->auth_tag, 0, authsize);
+	else
+		scatterwalk_map_and_copy(rctx->auth_tag, dst,
+					 req->cryptlen - authsize,
+					 authsize, 0);
+
+	sg_init_one(cipher, rctx->auth_tag, authsize);
+
+	/* construct the aad */
+	dstp = sg_page(dst);
+	vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset;
+
+	sg_init_table(payload, 2);
+	sg_set_buf(payload, req->iv, 8);
+	crypto_rfc4543_chain(payload, dst, vdst == req->iv + 8);
+	assoclen += 8 + req->cryptlen - (enc ? 0 : authsize);
+
+	sg_init_table(assoc, 2);
+	sg_set_page(assoc, sg_page(req->assoc), req->assoc->length,
+		    req->assoc->offset);
+	crypto_rfc4543_chain(assoc, payload, 0);
+
+	aead_request_set_tfm(subreq, ctx->child);
+	aead_request_set_callback(subreq, req->base.flags, req->base.complete,
+				  req->base.data);
+	aead_request_set_crypt(subreq, cipher, cipher, enc ? 0 : authsize, iv);
+	aead_request_set_assoc(subreq, assoc, assoclen);
+
+	return subreq;
+}
+
+static int crypto_rfc4543_encrypt(struct aead_request *req)
+{
+	struct crypto_aead *aead = crypto_aead_reqtfm(req);
+	struct crypto_rfc4543_req_ctx *rctx = crypto_rfc4543_reqctx(req);
+	struct aead_request *subreq;
+	int err;
+
+	subreq = crypto_rfc4543_crypt(req, 1);
+	err = crypto_aead_encrypt(subreq);
+	if (err)
+		return err;
+
+	scatterwalk_map_and_copy(rctx->auth_tag, req->dst, req->cryptlen,
+				 crypto_aead_authsize(aead), 1);
+
+	return 0;
+}
+
+static int crypto_rfc4543_decrypt(struct aead_request *req)
+{
+	req = crypto_rfc4543_crypt(req, 0);
+
+	return crypto_aead_decrypt(req);
+}
+
+static int crypto_rfc4543_init_tfm(struct crypto_tfm *tfm)
+{
+	struct crypto_instance *inst = (void *)tfm->__crt_alg;
+	struct crypto_aead_spawn *spawn = crypto_instance_ctx(inst);
+	struct crypto_rfc4543_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct crypto_aead *aead;
+	unsigned long align;
+
+	aead = crypto_spawn_aead(spawn);
+	if (IS_ERR(aead))
+		return PTR_ERR(aead);
+
+	ctx->child = aead;
+
+	align = crypto_aead_alignmask(aead);
+	align &= ~(crypto_tfm_ctx_alignment() - 1);
+	tfm->crt_aead.reqsize = sizeof(struct crypto_rfc4543_req_ctx) +
+				ALIGN(crypto_aead_reqsize(aead),
+				      crypto_tfm_ctx_alignment()) +
+				align + 16;
+
+	return 0;
+}
+
+static void crypto_rfc4543_exit_tfm(struct crypto_tfm *tfm)
+{
+	struct crypto_rfc4543_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	crypto_free_aead(ctx->child);
+}
+
+static struct crypto_instance *crypto_rfc4543_alloc(struct rtattr **tb)
+{
+	struct crypto_attr_type *algt;
+	struct crypto_instance *inst;
+	struct crypto_aead_spawn *spawn;
+	struct crypto_alg *alg;
+	const char *ccm_name;
+	int err;
+
+	algt = crypto_get_attr_type(tb);
+	err = PTR_ERR(algt);
+	if (IS_ERR(algt))
+		return ERR_PTR(err);
+
+	if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
+		return ERR_PTR(-EINVAL);
+
+	ccm_name = crypto_attr_alg_name(tb[1]);
+	err = PTR_ERR(ccm_name);
+	if (IS_ERR(ccm_name))
+		return ERR_PTR(err);
+
+	inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
+	if (!inst)
+		return ERR_PTR(-ENOMEM);
+
+	spawn = crypto_instance_ctx(inst);
+	crypto_set_aead_spawn(spawn, inst);
+	err = crypto_grab_aead(spawn, ccm_name, 0,
+			       crypto_requires_sync(algt->type, algt->mask));
+	if (err)
+		goto out_free_inst;
+
+	alg = crypto_aead_spawn_alg(spawn);
+
+	err = -EINVAL;
+
+	/* We only support 16-byte blocks. */
+	if (alg->cra_aead.ivsize != 16)
+		goto out_drop_alg;
+
+	/* Not a stream cipher? */
+	if (alg->cra_blocksize != 1)
+		goto out_drop_alg;
+
+	err = -ENAMETOOLONG;
+	if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
+		     "rfc4543(%s)", alg->cra_name) >= CRYPTO_MAX_ALG_NAME ||
+	    snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
+		     "rfc4543(%s)", alg->cra_driver_name) >=
+	    CRYPTO_MAX_ALG_NAME)
+		goto out_drop_alg;
+
+	inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD;
+	inst->alg.cra_flags |= alg->cra_flags & CRYPTO_ALG_ASYNC;
+	inst->alg.cra_priority = alg->cra_priority;
+	inst->alg.cra_blocksize = 1;
+	inst->alg.cra_alignmask = alg->cra_alignmask;
+	inst->alg.cra_type = &crypto_nivaead_type;
+
+	inst->alg.cra_aead.ivsize = 8;
+	inst->alg.cra_aead.maxauthsize = 16;
+
+	inst->alg.cra_ctxsize = sizeof(struct crypto_rfc4543_ctx);
+
+	inst->alg.cra_init = crypto_rfc4543_init_tfm;
+	inst->alg.cra_exit = crypto_rfc4543_exit_tfm;
+
+	inst->alg.cra_aead.setkey = crypto_rfc4543_setkey;
+	inst->alg.cra_aead.setauthsize = crypto_rfc4543_setauthsize;
+	inst->alg.cra_aead.encrypt = crypto_rfc4543_encrypt;
+	inst->alg.cra_aead.decrypt = crypto_rfc4543_decrypt;
+
+	inst->alg.cra_aead.geniv = "seqiv";
+
+out:
+	return inst;
+
+out_drop_alg:
+	crypto_drop_aead(spawn);
+out_free_inst:
+	kfree(inst);
+	inst = ERR_PTR(err);
+	goto out;
+}
+
+static void crypto_rfc4543_free(struct crypto_instance *inst)
+{
+	crypto_drop_spawn(crypto_instance_ctx(inst));
+	kfree(inst);
+}
+
+static struct crypto_template crypto_rfc4543_tmpl = {
+	.name = "rfc4543",
+	.alloc = crypto_rfc4543_alloc,
+	.free = crypto_rfc4543_free,
+	.module = THIS_MODULE,
+};
+
 static int __init crypto_gcm_module_init(void)
 {
 	int err;
@@ -1067,8 +1346,14 @@ static int __init crypto_gcm_module_init
 	if (err)
 		goto out_undo_gcm;
 
+	err = crypto_register_template(&crypto_rfc4543_tmpl);
+	if (err)
+		goto out_undo_rfc4106;
+
 	return 0;
 
+out_undo_rfc4106:
+	crypto_unregister_template(&crypto_rfc4106_tmpl);
 out_undo_gcm:
 	crypto_unregister_template(&crypto_gcm_tmpl);
 out_undo_base:
@@ -1081,6 +1366,7 @@ out:
 static void __exit crypto_gcm_module_exit(void)
 {
 	kfree(gcm_zeroes);
+	crypto_unregister_template(&crypto_rfc4543_tmpl);
 	crypto_unregister_template(&crypto_rfc4106_tmpl);
 	crypto_unregister_template(&crypto_gcm_tmpl);
 	crypto_unregister_template(&crypto_gcm_base_tmpl);
@@ -1094,3 +1380,4 @@ MODULE_DESCRIPTION("Galois/Counter Mode"
 MODULE_AUTHOR("Mikko Herranen <mh1@iki.fi>");
 MODULE_ALIAS("gcm_base");
 MODULE_ALIAS("rfc4106");
+MODULE_ALIAS("rfc4543");
diff -druNp linux-libre-2.6.33-gnu1/crypto/hmac.c linux-libre-2.6.34-gnu1/crypto/hmac.c
--- linux-libre-2.6.33-gnu1/crypto/hmac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/hmac.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/scatterlist.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 
 struct hmac_ctx {
diff -druNp linux-libre-2.6.33-gnu1/crypto/Kconfig linux-libre-2.6.34-gnu1/crypto/Kconfig
--- linux-libre-2.6.33-gnu1/crypto/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -114,6 +114,16 @@ config CRYPTO_NULL
 	help
 	  These are 'Null' algorithms, used by IPsec, which do nothing.
 
+config CRYPTO_PCRYPT
+	tristate "Parallel crypto engine (EXPERIMENTAL)"
+	depends on SMP && EXPERIMENTAL
+	select PADATA
+	select CRYPTO_MANAGER
+	select CRYPTO_AEAD
+	help
+	  This converts an arbitrary crypto algorithm into a parallel
+	  algorithm that executes in kernel threads.
+
 config CRYPTO_WORKQUEUE
        tristate
 
@@ -816,8 +826,8 @@ config CRYPTO_ANSI_CPRNG
 	help
 	  This option enables the generic pseudo random number generator
 	  for cryptographic modules.  Uses the Algorithm specified in
-	  ANSI X9.31 A.2.4. Not this option must be enabled if CRYPTO_FIPS 
-	  is selected
+	  ANSI X9.31 A.2.4. Note that this option must be enabled if
+	  CRYPTO_FIPS is selected
 
 source "drivers/crypto/Kconfig"
 
diff -druNp linux-libre-2.6.33-gnu1/crypto/Makefile linux-libre-2.6.34-gnu1/crypto/Makefile
--- linux-libre-2.6.33-gnu1/crypto/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -56,6 +56,7 @@ obj-$(CONFIG_CRYPTO_XTS) += xts.o
 obj-$(CONFIG_CRYPTO_CTR) += ctr.o
 obj-$(CONFIG_CRYPTO_GCM) += gcm.o
 obj-$(CONFIG_CRYPTO_CCM) += ccm.o
+obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o
 obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o
 obj-$(CONFIG_CRYPTO_DES) += des_generic.o
 obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o
diff -druNp linux-libre-2.6.33-gnu1/crypto/md5.c linux-libre-2.6.34-gnu1/crypto/md5.c
--- linux-libre-2.6.33-gnu1/crypto/md5.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/md5.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,17 +16,13 @@
  *
  */
 #include <crypto/internal/hash.h>
+#include <crypto/md5.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <asm/byteorder.h>
 
-#define MD5_DIGEST_SIZE		16
-#define MD5_HMAC_BLOCK_SIZE	64
-#define MD5_BLOCK_WORDS		16
-#define MD5_HASH_WORDS		4
-
 #define F1(x, y, z)	(z ^ (x & (y ^ z)))
 #define F2(x, y, z)	F1(z, x, y)
 #define F3(x, y, z)	(x ^ y ^ z)
@@ -35,12 +31,6 @@
 #define MD5STEP(f, w, x, y, z, in, s) \
 	(w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x)
 
-struct md5_ctx {
-	u32 hash[MD5_HASH_WORDS];
-	u32 block[MD5_BLOCK_WORDS];
-	u64 byte_count;
-};
-
 static void md5_transform(u32 *hash, u32 const *in)
 {
 	u32 a, b, c, d;
@@ -141,7 +131,7 @@ static inline void cpu_to_le32_array(u32
 	}
 }
 
-static inline void md5_transform_helper(struct md5_ctx *ctx)
+static inline void md5_transform_helper(struct md5_state *ctx)
 {
 	le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32));
 	md5_transform(ctx->hash, ctx->block);
@@ -149,7 +139,7 @@ static inline void md5_transform_helper(
 
 static int md5_init(struct shash_desc *desc)
 {
-	struct md5_ctx *mctx = shash_desc_ctx(desc);
+	struct md5_state *mctx = shash_desc_ctx(desc);
 
 	mctx->hash[0] = 0x67452301;
 	mctx->hash[1] = 0xefcdab89;
@@ -162,7 +152,7 @@ static int md5_init(struct shash_desc *d
 
 static int md5_update(struct shash_desc *desc, const u8 *data, unsigned int len)
 {
-	struct md5_ctx *mctx = shash_desc_ctx(desc);
+	struct md5_state *mctx = shash_desc_ctx(desc);
 	const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
 
 	mctx->byte_count += len;
@@ -194,7 +184,7 @@ static int md5_update(struct shash_desc
 
 static int md5_final(struct shash_desc *desc, u8 *out)
 {
-	struct md5_ctx *mctx = shash_desc_ctx(desc);
+	struct md5_state *mctx = shash_desc_ctx(desc);
 	const unsigned int offset = mctx->byte_count & 0x3f;
 	char *p = (char *)mctx->block + offset;
 	int padding = 56 - (offset + 1);
@@ -220,12 +210,31 @@ static int md5_final(struct shash_desc *
 	return 0;
 }
 
+static int md5_export(struct shash_desc *desc, void *out)
+{
+	struct md5_state *ctx = shash_desc_ctx(desc);
+
+	memcpy(out, ctx, sizeof(*ctx));
+	return 0;
+}
+
+static int md5_import(struct shash_desc *desc, const void *in)
+{
+	struct md5_state *ctx = shash_desc_ctx(desc);
+
+	memcpy(ctx, in, sizeof(*ctx));
+	return 0;
+}
+
 static struct shash_alg alg = {
 	.digestsize	=	MD5_DIGEST_SIZE,
 	.init		=	md5_init,
 	.update		=	md5_update,
 	.final		=	md5_final,
-	.descsize	=	sizeof(struct md5_ctx),
+	.export		=	md5_export,
+	.import		=	md5_import,
+	.descsize	=	sizeof(struct md5_state),
+	.statesize	=	sizeof(struct md5_state),
 	.base		=	{
 		.cra_name	=	"md5",
 		.cra_flags	=	CRYPTO_ALG_TYPE_SHASH,
diff -druNp linux-libre-2.6.33-gnu1/crypto/pcrypt.c linux-libre-2.6.34-gnu1/crypto/pcrypt.c
--- linux-libre-2.6.33-gnu1/crypto/pcrypt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/pcrypt.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,445 @@
+/*
+ * pcrypt - Parallel crypto wrapper.
+ *
+ * Copyright (C) 2009 secunet Security Networks AG
+ * Copyright (C) 2009 Steffen Klassert <steffen.klassert@secunet.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 <crypto/algapi.h>
+#include <crypto/internal/aead.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <crypto/pcrypt.h>
+
+static struct padata_instance *pcrypt_enc_padata;
+static struct padata_instance *pcrypt_dec_padata;
+static struct workqueue_struct *encwq;
+static struct workqueue_struct *decwq;
+
+struct pcrypt_instance_ctx {
+	struct crypto_spawn spawn;
+	unsigned int tfm_count;
+};
+
+struct pcrypt_aead_ctx {
+	struct crypto_aead *child;
+	unsigned int cb_cpu;
+};
+
+static int pcrypt_do_parallel(struct padata_priv *padata, unsigned int *cb_cpu,
+			      struct padata_instance *pinst)
+{
+	unsigned int cpu_index, cpu, i;
+
+	cpu = *cb_cpu;
+
+	if (cpumask_test_cpu(cpu, cpu_active_mask))
+			goto out;
+
+	cpu_index = cpu % cpumask_weight(cpu_active_mask);
+
+	cpu = cpumask_first(cpu_active_mask);
+	for (i = 0; i < cpu_index; i++)
+		cpu = cpumask_next(cpu, cpu_active_mask);
+
+	*cb_cpu = cpu;
+
+out:
+	return padata_do_parallel(pinst, padata, cpu);
+}
+
+static int pcrypt_aead_setkey(struct crypto_aead *parent,
+			      const u8 *key, unsigned int keylen)
+{
+	struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent);
+
+	return crypto_aead_setkey(ctx->child, key, keylen);
+}
+
+static int pcrypt_aead_setauthsize(struct crypto_aead *parent,
+				   unsigned int authsize)
+{
+	struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent);
+
+	return crypto_aead_setauthsize(ctx->child, authsize);
+}
+
+static void pcrypt_aead_serial(struct padata_priv *padata)
+{
+	struct pcrypt_request *preq = pcrypt_padata_request(padata);
+	struct aead_request *req = pcrypt_request_ctx(preq);
+
+	aead_request_complete(req->base.data, padata->info);
+}
+
+static void pcrypt_aead_giv_serial(struct padata_priv *padata)
+{
+	struct pcrypt_request *preq = pcrypt_padata_request(padata);
+	struct aead_givcrypt_request *req = pcrypt_request_ctx(preq);
+
+	aead_request_complete(req->areq.base.data, padata->info);
+}
+
+static void pcrypt_aead_done(struct crypto_async_request *areq, int err)
+{
+	struct aead_request *req = areq->data;
+	struct pcrypt_request *preq = aead_request_ctx(req);
+	struct padata_priv *padata = pcrypt_request_padata(preq);
+
+	padata->info = err;
+	req->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+
+	padata_do_serial(padata);
+}
+
+static void pcrypt_aead_enc(struct padata_priv *padata)
+{
+	struct pcrypt_request *preq = pcrypt_padata_request(padata);
+	struct aead_request *req = pcrypt_request_ctx(preq);
+
+	padata->info = crypto_aead_encrypt(req);
+
+	if (padata->info == -EINPROGRESS)
+		return;
+
+	padata_do_serial(padata);
+}
+
+static int pcrypt_aead_encrypt(struct aead_request *req)
+{
+	int err;
+	struct pcrypt_request *preq = aead_request_ctx(req);
+	struct aead_request *creq = pcrypt_request_ctx(preq);
+	struct padata_priv *padata = pcrypt_request_padata(preq);
+	struct crypto_aead *aead = crypto_aead_reqtfm(req);
+	struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(aead);
+	u32 flags = aead_request_flags(req);
+
+	memset(padata, 0, sizeof(struct padata_priv));
+
+	padata->parallel = pcrypt_aead_enc;
+	padata->serial = pcrypt_aead_serial;
+
+	aead_request_set_tfm(creq, ctx->child);
+	aead_request_set_callback(creq, flags & ~CRYPTO_TFM_REQ_MAY_SLEEP,
+				  pcrypt_aead_done, req);
+	aead_request_set_crypt(creq, req->src, req->dst,
+			       req->cryptlen, req->iv);
+	aead_request_set_assoc(creq, req->assoc, req->assoclen);
+
+	err = pcrypt_do_parallel(padata, &ctx->cb_cpu, pcrypt_enc_padata);
+	if (err)
+		return err;
+	else
+		err = crypto_aead_encrypt(creq);
+
+	return err;
+}
+
+static void pcrypt_aead_dec(struct padata_priv *padata)
+{
+	struct pcrypt_request *preq = pcrypt_padata_request(padata);
+	struct aead_request *req = pcrypt_request_ctx(preq);
+
+	padata->info = crypto_aead_decrypt(req);
+
+	if (padata->info == -EINPROGRESS)
+		return;
+
+	padata_do_serial(padata);
+}
+
+static int pcrypt_aead_decrypt(struct aead_request *req)
+{
+	int err;
+	struct pcrypt_request *preq = aead_request_ctx(req);
+	struct aead_request *creq = pcrypt_request_ctx(preq);
+	struct padata_priv *padata = pcrypt_request_padata(preq);
+	struct crypto_aead *aead = crypto_aead_reqtfm(req);
+	struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(aead);
+	u32 flags = aead_request_flags(req);
+
+	memset(padata, 0, sizeof(struct padata_priv));
+
+	padata->parallel = pcrypt_aead_dec;
+	padata->serial = pcrypt_aead_serial;
+
+	aead_request_set_tfm(creq, ctx->child);
+	aead_request_set_callback(creq, flags & ~CRYPTO_TFM_REQ_MAY_SLEEP,
+				  pcrypt_aead_done, req);
+	aead_request_set_crypt(creq, req->src, req->dst,
+			       req->cryptlen, req->iv);
+	aead_request_set_assoc(creq, req->assoc, req->assoclen);
+
+	err = pcrypt_do_parallel(padata, &ctx->cb_cpu, pcrypt_dec_padata);
+	if (err)
+		return err;
+	else
+		err = crypto_aead_decrypt(creq);
+
+	return err;
+}
+
+static void pcrypt_aead_givenc(struct padata_priv *padata)
+{
+	struct pcrypt_request *preq = pcrypt_padata_request(padata);
+	struct aead_givcrypt_request *req = pcrypt_request_ctx(preq);
+
+	padata->info = crypto_aead_givencrypt(req);
+
+	if (padata->info == -EINPROGRESS)
+		return;
+
+	padata_do_serial(padata);
+}
+
+static int pcrypt_aead_givencrypt(struct aead_givcrypt_request *req)
+{
+	int err;
+	struct aead_request *areq = &req->areq;
+	struct pcrypt_request *preq = aead_request_ctx(areq);
+	struct aead_givcrypt_request *creq = pcrypt_request_ctx(preq);
+	struct padata_priv *padata = pcrypt_request_padata(preq);
+	struct crypto_aead *aead = aead_givcrypt_reqtfm(req);
+	struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(aead);
+	u32 flags = aead_request_flags(areq);
+
+	memset(padata, 0, sizeof(struct padata_priv));
+
+	padata->parallel = pcrypt_aead_givenc;
+	padata->serial = pcrypt_aead_giv_serial;
+
+	aead_givcrypt_set_tfm(creq, ctx->child);
+	aead_givcrypt_set_callback(creq, flags & ~CRYPTO_TFM_REQ_MAY_SLEEP,
+				   pcrypt_aead_done, areq);
+	aead_givcrypt_set_crypt(creq, areq->src, areq->dst,
+				areq->cryptlen, areq->iv);
+	aead_givcrypt_set_assoc(creq, areq->assoc, areq->assoclen);
+	aead_givcrypt_set_giv(creq, req->giv, req->seq);
+
+	err = pcrypt_do_parallel(padata, &ctx->cb_cpu, pcrypt_enc_padata);
+	if (err)
+		return err;
+	else
+		err = crypto_aead_givencrypt(creq);
+
+	return err;
+}
+
+static int pcrypt_aead_init_tfm(struct crypto_tfm *tfm)
+{
+	int cpu, cpu_index;
+	struct crypto_instance *inst = crypto_tfm_alg_instance(tfm);
+	struct pcrypt_instance_ctx *ictx = crypto_instance_ctx(inst);
+	struct pcrypt_aead_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct crypto_aead *cipher;
+
+	ictx->tfm_count++;
+
+	cpu_index = ictx->tfm_count % cpumask_weight(cpu_active_mask);
+
+	ctx->cb_cpu = cpumask_first(cpu_active_mask);
+	for (cpu = 0; cpu < cpu_index; cpu++)
+		ctx->cb_cpu = cpumask_next(ctx->cb_cpu, cpu_active_mask);
+
+	cipher = crypto_spawn_aead(crypto_instance_ctx(inst));
+
+	if (IS_ERR(cipher))
+		return PTR_ERR(cipher);
+
+	ctx->child = cipher;
+	tfm->crt_aead.reqsize = sizeof(struct pcrypt_request)
+		+ sizeof(struct aead_givcrypt_request)
+		+ crypto_aead_reqsize(cipher);
+
+	return 0;
+}
+
+static void pcrypt_aead_exit_tfm(struct crypto_tfm *tfm)
+{
+	struct pcrypt_aead_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	crypto_free_aead(ctx->child);
+}
+
+static struct crypto_instance *pcrypt_alloc_instance(struct crypto_alg *alg)
+{
+	struct crypto_instance *inst;
+	struct pcrypt_instance_ctx *ctx;
+	int err;
+
+	inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
+	if (!inst) {
+		inst = ERR_PTR(-ENOMEM);
+		goto out;
+	}
+
+	err = -ENAMETOOLONG;
+	if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
+		     "pcrypt(%s)", alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
+		goto out_free_inst;
+
+	memcpy(inst->alg.cra_name, alg->cra_name, CRYPTO_MAX_ALG_NAME);
+
+	ctx = crypto_instance_ctx(inst);
+	err = crypto_init_spawn(&ctx->spawn, alg, inst,
+				CRYPTO_ALG_TYPE_MASK);
+	if (err)
+		goto out_free_inst;
+
+	inst->alg.cra_priority = alg->cra_priority + 100;
+	inst->alg.cra_blocksize = alg->cra_blocksize;
+	inst->alg.cra_alignmask = alg->cra_alignmask;
+
+out:
+	return inst;
+
+out_free_inst:
+	kfree(inst);
+	inst = ERR_PTR(err);
+	goto out;
+}
+
+static struct crypto_instance *pcrypt_alloc_aead(struct rtattr **tb)
+{
+	struct crypto_instance *inst;
+	struct crypto_alg *alg;
+	struct crypto_attr_type *algt;
+
+	algt = crypto_get_attr_type(tb);
+
+	alg = crypto_get_attr_alg(tb, algt->type,
+				  (algt->mask & CRYPTO_ALG_TYPE_MASK));
+	if (IS_ERR(alg))
+		return ERR_CAST(alg);
+
+	inst = pcrypt_alloc_instance(alg);
+	if (IS_ERR(inst))
+		goto out_put_alg;
+
+	inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC;
+	inst->alg.cra_type = &crypto_aead_type;
+
+	inst->alg.cra_aead.ivsize = alg->cra_aead.ivsize;
+	inst->alg.cra_aead.geniv = alg->cra_aead.geniv;
+	inst->alg.cra_aead.maxauthsize = alg->cra_aead.maxauthsize;
+
+	inst->alg.cra_ctxsize = sizeof(struct pcrypt_aead_ctx);
+
+	inst->alg.cra_init = pcrypt_aead_init_tfm;
+	inst->alg.cra_exit = pcrypt_aead_exit_tfm;
+
+	inst->alg.cra_aead.setkey = pcrypt_aead_setkey;
+	inst->alg.cra_aead.setauthsize = pcrypt_aead_setauthsize;
+	inst->alg.cra_aead.encrypt = pcrypt_aead_encrypt;
+	inst->alg.cra_aead.decrypt = pcrypt_aead_decrypt;
+	inst->alg.cra_aead.givencrypt = pcrypt_aead_givencrypt;
+
+out_put_alg:
+	crypto_mod_put(alg);
+	return inst;
+}
+
+static struct crypto_instance *pcrypt_alloc(struct rtattr **tb)
+{
+	struct crypto_attr_type *algt;
+
+	algt = crypto_get_attr_type(tb);
+	if (IS_ERR(algt))
+		return ERR_CAST(algt);
+
+	switch (algt->type & algt->mask & CRYPTO_ALG_TYPE_MASK) {
+	case CRYPTO_ALG_TYPE_AEAD:
+		return pcrypt_alloc_aead(tb);
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
+static void pcrypt_free(struct crypto_instance *inst)
+{
+	struct pcrypt_instance_ctx *ctx = crypto_instance_ctx(inst);
+
+	crypto_drop_spawn(&ctx->spawn);
+	kfree(inst);
+}
+
+static struct crypto_template pcrypt_tmpl = {
+	.name = "pcrypt",
+	.alloc = pcrypt_alloc,
+	.free = pcrypt_free,
+	.module = THIS_MODULE,
+};
+
+static int __init pcrypt_init(void)
+{
+	encwq = create_workqueue("pencrypt");
+	if (!encwq)
+		goto err;
+
+	decwq = create_workqueue("pdecrypt");
+	if (!decwq)
+		goto err_destroy_encwq;
+
+
+	pcrypt_enc_padata = padata_alloc(cpu_possible_mask, encwq);
+	if (!pcrypt_enc_padata)
+		goto err_destroy_decwq;
+
+	pcrypt_dec_padata = padata_alloc(cpu_possible_mask, decwq);
+	if (!pcrypt_dec_padata)
+		goto err_free_padata;
+
+	padata_start(pcrypt_enc_padata);
+	padata_start(pcrypt_dec_padata);
+
+	return crypto_register_template(&pcrypt_tmpl);
+
+err_free_padata:
+	padata_free(pcrypt_enc_padata);
+
+err_destroy_decwq:
+	destroy_workqueue(decwq);
+
+err_destroy_encwq:
+	destroy_workqueue(encwq);
+
+err:
+	return -ENOMEM;
+}
+
+static void __exit pcrypt_exit(void)
+{
+	padata_stop(pcrypt_enc_padata);
+	padata_stop(pcrypt_dec_padata);
+
+	destroy_workqueue(encwq);
+	destroy_workqueue(decwq);
+
+	padata_free(pcrypt_enc_padata);
+	padata_free(pcrypt_dec_padata);
+
+	crypto_unregister_template(&pcrypt_tmpl);
+}
+
+module_init(pcrypt_init);
+module_exit(pcrypt_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>");
+MODULE_DESCRIPTION("Parallel crypto wrapper");
diff -druNp linux-libre-2.6.33-gnu1/crypto/rng.c linux-libre-2.6.34-gnu1/crypto/rng.c
--- linux-libre-2.6.33-gnu1/crypto/rng.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/rng.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/mutex.h>
 #include <linux/random.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
 static DEFINE_MUTEX(crypto_default_rng_lock);
diff -druNp linux-libre-2.6.33-gnu1/crypto/seqiv.c linux-libre-2.6.34-gnu1/crypto/seqiv.c
--- linux-libre-2.6.33-gnu1/crypto/seqiv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/seqiv.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 
diff -druNp linux-libre-2.6.33-gnu1/crypto/tcrypt.c linux-libre-2.6.34-gnu1/crypto/tcrypt.c
--- linux-libre-2.6.33-gnu1/crypto/tcrypt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/tcrypt.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,8 +18,8 @@
 #include <crypto/hash.h>
 #include <linux/err.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/scatterlist.h>
 #include <linux/string.h>
 #include <linux/moduleparam.h>
diff -druNp linux-libre-2.6.33-gnu1/crypto/testmgr.c linux-libre-2.6.34-gnu1/crypto/testmgr.c
--- linux-libre-2.6.33-gnu1/crypto/testmgr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/testmgr.c	2010-05-16 17:17:36.000000000 -0400
@@ -1477,9 +1477,54 @@ static int alg_test_cprng(const struct a
 	return err;
 }
 
+static int alg_test_null(const struct alg_test_desc *desc,
+			     const char *driver, u32 type, u32 mask)
+{
+	return 0;
+}
+
 /* Please keep this list sorted by algorithm name. */
 static const struct alg_test_desc alg_test_descs[] = {
 	{
+		.alg = "__driver-cbc-aes-aesni",
+		.test = alg_test_null,
+		.suite = {
+			.cipher = {
+				.enc = {
+					.vecs = NULL,
+					.count = 0
+				},
+				.dec = {
+					.vecs = NULL,
+					.count = 0
+				}
+			}
+		}
+	}, {
+		.alg = "__driver-ecb-aes-aesni",
+		.test = alg_test_null,
+		.suite = {
+			.cipher = {
+				.enc = {
+					.vecs = NULL,
+					.count = 0
+				},
+				.dec = {
+					.vecs = NULL,
+					.count = 0
+				}
+			}
+		}
+	}, {
+		.alg = "__ghash-pclmulqdqni",
+		.test = alg_test_null,
+		.suite = {
+			.hash = {
+				.vecs = NULL,
+				.count = 0
+			}
+		}
+	}, {
 		.alg = "ansi_cprng",
 		.test = alg_test_cprng,
 		.fips_allowed = 1,
@@ -1623,6 +1668,30 @@ static const struct alg_test_desc alg_te
 			}
 		}
 	}, {
+		.alg = "cryptd(__driver-ecb-aes-aesni)",
+		.test = alg_test_null,
+		.suite = {
+			.cipher = {
+				.enc = {
+					.vecs = NULL,
+					.count = 0
+				},
+				.dec = {
+					.vecs = NULL,
+					.count = 0
+				}
+			}
+		}
+	}, {
+		.alg = "cryptd(__ghash-pclmulqdqni)",
+		.test = alg_test_null,
+		.suite = {
+			.hash = {
+				.vecs = NULL,
+				.count = 0
+			}
+		}
+	}, {
 		.alg = "ctr(aes)",
 		.test = alg_test_skcipher,
 		.fips_allowed = 1,
@@ -1668,6 +1737,21 @@ static const struct alg_test_desc alg_te
 				}
 			}
 		}
+	}, {
+		.alg = "ecb(__aes-aesni)",
+		.test = alg_test_null,
+		.suite = {
+			.cipher = {
+				.enc = {
+					.vecs = NULL,
+					.count = 0
+				},
+				.dec = {
+					.vecs = NULL,
+					.count = 0
+				}
+			}
+		}
 	}, {
 		.alg = "ecb(aes)",
 		.test = alg_test_skcipher,
diff -druNp linux-libre-2.6.33-gnu1/crypto/xor.c linux-libre-2.6.34-gnu1/crypto/xor.c
--- linux-libre-2.6.33-gnu1/crypto/xor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/crypto/xor.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 
 #define BH_TRACE 0
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/raid/xor.h>
 #include <linux/jiffies.h>
 #include <asm/xor.h>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/ABI/stable/sysfs-devices-node linux-libre-2.6.34-gnu1/Documentation/ABI/stable/sysfs-devices-node
--- linux-libre-2.6.33-gnu1/Documentation/ABI/stable/sysfs-devices-node	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/ABI/stable/sysfs-devices-node	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,7 @@
+What:		/sys/devices/system/node/nodeX
+Date:		October 2002
+Contact:	Linux Memory Management list <linux-mm@kvack.org>
+Description:
+		When CONFIG_NUMA is enabled, this is a directory containing
+		information on node X such as what CPUs are local to the
+		node.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-block linux-libre-2.6.34-gnu1/Documentation/ABI/testing/sysfs-block
--- linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-block	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/ABI/testing/sysfs-block	2010-05-16 17:17:36.000000000 -0400
@@ -128,3 +128,17 @@ Description:
 		preferred request size for workloads where sustained
 		throughput is desired.  If no optimal I/O size is
 		reported this file contains 0.
+
+What:		/sys/block/<disk>/queue/nomerges
+Date:		January 2010
+Contact:
+Description:
+		Standard I/O elevator operations include attempts to
+		merge contiguous I/Os. For known random I/O loads these
+		attempts will always fail and result in extra cycles
+		being spent in the kernel. This allows one to turn off
+		this behavior on one of two ways: When set to 1, complex
+		merge checks are disabled, but the simple one-shot merges
+		with the previous I/O request are enabled. When set to 2,
+		all merge tries are disabled. The default value is 0 -
+		which enables all types of merge tries.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-bus-usb linux-libre-2.6.34-gnu1/Documentation/ABI/testing/sysfs-bus-usb
--- linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-bus-usb	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/ABI/testing/sysfs-bus-usb	2010-05-16 17:17:36.000000000 -0400
@@ -159,3 +159,14 @@ Description:
 		device.  This is useful to ensure auto probing won't
 		match the driver to the device.  For example:
 		# echo "046d c315" > /sys/bus/usb/drivers/foo/remove_id
+
+What:		/sys/bus/usb/device/.../avoid_reset_quirk
+Date:		December 2009
+Contact:	Oliver Neukum <oliver@neukum.org>
+Description:
+		Writing 1 to this file tells the kernel that this
+		device will morph into another mode when it is reset.
+		Drivers will not use reset for error handling for
+		such devices.
+Users:
+		usb_modeswitch
diff -druNp linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-devices-power linux-libre-2.6.34-gnu1/Documentation/ABI/testing/sysfs-devices-power
--- linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-devices-power	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/ABI/testing/sysfs-devices-power	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,79 @@
+What:		/sys/devices/.../power/
+Date:		January 2009
+Contact:	Rafael J. Wysocki <rjw@sisk.pl>
+Description:
+		The /sys/devices/.../power directory contains attributes
+		allowing the user space to check and modify some power
+		management related properties of given device.
+
+What:		/sys/devices/.../power/wakeup
+Date:		January 2009
+Contact:	Rafael J. Wysocki <rjw@sisk.pl>
+Description:
+		The /sys/devices/.../power/wakeup attribute allows the user
+		space to check if the device is enabled to wake up the system
+		from sleep states, such as the memory sleep state (suspend to
+		RAM) and hibernation (suspend to disk), and to enable or disable
+		it to do that as desired.
+
+		Some devices support "wakeup" events, which are hardware signals
+		used to activate the system from a sleep state.  Such devices
+		have one of the following two values for the sysfs power/wakeup
+		file:
+
+		+ "enabled\n" to issue the events;
+		+ "disabled\n" not to do so;
+
+		In that cases the user space can change the setting represented
+		by the contents of this file by writing either "enabled", or
+		"disabled" to it.
+
+		For the devices that are not capable of generating system wakeup
+		events this file contains "\n".  In that cases the user space
+		cannot modify the contents of this file and the device cannot be
+		enabled to wake up the system.
+
+What:		/sys/devices/.../power/control
+Date:		January 2009
+Contact:	Rafael J. Wysocki <rjw@sisk.pl>
+Description:
+		The /sys/devices/.../power/control attribute allows the user
+		space to control the run-time power management of the device.
+
+		All devices have one of the following two values for the
+		power/control file:
+
+		+ "auto\n" to allow the device to be power managed at run time;
+		+ "on\n" to prevent the device from being power managed;
+
+		The default for all devices is "auto", which means that they may
+		be subject to automatic power management, depending on their
+		drivers.  Changing this attribute to "on" prevents the driver
+		from power managing the device at run time.  Doing that while
+		the device is suspended causes it to be woken up.
+
+What:		/sys/devices/.../power/async
+Date:		January 2009
+Contact:	Rafael J. Wysocki <rjw@sisk.pl>
+Description:
+		The /sys/devices/.../async attribute allows the user space to
+		enable or diasble the device's suspend and resume callbacks to
+		be executed asynchronously (ie. in separate threads, in parallel
+		with the main suspend/resume thread) during system-wide power
+		transitions (eg. suspend to RAM, hibernation).
+
+		All devices have one of the following two values for the
+		power/async file:
+
+		+ "enabled\n" to permit the asynchronous suspend/resume;
+		+ "disabled\n" to forbid it;
+
+		The value of this attribute may be changed by writing either
+		"enabled", or "disabled" to it.
+
+		It generally is unsafe to permit the asynchronous suspend/resume
+		of a device unless it is certain that all of the PM dependencies
+		of the device are known to the PM core.  However, for some
+		devices this attribute is set to "enabled" by bus type code or
+		device drivers and in that cases it should be safe to leave the
+		default value.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-platform-asus-laptop linux-libre-2.6.34-gnu1/Documentation/ABI/testing/sysfs-platform-asus-laptop
--- linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-platform-asus-laptop	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/ABI/testing/sysfs-platform-asus-laptop	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,4 @@
-What:		/sys/devices/platform/asus-laptop/display
+What:		/sys/devices/platform/asus_laptop/display
 Date:		January 2007
 KernelVersion:	2.6.20
 Contact:	"Corentin Chary" <corentincj@iksaif.net>
@@ -13,7 +13,7 @@ Description:
 		Ex: - 0 (0000b) means no display
 		    - 3 (0011b) CRT+LCD.
 
-What:		/sys/devices/platform/asus-laptop/gps
+What:		/sys/devices/platform/asus_laptop/gps
 Date:		January 2007
 KernelVersion:	2.6.20
 Contact:	"Corentin Chary" <corentincj@iksaif.net>
@@ -21,7 +21,7 @@ Description:
 		Control the gps device. 1 means on, 0 means off.
 Users:		Lapsus
 
-What:		/sys/devices/platform/asus-laptop/ledd
+What:		/sys/devices/platform/asus_laptop/ledd
 Date:		January 2007
 KernelVersion:	2.6.20
 Contact:	"Corentin Chary" <corentincj@iksaif.net>
@@ -29,11 +29,11 @@ Description:
 		Some models like the W1N have a LED display that can be
 		used to display several informations.
 		To control the LED display, use the following :
-		    echo 0x0T000DDD > /sys/devices/platform/asus-laptop/
+		    echo 0x0T000DDD > /sys/devices/platform/asus_laptop/
 		where T control the 3 letters display, and DDD the 3 digits display.
 		The DDD table can be found in Documentation/laptops/asus-laptop.txt
 
-What:		/sys/devices/platform/asus-laptop/bluetooth
+What:		/sys/devices/platform/asus_laptop/bluetooth
 Date:		January 2007
 KernelVersion:	2.6.20
 Contact:	"Corentin Chary" <corentincj@iksaif.net>
@@ -42,7 +42,7 @@ Description:
 		This may control the led, the device or both.
 Users:		Lapsus
 
-What:		/sys/devices/platform/asus-laptop/wlan
+What:		/sys/devices/platform/asus_laptop/wlan
 Date:		January 2007
 KernelVersion:	2.6.20
 Contact:	"Corentin Chary" <corentincj@iksaif.net>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-platform-eeepc-laptop linux-libre-2.6.34-gnu1/Documentation/ABI/testing/sysfs-platform-eeepc-laptop
--- linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-platform-eeepc-laptop	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/ABI/testing/sysfs-platform-eeepc-laptop	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,4 @@
-What:		/sys/devices/platform/eeepc-laptop/disp
+What:		/sys/devices/platform/eeepc/disp
 Date:		May 2008
 KernelVersion:	2.6.26
 Contact:	"Corentin Chary" <corentincj@iksaif.net>
@@ -9,21 +9,21 @@ Description:
 		- 3 = LCD+CRT
 		If you run X11, you should use xrandr instead.
 
-What:		/sys/devices/platform/eeepc-laptop/camera
+What:		/sys/devices/platform/eeepc/camera
 Date:		May 2008
 KernelVersion:	2.6.26
 Contact:	"Corentin Chary" <corentincj@iksaif.net>
 Description:
 		Control the camera. 1 means on, 0 means off.
 
-What:		/sys/devices/platform/eeepc-laptop/cardr
+What:		/sys/devices/platform/eeepc/cardr
 Date:		May 2008
 KernelVersion:	2.6.26
 Contact:	"Corentin Chary" <corentincj@iksaif.net>
 Description:
 		Control the card reader. 1 means on, 0 means off.
 
-What:		/sys/devices/platform/eeepc-laptop/cpufv
+What:		/sys/devices/platform/eeepc/cpufv
 Date:		Jun 2009
 KernelVersion:	2.6.31
 Contact:	"Corentin Chary" <corentincj@iksaif.net>
@@ -42,7 +42,7 @@ Description:
 		    `------------ Availables modes
 		For example, 0x301 means: mode 1 selected, 3 available modes.
 
-What:		/sys/devices/platform/eeepc-laptop/available_cpufv
+What:		/sys/devices/platform/eeepc/available_cpufv
 Date:		Jun 2009
 KernelVersion:	2.6.31
 Contact:	"Corentin Chary" <corentincj@iksaif.net>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-power linux-libre-2.6.34-gnu1/Documentation/ABI/testing/sysfs-power
--- linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-power	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/ABI/testing/sysfs-power	2010-05-16 17:17:36.000000000 -0400
@@ -101,3 +101,16 @@ Description:
 
 		CAUTION: Using it will cause your machine's real-time (CMOS)
 		clock to be set to a random invalid time after a resume.
+
+What:		/sys/power/pm_async
+Date:		January 2009
+Contact:	Rafael J. Wysocki <rjw@sisk.pl>
+Description:
+		The /sys/power/pm_async file controls the switch allowing the
+		user space to enable or disable asynchronous suspend and resume
+		of devices.  If enabled, this feature will cause some device
+		drivers' suspend and resume callbacks to be executed in parallel
+		with each other and with the main suspend thread.  It is enabled
+		if this file contains "1", which is the default.  It may be
+		disabled by writing "0" to this file, in which case all devices
+		will be suspended and resumed synchronously.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/arm/memory.txt linux-libre-2.6.34-gnu1/Documentation/arm/memory.txt
--- linux-libre-2.6.33-gnu1/Documentation/arm/memory.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/arm/memory.txt	2010-05-16 17:17:36.000000000 -0400
@@ -59,7 +59,11 @@ PAGE_OFFSET	high_memory-1	Kernel direct-
 				This maps the platforms RAM, and typically
 				maps all platform RAM in a 1:1 relationship.
 
-TASK_SIZE	PAGE_OFFSET-1	Kernel module space
+PKMAP_BASE	PAGE_OFFSET-1	Permanent kernel mappings
+				One way of mapping HIGHMEM pages into kernel
+				space.
+
+MODULES_VADDR	MODULES_END-1	Kernel module space
 				Kernel modules inserted via insmod are
 				placed here using dynamic mappings.
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/arm/Samsung/clksrc-change-registers.awk linux-libre-2.6.34-gnu1/Documentation/arm/Samsung/clksrc-change-registers.awk
--- linux-libre-2.6.33-gnu1/Documentation/arm/Samsung/clksrc-change-registers.awk	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/arm/Samsung/clksrc-change-registers.awk	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,167 @@
+#!/usr/bin/awk -f
+#
+# Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+#
+# Released under GPLv2
+
+# example usage
+# ./clksrc-change-registers.awk arch/arm/plat-s5pc1xx/include/plat/regs-clock.h < src > dst
+
+function extract_value(s)
+{
+    eqat = index(s, "=")
+    comat = index(s, ",")
+    return substr(s, eqat+2, (comat-eqat)-2)
+}
+
+function remove_brackets(b)
+{
+    return substr(b, 2, length(b)-2)
+}
+
+function splitdefine(l, p)
+{
+    r = split(l, tp)
+
+    p[0] = tp[2]
+    p[1] = remove_brackets(tp[3])
+}
+
+function find_length(f)
+{
+    if (0)
+	printf "find_length " f "\n" > "/dev/stderr"
+
+    if (f ~ /0x1/)
+	return 1
+    else if (f ~ /0x3/)
+	return 2
+    else if (f ~ /0x7/)
+	return 3
+    else if (f ~ /0xf/)
+	return 4
+
+    printf "unknown legnth " f "\n" > "/dev/stderr"
+    exit
+}
+
+function find_shift(s)
+{
+    id = index(s, "<")
+    if (id <= 0) {
+	printf "cannot find shift " s "\n" > "/dev/stderr"
+	exit
+    }
+
+    return substr(s, id+2)
+}
+
+
+BEGIN {
+    if (ARGC < 2) {
+	print "too few arguments" > "/dev/stderr"
+	exit
+    }
+
+# read the header file and find the mask values that we will need
+# to replace and create an associative array of values
+
+    while (getline line < ARGV[1] > 0) {
+	if (line ~ /\#define.*_MASK/ &&
+	    !(line ~ /S5PC100_EPLL_MASK/) &&
+	    !(line ~ /USB_SIG_MASK/)) {
+	    splitdefine(line, fields)
+	    name = fields[0]
+	    if (0)
+		printf "MASK " line "\n" > "/dev/stderr"
+	    dmask[name,0] = find_length(fields[1])
+	    dmask[name,1] = find_shift(fields[1])
+	    if (0)
+		printf "=> '" name "' LENGTH=" dmask[name,0] " SHIFT=" dmask[name,1] "\n" > "/dev/stderr"
+	} else {
+	}
+    }
+
+    delete ARGV[1]
+}
+
+/clksrc_clk.*=.*{/ {
+    shift=""
+    mask=""
+    divshift=""
+    reg_div=""
+    reg_src=""
+    indent=1
+
+    print $0
+
+    for(; indent >= 1;) {
+	if ((getline line) <= 0) {
+	    printf "unexpected end of file" > "/dev/stderr"
+	    exit 1;
+	}
+
+	if (line ~ /\.shift/) {
+	    shift = extract_value(line)
+	} else if (line ~ /\.mask/) {
+	    mask = extract_value(line)
+	} else if (line ~ /\.reg_divider/) {
+	    reg_div = extract_value(line)
+	} else if (line ~ /\.reg_source/) {
+	    reg_src = extract_value(line)
+	} else if (line ~ /\.divider_shift/) {
+	    divshift = extract_value(line)
+	} else if (line ~ /{/) {
+		indent++
+		print line
+	    } else if (line ~ /}/) {
+	    indent--
+
+	    if (indent == 0) {
+		if (0) {
+		    printf "shift '" shift   "' ='" dmask[shift,0] "'\n" > "/dev/stderr"
+		    printf "mask  '" mask    "'\n" > "/dev/stderr"
+		    printf "dshft '" divshift "'\n" > "/dev/stderr"
+		    printf "rdiv  '" reg_div "'\n" > "/dev/stderr"
+		    printf "rsrc  '" reg_src "'\n" > "/dev/stderr"
+		}
+
+		generated = mask
+		sub(reg_src, reg_div, generated)
+
+		if (0) {
+		    printf "/* rsrc " reg_src " */\n"
+		    printf "/* rdiv " reg_div " */\n"
+		    printf "/* shift " shift " */\n"
+		    printf "/* mask " mask " */\n"
+		    printf "/* generated " generated " */\n"
+		}
+
+		if (reg_div != "") {
+		    printf "\t.reg_div = { "
+		    printf ".reg = " reg_div ", "
+		    printf ".shift = " dmask[generated,1] ", "
+		    printf ".size = " dmask[generated,0] ", "
+		    printf "},\n"
+		}
+
+		printf "\t.reg_src = { "
+		printf ".reg = " reg_src ", "
+		printf ".shift = " dmask[mask,1] ", "
+		printf ".size = " dmask[mask,0] ", "
+
+		printf "},\n"
+
+	    }
+
+	    print line
+	} else {
+	    print line
+	}
+
+	if (0)
+	    printf indent ":" line "\n" > "/dev/stderr"
+    }
+}
+
+// && ! /clksrc_clk.*=.*{/ { print $0 }
diff -druNp linux-libre-2.6.33-gnu1/Documentation/arm/Samsung/Overview.txt linux-libre-2.6.34-gnu1/Documentation/arm/Samsung/Overview.txt
--- linux-libre-2.6.33-gnu1/Documentation/arm/Samsung/Overview.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/arm/Samsung/Overview.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,86 @@
+		Samsung ARM Linux Overview
+		==========================
+
+Introduction
+------------
+
+  The Samsung range of ARM SoCs spans many similar devices, from the initial
+  ARM9 through to the newest ARM cores. This document shows an overview of
+  the current kernel support, how to use it and where to find the code
+  that supports this.
+
+  The currently supported SoCs are:
+
+  - S3C24XX: See Documentation/arm/Samsung-S3C24XX/Overview.txt for full list
+  - S3C64XX: S3C6400 and S3C6410
+  - S5PC6440
+
+  S5PC100 and S5PC110 support is currently being merged
+
+
+S3C24XX Systems
+---------------
+
+  There is still documentation in Documnetation/arm/Samsung-S3C24XX/ which
+  deals with the architecture and drivers specific to these devices.
+
+  See Documentation/arm/Samsung-S3C24XX/Overview.txt for more information
+  on the implementation details and specific support.
+
+
+Configuration
+-------------
+
+  A number of configurations are supplied, as there is no current way of
+  unifying all the SoCs into one kernel.
+
+  s5p6440_defconfig - S5P6440 specific default configuration
+  s5pc100_defconfig - S5PC100 specific default configuration
+
+
+Layout
+------
+
+  The directory layout is currently being restructured, and consists of
+  several platform directories and then the machine specific directories
+  of the CPUs being built for.
+
+  plat-samsung provides the base for all the implementations, and is the
+  last in the line of include directories that are processed for the build
+  specific information. It contains the base clock, GPIO and device definitions
+  to get the system running.
+
+  plat-s3c is the s3c24xx/s3c64xx platform directory, although it is currently
+  involved in other builds this will be phased out once the relevant code is
+  moved elsewhere.
+
+  plat-s3c24xx is for s3c24xx specific builds, see the S3C24XX docs.
+
+  plat-s3c64xx is for the s3c64xx specific bits, see the S3C24XX docs.
+
+  plat-s5p is for s5p specific builds, more to be added.
+
+
+  [ to finish ]
+
+
+Port Contributors
+-----------------
+
+  Ben Dooks (BJD)
+  Vincent Sanders
+  Herbert Potzl
+  Arnaud Patard (RTP)
+  Roc Wu
+  Klaus Fetscher
+  Dimitry Andric
+  Shannon Holland
+  Guillaume Gourat (NexVision)
+  Christer Weinigel (wingel) (Acer N30)
+  Lucas Correia Villa Real (S3C2400 port)
+
+
+Document Author
+---------------
+
+Copyright 2009-2010 Ben Dooks <ben-linux@fluff.org>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/CPUfreq.txt linux-libre-2.6.34-gnu1/Documentation/arm/Samsung-S3C24XX/CPUfreq.txt
--- linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/CPUfreq.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/arm/Samsung-S3C24XX/CPUfreq.txt	2010-05-16 17:17:36.000000000 -0400
@@ -14,8 +14,8 @@ Introduction
  how the clocks are arranged. The first implementation used as single
  PLL to feed the ARM, memory and peripherals via a series of dividers
  and muxes and this is the implementation that is documented here. A
- newer version where there is a seperate PLL and clock divider for the
- ARM core is available as a seperate driver.
+ newer version where there is a separate PLL and clock divider for the
+ ARM core is available as a separate driver.
 
 
 Layout
diff -druNp linux-libre-2.6.33-gnu1/Documentation/block/biodoc.txt linux-libre-2.6.34-gnu1/Documentation/block/biodoc.txt
--- linux-libre-2.6.33-gnu1/Documentation/block/biodoc.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/block/biodoc.txt	2010-05-16 17:17:36.000000000 -0400
@@ -1162,8 +1162,8 @@ where a driver received a request ala th
 
 As mentioned, there is no virtual mapping of a bio. For DMA, this is
 not a problem as the driver probably never will need a virtual mapping.
-Instead it needs a bus mapping (pci_map_page for a single segment or
-use blk_rq_map_sg for scatter gather) to be able to ship it to the driver. For
+Instead it needs a bus mapping (dma_map_page for a single segment or
+use dma_map_sg for scatter gather) to be able to ship it to the driver. For
 PIO drivers (or drivers that need to revert to PIO transfer once in a
 while (IDE for example)), where the CPU is doing the actual data
 transfer a virtual mapping is needed. If the driver supports highmem I/O,
diff -druNp linux-libre-2.6.33-gnu1/Documentation/block/queue-sysfs.txt linux-libre-2.6.34-gnu1/Documentation/block/queue-sysfs.txt
--- linux-libre-2.6.33-gnu1/Documentation/block/queue-sysfs.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/block/queue-sysfs.txt	2010-05-16 17:17:36.000000000 -0400
@@ -25,11 +25,11 @@ size allowed by the hardware.
 
 nomerges (RW)
 -------------
-This enables the user to disable the lookup logic involved with IO merging
-requests in the block layer. Merging may still occur through a direct
-1-hit cache, since that comes for (almost) free. The IO scheduler will not
-waste cycles doing tree/hash lookups for merges if nomerges is 1. Defaults
-to 0, enabling all merges.
+This enables the user to disable the lookup logic involved with IO
+merging requests in the block layer. By default (0) all merges are
+enabled. When set to 1 only simple one-hit merges will be tried. When
+set to 2 no merge algorithms will be tried (including one-hit or more
+complex tree/hash lookups).
 
 nr_requests (RW)
 ----------------
diff -druNp linux-libre-2.6.33-gnu1/Documentation/cachetlb.txt linux-libre-2.6.34-gnu1/Documentation/cachetlb.txt
--- linux-libre-2.6.33-gnu1/Documentation/cachetlb.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/cachetlb.txt	2010-05-16 17:17:36.000000000 -0400
@@ -88,12 +88,12 @@ changes occur:
 	This is used primarily during fault processing.
 
 5) void update_mmu_cache(struct vm_area_struct *vma,
-			 unsigned long address, pte_t pte)
+			 unsigned long address, pte_t *ptep)
 
 	At the end of every page fault, this routine is invoked to
 	tell the architecture specific code that a translation
-	described by "pte" now exists at virtual address "address"
-	for address space "vma->vm_mm", in the software page tables.
+	now exists at virtual address "address" for address space
+	"vma->vm_mm", in the software page tables.
 
 	A port may use this information in any way it so chooses.
 	For example, it could use this event to pre-load TLB
@@ -377,3 +377,27 @@ maps this page at its virtual address.
 	All the functionality of flush_icache_page can be implemented in
 	flush_dcache_page and update_mmu_cache. In 2.7 the hope is to
 	remove this interface completely.
+
+The final category of APIs is for I/O to deliberately aliased address
+ranges inside the kernel.  Such aliases are set up by use of the
+vmap/vmalloc API.  Since kernel I/O goes via physical pages, the I/O
+subsystem assumes that the user mapping and kernel offset mapping are
+the only aliases.  This isn't true for vmap aliases, so anything in
+the kernel trying to do I/O to vmap areas must manually manage
+coherency.  It must do this by flushing the vmap range before doing
+I/O and invalidating it after the I/O returns.
+
+  void flush_kernel_vmap_range(void *vaddr, int size)
+       flushes the kernel cache for a given virtual address range in
+       the vmap area.  This is to make sure that any data the kernel
+       modified in the vmap range is made visible to the physical
+       page.  The design is to make this area safe to perform I/O on.
+       Note that this API does *not* also flush the offset map alias
+       of the area.
+
+  void invalidate_kernel_vmap_range(void *vaddr, int size) invalidates
+       the cache for a given virtual address range in the vmap area
+       which prevents the processor from making the cache stale by
+       speculatively reading data while the I/O was occurring to the
+       physical pages.  This is only necessary for data reads into the
+       vmap area.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/cdrom/ide-cd linux-libre-2.6.34-gnu1/Documentation/cdrom/ide-cd
--- linux-libre-2.6.33-gnu1/Documentation/cdrom/ide-cd	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/cdrom/ide-cd	2010-05-16 17:17:36.000000000 -0400
@@ -159,42 +159,7 @@ two arguments:  the CDROM device, and th
 to change.  If the slot number is -1, the drive is unloaded.
 
 
-4. Compilation options
-----------------------
-
-There are a few additional options which can be set when compiling the
-driver.  Most people should not need to mess with any of these; they
-are listed here simply for completeness.  A compilation option can be
-enabled by adding a line of the form `#define <option> 1' to the top
-of ide-cd.c.  All these options are disabled by default.
-
-VERBOSE_IDE_CD_ERRORS
-  If this is set, ATAPI error codes will be translated into textual
-  descriptions.  In addition, a dump is made of the command which
-  provoked the error.  This is off by default to save the memory used
-  by the (somewhat long) table of error descriptions.  
-
-STANDARD_ATAPI
-  If this is set, the code needed to deal with certain drives which do
-  not properly implement the ATAPI spec will be disabled.  If you know
-  your drive implements ATAPI properly, you can turn this on to get a
-  slightly smaller kernel.
-
-NO_DOOR_LOCKING
-  If this is set, the driver will never attempt to lock the door of
-  the drive.
-
-CDROM_NBLOCKS_BUFFER
-  This sets the size of the buffer to be used for a CDROMREADAUDIO
-  ioctl.  The default is 8.
-
-TEST
-  This currently enables an additional ioctl which enables a user-mode
-  program to execute an arbitrary packet command.  See the source for
-  details.  This should be left off unless you know what you're doing.
-
-
-5. Common problems
+4. Common problems
 ------------------
 
 This section discusses some common problems encountered when trying to
@@ -371,7 +336,7 @@ f. Data corruption.
     expense of low system performance.
 
 
-6. cdchange.c
+5. cdchange.c
 -------------
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/Documentation/cgroups/cgroup_event_listener.c linux-libre-2.6.34-gnu1/Documentation/cgroups/cgroup_event_listener.c
--- linux-libre-2.6.33-gnu1/Documentation/cgroups/cgroup_event_listener.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/cgroups/cgroup_event_listener.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,110 @@
+/*
+ * cgroup_event_listener.c - Simple listener of cgroup events
+ *
+ * Copyright (C) Kirill A. Shutemov <kirill@shutemov.name>
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/eventfd.h>
+
+#define USAGE_STR "Usage: cgroup_event_listener <path-to-control-file> <args>\n"
+
+int main(int argc, char **argv)
+{
+	int efd = -1;
+	int cfd = -1;
+	int event_control = -1;
+	char event_control_path[PATH_MAX];
+	char line[LINE_MAX];
+	int ret;
+
+	if (argc != 3) {
+		fputs(USAGE_STR, stderr);
+		return 1;
+	}
+
+	cfd = open(argv[1], O_RDONLY);
+	if (cfd == -1) {
+		fprintf(stderr, "Cannot open %s: %s\n", argv[1],
+				strerror(errno));
+		goto out;
+	}
+
+	ret = snprintf(event_control_path, PATH_MAX, "%s/cgroup.event_control",
+			dirname(argv[1]));
+	if (ret >= PATH_MAX) {
+		fputs("Path to cgroup.event_control is too long\n", stderr);
+		goto out;
+	}
+
+	event_control = open(event_control_path, O_WRONLY);
+	if (event_control == -1) {
+		fprintf(stderr, "Cannot open %s: %s\n", event_control_path,
+				strerror(errno));
+		goto out;
+	}
+
+	efd = eventfd(0, 0);
+	if (efd == -1) {
+		perror("eventfd() failed");
+		goto out;
+	}
+
+	ret = snprintf(line, LINE_MAX, "%d %d %s", efd, cfd, argv[2]);
+	if (ret >= LINE_MAX) {
+		fputs("Arguments string is too long\n", stderr);
+		goto out;
+	}
+
+	ret = write(event_control, line, strlen(line) + 1);
+	if (ret == -1) {
+		perror("Cannot write to cgroup.event_control");
+		goto out;
+	}
+
+	while (1) {
+		uint64_t result;
+
+		ret = read(efd, &result, sizeof(result));
+		if (ret == -1) {
+			if (errno == EINTR)
+				continue;
+			perror("Cannot read from eventfd");
+			break;
+		}
+		assert(ret == sizeof(result));
+
+		ret = access(event_control_path, W_OK);
+		if ((ret == -1) && (errno == ENOENT)) {
+				puts("The cgroup seems to have removed.");
+				ret = 0;
+				break;
+		}
+
+		if (ret == -1) {
+			perror("cgroup.event_control "
+					"is not accessable any more");
+			break;
+		}
+
+		printf("%s %s: crossed\n", argv[1], argv[2]);
+	}
+
+out:
+	if (efd >= 0)
+		close(efd);
+	if (event_control >= 0)
+		close(event_control);
+	if (cfd >= 0)
+		close(cfd);
+
+	return (ret != 0);
+}
diff -druNp linux-libre-2.6.33-gnu1/Documentation/cgroups/cgroups.txt linux-libre-2.6.34-gnu1/Documentation/cgroups/cgroups.txt
--- linux-libre-2.6.33-gnu1/Documentation/cgroups/cgroups.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/cgroups/cgroups.txt	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,8 @@ CONTENTS:
 2. Usage Examples and Syntax
   2.1 Basic Usage
   2.2 Attaching processes
+  2.3 Mounting hierarchies by name
+  2.4 Notification API
 3. Kernel API
   3.1 Overview
   3.2 Synchronization
@@ -233,8 +235,7 @@ containing the following files describin
  - cgroup.procs: list of tgids in the cgroup.  This list is not
    guaranteed to be sorted or free of duplicate tgids, and userspace
    should sort/uniquify the list if this property is required.
-   Writing a tgid into this file moves all threads with that tgid into
-   this cgroup.
+   This is a read-only file, for now.
  - notify_on_release flag: run the release agent on exit?
  - release_agent: the path to use for release notifications (this file
    exists in the top cgroup only)
@@ -434,6 +435,25 @@ you give a subsystem a name.
 The name of the subsystem appears as part of the hierarchy description
 in /proc/mounts and /proc/<pid>/cgroups.
 
+2.4 Notification API
+--------------------
+
+There is mechanism which allows to get notifications about changing
+status of a cgroup.
+
+To register new notification handler you need:
+ - create a file descriptor for event notification using eventfd(2);
+ - open a control file to be monitored (e.g. memory.usage_in_bytes);
+ - write "<event_fd> <control_fd> <args>" to cgroup.event_control.
+   Interpretation of args is defined by control file implementation;
+
+eventfd will be woken up by control file implementation or when the
+cgroup is removed.
+
+To unregister notification handler just close eventfd.
+
+NOTE: Support of notifications should be implemented for the control
+file. See documentation for the subsystem.
 
 3. Kernel API
 =============
@@ -488,6 +508,11 @@ Each subsystem should:
 - add an entry in linux/cgroup_subsys.h
 - define a cgroup_subsys object called <name>_subsys
 
+If a subsystem can be compiled as a module, it should also have in its
+module initcall a call to cgroup_load_subsys(), and in its exitcall a
+call to cgroup_unload_subsys(). It should also set its_subsys.module =
+THIS_MODULE in its .c file.
+
 Each subsystem may export the following methods. The only mandatory
 methods are create/destroy. Any others that are null are presumed to
 be successful no-ops.
@@ -536,10 +561,21 @@ returns an error, this will abort the at
 task is passed, then a successful result indicates that *any*
 unspecified task can be moved into the cgroup. Note that this isn't
 called on a fork. If this method returns 0 (success) then this should
-remain valid while the caller holds cgroup_mutex. If threadgroup is
+remain valid while the caller holds cgroup_mutex and it is ensured that either
+attach() or cancel_attach() will be called in future. If threadgroup is
 true, then a successful result indicates that all threads in the given
 thread's threadgroup can be moved together.
 
+void cancel_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
+	       struct task_struct *task, bool threadgroup)
+(cgroup_mutex held by caller)
+
+Called when a task attach operation has failed after can_attach() has succeeded.
+A subsystem whose can_attach() has some side-effects should provide this
+function, so that the subsytem can implement a rollback. If not, not necessary.
+This will be called only about subsystems whose can_attach() operation have
+succeeded.
+
 void attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
 	    struct cgroup *old_cgrp, struct task_struct *task,
 	    bool threadgroup)
diff -druNp linux-libre-2.6.33-gnu1/Documentation/cgroups/cpusets.txt linux-libre-2.6.34-gnu1/Documentation/cgroups/cpusets.txt
--- linux-libre-2.6.33-gnu1/Documentation/cgroups/cpusets.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/cgroups/cpusets.txt	2010-05-16 17:17:36.000000000 -0400
@@ -168,20 +168,20 @@ Each cpuset is represented by a director
 containing (on top of the standard cgroup files) the following
 files describing that cpuset:
 
- - cpus: list of CPUs in that cpuset
- - mems: list of Memory Nodes in that cpuset
- - memory_migrate flag: if set, move pages to cpusets nodes
- - cpu_exclusive flag: is cpu placement exclusive?
- - mem_exclusive flag: is memory placement exclusive?
- - mem_hardwall flag:  is memory allocation hardwalled
- - memory_pressure: measure of how much paging pressure in cpuset
- - memory_spread_page flag: if set, spread page cache evenly on allowed nodes
- - memory_spread_slab flag: if set, spread slab cache evenly on allowed nodes
- - sched_load_balance flag: if set, load balance within CPUs on that cpuset
- - sched_relax_domain_level: the searching range when migrating tasks
+ - cpuset.cpus: list of CPUs in that cpuset
+ - cpuset.mems: list of Memory Nodes in that cpuset
+ - cpuset.memory_migrate flag: if set, move pages to cpusets nodes
+ - cpuset.cpu_exclusive flag: is cpu placement exclusive?
+ - cpuset.mem_exclusive flag: is memory placement exclusive?
+ - cpuset.mem_hardwall flag:  is memory allocation hardwalled
+ - cpuset.memory_pressure: measure of how much paging pressure in cpuset
+ - cpuset.memory_spread_page flag: if set, spread page cache evenly on allowed nodes
+ - cpuset.memory_spread_slab flag: if set, spread slab cache evenly on allowed nodes
+ - cpuset.sched_load_balance flag: if set, load balance within CPUs on that cpuset
+ - cpuset.sched_relax_domain_level: the searching range when migrating tasks
 
 In addition, the root cpuset only has the following file:
- - memory_pressure_enabled flag: compute memory_pressure?
+ - cpuset.memory_pressure_enabled flag: compute memory_pressure?
 
 New cpusets are created using the mkdir system call or shell
 command.  The properties of a cpuset, such as its flags, allowed
@@ -229,7 +229,7 @@ If a cpuset is cpu or mem exclusive, no
 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",
+A cpuset that is cpuset.mem_exclusive *or* cpuset.mem_hardwall is "hardwalled",
 i.e. it restricts kernel allocations for page, buffer and other data
 commonly shared by the kernel across multiple users.  All cpusets,
 whether hardwalled or not, restrict allocations of memory for user
@@ -304,15 +304,15 @@ times 1000.
 ---------------------------
 There are two boolean flag files per cpuset that control where the
 kernel allocates pages for the file system buffers and related in
-kernel data structures.  They are called 'memory_spread_page' and
-'memory_spread_slab'.
+kernel data structures.  They are called 'cpuset.memory_spread_page' and
+'cpuset.memory_spread_slab'.
 
-If the per-cpuset boolean flag file 'memory_spread_page' is set, then
+If the per-cpuset boolean flag file 'cpuset.memory_spread_page' is set, then
 the kernel will spread the file system buffers (page cache) evenly
 over all the nodes that the faulting task is allowed to use, instead
 of preferring to put those pages on the node where the task is running.
 
-If the per-cpuset boolean flag file 'memory_spread_slab' is set,
+If the per-cpuset boolean flag file 'cpuset.memory_spread_slab' is set,
 then the kernel will spread some file system related slab caches,
 such as for inodes and dentries evenly over all the nodes that the
 faulting task is allowed to use, instead of preferring to put those
@@ -337,21 +337,21 @@ their containing tasks memory spread set
 is turned off, then the currently specified NUMA mempolicy once again
 applies to memory page allocations.
 
-Both 'memory_spread_page' and 'memory_spread_slab' are boolean flag
+Both 'cpuset.memory_spread_page' and 'cpuset.memory_spread_slab' are boolean flag
 files.  By default they contain "0", meaning that the feature is off
 for that cpuset.  If a "1" is written to that file, then that turns
 the named feature on.
 
 The implementation is simple.
 
-Setting the flag 'memory_spread_page' turns on a per-process flag
+Setting the flag 'cpuset.memory_spread_page' turns on a per-process flag
 PF_SPREAD_PAGE for each task that is in that cpuset or subsequently
 joins that cpuset.  The page allocation calls for the page cache
 is modified to perform an inline check for this PF_SPREAD_PAGE task
 flag, and if set, a call to a new routine cpuset_mem_spread_node()
 returns the node to prefer for the allocation.
 
-Similarly, setting 'memory_spread_slab' turns on the flag
+Similarly, setting 'cpuset.memory_spread_slab' turns on the flag
 PF_SPREAD_SLAB, and appropriately marked slab caches will allocate
 pages from the node returned by cpuset_mem_spread_node().
 
@@ -404,24 +404,24 @@ the following two situations:
     system overhead on those CPUs, including avoiding task load
     balancing if that is not needed.
 
-When the per-cpuset flag "sched_load_balance" is enabled (the default
-setting), it requests that all the CPUs in that cpusets allowed 'cpus'
+When the per-cpuset flag "cpuset.sched_load_balance" is enabled (the default
+setting), it requests that all the CPUs in that cpusets allowed 'cpuset.cpus'
 be contained in a single sched domain, ensuring that load balancing
 can move a task (not otherwised pinned, as by sched_setaffinity)
 from any CPU in that cpuset to any other.
 
-When the per-cpuset flag "sched_load_balance" is disabled, then the
+When the per-cpuset flag "cpuset.sched_load_balance" is disabled, then the
 scheduler will avoid load balancing across the CPUs in that cpuset,
 --except-- in so far as is necessary because some overlapping cpuset
 has "sched_load_balance" enabled.
 
-So, for example, if the top cpuset has the flag "sched_load_balance"
+So, for example, if the top cpuset has the flag "cpuset.sched_load_balance"
 enabled, then the scheduler will have one sched domain covering all
-CPUs, and the setting of the "sched_load_balance" flag in any other
+CPUs, and the setting of the "cpuset.sched_load_balance" flag in any other
 cpusets won't matter, as we're already fully load balancing.
 
 Therefore in the above two situations, the top cpuset flag
-"sched_load_balance" should be disabled, and only some of the smaller,
+"cpuset.sched_load_balance" should be disabled, and only some of the smaller,
 child cpusets have this flag enabled.
 
 When doing this, you don't usually want to leave any unpinned tasks in
@@ -433,7 +433,7 @@ scheduler might not consider the possibi
 task to that underused CPU.
 
 Of course, tasks pinned to a particular CPU can be left in a cpuset
-that disables "sched_load_balance" as those tasks aren't going anywhere
+that disables "cpuset.sched_load_balance" as those tasks aren't going anywhere
 else anyway.
 
 There is an impedance mismatch here, between cpusets and sched domains.
@@ -443,19 +443,19 @@ overlap and each CPU is in at most one s
 It is necessary for sched domains to be flat because load balancing
 across partially overlapping sets of CPUs would risk unstable dynamics
 that would be beyond our understanding.  So if each of two partially
-overlapping cpusets enables the flag 'sched_load_balance', then we
+overlapping cpusets enables the flag 'cpuset.sched_load_balance', then we
 form a single sched domain that is a superset of both.  We won't move
 a task to a CPU outside it cpuset, but the scheduler load balancing
 code might waste some compute cycles considering that possibility.
 
 This mismatch is why there is not a simple one-to-one relation
-between which cpusets have the flag "sched_load_balance" enabled,
+between which cpusets have the flag "cpuset.sched_load_balance" enabled,
 and the sched domain configuration.  If a cpuset enables the flag, it
 will get balancing across all its CPUs, but if it disables the flag,
 it will only be assured of no load balancing if no other overlapping
 cpuset enables the flag.
 
-If two cpusets have partially overlapping 'cpus' allowed, and only
+If two cpusets have partially overlapping 'cpuset.cpus' allowed, and only
 one of them has this flag enabled, then the other may find its
 tasks only partially load balanced, just on the overlapping CPUs.
 This is just the general case of the top_cpuset example given a few
@@ -468,23 +468,23 @@ load balancing to the other CPUs.
 1.7.1 sched_load_balance implementation details.
 ------------------------------------------------
 
-The per-cpuset flag 'sched_load_balance' defaults to enabled (contrary
+The per-cpuset flag 'cpuset.sched_load_balance' defaults to enabled (contrary
 to most cpuset flags.)  When enabled for a cpuset, the kernel will
 ensure that it can load balance across all the CPUs in that cpuset
 (makes sure that all the CPUs in the cpus_allowed of that cpuset are
 in the same sched domain.)
 
-If two overlapping cpusets both have 'sched_load_balance' enabled,
+If two overlapping cpusets both have 'cpuset.sched_load_balance' enabled,
 then they will be (must be) both in the same sched domain.
 
-If, as is the default, the top cpuset has 'sched_load_balance' enabled,
+If, as is the default, the top cpuset has 'cpuset.sched_load_balance' enabled,
 then by the above that means there is a single sched domain covering
 the whole system, regardless of any other cpuset settings.
 
 The kernel commits to user space that it will avoid load balancing
 where it can.  It will pick as fine a granularity partition of sched
 domains as it can while still providing load balancing for any set
-of CPUs allowed to a cpuset having 'sched_load_balance' enabled.
+of CPUs allowed to a cpuset having 'cpuset.sched_load_balance' enabled.
 
 The internal kernel cpuset to scheduler interface passes from the
 cpuset code to the scheduler code a partition of the load balanced
@@ -495,9 +495,9 @@ all the CPUs that must be load balanced.
 The cpuset code builds a new such partition and passes it to the
 scheduler sched domain setup code, to have the sched domains rebuilt
 as necessary, whenever:
- - the 'sched_load_balance' flag of a cpuset with non-empty CPUs changes,
+ - the 'cpuset.sched_load_balance' flag of a cpuset with non-empty CPUs changes,
  - or CPUs come or go from a cpuset with this flag enabled,
- - or 'sched_relax_domain_level' value of a cpuset with non-empty CPUs
+ - or 'cpuset.sched_relax_domain_level' value of a cpuset with non-empty CPUs
    and with this flag enabled changes,
  - or a cpuset with non-empty CPUs and with this flag enabled is removed,
  - or a cpu is offlined/onlined.
@@ -542,7 +542,7 @@ As the result, task B on CPU X need to w
 on the next tick.  For some applications in special situation, waiting
 1 tick may be too long.
 
-The 'sched_relax_domain_level' file allows you to request changing
+The 'cpuset.sched_relax_domain_level' file allows you to request changing
 this searching range as you like.  This file takes int value which
 indicates size of searching range in levels ideally as follows,
 otherwise initial value -1 that indicates the cpuset has no request.
@@ -559,8 +559,8 @@ The system default is architecture depen
 can be changed using the relax_domain_level= boot parameter.
 
 This file is per-cpuset and affect the sched domain where the cpuset
-belongs to.  Therefore if the flag 'sched_load_balance' of a cpuset
-is disabled, then 'sched_relax_domain_level' have no effect since
+belongs to.  Therefore if the flag 'cpuset.sched_load_balance' of a cpuset
+is disabled, then 'cpuset.sched_relax_domain_level' have no effect since
 there is no sched domain belonging the cpuset.
 
 If multiple cpusets are overlapping and hence they form a single sched
@@ -607,9 +607,9 @@ from one cpuset to another, then the ker
 memory placement, as above, the next time that the kernel attempts
 to allocate a page of memory for that task.
 
-If a cpuset has its 'cpus' modified, then each task in that cpuset
+If a cpuset has its 'cpuset.cpus' modified, then each task in that cpuset
 will have its allowed CPU placement changed immediately.  Similarly,
-if a tasks pid is written to another cpusets 'tasks' file, then its
+if a tasks pid is written to another cpusets 'cpuset.tasks' file, then its
 allowed CPU placement is changed immediately.  If such a task had been
 bound to some subset of its cpuset using the sched_setaffinity() call,
 the task will be allowed to run on any CPU allowed in its new cpuset,
@@ -622,8 +622,8 @@ and the processor placement is updated i
 Normally, once a page is allocated (given a physical page
 of main memory) then that page stays on whatever node it
 was allocated, so long as it remains allocated, even if the
-cpusets memory placement policy 'mems' subsequently changes.
-If the cpuset flag file 'memory_migrate' is set true, then when
+cpusets memory placement policy 'cpuset.mems' subsequently changes.
+If the cpuset flag file 'cpuset.memory_migrate' is set true, then when
 tasks are attached to that cpuset, any pages that task had
 allocated to it on nodes in its previous cpuset are migrated
 to the tasks new cpuset. The relative placement of the page within
@@ -631,12 +631,12 @@ the cpuset is preserved during these mig
 For example if the page was on the second valid node of the prior cpuset
 then the page will be placed on the second valid node of the new cpuset.
 
-Also if 'memory_migrate' is set true, then if that cpusets
-'mems' file is modified, pages allocated to tasks in that
-cpuset, that were on nodes in the previous setting of 'mems',
+Also if 'cpuset.memory_migrate' is set true, then if that cpusets
+'cpuset.mems' file is modified, pages allocated to tasks in that
+cpuset, that were on nodes in the previous setting of 'cpuset.mems',
 will be moved to nodes in the new setting of 'mems.'
 Pages that were not in the tasks prior cpuset, or in the cpusets
-prior 'mems' setting, will not be moved.
+prior 'cpuset.mems' setting, will not be moved.
 
 There is an exception to the above.  If hotplug functionality is used
 to remove all the CPUs that are currently assigned to a cpuset,
@@ -678,8 +678,8 @@ and then start a subshell 'sh' in that c
   cd /dev/cpuset
   mkdir Charlie
   cd Charlie
-  /bin/echo 2-3 > cpus
-  /bin/echo 1 > mems
+  /bin/echo 2-3 > cpuset.cpus
+  /bin/echo 1 > cpuset.mems
   /bin/echo $$ > tasks
   sh
   # The subshell 'sh' is now running in cpuset Charlie
@@ -725,10 +725,13 @@ Now you want to do something with this c
 
 In this directory you can find several files:
 # ls
-cpu_exclusive  memory_migrate      mems                      tasks
-cpus           memory_pressure     notify_on_release
-mem_exclusive  memory_spread_page  sched_load_balance
-mem_hardwall   memory_spread_slab  sched_relax_domain_level
+cpuset.cpu_exclusive       cpuset.memory_spread_slab
+cpuset.cpus                cpuset.mems
+cpuset.mem_exclusive       cpuset.sched_load_balance
+cpuset.mem_hardwall        cpuset.sched_relax_domain_level
+cpuset.memory_migrate      notify_on_release
+cpuset.memory_pressure     tasks
+cpuset.memory_spread_page
 
 Reading them will give you information about the state of this cpuset:
 the CPUs and Memory Nodes it can use, the processes that are using
@@ -736,13 +739,13 @@ it, its properties.  By writing to these
 the cpuset.
 
 Set some flags:
-# /bin/echo 1 > cpu_exclusive
+# /bin/echo 1 > cpuset.cpu_exclusive
 
 Add some cpus:
-# /bin/echo 0-7 > cpus
+# /bin/echo 0-7 > cpuset.cpus
 
 Add some mems:
-# /bin/echo 0-7 > mems
+# /bin/echo 0-7 > cpuset.mems
 
 Now attach your shell to this cpuset:
 # /bin/echo $$ > tasks
@@ -774,28 +777,28 @@ echo "/sbin/cpuset_release_agent" > /dev
 This is the syntax to use when writing in the cpus or mems files
 in cpuset directories:
 
-# /bin/echo 1-4 > cpus		-> set cpus list to cpus 1,2,3,4
-# /bin/echo 1,2,3,4 > cpus	-> set cpus list to cpus 1,2,3,4
+# /bin/echo 1-4 > cpuset.cpus		-> set cpus list to cpus 1,2,3,4
+# /bin/echo 1,2,3,4 > cpuset.cpus	-> set cpus list to cpus 1,2,3,4
 
 To add a CPU to a cpuset, write the new list of CPUs including the
 CPU to be added. To add 6 to the above cpuset:
 
-# /bin/echo 1-4,6 > cpus	-> set cpus list to cpus 1,2,3,4,6
+# /bin/echo 1-4,6 > cpuset.cpus	-> set cpus list to cpus 1,2,3,4,6
 
 Similarly to remove a CPU from a cpuset, write the new list of CPUs
 without the CPU to be removed.
 
 To remove all the CPUs:
 
-# /bin/echo "" > cpus		-> clear cpus list
+# /bin/echo "" > cpuset.cpus		-> clear cpus list
 
 2.3 Setting flags
 -----------------
 
 The syntax is very simple:
 
-# /bin/echo 1 > cpu_exclusive 	-> set flag 'cpu_exclusive'
-# /bin/echo 0 > cpu_exclusive 	-> unset flag 'cpu_exclusive'
+# /bin/echo 1 > cpuset.cpu_exclusive 	-> set flag 'cpuset.cpu_exclusive'
+# /bin/echo 0 > cpuset.cpu_exclusive 	-> unset flag 'cpuset.cpu_exclusive'
 
 2.4 Attaching processes
 -----------------------
diff -druNp linux-libre-2.6.33-gnu1/Documentation/cgroups/memcg_test.txt linux-libre-2.6.34-gnu1/Documentation/cgroups/memcg_test.txt
--- linux-libre-2.6.33-gnu1/Documentation/cgroups/memcg_test.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/cgroups/memcg_test.txt	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 Memory Resource Controller(Memcg)  Implementation Memo.
-Last Updated: 2009/1/20
-Base Kernel Version: based on 2.6.29-rc2.
+Last Updated: 2010/2
+Base Kernel Version: based on 2.6.33-rc7-mm(candidate for 34).
 
 Because VM is getting complex (one of reasons is memcg...), memcg's behavior
 is complex. This is a document for memcg's internal behavior.
@@ -337,7 +337,7 @@ Under below explanation, we assume CONFI
 	race and lock dependency with other cgroup subsystems.
 
 	example)
-	# mount -t cgroup none /cgroup -t cpuset,memory,cpu,devices
+	# mount -t cgroup none /cgroup -o cpuset,memory,cpu,devices
 
 	and do task move, mkdir, rmdir etc...under this.
 
@@ -348,7 +348,7 @@ Under below explanation, we assume CONFI
 
 	For example, test like following is good.
 	(Shell-A)
-	# mount -t cgroup none /cgroup -t memory
+	# mount -t cgroup none /cgroup -o memory
 	# mkdir /cgroup/test
 	# echo 40M > /cgroup/test/memory.limit_in_bytes
 	# echo 0 > /cgroup/test/tasks
@@ -378,3 +378,42 @@ Under below explanation, we assume CONFI
 	#echo 50M > memory.limit_in_bytes
 	#echo 50M > memory.memsw.limit_in_bytes
 	run 51M of malloc
+
+ 9.9 Move charges at task migration
+	Charges associated with a task can be moved along with task migration.
+
+	(Shell-A)
+	#mkdir /cgroup/A
+	#echo $$ >/cgroup/A/tasks
+	run some programs which uses some amount of memory in /cgroup/A.
+
+	(Shell-B)
+	#mkdir /cgroup/B
+	#echo 1 >/cgroup/B/memory.move_charge_at_immigrate
+	#echo "pid of the program running in group A" >/cgroup/B/tasks
+
+	You can see charges have been moved by reading *.usage_in_bytes or
+	memory.stat of both A and B.
+	See 8.2 of Documentation/cgroups/memory.txt to see what value should be
+	written to move_charge_at_immigrate.
+
+ 9.10 Memory thresholds
+	Memory controler implements memory thresholds using cgroups notification
+	API. You can use Documentation/cgroups/cgroup_event_listener.c to test
+	it.
+
+	(Shell-A) Create cgroup and run event listener
+	# mkdir /cgroup/A
+	# ./cgroup_event_listener /cgroup/A/memory.usage_in_bytes 5M
+
+	(Shell-B) Add task to cgroup and try to allocate and free memory
+	# echo $$ >/cgroup/A/tasks
+	# a="$(dd if=/dev/zero bs=1M count=10)"
+	# a=
+
+	You will see message from cgroup_event_listener every time you cross
+	the thresholds.
+
+	Use /cgroup/A/memory.memsw.usage_in_bytes to test memsw thresholds.
+
+	It's good idea to test root cgroup as well.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/cgroups/memory.txt linux-libre-2.6.34-gnu1/Documentation/cgroups/memory.txt
--- linux-libre-2.6.33-gnu1/Documentation/cgroups/memory.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/cgroups/memory.txt	2010-05-16 17:17:36.000000000 -0400
@@ -182,6 +182,8 @@ list.
 NOTE: Reclaim does not work for the root cgroup, since we cannot set any
 limits on the root cgroup.
 
+Note2: When panic_on_oom is set to "2", the whole system will panic.
+
 2. Locking
 
 The memory controller uses the following hierarchy
@@ -262,10 +264,12 @@ some of the pages cached in the cgroup (
 4.2 Task migration
 
 When a task migrates from one cgroup to another, it's charge is not
-carried forward. The pages allocated from the original cgroup still
+carried forward by default. The pages allocated from the original cgroup still
 remain charged to it, the charge is dropped when the page is freed or
 reclaimed.
 
+Note: You can move charges of a task along with task migration. See 8.
+
 4.3 Removing a cgroup
 
 A cgroup can be removed by rmdir, but as discussed in sections 4.1 and 4.2, a
@@ -336,7 +340,7 @@ Note:
 5.3 swappiness
   Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only.
 
-  Following cgroups' swapiness can't be changed.
+  Following cgroups' swappiness 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.
@@ -377,7 +381,8 @@ The feature can be disabled by
 NOTE1: Enabling/disabling will fail if the cgroup already has other
 cgroups created below it.
 
-NOTE2: This feature can be enabled/disabled per subtree.
+NOTE2: When panic_on_oom is set to "2", the whole system will panic in
+case of an oom event in any cgroup.
 
 7. Soft limits
 
@@ -414,7 +419,76 @@ NOTE1: Soft limits take effect over a lo
 NOTE2: It is recommended to set the soft limit always below the hard limit,
        otherwise the hard limit will take precedence.
 
-8. TODO
+8. Move charges at task migration
+
+Users can move charges associated with a task along with task migration, that
+is, uncharge task's pages from the old cgroup and charge them to the new cgroup.
+This feature is not supported in !CONFIG_MMU environments because of lack of
+page tables.
+
+8.1 Interface
+
+This feature is disabled by default. It can be enabled(and disabled again) by
+writing to memory.move_charge_at_immigrate of the destination cgroup.
+
+If you want to enable it:
+
+# echo (some positive value) > memory.move_charge_at_immigrate
+
+Note: Each bits of move_charge_at_immigrate has its own meaning about what type
+      of charges should be moved. See 8.2 for details.
+Note: Charges are moved only when you move mm->owner, IOW, a leader of a thread
+      group.
+Note: If we cannot find enough space for the task in the destination cgroup, we
+      try to make space by reclaiming memory. Task migration may fail if we
+      cannot make enough space.
+Note: It can take several seconds if you move charges in giga bytes order.
+
+And if you want disable it again:
+
+# echo 0 > memory.move_charge_at_immigrate
+
+8.2 Type of charges which can be move
+
+Each bits of move_charge_at_immigrate has its own meaning about what type of
+charges should be moved.
+
+  bit | what type of charges would be moved ?
+ -----+------------------------------------------------------------------------
+   0  | A charge of an anonymous page(or swap of it) used by the target task.
+      | Those pages and swaps must be used only by the target task. You must
+      | enable Swap Extension(see 2.4) to enable move of swap charges.
+
+Note: Those pages and swaps must be charged to the old cgroup.
+Note: More type of pages(e.g. file cache, shmem,) will be supported by other
+      bits in future.
+
+8.3 TODO
+
+- Add support for other types of pages(e.g. file cache, shmem, etc.).
+- Implement madvise(2) to let users decide the vma to be moved or not to be
+  moved.
+- All of moving charge operations are done under cgroup_mutex. It's not good
+  behavior to hold the mutex too long, so we may need some trick.
+
+9. Memory thresholds
+
+Memory controler implements memory thresholds using cgroups notification
+API (see cgroups.txt). It allows to register multiple memory and memsw
+thresholds and gets notifications when it crosses.
+
+To register a threshold application need:
+ - create an eventfd using eventfd(2);
+ - open memory.usage_in_bytes or memory.memsw.usage_in_bytes;
+ - write string like "<event_fd> <memory.usage_in_bytes> <threshold>" to
+   cgroup.event_control.
+
+Application will be notified through eventfd when memory usage crosses
+threshold in any direction.
+
+It's applicable for root and non-root cgroup.
+
+10. TODO
 
 1. Add support for accounting huge pages (as a separate controller)
 2. Make per-cgroup scanner reclaim not-shared pages first
diff -druNp linux-libre-2.6.33-gnu1/Documentation/circular-buffers.txt linux-libre-2.6.34-gnu1/Documentation/circular-buffers.txt
--- linux-libre-2.6.33-gnu1/Documentation/circular-buffers.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/circular-buffers.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,234 @@
+			       ================
+			       CIRCULAR BUFFERS
+			       ================
+
+By: David Howells <dhowells@redhat.com>
+    Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+
+
+Linux provides a number of features that can be used to implement circular
+buffering.  There are two sets of such features:
+
+ (1) Convenience functions for determining information about power-of-2 sized
+     buffers.
+
+ (2) Memory barriers for when the producer and the consumer of objects in the
+     buffer don't want to share a lock.
+
+To use these facilities, as discussed below, there needs to be just one
+producer and just one consumer.  It is possible to handle multiple producers by
+serialising them, and to handle multiple consumers by serialising them.
+
+
+Contents:
+
+ (*) What is a circular buffer?
+
+ (*) Measuring power-of-2 buffers.
+
+ (*) Using memory barriers with circular buffers.
+     - The producer.
+     - The consumer.
+
+
+==========================
+WHAT IS A CIRCULAR BUFFER?
+==========================
+
+First of all, what is a circular buffer?  A circular buffer is a buffer of
+fixed, finite size into which there are two indices:
+
+ (1) A 'head' index - the point at which the producer inserts items into the
+     buffer.
+
+ (2) A 'tail' index - the point at which the consumer finds the next item in
+     the buffer.
+
+Typically when the tail pointer is equal to the head pointer, the buffer is
+empty; and the buffer is full when the head pointer is one less than the tail
+pointer.
+
+The head index is incremented when items are added, and the tail index when
+items are removed.  The tail index should never jump the head index, and both
+indices should be wrapped to 0 when they reach the end of the buffer, thus
+allowing an infinite amount of data to flow through the buffer.
+
+Typically, items will all be of the same unit size, but this isn't strictly
+required to use the techniques below.  The indices can be increased by more
+than 1 if multiple items or variable-sized items are to be included in the
+buffer, provided that neither index overtakes the other.  The implementer must
+be careful, however, as a region more than one unit in size may wrap the end of
+the buffer and be broken into two segments.
+
+
+============================
+MEASURING POWER-OF-2 BUFFERS
+============================
+
+Calculation of the occupancy or the remaining capacity of an arbitrarily sized
+circular buffer would normally be a slow operation, requiring the use of a
+modulus (divide) instruction.  However, if the buffer is of a power-of-2 size,
+then a much quicker bitwise-AND instruction can be used instead.
+
+Linux provides a set of macros for handling power-of-2 circular buffers.  These
+can be made use of by:
+
+	#include <linux/circ_buf.h>
+
+The macros are:
+
+ (*) Measure the remaining capacity of a buffer:
+
+	CIRC_SPACE(head_index, tail_index, buffer_size);
+
+     This returns the amount of space left in the buffer[1] into which items
+     can be inserted.
+
+
+ (*) Measure the maximum consecutive immediate space in a buffer:
+
+	CIRC_SPACE_TO_END(head_index, tail_index, buffer_size);
+
+     This returns the amount of consecutive space left in the buffer[1] into
+     which items can be immediately inserted without having to wrap back to the
+     beginning of the buffer.
+
+
+ (*) Measure the occupancy of a buffer:
+
+	CIRC_CNT(head_index, tail_index, buffer_size);
+
+     This returns the number of items currently occupying a buffer[2].
+
+
+ (*) Measure the non-wrapping occupancy of a buffer:
+
+	CIRC_CNT_TO_END(head_index, tail_index, buffer_size);
+
+     This returns the number of consecutive items[2] that can be extracted from
+     the buffer without having to wrap back to the beginning of the buffer.
+
+
+Each of these macros will nominally return a value between 0 and buffer_size-1,
+however:
+
+ [1] CIRC_SPACE*() are intended to be used in the producer.  To the producer
+     they will return a lower bound as the producer controls the head index,
+     but the consumer may still be depleting the buffer on another CPU and
+     moving the tail index.
+
+     To the consumer it will show an upper bound as the producer may be busy
+     depleting the space.
+
+ [2] CIRC_CNT*() are intended to be used in the consumer.  To the consumer they
+     will return a lower bound as the consumer controls the tail index, but the
+     producer may still be filling the buffer on another CPU and moving the
+     head index.
+
+     To the producer it will show an upper bound as the consumer may be busy
+     emptying the buffer.
+
+ [3] To a third party, the order in which the writes to the indices by the
+     producer and consumer become visible cannot be guaranteed as they are
+     independent and may be made on different CPUs - so the result in such a
+     situation will merely be a guess, and may even be negative.
+
+
+===========================================
+USING MEMORY BARRIERS WITH CIRCULAR BUFFERS
+===========================================
+
+By using memory barriers in conjunction with circular buffers, you can avoid
+the need to:
+
+ (1) use a single lock to govern access to both ends of the buffer, thus
+     allowing the buffer to be filled and emptied at the same time; and
+
+ (2) use atomic counter operations.
+
+There are two sides to this: the producer that fills the buffer, and the
+consumer that empties it.  Only one thing should be filling a buffer at any one
+time, and only one thing should be emptying a buffer at any one time, but the
+two sides can operate simultaneously.
+
+
+THE PRODUCER
+------------
+
+The producer will look something like this:
+
+	spin_lock(&producer_lock);
+
+	unsigned long head = buffer->head;
+	unsigned long tail = ACCESS_ONCE(buffer->tail);
+
+	if (CIRC_SPACE(head, tail, buffer->size) >= 1) {
+		/* insert one item into the buffer */
+		struct item *item = buffer[head];
+
+		produce_item(item);
+
+		smp_wmb(); /* commit the item before incrementing the head */
+
+		buffer->head = (head + 1) & (buffer->size - 1);
+
+		/* wake_up() will make sure that the head is committed before
+		 * waking anyone up */
+		wake_up(consumer);
+	}
+
+	spin_unlock(&producer_lock);
+
+This will instruct the CPU that the contents of the new item must be written
+before the head index makes it available to the consumer and then instructs the
+CPU that the revised head index must be written before the consumer is woken.
+
+Note that wake_up() doesn't have to be the exact mechanism used, but whatever
+is used must guarantee a (write) memory barrier between the update of the head
+index and the change of state of the consumer, if a change of state occurs.
+
+
+THE CONSUMER
+------------
+
+The consumer will look something like this:
+
+	spin_lock(&consumer_lock);
+
+	unsigned long head = ACCESS_ONCE(buffer->head);
+	unsigned long tail = buffer->tail;
+
+	if (CIRC_CNT(head, tail, buffer->size) >= 1) {
+		/* read index before reading contents at that index */
+		smp_read_barrier_depends();
+
+		/* extract one item from the buffer */
+		struct item *item = buffer[tail];
+
+		consume_item(item);
+
+		smp_mb(); /* finish reading descriptor before incrementing tail */
+
+		buffer->tail = (tail + 1) & (buffer->size - 1);
+	}
+
+	spin_unlock(&consumer_lock);
+
+This will instruct the CPU to make sure the index is up to date before reading
+the new item, and then it shall make sure the CPU has finished reading the item
+before it writes the new tail pointer, which will erase the item.
+
+
+Note the use of ACCESS_ONCE() in both algorithms to read the opposition index.
+This prevents the compiler from discarding and reloading its cached value -
+which some compilers will do across smp_read_barrier_depends().  This isn't
+strictly needed if you can be sure that the opposition index will _only_ be
+used the once.
+
+
+===============
+FURTHER READING
+===============
+
+See also Documentation/memory-barriers.txt for a description of Linux's memory
+barrier facilities.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/connector/cn_test.c linux-libre-2.6.34-gnu1/Documentation/connector/cn_test.c
--- linux-libre-2.6.33-gnu1/Documentation/connector/cn_test.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/connector/cn_test.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 
 #include <linux/connector.h>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/console/console.txt linux-libre-2.6.34-gnu1/Documentation/console/console.txt
--- linux-libre-2.6.33-gnu1/Documentation/console/console.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/console/console.txt	2010-05-16 17:17:36.000000000 -0400
@@ -74,7 +74,7 @@ driver takes over the consoles vacated b
 hand, will bind the driver to the consoles that are currently occupied by a
 system driver.
 
-NOTE1: Binding and binding must be selected in Kconfig. It's under:
+NOTE1: Binding and unbinding must be selected in Kconfig. It's under:
 
 Device Drivers -> Character devices -> Support for binding and unbinding
 console drivers
diff -druNp linux-libre-2.6.33-gnu1/Documentation/cpu-freq/pcc-cpufreq.txt linux-libre-2.6.34-gnu1/Documentation/cpu-freq/pcc-cpufreq.txt
--- linux-libre-2.6.33-gnu1/Documentation/cpu-freq/pcc-cpufreq.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/cpu-freq/pcc-cpufreq.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,207 @@
+/*
+ *  pcc-cpufreq.txt - PCC interface documentation
+ *
+ *  Copyright (C) 2009 Red Hat, Matthew Garrett <mjg@redhat.com>
+ *  Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ *      Nagananda Chumbalkar <nagananda.chumbalkar@hp.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or NON
+ *  INFRINGEMENT. See the GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+
+			Processor Clocking Control Driver
+			---------------------------------
+
+Contents:
+---------
+1.	Introduction
+1.1	PCC interface
+1.1.1   Get Average Frequency
+1.1.2	Set Desired Frequency
+1.2	Platforms affected
+2.	Driver and /sys details
+2.1	scaling_available_frequencies
+2.2	cpuinfo_transition_latency
+2.3	cpuinfo_cur_freq
+2.4	related_cpus
+3.	Caveats
+
+1. Introduction:
+----------------
+Processor Clocking Control (PCC) is an interface between the platform
+firmware and OSPM. It is a mechanism for coordinating processor
+performance (ie: frequency) between the platform firmware and the OS.
+
+The PCC driver (pcc-cpufreq) allows OSPM to take advantage of the PCC
+interface.
+
+OS utilizes the PCC interface to inform platform firmware what frequency the
+OS wants for a logical processor. The platform firmware attempts to achieve
+the requested frequency. If the request for the target frequency could not be
+satisfied by platform firmware, then it usually means that power budget
+conditions are in place, and "power capping" is taking place.
+
+1.1 PCC interface:
+------------------
+The complete PCC specification is available here:
+http://www.acpica.org/download/Processor-Clocking-Control-v1p0.pdf
+
+PCC relies on a shared memory region that provides a channel for communication
+between the OS and platform firmware. PCC also implements a "doorbell" that
+is used by the OS to inform the platform firmware that a command has been
+sent.
+
+The ACPI PCCH() method is used to discover the location of the PCC shared
+memory region. The shared memory region header contains the "command" and
+"status" interface. PCCH() also contains details on how to access the platform
+doorbell.
+
+The following commands are supported by the PCC interface:
+* Get Average Frequency
+* Set Desired Frequency
+
+The ACPI PCCP() method is implemented for each logical processor and is
+used to discover the offsets for the input and output buffers in the shared
+memory region.
+
+When PCC mode is enabled, the platform will not expose processor performance
+or throttle states (_PSS, _TSS and related ACPI objects) to OSPM. Therefore,
+the native P-state driver (such as acpi-cpufreq for Intel, powernow-k8 for
+AMD) will not load.
+
+However, OSPM remains in control of policy. The governor (eg: "ondemand")
+computes the required performance for each processor based on server workload.
+The PCC driver fills in the command interface, and the input buffer and
+communicates the request to the platform firmware. The platform firmware is
+responsible for delivering the requested performance.
+
+Each PCC command is "global" in scope and can affect all the logical CPUs in
+the system. Therefore, PCC is capable of performing "group" updates. With PCC
+the OS is capable of getting/setting the frequency of all the logical CPUs in
+the system with a single call to the BIOS.
+
+1.1.1 Get Average Frequency:
+----------------------------
+This command is used by the OSPM to query the running frequency of the
+processor since the last time this command was completed. The output buffer
+indicates the average unhalted frequency of the logical processor expressed as
+a percentage of the nominal (ie: maximum) CPU frequency. The output buffer
+also signifies if the CPU frequency is limited by a power budget condition.
+
+1.1.2 Set Desired Frequency:
+----------------------------
+This command is used by the OSPM to communicate to the platform firmware the
+desired frequency for a logical processor. The output buffer is currently
+ignored by OSPM. The next invocation of "Get Average Frequency" will inform
+OSPM if the desired frequency was achieved or not.
+
+1.2 Platforms affected:
+-----------------------
+The PCC driver will load on any system where the platform firmware:
+* supports the PCC interface, and the associated PCCH() and PCCP() methods
+* assumes responsibility for managing the hardware clocking controls in order
+to deliver the requested processor performance
+
+Currently, certain HP ProLiant platforms implement the PCC interface. On those
+platforms PCC is the "default" choice.
+
+However, it is possible to disable this interface via a BIOS setting. In
+such an instance, as is also the case on platforms where the PCC interface
+is not implemented, the PCC driver will fail to load silently.
+
+2. Driver and /sys details:
+---------------------------
+When the driver loads, it merely prints the lowest and the highest CPU
+frequencies supported by the platform firmware.
+
+The PCC driver loads with a message such as:
+pcc-cpufreq: (v1.00.00) driver loaded with frequency limits: 1600 MHz, 2933
+MHz
+
+This means that the OPSM can request the CPU to run at any frequency in
+between the limits (1600 MHz, and 2933 MHz) specified in the message.
+
+Internally, there is no need for the driver to convert the "target" frequency
+to a corresponding P-state.
+
+The VERSION number for the driver will be of the format v.xy.ab.
+eg: 1.00.02
+   ----- --
+    |    |
+    |    -- this will increase with bug fixes/enhancements to the driver
+    |-- this is the version of the PCC specification the driver adheres to
+
+
+The following is a brief discussion on some of the fields exported via the
+/sys filesystem and how their values are affected by the PCC driver:
+
+2.1 scaling_available_frequencies:
+----------------------------------
+scaling_available_frequencies is not created in /sys. No intermediate
+frequencies need to be listed because the BIOS will try to achieve any
+frequency, within limits, requested by the governor. A frequency does not have
+to be strictly associated with a P-state.
+
+2.2 cpuinfo_transition_latency:
+-------------------------------
+The cpuinfo_transition_latency field is 0. The PCC specification does
+not include a field to expose this value currently.
+
+2.3 cpuinfo_cur_freq:
+---------------------
+A) Often cpuinfo_cur_freq will show a value different than what is declared
+in the scaling_available_frequencies or scaling_cur_freq, or scaling_max_freq.
+This is due to "turbo boost" available on recent Intel processors. If certain
+conditions are met the BIOS can achieve a slightly higher speed than requested
+by OSPM. An example:
+
+scaling_cur_freq	: 2933000
+cpuinfo_cur_freq	: 3196000
+
+B) There is a round-off error associated with the cpuinfo_cur_freq value.
+Since the driver obtains the current frequency as a "percentage" (%) of the
+nominal frequency from the BIOS, sometimes, the values displayed by
+scaling_cur_freq and cpuinfo_cur_freq may not match. An example:
+
+scaling_cur_freq	: 1600000
+cpuinfo_cur_freq	: 1583000
+
+In this example, the nominal frequency is 2933 MHz. The driver obtains the
+current frequency, cpuinfo_cur_freq, as 54% of the nominal frequency:
+
+	54% of 2933 MHz = 1583 MHz
+
+Nominal frequency is the maximum frequency of the processor, and it usually
+corresponds to the frequency of the P0 P-state.
+
+2.4 related_cpus:
+-----------------
+The related_cpus field is identical to affected_cpus.
+
+affected_cpus	: 4
+related_cpus	: 4
+
+Currently, the PCC driver does not evaluate _PSD. The platforms that support
+PCC do not implement SW_ALL. So OSPM doesn't need to perform any coordination
+to ensure that the same frequency is requested of all dependent CPUs.
+
+3. Caveats:
+-----------
+The "cpufreq_stats" module in its present form cannot be loaded and
+expected to work with the PCC driver. Since the "cpufreq_stats" module
+provides information wrt each P-state, it is not applicable to the PCC driver.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/device-mapper/snapshot.txt linux-libre-2.6.34-gnu1/Documentation/device-mapper/snapshot.txt
--- linux-libre-2.6.33-gnu1/Documentation/device-mapper/snapshot.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/device-mapper/snapshot.txt	2010-05-16 17:17:36.000000000 -0400
@@ -122,3 +122,47 @@ volumeGroup-base: 0 2097152 snapshot-mer
 brw-------  1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real
 brw-------  1 root root 254, 12 29 ago 18:16 /dev/mapper/volumeGroup-base-cow
 brw-------  1 root root 254, 10 29 ago 18:16 /dev/mapper/volumeGroup-base
+
+
+How to determine when a merging is complete
+===========================================
+The snapshot-merge and snapshot status lines end with:
+  <sectors_allocated>/<total_sectors> <metadata_sectors>
+
+Both <sectors_allocated> and <total_sectors> include both data and metadata.
+During merging, the number of sectors allocated gets smaller and
+smaller.  Merging has finished when the number of sectors holding data
+is zero, in other words <sectors_allocated> == <metadata_sectors>.
+
+Here is a practical example (using a hybrid of lvm and dmsetup commands):
+
+# lvs
+  LV      VG          Attr   LSize Origin  Snap%  Move Log Copy%  Convert
+  base    volumeGroup owi-a- 4.00g
+  snap    volumeGroup swi-a- 1.00g base  18.97
+
+# dmsetup status volumeGroup-snap
+0 8388608 snapshot 397896/2097152 1560
+                                  ^^^^ metadata sectors
+
+# lvconvert --merge -b volumeGroup/snap
+  Merging of volume snap started.
+
+# lvs volumeGroup/snap
+  LV      VG          Attr   LSize Origin  Snap%  Move Log Copy%  Convert
+  base    volumeGroup Owi-a- 4.00g          17.23
+
+# dmsetup status volumeGroup-base
+0 8388608 snapshot-merge 281688/2097152 1104
+
+# dmsetup status volumeGroup-base
+0 8388608 snapshot-merge 180480/2097152 712
+
+# dmsetup status volumeGroup-base
+0 8388608 snapshot-merge 16/2097152 16
+
+Merging has finished.
+
+# lvs
+  LV      VG          Attr   LSize Origin  Snap%  Move Log Copy%  Convert
+  base    volumeGroup owi-a- 4.00g
diff -druNp linux-libre-2.6.33-gnu1/Documentation/DMA-API-HOWTO.txt linux-libre-2.6.34-gnu1/Documentation/DMA-API-HOWTO.txt
--- linux-libre-2.6.33-gnu1/Documentation/DMA-API-HOWTO.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/DMA-API-HOWTO.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,758 @@
+		     Dynamic DMA mapping Guide
+		     =========================
+
+		 David S. Miller <davem@redhat.com>
+		 Richard Henderson <rth@cygnus.com>
+		  Jakub Jelinek <jakub@redhat.com>
+
+This is a guide to device driver writers on how to use the DMA API
+with example pseudo-code.  For a concise description of the API, see
+DMA-API.txt.
+
+Most of the 64bit platforms have special hardware that translates bus
+addresses (DMA addresses) into physical addresses.  This is similar to
+how page tables and/or a TLB translates virtual addresses to physical
+addresses on a CPU.  This is needed so that e.g. PCI devices can
+access with a Single Address Cycle (32bit DMA address) any page in the
+64bit physical address space.  Previously in Linux those 64bit
+platforms had to set artificial limits on the maximum RAM size in the
+system, so that the virt_to_bus() static scheme works (the DMA address
+translation tables were simply filled on bootup to map each bus
+address to the physical page __pa(bus_to_virt())).
+
+So that Linux can use the dynamic DMA mapping, it needs some help from the
+drivers, namely it has to take into account that DMA addresses should be
+mapped only for the time they are actually used and unmapped after the DMA
+transfer.
+
+The following API will work of course even on platforms where no such
+hardware exists.
+
+Note that the DMA API works with any bus independent of the underlying
+microprocessor architecture. You should use the DMA API rather than
+the bus specific DMA API (e.g. pci_dma_*).
+
+First of all, you should make sure
+
+#include <linux/dma-mapping.h>
+
+is in your driver. This file will obtain for you the definition of the
+dma_addr_t (which can hold any valid DMA address for the platform)
+type which should be used everywhere you hold a DMA (bus) address
+returned from the DMA mapping functions.
+
+			 What memory is DMA'able?
+
+The first piece of information you must know is what kernel memory can
+be used with the DMA mapping facilities.  There has been an unwritten
+set of rules regarding this, and this text is an attempt to finally
+write them down.
+
+If you acquired your memory via the page allocator
+(i.e. __get_free_page*()) or the generic memory allocators
+(i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from
+that memory using the addresses returned from those routines.
+
+This means specifically that you may _not_ use the memory/addresses
+returned from vmalloc() for DMA.  It is possible to DMA to the
+_underlying_ memory mapped into a vmalloc() area, but this requires
+walking page tables to get the physical addresses, and then
+translating each of those pages back to a kernel address using
+something like __va().  [ EDIT: Update this when we integrate
+Gerd Knorr's generic code which does this. ]
+
+This rule also means that you may use neither kernel image addresses
+(items in data/text/bss segments), nor module image addresses, nor
+stack addresses for DMA.  These could all be mapped somewhere entirely
+different than the rest of physical memory.  Even if those classes of
+memory could physically work with DMA, you'd need to ensure the I/O
+buffers were cacheline-aligned.  Without that, you'd see cacheline
+sharing problems (data corruption) on CPUs with DMA-incoherent caches.
+(The CPU could write to one word, DMA would write to a different one
+in the same cache line, and one of them could be overwritten.)
+
+Also, this means that you cannot take the return of a kmap()
+call and DMA to/from that.  This is similar to vmalloc().
+
+What about block I/O and networking buffers?  The block I/O and
+networking subsystems make sure that the buffers they use are valid
+for you to DMA from/to.
+
+			DMA addressing limitations
+
+Does your device have any DMA addressing limitations?  For example, is
+your device only capable of driving the low order 24-bits of address?
+If so, you need to inform the kernel of this fact.
+
+By default, the kernel assumes that your device can address the full
+32-bits.  For a 64-bit capable device, this needs to be increased.
+And for a device with limitations, as discussed in the previous
+paragraph, it needs to be decreased.
+
+Special note about PCI: PCI-X specification requires PCI-X devices to
+support 64-bit addressing (DAC) for all transactions.  And at least
+one platform (SGI SN2) requires 64-bit consistent allocations to
+operate correctly when the IO bus is in PCI-X mode.
+
+For correct operation, you must interrogate the kernel in your device
+probe routine to see if the DMA controller on the machine can properly
+support the DMA addressing limitation your device has.  It is good
+style to do this even if your device holds the default setting,
+because this shows that you did think about these issues wrt. your
+device.
+
+The query is performed via a call to dma_set_mask():
+
+	int dma_set_mask(struct device *dev, u64 mask);
+
+The query for consistent allocations is performed via a call to
+dma_set_coherent_mask():
+
+	int dma_set_coherent_mask(struct device *dev, u64 mask);
+
+Here, dev is a pointer to the device struct of your device, and mask
+is a bit mask describing which bits of an address your device
+supports.  It returns zero if your card can perform DMA properly on
+the machine given the address mask you provided.  In general, the
+device struct of your device is embedded in the bus specific device
+struct of your device.  For example, a pointer to the device struct of
+your PCI device is pdev->dev (pdev is a pointer to the PCI device
+struct of your device).
+
+If it returns non-zero, your device cannot perform DMA properly on
+this platform, and attempting to do so will result in undefined
+behavior.  You must either use a different mask, or not use DMA.
+
+This means that in the failure case, you have three options:
+
+1) Use another DMA mask, if possible (see below).
+2) Use some non-DMA mode for data transfer, if possible.
+3) Ignore this device and do not initialize it.
+
+It is recommended that your driver print a kernel KERN_WARNING message
+when you end up performing either #2 or #3.  In this manner, if a user
+of your driver reports that performance is bad or that the device is not
+even detected, you can ask them for the kernel messages to find out
+exactly why.
+
+The standard 32-bit addressing device would do something like this:
+
+	if (dma_set_mask(dev, DMA_BIT_MASK(32))) {
+		printk(KERN_WARNING
+		       "mydev: No suitable DMA available.\n");
+		goto ignore_this_device;
+	}
+
+Another common scenario is a 64-bit capable device.  The approach here
+is to try for 64-bit addressing, but back down to a 32-bit mask that
+should not fail.  The kernel may fail the 64-bit mask not because the
+platform is not capable of 64-bit addressing.  Rather, it may fail in
+this case simply because 32-bit addressing is done more efficiently
+than 64-bit addressing.  For example, Sparc64 PCI SAC addressing is
+more efficient than DAC addressing.
+
+Here is how you would handle a 64-bit capable device which can drive
+all 64-bits when accessing streaming DMA:
+
+	int using_dac;
+
+	if (!dma_set_mask(dev, DMA_BIT_MASK(64))) {
+		using_dac = 1;
+	} else if (!dma_set_mask(dev, DMA_BIT_MASK(32))) {
+		using_dac = 0;
+	} else {
+		printk(KERN_WARNING
+		       "mydev: No suitable DMA available.\n");
+		goto ignore_this_device;
+	}
+
+If a card is capable of using 64-bit consistent allocations as well,
+the case would look like this:
+
+	int using_dac, consistent_using_dac;
+
+	if (!dma_set_mask(dev, DMA_BIT_MASK(64))) {
+		using_dac = 1;
+	   	consistent_using_dac = 1;
+		dma_set_coherent_mask(dev, DMA_BIT_MASK(64));
+	} else if (!dma_set_mask(dev, DMA_BIT_MASK(32))) {
+		using_dac = 0;
+		consistent_using_dac = 0;
+		dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
+	} else {
+		printk(KERN_WARNING
+		       "mydev: No suitable DMA available.\n");
+		goto ignore_this_device;
+	}
+
+dma_set_coherent_mask() will always be able to set the same or a
+smaller mask as dma_set_mask(). However for the rare case that a
+device driver only uses consistent allocations, one would have to
+check the return value from dma_set_coherent_mask().
+
+Finally, if your device can only drive the low 24-bits of
+address you might do something like:
+
+	if (dma_set_mask(dev, DMA_BIT_MASK(24))) {
+		printk(KERN_WARNING
+		       "mydev: 24-bit DMA addressing not available.\n");
+		goto ignore_this_device;
+	}
+
+When dma_set_mask() is successful, and returns zero, the kernel saves
+away this mask you have provided.  The kernel will use this
+information later when you make DMA mappings.
+
+There is a case which we are aware of at this time, which is worth
+mentioning in this documentation.  If your device supports multiple
+functions (for example a sound card provides playback and record
+functions) and the various different functions have _different_
+DMA addressing limitations, you may wish to probe each mask and
+only provide the functionality which the machine can handle.  It
+is important that the last call to dma_set_mask() be for the
+most specific mask.
+
+Here is pseudo-code showing how this might be done:
+
+	#define PLAYBACK_ADDRESS_BITS	DMA_BIT_MASK(32)
+	#define RECORD_ADDRESS_BITS	DMA_BIT_MASK(24)
+
+	struct my_sound_card *card;
+	struct device *dev;
+
+	...
+	if (!dma_set_mask(dev, PLAYBACK_ADDRESS_BITS)) {
+		card->playback_enabled = 1;
+	} else {
+		card->playback_enabled = 0;
+		printk(KERN_WARNING "%s: Playback disabled due to DMA limitations.\n",
+		       card->name);
+	}
+	if (!dma_set_mask(dev, RECORD_ADDRESS_BITS)) {
+		card->record_enabled = 1;
+	} else {
+		card->record_enabled = 0;
+		printk(KERN_WARNING "%s: Record disabled due to DMA limitations.\n",
+		       card->name);
+	}
+
+A sound card was used as an example here because this genre of PCI
+devices seems to be littered with ISA chips given a PCI front end,
+and thus retaining the 16MB DMA addressing limitations of ISA.
+
+			Types of DMA mappings
+
+There are two types of DMA mappings:
+
+- Consistent DMA mappings which are usually mapped at driver
+  initialization, unmapped at the end and for which the hardware should
+  guarantee that the device and the CPU can access the data
+  in parallel and will see updates made by each other without any
+  explicit software flushing.
+
+  Think of "consistent" as "synchronous" or "coherent".
+
+  The current default is to return consistent memory in the low 32
+  bits of the bus space.  However, for future compatibility you should
+  set the consistent mask even if this default is fine for your
+  driver.
+
+  Good examples of what to use consistent mappings for are:
+
+	- Network card DMA ring descriptors.
+	- SCSI adapter mailbox command data structures.
+	- Device firmware microcode executed out of
+	  main memory.
+
+  The invariant these examples all require is that any CPU store
+  to memory is immediately visible to the device, and vice
+  versa.  Consistent mappings guarantee this.
+
+  IMPORTANT: Consistent DMA memory does not preclude the usage of
+             proper memory barriers.  The CPU may reorder stores to
+	     consistent memory just as it may normal memory.  Example:
+	     if it is important for the device to see the first word
+	     of a descriptor updated before the second, you must do
+	     something like:
+
+		desc->word0 = address;
+		wmb();
+		desc->word1 = DESC_VALID;
+
+             in order to get correct behavior on all platforms.
+
+	     Also, on some platforms your driver may need to flush CPU write
+	     buffers in much the same way as it needs to flush write buffers
+	     found in PCI bridges (such as by reading a register's value
+	     after writing it).
+
+- Streaming DMA mappings which are usually mapped for one DMA
+  transfer, unmapped right after it (unless you use dma_sync_* below)
+  and for which hardware can optimize for sequential accesses.
+
+  This of "streaming" as "asynchronous" or "outside the coherency
+  domain".
+
+  Good examples of what to use streaming mappings for are:
+
+	- Networking buffers transmitted/received by a device.
+	- Filesystem buffers written/read by a SCSI device.
+
+  The interfaces for using this type of mapping were designed in
+  such a way that an implementation can make whatever performance
+  optimizations the hardware allows.  To this end, when using
+  such mappings you must be explicit about what you want to happen.
+
+Neither type of DMA mapping has alignment restrictions that come from
+the underlying bus, although some devices may have such restrictions.
+Also, systems with caches that aren't DMA-coherent will work better
+when the underlying buffers don't share cache lines with other data.
+
+
+		 Using Consistent DMA mappings.
+
+To allocate and map large (PAGE_SIZE or so) consistent DMA regions,
+you should do:
+
+	dma_addr_t dma_handle;
+
+	cpu_addr = dma_alloc_coherent(dev, size, &dma_handle, gfp);
+
+where device is a struct device *. This may be called in interrupt
+context with the GFP_ATOMIC flag.
+
+Size is the length of the region you want to allocate, in bytes.
+
+This routine will allocate RAM for that region, so it acts similarly to
+__get_free_pages (but takes size instead of a page order).  If your
+driver needs regions sized smaller than a page, you may prefer using
+the dma_pool interface, described below.
+
+The consistent DMA mapping interfaces, for non-NULL dev, will by
+default return a DMA address which is 32-bit addressable.  Even if the
+device indicates (via DMA mask) that it may address the upper 32-bits,
+consistent allocation will only return > 32-bit addresses for DMA if
+the consistent DMA mask has been explicitly changed via
+dma_set_coherent_mask().  This is true of the dma_pool interface as
+well.
+
+dma_alloc_coherent returns two values: the virtual address which you
+can use to access it from the CPU and dma_handle which you pass to the
+card.
+
+The cpu return address and the DMA bus master address are both
+guaranteed to be aligned to the smallest PAGE_SIZE order which
+is greater than or equal to the requested size.  This invariant
+exists (for example) to guarantee that if you allocate a chunk
+which is smaller than or equal to 64 kilobytes, the extent of the
+buffer you receive will not cross a 64K boundary.
+
+To unmap and free such a DMA region, you call:
+
+	dma_free_coherent(dev, size, cpu_addr, dma_handle);
+
+where dev, size are the same as in the above call and cpu_addr and
+dma_handle are the values dma_alloc_coherent returned to you.
+This function may not be called in interrupt context.
+
+If your driver needs lots of smaller memory regions, you can write
+custom code to subdivide pages returned by dma_alloc_coherent,
+or you can use the dma_pool API to do that.  A dma_pool is like
+a kmem_cache, but it uses dma_alloc_coherent not __get_free_pages.
+Also, it understands common hardware constraints for alignment,
+like queue heads needing to be aligned on N byte boundaries.
+
+Create a dma_pool like this:
+
+	struct dma_pool *pool;
+
+	pool = dma_pool_create(name, dev, size, align, alloc);
+
+The "name" is for diagnostics (like a kmem_cache name); dev and size
+are as above.  The device's hardware alignment requirement for this
+type of data is "align" (which is expressed in bytes, and must be a
+power of two).  If your device has no boundary crossing restrictions,
+pass 0 for alloc; passing 4096 says memory allocated from this pool
+must not cross 4KByte boundaries (but at that time it may be better to
+go for dma_alloc_coherent directly instead).
+
+Allocate memory from a dma pool like this:
+
+	cpu_addr = dma_pool_alloc(pool, flags, &dma_handle);
+
+flags are SLAB_KERNEL if blocking is permitted (not in_interrupt nor
+holding SMP locks), SLAB_ATOMIC otherwise.  Like dma_alloc_coherent,
+this returns two values, cpu_addr and dma_handle.
+
+Free memory that was allocated from a dma_pool like this:
+
+	dma_pool_free(pool, cpu_addr, dma_handle);
+
+where pool is what you passed to dma_pool_alloc, and cpu_addr and
+dma_handle are the values dma_pool_alloc returned. This function
+may be called in interrupt context.
+
+Destroy a dma_pool by calling:
+
+	dma_pool_destroy(pool);
+
+Make sure you've called dma_pool_free for all memory allocated
+from a pool before you destroy the pool. This function may not
+be called in interrupt context.
+
+			DMA Direction
+
+The interfaces described in subsequent portions of this document
+take a DMA direction argument, which is an integer and takes on
+one of the following values:
+
+ DMA_BIDIRECTIONAL
+ DMA_TO_DEVICE
+ DMA_FROM_DEVICE
+ DMA_NONE
+
+One should provide the exact DMA direction if you know it.
+
+DMA_TO_DEVICE means "from main memory to the device"
+DMA_FROM_DEVICE means "from the device to main memory"
+It is the direction in which the data moves during the DMA
+transfer.
+
+You are _strongly_ encouraged to specify this as precisely
+as you possibly can.
+
+If you absolutely cannot know the direction of the DMA transfer,
+specify DMA_BIDIRECTIONAL.  It means that the DMA can go in
+either direction.  The platform guarantees that you may legally
+specify this, and that it will work, but this may be at the
+cost of performance for example.
+
+The value DMA_NONE is to be used for debugging.  One can
+hold this in a data structure before you come to know the
+precise direction, and this will help catch cases where your
+direction tracking logic has failed to set things up properly.
+
+Another advantage of specifying this value precisely (outside of
+potential platform-specific optimizations of such) is for debugging.
+Some platforms actually have a write permission boolean which DMA
+mappings can be marked with, much like page protections in the user
+program address space.  Such platforms can and do report errors in the
+kernel logs when the DMA controller hardware detects violation of the
+permission setting.
+
+Only streaming mappings specify a direction, consistent mappings
+implicitly have a direction attribute setting of
+DMA_BIDIRECTIONAL.
+
+The SCSI subsystem tells you the direction to use in the
+'sc_data_direction' member of the SCSI command your driver is
+working on.
+
+For Networking drivers, it's a rather simple affair.  For transmit
+packets, map/unmap them with the DMA_TO_DEVICE direction
+specifier.  For receive packets, just the opposite, map/unmap them
+with the DMA_FROM_DEVICE direction specifier.
+
+		  Using Streaming DMA mappings
+
+The streaming DMA mapping routines can be called from interrupt
+context.  There are two versions of each map/unmap, one which will
+map/unmap a single memory region, and one which will map/unmap a
+scatterlist.
+
+To map a single region, you do:
+
+	struct device *dev = &my_dev->dev;
+	dma_addr_t dma_handle;
+	void *addr = buffer->ptr;
+	size_t size = buffer->len;
+
+	dma_handle = dma_map_single(dev, addr, size, direction);
+
+and to unmap it:
+
+	dma_unmap_single(dev, dma_handle, size, direction);
+
+You should call dma_unmap_single when the DMA activity is finished, e.g.
+from the interrupt which told you that the DMA transfer is done.
+
+Using cpu pointers like this for single mappings has a disadvantage,
+you cannot reference HIGHMEM memory in this way.  Thus, there is a
+map/unmap interface pair akin to dma_{map,unmap}_single.  These
+interfaces deal with page/offset pairs instead of cpu pointers.
+Specifically:
+
+	struct device *dev = &my_dev->dev;
+	dma_addr_t dma_handle;
+	struct page *page = buffer->page;
+	unsigned long offset = buffer->offset;
+	size_t size = buffer->len;
+
+	dma_handle = dma_map_page(dev, page, offset, size, direction);
+
+	...
+
+	dma_unmap_page(dev, dma_handle, size, direction);
+
+Here, "offset" means byte offset within the given page.
+
+With scatterlists, you map a region gathered from several regions by:
+
+	int i, count = dma_map_sg(dev, sglist, nents, direction);
+	struct scatterlist *sg;
+
+	for_each_sg(sglist, sg, count, i) {
+		hw_address[i] = sg_dma_address(sg);
+		hw_len[i] = sg_dma_len(sg);
+	}
+
+where nents is the number of entries in the sglist.
+
+The implementation is free to merge several consecutive sglist entries
+into one (e.g. if DMA mapping is done with PAGE_SIZE granularity, any
+consecutive sglist entries can be merged into one provided the first one
+ends and the second one starts on a page boundary - in fact this is a huge
+advantage for cards which either cannot do scatter-gather or have very
+limited number of scatter-gather entries) and returns the actual number
+of sg entries it mapped them to. On failure 0 is returned.
+
+Then you should loop count times (note: this can be less than nents times)
+and use sg_dma_address() and sg_dma_len() macros where you previously
+accessed sg->address and sg->length as shown above.
+
+To unmap a scatterlist, just call:
+
+	dma_unmap_sg(dev, sglist, nents, direction);
+
+Again, make sure DMA activity has already finished.
+
+PLEASE NOTE:  The 'nents' argument to the dma_unmap_sg call must be
+              the _same_ one you passed into the dma_map_sg call,
+	      it should _NOT_ be the 'count' value _returned_ from the
+              dma_map_sg call.
+
+Every dma_map_{single,sg} call should have its dma_unmap_{single,sg}
+counterpart, because the bus address space is a shared resource (although
+in some ports the mapping is per each BUS so less devices contend for the
+same bus address space) and you could render the machine unusable by eating
+all bus addresses.
+
+If you need to use the same streaming DMA region multiple times and touch
+the data in between the DMA transfers, the buffer needs to be synced
+properly in order for the cpu and device to see the most uptodate and
+correct copy of the DMA buffer.
+
+So, firstly, just map it with dma_map_{single,sg}, and after each DMA
+transfer call either:
+
+	dma_sync_single_for_cpu(dev, dma_handle, size, direction);
+
+or:
+
+	dma_sync_sg_for_cpu(dev, sglist, nents, direction);
+
+as appropriate.
+
+Then, if you wish to let the device get at the DMA area again,
+finish accessing the data with the cpu, and then before actually
+giving the buffer to the hardware call either:
+
+	dma_sync_single_for_device(dev, dma_handle, size, direction);
+
+or:
+
+	dma_sync_sg_for_device(dev, sglist, nents, direction);
+
+as appropriate.
+
+After the last DMA transfer call one of the DMA unmap routines
+dma_unmap_{single,sg}. If you don't touch the data from the first dma_map_*
+call till dma_unmap_*, then you don't have to call the dma_sync_*
+routines at all.
+
+Here is pseudo code which shows a situation in which you would need
+to use the dma_sync_*() interfaces.
+
+	my_card_setup_receive_buffer(struct my_card *cp, char *buffer, int len)
+	{
+		dma_addr_t mapping;
+
+		mapping = dma_map_single(cp->dev, buffer, len, DMA_FROM_DEVICE);
+
+		cp->rx_buf = buffer;
+		cp->rx_len = len;
+		cp->rx_dma = mapping;
+
+		give_rx_buf_to_card(cp);
+	}
+
+	...
+
+	my_card_interrupt_handler(int irq, void *devid, struct pt_regs *regs)
+	{
+		struct my_card *cp = devid;
+
+		...
+		if (read_card_status(cp) == RX_BUF_TRANSFERRED) {
+			struct my_card_header *hp;
+
+			/* Examine the header to see if we wish
+			 * to accept the data.  But synchronize
+			 * the DMA transfer with the CPU first
+			 * so that we see updated contents.
+			 */
+			dma_sync_single_for_cpu(&cp->dev, cp->rx_dma,
+						cp->rx_len,
+						DMA_FROM_DEVICE);
+
+			/* Now it is safe to examine the buffer. */
+			hp = (struct my_card_header *) cp->rx_buf;
+			if (header_is_ok(hp)) {
+				dma_unmap_single(&cp->dev, cp->rx_dma, cp->rx_len,
+						 DMA_FROM_DEVICE);
+				pass_to_upper_layers(cp->rx_buf);
+				make_and_setup_new_rx_buf(cp);
+			} else {
+				/* Just sync the buffer and give it back
+				 * to the card.
+				 */
+				dma_sync_single_for_device(&cp->dev,
+							   cp->rx_dma,
+							   cp->rx_len,
+							   DMA_FROM_DEVICE);
+				give_rx_buf_to_card(cp);
+			}
+		}
+	}
+
+Drivers converted fully to this interface should not use virt_to_bus any
+longer, nor should they use bus_to_virt. Some drivers have to be changed a
+little bit, because there is no longer an equivalent to bus_to_virt in the
+dynamic DMA mapping scheme - you have to always store the DMA addresses
+returned by the dma_alloc_coherent, dma_pool_alloc, and dma_map_single
+calls (dma_map_sg stores them in the scatterlist itself if the platform
+supports dynamic DMA mapping in hardware) in your driver structures and/or
+in the card registers.
+
+All drivers should be using these interfaces with no exceptions.  It
+is planned to completely remove virt_to_bus() and bus_to_virt() as
+they are entirely deprecated.  Some ports already do not provide these
+as it is impossible to correctly support them.
+
+		Optimizing Unmap State Space Consumption
+
+On many platforms, dma_unmap_{single,page}() is simply a nop.
+Therefore, keeping track of the mapping address and length is a waste
+of space.  Instead of filling your drivers up with ifdefs and the like
+to "work around" this (which would defeat the whole purpose of a
+portable API) the following facilities are provided.
+
+Actually, instead of describing the macros one by one, we'll
+transform some example code.
+
+1) Use DEFINE_DMA_UNMAP_{ADDR,LEN} in state saving structures.
+   Example, before:
+
+	struct ring_state {
+		struct sk_buff *skb;
+		dma_addr_t mapping;
+		__u32 len;
+	};
+
+   after:
+
+	struct ring_state {
+		struct sk_buff *skb;
+		DEFINE_DMA_UNMAP_ADDR(mapping);
+		DEFINE_DMA_UNMAP_LEN(len);
+	};
+
+2) Use dma_unmap_{addr,len}_set to set these values.
+   Example, before:
+
+	ringp->mapping = FOO;
+	ringp->len = BAR;
+
+   after:
+
+	dma_unmap_addr_set(ringp, mapping, FOO);
+	dma_unmap_len_set(ringp, len, BAR);
+
+3) Use dma_unmap_{addr,len} to access these values.
+   Example, before:
+
+	dma_unmap_single(dev, ringp->mapping, ringp->len,
+			 DMA_FROM_DEVICE);
+
+   after:
+
+	dma_unmap_single(dev,
+			 dma_unmap_addr(ringp, mapping),
+			 dma_unmap_len(ringp, len),
+			 DMA_FROM_DEVICE);
+
+It really should be self-explanatory.  We treat the ADDR and LEN
+separately, because it is possible for an implementation to only
+need the address in order to perform the unmap operation.
+
+			Platform Issues
+
+If you are just writing drivers for Linux and do not maintain
+an architecture port for the kernel, you can safely skip down
+to "Closing".
+
+1) Struct scatterlist requirements.
+
+   Struct scatterlist must contain, at a minimum, the following
+   members:
+
+	struct page *page;
+	unsigned int offset;
+	unsigned int length;
+
+   The base address is specified by a "page+offset" pair.
+
+   Previous versions of struct scatterlist contained a "void *address"
+   field that was sometimes used instead of page+offset.  As of Linux
+   2.5., page+offset is always used, and the "address" field has been
+   deleted.
+
+2) More to come...
+
+			Handling Errors
+
+DMA address space is limited on some architectures and an allocation
+failure can be determined by:
+
+- checking if dma_alloc_coherent returns NULL or dma_map_sg returns 0
+
+- checking the returned dma_addr_t of dma_map_single and dma_map_page
+  by using dma_mapping_error():
+
+	dma_addr_t dma_handle;
+
+	dma_handle = dma_map_single(dev, addr, size, direction);
+	if (dma_mapping_error(dev, dma_handle)) {
+		/*
+		 * reduce current DMA mapping usage,
+		 * delay and try again later or
+		 * reset driver.
+		 */
+	}
+
+			   Closing
+
+This document, and the API itself, would not be in it's current
+form without the feedback and suggestions from numerous individuals.
+We would like to specifically mention, in no particular order, the
+following people:
+
+	Russell King <rmk@arm.linux.org.uk>
+	Leo Dagum <dagum@barrel.engr.sgi.com>
+	Ralf Baechle <ralf@oss.sgi.com>
+	Grant Grundler <grundler@cup.hp.com>
+	Jay Estabrook <Jay.Estabrook@compaq.com>
+	Thomas Sailer <sailer@ife.ee.ethz.ch>
+	Andrea Arcangeli <andrea@suse.de>
+	Jens Axboe <jens.axboe@oracle.com>
+	David Mosberger-Tang <davidm@hpl.hp.com>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/DMA-API.txt linux-libre-2.6.34-gnu1/Documentation/DMA-API.txt
--- linux-libre-2.6.33-gnu1/Documentation/DMA-API.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/DMA-API.txt	2010-05-16 17:17:36.000000000 -0400
@@ -4,20 +4,18 @@
         James E.J. Bottomley <James.Bottomley@HansenPartnership.com>
 
 This document describes the DMA API.  For a more gentle introduction
-phrased in terms of the pci_ equivalents (and actual examples) see
-Documentation/PCI/PCI-DMA-mapping.txt.
+of the API (and actual examples) see
+Documentation/DMA-API-HOWTO.txt.
 
-This API is split into two pieces.  Part I describes the API and the
-corresponding pci_ API.  Part II describes the extensions to the API
-for supporting non-consistent memory machines.  Unless you know that
-your driver absolutely has to support non-consistent platforms (this
-is usually only legacy platforms) you should only use the API
-described in part I.
+This API is split into two pieces.  Part I describes the API.  Part II
+describes the extensions to the API for supporting non-consistent
+memory machines.  Unless you know that your driver absolutely has to
+support non-consistent platforms (this is usually only legacy
+platforms) you should only use the API described in part I.
 
-Part I - pci_ and dma_ Equivalent API 
+Part I - dma_ API
 -------------------------------------
 
-To get the pci_ API, you must #include <linux/pci.h>
 To get the dma_ API, you must #include <linux/dma-mapping.h>
 
 
@@ -27,9 +25,6 @@ Part Ia - Using large dma-coherent buffe
 void *
 dma_alloc_coherent(struct device *dev, size_t size,
 			     dma_addr_t *dma_handle, gfp_t flag)
-void *
-pci_alloc_consistent(struct pci_dev *dev, size_t size,
-			     dma_addr_t *dma_handle)
 
 Consistent memory is memory for which a write by either the device or
 the processor can immediately be read by the processor or device
@@ -53,15 +48,11 @@ The simplest way to do that is to use th
 The flag parameter (dma_alloc_coherent only) allows the caller to
 specify the GFP_ flags (see kmalloc) for the allocation (the
 implementation may choose to ignore flags that affect the location of
-the returned memory, like GFP_DMA).  For pci_alloc_consistent, you
-must assume GFP_ATOMIC behaviour.
+the returned memory, like GFP_DMA).
 
 void
 dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
 			   dma_addr_t dma_handle)
-void
-pci_free_consistent(struct pci_dev *dev, size_t size, void *cpu_addr,
-			   dma_addr_t dma_handle)
 
 Free the region of consistent memory you previously allocated.  dev,
 size and dma_handle must all be the same as those passed into the
@@ -89,10 +80,6 @@ for alignment, like queue heads needing
 	dma_pool_create(const char *name, struct device *dev,
 			size_t size, size_t align, size_t alloc);
 
-	struct pci_pool *
-	pci_pool_create(const char *name, struct pci_device *dev,
-			size_t size, size_t align, size_t alloc);
-
 The pool create() routines initialize a pool of dma-coherent buffers
 for use with a given device.  It must be called in a context which
 can sleep.
@@ -108,9 +95,6 @@ from this pool must not cross 4KByte bou
 	void *dma_pool_alloc(struct dma_pool *pool, gfp_t gfp_flags,
 			dma_addr_t *dma_handle);
 
-	void *pci_pool_alloc(struct pci_pool *pool, gfp_t gfp_flags,
-			dma_addr_t *dma_handle);
-
 This allocates memory from the pool; the returned memory will meet the size
 and alignment requirements specified at creation time.  Pass GFP_ATOMIC to
 prevent blocking, or if it's permitted (not in_interrupt, not holding SMP locks),
@@ -122,9 +106,6 @@ pool's device.
 	void dma_pool_free(struct dma_pool *pool, void *vaddr,
 			dma_addr_t addr);
 
-	void pci_pool_free(struct pci_pool *pool, void *vaddr,
-			dma_addr_t addr);
-
 This puts memory back into the pool.  The pool is what was passed to
 the pool allocation routine; the cpu (vaddr) and dma addresses are what
 were returned when that routine allocated the memory being freed.
@@ -132,8 +113,6 @@ were returned when that routine allocate
 
 	void dma_pool_destroy(struct dma_pool *pool);
 
-	void pci_pool_destroy(struct pci_pool *pool);
-
 The pool destroy() routines free the resources of the pool.  They must be
 called in a context which can sleep.  Make sure you've freed all allocated
 memory back to the pool before you destroy it.
@@ -144,8 +123,6 @@ Part Ic - DMA addressing limitations
 
 int
 dma_supported(struct device *dev, u64 mask)
-int
-pci_dma_supported(struct pci_dev *hwdev, u64 mask)
 
 Checks to see if the device can support DMA to the memory described by
 mask.
@@ -159,8 +136,14 @@ driver writers.
 
 int
 dma_set_mask(struct device *dev, u64 mask)
+
+Checks to see if the mask is possible and updates the device
+parameters if it is.
+
+Returns: 0 if successful and a negative error if not.
+
 int
-pci_set_dma_mask(struct pci_device *dev, u64 mask)
+dma_set_coherent_mask(struct device *dev, u64 mask)
 
 Checks to see if the mask is possible and updates the device
 parameters if it is.
@@ -187,9 +170,6 @@ Part Id - Streaming DMA mappings
 dma_addr_t
 dma_map_single(struct device *dev, void *cpu_addr, size_t size,
 		      enum dma_data_direction direction)
-dma_addr_t
-pci_map_single(struct pci_dev *hwdev, void *cpu_addr, size_t size,
-		      int direction)
 
 Maps a piece of processor virtual memory so it can be accessed by the
 device and returns the physical handle of the memory.
@@ -198,14 +178,10 @@ The direction for both api's may be conv
 However the dma_ API uses a strongly typed enumerator for its
 direction:
 
-DMA_NONE		= PCI_DMA_NONE		no direction (used for
-						debugging)
-DMA_TO_DEVICE		= PCI_DMA_TODEVICE	data is going from the
-						memory to the device
-DMA_FROM_DEVICE		= PCI_DMA_FROMDEVICE	data is coming from
-						the device to the
-						memory
-DMA_BIDIRECTIONAL	= PCI_DMA_BIDIRECTIONAL	direction isn't known
+DMA_NONE		no direction (used for debugging)
+DMA_TO_DEVICE		data is going from the memory to the device
+DMA_FROM_DEVICE		data is coming from the device to the memory
+DMA_BIDIRECTIONAL	direction isn't known
 
 Notes:  Not all memory regions in a machine can be mapped by this
 API.  Further, regions that appear to be physically contiguous in
@@ -268,9 +244,6 @@ cache lines are updated with data that t
 void
 dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 		 enum dma_data_direction direction)
-void
-pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
-		 size_t size, int direction)
 
 Unmaps the region previously mapped.  All the parameters passed in
 must be identical to those passed in (and returned) by the mapping
@@ -280,15 +253,9 @@ dma_addr_t
 dma_map_page(struct device *dev, struct page *page,
 		    unsigned long offset, size_t size,
 		    enum dma_data_direction direction)
-dma_addr_t
-pci_map_page(struct pci_dev *hwdev, struct page *page,
-		    unsigned long offset, size_t size, int direction)
 void
 dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
 	       enum dma_data_direction direction)
-void
-pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
-	       size_t size, int direction)
 
 API for mapping and unmapping for pages.  All the notes and warnings
 for the other mapping APIs apply here.  Also, although the <offset>
@@ -299,9 +266,6 @@ cache width is.
 int
 dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 
-int
-pci_dma_mapping_error(struct pci_dev *hwdev, dma_addr_t dma_addr)
-
 In some circumstances dma_map_single and dma_map_page will fail to create
 a mapping. A driver can check for these errors by testing the returned
 dma address with dma_mapping_error(). A non-zero return value means the mapping
@@ -311,9 +275,6 @@ reduce current DMA mapping usage or dela
 	int
 	dma_map_sg(struct device *dev, struct scatterlist *sg,
 		int nents, enum dma_data_direction direction)
-	int
-	pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
-		int nents, int direction)
 
 Returns: the number of physical segments mapped (this may be shorter
 than <nents> passed in if some elements of the scatter/gather list are
@@ -353,9 +314,6 @@ accessed sg->address and sg->length as s
 	void
 	dma_unmap_sg(struct device *dev, struct scatterlist *sg,
 		int nhwentries, enum dma_data_direction direction)
-	void
-	pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
-		int nents, int direction)
 
 Unmap the previously mapped scatter/gather list.  All the parameters
 must be the same as those and passed in to the scatter/gather mapping
@@ -365,21 +323,23 @@ Note: <nents> must be the number you pas
 physical entries returned.
 
 void
-dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size,
-		enum dma_data_direction direction)
+dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
+			enum dma_data_direction direction)
 void
-pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle,
-			   size_t size, int direction)
+dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
+			   enum dma_data_direction direction)
 void
-dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems,
-			  enum dma_data_direction direction)
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+		    enum dma_data_direction direction)
 void
-pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg,
-		       int nelems, int direction)
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+		       enum dma_data_direction direction)
 
-Synchronise a single contiguous or scatter/gather mapping.  All the
-parameters must be the same as those passed into the single mapping
-API.
+Synchronise a single contiguous or scatter/gather mapping for the cpu
+and device. With the sync_sg API, all the parameters must be the same
+as those passed into the single mapping API. With the sync_single API,
+you can use dma_handle and size parameters that aren't identical to
+those passed into the single mapping API to do a partial sync.
 
 Notes:  You must do this:
 
@@ -461,9 +421,9 @@ void whizco_dma_map_sg_attrs(struct devi
 Part II - Advanced dma_ usage
 -----------------------------
 
-Warning: These pieces of the DMA API have no PCI equivalent.  They
-should also not be used in the majority of cases, since they cater for
-unlikely corner cases that don't belong in usual drivers.
+Warning: These pieces of the DMA API should not be used in the
+majority of cases, since they cater for unlikely corner cases that
+don't belong in usual drivers.
 
 If you don't understand how cache line coherency works between a
 processor and an I/O device, you should not be using this part of the
@@ -514,16 +474,6 @@ into the width returned by this call.  I
 of two for easy alignment.
 
 void
-dma_sync_single_range(struct device *dev, dma_addr_t dma_handle,
-		      unsigned long offset, size_t size,
-		      enum dma_data_direction direction)
-
-Does a partial sync, starting at offset and continuing for size.  You
-must be careful to observe the cache alignment and width when doing
-anything like this.  You must also be extra careful about accessing
-memory you intend to sync partially.
-
-void
 dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 	       enum dma_data_direction direction)
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/DocBook/device-drivers.tmpl linux-libre-2.6.34-gnu1/Documentation/DocBook/device-drivers.tmpl
--- linux-libre-2.6.33-gnu1/Documentation/DocBook/device-drivers.tmpl	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/DocBook/device-drivers.tmpl	2010-05-16 17:17:36.000000000 -0400
@@ -45,7 +45,7 @@
      </sect1>
 
      <sect1><title>Atomic and pointer manipulation</title>
-!Iarch/x86/include/asm/atomic_32.h
+!Iarch/x86/include/asm/atomic.h
 !Iarch/x86/include/asm/unaligned.h
      </sect1>
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/DocBook/deviceiobook.tmpl linux-libre-2.6.34-gnu1/Documentation/DocBook/deviceiobook.tmpl
--- linux-libre-2.6.33-gnu1/Documentation/DocBook/deviceiobook.tmpl	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/DocBook/deviceiobook.tmpl	2010-05-16 17:17:36.000000000 -0400
@@ -316,7 +316,7 @@ CPU B:  spin_unlock_irqrestore(&amp;dev_
 
   <chapter id="pubfunctions">
      <title>Public Functions Provided</title>
-!Iarch/x86/include/asm/io_32.h
+!Iarch/x86/include/asm/io.h
 !Elib/iomap.c
   </chapter>
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/DocBook/libata.tmpl linux-libre-2.6.34-gnu1/Documentation/DocBook/libata.tmpl
--- linux-libre-2.6.33-gnu1/Documentation/DocBook/libata.tmpl	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/DocBook/libata.tmpl	2010-05-16 17:17:36.000000000 -0400
@@ -107,10 +107,6 @@ void (*dev_config) (struct ata_port *, s
 	issue of SET FEATURES - XFER MODE, and prior to operation.
 	</para>
 	<para>
-	Called by ata_device_add() after ata_dev_identify() determines
-	a device is present.
-	</para>
-	<para>
 	This entry may be specified as NULL in ata_port_operations.
 	</para>
 
@@ -154,8 +150,8 @@ unsigned int (*mode_filter) (struct ata_
 
 	<sect2><title>Taskfile read/write</title>
 	<programlisting>
-void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
-void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
+void (*sff_tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
+void (*sff_tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
 	</programlisting>
 
 	<para>
@@ -164,36 +160,35 @@ void (*tf_read) (struct ata_port *ap, st
 	hardware registers / DMA buffers, to obtain the current set of
 	taskfile register values.
 	Most drivers for taskfile-based hardware (PIO or MMIO) use
-	ata_tf_load() and ata_tf_read() for these hooks.
+	ata_sff_tf_load() and ata_sff_tf_read() for these hooks.
 	</para>
 
 	</sect2>
 
 	<sect2><title>PIO data read/write</title>
 	<programlisting>
-void (*data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
+void (*sff_data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
 	</programlisting>
 
 	<para>
 All bmdma-style drivers must implement this hook.  This is the low-level
 operation that actually copies the data bytes during a PIO data
 transfer.
-Typically the driver
-will choose one of ata_pio_data_xfer_noirq(), ata_pio_data_xfer(), or
-ata_mmio_data_xfer().
+Typically the driver will choose one of ata_sff_data_xfer_noirq(),
+ata_sff_data_xfer(), or ata_sff_data_xfer32().
 	</para>
 
 	</sect2>
 
 	<sect2><title>ATA command execute</title>
 	<programlisting>
-void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
+void (*sff_exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
 	</programlisting>
 
 	<para>
 	causes an ATA command, previously loaded with
 	->tf_load(), to be initiated in hardware.
-	Most drivers for taskfile-based hardware use ata_exec_command()
+	Most drivers for taskfile-based hardware use ata_sff_exec_command()
 	for this hook.
 	</para>
 
@@ -218,8 +213,8 @@ command.
 
 	<sect2><title>Read specific ATA shadow registers</title>
 	<programlisting>
-u8   (*check_status)(struct ata_port *ap);
-u8   (*check_altstatus)(struct ata_port *ap);
+u8   (*sff_check_status)(struct ata_port *ap);
+u8   (*sff_check_altstatus)(struct ata_port *ap);
 	</programlisting>
 
 	<para>
@@ -227,20 +222,14 @@ u8   (*check_altstatus)(struct ata_port
 	hardware.  On some hardware, reading the Status register has
 	the side effect of clearing the interrupt condition.
 	Most drivers for taskfile-based hardware use
-	ata_check_status() for this hook.
-	</para>
-	<para>
-	Note that because this is called from ata_device_add(), at
-	least a dummy function that clears device interrupts must be
-	provided for all drivers, even if the controller doesn't
-	actually have a taskfile status register.
+	ata_sff_check_status() for this hook.
 	</para>
 
 	</sect2>
 
 	<sect2><title>Select ATA device on bus</title>
 	<programlisting>
-void (*dev_select)(struct ata_port *ap, unsigned int device);
+void (*sff_dev_select)(struct ata_port *ap, unsigned int device);
 	</programlisting>
 
 	<para>
@@ -251,9 +240,7 @@ void (*dev_select)(struct ata_port *ap,
 	</para>
 	<para>
 	Most drivers for taskfile-based hardware use
-	ata_std_dev_select() for this hook.  Controllers which do not
-	support second drives on a port (such as SATA contollers) will
-	use ata_noop_dev_select().
+	ata_sff_dev_select() for this hook.
 	</para>
 
 	</sect2>
@@ -441,13 +428,13 @@ void (*irq_clear) (struct ata_port *);
 	to struct ata_host_set.
 	</para>
 	<para>
-	Most legacy IDE drivers use ata_interrupt() for the
+	Most legacy IDE drivers use ata_sff_interrupt() for the
 	irq_handler hook, which scans all ports in the host_set,
 	determines which queued command was active (if any), and calls
-	ata_host_intr(ap,qc).
+	ata_sff_host_intr(ap,qc).
 	</para>
 	<para>
-	Most legacy IDE drivers use ata_bmdma_irq_clear() for the
+	Most legacy IDE drivers use ata_sff_irq_clear() for the
 	irq_clear() hook, which simply clears the interrupt and error
 	flags in the DMA status register.
 	</para>
@@ -496,10 +483,6 @@ void (*host_stop) (struct ata_host_set *
 	data from port at this time.
 	</para>
 	<para>
-	Many drivers use ata_port_stop() as this hook, which frees the
-	PRD table.
-	</para>
-	<para>
 	->host_stop() is called after all ->port_stop() calls
 have completed.  The hook must finalize hardware shutdown, release DMA
 and other resources, etc.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/DocBook/mac80211.tmpl linux-libre-2.6.34-gnu1/Documentation/DocBook/mac80211.tmpl
--- linux-libre-2.6.33-gnu1/Documentation/DocBook/mac80211.tmpl	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/DocBook/mac80211.tmpl	2010-05-16 17:17:36.000000000 -0400
@@ -144,7 +144,7 @@ usage should require reading the full do
         this though and the recommendation to allow only a single
         interface in STA mode at first!
       </para>
-!Finclude/net/mac80211.h ieee80211_if_init_conf
+!Finclude/net/mac80211.h ieee80211_vif
     </chapter>
 
     <chapter id="rx-tx">
@@ -234,7 +234,6 @@ usage should require reading the full do
       <title>Multiple queues and QoS support</title>
       <para>TBD</para>
 !Finclude/net/mac80211.h ieee80211_tx_queue_params
-!Finclude/net/mac80211.h ieee80211_tx_queue_stats
     </chapter>
 
     <chapter id="AP">
diff -druNp linux-libre-2.6.33-gnu1/Documentation/DocBook/mtdnand.tmpl linux-libre-2.6.34-gnu1/Documentation/DocBook/mtdnand.tmpl
--- linux-libre-2.6.33-gnu1/Documentation/DocBook/mtdnand.tmpl	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/DocBook/mtdnand.tmpl	2010-05-16 17:17:36.000000000 -0400
@@ -488,7 +488,7 @@ static void board_select_chip (struct mt
 				The ECC bytes must be placed immidiately after the data
 				bytes in order to make the syndrome generator work. This
 				is contrary to the usual layout used by software ECC. The
-				seperation of data and out of band area is not longer
+				separation of data and out of band area is not longer
 				possible. The nand driver code handles this layout and
 				the remaining free bytes in the oob area are managed by 
 				the autoplacement code. Provide a matching oob-layout
@@ -560,7 +560,7 @@ static void board_select_chip (struct mt
 				bad blocks. They have factory marked good blocks. The marker pattern
 				is erased when the block is erased to be reused. So in case of
 				powerloss before writing the pattern back to the chip this block 
-				would be lost and added to the bad blocks. Therefor we scan the 
+				would be lost and added to the bad blocks. Therefore we scan the 
 				chip(s) when we detect them the first time for good blocks and 
 				store this information in a bad block table before erasing any 
 				of the blocks.
@@ -1094,7 +1094,7 @@ in this page</entry>
 		manufacturers specifications. This applies similar to the spare area. 
 	</para>
 	<para>
-		Therefor NAND aware filesystems must either write in page size chunks
+		Therefore NAND aware filesystems must either write in page size chunks
 		or hold a writebuffer to collect smaller writes until they sum up to 
 		pagesize. Available NAND aware filesystems: JFFS2, YAFFS. 		
 	</para>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/DocBook/tracepoint.tmpl linux-libre-2.6.34-gnu1/Documentation/DocBook/tracepoint.tmpl
--- linux-libre-2.6.33-gnu1/Documentation/DocBook/tracepoint.tmpl	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/DocBook/tracepoint.tmpl	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,15 @@
      </address>
     </affiliation>
    </author>
+   <author>
+    <firstname>William</firstname>
+    <surname>Cohen</surname>
+    <affiliation>
+     <address>
+      <email>wcohen@redhat.com</email>
+     </address>
+    </affiliation>
+   </author>
   </authorgroup>
 
   <legalnotice>
@@ -91,4 +100,8 @@
 !Iinclude/trace/events/signal.h
   </chapter>
 
+  <chapter id="block">
+   <title>Block IO</title>
+!Iinclude/trace/events/block.h
+  </chapter>
 </book>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/common.xml linux-libre-2.6.34-gnu1/Documentation/DocBook/v4l/common.xml
--- linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/common.xml	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/DocBook/v4l/common.xml	2010-05-16 17:17:36.000000000 -0400
@@ -1170,7 +1170,7 @@ frames per second. If less than this num
 captured or output, applications can request frame skipping or
 duplicating on the driver side. This is especially useful when using
 the &func-read; or &func-write;, which are not augmented by timestamps
-or sequence counters, and to avoid unneccessary data copying.</para>
+or sequence counters, and to avoid unnecessary data copying.</para>
 
     <para>Finally these ioctls can be used to determine the number of
 buffers used internally by a driver in read/write mode. For
diff -druNp linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/io.xml linux-libre-2.6.34-gnu1/Documentation/DocBook/v4l/io.xml
--- linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/io.xml	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/DocBook/v4l/io.xml	2010-05-16 17:17:36.000000000 -0400
@@ -589,7 +589,8 @@ number of a video input as in &v4l2-inpu
 	    <entry></entry>
 	    <entry>A place holder for future extensions and custom
 (driver defined) buffer types
-<constant>V4L2_BUF_TYPE_PRIVATE</constant> and higher.</entry>
+<constant>V4L2_BUF_TYPE_PRIVATE</constant> and higher. Applications
+should set this to 0.</entry>
 	  </row>
 	</tbody>
       </tgroup>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-g-parm.xml linux-libre-2.6.34-gnu1/Documentation/DocBook/v4l/vidioc-g-parm.xml
--- linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-g-parm.xml	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/DocBook/v4l/vidioc-g-parm.xml	2010-05-16 17:17:36.000000000 -0400
@@ -55,7 +55,7 @@ captured or output, applications can req
 duplicating on the driver side. This is especially useful when using
 the <function>read()</function> or <function>write()</function>, which
 are not augmented by timestamps or sequence counters, and to avoid
-unneccessary data copying.</para>
+unnecessary data copying.</para>
 
     <para>Further these ioctls can be used to determine the number of
 buffers used internally by a driver in read/write mode. For
diff -druNp linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-qbuf.xml linux-libre-2.6.34-gnu1/Documentation/DocBook/v4l/vidioc-qbuf.xml
--- linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-qbuf.xml	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/DocBook/v4l/vidioc-qbuf.xml	2010-05-16 17:17:36.000000000 -0400
@@ -54,12 +54,10 @@ to enqueue an empty (capturing) or fille
 driver's incoming queue. The semantics depend on the selected I/O
 method.</para>
 
-    <para>To enqueue a <link linkend="mmap">memory mapped</link>
-buffer applications set the <structfield>type</structfield> field of a
-&v4l2-buffer; to the same buffer type as previously &v4l2-format;
-<structfield>type</structfield> and &v4l2-requestbuffers;
-<structfield>type</structfield>, the <structfield>memory</structfield>
-field to <constant>V4L2_MEMORY_MMAP</constant> and the
+    <para>To enqueue a buffer applications set the <structfield>type</structfield>
+field of a &v4l2-buffer; to the same buffer type as was previously used
+with &v4l2-format; <structfield>type</structfield> and &v4l2-requestbuffers;
+<structfield>type</structfield>. Applications must also set the
 <structfield>index</structfield> field. Valid index numbers range from
 zero to the number of buffers allocated with &VIDIOC-REQBUFS;
 (&v4l2-requestbuffers; <structfield>count</structfield>) minus one. The
@@ -70,8 +68,19 @@ intended for output (<structfield>type</
 <constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant>) applications must also
 initialize the <structfield>bytesused</structfield>,
 <structfield>field</structfield> and
-<structfield>timestamp</structfield> fields. See <xref
-	linkend="buffer" /> for details. When
+<structfield>timestamp</structfield> fields, see <xref
+linkend="buffer" /> for details.
+Applications must also set <structfield>flags</structfield> to 0. If a driver
+supports capturing from specific video inputs and you want to specify a video
+input, then <structfield>flags</structfield> should be set to
+<constant>V4L2_BUF_FLAG_INPUT</constant> and the field
+<structfield>input</structfield> must be initialized to the desired input.
+The <structfield>reserved</structfield> field must be set to 0.
+</para>
+
+    <para>To enqueue a <link linkend="mmap">memory mapped</link>
+buffer applications set the <structfield>memory</structfield>
+field to <constant>V4L2_MEMORY_MMAP</constant>. When
 <constant>VIDIOC_QBUF</constant> is called with a pointer to this
 structure the driver sets the
 <constant>V4L2_BUF_FLAG_MAPPED</constant> and
@@ -81,14 +90,10 @@ structure the driver sets the
 &EINVAL;.</para>
 
     <para>To enqueue a <link linkend="userp">user pointer</link>
-buffer applications set the <structfield>type</structfield> field of a
-&v4l2-buffer; to the same buffer type as previously &v4l2-format;
-<structfield>type</structfield> and &v4l2-requestbuffers;
-<structfield>type</structfield>, the <structfield>memory</structfield>
-field to <constant>V4L2_MEMORY_USERPTR</constant> and the
+buffer applications set the <structfield>memory</structfield>
+field to <constant>V4L2_MEMORY_USERPTR</constant>, the
 <structfield>m.userptr</structfield> field to the address of the
-buffer and <structfield>length</structfield> to its size. When the
-buffer is intended for output additional fields must be set as above.
+buffer and <structfield>length</structfield> to its size.
 When <constant>VIDIOC_QBUF</constant> is called with a pointer to this
 structure the driver sets the <constant>V4L2_BUF_FLAG_QUEUED</constant>
 flag and clears the <constant>V4L2_BUF_FLAG_MAPPED</constant> and
@@ -96,13 +101,14 @@ flag and clears the <constant>V4L2_BUF_F
 <structfield>flags</structfield> field, or it returns an error code.
 This ioctl locks the memory pages of the buffer in physical memory,
 they cannot be swapped out to disk. Buffers remain locked until
-dequeued, until the &VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl are
+dequeued, until the &VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl is
 called, or until the device is closed.</para>
 
     <para>Applications call the <constant>VIDIOC_DQBUF</constant>
 ioctl to dequeue a filled (capturing) or displayed (output) buffer
 from the driver's outgoing queue. They just set the
-<structfield>type</structfield> and <structfield>memory</structfield>
+<structfield>type</structfield>, <structfield>memory</structfield>
+and <structfield>reserved</structfield>
 fields of a &v4l2-buffer; as above, when <constant>VIDIOC_DQBUF</constant>
 is called with a pointer to this structure the driver fills the
 remaining fields or returns an error code.</para>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-querybuf.xml linux-libre-2.6.34-gnu1/Documentation/DocBook/v4l/vidioc-querybuf.xml
--- linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-querybuf.xml	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/DocBook/v4l/vidioc-querybuf.xml	2010-05-16 17:17:36.000000000 -0400
@@ -54,12 +54,13 @@ buffer at any time after buffers have be
 &VIDIOC-REQBUFS; ioctl.</para>
 
     <para>Applications set the <structfield>type</structfield> field
-    of a &v4l2-buffer; to the same buffer type as previously
+    of a &v4l2-buffer; to the same buffer type as was previously used with
 &v4l2-format; <structfield>type</structfield> and &v4l2-requestbuffers;
 <structfield>type</structfield>, and the <structfield>index</structfield>
     field. Valid index numbers range from zero
 to the number of buffers allocated with &VIDIOC-REQBUFS;
     (&v4l2-requestbuffers; <structfield>count</structfield>) minus one.
+The <structfield>reserved</structfield> field should to set to 0.
 After calling <constant>VIDIOC_QUERYBUF</constant> with a pointer to
     this structure drivers return an error code or fill the rest of
 the structure.</para>
@@ -68,8 +69,8 @@ the structure.</para>
 <constant>V4L2_BUF_FLAG_MAPPED</constant>,
 <constant>V4L2_BUF_FLAG_QUEUED</constant> and
 <constant>V4L2_BUF_FLAG_DONE</constant> flags will be valid. The
-<structfield>memory</structfield> field will be set to
-<constant>V4L2_MEMORY_MMAP</constant>, the <structfield>m.offset</structfield>
+<structfield>memory</structfield> field will be set to the current
+I/O method, the <structfield>m.offset</structfield>
 contains the offset of the buffer from the start of the device memory,
 the <structfield>length</structfield> field its size. The driver may
 or may not set the remaining fields and flags, they are meaningless in
diff -druNp linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-reqbufs.xml linux-libre-2.6.34-gnu1/Documentation/DocBook/v4l/vidioc-reqbufs.xml
--- linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-reqbufs.xml	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/DocBook/v4l/vidioc-reqbufs.xml	2010-05-16 17:17:36.000000000 -0400
@@ -54,23 +54,23 @@ I/O. Memory mapped buffers are located i
 allocated with this ioctl before they can be mapped into the
 application's address space. User buffers are allocated by
 applications themselves, and this ioctl is merely used to switch the
-driver into user pointer I/O mode.</para>
+driver into user pointer I/O mode and to setup some internal structures.</para>
 
-    <para>To allocate device buffers applications initialize three
-fields of a <structname>v4l2_requestbuffers</structname> structure.
+    <para>To allocate device buffers applications initialize all
+fields of the <structname>v4l2_requestbuffers</structname> structure.
 They set the <structfield>type</structfield> field to the respective
 stream or buffer type, the <structfield>count</structfield> field to
-the desired number of buffers, and <structfield>memory</structfield>
-must be set to <constant>V4L2_MEMORY_MMAP</constant>. When the ioctl
-is called with a pointer to this structure the driver attempts to
-allocate the requested number of buffers and stores the actual number
+the desired number of buffers, <structfield>memory</structfield>
+must be set to the requested I/O method and the reserved array
+must be zeroed. When the ioctl
+is called with a pointer to this structure the driver will attempt to allocate
+the requested number of buffers and it stores the actual number
 allocated in the <structfield>count</structfield> field. It can be
 smaller than the number requested, even zero, when the driver runs out
-of free memory. A larger number is possible when the driver requires
-more buffers to function correctly.<footnote>
-	<para>For example video output requires at least two buffers,
+of free memory. A larger number is also possible when the driver requires
+more buffers to function correctly. For example video output requires at least two buffers,
 one displayed and one filled by the application.</para>
-	</footnote> When memory mapping I/O is not supported the ioctl
+    <para>When the I/O method is not supported the ioctl
 returns an &EINVAL;.</para>
 
     <para>Applications can call <constant>VIDIOC_REQBUFS</constant>
@@ -81,14 +81,6 @@ in progress, an implicit &VIDIOC-STREAMO
 reason why munmap()ping one or even all buffers must imply
 streamoff.--></para>
 
-    <para>To negotiate user pointer I/O, applications initialize only
-the <structfield>type</structfield> field and set
-<structfield>memory</structfield> to
-<constant>V4L2_MEMORY_USERPTR</constant>. When the ioctl is called
-with a pointer to this structure the driver prepares for user pointer
-I/O, when this I/O method is not supported the ioctl returns an
-&EINVAL;.</para>
-
     <table pgwide="1" frame="none" id="v4l2-requestbuffers">
       <title>struct <structname>v4l2_requestbuffers</structname></title>
       <tgroup cols="3">
@@ -97,9 +89,7 @@ I/O, when this I/O method is not support
 	  <row>
 	    <entry>__u32</entry>
 	    <entry><structfield>count</structfield></entry>
-	    <entry>The number of buffers requested or granted. This
-field is only used when <structfield>memory</structfield> is set to
-<constant>V4L2_MEMORY_MMAP</constant>.</entry>
+	    <entry>The number of buffers requested or granted.</entry>
 	  </row>
 	  <row>
 	    <entry>&v4l2-buf-type;</entry>
@@ -120,7 +110,7 @@ as the &v4l2-format; <structfield>type</
 	    <entry><structfield>reserved</structfield>[2]</entry>
 	    <entry>A place holder for future extensions and custom
 (driver defined) buffer types <constant>V4L2_BUF_TYPE_PRIVATE</constant> and
-higher.</entry>
+higher. This array should be zeroed by applications.</entry>
 	  </row>
 	</tbody>
       </tgroup>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/dontdiff linux-libre-2.6.34-gnu1/Documentation/dontdiff
--- linux-libre-2.6.33-gnu1/Documentation/dontdiff	2013-05-03 12:03:02.000000000 -0400
+++ linux-libre-2.6.34-gnu1/Documentation/dontdiff	2013-05-03 09:44:05.000000000 -0400
@@ -69,7 +69,6 @@ av_permissions.h
 bbootsect
 bin2c
 binkernel.spec
-binoffset
 bootsect
 bounds.h
 bsetup
diff -druNp linux-libre-2.6.33-gnu1/Documentation/driver-model/platform.txt linux-libre-2.6.34-gnu1/Documentation/driver-model/platform.txt
--- linux-libre-2.6.33-gnu1/Documentation/driver-model/platform.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/driver-model/platform.txt	2010-05-16 17:17:36.000000000 -0400
@@ -192,7 +192,7 @@ command line. This will execute all matc
 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
+the class string, "serial" is the name of the platform driver and
 0 is the platform device id. If the id is -1 then the dot and the
 id can be omitted.
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/eisa.txt linux-libre-2.6.34-gnu1/Documentation/eisa.txt
--- linux-libre-2.6.33-gnu1/Documentation/eisa.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/eisa.txt	2010-05-16 17:17:36.000000000 -0400
@@ -171,7 +171,7 @@ device.
 virtual_root.force_probe :
 
 Force the probing code to probe EISA slots even when it cannot find an
-EISA compliant mainboard (nothing appears on slot 0). Defaultd to 0
+EISA compliant mainboard (nothing appears on slot 0). Defaults to 0
 (don't force), and set to 1 (force probing) when either
 CONFIG_ALPHA_JENSEN or CONFIG_EISA_VLB_PRIMING are set.
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/email-clients.txt linux-libre-2.6.34-gnu1/Documentation/email-clients.txt
--- linux-libre-2.6.33-gnu1/Documentation/email-clients.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/email-clients.txt	2010-05-16 17:17:36.000000000 -0400
@@ -216,26 +216,14 @@ Works.  Use "Insert file..." or external
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Gmail (Web GUI)
 
-If you just have to use Gmail to send patches, it CAN be made to work.  It
-requires a bit of external help, though.
-
-The first problem is that Gmail converts tabs to spaces.  This will
-totally break your patches.  To prevent this, you have to use a different
-editor.  There is a firefox extension called "ViewSourceWith"
-(https://addons.mozilla.org/en-US/firefox/addon/394) which allows you to
-edit any text box in the editor of your choice.  Configure it to launch
-your favorite editor.  When you want to send a patch, use this technique.
-Once you have crafted your messsage + patch, save and exit the editor,
-which should reload the Gmail edit box.  GMAIL WILL PRESERVE THE TABS.
-Hoorah.  Apparently you can cut-n-paste literal tabs, but Gmail will
-convert those to spaces upon sending!
+Does not work for sending patches.
 
-The second problem is that Gmail converts tabs to spaces on replies.  If
-you reply to a patch, don't expect to be able to apply it as a patch.
+Gmail web client converts tabs to spaces automatically.
 
-The last problem is that Gmail will base64-encode any message that has a
-non-ASCII character.  That includes things like European names.  Be aware.
+At the same time it wraps lines every 78 chars with CRLF style line breaks
+although tab2space problem can be solved with external editor.
 
-Gmail is not convenient for lkml patches, but CAN be made to work.
+Another problem is that Gmail will base64-encode any message that has a
+non-ASCII character. That includes things like European names.
 
                                 ###
diff -druNp linux-libre-2.6.33-gnu1/Documentation/fault-injection/provoke-crashes.txt linux-libre-2.6.34-gnu1/Documentation/fault-injection/provoke-crashes.txt
--- linux-libre-2.6.33-gnu1/Documentation/fault-injection/provoke-crashes.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/fault-injection/provoke-crashes.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,38 @@
+The lkdtm module provides an interface to crash or injure the kernel at
+predefined crashpoints to evaluate the reliability of crash dumps obtained
+using different dumping solutions. The module uses KPROBEs to instrument
+crashing points, but can also crash the kernel directly without KRPOBE
+support.
+
+
+You can provide the way either through module arguments when inserting
+the module, or through a debugfs interface.
+
+Usage: insmod lkdtm.ko [recur_count={>0}] cpoint_name=<> cpoint_type=<>
+				[cpoint_count={>0}]
+
+  recur_count : Recursion level for the stack overflow test. Default is 10.
+
+  cpoint_name : Crash point where the kernel is to be crashed. It can be
+	 one of INT_HARDWARE_ENTRY, INT_HW_IRQ_EN, INT_TASKLET_ENTRY,
+	 FS_DEVRW, MEM_SWAPOUT, TIMERADD, SCSI_DISPATCH_CMD,
+	 IDE_CORE_CP, DIRECT
+
+  cpoint_type : Indicates the action to be taken on hitting the crash point.
+     It can be one of PANIC, BUG, EXCEPTION, LOOP, OVERFLOW,
+     CORRUPT_STACK, UNALIGNED_LOAD_STORE_WRITE, OVERWRITE_ALLOCATION,
+     WRITE_AFTER_FREE,
+
+  cpoint_count : Indicates the number of times the crash point is to be hit
+    to trigger an action. The default is 10.
+
+You can also induce failures by mounting debugfs and writing the type to
+<mountpoint>/provoke-crash/<crashpoint>. E.g.,
+
+  mount -t debugfs debugfs /mnt
+  echo EXCEPTION > /mnt/provoke-crash/INT_HARDWARE_ENTRY
+
+
+A special file is `DIRECT' which will induce the crash directly without
+KPROBE instrumentation. This mode is the only one available when the module
+is built on a kernel without KPROBEs support.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/fb/efifb.txt linux-libre-2.6.34-gnu1/Documentation/fb/efifb.txt
--- linux-libre-2.6.33-gnu1/Documentation/fb/efifb.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/fb/efifb.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,31 @@
+
+What is efifb?
+===============
+
+This is a generic EFI platform driver for Intel based Apple computers.
+efifb is only for EFI booted Intel Macs.
+
+Supported Hardware
+==================
+
+iMac 17"/20"
+Macbook
+Macbook Pro 15"/17"
+MacMini
+
+How to use it?
+==============
+
+efifb does not have any kind of autodetection of your machine.
+You have to add the following kernel parameters in your elilo.conf:
+	Macbook :
+		video=efifb:macbook
+	MacMini :
+		video=efifb:mini
+	Macbook Pro 15", iMac 17" :
+		video=efifb:i17
+	Macbook Pro 17", iMac 20" :
+		video=efifb:i20
+
+--
+Edgar Hucek <gimli@dark-green.com>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/fb/imacfb.txt linux-libre-2.6.34-gnu1/Documentation/fb/imacfb.txt
--- linux-libre-2.6.33-gnu1/Documentation/fb/imacfb.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/fb/imacfb.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,31 +0,0 @@
-
-What is imacfb?
-===============
-
-This is a generic EFI platform driver for Intel based Apple computers.
-Imacfb is only for EFI booted Intel Macs.
-
-Supported Hardware
-==================
-
-iMac 17"/20"
-Macbook
-Macbook Pro 15"/17"
-MacMini
-
-How to use it?
-==============
-
-Imacfb does not have any kind of autodetection of your machine.
-You have to add the following kernel parameters in your elilo.conf:
-	Macbook :
-		video=imacfb:macbook
-	MacMini :
-		video=imacfb:mini
-	Macbook Pro 15", iMac 17" :
-		video=imacfb:i17
-	Macbook Pro 17", iMac 20" :
-		video=imacfb:i20
-
---
-Edgar Hucek <gimli@dark-green.com>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/feature-removal-schedule.txt linux-libre-2.6.34-gnu1/Documentation/feature-removal-schedule.txt
--- linux-libre-2.6.33-gnu1/Documentation/feature-removal-schedule.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/feature-removal-schedule.txt	2010-05-16 17:17:36.000000000 -0400
@@ -6,21 +6,6 @@ be removed from this file.
 
 ---------------------------
 
-What:	USER_SCHED
-When:	2.6.34
-
-Why:	USER_SCHED was implemented as a proof of concept for group scheduling.
-	The effect of USER_SCHED can already be achieved from userspace with
-	the help of libcgroup. The removal of USER_SCHED will also simplify
-	the scheduler code with the removal of one major ifdef. There are also
-	issues USER_SCHED has with USER_NS. A decision was taken not to fix
-	those and instead remove USER_SCHED. Also new group scheduling
-	features will not be implemented for USER_SCHED.
-
-Who:	Dhaval Giani <dhaval@linux.vnet.ibm.com>
-
----------------------------
-
 What:	PRISM54
 When:	2.6.34
 
@@ -64,6 +49,17 @@ Who:	Robin Getz <rgetz@blackfin.uclinux.
 
 ---------------------------
 
+What:	Deprecated snapshot ioctls
+When:	2.6.36
+
+Why:	The ioctls in kernel/power/user.c were marked as deprecated long time
+	ago. Now they notify users about that so that they need to replace
+	their userspace. After some more time, remove them completely.
+
+Who:	Jiri Slaby <jirislaby@gmail.com>
+
+---------------------------
+
 What:	The ieee80211_regdom module parameter
 When:	March 2010 / desktop catchup
 
@@ -88,27 +84,6 @@ Who:	Luis R. Rodriguez <lrodriguez@ather
 
 ---------------------------
 
-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 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>
-
----------------------------
-
 What:	dev->power.power_state
 When:	July 2007
 Why:	Broken design for runtime control over driver power states, confusing
@@ -142,19 +117,25 @@ Who:	Mauro Carvalho Chehab <mchehab@infr
 ---------------------------
 
 What:	PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
-When:	November 2005
+When:	2.6.35/2.6.36
 Files:	drivers/pcmcia/: pcmcia_ioctl.c
 Why:	With the 16-bit PCMCIA subsystem now behaving (almost) like a
 	normal hotpluggable bus, and with it using the default kernel
 	infrastructure (hotplug, driver core, sysfs) keeping the PCMCIA
 	control ioctl needed by cardmgr and cardctl from pcmcia-cs is
-	unnecessary, and makes further cleanups and integration of the
+	unnecessary and potentially harmful (it does not provide for
+	proper locking), and makes further cleanups and integration of the
 	PCMCIA subsystem into the Linux kernel device driver model more
 	difficult. The features provided by cardmgr and cardctl are either
 	handled by the kernel itself now or are available in the new
 	pcmciautils package available at
 	http://kernel.org/pub/linux/utils/kernel/pcmcia/
-Who:	Dominik Brodowski <linux@brodo.de>
+
+	For all architectures except ARM, the associated config symbol
+	has been removed from kernel 2.6.34; for ARM, it will be likely
+	be removed from kernel 2.6.35. The actual code will then likely
+	be removed from kernel 2.6.36.
+Who:	Dominik Brodowski <linux@dominikbrodowski.net>
 
 ---------------------------
 
@@ -468,12 +449,6 @@ Who:	Alok N Kataria <akataria@vmware.com
 
 ----------------------------
 
-What:	adt7473 hardware monitoring driver
-When:	February 2010
-Why:	Obsoleted by the adt7475 driver.
-Who:	Jean Delvare <khali@linux-fr.org>
-
----------------------------
 What:	Support for lcd_switch and display_get in asus-laptop driver
 When:	March 2010
 Why:	These two features use non-standard interfaces. There are the
@@ -542,3 +517,98 @@ Why:	Duplicate functionality with the gs
 	sensors) wich are also supported by the gspca_zc3xx driver
 	(which supports 53 USB-ID's in total)
 Who:	Hans de Goede <hdegoede@redhat.com>
+
+----------------------------
+
+What:	corgikbd, spitzkbd, tosakbd driver
+When:	2.6.35
+Files:	drivers/input/keyboard/{corgi,spitz,tosa}kbd.c
+Why:	We now have a generic GPIO based matrix keyboard driver that
+	are fully capable of handling all the keys on these devices.
+	The original drivers manipulate the GPIO registers directly
+	and so are difficult to maintain.
+Who:	Eric Miao <eric.y.miao@gmail.com>
+
+----------------------------
+
+What:	corgi_ssp and corgi_ts driver
+When:	2.6.35
+Files:	arch/arm/mach-pxa/corgi_ssp.c, drivers/input/touchscreen/corgi_ts.c
+Why:	The corgi touchscreen is now deprecated in favour of the generic
+	ads7846.c driver. The noise reduction technique used in corgi_ts.c,
+	that's to wait till vsync before ADC sampling, is also integrated into
+	ads7846 driver now. Provided that the original driver is not generic
+	and is difficult to maintain, it will be removed later.
+Who:	Eric Miao <eric.y.miao@gmail.com>
+
+----------------------------
+
+What:	capifs
+When:	February 2011
+Files:	drivers/isdn/capi/capifs.*
+Why:	udev fully replaces this special file system that only contains CAPI
+	NCCI TTY device nodes. User space (pppdcapiplugin) works without
+	noticing the difference.
+Who:	Jan Kiszka <jan.kiszka@web.de>
+
+----------------------------
+
+What:	KVM memory aliases support
+When:	July 2010
+Why:	Memory aliasing support is used for speeding up guest vga access
+	through the vga windows.
+
+	Modern userspace no longer uses this feature, so it's just bitrotted
+	code and can be removed with no impact.
+Who:	Avi Kivity <avi@redhat.com>
+
+----------------------------
+
+What:	KVM kernel-allocated memory slots
+When:	July 2010
+Why:	Since 2.6.25, kvm supports user-allocated memory slots, which are
+	much more flexible than kernel-allocated slots.  All current userspace
+	supports the newer interface and this code can be removed with no
+	impact.
+Who:	Avi Kivity <avi@redhat.com>
+
+----------------------------
+
+What:	KVM paravirt mmu host support
+When:	January 2011
+Why:	The paravirt mmu host support is slower than non-paravirt mmu, both
+	on newer and older hardware.  It is already not exposed to the guest,
+	and kept only for live migration purposes.
+Who:	Avi Kivity <avi@redhat.com>
+
+----------------------------
+
+What: 	"acpi=ht" boot option
+When:	2.6.35
+Why:	Useful in 2003, implementation is a hack.
+	Generally invoked by accident today.
+	Seen as doing more harm than good.
+Who:	Len Brown <len.brown@intel.com>
+
+----------------------------
+
+What:	video4linux /dev/vtx teletext API support
+When:	2.6.35
+Files:	drivers/media/video/saa5246a.c drivers/media/video/saa5249.c
+	include/linux/videotext.h
+Why:	The vtx device nodes have been superseded by vbi device nodes
+	for many years. No applications exist that use the vtx support.
+	Of the two i2c drivers that actually support this API the saa5249
+	has been impossible to use for a year now and no known hardware
+	that supports this device exists. The saa5246a is theoretically
+	supported by the old mxb boards, but it never actually worked.
+
+	In summary: there is no hardware that can use this API and there
+	are no applications actually implementing this API.
+
+	The vtx support still reserves minors 192-223 and we would really
+	like to reuse those for upcoming new functionality. In the unlikely
+	event that new hardware appears that wants to use the functionality
+	provided by the vtx API, then that functionality should be build
+	around the sliced VBI API instead.
+Who:	Hans Verkuil <hverkuil@xs4all.nl>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/filesystems/00-INDEX linux-libre-2.6.34-gnu1/Documentation/filesystems/00-INDEX
--- linux-libre-2.6.33-gnu1/Documentation/filesystems/00-INDEX	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/filesystems/00-INDEX	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,8 @@ befs.txt
 	- information about the BeOS filesystem for Linux.
 bfs.txt
 	- info for the SCO UnixWare Boot Filesystem (BFS).
+ceph.txt
+	- info for the Ceph Distributed File System
 cifs.txt
 	- description of the CIFS filesystem.
 coda.txt
@@ -32,6 +34,8 @@ dlmfs.txt
 	- info on the userspace interface to the OCFS2 DLM.
 dnotify.txt
 	- info about directory notification in Linux.
+dnotify_test.c
+	- example program for dnotify
 ecryptfs.txt
 	- docs on eCryptfs: stacked cryptographic filesystem for Linux.
 exofs.txt
@@ -62,6 +66,8 @@ jfs.txt
 	- info and mount options for the JFS filesystem.
 locks.txt
 	- info on file locking implementations, flock() vs. fcntl(), etc.
+logfs.txt
+	- info on the LogFS flash filesystem.
 mandatory-locking.txt
 	- info on the Linux implementation of Sys V mandatory file locking.
 ncpfs.txt
diff -druNp linux-libre-2.6.33-gnu1/Documentation/filesystems/9p.txt linux-libre-2.6.34-gnu1/Documentation/filesystems/9p.txt
--- linux-libre-2.6.33-gnu1/Documentation/filesystems/9p.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/filesystems/9p.txt	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,15 @@ For Plan 9 From User Space applications
 
 	mount -t 9p `namespace`/acme /mnt/9 -o trans=unix,uname=$USER
 
+For server running on QEMU host with virtio transport:
+
+	mount -t 9p -o trans=virtio <mount_tag> /mnt/9
+
+where mount_tag is the tag associated by the server to each of the exported
+mount points. Each 9P export is seen by the client as a virtio device with an
+associated "mount_tag" property. Available mount tags can be
+seen by reading /sys/bus/virtio/drivers/9pnet_virtio/virtio<n>/mount_tag files.
+
 OPTIONS
 =======
 
@@ -47,7 +56,7 @@ OPTIONS
 			fd   	- used passed file descriptors for connection
                                 (see rfdno and wfdno)
 			virtio	- connect to the next virtio channel available
-				(from lguest or KVM with trans_virtio module)
+				(from QEMU with trans_virtio module)
 			rdma	- connect to a specified RDMA channel
 
   uname=name	user name to attempt mount as on the remote server.  The
@@ -85,7 +94,12 @@ OPTIONS
 
   port=n	port to connect to on the remote server
 
-  noextend	force legacy mode (no 9p2000.u semantics)
+  noextend	force legacy mode (no 9p2000.u or 9p2000.L semantics)
+
+  version=name	Select 9P protocol version. Valid options are:
+			9p2000          - Legacy mode (same as noextend)
+			9p2000.u        - Use 9P2000.u protocol
+			9p2000.L        - Use 9P2000.L protocol
 
   dfltuid	attempt to mount as a particular uid
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/filesystems/ceph.txt linux-libre-2.6.34-gnu1/Documentation/filesystems/ceph.txt
--- linux-libre-2.6.33-gnu1/Documentation/filesystems/ceph.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/filesystems/ceph.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,140 @@
+Ceph Distributed File System
+============================
+
+Ceph is a distributed network file system designed to provide good
+performance, reliability, and scalability.
+
+Basic features include:
+
+ * POSIX semantics
+ * Seamless scaling from 1 to many thousands of nodes
+ * High availability and reliability.  No single point of failure.
+ * N-way replication of data across storage nodes
+ * Fast recovery from node failures
+ * Automatic rebalancing of data on node addition/removal
+ * Easy deployment: most FS components are userspace daemons
+
+Also,
+ * Flexible snapshots (on any directory)
+ * Recursive accounting (nested files, directories, bytes)
+
+In contrast to cluster filesystems like GFS, OCFS2, and GPFS that rely
+on symmetric access by all clients to shared block devices, Ceph
+separates data and metadata management into independent server
+clusters, similar to Lustre.  Unlike Lustre, however, metadata and
+storage nodes run entirely as user space daemons.  Storage nodes
+utilize btrfs to store data objects, leveraging its advanced features
+(checksumming, metadata replication, etc.).  File data is striped
+across storage nodes in large chunks to distribute workload and
+facilitate high throughputs.  When storage nodes fail, data is
+re-replicated in a distributed fashion by the storage nodes themselves
+(with some minimal coordination from a cluster monitor), making the
+system extremely efficient and scalable.
+
+Metadata servers effectively form a large, consistent, distributed
+in-memory cache above the file namespace that is extremely scalable,
+dynamically redistributes metadata in response to workload changes,
+and can tolerate arbitrary (well, non-Byzantine) node failures.  The
+metadata server takes a somewhat unconventional approach to metadata
+storage to significantly improve performance for common workloads.  In
+particular, inodes with only a single link are embedded in
+directories, allowing entire directories of dentries and inodes to be
+loaded into its cache with a single I/O operation.  The contents of
+extremely large directories can be fragmented and managed by
+independent metadata servers, allowing scalable concurrent access.
+
+The system offers automatic data rebalancing/migration when scaling
+from a small cluster of just a few nodes to many hundreds, without
+requiring an administrator carve the data set into static volumes or
+go through the tedious process of migrating data between servers.
+When the file system approaches full, new nodes can be easily added
+and things will "just work."
+
+Ceph includes flexible snapshot mechanism that allows a user to create
+a snapshot on any subdirectory (and its nested contents) in the
+system.  Snapshot creation and deletion are as simple as 'mkdir
+.snap/foo' and 'rmdir .snap/foo'.
+
+Ceph also provides some recursive accounting on directories for nested
+files and bytes.  That is, a 'getfattr -d foo' on any directory in the
+system will reveal the total number of nested regular files and
+subdirectories, and a summation of all nested file sizes.  This makes
+the identification of large disk space consumers relatively quick, as
+no 'du' or similar recursive scan of the file system is required.
+
+
+Mount Syntax
+============
+
+The basic mount syntax is:
+
+ # mount -t ceph monip[:port][,monip2[:port]...]:/[subdir] mnt
+
+You only need to specify a single monitor, as the client will get the
+full list when it connects.  (However, if the monitor you specify
+happens to be down, the mount won't succeed.)  The port can be left
+off if the monitor is using the default.  So if the monitor is at
+1.2.3.4,
+
+ # mount -t ceph 1.2.3.4:/ /mnt/ceph
+
+is sufficient.  If /sbin/mount.ceph is installed, a hostname can be
+used instead of an IP address.
+
+
+
+Mount Options
+=============
+
+  ip=A.B.C.D[:N]
+	Specify the IP and/or port the client should bind to locally.
+	There is normally not much reason to do this.  If the IP is not
+	specified, the client's IP address is determined by looking at the
+	address it's connection to the monitor originates from.
+
+  wsize=X
+	Specify the maximum write size in bytes.  By default there is no
+	maximum.  Ceph will normally size writes based on the file stripe
+	size.
+
+  rsize=X
+	Specify the maximum readahead.
+
+  mount_timeout=X
+	Specify the timeout value for mount (in seconds), in the case
+	of a non-responsive Ceph file system.  The default is 30
+	seconds.
+
+  rbytes
+	When stat() is called on a directory, set st_size to 'rbytes',
+	the summation of file sizes over all files nested beneath that
+	directory.  This is the default.
+
+  norbytes
+	When stat() is called on a directory, set st_size to the
+	number of entries in that directory.
+
+  nocrc
+	Disable CRC32C calculation for data writes.  If set, the storage node
+	must rely on TCP's error correction to detect data corruption
+	in the data payload.
+
+  noasyncreaddir
+	Disable client's use its local cache to satisfy	readdir
+	requests.  (This does not change correctness; the client uses
+	cached metadata only when a lease or capability ensures it is
+	valid.)
+
+
+More Information
+================
+
+For more information on Ceph, see the home page at
+	http://ceph.newdream.net/
+
+The Linux kernel client source tree is available at
+	git://ceph.newdream.net/git/ceph-client.git
+	git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git
+
+and the source for the full system is at
+	git://ceph.newdream.net/git/ceph.git
diff -druNp linux-libre-2.6.33-gnu1/Documentation/filesystems/dentry-locking.txt linux-libre-2.6.34-gnu1/Documentation/filesystems/dentry-locking.txt
--- linux-libre-2.6.33-gnu1/Documentation/filesystems/dentry-locking.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/filesystems/dentry-locking.txt	2010-05-16 17:17:36.000000000 -0400
@@ -62,7 +62,8 @@ changes are :
 2. Insertion of a dentry into the hash table is done using
    hlist_add_head_rcu() which take care of ordering the writes - the
    writes to the dentry must be visible before the dentry is
-   inserted. This works in conjunction with hlist_for_each_rcu() while
+   inserted. This works in conjunction with hlist_for_each_rcu(),
+   which has since been replaced by hlist_for_each_entry_rcu(), while
    walking the hash chain. The only requirement is that all
    initialization to the dentry must be done before
    hlist_add_head_rcu() since we don't have dcache_lock protection
diff -druNp linux-libre-2.6.33-gnu1/Documentation/filesystems/dnotify_test.c linux-libre-2.6.34-gnu1/Documentation/filesystems/dnotify_test.c
--- linux-libre-2.6.33-gnu1/Documentation/filesystems/dnotify_test.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/filesystems/dnotify_test.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,34 @@
+#define _GNU_SOURCE	/* needed to get the defines */
+#include <fcntl.h>	/* in glibc 2.2 this has the needed
+				   values defined */
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static volatile int event_fd;
+
+static void handler(int sig, siginfo_t *si, void *data)
+{
+	event_fd = si->si_fd;
+}
+
+int main(void)
+{
+	struct sigaction act;
+	int fd;
+
+	act.sa_sigaction = handler;
+	sigemptyset(&act.sa_mask);
+	act.sa_flags = SA_SIGINFO;
+	sigaction(SIGRTMIN + 1, &act, NULL);
+
+	fd = open(".", O_RDONLY);
+	fcntl(fd, F_SETSIG, SIGRTMIN + 1);
+	fcntl(fd, F_NOTIFY, DN_MODIFY|DN_CREATE|DN_MULTISHOT);
+	/* we will now be notified if any of the files
+	   in "." is modified or new files are created */
+	while (1) {
+		pause();
+		printf("Got event on fd=%d\n", event_fd);
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/Documentation/filesystems/dnotify.txt linux-libre-2.6.34-gnu1/Documentation/filesystems/dnotify.txt
--- linux-libre-2.6.33-gnu1/Documentation/filesystems/dnotify.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/filesystems/dnotify.txt	2010-05-16 17:17:36.000000000 -0400
@@ -62,38 +62,9 @@ disabled, fcntl(fd, F_NOTIFY, ...) will
 
 Example
 -------
+See Documentation/filesystems/dnotify_test.c for an example.
 
-	#define _GNU_SOURCE	/* needed to get the defines */
-	#include <fcntl.h>	/* in glibc 2.2 this has the needed
-					   values defined */
-	#include <signal.h>
-	#include <stdio.h>
-	#include <unistd.h>
-
-	static volatile int event_fd;
-
-	static void handler(int sig, siginfo_t *si, void *data)
-	{
-		event_fd = si->si_fd;
-	}
-
-	int main(void)
-	{
-		struct sigaction act;
-		int fd;
-
-		act.sa_sigaction = handler;
-		sigemptyset(&act.sa_mask);
-		act.sa_flags = SA_SIGINFO;
-		sigaction(SIGRTMIN + 1, &act, NULL);
-
-		fd = open(".", O_RDONLY);
-		fcntl(fd, F_SETSIG, SIGRTMIN + 1);
-		fcntl(fd, F_NOTIFY, DN_MODIFY|DN_CREATE|DN_MULTISHOT);
-		/* we will now be notified if any of the files
-		   in "." is modified or new files are created */
-		while (1) {
-			pause();
-			printf("Got event on fd=%d\n", event_fd);
-		}
-	}
+NOTE
+----
+Beginning with Linux 2.6.13, dnotify has been replaced by inotify.
+See Documentation/filesystems/inotify.txt for more information on it.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/filesystems/Locking linux-libre-2.6.34-gnu1/Documentation/filesystems/Locking
--- linux-libre-2.6.33-gnu1/Documentation/filesystems/Locking	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/filesystems/Locking	2010-05-16 17:17:36.000000000 -0400
@@ -460,13 +460,6 @@ in sys_read() and friends.
 
 --------------------------- dquot_operations -------------------------------
 prototypes:
-	int (*initialize) (struct inode *, int);
-	int (*drop) (struct inode *);
-	int (*alloc_space) (struct inode *, qsize_t, int);
-	int (*alloc_inode) (const struct inode *, unsigned long);
-	int (*free_space) (struct inode *, qsize_t);
-	int (*free_inode) (const struct inode *, unsigned long);
-	int (*transfer) (struct inode *, struct iattr *);
 	int (*write_dquot) (struct dquot *);
 	int (*acquire_dquot) (struct dquot *);
 	int (*release_dquot) (struct dquot *);
@@ -479,13 +472,6 @@ a proper locking wrt the filesystem and
 What filesystem should expect from the generic quota functions:
 
 		FS recursion	Held locks when called
-initialize:	yes		maybe dqonoff_sem
-drop:		yes		-
-alloc_space:	->mark_dirty()	-
-alloc_inode:	->mark_dirty()	-
-free_space:	->mark_dirty()	-
-free_inode:	->mark_dirty()	-
-transfer:	yes		-
 write_dquot:	yes		dqonoff_sem or dqptr_sem
 acquire_dquot:	yes		dqonoff_sem or dqptr_sem
 release_dquot:	yes		dqonoff_sem or dqptr_sem
@@ -495,10 +481,6 @@ write_info:	yes		dqonoff_sem
 FS recursion means calling ->quota_read() and ->quota_write() from superblock
 operations.
 
-->alloc_space(), ->alloc_inode(), ->free_space(), ->free_inode() are called
-only directly by the filesystem and do not call any fs functions only
-the ->mark_dirty() operation.
-
 More details about quota locking can be found in fs/dquot.c.
 
 --------------------------- vm_operations_struct -----------------------------
diff -druNp linux-libre-2.6.33-gnu1/Documentation/filesystems/logfs.txt linux-libre-2.6.34-gnu1/Documentation/filesystems/logfs.txt
--- linux-libre-2.6.33-gnu1/Documentation/filesystems/logfs.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/filesystems/logfs.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,241 @@
+
+The LogFS Flash Filesystem
+==========================
+
+Specification
+=============
+
+Superblocks
+-----------
+
+Two superblocks exist at the beginning and end of the filesystem.
+Each superblock is 256 Bytes large, with another 3840 Bytes reserved
+for future purposes, making a total of 4096 Bytes.
+
+Superblock locations may differ for MTD and block devices.  On MTD the
+first non-bad block contains a superblock in the first 4096 Bytes and
+the last non-bad block contains a superblock in the last 4096 Bytes.
+On block devices, the first 4096 Bytes of the device contain the first
+superblock and the last aligned 4096 Byte-block contains the second
+superblock.
+
+For the most part, the superblocks can be considered read-only.  They
+are written only to correct errors detected within the superblocks,
+move the journal and change the filesystem parameters through tunefs.
+As a result, the superblock does not contain any fields that require
+constant updates, like the amount of free space, etc.
+
+Segments
+--------
+
+The space in the device is split up into equal-sized segments.
+Segments are the primary write unit of LogFS.  Within each segments,
+writes happen from front (low addresses) to back (high addresses.  If
+only a partial segment has been written, the segment number, the
+current position within and optionally a write buffer are stored in
+the journal.
+
+Segments are erased as a whole.  Therefore Garbage Collection may be
+required to completely free a segment before doing so.
+
+Journal
+--------
+
+The journal contains all global information about the filesystem that
+is subject to frequent change.  At mount time, it has to be scanned
+for the most recent commit entry, which contains a list of pointers to
+all currently valid entries.
+
+Object Store
+------------
+
+All space except for the superblocks and journal is part of the object
+store.  Each segment contains a segment header and a number of
+objects, each consisting of the object header and the payload.
+Objects are either inodes, directory entries (dentries), file data
+blocks or indirect blocks.
+
+Levels
+------
+
+Garbage collection (GC) may fail if all data is written
+indiscriminately.  One requirement of GC is that data is seperated
+roughly according to the distance between the tree root and the data.
+Effectively that means all file data is on level 0, indirect blocks
+are on levels 1, 2, 3 4 or 5 for 1x, 2x, 3x, 4x or 5x indirect blocks,
+respectively.  Inode file data is on level 6 for the inodes and 7-11
+for indirect blocks.
+
+Each segment contains objects of a single level only.  As a result,
+each level requires its own seperate segment to be open for writing.
+
+Inode File
+----------
+
+All inodes are stored in a special file, the inode file.  Single
+exception is the inode file's inode (master inode) which for obvious
+reasons is stored in the journal instead.  Instead of data blocks, the
+leaf nodes of the inode files are inodes.
+
+Aliases
+-------
+
+Writes in LogFS are done by means of a wandering tree.  A naÃ¯ve
+implementation would require that for each write or a block, all
+parent blocks are written as well, since the block pointers have
+changed.  Such an implementation would not be very efficient.
+
+In LogFS, the block pointer changes are cached in the journal by means
+of alias entries.  Each alias consists of its logical address - inode
+number, block index, level and child number (index into block) - and
+the changed data.  Any 8-byte word can be changes in this manner.
+
+Currently aliases are used for block pointers, file size, file used
+bytes and the height of an inodes indirect tree.
+
+Segment Aliases
+---------------
+
+Related to regular aliases, these are used to handle bad blocks.
+Initially, bad blocks are handled by moving the affected segment
+content to a spare segment and noting this move in the journal with a
+segment alias, a simple (to, from) tupel.  GC will later empty this
+segment and the alias can be removed again.  This is used on MTD only.
+
+Vim
+---
+
+By cleverly predicting the life time of data, it is possible to
+seperate long-living data from short-living data and thereby reduce
+the GC overhead later.  Each type of distinc life expectency (vim) can
+have a seperate segment open for writing.  Each (level, vim) tupel can
+be open just once.  If an open segment with unknown vim is encountered
+at mount time, it is closed and ignored henceforth.
+
+Indirect Tree
+-------------
+
+Inodes in LogFS are similar to FFS-style filesystems with direct and
+indirect block pointers.  One difference is that LogFS uses a single
+indirect pointer that can be either a 1x, 2x, etc. indirect pointer.
+A height field in the inode defines the height of the indirect tree
+and thereby the indirection of the pointer.
+
+Another difference is the addressing of indirect blocks.  In LogFS,
+the first 16 pointers in the first indirect block are left empty,
+corresponding to the 16 direct pointers in the inode.  In ext2 (maybe
+others as well) the first pointer in the first indirect block
+corresponds to logical block 12, skipping the 12 direct pointers.
+So where ext2 is using arithmetic to better utilize space, LogFS keeps
+arithmetic simple and uses compression to save space.
+
+Compression
+-----------
+
+Both file data and metadata can be compressed.  Compression for file
+data can be enabled with chattr +c and disabled with chattr -c.  Doing
+so has no effect on existing data, but new data will be stored
+accordingly.  New inodes will inherit the compression flag of the
+parent directory.
+
+Metadata is always compressed.  However, the space accounting ignores
+this and charges for the uncompressed size.  Failing to do so could
+result in GC failures when, after moving some data, indirect blocks
+compress worse than previously.  Even on a 100% full medium, GC may
+not consume any extra space, so the compression gains are lost space
+to the user.
+
+However, they are not lost space to the filesystem internals.  By
+cheating the user for those bytes, the filesystem gained some slack
+space and GC will run less often and faster.
+
+Garbage Collection and Wear Leveling
+------------------------------------
+
+Garbage collection is invoked whenever the number of free segments
+falls below a threshold.  The best (known) candidate is picked based
+on the least amount of valid data contained in the segment.  All
+remaining valid data is copied elsewhere, thereby invalidating it.
+
+The GC code also checks for aliases and writes then back if their
+number gets too large.
+
+Wear leveling is done by occasionally picking a suboptimal segment for
+garbage collection.  If a stale segments erase count is significantly
+lower than the active segments' erase counts, it will be picked.  Wear
+leveling is rate limited, so it will never monopolize the device for
+more than one segment worth at a time.
+
+Values for "occasionally", "significantly lower" are compile time
+constants.
+
+Hashed directories
+------------------
+
+To satisfy efficient lookup(), directory entries are hashed and
+located based on the hash.  In order to both support large directories
+and not be overly inefficient for small directories, several hash
+tables of increasing size are used.  For each table, the hash value
+modulo the table size gives the table index.
+
+Tables sizes are chosen to limit the number of indirect blocks with a
+fully populated table to 0, 1, 2 or 3 respectively.  So the first
+table contains 16 entries, the second 512-16, etc.
+
+The last table is special in several ways.  First its size depends on
+the effective 32bit limit on telldir/seekdir cookies.  Since logfs
+uses the upper half of the address space for indirect blocks, the size
+is limited to 2^31.  Secondly the table contains hash buckets with 16
+entries each.
+
+Using single-entry buckets would result in birthday "attacks".  At
+just 2^16 used entries, hash collisions would be likely (P >= 0.5).
+My math skills are insufficient to do the combinatorics for the 17x
+collisions necessary to overflow a bucket, but testing showed that in
+10,000 runs the lowest directory fill before a bucket overflow was
+188,057,130 entries with an average of 315,149,915 entries.  So for
+directory sizes of up to a million, bucket overflows should be
+virtually impossible under normal circumstances.
+
+With carefully chosen filenames, it is obviously possible to cause an
+overflow with just 21 entries (4 higher tables + 16 entries + 1).  So
+there may be a security concern if a malicious user has write access
+to a directory.
+
+Open For Discussion
+===================
+
+Device Address Space
+--------------------
+
+A device address space is used for caching.  Both block devices and
+MTD provide functions to either read a single page or write a segment.
+Partial segments may be written for data integrity, but where possible
+complete segments are written for performance on simple block device
+flash media.
+
+Meta Inodes
+-----------
+
+Inodes are stored in the inode file, which is just a regular file for
+most purposes.  At umount time, however, the inode file needs to
+remain open until all dirty inodes are written.  So
+generic_shutdown_super() may not close this inode, but shouldn't
+complain about remaining inodes due to the inode file either.  Same
+goes for mapping inode of the device address space.
+
+Currently logfs uses a hack that essentially copies part of fs/inode.c
+code over.  A general solution would be preferred.
+
+Indirect block mapping
+----------------------
+
+With compression, the block device (or mapping inode) cannot be used
+to cache indirect blocks.  Some other place is required.  Currently
+logfs uses the top half of each inode's address space.  The low 8TB
+(on 32bit) are filled with file data, the high 8TB are used for
+indirect blocks.
+
+One problem is that 16TB files created on 64bit systems actually have
+data in the top 8TB.  But files >16TB would cause problems anyway, so
+only the limit has changed.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/filesystems/Makefile linux-libre-2.6.34-gnu1/Documentation/filesystems/Makefile
--- linux-libre-2.6.33-gnu1/Documentation/filesystems/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/filesystems/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,8 @@
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+obj- := dummy.o
+
+# List of programs to build
+hostprogs-y := dnotify_test
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
diff -druNp linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/nfs41-server.txt linux-libre-2.6.34-gnu1/Documentation/filesystems/nfs/nfs41-server.txt
--- linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/nfs41-server.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/filesystems/nfs/nfs41-server.txt	2010-05-16 17:17:36.000000000 -0400
@@ -17,8 +17,7 @@ kernels must turn 4.1 on or off *before*
 on or off; rpc.nfsd does this correctly.)
 
 The NFSv4 minorversion 1 (NFSv4.1) implementation in nfsd is based
-on the latest NFSv4.1 Internet Draft:
-http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-29
+on RFC 5661.
 
 From the many new features in NFSv4.1 the current implementation
 focuses on the mandatory-to-implement NFSv4.1 Sessions, providing
@@ -44,7 +43,7 @@ interoperability problems with future cl
 	  trunking, but this is a mandatory feature, and its use is
 	  recommended to clients in a number of places.  (E.g. to ensure
 	  timely renewal in case an existing connection's retry timeouts
-	  have gotten too long; see section 8.3 of the draft.)
+	  have gotten too long; see section 8.3 of the RFC.)
 	  Therefore, lack of this feature may cause future clients to
 	  fail.
 	- Incomplete backchannel support: incomplete backchannel gss
diff -druNp linux-libre-2.6.33-gnu1/Documentation/filesystems/nilfs2.txt linux-libre-2.6.34-gnu1/Documentation/filesystems/nilfs2.txt
--- linux-libre-2.6.33-gnu1/Documentation/filesystems/nilfs2.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/filesystems/nilfs2.txt	2010-05-16 17:17:36.000000000 -0400
@@ -74,6 +74,9 @@ norecovery		Disable recovery of the file
 			This disables every write access on the device for
 			read-only mounts or snapshots.  This option will fail
 			for r/w mounts on an unclean volume.
+discard			Issue discard/TRIM commands to the underlying block
+			device when blocks are freed.  This is useful for SSD
+			devices and sparse/thinly-provisioned LUNs.
 
 NILFS2 usage
 ============
diff -druNp linux-libre-2.6.33-gnu1/Documentation/filesystems/proc.txt linux-libre-2.6.34-gnu1/Documentation/filesystems/proc.txt
--- linux-libre-2.6.33-gnu1/Documentation/filesystems/proc.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/filesystems/proc.txt	2010-05-16 17:17:36.000000000 -0400
@@ -164,6 +164,7 @@ read the file /proc/PID/status:
   VmExe:        68 kB
   VmLib:      1412 kB
   VmPTE:        20 kb
+  VmSwap:        0 kB
   Threads:        1
   SigQ:   0/28578
   SigPnd: 0000000000000000
@@ -188,7 +189,13 @@ memory usage. Its seven fields are expla
 contains details information about the process itself.  Its fields are
 explained in Table 1-4.
 
-Table 1-2: Contents of the statm files (as of 2.6.30-rc7)
+(for SMP CONFIG users)
+For making accounting scalable, RSS related information are handled in
+asynchronous manner and the vaule may not be very precise. To see a precise
+snapshot of a moment, you can see /proc/<pid>/smaps file and scan page table.
+It's slow but very precise.
+
+Table 1-2: Contents of the status files (as of 2.6.30-rc7)
 ..............................................................................
  Field                       Content
  Name                        filename of the executable
@@ -213,6 +220,7 @@ Table 1-2: Contents of the statm files (
  VmExe                       size of text segment
  VmLib                       size of shared library code
  VmPTE                       size of page table entries
+ VmSwap                      size of swap usage (the number of referred swapents)
  Threads                     number of threads
  SigQ                        number of signals queued/max. number for queue
  SigPnd                      bitmap of pending signals for the thread
@@ -308,7 +316,7 @@ address           perms offset  dev   in
 08049000-0804a000 rw-p 00001000 03:00 8312       /opt/test
 0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
 a7cb1000-a7cb2000 ---p 00000000 00:00 0
-a7cb2000-a7eb2000 rw-p 00000000 00:00 0          [threadstack:001ff4b4]
+a7cb2000-a7eb2000 rw-p 00000000 00:00 0
 a7eb2000-a7eb3000 ---p 00000000 00:00 0
 a7eb3000-a7ed5000 rw-p 00000000 00:00 0
 a7ed5000-a8008000 r-xp 00000000 03:00 4222       /lib/libc.so.6
@@ -344,7 +352,6 @@ is not associated with a file:
  [stack]                  = the stack of the main process
  [vdso]                   = the "virtual dynamic shared object",
                             the kernel system call handler
- [threadstack:xxxxxxxx]   = the stack of the thread, xxxxxxxx is the stack size
 
  or if empty, the mapping is anonymous.
 
@@ -430,6 +437,7 @@ Table 1-5: Kernel info in /proc
  modules     List of loaded modules                            
  mounts      Mounted filesystems                               
  net         Networking info (see text)                        
+ pagetypeinfo Additional page allocator information (see text)  (2.5)
  partitions  Table of partitions known to the system           
  pci	     Deprecated info of PCI bus (new way -> /proc/bus/pci/,
              decoupled by lspci					(2.4)
@@ -584,7 +592,7 @@ Node 0, zone      DMA      0      4
 Node 0, zone   Normal      1      0      0      1    101      8 ...
 Node 0, zone  HighMem      2      0      0      1      1      0 ...
 
-Memory fragmentation is a problem under some workloads, and buddyinfo is a 
+External fragmentation is a problem under some workloads, and buddyinfo is a
 useful tool for helping diagnose these problems.  Buddyinfo will give you a 
 clue as to how big an area you can safely allocate, or why a previous
 allocation failed.
@@ -594,6 +602,48 @@ available.  In this case, there are 0 ch
 ZONE_DMA, 4 chunks of 2^1*PAGE_SIZE in ZONE_DMA, 101 chunks of 2^4*PAGE_SIZE 
 available in ZONE_NORMAL, etc... 
 
+More information relevant to external fragmentation can be found in
+pagetypeinfo.
+
+> cat /proc/pagetypeinfo
+Page block order: 9
+Pages per block:  512
+
+Free pages count per migrate type at order       0      1      2      3      4      5      6      7      8      9     10
+Node    0, zone      DMA, type    Unmovable      0      0      0      1      1      1      1      1      1      1      0
+Node    0, zone      DMA, type  Reclaimable      0      0      0      0      0      0      0      0      0      0      0
+Node    0, zone      DMA, type      Movable      1      1      2      1      2      1      1      0      1      0      2
+Node    0, zone      DMA, type      Reserve      0      0      0      0      0      0      0      0      0      1      0
+Node    0, zone      DMA, type      Isolate      0      0      0      0      0      0      0      0      0      0      0
+Node    0, zone    DMA32, type    Unmovable    103     54     77      1      1      1     11      8      7      1      9
+Node    0, zone    DMA32, type  Reclaimable      0      0      2      1      0      0      0      0      1      0      0
+Node    0, zone    DMA32, type      Movable    169    152    113     91     77     54     39     13      6      1    452
+Node    0, zone    DMA32, type      Reserve      1      2      2      2      2      0      1      1      1      1      0
+Node    0, zone    DMA32, type      Isolate      0      0      0      0      0      0      0      0      0      0      0
+
+Number of blocks type     Unmovable  Reclaimable      Movable      Reserve      Isolate
+Node 0, zone      DMA            2            0            5            1            0
+Node 0, zone    DMA32           41            6          967            2            0
+
+Fragmentation avoidance in the kernel works by grouping pages of different
+migrate types into the same contiguous regions of memory called page blocks.
+A page block is typically the size of the default hugepage size e.g. 2MB on
+X86-64. By keeping pages grouped based on their ability to move, the kernel
+can reclaim pages within a page block to satisfy a high-order allocation.
+
+The pagetypinfo begins with information on the size of a page block. It
+then gives the same type of information as buddyinfo except broken down
+by migrate-type and finishes with details on how many page blocks of each
+type exist.
+
+If min_free_kbytes has been tuned correctly (recommendations made by hugeadm
+from libhugetlbfs http://sourceforge.net/projects/libhugetlbfs/), one can
+make an estimate of the likely number of huge pages that can be allocated
+at a given point in time. All the "Movable" blocks should be allocatable
+unless memory has been mlock()'d. Some of the Reclaimable blocks should
+also be allocatable although a lot of filesystem metadata may have to be
+reclaimed to achieve this.
+
 ..............................................................................
 
 meminfo:
diff -druNp linux-libre-2.6.33-gnu1/Documentation/filesystems/sharedsubtree.txt linux-libre-2.6.34-gnu1/Documentation/filesystems/sharedsubtree.txt
--- linux-libre-2.6.33-gnu1/Documentation/filesystems/sharedsubtree.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/filesystems/sharedsubtree.txt	2010-05-16 17:17:36.000000000 -0400
@@ -837,6 +837,9 @@ replicas continue to be exactly same.
 	 individual lists does not affect propagation or the way propagation
 	 tree is modified by operations.
 
+	All vfsmounts in a peer group have the same ->mnt_master.  If it is
+	non-NULL, they form a contiguous (ordered) segment of slave list.
+
 	A example propagation tree looks as shown in the figure below.
 	[ NOTE: Though it looks like a forest, if we consider all the shared
 	mounts as a conceptual entity called 'pnode', it becomes a tree]
@@ -874,8 +877,19 @@ replicas continue to be exactly same.
 
 	NOTE: The propagation tree is orthogonal to the mount tree.
 
+8B Locking:
+
+	->mnt_share, ->mnt_slave, ->mnt_slave_list, ->mnt_master are protected
+	by namespace_sem (exclusive for modifications, shared for reading).
 
-8B Algorithm:
+	Normally we have ->mnt_flags modifications serialized by vfsmount_lock.
+	There are two exceptions: do_add_mount() and clone_mnt().
+	The former modifies a vfsmount that has not been visible in any shared
+	data structures yet.
+	The latter holds namespace_sem and the only references to vfsmount
+	are in lists that can't be traversed without namespace_sem.
+
+8C Algorithm:
 
 	The crux of the implementation resides in rbind/move operation.
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/filesystems/tmpfs.txt linux-libre-2.6.34-gnu1/Documentation/filesystems/tmpfs.txt
--- linux-libre-2.6.33-gnu1/Documentation/filesystems/tmpfs.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/filesystems/tmpfs.txt	2010-05-16 17:17:36.000000000 -0400
@@ -82,11 +82,13 @@ tmpfs has a mount option to set the NUMA
 all files in that instance (if CONFIG_NUMA is enabled) - which can be
 adjusted on the fly via 'mount -o remount ...'
 
-mpol=default             prefers to allocate memory from the local node
+mpol=default             use the process allocation policy
+                         (see set_mempolicy(2))
 mpol=prefer:Node         prefers to allocate memory from the given Node
 mpol=bind:NodeList       allocates memory only from nodes in NodeList
 mpol=interleave          prefers to allocate from each node in turn
 mpol=interleave:NodeList allocates from each node of NodeList in turn
+mpol=local		 prefers to allocate memory from the local node
 
 NodeList format is a comma-separated list of decimal numbers and ranges,
 a range being two hyphen-separated decimal numbers, the smallest and
@@ -134,3 +136,5 @@ Author:
    Christoph Rohland <cr@sap.com>, 1.12.01
 Updated:
    Hugh Dickins, 4 June 2007
+Updated:
+   KOSAKI Motohiro, 16 Mar 2010
diff -druNp linux-libre-2.6.33-gnu1/Documentation/gpio.txt linux-libre-2.6.34-gnu1/Documentation/gpio.txt
--- linux-libre-2.6.33-gnu1/Documentation/gpio.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/gpio.txt	2010-05-16 17:17:36.000000000 -0400
@@ -253,6 +253,70 @@ pin setup (e.g. controlling which pin th
 Also note that it's your responsibility to have stopped using a GPIO
 before you free it.
 
+Considering in most cases GPIOs are actually configured right after they
+are claimed, three additional calls are defined:
+
+	/* request a single GPIO, with initial configuration specified by
+	 * 'flags', identical to gpio_request() wrt other arguments and
+	 * return value
+	 */
+	int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
+
+	/* request multiple GPIOs in a single call
+	 */
+	int gpio_request_array(struct gpio *array, size_t num);
+
+	/* release multiple GPIOs in a single call
+	 */
+	void gpio_free_array(struct gpio *array, size_t num);
+
+where 'flags' is currently defined to specify the following properties:
+
+	* GPIOF_DIR_IN		- to configure direction as input
+	* GPIOF_DIR_OUT		- to configure direction as output
+
+	* GPIOF_INIT_LOW	- as output, set initial level to LOW
+	* GPIOF_INIT_HIGH	- as output, set initial level to HIGH
+
+since GPIOF_INIT_* are only valid when configured as output, so group valid
+combinations as:
+
+	* GPIOF_IN		- configure as input
+	* GPIOF_OUT_INIT_LOW	- configured as output, initial level LOW
+	* GPIOF_OUT_INIT_HIGH	- configured as output, initial level HIGH
+
+In the future, these flags can be extended to support more properties such
+as open-drain status.
+
+Further more, to ease the claim/release of multiple GPIOs, 'struct gpio' is
+introduced to encapsulate all three fields as:
+
+	struct gpio {
+		unsigned	gpio;
+		unsigned long	flags;
+		const char	*label;
+	};
+
+A typical example of usage:
+
+	static struct gpio leds_gpios[] = {
+		{ 32, GPIOF_OUT_INIT_HIGH, "Power LED" }, /* default to ON */
+		{ 33, GPIOF_OUT_INIT_LOW,  "Green LED" }, /* default to OFF */
+		{ 34, GPIOF_OUT_INIT_LOW,  "Red LED"   }, /* default to OFF */
+		{ 35, GPIOF_OUT_INIT_LOW,  "Blue LED"  }, /* default to OFF */
+		{ ... },
+	};
+
+	err = gpio_request_one(31, GPIOF_IN, "Reset Button");
+	if (err)
+		...
+
+	err = gpio_request_array(leds_gpios, ARRAY_SIZE(leds_gpios));
+	if (err)
+		...
+
+	gpio_free_array(leds_gpios, ARRAY_SIZE(leds_gpios));
+
 
 GPIOs mapped to IRQs
 --------------------
diff -druNp linux-libre-2.6.33-gnu1/Documentation/HOWTO linux-libre-2.6.34-gnu1/Documentation/HOWTO
--- linux-libre-2.6.33-gnu1/Documentation/HOWTO	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/HOWTO	2010-05-16 17:17:36.000000000 -0400
@@ -221,8 +221,8 @@ branches.  These different branches are:
   - main 2.6.x kernel tree
   - 2.6.x.y -stable kernel tree
   - 2.6.x -git kernel patches
-  - 2.6.x -mm kernel patches
   - subsystem specific kernel trees and patches
+  - the 2.6.x -next kernel tree for integration tests
 
 2.6.x kernel tree
 -----------------
@@ -232,9 +232,9 @@ process is as follows:
   - As soon as a new kernel is released a two weeks window is open,
     during this period of time maintainers can submit big diffs to
     Linus, usually the patches that have already been included in the
-    -mm kernel for a few weeks.  The preferred way to submit big changes
+    -next kernel for a few weeks.  The preferred way to submit big changes
     is using git (the kernel's source management tool, more information
-    can be found at http://git.or.cz/) but plain patches are also just
+    can be found at http://git-scm.com/) but plain patches are also just
     fine.
   - After two weeks a -rc1 kernel is released it is now possible to push
     only patches that do not include new features that could affect the
@@ -293,84 +293,43 @@ daily and represent the current state of
 experimental than -rc kernels since they are generated automatically
 without even a cursory glance to see if they are sane.
 
-2.6.x -mm kernel patches
-------------------------
-These are experimental kernel patches released by Andrew Morton.  Andrew
-takes all of the different subsystem kernel trees and patches and mushes
-them together, along with a lot of patches that have been plucked from
-the linux-kernel mailing list.  This tree serves as a proving ground for
-new features and patches.  Once a patch has proved its worth in -mm for
-a while Andrew or the subsystem maintainer pushes it on to Linus for
-inclusion in mainline.
-
-It is heavily encouraged that all new patches get tested in the -mm tree
-before they are sent to Linus for inclusion in the main kernel tree.  Code
-which does not make an appearance in -mm before the opening of the merge
-window will prove hard to merge into the mainline.
-
-These kernels are not appropriate for use on systems that are supposed
-to be stable and they are more risky to run than any of the other
-branches.
-
-If you wish to help out with the kernel development process, please test
-and use these kernel releases and provide feedback to the linux-kernel
-mailing list if you have any problems, and if everything works properly.
-
-In addition to all the other experimental patches, these kernels usually
-also contain any changes in the mainline -git kernels available at the
-time of release.
-
-The -mm kernels are not released on a fixed schedule, but usually a few
--mm kernels are released in between each -rc kernel (1 to 3 is common).
-
 Subsystem Specific kernel trees and patches
 -------------------------------------------
-A number of the different kernel subsystem developers expose their
-development trees so that others can see what is happening in the
-different areas of the kernel.  These trees are pulled into the -mm
-kernel releases as described above.
-
-Here is a list of some of the different kernel trees available:
-  git trees:
-    - Kbuild development tree, Sam Ravnborg <sam@ravnborg.org>
-	git.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
-
-    - ACPI development tree, Len Brown <len.brown@intel.com>
-	git.kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
-
-    - Block development tree, Jens Axboe <jens.axboe@oracle.com>
-	git.kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
-
-    - DRM development tree, Dave Airlie <airlied@linux.ie>
-	git.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git
-
-    - ia64 development tree, Tony Luck <tony.luck@intel.com>
-	git.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
-
-    - infiniband, Roland Dreier <rolandd@cisco.com>
-	git.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git
-
-    - libata, Jeff Garzik <jgarzik@pobox.com>
-	git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
-
-    - network drivers, Jeff Garzik <jgarzik@pobox.com>
-	git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
+The maintainers of the various kernel subsystems --- and also many
+kernel subsystem developers --- expose their current state of
+development in source repositories.  That way, others can see what is
+happening in the different areas of the kernel.  In areas where
+development is rapid, a developer may be asked to base his submissions
+onto such a subsystem kernel tree so that conflicts between the
+submission and other already ongoing work are avoided.
 
-    - pcmcia, Dominik Brodowski <linux@dominikbrodowski.net>
-	git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
+Most of these repositories are git trees, but there are also other SCMs
+in use, or patch queues being published as quilt series.  Addresses of
+these subsystem repositories are listed in the MAINTAINERS file.  Many
+of them can be browsed at http://git.kernel.org/.
 
-    - SCSI, James Bottomley <James.Bottomley@hansenpartnership.com>
-	git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
+Before a proposed patch is committed to such a subsystem tree, it is
+subject to review which primarily happens on mailing lists (see the
+respective section below).  For several kernel subsystems, this review
+process is tracked with the tool patchwork.  Patchwork offers a web
+interface which shows patch postings, any comments on a patch or
+revisions to it, and maintainers can mark patches as under review,
+accepted, or rejected.  Most of these patchwork sites are listed at
+http://patchwork.kernel.org/ or http://patchwork.ozlabs.org/.
 
-    - x86, Ingo Molnar <mingo@elte.hu>
-	git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
+2.6.x -next kernel tree for integration tests
+---------------------------------------------
+Before updates from subsystem trees are merged into the mainline 2.6.x
+tree, they need to be integration-tested.  For this purpose, a special
+testing repository exists into which virtually all subsystem trees are
+pulled on an almost daily basis:
+	http://git.kernel.org/?p=linux/kernel/git/sfr/linux-next.git
+	http://linux.f-seidel.de/linux-next/pmwiki/
 
-  quilt trees:
-    - USB, Driver Core, and I2C, Greg Kroah-Hartman <gregkh@suse.de>
-	kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
+This way, the -next kernel gives a summary outlook onto what will be
+expected to go into the mainline kernel at the next merge period.
+Adventurous testers are very welcome to runtime-test the -next kernel.
 
-  Other kernel trees can be found listed at http://git.kernel.org/ and in
-  the MAINTAINERS file.
 
 Bug Reporting
 -------------
diff -druNp linux-libre-2.6.33-gnu1/Documentation/hwmon/abituguru linux-libre-2.6.34-gnu1/Documentation/hwmon/abituguru
--- linux-libre-2.6.33-gnu1/Documentation/hwmon/abituguru	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/hwmon/abituguru	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,7 @@ Supported chips:
 	   bank1_types=1,1,0,0,0,0,0,2,0,0,0,0,2,0,0,1
 	   You may also need to specify the fan_sensors option for these boards
 	   fan_sensors=5
-	2) There is a seperate abituguru3 driver for these motherboards,
+	2) There is a separate abituguru3 driver for these motherboards,
 	   the abituguru (without the 3 !) driver will not work on these
 	   motherboards (and visa versa)!
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/hwmon/adt7411 linux-libre-2.6.34-gnu1/Documentation/hwmon/adt7411
--- linux-libre-2.6.33-gnu1/Documentation/hwmon/adt7411	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/hwmon/adt7411	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,42 @@
+Kernel driver adt7411
+=====================
+
+Supported chips:
+  * Analog Devices ADT7411
+    Prefix: 'adt7411'
+    Addresses scanned: 0x48, 0x4a, 0x4b
+    Datasheet: Publicly available at the Analog Devices website
+
+Author: Wolfram Sang (based on adt7470 by Darrick J. Wong)
+
+Description
+-----------
+
+This driver implements support for the Analog Devices ADT7411 chip. There may
+be other chips that implement this interface.
+
+The ADT7411 can use an I2C/SMBus compatible 2-wire interface or an
+SPI-compatible 4-wire interface. It provides a 10-bit analog to digital
+converter which measures 1 temperature, vdd and 8 input voltages. It has an
+internal temperature sensor, but an external one can also be connected (one
+loses 2 inputs then). There are high- and low-limit registers for all inputs.
+
+Check the datasheet for details.
+
+sysfs-Interface
+---------------
+
+in0_input	- vdd voltage input
+in[1-8]_input	- analog 1-8 input
+temp1_input	- temperature input
+
+Besides standard interfaces, this driver adds (0 = off, 1 = on):
+
+  adc_ref_vdd	- Use vdd as reference instead of 2.25 V
+  fast_sampling	- Sample at 22.5 kHz instead of 1.4 kHz, but drop filters
+  no_average	- Turn off averaging over 16 samples
+
+Notes
+-----
+
+SPI, external temperature sensor and limit registers are not supported yet.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/hwmon/adt7473 linux-libre-2.6.34-gnu1/Documentation/hwmon/adt7473
--- linux-libre-2.6.33-gnu1/Documentation/hwmon/adt7473	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/hwmon/adt7473	1969-12-31 19:00:00.000000000 -0500
@@ -1,74 +0,0 @@
-Kernel driver adt7473
-======================
-
-Supported chips:
-  * Analog Devices ADT7473
-    Prefix: 'adt7473'
-    Addresses scanned: I2C 0x2C, 0x2D, 0x2E
-    Datasheet: Publicly available at the Analog Devices website
-
-Author: Darrick J. Wong
-
-This driver is depreacted, please use the adt7475 driver instead.
-
-Description
------------
-
-This driver implements support for the Analog Devices ADT7473 chip family.
-
-The ADT7473 uses the 2-wire interface compatible with the SMBUS 2.0
-specification. Using an analog to digital converter it measures three (3)
-temperatures and two (2) voltages. It has four (4) 16-bit counters for
-measuring fan speed. There are three (3) PWM outputs that can be used
-to control fan speed.
-
-A sophisticated control system for the PWM outputs is designed into the
-ADT7473 that allows fan speed to be adjusted automatically based on any of the
-three temperature sensors. Each PWM output is individually adjustable and
-programmable. Once configured, the ADT7473 will adjust the PWM outputs in
-response to the measured temperatures without further host intervention.
-This feature can also be disabled for manual control of the PWM's.
-
-Each of the measured inputs (voltage, temperature, fan speed) has
-corresponding high/low limit values. The ADT7473 will signal an ALARM if
-any measured value exceeds either limit.
-
-The ADT7473 samples all inputs continuously. The driver will not read
-the registers more often than once every other second. Further,
-configuration data is only read once per minute.
-
-Special Features
-----------------
-
-The ADT7473 have a 10-bit ADC and can therefore measure temperatures
-with 0.25 degC resolution. Temperature readings can be configured either
-for twos complement format or "Offset 64" format, wherein 63 is subtracted
-from the raw value to get the temperature value.
-
-The Analog Devices datasheet is very detailed and describes a procedure for
-determining an optimal configuration for the automatic PWM control.
-
-Configuration Notes
--------------------
-
-Besides standard interfaces driver adds the following:
-
-* PWM Control
-
-* pwm#_auto_point1_pwm and temp#_auto_point1_temp and
-* pwm#_auto_point2_pwm and temp#_auto_point2_temp -
-
-point1: Set the pwm speed at a lower temperature bound.
-point2: Set the pwm speed at a higher temperature bound.
-
-The ADT7473 will scale the pwm between the lower and higher pwm speed when
-the temperature is between the two temperature boundaries.  PWM values range
-from 0 (off) to 255 (full speed).  Fan speed will be set to maximum when the
-temperature sensor associated with the PWM control exceeds temp#_max.
-
-Notes
------
-
-The NVIDIA binary driver presents an ADT7473 chip via an on-card i2c bus.
-Unfortunately, they fail to set the i2c adapter class, so this driver may
-fail to find the chip until the nvidia driver is patched.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/hwmon/asc7621 linux-libre-2.6.34-gnu1/Documentation/hwmon/asc7621
--- linux-libre-2.6.33-gnu1/Documentation/hwmon/asc7621	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/hwmon/asc7621	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,296 @@
+Kernel driver asc7621
+==================
+
+Supported chips:
+    Andigilog aSC7621 and aSC7621a
+    Prefix: 'asc7621'
+    Addresses scanned: I2C 0x2c, 0x2d, 0x2e
+    Datasheet: http://www.fairview5.com/linux/asc7621/asc7621.pdf
+
+Author:
+		George Joseph
+
+Description provided by Dave Pivin @ Andigilog:
+
+Andigilog has both the PECI and pre-PECI versions of the Heceta-6, as
+Intel calls them. Heceta-6e has high frequency PWM and Heceta-6p has
+added PECI and a 4th thermal zone. The Andigilog aSC7611 is the
+Heceta-6e part and aSC7621 is the Heceta-6p part. They are both in
+volume production, shipping to Intel and their subs.
+
+We have enhanced both parts relative to the governing Intel
+specification. First enhancement is temperature reading resolution. We
+have used registers below 20h for vendor-specific functions in addition
+to those in the Intel-specified vendor range.
+
+Our conversion process produces a result that is reported as two bytes.
+The fan speed control uses this finer value to produce a "step-less" fan
+PWM output. These two bytes are "read-locked" to guarantee that once a
+high or low byte is read, the other byte is locked-in until after the
+next read of any register. So to get an atomic reading, read high or low
+byte, then the very next read should be the opposite byte. Our data
+sheet says 10-bits of resolution, although you may find the lower bits
+are active, they are not necessarily reliable or useful externally. We
+chose not to mask them.
+
+We employ significant filtering that is user tunable as described in the
+data sheet. Our temperature reports and fan PWM outputs are very smooth
+when compared to the competition, in addition to the higher resolution
+temperature reports. The smoother PWM output does not require user
+intervention.
+
+We offer GPIO features on the former VID pins. These are open-drain
+outputs or inputs and may be used as general purpose I/O or as alarm
+outputs that are based on temperature limits. These are in 19h and 1Ah.
+
+We offer flexible mapping of temperature readings to thermal zones. Any
+temperature may be mapped to any zone, which has a default assignment
+that follows Intel's specs.
+
+Since there is a fan to zone assignment that allows for the "hotter" of
+a set of zones to control the PWM of an individual fan, but there is no
+indication to the user, we have added an indicator that shows which zone
+is currently controlling the PWM for a given fan. This is in register
+00h.
+
+Both remote diode temperature readings may be given an offset value such
+that the reported reading as well as the temperature used to determine
+PWM may be offset for system calibration purposes.
+
+PECI Extended configuration allows for having more than two domains per
+PECI address and also provides an enabling function for each PECI
+address. One could use our flexible zone assignment to have a zone
+assigned to up to 4 PECI addresses. This is not possible in the default
+Intel configuration. This would be useful in multi-CPU systems with
+individual fans on each that would benefit from individual fan control.
+This is in register 0Eh.
+
+The tachometer measurement system is flexible and able to adapt to many
+fan types. We can also support pulse-stretched PWM so that 3-wire fans
+may be used. These characteristics are in registers 04h to 07h.
+
+Finally, we have added a tach disable function that turns off the tach
+measurement system for individual tachs in order to save power. That is
+in register 75h.
+
+--
+aSC7621 Product Description
+
+The aSC7621 has a two wire digital interface compatible with SMBus 2.0.
+Using a 10-bit ADC, the aSC7621 measures the temperature of two remote diode
+connected transistors as well as its own die. Support for Platform
+Environmental Control Interface (PECI) is included.
+
+Using temperature information from these four zones, an automatic fan speed
+control algorithm is employed to minimize acoustic impact while achieving
+recommended CPU temperature under varying operational loads.
+
+To set fan speed, the aSC7621 has three independent pulse width modulation
+(PWM) outputs that are controlled by one, or a combination of three,
+temperature zones. Both high- and low-frequency PWM ranges are supported.
+
+The aSC7621 also includes a digital filter that can be invoked to smooth
+temperature readings for better control of fan speed and minimum acoustic
+impact.
+
+The aSC7621 has tachometer inputs to measure fan speed on up to four fans.
+Limit and status registers for all measured values are included to alert
+the system host that any measurements are outside of programmed limits
+via status registers.
+
+System voltages of VCCP, 2.5V, 3.3V, 5.0V, and 12V motherboard power are
+monitored efficiently with internal scaling resistors.
+
+Features
+- Supports PECI interface and monitors internal and remote thermal diodes
+- 2-wire, SMBus 2.0 compliant, serial interface
+- 10-bit ADC
+- Monitors VCCP, 2.5V, 3.3V, 5.0V, and 12V motherboard/processor supplies
+- Programmable autonomous fan control based on temperature readings
+- Noise filtering of temperature reading for fan speed control
+- 0.25C digital temperature sensor resolution
+- 3 PWM fan speed control outputs for 2-, 3- or 4-wire fans and up to 4 fan
+	tachometer inputs
+- Enhanced measured temperature to Temperature Zone assignment.
+- Provides high and low PWM frequency ranges
+- 3 GPIO pins for custom use
+- 24-Lead QSOP package
+
+Configuration Notes
+===================
+
+Except where noted below, the sysfs entries created by this driver follow
+the standards defined in "sysfs-interface".
+
+temp1_source
+	0 	(default) peci_legacy = 0, Remote 1 Temperature
+			peci_legacy = 1, PECI Processor Temperature 0
+	1 	Remote 1 Temperature
+	2 	Remote 2 Temperature
+	3 	Internal Temperature
+	4 	PECI Processor Temperature 0
+	5 	PECI Processor Temperature 1
+	6 	PECI Processor Temperature 2
+	7  PECI Processor Temperature 3
+
+temp2_source
+	0 	(default) Internal Temperature
+	1 	Remote 1 Temperature
+	2 	Remote 2 Temperature
+	3 	Internal Temperature
+	4 	PECI Processor Temperature 0
+	5 	PECI Processor Temperature 1
+	6 	PECI Processor Temperature 2
+	7 	PECI Processor Temperature 3
+
+temp3_source
+	0 	(default) Remote 2 Temperature
+	1 	Remote 1 Temperature
+	2 	Remote 2 Temperature
+	3 	Internal Temperature
+	4 	PECI Processor Temperature 0
+	5 	PECI Processor Temperature 1
+	6 	PECI Processor Temperature 2
+	7 	PECI Processor Temperature 3
+
+temp4_source
+	0 	(default) peci_legacy = 0, PECI Processor Temperature 0
+			peci_legacy = 1, Remote 1 Temperature
+	1 	Remote 1 Temperature
+	2 	Remote 2 Temperature
+	3 	Internal Temperature
+	4 	PECI Processor Temperature 0
+	5 	PECI Processor Temperature 1
+	6 	PECI Processor Temperature 2
+	7 	PECI Processor Temperature 3
+
+temp[1-4]_smoothing_enable
+temp[1-4]_smoothing_time
+	Smooths spikes in temp readings caused by noise.
+	Valid values in milliseconds are:
+	35000
+	17600
+	11800
+	 7000
+	 4400
+	 3000
+	 1600
+	  800
+
+temp[1-4]_crit
+	When the corresponding zone temperature reaches this value,
+	ALL pwm outputs will got to 100%.
+
+temp[5-8]_input
+temp[5-8]_enable
+	The aSC7621 can also read temperatures provided by the processor
+	via the PECI bus.  Usually these are "core" temps and are relative
+	to the point where the automatic thermal control circuit starts
+	throttling.  This means that these are usually negative numbers.
+
+pwm[1-3]_enable
+	0		Fan off.
+	1		Fan on manual control.
+	2		Fan on automatic control and will run at the minimum pwm
+				if the temperature for the zone is below the minimum.
+	3		Fan on automatic control but will be off if the temperature
+				for the zone is below the minimum.
+	4-254	Ignored.
+	255		Fan on full.
+
+pwm[1-3]_auto_channels
+	Bitmap as described in sysctl-interface with the following
+	exceptions...
+	Only the following combination of zones (and their corresponding masks)
+	are valid:
+	1
+	2
+	3
+	2,3
+	1,2,3
+	4
+	1,2,3,4
+
+	Special values:
+	0			Disabled.
+	16		Fan on manual control.
+	31		Fan on full.
+
+
+pwm[1-3]_invert
+	When set, inverts the meaning of pwm[1-3].
+	i.e.  when pwm = 0, the fan will be on full and
+	when pwm = 255 the fan will be off.
+
+pwm[1-3]_freq
+	PWM frequency in Hz
+	Valid values in Hz are:
+
+	10
+	15
+	23
+	30  (default)
+	38
+	47
+	62
+	94
+	23000
+	24000
+	25000
+	26000
+	27000
+	28000
+	29000
+	30000
+
+	Setting any other value will be ignored.
+
+peci_enable
+	Enables or disables PECI
+
+peci_avg
+	Input filter average time.
+
+	0 	0 Sec. (no Smoothing) (default)
+	1 	0.25 Sec.
+	2 	0.5 Sec.
+	3 	1.0 Sec.
+	4 	2.0 Sec.
+	5 	4.0 Sec.
+	6 	8.0 Sec.
+	7 	0.0 Sec.
+
+peci_legacy
+
+	0	Standard Mode (default)
+		Remote Diode 1 reading is associated with
+		Temperature Zone 1, PECI is associated with
+		Zone 4
+
+	1	Legacy Mode
+		PECI is associated with Temperature Zone 1,
+		Remote Diode 1 is associated with Zone 4
+
+peci_diode
+	Diode filter
+
+	0	0.25 Sec.
+	1 	1.1 Sec.
+	2 	2.4 Sec.  (default)
+	3 	3.4 Sec.
+	4 	5.0 Sec.
+	5 	6.8 Sec.
+	6 	10.2 Sec.
+	7 	16.4 Sec.
+
+peci_4domain
+	Four domain enable
+
+	0 	1 or 2 Domains for enabled processors (default)
+	1 	3 or 4 Domains for enabled processors
+
+peci_domain
+	Domain
+
+	0 	Processor contains a single domain (0) 	 (default)
+	1 	Processor contains two domains (0,1)
diff -druNp linux-libre-2.6.33-gnu1/Documentation/hwmon/it87 linux-libre-2.6.34-gnu1/Documentation/hwmon/it87
--- linux-libre-2.6.33-gnu1/Documentation/hwmon/it87	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/hwmon/it87	2010-05-16 17:17:36.000000000 -0400
@@ -5,31 +5,23 @@ Supported chips:
   * IT8705F
     Prefix: 'it87'
     Addresses scanned: from Super I/O config space (8 I/O ports)
-    Datasheet: Publicly available at the ITE website
-               http://www.ite.com.tw/product_info/file/pc/IT8705F_V.0.4.1.pdf
+    Datasheet: Once publicly available at the ITE website, but no longer
   * IT8712F
     Prefix: 'it8712'
     Addresses scanned: from Super I/O config space (8 I/O ports)
-    Datasheet: Publicly available at the ITE website
-               http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.1.pdf
-               http://www.ite.com.tw/product_info/file/pc/Errata%20V0.1%20for%20IT8712F%20V0.9.1.pdf
-               http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.3.pdf
+    Datasheet: Once publicly available at the ITE website, but no longer
   * IT8716F/IT8726F
     Prefix: 'it8716'
     Addresses scanned: from Super I/O config space (8 I/O ports)
-    Datasheet: Publicly available at the ITE website
-               http://www.ite.com.tw/product_info/file/pc/IT8716F_V0.3.ZIP
-               http://www.ite.com.tw/product_info/file/pc/IT8726F_V0.3.pdf
+    Datasheet: Once publicly available at the ITE website, but no longer
   * IT8718F
     Prefix: 'it8718'
     Addresses scanned: from Super I/O config space (8 I/O ports)
-    Datasheet: Publicly available at the ITE website
-               http://www.ite.com.tw/product_info/file/pc/IT8718F_V0.2.zip
-               http://www.ite.com.tw/product_info/file/pc/IT8718F_V0%203_(for%20C%20version).zip
+    Datasheet: Once publicly available at the ITE website, but no longer
   * IT8720F
     Prefix: 'it8720'
     Addresses scanned: from Super I/O config space (8 I/O ports)
-    Datasheet: Not yet publicly available.
+    Datasheet: Not publicly available
   * SiS950   [clone of IT8705F]
     Prefix: 'it87'
     Addresses scanned: from Super I/O config space (8 I/O ports)
@@ -136,6 +128,10 @@ registers are read whenever any data is
 seconds since the last update). This means that you can easily miss
 once-only alarms.
 
+Out-of-limit readings can also result in beeping, if the chip is properly
+wired and configured. Beeping can be enabled or disabled per sensor type
+(temperatures, voltages and fans.)
+
 The IT87xx only updates its values each 1.5 seconds; reading it more often
 will do no harm, but will return 'old' values.
 
@@ -150,11 +146,38 @@ Fan speed control
 -----------------
 
 The fan speed control features are limited to manual PWM mode. Automatic
-"Smart Guardian" mode control handling is not implemented. However
-if you want to go for "manual mode" just write 1 to pwmN_enable.
+"Smart Guardian" mode control handling is only implemented for older chips
+(see below.) However if you want to go for "manual mode" just write 1 to
+pwmN_enable.
 
 If you are only able to control the fan speed with very small PWM values,
 try lowering the PWM base frequency (pwm1_freq). Depending on the fan,
 it may give you a somewhat greater control range. The same frequency is
 used to drive all fan outputs, which is why pwm2_freq and pwm3_freq are
 read-only.
+
+
+Automatic fan speed control (old interface)
+-------------------------------------------
+
+The driver supports the old interface to automatic fan speed control
+which is implemented by IT8705F chips up to revision F and IT8712F
+chips up to revision G.
+
+This interface implements 4 temperature vs. PWM output trip points.
+The PWM output of trip point 4 is always the maximum value (fan running
+at full speed) while the PWM output of the other 3 trip points can be
+freely chosen. The temperature of all 4 trip points can be freely chosen.
+Additionally, trip point 1 has an hysteresis temperature attached, to
+prevent fast switching between fan on and off.
+
+The chip automatically computes the PWM output value based on the input
+temperature, based on this simple rule: if the temperature value is
+between trip point N and trip point N+1 then the PWM output value is
+the one of trip point N. The automatic control mode is less flexible
+than the manual control mode, but it reacts faster, is more robust and
+doesn't use CPU cycles.
+
+Trip points must be set properly before switching to automatic fan speed
+control mode. The driver will perform basic integrity checks before
+actually switching to automatic control mode.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/hwmon/lm90 linux-libre-2.6.34-gnu1/Documentation/hwmon/lm90
--- linux-libre-2.6.33-gnu1/Documentation/hwmon/lm90	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/hwmon/lm90	2010-05-16 17:17:36.000000000 -0400
@@ -84,6 +84,10 @@ Supported chips:
     Addresses scanned: I2C 0x4c
     Datasheet: Publicly available at the Maxim website
                http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3500
+  * Winbond/Nuvoton W83L771AWG/ASG
+    Prefix: 'w83l771'
+    Addresses scanned: I2C 0x4c
+    Datasheet: Not publicly available, can be requested from Nuvoton
 
 
 Author: Jean Delvare <khali@linux-fr.org>
@@ -147,6 +151,12 @@ MAX6680 and MAX6681:
   * Selectable address
   * Remote sensor type selection
 
+W83L771AWG/ASG
+  * The AWG and ASG variants only differ in package format.
+  * Filter and alert configuration register at 0xBF
+  * Diode ideality factor configuration (remote sensor) at 0xE3
+  * Moving average (depending on conversion rate)
+
 All temperature values are given in degrees Celsius. Resolution
 is 1.0 degree for the local temperature, 0.125 degree for the remote
 temperature, except for the MAX6657, MAX6658 and MAX6659 which have a
@@ -163,6 +173,18 @@ The lm90 driver will not update its valu
 other second; reading them more often will do no harm, but will return
 'old' values.
 
+SMBus Alert Support
+-------------------
+
+This driver has basic support for SMBus alert. When an alert is received,
+the status register is read and the faulty temperature channel is logged.
+
+The Analog Devices chips (ADM1032 and ADT7461) do not implement the SMBus
+alert protocol properly so additional care is needed: the ALERT output is
+disabled when an alert is received, and is re-enabled only when the alarm
+is gone. Otherwise the chip would block alerts from other chips in the bus
+as long as the alarm is active.
+
 PEC Support
 -----------
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/i2c/busses/i2c-i801 linux-libre-2.6.34-gnu1/Documentation/i2c/busses/i2c-i801
--- linux-libre-2.6.33-gnu1/Documentation/i2c/busses/i2c-i801	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/i2c/busses/i2c-i801	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,8 @@ Supported adapters:
   * Intel 82801I (ICH9)
   * Intel EP80579 (Tolapai)
   * Intel 82801JI (ICH10)
-  * Intel PCH
+  * Intel 3400/5 Series (PCH)
+  * Intel Cougar Point (PCH)
    Datasheets: Publicly available at the Intel website
 
 Authors: 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/i2c/busses/i2c-parport linux-libre-2.6.34-gnu1/Documentation/i2c/busses/i2c-parport
--- linux-libre-2.6.33-gnu1/Documentation/i2c/busses/i2c-parport	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/i2c/busses/i2c-parport	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,9 @@ can be easily added when needed.
 Earlier kernels defaulted to type=0 (Philips).  But now, if the type
 parameter is missing, the driver will simply fail to initialize.
 
+SMBus alert support is available on adapters which have this line properly
+connected to the parallel port's interrupt pin.
+
 
 Building your own adapter
 -------------------------
diff -druNp linux-libre-2.6.33-gnu1/Documentation/i2c/busses/i2c-parport-light linux-libre-2.6.34-gnu1/Documentation/i2c/busses/i2c-parport-light
--- linux-libre-2.6.33-gnu1/Documentation/i2c/busses/i2c-parport-light	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/i2c/busses/i2c-parport-light	2010-05-16 17:17:36.000000000 -0400
@@ -9,3 +9,14 @@ parport handling is not an option. The d
 and the impossibility to daisy-chain other parallel port devices.                 
   
 Please see i2c-parport for documentation.
+
+Module parameters:
+
+* type: type of adapter (see i2c-parport or modinfo)
+
+* base: base I/O address
+  Default is 0x378 which is fairly common for parallel ports, at least on PC.
+
+* irq: optional IRQ
+  This must be passed if you want SMBus alert support, assuming your adapter
+  actually supports this.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/i2c/smbus-protocol linux-libre-2.6.34-gnu1/Documentation/i2c/smbus-protocol
--- linux-libre-2.6.33-gnu1/Documentation/i2c/smbus-protocol	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/i2c/smbus-protocol	2010-05-16 17:17:36.000000000 -0400
@@ -185,6 +185,22 @@ the protocol. All ARP communications use
 require PEC checksums.
 
 
+SMBus Alert
+===========
+
+SMBus Alert was introduced in Revision 1.0 of the specification.
+
+The SMBus alert protocol allows several SMBus slave devices to share a
+single interrupt pin on the SMBus master, while still allowing the master
+to know which slave triggered the interrupt.
+
+This is implemented the following way in the Linux kernel:
+* I2C bus drivers which support SMBus alert should call
+  i2c_setup_smbus_alert() to setup SMBus alert support.
+* I2C drivers for devices which can trigger SMBus alerts should implement
+  the optional alert() callback.
+
+
 I2C Block Transactions
 ======================
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/i2c/writing-clients linux-libre-2.6.34-gnu1/Documentation/i2c/writing-clients
--- linux-libre-2.6.33-gnu1/Documentation/i2c/writing-clients	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/i2c/writing-clients	2010-05-16 17:17:36.000000000 -0400
@@ -74,6 +74,11 @@ structure at all.  You should use this t
 	/* retrieve the value */
 	void *i2c_get_clientdata(const struct i2c_client *client);
 
+Note that starting with kernel 2.6.34, you don't have to set the `data' field
+to NULL in remove() or if probe() failed anymore. The i2c-core does this
+automatically on these occasions. Those are also the only times the core will
+touch this field.
+
 
 Accessing the client
 ====================
@@ -318,8 +323,9 @@ Plain I2C communication
 These routines read and write some bytes from/to a client. The client
 contains the i2c address, so you do not have to include it. The second
 parameter contains the bytes to read/write, the third the number of bytes
-to read/write (must be less than the length of the buffer.) Returned is
-the actual number of bytes read/written.
+to read/write (must be less than the length of the buffer, also should be
+less than 64k since msg.len is u16.) Returned is the actual number of bytes
+read/written.
 
 	int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msg,
 			 int num);
diff -druNp linux-libre-2.6.33-gnu1/Documentation/init.txt linux-libre-2.6.34-gnu1/Documentation/init.txt
--- linux-libre-2.6.33-gnu1/Documentation/init.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/init.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,49 @@
+Explaining the dreaded "No init found." boot hang message
+=========================================================
+
+OK, so you've got this pretty unintuitive message (currently located
+in init/main.c) and are wondering what the H*** went wrong.
+Some high-level reasons for failure (listed roughly in order of execution)
+to load the init binary are:
+A) Unable to mount root FS
+B) init binary doesn't exist on rootfs
+C) broken console device
+D) binary exists but dependencies not available
+E) binary cannot be loaded
+
+Detailed explanations:
+0) Set "debug" kernel parameter (in bootloader config file or CONFIG_CMDLINE)
+   to get more detailed kernel messages.
+A) make sure you have the correct root FS type
+   (and root= kernel parameter points to the correct partition),
+   required drivers such as storage hardware (such as SCSI or USB!)
+   and filesystem (ext3, jffs2 etc.) are builtin (alternatively as modules,
+   to be pre-loaded by an initrd)
+C) Possibly a conflict in console= setup --> initial console unavailable.
+   E.g. some serial consoles are unreliable due to serial IRQ issues (e.g.
+   missing interrupt-based configuration).
+   Try using a different console= device or e.g. netconsole= .
+D) e.g. required library dependencies of the init binary such as
+   /lib/ld-linux.so.2 missing or broken. Use readelf -d <INIT>|grep NEEDED
+   to find out which libraries are required.
+E) make sure the binary's architecture matches your hardware.
+   E.g. i386 vs. x86_64 mismatch, or trying to load x86 on ARM hardware.
+   In case you tried loading a non-binary file here (shell script?),
+   you should make sure that the script specifies an interpreter in its shebang
+   header line (#!/...) that is fully working (including its library
+   dependencies). And before tackling scripts, better first test a simple
+   non-script binary such as /bin/sh and confirm its successful execution.
+   To find out more, add code to init/main.c to display kernel_execve()s
+   return values.
+
+Please extend this explanation whenever you find new failure causes
+(after all loading the init binary is a CRITICAL and hard transition step
+which needs to be made as painless as possible), then submit patch to LKML.
+Further TODOs:
+- Implement the various run_init_process() invocations via a struct array
+  which can then store the kernel_execve() result value and on failure
+  log it all by iterating over _all_ results (very important usability fix).
+- try to make the implementation itself more helpful in general,
+  e.g. by providing additional error messages at affected places.
+
+Andreas Mohr <andi at lisas period de>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/input/elantech.txt linux-libre-2.6.34-gnu1/Documentation/input/elantech.txt
--- linux-libre-2.6.33-gnu1/Documentation/input/elantech.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/input/elantech.txt	2010-05-16 17:17:36.000000000 -0400
@@ -333,14 +333,14 @@ byte 0:
 byte 1:
 
    bit   7   6   5   4   3   2   1   0
-        x15 x14 x13 x12 x11 x10 x9  x8
+         .   .   .   .   .  x10 x9  x8
 
 byte 2:
 
    bit   7   6   5   4   3   2   1   0
         x7  x6  x5  x4  x4  x2  x1  x0
 
-         x15..x0 = absolute x value (horizontal)
+         x10..x0 = absolute x value (horizontal)
 
 byte 3:
 
@@ -350,14 +350,14 @@ byte 3:
 byte 4:
 
    bit   7   6   5   4   3   2   1   0
-        y15 y14 y13 y12 y11 y10 y8  y8
+         .   .   .   .   .   .  y9  y8
 
 byte 5:
 
    bit   7   6   5   4   3   2   1   0
         y7  y6  y5  y4  y3  y2  y1  y0
 
-         y15..y0 = absolute y value (vertical)
+         y9..y0 = absolute y value (vertical)
 
 
 4.2.2 Two finger touch
diff -druNp linux-libre-2.6.33-gnu1/Documentation/input/multi-touch-protocol.txt linux-libre-2.6.34-gnu1/Documentation/input/multi-touch-protocol.txt
--- linux-libre-2.6.33-gnu1/Documentation/input/multi-touch-protocol.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/input/multi-touch-protocol.txt	2010-05-16 17:17:36.000000000 -0400
@@ -68,6 +68,22 @@ like:
    SYN_MT_REPORT
    SYN_REPORT
 
+Here is the sequence after lifting one of the fingers:
+
+   ABS_MT_POSITION_X
+   ABS_MT_POSITION_Y
+   SYN_MT_REPORT
+   SYN_REPORT
+
+And here is the sequence after lifting the remaining finger:
+
+   SYN_MT_REPORT
+   SYN_REPORT
+
+If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the
+ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the
+last SYN_REPORT will be dropped by the input core, resulting in no
+zero-finger event reaching userland.
 
 Event Semantics
 ---------------
@@ -217,11 +233,6 @@ where examples can be found.
 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.
+[3] Multitouch X driver project: http://bitmath.org/code/multitouch/.
 [4] See the section on event computation.
 [5] See the section on finger tracking.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/input/rotary-encoder.txt linux-libre-2.6.34-gnu1/Documentation/input/rotary-encoder.txt
--- linux-libre-2.6.33-gnu1/Documentation/input/rotary-encoder.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/input/rotary-encoder.txt	2010-05-16 17:17:36.000000000 -0400
@@ -75,7 +75,7 @@ and the number of steps or will clamp at
 the configuration.
 
 Because GPIO to IRQ mapping is platform specific, this information must
-be given in seperately to the driver. See the example below.
+be given in separately to the driver. See the example below.
 
 ---------<snip>---------
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/input/sentelic.txt linux-libre-2.6.34-gnu1/Documentation/input/sentelic.txt
--- linux-libre-2.6.33-gnu1/Documentation/input/sentelic.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/input/sentelic.txt	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
-Copyright (C) 2002-2008 Sentelic Corporation.
-Last update: Oct-31-2008
+Copyright (C) 2002-2010 Sentelic Corporation.
+Last update: Jan-13-2010
 
 ==============================================================================
 * Finger Sensing Pad Intellimouse Mode(scrolling wheel, 4th and 5th buttons)
@@ -44,7 +44,7 @@ B) MSID 6: Horizontal and Vertical scrol
 Packet 1
    Bit 7 6 5 4 3 2 1 0       7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0
 BYTE  |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
-  1   |Y|X|y|x|1|M|R|L|  2  |X|X|X|X|X|X|X|X|  3 |Y|Y|Y|Y|Y|Y|Y|Y|  4 | | |B|F|l|r|u|d|
+  1   |Y|X|y|x|1|M|R|L|  2  |X|X|X|X|X|X|X|X|  3 |Y|Y|Y|Y|Y|Y|Y|Y|  4 | | |B|F|r|l|u|d|
       |---------------|     |---------------|    |---------------|    |---------------|
 
 Byte 1: Bit7 => Y overflow
@@ -59,15 +59,15 @@ Byte 2: X Movement(9-bit 2's complement
 Byte 3: Y Movement(9-bit 2's complement integers)
 Byte 4: Bit0 => the Vertical scrolling movement downward.
 	Bit1 => the Vertical scrolling movement upward.
-	Bit2 => the Vertical scrolling movement rightward.
-	Bit3 => the Vertical scrolling movement leftward.
+	Bit2 => the Horizontal scrolling movement leftward.
+	Bit3 => the Horizontal scrolling movement rightward.
         Bit4 => 1 = 4th mouse button is pressed, Forward one page.
                 0 = 4th mouse button is not pressed.
         Bit5 => 1 = 5th mouse button is pressed, Backward one page.
                 0 = 5th mouse button is not pressed.
 
 C) MSID 7:
-# FSP uses 2 packets(8 Bytes) data to represent Absolute Position
+# FSP uses 2 packets (8 Bytes) to represent Absolute Position.
   so we have PACKET NUMBER to identify packets.
   If PACKET NUMBER is 0, the packet is Packet 1.
   If PACKET NUMBER is 1, the packet is Packet 2.
@@ -129,7 +129,7 @@ Byte 3: Message Type => 0x00 (Disabled)
 Byte 4: Bit7~Bit0 => Don't Care
 
 ==============================================================================
-* Absolute position for STL3888-A0.
+* Absolute position for STL3888-Ax.
 ==============================================================================
 Packet 1 (ABSOLUTE POSITION)
    Bit 7 6 5 4 3 2 1 0       7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0
@@ -179,14 +179,14 @@ Byte 4: Bit1~Bit0 => Y coordinate (xpos[
         Bit5~Bit4 => y2_g
         Bit7~Bit6 => x2_g
 
-Notify Packet for STL3888-A0
+Notify Packet for STL3888-Ax
    Bit 7 6 5 4 3 2 1 0       7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0
 BYTE  |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
   1   |1|0|1|P|1|M|R|L|  2  |C|C|C|C|C|C|C|C|  3 |0|0|F|F|0|0|0|i|  4 |r|l|d|u|0|0|0|0|
       |---------------|     |---------------|    |---------------|    |---------------|
 
 Byte 1: Bit7~Bit6 => 00, Normal data packet
-                  => 01, Absolute coordination packet
+                  => 01, Absolute coordinates packet
                   => 10, Notify packet
         Bit5 => 1
         Bit4 => when in absolute coordinates mode (valid when EN_PKT_GO is 1):
@@ -205,15 +205,106 @@ Byte 4: Bit7 => scroll right button
         Bit6 => scroll left button
         Bit5 => scroll down button
         Bit4 => scroll up button
-            * Note that if gesture and additional button (Bit4~Bit7)
-	      happen at the same time, the button information will not
-	      be sent.
+            * Note that if gesture and additional buttoni (Bit4~Bit7)
+              happen at the same time, the button information will not
+              be sent.
         Bit3~Bit0 => Reserved
 
 Sample sequence of Multi-finger, Multi-coordinate mode:
 
 	notify packet (valid bit == 1), abs pkt 1, abs pkt 2, abs pkt 1,
-	abs pkt 2, ..., notify packet(valid bit == 0)
+	abs pkt 2, ..., notify packet (valid bit == 0)
+
+==============================================================================
+* Absolute position for STL3888-B0.
+==============================================================================
+Packet 1(ABSOLUTE POSITION)
+   Bit 7 6 5 4 3 2 1 0       7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0
+BYTE  |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
+  1   |0|1|V|F|1|0|R|L|  2  |X|X|X|X|X|X|X|X|  3 |Y|Y|Y|Y|Y|Y|Y|Y|  4 |r|l|u|d|X|X|Y|Y|
+      |---------------|     |---------------|    |---------------|    |---------------|
+
+Byte 1: Bit7~Bit6 => 00, Normal data packet
+                  => 01, Absolute coordinates packet
+                  => 10, Notify packet
+        Bit5 => Valid bit, 0 means that the coordinate is invalid or finger up.
+                When both fingers are up, the last two reports have zero valid
+                bit.
+        Bit4 => finger up/down information. 1: finger down, 0: finger up.
+        Bit3 => 1
+        Bit2 => finger index, 0 is the first finger, 1 is the second finger.
+        Bit1 => Right Button, 1 is pressed, 0 is not pressed.
+        Bit0 => Left Button, 1 is pressed, 0 is not pressed.
+Byte 2: X coordinate (xpos[9:2])
+Byte 3: Y coordinate (ypos[9:2])
+Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
+        Bit3~Bit2 => X coordinate (ypos[1:0])
+        Bit4 => scroll down button
+        Bit5 => scroll up button
+        Bit6 => scroll left button
+        Bit7 => scroll right button
+
+Packet 2 (ABSOLUTE POSITION)
+   Bit 7 6 5 4 3 2 1 0       7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0
+BYTE  |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
+  1   |0|1|V|F|1|1|R|L|  2  |X|X|X|X|X|X|X|X|  3 |Y|Y|Y|Y|Y|Y|Y|Y|  4 |r|l|u|d|X|X|Y|Y|
+      |---------------|     |---------------|    |---------------|    |---------------|
+
+Byte 1: Bit7~Bit6 => 00, Normal data packet
+                  => 01, Absolute coordination packet
+                  => 10, Notify packet
+        Bit5 => Valid bit, 0 means that the coordinate is invalid or finger up.
+                When both fingers are up, the last two reports have zero valid
+                bit.
+        Bit4 => finger up/down information. 1: finger down, 0: finger up.
+        Bit3 => 1
+        Bit2 => finger index, 0 is the first finger, 1 is the second finger.
+        Bit1 => Right Button, 1 is pressed, 0 is not pressed.
+        Bit0 => Left Button, 1 is pressed, 0 is not pressed.
+Byte 2: X coordinate (xpos[9:2])
+Byte 3: Y coordinate (ypos[9:2])
+Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
+        Bit3~Bit2 => X coordinate (ypos[1:0])
+        Bit4 => scroll down button
+        Bit5 => scroll up button
+        Bit6 => scroll left button
+        Bit7 => scroll right button
+
+Notify Packet for STL3888-B0
+   Bit 7 6 5 4 3 2 1 0       7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0
+BYTE  |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
+  1   |1|0|1|P|1|M|R|L|  2  |C|C|C|C|C|C|C|C|  3 |0|0|F|F|0|0|0|i|  4 |r|l|u|d|0|0|0|0|
+      |---------------|     |---------------|    |---------------|    |---------------|
+
+Byte 1: Bit7~Bit6 => 00, Normal data packet
+                  => 01, Absolute coordination packet
+                  => 10, Notify packet
+        Bit5 => 1
+        Bit4 => when in absolute coordinate mode (valid when EN_PKT_GO is 1):
+                0: left button is generated by the on-pad command
+                1: left button is generated by the external button
+        Bit3 => 1
+        Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
+        Bit1 => Right Button, 1 is pressed, 0 is not pressed.
+        Bit0 => Left Button, 1 is pressed, 0 is not pressed.
+Byte 2: Message Type => 0xB7 (Multi Finger, Multi Coordinate mode)
+Byte 3: Bit7~Bit6 => Don't care
+        Bit5~Bit4 => Number of fingers
+        Bit3~Bit1 => Reserved
+        Bit0 => 1: enter gesture mode; 0: leaving gesture mode
+Byte 4: Bit7 => scroll right button
+        Bit6 => scroll left button
+        Bit5 => scroll up button
+        Bit4 => scroll down button
+            * Note that if gesture and additional button(Bit4~Bit7)
+              happen at the same time, the button information will not
+              be sent.
+        Bit3~Bit0 => Reserved
+
+Sample sequence of Multi-finger, Multi-coordinate mode:
+
+	notify packet (valid bit == 1), abs pkt 1, abs pkt 2, abs pkt 1,
+	abs pkt 2, ..., notify packet (valid bit == 0)
 
 ==============================================================================
 * FSP Enable/Disable packet
@@ -409,7 +500,8 @@ offset	width		default	r/w	name
 					0: read only, 1: read/write enable
 	(Note that following registers does not require clock gating being
 	enabled prior to write: 05 06 07 08 09 0c 0f 10 11 12 16 17 18 23 2e
-	40 41 42 43.)
+	40 41 42 43.  In addition to that, this bit must be 1 when gesture
+	mode is enabled)
 
 0x31				RW	on-pad command detection
 	bit7		0	RW	on-pad command left button down tag
@@ -463,6 +555,10 @@ offset	width		default	r/w	name
 	absolute coordinates; otherwise, host only receives packets with
 	relative coordinate.)
 
+	bit7		0	RW	EN_PS2_F2: PS/2 gesture mode 2nd
+					finger packet enable
+					0: disable, 1: enable
+
 0x43				RW	on-pad control
 	bit0		0	RW	on-pad control enable
 					0: disable, 1: enable
diff -druNp linux-libre-2.6.33-gnu1/Documentation/ioctl/ioctl-number.txt linux-libre-2.6.34-gnu1/Documentation/ioctl/ioctl-number.txt
--- linux-libre-2.6.33-gnu1/Documentation/ioctl/ioctl-number.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/ioctl/ioctl-number.txt	2010-05-16 17:17:36.000000000 -0400
@@ -139,7 +139,6 @@ Code  Seq#(hex)	Include File		Comments
 'K'	all	linux/kd.h
 'L'	00-1F	linux/loop.h		conflict!
 'L'	10-1F	drivers/scsi/mpt2sas/mpt2sas_ctl.h	conflict!
-'L'	20-2F	linux/usb/vstusb.h
 'L'	E0-FF	linux/ppdd.h		encrypted disk device driver
 					<http://linux01.gwdg.de/~alatham/ppdd.html>
 'M'	all	linux/soundcard.h	conflict!
@@ -292,6 +291,7 @@ Code  Seq#(hex)	Include File		Comments
 0x92	00-0F	drivers/usb/mon/mon_bin.c
 0x93	60-7F	linux/auto_fs.h
 0x94	all	fs/btrfs/ioctl.h
+0x97	00-7F	fs/ceph/ioctl.h		Ceph file system
 0x99	00-0F				537-Addinboard driver
 					<mailto:buk@buks.ipn.de>
 0xA0	all	linux/sdp/sdp.h		Industrial Device Project
diff -druNp linux-libre-2.6.33-gnu1/Documentation/IPMI.txt linux-libre-2.6.34-gnu1/Documentation/IPMI.txt
--- linux-libre-2.6.33-gnu1/Documentation/IPMI.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/IPMI.txt	2010-05-16 17:17:36.000000000 -0400
@@ -365,6 +365,7 @@ You can change this at module load time
        regshifts=<shift1>,<shift2>,...
        slave_addrs=<addr1>,<addr2>,...
        force_kipmid=<enable1>,<enable2>,...
+       kipmid_max_busy_us=<ustime1>,<ustime2>,...
        unload_when_empty=[0|1]
 
 Each of these except si_trydefaults is a list, the first item for the
@@ -433,6 +434,7 @@ kernel command line as:
        ipmi_si.regshifts=<shift1>,<shift2>,...
        ipmi_si.slave_addrs=<addr1>,<addr2>,...
        ipmi_si.force_kipmid=<enable1>,<enable2>,...
+       ipmi_si.kipmid_max_busy_us=<ustime1>,<ustime2>,...
 
 It works the same as the module parameters of the same names.
 
@@ -450,6 +452,16 @@ force this thread on or off.  If you for
 interrupts, the driver will run VERY slowly.  Don't blame me,
 these interfaces suck.
 
+Unfortunately, this thread can use a lot of CPU depending on the
+interface's performance.  This can waste a lot of CPU and cause
+various issues with detecting idle CPU and using extra power.  To
+avoid this, the kipmid_max_busy_us sets the maximum amount of time, in
+microseconds, that kipmid will spin before sleeping for a tick.  This
+value sets a balance between performance and CPU waste and needs to be
+tuned to your needs.  Maybe, someday, auto-tuning will be added, but
+that's not a simple thing and even the auto-tuning would need to be
+tuned to the user's desired performance.
+
 The driver supports a hot add and remove of interfaces.  This way,
 interfaces can be added or removed after the kernel is up and running.
 This is done using /sys/modules/ipmi_si/parameters/hotmod, which is a
diff -druNp linux-libre-2.6.33-gnu1/Documentation/isdn/INTERFACE.CAPI linux-libre-2.6.34-gnu1/Documentation/isdn/INTERFACE.CAPI
--- linux-libre-2.6.33-gnu1/Documentation/isdn/INTERFACE.CAPI	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/isdn/INTERFACE.CAPI	2010-05-16 17:17:36.000000000 -0400
@@ -149,10 +149,11 @@ 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
+const struct file_operations *proc_fops
+	pointers to callback functions for the device's proc file
+	system entry, /proc/capi/controllers/<n>; pointer to the device's
+	capi_ctr structure is available from struct proc_dir_entry::data
+	which is available from struct inode.
 
 Note: Callback functions except send_message() are never called in interrupt
 context.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/isdn/README.gigaset linux-libre-2.6.34-gnu1/Documentation/isdn/README.gigaset
--- linux-libre-2.6.33-gnu1/Documentation/isdn/README.gigaset	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/isdn/README.gigaset	2010-05-16 17:17:36.000000000 -0400
@@ -292,10 +292,10 @@ GigaSet 307x Device Driver
         to /etc/modprobe.d/gigaset, /etc/modprobe.conf.local or a similar file.
 
      Problem:
-        Your isdn script aborts with a message about isdnlog.
+        The isdnlog program emits error messages or just doesn't work.
      Solution:
-        Try deactivating (or commenting out) isdnlog. This driver does not
-        support it.
+        Isdnlog supports only the HiSax driver. Do not attempt to use it with
+	other drivers such as Gigaset.
 
      Problem:
         You have two or more DECT data adapters (M101/M105) and only the
@@ -321,8 +321,8 @@ GigaSet 307x Device Driver
      writing an appropriate value to /sys/module/gigaset/parameters/debug, e.g.
         echo 0 > /sys/module/gigaset/parameters/debug
      switches off debugging output completely,
-        echo 0x10a020 > /sys/module/gigaset/parameters/debug
-     enables the standard set of debugging output messages. These values are
+        echo 0x302020 > /sys/module/gigaset/parameters/debug
+     enables a reasonable set of debugging output messages. These values are
      bit patterns where every bit controls a certain type of debugging output.
      See the constants DEBUG_* in the source file gigaset.h for details.
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/kernel-parameters.txt linux-libre-2.6.34-gnu1/Documentation/kernel-parameters.txt
--- linux-libre-2.6.33-gnu1/Documentation/kernel-parameters.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/kernel-parameters.txt	2010-05-16 17:17:36.000000000 -0400
@@ -54,6 +54,7 @@ parameter is applicable:
 	IMA     Integrity measurement architecture is enabled.
 	IOSCHED	More than one I/O scheduler is enabled.
 	IP_PNP	IP DHCP, BOOTP, or RARP is enabled.
+	IPV6	IPv6 support is enabled.
 	ISAPNP	ISA PnP code is enabled.
 	ISDN	Appropriate ISDN support is enabled.
 	JOY	Appropriate joystick support is enabled.
@@ -199,10 +200,6 @@ and is between 256 and 4096 characters.
 			acpi_display_output=video
 			See above.
 
-	acpi_early_pdc_eval	[HW,ACPI] Evaluate processor _PDC methods
-				early. Needed on some platforms to properly
-				initialize the EC.
-
 	acpi_irq_balance [HW,ACPI]
 			ACPI will balance active IRQs
 			default in APIC mode
@@ -323,11 +320,6 @@ and is between 256 and 4096 characters.
 	amd_iommu=	[HW,X86-84]
 			Pass parameters to the AMD IOMMU driver in the system.
 			Possible values are:
-			isolate - enable device isolation (each device, as far
-			          as possible, will get its own protection
-			          domain) [default]
-			share - put every device behind one IOMMU into the
-				same protection domain
 			fullflush - enable flushing of IO/TLB entries when
 				    they are unmapped. Otherwise they are
 				    flushed before they will be reused, which
@@ -356,6 +348,9 @@ and is between 256 and 4096 characters.
 			Change the amount of debugging information output
 			when initialising the APIC and IO-APIC components.
 
+	autoconf=	[IPV6]
+			See Documentation/networking/ipv6.txt.
+
 	show_lapic=	[APIC,X86] Advanced Programmable Interrupt Controller
 			Limit apic dumping. The parameter defines the maximal
 			number of local apics being dumped. Also it is possible
@@ -638,6 +633,12 @@ and is between 256 and 4096 characters.
 			See drivers/char/README.epca and
 			Documentation/serial/digiepca.txt.
 
+	disable=	[IPV6]
+			See Documentation/networking/ipv6.txt.
+
+	disable_ipv6=	[IPV6]
+			See Documentation/networking/ipv6.txt.
+
 	disable_mtrr_cleanup [X86]
 			The kernel tries to adjust MTRR layout from continuous
 			to discrete, to make X server driver able to add WB
@@ -1193,7 +1194,7 @@ and is between 256 and 4096 characters.
 
 	libata.force=	[LIBATA] Force configurations.  The format is comma
 			separated list of "[ID:]VAL" where ID is
-			PORT[:DEVICE].  PORT and DEVICE are decimal numbers
+			PORT[.DEVICE].  PORT and DEVICE are decimal numbers
 			matching port, link or device.  Basically, it matches
 			the ATA ID string printed on console by libata.  If
 			the whole ID part is omitted, the last PORT and DEVICE
@@ -1738,6 +1739,9 @@ and is between 256 and 4096 characters.
 	nomfgpt		[X86-32] Disable Multi-Function General Purpose
 			Timer usage (for AMD Geode machines).
 
+	nopat		[X86] Disable PAT (page attribute table extension of
+			pagetables) support.
+
 	norandmaps	Don't use address space randomization.  Equivalent to
 			echo 0 > /proc/sys/kernel/randomize_va_space
 
@@ -1781,6 +1785,12 @@ and is between 256 and 4096 characters.
 			purges which is reported from either PAL_VM_SUMMARY or
 			SAL PALO.
 
+	nr_cpus=	[SMP] Maximum number of processors that	an SMP kernel
+			could support.  nr_cpus=n : n >= 1 limits the kernel to
+			supporting 'n' processors. Later in runtime you can not
+			use hotplug cpu feature to put more cpu back to online.
+			just like you compile the kernel NR_CPUS=n
+
 	nr_uarts=	[SERIAL] maximum number of UARTs to be registered.
 
 	numa_zonelist_order= [KNL, BOOT] Select zonelist order for NUMA.
@@ -1948,8 +1958,12 @@ and is between 256 and 4096 characters.
 				IRQ routing is enabled.
 		noacpi		[X86] Do not use ACPI for IRQ routing
 				or for PCI scanning.
-		use_crs		[X86] Use _CRS for PCI resource
-				allocation.
+		use_crs		[X86] Use PCI host bridge window information
+				from ACPI.  On BIOSes from 2008 or later, this
+				is enabled by default.  If you need to use this,
+				please report a bug.
+		nocrs		[X86] Ignore PCI host bridge windows from ACPI.
+			        If you need to use this, please report a bug.
 		routeirq	Do IRQ routing for all PCI devices.
 				This is normally done in pci_enable_device(),
 				so this option is a temporary workaround
@@ -1998,6 +2012,14 @@ and is between 256 and 4096 characters.
 		force	Enable ASPM even on devices that claim not to support it.
 			WARNING: Forcing ASPM on may cause system lockups.
 
+	pcie_pme=	[PCIE,PM] Native PCIe PME signaling options:
+		off	Do not use native PCIe PME signaling.
+		force	Use native PCIe PME signaling even if the BIOS refuses
+			to allow the kernel to control the relevant PCIe config
+			registers.
+		nomsi	Do not use MSI for native PCIe PME signaling (this makes
+			all PCIe root ports use INTx for everything).
+
 	pcmv=		[HW,PCMCIA] BadgePAD 4
 
 	pd.		[PARIDE]
@@ -2703,6 +2725,13 @@ and is between 256 and 4096 characters.
 					medium is write-protected).
 			Example: quirks=0419:aaf5:rl,0421:0433:rc
 
+	userpte=
+			[X86] Flags controlling user PTE allocations.
+
+				nohigh = do not allocate PTE pages in
+					HIGHMEM regardless of setting
+					of CONFIG_HIGHPTE.
+
 	vdso=		[X86,SH]
 			vdso=2: enable compat VDSO (default with COMPAT_VDSO)
 			vdso=1: enable VDSO (default)
@@ -2796,6 +2825,12 @@ and is between 256 and 4096 characters.
 			default x2apic cluster mode on platforms
 			supporting x2apic.
 
+	x86_mrst_timer= [X86-32,APBT]
+			Choose timer option for x86 Moorestown MID platform.
+			Two valid options are apbt timer only and lapic timer
+			plus one apbt timer for broadcast timer.
+			x86_mrst_timer=apbt_only | lapic_and_apbt
+
 	xd=		[HW,XT] Original XT pre-IDE (RLL encoded) disks.
 	xd_geo=		See header of drivers/block/xd.c.
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/kobject.txt linux-libre-2.6.34-gnu1/Documentation/kobject.txt
--- linux-libre-2.6.33-gnu1/Documentation/kobject.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/kobject.txt	2010-05-16 17:17:36.000000000 -0400
@@ -59,37 +59,56 @@ nice to have in other objects.  The C la
 direct expression of inheritance, so other techniques - such as structure
 embedding - must be used.
 
-So, for example, the UIO code has a structure that defines the memory
-region associated with a uio device:
+(As an aside, for those familiar with the kernel linked list implementation,
+this is analogous as to how "list_head" structs are rarely useful on
+their own, but are invariably found embedded in the larger objects of
+interest.)
 
-struct uio_mem {
+So, for example, the UIO code in drivers/uio/uio.c has a structure that
+defines the memory region associated with a uio device:
+
+    struct uio_map {
 	struct kobject kobj;
-	unsigned long addr;
-	unsigned long size;
-	int memtype;
-	void __iomem *internal_addr;
-};
+	struct uio_mem *mem;
+    };
 
-If you have a struct uio_mem structure, finding its embedded kobject is
+If you have a struct uio_map structure, finding its embedded kobject is
 just a matter of using the kobj member.  Code that works with kobjects will
 often have the opposite problem, however: given a struct kobject pointer,
 what is the pointer to the containing structure?  You must avoid tricks
 (such as assuming that the kobject is at the beginning of the structure)
 and, instead, use the container_of() macro, found in <linux/kernel.h>:
 
-	container_of(pointer, type, member)
+    container_of(pointer, type, member)
 
-where pointer is the pointer to the embedded kobject, type is the type of
-the containing structure, and member is the name of the structure field to
-which pointer points.  The return value from container_of() is a pointer to
-the given type. So, for example, a pointer "kp" to a struct kobject
-embedded within a struct uio_mem could be converted to a pointer to the
-containing uio_mem structure with:
+where:
 
-    struct uio_mem *u_mem = container_of(kp, struct uio_mem, kobj);
+  * "pointer" is the pointer to the embedded kobject,
+  * "type" is the type of the containing structure, and
+  * "member" is the name of the structure field to which "pointer" points.
 
-Programmers often define a simple macro for "back-casting" kobject pointers
-to the containing type.
+The return value from container_of() is a pointer to the corresponding
+container type. So, for example, a pointer "kp" to a struct kobject
+embedded *within* a struct uio_map could be converted to a pointer to the
+*containing* uio_map structure with:
+
+    struct uio_map *u_map = container_of(kp, struct uio_map, kobj);
+
+For convenience, programmers often define a simple macro for "back-casting"
+kobject pointers to the containing type.  Exactly this happens in the
+earlier drivers/uio/uio.c, as you can see here:
+
+    struct uio_map {
+        struct kobject kobj;
+        struct uio_mem *mem;
+    };
+
+    #define to_map(map) container_of(map, struct uio_map, kobj)
+
+where the macro argument "map" is a pointer to the struct kobject in
+question.  That macro is subsequently invoked with:
+
+    struct uio_map *map = to_map(kobj);
 
 
 Initialization of kobjects
@@ -266,7 +285,7 @@ kobj_type:
 
     struct kobj_type {
 	    void (*release)(struct kobject *);
-	    struct sysfs_ops	*sysfs_ops;
+	    const struct sysfs_ops *sysfs_ops;
 	    struct attribute	**default_attrs;
     };
 
@@ -387,4 +406,5 @@ called, and the objects in the former ci
 Example code to copy from
 
 For a more complete example of using ksets and kobjects properly, see the
-sample/kobject/kset-example.c code.
+example programs samples/kobject/{kobject-example.c,kset-example.c},
+which will be built as loadable modules if you select CONFIG_SAMPLE_KOBJECT.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/kprobes.txt linux-libre-2.6.34-gnu1/Documentation/kprobes.txt
--- linux-libre-2.6.33-gnu1/Documentation/kprobes.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/kprobes.txt	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 Title	: Kernel Probes (Kprobes)
 Authors	: Jim Keniston <jkenisto@us.ibm.com>
-	: Prasanna S Panchamukhi <prasanna@in.ibm.com>
+	: Prasanna S Panchamukhi <prasanna.panchamukhi@gmail.com>
+	: Masami Hiramatsu <mhiramat@redhat.com>
 
 CONTENTS
 
@@ -15,6 +16,7 @@ CONTENTS
 9. Jprobes Example
 10. Kretprobes Example
 Appendix A: The kprobes debugfs interface
+Appendix B: The kprobes sysctl interface
 
 1. Concepts: Kprobes, Jprobes, Return Probes
 
@@ -42,13 +44,13 @@ registration/unregistration of a group o
 can speed up unregistration process when you have to unregister
 a lot of probes at once.
 
-The next three subsections explain how the different types of
-probes work.  They explain certain things that you'll need to
-know in order to make the best use of Kprobes -- e.g., the
-difference between a pre_handler and a post_handler, and how
-to use the maxactive and nmissed fields of a kretprobe.  But
-if you're in a hurry to start using Kprobes, you can skip ahead
-to section 2.
+The next four subsections explain how the different types of
+probes work and how jump optimization works.  They explain certain
+things that you'll need to know in order to make the best use of
+Kprobes -- e.g., the difference between a pre_handler and
+a post_handler, and how to use the maxactive and nmissed fields of
+a kretprobe.  But if you're in a hurry to start using Kprobes, you
+can skip ahead to section 2.
 
 1.1 How Does a Kprobe Work?
 
@@ -161,13 +163,125 @@ In case probed function is entered but t
 object available, then in addition to incrementing the nmissed count,
 the user entry_handler invocation is also skipped.
 
+1.4 How Does Jump Optimization Work?
+
+If you configured your kernel with CONFIG_OPTPROBES=y (currently
+this option is supported on x86/x86-64, non-preemptive kernel) and
+the "debug.kprobes_optimization" kernel parameter is set to 1 (see
+sysctl(8)), Kprobes tries to reduce probe-hit overhead by using a jump
+instruction instead of a breakpoint instruction at each probepoint.
+
+1.4.1 Init a Kprobe
+
+When a probe is registered, before attempting this optimization,
+Kprobes inserts an ordinary, breakpoint-based kprobe at the specified
+address. So, even if it's not possible to optimize this particular
+probepoint, there'll be a probe there.
+
+1.4.2 Safety Check
+
+Before optimizing a probe, Kprobes performs the following safety checks:
+
+- Kprobes verifies that the region that will be replaced by the jump
+instruction (the "optimized region") lies entirely within one function.
+(A jump instruction is multiple bytes, and so may overlay multiple
+instructions.)
+
+- Kprobes analyzes the entire function and verifies that there is no
+jump into the optimized region.  Specifically:
+  - the function contains no indirect jump;
+  - the function contains no instruction that causes an exception (since
+  the fixup code triggered by the exception could jump back into the
+  optimized region -- Kprobes checks the exception tables to verify this);
+  and
+  - there is no near jump to the optimized region (other than to the first
+  byte).
+
+- For each instruction in the optimized region, Kprobes verifies that
+the instruction can be executed out of line.
+
+1.4.3 Preparing Detour Buffer
+
+Next, Kprobes prepares a "detour" buffer, which contains the following
+instruction sequence:
+- code to push the CPU's registers (emulating a breakpoint trap)
+- a call to the trampoline code which calls user's probe handlers.
+- code to restore registers
+- the instructions from the optimized region
+- a jump back to the original execution path.
+
+1.4.4 Pre-optimization
+
+After preparing the detour buffer, Kprobes verifies that none of the
+following situations exist:
+- The probe has either a break_handler (i.e., it's a jprobe) or a
+post_handler.
+- Other instructions in the optimized region are probed.
+- The probe is disabled.
+In any of the above cases, Kprobes won't start optimizing the probe.
+Since these are temporary situations, Kprobes tries to start
+optimizing it again if the situation is changed.
+
+If the kprobe can be optimized, Kprobes enqueues the kprobe to an
+optimizing list, and kicks the kprobe-optimizer workqueue to optimize
+it.  If the to-be-optimized probepoint is hit before being optimized,
+Kprobes returns control to the original instruction path by setting
+the CPU's instruction pointer to the copied code in the detour buffer
+-- thus at least avoiding the single-step.
+
+1.4.5 Optimization
+
+The Kprobe-optimizer doesn't insert the jump instruction immediately;
+rather, it calls synchronize_sched() for safety first, because it's
+possible for a CPU to be interrupted in the middle of executing the
+optimized region(*).  As you know, synchronize_sched() can ensure
+that all interruptions that were active when synchronize_sched()
+was called are done, but only if CONFIG_PREEMPT=n.  So, this version
+of kprobe optimization supports only kernels with CONFIG_PREEMPT=n.(**)
+
+After that, the Kprobe-optimizer calls stop_machine() to replace
+the optimized region with a jump instruction to the detour buffer,
+using text_poke_smp().
+
+1.4.6 Unoptimization
+
+When an optimized kprobe is unregistered, disabled, or blocked by
+another kprobe, it will be unoptimized.  If this happens before
+the optimization is complete, the kprobe is just dequeued from the
+optimized list.  If the optimization has been done, the jump is
+replaced with the original code (except for an int3 breakpoint in
+the first byte) by using text_poke_smp().
+
+(*)Please imagine that the 2nd instruction is interrupted and then
+the optimizer replaces the 2nd instruction with the jump *address*
+while the interrupt handler is running. When the interrupt
+returns to original address, there is no valid instruction,
+and it causes an unexpected result.
+
+(**)This optimization-safety checking may be replaced with the
+stop-machine method that ksplice uses for supporting a CONFIG_PREEMPT=y
+kernel.
+
+NOTE for geeks:
+The jump optimization changes the kprobe's pre_handler behavior.
+Without optimization, the pre_handler can change the kernel's execution
+path by changing regs->ip and returning 1.  However, when the probe
+is optimized, that modification is ignored.  Thus, if you want to
+tweak the kernel's execution path, you need to suppress optimization,
+using one of the following techniques:
+- Specify an empty function for the kprobe's post_handler or break_handler.
+ or
+- Config CONFIG_OPTPROBES=n.
+ or
+- Execute 'sysctl -w debug.kprobes_optimization=n'
+
 2. Architectures Supported
 
 Kprobes, jprobes, and return probes are implemented on the following
 architectures:
 
-- i386
-- x86_64 (AMD-64, EM64T)
+- i386 (Supports jump optimization)
+- x86_64 (AMD-64, EM64T) (Supports jump optimization)
 - ppc64
 - ia64 (Does not support probes on instruction slot1.)
 - sparc64 (Return probes not yet implemented.)
@@ -193,6 +307,10 @@ it useful to "Compile the kernel with de
 so you can use "objdump -d -l vmlinux" to see the source-to-object
 code mapping.
 
+If you want to reduce probing overhead, set "Kprobes jump optimization
+support" (CONFIG_OPTPROBES) to "y". You can find this option under the
+"Kprobes" line.
+
 4. API Reference
 
 The Kprobes API includes a "register" function and an "unregister"
@@ -389,7 +507,10 @@ the probe which has been registered.
 
 Kprobes allows multiple probes at the same address.  Currently,
 however, there cannot be multiple jprobes on the same function at
-the same time.
+the same time.  Also, a probepoint for which there is a jprobe or
+a post_handler cannot be optimized.  So if you install a jprobe,
+or a kprobe with a post_handler, at an optimized probepoint, the
+probepoint will be unoptimized automatically.
 
 In general, you can install a probe anywhere in the kernel.
 In particular, you can probe interrupt handlers.  Known exceptions
@@ -453,6 +574,38 @@ reason, Kprobes doesn't support return p
 on the x86_64 version of __switch_to(); the registration functions
 return -EINVAL.
 
+On x86/x86-64, since the Jump Optimization of Kprobes modifies
+instructions widely, there are some limitations to optimization. To
+explain it, we introduce some terminology. Imagine a 3-instruction
+sequence consisting of a two 2-byte instructions and one 3-byte
+instruction.
+
+        IA
+         |
+[-2][-1][0][1][2][3][4][5][6][7]
+        [ins1][ins2][  ins3 ]
+	[<-     DCR       ->]
+	   [<- JTPR ->]
+
+ins1: 1st Instruction
+ins2: 2nd Instruction
+ins3: 3rd Instruction
+IA:  Insertion Address
+JTPR: Jump Target Prohibition Region
+DCR: Detoured Code Region
+
+The instructions in DCR are copied to the out-of-line buffer
+of the kprobe, because the bytes in DCR are replaced by
+a 5-byte jump instruction. So there are several limitations.
+
+a) The instructions in DCR must be relocatable.
+b) The instructions in DCR must not include a call instruction.
+c) JTPR must not be targeted by any jump or call instruction.
+d) DCR must not straddle the border betweeen functions.
+
+Anyway, these limitations are checked by the in-kernel instruction
+decoder, so you don't need to worry about that.
+
 6. Probe Overhead
 
 On a typical CPU in use in 2005, a kprobe hit takes 0.5 to 1.0
@@ -476,6 +629,19 @@ k = 0.49 usec; j = 0.76; r = 0.80; kr =
 ppc64: POWER5 (gr), 1656 MHz (SMT disabled, 1 virtual CPU per physical CPU)
 k = 0.77 usec; j = 1.31; r = 1.26; kr = 1.45; jr = 1.99
 
+6.1 Optimized Probe Overhead
+
+Typically, an optimized kprobe hit takes 0.07 to 0.1 microseconds to
+process. Here are sample overhead figures (in usec) for x86 architectures.
+k = unoptimized kprobe, b = boosted (single-step skipped), o = optimized kprobe,
+r = unoptimized kretprobe, rb = boosted kretprobe, ro = optimized kretprobe.
+
+i386: Intel(R) Xeon(R) E5410, 2.33GHz, 4656.90 bogomips
+k = 0.80 usec; b = 0.33; o = 0.05; r = 1.10; rb = 0.61; ro = 0.33
+
+x86-64: Intel(R) Xeon(R) E5410, 2.33GHz, 4656.90 bogomips
+k = 0.99 usec; b = 0.43; o = 0.06; r = 1.24; rb = 0.68; ro = 0.30
+
 7. TODO
 
 a. SystemTap (http://sourceware.org/systemtap): Provides a simplified
@@ -523,7 +689,8 @@ is also specified. Following columns sho
 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]. If the probe is temporarily disabled,
-such probes are marked with [DISABLED].
+such probes are marked with [DISABLED]. If the probe is optimized, it is
+marked with [OPTIMIZED].
 
 /sys/kernel/debug/kprobes/enabled: Turn kprobes ON/OFF forcibly.
 
@@ -533,3 +700,19 @@ registered probes will be disarmed, till
 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.
+
+
+Appendix B: The kprobes sysctl interface
+
+/proc/sys/debug/kprobes-optimization: Turn kprobes optimization ON/OFF.
+
+When CONFIG_OPTPROBES=y, this sysctl interface appears and it provides
+a knob to globally and forcibly turn jump optimization (see section
+1.4) ON or OFF. By default, jump optimization is allowed (ON).
+If you echo "0" to this file or set "debug.kprobes_optimization" to
+0 via sysctl, all optimized probes will be unoptimized, and any new
+probes registered after that will not be optimized.  Note that this
+knob *changes* the optimized state. This means that optimized probes
+(marked [OPTIMIZED]) will be unoptimized ([OPTIMIZED] tag will be
+removed). If the knob is turned on, they will be optimized again.
+
diff -druNp linux-libre-2.6.33-gnu1/Documentation/kvm/api.txt linux-libre-2.6.34-gnu1/Documentation/kvm/api.txt
--- linux-libre-2.6.33-gnu1/Documentation/kvm/api.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/kvm/api.txt	2010-05-16 17:17:36.000000000 -0400
@@ -23,12 +23,12 @@ of a virtual machine.  The ioctls belong
    Only run vcpu ioctls from the same thread that was used to create the
    vcpu.
 
-2. File descritpors
+2. File descriptors
 
 The kvm API is centered around file descriptors.  An initial
 open("/dev/kvm") obtains a handle to the kvm subsystem; this handle
 can be used to issue system ioctls.  A KVM_CREATE_VM ioctl on this
-handle will create a VM file descripror which can be used to issue VM
+handle will create a VM file descriptor which can be used to issue VM
 ioctls.  A KVM_CREATE_VCPU ioctl on a VM fd will create a virtual cpu
 and return a file descriptor pointing to it.  Finally, ioctls on a vcpu
 fd can be used to control the vcpu, including the important task of
@@ -643,7 +643,7 @@ Type: vm ioctl
 Parameters: struct kvm_clock_data (in)
 Returns: 0 on success, -1 on error
 
-Sets the current timestamp of kvmclock to the valued specific in its parameter.
+Sets the current timestamp of kvmclock to the value specified in its parameter.
 In conjunction with KVM_GET_CLOCK, it is used to ensure monotonicity on scenarios
 such as migration.
 
@@ -795,11 +795,11 @@ Unused.
 			__u64 data_offset; /* relative to kvm_run start */
 		} io;
 
-If exit_reason is KVM_EXIT_IO_IN or KVM_EXIT_IO_OUT, then the vcpu has
+If exit_reason is KVM_EXIT_IO, then the vcpu has
 executed a port I/O instruction which could not be satisfied by kvm.
 data_offset describes where the data is located (KVM_EXIT_IO_OUT) or
 where kvm expects application code to place the data for the next
-KVM_RUN invocation (KVM_EXIT_IO_IN).  Data format is a patcked array.
+KVM_RUN invocation (KVM_EXIT_IO_IN).  Data format is a packed array.
 
 		struct {
 			struct kvm_debug_exit_arch arch;
@@ -815,7 +815,7 @@ Unused.
 			__u8  is_write;
 		} mmio;
 
-If exit_reason is KVM_EXIT_MMIO or KVM_EXIT_IO_OUT, then the vcpu has
+If exit_reason is KVM_EXIT_MMIO, then the vcpu has
 executed a memory-mapped I/O instruction which could not be satisfied
 by kvm.  The 'data' member contains the written data if 'is_write' is
 true, and should be filled by application code otherwise.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/laptops/00-INDEX linux-libre-2.6.34-gnu1/Documentation/laptops/00-INDEX
--- linux-libre-2.6.33-gnu1/Documentation/laptops/00-INDEX	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/laptops/00-INDEX	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,12 @@
 	- This file
 acer-wmi.txt
 	- information on the Acer Laptop WMI Extras driver.
+asus-laptop.txt
+	- information on the Asus Laptop Extras driver.
+disk-shock-protection.txt
+	- information on hard disk shock protection.
+dslm.c
+	- Simple Disk Sleep Monitor program
 laptop-mode.txt
 	- how to conserve battery power using laptop-mode.
 sony-laptop.txt
diff -druNp linux-libre-2.6.33-gnu1/Documentation/laptops/dslm.c linux-libre-2.6.34-gnu1/Documentation/laptops/dslm.c
--- linux-libre-2.6.33-gnu1/Documentation/laptops/dslm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/laptops/dslm.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,166 @@
+/*
+ * dslm.c
+ * Simple Disk Sleep Monitor
+ *  by Bartek Kania
+ * Licenced under the GPL
+ */
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <time.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <linux/hdreg.h>
+
+#ifdef DEBUG
+#define D(x) x
+#else
+#define D(x)
+#endif
+
+int endit = 0;
+
+/* Check if the disk is in powersave-mode
+ * Most of the code is stolen from hdparm.
+ * 1 = active, 0 = standby/sleep, -1 = unknown */
+static int check_powermode(int fd)
+{
+    unsigned char args[4] = {WIN_CHECKPOWERMODE1,0,0,0};
+    int state;
+
+    if (ioctl(fd, HDIO_DRIVE_CMD, &args)
+	&& (args[0] = WIN_CHECKPOWERMODE2) /* try again with 0x98 */
+	&& ioctl(fd, HDIO_DRIVE_CMD, &args)) {
+	if (errno != EIO || args[0] != 0 || args[1] != 0) {
+	    state = -1; /* "unknown"; */
+	} else
+	    state = 0; /* "sleeping"; */
+    } else {
+	state = (args[2] == 255) ? 1 : 0;
+    }
+    D(printf(" drive state is:  %d\n", state));
+
+    return state;
+}
+
+static char *state_name(int i)
+{
+    if (i == -1) return "unknown";
+    if (i == 0) return "sleeping";
+    if (i == 1) return "active";
+
+    return "internal error";
+}
+
+static char *myctime(time_t time)
+{
+    char *ts = ctime(&time);
+    ts[strlen(ts) - 1] = 0;
+
+    return ts;
+}
+
+static void measure(int fd)
+{
+    time_t start_time;
+    int last_state;
+    time_t last_time;
+    int curr_state;
+    time_t curr_time = 0;
+    time_t time_diff;
+    time_t active_time = 0;
+    time_t sleep_time = 0;
+    time_t unknown_time = 0;
+    time_t total_time = 0;
+    int changes = 0;
+    float tmp;
+
+    printf("Starting measurements\n");
+
+    last_state = check_powermode(fd);
+    start_time = last_time = time(0);
+    printf("  System is in state %s\n\n", state_name(last_state));
+
+    while(!endit) {
+	sleep(1);
+	curr_state = check_powermode(fd);
+
+	if (curr_state != last_state || endit) {
+	    changes++;
+	    curr_time = time(0);
+	    time_diff = curr_time - last_time;
+
+	    if (last_state == 1) active_time += time_diff;
+	    else if (last_state == 0) sleep_time += time_diff;
+	    else unknown_time += time_diff;
+
+	    last_state = curr_state;
+	    last_time = curr_time;
+
+	    printf("%s: State-change to %s\n", myctime(curr_time),
+		   state_name(curr_state));
+	}
+    }
+    changes--; /* Compensate for SIGINT */
+
+    total_time = time(0) - start_time;
+    printf("\nTotal running time:  %lus\n", curr_time - start_time);
+    printf(" State changed %d times\n", changes);
+
+    tmp = (float)sleep_time / (float)total_time * 100;
+    printf(" Time in sleep state:   %lus (%.2f%%)\n", sleep_time, tmp);
+    tmp = (float)active_time / (float)total_time * 100;
+    printf(" Time in active state:  %lus (%.2f%%)\n", active_time, tmp);
+    tmp = (float)unknown_time / (float)total_time * 100;
+    printf(" Time in unknown state: %lus (%.2f%%)\n", unknown_time, tmp);
+}
+
+static void ender(int s)
+{
+    endit = 1;
+}
+
+static void usage(void)
+{
+    puts("usage: dslm [-w <time>] <disk>");
+    exit(0);
+}
+
+int main(int argc, char **argv)
+{
+    int fd;
+    char *disk = 0;
+    int settle_time = 60;
+
+    /* Parse the simple command-line */
+    if (argc == 2)
+	disk = argv[1];
+    else if (argc == 4) {
+	settle_time = atoi(argv[2]);
+	disk = argv[3];
+    } else
+	usage();
+
+    if (!(fd = open(disk, O_RDONLY|O_NONBLOCK))) {
+	printf("Can't open %s, because: %s\n", disk, strerror(errno));
+	exit(-1);
+    }
+
+    if (settle_time) {
+	printf("Waiting %d seconds for the system to settle down to "
+	       "'normal'\n", settle_time);
+	sleep(settle_time);
+    } else
+	puts("Not waiting for system to settle down");
+
+    signal(SIGINT, ender);
+
+    measure(fd);
+
+    close(fd);
+
+    return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/Documentation/laptops/laptop-mode.txt linux-libre-2.6.34-gnu1/Documentation/laptops/laptop-mode.txt
--- linux-libre-2.6.33-gnu1/Documentation/laptops/laptop-mode.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/laptops/laptop-mode.txt	2010-05-16 17:17:36.000000000 -0400
@@ -779,172 +779,4 @@ Monitoring tool
 ---------------
 
 Bartek Kania submitted this, it can be used to measure how much time your disk
-spends spun up/down.
-
----------------------------dslm.c BEGIN-----------------------------------------
-/*
- * Simple Disk Sleep Monitor
- *  by Bartek Kania
- * Licenced under the GPL
- */
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <linux/hdreg.h>
-
-#ifdef DEBUG
-#define D(x) x
-#else
-#define D(x)
-#endif
-
-int endit = 0;
-
-/* Check if the disk is in powersave-mode
- * Most of the code is stolen from hdparm.
- * 1 = active, 0 = standby/sleep, -1 = unknown */
-int check_powermode(int fd)
-{
-    unsigned char args[4] = {WIN_CHECKPOWERMODE1,0,0,0};
-    int state;
-
-    if (ioctl(fd, HDIO_DRIVE_CMD, &args)
-	&& (args[0] = WIN_CHECKPOWERMODE2) /* try again with 0x98 */
-	&& ioctl(fd, HDIO_DRIVE_CMD, &args)) {
-	if (errno != EIO || args[0] != 0 || args[1] != 0) {
-	    state = -1; /* "unknown"; */
-	} else
-	    state = 0; /* "sleeping"; */
-    } else {
-	state = (args[2] == 255) ? 1 : 0;
-    }
-    D(printf(" drive state is:  %d\n", state));
-
-    return state;
-}
-
-char *state_name(int i)
-{
-    if (i == -1) return "unknown";
-    if (i == 0) return "sleeping";
-    if (i == 1) return "active";
-
-    return "internal error";
-}
-
-char *myctime(time_t time)
-{
-    char *ts = ctime(&time);
-    ts[strlen(ts) - 1] = 0;
-
-    return ts;
-}
-
-void measure(int fd)
-{
-    time_t start_time;
-    int last_state;
-    time_t last_time;
-    int curr_state;
-    time_t curr_time = 0;
-    time_t time_diff;
-    time_t active_time = 0;
-    time_t sleep_time = 0;
-    time_t unknown_time = 0;
-    time_t total_time = 0;
-    int changes = 0;
-    float tmp;
-
-    printf("Starting measurements\n");
-
-    last_state = check_powermode(fd);
-    start_time = last_time = time(0);
-    printf("  System is in state %s\n\n", state_name(last_state));
-
-    while(!endit) {
-	sleep(1);
-	curr_state = check_powermode(fd);
-
-	if (curr_state != last_state || endit) {
-	    changes++;
-	    curr_time = time(0);
-	    time_diff = curr_time - last_time;
-
-	    if (last_state == 1) active_time += time_diff;
-	    else if (last_state == 0) sleep_time += time_diff;
-	    else unknown_time += time_diff;
-
-	    last_state = curr_state;
-	    last_time = curr_time;
-
-	    printf("%s: State-change to %s\n", myctime(curr_time),
-		   state_name(curr_state));
-	}
-    }
-    changes--; /* Compensate for SIGINT */
-
-    total_time = time(0) - start_time;
-    printf("\nTotal running time:  %lus\n", curr_time - start_time);
-    printf(" State changed %d times\n", changes);
-
-    tmp = (float)sleep_time / (float)total_time * 100;
-    printf(" Time in sleep state:   %lus (%.2f%%)\n", sleep_time, tmp);
-    tmp = (float)active_time / (float)total_time * 100;
-    printf(" Time in active state:  %lus (%.2f%%)\n", active_time, tmp);
-    tmp = (float)unknown_time / (float)total_time * 100;
-    printf(" Time in unknown state: %lus (%.2f%%)\n", unknown_time, tmp);
-}
-
-void ender(int s)
-{
-    endit = 1;
-}
-
-void usage()
-{
-    puts("usage: dslm [-w <time>] <disk>");
-    exit(0);
-}
-
-int main(int argc, char **argv)
-{
-    int fd;
-    char *disk = 0;
-    int settle_time = 60;
-
-    /* Parse the simple command-line */
-    if (argc == 2)
-	disk = argv[1];
-    else if (argc == 4) {
-	settle_time = atoi(argv[2]);
-	disk = argv[3];
-    } else
-	usage();
-
-    if (!(fd = open(disk, O_RDONLY|O_NONBLOCK))) {
-	printf("Can't open %s, because: %s\n", disk, strerror(errno));
-	exit(-1);
-    }
-
-    if (settle_time) {
-	printf("Waiting %d seconds for the system to settle down to "
-	       "'normal'\n", settle_time);
-	sleep(settle_time);
-    } else
-	puts("Not waiting for system to settle down");
-
-    signal(SIGINT, ender);
-
-    measure(fd);
-
-    close(fd);
-
-    return 0;
-}
----------------------------dslm.c END-------------------------------------------
+spends spun up/down.  See Documentation/laptops/dslm.c
diff -druNp linux-libre-2.6.33-gnu1/Documentation/laptops/Makefile linux-libre-2.6.34-gnu1/Documentation/laptops/Makefile
--- linux-libre-2.6.33-gnu1/Documentation/laptops/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/laptops/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,8 @@
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+obj- := dummy.o
+
+# List of programs to build
+hostprogs-y := dslm
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
diff -druNp linux-libre-2.6.33-gnu1/Documentation/laptops/thinkpad-acpi.txt linux-libre-2.6.34-gnu1/Documentation/laptops/thinkpad-acpi.txt
--- linux-libre-2.6.33-gnu1/Documentation/laptops/thinkpad-acpi.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/laptops/thinkpad-acpi.txt	2010-05-16 17:17:36.000000000 -0400
@@ -650,6 +650,10 @@ LCD, CRT or DVI (if available). The foll
 	echo expand_toggle > /proc/acpi/ibm/video
 	echo video_switch > /proc/acpi/ibm/video
 
+NOTE: Access to this feature is restricted to processes owning the
+CAP_SYS_ADMIN capability for safety reasons, as it can interact badly
+enough with some versions of X.org to crash it.
+
 Each video output device can be enabled or disabled individually.
 Reading /proc/acpi/ibm/video shows the status of each device.
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/lguest/lguest.c linux-libre-2.6.34-gnu1/Documentation/lguest/lguest.c
--- linux-libre-2.6.33-gnu1/Documentation/lguest/lguest.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/lguest/lguest.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,6 @@
 #include <sys/uio.h>
 #include <termios.h>
 #include <getopt.h>
-#include <zlib.h>
 #include <assert.h>
 #include <sched.h>
 #include <limits.h>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/Makefile linux-libre-2.6.34-gnu1/Documentation/Makefile
--- linux-libre-2.6.33-gnu1/Documentation/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,3 +1,3 @@
 obj-m := DocBook/ accounting/ auxdisplay/ connector/ \
-	filesystems/configfs/ ia64/ networking/ \
-	pcmcia/ spi/ video4linux/ vm/ watchdog/src/
+	filesystems/ filesystems/configfs/ ia64/ laptops/ networking/ \
+	pcmcia/ spi/ timers/ video4linux/ vm/ watchdog/src/
diff -druNp linux-libre-2.6.33-gnu1/Documentation/memory-barriers.txt linux-libre-2.6.34-gnu1/Documentation/memory-barriers.txt
--- linux-libre-2.6.33-gnu1/Documentation/memory-barriers.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/memory-barriers.txt	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
 			 ============================
 
 By: David Howells <dhowells@redhat.com>
+    Paul E. McKenney <paulmck@linux.vnet.ibm.com>
 
 Contents:
 
@@ -60,6 +61,10 @@ Contents:
 
      - And then there's the Alpha.
 
+ (*) Example uses.
+
+     - Circular buffers.
+
  (*) References.
 
 
@@ -2226,6 +2231,21 @@ The Alpha defines the Linux kernel's mem
 See the subsection on "Cache Coherency" above.
 
 
+============
+EXAMPLE USES
+============
+
+CIRCULAR BUFFERS
+----------------
+
+Memory barriers can be used to implement circular buffering without the need
+of a lock to serialise the producer with the consumer.  See:
+
+	Documentation/circular-buffers.txt
+
+for details.
+
+
 ==========
 REFERENCES
 ==========
diff -druNp linux-libre-2.6.33-gnu1/Documentation/networking/00-INDEX linux-libre-2.6.34-gnu1/Documentation/networking/00-INDEX
--- linux-libre-2.6.33-gnu1/Documentation/networking/00-INDEX	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/networking/00-INDEX	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,8 @@ cs89x0.txt
 	- the Crystal LAN (CS8900/20-based) Ethernet ISA adapter driver
 cxacru.txt
 	- Conexant AccessRunner USB ADSL Modem
+cxacru-cf.py
+	- Conexant AccessRunner USB ADSL Modem configuration file parser
 de4x5.txt
 	- the Digital EtherWORKS DE4?? and DE5?? PCI Ethernet driver
 decnet.txt
diff -druNp linux-libre-2.6.33-gnu1/Documentation/networking/cxacru-cf.py linux-libre-2.6.34-gnu1/Documentation/networking/cxacru-cf.py
--- linux-libre-2.6.33-gnu1/Documentation/networking/cxacru-cf.py	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/networking/cxacru-cf.py	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+# Copyright 2009 Simon Arlott
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You 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.
+#
+# Usage: cxacru-cf.py < cxacru-cf.bin
+# Output: values string suitable for the sysfs adsl_config attribute
+#
+# Warning: cxacru-cf.bin with MD5 hash cdbac2689969d5ed5d4850f117702110
+# contains mis-aligned values which will stop the modem from being able
+# to make a connection. If the first and last two bytes are removed then
+# the values become valid, but the modulation will be forced to ANSI
+# T1.413 only which may not be appropriate.
+#
+# The original binary format is a packed list of le32 values.
+
+import sys
+import struct
+
+i = 0
+while True:
+	buf = sys.stdin.read(4)
+
+	if len(buf) == 0:
+		break
+	elif len(buf) != 4:
+		sys.stdout.write("\n")
+		sys.stderr.write("Error: read {0} not 4 bytes\n".format(len(buf)))
+		sys.exit(1)
+
+	if i > 0:
+		sys.stdout.write(" ")
+	sys.stdout.write("{0:x}={1}".format(i, struct.unpack("<I", buf)[0]))
+	i += 1
+
+sys.stdout.write("\n")
diff -druNp linux-libre-2.6.33-gnu1/Documentation/networking/cxacru.txt linux-libre-2.6.34-gnu1/Documentation/networking/cxacru.txt
--- linux-libre-2.6.33-gnu1/Documentation/networking/cxacru.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/networking/cxacru.txt	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,12 @@ While it is capable of managing/maintain
 module loaded, the device will sometimes stop responding after unloading the
 driver and it is necessary to unplug/remove power to the device to fix this.
 
+Note: support for cxacru-cf.bin has been removed. It was not loaded correctly
+so it had no effect on the device configuration. Fixing it could have stopped
+existing devices working when an invalid configuration is supplied.
+
+There is a script cxacru-cf.py to convert an existing file to the sysfs form.
+
 Detected devices will appear as ATM devices named "cxacru". In /sys/class/atm/
 these are directories named cxacruN where N is the device number. A symlink
 named device points to the USB interface device's directory which contains
@@ -15,6 +21,15 @@ several sysfs attribute files for retrie
 * adsl_headend_environment
 	Information about the remote headend.
 
+* adsl_config
+	Configuration writing interface.
+	Write parameters in hexadecimal format <index>=<value>,
+	separated by whitespace, e.g.:
+		"1=0 a=5"
+	Up to 7 parameters at a time will be sent and the modem will restart
+	the ADSL connection when any value is set. These are logged for future
+	reference.
+
 * downstream_attenuation (dB)
 * downstream_bits_per_frame
 * downstream_rate (kbps)
@@ -61,6 +76,7 @@ several sysfs attribute files for retrie
 * mac_address
 
 * modulation
+	"" (when not connected)
 	"ANSI T1.413"
 	"ITU-T G.992.1 (G.DMT)"
 	"ITU-T G.992.2 (G.LITE)"
diff -druNp linux-libre-2.6.33-gnu1/Documentation/networking/dccp.txt linux-libre-2.6.34-gnu1/Documentation/networking/dccp.txt
--- linux-libre-2.6.33-gnu1/Documentation/networking/dccp.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/networking/dccp.txt	2010-05-16 17:17:36.000000000 -0400
@@ -58,8 +58,10 @@ DCCP_SOCKOPT_GET_CUR_MPS is read-only an
 size (application payload size) in bytes, see RFC 4340, section 14.
 
 DCCP_SOCKOPT_AVAILABLE_CCIDS is also read-only and returns the list of CCIDs
-supported by the endpoint (see include/linux/dccp.h for symbolic constants).
-The caller needs to provide a sufficiently large (> 2) array of type uint8_t.
+supported by the endpoint. The option value is an array of type uint8_t whose
+size is passed as option length. The minimum array size is 4 elements, the
+value returned in the optlen argument always reflects the true number of
+built-in CCIDs.
 
 DCCP_SOCKOPT_CCID is write-only and sets both the TX and RX CCIDs at the same
 time, combining the operation of the next two socket options. This option is
diff -druNp linux-libre-2.6.33-gnu1/Documentation/networking/ip-sysctl.txt linux-libre-2.6.34-gnu1/Documentation/networking/ip-sysctl.txt
--- linux-libre-2.6.33-gnu1/Documentation/networking/ip-sysctl.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/networking/ip-sysctl.txt	2010-05-16 17:17:36.000000000 -0400
@@ -487,6 +487,30 @@ tcp_dma_copybreak - INTEGER
 	and CONFIG_NET_DMA is enabled.
 	Default: 4096
 
+tcp_thin_linear_timeouts - BOOLEAN
+	Enable dynamic triggering of linear timeouts for thin streams.
+	If set, a check is performed upon retransmission by timeout to
+	determine if the stream is thin (less than 4 packets in flight).
+	As long as the stream is found to be thin, up to 6 linear
+	timeouts may be performed before exponential backoff mode is
+	initiated. This improves retransmission latency for
+	non-aggressive thin streams, often found to be time-dependent.
+	For more information on thin streams, see
+	Documentation/networking/tcp-thin.txt
+	Default: 0
+
+tcp_thin_dupack - BOOLEAN
+	Enable dynamic triggering of retransmissions after one dupACK
+	for thin streams. If set, a check is performed upon reception
+	of a dupACK to determine if the stream is thin (less than 4
+	packets in flight). As long as the stream is found to be thin,
+	data is retransmitted on the first received dupACK. This
+	improves retransmission latency for non-aggressive thin
+	streams, often found to be time-dependent.
+	For more information on thin streams, see
+	Documentation/networking/tcp-thin.txt
+	Default: 0
+
 UDP variables:
 
 udp_mem - vector of 3 INTEGERs: min, pressure, max
@@ -692,6 +716,25 @@ proxy_arp - BOOLEAN
 	conf/{all,interface}/proxy_arp is set to TRUE,
 	it will be disabled otherwise
 
+proxy_arp_pvlan - BOOLEAN
+	Private VLAN proxy arp.
+	Basically allow proxy arp replies back to the same interface
+	(from which the ARP request/solicitation was received).
+
+	This is done to support (ethernet) switch features, like RFC
+	3069, where the individual ports are NOT allowed to
+	communicate with each other, but they are allowed to talk to
+	the upstream router.  As described in RFC 3069, it is possible
+	to allow these hosts to communicate through the upstream
+	router by proxy_arp'ing. Don't need to be used together with
+	proxy_arp.
+
+	This technology is known by different names:
+	  In RFC 3069 it is called VLAN Aggregation.
+	  Cisco and Allied Telesyn call it Private VLAN.
+	  Hewlett-Packard call it Source-Port filtering or port-isolation.
+	  Ericsson call it MAC-Forced Forwarding (RFC Draft).
+
 shared_media - BOOLEAN
 	Send(router) or accept(host) RFC1620 shared media redirects.
 	Overrides ip_secure_redirects.
@@ -833,9 +876,18 @@ arp_notify - BOOLEAN
 	    or hardware address changes.
 
 arp_accept - BOOLEAN
-	Define behavior when gratuitous arp replies are received:
-	0 - drop gratuitous arp frames
-	1 - accept gratuitous arp frames
+	Define behavior for gratuitous ARP frames who's IP is not
+	already present in the ARP table:
+	0 - don't create new entries in the ARP table
+	1 - create new entries in the ARP table
+
+	Both replies and requests type gratuitous arp will trigger the
+	ARP table to be updated, if this setting is on.
+
+	If the ARP table already contains the IP address of the
+	gratuitous arp frame, the arp table will be updated regardless
+	if this setting is on or off.
+
 
 app_solicit - INTEGER
 	The maximum number of probes to send to the user space ARP daemon
diff -druNp linux-libre-2.6.33-gnu1/Documentation/networking/ixgbevf.txt linux-libre-2.6.34-gnu1/Documentation/networking/ixgbevf.txt
--- linux-libre-2.6.33-gnu1/Documentation/networking/ixgbevf.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/networking/ixgbevf.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,90 @@
+Linux* Base Driver for Intel(R) Network Connection
+==================================================
+
+November 24, 2009
+
+Contents
+========
+
+- In This Release
+- Identifying Your Adapter
+- Known Issues/Troubleshooting
+- Support
+
+In This Release
+===============
+
+This file describes the ixgbevf Linux* Base Driver for Intel Network
+Connection.
+
+The ixgbevf driver supports 82599-based virtual function devices that can only
+be activated on kernels with CONFIG_PCI_IOV enabled.
+
+The ixgbevf driver supports virtual functions generated by the ixgbe driver
+with a max_vfs value of 1 or greater.
+
+The guest OS loading the ixgbevf driver must support MSI-X interrupts.
+
+VLANs: There is a limit of a total of 32 shared VLANs to 1 or more VFs.
+
+Identifying Your Adapter
+========================
+
+For more information on how to identify your adapter, go to the Adapter &
+Driver ID Guide at:
+
+    http://support.intel.com/support/network/sb/CS-008441.htm
+
+Known Issues/Troubleshooting
+============================
+
+  Unloading Physical Function (PF) Driver Causes System Reboots When VM is
+  Running and VF is Loaded on the VM
+  ------------------------------------------------------------------------
+  Do not unload the PF driver (ixgbe) while VFs are assigned to guests.
+
+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://sourceforge.net/projects/e1000
+
+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
+
+License
+=======
+
+Intel 10 Gigabit 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".
+
+Trademarks
+==========
+
+Intel, Itanium, and Pentium are trademarks or registered trademarks of
+Intel Corporation or its subsidiaries in the United States and other
+countries.
+
+* Other names and brands may be claimed as the property of others.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/networking/Makefile linux-libre-2.6.34-gnu1/Documentation/networking/Makefile
--- linux-libre-2.6.33-gnu1/Documentation/networking/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/networking/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -6,3 +6,5 @@ hostprogs-y := ifenslave
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
+
+obj-m := timestamping/
diff -druNp linux-libre-2.6.33-gnu1/Documentation/networking/packet_mmap.txt linux-libre-2.6.34-gnu1/Documentation/networking/packet_mmap.txt
--- linux-libre-2.6.33-gnu1/Documentation/networking/packet_mmap.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/networking/packet_mmap.txt	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
 + ABSTRACT
 --------------------------------------------------------------------------------
 
-This file documents the CONFIG_PACKET_MMAP option available with the PACKET
+This file documents the mmap() facility available with the PACKET
 socket interface on 2.4 and 2.6 kernels. This type of sockets is used for 
 capture network traffic with utilities like tcpdump or any other that needs
 raw access to network interface.
@@ -44,7 +44,7 @@ enabled. For transmission, check the MTU
 supported by devices of your network.
 
 --------------------------------------------------------------------------------
-+ How to use CONFIG_PACKET_MMAP to improve capture process
++ How to use mmap() to improve capture process
 --------------------------------------------------------------------------------
 
 From the user standpoint, you should use the higher level libpcap library, which
@@ -64,7 +64,7 @@ the low level details or want to improve
 support.
 
 --------------------------------------------------------------------------------
-+ How to use CONFIG_PACKET_MMAP directly to improve capture process
++ How to use mmap() directly to improve capture process
 --------------------------------------------------------------------------------
 
 From the system calls stand point, the use of PACKET_MMAP involves
@@ -105,7 +105,7 @@ also the mapping of the circular buffer
 the use of this buffer.
 
 --------------------------------------------------------------------------------
-+ How to use CONFIG_PACKET_MMAP directly to improve transmission process
++ How to use mmap() directly to improve transmission process
 --------------------------------------------------------------------------------
 Transmission process is similar to capture as shown below.
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/networking/regulatory.txt linux-libre-2.6.34-gnu1/Documentation/networking/regulatory.txt
--- linux-libre-2.6.33-gnu1/Documentation/networking/regulatory.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/networking/regulatory.txt	2010-05-16 17:17:36.000000000 -0400
@@ -188,3 +188,27 @@ Then in some part of your code after you
 		       &mydriver_jp_regdom.reg_rules[i],
 		       sizeof(struct ieee80211_reg_rule));
 	regulatory_struct_hint(rd);
+
+Statically compiled regulatory database
+---------------------------------------
+
+In most situations the userland solution using CRDA as described
+above is the preferred solution.  However in some cases a set of
+rules built into the kernel itself may be desirable.  To account
+for this situation, a configuration option has been provided
+(i.e. CONFIG_CFG80211_INTERNAL_REGDB).  With this option enabled,
+the wireless database information contained in net/wireless/db.txt is
+used to generate a data structure encoded in net/wireless/regdb.c.
+That option also enables code in net/wireless/reg.c which queries
+the data in regdb.c as an alternative to using CRDA.
+
+The file net/wireless/db.txt should be kept up-to-date with the db.txt
+file available in the git repository here:
+
+    git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-regdb.git
+
+Again, most users in most situations should be using the CRDA package
+provided with their distribution, and in most other situations users
+should be building and using CRDA on their own rather than using
+this option.  If you are not absolutely sure that you should be using
+CONFIG_CFG80211_INTERNAL_REGDB then _DO_NOT_USE_IT_.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/networking/skfp.txt linux-libre-2.6.34-gnu1/Documentation/networking/skfp.txt
--- linux-libre-2.6.33-gnu1/Documentation/networking/skfp.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/networking/skfp.txt	2010-05-16 17:17:36.000000000 -0400
@@ -68,7 +68,7 @@ Compaq adapters (not tested):
 =======================
 
 From v2.01 on, the driver is integrated in the linux kernel sources.
-Therefor, the installation is the same as for any other adapter
+Therefore, the installation is the same as for any other adapter
 supported by the kernel.
 Refer to the manual of your distribution about the installation
 of network adapters.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/networking/stmmac.txt linux-libre-2.6.34-gnu1/Documentation/networking/stmmac.txt
--- linux-libre-2.6.33-gnu1/Documentation/networking/stmmac.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/networking/stmmac.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,143 @@
+       STMicroelectronics 10/100/1000 Synopsys Ethernet driver
+
+Copyright (C) 2007-2010  STMicroelectronics Ltd
+Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+
+This is the driver for the MAC 10/100/1000 on-chip Ethernet controllers
+(Synopsys IP blocks); it has been fully tested on STLinux platforms.
+
+Currently this network device driver is for all STM embedded MAC/GMAC
+(7xxx SoCs).
+
+DWC Ether MAC 10/100/1000 Universal version 3.41a and DWC Ether MAC 10/100
+Universal version 4.0 have been used for developing the first code
+implementation.
+
+Please, for more information also visit: www.stlinux.com
+
+1) Kernel Configuration
+The kernel configuration option is STMMAC_ETH:
+ Device Drivers ---> Network device support ---> Ethernet (1000 Mbit) --->
+ STMicroelectronics 10/100/1000 Ethernet driver (STMMAC_ETH)
+
+2) Driver parameters list:
+	debug: message level (0: no output, 16: all);
+	phyaddr: to manually provide the physical address to the PHY device;
+	dma_rxsize: DMA rx ring size;
+	dma_txsize: DMA tx ring size;
+	buf_sz: DMA buffer size;
+	tc: control the HW FIFO threshold;
+	tx_coe: Enable/Disable Tx Checksum Offload engine;
+	watchdog: transmit timeout (in milliseconds);
+	flow_ctrl: Flow control ability [on/off];
+	pause: Flow Control Pause Time;
+	tmrate: timer period (only if timer optimisation is configured).
+
+3) Command line options
+Driver parameters can be also passed in command line by using:
+	stmmaceth=dma_rxsize:128,dma_txsize:512
+
+4) Driver information and notes
+
+4.1) Transmit process
+The xmit method is invoked when the kernel needs to transmit a packet; it sets
+the descriptors in the ring and informs the DMA engine that there is a packet
+ready to be transmitted.
+Once the controller has finished transmitting the packet, an interrupt is
+triggered; So the driver will be able to release the socket buffers.
+By default, the driver sets the NETIF_F_SG bit in the features field of the
+net_device structure enabling the scatter/gather feature.
+
+4.2) Receive process
+When one or more packets are received, an interrupt happens. The interrupts
+are not queued so the driver has to scan all the descriptors in the ring during
+the receive process.
+This is based on NAPI so the interrupt handler signals only if there is work to be
+done, and it exits.
+Then the poll method will be scheduled at some future point.
+The incoming packets are stored, by the DMA, in a list of pre-allocated socket
+buffers in order to avoid the memcpy (Zero-copy).
+
+4.3) Timer-Driver Interrupt
+Instead of having the device that asynchronously notifies the frame receptions, the
+driver configures a timer to generate an interrupt at regular intervals.
+Based on the granularity of the timer, the frames that are received by the device
+will experience different levels of latency. Some NICs have dedicated timer
+device to perform this task. STMMAC can use either the RTC device or the TMU
+channel 2  on STLinux platforms.
+The timers frequency can be passed to the driver as parameter; when change it,
+take care of both hardware capability and network stability/performance impact.
+Several performance tests on STM platforms showed this optimisation allows to spare
+the CPU while having the maximum throughput.
+
+4.4) WOL
+Wake up on Lan feature through Magic Frame is only supported for the GMAC
+core.
+
+4.5) DMA descriptors
+Driver handles both normal and enhanced descriptors. The latter has been only
+tested on DWC Ether MAC 10/100/1000 Universal version 3.41a.
+
+4.6) Ethtool support
+Ethtool is supported. Driver statistics and internal errors can be taken using:
+ethtool -S ethX command. It is possible to dump registers etc.
+
+4.7) Jumbo and Segmentation Offloading
+Jumbo frames are supported and tested for the GMAC.
+The GSO has been also added but it's performed in software.
+LRO is not supported.
+
+4.8) Physical
+The driver is compatible with PAL to work with PHY and GPHY devices.
+
+4.9) Platform information
+Several information came from the platform; please refer to the
+driver's Header file in include/linux directory.
+
+struct plat_stmmacenet_data {
+        int bus_id;
+        int pbl;
+        int has_gmac;
+        void (*fix_mac_speed)(void *priv, unsigned int speed);
+        void (*bus_setup)(unsigned long ioaddr);
+#ifdef CONFIG_STM_DRIVERS
+        struct stm_pad_config *pad_config;
+#endif
+        void *bsp_priv;
+};
+
+Where:
+- pbl (Programmable Burst Length) is maximum number of
+  beats to be transferred in one DMA transaction.
+  GMAC also enables the 4xPBL by default.
+- fix_mac_speed and bus_setup are used to configure internal target
+  registers (on STM platforms);
+- has_gmac: GMAC core is on board (get it at run-time in the next step);
+- bus_id: bus identifier.
+
+struct plat_stmmacphy_data {
+        int bus_id;
+        int phy_addr;
+        unsigned int phy_mask;
+        int interface;
+        int (*phy_reset)(void *priv);
+        void *priv;
+};
+
+Where:
+- bus_id: bus identifier;
+- phy_addr: physical address used for the attached phy device;
+            set it to -1 to get it at run-time;
+- interface: physical MII interface mode;
+- phy_reset: hook to reset HW function.
+
+TODO:
+- Continue to make the driver more generic and suitable for other Synopsys
+  Ethernet controllers used on other architectures (i.e. ARM).
+- 10G controllers are not supported.
+- MAC uses Normal descriptors and GMAC uses enhanced ones.
+  This is a limit that should be reviewed. MAC could want to
+  use the enhanced structure.
+- Checksumming: Rx/Tx csum is done in HW in case of GMAC only.
+- Review the timer optimisation code to use an embedded device that seems to be
+  available in new chip generations.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/networking/tcp-thin.txt linux-libre-2.6.34-gnu1/Documentation/networking/tcp-thin.txt
--- linux-libre-2.6.33-gnu1/Documentation/networking/tcp-thin.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/networking/tcp-thin.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,47 @@
+Thin-streams and TCP
+====================
+A wide range of Internet-based services that use reliable transport
+protocols display what we call thin-stream properties. This means
+that the application sends data with such a low rate that the
+retransmission mechanisms of the transport protocol are not fully
+effective. In time-dependent scenarios (like online games, control
+systems, stock trading etc.) where the user experience depends
+on the data delivery latency, packet loss can be devastating for
+the service quality. Extreme latencies are caused by TCP's
+dependency on the arrival of new data from the application to trigger
+retransmissions effectively through fast retransmit instead of
+waiting for long timeouts.
+
+After analysing a large number of time-dependent interactive
+applications, we have seen that they often produce thin streams
+and also stay with this traffic pattern throughout its entire
+lifespan. The combination of time-dependency and the fact that the
+streams provoke high latencies when using TCP is unfortunate.
+
+In order to reduce application-layer latency when packets are lost,
+a set of mechanisms has been made, which address these latency issues
+for thin streams. In short, if the kernel detects a thin stream,
+the retransmission mechanisms are modified in the following manner:
+
+1) If the stream is thin, fast retransmit on the first dupACK.
+2) If the stream is thin, do not apply exponential backoff.
+
+These enhancements are applied only if the stream is detected as
+thin. This is accomplished by defining a threshold for the number
+of packets in flight. If there are less than 4 packets in flight,
+fast retransmissions can not be triggered, and the stream is prone
+to experience high retransmission latencies.
+
+Since these mechanisms are targeted at time-dependent applications,
+they must be specifically activated by the application using the
+TCP_THIN_LINEAR_TIMEOUTS and TCP_THIN_DUPACK IOCTLS or the
+tcp_thin_linear_timeouts and tcp_thin_dupack sysctls. Both
+modifications are turned off by default.
+
+References
+==========
+More information on the modifications, as well as a wide range of
+experimental data can be found here:
+"Improving latency for interactive, thin-stream applications over
+reliable transport"
+http://simula.no/research/nd/publications/Simula.nd.477/simula_pdf_file
diff -druNp linux-libre-2.6.33-gnu1/Documentation/networking/timestamping/Makefile linux-libre-2.6.34-gnu1/Documentation/networking/timestamping/Makefile
--- linux-libre-2.6.33-gnu1/Documentation/networking/timestamping/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/networking/timestamping/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,13 @@
-CPPFLAGS = -I../../../include
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+obj- := dummy.o
 
-timestamping: timestamping.c
+# List of programs to build
+hostprogs-y := timestamping
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
+
+HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include
 
 clean:
 	rm -f timestamping
diff -druNp linux-libre-2.6.33-gnu1/Documentation/networking/timestamping/timestamping.c linux-libre-2.6.34-gnu1/Documentation/networking/timestamping/timestamping.c
--- linux-libre-2.6.33-gnu1/Documentation/networking/timestamping/timestamping.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/networking/timestamping/timestamping.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,9 +41,9 @@
 #include <arpa/inet.h>
 #include <net/if.h>
 
-#include "asm/types.h"
-#include "linux/net_tstamp.h"
-#include "linux/errqueue.h"
+#include <asm/types.h>
+#include <linux/net_tstamp.h>
+#include <linux/errqueue.h>
 
 #ifndef SO_TIMESTAMPING
 # define SO_TIMESTAMPING         37
@@ -164,7 +164,7 @@ static void printpacket(struct msghdr *m
 
 	gettimeofday(&now, 0);
 
-	printf("%ld.%06ld: received %s data, %d bytes from %s, %d bytes control messages\n",
+	printf("%ld.%06ld: received %s data, %d bytes from %s, %zu bytes control messages\n",
 	       (long)now.tv_sec, (long)now.tv_usec,
 	       (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
 	       res,
@@ -173,7 +173,7 @@ static void printpacket(struct msghdr *m
 	for (cmsg = CMSG_FIRSTHDR(msg);
 	     cmsg;
 	     cmsg = CMSG_NXTHDR(msg, cmsg)) {
-		printf("   cmsg len %d: ", cmsg->cmsg_len);
+		printf("   cmsg len %zu: ", cmsg->cmsg_len);
 		switch (cmsg->cmsg_level) {
 		case SOL_SOCKET:
 			printf("SOL_SOCKET ");
@@ -370,7 +370,7 @@ int main(int argc, char **argv)
 	}
 
 	sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
-	if (socket < 0)
+	if (sock < 0)
 		bail("socket");
 
 	memset(&device, 0, sizeof(device));
diff -druNp linux-libre-2.6.33-gnu1/Documentation/networking/timestamping.txt linux-libre-2.6.34-gnu1/Documentation/networking/timestamping.txt
--- linux-libre-2.6.33-gnu1/Documentation/networking/timestamping.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/networking/timestamping.txt	2010-05-16 17:17:36.000000000 -0400
@@ -41,11 +41,12 @@ SOF_TIMESTAMPING_SOFTWARE:     return sy
 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;
-    };
+
+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
@@ -87,12 +88,13 @@ by the network device and will be empty
 SIOCSHWTSTAMP:
 
 Hardware time stamping must also be initialized for each device driver
-that is expected to do hardware time stamping. The parameter is:
+that is expected to do hardware time stamping. The parameter is defined in
+/include/linux/net_tstamp.h as:
 
 struct hwtstamp_config {
-    int flags;           /* no flags defined right now, must be zero */
-    int tx_type;         /* HWTSTAMP_TX_* */
-    int rx_filter;       /* HWTSTAMP_FILTER_* */
+	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
@@ -139,42 +141,56 @@ enum {
 	/* time stamp any incoming packet */
 	HWTSTAMP_FILTER_ALL,
 
-        /* return value: time stamp all packets requested plus some others */
-        HWTSTAMP_FILTER_SOME,
+	/* 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,
 
-        ...
+	/* for the complete list of values, please check
+	 * the include file /include/linux/net_tstamp.h
+	 */
 };
 
 
 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().
+SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with
+the actual values as described in the section on SIOCSHWTSTAMP.
+
+Time stamps for received packets must be stored in the skb. To get a pointer
+to the shared time stamp structure of the skb call skb_hwtstamps(). Then
+set the time stamps in the structure:
+
+struct skb_shared_hwtstamps {
+	/* hardware time stamp transformed into duration
+	 * since arbitrary point in time
+	 */
+	ktime_t	hwtstamp;
+	ktime_t	syststamp; /* hwtstamp transformed to system time base */
+};
 
 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.
+- In hard_start_xmit(), check if skb_tx(skb)->hardware is set no-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.
+  that the driver is doing the time stamping by setting the field
+  skb_tx(skb)->in_progress non-zero. You might want to keep a pointer
+  to the associated skb for the next step and not free the skb. A driver
+  not supporting hardware time stamping doesn't do that. A driver must
+  never touch sk_buff::tstamp! It is used to store software generated
+  time stamps by the network subsystem.
 - 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
+  hardware time stamp. skb_hwtstamp_tx() clones the original skb and
+  adds the timestamps, therefore the original skb has to be freed now.
+  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 set skb_tx(skb)->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.33-gnu1/Documentation/PCI/PCI-DMA-mapping.txt linux-libre-2.6.34-gnu1/Documentation/PCI/PCI-DMA-mapping.txt
--- linux-libre-2.6.33-gnu1/Documentation/PCI/PCI-DMA-mapping.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/PCI/PCI-DMA-mapping.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,766 +0,0 @@
-			Dynamic DMA mapping
-			===================
-
-		 David S. Miller <davem@redhat.com>
-		 Richard Henderson <rth@cygnus.com>
-		  Jakub Jelinek <jakub@redhat.com>
-
-This document describes the DMA mapping system in terms of the pci_
-API.  For a similar API that works for generic devices, see
-DMA-API.txt.
-
-Most of the 64bit platforms have special hardware that translates bus
-addresses (DMA addresses) into physical addresses.  This is similar to
-how page tables and/or a TLB translates virtual addresses to physical
-addresses on a CPU.  This is needed so that e.g. PCI devices can
-access with a Single Address Cycle (32bit DMA address) any page in the
-64bit physical address space.  Previously in Linux those 64bit
-platforms had to set artificial limits on the maximum RAM size in the
-system, so that the virt_to_bus() static scheme works (the DMA address
-translation tables were simply filled on bootup to map each bus
-address to the physical page __pa(bus_to_virt())).
-
-So that Linux can use the dynamic DMA mapping, it needs some help from the
-drivers, namely it has to take into account that DMA addresses should be
-mapped only for the time they are actually used and unmapped after the DMA
-transfer.
-
-The following API will work of course even on platforms where no such
-hardware exists, see e.g. arch/x86/include/asm/pci.h for how it is implemented on
-top of the virt_to_bus interface.
-
-First of all, you should make sure
-
-#include <linux/pci.h>
-
-is in your driver. This file will obtain for you the definition of the
-dma_addr_t (which can hold any valid DMA address for the platform)
-type which should be used everywhere you hold a DMA (bus) address
-returned from the DMA mapping functions.
-
-			 What memory is DMA'able?
-
-The first piece of information you must know is what kernel memory can
-be used with the DMA mapping facilities.  There has been an unwritten
-set of rules regarding this, and this text is an attempt to finally
-write them down.
-
-If you acquired your memory via the page allocator
-(i.e. __get_free_page*()) or the generic memory allocators
-(i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from
-that memory using the addresses returned from those routines.
-
-This means specifically that you may _not_ use the memory/addresses
-returned from vmalloc() for DMA.  It is possible to DMA to the
-_underlying_ memory mapped into a vmalloc() area, but this requires
-walking page tables to get the physical addresses, and then
-translating each of those pages back to a kernel address using
-something like __va().  [ EDIT: Update this when we integrate
-Gerd Knorr's generic code which does this. ]
-
-This rule also means that you may use neither kernel image addresses
-(items in data/text/bss segments), nor module image addresses, nor
-stack addresses for DMA.  These could all be mapped somewhere entirely
-different than the rest of physical memory.  Even if those classes of
-memory could physically work with DMA, you'd need to ensure the I/O
-buffers were cacheline-aligned.  Without that, you'd see cacheline
-sharing problems (data corruption) on CPUs with DMA-incoherent caches.
-(The CPU could write to one word, DMA would write to a different one
-in the same cache line, and one of them could be overwritten.)
-
-Also, this means that you cannot take the return of a kmap()
-call and DMA to/from that.  This is similar to vmalloc().
-
-What about block I/O and networking buffers?  The block I/O and
-networking subsystems make sure that the buffers they use are valid
-for you to DMA from/to.
-
-			DMA addressing limitations
-
-Does your device have any DMA addressing limitations?  For example, is
-your device only capable of driving the low order 24-bits of address
-on the PCI bus for SAC DMA transfers?  If so, you need to inform the
-PCI layer of this fact.
-
-By default, the kernel assumes that your device can address the full
-32-bits in a SAC cycle.  For a 64-bit DAC capable device, this needs
-to be increased.  And for a device with limitations, as discussed in
-the previous paragraph, it needs to be decreased.
-
-pci_alloc_consistent() by default will return 32-bit DMA addresses.
-PCI-X specification requires PCI-X devices to support 64-bit
-addressing (DAC) for all transactions. And at least one platform (SGI
-SN2) requires 64-bit consistent allocations to operate correctly when
-the IO bus is in PCI-X mode. Therefore, like with pci_set_dma_mask(),
-it's good practice to call pci_set_consistent_dma_mask() to set the
-appropriate mask even if your device only supports 32-bit DMA
-(default) and especially if it's a PCI-X device.
-
-For correct operation, you must interrogate the PCI layer in your
-device probe routine to see if the PCI controller on the machine can
-properly support the DMA addressing limitation your device has.  It is
-good style to do this even if your device holds the default setting,
-because this shows that you did think about these issues wrt. your
-device.
-
-The query is performed via a call to pci_set_dma_mask():
-
-	int pci_set_dma_mask(struct pci_dev *pdev, u64 device_mask);
-
-The query for consistent allocations is performed via a call to
-pci_set_consistent_dma_mask():
-
-	int pci_set_consistent_dma_mask(struct pci_dev *pdev, u64 device_mask);
-
-Here, pdev is a pointer to the PCI device struct of your device, and
-device_mask is a bit mask describing which bits of a PCI address your
-device supports.  It returns zero if your card can perform DMA
-properly on the machine given the address mask you provided.
-
-If it returns non-zero, your device cannot perform DMA properly on
-this platform, and attempting to do so will result in undefined
-behavior.  You must either use a different mask, or not use DMA.
-
-This means that in the failure case, you have three options:
-
-1) Use another DMA mask, if possible (see below).
-2) Use some non-DMA mode for data transfer, if possible.
-3) Ignore this device and do not initialize it.
-
-It is recommended that your driver print a kernel KERN_WARNING message
-when you end up performing either #2 or #3.  In this manner, if a user
-of your driver reports that performance is bad or that the device is not
-even detected, you can ask them for the kernel messages to find out
-exactly why.
-
-The standard 32-bit addressing PCI device would do something like
-this:
-
-	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
-		printk(KERN_WARNING
-		       "mydev: No suitable DMA available.\n");
-		goto ignore_this_device;
-	}
-
-Another common scenario is a 64-bit capable device.  The approach
-here is to try for 64-bit DAC addressing, but back down to a
-32-bit mask should that fail.  The PCI platform code may fail the
-64-bit mask not because the platform is not capable of 64-bit
-addressing.  Rather, it may fail in this case simply because
-32-bit SAC addressing is done more efficiently than DAC addressing.
-Sparc64 is one platform which behaves in this way.
-
-Here is how you would handle a 64-bit capable device which can drive
-all 64-bits when accessing streaming DMA:
-
-	int using_dac;
-
-	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
-		using_dac = 1;
-	} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
-		using_dac = 0;
-	} else {
-		printk(KERN_WARNING
-		       "mydev: No suitable DMA available.\n");
-		goto ignore_this_device;
-	}
-
-If a card is capable of using 64-bit consistent allocations as well,
-the case would look like this:
-
-	int using_dac, consistent_using_dac;
-
-	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
-		using_dac = 1;
-	   	consistent_using_dac = 1;
-		pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
-	} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
-		using_dac = 0;
-		consistent_using_dac = 0;
-		pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
-	} else {
-		printk(KERN_WARNING
-		       "mydev: No suitable DMA available.\n");
-		goto ignore_this_device;
-	}
-
-pci_set_consistent_dma_mask() will always be able to set the same or a
-smaller mask as pci_set_dma_mask(). However for the rare case that a
-device driver only uses consistent allocations, one would have to
-check the return value from pci_set_consistent_dma_mask().
-
-Finally, if your device can only drive the low 24-bits of
-address during PCI bus mastering you might do something like:
-
-	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(24))) {
-		printk(KERN_WARNING
-		       "mydev: 24-bit DMA addressing not available.\n");
-		goto ignore_this_device;
-	}
-
-When pci_set_dma_mask() is successful, and returns zero, the PCI layer
-saves away this mask you have provided.  The PCI layer will use this
-information later when you make DMA mappings.
-
-There is a case which we are aware of at this time, which is worth
-mentioning in this documentation.  If your device supports multiple
-functions (for example a sound card provides playback and record
-functions) and the various different functions have _different_
-DMA addressing limitations, you may wish to probe each mask and
-only provide the functionality which the machine can handle.  It
-is important that the last call to pci_set_dma_mask() be for the
-most specific mask.
-
-Here is pseudo-code showing how this might be done:
-
-	#define PLAYBACK_ADDRESS_BITS	DMA_BIT_MASK(32)
-	#define RECORD_ADDRESS_BITS	DMA_BIT_MASK(24)
-
-	struct my_sound_card *card;
-	struct pci_dev *pdev;
-
-	...
-	if (!pci_set_dma_mask(pdev, PLAYBACK_ADDRESS_BITS)) {
-		card->playback_enabled = 1;
-	} else {
-		card->playback_enabled = 0;
-		printk(KERN_WARNING "%s: Playback disabled due to DMA limitations.\n",
-		       card->name);
-	}
-	if (!pci_set_dma_mask(pdev, RECORD_ADDRESS_BITS)) {
-		card->record_enabled = 1;
-	} else {
-		card->record_enabled = 0;
-		printk(KERN_WARNING "%s: Record disabled due to DMA limitations.\n",
-		       card->name);
-	}
-
-A sound card was used as an example here because this genre of PCI
-devices seems to be littered with ISA chips given a PCI front end,
-and thus retaining the 16MB DMA addressing limitations of ISA.
-
-			Types of DMA mappings
-
-There are two types of DMA mappings:
-
-- Consistent DMA mappings which are usually mapped at driver
-  initialization, unmapped at the end and for which the hardware should
-  guarantee that the device and the CPU can access the data
-  in parallel and will see updates made by each other without any
-  explicit software flushing.
-
-  Think of "consistent" as "synchronous" or "coherent".
-
-  The current default is to return consistent memory in the low 32
-  bits of the PCI bus space.  However, for future compatibility you
-  should set the consistent mask even if this default is fine for your
-  driver.
-
-  Good examples of what to use consistent mappings for are:
-
-	- Network card DMA ring descriptors.
-	- SCSI adapter mailbox command data structures.
-	- Device firmware microcode executed out of
-	  main memory.
-
-  The invariant these examples all require is that any CPU store
-  to memory is immediately visible to the device, and vice
-  versa.  Consistent mappings guarantee this.
-
-  IMPORTANT: Consistent DMA memory does not preclude the usage of
-             proper memory barriers.  The CPU may reorder stores to
-	     consistent memory just as it may normal memory.  Example:
-	     if it is important for the device to see the first word
-	     of a descriptor updated before the second, you must do
-	     something like:
-
-		desc->word0 = address;
-		wmb();
-		desc->word1 = DESC_VALID;
-
-             in order to get correct behavior on all platforms.
-
-	     Also, on some platforms your driver may need to flush CPU write
-	     buffers in much the same way as it needs to flush write buffers
-	     found in PCI bridges (such as by reading a register's value
-	     after writing it).
-
-- Streaming DMA mappings which are usually mapped for one DMA transfer,
-  unmapped right after it (unless you use pci_dma_sync_* below) and for which
-  hardware can optimize for sequential accesses.
-
-  This of "streaming" as "asynchronous" or "outside the coherency
-  domain".
-
-  Good examples of what to use streaming mappings for are:
-
-	- Networking buffers transmitted/received by a device.
-	- Filesystem buffers written/read by a SCSI device.
-
-  The interfaces for using this type of mapping were designed in
-  such a way that an implementation can make whatever performance
-  optimizations the hardware allows.  To this end, when using
-  such mappings you must be explicit about what you want to happen.
-
-Neither type of DMA mapping has alignment restrictions that come
-from PCI, although some devices may have such restrictions.
-Also, systems with caches that aren't DMA-coherent will work better
-when the underlying buffers don't share cache lines with other data.
-
-
-		 Using Consistent DMA mappings.
-
-To allocate and map large (PAGE_SIZE or so) consistent DMA regions,
-you should do:
-
-	dma_addr_t dma_handle;
-
-	cpu_addr = pci_alloc_consistent(pdev, size, &dma_handle);
-
-where pdev is a struct pci_dev *. This may be called in interrupt context.
-You should use dma_alloc_coherent (see DMA-API.txt) for buses
-where devices don't have struct pci_dev (like ISA, EISA).
-
-This argument is needed because the DMA translations may be bus
-specific (and often is private to the bus which the device is attached
-to).
-
-Size is the length of the region you want to allocate, in bytes.
-
-This routine will allocate RAM for that region, so it acts similarly to
-__get_free_pages (but takes size instead of a page order).  If your
-driver needs regions sized smaller than a page, you may prefer using
-the pci_pool interface, described below.
-
-The consistent DMA mapping interfaces, for non-NULL pdev, will by
-default return a DMA address which is SAC (Single Address Cycle)
-addressable.  Even if the device indicates (via PCI dma mask) that it
-may address the upper 32-bits and thus perform DAC cycles, consistent
-allocation will only return > 32-bit PCI addresses for DMA if the
-consistent dma mask has been explicitly changed via
-pci_set_consistent_dma_mask().  This is true of the pci_pool interface
-as well.
-
-pci_alloc_consistent returns two values: the virtual address which you
-can use to access it from the CPU and dma_handle which you pass to the
-card.
-
-The cpu return address and the DMA bus master address are both
-guaranteed to be aligned to the smallest PAGE_SIZE order which
-is greater than or equal to the requested size.  This invariant
-exists (for example) to guarantee that if you allocate a chunk
-which is smaller than or equal to 64 kilobytes, the extent of the
-buffer you receive will not cross a 64K boundary.
-
-To unmap and free such a DMA region, you call:
-
-	pci_free_consistent(pdev, size, cpu_addr, dma_handle);
-
-where pdev, size are the same as in the above call and cpu_addr and
-dma_handle are the values pci_alloc_consistent returned to you.
-This function may not be called in interrupt context.
-
-If your driver needs lots of smaller memory regions, you can write
-custom code to subdivide pages returned by pci_alloc_consistent,
-or you can use the pci_pool API to do that.  A pci_pool is like
-a kmem_cache, but it uses pci_alloc_consistent not __get_free_pages.
-Also, it understands common hardware constraints for alignment,
-like queue heads needing to be aligned on N byte boundaries.
-
-Create a pci_pool like this:
-
-	struct pci_pool *pool;
-
-	pool = pci_pool_create(name, pdev, size, align, alloc);
-
-The "name" is for diagnostics (like a kmem_cache name); pdev and size
-are as above.  The device's hardware alignment requirement for this
-type of data is "align" (which is expressed in bytes, and must be a
-power of two).  If your device has no boundary crossing restrictions,
-pass 0 for alloc; passing 4096 says memory allocated from this pool
-must not cross 4KByte boundaries (but at that time it may be better to
-go for pci_alloc_consistent directly instead).
-
-Allocate memory from a pci pool like this:
-
-	cpu_addr = pci_pool_alloc(pool, flags, &dma_handle);
-
-flags are SLAB_KERNEL if blocking is permitted (not in_interrupt nor
-holding SMP locks), SLAB_ATOMIC otherwise.  Like pci_alloc_consistent,
-this returns two values, cpu_addr and dma_handle.
-
-Free memory that was allocated from a pci_pool like this:
-
-	pci_pool_free(pool, cpu_addr, dma_handle);
-
-where pool is what you passed to pci_pool_alloc, and cpu_addr and
-dma_handle are the values pci_pool_alloc returned. This function
-may be called in interrupt context.
-
-Destroy a pci_pool by calling:
-
-	pci_pool_destroy(pool);
-
-Make sure you've called pci_pool_free for all memory allocated
-from a pool before you destroy the pool. This function may not
-be called in interrupt context.
-
-			DMA Direction
-
-The interfaces described in subsequent portions of this document
-take a DMA direction argument, which is an integer and takes on
-one of the following values:
-
- PCI_DMA_BIDIRECTIONAL
- PCI_DMA_TODEVICE
- PCI_DMA_FROMDEVICE
- PCI_DMA_NONE
-
-One should provide the exact DMA direction if you know it.
-
-PCI_DMA_TODEVICE means "from main memory to the PCI device"
-PCI_DMA_FROMDEVICE means "from the PCI device to main memory"
-It is the direction in which the data moves during the DMA
-transfer.
-
-You are _strongly_ encouraged to specify this as precisely
-as you possibly can.
-
-If you absolutely cannot know the direction of the DMA transfer,
-specify PCI_DMA_BIDIRECTIONAL.  It means that the DMA can go in
-either direction.  The platform guarantees that you may legally
-specify this, and that it will work, but this may be at the
-cost of performance for example.
-
-The value PCI_DMA_NONE is to be used for debugging.  One can
-hold this in a data structure before you come to know the
-precise direction, and this will help catch cases where your
-direction tracking logic has failed to set things up properly.
-
-Another advantage of specifying this value precisely (outside of
-potential platform-specific optimizations of such) is for debugging.
-Some platforms actually have a write permission boolean which DMA
-mappings can be marked with, much like page protections in the user
-program address space.  Such platforms can and do report errors in the
-kernel logs when the PCI controller hardware detects violation of the
-permission setting.
-
-Only streaming mappings specify a direction, consistent mappings
-implicitly have a direction attribute setting of
-PCI_DMA_BIDIRECTIONAL.
-
-The SCSI subsystem tells you the direction to use in the
-'sc_data_direction' member of the SCSI command your driver is
-working on.
-
-For Networking drivers, it's a rather simple affair.  For transmit
-packets, map/unmap them with the PCI_DMA_TODEVICE direction
-specifier.  For receive packets, just the opposite, map/unmap them
-with the PCI_DMA_FROMDEVICE direction specifier.
-
-		  Using Streaming DMA mappings
-
-The streaming DMA mapping routines can be called from interrupt
-context.  There are two versions of each map/unmap, one which will
-map/unmap a single memory region, and one which will map/unmap a
-scatterlist.
-
-To map a single region, you do:
-
-	struct pci_dev *pdev = mydev->pdev;
-	dma_addr_t dma_handle;
-	void *addr = buffer->ptr;
-	size_t size = buffer->len;
-
-	dma_handle = pci_map_single(pdev, addr, size, direction);
-
-and to unmap it:
-
-	pci_unmap_single(pdev, dma_handle, size, direction);
-
-You should call pci_unmap_single when the DMA activity is finished, e.g.
-from the interrupt which told you that the DMA transfer is done.
-
-Using cpu pointers like this for single mappings has a disadvantage,
-you cannot reference HIGHMEM memory in this way.  Thus, there is a
-map/unmap interface pair akin to pci_{map,unmap}_single.  These
-interfaces deal with page/offset pairs instead of cpu pointers.
-Specifically:
-
-	struct pci_dev *pdev = mydev->pdev;
-	dma_addr_t dma_handle;
-	struct page *page = buffer->page;
-	unsigned long offset = buffer->offset;
-	size_t size = buffer->len;
-
-	dma_handle = pci_map_page(pdev, page, offset, size, direction);
-
-	...
-
-	pci_unmap_page(pdev, dma_handle, size, direction);
-
-Here, "offset" means byte offset within the given page.
-
-With scatterlists, you map a region gathered from several regions by:
-
-	int i, count = pci_map_sg(pdev, sglist, nents, direction);
-	struct scatterlist *sg;
-
-	for_each_sg(sglist, sg, count, i) {
-		hw_address[i] = sg_dma_address(sg);
-		hw_len[i] = sg_dma_len(sg);
-	}
-
-where nents is the number of entries in the sglist.
-
-The implementation is free to merge several consecutive sglist entries
-into one (e.g. if DMA mapping is done with PAGE_SIZE granularity, any
-consecutive sglist entries can be merged into one provided the first one
-ends and the second one starts on a page boundary - in fact this is a huge
-advantage for cards which either cannot do scatter-gather or have very
-limited number of scatter-gather entries) and returns the actual number
-of sg entries it mapped them to. On failure 0 is returned.
-
-Then you should loop count times (note: this can be less than nents times)
-and use sg_dma_address() and sg_dma_len() macros where you previously
-accessed sg->address and sg->length as shown above.
-
-To unmap a scatterlist, just call:
-
-	pci_unmap_sg(pdev, sglist, nents, direction);
-
-Again, make sure DMA activity has already finished.
-
-PLEASE NOTE:  The 'nents' argument to the pci_unmap_sg call must be
-              the _same_ one you passed into the pci_map_sg call,
-	      it should _NOT_ be the 'count' value _returned_ from the
-              pci_map_sg call.
-
-Every pci_map_{single,sg} call should have its pci_unmap_{single,sg}
-counterpart, because the bus address space is a shared resource (although
-in some ports the mapping is per each BUS so less devices contend for the
-same bus address space) and you could render the machine unusable by eating
-all bus addresses.
-
-If you need to use the same streaming DMA region multiple times and touch
-the data in between the DMA transfers, the buffer needs to be synced
-properly in order for the cpu and device to see the most uptodate and
-correct copy of the DMA buffer.
-
-So, firstly, just map it with pci_map_{single,sg}, and after each DMA
-transfer call either:
-
-	pci_dma_sync_single_for_cpu(pdev, dma_handle, size, direction);
-
-or:
-
-	pci_dma_sync_sg_for_cpu(pdev, sglist, nents, direction);
-
-as appropriate.
-
-Then, if you wish to let the device get at the DMA area again,
-finish accessing the data with the cpu, and then before actually
-giving the buffer to the hardware call either:
-
-	pci_dma_sync_single_for_device(pdev, dma_handle, size, direction);
-
-or:
-
-	pci_dma_sync_sg_for_device(dev, sglist, nents, direction);
-
-as appropriate.
-
-After the last DMA transfer call one of the DMA unmap routines
-pci_unmap_{single,sg}. If you don't touch the data from the first pci_map_*
-call till pci_unmap_*, then you don't have to call the pci_dma_sync_*
-routines at all.
-
-Here is pseudo code which shows a situation in which you would need
-to use the pci_dma_sync_*() interfaces.
-
-	my_card_setup_receive_buffer(struct my_card *cp, char *buffer, int len)
-	{
-		dma_addr_t mapping;
-
-		mapping = pci_map_single(cp->pdev, buffer, len, PCI_DMA_FROMDEVICE);
-
-		cp->rx_buf = buffer;
-		cp->rx_len = len;
-		cp->rx_dma = mapping;
-
-		give_rx_buf_to_card(cp);
-	}
-
-	...
-
-	my_card_interrupt_handler(int irq, void *devid, struct pt_regs *regs)
-	{
-		struct my_card *cp = devid;
-
-		...
-		if (read_card_status(cp) == RX_BUF_TRANSFERRED) {
-			struct my_card_header *hp;
-
-			/* Examine the header to see if we wish
-			 * to accept the data.  But synchronize
-			 * the DMA transfer with the CPU first
-			 * so that we see updated contents.
-			 */
-			pci_dma_sync_single_for_cpu(cp->pdev, cp->rx_dma,
-						    cp->rx_len,
-						    PCI_DMA_FROMDEVICE);
-
-			/* Now it is safe to examine the buffer. */
-			hp = (struct my_card_header *) cp->rx_buf;
-			if (header_is_ok(hp)) {
-				pci_unmap_single(cp->pdev, cp->rx_dma, cp->rx_len,
-						 PCI_DMA_FROMDEVICE);
-				pass_to_upper_layers(cp->rx_buf);
-				make_and_setup_new_rx_buf(cp);
-			} else {
-				/* Just sync the buffer and give it back
-				 * to the card.
-				 */
-				pci_dma_sync_single_for_device(cp->pdev,
-							       cp->rx_dma,
-							       cp->rx_len,
-							       PCI_DMA_FROMDEVICE);
-				give_rx_buf_to_card(cp);
-			}
-		}
-	}
-
-Drivers converted fully to this interface should not use virt_to_bus any
-longer, nor should they use bus_to_virt. Some drivers have to be changed a
-little bit, because there is no longer an equivalent to bus_to_virt in the
-dynamic DMA mapping scheme - you have to always store the DMA addresses
-returned by the pci_alloc_consistent, pci_pool_alloc, and pci_map_single
-calls (pci_map_sg stores them in the scatterlist itself if the platform
-supports dynamic DMA mapping in hardware) in your driver structures and/or
-in the card registers.
-
-All PCI drivers should be using these interfaces with no exceptions.
-It is planned to completely remove virt_to_bus() and bus_to_virt() as
-they are entirely deprecated.  Some ports already do not provide these
-as it is impossible to correctly support them.
-
-		Optimizing Unmap State Space Consumption
-
-On many platforms, pci_unmap_{single,page}() is simply a nop.
-Therefore, keeping track of the mapping address and length is a waste
-of space.  Instead of filling your drivers up with ifdefs and the like
-to "work around" this (which would defeat the whole purpose of a
-portable API) the following facilities are provided.
-
-Actually, instead of describing the macros one by one, we'll
-transform some example code.
-
-1) Use DECLARE_PCI_UNMAP_{ADDR,LEN} in state saving structures.
-   Example, before:
-
-	struct ring_state {
-		struct sk_buff *skb;
-		dma_addr_t mapping;
-		__u32 len;
-	};
-
-   after:
-
-	struct ring_state {
-		struct sk_buff *skb;
-		DECLARE_PCI_UNMAP_ADDR(mapping)
-		DECLARE_PCI_UNMAP_LEN(len)
-	};
-
-   NOTE: DO NOT put a semicolon at the end of the DECLARE_*()
-         macro.
-
-2) Use pci_unmap_{addr,len}_set to set these values.
-   Example, before:
-
-	ringp->mapping = FOO;
-	ringp->len = BAR;
-
-   after:
-
-	pci_unmap_addr_set(ringp, mapping, FOO);
-	pci_unmap_len_set(ringp, len, BAR);
-
-3) Use pci_unmap_{addr,len} to access these values.
-   Example, before:
-
-	pci_unmap_single(pdev, ringp->mapping, ringp->len,
-			 PCI_DMA_FROMDEVICE);
-
-   after:
-
-	pci_unmap_single(pdev,
-			 pci_unmap_addr(ringp, mapping),
-			 pci_unmap_len(ringp, len),
-			 PCI_DMA_FROMDEVICE);
-
-It really should be self-explanatory.  We treat the ADDR and LEN
-separately, because it is possible for an implementation to only
-need the address in order to perform the unmap operation.
-
-			Platform Issues
-
-If you are just writing drivers for Linux and do not maintain
-an architecture port for the kernel, you can safely skip down
-to "Closing".
-
-1) Struct scatterlist requirements.
-
-   Struct scatterlist must contain, at a minimum, the following
-   members:
-
-	struct page *page;
-	unsigned int offset;
-	unsigned int length;
-
-   The base address is specified by a "page+offset" pair.
-
-   Previous versions of struct scatterlist contained a "void *address"
-   field that was sometimes used instead of page+offset.  As of Linux
-   2.5., page+offset is always used, and the "address" field has been
-   deleted.
-
-2) More to come...
-
-			Handling Errors
-
-DMA address space is limited on some architectures and an allocation
-failure can be determined by:
-
-- checking if pci_alloc_consistent returns NULL or pci_map_sg returns 0
-
-- checking the returned dma_addr_t of pci_map_single and pci_map_page
-  by using pci_dma_mapping_error():
-
-	dma_addr_t dma_handle;
-
-	dma_handle = pci_map_single(pdev, addr, size, direction);
-	if (pci_dma_mapping_error(pdev, dma_handle)) {
-		/*
-		 * reduce current DMA mapping usage,
-		 * delay and try again later or
-		 * reset driver.
-		 */
-	}
-
-			   Closing
-
-This document, and the API itself, would not be in it's current
-form without the feedback and suggestions from numerous individuals.
-We would like to specifically mention, in no particular order, the
-following people:
-
-	Russell King <rmk@arm.linux.org.uk>
-	Leo Dagum <dagum@barrel.engr.sgi.com>
-	Ralf Baechle <ralf@oss.sgi.com>
-	Grant Grundler <grundler@cup.hp.com>
-	Jay Estabrook <Jay.Estabrook@compaq.com>
-	Thomas Sailer <sailer@ife.ee.ethz.ch>
-	Andrea Arcangeli <andrea@suse.de>
-	Jens Axboe <jens.axboe@oracle.com>
-	David Mosberger-Tang <davidm@hpl.hp.com>
diff -druNp linux-libre-2.6.33-gnu1/Documentation/pcmcia/locking.txt linux-libre-2.6.34-gnu1/Documentation/pcmcia/locking.txt
--- linux-libre-2.6.33-gnu1/Documentation/pcmcia/locking.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/pcmcia/locking.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,118 @@
+This file explains the locking and exclusion scheme used in the PCCARD
+and PCMCIA subsystems.
+
+
+A) Overview, Locking Hierarchy:
+===============================
+
+pcmcia_socket_list_rwsem	- protects only the list of sockets
+- skt_mutex			- serializes card insert / ejection
+  - ops_mutex			- serializes socket operation
+
+
+B) Exclusion
+============
+
+The following functions and callbacks to struct pcmcia_socket must
+be called with "skt_mutex" held:
+
+	socket_detect_change()
+	send_event()
+	socket_reset()
+	socket_shutdown()
+	socket_setup()
+	socket_remove()
+	socket_insert()
+	socket_early_resume()
+	socket_late_resume()
+	socket_resume()
+	socket_suspend()
+
+	struct pcmcia_callback	*callback
+
+The following functions and callbacks to struct pcmcia_socket must
+be called with "ops_mutex" held:
+
+	socket_reset()
+	socket_setup()
+
+	struct pccard_operations	*ops
+	struct pccard_resource_ops	*resource_ops;
+
+Note that send_event() and struct pcmcia_callback *callback must not be
+called with "ops_mutex" held.
+
+
+C) Protection
+=============
+
+1. Global Data:
+---------------
+struct list_head	pcmcia_socket_list;
+
+protected by pcmcia_socket_list_rwsem;
+
+
+2. Per-Socket Data:
+-------------------
+The resource_ops and their data are protected by ops_mutex.
+
+The "main" struct pcmcia_socket is protected as follows (read-only fields
+or single-use fields not mentioned):
+
+- by pcmcia_socket_list_rwsem:
+	struct list_head	socket_list;
+
+- by thread_lock:
+	unsigned int		thread_events;
+
+- by skt_mutex:
+	u_int			suspended_state;
+	void			(*tune_bridge);
+	struct pcmcia_callback	*callback;
+	int			resume_status;
+
+- by ops_mutex:
+	socket_state_t		socket;
+	u_int			state;
+	u_short			lock_count;
+	pccard_mem_map		cis_mem;
+	void __iomem 		*cis_virt;
+	struct { }		irq;
+	io_window_t		io[];
+	pccard_mem_map		win[];
+	struct list_head	cis_cache;
+	size_t			fake_cis_len;
+	u8			*fake_cis;
+	u_int			irq_mask;
+	void 			(*zoom_video);
+	int 			(*power_hook);
+	u8			resource...;
+	struct list_head	devices_list;
+	u8			device_count;
+	struct 			pcmcia_state;
+
+
+3. Per PCMCIA-device Data:
+--------------------------
+
+The "main" struct pcmcia_devie is protected as follows (read-only fields
+or single-use fields not mentioned):
+
+
+- by pcmcia_socket->ops_mutex:
+	struct list_head	socket_device_list;
+	struct config_t		*function_config;
+	u16			_irq:1;
+	u16			_io:1;
+	u16			_win:4;
+	u16			_locked:1;
+	u16			allow_func_id_match:1;
+	u16			suspended:1;
+	u16			_removed:1;
+
+- by the PCMCIA driver:
+	io_req_t		io;
+	irq_req_t		irq;
+	config_req_t		conf;
+	window_handle_t		win;
diff -druNp linux-libre-2.6.33-gnu1/Documentation/pnp.txt linux-libre-2.6.34-gnu1/Documentation/pnp.txt
--- linux-libre-2.6.33-gnu1/Documentation/pnp.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/pnp.txt	2010-05-16 17:17:36.000000000 -0400
@@ -57,7 +57,7 @@ PC standard floppy disk controller
 # cat resources
 DISABLED
 
-- Notice the string "DISABLED".  THis means the device is not active.
+- Notice the string "DISABLED".  This means the device is not active.
 
 3.) check the device's possible configurations (optional)
 # cat options
@@ -139,7 +139,7 @@ Plug and Play but it is planned to be in
 
 Requirements for a Linux PnP protocol:
 1.) the protocol must use EISA IDs
-2.) the protocol must inform the PnP Layer of a devices current configuration
+2.) the protocol must inform the PnP Layer of a device's current configuration
 - the ability to set resources is optional but preferred.
 
 The following are PnP protocol related functions:
@@ -158,7 +158,7 @@ pnp_remove_device
 - automatically will free mem used by the device and related structures
 
 pnp_add_id
-- adds a EISA ID to the list of supported IDs for the specified device
+- adds an EISA ID to the list of supported IDs for the specified device
 
 For more information consult the source of a protocol such as
 /drivers/pnp/pnpbios/core.c.
@@ -167,7 +167,7 @@ For more information consult the source
 
 Linux Plug and Play Drivers
 ---------------------------
-	This section contains information for linux PnP driver developers.
+	This section contains information for Linux PnP driver developers.
 
 The New Way
 ...........
@@ -235,11 +235,10 @@ static int __init serial8250_pnp_init(vo
 The Old Way
 ...........
 
-a series of compatibility functions have been created to make it easy to convert 
-
+A series of compatibility functions have been created to make it easy to convert
 ISAPNP drivers.  They should serve as a temporary solution only.
 
-they are as follows:
+They are as follows:
 
 struct pnp_card *pnp_find_card(unsigned short vendor,
 				 unsigned short device,
diff -druNp linux-libre-2.6.33-gnu1/Documentation/power/runtime_pm.txt linux-libre-2.6.34-gnu1/Documentation/power/runtime_pm.txt
--- linux-libre-2.6.33-gnu1/Documentation/power/runtime_pm.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/power/runtime_pm.txt	2010-05-16 17:17:36.000000000 -0400
@@ -224,6 +224,12 @@ defined in include/linux/pm.h:
       RPM_SUSPENDED, which means that each device is initially regarded by the
       PM core as 'suspended', regardless of its real hardware status
 
+  unsigned int runtime_auto;
+    - if set, indicates that the user space has allowed the device driver to
+      power manage the device at run time via the /sys/devices/.../power/control
+      interface; it may only be modified with the help of the pm_runtime_allow()
+      and pm_runtime_forbid() helper functions
+
 All of the above fields are members of the 'power' member of 'struct device'.
 
 4. Run-time PM Device Helper Functions
@@ -250,7 +256,7 @@ drivers/base/power/runtime.c and include
       to suspend the device again in future
 
   int pm_runtime_resume(struct device *dev);
-    - execute the subsystem-leve resume callback for the device; returns 0 on
+    - execute the subsystem-level resume callback for the device; returns 0 on
       success, 1 if the device's run-time PM status was already 'active' or
       error code on failure, where -EAGAIN means it may be safe to attempt to
       resume the device again in future, but 'power.runtime_error' should be
@@ -329,6 +335,20 @@ drivers/base/power/runtime.c and include
       'power.runtime_error' is set or 'power.disable_depth' is greater than
       zero)
 
+  bool pm_runtime_suspended(struct device *dev);
+    - return true if the device's runtime PM status is 'suspended', or false
+      otherwise
+
+  void pm_runtime_allow(struct device *dev);
+    - set the power.runtime_auto flag for the device and decrease its usage
+      counter (used by the /sys/devices/.../power/control interface to
+      effectively allow the device to be power managed at run time)
+
+  void pm_runtime_forbid(struct device *dev);
+    - unset the power.runtime_auto flag for the device and increase its usage
+      counter (used by the /sys/devices/.../power/control interface to
+      effectively prevent the device from being power managed at run time)
+
 It is safe to execute the following helper functions from interrupt context:
 
 pm_request_idle()
@@ -382,6 +402,18 @@ may be desirable to suspend the device a
 finished, so the PM core uses pm_runtime_idle_sync() to invoke the
 subsystem-level idle callback for the device at that time.
 
+The user space can effectively disallow the driver of the device to power manage
+it at run time by changing the value of its /sys/devices/.../power/control
+attribute to "on", which causes pm_runtime_forbid() to be called.  In principle,
+this mechanism may also be used by the driver to effectively turn off the
+run-time power management of the device until the user space turns it on.
+Namely, during the initialization the driver can make sure that the run-time PM
+status of the device is 'active' and call pm_runtime_forbid().  It should be
+noted, however, that if the user space has already intentionally changed the
+value of /sys/devices/.../power/control to "auto" to allow the driver to power
+manage the device at run time, the driver may confuse it by using
+pm_runtime_forbid() this way.
+
 6. Run-time PM and System Sleep
 
 Run-time PM and system sleep (i.e., system suspend and hibernation, also known
@@ -431,3 +463,64 @@ The PM core always increments the run-ti
 ->prepare() callback and decrements it after calling the ->complete() callback.
 Hence disabling run-time PM temporarily like this will not cause any run-time
 suspend callbacks to be lost.
+
+7. Generic subsystem callbacks
+
+Subsystems may wish to conserve code space by using the set of generic power
+management callbacks provided by the PM core, defined in
+driver/base/power/generic_ops.c:
+
+  int pm_generic_runtime_idle(struct device *dev);
+    - invoke the ->runtime_idle() callback provided by the driver of this
+      device, if defined, and call pm_runtime_suspend() for this device if the
+      return value is 0 or the callback is not defined
+
+  int pm_generic_runtime_suspend(struct device *dev);
+    - invoke the ->runtime_suspend() callback provided by the driver of this
+      device and return its result, or return -EINVAL if not defined
+
+  int pm_generic_runtime_resume(struct device *dev);
+    - invoke the ->runtime_resume() callback provided by the driver of this
+      device and return its result, or return -EINVAL if not defined
+
+  int pm_generic_suspend(struct device *dev);
+    - if the device has not been suspended at run time, invoke the ->suspend()
+      callback provided by its driver and return its result, or return 0 if not
+      defined
+
+  int pm_generic_resume(struct device *dev);
+    - invoke the ->resume() callback provided by the driver of this device and,
+      if successful, change the device's runtime PM status to 'active'
+
+  int pm_generic_freeze(struct device *dev);
+    - if the device has not been suspended at run time, invoke the ->freeze()
+      callback provided by its driver and return its result, or return 0 if not
+      defined
+
+  int pm_generic_thaw(struct device *dev);
+    - if the device has not been suspended at run time, invoke the ->thaw()
+      callback provided by its driver and return its result, or return 0 if not
+      defined
+
+  int pm_generic_poweroff(struct device *dev);
+    - if the device has not been suspended at run time, invoke the ->poweroff()
+      callback provided by its driver and return its result, or return 0 if not
+      defined
+
+  int pm_generic_restore(struct device *dev);
+    - invoke the ->restore() callback provided by the driver of this device and,
+      if successful, change the device's runtime PM status to 'active'
+
+These functions can be assigned to the ->runtime_idle(), ->runtime_suspend(),
+->runtime_resume(), ->suspend(), ->resume(), ->freeze(), ->thaw(), ->poweroff(),
+or ->restore() callback pointers in the subsystem-level dev_pm_ops structures.
+
+If a subsystem wishes to use all of them at the same time, it can simply assign
+the GENERIC_SUBSYS_PM_OPS macro, defined in include/linux/pm.h, to its
+dev_pm_ops structure pointer.
+
+Device drivers that wish to use the same function as a system suspend, freeze,
+poweroff and run-time suspend callback, and similarly for system resume, thaw,
+restore, and run-time resume, can achieve this with the help of the
+UNIVERSAL_DEV_PM_OPS macro defined in include/linux/pm.h (possibly setting its
+last argument to NULL).
diff -druNp linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/can.txt linux-libre-2.6.34-gnu1/Documentation/powerpc/dts-bindings/fsl/can.txt
--- linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/can.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/powerpc/dts-bindings/fsl/can.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,53 @@
+CAN Device Tree Bindings
+------------------------
+
+(c) 2006-2009 Secret Lab Technologies Ltd
+Grant Likely <grant.likely@secretlab.ca>
+
+fsl,mpc5200-mscan nodes
+-----------------------
+In addition to the required compatible-, reg- and interrupt-properties, you can
+also specify which clock source shall be used for the controller:
+
+- fsl,mscan-clock-source : a string describing the clock source. Valid values
+			   are:	"ip" for ip bus clock
+				 "ref" for reference clock (XTAL)
+			   "ref" is default in case this property is not
+			   present.
+
+fsl,mpc5121-mscan nodes
+-----------------------
+In addition to the required compatible-, reg- and interrupt-properties, you can
+also specify which clock source and divider shall be used for the controller:
+
+- fsl,mscan-clock-source : a string describing the clock source. Valid values
+			   are:	"ip" for ip bus clock
+				"ref" for reference clock
+				"sys" for system clock
+			   If this property is not present, an optimal CAN
+			   clock source and frequency based on the system
+			   clock will be selected. If this is not possible,
+			   the reference clock will be used.
+
+- fsl,mscan-clock-divider: for the reference and system clock, an additional
+			   clock divider can be specified. By default, a
+			   value of 1 is used.
+
+Note that the MPC5121 Rev. 1 processor is not supported.
+
+Examples:
+	can@1300 {
+		compatible = "fsl,mpc5121-mscan";
+		interrupts = <12 0x8>;
+		interrupt-parent = <&ipic>;
+		reg = <0x1300 0x80>;
+	};
+
+	can@1380 {
+		compatible = "fsl,mpc5121-mscan";
+		interrupts = <13 0x8>;
+		interrupt-parent = <&ipic>;
+		reg = <0x1380 0x80>;
+		fsl,mscan-clock-source = "ref";
+		fsl,mscan-clock-divider = <3>;
+	};
diff -druNp linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt linux-libre-2.6.34-gnu1/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt
--- linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,15 @@ Required properties:
 - fsl,qe-num-snums: define how many serial number(SNUM) the QE can use for the
   threads.
 
+Optional properties:
+- fsl,firmware-phandle:
+    Usage: required only if there is no fsl,qe-firmware child node
+    Value type: <phandle>
+    Definition: Points to a firmware node (see "QE Firmware Node" below)
+        that contains the firmware that should be uploaded for this QE.
+        The compatible property for the firmware node should say,
+        "fsl,qe-firmware".
+
 Recommended properties
 - brg-frequency : the internal clock source frequency for baud-rate
   generators in Hz.
@@ -59,3 +68,48 @@ Example:
 		reg = <0 c000>;
 	};
      };
+
+* QE Firmware Node
+
+This node defines a firmware binary that is embedded in the device tree, for
+the purpose of passing the firmware from bootloader to the kernel, or from
+the hypervisor to the guest.
+
+The firmware node itself contains the firmware binary contents, a compatible
+property, and any firmware-specific properties.  The node should be placed
+inside a QE node that needs it.  Doing so eliminates the need for a
+fsl,firmware-phandle property.  Other QE nodes that need the same firmware
+should define an fsl,firmware-phandle property that points to the firmware node
+in the first QE node.
+
+The fsl,firmware property can be specified in the DTS (possibly using incbin)
+or can be inserted by the boot loader at boot time.
+
+Required properties:
+  - compatible
+      Usage: required
+      Value type: <string>
+      Definition: A standard property.  Specify a string that indicates what
+          kind of firmware it is.  For QE, this should be "fsl,qe-firmware".
+
+   - fsl,firmware
+      Usage: required
+      Value type: <prop-encoded-array>, encoded as an array of bytes
+      Definition: A standard property.  This property contains the firmware
+          binary "blob".
+
+Example:
+	qe1@e0080000 {
+		compatible = "fsl,qe";
+		qe_firmware:qe-firmware {
+			compatible = "fsl,qe-firmware";
+			fsl,firmware = [0x70 0xcd 0x00 0x00 0x01 0x46 0x45 ...];
+		};
+		...
+	};
+
+	qe2@e0090000 {
+		compatible = "fsl,qe";
+		fsl,firmware-phandle = <&qe_firmware>;
+		...
+	};
diff -druNp linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/dma.txt linux-libre-2.6.34-gnu1/Documentation/powerpc/dts-bindings/fsl/dma.txt
--- linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/dma.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/powerpc/dts-bindings/fsl/dma.txt	2010-05-16 17:17:36.000000000 -0400
@@ -44,21 +44,29 @@ Example:
 			compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
 			cell-index = <0>;
 			reg = <0 0x80>;
+			interrupt-parent = <&ipic>;
+			interrupts = <71 8>;
 		};
 		dma-channel@80 {
 			compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
 			cell-index = <1>;
 			reg = <0x80 0x80>;
+			interrupt-parent = <&ipic>;
+			interrupts = <71 8>;
 		};
 		dma-channel@100 {
 			compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
 			cell-index = <2>;
 			reg = <0x100 0x80>;
+			interrupt-parent = <&ipic>;
+			interrupts = <71 8>;
 		};
 		dma-channel@180 {
 			compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
 			cell-index = <3>;
 			reg = <0x180 0x80>;
+			interrupt-parent = <&ipic>;
+			interrupts = <71 8>;
 		};
 	};
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/i2c.txt linux-libre-2.6.34-gnu1/Documentation/powerpc/dts-bindings/fsl/i2c.txt
--- linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/i2c.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/powerpc/dts-bindings/fsl/i2c.txt	2010-05-16 17:17:36.000000000 -0400
@@ -2,15 +2,14 @@
 
 Required properties :
 
- - device_type : Should be "i2c"
  - reg : Offset and length of the register set for the device
+ - compatible : should be "fsl,CHIP-i2c" where CHIP is the name of a
+   compatible processor, e.g. mpc8313, mpc8543, mpc8544, mpc5121,
+   mpc5200 or mpc5200b. For the mpc5121, an additional node
+   "fsl,mpc5121-i2c-ctrl" is required as shown in the example below.
 
 Recommended properties :
 
- - 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
@@ -24,25 +23,40 @@ Recommended properties :
 
 Examples :
 
+	/* MPC5121 based board */
+	i2c@1740 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "fsl,mpc5121-i2c", "fsl-i2c";
+		reg = <0x1740 0x20>;
+		interrupts = <11 0x8>;
+		interrupt-parent = <&ipic>;
+		clock-frequency = <100000>;
+	};
+
+	i2ccontrol@1760 {
+		compatible = "fsl,mpc5121-i2c-ctrl";
+		reg = <0x1760 0x8>;
+	};
+
+	/* MPC5200B based board */
 	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;
 	};
 
+	/* MPC8544 base board */
 	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.33-gnu1/Documentation/powerpc/dts-bindings/fsl/mpc5121-psc.txt linux-libre-2.6.34-gnu1/Documentation/powerpc/dts-bindings/fsl/mpc5121-psc.txt
--- linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/mpc5121-psc.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/powerpc/dts-bindings/fsl/mpc5121-psc.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,70 @@
+MPC5121 PSC Device Tree Bindings
+
+PSC in UART mode
+----------------
+
+For PSC in UART mode the needed PSC serial devices
+are specified by fsl,mpc5121-psc-uart nodes in the
+fsl,mpc5121-immr SoC node. Additionally the PSC FIFO
+Controller node fsl,mpc5121-psc-fifo is requered there:
+
+fsl,mpc5121-psc-uart nodes
+--------------------------
+
+Required properties :
+ - compatible : Should contain "fsl,mpc5121-psc-uart" and "fsl,mpc5121-psc"
+ - cell-index : Index of the PSC in hardware
+ - reg : Offset and length of the register set for the PSC device
+ - interrupts : <a b> where a is the interrupt number of the
+   PSC FIFO Controller and b is a field that represents an
+   encoding of the sense and level information for the interrupt.
+ - interrupt-parent : the phandle for the interrupt controller that
+   services interrupts for this device.
+
+Recommended properties :
+ - fsl,rx-fifo-size : the size of the RX fifo slice (a multiple of 4)
+ - fsl,tx-fifo-size : the size of the TX fifo slice (a multiple of 4)
+
+
+fsl,mpc5121-psc-fifo node
+-------------------------
+
+Required properties :
+ - compatible : Should be "fsl,mpc5121-psc-fifo"
+ - reg : Offset and length of the register set for the PSC
+         FIFO Controller
+ - interrupts : <a b> where a is the interrupt number of the
+   PSC FIFO Controller and b is a field that represents an
+   encoding of the sense and level information for the interrupt.
+ - interrupt-parent : the phandle for the interrupt controller that
+   services interrupts for this device.
+
+
+Example for a board using PSC0 and PSC1 devices in serial mode:
+
+serial@11000 {
+	compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc";
+	cell-index = <0>;
+	reg = <0x11000 0x100>;
+	interrupts = <40 0x8>;
+	interrupt-parent = < &ipic >;
+	fsl,rx-fifo-size = <16>;
+	fsl,tx-fifo-size = <16>;
+};
+
+serial@11100 {
+	compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc";
+	cell-index = <1>;
+	reg = <0x11100 0x100>;
+	interrupts = <40 0x8>;
+	interrupt-parent = < &ipic >;
+	fsl,rx-fifo-size = <16>;
+	fsl,tx-fifo-size = <16>;
+};
+
+pscfifo@11f00 {
+	compatible = "fsl,mpc5121-psc-fifo";
+	reg = <0x11f00 0x100>;
+	interrupts = <40 0x8>;
+	interrupt-parent = < &ipic >;
+};
diff -druNp linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt linux-libre-2.6.34-gnu1/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt
--- linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt	2010-05-16 17:17:36.000000000 -0400
@@ -195,11 +195,4 @@ External interrupts:
 
 fsl,mpc5200-mscan nodes
 -----------------------
-In addition to the required compatible-, reg- and interrupt-properites, you can
-also specify which clock source shall be used for the controller:
-
-- fsl,mscan-clock-source- a string describing the clock source. Valid values
-			  are:	"ip" for ip bus clock
-				"ref" for reference clock (XTAL)
-			  "ref" is default in case this property is not
-			  present.
+See file can.txt in this directory.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/spi.txt linux-libre-2.6.34-gnu1/Documentation/powerpc/dts-bindings/fsl/spi.txt
--- linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/spi.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/powerpc/dts-bindings/fsl/spi.txt	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,11 @@ Required properties:
 - interrupt-parent : the phandle for the interrupt controller that
   services interrupts for this device.
 
+Optional properties:
+- gpios : specifies the gpio pins to be used for chipselects.
+  The gpios will be referred to as reg = <index> in the SPI child nodes.
+  If unspecified, a single SPI device without a chip select can be used.
+
 Example:
 	spi@4c0 {
 		cell-index = <0>;
@@ -21,4 +26,6 @@ Example:
 		interrupts = <82 0>;
 		interrupt-parent = <700>;
 		mode = "cpu";
+		gpios = <&gpio 18 1	// device reg=<0>
+			 &gpio 19 1>;	// device reg=<1>
 	};
diff -druNp linux-libre-2.6.33-gnu1/Documentation/powerpc/ptrace.txt linux-libre-2.6.34-gnu1/Documentation/powerpc/ptrace.txt
--- linux-libre-2.6.33-gnu1/Documentation/powerpc/ptrace.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/powerpc/ptrace.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,134 @@
+GDB intends to support the following hardware debug features of BookE
+processors:
+
+4 hardware breakpoints (IAC)
+2 hardware watchpoints (read, write and read-write) (DAC)
+2 value conditions for the hardware watchpoints (DVC)
+
+For that, we need to extend ptrace so that GDB can query and set these
+resources. Since we're extending, we're trying to create an interface
+that's extendable and that covers both BookE and server processors, so
+that GDB doesn't need to special-case each of them. We added the
+following 3 new ptrace requests.
+
+1. PTRACE_PPC_GETHWDEBUGINFO
+
+Query for GDB to discover the hardware debug features. The main info to
+be returned here is the minimum alignment for the hardware watchpoints.
+BookE processors don't have restrictions here, but server processors have
+an 8-byte alignment restriction for hardware watchpoints. We'd like to avoid
+adding special cases to GDB based on what it sees in AUXV.
+
+Since we're at it, we added other useful info that the kernel can return to
+GDB: this query will return the number of hardware breakpoints, hardware
+watchpoints and whether it supports a range of addresses and a condition.
+The query will fill the following structure provided by the requesting process:
+
+struct ppc_debug_info {
+       unit32_t version;
+       unit32_t num_instruction_bps;
+       unit32_t num_data_bps;
+       unit32_t num_condition_regs;
+       unit32_t data_bp_alignment;
+       unit32_t sizeof_condition; /* size of the DVC register */
+       uint64_t features; /* bitmask of the individual flags */
+};
+
+features will have bits indicating whether there is support for:
+
+#define PPC_DEBUG_FEATURE_INSN_BP_RANGE		0x1
+#define PPC_DEBUG_FEATURE_INSN_BP_MASK		0x2
+#define PPC_DEBUG_FEATURE_DATA_BP_RANGE		0x4
+#define PPC_DEBUG_FEATURE_DATA_BP_MASK		0x8
+
+2. PTRACE_SETHWDEBUG
+
+Sets a hardware breakpoint or watchpoint, according to the provided structure:
+
+struct ppc_hw_breakpoint {
+        uint32_t version;
+#define PPC_BREAKPOINT_TRIGGER_EXECUTE  0x1
+#define PPC_BREAKPOINT_TRIGGER_READ     0x2
+#define PPC_BREAKPOINT_TRIGGER_WRITE    0x4
+        uint32_t trigger_type;       /* only some combinations allowed */
+#define PPC_BREAKPOINT_MODE_EXACT               0x0
+#define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE     0x1
+#define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE     0x2
+#define PPC_BREAKPOINT_MODE_MASK                0x3
+        uint32_t addr_mode;          /* address match mode */
+
+#define PPC_BREAKPOINT_CONDITION_MODE   0x3
+#define PPC_BREAKPOINT_CONDITION_NONE   0x0
+#define PPC_BREAKPOINT_CONDITION_AND    0x1
+#define PPC_BREAKPOINT_CONDITION_EXACT  0x1	/* different name for the same thing as above */
+#define PPC_BREAKPOINT_CONDITION_OR     0x2
+#define PPC_BREAKPOINT_CONDITION_AND_OR 0x3
+#define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000	/* byte enable bits */
+#define PPC_BREAKPOINT_CONDITION_BE(n)  (1<<((n)+16))
+        uint32_t condition_mode;     /* break/watchpoint condition flags */
+
+        uint64_t addr;
+        uint64_t addr2;
+        uint64_t condition_value;
+};
+
+A request specifies one event, not necessarily just one register to be set.
+For instance, if the request is for a watchpoint with a condition, both the
+DAC and DVC registers will be set in the same request.
+
+With this GDB can ask for all kinds of hardware breakpoints and watchpoints
+that the BookE supports. COMEFROM breakpoints available in server processors
+are not contemplated, but that is out of the scope of this work.
+
+ptrace will return an integer (handle) uniquely identifying the breakpoint or
+watchpoint just created. This integer will be used in the PTRACE_DELHWDEBUG
+request to ask for its removal. Return -ENOSPC if the requested breakpoint
+can't be allocated on the registers.
+
+Some examples of using the structure to:
+
+- set a breakpoint in the first breakpoint register
+
+  p.version         = PPC_DEBUG_CURRENT_VERSION;
+  p.trigger_type    = PPC_BREAKPOINT_TRIGGER_EXECUTE;
+  p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
+  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
+  p.addr            = (uint64_t) address;
+  p.addr2           = 0;
+  p.condition_value = 0;
+
+- set a watchpoint which triggers on reads in the second watchpoint register
+
+  p.version         = PPC_DEBUG_CURRENT_VERSION;
+  p.trigger_type    = PPC_BREAKPOINT_TRIGGER_READ;
+  p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
+  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
+  p.addr            = (uint64_t) address;
+  p.addr2           = 0;
+  p.condition_value = 0;
+
+- set a watchpoint which triggers only with a specific value
+
+  p.version         = PPC_DEBUG_CURRENT_VERSION;
+  p.trigger_type    = PPC_BREAKPOINT_TRIGGER_READ;
+  p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
+  p.condition_mode  = PPC_BREAKPOINT_CONDITION_AND | PPC_BREAKPOINT_CONDITION_BE_ALL;
+  p.addr            = (uint64_t) address;
+  p.addr2           = 0;
+  p.condition_value = (uint64_t) condition;
+
+- set a ranged hardware breakpoint
+
+  p.version         = PPC_DEBUG_CURRENT_VERSION;
+  p.trigger_type    = PPC_BREAKPOINT_TRIGGER_EXECUTE;
+  p.addr_mode       = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
+  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
+  p.addr            = (uint64_t) begin_range;
+  p.addr2           = (uint64_t) end_range;
+  p.condition_value = 0;
+
+3. PTRACE_DELHWDEBUG
+
+Takes an integer which identifies an existing breakpoint or watchpoint
+(i.e., the value returned from PTRACE_SETHWDEBUG), and deletes the
+corresponding breakpoint or watchpoint..
diff -druNp linux-libre-2.6.33-gnu1/Documentation/RCU/00-INDEX linux-libre-2.6.34-gnu1/Documentation/RCU/00-INDEX
--- linux-libre-2.6.33-gnu1/Documentation/RCU/00-INDEX	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/RCU/00-INDEX	2010-05-16 17:17:36.000000000 -0400
@@ -6,16 +6,22 @@ checklist.txt
 	- Review Checklist for RCU Patches
 listRCU.txt
 	- Using RCU to Protect Read-Mostly Linked Lists
+lockdep.txt
+	- RCU and lockdep checking
 NMI-RCU.txt
 	- Using RCU to Protect Dynamic NMI Handlers
+rcubarrier.txt
+	- RCU and Unloadable Modules
+rculist_nulls.txt
+	- RCU list primitives for use with SLAB_DESTROY_BY_RCU
 rcuref.txt
 	- Reference-count design for elements of lists/arrays protected by RCU
 rcu.txt
 	- RCU Concepts
-rcubarrier.txt
-	- Unloading modules that use RCU callbacks
 RTFP.txt
 	- List of RCU papers (bibliography) going back to 1980.
+stallwarn.txt
+	- RCU CPU stall warnings (CONFIG_RCU_CPU_STALL_DETECTOR)
 torture.txt
 	- RCU Torture Test Operation (CONFIG_RCU_TORTURE_TEST)
 trace.txt
diff -druNp linux-libre-2.6.33-gnu1/Documentation/RCU/checklist.txt linux-libre-2.6.34-gnu1/Documentation/RCU/checklist.txt
--- linux-libre-2.6.33-gnu1/Documentation/RCU/checklist.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/RCU/checklist.txt	2010-05-16 17:17:36.000000000 -0400
@@ -8,13 +8,12 @@ would cause.  This list is based on expe
 over a rather long period of time, but improvements are always welcome!
 
 0.	Is RCU being applied to a read-mostly situation?  If the data
-	structure is updated more than about 10% of the time, then
-	you should strongly consider some other approach, unless
-	detailed performance measurements show that RCU is nonetheless
-	the right tool for the job.  Yes, you might think of RCU
-	as simply cutting overhead off of the readers and imposing it
-	on the writers.  That is exactly why normal uses of RCU will
-	do much more reading than updating.
+	structure is updated more than about 10% of the time, then you
+	should strongly consider some other approach, unless detailed
+	performance measurements show that RCU is nonetheless the right
+	tool for the job.  Yes, RCU does reduce read-side overhead by
+	increasing write-side overhead, which is exactly why normal uses
+	of RCU will do much more reading than updating.
 
 	Another exception is where performance is not an issue, and RCU
 	provides a simpler implementation.  An example of this situation
@@ -35,13 +34,13 @@ over a rather long period of time, but i
 
 	If you choose #b, be prepared to describe how you have handled
 	memory barriers on weakly ordered machines (pretty much all of
-	them -- even x86 allows reads to be reordered), and be prepared
-	to explain why this added complexity is worthwhile.  If you
-	choose #c, be prepared to explain how this single task does not
-	become a major bottleneck on big multiprocessor machines (for
-	example, if the task is updating information relating to itself
-	that other tasks can read, there by definition can be no
-	bottleneck).
+	them -- even x86 allows later loads to be reordered to precede
+	earlier stores), and be prepared to explain why this added
+	complexity is worthwhile.  If you choose #c, be prepared to
+	explain how this single task does not become a major bottleneck on
+	big multiprocessor machines (for example, if the task is updating
+	information relating to itself that other tasks can read, there
+	by definition can be no bottleneck).
 
 2.	Do the RCU read-side critical sections make proper use of
 	rcu_read_lock() and friends?  These primitives are needed
@@ -51,8 +50,10 @@ over a rather long period of time, but i
 	actuarial risk of your kernel.
 
 	As a rough rule of thumb, any dereference of an RCU-protected
-	pointer must be covered by rcu_read_lock() or rcu_read_lock_bh()
-	or by the appropriate update-side lock.
+	pointer must be covered by rcu_read_lock(), rcu_read_lock_bh(),
+	rcu_read_lock_sched(), or by the appropriate update-side lock.
+	Disabling of preemption can serve as rcu_read_lock_sched(), but
+	is less readable.
 
 3.	Does the update code tolerate concurrent accesses?
 
@@ -62,25 +63,27 @@ over a rather long period of time, but i
 	of ways to handle this concurrency, depending on the situation:
 
 	a.	Use the RCU variants of the list and hlist update
-		primitives to add, remove, and replace elements on an
-		RCU-protected list.  Alternatively, use the RCU-protected
-		trees that have been added to the Linux kernel.
+		primitives to add, remove, and replace elements on
+		an RCU-protected list.	Alternatively, use the other
+		RCU-protected data structures that have been added to
+		the Linux kernel.
 
 		This is almost always the best approach.
 
 	b.	Proceed as in (a) above, but also maintain per-element
 		locks (that are acquired by both readers and writers)
 		that guard per-element state.  Of course, fields that
-		the readers refrain from accessing can be guarded by the
-		update-side lock.
+		the readers refrain from accessing can be guarded by
+		some other lock acquired only by updaters, if desired.
 
 		This works quite well, also.
 
 	c.	Make updates appear atomic to readers.  For example,
-		pointer updates to properly aligned fields will appear
-		atomic, as will individual atomic primitives.  Operations
-		performed under a lock and sequences of multiple atomic
-		primitives will -not- appear to be atomic.
+		pointer updates to properly aligned fields will
+		appear atomic, as will individual atomic primitives.
+		Sequences of perations performed under a lock will -not-
+		appear to be atomic to RCU readers, nor will sequences
+		of multiple atomic primitives.
 
 		This can work, but is starting to get a bit tricky.
 
@@ -98,9 +101,9 @@ over a rather long period of time, but i
 		a new structure containing updated values.
 
 4.	Weakly ordered CPUs pose special challenges.  Almost all CPUs
-	are weakly ordered -- even i386 CPUs allow reads to be reordered.
-	RCU code must take all of the following measures to prevent
-	memory-corruption problems:
+	are weakly ordered -- even x86 CPUs allow later loads to be
+	reordered to precede earlier stores.  RCU code must take all of
+	the following measures to prevent memory-corruption problems:
 
 	a.	Readers must maintain proper ordering of their memory
 		accesses.  The rcu_dereference() primitive ensures that
@@ -113,14 +116,25 @@ over a rather long period of time, but i
 		The rcu_dereference() primitive is also an excellent
 		documentation aid, letting the person reading the code
 		know exactly which pointers are protected by RCU.
+		Please note that compilers can also reorder code, and
+		they are becoming increasingly aggressive about doing
+		just that.  The rcu_dereference() primitive therefore
+		also prevents destructive compiler optimizations.
 
-		The rcu_dereference() primitive is used by the various
-		"_rcu()" list-traversal primitives, such as the
-		list_for_each_entry_rcu().  Note that it is perfectly
-		legal (if redundant) for update-side code to use
-		rcu_dereference() and the "_rcu()" list-traversal
-		primitives.  This is particularly useful in code
-		that is common to readers and updaters.
+		The rcu_dereference() primitive is used by the
+		various "_rcu()" list-traversal primitives, such
+		as the list_for_each_entry_rcu().  Note that it is
+		perfectly legal (if redundant) for update-side code to
+		use rcu_dereference() and the "_rcu()" list-traversal
+		primitives.  This is particularly useful in code that
+		is common to readers and updaters.  However, lockdep
+		will complain if you access rcu_dereference() outside
+		of an RCU read-side critical section.  See lockdep.txt
+		to learn what to do about this.
+
+		Of course, neither rcu_dereference() nor the "_rcu()"
+		list-traversal primitives can substitute for a good
+		concurrency design coordinating among multiple updaters.
 
 	b.	If the list macros are being used, the list_add_tail_rcu()
 		and list_add_rcu() primitives must be used in order
@@ -135,11 +149,14 @@ over a rather long period of time, but i
 		readers.  Similarly, if the hlist macros are being used,
 		the hlist_del_rcu() primitive is required.
 
-		The list_replace_rcu() primitive may be used to
-		replace an old structure with a new one in an
-		RCU-protected list.
+		The list_replace_rcu() and hlist_replace_rcu() primitives
+		may be used to replace an old structure with a new one
+		in their respective types of RCU-protected lists.
 
-	d.	Updates must ensure that initialization of a given
+	d.	Rules similar to (4b) and (4c) apply to the "hlist_nulls"
+		type of RCU-protected linked lists.
+
+	e.	Updates must ensure that initialization of a given
 		structure happens before pointers to that structure are
 		publicized.  Use the rcu_assign_pointer() primitive
 		when publicizing a pointer to a structure that can
@@ -151,16 +168,31 @@ over a rather long period of time, but i
 	it cannot block.
 
 6.	Since synchronize_rcu() can block, it cannot be called from
-	any sort of irq context.  Ditto for synchronize_sched() and
-	synchronize_srcu().
+	any sort of irq context.  The same rule applies for
+	synchronize_rcu_bh(), synchronize_sched(), synchronize_srcu(),
+	synchronize_rcu_expedited(), synchronize_rcu_bh_expedited(),
+	synchronize_sched_expedite(), and synchronize_srcu_expedited().
 
-7.	If the updater uses call_rcu(), then the corresponding readers
-	must use rcu_read_lock() and rcu_read_unlock().  If the updater
-	uses call_rcu_bh(), then the corresponding readers must use
-	rcu_read_lock_bh() and rcu_read_unlock_bh().  If the updater
-	uses call_rcu_sched(), then the corresponding readers must
-	disable preemption.  Mixing things up will result in confusion
-	and broken kernels.
+	The expedited forms of these primitives have the same semantics
+	as the non-expedited forms, but expediting is both expensive
+	and unfriendly to real-time workloads.	Use of the expedited
+	primitives should be restricted to rare configuration-change
+	operations that would not normally be undertaken while a real-time
+	workload is running.
+
+7.	If the updater uses call_rcu() or synchronize_rcu(), then the
+	corresponding readers must use rcu_read_lock() and
+	rcu_read_unlock().  If the updater uses call_rcu_bh() or
+	synchronize_rcu_bh(), then the corresponding readers must
+	use rcu_read_lock_bh() and rcu_read_unlock_bh().  If the
+	updater uses call_rcu_sched() or synchronize_sched(), then
+	the corresponding readers must disable preemption, possibly
+	by calling rcu_read_lock_sched() and rcu_read_unlock_sched().
+	If the updater uses synchronize_srcu(), the the corresponding
+	readers must use srcu_read_lock() and srcu_read_unlock(),
+	and with the same srcu_struct.	The rules for the expedited
+	primitives are the same as for their non-expedited counterparts.
+	Mixing things up will result in confusion and broken kernels.
 
 	One exception to this rule: rcu_read_lock() and rcu_read_unlock()
 	may be substituted for rcu_read_lock_bh() and rcu_read_unlock_bh()
@@ -212,6 +244,8 @@ over a rather long period of time, but i
 	e.	Periodically invoke synchronize_rcu(), permitting a limited
 		number of updates per grace period.
 
+	The same cautions apply to call_rcu_bh() and call_rcu_sched().
+
 9.	All RCU list-traversal primitives, which include
 	rcu_dereference(), list_for_each_entry_rcu(),
 	list_for_each_continue_rcu(), and list_for_each_safe_rcu(),
@@ -219,17 +253,21 @@ over a rather long period of time, but i
 	must be protected by appropriate update-side locks.  RCU
 	read-side critical sections are delimited by rcu_read_lock()
 	and rcu_read_unlock(), or by similar primitives such as
-	rcu_read_lock_bh() and rcu_read_unlock_bh().
+	rcu_read_lock_bh() and rcu_read_unlock_bh(), in which case
+	the matching rcu_dereference() primitive must be used in order
+	to keep lockdep happy, in this case, rcu_dereference_bh().
 
 	The reason that it is permissible to use RCU list-traversal
 	primitives when the update-side lock is held is that doing so
 	can be quite helpful in reducing code bloat when common code is
-	shared between readers and updaters.
+	shared between readers and updaters.  Additional primitives
+	are provided for this case, as discussed in lockdep.txt.
 
 10.	Conversely, if you are in an RCU read-side critical section,
 	and you don't hold the appropriate update-side lock, you -must-
 	use the "_rcu()" variants of the list macros.  Failing to do so
-	will break Alpha and confuse people reading your code.
+	will break Alpha, cause aggressive compilers to generate bad code,
+	and confuse people trying to read your code.
 
 11.	Note that synchronize_rcu() -only- guarantees to wait until
 	all currently executing rcu_read_lock()-protected RCU read-side
@@ -239,15 +277,21 @@ over a rather long period of time, but i
 	rcu_read_lock()-protected read-side critical sections, do -not-
 	use synchronize_rcu().
 
-	If you want to wait for some of these other things, you might
-	instead need to use synchronize_irq() or synchronize_sched().
+	Similarly, disabling preemption is not an acceptable substitute
+	for rcu_read_lock().  Code that attempts to use preemption
+	disabling where it should be using rcu_read_lock() will break
+	in real-time kernel builds.
+
+	If you want to wait for interrupt handlers, NMI handlers, and
+	code under the influence of preempt_disable(), you instead
+	need to use synchronize_irq() or synchronize_sched().
 
 12.	Any lock acquired by an RCU callback must be acquired elsewhere
 	with softirq disabled, e.g., via spin_lock_irqsave(),
 	spin_lock_bh(), etc.  Failing to disable irq on a given
-	acquisition of that lock will result in deadlock as soon as the
-	RCU callback happens to interrupt that acquisition's critical
-	section.
+	acquisition of that lock will result in deadlock as soon as
+	the RCU softirq handler happens to run your RCU callback while
+	interrupting that acquisition's critical section.
 
 13.	RCU callbacks can be and are executed in parallel.  In many cases,
 	the callback code simply wrappers around kfree(), so that this
@@ -265,29 +309,30 @@ over a rather long period of time, but i
 	not the case, a self-spawning RCU callback would prevent the
 	victim CPU from ever going offline.)
 
-14.	SRCU (srcu_read_lock(), srcu_read_unlock(), and synchronize_srcu())
-	may only be invoked from process context.  Unlike other forms of
-	RCU, it -is- permissible to block in an SRCU read-side critical
-	section (demarked by srcu_read_lock() and srcu_read_unlock()),
-	hence the "SRCU": "sleepable RCU".  Please note that if you
-	don't need to sleep in read-side critical sections, you should
-	be using RCU rather than SRCU, because RCU is almost always
-	faster and easier to use than is SRCU.
+14.	SRCU (srcu_read_lock(), srcu_read_unlock(), srcu_dereference(),
+	synchronize_srcu(), and synchronize_srcu_expedited()) may only
+	be invoked from process context.  Unlike other forms of RCU, it
+	-is- permissible to block in an SRCU read-side critical section
+	(demarked by srcu_read_lock() and srcu_read_unlock()), hence the
+	"SRCU": "sleepable RCU".  Please note that if you don't need
+	to sleep in read-side critical sections, you should be using
+	RCU rather than SRCU, because RCU is almost always faster and
+	easier to use than is SRCU.
 
 	Also unlike other forms of RCU, explicit initialization
 	and cleanup is required via init_srcu_struct() and
 	cleanup_srcu_struct().	These are passed a "struct srcu_struct"
 	that defines the scope of a given SRCU domain.	Once initialized,
 	the srcu_struct is passed to srcu_read_lock(), srcu_read_unlock()
-	and synchronize_srcu().  A given synchronize_srcu() waits only
-	for SRCU read-side critical sections governed by srcu_read_lock()
-	and srcu_read_unlock() calls that have been passd the same
-	srcu_struct.  This property is what makes sleeping read-side
-	critical sections tolerable -- a given subsystem delays only
-	its own updates, not those of other subsystems using SRCU.
-	Therefore, SRCU is less prone to OOM the system than RCU would
-	be if RCU's read-side critical sections were permitted to
-	sleep.
+	synchronize_srcu(), and synchronize_srcu_expedited().  A given
+	synchronize_srcu() waits only for SRCU read-side critical
+	sections governed by srcu_read_lock() and srcu_read_unlock()
+	calls that have been passed the same srcu_struct.  This property
+	is what makes sleeping read-side critical sections tolerable --
+	a given subsystem delays only its own updates, not those of other
+	subsystems using SRCU.	Therefore, SRCU is less prone to OOM the
+	system than RCU would be if RCU's read-side critical sections
+	were permitted to sleep.
 
 	The ability to sleep in read-side critical sections does not
 	come for free.	First, corresponding srcu_read_lock() and
@@ -300,8 +345,8 @@ over a rather long period of time, but i
 	requiring SRCU's read-side deadlock immunity or low read-side
 	realtime latency.
 
-	Note that, rcu_assign_pointer() and rcu_dereference() relate to
-	SRCU just as they do to other forms of RCU.
+	Note that, rcu_assign_pointer() relates to SRCU just as they do
+	to other forms of RCU.
 
 15.	The whole point of call_rcu(), synchronize_rcu(), and friends
 	is to wait until all pre-existing readers have finished before
@@ -311,12 +356,12 @@ over a rather long period of time, but i
 	destructive operation, and -only- -then- invoke call_rcu(),
 	synchronize_rcu(), or friends.
 
-	Because these primitives only wait for pre-existing readers,
-	it is the caller's responsibility to guarantee safety to
-	any subsequent readers.
+	Because these primitives only wait for pre-existing readers, it
+	is the caller's responsibility to guarantee that any subsequent
+	readers will execute safely.
 
-16.	The various RCU read-side primitives do -not- contain memory
-	barriers.  The CPU (and in some cases, the compiler) is free
-	to reorder code into and out of RCU read-side critical sections.
-	It is the responsibility of the RCU update-side primitives to
-	deal with this.
+16.	The various RCU read-side primitives do -not- necessarily contain
+	memory barriers.  You should therefore plan for the CPU
+	and the compiler to freely reorder code into and out of RCU
+	read-side critical sections.  It is the responsibility of the
+	RCU update-side primitives to deal with this.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/RCU/lockdep.txt linux-libre-2.6.34-gnu1/Documentation/RCU/lockdep.txt
--- linux-libre-2.6.33-gnu1/Documentation/RCU/lockdep.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/RCU/lockdep.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,91 @@
+RCU and lockdep checking
+
+All flavors of RCU have lockdep checking available, so that lockdep is
+aware of when each task enters and leaves any flavor of RCU read-side
+critical section.  Each flavor of RCU is tracked separately (but note
+that this is not the case in 2.6.32 and earlier).  This allows lockdep's
+tracking to include RCU state, which can sometimes help when debugging
+deadlocks and the like.
+
+In addition, RCU provides the following primitives that check lockdep's
+state:
+
+	rcu_read_lock_held() for normal RCU.
+	rcu_read_lock_bh_held() for RCU-bh.
+	rcu_read_lock_sched_held() for RCU-sched.
+	srcu_read_lock_held() for SRCU.
+
+These functions are conservative, and will therefore return 1 if they
+aren't certain (for example, if CONFIG_DEBUG_LOCK_ALLOC is not set).
+This prevents things like WARN_ON(!rcu_read_lock_held()) from giving false
+positives when lockdep is disabled.
+
+In addition, a separate kernel config parameter CONFIG_PROVE_RCU enables
+checking of rcu_dereference() primitives:
+
+	rcu_dereference(p):
+		Check for RCU read-side critical section.
+	rcu_dereference_bh(p):
+		Check for RCU-bh read-side critical section.
+	rcu_dereference_sched(p):
+		Check for RCU-sched read-side critical section.
+	srcu_dereference(p, sp):
+		Check for SRCU read-side critical section.
+	rcu_dereference_check(p, c):
+		Use explicit check expression "c".  This is useful in
+		code that is invoked by both readers and updaters.
+	rcu_dereference_raw(p)
+		Don't check.  (Use sparingly, if at all.)
+	rcu_dereference_protected(p, c):
+		Use explicit check expression "c", and omit all barriers
+		and compiler constraints.  This is useful when the data
+		structure cannot change, for example, in code that is
+		invoked only by updaters.
+	rcu_access_pointer(p):
+		Return the value of the pointer and omit all barriers,
+		but retain the compiler constraints that prevent duplicating
+		or coalescsing.  This is useful when when testing the
+		value of the pointer itself, for example, against NULL.
+
+The rcu_dereference_check() check expression can be any boolean
+expression, but would normally include one of the rcu_read_lock_held()
+family of functions and a lockdep expression.  However, any boolean
+expression can be used.  For a moderately ornate example, consider
+the following:
+
+	file = rcu_dereference_check(fdt->fd[fd],
+				     rcu_read_lock_held() ||
+				     lockdep_is_held(&files->file_lock) ||
+				     atomic_read(&files->count) == 1);
+
+This expression picks up the pointer "fdt->fd[fd]" in an RCU-safe manner,
+and, if CONFIG_PROVE_RCU is configured, verifies that this expression
+is used in:
+
+1.	An RCU read-side critical section, or
+2.	with files->file_lock held, or
+3.	on an unshared files_struct.
+
+In case (1), the pointer is picked up in an RCU-safe manner for vanilla
+RCU read-side critical sections, in case (2) the ->file_lock prevents
+any change from taking place, and finally, in case (3) the current task
+is the only task accessing the file_struct, again preventing any change
+from taking place.  If the above statement was invoked only from updater
+code, it could instead be written as follows:
+
+	file = rcu_dereference_protected(fdt->fd[fd],
+					 lockdep_is_held(&files->file_lock) ||
+					 atomic_read(&files->count) == 1);
+
+This would verify cases #2 and #3 above, and furthermore lockdep would
+complain if this was used in an RCU read-side critical section unless one
+of these two cases held.  Because rcu_dereference_protected() omits all
+barriers and compiler constraints, it generates better code than do the
+other flavors of rcu_dereference().  On the other hand, it is illegal
+to use rcu_dereference_protected() if either the RCU-protected pointer
+or the RCU-protected data that it points to can change concurrently.
+
+There are currently only "universal" versions of the rcu_assign_pointer()
+and RCU list-/tree-traversal primitives, which do not (yet) check for
+being in an RCU read-side critical section.  In the future, separate
+versions of these primitives might be created.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/RCU/NMI-RCU.txt linux-libre-2.6.34-gnu1/Documentation/RCU/NMI-RCU.txt
--- linux-libre-2.6.33-gnu1/Documentation/RCU/NMI-RCU.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/RCU/NMI-RCU.txt	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,7 @@ NMI handler.
 		cpu = smp_processor_id();
 		++nmi_count(cpu);
 
-		if (!rcu_dereference(nmi_callback)(regs, cpu))
+		if (!rcu_dereference_sched(nmi_callback)(regs, cpu))
 			default_do_nmi(regs);
 
 		nmi_exit();
@@ -47,12 +47,13 @@ function pointer.  If this handler retur
 default_do_nmi() function to handle a machine-specific NMI.  Finally,
 preemption is restored.
 
-Strictly speaking, rcu_dereference() is not needed, since this code runs
-only on i386, which does not need rcu_dereference() anyway.  However,
-it is a good documentation aid, particularly for anyone attempting to
-do something similar on Alpha.
+In theory, rcu_dereference_sched() is not needed, since this code runs
+only on i386, which in theory does not need rcu_dereference_sched()
+anyway.  However, in practice it is a good documentation aid, particularly
+for anyone attempting to do something similar on Alpha or on systems
+with aggressive optimizing compilers.
 
-Quick Quiz:  Why might the rcu_dereference() be necessary on Alpha,
+Quick Quiz:  Why might the rcu_dereference_sched() be necessary on Alpha,
 	     given that the code referenced by the pointer is read-only?
 
 
@@ -99,17 +100,21 @@ invoke irq_enter() and irq_exit() on NMI
 
 Answer to Quick Quiz
 
-	Why might the rcu_dereference() be necessary on Alpha, given
+	Why might the rcu_dereference_sched() be necessary on Alpha, given
 	that the code referenced by the pointer is read-only?
 
 	Answer: The caller to set_nmi_callback() might well have
-		initialized some data that is to be used by the
-		new NMI handler.  In this case, the rcu_dereference()
-		would be needed, because otherwise a CPU that received
-		an NMI just after the new handler was set might see
-		the pointer to the new NMI handler, but the old
-		pre-initialized version of the handler's data.
+		initialized some data that is to be used by the new NMI
+		handler.  In this case, the rcu_dereference_sched() would
+		be needed, because otherwise a CPU that received an NMI
+		just after the new handler was set might see the pointer
+		to the new NMI handler, but the old pre-initialized
+		version of the handler's data.
 
-		More important, the rcu_dereference() makes it clear
-		to someone reading the code that the pointer is being
-		protected by RCU.
+		This same sad story can happen on other CPUs when using
+		a compiler with aggressive pointer-value speculation
+		optimizations.
+
+		More important, the rcu_dereference_sched() makes it
+		clear to someone reading the code that the pointer is
+		being protected by RCU-sched.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/RCU/rcu.txt linux-libre-2.6.34-gnu1/Documentation/RCU/rcu.txt
--- linux-libre-2.6.33-gnu1/Documentation/RCU/rcu.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/RCU/rcu.txt	2010-05-16 17:17:36.000000000 -0400
@@ -75,6 +75,8 @@ o	I hear that RCU is patented?  What is
 	search for the string "Patent" in RTFP.txt to find them.
 	Of these, one was allowed to lapse by the assignee, and the
 	others have been contributed to the Linux kernel under GPL.
+	There are now also LGPL implementations of user-level RCU
+	available (http://lttng.org/?q=node/18).
 
 o	I hear that RCU needs work in order to support realtime kernels?
 
@@ -91,48 +93,4 @@ o	Where can I find more information on R
 
 o	What are all these files in this directory?
 
-
-	NMI-RCU.txt
-
-		Describes how to use RCU to implement dynamic
-		NMI handlers, which can be revectored on the fly,
-		without rebooting.
-
-	RTFP.txt
-
-		List of RCU-related publications and web sites.
-
-	UP.txt
-
-		Discussion of RCU usage in UP kernels.
-
-	arrayRCU.txt
-
-		Describes how to use RCU to protect arrays, with
-		resizeable arrays whose elements reference other
-		data structures being of the most interest.
-
-	checklist.txt
-
-		Lists things to check for when inspecting code that
-		uses RCU.
-
-	listRCU.txt
-
-		Describes how to use RCU to protect linked lists.
-		This is the simplest and most common use of RCU
-		in the Linux kernel.
-
-	rcu.txt
-
-		You are reading it!
-
-	rcuref.txt
-
-		Describes how to combine use of reference counts
-		with RCU.
-
-	whatisRCU.txt
-
-		Overview of how the RCU implementation works.  Along
-		the way, presents a conceptual view of RCU.
+	See 00-INDEX for the list.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/RCU/RTFP.txt linux-libre-2.6.34-gnu1/Documentation/RCU/RTFP.txt
--- linux-libre-2.6.33-gnu1/Documentation/RCU/RTFP.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/RCU/RTFP.txt	2010-05-16 17:17:36.000000000 -0400
@@ -25,10 +25,10 @@ to be referencing the data structure.  H
 optimized for modern computer systems, which is not surprising given
 that these overheads were not so expensive in the mid-80s.  Nonetheless,
 passive serialization appears to be the first deferred-destruction
-mechanism to be used in production.  Furthermore, the relevant patent has
-lapsed, so this approach may be used in non-GPL software, if desired.
-(In contrast, use of RCU is permitted only in software licensed under
-GPL.  Sorry!!!)
+mechanism to be used in production.  Furthermore, the relevant patent
+has lapsed, so this approach may be used in non-GPL software, if desired.
+(In contrast, implementation of RCU is permitted only in software licensed
+under either GPL or LGPL.  Sorry!!!)
 
 In 1990, Pugh [Pugh90] noted that explicitly tracking which threads
 were reading a given data structure permitted deferred free to operate
@@ -150,6 +150,18 @@ preemptible RCU [PaulEMcKenney2007Preemp
 LWN "What is RCU?" series [PaulEMcKenney2007WhatIsRCUFundamentally,
 PaulEMcKenney2008WhatIsRCUUsage, and PaulEMcKenney2008WhatIsRCUAPI].
 
+2008 saw a journal paper on real-time RCU [DinakarGuniguntala2008IBMSysJ],
+a history of how Linux changed RCU more than RCU changed Linux
+[PaulEMcKenney2008RCUOSR], and a design overview of hierarchical RCU
+[PaulEMcKenney2008HierarchicalRCU].
+
+2009 introduced user-level RCU algorithms [PaulEMcKenney2009MaliciousURCU],
+which Mathieu Desnoyers is now maintaining [MathieuDesnoyers2009URCU]
+[MathieuDesnoyersPhD].  TINY_RCU [PaulEMcKenney2009BloatWatchRCU] made
+its appearance, as did expedited RCU [PaulEMcKenney2009expeditedRCU].
+The problem of resizeable RCU-protected hash tables may now be on a path
+to a solution [JoshTriplett2009RPHash].
+
 Bibtex Entries
 
 @article{Kung80
@@ -730,6 +742,11 @@ Revised:
 "
 }
 
+#
+#	"What is RCU?" LWN series.
+#
+########################################################################
+
 @article{DinakarGuniguntala2008IBMSysJ
 ,author="D. Guniguntala and P. E. McKenney and J. Triplett and J. Walpole"
 ,title="The read-copy-update mechanism for supporting real-time applications on shared-memory multiprocessor systems with {Linux}"
@@ -820,3 +837,39 @@ Revised:
 	Uniprocessor assumptions allow simplified RCU implementation.
 "
 }
+
+@unpublished{PaulEMcKenney2009expeditedRCU
+,Author="Paul E. McKenney"
+,Title="[{PATCH} -tip 0/3] expedited 'big hammer' {RCU} grace periods"
+,month="June"
+,day="25"
+,year="2009"
+,note="Available:
+\url{http://lkml.org/lkml/2009/6/25/306}
+[Viewed August 16, 2009]"
+,annotation="
+	First posting of expedited RCU to be accepted into -tip.
+"
+}
+
+@unpublished{JoshTriplett2009RPHash
+,Author="Josh Triplett"
+,Title="Scalable concurrent hash tables via relativistic programming"
+,month="September"
+,year="2009"
+,note="Linux Plumbers Conference presentation"
+,annotation="
+	RP fun with hash tables.
+"
+}
+
+@phdthesis{MathieuDesnoyersPhD
+, title  = "Low-Impact Operating System Tracing"
+, author = "Mathieu Desnoyers"
+, school = "Ecole Polytechnique de Montr\'{e}al"
+, month  = "December"
+, year   = 2009
+,note="Available:
+\url{http://www.lttng.org/pub/thesis/desnoyers-dissertation-2009-12.pdf}
+[Viewed December 9, 2009]"
+}
diff -druNp linux-libre-2.6.33-gnu1/Documentation/RCU/stallwarn.txt linux-libre-2.6.34-gnu1/Documentation/RCU/stallwarn.txt
--- linux-libre-2.6.33-gnu1/Documentation/RCU/stallwarn.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/RCU/stallwarn.txt	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,58 @@
+Using RCU's CPU Stall Detector
+
+The CONFIG_RCU_CPU_STALL_DETECTOR kernel config parameter enables
+RCU's CPU stall detector, which detects conditions that unduly delay
+RCU grace periods.  The stall detector's idea of what constitutes
+"unduly delayed" is controlled by a pair of C preprocessor macros:
+
+RCU_SECONDS_TILL_STALL_CHECK
+
+	This macro defines the period of time that RCU will wait from
+	the beginning of a grace period until it issues an RCU CPU
+	stall warning.	It is normally ten seconds.
+
+RCU_SECONDS_TILL_STALL_RECHECK
+
+	This macro defines the period of time that RCU will wait after
+	issuing a stall warning until it issues another stall warning.
+	It is normally set to thirty seconds.
+
+RCU_STALL_RAT_DELAY
+
+	The CPU stall detector tries to make the offending CPU rat on itself,
+	as this often gives better-quality stack traces.  However, if
+	the offending CPU does not detect its own stall in the number
+	of jiffies specified by RCU_STALL_RAT_DELAY, then other CPUs will
+	complain.  This is normally set to two jiffies.
+
+The following problems can result in an RCU CPU stall warning:
+
+o	A CPU looping in an RCU read-side critical section.
+	
+o	A CPU looping with interrupts disabled.
+
+o	A CPU looping with preemption disabled.
+
+o	For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel
+	without invoking schedule().
+
+o	A bug in the RCU implementation.
+
+o	A hardware failure.  This is quite unlikely, but has occurred
+	at least once in a former life.  A CPU failed in a running system,
+	becoming unresponsive, but not causing an immediate crash.
+	This resulted in a series of RCU CPU stall warnings, eventually
+	leading the realization that the CPU had failed.
+
+The RCU, RCU-sched, and RCU-bh implementations have CPU stall warning.
+SRCU does not do so directly, but its calls to synchronize_sched() will
+result in RCU-sched detecting any CPU stalls that might be occurring.
+
+To diagnose the cause of the stall, inspect the stack traces.  The offending
+function will usually be near the top of the stack.  If you have a series
+of stall warnings from a single extended stall, comparing the stack traces
+can often help determine where the stall is occurring, which will usually
+be in the function nearest the top of the stack that stays the same from
+trace to trace.
+
+RCU bugs can often be debugged with the help of CONFIG_RCU_TRACE.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/RCU/torture.txt linux-libre-2.6.34-gnu1/Documentation/RCU/torture.txt
--- linux-libre-2.6.33-gnu1/Documentation/RCU/torture.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/RCU/torture.txt	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,18 @@ MODULE PARAMETERS
 
 This module has the following parameters:
 
+fqs_duration	Duration (in microseconds) of artificially induced bursts
+		of force_quiescent_state() invocations.  In RCU
+		implementations having force_quiescent_state(), these
+		bursts help force races between forcing a given grace
+		period and that grace period ending on its own.
+
+fqs_holdoff	Holdoff time (in microseconds) between consecutive calls
+		to force_quiescent_state() within a burst.
+
+fqs_stutter	Wait time (in seconds) between consecutive bursts
+		of calls to force_quiescent_state().
+
 irqreaders	Says to invoke RCU readers from irq level.  This is currently
 		done via timers.  Defaults to "1" for variants of RCU that
 		permit this.  (Or, more accurately, variants of RCU that do
diff -druNp linux-libre-2.6.33-gnu1/Documentation/RCU/whatisRCU.txt linux-libre-2.6.34-gnu1/Documentation/RCU/whatisRCU.txt
--- linux-libre-2.6.33-gnu1/Documentation/RCU/whatisRCU.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/RCU/whatisRCU.txt	2010-05-16 17:17:36.000000000 -0400
@@ -323,14 +323,17 @@ used as follows:
 	Defer			Protect
 
 a.	synchronize_rcu()	rcu_read_lock() / rcu_read_unlock()
-	call_rcu()
+	call_rcu()		rcu_dereference()
 
 b.	call_rcu_bh()		rcu_read_lock_bh() / rcu_read_unlock_bh()
+				rcu_dereference_bh()
 
-c.	synchronize_sched()	preempt_disable() / preempt_enable()
+c.	synchronize_sched()	rcu_read_lock_sched() / rcu_read_unlock_sched()
+				preempt_disable() / preempt_enable()
 				local_irq_save() / local_irq_restore()
 				hardirq enter / hardirq exit
 				NMI enter / NMI exit
+				rcu_dereference_sched()
 
 These three mechanisms are used as follows:
 
@@ -780,9 +783,8 @@ Linux-kernel source code, but it helps t
 APIs, since there does not appear to be a way to categorize them
 in docbook.  Here is the list, by category.
 
-RCU pointer/list traversal:
+RCU list traversal:
 
-	rcu_dereference
 	list_for_each_entry_rcu
 	hlist_for_each_entry_rcu
 	hlist_nulls_for_each_entry_rcu
@@ -808,7 +810,7 @@ RCU:	Critical sections	Grace period		Bar
 
 	rcu_read_lock		synchronize_net		rcu_barrier
 	rcu_read_unlock		synchronize_rcu
-				synchronize_rcu_expedited
+	rcu_dereference		synchronize_rcu_expedited
 				call_rcu
 
 
@@ -816,7 +818,7 @@ bh:	Critical sections	Grace period		Barr
 
 	rcu_read_lock_bh	call_rcu_bh		rcu_barrier_bh
 	rcu_read_unlock_bh	synchronize_rcu_bh
-				synchronize_rcu_bh_expedited
+	rcu_dereference_bh	synchronize_rcu_bh_expedited
 
 
 sched:	Critical sections	Grace period		Barrier
@@ -825,17 +827,25 @@ sched:	Critical sections	Grace period		B
 	rcu_read_unlock_sched	call_rcu_sched
 	[preempt_disable]	synchronize_sched_expedited
 	[and friends]
+	rcu_dereference_sched
 
 
 SRCU:	Critical sections	Grace period		Barrier
 
 	srcu_read_lock		synchronize_srcu	N/A
 	srcu_read_unlock	synchronize_srcu_expedited
+	srcu_dereference
 
 SRCU:	Initialization/cleanup
 	init_srcu_struct
 	cleanup_srcu_struct
 
+All:  lockdep-checked RCU-protected pointer access
+
+	rcu_dereference_check
+	rcu_dereference_protected
+	rcu_access_pointer
+
 See the comment headers in the source code (or the docbook generated
 from them) for more information.
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/s390/CommonIO linux-libre-2.6.34-gnu1/Documentation/s390/CommonIO
--- linux-libre-2.6.33-gnu1/Documentation/s390/CommonIO	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/s390/CommonIO	2010-05-16 17:17:36.000000000 -0400
@@ -87,6 +87,12 @@ Command line parameters
   compatibility, by the device number in hexadecimal (0xabcd or abcd). Device
   numbers given as 0xabcd will be interpreted as 0.0.abcd.
 
+* /proc/cio_settle
+
+  A write request to this file is blocked until all queued cio actions are
+  handled. This will allow userspace to wait for pending work affecting
+  device availability after changing cio_ignore or the hardware configuration.
+
 * For some of the information present in the /proc filesystem in 2.4 (namely,
   /proc/subchannels and /proc/chpids), see driver-model.txt.
   Information formerly in /proc/irq_count is now in /proc/interrupts.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/s390/driver-model.txt linux-libre-2.6.34-gnu1/Documentation/s390/driver-model.txt
--- linux-libre-2.6.33-gnu1/Documentation/s390/driver-model.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/s390/driver-model.txt	2010-05-16 17:17:36.000000000 -0400
@@ -223,8 +223,8 @@ touched by the driver - it should use th
 private data.
 
 To implement a ccwgroup driver, please refer to include/asm/ccwgroup.h. Keep in
-mind that most drivers will need to implement both a ccwgroup and a ccw driver
-(unless you have a meta ccw driver, like cu3088 for lcs and ctc).
+mind that most drivers will need to implement both a ccwgroup and a ccw
+driver.
 
 
 2. Channel paths
diff -druNp linux-libre-2.6.33-gnu1/Documentation/s390/kvm.txt linux-libre-2.6.34-gnu1/Documentation/s390/kvm.txt
--- linux-libre-2.6.33-gnu1/Documentation/s390/kvm.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/s390/kvm.txt	2010-05-16 17:17:36.000000000 -0400
@@ -102,7 +102,7 @@ args:		unsigned long
 see also:	include/linux/kvm.h
 This ioctl stores the state of the cpu at the guest real address given as
 argument, unless one of the following values defined in include/linux/kvm.h
-is given as arguement:
+is given as argument:
 KVM_S390_STORE_STATUS_NOADDR - the CPU stores its status to the save area in
 absolute lowcore as defined by the principles of operation
 KVM_S390_STORE_STATUS_PREFIXED - the CPU stores its status to the save area in
diff -druNp linux-libre-2.6.33-gnu1/Documentation/scsi/ChangeLog.lpfc linux-libre-2.6.34-gnu1/Documentation/scsi/ChangeLog.lpfc
--- linux-libre-2.6.33-gnu1/Documentation/scsi/ChangeLog.lpfc	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/scsi/ChangeLog.lpfc	2010-05-16 17:17:36.000000000 -0400
@@ -989,8 +989,8 @@ Changes from 20040709 to 20040716
 	* Remove redundant port_cmp != 2 check in if
 	  (!port_cmp) { .... if (port_cmp != 2).... }
 	* Clock changes: removed struct clk_data and timerList.
-	* Clock changes: seperate nodev_tmo and els_retry_delay into 2
-	  seperate timers and convert to 1 argument changed
+	* Clock changes: separate nodev_tmo and els_retry_delay into 2
+	  separate timers and convert to 1 argument changed
 	  LPFC_NODE_FARP_PEND_t to struct lpfc_node_farp_pend convert
 	  ipfarp_tmo to 1 argument convert target struct tmofunc and
 	  rtplunfunc to 1 argument * cr_count, cr_delay and
@@ -1514,7 +1514,7 @@ Changes from 20040402 to 20040409
 	* Remove unused elxclock declaration in elx_sli.h.
 	* Since everywhere IOCB_ENTRY is used, the return value is cast,
 	  move the cast into the macro.
-	* Split ioctls out into seperate files
+	* Split ioctls out into separate files
 
 Changes from 20040326 to 20040402
 
@@ -1534,7 +1534,7 @@ Changes from 20040326 to 20040402
 	* Unused variable cleanup
 	* Use Linux list macros for DMABUF_t
 	* Break up ioctls into 3 sections, dfc, util, hbaapi
-	  rearranged code so this could be easily seperated into a
+	  rearranged code so this could be easily separated into a
 	  differnet module later All 3 are currently turned on by
 	  defines in lpfc_ioctl.c LPFC_DFC_IOCTL, LPFC_UTIL_IOCTL,
 	  LPFC_HBAAPI_IOCTL
@@ -1551,7 +1551,7 @@ Changes from 20040326 to 20040402
 	  started by lpfc_online().  lpfc_offline() only stopped
 	  els_timeout routine.  It now stops all timeout routines
 	  associated with that hba.
-	* Replace seperate next and prev pointers in struct
+	* Replace separate next and prev pointers in struct
 	  lpfc_bindlist with list_head type.  In elxHBA_t, replace
 	  fc_nlpbind_start and _end with fc_nlpbind_list and use
 	  list_head macros to access it.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/scsi/ChangeLog.megaraid_sas linux-libre-2.6.34-gnu1/Documentation/scsi/ChangeLog.megaraid_sas
--- linux-libre-2.6.33-gnu1/Documentation/scsi/ChangeLog.megaraid_sas	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/scsi/ChangeLog.megaraid_sas	2010-05-16 17:17:36.000000000 -0400
@@ -1,3 +1,19 @@
+1 Release Date    : Thur.  Oct 29, 2009 09:12:45 PST 2009 -
+			(emaild-id:megaraidlinux@lsi.com)
+			Bo Yang
+
+2 Current Version : 00.00.04.17.1-rc1
+3 Older Version   : 00.00.04.12
+
+1.	Add the pad_0 in mfi frame structure to 0 to fix the
+	context value larger than 32bit value issue.
+
+2.	Add the logic drive list to the driver.  Driver will
+	keep the logic drive list internal after driver load.
+
+3.	driver fixed the device update issue after get the AEN
+	PD delete/ADD, LD add/delete from FW.
+
 1 Release Date    : Tues.  July 28, 2009 10:12:45 PST 2009 -
 			(emaild-id:megaraidlinux@lsi.com)
 			Bo Yang
diff -druNp linux-libre-2.6.33-gnu1/Documentation/serial/tty.txt linux-libre-2.6.34-gnu1/Documentation/serial/tty.txt
--- linux-libre-2.6.33-gnu1/Documentation/serial/tty.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/serial/tty.txt	2010-05-16 17:17:36.000000000 -0400
@@ -105,6 +105,10 @@ write_wakeup()	-	May be called at any po
 			is permitted to call the driver write method from
 			this function. In such a situation defer it.
 
+dcd_change()	-	Report to the tty line the current DCD pin status
+			changes and the relative timestamp. The timestamp
+			can be NULL.
+
 
 Driver Access
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/sound/alsa/ALSA-Configuration.txt linux-libre-2.6.34-gnu1/Documentation/sound/alsa/ALSA-Configuration.txt
--- linux-libre-2.6.33-gnu1/Documentation/sound/alsa/ALSA-Configuration.txt	2013-05-03 12:15:05.000000000 -0400
+++ linux-libre-2.6.34-gnu1/Documentation/sound/alsa/ALSA-Configuration.txt	2013-05-03 09:54:43.000000000 -0400
@@ -482,6 +482,9 @@ Prior to version 0.9.0rc4 options had a
 
     reference_rate	- reference sample rate, 44100 or 48000 (default)
     multiple		- multiple to ref. sample rate, 1 or 2 (default)
+    subsystem		- override the PCI SSID for probing; the value
+			  consists of SSVID << 16 | SSDID.  The default is
+			  zero, which means no override.
 
     This module supports multiple cards.
 
@@ -1123,6 +1126,21 @@ Prior to version 0.9.0rc4 options had a
 
     This module supports multiple cards, autoprobe and ISA PnP.
 
+  Module snd-jazz16
+  -------------------
+
+    Module for Media Vision Jazz16 chipset. The chipset consists of 3 chips:
+    MVD1216 + MVA416 + MVA514.
+
+    port	- port # for SB DSP chip (0x210,0x220,0x230,0x240,0x250,0x260)
+    irq		- IRQ # for SB DSP chip (3,5,7,9,10,15)
+    dma8	- DMA # for SB DSP chip (1,3)
+    dma16	- DMA # for SB DSP chip (5,7)
+    mpu_port	- MPU-401 port # (0x300,0x310,0x320,0x330)
+    mpu_irq	- MPU-401 irq # (2,3,5,7)
+
+    This module supports multiple cards.
+
   Module snd-korg1212
   -------------------
 
@@ -1782,6 +1800,13 @@ Prior to version 0.9.0rc4 options had a
 
     The power-management is supported.
 
+  Module snd-ua101
+  ----------------
+
+    Module for the Edirol UA-101/UA-1000 audio/MIDI interfaces.
+
+    This module supports multiple devices, autoprobe and hotplugging.
+
   Module snd-usb-audio
   --------------------
 
@@ -1914,7 +1939,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, HDAV1.3 (Deluxe), Essence ST
+    i.e., Xonar D1, DX, D2, D2X, DS, HDAV1.3 (Deluxe), Essence ST
     (Deluxe) and Essence STX.
 
     This module supports autoprobe and multiple cards.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/sound/alsa/HD-Audio-Models.txt linux-libre-2.6.34-gnu1/Documentation/sound/alsa/HD-Audio-Models.txt
--- linux-libre-2.6.33-gnu1/Documentation/sound/alsa/HD-Audio-Models.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/sound/alsa/HD-Audio-Models.txt	2010-05-16 17:17:36.000000000 -0400
@@ -124,6 +124,8 @@ ALC882/883/885/888/889
   asus-a7m	ASUS A7M
   macpro	MacPro support
   mb5		Macbook 5,1
+  macmini3	Macmini 3,1
+  mba21		Macbook Air 2,1
   mbp3		Macbook Pro rev3
   imac24	iMac 24'' with jack detection
   imac91	iMac 9,1
@@ -279,13 +281,16 @@ Conexant 5051
   laptop	Basic Laptop config (default)
   hp		HP Spartan laptop
   hp-dv6736	HP dv6736
+  hp-f700	HP Compaq Presario F700
   lenovo-x200	Lenovo X200 laptop
+  toshiba	Toshiba Satellite M300
 
 Conexant 5066
 =============
   laptop	Basic Laptop config (default)
   dell-laptop	Dell laptops
   olpc-xo-1_5	OLPC XO 1.5
+  ideapad       Lenovo IdeaPad U150
 
 STAC9200
 ========
diff -druNp linux-libre-2.6.33-gnu1/Documentation/sound/alsa/HD-Audio.txt linux-libre-2.6.34-gnu1/Documentation/sound/alsa/HD-Audio.txt
--- linux-libre-2.6.33-gnu1/Documentation/sound/alsa/HD-Audio.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/sound/alsa/HD-Audio.txt	2010-05-16 17:17:36.000000000 -0400
@@ -119,10 +119,18 @@ the codec slots 0 and 1 no matter what t
 
 Interrupt Handling
 ~~~~~~~~~~~~~~~~~~
-In rare but some cases, the interrupt isn't properly handled as
-default.  You would notice this by the DMA transfer error reported by
-ALSA PCM core, for example.  Using MSI might help in such a case.
-Pass `enable_msi=1` option for enabling MSI.
+HD-audio driver uses MSI as default (if available) since 2.6.33
+kernel as MSI works better on some machines, and in general, it's
+better for performance.  However, Nvidia controllers showed bad
+regressions with MSI (especially in a combination with AMD chipset),
+thus we disabled MSI for them.
+
+There seem also still other devices that don't work with MSI.  If you
+see a regression wrt the sound quality (stuttering, etc) or a lock-up
+in the recent kernel, try to pass `enable_msi=0` option to disable
+MSI.  If it works, you can add the known bad device to the blacklist
+defined in hda_intel.c.  In such a case, please report and give the
+patch back to the upstream developer. 
 
 
 HD-AUDIO CODEC
@@ -452,6 +460,33 @@ Similarly, the lines after `[verb]` are
 sysfs entries, and the lines after `[hint]` are parsed as `hints`
 sysfs entries, respectively.
 
+Another example to override the codec vendor id from 0x12345678 to
+0xdeadbeef is like below:
+------------------------------------------------------------------------
+  [codec]
+  0x12345678 0xabcd1234 2
+
+  [vendor_id]
+  0xdeadbeef
+------------------------------------------------------------------------
+
+In the similar way, you can override the codec subsystem_id via
+`[subsystem_id]`, the revision id via `[revision_id]` line.
+Also, the codec chip name can be rewritten via `[chip_name]` line.
+------------------------------------------------------------------------
+  [codec]
+  0x12345678 0xabcd1234 2
+
+  [subsystem_id]
+  0xffff1111
+
+  [revision_id]
+  0x10
+
+  [chip_name]
+  My-own NEWS-0002
+------------------------------------------------------------------------
+
 The hd-audio driver reads the file via request_firmware().  Thus,
 a patch file has to be located on the appropriate firmware path,
 typically, /lib/firmware.  For example, when you pass the option
diff -druNp linux-libre-2.6.33-gnu1/Documentation/spi/spidev_test.c linux-libre-2.6.34-gnu1/Documentation/spi/spidev_test.c
--- linux-libre-2.6.33-gnu1/Documentation/spi/spidev_test.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/spi/spidev_test.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,7 +58,7 @@ static void transfer(int fd)
 	};
 
 	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
-	if (ret == 1)
+	if (ret < 1)
 		pabort("can't send spi message");
 
 	for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {
diff -druNp linux-libre-2.6.33-gnu1/Documentation/stable_kernel_rules.txt linux-libre-2.6.34-gnu1/Documentation/stable_kernel_rules.txt
--- linux-libre-2.6.33-gnu1/Documentation/stable_kernel_rules.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/stable_kernel_rules.txt	2010-05-16 17:17:36.000000000 -0400
@@ -18,16 +18,15 @@ Rules on what kind of patches are accept
  - It cannot contain any "trivial" fixes in it (spelling changes,
    whitespace cleanups, etc).
  - It must follow the Documentation/SubmittingPatches rules.
- - It or an equivalent fix must already exist in Linus' tree.  Quote the
-   respective commit ID in Linus' tree in your patch submission to -stable.
+ - It or an equivalent fix must already exist in Linus' tree (upstream).
 
 
 Procedure for submitting patches to the -stable tree:
 
  - Send the patch, after verifying that it follows the above rules, to
-   stable@kernel.org.
- - To have the patch automatically included in the stable tree, add the
-   the tag
+   stable@kernel.org.  You must note the upstream commit ID in the changelog
+   of your submission.
+ - To have the patch automatically included in the stable tree, add the tag
      Cc: stable@kernel.org
    in the sign-off area. Once the patch is merged it will be applied to
    the stable tree without anything else needing to be done by the author
diff -druNp linux-libre-2.6.33-gnu1/Documentation/SubmitChecklist linux-libre-2.6.34-gnu1/Documentation/SubmitChecklist
--- linux-libre-2.6.33-gnu1/Documentation/SubmitChecklist	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/SubmitChecklist	2010-05-16 17:17:36.000000000 -0400
@@ -9,10 +9,14 @@ Documentation/SubmittingPatches and else
 kernel patches.
 
 
-1: Builds cleanly with applicable or modified CONFIG options =y, =m, and
+1: If you use a facility then #include the file that defines/declares
+   that facility.  Don't depend on other header files pulling in ones
+   that you use.
+
+2: Builds cleanly with applicable or modified CONFIG options =y, =m, and
    =n.  No gcc warnings/errors, no linker warnings/errors.
 
-2: Passes allnoconfig, allmodconfig
+2b: Passes allnoconfig, allmodconfig
 
 3: Builds on multiple CPU architectures by using local cross-compile tools
    or some other build farm.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/sysctl/vm.txt linux-libre-2.6.34-gnu1/Documentation/sysctl/vm.txt
--- linux-libre-2.6.33-gnu1/Documentation/sysctl/vm.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/sysctl/vm.txt	2010-05-16 17:17:36.000000000 -0400
@@ -573,11 +573,14 @@ Because other nodes' memory may be free.
 may be not fatal yet.
 
 If this is set to 2, the kernel panics compulsorily even on the
-above-mentioned.
+above-mentioned. Even oom happens under memory cgroup, the whole
+system panics.
 
 The default value is 0.
 1 and 2 are for failover of clustering. Please select either
 according to your policy of failover.
+panic_on_oom=2+kdump gives you very strong tool to investigate
+why oom happens. You can get snapshot.
 
 =============================================================
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/timers/00-INDEX linux-libre-2.6.34-gnu1/Documentation/timers/00-INDEX
--- linux-libre-2.6.33-gnu1/Documentation/timers/00-INDEX	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/timers/00-INDEX	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,8 @@ highres.txt
 	- High resolution timers and dynamic ticks design notes
 hpet.txt
 	- High Precision Event Timer Driver for Linux
+hpet_example.c
+	- sample hpet timer test program
 hrtimers.txt
 	- subsystem for high-resolution kernel timers
 timer_stats.txt
diff -druNp linux-libre-2.6.33-gnu1/Documentation/timers/hpet_example.c linux-libre-2.6.34-gnu1/Documentation/timers/hpet_example.c
--- linux-libre-2.6.33-gnu1/Documentation/timers/hpet_example.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/timers/hpet_example.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,269 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <memory.h>
+#include <malloc.h>
+#include <time.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <linux/hpet.h>
+
+
+extern void hpet_open_close(int, const char **);
+extern void hpet_info(int, const char **);
+extern void hpet_poll(int, const char **);
+extern void hpet_fasync(int, const char **);
+extern void hpet_read(int, const char **);
+
+#include <sys/poll.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+
+struct hpet_command {
+	char		*command;
+	void		(*func)(int argc, const char ** argv);
+} hpet_command[] = {
+	{
+		"open-close",
+		hpet_open_close
+	},
+	{
+		"info",
+		hpet_info
+	},
+	{
+		"poll",
+		hpet_poll
+	},
+	{
+		"fasync",
+		hpet_fasync
+	},
+};
+
+int
+main(int argc, const char ** argv)
+{
+	int	i;
+
+	argc--;
+	argv++;
+
+	if (!argc) {
+		fprintf(stderr, "-hpet: requires command\n");
+		return -1;
+	}
+
+
+	for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++)
+		if (!strcmp(argv[0], hpet_command[i].command)) {
+			argc--;
+			argv++;
+			fprintf(stderr, "-hpet: executing %s\n",
+				hpet_command[i].command);
+			hpet_command[i].func(argc, argv);
+			return 0;
+		}
+
+	fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]);
+
+	return -1;
+}
+
+void
+hpet_open_close(int argc, const char **argv)
+{
+	int	fd;
+
+	if (argc != 1) {
+		fprintf(stderr, "hpet_open_close: device-name\n");
+		return;
+	}
+
+	fd = open(argv[0], O_RDONLY);
+	if (fd < 0)
+		fprintf(stderr, "hpet_open_close: open failed\n");
+	else
+		close(fd);
+
+	return;
+}
+
+void
+hpet_info(int argc, const char **argv)
+{
+}
+
+void
+hpet_poll(int argc, const char **argv)
+{
+	unsigned long		freq;
+	int			iterations, i, fd;
+	struct pollfd		pfd;
+	struct hpet_info	info;
+	struct timeval		stv, etv;
+	struct timezone		tz;
+	long			usec;
+
+	if (argc != 3) {
+		fprintf(stderr, "hpet_poll: device-name freq iterations\n");
+		return;
+	}
+
+	freq = atoi(argv[1]);
+	iterations = atoi(argv[2]);
+
+	fd = open(argv[0], O_RDONLY);
+
+	if (fd < 0) {
+		fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]);
+		return;
+	}
+
+	if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
+		fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n");
+		goto out;
+	}
+
+	if (ioctl(fd, HPET_INFO, &info) < 0) {
+		fprintf(stderr, "hpet_poll: failed to get info\n");
+		goto out;
+	}
+
+	fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags);
+
+	if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
+		fprintf(stderr, "hpet_poll: HPET_EPI failed\n");
+		goto out;
+	}
+
+	if (ioctl(fd, HPET_IE_ON, 0) < 0) {
+		fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n");
+		goto out;
+	}
+
+	pfd.fd = fd;
+	pfd.events = POLLIN;
+
+	for (i = 0; i < iterations; i++) {
+		pfd.revents = 0;
+		gettimeofday(&stv, &tz);
+		if (poll(&pfd, 1, -1) < 0)
+			fprintf(stderr, "hpet_poll: poll failed\n");
+		else {
+			long 	data;
+
+			gettimeofday(&etv, &tz);
+			usec = stv.tv_sec * 1000000 + stv.tv_usec;
+			usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec;
+
+			fprintf(stderr,
+				"hpet_poll: expired time = 0x%lx\n", usec);
+
+			fprintf(stderr, "hpet_poll: revents = 0x%x\n",
+				pfd.revents);
+
+			if (read(fd, &data, sizeof(data)) != sizeof(data)) {
+				fprintf(stderr, "hpet_poll: read failed\n");
+			}
+			else
+				fprintf(stderr, "hpet_poll: data 0x%lx\n",
+					data);
+		}
+	}
+
+out:
+	close(fd);
+	return;
+}
+
+static int hpet_sigio_count;
+
+static void
+hpet_sigio(int val)
+{
+	fprintf(stderr, "hpet_sigio: called\n");
+	hpet_sigio_count++;
+}
+
+void
+hpet_fasync(int argc, const char **argv)
+{
+	unsigned long		freq;
+	int			iterations, i, fd, value;
+	sig_t			oldsig;
+	struct hpet_info	info;
+
+	hpet_sigio_count = 0;
+	fd = -1;
+
+	if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) {
+		fprintf(stderr, "hpet_fasync: failed to set signal handler\n");
+		return;
+	}
+
+	if (argc != 3) {
+		fprintf(stderr, "hpet_fasync: device-name freq iterations\n");
+		goto out;
+	}
+
+	fd = open(argv[0], O_RDONLY);
+
+	if (fd < 0) {
+		fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]);
+		return;
+	}
+
+
+	if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
+		((value = fcntl(fd, F_GETFL)) == 1) ||
+		(fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
+		fprintf(stderr, "hpet_fasync: fcntl failed\n");
+		goto out;
+	}
+
+	freq = atoi(argv[1]);
+	iterations = atoi(argv[2]);
+
+	if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
+		fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n");
+		goto out;
+	}
+
+	if (ioctl(fd, HPET_INFO, &info) < 0) {
+		fprintf(stderr, "hpet_fasync: failed to get info\n");
+		goto out;
+	}
+
+	fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags);
+
+	if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
+		fprintf(stderr, "hpet_fasync: HPET_EPI failed\n");
+		goto out;
+	}
+
+	if (ioctl(fd, HPET_IE_ON, 0) < 0) {
+		fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n");
+		goto out;
+	}
+
+	for (i = 0; i < iterations; i++) {
+		(void) pause();
+		fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count);
+	}
+
+out:
+	signal(SIGIO, oldsig);
+
+	if (fd >= 0)
+		close(fd);
+
+	return;
+}
diff -druNp linux-libre-2.6.33-gnu1/Documentation/timers/hpet.txt linux-libre-2.6.34-gnu1/Documentation/timers/hpet.txt
--- linux-libre-2.6.33-gnu1/Documentation/timers/hpet.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/timers/hpet.txt	2010-05-16 17:17:36.000000000 -0400
@@ -26,274 +26,5 @@ initialization.  An example of this init
 arch/x86/kernel/hpet.c.
 
 The driver provides a userspace API which resembles the API found in the
-RTC driver framework.  An example user space program is provided below.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <memory.h>
-#include <malloc.h>
-#include <time.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <linux/hpet.h>
-
-
-extern void hpet_open_close(int, const char **);
-extern void hpet_info(int, const char **);
-extern void hpet_poll(int, const char **);
-extern void hpet_fasync(int, const char **);
-extern void hpet_read(int, const char **);
-
-#include <sys/poll.h>
-#include <sys/ioctl.h>
-#include <signal.h>
-
-struct hpet_command {
-	char		*command;
-	void		(*func)(int argc, const char ** argv);
-} hpet_command[] = {
-	{
-		"open-close",
-		hpet_open_close
-	},
-	{
-		"info",
-		hpet_info
-	},
-	{
-		"poll",
-		hpet_poll
-	},
-	{
-		"fasync",
-		hpet_fasync
-	},
-};
-
-int
-main(int argc, const char ** argv)
-{
-	int	i;
-
-	argc--;
-	argv++;
-
-	if (!argc) {
-		fprintf(stderr, "-hpet: requires command\n");
-		return -1;
-	}
-
-
-	for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++)
-		if (!strcmp(argv[0], hpet_command[i].command)) {
-			argc--;
-			argv++;
-			fprintf(stderr, "-hpet: executing %s\n",
-				hpet_command[i].command);
-			hpet_command[i].func(argc, argv);
-			return 0;
-		}
-
-	fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]);
-
-	return -1;
-}
-
-void
-hpet_open_close(int argc, const char **argv)
-{
-	int	fd;
-
-	if (argc != 1) {
-		fprintf(stderr, "hpet_open_close: device-name\n");
-		return;
-	}
-
-	fd = open(argv[0], O_RDONLY);
-	if (fd < 0)
-		fprintf(stderr, "hpet_open_close: open failed\n");
-	else
-		close(fd);
-
-	return;
-}
-
-void
-hpet_info(int argc, const char **argv)
-{
-}
-
-void
-hpet_poll(int argc, const char **argv)
-{
-	unsigned long		freq;
-	int			iterations, i, fd;
-	struct pollfd		pfd;
-	struct hpet_info	info;
-	struct timeval		stv, etv;
-	struct timezone		tz;
-	long			usec;
-
-	if (argc != 3) {
-		fprintf(stderr, "hpet_poll: device-name freq iterations\n");
-		return;
-	}
-
-	freq = atoi(argv[1]);
-	iterations = atoi(argv[2]);
-
-	fd = open(argv[0], O_RDONLY);
-
-	if (fd < 0) {
-		fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]);
-		return;
-	}
-
-	if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
-		fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n");
-		goto out;
-	}
-
-	if (ioctl(fd, HPET_INFO, &info) < 0) {
-		fprintf(stderr, "hpet_poll: failed to get info\n");
-		goto out;
-	}
-
-	fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags);
-
-	if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
-		fprintf(stderr, "hpet_poll: HPET_EPI failed\n");
-		goto out;
-	}
-
-	if (ioctl(fd, HPET_IE_ON, 0) < 0) {
-		fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n");
-		goto out;
-	}
-
-	pfd.fd = fd;
-	pfd.events = POLLIN;
-
-	for (i = 0; i < iterations; i++) {
-		pfd.revents = 0;
-		gettimeofday(&stv, &tz);
-		if (poll(&pfd, 1, -1) < 0)
-			fprintf(stderr, "hpet_poll: poll failed\n");
-		else {
-			long 	data;
-
-			gettimeofday(&etv, &tz);
-			usec = stv.tv_sec * 1000000 + stv.tv_usec;
-			usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec;
-
-			fprintf(stderr,
-				"hpet_poll: expired time = 0x%lx\n", usec);
-
-			fprintf(stderr, "hpet_poll: revents = 0x%x\n",
-				pfd.revents);
-
-			if (read(fd, &data, sizeof(data)) != sizeof(data)) {
-				fprintf(stderr, "hpet_poll: read failed\n");
-			}
-			else
-				fprintf(stderr, "hpet_poll: data 0x%lx\n",
-					data);
-		}
-	}
-
-out:
-	close(fd);
-	return;
-}
-
-static int hpet_sigio_count;
-
-static void
-hpet_sigio(int val)
-{
-	fprintf(stderr, "hpet_sigio: called\n");
-	hpet_sigio_count++;
-}
-
-void
-hpet_fasync(int argc, const char **argv)
-{
-	unsigned long		freq;
-	int			iterations, i, fd, value;
-	sig_t			oldsig;
-	struct hpet_info	info;
-
-	hpet_sigio_count = 0;
-	fd = -1;
-
-	if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) {
-		fprintf(stderr, "hpet_fasync: failed to set signal handler\n");
-		return;
-	}
-
-	if (argc != 3) {
-		fprintf(stderr, "hpet_fasync: device-name freq iterations\n");
-		goto out;
-	}
-
-	fd = open(argv[0], O_RDONLY);
-
-	if (fd < 0) {
-		fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]);
-		return;
-	}
-
-
-	if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
-		((value = fcntl(fd, F_GETFL)) == 1) ||
-		(fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
-		fprintf(stderr, "hpet_fasync: fcntl failed\n");
-		goto out;
-	}
-
-	freq = atoi(argv[1]);
-	iterations = atoi(argv[2]);
-
-	if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
-		fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n");
-		goto out;
-	}
-
-	if (ioctl(fd, HPET_INFO, &info) < 0) {
-		fprintf(stderr, "hpet_fasync: failed to get info\n");
-		goto out;
-	}
-
-	fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags);
-
-	if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
-		fprintf(stderr, "hpet_fasync: HPET_EPI failed\n");
-		goto out;
-	}
-
-	if (ioctl(fd, HPET_IE_ON, 0) < 0) {
-		fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n");
-		goto out;
-	}
-
-	for (i = 0; i < iterations; i++) {
-		(void) pause();
-		fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count);
-	}
-
-out:
-	signal(SIGIO, oldsig);
-
-	if (fd >= 0)
-		close(fd);
-
-	return;
-}
+RTC driver framework.  An example user space program is provided in
+file:Documentation/timers/hpet_example.c
diff -druNp linux-libre-2.6.33-gnu1/Documentation/timers/Makefile linux-libre-2.6.34-gnu1/Documentation/timers/Makefile
--- linux-libre-2.6.33-gnu1/Documentation/timers/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/timers/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,8 @@
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+obj- := dummy.o
+
+# List of programs to build
+hostprogs-y := hpet_example
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
diff -druNp linux-libre-2.6.33-gnu1/Documentation/trace/ftrace-design.txt linux-libre-2.6.34-gnu1/Documentation/trace/ftrace-design.txt
--- linux-libre-2.6.33-gnu1/Documentation/trace/ftrace-design.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/trace/ftrace-design.txt	2010-05-16 17:17:36.000000000 -0400
@@ -238,11 +238,10 @@ HAVE_SYSCALL_TRACEPOINTS
 
 You need very few things to get the syscalls tracing in an arch.
 
+- Support HAVE_ARCH_TRACEHOOK (see arch/Kconfig).
 - Have a NR_syscalls variable in <asm/unistd.h> that provides the number
   of syscalls supported by the arch.
-- Implement arch_syscall_addr() that resolves a syscall address from a
-  syscall number.
-- Support the TIF_SYSCALL_TRACEPOINT thread flags
+- Support the TIF_SYSCALL_TRACEPOINT thread flags.
 - Put the trace_sys_enter() and trace_sys_exit() tracepoints calls from ptrace
   in the ptrace syscalls tracing path.
 - Tag this arch as HAVE_SYSCALL_TRACEPOINTS.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/trace/ftrace.txt linux-libre-2.6.34-gnu1/Documentation/trace/ftrace.txt
--- linux-libre-2.6.33-gnu1/Documentation/trace/ftrace.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/trace/ftrace.txt	2010-05-16 17:17:36.000000000 -0400
@@ -1588,7 +1588,7 @@ module author does not need to worry abo
 
 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
+cause the CPU to do undesirable 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.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/trace/kprobetrace.txt linux-libre-2.6.34-gnu1/Documentation/trace/kprobetrace.txt
--- linux-libre-2.6.33-gnu1/Documentation/trace/kprobetrace.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/trace/kprobetrace.txt	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@ Synopsis of kprobe_events
 -------------------------
   p[:[GRP/]EVENT] SYMBOL[+offs]|MEMADDR [FETCHARGS]	: Set a probe
   r[:[GRP/]EVENT] SYMBOL[+0] [FETCHARGS]		: Set a return probe
+  -:[GRP/]EVENT						: Clear a probe
 
  GRP		: Group name. If omitted, use "kprobes" for it.
  EVENT		: Event name. If omitted, the event name is generated
@@ -37,15 +38,12 @@ Synopsis of kprobe_events
   @SYM[+|-offs]	: Fetch memory at SYM +|- offs (SYM should be a data symbol)
   $stackN	: Fetch Nth entry of stack (N >= 0)
   $stack	: Fetch stack address.
-  $argN		: Fetch function argument. (N >= 0)(*)
-  $retval	: Fetch return value.(**)
-  +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(***)
+  $retval	: Fetch return value.(*)
+  +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**)
   NAME=FETCHARG: Set NAME as the argument name of FETCHARG.
 
-  (*) aN may not correct on asmlinkaged functions and at the middle of
-      function body.
-  (**) only for return probe.
-  (***) this is useful for fetching a field of data structures.
+  (*) only for return probe.
+  (**) this is useful for fetching a field of data structures.
 
 
 Per-Probe Event Filtering
@@ -82,13 +80,16 @@ Usage examples
 To add a probe as a new event, write a new definition to kprobe_events
 as below.
 
-  echo p:myprobe do_sys_open dfd=$arg0 filename=$arg1 flags=$arg2 mode=$arg3 > /sys/kernel/debug/tracing/kprobe_events
+  echo 'p:myprobe do_sys_open dfd=%ax filename=%dx flags=%cx mode=+4($stack)' > /sys/kernel/debug/tracing/kprobe_events
 
  This sets a kprobe on the top of do_sys_open() function with recording
-1st to 4th arguments as "myprobe" event. As this example shows, users can
-choose more familiar names for each arguments.
+1st to 4th arguments as "myprobe" event. Note, which register/stack entry is
+assigned to each function argument depends on arch-specific ABI. If you unsure
+the ABI, please try to use probe subcommand of perf-tools (you can find it
+under tools/perf/).
+As this example shows, users can choose more familiar names for each arguments.
 
-  echo r:myretprobe do_sys_open $retval >> /sys/kernel/debug/tracing/kprobe_events
+  echo 'r:myretprobe do_sys_open $retval' >> /sys/kernel/debug/tracing/kprobe_events
 
  This sets a kretprobe on the return point of do_sys_open() function with
 recording return value as "myretprobe" event.
@@ -97,23 +98,24 @@ recording return value as "myretprobe" e
 
   cat /sys/kernel/debug/tracing/events/kprobes/myprobe/format
 name: myprobe
-ID: 75
+ID: 780
 format:
-	field:unsigned short common_type;	offset:0;	size:2;
-	field:unsigned char common_flags;	offset:2;	size:1;
-	field:unsigned char common_preempt_count;	offset:3;	size:1;
-	field:int common_pid;	offset:4;	size:4;
-	field:int common_tgid;	offset:8;	size:4;
+        field:unsigned short common_type;       offset:0;       size:2; signed:0;
+        field:unsigned char common_flags;       offset:2;       size:1; signed:0;
+        field:unsigned char common_preempt_count;       offset:3; size:1;signed:0;
+        field:int common_pid;   offset:4;       size:4; signed:1;
+        field:int common_lock_depth;    offset:8;       size:4; signed:1;
 
-	field: unsigned long ip;	offset:16;tsize:8;
-	field: int nargs;	offset:24;tsize:4;
-	field: unsigned long dfd;	offset:32;tsize:8;
-	field: unsigned long filename;	offset:40;tsize:8;
-	field: unsigned long flags;	offset:48;tsize:8;
-	field: unsigned long mode;	offset:56;tsize:8;
+        field:unsigned long __probe_ip; offset:12;      size:4; signed:0;
+        field:int __probe_nargs;        offset:16;      size:4; signed:1;
+        field:unsigned long dfd;        offset:20;      size:4; signed:0;
+        field:unsigned long filename;   offset:24;      size:4; signed:0;
+        field:unsigned long flags;      offset:28;      size:4; signed:0;
+        field:unsigned long mode;       offset:32;      size:4; signed:0;
 
-print fmt: "(%lx) dfd=%lx filename=%lx flags=%lx mode=%lx", REC->ip, REC->dfd, REC->filename, REC->flags, REC->mode
 
+print fmt: "(%lx) dfd=%lx filename=%lx flags=%lx mode=%lx", REC->__probe_ip,
+REC->dfd, REC->filename, REC->flags, REC->mode
 
  You can see that the event has 4 arguments as in the expressions you specified.
 
@@ -121,6 +123,12 @@ print fmt: "(%lx) dfd=%lx filename=%lx f
 
  This clears all probe points.
 
+ Or,
+
+  echo -:myprobe >> kprobe_events
+
+ This clears probe points selectively.
+
  Right after definition, each event is disabled by default. For tracing these
 events, you need to enable it.
 
@@ -146,4 +154,3 @@ events, you need to enable it.
 returns from SYMBOL(e.g. "sys_open+0x1b/0x1d <- do_sys_open" means kernel
 returns from do_sys_open to sys_open+0x1b).
 
-
diff -druNp linux-libre-2.6.33-gnu1/Documentation/usb/error-codes.txt linux-libre-2.6.34-gnu1/Documentation/usb/error-codes.txt
--- linux-libre-2.6.33-gnu1/Documentation/usb/error-codes.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/usb/error-codes.txt	2010-05-16 17:17:36.000000000 -0400
@@ -41,8 +41,8 @@ USB-specific:
 
 -EFBIG		Host controller driver can't schedule that many ISO frames.
 
--EPIPE		Specified endpoint is stalled.  For non-control endpoints,
-		reset this status with usb_clear_halt().
+-EPIPE		The pipe type specified in the URB doesn't match the
+		endpoint's actual type.
 
 -EMSGSIZE	(a) endpoint maxpacket size is zero; it is not usable
 		    in the current interface altsetting.
@@ -60,6 +60,8 @@ USB-specific:
 
 -EHOSTUNREACH	URB was rejected because the device is suspended.
 
+-ENOEXEC	A control URB doesn't contain a Setup packet.
+
 
 **************************************************************************
 *                   Error codes returned by in urb->status               *
diff -druNp linux-libre-2.6.33-gnu1/Documentation/usb/power-management.txt linux-libre-2.6.34-gnu1/Documentation/usb/power-management.txt
--- linux-libre-2.6.33-gnu1/Documentation/usb/power-management.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/usb/power-management.txt	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
 
 		 Alan Stern <stern@rowland.harvard.edu>
 
-			    November 10, 2009
+			    December 11, 2009
 
 
 
@@ -29,9 +29,9 @@ covered to some extent (see Documentatio
 information about system PM).
 
 Note: Dynamic PM support for USB is present only if the kernel was
-built with CONFIG_USB_SUSPEND enabled.  System PM support is present
-only if the kernel was built with CONFIG_SUSPEND or CONFIG_HIBERNATION
-enabled.
+built with CONFIG_USB_SUSPEND enabled (which depends on
+CONFIG_PM_RUNTIME).  System PM support is present only if the kernel
+was built with CONFIG_SUSPEND or CONFIG_HIBERNATION enabled.
 
 
 	What is Remote Wakeup?
@@ -229,6 +229,11 @@ necessary operations by hand or add them
 also change the idle-delay time; 2 seconds is not the best choice for
 every device.
 
+If a driver knows that its device has proper suspend/resume support,
+it can enable autosuspend all by itself.  For example, the video
+driver for a laptop's webcam might do this, since these devices are
+rarely used and so should normally be autosuspended.
+
 Sometimes it turns out that even when a device does work okay with
 autosuspend there are still problems.  For example, there are
 experimental patches adding autosuspend support to the usbhid driver,
@@ -321,69 +326,81 @@ driver does so by calling these six func
 	void usb_autopm_get_interface_no_resume(struct usb_interface *intf);
 	void usb_autopm_put_interface_no_suspend(struct usb_interface *intf);
 
-The functions work by maintaining a counter in the usb_interface
-structure.  When intf->pm_usage_count is > 0 then the interface is
-deemed to be busy, and the kernel will not autosuspend the interface's
-device.  When intf->pm_usage_count is <= 0 then the interface is
-considered to be idle, and the kernel may autosuspend the device.
+The functions work by maintaining a usage counter in the
+usb_interface's embedded device structure.  When the counter is > 0
+then the interface is deemed to be busy, and the kernel will not
+autosuspend the interface's device.  When the usage counter is = 0
+then the interface is considered to be idle, and the kernel may
+autosuspend the device.
 
-(There is a similar pm_usage_count field in struct usb_device,
+(There is a similar usage counter field in struct usb_device,
 associated with the device itself rather than any of its interfaces.
-This field is used only by the USB core.)
+This counter is used only by the USB core.)
 
-Drivers must not modify intf->pm_usage_count directly; its value
-should be changed only be using the functions listed above.  Drivers
-are responsible for insuring that the overall change to pm_usage_count
-during their lifetime balances out to 0 (it may be necessary for the
-disconnect method to call usb_autopm_put_interface() one or more times
-to fulfill this requirement).  The first two routines use the PM mutex
-in struct usb_device for mutual exclusion; drivers using the async
-routines are responsible for their own synchronization and mutual
-exclusion.
+Drivers need not be concerned about balancing changes to the usage
+counter; the USB core will undo any remaining "get"s when a driver
+is unbound from its interface.  As a corollary, drivers must not call
+any of the usb_autopm_* functions after their diconnect() routine has
+returned.
 
-	usb_autopm_get_interface() increments pm_usage_count and
-	attempts an autoresume if the new value is > 0 and the
-	device is suspended.
+Drivers using the async routines are responsible for their own
+synchronization and mutual exclusion.
 
-	usb_autopm_put_interface() decrements pm_usage_count and
-	attempts an autosuspend if the new value is <= 0 and the
-	device isn't suspended.
+	usb_autopm_get_interface() increments the usage counter and
+	does an autoresume if the device is suspended.  If the
+	autoresume fails, the counter is decremented back.
+
+	usb_autopm_put_interface() decrements the usage counter and
+	attempts an autosuspend if the new value is = 0.
 
 	usb_autopm_get_interface_async() and
 	usb_autopm_put_interface_async() do almost the same things as
-	their non-async counterparts.  The differences are: they do
-	not acquire the PM mutex, and they use a workqueue to do their
+	their non-async counterparts.  The big difference is that they
+	use a workqueue to do the resume or suspend part of their
 	jobs.  As a result they can be called in an atomic context,
 	such as an URB's completion handler, but when they return the
-	device will not generally not yet be in the desired state.
+	device will generally not yet be in the desired state.
 
 	usb_autopm_get_interface_no_resume() and
 	usb_autopm_put_interface_no_suspend() merely increment or
-	decrement the pm_usage_count value; they do not attempt to
-	carry out an autoresume or an autosuspend.  Hence they can be
-	called in an atomic context.
+	decrement the usage counter; they do not attempt to carry out
+	an autoresume or an autosuspend.  Hence they can be called in
+	an atomic context.
 
-The conventional usage pattern is that a driver calls
+The simplest usage pattern is that a driver calls
 usb_autopm_get_interface() in its open routine and
-usb_autopm_put_interface() in its close or release routine.  But
-other patterns are possible.
+usb_autopm_put_interface() in its close or release routine.  But other
+patterns are possible.
 
 The autosuspend attempts mentioned above will often fail for one
 reason or another.  For example, the power/level attribute might be
 set to "on", or another interface in the same device might not be
 idle.  This is perfectly normal.  If the reason for failure was that
-the device hasn't been idle for long enough, a delayed workqueue
-routine is automatically set up to carry out the operation when the
-autosuspend idle-delay has expired.
+the device hasn't been idle for long enough, a timer is scheduled to
+carry out the operation automatically when the autosuspend idle-delay
+has expired.
 
 Autoresume attempts also can fail, although failure would mean that
 the device is no longer present or operating properly.  Unlike
-autosuspend, there's no delay for an autoresume.
+autosuspend, there's no idle-delay for an autoresume.
 
 
 	Other parts of the driver interface
 	-----------------------------------
 
+Drivers can enable autosuspend for their devices by calling
+
+	usb_enable_autosuspend(struct usb_device *udev);
+
+in their probe() routine, if they know that the device is capable of
+suspending and resuming correctly.  This is exactly equivalent to
+writing "auto" to the device's power/level attribute.  Likewise,
+drivers can disable autosuspend by calling
+
+	usb_disable_autosuspend(struct usb_device *udev);
+
+This is exactly the same as writing "on" to the power/level attribute.
+
 Sometimes a driver needs to make sure that remote wakeup is enabled
 during autosuspend.  For example, there's not much point
 autosuspending a keyboard if the user can't cause the keyboard to do a
@@ -395,26 +412,27 @@ though, setting this flag won't cause th
 Normally a driver would set this flag in its probe method, at which
 time the device is guaranteed not to be autosuspended.)
 
-The synchronous usb_autopm_* routines have to run in a sleepable
-process context; they must not be called from an interrupt handler or
-while holding a spinlock.  In fact, the entire autosuspend mechanism
-is not well geared toward interrupt-driven operation.  However there
-is one thing a driver can do in an interrupt handler:
+If a driver does its I/O asynchronously in interrupt context, it
+should call usb_autopm_get_interface_async() before starting output and
+usb_autopm_put_interface_async() when the output queue drains.  When
+it receives an input event, it should call
 
 	usb_mark_last_busy(struct usb_device *udev);
 
-This sets udev->last_busy to the current time.  udev->last_busy is the
-field used for idle-delay calculations; updating it will cause any
-pending autosuspend to be moved back.  The usb_autopm_* routines will
-also set the last_busy field to the current time.
+in the event handler.  This sets udev->last_busy to the current time.
+udev->last_busy is the field used for idle-delay calculations;
+updating it will cause any pending autosuspend to be moved back.  Most
+of the usb_autopm_* routines will also set the last_busy field to the
+current time.
 
-Calling urb_mark_last_busy() from within an URB completion handler is
-subject to races: The kernel may have just finished deciding the
-device has been idle for long enough but not yet gotten around to
-calling the driver's suspend method.  The driver would have to be
-responsible for synchronizing its suspend method with its URB
-completion handler and causing the autosuspend to fail with -EBUSY if
-an URB had completed too recently.
+Asynchronous operation is always subject to races.  For example, a
+driver may call one of the usb_autopm_*_interface_async() routines at
+a time when the core has just finished deciding the device has been
+idle for long enough but not yet gotten around to calling the driver's
+suspend method.  The suspend method must be responsible for
+synchronizing with the output request routine and the URB completion
+handler; it should cause autosuspends to fail with -EBUSY if the
+driver needs to use the device.
 
 External suspend calls should never be allowed to fail in this way,
 only autosuspend calls.  The driver can tell them apart by checking
@@ -422,75 +440,23 @@ the PM_EVENT_AUTO bit in the message.eve
 method; this bit will be set for internal PM events (autosuspend) and
 clear for external PM events.
 
-Many of the ingredients in the autosuspend framework are oriented
-towards interfaces: The usb_interface structure contains the
-pm_usage_cnt field, and the usb_autopm_* routines take an interface
-pointer as their argument.  But somewhat confusingly, a few of the
-pieces (i.e., usb_mark_last_busy()) use the usb_device structure
-instead.  Drivers need to keep this straight; they can call
-interface_to_usbdev() to find the device structure for a given
-interface.
 
+	Mutual exclusion
+	----------------
 
-	Locking requirements
-	--------------------
-
-All three suspend/resume methods are always called while holding the
-usb_device's PM mutex.  For external events -- but not necessarily for
-autosuspend or autoresume -- the device semaphore (udev->dev.sem) will
-also be held.  This implies that external suspend/resume events are
-mutually exclusive with calls to probe, disconnect, pre_reset, and
-post_reset; the USB core guarantees that this is true of internal
-suspend/resume events as well.
+For external events -- but not necessarily for autosuspend or
+autoresume -- the device semaphore (udev->dev.sem) will be held when a
+suspend or resume method is called.  This implies that external
+suspend/resume events are mutually exclusive with calls to probe,
+disconnect, pre_reset, and post_reset; the USB core guarantees that
+this is true of autosuspend/autoresume events as well.
 
 If a driver wants to block all suspend/resume calls during some
-critical section, it can simply acquire udev->pm_mutex. Note that
-calls to resume may be triggered indirectly. Block IO due to memory
-allocations can make the vm subsystem resume a device. Thus while
-holding this lock you must not allocate memory with GFP_KERNEL or
-GFP_NOFS.
-
-Alternatively, if the critical section might call some of the
-usb_autopm_* routines, the driver can avoid deadlock by doing:
-
-	down(&udev->dev.sem);
-	rc = usb_autopm_get_interface(intf);
-
-and at the end of the critical section:
-
-	if (!rc)
-		usb_autopm_put_interface(intf);
-	up(&udev->dev.sem);
-
-Holding the device semaphore will block all external PM calls, and the
-usb_autopm_get_interface() will prevent any internal PM calls, even if
-it fails.  (Exercise: Why?)
-
-The rules for locking order are:
-
-	Never acquire any device semaphore while holding any PM mutex.
-
-	Never acquire udev->pm_mutex while holding the PM mutex for
-	a device that isn't a descendant of udev.
-
-In other words, PM mutexes should only be acquired going up the device
-tree, and they should be acquired only after locking all the device
-semaphores you need to hold.  These rules don't matter to drivers very
-much; they usually affect just the USB core.
-
-Still, drivers do need to be careful.  For example, many drivers use a
-private mutex to synchronize their normal I/O activities with their
-disconnect method.  Now if the driver supports autosuspend then it
-must call usb_autopm_put_interface() from somewhere -- maybe from its
-close method.  It should make the call while holding the private mutex,
-since a driver shouldn't call any of the usb_autopm_* functions for an
-interface from which it has been unbound.
-
-But the usb_autpm_* routines always acquire the device's PM mutex, and
-consequently the locking order has to be: private mutex first, PM
-mutex second.  Since the suspend method is always called with the PM
-mutex held, it mustn't try to acquire the private mutex.  It has to
-synchronize with the driver's I/O activities in some other way.
+critical section, the best way is to lock the device and call
+usb_autopm_get_interface() (and do the reverse at the end of the
+critical section).  Holding the device semaphore will block all
+external PM calls, and the usb_autopm_get_interface() will prevent any
+internal PM calls, even if it fails.  (Exercise: Why?)
 
 
 	Interaction between dynamic PM and system PM
@@ -499,22 +465,11 @@ synchronize with the driver's I/O activi
 Dynamic power management and system power management can interact in
 a couple of ways.
 
-Firstly, a device may already be manually suspended or autosuspended
-when a system suspend occurs.  Since system suspends are supposed to
-be as transparent as possible, the device should remain suspended
-following the system resume.  The 2.6.23 kernel obeys this principle
-for manually suspended devices but not for autosuspended devices; they
-do get resumed when the system wakes up.  (Presumably they will be
-autosuspended again after their idle-delay time expires.)  In later
-kernels this behavior will be fixed.
-
-(There is an exception.  If a device would undergo a reset-resume
-instead of a normal resume, and the device is enabled for remote
-wakeup, then the reset-resume takes place even if the device was
-already suspended when the system suspend began.  The justification is
-that a reset-resume is a kind of remote-wakeup event.  Or to put it
-another way, a device which needs a reset won't be able to generate
-normal remote-wakeup signals, so it ought to be resumed immediately.)
+Firstly, a device may already be autosuspended when a system suspend
+occurs.  Since system suspends are supposed to be as transparent as
+possible, the device should remain suspended following the system
+resume.  But this theory may not work out well in practice; over time
+the kernel's behavior in this regard has changed.
 
 Secondly, a dynamic power-management event may occur as a system
 suspend is underway.  The window for this is short, since system
diff -druNp linux-libre-2.6.33-gnu1/Documentation/video4linux/CARDLIST.cx23885 linux-libre-2.6.34-gnu1/Documentation/video4linux/CARDLIST.cx23885
--- linux-libre-2.6.33-gnu1/Documentation/video4linux/CARDLIST.cx23885	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/video4linux/CARDLIST.cx23885	2010-05-16 17:17:36.000000000 -0400
@@ -26,3 +26,4 @@
  25 -> Compro VideoMate E800                               [1858:e800]
  26 -> Hauppauge WinTV-HVR1290                             [0070:8551]
  27 -> Mygica X8558 PRO DMB-TH                             [14f1:8578]
+ 28 -> LEADTEK WinFast PxTV1200                            [107d:6f22]
diff -druNp linux-libre-2.6.33-gnu1/Documentation/video4linux/CARDLIST.saa7134 linux-libre-2.6.34-gnu1/Documentation/video4linux/CARDLIST.saa7134
--- linux-libre-2.6.33-gnu1/Documentation/video4linux/CARDLIST.saa7134	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/video4linux/CARDLIST.saa7134	2010-05-16 17:17:36.000000000 -0400
@@ -174,3 +174,4 @@
 173 -> Zolid Hybrid TV Tuner PCI                [1131:2004]
 174 -> Asus Europa Hybrid OEM                   [1043:4847]
 175 -> Leadtek Winfast DTV1000S                 [107d:6655]
+176 -> Beholder BeholdTV 505 RDS                [0000:5051]
diff -druNp linux-libre-2.6.33-gnu1/Documentation/video4linux/CARDLIST.tuner linux-libre-2.6.34-gnu1/Documentation/video4linux/CARDLIST.tuner
--- linux-libre-2.6.33-gnu1/Documentation/video4linux/CARDLIST.tuner	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/video4linux/CARDLIST.tuner	2010-05-16 17:17:36.000000000 -0400
@@ -81,3 +81,4 @@ tuner=80 - Philips FQ1216LME MK3 PAL/SEC
 tuner=81 - Partsnic (Daewoo) PTI-5NF05
 tuner=82 - Philips CU1216L
 tuner=83 - NXP TDA18271
+tuner=84 - Sony BTF-Pxn01Z
diff -druNp linux-libre-2.6.33-gnu1/Documentation/video4linux/gspca.txt linux-libre-2.6.34-gnu1/Documentation/video4linux/gspca.txt
--- linux-libre-2.6.33-gnu1/Documentation/video4linux/gspca.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/video4linux/gspca.txt	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@ ov519		041e:4064	Creative Live! VISTA VF
 ov519		041e:4067	Creative Live! Cam Video IM (VF0350)
 ov519		041e:4068	Creative Live! VISTA VF0470
 spca561		0458:7004	Genius VideoCAM Express V2
+sn9c2028	0458:7005	Genius Smart 300, version 2
 sunplus		0458:7006	Genius Dsc 1.3 Smart
 zc3xx		0458:7007	Genius VideoCam V2
 zc3xx		0458:700c	Genius VideoCam V3
@@ -109,6 +110,7 @@ sunplus		04a5:3003	Benq DC 1300
 sunplus		04a5:3008	Benq DC 1500
 sunplus		04a5:300a	Benq DC 3410
 spca500		04a5:300c	Benq DC 1016
+benq		04a5:3035	Benq DC E300
 finepix		04cb:0104	Fujifilm FinePix 4800
 finepix		04cb:0109	Fujifilm FinePix A202
 finepix		04cb:010b	Fujifilm FinePix A203
@@ -142,6 +144,7 @@ sunplus		04fc:5360	Sunplus Generic
 spca500		04fc:7333	PalmPixDC85
 sunplus		04fc:ffff	Pure DigitalDakota
 spca501		0506:00df	3Com HomeConnect Lite
+sunplus		052b:1507	Megapixel 5 Pretec DC-1007
 sunplus		052b:1513	Megapix V4
 sunplus		052b:1803	MegaImage VI
 tv8532		0545:808b	Veo Stingray
@@ -151,6 +154,7 @@ sunplus		0546:3191	Polaroid Ion 80
 sunplus		0546:3273	Polaroid PDC2030
 ov519		054c:0154	Sonny toy4
 ov519		054c:0155	Sonny toy5
+cpia1		0553:0002	CPIA CPiA (version1) based cameras
 zc3xx		055f:c005	Mustek Wcam300A
 spca500		055f:c200	Mustek Gsmart 300
 sunplus		055f:c211	Kowa Bs888e Microcamera
@@ -188,8 +192,7 @@ spca500		06bd:0404	Agfa CL20
 spca500		06be:0800	Optimedia
 sunplus		06d6:0031	Trust 610 LCD PowerC@m Zoom
 spca506		06e1:a190	ADS Instant VCD
-ov534		06f8:3002	Hercules Blog Webcam
-ov534		06f8:3003	Hercules Dualpix HD Weblog
+ov534_9		06f8:3003	Hercules Dualpix HD Weblog
 sonixj		06f8:3004	Hercules Classic Silver
 sonixj		06f8:3008	Hercules Deluxe Optical Glass
 pac7302		06f8:3009	Hercules Classic Link
@@ -204,6 +207,7 @@ sunplus		0733:2221	Mercury Digital Pro 3
 sunplus		0733:3261	Concord 3045 spca536a
 sunplus		0733:3281	Cyberpix S550V
 spca506		0734:043b	3DeMon USB Capture aka
+cpia1		0813:0001	QX3 camera
 ov519		0813:0002	Dual Mode USB Camera Plus
 spca500		084d:0003	D-Link DSC-350
 spca500		08ca:0103	Aiptek PocketDV
@@ -225,7 +229,8 @@ sunplus		08ca:2050	Medion MD 41437
 sunplus		08ca:2060	Aiptek PocketDV5300
 tv8532		0923:010f	ICM532 cams
 mars		093a:050f	Mars-Semi Pc-Camera
-mr97310a	093a:010f	Sakar Digital no. 77379
+mr97310a	093a:010e	All known CIF cams with this ID
+mr97310a	093a:010f	All known VGA cams with this ID
 pac207		093a:2460	Qtec Webcam 100
 pac207		093a:2461	HP Webcam
 pac207		093a:2463	Philips SPC 220 NC
@@ -302,6 +307,7 @@ sonixj		0c45:613b	Surfer SN-206
 sonixj		0c45:613c	Sonix Pccam168
 sonixj		0c45:6143	Sonix Pccam168
 sonixj		0c45:6148	Digitus DA-70811/ZSMC USB PC Camera ZS211/Microdia
+sonixj		0c45:614a	Frontech E-Ccam (JIL-2225)
 sn9c20x		0c45:6240	PC Camera (SN9C201 + MT9M001)
 sn9c20x		0c45:6242	PC Camera (SN9C201 + MT9M111)
 sn9c20x		0c45:6248	PC Camera (SN9C201 + OV9655)
@@ -324,6 +330,10 @@ sn9c20x		0c45:62b0	PC Camera (SN9C202 +
 sn9c20x		0c45:62b3	PC Camera (SN9C202 + OV9655)
 sn9c20x		0c45:62bb	PC Camera (SN9C202 + OV7660)
 sn9c20x		0c45:62bc	PC Camera (SN9C202 + HV7131R)
+sn9c2028	0c45:8001	Wild Planet Digital Spy Camera
+sn9c2028	0c45:8003	Sakar #11199, #6637x, #67480 keychain cams
+sn9c2028	0c45:8008	Mini-Shotz ms-350
+sn9c2028	0c45:800a	Vivitar Vivicam 3350B
 sunplus		0d64:0303	Sunplus FashionCam DXG
 ov519		0e96:c001	TRUST 380 USB2 SPACEC@M
 etoms		102c:6151	Qcam Sangha CIF
@@ -341,10 +351,11 @@ spca501		1776:501c	Arowana 300K CMOS Cam
 t613		17a1:0128	TASCORP JPEG Webcam, NGS Cyclops
 vc032x		17ef:4802	Lenovo Vc0323+MI1310_SOC
 pac207		2001:f115	D-Link DSB-C120
-sq905c		2770:9050	sq905c
-sq905c		2770:905c	DualCamera
-sq905		2770:9120	Argus Digital Camera DC1512
-sq905c		2770:913d	sq905c
+sq905c		2770:9050	Disney pix micro (CIF)
+sq905c		2770:9052	Disney pix micro 2 (VGA)
+sq905c		2770:905c	All 11 known cameras with this ID
+sq905		2770:9120	All 24 known cameras with this ID
+sq905c		2770:913d	All 4 known cameras with this ID
 spca500		2899:012c	Toptro Industrial
 ov519		8020:ef04	ov519
 spca508		8086:0110	Intel Easy PC Camera
diff -druNp linux-libre-2.6.33-gnu1/Documentation/video4linux/README.tlg2300 linux-libre-2.6.34-gnu1/Documentation/video4linux/README.tlg2300
--- linux-libre-2.6.33-gnu1/Documentation/video4linux/README.tlg2300	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/video4linux/README.tlg2300	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,47 @@
+tlg2300 release notes
+====================
+
+This is a v4l2/dvb device driver for the tlg2300 chip.
+
+
+current status
+==============
+
+video
+	- support mmap and read().(no overlay)
+
+audio
+	- The driver will register a ALSA card for the audio input.
+
+vbi
+	- Works for almost TV norms.
+
+dvb-t
+	- works for DVB-T
+
+FM
+	- Works for radio.
+
+---------------------------------------------------------------------------
+TESTED APPLICATIONS:
+
+-VLC1.0.4 test the video and dvb. The GUI is friendly to use.
+
+-Mplayer test the video.
+
+-Mplayer test the FM. The mplayer should be compiled with --enable-radio and
+	 --enable-radio-capture.
+	The command runs as this(The alsa audio registers to card 1):
+	#mplayer radio://103.7/capture/ -radio adevice=hw=1,0:arate=48000 \
+		-rawaudio rate=48000:channels=2
+
+---------------------------------------------------------------------------
+KNOWN PROBLEMS:
+about preemphasis:
+	You can set the preemphasis for radio by the following command:
+	#v4l2-ctl -d /dev/radio0 --set-ctrl=pre_emphasis_settings=1
+
+	"pre_emphasis_settings=1" means that you select the 50us. If you want
+	to select the 75us, please use "pre_emphasis_settings=2"
+
+
diff -druNp linux-libre-2.6.33-gnu1/Documentation/video4linux/v4l2-framework.txt linux-libre-2.6.34-gnu1/Documentation/video4linux/v4l2-framework.txt
--- linux-libre-2.6.33-gnu1/Documentation/video4linux/v4l2-framework.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/video4linux/v4l2-framework.txt	2010-05-16 17:17:36.000000000 -0400
@@ -599,99 +599,13 @@ video_device::minor fields.
 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 v4l2 core API provides a set of standard methods (called "videobuf")
+for dealing with video buffers. Those methods allow a driver to implement
+read(), mmap() and overlay() in 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).
 
-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).
+Please see Documentation/video4linux/videobuf for more information on how
+to use the videobuf layer.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/video4linux/videobuf linux-libre-2.6.34-gnu1/Documentation/video4linux/videobuf
--- linux-libre-2.6.33-gnu1/Documentation/video4linux/videobuf	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/video4linux/videobuf	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,360 @@
+An introduction to the videobuf layer
+Jonathan Corbet <corbet@lwn.net>
+Current as of 2.6.33
+
+The videobuf layer functions as a sort of glue layer between a V4L2 driver
+and user space.  It handles the allocation and management of buffers for
+the storage of video frames.  There is a set of functions which can be used
+to implement many of the standard POSIX I/O system calls, including read(),
+poll(), and, happily, mmap().  Another set of functions can be used to
+implement the bulk of the V4L2 ioctl() calls related to streaming I/O,
+including buffer allocation, queueing and dequeueing, and streaming
+control.  Using videobuf imposes a few design decisions on the driver
+author, but the payback comes in the form of reduced code in the driver and
+a consistent implementation of the V4L2 user-space API.
+
+Buffer types
+
+Not all video devices use the same kind of buffers.  In fact, there are (at
+least) three common variations:
+
+ - Buffers which are scattered in both the physical and (kernel) virtual
+   address spaces.  (Almost) all user-space buffers are like this, but it
+   makes great sense to allocate kernel-space buffers this way as well when
+   it is possible.  Unfortunately, it is not always possible; working with
+   this kind of buffer normally requires hardware which can do
+   scatter/gather DMA operations.
+
+ - Buffers which are physically scattered, but which are virtually
+   contiguous; buffers allocated with vmalloc(), in other words.  These
+   buffers are just as hard to use for DMA operations, but they can be
+   useful in situations where DMA is not available but virtually-contiguous
+   buffers are convenient.
+
+ - Buffers which are physically contiguous.  Allocation of this kind of
+   buffer can be unreliable on fragmented systems, but simpler DMA
+   controllers cannot deal with anything else.
+
+Videobuf can work with all three types of buffers, but the driver author
+must pick one at the outset and design the driver around that decision.
+
+[It's worth noting that there's a fourth kind of buffer: "overlay" buffers
+which are located within the system's video memory.  The overlay
+functionality is considered to be deprecated for most use, but it still
+shows up occasionally in system-on-chip drivers where the performance
+benefits merit the use of this technique.  Overlay buffers can be handled
+as a form of scattered buffer, but there are very few implementations in
+the kernel and a description of this technique is currently beyond the
+scope of this document.]
+
+Data structures, callbacks, and initialization
+
+Depending on which type of buffers are being used, the driver should
+include one of the following files:
+
+    <media/videobuf-dma-sg.h>		/* Physically scattered */
+    <media/videobuf-vmalloc.h>		/* vmalloc() buffers	*/
+    <media/videobuf-dma-contig.h>	/* Physically contiguous */
+
+The driver's data structure describing a V4L2 device should include a
+struct videobuf_queue instance for the management of the buffer queue,
+along with a list_head for the queue of available buffers.  There will also
+need to be an interrupt-safe spinlock which is used to protect (at least)
+the queue.
+
+The next step is to write four simple callbacks to help videobuf deal with
+the management of buffers:
+
+    struct videobuf_queue_ops {
+	int (*buf_setup)(struct videobuf_queue *q,
+			 unsigned int *count, unsigned int *size);
+	int (*buf_prepare)(struct videobuf_queue *q,
+			   struct videobuf_buffer *vb,
+			   enum v4l2_field field);
+	void (*buf_queue)(struct videobuf_queue *q,
+			  struct videobuf_buffer *vb);
+	void (*buf_release)(struct videobuf_queue *q,
+			    struct videobuf_buffer *vb);
+    };
+
+buf_setup() is called early in the I/O process, when streaming is being
+initiated; its purpose is to tell videobuf about the I/O stream.  The count
+parameter will be a suggested number of buffers to use; the driver should
+check it for rationality and adjust it if need be.  As a practical rule, a
+minimum of two buffers are needed for proper streaming, and there is
+usually a maximum (which cannot exceed 32) which makes sense for each
+device.  The size parameter should be set to the expected (maximum) size
+for each frame of data.
+
+Each buffer (in the form of a struct videobuf_buffer pointer) will be
+passed to buf_prepare(), which should set the buffer's size, width, height,
+and field fields properly.  If the buffer's state field is
+VIDEOBUF_NEEDS_INIT, the driver should pass it to:
+
+    int videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb,
+			struct v4l2_framebuffer *fbuf);
+
+Among other things, this call will usually allocate memory for the buffer.
+Finally, the buf_prepare() function should set the buffer's state to
+VIDEOBUF_PREPARED.
+
+When a buffer is queued for I/O, it is passed to buf_queue(), which should
+put it onto the driver's list of available buffers and set its state to
+VIDEOBUF_QUEUED.  Note that this function is called with the queue spinlock
+held; if it tries to acquire it as well things will come to a screeching
+halt.  Yes, this is the voice of experience.  Note also that videobuf may
+wait on the first buffer in the queue; placing other buffers in front of it
+could again gum up the works.  So use list_add_tail() to enqueue buffers.
+
+Finally, buf_release() is called when a buffer is no longer intended to be
+used.  The driver should ensure that there is no I/O active on the buffer,
+then pass it to the appropriate free routine(s):
+
+    /* Scatter/gather drivers */
+    int videobuf_dma_unmap(struct videobuf_queue *q,
+			   struct videobuf_dmabuf *dma);
+    int videobuf_dma_free(struct videobuf_dmabuf *dma);
+
+    /* vmalloc drivers */
+    void videobuf_vmalloc_free (struct videobuf_buffer *buf);
+
+    /* Contiguous drivers */
+    void videobuf_dma_contig_free(struct videobuf_queue *q,
+				  struct videobuf_buffer *buf);
+
+One way to ensure that a buffer is no longer under I/O is to pass it to:
+
+    int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr);
+
+Here, vb is the buffer, non_blocking indicates whether non-blocking I/O
+should be used (it should be zero in the buf_release() case), and intr
+controls whether an interruptible wait is used.
+
+File operations
+
+At this point, much of the work is done; much of the rest is slipping
+videobuf calls into the implementation of the other driver callbacks.  The
+first step is in the open() function, which must initialize the
+videobuf queue.  The function to use depends on the type of buffer used:
+
+    void videobuf_queue_sg_init(struct videobuf_queue *q,
+				struct videobuf_queue_ops *ops,
+				struct device *dev,
+				spinlock_t *irqlock,
+				enum v4l2_buf_type type,
+				enum v4l2_field field,
+				unsigned int msize,
+				void *priv);
+
+    void videobuf_queue_vmalloc_init(struct videobuf_queue *q,
+				struct videobuf_queue_ops *ops,
+				struct device *dev,
+				spinlock_t *irqlock,
+				enum v4l2_buf_type type,
+				enum v4l2_field field,
+				unsigned int msize,
+				void *priv);
+
+    void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
+				       struct videobuf_queue_ops *ops,
+				       struct device *dev,
+				       spinlock_t *irqlock,
+				       enum v4l2_buf_type type,
+				       enum v4l2_field field,
+				       unsigned int msize,
+				       void *priv);
+
+In each case, the parameters are the same: q is the queue structure for the
+device, ops is the set of callbacks as described above, dev is the device
+structure for this video device, irqlock is an interrupt-safe spinlock to
+protect access to the data structures, type is the buffer type used by the
+device (cameras will use V4L2_BUF_TYPE_VIDEO_CAPTURE, for example), field
+describes which field is being captured (often V4L2_FIELD_NONE for
+progressive devices), msize is the size of any containing structure used
+around struct videobuf_buffer, and priv is a private data pointer which
+shows up in the priv_data field of struct videobuf_queue.  Note that these
+are void functions which, evidently, are immune to failure.
+
+V4L2 capture drivers can be written to support either of two APIs: the
+read() system call and the rather more complicated streaming mechanism.  As
+a general rule, it is necessary to support both to ensure that all
+applications have a chance of working with the device.  Videobuf makes it
+easy to do that with the same code.  To implement read(), the driver need
+only make a call to one of:
+
+    ssize_t videobuf_read_one(struct videobuf_queue *q,
+			      char __user *data, size_t count,
+			      loff_t *ppos, int nonblocking);
+
+    ssize_t videobuf_read_stream(struct videobuf_queue *q,
+				 char __user *data, size_t count,
+				 loff_t *ppos, int vbihack, int nonblocking);
+
+Either one of these functions will read frame data into data, returning the
+amount actually read; the difference is that videobuf_read_one() will only
+read a single frame, while videobuf_read_stream() will read multiple frames
+if they are needed to satisfy the count requested by the application.  A
+typical driver read() implementation will start the capture engine, call
+one of the above functions, then stop the engine before returning (though a
+smarter implementation might leave the engine running for a little while in
+anticipation of another read() call happening in the near future).
+
+The poll() function can usually be implemented with a direct call to:
+
+    unsigned int videobuf_poll_stream(struct file *file,
+				      struct videobuf_queue *q,
+				      poll_table *wait);
+
+Note that the actual wait queue eventually used will be the one associated
+with the first available buffer.
+
+When streaming I/O is done to kernel-space buffers, the driver must support
+the mmap() system call to enable user space to access the data.  In many
+V4L2 drivers, the often-complex mmap() implementation simplifies to a
+single call to:
+
+    int videobuf_mmap_mapper(struct videobuf_queue *q,
+			     struct vm_area_struct *vma);
+
+Everything else is handled by the videobuf code.
+
+The release() function requires two separate videobuf calls:
+
+    void videobuf_stop(struct videobuf_queue *q);
+    int videobuf_mmap_free(struct videobuf_queue *q);
+
+The call to videobuf_stop() terminates any I/O in progress - though it is
+still up to the driver to stop the capture engine.  The call to
+videobuf_mmap_free() will ensure that all buffers have been unmapped; if
+so, they will all be passed to the buf_release() callback.  If buffers
+remain mapped, videobuf_mmap_free() returns an error code instead.  The
+purpose is clearly to cause the closing of the file descriptor to fail if
+buffers are still mapped, but every driver in the 2.6.32 kernel cheerfully
+ignores its return value.
+
+ioctl() operations
+
+The V4L2 API includes a very long list of driver callbacks to respond to
+the many ioctl() commands made available to user space.  A number of these
+- those associated with streaming I/O - turn almost directly into videobuf
+calls.  The relevant helper functions are:
+
+    int videobuf_reqbufs(struct videobuf_queue *q,
+			 struct v4l2_requestbuffers *req);
+    int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b);
+    int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b);
+    int videobuf_dqbuf(struct videobuf_queue *q, struct v4l2_buffer *b,
+		       int nonblocking);
+    int videobuf_streamon(struct videobuf_queue *q);
+    int videobuf_streamoff(struct videobuf_queue *q);
+    int videobuf_cgmbuf(struct videobuf_queue *q, struct video_mbuf *mbuf,
+			int count);
+
+So, for example, a VIDIOC_REQBUFS call turns into a call to the driver's
+vidioc_reqbufs() callback which, in turn, usually only needs to locate the
+proper struct videobuf_queue pointer and pass it to videobuf_reqbufs().
+These support functions can replace a great deal of buffer management
+boilerplate in a lot of V4L2 drivers.
+
+The vidioc_streamon() and vidioc_streamoff() functions will be a bit more
+complex, of course, since they will also need to deal with starting and
+stopping the capture engine.  videobuf_cgmbuf(), called from the driver's
+vidiocgmbuf() function, only exists if the V4L1 compatibility module has
+been selected with CONFIG_VIDEO_V4L1_COMPAT, so its use must be surrounded
+with #ifdef directives.
+
+Buffer allocation
+
+Thus far, we have talked about buffers, but have not looked at how they are
+allocated.  The scatter/gather case is the most complex on this front.  For
+allocation, the driver can leave buffer allocation entirely up to the
+videobuf layer; in this case, buffers will be allocated as anonymous
+user-space pages and will be very scattered indeed.  If the application is
+using user-space buffers, no allocation is needed; the videobuf layer will
+take care of calling get_user_pages() and filling in the scatterlist array.
+
+If the driver needs to do its own memory allocation, it should be done in
+the vidioc_reqbufs() function, *after* calling videobuf_reqbufs().  The
+first step is a call to:
+
+    struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf);
+
+The returned videobuf_dmabuf structure (defined in
+<media/videobuf-dma-sg.h>) includes a couple of relevant fields:
+
+    struct scatterlist  *sglist;
+    int                 sglen;
+
+The driver must allocate an appropriately-sized scatterlist array and
+populate it with pointers to the pieces of the allocated buffer; sglen
+should be set to the length of the array.
+
+Drivers using the vmalloc() method need not (and cannot) concern themselves
+with buffer allocation at all; videobuf will handle those details.  The
+same is normally true of contiguous-DMA drivers as well; videobuf will
+allocate the buffers (with dma_alloc_coherent()) when it sees fit.  That
+means that these drivers may be trying to do high-order allocations at any
+time, an operation which is not always guaranteed to work.  Some drivers
+play tricks by allocating DMA space at system boot time; videobuf does not
+currently play well with those drivers.
+
+As of 2.6.31, contiguous-DMA drivers can work with a user-supplied buffer,
+as long as that buffer is physically contiguous.  Normal user-space
+allocations will not meet that criterion, but buffers obtained from other
+kernel drivers, or those contained within huge pages, will work with these
+drivers.
+
+Filling the buffers
+
+The final part of a videobuf implementation has no direct callback - it's
+the portion of the code which actually puts frame data into the buffers,
+usually in response to interrupts from the device.  For all types of
+drivers, this process works approximately as follows:
+
+ - Obtain the next available buffer and make sure that somebody is actually
+   waiting for it.
+
+ - Get a pointer to the memory and put video data there.
+
+ - Mark the buffer as done and wake up the process waiting for it.
+
+Step (1) above is done by looking at the driver-managed list_head structure
+- the one which is filled in the buf_queue() callback.  Because starting
+the engine and enqueueing buffers are done in separate steps, it's possible
+for the engine to be running without any buffers available - in the
+vmalloc() case especially.  So the driver should be prepared for the list
+to be empty.  It is equally possible that nobody is yet interested in the
+buffer; the driver should not remove it from the list or fill it until a
+process is waiting on it.  That test can be done by examining the buffer's
+done field (a wait_queue_head_t structure) with waitqueue_active().
+
+A buffer's state should be set to VIDEOBUF_ACTIVE before being mapped for
+DMA; that ensures that the videobuf layer will not try to do anything with
+it while the device is transferring data.
+
+For scatter/gather drivers, the needed memory pointers will be found in the
+scatterlist structure described above.  Drivers using the vmalloc() method
+can get a memory pointer with:
+
+    void *videobuf_to_vmalloc(struct videobuf_buffer *buf);
+
+For contiguous DMA drivers, the function to use is:
+
+    dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
+
+The contiguous DMA API goes out of its way to hide the kernel-space address
+of the DMA buffer from drivers.
+
+The final step is to set the size field of the relevant videobuf_buffer
+structure to the actual size of the captured image, set state to
+VIDEOBUF_DONE, then call wake_up() on the done queue.  At this point, the
+buffer is owned by the videobuf layer and the driver should not touch it
+again.
+
+Developers who are interested in more information can go into the relevant
+header files; there are a few low-level functions declared there which have
+not been talked about here.  Also worthwhile is the vivi driver
+(drivers/media/video/vivi.c), which is maintained as an example of how V4L2
+drivers should be written.  Vivi only uses the vmalloc() API, but it's good
+enough to get started with.  Note also that all of these calls are exported
+GPL-only, so they will not be available to non-GPL kernel modules.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/vm/00-INDEX linux-libre-2.6.34-gnu1/Documentation/vm/00-INDEX
--- linux-libre-2.6.33-gnu1/Documentation/vm/00-INDEX	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/vm/00-INDEX	2010-05-16 17:17:36.000000000 -0400
@@ -4,23 +4,35 @@ active_mm.txt
 	- An explanation from Linus about tsk->active_mm vs tsk->mm.
 balance
 	- various information on memory balancing.
+hugepage-mmap.c
+	- Example app using huge page memory with the mmap system call.
+hugepage-shm.c
+	- Example app using huge page memory with Sys V shared memory system calls.
 hugetlbpage.txt
 	- a brief summary of hugetlbpage support in the Linux kernel.
+hwpoison.txt
+	- explains what hwpoison is
 ksm.txt
 	- how to use the Kernel Samepage Merging feature.
 locking
 	- info on how locking and synchronization is done in the Linux vm code.
+map_hugetlb.c
+	- an example program that uses the MAP_HUGETLB mmap flag.
 numa
 	- information about NUMA specific code in the Linux vm.
 numa_memory_policy.txt
 	- documentation of concepts and APIs of the 2.6 memory policy support.
 overcommit-accounting
 	- description of the Linux kernels overcommit handling modes.
+page-types.c
+	- Tool for querying page flags
 page_migration
 	- description of page migration in NUMA systems.
+pagemap.txt
+	- pagemap, from the userspace perspective
 slabinfo.c
 	- source code for a tool to get reports about slabs.
 slub.txt
 	- a short users guide for SLUB.
-map_hugetlb.c
-	- an example program that uses the MAP_HUGETLB mmap flag.
+unevictable-lru.txt
+	- Unevictable LRU infrastructure
diff -druNp linux-libre-2.6.33-gnu1/Documentation/vm/hugepage-mmap.c linux-libre-2.6.34-gnu1/Documentation/vm/hugepage-mmap.c
--- linux-libre-2.6.33-gnu1/Documentation/vm/hugepage-mmap.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/vm/hugepage-mmap.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,91 @@
+/*
+ * hugepage-mmap:
+ *
+ * Example of using huge page memory in a user application using the mmap
+ * system call.  Before running this application, make sure that the
+ * administrator has mounted the hugetlbfs filesystem (on some directory
+ * like /mnt) using the command mount -t hugetlbfs nodev /mnt. In this
+ * example, the app is requesting memory of size 256MB that is backed by
+ * huge pages.
+ *
+ * For the ia64 architecture, the Linux kernel reserves Region number 4 for
+ * huge pages.  That means that if one requires a fixed address, a huge page
+ * aligned address starting with 0x800000... will be required.  If a fixed
+ * address is not required, the kernel will select an address in the proper
+ * range.
+ * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#define FILE_NAME "/mnt/hugepagefile"
+#define LENGTH (256UL*1024*1024)
+#define PROTECTION (PROT_READ | PROT_WRITE)
+
+/* Only ia64 requires this */
+#ifdef __ia64__
+#define ADDR (void *)(0x8000000000000000UL)
+#define FLAGS (MAP_SHARED | MAP_FIXED)
+#else
+#define ADDR (void *)(0x0UL)
+#define FLAGS (MAP_SHARED)
+#endif
+
+static void check_bytes(char *addr)
+{
+	printf("First hex is %x\n", *((unsigned int *)addr));
+}
+
+static void write_bytes(char *addr)
+{
+	unsigned long i;
+
+	for (i = 0; i < LENGTH; i++)
+		*(addr + i) = (char)i;
+}
+
+static void read_bytes(char *addr)
+{
+	unsigned long i;
+
+	check_bytes(addr);
+	for (i = 0; i < LENGTH; i++)
+		if (*(addr + i) != (char)i) {
+			printf("Mismatch at %lu\n", i);
+			break;
+		}
+}
+
+int main(void)
+{
+	void *addr;
+	int fd;
+
+	fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
+	if (fd < 0) {
+		perror("Open failed");
+		exit(1);
+	}
+
+	addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, fd, 0);
+	if (addr == MAP_FAILED) {
+		perror("mmap");
+		unlink(FILE_NAME);
+		exit(1);
+	}
+
+	printf("Returned address is %p\n", addr);
+	check_bytes(addr);
+	write_bytes(addr);
+	read_bytes(addr);
+
+	munmap(addr, LENGTH);
+	close(fd);
+	unlink(FILE_NAME);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/Documentation/vm/hugepage-shm.c linux-libre-2.6.34-gnu1/Documentation/vm/hugepage-shm.c
--- linux-libre-2.6.33-gnu1/Documentation/vm/hugepage-shm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/vm/hugepage-shm.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,98 @@
+/*
+ * hugepage-shm:
+ *
+ * Example of using huge page memory in a user application using Sys V shared
+ * memory system calls.  In this example the app is requesting 256MB of
+ * memory that is backed by huge pages.  The application uses the flag
+ * SHM_HUGETLB in the shmget system call to inform the kernel that it is
+ * requesting huge pages.
+ *
+ * For the ia64 architecture, the Linux kernel reserves Region number 4 for
+ * huge pages.  That means that if one requires a fixed address, a huge page
+ * aligned address starting with 0x800000... will be required.  If a fixed
+ * address is not required, the kernel will select an address in the proper
+ * range.
+ * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
+ *
+ * Note: The default shared memory limit is quite low on many kernels,
+ * you may need to increase it via:
+ *
+ * echo 268435456 > /proc/sys/kernel/shmmax
+ *
+ * This will increase the maximum size per shared memory segment to 256MB.
+ * The other limit that you will hit eventually is shmall which is the
+ * total amount of shared memory in pages. To set it to 16GB on a system
+ * with a 4kB pagesize do:
+ *
+ * echo 4194304 > /proc/sys/kernel/shmall
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/mman.h>
+
+#ifndef SHM_HUGETLB
+#define SHM_HUGETLB 04000
+#endif
+
+#define LENGTH (256UL*1024*1024)
+
+#define dprintf(x)  printf(x)
+
+/* Only ia64 requires this */
+#ifdef __ia64__
+#define ADDR (void *)(0x8000000000000000UL)
+#define SHMAT_FLAGS (SHM_RND)
+#else
+#define ADDR (void *)(0x0UL)
+#define SHMAT_FLAGS (0)
+#endif
+
+int main(void)
+{
+	int shmid;
+	unsigned long i;
+	char *shmaddr;
+
+	if ((shmid = shmget(2, LENGTH,
+			    SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W)) < 0) {
+		perror("shmget");
+		exit(1);
+	}
+	printf("shmid: 0x%x\n", shmid);
+
+	shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS);
+	if (shmaddr == (char *)-1) {
+		perror("Shared memory attach failure");
+		shmctl(shmid, IPC_RMID, NULL);
+		exit(2);
+	}
+	printf("shmaddr: %p\n", shmaddr);
+
+	dprintf("Starting the writes:\n");
+	for (i = 0; i < LENGTH; i++) {
+		shmaddr[i] = (char)(i);
+		if (!(i % (1024 * 1024)))
+			dprintf(".");
+	}
+	dprintf("\n");
+
+	dprintf("Starting the Check...");
+	for (i = 0; i < LENGTH; i++)
+		if (shmaddr[i] != (char)i)
+			printf("\nIndex %lu mismatched\n", i);
+	dprintf("Done.\n");
+
+	if (shmdt((const void *)shmaddr) != 0) {
+		perror("Detach failure");
+		shmctl(shmid, IPC_RMID, NULL);
+		exit(3);
+	}
+
+	shmctl(shmid, IPC_RMID, NULL);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/Documentation/vm/hugetlbpage.txt linux-libre-2.6.34-gnu1/Documentation/vm/hugetlbpage.txt
--- linux-libre-2.6.33-gnu1/Documentation/vm/hugetlbpage.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/vm/hugetlbpage.txt	2010-05-16 17:17:36.000000000 -0400
@@ -299,176 +299,11 @@ map_hugetlb.c.
 *******************************************************************
 
 /*
- * Example of using huge page memory in a user application using Sys V shared
- * memory system calls.  In this example the app is requesting 256MB of
- * memory that is backed by huge pages.  The application uses the flag
- * SHM_HUGETLB in the shmget system call to inform the kernel that it is
- * requesting huge pages.
- *
- * For the ia64 architecture, the Linux kernel reserves Region number 4 for
- * huge pages.  That means that if one requires a fixed address, a huge page
- * aligned address starting with 0x800000... will be required.  If a fixed
- * address is not required, the kernel will select an address in the proper
- * range.
- * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
- *
- * Note: The default shared memory limit is quite low on many kernels,
- * you may need to increase it via:
- *
- * echo 268435456 > /proc/sys/kernel/shmmax
- *
- * This will increase the maximum size per shared memory segment to 256MB.
- * The other limit that you will hit eventually is shmall which is the
- * total amount of shared memory in pages. To set it to 16GB on a system
- * with a 4kB pagesize do:
- *
- * echo 4194304 > /proc/sys/kernel/shmall
+ * hugepage-shm:  see Documentation/vm/hugepage-shm.c
  */
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <sys/mman.h>
-
-#ifndef SHM_HUGETLB
-#define SHM_HUGETLB 04000
-#endif
-
-#define LENGTH (256UL*1024*1024)
-
-#define dprintf(x)  printf(x)
-
-#define ADDR (void *)(0x0UL)	/* let kernel choose address */
-#define SHMAT_FLAGS (0)
-
-int main(void)
-{
-	int shmid;
-	unsigned long i;
-	char *shmaddr;
-
-	if ((shmid = shmget(2, LENGTH,
-			    SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W)) < 0) {
-		perror("shmget");
-		exit(1);
-	}
-	printf("shmid: 0x%x\n", shmid);
-
-	shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS);
-	if (shmaddr == (char *)-1) {
-		perror("Shared memory attach failure");
-		shmctl(shmid, IPC_RMID, NULL);
-		exit(2);
-	}
-	printf("shmaddr: %p\n", shmaddr);
-
-	dprintf("Starting the writes:\n");
-	for (i = 0; i < LENGTH; i++) {
-		shmaddr[i] = (char)(i);
-		if (!(i % (1024 * 1024)))
-			dprintf(".");
-	}
-	dprintf("\n");
-
-	dprintf("Starting the Check...");
-	for (i = 0; i < LENGTH; i++)
-		if (shmaddr[i] != (char)i)
-			printf("\nIndex %lu mismatched\n", i);
-	dprintf("Done.\n");
-
-	if (shmdt((const void *)shmaddr) != 0) {
-		perror("Detach failure");
-		shmctl(shmid, IPC_RMID, NULL);
-		exit(3);
-	}
-
-	shmctl(shmid, IPC_RMID, NULL);
-
-	return 0;
-}
 
 *******************************************************************
 
 /*
- * Example of using huge page memory in a user application using the mmap
- * system call.  Before running this application, make sure that the
- * administrator has mounted the hugetlbfs filesystem (on some directory
- * like /mnt) using the command mount -t hugetlbfs nodev /mnt. In this
- * example, the app is requesting memory of size 256MB that is backed by
- * huge pages.
- *
- * For the ia64 architecture, the Linux kernel reserves Region number 4 for
- * huge pages.  That means that if one requires a fixed address, a huge page
- * aligned address starting with 0x800000... will be required.  If a fixed
- * address is not required, the kernel will select an address in the proper
- * range.
- * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
+ * hugepage-mmap:  see Documentation/vm/hugepage-mmap.c
  */
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-
-#define FILE_NAME "/mnt/hugepagefile"
-#define LENGTH (256UL*1024*1024)
-#define PROTECTION (PROT_READ | PROT_WRITE)
-
-#define ADDR (void *)(0x0UL)	/* let kernel choose address */
-#define FLAGS (MAP_SHARED)
-
-void check_bytes(char *addr)
-{
-	printf("First hex is %x\n", *((unsigned int *)addr));
-}
-
-void write_bytes(char *addr)
-{
-	unsigned long i;
-
-	for (i = 0; i < LENGTH; i++)
-		*(addr + i) = (char)i;
-}
-
-void read_bytes(char *addr)
-{
-	unsigned long i;
-
-	check_bytes(addr);
-	for (i = 0; i < LENGTH; i++)
-		if (*(addr + i) != (char)i) {
-			printf("Mismatch at %lu\n", i);
-			break;
-		}
-}
-
-int main(void)
-{
-	void *addr;
-	int fd;
-
-	fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
-	if (fd < 0) {
-		perror("Open failed");
-		exit(1);
-	}
-
-	addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, fd, 0);
-	if (addr == MAP_FAILED) {
-		perror("mmap");
-		unlink(FILE_NAME);
-		exit(1);
-	}
-
-	printf("Returned address is %p\n", addr);
-	check_bytes(addr);
-	write_bytes(addr);
-	read_bytes(addr);
-
-	munmap(addr, LENGTH);
-	close(fd);
-	unlink(FILE_NAME);
-
-	return 0;
-}
diff -druNp linux-libre-2.6.33-gnu1/Documentation/vm/Makefile linux-libre-2.6.34-gnu1/Documentation/vm/Makefile
--- linux-libre-2.6.33-gnu1/Documentation/vm/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/vm/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
 obj- := dummy.o
 
 # List of programs to build
-hostprogs-y := slabinfo page-types
+hostprogs-y := slabinfo page-types hugepage-mmap hugepage-shm map_hugetlb
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
diff -druNp linux-libre-2.6.33-gnu1/Documentation/vm/map_hugetlb.c linux-libre-2.6.34-gnu1/Documentation/vm/map_hugetlb.c
--- linux-libre-2.6.33-gnu1/Documentation/vm/map_hugetlb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/vm/map_hugetlb.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,12 +31,12 @@
 #define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
 #endif
 
-void check_bytes(char *addr)
+static void check_bytes(char *addr)
 {
 	printf("First hex is %x\n", *((unsigned int *)addr));
 }
 
-void write_bytes(char *addr)
+static void write_bytes(char *addr)
 {
 	unsigned long i;
 
@@ -44,7 +44,7 @@ void write_bytes(char *addr)
 		*(addr + i) = (char)i;
 }
 
-void read_bytes(char *addr)
+static void read_bytes(char *addr)
 {
 	unsigned long i;
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/vm/slub.txt linux-libre-2.6.34-gnu1/Documentation/vm/slub.txt
--- linux-libre-2.6.33-gnu1/Documentation/vm/slub.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/vm/slub.txt	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@ Possible debug options are
 	P		Poisoning (object and padding)
 	U		User tracking (free and alloc)
 	T		Trace (please only use on single slabs)
+	A		Toggle failslab filter mark for the cache
 	O		Switch debugging off for caches that would have
 			caused higher minimum slab orders
 	-		Switch all debugging off (useful if the kernel is
diff -druNp linux-libre-2.6.33-gnu1/Documentation/volatile-considered-harmful.txt linux-libre-2.6.34-gnu1/Documentation/volatile-considered-harmful.txt
--- linux-libre-2.6.33-gnu1/Documentation/volatile-considered-harmful.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/volatile-considered-harmful.txt	2010-05-16 17:17:36.000000000 -0400
@@ -63,9 +63,9 @@ way to perform a busy wait is:
         cpu_relax();
 
 The cpu_relax() call can lower CPU power consumption or yield to a
-hyperthreaded twin processor; it also happens to serve as a memory barrier,
-so, once again, volatile is unnecessary.  Of course, busy-waiting is
-generally an anti-social act to begin with.
+hyperthreaded twin processor; it also happens to serve as a compiler
+barrier, so, once again, volatile is unnecessary.  Of course, busy-
+waiting is generally an anti-social act to begin with.
 
 There are still a few rare situations where volatile makes sense in the
 kernel:
diff -druNp linux-libre-2.6.33-gnu1/Documentation/voyager.txt linux-libre-2.6.34-gnu1/Documentation/voyager.txt
--- linux-libre-2.6.33-gnu1/Documentation/voyager.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/voyager.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,95 +0,0 @@
-Running Linux on the Voyager Architecture
-=========================================
-
-For full details and current project status, see
-
-http://www.hansenpartnership.com/voyager
-
-The voyager architecture was designed by NCR in the mid 80s to be a
-fully SMP capable RAS computing architecture built around intel's 486
-chip set.  The voyager came in three levels of architectural
-sophistication: 3,4 and 5 --- 1 and 2 never made it out of prototype.
-The linux patches support only the Level 5 voyager architecture (any
-machine class 3435 and above).
-
-The Voyager Architecture
-------------------------
-
-Voyager machines consist of a Baseboard with a 386 diagnostic
-processor, a Power Supply Interface (PSI) a Primary and possibly
-Secondary Microchannel bus and between 2 and 20 voyager slots.  The
-voyager slots can be populated with memory and cpu cards (up to 4GB
-memory and from 1 486 to 32 Pentium Pro processors).  Internally, the
-voyager has a dual arbitrated system bus and a configuration and test
-bus (CAT).  The voyager bus speed is 40MHz.  Therefore (since all
-voyager cards are dual ported for each system bus) the maximum
-transfer rate is 320Mb/s but only if you have your slot configuration
-tuned (only memory cards can communicate with both busses at once, CPU
-cards utilise them one at a time).
-
-Voyager SMP
------------
-
-Since voyager was the first intel based SMP system, it is slightly
-more primitive than the Intel IO-APIC approach to SMP.  Voyager allows
-arbitrary interrupt routing (including processor affinity routing) of
-all 16 PC type interrupts.  However it does this by using a modified
-5259 master/slave chip set instead of an APIC bus.  Additionally,
-voyager supports Cross Processor Interrupts (CPI) equivalent to the
-APIC IPIs.  There are two routed voyager interrupt lines provided to
-each slot.
-
-Processor Cards
----------------
-
-These come in single, dyadic and quad configurations (the quads are
-problematic--see later).  The maximum configuration is 8 quad cards
-for 32 way SMP.
-
-Quad Processors
----------------
-
-Because voyager only supplies two interrupt lines to each Processor
-card, the Quad processors have to be configured (and Bootstrapped) in
-as a pair of Master/Slave processors.
-
-In fact, most Quad cards only accept one VIC interrupt line, so they
-have one interrupt handling processor (called the VIC extended
-processor) and three non-interrupt handling processors.
-
-Current Status
---------------
-
-The System will boot on Mono, Dyad and Quad cards.  There was
-originally a Quad boot problem which has been fixed by proper gdt
-alignment in the initial boot loader.  If you still cannot get your
-voyager system to boot, email me at:
-
-<J.E.J.Bottomley@HansenPartnership.com>
-
-
-The Quad cards now support using the separate Quad CPI vectors instead
-of going through the VIC mailbox system.
-
-The Level 4 architecture (3430 and 3360 Machines) should also work
-fine.
-
-Dump Switch
------------
-
-The voyager dump switch sends out a broadcast NMI which the voyager
-code intercepts and does a task dump.
-
-Power Switch
-------------
-
-The front panel power switch is intercepted by the kernel and should
-cause a system shutdown and power off.
-
-A Note About Mixed CPU Systems
-------------------------------
-
-Linux isn't designed to handle mixed CPU systems very well.  In order
-to get everything going you *must* make sure that your lowest
-capability CPU is used for booting.  Also, mixing CPU classes
-(e.g. 486 and 586) is really not going to work very well at all.
diff -druNp linux-libre-2.6.33-gnu1/Documentation/watchdog/src/watchdog-simple.c linux-libre-2.6.34-gnu1/Documentation/watchdog/src/watchdog-simple.c
--- linux-libre-2.6.33-gnu1/Documentation/watchdog/src/watchdog-simple.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/watchdog/src/watchdog-simple.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,9 +17,6 @@ int main(void)
 			ret = -1;
 			break;
 		}
-		ret = fsync(fd);
-		if (ret)
-			break;
 		sleep(10);
 	}
 	close(fd);
diff -druNp linux-libre-2.6.33-gnu1/Documentation/watchdog/src/watchdog-test.c linux-libre-2.6.34-gnu1/Documentation/watchdog/src/watchdog-test.c
--- linux-libre-2.6.33-gnu1/Documentation/watchdog/src/watchdog-test.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/watchdog/src/watchdog-test.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,8 @@ static void keep_alive(void)
  */
 int main(int argc, char *argv[])
 {
+    int flags;
+
     fd = open("/dev/watchdog", O_WRONLY);
 
     if (fd == -1) {
@@ -41,12 +43,14 @@ int main(int argc, char *argv[])
 
     if (argc > 1) {
 	if (!strncasecmp(argv[1], "-d", 2)) {
-	    ioctl(fd, WDIOC_SETOPTIONS, WDIOS_DISABLECARD);
+	    flags = WDIOS_DISABLECARD;
+	    ioctl(fd, WDIOC_SETOPTIONS, &flags);
 	    fprintf(stderr, "Watchdog card disabled.\n");
 	    fflush(stderr);
 	    exit(0);
 	} else if (!strncasecmp(argv[1], "-e", 2)) {
-	    ioctl(fd, WDIOC_SETOPTIONS, WDIOS_ENABLECARD);
+	    flags = WDIOS_ENABLECARD;
+	    ioctl(fd, WDIOC_SETOPTIONS, &flags);
 	    fprintf(stderr, "Watchdog card enabled.\n");
 	    fflush(stderr);
 	    exit(0);
diff -druNp linux-libre-2.6.33-gnu1/Documentation/watchdog/watchdog-api.txt linux-libre-2.6.34-gnu1/Documentation/watchdog/watchdog-api.txt
--- linux-libre-2.6.33-gnu1/Documentation/watchdog/watchdog-api.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/watchdog/watchdog-api.txt	2010-05-16 17:17:36.000000000 -0400
@@ -222,11 +222,10 @@ returned value is the temperature in deg
     ioctl(fd, WDIOC_GETTEMP, &temperature);
 
 Finally the SETOPTIONS ioctl can be used to control some aspects of
-the cards operation; right now the pcwd driver is the only one
-supporting this ioctl.
+the cards operation.
 
     int options = 0;
-    ioctl(fd, WDIOC_SETOPTIONS, options);
+    ioctl(fd, WDIOC_SETOPTIONS, &options);
 
 The following options are available:
 
diff -druNp linux-libre-2.6.33-gnu1/Documentation/x86/x86_64/boot-options.txt linux-libre-2.6.34-gnu1/Documentation/x86/x86_64/boot-options.txt
--- linux-libre-2.6.33-gnu1/Documentation/x86/x86_64/boot-options.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/Documentation/x86/x86_64/boot-options.txt	2010-05-16 17:17:36.000000000 -0400
@@ -166,19 +166,13 @@ NUMA
 
   numa=noacpi   Don't parse the SRAT table for NUMA setup
 
-  numa=fake=CMDLINE
-		If a number, fakes CMDLINE nodes and ignores NUMA setup of the
-		actual machine.  Otherwise, system memory is configured
-		depending on the sizes and coefficients listed.  For example:
-			numa=fake=2*512,1024,4*256,*128
-		gives two 512M nodes, a 1024M node, four 256M nodes, and the
-		rest split into 128M chunks.  If the last character of CMDLINE
-		is a *, the remaining memory is divided up equally among its
-		coefficient:
-			numa=fake=2*512,2*
-		gives two 512M nodes and the rest split into two nodes.
-		Otherwise, the remaining system RAM is allocated to an
-		additional node.
+  numa=fake=<size>[MG]
+		If given as a memory unit, fills all system RAM with nodes of
+		size interleaved over physical nodes.
+
+  numa=fake=<N>
+		If given as an integer, fills all system RAM with N fake nodes
+		interleaved over physical nodes.
 
 ACPI
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/ac.c linux-libre-2.6.34-gnu1/drivers/acpi/ac.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/ac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/ac.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #ifdef CONFIG_ACPI_PROCFS_POWER
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/accommon.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/accommon.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/accommon.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/accommon.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acconfig.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acconfig.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acconfig.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acconfig.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acdebug.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acdebug.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acdebug.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acdebug.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acdispat.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acdispat.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acdispat.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acdispat.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acevents.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acevents.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acevents.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acevents.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -76,12 +76,9 @@ acpi_ev_queue_notify_request(struct acpi
  * evgpe - GPE handling and dispatch
  */
 acpi_status
-acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info,
-				u8 type);
+acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info);
 
-acpi_status
-acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info,
-		   u8 write_to_hardware);
+acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
 
 acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
 
@@ -122,9 +119,6 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_eve
 u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list);
 
 acpi_status
-acpi_ev_set_gpe_type(struct acpi_gpe_event_info *gpe_event_info, u8 type);
-
-acpi_status
 acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info);
 
 acpi_status acpi_ev_gpe_initialize(void);
@@ -139,8 +133,7 @@ acpi_status acpi_ev_initialize_op_region
 acpi_status
 acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
 			       u32 function,
-			       u32 region_offset,
-			       u32 bit_width, acpi_integer * value);
+			       u32 region_offset, u32 bit_width, u64 *value);
 
 acpi_status
 acpi_ev_attach_region(union acpi_operand_object *handler_obj,
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acglobal.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acglobal.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acglobal.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acglobal.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/achware.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/achware.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/achware.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/achware.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acinterp.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acinterp.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acinterp.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acinterp.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -129,18 +129,17 @@ acpi_ex_common_buffer_setup(union acpi_o
 
 acpi_status
 acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,
-			       acpi_integer mask,
-			       acpi_integer field_value,
-			       u32 field_datum_byte_offset);
+			       u64 mask,
+			       u64 field_value, u32 field_datum_byte_offset);
 
 void
-acpi_ex_get_buffer_datum(acpi_integer * datum,
+acpi_ex_get_buffer_datum(u64 *datum,
 			 void *buffer,
 			 u32 buffer_length,
 			 u32 byte_granularity, u32 buffer_offset);
 
 void
-acpi_ex_set_buffer_datum(acpi_integer merged_datum,
+acpi_ex_set_buffer_datum(u64 merged_datum,
 			 void *buffer,
 			 u32 buffer_length,
 			 u32 byte_granularity, u32 buffer_offset);
@@ -168,8 +167,7 @@ acpi_ex_insert_into_field(union acpi_ope
 
 acpi_status
 acpi_ex_access_region(union acpi_operand_object *obj_desc,
-		      u32 field_datum_byte_offset,
-		      acpi_integer * value, u32 read_write);
+		      u32 field_datum_byte_offset, u64 *value, u32 read_write);
 
 /*
  * exmisc - misc support routines
@@ -193,16 +191,14 @@ acpi_ex_do_concatenate(union acpi_operan
 
 acpi_status
 acpi_ex_do_logical_numeric_op(u16 opcode,
-			      acpi_integer integer0,
-			      acpi_integer integer1, u8 * logical_result);
+			      u64 integer0, u64 integer1, u8 *logical_result);
 
 acpi_status
 acpi_ex_do_logical_op(u16 opcode,
 		      union acpi_operand_object *operand0,
-		      union acpi_operand_object *operand1, u8 * logical_result);
+		      union acpi_operand_object *operand1, u8 *logical_result);
 
-acpi_integer
-acpi_ex_do_math_op(u16 opcode, acpi_integer operand0, acpi_integer operand1);
+u64 acpi_ex_do_math_op(u16 opcode, u64 operand0, u64 operand1);
 
 acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state);
 
@@ -278,7 +274,7 @@ acpi_status
 acpi_ex_system_do_notify_op(union acpi_operand_object *value,
 			    union acpi_operand_object *obj_desc);
 
-acpi_status acpi_ex_system_do_suspend(acpi_integer time);
+acpi_status acpi_ex_system_do_suspend(u64 time);
 
 acpi_status acpi_ex_system_do_stall(u32 time);
 
@@ -461,9 +457,9 @@ void acpi_ex_acquire_global_lock(u32 rul
 
 void acpi_ex_release_global_lock(u32 rule);
 
-void acpi_ex_eisa_id_to_string(char *dest, acpi_integer compressed_id);
+void acpi_ex_eisa_id_to_string(char *dest, u64 compressed_id);
 
-void acpi_ex_integer_to_string(char *dest, acpi_integer value);
+void acpi_ex_integer_to_string(char *dest, u64 value);
 
 /*
  * exregion - default op_region handlers
@@ -472,7 +468,7 @@ acpi_status
 acpi_ex_system_memory_space_handler(u32 function,
 				    acpi_physical_address address,
 				    u32 bit_width,
-				    acpi_integer * value,
+				    u64 *value,
 				    void *handler_context,
 				    void *region_context);
 
@@ -480,35 +476,35 @@ acpi_status
 acpi_ex_system_io_space_handler(u32 function,
 				acpi_physical_address address,
 				u32 bit_width,
-				acpi_integer * value,
+				u64 *value,
 				void *handler_context, void *region_context);
 
 acpi_status
 acpi_ex_pci_config_space_handler(u32 function,
 				 acpi_physical_address address,
 				 u32 bit_width,
-				 acpi_integer * value,
+				 u64 *value,
 				 void *handler_context, void *region_context);
 
 acpi_status
 acpi_ex_cmos_space_handler(u32 function,
 			   acpi_physical_address address,
 			   u32 bit_width,
-			   acpi_integer * value,
+			   u64 *value,
 			   void *handler_context, void *region_context);
 
 acpi_status
 acpi_ex_pci_bar_space_handler(u32 function,
 			      acpi_physical_address address,
 			      u32 bit_width,
-			      acpi_integer * value,
+			      u64 *value,
 			      void *handler_context, void *region_context);
 
 acpi_status
 acpi_ex_embedded_controller_space_handler(u32 function,
 					  acpi_physical_address address,
 					  u32 bit_width,
-					  acpi_integer * value,
+					  u64 *value,
 					  void *handler_context,
 					  void *region_context);
 
@@ -516,14 +512,14 @@ acpi_status
 acpi_ex_sm_bus_space_handler(u32 function,
 			     acpi_physical_address address,
 			     u32 bit_width,
-			     acpi_integer * value,
+			     u64 *value,
 			     void *handler_context, void *region_context);
 
 acpi_status
 acpi_ex_data_table_space_handler(u32 function,
 				 acpi_physical_address address,
 				 u32 bit_width,
-				 acpi_integer * value,
+				 u64 *value,
 				 void *handler_context, void *region_context);
 
 #endif				/* __INTERP_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/aclocal.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/aclocal.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/aclocal.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/aclocal.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -374,6 +374,7 @@ union acpi_predefined_info {
 struct acpi_predefined_data {
 	char *pathname;
 	const union acpi_predefined_info *predefined;
+	union acpi_operand_object *parent_package;
 	u32 flags;
 	u8 node_flags;
 };
@@ -426,6 +427,8 @@ struct acpi_gpe_event_info {
 	struct acpi_gpe_register_info *register_info;	/* Backpointer to register info */
 	u8 flags;		/* Misc info about this GPE */
 	u8 gpe_number;		/* This GPE */
+	u8 runtime_count;
+	u8 wakeup_count;
 };
 
 /* Information about a GPE register pair, one per each status/enable pair in an array */
@@ -649,8 +652,7 @@ struct acpi_opcode_info {
 };
 
 union acpi_parse_value {
-	acpi_integer integer;	/* Integer constant (Up to 64 bits) */
-	struct uint64_struct integer64;	/* Structure overlay for 2 32-bit Dwords */
+	u64 integer;		/* Integer constant (Up to 64 bits) */
 	u32 size;		/* bytelist or field size */
 	char *string;		/* NULL terminated string */
 	u8 *buffer;		/* buffer or string */
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acmacros.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acmacros.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acmacros.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acmacros.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -272,8 +272,8 @@
  * MASK_BITS_ABOVE creates a mask starting AT the position and above
  * MASK_BITS_BELOW creates a mask starting one bit BELOW the position
  */
-#define ACPI_MASK_BITS_ABOVE(position)      (~((ACPI_INTEGER_MAX) << ((u32) (position))))
-#define ACPI_MASK_BITS_BELOW(position)      ((ACPI_INTEGER_MAX) << ((u32) (position)))
+#define ACPI_MASK_BITS_ABOVE(position)      (~((ACPI_UINT64_MAX) << ((u32) (position))))
+#define ACPI_MASK_BITS_BELOW(position)      ((ACPI_UINT64_MAX) << ((u32) (position)))
 
 /* Bitfields within ACPI registers */
 
@@ -414,16 +414,16 @@
 											acpi_ut_ptr_exit (ACPI_DEBUG_PARAMETERS, (u8 *) _s); \
 											return (_s); })
 #define return_VALUE(s)                 ACPI_DO_WHILE0 ({ \
-											register acpi_integer _s = (s); \
+											register u64 _s = (s); \
 											acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, _s); \
 											return (_s); })
 #define return_UINT8(s)                 ACPI_DO_WHILE0 ({ \
 											register u8 _s = (u8) (s); \
-											acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (acpi_integer) _s); \
+											acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (u64) _s); \
 											return (_s); })
 #define return_UINT32(s)                ACPI_DO_WHILE0 ({ \
 											register u32 _s = (u32) (s); \
-											acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (acpi_integer) _s); \
+											acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (u64) _s); \
 											return (_s); })
 #else				/* Use original less-safe macros */
 
@@ -434,7 +434,7 @@
 											acpi_ut_ptr_exit (ACPI_DEBUG_PARAMETERS, (u8 *) (s)); \
 											return((s)); })
 #define return_VALUE(s)                 ACPI_DO_WHILE0 ({ \
-											acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (acpi_integer) (s)); \
+											acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (u64) (s)); \
 											return((s)); })
 #define return_UINT8(s)                 return_VALUE(s)
 #define return_UINT32(s)                return_VALUE(s)
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acnamesp.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acnamesp.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acnamesp.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acnamesp.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -286,6 +286,17 @@ acpi_status
 acpi_ns_repair_package_list(struct acpi_predefined_data *data,
 			    union acpi_operand_object **obj_desc_ptr);
 
+acpi_status
+acpi_ns_repair_null_element(struct acpi_predefined_data *data,
+			    u32 expected_btypes,
+			    u32 package_index,
+			    union acpi_operand_object **return_object_ptr);
+
+void
+acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
+			     u8 package_type,
+			     union acpi_operand_object *obj_desc);
+
 /*
  * nsrepair2 - Return object repair for specific
  * predefined methods/objects
@@ -296,11 +307,6 @@ acpi_ns_complex_repairs(struct acpi_pred
 			acpi_status validate_status,
 			union acpi_operand_object **return_object_ptr);
 
-void
-acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
-			     u8 package_type,
-			     union acpi_operand_object *obj_desc);
-
 /*
  * nssearch - Namespace searching and entry
  */
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acobject.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acobject.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acobject.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acobject.h	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -111,7 +111,7 @@ ACPI_OBJECT_COMMON_HEADER};
 
 struct acpi_object_integer {
 	ACPI_OBJECT_COMMON_HEADER u8 fill[3];	/* Prevent warning on some compilers */
-	acpi_integer value;
+	u64 value;
 };
 
 /*
@@ -287,8 +287,10 @@ struct acpi_object_buffer_field {
 
 struct acpi_object_notify_handler {
 	ACPI_OBJECT_COMMON_HEADER struct acpi_namespace_node *node;	/* Parent device */
+	u32 handler_type;
 	acpi_notify_handler handler;
 	void *context;
+	struct acpi_object_notify_handler *next;
 };
 
 struct acpi_object_addr_handler {
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acopcode.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acopcode.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acopcode.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acopcode.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acparser.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acparser.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acparser.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acparser.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acpredef.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acpredef.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acpredef.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acpredef.h	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acresrc.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acresrc.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acresrc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acresrc.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acstruct.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acstruct.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acstruct.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acstruct.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/actables.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/actables.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/actables.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/actables.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acutils.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acutils.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acutils.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/acutils.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -134,7 +134,7 @@ char *acpi_ut_get_region_name(u8 space_i
 
 char *acpi_ut_get_event_name(u32 event_id);
 
-char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position);
+char acpi_ut_hex_to_ascii_char(u64 integer, u32 position);
 
 u8 acpi_ut_valid_object_type(acpi_object_type type);
 
@@ -279,8 +279,7 @@ acpi_ut_status_exit(u32 line_number,
 void
 acpi_ut_value_exit(u32 line_number,
 		   const char *function_name,
-		   const char *module_name,
-		   u32 component_id, acpi_integer value);
+		   const char *module_name, u32 component_id, u64 value);
 
 void
 acpi_ut_ptr_exit(u32 line_number,
@@ -324,7 +323,7 @@ acpi_ut_evaluate_object(struct acpi_name
 acpi_status
 acpi_ut_evaluate_numeric_object(char *object_name,
 				struct acpi_namespace_node *device_node,
-				acpi_integer *value);
+				u64 *value);
 
 acpi_status
 acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 *status_flags);
@@ -437,14 +436,12 @@ void acpi_ut_delete_generic_state(union
  * utmath
  */
 acpi_status
-acpi_ut_divide(acpi_integer in_dividend,
-	       acpi_integer in_divisor,
-	       acpi_integer * out_quotient, acpi_integer * out_remainder);
+acpi_ut_divide(u64 in_dividend,
+	       u64 in_divisor, u64 *out_quotient, u64 *out_remainder);
 
 acpi_status
-acpi_ut_short_divide(acpi_integer in_dividend,
-		     u32 divisor,
-		     acpi_integer * out_quotient, u32 * out_remainder);
+acpi_ut_short_divide(u64 in_dividend,
+		     u32 divisor, u64 *out_quotient, u32 *out_remainder);
 
 /*
  * utmisc
@@ -474,8 +471,7 @@ acpi_name acpi_ut_repair_name(char *name
 
 u8 acpi_ut_valid_acpi_char(char character, u32 position);
 
-acpi_status
-acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer);
+acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer);
 
 void ACPI_INTERNAL_VAR_XFACE
 acpi_ut_predefined_warning(const char *module_name,
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/amlcode.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/amlcode.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/amlcode.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/amlcode.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/amlresrc.h linux-libre-2.6.34-gnu1/drivers/acpi/acpica/amlresrc.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/amlresrc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/amlresrc.h	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsfield.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dsfield.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsfield.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dsfield.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -220,7 +220,7 @@ acpi_ds_get_field_names(struct acpi_crea
 			union acpi_parse_object *arg)
 {
 	acpi_status status;
-	acpi_integer position;
+	u64 position;
 
 	ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
 
@@ -240,8 +240,8 @@ acpi_ds_get_field_names(struct acpi_crea
 		switch (arg->common.aml_opcode) {
 		case AML_INT_RESERVEDFIELD_OP:
 
-			position = (acpi_integer) info->field_bit_position
-			    + (acpi_integer) arg->common.value.size;
+			position = (u64) info->field_bit_position
+			    + (u64) arg->common.value.size;
 
 			if (position > ACPI_UINT32_MAX) {
 				ACPI_ERROR((AE_INFO,
@@ -305,8 +305,8 @@ acpi_ds_get_field_names(struct acpi_crea
 
 			/* Keep track of bit position for the next field */
 
-			position = (acpi_integer) info->field_bit_position
-			    + (acpi_integer) arg->common.value.size;
+			position = (u64) info->field_bit_position
+			    + (u64) arg->common.value.size;
 
 			if (position > ACPI_UINT32_MAX) {
 				ACPI_ERROR((AE_INFO,
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsinit.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dsinit.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsinit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dsinit.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsmethod.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dsmethod.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsmethod.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dsmethod.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsmthdat.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dsmthdat.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsmthdat.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dsmthdat.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsobject.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dsobject.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsobject.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dsobject.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -684,7 +684,7 @@ acpi_ds_init_object_from_op(struct acpi_
 
 			case AML_ONES_OP:
 
-				obj_desc->integer.value = ACPI_INTEGER_MAX;
+				obj_desc->integer.value = ACPI_UINT64_MAX;
 
 				/* Truncate value if we are executing from a 32-bit ACPI table */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsopcode.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dsopcode.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsopcode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dsopcode.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsutils.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dsutils.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsutils.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dsutils.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dswexec.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dswexec.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dswexec.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dswexec.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dswload.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dswload.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dswload.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dswload.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dswscope.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dswscope.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dswscope.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dswscope.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dswstate.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dswstate.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dswstate.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/dswstate.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evevent.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evevent.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evevent.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evevent.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evgpeblk.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evgpeblk.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evgpeblk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evgpeblk.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -258,7 +258,6 @@ acpi_ev_save_method_info(acpi_handle obj
 	u32 gpe_number;
 	char name[ACPI_NAME_SIZE + 1];
 	u8 type;
-	acpi_status status;
 
 	ACPI_FUNCTION_TRACE(ev_save_method_info);
 
@@ -325,26 +324,20 @@ acpi_ev_save_method_info(acpi_handle obj
 
 	/*
 	 * Now we can add this information to the gpe_event_info block for use
-	 * during dispatch of this GPE. Default type is RUNTIME, although this may
-	 * change when the _PRW methods are executed later.
+	 * during dispatch of this GPE.
 	 */
 	gpe_event_info =
 	    &gpe_block->event_info[gpe_number - gpe_block->block_base_number];
 
-	gpe_event_info->flags = (u8)
-	    (type | ACPI_GPE_DISPATCH_METHOD | ACPI_GPE_TYPE_RUNTIME);
+	gpe_event_info->flags = (u8) (type | ACPI_GPE_DISPATCH_METHOD);
 
 	gpe_event_info->dispatch.method_node =
 	    (struct acpi_namespace_node *)obj_handle;
 
-	/* Update enable mask, but don't enable the HW GPE as of yet */
-
-	status = acpi_ev_enable_gpe(gpe_event_info, FALSE);
-
 	ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
 			  "Registered GPE method %s as GPE number 0x%.2X\n",
 			  name, gpe_number));
-	return_ACPI_STATUS(status);
+	return_ACPI_STATUS(AE_OK);
 }
 
 /*******************************************************************************
@@ -454,20 +447,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle ob
 							gpe_block->
 							block_base_number];
 
-		/* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
-
-		gpe_event_info->flags &=
-		    ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);
-
-		status =
-		    acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE);
-		if (ACPI_FAILURE(status)) {
-			goto cleanup;
-		}
-
-		status =
-		    acpi_ev_update_gpe_enable_masks(gpe_event_info,
-						    ACPI_GPE_DISABLE);
+		gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
 	}
 
       cleanup:
@@ -989,7 +969,6 @@ acpi_status
 acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
 			     struct acpi_gpe_block_info *gpe_block)
 {
-	acpi_status status;
 	struct acpi_gpe_event_info *gpe_event_info;
 	struct acpi_gpe_walk_info gpe_info;
 	u32 wake_gpe_count;
@@ -1019,42 +998,50 @@ acpi_ev_initialize_gpe_block(struct acpi
 		gpe_info.gpe_block = gpe_block;
 		gpe_info.gpe_device = gpe_device;
 
-		status =
-		    acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+		acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 					   ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
 					   acpi_ev_match_prw_and_gpe, NULL,
 					   &gpe_info, NULL);
 	}
 
 	/*
-	 * Enable all GPEs in this block that have these attributes:
-	 * 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.
+	 * Enable all GPEs that have a corresponding method and aren't
+	 * capable of generating wakeups. Any other GPEs within this block
+	 * must be enabled via the acpi_enable_gpe() interface.
 	 */
 	wake_gpe_count = 0;
 	gpe_enabled_count = 0;
+	if (gpe_device == acpi_gbl_fadt_gpe_device)
+		gpe_device = NULL;
 
 	for (i = 0; i < gpe_block->register_count; i++) {
-		for (j = 0; j < 8; j++) {
+		for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
+			acpi_status status;
+			acpi_size gpe_index;
+			int gpe_number;
 
 			/* Get the info block for this particular GPE */
+			gpe_index = (acpi_size)i * ACPI_GPE_REGISTER_WIDTH + j;
+			gpe_event_info = &gpe_block->event_info[gpe_index];
 
-			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)) {
-				gpe_enabled_count++;
-			}
-
-			if (gpe_event_info->flags & ACPI_GPE_TYPE_WAKE) {
+			if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
 				wake_gpe_count++;
+				if (acpi_gbl_leave_wake_gpes_disabled)
+					continue;
 			}
+
+			if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD))
+				continue;
+
+			gpe_number = gpe_index + gpe_block->block_base_number;
+			status = acpi_enable_gpe(gpe_device, gpe_number,
+						ACPI_GPE_TYPE_RUNTIME);
+			if (ACPI_FAILURE(status))
+				ACPI_ERROR((AE_INFO,
+						"Failed to enable GPE %02X\n",
+						gpe_number));
+			else
+				gpe_enabled_count++;
 		}
 	}
 
@@ -1062,15 +1049,7 @@ acpi_ev_initialize_gpe_block(struct acpi
 			  "Found %u Wake, Enabled %u Runtime GPEs in this block\n",
 			  wake_gpe_count, gpe_enabled_count));
 
-	/* Enable all valid runtime GPEs found above */
-
-	status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block, NULL);
-	if (ACPI_FAILURE(status)) {
-		ACPI_ERROR((AE_INFO, "Could not enable GPEs in GpeBlock %p",
-			    gpe_block));
-	}
-
-	return_ACPI_STATUS(status);
+	return_ACPI_STATUS(AE_OK);
 }
 
 /*******************************************************************************
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evgpe.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evgpe.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evgpe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evgpe.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -54,54 +54,9 @@ static void ACPI_SYSTEM_XFACE acpi_ev_as
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ev_set_gpe_type
- *
- * PARAMETERS:  gpe_event_info          - GPE to set
- *              Type                    - New type
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Sets the new type for the GPE (wake, run, or wake/run)
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ev_set_gpe_type(struct acpi_gpe_event_info *gpe_event_info, u8 type)
-{
-	acpi_status status;
-
-	ACPI_FUNCTION_TRACE(ev_set_gpe_type);
-
-	/* Validate type and update register enable masks */
-
-	switch (type) {
-	case ACPI_GPE_TYPE_WAKE:
-	case ACPI_GPE_TYPE_RUNTIME:
-	case ACPI_GPE_TYPE_WAKE_RUN:
-		break;
-
-	default:
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
-	}
-
-	/* Disable the GPE if currently enabled */
-
-	status = acpi_ev_disable_gpe(gpe_event_info);
-
-	/* Clear the type bits and insert the new Type */
-
-	gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK;
-	gpe_event_info->flags |= type;
-	return_ACPI_STATUS(status);
-}
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ev_update_gpe_enable_masks
  *
  * PARAMETERS:  gpe_event_info          - GPE to update
- *              Type                    - What to do: ACPI_GPE_DISABLE or
- *                                        ACPI_GPE_ENABLE
  *
  * RETURN:      Status
  *
@@ -110,8 +65,7 @@ acpi_ev_set_gpe_type(struct acpi_gpe_eve
  ******************************************************************************/
 
 acpi_status
-acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info,
-				u8 type)
+acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info)
 {
 	struct acpi_gpe_register_info *gpe_register_info;
 	u8 register_bit;
@@ -127,37 +81,14 @@ acpi_ev_update_gpe_enable_masks(struct a
 	    (1 <<
 	     (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number));
 
-	/* 1) Disable case. Simply clear all enable bits */
-
-	if (type == ACPI_GPE_DISABLE) {
-		ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
-			       register_bit);
-		ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit);
-		return_ACPI_STATUS(AE_OK);
-	}
-
-	/* 2) Enable case. Set/Clear the appropriate enable bits */
-
-	switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
-	case ACPI_GPE_TYPE_WAKE:
-		ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit);
-		ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit);
-		break;
+	ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, register_bit);
+	ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit);
 
-	case ACPI_GPE_TYPE_RUNTIME:
-		ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
-			       register_bit);
+	if (gpe_event_info->runtime_count)
 		ACPI_SET_BIT(gpe_register_info->enable_for_run, register_bit);
-		break;
 
-	case ACPI_GPE_TYPE_WAKE_RUN:
+	if (gpe_event_info->wakeup_count)
 		ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit);
-		ACPI_SET_BIT(gpe_register_info->enable_for_run, register_bit);
-		break;
-
-	default:
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
-	}
 
 	return_ACPI_STATUS(AE_OK);
 }
@@ -167,8 +98,6 @@ acpi_ev_update_gpe_enable_masks(struct a
  * FUNCTION:    acpi_ev_enable_gpe
  *
  * PARAMETERS:  gpe_event_info          - GPE to enable
- *              write_to_hardware       - Enable now, or just mark data structs
- *                                        (WAKE GPEs should be deferred)
  *
  * RETURN:      Status
  *
@@ -176,9 +105,7 @@ acpi_ev_update_gpe_enable_masks(struct a
  *
  ******************************************************************************/
 
-acpi_status
-acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info,
-		   u8 write_to_hardware)
+acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
 {
 	acpi_status status;
 
@@ -186,50 +113,18 @@ acpi_ev_enable_gpe(struct acpi_gpe_event
 
 	/* Make sure HW enable masks are updated */
 
-	status =
-	    acpi_ev_update_gpe_enable_masks(gpe_event_info, ACPI_GPE_ENABLE);
-	if (ACPI_FAILURE(status)) {
+	status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
+	if (ACPI_FAILURE(status))
 		return_ACPI_STATUS(status);
-	}
-
-	/* Mark wake-enabled or HW enable, or both */
-
-	switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
-	case ACPI_GPE_TYPE_WAKE:
-
-		ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
-		break;
-
-	case ACPI_GPE_TYPE_WAKE_RUN:
-
-		ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
-
-		/*lint -fallthrough */
-
-	case ACPI_GPE_TYPE_RUNTIME:
-
-		ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
-
-		if (write_to_hardware) {
-
-			/* Clear the GPE (of stale events), then enable it */
-
-			status = acpi_hw_clear_gpe(gpe_event_info);
-			if (ACPI_FAILURE(status)) {
-				return_ACPI_STATUS(status);
-			}
-
-			/* Enable the requested runtime GPE */
-
-			status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
-		}
-		break;
 
-	default:
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
-	}
+	/* Clear the GPE (of stale events), then enable it */
+	status = acpi_hw_clear_gpe(gpe_event_info);
+	if (ACPI_FAILURE(status))
+		return_ACPI_STATUS(status);
 
-	return_ACPI_STATUS(AE_OK);
+	/* Enable the requested GPE */
+	status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
+	return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
@@ -252,34 +147,9 @@ acpi_status acpi_ev_disable_gpe(struct a
 
 	/* Make sure HW enable masks are updated */
 
-	status =
-	    acpi_ev_update_gpe_enable_masks(gpe_event_info, ACPI_GPE_DISABLE);
-	if (ACPI_FAILURE(status)) {
+	status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
+	if (ACPI_FAILURE(status))
 		return_ACPI_STATUS(status);
-	}
-
-	/* Clear the appropriate enabled flags for this GPE */
-
-	switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
-	case ACPI_GPE_TYPE_WAKE:
-		ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
-		break;
-
-	case ACPI_GPE_TYPE_WAKE_RUN:
-		ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
-
-		/* fallthrough */
-
-	case ACPI_GPE_TYPE_RUNTIME:
-
-		/* Disable the requested runtime GPE */
-
-		ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
-		break;
-
-	default:
-		break;
-	}
 
 	/*
 	 * Even if we don't know the GPE type, make sure that we always
@@ -521,7 +391,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_as
 
 	/* Set the GPE flags for return to enabled state */
 
-	(void)acpi_ev_enable_gpe(gpe_event_info, FALSE);
+	(void)acpi_ev_update_gpe_enable_masks(gpe_event_info);
 
 	/*
 	 * Take a snapshot of the GPE info for this level - we copy the info to
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evmisc.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evmisc.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evmisc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evmisc.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -259,9 +259,15 @@ static void ACPI_SYSTEM_XFACE acpi_ev_no
 
 	handler_obj = notify_info->notify.handler_obj;
 	if (handler_obj) {
-		handler_obj->notify.handler(notify_info->notify.node,
-					    notify_info->notify.value,
-					    handler_obj->notify.context);
+		struct acpi_object_notify_handler *notifier;
+
+		notifier = &handler_obj->notify;
+		while (notifier) {
+			notifier->handler(notify_info->notify.node,
+					  notify_info->notify.value,
+					  notifier->context);
+			notifier = notifier->next;
+		}
 	}
 
 	/* All done with the info object */
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evregion.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evregion.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evregion.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evregion.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -329,7 +329,7 @@ acpi_ev_execute_reg_method(union acpi_op
  *              region_offset       - Where in the region to read or write
  *              bit_width           - Field width in bits (8, 16, 32, or 64)
  *              Value               - Pointer to in or out value, must be
- *                                    full 64-bit acpi_integer
+ *                                    a full 64-bit integer
  *
  * RETURN:      Status
  *
@@ -341,8 +341,7 @@ acpi_ev_execute_reg_method(union acpi_op
 acpi_status
 acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
 			       u32 function,
-			       u32 region_offset,
-			       u32 bit_width, acpi_integer * value)
+			       u32 region_offset, u32 bit_width, u64 *value)
 {
 	acpi_status status;
 	acpi_adr_space_handler handler;
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evrgnini.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evrgnini.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evrgnini.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evrgnini.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -168,7 +168,7 @@ acpi_ev_pci_config_region_setup(acpi_han
 				void *handler_context, void **region_context)
 {
 	acpi_status status = AE_OK;
-	acpi_integer pci_value;
+	u64 pci_value;
 	struct acpi_pci_id *pci_id = *region_context;
 	union acpi_operand_object *handler_obj;
 	struct acpi_namespace_node *parent_node;
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evsci.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evsci.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evsci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evsci.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evxface.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evxface.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evxface.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evxface.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -218,6 +218,72 @@ ACPI_EXPORT_SYMBOL(acpi_remove_fixed_eve
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_populate_handler_object
+ *
+ * PARAMETERS:  handler_obj        - Handler object to populate
+ *              handler_type       - The type of handler:
+ *                                  ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
+ *                                  ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
+ *                                  ACPI_ALL_NOTIFY:  both system and device
+ *              handler            - Address of the handler
+ *              context            - Value passed to the handler on each GPE
+ *              next               - Address of a handler object to link to
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Populate a handler object.
+ *
+ ******************************************************************************/
+static void
+acpi_populate_handler_object(struct acpi_object_notify_handler *handler_obj,
+			     u32 handler_type,
+			     acpi_notify_handler handler, void *context,
+			     struct acpi_object_notify_handler *next)
+{
+	handler_obj->handler_type = handler_type;
+	handler_obj->handler = handler;
+	handler_obj->context = context;
+	handler_obj->next = next;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_add_handler_object
+ *
+ * PARAMETERS:  parent_obj         - Parent of the new object
+ *              handler            - Address of the handler
+ *              context            - Value passed to the handler on each GPE
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new handler object and populate it.
+ *
+ ******************************************************************************/
+static acpi_status
+acpi_add_handler_object(struct acpi_object_notify_handler *parent_obj,
+			acpi_notify_handler handler, void *context)
+{
+	struct acpi_object_notify_handler *handler_obj;
+
+	/* The parent must not be a defice notify handler object. */
+	if (parent_obj->handler_type & ACPI_DEVICE_NOTIFY)
+		return AE_BAD_PARAMETER;
+
+	handler_obj = ACPI_ALLOCATE_ZEROED(sizeof(*handler_obj));
+	if (!handler_obj)
+		return AE_NO_MEMORY;
+
+	acpi_populate_handler_object(handler_obj,
+					ACPI_SYSTEM_NOTIFY,
+					handler, context,
+					parent_obj->next);
+	parent_obj->next = handler_obj;
+
+	return AE_OK;
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_install_notify_handler
  *
  * PARAMETERS:  Device          - The device for which notifies will be handled
@@ -316,15 +382,32 @@ acpi_install_notify_handler(acpi_handle
 		obj_desc = acpi_ns_get_attached_object(node);
 		if (obj_desc) {
 
-			/* Object exists - make sure there's no handler */
+			/* Object exists. */
 
-			if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
-			     obj_desc->common_notify.system_notify) ||
-			    ((handler_type & ACPI_DEVICE_NOTIFY) &&
-			     obj_desc->common_notify.device_notify)) {
+			/* For a device notify, make sure there's no handler. */
+			if ((handler_type & ACPI_DEVICE_NOTIFY) &&
+			     obj_desc->common_notify.device_notify) {
 				status = AE_ALREADY_EXISTS;
 				goto unlock_and_exit;
 			}
+
+			/* System notifies may have more handlers installed. */
+			notify_obj = obj_desc->common_notify.system_notify;
+
+			if ((handler_type & ACPI_SYSTEM_NOTIFY) && notify_obj) {
+				struct acpi_object_notify_handler *parent_obj;
+
+				if (handler_type & ACPI_DEVICE_NOTIFY) {
+					status = AE_ALREADY_EXISTS;
+					goto unlock_and_exit;
+				}
+
+				parent_obj = &notify_obj->notify;
+				status = acpi_add_handler_object(parent_obj,
+								 handler,
+								 context);
+				goto unlock_and_exit;
+			}
 		} else {
 			/* Create a new object */
 
@@ -356,9 +439,10 @@ acpi_install_notify_handler(acpi_handle
 			goto unlock_and_exit;
 		}
 
-		notify_obj->notify.node = node;
-		notify_obj->notify.handler = handler;
-		notify_obj->notify.context = context;
+		acpi_populate_handler_object(&notify_obj->notify,
+						handler_type,
+						handler, context,
+						NULL);
 
 		if (handler_type & ACPI_SYSTEM_NOTIFY) {
 			obj_desc->common_notify.system_notify = notify_obj;
@@ -418,6 +502,10 @@ acpi_remove_notify_handler(acpi_handle d
 		goto exit;
 	}
 
+
+	/* Make sure all deferred tasks are completed */
+	acpi_os_wait_events_complete(NULL);
+
 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 	if (ACPI_FAILURE(status)) {
 		goto exit;
@@ -445,15 +533,6 @@ acpi_remove_notify_handler(acpi_handle d
 			goto unlock_and_exit;
 		}
 
-		/* Make sure all deferred tasks are completed */
-
-		(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
-		acpi_os_wait_events_complete(NULL);
-		status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
 		if (handler_type & ACPI_SYSTEM_NOTIFY) {
 			acpi_gbl_system_notify.node = NULL;
 			acpi_gbl_system_notify.handler = NULL;
@@ -488,28 +567,60 @@ acpi_remove_notify_handler(acpi_handle d
 		/* Object exists - make sure there's an existing handler */
 
 		if (handler_type & ACPI_SYSTEM_NOTIFY) {
+			struct acpi_object_notify_handler *handler_obj;
+			struct acpi_object_notify_handler *parent_obj;
+
 			notify_obj = obj_desc->common_notify.system_notify;
 			if (!notify_obj) {
 				status = AE_NOT_EXIST;
 				goto unlock_and_exit;
 			}
 
-			if (notify_obj->notify.handler != handler) {
+			handler_obj = &notify_obj->notify;
+			parent_obj = NULL;
+			while (handler_obj->handler != handler) {
+				if (handler_obj->next) {
+					parent_obj = handler_obj;
+					handler_obj = handler_obj->next;
+				} else {
+					break;
+				}
+			}
+
+			if (handler_obj->handler != handler) {
 				status = AE_BAD_PARAMETER;
 				goto unlock_and_exit;
 			}
-			/* Make sure all deferred tasks are completed */
 
-			(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
-			acpi_os_wait_events_complete(NULL);
-			status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
-			if (ACPI_FAILURE(status)) {
-				goto exit;
+			/*
+			 * Remove the handler.  There are three possible cases.
+			 * First, we may need to remove a non-embedded object.
+			 * Second, we may need to remove the embedded object's
+			 * handler data, while non-embedded objects exist.
+			 * Finally, we may need to remove the embedded object
+			 * entirely along with its container.
+			 */
+			if (parent_obj) {
+				/* Non-embedded object is being removed. */
+				parent_obj->next = handler_obj->next;
+				ACPI_FREE(handler_obj);
+			} else if (notify_obj->notify.next) {
+				/*
+				 * The handler matches the embedded object, but
+				 * there are more handler objects in the list.
+				 * Replace the embedded object's data with the
+				 * first next object's data and remove that
+				 * object.
+				 */
+				parent_obj = &notify_obj->notify;
+				handler_obj = notify_obj->notify.next;
+				*parent_obj = *handler_obj;
+				ACPI_FREE(handler_obj);
+			} else {
+				/* No more handler objects in the list. */
+				obj_desc->common_notify.system_notify = NULL;
+				acpi_ut_remove_reference(notify_obj);
 			}
-
-			/* Remove the handler */
-			obj_desc->common_notify.system_notify = NULL;
-			acpi_ut_remove_reference(notify_obj);
 		}
 
 		if (handler_type & ACPI_DEVICE_NOTIFY) {
@@ -523,14 +634,6 @@ acpi_remove_notify_handler(acpi_handle d
 				status = AE_BAD_PARAMETER;
 				goto unlock_and_exit;
 			}
-			/* Make sure all deferred tasks are completed */
-
-			(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
-			acpi_os_wait_events_complete(NULL);
-			status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
-			if (ACPI_FAILURE(status)) {
-				goto exit;
-			}
 
 			/* Remove the handler */
 			obj_desc->common_notify.device_notify = NULL;
@@ -617,13 +720,6 @@ acpi_install_gpe_handler(acpi_handle gpe
 	handler->context = context;
 	handler->method_node = gpe_event_info->dispatch.method_node;
 
-	/* Disable the GPE before installing the handler */
-
-	status = acpi_ev_disable_gpe(gpe_event_info);
-	if (ACPI_FAILURE(status)) {
-		goto unlock_and_exit;
-	}
-
 	/* Install the handler */
 
 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
@@ -707,13 +803,6 @@ acpi_remove_gpe_handler(acpi_handle gpe_
 		goto unlock_and_exit;
 	}
 
-	/* Disable the GPE before removing the handler */
-
-	status = acpi_ev_disable_gpe(gpe_event_info);
-	if (ACPI_FAILURE(status)) {
-		goto unlock_and_exit;
-	}
-
 	/* Make sure all deferred tasks are completed */
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evxfevnt.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evxfevnt.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evxfevnt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evxfevnt.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -201,23 +201,27 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event)
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_set_gpe_type
+ * FUNCTION:    acpi_set_gpe
  *
  * PARAMETERS:  gpe_device      - Parent GPE Device
  *              gpe_number      - GPE level within the GPE block
- *              Type            - New GPE type
+ *              action          - Enable or disable
+ *                                Called from ISR or not
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Set the type of an individual GPE
+ * DESCRIPTION: Enable or disable an ACPI event (general purpose)
  *
  ******************************************************************************/
-acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type)
+acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
 {
 	acpi_status status = AE_OK;
+	acpi_cpu_flags flags;
 	struct acpi_gpe_event_info *gpe_event_info;
 
-	ACPI_FUNCTION_TRACE(acpi_set_gpe_type);
+	ACPI_FUNCTION_TRACE(acpi_set_gpe);
+
+	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 
 	/* Ensure that we have a valid GPE number */
 
@@ -227,19 +231,29 @@ acpi_status acpi_set_gpe_type(acpi_handl
 		goto unlock_and_exit;
 	}
 
-	if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) {
-		return_ACPI_STATUS(AE_OK);
-	}
+	/* Perform the action */
 
-	/* Set the new type (will disable GPE if currently enabled) */
+	switch (action) {
+	case ACPI_GPE_ENABLE:
+		status = acpi_ev_enable_gpe(gpe_event_info);
+		break;
 
-	status = acpi_ev_set_gpe_type(gpe_event_info, type);
+	case ACPI_GPE_DISABLE:
+		status = acpi_ev_disable_gpe(gpe_event_info);
+		break;
+
+	default:
+		ACPI_ERROR((AE_INFO, "Invalid action\n"));
+		status = AE_BAD_PARAMETER;
+		break;
+	}
 
       unlock_and_exit:
+	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 	return_ACPI_STATUS(status);
 }
 
-ACPI_EXPORT_SYMBOL(acpi_set_gpe_type)
+ACPI_EXPORT_SYMBOL(acpi_set_gpe)
 
 /*******************************************************************************
  *
@@ -247,15 +261,14 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe_type)
  *
  * PARAMETERS:  gpe_device      - Parent GPE Device
  *              gpe_number      - GPE level within the GPE block
- *              Flags           - Just enable, or also wake enable?
- *                                Called from ISR or not
+ *              type            - Purpose the GPE will be used for
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Enable an ACPI event (general purpose)
+ * DESCRIPTION: Take a reference to a GPE and enable it if necessary
  *
  ******************************************************************************/
-acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
+acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type)
 {
 	acpi_status status = AE_OK;
 	acpi_cpu_flags flags;
@@ -263,6 +276,9 @@ acpi_status acpi_enable_gpe(acpi_handle
 
 	ACPI_FUNCTION_TRACE(acpi_enable_gpe);
 
+	if (type & ~ACPI_GPE_TYPE_WAKE_RUN)
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+
 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 
 	/* Ensure that we have a valid GPE number */
@@ -273,15 +289,32 @@ acpi_status acpi_enable_gpe(acpi_handle
 		goto unlock_and_exit;
 	}
 
-	/* Perform the enable */
+	if (type & ACPI_GPE_TYPE_RUNTIME) {
+		if (++gpe_event_info->runtime_count == 1) {
+			status = acpi_ev_enable_gpe(gpe_event_info);
+			if (ACPI_FAILURE(status))
+				gpe_event_info->runtime_count--;
+		}
+	}
 
-	status = acpi_ev_enable_gpe(gpe_event_info, TRUE);
+	if (type & ACPI_GPE_TYPE_WAKE) {
+		if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
+			status = AE_BAD_PARAMETER;
+			goto unlock_and_exit;
+		}
 
-      unlock_and_exit:
+		/*
+		 * Wake-up GPEs are only enabled right prior to putting the
+		 * system into a sleep state.
+		 */
+		if (++gpe_event_info->wakeup_count == 1)
+			acpi_ev_update_gpe_enable_masks(gpe_event_info);
+	}
+
+unlock_and_exit:
 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 	return_ACPI_STATUS(status);
 }
-
 ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
 
 /*******************************************************************************
@@ -290,15 +323,14 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
  *
  * PARAMETERS:  gpe_device      - Parent GPE Device
  *              gpe_number      - GPE level within the GPE block
- *              Flags           - Just disable, or also wake disable?
- *                                Called from ISR or not
+ *              type            - Purpose the GPE won't be used for any more
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Disable an ACPI event (general purpose)
+ * DESCRIPTION: Release a reference to a GPE and disable it if necessary
  *
  ******************************************************************************/
-acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
+acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type)
 {
 	acpi_status status = AE_OK;
 	acpi_cpu_flags flags;
@@ -306,6 +338,9 @@ acpi_status acpi_disable_gpe(acpi_handle
 
 	ACPI_FUNCTION_TRACE(acpi_disable_gpe);
 
+	if (type & ~ACPI_GPE_TYPE_WAKE_RUN)
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+
 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 	/* Ensure that we have a valid GPE number */
 
@@ -315,13 +350,24 @@ acpi_status acpi_disable_gpe(acpi_handle
 		goto unlock_and_exit;
 	}
 
-	status = acpi_ev_disable_gpe(gpe_event_info);
+	if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->runtime_count) {
+		if (--gpe_event_info->runtime_count == 0)
+			status = acpi_ev_disable_gpe(gpe_event_info);
+	}
+
+	if ((type & ACPI_GPE_TYPE_WAKE) && gpe_event_info->wakeup_count) {
+		/*
+		 * Wake-up GPEs are not enabled after leaving system sleep
+		 * states, so we don't need to disable them here.
+		 */
+		if (--gpe_event_info->wakeup_count == 0)
+			acpi_ev_update_gpe_enable_masks(gpe_event_info);
+	}
 
 unlock_and_exit:
 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 	return_ACPI_STATUS(status);
 }
-
 ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
 
 /*******************************************************************************
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evxfregn.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evxfregn.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evxfregn.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/evxfregn.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exconfig.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exconfig.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exconfig.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exconfig.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -284,7 +284,7 @@ static acpi_status
 acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer)
 {
 	acpi_status status;
-	acpi_integer value;
+	u64 value;
 	u32 region_offset = 0;
 	u32 i;
 
@@ -490,7 +490,11 @@ acpi_ex_load_op(union acpi_operand_objec
 
 	status = acpi_tb_add_table(&table_desc, &table_index);
 	if (ACPI_FAILURE(status)) {
-		goto cleanup;
+
+		/* Delete allocated table buffer */
+
+		acpi_tb_delete_table(&table_desc);
+		return_ACPI_STATUS(status);
 	}
 
 	/*
@@ -533,13 +537,6 @@ acpi_ex_load_op(union acpi_operand_objec
 					     acpi_gbl_table_handler_context);
 	}
 
-      cleanup:
-	if (ACPI_FAILURE(status)) {
-
-		/* Delete allocated table buffer */
-
-		acpi_tb_delete_table(&table_desc);
-	}
 	return_ACPI_STATUS(status);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exconvrt.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exconvrt.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exconvrt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exconvrt.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -51,8 +51,7 @@ ACPI_MODULE_NAME("exconvrt")
 
 /* Local prototypes */
 static u32
-acpi_ex_convert_to_ascii(acpi_integer integer,
-			 u16 base, u8 * string, u8 max_length);
+acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 max_length);
 
 /*******************************************************************************
  *
@@ -75,7 +74,7 @@ acpi_ex_convert_to_integer(union acpi_op
 {
 	union acpi_operand_object *return_desc;
 	u8 *pointer;
-	acpi_integer result;
+	u64 result;
 	u32 i;
 	u32 count;
 	acpi_status status;
@@ -155,7 +154,7 @@ acpi_ex_convert_to_integer(union acpi_op
 			 * Little endian is used, meaning that the first byte of the buffer
 			 * is the LSB of the integer
 			 */
-			result |= (((acpi_integer) pointer[i]) << (i * 8));
+			result |= (((u64) pointer[i]) << (i * 8));
 		}
 		break;
 
@@ -285,10 +284,9 @@ acpi_ex_convert_to_buffer(union acpi_ope
  ******************************************************************************/
 
 static u32
-acpi_ex_convert_to_ascii(acpi_integer integer,
-			 u16 base, u8 * string, u8 data_width)
+acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 data_width)
 {
-	acpi_integer digit;
+	u64 digit;
 	u32 i;
 	u32 j;
 	u32 k = 0;
@@ -531,10 +529,9 @@ acpi_ex_convert_to_string(union acpi_ope
 		 * (separated by commas or spaces)
 		 */
 		for (i = 0; i < obj_desc->buffer.length; i++) {
-			new_buf += acpi_ex_convert_to_ascii((acpi_integer)
-							    obj_desc->buffer.
-							    pointer[i], base,
-							    new_buf, 1);
+			new_buf += acpi_ex_convert_to_ascii((u64) obj_desc->
+							    buffer.pointer[i],
+							    base, new_buf, 1);
 			*new_buf++ = separator;	/* each separated by a comma or space */
 		}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/excreate.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/excreate.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/excreate.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/excreate.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exdump.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exdump.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exdump.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exdump.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exfield.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exfield.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exfield.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exfield.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -130,7 +130,7 @@ acpi_ex_read_data_from_field(struct acpi
 		/* Call the region handler for the read */
 
 		status = acpi_ex_access_region(obj_desc, 0,
-					       ACPI_CAST_PTR(acpi_integer,
+					       ACPI_CAST_PTR(u64,
 							     buffer_desc->
 							     buffer.pointer),
 					       function);
@@ -141,7 +141,7 @@ acpi_ex_read_data_from_field(struct acpi
 	/*
 	 * Allocate a buffer for the contents of the field.
 	 *
-	 * If the field is larger than the size of an acpi_integer, create
+	 * If the field is larger than the current integer width, create
 	 * a BUFFER to hold it.  Otherwise, use an INTEGER.  This allows
 	 * the use of arithmetic operators on the returned value if the
 	 * field size is equal or smaller than an Integer.
@@ -306,8 +306,7 @@ acpi_ex_write_data_to_field(union acpi_o
 		 * same buffer)
 		 */
 		status = acpi_ex_access_region(obj_desc, 0,
-					       (acpi_integer *) buffer,
-					       function);
+					       (u64 *) buffer, function);
 		acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
 
 		*result_desc = buffer_desc;
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exfldio.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exfldio.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exfldio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exfldio.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -55,11 +55,10 @@ ACPI_MODULE_NAME("exfldio")
 static acpi_status
 acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
 		       u32 field_datum_byte_offset,
-		       acpi_integer * value, u32 read_write);
+		       u64 *value, u32 read_write);
 
 static u8
-acpi_ex_register_overflow(union acpi_operand_object *obj_desc,
-			  acpi_integer value);
+acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value);
 
 static acpi_status
 acpi_ex_setup_region(union acpi_operand_object *obj_desc,
@@ -212,7 +211,7 @@ acpi_ex_setup_region(union acpi_operand_
  *              field_datum_byte_offset - Byte offset of this datum within the
  *                                        parent field
  *              Value                   - Where to store value (must at least
- *                                        the size of acpi_integer)
+ *                                        64 bits)
  *              Function                - Read or Write flag plus other region-
  *                                        dependent flags
  *
@@ -224,8 +223,7 @@ acpi_ex_setup_region(union acpi_operand_
 
 acpi_status
 acpi_ex_access_region(union acpi_operand_object *obj_desc,
-		      u32 field_datum_byte_offset,
-		      acpi_integer * value, u32 function)
+		      u32 field_datum_byte_offset, u64 *value, u32 function)
 {
 	acpi_status status;
 	union acpi_operand_object *rgn_desc;
@@ -317,8 +315,7 @@ acpi_ex_access_region(union acpi_operand
  ******************************************************************************/
 
 static u8
-acpi_ex_register_overflow(union acpi_operand_object *obj_desc,
-			  acpi_integer value)
+acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value)
 {
 
 	if (obj_desc->common_field.bit_length >= ACPI_INTEGER_BIT_SIZE) {
@@ -329,7 +326,7 @@ acpi_ex_register_overflow(union acpi_ope
 		return (FALSE);
 	}
 
-	if (value >= ((acpi_integer) 1 << obj_desc->common_field.bit_length)) {
+	if (value >= ((u64) 1 << obj_desc->common_field.bit_length)) {
 		/*
 		 * The Value is larger than the maximum value that can fit into
 		 * the register.
@@ -362,11 +359,10 @@ acpi_ex_register_overflow(union acpi_ope
 
 static acpi_status
 acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
-		       u32 field_datum_byte_offset,
-		       acpi_integer * value, u32 read_write)
+		       u32 field_datum_byte_offset, u64 *value, u32 read_write)
 {
 	acpi_status status;
-	acpi_integer local_value;
+	u64 local_value;
 
 	ACPI_FUNCTION_TRACE_U32(ex_field_datum_io, field_datum_byte_offset);
 
@@ -439,8 +435,8 @@ acpi_ex_field_datum_io(union acpi_operan
 		 * the register
 		 */
 		if (acpi_ex_register_overflow(obj_desc->bank_field.bank_obj,
-					      (acpi_integer) obj_desc->
-					      bank_field.value)) {
+					      (u64) obj_desc->bank_field.
+					      value)) {
 			return_ACPI_STATUS(AE_AML_REGISTER_LIMIT);
 		}
 
@@ -481,8 +477,8 @@ acpi_ex_field_datum_io(union acpi_operan
 		 * the register
 		 */
 		if (acpi_ex_register_overflow(obj_desc->index_field.index_obj,
-					      (acpi_integer) obj_desc->
-					      index_field.value)) {
+					      (u64) obj_desc->index_field.
+					      value)) {
 			return_ACPI_STATUS(AE_AML_REGISTER_LIMIT);
 		}
 
@@ -512,7 +508,7 @@ acpi_ex_field_datum_io(union acpi_operan
 			status =
 			    acpi_ex_extract_from_field(obj_desc->index_field.
 						       data_obj, value,
-						       sizeof(acpi_integer));
+						       sizeof(u64));
 		} else {
 			/* Write the datum to the data_register */
 
@@ -523,7 +519,7 @@ acpi_ex_field_datum_io(union acpi_operan
 			status =
 			    acpi_ex_insert_into_field(obj_desc->index_field.
 						      data_obj, value,
-						      sizeof(acpi_integer));
+						      sizeof(u64));
 		}
 		break;
 
@@ -571,13 +567,12 @@ acpi_ex_field_datum_io(union acpi_operan
 
 acpi_status
 acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,
-			       acpi_integer mask,
-			       acpi_integer field_value,
-			       u32 field_datum_byte_offset)
+			       u64 mask,
+			       u64 field_value, u32 field_datum_byte_offset)
 {
 	acpi_status status = AE_OK;
-	acpi_integer merged_value;
-	acpi_integer current_value;
+	u64 merged_value;
+	u64 current_value;
 
 	ACPI_FUNCTION_TRACE_U32(ex_write_with_update_rule, mask);
 
@@ -587,7 +582,7 @@ acpi_ex_write_with_update_rule(union acp
 
 	/* If the mask is all ones, we don't need to worry about the update rule */
 
-	if (mask != ACPI_INTEGER_MAX) {
+	if (mask != ACPI_UINT64_MAX) {
 
 		/* Decode the update rule */
 
@@ -678,8 +673,8 @@ acpi_ex_extract_from_field(union acpi_op
 			   void *buffer, u32 buffer_length)
 {
 	acpi_status status;
-	acpi_integer raw_datum;
-	acpi_integer merged_datum;
+	u64 raw_datum;
+	u64 merged_datum;
 	u32 field_offset = 0;
 	u32 buffer_offset = 0;
 	u32 buffer_tail_bits;
@@ -804,10 +799,10 @@ acpi_ex_insert_into_field(union acpi_ope
 			  void *buffer, u32 buffer_length)
 {
 	acpi_status status;
-	acpi_integer mask;
-	acpi_integer width_mask;
-	acpi_integer merged_datum;
-	acpi_integer raw_datum = 0;
+	u64 mask;
+	u64 width_mask;
+	u64 merged_datum;
+	u64 raw_datum = 0;
 	u32 field_offset = 0;
 	u32 buffer_offset = 0;
 	u32 buffer_tail_bits;
@@ -855,7 +850,7 @@ acpi_ex_insert_into_field(union acpi_ope
 	 * shift operator
 	 */
 	if (obj_desc->common_field.access_bit_width == ACPI_INTEGER_BIT_SIZE) {
-		width_mask = ACPI_INTEGER_MAX;
+		width_mask = ACPI_UINT64_MAX;
 	} else {
 		width_mask =
 		    ACPI_MASK_BITS_ABOVE(obj_desc->common_field.
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exmisc.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exmisc.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exmisc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exmisc.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -409,8 +409,7 @@ acpi_ex_do_concatenate(union acpi_operan
  *
  ******************************************************************************/
 
-acpi_integer
-acpi_ex_do_math_op(u16 opcode, acpi_integer integer0, acpi_integer integer1)
+u64 acpi_ex_do_math_op(u16 opcode, u64 integer0, u64 integer1)
 {
 
 	ACPI_FUNCTION_ENTRY();
@@ -498,8 +497,7 @@ acpi_ex_do_math_op(u16 opcode, acpi_inte
 
 acpi_status
 acpi_ex_do_logical_numeric_op(u16 opcode,
-			      acpi_integer integer0,
-			      acpi_integer integer1, u8 * logical_result)
+			      u64 integer0, u64 integer1, u8 *logical_result)
 {
 	acpi_status status = AE_OK;
 	u8 local_result = FALSE;
@@ -564,8 +562,8 @@ acpi_ex_do_logical_op(u16 opcode,
 		      union acpi_operand_object *operand1, u8 * logical_result)
 {
 	union acpi_operand_object *local_operand1 = operand1;
-	acpi_integer integer0;
-	acpi_integer integer1;
+	u64 integer0;
+	u64 integer1;
 	u32 length0;
 	u32 length1;
 	acpi_status status = AE_OK;
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exmutex.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exmutex.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exmutex.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exmutex.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -375,8 +375,7 @@ acpi_ex_release_mutex(union acpi_operand
 		return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED);
 	}
 
-	/* Must have a valid thread ID */
-
+	/* Must have a valid thread. */
 	if (!walk_state->thread) {
 		ACPI_ERROR((AE_INFO,
 			    "Cannot release Mutex [%4.4s], null thread info",
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exnames.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exnames.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exnames.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exnames.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exoparg1.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exoparg1.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exoparg1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exoparg1.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -261,8 +261,8 @@ acpi_status acpi_ex_opcode_1A_1T_1R(stru
 	union acpi_operand_object *return_desc2 = NULL;
 	u32 temp32;
 	u32 i;
-	acpi_integer power_of_ten;
-	acpi_integer digit;
+	u64 power_of_ten;
+	u64 digit;
 
 	ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_1T_1R,
 				acpi_ps_get_opcode_name(walk_state->opcode));
@@ -362,7 +362,7 @@ acpi_status acpi_ex_opcode_1A_1T_1R(stru
 				/* Sum the digit into the result with the current power of 10 */
 
 				return_desc->integer.value +=
-				    (((acpi_integer) temp32) * power_of_ten);
+				    (((u64) temp32) * power_of_ten);
 
 				/* Shift to next BCD digit */
 
@@ -392,7 +392,7 @@ acpi_status acpi_ex_opcode_1A_1T_1R(stru
 				 * remainder from above
 				 */
 				return_desc->integer.value |=
-				    (((acpi_integer) temp32) << ACPI_MUL_4(i));
+				    (((u64) temp32) << ACPI_MUL_4(i));
 			}
 
 			/* Overflow if there is any data left in Digit */
@@ -439,7 +439,7 @@ acpi_status acpi_ex_opcode_1A_1T_1R(stru
 
 			/* The object exists in the namespace, return TRUE */
 
-			return_desc->integer.value = ACPI_INTEGER_MAX;
+			return_desc->integer.value = ACPI_UINT64_MAX;
 			goto cleanup;
 
 		default:
@@ -589,7 +589,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 	union acpi_operand_object *return_desc = NULL;
 	acpi_status status = AE_OK;
 	u32 type;
-	acpi_integer value;
+	u64 value;
 
 	ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_0T_1R,
 				acpi_ps_get_opcode_name(walk_state->opcode));
@@ -610,7 +610,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 		 * return_desc->Integer.Value is initially == 0 (FALSE) from above.
 		 */
 		if (!operand[0]->integer.value) {
-			return_desc->integer.value = ACPI_INTEGER_MAX;
+			return_desc->integer.value = ACPI_UINT64_MAX;
 		}
 		break;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exoparg2.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exoparg2.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exoparg2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exoparg2.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -282,7 +282,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(stru
 {
 	union acpi_operand_object **operand = &walk_state->operands[0];
 	union acpi_operand_object *return_desc = NULL;
-	acpi_integer index;
+	u64 index;
 	acpi_status status = AE_OK;
 	acpi_size length;
 
@@ -584,7 +584,7 @@ acpi_status acpi_ex_opcode_2A_0T_1R(stru
 	 * Default is FALSE (zero)
 	 */
 	if (logical_result) {
-		return_desc->integer.value = ACPI_INTEGER_MAX;
+		return_desc->integer.value = ACPI_UINT64_MAX;
 	}
 
       cleanup:
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exoparg3.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exoparg3.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exoparg3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exoparg3.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -148,7 +148,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(stru
 	union acpi_operand_object *return_desc = NULL;
 	char *buffer = NULL;
 	acpi_status status = AE_OK;
-	acpi_integer index;
+	u64 index;
 	acpi_size length;
 
 	ACPI_FUNCTION_TRACE_STR(ex_opcode_3A_1T_1R,
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exoparg6.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exoparg6.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exoparg6.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exoparg6.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -218,7 +218,7 @@ acpi_status acpi_ex_opcode_6A_0T_1R(stru
 	union acpi_operand_object **operand = &walk_state->operands[0];
 	union acpi_operand_object *return_desc = NULL;
 	acpi_status status = AE_OK;
-	acpi_integer index;
+	u64 index;
 	union acpi_operand_object *this_element;
 
 	ACPI_FUNCTION_TRACE_STR(ex_opcode_6A_0T_1R,
@@ -253,9 +253,9 @@ acpi_status acpi_ex_opcode_6A_0T_1R(stru
 		}
 
 		/* Create an integer for the return value */
-		/* Default return value is ACPI_INTEGER_MAX if no match found */
+		/* Default return value is ACPI_UINT64_MAX if no match found */
 
-		return_desc = acpi_ut_create_integer_object(ACPI_INTEGER_MAX);
+		return_desc = acpi_ut_create_integer_object(ACPI_UINT64_MAX);
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
@@ -270,7 +270,7 @@ acpi_status acpi_ex_opcode_6A_0T_1R(stru
 		 *
 		 * Upon finding a match, the loop will terminate via "break" at
 		 * the bottom.  If it terminates "normally", match_value will be
-		 * ACPI_INTEGER_MAX (Ones) (its initial value) indicating that no
+		 * ACPI_UINT64_MAX (Ones) (its initial value) indicating that no
 		 * match was found.
 		 */
 		for (; index < operand[0]->package.count; index++) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exprep.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exprep.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exprep.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exprep.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -468,6 +468,23 @@ acpi_status acpi_ex_prep_field_value(str
 
 		acpi_ut_add_reference(obj_desc->field.region_obj);
 
+		/* allow full data read from EC address space */
+		if (obj_desc->field.region_obj->region.space_id ==
+			ACPI_ADR_SPACE_EC) {
+			if (obj_desc->common_field.bit_length > 8) {
+				unsigned width =
+					ACPI_ROUND_BITS_UP_TO_BYTES(
+					obj_desc->common_field.bit_length);
+				// access_bit_width is u8, don't overflow it
+				if (width > 8)
+					width = 8;
+				obj_desc->common_field.access_byte_width =
+							width;
+				obj_desc->common_field.access_bit_width =
+							8 * width;
+			}
+		}
+
 		ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
 				  "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
 				  obj_desc->field.start_field_bit_offset,
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exregion.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exregion.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exregion.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exregion.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -70,7 +70,7 @@ acpi_status
 acpi_ex_system_memory_space_handler(u32 function,
 				    acpi_physical_address address,
 				    u32 bit_width,
-				    acpi_integer * value,
+				    u64 *value,
 				    void *handler_context, void *region_context)
 {
 	acpi_status status = AE_OK;
@@ -115,8 +115,7 @@ acpi_ex_system_memory_space_handler(u32
 	 * Hardware does not support non-aligned data transfers, we must verify
 	 * the request.
 	 */
-	(void)acpi_ut_short_divide((acpi_integer) address, length, NULL,
-				   &remainder);
+	(void)acpi_ut_short_divide((u64) address, length, NULL, &remainder);
 	if (remainder != 0) {
 		return_ACPI_STATUS(AE_AML_ALIGNMENT);
 	}
@@ -128,10 +127,9 @@ acpi_ex_system_memory_space_handler(u32
 	 *    2) Address beyond the current mapping?
 	 */
 	if ((address < mem_info->mapped_physical_address) ||
-	    (((acpi_integer) address + length) > ((acpi_integer)
-						  mem_info->
-						  mapped_physical_address +
-						  mem_info->mapped_length))) {
+	    (((u64) address + length) > ((u64)
+					 mem_info->mapped_physical_address +
+					 mem_info->mapped_length))) {
 		/*
 		 * The request cannot be resolved by the current memory mapping;
 		 * Delete the existing mapping and create a new one.
@@ -193,8 +191,7 @@ acpi_ex_system_memory_space_handler(u32
 	 * access
 	 */
 	logical_addr_ptr = mem_info->mapped_logical_address +
-	    ((acpi_integer) address -
-	     (acpi_integer) mem_info->mapped_physical_address);
+	    ((u64) address - (u64) mem_info->mapped_physical_address);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			  "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n",
@@ -215,19 +212,19 @@ acpi_ex_system_memory_space_handler(u32
 		*value = 0;
 		switch (bit_width) {
 		case 8:
-			*value = (acpi_integer) ACPI_GET8(logical_addr_ptr);
+			*value = (u64) ACPI_GET8(logical_addr_ptr);
 			break;
 
 		case 16:
-			*value = (acpi_integer) ACPI_GET16(logical_addr_ptr);
+			*value = (u64) ACPI_GET16(logical_addr_ptr);
 			break;
 
 		case 32:
-			*value = (acpi_integer) ACPI_GET32(logical_addr_ptr);
+			*value = (u64) ACPI_GET32(logical_addr_ptr);
 			break;
 
 		case 64:
-			*value = (acpi_integer) ACPI_GET64(logical_addr_ptr);
+			*value = (u64) ACPI_GET64(logical_addr_ptr);
 			break;
 
 		default:
@@ -291,7 +288,7 @@ acpi_status
 acpi_ex_system_io_space_handler(u32 function,
 				acpi_physical_address address,
 				u32 bit_width,
-				acpi_integer * value,
+				u64 *value,
 				void *handler_context, void *region_context)
 {
 	acpi_status status = AE_OK;
@@ -350,7 +347,7 @@ acpi_status
 acpi_ex_pci_config_space_handler(u32 function,
 				 acpi_physical_address address,
 				 u32 bit_width,
-				 acpi_integer * value,
+				 u64 *value,
 				 void *handler_context, void *region_context)
 {
 	acpi_status status = AE_OK;
@@ -425,7 +422,7 @@ acpi_status
 acpi_ex_cmos_space_handler(u32 function,
 			   acpi_physical_address address,
 			   u32 bit_width,
-			   acpi_integer * value,
+			   u64 *value,
 			   void *handler_context, void *region_context)
 {
 	acpi_status status = AE_OK;
@@ -457,7 +454,7 @@ acpi_status
 acpi_ex_pci_bar_space_handler(u32 function,
 			      acpi_physical_address address,
 			      u32 bit_width,
-			      acpi_integer * value,
+			      u64 *value,
 			      void *handler_context, void *region_context)
 {
 	acpi_status status = AE_OK;
@@ -489,7 +486,7 @@ acpi_status
 acpi_ex_data_table_space_handler(u32 function,
 				 acpi_physical_address address,
 				 u32 bit_width,
-				 acpi_integer * value,
+				 u64 *value,
 				 void *handler_context, void *region_context)
 {
 	ACPI_FUNCTION_TRACE(ex_data_table_space_handler);
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exresnte.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exresnte.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exresnte.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exresnte.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exresolv.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exresolv.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exresolv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exresolv.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exresop.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exresop.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exresop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exresop.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exstore.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exstore.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exstore.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exstore.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exstoren.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exstoren.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exstoren.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exstoren.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exstorob.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exstorob.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exstorob.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exstorob.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exsystem.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exsystem.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exsystem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exsystem.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -193,7 +193,7 @@ acpi_status acpi_ex_system_do_stall(u32
  *
  ******************************************************************************/
 
-acpi_status acpi_ex_system_do_suspend(acpi_integer how_long)
+acpi_status acpi_ex_system_do_suspend(u64 how_long)
 {
 	ACPI_FUNCTION_ENTRY();
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exutils.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exutils.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exutils.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/exutils.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -67,7 +67,7 @@
 ACPI_MODULE_NAME("exutils")
 
 /* Local prototypes */
-static u32 acpi_ex_digits_needed(acpi_integer value, u32 base);
+static u32 acpi_ex_digits_needed(u64 value, u32 base);
 
 #ifndef ACPI_NO_METHOD_EXECUTION
 /*******************************************************************************
@@ -230,7 +230,7 @@ void acpi_ex_truncate_for32bit_table(uni
 		 * We are running a method that exists in a 32-bit ACPI table.
 		 * Truncate the value to 32 bits by zeroing out the upper 32-bit field
 		 */
-		obj_desc->integer.value &= (acpi_integer) ACPI_UINT32_MAX;
+		obj_desc->integer.value &= (u64) ACPI_UINT32_MAX;
 	}
 }
 
@@ -327,14 +327,14 @@ void acpi_ex_release_global_lock(u32 fie
  *
  ******************************************************************************/
 
-static u32 acpi_ex_digits_needed(acpi_integer value, u32 base)
+static u32 acpi_ex_digits_needed(u64 value, u32 base)
 {
 	u32 num_digits;
-	acpi_integer current_value;
+	u64 current_value;
 
 	ACPI_FUNCTION_TRACE(ex_digits_needed);
 
-	/* acpi_integer is unsigned, so we don't worry about a '-' prefix */
+	/* u64 is unsigned, so we don't worry about a '-' prefix */
 
 	if (value == 0) {
 		return_UINT32(1);
@@ -370,7 +370,7 @@ static u32 acpi_ex_digits_needed(acpi_in
  *
  ******************************************************************************/
 
-void acpi_ex_eisa_id_to_string(char *out_string, acpi_integer compressed_id)
+void acpi_ex_eisa_id_to_string(char *out_string, u64 compressed_id)
 {
 	u32 swapped_id;
 
@@ -394,10 +394,10 @@ void acpi_ex_eisa_id_to_string(char *out
 	    (char)(0x40 + (((unsigned long)swapped_id >> 26) & 0x1F));
 	out_string[1] = (char)(0x40 + ((swapped_id >> 21) & 0x1F));
 	out_string[2] = (char)(0x40 + ((swapped_id >> 16) & 0x1F));
-	out_string[3] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 12);
-	out_string[4] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 8);
-	out_string[5] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 4);
-	out_string[6] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 0);
+	out_string[3] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 12);
+	out_string[4] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 8);
+	out_string[5] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 4);
+	out_string[6] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 0);
 	out_string[7] = 0;
 }
 
@@ -418,7 +418,7 @@ void acpi_ex_eisa_id_to_string(char *out
  *
  ******************************************************************************/
 
-void acpi_ex_integer_to_string(char *out_string, acpi_integer value)
+void acpi_ex_integer_to_string(char *out_string, u64 value)
 {
 	u32 count;
 	u32 digits_needed;
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/hwacpi.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/hwacpi.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/hwacpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/hwacpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/hwgpe.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/hwgpe.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/hwgpe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/hwgpe.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -224,7 +224,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_e
 
 	status = acpi_hw_read(&in_byte, &gpe_register_info->status_address);
 	if (ACPI_FAILURE(status)) {
-		goto unlock_and_exit;
+		return (status);
 	}
 
 	if (register_bit & in_byte) {
@@ -234,9 +234,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_e
 	/* Set return value */
 
 	(*event_status) = local_event_status;
-
-      unlock_and_exit:
-	return (status);
+	return (AE_OK);
 }
 
 /******************************************************************************
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/hwregs.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/hwregs.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/hwregs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/hwregs.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/hwsleep.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/hwsleep.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/hwsleep.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/hwsleep.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/hwtimer.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/hwtimer.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/hwtimer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/hwtimer.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -140,7 +140,7 @@ acpi_get_timer_duration(u32 start_ticks,
 {
 	acpi_status status;
 	u32 delta_ticks;
-	acpi_integer quotient;
+	u64 quotient;
 
 	ACPI_FUNCTION_TRACE(acpi_get_timer_duration);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/hwvalid.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/hwvalid.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/hwvalid.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/hwvalid.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2009, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/hwxface.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/hwxface.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/hwxface.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/hwxface.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsaccess.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsaccess.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsaccess.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsaccess.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsalloc.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsalloc.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsalloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsalloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsdump.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsdump.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsdump.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsdump.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsdumpdv.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsdumpdv.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsdumpdv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsdumpdv.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nseval.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nseval.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nseval.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nseval.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsinit.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsinit.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsinit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsinit.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsload.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsload.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsload.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsload.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsnames.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsnames.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsnames.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsnames.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsobject.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsobject.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsobject.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsobject.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsparse.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsparse.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsparse.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsparse.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nspredef.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nspredef.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nspredef.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nspredef.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -231,6 +231,7 @@ acpi_ns_check_predefined_names(struct ac
 	 * Note: Package may have been newly created by call above.
 	 */
 	if ((*return_object_ptr)->common.type == ACPI_TYPE_PACKAGE) {
+		data->parent_package = *return_object_ptr;
 		status = acpi_ns_check_package(data, return_object_ptr);
 		if (ACPI_FAILURE(status)) {
 			goto exit;
@@ -710,6 +711,7 @@ acpi_ns_check_package_list(struct acpi_p
 	for (i = 0; i < count; i++) {
 		sub_package = *elements;
 		sub_elements = sub_package->package.elements;
+		data->parent_package = sub_package;
 
 		/* Each sub-object must be of type Package */
 
@@ -721,6 +723,7 @@ acpi_ns_check_package_list(struct acpi_p
 
 		/* Examine the different types of expected sub-packages */
 
+		data->parent_package = sub_package;
 		switch (package->ret_info.type) {
 		case ACPI_PTYPE2:
 		case ACPI_PTYPE2_PKG_COUNT:
@@ -800,7 +803,7 @@ acpi_ns_check_package_list(struct acpi_p
 
 			/*
 			 * First element is the (Integer) count of elements, including
-			 * the count field.
+			 * the count field (the ACPI name is num_elements)
 			 */
 			status = acpi_ns_check_object_type(data, sub_elements,
 							   ACPI_RTYPE_INTEGER,
@@ -822,6 +825,16 @@ acpi_ns_check_package_list(struct acpi_p
 				expected_count = package->ret_info.count1;
 				goto package_too_small;
 			}
+			if (expected_count == 0) {
+				/*
+				 * Either the num_entries element was originally zero or it was
+				 * a NULL element and repaired to an Integer of value zero.
+				 * In either case, repair it by setting num_entries to be the
+				 * actual size of the subpackage.
+				 */
+				expected_count = sub_package->package.count;
+				(*sub_elements)->integer.value = expected_count;
+			}
 
 			/* Check the type of each sub-package element */
 
@@ -945,10 +958,18 @@ acpi_ns_check_object_type(struct acpi_pr
 	char type_buffer[48];	/* Room for 5 types */
 
 	/*
-	 * If we get a NULL return_object here, it is a NULL package element,
-	 * and this is always an error.
+	 * If we get a NULL return_object here, it is a NULL package element.
+	 * Since all extraneous NULL package elements were removed earlier by a
+	 * call to acpi_ns_remove_null_elements, this is an unexpected NULL element.
+	 * We will attempt to repair it.
 	 */
 	if (!return_object) {
+		status = acpi_ns_repair_null_element(data, expected_btypes,
+						     package_index,
+						     return_object_ptr);
+		if (ACPI_SUCCESS(status)) {
+			return (AE_OK);	/* Repair was successful */
+		}
 		goto type_error_exit;
 	}
 
@@ -1000,27 +1021,25 @@ acpi_ns_check_object_type(struct acpi_pr
 
 	/* Is the object one of the expected types? */
 
-	if (!(return_btype & expected_btypes)) {
+	if (return_btype & expected_btypes) {
 
-		/* Type mismatch -- attempt repair of the returned object */
+		/* For reference objects, check that the reference type is correct */
 
-		status = acpi_ns_repair_object(data, expected_btypes,
-					       package_index,
-					       return_object_ptr);
-		if (ACPI_SUCCESS(status)) {
-			return (AE_OK);	/* Repair was successful */
+		if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
+			status = acpi_ns_check_reference(data, return_object);
 		}
-		goto type_error_exit;
+
+		return (status);
 	}
 
-	/* For reference objects, check that the reference type is correct */
+	/* Type mismatch -- attempt repair of the returned object */
 
-	if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
-		status = acpi_ns_check_reference(data, return_object);
+	status = acpi_ns_repair_object(data, expected_btypes,
+				       package_index, return_object_ptr);
+	if (ACPI_SUCCESS(status)) {
+		return (AE_OK);	/* Repair was successful */
 	}
 
-	return (status);
-
       type_error_exit:
 
 	/* Create a string with all expected types for this predefined object */
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsrepair2.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsrepair2.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsrepair2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsrepair2.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2009, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -45,7 +45,6 @@
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acnamesp.h"
-#include "acpredef.h"
 
 #define _COMPONENT          ACPI_NAMESPACE
 ACPI_MODULE_NAME("nsrepair2")
@@ -93,7 +92,7 @@ acpi_ns_check_sorted_list(struct acpi_pr
 			  u32 sort_index,
 			  u8 sort_direction, char *sort_key_name);
 
-static acpi_status
+static void
 acpi_ns_sort_list(union acpi_operand_object **elements,
 		  u32 count, u32 index, u8 sort_direction);
 
@@ -443,7 +442,6 @@ acpi_ns_check_sorted_list(struct acpi_pr
 	union acpi_operand_object *obj_desc;
 	u32 i;
 	u32 previous_value;
-	acpi_status status;
 
 	ACPI_FUNCTION_NAME(ns_check_sorted_list);
 
@@ -494,19 +492,15 @@ acpi_ns_check_sorted_list(struct acpi_pr
 
 		/*
 		 * The list must be sorted in the specified order. If we detect a
-		 * discrepancy, issue a warning and sort the entire list
+		 * discrepancy, sort the entire list.
 		 */
 		if (((sort_direction == ACPI_SORT_ASCENDING) &&
 		     (obj_desc->integer.value < previous_value)) ||
 		    ((sort_direction == ACPI_SORT_DESCENDING) &&
 		     (obj_desc->integer.value > previous_value))) {
-			status =
-			    acpi_ns_sort_list(return_object->package.elements,
-					      outer_element_count, sort_index,
-					      sort_direction);
-			if (ACPI_FAILURE(status)) {
-				return (status);
-			}
+			acpi_ns_sort_list(return_object->package.elements,
+					  outer_element_count, sort_index,
+					  sort_direction);
 
 			data->flags |= ACPI_OBJECT_REPAIRED;
 
@@ -525,89 +519,6 @@ acpi_ns_check_sorted_list(struct acpi_pr
 
 /******************************************************************************
  *
- * FUNCTION:    acpi_ns_remove_null_elements
- *
- * PARAMETERS:  Data                - Pointer to validation data structure
- *              package_type        - An acpi_return_package_types value
- *              obj_desc            - A Package object
- *
- * RETURN:      None.
- *
- * DESCRIPTION: Remove all NULL package elements from packages that contain
- *              a variable number of sub-packages.
- *
- *****************************************************************************/
-
-void
-acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
-			     u8 package_type,
-			     union acpi_operand_object *obj_desc)
-{
-	union acpi_operand_object **source;
-	union acpi_operand_object **dest;
-	u32 count;
-	u32 new_count;
-	u32 i;
-
-	ACPI_FUNCTION_NAME(ns_remove_null_elements);
-
-	/*
-	 * PTYPE1 packages contain no subpackages.
-	 * PTYPE2 packages contain a variable number of sub-packages. We can
-	 * safely remove all NULL elements from the PTYPE2 packages.
-	 */
-	switch (package_type) {
-	case ACPI_PTYPE1_FIXED:
-	case ACPI_PTYPE1_VAR:
-	case ACPI_PTYPE1_OPTION:
-		return;
-
-	case ACPI_PTYPE2:
-	case ACPI_PTYPE2_COUNT:
-	case ACPI_PTYPE2_PKG_COUNT:
-	case ACPI_PTYPE2_FIXED:
-	case ACPI_PTYPE2_MIN:
-	case ACPI_PTYPE2_REV_FIXED:
-		break;
-
-	default:
-		return;
-	}
-
-	count = obj_desc->package.count;
-	new_count = count;
-
-	source = obj_desc->package.elements;
-	dest = source;
-
-	/* Examine all elements of the package object, remove nulls */
-
-	for (i = 0; i < count; i++) {
-		if (!*source) {
-			new_count--;
-		} else {
-			*dest = *source;
-			dest++;
-		}
-		source++;
-	}
-
-	/* Update parent package if any null elements were removed */
-
-	if (new_count < count) {
-		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
-				  "%s: Found and removed %u NULL elements\n",
-				  data->pathname, (count - new_count)));
-
-		/* NULL terminate list and update the package count */
-
-		*dest = NULL;
-		obj_desc->package.count = new_count;
-	}
-}
-
-/******************************************************************************
- *
  * FUNCTION:    acpi_ns_sort_list
  *
  * PARAMETERS:  Elements            - Package object element list
@@ -615,15 +526,16 @@ acpi_ns_remove_null_elements(struct acpi
  *              Index               - Sort by which package element
  *              sort_direction      - Ascending or Descending sort
  *
- * RETURN:      Status
+ * RETURN:      None
  *
  * DESCRIPTION: Sort the objects that are in a package element list.
  *
- * NOTE: Assumes that all NULL elements have been removed from the package.
+ * NOTE: Assumes that all NULL elements have been removed from the package,
+ *       and that all elements have been verified to be of type Integer.
  *
  *****************************************************************************/
 
-static acpi_status
+static void
 acpi_ns_sort_list(union acpi_operand_object **elements,
 		  u32 count, u32 index, u8 sort_direction)
 {
@@ -652,6 +564,4 @@ acpi_ns_sort_list(union acpi_operand_obj
 			}
 		}
 	}
-
-	return (AE_OK);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsrepair.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsrepair.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsrepair.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsrepair.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2009, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,7 @@
 #include "accommon.h"
 #include "acnamesp.h"
 #include "acinterp.h"
+#include "acpredef.h"
 
 #define _COMPONENT          ACPI_NAMESPACE
 ACPI_MODULE_NAME("nsrepair")
@@ -71,6 +72,12 @@ ACPI_MODULE_NAME("nsrepair")
  * Buffer  -> Package of Integers
  * Package -> Package of one Package
  *
+ * Additional possible repairs:
+ *
+ * Optional/unnecessary NULL package elements removed
+ * Required package elements that are NULL replaced by Integer/String/Buffer
+ * Incorrect standalone package wrapped with required outer package
+ *
  ******************************************************************************/
 /* Local prototypes */
 static acpi_status
@@ -505,6 +512,172 @@ acpi_ns_convert_to_package(union acpi_op
 }
 
 /*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_repair_null_element
+ *
+ * PARAMETERS:  Data                - Pointer to validation data structure
+ *              expected_btypes     - Object types expected
+ *              package_index       - Index of object within parent package (if
+ *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
+ *                                    otherwise)
+ *              return_object_ptr   - Pointer to the object returned from the
+ *                                    evaluation of a method or object
+ *
+ * RETURN:      Status. AE_OK if repair was successful.
+ *
+ * DESCRIPTION: Attempt to repair a NULL element of a returned Package object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_repair_null_element(struct acpi_predefined_data *data,
+			    u32 expected_btypes,
+			    u32 package_index,
+			    union acpi_operand_object **return_object_ptr)
+{
+	union acpi_operand_object *return_object = *return_object_ptr;
+	union acpi_operand_object *new_object;
+
+	ACPI_FUNCTION_NAME(ns_repair_null_element);
+
+	/* No repair needed if return object is non-NULL */
+
+	if (return_object) {
+		return (AE_OK);
+	}
+
+	/*
+	 * Attempt to repair a NULL element of a Package object. This applies to
+	 * predefined names that return a fixed-length package and each element
+	 * is required. It does not apply to variable-length packages where NULL
+	 * elements are allowed, especially at the end of the package.
+	 */
+	if (expected_btypes & ACPI_RTYPE_INTEGER) {
+
+		/* Need an Integer - create a zero-value integer */
+
+		new_object = acpi_ut_create_integer_object(0);
+	} else if (expected_btypes & ACPI_RTYPE_STRING) {
+
+		/* Need a String - create a NULL string */
+
+		new_object = acpi_ut_create_string_object(0);
+	} else if (expected_btypes & ACPI_RTYPE_BUFFER) {
+
+		/* Need a Buffer - create a zero-length buffer */
+
+		new_object = acpi_ut_create_buffer_object(0);
+	} else {
+		/* Error for all other expected types */
+
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+	if (!new_object) {
+		return (AE_NO_MEMORY);
+	}
+
+	/* Set the reference count according to the parent Package object */
+
+	new_object->common.reference_count =
+	    data->parent_package->common.reference_count;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
+			  "%s: Converted NULL package element to expected %s at index %u\n",
+			  data->pathname,
+			  acpi_ut_get_object_type_name(new_object),
+			  package_index));
+
+	*return_object_ptr = new_object;
+	data->flags |= ACPI_OBJECT_REPAIRED;
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_remove_null_elements
+ *
+ * PARAMETERS:  Data                - Pointer to validation data structure
+ *              package_type        - An acpi_return_package_types value
+ *              obj_desc            - A Package object
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Remove all NULL package elements from packages that contain
+ *              a variable number of sub-packages. For these types of
+ *              packages, NULL elements can be safely removed.
+ *
+ *****************************************************************************/
+
+void
+acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
+			     u8 package_type,
+			     union acpi_operand_object *obj_desc)
+{
+	union acpi_operand_object **source;
+	union acpi_operand_object **dest;
+	u32 count;
+	u32 new_count;
+	u32 i;
+
+	ACPI_FUNCTION_NAME(ns_remove_null_elements);
+
+	/*
+	 * PTYPE1 packages contain no subpackages.
+	 * PTYPE2 packages contain a variable number of sub-packages. We can
+	 * safely remove all NULL elements from the PTYPE2 packages.
+	 */
+	switch (package_type) {
+	case ACPI_PTYPE1_FIXED:
+	case ACPI_PTYPE1_VAR:
+	case ACPI_PTYPE1_OPTION:
+		return;
+
+	case ACPI_PTYPE2:
+	case ACPI_PTYPE2_COUNT:
+	case ACPI_PTYPE2_PKG_COUNT:
+	case ACPI_PTYPE2_FIXED:
+	case ACPI_PTYPE2_MIN:
+	case ACPI_PTYPE2_REV_FIXED:
+		break;
+
+	default:
+		return;
+	}
+
+	count = obj_desc->package.count;
+	new_count = count;
+
+	source = obj_desc->package.elements;
+	dest = source;
+
+	/* Examine all elements of the package object, remove nulls */
+
+	for (i = 0; i < count; i++) {
+		if (!*source) {
+			new_count--;
+		} else {
+			*dest = *source;
+			dest++;
+		}
+		source++;
+	}
+
+	/* Update parent package if any null elements were removed */
+
+	if (new_count < count) {
+		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
+				  "%s: Found and removed %u NULL elements\n",
+				  data->pathname, (count - new_count)));
+
+		/* NULL terminate list and update the package count */
+
+		*dest = NULL;
+		obj_desc->package.count = new_count;
+	}
+}
+
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ns_repair_package_list
  *
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nssearch.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nssearch.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nssearch.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nssearch.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsutils.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsutils.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsutils.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsutils.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nswalk.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nswalk.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nswalk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nswalk.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsxfeval.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsxfeval.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsxfeval.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsxfeval.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -562,25 +562,20 @@ acpi_ns_get_device_callback(acpi_handle
 		return (AE_BAD_PARAMETER);
 	}
 
-	/* Run _STA to determine if device is present */
-
-	status = acpi_ut_execute_STA(node, &flags);
-	if (ACPI_FAILURE(status)) {
-		return (AE_CTRL_DEPTH);
-	}
-
-	if (!(flags & ACPI_STA_DEVICE_PRESENT) &&
-	    !(flags & ACPI_STA_DEVICE_FUNCTIONING)) {
-		/*
-		 * Don't examine the children of the device only when the
-		 * device is neither present nor functional. See ACPI spec,
-		 * description of _STA for more information.
-		 */
-		return (AE_CTRL_DEPTH);
-	}
-
-	/* Filter based on device HID & CID */
-
+	/*
+	 * First, filter based on the device HID and CID.
+	 *
+	 * 01/2010: For this case where a specific HID is requested, we don't
+	 * want to run _STA until we have an actual HID match. Thus, we will
+	 * not unnecessarily execute _STA on devices for which the caller
+	 * doesn't care about. Previously, _STA was executed unconditionally
+	 * on all devices found here.
+	 *
+	 * A side-effect of this change is that now we will continue to search
+	 * for a matching HID even under device trees where the parent device
+	 * would have returned a _STA that indicates it is not present or
+	 * not functioning (thus aborting the search on that branch).
+	 */
 	if (info->hid != NULL) {
 		status = acpi_ut_execute_HID(node, &hid);
 		if (status == AE_NOT_FOUND) {
@@ -620,6 +615,25 @@ acpi_ns_get_device_callback(acpi_handle
 		}
 	}
 
+	/* Run _STA to determine if device is present */
+
+	status = acpi_ut_execute_STA(node, &flags);
+	if (ACPI_FAILURE(status)) {
+		return (AE_CTRL_DEPTH);
+	}
+
+	if (!(flags & ACPI_STA_DEVICE_PRESENT) &&
+	    !(flags & ACPI_STA_DEVICE_FUNCTIONING)) {
+		/*
+		 * Don't examine the children of the device only when the
+		 * device is neither present nor functional. See ACPI spec,
+		 * description of _STA for more information.
+		 */
+		return (AE_CTRL_DEPTH);
+	}
+
+	/* We have a valid device, invoke the user function */
+
 	status = info->user_function(obj_handle, nesting_level, info->context,
 				     return_value);
 	return (status);
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsxfname.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsxfname.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsxfname.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsxfname.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsxfobj.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsxfobj.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsxfobj.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/nsxfobj.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psargs.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/psargs.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psargs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/psargs.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -403,7 +403,7 @@ acpi_ps_get_next_simple_arg(struct acpi_
 		/* Get 1 byte from the AML stream */
 
 		opcode = AML_BYTE_OP;
-		arg->common.value.integer = (acpi_integer) * aml;
+		arg->common.value.integer = (u64) *aml;
 		length = 1;
 		break;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psloop.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/psloop.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psloop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/psloop.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psopcode.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/psopcode.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psopcode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/psopcode.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psparse.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/psparse.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psparse.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/psparse.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psscope.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/psscope.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psscope.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/psscope.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/pstree.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/pstree.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/pstree.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/pstree.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psutils.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/psutils.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psutils.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/psutils.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/pswalk.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/pswalk.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/pswalk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/pswalk.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psxface.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/psxface.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psxface.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/psxface.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsaddr.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsaddr.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsaddr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsaddr.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rscalc.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rscalc.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rscalc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rscalc.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rscreate.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rscreate.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rscreate.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rscreate.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -182,7 +182,7 @@ acpi_rs_create_pci_routing_table(union a
 
 	/*
 	 * Loop through the ACPI_INTERNAL_OBJECTS - Each object should be a
-	 * package that in turn contains an acpi_integer Address, a u8 Pin,
+	 * package that in turn contains an u64 Address, a u8 Pin,
 	 * a Name, and a u8 source_index.
 	 */
 	top_object_list = package_object->package.elements;
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsdump.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsdump.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsdump.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsdump.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsinfo.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsinfo.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsinfo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsinfo.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsio.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsio.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsio.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsirq.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsirq.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsirq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsirq.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rslist.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rslist.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rslist.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rslist.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsmemory.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsmemory.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsmemory.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsmemory.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsmisc.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsmisc.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsmisc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsmisc.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsutils.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsutils.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsutils.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsutils.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsxface.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsxface.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsxface.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/rsxface.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/tbfadt.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/tbfadt.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/tbfadt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/tbfadt.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/tbfind.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/tbfind.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/tbfind.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/tbfind.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/tbinstal.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/tbinstal.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/tbinstal.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/tbinstal.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/tbutils.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/tbutils.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/tbutils.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/tbutils.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/tbxface.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/tbxface.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/tbxface.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/tbxface.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/tbxfroot.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/tbxfroot.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/tbxfroot.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/tbxfroot.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utalloc.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utalloc.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utalloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utalloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utcopy.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utcopy.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utcopy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utcopy.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utdebug.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utdebug.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utdebug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utdebug.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -460,8 +460,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_status_exit)
 void
 acpi_ut_value_exit(u32 line_number,
 		   const char *function_name,
-		   const char *module_name,
-		   u32 component_id, acpi_integer value)
+		   const char *module_name, u32 component_id, u64 value)
 {
 
 	acpi_debug_print(ACPI_LV_FUNCTIONS,
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utdelete.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utdelete.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utdelete.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utdelete.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/uteval.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/uteval.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/uteval.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/uteval.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -348,7 +348,7 @@ acpi_ut_evaluate_object(struct acpi_name
 acpi_status
 acpi_ut_evaluate_numeric_object(char *object_name,
 				struct acpi_namespace_node *device_node,
-				acpi_integer *value)
+				u64 *value)
 {
 	union acpi_operand_object *obj_desc;
 	acpi_status status;
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utglobal.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utglobal.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utglobal.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utglobal.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -234,7 +234,7 @@ static const char acpi_gbl_hex_to_ascii[
  *
  ******************************************************************************/
 
-char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position)
+char acpi_ut_hex_to_ascii_char(u64 integer, u32 position)
 {
 
 	return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]);
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utids.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utids.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utids.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utids.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2009, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utinit.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utinit.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utinit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utinit.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utlock.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utlock.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utlock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utlock.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2009, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utmath.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utmath.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utmath.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utmath.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -70,9 +70,8 @@ ACPI_MODULE_NAME("utmath")
  *
  ******************************************************************************/
 acpi_status
-acpi_ut_short_divide(acpi_integer dividend,
-		     u32 divisor,
-		     acpi_integer * out_quotient, u32 * out_remainder)
+acpi_ut_short_divide(u64 dividend,
+		     u32 divisor, u64 *out_quotient, u32 *out_remainder)
 {
 	union uint64_overlay dividend_ovl;
 	union uint64_overlay quotient;
@@ -126,9 +125,8 @@ acpi_ut_short_divide(acpi_integer divide
  ******************************************************************************/
 
 acpi_status
-acpi_ut_divide(acpi_integer in_dividend,
-	       acpi_integer in_divisor,
-	       acpi_integer * out_quotient, acpi_integer * out_remainder)
+acpi_ut_divide(u64 in_dividend,
+	       u64 in_divisor, u64 *out_quotient, u64 *out_remainder)
 {
 	union uint64_overlay dividend;
 	union uint64_overlay divisor;
@@ -199,9 +197,8 @@ acpi_ut_divide(acpi_integer in_dividend,
 		 * The 64-bit remainder must be generated.
 		 */
 		partial1 = quotient.part.lo * divisor.part.hi;
-		partial2.full =
-		    (acpi_integer) quotient.part.lo * divisor.part.lo;
-		partial3.full = (acpi_integer) partial2.part.hi + partial1;
+		partial2.full = (u64) quotient.part.lo * divisor.part.lo;
+		partial3.full = (u64) partial2.part.hi + partial1;
 
 		remainder.part.hi = partial3.part.lo;
 		remainder.part.lo = partial2.part.lo;
@@ -257,9 +254,8 @@ acpi_ut_divide(acpi_integer in_dividend,
  *
  ******************************************************************************/
 acpi_status
-acpi_ut_short_divide(acpi_integer in_dividend,
-		     u32 divisor,
-		     acpi_integer * out_quotient, u32 * out_remainder)
+acpi_ut_short_divide(u64 in_dividend,
+		     u32 divisor, u64 *out_quotient, u32 *out_remainder)
 {
 
 	ACPI_FUNCTION_TRACE(ut_short_divide);
@@ -284,9 +280,8 @@ acpi_ut_short_divide(acpi_integer in_div
 }
 
 acpi_status
-acpi_ut_divide(acpi_integer in_dividend,
-	       acpi_integer in_divisor,
-	       acpi_integer * out_quotient, acpi_integer * out_remainder)
+acpi_ut_divide(u64 in_dividend,
+	       u64 in_divisor, u64 *out_quotient, u64 *out_remainder)
 {
 	ACPI_FUNCTION_TRACE(ut_divide);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utmisc.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utmisc.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utmisc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utmisc.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -724,13 +724,12 @@ acpi_name acpi_ut_repair_name(char *name
  *
  ******************************************************************************/
 
-acpi_status
-acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
+acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer)
 {
 	u32 this_digit = 0;
-	acpi_integer return_value = 0;
-	acpi_integer quotient;
-	acpi_integer dividend;
+	u64 return_value = 0;
+	u64 quotient;
+	u64 dividend;
 	u32 to_integer_op = (base == ACPI_ANY_BASE);
 	u32 mode32 = (acpi_gbl_integer_byte_width == 4);
 	u8 valid_digits = 0;
@@ -844,9 +843,8 @@ acpi_ut_strtoul64(char *string, u32 base
 
 		/* Divide the digit into the correct position */
 
-		(void)
-		    acpi_ut_short_divide((dividend - (acpi_integer) this_digit),
-					 base, &quotient, NULL);
+		(void)acpi_ut_short_divide((dividend - (u64) this_digit),
+					   base, &quotient, NULL);
 
 		if (return_value > quotient) {
 			if (to_integer_op) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utmutex.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utmutex.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utmutex.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utmutex.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -50,7 +50,7 @@ ACPI_MODULE_NAME("utmutex")
 /* Local prototypes */
 static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id);
 
-static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id);
+static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id);
 
 /*******************************************************************************
  *
@@ -114,7 +114,7 @@ void acpi_ut_mutex_terminate(void)
 	/* Delete each predefined mutex object */
 
 	for (i = 0; i < ACPI_NUM_MUTEX; i++) {
-		(void)acpi_ut_delete_mutex(i);
+		acpi_ut_delete_mutex(i);
 	}
 
 	/* Delete the spinlocks */
@@ -146,10 +146,6 @@ static acpi_status acpi_ut_create_mutex(
 
 	ACPI_FUNCTION_TRACE_U32(ut_create_mutex, mutex_id);
 
-	if (mutex_id > ACPI_MAX_MUTEX) {
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
-	}
-
 	if (!acpi_gbl_mutex_info[mutex_id].mutex) {
 		status =
 		    acpi_os_create_mutex(&acpi_gbl_mutex_info[mutex_id].mutex);
@@ -173,21 +169,15 @@ static acpi_status acpi_ut_create_mutex(
  *
  ******************************************************************************/
 
-static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id)
+static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id)
 {
 
 	ACPI_FUNCTION_TRACE_U32(ut_delete_mutex, mutex_id);
 
-	if (mutex_id > ACPI_MAX_MUTEX) {
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
-	}
-
 	acpi_os_delete_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
 
 	acpi_gbl_mutex_info[mutex_id].mutex = NULL;
 	acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
-
-	return_ACPI_STATUS(AE_OK);
 }
 
 /*******************************************************************************
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utobject.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utobject.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utobject.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utobject.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utresrc.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utresrc.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utresrc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utresrc.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utstate.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utstate.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utstate.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utstate.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utxface.c linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utxface.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utxface.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpica/utxface.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2010, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpi_memhotplug.c linux-libre-2.6.34-gnu1/drivers/acpi/acpi_memhotplug.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpi_memhotplug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpi_memhotplug.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/memory_hotplug.h>
+#include <linux/slab.h>
 #include <acpi/acpi_drivers.h>
 
 #define ACPI_MEMORY_DEVICE_CLASS		"memory"
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/acpi_pad.c linux-libre-2.6.34-gnu1/drivers/acpi/acpi_pad.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/acpi_pad.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/acpi_pad.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,10 +27,11 @@
 #include <linux/freezer.h>
 #include <linux/cpu.h>
 #include <linux/clockchips.h>
+#include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
-#define ACPI_PROCESSOR_AGGREGATOR_CLASS	"processor_aggregator"
+#define ACPI_PROCESSOR_AGGREGATOR_CLASS	"acpi_pad"
 #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator"
 #define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80
 static DEFINE_MUTEX(isolated_cpus_lock);
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/battery.c linux-libre-2.6.34-gnu1/drivers/acpi/battery.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/battery.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/battery.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/jiffies.h>
 #include <linux/async.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_ACPI_PROCFS_POWER
 #include <linux/proc_fs.h>
@@ -54,6 +55,7 @@
 #define ACPI_BATTERY_DEVICE_NAME	"Battery"
 #define ACPI_BATTERY_NOTIFY_STATUS	0x80
 #define ACPI_BATTERY_NOTIFY_INFO	0x81
+#define ACPI_BATTERY_NOTIFY_THRESHOLD   0x82
 
 #define _COMPONENT		ACPI_BATTERY_COMPONENT
 
@@ -88,10 +90,15 @@ static const struct acpi_device_id batte
 
 MODULE_DEVICE_TABLE(acpi, battery_device_ids);
 
-/* For buggy DSDTs that report negative 16-bit values for either charging
- * or discharging current and/or report 0 as 65536 due to bad math.
- */
-#define QUIRK_SIGNED16_CURRENT 0x0001
+enum {
+	ACPI_BATTERY_ALARM_PRESENT,
+	ACPI_BATTERY_XINFO_PRESENT,
+	/* For buggy DSDTs that report negative 16-bit values for either
+	 * charging or discharging current and/or report 0 as 65536
+	 * due to bad math.
+	 */
+	ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
+};
 
 struct acpi_battery {
 	struct mutex lock;
@@ -109,6 +116,12 @@ struct acpi_battery {
 	int design_voltage;
 	int design_capacity_warning;
 	int design_capacity_low;
+	int cycle_count;
+	int measurement_accuracy;
+	int max_sampling_time;
+	int min_sampling_time;
+	int max_averaging_interval;
+	int min_averaging_interval;
 	int capacity_granularity_1;
 	int capacity_granularity_2;
 	int alarm;
@@ -118,8 +131,7 @@ struct acpi_battery {
 	char oem_info[32];
 	int state;
 	int power_unit;
-	u8 alarm_present;
-	long quirks;
+	unsigned long flags;
 };
 
 #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
@@ -198,6 +210,9 @@ static int acpi_battery_get_property(str
 	case POWER_SUPPLY_PROP_TECHNOLOGY:
 		val->intval = acpi_battery_technology(battery);
 		break;
+	case POWER_SUPPLY_PROP_CYCLE_COUNT:
+		val->intval = battery->cycle_count;
+		break;
 	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
 		val->intval = battery->design_voltage * 1000;
 		break;
@@ -239,6 +254,7 @@ static enum power_supply_property charge
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_CYCLE_COUNT,
 	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
@@ -254,6 +270,7 @@ static enum power_supply_property energy
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_CYCLE_COUNT,
 	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
@@ -305,6 +322,28 @@ static struct acpi_offsets info_offsets[
 	{offsetof(struct acpi_battery, oem_info), 1},
 };
 
+static struct acpi_offsets extended_info_offsets[] = {
+	{offsetof(struct acpi_battery, power_unit), 0},
+	{offsetof(struct acpi_battery, design_capacity), 0},
+	{offsetof(struct acpi_battery, full_charge_capacity), 0},
+	{offsetof(struct acpi_battery, technology), 0},
+	{offsetof(struct acpi_battery, design_voltage), 0},
+	{offsetof(struct acpi_battery, design_capacity_warning), 0},
+	{offsetof(struct acpi_battery, design_capacity_low), 0},
+	{offsetof(struct acpi_battery, cycle_count), 0},
+	{offsetof(struct acpi_battery, measurement_accuracy), 0},
+	{offsetof(struct acpi_battery, max_sampling_time), 0},
+	{offsetof(struct acpi_battery, min_sampling_time), 0},
+	{offsetof(struct acpi_battery, max_averaging_interval), 0},
+	{offsetof(struct acpi_battery, min_averaging_interval), 0},
+	{offsetof(struct acpi_battery, capacity_granularity_1), 0},
+	{offsetof(struct acpi_battery, capacity_granularity_2), 0},
+	{offsetof(struct acpi_battery, model_number), 1},
+	{offsetof(struct acpi_battery, serial_number), 1},
+	{offsetof(struct acpi_battery, type), 1},
+	{offsetof(struct acpi_battery, oem_info), 1},
+};
+
 static int extract_package(struct acpi_battery *battery,
 			   union acpi_object *package,
 			   struct acpi_offsets *offsets, int num)
@@ -324,8 +363,8 @@ static int extract_package(struct acpi_b
 				strncpy(ptr, element->string.pointer, 32);
 			else if (element->type == ACPI_TYPE_INTEGER) {
 				strncpy(ptr, (u8 *)&element->integer.value,
-					sizeof(acpi_integer));
-				ptr[sizeof(acpi_integer)] = 0;
+					sizeof(u64));
+				ptr[sizeof(u64)] = 0;
 			} else
 				*ptr = 0; /* don't have value */
 		} else {
@@ -350,22 +389,29 @@ static int acpi_battery_get_info(struct
 {
 	int result = -EFAULT;
 	acpi_status status = 0;
+	char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)?
+			"_BIX" : "_BIF";
+
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
 	if (!acpi_battery_present(battery))
 		return 0;
 	mutex_lock(&battery->lock);
-	status = acpi_evaluate_object(battery->device->handle, "_BIF",
-				      NULL, &buffer);
+	status = acpi_evaluate_object(battery->device->handle, name,
+						NULL, &buffer);
 	mutex_unlock(&battery->lock);
 
 	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
+		ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name));
 		return -ENODEV;
 	}
-
-	result = extract_package(battery, buffer.pointer,
-				 info_offsets, ARRAY_SIZE(info_offsets));
+	if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags))
+		result = extract_package(battery, buffer.pointer,
+				extended_info_offsets,
+				ARRAY_SIZE(extended_info_offsets));
+	else
+		result = extract_package(battery, buffer.pointer,
+				info_offsets, ARRAY_SIZE(info_offsets));
 	kfree(buffer.pointer);
 	return result;
 }
@@ -399,7 +445,7 @@ static int acpi_battery_get_state(struct
 	battery->update_time = jiffies;
 	kfree(buffer.pointer);
 
-	if ((battery->quirks & QUIRK_SIGNED16_CURRENT) &&
+	if (test_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags) &&
 	    battery->rate_now != -1)
 		battery->rate_now = abs((s16)battery->rate_now);
 
@@ -412,7 +458,8 @@ static int acpi_battery_set_alarm(struct
 	union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
 	struct acpi_object_list arg_list = { 1, &arg0 };
 
-	if (!acpi_battery_present(battery)|| !battery->alarm_present)
+	if (!acpi_battery_present(battery) ||
+	    !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
 		return -ENODEV;
 
 	arg0.integer.value = battery->alarm;
@@ -437,10 +484,10 @@ static int acpi_battery_init_alarm(struc
 	/* See if alarms are supported, and if so, set default */
 	status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
 	if (ACPI_FAILURE(status)) {
-		battery->alarm_present = 0;
+		clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
 		return 0;
 	}
-	battery->alarm_present = 1;
+	set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
 	if (!battery->alarm)
 		battery->alarm = battery->design_capacity_warning;
 	return acpi_battery_set_alarm(battery);
@@ -510,9 +557,8 @@ static void sysfs_remove_battery(struct
 
 static void acpi_battery_quirks(struct acpi_battery *battery)
 {
-	battery->quirks = 0;
 	if (dmi_name_in_vendors("Acer") && battery->power_unit) {
-		battery->quirks |= QUIRK_SIGNED16_CURRENT;
+		set_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags);
 	}
 }
 
@@ -522,13 +568,13 @@ static int acpi_battery_update(struct ac
 	result = acpi_battery_get_status(battery);
 	if (result)
 		return result;
-#ifdef CONFIG_ACPI_SYSFS_POWER
 	if (!acpi_battery_present(battery)) {
+#ifdef CONFIG_ACPI_SYSFS_POWER
 		sysfs_remove_battery(battery);
+#endif
 		battery->update_time = 0;
 		return 0;
 	}
-#endif
 	if (!battery->update_time ||
 	    old_present != acpi_battery_present(battery)) {
 		result = acpi_battery_get_info(battery);
@@ -590,6 +636,7 @@ static int acpi_battery_print_info(struc
 	seq_printf(seq, "design capacity low:     %d %sh\n",
 		   battery->design_capacity_low,
 		   acpi_battery_units(battery));
+	seq_printf(seq, "cycle count:		  %i\n", battery->cycle_count);
 	seq_printf(seq, "capacity granularity 1:  %d %sh\n",
 		   battery->capacity_granularity_1,
 		   acpi_battery_units(battery));
@@ -833,7 +880,7 @@ static void acpi_battery_notify(struct a
 #ifdef CONFIG_ACPI_SYSFS_POWER
 	/* acpi_battery_update could remove power_supply object */
 	if (battery->bat.dev)
-		kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
+		power_supply_changed(&battery->bat);
 #endif
 }
 
@@ -841,6 +888,7 @@ static int acpi_battery_add(struct acpi_
 {
 	int result = 0;
 	struct acpi_battery *battery = NULL;
+	acpi_handle handle;
 	if (!device)
 		return -EINVAL;
 	battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
@@ -851,6 +899,9 @@ static int acpi_battery_add(struct acpi_
 	strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
 	device->driver_data = battery;
 	mutex_init(&battery->lock);
+	if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
+			"_BIX", &handle)))
+		set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
 	acpi_battery_update(battery);
 #ifdef CONFIG_ACPI_PROCFS_POWER
 	result = acpi_battery_add_fs(device);
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/bus.c linux-libre-2.6.34-gnu1/drivers/acpi/bus.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/bus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/bus.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/device.h>
 #include <linux/proc_fs.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #ifdef CONFIG_X86
 #include <asm/mpspec.h>
 #endif
@@ -190,16 +191,16 @@ int acpi_bus_get_power(acpi_handle handl
 		 * Get the device's power state either directly (via _PSC) or
 		 * indirectly (via power resources).
 		 */
-		if (device->power.flags.explicit_get) {
+		if (device->power.flags.power_resources) {
+			result = acpi_power_get_inferred_state(device);
+			if (result)
+				return result;
+		} else if (device->power.flags.explicit_get) {
 			status = acpi_evaluate_integer(device->handle, "_PSC",
 						       NULL, &psc);
 			if (ACPI_FAILURE(status))
 				return -ENODEV;
 			device->power.state = (int)psc;
-		} else if (device->power.flags.power_resources) {
-			result = acpi_power_get_inferred_state(device);
-			if (result)
-				return result;
 		}
 
 		*state = device->power.state;
@@ -526,7 +527,7 @@ int acpi_bus_generate_proc_event4(const
 	if (!event_is_open)
 		return 0;
 
-	event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
+	event = kzalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
 	if (!event)
 		return -ENOMEM;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/button.c linux-libre-2.6.34-gnu1/drivers/acpi/button.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/button.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/button.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -422,11 +423,10 @@ static int acpi_button_add(struct acpi_d
 
 	if (device->wakeup.flags.valid) {
 		/* Button's GPE is run-wake GPE */
-		acpi_set_gpe_type(device->wakeup.gpe_device,
-				  device->wakeup.gpe_number,
-				  ACPI_GPE_TYPE_WAKE_RUN);
 		acpi_enable_gpe(device->wakeup.gpe_device,
-				device->wakeup.gpe_number);
+				device->wakeup.gpe_number,
+				ACPI_GPE_TYPE_WAKE_RUN);
+		device->wakeup.run_wake_count++;
 		device->wakeup.state.enabled = 1;
 	}
 
@@ -446,6 +446,14 @@ static int acpi_button_remove(struct acp
 {
 	struct acpi_button *button = acpi_driver_data(device);
 
+	if (device->wakeup.flags.valid) {
+		acpi_disable_gpe(device->wakeup.gpe_device,
+				device->wakeup.gpe_number,
+				ACPI_GPE_TYPE_WAKE_RUN);
+		device->wakeup.run_wake_count--;
+		device->wakeup.state.enabled = 0;
+	}
+
 	acpi_button_remove_fs(device);
 	input_unregister_device(button->input);
 	kfree(button);
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/container.c linux-libre-2.6.34-gnu1/drivers/acpi/container.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/container.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/container.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/acpi.h>
 #include <acpi/acpi_bus.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/debug.c linux-libre-2.6.34-gnu1/drivers/acpi/debug.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/debug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/debug.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/moduleparam.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <acpi/acpi_drivers.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/dock.c linux-libre-2.6.34-gnu1/drivers/acpi/dock.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/dock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/dock.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/notifier.h>
@@ -605,7 +606,7 @@ register_hotplug_dock_device(acpi_handle
 	list_for_each_entry(dock_station, &dock_stations, sibling) {
 		/*
 		 * An ATA bay can be in a dock and itself can be ejected
-		 * seperately, so there are two 'dock stations' which need the
+		 * separately, so there are two 'dock stations' which need the
 		 * ops
 		 */
 		dd = find_dock_dependent_device(dock_station, handle);
@@ -1025,13 +1026,10 @@ static int dock_remove(struct dock_stati
 static acpi_status
 find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
-	acpi_status status = AE_OK;
-
 	if (is_dock(handle))
-		if (dock_add(handle) >= 0)
-			status = AE_CTRL_TERMINATE;
+		dock_add(handle);
 
-	return status;
+	return AE_OK;
 }
 
 static acpi_status
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/ec.c linux-libre-2.6.34-gnu1/drivers/acpi/ec.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/ec.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/ec.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
@@ -76,8 +77,9 @@ enum ec_command {
 enum {
 	EC_FLAGS_QUERY_PENDING,		/* Query is pending */
 	EC_FLAGS_GPE_STORM,		/* GPE storm detected */
-	EC_FLAGS_HANDLERS_INSTALLED	/* Handlers for GPE and
+	EC_FLAGS_HANDLERS_INSTALLED,	/* Handlers for GPE and
 					 * OpReg are installed */
+	EC_FLAGS_FROZEN,		/* Transactions are suspended */
 };
 
 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -291,6 +293,10 @@ static int acpi_ec_transaction(struct ac
 	if (t->rdata)
 		memset(t->rdata, 0, t->rlen);
 	mutex_lock(&ec->lock);
+	if (test_bit(EC_FLAGS_FROZEN, &ec->flags)) {
+		status = -EINVAL;
+		goto unlock;
+	}
 	if (ec->global_lock) {
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		if (ACPI_FAILURE(status)) {
@@ -307,7 +313,11 @@ static int acpi_ec_transaction(struct ac
 	pr_debug(PREFIX "transaction start\n");
 	/* disable GPE during transaction if storm is detected */
 	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
-		acpi_disable_gpe(NULL, ec->gpe);
+		/*
+		 * It has to be disabled at the hardware level regardless of the
+		 * GPE reference counting, so that it doesn't trigger.
+		 */
+		acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE);
 	}
 
 	status = acpi_ec_transaction_unlocked(ec, t);
@@ -316,8 +326,12 @@ static int acpi_ec_transaction(struct ac
 	ec_check_sci_sync(ec, acpi_ec_read_status(ec));
 	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
 		msleep(1);
-		/* it is safe to enable GPE outside of transaction */
-		acpi_enable_gpe(NULL, ec->gpe);
+		/*
+		 * It is safe to enable the GPE outside of the transaction.  Use
+		 * acpi_set_gpe() for that, since we used it to disable the GPE
+		 * above.
+		 */
+		acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE);
 	} else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
 		pr_info(PREFIX "GPE storm detected, "
 			"transactions will use polling mode\n");
@@ -445,6 +459,32 @@ int ec_transaction(u8 command,
 
 EXPORT_SYMBOL(ec_transaction);
 
+void acpi_ec_suspend_transactions(void)
+{
+	struct acpi_ec *ec = first_ec;
+
+	if (!ec)
+		return;
+
+	mutex_lock(&ec->lock);
+	/* Prevent transactions from being carried out */
+	set_bit(EC_FLAGS_FROZEN, &ec->flags);
+	mutex_unlock(&ec->lock);
+}
+
+void acpi_ec_resume_transactions(void)
+{
+	struct acpi_ec *ec = first_ec;
+
+	if (!ec)
+		return;
+
+	mutex_lock(&ec->lock);
+	/* Allow transactions to be carried out again */
+	clear_bit(EC_FLAGS_FROZEN, &ec->flags);
+	mutex_unlock(&ec->lock);
+}
+
 static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data)
 {
 	int result;
@@ -589,12 +629,12 @@ static u32 acpi_ec_gpe_handler(void *dat
 
 static acpi_status
 acpi_ec_space_handler(u32 function, acpi_physical_address address,
-		      u32 bits, acpi_integer *value,
+		      u32 bits, u64 *value64,
 		      void *handler_context, void *region_context)
 {
 	struct acpi_ec *ec = handler_context;
-	int result = 0, i;
-	u8 temp = 0;
+	int result = 0, i, bytes = bits / 8;
+	u8 *value = (u8 *)value64;
 
 	if ((address > 0xFF) || !value || !handler_context)
 		return AE_BAD_PARAMETER;
@@ -602,32 +642,15 @@ acpi_ec_space_handler(u32 function, acpi
 	if (function != ACPI_READ && function != ACPI_WRITE)
 		return AE_BAD_PARAMETER;
 
-	if (bits != 8 && acpi_strict)
-		return AE_BAD_PARAMETER;
-
-	if (EC_FLAGS_MSI)
+	if (EC_FLAGS_MSI || bits > 8)
 		acpi_ec_burst_enable(ec);
 
-	if (function == ACPI_READ) {
-		result = acpi_ec_read(ec, address, &temp);
-		*value = temp;
-	} else {
-		temp = 0xff & (*value);
-		result = acpi_ec_write(ec, address, temp);
-	}
-
-	for (i = 8; unlikely(bits - i > 0); i += 8) {
-		++address;
-		if (function == ACPI_READ) {
-			result = acpi_ec_read(ec, address, &temp);
-			(*value) |= ((acpi_integer)temp) << i;
-		} else {
-			temp = 0xff & ((*value) >> i);
-			result = acpi_ec_write(ec, address, temp);
-		}
-	}
+	for (i = 0; i < bytes; ++i, ++address, ++value)
+		result = (function == ACPI_READ) ?
+			acpi_ec_read(ec, address, value) :
+			acpi_ec_write(ec, address, *value);
 
-	if (EC_FLAGS_MSI)
+	if (EC_FLAGS_MSI || bits > 8)
 		acpi_ec_burst_disable(ec);
 
 	switch (result) {
@@ -788,8 +811,8 @@ static int ec_install_handlers(struct ac
 				  &acpi_ec_gpe_handler, ec);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
-	acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
-	acpi_enable_gpe(NULL, ec->gpe);
+
+	acpi_enable_gpe(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
 	status = acpi_install_address_space_handler(ec->handle,
 						    ACPI_ADR_SPACE_EC,
 						    &acpi_ec_space_handler,
@@ -806,6 +829,7 @@ static int ec_install_handlers(struct ac
 		} else {
 			acpi_remove_gpe_handler(NULL, ec->gpe,
 				&acpi_ec_gpe_handler);
+			acpi_disable_gpe(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
 			return -ENODEV;
 		}
 	}
@@ -816,6 +840,7 @@ static int ec_install_handlers(struct ac
 
 static void ec_remove_handlers(struct acpi_ec *ec)
 {
+	acpi_disable_gpe(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
 	if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
 				ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
 		pr_err(PREFIX "failed to remove space handler\n");
@@ -1057,16 +1082,16 @@ error:
 static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state)
 {
 	struct acpi_ec *ec = acpi_driver_data(device);
-	/* Stop using GPE */
-	acpi_disable_gpe(NULL, ec->gpe);
+	/* Stop using the GPE, but keep it reference counted. */
+	acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE);
 	return 0;
 }
 
 static int acpi_ec_resume(struct acpi_device *device)
 {
 	struct acpi_ec *ec = acpi_driver_data(device);
-	/* Enable use of GPE back */
-	acpi_enable_gpe(NULL, ec->gpe);
+	/* Enable the GPE again, but don't reference count it once more. */
+	acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/event.c linux-libre-2.6.34-gnu1/drivers/acpi/event.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/event.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/event.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/poll.h>
+#include <linux/gfp.h>
 #include <acpi/acpi_drivers.h>
 #include <net/netlink.h>
 #include <net/genetlink.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/glue.c linux-libre-2.6.34-gnu1/drivers/acpi/glue.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/glue.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/glue.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/rwsem.h>
 #include <linux/acpi.h>
 
@@ -87,7 +88,7 @@ static int acpi_find_bridge_device(struc
 /* Get device's handler per its address under its parent */
 struct acpi_find_child {
 	acpi_handle handle;
-	acpi_integer address;
+	u64 address;
 };
 
 static acpi_status
@@ -106,7 +107,7 @@ do_acpi_find_child(acpi_handle handle, u
 	return AE_OK;
 }
 
-acpi_handle acpi_get_child(acpi_handle parent, acpi_integer address)
+acpi_handle acpi_get_child(acpi_handle parent, u64 address)
 {
 	struct acpi_find_child find = { NULL, address };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/hest.c linux-libre-2.6.34-gnu1/drivers/acpi/hest.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/hest.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/hest.c	2010-05-16 17:17:36.000000000 -0400
@@ -123,6 +123,10 @@ int acpi_hest_firmware_first_pci(struct
 {
 	acpi_status status = AE_NOT_FOUND;
 	struct acpi_table_header *hest = NULL;
+
+	if (acpi_disabled)
+		return 0;
+
 	status = acpi_get_table(ACPI_SIG_HEST, 1, &hest);
 
 	if (ACPI_SUCCESS(status)) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/internal.h linux-libre-2.6.34-gnu1/drivers/acpi/internal.h
--- linux-libre-2.6.33-gnu1/drivers/acpi/internal.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/internal.h	2010-05-16 17:17:36.000000000 -0400
@@ -36,8 +36,6 @@ static inline int acpi_debug_init(void)
 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;
@@ -51,6 +49,8 @@ void acpi_early_processor_set_pdc(void);
 int acpi_ec_init(void);
 int acpi_ec_ecdt_probe(void);
 int acpi_boot_ec_enable(void);
+void acpi_ec_suspend_transactions(void);
+void acpi_ec_resume_transactions(void);
 
 /*--------------------------------------------------------------------------
                                   Suspend/Resume
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/Makefile linux-libre-2.6.34-gnu1/drivers/acpi/Makefile
--- linux-libre-2.6.33-gnu1/drivers/acpi/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,7 @@ acpi-$(CONFIG_ACPI_SLEEP)	+= proc.o
 #
 acpi-y				+= bus.o glue.o
 acpi-y				+= scan.o
-acpi-y				+= processor_pdc.o
+acpi-y				+= processor_core.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
@@ -61,7 +61,7 @@ obj-$(CONFIG_ACPI_SBS)		+= sbs.o
 obj-$(CONFIG_ACPI_POWER_METER)	+= power_meter.o
 
 # processor has its own "processor." module_param namespace
-processor-y			:= processor_core.o processor_throttling.o
+processor-y			:= processor_driver.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.33-gnu1/drivers/acpi/numa.c linux-libre-2.6.34-gnu1/drivers/acpi/numa.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/numa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/numa.c	2010-05-16 17:17:36.000000000 -0400
@@ -61,8 +61,10 @@ int node_to_pxm(int node)
 
 void __acpi_map_pxm_to_node(int pxm, int node)
 {
-	pxm_to_node_map[pxm] = node;
-	node_to_pxm_map[node] = pxm;
+	if (pxm_to_node_map[pxm] == NUMA_NO_NODE || node < pxm_to_node_map[pxm])
+		pxm_to_node_map[pxm] = node;
+	if (node_to_pxm_map[node] == PXM_INVAL || pxm < node_to_pxm_map[node])
+		node_to_pxm_map[node] = pxm;
 }
 
 int acpi_map_pxm_to_node(int pxm)
@@ -279,9 +281,9 @@ 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_parse_x2apic_affinity, nr_cpu_ids);
 		acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
-				      acpi_parse_processor_affinity, NR_CPUS);
+				     acpi_parse_processor_affinity, nr_cpu_ids);
 		ret = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
 					    acpi_parse_memory_affinity,
 					    NR_NODE_MEMBLKS);
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/osl.c linux-libre-2.6.34-gnu1/drivers/acpi/osl.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/osl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/osl.c	2010-05-16 17:17:36.000000000 -0400
@@ -436,7 +436,7 @@ acpi_status acpi_os_remove_interrupt_han
  * Running in interpreter thread context, safe to sleep
  */
 
-void acpi_os_sleep(acpi_integer ms)
+void acpi_os_sleep(u64 ms)
 {
 	schedule_timeout_interruptible(msecs_to_jiffies(ms));
 }
@@ -603,7 +603,7 @@ acpi_os_read_pci_configuration(struct ac
 
 acpi_status
 acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
-				acpi_integer value, u32 width)
+				u64 value, u32 width)
 {
 	int result, size;
 
@@ -758,7 +758,14 @@ static acpi_status __acpi_os_execute(acp
 	queue = hp ? kacpi_hotplug_wq :
 		(type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq);
 	dpc->wait = hp ? 1 : 0;
-	INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+
+	if (queue == kacpi_hotplug_wq)
+		INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+	else if (queue == kacpi_notify_wq)
+		INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+	else
+		INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+
 	ret = queue_work(queue, &dpc->work);
 
 	if (!ret) {
@@ -1151,16 +1158,10 @@ int acpi_check_resource_conflict(const s
 
 	if (clash) {
 		if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
-			printk("%sACPI: %s resource %s [0x%llx-0x%llx]"
-			       " conflicts with ACPI region %s"
-			       " [0x%llx-0x%llx]\n",
-			       acpi_enforce_resources == ENFORCE_RESOURCES_LAX
-			       ? KERN_WARNING : KERN_ERR,
-			       ioport ? "I/O" : "Memory", res->name,
-			       (long long) res->start, (long long) res->end,
-			       res_list_elem->name,
-			       (long long) res_list_elem->start,
-			       (long long) res_list_elem->end);
+			printk(KERN_WARNING "ACPI: resource %s %pR"
+			       " conflicts with ACPI region %s %pR\n",
+			       res->name, res, res_list_elem->name,
+			       res_list_elem);
 			if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX)
 				printk(KERN_NOTICE "ACPI: This conflict may"
 				       " cause random problems and system"
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/pci_bind.c linux-libre-2.6.34-gnu1/drivers/acpi/pci_bind.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/pci_bind.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/pci_bind.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,9 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/pci-acpi.h>
 #include <linux/acpi.h>
+#include <linux/pm_runtime.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -38,7 +40,13 @@ static int acpi_pci_unbind(struct acpi_d
 	struct pci_dev *dev;
 
 	dev = acpi_get_pci_dev(device->handle);
-	if (!dev || !dev->subordinate)
+	if (!dev)
+		goto out;
+
+	device_set_run_wake(&dev->dev, false);
+	pci_acpi_remove_pm_notifier(device);
+
+	if (!dev->subordinate)
 		goto out;
 
 	acpi_pci_irq_del_prt(dev->subordinate);
@@ -62,6 +70,10 @@ static int acpi_pci_bind(struct acpi_dev
 	if (!dev)
 		return 0;
 
+	pci_acpi_add_pm_notifier(device, dev);
+	if (device->wakeup.flags.run_wake)
+		device_set_run_wake(&dev->dev, true);
+
 	/*
 	 * Install the 'bind' function to facilitate callbacks for
 	 * children of the P2P bridge.
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/pci_irq.c linux-libre-2.6.34-gnu1/drivers/acpi/pci_irq.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/pci_irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/pci_irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/pm.h>
 #include <linux/pci.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/pci_link.c linux-libre-2.6.34-gnu1/drivers/acpi/pci_link.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/pci_link.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/pci_link.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/pm.h>
 #include <linux/pci.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/pci_root.c linux-libre-2.6.34-gnu1/drivers/acpi/pci_root.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/pci_root.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/pci_root.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,9 +30,11 @@
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
 #include <linux/pm.h>
+#include <linux/pm_runtime.h>
 #include <linux/pci.h>
 #include <linux/pci-acpi.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -528,6 +530,10 @@ static int __devinit acpi_pci_root_add(s
 	if (flags != base_flags)
 		acpi_pci_osc_support(root, flags);
 
+	pci_acpi_add_bus_pm_notifier(device, root->bus);
+	if (device->wakeup.flags.run_wake)
+		device_set_run_wake(root->bus->bridge, true);
+
 	return 0;
 
 end:
@@ -549,6 +555,9 @@ static int acpi_pci_root_remove(struct a
 {
 	struct acpi_pci_root *root = acpi_driver_data(device);
 
+	device_set_run_wake(root->bus->bridge, false);
+	pci_acpi_remove_bus_pm_notifier(device);
+
 	kfree(root);
 	return 0;
 }
@@ -558,6 +567,7 @@ static int __init acpi_pci_root_init(voi
 	if (acpi_pci_disabled)
 		return 0;
 
+	pci_acpi_crs_quirks();
 	if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0)
 		return -ENODEV;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/pci_slot.c linux-libre-2.6.34-gnu1/drivers/acpi/pci_slot.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/pci_slot.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/pci_slot.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/acpi.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/power.c linux-libre-2.6.34-gnu1/drivers/acpi/power.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/power.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/power.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <acpi/acpi_bus.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/power_meter.c linux-libre-2.6.34-gnu1/drivers/acpi/power_meter.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/power_meter.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/power_meter.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/jiffies.h>
 #include <linux/mutex.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 #include <linux/kdev_t.h>
 #include <linux/sched.h>
 #include <linux/time.h>
@@ -34,7 +35,7 @@
 #define ACPI_POWER_METER_NAME		"power_meter"
 ACPI_MODULE_NAME(ACPI_POWER_METER_NAME);
 #define ACPI_POWER_METER_DEVICE_NAME	"Power Meter"
-#define ACPI_POWER_METER_CLASS		"power_meter_resource"
+#define ACPI_POWER_METER_CLASS		"pwr_meter_resource"
 
 #define NUM_SENSORS			17
 
@@ -71,17 +72,17 @@ static const struct acpi_device_id power
 MODULE_DEVICE_TABLE(acpi, power_meter_ids);
 
 struct acpi_power_meter_capabilities {
-	acpi_integer		flags;
-	acpi_integer		units;
-	acpi_integer		type;
-	acpi_integer		accuracy;
-	acpi_integer		sampling_time;
-	acpi_integer		min_avg_interval;
-	acpi_integer		max_avg_interval;
-	acpi_integer		hysteresis;
-	acpi_integer		configurable_cap;
-	acpi_integer		min_cap;
-	acpi_integer		max_cap;
+	u64		flags;
+	u64		units;
+	u64		type;
+	u64		accuracy;
+	u64		sampling_time;
+	u64		min_avg_interval;
+	u64		max_avg_interval;
+	u64		hysteresis;
+	u64		configurable_cap;
+	u64		min_cap;
+	u64		max_cap;
 };
 
 struct acpi_power_meter_resource {
@@ -93,9 +94,9 @@ struct acpi_power_meter_resource {
 	acpi_string		model_number;
 	acpi_string		serial_number;
 	acpi_string		oem_info;
-	acpi_integer		power;
-	acpi_integer		cap;
-	acpi_integer		avg_interval;
+	u64		power;
+	u64		cap;
+	u64		avg_interval;
 	int			sensors_valid;
 	unsigned long		sensors_last_updated;
 	struct sensor_device_attribute	sensors[NUM_SENSORS];
@@ -402,7 +403,7 @@ static ssize_t show_val(struct device *d
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct acpi_device *acpi_dev = to_acpi_device(dev);
 	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
-	acpi_integer val = 0;
+	u64 val = 0;
 
 	switch (attr->index) {
 	case 0:
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/proc.c linux-libre-2.6.34-gnu1/drivers/acpi/proc.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -435,7 +435,7 @@ acpi_system_write_wakeup_device(struct f
 				found_dev->wakeup.gpe_device)) {
 				printk(KERN_WARNING
 				       "ACPI: '%s' and '%s' have the same GPE, "
-				       "can't disable/enable one seperately\n",
+				       "can't disable/enable one separately\n",
 				       dev->pnp.bus_id, found_dev->pnp.bus_id);
 				dev->wakeup.state.enabled =
 				    found_dev->wakeup.state.enabled;
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/processor_core.c linux-libre-2.6.34-gnu1/drivers/acpi/processor_core.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/processor_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/processor_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,381 +1,63 @@
 /*
- * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $)
- *
- *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
- *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
- *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
- *  			- Added processor hotplug support
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or (at
- *  your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ * Copyright (C) 2005 Intel Corporation
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
  *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *  TBD:
- *	1. Make # power states dynamic.
- *	2. Support duty_cycle values that span bit 4.
- *	3. Optimize by having scheduler determine business instead of
- *	   having us try to calculate it here.
- *	4. Need C1 timing -- must modify kernel (IRQ handler) to get this.
+ *	Alex Chiang <achiang@hp.com>
+ *	- Unified x86/ia64 implementations
+ *	Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *	- Added _PDC for platforms with Intel CPUs
  */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pm.h>
-#include <linux/cpufreq.h>
-#include <linux/cpu.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
 #include <linux/dmi.h>
-#include <linux/moduleparam.h>
-#include <linux/cpuidle.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/cpu.h>
-#include <asm/delay.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
-#include <asm/smp.h>
-#include <asm/acpi.h>
+#include <linux/slab.h>
 
-#include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/processor.h>
 
-#define PREFIX "ACPI: "
-
-#define ACPI_PROCESSOR_CLASS		"processor"
-#define ACPI_PROCESSOR_DEVICE_NAME	"Processor"
-#define ACPI_PROCESSOR_FILE_INFO	"info"
-#define ACPI_PROCESSOR_FILE_THROTTLING	"throttling"
-#define ACPI_PROCESSOR_FILE_LIMIT	"limit"
-#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
-#define ACPI_PROCESSOR_NOTIFY_POWER	0x81
-#define ACPI_PROCESSOR_NOTIFY_THROTTLING	0x82
-
-#define ACPI_PROCESSOR_LIMIT_USER	0
-#define ACPI_PROCESSOR_LIMIT_THERMAL	1
+#include "internal.h"
 
+#define PREFIX			"ACPI: "
 #define _COMPONENT		ACPI_PROCESSOR_COMPONENT
 ACPI_MODULE_NAME("processor_core");
 
-MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_DESCRIPTION("ACPI Processor Driver");
-MODULE_LICENSE("GPL");
-
-static int acpi_processor_add(struct acpi_device *device);
-static int acpi_processor_remove(struct acpi_device *device, int type);
-#ifdef CONFIG_ACPI_PROCFS
-static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
-#endif
-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);
-
-
-static const struct acpi_device_id processor_device_ids[] = {
-	{ACPI_PROCESSOR_OBJECT_HID, 0},
-	{"ACPI0007", 0},
-	{"", 0},
-};
-MODULE_DEVICE_TABLE(acpi, processor_device_ids);
-
-static struct acpi_driver acpi_processor_driver = {
-	.name = "processor",
-	.class = ACPI_PROCESSOR_CLASS,
-	.ids = processor_device_ids,
-	.ops = {
-		.add = acpi_processor_add,
-		.remove = acpi_processor_remove,
-		.suspend = acpi_processor_suspend,
-		.resume = acpi_processor_resume,
-		.notify = acpi_processor_notify,
-		},
-};
-
-#define INSTALL_NOTIFY_HANDLER		1
-#define UNINSTALL_NOTIFY_HANDLER	2
-#ifdef CONFIG_ACPI_PROCFS
-static const struct file_operations acpi_processor_info_fops = {
-	.owner = THIS_MODULE,
-	.open = acpi_processor_info_open_fs,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-#endif
-
-DEFINE_PER_CPU(struct acpi_processor *, processors);
-struct acpi_processor_errata errata __read_mostly;
-
-/* --------------------------------------------------------------------------
-                                Errata Handling
-   -------------------------------------------------------------------------- */
-
-static int acpi_processor_errata_piix4(struct pci_dev *dev)
-{
-	u8 value1 = 0;
-	u8 value2 = 0;
-
-
-	if (!dev)
-		return -EINVAL;
-
-	/*
-	 * Note that 'dev' references the PIIX4 ACPI Controller.
-	 */
-
-	switch (dev->revision) {
-	case 0:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n"));
-		break;
-	case 1:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n"));
-		break;
-	case 2:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n"));
-		break;
-	case 3:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n"));
-		break;
-	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n"));
-		break;
-	}
-
-	switch (dev->revision) {
-
-	case 0:		/* PIIX4 A-step */
-	case 1:		/* PIIX4 B-step */
-		/*
-		 * See specification changes #13 ("Manual Throttle Duty Cycle")
-		 * and #14 ("Enabling and Disabling Manual Throttle"), plus
-		 * erratum #5 ("STPCLK# Deassertion Time") from the January
-		 * 2002 PIIX4 specification update.  Applies to only older
-		 * PIIX4 models.
-		 */
-		errata.piix4.throttle = 1;
-
-	case 2:		/* PIIX4E */
-	case 3:		/* PIIX4M */
-		/*
-		 * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA
-		 * Livelock") from the January 2002 PIIX4 specification update.
-		 * Applies to all PIIX4 models.
-		 */
-
-		/*
-		 * BM-IDE
-		 * ------
-		 * Find the PIIX4 IDE Controller and get the Bus Master IDE
-		 * Status register address.  We'll use this later to read
-		 * each IDE controller's DMA status to make sure we catch all
-		 * DMA activity.
-		 */
-		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
-				     PCI_DEVICE_ID_INTEL_82371AB,
-				     PCI_ANY_ID, PCI_ANY_ID, NULL);
-		if (dev) {
-			errata.piix4.bmisx = pci_resource_start(dev, 4);
-			pci_dev_put(dev);
-		}
-
-		/*
-		 * Type-F DMA
-		 * ----------
-		 * Find the PIIX4 ISA Controller and read the Motherboard
-		 * DMA controller's status to see if Type-F (Fast) DMA mode
-		 * is enabled (bit 7) on either channel.  Note that we'll
-		 * disable C3 support if this is enabled, as some legacy
-		 * devices won't operate well if fast DMA is disabled.
-		 */
-		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
-				     PCI_DEVICE_ID_INTEL_82371AB_0,
-				     PCI_ANY_ID, PCI_ANY_ID, NULL);
-		if (dev) {
-			pci_read_config_byte(dev, 0x76, &value1);
-			pci_read_config_byte(dev, 0x77, &value2);
-			if ((value1 & 0x80) || (value2 & 0x80))
-				errata.piix4.fdma = 1;
-			pci_dev_put(dev);
-		}
-
-		break;
-	}
-
-	if (errata.piix4.bmisx)
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Bus master activity detection (BM-IDE) erratum enabled\n"));
-	if (errata.piix4.fdma)
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Type-F DMA livelock erratum (C3 disabled)\n"));
-
-	return 0;
-}
-
-static int acpi_processor_errata(struct acpi_processor *pr)
-{
-	int result = 0;
-	struct pci_dev *dev = NULL;
-
-
-	if (!pr)
-		return -EINVAL;
-
-	/*
-	 * PIIX4
-	 */
-	dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
-			     PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID,
-			     PCI_ANY_ID, NULL);
-	if (dev) {
-		result = acpi_processor_errata_piix4(dev);
-		pci_dev_put(dev);
-	}
-
-	return result;
-}
-
-/* --------------------------------------------------------------------------
-                              FS Interface (/proc)
-   -------------------------------------------------------------------------- */
-
-#ifdef CONFIG_ACPI_PROCFS
-static struct proc_dir_entry *acpi_processor_dir = NULL;
-
-static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
-{
-	struct acpi_processor *pr = seq->private;
-
-
-	if (!pr)
-		goto end;
-
-	seq_printf(seq, "processor id:            %d\n"
-		   "acpi id:                 %d\n"
-		   "bus mastering control:   %s\n"
-		   "power management:        %s\n"
-		   "throttling control:      %s\n"
-		   "limit interface:         %s\n",
-		   pr->id,
-		   pr->acpi_id,
-		   pr->flags.bm_control ? "yes" : "no",
-		   pr->flags.power ? "yes" : "no",
-		   pr->flags.throttling ? "yes" : "no",
-		   pr->flags.limit ? "yes" : "no");
-
-      end:
-	return 0;
-}
-
-static int acpi_processor_info_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_processor_info_seq_show,
-			   PDE(inode)->data);
-}
-
-static int __cpuinit acpi_processor_add_fs(struct acpi_device *device)
-{
-	struct proc_dir_entry *entry = NULL;
-
-
-	if (!acpi_device_dir(device)) {
-		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
-						     acpi_processor_dir);
-		if (!acpi_device_dir(device))
-			return -ENODEV;
-	}
-
-	/* 'info' [R] */
-	entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO,
-				 S_IRUGO, acpi_device_dir(device),
-				 &acpi_processor_info_fops,
-				 acpi_driver_data(device));
-	if (!entry)
-		return -EIO;
-
-	/* 'throttling' [R/W] */
-	entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING,
-				 S_IFREG | S_IRUGO | S_IWUSR,
-				 acpi_device_dir(device),
-				 &acpi_processor_throttling_fops,
-				 acpi_driver_data(device));
-	if (!entry)
-		return -EIO;
-
-	/* 'limit' [R/W] */
-	entry = proc_create_data(ACPI_PROCESSOR_FILE_LIMIT,
-				 S_IFREG | S_IRUGO | S_IWUSR,
-				 acpi_device_dir(device),
-				 &acpi_processor_limit_fops,
-				 acpi_driver_data(device));
-	if (!entry)
-		return -EIO;
-	return 0;
-}
-static int acpi_processor_remove_fs(struct acpi_device *device)
-{
-
-	if (acpi_device_dir(device)) {
-		remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,
-				  acpi_device_dir(device));
-		remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
-				  acpi_device_dir(device));
-		remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,
-				  acpi_device_dir(device));
-		remove_proc_entry(acpi_device_bid(device), acpi_processor_dir);
-		acpi_device_dir(device) = NULL;
-	}
-
-	return 0;
-}
-#else
-static inline int acpi_processor_add_fs(struct acpi_device *device)
-{
-	return 0;
-}
-static inline int acpi_processor_remove_fs(struct acpi_device *device)
+static int set_no_mwait(const struct dmi_system_id *id)
 {
+	printk(KERN_NOTICE PREFIX "%s detected - "
+		"disabling mwait for CPU C-states\n", id->ident);
+	idle_nomwait = 1;
 	return 0;
 }
-#endif
-
-/* Use the acpiid in MADT to map cpus in case of SMP */
 
-#ifndef CONFIG_SMP
-static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) { return -1; }
-#else
-
-static struct acpi_table_madt *madt;
+static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
+	{
+	set_no_mwait, "IFL91 board", {
+	DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
+	DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"),
+	DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"),
+	DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL},
+	{
+	set_no_mwait, "Extensa 5220", {
+	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+	DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+	DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
+	DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
+	{},
+};
 
+#ifdef CONFIG_SMP
 static int map_lapic_id(struct acpi_subtable_header *entry,
 		 u32 acpi_id, int *apic_id)
 {
 	struct acpi_madt_local_apic *lapic =
 		(struct acpi_madt_local_apic *)entry;
-	if ((lapic->lapic_flags & ACPI_MADT_ENABLED) &&
-	    lapic->processor_id == acpi_id) {
-		*apic_id = lapic->id;
-		return 1;
-	}
-	return 0;
+
+	if (!(lapic->lapic_flags & ACPI_MADT_ENABLED))
+		return 0;
+
+	if (lapic->processor_id != acpi_id)
+		return 0;
+
+	*apic_id = lapic->id;
+	return 1;
 }
 
 static int map_x2apic_id(struct acpi_subtable_header *entry,
@@ -383,22 +65,16 @@ static int map_x2apic_id(struct acpi_sub
 {
 	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;
+	if (device_declaration && (apic->uid == acpi_id)) {
+		*apic_id = apic->local_apic_id;
+		return 1;
 	}
 
 	return 0;
-found:
-	*apic_id = tmp;
-	return 1;
 }
 
 static int map_lsapic_id(struct acpi_subtable_header *entry,
@@ -406,35 +82,34 @@ static int map_lsapic_id(struct acpi_sub
 {
 	struct acpi_madt_local_sapic *lsapic =
 		(struct acpi_madt_local_sapic *)entry;
-	u32 tmp = (lsapic->id << 8) | lsapic->eid;
 
-	/* Only check enabled APICs*/
 	if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED))
 		return 0;
 
-	/* Device statement declaration type */
 	if (device_declaration) {
-		if (entry->length < 16)
-			printk(KERN_ERR PREFIX
-			    "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n",
-			    tmp);
-		else if (lsapic->uid == acpi_id)
-			goto found;
-	/* Processor statement declaration type */
-	} else if (lsapic->processor_id == acpi_id)
-		goto found;
+		if ((entry->length < 16) || (lsapic->uid != acpi_id))
+			return 0;
+	} else if (lsapic->processor_id != acpi_id)
+		return 0;
 
-	return 0;
-found:
-	*apic_id = tmp;
+	*apic_id = (lsapic->id << 8) | lsapic->eid;
 	return 1;
 }
 
 static int map_madt_entry(int type, u32 acpi_id)
 {
 	unsigned long madt_end, entry;
+	static struct acpi_table_madt *madt;
+	static int read_madt;
 	int apic_id = -1;
 
+	if (!read_madt) {
+		if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
+					(struct acpi_table_header **)&madt)))
+			madt = NULL;
+		read_madt++;
+	}
+
 	if (!madt)
 		return apic_id;
 
@@ -494,7 +169,7 @@ exit:
 	return apic_id;
 }
 
-static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id)
+int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
 {
 	int i;
 	int apic_id = -1;
@@ -511,630 +186,170 @@ static int get_cpu_id(acpi_handle handle
 	}
 	return -1;
 }
+EXPORT_SYMBOL_GPL(acpi_get_cpuid);
 #endif
 
-/* --------------------------------------------------------------------------
-                                 Driver Interface
-   -------------------------------------------------------------------------- */
-
-static int acpi_processor_get_info(struct acpi_device *device)
+static bool processor_physically_present(acpi_handle handle)
 {
-	acpi_status status = 0;
+	int cpuid, type;
+	u32 acpi_id;
+	acpi_status status;
+	acpi_object_type acpi_type;
+	unsigned long long tmp;
 	union acpi_object object = { 0 };
 	struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
-	struct acpi_processor *pr;
-	int cpu_index, device_declaration = 0;
-	static int cpu0_initialized;
-
-	pr = acpi_driver_data(device);
-	if (!pr)
-		return -EINVAL;
 
-	if (num_online_cpus() > 1)
-		errata.smp = TRUE;
-
-	acpi_processor_errata(pr);
-
-	/*
-	 * Check to see if we have bus mastering arbitration control.  This
-	 * is required for proper C3 usage (to maintain cache coherency).
-	 */
-	if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) {
-		pr->flags.bm_control = 1;
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Bus mastering arbitration control present\n"));
-	} else
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "No bus mastering arbitration control\n"));
-
-	if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) {
-		/* Declared with "Processor" statement; match ProcessorID */
-		status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
-		if (ACPI_FAILURE(status)) {
-			printk(KERN_ERR PREFIX "Evaluating processor object\n");
-			return -ENODEV;
-		}
-
-		/*
-		 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
-		 *      >>> 'acpi_get_processor_id(acpi_id, &id)' in
-		 *      arch/xxx/acpi.c
-		 */
-		pr->acpi_id = object.processor.proc_id;
-	} else {
-		/*
-		 * Declared with "Device" statement; match _UID.
-		 * Note that we don't handle string _UIDs yet.
-		 */
-		unsigned long long value;
-		status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
-						NULL, &value);
-		if (ACPI_FAILURE(status)) {
-			printk(KERN_ERR PREFIX
-			    "Evaluating processor _UID [%#x]\n", status);
-			return -ENODEV;
-		}
-		device_declaration = 1;
-		pr->acpi_id = value;
-	}
-	cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id);
-
-	/* Handle UP system running SMP kernel, with no LAPIC in MADT */
-	if (!cpu0_initialized && (cpu_index == -1) &&
-	    (num_online_cpus() == 1)) {
-		cpu_index = 0;
-	}
-
-	cpu0_initialized = 1;
-
-	pr->id = cpu_index;
-
-	/*
-	 *  Extra Processor objects may be enumerated on MP systems with
-	 *  less than the max # of CPUs. They should be ignored _iff
-	 *  they are physically not present.
-	 */
-	if (pr->id == -1) {
-		if (ACPI_FAILURE
-		    (acpi_processor_hotadd_init(pr->handle, &pr->id))) {
-			return -ENODEV;
-		}
-	}
-	/*
-	 * On some boxes several processors use the same processor bus id.
-	 * But they are located in different scope. For example:
-	 * \_SB.SCK0.CPU0
-	 * \_SB.SCK1.CPU0
-	 * Rename the processor device bus id. And the new bus id will be
-	 * generated as the following format:
-	 * CPU+CPU ID.
-	 */
-	sprintf(acpi_device_bid(device), "CPU%X", pr->id);
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
-			  pr->acpi_id));
-
-	if (!object.processor.pblk_address)
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
-	else if (object.processor.pblk_length != 6)
-		printk(KERN_ERR PREFIX "Invalid PBLK length [%d]\n",
-			    object.processor.pblk_length);
-	else {
-		pr->throttling.address = object.processor.pblk_address;
-		pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset;
-		pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
-
-		pr->pblk = object.processor.pblk_address;
-
-		/*
-		 * We don't care about error returns - we just try to mark
-		 * these reserved so that nobody else is confused into thinking
-		 * that this region might be unused..
-		 *
-		 * (In particular, allocating the IO range for Cardbus)
-		 */
-		request_region(pr->throttling.address, 6, "ACPI CPU throttle");
-	}
-
-	/*
-	 * If ACPI describes a slot number for this CPU, we can use it
-	 * ensure we get the right value in the "physical id" field
-	 * of /proc/cpuinfo
-	 */
-	status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer);
-	if (ACPI_SUCCESS(status))
-		arch_fix_phys_package_id(pr->id, object.integer.value);
-
-	return 0;
-}
-
-static DEFINE_PER_CPU(void *, processor_device_array);
-
-static void acpi_processor_notify(struct acpi_device *device, u32 event)
-{
-	struct acpi_processor *pr = acpi_driver_data(device);
-	int saved;
-
-	if (!pr)
-		return;
+	status = acpi_get_type(handle, &acpi_type);
+	if (ACPI_FAILURE(status))
+		return false;
 
-	switch (event) {
-	case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
-		saved = pr->performance_platform_limit;
-		acpi_processor_ppc_has_changed(pr, 1);
-		if (saved == pr->performance_platform_limit)
-			break;
-		acpi_bus_generate_proc_event(device, event,
-					pr->performance_platform_limit);
-		acpi_bus_generate_netlink_event(device->pnp.device_class,
-						  dev_name(&device->dev), event,
-						  pr->performance_platform_limit);
+	switch (acpi_type) {
+	case ACPI_TYPE_PROCESSOR:
+		status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
+		if (ACPI_FAILURE(status))
+			return false;
+		acpi_id = object.processor.proc_id;
 		break;
-	case ACPI_PROCESSOR_NOTIFY_POWER:
-		acpi_processor_cst_has_changed(pr);
-		acpi_bus_generate_proc_event(device, event, 0);
-		acpi_bus_generate_netlink_event(device->pnp.device_class,
-						  dev_name(&device->dev), event, 0);
+	case ACPI_TYPE_DEVICE:
+		status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp);
+		if (ACPI_FAILURE(status))
+			return false;
+		acpi_id = tmp;
 		break;
-	case ACPI_PROCESSOR_NOTIFY_THROTTLING:
-		acpi_processor_tstate_has_changed(pr);
-		acpi_bus_generate_proc_event(device, event, 0);
-		acpi_bus_generate_netlink_event(device->pnp.device_class,
-						  dev_name(&device->dev), event, 0);
 	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Unsupported event [0x%x]\n", event));
-		break;
+		return false;
 	}
 
-	return;
-}
+	type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
+	cpuid = acpi_get_cpuid(handle, type, acpi_id);
 
-static int acpi_cpu_soft_notify(struct notifier_block *nfb,
-		unsigned long action, void *hcpu)
-{
-	unsigned int cpu = (unsigned long)hcpu;
-	struct acpi_processor *pr = per_cpu(processors, cpu);
+	if (cpuid == -1)
+		return false;
 
-	if (action == CPU_ONLINE && pr) {
-		acpi_processor_ppc_has_changed(pr, 0);
-		acpi_processor_cst_has_changed(pr);
-		acpi_processor_tstate_has_changed(pr);
-	}
-	return NOTIFY_OK;
+	return true;
 }
 
-static struct notifier_block acpi_cpu_notifier =
-{
-	    .notifier_call = acpi_cpu_soft_notify,
-};
-
-static int __cpuinit acpi_processor_add(struct acpi_device *device)
+static void acpi_set_pdc_bits(u32 *buf)
 {
-	struct acpi_processor *pr = NULL;
-	int result = 0;
-	struct sys_device *sysdev;
-
-	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
-	if (!pr)
-		return -ENOMEM;
-
-	if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
-		kfree(pr);
-		return -ENOMEM;
-	}
-
-	pr->handle = device->handle;
-	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
-	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
-	device->driver_data = pr;
-
-	result = acpi_processor_get_info(device);
-	if (result) {
-		/* Processor is physically not present */
-		return 0;
-	}
-
-	BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
-
-	/*
-	 * Buggy BIOS check
-	 * ACPI id of processors can be reported wrongly by the BIOS.
-	 * Don't trust it blindly
-	 */
-	if (per_cpu(processor_device_array, pr->id) != NULL &&
-	    per_cpu(processor_device_array, pr->id) != device) {
-		printk(KERN_WARNING "BIOS reported wrong ACPI id "
-			"for the processor\n");
-		result = -ENODEV;
-		goto err_free_cpumask;
-	}
-	per_cpu(processor_device_array, pr->id) = device;
-
-	per_cpu(processors, pr->id) = pr;
-
-	result = acpi_processor_add_fs(device);
-	if (result)
-		goto err_free_cpumask;
-
-	sysdev = get_cpu_sysdev(pr->id);
-	if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) {
-		result = -EFAULT;
-		goto err_remove_fs;
-	}
-
-	/* _PDC call should be done before doing anything else (if reqd.). */
-	acpi_processor_set_pdc(pr->handle);
-
-#ifdef CONFIG_CPU_FREQ
-	acpi_processor_ppc_has_changed(pr, 0);
-#endif
-	acpi_processor_get_throttling_info(pr);
-	acpi_processor_get_limit_info(pr);
-
-
-	acpi_processor_power_init(pr, device);
-
-	pr->cdev = thermal_cooling_device_register("Processor", device,
-						&processor_cooling_ops);
-	if (IS_ERR(pr->cdev)) {
-		result = PTR_ERR(pr->cdev);
-		goto err_power_exit;
-	}
-
-	dev_dbg(&device->dev, "registered as cooling_device%d\n",
-		 pr->cdev->id);
-
-	result = sysfs_create_link(&device->dev.kobj,
-				   &pr->cdev->device.kobj,
-				   "thermal_cooling");
-	if (result) {
-		printk(KERN_ERR PREFIX "Create sysfs link\n");
-		goto err_thermal_unregister;
-	}
-	result = sysfs_create_link(&pr->cdev->device.kobj,
-				   &device->dev.kobj,
-				   "device");
-	if (result) {
-		printk(KERN_ERR PREFIX "Create sysfs link\n");
-		goto err_remove_sysfs;
-	}
-
-	return 0;
+	buf[0] = ACPI_PDC_REVISION_ID;
+	buf[1] = 1;
 
-err_remove_sysfs:
-	sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
-err_thermal_unregister:
-	thermal_cooling_device_unregister(pr->cdev);
-err_power_exit:
-	acpi_processor_power_exit(pr, device);
-err_remove_fs:
-	acpi_processor_remove_fs(device);
-err_free_cpumask:
-	free_cpumask_var(pr->throttling.shared_cpu_map);
+	/* Enable coordination with firmware's _TSD info */
+	buf[2] = ACPI_PDC_SMP_T_SWCOORD;
 
-	return result;
+	/* Twiddle arch-specific bits needed for _PDC */
+	arch_acpi_set_pdc_bits(buf);
 }
 
-static int acpi_processor_remove(struct acpi_device *device, int type)
+static struct acpi_object_list *acpi_processor_alloc_pdc(void)
 {
-	struct acpi_processor *pr = NULL;
-
-
-	if (!device || !acpi_driver_data(device))
-		return -EINVAL;
-
-	pr = acpi_driver_data(device);
-
-	if (pr->id >= nr_cpu_ids)
-		goto free;
+	struct acpi_object_list *obj_list;
+	union acpi_object *obj;
+	u32 *buf;
 
-	if (type == ACPI_BUS_REMOVAL_EJECT) {
-		if (acpi_processor_handle_eject(pr))
-			return -EINVAL;
+	/* allocate and initialize pdc. It will be used later. */
+	obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
+	if (!obj_list) {
+		printk(KERN_ERR "Memory allocation error\n");
+		return NULL;
 	}
 
-	acpi_processor_power_exit(pr, device);
-
-	sysfs_remove_link(&device->dev.kobj, "sysdev");
-
-	acpi_processor_remove_fs(device);
-
-	if (pr->cdev) {
-		sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
-		sysfs_remove_link(&pr->cdev->device.kobj, "device");
-		thermal_cooling_device_unregister(pr->cdev);
-		pr->cdev = NULL;
+	obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+	if (!obj) {
+		printk(KERN_ERR "Memory allocation error\n");
+		kfree(obj_list);
+		return NULL;
 	}
 
-	per_cpu(processors, pr->id) = NULL;
-	per_cpu(processor_device_array, pr->id) = NULL;
-
-free:
-	free_cpumask_var(pr->throttling.shared_cpu_map);
-	kfree(pr);
-
-	return 0;
-}
-
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
-/****************************************************************************
- * 	Acpi processor hotplug support 				       	    *
- ****************************************************************************/
-
-static int is_processor_present(acpi_handle handle)
-{
-	acpi_status status;
-	unsigned long long sta = 0;
-
-
-	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
-
-	if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
-		return 1;
-
-	/*
-	 * _STA is mandatory for a processor that supports hot plug
-	 */
-	if (status == AE_NOT_FOUND)
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				"Processor does not support hot plug\n"));
-	else
-		ACPI_EXCEPTION((AE_INFO, status,
-				"Processor Device is not present"));
-	return 0;
-}
-
-static
-int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
-{
-	acpi_handle phandle;
-	struct acpi_device *pdev;
-
-
-	if (acpi_get_parent(handle, &phandle)) {
-		return -ENODEV;
+	buf = kmalloc(12, GFP_KERNEL);
+	if (!buf) {
+		printk(KERN_ERR "Memory allocation error\n");
+		kfree(obj);
+		kfree(obj_list);
+		return NULL;
 	}
 
-	if (acpi_bus_get_device(phandle, &pdev)) {
-		return -ENODEV;
-	}
+	acpi_set_pdc_bits(buf);
 
-	if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) {
-		return -ENODEV;
-	}
+	obj->type = ACPI_TYPE_BUFFER;
+	obj->buffer.length = 12;
+	obj->buffer.pointer = (u8 *) buf;
+	obj_list->count = 1;
+	obj_list->pointer = obj;
 
-	return 0;
+	return obj_list;
 }
 
-static void __ref acpi_processor_hotplug_notify(acpi_handle handle,
-						u32 event, void *data)
+/*
+ * _PDC is required for a BIOS-OS handshake for most of the newer
+ * ACPI processor features.
+ */
+static int
+acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
 {
-	struct acpi_processor *pr;
-	struct acpi_device *device = NULL;
-	int result;
-
-
-	switch (event) {
-	case ACPI_NOTIFY_BUS_CHECK:
-	case ACPI_NOTIFY_DEVICE_CHECK:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-		"Processor driver received %s event\n",
-		       (event == ACPI_NOTIFY_BUS_CHECK) ?
-		       "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"));
+	acpi_status status = AE_OK;
 
-		if (!is_processor_present(handle))
-			break;
+	if (idle_nomwait) {
+		/*
+		 * If mwait is disabled for CPU C-states, the C2C3_FFH access
+		 * mode will be disabled in the parameter of _PDC object.
+		 * Of course C1_FFH access mode will also be disabled.
+		 */
+		union acpi_object *obj;
+		u32 *buffer = NULL;
 
-		if (acpi_bus_get_device(handle, &device)) {
-			result = acpi_processor_device_add(handle, &device);
-			if (result)
-				printk(KERN_ERR PREFIX
-					    "Unable to add the device\n");
-			break;
-		}
-		break;
-	case ACPI_NOTIFY_EJECT_REQUEST:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "received ACPI_NOTIFY_EJECT_REQUEST\n"));
+		obj = pdc_in->pointer;
+		buffer = (u32 *)(obj->buffer.pointer);
+		buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
 
-		if (acpi_bus_get_device(handle, &device)) {
-			printk(KERN_ERR PREFIX
-				    "Device don't exist, dropping EJECT\n");
-			break;
-		}
-		pr = acpi_driver_data(device);
-		if (!pr) {
-			printk(KERN_ERR PREFIX
-				    "Driver data is NULL, dropping EJECT\n");
-			return;
-		}
-		break;
-	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Unsupported event [0x%x]\n", event));
-		break;
 	}
+	status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);
 
-	return;
-}
-
-static acpi_status
-processor_walk_namespace_cb(acpi_handle handle,
-			    u32 lvl, void *context, void **rv)
-{
-	acpi_status status;
-	int *action = context;
-	acpi_object_type type = 0;
-
-	status = acpi_get_type(handle, &type);
 	if (ACPI_FAILURE(status))
-		return (AE_OK);
-
-	if (type != ACPI_TYPE_PROCESSOR)
-		return (AE_OK);
-
-	switch (*action) {
-	case INSTALL_NOTIFY_HANDLER:
-		acpi_install_notify_handler(handle,
-					    ACPI_SYSTEM_NOTIFY,
-					    acpi_processor_hotplug_notify,
-					    NULL);
-		break;
-	case UNINSTALL_NOTIFY_HANDLER:
-		acpi_remove_notify_handler(handle,
-					   ACPI_SYSTEM_NOTIFY,
-					   acpi_processor_hotplug_notify);
-		break;
-	default:
-		break;
-	}
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+		    "Could not evaluate _PDC, using legacy perf. control.\n"));
 
-	return (AE_OK);
+	return status;
 }
 
-static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
+void acpi_processor_set_pdc(acpi_handle handle)
 {
+	struct acpi_object_list *obj_list;
 
-	if (!is_processor_present(handle)) {
-		return AE_ERROR;
-	}
+	if (arch_has_acpi_pdc() == false)
+		return;
 
-	if (acpi_map_lsapic(handle, p_cpu))
-		return AE_ERROR;
+	obj_list = acpi_processor_alloc_pdc();
+	if (!obj_list)
+		return;
 
-	if (arch_register_cpu(*p_cpu)) {
-		acpi_unmap_lsapic(*p_cpu);
-		return AE_ERROR;
-	}
+	acpi_processor_eval_pdc(handle, obj_list);
 
-	return AE_OK;
+	kfree(obj_list->pointer->buffer.pointer);
+	kfree(obj_list->pointer);
+	kfree(obj_list);
 }
+EXPORT_SYMBOL_GPL(acpi_processor_set_pdc);
 
-static int acpi_processor_handle_eject(struct acpi_processor *pr)
+static acpi_status
+early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
-	if (cpu_online(pr->id))
-		cpu_down(pr->id);
+	if (processor_physically_present(handle) == false)
+		return AE_OK;
 
-	arch_unregister_cpu(pr->id);
-	acpi_unmap_lsapic(pr->id);
-	return (0);
-}
-#else
-static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
-{
-	return AE_ERROR;
-}
-static int acpi_processor_handle_eject(struct acpi_processor *pr)
-{
-	return (-EINVAL);
+	acpi_processor_set_pdc(handle);
+	return AE_OK;
 }
-#endif
 
-static
-void acpi_processor_install_hotplug_notify(void)
+void __init acpi_early_processor_set_pdc(void)
 {
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
-	int action = INSTALL_NOTIFY_HANDLER;
-	acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
-			    ACPI_ROOT_OBJECT,
-			    ACPI_UINT32_MAX,
-			    processor_walk_namespace_cb, NULL, &action, NULL);
-#endif
-	register_hotcpu_notifier(&acpi_cpu_notifier);
-}
+	/*
+	 * Check whether the system is DMI table. If yes, OSPM
+	 * should not use mwait for CPU-states.
+	 */
+	dmi_check_system(processor_idle_dmi_table);
 
-static
-void acpi_processor_uninstall_hotplug_notify(void)
-{
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
-	int action = UNINSTALL_NOTIFY_HANDLER;
-	acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
-			    ACPI_ROOT_OBJECT,
+	acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
 			    ACPI_UINT32_MAX,
-			    processor_walk_namespace_cb, NULL, &action, NULL);
-#endif
-	unregister_hotcpu_notifier(&acpi_cpu_notifier);
-}
-
-/*
- * We keep the driver loaded even when ACPI is not running.
- * This is needed for the powernow-k8 driver, that works even without
- * ACPI, but needs symbols from this driver
- */
-
-static int __init acpi_processor_init(void)
-{
-	int result = 0;
-
-	if (acpi_disabled)
-		return 0;
-
-	memset(&errata, 0, sizeof(errata));
-
-#ifdef CONFIG_SMP
-	if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
-				(struct acpi_table_header **)&madt)))
-		madt = NULL;
-#endif
-#ifdef CONFIG_ACPI_PROCFS
-	acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
-	if (!acpi_processor_dir)
-		return -ENOMEM;
-#endif
-	result = cpuidle_register_driver(&acpi_idle_driver);
-	if (result < 0)
-		goto out_proc;
-
-	result = acpi_bus_register_driver(&acpi_processor_driver);
-	if (result < 0)
-		goto out_cpuidle;
-
-	acpi_processor_install_hotplug_notify();
-
-	acpi_thermal_cpufreq_init();
-
-	acpi_processor_ppc_init();
-
-	acpi_processor_throttling_init();
-
-	return 0;
-
-out_cpuidle:
-	cpuidle_unregister_driver(&acpi_idle_driver);
-
-out_proc:
-#ifdef CONFIG_ACPI_PROCFS
-	remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
-#endif
-
-	return result;
-}
-
-static void __exit acpi_processor_exit(void)
-{
-	if (acpi_disabled)
-		return;
-
-	acpi_processor_ppc_exit();
-
-	acpi_thermal_cpufreq_exit();
-
-	acpi_processor_uninstall_hotplug_notify();
-
-	acpi_bus_unregister_driver(&acpi_processor_driver);
-
-	cpuidle_unregister_driver(&acpi_idle_driver);
-
-#ifdef CONFIG_ACPI_PROCFS
-	remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
-#endif
-
-	return;
+			    early_init_pdc, NULL, NULL, NULL);
 }
-
-module_init(acpi_processor_init);
-module_exit(acpi_processor_exit);
-
-EXPORT_SYMBOL(acpi_processor_set_thermal_limit);
-
-MODULE_ALIAS("processor");
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/processor_driver.c linux-libre-2.6.34-gnu1/drivers/acpi/processor_driver.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/processor_driver.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/processor_driver.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,979 @@
+/*
+ * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
+ *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *  			- Added processor hotplug support
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You 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.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *  TBD:
+ *	1. Make # power states dynamic.
+ *	2. Support duty_cycle values that span bit 4.
+ *	3. Optimize by having scheduler determine business instead of
+ *	   having us try to calculate it here.
+ *	4. Need C1 timing -- must modify kernel (IRQ handler) to get this.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+#include <linux/cpufreq.h>
+#include <linux/cpu.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/dmi.h>
+#include <linux/moduleparam.h>
+#include <linux/cpuidle.h>
+#include <linux/slab.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/cpu.h>
+#include <asm/delay.h>
+#include <asm/uaccess.h>
+#include <asm/processor.h>
+#include <asm/smp.h>
+#include <asm/acpi.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/processor.h>
+
+#define PREFIX "ACPI: "
+
+#define ACPI_PROCESSOR_CLASS		"processor"
+#define ACPI_PROCESSOR_DEVICE_NAME	"Processor"
+#define ACPI_PROCESSOR_FILE_INFO	"info"
+#define ACPI_PROCESSOR_FILE_THROTTLING	"throttling"
+#define ACPI_PROCESSOR_FILE_LIMIT	"limit"
+#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
+#define ACPI_PROCESSOR_NOTIFY_POWER	0x81
+#define ACPI_PROCESSOR_NOTIFY_THROTTLING	0x82
+
+#define ACPI_PROCESSOR_LIMIT_USER	0
+#define ACPI_PROCESSOR_LIMIT_THERMAL	1
+
+#define _COMPONENT		ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME("processor_driver");
+
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION("ACPI Processor Driver");
+MODULE_LICENSE("GPL");
+
+static int acpi_processor_add(struct acpi_device *device);
+static int acpi_processor_remove(struct acpi_device *device, int type);
+#ifdef CONFIG_ACPI_PROCFS
+static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
+#endif
+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);
+
+
+static const struct acpi_device_id processor_device_ids[] = {
+	{ACPI_PROCESSOR_OBJECT_HID, 0},
+	{"ACPI0007", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, processor_device_ids);
+
+static struct acpi_driver acpi_processor_driver = {
+	.name = "processor",
+	.class = ACPI_PROCESSOR_CLASS,
+	.ids = processor_device_ids,
+	.ops = {
+		.add = acpi_processor_add,
+		.remove = acpi_processor_remove,
+		.suspend = acpi_processor_suspend,
+		.resume = acpi_processor_resume,
+		.notify = acpi_processor_notify,
+		},
+};
+
+#define INSTALL_NOTIFY_HANDLER		1
+#define UNINSTALL_NOTIFY_HANDLER	2
+#ifdef CONFIG_ACPI_PROCFS
+static const struct file_operations acpi_processor_info_fops = {
+	.owner = THIS_MODULE,
+	.open = acpi_processor_info_open_fs,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+#endif
+
+DEFINE_PER_CPU(struct acpi_processor *, processors);
+EXPORT_PER_CPU_SYMBOL(processors);
+
+struct acpi_processor_errata errata __read_mostly;
+
+/* --------------------------------------------------------------------------
+                                Errata Handling
+   -------------------------------------------------------------------------- */
+
+static int acpi_processor_errata_piix4(struct pci_dev *dev)
+{
+	u8 value1 = 0;
+	u8 value2 = 0;
+
+
+	if (!dev)
+		return -EINVAL;
+
+	/*
+	 * Note that 'dev' references the PIIX4 ACPI Controller.
+	 */
+
+	switch (dev->revision) {
+	case 0:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n"));
+		break;
+	case 1:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n"));
+		break;
+	case 2:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n"));
+		break;
+	case 3:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n"));
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n"));
+		break;
+	}
+
+	switch (dev->revision) {
+
+	case 0:		/* PIIX4 A-step */
+	case 1:		/* PIIX4 B-step */
+		/*
+		 * See specification changes #13 ("Manual Throttle Duty Cycle")
+		 * and #14 ("Enabling and Disabling Manual Throttle"), plus
+		 * erratum #5 ("STPCLK# Deassertion Time") from the January
+		 * 2002 PIIX4 specification update.  Applies to only older
+		 * PIIX4 models.
+		 */
+		errata.piix4.throttle = 1;
+
+	case 2:		/* PIIX4E */
+	case 3:		/* PIIX4M */
+		/*
+		 * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA
+		 * Livelock") from the January 2002 PIIX4 specification update.
+		 * Applies to all PIIX4 models.
+		 */
+
+		/*
+		 * BM-IDE
+		 * ------
+		 * Find the PIIX4 IDE Controller and get the Bus Master IDE
+		 * Status register address.  We'll use this later to read
+		 * each IDE controller's DMA status to make sure we catch all
+		 * DMA activity.
+		 */
+		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+				     PCI_DEVICE_ID_INTEL_82371AB,
+				     PCI_ANY_ID, PCI_ANY_ID, NULL);
+		if (dev) {
+			errata.piix4.bmisx = pci_resource_start(dev, 4);
+			pci_dev_put(dev);
+		}
+
+		/*
+		 * Type-F DMA
+		 * ----------
+		 * Find the PIIX4 ISA Controller and read the Motherboard
+		 * DMA controller's status to see if Type-F (Fast) DMA mode
+		 * is enabled (bit 7) on either channel.  Note that we'll
+		 * disable C3 support if this is enabled, as some legacy
+		 * devices won't operate well if fast DMA is disabled.
+		 */
+		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+				     PCI_DEVICE_ID_INTEL_82371AB_0,
+				     PCI_ANY_ID, PCI_ANY_ID, NULL);
+		if (dev) {
+			pci_read_config_byte(dev, 0x76, &value1);
+			pci_read_config_byte(dev, 0x77, &value2);
+			if ((value1 & 0x80) || (value2 & 0x80))
+				errata.piix4.fdma = 1;
+			pci_dev_put(dev);
+		}
+
+		break;
+	}
+
+	if (errata.piix4.bmisx)
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "Bus master activity detection (BM-IDE) erratum enabled\n"));
+	if (errata.piix4.fdma)
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "Type-F DMA livelock erratum (C3 disabled)\n"));
+
+	return 0;
+}
+
+static int acpi_processor_errata(struct acpi_processor *pr)
+{
+	int result = 0;
+	struct pci_dev *dev = NULL;
+
+
+	if (!pr)
+		return -EINVAL;
+
+	/*
+	 * PIIX4
+	 */
+	dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+			     PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID,
+			     PCI_ANY_ID, NULL);
+	if (dev) {
+		result = acpi_processor_errata_piix4(dev);
+		pci_dev_put(dev);
+	}
+
+	return result;
+}
+
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc)
+   -------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ACPI_PROCFS
+static struct proc_dir_entry *acpi_processor_dir = NULL;
+
+static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_processor *pr = seq->private;
+
+
+	if (!pr)
+		goto end;
+
+	seq_printf(seq, "processor id:            %d\n"
+		   "acpi id:                 %d\n"
+		   "bus mastering control:   %s\n"
+		   "power management:        %s\n"
+		   "throttling control:      %s\n"
+		   "limit interface:         %s\n",
+		   pr->id,
+		   pr->acpi_id,
+		   pr->flags.bm_control ? "yes" : "no",
+		   pr->flags.power ? "yes" : "no",
+		   pr->flags.throttling ? "yes" : "no",
+		   pr->flags.limit ? "yes" : "no");
+
+      end:
+	return 0;
+}
+
+static int acpi_processor_info_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_processor_info_seq_show,
+			   PDE(inode)->data);
+}
+
+static int __cpuinit acpi_processor_add_fs(struct acpi_device *device)
+{
+	struct proc_dir_entry *entry = NULL;
+
+
+	if (!acpi_device_dir(device)) {
+		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
+						     acpi_processor_dir);
+		if (!acpi_device_dir(device))
+			return -ENODEV;
+	}
+
+	/* 'info' [R] */
+	entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO,
+				 S_IRUGO, acpi_device_dir(device),
+				 &acpi_processor_info_fops,
+				 acpi_driver_data(device));
+	if (!entry)
+		return -EIO;
+
+	/* 'throttling' [R/W] */
+	entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING,
+				 S_IFREG | S_IRUGO | S_IWUSR,
+				 acpi_device_dir(device),
+				 &acpi_processor_throttling_fops,
+				 acpi_driver_data(device));
+	if (!entry)
+		return -EIO;
+
+	/* 'limit' [R/W] */
+	entry = proc_create_data(ACPI_PROCESSOR_FILE_LIMIT,
+				 S_IFREG | S_IRUGO | S_IWUSR,
+				 acpi_device_dir(device),
+				 &acpi_processor_limit_fops,
+				 acpi_driver_data(device));
+	if (!entry)
+		return -EIO;
+	return 0;
+}
+static int acpi_processor_remove_fs(struct acpi_device *device)
+{
+
+	if (acpi_device_dir(device)) {
+		remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,
+				  acpi_device_dir(device));
+		remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
+				  acpi_device_dir(device));
+		remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,
+				  acpi_device_dir(device));
+		remove_proc_entry(acpi_device_bid(device), acpi_processor_dir);
+		acpi_device_dir(device) = NULL;
+	}
+
+	return 0;
+}
+#else
+static inline int acpi_processor_add_fs(struct acpi_device *device)
+{
+	return 0;
+}
+static inline int acpi_processor_remove_fs(struct acpi_device *device)
+{
+	return 0;
+}
+#endif
+
+/* --------------------------------------------------------------------------
+                                 Driver Interface
+   -------------------------------------------------------------------------- */
+
+static int acpi_processor_get_info(struct acpi_device *device)
+{
+	acpi_status status = 0;
+	union acpi_object object = { 0 };
+	struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
+	struct acpi_processor *pr;
+	int cpu_index, device_declaration = 0;
+	static int cpu0_initialized;
+
+	pr = acpi_driver_data(device);
+	if (!pr)
+		return -EINVAL;
+
+	if (num_online_cpus() > 1)
+		errata.smp = TRUE;
+
+	acpi_processor_errata(pr);
+
+	/*
+	 * Check to see if we have bus mastering arbitration control.  This
+	 * is required for proper C3 usage (to maintain cache coherency).
+	 */
+	if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) {
+		pr->flags.bm_control = 1;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "Bus mastering arbitration control present\n"));
+	} else
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "No bus mastering arbitration control\n"));
+
+	if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) {
+		/* Declared with "Processor" statement; match ProcessorID */
+		status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
+		if (ACPI_FAILURE(status)) {
+			printk(KERN_ERR PREFIX "Evaluating processor object\n");
+			return -ENODEV;
+		}
+
+		/*
+		 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
+		 *      >>> 'acpi_get_processor_id(acpi_id, &id)' in
+		 *      arch/xxx/acpi.c
+		 */
+		pr->acpi_id = object.processor.proc_id;
+	} else {
+		/*
+		 * Declared with "Device" statement; match _UID.
+		 * Note that we don't handle string _UIDs yet.
+		 */
+		unsigned long long value;
+		status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
+						NULL, &value);
+		if (ACPI_FAILURE(status)) {
+			printk(KERN_ERR PREFIX
+			    "Evaluating processor _UID [%#x]\n", status);
+			return -ENODEV;
+		}
+		device_declaration = 1;
+		pr->acpi_id = value;
+	}
+	cpu_index = acpi_get_cpuid(pr->handle, device_declaration, pr->acpi_id);
+
+	/* Handle UP system running SMP kernel, with no LAPIC in MADT */
+	if (!cpu0_initialized && (cpu_index == -1) &&
+	    (num_online_cpus() == 1)) {
+		cpu_index = 0;
+	}
+
+	cpu0_initialized = 1;
+
+	pr->id = cpu_index;
+
+	/*
+	 *  Extra Processor objects may be enumerated on MP systems with
+	 *  less than the max # of CPUs. They should be ignored _iff
+	 *  they are physically not present.
+	 */
+	if (pr->id == -1) {
+		if (ACPI_FAILURE
+		    (acpi_processor_hotadd_init(pr->handle, &pr->id))) {
+			return -ENODEV;
+		}
+	}
+	/*
+	 * On some boxes several processors use the same processor bus id.
+	 * But they are located in different scope. For example:
+	 * \_SB.SCK0.CPU0
+	 * \_SB.SCK1.CPU0
+	 * Rename the processor device bus id. And the new bus id will be
+	 * generated as the following format:
+	 * CPU+CPU ID.
+	 */
+	sprintf(acpi_device_bid(device), "CPU%X", pr->id);
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
+			  pr->acpi_id));
+
+	if (!object.processor.pblk_address)
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
+	else if (object.processor.pblk_length != 6)
+		printk(KERN_ERR PREFIX "Invalid PBLK length [%d]\n",
+			    object.processor.pblk_length);
+	else {
+		pr->throttling.address = object.processor.pblk_address;
+		pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset;
+		pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
+
+		pr->pblk = object.processor.pblk_address;
+
+		/*
+		 * We don't care about error returns - we just try to mark
+		 * these reserved so that nobody else is confused into thinking
+		 * that this region might be unused..
+		 *
+		 * (In particular, allocating the IO range for Cardbus)
+		 */
+		request_region(pr->throttling.address, 6, "ACPI CPU throttle");
+	}
+
+	/*
+	 * If ACPI describes a slot number for this CPU, we can use it
+	 * ensure we get the right value in the "physical id" field
+	 * of /proc/cpuinfo
+	 */
+	status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer);
+	if (ACPI_SUCCESS(status))
+		arch_fix_phys_package_id(pr->id, object.integer.value);
+
+	return 0;
+}
+
+static DEFINE_PER_CPU(void *, processor_device_array);
+
+static void acpi_processor_notify(struct acpi_device *device, u32 event)
+{
+	struct acpi_processor *pr = acpi_driver_data(device);
+	int saved;
+
+	if (!pr)
+		return;
+
+	switch (event) {
+	case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
+		saved = pr->performance_platform_limit;
+		acpi_processor_ppc_has_changed(pr, 1);
+		if (saved == pr->performance_platform_limit)
+			break;
+		acpi_bus_generate_proc_event(device, event,
+					pr->performance_platform_limit);
+		acpi_bus_generate_netlink_event(device->pnp.device_class,
+						  dev_name(&device->dev), event,
+						  pr->performance_platform_limit);
+		break;
+	case ACPI_PROCESSOR_NOTIFY_POWER:
+		acpi_processor_cst_has_changed(pr);
+		acpi_bus_generate_proc_event(device, event, 0);
+		acpi_bus_generate_netlink_event(device->pnp.device_class,
+						  dev_name(&device->dev), event, 0);
+		break;
+	case ACPI_PROCESSOR_NOTIFY_THROTTLING:
+		acpi_processor_tstate_has_changed(pr);
+		acpi_bus_generate_proc_event(device, event, 0);
+		acpi_bus_generate_netlink_event(device->pnp.device_class,
+						  dev_name(&device->dev), event, 0);
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "Unsupported event [0x%x]\n", event));
+		break;
+	}
+
+	return;
+}
+
+static int acpi_cpu_soft_notify(struct notifier_block *nfb,
+		unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (unsigned long)hcpu;
+	struct acpi_processor *pr = per_cpu(processors, cpu);
+
+	if (action == CPU_ONLINE && pr) {
+		acpi_processor_ppc_has_changed(pr, 0);
+		acpi_processor_cst_has_changed(pr);
+		acpi_processor_tstate_has_changed(pr);
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block acpi_cpu_notifier =
+{
+	    .notifier_call = acpi_cpu_soft_notify,
+};
+
+static int __cpuinit acpi_processor_add(struct acpi_device *device)
+{
+	struct acpi_processor *pr = NULL;
+	int result = 0;
+	struct sys_device *sysdev;
+
+	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
+	if (!pr)
+		return -ENOMEM;
+
+	if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
+		kfree(pr);
+		return -ENOMEM;
+	}
+
+	pr->handle = device->handle;
+	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
+	device->driver_data = pr;
+
+	result = acpi_processor_get_info(device);
+	if (result) {
+		/* Processor is physically not present */
+		return 0;
+	}
+
+	BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
+
+	/*
+	 * Buggy BIOS check
+	 * ACPI id of processors can be reported wrongly by the BIOS.
+	 * Don't trust it blindly
+	 */
+	if (per_cpu(processor_device_array, pr->id) != NULL &&
+	    per_cpu(processor_device_array, pr->id) != device) {
+		printk(KERN_WARNING "BIOS reported wrong ACPI id "
+			"for the processor\n");
+		result = -ENODEV;
+		goto err_free_cpumask;
+	}
+	per_cpu(processor_device_array, pr->id) = device;
+
+	per_cpu(processors, pr->id) = pr;
+
+	result = acpi_processor_add_fs(device);
+	if (result)
+		goto err_free_cpumask;
+
+	sysdev = get_cpu_sysdev(pr->id);
+	if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) {
+		result = -EFAULT;
+		goto err_remove_fs;
+	}
+
+#ifdef CONFIG_CPU_FREQ
+	acpi_processor_ppc_has_changed(pr, 0);
+#endif
+	acpi_processor_get_throttling_info(pr);
+	acpi_processor_get_limit_info(pr);
+
+
+	acpi_processor_power_init(pr, device);
+
+	pr->cdev = thermal_cooling_device_register("Processor", device,
+						&processor_cooling_ops);
+	if (IS_ERR(pr->cdev)) {
+		result = PTR_ERR(pr->cdev);
+		goto err_power_exit;
+	}
+
+	dev_dbg(&device->dev, "registered as cooling_device%d\n",
+		 pr->cdev->id);
+
+	result = sysfs_create_link(&device->dev.kobj,
+				   &pr->cdev->device.kobj,
+				   "thermal_cooling");
+	if (result) {
+		printk(KERN_ERR PREFIX "Create sysfs link\n");
+		goto err_thermal_unregister;
+	}
+	result = sysfs_create_link(&pr->cdev->device.kobj,
+				   &device->dev.kobj,
+				   "device");
+	if (result) {
+		printk(KERN_ERR PREFIX "Create sysfs link\n");
+		goto err_remove_sysfs;
+	}
+
+	return 0;
+
+err_remove_sysfs:
+	sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
+err_thermal_unregister:
+	thermal_cooling_device_unregister(pr->cdev);
+err_power_exit:
+	acpi_processor_power_exit(pr, device);
+err_remove_fs:
+	acpi_processor_remove_fs(device);
+err_free_cpumask:
+	free_cpumask_var(pr->throttling.shared_cpu_map);
+
+	return result;
+}
+
+static int acpi_processor_remove(struct acpi_device *device, int type)
+{
+	struct acpi_processor *pr = NULL;
+
+
+	if (!device || !acpi_driver_data(device))
+		return -EINVAL;
+
+	pr = acpi_driver_data(device);
+
+	if (pr->id >= nr_cpu_ids)
+		goto free;
+
+	if (type == ACPI_BUS_REMOVAL_EJECT) {
+		if (acpi_processor_handle_eject(pr))
+			return -EINVAL;
+	}
+
+	acpi_processor_power_exit(pr, device);
+
+	sysfs_remove_link(&device->dev.kobj, "sysdev");
+
+	acpi_processor_remove_fs(device);
+
+	if (pr->cdev) {
+		sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
+		sysfs_remove_link(&pr->cdev->device.kobj, "device");
+		thermal_cooling_device_unregister(pr->cdev);
+		pr->cdev = NULL;
+	}
+
+	per_cpu(processors, pr->id) = NULL;
+	per_cpu(processor_device_array, pr->id) = NULL;
+
+free:
+	free_cpumask_var(pr->throttling.shared_cpu_map);
+	kfree(pr);
+
+	return 0;
+}
+
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+/****************************************************************************
+ * 	Acpi processor hotplug support 				       	    *
+ ****************************************************************************/
+
+static int is_processor_present(acpi_handle handle)
+{
+	acpi_status status;
+	unsigned long long sta = 0;
+
+
+	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+
+	if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
+		return 1;
+
+	/*
+	 * _STA is mandatory for a processor that supports hot plug
+	 */
+	if (status == AE_NOT_FOUND)
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				"Processor does not support hot plug\n"));
+	else
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Processor Device is not present"));
+	return 0;
+}
+
+static
+int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
+{
+	acpi_handle phandle;
+	struct acpi_device *pdev;
+
+
+	if (acpi_get_parent(handle, &phandle)) {
+		return -ENODEV;
+	}
+
+	if (acpi_bus_get_device(phandle, &pdev)) {
+		return -ENODEV;
+	}
+
+	if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) {
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void __ref acpi_processor_hotplug_notify(acpi_handle handle,
+						u32 event, void *data)
+{
+	struct acpi_processor *pr;
+	struct acpi_device *device = NULL;
+	int result;
+
+
+	switch (event) {
+	case ACPI_NOTIFY_BUS_CHECK:
+	case ACPI_NOTIFY_DEVICE_CHECK:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+		"Processor driver received %s event\n",
+		       (event == ACPI_NOTIFY_BUS_CHECK) ?
+		       "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"));
+
+		if (!is_processor_present(handle))
+			break;
+
+		if (acpi_bus_get_device(handle, &device)) {
+			result = acpi_processor_device_add(handle, &device);
+			if (result)
+				printk(KERN_ERR PREFIX
+					    "Unable to add the device\n");
+			break;
+		}
+		break;
+	case ACPI_NOTIFY_EJECT_REQUEST:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "received ACPI_NOTIFY_EJECT_REQUEST\n"));
+
+		if (acpi_bus_get_device(handle, &device)) {
+			printk(KERN_ERR PREFIX
+				    "Device don't exist, dropping EJECT\n");
+			break;
+		}
+		pr = acpi_driver_data(device);
+		if (!pr) {
+			printk(KERN_ERR PREFIX
+				    "Driver data is NULL, dropping EJECT\n");
+			return;
+		}
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "Unsupported event [0x%x]\n", event));
+		break;
+	}
+
+	return;
+}
+
+static acpi_status
+processor_walk_namespace_cb(acpi_handle handle,
+			    u32 lvl, void *context, void **rv)
+{
+	acpi_status status;
+	int *action = context;
+	acpi_object_type type = 0;
+
+	status = acpi_get_type(handle, &type);
+	if (ACPI_FAILURE(status))
+		return (AE_OK);
+
+	if (type != ACPI_TYPE_PROCESSOR)
+		return (AE_OK);
+
+	switch (*action) {
+	case INSTALL_NOTIFY_HANDLER:
+		acpi_install_notify_handler(handle,
+					    ACPI_SYSTEM_NOTIFY,
+					    acpi_processor_hotplug_notify,
+					    NULL);
+		break;
+	case UNINSTALL_NOTIFY_HANDLER:
+		acpi_remove_notify_handler(handle,
+					   ACPI_SYSTEM_NOTIFY,
+					   acpi_processor_hotplug_notify);
+		break;
+	default:
+		break;
+	}
+
+	return (AE_OK);
+}
+
+static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
+{
+
+	if (!is_processor_present(handle)) {
+		return AE_ERROR;
+	}
+
+	if (acpi_map_lsapic(handle, p_cpu))
+		return AE_ERROR;
+
+	if (arch_register_cpu(*p_cpu)) {
+		acpi_unmap_lsapic(*p_cpu);
+		return AE_ERROR;
+	}
+
+	return AE_OK;
+}
+
+static int acpi_processor_handle_eject(struct acpi_processor *pr)
+{
+	if (cpu_online(pr->id))
+		cpu_down(pr->id);
+
+	arch_unregister_cpu(pr->id);
+	acpi_unmap_lsapic(pr->id);
+	return (0);
+}
+#else
+static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
+{
+	return AE_ERROR;
+}
+static int acpi_processor_handle_eject(struct acpi_processor *pr)
+{
+	return (-EINVAL);
+}
+#endif
+
+static
+void acpi_processor_install_hotplug_notify(void)
+{
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+	int action = INSTALL_NOTIFY_HANDLER;
+	acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
+			    ACPI_ROOT_OBJECT,
+			    ACPI_UINT32_MAX,
+			    processor_walk_namespace_cb, NULL, &action, NULL);
+#endif
+	register_hotcpu_notifier(&acpi_cpu_notifier);
+}
+
+static
+void acpi_processor_uninstall_hotplug_notify(void)
+{
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+	int action = UNINSTALL_NOTIFY_HANDLER;
+	acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
+			    ACPI_ROOT_OBJECT,
+			    ACPI_UINT32_MAX,
+			    processor_walk_namespace_cb, NULL, &action, NULL);
+#endif
+	unregister_hotcpu_notifier(&acpi_cpu_notifier);
+}
+
+/*
+ * We keep the driver loaded even when ACPI is not running.
+ * This is needed for the powernow-k8 driver, that works even without
+ * ACPI, but needs symbols from this driver
+ */
+
+static int __init acpi_processor_init(void)
+{
+	int result = 0;
+
+	if (acpi_disabled)
+		return 0;
+
+	memset(&errata, 0, sizeof(errata));
+
+#ifdef CONFIG_ACPI_PROCFS
+	acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+	if (!acpi_processor_dir)
+		return -ENOMEM;
+#endif
+	result = cpuidle_register_driver(&acpi_idle_driver);
+	if (result < 0)
+		goto out_proc;
+
+	result = acpi_bus_register_driver(&acpi_processor_driver);
+	if (result < 0)
+		goto out_cpuidle;
+
+	acpi_processor_install_hotplug_notify();
+
+	acpi_thermal_cpufreq_init();
+
+	acpi_processor_ppc_init();
+
+	acpi_processor_throttling_init();
+
+	return 0;
+
+out_cpuidle:
+	cpuidle_unregister_driver(&acpi_idle_driver);
+
+out_proc:
+#ifdef CONFIG_ACPI_PROCFS
+	remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+#endif
+
+	return result;
+}
+
+static void __exit acpi_processor_exit(void)
+{
+	if (acpi_disabled)
+		return;
+
+	acpi_processor_ppc_exit();
+
+	acpi_thermal_cpufreq_exit();
+
+	acpi_processor_uninstall_hotplug_notify();
+
+	acpi_bus_unregister_driver(&acpi_processor_driver);
+
+	cpuidle_unregister_driver(&acpi_idle_driver);
+
+#ifdef CONFIG_ACPI_PROCFS
+	remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+#endif
+
+	return;
+}
+
+module_init(acpi_processor_init);
+module_exit(acpi_processor_exit);
+
+EXPORT_SYMBOL(acpi_processor_set_thermal_limit);
+
+MODULE_ALIAS("processor");
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/processor_idle.c linux-libre-2.6.34-gnu1/drivers/acpi/processor_idle.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/processor_idle.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/processor_idle.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
+#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/acpi.h>
@@ -360,7 +361,7 @@ static int acpi_processor_get_power_info
 static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
 {
 	acpi_status status = 0;
-	acpi_integer count;
+	u64 count;
 	int current_count;
 	int i;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/processor_pdc.c linux-libre-2.6.34-gnu1/drivers/acpi/processor_pdc.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/processor_pdc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/processor_pdc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2005 Intel Corporation
- * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
- *
- *	Alex Chiang <achiang@hp.com>
- *	- Unified x86/ia64 implementations
- *	Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
- *	- Added _PDC for platforms with Intel CPUs
- */
-#include <linux/dmi.h>
-
-#include <acpi/acpi_drivers.h>
-#include <acpi/processor.h>
-
-#include "internal.h"
-
-#define PREFIX			"ACPI: "
-#define _COMPONENT		ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME("processor_pdc");
-
-static int set_no_mwait(const struct dmi_system_id *id)
-{
-	printk(KERN_NOTICE PREFIX "%s detected - "
-		"disabling mwait for CPU C-states\n", id->ident);
-	idle_nomwait = 1;
-	return 0;
-}
-
-static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
-	{
-	set_no_mwait, "IFL91 board", {
-	DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
-	DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"),
-	DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"),
-	DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL},
-	{
-	set_no_mwait, "Extensa 5220", {
-	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
-	DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-	DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
-	DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
-	{},
-};
-
-static void acpi_set_pdc_bits(u32 *buf)
-{
-	buf[0] = ACPI_PDC_REVISION_ID;
-	buf[1] = 1;
-
-	/* Enable coordination with firmware's _TSD info */
-	buf[2] = ACPI_PDC_SMP_T_SWCOORD;
-
-	/* Twiddle arch-specific bits needed for _PDC */
-	arch_acpi_set_pdc_bits(buf);
-}
-
-static struct acpi_object_list *acpi_processor_alloc_pdc(void)
-{
-	struct acpi_object_list *obj_list;
-	union acpi_object *obj;
-	u32 *buf;
-
-	/* allocate and initialize pdc. It will be used later. */
-	obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
-	if (!obj_list) {
-		printk(KERN_ERR "Memory allocation error\n");
-		return NULL;
-	}
-
-	obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
-	if (!obj) {
-		printk(KERN_ERR "Memory allocation error\n");
-		kfree(obj_list);
-		return NULL;
-	}
-
-	buf = kmalloc(12, GFP_KERNEL);
-	if (!buf) {
-		printk(KERN_ERR "Memory allocation error\n");
-		kfree(obj);
-		kfree(obj_list);
-		return NULL;
-	}
-
-	acpi_set_pdc_bits(buf);
-
-	obj->type = ACPI_TYPE_BUFFER;
-	obj->buffer.length = 12;
-	obj->buffer.pointer = (u8 *) buf;
-	obj_list->count = 1;
-	obj_list->pointer = obj;
-
-	return obj_list;
-}
-
-/*
- * _PDC is required for a BIOS-OS handshake for most of the newer
- * ACPI processor features.
- */
-static int
-acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
-{
-	acpi_status status = AE_OK;
-
-	if (idle_nomwait) {
-		/*
-		 * If mwait is disabled for CPU C-states, the C2C3_FFH access
-		 * mode will be disabled in the parameter of _PDC object.
-		 * Of course C1_FFH access mode will also be disabled.
-		 */
-		union acpi_object *obj;
-		u32 *buffer = NULL;
-
-		obj = pdc_in->pointer;
-		buffer = (u32 *)(obj->buffer.pointer);
-		buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
-
-	}
-	status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);
-
-	if (ACPI_FAILURE(status))
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-		    "Could not evaluate _PDC, using legacy perf. control.\n"));
-
-	return status;
-}
-
-static int early_pdc_done;
-
-void acpi_processor_set_pdc(acpi_handle handle)
-{
-	struct acpi_object_list *obj_list;
-
-	if (arch_has_acpi_pdc() == false)
-		return;
-
-	if (early_pdc_done)
-		return;
-
-	obj_list = acpi_processor_alloc_pdc();
-	if (!obj_list)
-		return;
-
-	acpi_processor_eval_pdc(handle, obj_list);
-
-	kfree(obj_list->pointer->buffer.pointer);
-	kfree(obj_list->pointer);
-	kfree(obj_list);
-}
-EXPORT_SYMBOL_GPL(acpi_processor_set_pdc);
-
-static int early_pdc_optin;
-static int set_early_pdc_optin(const struct dmi_system_id *id)
-{
-	early_pdc_optin = 1;
-	return 0;
-}
-
-static int param_early_pdc_optin(char *s)
-{
-	early_pdc_optin = 1;
-	return 1;
-}
-__setup("acpi_early_pdc_eval", param_early_pdc_optin);
-
-static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = {
-	{
-	set_early_pdc_optin, "HP Envy", {
-	DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"),
-	DMI_MATCH(DMI_PRODUCT_NAME, "HP Envy") }, NULL},
-	{
-	set_early_pdc_optin, "HP Pavilion dv6", {
-	DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"),
-	DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6") }, NULL},
-	{
-	set_early_pdc_optin, "HP Pavilion dv7", {
-	DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"),
-	DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7") }, NULL},
-	{},
-};
-
-static acpi_status
-early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-	acpi_processor_set_pdc(handle);
-	return AE_OK;
-}
-
-void __init acpi_early_processor_set_pdc(void)
-{
-	/*
-	 * Check whether the system is DMI table. If yes, OSPM
-	 * should not use mwait for CPU-states.
-	 */
-	dmi_check_system(processor_idle_dmi_table);
-
-	/*
-	 * Allow systems to opt-in to early _PDC evaluation.
-	 */
-	dmi_check_system(early_pdc_optin_table);
-	if (!early_pdc_optin)
-		return;
-
-	acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
-			    ACPI_UINT32_MAX,
-			    early_init_pdc, NULL, NULL, NULL);
-
-	early_pdc_done = 1;
-}
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/processor_perflib.c linux-libre-2.6.34-gnu1/drivers/acpi/processor_perflib.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/processor_perflib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/processor_perflib.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_X86
 #include <asm/cpufeature.h>
@@ -561,7 +562,7 @@ end:
 }
 
 int acpi_processor_preregister_performance(
-		struct acpi_processor_performance *performance)
+		struct acpi_processor_performance __percpu *performance)
 {
 	int count, count_target;
 	int retval = 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/processor_throttling.c linux-libre-2.6.34-gnu1/drivers/acpi/processor_throttling.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/processor_throttling.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/processor_throttling.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/cpufreq.h>
@@ -660,7 +661,7 @@ static int acpi_processor_get_throttling
 
 #ifdef CONFIG_X86
 static int acpi_throttling_rdmsr(struct acpi_processor *pr,
-					acpi_integer * value)
+					u64 *value)
 {
 	struct cpuinfo_x86 *c;
 	u64 msr_high, msr_low;
@@ -681,13 +682,13 @@ static int acpi_throttling_rdmsr(struct
 		rdmsr_safe(MSR_IA32_THERM_CONTROL,
 			(u32 *)&msr_low , (u32 *) &msr_high);
 		msr = (msr_high << 32) | msr_low;
-		*value = (acpi_integer) msr;
+		*value = (u64) msr;
 		ret = 0;
 	}
 	return ret;
 }
 
-static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value)
+static int acpi_throttling_wrmsr(struct acpi_processor *pr, u64 value)
 {
 	struct cpuinfo_x86 *c;
 	unsigned int cpu;
@@ -711,14 +712,14 @@ static int acpi_throttling_wrmsr(struct
 }
 #else
 static int acpi_throttling_rdmsr(struct acpi_processor *pr,
-				acpi_integer * value)
+				u64 *value)
 {
 	printk(KERN_ERR PREFIX
 		"HARDWARE addr space,NOT supported yet\n");
 	return -1;
 }
 
-static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value)
+static int acpi_throttling_wrmsr(struct acpi_processor *pr, u64 value)
 {
 	printk(KERN_ERR PREFIX
 		"HARDWARE addr space,NOT supported yet\n");
@@ -727,7 +728,7 @@ static int acpi_throttling_wrmsr(struct
 #endif
 
 static int acpi_read_throttling_status(struct acpi_processor *pr,
-					acpi_integer *value)
+					u64 *value)
 {
 	u32 bit_width, bit_offset;
 	u64 ptc_value;
@@ -746,7 +747,7 @@ static int acpi_read_throttling_status(s
 				  address, (u32 *) &ptc_value,
 				  (u32) (bit_width + bit_offset));
 		ptc_mask = (1 << bit_width) - 1;
-		*value = (acpi_integer) ((ptc_value >> bit_offset) & ptc_mask);
+		*value = (u64) ((ptc_value >> bit_offset) & ptc_mask);
 		ret = 0;
 		break;
 	case ACPI_ADR_SPACE_FIXED_HARDWARE:
@@ -760,7 +761,7 @@ static int acpi_read_throttling_status(s
 }
 
 static int acpi_write_throttling_state(struct acpi_processor *pr,
-				acpi_integer value)
+				u64 value)
 {
 	u32 bit_width, bit_offset;
 	u64 ptc_value;
@@ -793,7 +794,7 @@ static int acpi_write_throttling_state(s
 }
 
 static int acpi_get_throttling_state(struct acpi_processor *pr,
-				acpi_integer value)
+				u64 value)
 {
 	int i;
 
@@ -808,7 +809,7 @@ static int acpi_get_throttling_state(str
 }
 
 static int acpi_get_throttling_value(struct acpi_processor *pr,
-			int state, acpi_integer *value)
+			int state, u64 *value)
 {
 	int ret = -1;
 
@@ -826,7 +827,7 @@ static int acpi_processor_get_throttling
 {
 	int state = 0;
 	int ret;
-	acpi_integer value;
+	u64 value;
 
 	if (!pr)
 		return -EINVAL;
@@ -993,7 +994,7 @@ static int acpi_processor_set_throttling
 					     int state, bool force)
 {
 	int ret;
-	acpi_integer value;
+	u64 value;
 
 	if (!pr)
 		return -EINVAL;
@@ -1133,9 +1134,6 @@ int acpi_processor_get_throttling_info(s
 	int result = 0;
 	struct acpi_processor_throttling *pthrottling;
 
-	if (!pr)
-		return -EINVAL;
-
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			  "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
 			  pr->throttling.address,
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/sbs.c linux-libre-2.6.34-gnu1/drivers/acpi/sbs.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/sbs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/sbs.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
@@ -217,6 +218,9 @@ static int acpi_sbs_battery_get_property
 	case POWER_SUPPLY_PROP_TECHNOLOGY:
 		val->intval = acpi_battery_technology(battery);
 		break;
+	case POWER_SUPPLY_PROP_CYCLE_COUNT:
+		val->intval = battery->cycle_count;
+		break;
 	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
 		val->intval = battery->design_voltage *
 			acpi_battery_vscale(battery) * 1000;
@@ -276,6 +280,7 @@ static enum power_supply_property sbs_ch
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_CYCLE_COUNT,
 	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
@@ -560,6 +565,7 @@ static int acpi_battery_read_info(struct
 		   battery->design_voltage * acpi_battery_vscale(battery));
 	seq_printf(seq, "design capacity warning: unknown\n");
 	seq_printf(seq, "design capacity low:     unknown\n");
+	seq_printf(seq, "cycle count:		  %i\n", battery->cycle_count);
 	seq_printf(seq, "capacity granularity 1:  unknown\n");
 	seq_printf(seq, "capacity granularity 2:  unknown\n");
 	seq_printf(seq, "model number:            %s\n", battery->device_name);
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/sbshc.c linux-libre-2.6.34-gnu1/drivers/acpi/sbshc.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/sbshc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/sbshc.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,13 +11,14 @@
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include "sbshc.h"
 
 #define PREFIX "ACPI: "
 
-#define ACPI_SMB_HC_CLASS	"smbus_host_controller"
+#define ACPI_SMB_HC_CLASS	"smbus_host_ctl"
 #define ACPI_SMB_HC_DEVICE_NAME	"ACPI SMBus HC"
 
 struct acpi_smb_hc {
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/scan.c linux-libre-2.6.34-gnu1/drivers/acpi/scan.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/scan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/scan.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,10 +4,12 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/acpi.h>
 #include <linux/signal.h>
 #include <linux/kthread.h>
+#include <linux/dmi.h>
 
 #include <acpi/acpi_drivers.h>
 
@@ -741,19 +743,40 @@ acpi_bus_extract_wakeup_device_power_pac
 	return AE_OK;
 }
 
-static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
+static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
 {
-	acpi_status status = 0;
-	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-	union acpi_object *package = NULL;
-	int psw_error;
-
 	struct acpi_device_id button_device_ids[] = {
 		{"PNP0C0D", 0},
 		{"PNP0C0C", 0},
 		{"PNP0C0E", 0},
 		{"", 0},
 	};
+	acpi_status status;
+	acpi_event_status event_status;
+
+	device->wakeup.run_wake_count = 0;
+	device->wakeup.flags.notifier_present = 0;
+
+	/* Power button, Lid switch always enable wakeup */
+	if (!acpi_match_device_ids(device, button_device_ids)) {
+		device->wakeup.flags.run_wake = 1;
+		device->wakeup.flags.always_enabled = 1;
+		return;
+	}
+
+	status = acpi_get_gpe_status(NULL, device->wakeup.gpe_number,
+					ACPI_NOT_ISR, &event_status);
+	if (status == AE_OK)
+		device->wakeup.flags.run_wake =
+				!!(event_status & ACPI_EVENT_FLAG_HANDLE);
+}
+
+static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
+{
+	acpi_status status = 0;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *package = NULL;
+	int psw_error;
 
 	/* _PRW */
 	status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
@@ -773,6 +796,7 @@ static int acpi_bus_get_wakeup_device_fl
 
 	device->wakeup.flags.valid = 1;
 	device->wakeup.prepare_count = 0;
+	acpi_bus_set_run_wake_flags(device);
 	/* Call _PSW/_DSW object to disable its ability to wake the sleeping
 	 * system for the ACPI device with the _PRW object.
 	 * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
@@ -784,10 +808,6 @@ static int acpi_bus_get_wakeup_device_fl
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				"error in _DSW or _PSW evaluation\n"));
 
-	/* Power button, Lid switch always enable wakeup */
-	if (!acpi_match_device_ids(device, button_device_ids))
-		device->wakeup.flags.run_wake = 1;
-
 end:
 	if (ACPI_FAILURE(status))
 		device->flags.wake_capable = 0;
@@ -1014,6 +1034,41 @@ static void acpi_add_id(struct acpi_devi
 	list_add_tail(&id->list, &device->pnp.ids);
 }
 
+/*
+ * Old IBM workstations have a DSDT bug wherein the SMBus object
+ * lacks the SMBUS01 HID and the methods do not have the necessary "_"
+ * prefix.  Work around this.
+ */
+static int acpi_ibm_smbus_match(struct acpi_device *device)
+{
+	acpi_handle h_dummy;
+	struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
+	int result;
+
+	if (!dmi_name_in_vendors("IBM"))
+		return -ENODEV;
+
+	/* Look for SMBS object */
+	result = acpi_get_name(device->handle, ACPI_SINGLE_NAME, &path);
+	if (result)
+		return result;
+
+	if (strcmp("SMBS", path.pointer)) {
+		result = -ENODEV;
+		goto out;
+	}
+
+	/* Does it have the necessary (but misnamed) methods? */
+	result = -ENODEV;
+	if (ACPI_SUCCESS(acpi_get_handle(device->handle, "SBI", &h_dummy)) &&
+	    ACPI_SUCCESS(acpi_get_handle(device->handle, "SBR", &h_dummy)) &&
+	    ACPI_SUCCESS(acpi_get_handle(device->handle, "SBW", &h_dummy)))
+		result = 0;
+out:
+	kfree(path.pointer);
+	return result;
+}
+
 static void acpi_device_set_id(struct acpi_device *device)
 {
 	acpi_status status;
@@ -1026,12 +1081,6 @@ static void acpi_device_set_id(struct ac
 		if (ACPI_IS_ROOT_DEVICE(device)) {
 			acpi_add_id(device, ACPI_SYSTEM_HID);
 			break;
-		} else if (ACPI_IS_ROOT_DEVICE(device->parent)) {
-			/* \_SB_, the only root-level namespace device */
-			acpi_add_id(device, ACPI_BUS_HID);
-			strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
-			strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
-			break;
 		}
 
 		status = acpi_get_object_info(device->handle, &info);
@@ -1064,6 +1113,14 @@ static void acpi_device_set_id(struct ac
 			acpi_add_id(device, ACPI_BAY_HID);
 		else if (ACPI_SUCCESS(acpi_dock_match(device)))
 			acpi_add_id(device, ACPI_DOCK_HID);
+		else if (!acpi_ibm_smbus_match(device))
+			acpi_add_id(device, ACPI_SMBUS_IBM_HID);
+		else if (!acpi_device_hid(device) &&
+			 ACPI_IS_ROOT_DEVICE(device->parent)) {
+			acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */
+			strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
+			strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
+		}
 
 		break;
 	case ACPI_BUS_TYPE_POWER:
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/sleep.c linux-libre-2.6.34-gnu1/drivers/acpi/sleep.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/sleep.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/sleep.c	2010-05-16 17:17:36.000000000 -0400
@@ -450,6 +450,38 @@ static struct dmi_system_id __initdata a
 		},
 	},
 	{
+	.callback = init_set_sci_en_on_resume,
+	.ident = "Lenovo ThinkPad T410",
+	.matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T410"),
+		},
+	},
+	{
+	.callback = init_set_sci_en_on_resume,
+	.ident = "Lenovo ThinkPad T510",
+	.matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T510"),
+		},
+	},
+	{
+	.callback = init_set_sci_en_on_resume,
+	.ident = "Lenovo ThinkPad W510",
+	.matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W510"),
+		},
+	},
+	{
+	.callback = init_set_sci_en_on_resume,
+	.ident = "Lenovo ThinkPad X201[s]",
+	.matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201"),
+		},
+	},
+	{
 	.callback = init_old_suspend_ordering,
 	.ident = "Panasonic CF51-2L",
 	.matches = {
@@ -458,6 +490,30 @@ static struct dmi_system_id __initdata a
 		DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
 		},
 	},
+	{
+	.callback = init_set_sci_en_on_resume,
+	.ident = "Dell Studio 1558",
+	.matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+		DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1558"),
+		},
+	},
+	{
+	.callback = init_set_sci_en_on_resume,
+	.ident = "Dell Studio 1557",
+	.matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+		DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1557"),
+		},
+	},
+	{
+	.callback = init_set_sci_en_on_resume,
+	.ident = "Dell Studio 1555",
+	.matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+		DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1555"),
+		},
+	},
 	{},
 };
 #endif /* CONFIG_SUSPEND */
@@ -552,8 +608,17 @@ static void acpi_hibernation_leave(void)
 	hibernate_nvs_restore();
 }
 
-static void acpi_pm_enable_gpes(void)
+static int acpi_pm_pre_restore(void)
 {
+	acpi_disable_all_gpes();
+	acpi_os_wait_events_complete(NULL);
+	acpi_ec_suspend_transactions();
+	return 0;
+}
+
+static void acpi_pm_restore_cleanup(void)
+{
+	acpi_ec_resume_transactions();
 	acpi_enable_all_runtime_gpes();
 }
 
@@ -565,8 +630,8 @@ static struct platform_hibernation_ops a
 	.prepare = acpi_pm_prepare,
 	.enter = acpi_hibernation_enter,
 	.leave = acpi_hibernation_leave,
-	.pre_restore = acpi_pm_disable_gpes,
-	.restore_cleanup = acpi_pm_enable_gpes,
+	.pre_restore = acpi_pm_pre_restore,
+	.restore_cleanup = acpi_pm_restore_cleanup,
 };
 
 /**
@@ -618,8 +683,8 @@ static struct platform_hibernation_ops a
 	.prepare = acpi_pm_disable_gpes,
 	.enter = acpi_hibernation_enter,
 	.leave = acpi_hibernation_leave,
-	.pre_restore = acpi_pm_disable_gpes,
-	.restore_cleanup = acpi_pm_enable_gpes,
+	.pre_restore = acpi_pm_pre_restore,
+	.restore_cleanup = acpi_pm_restore_cleanup,
 	.recover = acpi_pm_finish,
 };
 #endif /* CONFIG_HIBERNATION */
@@ -745,9 +810,18 @@ int acpi_pm_device_sleep_wake(struct dev
 		return -ENODEV;
 	}
 
-	error = enable ?
-		acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) :
-		acpi_disable_wakeup_device_power(adev);
+	if (enable) {
+		error = acpi_enable_wakeup_device_power(adev,
+						acpi_target_sleep_state);
+		if (!error)
+			acpi_enable_gpe(adev->wakeup.gpe_device,
+					adev->wakeup.gpe_number,
+					ACPI_GPE_TYPE_WAKE);
+	} else {
+		acpi_disable_gpe(adev->wakeup.gpe_device, adev->wakeup.gpe_number,
+				ACPI_GPE_TYPE_WAKE);
+		error = acpi_disable_wakeup_device_power(adev);
+	}
 	if (!error)
 		dev_info(dev, "wake-up capability %s by ACPI\n",
 				enable ? "enabled" : "disabled");
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/system.c linux-libre-2.6.34-gnu1/drivers/acpi/system.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/system.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/system.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/string.h>
 #include <asm/uaccess.h>
@@ -101,6 +102,7 @@ static void acpi_table_attr_init(struct
 	struct acpi_table_header *header = NULL;
 	struct acpi_table_attr *attr = NULL;
 
+	sysfs_attr_init(&table_attr->attr.attr);
 	if (table_header->signature[0] != '\0')
 		memcpy(table_attr->name, table_header->signature,
 			ACPI_NAME_SIZE);
@@ -387,10 +389,10 @@ static ssize_t counter_set(struct kobjec
 	if (index < num_gpes) {
 		if (!strcmp(buf, "disable\n") &&
 				(status & ACPI_EVENT_FLAG_ENABLED))
-			result = acpi_disable_gpe(handle, index);
+			result = acpi_set_gpe(handle, index, ACPI_GPE_DISABLE);
 		else if (!strcmp(buf, "enable\n") &&
 				!(status & ACPI_EVENT_FLAG_ENABLED))
-			result = acpi_enable_gpe(handle, index);
+			result = acpi_set_gpe(handle, index, ACPI_GPE_ENABLE);
 		else if (!strcmp(buf, "clear\n") &&
 				(status & ACPI_EVENT_FLAG_SET))
 			result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR);
@@ -475,6 +477,7 @@ void acpi_irq_stats_init(void)
 			goto fail;
 		strncpy(name, buffer, strlen(buffer) + 1);
 
+		sysfs_attr_init(&counter_attrs[i].attr);
 		counter_attrs[i].attr.name = name;
 		counter_attrs[i].attr.mode = 0644;
 		counter_attrs[i].show = counter_show;
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/thermal.c linux-libre-2.6.34-gnu1/drivers/acpi/thermal.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/thermal.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/thermal.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/module.h>
 #include <linux/dmi.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/jiffies.h>
@@ -368,7 +369,7 @@ static int acpi_thermal_trips_update(str
 	int valid = 0;
 	int i;
 
-	/* Critical Shutdown (required) */
+	/* Critical Shutdown */
 	if (flag & ACPI_TRIPS_CRITICAL) {
 		status = acpi_evaluate_integer(tz->device->handle,
 				"_CRT", NULL, &tmp);
@@ -379,17 +380,19 @@ static int acpi_thermal_trips_update(str
 		 * Below zero (Celsius) values clearly aren't right for sure..
 		 * ... so lets discard those as invalid.
 		 */
-		if (ACPI_FAILURE(status) ||
-				tz->trips.critical.temperature <= 2732) {
+		if (ACPI_FAILURE(status)) {
+			tz->trips.critical.flags.valid = 0;
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					  "No critical threshold\n"));
+		} else if (tmp <= 2732) {
+			printk(KERN_WARNING FW_BUG "Invalid critical threshold "
+			       "(%llu)\n", tmp);
 			tz->trips.critical.flags.valid = 0;
-			ACPI_EXCEPTION((AE_INFO, status,
-					"No or invalid critical threshold"));
-			return -ENODEV;
 		} else {
 			tz->trips.critical.flags.valid = 1;
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-					"Found critical threshold [%lu]\n",
-					tz->trips.critical.temperature));
+					  "Found critical threshold [%lu]\n",
+					  tz->trips.critical.temperature));
 		}
 		if (tz->trips.critical.flags.valid == 1) {
 			if (crt == -1) {
@@ -575,7 +578,23 @@ static int acpi_thermal_trips_update(str
 
 static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
 {
-	return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
+	int i, valid, ret = acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
+
+	if (ret)
+		return ret;
+
+	valid = tz->trips.critical.flags.valid |
+		tz->trips.hot.flags.valid |
+		tz->trips.passive.flags.valid;
+
+	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
+		valid |= tz->trips.active[i].flags.valid;
+
+	if (!valid) {
+		printk(KERN_WARNING FW_BUG "No valid trip found\n");
+		return -ENODEV;
+	}
+	return 0;
 }
 
 static void acpi_thermal_check(void *data)
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/utils.c linux-libre-2.6.34-gnu1/drivers/acpi/utils.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/utils.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/utils.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <acpi/acpi_bus.h>
@@ -107,12 +108,12 @@ acpi_extract_package(union acpi_object *
 		case ACPI_TYPE_INTEGER:
 			switch (format_string[i]) {
 			case 'N':
-				size_required += sizeof(acpi_integer);
-				tail_offset += sizeof(acpi_integer);
+				size_required += sizeof(u64);
+				tail_offset += sizeof(u64);
 				break;
 			case 'S':
 				size_required +=
-				    sizeof(char *) + sizeof(acpi_integer) +
+				    sizeof(char *) + sizeof(u64) +
 				    sizeof(char);
 				tail_offset += sizeof(char *);
 				break;
@@ -193,17 +194,17 @@ acpi_extract_package(union acpi_object *
 		case ACPI_TYPE_INTEGER:
 			switch (format_string[i]) {
 			case 'N':
-				*((acpi_integer *) head) =
+				*((u64 *) head) =
 				    element->integer.value;
-				head += sizeof(acpi_integer);
+				head += sizeof(u64);
 				break;
 			case 'S':
 				pointer = (u8 **) head;
 				*pointer = tail;
-				*((acpi_integer *) tail) =
+				*((u64 *) tail) =
 				    element->integer.value;
-				head += sizeof(acpi_integer *);
-				tail += sizeof(acpi_integer);
+				head += sizeof(u64 *);
+				tail += sizeof(u64);
 				/* NULL terminate string */
 				*tail = (char)0;
 				tail += sizeof(char);
@@ -289,51 +290,6 @@ acpi_evaluate_integer(acpi_handle handle
 
 EXPORT_SYMBOL(acpi_evaluate_integer);
 
-#if 0
-acpi_status
-acpi_evaluate_string(acpi_handle handle,
-		     acpi_string pathname,
-		     acpi_object_list * arguments, acpi_string * data)
-{
-	acpi_status status = AE_OK;
-	acpi_object *element = NULL;
-	acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-
-
-	if (!data)
-		return AE_BAD_PARAMETER;
-
-	status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
-	if (ACPI_FAILURE(status)) {
-		acpi_util_eval_error(handle, pathname, status);
-		return status;
-	}
-
-	element = (acpi_object *) buffer.pointer;
-
-	if ((element->type != ACPI_TYPE_STRING)
-	    || (element->type != ACPI_TYPE_BUFFER)
-	    || !element->string.length) {
-		acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
-		return AE_BAD_DATA;
-	}
-
-	*data = kzalloc(element->string.length + 1, GFP_KERNEL);
-	if (!data) {
-		printk(KERN_ERR PREFIX "Memory allocation\n");
-		return -ENOMEM;
-	}
-
-	memcpy(*data, element->string.pointer, element->string.length);
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%s]\n", *data));
-
-	kfree(buffer.pointer);
-
-	return AE_OK;
-}
-#endif
-
 acpi_status
 acpi_evaluate_reference(acpi_handle handle,
 			acpi_string pathname,
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/video.c linux-libre-2.6.34-gnu1/drivers/acpi/video.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/video.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/video.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,10 +39,12 @@
 #include <linux/sort.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/dmi.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
+#include <linux/suspend.h>
 
 #define PREFIX "ACPI: "
 
@@ -88,7 +90,6 @@ module_param(allow_duplicates, bool, 064
 static int register_count = 0;
 static int acpi_video_bus_add(struct acpi_device *device);
 static int acpi_video_bus_remove(struct acpi_device *device, int type);
-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[] = {
@@ -104,7 +105,6 @@ static struct acpi_driver acpi_video_bus
 	.ops = {
 		.add = acpi_video_bus_add,
 		.remove = acpi_video_bus_remove,
-		.resume = acpi_video_resume,
 		.notify = acpi_video_bus_notify,
 		},
 };
@@ -159,6 +159,7 @@ struct acpi_video_bus {
 	struct proc_dir_entry *dir;
 	struct input_dev *input;
 	char phys[32];	/* for input device */
+	struct notifier_block pm_nb;
 };
 
 struct acpi_video_device_flags {
@@ -327,7 +328,7 @@ static int acpi_video_device_lcd_set_lev
 			int level);
 static int acpi_video_device_lcd_get_level_current(
 			struct acpi_video_device *device,
-			unsigned long long *level);
+			unsigned long long *level, int init);
 static int acpi_video_get_next_level(struct acpi_video_device *device,
 				     u32 level_current, u32 event);
 static int acpi_video_switch_brightness(struct acpi_video_device *device,
@@ -345,7 +346,7 @@ static int acpi_video_get_brightness(str
 	struct acpi_video_device *vd =
 		(struct acpi_video_device *)bl_get_data(bd);
 
-	if (acpi_video_device_lcd_get_level_current(vd, &cur_level))
+	if (acpi_video_device_lcd_get_level_current(vd, &cur_level, 0))
 		return -EINVAL;
 	for (i = 2; i < vd->brightness->count; i++) {
 		if (vd->brightness->levels[i] == cur_level)
@@ -414,7 +415,7 @@ static int video_get_cur_state(struct th
 	unsigned long long level;
 	int offset;
 
-	if (acpi_video_device_lcd_get_level_current(video, &level))
+	if (acpi_video_device_lcd_get_level_current(video, &level, 0))
 		return -EINVAL;
 	for (offset = 2; offset < video->brightness->count; offset++)
 		if (level == video->brightness->levels[offset]) {
@@ -609,7 +610,7 @@ static struct dmi_system_id video_dmi_ta
 
 static int
 acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
-					unsigned long long *level)
+					unsigned long long *level, int init)
 {
 	acpi_status status = AE_OK;
 	int i;
@@ -633,10 +634,16 @@ acpi_video_device_lcd_get_level_current(
 					device->brightness->curr = *level;
 					return 0;
 			}
-			/* BQC returned an invalid level. Stop using it.  */
-			ACPI_WARNING((AE_INFO, "%s returned an invalid level",
-						buf));
-			device->cap._BQC = device->cap._BCQ = 0;
+			if (!init) {
+				/*
+				 * BQC returned an invalid level.
+				 * Stop using it.
+				 */
+				ACPI_WARNING((AE_INFO,
+					      "%s returned an invalid level",
+					      buf));
+				device->cap._BQC = device->cap._BCQ = 0;
+			}
 		} else {
 			/* Fixme:
 			 * should we return an error or ignore this failure?
@@ -759,7 +766,7 @@ acpi_video_bus_POST_options(struct acpi_
 static int
 acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
 {
-	acpi_integer status = 0;
+	u64 status = 0;
 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 	struct acpi_object_list args = { 1, &arg0 };
 
@@ -892,7 +899,7 @@ acpi_video_init_brightness(struct acpi_v
 	if (!device->cap._BQC)
 		goto set_level;
 
-	result = acpi_video_device_lcd_get_level_current(device, &level_old);
+	result = acpi_video_device_lcd_get_level_current(device, &level_old, 1);
 	if (result)
 		goto out_free_levels;
 
@@ -903,7 +910,7 @@ acpi_video_init_brightness(struct acpi_v
 	if (result)
 		goto out_free_levels;
 
-	result = acpi_video_device_lcd_get_level_current(device, &level);
+	result = acpi_video_device_lcd_get_level_current(device, &level, 0);
 	if (result)
 		goto out_free_levels;
 
@@ -992,6 +999,7 @@ static void acpi_video_device_find_cap(s
 	}
 
 	if (acpi_video_backlight_support()) {
+		struct backlight_properties props;
 		int result;
 		static int count = 0;
 		char *name;
@@ -1004,12 +1012,21 @@ static void acpi_video_device_find_cap(s
 			return;
 
 		sprintf(name, "acpi_video%d", count++);
-		device->backlight = backlight_device_register(name,
-			NULL, device, &acpi_backlight_ops);
+		memset(&props, 0, sizeof(struct backlight_properties));
+		props.max_brightness = device->brightness->count - 3;
+		device->backlight = backlight_device_register(name, NULL, device,
+							      &acpi_backlight_ops,
+							      &props);
 		kfree(name);
 		if (IS_ERR(device->backlight))
 			return;
-		device->backlight->props.max_brightness = device->brightness->count-3;
+
+		/*
+		 * Save current brightness level in case we have to restore it
+		 * before acpi_video_device_lcd_set_level() is called next time.
+		 */
+		device->backlight->props.brightness =
+				acpi_video_get_brightness(device->backlight);
 
 		result = sysfs_create_link(&device->backlight->dev.kobj,
 					   &device->dev->dev.kobj, "device");
@@ -1996,7 +2013,7 @@ acpi_video_switch_brightness(struct acpi
 		goto out;
 
 	result = acpi_video_device_lcd_get_level_current(device,
-							 &level_current);
+							 &level_current, 0);
 	if (result)
 		goto out;
 
@@ -2113,7 +2130,7 @@ static void acpi_video_bus_notify(struct
 {
 	struct acpi_video_bus *video = acpi_driver_data(device);
 	struct input_dev *input;
-	int keycode;
+	int keycode = 0;
 
 	if (!video)
 		return;
@@ -2149,17 +2166,19 @@ static void acpi_video_bus_notify(struct
 		break;
 
 	default:
-		keycode = KEY_UNKNOWN;
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Unsupported event [0x%x]\n", event));
 		break;
 	}
 
 	acpi_notifier_call_chain(device, event, 0);
-	input_report_key(input, keycode, 1);
-	input_sync(input);
-	input_report_key(input, keycode, 0);
-	input_sync(input);
+
+	if (keycode) {
+		input_report_key(input, keycode, 1);
+		input_sync(input);
+		input_report_key(input, keycode, 0);
+		input_sync(input);
+	}
 
 	return;
 }
@@ -2170,7 +2189,7 @@ static void acpi_video_device_notify(acp
 	struct acpi_device *device = NULL;
 	struct acpi_video_bus *bus;
 	struct input_dev *input;
-	int keycode;
+	int keycode = 0;
 
 	if (!video_device)
 		return;
@@ -2211,39 +2230,48 @@ static void acpi_video_device_notify(acp
 		keycode = KEY_DISPLAY_OFF;
 		break;
 	default:
-		keycode = KEY_UNKNOWN;
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Unsupported event [0x%x]\n", event));
 		break;
 	}
 
 	acpi_notifier_call_chain(device, event, 0);
-	input_report_key(input, keycode, 1);
-	input_sync(input);
-	input_report_key(input, keycode, 0);
-	input_sync(input);
+
+	if (keycode) {
+		input_report_key(input, keycode, 1);
+		input_sync(input);
+		input_report_key(input, keycode, 0);
+		input_sync(input);
+	}
 
 	return;
 }
 
-static int instance;
-static int acpi_video_resume(struct acpi_device *device)
+static int acpi_video_resume(struct notifier_block *nb,
+				unsigned long val, void *ign)
 {
 	struct acpi_video_bus *video;
 	struct acpi_video_device *video_device;
 	int i;
 
-	if (!device || !acpi_driver_data(device))
-		return -EINVAL;
+	switch (val) {
+	case PM_HIBERNATION_PREPARE:
+	case PM_SUSPEND_PREPARE:
+	case PM_RESTORE_PREPARE:
+		return NOTIFY_DONE;
+	}
 
-	video = acpi_driver_data(device);
+	video = container_of(nb, struct acpi_video_bus, pm_nb);
+
+	dev_info(&video->device->dev, "Restoring backlight state\n");
 
 	for (i = 0; i < video->attached_count; i++) {
 		video_device = video->attached_array[i].bind_info;
 		if (video_device && video_device->backlight)
 			acpi_video_set_brightness(video_device->backlight);
 	}
-	return AE_OK;
+
+	return NOTIFY_OK;
 }
 
 static acpi_status
@@ -2267,6 +2295,8 @@ acpi_video_bus_match(acpi_handle handle,
 	return AE_OK;
 }
 
+static int instance;
+
 static int acpi_video_bus_add(struct acpi_device *device)
 {
 	struct acpi_video_bus *video;
@@ -2348,7 +2378,6 @@ static int acpi_video_bus_add(struct acp
 	set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
 	set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
 	set_bit(KEY_DISPLAY_OFF, input->keybit);
-	set_bit(KEY_UNKNOWN, input->keybit);
 
 	error = input_register_device(input);
 	if (error)
@@ -2360,6 +2389,10 @@ static int acpi_video_bus_add(struct acp
 	       video->flags.rom ? "yes" : "no",
 	       video->flags.post ? "yes" : "no");
 
+	video->pm_nb.notifier_call = acpi_video_resume;
+	video->pm_nb.priority = 0;
+	register_pm_notifier(&video->pm_nb);
+
 	return 0;
 
  err_free_input_dev:
@@ -2386,6 +2419,8 @@ static int acpi_video_bus_remove(struct
 
 	video = acpi_driver_data(device);
 
+	unregister_pm_notifier(&video->pm_nb);
+
 	acpi_video_bus_stop_devices(video);
 	acpi_video_bus_put_devices(video);
 	acpi_video_bus_remove_fs(device);
diff -druNp linux-libre-2.6.33-gnu1/drivers/acpi/wakeup.c linux-libre-2.6.34-gnu1/drivers/acpi/wakeup.c
--- linux-libre-2.6.33-gnu1/drivers/acpi/wakeup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/acpi/wakeup.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,12 +21,12 @@
 ACPI_MODULE_NAME("wakeup_devices")
 
 /**
- * acpi_enable_wakeup_device_prep - prepare wakeup devices
- *	@sleep_state:	ACPI state
- * Enable all wakup devices power if the devices' wakeup level
- * is higher than requested sleep level
+ * acpi_enable_wakeup_device_prep - Prepare wake-up devices.
+ * @sleep_state: ACPI system sleep state.
+ *
+ * Enable all wake-up devices' power, unless the requested system sleep state is
+ * too deep.
  */
-
 void acpi_enable_wakeup_device_prep(u8 sleep_state)
 {
 	struct list_head *node, *next;
@@ -36,9 +36,8 @@ void acpi_enable_wakeup_device_prep(u8 s
 						       struct acpi_device,
 						       wakeup_list);
 
-		if (!dev->wakeup.flags.valid ||
-		    !dev->wakeup.state.enabled ||
-		    (sleep_state > (u32) dev->wakeup.sleep_state))
+		if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled
+		    || (sleep_state > (u32) dev->wakeup.sleep_state))
 			continue;
 
 		acpi_enable_wakeup_device_power(dev, sleep_state);
@@ -46,9 +45,12 @@ void acpi_enable_wakeup_device_prep(u8 s
 }
 
 /**
- * acpi_enable_wakeup_device - enable wakeup devices
- *	@sleep_state:	ACPI state
- * Enable all wakup devices's GPE
+ * acpi_enable_wakeup_device - Enable wake-up device GPEs.
+ * @sleep_state: ACPI system sleep state.
+ *
+ * Enable all wake-up devices' GPEs, with the assumption that
+ * acpi_disable_all_gpes() was executed before, so we don't need to disable any
+ * GPEs here.
  */
 void acpi_enable_wakeup_device(u8 sleep_state)
 {
@@ -65,29 +67,22 @@ void acpi_enable_wakeup_device(u8 sleep_
 		if (!dev->wakeup.flags.valid)
 			continue;
 
-		/* If users want to disable run-wake GPE,
-		 * we only disable it for wake and leave it for runtime
-		 */
 		if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count)
-		    || sleep_state > (u32) dev->wakeup.sleep_state) {
-			if (dev->wakeup.flags.run_wake) {
-				/* 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);
-			}
+		    || sleep_state > (u32) dev->wakeup.sleep_state)
 			continue;
-		}
-		if (!dev->wakeup.flags.run_wake)
-			acpi_enable_gpe(dev->wakeup.gpe_device,
-					dev->wakeup.gpe_number);
+
+		/* The wake-up power should have been enabled already. */
+		acpi_set_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
+				ACPI_GPE_ENABLE);
 	}
 }
 
 /**
- * acpi_disable_wakeup_device - disable devices' wakeup capability
- *	@sleep_state:	ACPI state
- * Disable all wakup devices's GPE and wakeup capability
+ * acpi_disable_wakeup_device - Disable devices' wakeup capability.
+ * @sleep_state: ACPI system sleep state.
+ *
+ * This function only affects devices with wakeup.state.enabled set, which means
+ * that it reverses the changes made by acpi_enable_wakeup_device_prep().
  */
 void acpi_disable_wakeup_device(u8 sleep_state)
 {
@@ -97,30 +92,11 @@ void acpi_disable_wakeup_device(u8 sleep
 		struct acpi_device *dev =
 			container_of(node, struct acpi_device, wakeup_list);
 
-		if (!dev->wakeup.flags.valid)
-			continue;
-
-		if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count)
-		    || sleep_state > (u32) dev->wakeup.sleep_state) {
-			if (dev->wakeup.flags.run_wake) {
-				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);
-			}
+		if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled
+		    || (sleep_state > (u32) dev->wakeup.sleep_state))
 			continue;
-		}
 
 		acpi_disable_wakeup_device_power(dev);
-		/* Never disable run-wake GPE */
-		if (!dev->wakeup.flags.run_wake) {
-			acpi_disable_gpe(dev->wakeup.gpe_device,
-					 dev->wakeup.gpe_number);
-			acpi_clear_gpe(dev->wakeup.gpe_device,
-				       dev->wakeup.gpe_number, ACPI_NOT_ISR);
-		}
 	}
 }
 
@@ -134,13 +110,11 @@ int __init acpi_wakeup_device_init(void)
 						       struct acpi_device,
 						       wakeup_list);
 		/* In case user doesn't load button driver */
-		if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
+		if (!dev->wakeup.flags.always_enabled ||
+		    dev->wakeup.state.enabled)
 			continue;
-		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);
+ 		acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
+ 				ACPI_GPE_TYPE_WAKE);
 		dev->wakeup.state.enabled = 1;
 	}
 	mutex_unlock(&acpi_device_lock);
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/ahci.c linux-libre-2.6.34-gnu1/drivers/ata/ahci.c
--- linux-libre-2.6.33-gnu1/drivers/ata/ahci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/ahci.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/device.h>
 #include <linux/dmi.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <linux/libata.h>
@@ -93,6 +94,9 @@ enum {
 	AHCI_CMD_TBL_AR_SZ	= AHCI_CMD_TBL_SZ * AHCI_MAX_CMDS,
 	AHCI_PORT_PRIV_DMA_SZ	= AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ +
 				  AHCI_RX_FIS_SZ,
+	AHCI_PORT_PRIV_FBS_DMA_SZ	= AHCI_CMD_SLOT_SZ +
+					  AHCI_CMD_TBL_AR_SZ +
+					  (AHCI_RX_FIS_SZ * 16),
 	AHCI_IRQ_ON_SG		= (1 << 31),
 	AHCI_CMD_ATAPI		= (1 << 5),
 	AHCI_CMD_WRITE		= (1 << 6),
@@ -170,6 +174,7 @@ enum {
 	PORT_SCR_ERR		= 0x30, /* SATA phy register: SError */
 	PORT_SCR_ACT		= 0x34, /* SATA phy register: SActive */
 	PORT_SCR_NTF		= 0x3c, /* SATA phy register: SNotification */
+	PORT_FBS		= 0x40, /* FIS-based Switching */
 
 	/* PORT_IRQ_{STAT,MASK} bits */
 	PORT_IRQ_COLD_PRES	= (1 << 31), /* cold presence detect */
@@ -208,6 +213,7 @@ enum {
 	PORT_CMD_ASP		= (1 << 27), /* Aggressive Slumber/Partial */
 	PORT_CMD_ALPE		= (1 << 26), /* Aggressive Link PM enable */
 	PORT_CMD_ATAPI		= (1 << 24), /* Device is ATAPI */
+	PORT_CMD_FBSCP		= (1 << 22), /* FBS Capable Port */
 	PORT_CMD_PMP		= (1 << 17), /* PMP attached */
 	PORT_CMD_LIST_ON	= (1 << 15), /* cmd list DMA engine running */
 	PORT_CMD_FIS_ON		= (1 << 14), /* FIS DMA engine running */
@@ -222,6 +228,14 @@ enum {
 	PORT_CMD_ICC_PARTIAL	= (0x2 << 28), /* Put i/f in partial state */
 	PORT_CMD_ICC_SLUMBER	= (0x6 << 28), /* Put i/f in slumber state */
 
+	PORT_FBS_DWE_OFFSET	= 16, /* FBS device with error offset */
+	PORT_FBS_ADO_OFFSET	= 12, /* FBS active dev optimization offset */
+	PORT_FBS_DEV_OFFSET	= 8,  /* FBS device to issue offset */
+	PORT_FBS_DEV_MASK	= (0xf << PORT_FBS_DEV_OFFSET),  /* FBS.DEV */
+	PORT_FBS_SDE		= (1 << 2), /* FBS single device error */
+	PORT_FBS_DEC		= (1 << 1), /* FBS device error clear */
+	PORT_FBS_EN		= (1 << 0), /* Enable FBS */
+
 	/* hpriv->flags bits */
 	AHCI_HFLAG_NO_NCQ		= (1 << 0),
 	AHCI_HFLAG_IGN_IRQ_IF_ERR	= (1 << 1), /* ignore IRQ_IF_ERR */
@@ -304,6 +318,9 @@ struct ahci_port_priv {
 	unsigned int		ncq_saw_dmas:1;
 	unsigned int		ncq_saw_sdb:1;
 	u32 			intr_mask;	/* interrupts to enable */
+	bool			fbs_supported;	/* set iff FBS is supported */
+	bool			fbs_enabled;	/* set iff FBS is enabled */
+	int			fbs_last_dev;	/* save FBS.DEV of last FIS */
 	/* enclosure management info per PM slot */
 	struct ahci_em_priv	em_priv[EM_MAX_SLOTS];
 };
@@ -315,9 +332,12 @@ static unsigned int ahci_qc_issue(struct
 static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc);
 static int ahci_port_start(struct ata_port *ap);
 static void ahci_port_stop(struct ata_port *ap);
+static int ahci_pmp_qc_defer(struct ata_queued_cmd *qc);
 static void ahci_qc_prep(struct ata_queued_cmd *qc);
 static void ahci_freeze(struct ata_port *ap);
 static void ahci_thaw(struct ata_port *ap);
+static void ahci_enable_fbs(struct ata_port *ap);
+static void ahci_disable_fbs(struct ata_port *ap);
 static void ahci_pmp_attach(struct ata_port *ap);
 static void ahci_pmp_detach(struct ata_port *ap);
 static int ahci_softreset(struct ata_link *link, unsigned int *class,
@@ -356,10 +376,10 @@ static ssize_t ahci_show_host_version(st
 static ssize_t ahci_show_port_cmd(struct device *dev,
 				  struct device_attribute *attr, char *buf);
 
-DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL);
-DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL);
-DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL);
-DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL);
+static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL);
+static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL);
+static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL);
+static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL);
 
 static struct device_attribute *ahci_shost_attrs[] = {
 	&dev_attr_link_power_management_policy,
@@ -390,7 +410,7 @@ static struct scsi_host_template ahci_sh
 static struct ata_port_operations ahci_ops = {
 	.inherits		= &sata_pmp_port_ops,
 
-	.qc_defer		= sata_pmp_qc_defer_cmd_switch,
+	.qc_defer		= ahci_pmp_qc_defer,
 	.qc_prep		= ahci_qc_prep,
 	.qc_issue		= ahci_qc_issue,
 	.qc_fill_rtf		= ahci_qc_fill_rtf,
@@ -570,6 +590,12 @@ static const struct pci_device_id ahci_p
 	{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
 	{ PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */
 	{ PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */
+	{ PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */
+	{ PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */
+	{ PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */
+	{ PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT RAID */
+	{ PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */
+	{ PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */
 
 	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
 	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -616,6 +642,21 @@ static const struct pci_device_id ahci_p
 	{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq },	/* MCP67 */
 	{ PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq },	/* MCP67 */
 	{ PCI_VDEVICE(NVIDIA, 0x0580), board_ahci_yesncq },	/* Linux ID */
+	{ PCI_VDEVICE(NVIDIA, 0x0581), board_ahci_yesncq },	/* Linux ID */
+	{ PCI_VDEVICE(NVIDIA, 0x0582), board_ahci_yesncq },	/* Linux ID */
+	{ PCI_VDEVICE(NVIDIA, 0x0583), board_ahci_yesncq },	/* Linux ID */
+	{ PCI_VDEVICE(NVIDIA, 0x0584), board_ahci_yesncq },	/* Linux ID */
+	{ PCI_VDEVICE(NVIDIA, 0x0585), board_ahci_yesncq },	/* Linux ID */
+	{ PCI_VDEVICE(NVIDIA, 0x0586), board_ahci_yesncq },	/* Linux ID */
+	{ PCI_VDEVICE(NVIDIA, 0x0587), board_ahci_yesncq },	/* Linux ID */
+	{ PCI_VDEVICE(NVIDIA, 0x0588), board_ahci_yesncq },	/* Linux ID */
+	{ PCI_VDEVICE(NVIDIA, 0x0589), board_ahci_yesncq },	/* Linux ID */
+	{ PCI_VDEVICE(NVIDIA, 0x058a), board_ahci_yesncq },	/* Linux ID */
+	{ PCI_VDEVICE(NVIDIA, 0x058b), board_ahci_yesncq },	/* Linux ID */
+	{ PCI_VDEVICE(NVIDIA, 0x058c), board_ahci_yesncq },	/* Linux ID */
+	{ PCI_VDEVICE(NVIDIA, 0x058d), board_ahci_yesncq },	/* Linux ID */
+	{ PCI_VDEVICE(NVIDIA, 0x058e), board_ahci_yesncq },	/* Linux ID */
+	{ PCI_VDEVICE(NVIDIA, 0x058f), board_ahci_yesncq },	/* Linux ID */
 	{ PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq },	/* MCP73 */
 	{ PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq },	/* MCP73 */
 	{ PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq },	/* MCP73 */
@@ -2045,6 +2086,17 @@ static unsigned int ahci_fill_sg(struct
 	return si;
 }
 
+static int ahci_pmp_qc_defer(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct ahci_port_priv *pp = ap->private_data;
+
+	if (!sata_pmp_attached(ap) || pp->fbs_enabled)
+		return ata_std_qc_defer(qc);
+	else
+		return sata_pmp_qc_defer_cmd_switch(qc);
+}
+
 static void ahci_qc_prep(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
@@ -2083,6 +2135,31 @@ static void ahci_qc_prep(struct ata_queu
 	ahci_fill_cmd_slot(pp, qc->tag, opts);
 }
 
+static void ahci_fbs_dec_intr(struct ata_port *ap)
+{
+	struct ahci_port_priv *pp = ap->private_data;
+	void __iomem *port_mmio = ahci_port_base(ap);
+	u32 fbs = readl(port_mmio + PORT_FBS);
+	int retries = 3;
+
+	DPRINTK("ENTER\n");
+	BUG_ON(!pp->fbs_enabled);
+
+	/* time to wait for DEC is not specified by AHCI spec,
+	 * add a retry loop for safety.
+	 */
+	writel(fbs | PORT_FBS_DEC, port_mmio + PORT_FBS);
+	fbs = readl(port_mmio + PORT_FBS);
+	while ((fbs & PORT_FBS_DEC) && retries--) {
+		udelay(1);
+		fbs = readl(port_mmio + PORT_FBS);
+	}
+
+	if (fbs & PORT_FBS_DEC)
+		dev_printk(KERN_ERR, ap->host->dev,
+			   "failed to clear device error\n");
+}
+
 static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
 {
 	struct ahci_host_priv *hpriv = ap->host->private_data;
@@ -2091,12 +2168,26 @@ static void ahci_error_intr(struct ata_p
 	struct ata_link *link = NULL;
 	struct ata_queued_cmd *active_qc;
 	struct ata_eh_info *active_ehi;
+	bool fbs_need_dec = false;
 	u32 serror;
 
-	/* determine active link */
-	ata_for_each_link(link, ap, EDGE)
-		if (ata_link_active(link))
-			break;
+	/* determine active link with error */
+	if (pp->fbs_enabled) {
+		void __iomem *port_mmio = ahci_port_base(ap);
+		u32 fbs = readl(port_mmio + PORT_FBS);
+		int pmp = fbs >> PORT_FBS_DWE_OFFSET;
+
+		if ((fbs & PORT_FBS_SDE) && (pmp < ap->nr_pmp_links) &&
+		    ata_link_online(&ap->pmp_link[pmp])) {
+			link = &ap->pmp_link[pmp];
+			fbs_need_dec = true;
+		}
+
+	} else
+		ata_for_each_link(link, ap, EDGE)
+			if (ata_link_active(link))
+				break;
+
 	if (!link)
 		link = &ap->link;
 
@@ -2153,8 +2244,13 @@ static void ahci_error_intr(struct ata_p
 	}
 
 	if (irq_stat & PORT_IRQ_IF_ERR) {
-		host_ehi->err_mask |= AC_ERR_ATA_BUS;
-		host_ehi->action |= ATA_EH_RESET;
+		if (fbs_need_dec)
+			active_ehi->err_mask |= AC_ERR_DEV;
+		else {
+			host_ehi->err_mask |= AC_ERR_ATA_BUS;
+			host_ehi->action |= ATA_EH_RESET;
+		}
+
 		ata_ehi_push_desc(host_ehi, "interface fatal error");
 	}
 
@@ -2169,7 +2265,10 @@ static void ahci_error_intr(struct ata_p
 
 	if (irq_stat & PORT_IRQ_FREEZE)
 		ata_port_freeze(ap);
-	else
+	else if (fbs_need_dec) {
+		ata_link_abort(link);
+		ahci_fbs_dec_intr(ap);
+	} else
 		ata_port_abort(ap);
 }
 
@@ -2180,7 +2279,7 @@ static void ahci_port_intr(struct ata_po
 	struct ahci_port_priv *pp = ap->private_data;
 	struct ahci_host_priv *hpriv = ap->host->private_data;
 	int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING);
-	u32 status, qc_active;
+	u32 status, qc_active = 0;
 	int rc;
 
 	status = readl(port_mmio + PORT_IRQ_STAT);
@@ -2222,20 +2321,38 @@ static void ahci_port_intr(struct ata_po
 			/* If the 'N' bit in word 0 of the FIS is set,
 			 * we just received asynchronous notification.
 			 * Tell libata about it.
+			 *
+			 * Lack of SNotification should not appear in
+			 * ahci 1.2, so the workaround is unnecessary
+			 * when FBS is enabled.
 			 */
-			const __le32 *f = pp->rx_fis + RX_FIS_SDB;
-			u32 f0 = le32_to_cpu(f[0]);
-
-			if (f0 & (1 << 15))
-				sata_async_notification(ap);
+			if (pp->fbs_enabled)
+				WARN_ON_ONCE(1);
+			else {
+				const __le32 *f = pp->rx_fis + RX_FIS_SDB;
+				u32 f0 = le32_to_cpu(f[0]);
+				if (f0 & (1 << 15))
+					sata_async_notification(ap);
+			}
 		}
 	}
 
-	/* pp->active_link is valid iff any command is in flight */
-	if (ap->qc_active && pp->active_link->sactive)
-		qc_active = readl(port_mmio + PORT_SCR_ACT);
-	else
-		qc_active = readl(port_mmio + PORT_CMD_ISSUE);
+	/* pp->active_link is not reliable once FBS is enabled, both
+	 * PORT_SCR_ACT and PORT_CMD_ISSUE should be checked because
+	 * NCQ and non-NCQ commands may be in flight at the same time.
+	 */
+	if (pp->fbs_enabled) {
+		if (ap->qc_active) {
+			qc_active = readl(port_mmio + PORT_SCR_ACT);
+			qc_active |= readl(port_mmio + PORT_CMD_ISSUE);
+		}
+	} else {
+		/* pp->active_link is valid iff any command is in flight */
+		if (ap->qc_active && pp->active_link->sactive)
+			qc_active = readl(port_mmio + PORT_SCR_ACT);
+		else
+			qc_active = readl(port_mmio + PORT_CMD_ISSUE);
+	}
 
 	rc = ata_qc_complete_multiple(ap, qc_active);
 
@@ -2321,6 +2438,15 @@ static unsigned int ahci_qc_issue(struct
 
 	if (qc->tf.protocol == ATA_PROT_NCQ)
 		writel(1 << qc->tag, port_mmio + PORT_SCR_ACT);
+
+	if (pp->fbs_enabled && pp->fbs_last_dev != qc->dev->link->pmp) {
+		u32 fbs = readl(port_mmio + PORT_FBS);
+		fbs &= ~(PORT_FBS_DEV_MASK | PORT_FBS_DEC);
+		fbs |= qc->dev->link->pmp << PORT_FBS_DEV_OFFSET;
+		writel(fbs, port_mmio + PORT_FBS);
+		pp->fbs_last_dev = qc->dev->link->pmp;
+	}
+
 	writel(1 << qc->tag, port_mmio + PORT_CMD_ISSUE);
 
 	ahci_sw_activity(qc->dev->link);
@@ -2333,6 +2459,9 @@ static bool ahci_qc_fill_rtf(struct ata_
 	struct ahci_port_priv *pp = qc->ap->private_data;
 	u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
 
+	if (pp->fbs_enabled)
+		d2h_fis += qc->dev->link->pmp * AHCI_RX_FIS_SZ;
+
 	ata_tf_from_fis(d2h_fis, &qc->result_tf);
 	return true;
 }
@@ -2381,6 +2510,71 @@ static void ahci_post_internal_cmd(struc
 		ahci_kick_engine(ap);
 }
 
+static void ahci_enable_fbs(struct ata_port *ap)
+{
+	struct ahci_port_priv *pp = ap->private_data;
+	void __iomem *port_mmio = ahci_port_base(ap);
+	u32 fbs;
+	int rc;
+
+	if (!pp->fbs_supported)
+		return;
+
+	fbs = readl(port_mmio + PORT_FBS);
+	if (fbs & PORT_FBS_EN) {
+		pp->fbs_enabled = true;
+		pp->fbs_last_dev = -1; /* initialization */
+		return;
+	}
+
+	rc = ahci_stop_engine(ap);
+	if (rc)
+		return;
+
+	writel(fbs | PORT_FBS_EN, port_mmio + PORT_FBS);
+	fbs = readl(port_mmio + PORT_FBS);
+	if (fbs & PORT_FBS_EN) {
+		dev_printk(KERN_INFO, ap->host->dev, "FBS is enabled.\n");
+		pp->fbs_enabled = true;
+		pp->fbs_last_dev = -1; /* initialization */
+	} else
+		dev_printk(KERN_ERR, ap->host->dev, "Failed to enable FBS\n");
+
+	ahci_start_engine(ap);
+}
+
+static void ahci_disable_fbs(struct ata_port *ap)
+{
+	struct ahci_port_priv *pp = ap->private_data;
+	void __iomem *port_mmio = ahci_port_base(ap);
+	u32 fbs;
+	int rc;
+
+	if (!pp->fbs_supported)
+		return;
+
+	fbs = readl(port_mmio + PORT_FBS);
+	if ((fbs & PORT_FBS_EN) == 0) {
+		pp->fbs_enabled = false;
+		return;
+	}
+
+	rc = ahci_stop_engine(ap);
+	if (rc)
+		return;
+
+	writel(fbs & ~PORT_FBS_EN, port_mmio + PORT_FBS);
+	fbs = readl(port_mmio + PORT_FBS);
+	if (fbs & PORT_FBS_EN)
+		dev_printk(KERN_ERR, ap->host->dev, "Failed to disable FBS\n");
+	else {
+		dev_printk(KERN_INFO, ap->host->dev, "FBS is disabled.\n");
+		pp->fbs_enabled = false;
+	}
+
+	ahci_start_engine(ap);
+}
+
 static void ahci_pmp_attach(struct ata_port *ap)
 {
 	void __iomem *port_mmio = ahci_port_base(ap);
@@ -2391,6 +2585,8 @@ static void ahci_pmp_attach(struct ata_p
 	cmd |= PORT_CMD_PMP;
 	writel(cmd, port_mmio + PORT_CMD);
 
+	ahci_enable_fbs(ap);
+
 	pp->intr_mask |= PORT_IRQ_BAD_PMP;
 	writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
 }
@@ -2401,6 +2597,8 @@ static void ahci_pmp_detach(struct ata_p
 	struct ahci_port_priv *pp = ap->private_data;
 	u32 cmd;
 
+	ahci_disable_fbs(ap);
+
 	cmd = readl(port_mmio + PORT_CMD);
 	cmd &= ~PORT_CMD_PMP;
 	writel(cmd, port_mmio + PORT_CMD);
@@ -2492,20 +2690,40 @@ static int ahci_pci_device_resume(struct
 
 static int ahci_port_start(struct ata_port *ap)
 {
+	struct ahci_host_priv *hpriv = ap->host->private_data;
 	struct device *dev = ap->host->dev;
 	struct ahci_port_priv *pp;
 	void *mem;
 	dma_addr_t mem_dma;
+	size_t dma_sz, rx_fis_sz;
 
 	pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
 	if (!pp)
 		return -ENOMEM;
 
-	mem = dmam_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma,
-				  GFP_KERNEL);
+	/* check FBS capability */
+	if ((hpriv->cap & HOST_CAP_FBS) && sata_pmp_supported(ap)) {
+		void __iomem *port_mmio = ahci_port_base(ap);
+		u32 cmd = readl(port_mmio + PORT_CMD);
+		if (cmd & PORT_CMD_FBSCP)
+			pp->fbs_supported = true;
+		else
+			dev_printk(KERN_WARNING, dev,
+				   "The port is not capable of FBS\n");
+	}
+
+	if (pp->fbs_supported) {
+		dma_sz = AHCI_PORT_PRIV_FBS_DMA_SZ;
+		rx_fis_sz = AHCI_RX_FIS_SZ * 16;
+	} else {
+		dma_sz = AHCI_PORT_PRIV_DMA_SZ;
+		rx_fis_sz = AHCI_RX_FIS_SZ;
+	}
+
+	mem = dmam_alloc_coherent(dev, dma_sz, &mem_dma, GFP_KERNEL);
 	if (!mem)
 		return -ENOMEM;
-	memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);
+	memset(mem, 0, dma_sz);
 
 	/*
 	 * First item in chunk of DMA memory: 32-slot command table,
@@ -2523,8 +2741,8 @@ static int ahci_port_start(struct ata_po
 	pp->rx_fis = mem;
 	pp->rx_fis_dma = mem_dma;
 
-	mem += AHCI_RX_FIS_SZ;
-	mem_dma += AHCI_RX_FIS_SZ;
+	mem += rx_fis_sz;
+	mem_dma += rx_fis_sz;
 
 	/*
 	 * Third item: data area for storing a single command
@@ -2831,6 +3049,14 @@ static bool ahci_broken_suspend(struct p
 		 * 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.
+		 *
+		 * http://bugzilla.kernel.org/show_bug.cgi?id=12276
+		 *
+		 * Use dates instead of versions to match as HP is
+		 * apparently recycling both product and version
+		 * strings.
+		 *
+		 * http://bugzilla.kernel.org/show_bug.cgi?id=15462
 		 */
 		{
 			.ident = "dv4",
@@ -2839,7 +3065,7 @@ static bool ahci_broken_suspend(struct p
 				DMI_MATCH(DMI_PRODUCT_NAME,
 					  "HP Pavilion dv4 Notebook PC"),
 			},
-			.driver_data = "F.30", /* cutoff BIOS version */
+			.driver_data = "20090105",	/* F.30 */
 		},
 		{
 			.ident = "dv5",
@@ -2848,7 +3074,7 @@ static bool ahci_broken_suspend(struct p
 				DMI_MATCH(DMI_PRODUCT_NAME,
 					  "HP Pavilion dv5 Notebook PC"),
 			},
-			.driver_data = "F.16", /* cutoff BIOS version */
+			.driver_data = "20090506",	/* F.16 */
 		},
 		{
 			.ident = "dv6",
@@ -2857,7 +3083,7 @@ static bool ahci_broken_suspend(struct p
 				DMI_MATCH(DMI_PRODUCT_NAME,
 					  "HP Pavilion dv6 Notebook PC"),
 			},
-			.driver_data = "F.21",	/* cutoff BIOS version */
+			.driver_data = "20090423",	/* F.21 */
 		},
 		{
 			.ident = "HDX18",
@@ -2866,7 +3092,7 @@ static bool ahci_broken_suspend(struct p
 				DMI_MATCH(DMI_PRODUCT_NAME,
 					  "HP HDX18 Notebook PC"),
 			},
-			.driver_data = "F.23",	/* cutoff BIOS version */
+			.driver_data = "20090430",	/* F.23 */
 		},
 		/*
 		 * Acer eMachines G725 has the same problem.  BIOS
@@ -2874,6 +3100,8 @@ static bool ahci_broken_suspend(struct p
 		 * work.  Inbetween, there are V1.06, V2.06 and V3.03
 		 * that we don't have much idea about.  For now,
 		 * blacklist anything older than V3.04.
+		 *
+		 * http://bugzilla.kernel.org/show_bug.cgi?id=15104
 		 */
 		{
 			.ident = "G725",
@@ -2881,19 +3109,21 @@ static bool ahci_broken_suspend(struct p
 				DMI_MATCH(DMI_SYS_VENDOR, "eMachines"),
 				DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"),
 			},
-			.driver_data = "V3.04",	/* cutoff BIOS version */
+			.driver_data = "20091216",	/* V3.04 */
 		},
 		{ }	/* terminate list */
 	};
 	const struct dmi_system_id *dmi = dmi_first_match(sysids);
-	const char *ver;
+	int year, month, date;
+	char buf[9];
 
 	if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2))
 		return false;
 
-	ver = dmi_get_system_info(DMI_BIOS_VERSION);
+	dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
+	snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
 
-	return !ver || strcmp(ver, dmi->driver_data) < 0;
+	return strcmp(buf, dmi->driver_data) < 0;
 }
 
 static bool ahci_broken_online(struct pci_dev *pdev)
@@ -3082,8 +3312,16 @@ static int ahci_init_one(struct pci_dev
 	ahci_save_initial_config(pdev, hpriv);
 
 	/* prepare host */
-	if (hpriv->cap & HOST_CAP_NCQ)
-		pi.flags |= ATA_FLAG_NCQ | ATA_FLAG_FPDMA_AA;
+	if (hpriv->cap & HOST_CAP_NCQ) {
+		pi.flags |= ATA_FLAG_NCQ;
+		/* Auto-activate optimization is supposed to be supported on
+		   all AHCI controllers indicating NCQ support, but it seems
+		   to be broken at least on some NVIDIA MCP79 chipsets.
+		   Until we get info on which NVIDIA chipsets don't have this
+		   issue, if any, disable AA on all NVIDIA AHCIs. */
+		if (pdev->vendor != PCI_VENDOR_ID_NVIDIA)
+			pi.flags |= ATA_FLAG_FPDMA_AA;
+	}
 
 	if (hpriv->cap & HOST_CAP_PMP)
 		pi.flags |= ATA_FLAG_PMP;
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/ata_generic.c linux-libre-2.6.34-gnu1/drivers/ata/ata_generic.c
--- linux-libre-2.6.33-gnu1/drivers/ata/ata_generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/ata_generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -155,7 +155,7 @@ static int ata_generic_init_one(struct p
 			return rc;
 		pcim_pin_device(dev);
 	}
-	return ata_pci_sff_init_one(dev, ppi, &generic_sht, NULL);
+	return ata_pci_sff_init_one(dev, ppi, &generic_sht, NULL, 0);
 }
 
 static struct pci_device_id ata_generic[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/ata_piix.c linux-libre-2.6.34-gnu1/drivers/ata/ata_piix.c
--- linux-libre-2.6.33-gnu1/drivers/ata/ata_piix.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/ata_piix.c	2010-05-16 17:17:36.000000000 -0400
@@ -90,6 +90,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 #include <linux/dmi.h>
@@ -173,6 +174,7 @@ static int piix_sidpr_scr_read(struct at
 			       unsigned int reg, u32 *val);
 static int piix_sidpr_scr_write(struct ata_link *link,
 				unsigned int reg, u32 val);
+static bool piix_irq_check(struct ata_port *ap);
 #ifdef CONFIG_PM
 static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
 static int piix_pci_device_resume(struct pci_dev *pdev);
@@ -291,6 +293,14 @@ static const struct pci_device_id piix_p
 	{ 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
 	/* SATA Controller IDE (PCH) */
 	{ 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
+	/* SATA Controller IDE (CPT) */
+	{ 0x8086, 0x1c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
+	/* SATA Controller IDE (CPT) */
+	{ 0x8086, 0x1c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
+	/* SATA Controller IDE (CPT) */
+	{ 0x8086, 0x1c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+	/* SATA Controller IDE (CPT) */
+	{ 0x8086, 0x1c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
 	{ }	/* terminate list */
 };
 
@@ -309,8 +319,13 @@ static struct scsi_host_template piix_sh
 	ATA_BMDMA_SHT(DRV_NAME),
 };
 
-static struct ata_port_operations piix_pata_ops = {
+static struct ata_port_operations piix_sata_ops = {
 	.inherits		= &ata_bmdma32_port_ops,
+	.sff_irq_check		= piix_irq_check,
+};
+
+static struct ata_port_operations piix_pata_ops = {
+	.inherits		= &piix_sata_ops,
 	.cable_detect		= ata_cable_40wire,
 	.set_piomode		= piix_set_piomode,
 	.set_dmamode		= piix_set_dmamode,
@@ -328,10 +343,6 @@ static struct ata_port_operations ich_pa
 	.set_dmamode		= ich_set_dmamode,
 };
 
-static struct ata_port_operations piix_sata_ops = {
-	.inherits		= &ata_bmdma32_port_ops,
-};
-
 static struct ata_port_operations piix_sidpr_sata_ops = {
 	.inherits		= &piix_sata_ops,
 	.hardreset		= sata_std_hardreset,
@@ -962,6 +973,14 @@ static int piix_sidpr_scr_write(struct a
 	return 0;
 }
 
+static bool piix_irq_check(struct ata_port *ap)
+{
+	if (unlikely(!ap->ioaddr.bmdma_addr))
+		return false;
+
+	return ap->ops->bmdma_status(ap) & ATA_DMA_INTR;
+}
+
 #ifdef CONFIG_PM
 static int piix_broken_suspend(void)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/Kconfig linux-libre-2.6.34-gnu1/drivers/ata/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/ata/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -446,9 +446,9 @@ config PATA_JMICRON
 
 config PATA_LEGACY
 	tristate "Legacy ISA PATA support (Experimental)"
-	depends on ISA && EXPERIMENTAL
+	depends on (ISA || PCI)  && EXPERIMENTAL
 	help
-	  This option enables support for ISA/VLB bus legacy PATA
+	  This option enables support for ISA/VLB/PCI bus legacy PATA
 	  ports and allows them to be accessed via the new ATA layer.
 
 	  If unsure, say N.
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/libata-acpi.c linux-libre-2.6.34-gnu1/drivers/ata/libata-acpi.c
--- linux-libre-2.6.33-gnu1/drivers/ata/libata-acpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/libata-acpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/acpi.h>
 #include <linux/libata.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <scsi/scsi_device.h>
 #include "libata.h"
 
@@ -64,7 +65,7 @@ void ata_acpi_associate_sata_port(struct
 	WARN_ON(!(ap->flags & ATA_FLAG_ACPI_SATA));
 
 	if (!sata_pmp_attached(ap)) {
-		acpi_integer adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
+		u64 adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
 
 		ap->link.device->acpi_handle =
 			acpi_get_child(ap->host->acpi_handle, adr);
@@ -74,7 +75,7 @@ void ata_acpi_associate_sata_port(struct
 		ap->link.device->acpi_handle = NULL;
 
 		ata_for_each_link(link, ap, EDGE) {
-			acpi_integer adr = SATA_ADR(ap->port_no, link->pmp);
+			u64 adr = SATA_ADR(ap->port_no, link->pmp);
 
 			link->device->acpi_handle =
 				acpi_get_child(ap->host->acpi_handle, adr);
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/libata-core.c linux-libre-2.6.34-gnu1/drivers/ata/libata-core.c
--- linux-libre-2.6.33-gnu1/drivers/ata/libata-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/libata-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,6 +58,7 @@
 #include <linux/io.h>
 #include <linux/async.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
@@ -1493,6 +1494,7 @@ static int ata_hpa_resize(struct ata_dev
 {
 	struct ata_eh_context *ehc = &dev->link->eh_context;
 	int print_info = ehc->i.flags & ATA_EHI_PRINTINFO;
+	bool unlock_hpa = ata_ignore_hpa || dev->flags & ATA_DFLAG_UNLOCK_HPA;
 	u64 sectors = ata_id_n_sectors(dev->id);
 	u64 native_sectors;
 	int rc;
@@ -1509,7 +1511,7 @@ static int ata_hpa_resize(struct ata_dev
 		/* If device aborted the command or HPA isn't going to
 		 * be unlocked, skip HPA resizing.
 		 */
-		if (rc == -EACCES || !ata_ignore_hpa) {
+		if (rc == -EACCES || !unlock_hpa) {
 			ata_dev_printk(dev, KERN_WARNING, "HPA support seems "
 				       "broken, skipping HPA handling\n");
 			dev->horkage |= ATA_HORKAGE_BROKEN_HPA;
@@ -1524,7 +1526,7 @@ static int ata_hpa_resize(struct ata_dev
 	dev->n_native_sectors = native_sectors;
 
 	/* nothing to do? */
-	if (native_sectors <= sectors || !ata_ignore_hpa) {
+	if (native_sectors <= sectors || !unlock_hpa) {
 		if (!print_info || native_sectors == sectors)
 			return 0;
 
@@ -2232,7 +2234,7 @@ retry:
 		 * Some drives were very specific about that exact sequence.
 		 *
 		 * Note that ATA4 says lba is mandatory so the second check
-		 * shoud never trigger.
+		 * should never trigger.
 		 */
 		if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) {
 			err_mask = ata_dev_init_params(dev, id[3], id[6]);
@@ -3211,6 +3213,7 @@ const struct ata_timing *ata_timing_find
 int ata_timing_compute(struct ata_device *adev, unsigned short speed,
 		       struct ata_timing *t, int T, int UT)
 {
+	const u16 *id = adev->id;
 	const struct ata_timing *s;
 	struct ata_timing p;
 
@@ -3228,14 +3231,18 @@ int ata_timing_compute(struct ata_device
 	 * PIO/MW_DMA cycle timing.
 	 */
 
-	if (adev->id[ATA_ID_FIELD_VALID] & 2) {	/* EIDE drive */
+	if (id[ATA_ID_FIELD_VALID] & 2) {	/* EIDE drive */
 		memset(&p, 0, sizeof(p));
+
 		if (speed >= XFER_PIO_0 && speed <= XFER_SW_DMA_0) {
-			if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO];
-					    else p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO_IORDY];
-		} else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) {
-			p.cycle = adev->id[ATA_ID_EIDE_DMA_MIN];
-		}
+			if (speed <= XFER_PIO_2)
+				p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO];
+			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];
+
 		ata_timing_merge(&p, t, t, ATA_TIMING_CYCLE | ATA_TIMING_CYC8B);
 	}
 
@@ -4180,36 +4187,51 @@ int ata_dev_revalidate(struct ata_device
 		goto fail;
 
 	/* verify n_sectors hasn't changed */
-	if (dev->class == ATA_DEV_ATA && n_sectors &&
-	    dev->n_sectors != n_sectors) {
-		ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch "
-			       "%llu != %llu\n",
-			       (unsigned long long)n_sectors,
-			       (unsigned long long)dev->n_sectors);
-		/*
-		 * Something could have caused HPA to be unlocked
-		 * involuntarily.  If n_native_sectors hasn't changed
-		 * and the new size matches it, keep the device.
-		 */
-		if (dev->n_native_sectors == n_native_sectors &&
-		    dev->n_sectors > n_sectors &&
-		    dev->n_sectors == n_native_sectors) {
-			ata_dev_printk(dev, KERN_WARNING,
-				       "new n_sectors matches native, probably "
-				       "late HPA unlock, continuing\n");
-			/* keep using the old n_sectors */
-			dev->n_sectors = n_sectors;
-		} else {
-			/* restore original n_[native]_sectors and fail */
-			dev->n_native_sectors = n_native_sectors;
-			dev->n_sectors = n_sectors;
-			rc = -ENODEV;
-			goto fail;
-		}
+	if (dev->class != ATA_DEV_ATA || !n_sectors ||
+	    dev->n_sectors == n_sectors)
+		return 0;
+
+	/* n_sectors has changed */
+	ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch %llu != %llu\n",
+		       (unsigned long long)n_sectors,
+		       (unsigned long long)dev->n_sectors);
+
+	/*
+	 * Something could have caused HPA to be unlocked
+	 * involuntarily.  If n_native_sectors hasn't changed and the
+	 * new size matches it, keep the device.
+	 */
+	if (dev->n_native_sectors == n_native_sectors &&
+	    dev->n_sectors > n_sectors && dev->n_sectors == n_native_sectors) {
+		ata_dev_printk(dev, KERN_WARNING,
+			       "new n_sectors matches native, probably "
+			       "late HPA unlock, continuing\n");
+		/* keep using the old n_sectors */
+		dev->n_sectors = n_sectors;
+		return 0;
 	}
 
-	return 0;
+	/*
+	 * Some BIOSes boot w/o HPA but resume w/ HPA locked.  Try
+	 * unlocking HPA in those cases.
+	 *
+	 * https://bugzilla.kernel.org/show_bug.cgi?id=15396
+	 */
+	if (dev->n_native_sectors == n_native_sectors &&
+	    dev->n_sectors < n_sectors && n_sectors == n_native_sectors &&
+	    !(dev->horkage & ATA_HORKAGE_BROKEN_HPA)) {
+		ata_dev_printk(dev, KERN_WARNING,
+			       "old n_sectors matches native, probably "
+			       "late HPA lock, will try to unlock HPA\n");
+		/* try unlocking HPA */
+		dev->flags |= ATA_DFLAG_UNLOCK_HPA;
+		rc = -EIO;
+	} else
+		rc = -ENODEV;
 
+	/* restore original n_[native_]sectors and fail */
+	dev->n_native_sectors = n_native_sectors;
+	dev->n_sectors = n_sectors;
  fail:
 	ata_dev_printk(dev, KERN_ERR, "revalidation failed (errno=%d)\n", rc);
 	return rc;
@@ -4348,6 +4370,9 @@ static const struct ata_blacklist_entry
 	{ "HTS541080G9SA00",    "MB4OC60D",     ATA_HORKAGE_NONCQ, },
 	{ "HTS541010G9SA00",    "MBZOC60D",     ATA_HORKAGE_NONCQ, },
 
+	/* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */
+	{ "C300-CTFDDAC128MAG",	"0001",		ATA_HORKAGE_NONCQ, },
+
 	/* devices which puke on READ_NATIVE_MAX */
 	{ "HDS724040KLSA80",	"KFAOA20N",	ATA_HORKAGE_BROKEN_HPA, },
 	{ "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA },
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/libata-eh.c linux-libre-2.6.34-gnu1/drivers/ata/libata-eh.c
--- linux-libre-2.6.33-gnu1/drivers/ata/libata-eh.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/libata-eh.c	2010-05-16 17:17:36.000000000 -0400
@@ -879,6 +879,8 @@ static void ata_eh_set_pending(struct at
 void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
+	struct request_queue *q = qc->scsicmd->device->request_queue;
+	unsigned long flags;
 
 	WARN_ON(!ap->ops->error_handler);
 
@@ -890,7 +892,9 @@ void ata_qc_schedule_eh(struct ata_queue
 	 * Note that ATA_QCFLAG_FAILED is unconditionally set after
 	 * this function completes.
 	 */
+	spin_lock_irqsave(q->queue_lock, flags);
 	blk_abort_request(qc->scsicmd->request);
+	spin_unlock_irqrestore(q->queue_lock, flags);
 }
 
 /**
@@ -1624,6 +1628,7 @@ void ata_eh_analyze_ncq_error(struct ata
 	}
 
 	/* okay, this error is ours */
+	memset(&tf, 0, sizeof(tf));
 	rc = ata_eh_read_log_10h(dev, &tag, &tf);
 	if (rc) {
 		ata_link_printk(link, KERN_ERR, "failed to read log page 10h "
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/libata-pmp.c linux-libre-2.6.34-gnu1/drivers/ata/libata-pmp.c
--- linux-libre-2.6.33-gnu1/drivers/ata/libata-pmp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/libata-pmp.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 
 #include <linux/kernel.h>
 #include <linux/libata.h>
+#include <linux/slab.h>
 #include "libata.h"
 
 const struct ata_port_operations sata_pmp_port_ops = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/libata-scsi.c linux-libre-2.6.34-gnu1/drivers/ata/libata-scsi.c
--- linux-libre-2.6.33-gnu1/drivers/ata/libata-scsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/libata-scsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/blkdev.h>
 #include <linux/spinlock.h>
@@ -1097,7 +1098,7 @@ static int ata_scsi_dev_config(struct sc
 		dev->flags |= ATA_DFLAG_NO_UNLOAD;
 
 	/* configure max sectors */
-	blk_queue_max_sectors(sdev->request_queue, dev->max_sectors);
+	blk_queue_max_hw_sectors(sdev->request_queue, dev->max_sectors);
 
 	if (dev->class == ATA_DEV_ATAPI) {
 		struct request_queue *q = sdev->request_queue;
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/libata-sff.c linux-libre-2.6.34-gnu1/drivers/ata/libata-sff.c
--- linux-libre-2.6.33-gnu1/drivers/ata/libata-sff.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/libata-sff.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/libata.h>
 #include <linux/highmem.h>
@@ -1667,6 +1668,7 @@ unsigned int ata_sff_host_intr(struct at
 {
 	struct ata_eh_info *ehi = &ap->link.eh_info;
 	u8 status, host_stat = 0;
+	bool bmdma_stopped = false;
 
 	VPRINTK("ata%u: protocol %d task_state %d\n",
 		ap->print_id, qc->tf.protocol, ap->hsm_task_state);
@@ -1699,6 +1701,7 @@ unsigned int ata_sff_host_intr(struct at
 
 			/* before we do anything else, clear DMA-Start bit */
 			ap->ops->bmdma_stop(qc);
+			bmdma_stopped = true;
 
 			if (unlikely(host_stat & ATA_DMA_ERR)) {
 				/* error when transfering data to/from memory */
@@ -1716,8 +1719,14 @@ unsigned int ata_sff_host_intr(struct at
 
 	/* check main status, clearing INTRQ if needed */
 	status = ata_sff_irq_status(ap);
-	if (status & ATA_BUSY)
-		goto idle_irq;
+	if (status & ATA_BUSY) {
+		if (bmdma_stopped) {
+			/* BMDMA engine is already stopped, we're screwed */
+			qc->err_mask |= AC_ERR_HSM;
+			ap->hsm_task_state = HSM_ST_ERR;
+		} else
+			goto idle_irq;
+	}
 
 	/* ack bmdma irq events */
 	ap->ops->sff_irq_clear(ap);
@@ -1762,25 +1771,68 @@ EXPORT_SYMBOL_GPL(ata_sff_host_intr);
 irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
 {
 	struct ata_host *host = dev_instance;
+	bool retried = false;
 	unsigned int i;
-	unsigned int handled = 0;
+	unsigned int handled, idle, polling;
 	unsigned long flags;
 
 	/* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
 	spin_lock_irqsave(&host->lock, flags);
 
+retry:
+	handled = idle = polling = 0;
 	for (i = 0; i < host->n_ports; i++) {
-		struct ata_port *ap;
+		struct ata_port *ap = host->ports[i];
+		struct ata_queued_cmd *qc;
 
-		ap = host->ports[i];
-		if (ap &&
-		    !(ap->flags & ATA_FLAG_DISABLED)) {
-			struct ata_queued_cmd *qc;
+		if (unlikely(ap->flags & ATA_FLAG_DISABLED))
+			continue;
 
-			qc = ata_qc_from_tag(ap, ap->link.active_tag);
-			if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) &&
-			    (qc->flags & ATA_QCFLAG_ACTIVE))
+		qc = ata_qc_from_tag(ap, ap->link.active_tag);
+		if (qc) {
+			if (!(qc->tf.flags & ATA_TFLAG_POLLING))
 				handled |= ata_sff_host_intr(ap, qc);
+			else
+				polling |= 1 << i;
+		} else
+			idle |= 1 << i;
+	}
+
+	/*
+	 * If no port was expecting IRQ but the controller is actually
+	 * asserting IRQ line, nobody cared will ensue.  Check IRQ
+	 * pending status if available and clear spurious IRQ.
+	 */
+	if (!handled && !retried) {
+		bool retry = false;
+
+		for (i = 0; i < host->n_ports; i++) {
+			struct ata_port *ap = host->ports[i];
+
+			if (polling & (1 << i))
+				continue;
+
+			if (!ap->ops->sff_irq_check ||
+			    !ap->ops->sff_irq_check(ap))
+				continue;
+
+			if (idle & (1 << i)) {
+				ap->ops->sff_check_status(ap);
+				ap->ops->sff_irq_clear(ap);
+			} else {
+				/* clear INTRQ and check if BUSY cleared */
+				if (!(ap->ops->sff_check_status(ap) & ATA_BUSY))
+					retry |= true;
+				/*
+				 * With command in flight, we can't do
+				 * sff_irq_clear() w/o racing with completion.
+				 */
+			}
+		}
+
+		if (retry) {
+			retried = true;
+			goto retry;
 		}
 	}
 
@@ -2261,7 +2313,7 @@ EXPORT_SYMBOL_GPL(ata_sff_postreset);
  *	@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
+ *	failing to complete. In some cases this is necessary before a
  *	reset will recover the device.
  *
  */
@@ -3011,6 +3063,7 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_activate_h
  *	@ppi: array of port_info, must be enough for two ports
  *	@sht: scsi_host_template to use when registering the host
  *	@host_priv: host private_data
+ *	@hflag: host flags
  *
  *	This is a helper function which can be called from a driver's
  *	xxx_init_one() probe function if the hardware uses traditional
@@ -3031,8 +3084,8 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_activate_h
  *	Zero on success, negative on errno-based value on error.
  */
 int ata_pci_sff_init_one(struct pci_dev *pdev,
-			 const struct ata_port_info * const *ppi,
-			 struct scsi_host_template *sht, void *host_priv)
+		 const struct ata_port_info * const *ppi,
+		 struct scsi_host_template *sht, void *host_priv, int hflag)
 {
 	struct device *dev = &pdev->dev;
 	const struct ata_port_info *pi = NULL;
@@ -3067,6 +3120,7 @@ int ata_pci_sff_init_one(struct pci_dev
 	if (rc)
 		goto out;
 	host->private_data = host_priv;
+	host->flags |= hflag;
 
 	pci_set_master(pdev);
 	rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht);
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_acpi.c linux-libre-2.6.34-gnu1/drivers/ata/pata_acpi.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_acpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_acpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <acpi/acpi_bus.h>
 
@@ -161,7 +162,7 @@ static void pacpi_set_dmamode(struct ata
  *
  *	Called when the libata layer is about to issue a command. We wrap
  *	this interface so that we can load the correct ATA timings if
- *	neccessary.
+ *	necessary.
  */
 
 static unsigned int pacpi_qc_issue(struct ata_queued_cmd *qc)
@@ -259,7 +260,7 @@ static int pacpi_init_one (struct pci_de
 			return rc;
 		pcim_pin_device(pdev);
 	}
-	return ata_pci_sff_init_one(pdev, ppi, &pacpi_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &pacpi_sht, NULL, 0);
 }
 
 static const struct pci_device_id pacpi_pci_tbl[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_ali.c linux-libre-2.6.34-gnu1/drivers/ata/pata_ali.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_ali.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_ali.c	2010-05-16 17:17:36.000000000 -0400
@@ -159,8 +159,7 @@ static void ali_fifo_control(struct ata_
  *	ali_program_modes	-	load mode registers
  *	@ap: ALi channel to load
  *	@adev: Device the timing is for
- *	@cmd: Command timing
- *	@data: Data timing
+ *	@t: timing data
  *	@ultra: UDMA timing or zero for off
  *
  *	Loads the timing registers for cmd/data and disable UDMA if
@@ -202,8 +201,7 @@ static void ali_program_modes(struct ata
  *	@ap: ATA interface
  *	@adev: ATA device
  *
- *	Program the ALi registers for PIO mode. FIXME: add timings for
- *	PIO5.
+ *	Program the ALi registers for PIO mode.
  */
 
 static void ali_set_piomode(struct ata_port *ap, struct ata_device *adev)
@@ -237,7 +235,7 @@ static void ali_set_piomode(struct ata_p
  *	@ap: ATA interface
  *	@adev: ATA device
  *
- *	FIXME: MWDMA timings
+ *	Program the ALi registers for DMA mode.
  */
 
 static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev)
@@ -585,7 +583,7 @@ static int ali_init_one(struct pci_dev *
 	        	ppi[0] = &info_20_udma;
 	}
 
-	return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL, 0);
 }
 
 #ifdef CONFIG_PM
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_amd.c linux-libre-2.6.34-gnu1/drivers/ata/pata_amd.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_amd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_amd.c	2010-05-16 17:17:36.000000000 -0400
@@ -574,7 +574,7 @@ static int amd_init_one(struct pci_dev *
 	}
 
 	/* And fire it up */
-	return ata_pci_sff_init_one(pdev, ppi, &amd_sht, hpriv);
+	return ata_pci_sff_init_one(pdev, ppi, &amd_sht, hpriv, 0);
 }
 
 #ifdef CONFIG_PM
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_artop.c linux-libre-2.6.34-gnu1/drivers/ata/pata_artop.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_artop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_artop.c	2010-05-16 17:17:36.000000000 -0400
@@ -421,7 +421,7 @@ static int artop_init_one (struct pci_de
 
 	BUG_ON(ppi[0] == NULL);
 
-	return ata_pci_sff_init_one(pdev, ppi, &artop_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &artop_sht, NULL, 0);
 }
 
 static const struct pci_device_id artop_pci_tbl[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_at32.c linux-libre-2.6.34-gnu1/drivers/ata/pata_at32.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_at32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_at32.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <scsi/scsi_host.h>
 #include <linux/ata.h>
 #include <linux/libata.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_at91.c linux-libre-2.6.34-gnu1/drivers/ata/pata_at91.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_at91.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_at91.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <linux/ata.h>
 #include <linux/clk.h>
@@ -153,8 +154,8 @@ static void pata_at91_set_piomode(struct
 	/* Compute ATA timing and set it to SMC */
 	ret = ata_timing_compute(adev, adev->pio_mode, &timing, 1000, 0);
 	if (ret) {
-		dev_warn(ap->dev, "Failed to compute ATA timing %d, \
-				set PIO_0 timing\n", ret);
+		dev_warn(ap->dev, "Failed to compute ATA timing %d, "
+			 "set PIO_0 timing\n", ret);
 		set_smc_timing(ap->dev, info, &initial_timing);
 	} else {
 		set_smc_timing(ap->dev, info, &timing);
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_atiixp.c linux-libre-2.6.34-gnu1/drivers/ata/pata_atiixp.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_atiixp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_atiixp.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * pata_atiixp.c 	- ATI PATA for new ATA layer
  *			  (C) 2005 Red Hat Inc
- *			  (C) 2009 Bartlomiej Zolnierkiewicz
+ *			  (C) 2009-2010 Bartlomiej Zolnierkiewicz
  *
  * Based on
  *
@@ -46,6 +46,8 @@ static int atiixp_cable_detect(struct at
 	return ATA_CBL_PATA40;
 }
 
+static DEFINE_SPINLOCK(atiixp_lock);
+
 /**
  *	atiixp_set_pio_timing	-	set initial PIO mode data
  *	@ap: ATA interface
@@ -88,7 +90,10 @@ static void atiixp_set_pio_timing(struct
 
 static void atiixp_set_piomode(struct ata_port *ap, struct ata_device *adev)
 {
+	unsigned long flags;
+	spin_lock_irqsave(&atiixp_lock, flags);
 	atiixp_set_pio_timing(ap, adev, adev->pio_mode - XFER_PIO_0);
+	spin_unlock_irqrestore(&atiixp_lock, flags);
 }
 
 /**
@@ -108,6 +113,9 @@ static void atiixp_set_dmamode(struct at
 	int dma = adev->dma_mode;
 	int dn = 2 * ap->port_no + adev->devno;
 	int wanted_pio;
+	unsigned long flags;
+
+	spin_lock_irqsave(&atiixp_lock, flags);
 
 	if (adev->dma_mode >= XFER_UDMA_0) {
 		u16 udma_mode_data;
@@ -145,6 +153,7 @@ static void atiixp_set_dmamode(struct at
 
 	if (adev->pio_mode != wanted_pio)
 		atiixp_set_pio_timing(ap, adev, wanted_pio);
+	spin_unlock_irqrestore(&atiixp_lock, flags);
 }
 
 /**
@@ -237,7 +246,8 @@ static int atiixp_init_one(struct pci_de
 		if (!pci_test_config_bits(pdev, &atiixp_enable_bits[i]))
 			ppi[i] = &ata_dummy_port_info;
 
-	return ata_pci_sff_init_one(pdev, ppi, &atiixp_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &atiixp_sht, NULL,
+						ATA_HOST_PARALLEL_SCAN);
 }
 
 static const struct pci_device_id atiixp[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_atp867x.c linux-libre-2.6.34-gnu1/drivers/ata/pata_atp867x.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_atp867x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_atp867x.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_cmd640.c linux-libre-2.6.34-gnu1/drivers/ata/pata_cmd640.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_cmd640.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_cmd640.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 
@@ -223,7 +224,7 @@ static int cmd640_init_one(struct pci_de
 
 	cmd640_hardware_init(pdev);
 
-	return ata_pci_sff_init_one(pdev, ppi, &cmd640_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &cmd640_sht, NULL, 0);
 }
 
 #ifdef CONFIG_PM
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_cmd64x.c linux-libre-2.6.34-gnu1/drivers/ata/pata_cmd64x.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_cmd64x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_cmd64x.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
  * pata_cmd64x.c 	- CMD64x PATA for new ATA layer
  *			  (C) 2005 Red Hat Inc
  *			  Alan Cox <alan@lxorguk.ukuu.org.uk>
+ *			  (C) 2009-2010 Bartlomiej Zolnierkiewicz
  *
  * Based upon
  * linux/drivers/ide/pci/cmd64x.c		Version 1.30	Sept 10, 2002
@@ -39,11 +40,7 @@
 
 enum {
 	CFR 		= 0x50,
-		CFR_INTR_CH0  = 0x02,
-	CNTRL 		= 0x51,
-		CNTRL_DIS_RA0 = 0x40,
-		CNTRL_DIS_RA1 = 0x80,
-		CNTRL_ENA_2ND = 0x08,
+		CFR_INTR_CH0  = 0x04,
 	CMDTIM 		= 0x52,
 	ARTTIM0 	= 0x53,
 	DRWTIM0 	= 0x54,
@@ -53,9 +50,6 @@ enum {
 		ARTTIM23_DIS_RA2  = 0x04,
 		ARTTIM23_DIS_RA3  = 0x08,
 		ARTTIM23_INTR_CH1 = 0x10,
-	ARTTIM2 	= 0x57,
-	ARTTIM3 	= 0x57,
-	DRWTIM23	= 0x58,
 	DRWTIM2 	= 0x58,
 	BRST 		= 0x59,
 	DRWTIM3 	= 0x5b,
@@ -63,14 +57,11 @@ enum {
 	MRDMODE		= 0x71,
 		MRDMODE_INTR_CH0 = 0x04,
 		MRDMODE_INTR_CH1 = 0x08,
-		MRDMODE_BLK_CH0  = 0x10,
-		MRDMODE_BLK_CH1	 = 0x20,
 	BMIDESR0	= 0x72,
 	UDIDETCR0	= 0x73,
 	DTPR0		= 0x74,
 	BMIDECR1	= 0x78,
 	BMIDECSR	= 0x79,
-	BMIDESR1	= 0x7A,
 	UDIDETCR1	= 0x7B,
 	DTPR1		= 0x7C
 };
@@ -130,8 +121,14 @@ static void cmd64x_set_timing(struct ata
 
 		if (pair) {
 			struct ata_timing tp;
+
 			ata_timing_compute(pair, pair->pio_mode, &tp, T, 0);
 			ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP);
+			if (pair->dma_mode) {
+				ata_timing_compute(pair, pair->dma_mode,
+						&tp, T, 0);
+				ata_timing_merge(&tp, &t, &t, ATA_TIMING_SETUP);
+			}
 		}
 	}
 
@@ -147,7 +144,9 @@ static void cmd64x_set_timing(struct ata
 	/* Now convert the clocks into values we can actually stuff into
 	   the chip */
 
-	if (t.recover > 1)
+	if (t.recover == 16)
+		t.recover = 0;
+	else if (t.recover > 1)
 		t.recover--;
 	else
 		t.recover = 15;
@@ -245,7 +244,7 @@ static void cmd648_bmdma_stop(struct ata
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u8 dma_intr;
 	int dma_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
-	int dma_reg = ap->port_no ? ARTTIM2 : CFR;
+	int dma_reg = ap->port_no ? ARTTIM23 : CFR;
 
 	ata_bmdma_stop(qc);
 
@@ -368,7 +367,7 @@ static int cmd64x_init_one(struct pci_de
 	pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
 #endif
 
-	return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL, 0);
 }
 
 #ifdef CONFIG_PM
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_cs5530.c linux-libre-2.6.34-gnu1/drivers/ata/pata_cs5530.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_cs5530.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_cs5530.c	2010-05-16 17:17:36.000000000 -0400
@@ -324,7 +324,7 @@ static int cs5530_init_one(struct pci_de
 		ppi[1] = &info_palmax_secondary;
 
 	/* Now kick off ATA set up */
-	return ata_pci_sff_init_one(pdev, ppi, &cs5530_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &cs5530_sht, NULL, 0);
 }
 
 #ifdef CONFIG_PM
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_cs5535.c linux-libre-2.6.34-gnu1/drivers/ata/pata_cs5535.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_cs5535.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_cs5535.c	2010-05-16 17:17:36.000000000 -0400
@@ -100,7 +100,7 @@ static int cs5535_cable_detect(struct at
 static void cs5535_set_piomode(struct ata_port *ap, struct ata_device *adev)
 {
 	static const u16 pio_timings[5] = {
-		0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131
+		0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131
 	};
 	static const u16 pio_cmd_timings[5] = {
 		0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131
@@ -198,7 +198,7 @@ static int cs5535_init_one(struct pci_de
 	rdmsr(ATAC_CH0D1_PIO, timings, dummy);
 	if (CS5535_BAD_PIO(timings))
 		wrmsr(ATAC_CH0D1_PIO, 0xF7F4F7F4UL, 0);
-	return ata_pci_sff_init_one(dev, ppi, &cs5535_sht, NULL);
+	return ata_pci_sff_init_one(dev, ppi, &cs5535_sht, NULL, 0);
 }
 
 static const struct pci_device_id cs5535[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_cs5536.c linux-libre-2.6.34-gnu1/drivers/ata/pata_cs5536.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_cs5536.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_cs5536.c	2010-05-16 17:17:36.000000000 -0400
@@ -260,7 +260,7 @@ static int cs5536_init_one(struct pci_de
 		return -ENODEV;
 	}
 
-	return ata_pci_sff_init_one(dev, ppi, &cs5536_sht, NULL);
+	return ata_pci_sff_init_one(dev, ppi, &cs5536_sht, NULL, 0);
 }
 
 static const struct pci_device_id cs5536[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_cypress.c linux-libre-2.6.34-gnu1/drivers/ata/pata_cypress.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_cypress.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_cypress.c	2010-05-16 17:17:36.000000000 -0400
@@ -62,14 +62,16 @@ static void cy82c693_set_piomode(struct
 		return;
 	}
 
-	time_16 = clamp_val(t.recover, 0, 15) | (clamp_val(t.active, 0, 15) << 4);
-	time_8 = clamp_val(t.act8b, 0, 15) | (clamp_val(t.rec8b, 0, 15) << 4);
+	time_16 = clamp_val(t.recover - 1, 0, 15) |
+		  (clamp_val(t.active - 1, 0, 15) << 4);
+	time_8 = clamp_val(t.act8b - 1, 0, 15) |
+		 (clamp_val(t.rec8b - 1, 0, 15) << 4);
 
 	if (adev->devno == 0) {
 		pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr);
 
 		addr &= ~0x0F;	/* Mask bits */
-		addr |= clamp_val(t.setup, 0, 15);
+		addr |= clamp_val(t.setup - 1, 0, 15);
 
 		pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr);
 		pci_write_config_byte(pdev, CY82_IDE_MASTER_IOR, time_16);
@@ -79,7 +81,7 @@ static void cy82c693_set_piomode(struct
 		pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr);
 
 		addr &= ~0xF0;	/* Mask bits */
-		addr |= (clamp_val(t.setup, 0, 15) << 4);
+		addr |= (clamp_val(t.setup - 1, 0, 15) << 4);
 
 		pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr);
 		pci_write_config_byte(pdev, CY82_IDE_SLAVE_IOR, time_16);
@@ -136,7 +138,7 @@ static int cy82c693_init_one(struct pci_
 	if (PCI_FUNC(pdev->devfn) != 1)
 		return -ENODEV;
 
-	return ata_pci_sff_init_one(pdev, ppi, &cy82c693_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &cy82c693_sht, NULL, 0);
 }
 
 static const struct pci_device_id cy82c693[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_efar.c linux-libre-2.6.34-gnu1/drivers/ata/pata_efar.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_efar.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_efar.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  *    pata_efar.c - EFAR PIIX clone controller driver
  *
  *	(C) 2005 Red Hat
- *	(C) 2009 Bartlomiej Zolnierkiewicz
+ *	(C) 2009-2010 Bartlomiej Zolnierkiewicz
  *
  *    Some parts based on ata_piix.c by Jeff Garzik and others.
  *
@@ -68,6 +68,8 @@ static int efar_cable_detect(struct ata_
 	return ATA_CBL_PATA80;
 }
 
+static DEFINE_SPINLOCK(efar_lock);
+
 /**
  *	efar_set_piomode - Initialize host controller PATA PIO timings
  *	@ap: Port whose timings we are configuring
@@ -84,7 +86,9 @@ static void efar_set_piomode (struct ata
 	unsigned int pio	= adev->pio_mode - XFER_PIO_0;
 	struct pci_dev *dev	= to_pci_dev(ap->host->dev);
 	unsigned int idetm_port= ap->port_no ? 0x42 : 0x40;
+	unsigned long flags;
 	u16 idetm_data;
+	u8 udma_enable;
 	int control = 0;
 
 	/*
@@ -107,6 +111,8 @@ static void efar_set_piomode (struct ata
 	if (adev->class == ATA_DEV_ATA)
 		control |= 4;	/* PPE */
 
+	spin_lock_irqsave(&efar_lock, flags);
+
 	pci_read_config_word(dev, idetm_port, &idetm_data);
 
 	/* Set PPE, IE, and TIME as appropriate */
@@ -131,6 +137,11 @@ static void efar_set_piomode (struct ata
 
 	idetm_data |= 0x4000;	/* Ensure SITRE is set */
 	pci_write_config_word(dev, idetm_port, idetm_data);
+
+	pci_read_config_byte(dev, 0x48, &udma_enable);
+	udma_enable &= ~(1 << (2 * ap->port_no + adev->devno));
+	pci_write_config_byte(dev, 0x48, udma_enable);
+	spin_unlock_irqrestore(&efar_lock, flags);
 }
 
 /**
@@ -151,6 +162,7 @@ static void efar_set_dmamode (struct ata
 	u16 master_data;
 	u8 speed		= adev->dma_mode;
 	int devid		= adev->devno + 2 * ap->port_no;
+	unsigned long flags;
 	u8 udma_enable;
 
 	static const	 /* ISP  RTC */
@@ -160,6 +172,8 @@ static void efar_set_dmamode (struct ata
 			    { 2, 1 },
 			    { 2, 3 }, };
 
+	spin_lock_irqsave(&efar_lock, flags);
+
 	pci_read_config_word(dev, master_port, &master_data);
 	pci_read_config_byte(dev, 0x48, &udma_enable);
 
@@ -217,6 +231,7 @@ static void efar_set_dmamode (struct ata
 		pci_write_config_word(dev, master_port, master_data);
 	}
 	pci_write_config_byte(dev, 0x48, udma_enable);
+	spin_unlock_irqrestore(&efar_lock, flags);
 }
 
 static struct scsi_host_template efar_sht = {
@@ -256,13 +271,14 @@ static int efar_init_one (struct pci_dev
 		.udma_mask 	= ATA_UDMA4,
 		.port_ops	= &efar_ops,
 	};
-	const struct ata_port_info *ppi[] = { &info, NULL };
+	const struct ata_port_info *ppi[] = { &info, &info };
 
 	if (!printed_version++)
 		dev_printk(KERN_DEBUG, &pdev->dev,
 			   "version " DRV_VERSION "\n");
 
-	return ata_pci_sff_init_one(pdev, ppi, &efar_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &efar_sht, NULL,
+					ATA_HOST_PARALLEL_SCAN);
 }
 
 static const struct pci_device_id efar_pci_tbl[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt366.c linux-libre-2.6.34-gnu1/drivers/ata/pata_hpt366.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt366.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_hpt366.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,9 +11,7 @@
  *
  *
  * TODO
- *	Maybe PLL mode
- *	Look into engine reset on timeout errors. Should not be
- *		required.
+ *	Look into engine reset on timeout errors. Should not be required.
  */
 
 
@@ -27,7 +25,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"pata_hpt366"
-#define DRV_VERSION	"0.6.7"
+#define DRV_VERSION	"0.6.8"
 
 struct hpt_clock {
 	u8	xfer_mode;
@@ -207,17 +205,8 @@ static void hpt366_set_mode(struct ata_p
 {
 	struct hpt_clock *clocks = ap->host->private_data;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-	u32 addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
-	u32 addr2 = 0x51 + 4 * ap->port_no;
+	u32 addr = 0x40 + 4 * adev->devno;
 	u32 mask, reg;
-	u8 fast;
-
-	/* Fast interrupt prediction disable, hold off interrupt disable */
-	pci_read_config_byte(pdev, addr2, &fast);
-	if (fast & 0x80) {
-		fast &= ~0x80;
-		pci_write_config_byte(pdev, addr2, fast);
-	}
 
 	/* determine timing mask and find matching clock entry */
 	if (mode < XFER_MW_DMA_0)
@@ -240,9 +229,9 @@ static void hpt366_set_mode(struct ata_p
 	 * on-chip PIO FIFO/buffer (and PIO MST mode as well) to avoid
 	 * problems handling I/O errors later.
 	 */
-	pci_read_config_dword(pdev, addr1, &reg);
+	pci_read_config_dword(pdev, addr, &reg);
 	reg = ((reg & ~mask) | (clocks->timing & mask)) & ~0xc0000000;
-	pci_write_config_dword(pdev, addr1, reg);
+	pci_write_config_dword(pdev, addr, reg);
 }
 
 /**
@@ -372,7 +361,7 @@ static int hpt36x_init_one(struct pci_de
 			break;
 	}
 	/* Now kick off ATA set up */
-	return ata_pci_sff_init_one(dev, ppi, &hpt36x_sht, hpriv);
+	return ata_pci_sff_init_one(dev, ppi, &hpt36x_sht, hpriv, 0);
 }
 
 #ifdef CONFIG_PM
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt37x.c linux-libre-2.6.34-gnu1/drivers/ata/pata_hpt37x.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt37x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_hpt37x.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"pata_hpt37x"
-#define DRV_VERSION	"0.6.14"
+#define DRV_VERSION	"0.6.15"
 
 struct hpt_clock {
 	u8	xfer_speed;
@@ -39,25 +39,24 @@ struct hpt_chip {
 
 /* key for bus clock timings
  * bit
- * 0:3    data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
- *        DMA. cycles = value + 1
- * 4:8    data_low_time. active time of DIOW_/DIOR_ for PIO and MW
- *        DMA. cycles = value + 1
- * 9:12   cmd_high_time. inactive time of DIOW_/DIOR_ during task file
+ * 0:3    data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA.
+ *        cycles = value + 1
+ * 4:8    data_low_time. Active time of DIOW_/DIOR_ for PIO and MW DMA.
+ *        cycles = value + 1
+ * 9:12   cmd_high_time. Inactive time of DIOW_/DIOR_ during task file
  *        register access.
- * 13:17  cmd_low_time. active time of DIOW_/DIOR_ during task file
+ * 13:17  cmd_low_time. Active time of DIOW_/DIOR_ during task file
  *        register access.
- * 18:21  udma_cycle_time. clock freq and clock cycles for UDMA xfer.
- *        during task file register access.
- * 22:24  pre_high_time. time to initialize 1st cycle for PIO and MW DMA
- *        xfer.
- * 25:27  cmd_pre_high_time. time to initialize 1st PIO cycle for task
+ * 18:20  udma_cycle_time. Clock cycles for UDMA xfer.
+ * 21     CLK frequency for UDMA: 0=ATA clock, 1=dual ATA clock.
+ * 22:24  pre_high_time. Time to initialize 1st cycle for PIO and MW DMA xfer.
+ * 25:27  cmd_pre_high_time. Time to initialize 1st PIO cycle for task file
  *        register access.
- * 28     UDMA enable
- * 29     DMA enable
- * 30     PIO_MST enable. if set, the chip is in bus master mode during
- *        PIO.
- * 31     FIFO enable.
+ * 28     UDMA enable.
+ * 29     DMA  enable.
+ * 30     PIO_MST enable. If set, the chip is in bus master mode during
+ *        PIO xfer.
+ * 31     FIFO enable. Only for PIO.
  */
 
 static struct hpt_clock hpt37x_timings_33[] = {
@@ -384,20 +383,12 @@ static int hpt37x_pre_reset(struct ata_l
 	return ata_sff_prereset(link, deadline);
 }
 
-/**
- *	hpt370_set_piomode		-	PIO setup
- *	@ap: ATA interface
- *	@adev: device on the interface
- *
- *	Perform PIO mode setup.
- */
-
-static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev)
+static void hpt370_set_mode(struct ata_port *ap, struct ata_device *adev,
+			    u8 mode)
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u32 addr1, addr2;
-	u32 reg;
-	u32 mode;
+	u32 reg, timing, mask;
 	u8 fast;
 
 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
@@ -409,11 +400,31 @@ static void hpt370_set_piomode(struct at
 	fast |= 0x01;
 	pci_write_config_byte(pdev, addr2, fast);
 
+	/* Determine timing mask and find matching mode entry */
+	if (mode < XFER_MW_DMA_0)
+		mask = 0xcfc3ffff;
+	else if (mode < XFER_UDMA_0)
+		mask = 0x31c001ff;
+	else
+		mask = 0x303c0000;
+
+	timing = hpt37x_find_mode(ap, mode);
+
 	pci_read_config_dword(pdev, addr1, &reg);
-	mode = hpt37x_find_mode(ap, adev->pio_mode);
-	mode &= 0xCFC3FFFF;	/* Leave DMA bits alone */
-	reg &= ~0xCFC3FFFF;	/* Strip timing bits */
-	pci_write_config_dword(pdev, addr1, reg | mode);
+	reg = (reg & ~mask) | (timing & mask);
+	pci_write_config_dword(pdev, addr1, reg);
+}
+/**
+ *	hpt370_set_piomode		-	PIO setup
+ *	@ap: ATA interface
+ *	@adev: device on the interface
+ *
+ *	Perform PIO mode setup.
+ */
+
+static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+	hpt370_set_mode(ap, adev, adev->pio_mode);
 }
 
 /**
@@ -421,33 +432,12 @@ static void hpt370_set_piomode(struct at
  *	@ap: ATA interface
  *	@adev: Device being configured
  *
- *	Set up the channel for MWDMA or UDMA modes. Much the same as with
- *	PIO, load the mode number and then set MWDMA or UDMA flag.
+ *	Set up the channel for MWDMA or UDMA modes.
  */
 
 static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev)
 {
-	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-	u32 addr1, addr2;
-	u32 reg, mode, mask;
-	u8 fast;
-
-	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
-	addr2 = 0x51 + 4 * ap->port_no;
-
-	/* Fast interrupt prediction disable, hold off interrupt disable */
-	pci_read_config_byte(pdev, addr2, &fast);
-	fast &= ~0x02;
-	fast |= 0x01;
-	pci_write_config_byte(pdev, addr2, fast);
-
-	mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000;
-
-	pci_read_config_dword(pdev, addr1, &reg);
-	mode = hpt37x_find_mode(ap, adev->dma_mode);
-	mode &= mask;
-	reg &= ~mask;
-	pci_write_config_dword(pdev, addr1, reg | mode);
+	hpt370_set_mode(ap, adev, adev->dma_mode);
 }
 
 /**
@@ -461,24 +451,25 @@ static void hpt370_bmdma_stop(struct ata
 {
 	struct ata_port *ap = qc->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-	u8 dma_stat = ioread8(ap->ioaddr.bmdma_addr + 2);
-	u8 dma_cmd;
 	void __iomem *bmdma = ap->ioaddr.bmdma_addr;
+	u8 dma_stat = ioread8(bmdma + ATA_DMA_STATUS);
+	u8 dma_cmd;
 
-	if (dma_stat & 0x01) {
+	if (dma_stat & ATA_DMA_ACTIVE) {
 		udelay(20);
-		dma_stat = ioread8(bmdma + 2);
+		dma_stat = ioread8(bmdma + ATA_DMA_STATUS);
 	}
-	if (dma_stat & 0x01) {
+	if (dma_stat & ATA_DMA_ACTIVE) {
 		/* Clear the engine */
 		pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
 		udelay(10);
 		/* Stop DMA */
-		dma_cmd = ioread8(bmdma );
-		iowrite8(dma_cmd & 0xFE, bmdma);
+		dma_cmd = ioread8(bmdma + ATA_DMA_CMD);
+		iowrite8(dma_cmd & ~ATA_DMA_START, bmdma + ATA_DMA_CMD);
 		/* Clear Error */
-		dma_stat = ioread8(bmdma + 2);
-		iowrite8(dma_stat | 0x06 , bmdma + 2);
+		dma_stat = ioread8(bmdma + ATA_DMA_STATUS);
+		iowrite8(dma_stat | ATA_DMA_INTR | ATA_DMA_ERR,
+			 bmdma + ATA_DMA_STATUS);
 		/* Clear the engine */
 		pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
 		udelay(10);
@@ -486,20 +477,12 @@ static void hpt370_bmdma_stop(struct ata
 	ata_bmdma_stop(qc);
 }
 
-/**
- *	hpt372_set_piomode		-	PIO setup
- *	@ap: ATA interface
- *	@adev: device on the interface
- *
- *	Perform PIO mode setup.
- */
-
-static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev)
+static void hpt372_set_mode(struct ata_port *ap, struct ata_device *adev,
+			    u8 mode)
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u32 addr1, addr2;
-	u32 reg;
-	u32 mode;
+	u32 reg, timing, mask;
 	u8 fast;
 
 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
@@ -510,13 +493,32 @@ static void hpt372_set_piomode(struct at
 	fast &= ~0x07;
 	pci_write_config_byte(pdev, addr2, fast);
 
+	/* Determine timing mask and find matching mode entry */
+	if (mode < XFER_MW_DMA_0)
+		mask = 0xcfc3ffff;
+	else if (mode < XFER_UDMA_0)
+		mask = 0x31c001ff;
+	else
+		mask = 0x303c0000;
+
+	timing = hpt37x_find_mode(ap, mode);
+
 	pci_read_config_dword(pdev, addr1, &reg);
-	mode = hpt37x_find_mode(ap, adev->pio_mode);
+	reg = (reg & ~mask) | (timing & mask);
+	pci_write_config_dword(pdev, addr1, reg);
+}
 
-	printk("Find mode for %d reports %X\n", adev->pio_mode, mode);
-	mode &= 0xCFC3FFFF;	/* Leave DMA bits alone */
-	reg &= ~0xCFC3FFFF;	/* Strip timing bits */
-	pci_write_config_dword(pdev, addr1, reg | mode);
+/**
+ *	hpt372_set_piomode		-	PIO setup
+ *	@ap: ATA interface
+ *	@adev: device on the interface
+ *
+ *	Perform PIO mode setup.
+ */
+
+static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+	hpt372_set_mode(ap, adev, adev->pio_mode);
 }
 
 /**
@@ -524,33 +526,12 @@ static void hpt372_set_piomode(struct at
  *	@ap: ATA interface
  *	@adev: Device being configured
  *
- *	Set up the channel for MWDMA or UDMA modes. Much the same as with
- *	PIO, load the mode number and then set MWDMA or UDMA flag.
+ *	Set up the channel for MWDMA or UDMA modes.
  */
 
 static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev)
 {
-	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-	u32 addr1, addr2;
-	u32 reg, mode, mask;
-	u8 fast;
-
-	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
-	addr2 = 0x51 + 4 * ap->port_no;
-
-	/* Fast interrupt prediction disable, hold off interrupt disable */
-	pci_read_config_byte(pdev, addr2, &fast);
-	fast &= ~0x07;
-	pci_write_config_byte(pdev, addr2, fast);
-
-	mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000;
-
-	pci_read_config_dword(pdev, addr1, &reg);
-	mode = hpt37x_find_mode(ap, adev->dma_mode);
-	printk("Find mode for DMA %d reports %X\n", adev->dma_mode, mode);
-	mode &= mask;
-	reg &= ~mask;
-	pci_write_config_dword(pdev, addr1, reg | mode);
+	hpt372_set_mode(ap, adev, adev->dma_mode);
 }
 
 /**
@@ -1006,7 +987,7 @@ static int hpt37x_init_one(struct pci_de
 	}
 
 	/* Now kick off ATA set up */
-	return ata_pci_sff_init_one(dev, ppi, &hpt37x_sht, private_data);
+	return ata_pci_sff_init_one(dev, ppi, &hpt37x_sht, private_data, 0);
 }
 
 static const struct pci_device_id hpt37x[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt3x2n.c linux-libre-2.6.34-gnu1/drivers/ata/pata_hpt3x2n.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt3x2n.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_hpt3x2n.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"pata_hpt3x2n"
-#define DRV_VERSION	"0.3.8"
+#define DRV_VERSION	"0.3.10"
 
 enum {
 	HPT_PCI_FAST	=	(1 << 31),
@@ -45,25 +45,24 @@ struct hpt_chip {
 
 /* key for bus clock timings
  * bit
- * 0:3    data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
- *        DMA. cycles = value + 1
- * 4:8    data_low_time. active time of DIOW_/DIOR_ for PIO and MW
- *        DMA. cycles = value + 1
- * 9:12   cmd_high_time. inactive time of DIOW_/DIOR_ during task file
+ * 0:3    data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA.
+ *        cycles = value + 1
+ * 4:8    data_low_time. Active time of DIOW_/DIOR_ for PIO and MW DMA.
+ *        cycles = value + 1
+ * 9:12   cmd_high_time. Inactive time of DIOW_/DIOR_ during task file
  *        register access.
- * 13:17  cmd_low_time. active time of DIOW_/DIOR_ during task file
+ * 13:17  cmd_low_time. Active time of DIOW_/DIOR_ during task file
  *        register access.
- * 18:21  udma_cycle_time. clock freq and clock cycles for UDMA xfer.
- *        during task file register access.
- * 22:24  pre_high_time. time to initialize 1st cycle for PIO and MW DMA
- *        xfer.
- * 25:27  cmd_pre_high_time. time to initialize 1st PIO cycle for task
+ * 18:20  udma_cycle_time. Clock cycles for UDMA xfer.
+ * 21     CLK frequency for UDMA: 0=ATA clock, 1=dual ATA clock.
+ * 22:24  pre_high_time. Time to initialize 1st cycle for PIO and MW DMA xfer.
+ * 25:27  cmd_pre_high_time. Time to initialize 1st PIO cycle for task file
  *        register access.
- * 28     UDMA enable
- * 29     DMA enable
- * 30     PIO_MST enable. if set, the chip is in bus master mode during
- *        PIO.
- * 31     FIFO enable.
+ * 28     UDMA enable.
+ * 29     DMA  enable.
+ * 30     PIO_MST enable. If set, the chip is in bus master mode during
+ *        PIO xfer.
+ * 31     FIFO enable. Only for PIO.
  */
 
 /* 66MHz DPLL clocks */
@@ -161,20 +160,12 @@ static int hpt3x2n_pre_reset(struct ata_
 	return ata_sff_prereset(link, deadline);
 }
 
-/**
- *	hpt3x2n_set_piomode		-	PIO setup
- *	@ap: ATA interface
- *	@adev: device on the interface
- *
- *	Perform PIO mode setup.
- */
-
-static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev)
+static void hpt3x2n_set_mode(struct ata_port *ap, struct ata_device *adev,
+			     u8 mode)
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u32 addr1, addr2;
-	u32 reg;
-	u32 mode;
+	u32 reg, timing, mask;
 	u8 fast;
 
 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
@@ -185,11 +176,32 @@ static void hpt3x2n_set_piomode(struct a
 	fast &= ~0x07;
 	pci_write_config_byte(pdev, addr2, fast);
 
+	/* Determine timing mask and find matching mode entry */
+	if (mode < XFER_MW_DMA_0)
+		mask = 0xcfc3ffff;
+	else if (mode < XFER_UDMA_0)
+		mask = 0x31c001ff;
+	else
+		mask = 0x303c0000;
+
+	timing = hpt3x2n_find_mode(ap, mode);
+
 	pci_read_config_dword(pdev, addr1, &reg);
-	mode = hpt3x2n_find_mode(ap, adev->pio_mode);
-	mode &= 0xCFC3FFFF;	/* Leave DMA bits alone */
-	reg &= ~0xCFC3FFFF;	/* Strip timing bits */
-	pci_write_config_dword(pdev, addr1, reg | mode);
+	reg = (reg & ~mask) | (timing & mask);
+	pci_write_config_dword(pdev, addr1, reg);
+}
+
+/**
+ *	hpt3x2n_set_piomode		-	PIO setup
+ *	@ap: ATA interface
+ *	@adev: device on the interface
+ *
+ *	Perform PIO mode setup.
+ */
+
+static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+	hpt3x2n_set_mode(ap, adev, adev->pio_mode);
 }
 
 /**
@@ -197,32 +209,12 @@ static void hpt3x2n_set_piomode(struct a
  *	@ap: ATA interface
  *	@adev: Device being configured
  *
- *	Set up the channel for MWDMA or UDMA modes. Much the same as with
- *	PIO, load the mode number and then set MWDMA or UDMA flag.
+ *	Set up the channel for MWDMA or UDMA modes.
  */
 
 static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev)
 {
-	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-	u32 addr1, addr2;
-	u32 reg, mode, mask;
-	u8 fast;
-
-	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
-	addr2 = 0x51 + 4 * ap->port_no;
-
-	/* Fast interrupt prediction disable, hold off interrupt disable */
-	pci_read_config_byte(pdev, addr2, &fast);
-	fast &= ~0x07;
-	pci_write_config_byte(pdev, addr2, fast);
-
-	mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000;
-
-	pci_read_config_dword(pdev, addr1, &reg);
-	mode = hpt3x2n_find_mode(ap, adev->dma_mode);
-	mode &= mask;
-	reg &= ~mask;
-	pci_write_config_dword(pdev, addr1, reg | mode);
+	hpt3x2n_set_mode(ap, adev, adev->dma_mode);
 }
 
 /**
@@ -544,19 +536,19 @@ static int hpt3x2n_init_one(struct pci_d
 	       pci_mhz);
 	/* Set our private data up. We only need a few flags so we use
 	   it directly */
-	if (pci_mhz > 60) {
+	if (pci_mhz > 60)
 		hpriv = (void *)(PCI66 | USE_DPLL);
-		/*
-		 * On  HPT371N, if ATA clock is 66 MHz we must set bit 2 in
-		 * the MISC. register to stretch the UltraDMA Tss timing.
-		 * NOTE: This register is only writeable via I/O space.
-		 */
-		if (dev->device == PCI_DEVICE_ID_TTI_HPT371)
-			outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c);
-	}
+
+	/*
+	 * On  HPT371N, if ATA clock is 66 MHz we must set bit 2 in
+	 * the MISC. register to stretch the UltraDMA Tss timing.
+	 * NOTE: This register is only writeable via I/O space.
+	 */
+	if (dev->device == PCI_DEVICE_ID_TTI_HPT371)
+		outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c);
 
 	/* Now kick off ATA set up */
-	return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv);
+	return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv, 0);
 }
 
 static const struct pci_device_id hpt3x2n[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt3x3.c linux-libre-2.6.34-gnu1/drivers/ata/pata_hpt3x3.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt3x3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_hpt3x3.c	2010-05-16 17:17:36.000000000 -0400
@@ -180,7 +180,7 @@ static void hpt3x3_init_chipset(struct p
  *	@id: Entry in match table
  *
  *	Perform basic initialisation. We set the device up so we access all
- *	ports via BAR4. This is neccessary to work around errata.
+ *	ports via BAR4. This is necessary to work around errata.
  */
 
 static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_icside.c linux-libre-2.6.34-gnu1/drivers/ata/pata_icside.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_icside.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_icside.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <linux/ata.h>
 #include <linux/libata.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_it8213.c linux-libre-2.6.34-gnu1/drivers/ata/pata_it8213.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_it8213.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_it8213.c	2010-05-16 17:17:36.000000000 -0400
@@ -273,7 +273,7 @@ static int it8213_init_one (struct pci_d
 		dev_printk(KERN_DEBUG, &pdev->dev,
 			   "version " DRV_VERSION "\n");
 
-	return ata_pci_sff_init_one(pdev, ppi, &it8213_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &it8213_sht, NULL, 0);
 }
 
 static const struct pci_device_id it8213_pci_tbl[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_it821x.c linux-libre-2.6.34-gnu1/drivers/ata/pata_it821x.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_it821x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_it821x.c	2010-05-16 17:17:36.000000000 -0400
@@ -75,6 +75,7 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 
@@ -932,7 +933,7 @@ static int it821x_init_one(struct pci_de
 		else
 			ppi[0] = &info_smart;
 	}
-	return ata_pci_sff_init_one(pdev, ppi, &it821x_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &it821x_sht, NULL, 0);
 }
 
 #ifdef CONFIG_PM
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_jmicron.c linux-libre-2.6.34-gnu1/drivers/ata/pata_jmicron.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_jmicron.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_jmicron.c	2010-05-16 17:17:36.000000000 -0400
@@ -144,7 +144,7 @@ static int jmicron_init_one (struct pci_
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
 
-	return ata_pci_sff_init_one(pdev, ppi, &jmicron_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &jmicron_sht, NULL, 0);
 }
 
 static const struct pci_device_id jmicron_pci_tbl[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_macio.c linux-libre-2.6.34-gnu1/drivers/ata/pata_macio.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_macio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_macio.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/pmu.h>
 #include <linux/scatterlist.h>
 #include <linux/of.h>
+#include <linux/gfp.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_marvell.c linux-libre-2.6.34-gnu1/drivers/ata/pata_marvell.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_marvell.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_marvell.c	2010-05-16 17:17:36.000000000 -0400
@@ -147,13 +147,13 @@ static int marvell_init_one (struct pci_
 	if (pdev->device == 0x6101)
 		ppi[1] = &ata_dummy_port_info;
 
-#if defined(CONFIG_AHCI) || defined(CONFIG_AHCI_MODULE)
+#if defined(CONFIG_SATA_AHCI) || defined(CONFIG_SATA_AHCI_MODULE)
 	if (!marvell_pata_active(pdev)) {
 		printk(KERN_INFO DRV_NAME ": PATA port not active, deferring to AHCI driver.\n");
 		return -ENODEV;
 	}
 #endif
-	return ata_pci_sff_init_one(pdev, ppi, &marvell_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &marvell_sht, NULL, 0);
 }
 
 static const struct pci_device_id marvell_pci_tbl[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_mpc52xx.c linux-libre-2.6.34-gnu1/drivers/ata/pata_mpc52xx.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_mpc52xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_mpc52xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/libata.h>
 #include <linux/of_platform.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_netcell.c linux-libre-2.6.34-gnu1/drivers/ata/pata_netcell.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_netcell.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_netcell.c	2010-05-16 17:17:36.000000000 -0400
@@ -82,7 +82,7 @@ static int netcell_init_one (struct pci_
 	ata_pci_bmdma_clear_simplex(pdev);
 
 	/* And let the library code do the work */
-	return ata_pci_sff_init_one(pdev, port_info, &netcell_sht, NULL);
+	return ata_pci_sff_init_one(pdev, port_info, &netcell_sht, NULL, 0);
 }
 
 static const struct pci_device_id netcell_pci_tbl[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_ns87410.c linux-libre-2.6.34-gnu1/drivers/ata/pata_ns87410.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_ns87410.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_ns87410.c	2010-05-16 17:17:36.000000000 -0400
@@ -148,7 +148,7 @@ static int ns87410_init_one(struct pci_d
 		.port_ops = &ns87410_port_ops
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
-	return ata_pci_sff_init_one(dev, ppi, &ns87410_sht, NULL);
+	return ata_pci_sff_init_one(dev, ppi, &ns87410_sht, NULL, 0);
 }
 
 static const struct pci_device_id ns87410[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_ns87415.c linux-libre-2.6.34-gnu1/drivers/ata/pata_ns87415.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_ns87415.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_ns87415.c	2010-05-16 17:17:36.000000000 -0400
@@ -380,7 +380,7 @@ static int ns87415_init_one (struct pci_
 
 	ns87415_fixup(pdev);
 
-	return ata_pci_sff_init_one(pdev, ppi, &ns87415_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &ns87415_sht, NULL, 0);
 }
 
 static const struct pci_device_id ns87415_pci_tbl[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_octeon_cf.c linux-libre-2.6.34-gnu1/drivers/ata/pata_octeon_cf.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_octeon_cf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_octeon_cf.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/libata.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/workqueue.h>
 #include <scsi/scsi_host.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_oldpiix.c linux-libre-2.6.34-gnu1/drivers/ata/pata_oldpiix.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_oldpiix.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_oldpiix.c	2010-05-16 17:17:36.000000000 -0400
@@ -248,7 +248,7 @@ static int oldpiix_init_one (struct pci_
 		dev_printk(KERN_DEBUG, &pdev->dev,
 			   "version " DRV_VERSION "\n");
 
-	return ata_pci_sff_init_one(pdev, ppi, &oldpiix_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &oldpiix_sht, NULL, 0);
 }
 
 static const struct pci_device_id oldpiix_pci_tbl[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_opti.c linux-libre-2.6.34-gnu1/drivers/ata/pata_opti.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_opti.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_opti.c	2010-05-16 17:17:36.000000000 -0400
@@ -172,7 +172,7 @@ static int opti_init_one(struct pci_dev
 	if (!printed_version++)
 		dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
 
-	return ata_pci_sff_init_one(dev, ppi, &opti_sht, NULL);
+	return ata_pci_sff_init_one(dev, ppi, &opti_sht, NULL, 0);
 }
 
 static const struct pci_device_id opti[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_optidma.c linux-libre-2.6.34-gnu1/drivers/ata/pata_optidma.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_optidma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_optidma.c	2010-05-16 17:17:36.000000000 -0400
@@ -429,7 +429,7 @@ static int optidma_init_one(struct pci_d
 	if (optiplus_with_udma(dev))
 		ppi[0] = &info_82c700_udma;
 
-	return ata_pci_sff_init_one(dev, ppi, &optidma_sht, NULL);
+	return ata_pci_sff_init_one(dev, ppi, &optidma_sht, NULL, 0);
 }
 
 static const struct pci_device_id optidma[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_pcmcia.c linux-libre-2.6.34-gnu1/drivers/ata/pata_pcmcia.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_pcmcia.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_pcmcia.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <scsi/scsi_host.h>
 #include <linux/ata.h>
 #include <linux/libata.h>
@@ -131,12 +132,12 @@ static unsigned int ata_data_xfer_8bit(s
  *	@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
+ *	failing to complete. In some cases this is necessary before a
  *	reset will recover the device.
  *
  */
  
-void pcmcia_8bit_drain_fifo(struct ata_queued_cmd *qc)
+static void pcmcia_8bit_drain_fifo(struct ata_queued_cmd *qc)
 {
 	int count;
 	struct ata_port *ap;
@@ -423,6 +424,8 @@ static struct pcmcia_device_id pcmcia_de
 	PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
 	PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
 	PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
+	PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 1GB", 0x2e6d1829, 0x55d5bffb),
+	PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 4GB", 0x2e6d1829, 0x531e7d10),
 	PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
 	PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),
 	PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
@@ -443,6 +446,8 @@ static struct pcmcia_device_id pcmcia_de
 	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
 	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
 	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
+	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF133", 0x709b1bf1, 0x7558f133),
+	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS8GCF133", 0x709b1bf1, 0xb2f89b47),
 	PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
 	PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
 	PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_pdc202xx_old.c linux-libre-2.6.34-gnu1/drivers/ata/pata_pdc202xx_old.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_pdc202xx_old.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_pdc202xx_old.c	2010-05-16 17:17:36.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,2009 Bartlomiej Zolnierkiewicz
+ *			  (C) 2007,2009,2010 Bartlomiej Zolnierkiewicz
  *
  * Based in part on linux/drivers/ide/pci/pdc202xx_old.c
  *
@@ -35,6 +35,15 @@ static int pdc2026x_cable_detect(struct
 	return ATA_CBL_PATA80;
 }
 
+static void pdc202xx_exec_command(struct ata_port *ap,
+				  const struct ata_taskfile *tf)
+{
+	DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
+
+	iowrite8(tf->command, ap->ioaddr.command_addr);
+	ndelay(400);
+}
+
 /**
  *	pdc202xx_configure_piomode	-	set chip PIO timing
  *	@ap: ATA interface
@@ -271,6 +280,8 @@ static struct ata_port_operations pdc202
 	.cable_detect		= ata_cable_40wire,
 	.set_piomode		= pdc202xx_set_piomode,
 	.set_dmamode		= pdc202xx_set_dmamode,
+
+	.sff_exec_command	= pdc202xx_exec_command,
 };
 
 static struct ata_port_operations pdc2026x_port_ops = {
@@ -284,6 +295,8 @@ static struct ata_port_operations pdc202
 	.dev_config		= pdc2026x_dev_config,
 
 	.port_start		= pdc2026x_port_start,
+
+	.sff_exec_command	= pdc202xx_exec_command,
 };
 
 static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
@@ -324,7 +337,7 @@ static int pdc202xx_init_one(struct pci_
 				return -ENODEV;
 		}
 	}
-	return ata_pci_sff_init_one(dev, ppi, &pdc202xx_sht, NULL);
+	return ata_pci_sff_init_one(dev, ppi, &pdc202xx_sht, NULL, 0);
 }
 
 static const struct pci_device_id pdc202xx[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_piccolo.c linux-libre-2.6.34-gnu1/drivers/ata/pata_piccolo.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_piccolo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_piccolo.c	2010-05-16 17:17:36.000000000 -0400
@@ -95,7 +95,7 @@ static int ata_tosh_init_one(struct pci_
 	};
 	const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
 	/* Just one port for the moment */
-	return ata_pci_sff_init_one(dev, ppi, &tosh_sht, NULL);
+	return ata_pci_sff_init_one(dev, ppi, &tosh_sht, NULL, 0);
 }
 
 static struct pci_device_id ata_tosh[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_radisys.c linux-libre-2.6.34-gnu1/drivers/ata/pata_radisys.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_radisys.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_radisys.c	2010-05-16 17:17:36.000000000 -0400
@@ -227,7 +227,7 @@ static int radisys_init_one (struct pci_
 		dev_printk(KERN_DEBUG, &pdev->dev,
 			   "version " DRV_VERSION "\n");
 
-	return ata_pci_sff_init_one(pdev, ppi, &radisys_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &radisys_sht, NULL, 0);
 }
 
 static const struct pci_device_id radisys_pci_tbl[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_rb532_cf.c linux-libre-2.6.34-gnu1/drivers/ata/pata_rb532_cf.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_rb532_cf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_rb532_cf.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  *
  */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_rdc.c linux-libre-2.6.34-gnu1/drivers/ata/pata_rdc.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_rdc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_rdc.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 #include <linux/dmi.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_rz1000.c linux-libre-2.6.34-gnu1/drivers/ata/pata_rz1000.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_rz1000.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_rz1000.c	2010-05-16 17:17:36.000000000 -0400
@@ -95,7 +95,7 @@ static int rz1000_init_one (struct pci_d
 	printk_once(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
 
 	if (rz1000_fifo_disable(pdev) == 0)
-		return ata_pci_sff_init_one(pdev, ppi, &rz1000_sht, NULL);
+		return ata_pci_sff_init_one(pdev, ppi, &rz1000_sht, NULL, 0);
 
 	printk(KERN_ERR DRV_NAME ": failed to disable read-ahead on chipset..\n");
 	/* Not safe to use so skip */
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_sc1200.c linux-libre-2.6.34-gnu1/drivers/ata/pata_sc1200.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_sc1200.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_sc1200.c	2010-05-16 17:17:36.000000000 -0400
@@ -237,7 +237,7 @@ static int sc1200_init_one(struct pci_de
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
 
-	return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL);
+	return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL, 0);
 }
 
 static const struct pci_device_id sc1200[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_serverworks.c linux-libre-2.6.34-gnu1/drivers/ata/pata_serverworks.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_serverworks.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_serverworks.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 /*
  * pata_serverworks.c 	- Serverworks PATA for new ATA layer
  *			  (C) 2005 Red Hat Inc
+ *			  (C) 2010 Bartlomiej Zolnierkiewicz
  *
  * based upon
  *
@@ -253,7 +254,7 @@ static void serverworks_set_piomode(stru
 	if (serverworks_is_csb(pdev)) {
 		pci_read_config_word(pdev, 0x4A, &csb5_pio);
 		csb5_pio &= ~(0x0F << devbits);
-		pci_write_config_byte(pdev, 0x4A, csb5_pio | (pio << devbits));
+		pci_write_config_word(pdev, 0x4A, csb5_pio | (pio << devbits));
 	}
 }
 
@@ -327,7 +328,7 @@ static int serverworks_fixup_osb4(struct
 		pci_dev_put(isa_dev);
 		return 0;
 	}
-	printk(KERN_WARNING "ata_serverworks: Unable to find bridge.\n");
+	printk(KERN_WARNING DRV_NAME ": Unable to find bridge.\n");
 	return -ENODEV;
 }
 
@@ -459,7 +460,7 @@ static int serverworks_init_one(struct p
 	if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
 		ata_pci_bmdma_clear_simplex(pdev);
 
-	return ata_pci_sff_init_one(pdev, ppi, &serverworks_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &serverworks_sht, NULL, 0);
 }
 
 #ifdef CONFIG_PM
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_sil680.c linux-libre-2.6.34-gnu1/drivers/ata/pata_sil680.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_sil680.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_sil680.c	2010-05-16 17:17:36.000000000 -0400
@@ -356,7 +356,7 @@ static int __devinit sil680_init_one(str
 				 IRQF_SHARED, &sil680_sht);
 
 use_ioports:
-	return ata_pci_sff_init_one(pdev, ppi, &sil680_sht, NULL);
+	return ata_pci_sff_init_one(pdev, ppi, &sil680_sht, NULL, 0);
 }
 
 #ifdef CONFIG_PM
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_sis.c linux-libre-2.6.34-gnu1/drivers/ata/pata_sis.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_sis.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_sis.c	2010-05-16 17:17:36.000000000 -0400
@@ -826,7 +826,7 @@ static int sis_init_one (struct pci_dev
 
 	sis_fixup(pdev, chipset);
 
-	return ata_pci_sff_init_one(pdev, ppi, &sis_sht, chipset);
+	return ata_pci_sff_init_one(pdev, ppi, &sis_sht, chipset, 0);
 }
 
 #ifdef CONFIG_PM
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_sl82c105.c linux-libre-2.6.34-gnu1/drivers/ata/pata_sl82c105.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_sl82c105.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_sl82c105.c	2010-05-16 17:17:36.000000000 -0400
@@ -316,7 +316,7 @@ static int sl82c105_init_one(struct pci_
 	val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
 	pci_write_config_dword(dev, 0x40, val);
 
-	return ata_pci_sff_init_one(dev, ppi, &sl82c105_sht, NULL);
+	return ata_pci_sff_init_one(dev, ppi, &sl82c105_sht, NULL, 0);
 }
 
 static const struct pci_device_id sl82c105[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_triflex.c linux-libre-2.6.34-gnu1/drivers/ata/pata_triflex.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_triflex.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_triflex.c	2010-05-16 17:17:36.000000000 -0400
@@ -201,7 +201,7 @@ static int triflex_init_one(struct pci_d
 	if (!printed_version++)
 		dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
 
-	return ata_pci_sff_init_one(dev, ppi, &triflex_sht, NULL);
+	return ata_pci_sff_init_one(dev, ppi, &triflex_sht, NULL, 0);
 }
 
 static const struct pci_device_id triflex[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pata_via.c linux-libre-2.6.34-gnu1/drivers/ata/pata_via.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pata_via.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pata_via.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  *	VIA VT8233c	-	UDMA100
  *	VIA VT8235	-	UDMA133
  *	VIA VT8237	-	UDMA133
+ *	VIA VT8237A	-	UDMA133
  *	VIA VT8237S	-	UDMA133
  *	VIA VT8251	-	UDMA133
  *
@@ -57,6 +58,7 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 #include <linux/dmi.h>
@@ -64,26 +66,15 @@
 #define DRV_NAME "pata_via"
 #define DRV_VERSION "0.3.4"
 
-/*
- *	The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
- *	driver.
- */
-
 enum {
-	VIA_UDMA	= 0x007,
-	VIA_UDMA_NONE	= 0x000,
-	VIA_UDMA_33	= 0x001,
-	VIA_UDMA_66	= 0x002,
-	VIA_UDMA_100	= 0x003,
-	VIA_UDMA_133	= 0x004,
-	VIA_BAD_PREQ	= 0x010, /* Crashes if PREQ# till DDACK# set */
-	VIA_BAD_CLK66	= 0x020, /* 66 MHz clock doesn't work correctly */
-	VIA_SET_FIFO	= 0x040, /* Needs to have FIFO split set */
-	VIA_NO_UNMASK	= 0x080, /* Doesn't work with IRQ unmasking on */
-	VIA_BAD_ID	= 0x100, /* Has wrong vendor ID (0x1107) */
-	VIA_BAD_AST	= 0x200, /* Don't touch Address Setup Timing */
-	VIA_NO_ENABLES	= 0x400, /* Has no enablebits */
-	VIA_SATA_PATA	= 0x800, /* SATA/PATA combined configuration */
+	VIA_BAD_PREQ	= 0x01, /* Crashes if PREQ# till DDACK# set */
+	VIA_BAD_CLK66	= 0x02, /* 66 MHz clock doesn't work correctly */
+	VIA_SET_FIFO	= 0x04, /* Needs to have FIFO split set */
+	VIA_NO_UNMASK	= 0x08, /* Doesn't work with IRQ unmasking on */
+	VIA_BAD_ID	= 0x10, /* Has wrong vendor ID (0x1107) */
+	VIA_BAD_AST	= 0x20, /* Don't touch Address Setup Timing */
+	VIA_NO_ENABLES	= 0x40, /* Has no enablebits */
+	VIA_SATA_PATA	= 0x80, /* SATA/PATA combined configuration */
 };
 
 enum {
@@ -99,40 +90,37 @@ static const struct via_isa_bridge {
 	u16 id;
 	u8 rev_min;
 	u8 rev_max;
-	u16 flags;
+	u8 udma_mask;
+	u8 flags;
 } via_isa_bridges[] = {
-	{ "vx855",	PCI_DEVICE_ID_VIA_VX855,    0x00, 0x2f,
-	  VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA },
-	{ "vx800",	PCI_DEVICE_ID_VIA_VX800,    0x00, 0x2f, VIA_UDMA_133 |
-	VIA_BAD_AST | VIA_SATA_PATA },
-	{ "vt8261",	PCI_DEVICE_ID_VIA_8261,     0x00, 0x2f,
-	  VIA_UDMA_133 | VIA_BAD_AST },
-	{ "vt8237s",	PCI_DEVICE_ID_VIA_8237S,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-	{ "vt8251",	PCI_DEVICE_ID_VIA_8251,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-	{ "cx700",	PCI_DEVICE_ID_VIA_CX700,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA },
-	{ "vt6410",	PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
-	{ "vt6415",	PCI_DEVICE_ID_VIA_6415,     0x00, 0xff, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
-	{ "vt8237a",	PCI_DEVICE_ID_VIA_8237A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-	{ "vt8235",	PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-	{ "vt8233a",	PCI_DEVICE_ID_VIA_8233A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
-	{ "vt8233c",	PCI_DEVICE_ID_VIA_8233C_0,  0x00, 0x2f, VIA_UDMA_100 },
-	{ "vt8233",	PCI_DEVICE_ID_VIA_8233_0,   0x00, 0x2f, VIA_UDMA_100 },
-	{ "vt8231",	PCI_DEVICE_ID_VIA_8231,     0x00, 0x2f, VIA_UDMA_100 },
-	{ "vt82c686b",	PCI_DEVICE_ID_VIA_82C686,   0x40, 0x4f, VIA_UDMA_100 },
-	{ "vt82c686a",	PCI_DEVICE_ID_VIA_82C686,   0x10, 0x2f, VIA_UDMA_66 },
-	{ "vt82c686",	PCI_DEVICE_ID_VIA_82C686,   0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 },
-	{ "vt82c596b",	PCI_DEVICE_ID_VIA_82C596,   0x10, 0x2f, VIA_UDMA_66 },
-	{ "vt82c596a",	PCI_DEVICE_ID_VIA_82C596,   0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 },
-	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, VIA_UDMA_33 | VIA_SET_FIFO },
-	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, VIA_UDMA_33 | VIA_SET_FIFO | VIA_BAD_PREQ },
-	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, VIA_UDMA_33 | VIA_SET_FIFO },
-	{ "vt82c586a",	PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, VIA_UDMA_33 | VIA_SET_FIFO },
-	{ "vt82c586",	PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO },
-	{ "vt82c576",	PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK },
-	{ "vt82c576",	PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
-	{ "vtxxxx",	PCI_DEVICE_ID_VIA_ANON,    0x00, 0x2f,
-	  VIA_UDMA_133 | VIA_BAD_AST },
+	{ "vx855",	PCI_DEVICE_ID_VIA_VX855,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
+	{ "vx800",	PCI_DEVICE_ID_VIA_VX800,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
+	{ "vt8261",	PCI_DEVICE_ID_VIA_8261,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+	{ "vt8237s",	PCI_DEVICE_ID_VIA_8237S,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+	{ "vt8251",	PCI_DEVICE_ID_VIA_8251,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+	{ "cx700",	PCI_DEVICE_ID_VIA_CX700,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
+	{ "vt6410",	PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_NO_ENABLES },
+	{ "vt6415",	PCI_DEVICE_ID_VIA_6415,     0x00, 0xff, ATA_UDMA6, VIA_BAD_AST | VIA_NO_ENABLES },
+	{ "vt8237a",	PCI_DEVICE_ID_VIA_8237A,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+	{ "vt8235",	PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+	{ "vt8233a",	PCI_DEVICE_ID_VIA_8233A,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+	{ "vt8233c",	PCI_DEVICE_ID_VIA_8233C_0,  0x00, 0x2f, ATA_UDMA5, },
+	{ "vt8233",	PCI_DEVICE_ID_VIA_8233_0,   0x00, 0x2f, ATA_UDMA5, },
+	{ "vt8231",	PCI_DEVICE_ID_VIA_8231,     0x00, 0x2f, ATA_UDMA5, },
+	{ "vt82c686b",	PCI_DEVICE_ID_VIA_82C686,   0x40, 0x4f, ATA_UDMA5, },
+	{ "vt82c686a",	PCI_DEVICE_ID_VIA_82C686,   0x10, 0x2f, ATA_UDMA4, },
+	{ "vt82c686",	PCI_DEVICE_ID_VIA_82C686,   0x00, 0x0f, ATA_UDMA2, VIA_BAD_CLK66 },
+	{ "vt82c596b",	PCI_DEVICE_ID_VIA_82C596,   0x10, 0x2f, ATA_UDMA4, },
+	{ "vt82c596a",	PCI_DEVICE_ID_VIA_82C596,   0x00, 0x0f, ATA_UDMA2, VIA_BAD_CLK66 },
+	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, ATA_UDMA2, VIA_SET_FIFO },
+	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, ATA_UDMA2, VIA_SET_FIFO | VIA_BAD_PREQ },
+	{ "vt82c586b",	PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, ATA_UDMA2, VIA_SET_FIFO },
+	{ "vt82c586a",	PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, ATA_UDMA2, VIA_SET_FIFO },
+	{ "vt82c586",	PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f,      0x00, VIA_SET_FIFO },
+	{ "vt82c576",	PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f,      0x00, VIA_SET_FIFO | VIA_NO_UNMASK },
+	{ "vt82c576",	PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f,      0x00, VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
+	{ "vtxxxx",	PCI_DEVICE_ID_VIA_ANON,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
 	{ NULL }
 };
 
@@ -191,10 +179,10 @@ static int via_cable_detect(struct ata_p
 		return ATA_CBL_SATA;
 
 	/* Early chips are 40 wire */
-	if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
+	if (config->udma_mask < ATA_UDMA4)
 		return ATA_CBL_PATA40;
 	/* UDMA 66 chips have only drive side logic */
-	else if ((config->flags & VIA_UDMA) < VIA_UDMA_100)
+	else if (config->udma_mask < ATA_UDMA5)
 		return ATA_CBL_PATA_UNK;
 	/* UDMA 100 or later */
 	pci_read_config_dword(pdev, 0x50, &ata66);
@@ -229,11 +217,10 @@ static int via_pre_reset(struct ata_link
 
 
 /**
- *	via_do_set_mode	-	set initial PIO mode data
+ *	via_do_set_mode	-	set transfer mode data
  *	@ap: ATA interface
  *	@adev: ATA device
  *	@mode: ATA mode being programmed
- *	@tdiv: Clocks per PCI clock
  *	@set_ast: Set to program address setup
  *	@udma_type: UDMA mode/format of registers
  *
@@ -244,17 +231,27 @@ static int via_pre_reset(struct ata_link
  *	on the two channels.
  */
 
-static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mode, int tdiv, int set_ast, int udma_type)
+static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev,
+			    int mode, int set_ast, int udma_type)
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	struct ata_device *peer = ata_dev_pair(adev);
 	struct ata_timing t, p;
-	static int via_clock = 33333;	/* Bus clock in kHZ - ought to be tunable one day */
+	static int via_clock = 33333;	/* Bus clock in kHZ */
 	unsigned long T =  1000000000 / via_clock;
-	unsigned long UT = T/tdiv;
+	unsigned long UT = T;
 	int ut;
 	int offset = 3 - (2*ap->port_no) - adev->devno;
 
+	switch (udma_type) {
+	case ATA_UDMA4:
+		UT = T / 2; break;
+	case ATA_UDMA5:
+		UT = T / 3; break;
+	case ATA_UDMA6:
+		UT = T / 4; break;
+	}
+
 	/* Calculate the timing values we require */
 	ata_timing_compute(adev, mode, &t, T, UT);
 
@@ -273,7 +270,7 @@ static void via_do_set_mode(struct ata_p
 
 		pci_read_config_byte(pdev, 0x4C, &setup);
 		setup &= ~(3 << shift);
-		setup |= clamp_val(t.setup, 1, 4) << shift;	/* 1,4 or 1,4 - 1  FIXME */
+		setup |= (clamp_val(t.setup, 1, 4) - 1) << shift;
 		pci_write_config_byte(pdev, 0x4C, setup);
 	}
 
@@ -284,22 +281,20 @@ static void via_do_set_mode(struct ata_p
 		((clamp_val(t.active, 1, 16) - 1) << 4) | (clamp_val(t.recover, 1, 16) - 1));
 
 	/* Load the UDMA bits according to type */
-	switch(udma_type) {
-		default:
-			/* BUG() ? */
-			/* fall through */
-		case 33:
-			ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 5) - 2)) : 0x03;
-			break;
-		case 66:
-			ut = t.udma ? (0xe8 | (clamp_val(t.udma, 2, 9) - 2)) : 0x0f;
-			break;
-		case 100:
-			ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 9) - 2)) : 0x07;
-			break;
-		case 133:
-			ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 9) - 2)) : 0x07;
-			break;
+	switch (udma_type) {
+	case ATA_UDMA2:
+	default:
+		ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 5) - 2)) : 0x03;
+		break;
+	case ATA_UDMA4:
+		ut = t.udma ? (0xe8 | (clamp_val(t.udma, 2, 9) - 2)) : 0x0f;
+		break;
+	case ATA_UDMA5:
+		ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 9) - 2)) : 0x07;
+		break;
+	case ATA_UDMA6:
+		ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 9) - 2)) : 0x07;
+		break;
 	}
 
 	/* Set UDMA unless device is not UDMA capable */
@@ -325,22 +320,16 @@ static void via_set_piomode(struct ata_p
 {
 	const struct via_isa_bridge *config = ap->host->private_data;
 	int set_ast = (config->flags & VIA_BAD_AST) ? 0 : 1;
-	int mode = config->flags & VIA_UDMA;
-	static u8 tclock[5] = { 1, 1, 2, 3, 4 };
-	static u8 udma[5] = { 0, 33, 66, 100, 133 };
 
-	via_do_set_mode(ap, adev, adev->pio_mode, tclock[mode], set_ast, udma[mode]);
+	via_do_set_mode(ap, adev, adev->pio_mode, set_ast, config->udma_mask);
 }
 
 static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev)
 {
 	const struct via_isa_bridge *config = ap->host->private_data;
 	int set_ast = (config->flags & VIA_BAD_AST) ? 0 : 1;
-	int mode = config->flags & VIA_UDMA;
-	static u8 tclock[5] = { 1, 1, 2, 3, 4 };
-	static u8 udma[5] = { 0, 33, 66, 100, 133 };
 
-	via_do_set_mode(ap, adev, adev->dma_mode, tclock[mode], set_ast, udma[mode]);
+	via_do_set_mode(ap, adev, adev->dma_mode, set_ast, config->udma_mask);
 }
 
 /**
@@ -588,6 +577,10 @@ static int via_init_one(struct pci_dev *
 			u8 rev = isa->revision;
 			pci_dev_put(isa);
 
+			if ((id->device == 0x0415 || id->device == 0x3164) &&
+			    (config->id != id->device))
+				continue;
+
 			if (rev >= config->rev_min && rev <= config->rev_max)
 				break;
 		}
@@ -604,33 +597,29 @@ static int via_init_one(struct pci_dev *
 	via_config_fifo(pdev, config->flags);
 
 	/* Clock set up */
-	switch(config->flags & VIA_UDMA) {
-		case VIA_UDMA_NONE:
-			if (config->flags & VIA_NO_UNMASK)
-				ppi[0] = &via_mwdma_info_borked;
-			else
-				ppi[0] = &via_mwdma_info;
-			break;
-		case VIA_UDMA_33:
-			ppi[0] = &via_udma33_info;
-			break;
-		case VIA_UDMA_66:
-			ppi[0] = &via_udma66_info;
-			/* The 66 MHz devices require we enable the clock */
-			pci_read_config_dword(pdev, 0x50, &timing);
-			timing |= 0x80008;
-			pci_write_config_dword(pdev, 0x50, timing);
-			break;
-		case VIA_UDMA_100:
-			ppi[0] = &via_udma100_info;
-			break;
-		case VIA_UDMA_133:
-			ppi[0] = &via_udma133_info;
-			break;
-		default:
-			WARN_ON(1);
-			return -ENODEV;
-	}
+	switch (config->udma_mask) {
+	case 0x00:
+		if (config->flags & VIA_NO_UNMASK)
+			ppi[0] = &via_mwdma_info_borked;
+		else
+			ppi[0] = &via_mwdma_info;
+		break;
+	case ATA_UDMA2:
+		ppi[0] = &via_udma33_info;
+		break;
+	case ATA_UDMA4:
+		ppi[0] = &via_udma66_info;
+		break;
+	case ATA_UDMA5:
+		ppi[0] = &via_udma100_info;
+		break;
+	case ATA_UDMA6:
+		ppi[0] = &via_udma133_info;
+		break;
+	default:
+		WARN_ON(1);
+		return -ENODEV;
+ 	}
 
 	if (config->flags & VIA_BAD_CLK66) {
 		/* Disable the 66MHz clock on problem devices */
@@ -640,7 +629,7 @@ static int via_init_one(struct pci_dev *
 	}
 
 	/* We have established the device type, now fire it up */
-	return ata_pci_sff_init_one(pdev, ppi, &via_sht, (void *)config);
+	return ata_pci_sff_init_one(pdev, ppi, &via_sht, (void *)config, 0);
 }
 
 #ifdef CONFIG_PM
@@ -667,7 +656,7 @@ static int via_reinit_one(struct pci_dev
 
 	via_config_fifo(pdev, config->flags);
 
-	if ((config->flags & VIA_UDMA) == VIA_UDMA_66) {
+	if (config->udma_mask == ATA_UDMA4) {
 		/* The 66 MHz devices require we enable the clock */
 		pci_read_config_dword(pdev, 0x50, &timing);
 		timing |= 0x80008;
@@ -693,6 +682,7 @@ static const struct pci_device_id via[]
 	{ PCI_VDEVICE(VIA, 0x3164), },
 	{ PCI_VDEVICE(VIA, 0x5324), },
 	{ PCI_VDEVICE(VIA, 0xC409), VIA_IDFLAG_SINGLE },
+	{ PCI_VDEVICE(VIA, 0x9001), VIA_IDFLAG_SINGLE },
 
 	{ },
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/pdc_adma.c linux-libre-2.6.34-gnu1/drivers/ata/pdc_adma.c
--- linux-libre-2.6.33-gnu1/drivers/ata/pdc_adma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/pdc_adma.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/sata_fsl.c linux-libre-2.6.34-gnu1/drivers/ata/sata_fsl.c
--- linux-libre-2.6.33-gnu1/drivers/ata/sata_fsl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/sata_fsl.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/sata_inic162x.c linux-libre-2.6.34-gnu1/drivers/ata/sata_inic162x.c
--- linux-libre-2.6.33-gnu1/drivers/ata/sata_inic162x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/sata_inic162x.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
  * happy to assist.
  */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/sata_mv.c linux-libre-2.6.34-gnu1/drivers/ata/sata_mv.c
--- linux-libre-2.6.33-gnu1/drivers/ata/sata_mv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/sata_mv.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,6 +64,7 @@
 #include <linux/ata_platform.h>
 #include <linux/mbus.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/sata_nv.c linux-libre-2.6.34-gnu1/drivers/ata/sata_nv.c
--- linux-libre-2.6.33-gnu1/drivers/ata/sata_nv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/sata_nv.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
@@ -772,7 +773,7 @@ static int nv_adma_slave_config(struct s
 	}
 
 	blk_queue_segment_boundary(sdev->request_queue, segment_boundary);
-	blk_queue_max_hw_segments(sdev->request_queue, sg_tablesize);
+	blk_queue_max_segments(sdev->request_queue, sg_tablesize);
 	ata_port_printk(ap, KERN_INFO,
 		"DMA mask 0x%llX, segment boundary 0x%lX, hw segs %hu\n",
 		(unsigned long long)*ap->host->dev->dma_mask,
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/sata_promise.c linux-libre-2.6.34-gnu1/drivers/ata/sata_promise.c
--- linux-libre-2.6.33-gnu1/drivers/ata/sata_promise.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/sata_promise.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/sata_qstor.c linux-libre-2.6.34-gnu1/drivers/ata/sata_qstor.c
--- linux-libre-2.6.33-gnu1/drivers/ata/sata_qstor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/sata_qstor.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/sata_sil24.c linux-libre-2.6.34-gnu1/drivers/ata/sata_sil24.c
--- linux-libre-2.6.33-gnu1/drivers/ata/sata_sil24.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/sata_sil24.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/sata_sx4.c linux-libre-2.6.34-gnu1/drivers/ata/sata_sx4.c
--- linux-libre-2.6.33-gnu1/drivers/ata/sata_sx4.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/sata_sx4.c	2010-05-16 17:17:36.000000000 -0400
@@ -81,6 +81,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/sata_uli.c linux-libre-2.6.34-gnu1/drivers/ata/sata_uli.c
--- linux-libre-2.6.33-gnu1/drivers/ata/sata_uli.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/sata_uli.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ata/sata_via.c linux-libre-2.6.34-gnu1/drivers/ata/sata_via.c
--- linux-libre-2.6.33-gnu1/drivers/ata/sata_via.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ata/sata_via.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,11 +40,13 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 
 #define DRV_NAME	"sata_via"
-#define DRV_VERSION	"2.4"
+#define DRV_VERSION	"2.6"
 
 /*
  * vt8251 is different from other sata controllers of VIA.  It has two
@@ -80,6 +82,7 @@ static int vt8251_scr_write(struct ata_l
 static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
 static void svia_noop_freeze(struct ata_port *ap);
 static int vt6420_prereset(struct ata_link *link, unsigned long deadline);
+static void vt6420_bmdma_start(struct ata_queued_cmd *qc);
 static int vt6421_pata_cable_detect(struct ata_port *ap);
 static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev);
 static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev);
@@ -121,6 +124,7 @@ static struct ata_port_operations vt6420
 	.inherits		= &svia_base_ops,
 	.freeze			= svia_noop_freeze,
 	.prereset		= vt6420_prereset,
+	.bmdma_start		= vt6420_bmdma_start,
 };
 
 static struct ata_port_operations vt6421_pata_ops = {
@@ -377,6 +381,17 @@ static int vt6420_prereset(struct ata_li
 	return 0;
 }
 
+static void vt6420_bmdma_start(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	if ((qc->tf.command == ATA_CMD_PACKET) &&
+	    (qc->scsicmd->sc_data_direction == DMA_TO_DEVICE)) {
+		/* Prevents corruption on some ATAPI burners */
+		ata_sff_pause(ap);
+	}
+	ata_bmdma_start(qc);
+}
+
 static int vt6421_pata_cable_detect(struct ata_port *ap)
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
@@ -392,14 +407,16 @@ static void vt6421_set_pio_mode(struct a
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	static const u8 pio_bits[] = { 0xA8, 0x65, 0x65, 0x31, 0x20 };
-	pci_write_config_byte(pdev, PATA_PIO_TIMING, pio_bits[adev->pio_mode - XFER_PIO_0]);
+	pci_write_config_byte(pdev, PATA_PIO_TIMING - adev->devno,
+			      pio_bits[adev->pio_mode - XFER_PIO_0]);
 }
 
 static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	static const u8 udma_bits[] = { 0xEE, 0xE8, 0xE6, 0xE4, 0xE2, 0xE1, 0xE0, 0xE0 };
-	pci_write_config_byte(pdev, PATA_UDMA_TIMING, udma_bits[adev->dma_mode - XFER_UDMA_0]);
+	pci_write_config_byte(pdev, PATA_UDMA_TIMING - adev->devno,
+			      udma_bits[adev->dma_mode - XFER_UDMA_0]);
 }
 
 static const unsigned int svia_bar_sizes[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/adummy.c linux-libre-2.6.34-gnu1/drivers/atm/adummy.c
--- linux-libre-2.6.33-gnu1/drivers/atm/adummy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/atm/adummy.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/mm.h>
 #include <linux/timer.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/ambassador.c linux-libre-2.6.34-gnu1/drivers/atm/ambassador.c
--- linux-libre-2.6.33-gnu1/drivers/atm/ambassador.c	2013-05-03 12:02:51.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/atm/ambassador.c	2013-05-03 09:43:55.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/mutex.h>
 #include <linux/firmware.h>
 #include <linux/ihex.h>
+#include <linux/slab.h>
 
 #include <asm/atomic.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/atmtcp.c linux-libre-2.6.34-gnu1/drivers/atm/atmtcp.c
--- linux-libre-2.6.33-gnu1/drivers/atm/atmtcp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/atm/atmtcp.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/atm_tcp.h>
 #include <linux/bitops.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/eni.c linux-libre-2.6.34-gnu1/drivers/atm/eni.c
--- linux-libre-2.6.33-gnu1/drivers/atm/eni.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/atm/eni.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/atm_eni.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/atomic.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/firestream.c linux-libre-2.6.34-gnu1/drivers/atm/firestream.c
--- linux-libre-2.6.33-gnu1/drivers/atm/firestream.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/atm/firestream.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,7 @@
 #include <linux/init.h>
 #include <linux/capability.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 #include <asm/system.h>
 #include <asm/string.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/fore200e.c linux-libre-2.6.34-gnu1/drivers/atm/fore200e.c
--- linux-libre-2.6.33-gnu1/drivers/atm/fore200e.c	2013-05-03 12:02:56.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/atm/fore200e.c	2013-05-03 09:44:00.000000000 -0400
@@ -2064,12 +2064,10 @@ fore200e_get_esi(struct fore200e* fore20
 	return -EBUSY;
     }
 	
-    printk(FORE200E "device %s, rev. %c, S/N: %d, ESI: %02x:%02x:%02x:%02x:%02x:%02x\n", 
+    printk(FORE200E "device %s, rev. %c, S/N: %d, ESI: %pM\n",
 	   fore200e->name, 
 	   (prom->hw_revision & 0xFF) + '@',    /* probably meaningless with SBA boards */
-	   prom->serial_number & 0xFFFF,
-	   prom->mac_addr[ 2 ], prom->mac_addr[ 3 ], prom->mac_addr[ 4 ],
-	   prom->mac_addr[ 5 ], prom->mac_addr[ 6 ], prom->mac_addr[ 7 ]);
+	   prom->serial_number & 0xFFFF, &prom->mac_addr[2]);
 	
     for (i = 0; i < ESI_LEN; i++) {
 	fore200e->esi[ i ] = fore200e->atm_dev->esi[ i ] = prom->mac_addr[ i + 2 ];
@@ -2841,13 +2839,12 @@ fore200e_proc_read(struct atm_dev *dev,
 		"   interrupt line:\t\t%s\n"
 		"   physical base address:\t0x%p\n"
 		"   virtual base address:\t0x%p\n"
-		"   factory address (ESI):\t%02x:%02x:%02x:%02x:%02x:%02x\n"
+		"   factory address (ESI):\t%pM\n"
 		"   board serial number:\t\t%d\n\n",
 		fore200e_irq_itoa(fore200e->irq),
 		(void*)fore200e->phys_base,
 		fore200e->virt_base,
-		fore200e->esi[0], fore200e->esi[1], fore200e->esi[2],
-		fore200e->esi[3], fore200e->esi[4], fore200e->esi[5],
+		fore200e->esi,
 		fore200e->esi[4] * 256 + fore200e->esi[5]);
 
 	return len;
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/he.c linux-libre-2.6.34-gnu1/drivers/atm/he.c
--- linux-libre-2.6.33-gnu1/drivers/atm/he.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/atm/he.c	2010-05-16 17:17:36.000000000 -0400
@@ -67,6 +67,7 @@
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/horizon.c linux-libre-2.6.34-gnu1/drivers/atm/horizon.c
--- linux-libre-2.6.33-gnu1/drivers/atm/horizon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/atm/horizon.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/idt77105.c linux-libre-2.6.34-gnu1/drivers/atm/idt77105.c
--- linux-libre-2.6.33-gnu1/drivers/atm/idt77105.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/atm/idt77105.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/capability.h>
 #include <linux/atm_idt77105.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <asm/param.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/idt77252.c linux-libre-2.6.34-gnu1/drivers/atm/idt77252.c
--- linux-libre-2.6.33-gnu1/drivers/atm/idt77252.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/atm/idt77252.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@
 #include <linux/wait.h>
 #include <linux/jiffies.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -3557,10 +3558,7 @@ init_card(struct atm_dev *dev)
 	if (tmp) {
 		memcpy(card->atmdev->esi, tmp->dev_addr, 6);
 
-		printk("%s: ESI %02x:%02x:%02x:%02x:%02x:%02x\n",
-		       card->name, card->atmdev->esi[0], card->atmdev->esi[1],
-		       card->atmdev->esi[2], card->atmdev->esi[3],
-		       card->atmdev->esi[4], card->atmdev->esi[5]);
+		printk("%s: ESI %pM\n", card->name, card->atmdev->esi);
 	}
 	/*
 	 * XXX: </hack>
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/iphase.c linux-libre-2.6.34-gnu1/drivers/atm/iphase.c
--- linux-libre-2.6.33-gnu1/drivers/atm/iphase.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/atm/iphase.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,6 +54,7 @@
 #include <linux/uio.h>  
 #include <linux/init.h>  
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <asm/system.h>  
 #include <asm/io.h>  
 #include <asm/atomic.h>  
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/lanai.c linux-libre-2.6.34-gnu1/drivers/atm/lanai.c
--- linux-libre-2.6.33-gnu1/drivers/atm/lanai.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/atm/lanai.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,6 +55,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/atmdev.h>
 #include <asm/io.h>
@@ -306,11 +307,10 @@ static void vci_bitfield_iterate(struct
 	const unsigned long *lp,
 	void (*func)(struct lanai_dev *,vci_t vci))
 {
-	vci_t vci = find_first_bit(lp, NUM_VCI);
-	while (vci < NUM_VCI) {
+	vci_t vci;
+
+	for_each_set_bit(vci, lp, NUM_VCI)
 		func(lanai, vci);
-		vci = find_next_bit(lp, NUM_VCI, vci + 1);
-	}
 }
 
 /* -------------------- BUFFER  UTILITIES: */
@@ -998,9 +998,7 @@ static int __devinit eeprom_validate(str
 			    (unsigned int) e[EEPROM_MAC_REV + i]);
 			return -EIO;
 		}
-	DPRINTK("eeprom: MAC address = %02X:%02X:%02X:%02X:%02X:%02X\n",
-		e[EEPROM_MAC + 0], e[EEPROM_MAC + 1], e[EEPROM_MAC + 2],
-		e[EEPROM_MAC + 3], e[EEPROM_MAC + 4], e[EEPROM_MAC + 5]);
+	DPRINTK("eeprom: MAC address = %pM\n", &e[EEPROM_MAC]);
 	/* Verify serial number */
 	lanai->serialno = eeprom_be4(lanai, EEPROM_SERIAL);
 	v = eeprom_be4(lanai, EEPROM_SERIAL_REV);
@@ -2483,14 +2481,8 @@ static int lanai_proc_read(struct atm_de
 		return sprintf(page, "revision: board=%d, pci_if=%d\n",
 		    lanai->board_rev, (int) lanai->pci->revision);
 	if (left-- == 0)
-		return sprintf(page, "EEPROM ESI: "
-		    "%02X:%02X:%02X:%02X:%02X:%02X\n",
-		    lanai->eeprom[EEPROM_MAC + 0],
-		    lanai->eeprom[EEPROM_MAC + 1],
-		    lanai->eeprom[EEPROM_MAC + 2],
-		    lanai->eeprom[EEPROM_MAC + 3],
-		    lanai->eeprom[EEPROM_MAC + 4],
-		    lanai->eeprom[EEPROM_MAC + 5]);
+		return sprintf(page, "EEPROM ESI: %pM\n",
+		    &lanai->eeprom[EEPROM_MAC]);
 	if (left-- == 0)
 		return sprintf(page, "status: SOOL=%d, LOCD=%d, LED=%d, "
 		    "GPIN=%d\n", (lanai->status & STATUS_SOOL) ? 1 : 0,
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/nicstar.c linux-libre-2.6.34-gnu1/drivers/atm/nicstar.c
--- linux-libre-2.6.33-gnu1/drivers/atm/nicstar.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/atm/nicstar.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,7 @@
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
@@ -807,9 +808,7 @@ static int __devinit ns_init_card(int i,
       }
    }
 
-   printk("nicstar%d: MAC address %02X:%02X:%02X:%02X:%02X:%02X\n", i,
-          card->atmdev->esi[0], card->atmdev->esi[1], card->atmdev->esi[2],
-          card->atmdev->esi[3], card->atmdev->esi[4], card->atmdev->esi[5]);
+   printk("nicstar%d: MAC address %pM\n", i, card->atmdev->esi);
 
    card->atmdev->dev_data = card;
    card->atmdev->ci_range.vpi_bits = card->vpibits;
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/solos-pci.c linux-libre-2.6.34-gnu1/drivers/atm/solos-pci.c
--- linux-libre-2.6.33-gnu1/drivers/atm/solos-pci.c	2013-05-03 12:03:04.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/atm/solos-pci.c	2013-05-03 09:44:07.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/firmware.h>
 #include <linux/ctype.h>
 #include <linux/swab.h>
+#include <linux/slab.h>
 
 #define VERSION "0.07"
 #define PTAG "solos-pci"
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/suni.c linux-libre-2.6.34-gnu1/drivers/atm/suni.c
--- linux-libre-2.6.33-gnu1/drivers/atm/suni.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/atm/suni.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/capability.h>
 #include <linux/atm_suni.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <asm/param.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/uPD98402.c linux-libre-2.6.34-gnu1/drivers/atm/uPD98402.c
--- linux-libre-2.6.33-gnu1/drivers/atm/uPD98402.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/atm/uPD98402.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/atmdev.h>
 #include <linux/sonet.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/atm/zatm.c linux-libre-2.6.34-gnu1/drivers/atm/zatm.c
--- linux-libre-2.6.33-gnu1/drivers/atm/zatm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/atm/zatm.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/capability.h>
 #include <linux/bitops.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 #include <asm/system.h>
 #include <asm/string.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/auxdisplay/cfag12864b.c linux-libre-2.6.34-gnu1/drivers/auxdisplay/cfag12864b.c
--- linux-libre-2.6.33-gnu1/drivers/auxdisplay/cfag12864b.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/auxdisplay/cfag12864b.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/cdev.h>
 #include <linux/delay.h>
 #include <linux/device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/auxdisplay/cfag12864bfb.c linux-libre-2.6.34-gnu1/drivers/auxdisplay/cfag12864bfb.c
--- linux-libre-2.6.33-gnu1/drivers/auxdisplay/cfag12864bfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/auxdisplay/cfag12864bfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,6 @@
 #include <linux/fb.h>
 #include <linux/mm.h>
 #include <linux/platform_device.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/uaccess.h>
 #include <linux/cfag12864b.h>
@@ -81,7 +80,7 @@ static struct fb_ops cfag12864bfb_ops =
 	.fb_mmap = cfag12864bfb_mmap,
 };
 
-static int __init cfag12864bfb_probe(struct platform_device *device)
+static int __devinit cfag12864bfb_probe(struct platform_device *device)
 {
 	int ret = -EINVAL;
  	struct fb_info *info = framebuffer_alloc(0, &device->dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/attribute_container.c linux-libre-2.6.34-gnu1/drivers/base/attribute_container.c
--- linux-libre-2.6.33-gnu1/drivers/base/attribute_container.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/attribute_container.c	2010-05-16 17:17:36.000000000 -0400
@@ -328,6 +328,7 @@ attribute_container_add_attrs(struct dev
 		return sysfs_create_group(&classdev->kobj, cont->grp);
 
 	for (i = 0; attrs[i]; i++) {
+		sysfs_attr_init(&attrs[i]->attr);
 		error = device_create_file(classdev, attrs[i]);
 		if (error)
 			return error;
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/bus.c linux-libre-2.6.34-gnu1/drivers/base/bus.c
--- linux-libre-2.6.33-gnu1/drivers/base/bus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/bus.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/string.h>
 #include "base.h"
@@ -70,7 +71,7 @@ static ssize_t drv_attr_store(struct kob
 	return ret;
 }
 
-static struct sysfs_ops driver_sysfs_ops = {
+static const struct sysfs_ops driver_sysfs_ops = {
 	.show	= drv_attr_show,
 	.store	= drv_attr_store,
 };
@@ -115,7 +116,7 @@ static ssize_t bus_attr_store(struct kob
 	return ret;
 }
 
-static struct sysfs_ops bus_sysfs_ops = {
+static const struct sysfs_ops bus_sysfs_ops = {
 	.show	= bus_attr_show,
 	.store	= bus_attr_store,
 };
@@ -154,7 +155,7 @@ static int bus_uevent_filter(struct kset
 	return 0;
 }
 
-static struct kset_uevent_ops bus_uevent_ops = {
+static const struct kset_uevent_ops bus_uevent_ops = {
 	.filter = bus_uevent_filter,
 };
 
@@ -173,10 +174,10 @@ static ssize_t driver_unbind(struct devi
 	dev = bus_find_device_by_name(bus, NULL, buf);
 	if (dev && dev->driver == drv) {
 		if (dev->parent)	/* Needed for USB */
-			down(&dev->parent->sem);
+			device_lock(dev->parent);
 		device_release_driver(dev);
 		if (dev->parent)
-			up(&dev->parent->sem);
+			device_unlock(dev->parent);
 		err = count;
 	}
 	put_device(dev);
@@ -200,12 +201,12 @@ static ssize_t driver_bind(struct device
 	dev = bus_find_device_by_name(bus, NULL, buf);
 	if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
 		if (dev->parent)	/* Needed for USB */
-			down(&dev->parent->sem);
-		down(&dev->sem);
+			device_lock(dev->parent);
+		device_lock(dev);
 		err = driver_probe_device(drv, dev);
-		up(&dev->sem);
+		device_unlock(dev);
 		if (dev->parent)
-			up(&dev->parent->sem);
+			device_unlock(dev->parent);
 
 		if (err > 0) {
 			/* success */
@@ -744,10 +745,10 @@ static int __must_check bus_rescan_devic
 
 	if (!dev->driver) {
 		if (dev->parent)	/* Needed for USB */
-			down(&dev->parent->sem);
+			device_lock(dev->parent);
 		ret = device_attach(dev);
 		if (dev->parent)
-			up(&dev->parent->sem);
+			device_unlock(dev->parent);
 	}
 	return ret < 0 ? ret : 0;
 }
@@ -779,10 +780,10 @@ int device_reprobe(struct device *dev)
 {
 	if (dev->driver) {
 		if (dev->parent)        /* Needed for USB */
-			down(&dev->parent->sem);
+			device_lock(dev->parent);
 		device_release_driver(dev);
 		if (dev->parent)
-			up(&dev->parent->sem);
+			device_unlock(dev->parent);
 	}
 	return bus_rescan_devices_helper(dev, NULL);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/class.c linux-libre-2.6.34-gnu1/drivers/base/class.c
--- linux-libre-2.6.33-gnu1/drivers/base/class.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/class.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,7 @@ static ssize_t class_attr_show(struct ko
 	ssize_t ret = -EIO;
 
 	if (class_attr->show)
-		ret = class_attr->show(cp->class, buf);
+		ret = class_attr->show(cp->class, class_attr, buf);
 	return ret;
 }
 
@@ -43,7 +43,7 @@ static ssize_t class_attr_store(struct k
 	ssize_t ret = -EIO;
 
 	if (class_attr->store)
-		ret = class_attr->store(cp->class, buf, count);
+		ret = class_attr->store(cp->class, class_attr, buf, count);
 	return ret;
 }
 
@@ -63,7 +63,7 @@ static void class_release(struct kobject
 	kfree(cp);
 }
 
-static struct sysfs_ops class_sysfs_ops = {
+static const struct sysfs_ops class_sysfs_ops = {
 	.show	= class_attr_show,
 	.store	= class_attr_store,
 };
@@ -219,6 +219,8 @@ static void class_create_release(struct
  * This is used to create a struct class pointer that can then be used
  * in calls to device_create().
  *
+ * Returns &struct class pointer on success, or ERR_PTR() on error.
+ *
  * Note, the pointer created here is to be destroyed when finished by
  * making a call to class_destroy().
  */
@@ -490,6 +492,16 @@ void class_interface_unregister(struct c
 	class_put(parent);
 }
 
+ssize_t show_class_attr_string(struct class *class, struct class_attribute *attr,
+                        	char *buf)
+{
+	struct class_attribute_string *cs;
+	cs = container_of(attr, struct class_attribute_string, attr);
+	return snprintf(buf, PAGE_SIZE, "%s\n", cs->str);
+}
+
+EXPORT_SYMBOL_GPL(show_class_attr_string);
+
 struct class_compat {
 	struct kobject *kobj;
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/core.c linux-libre-2.6.34-gnu1/drivers/base/core.c
--- linux-libre-2.6.33-gnu1/drivers/base/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -100,7 +100,7 @@ static ssize_t dev_attr_store(struct kob
 	return ret;
 }
 
-static struct sysfs_ops dev_sysfs_ops = {
+static const struct sysfs_ops dev_sysfs_ops = {
 	.show	= dev_attr_show,
 	.store	= dev_attr_store,
 };
@@ -252,7 +252,7 @@ static int dev_uevent(struct kset *kset,
 	return retval;
 }
 
-static struct kset_uevent_ops device_uevent_ops = {
+static const struct kset_uevent_ops device_uevent_ops = {
 	.filter =	dev_uevent_filter,
 	.name =		dev_uevent_name,
 	.uevent =	dev_uevent,
@@ -306,15 +306,10 @@ static ssize_t store_uevent(struct devic
 {
 	enum kobject_action action;
 
-	if (kobject_action_type(buf, count, &action) == 0) {
+	if (kobject_action_type(buf, count, &action) == 0)
 		kobject_uevent(&dev->kobj, action);
-		goto out;
-	}
-
-	dev_err(dev, "uevent: unsupported action-string; this will "
-		     "be ignored in a future kernel version\n");
-	kobject_uevent(&dev->kobj, KOBJ_ADD);
-out:
+	else
+		dev_err(dev, "uevent: unknown action-string\n");
 	return count;
 }
 
@@ -607,6 +602,7 @@ static struct kobject *get_device_parent
 	int retval;
 
 	if (dev->class) {
+		static DEFINE_MUTEX(gdp_mutex);
 		struct kobject *kobj = NULL;
 		struct kobject *parent_kobj;
 		struct kobject *k;
@@ -623,6 +619,8 @@ static struct kobject *get_device_parent
 		else
 			parent_kobj = &parent->kobj;
 
+		mutex_lock(&gdp_mutex);
+
 		/* find our class-directory at the parent and reference it */
 		spin_lock(&dev->class->p->class_dirs.list_lock);
 		list_for_each_entry(k, &dev->class->p->class_dirs.list, entry)
@@ -631,20 +629,26 @@ static struct kobject *get_device_parent
 				break;
 			}
 		spin_unlock(&dev->class->p->class_dirs.list_lock);
-		if (kobj)
+		if (kobj) {
+			mutex_unlock(&gdp_mutex);
 			return kobj;
+		}
 
 		/* or create a new class-directory at the parent device */
 		k = kobject_create();
-		if (!k)
+		if (!k) {
+			mutex_unlock(&gdp_mutex);
 			return NULL;
+		}
 		k->kset = &dev->class->p->class_dirs;
 		retval = kobject_add(k, parent_kobj, "%s", dev->class->name);
 		if (retval < 0) {
+			mutex_unlock(&gdp_mutex);
 			kobject_put(k);
 			return NULL;
 		}
 		/* do not emit an uevent for this simple "glue" directory */
+		mutex_unlock(&gdp_mutex);
 		return k;
 	}
 
@@ -1341,6 +1345,8 @@ static void root_device_release(struct d
  * 'module' symlink which points to the @owner directory
  * in sysfs.
  *
+ * Returns &struct device pointer on success, or ERR_PTR() on error.
+ *
  * Note: You probably want to use root_device_register().
  */
 struct device *__root_device_register(const char *name, struct module *owner)
@@ -1428,6 +1434,8 @@ static void device_create_release(struct
  * Any further sysfs files that might be required can be created using this
  * pointer.
  *
+ * Returns &struct device pointer on success, or ERR_PTR() on error.
+ *
  * Note: the struct class passed to this function must have previously
  * been created with a call to class_create().
  */
@@ -1488,6 +1496,8 @@ EXPORT_SYMBOL_GPL(device_create_vargs);
  * Any further sysfs files that might be required can be created using this
  * pointer.
  *
+ * Returns &struct device pointer on success, or ERR_PTR() on error.
+ *
  * Note: the struct class passed to this function must have previously
  * been created with a call to class_create().
  */
@@ -1574,22 +1584,16 @@ int device_rename(struct device *dev, ch
 	if (old_class_name) {
 		new_class_name = make_class_name(dev->class->name, &dev->kobj);
 		if (new_class_name) {
-			error = sysfs_create_link_nowarn(&dev->parent->kobj,
-							 &dev->kobj,
-							 new_class_name);
-			if (error)
-				goto out;
-			sysfs_remove_link(&dev->parent->kobj, old_class_name);
+			error = sysfs_rename_link(&dev->parent->kobj,
+						  &dev->kobj,
+						  old_class_name,
+						  new_class_name);
 		}
 	}
 #else
 	if (dev->class) {
-		error = sysfs_create_link_nowarn(&dev->class->p->class_subsys.kobj,
-						 &dev->kobj, dev_name(dev));
-		if (error)
-			goto out;
-		sysfs_remove_link(&dev->class->p->class_subsys.kobj,
-				  old_device_name);
+		error = sysfs_rename_link(&dev->class->p->class_subsys.kobj,
+					  &dev->kobj, old_device_name, new_name);
 	}
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/cpu.c linux-libre-2.6.34-gnu1/drivers/base/cpu.c
--- linux-libre-2.6.33-gnu1/drivers/base/cpu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/cpu.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,11 +10,15 @@
 #include <linux/topology.h>
 #include <linux/device.h>
 #include <linux/node.h>
+#include <linux/gfp.h>
 
 #include "base.h"
 
+static struct sysdev_class_attribute *cpu_sysdev_class_attrs[];
+
 struct sysdev_class cpu_sysdev_class = {
 	.name = "cpu",
+	.attrs = cpu_sysdev_class_attrs,
 };
 EXPORT_SYMBOL(cpu_sysdev_class);
 
@@ -76,34 +80,24 @@ void unregister_cpu(struct cpu *cpu)
 }
 
 #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
-static ssize_t cpu_probe_store(struct class *class, const char *buf,
+static ssize_t cpu_probe_store(struct sysdev_class *class,
+			       struct sysdev_class_attribute *attr,
+			       const char *buf,
 			       size_t count)
 {
 	return arch_cpu_probe(buf, count);
 }
 
-static ssize_t cpu_release_store(struct class *class, const char *buf,
+static ssize_t cpu_release_store(struct sysdev_class *class,
+				 struct sysdev_class_attribute *attr,
+				 const char *buf,
 				 size_t count)
 {
 	return arch_cpu_release(buf, count);
 }
 
-static CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
-static CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store);
-
-int __init cpu_probe_release_init(void)
-{
-	int rc;
-
-	rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
-			       &class_attr_probe.attr);
-	if (!rc)
-		rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
-				       &class_attr_release.attr);
-
-	return rc;
-}
-device_initcall(cpu_probe_release_init);
+static SYSDEV_CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
+static SYSDEV_CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store);
 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
 
 #else /* ... !CONFIG_HOTPLUG_CPU */
@@ -141,31 +135,39 @@ static SYSDEV_ATTR(crash_notes, 0400, sh
 /*
  * Print cpu online, possible, present, and system maps
  */
-static ssize_t print_cpus_map(char *buf, const struct cpumask *map)
+
+struct cpu_attr {
+	struct sysdev_class_attribute attr;
+	const struct cpumask *const * const map;
+};
+
+static ssize_t show_cpus_attr(struct sysdev_class *class,
+			      struct sysdev_class_attribute *attr,
+			      char *buf)
 {
-	int n = cpulist_scnprintf(buf, PAGE_SIZE-2, map);
+	struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr);
+	int n = cpulist_scnprintf(buf, PAGE_SIZE-2, *(ca->map));
 
 	buf[n++] = '\n';
 	buf[n] = '\0';
 	return n;
 }
 
-#define	print_cpus_func(type) \
-static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf)	\
-{									\
-	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)
+#define _CPU_ATTR(name, map)						\
+	{ _SYSDEV_CLASS_ATTR(name, 0444, show_cpus_attr, NULL), map }
 
-print_cpus_func(online);
-print_cpus_func(possible);
-print_cpus_func(present);
+/* Keep in sync with cpu_sysdev_class_attrs */
+static struct cpu_attr cpu_attrs[] = {
+	_CPU_ATTR(online, &cpu_online_mask),
+	_CPU_ATTR(possible, &cpu_possible_mask),
+	_CPU_ATTR(present, &cpu_present_mask),
+};
 
 /*
  * Print values for NR_CPUS and offlined cpus
  */
-static ssize_t print_cpus_kernel_max(struct sysdev_class *class, char *buf)
+static ssize_t print_cpus_kernel_max(struct sysdev_class *class,
+				     struct sysdev_class_attribute *attr, char *buf)
 {
 	int n = snprintf(buf, PAGE_SIZE-2, "%d\n", NR_CPUS - 1);
 	return n;
@@ -175,7 +177,8 @@ static SYSDEV_CLASS_ATTR(kernel_max, 044
 /* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */
 unsigned int total_cpus;
 
-static ssize_t print_cpus_offline(struct sysdev_class *class, char *buf)
+static ssize_t print_cpus_offline(struct sysdev_class *class,
+				  struct sysdev_class_attribute *attr, char *buf)
 {
 	int n = 0, len = PAGE_SIZE-2;
 	cpumask_var_t offline;
@@ -204,29 +207,6 @@ static ssize_t print_cpus_offline(struct
 }
 static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL);
 
-static struct sysdev_class_attribute *cpu_state_attr[] = {
-	&attr_online_map,
-	&attr_possible_map,
-	&attr_present_map,
-	&attr_kernel_max,
-	&attr_offline,
-};
-
-static int cpu_states_init(void)
-{
-	int i;
-	int err = 0;
-
-	for (i = 0;  i < ARRAY_SIZE(cpu_state_attr); i++) {
-		int ret;
-		ret = sysdev_class_create_file(&cpu_sysdev_class,
-						cpu_state_attr[i]);
-		if (!err)
-			err = ret;
-	}
-	return err;
-}
-
 /*
  * register_cpu - Setup a sysfs device for a CPU.
  * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
@@ -272,9 +252,6 @@ int __init cpu_dev_init(void)
 	int err;
 
 	err = sysdev_class_register(&cpu_sysdev_class);
-	if (!err)
-		err = cpu_states_init();
-
 #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
 	if (!err)
 		err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class);
@@ -282,3 +259,16 @@ int __init cpu_dev_init(void)
 
 	return err;
 }
+
+static struct sysdev_class_attribute *cpu_sysdev_class_attrs[] = {
+#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
+	&attr_probe,
+	&attr_release,
+#endif
+	&cpu_attrs[0].attr,
+	&cpu_attrs[1].attr,
+	&cpu_attrs[2].attr,
+	&attr_kernel_max,
+	&attr_offline,
+	NULL
+};
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/dd.c linux-libre-2.6.34-gnu1/drivers/base/dd.c
--- linux-libre-2.6.33-gnu1/drivers/base/dd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/dd.c	2010-05-16 17:17:36.000000000 -0400
@@ -85,7 +85,7 @@ static void driver_sysfs_remove(struct d
  * for before calling this. (It is ok to call with no other effort
  * from a driver's probe() method.)
  *
- * This function must be called with @dev->sem held.
+ * This function must be called with the device lock held.
  */
 int device_bind_driver(struct device *dev)
 {
@@ -190,8 +190,8 @@ EXPORT_SYMBOL_GPL(wait_for_device_probe)
  * This function returns -ENODEV if the device is not registered,
  * 1 if the device is bound successfully and 0 otherwise.
  *
- * This function must be called with @dev->sem held.  When called for a
- * USB interface, @dev->parent->sem must be held as well.
+ * This function must be called with @dev lock held.  When called for a
+ * USB interface, @dev->parent lock must be held as well.
  */
 int driver_probe_device(struct device_driver *drv, struct device *dev)
 {
@@ -233,13 +233,13 @@ static int __device_attach(struct device
  * 0 if no matching driver was found;
  * -ENODEV if the device is not registered.
  *
- * When called for a USB interface, @dev->parent->sem must be held.
+ * When called for a USB interface, @dev->parent lock must be held.
  */
 int device_attach(struct device *dev)
 {
 	int ret = 0;
 
-	down(&dev->sem);
+	device_lock(dev);
 	if (dev->driver) {
 		ret = device_bind_driver(dev);
 		if (ret == 0)
@@ -253,7 +253,7 @@ int device_attach(struct device *dev)
 		ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
 		pm_runtime_put_sync(dev);
 	}
-	up(&dev->sem);
+	device_unlock(dev);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(device_attach);
@@ -276,13 +276,13 @@ static int __driver_attach(struct device
 		return 0;
 
 	if (dev->parent)	/* Needed for USB */
-		down(&dev->parent->sem);
-	down(&dev->sem);
+		device_lock(dev->parent);
+	device_lock(dev);
 	if (!dev->driver)
 		driver_probe_device(drv, dev);
-	up(&dev->sem);
+	device_unlock(dev);
 	if (dev->parent)
-		up(&dev->parent->sem);
+		device_unlock(dev->parent);
 
 	return 0;
 }
@@ -303,8 +303,8 @@ int driver_attach(struct device_driver *
 EXPORT_SYMBOL_GPL(driver_attach);
 
 /*
- * __device_release_driver() must be called with @dev->sem held.
- * When called for a USB interface, @dev->parent->sem must be held as well.
+ * __device_release_driver() must be called with @dev lock held.
+ * When called for a USB interface, @dev->parent lock must be held as well.
  */
 static void __device_release_driver(struct device *dev)
 {
@@ -343,7 +343,7 @@ static void __device_release_driver(stru
  * @dev: device.
  *
  * Manually detach device from driver.
- * When called for a USB interface, @dev->parent->sem must be held.
+ * When called for a USB interface, @dev->parent lock must be held.
  */
 void device_release_driver(struct device *dev)
 {
@@ -352,9 +352,9 @@ void device_release_driver(struct device
 	 * within their ->remove callback for the same device, they
 	 * will deadlock right here.
 	 */
-	down(&dev->sem);
+	device_lock(dev);
 	__device_release_driver(dev);
-	up(&dev->sem);
+	device_unlock(dev);
 }
 EXPORT_SYMBOL_GPL(device_release_driver);
 
@@ -381,13 +381,13 @@ void driver_detach(struct device_driver
 		spin_unlock(&drv->p->klist_devices.k_lock);
 
 		if (dev->parent)	/* Needed for USB */
-			down(&dev->parent->sem);
-		down(&dev->sem);
+			device_lock(dev->parent);
+		device_lock(dev);
 		if (dev->driver == drv)
 			__device_release_driver(dev);
-		up(&dev->sem);
+		device_unlock(dev);
 		if (dev->parent)
-			up(&dev->parent->sem);
+			device_unlock(dev->parent);
 		put_device(dev);
 	}
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/devres.c linux-libre-2.6.34-gnu1/drivers/base/devres.c
--- linux-libre-2.6.33-gnu1/drivers/base/devres.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/devres.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 
 #include <linux/device.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "base.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/devtmpfs.c linux-libre-2.6.34-gnu1/drivers/base/devtmpfs.c
--- linux-libre-2.6.33-gnu1/drivers/base/devtmpfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/devtmpfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/cred.h>
 #include <linux/sched.h>
 #include <linux/init_task.h>
+#include <linux/slab.h>
 
 static struct vfsmount *dev_mnt;
 
@@ -301,6 +302,19 @@ int devtmpfs_delete_node(struct device *
 		if (dentry->d_inode) {
 			err = vfs_getattr(nd.path.mnt, dentry, &stat);
 			if (!err && dev_mynode(dev, dentry->d_inode, &stat)) {
+				struct iattr newattrs;
+				/*
+				 * before unlinking this node, reset permissions
+				 * of possible references like hardlinks
+				 */
+				newattrs.ia_uid = 0;
+				newattrs.ia_gid = 0;
+				newattrs.ia_mode = stat.mode & ~0777;
+				newattrs.ia_valid =
+					ATTR_UID|ATTR_GID|ATTR_MODE;
+				mutex_lock(&dentry->d_inode->i_mutex);
+				notify_change(dentry, &newattrs);
+				mutex_unlock(&dentry->d_inode->i_mutex);
 				err = vfs_unlink(nd.path.dentry->d_inode,
 						 dentry);
 				if (!err || err == -ENOENT)
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/dma-coherent.c linux-libre-2.6.34-gnu1/drivers/base/dma-coherent.c
--- linux-libre-2.6.33-gnu1/drivers/base/dma-coherent.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/dma-coherent.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
  * Coherent per-device memory handling.
  * Borrowed from i386
  */
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/dma-mapping.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/dma-mapping.c linux-libre-2.6.34-gnu1/drivers/base/dma-mapping.c
--- linux-libre-2.6.33-gnu1/drivers/base/dma-mapping.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/dma-mapping.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 /*
  * Managed DMA API
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/driver.c linux-libre-2.6.34-gnu1/drivers/base/driver.c
--- linux-libre-2.6.33-gnu1/drivers/base/driver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/driver.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include "base.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/firmware_class.c linux-libre-2.6.34-gnu1/drivers/base/firmware_class.c
--- linux-libre-2.6.33-gnu1/drivers/base/firmware_class.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/firmware_class.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,7 @@
 #include <linux/kthread.h>
 #include <linux/highmem.h>
 #include <linux/firmware.h>
-#include "base.h"
+#include <linux/slab.h>
 
 #define to_dev(obj) container_of(obj, struct device, kobj)
 
@@ -69,7 +69,9 @@ fw_load_abort(struct firmware_priv *fw_p
 }
 
 static ssize_t
-firmware_timeout_show(struct class *class, char *buf)
+firmware_timeout_show(struct class *class,
+		      struct class_attribute *attr,
+		      char *buf)
 {
 	return sprintf(buf, "%d\n", loading_timeout);
 }
@@ -77,6 +79,7 @@ firmware_timeout_show(struct class *clas
 /**
  * firmware_timeout_store - set number of seconds to wait for firmware
  * @class: device class pointer
+ * @attr: device attribute pointer
  * @buf: buffer to scan for timeout value
  * @count: number of bytes in @buf
  *
@@ -87,7 +90,9 @@ firmware_timeout_show(struct class *clas
  *	Note: zero means 'wait forever'.
  **/
 static ssize_t
-firmware_timeout_store(struct class *class, const char *buf, size_t count)
+firmware_timeout_store(struct class *class,
+			struct class_attribute *attr,
+			const char *buf, size_t count)
 {
 	loading_timeout = simple_strtol(buf, NULL, 10);
 	if (loading_timeout < 0)
@@ -439,6 +444,7 @@ static int fw_setup_device(struct firmwa
 	fw_priv = dev_get_drvdata(f_dev);
 
 	fw_priv->fw = fw;
+	sysfs_bin_attr_init(&fw_priv->attr_data);
 	retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
 	if (retval) {
 		dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__);
@@ -610,7 +616,7 @@ request_firmware_work_func(void *arg)
 }
 
 /**
- * request_firmware_nowait: asynchronous version of request_firmware
+ * request_firmware_nowait - asynchronous version of request_firmware
  * @module: module requesting the firmware
  * @uevent: sends uevent to copy the firmware image if this flag
  *	is non-zero else the firmware copy must be done manually.
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/Kconfig linux-libre-2.6.34-gnu1/drivers/base/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/base/Kconfig	2013-05-03 12:15:14.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/base/Kconfig	2013-05-03 09:54:51.000000000 -0400
@@ -3,35 +3,50 @@ menu "Generic Driver Options"
 config UEVENT_HELPER_PATH
 	string "path to uevent helper"
 	depends on HOTPLUG
-	default "/sbin/hotplug"
+	default ""
 	help
 	  Path to uevent helper program forked by the kernel for
 	  every uevent.
+	  Before the switch to the netlink-based uevent source, this was
+	  used to hook hotplug scripts into kernel device events. It
+	  usually pointed to a shell script at /sbin/hotplug.
+	  This should not be used today, because usual systems create
+	  many events at bootup or device discovery in a very short time
+	  frame. One forked process per event can create so many processes
+	  that it creates a high system load, or on smaller systems
+	  it is known to create out-of-memory situations during bootup.
 
 config DEVTMPFS
-	bool "Create a kernel maintained /dev tmpfs (EXPERIMENTAL)"
+	bool "Maintain a devtmpfs filesystem to mount at /dev"
 	depends on HOTPLUG && SHMEM && TMPFS
 	help
-	  This creates a tmpfs filesystem, and mounts it at bootup
-	  and mounts it at /dev. The kernel driver core creates device
-	  nodes for all registered devices in that filesystem. All device
-	  nodes are owned by root and have the default mode of 0600.
-	  Userspace can add and delete the nodes as needed. This is
-	  intended to simplify bootup, and make it possible to delay
-	  the initial coldplug at bootup done by udev in userspace.
-	  It should also provide a simpler way for rescue systems
-	  to bring up a kernel with dynamic major/minor numbers.
-	  Meaningful symlinks, permissions and device ownership must
-	  still be handled by userspace.
-	  If unsure, say N here.
+	  This creates a tmpfs filesystem instance early at bootup.
+	  In this filesystem, the kernel driver core maintains device
+	  nodes with their default names and permissions for all
+	  registered devices with an assigned major/minor number.
+	  Userspace can modify the filesystem content as needed, add
+	  symlinks, and apply needed permissions.
+	  It provides a fully functional /dev directory, where usually
+	  udev runs on top, managing permissions and adding meaningful
+	  symlinks.
+	  In very limited environments, it may provide a sufficient
+	  functional /dev without any further help. It also allows simple
+	  rescue systems, and reliably handles dynamic major/minor numbers.
 
 config DEVTMPFS_MOUNT
-	bool "Automount devtmpfs at /dev"
+	bool "Automount devtmpfs at /dev, after the kernel mounted the rootfs"
 	depends on DEVTMPFS
 	help
-	  This will mount devtmpfs at /dev if the kernel mounts the root
-	  filesystem. It will not affect initramfs based mounting.
-	  If unsure, say N here.
+	  This will instruct the kernel to automatically mount the
+	  devtmpfs filesystem at /dev, directly after the kernel has
+	  mounted the root filesystem. The behavior can be overridden
+	  with the commandline parameter: devtmpfs.mount=0|1.
+	  This option does not affect initramfs based booting, here
+	  the devtmpfs filesystem always needs to be mounted manually
+	  after the roots is mounted.
+	  With this option enabled, it allows to bring up a system in
+	  rescue mode with init=/bin/sh, even when the /dev directory
+	  on the rootfs is completely empty.
 
 config STANDALONE
 	bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/memory.c linux-libre-2.6.34-gnu1/drivers/base/memory.c
--- linux-libre-2.6.33-gnu1/drivers/base/memory.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/memory.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/mm.h>
 #include <linux/mutex.h>
 #include <linux/stat.h>
+#include <linux/slab.h>
 
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
@@ -44,7 +45,7 @@ static int memory_uevent(struct kset *ks
 	return retval;
 }
 
-static struct kset_uevent_ops memory_uevent_ops = {
+static const struct kset_uevent_ops memory_uevent_ops = {
 	.name		= memory_uevent_name,
 	.uevent		= memory_uevent,
 };
@@ -309,17 +310,18 @@ static SYSDEV_ATTR(removable, 0444, show
  * Block size attribute stuff
  */
 static ssize_t
-print_block_size(struct class *class, char *buf)
+print_block_size(struct sysdev_class *class, struct sysdev_class_attribute *attr,
+		 char *buf)
 {
-	return sprintf(buf, "%#lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
+	return sprintf(buf, "%lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
 }
 
-static CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
+static SYSDEV_CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
 
 static int block_size_init(void)
 {
 	return sysfs_create_file(&memory_sysdev_class.kset.kobj,
-				&class_attr_block_size_bytes.attr);
+				&attr_block_size_bytes.attr);
 }
 
 /*
@@ -330,7 +332,8 @@ static int block_size_init(void)
  */
 #ifdef CONFIG_ARCH_MEMORY_PROBE
 static ssize_t
-memory_probe_store(struct class *class, const char *buf, size_t count)
+memory_probe_store(struct class *class, struct class_attribute *attr,
+		   const char *buf, size_t count)
 {
 	u64 phys_addr;
 	int nid;
@@ -367,7 +370,9 @@ static inline int memory_probe_init(void
 
 /* Soft offline a page */
 static ssize_t
-store_soft_offline_page(struct class *class, const char *buf, size_t count)
+store_soft_offline_page(struct class *class,
+			struct class_attribute *attr,
+			const char *buf, size_t count)
 {
 	int ret;
 	u64 pfn;
@@ -384,7 +389,9 @@ store_soft_offline_page(struct class *cl
 
 /* Forcibly offline a page, including killing processes. */
 static ssize_t
-store_hard_offline_page(struct class *class, const char *buf, size_t count)
+store_hard_offline_page(struct class *class,
+			struct class_attribute *attr,
+			const char *buf, size_t count)
 {
 	int ret;
 	u64 pfn;
@@ -423,12 +430,16 @@ static inline int memory_fail_init(void)
  * differentiation between which *physical* devices each
  * section belongs to...
  */
+int __weak arch_get_memory_phys_device(unsigned long start_pfn)
+{
+	return 0;
+}
 
 static int add_memory_block(int nid, struct mem_section *section,
-			unsigned long state, int phys_device,
-			enum mem_add_context context)
+			unsigned long state, enum mem_add_context context)
 {
 	struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+	unsigned long start_pfn;
 	int ret = 0;
 
 	if (!mem)
@@ -437,7 +448,8 @@ static int add_memory_block(int nid, str
 	mem->phys_index = __section_nr(section);
 	mem->state = state;
 	mutex_init(&mem->state_mutex);
-	mem->phys_device = phys_device;
+	start_pfn = section_nr_to_pfn(mem->phys_index);
+	mem->phys_device = arch_get_memory_phys_device(start_pfn);
 
 	ret = register_memory(mem, section);
 	if (!ret)
@@ -509,7 +521,7 @@ int remove_memory_block(unsigned long no
  */
 int register_new_memory(int nid, struct mem_section *section)
 {
-	return add_memory_block(nid, section, MEM_OFFLINE, 0, HOTPLUG);
+	return add_memory_block(nid, section, MEM_OFFLINE, HOTPLUG);
 }
 
 int unregister_memory_section(struct mem_section *section)
@@ -542,7 +554,7 @@ int __init memory_dev_init(void)
 		if (!present_section_nr(i))
 			continue;
 		err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE,
-					0, BOOT);
+				       BOOT);
 		if (!ret)
 			ret = err;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/module.c linux-libre-2.6.34-gnu1/drivers/base/module.c
--- linux-libre-2.6.33-gnu1/drivers/base/module.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/module.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include "base.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/node.c linux-libre-2.6.34-gnu1/drivers/base/node.c
--- linux-libre-2.6.33-gnu1/drivers/base/node.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/node.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,9 +15,13 @@
 #include <linux/cpu.h>
 #include <linux/device.h>
 #include <linux/swap.h>
+#include <linux/slab.h>
+
+static struct sysdev_class_attribute *node_state_attrs[];
 
 static struct sysdev_class node_class = {
 	.name = "node",
+	.attrs = node_state_attrs,
 };
 
 
@@ -162,8 +166,11 @@ static ssize_t node_read_distance(struct
 	int len = 0;
 	int i;
 
-	/* buf currently PAGE_SIZE, need ~4 chars per node */
-	BUILD_BUG_ON(MAX_NUMNODES*4 > PAGE_SIZE/2);
+	/*
+	 * buf is currently PAGE_SIZE in length and each node needs 4 chars
+	 * at the most (distance + space or newline).
+	 */
+	BUILD_BUG_ON(MAX_NUMNODES * 4 > PAGE_SIZE);
 
 	for_each_online_node(i)
 		len += sprintf(buf + len, "%s%d", i ? " " : "", node_distance(nid, i));
@@ -544,76 +551,52 @@ static ssize_t print_nodes_state(enum no
 	return n;
 }
 
-static ssize_t print_nodes_possible(struct sysdev_class *class, char *buf)
-{
-	return print_nodes_state(N_POSSIBLE, buf);
-}
-
-static ssize_t print_nodes_online(struct sysdev_class *class, char *buf)
-{
-	return print_nodes_state(N_ONLINE, buf);
-}
-
-static ssize_t print_nodes_has_normal_memory(struct sysdev_class *class,
-						char *buf)
-{
-	return print_nodes_state(N_NORMAL_MEMORY, buf);
-}
+struct node_attr {
+	struct sysdev_class_attribute attr;
+	enum node_states state;
+};
 
-static ssize_t print_nodes_has_cpu(struct sysdev_class *class, char *buf)
+static ssize_t show_node_state(struct sysdev_class *class,
+			       struct sysdev_class_attribute *attr, char *buf)
 {
-	return print_nodes_state(N_CPU, buf);
+	struct node_attr *na = container_of(attr, struct node_attr, attr);
+	return print_nodes_state(na->state, buf);
 }
 
-static SYSDEV_CLASS_ATTR(possible, 0444, print_nodes_possible, NULL);
-static SYSDEV_CLASS_ATTR(online, 0444, print_nodes_online, NULL);
-static SYSDEV_CLASS_ATTR(has_normal_memory, 0444, print_nodes_has_normal_memory,
-									NULL);
-static SYSDEV_CLASS_ATTR(has_cpu, 0444, print_nodes_has_cpu, NULL);
+#define _NODE_ATTR(name, state) \
+	{ _SYSDEV_CLASS_ATTR(name, 0444, show_node_state, NULL), state }
 
+static struct node_attr node_state_attr[] = {
+	_NODE_ATTR(possible, N_POSSIBLE),
+	_NODE_ATTR(online, N_ONLINE),
+	_NODE_ATTR(has_normal_memory, N_NORMAL_MEMORY),
+	_NODE_ATTR(has_cpu, N_CPU),
 #ifdef CONFIG_HIGHMEM
-static ssize_t print_nodes_has_high_memory(struct sysdev_class *class,
-						 char *buf)
-{
-	return print_nodes_state(N_HIGH_MEMORY, buf);
-}
-
-static SYSDEV_CLASS_ATTR(has_high_memory, 0444, print_nodes_has_high_memory,
-									 NULL);
+	_NODE_ATTR(has_high_memory, N_HIGH_MEMORY),
 #endif
+};
 
-struct sysdev_class_attribute *node_state_attr[] = {
-	&attr_possible,
-	&attr_online,
-	&attr_has_normal_memory,
+static struct sysdev_class_attribute *node_state_attrs[] = {
+	&node_state_attr[0].attr,
+	&node_state_attr[1].attr,
+	&node_state_attr[2].attr,
+	&node_state_attr[3].attr,
 #ifdef CONFIG_HIGHMEM
-	&attr_has_high_memory,
+	&node_state_attr[4].attr,
 #endif
-	&attr_has_cpu,
+	NULL
 };
 
-static int node_states_init(void)
-{
-	int i;
-	int err = 0;
-
-	for (i = 0;  i < NR_NODE_STATES; i++) {
-		int ret;
-		ret = sysdev_class_create_file(&node_class, node_state_attr[i]);
-		if (!err)
-			err = ret;
-	}
-	return err;
-}
-
 #define NODE_CALLBACK_PRI	2	/* lower than SLAB */
 static int __init register_node_type(void)
 {
 	int ret;
 
+ 	BUILD_BUG_ON(ARRAY_SIZE(node_state_attr) != NR_NODE_STATES);
+ 	BUILD_BUG_ON(ARRAY_SIZE(node_state_attrs)-1 != NR_NODE_STATES);
+
 	ret = sysdev_class_register(&node_class);
 	if (!ret) {
-		ret = node_states_init();
 		hotplug_memory_notifier(node_memory_callback,
 					NODE_CALLBACK_PRI);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/platform.c linux-libre-2.6.34-gnu1/drivers/base/platform.c
--- linux-libre-2.6.33-gnu1/drivers/base/platform.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/platform.c	2010-05-16 17:17:36.000000000 -0400
@@ -128,7 +128,7 @@ struct platform_object {
 };
 
 /**
- * platform_device_put
+ * platform_device_put - destroy a platform device
  * @pdev: platform device to free
  *
  * Free all memory associated with a platform device.  This function must
@@ -152,7 +152,7 @@ static void platform_device_release(stru
 }
 
 /**
- * platform_device_alloc
+ * platform_device_alloc - create a platform device
  * @name: base name of the device we're adding
  * @id: instance id
  *
@@ -177,7 +177,7 @@ struct platform_device *platform_device_
 EXPORT_SYMBOL_GPL(platform_device_alloc);
 
 /**
- * platform_device_add_resources
+ * platform_device_add_resources - add resources to a platform device
  * @pdev: platform device allocated by platform_device_alloc to add resources to
  * @res: set of resources that needs to be allocated for the device
  * @num: number of resources
@@ -202,7 +202,7 @@ int platform_device_add_resources(struct
 EXPORT_SYMBOL_GPL(platform_device_add_resources);
 
 /**
- * platform_device_add_data
+ * platform_device_add_data - add platform-specific data to a platform device
  * @pdev: platform device allocated by platform_device_alloc to add resources to
  * @data: platform specific data for this platform device
  * @size: size of platform specific data
@@ -344,7 +344,7 @@ void platform_device_unregister(struct p
 EXPORT_SYMBOL_GPL(platform_device_unregister);
 
 /**
- * platform_device_register_simple
+ * platform_device_register_simple - add a platform-level device and its resources
  * @name: base name of the device we're adding
  * @id: instance id
  * @res: set of resources that needs to be allocated for the device
@@ -362,6 +362,8 @@ EXPORT_SYMBOL_GPL(platform_device_unregi
  * enumeration tasks, they don't fully conform to the Linux driver model.
  * In particular, when such drivers are built as modules, they can't be
  * "hotplugged".
+ *
+ * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
  */
 struct platform_device *platform_device_register_simple(const char *name,
 							int id,
@@ -396,7 +398,7 @@ error:
 EXPORT_SYMBOL_GPL(platform_device_register_simple);
 
 /**
- * platform_device_register_data
+ * platform_device_register_data - add a platform-level device with platform-specific data
  * @parent: parent device for the device we're adding
  * @name: base name of the device we're adding
  * @id: instance id
@@ -408,6 +410,8 @@ EXPORT_SYMBOL_GPL(platform_device_regist
  * allocated for the device allows drivers using such devices to be
  * unloaded without waiting for the last reference to the device to be
  * dropped.
+ *
+ * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
  */
 struct platform_device *platform_device_register_data(
 		struct device *parent,
@@ -473,7 +477,7 @@ static void platform_drv_shutdown(struct
 }
 
 /**
- * platform_driver_register
+ * platform_driver_register - register a driver for platform-level devices
  * @drv: platform driver structure
  */
 int platform_driver_register(struct platform_driver *drv)
@@ -491,7 +495,7 @@ int platform_driver_register(struct plat
 EXPORT_SYMBOL_GPL(platform_driver_register);
 
 /**
- * platform_driver_unregister
+ * platform_driver_unregister - unregister a driver for platform-level devices
  * @drv: platform driver structure
  */
 void platform_driver_unregister(struct platform_driver *drv)
@@ -548,6 +552,66 @@ int __init_or_module platform_driver_pro
 }
 EXPORT_SYMBOL_GPL(platform_driver_probe);
 
+/**
+ * platform_create_bundle - register driver and create corresponding device
+ * @driver: platform driver structure
+ * @probe: the driver probe routine, probably from an __init section
+ * @res: set of resources that needs to be allocated for the device
+ * @n_res: number of resources
+ * @data: platform specific data for this platform device
+ * @size: size of platform specific data
+ *
+ * Use this in legacy-style modules that probe hardware directly and
+ * register a single platform device and corresponding platform driver.
+ *
+ * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
+ */
+struct platform_device * __init_or_module platform_create_bundle(
+			struct platform_driver *driver,
+			int (*probe)(struct platform_device *),
+			struct resource *res, unsigned int n_res,
+			const void *data, size_t size)
+{
+	struct platform_device *pdev;
+	int error;
+
+	pdev = platform_device_alloc(driver->driver.name, -1);
+	if (!pdev) {
+		error = -ENOMEM;
+		goto err_out;
+	}
+
+	if (res) {
+		error = platform_device_add_resources(pdev, res, n_res);
+		if (error)
+			goto err_pdev_put;
+	}
+
+	if (data) {
+		error = platform_device_add_data(pdev, data, size);
+		if (error)
+			goto err_pdev_put;
+	}
+
+	error = platform_device_add(pdev);
+	if (error)
+		goto err_pdev_put;
+
+	error = platform_driver_probe(driver, probe);
+	if (error)
+		goto err_pdev_del;
+
+	return pdev;
+
+err_pdev_del:
+	platform_device_del(pdev);
+err_pdev_put:
+	platform_device_put(pdev);
+err_out:
+	return ERR_PTR(error);
+}
+EXPORT_SYMBOL_GPL(platform_create_bundle);
+
 /* modalias support enables more hands-off userspace setup:
  * (a) environment variable lets new-style hotplug events work once system is
  *     fully running:  "modprobe $MODALIAS"
@@ -578,7 +642,7 @@ static int platform_uevent(struct device
 }
 
 static const struct platform_device_id *platform_match_id(
-			struct platform_device_id *id,
+			const struct platform_device_id *id,
 			struct platform_device *pdev)
 {
 	while (id->name[0]) {
@@ -994,9 +1058,11 @@ static __initdata LIST_HEAD(early_platfo
 static __initdata LIST_HEAD(early_platform_device_list);
 
 /**
- * early_platform_driver_register
+ * early_platform_driver_register - register early platform driver
  * @epdrv: early_platform driver structure
  * @buf: string passed from early_param()
+ *
+ * Helper function for early_platform_init() / early_platform_init_buffer()
  */
 int __init early_platform_driver_register(struct early_platform_driver *epdrv,
 					  char *buf)
@@ -1048,9 +1114,12 @@ int __init early_platform_driver_registe
 }
 
 /**
- * early_platform_add_devices - add a numbers of early platform devices
+ * early_platform_add_devices - adds a number of early platform devices
  * @devs: array of early platform devices to add
  * @num: number of early platform devices in array
+ *
+ * Used by early architecture code to register early platform devices and
+ * their platform data.
  */
 void __init early_platform_add_devices(struct platform_device **devs, int num)
 {
@@ -1070,8 +1139,12 @@ void __init early_platform_add_devices(s
 }
 
 /**
- * early_platform_driver_register_all
+ * early_platform_driver_register_all - register early platform drivers
  * @class_str: string to identify early platform driver class
+ *
+ * Used by architecture code to register all early platform drivers
+ * for a certain class. If omitted then only early platform drivers
+ * with matching kernel command line class parameters will be registered.
  */
 void __init early_platform_driver_register_all(char *class_str)
 {
@@ -1093,7 +1166,7 @@ void __init early_platform_driver_regist
 }
 
 /**
- * early_platform_match
+ * early_platform_match - find early platform device matching driver
  * @epdrv: early platform driver structure
  * @id: id to match against
  */
@@ -1111,7 +1184,7 @@ early_platform_match(struct early_platfo
 }
 
 /**
- * early_platform_left
+ * early_platform_left - check if early platform driver has matching devices
  * @epdrv: early platform driver structure
  * @id: return true if id or above exists
  */
@@ -1129,7 +1202,7 @@ static  __init int early_platform_left(s
 }
 
 /**
- * early_platform_driver_probe_id
+ * early_platform_driver_probe_id - probe drivers matching class_str and 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
@@ -1199,10 +1272,14 @@ static int __init early_platform_driver_
 }
 
 /**
- * early_platform_driver_probe
+ * early_platform_driver_probe - probe a class of registered drivers
  * @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
+ *
+ * Used by architecture code to probe registered early platform drivers
+ * within a certain class. For probe to happen a registered early platform
+ * device matching a registered early platform driver is needed.
  */
 int __init early_platform_driver_probe(char *class_str,
 				       int nr_probe,
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/power/generic_ops.c linux-libre-2.6.34-gnu1/drivers/base/power/generic_ops.c
--- linux-libre-2.6.33-gnu1/drivers/base/power/generic_ops.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/power/generic_ops.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,233 @@
+/*
+ * drivers/base/power/generic_ops.c - Generic PM callbacks for subsystems
+ *
+ * Copyright (c) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+
+#ifdef CONFIG_PM_RUNTIME
+/**
+ * pm_generic_runtime_idle - Generic runtime idle callback for subsystems.
+ * @dev: Device to handle.
+ *
+ * If PM operations are defined for the @dev's driver and they include
+ * ->runtime_idle(), execute it and return its error code, if nonzero.
+ * Otherwise, execute pm_runtime_suspend() for the device and return 0.
+ */
+int pm_generic_runtime_idle(struct device *dev)
+{
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	if (pm && pm->runtime_idle) {
+		int ret = pm->runtime_idle(dev);
+		if (ret)
+			return ret;
+	}
+
+	pm_runtime_suspend(dev);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pm_generic_runtime_idle);
+
+/**
+ * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems.
+ * @dev: Device to suspend.
+ *
+ * If PM operations are defined for the @dev's driver and they include
+ * ->runtime_suspend(), execute it and return its error code.  Otherwise,
+ * return -EINVAL.
+ */
+int pm_generic_runtime_suspend(struct device *dev)
+{
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	int ret;
+
+	ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : -EINVAL;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend);
+
+/**
+ * pm_generic_runtime_resume - Generic runtime resume callback for subsystems.
+ * @dev: Device to resume.
+ *
+ * If PM operations are defined for the @dev's driver and they include
+ * ->runtime_resume(), execute it and return its error code.  Otherwise,
+ * return -EINVAL.
+ */
+int pm_generic_runtime_resume(struct device *dev)
+{
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	int ret;
+
+	ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : -EINVAL;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pm_generic_runtime_resume);
+#endif /* CONFIG_PM_RUNTIME */
+
+#ifdef CONFIG_PM_SLEEP
+/**
+ * __pm_generic_call - Generic suspend/freeze/poweroff/thaw subsystem callback.
+ * @dev: Device to handle.
+ * @event: PM transition of the system under way.
+ *
+ * If the device has not been suspended at run time, execute the
+ * suspend/freeze/poweroff/thaw callback provided by its driver, if defined, and
+ * return its error code.  Otherwise, return zero.
+ */
+static int __pm_generic_call(struct device *dev, int event)
+{
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	int (*callback)(struct device *);
+
+	if (!pm || pm_runtime_suspended(dev))
+		return 0;
+
+	switch (event) {
+	case PM_EVENT_SUSPEND:
+		callback = pm->suspend;
+		break;
+	case PM_EVENT_FREEZE:
+		callback = pm->freeze;
+		break;
+	case PM_EVENT_HIBERNATE:
+		callback = pm->poweroff;
+		break;
+	case PM_EVENT_THAW:
+		callback = pm->thaw;
+		break;
+	default:
+		callback = NULL;
+		break;
+	}
+
+	return callback ? callback(dev) : 0;
+}
+
+/**
+ * pm_generic_suspend - Generic suspend callback for subsystems.
+ * @dev: Device to suspend.
+ */
+int pm_generic_suspend(struct device *dev)
+{
+	return __pm_generic_call(dev, PM_EVENT_SUSPEND);
+}
+EXPORT_SYMBOL_GPL(pm_generic_suspend);
+
+/**
+ * pm_generic_freeze - Generic freeze callback for subsystems.
+ * @dev: Device to freeze.
+ */
+int pm_generic_freeze(struct device *dev)
+{
+	return __pm_generic_call(dev, PM_EVENT_FREEZE);
+}
+EXPORT_SYMBOL_GPL(pm_generic_freeze);
+
+/**
+ * pm_generic_poweroff - Generic poweroff callback for subsystems.
+ * @dev: Device to handle.
+ */
+int pm_generic_poweroff(struct device *dev)
+{
+	return __pm_generic_call(dev, PM_EVENT_HIBERNATE);
+}
+EXPORT_SYMBOL_GPL(pm_generic_poweroff);
+
+/**
+ * pm_generic_thaw - Generic thaw callback for subsystems.
+ * @dev: Device to thaw.
+ */
+int pm_generic_thaw(struct device *dev)
+{
+	return __pm_generic_call(dev, PM_EVENT_THAW);
+}
+EXPORT_SYMBOL_GPL(pm_generic_thaw);
+
+/**
+ * __pm_generic_resume - Generic resume/restore callback for subsystems.
+ * @dev: Device to handle.
+ * @event: PM transition of the system under way.
+ *
+ * Execute the resume/resotre callback provided by the @dev's driver, if
+ * defined.  If it returns 0, change the device's runtime PM status to 'active'.
+ * Return the callback's error code.
+ */
+static int __pm_generic_resume(struct device *dev, int event)
+{
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	int (*callback)(struct device *);
+	int ret;
+
+	if (!pm)
+		return 0;
+
+	switch (event) {
+	case PM_EVENT_RESUME:
+		callback = pm->resume;
+		break;
+	case PM_EVENT_RESTORE:
+		callback = pm->restore;
+		break;
+	default:
+		callback = NULL;
+		break;
+	}
+
+	if (!callback)
+		return 0;
+
+	ret = callback(dev);
+	if (!ret) {
+		pm_runtime_disable(dev);
+		pm_runtime_set_active(dev);
+		pm_runtime_enable(dev);
+	}
+
+	return ret;
+}
+
+/**
+ * pm_generic_resume - Generic resume callback for subsystems.
+ * @dev: Device to resume.
+ */
+int pm_generic_resume(struct device *dev)
+{
+	return __pm_generic_resume(dev, PM_EVENT_RESUME);
+}
+EXPORT_SYMBOL_GPL(pm_generic_resume);
+
+/**
+ * pm_generic_restore - Generic restore callback for subsystems.
+ * @dev: Device to restore.
+ */
+int pm_generic_restore(struct device *dev)
+{
+	return __pm_generic_resume(dev, PM_EVENT_RESTORE);
+}
+EXPORT_SYMBOL_GPL(pm_generic_restore);
+#endif /* CONFIG_PM_SLEEP */
+
+struct dev_pm_ops generic_subsys_pm_ops = {
+#ifdef CONFIG_PM_SLEEP
+	.suspend = pm_generic_suspend,
+	.resume = pm_generic_resume,
+	.freeze = pm_generic_freeze,
+	.thaw = pm_generic_thaw,
+	.poweroff = pm_generic_poweroff,
+	.restore = pm_generic_restore,
+#endif
+#ifdef CONFIG_PM_RUNTIME
+	.runtime_suspend = pm_generic_runtime_suspend,
+	.runtime_resume = pm_generic_runtime_resume,
+	.runtime_idle = pm_generic_runtime_idle,
+#endif
+};
+EXPORT_SYMBOL_GPL(generic_subsys_pm_ops);
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/power/main.c linux-libre-2.6.34-gnu1/drivers/base/power/main.c
--- linux-libre-2.6.33-gnu1/drivers/base/power/main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/power/main.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/resume-trace.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
+#include <linux/async.h>
 
 #include "../base.h"
 #include "power.h"
@@ -34,14 +35,15 @@
  * because children are guaranteed to be discovered after parents, and
  * are inserted at the back of the list on discovery.
  *
- * Since device_pm_add() may be called with a device semaphore held,
- * we must never try to acquire a device semaphore while holding
+ * Since device_pm_add() may be called with a device lock held,
+ * we must never try to acquire a device lock while holding
  * dpm_list_mutex.
  */
 
 LIST_HEAD(dpm_list);
 
 static DEFINE_MUTEX(dpm_list_mtx);
+static pm_message_t pm_transition;
 
 /*
  * Set once the preparation of devices for a PM transition has started, reset
@@ -56,6 +58,7 @@ static bool transition_started;
 void device_pm_init(struct device *dev)
 {
 	dev->power.status = DPM_ON;
+	init_completion(&dev->power.completion);
 	pm_runtime_init(dev);
 }
 
@@ -111,6 +114,7 @@ void device_pm_remove(struct device *dev
 	pr_debug("PM: Removing info for %s:%s\n",
 		 dev->bus ? dev->bus->name : "No Bus",
 		 kobject_name(&dev->kobj));
+	complete_all(&dev->power.completion);
 	mutex_lock(&dpm_list_mtx);
 	list_del_init(&dev->power.entry);
 	mutex_unlock(&dpm_list_mtx);
@@ -188,6 +192,31 @@ static void initcall_debug_report(struct
 }
 
 /**
+ * dpm_wait - Wait for a PM operation to complete.
+ * @dev: Device to wait for.
+ * @async: If unset, wait only if the device's power.async_suspend flag is set.
+ */
+static void dpm_wait(struct device *dev, bool async)
+{
+	if (!dev)
+		return;
+
+	if (async || (pm_async_enabled && dev->power.async_suspend))
+		wait_for_completion(&dev->power.completion);
+}
+
+static int dpm_wait_fn(struct device *dev, void *async_ptr)
+{
+	dpm_wait(dev, *((bool *)async_ptr));
+	return 0;
+}
+
+static void dpm_wait_for_children(struct device *dev, bool async)
+{
+       device_for_each_child(dev, &async, dpm_wait_fn);
+}
+
+/**
  * pm_op - Execute the PM operation appropriate for given PM event.
  * @dev: Device to handle.
  * @ops: PM operations to choose from.
@@ -271,8 +300,9 @@ static int pm_noirq_op(struct device *de
 	ktime_t calltime, delta, rettime;
 
 	if (initcall_debug) {
-		pr_info("calling  %s_i+ @ %i\n",
-				dev_name(dev), task_pid_nr(current));
+		pr_info("calling  %s+ @ %i, parent: %s\n",
+				dev_name(dev), task_pid_nr(current),
+				dev->parent ? dev_name(dev->parent) : "none");
 		calltime = ktime_get();
 	}
 
@@ -409,8 +439,23 @@ static int device_resume_noirq(struct de
 	if (dev->bus && dev->bus->pm) {
 		pm_dev_dbg(dev, state, "EARLY ");
 		error = pm_noirq_op(dev, dev->bus->pm, state);
+		if (error)
+			goto End;
+	}
+
+	if (dev->type && dev->type->pm) {
+		pm_dev_dbg(dev, state, "EARLY type ");
+		error = pm_noirq_op(dev, dev->type->pm, state);
+		if (error)
+			goto End;
 	}
 
+	if (dev->class && dev->class->pm) {
+		pm_dev_dbg(dev, state, "EARLY class ");
+		error = pm_noirq_op(dev, dev->class->pm, state);
+	}
+
+End:
 	TRACE_RESUME(error);
 	return error;
 }
@@ -468,15 +513,19 @@ static int legacy_resume(struct device *
  * device_resume - Execute "resume" callbacks for given device.
  * @dev: Device to handle.
  * @state: PM transition of the system being carried out.
+ * @async: If true, the device is being resumed asynchronously.
  */
-static int device_resume(struct device *dev, pm_message_t state)
+static int device_resume(struct device *dev, pm_message_t state, bool async)
 {
 	int error = 0;
 
 	TRACE_DEVICE(dev);
 	TRACE_RESUME(0);
 
-	down(&dev->sem);
+	dpm_wait(dev->parent, async);
+	device_lock(dev);
+
+	dev->power.status = DPM_RESUMING;
 
 	if (dev->bus) {
 		if (dev->bus->pm) {
@@ -509,12 +558,30 @@ static int device_resume(struct device *
 		}
 	}
  End:
-	up(&dev->sem);
+	device_unlock(dev);
+	complete_all(&dev->power.completion);
 
 	TRACE_RESUME(error);
 	return error;
 }
 
+static void async_resume(void *data, async_cookie_t cookie)
+{
+	struct device *dev = (struct device *)data;
+	int error;
+
+	error = device_resume(dev, pm_transition, true);
+	if (error)
+		pm_dev_err(dev, pm_transition, " async", error);
+	put_device(dev);
+}
+
+static bool is_async(struct device *dev)
+{
+	return dev->power.async_suspend && pm_async_enabled
+		&& !pm_trace_is_enabled();
+}
+
 /**
  * dpm_resume - Execute "resume" callbacks for non-sysdev devices.
  * @state: PM transition of the system being carried out.
@@ -525,21 +592,33 @@ static int device_resume(struct device *
 static void dpm_resume(pm_message_t state)
 {
 	struct list_head list;
+	struct device *dev;
 	ktime_t starttime = ktime_get();
 
 	INIT_LIST_HEAD(&list);
 	mutex_lock(&dpm_list_mtx);
-	while (!list_empty(&dpm_list)) {
-		struct device *dev = to_device(dpm_list.next);
+	pm_transition = state;
 
+	list_for_each_entry(dev, &dpm_list, power.entry) {
+		if (dev->power.status < DPM_OFF)
+			continue;
+
+		INIT_COMPLETION(dev->power.completion);
+		if (is_async(dev)) {
+			get_device(dev);
+			async_schedule(async_resume, dev);
+		}
+	}
+
+	while (!list_empty(&dpm_list)) {
+		dev = to_device(dpm_list.next);
 		get_device(dev);
-		if (dev->power.status >= DPM_OFF) {
+		if (dev->power.status >= DPM_OFF && !is_async(dev)) {
 			int error;
 
-			dev->power.status = DPM_RESUMING;
 			mutex_unlock(&dpm_list_mtx);
 
-			error = device_resume(dev, state);
+			error = device_resume(dev, state, false);
 
 			mutex_lock(&dpm_list_mtx);
 			if (error)
@@ -554,6 +633,7 @@ static void dpm_resume(pm_message_t stat
 	}
 	list_splice(&list, &dpm_list);
 	mutex_unlock(&dpm_list_mtx);
+	async_synchronize_full();
 	dpm_show_time(starttime, state, NULL);
 }
 
@@ -564,7 +644,7 @@ static void dpm_resume(pm_message_t stat
  */
 static void device_complete(struct device *dev, pm_message_t state)
 {
-	down(&dev->sem);
+	device_lock(dev);
 
 	if (dev->class && dev->class->pm && dev->class->pm->complete) {
 		pm_dev_dbg(dev, state, "completing class ");
@@ -581,7 +661,7 @@ static void device_complete(struct devic
 		dev->bus->pm->complete(dev);
 	}
 
-	up(&dev->sem);
+	device_unlock(dev);
 }
 
 /**
@@ -670,10 +750,26 @@ static int device_suspend_noirq(struct d
 {
 	int error = 0;
 
+	if (dev->class && dev->class->pm) {
+		pm_dev_dbg(dev, state, "LATE class ");
+		error = pm_noirq_op(dev, dev->class->pm, state);
+		if (error)
+			goto End;
+	}
+
+	if (dev->type && dev->type->pm) {
+		pm_dev_dbg(dev, state, "LATE type ");
+		error = pm_noirq_op(dev, dev->type->pm, state);
+		if (error)
+			goto End;
+	}
+
 	if (dev->bus && dev->bus->pm) {
 		pm_dev_dbg(dev, state, "LATE ");
 		error = pm_noirq_op(dev, dev->bus->pm, state);
 	}
+
+End:
 	return error;
 }
 
@@ -731,16 +827,23 @@ static int legacy_suspend(struct device
 	return error;
 }
 
+static int async_error;
+
 /**
  * device_suspend - Execute "suspend" callbacks for given device.
  * @dev: Device to handle.
  * @state: PM transition of the system being carried out.
+ * @async: If true, the device is being suspended asynchronously.
  */
-static int device_suspend(struct device *dev, pm_message_t state)
+static int __device_suspend(struct device *dev, pm_message_t state, bool async)
 {
 	int error = 0;
 
-	down(&dev->sem);
+	dpm_wait_for_children(dev, async);
+	device_lock(dev);
+
+	if (async_error)
+		goto End;
 
 	if (dev->class) {
 		if (dev->class->pm) {
@@ -772,12 +875,44 @@ static int device_suspend(struct device
 			error = legacy_suspend(dev, state, dev->bus->suspend);
 		}
 	}
+
+	if (!error)
+		dev->power.status = DPM_OFF;
+
  End:
-	up(&dev->sem);
+	device_unlock(dev);
+	complete_all(&dev->power.completion);
 
 	return error;
 }
 
+static void async_suspend(void *data, async_cookie_t cookie)
+{
+	struct device *dev = (struct device *)data;
+	int error;
+
+	error = __device_suspend(dev, pm_transition, true);
+	if (error) {
+		pm_dev_err(dev, pm_transition, " async", error);
+		async_error = error;
+	}
+
+	put_device(dev);
+}
+
+static int device_suspend(struct device *dev)
+{
+	INIT_COMPLETION(dev->power.completion);
+
+	if (pm_async_enabled && dev->power.async_suspend) {
+		get_device(dev);
+		async_schedule(async_suspend, dev);
+		return 0;
+	}
+
+	return __device_suspend(dev, pm_transition, false);
+}
+
 /**
  * dpm_suspend - Execute "suspend" callbacks for all non-sysdev devices.
  * @state: PM transition of the system being carried out.
@@ -790,13 +925,15 @@ static int dpm_suspend(pm_message_t stat
 
 	INIT_LIST_HEAD(&list);
 	mutex_lock(&dpm_list_mtx);
+	pm_transition = state;
+	async_error = 0;
 	while (!list_empty(&dpm_list)) {
 		struct device *dev = to_device(dpm_list.prev);
 
 		get_device(dev);
 		mutex_unlock(&dpm_list_mtx);
 
-		error = device_suspend(dev, state);
+		error = device_suspend(dev);
 
 		mutex_lock(&dpm_list_mtx);
 		if (error) {
@@ -804,13 +941,17 @@ static int dpm_suspend(pm_message_t stat
 			put_device(dev);
 			break;
 		}
-		dev->power.status = DPM_OFF;
 		if (!list_empty(&dev->power.entry))
 			list_move(&dev->power.entry, &list);
 		put_device(dev);
+		if (async_error)
+			break;
 	}
 	list_splice(&list, dpm_list.prev);
 	mutex_unlock(&dpm_list_mtx);
+	async_synchronize_full();
+	if (!error)
+		error = async_error;
 	if (!error)
 		dpm_show_time(starttime, state, NULL);
 	return error;
@@ -828,7 +969,7 @@ static int device_prepare(struct device
 {
 	int error = 0;
 
-	down(&dev->sem);
+	device_lock(dev);
 
 	if (dev->bus && dev->bus->pm && dev->bus->pm->prepare) {
 		pm_dev_dbg(dev, state, "preparing ");
@@ -852,7 +993,7 @@ static int device_prepare(struct device
 		suspend_report_result(dev->class->pm->prepare, error);
 	}
  End:
-	up(&dev->sem);
+	device_unlock(dev);
 
 	return error;
 }
@@ -936,3 +1077,14 @@ void __suspend_report_result(const char
 		printk(KERN_ERR "%s(): %pF returns %d\n", function, fn, ret);
 }
 EXPORT_SYMBOL_GPL(__suspend_report_result);
+
+/**
+ * device_pm_wait_for_dev - Wait for suspend/resume of a device to complete.
+ * @dev: Device to wait for.
+ * @subordinate: Device that needs to wait for @dev.
+ */
+void device_pm_wait_for_dev(struct device *subordinate, struct device *dev)
+{
+	dpm_wait(dev, subordinate->power.async_suspend);
+}
+EXPORT_SYMBOL_GPL(device_pm_wait_for_dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/power/Makefile linux-libre-2.6.34-gnu1/drivers/base/power/Makefile
--- linux-libre-2.6.33-gnu1/drivers/base/power/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/power/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 obj-$(CONFIG_PM)	+= sysfs.o
 obj-$(CONFIG_PM_SLEEP)	+= main.o
 obj-$(CONFIG_PM_RUNTIME)	+= runtime.o
+obj-$(CONFIG_PM_OPS)	+= generic_ops.o
 obj-$(CONFIG_PM_TRACE_RTC)	+= trace.o
 
 ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/power/power.h linux-libre-2.6.34-gnu1/drivers/base/power/power.h
--- linux-libre-2.6.33-gnu1/drivers/base/power/power.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/power/power.h	2010-05-16 17:17:36.000000000 -0400
@@ -12,10 +12,10 @@ static inline void pm_runtime_remove(str
 
 #ifdef CONFIG_PM_SLEEP
 
-/*
- * main.c
- */
+/* kernel/power/main.c */
+extern int pm_async_enabled;
 
+/* drivers/base/power/main.c */
 extern struct list_head dpm_list;	/* The active device list */
 
 static inline struct device *to_device(struct list_head *entry)
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/power/runtime.c linux-libre-2.6.34-gnu1/drivers/base/power/runtime.c
--- linux-libre-2.6.33-gnu1/drivers/base/power/runtime.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/power/runtime.c	2010-05-16 17:17:36.000000000 -0400
@@ -1011,6 +1011,50 @@ void pm_runtime_enable(struct device *de
 EXPORT_SYMBOL_GPL(pm_runtime_enable);
 
 /**
+ * pm_runtime_forbid - Block run-time PM of a device.
+ * @dev: Device to handle.
+ *
+ * Increase the device's usage count and clear its power.runtime_auto flag,
+ * so that it cannot be suspended at run time until pm_runtime_allow() is called
+ * for it.
+ */
+void pm_runtime_forbid(struct device *dev)
+{
+	spin_lock_irq(&dev->power.lock);
+	if (!dev->power.runtime_auto)
+		goto out;
+
+	dev->power.runtime_auto = false;
+	atomic_inc(&dev->power.usage_count);
+	__pm_runtime_resume(dev, false);
+
+ out:
+	spin_unlock_irq(&dev->power.lock);
+}
+EXPORT_SYMBOL_GPL(pm_runtime_forbid);
+
+/**
+ * pm_runtime_allow - Unblock run-time PM of a device.
+ * @dev: Device to handle.
+ *
+ * Decrease the device's usage count and set its power.runtime_auto flag.
+ */
+void pm_runtime_allow(struct device *dev)
+{
+	spin_lock_irq(&dev->power.lock);
+	if (dev->power.runtime_auto)
+		goto out;
+
+	dev->power.runtime_auto = true;
+	if (atomic_dec_and_test(&dev->power.usage_count))
+		__pm_runtime_idle(dev);
+
+ out:
+	spin_unlock_irq(&dev->power.lock);
+}
+EXPORT_SYMBOL_GPL(pm_runtime_allow);
+
+/**
  * pm_runtime_init - Initialize run-time PM fields in given device object.
  * @dev: Device object to initialize.
  */
@@ -1028,6 +1072,7 @@ void pm_runtime_init(struct device *dev)
 
 	atomic_set(&dev->power.child_count, 0);
 	pm_suspend_ignore_children(dev, false);
+	dev->power.runtime_auto = true;
 
 	dev->power.request_pending = false;
 	dev->power.request = RPM_REQ_NONE;
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/power/sysfs.c linux-libre-2.6.34-gnu1/drivers/base/power/sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/base/power/sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/power/sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,9 +4,25 @@
 
 #include <linux/device.h>
 #include <linux/string.h>
+#include <linux/pm_runtime.h>
 #include "power.h"
 
 /*
+ *	control - Report/change current runtime PM setting of the device
+ *
+ *	Runtime power management of a device can be blocked with the help of
+ *	this attribute.  All devices have one of the following two values for
+ *	the power/control file:
+ *
+ *	 + "auto\n" to allow the device to be power managed at run time;
+ *	 + "on\n" to prevent the device from being power managed at run time;
+ *
+ *	The default for all devices is "auto", which means that devices may be
+ *	subject to automatic power management, depending on their drivers.
+ *	Changing this attribute to "on" prevents the driver from power managing
+ *	the device at run time.  Doing that while the device is suspended causes
+ *	it to be woken up.
+ *
  *	wakeup - Report/change current wakeup option for device
  *
  *	Some devices support "wakeup" events, which are hardware signals
@@ -38,11 +54,61 @@
  *	wakeup events internally (unless they are disabled), keeping
  *	their hardware in low power modes whenever they're unused.  This
  *	saves runtime power, without requiring system-wide sleep states.
+ *
+ *	async - Report/change current async suspend setting for the device
+ *
+ *	Asynchronous suspend and resume of the device during system-wide power
+ *	state transitions can be enabled by writing "enabled" to this file.
+ *	Analogously, if "disabled" is written to this file, the device will be
+ *	suspended and resumed synchronously.
+ *
+ *	All devices have one of the following two values for power/async:
+ *
+ *	 + "enabled\n" to permit the asynchronous suspend/resume of the device;
+ *	 + "disabled\n" to forbid it;
+ *
+ *	NOTE: It generally is unsafe to permit the asynchronous suspend/resume
+ *	of a device unless it is certain that all of the PM dependencies of the
+ *	device are known to the PM core.  However, for some devices this
+ *	attribute is set to "enabled" by bus type code or device drivers and in
+ *	that cases it should be safe to leave the default value.
  */
 
 static const char enabled[] = "enabled";
 static const char disabled[] = "disabled";
 
+#ifdef CONFIG_PM_RUNTIME
+static const char ctrl_auto[] = "auto";
+static const char ctrl_on[] = "on";
+
+static ssize_t control_show(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	return sprintf(buf, "%s\n",
+				dev->power.runtime_auto ? ctrl_auto : ctrl_on);
+}
+
+static ssize_t control_store(struct device * dev, struct device_attribute *attr,
+			     const char * buf, size_t n)
+{
+	char *cp;
+	int len = n;
+
+	cp = memchr(buf, '\n', n);
+	if (cp)
+		len = cp - buf;
+	if (len == sizeof ctrl_auto - 1 && strncmp(buf, ctrl_auto, len) == 0)
+		pm_runtime_allow(dev);
+	else if (len == sizeof ctrl_on - 1 && strncmp(buf, ctrl_on, len) == 0)
+		pm_runtime_forbid(dev);
+	else
+		return -EINVAL;
+	return n;
+}
+
+static DEVICE_ATTR(control, 0644, control_show, control_store);
+#endif
+
 static ssize_t
 wake_show(struct device * dev, struct device_attribute *attr, char * buf)
 {
@@ -77,9 +143,43 @@ wake_store(struct device * dev, struct d
 
 static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store);
 
+#ifdef CONFIG_PM_SLEEP_ADVANCED_DEBUG
+static ssize_t async_show(struct device *dev, struct device_attribute *attr,
+			  char *buf)
+{
+	return sprintf(buf, "%s\n",
+			device_async_suspend_enabled(dev) ? enabled : disabled);
+}
+
+static ssize_t async_store(struct device *dev, struct device_attribute *attr,
+			   const char *buf, size_t n)
+{
+	char *cp;
+	int len = n;
+
+	cp = memchr(buf, '\n', n);
+	if (cp)
+		len = cp - buf;
+	if (len == sizeof enabled - 1 && strncmp(buf, enabled, len) == 0)
+		device_enable_async_suspend(dev);
+	else if (len == sizeof disabled - 1 && strncmp(buf, disabled, len) == 0)
+		device_disable_async_suspend(dev);
+	else
+		return -EINVAL;
+	return n;
+}
+
+static DEVICE_ATTR(async, 0644, async_show, async_store);
+#endif /* CONFIG_PM_SLEEP_ADVANCED_DEBUG */
 
 static struct attribute * power_attrs[] = {
+#ifdef CONFIG_PM_RUNTIME
+	&dev_attr_control.attr,
+#endif
 	&dev_attr_wakeup.attr,
+#ifdef CONFIG_PM_SLEEP_ADVANCED_DEBUG
+	&dev_attr_async.attr,
+#endif
 	NULL,
 };
 static struct attribute_group pm_attr_group = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/base/sys.c linux-libre-2.6.34-gnu1/drivers/base/sys.c
--- linux-libre-2.6.33-gnu1/drivers/base/sys.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/base/sys.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/pm.h>
 #include <linux/device.h>
@@ -54,7 +53,7 @@ sysdev_store(struct kobject *kobj, struc
 	return -EIO;
 }
 
-static struct sysfs_ops sysfs_ops = {
+static const struct sysfs_ops sysfs_ops = {
 	.show	= sysdev_show,
 	.store	= sysdev_store,
 };
@@ -89,7 +88,7 @@ static ssize_t sysdev_class_show(struct
 	struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
 
 	if (class_attr->show)
-		return class_attr->show(class, buffer);
+		return class_attr->show(class, class_attr, buffer);
 	return -EIO;
 }
 
@@ -100,11 +99,11 @@ static ssize_t sysdev_class_store(struct
 	struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
 
 	if (class_attr->store)
-		return class_attr->store(class, buffer, count);
+		return class_attr->store(class, class_attr, buffer, count);
 	return -EIO;
 }
 
-static struct sysfs_ops sysfs_class_ops = {
+static const struct sysfs_ops sysfs_class_ops = {
 	.show	= sysdev_class_show,
 	.store	= sysdev_class_store,
 };
@@ -145,13 +144,20 @@ int sysdev_class_register(struct sysdev_
 	if (retval)
 		return retval;
 
-	return kset_register(&cls->kset);
+	retval = kset_register(&cls->kset);
+	if (!retval && cls->attrs)
+		retval = sysfs_create_files(&cls->kset.kobj,
+					    (const struct attribute **)cls->attrs);
+	return retval;
 }
 
 void sysdev_class_unregister(struct sysdev_class *cls)
 {
 	pr_debug("Unregistering sysdev class '%s'\n",
 		 kobject_name(&cls->kset.kobj));
+	if (cls->attrs)
+		sysfs_remove_files(&cls->kset.kobj,
+				   (const struct attribute **)cls->attrs);
 	kset_unregister(&cls->kset);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/amiflop.c linux-libre-2.6.34-gnu1/drivers/block/amiflop.c
--- linux-libre-2.6.33-gnu1/drivers/block/amiflop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/amiflop.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,6 +54,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/fd.h>
 #include <linux/hdreg.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/aoe/aoeblk.c linux-libre-2.6.34-gnu1/drivers/block/aoe/aoeblk.c
--- linux-libre-2.6.33-gnu1/drivers/block/aoe/aoeblk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/aoe/aoeblk.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/backing-dev.h>
 #include <linux/fs.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 #include <linux/genhd.h>
 #include <linux/netdevice.h>
 #include "aoe.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/aoe/aoechr.c linux-libre-2.6.34-gnu1/drivers/block/aoe/aoechr.c
--- linux-libre-2.6.33-gnu1/drivers/block/aoe/aoechr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/aoe/aoechr.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 #include <linux/blkdev.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/skbuff.h>
 #include "aoe.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/aoe/aoecmd.c linux-libre-2.6.34-gnu1/drivers/block/aoe/aoecmd.c
--- linux-libre-2.6.33-gnu1/drivers/block/aoe/aoecmd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/aoe/aoecmd.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
  */
 
 #include <linux/ata.h>
+#include <linux/slab.h>
 #include <linux/hdreg.h>
 #include <linux/blkdev.h>
 #include <linux/skbuff.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/aoe/aoedev.c linux-libre-2.6.34-gnu1/drivers/block/aoe/aoedev.c
--- linux-libre-2.6.33-gnu1/drivers/block/aoe/aoedev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/aoe/aoedev.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 #include <linux/blkdev.h>
 #include <linux/netdevice.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include "aoe.h"
 
 static void dummy_timer(ulong);
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/aoe/aoenet.c linux-libre-2.6.34-gnu1/drivers/block/aoe/aoenet.c
--- linux-libre-2.6.33-gnu1/drivers/block/aoe/aoenet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/aoe/aoenet.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
  * Ethernet portion of AoE driver
  */
 
+#include <linux/gfp.h>
 #include <linux/hdreg.h>
 #include <linux/blkdev.h>
 #include <linux/netdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/ataflop.c linux-libre-2.6.34-gnu1/drivers/block/ataflop.c
--- linux-libre-2.6.33-gnu1/drivers/block/ataflop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/ataflop.c	2010-05-16 17:17:36.000000000 -0400
@@ -1470,8 +1470,6 @@ repeat:
 
 void do_fd_request(struct request_queue * q)
 {
- 	unsigned long flags;
-
 	DPRINT(("do_fd_request for pid %d\n",current->pid));
 	while( fdc_busy ) sleep_on( &fdc_wait );
 	fdc_busy = 1;
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/brd.c linux-libre-2.6.34-gnu1/drivers/block/brd.c
--- linux-libre-2.6.33-gnu1/drivers/block/brd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/brd.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,9 +15,9 @@
 #include <linux/blkdev.h>
 #include <linux/bio.h>
 #include <linux/highmem.h>
-#include <linux/gfp.h>
 #include <linux/radix-tree.h>
 #include <linux/buffer_head.h> /* invalidate_bh_lrus() */
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
@@ -434,7 +434,7 @@ static struct brd_device *brd_alloc(int
 		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_max_hw_sectors(brd->brd_queue, 1024);
 	blk_queue_bounce_limit(brd->brd_queue, BLK_BOUNCE_ANY);
 
 	disk = brd->brd_disk = alloc_disk(1 << part_shift);
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/cciss.c linux-libre-2.6.34-gnu1/drivers/block/cciss.c
--- linux-libre-2.6.33-gnu1/drivers/block/cciss.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/cciss.c	2010-05-16 17:17:36.000000000 -0400
@@ -257,6 +257,79 @@ static inline void removeQ(CommandList_s
 	hlist_del_init(&c->list);
 }
 
+static void cciss_free_sg_chain_blocks(SGDescriptor_struct **cmd_sg_list,
+	int nr_cmds)
+{
+	int i;
+
+	if (!cmd_sg_list)
+		return;
+	for (i = 0; i < nr_cmds; i++) {
+		kfree(cmd_sg_list[i]);
+		cmd_sg_list[i] = NULL;
+	}
+	kfree(cmd_sg_list);
+}
+
+static SGDescriptor_struct **cciss_allocate_sg_chain_blocks(
+	ctlr_info_t *h, int chainsize, int nr_cmds)
+{
+	int j;
+	SGDescriptor_struct **cmd_sg_list;
+
+	if (chainsize <= 0)
+		return NULL;
+
+	cmd_sg_list = kmalloc(sizeof(*cmd_sg_list) * nr_cmds, GFP_KERNEL);
+	if (!cmd_sg_list)
+		return NULL;
+
+	/* Build up chain blocks for each command */
+	for (j = 0; j < nr_cmds; j++) {
+		/* Need a block of chainsized s/g elements. */
+		cmd_sg_list[j] = kmalloc((chainsize *
+			sizeof(*cmd_sg_list[j])), GFP_KERNEL);
+		if (!cmd_sg_list[j]) {
+			dev_err(&h->pdev->dev, "Cannot get memory "
+				"for s/g chains.\n");
+			goto clean;
+		}
+	}
+	return cmd_sg_list;
+clean:
+	cciss_free_sg_chain_blocks(cmd_sg_list, nr_cmds);
+	return NULL;
+}
+
+static void cciss_unmap_sg_chain_block(ctlr_info_t *h, CommandList_struct *c)
+{
+	SGDescriptor_struct *chain_sg;
+	u64bit temp64;
+
+	if (c->Header.SGTotal <= h->max_cmd_sgentries)
+		return;
+
+	chain_sg = &c->SG[h->max_cmd_sgentries - 1];
+	temp64.val32.lower = chain_sg->Addr.lower;
+	temp64.val32.upper = chain_sg->Addr.upper;
+	pci_unmap_single(h->pdev, temp64.val, chain_sg->Len, PCI_DMA_TODEVICE);
+}
+
+static void cciss_map_sg_chain_block(ctlr_info_t *h, CommandList_struct *c,
+	SGDescriptor_struct *chain_block, int len)
+{
+	SGDescriptor_struct *chain_sg;
+	u64bit temp64;
+
+	chain_sg = &c->SG[h->max_cmd_sgentries - 1];
+	chain_sg->Ext = CCISS_SG_CHAIN;
+	chain_sg->Len = len;
+	temp64.val = pci_map_single(h->pdev, chain_block, len,
+				PCI_DMA_TODEVICE);
+	chain_sg->Addr.lower = temp64.val32.lower;
+	chain_sg->Addr.upper = temp64.val32.upper;
+}
+
 #include "cciss_scsi.c"		/* For SCSI tape support */
 
 static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
@@ -1344,26 +1417,27 @@ static int cciss_ioctl(struct block_devi
 				kfree(buff);
 				return -ENOMEM;
 			}
-			// Fill in the command type
+			/* Fill in the command type */
 			c->cmd_type = CMD_IOCTL_PEND;
-			// Fill in Command Header
-			c->Header.ReplyQueue = 0;	// unused in simple mode
-			if (iocommand.buf_size > 0)	// buffer to fill
+			/* Fill in Command Header */
+			c->Header.ReplyQueue = 0;   /* unused in simple mode */
+			if (iocommand.buf_size > 0) /* buffer to fill */
 			{
 				c->Header.SGList = 1;
 				c->Header.SGTotal = 1;
-			} else	// no buffers to fill
+			} else /* no buffers to fill */
 			{
 				c->Header.SGList = 0;
 				c->Header.SGTotal = 0;
 			}
 			c->Header.LUN = iocommand.LUN_info;
-			c->Header.Tag.lower = c->busaddr;	// use the kernel address the cmd block for tag
+			/* use the kernel address the cmd block for tag */
+			c->Header.Tag.lower = c->busaddr;
 
-			// Fill in Request block
+			/* Fill in Request block */
 			c->Request = iocommand.Request;
 
-			// Fill in the scatter gather information
+			/* Fill in the scatter gather information */
 			if (iocommand.buf_size > 0) {
 				temp64.val = pci_map_single(host->pdev, buff,
 					iocommand.buf_size,
@@ -1371,7 +1445,7 @@ static int cciss_ioctl(struct block_devi
 				c->SG[0].Addr.lower = temp64.val32.lower;
 				c->SG[0].Addr.upper = temp64.val32.upper;
 				c->SG[0].Len = iocommand.buf_size;
-				c->SG[0].Ext = 0;	// we are not chaining
+				c->SG[0].Ext = 0;  /* we are not chaining */
 			}
 			c->waiting = &wait;
 
@@ -1670,14 +1744,9 @@ static void cciss_softirq_done(struct re
 	/* unmap the DMA mapping for all the scatter gather elements */
 	for (i = 0; i < cmd->Header.SGList; i++) {
 		if (curr_sg[sg_index].Ext == CCISS_SG_CHAIN) {
-			temp64.val32.lower = cmd->SG[i].Addr.lower;
-			temp64.val32.upper = cmd->SG[i].Addr.upper;
-			pci_dma_sync_single_for_cpu(h->pdev, temp64.val,
-						cmd->SG[i].Len, ddir);
-			pci_unmap_single(h->pdev, temp64.val,
-						cmd->SG[i].Len, ddir);
+			cciss_unmap_sg_chain_block(h, cmd);
 			/* Point to the next block */
-			curr_sg = h->cmd_sg_list[cmd->cmdindex]->sgchain;
+			curr_sg = h->cmd_sg_list[cmd->cmdindex];
 			sg_index = 0;
 		}
 		temp64.val32.lower = curr_sg[sg_index].Addr.lower;
@@ -1796,12 +1865,9 @@ static int cciss_add_disk(ctlr_info_t *h
 	blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask);
 
 	/* This is a hardware imposed limit. */
-	blk_queue_max_hw_segments(disk->queue, h->maxsgentries);
-
-	/* This is a limit in the driver and could be eliminated. */
-	blk_queue_max_phys_segments(disk->queue, h->maxsgentries);
+	blk_queue_max_segments(disk->queue, h->maxsgentries);
 
-	blk_queue_max_sectors(disk->queue, h->cciss_max_sectors);
+	blk_queue_max_hw_sectors(disk->queue, h->cciss_max_sectors);
 
 	blk_queue_softirq_done(disk->queue, cciss_softirq_done);
 
@@ -2425,7 +2491,7 @@ static int fill_cmd(CommandList_struct *
 			c->Request.Type.Direction = XFER_READ;
 			c->Request.Timeout = 0;
 			c->Request.CDB[0] = cmd;
-			c->Request.CDB[6] = (size >> 24) & 0xFF;	//MSB
+			c->Request.CDB[6] = (size >> 24) & 0xFF; /* MSB */
 			c->Request.CDB[7] = (size >> 16) & 0xFF;
 			c->Request.CDB[8] = (size >> 8) & 0xFF;
 			c->Request.CDB[9] = size & 0xFF;
@@ -2694,7 +2760,7 @@ static void cciss_geometry_inquiry(int c
 			       "cciss: reading geometry failed, volume "
 			       "does not support reading geometry\n");
 			drv->heads = 255;
-			drv->sectors = 32;	// Sectors per track
+			drv->sectors = 32;	/* Sectors per track */
 			drv->cylinders = total_size + 1;
 			drv->raid_level = RAID_UNKNOWN;
 		} else {
@@ -3082,7 +3148,6 @@ static void do_cciss_request(struct requ
 	SGDescriptor_struct *curr_sg;
 	drive_info_struct *drv;
 	int i, dir;
-	int nseg = 0;
 	int sg_index = 0;
 	int chained = 0;
 
@@ -3112,19 +3177,19 @@ static void do_cciss_request(struct requ
 
 	/* fill in the request */
 	drv = creq->rq_disk->private_data;
-	c->Header.ReplyQueue = 0;	// unused in simple mode
+	c->Header.ReplyQueue = 0;	/* unused in simple mode */
 	/* got command from pool, so use the command block index instead */
 	/* for direct lookups. */
 	/* The first 2 bits are reserved for controller error reporting. */
 	c->Header.Tag.lower = (c->cmdindex << 3);
 	c->Header.Tag.lower |= 0x04;	/* flag for direct lookup. */
 	memcpy(&c->Header.LUN, drv->LunID, sizeof(drv->LunID));
-	c->Request.CDBLen = 10;	// 12 byte commands not in FW yet;
-	c->Request.Type.Type = TYPE_CMD;	// It is a command.
+	c->Request.CDBLen = 10;	/* 12 byte commands not in FW yet; */
+	c->Request.Type.Type = TYPE_CMD;	/* It is a command. */
 	c->Request.Type.Attribute = ATTR_SIMPLE;
 	c->Request.Type.Direction =
 	    (rq_data_dir(creq) == READ) ? XFER_READ : XFER_WRITE;
-	c->Request.Timeout = 0;	// Don't time out
+	c->Request.Timeout = 0;	/* Don't time out */
 	c->Request.CDB[0] =
 	    (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write;
 	start_blk = blk_rq_pos(creq);
@@ -3149,13 +3214,8 @@ static void do_cciss_request(struct requ
 	for (i = 0; i < seg; i++) {
 		if (((sg_index+1) == (h->max_cmd_sgentries)) &&
 			!chained && ((seg - i) > 1)) {
-			nseg = seg - i;
-			curr_sg[sg_index].Len = (nseg) *
-					sizeof(SGDescriptor_struct);
-			curr_sg[sg_index].Ext = CCISS_SG_CHAIN;
-
 			/* Point to next chain block. */
-			curr_sg = h->cmd_sg_list[c->cmdindex]->sgchain;
+			curr_sg = h->cmd_sg_list[c->cmdindex];
 			sg_index = 0;
 			chained = 1;
 		}
@@ -3166,31 +3226,12 @@ static void do_cciss_request(struct requ
 		curr_sg[sg_index].Addr.lower = temp64.val32.lower;
 		curr_sg[sg_index].Addr.upper = temp64.val32.upper;
 		curr_sg[sg_index].Ext = 0;  /* we are not chaining */
-
 		++sg_index;
 	}
-
-	if (chained) {
-		int len;
-		curr_sg = c->SG;
-		sg_index = h->max_cmd_sgentries - 1;
-		len = curr_sg[sg_index].Len;
-		/* Setup pointer to next chain block.
-		 * Fill out last element in current chain
-		 * block with address of next chain block.
-		 */
-		temp64.val = pci_map_single(h->pdev,
-					h->cmd_sg_list[c->cmdindex]->sgchain,
-					len, dir);
-
-		h->cmd_sg_list[c->cmdindex]->sg_chain_dma = temp64.val;
-		curr_sg[sg_index].Addr.lower = temp64.val32.lower;
-		curr_sg[sg_index].Addr.upper = temp64.val32.upper;
-
-		pci_dma_sync_single_for_device(h->pdev,
-				h->cmd_sg_list[c->cmdindex]->sg_chain_dma,
-				len, dir);
-	}
+	if (chained)
+		cciss_map_sg_chain_block(h, c, h->cmd_sg_list[c->cmdindex],
+			(seg - (h->max_cmd_sgentries - 1)) *
+				sizeof(SGDescriptor_struct));
 
 	/* track how many SG entries we are using */
 	if (seg > h->maxSG)
@@ -3209,11 +3250,11 @@ static void do_cciss_request(struct requ
 	if (likely(blk_fs_request(creq))) {
 		if(h->cciss_read == CCISS_READ_10) {
 			c->Request.CDB[1] = 0;
-			c->Request.CDB[2] = (start_blk >> 24) & 0xff;	//MSB
+			c->Request.CDB[2] = (start_blk >> 24) & 0xff; /* MSB */
 			c->Request.CDB[3] = (start_blk >> 16) & 0xff;
 			c->Request.CDB[4] = (start_blk >> 8) & 0xff;
 			c->Request.CDB[5] = start_blk & 0xff;
-			c->Request.CDB[6] = 0;	// (sect >> 24) & 0xff; MSB
+			c->Request.CDB[6] = 0; /* (sect >> 24) & 0xff; MSB */
 			c->Request.CDB[7] = (blk_rq_sectors(creq) >> 8) & 0xff;
 			c->Request.CDB[8] = blk_rq_sectors(creq) & 0xff;
 			c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
@@ -3222,7 +3263,7 @@ static void do_cciss_request(struct requ
 
 			c->Request.CDBLen = 16;
 			c->Request.CDB[1]= 0;
-			c->Request.CDB[2]= (upper32 >> 24) & 0xff;	//MSB
+			c->Request.CDB[2]= (upper32 >> 24) & 0xff; /* MSB */
 			c->Request.CDB[3]= (upper32 >> 16) & 0xff;
 			c->Request.CDB[4]= (upper32 >>  8) & 0xff;
 			c->Request.CDB[5]= upper32 & 0xff;
@@ -3300,6 +3341,7 @@ static irqreturn_t do_cciss_intr(int irq
 					printk(KERN_WARNING
 					       "cciss: controller cciss%d failed, stopping.\n",
 					       h->ctlr);
+					spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
 					fail_all_cmds(h->ctlr);
 					return IRQ_HANDLED;
 				}
@@ -4240,37 +4282,10 @@ static int __devinit cciss_init_one(stru
 			goto clean4;
 		}
 	}
-	hba[i]->cmd_sg_list = kmalloc(sizeof(struct Cmd_sg_list *) *
-						hba[i]->nr_cmds,
-						GFP_KERNEL);
-	if (!hba[i]->cmd_sg_list) {
-		printk(KERN_ERR "cciss%d: Cannot get memory for "
-			"s/g chaining.\n", i);
+	hba[i]->cmd_sg_list = cciss_allocate_sg_chain_blocks(hba[i],
+		hba[i]->chainsize, hba[i]->nr_cmds);
+	if (!hba[i]->cmd_sg_list && hba[i]->chainsize > 0)
 		goto clean4;
-	}
-	/* Build up chain blocks for each command */
-	if (hba[i]->chainsize > 0) {
-		for (j = 0; j < hba[i]->nr_cmds; j++) {
-			hba[i]->cmd_sg_list[j] =
-					kmalloc(sizeof(struct Cmd_sg_list),
-							GFP_KERNEL);
-			if (!hba[i]->cmd_sg_list[j]) {
-				printk(KERN_ERR "cciss%d: Cannot get memory "
-					"for chain block.\n", i);
-				goto clean4;
-			}
-			/* Need a block of chainsized s/g elements. */
-			hba[i]->cmd_sg_list[j]->sgchain =
-					kmalloc((hba[i]->chainsize *
-						sizeof(SGDescriptor_struct)),
-						GFP_KERNEL);
-			if (!hba[i]->cmd_sg_list[j]->sgchain) {
-				printk(KERN_ERR "cciss%d: Cannot get memory "
-					"for s/g chains\n", i);
-				goto clean4;
-			}
-		}
-	}
 
 	spin_lock_init(&hba[i]->lock);
 
@@ -4329,16 +4344,7 @@ clean4:
 	for (k = 0; k < hba[i]->nr_cmds; k++)
 		kfree(hba[i]->scatter_list[k]);
 	kfree(hba[i]->scatter_list);
-	/* Only free up extra s/g lists if controller supports them */
-	if (hba[i]->chainsize > 0) {
-		for (j = 0; j < hba[i]->nr_cmds; j++) {
-			if (hba[i]->cmd_sg_list[j]) {
-				kfree(hba[i]->cmd_sg_list[j]->sgchain);
-				kfree(hba[i]->cmd_sg_list[j]);
-			}
-		}
-		kfree(hba[i]->cmd_sg_list);
-	}
+	cciss_free_sg_chain_blocks(hba[i]->cmd_sg_list, hba[i]->nr_cmds);
 	if (hba[i]->cmd_pool)
 		pci_free_consistent(hba[i]->pdev,
 				    hba[i]->nr_cmds * sizeof(CommandList_struct),
@@ -4456,16 +4462,7 @@ static void __devexit cciss_remove_one(s
 	for (j = 0; j < hba[i]->nr_cmds; j++)
 		kfree(hba[i]->scatter_list[j]);
 	kfree(hba[i]->scatter_list);
-	/* Only free up extra s/g lists if controller supports them */
-	if (hba[i]->chainsize > 0) {
-		for (j = 0; j < hba[i]->nr_cmds; j++) {
-			if (hba[i]->cmd_sg_list[j]) {
-				kfree(hba[i]->cmd_sg_list[j]->sgchain);
-				kfree(hba[i]->cmd_sg_list[j]);
-			}
-		}
-		kfree(hba[i]->cmd_sg_list);
-	}
+	cciss_free_sg_chain_blocks(hba[i]->cmd_sg_list, hba[i]->nr_cmds);
 	/*
 	 * Deliberately omit pci_disable_device(): it does something nasty to
 	 * Smart Array controllers that pci_enable_device does not undo
@@ -4498,7 +4495,7 @@ static int __init cciss_init(void)
 	 * 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);
+	BUILD_BUG_ON(sizeof(CommandList_struct) % COMMANDLIST_ALIGNMENT);
 
 	printk(KERN_INFO DRIVER_NAME "\n");
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/cciss_cmd.h linux-libre-2.6.34-gnu1/drivers/block/cciss_cmd.h
--- linux-libre-2.6.33-gnu1/drivers/block/cciss_cmd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/cciss_cmd.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,31 +1,16 @@
 #ifndef CCISS_CMD_H
 #define CCISS_CMD_H
-//###########################################################################
-//DEFINES
-//###########################################################################
+
+#include <linux/cciss_defs.h>
+
+/* DEFINES */
 #define CISS_VERSION "1.00"
 
-//general boundary definitions
-#define SENSEINFOBYTES          32//note that this value may vary between host implementations
+/* general boundary definitions */
 #define MAXSGENTRIES            32
 #define CCISS_SG_CHAIN          0x80000000
 #define MAXREPLYQS              256
 
-//Command Status value
-#define CMD_SUCCESS             0x0000
-#define CMD_TARGET_STATUS       0x0001
-#define CMD_DATA_UNDERRUN       0x0002
-#define CMD_DATA_OVERRUN        0x0003
-#define CMD_INVALID             0x0004
-#define CMD_PROTOCOL_ERR        0x0005
-#define CMD_HARDWARE_ERR        0x0006
-#define CMD_CONNECTION_LOST     0x0007
-#define CMD_ABORTED             0x0008
-#define CMD_ABORT_FAILED        0x0009
-#define CMD_UNSOLICITED_ABORT   0x000A
-#define CMD_TIMEOUT             0x000B
-#define CMD_UNABORTABLE		0x000C
-
 /* Unit Attentions ASC's as defined for the MSA2012sa */
 #define POWER_OR_RESET			0x29
 #define STATE_CHANGED			0x2a
@@ -49,30 +34,13 @@
 #define ASYM_ACCESS_CHANGED		0x06
 #define LUN_CAPACITY_CHANGED		0x09
 
-//transfer direction
-#define XFER_NONE               0x00
-#define XFER_WRITE              0x01
-#define XFER_READ               0x02
-#define XFER_RSVD               0x03
-
-//task attribute
-#define ATTR_UNTAGGED           0x00
-#define ATTR_SIMPLE             0x04
-#define ATTR_HEADOFQUEUE        0x05
-#define ATTR_ORDERED            0x06
-#define ATTR_ACA                0x07
-
-//cdb type
-#define TYPE_CMD				0x00
-#define TYPE_MSG				0x01
-
-//config space register offsets
+/* config space register offsets */
 #define CFG_VENDORID            0x00
 #define CFG_DEVICEID            0x02
 #define CFG_I2OBAR              0x10
 #define CFG_MEM1BAR             0x14
 
-//i2o space register offsets
+/* i2o space register offsets */
 #define I2O_IBDB_SET            0x20
 #define I2O_IBDB_CLEAR          0x70
 #define I2O_INT_STATUS          0x30
@@ -81,7 +49,7 @@
 #define I2O_OBPOST_Q            0x44
 #define I2O_DMA1_CFG		0x214
 
-//Configuration Table
+/* Configuration Table */
 #define CFGTBL_ChangeReq        0x00000001l
 #define CFGTBL_AccCmds          0x00000001l
 
@@ -103,24 +71,17 @@ typedef union _u64bit
    __u64	val;
 } u64bit;
 
-// Type defs used in the following structs
-#define BYTE __u8
-#define WORD __u16
-#define HWORD __u16
-#define DWORD __u32
+/* Type defs used in the following structs */
 #define QWORD vals32 
 
-//###########################################################################
-//STRUCTURES
-//###########################################################################
-#define CISS_MAX_LUN	1024
+/* STRUCTURES */
 #define CISS_MAX_PHYS_LUN	1024
-// SCSI-3 Cmmands 
+/* SCSI-3 Cmmands */
 
 #pragma pack(1)	
 
 #define CISS_INQUIRY 0x12
-//Date returned
+/* Date returned */
 typedef struct _InquiryData_struct
 {
   BYTE data_byte[36];
@@ -128,7 +89,7 @@ typedef struct _InquiryData_struct
 
 #define CISS_REPORT_LOG 0xc2    /* Report Logical LUNs */
 #define CISS_REPORT_PHYS 0xc3   /* Report Physical LUNs */
-// Data returned
+/* Data returned */
 typedef struct _ReportLUNdata_struct
 {
   BYTE LUNListLength[4];
@@ -139,8 +100,8 @@ typedef struct _ReportLUNdata_struct
 #define CCISS_READ_CAPACITY 0x25 /* Read Capacity */ 
 typedef struct _ReadCapdata_struct
 {
-  BYTE total_size[4];	// Total size in blocks
-  BYTE block_size[4];	// Size of blocks in bytes
+  BYTE total_size[4];	/* Total size in blocks */
+  BYTE block_size[4];	/* Size of blocks in bytes */
 } ReadCapdata_struct;
 
 #define CCISS_READ_CAPACITY_16 0x9e /* Read Capacity 16 */
@@ -172,52 +133,13 @@ typedef struct _ReadCapdata_struct_16
 #define CDB_LEN10	10
 #define CDB_LEN16	16
 
-// BMIC commands 
+/* BMIC commands */
 #define BMIC_READ 0x26
 #define BMIC_WRITE 0x27
 #define BMIC_CACHE_FLUSH 0xc2
-#define CCISS_CACHE_FLUSH 0x01	//C2 was already being used by CCISS
-
-//Command List Structure
-typedef union _SCSI3Addr_struct {
-   struct {
-    BYTE Dev;
-    BYTE Bus:6;
-    BYTE Mode:2;        // b00
-  } PeripDev;
-   struct {
-    BYTE DevLSB;
-    BYTE DevMSB:6;
-    BYTE Mode:2;        // b01
-  } LogDev;
-   struct {
-    BYTE Dev:5;
-    BYTE Bus:3;
-    BYTE Targ:6;
-    BYTE Mode:2;        // b10
-  } LogUnit;
-} SCSI3Addr_struct;
-
-typedef struct _PhysDevAddr_struct {
-  DWORD             TargetId:24;
-  DWORD             Bus:6;
-  DWORD             Mode:2;
-  SCSI3Addr_struct  Target[2]; //2 level target device addr
-} PhysDevAddr_struct;
-  
-typedef struct _LogDevAddr_struct {
-  DWORD            VolId:30;
-  DWORD            Mode:2;
-  BYTE             reserved[4];
-} LogDevAddr_struct;
-
-typedef union _LUNAddr_struct {
-  BYTE               LunAddrBytes[8];
-  SCSI3Addr_struct   SCSI3Lun[4];
-  PhysDevAddr_struct PhysDev;
-  LogDevAddr_struct  LogDev;
-} LUNAddr_struct;
+#define CCISS_CACHE_FLUSH 0x01	/* C2 was already being used by CCISS */
 
+/* Command List Structure */
 #define CTLR_LUNID "\0\0\0\0\0\0\0\0"
 
 typedef struct _CommandListHeader_struct {
@@ -227,16 +149,6 @@ typedef struct _CommandListHeader_struct
   QWORD             Tag;
   LUNAddr_struct    LUN;
 } CommandListHeader_struct;
-typedef struct _RequestBlock_struct {
-  BYTE   CDBLen;
-  struct {
-    BYTE Type:3;
-    BYTE Attribute:3;
-    BYTE Direction:2;
-  } Type;
-  HWORD  Timeout;
-  BYTE   CDB[16];
-} RequestBlock_struct;
 typedef struct _ErrDescriptor_struct {
   QWORD  Addr;
   DWORD  Len;
@@ -247,28 +159,6 @@ typedef struct _SGDescriptor_struct {
   DWORD  Ext;
 } SGDescriptor_struct;
 
-typedef union _MoreErrInfo_struct{
-  struct {
-    BYTE  Reserved[3];
-    BYTE  Type;
-    DWORD ErrorInfo;
-  }Common_Info;
-  struct{
-    BYTE  Reserved[2];
-    BYTE  offense_size;//size of offending entry
-    BYTE  offense_num; //byte # of offense 0-base
-    DWORD offense_value;
-  }Invalid_Cmd;
-}MoreErrInfo_struct;
-typedef struct _ErrorInfo_struct {
-  BYTE               ScsiStatus;
-  BYTE               SenseLen;
-  HWORD              CommandStatus;
-  DWORD              ResidualCnt;
-  MoreErrInfo_struct MoreErrInfo;
-  BYTE               SenseInfo[SENSEINFOBYTES];
-} ErrorInfo_struct;
-
 /* Command types */
 #define CMD_RWREQ       0x00
 #define CMD_IOCTL_PEND  0x01
@@ -277,10 +167,18 @@ typedef struct _ErrorInfo_struct {
 #define CMD_MSG_TIMEOUT 0x05
 #define CMD_MSG_STALE	0xff
 
-/* This structure needs to be divisible by 8 for new
- * indexing method.
+/* This structure needs to be divisible by COMMANDLIST_ALIGNMENT
+ * because low bits of the address are used to to indicate that
+ * whether the tag contains an index or an address.  PAD_32 and
+ * PAD_64 can be adjusted independently as needed for 32-bit
+ * and 64-bits systems.
  */
-#define PADSIZE (sizeof(long) - 4)
+#define COMMANDLIST_ALIGNMENT (8)
+#define IS_64_BIT ((sizeof(long) - 4)/4)
+#define IS_32_BIT (!IS_64_BIT)
+#define PAD_32 (0)
+#define PAD_64 (4)
+#define PADSIZE (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64)
 typedef struct _CommandList_struct {
   CommandListHeader_struct Header;
   RequestBlock_struct      Request;
@@ -300,7 +198,7 @@ typedef struct _CommandList_struct {
   char   pad[PADSIZE];
 } CommandList_struct;
 
-//Configuration Table Structure
+/* Configuration Table Structure */
 typedef struct _HostWrite_struct {
   DWORD TransportRequest;
   DWORD Reserved;
@@ -326,4 +224,4 @@ typedef struct _CfgTable_struct {
   DWORD            MaxPhysicalDrivesPerLogicalUnit;
 } CfgTable_struct;
 #pragma pack()	 
-#endif // CCISS_CMD_H
+#endif /* CCISS_CMD_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/cciss.h linux-libre-2.6.34-gnu1/drivers/block/cciss.h
--- linux-libre-2.6.33-gnu1/drivers/block/cciss.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/cciss.h	2010-05-16 17:17:36.000000000 -0400
@@ -55,18 +55,12 @@ typedef struct _drive_info_struct
 	char device_initialized;     /* indicates whether dev is initialized */
 } drive_info_struct;
 
-struct Cmd_sg_list {
-	SGDescriptor_struct	*sgchain;
-	dma_addr_t		sg_chain_dma;
-	int			chain_block_size;
-};
-
 struct ctlr_info
 {
 	int	ctlr;
 	char	devname[8];
 	char    *product_name;
-	char	firm_ver[4]; // Firmware version 
+	char	firm_ver[4]; /* Firmware version */
 	struct pci_dev *pdev;
 	__u32	board_id;
 	void __iomem *vaddr;
@@ -89,7 +83,7 @@ struct ctlr_info
 	int	maxsgentries;
 	int	chainsize;
 	int	max_cmd_sgentries;
-	struct Cmd_sg_list **cmd_sg_list;
+	SGDescriptor_struct **cmd_sg_list;
 
 #	define DOORBELL_INT	0
 #	define PERF_MODE_INT	1
@@ -103,7 +97,7 @@ struct ctlr_info
 	BYTE	cciss_write;
 	BYTE	cciss_read_capacity;
 
-	// information about each logical volume
+	/* information about each logical volume */
 	drive_info_struct *drv[CISS_MAX_LUN];
 
 	struct access_method access;
@@ -116,7 +110,7 @@ struct ctlr_info
 	unsigned int maxSG;
 	spinlock_t lock;
 
-	//* pointers to command and error info pool */ 
+	/* pointers to command and error info pool */
 	CommandList_struct 	*cmd_pool;
 	dma_addr_t		cmd_pool_dhandle; 
 	ErrorInfo_struct 	*errinfo_pool;
@@ -134,12 +128,10 @@ struct ctlr_info
 	*/
 	int			next_to_run;
 
-	// Disk structures we need to pass back
+	/* Disk structures we need to pass back */
 	struct gendisk   *gendisk[CISS_MAX_LUN];
 #ifdef CONFIG_CISS_SCSI_TAPE
-	void *scsi_ctlr; /* ptr to structure containing scsi related stuff */
-	/* list of block side commands the scsi error handling sucked up */
-	/* and saved for later processing */
+	struct cciss_scsi_adapter_data_t *scsi_ctlr;
 #endif
 	unsigned char alive;
 	struct list_head scan_list;
@@ -315,4 +307,3 @@ struct board_type {
 #define CCISS_LOCK(i)	(&hba[i]->lock)
 
 #endif /* CCISS_H */
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/cciss_scsi.c linux-libre-2.6.34-gnu1/drivers/block/cciss_scsi.c
--- linux-libre-2.6.33-gnu1/drivers/block/cciss_scsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/cciss_scsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -84,7 +84,6 @@ static struct scsi_host_template cciss_d
 	.queuecommand		= cciss_scsi_queue_command,
 	.can_queue		= SCSI_CCISS_CAN_QUEUE,
 	.this_id		= 7,
-	.sg_tablesize		= MAXSGENTRIES,
 	.cmd_per_lun		= 1,
 	.use_clustering		= DISABLE_CLUSTERING,
 	/* Can't have eh_bus_reset_handler or eh_host_reset_handler for cciss */
@@ -93,11 +92,16 @@ static struct scsi_host_template cciss_d
 };
 
 #pragma pack(1)
+
+#define SCSI_PAD_32 0
+#define SCSI_PAD_64 0
+
 struct cciss_scsi_cmd_stack_elem_t {
 	CommandList_struct cmd;
 	ErrorInfo_struct Err;
 	__u32 busaddr;
-	__u32 pad;
+	int cmdindex;
+	u8 pad[IS_32_BIT * SCSI_PAD_32 + IS_64_BIT * SCSI_PAD_64];
 };
 
 #pragma pack()
@@ -118,16 +122,15 @@ struct cciss_scsi_cmd_stack_t {
 struct cciss_scsi_adapter_data_t {
 	struct Scsi_Host *scsi_host;
 	struct cciss_scsi_cmd_stack_t cmd_stack;
+	SGDescriptor_struct **cmd_sg_list;
 	int registered;
 	spinlock_t lock; // to protect ccissscsi[ctlr]; 
 };
 
 #define CPQ_TAPE_LOCK(ctlr, flags) spin_lock_irqsave( \
-	&(((struct cciss_scsi_adapter_data_t *) \
-	hba[ctlr]->scsi_ctlr)->lock), flags);
+	&hba[ctlr]->scsi_ctlr->lock, flags);
 #define CPQ_TAPE_UNLOCK(ctlr, flags) spin_unlock_irqrestore( \
-	&(((struct cciss_scsi_adapter_data_t *) \
-	hba[ctlr]->scsi_ctlr)->lock), flags);
+	&hba[ctlr]->scsi_ctlr->lock, flags);
 
 static CommandList_struct *
 scsi_cmd_alloc(ctlr_info_t *h)
@@ -143,7 +146,7 @@ scsi_cmd_alloc(ctlr_info_t *h)
 	struct cciss_scsi_cmd_stack_t *stk;
 	u64bit temp64;
 
-	sa = (struct cciss_scsi_adapter_data_t *) h->scsi_ctlr;
+	sa = h->scsi_ctlr;
 	stk = &sa->cmd_stack; 
 
 	if (stk->top < 0) 
@@ -154,6 +157,7 @@ scsi_cmd_alloc(ctlr_info_t *h)
 	memset(&c->Err, 0, sizeof(c->Err));
 	/* set physical addr of cmd and addr of scsi parameters */
 	c->cmd.busaddr = c->busaddr; 
+	c->cmd.cmdindex = c->cmdindex;
 	/* (__u32) (stk->cmd_pool_handle + 
 		(sizeof(struct cciss_scsi_cmd_stack_elem_t)*stk->top)); */
 
@@ -182,7 +186,7 @@ scsi_cmd_free(ctlr_info_t *h, CommandLis
 	struct cciss_scsi_adapter_data_t *sa;
 	struct cciss_scsi_cmd_stack_t *stk;
 
-	sa = (struct cciss_scsi_adapter_data_t *) h->scsi_ctlr;
+	sa = h->scsi_ctlr;
 	stk = &sa->cmd_stack; 
 	if (stk->top >= CMD_STACK_SIZE) {
 		printk("cciss: scsi_cmd_free called too many times.\n");
@@ -199,24 +203,31 @@ scsi_cmd_stack_setup(int ctlr, struct cc
 	struct cciss_scsi_cmd_stack_t *stk;
 	size_t size;
 
+	sa->cmd_sg_list = cciss_allocate_sg_chain_blocks(hba[ctlr],
+		hba[ctlr]->chainsize, CMD_STACK_SIZE);
+	if (!sa->cmd_sg_list && hba[ctlr]->chainsize > 0)
+		return -ENOMEM;
+
 	stk = &sa->cmd_stack; 
 	size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
 
-	// pci_alloc_consistent guarantees 32-bit DMA address will
-	// be used
-
+	/* Check alignment, see cciss_cmd.h near CommandList_struct def. */
+	BUILD_BUG_ON((sizeof(*stk->pool) % COMMANDLIST_ALIGNMENT) != 0);
+	/* pci_alloc_consistent guarantees 32-bit DMA address will be used */
 	stk->pool = (struct cciss_scsi_cmd_stack_elem_t *)
 		pci_alloc_consistent(hba[ctlr]->pdev, size, &stk->cmd_pool_handle);
 
 	if (stk->pool == NULL) {
-		printk("stk->pool is null\n");
-		return -1;
+		cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE);
+		sa->cmd_sg_list = NULL;
+		return -ENOMEM;
 	}
 
 	for (i=0; i<CMD_STACK_SIZE; i++) {
 		stk->elem[i] = &stk->pool[i];
 		stk->elem[i]->busaddr = (__u32) (stk->cmd_pool_handle + 
 			(sizeof(struct cciss_scsi_cmd_stack_elem_t) * i));
+		stk->elem[i]->cmdindex = i;
 	}
 	stk->top = CMD_STACK_SIZE-1;
 	return 0;
@@ -229,7 +240,7 @@ scsi_cmd_stack_free(int ctlr)
 	struct cciss_scsi_cmd_stack_t *stk;
 	size_t size;
 
-	sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
+	sa = hba[ctlr]->scsi_ctlr;
 	stk = &sa->cmd_stack; 
 	if (stk->top != CMD_STACK_SIZE-1) {
 		printk( "cciss: %d scsi commands are still outstanding.\n",
@@ -241,6 +252,7 @@ scsi_cmd_stack_free(int ctlr)
 
 	pci_free_consistent(hba[ctlr]->pdev, size, stk->pool, stk->cmd_pool_handle);
 	stk->pool = NULL;
+	cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE);
 }
 
 #if 0
@@ -530,8 +542,7 @@ adjust_cciss_scsi_table(int ctlr, int ho
 	CPQ_TAPE_LOCK(ctlr, flags);
 
 	if (hostno != -1)  /* if it's not the first time... */
-		sh = ((struct cciss_scsi_adapter_data_t *)
-			hba[ctlr]->scsi_ctlr)->scsi_host;
+		sh = hba[ctlr]->scsi_ctlr->scsi_host;
 
 	/* find any devices in ccissscsi[] that are not in 
 	   sd[] and remove them from ccissscsi[] */
@@ -702,7 +713,7 @@ cciss_scsi_setup(int cntl_num)
 		kfree(shba);
 		shba = NULL;
 	}
-	hba[cntl_num]->scsi_ctlr = (void *) shba;
+	hba[cntl_num]->scsi_ctlr = shba;
 	return;
 }
 
@@ -725,6 +736,8 @@ complete_scsi_command( CommandList_struc
 	ctlr = hba[cp->ctlr];
 
 	scsi_dma_unmap(cmd);
+	if (cp->Header.SGTotal > ctlr->max_cmd_sgentries)
+		cciss_unmap_sg_chain_block(ctlr, cp);
 
 	cmd->result = (DID_OK << 16); 		/* host byte */
 	cmd->result |= (COMMAND_COMPLETE << 8);	/* msg byte */
@@ -847,9 +860,10 @@ cciss_scsi_detect(int ctlr)
 	sh->io_port = 0;	// good enough?  FIXME, 
 	sh->n_io_port = 0;	// I don't think we use these two...
 	sh->this_id = SELF_SCSI_ID;  
+	sh->sg_tablesize = hba[ctlr]->maxsgentries;
 
 	((struct cciss_scsi_adapter_data_t *) 
-		hba[ctlr]->scsi_ctlr)->scsi_host = (void *) sh;
+		hba[ctlr]->scsi_ctlr)->scsi_host = sh;
 	sh->hostdata[0] = (unsigned long) hba[ctlr];
 	sh->irq = hba[ctlr]->intr[SIMPLE_MODE_INT];
 	sh->unique_id = sh->irq;
@@ -1364,34 +1378,54 @@ cciss_scsi_proc_info(struct Scsi_Host *s
    dma mapping  and fills in the scatter gather entries of the 
    cciss command, cp. */
 
-static void
-cciss_scatter_gather(struct pci_dev *pdev, 
-		CommandList_struct *cp,	
-		struct scsi_cmnd *cmd)
+static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp,
+	struct scsi_cmnd *cmd)
 {
 	unsigned int len;
 	struct scatterlist *sg;
 	__u64 addr64;
-	int use_sg, i;
+	int request_nsgs, i, chained, sg_index;
+	struct cciss_scsi_adapter_data_t *sa = h->scsi_ctlr;
+	SGDescriptor_struct *curr_sg;
 
-	BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES);
+	BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);
 
-	use_sg = scsi_dma_map(cmd);
-	if (use_sg) {	/* not too many addrs? */
-		scsi_for_each_sg(cmd, sg, use_sg, i) {
+	chained = 0;
+	sg_index = 0;
+	curr_sg = cp->SG;
+	request_nsgs = scsi_dma_map(cmd);
+	if (request_nsgs) {
+		scsi_for_each_sg(cmd, sg, request_nsgs, i) {
+			if (sg_index + 1 == h->max_cmd_sgentries &&
+				!chained && request_nsgs - i > 1) {
+				chained = 1;
+				sg_index = 0;
+				curr_sg = sa->cmd_sg_list[cp->cmdindex];
+			}
 			addr64 = (__u64) sg_dma_address(sg);
 			len  = sg_dma_len(sg);
-			cp->SG[i].Addr.lower =
-				(__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
-			cp->SG[i].Addr.upper =
-				(__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
-			cp->SG[i].Len = len;
-			cp->SG[i].Ext = 0;  // we are not chaining
+			curr_sg[sg_index].Addr.lower =
+				(__u32) (addr64 & 0x0FFFFFFFFULL);
+			curr_sg[sg_index].Addr.upper =
+				(__u32) ((addr64 >> 32) & 0x0FFFFFFFFULL);
+			curr_sg[sg_index].Len = len;
+			curr_sg[sg_index].Ext = 0;
+			++sg_index;
 		}
+		if (chained)
+			cciss_map_sg_chain_block(h, cp,
+				sa->cmd_sg_list[cp->cmdindex],
+				(request_nsgs - (h->max_cmd_sgentries - 1)) *
+					sizeof(SGDescriptor_struct));
 	}
-
-	cp->Header.SGList = (__u8) use_sg;   /* no. SGs contig in this cmd */
-	cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */
+	/* track how many SG entries we are using */
+	if (request_nsgs > h->maxSG)
+		h->maxSG = request_nsgs;
+	cp->Header.SGTotal = (__u8) request_nsgs + chained;
+	if (request_nsgs > h->max_cmd_sgentries)
+		cp->Header.SGList = h->max_cmd_sgentries;
+	else
+		cp->Header.SGList = cp->Header.SGTotal;
 	return;
 }
 
@@ -1399,7 +1433,7 @@ cciss_scatter_gather(struct pci_dev *pde
 static int
 cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
 {
-	ctlr_info_t **c;
+	ctlr_info_t *c;
 	int ctlr, rc;
 	unsigned char scsi3addr[8];
 	CommandList_struct *cp;
@@ -1407,8 +1441,8 @@ cciss_scsi_queue_command (struct scsi_cm
 
 	// Get the ptr to our adapter structure (hba[i]) out of cmd->host.
 	// We violate cmd->host privacy here.  (Is there another way?)
-	c = (ctlr_info_t **) &cmd->device->host->hostdata[0];	
-	ctlr = (*c)->ctlr;
+	c = (ctlr_info_t *) cmd->device->host->hostdata[0];
+	ctlr = c->ctlr;
 
 	rc = lookup_scsi3addr(ctlr, cmd->device->channel, cmd->device->id, 
 			cmd->device->lun, scsi3addr);
@@ -1431,7 +1465,7 @@ cciss_scsi_queue_command (struct scsi_cm
            see what the device thinks of it. */
 
 	spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
-	cp = scsi_cmd_alloc(*c);
+	cp = scsi_cmd_alloc(c);
 	spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
 	if (cp == NULL) {			/* trouble... */
 		printk("scsi_cmd_alloc returned NULL!\n");
@@ -1489,15 +1523,14 @@ cciss_scsi_queue_command (struct scsi_cm
 		BUG();
 		break;
 	}
-
-	cciss_scatter_gather((*c)->pdev, cp, cmd); // Fill the SG list
+	cciss_scatter_gather(c, cp, cmd);
 
 	/* Put the request on the tail of the request queue */
 
 	spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
-	addQ(&(*c)->reqQ, cp);
-	(*c)->Qdepth++;
-	start_io(*c);
+	addQ(&c->reqQ, cp);
+	c->Qdepth++;
+	start_io(c);
 	spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
 
 	/* the cmd'll come back via intr handler in complete_scsi_command()  */
@@ -1514,7 +1547,7 @@ cciss_unregister_scsi(int ctlr)
 	/* we are being forcibly unloaded, and may not refuse. */
 
 	spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
-	sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
+	sa = hba[ctlr]->scsi_ctlr;
 	stk = &sa->cmd_stack; 
 
 	/* if we weren't ever actually registered, don't unregister */ 
@@ -1541,7 +1574,7 @@ cciss_engage_scsi(int ctlr)
 	unsigned long flags;
 
 	spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
-	sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
+	sa = hba[ctlr]->scsi_ctlr;
 	stk = &sa->cmd_stack; 
 
 	if (sa->registered) {
@@ -1654,14 +1687,14 @@ static int cciss_eh_device_reset_handler
 	int rc;
 	CommandList_struct *cmd_in_trouble;
 	unsigned char lunaddr[8];
-	ctlr_info_t **c;
+	ctlr_info_t *c;
 	int ctlr;
 
 	/* find the controller to which the command to be aborted was sent */
-	c = (ctlr_info_t **) &scsicmd->device->host->hostdata[0];	
+	c = (ctlr_info_t *) scsicmd->device->host->hostdata[0];
 	if (c == NULL) /* paranoia */
 		return FAILED;
-	ctlr = (*c)->ctlr;
+	ctlr = c->ctlr;
 	printk(KERN_WARNING "cciss%d: resetting tape drive or medium changer.\n", ctlr);
 	/* find the command that's giving us trouble */
 	cmd_in_trouble = (CommandList_struct *) scsicmd->host_scribble;
@@ -1671,7 +1704,7 @@ static int cciss_eh_device_reset_handler
 	/* send a reset to the SCSI LUN which the command was sent to */
 	rc = sendcmd_withirq(CCISS_RESET_MSG, ctlr, NULL, 0, 0, lunaddr,
 		TYPE_MSG);
-	if (rc == 0 && wait_for_device_to_become_ready(*c, lunaddr) == 0)
+	if (rc == 0 && wait_for_device_to_become_ready(c, lunaddr) == 0)
 		return SUCCESS;
 	printk(KERN_WARNING "cciss%d: resetting device failed.\n", ctlr);
 	return FAILED;
@@ -1682,14 +1715,14 @@ static int  cciss_eh_abort_handler(struc
 	int rc;
 	CommandList_struct *cmd_to_abort;
 	unsigned char lunaddr[8];
-	ctlr_info_t **c;
+	ctlr_info_t *c;
 	int ctlr;
 
 	/* find the controller to which the command to be aborted was sent */
-	c = (ctlr_info_t **) &scsicmd->device->host->hostdata[0];	
+	c = (ctlr_info_t *) scsicmd->device->host->hostdata[0];
 	if (c == NULL) /* paranoia */
 		return FAILED;
-	ctlr = (*c)->ctlr;
+	ctlr = c->ctlr;
 	printk(KERN_WARNING "cciss%d: aborting tardy SCSI cmd\n", ctlr);
 
 	/* find the command to be aborted */
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/cciss_scsi.h linux-libre-2.6.34-gnu1/drivers/block/cciss_scsi.h
--- linux-libre-2.6.33-gnu1/drivers/block/cciss_scsi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/cciss_scsi.h	2010-05-16 17:17:36.000000000 -0400
@@ -25,16 +25,16 @@
 
 #include <scsi/scsicam.h> /* possibly irrelevant, since we don't show disks */
 
-		// the scsi id of the adapter...
+		/* the scsi id of the adapter... */
 #define SELF_SCSI_ID 15
-		// 15 is somewhat arbitrary, since the scsi-2 bus
-		// that's presented by the driver to the OS is
-		// fabricated.  The "real" scsi-3 bus the 
-		// hardware presents is fabricated too.
-		// The actual, honest-to-goodness physical
-		// bus that the devices are attached to is not 
-		// addressible natively, and may in fact turn
-		// out to be not scsi at all.
+		/* 15 is somewhat arbitrary, since the scsi-2 bus
+		   that's presented by the driver to the OS is
+		   fabricated.  The "real" scsi-3 bus the
+		   hardware presents is fabricated too.
+		   The actual, honest-to-goodness physical
+		   bus that the devices are attached to is not
+		   addressible natively, and may in fact turn
+		   out to be not scsi at all. */
 
 #define SCSI_CCISS_CAN_QUEUE 2
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/cpqarray.c linux-libre-2.6.34-gnu1/drivers/block/cpqarray.c
--- linux-libre-2.6.33-gnu1/drivers/block/cpqarray.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/cpqarray.c	2010-05-16 17:17:36.000000000 -0400
@@ -448,11 +448,8 @@ static int __init cpqarray_register_ctlr
 		blk_queue_bounce_limit(q, hba[i]->pci_dev->dma_mask);
 
 	/* This is a hardware imposed limit. */
-	blk_queue_max_hw_segments(q, SG_MAX);
+	blk_queue_max_segments(q, SG_MAX);
 
-	/* This is a driver limit and could be eliminated. */
-	blk_queue_max_phys_segments(q, SG_MAX);
-	
 	init_timer(&hba[i]->timer);
 	hba[i]->timer.expires = jiffies + IDA_TIMER;
 	hba[i]->timer.data = (unsigned long)hba[i];
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/DAC960.c linux-libre-2.6.34-gnu1/drivers/block/DAC960.c
--- linux-libre-2.6.33-gnu1/drivers/block/DAC960.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/DAC960.c	2010-05-16 17:17:36.000000000 -0400
@@ -2533,9 +2533,8 @@ static bool DAC960_RegisterBlockDevice(D
   	Controller->RequestQueue[n] = RequestQueue;
   	blk_queue_bounce_limit(RequestQueue, Controller->BounceBufferLimit);
   	RequestQueue->queuedata = Controller;
-  	blk_queue_max_hw_segments(RequestQueue, Controller->DriverScatterGatherLimit);
-	blk_queue_max_phys_segments(RequestQueue, Controller->DriverScatterGatherLimit);
-	blk_queue_max_sectors(RequestQueue, Controller->MaxBlocksPerCommand);
+	blk_queue_max_segments(RequestQueue, Controller->DriverScatterGatherLimit);
+	blk_queue_max_hw_sectors(RequestQueue, Controller->MaxBlocksPerCommand);
 	disk->queue = RequestQueue;
 	sprintf(disk->disk_name, "rd/c%dd%d", Controller->ControllerNumber, n);
 	disk->major = MajorNumber;
@@ -7134,7 +7133,7 @@ static struct DAC960_privdata DAC960_P_p
 	.MemoryWindowSize =	DAC960_PD_RegisterWindowSize,
 };
 
-static struct pci_device_id DAC960_id_table[] = {
+static const struct pci_device_id DAC960_id_table[] = {
 	{
 		.vendor 	= PCI_VENDOR_ID_MYLEX,
 		.device		= PCI_DEVICE_ID_MYLEX_DAC960_GEM,
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_actlog.c linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_actlog.c
--- linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_actlog.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_actlog.c	2010-05-16 17:17:36.000000000 -0400
@@ -536,7 +536,9 @@ static void atodb_endio(struct bio *bio,
 	put_ldev(mdev);
 }
 
+/* sector to word */
 #define S2W(s)	((s)<<(BM_EXT_SHIFT-BM_BLOCK_SHIFT-LN2_BPL))
+
 /* activity log to on disk bitmap -- prepare bio unless that sector
  * is already covered by previously prepared bios */
 static int atodb_prepare_unless_covered(struct drbd_conf *mdev,
@@ -546,13 +548,20 @@ static int atodb_prepare_unless_covered(
 {
 	struct bio *bio;
 	struct page *page;
-	sector_t on_disk_sector = enr + mdev->ldev->md.md_offset
-				      + mdev->ldev->md.bm_offset;
+	sector_t on_disk_sector;
 	unsigned int page_offset = PAGE_SIZE;
 	int offset;
 	int i = 0;
 	int err = -ENOMEM;
 
+	/* We always write aligned, full 4k blocks,
+	 * so we can ignore the logical_block_size (for now) */
+	enr &= ~7U;
+	on_disk_sector = enr + mdev->ldev->md.md_offset
+			     + mdev->ldev->md.bm_offset;
+
+	D_ASSERT(!(on_disk_sector & 7U));
+
 	/* Check if that enr is already covered by an already created bio.
 	 * Caution, bios[] is not NULL terminated,
 	 * but only initialized to all NULL.
@@ -588,7 +597,7 @@ static int atodb_prepare_unless_covered(
 
 	offset = S2W(enr);
 	drbd_bm_get_lel(mdev, offset,
-			min_t(size_t, S2W(1), drbd_bm_words(mdev) - offset),
+			min_t(size_t, S2W(8), drbd_bm_words(mdev) - offset),
 			kmap(page) + page_offset);
 	kunmap(page);
 
@@ -597,7 +606,7 @@ static int atodb_prepare_unless_covered(
 	bio->bi_bdev = mdev->ldev->md_bdev;
 	bio->bi_sector = on_disk_sector;
 
-	if (bio_add_page(bio, page, MD_SECTOR_SIZE, page_offset) != MD_SECTOR_SIZE)
+	if (bio_add_page(bio, page, 4096, page_offset) != 4096)
 		goto out_put_page;
 
 	atomic_inc(&wc->count);
@@ -1327,7 +1336,7 @@ int drbd_rs_del_all(struct drbd_conf *md
 		/* ok, ->resync is there. */
 		for (i = 0; i < mdev->resync->nr_elements; i++) {
 			e = lc_element_by_index(mdev->resync, i);
-			bm_ext = e ? lc_entry(e, struct bm_extent, lce) : NULL;
+			bm_ext = lc_entry(e, struct bm_extent, lce);
 			if (bm_ext->lce.lc_number == LC_FREE)
 				continue;
 			if (bm_ext->lce.lc_number == mdev->resync_wenr) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_bitmap.c linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_bitmap.c
--- linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_bitmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_bitmap.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/vmalloc.h>
 #include <linux/string.h>
 #include <linux/drbd.h>
+#include <linux/slab.h>
 #include <asm/kmap_types.h>
 #include "drbd_int.h"
 
@@ -66,7 +67,7 @@ struct drbd_bitmap {
 	size_t   bm_words;
 	size_t   bm_number_of_pages;
 	sector_t bm_dev_capacity;
-	struct semaphore bm_change; /* serializes resize operations */
+	struct mutex bm_change; /* serializes resize operations */
 
 	atomic_t bm_async_io;
 	wait_queue_head_t bm_io_wait;
@@ -114,7 +115,7 @@ void drbd_bm_lock(struct drbd_conf *mdev
 		return;
 	}
 
-	trylock_failed = down_trylock(&b->bm_change);
+	trylock_failed = !mutex_trylock(&b->bm_change);
 
 	if (trylock_failed) {
 		dev_warn(DEV, "%s going to '%s' but bitmap already locked for '%s' by %s\n",
@@ -125,7 +126,7 @@ void drbd_bm_lock(struct drbd_conf *mdev
 		    b->bm_task == mdev->receiver.task ? "receiver" :
 		    b->bm_task == mdev->asender.task  ? "asender"  :
 		    b->bm_task == mdev->worker.task   ? "worker"   : "?");
-		down(&b->bm_change);
+		mutex_lock(&b->bm_change);
 	}
 	if (__test_and_set_bit(BM_LOCKED, &b->bm_flags))
 		dev_err(DEV, "FIXME bitmap already locked in bm_lock\n");
@@ -147,7 +148,7 @@ void drbd_bm_unlock(struct drbd_conf *md
 
 	b->bm_why  = NULL;
 	b->bm_task = NULL;
-	up(&b->bm_change);
+	mutex_unlock(&b->bm_change);
 }
 
 /* word offset to long pointer */
@@ -295,7 +296,7 @@ int drbd_bm_init(struct drbd_conf *mdev)
 	if (!b)
 		return -ENOMEM;
 	spin_lock_init(&b->bm_lock);
-	init_MUTEX(&b->bm_change);
+	mutex_init(&b->bm_change);
 	init_waitqueue_head(&b->bm_io_wait);
 
 	mdev->bitmap = b;
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_int.h linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_int.h
--- linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_int.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_int.h	2010-05-16 17:17:36.000000000 -0400
@@ -95,7 +95,7 @@ extern char usermode_helper[];
 
 /* All EEs on the free list should have ID_VACANT (== 0)
  * freshly allocated EEs get !ID_VACANT (== 1)
- * so if it says "cannot dereference null pointer at adress 0x00000001",
+ * so if it says "cannot dereference null pointer at address 0x00000001",
  * it is most likely one of these :( */
 
 #define ID_IN_SYNC      (4711ULL)
@@ -261,6 +261,9 @@ static inline const char *cmdname(enum d
 		[P_OV_REQUEST]          = "OVRequest",
 		[P_OV_REPLY]            = "OVReply",
 		[P_OV_RESULT]           = "OVResult",
+		[P_CSUM_RS_REQUEST]     = "CsumRSRequest",
+		[P_RS_IS_IN_SYNC]	= "CsumRSIsInSync",
+		[P_COMPRESSED_BITMAP]   = "CBitmap",
 		[P_MAX_CMD]	        = NULL,
 	};
 
@@ -443,13 +446,18 @@ struct p_rs_param_89 {
 	char csums_alg[SHARED_SECRET_MAX];
 } __packed;
 
+enum drbd_conn_flags {
+	CF_WANT_LOSE = 1,
+	CF_DRY_RUN = 2,
+};
+
 struct p_protocol {
 	struct p_header head;
 	u32 protocol;
 	u32 after_sb_0p;
 	u32 after_sb_1p;
 	u32 after_sb_2p;
-	u32 want_lose;
+	u32 conn_flags;
 	u32 two_primaries;
 
               /* Since protocol version 87 and higher. */
@@ -791,6 +799,8 @@ enum {
 				 * while this is set. */
 	RESIZE_PENDING,		/* Size change detected locally, waiting for the response from
 				 * the peer, if it changed there as well. */
+	CONN_DRY_RUN,		/* Expect disconnect after resync handshake. */
+	GOT_PING_ACK,		/* set when we receive a ping_ack packet, misc wait gets woken */
 };
 
 struct drbd_bitmap; /* opaque for drbd_conf */
@@ -1171,7 +1181,7 @@ extern int drbd_bitmap_io(struct drbd_co
 /* Meta data layout
    We reserve a 128MB Block (4k aligned)
    * either at the end of the backing device
-   * or on a seperate meta data device. */
+   * or on a separate meta data device. */
 
 #define MD_RESERVED_SECT (128LU << 11)  /* 128 MB, unit sectors */
 /* The following numbers are sectors */
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_main.c linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_main.c
--- linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -1668,7 +1668,7 @@ int drbd_send_sync_param(struct drbd_con
 int drbd_send_protocol(struct drbd_conf *mdev)
 {
 	struct p_protocol *p;
-	int size, rv;
+	int size, cf, rv;
 
 	size = sizeof(struct p_protocol);
 
@@ -1685,9 +1685,22 @@ int drbd_send_protocol(struct drbd_conf
 	p->after_sb_0p   = cpu_to_be32(mdev->net_conf->after_sb_0p);
 	p->after_sb_1p   = cpu_to_be32(mdev->net_conf->after_sb_1p);
 	p->after_sb_2p   = cpu_to_be32(mdev->net_conf->after_sb_2p);
-	p->want_lose     = cpu_to_be32(mdev->net_conf->want_lose);
 	p->two_primaries = cpu_to_be32(mdev->net_conf->two_primaries);
 
+	cf = 0;
+	if (mdev->net_conf->want_lose)
+		cf |= CF_WANT_LOSE;
+	if (mdev->net_conf->dry_run) {
+		if (mdev->agreed_pro_version >= 92)
+			cf |= CF_DRY_RUN;
+		else {
+			dev_err(DEV, "--dry-run is not supported by peer");
+			kfree(p);
+			return 0;
+		}
+	}
+	p->conn_flags    = cpu_to_be32(cf);
+
 	if (mdev->agreed_pro_version >= 87)
 		strcpy(p->integrity_alg, mdev->net_conf->integrity_alg);
 
@@ -3161,14 +3174,18 @@ void drbd_free_bc(struct drbd_backing_de
 void drbd_free_sock(struct drbd_conf *mdev)
 {
 	if (mdev->data.socket) {
+		mutex_lock(&mdev->data.mutex);
 		kernel_sock_shutdown(mdev->data.socket, SHUT_RDWR);
 		sock_release(mdev->data.socket);
 		mdev->data.socket = NULL;
+		mutex_unlock(&mdev->data.mutex);
 	}
 	if (mdev->meta.socket) {
+		mutex_lock(&mdev->meta.mutex);
 		kernel_sock_shutdown(mdev->meta.socket, SHUT_RDWR);
 		sock_release(mdev->meta.socket);
 		mdev->meta.socket = NULL;
+		mutex_unlock(&mdev->meta.mutex);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_nl.c linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_nl.c
--- linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_nl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_nl.c	2010-05-16 17:17:36.000000000 -0400
@@ -285,8 +285,8 @@ int drbd_set_role(struct drbd_conf *mdev
 		}
 
 		if (r == SS_NO_UP_TO_DATE_DISK && force &&
-		    (mdev->state.disk == D_INCONSISTENT ||
-		     mdev->state.disk == D_OUTDATED)) {
+		    (mdev->state.disk < D_UP_TO_DATE &&
+		     mdev->state.disk >= D_INCONSISTENT)) {
 			mask.disk = D_MASK;
 			val.disk  = D_UP_TO_DATE;
 			forced = 1;
@@ -407,7 +407,7 @@ static int drbd_nl_primary(struct drbd_c
 	}
 
 	reply->ret_code =
-		drbd_set_role(mdev, R_PRIMARY, primary_args.overwrite_peer);
+		drbd_set_role(mdev, R_PRIMARY, primary_args.primary_force);
 
 	return 0;
 }
@@ -709,9 +709,8 @@ void drbd_setup_queue_param(struct drbd_
 
 	max_seg_s = min(queue_max_sectors(b) * queue_logical_block_size(b), max_seg_s);
 
-	blk_queue_max_sectors(q, max_seg_s >> 9);
-	blk_queue_max_phys_segments(q, max_segments ? max_segments : MAX_PHYS_SEGMENTS);
-	blk_queue_max_hw_segments(q, max_segments ? max_segments : MAX_HW_SEGMENTS);
+	blk_queue_max_hw_sectors(q, max_seg_s >> 9);
+	blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS);
 	blk_queue_max_segment_size(q, max_seg_s);
 	blk_queue_logical_block_size(q, 512);
 	blk_queue_segment_boundary(q, PAGE_SIZE-1);
@@ -942,6 +941,25 @@ static int drbd_nl_disk_conf(struct drbd
 
 	drbd_md_set_sector_offsets(mdev, nbc);
 
+	/* allocate a second IO page if logical_block_size != 512 */
+	logical_block_size = bdev_logical_block_size(nbc->md_bdev);
+	if (logical_block_size == 0)
+		logical_block_size = MD_SECTOR_SIZE;
+
+	if (logical_block_size != MD_SECTOR_SIZE) {
+		if (!mdev->md_io_tmpp) {
+			struct page *page = alloc_page(GFP_NOIO);
+			if (!page)
+				goto force_diskless_dec;
+
+			dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n",
+			     logical_block_size, MD_SECTOR_SIZE);
+			dev_warn(DEV, "Workaround engaged (has performance impact).\n");
+
+			mdev->md_io_tmpp = page;
+		}
+	}
+
 	if (!mdev->bitmap) {
 		if (drbd_bm_init(mdev)) {
 			retcode = ERR_NOMEM;
@@ -981,25 +999,6 @@ static int drbd_nl_disk_conf(struct drbd
 		goto force_diskless_dec;
 	}
 
-	/* allocate a second IO page if logical_block_size != 512 */
-	logical_block_size = bdev_logical_block_size(nbc->md_bdev);
-	if (logical_block_size == 0)
-		logical_block_size = MD_SECTOR_SIZE;
-
-	if (logical_block_size != MD_SECTOR_SIZE) {
-		if (!mdev->md_io_tmpp) {
-			struct page *page = alloc_page(GFP_NOIO);
-			if (!page)
-				goto force_diskless_dec;
-
-			dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n",
-			     logical_block_size, MD_SECTOR_SIZE);
-			dev_warn(DEV, "Workaround engaged (has performance impact).\n");
-
-			mdev->md_io_tmpp = page;
-		}
-	}
-
 	/* Reset the "barriers don't work" bits here, then force meta data to
 	 * be written, to ensure we determine if barriers are supported. */
 	if (nbc->dc.no_md_flush)
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_proc.c linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_proc.c
--- linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,6 @@
 #include <asm/uaccess.h>
 #include <linux/fs.h>
 #include <linux/file.h>
-#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/drbd.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_receiver.c linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_receiver.c
--- linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_receiver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_receiver.c	2010-05-16 17:17:36.000000000 -0400
@@ -899,7 +899,8 @@ retry:
 
 	drbd_thread_start(&mdev->asender);
 
-	drbd_send_protocol(mdev);
+	if (!drbd_send_protocol(mdev))
+		return -1;
 	drbd_send_sync_param(mdev, &mdev->sync_conf);
 	drbd_send_sizes(mdev, 0);
 	drbd_send_uuids(mdev);
@@ -2513,6 +2514,10 @@ static enum drbd_conns drbd_sync_handsha
 	}
 
 	if (hg == -100) {
+		/* FIXME this log message is not correct if we end up here
+		 * after an attempted attach on a diskless node.
+		 * We just refuse to attach -- well, we drop the "connection"
+		 * to that disk, in a way... */
 		dev_alert(DEV, "Split-Brain detected, dropping connection!\n");
 		drbd_khelper(mdev, "split-brain");
 		return C_MASK;
@@ -2538,6 +2543,16 @@ static enum drbd_conns drbd_sync_handsha
 		}
 	}
 
+	if (mdev->net_conf->dry_run || test_bit(CONN_DRY_RUN, &mdev->flags)) {
+		if (hg == 0)
+			dev_info(DEV, "dry-run connect: No resync, would become Connected immediately.\n");
+		else
+			dev_info(DEV, "dry-run connect: Would become %s, doing a %s resync.",
+				 drbd_conn_str(hg > 0 ? C_SYNC_SOURCE : C_SYNC_TARGET),
+				 abs(hg) >= 2 ? "full" : "bit-map based");
+		return C_MASK;
+	}
+
 	if (abs(hg) >= 2) {
 		dev_info(DEV, "Writing the whole bitmap, full sync required after drbd_sync_handshake.\n");
 		if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake"))
@@ -2585,7 +2600,7 @@ static int receive_protocol(struct drbd_
 	struct p_protocol *p = (struct p_protocol *)h;
 	int header_size, data_size;
 	int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p;
-	int p_want_lose, p_two_primaries;
+	int p_want_lose, p_two_primaries, cf;
 	char p_integrity_alg[SHARED_SECRET_MAX] = "";
 
 	header_size = sizeof(*p) - sizeof(*h);
@@ -2598,8 +2613,14 @@ static int receive_protocol(struct drbd_
 	p_after_sb_0p	= be32_to_cpu(p->after_sb_0p);
 	p_after_sb_1p	= be32_to_cpu(p->after_sb_1p);
 	p_after_sb_2p	= be32_to_cpu(p->after_sb_2p);
-	p_want_lose	= be32_to_cpu(p->want_lose);
 	p_two_primaries = be32_to_cpu(p->two_primaries);
+	cf		= be32_to_cpu(p->conn_flags);
+	p_want_lose = cf & CF_WANT_LOSE;
+
+	clear_bit(CONN_DRY_RUN, &mdev->flags);
+
+	if (cf & CF_DRY_RUN)
+		set_bit(CONN_DRY_RUN, &mdev->flags);
 
 	if (p_proto != mdev->net_conf->wire_protocol) {
 		dev_err(DEV, "incompatible communication protocols\n");
@@ -3118,13 +3139,16 @@ static int receive_state(struct drbd_con
 
 		put_ldev(mdev);
 		if (nconn == C_MASK) {
+			nconn = C_CONNECTED;
 			if (mdev->state.disk == D_NEGOTIATING) {
 				drbd_force_state(mdev, NS(disk, D_DISKLESS));
-				nconn = C_CONNECTED;
 			} else if (peer_state.disk == D_NEGOTIATING) {
 				dev_err(DEV, "Disk attach process on the peer node was aborted.\n");
 				peer_state.disk = D_DISKLESS;
+				real_peer_disk = D_DISKLESS;
 			} else {
+				if (test_and_clear_bit(CONN_DRY_RUN, &mdev->flags))
+					return FALSE;
 				D_ASSERT(oconn == C_WF_REPORT_PARAMS);
 				drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
 				return FALSE;
@@ -3594,10 +3618,7 @@ static void drbd_disconnect(struct drbd_
 
 	/* asender does not clean up anything. it must not interfere, either */
 	drbd_thread_stop(&mdev->asender);
-
-	mutex_lock(&mdev->data.mutex);
 	drbd_free_sock(mdev);
-	mutex_unlock(&mdev->data.mutex);
 
 	spin_lock_irq(&mdev->req_lock);
 	_drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
@@ -4054,6 +4075,8 @@ static int got_PingAck(struct drbd_conf
 {
 	/* restore idle timeout */
 	mdev->meta.socket->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ;
+	if (!test_and_set_bit(GOT_PING_ACK, &mdev->flags))
+		wake_up(&mdev->misc_wait);
 
 	return TRUE;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_req.h linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_req.h
--- linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_req.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_req.h	2010-05-16 17:17:36.000000000 -0400
@@ -57,7 +57,7 @@
  *
  *  It may me handed over to the local disk subsystem.
  *  It may be completed by the local disk subsystem,
- *    either sucessfully or with io-error.
+ *    either successfully or with io-error.
  *  In case it is a READ request, and it failed locally,
  *    it may be retried remotely.
  *
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_worker.c linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_worker.c
--- linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_worker.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/drbd/drbd_worker.c	2010-05-16 17:17:36.000000000 -0400
@@ -235,7 +235,7 @@ void drbd_endio_pri(struct bio *bio, int
 	if (unlikely(error)) {
 		what = (bio_data_dir(bio) == WRITE)
 			? write_completed_with_error
-			: (bio_rw(bio) == READA)
+			: (bio_rw(bio) == READ)
 			  ? read_completed_with_error
 			  : read_ahead_completed_with_error;
 	} else
@@ -938,7 +938,8 @@ int w_e_end_csum_rs_req(struct drbd_conf
 
 		if (eq) {
 			drbd_set_in_sync(mdev, e->sector, e->size);
-			mdev->rs_same_csum++;
+			/* rs_same_csums unit is BM_BLOCK_SIZE */
+			mdev->rs_same_csum += e->size >> BM_BLOCK_SHIFT;
 			ok = drbd_send_ack(mdev, P_RS_IS_IN_SYNC, e);
 		} else {
 			inc_rs_pending(mdev);
@@ -1288,6 +1289,14 @@ int drbd_alter_sa(struct drbd_conf *mdev
 	return retcode;
 }
 
+static void ping_peer(struct drbd_conf *mdev)
+{
+	clear_bit(GOT_PING_ACK, &mdev->flags);
+	request_ping(mdev);
+	wait_event(mdev->misc_wait,
+		   test_bit(GOT_PING_ACK, &mdev->flags) || mdev->state.conn < C_CONNECTED);
+}
+
 /**
  * drbd_start_resync() - Start the resync process
  * @mdev:	DRBD device.
@@ -1371,7 +1380,6 @@ void drbd_start_resync(struct drbd_conf
 		_drbd_pause_after(mdev);
 	}
 	write_unlock_irq(&global_state_lock);
-	drbd_state_unlock(mdev);
 	put_ldev(mdev);
 
 	if (r == SS_SUCCESS) {
@@ -1382,11 +1390,8 @@ void drbd_start_resync(struct drbd_conf
 
 		if (mdev->rs_total == 0) {
 			/* Peer still reachable? Beware of failing before-resync-target handlers! */
-			request_ping(mdev);
-			__set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(mdev->net_conf->ping_timeo*HZ/9); /* 9 instead 10 */
+			ping_peer(mdev);
 			drbd_resync_finished(mdev);
-			return;
 		}
 
 		/* ns.conn may already be != mdev->state.conn,
@@ -1398,6 +1403,7 @@ void drbd_start_resync(struct drbd_conf
 
 		drbd_md_sync(mdev);
 	}
+	drbd_state_unlock(mdev);
 }
 
 int drbd_worker(struct drbd_thread *thi)
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/floppy.c linux-libre-2.6.34-gnu1/drivers/block/floppy.c
--- linux-libre-2.6.33-gnu1/drivers/block/floppy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/floppy.c	2010-05-16 17:17:36.000000000 -0400
@@ -144,13 +144,23 @@
  * Better audit of register_blkdev.
  */
 
-#define FLOPPY_SANITY_CHECK
 #undef  FLOPPY_SILENT_DCL_CLEAR
 
 #define REALLY_SLOW_IO
 
 #define DEBUGT 2
-#define DCL_DEBUG	/* debug disk change line */
+
+#define DPRINT(format, args...) \
+	pr_info("floppy%d: " format, current_drive, ##args)
+
+#define DCL_DEBUG		/* debug disk change line */
+#ifdef DCL_DEBUG
+#define debug_dcl(test, fmt, args...) \
+	do { if ((test) & FD_DEBUG) DPRINT(fmt, ##args); } while (0)
+#else
+#define debug_dcl(test, fmt, args...) \
+	do { if (0) DPRINT(fmt, ##args); } while (0)
+#endif
 
 /* do print messages for unexpected interrupts */
 static int print_unex = 1;
@@ -180,6 +190,8 @@ static int print_unex = 1;
 #include <linux/mod_devicetable.h>
 #include <linux/buffer_head.h>	/* for invalidate_buffers() */
 #include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
 
 /*
  * PS/2 floppies have much slower step rates than regular floppies.
@@ -191,8 +203,6 @@ static int slow_floppy;
 #include <asm/dma.h>
 #include <asm/irq.h>
 #include <asm/system.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
 
 static int FLOPPY_IRQ = 6;
 static int FLOPPY_DMA = 2;
@@ -241,8 +251,6 @@ static int allowed_drive_mask = 0x33;
 
 static int irqdma_allocated;
 
-#define DEVICE_NAME "floppy"
-
 #include <linux/blkdev.h>
 #include <linux/blkpg.h>
 #include <linux/cdrom.h>	/* for the compatibility eject ioctl */
@@ -250,7 +258,7 @@ static int irqdma_allocated;
 
 static struct request *current_req;
 static struct request_queue *floppy_queue;
-static void do_fd_request(struct request_queue * q);
+static void do_fd_request(struct request_queue *q);
 
 #ifndef fd_get_dma_residue
 #define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA)
@@ -263,7 +271,7 @@ static void do_fd_request(struct request
 #endif
 
 #ifndef fd_dma_mem_alloc
-#define fd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size))
+#define fd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL, get_order(size))
 #endif
 
 static inline void fallback_on_nodma_alloc(char **addr, size_t l)
@@ -273,7 +281,7 @@ static inline void fallback_on_nodma_all
 		return;		/* we have the memory */
 	if (can_use_virtual_dma != 2)
 		return;		/* no fallback allowed */
-	printk("DMA memory shortage. Temporarily falling back on virtual DMA\n");
+	pr_info("DMA memory shortage. Temporarily falling back on virtual DMA\n");
 	*addr = (char *)nodma_mem_alloc(l);
 #else
 	return;
@@ -283,59 +291,50 @@ static inline void fallback_on_nodma_all
 /* End dma memory related stuff */
 
 static unsigned long fake_change;
-static int initialising = 1;
+static bool initialized;
 
-#define ITYPE(x) (((x)>>2) & 0x1f)
-#define TOMINOR(x) ((x & 3) | ((x & 4) << 5))
-#define UNIT(x) ((x) & 0x03)	/* drive on fdc */
-#define FDC(x) (((x) & 0x04) >> 2)	/* fdc of drive */
+#define ITYPE(x)	(((x) >> 2) & 0x1f)
+#define TOMINOR(x)	((x & 3) | ((x & 4) << 5))
+#define UNIT(x)		((x) & 0x03)		/* drive on fdc */
+#define FDC(x)		(((x) & 0x04) >> 2)	/* fdc of drive */
 	/* reverse mapping from unit and fdc to drive */
 #define REVDRIVE(fdc, unit) ((unit) + ((fdc) << 2))
-#define DP (&drive_params[current_drive])
-#define DRS (&drive_state[current_drive])
-#define DRWE (&write_errors[current_drive])
-#define FDCS (&fdc_state[fdc])
-#define CLEARF(x) clear_bit(x##_BIT, &DRS->flags)
-#define SETF(x) set_bit(x##_BIT, &DRS->flags)
-#define TESTF(x) test_bit(x##_BIT, &DRS->flags)
-
-#define UDP (&drive_params[drive])
-#define UDRS (&drive_state[drive])
-#define UDRWE (&write_errors[drive])
-#define UFDCS (&fdc_state[FDC(drive)])
-#define UCLEARF(x) clear_bit(x##_BIT, &UDRS->flags)
-#define USETF(x) set_bit(x##_BIT, &UDRS->flags)
-#define UTESTF(x) test_bit(x##_BIT, &UDRS->flags)
 
-#define DPRINT(format, args...) printk(DEVICE_NAME "%d: " format, current_drive , ## args)
+#define DP	(&drive_params[current_drive])
+#define DRS	(&drive_state[current_drive])
+#define DRWE	(&write_errors[current_drive])
+#define FDCS	(&fdc_state[fdc])
 
-#define PH_HEAD(floppy,head) (((((floppy)->stretch & 2) >>1) ^ head) << 2)
-#define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH)
+#define UDP	(&drive_params[drive])
+#define UDRS	(&drive_state[drive])
+#define UDRWE	(&write_errors[drive])
+#define UFDCS	(&fdc_state[FDC(drive)])
 
-#define CLEARSTRUCT(x) memset((x), 0, sizeof(*(x)))
+#define PH_HEAD(floppy, head) (((((floppy)->stretch & 2) >> 1) ^ head) << 2)
+#define STRETCH(floppy)	((floppy)->stretch & FD_STRETCH)
 
 /* read/write */
-#define COMMAND raw_cmd->cmd[0]
-#define DR_SELECT raw_cmd->cmd[1]
-#define TRACK raw_cmd->cmd[2]
-#define HEAD raw_cmd->cmd[3]
-#define SECTOR raw_cmd->cmd[4]
-#define SIZECODE raw_cmd->cmd[5]
-#define SECT_PER_TRACK raw_cmd->cmd[6]
-#define GAP raw_cmd->cmd[7]
-#define SIZECODE2 raw_cmd->cmd[8]
+#define COMMAND		(raw_cmd->cmd[0])
+#define DR_SELECT	(raw_cmd->cmd[1])
+#define TRACK		(raw_cmd->cmd[2])
+#define HEAD		(raw_cmd->cmd[3])
+#define SECTOR		(raw_cmd->cmd[4])
+#define SIZECODE	(raw_cmd->cmd[5])
+#define SECT_PER_TRACK	(raw_cmd->cmd[6])
+#define GAP		(raw_cmd->cmd[7])
+#define SIZECODE2	(raw_cmd->cmd[8])
 #define NR_RW 9
 
 /* format */
-#define F_SIZECODE raw_cmd->cmd[2]
-#define F_SECT_PER_TRACK raw_cmd->cmd[3]
-#define F_GAP raw_cmd->cmd[4]
-#define F_FILL raw_cmd->cmd[5]
+#define F_SIZECODE	(raw_cmd->cmd[2])
+#define F_SECT_PER_TRACK (raw_cmd->cmd[3])
+#define F_GAP		(raw_cmd->cmd[4])
+#define F_FILL		(raw_cmd->cmd[5])
 #define NR_F 6
 
 /*
- * Maximum disk size (in kilobytes). This default is used whenever the
- * current disk size is unknown.
+ * Maximum disk size (in kilobytes).
+ * This default is used whenever the current disk size is unknown.
  * [Now it is rather a minimum]
  */
 #define MAX_DISK_SIZE 4		/* 3984 */
@@ -345,16 +344,17 @@ static int initialising = 1;
  */
 #define MAX_REPLIES 16
 static unsigned char reply_buffer[MAX_REPLIES];
-static int inr;			/* size of reply buffer, when called from interrupt */
-#define ST0 (reply_buffer[0])
-#define ST1 (reply_buffer[1])
-#define ST2 (reply_buffer[2])
-#define ST3 (reply_buffer[0])	/* result of GETSTATUS */
-#define R_TRACK (reply_buffer[3])
-#define R_HEAD (reply_buffer[4])
-#define R_SECTOR (reply_buffer[5])
-#define R_SIZECODE (reply_buffer[6])
-#define SEL_DLY (2*HZ/100)
+static int inr;		/* size of reply buffer, when called from interrupt */
+#define ST0		(reply_buffer[0])
+#define ST1		(reply_buffer[1])
+#define ST2		(reply_buffer[2])
+#define ST3		(reply_buffer[0])	/* result of GETSTATUS */
+#define R_TRACK		(reply_buffer[3])
+#define R_HEAD		(reply_buffer[4])
+#define R_SECTOR	(reply_buffer[5])
+#define R_SIZECODE	(reply_buffer[6])
+
+#define SEL_DLY		(2 * HZ / 100)
 
 /*
  * this struct defines the different floppy drive types.
@@ -505,9 +505,9 @@ static char floppy_device_name[] = "flop
 static int probing;
 
 /* Synchronization of FDC access. */
-#define FD_COMMAND_NONE -1
-#define FD_COMMAND_ERROR 2
-#define FD_COMMAND_OKAY 3
+#define FD_COMMAND_NONE		-1
+#define FD_COMMAND_ERROR	2
+#define FD_COMMAND_OKAY		3
 
 static volatile int command_status = FD_COMMAND_NONE;
 static unsigned long fdc_busy;
@@ -515,11 +515,6 @@ static DECLARE_WAIT_QUEUE_HEAD(fdc_wait)
 static DECLARE_WAIT_QUEUE_HEAD(command_done);
 
 #define NO_SIGNAL (!interruptible || !signal_pending(current))
-#define CALL(x) if ((x) == -EINTR) return -EINTR
-#define ECALL(x) if ((ret = (x))) return ret;
-#define _WAIT(x,i) CALL(ret=wait_til_done((x),i))
-#define WAIT(x) _WAIT((x),interruptible)
-#define IWAIT(x) _WAIT((x),1)
 
 /* Errors during formatting are counted here. */
 static int format_errors;
@@ -545,8 +540,9 @@ static int max_buffer_sectors;
 static int *errors;
 typedef void (*done_f)(int);
 static struct cont_t {
-	void (*interrupt)(void);	/* this is called after the interrupt of the
-					 * main command */
+	void (*interrupt)(void);
+				/* this is called after the interrupt of the
+				 * main command */
 	void (*redo)(void);	/* this is called to retry the operation */
 	void (*error)(void);	/* this is called to tally an error */
 	done_f done;		/* this is called to say if the operation has
@@ -571,7 +567,6 @@ static void floppy_release_irq_and_dma(v
  * reset doesn't need to be tested before sending commands, because
  * output_byte is automatically disabled when reset is set.
  */
-#define CHECK_RESET { if (FDCS->reset){ reset_fdc(); return; } }
 static void reset_fdc(void);
 
 /*
@@ -579,9 +574,9 @@ static void reset_fdc(void);
  * information to interrupts. They are the data used for the current
  * request.
  */
-#define NO_TRACK -1
-#define NEED_1_RECAL -2
-#define NEED_2_RECAL -3
+#define NO_TRACK	-1
+#define NEED_1_RECAL	-2
+#define NEED_2_RECAL	-3
 
 static int usage_count;
 
@@ -621,39 +616,35 @@ static inline void set_debugt(void)
 	debugtimer = jiffies;
 }
 
-static inline void debugt(const char *message)
+static inline void debugt(const char *func, const char *msg)
 {
 	if (DP->flags & DEBUGT)
-		printk("%s dtime=%lu\n", message, jiffies - debugtimer);
+		pr_info("%s:%s dtime=%lu\n", func, msg, jiffies - debugtimer);
 }
 #else
 static inline void set_debugt(void) { }
-static inline void debugt(const char *message) { }
+static inline void debugt(const char *func, const char *msg) { }
 #endif /* DEBUGT */
 
-typedef void (*timeout_fn) (unsigned long);
+typedef void (*timeout_fn)(unsigned long);
 static DEFINE_TIMER(fd_timeout, floppy_shutdown, 0, 0);
 
 static const char *timeout_message;
 
-#ifdef FLOPPY_SANITY_CHECK
-static void is_alive(const char *message)
+static void is_alive(const char *func, const char *message)
 {
 	/* this routine checks whether the floppy driver is "alive" */
-	if (test_bit(0, &fdc_busy) && command_status < 2
-	    && !timer_pending(&fd_timeout)) {
-		DPRINT("timeout handler died: %s\n", message);
+	if (test_bit(0, &fdc_busy) && command_status < 2 &&
+	    !timer_pending(&fd_timeout)) {
+		DPRINT("%s: timeout handler died.  %s\n", func, message);
 	}
 }
-#endif
-
-static void (*do_floppy) (void) = NULL;
 
-#ifdef FLOPPY_SANITY_CHECK
+static void (*do_floppy)(void) = NULL;
 
 #define OLOGSIZE 20
 
-static void (*lasthandler) (void);
+static void (*lasthandler)(void);
 static unsigned long interruptjiffies;
 static unsigned long resultjiffies;
 static int resultsize;
@@ -666,12 +657,11 @@ static struct output_log {
 } output_log[OLOGSIZE];
 
 static int output_log_pos;
-#endif
 
 #define current_reqD -1
 #define MAXTIMEOUT -2
 
-static void __reschedule_timeout(int drive, const char *message, int marg)
+static void __reschedule_timeout(int drive, const char *message)
 {
 	if (drive == current_reqD)
 		drive = current_drive;
@@ -682,25 +672,22 @@ static void __reschedule_timeout(int dri
 	} else
 		fd_timeout.expires = jiffies + UDP->timeout;
 	add_timer(&fd_timeout);
-	if (UDP->flags & FD_DEBUG) {
-		DPRINT("reschedule timeout ");
-		printk(message, marg);
-		printk("\n");
-	}
+	if (UDP->flags & FD_DEBUG)
+		DPRINT("reschedule timeout %s\n", message);
 	timeout_message = message;
 }
 
-static void reschedule_timeout(int drive, const char *message, int marg)
+static void reschedule_timeout(int drive, const char *message)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&floppy_lock, flags);
-	__reschedule_timeout(drive, message, marg);
+	__reschedule_timeout(drive, message);
 	spin_unlock_irqrestore(&floppy_lock, flags);
 }
 
-#define INFBOUND(a,b) (a)=max_t(int, a, b)
-#define SUPBOUND(a,b) (a)=min_t(int, a, b)
+#define INFBOUND(a, b) (a) = max_t(int, a, b)
+#define SUPBOUND(a, b) (a) = min_t(int, a, b)
 
 /*
  * Bottom half floppy driver.
@@ -739,7 +726,6 @@ static int disk_change(int drive)
 {
 	int fdc = FDC(drive);
 
-#ifdef FLOPPY_SANITY_CHECK
 	if (time_before(jiffies, UDRS->select_date + UDP->select_delay))
 		DPRINT("WARNING disk change called early\n");
 	if (!(FDCS->dor & (0x10 << UNIT(drive))) ||
@@ -748,31 +734,27 @@ static int disk_change(int drive)
 		DPRINT("drive=%d fdc=%d dor=%x\n", drive, FDC(drive),
 		       (unsigned int)FDCS->dor);
 	}
-#endif
 
-#ifdef DCL_DEBUG
-	if (UDP->flags & FD_DEBUG) {
-		DPRINT("checking disk change line for drive %d\n", drive);
-		DPRINT("jiffies=%lu\n", jiffies);
-		DPRINT("disk change line=%x\n", fd_inb(FD_DIR) & 0x80);
-		DPRINT("flags=%lx\n", UDRS->flags);
-	}
-#endif
+	debug_dcl(UDP->flags,
+		  "checking disk change line for drive %d\n", drive);
+	debug_dcl(UDP->flags, "jiffies=%lu\n", jiffies);
+	debug_dcl(UDP->flags, "disk change line=%x\n", fd_inb(FD_DIR) & 0x80);
+	debug_dcl(UDP->flags, "flags=%lx\n", UDRS->flags);
+
 	if (UDP->flags & FD_BROKEN_DCL)
-		return UTESTF(FD_DISK_CHANGED);
+		return test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
 	if ((fd_inb(FD_DIR) ^ UDP->flags) & 0x80) {
-		USETF(FD_VERIFY);	/* verify write protection */
-		if (UDRS->maxblock) {
-			/* mark it changed */
-			USETF(FD_DISK_CHANGED);
-		}
+		set_bit(FD_VERIFY_BIT, &UDRS->flags);
+					/* verify write protection */
+
+		if (UDRS->maxblock)	/* mark it changed */
+			set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
 
 		/* invalidate its geometry */
 		if (UDRS->keep_data >= 0) {
 			if ((UDP->flags & FTD_MSG) &&
 			    current_type[drive] != NULL)
-				DPRINT("Disk type is undefined after "
-				       "disk change\n");
+				DPRINT("Disk type is undefined after disk change\n");
 			current_type[drive] = NULL;
 			floppy_sizes[TOMINOR(drive)] = MAX_DISK_SIZE << 1;
 		}
@@ -780,7 +762,7 @@ static int disk_change(int drive)
 		return 1;
 	} else {
 		UDRS->last_checked = jiffies;
-		UCLEARF(FD_DISK_NEWCHANGE);
+		clear_bit(FD_DISK_NEWCHANGE_BIT, &UDRS->flags);
 	}
 	return 0;
 }
@@ -790,6 +772,12 @@ static inline int is_selected(int dor, i
 	return ((dor & (0x10 << unit)) && (dor & 3) == unit);
 }
 
+static bool is_ready_state(int status)
+{
+	int state = status & (STATUS_READY | STATUS_DIR | STATUS_DMA);
+	return state == STATUS_READY;
+}
+
 static int set_dor(int fdc, char mask, char data)
 {
 	unsigned char unit;
@@ -806,11 +794,8 @@ static int set_dor(int fdc, char mask, c
 		unit = olddor & 0x3;
 		if (is_selected(olddor, unit) && !is_selected(newdor, unit)) {
 			drive = REVDRIVE(fdc, unit);
-#ifdef DCL_DEBUG
-			if (UDP->flags & FD_DEBUG) {
-				DPRINT("calling disk change from set_dor\n");
-			}
-#endif
+			debug_dcl(UDP->flags,
+				  "calling disk change from set_dor\n");
 			disk_change(drive);
 		}
 		FDCS->dor = newdor;
@@ -834,8 +819,10 @@ static void twaddle(void)
 	DRS->select_date = jiffies;
 }
 
-/* reset all driver information about the current fdc. This is needed after
- * a reset, and after a raw command. */
+/*
+ * Reset all driver information about the current fdc.
+ * This is needed after a reset, and after a raw command.
+ */
 static void reset_fdc_info(int mode)
 {
 	int drive;
@@ -857,7 +844,7 @@ static void set_fdc(int drive)
 		current_drive = drive;
 	}
 	if (fdc != 1 && fdc != 0) {
-		printk("bad fdc value\n");
+		pr_info("bad fdc value\n");
 		return;
 	}
 	set_dor(fdc, ~0, 8);
@@ -871,11 +858,10 @@ static void set_fdc(int drive)
 }
 
 /* locks the driver */
-static int _lock_fdc(int drive, int interruptible, int line)
+static int _lock_fdc(int drive, bool interruptible, int line)
 {
 	if (!usage_count) {
-		printk(KERN_ERR
-		       "Trying to lock fdc while usage count=0 at line %d\n",
+		pr_err("Trying to lock fdc while usage count=0 at line %d\n",
 		       line);
 		return -1;
 	}
@@ -904,15 +890,13 @@ static int _lock_fdc(int drive, int inte
 	}
 	command_status = FD_COMMAND_NONE;
 
-	__reschedule_timeout(drive, "lock fdc", 0);
+	__reschedule_timeout(drive, "lock fdc");
 	set_fdc(drive);
 	return 0;
 }
 
-#define lock_fdc(drive,interruptible) _lock_fdc(drive,interruptible, __LINE__)
-
-#define LOCK_FDC(drive,interruptible) \
-if (lock_fdc(drive,interruptible)) return -EINTR;
+#define lock_fdc(drive, interruptible)			\
+	_lock_fdc(drive, interruptible, __LINE__)
 
 /* unlocks the driver */
 static inline void unlock_fdc(void)
@@ -924,7 +908,7 @@ static inline void unlock_fdc(void)
 		DPRINT("FDC access conflict!\n");
 
 	if (do_floppy)
-		DPRINT("device interrupt still active at FDC release: %p!\n",
+		DPRINT("device interrupt still active at FDC release: %pf!\n",
 		       do_floppy);
 	command_status = FD_COMMAND_NONE;
 	spin_lock_irqsave(&floppy_lock, flags);
@@ -1003,7 +987,7 @@ static void empty(void)
 
 static DECLARE_WORK(floppy_work, NULL);
 
-static void schedule_bh(void (*handler) (void))
+static void schedule_bh(void (*handler)(void))
 {
 	PREPARE_WORK(&floppy_work, (work_func_t)handler);
 	schedule_work(&floppy_work);
@@ -1026,11 +1010,7 @@ static void cancel_activity(void)
  * transfer */
 static void fd_watchdog(void)
 {
-#ifdef DCL_DEBUG
-	if (DP->flags & FD_DEBUG) {
-		DPRINT("calling disk change from watchdog\n");
-	}
-#endif
+	debug_dcl(DP->flags, "calling disk change from watchdog\n");
 
 	if (disk_change(current_drive)) {
 		DPRINT("disk removed during i/o\n");
@@ -1039,7 +1019,7 @@ static void fd_watchdog(void)
 		reset_fdc();
 	} else {
 		del_timer(&fd_timer);
-		fd_timer.function = (timeout_fn) fd_watchdog;
+		fd_timer.function = (timeout_fn)fd_watchdog;
 		fd_timer.expires = jiffies + HZ / 10;
 		add_timer(&fd_timer);
 	}
@@ -1105,25 +1085,23 @@ static void setup_DMA(void)
 {
 	unsigned long f;
 
-#ifdef FLOPPY_SANITY_CHECK
 	if (raw_cmd->length == 0) {
 		int i;
 
-		printk("zero dma transfer size:");
+		pr_info("zero dma transfer size:");
 		for (i = 0; i < raw_cmd->cmd_count; i++)
-			printk("%x,", raw_cmd->cmd[i]);
-		printk("\n");
+			pr_cont("%x,", raw_cmd->cmd[i]);
+		pr_cont("\n");
 		cont->done(0);
 		FDCS->reset = 1;
 		return;
 	}
 	if (((unsigned long)raw_cmd->kernel_data) % 512) {
-		printk("non aligned address: %p\n", raw_cmd->kernel_data);
+		pr_info("non aligned address: %p\n", raw_cmd->kernel_data);
 		cont->done(0);
 		FDCS->reset = 1;
 		return;
 	}
-#endif
 	f = claim_dma_lock();
 	fd_disable_dma();
 #ifdef fd_dma_setup
@@ -1165,7 +1143,7 @@ static int wait_til_ready(void)
 		if (status & STATUS_READY)
 			return status;
 	}
-	if (!initialising) {
+	if (initialized) {
 		DPRINT("Getstatus times out (%x) on fdc %d\n", status, fdc);
 		show_floppy();
 	}
@@ -1176,22 +1154,21 @@ static int wait_til_ready(void)
 /* sends a command byte to the fdc */
 static int output_byte(char byte)
 {
-	int status;
+	int status = wait_til_ready();
 
-	if ((status = wait_til_ready()) < 0)
+	if (status < 0)
 		return -1;
-	if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY) {
+
+	if (is_ready_state(status)) {
 		fd_outb(byte, FD_DATA);
-#ifdef FLOPPY_SANITY_CHECK
 		output_log[output_log_pos].data = byte;
 		output_log[output_log_pos].status = status;
 		output_log[output_log_pos].jiffies = jiffies;
 		output_log_pos = (output_log_pos + 1) % OLOGSIZE;
-#endif
 		return 0;
 	}
 	FDCS->reset = 1;
-	if (!initialising) {
+	if (initialized) {
 		DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n",
 		       byte, fdc, status);
 		show_floppy();
@@ -1199,8 +1176,6 @@ static int output_byte(char byte)
 	return -1;
 }
 
-#define LAST_OUT(x) if (output_byte(x)<0){ reset_fdc();return;}
-
 /* gets the response from the fdc */
 static int result(void)
 {
@@ -1208,14 +1183,13 @@ static int result(void)
 	int status = 0;
 
 	for (i = 0; i < MAX_REPLIES; i++) {
-		if ((status = wait_til_ready()) < 0)
+		status = wait_til_ready();
+		if (status < 0)
 			break;
 		status &= STATUS_DIR | STATUS_READY | STATUS_BUSY | STATUS_DMA;
 		if ((status & ~STATUS_BUSY) == STATUS_READY) {
-#ifdef FLOPPY_SANITY_CHECK
 			resultjiffies = jiffies;
 			resultsize = i;
-#endif
 			return i;
 		}
 		if (status == (STATUS_DIR | STATUS_READY | STATUS_BUSY))
@@ -1223,10 +1197,9 @@ static int result(void)
 		else
 			break;
 	}
-	if (!initialising) {
-		DPRINT
-		    ("get result error. Fdc=%d Last status=%x Read bytes=%d\n",
-		     fdc, status, i);
+	if (initialized) {
+		DPRINT("get result error. Fdc=%d Last status=%x Read bytes=%d\n",
+		       fdc, status, i);
 		show_floppy();
 	}
 	FDCS->reset = 1;
@@ -1237,12 +1210,14 @@ static int result(void)
 /* does the fdc need more output? */
 static int need_more_output(void)
 {
-	int status;
+	int status = wait_til_ready();
 
-	if ((status = wait_til_ready()) < 0)
+	if (status < 0)
 		return -1;
-	if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY)
+
+	if (is_ready_state(status))
 		return MORE_OUTPUT;
+
 	return result();
 }
 
@@ -1264,9 +1239,12 @@ static inline void perpendicular_mode(vo
 		default:
 			DPRINT("Invalid data rate for perpendicular mode!\n");
 			cont->done(0);
-			FDCS->reset = 1;	/* convenient way to return to
-						 * redo without to much hassle (deep
-						 * stack et al. */
+			FDCS->reset = 1;
+					/*
+					 * convenient way to return to
+					 * redo without too much hassle
+					 * (deep stack et al.)
+					 */
 			return;
 		}
 	} else
@@ -1366,9 +1344,9 @@ static void fdc_specify(void)
 
 	/* Convert step rate from microseconds to milliseconds and 4 bits */
 	srt = 16 - DIV_ROUND_UP(DP->srt * scale_dtr / 1000, NOMINAL_DTR);
-	if (slow_floppy) {
+	if (slow_floppy)
 		srt = srt / 4;
-	}
+
 	SUPBOUND(srt, 0xf);
 	INFBOUND(srt, 0);
 
@@ -1415,16 +1393,46 @@ static int fdc_dtr(void)
 	 * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies)
 	 */
 	FDCS->dtr = raw_cmd->rate & 3;
-	return (fd_wait_for_completion(jiffies + 2UL * HZ / 100,
-				       (timeout_fn) floppy_ready));
+	return fd_wait_for_completion(jiffies + 2UL * HZ / 100,
+				      (timeout_fn)floppy_ready);
 }				/* fdc_dtr */
 
 static void tell_sector(void)
 {
-	printk(": track %d, head %d, sector %d, size %d",
-	       R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE);
+	pr_cont(": track %d, head %d, sector %d, size %d",
+		R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE);
 }				/* tell_sector */
 
+static void print_errors(void)
+{
+	DPRINT("");
+	if (ST0 & ST0_ECE) {
+		pr_cont("Recalibrate failed!");
+	} else if (ST2 & ST2_CRC) {
+		pr_cont("data CRC error");
+		tell_sector();
+	} else if (ST1 & ST1_CRC) {
+		pr_cont("CRC error");
+		tell_sector();
+	} else if ((ST1 & (ST1_MAM | ST1_ND)) ||
+		   (ST2 & ST2_MAM)) {
+		if (!probing) {
+			pr_cont("sector not found");
+			tell_sector();
+		} else
+			pr_cont("probe failed...");
+	} else if (ST2 & ST2_WC) {	/* seek error */
+		pr_cont("wrong cylinder");
+	} else if (ST2 & ST2_BC) {	/* cylinder marked as bad */
+		pr_cont("bad cylinder");
+	} else {
+		pr_cont("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x",
+			ST0, ST1, ST2);
+		tell_sector();
+	}
+	pr_cont("\n");
+}
+
 /*
  * OK, this error interpreting routine is called after a
  * DMA read/write has succeeded
@@ -1437,7 +1445,7 @@ static int interpret_errors(void)
 	char bad;
 
 	if (inr != 7) {
-		DPRINT("-- FDC reply error");
+		DPRINT("-- FDC reply error\n");
 		FDCS->reset = 1;
 		return 1;
 	}
@@ -1450,43 +1458,17 @@ static int interpret_errors(void)
 		bad = 1;
 		if (ST1 & ST1_WP) {
 			DPRINT("Drive is write protected\n");
-			CLEARF(FD_DISK_WRITABLE);
+			clear_bit(FD_DISK_WRITABLE_BIT, &DRS->flags);
 			cont->done(0);
 			bad = 2;
 		} else if (ST1 & ST1_ND) {
-			SETF(FD_NEED_TWADDLE);
+			set_bit(FD_NEED_TWADDLE_BIT, &DRS->flags);
 		} else if (ST1 & ST1_OR) {
 			if (DP->flags & FTD_MSG)
 				DPRINT("Over/Underrun - retrying\n");
 			bad = 0;
 		} else if (*errors >= DP->max_errors.reporting) {
-			DPRINT("");
-			if (ST0 & ST0_ECE) {
-				printk("Recalibrate failed!");
-			} else if (ST2 & ST2_CRC) {
-				printk("data CRC error");
-				tell_sector();
-			} else if (ST1 & ST1_CRC) {
-				printk("CRC error");
-				tell_sector();
-			} else if ((ST1 & (ST1_MAM | ST1_ND))
-				   || (ST2 & ST2_MAM)) {
-				if (!probing) {
-					printk("sector not found");
-					tell_sector();
-				} else
-					printk("probe failed...");
-			} else if (ST2 & ST2_WC) {	/* seek error */
-				printk("wrong cylinder");
-			} else if (ST2 & ST2_BC) {	/* cylinder marked as bad */
-				printk("bad cylinder");
-			} else {
-				printk
-				    ("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x",
-				     ST0, ST1, ST2);
-				tell_sector();
-			}
-			printk("\n");
+			print_errors();
 		}
 		if (ST2 & ST2_WC || ST2 & ST2_BC)
 			/* wrong cylinder => recal */
@@ -1531,9 +1513,9 @@ static void setup_rw_floppy(void)
 		 */
 		if (time_after(ready_date, jiffies + DP->select_delay)) {
 			ready_date -= DP->select_delay;
-			function = (timeout_fn) floppy_start;
+			function = (timeout_fn)floppy_start;
 		} else
-			function = (timeout_fn) setup_rw_floppy;
+			function = (timeout_fn)setup_rw_floppy;
 
 		/* wait until the floppy is spinning fast enough */
 		if (fd_wait_for_completion(ready_date, function))
@@ -1551,7 +1533,7 @@ static void setup_rw_floppy(void)
 	for (i = 0; i < raw_cmd->cmd_count; i++)
 		r |= output_byte(raw_cmd->cmd[i]);
 
-	debugt("rw_command: ");
+	debugt(__func__, "rw_command");
 
 	if (r) {
 		cont->error();
@@ -1574,7 +1556,7 @@ static int blind_seek;
  */
 static void seek_interrupt(void)
 {
-	debugt("seek interrupt:");
+	debugt(__func__, "");
 	if (inr != 2 || (ST0 & 0xF8) != 0x20) {
 		DPRINT("seek failed\n");
 		DRS->track = NEED_2_RECAL;
@@ -1583,14 +1565,11 @@ static void seek_interrupt(void)
 		return;
 	}
 	if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek) {
-#ifdef DCL_DEBUG
-		if (DP->flags & FD_DEBUG) {
-			DPRINT
-			    ("clearing NEWCHANGE flag because of effective seek\n");
-			DPRINT("jiffies=%lu\n", jiffies);
-		}
-#endif
-		CLEARF(FD_DISK_NEWCHANGE);	/* effective seek */
+		debug_dcl(DP->flags,
+			  "clearing NEWCHANGE flag because of effective seek\n");
+		debug_dcl(DP->flags, "jiffies=%lu\n", jiffies);
+		clear_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags);
+					/* effective seek */
 		DRS->select_date = jiffies;
 	}
 	DRS->track = ST1;
@@ -1599,26 +1578,23 @@ static void seek_interrupt(void)
 
 static void check_wp(void)
 {
-	if (TESTF(FD_VERIFY)) {
-		/* check write protection */
+	if (test_bit(FD_VERIFY_BIT, &DRS->flags)) {
+					/* check write protection */
 		output_byte(FD_GETSTATUS);
 		output_byte(UNIT(current_drive));
 		if (result() != 1) {
 			FDCS->reset = 1;
 			return;
 		}
-		CLEARF(FD_VERIFY);
-		CLEARF(FD_NEED_TWADDLE);
-#ifdef DCL_DEBUG
-		if (DP->flags & FD_DEBUG) {
-			DPRINT("checking whether disk is write protected\n");
-			DPRINT("wp=%x\n", ST3 & 0x40);
-		}
-#endif
+		clear_bit(FD_VERIFY_BIT, &DRS->flags);
+		clear_bit(FD_NEED_TWADDLE_BIT, &DRS->flags);
+		debug_dcl(DP->flags,
+			  "checking whether disk is write protected\n");
+		debug_dcl(DP->flags, "wp=%x\n", ST3 & 0x40);
 		if (!(ST3 & 0x40))
-			SETF(FD_DISK_WRITABLE);
+			set_bit(FD_DISK_WRITABLE_BIT, &DRS->flags);
 		else
-			CLEARF(FD_DISK_WRITABLE);
+			clear_bit(FD_DISK_WRITABLE_BIT, &DRS->flags);
 	}
 }
 
@@ -1628,19 +1604,15 @@ static void seek_floppy(void)
 
 	blind_seek = 0;
 
-#ifdef DCL_DEBUG
-	if (DP->flags & FD_DEBUG) {
-		DPRINT("calling disk change from seek\n");
-	}
-#endif
+	debug_dcl(DP->flags, "calling disk change from %s\n", __func__);
 
-	if (!TESTF(FD_DISK_NEWCHANGE) &&
+	if (!test_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags) &&
 	    disk_change(current_drive) && (raw_cmd->flags & FD_RAW_NEED_DISK)) {
 		/* the media changed flag should be cleared after the seek.
 		 * If it isn't, this means that there is really no disk in
 		 * the drive.
 		 */
-		SETF(FD_DISK_CHANGED);
+		set_bit(FD_DISK_CHANGED_BIT, &DRS->flags);
 		cont->done(0);
 		cont->redo();
 		return;
@@ -1648,7 +1620,7 @@ static void seek_floppy(void)
 	if (DRS->track <= NEED_1_RECAL) {
 		recalibrate_floppy();
 		return;
-	} else if (TESTF(FD_DISK_NEWCHANGE) &&
+	} else if (test_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags) &&
 		   (raw_cmd->flags & FD_RAW_NEED_DISK) &&
 		   (DRS->track <= NO_TRACK || DRS->track == raw_cmd->track)) {
 		/* we seek to clear the media-changed condition. Does anybody
@@ -1677,19 +1649,22 @@ static void seek_floppy(void)
 	do_floppy = seek_interrupt;
 	output_byte(FD_SEEK);
 	output_byte(UNIT(current_drive));
-	LAST_OUT(track);
-	debugt("seek command:");
+	if (output_byte(track) < 0) {
+		reset_fdc();
+		return;
+	}
+	debugt(__func__, "");
 }
 
 static void recal_interrupt(void)
 {
-	debugt("recal interrupt:");
+	debugt(__func__, "");
 	if (inr != 2)
 		FDCS->reset = 1;
 	else if (ST0 & ST0_ECE) {
 		switch (DRS->track) {
 		case NEED_1_RECAL:
-			debugt("recal interrupt need 1 recal:");
+			debugt(__func__, "need 1 recal");
 			/* after a second recalibrate, we still haven't
 			 * reached track 0. Probably no drive. Raise an
 			 * error, as failing immediately might upset
@@ -1698,25 +1673,21 @@ static void recal_interrupt(void)
 			cont->redo();
 			return;
 		case NEED_2_RECAL:
-			debugt("recal interrupt need 2 recal:");
+			debugt(__func__, "need 2 recal");
 			/* If we already did a recalibrate,
 			 * and we are not at track 0, this
 			 * means we have moved. (The only way
 			 * not to move at recalibration is to
 			 * be already at track 0.) Clear the
 			 * new change flag */
-#ifdef DCL_DEBUG
-			if (DP->flags & FD_DEBUG) {
-				DPRINT
-				    ("clearing NEWCHANGE flag because of second recalibrate\n");
-			}
-#endif
+			debug_dcl(DP->flags,
+				  "clearing NEWCHANGE flag because of second recalibrate\n");
 
-			CLEARF(FD_DISK_NEWCHANGE);
+			clear_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags);
 			DRS->select_date = jiffies;
 			/* fall through */
 		default:
-			debugt("recal interrupt default:");
+			debugt(__func__, "default");
 			/* Recalibrate moves the head by at
 			 * most 80 steps. If after one
 			 * recalibrate we don't have reached
@@ -1738,8 +1709,8 @@ static void print_result(char *message,
 	DPRINT("%s ", message);
 	if (inr >= 0)
 		for (i = 0; i < inr; i++)
-			printk("repl[%d]=%x ", i, reply_buffer[i]);
-	printk("\n");
+			pr_cont("repl[%d]=%x ", i, reply_buffer[i]);
+	pr_cont("\n");
 }
 
 /* interrupt handler. Note that this can be called externally on the Sparc */
@@ -1760,10 +1731,10 @@ irqreturn_t floppy_interrupt(int irq, vo
 	do_floppy = NULL;
 	if (fdc >= N_FDC || FDCS->address == -1) {
 		/* we don't even know which FDC is the culprit */
-		printk("DOR0=%x\n", fdc_state[0].dor);
-		printk("floppy interrupt on bizarre fdc %d\n", fdc);
-		printk("handler=%p\n", handler);
-		is_alive("bizarre fdc");
+		pr_info("DOR0=%x\n", fdc_state[0].dor);
+		pr_info("floppy interrupt on bizarre fdc %d\n", fdc);
+		pr_info("handler=%pf\n", handler);
+		is_alive(__func__, "bizarre fdc");
 		return IRQ_NONE;
 	}
 
@@ -1777,7 +1748,7 @@ irqreturn_t floppy_interrupt(int irq, vo
 	 * activity.
 	 */
 
-	do_print = !handler && print_unex && !initialising;
+	do_print = !handler && print_unex && initialized;
 
 	inr = result();
 	if (do_print)
@@ -1790,15 +1761,15 @@ irqreturn_t floppy_interrupt(int irq, vo
 			if (do_print)
 				print_result("sensei", inr);
 			max_sensei--;
-		} while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2
-			 && max_sensei);
+		} while ((ST0 & 0x83) != UNIT(current_drive) &&
+			 inr == 2 && max_sensei);
 	}
 	if (!handler) {
 		FDCS->reset = 1;
 		return IRQ_NONE;
 	}
 	schedule_bh(handler);
-	is_alive("normal interrupt end");
+	is_alive(__func__, "normal interrupt end");
 
 	/* FIXME! Was it really for us? */
 	return IRQ_HANDLED;
@@ -1806,10 +1777,11 @@ irqreturn_t floppy_interrupt(int irq, vo
 
 static void recalibrate_floppy(void)
 {
-	debugt("recalibrate floppy:");
+	debugt(__func__, "");
 	do_floppy = recal_interrupt;
 	output_byte(FD_RECALIBRATE);
-	LAST_OUT(UNIT(current_drive));
+	if (output_byte(UNIT(current_drive)) < 0)
+		reset_fdc();
 }
 
 /*
@@ -1817,10 +1789,10 @@ static void recalibrate_floppy(void)
  */
 static void reset_interrupt(void)
 {
-	debugt("reset interrupt:");
+	debugt(__func__, "");
 	result();		/* get the status ready for set_fdc */
 	if (FDCS->reset) {
-		printk("reset set in interrupt, calling %p\n", cont->error);
+		pr_info("reset set in interrupt, calling %pf\n", cont->error);
 		cont->error();	/* a reset just after a reset. BAD! */
 	}
 	cont->redo();
@@ -1858,53 +1830,49 @@ static void show_floppy(void)
 {
 	int i;
 
-	printk("\n");
-	printk("floppy driver state\n");
-	printk("-------------------\n");
-	printk("now=%lu last interrupt=%lu diff=%lu last called handler=%p\n",
-	       jiffies, interruptjiffies, jiffies - interruptjiffies,
-	       lasthandler);
+	pr_info("\n");
+	pr_info("floppy driver state\n");
+	pr_info("-------------------\n");
+	pr_info("now=%lu last interrupt=%lu diff=%lu last called handler=%pf\n",
+		jiffies, interruptjiffies, jiffies - interruptjiffies,
+		lasthandler);
 
-#ifdef FLOPPY_SANITY_CHECK
-	printk("timeout_message=%s\n", timeout_message);
-	printk("last output bytes:\n");
+	pr_info("timeout_message=%s\n", timeout_message);
+	pr_info("last output bytes:\n");
 	for (i = 0; i < OLOGSIZE; i++)
-		printk("%2x %2x %lu\n",
-		       output_log[(i + output_log_pos) % OLOGSIZE].data,
-		       output_log[(i + output_log_pos) % OLOGSIZE].status,
-		       output_log[(i + output_log_pos) % OLOGSIZE].jiffies);
-	printk("last result at %lu\n", resultjiffies);
-	printk("last redo_fd_request at %lu\n", lastredo);
-	for (i = 0; i < resultsize; i++) {
-		printk("%2x ", reply_buffer[i]);
-	}
-	printk("\n");
-#endif
+		pr_info("%2x %2x %lu\n",
+			output_log[(i + output_log_pos) % OLOGSIZE].data,
+			output_log[(i + output_log_pos) % OLOGSIZE].status,
+			output_log[(i + output_log_pos) % OLOGSIZE].jiffies);
+	pr_info("last result at %lu\n", resultjiffies);
+	pr_info("last redo_fd_request at %lu\n", lastredo);
+	print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1,
+		       reply_buffer, resultsize, true);
 
-	printk("status=%x\n", fd_inb(FD_STATUS));
-	printk("fdc_busy=%lu\n", fdc_busy);
+	pr_info("status=%x\n", fd_inb(FD_STATUS));
+	pr_info("fdc_busy=%lu\n", fdc_busy);
 	if (do_floppy)
-		printk("do_floppy=%p\n", do_floppy);
+		pr_info("do_floppy=%pf\n", do_floppy);
 	if (work_pending(&floppy_work))
-		printk("floppy_work.func=%p\n", floppy_work.func);
+		pr_info("floppy_work.func=%pf\n", floppy_work.func);
 	if (timer_pending(&fd_timer))
-		printk("fd_timer.function=%p\n", fd_timer.function);
+		pr_info("fd_timer.function=%pf\n", fd_timer.function);
 	if (timer_pending(&fd_timeout)) {
-		printk("timer_function=%p\n", fd_timeout.function);
-		printk("expires=%lu\n", fd_timeout.expires - jiffies);
-		printk("now=%lu\n", jiffies);
+		pr_info("timer_function=%pf\n", fd_timeout.function);
+		pr_info("expires=%lu\n", fd_timeout.expires - jiffies);
+		pr_info("now=%lu\n", jiffies);
 	}
-	printk("cont=%p\n", cont);
-	printk("current_req=%p\n", current_req);
-	printk("command_status=%d\n", command_status);
-	printk("\n");
+	pr_info("cont=%p\n", cont);
+	pr_info("current_req=%p\n", current_req);
+	pr_info("command_status=%d\n", command_status);
+	pr_info("\n");
 }
 
 static void floppy_shutdown(unsigned long data)
 {
 	unsigned long flags;
 
-	if (!initialising)
+	if (initialized)
 		show_floppy();
 	cancel_activity();
 
@@ -1916,17 +1884,17 @@ static void floppy_shutdown(unsigned lon
 
 	/* avoid dma going to a random drive after shutdown */
 
-	if (!initialising)
+	if (initialized)
 		DPRINT("floppy timeout called\n");
 	FDCS->reset = 1;
 	if (cont) {
 		cont->done(0);
 		cont->redo();	/* this will recall reset when needed */
 	} else {
-		printk("no cont in shutdown!\n");
+		pr_info("no cont in shutdown!\n");
 		process_fd_request();
 	}
-	is_alive("floppy shutdown");
+	is_alive(__func__, "");
 }
 
 /* start motor, check media-changed condition and write protection */
@@ -1954,27 +1922,26 @@ static int start_motor(void (*function)(
 	set_dor(fdc, mask, data);
 
 	/* wait_for_completion also schedules reset if needed. */
-	return (fd_wait_for_completion(DRS->select_date + DP->select_delay,
-				       (timeout_fn) function));
+	return fd_wait_for_completion(DRS->select_date + DP->select_delay,
+				      (timeout_fn)function);
 }
 
 static void floppy_ready(void)
 {
-	CHECK_RESET;
+	if (FDCS->reset) {
+		reset_fdc();
+		return;
+	}
 	if (start_motor(floppy_ready))
 		return;
 	if (fdc_dtr())
 		return;
 
-#ifdef DCL_DEBUG
-	if (DP->flags & FD_DEBUG) {
-		DPRINT("calling disk change from floppy_ready\n");
-	}
-#endif
+	debug_dcl(DP->flags, "calling disk change from floppy_ready\n");
 	if (!(raw_cmd->flags & FD_RAW_NO_MOTOR) &&
 	    disk_change(current_drive) && !DP->select_delay)
-		twaddle();	/* this clears the dcl on certain drive/controller
-				 * combinations */
+		twaddle();	/* this clears the dcl on certain
+				 * drive/controller combinations */
 
 #ifdef fd_chose_dma_mode
 	if ((raw_cmd->flags & FD_RAW_READ) || (raw_cmd->flags & FD_RAW_WRITE)) {
@@ -1998,15 +1965,11 @@ static void floppy_ready(void)
 
 static void floppy_start(void)
 {
-	reschedule_timeout(current_reqD, "floppy start", 0);
+	reschedule_timeout(current_reqD, "floppy start");
 
 	scandrives();
-#ifdef DCL_DEBUG
-	if (DP->flags & FD_DEBUG) {
-		DPRINT("setting NEWCHANGE in floppy_start\n");
-	}
-#endif
-	SETF(FD_DISK_NEWCHANGE);
+	debug_dcl(DP->flags, "setting NEWCHANGE in floppy_start\n");
+	set_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags);
 	floppy_ready();
 }
 
@@ -2026,7 +1989,7 @@ static void floppy_start(void)
 
 static void do_wakeup(void)
 {
-	reschedule_timeout(MAXTIMEOUT, "do wakeup", 0);
+	reschedule_timeout(MAXTIMEOUT, "do wakeup");
 	cont = NULL;
 	command_status += 2;
 	wake_up(&command_done);
@@ -2046,7 +2009,7 @@ static struct cont_t intr_cont = {
 	.done		= (done_f)empty
 };
 
-static int wait_til_done(void (*handler)(void), int interruptible)
+static int wait_til_done(void (*handler)(void), bool interruptible)
 {
 	int ret;
 
@@ -2064,7 +2027,7 @@ static int wait_til_done(void (*handler)
 			if (command_status >= 2 || !NO_SIGNAL)
 				break;
 
-			is_alive("wait_til_done");
+			is_alive(__func__, "");
 			schedule();
 		}
 
@@ -2180,9 +2143,9 @@ static void format_interrupt(void)
 	cont->redo();
 }
 
-#define CODE2SIZE (ssize = ((1 << SIZECODE) + 3) >> 2)
-#define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80) >>1))
+#define FM_MODE(x, y) ((y) & ~(((x)->rate & 0x80) >> 1))
 #define CT(x) ((x) | 0xc0)
+
 static void setup_format_params(int track)
 {
 	int n;
@@ -2197,8 +2160,8 @@ static void setup_format_params(int trac
 	raw_cmd = &default_raw_cmd;
 	raw_cmd->track = track;
 
-	raw_cmd->flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
-	    FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK;
+	raw_cmd->flags = (FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
+			  FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK);
 	raw_cmd->rate = _floppy->rate & 0x43;
 	raw_cmd->cmd_count = NR_F;
 	COMMAND = FM_MODE(_floppy, FD_FORMAT);
@@ -2257,7 +2220,7 @@ static void redo_format(void)
 	buffer_track = -1;
 	setup_format_params(format_req.track << STRETCH(_floppy));
 	floppy_start();
-	debugt("queue format request");
+	debugt(__func__, "queue format request");
 }
 
 static struct cont_t format_cont = {
@@ -2271,7 +2234,9 @@ static int do_format(int drive, struct f
 {
 	int ret;
 
-	LOCK_FDC(drive, 1);
+	if (lock_fdc(drive, true))
+		return -EINTR;
+
 	set_floppy(drive);
 	if (!_floppy ||
 	    _floppy->track > DP->tracks ||
@@ -2286,7 +2251,9 @@ static int do_format(int drive, struct f
 	format_errors = 0;
 	cont = &format_cont;
 	errors = &format_errors;
-	IWAIT(redo_format);
+	ret = wait_til_done(redo_format, true);
+	if (ret == -EINTR)
+		return -EINTR;
 	process_fd_request();
 	return ret;
 }
@@ -2320,12 +2287,14 @@ static void request_done(int uptodate)
 	struct request *req = current_req;
 	unsigned long flags;
 	int block;
+	char msg[sizeof("request done ") + sizeof(int) * 3];
 
 	probing = 0;
-	reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate);
+	snprintf(msg, sizeof(msg), "request done %d", uptodate);
+	reschedule_timeout(MAXTIMEOUT, msg);
 
 	if (!req) {
-		printk("floppy.c: no request in request_done\n");
+		pr_info("floppy.c: no request in request_done\n");
 		return;
 	}
 
@@ -2377,7 +2346,7 @@ static void rw_interrupt(void)
 		DRS->first_read_date = jiffies;
 
 	nr_sectors = 0;
-	CODE2SIZE;
+	ssize = DIV_ROUND_UP(1 << SIZECODE, 4);
 
 	if (ST1 & ST1_EOC)
 		eoc = 1;
@@ -2393,20 +2362,18 @@ static void rw_interrupt(void)
 		       R_HEAD - HEAD) * SECT_PER_TRACK +
 		      R_SECTOR - SECTOR + eoc) << SIZECODE >> 2;
 
-#ifdef FLOPPY_SANITY_CHECK
 	if (nr_sectors / ssize >
 	    DIV_ROUND_UP(in_sector_offset + current_count_sectors, ssize)) {
 		DPRINT("long rw: %x instead of %lx\n",
 		       nr_sectors, current_count_sectors);
-		printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
-		printk("rh=%d h=%d\n", R_HEAD, HEAD);
-		printk("rt=%d t=%d\n", R_TRACK, TRACK);
-		printk("heads=%d eoc=%d\n", heads, eoc);
-		printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
-		       fsector_t, ssize);
-		printk("in_sector_offset=%d\n", in_sector_offset);
+		pr_info("rs=%d s=%d\n", R_SECTOR, SECTOR);
+		pr_info("rh=%d h=%d\n", R_HEAD, HEAD);
+		pr_info("rt=%d t=%d\n", R_TRACK, TRACK);
+		pr_info("heads=%d eoc=%d\n", heads, eoc);
+		pr_info("spt=%d st=%d ss=%d\n",
+			SECT_PER_TRACK, fsector_t, ssize);
+		pr_info("in_sector_offset=%d\n", in_sector_offset);
 	}
-#endif
 
 	nr_sectors -= in_sector_offset;
 	INFBOUND(nr_sectors, 0);
@@ -2511,19 +2478,17 @@ static void copy_buffer(int ssize, int m
 					      blk_rq_sectors(current_req));
 
 	remaining = current_count_sectors << 9;
-#ifdef FLOPPY_SANITY_CHECK
 	if (remaining > blk_rq_bytes(current_req) && CT(COMMAND) == FD_WRITE) {
 		DPRINT("in copy buffer\n");
-		printk("current_count_sectors=%ld\n", current_count_sectors);
-		printk("remaining=%d\n", remaining >> 9);
-		printk("current_req->nr_sectors=%u\n",
-		       blk_rq_sectors(current_req));
-		printk("current_req->current_nr_sectors=%u\n",
-		       blk_rq_cur_sectors(current_req));
-		printk("max_sector=%d\n", max_sector);
-		printk("ssize=%d\n", ssize);
+		pr_info("current_count_sectors=%ld\n", current_count_sectors);
+		pr_info("remaining=%d\n", remaining >> 9);
+		pr_info("current_req->nr_sectors=%u\n",
+			blk_rq_sectors(current_req));
+		pr_info("current_req->current_nr_sectors=%u\n",
+			blk_rq_cur_sectors(current_req));
+		pr_info("max_sector=%d\n", max_sector);
+		pr_info("ssize=%d\n", ssize);
 	}
-#endif
 
 	buffer_max = max(max_sector, buffer_max);
 
@@ -2539,26 +2504,24 @@ static void copy_buffer(int ssize, int m
 		SUPBOUND(size, remaining);
 
 		buffer = page_address(bv->bv_page) + bv->bv_offset;
-#ifdef FLOPPY_SANITY_CHECK
 		if (dma_buffer + size >
 		    floppy_track_buffer + (max_buffer_sectors << 10) ||
 		    dma_buffer < floppy_track_buffer) {
 			DPRINT("buffer overrun in copy buffer %d\n",
-			       (int)((floppy_track_buffer -
-				      dma_buffer) >> 9));
-			printk("fsector_t=%d buffer_min=%d\n",
-			       fsector_t, buffer_min);
-			printk("current_count_sectors=%ld\n",
-			       current_count_sectors);
+			       (int)((floppy_track_buffer - dma_buffer) >> 9));
+			pr_info("fsector_t=%d buffer_min=%d\n",
+				fsector_t, buffer_min);
+			pr_info("current_count_sectors=%ld\n",
+				current_count_sectors);
 			if (CT(COMMAND) == FD_READ)
-				printk("read\n");
+				pr_info("read\n");
 			if (CT(COMMAND) == FD_WRITE)
-				printk("write\n");
+				pr_info("write\n");
 			break;
 		}
 		if (((unsigned long)buffer) % 512)
 			DPRINT("%p buffer not aligned\n", buffer);
-#endif
+
 		if (CT(COMMAND) == FD_READ)
 			memcpy(buffer, dma_buffer, size);
 		else
@@ -2567,13 +2530,11 @@ static void copy_buffer(int ssize, int m
 		remaining -= size;
 		dma_buffer += size;
 	}
-#ifdef FLOPPY_SANITY_CHECK
 	if (remaining) {
 		if (remaining > 0)
 			max_sector -= remaining >> 9;
 		DPRINT("weirdness: remaining %d\n", remaining >> 9);
 	}
-#endif
 }
 
 /* work around a bug in pseudo DMA
@@ -2593,15 +2554,14 @@ static void virtualdmabug_workaround(voi
 
 		hard_sectors = raw_cmd->length >> (7 + SIZECODE);
 		end_sector = SECTOR + hard_sectors - 1;
-#ifdef FLOPPY_SANITY_CHECK
 		if (end_sector > SECT_PER_TRACK) {
-			printk("too many sectors %d > %d\n",
-			       end_sector, SECT_PER_TRACK);
+			pr_info("too many sectors %d > %d\n",
+				end_sector, SECT_PER_TRACK);
 			return;
 		}
-#endif
-		SECT_PER_TRACK = end_sector;	/* make sure SECT_PER_TRACK points
-						 * to end of transfer */
+		SECT_PER_TRACK = end_sector;
+					/* make sure SECT_PER_TRACK
+					 * points to end of transfer */
 	}
 }
 
@@ -2624,7 +2584,7 @@ static int make_raw_rw_request(void)
 	int ssize;
 
 	if (max_buffer_sectors == 0) {
-		printk("VFS: Block I/O scheduled on unopened device\n");
+		pr_info("VFS: Block I/O scheduled on unopened device\n");
 		return 0;
 	}
 
@@ -2641,7 +2601,7 @@ static int make_raw_rw_request(void)
 		raw_cmd->flags |= FD_RAW_WRITE;
 		COMMAND = FM_MODE(_floppy, FD_WRITE);
 	} else {
-		DPRINT("make_raw_rw_request: unknown command\n");
+		DPRINT("%s: unknown command\n", __func__);
 		return 0;
 	}
 
@@ -2659,7 +2619,8 @@ static int make_raw_rw_request(void)
 	HEAD = fsector_t / _floppy->sect;
 
 	if (((_floppy->stretch & (FD_SWAPSIDES | FD_SECTBASEMASK)) ||
-	     TESTF(FD_NEED_TWADDLE)) && fsector_t < _floppy->sect)
+	     test_bit(FD_NEED_TWADDLE_BIT, &DRS->flags)) &&
+	    fsector_t < _floppy->sect)
 		max_sector = _floppy->sect;
 
 	/* 2M disks have phantom sectors on the first track */
@@ -2685,7 +2646,7 @@ static int make_raw_rw_request(void)
 	raw_cmd->track = TRACK << STRETCH(_floppy);
 	DR_SELECT = UNIT(current_drive) + PH_HEAD(_floppy, HEAD);
 	GAP = _floppy->gap;
-	CODE2SIZE;
+	ssize = DIV_ROUND_UP(1 << SIZECODE, 4);
 	SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE;
 	SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) +
 	    FD_SECTBASE(_floppy);
@@ -2730,8 +2691,10 @@ static int make_raw_rw_request(void)
 		}
 	} else if (in_sector_offset || blk_rq_sectors(current_req) < ssize) {
 		if (CT(COMMAND) == FD_WRITE) {
-			if (fsector_t + blk_rq_sectors(current_req) > ssize &&
-			    fsector_t + blk_rq_sectors(current_req) < ssize + ssize)
+			unsigned int sectors;
+
+			sectors = fsector_t + blk_rq_sectors(current_req);
+			if (sectors > ssize && sectors < ssize + ssize)
 				max_size = ssize + ssize;
 			else
 				max_size = ssize;
@@ -2752,12 +2715,10 @@ static int make_raw_rw_request(void)
 		 * on a 64 bit machine!
 		 */
 		max_size = buffer_chain_size();
-		dma_limit =
-		    (MAX_DMA_ADDRESS -
-		     ((unsigned long)current_req->buffer)) >> 9;
-		if ((unsigned long)max_size > dma_limit) {
+		dma_limit = (MAX_DMA_ADDRESS -
+			     ((unsigned long)current_req->buffer)) >> 9;
+		if ((unsigned long)max_size > dma_limit)
 			max_size = dma_limit;
-		}
 		/* 64 kb boundaries */
 		if (CROSS_64KB(current_req->buffer, max_size << 9))
 			max_size = (K_64 -
@@ -2773,16 +2734,16 @@ static int make_raw_rw_request(void)
 		 */
 		if (!direct ||
 		    (indirect * 2 > direct * 3 &&
-		     *errors < DP->max_errors.read_track && ((!probing
-		       || (DP->read_track & (1 << DRS->probed_format)))))) {
+		     *errors < DP->max_errors.read_track &&
+		     ((!probing ||
+		       (DP->read_track & (1 << DRS->probed_format)))))) {
 			max_size = blk_rq_sectors(current_req);
 		} else {
 			raw_cmd->kernel_data = current_req->buffer;
 			raw_cmd->length = current_count_sectors << 9;
 			if (raw_cmd->length == 0) {
-				DPRINT
-				    ("zero dma transfer attempted from make_raw_request\n");
-				DPRINT("indirect=%d direct=%d fsector_t=%d",
+				DPRINT("%s: zero dma transfer attempted\n", __func__);
+				DPRINT("indirect=%d direct=%d fsector_t=%d\n",
 				       indirect, direct, fsector_t);
 				return 0;
 			}
@@ -2802,25 +2763,22 @@ static int make_raw_rw_request(void)
 	    ((CT(COMMAND) == FD_READ ||
 	      (!in_sector_offset && blk_rq_sectors(current_req) >= ssize)) &&
 	     max_sector > 2 * max_buffer_sectors + buffer_min &&
-	     max_size + fsector_t > 2 * max_buffer_sectors + buffer_min)
-	    /* not enough space */
-	    ) {
+	     max_size + fsector_t > 2 * max_buffer_sectors + buffer_min)) {
+		/* not enough space */
 		buffer_track = -1;
 		buffer_drive = current_drive;
 		buffer_max = buffer_min = aligned_sector_t;
 	}
 	raw_cmd->kernel_data = floppy_track_buffer +
-	    ((aligned_sector_t - buffer_min) << 9);
+		((aligned_sector_t - buffer_min) << 9);
 
 	if (CT(COMMAND) == FD_WRITE) {
 		/* copy write buffer to track buffer.
 		 * if we get here, we know that the write
 		 * is either aligned or the data already in the buffer
 		 * (buffer will be overwritten) */
-#ifdef FLOPPY_SANITY_CHECK
 		if (in_sector_offset && buffer_track == -1)
 			DPRINT("internal error offset !=0 on write\n");
-#endif
 		buffer_track = raw_cmd->track;
 		buffer_drive = current_drive;
 		copy_buffer(ssize, max_sector,
@@ -2834,7 +2792,6 @@ static int make_raw_rw_request(void)
 	raw_cmd->length = in_sector_offset + current_count_sectors;
 	raw_cmd->length = ((raw_cmd->length - 1) | (ssize - 1)) + 1;
 	raw_cmd->length <<= 9;
-#ifdef FLOPPY_SANITY_CHECK
 	if ((raw_cmd->length < current_count_sectors << 9) ||
 	    (raw_cmd->kernel_data != current_req->buffer &&
 	     CT(COMMAND) == FD_WRITE &&
@@ -2845,19 +2802,19 @@ static int make_raw_rw_request(void)
 		DPRINT("fractionary current count b=%lx s=%lx\n",
 		       raw_cmd->length, current_count_sectors);
 		if (raw_cmd->kernel_data != current_req->buffer)
-			printk("addr=%d, length=%ld\n",
-			       (int)((raw_cmd->kernel_data -
-				      floppy_track_buffer) >> 9),
-			       current_count_sectors);
-		printk("st=%d ast=%d mse=%d msi=%d\n",
-		       fsector_t, aligned_sector_t, max_sector, max_size);
-		printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
-		printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
-		       COMMAND, SECTOR, HEAD, TRACK);
-		printk("buffer drive=%d\n", buffer_drive);
-		printk("buffer track=%d\n", buffer_track);
-		printk("buffer_min=%d\n", buffer_min);
-		printk("buffer_max=%d\n", buffer_max);
+			pr_info("addr=%d, length=%ld\n",
+				(int)((raw_cmd->kernel_data -
+				       floppy_track_buffer) >> 9),
+				current_count_sectors);
+		pr_info("st=%d ast=%d mse=%d msi=%d\n",
+			fsector_t, aligned_sector_t, max_sector, max_size);
+		pr_info("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
+		pr_info("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
+			COMMAND, SECTOR, HEAD, TRACK);
+		pr_info("buffer drive=%d\n", buffer_drive);
+		pr_info("buffer track=%d\n", buffer_track);
+		pr_info("buffer_min=%d\n", buffer_min);
+		pr_info("buffer_max=%d\n", buffer_max);
 		return 0;
 	}
 
@@ -2868,14 +2825,14 @@ static int make_raw_rw_request(void)
 		    raw_cmd->kernel_data + raw_cmd->length >
 		    floppy_track_buffer + (max_buffer_sectors << 10)) {
 			DPRINT("buffer overrun in schedule dma\n");
-			printk("fsector_t=%d buffer_min=%d current_count=%ld\n",
-			       fsector_t, buffer_min, raw_cmd->length >> 9);
-			printk("current_count_sectors=%ld\n",
-			       current_count_sectors);
+			pr_info("fsector_t=%d buffer_min=%d current_count=%ld\n",
+				fsector_t, buffer_min, raw_cmd->length >> 9);
+			pr_info("current_count_sectors=%ld\n",
+				current_count_sectors);
 			if (CT(COMMAND) == FD_READ)
-				printk("read\n");
+				pr_info("read\n");
 			if (CT(COMMAND) == FD_WRITE)
-				printk("write\n");
+				pr_info("write\n");
 			return 0;
 		}
 	} else if (raw_cmd->length > blk_rq_bytes(current_req) ||
@@ -2884,14 +2841,13 @@ static int make_raw_rw_request(void)
 		return 0;
 	} else if (raw_cmd->length < current_count_sectors << 9) {
 		DPRINT("more sectors than bytes\n");
-		printk("bytes=%ld\n", raw_cmd->length >> 9);
-		printk("sectors=%ld\n", current_count_sectors);
+		pr_info("bytes=%ld\n", raw_cmd->length >> 9);
+		pr_info("sectors=%ld\n", current_count_sectors);
 	}
 	if (raw_cmd->length == 0) {
 		DPRINT("zero dma transfer attempted from make_raw_request\n");
 		return 0;
 	}
-#endif
 
 	virtualdmabug_workaround();
 	return 2;
@@ -2899,7 +2855,6 @@ static int make_raw_rw_request(void)
 
 static void redo_fd_request(void)
 {
-#define REPEAT {request_done(0); continue; }
 	int drive;
 	int tmp;
 
@@ -2907,63 +2862,63 @@ static void redo_fd_request(void)
 	if (current_drive < N_DRIVE)
 		floppy_off(current_drive);
 
-	for (;;) {
-		if (!current_req) {
-			struct request *req;
-
-			spin_lock_irq(floppy_queue->queue_lock);
-			req = blk_fetch_request(floppy_queue);
-			spin_unlock_irq(floppy_queue->queue_lock);
-			if (!req) {
-				do_floppy = NULL;
-				unlock_fdc();
-				return;
-			}
-			current_req = req;
-		}
-		drive = (long)current_req->rq_disk->private_data;
-		set_fdc(drive);
-		reschedule_timeout(current_reqD, "redo fd request", 0);
+do_request:
+	if (!current_req) {
+		struct request *req;
 
-		set_floppy(drive);
-		raw_cmd = &default_raw_cmd;
-		raw_cmd->flags = 0;
-		if (start_motor(redo_fd_request))
+		spin_lock_irq(floppy_queue->queue_lock);
+		req = blk_fetch_request(floppy_queue);
+		spin_unlock_irq(floppy_queue->queue_lock);
+		if (!req) {
+			do_floppy = NULL;
+			unlock_fdc();
 			return;
-		disk_change(current_drive);
-		if (test_bit(current_drive, &fake_change) ||
-		    TESTF(FD_DISK_CHANGED)) {
-			DPRINT("disk absent or changed during operation\n");
-			REPEAT;
-		}
-		if (!_floppy) {	/* Autodetection */
-			if (!probing) {
-				DRS->probed_format = 0;
-				if (next_valid_format()) {
-					DPRINT("no autodetectable formats\n");
-					_floppy = NULL;
-					REPEAT;
-				}
-			}
-			probing = 1;
-			_floppy =
-			    floppy_type + DP->autodetect[DRS->probed_format];
-		} else
-			probing = 0;
-		errors = &(current_req->errors);
-		tmp = make_raw_rw_request();
-		if (tmp < 2) {
-			request_done(tmp);
-			continue;
 		}
+		current_req = req;
+	}
+	drive = (long)current_req->rq_disk->private_data;
+	set_fdc(drive);
+	reschedule_timeout(current_reqD, "redo fd request");
 
-		if (TESTF(FD_NEED_TWADDLE))
-			twaddle();
-		schedule_bh(floppy_start);
-		debugt("queue fd request");
+	set_floppy(drive);
+	raw_cmd = &default_raw_cmd;
+	raw_cmd->flags = 0;
+	if (start_motor(redo_fd_request))
 		return;
+
+	disk_change(current_drive);
+	if (test_bit(current_drive, &fake_change) ||
+	    test_bit(FD_DISK_CHANGED_BIT, &DRS->flags)) {
+		DPRINT("disk absent or changed during operation\n");
+		request_done(0);
+		goto do_request;
 	}
-#undef REPEAT
+	if (!_floppy) {	/* Autodetection */
+		if (!probing) {
+			DRS->probed_format = 0;
+			if (next_valid_format()) {
+				DPRINT("no autodetectable formats\n");
+				_floppy = NULL;
+				request_done(0);
+				goto do_request;
+			}
+		}
+		probing = 1;
+		_floppy = floppy_type + DP->autodetect[DRS->probed_format];
+	} else
+		probing = 0;
+	errors = &(current_req->errors);
+	tmp = make_raw_rw_request();
+	if (tmp < 2) {
+		request_done(tmp);
+		goto do_request;
+	}
+
+	if (test_bit(FD_NEED_TWADDLE_BIT, &DRS->flags))
+		twaddle();
+	schedule_bh(floppy_start);
+	debugt(__func__, "queue fd request");
+	return;
 }
 
 static struct cont_t rw_cont = {
@@ -2979,30 +2934,30 @@ static void process_fd_request(void)
 	schedule_bh(redo_fd_request);
 }
 
-static void do_fd_request(struct request_queue * q)
+static void do_fd_request(struct request_queue *q)
 {
 	if (max_buffer_sectors == 0) {
-		printk("VFS: do_fd_request called on non-open device\n");
+		pr_info("VFS: %s called on non-open device\n", __func__);
 		return;
 	}
 
 	if (usage_count == 0) {
-		printk("warning: usage count=0, current_req=%p exiting\n",
-		       current_req);
-		printk("sect=%ld type=%x flags=%x\n",
-		       (long)blk_rq_pos(current_req), current_req->cmd_type,
-		       current_req->cmd_flags);
+		pr_info("warning: usage count=0, current_req=%p exiting\n",
+			current_req);
+		pr_info("sect=%ld type=%x flags=%x\n",
+			(long)blk_rq_pos(current_req), current_req->cmd_type,
+			current_req->cmd_flags);
 		return;
 	}
 	if (test_bit(0, &fdc_busy)) {
 		/* fdc busy, this new request will be treated when the
 		   current one is done */
-		is_alive("do fd request, old request running");
+		is_alive(__func__, "old request running");
 		return;
 	}
-	lock_fdc(MAXTIMEOUT, 0);
+	lock_fdc(MAXTIMEOUT, false);
 	process_fd_request();
-	is_alive("do fd request");
+	is_alive(__func__, "");
 }
 
 static struct cont_t poll_cont = {
@@ -3012,24 +2967,18 @@ static struct cont_t poll_cont = {
 	.done		= generic_done
 };
 
-static int poll_drive(int interruptible, int flag)
+static int poll_drive(bool interruptible, int flag)
 {
-	int ret;
-
 	/* no auto-sense, just clear dcl */
 	raw_cmd = &default_raw_cmd;
 	raw_cmd->flags = flag;
 	raw_cmd->track = 0;
 	raw_cmd->cmd_count = 0;
 	cont = &poll_cont;
-#ifdef DCL_DEBUG
-	if (DP->flags & FD_DEBUG) {
-		DPRINT("setting NEWCHANGE in poll_drive\n");
-	}
-#endif
-	SETF(FD_DISK_NEWCHANGE);
-	WAIT(floppy_ready);
-	return ret;
+	debug_dcl(DP->flags, "setting NEWCHANGE in poll_drive\n");
+	set_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags);
+
+	return wait_til_done(floppy_ready, interruptible);
 }
 
 /*
@@ -3039,7 +2988,7 @@ static int poll_drive(int interruptible,
 
 static void reset_intr(void)
 {
-	printk("weird, reset interrupt called\n");
+	pr_info("weird, reset interrupt called\n");
 }
 
 static struct cont_t reset_cont = {
@@ -3049,20 +2998,23 @@ static struct cont_t reset_cont = {
 	.done		= generic_done
 };
 
-static int user_reset_fdc(int drive, int arg, int interruptible)
+static int user_reset_fdc(int drive, int arg, bool interruptible)
 {
 	int ret;
 
-	ret = 0;
-	LOCK_FDC(drive, interruptible);
+	if (lock_fdc(drive, interruptible))
+		return -EINTR;
+
 	if (arg == FD_RESET_ALWAYS)
 		FDCS->reset = 1;
 	if (FDCS->reset) {
 		cont = &reset_cont;
-		WAIT(reset_fdc);
+		ret = wait_til_done(reset_fdc, interruptible);
+		if (ret == -EINTR)
+			return -EINTR;
 	}
 	process_fd_request();
-	return ret;
+	return 0;
 }
 
 /*
@@ -3075,17 +3027,12 @@ static inline int fd_copyout(void __user
 	return copy_to_user(param, address, size) ? -EFAULT : 0;
 }
 
-static inline int fd_copyin(void __user *param, void *address, unsigned long size)
+static inline int fd_copyin(void __user *param, void *address,
+			    unsigned long size)
 {
 	return copy_from_user(address, param, size) ? -EFAULT : 0;
 }
 
-#define _COPYOUT(x) (copy_to_user((void __user *)param, &(x), sizeof(x)) ? -EFAULT : 0)
-#define _COPYIN(x) (copy_from_user(&(x), (void __user *)param, sizeof(x)) ? -EFAULT : 0)
-
-#define COPYOUT(x) ECALL(_COPYOUT(x))
-#define COPYIN(x) ECALL(_COPYIN(x))
-
 static inline const char *drive_name(int type, int drive)
 {
 	struct floppy_struct *floppy;
@@ -3156,23 +3103,29 @@ static struct cont_t raw_cmd_cont = {
 	.done		= raw_cmd_done
 };
 
-static inline int raw_cmd_copyout(int cmd, char __user *param,
+static inline int raw_cmd_copyout(int cmd, void __user *param,
 				  struct floppy_raw_cmd *ptr)
 {
 	int ret;
 
 	while (ptr) {
-		COPYOUT(*ptr);
+		ret = copy_to_user(param, ptr, sizeof(*ptr));
+		if (ret)
+			return -EFAULT;
 		param += sizeof(struct floppy_raw_cmd);
 		if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length) {
-			if (ptr->length >= 0
-			    && ptr->length <= ptr->buffer_length)
-				ECALL(fd_copyout
-				      (ptr->data, ptr->kernel_data,
-				       ptr->buffer_length - ptr->length));
+			if (ptr->length >= 0 &&
+			    ptr->length <= ptr->buffer_length) {
+				long length = ptr->buffer_length - ptr->length;
+				ret = fd_copyout(ptr->data, ptr->kernel_data,
+						 length);
+				if (ret)
+					return ret;
+			}
 		}
 		ptr = ptr->next;
 	}
+
 	return 0;
 }
 
@@ -3195,7 +3148,7 @@ static void raw_cmd_free(struct floppy_r
 	}
 }
 
-static inline int raw_cmd_copyin(int cmd, char __user *param,
+static inline int raw_cmd_copyin(int cmd, void __user *param,
 				 struct floppy_raw_cmd **rcmd)
 {
 	struct floppy_raw_cmd *ptr;
@@ -3203,17 +3156,19 @@ static inline int raw_cmd_copyin(int cmd
 	int i;
 
 	*rcmd = NULL;
-	while (1) {
-		ptr = (struct floppy_raw_cmd *)
-		    kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER);
-		if (!ptr)
-			return -ENOMEM;
-		*rcmd = ptr;
-		COPYIN(*ptr);
-		ptr->next = NULL;
-		ptr->buffer_length = 0;
-		param += sizeof(struct floppy_raw_cmd);
-		if (ptr->cmd_count > 33)
+
+loop:
+	ptr = kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER);
+	if (!ptr)
+		return -ENOMEM;
+	*rcmd = ptr;
+	ret = copy_from_user(ptr, param, sizeof(*ptr));
+	if (ret)
+		return -EFAULT;
+	ptr->next = NULL;
+	ptr->buffer_length = 0;
+	param += sizeof(struct floppy_raw_cmd);
+	if (ptr->cmd_count > 33)
 			/* the command may now also take up the space
 			 * initially intended for the reply & the
 			 * reply count. Needed for long 82078 commands
@@ -3222,31 +3177,35 @@ static inline int raw_cmd_copyin(int cmd
 			 * 16 bytes for a structure, you'll one day
 			 * discover that you really need 17...
 			 */
-			return -EINVAL;
+		return -EINVAL;
 
-		for (i = 0; i < 16; i++)
-			ptr->reply[i] = 0;
-		ptr->resultcode = 0;
-		ptr->kernel_data = NULL;
+	for (i = 0; i < 16; i++)
+		ptr->reply[i] = 0;
+	ptr->resultcode = 0;
+	ptr->kernel_data = NULL;
 
-		if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
-			if (ptr->length <= 0)
-				return -EINVAL;
-			ptr->kernel_data =
-			    (char *)fd_dma_mem_alloc(ptr->length);
-			fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length);
-			if (!ptr->kernel_data)
-				return -ENOMEM;
-			ptr->buffer_length = ptr->length;
-		}
-		if (ptr->flags & FD_RAW_WRITE)
-			ECALL(fd_copyin(ptr->data, ptr->kernel_data,
-					ptr->length));
+	if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
+		if (ptr->length <= 0)
+			return -EINVAL;
+		ptr->kernel_data = (char *)fd_dma_mem_alloc(ptr->length);
+		fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length);
+		if (!ptr->kernel_data)
+			return -ENOMEM;
+		ptr->buffer_length = ptr->length;
+	}
+	if (ptr->flags & FD_RAW_WRITE) {
+		ret = fd_copyin(ptr->data, ptr->kernel_data, ptr->length);
+		if (ret)
+			return ret;
+	}
+
+	if (ptr->flags & FD_RAW_MORE) {
 		rcmd = &(ptr->next);
-		if (!(ptr->flags & FD_RAW_MORE))
-			return 0;
 		ptr->rate &= 0x43;
+		goto loop;
 	}
+
+	return 0;
 }
 
 static int raw_cmd_ioctl(int cmd, void __user *param)
@@ -3283,12 +3242,8 @@ static int raw_cmd_ioctl(int cmd, void _
 
 	raw_cmd = my_raw_cmd;
 	cont = &raw_cmd_cont;
-	ret = wait_til_done(floppy_start, 1);
-#ifdef DCL_DEBUG
-	if (DP->flags & FD_DEBUG) {
-		DPRINT("calling disk change from raw_cmd ioctl\n");
-	}
-#endif
+	ret = wait_til_done(floppy_start, true);
+	debug_dcl(DP->flags, "calling disk change from raw_cmd ioctl\n");
 
 	if (ret != -EINTR && FDCS->reset)
 		ret = -EIO;
@@ -3327,7 +3282,7 @@ static inline int set_geometry(unsigned
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		mutex_lock(&open_lock);
-		if (lock_fdc(drive, 1)) {
+		if (lock_fdc(drive, true)) {
 			mutex_unlock(&open_lock);
 			return -EINTR;
 		}
@@ -3346,11 +3301,15 @@ static inline int set_geometry(unsigned
 		mutex_unlock(&open_lock);
 	} else {
 		int oldStretch;
-		LOCK_FDC(drive, 1);
-		if (cmd != FDDEFPRM)
+
+		if (lock_fdc(drive, true))
+			return -EINTR;
+		if (cmd != FDDEFPRM) {
 			/* notice a disk change immediately, else
 			 * we lose our settings immediately*/
-			CALL(poll_drive(1, FD_RAW_NEED_DISK));
+			if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR)
+				return -EINTR;
+		}
 		oldStretch = g->stretch;
 		user_params[drive] = *g;
 		if (buffer_drive == drive)
@@ -3415,7 +3374,7 @@ static inline int normalize_ioctl(int *c
 			*size = _IOC_SIZE(*cmd);
 			*cmd = ioctl_table[i];
 			if (*size > _IOC_SIZE(*cmd)) {
-				printk("ioctl not yet supported\n");
+				pr_info("ioctl not yet supported\n");
 				return -EFAULT;
 			}
 			return 0;
@@ -3429,8 +3388,10 @@ static int get_floppy_geometry(int drive
 	if (type)
 		*g = &floppy_type[type];
 	else {
-		LOCK_FDC(drive, 0);
-		CALL(poll_drive(0, 0));
+		if (lock_fdc(drive, false))
+			return -EINTR;
+		if (poll_drive(false, 0) == -EINTR)
+			return -EINTR;
 		process_fd_request();
 		*g = current_type[drive];
 	}
@@ -3459,10 +3420,6 @@ static int fd_getgeo(struct block_device
 static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
 		    unsigned long param)
 {
-#define FD_IOCTL_ALLOWED (mode & (FMODE_WRITE|FMODE_WRITE_IOCTL))
-#define OUT(c,x) case c: outparam = (const char *) (x); break
-#define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0
-
 	int drive = (long)bdev->bd_disk->private_data;
 	int type = ITYPE(UDRS->fd_device);
 	int i;
@@ -3474,26 +3431,28 @@ static int fd_ioctl(struct block_device
 		struct floppy_max_errors max_errors;
 		struct floppy_drive_params dp;
 	} inparam;		/* parameters coming from user space */
-	const char *outparam;	/* parameters passed back to user space */
+	const void *outparam;	/* parameters passed back to user space */
 
 	/* convert compatibility eject ioctls into floppy eject ioctl.
 	 * We do this in order to provide a means to eject floppy disks before
 	 * installing the new fdutils package */
 	if (cmd == CDROMEJECT ||	/* CD-ROM eject */
-	    cmd == 0x6470 /* SunOS floppy eject */ ) {
+	    cmd == 0x6470) {		/* SunOS floppy eject */
 		DPRINT("obsolete eject ioctl\n");
 		DPRINT("please use floppycontrol --eject\n");
 		cmd = FDEJECT;
 	}
 
-	/* convert the old style command into a new style command */
-	if ((cmd & 0xff00) == 0x0200) {
-		ECALL(normalize_ioctl(&cmd, &size));
-	} else
+	if (!((cmd & 0xff00) == 0x0200))
 		return -EINVAL;
 
+	/* convert the old style command into a new style command */
+	ret = normalize_ioctl(&cmd, &size);
+	if (ret)
+		return ret;
+
 	/* permission checks */
-	if (((cmd & 0x40) && !FD_IOCTL_ALLOWED) ||
+	if (((cmd & 0x40) && !(mode & (FMODE_WRITE | FMODE_WRITE_IOCTL))) ||
 	    ((cmd & 0x80) && !capable(CAP_SYS_ADMIN)))
 		return -EPERM;
 
@@ -3501,129 +3460,142 @@ static int fd_ioctl(struct block_device
 		return -EINVAL;
 
 	/* copyin */
-	CLEARSTRUCT(&inparam);
-	if (_IOC_DIR(cmd) & _IOC_WRITE)
-	    ECALL(fd_copyin((void __user *)param, &inparam, size))
-
-		switch (cmd) {
-		case FDEJECT:
-			if (UDRS->fd_ref != 1)
-				/* somebody else has this drive open */
-				return -EBUSY;
-			LOCK_FDC(drive, 1);
-
-			/* do the actual eject. Fails on
-			 * non-Sparc architectures */
-			ret = fd_eject(UNIT(drive));
-
-			USETF(FD_DISK_CHANGED);
-			USETF(FD_VERIFY);
-			process_fd_request();
+	memset(&inparam, 0, sizeof(inparam));
+	if (_IOC_DIR(cmd) & _IOC_WRITE) {
+		ret = fd_copyin((void __user *)param, &inparam, size);
+		if (ret)
 			return ret;
-		case FDCLRPRM:
-			LOCK_FDC(drive, 1);
-			current_type[drive] = NULL;
-			floppy_sizes[drive] = MAX_DISK_SIZE << 1;
-			UDRS->keep_data = 0;
-			return invalidate_drive(bdev);
-		case FDSETPRM:
-		case FDDEFPRM:
-			return set_geometry(cmd, &inparam.g,
-					    drive, type, bdev);
-		case FDGETPRM:
-			ECALL(get_floppy_geometry(drive, type,
-						  (struct floppy_struct **)
-						  &outparam));
-			break;
-
-		case FDMSGON:
-			UDP->flags |= FTD_MSG;
-			return 0;
-		case FDMSGOFF:
-			UDP->flags &= ~FTD_MSG;
-			return 0;
-
-		case FDFMTBEG:
-			LOCK_FDC(drive, 1);
-			CALL(poll_drive(1, FD_RAW_NEED_DISK));
-			ret = UDRS->flags;
-			process_fd_request();
-			if (ret & FD_VERIFY)
-				return -ENODEV;
-			if (!(ret & FD_DISK_WRITABLE))
-				return -EROFS;
-			return 0;
-		case FDFMTTRK:
-			if (UDRS->fd_ref != 1)
-				return -EBUSY;
-			return do_format(drive, &inparam.f);
-		case FDFMTEND:
-		case FDFLUSH:
-			LOCK_FDC(drive, 1);
-			return invalidate_drive(bdev);
-
-		case FDSETEMSGTRESH:
-			UDP->max_errors.reporting =
-			    (unsigned short)(param & 0x0f);
-			return 0;
-			OUT(FDGETMAXERRS, &UDP->max_errors);
-			IN(FDSETMAXERRS, &UDP->max_errors, max_errors);
-
-		case FDGETDRVTYP:
-			outparam = drive_name(type, drive);
-			SUPBOUND(size, strlen(outparam) + 1);
-			break;
-
-			IN(FDSETDRVPRM, UDP, dp);
-			OUT(FDGETDRVPRM, UDP);
-
-		case FDPOLLDRVSTAT:
-			LOCK_FDC(drive, 1);
-			CALL(poll_drive(1, FD_RAW_NEED_DISK));
-			process_fd_request();
-			/* fall through */
-			OUT(FDGETDRVSTAT, UDRS);
-
-		case FDRESET:
-			return user_reset_fdc(drive, (int)param, 1);
-
-			OUT(FDGETFDCSTAT, UFDCS);
-
-		case FDWERRORCLR:
-			CLEARSTRUCT(UDRWE);
-			return 0;
-			OUT(FDWERRORGET, UDRWE);
+	}
 
-		case FDRAWCMD:
-			if (type)
-				return -EINVAL;
-			LOCK_FDC(drive, 1);
-			set_floppy(drive);
-			CALL(i = raw_cmd_ioctl(cmd, (void __user *)param));
-			process_fd_request();
-			return i;
+	switch (cmd) {
+	case FDEJECT:
+		if (UDRS->fd_ref != 1)
+			/* somebody else has this drive open */
+			return -EBUSY;
+		if (lock_fdc(drive, true))
+			return -EINTR;
 
-		case FDTWADDLE:
-			LOCK_FDC(drive, 1);
-			twaddle();
-			process_fd_request();
-			return 0;
+		/* do the actual eject. Fails on
+		 * non-Sparc architectures */
+		ret = fd_eject(UNIT(drive));
 
-		default:
+		set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
+		set_bit(FD_VERIFY_BIT, &UDRS->flags);
+		process_fd_request();
+		return ret;
+	case FDCLRPRM:
+		if (lock_fdc(drive, true))
+			return -EINTR;
+		current_type[drive] = NULL;
+		floppy_sizes[drive] = MAX_DISK_SIZE << 1;
+		UDRS->keep_data = 0;
+		return invalidate_drive(bdev);
+	case FDSETPRM:
+	case FDDEFPRM:
+		return set_geometry(cmd, &inparam.g, drive, type, bdev);
+	case FDGETPRM:
+		ret = get_floppy_geometry(drive, type,
+					  (struct floppy_struct **)&outparam);
+		if (ret)
+			return ret;
+		break;
+	case FDMSGON:
+		UDP->flags |= FTD_MSG;
+		return 0;
+	case FDMSGOFF:
+		UDP->flags &= ~FTD_MSG;
+		return 0;
+	case FDFMTBEG:
+		if (lock_fdc(drive, true))
+			return -EINTR;
+		if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR)
+			return -EINTR;
+		ret = UDRS->flags;
+		process_fd_request();
+		if (ret & FD_VERIFY)
+			return -ENODEV;
+		if (!(ret & FD_DISK_WRITABLE))
+			return -EROFS;
+		return 0;
+	case FDFMTTRK:
+		if (UDRS->fd_ref != 1)
+			return -EBUSY;
+		return do_format(drive, &inparam.f);
+	case FDFMTEND:
+	case FDFLUSH:
+		if (lock_fdc(drive, true))
+			return -EINTR;
+		return invalidate_drive(bdev);
+	case FDSETEMSGTRESH:
+		UDP->max_errors.reporting = (unsigned short)(param & 0x0f);
+		return 0;
+	case FDGETMAXERRS:
+		outparam = &UDP->max_errors;
+		break;
+	case FDSETMAXERRS:
+		UDP->max_errors = inparam.max_errors;
+		break;
+	case FDGETDRVTYP:
+		outparam = drive_name(type, drive);
+		SUPBOUND(size, strlen((const char *)outparam) + 1);
+		break;
+	case FDSETDRVPRM:
+		*UDP = inparam.dp;
+		break;
+	case FDGETDRVPRM:
+		outparam = UDP;
+		break;
+	case FDPOLLDRVSTAT:
+		if (lock_fdc(drive, true))
+			return -EINTR;
+		if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR)
+			return -EINTR;
+		process_fd_request();
+		/* fall through */
+	case FDGETDRVSTAT:
+		outparam = UDRS;
+		break;
+	case FDRESET:
+		return user_reset_fdc(drive, (int)param, true);
+	case FDGETFDCSTAT:
+		outparam = UFDCS;
+		break;
+	case FDWERRORCLR:
+		memset(UDRWE, 0, sizeof(*UDRWE));
+		return 0;
+	case FDWERRORGET:
+		outparam = UDRWE;
+		break;
+	case FDRAWCMD:
+		if (type)
 			return -EINVAL;
-		}
+		if (lock_fdc(drive, true))
+			return -EINTR;
+		set_floppy(drive);
+		i = raw_cmd_ioctl(cmd, (void __user *)param);
+		if (i == -EINTR)
+			return -EINTR;
+		process_fd_request();
+		return i;
+	case FDTWADDLE:
+		if (lock_fdc(drive, true))
+			return -EINTR;
+		twaddle();
+		process_fd_request();
+		return 0;
+	default:
+		return -EINVAL;
+	}
 
 	if (_IOC_DIR(cmd) & _IOC_READ)
 		return fd_copyout((void __user *)param, outparam, size);
-	else
-		return 0;
-#undef OUT
-#undef IN
+
+	return 0;
 }
 
 static void __init config_types(void)
 {
-	int first = 1;
+	bool has_drive = false;
 	int drive;
 
 	/* read drive info out of physical CMOS */
@@ -3655,17 +3627,22 @@ static void __init config_types(void)
 			name = temparea;
 		}
 		if (name) {
-			const char *prepend = ",";
-			if (first) {
-				prepend = KERN_INFO "Floppy drive(s):";
-				first = 0;
+			const char *prepend;
+			if (!has_drive) {
+				prepend = "";
+				has_drive = true;
+				pr_info("Floppy drive(s):");
+			} else {
+				prepend = ",";
 			}
-			printk("%s fd%d is %s", prepend, drive, name);
+
+			pr_cont("%s fd%d is %s", prepend, drive, name);
 		}
 		*UDP = *params;
 	}
-	if (!first)
-		printk("\n");
+
+	if (has_drive)
+		pr_cont("\n");
 }
 
 static int floppy_release(struct gendisk *disk, fmode_t mode)
@@ -3705,8 +3682,8 @@ static int floppy_open(struct block_devi
 		goto out2;
 
 	if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)) {
-		USETF(FD_DISK_CHANGED);
-		USETF(FD_VERIFY);
+		set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
+		set_bit(FD_VERIFY_BIT, &UDRS->flags);
 	}
 
 	if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (mode & FMODE_EXCL)))
@@ -3735,9 +3712,8 @@ static int floppy_open(struct block_devi
 			INFBOUND(try, 16);
 			tmp = (char *)fd_dma_mem_alloc(1024 * try);
 		}
-		if (!tmp && !floppy_track_buffer) {
+		if (!tmp && !floppy_track_buffer)
 			fallback_on_nodma_alloc(&tmp, 2048 * try);
-		}
 		if (!tmp && !floppy_track_buffer) {
 			DPRINT("Unable to allocate DMA memory\n");
 			goto out;
@@ -3767,11 +3743,12 @@ static int floppy_open(struct block_devi
 		if (mode & (FMODE_READ|FMODE_WRITE)) {
 			UDRS->last_checked = 0;
 			check_disk_change(bdev);
-			if (UTESTF(FD_DISK_CHANGED))
+			if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags))
 				goto out;
 		}
 		res = -EROFS;
-		if ((mode & FMODE_WRITE) && !(UTESTF(FD_DISK_WRITABLE)))
+		if ((mode & FMODE_WRITE) &&
+		    !test_bit(FD_DISK_WRITABLE_BIT, &UDRS->flags))
 			goto out;
 	}
 	mutex_unlock(&open_lock);
@@ -3795,17 +3772,18 @@ static int check_floppy_change(struct ge
 {
 	int drive = (long)disk->private_data;
 
-	if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY))
+	if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) ||
+	    test_bit(FD_VERIFY_BIT, &UDRS->flags))
 		return 1;
 
 	if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) {
-		lock_fdc(drive, 0);
-		poll_drive(0, 0);
+		lock_fdc(drive, false);
+		poll_drive(false, 0);
 		process_fd_request();
 	}
 
-	if (UTESTF(FD_DISK_CHANGED) ||
-	    UTESTF(FD_VERIFY) ||
+	if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) ||
+	    test_bit(FD_VERIFY_BIT, &UDRS->flags) ||
 	    test_bit(drive, &fake_change) ||
 	    (!ITYPE(UDRS->fd_device) && !current_type[drive]))
 		return 1;
@@ -3818,8 +3796,7 @@ static int check_floppy_change(struct ge
  * a disk in the drive, and whether that disk is writable.
  */
 
-static void floppy_rb0_complete(struct bio *bio,
-			       int err)
+static void floppy_rb0_complete(struct bio *bio, int err)
 {
 	complete((struct completion *)bio->bi_private);
 }
@@ -3877,14 +3854,16 @@ static int floppy_revalidate(struct gend
 	int cf;
 	int res = 0;
 
-	if (UTESTF(FD_DISK_CHANGED) ||
-	    UTESTF(FD_VERIFY) || test_bit(drive, &fake_change) || NO_GEOM) {
+	if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) ||
+	    test_bit(FD_VERIFY_BIT, &UDRS->flags) ||
+	    test_bit(drive, &fake_change) || NO_GEOM) {
 		if (usage_count == 0) {
-			printk("VFS: revalidate called on non-open device.\n");
+			pr_info("VFS: revalidate called on non-open device.\n");
 			return -EFAULT;
 		}
-		lock_fdc(drive, 0);
-		cf = UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY);
+		lock_fdc(drive, false);
+		cf = (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) ||
+		      test_bit(FD_VERIFY_BIT, &UDRS->flags));
 		if (!(cf || test_bit(drive, &fake_change) || NO_GEOM)) {
 			process_fd_request();	/*already done by another thread */
 			return 0;
@@ -3894,7 +3873,7 @@ static int floppy_revalidate(struct gend
 		if (buffer_drive == drive)
 			buffer_track = -1;
 		clear_bit(drive, &fake_change);
-		UCLEARF(FD_DISK_CHANGED);
+		clear_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
 		if (cf)
 			UDRS->generation++;
 		if (NO_GEOM) {
@@ -3902,7 +3881,7 @@ static int floppy_revalidate(struct gend
 			res = __floppy_read_block_0(opened_bdev[drive]);
 		} else {
 			if (cf)
-				poll_drive(0, FD_RAW_NEED_DISK);
+				poll_drive(false, FD_RAW_NEED_DISK);
 			process_fd_request();
 		}
 	}
@@ -3934,21 +3913,21 @@ static char __init get_fdc_version(void)
 	output_byte(FD_DUMPREGS);	/* 82072 and better know DUMPREGS */
 	if (FDCS->reset)
 		return FDC_NONE;
-	if ((r = result()) <= 0x00)
+	r = result();
+	if (r <= 0x00)
 		return FDC_NONE;	/* No FDC present ??? */
 	if ((r == 1) && (reply_buffer[0] == 0x80)) {
-		printk(KERN_INFO "FDC %d is an 8272A\n", fdc);
+		pr_info("FDC %d is an 8272A\n", fdc);
 		return FDC_8272A;	/* 8272a/765 don't know DUMPREGS */
 	}
 	if (r != 10) {
-		printk
-		    ("FDC %d init: DUMPREGS: unexpected return of %d bytes.\n",
-		     fdc, r);
+		pr_info("FDC %d init: DUMPREGS: unexpected return of %d bytes.\n",
+			fdc, r);
 		return FDC_UNKNOWN;
 	}
 
 	if (!fdc_configure()) {
-		printk(KERN_INFO "FDC %d is an 82072\n", fdc);
+		pr_info("FDC %d is an 82072\n", fdc);
 		return FDC_82072;	/* 82072 doesn't know CONFIGURE */
 	}
 
@@ -3956,52 +3935,50 @@ static char __init get_fdc_version(void)
 	if (need_more_output() == MORE_OUTPUT) {
 		output_byte(0);
 	} else {
-		printk(KERN_INFO "FDC %d is an 82072A\n", fdc);
+		pr_info("FDC %d is an 82072A\n", fdc);
 		return FDC_82072A;	/* 82072A as found on Sparcs. */
 	}
 
 	output_byte(FD_UNLOCK);
 	r = result();
 	if ((r == 1) && (reply_buffer[0] == 0x80)) {
-		printk(KERN_INFO "FDC %d is a pre-1991 82077\n", fdc);
-		return FDC_82077_ORIG;	/* Pre-1991 82077, doesn't know 
+		pr_info("FDC %d is a pre-1991 82077\n", fdc);
+		return FDC_82077_ORIG;	/* Pre-1991 82077, doesn't know
 					 * LOCK/UNLOCK */
 	}
 	if ((r != 1) || (reply_buffer[0] != 0x00)) {
-		printk("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
-		       fdc, r);
+		pr_info("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
+			fdc, r);
 		return FDC_UNKNOWN;
 	}
 	output_byte(FD_PARTID);
 	r = result();
 	if (r != 1) {
-		printk("FDC %d init: PARTID: unexpected return of %d bytes.\n",
-		       fdc, r);
+		pr_info("FDC %d init: PARTID: unexpected return of %d bytes.\n",
+			fdc, r);
 		return FDC_UNKNOWN;
 	}
 	if (reply_buffer[0] == 0x80) {
-		printk(KERN_INFO "FDC %d is a post-1991 82077\n", fdc);
+		pr_info("FDC %d is a post-1991 82077\n", fdc);
 		return FDC_82077;	/* Revised 82077AA passes all the tests */
 	}
 	switch (reply_buffer[0] >> 5) {
 	case 0x0:
 		/* Either a 82078-1 or a 82078SL running at 5Volt */
-		printk(KERN_INFO "FDC %d is an 82078.\n", fdc);
+		pr_info("FDC %d is an 82078.\n", fdc);
 		return FDC_82078;
 	case 0x1:
-		printk(KERN_INFO "FDC %d is a 44pin 82078\n", fdc);
+		pr_info("FDC %d is a 44pin 82078\n", fdc);
 		return FDC_82078;
 	case 0x2:
-		printk(KERN_INFO "FDC %d is a S82078B\n", fdc);
+		pr_info("FDC %d is a S82078B\n", fdc);
 		return FDC_S82078B;
 	case 0x3:
-		printk(KERN_INFO "FDC %d is a National Semiconductor PC87306\n",
-		       fdc);
+		pr_info("FDC %d is a National Semiconductor PC87306\n", fdc);
 		return FDC_87306;
 	default:
-		printk(KERN_INFO
-		       "FDC %d init: 82078 variant with unknown PARTID=%d.\n",
-		       fdc, reply_buffer[0] >> 5);
+		pr_info("FDC %d init: 82078 variant with unknown PARTID=%d.\n",
+			fdc, reply_buffer[0] >> 5);
 		return FDC_82078_UNKN;
 	}
 }				/* get_fdc_version */
@@ -4113,9 +4090,9 @@ static int __init floppy_setup(char *str
 				else
 					param = config_params[i].def_param;
 				if (config_params[i].fn)
-					config_params[i].
-					    fn(ints, param,
-					       config_params[i].param2);
+					config_params[i].fn(ints, param,
+							    config_params[i].
+							    param2);
 				if (config_params[i].var) {
 					DPRINT("%s=%d\n", str, param);
 					*config_params[i].var = param;
@@ -4129,8 +4106,8 @@ static int __init floppy_setup(char *str
 
 		DPRINT("allowed options are:");
 		for (i = 0; i < ARRAY_SIZE(config_params); i++)
-			printk(" %s", config_params[i].name);
-		printk("\n");
+			pr_cont(" %s", config_params[i].name);
+		pr_cont("\n");
 	} else
 		DPRINT("botched floppy option\n");
 	DPRINT("Read Documentation/blockdev/floppy.txt\n");
@@ -4148,7 +4125,8 @@ static ssize_t floppy_cmos_show(struct d
 	drive = p->id;
 	return sprintf(buf, "%X\n", UDP->cmos);
 }
-DEVICE_ATTR(cmos,S_IRUGO,floppy_cmos_show,NULL);
+
+DEVICE_ATTR(cmos, S_IRUGO, floppy_cmos_show, NULL);
 
 static void floppy_device_release(struct device *dev)
 {
@@ -4160,7 +4138,7 @@ static int floppy_resume(struct device *
 
 	for (fdc = 0; fdc < N_FDC; fdc++)
 		if (FDCS->address != -1)
-			user_reset_fdc(-1, FD_RESET_ALWAYS, 0);
+			user_reset_fdc(-1, FD_RESET_ALWAYS, false);
 
 	return 0;
 }
@@ -4172,8 +4150,8 @@ static const struct dev_pm_ops floppy_pm
 
 static struct platform_driver floppy_driver = {
 	.driver = {
-		.name = "floppy",
-		.pm = &floppy_pm_ops,
+		   .name = "floppy",
+		   .pm = &floppy_pm_ops,
 	},
 };
 
@@ -4234,7 +4212,7 @@ static int __init floppy_init(void)
 		err = -ENOMEM;
 		goto out_unreg_driver;
 	}
-	blk_queue_max_sectors(floppy_queue, 64);
+	blk_queue_max_hw_sectors(floppy_queue, 64);
 
 	blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
 			    floppy_find, NULL, NULL);
@@ -4245,16 +4223,16 @@ static int __init floppy_init(void)
 		else
 			floppy_sizes[i] = MAX_DISK_SIZE << 1;
 
-	reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT);
+	reschedule_timeout(MAXTIMEOUT, "floppy init");
 	config_types();
 
 	for (i = 0; i < N_FDC; i++) {
 		fdc = i;
-		CLEARSTRUCT(FDCS);
+		memset(FDCS, 0, sizeof(*FDCS));
 		FDCS->dtr = -1;
 		FDCS->dor = 0x4;
 #if defined(__sparc__) || defined(__mc68000__)
-		/*sparcs/sun3x don't have a DOR reset which we can fall back on to */
+	/*sparcs/sun3x don't have a DOR reset which we can fall back on to */
 #ifdef __mc68000__
 		if (MACH_IS_SUN3X)
 #endif
@@ -4283,11 +4261,11 @@ static int __init floppy_init(void)
 
 	/* initialise drive state */
 	for (drive = 0; drive < N_DRIVE; drive++) {
-		CLEARSTRUCT(UDRS);
-		CLEARSTRUCT(UDRWE);
-		USETF(FD_DISK_NEWCHANGE);
-		USETF(FD_DISK_CHANGED);
-		USETF(FD_VERIFY);
+		memset(UDRS, 0, sizeof(*UDRS));
+		memset(UDRWE, 0, sizeof(*UDRWE));
+		set_bit(FD_DISK_NEWCHANGE_BIT, &UDRS->flags);
+		set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
+		set_bit(FD_VERIFY_BIT, &UDRS->flags);
 		UDRS->fd_device = -1;
 		floppy_track_buffer = NULL;
 		max_buffer_sectors = 0;
@@ -4307,7 +4285,7 @@ static int __init floppy_init(void)
 		if (FDCS->address == -1)
 			continue;
 		FDCS->rawcmd = 2;
-		if (user_reset_fdc(-1, FD_RESET_ALWAYS, 0)) {
+		if (user_reset_fdc(-1, FD_RESET_ALWAYS, false)) {
 			/* free ioports reserved by floppy_grab_irq_and_dma() */
 			floppy_release_regions(fdc);
 			FDCS->address = -1;
@@ -4330,12 +4308,12 @@ static int __init floppy_init(void)
 		 * properly, so force a reset for the standard FDC clones,
 		 * to avoid interrupt garbage.
 		 */
-		user_reset_fdc(-1, FD_RESET_ALWAYS, 0);
+		user_reset_fdc(-1, FD_RESET_ALWAYS, false);
 	}
 	fdc = 0;
 	del_timer(&fd_timeout);
 	current_drive = 0;
-	initialising = 0;
+	initialized = true;
 	if (have_no_fdc) {
 		DPRINT("no floppy controllers found\n");
 		err = have_no_fdc;
@@ -4356,7 +4334,8 @@ static int __init floppy_init(void)
 		if (err)
 			goto out_flush_work;
 
-		err = device_create_file(&floppy_device[drive].dev,&dev_attr_cmos);
+		err = device_create_file(&floppy_device[drive].dev,
+					 &dev_attr_cmos);
 		if (err)
 			goto out_unreg_platform_dev;
 
@@ -4420,8 +4399,10 @@ static int floppy_request_regions(int fd
 	const struct io_region *p;
 
 	for (p = io_regions; p < ARRAY_END(io_regions); p++) {
-		if (!request_region(FDCS->address + p->offset, p->size, "floppy")) {
-			DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address + p->offset);
+		if (!request_region(FDCS->address + p->offset,
+				    p->size, "floppy")) {
+			DPRINT("Floppy io-port 0x%04lx in use\n",
+			       FDCS->address + p->offset);
 			floppy_release_allocated_regions(fdc, p);
 			return -EBUSY;
 		}
@@ -4512,11 +4493,9 @@ cleanup:
 static void floppy_release_irq_and_dma(void)
 {
 	int old_fdc;
-#ifdef FLOPPY_SANITY_CHECK
 #ifndef __sparc__
 	int drive;
 #endif
-#endif
 	long tmpsize;
 	unsigned long tmpaddr;
 	unsigned long flags;
@@ -4547,20 +4526,18 @@ static void floppy_release_irq_and_dma(v
 		buffer_min = buffer_max = -1;
 		fd_dma_mem_free(tmpaddr, tmpsize);
 	}
-#ifdef FLOPPY_SANITY_CHECK
 #ifndef __sparc__
 	for (drive = 0; drive < N_FDC * 4; drive++)
 		if (timer_pending(motor_off_timer + drive))
-			printk("motor off timer %d still active\n", drive);
+			pr_info("motor off timer %d still active\n", drive);
 #endif
 
 	if (timer_pending(&fd_timeout))
-		printk("floppy timer still active:%s\n", timeout_message);
+		pr_info("floppy timer still active:%s\n", timeout_message);
 	if (timer_pending(&fd_timer))
-		printk("auxiliary floppy timer still active\n");
+		pr_info("auxiliary floppy timer still active\n");
 	if (work_pending(&floppy_work))
-		printk("work still pending\n");
-#endif
+		pr_info("work still pending\n");
 	old_fdc = fdc;
 	for (fdc = 0; fdc < N_FDC; fdc++)
 		if (FDCS->address != -1)
@@ -4577,7 +4554,9 @@ static void __init parse_floppy_cfg_stri
 	char *ptr;
 
 	while (*cfg) {
-		for (ptr = cfg; *cfg && *cfg != ' ' && *cfg != '\t'; cfg++) ;
+		ptr = cfg;
+		while (*cfg && *cfg != ' ' && *cfg != '\t')
+			cfg++;
 		if (*cfg) {
 			*cfg = '\0';
 			cfg++;
@@ -4625,6 +4604,7 @@ static void __exit floppy_module_exit(vo
 	/* eject disk, if any */
 	fd_eject(0);
 }
+
 module_exit(floppy_module_exit);
 
 module_param(floppy, charp, 0);
@@ -4636,9 +4616,10 @@ MODULE_LICENSE("GPL");
 
 /* This doesn't actually get used other than for module information */
 static const struct pnp_device_id floppy_pnpids[] = {
-	{ "PNP0700", 0 },
-	{ }
+	{"PNP0700", 0},
+	{}
 };
+
 MODULE_DEVICE_TABLE(pnp, floppy_pnpids);
 
 #else
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/hd.c linux-libre-2.6.34-gnu1/drivers/block/hd.c
--- linux-libre-2.6.33-gnu1/drivers/block/hd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/hd.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,6 @@
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/genhd.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
@@ -719,7 +718,7 @@ static int __init hd_init(void)
 		return -ENOMEM;
 	}
 
-	blk_queue_max_sectors(hd_queue, 255);
+	blk_queue_max_hw_sectors(hd_queue, 255);
 	init_timer(&device_timer);
 	device_timer.function = hd_times_out;
 	blk_queue_logical_block_size(hd_queue, 512);
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/loop.c linux-libre-2.6.34-gnu1/drivers/block/loop.c
--- linux-libre-2.6.33-gnu1/drivers/block/loop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/loop.c	2010-05-16 17:17:36.000000000 -0400
@@ -71,7 +71,6 @@
 #include <linux/buffer_head.h>		/* for invalidate_bdev() */
 #include <linux/completion.h>
 #include <linux/highmem.h>
-#include <linux/gfp.h>
 #include <linux/kthread.h>
 #include <linux/splice.h>
 
@@ -238,6 +237,8 @@ static int do_lo_send_aops(struct loop_d
 		if (ret)
 			goto fail;
 
+		file_update_time(file);
+
 		transfer_result = lo_do_transfer(lo, WRITE, page, offset,
 				bvec->bv_page, bv_offs, size, IV);
 		copied = size;
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/mg_disk.c linux-libre-2.6.34-gnu1/drivers/block/mg_disk.c
--- linux-libre-2.6.33-gnu1/drivers/block/mg_disk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/mg_disk.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/mg_disk.h>
+#include <linux/slab.h>
 
 #define MG_RES_SEC (CONFIG_MG_DISK_RES << 1)
 
@@ -980,7 +981,7 @@ static int mg_probe(struct platform_devi
 				__func__, __LINE__);
 		goto probe_err_6;
 	}
-	blk_queue_max_sectors(host->breq, MG_MAX_SECTS);
+	blk_queue_max_hw_sectors(host->breq, MG_MAX_SECTS);
 	blk_queue_logical_block_size(host->breq, MG_SECTOR_SIZE);
 
 	init_timer(&host->timer);
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/nbd.c linux-libre-2.6.34-gnu1/drivers/block/nbd.c
--- linux-libre-2.6.33-gnu1/drivers/block/nbd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/nbd.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/compiler.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <linux/net.h>
 #include <linux/kthread.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/osdblk.c linux-libre-2.6.34-gnu1/drivers/block/osdblk.c
--- linux-libre-2.6.33-gnu1/drivers/block/osdblk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/osdblk.c	2010-05-16 17:17:36.000000000 -0400
@@ -63,6 +63,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <scsi/osd_initiator.h>
 #include <scsi/osd_attributes.h>
 #include <scsi/osd_sec.h>
@@ -476,7 +477,9 @@ static void class_osdblk_release(struct
 	kfree(cls);
 }
 
-static ssize_t class_osdblk_list(struct class *c, char *data)
+static ssize_t class_osdblk_list(struct class *c,
+				struct class_attribute *attr,
+				char *data)
 {
 	int n = 0;
 	struct list_head *tmp;
@@ -500,7 +503,9 @@ static ssize_t class_osdblk_list(struct
 	return n;
 }
 
-static ssize_t class_osdblk_add(struct class *c, const char *buf, size_t count)
+static ssize_t class_osdblk_add(struct class *c,
+				struct class_attribute *attr,
+				const char *buf, size_t count)
 {
 	struct osdblk_device *osdev;
 	ssize_t rc;
@@ -592,7 +597,9 @@ err_out_mod:
 	return rc;
 }
 
-static ssize_t class_osdblk_remove(struct class *c, const char *buf,
+static ssize_t class_osdblk_remove(struct class *c,
+					struct class_attribute *attr,
+					const char *buf,
 					size_t count)
 {
 	struct osdblk_device *osdev = NULL;
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/paride/pcd.c linux-libre-2.6.34-gnu1/drivers/block/paride/pcd.c
--- linux-libre-2.6.33-gnu1/drivers/block/paride/pcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/paride/pcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -341,11 +341,11 @@ static int pcd_wait(struct pcd_unit *cd,
 	       && (j++ < PCD_SPIN))
 		udelay(PCD_DELAY);
 
-	if ((r & (IDE_ERR & stop)) || (j >= PCD_SPIN)) {
+	if ((r & (IDE_ERR & stop)) || (j > PCD_SPIN)) {
 		s = read_reg(cd, 7);
 		e = read_reg(cd, 1);
 		p = read_reg(cd, 2);
-		if (j >= PCD_SPIN)
+		if (j > PCD_SPIN)
 			e |= 0x100;
 		if (fun)
 			printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/paride/pd.c linux-libre-2.6.34-gnu1/drivers/block/paride/pd.c
--- linux-libre-2.6.33-gnu1/drivers/block/paride/pd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/paride/pd.c	2010-05-16 17:17:36.000000000 -0400
@@ -145,6 +145,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO,
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/fs.h>
 #include <linux/delay.h>
 #include <linux/hdreg.h>
@@ -906,7 +907,7 @@ static int __init pd_init(void)
 	if (!pd_queue)
 		goto out1;
 
-	blk_queue_max_sectors(pd_queue, cluster);
+	blk_queue_max_hw_sectors(pd_queue, cluster);
 
 	if (register_blkdev(major, name))
 		goto out2;
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/paride/pf.c linux-libre-2.6.34-gnu1/drivers/block/paride/pf.c
--- linux-libre-2.6.33-gnu1/drivers/block/paride/pf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/paride/pf.c	2010-05-16 17:17:36.000000000 -0400
@@ -391,11 +391,11 @@ static int pf_wait(struct pf_unit *pf, i
 	       && (j++ < PF_SPIN))
 		udelay(PF_SPIN_DEL);
 
-	if ((r & (STAT_ERR & stop)) || (j >= PF_SPIN)) {
+	if ((r & (STAT_ERR & stop)) || (j > PF_SPIN)) {
 		s = read_reg(pf, 7);
 		e = read_reg(pf, 1);
 		p = read_reg(pf, 2);
-		if (j >= PF_SPIN)
+		if (j > PF_SPIN)
 			e |= 0x100;
 		if (fun)
 			printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
@@ -956,8 +956,7 @@ static int __init pf_init(void)
 		return -ENOMEM;
 	}
 
-	blk_queue_max_phys_segments(pf_queue, cluster);
-	blk_queue_max_hw_segments(pf_queue, cluster);
+	blk_queue_max_segments(pf_queue, cluster);
 
 	for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) {
 		struct gendisk *disk = pf->disk;
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/paride/pt.c linux-libre-2.6.34-gnu1/drivers/block/paride/pt.c
--- linux-libre-2.6.33-gnu1/drivers/block/paride/pt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/paride/pt.c	2010-05-16 17:17:36.000000000 -0400
@@ -274,11 +274,11 @@ static int pt_wait(struct pt_unit *tape,
 	       && (j++ < PT_SPIN))
 		udelay(PT_SPIN_DEL);
 
-	if ((r & (STAT_ERR & stop)) || (j >= PT_SPIN)) {
+	if ((r & (STAT_ERR & stop)) || (j > PT_SPIN)) {
 		s = read_reg(pi, 7);
 		e = read_reg(pi, 1);
 		p = read_reg(pi, 2);
-		if (j >= PT_SPIN)
+		if (j > PT_SPIN)
 			e |= 0x100;
 		if (fun)
 			printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/pktcdvd.c linux-libre-2.6.34-gnu1/drivers/block/pktcdvd.c
--- linux-libre-2.6.33-gnu1/drivers/block/pktcdvd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/pktcdvd.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,6 +48,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/compat.h>
 #include <linux/kthread.h>
 #include <linux/errno.h>
 #include <linux/spinlock.h>
@@ -57,6 +58,7 @@
 #include <linux/miscdevice.h>
 #include <linux/freezer.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_ioctl.h>
 #include <scsi/scsi.h>
@@ -284,7 +286,7 @@ static ssize_t kobj_pkt_store(struct kob
 	return len;
 }
 
-static struct sysfs_ops kobj_pkt_ops = {
+static const struct sysfs_ops kobj_pkt_ops = {
 	.show = kobj_pkt_show,
 	.store = kobj_pkt_store
 };
@@ -337,7 +339,9 @@ static void class_pktcdvd_release(struct
 {
 	kfree(cls);
 }
-static ssize_t class_pktcdvd_show_map(struct class *c, char *data)
+static ssize_t class_pktcdvd_show_map(struct class *c,
+					struct class_attribute *attr,
+					char *data)
 {
 	int n = 0;
 	int idx;
@@ -356,7 +360,9 @@ static ssize_t class_pktcdvd_show_map(st
 	return n;
 }
 
-static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf,
+static ssize_t class_pktcdvd_store_add(struct class *c,
+					struct class_attribute *attr,
+					const char *buf,
 					size_t count)
 {
 	unsigned int major, minor;
@@ -376,7 +382,9 @@ static ssize_t class_pktcdvd_store_add(s
 	return -EINVAL;
 }
 
-static ssize_t class_pktcdvd_store_remove(struct class *c, const char *buf,
+static ssize_t class_pktcdvd_store_remove(struct class *c,
+					  struct class_attribute *attr,
+					  const char *buf,
 					size_t count)
 {
 	unsigned int major, minor;
@@ -569,6 +577,7 @@ static struct packet_data *pkt_alloc_pac
 	}
 
 	spin_lock_init(&pkt->lock);
+	bio_list_init(&pkt->orig_bios);
 
 	for (i = 0; i < frames; i++) {
 		struct bio *bio = pkt_bio_alloc(1);
@@ -721,43 +730,6 @@ static void pkt_rbtree_insert(struct pkt
 }
 
 /*
- * Add a bio to a single linked list defined by its head and tail pointers.
- */
-static void pkt_add_list_last(struct bio *bio, struct bio **list_head, struct bio **list_tail)
-{
-	bio->bi_next = NULL;
-	if (*list_tail) {
-		BUG_ON((*list_head) == NULL);
-		(*list_tail)->bi_next = bio;
-		(*list_tail) = bio;
-	} else {
-		BUG_ON((*list_head) != NULL);
-		(*list_head) = bio;
-		(*list_tail) = bio;
-	}
-}
-
-/*
- * Remove and return the first bio from a single linked list defined by its
- * head and tail pointers.
- */
-static inline struct bio *pkt_get_list_first(struct bio **list_head, struct bio **list_tail)
-{
-	struct bio *bio;
-
-	if (*list_head == NULL)
-		return NULL;
-
-	bio = *list_head;
-	*list_head = bio->bi_next;
-	if (*list_head == NULL)
-		*list_tail = NULL;
-
-	bio->bi_next = NULL;
-	return bio;
-}
-
-/*
  * Send a packet_command to the underlying block device and
  * wait for completion.
  */
@@ -876,13 +848,10 @@ static noinline_for_stack int pkt_set_sp
 static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio)
 {
 	spin_lock(&pd->iosched.lock);
-	if (bio_data_dir(bio) == READ) {
-		pkt_add_list_last(bio, &pd->iosched.read_queue,
-				  &pd->iosched.read_queue_tail);
-	} else {
-		pkt_add_list_last(bio, &pd->iosched.write_queue,
-				  &pd->iosched.write_queue_tail);
-	}
+	if (bio_data_dir(bio) == READ)
+		bio_list_add(&pd->iosched.read_queue, bio);
+	else
+		bio_list_add(&pd->iosched.write_queue, bio);
 	spin_unlock(&pd->iosched.lock);
 
 	atomic_set(&pd->iosched.attention, 1);
@@ -917,8 +886,8 @@ static void pkt_iosched_process_queue(st
 		int reads_queued, writes_queued;
 
 		spin_lock(&pd->iosched.lock);
-		reads_queued = (pd->iosched.read_queue != NULL);
-		writes_queued = (pd->iosched.write_queue != NULL);
+		reads_queued = !bio_list_empty(&pd->iosched.read_queue);
+		writes_queued = !bio_list_empty(&pd->iosched.write_queue);
 		spin_unlock(&pd->iosched.lock);
 
 		if (!reads_queued && !writes_queued)
@@ -927,7 +896,7 @@ static void pkt_iosched_process_queue(st
 		if (pd->iosched.writing) {
 			int need_write_seek = 1;
 			spin_lock(&pd->iosched.lock);
-			bio = pd->iosched.write_queue;
+			bio = bio_list_peek(&pd->iosched.write_queue);
 			spin_unlock(&pd->iosched.lock);
 			if (bio && (bio->bi_sector == pd->iosched.last_write))
 				need_write_seek = 0;
@@ -950,13 +919,10 @@ static void pkt_iosched_process_queue(st
 		}
 
 		spin_lock(&pd->iosched.lock);
-		if (pd->iosched.writing) {
-			bio = pkt_get_list_first(&pd->iosched.write_queue,
-						 &pd->iosched.write_queue_tail);
-		} else {
-			bio = pkt_get_list_first(&pd->iosched.read_queue,
-						 &pd->iosched.read_queue_tail);
-		}
+		if (pd->iosched.writing)
+			bio = bio_list_pop(&pd->iosched.write_queue);
+		else
+			bio = bio_list_pop(&pd->iosched.read_queue);
 		spin_unlock(&pd->iosched.lock);
 
 		if (!bio)
@@ -992,14 +958,14 @@ static void pkt_iosched_process_queue(st
 static int pkt_set_segment_merging(struct pktcdvd_device *pd, struct request_queue *q)
 {
 	if ((pd->settings.size << 9) / CD_FRAMESIZE
-	    <= queue_max_phys_segments(q)) {
+	    <= queue_max_segments(q)) {
 		/*
 		 * The cdrom device can handle one segment/frame
 		 */
 		clear_bit(PACKET_MERGE_SEGS, &pd->flags);
 		return 0;
 	} else if ((pd->settings.size << 9) / PAGE_SIZE
-		   <= queue_max_phys_segments(q)) {
+		   <= queue_max_segments(q)) {
 		/*
 		 * We can handle this case at the expense of some extra memory
 		 * copies during write operations
@@ -1114,7 +1080,7 @@ static void pkt_gather_data(struct pktcd
 	int f;
 	char written[PACKET_MAX_SIZE];
 
-	BUG_ON(!pkt->orig_bios);
+	BUG_ON(bio_list_empty(&pkt->orig_bios));
 
 	atomic_set(&pkt->io_wait, 0);
 	atomic_set(&pkt->io_errors, 0);
@@ -1124,7 +1090,7 @@ static void pkt_gather_data(struct pktcd
 	 */
 	memset(written, 0, sizeof(written));
 	spin_lock(&pkt->lock);
-	for (bio = pkt->orig_bios; bio; bio = bio->bi_next) {
+	bio_list_for_each(bio, &pkt->orig_bios) {
 		int first_frame = (bio->bi_sector - pkt->sector) / (CD_FRAMESIZE >> 9);
 		int num_frames = bio->bi_size / CD_FRAMESIZE;
 		pd->stats.secs_w += num_frames * (CD_FRAMESIZE >> 9);
@@ -1363,7 +1329,7 @@ try_next_bio:
 			break;
 		pkt_rbtree_erase(pd, node);
 		spin_lock(&pkt->lock);
-		pkt_add_list_last(bio, &pkt->orig_bios, &pkt->orig_bios_tail);
+		bio_list_add(&pkt->orig_bios, bio);
 		pkt->write_size += bio->bi_size / CD_FRAMESIZE;
 		spin_unlock(&pkt->lock);
 	}
@@ -1409,7 +1375,7 @@ static void pkt_start_write(struct pktcd
 	 */
 	frames_write = 0;
 	spin_lock(&pkt->lock);
-	for (bio = pkt->orig_bios; bio; bio = bio->bi_next) {
+	bio_list_for_each(bio, &pkt->orig_bios) {
 		int segment = bio->bi_idx;
 		int src_offs = 0;
 		int first_frame = (bio->bi_sector - pkt->sector) / (CD_FRAMESIZE >> 9);
@@ -1472,20 +1438,14 @@ static void pkt_start_write(struct pktcd
 
 static void pkt_finish_packet(struct packet_data *pkt, int uptodate)
 {
-	struct bio *bio, *next;
+	struct bio *bio;
 
 	if (!uptodate)
 		pkt->cache_valid = 0;
 
 	/* Finish all bios corresponding to this packet */
-	bio = pkt->orig_bios;
-	while (bio) {
-		next = bio->bi_next;
-		bio->bi_next = NULL;
+	while ((bio = bio_list_pop(&pkt->orig_bios)))
 		bio_endio(bio, uptodate ? 0 : -EIO);
-		bio = next;
-	}
-	pkt->orig_bios = pkt->orig_bios_tail = NULL;
 }
 
 static void pkt_run_state_machine(struct pktcdvd_device *pd, struct packet_data *pkt)
@@ -2360,7 +2320,7 @@ static int pkt_open_dev(struct pktcdvd_d
 		 * even if the size is a multiple of the packet size.
 		 */
 		spin_lock_irq(q->queue_lock);
-		blk_queue_max_sectors(q, pd->settings.size);
+		blk_queue_max_hw_sectors(q, pd->settings.size);
 		spin_unlock_irq(q->queue_lock);
 		set_bit(PACKET_WRITABLE, &pd->flags);
 	} else {
@@ -2567,8 +2527,7 @@ static int pkt_make_request(struct reque
 			spin_lock(&pkt->lock);
 			if ((pkt->state == PACKET_WAITING_STATE) ||
 			    (pkt->state == PACKET_READ_WAIT_STATE)) {
-				pkt_add_list_last(bio, &pkt->orig_bios,
-						  &pkt->orig_bios_tail);
+				bio_list_add(&pkt->orig_bios, bio);
 				pkt->write_size += bio->bi_size / CD_FRAMESIZE;
 				if ((pkt->write_size >= pkt->frames) &&
 				    (pkt->state == PACKET_WAITING_STATE)) {
@@ -2662,7 +2621,7 @@ static void pkt_init_queue(struct pktcdv
 
 	blk_queue_make_request(q, pkt_make_request);
 	blk_queue_logical_block_size(q, CD_FRAMESIZE);
-	blk_queue_max_sectors(q, PACKET_MAX_SECTORS);
+	blk_queue_max_hw_sectors(q, PACKET_MAX_SECTORS);
 	blk_queue_merge_bvec(q, pkt_merge_bvec);
 	q->queuedata = pd;
 }
@@ -2898,6 +2857,8 @@ static int pkt_setup_dev(dev_t dev, dev_
 
 	spin_lock_init(&pd->lock);
 	spin_lock_init(&pd->iosched.lock);
+	bio_list_init(&pd->iosched.read_queue);
+	bio_list_init(&pd->iosched.write_queue);
 	sprintf(pd->name, DRIVER_NAME"%d", idx);
 	init_waitqueue_head(&pd->wqueue);
 	pd->bio_queue = RB_ROOT;
@@ -3024,7 +2985,7 @@ static void pkt_get_status(struct pkt_ct
 	mutex_unlock(&ctl_mutex);
 }
 
-static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long pkt_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	void __user *argp = (void __user *)arg;
 	struct pkt_ctrl_command ctrl_cmd;
@@ -3061,10 +3022,20 @@ static int pkt_ctl_ioctl(struct inode *i
 	return ret;
 }
 
+#ifdef CONFIG_COMPAT
+static long pkt_ctl_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	return pkt_ctl_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
+}
+#endif
 
 static const struct file_operations pkt_ctl_fops = {
-	.ioctl	 = pkt_ctl_ioctl,
-	.owner	 = THIS_MODULE,
+	.open		= nonseekable_open,
+	.unlocked_ioctl	= pkt_ctl_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= pkt_ctl_compat_ioctl,
+#endif
+	.owner		= THIS_MODULE,
 };
 
 static struct miscdevice pkt_misc = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/ps3disk.c linux-libre-2.6.34-gnu1/drivers/block/ps3disk.c
--- linux-libre-2.6.33-gnu1/drivers/block/ps3disk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/ps3disk.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 
 #include <linux/ata.h>
 #include <linux/blkdev.h>
+#include <linux/slab.h>
 
 #include <asm/lv1call.h>
 #include <asm/ps3stor.h>
@@ -474,7 +475,7 @@ static int __devinit ps3disk_probe(struc
 
 	blk_queue_bounce_limit(queue, BLK_BOUNCE_HIGH);
 
-	blk_queue_max_sectors(queue, dev->bounce_size >> 9);
+	blk_queue_max_hw_sectors(queue, dev->bounce_size >> 9);
 	blk_queue_segment_boundary(queue, -1UL);
 	blk_queue_dma_alignment(queue, dev->blk_size-1);
 	blk_queue_logical_block_size(queue, dev->blk_size);
@@ -482,8 +483,7 @@ static int __devinit ps3disk_probe(struc
 	blk_queue_ordered(queue, QUEUE_ORDERED_DRAIN_FLUSH,
 			  ps3disk_prepare_flush);
 
-	blk_queue_max_phys_segments(queue, -1);
-	blk_queue_max_hw_segments(queue, -1);
+	blk_queue_max_segments(queue, -1);
 	blk_queue_max_segment_size(queue, dev->bounce_size);
 
 	gendisk = alloc_disk(PS3DISK_MINORS);
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/ps3vram.c linux-libre-2.6.34-gnu1/drivers/block/ps3vram.c
--- linux-libre-2.6.33-gnu1/drivers/block/ps3vram.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/ps3vram.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <asm/cell-regs.h>
 #include <asm/firmware.h>
@@ -751,10 +752,9 @@ static int __devinit ps3vram_probe(struc
 	priv->queue = queue;
 	queue->queuedata = dev;
 	blk_queue_make_request(queue, ps3vram_make_request);
-	blk_queue_max_phys_segments(queue, MAX_PHYS_SEGMENTS);
-	blk_queue_max_hw_segments(queue, MAX_HW_SEGMENTS);
-	blk_queue_max_segment_size(queue, MAX_SEGMENT_SIZE);
-	blk_queue_max_sectors(queue, SAFE_MAX_SECTORS);
+	blk_queue_max_segments(queue, BLK_MAX_SEGMENTS);
+	blk_queue_max_segment_size(queue, BLK_MAX_SEGMENT_SIZE);
+	blk_queue_max_hw_sectors(queue, BLK_SAFE_MAX_SECTORS);
 
 	gendisk = alloc_disk(1);
 	if (!gendisk) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/sunvdc.c linux-libre-2.6.34-gnu1/drivers/block/sunvdc.c
--- linux-libre-2.6.33-gnu1/drivers/block/sunvdc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/sunvdc.c	2010-05-16 17:17:36.000000000 -0400
@@ -691,9 +691,8 @@ static int probe_disk(struct vdc_port *p
 
 	port->disk = g;
 
-	blk_queue_max_hw_segments(q, port->ring_cookies);
-	blk_queue_max_phys_segments(q, port->ring_cookies);
-	blk_queue_max_sectors(q, port->max_xfer_size);
+	blk_queue_max_segments(q, port->ring_cookies);
+	blk_queue_max_hw_sectors(q, port->max_xfer_size);
 	g->major = vdc_major;
 	g->first_minor = port->vio.vdev->dev_no << PARTITION_SHIFT;
 	strcpy(g->disk_name, port->disk_name);
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/swim.c linux-libre-2.6.34-gnu1/drivers/block/swim.c
--- linux-libre-2.6.33-gnu1/drivers/block/swim.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/swim.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 
 #include <linux/module.h>
 #include <linux/fd.h>
+#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/hdreg.h>
 #include <linux/kernel.h>
@@ -864,7 +865,7 @@ static int __devinit swim_probe(struct p
 	struct swim_priv *swd;
 	int ret;
 
-	res = platform_get_resource_byname(dev, IORESOURCE_MEM, "swim-regs");
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
 	if (!res) {
 		ret = -ENODEV;
 		goto out;
@@ -942,7 +943,7 @@ static int __devexit swim_remove(struct
 
 	iounmap(swd->base);
 
-	res = platform_get_resource_byname(dev, IORESOURCE_MEM, "swim-regs");
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
 	if (res)
 		release_mem_region(res->start, resource_size(res));
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/sx8.c linux-libre-2.6.34-gnu1/drivers/block/sx8.c
--- linux-libre-2.6.33-gnu1/drivers/block/sx8.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/sx8.c	2010-05-16 17:17:36.000000000 -0400
@@ -409,7 +409,7 @@ static int carm_init_one (struct pci_dev
 static void carm_remove_one (struct pci_dev *pdev);
 static int carm_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 
-static struct pci_device_id carm_pci_tbl[] = {
+static const struct pci_device_id carm_pci_tbl[] = {
 	{ PCI_VENDOR_ID_PROMISE, 0x8000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
 	{ PCI_VENDOR_ID_PROMISE, 0x8002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
 	{ }	/* terminate list */
@@ -1518,8 +1518,7 @@ static int carm_init_disks(struct carm_h
 			break;
 		}
 		disk->queue = q;
-		blk_queue_max_hw_segments(q, CARM_MAX_REQ_SG);
-		blk_queue_max_phys_segments(q, CARM_MAX_REQ_SG);
+		blk_queue_max_segments(q, CARM_MAX_REQ_SG);
 		blk_queue_segment_boundary(q, CARM_SG_BOUNDARY);
 
 		q->queuedata = port;
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/ub.c linux-libre-2.6.34-gnu1/drivers/block/ub.c
--- linux-libre-2.6.33-gnu1/drivers/block/ub.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/ub.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/blkdev.h>
 #include <linux/timer.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 
 #define DRV_NAME "ub"
@@ -393,7 +394,7 @@ static int ub_probe_lun(struct ub_dev *s
 #define ub_usb_ids  usb_storage_usb_ids
 #else
 
-static struct usb_device_id ub_usb_ids[] = {
+static const struct usb_device_id ub_usb_ids[] = {
 	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
 	{ }
 };
@@ -2320,10 +2321,9 @@ static int ub_probe_lun(struct ub_dev *s
 	disk->queue = q;
 
 	blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH);
-	blk_queue_max_hw_segments(q, UB_MAX_REQ_SG);
-	blk_queue_max_phys_segments(q, UB_MAX_REQ_SG);
+	blk_queue_max_segments(q, UB_MAX_REQ_SG);
 	blk_queue_segment_boundary(q, 0xffffffff);	/* Dubious. */
-	blk_queue_max_sectors(q, UB_MAX_SECTORS);
+	blk_queue_max_hw_sectors(q, UB_MAX_SECTORS);
 	blk_queue_logical_block_size(q, lun->capacity.bsize);
 
 	lun->disk = disk;
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/umem.c linux-libre-2.6.34-gnu1/drivers/block/umem.c
--- linux-libre-2.6.33-gnu1/drivers/block/umem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/umem.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,13 +40,13 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
+#include <linux/gfp.h>
 #include <linux/ioctl.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/timer.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/dma-mapping.h>
 
 #include <linux/fcntl.h>        /* O_ACCMODE */
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/viodasd.c linux-libre-2.6.34-gnu1/drivers/block/viodasd.c
--- linux-libre-2.6.33-gnu1/drivers/block/viodasd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/viodasd.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,9 @@
  * All disk operations are performed by sending messages back and forth to
  * the OS/400 partition.
  */
+
+#define pr_fmt(fmt) "viod: " fmt
+
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/module.h>
@@ -63,9 +66,6 @@ MODULE_LICENSE("GPL");
 
 #define VIOD_VERS		"1.64"
 
-#define VIOD_KERN_WARNING	KERN_WARNING "viod: "
-#define VIOD_KERN_INFO		KERN_INFO "viod: "
-
 enum {
 	PARTITION_SHIFT = 3,
 	MAX_DISKNO = HVMAXARCHITECTEDVIRTUALDISKS,
@@ -156,7 +156,7 @@ static int viodasd_open(struct block_dev
 			((u64)DEVICE_NO(d) << 48) | ((u64)flags << 32),
 			0, 0, 0);
 	if (hvrc != 0) {
-		printk(VIOD_KERN_WARNING "HV open failed %d\n", (int)hvrc);
+		pr_warning("HV open failed %d\n", (int)hvrc);
 		return -EIO;
 	}
 
@@ -167,9 +167,8 @@ static int viodasd_open(struct block_dev
 		const struct vio_error_entry *err =
 			vio_lookup_rc(viodasd_err_table, we.sub_result);
 
-		printk(VIOD_KERN_WARNING
-				"bad rc opening disk: %d:0x%04x (%s)\n",
-				(int)we.rc, we.sub_result, err->msg);
+		pr_warning("bad rc opening disk: %d:0x%04x (%s)\n",
+			   (int)we.rc, we.sub_result, err->msg);
 		return -EIO;
 	}
 
@@ -195,8 +194,7 @@ static int viodasd_release(struct gendis
 			((u64)DEVICE_NO(d) << 48) /* | ((u64)flags << 32) */,
 			0, 0, 0);
 	if (hvrc != 0)
-		printk(VIOD_KERN_WARNING "HV close call failed %d\n",
-				(int)hvrc);
+		pr_warning("HV close call failed %d\n", (int)hvrc);
 	return 0;
 }
 
@@ -288,8 +286,7 @@ static int send_request(struct request *
 		bevent = (struct vioblocklpevent *)
 			vio_get_event_buffer(viomajorsubtype_blockio);
 		if (bevent == NULL) {
-			printk(VIOD_KERN_WARNING
-			       "error allocating disk event buffer\n");
+			pr_warning("error allocating disk event buffer\n");
 			goto error_ret;
 		}
 
@@ -333,9 +330,8 @@ static int send_request(struct request *
 	}
 
 	if (hvrc != HvLpEvent_Rc_Good) {
-		printk(VIOD_KERN_WARNING
-		       "error sending disk event to OS/400 (rc %d)\n",
-		       (int)hvrc);
+		pr_warning("error sending disk event to OS/400 (rc %d)\n",
+			   (int)hvrc);
 		goto error_ret;
 	}
 	spin_unlock_irqrestore(&viodasd_spinlock, flags);
@@ -402,7 +398,7 @@ retry:
 			((u64)dev_no << 48) | ((u64)flags<< 32),
 			0, 0, 0);
 	if (hvrc != 0) {
-		printk(VIOD_KERN_WARNING "bad rc on HV open %d\n", (int)hvrc);
+		pr_warning("bad rc on HV open %d\n", (int)hvrc);
 		return 0;
 	}
 
@@ -416,9 +412,8 @@ retry:
 		goto retry;
 	}
 	if (we.max_disk > (MAX_DISKNO - 1)) {
-		printk_once(VIOD_KERN_INFO
-			"Only examining the first %d of %d disks connected\n",
-			MAX_DISKNO, we.max_disk + 1);
+		printk_once(KERN_INFO pr_fmt("Only examining the first %d of %d disks connected\n"),
+			    MAX_DISKNO, we.max_disk + 1);
 	}
 
 	/* Send the close event to OS/400.  We DON'T expect a response */
@@ -432,17 +427,15 @@ retry:
 			((u64)dev_no << 48) | ((u64)flags << 32),
 			0, 0, 0);
 	if (hvrc != 0) {
-		printk(VIOD_KERN_WARNING
-		       "bad rc sending event to OS/400 %d\n", (int)hvrc);
+		pr_warning("bad rc sending event to OS/400 %d\n", (int)hvrc);
 		return 0;
 	}
 
 	if (d->dev == NULL) {
 		/* this is when we reprobe for new disks */
 		if (vio_create_viodasd(dev_no) == NULL) {
-			printk(VIOD_KERN_WARNING
-				"cannot allocate virtual device for disk %d\n",
-				dev_no);
+			pr_warning("cannot allocate virtual device for disk %d\n",
+				   dev_no);
 			return 0;
 		}
 		/*
@@ -457,23 +450,20 @@ retry:
 	spin_lock_init(&d->q_lock);
 	q = blk_init_queue(do_viodasd_request, &d->q_lock);
 	if (q == NULL) {
-		printk(VIOD_KERN_WARNING "cannot allocate queue for disk %d\n",
-				dev_no);
+		pr_warning("cannot allocate queue for disk %d\n", dev_no);
 		return 0;
 	}
 	g = alloc_disk(1 << PARTITION_SHIFT);
 	if (g == NULL) {
-		printk(VIOD_KERN_WARNING
-				"cannot allocate disk structure for disk %d\n",
-				dev_no);
+		pr_warning("cannot allocate disk structure for disk %d\n",
+			   dev_no);
 		blk_cleanup_queue(q);
 		return 0;
 	}
 
 	d->disk = g;
-	blk_queue_max_hw_segments(q, VIOMAXBLOCKDMA);
-	blk_queue_max_phys_segments(q, VIOMAXBLOCKDMA);
-	blk_queue_max_sectors(q, VIODASD_MAXSECTORS);
+	blk_queue_max_segments(q, VIOMAXBLOCKDMA);
+	blk_queue_max_hw_sectors(q, VIODASD_MAXSECTORS);
 	g->major = VIODASD_MAJOR;
 	g->first_minor = dev_no << PARTITION_SHIFT;
 	if (dev_no >= 26)
@@ -489,13 +479,12 @@ retry:
 	g->driverfs_dev = d->dev;
 	set_capacity(g, d->size >> 9);
 
-	printk(VIOD_KERN_INFO "disk %d: %lu sectors (%lu MB) "
-			"CHS=%d/%d/%d sector size %d%s\n",
-			dev_no, (unsigned long)(d->size >> 9),
-			(unsigned long)(d->size >> 20),
-			(int)d->cylinders, (int)d->tracks,
-			(int)d->sectors, (int)d->bytes_per_sector,
-			d->read_only ? " (RO)" : "");
+	pr_info("disk %d: %lu sectors (%lu MB) CHS=%d/%d/%d sector size %d%s\n",
+		dev_no, (unsigned long)(d->size >> 9),
+		(unsigned long)(d->size >> 20),
+		(int)d->cylinders, (int)d->tracks,
+		(int)d->sectors, (int)d->bytes_per_sector,
+		d->read_only ? " (RO)" : "");
 
 	/* register us in the global list */
 	add_disk(g);
@@ -580,8 +569,8 @@ static int viodasd_handle_read_write(str
 	if (error) {
 		const struct vio_error_entry *err;
 		err = vio_lookup_rc(viodasd_err_table, bevent->sub_result);
-		printk(VIOD_KERN_WARNING "read/write error %d:0x%04x (%s)\n",
-				event->xRc, bevent->sub_result, err->msg);
+		pr_warning("read/write error %d:0x%04x (%s)\n",
+			   event->xRc, bevent->sub_result, err->msg);
 		num_sect = blk_rq_sectors(req);
 	}
 	qlock = req->q->queue_lock;
@@ -606,8 +595,7 @@ static void handle_block_event(struct Hv
 		return;
 	/* First, we should NEVER get an int here...only acks */
 	if (hvlpevent_is_int(event)) {
-		printk(VIOD_KERN_WARNING
-		       "Yikes! got an int in viodasd event handler!\n");
+		pr_warning("Yikes! got an int in viodasd event handler!\n");
 		if (hvlpevent_need_ack(event)) {
 			event->xRc = HvLpEvent_Rc_InvalidSubtype;
 			HvCallEvent_ackLpEvent(event);
@@ -650,7 +638,7 @@ static void handle_block_event(struct Hv
 		break;
 
 	default:
-		printk(VIOD_KERN_WARNING "invalid subtype!");
+		pr_warning("invalid subtype!");
 		if (hvlpevent_need_ack(event)) {
 			event->xRc = HvLpEvent_Rc_InvalidSubtype;
 			HvCallEvent_ackLpEvent(event);
@@ -739,29 +727,26 @@ static int __init viodasd_init(void)
 		vio_set_hostlp();
 
 	if (viopath_hostLp == HvLpIndexInvalid) {
-		printk(VIOD_KERN_WARNING "invalid hosting partition\n");
+		pr_warning("invalid hosting partition\n");
 		rc = -EIO;
 		goto early_fail;
 	}
 
-	printk(VIOD_KERN_INFO "vers " VIOD_VERS ", hosting partition %d\n",
-			viopath_hostLp);
+	pr_info("vers " VIOD_VERS ", hosting partition %d\n", viopath_hostLp);
 
         /* register the block device */
 	rc =  register_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME);
 	if (rc) {
-		printk(VIOD_KERN_WARNING
-				"Unable to get major number %d for %s\n",
-				VIODASD_MAJOR, VIOD_GENHD_NAME);
+		pr_warning("Unable to get major number %d for %s\n",
+			   VIODASD_MAJOR, VIOD_GENHD_NAME);
 		goto early_fail;
 	}
 	/* Actually open the path to the hosting partition */
 	rc = viopath_open(viopath_hostLp, viomajorsubtype_blockio,
 				VIOMAXREQ + 2);
 	if (rc) {
-		printk(VIOD_KERN_WARNING
-		       "error opening path to host partition %d\n",
-		       viopath_hostLp);
+		pr_warning("error opening path to host partition %d\n",
+			   viopath_hostLp);
 		goto unregister_blk;
 	}
 
@@ -770,7 +755,7 @@ static int __init viodasd_init(void)
 
 	rc = vio_register_driver(&viodasd_driver);
 	if (rc) {
-		printk(VIOD_KERN_WARNING "vio_register_driver failed\n");
+		pr_warning("vio_register_driver failed\n");
 		goto unset_handler;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/virtio_blk.c linux-libre-2.6.34-gnu1/drivers/block/virtio_blk.c
--- linux-libre-2.6.33-gnu1/drivers/block/virtio_blk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/virtio_blk.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,6 @@
 //#define DEBUG
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/hdreg.h>
 #include <linux/virtio.h>
@@ -243,10 +244,12 @@ static int index_to_minor(int index)
 static int __devinit virtblk_probe(struct virtio_device *vdev)
 {
 	struct virtio_blk *vblk;
+	struct request_queue *q;
 	int err;
 	u64 cap;
-	u32 v;
-	u32 blk_size, sg_elems;
+	u32 v, blk_size, sg_elems, opt_io_size;
+	u16 min_io_size;
+	u8 physical_block_exp, alignment_offset;
 
 	if (index_to_minor(index) >= 1 << MINORBITS)
 		return -ENOSPC;
@@ -293,13 +296,13 @@ static int __devinit virtblk_probe(struc
 		goto out_mempool;
 	}
 
-	vblk->disk->queue = blk_init_queue(do_virtblk_request, &vblk->lock);
-	if (!vblk->disk->queue) {
+	q = vblk->disk->queue = blk_init_queue(do_virtblk_request, &vblk->lock);
+	if (!q) {
 		err = -ENOMEM;
 		goto out_put_disk;
 	}
 
-	vblk->disk->queue->queuedata = vblk;
+	q->queuedata = vblk;
 
 	if (index < 26) {
 		sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26);
@@ -323,10 +326,10 @@ static int __devinit virtblk_probe(struc
 
 	/* If barriers are supported, tell block layer that queue is ordered */
 	if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH))
-		blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_DRAIN_FLUSH,
+		blk_queue_ordered(q, QUEUE_ORDERED_DRAIN_FLUSH,
 				  virtblk_prepare_flush);
 	else if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER))
-		blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL);
+		blk_queue_ordered(q, QUEUE_ORDERED_TAG, NULL);
 
 	/* If disk is read-only in the host, the guest should obey */
 	if (virtio_has_feature(vdev, VIRTIO_BLK_F_RO))
@@ -345,14 +348,13 @@ static int __devinit virtblk_probe(struc
 	set_capacity(vblk->disk, cap);
 
 	/* We can handle whatever the host told us to handle. */
-	blk_queue_max_phys_segments(vblk->disk->queue, vblk->sg_elems-2);
-	blk_queue_max_hw_segments(vblk->disk->queue, vblk->sg_elems-2);
+	blk_queue_max_segments(q, vblk->sg_elems-2);
 
 	/* No need to bounce any requests */
-	blk_queue_bounce_limit(vblk->disk->queue, BLK_BOUNCE_ANY);
+	blk_queue_bounce_limit(q, BLK_BOUNCE_ANY);
 
 	/* No real sector limit. */
-	blk_queue_max_sectors(vblk->disk->queue, -1U);
+	blk_queue_max_hw_sectors(q, -1U);
 
 	/* Host can optionally specify maximum segment size and number of
 	 * segments. */
@@ -360,16 +362,45 @@ static int __devinit virtblk_probe(struc
 				offsetof(struct virtio_blk_config, size_max),
 				&v);
 	if (!err)
-		blk_queue_max_segment_size(vblk->disk->queue, v);
+		blk_queue_max_segment_size(q, v);
 	else
-		blk_queue_max_segment_size(vblk->disk->queue, -1U);
+		blk_queue_max_segment_size(q, -1U);
 
 	/* Host can optionally specify the block size of the device */
 	err = virtio_config_val(vdev, VIRTIO_BLK_F_BLK_SIZE,
 				offsetof(struct virtio_blk_config, blk_size),
 				&blk_size);
 	if (!err)
-		blk_queue_logical_block_size(vblk->disk->queue, blk_size);
+		blk_queue_logical_block_size(q, blk_size);
+	else
+		blk_size = queue_logical_block_size(q);
+
+	/* Use topology information if available */
+	err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY,
+			offsetof(struct virtio_blk_config, physical_block_exp),
+			&physical_block_exp);
+	if (!err && physical_block_exp)
+		blk_queue_physical_block_size(q,
+				blk_size * (1 << physical_block_exp));
+
+	err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY,
+			offsetof(struct virtio_blk_config, alignment_offset),
+			&alignment_offset);
+	if (!err && alignment_offset)
+		blk_queue_alignment_offset(q, blk_size * alignment_offset);
+
+	err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY,
+			offsetof(struct virtio_blk_config, min_io_size),
+			&min_io_size);
+	if (!err && min_io_size)
+		blk_queue_io_min(q, blk_size * min_io_size);
+
+	err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY,
+			offsetof(struct virtio_blk_config, opt_io_size),
+			&opt_io_size);
+	if (!err && opt_io_size)
+		blk_queue_io_opt(q, blk_size * opt_io_size);
+
 
 	add_disk(vblk->disk);
 	return 0;
@@ -404,7 +435,7 @@ static void __devexit virtblk_remove(str
 	kfree(vblk);
 }
 
-static struct virtio_device_id id_table[] = {
+static const struct virtio_device_id id_table[] = {
 	{ VIRTIO_ID_BLOCK, VIRTIO_DEV_ANY_ID },
 	{ 0 },
 };
@@ -412,7 +443,7 @@ static struct virtio_device_id id_table[
 static unsigned int features[] = {
 	VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX,
 	VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
-	VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_FLUSH
+	VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY
 };
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/xd.c linux-libre-2.6.34-gnu1/drivers/block/xd.c
--- linux-libre-2.6.33-gnu1/drivers/block/xd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/xd.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,7 @@
 #include <linux/blkpg.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -242,7 +243,7 @@ static int __init xd_init(void)
 	}
 
 	/* xd_maxsectors depends on controller - so set after detection */
-	blk_queue_max_sectors(xd_queue, xd_maxsectors);
+	blk_queue_max_hw_sectors(xd_queue, xd_maxsectors);
 
 	for (i = 0; i < xd_drives; i++)
 		add_disk(xd_gendisk[i]);
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/xen-blkfront.c linux-libre-2.6.34-gnu1/drivers/block/xen-blkfront.c
--- linux-libre-2.6.33-gnu1/drivers/block/xen-blkfront.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/xen-blkfront.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/hdreg.h>
 #include <linux/cdrom.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/scatterlist.h>
 
 #include <xen/xen.h>
@@ -346,15 +347,14 @@ static int xlvbd_init_blk_queue(struct g
 
 	/* Hard sector size and max sectors impersonate the equiv. hardware. */
 	blk_queue_logical_block_size(rq, sector_size);
-	blk_queue_max_sectors(rq, 512);
+	blk_queue_max_hw_sectors(rq, 512);
 
 	/* Each segment in a request is up to an aligned page in size. */
 	blk_queue_segment_boundary(rq, PAGE_SIZE - 1);
 	blk_queue_max_segment_size(rq, PAGE_SIZE);
 
 	/* Ensure a merged request will fit in a single I/O ring slot. */
-	blk_queue_max_phys_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST);
-	blk_queue_max_hw_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST);
+	blk_queue_max_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST);
 
 	/* Make sure buffer addresses are sector-aligned. */
 	blk_queue_dma_alignment(rq, 511);
@@ -1050,7 +1050,7 @@ static const struct block_device_operati
 };
 
 
-static struct xenbus_device_id blkfront_ids[] = {
+static const struct xenbus_device_id blkfront_ids[] = {
 	{ "vbd" },
 	{ "" }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/xsysace.c linux-libre-2.6.34-gnu1/drivers/block/xsysace.c
--- linux-libre-2.6.33-gnu1/drivers/block/xsysace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/xsysace.c	2010-05-16 17:17:36.000000000 -0400
@@ -1227,7 +1227,7 @@ static int __devexit ace_of_remove(struc
 }
 
 /* Match table for of_platform binding */
-static struct of_device_id ace_of_match[] __devinitdata = {
+static const struct of_device_id ace_of_match[] __devinitconst = {
 	{ .compatible = "xlnx,opb-sysace-1.00.b", },
 	{ .compatible = "xlnx,opb-sysace-1.00.c", },
 	{ .compatible = "xlnx,xps-sysace-1.00.a", },
diff -druNp linux-libre-2.6.33-gnu1/drivers/block/z2ram.c linux-libre-2.6.34-gnu1/drivers/block/z2ram.c
--- linux-libre-2.6.33-gnu1/drivers/block/z2ram.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/block/z2ram.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/module.h>
 #include <linux/blkdev.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 
 #include <asm/setup.h>
 #include <asm/amigahw.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/ath3k.c linux-libre-2.6.34-gnu1/drivers/bluetooth/ath3k.c
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/ath3k.c	2013-05-03 12:11:52.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/ath3k.c	2013-05-03 09:51:24.000000000 -0400
@@ -143,6 +143,8 @@ static int ath3k_probe(struct usb_interf
 	usb_set_intfdata(intf, data);
 	if (ath3k_load_firmware(data, data->fw_data, data->fw_size)) {
 		usb_set_intfdata(intf, NULL);
+		kfree(data->fw_data);
+		kfree(data);
 		return -EIO;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/bcm203x.c linux-libre-2.6.34-gnu1/drivers/bluetooth/bcm203x.c
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/bcm203x.c	2013-05-03 12:11:53.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/bcm203x.c	2013-05-03 09:51:26.000000000 -0400
@@ -39,7 +39,7 @@
 
 #define VERSION "1.2"
 
-static struct usb_device_id bcm203x_table[] = {
+static const struct usb_device_id bcm203x_table[] = {
 	/* Broadcom Blutonium (BCM2033) */
 	{ USB_DEVICE(0x0a5c, 0x2033) },
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/bfusb.c linux-libre-2.6.34-gnu1/drivers/bluetooth/bfusb.c
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/bfusb.c	2013-05-03 12:11:55.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/bfusb.c	2013-05-03 09:51:28.000000000 -0400
@@ -703,7 +703,7 @@ static int bfusb_probe(struct usb_interf
 
 	data->hdev = hdev;
 
-	hdev->type = HCI_USB;
+	hdev->bus = HCI_USB;
 	hdev->driver_data = data;
 	SET_HCIDEV_DEV(hdev, &intf->dev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/bluecard_cs.c linux-libre-2.6.34-gnu1/drivers/bluetooth/bluecard_cs.c
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/bluecard_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/bluecard_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -736,7 +736,7 @@ static int bluecard_open(bluecard_info_t
 
 	info->hdev = hdev;
 
-	hdev->type = HCI_PCCARD;
+	hdev->bus = HCI_PCCARD;
 	hdev->driver_data = info;
 	SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/bpa10x.c linux-libre-2.6.34-gnu1/drivers/bluetooth/bpa10x.c
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/bpa10x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/bpa10x.c	2010-05-16 17:17:36.000000000 -0400
@@ -469,7 +469,7 @@ static int bpa10x_probe(struct usb_inter
 		return -ENOMEM;
 	}
 
-	hdev->type = HCI_USB;
+	hdev->bus = HCI_USB;
 	hdev->driver_data = data;
 
 	data->hdev = hdev;
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/bt3c_cs.c linux-libre-2.6.34-gnu1/drivers/bluetooth/bt3c_cs.c
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/bt3c_cs.c	2013-05-03 12:11:57.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/bt3c_cs.c	2013-05-03 09:51:30.000000000 -0400
@@ -582,7 +582,7 @@ static int bt3c_open(bt3c_info_t *info)
 
 	info->hdev = hdev;
 
-	hdev->type = HCI_PCCARD;
+	hdev->bus = HCI_PCCARD;
 	hdev->driver_data = info;
 	SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_debugfs.c linux-libre-2.6.34-gnu1/drivers/bluetooth/btmrvl_debugfs.c
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_debugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/btmrvl_debugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  **/
 
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
@@ -26,7 +27,8 @@
 #include "btmrvl_drv.h"
 
 struct btmrvl_debugfs_data {
-	struct dentry *root_dir, *config_dir, *status_dir;
+	struct dentry *config_dir;
+	struct dentry *status_dir;
 
 	/* config */
 	struct dentry *psmode;
@@ -363,6 +365,9 @@ void btmrvl_debugfs_init(struct hci_dev
 	struct btmrvl_private *priv = hdev->driver_data;
 	struct btmrvl_debugfs_data *dbg;
 
+	if (!hdev->debugfs)
+		return;
+
 	dbg = kzalloc(sizeof(*dbg), GFP_KERNEL);
 	priv->debugfs_data = dbg;
 
@@ -371,9 +376,7 @@ void btmrvl_debugfs_init(struct hci_dev
 		return;
 	}
 
-	dbg->root_dir = debugfs_create_dir("btmrvl", NULL);
-
-	dbg->config_dir = debugfs_create_dir("config", dbg->root_dir);
+	dbg->config_dir = debugfs_create_dir("config", hdev->debugfs);
 
 	dbg->psmode = debugfs_create_file("psmode", 0644, dbg->config_dir,
 				hdev->driver_data, &btmrvl_psmode_fops);
@@ -388,7 +391,7 @@ void btmrvl_debugfs_init(struct hci_dev
 	dbg->hscfgcmd = debugfs_create_file("hscfgcmd", 0644, dbg->config_dir,
 				hdev->driver_data, &btmrvl_hscfgcmd_fops);
 
-	dbg->status_dir = debugfs_create_dir("status", dbg->root_dir);
+	dbg->status_dir = debugfs_create_dir("status", hdev->debugfs);
 	dbg->curpsmode = debugfs_create_file("curpsmode", 0444,
 						dbg->status_dir,
 						hdev->driver_data,
@@ -425,7 +428,5 @@ void btmrvl_debugfs_remove(struct hci_de
 	debugfs_remove(dbg->txdnldready);
 	debugfs_remove(dbg->status_dir);
 
-	debugfs_remove(dbg->root_dir);
-
 	kfree(dbg);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_drv.h linux-libre-2.6.34-gnu1/drivers/bluetooth/btmrvl_drv.h
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_drv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/btmrvl_drv.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 
 #include <linux/kthread.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include <net/bluetooth/bluetooth.h>
 
 #define BTM_HEADER_LEN			4
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_main.c linux-libre-2.6.34-gnu1/drivers/bluetooth/btmrvl_main.c
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/btmrvl_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -563,7 +563,7 @@ struct btmrvl_private *btmrvl_add_card(v
 
 	priv->btmrvl_dev.tx_dnld_rdy = true;
 
-	hdev->type = HCI_SDIO;
+	hdev->bus = HCI_SDIO;
 	hdev->open = btmrvl_open;
 	hdev->close = btmrvl_close;
 	hdev->flush = btmrvl_flush;
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_sdio.c linux-libre-2.6.34-gnu1/drivers/bluetooth/btmrvl_sdio.c
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_sdio.c	2013-05-03 12:12:00.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/btmrvl_sdio.c	2013-05-03 09:51:32.000000000 -0400
@@ -19,6 +19,7 @@
  **/
 
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/sdio_ids.h>
 #include <linux/mmc/sdio_func.h>
@@ -975,7 +976,7 @@ static struct sdio_driver bt_mrvl_sdio =
 	.remove		= btmrvl_sdio_remove,
 };
 
-static int btmrvl_sdio_init_module(void)
+static int __init btmrvl_sdio_init_module(void)
 {
 	if (sdio_register_driver(&bt_mrvl_sdio) != 0) {
 		BT_ERR("SDIO Driver Registration Failed");
@@ -988,7 +989,7 @@ static int btmrvl_sdio_init_module(void)
 	return 0;
 }
 
-static void btmrvl_sdio_exit_module(void)
+static void __exit btmrvl_sdio_exit_module(void)
 {
 	/* Set the flag as user is removing this module. */
 	user_rmmod = 1;
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/btsdio.c linux-libre-2.6.34-gnu1/drivers/bluetooth/btsdio.c
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/btsdio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/btsdio.c	2010-05-16 17:17:36.000000000 -0400
@@ -326,7 +326,7 @@ static int btsdio_probe(struct sdio_func
 		return -ENOMEM;
 	}
 
-	hdev->type = HCI_SDIO;
+	hdev->bus = HCI_SDIO;
 	hdev->driver_data = data;
 
 	data->hdev = hdev;
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/btuart_cs.c linux-libre-2.6.34-gnu1/drivers/bluetooth/btuart_cs.c
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/btuart_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/btuart_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -500,7 +500,7 @@ static int btuart_open(btuart_info_t *in
 
 	info->hdev = hdev;
 
-	hdev->type = HCI_PCCARD;
+	hdev->bus = HCI_PCCARD;
 	hdev->driver_data = info;
 	SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/btusb.c linux-libre-2.6.34-gnu1/drivers/bluetooth/btusb.c
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/btusb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/btusb.c	2010-05-16 17:17:36.000000000 -0400
@@ -939,7 +939,7 @@ static int btusb_probe(struct usb_interf
 		return -ENOMEM;
 	}
 
-	hdev->type = HCI_USB;
+	hdev->bus = HCI_USB;
 	hdev->driver_data = data;
 
 	data->hdev = hdev;
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/dtl1_cs.c linux-libre-2.6.34-gnu1/drivers/bluetooth/dtl1_cs.c
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/dtl1_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/dtl1_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -485,7 +485,7 @@ static int dtl1_open(dtl1_info_t *info)
 
 	info->hdev = hdev;
 
-	hdev->type = HCI_PCCARD;
+	hdev->bus = HCI_PCCARD;
 	hdev->driver_data = info;
 	SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/hci_ldisc.c linux-libre-2.6.34-gnu1/drivers/bluetooth/hci_ldisc.c
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/hci_ldisc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/hci_ldisc.c	2010-05-16 17:17:36.000000000 -0400
@@ -383,7 +383,7 @@ static int hci_uart_register_dev(struct
 
 	hu->hdev = hdev;
 
-	hdev->type = HCI_UART;
+	hdev->bus = HCI_UART;
 	hdev->driver_data = hu;
 
 	hdev->open  = hci_uart_open;
diff -druNp linux-libre-2.6.33-gnu1/drivers/bluetooth/hci_vhci.c linux-libre-2.6.34-gnu1/drivers/bluetooth/hci_vhci.c
--- linux-libre-2.6.33-gnu1/drivers/bluetooth/hci_vhci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/bluetooth/hci_vhci.c	2010-05-16 17:17:36.000000000 -0400
@@ -236,7 +236,7 @@ static int vhci_open(struct inode *inode
 
 	data->hdev = hdev;
 
-	hdev->type = HCI_VIRTUAL;
+	hdev->bus = HCI_VIRTUAL;
 	hdev->driver_data = data;
 
 	hdev->open     = vhci_open_dev;
diff -druNp linux-libre-2.6.33-gnu1/drivers/cdrom/gdrom.c linux-libre-2.6.34-gnu1/drivers/cdrom/gdrom.c
--- linux-libre-2.6.33-gnu1/drivers/cdrom/gdrom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/cdrom/gdrom.c	2010-05-16 17:17:36.000000000 -0400
@@ -741,7 +741,7 @@ static int __devinit probe_gdrom_setupqu
 {
 	blk_queue_logical_block_size(gd.gdrom_rq, GDROM_HARD_SECTOR);
 	/* using DMA so memory will need to be contiguous */
-	blk_queue_max_hw_segments(gd.gdrom_rq, 1);
+	blk_queue_max_segments(gd.gdrom_rq, 1);
 	/* set a large max size to get most from DMA */
 	blk_queue_max_segment_size(gd.gdrom_rq, 0x40000);
 	gd.disk->queue = gd.gdrom_rq;
diff -druNp linux-libre-2.6.33-gnu1/drivers/cdrom/viocd.c linux-libre-2.6.34-gnu1/drivers/cdrom/viocd.c
--- linux-libre-2.6.33-gnu1/drivers/cdrom/viocd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/cdrom/viocd.c	2010-05-16 17:17:36.000000000 -0400
@@ -616,9 +616,8 @@ static int viocd_probe(struct vio_dev *v
 	gendisk->first_minor = deviceno;
 	strncpy(gendisk->disk_name, c->name,
 			sizeof(gendisk->disk_name));
-	blk_queue_max_hw_segments(q, 1);
-	blk_queue_max_phys_segments(q, 1);
-	blk_queue_max_sectors(q, 4096 / 512);
+	blk_queue_max_segments(q, 1);
+	blk_queue_max_hw_sectors(q, 4096 / 512);
 	gendisk->queue = q;
 	gendisk->fops = &viocd_fops;
 	gendisk->flags = GENHD_FL_CD|GENHD_FL_REMOVABLE;
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/agp/amd-k7-agp.c linux-libre-2.6.34-gnu1/drivers/char/agp/amd-k7-agp.c
--- linux-libre-2.6.33-gnu1/drivers/char/agp/amd-k7-agp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/agp/amd-k7-agp.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,9 +6,9 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/agp_backend.h>
-#include <linux/gfp.h>
 #include <linux/page-flags.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include "agp.h"
 
 #define AMD_MMBASE	0x14
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/agp/backend.c linux-libre-2.6.34-gnu1/drivers/char/agp/backend.c
--- linux-libre-2.6.33-gnu1/drivers/char/agp/backend.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/agp/backend.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/miscdevice.h>
 #include <linux/pm.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/agp/compat_ioctl.c linux-libre-2.6.34-gnu1/drivers/char/agp/compat_ioctl.c
--- linux-libre-2.6.33-gnu1/drivers/char/agp/compat_ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/agp/compat_ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include <linux/fs.h>
 #include <linux/agpgart.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include "agp.h"
 #include "compat_ioctl.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/agp/generic.c linux-libre-2.6.34-gnu1/drivers/char/agp/generic.c
--- linux-libre-2.6.33-gnu1/drivers/char/agp/generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/agp/generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/cacheflush.h>
 #include <asm/pgtable.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/agp/hp-agp.c linux-libre-2.6.34-gnu1/drivers/char/agp/hp-agp.c
--- linux-libre-2.6.33-gnu1/drivers/char/agp/hp-agp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/agp/hp-agp.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/agp_backend.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 
 #include <asm/acpi-ext.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/agp/intel-agp.c linux-libre-2.6.34-gnu1/drivers/char/agp/intel-agp.c
--- linux-libre-2.6.33-gnu1/drivers/char/agp/intel-agp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/agp/intel-agp.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,12 +4,17 @@
 
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/pagemap.h>
 #include <linux/agp_backend.h>
+#include <asm/smp.h>
 #include "agp.h"
 
+int intel_agp_enabled;
+EXPORT_SYMBOL(intel_agp_enabled);
+
 /*
  * If we have Intel graphics, we're not going to have anything other than
  * an Intel IOMMU. So make the correct use of the PCI DMA API contingent
@@ -64,6 +69,10 @@
 #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB	    0x0062
 #define PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB    0x006a
 #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG	    0x0046
+#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB  0x0100
+#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG  0x0102
+#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB  0x0104
+#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG  0x0106
 
 /* cover 915 and 945 variants */
 #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \
@@ -89,6 +98,9 @@
 #define IS_PINEVIEW (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB)
 
+#define IS_SNB (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
+
 #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \
@@ -98,7 +110,8 @@
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \
-		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB)
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB || \
+		IS_SNB)
 
 extern int agp_memory_reserved;
 
@@ -147,6 +160,29 @@ extern int agp_memory_reserved;
 #define INTEL_I7505_AGPCTRL	0x70
 #define INTEL_I7505_MCHCFG	0x50
 
+#define SNB_GMCH_CTRL	0x50
+#define SNB_GMCH_GMS_STOLEN_MASK	0xF8
+#define SNB_GMCH_GMS_STOLEN_32M		(1 << 3)
+#define SNB_GMCH_GMS_STOLEN_64M		(2 << 3)
+#define SNB_GMCH_GMS_STOLEN_96M		(3 << 3)
+#define SNB_GMCH_GMS_STOLEN_128M	(4 << 3)
+#define SNB_GMCH_GMS_STOLEN_160M	(5 << 3)
+#define SNB_GMCH_GMS_STOLEN_192M	(6 << 3)
+#define SNB_GMCH_GMS_STOLEN_224M	(7 << 3)
+#define SNB_GMCH_GMS_STOLEN_256M	(8 << 3)
+#define SNB_GMCH_GMS_STOLEN_288M	(9 << 3)
+#define SNB_GMCH_GMS_STOLEN_320M	(0xa << 3)
+#define SNB_GMCH_GMS_STOLEN_352M	(0xb << 3)
+#define SNB_GMCH_GMS_STOLEN_384M	(0xc << 3)
+#define SNB_GMCH_GMS_STOLEN_416M	(0xd << 3)
+#define SNB_GMCH_GMS_STOLEN_448M	(0xe << 3)
+#define SNB_GMCH_GMS_STOLEN_480M	(0xf << 3)
+#define SNB_GMCH_GMS_STOLEN_512M	(0x10 << 3)
+#define SNB_GTT_SIZE_0M			(0 << 8)
+#define SNB_GTT_SIZE_1M			(1 << 8)
+#define SNB_GTT_SIZE_2M			(2 << 8)
+#define SNB_GTT_SIZE_MASK		(3 << 8)
+
 static const struct aper_size_info_fixed intel_i810_sizes[] =
 {
 	{64, 16384, 4},
@@ -269,7 +305,7 @@ static void intel_agp_insert_sg_entries(
 			j++;
 		}
 	} else {
-		/* sg may merge pages, but we have to seperate
+		/* sg may merge pages, but we have to separate
 		 * per-page addr for GTT */
 		unsigned int len, m;
 
@@ -293,6 +329,13 @@ static void intel_agp_insert_sg_entries(
 					off_t pg_start, int mask_type)
 {
 	int i, j;
+	u32 cache_bits = 0;
+
+	if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB ||
+	    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
+	{
+		cache_bits = I830_PTE_SYSTEM_CACHED;
+	}
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 		writel(agp_bridge->driver->mask_memory(agp_bridge,
@@ -613,7 +656,7 @@ static struct aper_size_info_fixed intel
 static void intel_i830_init_gtt_entries(void)
 {
 	u16 gmch_ctrl;
-	int gtt_entries;
+	int gtt_entries = 0;
 	u8 rdct;
 	int local = 0;
 	static const int ddt[4] = { 0, 16, 32, 64 };
@@ -705,6 +748,63 @@ static void intel_i830_init_gtt_entries(
 			gtt_entries = 0;
 			break;
 		}
+	} else if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB ||
+		   agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) {
+		/*
+		 * SandyBridge has new memory control reg at 0x50.w
+		 */
+		u16 snb_gmch_ctl;
+		pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl);
+		switch (snb_gmch_ctl & SNB_GMCH_GMS_STOLEN_MASK) {
+		case SNB_GMCH_GMS_STOLEN_32M:
+			gtt_entries = MB(32) - KB(size);
+			break;
+		case SNB_GMCH_GMS_STOLEN_64M:
+			gtt_entries = MB(64) - KB(size);
+			break;
+		case SNB_GMCH_GMS_STOLEN_96M:
+			gtt_entries = MB(96) - KB(size);
+			break;
+		case SNB_GMCH_GMS_STOLEN_128M:
+			gtt_entries = MB(128) - KB(size);
+			break;
+		case SNB_GMCH_GMS_STOLEN_160M:
+			gtt_entries = MB(160) - KB(size);
+			break;
+		case SNB_GMCH_GMS_STOLEN_192M:
+			gtt_entries = MB(192) - KB(size);
+			break;
+		case SNB_GMCH_GMS_STOLEN_224M:
+			gtt_entries = MB(224) - KB(size);
+			break;
+		case SNB_GMCH_GMS_STOLEN_256M:
+			gtt_entries = MB(256) - KB(size);
+			break;
+		case SNB_GMCH_GMS_STOLEN_288M:
+			gtt_entries = MB(288) - KB(size);
+			break;
+		case SNB_GMCH_GMS_STOLEN_320M:
+			gtt_entries = MB(320) - KB(size);
+			break;
+		case SNB_GMCH_GMS_STOLEN_352M:
+			gtt_entries = MB(352) - KB(size);
+			break;
+		case SNB_GMCH_GMS_STOLEN_384M:
+			gtt_entries = MB(384) - KB(size);
+			break;
+		case SNB_GMCH_GMS_STOLEN_416M:
+			gtt_entries = MB(416) - KB(size);
+			break;
+		case SNB_GMCH_GMS_STOLEN_448M:
+			gtt_entries = MB(448) - KB(size);
+			break;
+		case SNB_GMCH_GMS_STOLEN_480M:
+			gtt_entries = MB(480) - KB(size);
+			break;
+		case SNB_GMCH_GMS_STOLEN_512M:
+			gtt_entries = MB(512) - KB(size);
+			break;
+		}
 	} else {
 		switch (gmch_ctrl & I855_GMCH_GMS_MASK) {
 		case I855_GMCH_GMS_STOLEN_1M:
@@ -815,12 +915,6 @@ static void intel_i830_setup_flush(void)
 		intel_i830_fini_flush();
 }
 
-static void
-do_wbinvd(void *null)
-{
-	wbinvd();
-}
-
 /* The chipset_flush interface needs to get data that has already been
  * flushed out of the CPU all the way out to main memory, because the GPU
  * doesn't snoop those buffers.
@@ -837,12 +931,10 @@ static void intel_i830_chipset_flush(str
 
 	memset(pg, 0, 1024);
 
-	if (cpu_has_clflush) {
+	if (cpu_has_clflush)
 		clflush_cache_range(pg, 1024);
-	} else {
-		if (on_each_cpu(do_wbinvd, NULL, 1) != 0)
-			printk(KERN_ERR "Timed out waiting for cache flush.\n");
-	}
+	else if (wbinvd_on_all_cpus() != 0)
+		printk(KERN_ERR "Timed out waiting for cache flush.\n");
 }
 
 /* The intel i830 automatically initializes the agp aperture during POST.
@@ -1115,6 +1207,9 @@ static void intel_i9xx_setup_flush(void)
 	if (intel_private.ifp_resource.start)
 		return;
 
+	if (IS_SNB)
+		return;
+
 	/* setup a resource for this object */
 	intel_private.ifp_resource.name = "Intel Flush Page";
 	intel_private.ifp_resource.flags = IORESOURCE_MEM;
@@ -1353,6 +1448,8 @@ static unsigned long intel_i965_mask_mem
 
 static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
 {
+	u16 snb_gmch_ctl;
+
 	switch (agp_bridge->dev->device) {
 	case PCI_DEVICE_ID_INTEL_GM45_HB:
 	case PCI_DEVICE_ID_INTEL_EAGLELAKE_HB:
@@ -1366,6 +1463,25 @@ static void intel_i965_get_gtt_range(int
 	case PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB:
 		*gtt_offset = *gtt_size = MB(2);
 		break;
+	case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB:
+	case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB:
+		*gtt_offset = MB(2);
+
+		pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl);
+		switch (snb_gmch_ctl & SNB_GTT_SIZE_MASK) {
+		default:
+		case SNB_GTT_SIZE_0M:
+			printk(KERN_ERR "Bad GTT size mask: 0x%04x.\n", snb_gmch_ctl);
+			*gtt_size = MB(0);
+			break;
+		case SNB_GTT_SIZE_1M:
+			*gtt_size = MB(1);
+			break;
+		case SNB_GTT_SIZE_2M:
+			*gtt_size = MB(2);
+			break;
+		}
+		break;
 	default:
 		*gtt_offset = *gtt_size = KB(512);
 	}
@@ -1701,8 +1817,6 @@ static int intel_845_configure(void)
 	pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
 	/* clear any possible error conditions */
 	pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c);
-
-	intel_i830_setup_flush();
 	return 0;
 }
 
@@ -2072,7 +2186,6 @@ static const struct agp_bridge_driver in
 	.agp_destroy_page	= agp_generic_destroy_page,
 	.agp_destroy_pages      = agp_generic_destroy_pages,
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
-	.chipset_flush		= intel_i830_chipset_flush,
 };
 
 static const struct agp_bridge_driver intel_850_driver = {
@@ -2345,9 +2458,9 @@ 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_PINEVIEW_M_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG, 0, "Pineview",
+	{ PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG, 0, "GMA3150",
 		NULL, &intel_g33_driver },
-	{ PCI_DEVICE_ID_INTEL_PINEVIEW_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_IG, 0, "Pineview",
+	{ PCI_DEVICE_ID_INTEL_PINEVIEW_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_IG, 0, "GMA3150",
 		NULL, &intel_g33_driver },
 	{ PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0,
 	    "GM45", NULL, &intel_i965_driver },
@@ -2362,13 +2475,17 @@ static const struct intel_driver_descrip
 	{ PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, 0,
 	    "G41", NULL, &intel_i965_driver },
 	{ PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, 0,
-	    "Ironlake/D", NULL, &intel_i965_driver },
+	    "HD Graphics", NULL, &intel_i965_driver },
 	{ PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0,
-	    "Ironlake/M", NULL, &intel_i965_driver },
+	    "HD Graphics", NULL, &intel_i965_driver },
 	{ PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0,
-	    "Ironlake/MA", NULL, &intel_i965_driver },
+	    "HD Graphics", NULL, &intel_i965_driver },
 	{ PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0,
-	    "Ironlake/MC2", NULL, &intel_i965_driver },
+	    "HD Graphics", NULL, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG, 0,
+	    "Sandybridge", NULL, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG, 0,
+	    "Sandybridge", NULL, &intel_i965_driver },
 	{ 0, 0, 0, NULL, NULL, NULL }
 };
 
@@ -2378,7 +2495,7 @@ static int __devinit agp_intel_probe(str
 	struct agp_bridge_data *bridge;
 	u8 cap_ptr = 0;
 	struct resource *r;
-	int i;
+	int i, err;
 
 	cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
 
@@ -2470,7 +2587,10 @@ static int __devinit agp_intel_probe(str
 	}
 
 	pci_set_drvdata(pdev, bridge);
-	return agp_add_bridge(bridge);
+	err = agp_add_bridge(bridge);
+	if (!err)
+		intel_agp_enabled = 1;
+	return err;
 }
 
 static void __devexit agp_intel_remove(struct pci_dev *pdev)
@@ -2575,6 +2695,8 @@ static struct pci_device_id agp_intel_pc
 	ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB),
 	ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB),
 	ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),
+	ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB),
+	ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB),
 	{ }
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/agp/Kconfig linux-libre-2.6.34-gnu1/drivers/char/agp/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/char/agp/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/agp/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -57,7 +57,7 @@ config AGP_AMD
 
 config AGP_AMD64
 	tristate "AMD Opteron/Athlon64 on-CPU GART support"
-	depends on AGP && X86
+	depends on AGP && X86 && K8_NB
 	help
 	  This option gives you AGP support for the GLX component of
 	  X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs.
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/agp/nvidia-agp.c linux-libre-2.6.34-gnu1/drivers/char/agp/nvidia-agp.c
--- linux-libre-2.6.33-gnu1/drivers/char/agp/nvidia-agp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/agp/nvidia-agp.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,6 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/agp_backend.h>
-#include <linux/gfp.h>
 #include <linux/page-flags.h>
 #include <linux/mm.h>
 #include <linux/jiffies.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/agp/sgi-agp.c linux-libre-2.6.34-gnu1/drivers/char/agp/sgi-agp.c
--- linux-libre-2.6.33-gnu1/drivers/char/agp/sgi-agp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/agp/sgi-agp.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/acpi.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/agp_backend.h>
 #include <asm/sn/addrs.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/agp/uninorth-agp.c linux-libre-2.6.34-gnu1/drivers/char/agp/uninorth-agp.c
--- linux-libre-2.6.33-gnu1/drivers/char/agp/uninorth-agp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/agp/uninorth-agp.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
  */
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/pagemap.h>
 #include <linux/agp_backend.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/amiserial.c linux-libre-2.6.34-gnu1/drivers/char/amiserial.c
--- linux-libre-2.6.33-gnu1/drivers/char/amiserial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/amiserial.c	2010-05-16 17:17:36.000000000 -0400
@@ -2021,8 +2021,6 @@ static int __init rs_init(void)
 	state->baud_base = amiga_colorclock;
 	state->xmit_fifo_size = 1;
 
-	local_irq_save(flags);
-
 	/* set ISRs, and then disable the rx interrupts */
 	error = request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state);
 	if (error)
@@ -2033,6 +2031,8 @@ static int __init rs_init(void)
 	if (error)
 		goto fail_free_irq;
 
+	local_irq_save(flags);
+
 	/* turn off Rx and Tx interrupts */
 	custom.intena = IF_RBF | IF_TBE;
 	mb();
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/applicom.c linux-libre-2.6.34-gnu1/drivers/char/applicom.c
--- linux-libre-2.6.33-gnu1/drivers/char/applicom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/applicom.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,7 @@
 /* et passe en argument a acinit, mais est scrute sur le bus pour s'adapter  */
 /* au nombre de cartes presentes sur le bus. IOCL code 6 affichait V2.4.3    */
 /* F.LAFORSE 28/11/95 creation de fichiers acXX.o avec les differentes       */
-/* adresses de base des cartes, IOCTL 6 plus complet                         */
+/* addresses de base des cartes, IOCTL 6 plus complet                         */
 /* J.PAGET le 19/08/96 copie de la version V2.6 en V2.8.0 sans modification  */
 /* de code autre que le texte V2.6.1 en V2.8.0                               */
 /*****************************************************************************/
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/bfin_jtag_comm.c linux-libre-2.6.34-gnu1/drivers/char/bfin_jtag_comm.c
--- linux-libre-2.6.33-gnu1/drivers/char/bfin_jtag_comm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/bfin_jtag_comm.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/briq_panel.c linux-libre-2.6.34-gnu1/drivers/char/briq_panel.c
--- linux-libre-2.6.33-gnu1/drivers/char/briq_panel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/briq_panel.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
 #include <linux/kernel.h>
 #include <linux/wait.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/miscdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/bsr.c linux-libre-2.6.34-gnu1/drivers/char/bsr.c
--- linux-libre-2.6.33-gnu1/drivers/char/bsr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/bsr.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/cdev.h>
 #include <linux/list.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/ChangeLog linux-libre-2.6.34-gnu1/drivers/char/ChangeLog
--- linux-libre-2.6.33-gnu1/drivers/char/ChangeLog	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/ChangeLog	1969-12-31 19:00:00.000000000 -0500
@@ -1,775 +0,0 @@
-2001-08-11  Tim Waugh  <twaugh@redhat.com>
-
-	* serial.c (get_pci_port): Deal with awkward Titan cards.
-
-1998-08-26  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* serial.c (rs_open): Correctly decrement the module in-use count
-		on errors.
-
-Thu Feb 19 14:24:08 1998  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* tty_io.c (tty_name): Remove the non-reentrant (and non-SMP safe)
-		version of tty_name, and rename the reentrant _tty_name
-		function to be tty_name.
-		(tty_open): Add a warning message stating callout devices
-		are deprecated.
-
-Mon Dec  1 08:24:15 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* tty_io.c (tty_get_baud_rate): Print a warning syslog if the
-		tty->alt_speed kludge is used; this means the system is
-		using the deprecated SPD_HI ioctls.
-
-Mon Nov 24 10:37:49 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* serial.c, esp.c, rocket.c: Change drivers to take advantage of
-	 	tty_get_baud_rate().
-	
-	* tty_io.c (tty_get_baud_rate): New function which computes the
-		correct baud rate for the tty.  More factoring out of
-		common code out of the serial driver to the high-level tty
-		functions....
-
-Sat Nov 22 07:53:36 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* serial.c, esp.c, rocket.c: Add tty->driver.break() routine, and
- 		allow high-level tty code to handle the break and soft
- 		carrier ioctls.
-	
-	* tty_ioctl.c (n_tty_ioctl): Support TIOCGSOFTCAR and
- 		TIOCSSOFTCAR, so that device drivers don't have to support
- 		it.
-
-	* serial.c (autoconfig): Change 16750 test to hopefully eliminate
-		false results by people with strange 16550As being
-		detected as 16750s.  Hopefully 16750s will still be
-		detected as 16750, and other weird UARTs won't get poorly
-		autodetected.  If this doesn't work, I'll have to disable
-		the auto identification for the 16750.
-
-	* tty_io.c (tty_hangup): Now actually do the tty hangup
-		processing during the timer processing, and disable
-		interrupts while doing the hangup processing.  This avoids
-		several nasty race conditions which happened when the
-		hangup processing was done asynchronously.
-		(tty_ioctl): Do break handling in the tty driver if
-		driver's break function is supported.  
-		(tty_flip_buffer_push): New exported function which should
-		be used by drivers to push characters in the flip buffer
-		to the tty handler.  This may either be done using a task
-		queue function for better CPU efficiency, or directly for
-		low latency operation.
-
-	* serial.c (rs_set_termios): Fix bug rs_set_termios when
-		transitioning away from B0, submitted by Stanislav
-		Voronyi. 
-
-Thu Jun 19 20:05:58 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* serial.c (begin_break, end_break, rs_ioctl): Applied patch
-		to support BSD ioctls to set and clear the break
-		condition explicitly.
-
-	* console.c (scrup, scrdown, insert_line, delete_line): Applied
-		fix suggested by Aaron Tiensivu to speed up block scrolls
-		up and down.
-
-	* n_tty.c (opost_block, write_chan): Added a modified "fast
- 		console" patch which processes a block of text via
-		"cooking" efficiently.
-
-Wed Jun 18 15:25:50 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* tty_io.c (init_dev, release_dev): Applied fix suggested by Bill
-		Hawes to prevent race conditions in the tty code.
-
-	* n_tty.c (n_tty_chars_in_buffer): Applied fix suggested by Bill
-		Hawes so that n_tty_chars_in_buffer returns the correct
-		value in the case when the tty is in cannonical mode.  (To
-		avoid a pty deadlock with telnetd.)
-
-Thu Feb 27 01:53:08 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* serial.c (change_speed): Add support for the termios flag
-		CMSPAR, which allows the user to select stick parity.
-		(i.e, if PARODD is set, the parity bit is always 1; if
-		PARRODD is not set, then the parity bit is always 0).
-
-Wed Feb 26 19:03:10 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* serial.c (cleanup_module): Fix memory leak when using the serial
-		driver as a module; make sure tmp_buf gets freed!
-
-Tue Feb 25 11:01:59 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* serial.c (set_modem_info): Add support for setting and clearing
-		the OUT1 and OUT2 bits.  (For special case UART's, usually
-		for half-duplex.)
-		(autoconfig, change_speed): Fix TI 16750 support.
-
-Sun Feb 16 00:14:43 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* tty_io.c (release_dev): Add sanity check to make sure there are
-		no waiters on tty->read_wait or tty->write_wait.
-
-	* serial.c (rs_init): Don't autoconfig a device if the I/O region
-		is already reserved.
-
-	* serial.c (serial_proc_info): Add support for /proc/serial.
-
-Thu Feb 13 00:49:10 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* serial.c (receive_chars): When the UART repotrs an overrun
- 		condition, it does so with a valid character.  Changed to
- 		not throw away the valid character, but instead report the
-		overrun after the valid character.
-
-	* serial.c: Added new #ifdef's for some of the advanced serial
-		driver features.  A minimal driver that only supports COM
-		1/2/3/4 without sharing serial interrupts only takes 17k;
-		the full driver takes 32k.
-		
-Wed Feb 12 14:50:44 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* vt.c:
-	* pty.c: 
-	* tty_ioctl.c: 
-	* serial.c: Update routines to use the new 2.1 memory access
-	 	routines.
-
-Wed Dec  4 07:51:52 1996  Theodore Ts'o  <tytso@localhost.mit.edu>
-
-	* serial.c (change_speed): Use save_flags(); cli() and
-		restore_flags() in order to ensure we don't accidentally
-		turn on interrupts when starting up the port.
-		(startup): Move the insertion of serial structure into the
-		IRQ chain earlier into the startup processing.  Interrupts
-		should be off this whole time, but we eventually will want
-		to reduce this window.
-
-Thu Nov 21 10:05:22 1996  Theodore Ts'o  <tytso@localhost.mit.edu>
-
-	* tty_ioctl.c (tty_wait_until_sent): Always check the driver
- 		wait_until_ready routine, even if there are no characters
- 		in the xmit buffer.  (There may be charactes in the device
- 		FIFO.)
-		(n_tty_ioctl): Add new flag tty->flow_stopped which
- 		indicates whether the tty is stopped due to a request by
- 		the TCXONC ioctl (used by tcflow).  If so, don't let an
- 		incoming XOFF character restart the tty.  The tty can only
- 		be restarted by another TCXONC request.
-
-	* tty_io.c (start_tty): Don't allow the tty to be restarted if
-		tty->flow_stopped is true.
-
-	* n_tty.c (n_tty_receive_char): If tty->flow_stopped is true, and
- 		IXANY is set, don't eat a character trying to restart the
- 		tty.
-
-	* serial.c (startup): Remove need for MCR_noint from the
- 		async_struct structure.  Only turn on DTR and RTS if the
- 		baud rate is not zero.
-		(change_speed): More accurately calculate the timeout
- 		value based on the word size.  Move responsibility of
- 		hangup when speed becomes B0 to rs_set_termios()
-		(set_serial_info): When changing the UART type set the
- 		current xmit_fifo_size as well as the permanent
- 		xmit_fifo_size.
-		(rs_ioctl): Fix TCSBRK (used by tcdrain) and TCSBRKP
- 		ioctls to return EINTR if interrupted by a signal.
-		(rs_set_termios): If the baud rate changes to or from B0,
- 		this function is now responsible for setting or clearing
- 		DTR and RTS.  DTR and RTS are only be changed on the
- 		transition to or from the B0 state.
-		(rs_close): Wait for the characters to drain based on
- 		info->timeout.  At low baud rates (50 bps), it may take a
- 		long time for the FIFO to completely drain out!
-		(rs_wait_until_sent): Fixed timeout handling.  Now
- 		releases control to the scheduler, but checks frequently
- 		enough so that the function is sensitive enough to pass
- 		the timing requirements of the NIST-PCTS.
-		(block_til_ready): When opening the device, don't turn on
- 		DTR and RTS if the baud rate is B0.
-
-Thu Nov 14 00:06:09 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* serial.c (autoconfig): Fix autoconfiguration problems;
-		info->flags wasn't getting initialized from the state
-		structure.  Put in more paranoid test for the 16750.
-
-Fri Nov  8 20:19:50 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* n_tty.c (n_tty_flush_buffer): Only call driver->unthrottle() if
- 		the tty was previous throttled.
-		(n_tty_set_termios, write_chan): Add changes suggested by
- 			Simon P. Allen to allow hardware cooking.
-
-	* tty_ioctl.c (set_termios): If we get a signal while waiting for
-		the tty to drain, return -EINTR.
-	
-	* serial.c (change_speed): Add support for CREAD, as required by
-	 	POSIX.
-
-Sat Nov  2 20:43:10 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* serial.c: Wholesale changes.  Added support for the Startech
- 		16650 and 16650V2 chips.  (WARNING: the new startech
- 		16650A may or may not work!)  Added support for the
- 		TI16750 (not yet tested).  Split async_struct into a
- 		transient part (async_struct) and a permanent part
-		(serial_state) which contains the configuration
- 		information for the ports.  Added new driver routines
- 		wait_until_sent() and send_xchar() to help with POSIX
- 		compliance.  Added support for radio clocks which waggle
-		the carrier detect line (CONFIG_HARD_PPS).
-	
-	* tty_ioctl.c (tty_wait_until_sent): Added call to new driver
-		function tty->driver.wait_until_sent(), which returns when
-		the tty's device xmit buffers are drained.  Needed for
-		full POSIX compliance.
-
-		(send_prio_char): New function, called by the ioctl's
-		TCIOFF and TCION; uses the new driver call send_xchar(),
-		which will send the XON or XOFF character at high priority
-		(and even if tty output is stopped).
-
-Wed Jun  5 18:52:04 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* pty.c (pty_close): When closing a pty, make sure packet mode is
-	 	cleared.
-
-Sun May 26 09:33:52 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* vesa_blank.c (set_vesa_blanking): Add missing verify_area() call.
-
-	* selection.c (set_selection): Add missing verify_area() call.
-
-	* tty_io.c (tty_ioctl): Add missing verify_area() calls.
-
-	* serial.c (rs_ioctl): Add missing verify_area() calls.
-		(rs_init): Allow initialization of serial driver
-		configuration from a module.
-
-	* random.c (extract_entropy): Add missing verify_area call.
-		Don't limit number of characters returned to
-		32,768. Extract entropy is now no longer a inlined
-		function.
-
-		(random_read): Check return value in case extract_entropy
-		returns an error.
-
-		(secure_tcp_sequence_number): New function which returns a
-		secure TCP sequence number.  This is needed to prevent some
-		nasty TCP hijacking attacks.
-	
-		(init_std_data): Initialize using gettimeofday() instead of
-		struct timeval xtime.
-
-		(fast_add_entropy_word, add_entropy_word): Rename the
-		inline function add_entropy_word() to
-		fast_add_entropy_word().  Make add_entropy_word() be the
-		non-inlined function which is used in non-timing critical
-		places, in order to save space.
-
-		(initialize_benchmark, begin_benchmark, end_benchmark): New
-		functions defined when RANDOM_BENCHMARK is defined.  They
-		allow us to benchmark the speed of the
-		add_timer_randomness() call.
-
-		(int_ln, rotate_left): Add two new inline functions with
-		i386 optimized asm instructions.  This speeds up the
-		critical add_entropy_word() and add_timer_randomness()
-		functions, which are called from interrupt handlers.
-
-Tue May  7 22:51:11 1996    <tytso@rsts-11.mit.edu>
-
-	* random.c (add_timer_randomness): Limit the amount randomness
-		that we estimate to 12 bits.  (An arbitrary amount).
-
-		(extract_entropy): To make it harder to analyze the hash
-		function, fold the hash function in half using XOR, and
-		use the folded result as the value to emit to the user.
-		Also, add timer randomness each pass through the
-		exact_entropy call, to increase the amount of unknown
-		values during the extraction process.
-
-		(random_ioctl): Use IOR/IOW definitions to define the
-		ioctl values used by the /dev/random driver.  Allow the
-		old ioctl values to be used for backwards compatibility
-		(for a limited amount of time).
-
-Wed Apr 24 14:02:04 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-
-	* random.c (add_timer_randomness): Use 2nd derivative as well to
-		better estimate entropy.
-
-		(rand_initialize): Explicitly initialize all the pointers
-		to NULL.  (Clearing pointers using memset isn't portable.)
-		Initialize the random pool with OS-dependent data.
-
-		(random_write): Add sanity checking to the arguments to
-		random_write(), so that bad arguments won't cause a kernel
-		SEGV. 
-
-		(random_read): Update the access time of the device inode
-		when you return data to the user.
-
-		(random_ioctl): Wake up the random_wait channel when there
-		are only WAIT_INPUT_BITS available.  Add more paranoia
-		checks to make sure entropy_count doesn't go beyond the
-		bounds of (0, POOLSIZE).  Add a few missing verify_area
-		checks.  Add support for the RNDCLEARPOOL ioctl, which
-		zaps the random pool.
-
-		(add_timer_randomness): Wake up the random_wait
-		channel only when there are WAIT_INPUT_BITS available.
-
-		(random_select): Allow a random refresh daemon process to
-		select on /dev/random for writing; wake up the daemon when
-		there are less than WAIT_OUTPUT_BITS bits of randomness
-		available.
-
-Tue Apr 23 22:56:07 1996    <tytso@rsts-11.mit.edu>
-
-	* tty_io.c (init_dev): Change return code when user attempts to
-		open master pty which is already open from EAGAIN to EIO,
-		to match with BSD expectations.  EIO is more correct
-		anyway, since EAGAIN implies that retrying will be
-		successful --- which it might be.... Eventually!!
-
-	* pty.c (pty_open, pty_close): Fix wait loop so that we don't
-		busy loop while waiting for the master side to open.
-		Fix tty opening/closing logic.  TTY_SLAVE_CLOSED was
-		renamed to TTY_OTHER_CLOSED, so that the name is more
-		descriptive.  Also fixed code so that the tty flag
-		actually works correctly now....
-
-Mon Apr  1 10:22:01 1996    <tytso@rsts-11.mit.edu>
-
-	* serial.c (rs_close): Cleaned up modularization changes.
-		Remove code which forced line discipline back to N_TTY
-		this is done in the tty upper layers, and there's no
-		reason to do it here.  (Making this change also
-		removed the requirement that the serial module access
-		the internal kernel symbol "ldiscs".)
-
-	* tty_io.c (tty_init): Formally register a tty_driver entry for
-		/dev/tty (device 4, 0) and /dev/console (device 5, 0).
-		This guarantees that major device numbers 4 and 5 will be
-		reserved for the tty subsystem (as they have to be because
-		of /dev/tty and /dev/console).  Removed tty_regdev, as
-		this interface is no longer necessary.
-
-Sun Mar 17 20:42:47 GMT 1996 <ah@doc.ic.ac.uk>
-
-	* serial.c : modularisation (changes in linux/fs/device.c allow
-		kerneld to automatically load the serial module).
-
-	* Makefile, Config.in : serial modularisation adds.
-
-	* tty_io.c : tty_init_ctty used by to register "cua" driver just
-		for the /dev/tty device (5,0).  Added tty_regdev.
-	
-	* serial.c (shutdown, rs_ioctl) : when port shuts down wakeup processes
-	  waiting on delta_msr_wait. The TIOCMIWAIT ioctl returns EIO
-	  if no change was done since the time of call.
-
-Sat Mar 16 14:33:13 1996 <aeb@cwi.nl>
-
-	* tty_io.c (disassociate_ctty): If disassociate_ctty is called by
-		exit, do not perform an implicit vhangup on a pty.
-
-Fri Feb  9 14:15:47 1996    <tytso@rsts-11.mit.edu>
-
-	* serial.c (block_til_ready): Fixed another race condition which
-		happens if a hangup happens during the open.
-
-Wed Jan 10 10:08:00 1996    <tytso@rsts-11.mit.edu>
-
-	* serial.c (block_til_ready): Remove race condition which happened
-		if a hangup condition happened during the setup of the
-		UART, before rs_open() called block_til_ready().  This
-		caused the info->count counter to be erroneously
-		decremented.
-
-	* serial.c (startup, rs_open): Remove race condition that could
-		cause a memory leak of one page.  (Fortunately, both race
-		conditions were relatively rare in practice.)
-
-Tue Dec  5 13:21:27 1995    <tytso@rsts-11.mit.edu>
-
-	* serial.c (check_modem_status, rs_ioctl): Support the new
-		ioctl()'s TIOCGICOUNT, TIOCMIWAIT.  These allow an
-		application program to wait on a modem serial register
-		status bit change, and to find out how many changes have
-		taken place for the MSR bits.
-
-		(rs_write): Eliminate a race condition which is introduced
-		if it is necessary to wait for the semaphore.
-
-Sat Nov  4 17:14:45 1995    <tytso@rsts-11.mit.edu>
-
-	* tty_io.c (tty_init): Move registration of TTY_MAJOR and
-		TTY_AUX_MAJOR to the end, so that /proc/devices looks
-		prettier. 
-
-	* pty.c (pty_init): Use new major numbers for PTY master and slave
-		devices.  This allow us to have more than 64 pty's.  We
-		register the old pty devices for backwards compatibility.
-		Note that a system should either be using the old pty
-		devices or the new pty devices --- in general, it should
-		try to use both, since they map into the same pty table.
-		The old pty devices are strictly for backwards compatibility.
-
-Wed Oct 11 12:45:24 1995    <tytso@rsts-11.mit.edu>
-
-	* tty_io.c (disassociate_ctty): If disassociate_ctty is called by
-		exit, perform an implicit vhangup on the tty.
-
-	* pty.c (pty_close): When the master pty is closed, send a hangup
-		to the slave pty.
-		(pty_open): Use the flag TTY_SLAVE_CLOSED to test to see
-		if there are any open slave ptys, instead of using
-		tty->link->count.  The old method got confused if there
-		were processes that had hung-up file descriptors on the
-		slave tty.
-
-Tue May  2 00:53:25 1995    <tytso@rsx-11.mit.edu>
-
-	* tty_io.c (tty_set_ldisc): Wait until the output buffer is
-		drained before closing the old line discipline --- needed
-		in only one case: XON/XOFF processing.
-
-	* n_tty.c (n_tty_close): Don't bother waiting until the output
-		driver is closed; in general, the line discipline
-		shouldn't care if the hardware is finished
-		transmitting before the line discipline terminates.
-
-	* tty_io.c (release_dev): Shutdown the line discipline after
-		decrementing the tty count variable; but set the
-		TTY_CLOSING flag so that we know that this tty structure
-		isn't long for this world.
-
-	* tty_io.c (init_dev): Add sanity code to check to see if
-		TTY_CLOSING is set on a tty structure; if so, something
-		bad has happened (probably a line discipline close blocked
-		when it shouldn't have; so do a kernel printk and then
-		return an error).
-
-Wed Apr 26 10:23:44 1995  Theodore Y. Ts'o  <tytso@localhost>
-
-	* tty_io.c (release_dev): Try to shutdown the line discipline
-		*before* decrementing the tty count variable; this removes
-		a potential race condition which occurs when the line
-		discipline close blocks, and another process then tries
-		open the same serial port.
-
-	* serial.c (rs_hangup): When hanging up, flush the output buffer
-		before shutting down the UART.  Otherwise the line
-		discipline close blocks waiting for the characters to get
-		flushed, which never happens until the serial port gets reused.
-
-Wed Apr 12 08:06:16 1995  Theodore Y. Ts'o  <tytso@localhost>
-
-	* serial.c (do_serial_hangup, do_softint, check_modem_status,
-		rs_init):  Hangups are now scheduled via a separate tqueue
-		structure in the async_struct structure, tqueue_hangup.
-		This task is pushed on to the tq_schedule queue, so that
-		it is processed synchronously by the scheduler.
-
-Sat Feb 18 12:13:51 1995  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* tty_io.c (disassociate_ctty, tty_open, tty_ioctl): Clear
-		current->tty_old_pgrp field when a session leader
-		acquires a controlling tty, and after a session leader
-		has disassociated from a controlling tty.
-
-Fri Feb 17 09:34:09 1995  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* serial.c (rs_interrupt_single, rs_interrupt, rs_interrupt_multi): 
-		Change the number of passes made from 64 to be 256,
-		configurable with the #define RS_ISR_PASS_LIMIT.
-
-	* serial.c (rs_init, set_serial_info, get_serial_info, rs_close):
-		Remove support for closing_wait2.  Instead, set
-		tty->closing and rely on the line discipline to prevent
-		echo wars.
-
-	* n_tty.c (n_tty_receive_char):  IEXTEN does not need to be
-		enabled in order for IXANY to be active.
-
-		If tty->closing is set, then only process XON and XOFF
-                characters.
-
-Sun Feb 12 23:57:48 1995  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* serial.c (rs_timer): Change the interrupt poll time from 60
-		seconds to 10 seconds, configurable with the #define
-		RS_STROBE_TIME.
-
-	* serial.c (rs_interrupt_multi, startup, shutdown, rs_ioctl,
-		set_multiport_struct, get_multiport_struct): Add
-		provisions for a new type of interrupt service routine,
-		which better supports multiple serial ports on a single
-		IRQ.  
-
-Sun Feb  5 19:35:11 1995  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* tty_ioctl.c (n_tty_ioctl, set_termios, tty_wait_until_sent): 
-	* serial.c (rs_ioctl, rs_close): 
-	* cyclades.c (cy_ioctl, cy_close): 
-	* n_tty.c (n_tty_close):  Rename wait_until_sent to
-		tty_wait_until_sent, so that it's a better name to export
-		in ksyms.c.
-
-Sat Feb  4 23:36:20 1995  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* serial.c (rs_close): Added missing check for closing_wait2 being
-		ASYNC_CLOSING_WAIT_NONE.
-
-Thu Jan 26 09:02:49 1995  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* serial.c (rs_init, set_serial_info, get_serial_info,
-		rs_close): Support close_wait in the serial driver.
-		This is helpful for slow devices (like serial
-		plotters) so that their outputs don't get flushed upon
-		device close.  This has to be configurable because
-		normally we don't want ports to be hung up for long
-		periods of time during a close when they are not
-		connected to a device, or the device is powered off.
-
-		The default is to wait 30 seconds; in the case of a
-		very slow device, the close_wait timeout should be
-		lengthened.  If it is set to 0, the kernel will wait
-		forever for all of the data to be transmitted.
-
-Thu Jan 17 01:17:20 1995  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* serial.c (startup, change_speed, rs_init): Add support to detect
-		the StarTech 16650 chip.  Treat it as a 16450 for now,
-		because of its FIFO bugs.
-
-Thu Jan  5 21:21:57 1995  <dahinds@users.sourceforge.net>
-
-	* serial.c: (receive_char): Added counter to prevent infinite loop
-		when a PCMCIA serial device is ejected.
-
-Thu Dec 29 17:53:48 1994    <tytso@rsx-11.mit.edu>
-
-	* tty_io.c (check_tty_count): New procedure which checks
-		tty->count to make sure that it matches with the number of
-		open file descriptors which point at the structure.  If
-		the number doesn't match, it prints a warning message.
-
-Wed Dec 28 15:41:51 1994    <tytso@rsx-11.mit.edu>
-
-	* tty_io.c (do_tty_hangup, disassociate_ctty): At hangup time,
-		save the tty's current foreground process group in the
-		session leader's task structure.  When the session leader
-		terminates, send a SIGHUP, SIGCONT to that process group.
-		This is not required by POSIX, but it's not prohibited
-		either, and it appears to be the least intrusive way
-		to fix a problem that dialup servers have with
-		orphaned process groups caused by modem hangups.
-
-Thu Dec  8 14:52:11 1994    <tytso@rsx-11.mit.edu>
-
-	* serial.c (rs_ioctl): Don't allow most ioctl's if the serial port
-		isn't initialized.
-
-	* serial.c (rs_close): Don't clear the IER if the serial port
-		isn't initialized. 
-
-	* serial.c (block_til_ready): Don't try to block on the dialin
-		port if the serial port isn't initialized.
-
-Wed Dec  7 10:48:30 1994  Si Park (si@wimpol.demon.co.uk)
-	* tty_io.c (tty_register_driver): Fix bug when linking onto
-		the tty_drivers list. We now test that there are elements
-		already on the list before setting the back link from the
-		first element to the new driver.
-
-	* tty_io.c (tty_unregister_driver): Fix bug in unlinking the
-		specified driver from the tty_drivers list. We were not
-		setting the back link correctly. This used to result in
-		a dangling back link pointer and cause panics on the next
-		call to get_tty_driver().
-
-Tue Nov 29 10:21:09 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* tty_io.c (tty_unregister_driver): Fix bug in
-		tty_unregister_driver where the pointer to the refcount is
-		tested, instead of the refcount itself.  This caused
-		tty_unregister_driver to always return EBUSY.
-
-Sat Nov 26 11:59:24 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* tty_io.c (tty_ioctl): Add support for the new ioctl
-		TIOCTTYGSTRUCT, which allow a kernel debugging program
-		direct read access to the tty and tty_driver structures.
-
-Fri Nov 25 17:26:22 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* serial.c (rs_set_termios): Don't wake up processes blocked in
-		open when the CLOCAL flag changes, since a blocking
-		open only samples the CLOCAL flag once when it blocks,
-		and doesn't check it again.  (n.b.  FreeBSD has a
-		different behavior for blocking opens; it's not clear
-		whether Linux or FreeBSD's interpretation is correct.
-		POSIX doesn't give clear guidance on this issue, so
-		this may change in the future....)
-
-	* serial.c (block_til_ready): Use the correct termios structure to
-		check the CLOCAL flag.  If the cuaXX device is active,
-		then check the saved termios for the ttySXX device.
-		Otherwise, use the currently active termios structure.
-
-Sun Nov  6 21:05:44 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* serial.c (change_speed): Add support for direct access of
-		57,600 and 115,200 bps.
-
-Wed Nov  2 10:32:36 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* n_tty.c (n_tty_receive_room): Only allow excess characters
-		through if we are in ICANON mode *and* there are other no
-		pending lines in the buffer.  Otherwise cut and paste over
-		4k breaks.
-
-Sat Oct 29 18:17:34 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* serial.c (rs_ioctl, get_lsr_info): Added patch suggested by Arne
-		Riiber so that user mode programs can tell when the
-		transmitter shift register is empty.
-
-Thu Oct 27 23:14:29 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* tty_ioctl.c (wait_until_sent): Added debugging printk statements
-		(under the #ifdef TTY_DEBUG_WAIT_UNTIL_SENT)  
-
-	* serial.c (rs_interrupt, rs_interrupt_single, receive_chars,
-		change_speed, rs_close): rs_close now disables receiver
-		interrupts when closing the serial port.  This allows the
-		serial port to close quickly when Linux and a modem (or a
-		mouse) are engaged in an echo war; when closing the serial
-		port, we now first stop listening to incoming characters,
-		and *then* wait for the transmit buffer to drain.  
-
-		In order to make this change, the info->read_status_mask
-		is now used to control what bits of the line status
-		register are looked at in the interrupt routine in all
-		cases; previously it was only used in receive_chars to
-		select a few of the status bits.
-
-Mon Oct 24 23:36:21 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* serial.c (rs_close): Add a timeout to the transmitter flush
-		loop; this is just a sanity check in case we have flaky
-		(or non-existent-but-configured-by-the-user) hardware.
-
-Fri Oct 21 09:37:23 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* tty_io.c (tty_fasync): When asynchronous I/O is enabled, if the
-		process or process group has not be specified yet, set it
-		to be the tty's process group, or if that is not yet set,
-		to the current process's pid.
-
-Thu Oct 20 23:17:28 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* n_tty.c (n_tty_receive_room): If we are doing input
-		canonicalization, let as many characters through as
-		possible, so that the excess characters can be "beeped".
-
-Tue Oct 18 10:02:43 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* serial.c (rs_start): Removed an incorrect '!' that was
-		preventing transmit interrupts from being re-enabled in
-		rs_start().  Fortunately in most cases it would be
-		re-enabled elsewhere, but this still should be fixed
-		correctly.
-
-Sun Oct  9 23:46:03 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* tty_io.c (do_tty_hangup): If the tty driver flags
-		TTY_DRIVER_RESET_TERMIOS is set, then reset the termios
-		settings back to the driver's initial configuration.  This
-		allows the termios settings to be reset even if a process
-		has hung up file descriptors keeping a pty's termios from
-		being freed and reset.
-
-	* tty_io.c (release_dev): Fix memory leak.  The pty's other
-		termios structure should also be freed.
-
-	* serial.c (rs_close, shutdown): Change how we wait for the
-		transmitter to completely drain before shutting down the
-		serial port.  We now do it by scheduling in another
-		process instead of busy looping with the interrupts turned
-		on.  This may eliminate some race condition problems that
-		some people seem to be reporting.
-
-Sun Sep 25 14:18:14 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* tty_io.c (release_dev): When freeing a tty make sure that both
-		the tty and the o_tty (if present) aren't a process's
-		controlling tty.  (Previously, we only checked the tty.)
-
-	* serial.c (change_speed): Only enable the Modem Status
-		Interrupt for a port if CLOCAL is not set or CRTSCTS
-		is set.  If we're not checking the carrier detect and
-		CTS line, there's no point in enabling the modem
-		status interrupt.  This will save spurious interrupts
-		from slowing down systems who have terminals that
-		don't support either line.  (Of course, if you want
-		only one of CD and CTS support, you will need a
-		properly wired serial cable.)
-
-Thu Sep 22 08:32:48 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* tty_io.c (do_SAK): Return if tty is null.
-
-	* tty_io.c (_tty_name): Return "NULL tty" if the passed in tty is
-		NULL.
-
-Sat Sep 17 13:19:25 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* tty_ioctl.c (n_tty_ioctl): Fix TIOCGLCKTRMIOS and
-		TIOCSLCKTRMIOS, which were totally broken.  Remove
-		extra indirection from argument; it should be a struct
-		termios *, not a struct termios **.
-		&real_tty->termios_locked should have been
-		real_tty->termios_locked.  This caused us to be
-		reading and writing the termios_locked structure to
-		random places in kernel memory.  
-
-	* tty_io.c (release_dev): Oops!  Forgot to delete a critical kfree
-		of the locked_termios.  This leaves the locked_termios
-		structure pointed at a freed object.  
-
-Fri Sep 16 08:13:25 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* tty_io.c (tty_open): Don't check for an exclusive open until
-		after the device specific open routine has been called.
-		Otherwise, the serial device ref counting will be screwed
-		up.
-
-	* serial.c (rs_open, block_til_ready): Don't set termios structure
-		until after block_til_ready has returned successfully.
-		Modify block_til_ready to check the normal_termios
-		structure directly, so it doesn't rely on termios being
-		set before it's called.
-
-Thu Sep 15 23:34:01 1994  Theodore Y. Ts'o  (tytso@rt-11)
-
-	* serial.c (rs_close): Turn off interrupts during rs_close() to
-		prevent a race condition with the hangup code (which
-		runs during a software interrupt).
-
-	* tty_io.c (release_dev): Don't free the locked_termios structure;
-		its state must be retained across device opens.
-
-
-	* tty_io.c (tty_unregister_driver): Added function to unregister a
-		tty driver.  (For loadable device drivers.)
-
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/cyclades.c linux-libre-2.6.34-gnu1/drivers/char/cyclades.c
--- linux-libre-2.6.33-gnu1/drivers/char/cyclades.c	2013-05-03 12:03:11.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/char/cyclades.c	2013-05-03 09:44:15.000000000 -0400
@@ -79,6 +79,7 @@
 #include <linux/bitops.h>
 #include <linux/firmware.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 
 #include <linux/io.h>
 #include <linux/uaccess.h>
@@ -158,13 +159,11 @@ static unsigned int cy_isa_addresses[] =
 
 #define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses)
 
-#ifdef MODULE
 static long maddr[NR_CARDS];
 static int irq[NR_CARDS];
 
 module_param_array(maddr, long, NULL, 0);
 module_param_array(irq, int, NULL, 0);
-#endif
 
 #endif				/* CONFIG_ISA */
 
@@ -598,12 +597,6 @@ static void cyy_chip_tx(struct cyclades_
 	save_car = readb(base_addr + (CyCAR << index));
 	cy_writeb(base_addr + (CyCAR << index), save_xir);
 
-	/* validate the port# (as configured and open) */
-	if (channel + chip * 4 >= cinfo->nports) {
-		cy_writeb(base_addr + (CySRER << index),
-			  readb(base_addr + (CySRER << index)) & ~CyTxRdy);
-		goto end;
-	}
 	info = &cinfo->ports[channel + chip * 4];
 	tty = tty_port_tty_get(&info->port);
 	if (tty == NULL) {
@@ -3316,13 +3309,10 @@ static int __init cy_detect_isa(void)
 	unsigned short cy_isa_irq, nboard;
 	void __iomem *cy_isa_address;
 	unsigned short i, j, cy_isa_nchan;
-#ifdef MODULE
 	int isparam = 0;
-#endif
 
 	nboard = 0;
 
-#ifdef MODULE
 	/* Check for module parameters */
 	for (i = 0; i < NR_CARDS; i++) {
 		if (maddr[i] || i) {
@@ -3332,7 +3322,6 @@ static int __init cy_detect_isa(void)
 		if (!maddr[i])
 			break;
 	}
-#endif
 
 	/* scan the address table probing for Cyclom-Y/ISA boards */
 	for (i = 0; i < NR_ISA_ADDRS; i++) {
@@ -3353,11 +3342,10 @@ static int __init cy_detect_isa(void)
 			iounmap(cy_isa_address);
 			continue;
 		}
-#ifdef MODULE
+
 		if (isparam && i < NR_CARDS && irq[i])
 			cy_isa_irq = irq[i];
 		else
-#endif
 			/* find out the board's irq by probing */
 			cy_isa_irq = detect_isa_irq(cy_isa_address);
 		if (cy_isa_irq == 0) {
@@ -4208,3 +4196,4 @@ module_exit(cy_cleanup_module);
 MODULE_LICENSE("GPL");
 MODULE_VERSION(CY_VERSION);
 MODULE_ALIAS_CHARDEV_MAJOR(CYCLADES_MAJOR);
+/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/dsp56k.c linux-libre-2.6.34-gnu1/drivers/char/dsp56k.c
--- linux-libre-2.6.33-gnu1/drivers/char/dsp56k.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/dsp56k.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/slab.h>	/* for kmalloc() and kfree() */
 #include <linux/major.h>
 #include <linux/types.h>
 #include <linux/errno.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/epca.c linux-libre-2.6.34-gnu1/drivers/char/epca.c
--- linux-libre-2.6.33-gnu1/drivers/char/epca.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/epca.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,7 +36,6 @@
 #include <linux/ctype.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
-#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/generic_serial.c linux-libre-2.6.34-gnu1/drivers/char/generic_serial.c
--- linux-libre-2.6.33-gnu1/drivers/char/generic_serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/generic_serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/interrupt.h>
 #include <linux/tty_flip.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 
 #define DEBUG 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hpet.c linux-libre-2.6.34-gnu1/drivers/char/hpet.c
--- linux-libre-2.6.33-gnu1/drivers/char/hpet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hpet.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/seq_file.h>
 #include <linux/bitops.h>
 #include <linux/clocksource.h>
+#include <linux/slab.h>
 
 #include <asm/current.h>
 #include <asm/uaccess.h>
@@ -215,9 +216,7 @@ static void hpet_timer_set_irq(struct hp
 	else
 		v &= ~0xffff;
 
-	for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ;
-		irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) {
-
+	for_each_set_bit(irq, &v, HPET_MAX_IRQ) {
 		if (irq >= nr_irqs) {
 			irq = HPET_MAX_IRQ;
 			break;
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hvc_beat.c linux-libre-2.6.34-gnu1/drivers/char/hvc_beat.c
--- linux-libre-2.6.33-gnu1/drivers/char/hvc_beat.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hvc_beat.c	2010-05-16 17:17:36.000000000 -0400
@@ -84,7 +84,7 @@ static int hvc_beat_put_chars(uint32_t v
 	return cnt;
 }
 
-static struct hv_ops hvc_beat_get_put_ops = {
+static const struct hv_ops hvc_beat_get_put_ops = {
 	.get_chars = hvc_beat_get_chars,
 	.put_chars = hvc_beat_put_chars,
 };
@@ -99,7 +99,7 @@ static int hvc_beat_config(char *p)
 
 static int __init hvc_beat_console_init(void)
 {
-	if (hvc_beat_useit && machine_is_compatible("Beat")) {
+	if (hvc_beat_useit && of_machine_is_compatible("Beat")) {
 		hvc_instantiate(0, 0, &hvc_beat_get_put_ops);
 	}
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hvc_console.c linux-libre-2.6.34-gnu1/drivers/char/hvc_console.c
--- linux-libre-2.6.33-gnu1/drivers/char/hvc_console.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hvc_console.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/spinlock.h>
 #include <linux/delay.h>
 #include <linux/freezer.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
@@ -125,7 +126,7 @@ static struct hvc_struct *hvc_get_by_ind
  * console interfaces but can still be used as a tty device.  This has to be
  * static because kmalloc will not work during early console init.
  */
-static struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES];
+static const struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES];
 static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
 	{[0 ... MAX_NR_HVC_CONSOLES - 1] = -1};
 
@@ -146,7 +147,7 @@ static void hvc_console_print(struct con
 		return;
 
 	/* This console adapter was removed so it is not usable. */
-	if (vtermnos[index] < 0)
+	if (vtermnos[index] == -1)
 		return;
 
 	while (count > 0 || i > 0) {
@@ -247,7 +248,7 @@ static void destroy_hvc_struct(struct kr
  * vty adapters do NOT get an hvc_instantiate() callback since they
  * appear after early console init.
  */
-int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops)
+int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops)
 {
 	struct hvc_struct *hp;
 
@@ -312,6 +313,7 @@ static int hvc_open(struct tty_struct *t
 	spin_lock_irqsave(&hp->lock, flags);
 	/* Check and then increment for fast path open. */
 	if (hp->count++ > 0) {
+		tty_kref_get(tty);
 		spin_unlock_irqrestore(&hp->lock, flags);
 		hvc_kick();
 		return 0;
@@ -319,7 +321,7 @@ static int hvc_open(struct tty_struct *t
 
 	tty->driver_data = hp;
 
-	hp->tty = tty;
+	hp->tty = tty_kref_get(tty);
 
 	spin_unlock_irqrestore(&hp->lock, flags);
 
@@ -336,6 +338,7 @@ static int hvc_open(struct tty_struct *t
 		spin_lock_irqsave(&hp->lock, flags);
 		hp->tty = NULL;
 		spin_unlock_irqrestore(&hp->lock, flags);
+		tty_kref_put(tty);
 		tty->driver_data = NULL;
 		kref_put(&hp->kref, destroy_hvc_struct);
 		printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
@@ -363,6 +366,7 @@ static void hvc_close(struct tty_struct
 		return;
 
 	hp = tty->driver_data;
+
 	spin_lock_irqsave(&hp->lock, flags);
 
 	if (--hp->count == 0) {
@@ -389,6 +393,7 @@ static void hvc_close(struct tty_struct
 		spin_unlock_irqrestore(&hp->lock, flags);
 	}
 
+	tty_kref_put(tty);
 	kref_put(&hp->kref, destroy_hvc_struct);
 }
 
@@ -424,10 +429,11 @@ static void hvc_hangup(struct tty_struct
 	spin_unlock_irqrestore(&hp->lock, flags);
 
 	if (hp->ops->notifier_hangup)
-			hp->ops->notifier_hangup(hp, hp->data);
+		hp->ops->notifier_hangup(hp, hp->data);
 
 	while(temp_open_count) {
 		--temp_open_count;
+		tty_kref_put(tty);
 		kref_put(&hp->kref, destroy_hvc_struct);
 	}
 }
@@ -592,7 +598,7 @@ int hvc_poll(struct hvc_struct *hp)
 	}
 
 	/* No tty attached, just skip */
-	tty = hp->tty;
+	tty = tty_kref_get(hp->tty);
 	if (tty == NULL)
 		goto bail;
 
@@ -672,6 +678,8 @@ int hvc_poll(struct hvc_struct *hp)
 
 		tty_flip_buffer_push(tty);
 	}
+	if (tty)
+		tty_kref_put(tty);
 
 	return poll_mask;
 }
@@ -748,8 +756,9 @@ static const struct tty_operations hvc_o
 	.chars_in_buffer = hvc_chars_in_buffer,
 };
 
-struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data,
-					struct hv_ops *ops, int outbuf_size)
+struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
+			     const struct hv_ops *ops,
+			     int outbuf_size)
 {
 	struct hvc_struct *hp;
 	int i;
@@ -806,7 +815,7 @@ int hvc_remove(struct hvc_struct *hp)
 	struct tty_struct *tty;
 
 	spin_lock_irqsave(&hp->lock, flags);
-	tty = hp->tty;
+	tty = tty_kref_get(hp->tty);
 
 	if (hp->index < MAX_NR_HVC_CONSOLES)
 		vtermnos[hp->index] = -1;
@@ -818,18 +827,18 @@ int hvc_remove(struct hvc_struct *hp)
 	/*
 	 * We 'put' the instance that was grabbed when the kref instance
 	 * was initialized using kref_init().  Let the last holder of this
-	 * kref cause it to be removed, which will probably be the tty_hangup
+	 * kref cause it to be removed, which will probably be the tty_vhangup
 	 * below.
 	 */
 	kref_put(&hp->kref, destroy_hvc_struct);
 
 	/*
-	 * This function call will auto chain call hvc_hangup.  The tty should
-	 * always be valid at this time unless a simultaneous tty close already
-	 * cleaned up the hvc_struct.
+	 * This function call will auto chain call hvc_hangup.
 	 */
-	if (tty)
-		tty_hangup(tty);
+	if (tty) {
+		tty_vhangup(tty);
+		tty_kref_put(tty);
+	}
 	return 0;
 }
 EXPORT_SYMBOL_GPL(hvc_remove);
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hvc_console.h linux-libre-2.6.34-gnu1/drivers/char/hvc_console.h
--- linux-libre-2.6.33-gnu1/drivers/char/hvc_console.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hvc_console.h	2010-05-16 17:17:36.000000000 -0400
@@ -55,7 +55,7 @@ struct hvc_struct {
 	int outbuf_size;
 	int n_outbuf;
 	uint32_t vtermno;
-	struct hv_ops *ops;
+	const struct hv_ops *ops;
 	int irq_requested;
 	int data;
 	struct winsize ws;
@@ -76,11 +76,12 @@ struct hv_ops {
 };
 
 /* Register a vterm and a slot index for use as a console (console_init) */
-extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);
+extern int hvc_instantiate(uint32_t vtermno, int index,
+			   const struct hv_ops *ops);
 
 /* register a vterm for hvc tty operation (module_init or hotplug add) */
-extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int data,
-				struct hv_ops *ops, int outbuf_size);
+extern struct hvc_struct * hvc_alloc(uint32_t vtermno, int data,
+				     const struct hv_ops *ops, int outbuf_size);
 /* remove a vterm from hvc tty operation (module_exit or hotplug remove) */
 extern int hvc_remove(struct hvc_struct *hp);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hvc_iseries.c linux-libre-2.6.34-gnu1/drivers/char/hvc_iseries.c
--- linux-libre-2.6.33-gnu1/drivers/char/hvc_iseries.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hvc_iseries.c	2010-05-16 17:17:36.000000000 -0400
@@ -197,7 +197,7 @@ done:
 	return sent;
 }
 
-static struct hv_ops hvc_get_put_ops = {
+static const struct hv_ops hvc_get_put_ops = {
 	.get_chars = get_chars,
 	.put_chars = put_chars,
 	.notifier_add = notifier_add_irq,
@@ -353,7 +353,7 @@ static void hvc_close_event(struct HvLpE
 
 	if (!hvlpevent_is_int(event)) {
 		printk(KERN_WARNING
-			"hvc: got unexpected close acknowlegement\n");
+			"hvc: got unexpected close acknowledgement\n");
 		return;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hvc_iucv.c linux-libre-2.6.34-gnu1/drivers/char/hvc_iucv.c
--- linux-libre-2.6.33-gnu1/drivers/char/hvc_iucv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hvc_iucv.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #define pr_fmt(fmt)		KMSG_COMPONENT ": " fmt
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <asm/ebcdic.h>
 #include <linux/ctype.h>
 #include <linux/delay.h>
@@ -139,6 +140,8 @@ struct hvc_iucv_private *hvc_iucv_get_pr
  *
  * This function allocates a new struct iucv_tty_buffer element and, optionally,
  * allocates an internal data buffer with the specified size @size.
+ * The internal data buffer is always allocated with GFP_DMA which is
+ * required for receiving and sending data with IUCV.
  * Note: The total message size arises from the internal buffer size and the
  *	 members of the iucv_tty_msg structure.
  * The function returns NULL if memory allocation has failed.
@@ -154,7 +157,7 @@ static struct iucv_tty_buffer *alloc_tty
 
 	if (size > 0) {
 		bufp->msg.length = MSG_SIZE(size);
-		bufp->mbuf = kmalloc(bufp->msg.length, flags);
+		bufp->mbuf = kmalloc(bufp->msg.length, flags | GFP_DMA);
 		if (!bufp->mbuf) {
 			mempool_free(bufp, hvc_iucv_mempool);
 			return NULL;
@@ -237,7 +240,7 @@ static int hvc_iucv_write(struct hvc_iuc
 	if (!rb->mbuf) { /* message not yet received ... */
 		/* allocate mem to store msg data; if no memory is available
 		 * then leave the buffer on the list and re-try later */
-		rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC);
+		rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC | GFP_DMA);
 		if (!rb->mbuf)
 			return -ENOMEM;
 
@@ -922,7 +925,7 @@ static int hvc_iucv_pm_restore_thaw(stru
 
 
 /* HVC operations */
-static struct hv_ops hvc_iucv_ops = {
+static const struct hv_ops hvc_iucv_ops = {
 	.get_chars = hvc_iucv_get_chars,
 	.put_chars = hvc_iucv_put_chars,
 	.notifier_add = hvc_iucv_notifier_add,
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hvc_rtas.c linux-libre-2.6.34-gnu1/drivers/char/hvc_rtas.c
--- linux-libre-2.6.33-gnu1/drivers/char/hvc_rtas.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hvc_rtas.c	2010-05-16 17:17:36.000000000 -0400
@@ -71,7 +71,7 @@ static int hvc_rtas_read_console(uint32_
 	return i;
 }
 
-static struct hv_ops hvc_rtas_get_put_ops = {
+static const struct hv_ops hvc_rtas_get_put_ops = {
 	.get_chars = hvc_rtas_read_console,
 	.put_chars = hvc_rtas_write_console,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hvcs.c linux-libre-2.6.34-gnu1/drivers/char/hvcs.c
--- linux-libre-2.6.33-gnu1/drivers/char/hvcs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hvcs.c	2010-05-16 17:17:36.000000000 -0400
@@ -74,6 +74,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/stat.h>
 #include <linux/tty.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hvc_udbg.c linux-libre-2.6.34-gnu1/drivers/char/hvc_udbg.c
--- linux-libre-2.6.33-gnu1/drivers/char/hvc_udbg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hvc_udbg.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,7 +58,7 @@ static int hvc_udbg_get(uint32_t vtermno
 	return i;
 }
 
-static struct hv_ops hvc_udbg_ops = {
+static const struct hv_ops hvc_udbg_ops = {
 	.get_chars = hvc_udbg_get,
 	.put_chars = hvc_udbg_put,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hvc_vio.c linux-libre-2.6.34-gnu1/drivers/char/hvc_vio.c
--- linux-libre-2.6.33-gnu1/drivers/char/hvc_vio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hvc_vio.c	2010-05-16 17:17:36.000000000 -0400
@@ -77,7 +77,7 @@ static int filtered_get_chars(uint32_t v
 	return got;
 }
 
-static struct hv_ops hvc_get_put_ops = {
+static const struct hv_ops hvc_get_put_ops = {
 	.get_chars = filtered_get_chars,
 	.put_chars = hvc_put_chars,
 	.notifier_add = notifier_add_irq,
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hvc_xen.c linux-libre-2.6.34-gnu1/drivers/char/hvc_xen.c
--- linux-libre-2.6.33-gnu1/drivers/char/hvc_xen.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hvc_xen.c	2010-05-16 17:17:36.000000000 -0400
@@ -122,7 +122,7 @@ static int read_console(uint32_t vtermno
 	return recv;
 }
 
-static struct hv_ops hvc_ops = {
+static const struct hv_ops hvc_ops = {
 	.get_chars = read_console,
 	.put_chars = write_console,
 	.notifier_add = notifier_add_irq,
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hw_random/intel-rng.c linux-libre-2.6.34-gnu1/drivers/char/hw_random/intel-rng.c
--- linux-libre-2.6.33-gnu1/drivers/char/hw_random/intel-rng.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hw_random/intel-rng.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include <linux/stop_machine.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hw_random/Kconfig linux-libre-2.6.34-gnu1/drivers/char/hw_random/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/char/hw_random/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hw_random/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -114,7 +114,7 @@ config HW_RANDOM_IXP4XX
 
 config HW_RANDOM_OMAP
 	tristate "OMAP Random Number Generator support"
-	depends on HW_RANDOM && (ARCH_OMAP16XX || ARCH_OMAP24XX)
+	depends on HW_RANDOM && (ARCH_OMAP16XX || ARCH_OMAP2)
 	default HW_RANDOM
  	---help---
  	  This driver provides kernel-side support for the Random Number
@@ -186,3 +186,15 @@ config HW_RANDOM_MXC_RNGA
 	  module will be called mxc-rnga.
 
 	  If unsure, say Y.
+
+config HW_RANDOM_NOMADIK
+	tristate "ST-Ericsson Nomadik Random Number Generator support"
+	depends on HW_RANDOM && PLAT_NOMADIK
+	---help---
+	  This driver provides kernel-side support for the Random Number
+	  Generator hardware found on ST-Ericsson SoCs (8815 and 8500).
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called nomadik-rng.
+
+	  If unsure, say Y.
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hw_random/Makefile linux-libre-2.6.34-gnu1/drivers/char/hw_random/Makefile
--- linux-libre-2.6.33-gnu1/drivers/char/hw_random/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hw_random/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -18,3 +18,4 @@ obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio
 obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
 obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o
 obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
+obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hw_random/n2-drv.c linux-libre-2.6.34-gnu1/drivers/char/hw_random/n2-drv.c
--- linux-libre-2.6.33-gnu1/drivers/char/hw_random/n2-drv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hw_random/n2-drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -71,7 +71,7 @@ MODULE_VERSION(DRV_MODULE_VERSION);
  *        x22 + x21 + x17 + x15 + x13 + x12 + x11 + x7 + x5 + x + 1
  *
  * The RNG_CTL_VCO value of each noise cell must be programmed
- * seperately.  This is why 4 control register values must be provided
+ * separately.  This is why 4 control register values must be provided
  * to the hypervisor.  During a write, the hypervisor writes them all,
  * one at a time, to the actual RNG_CTL register.  The first three
  * values are used to setup the desired RNG_CTL_VCO for each entropy
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hw_random/nomadik-rng.c linux-libre-2.6.34-gnu1/drivers/char/hw_random/nomadik-rng.c
--- linux-libre-2.6.33-gnu1/drivers/char/hw_random/nomadik-rng.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hw_random/nomadik-rng.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,103 @@
+/*
+ * Nomadik RNG support
+ *  Copyright 2009 Alessandro Rubini
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+
+static int nmk_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+{
+	void __iomem *base = (void __iomem *)rng->priv;
+
+	/*
+	 * The register is 32 bits and gives 16 random bits (low half).
+	 * A subsequent read will delay the core for 400ns, so we just read
+	 * once and accept the very unlikely very small delay, even if wait==0.
+	 */
+	*(u16 *)data = __raw_readl(base + 8) & 0xffff;
+	return 2;
+}
+
+/* we have at most one RNG per machine, granted */
+static struct hwrng nmk_rng = {
+	.name		= "nomadik",
+	.read		= nmk_rng_read,
+};
+
+static int nmk_rng_probe(struct amba_device *dev, struct amba_id *id)
+{
+	void __iomem *base;
+	int ret;
+
+	ret = amba_request_regions(dev, dev->dev.init_name);
+	if (ret)
+		return ret;
+	ret = -ENOMEM;
+	base = ioremap(dev->res.start, resource_size(&dev->res));
+	if (!base)
+		goto out_release;
+	nmk_rng.priv = (unsigned long)base;
+	ret = hwrng_register(&nmk_rng);
+	if (ret)
+		goto out_unmap;
+	return 0;
+
+out_unmap:
+	iounmap(base);
+out_release:
+	amba_release_regions(dev);
+	return ret;
+}
+
+static int nmk_rng_remove(struct amba_device *dev)
+{
+	void __iomem *base = (void __iomem *)nmk_rng.priv;
+	hwrng_unregister(&nmk_rng);
+	iounmap(base);
+	amba_release_regions(dev);
+	return 0;
+}
+
+static struct amba_id nmk_rng_ids[] = {
+	{
+		.id	= 0x000805e1,
+		.mask	= 0x000fffff, /* top bits are rev and cfg: accept all */
+	},
+	{0, 0},
+};
+
+static struct amba_driver nmk_rng_driver = {
+	.drv = {
+		.owner = THIS_MODULE,
+		.name = "rng",
+		},
+	.probe = nmk_rng_probe,
+	.remove = nmk_rng_remove,
+	.id_table = nmk_rng_ids,
+};
+
+static int __init nmk_rng_init(void)
+{
+	return amba_driver_register(&nmk_rng_driver);
+}
+
+static void __devexit nmk_rng_exit(void)
+{
+	amba_driver_unregister(&nmk_rng_driver);
+}
+
+module_init(nmk_rng_init);
+module_exit(nmk_rng_exit);
+
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hw_random/octeon-rng.c linux-libre-2.6.34-gnu1/drivers/char/hw_random/octeon-rng.c
--- linux-libre-2.6.33-gnu1/drivers/char/hw_random/octeon-rng.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hw_random/octeon-rng.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/device.h>
 #include <linux/hw_random.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 
 #include <asm/octeon/octeon.h>
 #include <asm/octeon/cvmx-rnm-defs.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/hw_random/tx4939-rng.c linux-libre-2.6.34-gnu1/drivers/char/hw_random/tx4939-rng.c
--- linux-libre-2.6.33-gnu1/drivers/char/hw_random/tx4939-rng.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/hw_random/tx4939-rng.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/hw_random.h>
+#include <linux/gfp.h>
 
 #define TX4939_RNG_RCSR		0x00000000
 #define TX4939_RNG_ROR(n)	(0x00000018 + (n) * 8)
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/ip2/i2hw.h linux-libre-2.6.34-gnu1/drivers/char/ip2/i2hw.h
--- linux-libre-2.6.33-gnu1/drivers/char/ip2/i2hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/ip2/i2hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -559,7 +559,7 @@ Loadware may be sent to the board in two
 
 2) It may be hard-coded into your source by including a .h file (typically
 	supplied by Computone), which declares a data array and initializes every
-	element. This acheives the same result as if an entire loadware file had 
+	element. This achieves the same result as if an entire loadware file had 
 	been read into the array.
 
 	This requires more data space in your program, but access to the file system
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/ip2/ip2main.c linux-libre-2.6.34-gnu1/drivers/char/ip2/ip2main.c
--- linux-libre-2.6.33-gnu1/drivers/char/ip2/ip2main.c	2013-05-03 12:03:07.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/char/ip2/ip2main.c	2013-05-03 09:44:11.000000000 -0400
@@ -208,6 +208,7 @@ static int DumpFifoBuffer( char __user *
 
 static void ip2_init_board(int, const struct firmware *);
 static unsigned short find_eisa_board(int);
+static int ip2_setup(char *str);
 
 /***************/
 /* Static Data */
@@ -263,7 +264,7 @@ static int tracewrap;
 /* Macros */
 /**********/
 
-#if defined(MODULE) && defined(IP2DEBUG_OPEN)
+#ifdef IP2DEBUG_OPEN
 #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] ttyc=%d, modc=%x -> %s\n", \
 		    tty->name,(pCh->flags), \
 		    tty->count,/*GET_USE_COUNT(module)*/0,s)
@@ -285,7 +286,10 @@ MODULE_AUTHOR("Doug McNash");
 MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
 MODULE_LICENSE("GPL");
 
+#define	MAX_CMD_STR	50
+
 static int poll_only;
+static char cmd[MAX_CMD_STR];
 
 static int Eisa_irq;
 static int Eisa_slot;
@@ -309,6 +313,8 @@ module_param_array(io, int, NULL, 0);
 MODULE_PARM_DESC(io, "I/O ports for IntelliPort Cards");
 module_param(poll_only, bool, 0);
 MODULE_PARM_DESC(poll_only, "Do not use card interrupts");
+module_param_string(ip2, cmd, MAX_CMD_STR, 0);
+MODULE_PARM_DESC(ip2, "Contains module parameter passed with 'ip2='");
 
 /* for sysfs class support */
 static struct class *ip2_class;
@@ -487,7 +493,6 @@ static const struct firmware *ip2_reject
 	return fw;
 }
 
-#ifndef MODULE
 /******************************************************************************
  *	ip2_setup:
  *		str: kernel command line string
@@ -531,7 +536,6 @@ static int __init ip2_setup(char *str)
 	return 1;
 }
 __setup("ip2=", ip2_setup);
-#endif /* !MODULE */
 
 static int __init ip2_loadmain(void)
 {
@@ -539,14 +543,20 @@ static int __init ip2_loadmain(void)
 	int err = 0;
 	i2eBordStrPtr pB = NULL;
 	int rc = -1;
-	struct pci_dev *pdev = NULL;
 	const struct firmware *fw = NULL;
+	char *str;
+
+	str = cmd;
 
 	if (poll_only) {
 		/* Hard lock the interrupts to zero */
 		irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0;
 	}
 
+	/* Check module parameter with 'ip2=' has been passed or not */
+	if (!poll_only && (!strncmp(str, "ip2=", 4)))
+		ip2_setup(str);
+
 	ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0);
 
 	/* process command line arguments to modprobe or
@@ -612,6 +622,7 @@ static int __init ip2_loadmain(void)
 		case PCI:
 #ifdef CONFIG_PCI
 		{
+			struct pci_dev *pdev = NULL;
 			u32 addr;
 			int status;
 
@@ -626,7 +637,7 @@ static int __init ip2_loadmain(void)
 
 			if (pci_enable_device(pdev)) {
 				dev_err(&pdev->dev, "can't enable device\n");
-				break;
+				goto out;
 			}
 			ip2config.type[i] = PCI;
 			ip2config.pci_dev[i] = pci_dev_get(pdev);
@@ -638,6 +649,8 @@ static int __init ip2_loadmain(void)
 				dev_err(&pdev->dev, "I/O address error\n");
 
 			ip2config.irq[i] = pdev->irq;
+out:
+			pci_dev_put(pdev);
 		}
 #else
 			printk(KERN_ERR "IP2: PCI card specified but PCI "
@@ -656,7 +669,6 @@ static int __init ip2_loadmain(void)
 			break;
 		}	/* switch */
 	}	/* for */
-	pci_dev_put(pdev);
 
 	for (i = 0; i < IP2_MAX_BOARDS; ++i) {
 		if (ip2config.addr[i]) {
@@ -3197,3 +3209,5 @@ static struct pci_device_id ip2main_pci_
 };
 
 MODULE_DEVICE_TABLE(pci, ip2main_pci_tbl);
+
+/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/ipmi/ipmi_msghandler.c linux-libre-2.6.34-gnu1/drivers/char/ipmi/ipmi_msghandler.c
--- linux-libre-2.6.33-gnu1/drivers/char/ipmi/ipmi_msghandler.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/ipmi/ipmi_msghandler.c	2010-05-16 17:17:36.000000000 -0400
@@ -2272,42 +2272,52 @@ static int create_files(struct bmc_devic
 	bmc->device_id_attr.attr.name = "device_id";
 	bmc->device_id_attr.attr.mode = S_IRUGO;
 	bmc->device_id_attr.show = device_id_show;
+	sysfs_attr_init(&bmc->device_id_attr.attr);
 
 	bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs";
 	bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
 	bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
+	sysfs_attr_init(&bmc->provides_dev_sdrs_attr.attr);
 
 	bmc->revision_attr.attr.name = "revision";
 	bmc->revision_attr.attr.mode = S_IRUGO;
 	bmc->revision_attr.show = revision_show;
+	sysfs_attr_init(&bmc->revision_attr.attr);
 
 	bmc->firmware_rev_attr.attr.name = "firmware_revision";
 	bmc->firmware_rev_attr.attr.mode = S_IRUGO;
 	bmc->firmware_rev_attr.show = firmware_rev_show;
+	sysfs_attr_init(&bmc->firmware_rev_attr.attr);
 
 	bmc->version_attr.attr.name = "ipmi_version";
 	bmc->version_attr.attr.mode = S_IRUGO;
 	bmc->version_attr.show = ipmi_version_show;
+	sysfs_attr_init(&bmc->version_attr.attr);
 
 	bmc->add_dev_support_attr.attr.name = "additional_device_support";
 	bmc->add_dev_support_attr.attr.mode = S_IRUGO;
 	bmc->add_dev_support_attr.show = add_dev_support_show;
+	sysfs_attr_init(&bmc->add_dev_support_attr.attr);
 
 	bmc->manufacturer_id_attr.attr.name = "manufacturer_id";
 	bmc->manufacturer_id_attr.attr.mode = S_IRUGO;
 	bmc->manufacturer_id_attr.show = manufacturer_id_show;
+	sysfs_attr_init(&bmc->manufacturer_id_attr.attr);
 
 	bmc->product_id_attr.attr.name = "product_id";
 	bmc->product_id_attr.attr.mode = S_IRUGO;
 	bmc->product_id_attr.show = product_id_show;
+	sysfs_attr_init(&bmc->product_id_attr.attr);
 
 	bmc->guid_attr.attr.name = "guid";
 	bmc->guid_attr.attr.mode = S_IRUGO;
 	bmc->guid_attr.show = guid_show;
+	sysfs_attr_init(&bmc->guid_attr.attr);
 
 	bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision";
 	bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
 	bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
+	sysfs_attr_init(&bmc->aux_firmware_rev_attr.attr);
 
 	err = device_create_file(&bmc->dev->dev,
 			   &bmc->device_id_attr);
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/ipmi/ipmi_si_intf.c linux-libre-2.6.34-gnu1/drivers/char/ipmi/ipmi_si_intf.c
--- linux-libre-2.6.33-gnu1/drivers/char/ipmi/ipmi_si_intf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/ipmi/ipmi_si_intf.c	2010-05-16 17:17:36.000000000 -0400
@@ -295,6 +295,9 @@ struct smi_info {
 static int force_kipmid[SI_MAX_PARMS];
 static int num_force_kipmid;
 
+static unsigned int kipmid_max_busy_us[SI_MAX_PARMS];
+static int num_max_busy_us;
+
 static int unload_when_empty = 1;
 
 static int try_smi_init(struct smi_info *smi);
@@ -925,23 +928,77 @@ static void set_run_to_completion(void *
 	}
 }
 
+/*
+ * Use -1 in the nsec value of the busy waiting timespec to tell that
+ * we are spinning in kipmid looking for something and not delaying
+ * between checks
+ */
+static inline void ipmi_si_set_not_busy(struct timespec *ts)
+{
+	ts->tv_nsec = -1;
+}
+static inline int ipmi_si_is_busy(struct timespec *ts)
+{
+	return ts->tv_nsec != -1;
+}
+
+static int ipmi_thread_busy_wait(enum si_sm_result smi_result,
+				 const struct smi_info *smi_info,
+				 struct timespec *busy_until)
+{
+	unsigned int max_busy_us = 0;
+
+	if (smi_info->intf_num < num_max_busy_us)
+		max_busy_us = kipmid_max_busy_us[smi_info->intf_num];
+	if (max_busy_us == 0 || smi_result != SI_SM_CALL_WITH_DELAY)
+		ipmi_si_set_not_busy(busy_until);
+	else if (!ipmi_si_is_busy(busy_until)) {
+		getnstimeofday(busy_until);
+		timespec_add_ns(busy_until, max_busy_us*NSEC_PER_USEC);
+	} else {
+		struct timespec now;
+		getnstimeofday(&now);
+		if (unlikely(timespec_compare(&now, busy_until) > 0)) {
+			ipmi_si_set_not_busy(busy_until);
+			return 0;
+		}
+	}
+	return 1;
+}
+
+
+/*
+ * A busy-waiting loop for speeding up IPMI operation.
+ *
+ * Lousy hardware makes this hard.  This is only enabled for systems
+ * that are not BT and do not have interrupts.  It starts spinning
+ * when an operation is complete or until max_busy tells it to stop
+ * (if that is enabled).  See the paragraph on kimid_max_busy_us in
+ * Documentation/IPMI.txt for details.
+ */
 static int ipmi_thread(void *data)
 {
 	struct smi_info *smi_info = data;
 	unsigned long flags;
 	enum si_sm_result smi_result;
+	struct timespec busy_until;
 
+	ipmi_si_set_not_busy(&busy_until);
 	set_user_nice(current, 19);
 	while (!kthread_should_stop()) {
+		int busy_wait;
+
 		spin_lock_irqsave(&(smi_info->si_lock), flags);
 		smi_result = smi_event_handler(smi_info, 0);
 		spin_unlock_irqrestore(&(smi_info->si_lock), flags);
+		busy_wait = ipmi_thread_busy_wait(smi_result, smi_info,
+						  &busy_until);
 		if (smi_result == SI_SM_CALL_WITHOUT_DELAY)
 			; /* do nothing */
-		else if (smi_result == SI_SM_CALL_WITH_DELAY)
+		else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait)
 			schedule();
 		else
-			schedule_timeout_interruptible(1);
+			schedule_timeout_interruptible(0);
 	}
 	return 0;
 }
@@ -1144,7 +1201,7 @@ static int           regsizes[SI_MAX_PAR
 static unsigned int num_regsizes;
 static int           regshifts[SI_MAX_PARMS];
 static unsigned int num_regshifts;
-static int slave_addrs[SI_MAX_PARMS];
+static int slave_addrs[SI_MAX_PARMS]; /* Leaving 0 chooses the default value */
 static unsigned int num_slave_addrs;
 
 #define IPMI_IO_ADDR_SPACE  0
@@ -1212,6 +1269,11 @@ module_param(unload_when_empty, int, 0);
 MODULE_PARM_DESC(unload_when_empty, "Unload the module if no interfaces are"
 		 " specified or found, default is 1.  Setting to 0"
 		 " is useful for hot add of devices using hotmod.");
+module_param_array(kipmid_max_busy_us, uint, &num_max_busy_us, 0644);
+MODULE_PARM_DESC(kipmid_max_busy_us,
+		 "Max time (in microseconds) to busy-wait for IPMI data before"
+		 " sleeping. 0 (default) means to wait forever. Set to 100-500"
+		 " if kipmid is using up a lot of CPU time.");
 
 
 static void std_irq_cleanup(struct smi_info *info)
@@ -1607,7 +1669,7 @@ static int hotmod_handler(const char *va
 		regsize = 1;
 		regshift = 0;
 		irq = 0;
-		ipmb = 0x20;
+		ipmb = 0; /* Choose the default if not specified */
 
 		next = strchr(curr, ':');
 		if (next) {
@@ -1799,6 +1861,7 @@ static __devinit void hardcode_find_bmc(
 		info->irq = irqs[i];
 		if (info->irq)
 			info->irq_setup = std_irq_setup;
+		info->slave_addr = slave_addrs[i];
 
 		try_smi_init(info);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/isicom.c linux-libre-2.6.34-gnu1/drivers/char/isicom.c
--- linux-libre-2.6.33-gnu1/drivers/char/isicom.c	2013-05-03 12:03:13.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/char/isicom.c	2013-05-03 09:44:18.000000000 -0400
@@ -113,6 +113,8 @@
  *		64-bit verification
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/kernel.h>
@@ -128,6 +130,7 @@
 #include <linux/timer.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
 
 #include <linux/uaccess.h>
 #include <linux/io.h>
@@ -140,7 +143,6 @@
 #define InterruptTheCard(base) outw(0, (base) + 0xc)
 #define ClearInterrupt(base) inw((base) + 0x0a)
 
-#define pr_dbg(str...) pr_debug("ISICOM: " str)
 #ifdef DEBUG
 #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c))
 #else
@@ -249,8 +251,7 @@ static int lock_card(struct isi_board *c
 		spin_unlock_irqrestore(&card->card_lock, card->flags);
 		msleep(10);
 	}
-	printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%lx)\n",
-		card->base);
+	pr_warning("Failed to lock Card (0x%lx)\n", card->base);
 
 	return 0;	/* Failed to acquire the card! */
 }
@@ -379,13 +380,13 @@ static inline int __isicom_paranoia_chec
 	char *name, const char *routine)
 {
 	if (!port) {
-		printk(KERN_WARNING "ISICOM: Warning: bad isicom magic for "
-			"dev %s in %s.\n", name, routine);
+		pr_warning("Warning: bad isicom magic for dev %s in %s.\n",
+			   name, routine);
 		return 1;
 	}
 	if (port->magic != ISICOM_MAGIC) {
-		printk(KERN_WARNING "ISICOM: Warning: NULL isicom port for "
-			"dev %s in %s.\n", name, routine);
+		pr_warning("Warning: NULL isicom port for dev %s in %s.\n",
+			   name, routine);
 		return 1;
 	}
 
@@ -450,8 +451,8 @@ static void isicom_tx(unsigned long _dat
 		if (!(inw(base + 0x02) & (1 << port->channel)))
 			continue;
 
-		pr_dbg("txing %d bytes, port%d.\n", txcount,
-			port->channel + 1);
+		pr_debug("txing %d bytes, port%d.\n",
+			 txcount, port->channel + 1);
 		outw((port->channel << isi_card[card].shift_count) | txcount,
 			base);
 		residue = NO;
@@ -547,8 +548,8 @@ static irqreturn_t isicom_interrupt(int
 	byte_count = header & 0xff;
 
 	if (channel + 1 > card->port_count) {
-		printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): "
-			"%d(channel) > port_count.\n", base, channel+1);
+		pr_warning("%s(0x%lx): %d(channel) > port_count.\n",
+			   __func__, base, channel+1);
 		outw(0x0000, base+0x04); /* enable interrupts */
 		spin_unlock(&card->card_lock);
 		return IRQ_HANDLED;
@@ -582,14 +583,15 @@ static irqreturn_t isicom_interrupt(int
 				if (port->status & ISI_DCD) {
 					if (!(header & ISI_DCD)) {
 					/* Carrier has been lost  */
-						pr_dbg("interrupt: DCD->low.\n"
-							);
+						pr_debug("%s: DCD->low.\n",
+							 __func__);
 						port->status &= ~ISI_DCD;
 						tty_hangup(tty);
 					}
 				} else if (header & ISI_DCD) {
 				/* Carrier has been detected */
-					pr_dbg("interrupt: DCD->high.\n");
+					pr_debug("%s: DCD->high.\n",
+						__func__);
 					port->status |= ISI_DCD;
 					wake_up_interruptible(&port->port.open_wait);
 				}
@@ -641,17 +643,19 @@ static irqreturn_t isicom_interrupt(int
 			break;
 
 		case 2:	/* Statistics		 */
-			pr_dbg("isicom_interrupt: stats!!!.\n");
+			pr_debug("%s: stats!!!\n", __func__);
 			break;
 
 		default:
-			pr_dbg("Intr: Unknown code in status packet.\n");
+			pr_debug("%s: Unknown code in status packet.\n",
+				 __func__);
 			break;
 		}
 	} else {				/* Data   Packet */
 
 		count = tty_prepare_flip_string(tty, &rp, byte_count & ~1);
-		pr_dbg("Intr: Can rx %d of %d bytes.\n", count, byte_count);
+		pr_debug("%s: Can rx %d of %d bytes.\n",
+			 __func__, count, byte_count);
 		word_count = count >> 1;
 		insw(base, rp, word_count);
 		byte_count -= (word_count << 1);
@@ -661,8 +665,8 @@ static irqreturn_t isicom_interrupt(int
 			byte_count -= 2;
 		}
 		if (byte_count > 0) {
-			pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping "
-				"bytes...\n", base, channel + 1);
+			pr_debug("%s(0x%lx:%d): Flip buffer overflow! dropping bytes...\n",
+				 __func__, base, channel + 1);
 		/* drain out unread xtra data */
 		while (byte_count > 0) {
 				inw(base);
@@ -875,8 +879,8 @@ static int isicom_open(struct tty_struct
 	if (tport == NULL)
 		return -ENODEV;
 	port = container_of(tport, struct isi_port, port);
-	card = &isi_card[BOARD(tty->index)];
 
+	tty->driver_data = port;
 	return tty_port_open(tport, tty, filp);
 }
 
@@ -888,8 +892,8 @@ static void isicom_shutdown_port(struct
 	struct isi_board *card = port->card;
 
 	if (--card->count < 0) {
-		pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n",
-			card->base, card->count);
+		pr_debug("%s: bad board(0x%lx) count %d.\n",
+			 __func__, card->base, card->count);
 		card->count = 0;
 	}
 	/* last port was closed, shutdown that board too */
@@ -932,7 +936,12 @@ static void isicom_shutdown(struct tty_p
 static void isicom_close(struct tty_struct *tty, struct file *filp)
 {
 	struct isi_port *ip = tty->driver_data;
-	struct tty_port *port = &ip->port;
+	struct tty_port *port;
+
+	if (ip == NULL)
+		return;
+
+	port = &ip->port;
 	if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
 		return;
 	tty_port_close(port, tty, filp);
@@ -1681,13 +1690,13 @@ static int __init isicom_init(void)
 
 	retval = tty_register_driver(isicom_normal);
 	if (retval) {
-		pr_dbg("Couldn't register the dialin driver\n");
+		pr_debug("Couldn't register the dialin driver\n");
 		goto err_puttty;
 	}
 
 	retval = pci_register_driver(&isicom_driver);
 	if (retval < 0) {
-		printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
+		pr_err("Unable to register pci driver.\n");
 		goto err_unrtty;
 	}
 
@@ -1717,3 +1726,4 @@ module_exit(isicom_exit);
 MODULE_AUTHOR("MultiTech");
 MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
 MODULE_LICENSE("GPL");
+/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/istallion.c linux-libre-2.6.34-gnu1/drivers/char/istallion.c
--- linux-libre-2.6.33-gnu1/drivers/char/istallion.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/istallion.c	2010-05-16 17:17:36.000000000 -0400
@@ -827,6 +827,8 @@ static int stli_open(struct tty_struct *
 		return -ENODEV;
 	if (portp->devnr < 1)
 		return -ENODEV;
+
+	tty->driver_data = portp;
 	return tty_port_open(&portp->port, tty, filp);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/Kconfig linux-libre-2.6.34-gnu1/drivers/char/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/char/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -666,6 +666,14 @@ config VIRTIO_CONSOLE
 	help
 	  Virtio console for use with lguest and other hypervisors.
 
+	  Also serves as a general-purpose serial device for data
+	  transfer between the guest and host.  Character devices at
+	  /dev/vportNpn will be created when corresponding ports are
+	  found, where N is the device number and n is the port number
+	  within that device.  If specified by the host, a sysfs
+	  attribute called 'name' will be populated with a name for
+	  the port which can be used by udev scripts to create a
+	  symlink to the device.
 
 config HVCS
 	tristate "IBM Hypervisor Virtual Console Server support"
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/keyboard.c linux-libre-2.6.34-gnu1/drivers/char/keyboard.c
--- linux-libre-2.6.33-gnu1/drivers/char/keyboard.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/keyboard.c	2010-05-16 17:17:36.000000000 -0400
@@ -1185,11 +1185,6 @@ static void kbd_keycode(unsigned int key
 
 	rep = (down == 2);
 
-#ifdef CONFIG_MAC_EMUMOUSEBTN
-	if (mac_hid_mouse_emulate_buttons(1, keycode, down))
-		return;
-#endif /* CONFIG_MAC_EMUMOUSEBTN */
-
 	if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw)
 		if (emulate_raw(vc, keycode, !down << 7))
 			if (keycode < BTN_MISC && printk_ratelimit())
@@ -1328,6 +1323,21 @@ static void kbd_event(struct input_handl
 	schedule_console_callback();
 }
 
+static bool kbd_match(struct input_handler *handler, struct input_dev *dev)
+{
+	int i;
+
+	if (test_bit(EV_SND, dev->evbit))
+		return true;
+
+	if (test_bit(EV_KEY, dev->evbit))
+		for (i = KEY_RESERVED; i < BTN_MISC; i++)
+			if (test_bit(i, dev->keybit))
+				return true;
+
+	return false;
+}
+
 /*
  * When a keyboard (or other input device) is found, the kbd_connect
  * function is called. The function then looks at the device, and if it
@@ -1339,14 +1349,6 @@ static int kbd_connect(struct input_hand
 {
 	struct input_handle *handle;
 	int error;
-	int i;
-
-	for (i = KEY_RESERVED; i < BTN_MISC; i++)
-		if (test_bit(i, dev->keybit))
-			break;
-
-	if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit))
-		return -ENODEV;
 
 	handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
 	if (!handle)
@@ -1412,6 +1414,7 @@ MODULE_DEVICE_TABLE(input, kbd_ids);
 
 static struct input_handler kbd_handler = {
 	.event		= kbd_event,
+	.match		= kbd_match,
 	.connect	= kbd_connect,
 	.disconnect	= kbd_disconnect,
 	.start		= kbd_start,
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/mbcs.c linux-libre-2.6.34-gnu1/drivers/char/mbcs.c
--- linux-libre-2.6.33-gnu1/drivers/char/mbcs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/mbcs.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/uio.h>
 #include <linux/mutex.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/mem.c linux-libre-2.6.34-gnu1/drivers/char/mem.c
--- linux-libre-2.6.33-gnu1/drivers/char/mem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/mem.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *
- *  Added devfs support. 
+ *  Added devfs support.
  *    Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
  *  Shared /dev/zero mmapping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
  */
@@ -44,36 +44,6 @@ static inline unsigned long size_inside_
 	return min(sz, size);
 }
 
-/*
- * Architectures vary in how they handle caching for addresses
- * outside of main memory.
- *
- */
-static inline int uncached_access(struct file *file, unsigned long addr)
-{
-#if defined(CONFIG_IA64)
-	/*
-	 * On ia64, we ignore O_DSYNC because we cannot tolerate memory attribute aliases.
-	 */
-	return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
-#elif defined(CONFIG_MIPS)
-	{
-		extern int __uncached_access(struct file *file,
-					     unsigned long addr);
-
-		return __uncached_access(file, addr);
-	}
-#else
-	/*
-	 * Accessing memory above the top the kernel knows about or through a file pointer
-	 * that was marked O_DSYNC will be done non-cached.
-	 */
-	if (file->f_flags & O_DSYNC)
-		return 1;
-	return addr >= __pa(high_memory);
-#endif
-}
-
 #ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE
 static inline int valid_phys_addr_range(unsigned long addr, size_t count)
 {
@@ -115,15 +85,15 @@ static inline int range_is_allowed(unsig
 }
 #endif
 
-void __attribute__((weak)) unxlate_dev_mem_ptr(unsigned long phys, void *addr)
+void __weak unxlate_dev_mem_ptr(unsigned long phys, void *addr)
 {
 }
 
 /*
- * This funcion reads the *physical* memory. The f_pos points directly to the 
- * memory location. 
+ * This funcion reads the *physical* memory. The f_pos points directly to the
+ * memory location.
  */
-static ssize_t read_mem(struct file * file, char __user * buf,
+static ssize_t read_mem(struct file *file, char __user *buf,
 			size_t count, loff_t *ppos)
 {
 	unsigned long p = *ppos;
@@ -140,10 +110,10 @@ static ssize_t read_mem(struct file * fi
 		if (sz > 0) {
 			if (clear_user(buf, sz))
 				return -EFAULT;
-			buf += sz; 
-			p += sz; 
-			count -= sz; 
-			read += sz; 
+			buf += sz;
+			p += sz;
+			count -= sz;
+			read += sz;
 		}
 	}
 #endif
@@ -157,9 +127,9 @@ static ssize_t read_mem(struct file * fi
 			return -EPERM;
 
 		/*
-		 * On ia64 if a page has been mapped somewhere as
-		 * uncached, then it must also be accessed uncached
-		 * by the kernel or data corruption may occur
+		 * On ia64 if a page has been mapped somewhere as uncached, then
+		 * it must also be accessed uncached by the kernel or data
+		 * corruption may occur.
 		 */
 		ptr = xlate_dev_mem_ptr(p);
 		if (!ptr)
@@ -180,7 +150,7 @@ static ssize_t read_mem(struct file * fi
 	return read;
 }
 
-static ssize_t write_mem(struct file * file, const char __user * buf, 
+static ssize_t write_mem(struct file *file, const char __user *buf,
 			 size_t count, loff_t *ppos)
 {
 	unsigned long p = *ppos;
@@ -212,9 +182,9 @@ static ssize_t write_mem(struct file * f
 			return -EPERM;
 
 		/*
-		 * On ia64 if a page has been mapped somewhere as
-		 * uncached, then it must also be accessed uncached
-		 * by the kernel or data corruption may occur
+		 * On ia64 if a page has been mapped somewhere as uncached, then
+		 * it must also be accessed uncached by the kernel or data
+		 * corruption may occur.
 		 */
 		ptr = xlate_dev_mem_ptr(p);
 		if (!ptr) {
@@ -242,13 +212,48 @@ static ssize_t write_mem(struct file * f
 	return written;
 }
 
-int __attribute__((weak)) phys_mem_access_prot_allowed(struct file *file,
+int __weak phys_mem_access_prot_allowed(struct file *file,
 	unsigned long pfn, unsigned long size, pgprot_t *vma_prot)
 {
 	return 1;
 }
 
 #ifndef __HAVE_PHYS_MEM_ACCESS_PROT
+
+/*
+ * Architectures vary in how they handle caching for addresses
+ * outside of main memory.
+ *
+ */
+#ifdef pgprot_noncached
+static int uncached_access(struct file *file, unsigned long addr)
+{
+#if defined(CONFIG_IA64)
+	/*
+	 * On ia64, we ignore O_DSYNC because we cannot tolerate memory
+	 * attribute aliases.
+	 */
+	return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
+#elif defined(CONFIG_MIPS)
+	{
+		extern int __uncached_access(struct file *file,
+					     unsigned long addr);
+
+		return __uncached_access(file, addr);
+	}
+#else
+	/*
+	 * Accessing memory above the top the kernel knows about or through a
+	 * file pointer
+	 * that was marked O_DSYNC will be done non-cached.
+	 */
+	if (file->f_flags & O_DSYNC)
+		return 1;
+	return addr >= __pa(high_memory);
+#endif
+}
+#endif
+
 static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
 				     unsigned long size, pgprot_t vma_prot)
 {
@@ -294,7 +299,7 @@ static const struct vm_operations_struct
 #endif
 };
 
-static int mmap_mem(struct file * file, struct vm_area_struct * vma)
+static int mmap_mem(struct file *file, struct vm_area_struct *vma)
 {
 	size_t size = vma->vm_end - vma->vm_start;
 
@@ -329,7 +334,7 @@ static int mmap_mem(struct file * file,
 }
 
 #ifdef CONFIG_DEVKMEM
-static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
+static int mmap_kmem(struct file *file, struct vm_area_struct *vma)
 {
 	unsigned long pfn;
 
@@ -337,9 +342,9 @@ static int mmap_kmem(struct file * file,
 	pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT;
 
 	/*
-	 * RED-PEN: on some architectures there is more mapped memory
-	 * than available in mem_map which pfn_valid checks
-	 * for. Perhaps should add a new macro here.
+	 * RED-PEN: on some architectures there is more mapped memory than
+	 * available in mem_map which pfn_valid checks for. Perhaps should add a
+	 * new macro here.
 	 *
 	 * RED-PEN: vmalloc is not supported right now.
 	 */
@@ -389,7 +394,7 @@ static ssize_t read_oldmem(struct file *
 /*
  * This function reads the *virtual* memory as seen by the kernel.
  */
-static ssize_t read_kmem(struct file *file, char __user *buf, 
+static ssize_t read_kmem(struct file *file, char __user *buf,
 			 size_t count, loff_t *ppos)
 {
 	unsigned long p = *ppos;
@@ -400,8 +405,8 @@ static ssize_t read_kmem(struct file *fi
 	read = 0;
 	if (p < (unsigned long) high_memory) {
 		low_count = count;
-		if (count > (unsigned long) high_memory - p)
-			low_count = (unsigned long) high_memory - p;
+		if (count > (unsigned long)high_memory - p)
+			low_count = (unsigned long)high_memory - p;
 
 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
 		/* we don't have page 0 mapped on sparc and m68k.. */
@@ -465,9 +470,8 @@ static ssize_t read_kmem(struct file *fi
 }
 
 
-static inline ssize_t
-do_write_kmem(unsigned long p, const char __user *buf,
-	      size_t count, loff_t *ppos)
+static ssize_t do_write_kmem(unsigned long p, const char __user *buf,
+				size_t count, loff_t *ppos)
 {
 	ssize_t written, sz;
 	unsigned long copied;
@@ -491,9 +495,9 @@ do_write_kmem(unsigned long p, const cha
 		sz = size_inside_page(p, count);
 
 		/*
-		 * On ia64 if a page has been mapped somewhere as
-		 * uncached, then it must also be accessed uncached
-		 * by the kernel or data corruption may occur
+		 * On ia64 if a page has been mapped somewhere as uncached, then
+		 * it must also be accessed uncached by the kernel or data
+		 * corruption may occur.
 		 */
 		ptr = xlate_dev_kmem_ptr((char *)p);
 
@@ -514,11 +518,10 @@ do_write_kmem(unsigned long p, const cha
 	return written;
 }
 
-
 /*
  * This function writes to the *virtual* memory as seen by the kernel.
  */
-static ssize_t write_kmem(struct file * file, const char __user * buf, 
+static ssize_t write_kmem(struct file *file, const char __user *buf,
 			  size_t count, loff_t *ppos)
 {
 	unsigned long p = *ppos;
@@ -570,17 +573,17 @@ static ssize_t write_kmem(struct file *
 #endif
 
 #ifdef CONFIG_DEVPORT
-static ssize_t read_port(struct file * file, char __user * buf,
+static ssize_t read_port(struct file *file, char __user *buf,
 			 size_t count, loff_t *ppos)
 {
 	unsigned long i = *ppos;
 	char __user *tmp = buf;
 
 	if (!access_ok(VERIFY_WRITE, buf, count))
-		return -EFAULT; 
+		return -EFAULT;
 	while (count-- > 0 && i < 65536) {
-		if (__put_user(inb(i),tmp) < 0) 
-			return -EFAULT;  
+		if (__put_user(inb(i), tmp) < 0)
+			return -EFAULT;
 		i++;
 		tmp++;
 	}
@@ -588,22 +591,22 @@ static ssize_t read_port(struct file * f
 	return tmp-buf;
 }
 
-static ssize_t write_port(struct file * file, const char __user * buf,
+static ssize_t write_port(struct file *file, const char __user *buf,
 			  size_t count, loff_t *ppos)
 {
 	unsigned long i = *ppos;
 	const char __user * tmp = buf;
 
-	if (!access_ok(VERIFY_READ,buf,count))
+	if (!access_ok(VERIFY_READ, buf, count))
 		return -EFAULT;
 	while (count-- > 0 && i < 65536) {
 		char c;
 		if (__get_user(c, tmp)) {
 			if (tmp > buf)
 				break;
-			return -EFAULT; 
+			return -EFAULT;
 		}
-		outb(c,i);
+		outb(c, i);
 		i++;
 		tmp++;
 	}
@@ -612,13 +615,13 @@ static ssize_t write_port(struct file *
 }
 #endif
 
-static ssize_t read_null(struct file * file, char __user * buf,
+static ssize_t read_null(struct file *file, char __user *buf,
 			 size_t count, loff_t *ppos)
 {
 	return 0;
 }
 
-static ssize_t write_null(struct file * file, const char __user * buf,
+static ssize_t write_null(struct file *file, const char __user *buf,
 			  size_t count, loff_t *ppos)
 {
 	return count;
@@ -630,13 +633,13 @@ static int pipe_to_null(struct pipe_inod
 	return sd->len;
 }
 
-static ssize_t splice_write_null(struct pipe_inode_info *pipe,struct file *out,
+static ssize_t splice_write_null(struct pipe_inode_info *pipe, struct file *out,
 				 loff_t *ppos, size_t len, unsigned int flags)
 {
 	return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null);
 }
 
-static ssize_t read_zero(struct file * file, char __user * buf, 
+static ssize_t read_zero(struct file *file, char __user *buf,
 			 size_t count, loff_t *ppos)
 {
 	size_t written;
@@ -667,7 +670,7 @@ static ssize_t read_zero(struct file * f
 	return written ? written : -EFAULT;
 }
 
-static int mmap_zero(struct file * file, struct vm_area_struct * vma)
+static int mmap_zero(struct file *file, struct vm_area_struct *vma)
 {
 #ifndef CONFIG_MMU
 	return -ENOSYS;
@@ -677,7 +680,7 @@ static int mmap_zero(struct file * file,
 	return 0;
 }
 
-static ssize_t write_full(struct file * file, const char __user * buf,
+static ssize_t write_full(struct file *file, const char __user *buf,
 			  size_t count, loff_t *ppos)
 {
 	return -ENOSPC;
@@ -688,8 +691,7 @@ static ssize_t write_full(struct file *
  * can fopen() both devices with "a" now.  This was previously impossible.
  * -- SRB.
  */
-
-static loff_t null_lseek(struct file * file, loff_t offset, int orig)
+static loff_t null_lseek(struct file *file, loff_t offset, int orig)
 {
 	return file->f_pos = 0;
 }
@@ -702,24 +704,26 @@ static loff_t null_lseek(struct file * f
  * also note that seeking relative to the "end of file" isn't supported:
  * it has no meaning, so it returns -EINVAL.
  */
-static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
+static loff_t memory_lseek(struct file *file, loff_t offset, int orig)
 {
 	loff_t ret;
 
 	mutex_lock(&file->f_path.dentry->d_inode->i_mutex);
 	switch (orig) {
-		case 0:
-			file->f_pos = offset;
-			ret = file->f_pos;
-			force_successful_syscall_return();
-			break;
-		case 1:
-			file->f_pos += offset;
-			ret = file->f_pos;
-			force_successful_syscall_return();
+	case SEEK_CUR:
+		offset += file->f_pos;
+	case SEEK_SET:
+		/* to avoid userland mistaking f_pos=-9 as -EBADF=-9 */
+		if ((unsigned long long)offset >= ~0xFFFULL) {
+			ret = -EOVERFLOW;
 			break;
-		default:
-			ret = -EINVAL;
+		}
+		file->f_pos = offset;
+		ret = file->f_pos;
+		force_successful_syscall_return();
+		break;
+	default:
+		ret = -EINVAL;
 	}
 	mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
 	return ret;
@@ -803,7 +807,7 @@ static const struct file_operations oldm
 };
 #endif
 
-static ssize_t kmsg_write(struct file * file, const char __user * buf,
+static ssize_t kmsg_write(struct file *file, const char __user *buf,
 			  size_t count, loff_t *ppos)
 {
 	char *tmp;
@@ -825,7 +829,7 @@ static ssize_t kmsg_write(struct file *
 }
 
 static const struct file_operations kmsg_fops = {
-	.write =	kmsg_write,
+	.write = kmsg_write,
 };
 
 static const struct memdev {
@@ -876,7 +880,7 @@ static int memory_open(struct inode *ino
 }
 
 static const struct file_operations memory_fops = {
-	.open		= memory_open,
+	.open = memory_open,
 };
 
 static char *mem_devnode(struct device *dev, mode_t *mode)
@@ -897,10 +901,13 @@ static int __init chr_dev_init(void)
 	if (err)
 		return err;
 
-	if (register_chrdev(MEM_MAJOR,"mem",&memory_fops))
+	if (register_chrdev(MEM_MAJOR, "mem", &memory_fops))
 		printk("unable to get major %d for memory devs\n", MEM_MAJOR);
 
 	mem_class = class_create(THIS_MODULE, "mem");
+	if (IS_ERR(mem_class))
+		return PTR_ERR(mem_class);
+
 	mem_class->devnode = mem_devnode;
 	for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
 		if (!devlist[minor].name)
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/misc.c linux-libre-2.6.34-gnu1/drivers/char/misc.c
--- linux-libre-2.6.33-gnu1/drivers/char/misc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/misc.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,7 +40,6 @@
 #include <linux/miscdevice.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
-#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
@@ -49,6 +48,7 @@
 #include <linux/device.h>
 #include <linux/tty.h>
 #include <linux/kmod.h>
+#include <linux/gfp.h>
 
 /*
  * Head entry for the doubly linked miscdevice list
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/mmtimer.c linux-libre-2.6.34-gnu1/drivers/char/mmtimer.c
--- linux-libre-2.6.33-gnu1/drivers/char/mmtimer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/mmtimer.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/time.h>
 #include <linux/math64.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/sn/addrs.h>
@@ -546,7 +547,7 @@ static void mmtimer_tasklet(unsigned lon
 {
 	int nodeid = data;
 	struct mmtimer_node *mn = &timers[nodeid];
-	struct mmtimer *x = rb_entry(mn->next, struct mmtimer, list);
+	struct mmtimer *x;
 	struct k_itimer *t;
 	unsigned long flags;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/moxa.c linux-libre-2.6.34-gnu1/drivers/char/moxa.c
--- linux-libre-2.6.33-gnu1/drivers/char/moxa.c	2013-05-03 12:03:16.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/char/moxa.c	2013-05-03 09:44:23.000000000 -0400
@@ -43,6 +43,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -164,24 +165,23 @@ static unsigned int moxaFuncTout = HZ /
 static unsigned int moxaLowWaterChk;
 static DEFINE_MUTEX(moxa_openlock);
 static DEFINE_SPINLOCK(moxa_lock);
-/* Variables for insmod */
-#ifdef MODULE
+
 static unsigned long baseaddr[MAX_BOARDS];
 static unsigned int type[MAX_BOARDS];
 static unsigned int numports[MAX_BOARDS];
-#endif
 
 MODULE_AUTHOR("William Chen");
 MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver");
 MODULE_LICENSE("GPL");
-#ifdef MODULE
+/*(DEBLOBBED)*/
+
 module_param_array(type, uint, NULL, 0);
 MODULE_PARM_DESC(type, "card type: C218=2, C320=4");
 module_param_array(baseaddr, ulong, NULL, 0);
 MODULE_PARM_DESC(baseaddr, "base address");
 module_param_array(numports, uint, NULL, 0);
 MODULE_PARM_DESC(numports, "numports (ignored for C218)");
-#endif
+
 module_param(ttymajor, int, 0);
 
 /*
@@ -1024,6 +1024,8 @@ static int __init moxa_init(void)
 {
 	unsigned int isabrds = 0;
 	int retval = 0;
+	struct moxa_board_conf *brd = moxa_boards;
+	unsigned int i;
 
 	printk(KERN_INFO "MOXA Intellio family driver version %s\n",
 			MOXA_VERSION);
@@ -1051,10 +1053,7 @@ static int __init moxa_init(void)
 	}
 
 	/* Find the boards defined from module args. */
-#ifdef MODULE
-	{
-	struct moxa_board_conf *brd = moxa_boards;
-	unsigned int i;
+
 	for (i = 0; i < MAX_BOARDS; i++) {
 		if (!baseaddr[i])
 			break;
@@ -1087,8 +1086,6 @@ static int __init moxa_init(void)
 			isabrds++;
 		}
 	}
-	}
-#endif
 
 #ifdef CONFIG_PCI
 	retval = pci_register_driver(&moxa_pci_driver);
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/mxser.c linux-libre-2.6.34-gnu1/drivers/char/mxser.c
--- linux-libre-2.6.33-gnu1/drivers/char/mxser.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/mxser.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,12 +33,12 @@
 #include <linux/string.h>
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
-#include <linux/gfp.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -895,8 +895,7 @@ static int mxser_activate(struct tty_por
 	if (inb(info->ioaddr + UART_LSR) == 0xff) {
 		spin_unlock_irqrestore(&info->slock, flags);
 		if (capable(CAP_SYS_ADMIN)) {
-			if (tty)
-				set_bit(TTY_IO_ERROR, &tty->flags);
+			set_bit(TTY_IO_ERROR, &tty->flags);
 			return 0;
 		} else
 			return -ENODEV;
@@ -1012,6 +1011,7 @@ static int mxser_open(struct tty_struct
 	if (!info->ioaddr)
 		return -ENODEV;
 
+	tty->driver_data = info;
 	return tty_port_open(&info->port, tty, filp);
 }
 
@@ -1075,7 +1075,7 @@ static void mxser_close(struct tty_struc
 	struct mxser_port *info = tty->driver_data;
 	struct tty_port *port = &info->port;
 
-	if (tty->index == MXSER_PORTS)
+	if (tty->index == MXSER_PORTS || info == NULL)
 		return;
 	if (tty_port_close_start(port, tty, filp) == 0)
 		return;
@@ -1769,7 +1769,7 @@ static int mxser_ioctl(struct tty_struct
 		int len, lsr;
 
 		len = mxser_chars_in_buffer(tty);
-		spin_lock(&info->slock);
+		spin_lock_irq(&info->slock);
 		lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE;
 		spin_unlock_irq(&info->slock);
 		len += (lsr ? 0 : 1);
@@ -1779,12 +1779,12 @@ static int mxser_ioctl(struct tty_struct
 	case MOXA_ASPP_MON: {
 		int mcr, status;
 
-		spin_lock(&info->slock);
+		spin_lock_irq(&info->slock);
 		status = mxser_get_msr(info->ioaddr, 1, tty->index);
 		mxser_check_modem_status(tty, info, status);
 
 		mcr = inb(info->ioaddr + UART_MCR);
-		spin_unlock(&info->slock);
+		spin_unlock_irq(&info->slock);
 
 		if (mcr & MOXA_MUST_MCR_XON_FLAG)
 			info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD;
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/nozomi.c linux-libre-2.6.34-gnu1/drivers/char/nozomi.c
--- linux-libre-2.6.33-gnu1/drivers/char/nozomi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/nozomi.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,6 +55,7 @@
 #include <linux/init.h>
 #include <linux/kfifo.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 
 #include <linux/delay.h>
@@ -136,10 +137,6 @@ static int debug;
 #define RECEIVE_BUF_MAX		4
 
 
-/* Define all types of vendors and devices to support */
-#define VENDOR1		0x1931	/* Vendor Option */
-#define DEVICE1		0x000c	/* HSDPA card */
-
 #define R_IIR		0x0000	/* Interrupt Identity Register */
 #define R_FCR		0x0000	/* Flow Control Register */
 #define R_IER		0x0004	/* Interrupt Enable Register */
@@ -371,6 +368,8 @@ struct port {
 	struct mutex tty_sem;
 	wait_queue_head_t tty_wait;
 	struct async_icount tty_icount;
+
+	struct nozomi *dc;
 };
 
 /* Private data one for each card in the system */
@@ -405,7 +404,7 @@ struct buffer {
 
 /*    Global variables */
 static const struct pci_device_id nozomi_pci_tbl[] __devinitconst = {
-	{PCI_DEVICE(VENDOR1, DEVICE1)},
+	{PCI_DEVICE(0x1931, 0x000c)},	/* Nozomi HSDPA */
 	{},
 };
 
@@ -414,6 +413,8 @@ MODULE_DEVICE_TABLE(pci, nozomi_pci_tbl)
 static struct nozomi *ndevs[NOZOMI_MAX_CARDS];
 static struct tty_driver *ntty_driver;
 
+static const struct tty_port_operations noz_tty_port_ops;
+
 /*
  * find card by tty_index
  */
@@ -853,8 +854,6 @@ static int receive_data(enum port_type i
 		goto put;
 	}
 
-	tty_buffer_request_room(tty, size);
-
 	while (size > 0) {
 		read_mem32((u32 *) buf, addr + offset, RECEIVE_BUF_MAX);
 
@@ -1473,9 +1472,11 @@ static int __devinit nozomi_card_init(st
 
 	for (i = 0; i < MAX_PORT; i++) {
 		struct device *tty_dev;
-
-		mutex_init(&dc->port[i].tty_sem);
-		tty_port_init(&dc->port[i].port);
+		struct port *port = &dc->port[i];
+		port->dc = dc;
+		mutex_init(&port->tty_sem);
+		tty_port_init(&port->port);
+		port->port.ops = &noz_tty_port_ops;
 		tty_dev = tty_register_device(ntty_driver, dc->index_start + i,
 							&pdev->dev);
 
@@ -1600,67 +1601,74 @@ static void set_dtr(const struct tty_str
  * ----------------------------------------------------------------------------
  */
 
-/* Called when the userspace process opens the tty, /dev/noz*.  */
-static int ntty_open(struct tty_struct *tty, struct file *file)
+static int ntty_install(struct tty_driver *driver, struct tty_struct *tty)
 {
 	struct port *port = get_port_by_tty(tty);
 	struct nozomi *dc = get_dc_by_tty(tty);
-	unsigned long flags;
-
+	int ret;
 	if (!port || !dc || dc->state != NOZOMI_STATE_READY)
 		return -ENODEV;
-
-	if (mutex_lock_interruptible(&port->tty_sem))
-		return -ERESTARTSYS;
-
-	port->port.count++;
-	dc->open_ttys++;
-
-	/* Enable interrupt downlink for channel */
-	if (port->port.count == 1) {
-		tty->driver_data = port;
-		tty_port_tty_set(&port->port, tty);
-		DBG1("open: %d", port->token_dl);
-		spin_lock_irqsave(&dc->spin_mutex, flags);
-		dc->last_ier = dc->last_ier | port->token_dl;
-		writew(dc->last_ier, dc->reg_ier);
-		spin_unlock_irqrestore(&dc->spin_mutex, flags);
+	ret = tty_init_termios(tty);
+	if (ret == 0) {
+		tty_driver_kref_get(driver);
+		driver->ttys[tty->index] = tty;
 	}
-	mutex_unlock(&port->tty_sem);
-	return 0;
+	return ret;
 }
 
-/* Called when the userspace process close the tty, /dev/noz*. Also
-   called immediately if ntty_open fails in which case tty->driver_data
-   will be NULL an we exit by the first return */
+static void ntty_cleanup(struct tty_struct *tty)
+{
+	tty->driver_data = NULL;
+}
 
-static void ntty_close(struct tty_struct *tty, struct file *file)
+static int ntty_activate(struct tty_port *tport, struct tty_struct *tty)
 {
-	struct nozomi *dc = get_dc_by_tty(tty);
-	struct port *nport = tty->driver_data;
-	struct tty_port *port = &nport->port;
+	struct port *port = container_of(tport, struct port, port);
+	struct nozomi *dc = port->dc;
 	unsigned long flags;
 
-	if (!dc || !nport)
-		return;
+	DBG1("open: %d", port->token_dl);
+	spin_lock_irqsave(&dc->spin_mutex, flags);
+	dc->last_ier = dc->last_ier | port->token_dl;
+	writew(dc->last_ier, dc->reg_ier);
+	dc->open_ttys++;
+	spin_unlock_irqrestore(&dc->spin_mutex, flags);
+	printk("noz: activated %d: %p\n", tty->index, tport);
+	return 0;
+}
 
-	/* Users cannot interrupt a close */
-	mutex_lock(&nport->tty_sem);
+static int ntty_open(struct tty_struct *tty, struct file *filp)
+{
+	struct port *port = get_port_by_tty(tty);
+	return tty_port_open(&port->port, tty, filp);
+}
 
-	WARN_ON(!port->count);
+static void ntty_shutdown(struct tty_port *tport)
+{
+	struct port *port = container_of(tport, struct port, port);
+	struct nozomi *dc = port->dc;
+	unsigned long flags;
 
+	DBG1("close: %d", port->token_dl);
+	spin_lock_irqsave(&dc->spin_mutex, flags);
+	dc->last_ier &= ~(port->token_dl);
+	writew(dc->last_ier, dc->reg_ier);
 	dc->open_ttys--;
-	port->count--;
+	spin_unlock_irqrestore(&dc->spin_mutex, flags);
+	printk("noz: shutdown %p\n", tport);
+}
 
-	if (port->count == 0) {
-		DBG1("close: %d", nport->token_dl);
-		tty_port_tty_set(port, NULL);
-		spin_lock_irqsave(&dc->spin_mutex, flags);
-		dc->last_ier &= ~(nport->token_dl);
-		writew(dc->last_ier, dc->reg_ier);
-		spin_unlock_irqrestore(&dc->spin_mutex, flags);
-	}
-	mutex_unlock(&nport->tty_sem);
+static void ntty_close(struct tty_struct *tty, struct file *filp)
+{
+	struct port *port = tty->driver_data;
+	if (port)
+		tty_port_close(&port->port, tty, filp);
+}
+
+static void ntty_hangup(struct tty_struct *tty)
+{
+	struct port *port = tty->driver_data;
+	tty_port_hangup(&port->port);
 }
 
 /*
@@ -1680,15 +1688,7 @@ static int ntty_write(struct tty_struct
 	if (!dc || !port)
 		return -ENODEV;
 
-	if (unlikely(!mutex_trylock(&port->tty_sem))) {
-		/*
-		 * must test lock as tty layer wraps calls
-		 * to this function with BKL
-		 */
-		dev_err(&dc->pdev->dev, "Would have deadlocked - "
-			"return EAGAIN\n");
-		return -EAGAIN;
-	}
+	mutex_lock(&port->tty_sem);
 
 	if (unlikely(!port->port.count)) {
 		DBG1(" ");
@@ -1728,25 +1728,23 @@ exit:
  * This method is called by the upper tty layer.
  *   #according to sources N_TTY.c it expects a value >= 0 and
  *    does not check for negative values.
+ *
+ * If the port is unplugged report lots of room and let the bits
+ * dribble away so we don't block anything.
  */
 static int ntty_write_room(struct tty_struct *tty)
 {
 	struct port *port = tty->driver_data;
-	int room = 0;
+	int room = 4096;
 	const struct nozomi *dc = get_dc_by_tty(tty);
 
-	if (!dc || !port)
-		return 0;
-	if (!mutex_trylock(&port->tty_sem))
-		return 0;
-
-	if (!port->port.count)
-		goto exit;
-
-	room = port->fifo_ul.size - kfifo_len(&port->fifo_ul);
-
-exit:
-	mutex_unlock(&port->tty_sem);
+	if (dc) {
+		mutex_lock(&port->tty_sem);
+		if (port->port.count)
+			room = port->fifo_ul.size -
+					kfifo_len(&port->fifo_ul);
+		mutex_unlock(&port->tty_sem);
+	}
 	return room;
 }
 
@@ -1906,10 +1904,16 @@ exit_in_buffer:
 	return rval;
 }
 
+static const struct tty_port_operations noz_tty_port_ops = {
+	.activate = ntty_activate,
+	.shutdown = ntty_shutdown,
+};
+
 static const struct tty_operations tty_ops = {
 	.ioctl = ntty_ioctl,
 	.open = ntty_open,
 	.close = ntty_close,
+	.hangup = ntty_hangup,
 	.write = ntty_write,
 	.write_room = ntty_write_room,
 	.unthrottle = ntty_unthrottle,
@@ -1917,6 +1921,8 @@ static const struct tty_operations tty_o
 	.chars_in_buffer = ntty_chars_in_buffer,
 	.tiocmget = ntty_tiocmget,
 	.tiocmset = ntty_tiocmset,
+	.install = ntty_install,
+	.cleanup = ntty_cleanup,
 };
 
 /* Module initialization */
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/n_tty.c linux-libre-2.6.34-gnu1/drivers/char/n_tty.c
--- linux-libre-2.6.33-gnu1/drivers/char/n_tty.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/n_tty.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,6 +48,7 @@
 #include <linux/audit.h>
 #include <linux/file.h>
 #include <linux/uaccess.h>
+#include <linux/module.h>
 
 #include <asm/system.h>
 
@@ -2091,3 +2092,19 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = {
 	.receive_buf     = n_tty_receive_buf,
 	.write_wakeup    = n_tty_write_wakeup
 };
+
+/**
+ *	n_tty_inherit_ops	-	inherit N_TTY methods
+ *	@ops: struct tty_ldisc_ops where to save N_TTY methods
+ *
+ *	Used by a generic struct tty_ldisc_ops to easily inherit N_TTY
+ *	methods.
+ */
+
+void n_tty_inherit_ops(struct tty_ldisc_ops *ops)
+{
+	*ops = tty_ldisc_N_TTY;
+	ops->owner = NULL;
+	ops->refcount = ops->flags = 0;
+}
+EXPORT_SYMBOL_GPL(n_tty_inherit_ops);
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/nvram.c linux-libre-2.6.34-gnu1/drivers/char/nvram.c
--- linux-libre-2.6.33-gnu1/drivers/char/nvram.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/nvram.c	2010-05-16 17:17:36.000000000 -0400
@@ -100,7 +100,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/fcntl.h>
 #include <linux/mc146818rtc.h>
@@ -336,14 +335,12 @@ static int nvram_ioctl(struct inode *ino
 
 static int nvram_open(struct inode *inode, struct file *file)
 {
-	lock_kernel();
 	spin_lock(&nvram_state_lock);
 
 	if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
 	    (nvram_open_mode & NVRAM_EXCL) ||
 	    ((file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE))) {
 		spin_unlock(&nvram_state_lock);
-		unlock_kernel();
 		return -EBUSY;
 	}
 
@@ -354,7 +351,6 @@ static int nvram_open(struct inode *inod
 	nvram_open_cnt++;
 
 	spin_unlock(&nvram_state_lock);
-	unlock_kernel();
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/pcmcia/cm4000_cs.c linux-libre-2.6.34-gnu1/drivers/char/pcmcia/cm4000_cs.c
--- linux-libre-2.6.33-gnu1/drivers/char/pcmcia/cm4000_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/pcmcia/cm4000_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -1026,14 +1026,16 @@ static ssize_t cmm_read(struct file *fil
 
 	xoutb(0, REG_FLAGS1(iobase));	/* clear detectCMM */
 	/* last check before exit */
-	if (!io_detect_cm4000(iobase, dev))
-		count = -ENODEV;
+	if (!io_detect_cm4000(iobase, dev)) {
+		rc = -ENODEV;
+		goto release_io;
+	}
 
 	if (test_bit(IS_INVREV, &dev->flags) && count > 0)
 		str_invert_revert(dev->rbuf, count);
 
 	if (copy_to_user(buf, dev->rbuf, count))
-		return -EFAULT;
+		rc = -EFAULT;
 
 release_io:
 	clear_bit(LOCK_IO, &dev->flags);
@@ -1047,7 +1049,7 @@ release_io:
 static ssize_t cmm_write(struct file *filp, const char __user *buf,
 			 size_t count, loff_t *ppos)
 {
-	struct cm4000_dev *dev = (struct cm4000_dev *) filp->private_data;
+	struct cm4000_dev *dev = filp->private_data;
 	unsigned int iobase = dev->p_dev->io.BasePort1;
 	unsigned short s;
 	unsigned char tmp;
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/pcmcia/ipwireless/network.c linux-libre-2.6.34-gnu1/drivers/char/pcmcia/ipwireless/network.c
--- linux-libre-2.6.33-gnu1/drivers/char/pcmcia/ipwireless/network.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/pcmcia/ipwireless/network.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/netdevice.h>
 #include <linux/ppp_channel.h>
 #include <linux/ppp_defs.h>
+#include <linux/slab.h>
 #include <linux/if_ppp.h>
 #include <linux/skbuff.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/ppdev.c linux-libre-2.6.34-gnu1/drivers/char/ppdev.c
--- linux-libre-2.6.33-gnu1/drivers/char/ppdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/ppdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,6 +64,7 @@
 #include <linux/parport.h>
 #include <linux/ctype.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/major.h>
 #include <linux/ppdev.h>
 #include <linux/smp_lock.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/ps3flash.c linux-libre-2.6.34-gnu1/drivers/char/ps3flash.c
--- linux-libre-2.6.33-gnu1/drivers/char/ps3flash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/ps3flash.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 
 #include <asm/lv1call.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/pty.c linux-libre-2.6.34-gnu1/drivers/char/pty.c
--- linux-libre-2.6.33-gnu1/drivers/char/pty.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/pty.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/uaccess.h>
 #include <linux/bitops.h>
 #include <linux/devpts_fs.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 
@@ -220,7 +221,7 @@ static void pty_set_termios(struct tty_s
  *	@tty: tty being resized
  *	@ws: window size being set.
  *
- *	Update the termios variables and send the neccessary signals to
+ *	Update the termios variables and send the necessary signals to
  *	peform a terminal resize correctly
  */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/random.c linux-libre-2.6.34-gnu1/drivers/char/random.c
--- linux-libre-2.6.33-gnu1/drivers/char/random.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/random.c	2010-05-16 17:17:36.000000000 -0400
@@ -1191,7 +1191,7 @@ const struct file_operations urandom_fop
 void generate_random_uuid(unsigned char uuid_out[16])
 {
 	get_random_bytes(uuid_out, 16);
-	/* Set UUID version to 4 --- truely random generation */
+	/* Set UUID version to 4 --- truly random generation */
 	uuid_out[6] = (uuid_out[6] & 0x0F) | 0x40;
 	/* Set the UUID variant to DCE */
 	uuid_out[8] = (uuid_out[8] & 0x3F) | 0x80;
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/raw.c linux-libre-2.6.34-gnu1/drivers/char/raw.c
--- linux-libre-2.6.33-gnu1/drivers/char/raw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/raw.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/device.h>
 #include <linux/mutex.h>
 #include <linux/smp_lock.h>
+#include <linux/gfp.h>
 
 #include <asm/uaccess.h>
 
@@ -247,6 +248,7 @@ static const struct file_operations raw_
 	.aio_read = 	generic_file_aio_read,
 	.write	=	do_sync_write,
 	.aio_write =	blkdev_aio_write,
+	.fsync	=	blkdev_fsync,
 	.open	=	raw_open,
 	.release=	raw_release,
 	.ioctl	=	raw_ioctl,
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/rio/rioinit.c linux-libre-2.6.34-gnu1/drivers/char/rio/rioinit.c
--- linux-libre-2.6.33-gnu1/drivers/char/rio/rioinit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/rio/rioinit.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/rio/riointr.c linux-libre-2.6.34-gnu1/drivers/char/rio/riointr.c
--- linux-libre-2.6.33-gnu1/drivers/char/rio/riointr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/rio/riointr.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/rio/rioparam.c linux-libre-2.6.34-gnu1/drivers/char/rio/rioparam.c
--- linux-libre-2.6.33-gnu1/drivers/char/rio/rioparam.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/rio/rioparam.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/rio/rioroute.c linux-libre-2.6.34-gnu1/drivers/char/rio/rioroute.c
--- linux-libre-2.6.33-gnu1/drivers/char/rio/rioroute.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/rio/rioroute.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <asm/io.h>
 #include <asm/system.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/rio/riotty.c linux-libre-2.6.34-gnu1/drivers/char/rio/riotty.c
--- linux-libre-2.6.33-gnu1/drivers/char/rio/riotty.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/rio/riotty.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,6 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
 #include <linux/string.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/riscom8.c linux-libre-2.6.34-gnu1/drivers/char/riscom8.c
--- linux-libre-2.6.33-gnu1/drivers/char/riscom8.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/riscom8.c	2010-05-16 17:17:36.000000000 -0400
@@ -909,6 +909,7 @@ static int rc_open(struct tty_struct *tt
 	if (error)
 		return error;
 
+	tty->driver_data = port;
 	return tty_port_open(&port->port, tty, filp);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/serial167.c linux-libre-2.6.34-gnu1/drivers/char/serial167.c
--- linux-libre-2.6.33-gnu1/drivers/char/serial167.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/serial167.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,6 +64,7 @@
 #include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/tty_flip.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -658,8 +659,7 @@ static irqreturn_t cd2401_rx_interrupt(i
 			info->mon.char_max = char_count;
 		info->mon.char_last = char_count;
 #endif
-		len = tty_buffer_request_room(tty, char_count);
-		while (len--) {
+		while (char_count--) {
 			data = base_addr[CyRDR];
 			tty_insert_flip_char(tty, data, TTY_NORMAL);
 #ifdef CYCLOM_16Y_HACK
@@ -1990,7 +1990,7 @@ void mvme167_serial_console_setup(int cf
 	/*
 	 * Attempt to set up all channels to something reasonable, and
 	 * bang out a INIT_CHAN command.  We should then be able to limit
-	 * the ammount of fiddling we have to do in normal running.
+	 * the amount of fiddling we have to do in normal running.
 	 */
 
 	for (ch = 3; ch >= 0; ch--) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/snsc_event.c linux-libre-2.6.34-gnu1/drivers/char/snsc_event.c
--- linux-libre-2.6.33-gnu1/drivers/char/snsc_event.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/snsc_event.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/unaligned.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/sonypi.c linux-libre-2.6.34-gnu1/drivers/char/sonypi.c
--- linux-libre-2.6.33-gnu1/drivers/char/sonypi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/sonypi.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,6 +50,7 @@
 #include <linux/err.h>
 #include <linux/kfifo.h>
 #include <linux/platform_device.h>
+#include <linux/gfp.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/specialix.c linux-libre-2.6.34-gnu1/drivers/char/specialix.c
--- linux-libre-2.6.33-gnu1/drivers/char/specialix.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/specialix.c	2010-05-16 17:17:36.000000000 -0400
@@ -94,6 +94,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/uaccess.h>
+#include <linux/gfp.h>
 
 #include "specialix_io8.h"
 #include "cd1865.h"
@@ -646,8 +647,6 @@ static void sx_receive(struct specialix_
 	dprintk(SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
 	port->hits[count > 8 ? 9 : count]++;
 
-	tty_buffer_request_room(tty, count);
-
 	while (count--)
 		tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL);
 	tty_flip_buffer_push(tty);
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/stallion.c linux-libre-2.6.34-gnu1/drivers/char/stallion.c
--- linux-libre-2.6.33-gnu1/drivers/char/stallion.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/stallion.c	2010-05-16 17:17:36.000000000 -0400
@@ -724,7 +724,6 @@ static int stl_open(struct tty_struct *t
 {
 	struct stlport	*portp;
 	struct stlbrd	*brdp;
-	struct tty_port *port;
 	unsigned int	minordev, brdnr, panelnr;
 	int		portnr;
 
@@ -754,7 +753,8 @@ static int stl_open(struct tty_struct *t
 	portp = brdp->panels[panelnr]->ports[portnr];
 	if (portp == NULL)
 		return -ENODEV;
-	port = &portp->port;
+
+	tty->driver_data = portp;
 	return tty_port_open(&portp->port, tty, filp);
 
 }
@@ -841,7 +841,8 @@ static void stl_close(struct tty_struct
 	pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);
 
 	portp = tty->driver_data;
-	BUG_ON(portp == NULL);
+	if(portp == NULL)
+		return;
 	tty_port_close(&portp->port, tty, filp);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/synclink.c linux-libre-2.6.34-gnu1/drivers/char/synclink.c
--- linux-libre-2.6.33-gnu1/drivers/char/synclink.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/synclink.c	2010-05-16 17:17:36.000000000 -0400
@@ -2031,7 +2031,7 @@ static int mgsl_put_char(struct tty_stru
 	if (mgsl_paranoia_check(info, tty->name, "mgsl_put_char"))
 		return 0;
 
-	if (!tty || !info->xmit_buf)
+	if (!info->xmit_buf)
 		return 0;
 
 	spin_lock_irqsave(&info->irq_spinlock, flags);
@@ -2121,7 +2121,7 @@ static int mgsl_write(struct tty_struct
 	if (mgsl_paranoia_check(info, tty->name, "mgsl_write"))
 		goto cleanup;
 
-	if (!tty || !info->xmit_buf)
+	if (!info->xmit_buf)
 		goto cleanup;
 
 	if ( info->params.mode == MGSL_MODE_HDLC ||
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/synclink_gt.c linux-libre-2.6.34-gnu1/drivers/char/synclink_gt.c
--- linux-libre-2.6.33-gnu1/drivers/char/synclink_gt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/synclink_gt.c	2010-05-16 17:17:36.000000000 -0400
@@ -468,7 +468,7 @@ static unsigned int free_tbuf_count(stru
 static unsigned int tbuf_bytes(struct slgt_info *info);
 static void reset_tbufs(struct slgt_info *info);
 static void tdma_reset(struct slgt_info *info);
-static void tx_load(struct slgt_info *info, const char *buf, unsigned int count);
+static bool tx_load(struct slgt_info *info, const char *buf, unsigned int count);
 
 static void get_signals(struct slgt_info *info);
 static void set_signals(struct slgt_info *info);
@@ -813,59 +813,32 @@ static int write(struct tty_struct *tty,
 	int ret = 0;
 	struct slgt_info *info = tty->driver_data;
 	unsigned long flags;
-	unsigned int bufs_needed;
 
 	if (sanity_check(info, tty->name, "write"))
-		goto cleanup;
+		return -EIO;
+
 	DBGINFO(("%s write count=%d\n", info->device_name, count));
 
-	if (!info->tx_buf)
-		goto cleanup;
+	if (!info->tx_buf || (count > info->max_frame_size))
+		return -EIO;
 
-	if (count > info->max_frame_size) {
-		ret = -EIO;
-		goto cleanup;
-	}
+	if (!count || tty->stopped || tty->hw_stopped)
+		return 0;
 
-	if (!count)
-		goto cleanup;
+	spin_lock_irqsave(&info->lock, flags);
 
-	if (!info->tx_active && info->tx_count) {
+	if (info->tx_count) {
 		/* send accumulated data from send_char() */
-		tx_load(info, info->tx_buf, info->tx_count);
-		goto start;
+		if (!tx_load(info, info->tx_buf, info->tx_count))
+			goto cleanup;
+		info->tx_count = 0;
 	}
-	bufs_needed = (count/DMABUFSIZE);
-	if (count % DMABUFSIZE)
-		++bufs_needed;
-	if (bufs_needed > free_tbuf_count(info))
-		goto cleanup;
-
-	ret = info->tx_count = count;
-	tx_load(info, buf, count);
-	goto start;
 
-start:
- 	if (info->tx_count && !tty->stopped && !tty->hw_stopped) {
-		spin_lock_irqsave(&info->lock,flags);
-		if (!info->tx_active)
-		 	tx_start(info);
-		else if (!(rd_reg32(info, TDCSR) & BIT0)) {
-			/* transmit still active but transmit DMA stopped */
-			unsigned int i = info->tbuf_current;
-			if (!i)
-				i = info->tbuf_count;
-			i--;
-			/* if DMA buf unsent must try later after tx idle */
-			if (desc_count(info->tbufs[i]))
-				ret = 0;
-		}
-		if (ret > 0)
-			update_tx_timer(info);
-		spin_unlock_irqrestore(&info->lock,flags);
- 	}
+	if (tx_load(info, buf, count))
+		ret = count;
 
 cleanup:
+	spin_unlock_irqrestore(&info->lock, flags);
 	DBGINFO(("%s write rc=%d\n", info->device_name, ret));
 	return ret;
 }
@@ -882,7 +855,7 @@ static int put_char(struct tty_struct *t
 	if (!info->tx_buf)
 		return 0;
 	spin_lock_irqsave(&info->lock,flags);
-	if (!info->tx_active && (info->tx_count < info->max_frame_size)) {
+	if (info->tx_count < info->max_frame_size) {
 		info->tx_buf[info->tx_count++] = ch;
 		ret = 1;
 	}
@@ -981,10 +954,8 @@ static void flush_chars(struct tty_struc
 	DBGINFO(("%s flush_chars start transmit\n", info->device_name));
 
 	spin_lock_irqsave(&info->lock,flags);
-	if (!info->tx_active && info->tx_count) {
-		tx_load(info, info->tx_buf,info->tx_count);
-	 	tx_start(info);
-	}
+	if (info->tx_count && tx_load(info, info->tx_buf, info->tx_count))
+		info->tx_count = 0;
 	spin_unlock_irqrestore(&info->lock,flags);
 }
 
@@ -997,10 +968,9 @@ static void flush_buffer(struct tty_stru
 		return;
 	DBGINFO(("%s flush_buffer\n", info->device_name));
 
-	spin_lock_irqsave(&info->lock,flags);
-	if (!info->tx_active)
-		info->tx_count = 0;
-	spin_unlock_irqrestore(&info->lock,flags);
+	spin_lock_irqsave(&info->lock, flags);
+	info->tx_count = 0;
+	spin_unlock_irqrestore(&info->lock, flags);
 
 	tty_wakeup(tty);
 }
@@ -1033,12 +1003,10 @@ static void tx_release(struct tty_struct
 	if (sanity_check(info, tty->name, "tx_release"))
 		return;
 	DBGINFO(("%s tx_release\n", info->device_name));
-	spin_lock_irqsave(&info->lock,flags);
-	if (!info->tx_active && info->tx_count) {
-		tx_load(info, info->tx_buf, info->tx_count);
-	 	tx_start(info);
-	}
-	spin_unlock_irqrestore(&info->lock,flags);
+	spin_lock_irqsave(&info->lock, flags);
+	if (info->tx_count && tx_load(info, info->tx_buf, info->tx_count))
+		info->tx_count = 0;
+	spin_unlock_irqrestore(&info->lock, flags);
 }
 
 /*
@@ -1506,27 +1474,25 @@ static netdev_tx_t hdlcdev_xmit(struct s
 
 	DBGINFO(("%s hdlc_xmit\n", dev->name));
 
+	if (!skb->len)
+		return NETDEV_TX_OK;
+
 	/* stop sending until this frame completes */
 	netif_stop_queue(dev);
 
-	/* copy data to device buffers */
-	info->tx_count = skb->len;
-	tx_load(info, skb->data, skb->len);
-
 	/* update network statistics */
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += skb->len;
 
-	/* done with socket buffer, so free it */
-	dev_kfree_skb(skb);
-
 	/* save start time for transmit timeout detection */
 	dev->trans_start = jiffies;
 
-	spin_lock_irqsave(&info->lock,flags);
-	tx_start(info);
-	update_tx_timer(info);
-	spin_unlock_irqrestore(&info->lock,flags);
+	spin_lock_irqsave(&info->lock, flags);
+	tx_load(info, skb->data, skb->len);
+	spin_unlock_irqrestore(&info->lock, flags);
+
+	/* done with socket buffer, so free it */
+	dev_kfree_skb(skb);
 
 	return NETDEV_TX_OK;
 }
@@ -2180,7 +2146,7 @@ static void isr_serial(struct slgt_info
 
 	if (info->params.mode == MGSL_MODE_ASYNC) {
 		if (status & IRQ_TXIDLE) {
-			if (info->tx_count)
+			if (info->tx_active)
 				isr_txeom(info, status);
 		}
 		if (info->rx_pio && (status & IRQ_RXDATA))
@@ -2276,13 +2242,42 @@ static void isr_tdma(struct slgt_info *i
 	}
 }
 
+/*
+ * return true if there are unsent tx DMA buffers, otherwise false
+ *
+ * if there are unsent buffers then info->tbuf_start
+ * is set to index of first unsent buffer
+ */
+static bool unsent_tbufs(struct slgt_info *info)
+{
+	unsigned int i = info->tbuf_current;
+	bool rc = false;
+
+	/*
+	 * search backwards from last loaded buffer (precedes tbuf_current)
+	 * for first unsent buffer (desc_count > 0)
+	 */
+
+	do {
+		if (i)
+			i--;
+		else
+			i = info->tbuf_count - 1;
+		if (!desc_count(info->tbufs[i]))
+			break;
+		info->tbuf_start = i;
+		rc = true;
+	} while (i != info->tbuf_current);
+
+	return rc;
+}
+
 static void isr_txeom(struct slgt_info *info, unsigned short status)
 {
 	DBGISR(("%s txeom status=%04x\n", info->device_name, status));
 
 	slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER);
 	tdma_reset(info);
-	reset_tbufs(info);
 	if (status & IRQ_TXUNDER) {
 		unsigned short val = rd_reg16(info, TCR);
 		wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */
@@ -2297,8 +2292,12 @@ static void isr_txeom(struct slgt_info *
 				info->icount.txok++;
 		}
 
+		if (unsent_tbufs(info)) {
+			tx_start(info);
+			update_tx_timer(info);
+			return;
+		}
 		info->tx_active = false;
-		info->tx_count = 0;
 
 		del_timer(&info->tx_timer);
 
@@ -3949,7 +3948,7 @@ static void tx_start(struct slgt_info *i
 		info->tx_enabled = true;
 	}
 
-	if (info->tx_count) {
+	if (desc_count(info->tbufs[info->tbuf_start])) {
 		info->drop_rts_on_tx_done = false;
 
 		if (info->params.mode != MGSL_MODE_ASYNC) {
@@ -4772,25 +4771,36 @@ static unsigned int tbuf_bytes(struct sl
 }
 
 /*
- * load transmit DMA buffer(s) with data
+ * load data into transmit DMA buffer ring and start transmitter if needed
+ * return true if data accepted, otherwise false (buffers full)
  */
-static void tx_load(struct slgt_info *info, const char *buf, unsigned int size)
+static bool tx_load(struct slgt_info *info, const char *buf, unsigned int size)
 {
 	unsigned short count;
 	unsigned int i;
 	struct slgt_desc *d;
 
-	if (size == 0)
-		return;
+	/* check required buffer space */
+	if (DIV_ROUND_UP(size, DMABUFSIZE) > free_tbuf_count(info))
+		return false;
 
 	DBGDATA(info, buf, size, "tx");
 
+	/*
+	 * copy data to one or more DMA buffers in circular ring
+	 * tbuf_start   = first buffer for this data
+	 * tbuf_current = next free buffer
+	 *
+	 * Copy all data before making data visible to DMA controller by
+	 * setting descriptor count of the first buffer.
+	 * This prevents an active DMA controller from reading the first DMA
+	 * buffers of a frame and stopping before the final buffers are filled.
+	 */
+
 	info->tbuf_start = i = info->tbuf_current;
 
 	while (size) {
 		d = &info->tbufs[i];
-		if (++i == info->tbuf_count)
-			i = 0;
 
 		count = (unsigned short)((size > DMABUFSIZE) ? DMABUFSIZE : size);
 		memcpy(d->buf, buf, count);
@@ -4808,11 +4818,27 @@ static void tx_load(struct slgt_info *in
 		else
 			set_desc_eof(*d, 0);
 
-		set_desc_count(*d, count);
+		/* set descriptor count for all but first buffer */
+		if (i != info->tbuf_start)
+			set_desc_count(*d, count);
 		d->buf_count = count;
+
+		if (++i == info->tbuf_count)
+			i = 0;
 	}
 
 	info->tbuf_current = i;
+
+	/* set first buffer count to make new data visible to DMA controller */
+	d = &info->tbufs[info->tbuf_start];
+	set_desc_count(*d, d->buf_count);
+
+	/* start transmitter if needed and update transmit timeout */
+	if (!info->tx_active)
+		tx_start(info);
+	update_tx_timer(info);
+
+	return true;
 }
 
 static int register_test(struct slgt_info *info)
@@ -4934,9 +4960,7 @@ static int loopback_test(struct slgt_inf
 	spin_lock_irqsave(&info->lock,flags);
 	async_mode(info);
 	rx_start(info);
-	info->tx_count = count;
 	tx_load(info, buf, count);
-	tx_start(info);
 	spin_unlock_irqrestore(&info->lock, flags);
 
 	/* wait for receive complete */
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/sysrq.c linux-libre-2.6.34-gnu1/drivers/char/sysrq.c
--- linux-libre-2.6.33-gnu1/drivers/char/sysrq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/sysrq.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/workqueue.h>
 #include <linux/hrtimer.h>
 #include <linux/oom.h>
+#include <linux/slab.h>
 
 #include <asm/ptrace.h>
 #include <asm/irq_regs.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/tpm/tpm_bios.c linux-libre-2.6.34-gnu1/drivers/char/tpm/tpm_bios.c
--- linux-libre-2.6.33-gnu1/drivers/char/tpm/tpm_bios.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/tpm/tpm_bios.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/fs.h>
 #include <linux/security.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <acpi/acpi.h>
 #include "tpm.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/tpm/tpm.c linux-libre-2.6.34-gnu1/drivers/char/tpm/tpm.c
--- linux-libre-2.6.33-gnu1/drivers/char/tpm/tpm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/tpm/tpm.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
  */
 
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/tpm/tpm_nsc.c linux-libre-2.6.34-gnu1/drivers/char/tpm/tpm_nsc.c
--- linux-libre-2.6.33-gnu1/drivers/char/tpm/tpm_nsc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/tpm/tpm_nsc.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include "tpm.h"
 
 /* National definitions */
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/tpm/tpm_tis.c linux-libre-2.6.34-gnu1/drivers/char/tpm/tpm_tis.c
--- linux-libre-2.6.33-gnu1/drivers/char/tpm/tpm_tis.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/tpm/tpm_tis.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/pnp.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/wait.h>
 #include "tpm.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/tty_audit.c linux-libre-2.6.34-gnu1/drivers/char/tty_audit.c
--- linux-libre-2.6.33-gnu1/drivers/char/tty_audit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/tty_audit.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/audit.h>
+#include <linux/slab.h>
 #include <linux/tty.h>
 
 struct tty_audit_buf {
@@ -148,7 +149,6 @@ void tty_audit_fork(struct signal_struct
 	spin_lock_irq(&current->sighand->siglock);
 	sig->audit_tty = current->signal->audit_tty;
 	spin_unlock_irq(&current->sighand->siglock);
-	sig->tty_audit_buf = NULL;
 }
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/tty_buffer.c linux-libre-2.6.34-gnu1/drivers/char/tty_buffer.c
--- linux-libre-2.6.33-gnu1/drivers/char/tty_buffer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/tty_buffer.c	2010-05-16 17:17:36.000000000 -0400
@@ -231,9 +231,10 @@ int tty_buffer_request_room(struct tty_s
 EXPORT_SYMBOL_GPL(tty_buffer_request_room);
 
 /**
- *	tty_insert_flip_string	-	Add characters to the tty buffer
+ *	tty_insert_flip_string_fixed_flag - Add characters to the tty buffer
  *	@tty: tty structure
  *	@chars: characters
+ *	@flag: flag value for each character
  *	@size: size
  *
  *	Queue a series of bytes to the tty buffering. All the characters
@@ -242,18 +243,19 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_roo
  *	Locking: Called functions may take tty->buf.lock
  */
 
-int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars,
-				size_t size)
+int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
+		const unsigned char *chars, char flag, size_t size)
 {
 	int copied = 0;
 	do {
-		int space = tty_buffer_request_room(tty, size - copied);
+		int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
+		int space = tty_buffer_request_room(tty, goal);
 		struct tty_buffer *tb = tty->buf.tail;
 		/* If there is no space then tb may be NULL */
 		if (unlikely(space == 0))
 			break;
 		memcpy(tb->char_buf_ptr + tb->used, chars, space);
-		memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
+		memset(tb->flag_buf_ptr + tb->used, flag, space);
 		tb->used += space;
 		copied += space;
 		chars += space;
@@ -262,7 +264,7 @@ int tty_insert_flip_string(struct tty_st
 	} while (unlikely(size > copied));
 	return copied;
 }
-EXPORT_SYMBOL(tty_insert_flip_string);
+EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag);
 
 /**
  *	tty_insert_flip_string_flags	-	Add characters to the tty buffer
@@ -283,7 +285,8 @@ int tty_insert_flip_string_flags(struct
 {
 	int copied = 0;
 	do {
-		int space = tty_buffer_request_room(tty, size - copied);
+		int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
+		int space = tty_buffer_request_room(tty, goal);
 		struct tty_buffer *tb = tty->buf.tail;
 		/* If there is no space then tb may be NULL */
 		if (unlikely(space == 0))
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/tty_io.c linux-libre-2.6.34-gnu1/drivers/char/tty_io.c
--- linux-libre-2.6.33-gnu1/drivers/char/tty_io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/tty_io.c	2010-05-16 17:17:36.000000000 -0400
@@ -1423,6 +1423,8 @@ static void release_one_tty(struct work_
 	list_del_init(&tty->tty_files);
 	file_list_unlock();
 
+	put_pid(tty->pgrp);
+	put_pid(tty->session);
 	free_tty_struct(tty);
 }
 
@@ -1873,6 +1875,7 @@ got_driver:
 		 */
 		if (filp->f_op == &hung_up_tty_fops)
 			filp->f_op = &tty_fops;
+		unlock_kernel();
 		goto retry_open;
 	}
 	unlock_kernel();
@@ -2028,7 +2031,7 @@ static int tiocgwinsz(struct tty_struct
  *	@rows: rows (character)
  *	@cols: cols (character)
  *
- *	Update the termios variables and send the neccessary signals to
+ *	Update the termios variables and send the necessary signals to
  *	peform a terminal resize correctly
  */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/tty_ldisc.c linux-libre-2.6.34-gnu1/drivers/char/tty_ldisc.c
--- linux-libre-2.6.33-gnu1/drivers/char/tty_ldisc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/tty_ldisc.c	2010-05-16 17:17:36.000000000 -0400
@@ -706,12 +706,13 @@ static void tty_reset_termios(struct tty
 /**
  *	tty_ldisc_reinit	-	reinitialise the tty ldisc
  *	@tty: tty to reinit
+ *	@ldisc: line discipline to reinitialize
  *
- *	Switch the tty back to N_TTY line discipline and leave the
- *	ldisc state closed
+ *	Switch the tty to a line discipline and leave the ldisc
+ *	state closed
  */
 
-static void tty_ldisc_reinit(struct tty_struct *tty)
+static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
 {
 	struct tty_ldisc *ld;
 
@@ -721,10 +722,10 @@ static void tty_ldisc_reinit(struct tty_
 	/*
 	 *	Switch the line discipline back
 	 */
-	ld = tty_ldisc_get(N_TTY);
+	ld = tty_ldisc_get(ldisc);
 	BUG_ON(IS_ERR(ld));
 	tty_ldisc_assign(tty, ld);
-	tty_set_termios_ldisc(tty, N_TTY);
+	tty_set_termios_ldisc(tty, ldisc);
 }
 
 /**
@@ -745,6 +746,8 @@ static void tty_ldisc_reinit(struct tty_
 void tty_ldisc_hangup(struct tty_struct *tty)
 {
 	struct tty_ldisc *ld;
+	int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS;
+	int err = 0;
 
 	/*
 	 * FIXME! What are the locking issues here? This may me overdoing
@@ -772,25 +775,32 @@ void tty_ldisc_hangup(struct tty_struct
 	wake_up_interruptible_poll(&tty->read_wait, POLLIN);
 	/*
 	 * Shutdown the current line discipline, and reset it to
-	 * N_TTY.
+	 * N_TTY if need be.
+	 *
+	 * Avoid racing set_ldisc or tty_ldisc_release
 	 */
-	if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
-		/* Avoid racing set_ldisc or tty_ldisc_release */
-		mutex_lock(&tty->ldisc_mutex);
-		tty_ldisc_halt(tty);
-		if (tty->ldisc) {	/* Not yet closed */
-			/* Switch back to N_TTY */
-			tty_ldisc_reinit(tty);
-			/* At this point we have a closed ldisc and we want to
-			   reopen it. We could defer this to the next open but
-			   it means auditing a lot of other paths so this is
-			   a FIXME */
+	mutex_lock(&tty->ldisc_mutex);
+	tty_ldisc_halt(tty);
+	/* At this point we have a closed ldisc and we want to
+	   reopen it. We could defer this to the next open but
+	   it means auditing a lot of other paths so this is
+	   a FIXME */
+	if (tty->ldisc) {	/* Not yet closed */
+		if (reset == 0) {
+			tty_ldisc_reinit(tty, tty->termios->c_line);
+			err = tty_ldisc_open(tty, tty->ldisc);
+		}
+		/* If the re-open fails or we reset then go to N_TTY. The
+		   N_TTY open cannot fail */
+		if (reset || err) {
+			tty_ldisc_reinit(tty, N_TTY);
 			WARN_ON(tty_ldisc_open(tty, tty->ldisc));
-			tty_ldisc_enable(tty);
 		}
-		mutex_unlock(&tty->ldisc_mutex);
-		tty_reset_termios(tty);
+		tty_ldisc_enable(tty);
 	}
+	mutex_unlock(&tty->ldisc_mutex);
+	if (reset)
+		tty_reset_termios(tty);
 }
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/tty_port.c linux-libre-2.6.34-gnu1/drivers/char/tty_port.c
--- linux-libre-2.6.33-gnu1/drivers/char/tty_port.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/tty_port.c	2010-05-16 17:17:36.000000000 -0400
@@ -119,7 +119,7 @@ EXPORT_SYMBOL(tty_port_tty_set);
 static void tty_port_shutdown(struct tty_port *port)
 {
 	mutex_lock(&port->mutex);
-	if (port->ops->shutdown &&
+	if (port->ops->shutdown && !port->console &&
 		test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
 			port->ops->shutdown(port);
 	mutex_unlock(&port->mutex);
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/viotape.c linux-libre-2.6.34-gnu1/drivers/char/viotape.c
--- linux-libre-2.6.33-gnu1/drivers/char/viotape.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/viotape.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/virtio_console.c linux-libre-2.6.34-gnu1/drivers/char/virtio_console.c
--- linux-libre-2.6.33-gnu1/drivers/char/virtio_console.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/virtio_console.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,18 +1,6 @@
-/*D:300
- * The Guest console driver
- *
- * Writing console drivers is one of the few remaining Dark Arts in Linux.
- * Fortunately for us, the path of virtual consoles has been well-trodden by
- * the PowerPC folks, who wrote "hvc_console.c" to generically support any
- * virtual console.  We use that infrastructure which only requires us to write
- * the basic put_chars and get_chars functions and call the right register
- * functions.
- :*/
-
-/*M:002 The console can be flooded: while the Guest is processing input the
- * Host can send more.  Buffering in the Host could alleviate this, but it is a
- * difficult problem in general. :*/
-/* Copyright (C) 2006, 2007 Rusty Russell, IBM Corporation
+/*
+ * Copyright (C) 2006, 2007, 2009 Rusty Russell, IBM Corporation
+ * Copyright (C) 2009, 2010 Red Hat, 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
@@ -28,142 +16,724 @@
  * 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/cdev.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
 #include <linux/err.h>
+#include <linux/fs.h>
 #include <linux/init.h>
+#include <linux/list.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
 #include <linux/virtio.h>
 #include <linux/virtio_console.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
 #include "hvc_console.h"
 
-/*D:340 These represent our input and output console queues, and the virtio
- * operations for them. */
-static struct virtqueue *in_vq, *out_vq;
-static struct virtio_device *vdev;
+/* Moved here from .h file in order to disable MULTIPORT. */
+#define VIRTIO_CONSOLE_F_MULTIPORT 1	/* Does host provide multiple ports? */
 
-/* This is our input buffer, and how much data is left in it. */
-static unsigned int in_len;
-static char *in, *inbuf;
+struct virtio_console_multiport_conf {
+	struct virtio_console_config config;
+	/* max. number of ports this device can hold */
+	__u32 max_nr_ports;
+	/* number of ports added so far */
+	__u32 nr_ports;
+} __attribute__((packed));
 
-/* The operations for our console. */
-static struct hv_ops virtio_cons;
+/*
+ * A message that's passed between the Host and the Guest for a
+ * particular port.
+ */
+struct virtio_console_control {
+	__u32 id;		/* Port number */
+	__u16 event;		/* The kind of control event (see below) */
+	__u16 value;		/* Extra information for the key */
+};
 
-/* The hvc device */
-static struct hvc_struct *hvc;
+/* Some events for control messages */
+#define VIRTIO_CONSOLE_PORT_READY	0
+#define VIRTIO_CONSOLE_CONSOLE_PORT	1
+#define VIRTIO_CONSOLE_RESIZE		2
+#define VIRTIO_CONSOLE_PORT_OPEN	3
+#define VIRTIO_CONSOLE_PORT_NAME	4
+#define VIRTIO_CONSOLE_PORT_REMOVE	5
 
-/*D:310 The put_chars() callback is pretty straightforward.
+/*
+ * This is a global struct for storing common data for all the devices
+ * this driver handles.
  *
- * We turn the characters into a scatter-gather list, add it to the output
- * queue and then kick the Host.  Then we sit here waiting for it to finish:
- * inefficient in theory, but in practice implementations will do it
- * immediately (lguest's Launcher does). */
-static int put_chars(u32 vtermno, const char *buf, int count)
+ * Mainly, it has a linked list for all the consoles in one place so
+ * that callbacks from hvc for get_chars(), put_chars() work properly
+ * across multiple devices and multiple ports per device.
+ */
+struct ports_driver_data {
+	/* Used for registering chardevs */
+	struct class *class;
+
+	/* Used for exporting per-port information to debugfs */
+	struct dentry *debugfs_dir;
+
+	/* Number of devices this driver is handling */
+	unsigned int index;
+
+	/*
+	 * This is used to keep track of the number of hvc consoles
+	 * spawned by this driver.  This number is given as the first
+	 * argument to hvc_alloc().  To correctly map an initial
+	 * console spawned via hvc_instantiate to the console being
+	 * hooked up via hvc_alloc, we need to pass the same vtermno.
+	 *
+	 * We also just assume the first console being initialised was
+	 * the first one that got used as the initial console.
+	 */
+	unsigned int next_vtermno;
+
+	/* All the console devices handled by this driver */
+	struct list_head consoles;
+};
+static struct ports_driver_data pdrvdata;
+
+DEFINE_SPINLOCK(pdrvdata_lock);
+
+/* This struct holds information that's relevant only for console ports */
+struct console {
+	/* We'll place all consoles in a list in the pdrvdata struct */
+	struct list_head list;
+
+	/* The hvc device associated with this console port */
+	struct hvc_struct *hvc;
+
+	/*
+	 * This number identifies the number that we used to register
+	 * with hvc in hvc_instantiate() and hvc_alloc(); this is the
+	 * number passed on by the hvc callbacks to us to
+	 * differentiate between the other console ports handled by
+	 * this driver
+	 */
+	u32 vtermno;
+};
+
+struct port_buffer {
+	char *buf;
+
+	/* size of the buffer in *buf above */
+	size_t size;
+
+	/* used length of the buffer */
+	size_t len;
+	/* offset in the buf from which to consume data */
+	size_t offset;
+};
+
+/*
+ * This is a per-device struct that stores data common to all the
+ * ports for that device (vdev->priv).
+ */
+struct ports_device {
+	/*
+	 * Workqueue handlers where we process deferred work after
+	 * notification
+	 */
+	struct work_struct control_work;
+	struct work_struct config_work;
+
+	struct list_head ports;
+
+	/* To protect the list of ports */
+	spinlock_t ports_lock;
+
+	/* To protect the vq operations for the control channel */
+	spinlock_t cvq_lock;
+
+	/* The current config space is stored here */
+	struct virtio_console_multiport_conf config;
+
+	/* The virtio device we're associated with */
+	struct virtio_device *vdev;
+
+	/*
+	 * A couple of virtqueues for the control channel: one for
+	 * guest->host transfers, one for host->guest transfers
+	 */
+	struct virtqueue *c_ivq, *c_ovq;
+
+	/* Array of per-port IO virtqueues */
+	struct virtqueue **in_vqs, **out_vqs;
+
+	/* Used for numbering devices for sysfs and debugfs */
+	unsigned int drv_index;
+
+	/* Major number for this device.  Ports will be created as minors. */
+	int chr_major;
+};
+
+/* This struct holds the per-port data */
+struct port {
+	/* Next port in the list, head is in the ports_device */
+	struct list_head list;
+
+	/* Pointer to the parent virtio_console device */
+	struct ports_device *portdev;
+
+	/* The current buffer from which data has to be fed to readers */
+	struct port_buffer *inbuf;
+
+	/*
+	 * To protect the operations on the in_vq associated with this
+	 * port.  Has to be a spinlock because it can be called from
+	 * interrupt context (get_char()).
+	 */
+	spinlock_t inbuf_lock;
+
+	/* The IO vqs for this port */
+	struct virtqueue *in_vq, *out_vq;
+
+	/* File in the debugfs directory that exposes this port's information */
+	struct dentry *debugfs_file;
+
+	/*
+	 * The entries in this struct will be valid if this port is
+	 * hooked up to an hvc console
+	 */
+	struct console cons;
+
+	/* Each port associates with a separate char device */
+	struct cdev cdev;
+	struct device *dev;
+
+	/* A waitqueue for poll() or blocking read operations */
+	wait_queue_head_t waitqueue;
+
+	/* The 'name' of the port that we expose via sysfs properties */
+	char *name;
+
+	/* The 'id' to identify the port with the Host */
+	u32 id;
+
+	/* Is the host device open */
+	bool host_connected;
+
+	/* We should allow only one process to open a port */
+	bool guest_connected;
+};
+
+/* This is the very early arch-specified put chars function. */
+static int (*early_put_chars)(u32, const char *, int);
+
+static struct port *find_port_by_vtermno(u32 vtermno)
+{
+	struct port *port;
+	struct console *cons;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdrvdata_lock, flags);
+	list_for_each_entry(cons, &pdrvdata.consoles, list) {
+		if (cons->vtermno == vtermno) {
+			port = container_of(cons, struct port, cons);
+			goto out;
+		}
+	}
+	port = NULL;
+out:
+	spin_unlock_irqrestore(&pdrvdata_lock, flags);
+	return port;
+}
+
+static struct port *find_port_by_id(struct ports_device *portdev, u32 id)
+{
+	struct port *port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&portdev->ports_lock, flags);
+	list_for_each_entry(port, &portdev->ports, list)
+		if (port->id == id)
+			goto out;
+	port = NULL;
+out:
+	spin_unlock_irqrestore(&portdev->ports_lock, flags);
+
+	return port;
+}
+
+static struct port *find_port_by_vq(struct ports_device *portdev,
+				    struct virtqueue *vq)
+{
+	struct port *port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&portdev->ports_lock, flags);
+	list_for_each_entry(port, &portdev->ports, list)
+		if (port->in_vq == vq || port->out_vq == vq)
+			goto out;
+	port = NULL;
+out:
+	spin_unlock_irqrestore(&portdev->ports_lock, flags);
+	return port;
+}
+
+static bool is_console_port(struct port *port)
+{
+	if (port->cons.hvc)
+		return true;
+	return false;
+}
+
+static inline bool use_multiport(struct ports_device *portdev)
+{
+	/*
+	 * This condition can be true when put_chars is called from
+	 * early_init
+	 */
+	if (!portdev->vdev)
+		return 0;
+	return portdev->vdev->features[0] & (1 << VIRTIO_CONSOLE_F_MULTIPORT);
+}
+
+static void free_buf(struct port_buffer *buf)
+{
+	kfree(buf->buf);
+	kfree(buf);
+}
+
+static struct port_buffer *alloc_buf(size_t buf_size)
+{
+	struct port_buffer *buf;
+
+	buf = kmalloc(sizeof(*buf), GFP_KERNEL);
+	if (!buf)
+		goto fail;
+	buf->buf = kzalloc(buf_size, GFP_KERNEL);
+	if (!buf->buf)
+		goto free_buf;
+	buf->len = 0;
+	buf->offset = 0;
+	buf->size = buf_size;
+	return buf;
+
+free_buf:
+	kfree(buf);
+fail:
+	return NULL;
+}
+
+/* Callers should take appropriate locks */
+static void *get_inbuf(struct port *port)
+{
+	struct port_buffer *buf;
+	struct virtqueue *vq;
+	unsigned int len;
+
+	vq = port->in_vq;
+	buf = vq->vq_ops->get_buf(vq, &len);
+	if (buf) {
+		buf->len = len;
+		buf->offset = 0;
+	}
+	return buf;
+}
+
+/*
+ * Create a scatter-gather list representing our input buffer and put
+ * it in the queue.
+ *
+ * Callers should take appropriate locks.
+ */
+static int add_inbuf(struct virtqueue *vq, struct port_buffer *buf)
 {
 	struct scatterlist sg[1];
+	int ret;
+
+	sg_init_one(sg, buf->buf, buf->size);
+
+	ret = vq->vq_ops->add_buf(vq, sg, 0, 1, buf);
+	vq->vq_ops->kick(vq);
+	return ret;
+}
+
+/* Discard any unread data this port has. Callers lockers. */
+static void discard_port_data(struct port *port)
+{
+	struct port_buffer *buf;
+	struct virtqueue *vq;
 	unsigned int len;
+	int ret;
 
-	/* This is a convenient routine to initialize a single-elem sg list */
-	sg_init_one(sg, buf, count);
+	vq = port->in_vq;
+	if (port->inbuf)
+		buf = port->inbuf;
+	else
+		buf = vq->vq_ops->get_buf(vq, &len);
 
-	/* add_buf wants a token to identify this buffer: we hand it any
-	 * non-NULL pointer, since there's only ever one buffer. */
-	if (out_vq->vq_ops->add_buf(out_vq, sg, 1, 0, (void *)1) >= 0) {
-		/* Tell Host to go! */
-		out_vq->vq_ops->kick(out_vq);
-		/* Chill out until it's done with the buffer. */
-		while (!out_vq->vq_ops->get_buf(out_vq, &len))
-			cpu_relax();
+	ret = 0;
+	while (buf) {
+		if (add_inbuf(vq, buf) < 0) {
+			ret++;
+			free_buf(buf);
+		}
+		buf = vq->vq_ops->get_buf(vq, &len);
 	}
+	port->inbuf = NULL;
+	if (ret)
+		dev_warn(port->dev, "Errors adding %d buffers back to vq\n",
+			 ret);
+}
 
-	/* We're expected to return the amount of data we wrote: all of it. */
-	return count;
+static bool port_has_data(struct port *port)
+{
+	unsigned long flags;
+	bool ret;
+
+	spin_lock_irqsave(&port->inbuf_lock, flags);
+	if (port->inbuf) {
+		ret = true;
+		goto out;
+	}
+	port->inbuf = get_inbuf(port);
+	if (port->inbuf) {
+		ret = true;
+		goto out;
+	}
+	ret = false;
+out:
+	spin_unlock_irqrestore(&port->inbuf_lock, flags);
+	return ret;
 }
 
-/* Create a scatter-gather list representing our input buffer and put it in the
- * queue. */
-static void add_inbuf(void)
+static ssize_t send_control_msg(struct port *port, unsigned int event,
+				unsigned int value)
 {
 	struct scatterlist sg[1];
-	sg_init_one(sg, inbuf, PAGE_SIZE);
+	struct virtio_console_control cpkt;
+	struct virtqueue *vq;
+	unsigned int len;
 
-	/* We should always be able to add one buffer to an empty queue. */
-	if (in_vq->vq_ops->add_buf(in_vq, sg, 0, 1, inbuf) < 0)
-		BUG();
-	in_vq->vq_ops->kick(in_vq);
+	if (!use_multiport(port->portdev))
+		return 0;
+
+	cpkt.id = port->id;
+	cpkt.event = event;
+	cpkt.value = value;
+
+	vq = port->portdev->c_ovq;
+
+	sg_init_one(sg, &cpkt, sizeof(cpkt));
+	if (vq->vq_ops->add_buf(vq, sg, 1, 0, &cpkt) >= 0) {
+		vq->vq_ops->kick(vq);
+		while (!vq->vq_ops->get_buf(vq, &len))
+			cpu_relax();
+	}
+	return 0;
 }
 
-/*D:350 get_chars() is the callback from the hvc_console infrastructure when
- * an interrupt is received.
- *
- * Most of the code deals with the fact that the hvc_console() infrastructure
- * only asks us for 16 bytes at a time.  We keep in_offset and in_used fields
- * for partially-filled buffers. */
-static int get_chars(u32 vtermno, char *buf, int count)
+static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count)
 {
-	/* If we don't have an input queue yet, we can't get input. */
-	BUG_ON(!in_vq);
+	struct scatterlist sg[1];
+	struct virtqueue *out_vq;
+	ssize_t ret;
+	unsigned int len;
 
-	/* No buffer?  Try to get one. */
-	if (!in_len) {
-		in = in_vq->vq_ops->get_buf(in_vq, &in_len);
-		if (!in)
+	out_vq = port->out_vq;
+
+	sg_init_one(sg, in_buf, in_count);
+	ret = out_vq->vq_ops->add_buf(out_vq, sg, 1, 0, in_buf);
+
+	/* Tell Host to go! */
+	out_vq->vq_ops->kick(out_vq);
+
+	if (ret < 0) {
+		in_count = 0;
+		goto fail;
+	}
+
+	/* Wait till the host acknowledges it pushed out the data we sent. */
+	while (!out_vq->vq_ops->get_buf(out_vq, &len))
+		cpu_relax();
+fail:
+	/* We're expected to return the amount of data we wrote */
+	return in_count;
+}
+
+/*
+ * Give out the data that's requested from the buffer that we have
+ * queued up.
+ */
+static ssize_t fill_readbuf(struct port *port, char *out_buf, size_t out_count,
+			    bool to_user)
+{
+	struct port_buffer *buf;
+	unsigned long flags;
+
+	if (!out_count || !port_has_data(port))
+		return 0;
+
+	buf = port->inbuf;
+	out_count = min(out_count, buf->len - buf->offset);
+
+	if (to_user) {
+		ssize_t ret;
+
+		ret = copy_to_user(out_buf, buf->buf + buf->offset, out_count);
+		if (ret)
+			return -EFAULT;
+	} else {
+		memcpy(out_buf, buf->buf + buf->offset, out_count);
+	}
+
+	buf->offset += out_count;
+
+	if (buf->offset == buf->len) {
+		/*
+		 * We're done using all the data in this buffer.
+		 * Re-queue so that the Host can send us more data.
+		 */
+		spin_lock_irqsave(&port->inbuf_lock, flags);
+		port->inbuf = NULL;
+
+		if (add_inbuf(port->in_vq, buf) < 0)
+			dev_warn(port->dev, "failed add_buf\n");
+
+		spin_unlock_irqrestore(&port->inbuf_lock, flags);
+	}
+	/* Return the number of bytes actually copied */
+	return out_count;
+}
+
+/* The condition that must be true for polling to end */
+static bool wait_is_over(struct port *port)
+{
+	return port_has_data(port) || !port->host_connected;
+}
+
+static ssize_t port_fops_read(struct file *filp, char __user *ubuf,
+			      size_t count, loff_t *offp)
+{
+	struct port *port;
+	ssize_t ret;
+
+	port = filp->private_data;
+
+	if (!port_has_data(port)) {
+		/*
+		 * If nothing's connected on the host just return 0 in
+		 * case of list_empty; this tells the userspace app
+		 * that there's no connection
+		 */
+		if (!port->host_connected)
 			return 0;
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+
+		ret = wait_event_interruptible(port->waitqueue,
+					       wait_is_over(port));
+		if (ret < 0)
+			return ret;
 	}
+	/*
+	 * We could've received a disconnection message while we were
+	 * waiting for more data.
+	 *
+	 * This check is not clubbed in the if() statement above as we
+	 * might receive some data as well as the host could get
+	 * disconnected after we got woken up from our wait.  So we
+	 * really want to give off whatever data we have and only then
+	 * check for host_connected.
+	 */
+	if (!port_has_data(port) && !port->host_connected)
+		return 0;
 
-	/* You want more than we have to give?  Well, try wanting less! */
-	if (in_len < count)
-		count = in_len;
+	return fill_readbuf(port, ubuf, count, true);
+}
 
-	/* Copy across to their buffer and increment offset. */
-	memcpy(buf, in, count);
-	in += count;
-	in_len -= count;
+static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
+			       size_t count, loff_t *offp)
+{
+	struct port *port;
+	char *buf;
+	ssize_t ret;
 
-	/* Finished?  Re-register buffer so Host will use it again. */
-	if (in_len == 0)
-		add_inbuf();
+	port = filp->private_data;
 
-	return count;
+	count = min((size_t)(32 * 1024), count);
+
+	buf = kmalloc(count, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = copy_from_user(buf, ubuf, count);
+	if (ret) {
+		ret = -EFAULT;
+		goto free_buf;
+	}
+
+	ret = send_buf(port, buf, count);
+free_buf:
+	kfree(buf);
+	return ret;
 }
-/*:*/
 
-/*D:320 Console drivers are initialized very early so boot messages can go out,
- * so we do things slightly differently from the generic virtio initialization
- * of the net and block drivers.
+static unsigned int port_fops_poll(struct file *filp, poll_table *wait)
+{
+	struct port *port;
+	unsigned int ret;
+
+	port = filp->private_data;
+	poll_wait(filp, &port->waitqueue, wait);
+
+	ret = 0;
+	if (port->inbuf)
+		ret |= POLLIN | POLLRDNORM;
+	if (port->host_connected)
+		ret |= POLLOUT;
+	if (!port->host_connected)
+		ret |= POLLHUP;
+
+	return ret;
+}
+
+static int port_fops_release(struct inode *inode, struct file *filp)
+{
+	struct port *port;
+
+	port = filp->private_data;
+
+	/* Notify host of port being closed */
+	send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0);
+
+	spin_lock_irq(&port->inbuf_lock);
+	port->guest_connected = false;
+
+	discard_port_data(port);
+
+	spin_unlock_irq(&port->inbuf_lock);
+
+	return 0;
+}
+
+static int port_fops_open(struct inode *inode, struct file *filp)
+{
+	struct cdev *cdev = inode->i_cdev;
+	struct port *port;
+
+	port = container_of(cdev, struct port, cdev);
+	filp->private_data = port;
+
+	/*
+	 * Don't allow opening of console port devices -- that's done
+	 * via /dev/hvc
+	 */
+	if (is_console_port(port))
+		return -ENXIO;
+
+	/* Allow only one process to open a particular port at a time */
+	spin_lock_irq(&port->inbuf_lock);
+	if (port->guest_connected) {
+		spin_unlock_irq(&port->inbuf_lock);
+		return -EMFILE;
+	}
+
+	port->guest_connected = true;
+	spin_unlock_irq(&port->inbuf_lock);
+
+	/* Notify host of port being opened */
+	send_control_msg(filp->private_data, VIRTIO_CONSOLE_PORT_OPEN, 1);
+
+	return 0;
+}
+
+/*
+ * The file operations that we support: programs in the guest can open
+ * a console device, read from it, write to it, poll for data and
+ * close it.  The devices are at
+ *   /dev/vport<device number>p<port number>
+ */
+static const struct file_operations port_fops = {
+	.owner = THIS_MODULE,
+	.open  = port_fops_open,
+	.read  = port_fops_read,
+	.write = port_fops_write,
+	.poll  = port_fops_poll,
+	.release = port_fops_release,
+};
+
+/*
+ * The put_chars() callback is pretty straightforward.
  *
- * At this stage, the console is output-only.  It's too early to set up a
- * virtqueue, so we let the drivers do some boutique early-output thing. */
-int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int))
+ * We turn the characters into a scatter-gather list, add it to the
+ * output queue and then kick the Host.  Then we sit here waiting for
+ * it to finish: inefficient in theory, but in practice
+ * implementations will do it immediately (lguest's Launcher does).
+ */
+static int put_chars(u32 vtermno, const char *buf, int count)
 {
-	virtio_cons.put_chars = put_chars;
-	return hvc_instantiate(0, 0, &virtio_cons);
+	struct port *port;
+
+	if (unlikely(early_put_chars))
+		return early_put_chars(vtermno, buf, count);
+
+	port = find_port_by_vtermno(vtermno);
+	if (!port)
+		return 0;
+
+	return send_buf(port, (void *)buf, count);
 }
 
 /*
- * virtio console configuration. This supports:
- * - console resize
+ * get_chars() is the callback from the hvc_console infrastructure
+ * when an interrupt is received.
+ *
+ * We call out to fill_readbuf that gets us the required data from the
+ * buffers that are queued up.
  */
-static void virtcons_apply_config(struct virtio_device *dev)
+static int get_chars(u32 vtermno, char *buf, int count)
 {
+	struct port *port;
+
+	port = find_port_by_vtermno(vtermno);
+	if (!port)
+		return 0;
+
+	/* If we don't have an input queue yet, we can't get input. */
+	BUG_ON(!port->in_vq);
+
+	return fill_readbuf(port, buf, count, false);
+}
+
+static void resize_console(struct port *port)
+{
+	struct virtio_device *vdev;
 	struct winsize ws;
 
-	if (virtio_has_feature(dev, VIRTIO_CONSOLE_F_SIZE)) {
-		dev->config->get(dev,
-				 offsetof(struct virtio_console_config, cols),
-				 &ws.ws_col, sizeof(u16));
-		dev->config->get(dev,
-				 offsetof(struct virtio_console_config, rows),
-				 &ws.ws_row, sizeof(u16));
-		hvc_resize(hvc, ws);
+	/* The port could have been hot-unplugged */
+	if (!port)
+		return;
+
+	vdev = port->portdev->vdev;
+	if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)) {
+		vdev->config->get(vdev,
+				  offsetof(struct virtio_console_config, cols),
+				  &ws.ws_col, sizeof(u16));
+		vdev->config->get(vdev,
+				  offsetof(struct virtio_console_config, rows),
+				  &ws.ws_row, sizeof(u16));
+		hvc_resize(port->cons.hvc, ws);
 	}
 }
 
-/*
- * we support only one console, the hvc struct is a global var
- * We set the configuration at this point, since we now have a tty
- */
+/* We set the configuration at this point, since we now have a tty */
 static int notifier_add_vio(struct hvc_struct *hp, int data)
 {
+	struct port *port;
+
+	port = find_port_by_vtermno(hp->vtermno);
+	if (!port)
+		return -EINVAL;
+
 	hp->irq_requested = 1;
-	virtcons_apply_config(vdev);
+	resize_console(port);
 
 	return 0;
 }
@@ -173,79 +743,812 @@ static void notifier_del_vio(struct hvc_
 	hp->irq_requested = 0;
 }
 
-static void hvc_handle_input(struct virtqueue *vq)
+/* The operations for console ports. */
+static const struct hv_ops hv_ops = {
+	.get_chars = get_chars,
+	.put_chars = put_chars,
+	.notifier_add = notifier_add_vio,
+	.notifier_del = notifier_del_vio,
+	.notifier_hangup = notifier_del_vio,
+};
+
+/*
+ * Console drivers are initialized very early so boot messages can go
+ * out, so we do things slightly differently from the generic virtio
+ * initialization of the net and block drivers.
+ *
+ * At this stage, the console is output-only.  It's too early to set
+ * up a virtqueue, so we let the drivers do some boutique early-output
+ * thing.
+ */
+int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int))
 {
-	if (hvc_poll(hvc))
+	early_put_chars = put_chars;
+	return hvc_instantiate(0, 0, &hv_ops);
+}
+
+int init_port_console(struct port *port)
+{
+	int ret;
+
+	/*
+	 * The Host's telling us this port is a console port.  Hook it
+	 * up with an hvc console.
+	 *
+	 * To set up and manage our virtual console, we call
+	 * hvc_alloc().
+	 *
+	 * The first argument of hvc_alloc() is the virtual console
+	 * number.  The second argument is the parameter for the
+	 * notification mechanism (like irq number).  We currently
+	 * leave this as zero, virtqueues have implicit notifications.
+	 *
+	 * The third argument is a "struct hv_ops" containing the
+	 * put_chars() get_chars(), notifier_add() and notifier_del()
+	 * pointers.  The final argument is the output buffer size: we
+	 * can do any size, so we put PAGE_SIZE here.
+	 */
+	port->cons.vtermno = pdrvdata.next_vtermno;
+
+	port->cons.hvc = hvc_alloc(port->cons.vtermno, 0, &hv_ops, PAGE_SIZE);
+	if (IS_ERR(port->cons.hvc)) {
+		ret = PTR_ERR(port->cons.hvc);
+		dev_err(port->dev,
+			"error %d allocating hvc for port\n", ret);
+		port->cons.hvc = NULL;
+		return ret;
+	}
+	spin_lock_irq(&pdrvdata_lock);
+	pdrvdata.next_vtermno++;
+	list_add_tail(&port->cons.list, &pdrvdata.consoles);
+	spin_unlock_irq(&pdrvdata_lock);
+	port->guest_connected = true;
+
+	/* Notify host of port being opened */
+	send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 1);
+
+	return 0;
+}
+
+static ssize_t show_port_name(struct device *dev,
+			      struct device_attribute *attr, char *buffer)
+{
+	struct port *port;
+
+	port = dev_get_drvdata(dev);
+
+	return sprintf(buffer, "%s\n", port->name);
+}
+
+static DEVICE_ATTR(name, S_IRUGO, show_port_name, NULL);
+
+static struct attribute *port_sysfs_entries[] = {
+	&dev_attr_name.attr,
+	NULL
+};
+
+static struct attribute_group port_attribute_group = {
+	.name = NULL,		/* put in device directory */
+	.attrs = port_sysfs_entries,
+};
+
+static int debugfs_open(struct inode *inode, struct file *filp)
+{
+	filp->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t debugfs_read(struct file *filp, char __user *ubuf,
+			    size_t count, loff_t *offp)
+{
+	struct port *port;
+	char *buf;
+	ssize_t ret, out_offset, out_count;
+
+	out_count = 1024;
+	buf = kmalloc(out_count, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	port = filp->private_data;
+	out_offset = 0;
+	out_offset += snprintf(buf + out_offset, out_count,
+			       "name: %s\n", port->name ? port->name : "");
+	out_offset += snprintf(buf + out_offset, out_count - out_offset,
+			       "guest_connected: %d\n", port->guest_connected);
+	out_offset += snprintf(buf + out_offset, out_count - out_offset,
+			       "host_connected: %d\n", port->host_connected);
+	out_offset += snprintf(buf + out_offset, out_count - out_offset,
+			       "is_console: %s\n",
+			       is_console_port(port) ? "yes" : "no");
+	out_offset += snprintf(buf + out_offset, out_count - out_offset,
+			       "console_vtermno: %u\n", port->cons.vtermno);
+
+	ret = simple_read_from_buffer(ubuf, count, offp, buf, out_offset);
+	kfree(buf);
+	return ret;
+}
+
+static const struct file_operations port_debugfs_ops = {
+	.owner = THIS_MODULE,
+	.open  = debugfs_open,
+	.read  = debugfs_read,
+};
+
+/* Remove all port-specific data. */
+static int remove_port(struct port *port)
+{
+	struct port_buffer *buf;
+
+	spin_lock_irq(&port->portdev->ports_lock);
+	list_del(&port->list);
+	spin_unlock_irq(&port->portdev->ports_lock);
+
+	if (is_console_port(port)) {
+		spin_lock_irq(&pdrvdata_lock);
+		list_del(&port->cons.list);
+		spin_unlock_irq(&pdrvdata_lock);
+		hvc_remove(port->cons.hvc);
+	}
+	if (port->guest_connected)
+		send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0);
+
+	sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
+	device_destroy(pdrvdata.class, port->dev->devt);
+	cdev_del(&port->cdev);
+
+	/* Remove unused data this port might have received. */
+	discard_port_data(port);
+
+	/* Remove buffers we queued up for the Host to send us data in. */
+	while ((buf = port->in_vq->vq_ops->detach_unused_buf(port->in_vq)))
+		free_buf(buf);
+
+	kfree(port->name);
+
+	debugfs_remove(port->debugfs_file);
+
+	kfree(port);
+	return 0;
+}
+
+/* Any private messages that the Host and Guest want to share */
+static void handle_control_message(struct ports_device *portdev,
+				   struct port_buffer *buf)
+{
+	struct virtio_console_control *cpkt;
+	struct port *port;
+	size_t name_size;
+	int err;
+
+	cpkt = (struct virtio_console_control *)(buf->buf + buf->offset);
+
+	port = find_port_by_id(portdev, cpkt->id);
+	if (!port) {
+		/* No valid header at start of buffer.  Drop it. */
+		dev_dbg(&portdev->vdev->dev,
+			"Invalid index %u in control packet\n", cpkt->id);
+		return;
+	}
+
+	switch (cpkt->event) {
+	case VIRTIO_CONSOLE_CONSOLE_PORT:
+		if (!cpkt->value)
+			break;
+		if (is_console_port(port))
+			break;
+
+		init_port_console(port);
+		/*
+		 * Could remove the port here in case init fails - but
+		 * have to notify the host first.
+		 */
+		break;
+	case VIRTIO_CONSOLE_RESIZE:
+		if (!is_console_port(port))
+			break;
+		port->cons.hvc->irq_requested = 1;
+		resize_console(port);
+		break;
+	case VIRTIO_CONSOLE_PORT_OPEN:
+		port->host_connected = cpkt->value;
+		wake_up_interruptible(&port->waitqueue);
+		break;
+	case VIRTIO_CONSOLE_PORT_NAME:
+		/*
+		 * Skip the size of the header and the cpkt to get the size
+		 * of the name that was sent
+		 */
+		name_size = buf->len - buf->offset - sizeof(*cpkt) + 1;
+
+		port->name = kmalloc(name_size, GFP_KERNEL);
+		if (!port->name) {
+			dev_err(port->dev,
+				"Not enough space to store port name\n");
+			break;
+		}
+		strncpy(port->name, buf->buf + buf->offset + sizeof(*cpkt),
+			name_size - 1);
+		port->name[name_size - 1] = 0;
+
+		/*
+		 * Since we only have one sysfs attribute, 'name',
+		 * create it only if we have a name for the port.
+		 */
+		err = sysfs_create_group(&port->dev->kobj,
+					 &port_attribute_group);
+		if (err) {
+			dev_err(port->dev,
+				"Error %d creating sysfs device attributes\n",
+				err);
+		} else {
+			/*
+			 * Generate a udev event so that appropriate
+			 * symlinks can be created based on udev
+			 * rules.
+			 */
+			kobject_uevent(&port->dev->kobj, KOBJ_CHANGE);
+		}
+		break;
+	case VIRTIO_CONSOLE_PORT_REMOVE:
+		/*
+		 * Hot unplug the port.  We don't decrement nr_ports
+		 * since we don't want to deal with extra complexities
+		 * of using the lowest-available port id: We can just
+		 * pick up the nr_ports number as the id and not have
+		 * userspace send it to us.  This helps us in two
+		 * ways:
+		 *
+		 * - We don't need to have a 'port_id' field in the
+		 *   config space when a port is hot-added.  This is a
+		 *   good thing as we might queue up multiple hotplug
+		 *   requests issued in our workqueue.
+		 *
+		 * - Another way to deal with this would have been to
+		 *   use a bitmap of the active ports and select the
+		 *   lowest non-active port from that map.  That
+		 *   bloats the already tight config space and we
+		 *   would end up artificially limiting the
+		 *   max. number of ports to sizeof(bitmap).  Right
+		 *   now we can support 2^32 ports (as the port id is
+		 *   stored in a u32 type).
+		 *
+		 */
+		remove_port(port);
+		break;
+	}
+}
+
+static void control_work_handler(struct work_struct *work)
+{
+	struct ports_device *portdev;
+	struct virtqueue *vq;
+	struct port_buffer *buf;
+	unsigned int len;
+
+	portdev = container_of(work, struct ports_device, control_work);
+	vq = portdev->c_ivq;
+
+	spin_lock(&portdev->cvq_lock);
+	while ((buf = vq->vq_ops->get_buf(vq, &len))) {
+		spin_unlock(&portdev->cvq_lock);
+
+		buf->len = len;
+		buf->offset = 0;
+
+		handle_control_message(portdev, buf);
+
+		spin_lock(&portdev->cvq_lock);
+		if (add_inbuf(portdev->c_ivq, buf) < 0) {
+			dev_warn(&portdev->vdev->dev,
+				 "Error adding buffer to queue\n");
+			free_buf(buf);
+		}
+	}
+	spin_unlock(&portdev->cvq_lock);
+}
+
+static void in_intr(struct virtqueue *vq)
+{
+	struct port *port;
+	unsigned long flags;
+
+	port = find_port_by_vq(vq->vdev->priv, vq);
+	if (!port)
+		return;
+
+	spin_lock_irqsave(&port->inbuf_lock, flags);
+	if (!port->inbuf)
+		port->inbuf = get_inbuf(port);
+
+	/*
+	 * Don't queue up data when port is closed.  This condition
+	 * can be reached when a console port is not yet connected (no
+	 * tty is spawned) and the host sends out data to console
+	 * ports.  For generic serial ports, the host won't
+	 * (shouldn't) send data till the guest is connected.
+	 */
+	if (!port->guest_connected)
+		discard_port_data(port);
+
+	spin_unlock_irqrestore(&port->inbuf_lock, flags);
+
+	wake_up_interruptible(&port->waitqueue);
+
+	if (is_console_port(port) && hvc_poll(port->cons.hvc))
 		hvc_kick();
 }
 
-/*D:370 Once we're further in boot, we get probed like any other virtio device.
- * At this stage we set up the output virtqueue.
- *
- * To set up and manage our virtual console, we call hvc_alloc().  Since we
- * never remove the console device we never need this pointer again.
+static void control_intr(struct virtqueue *vq)
+{
+	struct ports_device *portdev;
+
+	portdev = vq->vdev->priv;
+	schedule_work(&portdev->control_work);
+}
+
+static void config_intr(struct virtio_device *vdev)
+{
+	struct ports_device *portdev;
+
+	portdev = vdev->priv;
+	if (use_multiport(portdev)) {
+		/* Handle port hot-add */
+		schedule_work(&portdev->config_work);
+	}
+	/*
+	 * We'll use this way of resizing only for legacy support.
+	 * For newer userspace (VIRTIO_CONSOLE_F_MULTPORT+), use
+	 * control messages to indicate console size changes so that
+	 * it can be done per-port
+	 */
+	resize_console(find_port_by_id(portdev, 0));
+}
+
+static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
+{
+	struct port_buffer *buf;
+	unsigned int nr_added_bufs;
+	int ret;
+
+	nr_added_bufs = 0;
+	do {
+		buf = alloc_buf(PAGE_SIZE);
+		if (!buf)
+			break;
+
+		spin_lock_irq(lock);
+		ret = add_inbuf(vq, buf);
+		if (ret < 0) {
+			spin_unlock_irq(lock);
+			free_buf(buf);
+			break;
+		}
+		nr_added_bufs++;
+		spin_unlock_irq(lock);
+	} while (ret > 0);
+
+	return nr_added_bufs;
+}
+
+static int add_port(struct ports_device *portdev, u32 id)
+{
+	char debugfs_name[16];
+	struct port *port;
+	struct port_buffer *buf;
+	dev_t devt;
+	unsigned int nr_added_bufs;
+	int err;
+
+	port = kmalloc(sizeof(*port), GFP_KERNEL);
+	if (!port) {
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	port->portdev = portdev;
+	port->id = id;
+
+	port->name = NULL;
+	port->inbuf = NULL;
+	port->cons.hvc = NULL;
+
+	port->host_connected = port->guest_connected = false;
+
+	port->in_vq = portdev->in_vqs[port->id];
+	port->out_vq = portdev->out_vqs[port->id];
+
+	cdev_init(&port->cdev, &port_fops);
+
+	devt = MKDEV(portdev->chr_major, id);
+	err = cdev_add(&port->cdev, devt, 1);
+	if (err < 0) {
+		dev_err(&port->portdev->vdev->dev,
+			"Error %d adding cdev for port %u\n", err, id);
+		goto free_port;
+	}
+	port->dev = device_create(pdrvdata.class, &port->portdev->vdev->dev,
+				  devt, port, "vport%up%u",
+				  port->portdev->drv_index, id);
+	if (IS_ERR(port->dev)) {
+		err = PTR_ERR(port->dev);
+		dev_err(&port->portdev->vdev->dev,
+			"Error %d creating device for port %u\n",
+			err, id);
+		goto free_cdev;
+	}
+
+	spin_lock_init(&port->inbuf_lock);
+	init_waitqueue_head(&port->waitqueue);
+
+	/* Fill the in_vq with buffers so the host can send us data. */
+	nr_added_bufs = fill_queue(port->in_vq, &port->inbuf_lock);
+	if (!nr_added_bufs) {
+		dev_err(port->dev, "Error allocating inbufs\n");
+		err = -ENOMEM;
+		goto free_device;
+	}
+
+	/*
+	 * If we're not using multiport support, this has to be a console port
+	 */
+	if (!use_multiport(port->portdev)) {
+		err = init_port_console(port);
+		if (err)
+			goto free_inbufs;
+	}
+
+	spin_lock_irq(&portdev->ports_lock);
+	list_add_tail(&port->list, &port->portdev->ports);
+	spin_unlock_irq(&portdev->ports_lock);
+
+	/*
+	 * Tell the Host we're set so that it can send us various
+	 * configuration parameters for this port (eg, port name,
+	 * caching, whether this is a console port, etc.)
+	 */
+	send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1);
+
+	if (pdrvdata.debugfs_dir) {
+		/*
+		 * Finally, create the debugfs file that we can use to
+		 * inspect a port's state at any time
+		 */
+		sprintf(debugfs_name, "vport%up%u",
+			port->portdev->drv_index, id);
+		port->debugfs_file = debugfs_create_file(debugfs_name, 0444,
+							 pdrvdata.debugfs_dir,
+							 port,
+							 &port_debugfs_ops);
+	}
+	return 0;
+
+free_inbufs:
+	while ((buf = port->in_vq->vq_ops->detach_unused_buf(port->in_vq)))
+		free_buf(buf);
+free_device:
+	device_destroy(pdrvdata.class, port->dev->devt);
+free_cdev:
+	cdev_del(&port->cdev);
+free_port:
+	kfree(port);
+fail:
+	return err;
+}
+
+/*
+ * The workhandler for config-space updates.
  *
- * Finally we put our input buffer in the input queue, ready to receive. */
-static int __devinit virtcons_probe(struct virtio_device *dev)
+ * This is called when ports are hot-added.
+ */
+static void config_work_handler(struct work_struct *work)
 {
-	vq_callback_t *callbacks[] = { hvc_handle_input, NULL};
-	const char *names[] = { "input", "output" };
-	struct virtqueue *vqs[2];
+	struct virtio_console_multiport_conf virtconconf;
+	struct ports_device *portdev;
+	struct virtio_device *vdev;
 	int err;
 
-	vdev = dev;
+	portdev = container_of(work, struct ports_device, config_work);
 
-	/* This is the scratch page we use to receive console input */
-	inbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!inbuf) {
+	vdev = portdev->vdev;
+	vdev->config->get(vdev,
+			  offsetof(struct virtio_console_multiport_conf,
+				   nr_ports),
+			  &virtconconf.nr_ports,
+			  sizeof(virtconconf.nr_ports));
+
+	if (portdev->config.nr_ports == virtconconf.nr_ports) {
+		/*
+		 * Port 0 got hot-added.  Since we already did all the
+		 * other initialisation for it, just tell the Host
+		 * that the port is ready if we find the port.  In
+		 * case the port was hot-removed earlier, we call
+		 * add_port to add the port.
+		 */
+		struct port *port;
+
+		port = find_port_by_id(portdev, 0);
+		if (!port)
+			add_port(portdev, 0);
+		else
+			send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1);
+		return;
+	}
+	if (virtconconf.nr_ports > portdev->config.max_nr_ports) {
+		dev_warn(&vdev->dev,
+			 "More ports specified (%u) than allowed (%u)",
+			 portdev->config.nr_ports + 1,
+			 portdev->config.max_nr_ports);
+		return;
+	}
+	if (virtconconf.nr_ports < portdev->config.nr_ports)
+		return;
+
+	/* Hot-add ports */
+	while (virtconconf.nr_ports - portdev->config.nr_ports) {
+		err = add_port(portdev, portdev->config.nr_ports);
+		if (err)
+			break;
+		portdev->config.nr_ports++;
+	}
+}
+
+static int init_vqs(struct ports_device *portdev)
+{
+	vq_callback_t **io_callbacks;
+	char **io_names;
+	struct virtqueue **vqs;
+	u32 i, j, nr_ports, nr_queues;
+	int err;
+
+	nr_ports = portdev->config.max_nr_ports;
+	nr_queues = use_multiport(portdev) ? (nr_ports + 1) * 2 : 2;
+
+	vqs = kmalloc(nr_queues * sizeof(struct virtqueue *), GFP_KERNEL);
+	if (!vqs) {
 		err = -ENOMEM;
 		goto fail;
 	}
+	io_callbacks = kmalloc(nr_queues * sizeof(vq_callback_t *), GFP_KERNEL);
+	if (!io_callbacks) {
+		err = -ENOMEM;
+		goto free_vqs;
+	}
+	io_names = kmalloc(nr_queues * sizeof(char *), GFP_KERNEL);
+	if (!io_names) {
+		err = -ENOMEM;
+		goto free_callbacks;
+	}
+	portdev->in_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *),
+				  GFP_KERNEL);
+	if (!portdev->in_vqs) {
+		err = -ENOMEM;
+		goto free_names;
+	}
+	portdev->out_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *),
+				   GFP_KERNEL);
+	if (!portdev->out_vqs) {
+		err = -ENOMEM;
+		goto free_invqs;
+	}
 
+	/*
+	 * For backward compat (newer host but older guest), the host
+	 * spawns a console port first and also inits the vqs for port
+	 * 0 before others.
+	 */
+	j = 0;
+	io_callbacks[j] = in_intr;
+	io_callbacks[j + 1] = NULL;
+	io_names[j] = "input";
+	io_names[j + 1] = "output";
+	j += 2;
+
+	if (use_multiport(portdev)) {
+		io_callbacks[j] = control_intr;
+		io_callbacks[j + 1] = NULL;
+		io_names[j] = "control-i";
+		io_names[j + 1] = "control-o";
+
+		for (i = 1; i < nr_ports; i++) {
+			j += 2;
+			io_callbacks[j] = in_intr;
+			io_callbacks[j + 1] = NULL;
+			io_names[j] = "input";
+			io_names[j + 1] = "output";
+		}
+	}
 	/* Find the queues. */
-	/* FIXME: This is why we want to wean off hvc: we do nothing
-	 * when input comes in. */
-	err = vdev->config->find_vqs(vdev, 2, vqs, callbacks, names);
+	err = portdev->vdev->config->find_vqs(portdev->vdev, nr_queues, vqs,
+					      io_callbacks,
+					      (const char **)io_names);
 	if (err)
+		goto free_outvqs;
+
+	j = 0;
+	portdev->in_vqs[0] = vqs[0];
+	portdev->out_vqs[0] = vqs[1];
+	j += 2;
+	if (use_multiport(portdev)) {
+		portdev->c_ivq = vqs[j];
+		portdev->c_ovq = vqs[j + 1];
+
+		for (i = 1; i < nr_ports; i++) {
+			j += 2;
+			portdev->in_vqs[i] = vqs[j];
+			portdev->out_vqs[i] = vqs[j + 1];
+		}
+	}
+	kfree(io_callbacks);
+	kfree(io_names);
+	kfree(vqs);
+
+	return 0;
+
+free_names:
+	kfree(io_names);
+free_callbacks:
+	kfree(io_callbacks);
+free_outvqs:
+	kfree(portdev->out_vqs);
+free_invqs:
+	kfree(portdev->in_vqs);
+free_vqs:
+	kfree(vqs);
+fail:
+	return err;
+}
+
+static const struct file_operations portdev_fops = {
+	.owner = THIS_MODULE,
+};
+
+/*
+ * Once we're further in boot, we get probed like any other virtio
+ * device.
+ *
+ * If the host also supports multiple console ports, we check the
+ * config space to see how many ports the host has spawned.  We
+ * initialize each port found.
+ */
+static int __devinit virtcons_probe(struct virtio_device *vdev)
+{
+	struct ports_device *portdev;
+	u32 i;
+	int err;
+	bool multiport;
+
+	portdev = kmalloc(sizeof(*portdev), GFP_KERNEL);
+	if (!portdev) {
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	/* Attach this portdev to this virtio_device, and vice-versa. */
+	portdev->vdev = vdev;
+	vdev->priv = portdev;
+
+	spin_lock_irq(&pdrvdata_lock);
+	portdev->drv_index = pdrvdata.index++;
+	spin_unlock_irq(&pdrvdata_lock);
+
+	portdev->chr_major = register_chrdev(0, "virtio-portsdev",
+					     &portdev_fops);
+	if (portdev->chr_major < 0) {
+		dev_err(&vdev->dev,
+			"Error %d registering chrdev for device %u\n",
+			portdev->chr_major, portdev->drv_index);
+		err = portdev->chr_major;
 		goto free;
+	}
 
-	in_vq = vqs[0];
-	out_vq = vqs[1];
+	multiport = false;
+	portdev->config.nr_ports = 1;
+	portdev->config.max_nr_ports = 1;
+#if 0 /* Multiport is not quite ready yet --RR */
+	if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) {
+		multiport = true;
+		vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT;
 
-	/* Start using the new console output. */
-	virtio_cons.get_chars = get_chars;
-	virtio_cons.put_chars = put_chars;
-	virtio_cons.notifier_add = notifier_add_vio;
-	virtio_cons.notifier_del = notifier_del_vio;
-	virtio_cons.notifier_hangup = notifier_del_vio;
+		vdev->config->get(vdev,
+				  offsetof(struct virtio_console_multiport_conf,
+					   nr_ports),
+				  &portdev->config.nr_ports,
+				  sizeof(portdev->config.nr_ports));
+		vdev->config->get(vdev,
+				  offsetof(struct virtio_console_multiport_conf,
+					   max_nr_ports),
+				  &portdev->config.max_nr_ports,
+				  sizeof(portdev->config.max_nr_ports));
+		if (portdev->config.nr_ports > portdev->config.max_nr_ports) {
+			dev_warn(&vdev->dev,
+				 "More ports (%u) specified than allowed (%u). Will init %u ports.",
+				 portdev->config.nr_ports,
+				 portdev->config.max_nr_ports,
+				 portdev->config.max_nr_ports);
 
-	/* The first argument of hvc_alloc() is the virtual console number, so
-	 * we use zero.  The second argument is the parameter for the
-	 * notification mechanism (like irq number). We currently leave this
-	 * as zero, virtqueues have implicit notifications.
-	 *
-	 * The third argument is a "struct hv_ops" containing the put_chars()
-	 * get_chars(), notifier_add() and notifier_del() pointers.
-	 * The final argument is the output buffer size: we can do any size,
-	 * so we put PAGE_SIZE here. */
-	hvc = hvc_alloc(0, 0, &virtio_cons, PAGE_SIZE);
-	if (IS_ERR(hvc)) {
-		err = PTR_ERR(hvc);
-		goto free_vqs;
+			portdev->config.nr_ports = portdev->config.max_nr_ports;
+		}
 	}
 
-	/* Register the input buffer the first time. */
-	add_inbuf();
+	/* Let the Host know we support multiple ports.*/
+	vdev->config->finalize_features(vdev);
+#endif
+
+	err = init_vqs(portdev);
+	if (err < 0) {
+		dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
+		goto free_chrdev;
+	}
+
+	spin_lock_init(&portdev->ports_lock);
+	INIT_LIST_HEAD(&portdev->ports);
+
+	if (multiport) {
+		unsigned int nr_added_bufs;
+
+		spin_lock_init(&portdev->cvq_lock);
+		INIT_WORK(&portdev->control_work, &control_work_handler);
+		INIT_WORK(&portdev->config_work, &config_work_handler);
+
+		nr_added_bufs = fill_queue(portdev->c_ivq, &portdev->cvq_lock);
+		if (!nr_added_bufs) {
+			dev_err(&vdev->dev,
+				"Error allocating buffers for control queue\n");
+			err = -ENOMEM;
+			goto free_vqs;
+		}
+	}
+
+	for (i = 0; i < portdev->config.nr_ports; i++)
+		add_port(portdev, i);
+
+	/* Start using the new console output. */
+	early_put_chars = NULL;
 	return 0;
 
 free_vqs:
 	vdev->config->del_vqs(vdev);
+	kfree(portdev->in_vqs);
+	kfree(portdev->out_vqs);
+free_chrdev:
+	unregister_chrdev(portdev->chr_major, "virtio-portsdev");
 free:
-	kfree(inbuf);
+	kfree(portdev);
 fail:
 	return err;
 }
 
+static void virtcons_remove(struct virtio_device *vdev)
+{
+	struct ports_device *portdev;
+	struct port *port, *port2;
+	struct port_buffer *buf;
+	unsigned int len;
+
+	portdev = vdev->priv;
+
+	cancel_work_sync(&portdev->control_work);
+	cancel_work_sync(&portdev->config_work);
+
+	list_for_each_entry_safe(port, port2, &portdev->ports, list)
+		remove_port(port);
+
+	unregister_chrdev(portdev->chr_major, "virtio-portsdev");
+
+	while ((buf = portdev->c_ivq->vq_ops->get_buf(portdev->c_ivq, &len)))
+		free_buf(buf);
+
+	while ((buf = portdev->c_ivq->vq_ops->detach_unused_buf(portdev->c_ivq)))
+		free_buf(buf);
+
+	vdev->config->del_vqs(vdev);
+	kfree(portdev->in_vqs);
+	kfree(portdev->out_vqs);
+
+	kfree(portdev);
+}
+
 static struct virtio_device_id id_table[] = {
 	{ VIRTIO_ID_CONSOLE, VIRTIO_DEV_ANY_ID },
 	{ 0 },
@@ -262,14 +1565,41 @@ static struct virtio_driver virtio_conso
 	.driver.owner =	THIS_MODULE,
 	.id_table =	id_table,
 	.probe =	virtcons_probe,
-	.config_changed = virtcons_apply_config,
+	.remove =	virtcons_remove,
+	.config_changed = config_intr,
 };
 
 static int __init init(void)
 {
+	int err;
+
+	pdrvdata.class = class_create(THIS_MODULE, "virtio-ports");
+	if (IS_ERR(pdrvdata.class)) {
+		err = PTR_ERR(pdrvdata.class);
+		pr_err("Error %d creating virtio-ports class\n", err);
+		return err;
+	}
+
+	pdrvdata.debugfs_dir = debugfs_create_dir("virtio-ports", NULL);
+	if (!pdrvdata.debugfs_dir) {
+		pr_warning("Error %ld creating debugfs dir for virtio-ports\n",
+			   PTR_ERR(pdrvdata.debugfs_dir));
+	}
+	INIT_LIST_HEAD(&pdrvdata.consoles);
+
 	return register_virtio_driver(&virtio_console);
 }
+
+static void __exit fini(void)
+{
+	unregister_virtio_driver(&virtio_console);
+
+	class_destroy(pdrvdata.class);
+	if (pdrvdata.debugfs_dir)
+		debugfs_remove_recursive(pdrvdata.debugfs_dir);
+}
 module_init(init);
+module_exit(fini);
 
 MODULE_DEVICE_TABLE(virtio, id_table);
 MODULE_DESCRIPTION("Virtio console driver");
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/vme_scc.c linux-libre-2.6.34-gnu1/drivers/char/vme_scc.c
--- linux-libre-2.6.33-gnu1/drivers/char/vme_scc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/vme_scc.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/fcntl.h>
 #include <linux/major.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/miscdevice.h>
 #include <linux/console.h>
 #include <linux/init.h>
@@ -136,7 +135,7 @@ static const struct tty_port_operations
  * vme_scc_init() and support functions
  *---------------------------------------------------------------------------*/
 
-static int scc_init_drivers(void)
+static int __init scc_init_drivers(void)
 {
 	int error;
 
@@ -172,7 +171,7 @@ static int scc_init_drivers(void)
 /* ports[] array is indexed by line no (i.e. [0] for ttyS0, [1] for ttyS1).
  */
 
-static void scc_init_portstructs(void)
+static void __init scc_init_portstructs(void)
 {
 	struct scc_port *port;
 	int i;
@@ -195,7 +194,7 @@ static void scc_init_portstructs(void)
 
 
 #ifdef CONFIG_MVME147_SCC
-static int mvme147_scc_init(void)
+static int __init mvme147_scc_init(void)
 {
 	struct scc_port *port;
 	int error;
@@ -298,7 +297,7 @@ fail:
 
 
 #ifdef CONFIG_MVME162_SCC
-static int mvme162_scc_init(void)
+static int __init mvme162_scc_init(void)
 {
 	struct scc_port *port;
 	int error;
@@ -404,7 +403,7 @@ fail:
 
 
 #ifdef CONFIG_BVME6000_SCC
-static int bvme6000_scc_init(void)
+static int __init bvme6000_scc_init(void)
 {
 	struct scc_port *port;
 	int error;
@@ -503,7 +502,7 @@ fail_free_b_rx:
 #endif
 
 
-static int vme_scc_init(void)
+static int __init vme_scc_init(void)
 {
 	int res = -ENODEV;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/vt.c linux-libre-2.6.34-gnu1/drivers/char/vt.c
--- linux-libre-2.6.33-gnu1/drivers/char/vt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/vt.c	2010-05-16 17:17:36.000000000 -0400
@@ -821,7 +821,7 @@ static inline int resize_screen(struct v
  *
  *	Resize a virtual console, clipping according to the actual constraints.
  *	If the caller passes a tty structure then update the termios winsize
- *	information and perform any neccessary signal handling.
+ *	information and perform any necessary signal handling.
  *
  *	Caller must hold the console semaphore. Takes the termios mutex and
  *	ctrl_lock of the tty IFF a tty is passed.
@@ -2119,8 +2119,6 @@ static int do_con_write(struct tty_struc
 	uint8_t inverse;
 	uint8_t width;
 	u16 himask, charmask;
-	const unsigned char *orig_buf = NULL;
-	int orig_count;
 
 	if (in_interrupt())
 		return count;
@@ -2142,8 +2140,6 @@ static int do_con_write(struct tty_struc
 	    release_console_sem();
 	    return 0;
 	}
-	orig_buf = buf;
-	orig_count = count;
 
 	himask = vc->vc_hi_font_mask;
 	charmask = himask ? 0x1ff : 0xff;
diff -druNp linux-libre-2.6.33-gnu1/drivers/char/xilinx_hwicap/xilinx_hwicap.c linux-libre-2.6.34-gnu1/drivers/char/xilinx_hwicap/xilinx_hwicap.c
--- linux-libre-2.6.33-gnu1/drivers/char/xilinx_hwicap/xilinx_hwicap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/char/xilinx_hwicap/xilinx_hwicap.c	2010-05-16 17:17:36.000000000 -0400
@@ -86,6 +86,7 @@
 #include <linux/fs.h>
 #include <linux/cdev.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/clocksource/Kconfig linux-libre-2.6.34-gnu1/drivers/clocksource/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/clocksource/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/clocksource/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,9 +0,0 @@
-config CS5535_CLOCK_EVENT_SRC
-	tristate "CS5535/CS5536 high-res timer (MFGPT) events"
-	depends on GENERIC_TIME && GENERIC_CLOCKEVENTS && CS5535_MFGPT
-	help
-	  This driver provides a clock event source based on the MFGPT
-	  timer(s) in the CS5535 and CS5536 companion chips.
-	  MFGPTs have a better resolution and max interval than the
-	  generic PIT, and are suitable for use as high-res timers.
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/clocksource/sh_cmt.c linux-libre-2.6.34-gnu1/drivers/clocksource/sh_cmt.c
--- linux-libre-2.6.33-gnu1/drivers/clocksource/sh_cmt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/clocksource/sh_cmt.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/sh_timer.h>
+#include <linux/slab.h>
 
 struct sh_cmt_priv {
 	void __iomem *mapbase;
@@ -40,7 +41,6 @@ struct sh_cmt_priv {
 	struct platform_device *pdev;
 
 	unsigned long flags;
-	unsigned long flags_suspend;
 	unsigned long match_value;
 	unsigned long next_match_value;
 	unsigned long max_match_value;
@@ -432,6 +432,11 @@ static void sh_cmt_clocksource_disable(s
 	sh_cmt_stop(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE);
 }
 
+static void sh_cmt_clocksource_resume(struct clocksource *cs)
+{
+	sh_cmt_start(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE);
+}
+
 static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
 				       char *name, unsigned long rating)
 {
@@ -442,6 +447,8 @@ static int sh_cmt_register_clocksource(s
 	cs->read = sh_cmt_clocksource_read;
 	cs->enable = sh_cmt_clocksource_enable;
 	cs->disable = sh_cmt_clocksource_disable;
+	cs->suspend = sh_cmt_clocksource_disable;
+	cs->resume = sh_cmt_clocksource_resume;
 	cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
 	cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
 	pr_info("sh_cmt: %s used as clock source\n", cs->name);
@@ -603,18 +610,13 @@ static int sh_cmt_setup(struct sh_cmt_pr
 	p->irqaction.handler = sh_cmt_interrupt;
 	p->irqaction.dev_id = p;
 	p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL;
-	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;
+		goto err1;
 	}
 
 	if (resource_size(res) == 6) {
@@ -627,14 +629,25 @@ static int sh_cmt_setup(struct sh_cmt_pr
 		p->clear_bits = ~0xc000;
 	}
 
-	return sh_cmt_register(p, cfg->name,
-			       cfg->clockevent_rating,
-			       cfg->clocksource_rating);
- err2:
-	remove_irq(irq, &p->irqaction);
- err1:
+	ret = sh_cmt_register(p, cfg->name,
+			      cfg->clockevent_rating,
+			      cfg->clocksource_rating);
+	if (ret) {
+		pr_err("sh_cmt: registration failed\n");
+		goto err1;
+	}
+
+	ret = setup_irq(irq, &p->irqaction);
+	if (ret) {
+		pr_err("sh_cmt: failed to request irq %d\n", irq);
+		goto err1;
+	}
+
+	return 0;
+
+err1:
 	iounmap(p->mapbase);
- err0:
+err0:
 	return ret;
 }
 
@@ -668,38 +681,11 @@ static int __devexit sh_cmt_remove(struc
 	return -EBUSY; /* cannot unregister clockevent and clocksource */
 }
 
-static int sh_cmt_suspend(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct sh_cmt_priv *p = platform_get_drvdata(pdev);
-
-	/* save flag state and stop CMT channel */
-	p->flags_suspend = p->flags;
-	sh_cmt_stop(p, p->flags);
-	return 0;
-}
-
-static int sh_cmt_resume(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct sh_cmt_priv *p = platform_get_drvdata(pdev);
-
-	/* start CMT channel from saved state */
-	sh_cmt_start(p, p->flags_suspend);
-	return 0;
-}
-
-static struct dev_pm_ops sh_cmt_dev_pm_ops = {
-	.suspend = sh_cmt_suspend,
-	.resume = sh_cmt_resume,
-};
-
 static struct platform_driver sh_cmt_device_driver = {
 	.probe		= sh_cmt_probe,
 	.remove		= __devexit_p(sh_cmt_remove),
 	.driver		= {
 		.name	= "sh_cmt",
-		.pm	= &sh_cmt_dev_pm_ops,
 	}
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/clocksource/sh_mtu2.c linux-libre-2.6.34-gnu1/drivers/clocksource/sh_mtu2.c
--- linux-libre-2.6.33-gnu1/drivers/clocksource/sh_mtu2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/clocksource/sh_mtu2.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/err.h>
 #include <linux/clockchips.h>
 #include <linux/sh_timer.h>
+#include <linux/slab.h>
 
 struct sh_mtu2_priv {
 	void __iomem *mapbase;
@@ -221,15 +222,15 @@ static void sh_mtu2_register_clockevent(
 	ced->cpumask = cpumask_of(0);
 	ced->set_mode = sh_mtu2_clock_event_mode;
 
+	pr_info("sh_mtu2: %s used for clock events\n", ced->name);
+	clockevents_register_device(ced);
+
 	ret = setup_irq(p->irqaction.irq, &p->irqaction);
 	if (ret) {
 		pr_err("sh_mtu2: failed to request irq %d\n",
 		       p->irqaction.irq);
 		return;
 	}
-
-	pr_info("sh_mtu2: %s used for clock events\n", ced->name);
-	clockevents_register_device(ced);
 }
 
 static int sh_mtu2_register(struct sh_mtu2_priv *p, char *name,
diff -druNp linux-libre-2.6.33-gnu1/drivers/clocksource/sh_tmu.c linux-libre-2.6.34-gnu1/drivers/clocksource/sh_tmu.c
--- linux-libre-2.6.33-gnu1/drivers/clocksource/sh_tmu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/clocksource/sh_tmu.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/sh_timer.h>
+#include <linux/slab.h>
 
 struct sh_tmu_priv {
 	void __iomem *mapbase;
@@ -323,15 +324,15 @@ static void sh_tmu_register_clockevent(s
 	ced->set_next_event = sh_tmu_clock_event_next;
 	ced->set_mode = sh_tmu_clock_event_mode;
 
+	pr_info("sh_tmu: %s used for clock events\n", ced->name);
+	clockevents_register_device(ced);
+
 	ret = setup_irq(p->irqaction.irq, &p->irqaction);
 	if (ret) {
 		pr_err("sh_tmu: failed to request irq %d\n",
 		       p->irqaction.irq);
 		return;
 	}
-
-	pr_info("sh_tmu: %s used for clock events\n", ced->name);
-	clockevents_register_device(ced);
 }
 
 static int sh_tmu_register(struct sh_tmu_priv *p, char *name,
diff -druNp linux-libre-2.6.33-gnu1/drivers/connector/cn_proc.c linux-libre-2.6.34-gnu1/drivers/connector/cn_proc.c
--- linux-libre-2.6.33-gnu1/drivers/connector/cn_proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/connector/cn_proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/ktime.h>
 #include <linux/init.h>
 #include <linux/connector.h>
+#include <linux/gfp.h>
 #include <asm/atomic.h>
 #include <asm/unaligned.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/connector/connector.c linux-libre-2.6.34-gnu1/drivers/connector/connector.c
--- linux-libre-2.6.33-gnu1/drivers/connector/connector.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/connector/connector.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/netlink.h>
 #include <linux/moduleparam.h>
 #include <linux/connector.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/cpufreq/cpufreq.c linux-libre-2.6.34-gnu1/drivers/cpufreq/cpufreq.c
--- linux-libre-2.6.33-gnu1/drivers/cpufreq/cpufreq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/cpufreq/cpufreq.c	2010-05-16 17:17:36.000000000 -0400
@@ -766,7 +766,7 @@ static void cpufreq_sysfs_release(struct
 	complete(&policy->kobj_unregister);
 }
 
-static struct sysfs_ops sysfs_ops = {
+static const struct sysfs_ops sysfs_ops = {
 	.show	= show,
 	.store	= store,
 };
@@ -1113,6 +1113,8 @@ static int __cpufreq_remove_dev(struct s
 	unsigned int cpu = sys_dev->id;
 	unsigned long flags;
 	struct cpufreq_policy *data;
+	struct kobject *kobj;
+	struct completion *cmp;
 #ifdef CONFIG_SMP
 	struct sys_device *cpu_sys_dev;
 	unsigned int j;
@@ -1141,10 +1143,11 @@ static int __cpufreq_remove_dev(struct s
 		dprintk("removing link\n");
 		cpumask_clear_cpu(cpu, data->cpus);
 		spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-		sysfs_remove_link(&sys_dev->kobj, "cpufreq");
+		kobj = &sys_dev->kobj;
 		cpufreq_cpu_put(data);
 		cpufreq_debug_enable_ratelimit();
 		unlock_policy_rwsem_write(cpu);
+		sysfs_remove_link(kobj, "cpufreq");
 		return 0;
 	}
 #endif
@@ -1181,7 +1184,10 @@ static int __cpufreq_remove_dev(struct s
 				data->governor->name, CPUFREQ_NAME_LEN);
 #endif
 			cpu_sys_dev = get_cpu_sysdev(j);
-			sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq");
+			kobj = &cpu_sys_dev->kobj;
+			unlock_policy_rwsem_write(cpu);
+			sysfs_remove_link(kobj, "cpufreq");
+			lock_policy_rwsem_write(cpu);
 			cpufreq_cpu_put(data);
 		}
 	}
@@ -1192,19 +1198,22 @@ static int __cpufreq_remove_dev(struct s
 	if (cpufreq_driver->target)
 		__cpufreq_governor(data, CPUFREQ_GOV_STOP);
 
-	kobject_put(&data->kobj);
+	kobj = &data->kobj;
+	cmp = &data->kobj_unregister;
+	unlock_policy_rwsem_write(cpu);
+	kobject_put(kobj);
 
 	/* we need to make sure that the underlying kobj is actually
 	 * not referenced anymore by anybody before we proceed with
 	 * unloading.
 	 */
 	dprintk("waiting for dropping of refcount\n");
-	wait_for_completion(&data->kobj_unregister);
+	wait_for_completion(cmp);
 	dprintk("wait complete\n");
 
+	lock_policy_rwsem_write(cpu);
 	if (cpufreq_driver->exit)
 		cpufreq_driver->exit(data);
-
 	unlock_policy_rwsem_write(cpu);
 
 	free_cpumask_var(data->related_cpus);
diff -druNp linux-libre-2.6.33-gnu1/drivers/cpufreq/cpufreq_conservative.c linux-libre-2.6.34-gnu1/drivers/cpufreq/cpufreq_conservative.c
--- linux-libre-2.6.33-gnu1/drivers/cpufreq/cpufreq_conservative.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/cpufreq/cpufreq_conservative.c	2010-05-16 17:17:36.000000000 -0400
@@ -444,6 +444,7 @@ static struct attribute_group dbs_attr_g
 static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
 {
 	unsigned int load = 0;
+	unsigned int max_load = 0;
 	unsigned int freq_target;
 
 	struct cpufreq_policy *policy;
@@ -501,6 +502,9 @@ static void dbs_check_cpu(struct cpu_dbs
 			continue;
 
 		load = 100 * (wall_time - idle_time) / wall_time;
+
+		if (load > max_load)
+			max_load = load;
 	}
 
 	/*
@@ -511,7 +515,7 @@ static void dbs_check_cpu(struct cpu_dbs
 		return;
 
 	/* Check for frequency increase */
-	if (load > dbs_tuners_ins.up_threshold) {
+	if (max_load > dbs_tuners_ins.up_threshold) {
 		this_dbs_info->down_skip = 0;
 
 		/* if we are already at full speed then break out early */
@@ -538,7 +542,7 @@ static void dbs_check_cpu(struct cpu_dbs
 	 * 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)) {
+	if (max_load < (dbs_tuners_ins.down_threshold - 10)) {
 		freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100;
 
 		this_dbs_info->requested_freq -= freq_target;
diff -druNp linux-libre-2.6.33-gnu1/drivers/cpufreq/cpufreq_stats.c linux-libre-2.6.34-gnu1/drivers/cpufreq/cpufreq_stats.c
--- linux-libre-2.6.33-gnu1/drivers/cpufreq/cpufreq_stats.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/cpufreq/cpufreq_stats.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/sysdev.h>
 #include <linux/cpu.h>
 #include <linux/sysfs.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/cpuidle/governors/menu.c linux-libre-2.6.34-gnu1/drivers/cpuidle/governors/menu.c
--- linux-libre-2.6.33-gnu1/drivers/cpuidle/governors/menu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/cpuidle/governors/menu.c	2010-05-16 17:17:36.000000000 -0400
@@ -101,7 +101,6 @@ struct menu_device {
 
 	unsigned int	expected_us;
 	u64		predicted_us;
-	unsigned int	measured_us;
 	unsigned int	exit_us;
 	unsigned int	bucket;
 	u64		correction_factor[BUCKETS];
@@ -187,14 +186,14 @@ static int menu_select(struct cpuidle_de
 	int i;
 	int multiplier;
 
-	data->last_state_idx = 0;
-	data->exit_us = 0;
-
 	if (data->needs_update) {
 		menu_update(dev);
 		data->needs_update = 0;
 	}
 
+	data->last_state_idx = 0;
+	data->exit_us = 0;
+
 	/* Special case when user has set very strict latency requirement */
 	if (unlikely(latency_req == 0))
 		return 0;
@@ -294,7 +293,7 @@ static void menu_update(struct cpuidle_d
 	new_factor = data->correction_factor[data->bucket]
 			* (DECAY - 1) / DECAY;
 
-	if (data->expected_us > 0 && data->measured_us < MAX_INTERESTING)
+	if (data->expected_us > 0 && measured_us < MAX_INTERESTING)
 		new_factor += RESOLUTION * measured_us / data->expected_us;
 	else
 		/*
diff -druNp linux-libre-2.6.33-gnu1/drivers/cpuidle/sysfs.c linux-libre-2.6.34-gnu1/drivers/cpuidle/sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/cpuidle/sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/cpuidle/sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/cpuidle.h>
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 #include <linux/cpu.h>
 
 #include "cpuidle.h"
@@ -22,6 +23,7 @@ static int __init cpuidle_sysfs_setup(ch
 __setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup);
 
 static ssize_t show_available_governors(struct sysdev_class *class,
+					struct sysdev_class_attribute *attr,
 					char *buf)
 {
 	ssize_t i = 0;
@@ -41,6 +43,7 @@ out:
 }
 
 static ssize_t show_current_driver(struct sysdev_class *class,
+				   struct sysdev_class_attribute *attr,
 				   char *buf)
 {
 	ssize_t ret;
@@ -56,6 +59,7 @@ static ssize_t show_current_driver(struc
 }
 
 static ssize_t show_current_governor(struct sysdev_class *class,
+				     struct sysdev_class_attribute *attr,
 				     char *buf)
 {
 	ssize_t ret;
@@ -71,6 +75,7 @@ static ssize_t show_current_governor(str
 }
 
 static ssize_t store_current_governor(struct sysdev_class *class,
+				      struct sysdev_class_attribute *attr,
 				      const char *buf, size_t count)
 {
 	char gov_name[CPUIDLE_NAME_LEN];
@@ -191,7 +196,7 @@ static ssize_t cpuidle_store(struct kobj
 	return ret;
 }
 
-static struct sysfs_ops cpuidle_sysfs_ops = {
+static const struct sysfs_ops cpuidle_sysfs_ops = {
 	.show = cpuidle_show,
 	.store = cpuidle_store,
 };
@@ -277,7 +282,7 @@ static ssize_t cpuidle_state_show(struct
 	return ret;
 }
 
-static struct sysfs_ops cpuidle_state_sysfs_ops = {
+static const struct sysfs_ops cpuidle_state_sysfs_ops = {
 	.show = cpuidle_state_show,
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/crypto/amcc/crypto4xx_core.c linux-libre-2.6.34-gnu1/drivers/crypto/amcc/crypto4xx_core.c
--- linux-libre-2.6.33-gnu1/drivers/crypto/amcc/crypto4xx_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/crypto/amcc/crypto4xx_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 #include <asm/dcr.h>
 #include <asm/dcr-regs.h>
 #include <asm/cacheflush.h>
@@ -1274,7 +1275,7 @@ static int __exit crypto4xx_remove(struc
 	return 0;
 }
 
-static struct of_device_id crypto4xx_match[] = {
+static const struct of_device_id crypto4xx_match[] = {
 	{ .compatible      = "amcc,ppc4xx-crypto",},
 	{ },
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/crypto/geode-aes.c linux-libre-2.6.34-gnu1/drivers/crypto/geode-aes.c
--- linux-libre-2.6.33-gnu1/drivers/crypto/geode-aes.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/crypto/geode-aes.c	2010-05-16 17:17:36.000000000 -0400
@@ -135,13 +135,13 @@ static int geode_setkey_cip(struct crypt
 	/*
 	 * The requested key size is not supported by HW, do a fallback
 	 */
-	op->fallback.blk->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
-	op->fallback.blk->base.crt_flags |= (tfm->crt_flags & CRYPTO_TFM_REQ_MASK);
+	op->fallback.cip->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
+	op->fallback.cip->base.crt_flags |= (tfm->crt_flags & CRYPTO_TFM_REQ_MASK);
 
 	ret = crypto_cipher_setkey(op->fallback.cip, key, len);
 	if (ret) {
 		tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
-		tfm->crt_flags |= (op->fallback.blk->base.crt_flags & CRYPTO_TFM_RES_MASK);
+		tfm->crt_flags |= (op->fallback.cip->base.crt_flags & CRYPTO_TFM_RES_MASK);
 	}
 	return ret;
 }
@@ -263,7 +263,7 @@ static int fallback_init_cip(struct cryp
 
 	if (IS_ERR(op->fallback.cip)) {
 		printk(KERN_ERR "Error allocating fallback algo %s\n", name);
-		return PTR_ERR(op->fallback.blk);
+		return PTR_ERR(op->fallback.cip);
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/crypto/hifn_795x.c linux-libre-2.6.34-gnu1/drivers/crypto/hifn_795x.c
--- linux-libre-2.6.33-gnu1/drivers/crypto/hifn_795x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/crypto/hifn_795x.c	2010-05-16 17:17:36.000000000 -0400
@@ -321,7 +321,7 @@ static atomic_t hifn_dev_number;
 #define	HIFN_PUBOPLEN_MOD_M	0x0000007f	/* modulus length mask */
 #define	HIFN_PUBOPLEN_MOD_S	0		/* modulus length shift */
 #define	HIFN_PUBOPLEN_EXP_M	0x0003ff80	/* exponent length mask */
-#define	HIFN_PUBOPLEN_EXP_S	7		/* exponent lenght shift */
+#define	HIFN_PUBOPLEN_EXP_S	7		/* exponent length shift */
 #define	HIFN_PUBOPLEN_RED_M	0x003c0000	/* reducend length mask */
 #define	HIFN_PUBOPLEN_RED_S	18		/* reducend length shift */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/crypto/ixp4xx_crypto.c linux-libre-2.6.34-gnu1/drivers/crypto/ixp4xx_crypto.c
--- linux-libre-2.6.33-gnu1/drivers/crypto/ixp4xx_crypto.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/crypto/ixp4xx_crypto.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
+#include <linux/gfp.h>
 
 #include <crypto/ctr.h>
 #include <crypto/des.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/crypto/mv_cesa.c linux-libre-2.6.34-gnu1/drivers/crypto/mv_cesa.c
--- linux-libre-2.6.33-gnu1/drivers/crypto/mv_cesa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/crypto/mv_cesa.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/kthread.h>
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 #include "mv_cesa.h"
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/crypto/padlock-aes.c linux-libre-2.6.34-gnu1/drivers/crypto/padlock-aes.c
--- linux-libre-2.6.33-gnu1/drivers/crypto/padlock-aes.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/crypto/padlock-aes.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/percpu.h>
 #include <linux/smp.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 #include <asm/processor.h>
 #include <asm/i387.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/crypto/talitos.c linux-libre-2.6.34-gnu1/drivers/crypto/talitos.c
--- linux-libre-2.6.33-gnu1/drivers/crypto/talitos.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/crypto/talitos.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/io.h>
 #include <linux/spinlock.h>
 #include <linux/rtnetlink.h>
+#include <linux/slab.h>
 
 #include <crypto/algapi.h>
 #include <crypto/aes.h>
@@ -1958,7 +1959,7 @@ err_out:
 	return err;
 }
 
-static struct of_device_id talitos_match[] = {
+static const struct of_device_id talitos_match[] = {
 	{
 		.compatible = "fsl,sec2.0",
 	},
diff -druNp linux-libre-2.6.33-gnu1/drivers/dca/dca-core.c linux-libre-2.6.34-gnu1/drivers/dca/dca-core.c
--- linux-libre-2.6.33-gnu1/drivers/dca/dca-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dca/dca-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/notifier.h>
 #include <linux/device.h>
 #include <linux/dca.h>
+#include <linux/slab.h>
 
 #define DCA_VERSION "1.12.1"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/dca/dca-sysfs.c linux-libre-2.6.34-gnu1/drivers/dca/dca-sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/dca/dca-sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dca/dca-sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/kdev_t.h>
 #include <linux/err.h>
 #include <linux/dca.h>
+#include <linux/gfp.h>
 
 static struct class *dca_class;
 static struct idr dca_idr;
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/at_hdmac.c linux-libre-2.6.34-gnu1/drivers/dma/at_hdmac.c
--- linux-libre-2.6.33-gnu1/drivers/dma/at_hdmac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/at_hdmac.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include "at_hdmac_regs.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/coh901318.c linux-libre-2.6.34-gnu1/drivers/dma/coh901318.c
--- linux-libre-2.6.33-gnu1/drivers/dma/coh901318.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/coh901318.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,6 @@ struct coh901318_desc {
 	unsigned int sg_len;
 	struct coh901318_lli *data;
 	enum dma_data_direction dir;
-	int pending_irqs;
 	unsigned long flags;
 };
 
@@ -72,7 +71,6 @@ struct coh901318_chan {
 
 	unsigned long nbr_active_done;
 	unsigned long busy;
-	int pending_irqs;
 
 	struct coh901318_base *base;
 };
@@ -80,18 +78,16 @@ struct coh901318_chan {
 static void coh901318_list_print(struct coh901318_chan *cohc,
 				 struct coh901318_lli *lli)
 {
-	struct coh901318_lli *l;
-	dma_addr_t addr =  virt_to_phys(lli);
+	struct coh901318_lli *l = lli;
 	int i = 0;
 
-	while (addr) {
-		l = phys_to_virt(addr);
+	while (l) {
 		dev_vdbg(COHC_2_DEV(cohc), "i %d, lli %p, ctrl 0x%x, src 0x%x"
-			 ", dst 0x%x, link 0x%x link_virt 0x%p\n",
+			 ", dst 0x%x, link 0x%x virt_link_addr 0x%p\n",
 			 i, l, l->control, l->src_addr, l->dst_addr,
-			 l->link_addr, phys_to_virt(l->link_addr));
+			 l->link_addr, l->virt_link_addr);
 		i++;
-		addr = l->link_addr;
+		l = l->virt_link_addr;
 	}
 }
 
@@ -125,7 +121,7 @@ static int coh901318_debugfs_read(struct
 		goto err_kmalloc;
 	tmp = dev_buf;
 
-	tmp += sprintf(tmp, "DMA -- enable dma channels\n");
+	tmp += sprintf(tmp, "DMA -- enabled dma channels\n");
 
 	for (i = 0; i < debugfs_dma_base->platform->max_channels; i++)
 		if (started_channels & (1 << i))
@@ -337,16 +333,22 @@ coh901318_desc_get(struct coh901318_chan
 		 * TODO: alloc a pile of descs instead of just one,
 		 * avoid many small allocations.
 		 */
-		desc = kmalloc(sizeof(struct coh901318_desc), GFP_NOWAIT);
+		desc = kzalloc(sizeof(struct coh901318_desc), GFP_NOWAIT);
 		if (desc == NULL)
 			goto out;
 		INIT_LIST_HEAD(&desc->node);
+		dma_async_tx_descriptor_init(&desc->desc, &cohc->chan);
 	} else {
 		/* Reuse an old desc. */
 		desc = list_first_entry(&cohc->free,
 					struct coh901318_desc,
 					node);
 		list_del(&desc->node);
+		/* Initialize it a bit so it's not insane */
+		desc->sg = NULL;
+		desc->sg_len = 0;
+		desc->desc.callback = NULL;
+		desc->desc.callback_param = NULL;
 	}
 
  out:
@@ -364,10 +366,6 @@ static void
 coh901318_desc_submit(struct coh901318_chan *cohc, struct coh901318_desc *desc)
 {
 	list_add_tail(&desc->node, &cohc->active);
-
-	BUG_ON(cohc->pending_irqs != 0);
-
-	cohc->pending_irqs = desc->pending_irqs;
 }
 
 static struct coh901318_desc *
@@ -592,6 +590,10 @@ static struct coh901318_desc *coh901318_
 	return cohd_que;
 }
 
+/*
+ * This tasklet is called from the interrupt handler to
+ * handle each descriptor (DMA job) that is sent to a channel.
+ */
 static void dma_tasklet(unsigned long data)
 {
 	struct coh901318_chan *cohc = (struct coh901318_chan *) data;
@@ -600,55 +602,58 @@ static void dma_tasklet(unsigned long da
 	dma_async_tx_callback callback;
 	void *callback_param;
 
+	dev_vdbg(COHC_2_DEV(cohc), "[%s] chan_id %d"
+		 " nbr_active_done %ld\n", __func__,
+		 cohc->id, cohc->nbr_active_done);
+
 	spin_lock_irqsave(&cohc->lock, flags);
 
-	/* get first active entry from list */
+	/* get first active descriptor entry from list */
 	cohd_fin = coh901318_first_active_get(cohc);
 
-	BUG_ON(cohd_fin->pending_irqs == 0);
-
 	if (cohd_fin == NULL)
 		goto err;
 
-	cohd_fin->pending_irqs--;
-	cohc->completed = cohd_fin->desc.cookie;
-
-	if (cohc->nbr_active_done == 0)
-		return;
+	/* locate callback to client */
+	callback = cohd_fin->desc.callback;
+	callback_param = cohd_fin->desc.callback_param;
 
-	if (!cohd_fin->pending_irqs) {
-		/* release the lli allocation*/
-		coh901318_lli_free(&cohc->base->pool, &cohd_fin->data);
-	}
+	/* sign this job as completed on the channel */
+	cohc->completed = cohd_fin->desc.cookie;
 
-	dev_vdbg(COHC_2_DEV(cohc), "[%s] chan_id %d pending_irqs %d"
-		 " nbr_active_done %ld\n", __func__,
-		 cohc->id, cohc->pending_irqs, cohc->nbr_active_done);
+	/* release the lli allocation and remove the descriptor */
+	coh901318_lli_free(&cohc->base->pool, &cohd_fin->data);
 
-	/* callback to client */
-	callback = cohd_fin->desc.callback;
-	callback_param = cohd_fin->desc.callback_param;
+	/* return desc to free-list */
+	coh901318_desc_remove(cohd_fin);
+	coh901318_desc_free(cohc, cohd_fin);
 
-	if (!cohd_fin->pending_irqs) {
-		coh901318_desc_remove(cohd_fin);
+	spin_unlock_irqrestore(&cohc->lock, flags);
 
-		/* return desc to free-list */
-		coh901318_desc_free(cohc, cohd_fin);
-	}
+	/* Call the callback when we're done */
+	if (callback)
+		callback(callback_param);
 
-	if (cohc->nbr_active_done)
-		cohc->nbr_active_done--;
+	spin_lock_irqsave(&cohc->lock, flags);
 
+	/*
+	 * If another interrupt fired while the tasklet was scheduling,
+	 * we don't get called twice, so we have this number of active
+	 * counter that keep track of the number of IRQs expected to
+	 * be handled for this channel. If there happen to be more than
+	 * one IRQ to be ack:ed, we simply schedule this tasklet again.
+	 */
+	cohc->nbr_active_done--;
 	if (cohc->nbr_active_done) {
+		dev_dbg(COHC_2_DEV(cohc), "scheduling tasklet again, new IRQs "
+			"came in while we were scheduling this tasklet\n");
 		if (cohc_chan_conf(cohc)->priority_high)
 			tasklet_hi_schedule(&cohc->tasklet);
 		else
 			tasklet_schedule(&cohc->tasklet);
 	}
-	spin_unlock_irqrestore(&cohc->lock, flags);
 
-	if (callback)
-		callback(callback_param);
+	spin_unlock_irqrestore(&cohc->lock, flags);
 
 	return;
 
@@ -667,16 +672,17 @@ static void dma_tc_handle(struct coh9013
 	if (!cohc->allocated)
 		return;
 
-	BUG_ON(cohc->pending_irqs == 0);
+	spin_lock(&cohc->lock);
 
-	cohc->pending_irqs--;
 	cohc->nbr_active_done++;
 
-	if (cohc->pending_irqs == 0 && coh901318_queue_start(cohc) == NULL)
+	if (coh901318_queue_start(cohc) == NULL)
 		cohc->busy = 0;
 
 	BUG_ON(list_empty(&cohc->active));
 
+	spin_unlock(&cohc->lock);
+
 	if (cohc_chan_conf(cohc)->priority_high)
 		tasklet_hi_schedule(&cohc->tasklet);
 	else
@@ -870,6 +876,7 @@ coh901318_prep_memcpy(struct dma_chan *c
 	struct coh901318_chan *cohc = to_coh901318_chan(chan);
 	int lli_len;
 	u32 ctrl_last = cohc_chan_param(cohc)->ctrl_lli_last;
+	int ret;
 
 	spin_lock_irqsave(&cohc->lock, flg);
 
@@ -890,22 +897,19 @@ coh901318_prep_memcpy(struct dma_chan *c
 	if (data == NULL)
 		goto err;
 
-	cohd = coh901318_desc_get(cohc);
-	cohd->sg = NULL;
-	cohd->sg_len = 0;
-	cohd->data = data;
-
-	cohd->pending_irqs =
-		coh901318_lli_fill_memcpy(
-				&cohc->base->pool, data, src, size, dest,
-				cohc_chan_param(cohc)->ctrl_lli_chained,
-				ctrl_last);
-	cohd->flags = flags;
+	ret = coh901318_lli_fill_memcpy(
+		&cohc->base->pool, data, src, size, dest,
+		cohc_chan_param(cohc)->ctrl_lli_chained,
+		ctrl_last);
+	if (ret)
+		goto err;
 
 	COH_DBG(coh901318_list_print(cohc, data));
 
-	dma_async_tx_descriptor_init(&cohd->desc, chan);
-
+	/* Pick a descriptor to handle this transfer */
+	cohd = coh901318_desc_get(cohc);
+	cohd->data = data;
+	cohd->flags = flags;
 	cohd->desc.tx_submit = coh901318_tx_submit;
 
 	spin_unlock_irqrestore(&cohc->lock, flg);
@@ -924,6 +928,7 @@ coh901318_prep_slave_sg(struct dma_chan
 	struct coh901318_chan *cohc = to_coh901318_chan(chan);
 	struct coh901318_lli *data;
 	struct coh901318_desc *cohd;
+	const struct coh901318_params *params;
 	struct scatterlist *sg;
 	int len = 0;
 	int size;
@@ -931,7 +936,9 @@ coh901318_prep_slave_sg(struct dma_chan
 	u32 ctrl_chained = cohc_chan_param(cohc)->ctrl_lli_chained;
 	u32 ctrl = cohc_chan_param(cohc)->ctrl_lli;
 	u32 ctrl_last = cohc_chan_param(cohc)->ctrl_lli_last;
+	u32 config;
 	unsigned long flg;
+	int ret;
 
 	if (!sgl)
 		goto out;
@@ -947,15 +954,14 @@ coh901318_prep_slave_sg(struct dma_chan
 		/* Trigger interrupt after last lli */
 		ctrl_last |= COH901318_CX_CTRL_TC_IRQ_ENABLE;
 
-	cohd = coh901318_desc_get(cohc);
-	cohd->sg = NULL;
-	cohd->sg_len = 0;
-	cohd->dir = direction;
+	params = cohc_chan_param(cohc);
+	config = params->config;
 
 	if (direction == DMA_TO_DEVICE) {
 		u32 tx_flags = COH901318_CX_CTRL_PRDD_SOURCE |
 			COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE;
 
+		config |= COH901318_CX_CFG_RM_MEMORY_TO_PRIMARY;
 		ctrl_chained |= tx_flags;
 		ctrl_last |= tx_flags;
 		ctrl |= tx_flags;
@@ -963,16 +969,14 @@ coh901318_prep_slave_sg(struct dma_chan
 		u32 rx_flags = COH901318_CX_CTRL_PRDD_DEST |
 			COH901318_CX_CTRL_DST_ADDR_INC_ENABLE;
 
+		config |= COH901318_CX_CFG_RM_PRIMARY_TO_MEMORY;
 		ctrl_chained |= rx_flags;
 		ctrl_last |= rx_flags;
 		ctrl |= rx_flags;
 	} else
 		goto err_direction;
 
-	dma_async_tx_descriptor_init(&cohd->desc, chan);
-
-	cohd->desc.tx_submit = coh901318_tx_submit;
-
+	coh901318_set_conf(cohc, config);
 
 	/* The dma only supports transmitting packages up to
 	 * MAX_DMA_PACKET_SIZE. Calculate to total number of
@@ -994,32 +998,37 @@ coh901318_prep_slave_sg(struct dma_chan
 		len += factor;
 	}
 
+	pr_debug("Allocate %d lli:s for this transfer\n", len);
 	data = coh901318_lli_alloc(&cohc->base->pool, len);
 
 	if (data == NULL)
 		goto err_dma_alloc;
 
 	/* initiate allocated data list */
-	cohd->pending_irqs =
-		coh901318_lli_fill_sg(&cohc->base->pool, data, sgl, sg_len,
-				      cohc_dev_addr(cohc),
-				      ctrl_chained,
-				      ctrl,
-				      ctrl_last,
-				      direction, COH901318_CX_CTRL_TC_IRQ_ENABLE);
-	cohd->data = data;
-
-	cohd->flags = flags;
+	ret = coh901318_lli_fill_sg(&cohc->base->pool, data, sgl, sg_len,
+				    cohc_dev_addr(cohc),
+				    ctrl_chained,
+				    ctrl,
+				    ctrl_last,
+				    direction, COH901318_CX_CTRL_TC_IRQ_ENABLE);
+	if (ret)
+		goto err_lli_fill;
 
 	COH_DBG(coh901318_list_print(cohc, data));
 
+	/* Pick a descriptor to handle this transfer */
+	cohd = coh901318_desc_get(cohc);
+	cohd->dir = direction;
+	cohd->flags = flags;
+	cohd->desc.tx_submit = coh901318_tx_submit;
+	cohd->data = data;
+
 	spin_unlock_irqrestore(&cohc->lock, flg);
 
 	return &cohd->desc;
+ err_lli_fill:
  err_dma_alloc:
  err_direction:
-	coh901318_desc_remove(cohd);
-	coh901318_desc_free(cohc, cohd);
 	spin_unlock_irqrestore(&cohc->lock, flg);
  out:
 	return NULL;
@@ -1092,9 +1101,8 @@ coh901318_terminate_all(struct dma_chan
 		/* release the lli allocation*/
 		coh901318_lli_free(&cohc->base->pool, &cohd->data);
 
-		coh901318_desc_remove(cohd);
-
 		/* return desc to free-list */
+		coh901318_desc_remove(cohd);
 		coh901318_desc_free(cohc, cohd);
 	}
 
@@ -1102,16 +1110,14 @@ coh901318_terminate_all(struct dma_chan
 		/* release the lli allocation*/
 		coh901318_lli_free(&cohc->base->pool, &cohd->data);
 
-		coh901318_desc_remove(cohd);
-
 		/* return desc to free-list */
+		coh901318_desc_remove(cohd);
 		coh901318_desc_free(cohc, cohd);
 	}
 
 
 	cohc->nbr_active_done = 0;
 	cohc->busy = 0;
-	cohc->pending_irqs = 0;
 
 	spin_unlock_irqrestore(&cohc->lock, flags);
 }
@@ -1138,7 +1144,6 @@ void coh901318_base_init(struct dma_devi
 
 			spin_lock_init(&cohc->lock);
 
-			cohc->pending_irqs = 0;
 			cohc->nbr_active_done = 0;
 			cohc->busy = 0;
 			INIT_LIST_HEAD(&cohc->free);
@@ -1254,12 +1259,17 @@ static int __init coh901318_probe(struct
 	base->dma_memcpy.device_issue_pending = coh901318_issue_pending;
 	base->dma_memcpy.device_terminate_all = coh901318_terminate_all;
 	base->dma_memcpy.dev = &pdev->dev;
+	/*
+	 * This controller can only access address at even 32bit boundaries,
+	 * i.e. 2^2
+	 */
+	base->dma_memcpy.copy_align = 2;
 	err = dma_async_device_register(&base->dma_memcpy);
 
 	if (err)
 		goto err_register_memcpy;
 
-	dev_dbg(&pdev->dev, "Initialized COH901318 DMA on virtual base 0x%08x\n",
+	dev_info(&pdev->dev, "Initialized COH901318 DMA on virtual base 0x%08x\n",
 		(u32) base->virtbase);
 
 	return err;
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/coh901318_lli.c linux-libre-2.6.34-gnu1/drivers/dma/coh901318_lli.c
--- linux-libre-2.6.33-gnu1/drivers/dma/coh901318_lli.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/coh901318_lli.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/spinlock.h>
 #include <linux/dmapool.h>
 #include <linux/memory.h>
+#include <linux/gfp.h>
 #include <mach/coh901318.h>
 
 #include "coh901318_lli.h"
@@ -74,6 +75,8 @@ coh901318_lli_alloc(struct coh901318_poo
 
 	lli = head;
 	lli->phy_this = phy;
+	lli->link_addr = 0x00000000;
+	lli->virt_link_addr = 0x00000000U;
 
 	for (i = 1; i < len; i++) {
 		lli_prev = lli;
@@ -85,13 +88,13 @@ coh901318_lli_alloc(struct coh901318_poo
 
 		DEBUGFS_POOL_COUNTER_ADD(pool, 1);
 		lli->phy_this = phy;
+		lli->link_addr = 0x00000000;
+		lli->virt_link_addr = 0x00000000U;
 
 		lli_prev->link_addr = phy;
 		lli_prev->virt_link_addr = lli;
 	}
 
-	lli->link_addr = 0x00000000U;
-
 	spin_unlock(&pool->lock);
 
 	return head;
@@ -166,8 +169,7 @@ coh901318_lli_fill_memcpy(struct coh9013
 	lli->src_addr = src;
 	lli->dst_addr = dst;
 
-	/* One irq per single transfer */
-	return 1;
+	return 0;
 }
 
 int
@@ -223,8 +225,7 @@ coh901318_lli_fill_single(struct coh9013
 	lli->src_addr = src;
 	lli->dst_addr = dst;
 
-	/* One irq per single transfer */
-	return 1;
+	return 0;
 }
 
 int
@@ -240,7 +241,6 @@ coh901318_lli_fill_sg(struct coh901318_p
 	u32 ctrl_sg;
 	dma_addr_t src = 0;
 	dma_addr_t dst = 0;
-	int nbr_of_irq = 0;
 	u32 bytes_to_transfer;
 	u32 elem_size;
 
@@ -269,15 +269,12 @@ coh901318_lli_fill_sg(struct coh901318_p
 			ctrl_sg = ctrl ? ctrl : ctrl_last;
 
 
-		if ((ctrl_sg & ctrl_irq_mask))
-			nbr_of_irq++;
-
 		if (dir == DMA_TO_DEVICE)
 			/* increment source address */
-			src = sg_dma_address(sg);
+			src = sg_phys(sg);
 		else
 			/* increment destination address */
-			dst =  sg_dma_address(sg);
+			dst =  sg_phys(sg);
 
 		bytes_to_transfer = sg_dma_len(sg);
 
@@ -310,8 +307,7 @@ coh901318_lli_fill_sg(struct coh901318_p
 	}
 	spin_unlock(&pool->lock);
 
-	/* There can be many IRQs per sg transfer */
-	return nbr_of_irq;
+	return 0;
  err:
 	spin_unlock(&pool->lock);
 	return -EINVAL;
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/coh901318_lli.h linux-libre-2.6.34-gnu1/drivers/dma/coh901318_lli.h
--- linux-libre-2.6.33-gnu1/drivers/dma/coh901318_lli.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/coh901318_lli.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,7 @@ struct device;
  * @pool: pool handle
  * @dev: dma device
  * @lli_nbr: number of lli:s in the pool
- * @algin: adress alignemtn of lli:s
+ * @algin: address alignemtn of lli:s
  * returns 0 on success otherwise none zero
  */
 int coh901318_pool_create(struct coh901318_pool *pool,
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/dmaengine.c linux-libre-2.6.34-gnu1/drivers/dma/dmaengine.c
--- linux-libre-2.6.33-gnu1/drivers/dma/dmaengine.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/dmaengine.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,6 +58,7 @@
 #include <linux/jiffies.h>
 #include <linux/rculist.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 
 static DEFINE_MUTEX(dma_list_mutex);
 static LIST_HEAD(dma_device_list);
@@ -284,7 +285,7 @@ struct dma_chan_tbl_ent {
 /**
  * channel_table - percpu lookup table for memory-to-memory offload providers
  */
-static struct dma_chan_tbl_ent *channel_table[DMA_TX_TYPE_END];
+static struct dma_chan_tbl_ent __percpu *channel_table[DMA_TX_TYPE_END];
 
 static int __init dma_channel_table_init(void)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/dmatest.c linux-libre-2.6.34-gnu1/drivers/dma/dmatest.c
--- linux-libre-2.6.33-gnu1/drivers/dma/dmatest.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/dmatest.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <linux/wait.h>
 
 static unsigned int test_buf_size = 16384;
@@ -237,7 +238,7 @@ static int dmatest_func(void *data)
 	dma_cookie_t		cookie;
 	enum dma_status		status;
 	enum dma_ctrl_flags 	flags;
-	u8			pq_coefs[pq_sources];
+	u8			pq_coefs[pq_sources + 1];
 	int			ret;
 	int			src_cnt;
 	int			dst_cnt;
@@ -257,7 +258,7 @@ static int dmatest_func(void *data)
 	} else if (thread->type == DMA_PQ) {
 		src_cnt = pq_sources | 1; /* force odd to ensure dst = src */
 		dst_cnt = 2;
-		for (i = 0; i < pq_sources; i++)
+		for (i = 0; i < src_cnt; i++)
 			pq_coefs[i] = 1;
 	} else
 		goto err_srcs;
@@ -347,7 +348,7 @@ static int dmatest_func(void *data)
 		else if (thread->type == DMA_XOR)
 			tx = dev->device_prep_dma_xor(chan,
 						      dma_dsts[0] + dst_off,
-						      dma_srcs, xor_sources,
+						      dma_srcs, src_cnt,
 						      len, flags);
 		else if (thread->type == DMA_PQ) {
 			dma_addr_t dma_pq[dst_cnt];
@@ -355,7 +356,7 @@ static int dmatest_func(void *data)
 			for (i = 0; i < dst_cnt; i++)
 				dma_pq[i] = dma_dsts[i] + dst_off;
 			tx = dev->device_prep_dma_pq(chan, dma_pq, dma_srcs,
-						     pq_sources, pq_coefs,
+						     src_cnt, pq_coefs,
 						     len, flags);
 		}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/fsldma.c linux-libre-2.6.34-gnu1/drivers/dma/fsldma.c
--- linux-libre-2.6.33-gnu1/drivers/dma/fsldma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/fsldma.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/dmaengine.h>
 #include <linux/delay.h>
@@ -37,19 +38,19 @@
 #include <asm/fsldma.h>
 #include "fsldma.h"
 
-static void dma_init(struct fsl_dma_chan *fsl_chan)
+static void dma_init(struct fsldma_chan *chan)
 {
 	/* Reset the channel */
-	DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, 0, 32);
+	DMA_OUT(chan, &chan->regs->mr, 0, 32);
 
-	switch (fsl_chan->feature & FSL_DMA_IP_MASK) {
+	switch (chan->feature & FSL_DMA_IP_MASK) {
 	case FSL_DMA_IP_85XX:
 		/* Set the channel to below modes:
 		 * EIE - Error interrupt enable
 		 * EOSIE - End of segments interrupt enable (basic mode)
 		 * EOLNIE - End of links interrupt enable
 		 */
-		DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, FSL_DMA_MR_EIE
+		DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_EIE
 				| FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32);
 		break;
 	case FSL_DMA_IP_83XX:
@@ -57,170 +58,146 @@ static void dma_init(struct fsl_dma_chan
 		 * EOTIE - End-of-transfer interrupt enable
 		 * PRC_RM - PCI read multiple
 		 */
-		DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, FSL_DMA_MR_EOTIE
+		DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_EOTIE
 				| FSL_DMA_MR_PRC_RM, 32);
 		break;
 	}
-
 }
 
-static void set_sr(struct fsl_dma_chan *fsl_chan, u32 val)
+static void set_sr(struct fsldma_chan *chan, u32 val)
 {
-	DMA_OUT(fsl_chan, &fsl_chan->reg_base->sr, val, 32);
+	DMA_OUT(chan, &chan->regs->sr, val, 32);
 }
 
-static u32 get_sr(struct fsl_dma_chan *fsl_chan)
+static u32 get_sr(struct fsldma_chan *chan)
 {
-	return DMA_IN(fsl_chan, &fsl_chan->reg_base->sr, 32);
+	return DMA_IN(chan, &chan->regs->sr, 32);
 }
 
-static void set_desc_cnt(struct fsl_dma_chan *fsl_chan,
+static void set_desc_cnt(struct fsldma_chan *chan,
 				struct fsl_dma_ld_hw *hw, u32 count)
 {
-	hw->count = CPU_TO_DMA(fsl_chan, count, 32);
+	hw->count = CPU_TO_DMA(chan, count, 32);
 }
 
-static void set_desc_src(struct fsl_dma_chan *fsl_chan,
+static void set_desc_src(struct fsldma_chan *chan,
 				struct fsl_dma_ld_hw *hw, dma_addr_t src)
 {
 	u64 snoop_bits;
 
-	snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX)
+	snoop_bits = ((chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX)
 		? ((u64)FSL_DMA_SATR_SREADTYPE_SNOOP_READ << 32) : 0;
-	hw->src_addr = CPU_TO_DMA(fsl_chan, snoop_bits | src, 64);
+	hw->src_addr = CPU_TO_DMA(chan, snoop_bits | src, 64);
 }
 
-static void set_desc_dest(struct fsl_dma_chan *fsl_chan,
-				struct fsl_dma_ld_hw *hw, dma_addr_t dest)
+static void set_desc_dst(struct fsldma_chan *chan,
+				struct fsl_dma_ld_hw *hw, dma_addr_t dst)
 {
 	u64 snoop_bits;
 
-	snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX)
+	snoop_bits = ((chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX)
 		? ((u64)FSL_DMA_DATR_DWRITETYPE_SNOOP_WRITE << 32) : 0;
-	hw->dst_addr = CPU_TO_DMA(fsl_chan, snoop_bits | dest, 64);
+	hw->dst_addr = CPU_TO_DMA(chan, snoop_bits | dst, 64);
 }
 
-static void set_desc_next(struct fsl_dma_chan *fsl_chan,
+static void set_desc_next(struct fsldma_chan *chan,
 				struct fsl_dma_ld_hw *hw, dma_addr_t next)
 {
 	u64 snoop_bits;
 
-	snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_83XX)
+	snoop_bits = ((chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_83XX)
 		? FSL_DMA_SNEN : 0;
-	hw->next_ln_addr = CPU_TO_DMA(fsl_chan, snoop_bits | next, 64);
-}
-
-static void set_cdar(struct fsl_dma_chan *fsl_chan, dma_addr_t addr)
-{
-	DMA_OUT(fsl_chan, &fsl_chan->reg_base->cdar, addr | FSL_DMA_SNEN, 64);
+	hw->next_ln_addr = CPU_TO_DMA(chan, snoop_bits | next, 64);
 }
 
-static dma_addr_t get_cdar(struct fsl_dma_chan *fsl_chan)
+static void set_cdar(struct fsldma_chan *chan, dma_addr_t addr)
 {
-	return DMA_IN(fsl_chan, &fsl_chan->reg_base->cdar, 64) & ~FSL_DMA_SNEN;
+	DMA_OUT(chan, &chan->regs->cdar, addr | FSL_DMA_SNEN, 64);
 }
 
-static void set_ndar(struct fsl_dma_chan *fsl_chan, dma_addr_t addr)
+static dma_addr_t get_cdar(struct fsldma_chan *chan)
 {
-	DMA_OUT(fsl_chan, &fsl_chan->reg_base->ndar, addr, 64);
+	return DMA_IN(chan, &chan->regs->cdar, 64) & ~FSL_DMA_SNEN;
 }
 
-static dma_addr_t get_ndar(struct fsl_dma_chan *fsl_chan)
+static dma_addr_t get_ndar(struct fsldma_chan *chan)
 {
-	return DMA_IN(fsl_chan, &fsl_chan->reg_base->ndar, 64);
+	return DMA_IN(chan, &chan->regs->ndar, 64);
 }
 
-static u32 get_bcr(struct fsl_dma_chan *fsl_chan)
+static u32 get_bcr(struct fsldma_chan *chan)
 {
-	return DMA_IN(fsl_chan, &fsl_chan->reg_base->bcr, 32);
+	return DMA_IN(chan, &chan->regs->bcr, 32);
 }
 
-static int dma_is_idle(struct fsl_dma_chan *fsl_chan)
+static int dma_is_idle(struct fsldma_chan *chan)
 {
-	u32 sr = get_sr(fsl_chan);
+	u32 sr = get_sr(chan);
 	return (!(sr & FSL_DMA_SR_CB)) || (sr & FSL_DMA_SR_CH);
 }
 
-static void dma_start(struct fsl_dma_chan *fsl_chan)
+static void dma_start(struct fsldma_chan *chan)
 {
-	u32 mr_set = 0;
+	u32 mode;
 
-	if (fsl_chan->feature & FSL_DMA_CHAN_PAUSE_EXT) {
-		DMA_OUT(fsl_chan, &fsl_chan->reg_base->bcr, 0, 32);
-		mr_set |= FSL_DMA_MR_EMP_EN;
-	} else if ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX) {
-		DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
-			DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32)
-				& ~FSL_DMA_MR_EMP_EN, 32);
+	mode = DMA_IN(chan, &chan->regs->mr, 32);
+
+	if ((chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX) {
+		if (chan->feature & FSL_DMA_CHAN_PAUSE_EXT) {
+			DMA_OUT(chan, &chan->regs->bcr, 0, 32);
+			mode |= FSL_DMA_MR_EMP_EN;
+		} else {
+			mode &= ~FSL_DMA_MR_EMP_EN;
+		}
 	}
 
-	if (fsl_chan->feature & FSL_DMA_CHAN_START_EXT)
-		mr_set |= FSL_DMA_MR_EMS_EN;
+	if (chan->feature & FSL_DMA_CHAN_START_EXT)
+		mode |= FSL_DMA_MR_EMS_EN;
 	else
-		mr_set |= FSL_DMA_MR_CS;
+		mode |= FSL_DMA_MR_CS;
 
-	DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
-			DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32)
-			| mr_set, 32);
+	DMA_OUT(chan, &chan->regs->mr, mode, 32);
 }
 
-static void dma_halt(struct fsl_dma_chan *fsl_chan)
+static void dma_halt(struct fsldma_chan *chan)
 {
+	u32 mode;
 	int i;
 
-	DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
-		DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) | FSL_DMA_MR_CA,
-		32);
-	DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
-		DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) & ~(FSL_DMA_MR_CS
-		| FSL_DMA_MR_EMS_EN | FSL_DMA_MR_CA), 32);
+	mode = DMA_IN(chan, &chan->regs->mr, 32);
+	mode |= FSL_DMA_MR_CA;
+	DMA_OUT(chan, &chan->regs->mr, mode, 32);
+
+	mode &= ~(FSL_DMA_MR_CS | FSL_DMA_MR_EMS_EN | FSL_DMA_MR_CA);
+	DMA_OUT(chan, &chan->regs->mr, mode, 32);
 
 	for (i = 0; i < 100; i++) {
-		if (dma_is_idle(fsl_chan))
-			break;
+		if (dma_is_idle(chan))
+			return;
+
 		udelay(10);
 	}
-	if (i >= 100 && !dma_is_idle(fsl_chan))
-		dev_err(fsl_chan->dev, "DMA halt timeout!\n");
+
+	if (!dma_is_idle(chan))
+		dev_err(chan->dev, "DMA halt timeout!\n");
 }
 
-static void set_ld_eol(struct fsl_dma_chan *fsl_chan,
+static void set_ld_eol(struct fsldma_chan *chan,
 			struct fsl_desc_sw *desc)
 {
 	u64 snoop_bits;
 
-	snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_83XX)
+	snoop_bits = ((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
+	desc->hw.next_ln_addr = CPU_TO_DMA(chan,
+		DMA_TO_CPU(chan, desc->hw.next_ln_addr, 64) | FSL_DMA_EOL
 			| snoop_bits, 64);
 }
 
-static void append_ld_queue(struct fsl_dma_chan *fsl_chan,
-		struct fsl_desc_sw *new_desc)
-{
-	struct fsl_desc_sw *queue_tail = to_fsl_desc(fsl_chan->ld_queue.prev);
-
-	if (list_empty(&fsl_chan->ld_queue))
-		return;
-
-	/* Link to the new descriptor physical address and
-	 * Enable End-of-segment interrupt for
-	 * the last link descriptor.
-	 * (the previous node's next link descriptor)
-	 *
-	 * For FSL_DMA_IP_83xx, the snoop enable bit need be set.
-	 */
-	queue_tail->hw.next_ln_addr = CPU_TO_DMA(fsl_chan,
-			new_desc->async_tx.phys | FSL_DMA_EOSIE |
-			(((fsl_chan->feature & FSL_DMA_IP_MASK)
-				== FSL_DMA_IP_83XX) ? FSL_DMA_SNEN : 0), 64);
-}
-
 /**
  * fsl_chan_set_src_loop_size - Set source address hold transfer size
- * @fsl_chan : Freescale DMA channel
+ * @chan : Freescale DMA channel
  * @size     : Address loop size, 0 for disable loop
  *
  * The set source address hold transfer size. The source
@@ -229,29 +206,30 @@ static void append_ld_queue(struct fsl_d
  * read data from SA, SA + 1, SA + 2, SA + 3, then loop back to SA,
  * SA + 1 ... and so on.
  */
-static void fsl_chan_set_src_loop_size(struct fsl_dma_chan *fsl_chan, int size)
+static void fsl_chan_set_src_loop_size(struct fsldma_chan *chan, int size)
 {
+	u32 mode;
+
+	mode = DMA_IN(chan, &chan->regs->mr, 32);
+
 	switch (size) {
 	case 0:
-		DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
-			DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) &
-			(~FSL_DMA_MR_SAHE), 32);
+		mode &= ~FSL_DMA_MR_SAHE;
 		break;
 	case 1:
 	case 2:
 	case 4:
 	case 8:
-		DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
-			DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) |
-			FSL_DMA_MR_SAHE | (__ilog2(size) << 14),
-			32);
+		mode |= FSL_DMA_MR_SAHE | (__ilog2(size) << 14);
 		break;
 	}
+
+	DMA_OUT(chan, &chan->regs->mr, mode, 32);
 }
 
 /**
- * fsl_chan_set_dest_loop_size - Set destination address hold transfer size
- * @fsl_chan : Freescale DMA channel
+ * fsl_chan_set_dst_loop_size - Set destination address hold transfer size
+ * @chan : Freescale DMA channel
  * @size     : Address loop size, 0 for disable loop
  *
  * The set destination address hold transfer size. The destination
@@ -260,29 +238,30 @@ static void fsl_chan_set_src_loop_size(s
  * write data to TA, TA + 1, TA + 2, TA + 3, then loop back to TA,
  * TA + 1 ... and so on.
  */
-static void fsl_chan_set_dest_loop_size(struct fsl_dma_chan *fsl_chan, int size)
+static void fsl_chan_set_dst_loop_size(struct fsldma_chan *chan, int size)
 {
+	u32 mode;
+
+	mode = DMA_IN(chan, &chan->regs->mr, 32);
+
 	switch (size) {
 	case 0:
-		DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
-			DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) &
-			(~FSL_DMA_MR_DAHE), 32);
+		mode &= ~FSL_DMA_MR_DAHE;
 		break;
 	case 1:
 	case 2:
 	case 4:
 	case 8:
-		DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
-			DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) |
-			FSL_DMA_MR_DAHE | (__ilog2(size) << 16),
-			32);
+		mode |= FSL_DMA_MR_DAHE | (__ilog2(size) << 16);
 		break;
 	}
+
+	DMA_OUT(chan, &chan->regs->mr, mode, 32);
 }
 
 /**
  * fsl_chan_set_request_count - Set DMA Request Count for external control
- * @fsl_chan : Freescale DMA channel
+ * @chan : Freescale DMA channel
  * @size     : Number of bytes to transfer in a single request
  *
  * The Freescale DMA channel can be controlled by the external signal DREQ#.
@@ -292,35 +271,38 @@ static void fsl_chan_set_dest_loop_size(
  *
  * A size of 0 disables external pause control. The maximum size is 1024.
  */
-static void fsl_chan_set_request_count(struct fsl_dma_chan *fsl_chan, int size)
+static void fsl_chan_set_request_count(struct fsldma_chan *chan, int size)
 {
+	u32 mode;
+
 	BUG_ON(size > 1024);
-	DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
-		DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32)
-			| ((__ilog2(size) << 24) & 0x0f000000),
-		32);
+
+	mode = DMA_IN(chan, &chan->regs->mr, 32);
+	mode |= (__ilog2(size) << 24) & 0x0f000000;
+
+	DMA_OUT(chan, &chan->regs->mr, mode, 32);
 }
 
 /**
  * fsl_chan_toggle_ext_pause - Toggle channel external pause status
- * @fsl_chan : Freescale DMA channel
+ * @chan : Freescale DMA channel
  * @enable   : 0 is disabled, 1 is enabled.
  *
  * The Freescale DMA channel can be controlled by the external signal DREQ#.
  * The DMA Request Count feature should be used in addition to this feature
  * to set the number of bytes to transfer before pausing the channel.
  */
-static void fsl_chan_toggle_ext_pause(struct fsl_dma_chan *fsl_chan, int enable)
+static void fsl_chan_toggle_ext_pause(struct fsldma_chan *chan, int enable)
 {
 	if (enable)
-		fsl_chan->feature |= FSL_DMA_CHAN_PAUSE_EXT;
+		chan->feature |= FSL_DMA_CHAN_PAUSE_EXT;
 	else
-		fsl_chan->feature &= ~FSL_DMA_CHAN_PAUSE_EXT;
+		chan->feature &= ~FSL_DMA_CHAN_PAUSE_EXT;
 }
 
 /**
  * fsl_chan_toggle_ext_start - Toggle channel external start status
- * @fsl_chan : Freescale DMA channel
+ * @chan : Freescale DMA channel
  * @enable   : 0 is disabled, 1 is enabled.
  *
  * If enable the external start, the channel can be started by an
@@ -328,141 +310,196 @@ static void fsl_chan_toggle_ext_pause(st
  * transfer immediately. The DMA channel will wait for the
  * control pin asserted.
  */
-static void fsl_chan_toggle_ext_start(struct fsl_dma_chan *fsl_chan, int enable)
+static void fsl_chan_toggle_ext_start(struct fsldma_chan *chan, int enable)
 {
 	if (enable)
-		fsl_chan->feature |= FSL_DMA_CHAN_START_EXT;
+		chan->feature |= FSL_DMA_CHAN_START_EXT;
 	else
-		fsl_chan->feature &= ~FSL_DMA_CHAN_START_EXT;
+		chan->feature &= ~FSL_DMA_CHAN_START_EXT;
+}
+
+static void append_ld_queue(struct fsldma_chan *chan,
+			    struct fsl_desc_sw *desc)
+{
+	struct fsl_desc_sw *tail = to_fsl_desc(chan->ld_pending.prev);
+
+	if (list_empty(&chan->ld_pending))
+		goto out_splice;
+
+	/*
+	 * Add the hardware descriptor to the chain of hardware descriptors
+	 * that already exists in memory.
+	 *
+	 * This will un-set the EOL bit of the existing transaction, and the
+	 * last link in this transaction will become the EOL descriptor.
+	 */
+	set_desc_next(chan, &tail->hw, desc->async_tx.phys);
+
+	/*
+	 * Add the software descriptor and all children to the list
+	 * of pending transactions
+	 */
+out_splice:
+	list_splice_tail_init(&desc->tx_list, &chan->ld_pending);
 }
 
 static dma_cookie_t fsl_dma_tx_submit(struct dma_async_tx_descriptor *tx)
 {
-	struct fsl_dma_chan *fsl_chan = to_fsl_chan(tx->chan);
+	struct fsldma_chan *chan = to_fsl_chan(tx->chan);
 	struct fsl_desc_sw *desc = tx_to_fsl_desc(tx);
 	struct fsl_desc_sw *child;
 	unsigned long flags;
 	dma_cookie_t cookie;
 
-	/* cookie increment and adding to ld_queue must be atomic */
-	spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+	spin_lock_irqsave(&chan->desc_lock, flags);
 
-	cookie = fsl_chan->common.cookie;
+	/*
+	 * assign cookies to all of the software descriptors
+	 * that make up this transaction
+	 */
+	cookie = chan->common.cookie;
 	list_for_each_entry(child, &desc->tx_list, node) {
 		cookie++;
 		if (cookie < 0)
 			cookie = 1;
 
-		desc->async_tx.cookie = cookie;
+		child->async_tx.cookie = cookie;
 	}
 
-	fsl_chan->common.cookie = cookie;
-	append_ld_queue(fsl_chan, desc);
-	list_splice_init(&desc->tx_list, fsl_chan->ld_queue.prev);
+	chan->common.cookie = cookie;
 
-	spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+	/* put this transaction onto the tail of the pending queue */
+	append_ld_queue(chan, desc);
+
+	spin_unlock_irqrestore(&chan->desc_lock, flags);
 
 	return cookie;
 }
 
 /**
  * fsl_dma_alloc_descriptor - Allocate descriptor from channel's DMA pool.
- * @fsl_chan : Freescale DMA channel
+ * @chan : Freescale DMA channel
  *
  * Return - The descriptor allocated. NULL for failed.
  */
 static struct fsl_desc_sw *fsl_dma_alloc_descriptor(
-					struct fsl_dma_chan *fsl_chan)
+					struct fsldma_chan *chan)
 {
+	struct fsl_desc_sw *desc;
 	dma_addr_t pdesc;
-	struct fsl_desc_sw *desc_sw;
 
-	desc_sw = dma_pool_alloc(fsl_chan->desc_pool, GFP_ATOMIC, &pdesc);
-	if (desc_sw) {
-		memset(desc_sw, 0, sizeof(struct fsl_desc_sw));
-		INIT_LIST_HEAD(&desc_sw->tx_list);
-		dma_async_tx_descriptor_init(&desc_sw->async_tx,
-						&fsl_chan->common);
-		desc_sw->async_tx.tx_submit = fsl_dma_tx_submit;
-		desc_sw->async_tx.phys = pdesc;
+	desc = dma_pool_alloc(chan->desc_pool, GFP_ATOMIC, &pdesc);
+	if (!desc) {
+		dev_dbg(chan->dev, "out of memory for link desc\n");
+		return NULL;
 	}
 
-	return desc_sw;
+	memset(desc, 0, sizeof(*desc));
+	INIT_LIST_HEAD(&desc->tx_list);
+	dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
+	desc->async_tx.tx_submit = fsl_dma_tx_submit;
+	desc->async_tx.phys = pdesc;
+
+	return desc;
 }
 
 
 /**
  * fsl_dma_alloc_chan_resources - Allocate resources for DMA channel.
- * @fsl_chan : Freescale DMA channel
+ * @chan : Freescale DMA channel
  *
  * This function will create a dma pool for descriptor allocation.
  *
  * Return - The number of descriptors allocated.
  */
-static int fsl_dma_alloc_chan_resources(struct dma_chan *chan)
+static int fsl_dma_alloc_chan_resources(struct dma_chan *dchan)
 {
-	struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+	struct fsldma_chan *chan = to_fsl_chan(dchan);
 
 	/* Has this channel already been allocated? */
-	if (fsl_chan->desc_pool)
+	if (chan->desc_pool)
 		return 1;
 
-	/* We need the descriptor to be aligned to 32bytes
+	/*
+	 * We need the descriptor to be aligned to 32bytes
 	 * for meeting FSL DMA specification requirement.
 	 */
-	fsl_chan->desc_pool = dma_pool_create("fsl_dma_engine_desc_pool",
-			fsl_chan->dev, sizeof(struct fsl_desc_sw),
-			32, 0);
-	if (!fsl_chan->desc_pool) {
-		dev_err(fsl_chan->dev, "No memory for channel %d "
-			"descriptor dma pool.\n", fsl_chan->id);
-		return 0;
+	chan->desc_pool = dma_pool_create("fsl_dma_engine_desc_pool",
+					  chan->dev,
+					  sizeof(struct fsl_desc_sw),
+					  __alignof__(struct fsl_desc_sw), 0);
+	if (!chan->desc_pool) {
+		dev_err(chan->dev, "unable to allocate channel %d "
+				   "descriptor pool\n", chan->id);
+		return -ENOMEM;
 	}
 
+	/* there is at least one descriptor free to be allocated */
 	return 1;
 }
 
 /**
- * fsl_dma_free_chan_resources - Free all resources of the channel.
- * @fsl_chan : Freescale DMA channel
+ * fsldma_free_desc_list - Free all descriptors in a queue
+ * @chan: Freescae DMA channel
+ * @list: the list to free
+ *
+ * LOCKING: must hold chan->desc_lock
  */
-static void fsl_dma_free_chan_resources(struct dma_chan *chan)
+static void fsldma_free_desc_list(struct fsldma_chan *chan,
+				  struct list_head *list)
 {
-	struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
 	struct fsl_desc_sw *desc, *_desc;
-	unsigned long flags;
 
-	dev_dbg(fsl_chan->dev, "Free all channel resources.\n");
-	spin_lock_irqsave(&fsl_chan->desc_lock, flags);
-	list_for_each_entry_safe(desc, _desc, &fsl_chan->ld_queue, node) {
-#ifdef FSL_DMA_LD_DEBUG
-		dev_dbg(fsl_chan->dev,
-				"LD %p will be released.\n", desc);
-#endif
+	list_for_each_entry_safe(desc, _desc, list, node) {
 		list_del(&desc->node);
-		/* free link descriptor */
-		dma_pool_free(fsl_chan->desc_pool, desc, desc->async_tx.phys);
+		dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys);
 	}
-	spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
-	dma_pool_destroy(fsl_chan->desc_pool);
+}
 
-	fsl_chan->desc_pool = NULL;
+static void fsldma_free_desc_list_reverse(struct fsldma_chan *chan,
+					  struct list_head *list)
+{
+	struct fsl_desc_sw *desc, *_desc;
+
+	list_for_each_entry_safe_reverse(desc, _desc, list, node) {
+		list_del(&desc->node);
+		dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys);
+	}
+}
+
+/**
+ * fsl_dma_free_chan_resources - Free all resources of the channel.
+ * @chan : Freescale DMA channel
+ */
+static void fsl_dma_free_chan_resources(struct dma_chan *dchan)
+{
+	struct fsldma_chan *chan = to_fsl_chan(dchan);
+	unsigned long flags;
+
+	dev_dbg(chan->dev, "Free all channel resources.\n");
+	spin_lock_irqsave(&chan->desc_lock, flags);
+	fsldma_free_desc_list(chan, &chan->ld_pending);
+	fsldma_free_desc_list(chan, &chan->ld_running);
+	spin_unlock_irqrestore(&chan->desc_lock, flags);
+
+	dma_pool_destroy(chan->desc_pool);
+	chan->desc_pool = NULL;
 }
 
 static struct dma_async_tx_descriptor *
-fsl_dma_prep_interrupt(struct dma_chan *chan, unsigned long flags)
+fsl_dma_prep_interrupt(struct dma_chan *dchan, unsigned long flags)
 {
-	struct fsl_dma_chan *fsl_chan;
+	struct fsldma_chan *chan;
 	struct fsl_desc_sw *new;
 
-	if (!chan)
+	if (!dchan)
 		return NULL;
 
-	fsl_chan = to_fsl_chan(chan);
+	chan = to_fsl_chan(dchan);
 
-	new = fsl_dma_alloc_descriptor(fsl_chan);
+	new = fsl_dma_alloc_descriptor(chan);
 	if (!new) {
-		dev_err(fsl_chan->dev, "No free memory for link descriptor\n");
+		dev_err(chan->dev, "No free memory for link descriptor\n");
 		return NULL;
 	}
 
@@ -473,51 +510,50 @@ fsl_dma_prep_interrupt(struct dma_chan *
 	list_add_tail(&new->node, &new->tx_list);
 
 	/* Set End-of-link to the last link descriptor of new list*/
-	set_ld_eol(fsl_chan, new);
+	set_ld_eol(chan, new);
 
 	return &new->async_tx;
 }
 
 static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
-	struct dma_chan *chan, dma_addr_t dma_dest, dma_addr_t dma_src,
+	struct dma_chan *dchan, dma_addr_t dma_dst, dma_addr_t dma_src,
 	size_t len, unsigned long flags)
 {
-	struct fsl_dma_chan *fsl_chan;
+	struct fsldma_chan *chan;
 	struct fsl_desc_sw *first = NULL, *prev = NULL, *new;
-	struct list_head *list;
 	size_t copy;
 
-	if (!chan)
+	if (!dchan)
 		return NULL;
 
 	if (!len)
 		return NULL;
 
-	fsl_chan = to_fsl_chan(chan);
+	chan = to_fsl_chan(dchan);
 
 	do {
 
 		/* Allocate the link descriptor from DMA pool */
-		new = fsl_dma_alloc_descriptor(fsl_chan);
+		new = fsl_dma_alloc_descriptor(chan);
 		if (!new) {
-			dev_err(fsl_chan->dev,
+			dev_err(chan->dev,
 					"No free memory for link descriptor\n");
 			goto fail;
 		}
 #ifdef FSL_DMA_LD_DEBUG
-		dev_dbg(fsl_chan->dev, "new link desc alloc %p\n", new);
+		dev_dbg(chan->dev, "new link desc alloc %p\n", new);
 #endif
 
 		copy = min(len, (size_t)FSL_DMA_BCR_MAX_CNT);
 
-		set_desc_cnt(fsl_chan, &new->hw, copy);
-		set_desc_src(fsl_chan, &new->hw, dma_src);
-		set_desc_dest(fsl_chan, &new->hw, dma_dest);
+		set_desc_cnt(chan, &new->hw, copy);
+		set_desc_src(chan, &new->hw, dma_src);
+		set_desc_dst(chan, &new->hw, dma_dst);
 
 		if (!first)
 			first = new;
 		else
-			set_desc_next(fsl_chan, &prev->hw, new->async_tx.phys);
+			set_desc_next(chan, &prev->hw, new->async_tx.phys);
 
 		new->async_tx.cookie = 0;
 		async_tx_ack(&new->async_tx);
@@ -525,7 +561,7 @@ static struct dma_async_tx_descriptor *f
 		prev = new;
 		len -= copy;
 		dma_src += copy;
-		dma_dest += copy;
+		dma_dst += copy;
 
 		/* Insert the link descriptor to the LD ring */
 		list_add_tail(&new->node, &first->tx_list);
@@ -535,7 +571,7 @@ static struct dma_async_tx_descriptor *f
 	new->async_tx.cookie = -EBUSY;
 
 	/* Set End-of-link to the last link descriptor of new list*/
-	set_ld_eol(fsl_chan, new);
+	set_ld_eol(chan, new);
 
 	return &first->async_tx;
 
@@ -543,12 +579,7 @@ fail:
 	if (!first)
 		return NULL;
 
-	list = &first->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);
-	}
-
+	fsldma_free_desc_list_reverse(chan, &first->tx_list);
 	return NULL;
 }
 
@@ -565,13 +596,12 @@ fail:
  * chan->private variable.
  */
 static struct dma_async_tx_descriptor *fsl_dma_prep_slave_sg(
-	struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len,
+	struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len,
 	enum dma_data_direction direction, unsigned long flags)
 {
-	struct fsl_dma_chan *fsl_chan;
+	struct fsldma_chan *chan;
 	struct fsl_desc_sw *first = NULL, *prev = NULL, *new = NULL;
 	struct fsl_dma_slave *slave;
-	struct list_head *tx_list;
 	size_t copy;
 
 	int i;
@@ -581,14 +611,14 @@ static struct dma_async_tx_descriptor *f
 	struct fsl_dma_hw_addr *hw;
 	dma_addr_t dma_dst, dma_src;
 
-	if (!chan)
+	if (!dchan)
 		return NULL;
 
-	if (!chan->private)
+	if (!dchan->private)
 		return NULL;
 
-	fsl_chan = to_fsl_chan(chan);
-	slave = chan->private;
+	chan = to_fsl_chan(dchan);
+	slave = dchan->private;
 
 	if (list_empty(&slave->addresses))
 		return NULL;
@@ -637,14 +667,14 @@ static struct dma_async_tx_descriptor *f
 			}
 
 			/* Allocate the link descriptor from DMA pool */
-			new = fsl_dma_alloc_descriptor(fsl_chan);
+			new = fsl_dma_alloc_descriptor(chan);
 			if (!new) {
-				dev_err(fsl_chan->dev, "No free memory for "
+				dev_err(chan->dev, "No free memory for "
 						       "link descriptor\n");
 				goto fail;
 			}
 #ifdef FSL_DMA_LD_DEBUG
-			dev_dbg(fsl_chan->dev, "new link desc alloc %p\n", new);
+			dev_dbg(chan->dev, "new link desc alloc %p\n", new);
 #endif
 
 			/*
@@ -671,9 +701,9 @@ static struct dma_async_tx_descriptor *f
 			}
 
 			/* Fill in the descriptor */
-			set_desc_cnt(fsl_chan, &new->hw, copy);
-			set_desc_src(fsl_chan, &new->hw, dma_src);
-			set_desc_dest(fsl_chan, &new->hw, dma_dst);
+			set_desc_cnt(chan, &new->hw, copy);
+			set_desc_src(chan, &new->hw, dma_src);
+			set_desc_dst(chan, &new->hw, dma_dst);
 
 			/*
 			 * If this is not the first descriptor, chain the
@@ -682,7 +712,7 @@ static struct dma_async_tx_descriptor *f
 			if (!first) {
 				first = new;
 			} else {
-				set_desc_next(fsl_chan, &prev->hw,
+				set_desc_next(chan, &prev->hw,
 					      new->async_tx.phys);
 			}
 
@@ -708,23 +738,23 @@ finished:
 	new->async_tx.cookie = -EBUSY;
 
 	/* Set End-of-link to the last link descriptor of new list */
-	set_ld_eol(fsl_chan, new);
+	set_ld_eol(chan, new);
 
 	/* Enable extra controller features */
-	if (fsl_chan->set_src_loop_size)
-		fsl_chan->set_src_loop_size(fsl_chan, slave->src_loop_size);
+	if (chan->set_src_loop_size)
+		chan->set_src_loop_size(chan, slave->src_loop_size);
 
-	if (fsl_chan->set_dest_loop_size)
-		fsl_chan->set_dest_loop_size(fsl_chan, slave->dst_loop_size);
+	if (chan->set_dst_loop_size)
+		chan->set_dst_loop_size(chan, slave->dst_loop_size);
 
-	if (fsl_chan->toggle_ext_start)
-		fsl_chan->toggle_ext_start(fsl_chan, slave->external_start);
+	if (chan->toggle_ext_start)
+		chan->toggle_ext_start(chan, slave->external_start);
 
-	if (fsl_chan->toggle_ext_pause)
-		fsl_chan->toggle_ext_pause(fsl_chan, slave->external_pause);
+	if (chan->toggle_ext_pause)
+		chan->toggle_ext_pause(chan, slave->external_pause);
 
-	if (fsl_chan->set_request_count)
-		fsl_chan->set_request_count(fsl_chan, slave->request_count);
+	if (chan->set_request_count)
+		chan->set_request_count(chan, slave->request_count);
 
 	return &first->async_tx;
 
@@ -741,215 +771,216 @@ fail:
 	 *
 	 * We're re-using variables for the loop, oh well
 	 */
-	tx_list = &first->tx_list;
-	list_for_each_entry_safe_reverse(new, prev, tx_list, node) {
-		list_del_init(&new->node);
-		dma_pool_free(fsl_chan->desc_pool, new, new->async_tx.phys);
-	}
-
+	fsldma_free_desc_list_reverse(chan, &first->tx_list);
 	return NULL;
 }
 
-static void fsl_dma_device_terminate_all(struct dma_chan *chan)
+static void fsl_dma_device_terminate_all(struct dma_chan *dchan)
 {
-	struct fsl_dma_chan *fsl_chan;
-	struct fsl_desc_sw *desc, *tmp;
+	struct fsldma_chan *chan;
 	unsigned long flags;
 
-	if (!chan)
+	if (!dchan)
 		return;
 
-	fsl_chan = to_fsl_chan(chan);
+	chan = to_fsl_chan(dchan);
 
 	/* Halt the DMA engine */
-	dma_halt(fsl_chan);
+	dma_halt(chan);
 
-	spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+	spin_lock_irqsave(&chan->desc_lock, flags);
 
 	/* Remove and free all of the descriptors in the LD queue */
-	list_for_each_entry_safe(desc, tmp, &fsl_chan->ld_queue, node) {
-		list_del(&desc->node);
-		dma_pool_free(fsl_chan->desc_pool, desc, desc->async_tx.phys);
-	}
+	fsldma_free_desc_list(chan, &chan->ld_pending);
+	fsldma_free_desc_list(chan, &chan->ld_running);
 
-	spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+	spin_unlock_irqrestore(&chan->desc_lock, flags);
 }
 
 /**
  * fsl_dma_update_completed_cookie - Update the completed cookie.
- * @fsl_chan : Freescale DMA channel
+ * @chan : Freescale DMA channel
+ *
+ * CONTEXT: hardirq
  */
-static void fsl_dma_update_completed_cookie(struct fsl_dma_chan *fsl_chan)
+static void fsl_dma_update_completed_cookie(struct fsldma_chan *chan)
 {
-	struct fsl_desc_sw *cur_desc, *desc;
-	dma_addr_t ld_phy;
+	struct fsl_desc_sw *desc;
+	unsigned long flags;
+	dma_cookie_t cookie;
 
-	ld_phy = get_cdar(fsl_chan) & FSL_DMA_NLDA_MASK;
+	spin_lock_irqsave(&chan->desc_lock, flags);
 
-	if (ld_phy) {
-		cur_desc = NULL;
-		list_for_each_entry(desc, &fsl_chan->ld_queue, node)
-			if (desc->async_tx.phys == ld_phy) {
-				cur_desc = desc;
-				break;
-			}
+	if (list_empty(&chan->ld_running)) {
+		dev_dbg(chan->dev, "no running descriptors\n");
+		goto out_unlock;
+	}
 
-		if (cur_desc && cur_desc->async_tx.cookie) {
-			if (dma_is_idle(fsl_chan))
-				fsl_chan->completed_cookie =
-					cur_desc->async_tx.cookie;
-			else
-				fsl_chan->completed_cookie =
-					cur_desc->async_tx.cookie - 1;
-		}
+	/* Get the last descriptor, update the cookie to that */
+	desc = to_fsl_desc(chan->ld_running.prev);
+	if (dma_is_idle(chan))
+		cookie = desc->async_tx.cookie;
+	else {
+		cookie = desc->async_tx.cookie - 1;
+		if (unlikely(cookie < DMA_MIN_COOKIE))
+			cookie = DMA_MAX_COOKIE;
 	}
+
+	chan->completed_cookie = cookie;
+
+out_unlock:
+	spin_unlock_irqrestore(&chan->desc_lock, flags);
+}
+
+/**
+ * fsldma_desc_status - Check the status of a descriptor
+ * @chan: Freescale DMA channel
+ * @desc: DMA SW descriptor
+ *
+ * This function will return the status of the given descriptor
+ */
+static enum dma_status fsldma_desc_status(struct fsldma_chan *chan,
+					  struct fsl_desc_sw *desc)
+{
+	return dma_async_is_complete(desc->async_tx.cookie,
+				     chan->completed_cookie,
+				     chan->common.cookie);
 }
 
 /**
  * fsl_chan_ld_cleanup - Clean up link descriptors
- * @fsl_chan : Freescale DMA channel
+ * @chan : Freescale DMA channel
  *
  * This function clean up the ld_queue of DMA channel.
- * If 'in_intr' is set, the function will move the link descriptor to
- * the recycle list. Otherwise, free it directly.
  */
-static void fsl_chan_ld_cleanup(struct fsl_dma_chan *fsl_chan)
+static void fsl_chan_ld_cleanup(struct fsldma_chan *chan)
 {
 	struct fsl_desc_sw *desc, *_desc;
 	unsigned long flags;
 
-	spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+	spin_lock_irqsave(&chan->desc_lock, flags);
 
-	dev_dbg(fsl_chan->dev, "chan completed_cookie = %d\n",
-			fsl_chan->completed_cookie);
-	list_for_each_entry_safe(desc, _desc, &fsl_chan->ld_queue, node) {
+	dev_dbg(chan->dev, "chan completed_cookie = %d\n", chan->completed_cookie);
+	list_for_each_entry_safe(desc, _desc, &chan->ld_running, node) {
 		dma_async_tx_callback callback;
 		void *callback_param;
 
-		if (dma_async_is_complete(desc->async_tx.cookie,
-			    fsl_chan->completed_cookie, fsl_chan->common.cookie)
-				== DMA_IN_PROGRESS)
+		if (fsldma_desc_status(chan, desc) == DMA_IN_PROGRESS)
 			break;
 
-		callback = desc->async_tx.callback;
-		callback_param = desc->async_tx.callback_param;
-
-		/* Remove from ld_queue list */
+		/* Remove from the list of running transactions */
 		list_del(&desc->node);
 
-		dev_dbg(fsl_chan->dev, "link descriptor %p will be recycle.\n",
-				desc);
-		dma_pool_free(fsl_chan->desc_pool, desc, desc->async_tx.phys);
-
 		/* Run the link descriptor callback function */
+		callback = desc->async_tx.callback;
+		callback_param = desc->async_tx.callback_param;
 		if (callback) {
-			spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
-			dev_dbg(fsl_chan->dev, "link descriptor %p callback\n",
-					desc);
+			spin_unlock_irqrestore(&chan->desc_lock, flags);
+			dev_dbg(chan->dev, "LD %p callback\n", desc);
 			callback(callback_param);
-			spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+			spin_lock_irqsave(&chan->desc_lock, flags);
 		}
+
+		/* Run any dependencies, then free the descriptor */
+		dma_run_dependencies(&desc->async_tx);
+		dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys);
 	}
-	spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+
+	spin_unlock_irqrestore(&chan->desc_lock, flags);
 }
 
 /**
- * fsl_chan_xfer_ld_queue - Transfer link descriptors in channel ld_queue.
- * @fsl_chan : Freescale DMA channel
+ * fsl_chan_xfer_ld_queue - transfer any pending transactions
+ * @chan : Freescale DMA channel
+ *
+ * This will make sure that any pending transactions will be run.
+ * If the DMA controller is idle, it will be started. Otherwise,
+ * the DMA controller's interrupt handler will start any pending
+ * transactions when it becomes idle.
  */
-static void fsl_chan_xfer_ld_queue(struct fsl_dma_chan *fsl_chan)
+static void fsl_chan_xfer_ld_queue(struct fsldma_chan *chan)
 {
-	struct list_head *ld_node;
-	dma_addr_t next_dest_addr;
+	struct fsl_desc_sw *desc;
 	unsigned long flags;
 
-	spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+	spin_lock_irqsave(&chan->desc_lock, flags);
 
-	if (!dma_is_idle(fsl_chan))
+	/*
+	 * If the list of pending descriptors is empty, then we
+	 * don't need to do any work at all
+	 */
+	if (list_empty(&chan->ld_pending)) {
+		dev_dbg(chan->dev, "no pending LDs\n");
 		goto out_unlock;
+	}
 
-	dma_halt(fsl_chan);
+	/*
+	 * The DMA controller is not idle, which means the interrupt
+	 * handler will start any queued transactions when it runs
+	 * at the end of the current transaction
+	 */
+	if (!dma_is_idle(chan)) {
+		dev_dbg(chan->dev, "DMA controller still busy\n");
+		goto out_unlock;
+	}
 
-	/* If there are some link descriptors
-	 * not transfered in queue. We need to start it.
+	/*
+	 * TODO:
+	 * make sure the dma_halt() function really un-wedges the
+	 * controller as much as possible
 	 */
+	dma_halt(chan);
 
-	/* Find the first un-transfer desciptor */
-	for (ld_node = fsl_chan->ld_queue.next;
-		(ld_node != &fsl_chan->ld_queue)
-			&& (dma_async_is_complete(
-				to_fsl_desc(ld_node)->async_tx.cookie,
-				fsl_chan->completed_cookie,
-				fsl_chan->common.cookie) == DMA_SUCCESS);
-		ld_node = ld_node->next);
+	/*
+	 * If there are some link descriptors which have not been
+	 * transferred, we need to start the controller
+	 */
 
-	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 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);
-	}
+	/*
+	 * Move all elements from the queue of pending transactions
+	 * onto the list of running transactions
+	 */
+	desc = list_first_entry(&chan->ld_pending, struct fsl_desc_sw, node);
+	list_splice_tail_init(&chan->ld_pending, &chan->ld_running);
+
+	/*
+	 * Program the descriptor's address into the DMA controller,
+	 * then start the DMA transaction
+	 */
+	set_cdar(chan, desc->async_tx.phys);
+	dma_start(chan);
 
 out_unlock:
-	spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+	spin_unlock_irqrestore(&chan->desc_lock, flags);
 }
 
 /**
  * fsl_dma_memcpy_issue_pending - Issue the DMA start command
- * @fsl_chan : Freescale DMA channel
+ * @chan : Freescale DMA channel
  */
-static void fsl_dma_memcpy_issue_pending(struct dma_chan *chan)
+static void fsl_dma_memcpy_issue_pending(struct dma_chan *dchan)
 {
-	struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
-
-#ifdef FSL_DMA_LD_DEBUG
-	struct fsl_desc_sw *ld;
-	unsigned long flags;
-
-	spin_lock_irqsave(&fsl_chan->desc_lock, flags);
-	if (list_empty(&fsl_chan->ld_queue)) {
-		spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
-		return;
-	}
-
-	dev_dbg(fsl_chan->dev, "--memcpy issue--\n");
-	list_for_each_entry(ld, &fsl_chan->ld_queue, node) {
-		int i;
-		dev_dbg(fsl_chan->dev, "Ch %d, LD %08x\n",
-				fsl_chan->id, ld->async_tx.phys);
-		for (i = 0; i < 8; i++)
-			dev_dbg(fsl_chan->dev, "LD offset %d: %08x\n",
-					i, *(((u32 *)&ld->hw) + i));
-	}
-	dev_dbg(fsl_chan->dev, "----------------\n");
-	spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
-#endif
-
-	fsl_chan_xfer_ld_queue(fsl_chan);
+	struct fsldma_chan *chan = to_fsl_chan(dchan);
+	fsl_chan_xfer_ld_queue(chan);
 }
 
 /**
  * fsl_dma_is_complete - Determine the DMA status
- * @fsl_chan : Freescale DMA channel
+ * @chan : Freescale DMA channel
  */
-static enum dma_status fsl_dma_is_complete(struct dma_chan *chan,
+static enum dma_status fsl_dma_is_complete(struct dma_chan *dchan,
 					dma_cookie_t cookie,
 					dma_cookie_t *done,
 					dma_cookie_t *used)
 {
-	struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+	struct fsldma_chan *chan = to_fsl_chan(dchan);
 	dma_cookie_t last_used;
 	dma_cookie_t last_complete;
 
-	fsl_chan_ld_cleanup(fsl_chan);
+	fsl_chan_ld_cleanup(chan);
 
-	last_used = chan->cookie;
-	last_complete = fsl_chan->completed_cookie;
+	last_used = dchan->cookie;
+	last_complete = chan->completed_cookie;
 
 	if (done)
 		*done = last_complete;
@@ -960,32 +991,37 @@ static enum dma_status fsl_dma_is_comple
 	return dma_async_is_complete(cookie, last_complete, last_used);
 }
 
-static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data)
+/*----------------------------------------------------------------------------*/
+/* Interrupt Handling                                                         */
+/*----------------------------------------------------------------------------*/
+
+static irqreturn_t fsldma_chan_irq(int irq, void *data)
 {
-	struct fsl_dma_chan *fsl_chan = (struct fsl_dma_chan *)data;
-	u32 stat;
+	struct fsldma_chan *chan = data;
 	int update_cookie = 0;
 	int xfer_ld_q = 0;
+	u32 stat;
 
-	stat = get_sr(fsl_chan);
-	dev_dbg(fsl_chan->dev, "event: channel %d, stat = 0x%x\n",
-						fsl_chan->id, stat);
-	set_sr(fsl_chan, stat);		/* Clear the event register */
+	/* save and clear the status register */
+	stat = get_sr(chan);
+	set_sr(chan, stat);
+	dev_dbg(chan->dev, "irq: channel %d, stat = 0x%x\n", chan->id, stat);
 
 	stat &= ~(FSL_DMA_SR_CB | FSL_DMA_SR_CH);
 	if (!stat)
 		return IRQ_NONE;
 
 	if (stat & FSL_DMA_SR_TE)
-		dev_err(fsl_chan->dev, "Transfer Error!\n");
+		dev_err(chan->dev, "Transfer Error!\n");
 
-	/* Programming Error
+	/*
+	 * Programming Error
 	 * The DMA_INTERRUPT async_tx is a NULL transfer, which will
 	 * triger a PE interrupt.
 	 */
 	if (stat & FSL_DMA_SR_PE) {
-		dev_dbg(fsl_chan->dev, "event: Programming Error INT\n");
-		if (get_bcr(fsl_chan) == 0) {
+		dev_dbg(chan->dev, "irq: Programming Error INT\n");
+		if (get_bcr(chan) == 0) {
 			/* BCR register is 0, this is a DMA_INTERRUPT async_tx.
 			 * Now, update the completed cookie, and continue the
 			 * next uncompleted transfer.
@@ -996,208 +1032,296 @@ static irqreturn_t fsl_dma_chan_do_inter
 		stat &= ~FSL_DMA_SR_PE;
 	}
 
-	/* If the link descriptor segment transfer finishes,
+	/*
+	 * If the link descriptor segment transfer finishes,
 	 * we will recycle the used descriptor.
 	 */
 	if (stat & FSL_DMA_SR_EOSI) {
-		dev_dbg(fsl_chan->dev, "event: End-of-segments INT\n");
-		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));
+		dev_dbg(chan->dev, "irq: End-of-segments INT\n");
+		dev_dbg(chan->dev, "irq: clndar 0x%llx, nlndar 0x%llx\n",
+			(unsigned long long)get_cdar(chan),
+			(unsigned long long)get_ndar(chan));
 		stat &= ~FSL_DMA_SR_EOSI;
 		update_cookie = 1;
 	}
 
-	/* For MPC8349, EOCDI event need to update cookie
+	/*
+	 * For MPC8349, EOCDI event need to update cookie
 	 * and start the next transfer if it exist.
 	 */
 	if (stat & FSL_DMA_SR_EOCDI) {
-		dev_dbg(fsl_chan->dev, "event: End-of-Chain link INT\n");
+		dev_dbg(chan->dev, "irq: End-of-Chain link INT\n");
 		stat &= ~FSL_DMA_SR_EOCDI;
 		update_cookie = 1;
 		xfer_ld_q = 1;
 	}
 
-	/* If it current transfer is the end-of-transfer,
+	/*
+	 * If it current transfer is the end-of-transfer,
 	 * we should clear the Channel Start bit for
 	 * prepare next transfer.
 	 */
 	if (stat & FSL_DMA_SR_EOLNI) {
-		dev_dbg(fsl_chan->dev, "event: End-of-link INT\n");
+		dev_dbg(chan->dev, "irq: End-of-link INT\n");
 		stat &= ~FSL_DMA_SR_EOLNI;
 		xfer_ld_q = 1;
 	}
 
 	if (update_cookie)
-		fsl_dma_update_completed_cookie(fsl_chan);
+		fsl_dma_update_completed_cookie(chan);
 	if (xfer_ld_q)
-		fsl_chan_xfer_ld_queue(fsl_chan);
+		fsl_chan_xfer_ld_queue(chan);
 	if (stat)
-		dev_dbg(fsl_chan->dev, "event: unhandled sr 0x%02x\n",
-					stat);
+		dev_dbg(chan->dev, "irq: unhandled sr 0x%02x\n", stat);
 
-	dev_dbg(fsl_chan->dev, "event: Exit\n");
-	tasklet_schedule(&fsl_chan->tasklet);
+	dev_dbg(chan->dev, "irq: Exit\n");
+	tasklet_schedule(&chan->tasklet);
 	return IRQ_HANDLED;
 }
 
-static irqreturn_t fsl_dma_do_interrupt(int irq, void *data)
+static void dma_do_tasklet(unsigned long data)
 {
-	struct fsl_dma_device *fdev = (struct fsl_dma_device *)data;
-	u32 gsr;
-	int ch_nr;
+	struct fsldma_chan *chan = (struct fsldma_chan *)data;
+	fsl_chan_ld_cleanup(chan);
+}
 
-	gsr = (fdev->feature & FSL_DMA_BIG_ENDIAN) ? in_be32(fdev->reg_base)
-			: in_le32(fdev->reg_base);
-	ch_nr = (32 - ffs(gsr)) / 8;
+static irqreturn_t fsldma_ctrl_irq(int irq, void *data)
+{
+	struct fsldma_device *fdev = data;
+	struct fsldma_chan *chan;
+	unsigned int handled = 0;
+	u32 gsr, mask;
+	int i;
 
-	return fdev->chan[ch_nr] ? fsl_dma_chan_do_interrupt(irq,
-			fdev->chan[ch_nr]) : IRQ_NONE;
+	gsr = (fdev->feature & FSL_DMA_BIG_ENDIAN) ? in_be32(fdev->regs)
+						   : in_le32(fdev->regs);
+	mask = 0xff000000;
+	dev_dbg(fdev->dev, "IRQ: gsr 0x%.8x\n", gsr);
+
+	for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++) {
+		chan = fdev->chan[i];
+		if (!chan)
+			continue;
+
+		if (gsr & mask) {
+			dev_dbg(fdev->dev, "IRQ: chan %d\n", chan->id);
+			fsldma_chan_irq(irq, chan);
+			handled++;
+		}
+
+		gsr &= ~mask;
+		mask >>= 8;
+	}
+
+	return IRQ_RETVAL(handled);
 }
 
-static void dma_do_tasklet(unsigned long data)
+static void fsldma_free_irqs(struct fsldma_device *fdev)
 {
-	struct fsl_dma_chan *fsl_chan = (struct fsl_dma_chan *)data;
-	fsl_chan_ld_cleanup(fsl_chan);
+	struct fsldma_chan *chan;
+	int i;
+
+	if (fdev->irq != NO_IRQ) {
+		dev_dbg(fdev->dev, "free per-controller IRQ\n");
+		free_irq(fdev->irq, fdev);
+		return;
+	}
+
+	for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++) {
+		chan = fdev->chan[i];
+		if (chan && chan->irq != NO_IRQ) {
+			dev_dbg(fdev->dev, "free channel %d IRQ\n", chan->id);
+			free_irq(chan->irq, chan);
+		}
+	}
 }
 
-static int __devinit fsl_dma_chan_probe(struct fsl_dma_device *fdev,
+static int fsldma_request_irqs(struct fsldma_device *fdev)
+{
+	struct fsldma_chan *chan;
+	int ret;
+	int i;
+
+	/* if we have a per-controller IRQ, use that */
+	if (fdev->irq != NO_IRQ) {
+		dev_dbg(fdev->dev, "request per-controller IRQ\n");
+		ret = request_irq(fdev->irq, fsldma_ctrl_irq, IRQF_SHARED,
+				  "fsldma-controller", fdev);
+		return ret;
+	}
+
+	/* no per-controller IRQ, use the per-channel IRQs */
+	for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++) {
+		chan = fdev->chan[i];
+		if (!chan)
+			continue;
+
+		if (chan->irq == NO_IRQ) {
+			dev_err(fdev->dev, "no interrupts property defined for "
+					   "DMA channel %d. Please fix your "
+					   "device tree\n", chan->id);
+			ret = -ENODEV;
+			goto out_unwind;
+		}
+
+		dev_dbg(fdev->dev, "request channel %d IRQ\n", chan->id);
+		ret = request_irq(chan->irq, fsldma_chan_irq, IRQF_SHARED,
+				  "fsldma-chan", chan);
+		if (ret) {
+			dev_err(fdev->dev, "unable to request IRQ for DMA "
+					   "channel %d\n", chan->id);
+			goto out_unwind;
+		}
+	}
+
+	return 0;
+
+out_unwind:
+	for (/* none */; i >= 0; i--) {
+		chan = fdev->chan[i];
+		if (!chan)
+			continue;
+
+		if (chan->irq == NO_IRQ)
+			continue;
+
+		free_irq(chan->irq, chan);
+	}
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+/* OpenFirmware Subsystem                                                     */
+/*----------------------------------------------------------------------------*/
+
+static int __devinit fsl_dma_chan_probe(struct fsldma_device *fdev,
 	struct device_node *node, u32 feature, const char *compatible)
 {
-	struct fsl_dma_chan *new_fsl_chan;
+	struct fsldma_chan *chan;
+	struct resource res;
 	int err;
 
 	/* alloc channel */
-	new_fsl_chan = kzalloc(sizeof(struct fsl_dma_chan), GFP_KERNEL);
-	if (!new_fsl_chan) {
-		dev_err(fdev->dev, "No free memory for allocating "
-				"dma channels!\n");
-		return -ENOMEM;
+	chan = kzalloc(sizeof(*chan), GFP_KERNEL);
+	if (!chan) {
+		dev_err(fdev->dev, "no free memory for DMA channels!\n");
+		err = -ENOMEM;
+		goto out_return;
 	}
 
-	/* get dma channel register base */
-	err = of_address_to_resource(node, 0, &new_fsl_chan->reg);
-	if (err) {
-		dev_err(fdev->dev, "Can't get %s property 'reg'\n",
-				node->full_name);
-		goto err_no_reg;
+	/* ioremap registers for use */
+	chan->regs = of_iomap(node, 0);
+	if (!chan->regs) {
+		dev_err(fdev->dev, "unable to ioremap registers\n");
+		err = -ENOMEM;
+		goto out_free_chan;
 	}
 
-	new_fsl_chan->feature = feature;
+	err = of_address_to_resource(node, 0, &res);
+	if (err) {
+		dev_err(fdev->dev, "unable to find 'reg' property\n");
+		goto out_iounmap_regs;
+	}
 
+	chan->feature = feature;
 	if (!fdev->feature)
-		fdev->feature = new_fsl_chan->feature;
+		fdev->feature = chan->feature;
 
-	/* If the DMA device's feature is different than its channels',
-	 * report the bug.
+	/*
+	 * If the DMA device's feature is different than the feature
+	 * of its channels, report the bug
 	 */
-	WARN_ON(fdev->feature != new_fsl_chan->feature);
-
-	new_fsl_chan->dev = fdev->dev;
-	new_fsl_chan->reg_base = ioremap(new_fsl_chan->reg.start,
-			new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1);
+	WARN_ON(fdev->feature != chan->feature);
 
-	new_fsl_chan->id = ((new_fsl_chan->reg.start - 0x100) & 0xfff) >> 7;
-	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);
+	chan->dev = fdev->dev;
+	chan->id = ((res.start - 0x100) & 0xfff) >> 7;
+	if (chan->id >= FSL_DMA_MAX_CHANS_PER_DEVICE) {
+		dev_err(fdev->dev, "too many channels for device\n");
 		err = -EINVAL;
-		goto err_no_chan;
+		goto out_iounmap_regs;
 	}
-	fdev->chan[new_fsl_chan->id] = new_fsl_chan;
-	tasklet_init(&new_fsl_chan->tasklet, dma_do_tasklet,
-			(unsigned long)new_fsl_chan);
 
-	/* Init the channel */
-	dma_init(new_fsl_chan);
+	fdev->chan[chan->id] = chan;
+	tasklet_init(&chan->tasklet, dma_do_tasklet, (unsigned long)chan);
+
+	/* Initialize the channel */
+	dma_init(chan);
 
 	/* Clear cdar registers */
-	set_cdar(new_fsl_chan, 0);
+	set_cdar(chan, 0);
 
-	switch (new_fsl_chan->feature & FSL_DMA_IP_MASK) {
+	switch (chan->feature & FSL_DMA_IP_MASK) {
 	case FSL_DMA_IP_85XX:
-		new_fsl_chan->toggle_ext_pause = fsl_chan_toggle_ext_pause;
+		chan->toggle_ext_pause = fsl_chan_toggle_ext_pause;
 	case FSL_DMA_IP_83XX:
-		new_fsl_chan->toggle_ext_start = fsl_chan_toggle_ext_start;
-		new_fsl_chan->set_src_loop_size = fsl_chan_set_src_loop_size;
-		new_fsl_chan->set_dest_loop_size = fsl_chan_set_dest_loop_size;
-		new_fsl_chan->set_request_count = fsl_chan_set_request_count;
+		chan->toggle_ext_start = fsl_chan_toggle_ext_start;
+		chan->set_src_loop_size = fsl_chan_set_src_loop_size;
+		chan->set_dst_loop_size = fsl_chan_set_dst_loop_size;
+		chan->set_request_count = fsl_chan_set_request_count;
 	}
 
-	spin_lock_init(&new_fsl_chan->desc_lock);
-	INIT_LIST_HEAD(&new_fsl_chan->ld_queue);
+	spin_lock_init(&chan->desc_lock);
+	INIT_LIST_HEAD(&chan->ld_pending);
+	INIT_LIST_HEAD(&chan->ld_running);
 
-	new_fsl_chan->common.device = &fdev->common;
+	chan->common.device = &fdev->common;
+
+	/* find the IRQ line, if it exists in the device tree */
+	chan->irq = irq_of_parse_and_map(node, 0);
 
 	/* Add the channel to DMA device channel list */
-	list_add_tail(&new_fsl_chan->common.device_node,
-			&fdev->common.channels);
+	list_add_tail(&chan->common.device_node, &fdev->common.channels);
 	fdev->common.chancnt++;
 
-	new_fsl_chan->irq = irq_of_parse_and_map(node, 0);
-	if (new_fsl_chan->irq != NO_IRQ) {
-		err = request_irq(new_fsl_chan->irq,
-					&fsl_dma_chan_do_interrupt, IRQF_SHARED,
-					"fsldma-channel", new_fsl_chan);
-		if (err) {
-			dev_err(fdev->dev, "DMA channel %s request_irq error "
-				"with return %d\n", node->full_name, err);
-			goto err_no_irq;
-		}
-	}
-
-	dev_info(fdev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id,
-		 compatible,
-		 new_fsl_chan->irq != NO_IRQ ? new_fsl_chan->irq : fdev->irq);
+	dev_info(fdev->dev, "#%d (%s), irq %d\n", chan->id, compatible,
+		 chan->irq != NO_IRQ ? chan->irq : fdev->irq);
 
 	return 0;
 
-err_no_irq:
-	list_del(&new_fsl_chan->common.device_node);
-err_no_chan:
-	iounmap(new_fsl_chan->reg_base);
-err_no_reg:
-	kfree(new_fsl_chan);
+out_iounmap_regs:
+	iounmap(chan->regs);
+out_free_chan:
+	kfree(chan);
+out_return:
 	return err;
 }
 
-static void fsl_dma_chan_remove(struct fsl_dma_chan *fchan)
+static void fsl_dma_chan_remove(struct fsldma_chan *chan)
 {
-	if (fchan->irq != NO_IRQ)
-		free_irq(fchan->irq, fchan);
-	list_del(&fchan->common.device_node);
-	iounmap(fchan->reg_base);
-	kfree(fchan);
+	irq_dispose_mapping(chan->irq);
+	list_del(&chan->common.device_node);
+	iounmap(chan->regs);
+	kfree(chan);
 }
 
-static int __devinit of_fsl_dma_probe(struct of_device *dev,
+static int __devinit fsldma_of_probe(struct of_device *op,
 			const struct of_device_id *match)
 {
-	int err;
-	struct fsl_dma_device *fdev;
+	struct fsldma_device *fdev;
 	struct device_node *child;
+	int err;
 
-	fdev = kzalloc(sizeof(struct fsl_dma_device), GFP_KERNEL);
+	fdev = kzalloc(sizeof(*fdev), GFP_KERNEL);
 	if (!fdev) {
-		dev_err(&dev->dev, "No enough memory for 'priv'\n");
-		return -ENOMEM;
+		dev_err(&op->dev, "No enough memory for 'priv'\n");
+		err = -ENOMEM;
+		goto out_return;
 	}
-	fdev->dev = &dev->dev;
+
+	fdev->dev = &op->dev;
 	INIT_LIST_HEAD(&fdev->common.channels);
 
-	/* get DMA controller register base */
-	err = of_address_to_resource(dev->node, 0, &fdev->reg);
-	if (err) {
-		dev_err(&dev->dev, "Can't get %s property 'reg'\n",
-				dev->node->full_name);
-		goto err_no_reg;
+	/* ioremap the registers for use */
+	fdev->regs = of_iomap(op->node, 0);
+	if (!fdev->regs) {
+		dev_err(&op->dev, "unable to ioremap registers\n");
+		err = -ENOMEM;
+		goto out_free_fdev;
 	}
 
-	dev_info(&dev->dev, "Probe the Freescale DMA driver for %s "
-			"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);
+	/* map the channel IRQ if it exists, but don't hookup the handler yet */
+	fdev->irq = irq_of_parse_and_map(op->node, 0);
 
 	dma_cap_set(DMA_MEMCPY, fdev->common.cap_mask);
 	dma_cap_set(DMA_INTERRUPT, fdev->common.cap_mask);
@@ -1210,103 +1334,111 @@ static int __devinit of_fsl_dma_probe(st
 	fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending;
 	fdev->common.device_prep_slave_sg = fsl_dma_prep_slave_sg;
 	fdev->common.device_terminate_all = fsl_dma_device_terminate_all;
-	fdev->common.dev = &dev->dev;
-
-	fdev->irq = irq_of_parse_and_map(dev->node, 0);
-	if (fdev->irq != NO_IRQ) {
-		err = request_irq(fdev->irq, &fsl_dma_do_interrupt, IRQF_SHARED,
-					"fsldma-device", fdev);
-		if (err) {
-			dev_err(&dev->dev, "DMA device request_irq error "
-				"with return %d\n", err);
-			goto err;
-		}
-	}
+	fdev->common.dev = &op->dev;
 
-	dev_set_drvdata(&(dev->dev), fdev);
+	dev_set_drvdata(&op->dev, fdev);
 
-	/* We cannot use of_platform_bus_probe() because there is no
-	 * of_platform_bus_remove.  Instead, we manually instantiate every DMA
+	/*
+	 * We cannot use of_platform_bus_probe() because there is no
+	 * of_platform_bus_remove(). Instead, we manually instantiate every DMA
 	 * channel object.
 	 */
-	for_each_child_of_node(dev->node, child) {
-		if (of_device_is_compatible(child, "fsl,eloplus-dma-channel"))
+	for_each_child_of_node(op->node, child) {
+		if (of_device_is_compatible(child, "fsl,eloplus-dma-channel")) {
 			fsl_dma_chan_probe(fdev, child,
 				FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN,
 				"fsl,eloplus-dma-channel");
-		if (of_device_is_compatible(child, "fsl,elo-dma-channel"))
+		}
+
+		if (of_device_is_compatible(child, "fsl,elo-dma-channel")) {
 			fsl_dma_chan_probe(fdev, child,
 				FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN,
 				"fsl,elo-dma-channel");
+		}
+	}
+
+	/*
+	 * Hookup the IRQ handler(s)
+	 *
+	 * If we have a per-controller interrupt, we prefer that to the
+	 * per-channel interrupts to reduce the number of shared interrupt
+	 * handlers on the same IRQ line
+	 */
+	err = fsldma_request_irqs(fdev);
+	if (err) {
+		dev_err(fdev->dev, "unable to request IRQs\n");
+		goto out_free_fdev;
 	}
 
 	dma_async_device_register(&fdev->common);
 	return 0;
 
-err:
-	iounmap(fdev->reg_base);
-err_no_reg:
+out_free_fdev:
+	irq_dispose_mapping(fdev->irq);
 	kfree(fdev);
+out_return:
 	return err;
 }
 
-static int of_fsl_dma_remove(struct of_device *of_dev)
+static int fsldma_of_remove(struct of_device *op)
 {
-	struct fsl_dma_device *fdev;
+	struct fsldma_device *fdev;
 	unsigned int i;
 
-	fdev = dev_get_drvdata(&of_dev->dev);
-
+	fdev = dev_get_drvdata(&op->dev);
 	dma_async_device_unregister(&fdev->common);
 
-	for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++)
+	fsldma_free_irqs(fdev);
+
+	for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++) {
 		if (fdev->chan[i])
 			fsl_dma_chan_remove(fdev->chan[i]);
+	}
 
-	if (fdev->irq != NO_IRQ)
-		free_irq(fdev->irq, fdev);
-
-	iounmap(fdev->reg_base);
-
+	iounmap(fdev->regs);
+	dev_set_drvdata(&op->dev, NULL);
 	kfree(fdev);
-	dev_set_drvdata(&of_dev->dev, NULL);
 
 	return 0;
 }
 
-static struct of_device_id of_fsl_dma_ids[] = {
+static const struct of_device_id fsldma_of_ids[] = {
 	{ .compatible = "fsl,eloplus-dma", },
 	{ .compatible = "fsl,elo-dma", },
 	{}
 };
 
-static struct of_platform_driver of_fsl_dma_driver = {
-	.name = "fsl-elo-dma",
-	.match_table = of_fsl_dma_ids,
-	.probe = of_fsl_dma_probe,
-	.remove = of_fsl_dma_remove,
+static struct of_platform_driver fsldma_of_driver = {
+	.name		= "fsl-elo-dma",
+	.match_table	= fsldma_of_ids,
+	.probe		= fsldma_of_probe,
+	.remove		= fsldma_of_remove,
 };
 
-static __init int of_fsl_dma_init(void)
+/*----------------------------------------------------------------------------*/
+/* Module Init / Exit                                                         */
+/*----------------------------------------------------------------------------*/
+
+static __init int fsldma_init(void)
 {
 	int ret;
 
 	pr_info("Freescale Elo / Elo Plus DMA driver\n");
 
-	ret = of_register_platform_driver(&of_fsl_dma_driver);
+	ret = of_register_platform_driver(&fsldma_of_driver);
 	if (ret)
 		pr_err("fsldma: failed to register platform driver\n");
 
 	return ret;
 }
 
-static void __exit of_fsl_dma_exit(void)
+static void __exit fsldma_exit(void)
 {
-	of_unregister_platform_driver(&of_fsl_dma_driver);
+	of_unregister_platform_driver(&fsldma_of_driver);
 }
 
-subsys_initcall(of_fsl_dma_init);
-module_exit(of_fsl_dma_exit);
+subsys_initcall(fsldma_init);
+module_exit(fsldma_exit);
 
 MODULE_DESCRIPTION("Freescale Elo / Elo Plus DMA driver");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/fsldma.h linux-libre-2.6.34-gnu1/drivers/dma/fsldma.h
--- linux-libre-2.6.33-gnu1/drivers/dma/fsldma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/fsldma.h	2010-05-16 17:17:36.000000000 -0400
@@ -92,11 +92,9 @@ struct fsl_desc_sw {
 	struct list_head node;
 	struct list_head tx_list;
 	struct dma_async_tx_descriptor async_tx;
-	struct list_head *ld;
-	void *priv;
 } __attribute__((aligned(32)));
 
-struct fsl_dma_chan_regs {
+struct fsldma_chan_regs {
 	u32 mr;	/* 0x00 - Mode Register */
 	u32 sr;	/* 0x04 - Status Register */
 	u64 cdar;	/* 0x08 - Current descriptor address register */
@@ -106,20 +104,19 @@ struct fsl_dma_chan_regs {
 	u64 ndar;	/* 0x24 - Next Descriptor Address Register */
 };
 
-struct fsl_dma_chan;
+struct fsldma_chan;
 #define FSL_DMA_MAX_CHANS_PER_DEVICE 4
 
-struct fsl_dma_device {
-	void __iomem *reg_base;	/* DGSR register base */
-	struct resource reg;	/* Resource for register */
+struct fsldma_device {
+	void __iomem *regs;	/* DGSR register base */
 	struct device *dev;
 	struct dma_device common;
-	struct fsl_dma_chan *chan[FSL_DMA_MAX_CHANS_PER_DEVICE];
+	struct fsldma_chan *chan[FSL_DMA_MAX_CHANS_PER_DEVICE];
 	u32 feature;		/* The same as DMA channels */
 	int irq;		/* Channel IRQ */
 };
 
-/* Define macros for fsl_dma_chan->feature property */
+/* Define macros for fsldma_chan->feature property */
 #define FSL_DMA_LITTLE_ENDIAN	0x00000000
 #define FSL_DMA_BIG_ENDIAN	0x00000001
 
@@ -130,28 +127,28 @@ struct fsl_dma_device {
 #define FSL_DMA_CHAN_PAUSE_EXT	0x00001000
 #define FSL_DMA_CHAN_START_EXT	0x00002000
 
-struct fsl_dma_chan {
-	struct fsl_dma_chan_regs __iomem *reg_base;
+struct fsldma_chan {
+	struct fsldma_chan_regs __iomem *regs;
 	dma_cookie_t completed_cookie;	/* The maximum cookie completed */
 	spinlock_t desc_lock;		/* Descriptor operation lock */
-	struct list_head ld_queue;	/* Link descriptors queue */
+	struct list_head ld_pending;	/* Link descriptors queue */
+	struct list_head ld_running;	/* Link descriptors queue */
 	struct dma_chan common;		/* DMA common channel */
 	struct dma_pool *desc_pool;	/* Descriptors pool */
 	struct device *dev;		/* Channel device */
-	struct resource reg;		/* Resource for register */
 	int irq;			/* Channel IRQ */
 	int id;				/* Raw id of this channel */
 	struct tasklet_struct tasklet;
 	u32 feature;
 
-	void (*toggle_ext_pause)(struct fsl_dma_chan *fsl_chan, int enable);
-	void (*toggle_ext_start)(struct fsl_dma_chan *fsl_chan, int enable);
-	void (*set_src_loop_size)(struct fsl_dma_chan *fsl_chan, int size);
-	void (*set_dest_loop_size)(struct fsl_dma_chan *fsl_chan, int size);
-	void (*set_request_count)(struct fsl_dma_chan *fsl_chan, int size);
+	void (*toggle_ext_pause)(struct fsldma_chan *fsl_chan, int enable);
+	void (*toggle_ext_start)(struct fsldma_chan *fsl_chan, int enable);
+	void (*set_src_loop_size)(struct fsldma_chan *fsl_chan, int size);
+	void (*set_dst_loop_size)(struct fsldma_chan *fsl_chan, int size);
+	void (*set_request_count)(struct fsldma_chan *fsl_chan, int size);
 };
 
-#define to_fsl_chan(chan) container_of(chan, struct fsl_dma_chan, common)
+#define to_fsl_chan(chan) container_of(chan, struct fsldma_chan, common)
 #define to_fsl_desc(lh) container_of(lh, struct fsl_desc_sw, node)
 #define tx_to_fsl_desc(tx) container_of(tx, struct fsl_desc_sw, async_tx)
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma.c linux-libre-2.6.34-gnu1/drivers/dma/ioat/dma.c
--- linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/ioat/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/dmaengine.h>
@@ -71,7 +72,7 @@ static irqreturn_t ioat_dma_do_interrupt
 	}
 
 	attnstatus = readl(instance->reg_base + IOAT_ATTNSTATUS_OFFSET);
-	for_each_bit(bit, &attnstatus, BITS_PER_LONG) {
+	for_each_set_bit(bit, &attnstatus, BITS_PER_LONG) {
 		chan = ioat_chan_by_index(instance, bit);
 		tasklet_schedule(&chan->cleanup_task);
 	}
@@ -94,16 +95,12 @@ static irqreturn_t ioat_dma_do_interrupt
 	return IRQ_HANDLED;
 }
 
-static void ioat1_cleanup_tasklet(unsigned long data);
-
 /* common channel initialization */
-void ioat_init_channel(struct ioatdma_device *device,
-		       struct ioat_chan_common *chan, int idx,
-		       void (*timer_fn)(unsigned long),
-		       void (*tasklet)(unsigned long),
-		       unsigned long ioat)
+void ioat_init_channel(struct ioatdma_device *device, struct ioat_chan_common *chan, int idx)
 {
 	struct dma_device *dma = &device->common;
+	struct dma_chan *c = &chan->common;
+	unsigned long data = (unsigned long) c;
 
 	chan->device = device;
 	chan->reg_base = device->reg_base + (0x80 * (idx + 1));
@@ -112,14 +109,12 @@ void ioat_init_channel(struct ioatdma_de
 	list_add_tail(&chan->common.device_node, &dma->channels);
 	device->idx[idx] = chan;
 	init_timer(&chan->timer);
-	chan->timer.function = timer_fn;
-	chan->timer.data = ioat;
-	tasklet_init(&chan->cleanup_task, tasklet, ioat);
+	chan->timer.function = device->timer_fn;
+	chan->timer.data = data;
+	tasklet_init(&chan->cleanup_task, device->cleanup_fn, data);
 	tasklet_disable(&chan->cleanup_task);
 }
 
-static void ioat1_timer_event(unsigned long data);
-
 /**
  * ioat1_dma_enumerate_channels - find and initialize the device's channels
  * @device: the device to be enumerated
@@ -155,10 +150,7 @@ static int ioat1_enumerate_channels(stru
 		if (!ioat)
 			break;
 
-		ioat_init_channel(device, &ioat->base, i,
-				  ioat1_timer_event,
-				  ioat1_cleanup_tasklet,
-				  (unsigned long) ioat);
+		ioat_init_channel(device, &ioat->base, i);
 		ioat->xfercap = xfercap;
 		spin_lock_init(&ioat->desc_lock);
 		INIT_LIST_HEAD(&ioat->free_desc);
@@ -532,12 +524,12 @@ ioat1_dma_prep_memcpy(struct dma_chan *c
 	return &desc->txd;
 }
 
-static void ioat1_cleanup_tasklet(unsigned long data)
+static void ioat1_cleanup_event(unsigned long data)
 {
-	struct ioat_dma_chan *chan = (void *)data;
+	struct ioat_dma_chan *ioat = to_ioat_chan((void *) data);
 
-	ioat1_cleanup(chan);
-	writew(IOAT_CHANCTRL_RUN, chan->base.reg_base + IOAT_CHANCTRL_OFFSET);
+	ioat1_cleanup(ioat);
+	writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET);
 }
 
 void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags,
@@ -687,7 +679,7 @@ static void ioat1_cleanup(struct ioat_dm
 
 static void ioat1_timer_event(unsigned long data)
 {
-	struct ioat_dma_chan *ioat = (void *) data;
+	struct ioat_dma_chan *ioat = to_ioat_chan((void *) data);
 	struct ioat_chan_common *chan = &ioat->base;
 
 	dev_dbg(to_dev(chan), "%s: state: %lx\n", __func__, chan->state);
@@ -734,16 +726,17 @@ static void ioat1_timer_event(unsigned l
 	spin_unlock_bh(&chan->cleanup_lock);
 }
 
-static enum dma_status
-ioat1_dma_is_complete(struct dma_chan *c, dma_cookie_t cookie,
+enum dma_status
+ioat_is_dma_complete(struct dma_chan *c, dma_cookie_t cookie,
 		      dma_cookie_t *done, dma_cookie_t *used)
 {
-	struct ioat_dma_chan *ioat = to_ioat_chan(c);
+	struct ioat_chan_common *chan = to_chan_common(c);
+	struct ioatdma_device *device = chan->device;
 
 	if (ioat_is_complete(c, cookie, done, used) == DMA_SUCCESS)
 		return DMA_SUCCESS;
 
-	ioat1_cleanup(ioat);
+	device->cleanup_fn((unsigned long) c);
 
 	return ioat_is_complete(c, cookie, done, used);
 }
@@ -1146,7 +1139,7 @@ ioat_attr_show(struct kobject *kobj, str
 	return entry->show(&chan->common, page);
 }
 
-struct sysfs_ops ioat_sysfs_ops = {
+const struct sysfs_ops ioat_sysfs_ops = {
 	.show	= ioat_attr_show,
 };
 
@@ -1199,12 +1192,14 @@ int __devinit ioat1_dma_probe(struct ioa
 	device->intr_quirk = ioat1_intr_quirk;
 	device->enumerate_channels = ioat1_enumerate_channels;
 	device->self_test = ioat_dma_self_test;
+	device->timer_fn = ioat1_timer_event;
+	device->cleanup_fn = ioat1_cleanup_event;
 	dma = &device->common;
 	dma->device_prep_dma_memcpy = ioat1_dma_prep_memcpy;
 	dma->device_issue_pending = ioat1_dma_memcpy_issue_pending;
 	dma->device_alloc_chan_resources = ioat1_dma_alloc_chan_resources;
 	dma->device_free_chan_resources = ioat1_dma_free_chan_resources;
-	dma->device_is_tx_complete = ioat1_dma_is_complete;
+	dma->device_is_tx_complete = ioat_is_dma_complete;
 
 	err = ioat_probe(device);
 	if (err)
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma.h linux-libre-2.6.34-gnu1/drivers/dma/ioat/dma.h
--- linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/ioat/dma.h	2010-05-16 17:17:36.000000000 -0400
@@ -61,7 +61,7 @@
  * @intr_quirk: interrupt setup quirk (for ioat_v1 devices)
  * @enumerate_channels: hw version specific channel enumeration
  * @reset_hw: hw version specific channel (re)initialization
- * @cleanup_tasklet: select between the v2 and v3 cleanup routines
+ * @cleanup_fn: select between the v2 and v3 cleanup routines
  * @timer_fn: select between the v2 and v3 timer watchdog routines
  * @self_test: hardware version specific self test for each supported op type
  *
@@ -80,7 +80,7 @@ struct ioatdma_device {
 	void (*intr_quirk)(struct ioatdma_device *device);
 	int (*enumerate_channels)(struct ioatdma_device *device);
 	int (*reset_hw)(struct ioat_chan_common *chan);
-	void (*cleanup_tasklet)(unsigned long data);
+	void (*cleanup_fn)(unsigned long data);
 	void (*timer_fn)(unsigned long data);
 	int (*self_test)(struct ioatdma_device *device);
 };
@@ -337,17 +337,16 @@ struct dca_provider * __devinit ioat_dca
 					      void __iomem *iobase);
 unsigned long ioat_get_current_completion(struct ioat_chan_common *chan);
 void ioat_init_channel(struct ioatdma_device *device,
-		       struct ioat_chan_common *chan, int idx,
-		       void (*timer_fn)(unsigned long),
-		       void (*tasklet)(unsigned long),
-		       unsigned long ioat);
+		       struct ioat_chan_common *chan, int idx);
+enum dma_status ioat_is_dma_complete(struct dma_chan *c, dma_cookie_t cookie,
+				     dma_cookie_t *done, dma_cookie_t *used);
 void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags,
 		    size_t len, struct ioat_dma_descriptor *hw);
 bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
 			   unsigned long *phys_complete);
 void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type);
 void ioat_kobject_del(struct ioatdma_device *device);
-extern struct sysfs_ops ioat_sysfs_ops;
+extern const struct sysfs_ops ioat_sysfs_ops;
 extern struct ioat_sysfs_entry ioat_version_attr;
 extern struct ioat_sysfs_entry ioat_cap_attr;
 #endif /* IOATDMA_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma_v2.c linux-libre-2.6.34-gnu1/drivers/dma/ioat/dma_v2.c
--- linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma_v2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/ioat/dma_v2.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/dmaengine.h>
@@ -51,48 +52,40 @@ MODULE_PARM_DESC(ioat_ring_max_alloc_ord
 
 void __ioat2_issue_pending(struct ioat2_dma_chan *ioat)
 {
-	void * __iomem reg_base = ioat->base.reg_base;
+	struct ioat_chan_common *chan = &ioat->base;
 
-	ioat->pending = 0;
 	ioat->dmacount += ioat2_ring_pending(ioat);
 	ioat->issued = ioat->head;
 	/* make descriptor updates globally visible before notifying channel */
 	wmb();
-	writew(ioat->dmacount, reg_base + IOAT_CHAN_DMACOUNT_OFFSET);
-	dev_dbg(to_dev(&ioat->base),
+	writew(ioat->dmacount, chan->reg_base + IOAT_CHAN_DMACOUNT_OFFSET);
+	dev_dbg(to_dev(chan),
 		"%s: head: %#x tail: %#x issued: %#x count: %#x\n",
 		__func__, ioat->head, ioat->tail, ioat->issued, ioat->dmacount);
 }
 
-void ioat2_issue_pending(struct dma_chan *chan)
+void ioat2_issue_pending(struct dma_chan *c)
 {
-	struct ioat2_dma_chan *ioat = to_ioat2_chan(chan);
+	struct ioat2_dma_chan *ioat = to_ioat2_chan(c);
 
-	spin_lock_bh(&ioat->ring_lock);
-	if (ioat->pending == 1)
+	if (ioat2_ring_pending(ioat)) {
+		spin_lock_bh(&ioat->ring_lock);
 		__ioat2_issue_pending(ioat);
-	spin_unlock_bh(&ioat->ring_lock);
+		spin_unlock_bh(&ioat->ring_lock);
+	}
 }
 
 /**
  * ioat2_update_pending - log pending descriptors
  * @ioat: ioat2+ channel
  *
- * set pending to '1' unless pending is already set to '2', pending == 2
- * indicates that submission is temporarily blocked due to an in-flight
- * reset.  If we are already above the ioat_pending_level threshold then
- * just issue pending.
- *
- * called with ring_lock held
+ * Check if the number of unsubmitted descriptors has exceeded the
+ * watermark.  Called with ring_lock held
  */
 static void ioat2_update_pending(struct ioat2_dma_chan *ioat)
 {
-	if (unlikely(ioat->pending == 2))
-		return;
-	else if (ioat2_ring_pending(ioat) > ioat_pending_level)
+	if (ioat2_ring_pending(ioat) > ioat_pending_level)
 		__ioat2_issue_pending(ioat);
-	else
-		ioat->pending = 1;
 }
 
 static void __ioat2_start_null_desc(struct ioat2_dma_chan *ioat)
@@ -166,7 +159,7 @@ static void __cleanup(struct ioat2_dma_c
 			seen_current = true;
 	}
 	ioat->tail += i;
-	BUG_ON(!seen_current); /* no active descs have written a completion? */
+	BUG_ON(active && !seen_current); /* no active descs have written a completion? */
 
 	chan->last_completion = phys_complete;
 	if (ioat->head == ioat->tail) {
@@ -207,9 +200,9 @@ static void ioat2_cleanup(struct ioat2_d
 	spin_unlock_bh(&chan->cleanup_lock);
 }
 
-void ioat2_cleanup_tasklet(unsigned long data)
+void ioat2_cleanup_event(unsigned long data)
 {
-	struct ioat2_dma_chan *ioat = (void *) data;
+	struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data);
 
 	ioat2_cleanup(ioat);
 	writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET);
@@ -291,7 +284,7 @@ static void ioat2_restart_channel(struct
 
 void ioat2_timer_event(unsigned long data)
 {
-	struct ioat2_dma_chan *ioat = (void *) data;
+	struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data);
 	struct ioat_chan_common *chan = &ioat->base;
 
 	spin_lock_bh(&chan->cleanup_lock);
@@ -397,10 +390,7 @@ int ioat2_enumerate_channels(struct ioat
 		if (!ioat)
 			break;
 
-		ioat_init_channel(device, &ioat->base, i,
-				  device->timer_fn,
-				  device->cleanup_tasklet,
-				  (unsigned long) ioat);
+		ioat_init_channel(device, &ioat->base, i);
 		ioat->xfercap_log = xfercap_log;
 		spin_lock_init(&ioat->ring_lock);
 		if (device->reset_hw(&ioat->base)) {
@@ -546,7 +536,6 @@ int ioat2_alloc_chan_resources(struct dm
 	ioat->head = 0;
 	ioat->issued = 0;
 	ioat->tail = 0;
-	ioat->pending = 0;
 	ioat->alloc_order = order;
 	spin_unlock_bh(&ioat->ring_lock);
 
@@ -701,7 +690,7 @@ int ioat2_alloc_and_lock(u16 *idx, struc
 
 			mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT);
 			spin_unlock_bh(&chan->cleanup_lock);
-			device->timer_fn((unsigned long) ioat);
+			device->timer_fn((unsigned long) &chan->common);
 		} else
 			spin_unlock_bh(&chan->cleanup_lock);
 		return -ENOMEM;
@@ -785,7 +774,7 @@ void ioat2_free_chan_resources(struct dm
 
 	tasklet_disable(&chan->cleanup_task);
 	del_timer_sync(&chan->timer);
-	device->cleanup_tasklet((unsigned long) ioat);
+	device->cleanup_fn((unsigned long) c);
 	device->reset_hw(chan);
 
 	spin_lock_bh(&ioat->ring_lock);
@@ -815,25 +804,9 @@ void ioat2_free_chan_resources(struct dm
 
 	chan->last_completion = 0;
 	chan->completion_dma = 0;
-	ioat->pending = 0;
 	ioat->dmacount = 0;
 }
 
-enum dma_status
-ioat2_is_complete(struct dma_chan *c, dma_cookie_t cookie,
-		     dma_cookie_t *done, dma_cookie_t *used)
-{
-	struct ioat2_dma_chan *ioat = to_ioat2_chan(c);
-	struct ioatdma_device *device = ioat->base.device;
-
-	if (ioat_is_complete(c, cookie, done, used) == DMA_SUCCESS)
-		return DMA_SUCCESS;
-
-	device->cleanup_tasklet((unsigned long) ioat);
-
-	return ioat_is_complete(c, cookie, done, used);
-}
-
 static ssize_t ring_size_show(struct dma_chan *c, char *page)
 {
 	struct ioat2_dma_chan *ioat = to_ioat2_chan(c);
@@ -874,7 +847,7 @@ int __devinit ioat2_dma_probe(struct ioa
 
 	device->enumerate_channels = ioat2_enumerate_channels;
 	device->reset_hw = ioat2_reset_hw;
-	device->cleanup_tasklet = ioat2_cleanup_tasklet;
+	device->cleanup_fn = ioat2_cleanup_event;
 	device->timer_fn = ioat2_timer_event;
 	device->self_test = ioat_dma_self_test;
 	dma = &device->common;
@@ -882,7 +855,7 @@ int __devinit ioat2_dma_probe(struct ioa
 	dma->device_issue_pending = ioat2_issue_pending;
 	dma->device_alloc_chan_resources = ioat2_alloc_chan_resources;
 	dma->device_free_chan_resources = ioat2_free_chan_resources;
-	dma->device_is_tx_complete = ioat2_is_complete;
+	dma->device_is_tx_complete = ioat_is_dma_complete;
 
 	err = ioat_probe(device);
 	if (err)
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma_v2.h linux-libre-2.6.34-gnu1/drivers/dma/ioat/dma_v2.h
--- linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma_v2.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/ioat/dma_v2.h	2010-05-16 17:17:36.000000000 -0400
@@ -47,7 +47,6 @@ extern int ioat_ring_alloc_order;
  * @head: allocated index
  * @issued: hardware notification point
  * @tail: cleanup index
- * @pending: lock free indicator for issued != head
  * @dmacount: identical to 'head' except for occasionally resetting to zero
  * @alloc_order: log2 of the number of allocated descriptors
  * @ring: software ring buffer implementation of hardware ring
@@ -61,7 +60,6 @@ struct ioat2_dma_chan {
 	u16 tail;
 	u16 dmacount;
 	u16 alloc_order;
-	int pending;
 	struct ioat_ring_ent **ring;
 	spinlock_t ring_lock;
 };
@@ -178,12 +176,10 @@ ioat2_dma_prep_memcpy_lock(struct dma_ch
 void ioat2_issue_pending(struct dma_chan *chan);
 int ioat2_alloc_chan_resources(struct dma_chan *c);
 void ioat2_free_chan_resources(struct dma_chan *c);
-enum dma_status ioat2_is_complete(struct dma_chan *c, dma_cookie_t cookie,
-				  dma_cookie_t *done, dma_cookie_t *used);
 void __ioat2_restart_chan(struct ioat2_dma_chan *ioat);
 bool reshape_ring(struct ioat2_dma_chan *ioat, int order);
 void __ioat2_issue_pending(struct ioat2_dma_chan *ioat);
-void ioat2_cleanup_tasklet(unsigned long data);
+void ioat2_cleanup_event(unsigned long data);
 void ioat2_timer_event(unsigned long data);
 int ioat2_quiesce(struct ioat_chan_common *chan, unsigned long tmo);
 int ioat2_reset_sync(struct ioat_chan_common *chan, unsigned long tmo);
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma_v3.c linux-libre-2.6.34-gnu1/drivers/dma/ioat/dma_v3.c
--- linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma_v3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/ioat/dma_v3.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,6 +57,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include "registers.h"
@@ -293,17 +294,25 @@ static void __cleanup(struct ioat2_dma_c
 		}
 	}
 	ioat->tail += i;
-	BUG_ON(!seen_current); /* no active descs have written a completion? */
+	BUG_ON(active && !seen_current); /* no active descs have written a completion? */
 	chan->last_completion = phys_complete;
-	if (ioat->head == ioat->tail) {
+
+	active = ioat2_ring_active(ioat);
+	if (active == 0) {
 		dev_dbg(to_dev(chan), "%s: cancel completion timeout\n",
 			__func__);
 		clear_bit(IOAT_COMPLETION_PENDING, &chan->state);
 		mod_timer(&chan->timer, jiffies + IDLE_TIMEOUT);
 	}
+	/* 5 microsecond delay per pending descriptor */
+	writew(min((5 * active), IOAT_INTRDELAY_MASK),
+	       chan->device->reg_base + IOAT_INTRDELAY_OFFSET);
 }
 
-static void ioat3_cleanup(struct ioat2_dma_chan *ioat)
+/* try to cleanup, but yield (via spin_trylock) to incoming submissions
+ * with the expectation that we will immediately poll again shortly
+ */
+static void ioat3_cleanup_poll(struct ioat2_dma_chan *ioat)
 {
 	struct ioat_chan_common *chan = &ioat->base;
 	unsigned long phys_complete;
@@ -329,29 +338,41 @@ static void ioat3_cleanup(struct ioat2_d
 	spin_unlock_bh(&chan->cleanup_lock);
 }
 
-static void ioat3_cleanup_tasklet(unsigned long data)
+/* run cleanup now because we already delayed the interrupt via INTRDELAY */
+static void ioat3_cleanup_sync(struct ioat2_dma_chan *ioat)
 {
-	struct ioat2_dma_chan *ioat = (void *) data;
+	struct ioat_chan_common *chan = &ioat->base;
+	unsigned long phys_complete;
 
-	ioat3_cleanup(ioat);
-	writew(IOAT_CHANCTRL_RUN | IOAT3_CHANCTRL_COMPL_DCA_EN,
-	       ioat->base.reg_base + IOAT_CHANCTRL_OFFSET);
+	prefetch(chan->completion);
+
+	spin_lock_bh(&chan->cleanup_lock);
+	if (!ioat_cleanup_preamble(chan, &phys_complete)) {
+		spin_unlock_bh(&chan->cleanup_lock);
+		return;
+	}
+	spin_lock_bh(&ioat->ring_lock);
+
+	__cleanup(ioat, phys_complete);
+
+	spin_unlock_bh(&ioat->ring_lock);
+	spin_unlock_bh(&chan->cleanup_lock);
+}
+
+static void ioat3_cleanup_event(unsigned long data)
+{
+	struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data);
+
+	ioat3_cleanup_sync(ioat);
+	writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET);
 }
 
 static void ioat3_restart_channel(struct ioat2_dma_chan *ioat)
 {
 	struct ioat_chan_common *chan = &ioat->base;
 	unsigned long phys_complete;
-	u32 status;
-
-	status = ioat_chansts(chan);
-	if (is_ioat_active(status) || is_ioat_idle(status))
-		ioat_suspend(chan);
-	while (is_ioat_active(status) || is_ioat_idle(status)) {
-		status = ioat_chansts(chan);
-		cpu_relax();
-	}
 
+	ioat2_quiesce(chan, 0);
 	if (ioat_cleanup_preamble(chan, &phys_complete))
 		__cleanup(ioat, phys_complete);
 
@@ -360,7 +381,7 @@ static void ioat3_restart_channel(struct
 
 static void ioat3_timer_event(unsigned long data)
 {
-	struct ioat2_dma_chan *ioat = (void *) data;
+	struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data);
 	struct ioat_chan_common *chan = &ioat->base;
 
 	spin_lock_bh(&chan->cleanup_lock);
@@ -426,7 +447,7 @@ ioat3_is_complete(struct dma_chan *c, dm
 	if (ioat_is_complete(c, cookie, done, used) == DMA_SUCCESS)
 		return DMA_SUCCESS;
 
-	ioat3_cleanup(ioat);
+	ioat3_cleanup_poll(ioat);
 
 	return ioat_is_complete(c, cookie, done, used);
 }
@@ -1239,11 +1260,11 @@ int __devinit ioat3_dma_probe(struct ioa
 
 	if (is_raid_device) {
 		dma->device_is_tx_complete = ioat3_is_complete;
-		device->cleanup_tasklet = ioat3_cleanup_tasklet;
+		device->cleanup_fn = ioat3_cleanup_event;
 		device->timer_fn = ioat3_timer_event;
 	} else {
-		dma->device_is_tx_complete = ioat2_is_complete;
-		device->cleanup_tasklet = ioat2_cleanup_tasklet;
+		dma->device_is_tx_complete = ioat_is_dma_complete;
+		device->cleanup_fn = ioat2_cleanup_event;
 		device->timer_fn = ioat2_timer_event;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/ioat/pci.c linux-libre-2.6.34-gnu1/drivers/dma/ioat/pci.c
--- linux-libre-2.6.33-gnu1/drivers/dma/ioat/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/ioat/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/dca.h>
+#include <linux/slab.h>
 #include "dma.h"
 #include "dma_v2.h"
 #include "registers.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/ioat/registers.h linux-libre-2.6.34-gnu1/drivers/dma/ioat/registers.h
--- linux-libre-2.6.33-gnu1/drivers/dma/ioat/registers.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/ioat/registers.h	2010-05-16 17:17:36.000000000 -0400
@@ -60,7 +60,7 @@
 #define IOAT_PERPORTOFFSET_OFFSET		0x0A	/* 16-bit */
 
 #define IOAT_INTRDELAY_OFFSET			0x0C	/* 16-bit */
-#define IOAT_INTRDELAY_INT_DELAY_MASK		0x3FFF	/* Interrupt Delay Time */
+#define IOAT_INTRDELAY_MASK			0x3FFF	/* Interrupt Delay Time */
 #define IOAT_INTRDELAY_COALESE_SUPPORT		0x8000	/* Interrupt Coalescing Supported */
 
 #define IOAT_DEVICE_STATUS_OFFSET		0x0E	/* 16-bit */
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/iop-adma.c linux-libre-2.6.34-gnu1/drivers/dma/iop-adma.c
--- linux-libre-2.6.33-gnu1/drivers/dma/iop-adma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/iop-adma.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/memory.h>
 #include <linux/ioport.h>
 #include <linux/raid/pq.h>
+#include <linux/slab.h>
 
 #include <mach/adma.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/iovlock.c linux-libre-2.6.34-gnu1/drivers/dma/iovlock.c
--- linux-libre-2.6.33-gnu1/drivers/dma/iovlock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/iovlock.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 
 #include <linux/dmaengine.h>
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 #include <net/tcp.h> /* for memcpy_toiovec */
 #include <asm/io.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/ipu/ipu_idmac.c linux-libre-2.6.34-gnu1/drivers/dma/ipu/ipu_idmac.c
--- linux-libre-2.6.33-gnu1/drivers/dma/ipu/ipu_idmac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/ipu/ipu_idmac.c	2010-05-16 17:17:36.000000000 -0400
@@ -348,6 +348,7 @@ static void ipu_ch_param_set_size(union
 		break;
 	case IPU_PIX_FMT_BGRA32:
 	case IPU_PIX_FMT_BGR32:
+	case IPU_PIX_FMT_ABGR32:
 		params->ip.bpp	= 0;
 		params->ip.pfs	= 4;
 		params->ip.npb	= 7;
@@ -373,20 +374,6 @@ static void ipu_ch_param_set_size(union
 		params->ip.ofs3	= 0;		/* Alpha bit offset */
 		params->ip.wid0	= 7;		/* Red bit width - 1 */
 		params->ip.wid1	= 7;		/* Green bit width - 1 */
-		params->ip.wid2	= 7;		/* Blue bit width - 1 */
-		params->ip.wid3	= 7;		/* Alpha bit width - 1 */
-		break;
-	case IPU_PIX_FMT_ABGR32:
-		params->ip.bpp	= 0;
-		params->ip.pfs	= 4;
-		params->ip.npb	= 7;
-		params->ip.sat	= 2;		/* SAT = 32-bit access */
-		params->ip.ofs0	= 8;		/* Red bit offset */
-		params->ip.ofs1	= 16;		/* Green bit offset */
-		params->ip.ofs2	= 24;		/* Blue bit offset */
-		params->ip.ofs3	= 0;		/* Alpha bit offset */
-		params->ip.wid0	= 7;		/* Red bit width - 1 */
-		params->ip.wid1	= 7;		/* Green bit width - 1 */
 		params->ip.wid2	= 7;		/* Blue bit width - 1 */
 		params->ip.wid3	= 7;		/* Alpha bit width - 1 */
 		break;
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/Kconfig linux-libre-2.6.34-gnu1/drivers/dma/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/dma/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,22 @@ menuconfig DMADEVICES
 	  DMA Device drivers supported by the configured arch, it may
 	  be empty in some cases.
 
+config DMADEVICES_DEBUG
+        bool "DMA Engine debugging"
+        depends on DMADEVICES != n
+        help
+          This is an option for use by developers; most people should
+          say N here.  This enables DMA engine core and driver debugging.
+
+config DMADEVICES_VDEBUG
+        bool "DMA Engine verbose debugging"
+        depends on DMADEVICES_DEBUG != n
+        help
+          This is an option for use by developers; most people should
+          say N here.  This enables deeper (more verbose) debugging of
+          the DMA engine core and drivers.
+
+
 if DMADEVICES
 
 comment "DMA Devices"
@@ -69,6 +85,13 @@ config FSL_DMA
 	  The Elo is the DMA controller on some 82xx and 83xx parts, and the
 	  Elo Plus is the DMA controller on 85xx and 86xx parts.
 
+config MPC512X_DMA
+	tristate "Freescale MPC512x built-in DMA engine support"
+	depends on PPC_MPC512x
+	select DMA_ENGINE
+	---help---
+	  Enable support for the Freescale MPC512x built-in DMA engine.
+
 config MV_XOR
 	bool "Marvell XOR engine support"
 	depends on PLAT_ORION
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/Makefile linux-libre-2.6.34-gnu1/drivers/dma/Makefile
--- linux-libre-2.6.33-gnu1/drivers/dma/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,9 +1,17 @@
+ifeq ($(CONFIG_DMADEVICES_DEBUG),y)
+	EXTRA_CFLAGS	+= -DDEBUG
+endif
+ifeq ($(CONFIG_DMADEVICES_VDEBUG),y)
+	EXTRA_CFLAGS	+= -DVERBOSE_DEBUG
+endif
+
 obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
 obj-$(CONFIG_NET_DMA) += iovlock.o
 obj-$(CONFIG_DMATEST) += dmatest.o
 obj-$(CONFIG_INTEL_IOATDMA) += ioat/
 obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
 obj-$(CONFIG_FSL_DMA) += fsldma.o
+obj-$(CONFIG_MPC512X_DMA) += mpc512x_dma.o
 obj-$(CONFIG_MV_XOR) += mv_xor.o
 obj-$(CONFIG_DW_DMAC) += dw_dmac.o
 obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/mpc512x_dma.c linux-libre-2.6.34-gnu1/drivers/dma/mpc512x_dma.c
--- linux-libre-2.6.33-gnu1/drivers/dma/mpc512x_dma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/mpc512x_dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,801 @@
+/*
+ * Copyright (C) Freescale Semicondutor, Inc. 2007, 2008.
+ * Copyright (C) Semihalf 2009
+ *
+ * Written by Piotr Ziecik <kosmo@semihalf.com>. Hardware description
+ * (defines, structures and comments) was taken from MPC5121 DMA driver
+ * written by Hongjun Chen <hong-jun.chen@freescale.com>.
+ *
+ * Approved as OSADL project by a majority of OSADL members and funded
+ * by OSADL membership fees in 2009;  for details see www.osadl.org.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+
+/*
+ * This is initial version of MPC5121 DMA driver. Only memory to memory
+ * transfers are supported (tested using dmatest module).
+ */
+
+#include <linux/module.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+
+#include <linux/random.h>
+
+/* Number of DMA Transfer descriptors allocated per channel */
+#define MPC_DMA_DESCRIPTORS	64
+
+/* Macro definitions */
+#define MPC_DMA_CHANNELS	64
+#define MPC_DMA_TCD_OFFSET	0x1000
+
+/* Arbitration mode of group and channel */
+#define MPC_DMA_DMACR_EDCG	(1 << 31)
+#define MPC_DMA_DMACR_ERGA	(1 << 3)
+#define MPC_DMA_DMACR_ERCA	(1 << 2)
+
+/* Error codes */
+#define MPC_DMA_DMAES_VLD	(1 << 31)
+#define MPC_DMA_DMAES_GPE	(1 << 15)
+#define MPC_DMA_DMAES_CPE	(1 << 14)
+#define MPC_DMA_DMAES_ERRCHN(err) \
+				(((err) >> 8) & 0x3f)
+#define MPC_DMA_DMAES_SAE	(1 << 7)
+#define MPC_DMA_DMAES_SOE	(1 << 6)
+#define MPC_DMA_DMAES_DAE	(1 << 5)
+#define MPC_DMA_DMAES_DOE	(1 << 4)
+#define MPC_DMA_DMAES_NCE	(1 << 3)
+#define MPC_DMA_DMAES_SGE	(1 << 2)
+#define MPC_DMA_DMAES_SBE	(1 << 1)
+#define MPC_DMA_DMAES_DBE	(1 << 0)
+
+#define MPC_DMA_TSIZE_1		0x00
+#define MPC_DMA_TSIZE_2		0x01
+#define MPC_DMA_TSIZE_4		0x02
+#define MPC_DMA_TSIZE_16	0x04
+#define MPC_DMA_TSIZE_32	0x05
+
+/* MPC5121 DMA engine registers */
+struct __attribute__ ((__packed__)) mpc_dma_regs {
+	/* 0x00 */
+	u32 dmacr;		/* DMA control register */
+	u32 dmaes;		/* DMA error status */
+	/* 0x08 */
+	u32 dmaerqh;		/* DMA enable request high(channels 63~32) */
+	u32 dmaerql;		/* DMA enable request low(channels 31~0) */
+	u32 dmaeeih;		/* DMA enable error interrupt high(ch63~32) */
+	u32 dmaeeil;		/* DMA enable error interrupt low(ch31~0) */
+	/* 0x18 */
+	u8 dmaserq;		/* DMA set enable request */
+	u8 dmacerq;		/* DMA clear enable request */
+	u8 dmaseei;		/* DMA set enable error interrupt */
+	u8 dmaceei;		/* DMA clear enable error interrupt */
+	/* 0x1c */
+	u8 dmacint;		/* DMA clear interrupt request */
+	u8 dmacerr;		/* DMA clear error */
+	u8 dmassrt;		/* DMA set start bit */
+	u8 dmacdne;		/* DMA clear DONE status bit */
+	/* 0x20 */
+	u32 dmainth;		/* DMA interrupt request high(ch63~32) */
+	u32 dmaintl;		/* DMA interrupt request low(ch31~0) */
+	u32 dmaerrh;		/* DMA error high(ch63~32) */
+	u32 dmaerrl;		/* DMA error low(ch31~0) */
+	/* 0x30 */
+	u32 dmahrsh;		/* DMA hw request status high(ch63~32) */
+	u32 dmahrsl;		/* DMA hardware request status low(ch31~0) */
+	u32 dmaihsa;		/* DMA interrupt high select AXE(ch63~32) */
+	u32 dmailsa;		/* DMA interrupt low select AXE(ch31~0) */
+	/* 0x40 ~ 0xff */
+	u32 reserve0[48];	/* Reserved */
+	/* 0x100 */
+	u8 dchpri[MPC_DMA_CHANNELS];
+	/* DMA channels(0~63) priority */
+};
+
+struct __attribute__ ((__packed__)) mpc_dma_tcd {
+	/* 0x00 */
+	u32 saddr;		/* Source address */
+
+	u32 smod:5;		/* Source address modulo */
+	u32 ssize:3;		/* Source data transfer size */
+	u32 dmod:5;		/* Destination address modulo */
+	u32 dsize:3;		/* Destination data transfer size */
+	u32 soff:16;		/* Signed source address offset */
+
+	/* 0x08 */
+	u32 nbytes;		/* Inner "minor" byte count */
+	u32 slast;		/* Last source address adjustment */
+	u32 daddr;		/* Destination address */
+
+	/* 0x14 */
+	u32 citer_elink:1;	/* Enable channel-to-channel linking on
+				 * minor loop complete
+				 */
+	u32 citer_linkch:6;	/* Link channel for minor loop complete */
+	u32 citer:9;		/* Current "major" iteration count */
+	u32 doff:16;		/* Signed destination address offset */
+
+	/* 0x18 */
+	u32 dlast_sga;		/* Last Destination address adjustment/scatter
+				 * gather address
+				 */
+
+	/* 0x1c */
+	u32 biter_elink:1;	/* Enable channel-to-channel linking on major
+				 * loop complete
+				 */
+	u32 biter_linkch:6;
+	u32 biter:9;		/* Beginning "major" iteration count */
+	u32 bwc:2;		/* Bandwidth control */
+	u32 major_linkch:6;	/* Link channel number */
+	u32 done:1;		/* Channel done */
+	u32 active:1;		/* Channel active */
+	u32 major_elink:1;	/* Enable channel-to-channel linking on major
+				 * loop complete
+				 */
+	u32 e_sg:1;		/* Enable scatter/gather processing */
+	u32 d_req:1;		/* Disable request */
+	u32 int_half:1;		/* Enable an interrupt when major counter is
+				 * half complete
+				 */
+	u32 int_maj:1;		/* Enable an interrupt when major iteration
+				 * count completes
+				 */
+	u32 start:1;		/* Channel start */
+};
+
+struct mpc_dma_desc {
+	struct dma_async_tx_descriptor	desc;
+	struct mpc_dma_tcd		*tcd;
+	dma_addr_t			tcd_paddr;
+	int				error;
+	struct list_head		node;
+};
+
+struct mpc_dma_chan {
+	struct dma_chan			chan;
+	struct list_head		free;
+	struct list_head		prepared;
+	struct list_head		queued;
+	struct list_head		active;
+	struct list_head		completed;
+	struct mpc_dma_tcd		*tcd;
+	dma_addr_t			tcd_paddr;
+	dma_cookie_t			completed_cookie;
+
+	/* Lock for this structure */
+	spinlock_t			lock;
+};
+
+struct mpc_dma {
+	struct dma_device		dma;
+	struct tasklet_struct		tasklet;
+	struct mpc_dma_chan		channels[MPC_DMA_CHANNELS];
+	struct mpc_dma_regs __iomem	*regs;
+	struct mpc_dma_tcd __iomem	*tcd;
+	int				irq;
+	uint				error_status;
+
+	/* Lock for error_status field in this structure */
+	spinlock_t			error_status_lock;
+};
+
+#define DRV_NAME	"mpc512x_dma"
+
+/* Convert struct dma_chan to struct mpc_dma_chan */
+static inline struct mpc_dma_chan *dma_chan_to_mpc_dma_chan(struct dma_chan *c)
+{
+	return container_of(c, struct mpc_dma_chan, chan);
+}
+
+/* Convert struct dma_chan to struct mpc_dma */
+static inline struct mpc_dma *dma_chan_to_mpc_dma(struct dma_chan *c)
+{
+	struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(c);
+	return container_of(mchan, struct mpc_dma, channels[c->chan_id]);
+}
+
+/*
+ * Execute all queued DMA descriptors.
+ *
+ * Following requirements must be met while calling mpc_dma_execute():
+ * 	a) mchan->lock is acquired,
+ * 	b) mchan->active list is empty,
+ * 	c) mchan->queued list contains at least one entry.
+ */
+static void mpc_dma_execute(struct mpc_dma_chan *mchan)
+{
+	struct mpc_dma *mdma = dma_chan_to_mpc_dma(&mchan->chan);
+	struct mpc_dma_desc *first = NULL;
+	struct mpc_dma_desc *prev = NULL;
+	struct mpc_dma_desc *mdesc;
+	int cid = mchan->chan.chan_id;
+
+	/* Move all queued descriptors to active list */
+	list_splice_tail_init(&mchan->queued, &mchan->active);
+
+	/* Chain descriptors into one transaction */
+	list_for_each_entry(mdesc, &mchan->active, node) {
+		if (!first)
+			first = mdesc;
+
+		if (!prev) {
+			prev = mdesc;
+			continue;
+		}
+
+		prev->tcd->dlast_sga = mdesc->tcd_paddr;
+		prev->tcd->e_sg = 1;
+		mdesc->tcd->start = 1;
+
+		prev = mdesc;
+	}
+
+	prev->tcd->start = 0;
+	prev->tcd->int_maj = 1;
+
+	/* Send first descriptor in chain into hardware */
+	memcpy_toio(&mdma->tcd[cid], first->tcd, sizeof(struct mpc_dma_tcd));
+	out_8(&mdma->regs->dmassrt, cid);
+}
+
+/* Handle interrupt on one half of DMA controller (32 channels) */
+static void mpc_dma_irq_process(struct mpc_dma *mdma, u32 is, u32 es, int off)
+{
+	struct mpc_dma_chan *mchan;
+	struct mpc_dma_desc *mdesc;
+	u32 status = is | es;
+	int ch;
+
+	while ((ch = fls(status) - 1) >= 0) {
+		status &= ~(1 << ch);
+		mchan = &mdma->channels[ch + off];
+
+		spin_lock(&mchan->lock);
+
+		/* Check error status */
+		if (es & (1 << ch))
+			list_for_each_entry(mdesc, &mchan->active, node)
+				mdesc->error = -EIO;
+
+		/* Execute queued descriptors */
+		list_splice_tail_init(&mchan->active, &mchan->completed);
+		if (!list_empty(&mchan->queued))
+			mpc_dma_execute(mchan);
+
+		spin_unlock(&mchan->lock);
+	}
+}
+
+/* Interrupt handler */
+static irqreturn_t mpc_dma_irq(int irq, void *data)
+{
+	struct mpc_dma *mdma = data;
+	uint es;
+
+	/* Save error status register */
+	es = in_be32(&mdma->regs->dmaes);
+	spin_lock(&mdma->error_status_lock);
+	if ((es & MPC_DMA_DMAES_VLD) && mdma->error_status == 0)
+		mdma->error_status = es;
+	spin_unlock(&mdma->error_status_lock);
+
+	/* Handle interrupt on each channel */
+	mpc_dma_irq_process(mdma, in_be32(&mdma->regs->dmainth),
+					in_be32(&mdma->regs->dmaerrh), 32);
+	mpc_dma_irq_process(mdma, in_be32(&mdma->regs->dmaintl),
+					in_be32(&mdma->regs->dmaerrl), 0);
+
+	/* Ack interrupt on all channels */
+	out_be32(&mdma->regs->dmainth, 0xFFFFFFFF);
+	out_be32(&mdma->regs->dmaintl, 0xFFFFFFFF);
+	out_be32(&mdma->regs->dmaerrh, 0xFFFFFFFF);
+	out_be32(&mdma->regs->dmaerrl, 0xFFFFFFFF);
+
+	/* Schedule tasklet */
+	tasklet_schedule(&mdma->tasklet);
+
+	return IRQ_HANDLED;
+}
+
+/* DMA Tasklet */
+static void mpc_dma_tasklet(unsigned long data)
+{
+	struct mpc_dma *mdma = (void *)data;
+	dma_cookie_t last_cookie = 0;
+	struct mpc_dma_chan *mchan;
+	struct mpc_dma_desc *mdesc;
+	struct dma_async_tx_descriptor *desc;
+	unsigned long flags;
+	LIST_HEAD(list);
+	uint es;
+	int i;
+
+	spin_lock_irqsave(&mdma->error_status_lock, flags);
+	es = mdma->error_status;
+	mdma->error_status = 0;
+	spin_unlock_irqrestore(&mdma->error_status_lock, flags);
+
+	/* Print nice error report */
+	if (es) {
+		dev_err(mdma->dma.dev,
+			"Hardware reported following error(s) on channel %u:\n",
+						      MPC_DMA_DMAES_ERRCHN(es));
+
+		if (es & MPC_DMA_DMAES_GPE)
+			dev_err(mdma->dma.dev, "- Group Priority Error\n");
+		if (es & MPC_DMA_DMAES_CPE)
+			dev_err(mdma->dma.dev, "- Channel Priority Error\n");
+		if (es & MPC_DMA_DMAES_SAE)
+			dev_err(mdma->dma.dev, "- Source Address Error\n");
+		if (es & MPC_DMA_DMAES_SOE)
+			dev_err(mdma->dma.dev, "- Source Offset"
+						" Configuration Error\n");
+		if (es & MPC_DMA_DMAES_DAE)
+			dev_err(mdma->dma.dev, "- Destination Address"
+								" Error\n");
+		if (es & MPC_DMA_DMAES_DOE)
+			dev_err(mdma->dma.dev, "- Destination Offset"
+						" Configuration Error\n");
+		if (es & MPC_DMA_DMAES_NCE)
+			dev_err(mdma->dma.dev, "- NBytes/Citter"
+						" Configuration Error\n");
+		if (es & MPC_DMA_DMAES_SGE)
+			dev_err(mdma->dma.dev, "- Scatter/Gather"
+						" Configuration Error\n");
+		if (es & MPC_DMA_DMAES_SBE)
+			dev_err(mdma->dma.dev, "- Source Bus Error\n");
+		if (es & MPC_DMA_DMAES_DBE)
+			dev_err(mdma->dma.dev, "- Destination Bus Error\n");
+	}
+
+	for (i = 0; i < mdma->dma.chancnt; i++) {
+		mchan = &mdma->channels[i];
+
+		/* Get all completed descriptors */
+		spin_lock_irqsave(&mchan->lock, flags);
+		if (!list_empty(&mchan->completed))
+			list_splice_tail_init(&mchan->completed, &list);
+		spin_unlock_irqrestore(&mchan->lock, flags);
+
+		if (list_empty(&list))
+			continue;
+
+		/* Execute callbacks and run dependencies */
+		list_for_each_entry(mdesc, &list, node) {
+			desc = &mdesc->desc;
+
+			if (desc->callback)
+				desc->callback(desc->callback_param);
+
+			last_cookie = desc->cookie;
+			dma_run_dependencies(desc);
+		}
+
+		/* Free descriptors */
+		spin_lock_irqsave(&mchan->lock, flags);
+		list_splice_tail_init(&list, &mchan->free);
+		mchan->completed_cookie = last_cookie;
+		spin_unlock_irqrestore(&mchan->lock, flags);
+	}
+}
+
+/* Submit descriptor to hardware */
+static dma_cookie_t mpc_dma_tx_submit(struct dma_async_tx_descriptor *txd)
+{
+	struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(txd->chan);
+	struct mpc_dma_desc *mdesc;
+	unsigned long flags;
+	dma_cookie_t cookie;
+
+	mdesc = container_of(txd, struct mpc_dma_desc, desc);
+
+	spin_lock_irqsave(&mchan->lock, flags);
+
+	/* Move descriptor to queue */
+	list_move_tail(&mdesc->node, &mchan->queued);
+
+	/* If channel is idle, execute all queued descriptors */
+	if (list_empty(&mchan->active))
+		mpc_dma_execute(mchan);
+
+	/* Update cookie */
+	cookie = mchan->chan.cookie + 1;
+	if (cookie <= 0)
+		cookie = 1;
+
+	mchan->chan.cookie = cookie;
+	mdesc->desc.cookie = cookie;
+
+	spin_unlock_irqrestore(&mchan->lock, flags);
+
+	return cookie;
+}
+
+/* Alloc channel resources */
+static int mpc_dma_alloc_chan_resources(struct dma_chan *chan)
+{
+	struct mpc_dma *mdma = dma_chan_to_mpc_dma(chan);
+	struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan);
+	struct mpc_dma_desc *mdesc;
+	struct mpc_dma_tcd *tcd;
+	dma_addr_t tcd_paddr;
+	unsigned long flags;
+	LIST_HEAD(descs);
+	int i;
+
+	/* Alloc DMA memory for Transfer Control Descriptors */
+	tcd = dma_alloc_coherent(mdma->dma.dev,
+			MPC_DMA_DESCRIPTORS * sizeof(struct mpc_dma_tcd),
+							&tcd_paddr, GFP_KERNEL);
+	if (!tcd)
+		return -ENOMEM;
+
+	/* Alloc descriptors for this channel */
+	for (i = 0; i < MPC_DMA_DESCRIPTORS; i++) {
+		mdesc = kzalloc(sizeof(struct mpc_dma_desc), GFP_KERNEL);
+		if (!mdesc) {
+			dev_notice(mdma->dma.dev, "Memory allocation error. "
+					"Allocated only %u descriptors\n", i);
+			break;
+		}
+
+		dma_async_tx_descriptor_init(&mdesc->desc, chan);
+		mdesc->desc.flags = DMA_CTRL_ACK;
+		mdesc->desc.tx_submit = mpc_dma_tx_submit;
+
+		mdesc->tcd = &tcd[i];
+		mdesc->tcd_paddr = tcd_paddr + (i * sizeof(struct mpc_dma_tcd));
+
+		list_add_tail(&mdesc->node, &descs);
+	}
+
+	/* Return error only if no descriptors were allocated */
+	if (i == 0) {
+		dma_free_coherent(mdma->dma.dev,
+			MPC_DMA_DESCRIPTORS * sizeof(struct mpc_dma_tcd),
+								tcd, tcd_paddr);
+		return -ENOMEM;
+	}
+
+	spin_lock_irqsave(&mchan->lock, flags);
+	mchan->tcd = tcd;
+	mchan->tcd_paddr = tcd_paddr;
+	list_splice_tail_init(&descs, &mchan->free);
+	spin_unlock_irqrestore(&mchan->lock, flags);
+
+	/* Enable Error Interrupt */
+	out_8(&mdma->regs->dmaseei, chan->chan_id);
+
+	return 0;
+}
+
+/* Free channel resources */
+static void mpc_dma_free_chan_resources(struct dma_chan *chan)
+{
+	struct mpc_dma *mdma = dma_chan_to_mpc_dma(chan);
+	struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan);
+	struct mpc_dma_desc *mdesc, *tmp;
+	struct mpc_dma_tcd *tcd;
+	dma_addr_t tcd_paddr;
+	unsigned long flags;
+	LIST_HEAD(descs);
+
+	spin_lock_irqsave(&mchan->lock, flags);
+
+	/* Channel must be idle */
+	BUG_ON(!list_empty(&mchan->prepared));
+	BUG_ON(!list_empty(&mchan->queued));
+	BUG_ON(!list_empty(&mchan->active));
+	BUG_ON(!list_empty(&mchan->completed));
+
+	/* Move data */
+	list_splice_tail_init(&mchan->free, &descs);
+	tcd = mchan->tcd;
+	tcd_paddr = mchan->tcd_paddr;
+
+	spin_unlock_irqrestore(&mchan->lock, flags);
+
+	/* Free DMA memory used by descriptors */
+	dma_free_coherent(mdma->dma.dev,
+			MPC_DMA_DESCRIPTORS * sizeof(struct mpc_dma_tcd),
+								tcd, tcd_paddr);
+
+	/* Free descriptors */
+	list_for_each_entry_safe(mdesc, tmp, &descs, node)
+		kfree(mdesc);
+
+	/* Disable Error Interrupt */
+	out_8(&mdma->regs->dmaceei, chan->chan_id);
+}
+
+/* Send all pending descriptor to hardware */
+static void mpc_dma_issue_pending(struct dma_chan *chan)
+{
+	/*
+	 * We are posting descriptors to the hardware as soon as
+	 * they are ready, so this function does nothing.
+	 */
+}
+
+/* Check request completion status */
+static enum dma_status
+mpc_dma_is_tx_complete(struct dma_chan *chan, dma_cookie_t cookie,
+					dma_cookie_t *done, dma_cookie_t *used)
+{
+	struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan);
+	unsigned long flags;
+	dma_cookie_t last_used;
+	dma_cookie_t last_complete;
+
+	spin_lock_irqsave(&mchan->lock, flags);
+	last_used = mchan->chan.cookie;
+	last_complete = mchan->completed_cookie;
+	spin_unlock_irqrestore(&mchan->lock, flags);
+
+	if (done)
+		*done = last_complete;
+
+	if (used)
+		*used = last_used;
+
+	return dma_async_is_complete(cookie, last_complete, last_used);
+}
+
+/* Prepare descriptor for memory to memory copy */
+static struct dma_async_tx_descriptor *
+mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
+					size_t len, unsigned long flags)
+{
+	struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan);
+	struct mpc_dma_desc *mdesc = NULL;
+	struct mpc_dma_tcd *tcd;
+	unsigned long iflags;
+
+	/* Get free descriptor */
+	spin_lock_irqsave(&mchan->lock, iflags);
+	if (!list_empty(&mchan->free)) {
+		mdesc = list_first_entry(&mchan->free, struct mpc_dma_desc,
+									node);
+		list_del(&mdesc->node);
+	}
+	spin_unlock_irqrestore(&mchan->lock, iflags);
+
+	if (!mdesc)
+		return NULL;
+
+	mdesc->error = 0;
+	tcd = mdesc->tcd;
+
+	/* Prepare Transfer Control Descriptor for this transaction */
+	memset(tcd, 0, sizeof(struct mpc_dma_tcd));
+
+	if (IS_ALIGNED(src | dst | len, 32)) {
+		tcd->ssize = MPC_DMA_TSIZE_32;
+		tcd->dsize = MPC_DMA_TSIZE_32;
+		tcd->soff = 32;
+		tcd->doff = 32;
+	} else if (IS_ALIGNED(src | dst | len, 16)) {
+		tcd->ssize = MPC_DMA_TSIZE_16;
+		tcd->dsize = MPC_DMA_TSIZE_16;
+		tcd->soff = 16;
+		tcd->doff = 16;
+	} else if (IS_ALIGNED(src | dst | len, 4)) {
+		tcd->ssize = MPC_DMA_TSIZE_4;
+		tcd->dsize = MPC_DMA_TSIZE_4;
+		tcd->soff = 4;
+		tcd->doff = 4;
+	} else if (IS_ALIGNED(src | dst | len, 2)) {
+		tcd->ssize = MPC_DMA_TSIZE_2;
+		tcd->dsize = MPC_DMA_TSIZE_2;
+		tcd->soff = 2;
+		tcd->doff = 2;
+	} else {
+		tcd->ssize = MPC_DMA_TSIZE_1;
+		tcd->dsize = MPC_DMA_TSIZE_1;
+		tcd->soff = 1;
+		tcd->doff = 1;
+	}
+
+	tcd->saddr = src;
+	tcd->daddr = dst;
+	tcd->nbytes = len;
+	tcd->biter = 1;
+	tcd->citer = 1;
+
+	/* Place descriptor in prepared list */
+	spin_lock_irqsave(&mchan->lock, iflags);
+	list_add_tail(&mdesc->node, &mchan->prepared);
+	spin_unlock_irqrestore(&mchan->lock, iflags);
+
+	return &mdesc->desc;
+}
+
+static int __devinit mpc_dma_probe(struct of_device *op,
+					const struct of_device_id *match)
+{
+	struct device_node *dn = op->node;
+	struct device *dev = &op->dev;
+	struct dma_device *dma;
+	struct mpc_dma *mdma;
+	struct mpc_dma_chan *mchan;
+	struct resource res;
+	ulong regs_start, regs_size;
+	int retval, i;
+
+	mdma = devm_kzalloc(dev, sizeof(struct mpc_dma), GFP_KERNEL);
+	if (!mdma) {
+		dev_err(dev, "Memory exhausted!\n");
+		return -ENOMEM;
+	}
+
+	mdma->irq = irq_of_parse_and_map(dn, 0);
+	if (mdma->irq == NO_IRQ) {
+		dev_err(dev, "Error mapping IRQ!\n");
+		return -EINVAL;
+	}
+
+	retval = of_address_to_resource(dn, 0, &res);
+	if (retval) {
+		dev_err(dev, "Error parsing memory region!\n");
+		return retval;
+	}
+
+	regs_start = res.start;
+	regs_size = res.end - res.start + 1;
+
+	if (!devm_request_mem_region(dev, regs_start, regs_size, DRV_NAME)) {
+		dev_err(dev, "Error requesting memory region!\n");
+		return -EBUSY;
+	}
+
+	mdma->regs = devm_ioremap(dev, regs_start, regs_size);
+	if (!mdma->regs) {
+		dev_err(dev, "Error mapping memory region!\n");
+		return -ENOMEM;
+	}
+
+	mdma->tcd = (struct mpc_dma_tcd *)((u8 *)(mdma->regs)
+							+ MPC_DMA_TCD_OFFSET);
+
+	retval = devm_request_irq(dev, mdma->irq, &mpc_dma_irq, 0, DRV_NAME,
+									mdma);
+	if (retval) {
+		dev_err(dev, "Error requesting IRQ!\n");
+		return -EINVAL;
+	}
+
+	spin_lock_init(&mdma->error_status_lock);
+
+	dma = &mdma->dma;
+	dma->dev = dev;
+	dma->chancnt = MPC_DMA_CHANNELS;
+	dma->device_alloc_chan_resources = mpc_dma_alloc_chan_resources;
+	dma->device_free_chan_resources = mpc_dma_free_chan_resources;
+	dma->device_issue_pending = mpc_dma_issue_pending;
+	dma->device_is_tx_complete = mpc_dma_is_tx_complete;
+	dma->device_prep_dma_memcpy = mpc_dma_prep_memcpy;
+
+	INIT_LIST_HEAD(&dma->channels);
+	dma_cap_set(DMA_MEMCPY, dma->cap_mask);
+
+	for (i = 0; i < dma->chancnt; i++) {
+		mchan = &mdma->channels[i];
+
+		mchan->chan.device = dma;
+		mchan->chan.chan_id = i;
+		mchan->chan.cookie = 1;
+		mchan->completed_cookie = mchan->chan.cookie;
+
+		INIT_LIST_HEAD(&mchan->free);
+		INIT_LIST_HEAD(&mchan->prepared);
+		INIT_LIST_HEAD(&mchan->queued);
+		INIT_LIST_HEAD(&mchan->active);
+		INIT_LIST_HEAD(&mchan->completed);
+
+		spin_lock_init(&mchan->lock);
+		list_add_tail(&mchan->chan.device_node, &dma->channels);
+	}
+
+	tasklet_init(&mdma->tasklet, mpc_dma_tasklet, (unsigned long)mdma);
+
+	/*
+	 * Configure DMA Engine:
+	 * - Dynamic clock,
+	 * - Round-robin group arbitration,
+	 * - Round-robin channel arbitration.
+	 */
+	out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_EDCG |
+				MPC_DMA_DMACR_ERGA | MPC_DMA_DMACR_ERCA);
+
+	/* Disable hardware DMA requests */
+	out_be32(&mdma->regs->dmaerqh, 0);
+	out_be32(&mdma->regs->dmaerql, 0);
+
+	/* Disable error interrupts */
+	out_be32(&mdma->regs->dmaeeih, 0);
+	out_be32(&mdma->regs->dmaeeil, 0);
+
+	/* Clear interrupts status */
+	out_be32(&mdma->regs->dmainth, 0xFFFFFFFF);
+	out_be32(&mdma->regs->dmaintl, 0xFFFFFFFF);
+	out_be32(&mdma->regs->dmaerrh, 0xFFFFFFFF);
+	out_be32(&mdma->regs->dmaerrl, 0xFFFFFFFF);
+
+	/* Route interrupts to IPIC */
+	out_be32(&mdma->regs->dmaihsa, 0);
+	out_be32(&mdma->regs->dmailsa, 0);
+
+	/* Register DMA engine */
+	dev_set_drvdata(dev, mdma);
+	retval = dma_async_device_register(dma);
+	if (retval) {
+		devm_free_irq(dev, mdma->irq, mdma);
+		irq_dispose_mapping(mdma->irq);
+	}
+
+	return retval;
+}
+
+static int __devexit mpc_dma_remove(struct of_device *op)
+{
+	struct device *dev = &op->dev;
+	struct mpc_dma *mdma = dev_get_drvdata(dev);
+
+	dma_async_device_unregister(&mdma->dma);
+	devm_free_irq(dev, mdma->irq, mdma);
+	irq_dispose_mapping(mdma->irq);
+
+	return 0;
+}
+
+static struct of_device_id mpc_dma_match[] = {
+	{ .compatible = "fsl,mpc5121-dma", },
+	{},
+};
+
+static struct of_platform_driver mpc_dma_driver = {
+	.match_table	= mpc_dma_match,
+	.probe		= mpc_dma_probe,
+	.remove		= __devexit_p(mpc_dma_remove),
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init mpc_dma_init(void)
+{
+	return of_register_platform_driver(&mpc_dma_driver);
+}
+module_init(mpc_dma_init);
+
+static void __exit mpc_dma_exit(void)
+{
+	of_unregister_platform_driver(&mpc_dma_driver);
+}
+module_exit(mpc_dma_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Piotr Ziecik <kosmo@semihalf.com>");
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/mv_xor.c linux-libre-2.6.34-gnu1/drivers/dma/mv_xor.c
--- linux-libre-2.6.33-gnu1/drivers/dma/mv_xor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/mv_xor.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/ppc4xx/adma.c linux-libre-2.6.34-gnu1/drivers/dma/ppc4xx/adma.c
--- linux-libre-2.6.33-gnu1/drivers/dma/ppc4xx/adma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/ppc4xx/adma.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/proc_fs.h>
 #include <linux/of.h>
@@ -4940,7 +4941,7 @@ out_free:
 	return ret;
 }
 
-static struct of_device_id __devinitdata ppc440spe_adma_of_match[] = {
+static const struct of_device_id ppc440spe_adma_of_match[] __devinitconst = {
 	{ .compatible	= "ibm,dma-440spe", },
 	{ .compatible	= "amcc,xor-accelerator", },
 	{},
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/shdma.c linux-libre-2.6.34-gnu1/drivers/dma/shdma.c
--- linux-libre-2.6.33-gnu1/drivers/dma/shdma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/shdma.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,13 +19,16 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/dmaengine.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
-#include <cpu/dma.h>
-#include <asm/dma-sh.h>
+#include <linux/pm_runtime.h>
+
+#include <asm/dmaengine.h>
+
 #include "shdma.h"
 
 /* DMA descriptor control */
@@ -38,33 +41,32 @@ enum sh_dmae_desc_status {
 };
 
 #define NR_DESCS_PER_CHANNEL 32
-/*
- * Define the default configuration for dual address memory-memory transfer.
- * The 0x400 value represents auto-request, external->external.
- *
- * And this driver set 4byte burst mode.
- * If you want to change mode, you need to change RS_DEFAULT of value.
- * (ex 1byte burst mode -> (RS_DUAL & ~TS_32)
- */
-#define RS_DEFAULT  (RS_DUAL)
+/* Default MEMCPY transfer size = 2^2 = 4 bytes */
+#define LOG2_DEFAULT_XFER_SIZE	2
+
+/* A bitmask with bits enough for enum sh_dmae_slave_chan_id */
+static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SHDMA_SLAVE_NUMBER)];
 
 static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all);
 
-#define SH_DMAC_CHAN_BASE(id) (dma_base_addr[id])
 static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg)
 {
-	ctrl_outl(data, (SH_DMAC_CHAN_BASE(sh_dc->id) + reg));
+	__raw_writel(data, sh_dc->base + reg / sizeof(u32));
 }
 
 static u32 sh_dmae_readl(struct sh_dmae_chan *sh_dc, u32 reg)
 {
-	return ctrl_inl((SH_DMAC_CHAN_BASE(sh_dc->id) + reg));
+	return __raw_readl(sh_dc->base + reg / sizeof(u32));
 }
 
-static void dmae_init(struct sh_dmae_chan *sh_chan)
+static u16 dmaor_read(struct sh_dmae_device *shdev)
 {
-	u32 chcr = RS_DEFAULT; /* default is DUAL mode */
-	sh_dmae_writel(sh_chan, chcr, CHCR);
+	return __raw_readw(shdev->chan_reg + DMAOR / sizeof(u32));
+}
+
+static void dmaor_write(struct sh_dmae_device *shdev, u16 data)
+{
+	__raw_writew(data, shdev->chan_reg + DMAOR / sizeof(u32));
 }
 
 /*
@@ -72,50 +74,75 @@ static void dmae_init(struct sh_dmae_cha
  *
  * SH7780 has two DMAOR register
  */
-static void sh_dmae_ctl_stop(int id)
+static void sh_dmae_ctl_stop(struct sh_dmae_device *shdev)
 {
-	unsigned short dmaor = dmaor_read_reg(id);
+	unsigned short dmaor = dmaor_read(shdev);
 
-	dmaor &= ~(DMAOR_NMIF | DMAOR_AE);
-	dmaor_write_reg(id, dmaor);
+	dmaor_write(shdev, dmaor & ~(DMAOR_NMIF | DMAOR_AE | DMAOR_DME));
 }
 
-static int sh_dmae_rst(int id)
+static int sh_dmae_rst(struct sh_dmae_device *shdev)
 {
 	unsigned short dmaor;
 
-	sh_dmae_ctl_stop(id);
-	dmaor = dmaor_read_reg(id) | DMAOR_INIT;
+	sh_dmae_ctl_stop(shdev);
+	dmaor = dmaor_read(shdev) | shdev->pdata->dmaor_init;
 
-	dmaor_write_reg(id, dmaor);
-	if (dmaor_read_reg(id) & (DMAOR_AE | DMAOR_NMIF)) {
-		pr_warning(KERN_ERR "dma-sh: Can't initialize DMAOR.\n");
+	dmaor_write(shdev, dmaor);
+	if (dmaor_read(shdev) & (DMAOR_AE | DMAOR_NMIF)) {
+		pr_warning("dma-sh: Can't initialize DMAOR.\n");
 		return -EINVAL;
 	}
 	return 0;
 }
 
-static int dmae_is_busy(struct sh_dmae_chan *sh_chan)
+static bool dmae_is_busy(struct sh_dmae_chan *sh_chan)
 {
 	u32 chcr = sh_dmae_readl(sh_chan, CHCR);
-	if (chcr & CHCR_DE) {
-		if (!(chcr & CHCR_TE))
-			return -EBUSY; /* working */
-	}
-	return 0; /* waiting */
+
+	if ((chcr & (CHCR_DE | CHCR_TE)) == CHCR_DE)
+		return true; /* working */
+
+	return false; /* waiting */
 }
 
-static inline unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan)
+static unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan, u32 chcr)
 {
-	u32 chcr = sh_dmae_readl(sh_chan, CHCR);
-	return ts_shift[(chcr & CHCR_TS_MASK) >> CHCR_TS_SHIFT];
+	struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
+						struct sh_dmae_device, common);
+	struct sh_dmae_pdata *pdata = shdev->pdata;
+	int cnt = ((chcr & pdata->ts_low_mask) >> pdata->ts_low_shift) |
+		((chcr & pdata->ts_high_mask) >> pdata->ts_high_shift);
+
+	if (cnt >= pdata->ts_shift_num)
+		cnt = 0;
+
+	return pdata->ts_shift[cnt];
+}
+
+static u32 log2size_to_chcr(struct sh_dmae_chan *sh_chan, int l2size)
+{
+	struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
+						struct sh_dmae_device, common);
+	struct sh_dmae_pdata *pdata = shdev->pdata;
+	int i;
+
+	for (i = 0; i < pdata->ts_shift_num; i++)
+		if (pdata->ts_shift[i] == l2size)
+			break;
+
+	if (i == pdata->ts_shift_num)
+		i = 0;
+
+	return ((i << pdata->ts_low_shift) & pdata->ts_low_mask) |
+		((i << pdata->ts_high_shift) & pdata->ts_high_mask);
 }
 
 static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw)
 {
 	sh_dmae_writel(sh_chan, hw->sar, SAR);
 	sh_dmae_writel(sh_chan, hw->dar, DAR);
-	sh_dmae_writel(sh_chan, hw->tcr >> calc_xmit_shift(sh_chan), TCR);
+	sh_dmae_writel(sh_chan, hw->tcr >> sh_chan->xmit_shift, TCR);
 }
 
 static void dmae_start(struct sh_dmae_chan *sh_chan)
@@ -123,7 +150,7 @@ static void dmae_start(struct sh_dmae_ch
 	u32 chcr = sh_dmae_readl(sh_chan, CHCR);
 
 	chcr |= CHCR_DE | CHCR_IE;
-	sh_dmae_writel(sh_chan, chcr, CHCR);
+	sh_dmae_writel(sh_chan, chcr & ~CHCR_TE, CHCR);
 }
 
 static void dmae_halt(struct sh_dmae_chan *sh_chan)
@@ -134,55 +161,44 @@ static void dmae_halt(struct sh_dmae_cha
 	sh_dmae_writel(sh_chan, chcr, CHCR);
 }
 
+static void dmae_init(struct sh_dmae_chan *sh_chan)
+{
+	/*
+	 * Default configuration for dual address memory-memory transfer.
+	 * 0x400 represents auto-request.
+	 */
+	u32 chcr = DM_INC | SM_INC | 0x400 | log2size_to_chcr(sh_chan,
+						   LOG2_DEFAULT_XFER_SIZE);
+	sh_chan->xmit_shift = calc_xmit_shift(sh_chan, chcr);
+	sh_dmae_writel(sh_chan, chcr, CHCR);
+}
+
 static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val)
 {
-	int ret = dmae_is_busy(sh_chan);
 	/* When DMA was working, can not set data to CHCR */
-	if (ret)
-		return ret;
+	if (dmae_is_busy(sh_chan))
+		return -EBUSY;
 
+	sh_chan->xmit_shift = calc_xmit_shift(sh_chan, val);
 	sh_dmae_writel(sh_chan, val, CHCR);
+
 	return 0;
 }
 
-#define DMARS1_ADDR	0x04
-#define DMARS2_ADDR	0x08
-#define DMARS_SHIFT 8
-#define DMARS_CHAN_MSK 0x01
 static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val)
 {
-	u32 addr;
-	int shift = 0;
-	int ret = dmae_is_busy(sh_chan);
-	if (ret)
-		return ret;
-
-	if (sh_chan->id & DMARS_CHAN_MSK)
-		shift = DMARS_SHIFT;
+	struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
+						struct sh_dmae_device, common);
+	struct sh_dmae_pdata *pdata = shdev->pdata;
+	struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id];
+	u16 __iomem *addr = shdev->dmars + chan_pdata->dmars / sizeof(u16);
+	int shift = chan_pdata->dmars_bit;
 
-	switch (sh_chan->id) {
-	/* DMARS0 */
-	case 0:
-	case 1:
-		addr = SH_DMARS_BASE;
-		break;
-	/* DMARS1 */
-	case 2:
-	case 3:
-		addr = (SH_DMARS_BASE + DMARS1_ADDR);
-		break;
-	/* DMARS2 */
-	case 4:
-	case 5:
-		addr = (SH_DMARS_BASE + DMARS2_ADDR);
-		break;
-	default:
-		return -EINVAL;
-	}
+	if (dmae_is_busy(sh_chan))
+		return -EBUSY;
 
-	ctrl_outw((val << shift) |
-		(ctrl_inw(addr) & (shift ? 0xFF00 : 0x00FF)),
-		addr);
+	__raw_writew((__raw_readw(addr) & (0xff00 >> shift)) | (val << shift),
+		     addr);
 
 	return 0;
 }
@@ -250,10 +266,59 @@ static struct sh_desc *sh_dmae_get_desc(
 	return NULL;
 }
 
+static struct sh_dmae_slave_config *sh_dmae_find_slave(
+	struct sh_dmae_chan *sh_chan, enum sh_dmae_slave_chan_id slave_id)
+{
+	struct dma_device *dma_dev = sh_chan->common.device;
+	struct sh_dmae_device *shdev = container_of(dma_dev,
+					struct sh_dmae_device, common);
+	struct sh_dmae_pdata *pdata = shdev->pdata;
+	int i;
+
+	if ((unsigned)slave_id >= SHDMA_SLAVE_NUMBER)
+		return NULL;
+
+	for (i = 0; i < pdata->slave_num; i++)
+		if (pdata->slave[i].slave_id == slave_id)
+			return pdata->slave + i;
+
+	return NULL;
+}
+
 static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
 {
 	struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
 	struct sh_desc *desc;
+	struct sh_dmae_slave *param = chan->private;
+	int ret;
+
+	pm_runtime_get_sync(sh_chan->dev);
+
+	/*
+	 * This relies on the guarantee from dmaengine that alloc_chan_resources
+	 * never runs concurrently with itself or free_chan_resources.
+	 */
+	if (param) {
+		struct sh_dmae_slave_config *cfg;
+
+		cfg = sh_dmae_find_slave(sh_chan, param->slave_id);
+		if (!cfg) {
+			ret = -EINVAL;
+			goto efindslave;
+		}
+
+		if (test_and_set_bit(param->slave_id, sh_dmae_slave_used)) {
+			ret = -EBUSY;
+			goto etestused;
+		}
+
+		param->config = cfg;
+
+		dmae_set_dmars(sh_chan, cfg->mid_rid);
+		dmae_set_chcr(sh_chan, cfg->chcr);
+	} else if ((sh_dmae_readl(sh_chan, CHCR) & 0xf00) != 0x400) {
+		dmae_init(sh_chan);
+	}
 
 	spin_lock_bh(&sh_chan->desc_lock);
 	while (sh_chan->descs_allocated < NR_DESCS_PER_CHANNEL) {
@@ -274,7 +339,20 @@ static int sh_dmae_alloc_chan_resources(
 	}
 	spin_unlock_bh(&sh_chan->desc_lock);
 
+	if (!sh_chan->descs_allocated) {
+		ret = -ENOMEM;
+		goto edescalloc;
+	}
+
 	return sh_chan->descs_allocated;
+
+edescalloc:
+	if (param)
+		clear_bit(param->slave_id, sh_dmae_slave_used);
+etestused:
+efindslave:
+	pm_runtime_put(sh_chan->dev);
+	return ret;
 }
 
 /*
@@ -285,11 +363,20 @@ static void sh_dmae_free_chan_resources(
 	struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
 	struct sh_desc *desc, *_desc;
 	LIST_HEAD(list);
+	int descs = sh_chan->descs_allocated;
+
+	dmae_halt(sh_chan);
 
 	/* Prepared and not submitted descriptors can still be on the queue */
 	if (!list_empty(&sh_chan->ld_queue))
 		sh_dmae_chan_ld_cleanup(sh_chan, true);
 
+	if (chan->private) {
+		/* The caller is holding dma_list_mutex */
+		struct sh_dmae_slave *param = chan->private;
+		clear_bit(param->slave_id, sh_dmae_slave_used);
+	}
+
 	spin_lock_bh(&sh_chan->desc_lock);
 
 	list_splice_init(&sh_chan->ld_free, &list);
@@ -297,27 +384,104 @@ static void sh_dmae_free_chan_resources(
 
 	spin_unlock_bh(&sh_chan->desc_lock);
 
+	if (descs > 0)
+		pm_runtime_put(sh_chan->dev);
+
 	list_for_each_entry_safe(desc, _desc, &list, node)
 		kfree(desc);
 }
 
-static struct dma_async_tx_descriptor *sh_dmae_prep_memcpy(
-	struct dma_chan *chan, dma_addr_t dma_dest, dma_addr_t dma_src,
-	size_t len, unsigned long flags)
+/**
+ * sh_dmae_add_desc - get, set up and return one transfer descriptor
+ * @sh_chan:	DMA channel
+ * @flags:	DMA transfer flags
+ * @dest:	destination DMA address, incremented when direction equals
+ *		DMA_FROM_DEVICE or DMA_BIDIRECTIONAL
+ * @src:	source DMA address, incremented when direction equals
+ *		DMA_TO_DEVICE or DMA_BIDIRECTIONAL
+ * @len:	DMA transfer length
+ * @first:	if NULL, set to the current descriptor and cookie set to -EBUSY
+ * @direction:	needed for slave DMA to decide which address to keep constant,
+ *		equals DMA_BIDIRECTIONAL for MEMCPY
+ * Returns 0 or an error
+ * Locks: called with desc_lock held
+ */
+static struct sh_desc *sh_dmae_add_desc(struct sh_dmae_chan *sh_chan,
+	unsigned long flags, dma_addr_t *dest, dma_addr_t *src, size_t *len,
+	struct sh_desc **first, enum dma_data_direction direction)
 {
-	struct sh_dmae_chan *sh_chan;
-	struct sh_desc *first = NULL, *prev = NULL, *new;
+	struct sh_desc *new;
 	size_t copy_size;
-	LIST_HEAD(tx_list);
-	int chunks = (len + SH_DMA_TCR_MAX) / (SH_DMA_TCR_MAX + 1);
 
-	if (!chan)
+	if (!*len)
 		return NULL;
 
-	if (!len)
+	/* Allocate the link descriptor from the free list */
+	new = sh_dmae_get_desc(sh_chan);
+	if (!new) {
+		dev_err(sh_chan->dev, "No free link descriptor available\n");
 		return NULL;
+	}
 
-	sh_chan = to_sh_chan(chan);
+	copy_size = min(*len, (size_t)SH_DMA_TCR_MAX + 1);
+
+	new->hw.sar = *src;
+	new->hw.dar = *dest;
+	new->hw.tcr = copy_size;
+
+	if (!*first) {
+		/* First desc */
+		new->async_tx.cookie = -EBUSY;
+		*first = new;
+	} else {
+		/* Other desc - invisible to the user */
+		new->async_tx.cookie = -EINVAL;
+	}
+
+	dev_dbg(sh_chan->dev,
+		"chaining (%u/%u)@%x -> %x with %p, cookie %d, shift %d\n",
+		copy_size, *len, *src, *dest, &new->async_tx,
+		new->async_tx.cookie, sh_chan->xmit_shift);
+
+	new->mark = DESC_PREPARED;
+	new->async_tx.flags = flags;
+	new->direction = direction;
+
+	*len -= copy_size;
+	if (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE)
+		*src += copy_size;
+	if (direction == DMA_BIDIRECTIONAL || direction == DMA_FROM_DEVICE)
+		*dest += copy_size;
+
+	return new;
+}
+
+/*
+ * sh_dmae_prep_sg - prepare transfer descriptors from an SG list
+ *
+ * Common routine for public (MEMCPY) and slave DMA. The MEMCPY case is also
+ * converted to scatter-gather to guarantee consistent locking and a correct
+ * list manipulation. For slave DMA direction carries the usual meaning, and,
+ * logically, the SG list is RAM and the addr variable contains slave address,
+ * e.g., the FIFO I/O register. For MEMCPY direction equals DMA_BIDIRECTIONAL
+ * and the SG list contains only one element and points at the source buffer.
+ */
+static struct dma_async_tx_descriptor *sh_dmae_prep_sg(struct sh_dmae_chan *sh_chan,
+	struct scatterlist *sgl, unsigned int sg_len, dma_addr_t *addr,
+	enum dma_data_direction direction, unsigned long flags)
+{
+	struct scatterlist *sg;
+	struct sh_desc *first = NULL, *new = NULL /* compiler... */;
+	LIST_HEAD(tx_list);
+	int chunks = 0;
+	int i;
+
+	if (!sg_len)
+		return NULL;
+
+	for_each_sg(sgl, sg, sg_len, i)
+		chunks += (sg_dma_len(sg) + SH_DMA_TCR_MAX) /
+			(SH_DMA_TCR_MAX + 1);
 
 	/* Have to lock the whole loop to protect against concurrent release */
 	spin_lock_bh(&sh_chan->desc_lock);
@@ -333,49 +497,32 @@ static struct dma_async_tx_descriptor *s
 	 *	only during this function, then they are immediately spliced
 	 *	back onto the free list in form of a chain
 	 */
-	do {
-		/* Allocate the link descriptor from the free list */
-		new = sh_dmae_get_desc(sh_chan);
-		if (!new) {
-			dev_err(sh_chan->dev,
-				"No free memory for link descriptor\n");
-			list_for_each_entry(new, &tx_list, node)
-				new->mark = DESC_IDLE;
-			list_splice(&tx_list, &sh_chan->ld_free);
-			spin_unlock_bh(&sh_chan->desc_lock);
-			return NULL;
-		}
-
-		copy_size = min(len, (size_t)SH_DMA_TCR_MAX + 1);
+	for_each_sg(sgl, sg, sg_len, i) {
+		dma_addr_t sg_addr = sg_dma_address(sg);
+		size_t len = sg_dma_len(sg);
 
-		new->hw.sar = dma_src;
-		new->hw.dar = dma_dest;
-		new->hw.tcr = copy_size;
-		if (!first) {
-			/* First desc */
-			new->async_tx.cookie = -EBUSY;
-			first = new;
-		} else {
-			/* Other desc - invisible to the user */
-			new->async_tx.cookie = -EINVAL;
-		}
+		if (!len)
+			goto err_get_desc;
 
-		dev_dbg(sh_chan->dev,
-			"chaining %u of %u with %p, dst %x, cookie %d\n",
-			copy_size, len, &new->async_tx, dma_dest,
-			new->async_tx.cookie);
+		do {
+			dev_dbg(sh_chan->dev, "Add SG #%d@%p[%d], dma %llx\n",
+				i, sg, len, (unsigned long long)sg_addr);
 
-		new->mark = DESC_PREPARED;
-		new->async_tx.flags = flags;
-		new->chunks = chunks--;
+			if (direction == DMA_FROM_DEVICE)
+				new = sh_dmae_add_desc(sh_chan, flags,
+						&sg_addr, addr, &len, &first,
+						direction);
+			else
+				new = sh_dmae_add_desc(sh_chan, flags,
+						addr, &sg_addr, &len, &first,
+						direction);
+			if (!new)
+				goto err_get_desc;
 
-		prev = new;
-		len -= copy_size;
-		dma_src += copy_size;
-		dma_dest += copy_size;
-		/* Insert the link descriptor to the LD ring */
-		list_add_tail(&new->node, &tx_list);
-	} while (len);
+			new->chunks = chunks--;
+			list_add_tail(&new->node, &tx_list);
+		} while (len);
+	}
 
 	if (new != first)
 		new->async_tx.cookie = -ENOSPC;
@@ -386,6 +533,90 @@ static struct dma_async_tx_descriptor *s
 	spin_unlock_bh(&sh_chan->desc_lock);
 
 	return &first->async_tx;
+
+err_get_desc:
+	list_for_each_entry(new, &tx_list, node)
+		new->mark = DESC_IDLE;
+	list_splice(&tx_list, &sh_chan->ld_free);
+
+	spin_unlock_bh(&sh_chan->desc_lock);
+
+	return NULL;
+}
+
+static struct dma_async_tx_descriptor *sh_dmae_prep_memcpy(
+	struct dma_chan *chan, dma_addr_t dma_dest, dma_addr_t dma_src,
+	size_t len, unsigned long flags)
+{
+	struct sh_dmae_chan *sh_chan;
+	struct scatterlist sg;
+
+	if (!chan || !len)
+		return NULL;
+
+	chan->private = NULL;
+
+	sh_chan = to_sh_chan(chan);
+
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, pfn_to_page(PFN_DOWN(dma_src)), len,
+		    offset_in_page(dma_src));
+	sg_dma_address(&sg) = dma_src;
+	sg_dma_len(&sg) = len;
+
+	return sh_dmae_prep_sg(sh_chan, &sg, 1, &dma_dest, DMA_BIDIRECTIONAL,
+			       flags);
+}
+
+static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg(
+	struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len,
+	enum dma_data_direction direction, unsigned long flags)
+{
+	struct sh_dmae_slave *param;
+	struct sh_dmae_chan *sh_chan;
+
+	if (!chan)
+		return NULL;
+
+	sh_chan = to_sh_chan(chan);
+	param = chan->private;
+
+	/* Someone calling slave DMA on a public channel? */
+	if (!param || !sg_len) {
+		dev_warn(sh_chan->dev, "%s: bad parameter: %p, %d, %d\n",
+			 __func__, param, sg_len, param ? param->slave_id : -1);
+		return NULL;
+	}
+
+	/*
+	 * if (param != NULL), this is a successfully requested slave channel,
+	 * therefore param->config != NULL too.
+	 */
+	return sh_dmae_prep_sg(sh_chan, sgl, sg_len, &param->config->addr,
+			       direction, flags);
+}
+
+static void sh_dmae_terminate_all(struct dma_chan *chan)
+{
+	struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
+
+	if (!chan)
+		return;
+
+	dmae_halt(sh_chan);
+
+	spin_lock_bh(&sh_chan->desc_lock);
+	if (!list_empty(&sh_chan->ld_queue)) {
+		/* Record partial transfer */
+		struct sh_desc *desc = list_entry(sh_chan->ld_queue.next,
+						  struct sh_desc, node);
+		desc->partial = (desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) <<
+			sh_chan->xmit_shift;
+
+	}
+	spin_unlock_bh(&sh_chan->desc_lock);
+
+	sh_dmae_chan_ld_cleanup(sh_chan, true);
 }
 
 static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all)
@@ -419,7 +650,11 @@ static dma_async_tx_callback __ld_cleanu
 			cookie = tx->cookie;
 
 		if (desc->mark == DESC_COMPLETED && desc->chunks == 1) {
-			BUG_ON(sh_chan->completed_cookie != desc->cookie - 1);
+			if (sh_chan->completed_cookie != desc->cookie - 1)
+				dev_dbg(sh_chan->dev,
+					"Completing cookie %d, expected %d\n",
+					desc->cookie,
+					sh_chan->completed_cookie + 1);
 			sh_chan->completed_cookie = desc->cookie;
 		}
 
@@ -483,7 +718,7 @@ static void sh_dmae_chan_ld_cleanup(stru
 
 static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
 {
-	struct sh_desc *sd;
+	struct sh_desc *desc;
 
 	spin_lock_bh(&sh_chan->desc_lock);
 	/* DMA work check */
@@ -492,11 +727,14 @@ static void sh_chan_xfer_ld_queue(struct
 		return;
 	}
 
-	/* Find the first un-transfer desciptor */
-	list_for_each_entry(sd, &sh_chan->ld_queue, node)
-		if (sd->mark == DESC_SUBMITTED) {
+	/* Find the first not transferred desciptor */
+	list_for_each_entry(desc, &sh_chan->ld_queue, node)
+		if (desc->mark == DESC_SUBMITTED) {
+			dev_dbg(sh_chan->dev, "Queue #%d to %d: %u@%x -> %x\n",
+				desc->async_tx.cookie, sh_chan->id,
+				desc->hw.tcr, desc->hw.sar, desc->hw.dar);
 			/* Get the ld start address from ld_queue */
-			dmae_set_reg(sh_chan, &sd->hw);
+			dmae_set_reg(sh_chan, &desc->hw);
 			dmae_start(sh_chan);
 			break;
 		}
@@ -518,6 +756,7 @@ static enum dma_status sh_dmae_is_comple
 	struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
 	dma_cookie_t last_used;
 	dma_cookie_t last_complete;
+	enum dma_status status;
 
 	sh_dmae_chan_ld_cleanup(sh_chan, false);
 
@@ -531,7 +770,27 @@ static enum dma_status sh_dmae_is_comple
 	if (used)
 		*used = last_used;
 
-	return dma_async_is_complete(cookie, last_complete, last_used);
+	spin_lock_bh(&sh_chan->desc_lock);
+
+	status = dma_async_is_complete(cookie, last_complete, last_used);
+
+	/*
+	 * If we don't find cookie on the queue, it has been aborted and we have
+	 * to report error
+	 */
+	if (status != DMA_SUCCESS) {
+		struct sh_desc *desc;
+		status = DMA_ERROR;
+		list_for_each_entry(desc, &sh_chan->ld_queue, node)
+			if (desc->cookie == cookie) {
+				status = DMA_IN_PROGRESS;
+				break;
+			}
+	}
+
+	spin_unlock_bh(&sh_chan->desc_lock);
+
+	return status;
 }
 
 static irqreturn_t sh_dmae_interrupt(int irq, void *data)
@@ -554,40 +813,32 @@ static irqreturn_t sh_dmae_interrupt(int
 #if defined(CONFIG_CPU_SH4)
 static irqreturn_t sh_dmae_err(int irq, void *data)
 {
-	int err = 0;
 	struct sh_dmae_device *shdev = (struct sh_dmae_device *)data;
+	int i;
 
-	/* IRQ Multi */
-	if (shdev->pdata.mode & SHDMA_MIX_IRQ) {
-		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);
-				return IRQ_HANDLED;
+	/* halt the dma controller */
+	sh_dmae_ctl_stop(shdev);
+
+	/* We cannot detect, which channel caused the error, have to reset all */
+	for (i = 0; i < SH_DMAC_MAX_CHANNELS; i++) {
+		struct sh_dmae_chan *sh_chan = shdev->chan[i];
+		if (sh_chan) {
+			struct sh_desc *desc;
+			/* Stop the channel */
+			dmae_halt(sh_chan);
+			/* Complete all  */
+			list_for_each_entry(desc, &sh_chan->ld_queue, node) {
+				struct dma_async_tx_descriptor *tx = &desc->async_tx;
+				desc->mark = DESC_IDLE;
+				if (tx->callback)
+					tx->callback(tx->callback_param);
 			}
-		default:
-			return IRQ_NONE;
-		}
-	} else {
-		/* reset dma controller */
-		err = sh_dmae_rst(0);
-		if (err)
-			return err;
-#ifdef SH_DMAC_BASE1
-		if (shdev->pdata.mode & SHDMA_DMAOR1) {
-			err = sh_dmae_rst(1);
-			if (err)
-				return err;
+			list_splice_init(&sh_chan->ld_queue, &sh_chan->ld_free);
 		}
-#endif
-		disable_irq(irq);
-		return IRQ_HANDLED;
 	}
+	sh_dmae_rst(shdev);
+
+	return IRQ_HANDLED;
 }
 #endif
 
@@ -596,11 +847,14 @@ static void dmae_do_tasklet(unsigned lon
 	struct sh_dmae_chan *sh_chan = (struct sh_dmae_chan *)data;
 	struct sh_desc *desc;
 	u32 sar_buf = sh_dmae_readl(sh_chan, SAR);
+	u32 dar_buf = sh_dmae_readl(sh_chan, DAR);
 
 	spin_lock(&sh_chan->desc_lock);
 	list_for_each_entry(desc, &sh_chan->ld_queue, node) {
-		if ((desc->hw.sar + desc->hw.tcr) == sar_buf &&
-		    desc->mark == DESC_SUBMITTED) {
+		if (desc->mark == DESC_SUBMITTED &&
+		    ((desc->direction == DMA_FROM_DEVICE &&
+		      (desc->hw.dar + desc->hw.tcr) == dar_buf) ||
+		     (desc->hw.sar + desc->hw.tcr) == sar_buf)) {
 			dev_dbg(sh_chan->dev, "done #%d@%p dst %u\n",
 				desc->async_tx.cookie, &desc->async_tx,
 				desc->hw.dar);
@@ -615,19 +869,12 @@ static void dmae_do_tasklet(unsigned lon
 	sh_dmae_chan_ld_cleanup(sh_chan, false);
 }
 
-static unsigned int get_dmae_irq(unsigned int id)
-{
-	unsigned int irq = 0;
-	if (id < ARRAY_SIZE(dmte_irq_map))
-		irq = dmte_irq_map[id];
-	return irq;
-}
-
-static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id)
+static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
+					int irq, unsigned long flags)
 {
 	int err;
-	unsigned int irq = get_dmae_irq(id);
-	unsigned long irqflags = IRQF_DISABLED;
+	struct sh_dmae_channel *chan_pdata = &shdev->pdata->channel[id];
+	struct platform_device *pdev = to_platform_device(shdev->common.dev);
 	struct sh_dmae_chan *new_sh_chan;
 
 	/* alloc channel */
@@ -638,8 +885,13 @@ static int __devinit sh_dmae_chan_probe(
 		return -ENOMEM;
 	}
 
+	/* copy struct dma_device */
+	new_sh_chan->common.device = &shdev->common;
+
 	new_sh_chan->dev = shdev->common.dev;
 	new_sh_chan->id = id;
+	new_sh_chan->irq = irq;
+	new_sh_chan->base = shdev->chan_reg + chan_pdata->offset / sizeof(u32);
 
 	/* Init DMA tasklet */
 	tasklet_init(&new_sh_chan->tasklet, dmae_do_tasklet,
@@ -654,29 +906,20 @@ static int __devinit sh_dmae_chan_probe(
 	INIT_LIST_HEAD(&new_sh_chan->ld_queue);
 	INIT_LIST_HEAD(&new_sh_chan->ld_free);
 
-	/* copy struct dma_device */
-	new_sh_chan->common.device = &shdev->common;
-
 	/* Add the channel to DMA device channel list */
 	list_add_tail(&new_sh_chan->common.device_node,
 			&shdev->common.channels);
 	shdev->common.chancnt++;
 
-	if (shdev->pdata.mode & SHDMA_MIX_IRQ) {
-		irqflags = IRQF_SHARED;
-#if defined(DMTE6_IRQ)
-		if (irq >= DMTE6_IRQ)
-			irq = DMTE6_IRQ;
-		else
-#endif
-			irq = DMTE0_IRQ;
-	}
-
-	snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id),
-			"sh-dmae%d", new_sh_chan->id);
+	if (pdev->id >= 0)
+		snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id),
+			 "sh-dmae%d.%d", pdev->id, new_sh_chan->id);
+	else
+		snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id),
+			 "sh-dma%d", new_sh_chan->id);
 
 	/* set up channel irq */
-	err = request_irq(irq, &sh_dmae_interrupt, irqflags,
+	err = request_irq(irq, &sh_dmae_interrupt, flags,
 			  new_sh_chan->dev_id, new_sh_chan);
 	if (err) {
 		dev_err(shdev->common.dev, "DMA channel %d request_irq error "
@@ -684,11 +927,6 @@ static int __devinit sh_dmae_chan_probe(
 		goto err_no_irq;
 	}
 
-	/* CHCR register control function */
-	new_sh_chan->set_chcr = dmae_set_chcr;
-	/* DMARS register control function */
-	new_sh_chan->set_dmars = dmae_set_dmars;
-
 	shdev->chan[id] = new_sh_chan;
 	return 0;
 
@@ -705,12 +943,12 @@ static void sh_dmae_chan_remove(struct s
 
 	for (i = shdev->common.chancnt - 1 ; i >= 0 ; i--) {
 		if (shdev->chan[i]) {
-			struct sh_dmae_chan *shchan = shdev->chan[i];
-			if (!(shdev->pdata.mode & SHDMA_MIX_IRQ))
-				free_irq(dmte_irq_map[i], shchan);
+			struct sh_dmae_chan *sh_chan = shdev->chan[i];
 
-			list_del(&shchan->common.device_node);
-			kfree(shchan);
+			free_irq(sh_chan->irq, sh_chan);
+
+			list_del(&sh_chan->common.device_node);
+			kfree(sh_chan);
 			shdev->chan[i] = NULL;
 		}
 	}
@@ -719,85 +957,164 @@ static void sh_dmae_chan_remove(struct s
 
 static int __init sh_dmae_probe(struct platform_device *pdev)
 {
-	int err = 0, cnt, ecnt;
-	unsigned long irqflags = IRQF_DISABLED;
-#if defined(CONFIG_CPU_SH4)
-	int eirq[] = { DMAE0_IRQ,
-#if defined(DMAE1_IRQ)
-			DMAE1_IRQ
-#endif
-		};
-#endif
+	struct sh_dmae_pdata *pdata = pdev->dev.platform_data;
+	unsigned long irqflags = IRQF_DISABLED,
+		chan_flag[SH_DMAC_MAX_CHANNELS] = {};
+	int errirq, chan_irq[SH_DMAC_MAX_CHANNELS];
+	int err, i, irq_cnt = 0, irqres = 0;
 	struct sh_dmae_device *shdev;
+	struct resource *chan, *dmars, *errirq_res, *chanirq_res;
 
 	/* get platform data */
-	if (!pdev->dev.platform_data)
+	if (!pdata || !pdata->channel_num)
 		return -ENODEV;
 
+	chan = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	/* DMARS area is optional, if absent, this controller cannot do slave DMA */
+	dmars = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	/*
+	 * IRQ resources:
+	 * 1. there always must be at least one IRQ IO-resource. On SH4 it is
+	 *    the error IRQ, in which case it is the only IRQ in this resource:
+	 *    start == end. If it is the only IRQ resource, all channels also
+	 *    use the same IRQ.
+	 * 2. DMA channel IRQ resources can be specified one per resource or in
+	 *    ranges (start != end)
+	 * 3. iff all events (channels and, optionally, error) on this
+	 *    controller use the same IRQ, only one IRQ resource can be
+	 *    specified, otherwise there must be one IRQ per channel, even if
+	 *    some of them are equal
+	 * 4. if all IRQs on this controller are equal or if some specific IRQs
+	 *    specify IORESOURCE_IRQ_SHAREABLE in their resources, they will be
+	 *    requested with the IRQF_SHARED flag
+	 */
+	errirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!chan || !errirq_res)
+		return -ENODEV;
+
+	if (!request_mem_region(chan->start, resource_size(chan), pdev->name)) {
+		dev_err(&pdev->dev, "DMAC register region already claimed\n");
+		return -EBUSY;
+	}
+
+	if (dmars && !request_mem_region(dmars->start, resource_size(dmars), pdev->name)) {
+		dev_err(&pdev->dev, "DMAC DMARS region already claimed\n");
+		err = -EBUSY;
+		goto ermrdmars;
+	}
+
+	err = -ENOMEM;
 	shdev = kzalloc(sizeof(struct sh_dmae_device), GFP_KERNEL);
 	if (!shdev) {
-		dev_err(&pdev->dev, "No enough memory\n");
-		return -ENOMEM;
+		dev_err(&pdev->dev, "Not enough memory\n");
+		goto ealloc;
+	}
+
+	shdev->chan_reg = ioremap(chan->start, resource_size(chan));
+	if (!shdev->chan_reg)
+		goto emapchan;
+	if (dmars) {
+		shdev->dmars = ioremap(dmars->start, resource_size(dmars));
+		if (!shdev->dmars)
+			goto emapdmars;
 	}
 
 	/* platform data */
-	memcpy(&shdev->pdata, pdev->dev.platform_data,
-			sizeof(struct sh_dmae_pdata));
+	shdev->pdata = pdata;
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_get_sync(&pdev->dev);
 
 	/* reset dma controller */
-	err = sh_dmae_rst(0);
+	err = sh_dmae_rst(shdev);
 	if (err)
 		goto rst_err;
 
-	/* SH7780/85/23 has DMAOR1 */
-	if (shdev->pdata.mode & SHDMA_DMAOR1) {
-		err = sh_dmae_rst(1);
-		if (err)
-			goto rst_err;
-	}
-
 	INIT_LIST_HEAD(&shdev->common.channels);
 
 	dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask);
+	if (dmars)
+		dma_cap_set(DMA_SLAVE, shdev->common.cap_mask);
+
 	shdev->common.device_alloc_chan_resources
 		= sh_dmae_alloc_chan_resources;
 	shdev->common.device_free_chan_resources = sh_dmae_free_chan_resources;
 	shdev->common.device_prep_dma_memcpy = sh_dmae_prep_memcpy;
 	shdev->common.device_is_tx_complete = sh_dmae_is_complete;
 	shdev->common.device_issue_pending = sh_dmae_memcpy_issue_pending;
+
+	/* Compulsory for DMA_SLAVE fields */
+	shdev->common.device_prep_slave_sg = sh_dmae_prep_slave_sg;
+	shdev->common.device_terminate_all = sh_dmae_terminate_all;
+
 	shdev->common.dev = &pdev->dev;
 	/* Default transfer size of 32 bytes requires 32-byte alignment */
-	shdev->common.copy_align = 5;
+	shdev->common.copy_align = LOG2_DEFAULT_XFER_SIZE;
 
 #if defined(CONFIG_CPU_SH4)
-	/* Non Mix IRQ mode SH7722/SH7730 etc... */
-	if (shdev->pdata.mode & SHDMA_MIX_IRQ) {
+	chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+
+	if (!chanirq_res)
+		chanirq_res = errirq_res;
+	else
+		irqres++;
+
+	if (chanirq_res == errirq_res ||
+	    (errirq_res->flags & IORESOURCE_BITS) == IORESOURCE_IRQ_SHAREABLE)
 		irqflags = IRQF_SHARED;
-		eirq[0] = DMTE0_IRQ;
-#if defined(DMTE6_IRQ) && defined(DMAE1_IRQ)
-		eirq[1] = DMTE6_IRQ;
-#endif
+
+	errirq = errirq_res->start;
+
+	err = request_irq(errirq, sh_dmae_err, irqflags,
+			  "DMAC Address Error", shdev);
+	if (err) {
+		dev_err(&pdev->dev,
+			"DMA failed requesting irq #%d, error %d\n",
+			errirq, err);
+		goto eirq_err;
 	}
 
-	for (ecnt = 0 ; ecnt < ARRAY_SIZE(eirq); ecnt++) {
-		err = request_irq(eirq[ecnt], sh_dmae_err, irqflags,
-				  "DMAC Address Error", shdev);
-		if (err) {
-			dev_err(&pdev->dev, "DMA device request_irq"
-				"error (irq %d) with return %d\n",
-				eirq[ecnt], err);
-			goto eirq_err;
+#else
+	chanirq_res = errirq_res;
+#endif /* CONFIG_CPU_SH4 */
+
+	if (chanirq_res->start == chanirq_res->end &&
+	    !platform_get_resource(pdev, IORESOURCE_IRQ, 1)) {
+		/* Special case - all multiplexed */
+		for (; irq_cnt < pdata->channel_num; irq_cnt++) {
+			chan_irq[irq_cnt] = chanirq_res->start;
+			chan_flag[irq_cnt] = IRQF_SHARED;
 		}
+	} else {
+		do {
+			for (i = chanirq_res->start; i <= chanirq_res->end; i++) {
+				if ((errirq_res->flags & IORESOURCE_BITS) ==
+				    IORESOURCE_IRQ_SHAREABLE)
+					chan_flag[irq_cnt] = IRQF_SHARED;
+				else
+					chan_flag[irq_cnt] = IRQF_DISABLED;
+				dev_dbg(&pdev->dev,
+					"Found IRQ %d for channel %d\n",
+					i, irq_cnt);
+				chan_irq[irq_cnt++] = i;
+			}
+			chanirq_res = platform_get_resource(pdev,
+						IORESOURCE_IRQ, ++irqres);
+		} while (irq_cnt < pdata->channel_num && chanirq_res);
 	}
-#endif /* CONFIG_CPU_SH4 */
+
+	if (irq_cnt < pdata->channel_num)
+		goto eirqres;
 
 	/* Create DMA Channel */
-	for (cnt = 0 ; cnt < MAX_DMA_CHANNELS ; cnt++) {
-		err = sh_dmae_chan_probe(shdev, cnt);
+	for (i = 0; i < pdata->channel_num; i++) {
+		err = sh_dmae_chan_probe(shdev, i, chan_irq[i], chan_flag[i]);
 		if (err)
 			goto chan_probe_err;
 	}
 
+	pm_runtime_put(&pdev->dev);
+
 	platform_set_drvdata(pdev, shdev);
 	dma_async_device_register(&shdev->common);
 
@@ -805,13 +1122,24 @@ static int __init sh_dmae_probe(struct p
 
 chan_probe_err:
 	sh_dmae_chan_remove(shdev);
-
+eirqres:
+#if defined(CONFIG_CPU_SH4)
+	free_irq(errirq, shdev);
 eirq_err:
-	for (ecnt-- ; ecnt >= 0; ecnt--)
-		free_irq(eirq[ecnt], shdev);
-
+#endif
 rst_err:
+	pm_runtime_put(&pdev->dev);
+	if (dmars)
+		iounmap(shdev->dmars);
+emapdmars:
+	iounmap(shdev->chan_reg);
+emapchan:
 	kfree(shdev);
+ealloc:
+	if (dmars)
+		release_mem_region(dmars->start, resource_size(dmars));
+ermrdmars:
+	release_mem_region(chan->start, resource_size(chan));
 
 	return err;
 }
@@ -819,36 +1147,39 @@ rst_err:
 static int __exit sh_dmae_remove(struct platform_device *pdev)
 {
 	struct sh_dmae_device *shdev = platform_get_drvdata(pdev);
+	struct resource *res;
+	int errirq = platform_get_irq(pdev, 0);
 
 	dma_async_device_unregister(&shdev->common);
 
-	if (shdev->pdata.mode & SHDMA_MIX_IRQ) {
-		free_irq(DMTE0_IRQ, shdev);
-#if defined(DMTE6_IRQ)
-		free_irq(DMTE6_IRQ, shdev);
-#endif
-	}
+	if (errirq > 0)
+		free_irq(errirq, shdev);
 
 	/* channel data remove */
 	sh_dmae_chan_remove(shdev);
 
-	if (!(shdev->pdata.mode & SHDMA_MIX_IRQ)) {
-		free_irq(DMAE0_IRQ, shdev);
-#if defined(DMAE1_IRQ)
-		free_irq(DMAE1_IRQ, shdev);
-#endif
-	}
+	pm_runtime_disable(&pdev->dev);
+
+	if (shdev->dmars)
+		iounmap(shdev->dmars);
+	iounmap(shdev->chan_reg);
+
 	kfree(shdev);
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res)
+		release_mem_region(res->start, resource_size(res));
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (res)
+		release_mem_region(res->start, resource_size(res));
+
 	return 0;
 }
 
 static void sh_dmae_shutdown(struct platform_device *pdev)
 {
 	struct sh_dmae_device *shdev = platform_get_drvdata(pdev);
-	sh_dmae_ctl_stop(0);
-	if (shdev->pdata.mode & SHDMA_DMAOR1)
-		sh_dmae_ctl_stop(1);
+	sh_dmae_ctl_stop(shdev);
 }
 
 static struct platform_driver sh_dmae_driver = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/shdma.h linux-libre-2.6.34-gnu1/drivers/dma/shdma.h
--- linux-libre-2.6.33-gnu1/drivers/dma/shdma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/shdma.h	2010-05-16 17:17:36.000000000 -0400
@@ -17,22 +17,9 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 
-#define SH_DMA_TCR_MAX 0x00FFFFFF	/* 16MB */
-
-struct sh_dmae_regs {
-	u32 sar; /* SAR / source address */
-	u32 dar; /* DAR / destination address */
-	u32 tcr; /* TCR / transfer count */
-};
+#include <asm/dmaengine.h>
 
-struct sh_desc {
-	struct sh_dmae_regs hw;
-	struct list_head node;
-	struct dma_async_tx_descriptor async_tx;
-	dma_cookie_t cookie;
-	int chunks;
-	int mark;
-};
+#define SH_DMA_TCR_MAX 0x00FFFFFF	/* 16MB */
 
 struct device;
 
@@ -45,19 +32,19 @@ struct sh_dmae_chan {
 	struct device *dev;		/* Channel device */
 	struct tasklet_struct tasklet;	/* Tasklet */
 	int descs_allocated;		/* desc count */
+	int xmit_shift;			/* log_2(bytes_per_xfer) */
+	int irq;
 	int id;				/* Raw id of this channel */
+	u32 __iomem *base;
 	char dev_id[16];		/* unique name per DMAC of channel */
-
-	/* Set chcr */
-	int (*set_chcr)(struct sh_dmae_chan *sh_chan, u32 regs);
-	/* Set DMA resource */
-	int (*set_dmars)(struct sh_dmae_chan *sh_chan, u16 res);
 };
 
 struct sh_dmae_device {
 	struct dma_device common;
-	struct sh_dmae_chan *chan[MAX_DMA_CHANNELS];
-	struct sh_dmae_pdata pdata;
+	struct sh_dmae_chan *chan[SH_DMAC_MAX_CHANNELS];
+	struct sh_dmae_pdata *pdata;
+	u32 __iomem *chan_reg;
+	u16 __iomem *dmars;
 };
 
 #define to_sh_chan(chan) container_of(chan, struct sh_dmae_chan, common)
diff -druNp linux-libre-2.6.33-gnu1/drivers/dma/txx9dmac.c linux-libre-2.6.34-gnu1/drivers/dma/txx9dmac.c
--- linux-libre-2.6.33-gnu1/drivers/dma/txx9dmac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/dma/txx9dmac.c	2010-05-16 17:17:36.000000000 -0400
@@ -1359,3 +1359,5 @@ module_exit(txx9dmac_exit);
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("TXx9 DMA Controller driver");
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
+MODULE_ALIAS("platform:txx9dmac");
+MODULE_ALIAS("platform:txx9dmac-chan");
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/amd64_edac.c linux-libre-2.6.34-gnu1/drivers/edac/amd64_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/amd64_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/amd64_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,7 @@ module_param(report_gart_errors, int, 06
 static int ecc_enable_override;
 module_param(ecc_enable_override, int, 0644);
 
-static struct msr *msrs;
+static struct msr __percpu *msrs;
 
 /* Lookup table for all possible MC control instances */
 struct amd64_pvt;
@@ -2553,14 +2553,14 @@ static int amd64_toggle_ecc_err_reportin
 
 		if (on) {
 			if (reg->l & K8_MSR_MCGCTL_NBE)
-				pvt->flags.ecc_report = 1;
+				pvt->flags.nb_mce_enable = 1;
 
 			reg->l |= K8_MSR_MCGCTL_NBE;
 		} else {
 			/*
-			 * Turn off ECC reporting only when it was off before
+			 * Turn off NB MCE reporting only when it was off before
 			 */
-			if (!pvt->flags.ecc_report)
+			if (!pvt->flags.nb_mce_enable)
 				reg->l &= ~K8_MSR_MCGCTL_NBE;
 		}
 	}
@@ -2571,22 +2571,11 @@ static int amd64_toggle_ecc_err_reportin
 	return 0;
 }
 
-/*
- * Only if 'ecc_enable_override' is set AND BIOS had ECC disabled, do "we"
- * enable it.
- */
 static void amd64_enable_ecc_error_reporting(struct mem_ctl_info *mci)
 {
 	struct amd64_pvt *pvt = mci->pvt_info;
 	u32 value, mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
 
-	if (!ecc_enable_override)
-		return;
-
-	amd64_printk(KERN_WARNING,
-		"'ecc_enable_override' parameter is active, "
-		"Enabling AMD ECC hardware now: CAUTION\n");
-
 	amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCTL, &value);
 
 	/* turn on UECCn and CECCEn bits */
@@ -2611,6 +2600,8 @@ static void amd64_enable_ecc_error_repor
 			"This node reports that DRAM ECC is "
 			"currently Disabled; ENABLING now\n");
 
+		pvt->flags.nb_ecc_prev = 0;
+
 		/* Attempt to turn on DRAM ECC Enable */
 		value |= K8_NBCFG_ECC_ENABLE;
 		pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCFG, value);
@@ -2625,7 +2616,10 @@ static void amd64_enable_ecc_error_repor
 			amd64_printk(KERN_DEBUG,
 				"Hardware accepted DRAM ECC Enable\n");
 		}
+	} else {
+		pvt->flags.nb_ecc_prev = 1;
 	}
+
 	debugf0("NBCFG(2)= 0x%x  CHIPKILL= %s ECC_ENABLE= %s\n", value,
 		(value & K8_NBCFG_CHIPKILL) ? "Enabled" : "Disabled",
 		(value & K8_NBCFG_ECC_ENABLE) ? "Enabled" : "Disabled");
@@ -2644,12 +2638,18 @@ static void amd64_restore_ecc_error_repo
 	value &= ~mask;
 	value |= pvt->old_nbctl;
 
-	/* restore the NB Enable MCGCTL bit */
 	pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCTL, value);
 
+	/* restore previous BIOS DRAM ECC "off" setting which we force-enabled */
+	if (!pvt->flags.nb_ecc_prev) {
+		amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCFG, &value);
+		value &= ~K8_NBCFG_ECC_ENABLE;
+		pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCFG, value);
+	}
+
+	/* restore the NB Enable MCGCTL bit */
 	if (amd64_toggle_ecc_err_reporting(pvt, OFF))
-		amd64_printk(KERN_WARNING, "Error restoring ECC reporting over "
-					   "MCGCTL!\n");
+		amd64_printk(KERN_WARNING, "Error restoring NB MCGCTL settings!\n");
 }
 
 /*
@@ -2690,8 +2690,9 @@ static int amd64_check_ecc_enabled(struc
 		if (!ecc_enable_override) {
 			amd64_printk(KERN_NOTICE, "%s", ecc_msg);
 			return -ENODEV;
+		} else {
+			amd64_printk(KERN_WARNING, "Forcing ECC checking on!\n");
 		}
-		ecc_enable_override = 0;
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/amd64_edac.h linux-libre-2.6.34-gnu1/drivers/edac/amd64_edac.h
--- linux-libre-2.6.33-gnu1/drivers/edac/amd64_edac.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/amd64_edac.h	2010-05-16 17:17:36.000000000 -0400
@@ -487,7 +487,8 @@ struct amd64_pvt {
 	/* misc settings */
 	struct flags {
 		unsigned long cf8_extcfg:1;
-		unsigned long ecc_report:1;
+		unsigned long nb_mce_enable:1;
+		unsigned long nb_ecc_prev:1;
 	} flags;
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/amd76x_edac.c linux-libre-2.6.34-gnu1/drivers/edac/amd76x_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/amd76x_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/amd76x_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/cpc925_edac.c linux-libre-2.6.34-gnu1/drivers/edac/cpc925_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/cpc925_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/cpc925_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/edac.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/gfp.h>
 
 #include "edac_core.h"
 #include "edac_module.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/e752x_edac.c linux-libre-2.6.34-gnu1/drivers/edac/e752x_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/e752x_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/e752x_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
@@ -75,6 +74,14 @@ static struct edac_pci_ctl_info *e752x_p
 #define E752X_NR_CSROWS		8	/* number of csrows */
 
 /* E752X register addresses - device 0 function 0 */
+#define E752X_MCHSCRB		0x52	/* Memory Scrub register (16b) */
+					/*
+					 * 6:5     Scrub Completion Count
+					 * 3:2     Scrub Rate (i3100 only)
+					 *      01=fast 10=normal
+					 * 1:0     Scrub Mode enable
+					 *      00=off 10=on
+					 */
 #define E752X_DRB		0x60	/* DRAM row boundary register (8b) */
 #define E752X_DRA		0x70	/* DRAM row attribute register (8b) */
 					/*
@@ -240,6 +247,41 @@ static const struct e752x_dev_info e752x
 		.ctl_name = "3100"},
 };
 
+/* Valid scrub rates for the e752x/3100 hardware memory scrubber. We
+ * map the scrubbing bandwidth to a hardware register value. The 'set'
+ * operation finds the 'matching or higher value'.  Note that scrubbing
+ * on the e752x can only be enabled/disabled.  The 3100 supports
+ * a normal and fast mode.
+ */
+
+#define SDRATE_EOT 0xFFFFFFFF
+
+struct scrubrate {
+	u32 bandwidth;	/* bandwidth consumed by scrubbing in bytes/sec */
+	u16 scrubval;	/* register value for scrub rate */
+};
+
+/* Rate below assumes same performance as i3100 using PC3200 DDR2 in
+ * normal mode.  e752x bridges don't support choosing normal or fast mode,
+ * so the scrubbing bandwidth value isn't all that important - scrubbing is
+ * either on or off.
+ */
+static const struct scrubrate scrubrates_e752x[] = {
+	{0,		0x00},	/* Scrubbing Off */
+	{500000,	0x02},	/* Scrubbing On */
+	{SDRATE_EOT,	0x00}	/* End of Table */
+};
+
+/* Fast mode: 2 GByte PC3200 DDR2 scrubbed in 33s = 63161283 bytes/s
+ * Normal mode: 125 (32000 / 256) times slower than fast mode.
+ */
+static const struct scrubrate scrubrates_i3100[] = {
+	{0,		0x00},	/* Scrubbing Off */
+	{500000,	0x0a},	/* Normal mode - 32k clocks */
+	{62500000,	0x06},	/* Fast mode - 256 clocks */
+	{SDRATE_EOT,	0x00}	/* End of Table */
+};
+
 static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci,
 				unsigned long page)
 {
@@ -915,6 +957,68 @@ static void e752x_check(struct mem_ctl_i
 	e752x_process_error_info(mci, &info, 1);
 }
 
+/* Program byte/sec bandwidth scrub rate to hardware */
+static int set_sdram_scrub_rate(struct mem_ctl_info *mci, u32 *new_bw)
+{
+	const struct scrubrate *scrubrates;
+	struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info;
+	struct pci_dev *pdev = pvt->dev_d0f0;
+	int i;
+
+	if (pvt->dev_info->ctl_dev == PCI_DEVICE_ID_INTEL_3100_0)
+		scrubrates = scrubrates_i3100;
+	else
+		scrubrates = scrubrates_e752x;
+
+	/* Translate the desired scrub rate to a e752x/3100 register value.
+	 * Search for the bandwidth that is equal or greater than the
+	 * desired rate and program the cooresponding register value.
+	 */
+	for (i = 0; scrubrates[i].bandwidth != SDRATE_EOT; i++)
+		if (scrubrates[i].bandwidth >= *new_bw)
+			break;
+
+	if (scrubrates[i].bandwidth == SDRATE_EOT)
+		return -1;
+
+	pci_write_config_word(pdev, E752X_MCHSCRB, scrubrates[i].scrubval);
+
+	return 0;
+}
+
+/* Convert current scrub rate value into byte/sec bandwidth */
+static int get_sdram_scrub_rate(struct mem_ctl_info *mci, u32 *bw)
+{
+	const struct scrubrate *scrubrates;
+	struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info;
+	struct pci_dev *pdev = pvt->dev_d0f0;
+	u16 scrubval;
+	int i;
+
+	if (pvt->dev_info->ctl_dev == PCI_DEVICE_ID_INTEL_3100_0)
+		scrubrates = scrubrates_i3100;
+	else
+		scrubrates = scrubrates_e752x;
+
+	/* Find the bandwidth matching the memory scrubber configuration */
+	pci_read_config_word(pdev, E752X_MCHSCRB, &scrubval);
+	scrubval = scrubval & 0x0f;
+
+	for (i = 0; scrubrates[i].bandwidth != SDRATE_EOT; i++)
+		if (scrubrates[i].scrubval == scrubval)
+			break;
+
+	if (scrubrates[i].bandwidth == SDRATE_EOT) {
+		e752x_printk(KERN_WARNING,
+			"Invalid sdram scrub control value: 0x%x\n", scrubval);
+		return -1;
+	}
+
+	*bw = scrubrates[i].bandwidth;
+
+	return 0;
+}
+
 /* Return 1 if dual channel mode is active.  Else return 0. */
 static inline int dual_channel_active(u16 ddrcsr)
 {
@@ -1073,10 +1177,7 @@ fail:
 
 /* Setup system bus parity mask register.
  * Sysbus parity supported on:
- *   e7320/e7520/e7525 + Xeon
- *   i3100 + Xeon/Celeron
- * Sysbus parity not supported on:
- *   i3100 + Pentium M/Celeron M/Core Duo/Core2 Duo
+ * e7320/e7520/e7525 + Xeon
  */
 static void e752x_init_sysbus_parity_mask(struct e752x_pvt *pvt)
 {
@@ -1087,10 +1188,7 @@ static void e752x_init_sysbus_parity_mas
 	/* Allow module parameter override, else see if CPU supports parity */
 	if (sysbus_parity != -1) {
 		enable = sysbus_parity;
-	} else if (cpu_id[0] &&
-		   ((strstr(cpu_id, "Pentium") && strstr(cpu_id, " M ")) ||
-		    (strstr(cpu_id, "Celeron") && strstr(cpu_id, " M ")) ||
-		    (strstr(cpu_id, "Core") && strstr(cpu_id, "Duo")))) {
+	} else if (cpu_id[0] && !strstr(cpu_id, "Xeon")) {
 		e752x_printk(KERN_INFO, "System Bus Parity not "
 			     "supported by CPU, disabling\n");
 		enable = 0;
@@ -1187,6 +1285,8 @@ static int e752x_probe1(struct pci_dev *
 	mci->dev_name = pci_name(pdev);
 	mci->edac_check = e752x_check;
 	mci->ctl_page_to_phys = ctl_page_to_phys;
+	mci->set_sdram_scrub_rate = set_sdram_scrub_rate;
+	mci->get_sdram_scrub_rate = get_sdram_scrub_rate;
 
 	/* set the map type.  1 = normal, 0 = reversed
 	 * Must be set before e752x_init_csrows in case csrow mapping
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/e7xxx_edac.c linux-libre-2.6.34-gnu1/drivers/edac/e7xxx_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/e7xxx_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/e7xxx_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/edac_device_sysfs.c linux-libre-2.6.34-gnu1/drivers/edac/edac_device_sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/edac/edac_device_sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/edac_device_sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 
 #include <linux/ctype.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "edac_core.h"
 #include "edac_module.h"
@@ -137,7 +138,7 @@ static ssize_t edac_dev_ctl_info_store(s
 }
 
 /* edac_dev file operations for an 'ctl_info' */
-static struct sysfs_ops device_ctl_info_ops = {
+static const struct sysfs_ops device_ctl_info_ops = {
 	.show = edac_dev_ctl_info_show,
 	.store = edac_dev_ctl_info_store
 };
@@ -373,7 +374,7 @@ static ssize_t edac_dev_instance_store(s
 }
 
 /* edac_dev file operations for an 'instance' */
-static struct sysfs_ops device_instance_ops = {
+static const struct sysfs_ops device_instance_ops = {
 	.show = edac_dev_instance_show,
 	.store = edac_dev_instance_store
 };
@@ -476,7 +477,7 @@ static ssize_t edac_dev_block_store(stru
 }
 
 /* edac_dev file operations for a 'block' */
-static struct sysfs_ops device_block_ops = {
+static const struct sysfs_ops device_block_ops = {
 	.show = edac_dev_block_show,
 	.store = edac_dev_block_store
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/edac_mce_amd.c linux-libre-2.6.34-gnu1/drivers/edac/edac_mce_amd.c
--- linux-libre-2.6.33-gnu1/drivers/edac/edac_mce_amd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/edac_mce_amd.c	2010-05-16 17:17:36.000000000 -0400
@@ -294,7 +294,6 @@ wrong_ls_mce:
 void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
 {
 	u32 ec  = ERROR_CODE(regs->nbsl);
-	u32 xec = EXT_ERROR_CODE(regs->nbsl);
 
 	if (!handle_errors)
 		return;
@@ -316,10 +315,15 @@ void amd_decode_nb_mce(int node_id, stru
 		if (regs->nbsh & K8_NBSH_ERR_CPU_VAL)
 			pr_cont(", core: %u\n", (u8)(regs->nbsh & 0xf));
 	} else {
-		pr_cont(", core: %d\n", fls((regs->nbsh & 0xf) - 1));
+		u8 assoc_cpus = regs->nbsh & 0xf;
+
+		if (assoc_cpus > 0)
+			pr_cont(", core: %d", fls(assoc_cpus) - 1);
+
+		pr_cont("\n");
 	}
 
-	pr_emerg("%s.\n", EXT_ERR_MSG(xec));
+	pr_emerg("%s.\n", EXT_ERR_MSG(regs->nbsl));
 
 	if (BUS_ERROR(ec) && nb_bus_decoder)
 		nb_bus_decoder(node_id, regs);
@@ -369,7 +373,7 @@ static int amd_decode_mce(struct notifie
 		 ((m->status & MCI_STATUS_PCC) ? "yes" : "no"));
 
 	/* do the two bits[14:13] together */
-	ecc = m->status & (3ULL << 45);
+	ecc = (m->status >> 45) & 0x3;
 	if (ecc)
 		pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/edac_mc_sysfs.c linux-libre-2.6.34-gnu1/drivers/edac/edac_mc_sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/edac/edac_mc_sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/edac_mc_sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <linux/bug.h>
 
 #include "edac_core.h"
@@ -245,7 +246,7 @@ static ssize_t csrowdev_store(struct kob
 	return -EIO;
 }
 
-static struct sysfs_ops csrowfs_ops = {
+static const struct sysfs_ops csrowfs_ops = {
 	.show = csrowdev_show,
 	.store = csrowdev_store
 };
@@ -575,7 +576,7 @@ static ssize_t mcidev_store(struct kobje
 }
 
 /* Intermediate show/store table */
-static struct sysfs_ops mci_ops = {
+static const struct sysfs_ops mci_ops = {
 	.show = mcidev_show,
 	.store = mcidev_store
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/edac_pci_sysfs.c linux-libre-2.6.34-gnu1/drivers/edac/edac_pci_sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/edac/edac_pci_sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/edac_pci_sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  */
 #include <linux/module.h>
 #include <linux/sysdev.h>
+#include <linux/slab.h>
 #include <linux/ctype.h>
 
 #include "edac_core.h"
@@ -121,7 +122,7 @@ static ssize_t edac_pci_instance_store(s
 }
 
 /* fs_ops table */
-static struct sysfs_ops pci_instance_ops = {
+static const struct sysfs_ops pci_instance_ops = {
 	.show = edac_pci_instance_show,
 	.store = edac_pci_instance_store
 };
@@ -261,7 +262,7 @@ static ssize_t edac_pci_dev_store(struct
 	return -EIO;
 }
 
-static struct sysfs_ops edac_pci_sysfs_ops = {
+static const struct sysfs_ops edac_pci_sysfs_ops = {
 	.show = edac_pci_dev_show,
 	.store = edac_pci_dev_store
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/i3000_edac.c linux-libre-2.6.34-gnu1/drivers/edac/i3000_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/i3000_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/i3000_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/i3200_edac.c linux-libre-2.6.34-gnu1/drivers/edac/i3200_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/i3200_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/i3200_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include <linux/io.h>
 #include "edac_core.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/i5100_edac.c linux-libre-2.6.34-gnu1/drivers/edac/i5100_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/i5100_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/i5100_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include <linux/delay.h>
 #include <linux/mmzone.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/i82443bxgx_edac.c linux-libre-2.6.34-gnu1/drivers/edac/i82443bxgx_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/i82443bxgx_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/i82443bxgx_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
 
-#include <linux/slab.h>
 
 #include <linux/edac.h>
 #include "edac_core.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/i82860_edac.c linux-libre-2.6.34-gnu1/drivers/edac/i82860_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/i82860_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/i82860_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/i82875p_edac.c linux-libre-2.6.34-gnu1/drivers/edac/i82875p_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/i82875p_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/i82875p_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/i82975x_edac.c linux-libre-2.6.34-gnu1/drivers/edac/i82975x_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/i82975x_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/i82975x_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/mpc85xx_edac.c linux-libre-2.6.34-gnu1/drivers/edac/mpc85xx_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/mpc85xx_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/mpc85xx_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,13 +11,13 @@
  */
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/ctype.h>
 #include <linux/io.h>
 #include <linux/mod_devicetable.h>
 #include <linux/edac.h>
 #include <linux/smp.h>
+#include <linux/gfp.h>
 
 #include <linux/of_platform.h>
 #include <linux/of_device.h>
@@ -239,16 +239,15 @@ static int __devinit mpc85xx_pci_err_pro
 	/* we only need the error registers */
 	r.start += 0xe00;
 
-	if (!devm_request_mem_region(&op->dev, r.start,
-					r.end - r.start + 1, pdata->name)) {
+	if (!devm_request_mem_region(&op->dev, r.start, resource_size(&r),
+					pdata->name)) {
 		printk(KERN_ERR "%s: Error while requesting mem region\n",
 		       __func__);
 		res = -EBUSY;
 		goto err;
 	}
 
-	pdata->pci_vbase = devm_ioremap(&op->dev, r.start,
-					r.end - r.start + 1);
+	pdata->pci_vbase = devm_ioremap(&op->dev, r.start, resource_size(&r));
 	if (!pdata->pci_vbase) {
 		printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__);
 		res = -ENOMEM;
@@ -668,15 +667,125 @@ static struct of_platform_driver mpc85xx
 
 /**************************** MC Err device ***************************/
 
+/*
+ * Taken from table 8-55 in the MPC8641 User's Manual and/or 9-61 in the
+ * MPC8572 User's Manual.  Each line represents a syndrome bit column as a
+ * 64-bit value, but split into an upper and lower 32-bit chunk.  The labels
+ * below correspond to Freescale's manuals.
+ */
+static unsigned int ecc_table[16] = {
+	/* MSB           LSB */
+	/* [0:31]    [32:63] */
+	0xf00fe11e, 0xc33c0ff7,	/* Syndrome bit 7 */
+	0x00ff00ff, 0x00fff0ff,
+	0x0f0f0f0f, 0x0f0fff00,
+	0x11113333, 0x7777000f,
+	0x22224444, 0x8888222f,
+	0x44448888, 0xffff4441,
+	0x8888ffff, 0x11118882,
+	0xffff1111, 0x22221114,	/* Syndrome bit 0 */
+};
+
+/*
+ * Calculate the correct ECC value for a 64-bit value specified by high:low
+ */
+static u8 calculate_ecc(u32 high, u32 low)
+{
+	u32 mask_low;
+	u32 mask_high;
+	int bit_cnt;
+	u8 ecc = 0;
+	int i;
+	int j;
+
+	for (i = 0; i < 8; i++) {
+		mask_high = ecc_table[i * 2];
+		mask_low = ecc_table[i * 2 + 1];
+		bit_cnt = 0;
+
+		for (j = 0; j < 32; j++) {
+			if ((mask_high >> j) & 1)
+				bit_cnt ^= (high >> j) & 1;
+			if ((mask_low >> j) & 1)
+				bit_cnt ^= (low >> j) & 1;
+		}
+
+		ecc |= bit_cnt << i;
+	}
+
+	return ecc;
+}
+
+/*
+ * Create the syndrome code which is generated if the data line specified by
+ * 'bit' failed.  Eg generate an 8-bit codes seen in Table 8-55 in the MPC8641
+ * User's Manual and 9-61 in the MPC8572 User's Manual.
+ */
+static u8 syndrome_from_bit(unsigned int bit) {
+	int i;
+	u8 syndrome = 0;
+
+	/*
+	 * Cycle through the upper or lower 32-bit portion of each value in
+	 * ecc_table depending on if 'bit' is in the upper or lower half of
+	 * 64-bit data.
+	 */
+	for (i = bit < 32; i < 16; i += 2)
+		syndrome |= ((ecc_table[i] >> (bit % 32)) & 1) << (i / 2);
+
+	return syndrome;
+}
+
+/*
+ * Decode data and ecc syndrome to determine what went wrong
+ * Note: This can only decode single-bit errors
+ */
+static void sbe_ecc_decode(u32 cap_high, u32 cap_low, u32 cap_ecc,
+		       int *bad_data_bit, int *bad_ecc_bit)
+{
+	int i;
+	u8 syndrome;
+
+	*bad_data_bit = -1;
+	*bad_ecc_bit = -1;
+
+	/*
+	 * Calculate the ECC of the captured data and XOR it with the captured
+	 * ECC to find an ECC syndrome value we can search for
+	 */
+	syndrome = calculate_ecc(cap_high, cap_low) ^ cap_ecc;
+
+	/* Check if a data line is stuck... */
+	for (i = 0; i < 64; i++) {
+		if (syndrome == syndrome_from_bit(i)) {
+			*bad_data_bit = i;
+			return;
+		}
+	}
+
+	/* If data is correct, check ECC bits for errors... */
+	for (i = 0; i < 8; i++) {
+		if ((syndrome >> i) & 0x1) {
+			*bad_ecc_bit = i;
+			return;
+		}
+	}
+}
+
 static void mpc85xx_mc_check(struct mem_ctl_info *mci)
 {
 	struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
 	struct csrow_info *csrow;
+	u32 bus_width;
 	u32 err_detect;
 	u32 syndrome;
 	u32 err_addr;
 	u32 pfn;
 	int row_index;
+	u32 cap_high;
+	u32 cap_low;
+	int bad_data_bit;
+	int bad_ecc_bit;
 
 	err_detect = in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT);
 	if (!err_detect)
@@ -692,6 +801,15 @@ static void mpc85xx_mc_check(struct mem_
 	}
 
 	syndrome = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_ECC);
+
+	/* Mask off appropriate bits of syndrome based on bus width */
+	bus_width = (in_be32(pdata->mc_vbase + MPC85XX_MC_DDR_SDRAM_CFG) &
+			DSC_DBW_MASK) ? 32 : 64;
+	if (bus_width == 64)
+		syndrome &= 0xff;
+	else
+		syndrome &= 0xffff;
+
 	err_addr = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_ADDRESS);
 	pfn = err_addr >> PAGE_SHIFT;
 
@@ -701,14 +819,35 @@ static void mpc85xx_mc_check(struct mem_
 			break;
 	}
 
-	mpc85xx_mc_printk(mci, KERN_ERR, "Capture Data High: %#8.8x\n",
-			  in_be32(pdata->mc_vbase +
-				  MPC85XX_MC_CAPTURE_DATA_HI));
-	mpc85xx_mc_printk(mci, KERN_ERR, "Capture Data Low: %#8.8x\n",
-			  in_be32(pdata->mc_vbase +
-				  MPC85XX_MC_CAPTURE_DATA_LO));
-	mpc85xx_mc_printk(mci, KERN_ERR, "syndrome: %#8.8x\n", syndrome);
-	mpc85xx_mc_printk(mci, KERN_ERR, "err addr: %#8.8x\n", err_addr);
+	cap_high = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_DATA_HI);
+	cap_low = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_DATA_LO);
+
+	/*
+	 * Analyze single-bit errors on 64-bit wide buses
+	 * TODO: Add support for 32-bit wide buses
+	 */
+	if ((err_detect & DDR_EDE_SBE) && (bus_width == 64)) {
+		sbe_ecc_decode(cap_high, cap_low, syndrome,
+				&bad_data_bit, &bad_ecc_bit);
+
+		if (bad_data_bit != -1)
+			mpc85xx_mc_printk(mci, KERN_ERR,
+				"Faulty Data bit: %d\n", bad_data_bit);
+		if (bad_ecc_bit != -1)
+			mpc85xx_mc_printk(mci, KERN_ERR,
+				"Faulty ECC bit: %d\n", bad_ecc_bit);
+
+		mpc85xx_mc_printk(mci, KERN_ERR,
+			"Expected Data / ECC:\t%#8.8x_%08x / %#2.2x\n",
+			cap_high ^ (1 << (bad_data_bit - 32)),
+			cap_low ^ (1 << bad_data_bit),
+			syndrome ^ (1 << bad_ecc_bit));
+	}
+
+	mpc85xx_mc_printk(mci, KERN_ERR,
+			"Captured Data / ECC:\t%#8.8x_%08x / %#2.2x\n",
+			cap_high, cap_low, syndrome);
+	mpc85xx_mc_printk(mci, KERN_ERR, "Err addr: %#8.8x\n", err_addr);
 	mpc85xx_mc_printk(mci, KERN_ERR, "PFN: %#8.8x\n", pfn);
 
 	/* we are out of range */
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/mpc85xx_edac.h linux-libre-2.6.34-gnu1/drivers/edac/mpc85xx_edac.h
--- linux-libre-2.6.33-gnu1/drivers/edac/mpc85xx_edac.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/mpc85xx_edac.h	2010-05-16 17:17:36.000000000 -0400
@@ -48,6 +48,9 @@
 #define DSC_MEM_EN	0x80000000
 #define DSC_ECC_EN	0x20000000
 #define DSC_RD_EN	0x10000000
+#define DSC_DBW_MASK	0x00180000
+#define DSC_DBW_32	0x00080000
+#define DSC_DBW_64	0x00000000
 
 #define DSC_SDTYPE_MASK		0x07000000
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/mv64x60_edac.c linux-libre-2.6.34-gnu1/drivers/edac/mv64x60_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/mv64x60_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/mv64x60_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,10 +12,10 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/edac.h>
+#include <linux/gfp.h>
 
 #include "edac_core.h"
 #include "edac_module.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/pasemi_edac.c linux-libre-2.6.34-gnu1/drivers/edac/pasemi_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/pasemi_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/pasemi_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/r82600_edac.c linux-libre-2.6.34-gnu1/drivers/edac/r82600_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/r82600_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/r82600_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/edac/x38_edac.c linux-libre-2.6.34-gnu1/drivers/edac/x38_edac.c
--- linux-libre-2.6.33-gnu1/drivers/edac/x38_edac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/edac/x38_edac.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/eisa/eisa-bus.c linux-libre-2.6.34-gnu1/drivers/eisa/eisa-bus.c
--- linux-libre-2.6.33-gnu1/drivers/eisa/eisa-bus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/eisa/eisa-bus.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,10 +39,10 @@ static unsigned int enable_dev_count;
 static int disable_dev[EISA_MAX_FORCED_DEV];
 static unsigned int disable_dev_count;
 
-static int is_forced_dev (int *forced_tab,
-			  int forced_count,
-			  struct eisa_root_device *root,
-			  struct eisa_device *edev)
+static int is_forced_dev(int *forced_tab,
+			 int forced_count,
+			 struct eisa_root_device *root,
+			 struct eisa_device *edev)
 {
 	int i, x;
 
@@ -55,21 +55,21 @@ static int is_forced_dev (int *forced_ta
 	return 0;
 }
 
-static void __init eisa_name_device (struct eisa_device *edev)
+static void __init eisa_name_device(struct eisa_device *edev)
 {
 #ifdef CONFIG_EISA_NAMES
 	int i;
 	for (i = 0; i < EISA_INFOS; i++) {
-		if (!strcmp (edev->id.sig, eisa_table[i].id.sig)) {
-			strlcpy (edev->pretty_name,
-				 eisa_table[i].name,
-				 sizeof(edev->pretty_name));
+		if (!strcmp(edev->id.sig, eisa_table[i].id.sig)) {
+			strlcpy(edev->pretty_name,
+				eisa_table[i].name,
+				sizeof(edev->pretty_name));
 			return;
 		}
 	}
 
 	/* No name was found */
-	sprintf (edev->pretty_name, "EISA device %.7s", edev->id.sig);
+	sprintf(edev->pretty_name, "EISA device %.7s", edev->id.sig);
 #endif
 }
 
@@ -91,7 +91,7 @@ static char __init *decode_eisa_sig(unsi
 		 */
 		outb(0x80 + i, addr);
 #endif
-		sig[i] = inb (addr + i);
+		sig[i] = inb(addr + i);
 
 		if (!i && (sig[0] & 0x80))
 			return NULL;
@@ -106,17 +106,17 @@ static char __init *decode_eisa_sig(unsi
         return sig_str;
 }
 
-static int eisa_bus_match (struct device *dev, struct device_driver *drv)
+static int eisa_bus_match(struct device *dev, struct device_driver *drv)
 {
-	struct eisa_device *edev = to_eisa_device (dev);
-	struct eisa_driver *edrv = to_eisa_driver (drv);
+	struct eisa_device *edev = to_eisa_device(dev);
+	struct eisa_driver *edrv = to_eisa_driver(drv);
 	const struct eisa_device_id *eids = edrv->id_table;
 
 	if (!eids)
 		return 0;
 
-	while (strlen (eids->sig)) {
-		if (!strcmp (eids->sig, edev->id.sig) &&
+	while (strlen(eids->sig)) {
+		if (!strcmp(eids->sig, edev->id.sig) &&
 		    edev->state & EISA_CONFIG_ENABLED) {
 			edev->id.driver_data = eids->driver_data;
 			return 1;
@@ -141,61 +141,71 @@ struct bus_type eisa_bus_type = {
 	.match = eisa_bus_match,
 	.uevent = eisa_bus_uevent,
 };
+EXPORT_SYMBOL(eisa_bus_type);
 
-int eisa_driver_register (struct eisa_driver *edrv)
+int eisa_driver_register(struct eisa_driver *edrv)
 {
 	edrv->driver.bus = &eisa_bus_type;
-	return driver_register (&edrv->driver);
+	return driver_register(&edrv->driver);
 }
+EXPORT_SYMBOL(eisa_driver_register);
 
-void eisa_driver_unregister (struct eisa_driver *edrv)
+void eisa_driver_unregister(struct eisa_driver *edrv)
 {
-	driver_unregister (&edrv->driver);
+	driver_unregister(&edrv->driver);
 }
+EXPORT_SYMBOL(eisa_driver_unregister);
 
-static ssize_t eisa_show_sig (struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t eisa_show_sig(struct device *dev, struct device_attribute *attr,
+			     char *buf)
 {
-        struct eisa_device *edev = to_eisa_device (dev);
-        return sprintf (buf,"%s\n", edev->id.sig);
+	struct eisa_device *edev = to_eisa_device(dev);
+	return sprintf(buf, "%s\n", edev->id.sig);
 }
 
 static DEVICE_ATTR(signature, S_IRUGO, eisa_show_sig, NULL);
 
-static ssize_t eisa_show_state (struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t eisa_show_state(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
 {
-        struct eisa_device *edev = to_eisa_device (dev);
-        return sprintf (buf,"%d\n", edev->state & EISA_CONFIG_ENABLED);
+	struct eisa_device *edev = to_eisa_device(dev);
+	return sprintf(buf, "%d\n", edev->state & EISA_CONFIG_ENABLED);
 }
 
 static DEVICE_ATTR(enabled, S_IRUGO, eisa_show_state, NULL);
 
-static ssize_t eisa_show_modalias (struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t eisa_show_modalias(struct device *dev,
+				  struct device_attribute *attr,
+				  char *buf)
 {
-        struct eisa_device *edev = to_eisa_device (dev);
-        return sprintf (buf, EISA_DEVICE_MODALIAS_FMT "\n", edev->id.sig);
+	struct eisa_device *edev = to_eisa_device(dev);
+	return sprintf(buf, EISA_DEVICE_MODALIAS_FMT "\n", edev->id.sig);
 }
 
 static DEVICE_ATTR(modalias, S_IRUGO, eisa_show_modalias, NULL);
 
-static int __init eisa_init_device (struct eisa_root_device *root,
-				    struct eisa_device *edev,
-				    int slot)
+static int __init eisa_init_device(struct eisa_root_device *root,
+				   struct eisa_device *edev,
+				   int slot)
 {
 	char *sig;
-        unsigned long sig_addr;
+	unsigned long sig_addr;
 	int i;
 
-	sig_addr = SLOT_ADDRESS (root, slot) + EISA_VENDOR_ID_OFFSET;
+	sig_addr = SLOT_ADDRESS(root, slot) + EISA_VENDOR_ID_OFFSET;
 
-	if (!(sig = decode_eisa_sig (sig_addr)))
+	sig = decode_eisa_sig(sig_addr);
+	if (!sig)
 		return -1;	/* No EISA device here */
 	
-	memcpy (edev->id.sig, sig, EISA_SIG_LEN);
+	memcpy(edev->id.sig, sig, EISA_SIG_LEN);
 	edev->slot = slot;
-	edev->state = inb (SLOT_ADDRESS (root, slot) + EISA_CONFIG_OFFSET) & EISA_CONFIG_ENABLED;
-	edev->base_addr = SLOT_ADDRESS (root, slot);
+	edev->state = inb(SLOT_ADDRESS(root, slot) + EISA_CONFIG_OFFSET)
+		      & EISA_CONFIG_ENABLED;
+	edev->base_addr = SLOT_ADDRESS(root, slot);
 	edev->dma_mask = root->dma_mask; /* Default DMA mask */
-	eisa_name_device (edev);
+	eisa_name_device(edev);
 	edev->dev.parent = root->dev;
 	edev->dev.bus = &eisa_bus_type;
 	edev->dev.dma_mask = &edev->dma_mask;
@@ -210,42 +220,45 @@ static int __init eisa_init_device (stru
 #endif
 	}
 
-	if (is_forced_dev (enable_dev, enable_dev_count, root, edev))
+	if (is_forced_dev(enable_dev, enable_dev_count, root, edev))
 		edev->state = EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED;
 	
-	if (is_forced_dev (disable_dev, disable_dev_count, root, edev))
+	if (is_forced_dev(disable_dev, disable_dev_count, root, edev))
 		edev->state = EISA_CONFIG_FORCED;
 
 	return 0;
 }
 
-static int __init eisa_register_device (struct eisa_device *edev)
+static int __init eisa_register_device(struct eisa_device *edev)
 {
-	int rc = device_register (&edev->dev);
+	int rc = device_register(&edev->dev);
 	if (rc)
 		return rc;
 
-	rc = device_create_file (&edev->dev, &dev_attr_signature);
-	if (rc) goto err_devreg;
-	rc = device_create_file (&edev->dev, &dev_attr_enabled);
-	if (rc) goto err_sig;
-	rc = device_create_file (&edev->dev, &dev_attr_modalias);
-	if (rc) goto err_enab;
+	rc = device_create_file(&edev->dev, &dev_attr_signature);
+	if (rc)
+		goto err_devreg;
+	rc = device_create_file(&edev->dev, &dev_attr_enabled);
+	if (rc)
+		goto err_sig;
+	rc = device_create_file(&edev->dev, &dev_attr_modalias);
+	if (rc)
+		goto err_enab;
 
 	return 0;
 
 err_enab:
-	device_remove_file (&edev->dev, &dev_attr_enabled);
+	device_remove_file(&edev->dev, &dev_attr_enabled);
 err_sig:
-	device_remove_file (&edev->dev, &dev_attr_signature);
+	device_remove_file(&edev->dev, &dev_attr_signature);
 err_devreg:
 	device_unregister(&edev->dev);
 	return rc;
 }
 
-static int __init eisa_request_resources (struct eisa_root_device *root,
-					  struct eisa_device *edev,
-					  int slot)
+static int __init eisa_request_resources(struct eisa_root_device *root,
+					 struct eisa_device *edev,
+					 int slot)
 {
 	int i;
 
@@ -263,17 +276,19 @@ static int __init eisa_request_resources
 		
 		if (slot) {
 			edev->res[i].name  = NULL;
-			edev->res[i].start = SLOT_ADDRESS (root, slot) + (i * 0x400);
+			edev->res[i].start = SLOT_ADDRESS(root, slot)
+					     + (i * 0x400);
 			edev->res[i].end   = edev->res[i].start + 0xff;
 			edev->res[i].flags = IORESOURCE_IO;
 		} else {
 			edev->res[i].name  = NULL;
-			edev->res[i].start = SLOT_ADDRESS (root, slot) + EISA_VENDOR_ID_OFFSET;
+			edev->res[i].start = SLOT_ADDRESS(root, slot)
+					     + EISA_VENDOR_ID_OFFSET;
 			edev->res[i].end   = edev->res[i].start + 3;
 			edev->res[i].flags = IORESOURCE_BUSY;
 		}
 
-		if (request_resource (root->res, &edev->res[i]))
+		if (request_resource(root->res, &edev->res[i]))
 			goto failed;
 	}
 
@@ -281,99 +296,100 @@ static int __init eisa_request_resources
 	
  failed:
 	while (--i >= 0)
-		release_resource (&edev->res[i]);
+		release_resource(&edev->res[i]);
 
 	return -1;
 }
 
-static void __init eisa_release_resources (struct eisa_device *edev)
+static void __init eisa_release_resources(struct eisa_device *edev)
 {
 	int i;
 
 	for (i = 0; i < EISA_MAX_RESOURCES; i++)
 		if (edev->res[i].start || edev->res[i].end)
-			release_resource (&edev->res[i]);
+			release_resource(&edev->res[i]);
 }
 
-static int __init eisa_probe (struct eisa_root_device *root)
+static int __init eisa_probe(struct eisa_root_device *root)
 {
         int i, c;
 	struct eisa_device *edev;
 
-        printk (KERN_INFO "EISA: Probing bus %d at %s\n",
-		root->bus_nr, dev_name(root->dev));
+	printk(KERN_INFO "EISA: Probing bus %d at %s\n",
+	       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. */
 	
-	if (!(edev = kzalloc (sizeof (*edev), GFP_KERNEL))) {
-		printk (KERN_ERR "EISA: Couldn't allocate mainboard slot\n");
+	edev = kzalloc(sizeof(*edev), GFP_KERNEL);
+	if (!edev) {
+		printk(KERN_ERR "EISA: Couldn't allocate mainboard slot\n");
 		return -ENOMEM;
 	}
 		
-	if (eisa_request_resources (root, edev, 0)) {
-		printk (KERN_WARNING \
-			"EISA: Cannot allocate resource for mainboard\n");
-		kfree (edev);
+	if (eisa_request_resources(root, edev, 0)) {
+		printk(KERN_WARNING \
+		       "EISA: Cannot allocate resource for mainboard\n");
+		kfree(edev);
 		if (!root->force_probe)
 			return -EBUSY;
 		goto force_probe;
 	}
 
-	if (eisa_init_device (root, edev, 0)) {
-		eisa_release_resources (edev);
-		kfree (edev);
+	if (eisa_init_device(root, edev, 0)) {
+		eisa_release_resources(edev);
+		kfree(edev);
 		if (!root->force_probe)
 			return -ENODEV;
 		goto force_probe;
 	}
 
-	printk (KERN_INFO "EISA: Mainboard %s detected.\n", edev->id.sig);
+	printk(KERN_INFO "EISA: Mainboard %s detected.\n", edev->id.sig);
 
-	if (eisa_register_device (edev)) {
-		printk (KERN_ERR "EISA: Failed to register %s\n",
-			edev->id.sig);
-		eisa_release_resources (edev);
-		kfree (edev);
+	if (eisa_register_device(edev)) {
+		printk(KERN_ERR "EISA: Failed to register %s\n",
+		       edev->id.sig);
+		eisa_release_resources(edev);
+		kfree(edev);
 	}
 	
  force_probe:
 	
         for (c = 0, i = 1; i <= root->slots; i++) {
-		if (!(edev = kzalloc (sizeof (*edev), GFP_KERNEL))) {
-			printk (KERN_ERR "EISA: Out of memory for slot %d\n",
-				i);
+		edev = kzalloc(sizeof(*edev), GFP_KERNEL);
+		if (!edev) {
+			printk(KERN_ERR "EISA: Out of memory for slot %d\n", i);
 			continue;
 		}
 
-		if (eisa_request_resources (root, edev, i)) {
-			printk (KERN_WARNING \
-				"Cannot allocate resource for EISA slot %d\n",
-				i);
-			kfree (edev);
+		if (eisa_request_resources(root, edev, i)) {
+			printk(KERN_WARNING \
+			       "Cannot allocate resource for EISA slot %d\n",
+			       i);
+			kfree(edev);
 			continue;
 		}
 
-                if (eisa_init_device (root, edev, i)) {
-			eisa_release_resources (edev);
-			kfree (edev);
+		if (eisa_init_device(root, edev, i)) {
+			eisa_release_resources(edev);
+			kfree(edev);
 			continue;
 		}
 		
-		printk (KERN_INFO "EISA: slot %d : %s detected",
-			i, edev->id.sig);
+		printk(KERN_INFO "EISA: slot %d : %s detected",
+		       i, edev->id.sig);
 			
 		switch (edev->state) {
 		case EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED:
-			printk (" (forced enabled)");
+			printk(" (forced enabled)");
 			break;
 
 		case EISA_CONFIG_FORCED:
-			printk (" (forced disabled)");
+			printk(" (forced disabled)");
 			break;
 
 		case 0:
-			printk (" (disabled)");
+			printk(" (disabled)");
 			break;
 		}
 			
@@ -381,15 +397,15 @@ static int __init eisa_probe (struct eis
 
 		c++;
 
-		if (eisa_register_device (edev)) {
-			printk (KERN_ERR "EISA: Failed to register %s\n",
-				edev->id.sig);
-			eisa_release_resources (edev);
-			kfree (edev);
+		if (eisa_register_device(edev)) {
+			printk(KERN_ERR "EISA: Failed to register %s\n",
+			       edev->id.sig);
+			eisa_release_resources(edev);
+			kfree(edev);
 		}
         }
 
-        printk (KERN_INFO "EISA: Detected %d card%s.\n", c, c == 1 ? "" : "s");
+	printk(KERN_INFO "EISA: Detected %d card%s.\n", c, c == 1 ? "" : "s");
 
 	return 0;
 }
@@ -403,7 +419,7 @@ static struct resource eisa_root_res = {
 
 static int eisa_bus_count;
 
-int __init eisa_root_register (struct eisa_root_device *root)
+int __init eisa_root_register(struct eisa_root_device *root)
 {
 	int err;
 
@@ -417,35 +433,35 @@ int __init eisa_root_register (struct ei
 	root->eisa_root_res.end   = root->res->end;
 	root->eisa_root_res.flags = IORESOURCE_BUSY;
 
-	if ((err = request_resource (&eisa_root_res, &root->eisa_root_res)))
+	err = request_resource(&eisa_root_res, &root->eisa_root_res);
+	if (err)
 		return err;
 	
 	root->bus_nr = eisa_bus_count++;
 
-	if ((err = eisa_probe (root)))
-		release_resource (&root->eisa_root_res);
+	err = eisa_probe(root);
+	if (err)
+		release_resource(&root->eisa_root_res);
 
 	return err;
 }
 
-static int __init eisa_init (void)
+static int __init eisa_init(void)
 {
 	int r;
 	
-	if ((r = bus_register (&eisa_bus_type)))
+	r = bus_register(&eisa_bus_type);
+	if (r)
 		return r;
 
-	printk (KERN_INFO "EISA bus registered\n");
+	printk(KERN_INFO "EISA bus registered\n");
 	return 0;
 }
 
 module_param_array(enable_dev, int, &enable_dev_count, 0444);
 module_param_array(disable_dev, int, &disable_dev_count, 0444);
 
-postcore_initcall (eisa_init);
+postcore_initcall(eisa_init);
 
 int EISA_bus;		/* for legacy drivers */
-EXPORT_SYMBOL (EISA_bus);
-EXPORT_SYMBOL (eisa_bus_type);
-EXPORT_SYMBOL (eisa_driver_register);
-EXPORT_SYMBOL (eisa_driver_unregister);
+EXPORT_SYMBOL(EISA_bus);
diff -druNp linux-libre-2.6.33-gnu1/drivers/firewire/core-cdev.c linux-libre-2.6.34-gnu1/drivers/firewire/core-cdev.c
--- linux-libre-2.6.33-gnu1/drivers/firewire/core-cdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firewire/core-cdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/firewire.h>
 #include <linux/firewire-cdev.h>
 #include <linux/idr.h>
+#include <linux/irqflags.h>
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
 #include <linux/kref.h>
@@ -32,8 +33,8 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/poll.h>
-#include <linux/preempt.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/time.h>
@@ -368,39 +369,56 @@ void fw_device_cdev_remove(struct fw_dev
 	for_each_client(device, wake_up_client);
 }
 
-static int ioctl_get_info(struct client *client, void *buffer)
+union ioctl_arg {
+	struct fw_cdev_get_info			get_info;
+	struct fw_cdev_send_request		send_request;
+	struct fw_cdev_allocate			allocate;
+	struct fw_cdev_deallocate		deallocate;
+	struct fw_cdev_send_response		send_response;
+	struct fw_cdev_initiate_bus_reset	initiate_bus_reset;
+	struct fw_cdev_add_descriptor		add_descriptor;
+	struct fw_cdev_remove_descriptor	remove_descriptor;
+	struct fw_cdev_create_iso_context	create_iso_context;
+	struct fw_cdev_queue_iso		queue_iso;
+	struct fw_cdev_start_iso		start_iso;
+	struct fw_cdev_stop_iso			stop_iso;
+	struct fw_cdev_get_cycle_timer		get_cycle_timer;
+	struct fw_cdev_allocate_iso_resource	allocate_iso_resource;
+	struct fw_cdev_send_stream_packet	send_stream_packet;
+	struct fw_cdev_get_cycle_timer2		get_cycle_timer2;
+};
+
+static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
 {
-	struct fw_cdev_get_info *get_info = buffer;
+	struct fw_cdev_get_info *a = &arg->get_info;
 	struct fw_cdev_event_bus_reset bus_reset;
 	unsigned long ret = 0;
 
-	client->version = get_info->version;
-	get_info->version = FW_CDEV_VERSION;
-	get_info->card = client->device->card->index;
+	client->version = a->version;
+	a->version = FW_CDEV_VERSION;
+	a->card = client->device->card->index;
 
 	down_read(&fw_device_rwsem);
 
-	if (get_info->rom != 0) {
-		void __user *uptr = u64_to_uptr(get_info->rom);
-		size_t want = get_info->rom_length;
+	if (a->rom != 0) {
+		size_t want = a->rom_length;
 		size_t have = client->device->config_rom_length * 4;
 
-		ret = copy_to_user(uptr, client->device->config_rom,
-				   min(want, have));
+		ret = copy_to_user(u64_to_uptr(a->rom),
+				   client->device->config_rom, min(want, have));
 	}
-	get_info->rom_length = client->device->config_rom_length * 4;
+	a->rom_length = client->device->config_rom_length * 4;
 
 	up_read(&fw_device_rwsem);
 
 	if (ret != 0)
 		return -EFAULT;
 
-	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);
-
+	client->bus_reset_closure = a->bus_reset_closure;
+	if (a->bus_reset != 0) {
 		fill_bus_reset_event(&bus_reset, client);
-		if (copy_to_user(uptr, &bus_reset, sizeof(bus_reset)))
+		if (copy_to_user(u64_to_uptr(a->bus_reset),
+				 &bus_reset, sizeof(bus_reset)))
 			return -EFAULT;
 	}
 
@@ -571,11 +589,9 @@ static int init_request(struct client *c
 	return ret;
 }
 
-static int ioctl_send_request(struct client *client, void *buffer)
+static int ioctl_send_request(struct client *client, union ioctl_arg *arg)
 {
-	struct fw_cdev_send_request *request = buffer;
-
-	switch (request->tcode) {
+	switch (arg->send_request.tcode) {
 	case TCODE_WRITE_QUADLET_REQUEST:
 	case TCODE_WRITE_BLOCK_REQUEST:
 	case TCODE_READ_QUADLET_REQUEST:
@@ -592,7 +608,7 @@ static int ioctl_send_request(struct cli
 		return -EINVAL;
 	}
 
-	return init_request(client, request, client->device->node_id,
+	return init_request(client, &arg->send_request, client->device->node_id,
 			    client->device->max_speed);
 }
 
@@ -683,9 +699,9 @@ static void release_address_handler(stru
 	kfree(r);
 }
 
-static int ioctl_allocate(struct client *client, void *buffer)
+static int ioctl_allocate(struct client *client, union ioctl_arg *arg)
 {
-	struct fw_cdev_allocate *request = buffer;
+	struct fw_cdev_allocate *a = &arg->allocate;
 	struct address_handler_resource *r;
 	struct fw_address_region region;
 	int ret;
@@ -694,13 +710,13 @@ static int ioctl_allocate(struct client
 	if (r == NULL)
 		return -ENOMEM;
 
-	region.start = request->offset;
-	region.end = request->offset + request->length;
-	r->handler.length = request->length;
+	region.start = a->offset;
+	region.end   = a->offset + a->length;
+	r->handler.length           = a->length;
 	r->handler.address_callback = handle_request;
-	r->handler.callback_data = r;
-	r->closure = request->closure;
-	r->client = client;
+	r->handler.callback_data    = r;
+	r->closure   = a->closure;
+	r->client    = client;
 
 	ret = fw_core_add_address_handler(&r->handler, &region);
 	if (ret < 0) {
@@ -714,27 +730,25 @@ static int ioctl_allocate(struct client
 		release_address_handler(client, &r->resource);
 		return ret;
 	}
-	request->handle = r->resource.handle;
+	a->handle = r->resource.handle;
 
 	return 0;
 }
 
-static int ioctl_deallocate(struct client *client, void *buffer)
+static int ioctl_deallocate(struct client *client, union ioctl_arg *arg)
 {
-	struct fw_cdev_deallocate *request = buffer;
-
-	return release_client_resource(client, request->handle,
+	return release_client_resource(client, arg->deallocate.handle,
 				       release_address_handler, NULL);
 }
 
-static int ioctl_send_response(struct client *client, void *buffer)
+static int ioctl_send_response(struct client *client, union ioctl_arg *arg)
 {
-	struct fw_cdev_send_response *request = buffer;
+	struct fw_cdev_send_response *a = &arg->send_response;
 	struct client_resource *resource;
 	struct inbound_transaction_resource *r;
 	int ret = 0;
 
-	if (release_client_resource(client, request->handle,
+	if (release_client_resource(client, a->handle,
 				    release_request, &resource) < 0)
 		return -EINVAL;
 
@@ -743,28 +757,24 @@ static int ioctl_send_response(struct cl
 	if (is_fcp_request(r->request))
 		goto out;
 
-	if (request->length < r->length)
-		r->length = request->length;
-	if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) {
+	if (a->length < r->length)
+		r->length = a->length;
+	if (copy_from_user(r->data, u64_to_uptr(a->data), r->length)) {
 		ret = -EFAULT;
 		kfree(r->request);
 		goto out;
 	}
-	fw_send_response(client->device->card, r->request, request->rcode);
+	fw_send_response(client->device->card, r->request, a->rcode);
  out:
 	kfree(r);
 
 	return ret;
 }
 
-static int ioctl_initiate_bus_reset(struct client *client, void *buffer)
+static int ioctl_initiate_bus_reset(struct client *client, union ioctl_arg *arg)
 {
-	struct fw_cdev_initiate_bus_reset *request = buffer;
-	int short_reset;
-
-	short_reset = (request->type == FW_CDEV_SHORT_RESET);
-
-	return fw_core_initiate_bus_reset(client->device->card, short_reset);
+	return fw_core_initiate_bus_reset(client->device->card,
+			arg->initiate_bus_reset.type == FW_CDEV_SHORT_RESET);
 }
 
 static void release_descriptor(struct client *client,
@@ -777,9 +787,9 @@ static void release_descriptor(struct cl
 	kfree(r);
 }
 
-static int ioctl_add_descriptor(struct client *client, void *buffer)
+static int ioctl_add_descriptor(struct client *client, union ioctl_arg *arg)
 {
-	struct fw_cdev_add_descriptor *request = buffer;
+	struct fw_cdev_add_descriptor *a = &arg->add_descriptor;
 	struct descriptor_resource *r;
 	int ret;
 
@@ -787,22 +797,21 @@ static int ioctl_add_descriptor(struct c
 	if (!client->device->is_local)
 		return -ENOSYS;
 
-	if (request->length > 256)
+	if (a->length > 256)
 		return -EINVAL;
 
-	r = kmalloc(sizeof(*r) + request->length * 4, GFP_KERNEL);
+	r = kmalloc(sizeof(*r) + a->length * 4, GFP_KERNEL);
 	if (r == NULL)
 		return -ENOMEM;
 
-	if (copy_from_user(r->data,
-			   u64_to_uptr(request->data), request->length * 4)) {
+	if (copy_from_user(r->data, u64_to_uptr(a->data), a->length * 4)) {
 		ret = -EFAULT;
 		goto failed;
 	}
 
-	r->descriptor.length    = request->length;
-	r->descriptor.immediate = request->immediate;
-	r->descriptor.key       = request->key;
+	r->descriptor.length    = a->length;
+	r->descriptor.immediate = a->immediate;
+	r->descriptor.key       = a->key;
 	r->descriptor.data      = r->data;
 
 	ret = fw_core_add_descriptor(&r->descriptor);
@@ -815,7 +824,7 @@ static int ioctl_add_descriptor(struct c
 		fw_core_remove_descriptor(&r->descriptor);
 		goto failed;
 	}
-	request->handle = r->resource.handle;
+	a->handle = r->resource.handle;
 
 	return 0;
  failed:
@@ -824,11 +833,9 @@ static int ioctl_add_descriptor(struct c
 	return ret;
 }
 
-static int ioctl_remove_descriptor(struct client *client, void *buffer)
+static int ioctl_remove_descriptor(struct client *client, union ioctl_arg *arg)
 {
-	struct fw_cdev_remove_descriptor *request = buffer;
-
-	return release_client_resource(client, request->handle,
+	return release_client_resource(client, arg->remove_descriptor.handle,
 				       release_descriptor, NULL);
 }
 
@@ -851,49 +858,44 @@ static void iso_callback(struct fw_iso_c
 		    sizeof(e->interrupt) + header_length, NULL, 0);
 }
 
-static int ioctl_create_iso_context(struct client *client, void *buffer)
+static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
 {
-	struct fw_cdev_create_iso_context *request = buffer;
+	struct fw_cdev_create_iso_context *a = &arg->create_iso_context;
 	struct fw_iso_context *context;
 
 	/* We only support one context at this time. */
 	if (client->iso_context != NULL)
 		return -EBUSY;
 
-	if (request->channel > 63)
+	if (a->channel > 63)
 		return -EINVAL;
 
-	switch (request->type) {
+	switch (a->type) {
 	case FW_ISO_CONTEXT_RECEIVE:
-		if (request->header_size < 4 || (request->header_size & 3))
+		if (a->header_size < 4 || (a->header_size & 3))
 			return -EINVAL;
-
 		break;
 
 	case FW_ISO_CONTEXT_TRANSMIT:
-		if (request->speed > SCODE_3200)
+		if (a->speed > SCODE_3200)
 			return -EINVAL;
-
 		break;
 
 	default:
 		return -EINVAL;
 	}
 
-	context =  fw_iso_context_create(client->device->card,
-					 request->type,
-					 request->channel,
-					 request->speed,
-					 request->header_size,
-					 iso_callback, client);
+	context = fw_iso_context_create(client->device->card, a->type,
+					a->channel, a->speed, a->header_size,
+					iso_callback, client);
 	if (IS_ERR(context))
 		return PTR_ERR(context);
 
-	client->iso_closure = request->closure;
+	client->iso_closure = a->closure;
 	client->iso_context = context;
 
 	/* We only support one context at this time. */
-	request->handle = 0;
+	a->handle = 0;
 
 	return 0;
 }
@@ -906,9 +908,9 @@ static int ioctl_create_iso_context(stru
 #define GET_SY(v)		(((v) >> 20) & 0x0f)
 #define GET_HEADER_LENGTH(v)	(((v) >> 24) & 0xff)
 
-static int ioctl_queue_iso(struct client *client, void *buffer)
+static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
 {
-	struct fw_cdev_queue_iso *request = buffer;
+	struct fw_cdev_queue_iso *a = &arg->queue_iso;
 	struct fw_cdev_iso_packet __user *p, *end, *next;
 	struct fw_iso_context *ctx = client->iso_context;
 	unsigned long payload, buffer_end, header_length;
@@ -919,7 +921,7 @@ static int ioctl_queue_iso(struct client
 		u8 header[256];
 	} u;
 
-	if (ctx == NULL || request->handle != 0)
+	if (ctx == NULL || a->handle != 0)
 		return -EINVAL;
 
 	/*
@@ -929,23 +931,23 @@ static int ioctl_queue_iso(struct client
 	 * set them both to 0, which will still let packets with
 	 * payload_length == 0 through.  In other words, if no packets
 	 * use the indirect payload, the iso buffer need not be mapped
-	 * and the request->data pointer is ignored.
+	 * and the a->data pointer is ignored.
 	 */
 
-	payload = (unsigned long)request->data - client->vm_start;
+	payload = (unsigned long)a->data - client->vm_start;
 	buffer_end = client->buffer.page_count << PAGE_SHIFT;
-	if (request->data == 0 || client->buffer.pages == NULL ||
+	if (a->data == 0 || client->buffer.pages == NULL ||
 	    payload >= buffer_end) {
 		payload = 0;
 		buffer_end = 0;
 	}
 
-	p = (struct fw_cdev_iso_packet __user *)u64_to_uptr(request->packets);
+	p = (struct fw_cdev_iso_packet __user *)u64_to_uptr(a->packets);
 
-	if (!access_ok(VERIFY_READ, p, request->size))
+	if (!access_ok(VERIFY_READ, p, a->size))
 		return -EFAULT;
 
-	end = (void __user *)p + request->size;
+	end = (void __user *)p + a->size;
 	count = 0;
 	while (p < end) {
 		if (get_user(control, &p->control))
@@ -958,6 +960,8 @@ static int ioctl_queue_iso(struct client
 		u.packet.header_length = GET_HEADER_LENGTH(control);
 
 		if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
+			if (u.packet.header_length % 4 != 0)
+				return -EINVAL;
 			header_length = u.packet.header_length;
 		} else {
 			/*
@@ -967,7 +971,8 @@ static int ioctl_queue_iso(struct client
 			if (ctx->header_size == 0) {
 				if (u.packet.header_length > 0)
 					return -EINVAL;
-			} else if (u.packet.header_length % ctx->header_size != 0) {
+			} else if (u.packet.header_length == 0 ||
+				   u.packet.header_length % ctx->header_size != 0) {
 				return -EINVAL;
 			}
 			header_length = 0;
@@ -995,61 +1000,78 @@ static int ioctl_queue_iso(struct client
 		count++;
 	}
 
-	request->size    -= uptr_to_u64(p) - request->packets;
-	request->packets  = uptr_to_u64(p);
-	request->data     = client->vm_start + payload;
+	a->size    -= uptr_to_u64(p) - a->packets;
+	a->packets  = uptr_to_u64(p);
+	a->data     = client->vm_start + payload;
 
 	return count;
 }
 
-static int ioctl_start_iso(struct client *client, void *buffer)
+static int ioctl_start_iso(struct client *client, union ioctl_arg *arg)
 {
-	struct fw_cdev_start_iso *request = buffer;
+	struct fw_cdev_start_iso *a = &arg->start_iso;
 
-	if (client->iso_context == NULL || request->handle != 0)
+	if (client->iso_context == NULL || a->handle != 0)
 		return -EINVAL;
 
-	if (client->iso_context->type == FW_ISO_CONTEXT_RECEIVE) {
-		if (request->tags == 0 || request->tags > 15)
-			return -EINVAL;
-
-		if (request->sync > 15)
-			return -EINVAL;
-	}
+	if (client->iso_context->type == FW_ISO_CONTEXT_RECEIVE &&
+	    (a->tags == 0 || a->tags > 15 || a->sync > 15))
+		return -EINVAL;
 
-	return fw_iso_context_start(client->iso_context, request->cycle,
-				    request->sync, request->tags);
+	return fw_iso_context_start(client->iso_context,
+				    a->cycle, a->sync, a->tags);
 }
 
-static int ioctl_stop_iso(struct client *client, void *buffer)
+static int ioctl_stop_iso(struct client *client, union ioctl_arg *arg)
 {
-	struct fw_cdev_stop_iso *request = buffer;
+	struct fw_cdev_stop_iso *a = &arg->stop_iso;
 
-	if (client->iso_context == NULL || request->handle != 0)
+	if (client->iso_context == NULL || a->handle != 0)
 		return -EINVAL;
 
 	return fw_iso_context_stop(client->iso_context);
 }
 
-static int ioctl_get_cycle_timer(struct client *client, void *buffer)
+static int ioctl_get_cycle_timer2(struct client *client, union ioctl_arg *arg)
 {
-	struct fw_cdev_get_cycle_timer *request = buffer;
+	struct fw_cdev_get_cycle_timer2 *a = &arg->get_cycle_timer2;
 	struct fw_card *card = client->device->card;
-	unsigned long long bus_time;
-	struct timeval tv;
-	unsigned long flags;
+	struct timespec ts = {0, 0};
+	u32 cycle_time;
+	int ret = 0;
 
-	preempt_disable();
-	local_irq_save(flags);
+	local_irq_disable();
 
-	bus_time = card->driver->get_bus_time(card);
-	do_gettimeofday(&tv);
+	cycle_time = card->driver->get_cycle_time(card);
 
-	local_irq_restore(flags);
-	preempt_enable();
+	switch (a->clk_id) {
+	case CLOCK_REALTIME:      getnstimeofday(&ts);                   break;
+	case CLOCK_MONOTONIC:     do_posix_clock_monotonic_gettime(&ts); break;
+	case CLOCK_MONOTONIC_RAW: getrawmonotonic(&ts);                  break;
+	default:
+		ret = -EINVAL;
+	}
+
+	local_irq_enable();
+
+	a->tv_sec      = ts.tv_sec;
+	a->tv_nsec     = ts.tv_nsec;
+	a->cycle_timer = cycle_time;
+
+	return ret;
+}
+
+static int ioctl_get_cycle_timer(struct client *client, union ioctl_arg *arg)
+{
+	struct fw_cdev_get_cycle_timer *a = &arg->get_cycle_timer;
+	struct fw_cdev_get_cycle_timer2 ct2;
+
+	ct2.clk_id = CLOCK_REALTIME;
+	ioctl_get_cycle_timer2(client, (union ioctl_arg *)&ct2);
+
+	a->local_time = ct2.tv_sec * USEC_PER_SEC + ct2.tv_nsec / NSEC_PER_USEC;
+	a->cycle_timer = ct2.cycle_timer;
 
-	request->local_time = tv.tv_sec * 1000000ULL + tv.tv_usec;
-	request->cycle_timer = bus_time & 0xffffffff;
 	return 0;
 }
 
@@ -1220,33 +1242,32 @@ static int init_iso_resource(struct clie
 	return ret;
 }
 
-static int ioctl_allocate_iso_resource(struct client *client, void *buffer)
+static int ioctl_allocate_iso_resource(struct client *client,
+				       union ioctl_arg *arg)
 {
-	struct fw_cdev_allocate_iso_resource *request = buffer;
-
-	return init_iso_resource(client, request, ISO_RES_ALLOC);
+	return init_iso_resource(client,
+			&arg->allocate_iso_resource, ISO_RES_ALLOC);
 }
 
-static int ioctl_deallocate_iso_resource(struct client *client, void *buffer)
+static int ioctl_deallocate_iso_resource(struct client *client,
+					 union ioctl_arg *arg)
 {
-	struct fw_cdev_deallocate *request = buffer;
-
-	return release_client_resource(client, request->handle,
-				       release_iso_resource, NULL);
+	return release_client_resource(client,
+			arg->deallocate.handle, release_iso_resource, NULL);
 }
 
-static int ioctl_allocate_iso_resource_once(struct client *client, void *buffer)
+static int ioctl_allocate_iso_resource_once(struct client *client,
+					    union ioctl_arg *arg)
 {
-	struct fw_cdev_allocate_iso_resource *request = buffer;
-
-	return init_iso_resource(client, request, ISO_RES_ALLOC_ONCE);
+	return init_iso_resource(client,
+			&arg->allocate_iso_resource, ISO_RES_ALLOC_ONCE);
 }
 
-static int ioctl_deallocate_iso_resource_once(struct client *client, void *buffer)
+static int ioctl_deallocate_iso_resource_once(struct client *client,
+					      union ioctl_arg *arg)
 {
-	struct fw_cdev_allocate_iso_resource *request = buffer;
-
-	return init_iso_resource(client, request, ISO_RES_DEALLOC_ONCE);
+	return init_iso_resource(client,
+			&arg->allocate_iso_resource, ISO_RES_DEALLOC_ONCE);
 }
 
 /*
@@ -1254,16 +1275,17 @@ static int ioctl_deallocate_iso_resource
  * 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)
+static int ioctl_get_speed(struct client *client, union ioctl_arg *arg)
 {
 	return client->device->max_speed;
 }
 
-static int ioctl_send_broadcast_request(struct client *client, void *buffer)
+static int ioctl_send_broadcast_request(struct client *client,
+					union ioctl_arg *arg)
 {
-	struct fw_cdev_send_request *request = buffer;
+	struct fw_cdev_send_request *a = &arg->send_request;
 
-	switch (request->tcode) {
+	switch (a->tcode) {
 	case TCODE_WRITE_QUADLET_REQUEST:
 	case TCODE_WRITE_BLOCK_REQUEST:
 		break;
@@ -1272,36 +1294,36 @@ static int ioctl_send_broadcast_request(
 	}
 
 	/* Security policy: Only allow accesses to Units Space. */
-	if (request->offset < CSR_REGISTER_BASE + CSR_CONFIG_ROM_END)
+	if (a->offset < CSR_REGISTER_BASE + CSR_CONFIG_ROM_END)
 		return -EACCES;
 
-	return init_request(client, request, LOCAL_BUS | 0x3f, SCODE_100);
+	return init_request(client, a, LOCAL_BUS | 0x3f, SCODE_100);
 }
 
-static int ioctl_send_stream_packet(struct client *client, void *buffer)
+static int ioctl_send_stream_packet(struct client *client, union ioctl_arg *arg)
 {
-	struct fw_cdev_send_stream_packet *p = buffer;
+	struct fw_cdev_send_stream_packet *a = &arg->send_stream_packet;
 	struct fw_cdev_send_request request;
 	int dest;
 
-	if (p->speed > client->device->card->link_speed ||
-	    p->length > 1024 << p->speed)
+	if (a->speed > client->device->card->link_speed ||
+	    a->length > 1024 << a->speed)
 		return -EIO;
 
-	if (p->tag > 3 || p->channel > 63 || p->sy > 15)
+	if (a->tag > 3 || a->channel > 63 || a->sy > 15)
 		return -EINVAL;
 
-	dest = fw_stream_packet_destination_id(p->tag, p->channel, p->sy);
+	dest = fw_stream_packet_destination_id(a->tag, a->channel, a->sy);
 	request.tcode		= TCODE_STREAM_DATA;
-	request.length		= p->length;
-	request.closure		= p->closure;
-	request.data		= p->data;
-	request.generation	= p->generation;
+	request.length		= a->length;
+	request.closure		= a->closure;
+	request.data		= a->data;
+	request.generation	= a->generation;
 
-	return init_request(client, &request, dest, p->speed);
+	return init_request(client, &request, dest, a->speed);
 }
 
-static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
+static int (* const ioctl_handlers[])(struct client *, union ioctl_arg *) = {
 	ioctl_get_info,
 	ioctl_send_request,
 	ioctl_allocate,
@@ -1322,49 +1344,37 @@ static int (* const ioctl_handlers[])(st
 	ioctl_get_speed,
 	ioctl_send_broadcast_request,
 	ioctl_send_stream_packet,
+	ioctl_get_cycle_timer2,
 };
 
 static int dispatch_ioctl(struct client *client,
 			  unsigned int cmd, void __user *arg)
 {
-	char buffer[sizeof(union {
-		struct fw_cdev_get_info			_00;
-		struct fw_cdev_send_request		_01;
-		struct fw_cdev_allocate			_02;
-		struct fw_cdev_deallocate		_03;
-		struct fw_cdev_send_response		_04;
-		struct fw_cdev_initiate_bus_reset	_05;
-		struct fw_cdev_add_descriptor		_06;
-		struct fw_cdev_remove_descriptor	_07;
-		struct fw_cdev_create_iso_context	_08;
-		struct fw_cdev_queue_iso		_09;
-		struct fw_cdev_start_iso		_0a;
-		struct fw_cdev_stop_iso			_0b;
-		struct fw_cdev_get_cycle_timer		_0c;
-		struct fw_cdev_allocate_iso_resource	_0d;
-		struct fw_cdev_send_stream_packet	_13;
-	})];
+	union ioctl_arg buffer;
 	int ret;
 
+	if (fw_device_is_shutdown(client->device))
+		return -ENODEV;
+
 	if (_IOC_TYPE(cmd) != '#' ||
-	    _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers))
+	    _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) ||
+	    _IOC_SIZE(cmd) > sizeof(buffer))
 		return -EINVAL;
 
-	if (_IOC_DIR(cmd) & _IOC_WRITE) {
-		if (_IOC_SIZE(cmd) > sizeof(buffer) ||
-		    copy_from_user(buffer, arg, _IOC_SIZE(cmd)))
+	if (_IOC_DIR(cmd) == _IOC_READ)
+		memset(&buffer, 0, _IOC_SIZE(cmd));
+
+	if (_IOC_DIR(cmd) & _IOC_WRITE)
+		if (copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
 			return -EFAULT;
-	}
 
-	ret = ioctl_handlers[_IOC_NR(cmd)](client, buffer);
+	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) ||
-		    copy_to_user(arg, buffer, _IOC_SIZE(cmd)))
+	if (_IOC_DIR(cmd) & _IOC_READ)
+		if (copy_to_user(arg, &buffer, _IOC_SIZE(cmd)))
 			return -EFAULT;
-	}
 
 	return ret;
 }
@@ -1372,24 +1382,14 @@ static int dispatch_ioctl(struct client
 static long fw_device_op_ioctl(struct file *file,
 			       unsigned int cmd, unsigned long arg)
 {
-	struct client *client = file->private_data;
-
-	if (fw_device_is_shutdown(client->device))
-		return -ENODEV;
-
-	return dispatch_ioctl(client, cmd, (void __user *) arg);
+	return dispatch_ioctl(file->private_data, cmd, (void __user *)arg);
 }
 
 #ifdef CONFIG_COMPAT
 static long fw_device_op_compat_ioctl(struct file *file,
 				      unsigned int cmd, unsigned long arg)
 {
-	struct client *client = file->private_data;
-
-	if (fw_device_is_shutdown(client->device))
-		return -ENODEV;
-
-	return dispatch_ioctl(client, cmd, compat_ptr(arg));
+	return dispatch_ioctl(file->private_data, cmd, compat_ptr(arg));
 }
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/firewire/core-device.c linux-libre-2.6.34-gnu1/drivers/firewire/core-device.c
--- linux-libre-2.6.33-gnu1/drivers/firewire/core-device.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firewire/core-device.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#include <linux/bug.h>
 #include <linux/ctype.h>
 #include <linux/delay.h>
 #include <linux/device.h>
@@ -32,7 +33,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/rwsem.h>
-#include <linux/semaphore.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/workqueue.h>
@@ -43,7 +44,7 @@
 
 #include "core.h"
 
-void fw_csr_iterator_init(struct fw_csr_iterator *ci, u32 * p)
+void fw_csr_iterator_init(struct fw_csr_iterator *ci, const u32 *p)
 {
 	ci->p = p + 1;
 	ci->end = ci->p + (p[0] >> 16);
@@ -59,97 +60,141 @@ int fw_csr_iterator_next(struct fw_csr_i
 }
 EXPORT_SYMBOL(fw_csr_iterator_next);
 
-static bool is_fw_unit(struct device *dev);
-
-static int match_unit_directory(u32 *directory, u32 match_flags,
-				const struct ieee1394_device_id *id)
+static const u32 *search_leaf(const u32 *directory, int search_key)
 {
 	struct fw_csr_iterator ci;
-	int key, value, match;
+	int last_key = 0, key, value;
 
-	match = 0;
 	fw_csr_iterator_init(&ci, directory);
 	while (fw_csr_iterator_next(&ci, &key, &value)) {
-		if (key == CSR_VENDOR && value == id->vendor_id)
-			match |= IEEE1394_MATCH_VENDOR_ID;
-		if (key == CSR_MODEL && value == id->model_id)
-			match |= IEEE1394_MATCH_MODEL_ID;
-		if (key == CSR_SPECIFIER_ID && value == id->specifier_id)
-			match |= IEEE1394_MATCH_SPECIFIER_ID;
-		if (key == CSR_VERSION && value == id->version)
-			match |= IEEE1394_MATCH_VERSION;
+		if (last_key == search_key &&
+		    key == (CSR_DESCRIPTOR | CSR_LEAF))
+			return ci.p - 1 + value;
+
+		last_key = key;
 	}
 
-	return (match & match_flags) == match_flags;
+	return NULL;
 }
 
-static int fw_unit_match(struct device *dev, struct device_driver *drv)
+static int textual_leaf_to_string(const u32 *block, char *buf, size_t size)
 {
-	struct fw_unit *unit = fw_unit(dev);
-	struct fw_device *device;
-	const struct ieee1394_device_id *id;
+	unsigned int quadlets, i;
+	char c;
 
-	/* We only allow binding to fw_units. */
-	if (!is_fw_unit(dev))
-		return 0;
+	if (!size || !buf)
+		return -EINVAL;
 
-	device = fw_parent_device(unit);
-	id = container_of(drv, struct fw_driver, driver)->id_table;
+	quadlets = min(block[0] >> 16, 256U);
+	if (quadlets < 2)
+		return -ENODATA;
 
-	for (; id->match_flags != 0; id++) {
-		if (match_unit_directory(unit->directory, id->match_flags, id))
-			return 1;
+	if (block[1] != 0 || block[2] != 0)
+		/* unknown language/character set */
+		return -ENODATA;
 
-		/* Also check vendor ID in the root directory. */
-		if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
-		    match_unit_directory(&device->config_rom[5],
-				IEEE1394_MATCH_VENDOR_ID, id) &&
-		    match_unit_directory(unit->directory, id->match_flags
-				& ~IEEE1394_MATCH_VENDOR_ID, id))
-			return 1;
+	block += 3;
+	quadlets -= 2;
+	for (i = 0; i < quadlets * 4 && i < size - 1; i++) {
+		c = block[i / 4] >> (24 - 8 * (i % 4));
+		if (c == '\0')
+			break;
+		buf[i] = c;
 	}
+	buf[i] = '\0';
 
-	return 0;
+	return i;
 }
 
-static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
+/**
+ * fw_csr_string - reads a string from the configuration ROM
+ * @directory: e.g. root directory or unit directory
+ * @key: the key of the preceding directory entry
+ * @buf: where to put the string
+ * @size: size of @buf, in bytes
+ *
+ * The string is taken from a minimal ASCII text descriptor leaf after
+ * the immediate entry with @key.  The string is zero-terminated.
+ * Returns strlen(buf) or a negative error code.
+ */
+int fw_csr_string(const u32 *directory, int key, char *buf, size_t size)
 {
-	struct fw_device *device = fw_parent_device(unit);
-	struct fw_csr_iterator ci;
+	const u32 *leaf = search_leaf(directory, key);
+	if (!leaf)
+		return -ENOENT;
 
+	return textual_leaf_to_string(leaf, buf, size);
+}
+EXPORT_SYMBOL(fw_csr_string);
+
+static void get_ids(const u32 *directory, int *id)
+{
+	struct fw_csr_iterator ci;
 	int key, value;
-	int vendor = 0;
-	int model = 0;
-	int specifier_id = 0;
-	int version = 0;
 
-	fw_csr_iterator_init(&ci, &device->config_rom[5]);
+	fw_csr_iterator_init(&ci, directory);
 	while (fw_csr_iterator_next(&ci, &key, &value)) {
 		switch (key) {
-		case CSR_VENDOR:
-			vendor = value;
-			break;
-		case CSR_MODEL:
-			model = value;
-			break;
+		case CSR_VENDOR:	id[0] = value; break;
+		case CSR_MODEL:		id[1] = value; break;
+		case CSR_SPECIFIER_ID:	id[2] = value; break;
+		case CSR_VERSION:	id[3] = value; break;
 		}
 	}
+}
 
-	fw_csr_iterator_init(&ci, unit->directory);
-	while (fw_csr_iterator_next(&ci, &key, &value)) {
-		switch (key) {
-		case CSR_SPECIFIER_ID:
-			specifier_id = value;
-			break;
-		case CSR_VERSION:
-			version = value;
-			break;
-		}
-	}
+static void get_modalias_ids(struct fw_unit *unit, int *id)
+{
+	get_ids(&fw_parent_device(unit)->config_rom[5], id);
+	get_ids(unit->directory, id);
+}
+
+static bool match_ids(const struct ieee1394_device_id *id_table, int *id)
+{
+	int match = 0;
+
+	if (id[0] == id_table->vendor_id)
+		match |= IEEE1394_MATCH_VENDOR_ID;
+	if (id[1] == id_table->model_id)
+		match |= IEEE1394_MATCH_MODEL_ID;
+	if (id[2] == id_table->specifier_id)
+		match |= IEEE1394_MATCH_SPECIFIER_ID;
+	if (id[3] == id_table->version)
+		match |= IEEE1394_MATCH_VERSION;
+
+	return (match & id_table->match_flags) == id_table->match_flags;
+}
+
+static bool is_fw_unit(struct device *dev);
+
+static int fw_unit_match(struct device *dev, struct device_driver *drv)
+{
+	const struct ieee1394_device_id *id_table =
+			container_of(drv, struct fw_driver, driver)->id_table;
+	int id[] = {0, 0, 0, 0};
+
+	/* We only allow binding to fw_units. */
+	if (!is_fw_unit(dev))
+		return 0;
+
+	get_modalias_ids(fw_unit(dev), id);
+
+	for (; id_table->match_flags != 0; id_table++)
+		if (match_ids(id_table, id))
+			return 1;
+
+	return 0;
+}
+
+static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
+{
+	int id[] = {0, 0, 0, 0};
+
+	get_modalias_ids(unit, id);
 
 	return snprintf(buffer, buffer_size,
 			"ieee1394:ven%08Xmo%08Xsp%08Xver%08X",
-			vendor, model, specifier_id, version);
+			id[0], id[1], id[2], id[3]);
 }
 
 static int fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
@@ -195,7 +240,7 @@ static ssize_t show_immediate(struct dev
 	struct config_rom_attribute *attr =
 		container_of(dattr, struct config_rom_attribute, attr);
 	struct fw_csr_iterator ci;
-	u32 *dir;
+	const u32 *dir;
 	int key, value, ret = -ENOENT;
 
 	down_read(&fw_device_rwsem);
@@ -226,10 +271,10 @@ static ssize_t show_text_leaf(struct dev
 {
 	struct config_rom_attribute *attr =
 		container_of(dattr, struct config_rom_attribute, attr);
-	struct fw_csr_iterator ci;
-	u32 *dir, *block = NULL, *p, *end;
-	int length, key, value, last_key = 0, ret = -ENOENT;
-	char *b;
+	const u32 *dir;
+	size_t bufsize;
+	char dummy_buf[2];
+	int ret;
 
 	down_read(&fw_device_rwsem);
 
@@ -238,40 +283,23 @@ static ssize_t show_text_leaf(struct dev
 	else
 		dir = fw_device(dev)->config_rom + 5;
 
-	fw_csr_iterator_init(&ci, dir);
-	while (fw_csr_iterator_next(&ci, &key, &value)) {
-		if (attr->key == last_key &&
-		    key == (CSR_DESCRIPTOR | CSR_LEAF))
-			block = ci.p - 1 + value;
-		last_key = key;
+	if (buf) {
+		bufsize = PAGE_SIZE - 1;
+	} else {
+		buf = dummy_buf;
+		bufsize = 1;
 	}
 
-	if (block == NULL)
-		goto out;
-
-	length = min(block[0] >> 16, 256U);
-	if (length < 3)
-		goto out;
-
-	if (block[1] != 0 || block[2] != 0)
-		/* Unknown encoding. */
-		goto out;
+	ret = fw_csr_string(dir, attr->key, buf, bufsize);
 
-	if (buf == NULL) {
-		ret = length * 4;
-		goto out;
+	if (ret >= 0) {
+		/* Strip trailing whitespace and add newline. */
+		while (ret > 0 && isspace(buf[ret - 1]))
+			ret--;
+		strcpy(buf + ret, "\n");
+		ret++;
 	}
 
-	b = buf;
-	end = &block[length + 1];
-	for (p = &block[3]; p < end; p++, b += 4)
-		* (u32 *) b = (__force u32) __cpu_to_be32(*p);
-
-	/* Strip trailing whitespace and add newline. */
-	while (b--, (isspace(*b) || *b == '\0') && b > buf);
-	strcpy(b + 1, "\n");
-	ret = b + 2 - buf;
- out:
 	up_read(&fw_device_rwsem);
 
 	return ret;
@@ -371,7 +399,7 @@ static ssize_t guid_show(struct device *
 	return ret;
 }
 
-static int units_sprintf(char *buf, u32 *directory)
+static int units_sprintf(char *buf, const u32 *directory)
 {
 	struct fw_csr_iterator ci;
 	int key, value;
@@ -441,28 +469,29 @@ static int read_rom(struct fw_device *de
 	return rcode;
 }
 
-#define READ_BIB_ROM_SIZE	256
-#define READ_BIB_STACK_SIZE	16
+#define MAX_CONFIG_ROM_SIZE 256
 
 /*
  * Read the bus info block, perform a speed probe, and read all of the rest of
  * the config ROM.  We do all this with a cached bus generation.  If the bus
- * generation changes under us, read_bus_info_block will fail and get retried.
+ * generation changes under us, read_config_rom will fail and get retried.
  * It's better to start all over in this case because the node from which we
  * are reading the ROM may have changed the ROM during the reset.
  */
-static int read_bus_info_block(struct fw_device *device, int generation)
+static int read_config_rom(struct fw_device *device, int generation)
 {
-	u32 *rom, *stack, *old_rom, *new_rom;
+	const u32 *old_rom, *new_rom;
+	u32 *rom, *stack;
 	u32 sp, key;
 	int i, end, length, ret = -1;
 
-	rom = kmalloc(sizeof(*rom) * READ_BIB_ROM_SIZE +
-		      sizeof(*stack) * READ_BIB_STACK_SIZE, GFP_KERNEL);
+	rom = kmalloc(sizeof(*rom) * MAX_CONFIG_ROM_SIZE +
+		      sizeof(*stack) * MAX_CONFIG_ROM_SIZE, GFP_KERNEL);
 	if (rom == NULL)
 		return -ENOMEM;
 
-	stack = &rom[READ_BIB_ROM_SIZE];
+	stack = &rom[MAX_CONFIG_ROM_SIZE];
+	memset(rom, 0, sizeof(*rom) * MAX_CONFIG_ROM_SIZE);
 
 	device->max_speed = SCODE_100;
 
@@ -529,40 +558,54 @@ static int read_bus_info_block(struct fw
 		 */
 		key = stack[--sp];
 		i = key & 0xffffff;
-		if (i >= READ_BIB_ROM_SIZE)
-			/*
-			 * The reference points outside the standard
-			 * config rom area, something's fishy.
-			 */
+		if (WARN_ON(i >= MAX_CONFIG_ROM_SIZE))
 			goto out;
 
 		/* Read header quadlet for the block to get the length. */
 		if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE)
 			goto out;
 		end = i + (rom[i] >> 16) + 1;
-		i++;
-		if (end > READ_BIB_ROM_SIZE)
+		if (end > MAX_CONFIG_ROM_SIZE) {
 			/*
-			 * This block extends outside standard config
-			 * area (and the array we're reading it
-			 * into).  That's broken, so ignore this
-			 * device.
+			 * This block extends outside the config ROM which is
+			 * a firmware bug.  Ignore this whole block, i.e.
+			 * simply set a fake block length of 0.
 			 */
-			goto out;
+			fw_error("skipped invalid ROM block %x at %llx\n",
+				 rom[i],
+				 i * 4 | CSR_REGISTER_BASE | CSR_CONFIG_ROM);
+			rom[i] = 0;
+			end = i;
+		}
+		i++;
 
 		/*
 		 * Now read in the block.  If this is a directory
 		 * block, check the entries as we read them to see if
 		 * it references another block, and push it in that case.
 		 */
-		while (i < end) {
+		for (; i < end; i++) {
 			if (read_rom(device, generation, i, &rom[i]) !=
 			    RCODE_COMPLETE)
 				goto out;
-			if ((key >> 30) == 3 && (rom[i] >> 30) > 1 &&
-			    sp < READ_BIB_STACK_SIZE)
-				stack[sp++] = i + rom[i];
-			i++;
+
+			if ((key >> 30) != 3 || (rom[i] >> 30) < 2)
+				continue;
+			/*
+			 * Offset points outside the ROM.  May be a firmware
+			 * bug or an Extended ROM entry (IEEE 1212-2001 clause
+			 * 7.7.18).  Simply overwrite this pointer here by a
+			 * fake immediate entry so that later iterators over
+			 * the ROM don't have to check offsets all the time.
+			 */
+			if (i + (rom[i] & 0xffffff) >= MAX_CONFIG_ROM_SIZE) {
+				fw_error("skipped unsupported ROM entry %x at %llx\n",
+					 rom[i],
+					 i * 4 | CSR_REGISTER_BASE | CSR_CONFIG_ROM);
+				rom[i] = 0;
+				continue;
+			}
+			stack[sp++] = i + rom[i];
 		}
 		if (length < i)
 			length = i;
@@ -762,9 +805,9 @@ static int update_unit(struct device *de
 	struct fw_driver *driver = (struct fw_driver *)dev->driver;
 
 	if (is_fw_unit(dev) && driver != NULL && driver->update != NULL) {
-		down(&dev->sem);
+		device_lock(dev);
 		driver->update(unit);
-		up(&dev->sem);
+		device_unlock(dev);
 	}
 
 	return 0;
@@ -905,7 +948,7 @@ static void fw_device_init(struct work_s
 	 * device.
 	 */
 
-	if (read_bus_info_block(device, device->generation) < 0) {
+	if (read_config_rom(device, device->generation) < 0) {
 		if (device->config_rom_retries < MAX_RETRIES &&
 		    atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
 			device->config_rom_retries++;
@@ -1022,7 +1065,7 @@ enum {
 };
 
 /* Reread and compare bus info block and header of root directory */
-static int reread_bus_info_block(struct fw_device *device, int generation)
+static int reread_config_rom(struct fw_device *device, int generation)
 {
 	u32 q;
 	int i;
@@ -1048,7 +1091,7 @@ static void fw_device_refresh(struct wor
 	struct fw_card *card = device->card;
 	int node_id = device->node_id;
 
-	switch (reread_bus_info_block(device, device->generation)) {
+	switch (reread_config_rom(device, device->generation)) {
 	case REREAD_BIB_ERROR:
 		if (device->config_rom_retries < MAX_RETRIES / 2 &&
 		    atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
@@ -1082,7 +1125,7 @@ static void fw_device_refresh(struct wor
 	 */
 	device_for_each_child(&device->device, NULL, shutdown_unit);
 
-	if (read_bus_info_block(device, device->generation) < 0) {
+	if (read_config_rom(device, device->generation) < 0) {
 		if (device->config_rom_retries < MAX_RETRIES &&
 		    atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
 			device->config_rom_retries++;
diff -druNp linux-libre-2.6.33-gnu1/drivers/firewire/core.h linux-libre-2.6.34-gnu1/drivers/firewire/core.h
--- linux-libre-2.6.33-gnu1/drivers/firewire/core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firewire/core.h	2010-05-16 17:17:36.000000000 -0400
@@ -70,7 +70,7 @@ struct fw_card_driver {
 	int (*enable_phys_dma)(struct fw_card *card,
 			       int node_id, int generation);
 
-	u64 (*get_bus_time)(struct fw_card *card);
+	u32 (*get_cycle_time)(struct fw_card *card);
 
 	struct fw_iso_context *
 	(*allocate_iso_context)(struct fw_card *card,
diff -druNp linux-libre-2.6.33-gnu1/drivers/firewire/core-iso.c linux-libre-2.6.34-gnu1/drivers/firewire/core-iso.c
--- linux-libre-2.6.33-gnu1/drivers/firewire/core-iso.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firewire/core-iso.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/firewire-constants.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
 
@@ -189,7 +190,7 @@ static int manage_bandwidth(struct fw_ca
 	for (try = 0; try < 5; try++) {
 		new = allocate ? old - bandwidth : old + bandwidth;
 		if (new < 0 || new > BANDWIDTH_AVAILABLE_INITIAL)
-			break;
+			return -EBUSY;
 
 		data[0] = cpu_to_be32(old);
 		data[1] = cpu_to_be32(new);
@@ -217,7 +218,7 @@ static int manage_channel(struct fw_card
 		u32 channels_mask, u64 offset, bool allocate, __be32 data[2])
 {
 	__be32 c, all, old;
-	int i, retry = 5;
+	int i, ret = -EIO, retry = 5;
 
 	old = all = allocate ? cpu_to_be32(~0) : 0;
 
@@ -225,6 +226,8 @@ static int manage_channel(struct fw_card
 		if (!(channels_mask & 1 << i))
 			continue;
 
+		ret = -EBUSY;
+
 		c = cpu_to_be32(1 << (31 - i));
 		if ((old & c) != (all & c))
 			continue;
@@ -250,12 +253,16 @@ static int manage_channel(struct fw_card
 
 			/* 1394-1995 IRM, fall through to retry. */
 		default:
-			if (retry--)
+			if (retry) {
+				retry--;
 				i--;
+			} else {
+				ret = -EIO;
+			}
 		}
 	}
 
-	return -EIO;
+	return ret;
 }
 
 static void deallocate_channel(struct fw_card *card, int irm_id,
@@ -331,8 +338,9 @@ void fw_iso_resource_manage(struct fw_ca
 	if (ret < 0)
 		*bandwidth = 0;
 
-	if (allocate && ret < 0 && c >= 0) {
-		deallocate_channel(card, irm_id, generation, c, buffer);
+	if (allocate && ret < 0) {
+		if (c >= 0)
+			deallocate_channel(card, irm_id, generation, c, buffer);
 		*channel = ret;
 	}
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/firewire/core-transaction.c linux-libre-2.6.34-gnu1/drivers/firewire/core-transaction.c
--- linux-libre-2.6.33-gnu1/drivers/firewire/core-transaction.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firewire/core-transaction.c	2010-05-16 17:17:36.000000000 -0400
@@ -921,23 +921,15 @@ static void handle_registers(struct fw_c
 		void *payload, size_t length, void *callback_data)
 {
 	int reg = offset & ~CSR_REGISTER_BASE;
-	unsigned long long bus_time;
 	__be32 *data = payload;
 	int rcode = RCODE_COMPLETE;
 
 	switch (reg) {
 	case CSR_CYCLE_TIME:
-	case CSR_BUS_TIME:
-		if (!TCODE_IS_READ_REQUEST(tcode) || length != 4) {
-			rcode = RCODE_TYPE_ERROR;
-			break;
-		}
-
-		bus_time = card->driver->get_bus_time(card);
-		if (reg == CSR_CYCLE_TIME)
-			*data = cpu_to_be32(bus_time);
+		if (TCODE_IS_READ_REQUEST(tcode) && length == 4)
+			*data = cpu_to_be32(card->driver->get_cycle_time(card));
 		else
-			*data = cpu_to_be32(bus_time >> 25);
+			rcode = RCODE_TYPE_ERROR;
 		break;
 
 	case CSR_BROADCAST_CHANNEL:
@@ -968,6 +960,9 @@ static void handle_registers(struct fw_c
 	case CSR_BUSY_TIMEOUT:
 		/* FIXME: Implement this. */
 
+	case CSR_BUS_TIME:
+		/* Useless without initialization by the bus manager. */
+
 	default:
 		rcode = RCODE_ADDRESS_ERROR;
 		break;
diff -druNp linux-libre-2.6.33-gnu1/drivers/firewire/net.c linux-libre-2.6.34-gnu1/drivers/firewire/net.c
--- linux-libre-2.6.33-gnu1/drivers/firewire/net.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firewire/net.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/mutex.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 
 #include <asm/unaligned.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/firewire/ohci.c linux-libre-2.6.34-gnu1/drivers/firewire/ohci.c
--- linux-libre-2.6.33-gnu1/drivers/firewire/ohci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firewire/ohci.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/firewire.h>
 #include <linux/firewire-constants.h>
-#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -35,10 +34,10 @@
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 
-#include <asm/atomic.h>
 #include <asm/byteorder.h>
 #include <asm/page.h>
 #include <asm/system.h>
@@ -73,20 +72,6 @@ struct descriptor {
 	__le16 transfer_status;
 } __attribute__((aligned(16)));
 
-struct db_descriptor {
-	__le16 first_size;
-	__le16 control;
-	__le16 second_req_count;
-	__le16 first_req_count;
-	__le32 branch_address;
-	__le16 second_res_count;
-	__le16 first_res_count;
-	__le32 reserved0;
-	__le32 first_buffer;
-	__le32 second_buffer;
-	__le32 reserved1;
-} __attribute__((aligned(16)));
-
 #define CONTROL_SET(regs)	(regs)
 #define CONTROL_CLEAR(regs)	((regs) + 4)
 #define COMMAND_PTR(regs)	((regs) + 12)
@@ -181,31 +166,16 @@ struct fw_ohci {
 	struct fw_card card;
 
 	__iomem char *registers;
-	dma_addr_t self_id_bus;
-	__le32 *self_id_cpu;
-	struct tasklet_struct bus_reset_tasklet;
 	int node_id;
 	int generation;
 	int request_generation;	/* for timestamping incoming requests */
-	atomic_t bus_seconds;
-
-	bool use_dualbuffer;
-	bool old_uninorth;
-	bool bus_reset_packet_quirk;
+	unsigned quirks;
 
 	/*
 	 * Spinlock for accessing fw_ohci data.  Never call out of
 	 * this driver with this lock held.
 	 */
 	spinlock_t lock;
-	u32 self_id_buffer[512];
-
-	/* Config rom buffers */
-	__be32 *config_rom;
-	dma_addr_t config_rom_bus;
-	__be32 *next_config_rom;
-	dma_addr_t next_config_rom_bus;
-	__be32 next_header;
 
 	struct ar_context ar_request_ctx;
 	struct ar_context ar_response_ctx;
@@ -217,6 +187,18 @@ struct fw_ohci {
 	u64 ir_context_channels;
 	u32 ir_context_mask;
 	struct iso_context *ir_context_list;
+
+	__be32    *config_rom;
+	dma_addr_t config_rom_bus;
+	__be32    *next_config_rom;
+	dma_addr_t next_config_rom_bus;
+	__be32     next_header;
+
+	__le32    *self_id_cpu;
+	dma_addr_t self_id_bus;
+	struct tasklet_struct bus_reset_tasklet;
+
+	u32 self_id_buffer[512];
 };
 
 static inline struct fw_ohci *fw_ohci(struct fw_card *card)
@@ -249,6 +231,34 @@ static inline struct fw_ohci *fw_ohci(st
 
 static char ohci_driver_name[] = KBUILD_MODNAME;
 
+#define PCI_DEVICE_ID_TI_TSB12LV22	0x8009
+
+#define QUIRK_CYCLE_TIMER		1
+#define QUIRK_RESET_PACKET		2
+#define QUIRK_BE_HEADERS		4
+
+/* In case of multiple matches in ohci_quirks[], only the first one is used. */
+static const struct {
+	unsigned short vendor, device, flags;
+} ohci_quirks[] = {
+	{PCI_VENDOR_ID_TI,	PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER |
+							    QUIRK_RESET_PACKET},
+	{PCI_VENDOR_ID_TI,	PCI_ANY_ID,	QUIRK_RESET_PACKET},
+	{PCI_VENDOR_ID_AL,	PCI_ANY_ID,	QUIRK_CYCLE_TIMER},
+	{PCI_VENDOR_ID_NEC,	PCI_ANY_ID,	QUIRK_CYCLE_TIMER},
+	{PCI_VENDOR_ID_VIA,	PCI_ANY_ID,	QUIRK_CYCLE_TIMER},
+	{PCI_VENDOR_ID_APPLE,	PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS},
+};
+
+/* This overrides anything that was found in ohci_quirks[]. */
+static int param_quirks;
+module_param_named(quirks, param_quirks, int, 0644);
+MODULE_PARM_DESC(quirks, "Chip quirks (default = 0"
+	", nonatomic cycle timer = "	__stringify(QUIRK_CYCLE_TIMER)
+	", reset packet generation = "	__stringify(QUIRK_RESET_PACKET)
+	", AR/selfID endianess = "	__stringify(QUIRK_BE_HEADERS)
+	")");
+
 #ifdef CONFIG_FIREWIRE_OHCI_DEBUG
 
 #define OHCI_PARAM_DEBUG_AT_AR		1
@@ -275,7 +285,7 @@ static void log_irqs(u32 evt)
 	    !(evt & OHCI1394_busReset))
 		return;
 
-	fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt,
+	fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt,
 	    evt & OHCI1394_selfIDComplete	? " selfID"		: "",
 	    evt & OHCI1394_RQPkt		? " AR_req"		: "",
 	    evt & OHCI1394_RSPkt		? " AR_resp"		: "",
@@ -285,7 +295,6 @@ static void log_irqs(u32 evt)
 	    evt & OHCI1394_isochTx		? " IT"			: "",
 	    evt & OHCI1394_postedWriteErr	? " postedWriteErr"	: "",
 	    evt & OHCI1394_cycleTooLong		? " cycleTooLong"	: "",
-	    evt & OHCI1394_cycle64Seconds	? " cycle64Seconds"	: "",
 	    evt & OHCI1394_cycleInconsistent	? " cycleInconsistent"	: "",
 	    evt & OHCI1394_regAccessFail	? " regAccessFail"	: "",
 	    evt & OHCI1394_busReset		? " busReset"		: "",
@@ -293,8 +302,7 @@ static void log_irqs(u32 evt)
 		    OHCI1394_RSPkt | OHCI1394_reqTxComplete |
 		    OHCI1394_respTxComplete | OHCI1394_isochRx |
 		    OHCI1394_isochTx | OHCI1394_postedWriteErr |
-		    OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds |
-		    OHCI1394_cycleInconsistent |
+		    OHCI1394_cycleTooLong | OHCI1394_cycleInconsistent |
 		    OHCI1394_regAccessFail | OHCI1394_busReset)
 						? " ?"			: "");
 }
@@ -524,7 +532,7 @@ static void ar_context_release(struct ar
 
 #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
 #define cond_le32_to_cpu(v) \
-	(ohci->old_uninorth ? (__force __u32)(v) : le32_to_cpu(v))
+	(ohci->quirks & QUIRK_BE_HEADERS ? (__force __u32)(v) : le32_to_cpu(v))
 #else
 #define cond_le32_to_cpu(v) le32_to_cpu(v)
 #endif
@@ -605,7 +613,7 @@ static __le32 *handle_ar_packet(struct a
 	 * at a slightly incorrect time (in bus_reset_tasklet).
 	 */
 	if (evt == OHCI1394_evt_bus_reset) {
-		if (!ohci->bus_reset_packet_quirk)
+		if (!(ohci->quirks & QUIRK_RESET_PACKET))
 			ohci->request_generation = (p.header[2] >> 16) & 0xff;
 	} else if (ctx == &ohci->ar_request_ctx) {
 		fw_core_handle_request(&ohci->card, &p);
@@ -1150,7 +1158,7 @@ static void handle_local_lock(struct fw_
 			      struct fw_packet *packet, u32 csr)
 {
 	struct fw_packet response;
-	int tcode, length, ext_tcode, sel;
+	int tcode, length, ext_tcode, sel, try;
 	__be32 *payload, lock_old;
 	u32 lock_arg, lock_data;
 
@@ -1177,21 +1185,26 @@ static void handle_local_lock(struct fw_
 	reg_write(ohci, OHCI1394_CSRCompareData, lock_arg);
 	reg_write(ohci, OHCI1394_CSRControl, sel);
 
-	if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000)
-		lock_old = cpu_to_be32(reg_read(ohci, OHCI1394_CSRData));
-	else
-		fw_notify("swap not done yet\n");
+	for (try = 0; try < 20; try++)
+		if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) {
+			lock_old = cpu_to_be32(reg_read(ohci,
+							OHCI1394_CSRData));
+			fw_fill_response(&response, packet->header,
+					 RCODE_COMPLETE,
+					 &lock_old, sizeof(lock_old));
+			goto out;
+		}
+
+	fw_error("swap not done (CSR lock timeout)\n");
+	fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0);
 
-	fw_fill_response(&response, packet->header,
-			 RCODE_COMPLETE, &lock_old, sizeof(lock_old));
  out:
 	fw_core_handle_response(&ohci->card, &response);
 }
 
 static void handle_local_request(struct context *ctx, struct fw_packet *packet)
 {
-	u64 offset;
-	u32 csr;
+	u64 offset, csr;
 
 	if (ctx == &ctx->ohci->at_request_ctx) {
 		packet->ack = ACK_PENDING;
@@ -1329,7 +1342,7 @@ static void bus_reset_tasklet(unsigned l
 	context_stop(&ohci->at_response_ctx);
 	reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
 
-	if (ohci->bus_reset_packet_quirk)
+	if (ohci->quirks & QUIRK_RESET_PACKET)
 		ohci->request_generation = generation;
 
 	/*
@@ -1384,7 +1397,7 @@ static void bus_reset_tasklet(unsigned l
 static irqreturn_t irq_handler(int irq, void *data)
 {
 	struct fw_ohci *ohci = data;
-	u32 event, iso_event, cycle_time;
+	u32 event, iso_event;
 	int i;
 
 	event = reg_read(ohci, OHCI1394_IntEventClear);
@@ -1454,12 +1467,6 @@ static irqreturn_t irq_handler(int irq,
 			fw_notify("isochronous cycle inconsistent\n");
 	}
 
-	if (event & OHCI1394_cycle64Seconds) {
-		cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
-		if ((cycle_time & 0x80000000) == 0)
-			atomic_inc(&ohci->bus_seconds);
-	}
-
 	return IRQ_HANDLED;
 }
 
@@ -1553,8 +1560,7 @@ static int ohci_enable(struct fw_card *c
 		  OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
 		  OHCI1394_isochRx | OHCI1394_isochTx |
 		  OHCI1394_postedWriteErr | OHCI1394_cycleTooLong |
-		  OHCI1394_cycleInconsistent |
-		  OHCI1394_cycle64Seconds | OHCI1394_regAccessFail |
+		  OHCI1394_cycleInconsistent | OHCI1394_regAccessFail |
 		  OHCI1394_masterIntEnable);
 	if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS)
 		reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset);
@@ -1794,16 +1800,61 @@ static int ohci_enable_phys_dma(struct f
 #endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */
 }
 
-static u64 ohci_get_bus_time(struct fw_card *card)
+static u32 cycle_timer_ticks(u32 cycle_timer)
+{
+	u32 ticks;
+
+	ticks = cycle_timer & 0xfff;
+	ticks += 3072 * ((cycle_timer >> 12) & 0x1fff);
+	ticks += (3072 * 8000) * (cycle_timer >> 25);
+
+	return ticks;
+}
+
+/*
+ * Some controllers exhibit one or more of the following bugs when updating the
+ * iso cycle timer register:
+ *  - When the lowest six bits are wrapping around to zero, a read that happens
+ *    at the same time will return garbage in the lowest ten bits.
+ *  - When the cycleOffset field wraps around to zero, the cycleCount field is
+ *    not incremented for about 60 ns.
+ *  - Occasionally, the entire register reads zero.
+ *
+ * To catch these, we read the register three times and ensure that the
+ * difference between each two consecutive reads is approximately the same, i.e.
+ * less than twice the other.  Furthermore, any negative difference indicates an
+ * error.  (A PCI read should take at least 20 ticks of the 24.576 MHz timer to
+ * execute, so we have enough precision to compute the ratio of the differences.)
+ */
+static u32 ohci_get_cycle_time(struct fw_card *card)
 {
 	struct fw_ohci *ohci = fw_ohci(card);
-	u32 cycle_time;
-	u64 bus_time;
+	u32 c0, c1, c2;
+	u32 t0, t1, t2;
+	s32 diff01, diff12;
+	int i;
 
-	cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
-	bus_time = ((u64)atomic_read(&ohci->bus_seconds) << 32) | cycle_time;
+	c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
 
-	return bus_time;
+	if (ohci->quirks & QUIRK_CYCLE_TIMER) {
+		i = 0;
+		c1 = c2;
+		c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
+		do {
+			c0 = c1;
+			c1 = c2;
+			c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
+			t0 = cycle_timer_ticks(c0);
+			t1 = cycle_timer_ticks(c1);
+			t2 = cycle_timer_ticks(c2);
+			diff01 = t1 - t0;
+			diff12 = t2 - t1;
+		} while ((diff01 <= 0 || diff12 <= 0 ||
+			  diff01 / diff12 >= 2 || diff12 / diff01 >= 2)
+			 && i++ < 20);
+	}
+
+	return c2;
 }
 
 static void copy_iso_headers(struct iso_context *ctx, void *p)
@@ -1828,52 +1879,6 @@ static void copy_iso_headers(struct iso_
 	ctx->header_length += ctx->base.header_size;
 }
 
-static int handle_ir_dualbuffer_packet(struct context *context,
-				       struct descriptor *d,
-				       struct descriptor *last)
-{
-	struct iso_context *ctx =
-		container_of(context, struct iso_context, context);
-	struct db_descriptor *db = (struct db_descriptor *) d;
-	__le32 *ir_header;
-	size_t header_length;
-	void *p, *end;
-
-	if (db->first_res_count != 0 && db->second_res_count != 0) {
-		if (ctx->excess_bytes <= le16_to_cpu(db->second_req_count)) {
-			/* This descriptor isn't done yet, stop iteration. */
-			return 0;
-		}
-		ctx->excess_bytes -= le16_to_cpu(db->second_req_count);
-	}
-
-	header_length = le16_to_cpu(db->first_req_count) -
-		le16_to_cpu(db->first_res_count);
-
-	p = db + 1;
-	end = p + header_length;
-	while (p < end) {
-		copy_iso_headers(ctx, p);
-		ctx->excess_bytes +=
-			(le32_to_cpu(*(__le32 *)(p + 4)) >> 16) & 0xffff;
-		p += max(ctx->base.header_size, (size_t)8);
-	}
-
-	ctx->excess_bytes -= le16_to_cpu(db->second_req_count) -
-		le16_to_cpu(db->second_res_count);
-
-	if (le16_to_cpu(db->control) & DESCRIPTOR_IRQ_ALWAYS) {
-		ir_header = (__le32 *) (db + 1);
-		ctx->base.callback(&ctx->base,
-				   le32_to_cpu(ir_header[0]) & 0xffff,
-				   ctx->header_length, ctx->header,
-				   ctx->base.callback_data);
-		ctx->header_length = 0;
-	}
-
-	return 1;
-}
-
 static int handle_ir_packet_per_buffer(struct context *context,
 				       struct descriptor *d,
 				       struct descriptor *last)
@@ -1960,10 +1965,7 @@ static struct fw_iso_context *ohci_alloc
 		channels = &ohci->ir_context_channels;
 		mask = &ohci->ir_context_mask;
 		list = ohci->ir_context_list;
-		if (ohci->use_dualbuffer)
-			callback = handle_ir_dualbuffer_packet;
-		else
-			callback = handle_ir_packet_per_buffer;
+		callback = handle_ir_packet_per_buffer;
 	}
 
 	spin_lock_irqsave(&ohci->lock, flags);
@@ -2026,8 +2028,6 @@ static int ohci_start_iso(struct fw_iso_
 	} else {
 		index = ctx - ohci->ir_context_list;
 		control = IR_CONTEXT_ISOCH_HEADER;
-		if (ohci->use_dualbuffer)
-			control |= IR_CONTEXT_DUAL_BUFFER_MODE;
 		match = (tags << 28) | (sync << 8) | ctx->base.channel;
 		if (cycle >= 0) {
 			match |= (cycle & 0x07fff) << 12;
@@ -2188,92 +2188,6 @@ static int ohci_queue_iso_transmit(struc
 	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)
-{
-	struct iso_context *ctx = container_of(base, struct iso_context, base);
-	struct db_descriptor *db = NULL;
-	struct descriptor *d;
-	struct fw_iso_packet *p;
-	dma_addr_t d_bus, page_bus;
-	u32 z, header_z, length, rest;
-	int page, offset, packet_count, header_size;
-
-	/*
-	 * FIXME: Cycle lost behavior should be configurable: lose
-	 * packet, retransmit or terminate..
-	 */
-
-	p = packet;
-	z = 2;
-
-	/*
-	 * 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 * max(ctx->base.header_size, (size_t)8);
-
-	/* Get header size in number of descriptors. */
-	header_z = DIV_ROUND_UP(header_size, sizeof(*d));
-	page     = payload >> PAGE_SHIFT;
-	offset   = payload & ~PAGE_MASK;
-	rest     = p->payload_length;
-	/*
-	 * The controllers I've tested have not worked correctly when
-	 * second_req_count is zero.  Rather than do something we know won't
-	 * work, return an error
-	 */
-	if (rest == 0)
-		return -EINVAL;
-
-	while (rest > 0) {
-		d = context_get_descriptors(&ctx->context,
-					    z + header_z, &d_bus);
-		if (d == NULL)
-			return -ENOMEM;
-
-		db = (struct db_descriptor *) d;
-		db->control = cpu_to_le16(DESCRIPTOR_STATUS |
-					  DESCRIPTOR_BRANCH_ALWAYS);
-		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;
-		} else {
-			db->first_req_count = cpu_to_le16(header_size);
-		}
-		db->first_res_count = db->first_req_count;
-		db->first_buffer = cpu_to_le32(d_bus + sizeof(*db));
-
-		if (p->skip && rest == p->payload_length)
-			length = 4;
-		else if (offset + rest < PAGE_SIZE)
-			length = rest;
-		else
-			length = PAGE_SIZE - offset;
-
-		db->second_req_count = cpu_to_le16(length);
-		db->second_res_count = db->second_req_count;
-		page_bus = page_private(buffer->pages[page]);
-		db->second_buffer = cpu_to_le32(page_bus + offset);
-
-		if (p->interrupt && length == rest)
-			db->control |= cpu_to_le16(DESCRIPTOR_IRQ_ALWAYS);
-
-		context_append(&ctx->context, d, z, header_z);
-		offset = (offset + length) & ~PAGE_MASK;
-		rest -= length;
-		if (offset == 0)
-			page++;
-	}
-
-	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,
@@ -2364,9 +2278,6 @@ static int ohci_queue_iso(struct fw_iso_
 	spin_lock_irqsave(&ctx->context.ohci->lock, flags);
 	if (base->type == FW_ISO_CONTEXT_TRANSMIT)
 		ret = ohci_queue_iso_transmit(base, packet, buffer, payload);
-	else if (ctx->context.ohci->use_dualbuffer)
-		ret = ohci_queue_iso_receive_dualbuffer(base, packet,
-							buffer, payload);
 	else
 		ret = ohci_queue_iso_receive_packet_per_buffer(base, packet,
 							buffer, payload);
@@ -2383,7 +2294,7 @@ static const struct fw_card_driver ohci_
 	.send_response		= ohci_send_response,
 	.cancel_packet		= ohci_cancel_packet,
 	.enable_phys_dma	= ohci_enable_phys_dma,
-	.get_bus_time		= ohci_get_bus_time,
+	.get_cycle_time		= ohci_get_cycle_time,
 
 	.allocate_iso_context	= ohci_allocate_iso_context,
 	.free_iso_context	= ohci_free_iso_context,
@@ -2421,17 +2332,13 @@ static void ohci_pmac_off(struct pci_dev
 #define ohci_pmac_off(dev)
 #endif /* CONFIG_PPC_PMAC */
 
-#define PCI_VENDOR_ID_AGERE		PCI_VENDOR_ID_ATT
-#define PCI_DEVICE_ID_AGERE_FW643	0x5901
-#define PCI_DEVICE_ID_TI_TSB43AB23	0x8024
-
 static int __devinit pci_probe(struct pci_dev *dev,
 			       const struct pci_device_id *ent)
 {
 	struct fw_ohci *ohci;
 	u32 bus_options, max_receive, link_speed, version;
 	u64 guid;
-	int err;
+	int i, err, n_ir, n_it;
 	size_t size;
 
 	ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
@@ -2472,36 +2379,15 @@ static int __devinit pci_probe(struct pc
 		goto fail_iomem;
 	}
 
-	version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
-#if 0
-	/* FIXME: make it a context option or remove dual-buffer mode */
-	ohci->use_dualbuffer = version >= OHCI_VERSION_1_1;
-#endif
-
-	/* dual-buffer mode is broken if more than one IR context is active */
-	if (dev->vendor == PCI_VENDOR_ID_AGERE &&
-	    dev->device == PCI_DEVICE_ID_AGERE_FW643)
-		ohci->use_dualbuffer = false;
-
-	/* dual-buffer mode is broken */
-	if (dev->vendor == PCI_VENDOR_ID_RICOH &&
-	    dev->device == PCI_DEVICE_ID_RICOH_R5C832)
-		ohci->use_dualbuffer = false;
-
-/* x86-32 currently doesn't use highmem for dma_alloc_coherent */
-#if !defined(CONFIG_X86_32)
-	/* dual-buffer mode is broken with descriptor addresses above 2G */
-	if (dev->vendor == PCI_VENDOR_ID_TI &&
-	    (dev->device == PCI_DEVICE_ID_TI_TSB43AB22 ||
-	     dev->device == PCI_DEVICE_ID_TI_TSB43AB23))
-		ohci->use_dualbuffer = false;
-#endif
-
-#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
-	ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE &&
-			     dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW;
-#endif
-	ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI;
+	for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++)
+		if (ohci_quirks[i].vendor == dev->vendor &&
+		    (ohci_quirks[i].device == dev->device ||
+		     ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) {
+			ohci->quirks = ohci_quirks[i].flags;
+			break;
+		}
+	if (param_quirks)
+		ohci->quirks = param_quirks;
 
 	ar_context_init(&ohci->ar_request_ctx, ohci,
 			OHCI1394_AsReqRcvContextControlSet);
@@ -2516,17 +2402,19 @@ static int __devinit pci_probe(struct pc
 		     OHCI1394_AsRspTrContextControlSet, handle_at_packet);
 
 	reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0);
-	ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet);
+	ohci->ir_context_channels = ~0ULL;
+	ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet);
 	reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0);
-	size = sizeof(struct iso_context) * hweight32(ohci->it_context_mask);
-	ohci->it_context_list = kzalloc(size, GFP_KERNEL);
+	n_ir = hweight32(ohci->ir_context_mask);
+	size = sizeof(struct iso_context) * n_ir;
+	ohci->ir_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);
+	ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet);
 	reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0);
-	size = sizeof(struct iso_context) * hweight32(ohci->ir_context_mask);
-	ohci->ir_context_list = kzalloc(size, GFP_KERNEL);
+	n_it = hweight32(ohci->it_context_mask);
+	size = sizeof(struct iso_context) * n_it;
+	ohci->it_context_list = kzalloc(size, GFP_KERNEL);
 
 	if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) {
 		err = -ENOMEM;
@@ -2553,8 +2441,11 @@ static int __devinit pci_probe(struct pc
 	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);
+	version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
+	fw_notify("Added fw-ohci device %s, OHCI v%x.%x, "
+		  "%d IR + %d IT contexts, quirks 0x%x\n",
+		  dev_name(&dev->dev), version >> 16, version & 0xff,
+		  n_ir, n_it, ohci->quirks);
 
 	return 0;
 
@@ -2662,7 +2553,7 @@ static int pci_resume(struct pci_dev *de
 }
 #endif
 
-static struct pci_device_id pci_table[] = {
+static const struct pci_device_id pci_table[] = {
 	{ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_FIREWIRE_OHCI, ~0) },
 	{ }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/firewire/sbp2.c linux-libre-2.6.34-gnu1/drivers/firewire/sbp2.c
--- linux-libre-2.6.33-gnu1/drivers/firewire/sbp2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firewire/sbp2.c	2010-05-16 17:17:36.000000000 -0400
@@ -1014,7 +1014,8 @@ static int sbp2_add_logical_unit(struct
 	return 0;
 }
 
-static int sbp2_scan_logical_unit_dir(struct sbp2_target *tgt, u32 *directory)
+static int sbp2_scan_logical_unit_dir(struct sbp2_target *tgt,
+				      const u32 *directory)
 {
 	struct fw_csr_iterator ci;
 	int key, value;
@@ -1027,7 +1028,7 @@ static int sbp2_scan_logical_unit_dir(st
 	return 0;
 }
 
-static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
+static int sbp2_scan_unit_dir(struct sbp2_target *tgt, const u32 *directory,
 			      u32 *model, u32 *firmware_revision)
 {
 	struct fw_csr_iterator ci;
@@ -1571,7 +1572,7 @@ static int sbp2_scsi_slave_configure(str
 		sdev->start_stop_pwr_cond = 1;
 
 	if (lu->tgt->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
-		blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512);
+		blk_queue_max_hw_sectors(sdev->request_queue, 128 * 1024 / 512);
 
 	blk_queue_max_segment_size(sdev->request_queue, SBP2_MAX_SEG_SIZE);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/firmware/dcdbas.c linux-libre-2.6.34-gnu1/drivers/firmware/dcdbas.c
--- linux-libre-2.6.33-gnu1/drivers/firmware/dcdbas.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firmware/dcdbas.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mc146818rtc.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/firmware/dell_rbu.c linux-libre-2.6.34-gnu1/drivers/firmware/dell_rbu.c
--- linux-libre-2.6.33-gnu1/drivers/firmware/dell_rbu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firmware/dell_rbu.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/blkdev.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/firmware/dmi-id.c linux-libre-2.6.34-gnu1/drivers/firmware/dmi-id.c
--- linux-libre-2.6.33-gnu1/drivers/firmware/dmi-id.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firmware/dmi-id.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/dmi.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 
 struct dmi_device_attribute{
 	struct device_attribute dev_attr;
diff -druNp linux-libre-2.6.33-gnu1/drivers/firmware/dmi_scan.c linux-libre-2.6.34-gnu1/drivers/firmware/dmi_scan.c
--- linux-libre-2.6.33-gnu1/drivers/firmware/dmi_scan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firmware/dmi_scan.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,6 @@
 #include <linux/dmi.h>
 #include <linux/efi.h>
 #include <linux/bootmem.h>
-#include <linux/slab.h>
 #include <asm/dmi.h>
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/firmware/edd.c linux-libre-2.6.34-gnu1/drivers/firmware/edd.c
--- linux-libre-2.6.33-gnu1/drivers/firmware/edd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firmware/edd.c	2010-05-16 17:17:36.000000000 -0400
@@ -122,7 +122,7 @@ edd_attr_show(struct kobject * kobj, str
 	return ret;
 }
 
-static struct sysfs_ops edd_attr_ops = {
+static const struct sysfs_ops edd_attr_ops = {
 	.show = edd_attr_show,
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/firmware/efivars.c linux-libre-2.6.34-gnu1/drivers/firmware/efivars.c
--- linux-libre-2.6.33-gnu1/drivers/firmware/efivars.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firmware/efivars.c	2010-05-16 17:17:36.000000000 -0400
@@ -77,6 +77,7 @@
 #include <linux/sysfs.h>
 #include <linux/kobject.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
@@ -362,7 +363,7 @@ static ssize_t efivar_attr_store(struct
 	return ret;
 }
 
-static struct sysfs_ops efivar_attr_ops = {
+static const struct sysfs_ops efivar_attr_ops = {
 	.show = efivar_attr_show,
 	.store = efivar_attr_store,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/firmware/iscsi_ibft.c linux-libre-2.6.34-gnu1/drivers/firmware/iscsi_ibft.c
--- linux-libre-2.6.33-gnu1/drivers/firmware/iscsi_ibft.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firmware/iscsi_ibft.c	2010-05-16 17:17:36.000000000 -0400
@@ -380,8 +380,7 @@ static ssize_t ibft_attr_show_nic(struct
 	struct ibft_nic *nic = entry->nic;
 	void *ibft_loc = entry->header;
 	char *str = buf;
-	char *mac;
-	int val;
+	__be32 val;
 
 	if (!nic)
 		return 0;
@@ -397,10 +396,8 @@ static ssize_t ibft_attr_show_nic(struct
 		str += sprintf_ipaddr(str, nic->ip_addr);
 		break;
 	case ibft_eth_subnet_mask:
-		val = ~((1 << (32-nic->subnet_mask_prefix))-1);
-		str += sprintf(str, NIPQUAD_FMT,
-			       (u8)(val >> 24), (u8)(val >> 16),
-			       (u8)(val >> 8), (u8)(val));
+		val = cpu_to_be32(~((1 << (32-nic->subnet_mask_prefix))-1));
+		str += sprintf(str, "%pI4", &val);
 		break;
 	case ibft_eth_origin:
 		str += sprintf(str, "%d\n", nic->origin);
@@ -421,10 +418,7 @@ static ssize_t ibft_attr_show_nic(struct
 		str += sprintf(str, "%d\n", nic->vlan);
 		break;
 	case ibft_eth_mac:
-		mac = nic->mac;
-		str += sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x\n",
-			       (u8)mac[0], (u8)mac[1], (u8)mac[2],
-			       (u8)mac[3], (u8)mac[4], (u8)mac[5]);
+		str += sprintf(str, "%pM\n", nic->mac);
 		break;
 	case ibft_eth_hostname:
 		str += sprintf_string(str, nic->hostname_len,
@@ -525,7 +519,7 @@ static ssize_t ibft_show_attribute(struc
 	return ret;
 }
 
-static struct sysfs_ops ibft_attr_ops = {
+static const struct sysfs_ops ibft_attr_ops = {
 	.show = ibft_show_attribute,
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/firmware/iscsi_ibft_find.c linux-libre-2.6.34-gnu1/drivers/firmware/iscsi_ibft_find.c
--- linux-libre-2.6.33-gnu1/drivers/firmware/iscsi_ibft_find.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firmware/iscsi_ibft_find.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/limits.h>
 #include <linux/module.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/types.h>
@@ -52,7 +51,7 @@ EXPORT_SYMBOL_GPL(ibft_addr);
  * Routine used to find the iSCSI Boot Format Table. The logical
  * kernel address is set in the ibft_addr global variable.
  */
-void __init reserve_ibft_region(void)
+unsigned long __init find_ibft_region(unsigned long *sizep)
 {
 	unsigned long pos;
 	unsigned int len = 0;
@@ -78,6 +77,11 @@ void __init reserve_ibft_region(void)
 			}
 		}
 	}
-	if (ibft_addr)
-		reserve_bootmem(pos, PAGE_ALIGN(len), BOOTMEM_DEFAULT);
+	if (ibft_addr) {
+		*sizep = PAGE_ALIGN(len);
+		return pos;
+	}
+
+	*sizep = 0;
+	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/firmware/memmap.c linux-libre-2.6.34-gnu1/drivers/firmware/memmap.c
--- linux-libre-2.6.33-gnu1/drivers/firmware/memmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/firmware/memmap.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/bootmem.h>
+#include <linux/slab.h>
 
 /*
  * Data types ------------------------------------------------------------------
@@ -74,7 +75,7 @@ static struct attribute *def_attrs[] = {
 	NULL
 };
 
-static struct sysfs_ops memmap_attr_ops = {
+static const struct sysfs_ops memmap_attr_ops = {
 	.show = memmap_attr_show,
 };
 
@@ -122,29 +123,53 @@ static int firmware_map_add_entry(u64 st
 	return 0;
 }
 
+/*
+ * Add memmap entry on sysfs
+ */
+static int add_sysfs_fw_map_entry(struct firmware_map_entry *entry)
+{
+	static int map_entries_nr;
+	static struct kset *mmap_kset;
+
+	if (!mmap_kset) {
+		mmap_kset = kset_create_and_add("memmap", NULL, firmware_kobj);
+		if (!mmap_kset)
+			return -ENOMEM;
+	}
+
+	entry->kobj.kset = mmap_kset;
+	if (kobject_add(&entry->kobj, NULL, "%d", map_entries_nr++))
+		kobject_put(&entry->kobj);
+
+	return 0;
+}
+
 /**
- * firmware_map_add() - Adds a firmware mapping entry.
+ * firmware_map_add_hotplug() - Adds a firmware mapping entry when we do
+ * memory hotplug.
  * @start: Start of the memory range.
  * @end:   End of the memory range (inclusive).
  * @type:  Type of the memory range.
  *
- * This function uses kmalloc() for memory
- * allocation. Use firmware_map_add_early() if you want to use the bootmem
- * allocator.
- *
- * That function must be called before late_initcall.
+ * Adds a firmware mapping entry. This function is for memory hotplug, it is
+ * similar to function firmware_map_add_early(). The only difference is that
+ * it will create the syfs entry dynamically.
  *
  * Returns 0 on success, or -ENOMEM if no memory could be allocated.
  **/
-int firmware_map_add(u64 start, u64 end, const char *type)
+int __meminit firmware_map_add_hotplug(u64 start, u64 end, const char *type)
 {
 	struct firmware_map_entry *entry;
 
-	entry = kmalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC);
+	entry = kzalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC);
 	if (!entry)
 		return -ENOMEM;
 
-	return firmware_map_add_entry(start, end, type, entry);
+	firmware_map_add_entry(start, end, type, entry);
+	/* create the memmap entry */
+	add_sysfs_fw_map_entry(entry);
+
+	return 0;
 }
 
 /**
@@ -154,7 +179,7 @@ int firmware_map_add(u64 start, u64 end,
  * @type:  Type of the memory range.
  *
  * Adds a firmware mapping entry. This function uses the bootmem allocator
- * for memory allocation. Use firmware_map_add() if you want to use kmalloc().
+ * for memory allocation.
  *
  * That function must be called before late_initcall.
  *
@@ -214,19 +239,10 @@ static ssize_t memmap_attr_show(struct k
  */
 static int __init memmap_init(void)
 {
-	int i = 0;
 	struct firmware_map_entry *entry;
-	struct kset *memmap_kset;
-
-	memmap_kset = kset_create_and_add("memmap", NULL, firmware_kobj);
-	if (WARN_ON(!memmap_kset))
-		return -ENOMEM;
 
-	list_for_each_entry(entry, &map_entries, list) {
-		entry->kobj.kset = memmap_kset;
-		if (kobject_add(&entry->kobj, NULL, "%d", i++))
-			kobject_put(&entry->kobj);
-	}
+	list_for_each_entry(entry, &map_entries, list)
+		add_sysfs_fw_map_entry(entry);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/adp5520-gpio.c linux-libre-2.6.34-gnu1/drivers/gpio/adp5520-gpio.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/adp5520-gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/adp5520-gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/adp5588-gpio.c linux-libre-2.6.34-gnu1/drivers/gpio/adp5588-gpio.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/adp5588-gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/adp5588-gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/gpio.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/bt8xxgpio.c linux-libre-2.6.34-gnu1/drivers/gpio/bt8xxgpio.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/bt8xxgpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/bt8xxgpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,7 @@
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 /* Steal the hardware definitions from the bttv driver. */
 #include "../media/video/bt8xx/bt848.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/cs5535-gpio.c linux-libre-2.6.34-gnu1/drivers/gpio/cs5535-gpio.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/cs5535-gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/cs5535-gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -154,7 +154,7 @@ static int chip_gpio_request(struct gpio
 
 static int chip_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
-	return cs5535_gpio_isset(offset, GPIO_OUTPUT_VAL);
+	return cs5535_gpio_isset(offset, GPIO_READ_BACK);
 }
 
 static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
@@ -172,6 +172,7 @@ static int chip_direction_input(struct g
 
 	spin_lock_irqsave(&chip->lock, flags);
 	__cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
+	__cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_ENABLE);
 	spin_unlock_irqrestore(&chip->lock, flags);
 
 	return 0;
@@ -184,6 +185,7 @@ static int chip_direction_output(struct
 
 	spin_lock_irqsave(&chip->lock, flags);
 
+	__cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
 	__cs5535_gpio_set(chip, offset, GPIO_OUTPUT_ENABLE);
 	if (val)
 		__cs5535_gpio_set(chip, offset, GPIO_OUTPUT_VAL);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/gpiolib.c linux-libre-2.6.34-gnu1/drivers/gpio/gpiolib.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/gpiolib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/gpiolib.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/seq_file.h>
 #include <linux/gpio.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 
 
 /* Optional implementation infrastructure for GPIO interfaces.
@@ -415,7 +416,8 @@ static int gpio_setup_irq(struct gpio_de
 	return 0;
 
 free_sd:
-	sysfs_put(pdesc->value_sd);
+	if (pdesc)
+		sysfs_put(pdesc->value_sd);
 free_id:
 	idr_remove(&pdesc_idr, id);
 	desc->flags &= GPIO_FLAGS_MASK;
@@ -623,7 +625,9 @@ static const struct attribute_group gpio
  * /sys/class/gpio/unexport ... write-only
  *	integer N ... number of GPIO to unexport
  */
-static ssize_t export_store(struct class *class, const char *buf, size_t len)
+static ssize_t export_store(struct class *class,
+				struct class_attribute *attr,
+				const char *buf, size_t len)
 {
 	long	gpio;
 	int	status;
@@ -653,7 +657,9 @@ done:
 	return status ? : len;
 }
 
-static ssize_t unexport_store(struct class *class, const char *buf, size_t len)
+static ssize_t unexport_store(struct class *class,
+				struct class_attribute *attr,
+				const char *buf, size_t len)
 {
 	long	gpio;
 	int	status;
@@ -1237,6 +1243,64 @@ void gpio_free(unsigned gpio)
 }
 EXPORT_SYMBOL_GPL(gpio_free);
 
+/**
+ * gpio_request_one - request a single GPIO with initial configuration
+ * @gpio:	the GPIO number
+ * @flags:	GPIO configuration as specified by GPIOF_*
+ * @label:	a literal description string of this GPIO
+ */
+int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
+{
+	int err;
+
+	err = gpio_request(gpio, label);
+	if (err)
+		return err;
+
+	if (flags & GPIOF_DIR_IN)
+		err = gpio_direction_input(gpio);
+	else
+		err = gpio_direction_output(gpio,
+				(flags & GPIOF_INIT_HIGH) ? 1 : 0);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(gpio_request_one);
+
+/**
+ * gpio_request_array - request multiple GPIOs in a single call
+ * @array:	array of the 'struct gpio'
+ * @num:	how many GPIOs in the array
+ */
+int gpio_request_array(struct gpio *array, size_t num)
+{
+	int i, err;
+
+	for (i = 0; i < num; i++, array++) {
+		err = gpio_request_one(array->gpio, array->flags, array->label);
+		if (err)
+			goto err_free;
+	}
+	return 0;
+
+err_free:
+	while (i--)
+		gpio_free((--array)->gpio);
+	return err;
+}
+EXPORT_SYMBOL_GPL(gpio_request_array);
+
+/**
+ * gpio_free_array - release multiple GPIOs in a single call
+ * @array:	array of the 'struct gpio'
+ * @num:	how many GPIOs in the array
+ */
+void gpio_free_array(struct gpio *array, size_t num)
+{
+	while (num--)
+		gpio_free((array++)->gpio);
+}
+EXPORT_SYMBOL_GPL(gpio_free_array);
 
 /**
  * gpiochip_is_requested - return string iff signal was requested
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/it8761e_gpio.c linux-libre-2.6.34-gnu1/drivers/gpio/it8761e_gpio.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/it8761e_gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/it8761e_gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,231 @@
+/*
+ *  it8761_gpio.c - GPIO interface for IT8761E Super I/O chip
+ *
+ *  Author: Denis Turischev <denis@compulab.co.il>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License 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; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+
+#include <linux/gpio.h>
+
+#define SIO_CHIP_ID		0x8761
+#define CHIP_ID_HIGH_BYTE	0x20
+#define CHIP_ID_LOW_BYTE	0x21
+
+static u8 ports[2] = { 0x2e, 0x4e };
+static u8 port;
+
+static DEFINE_SPINLOCK(sio_lock);
+
+#define GPIO_NAME		"it8761-gpio"
+#define GPIO_BA_HIGH_BYTE	0x60
+#define GPIO_BA_LOW_BYTE	0x61
+#define GPIO_IOSIZE		4
+#define GPIO1X_IO		0xf0
+#define GPIO2X_IO		0xf1
+
+static u16 gpio_ba;
+
+static u8 read_reg(u8 addr, u8 port)
+{
+	outb(addr, port);
+	return inb(port + 1);
+}
+
+static void write_reg(u8 data, u8 addr, u8 port)
+{
+	outb(addr, port);
+	outb(data, port + 1);
+}
+
+static void enter_conf_mode(u8 port)
+{
+	outb(0x87, port);
+	outb(0x61, port);
+	outb(0x55, port);
+	outb((port == 0x2e) ? 0x55 : 0xaa, port);
+}
+
+static void exit_conf_mode(u8 port)
+{
+	outb(0x2, port);
+	outb(0x2, port + 1);
+}
+
+static void enter_gpio_mode(u8 port)
+{
+	write_reg(0x2, 0x7, port);
+}
+
+static int it8761e_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
+{
+	u16 reg;
+	u8 bit;
+
+	bit = gpio_num % 8;
+	reg = (gpio_num >= 8) ? gpio_ba + 1 : gpio_ba;
+
+	return !!(inb(reg) & (1 << bit));
+}
+
+static int it8761e_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
+{
+	u8 curr_dirs;
+	u8 io_reg, bit;
+
+	bit = gpio_num % 8;
+	io_reg = (gpio_num >= 8) ? GPIO2X_IO : GPIO1X_IO;
+
+	spin_lock(&sio_lock);
+
+	enter_conf_mode(port);
+	enter_gpio_mode(port);
+
+	curr_dirs = read_reg(io_reg, port);
+
+	if (curr_dirs & (1 << bit))
+		write_reg(curr_dirs & ~(1 << bit), io_reg, port);
+
+	exit_conf_mode(port);
+
+	spin_unlock(&sio_lock);
+	return 0;
+}
+
+static void it8761e_gpio_set(struct gpio_chip *gc,
+				unsigned gpio_num, int val)
+{
+	u8 curr_vals, bit;
+	u16 reg;
+
+	bit = gpio_num % 8;
+	reg = (gpio_num >= 8) ? gpio_ba + 1 : gpio_ba;
+
+	spin_lock(&sio_lock);
+
+	curr_vals = inb(reg);
+	if (val)
+		outb(curr_vals | (1 << bit) , reg);
+	else
+		outb(curr_vals & ~(1 << bit), reg);
+
+	spin_unlock(&sio_lock);
+}
+
+static int it8761e_gpio_direction_out(struct gpio_chip *gc,
+					unsigned gpio_num, int val)
+{
+	u8 curr_dirs, io_reg, bit;
+
+	bit = gpio_num % 8;
+	io_reg = (gpio_num >= 8) ? GPIO2X_IO : GPIO1X_IO;
+
+	it8761e_gpio_set(gc, gpio_num, val);
+
+	spin_lock(&sio_lock);
+
+	enter_conf_mode(port);
+	enter_gpio_mode(port);
+
+	curr_dirs = read_reg(io_reg, port);
+
+	if (!(curr_dirs & (1 << bit)))
+		write_reg(curr_dirs | (1 << bit), io_reg, port);
+
+	exit_conf_mode(port);
+
+	spin_unlock(&sio_lock);
+	return 0;
+}
+
+static struct gpio_chip it8761e_gpio_chip = {
+	.label			= GPIO_NAME,
+	.owner			= THIS_MODULE,
+	.get			= it8761e_gpio_get,
+	.direction_input	= it8761e_gpio_direction_in,
+	.set			= it8761e_gpio_set,
+	.direction_output	= it8761e_gpio_direction_out,
+};
+
+static int __init it8761e_gpio_init(void)
+{
+	int i, id, err;
+
+	/* chip and port detection */
+	for (i = 0; i < ARRAY_SIZE(ports); i++) {
+		spin_lock(&sio_lock);
+		enter_conf_mode(ports[i]);
+
+		id = (read_reg(CHIP_ID_HIGH_BYTE, ports[i]) << 8) +
+				read_reg(CHIP_ID_LOW_BYTE, ports[i]);
+
+		exit_conf_mode(ports[i]);
+		spin_unlock(&sio_lock);
+
+		if (id == SIO_CHIP_ID) {
+			port = ports[i];
+			break;
+		}
+	}
+
+	if (!port)
+		return -ENODEV;
+
+	/* fetch GPIO base address */
+	enter_conf_mode(port);
+	enter_gpio_mode(port);
+	gpio_ba = (read_reg(GPIO_BA_HIGH_BYTE, port) << 8) +
+				read_reg(GPIO_BA_LOW_BYTE, port);
+	exit_conf_mode(port);
+
+	if (!request_region(gpio_ba, GPIO_IOSIZE, GPIO_NAME))
+		return -EBUSY;
+
+	it8761e_gpio_chip.base = -1;
+	it8761e_gpio_chip.ngpio = 16;
+
+	err = gpiochip_add(&it8761e_gpio_chip);
+	if (err < 0)
+		goto gpiochip_add_err;
+
+	return 0;
+
+gpiochip_add_err:
+	release_region(gpio_ba, GPIO_IOSIZE);
+	gpio_ba = 0;
+	return err;
+}
+
+static void __exit it8761e_gpio_exit(void)
+{
+	if (gpio_ba) {
+		gpiochip_remove(&it8761e_gpio_chip);
+
+		release_region(gpio_ba, GPIO_IOSIZE);
+		gpio_ba = 0;
+	}
+}
+module_init(it8761e_gpio_init);
+module_exit(it8761e_gpio_exit);
+
+MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
+MODULE_DESCRIPTION("GPIO interface for IT8761E Super I/O chip");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/Kconfig linux-libre-2.6.34-gnu1/drivers/gpio/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/gpio/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -65,8 +65,17 @@ config GPIO_SYSFS
 
 # put expanders in the right section, in alphabetical order
 
+config GPIO_MAX730X
+	tristate
+
 comment "Memory mapped GPIO expanders:"
 
+config GPIO_IT8761E
+	tristate "IT8761E GPIO support"
+	depends on GPIOLIB
+	help
+	  Say yes here to support GPIO functionality of IT8761E super I/O chip.
+
 config GPIO_PL061
 	bool "PrimeCell PL061 GPIO support"
 	depends on ARM_AMBA
@@ -85,8 +94,32 @@ config GPIO_VR41XX
 	help
 	  Say yes here to support the NEC VR4100 series General-purpose I/O Uint
 
+config GPIO_SCH
+	tristate "Intel SCH GPIO"
+	depends on GPIOLIB && PCI
+	select MFD_CORE
+	select LPC_SCH
+	help
+	  Say yes here to support GPIO interface on Intel Poulsbo SCH.
+	  The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are
+	  powered by the core power rail and are turned off during sleep
+	  modes (S3 and higher). The remaining four GPIOs are powered by
+	  the Intel SCH suspend power supply. These GPIOs remain
+	  active during S3. The suspend powered GPIOs can be used to wake the
+	  system from the Suspend-to-RAM state.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called sch-gpio.
+
 comment "I2C GPIO expanders:"
 
+config GPIO_MAX7300
+	tristate "Maxim MAX7300 GPIO expander"
+	depends on I2C
+	select GPIO_MAX730X
+	help
+	  GPIO driver for Maxim MAX7301 I2C-based GPIO expander.
+
 config GPIO_MAX732X
 	tristate "MAX7319, MAX7320-7327 I2C Port Expanders"
 	depends on I2C
@@ -124,6 +157,13 @@ config GPIO_PCA953X
 	  This driver can also be built as a module.  If so, the module
 	  will be called pca953x.
 
+config GPIO_PCA953X_IRQ
+	bool "Interrupt controller support for PCA953x"
+	depends on GPIO_PCA953X=y
+	help
+	  Say yes here to enable the pca953x to be used as an interrupt
+	  controller. It requires the driver to be built in the kernel.
+
 config GPIO_PCF857X
 	tristate "PCF857x, PCA{85,96}7x, and MAX732[89] I2C GPIO expanders"
 	depends on I2C
@@ -162,6 +202,20 @@ config GPIO_WM831X
 	  Say yes here to access the GPIO signals of WM831x power management
 	  chips from Wolfson Microelectronics.
 
+config GPIO_WM8350
+	tristate "WM8350 GPIOs"
+	depends on MFD_WM8350
+	help
+	  Say yes here to access the GPIO signals of WM8350 power management
+	  chips from Wolfson Microelectronics.
+
+config GPIO_WM8994
+	tristate "WM8994 GPIOs"
+	depends on MFD_WM8994
+	help
+	  Say yes here to access the GPIO signals of WM8994 audio hub
+	  CODECs from Wolfson Microelectronics.
+
 config GPIO_ADP5520
 	tristate "GPIO Support for ADP5520 PMIC"
 	depends on PMIC_ADP5520
@@ -226,8 +280,9 @@ comment "SPI GPIO expanders:"
 config GPIO_MAX7301
 	tristate "Maxim MAX7301 GPIO expander"
 	depends on SPI_MASTER
+	select GPIO_MAX730X
 	help
-	  gpio driver for Maxim MAX7301 SPI GPIO expander.
+	  GPIO driver for Maxim MAX7301 SPI-based GPIO expander.
 
 config GPIO_MCP23S08
 	tristate "Microchip MCP23S08 I/O expander"
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/langwell_gpio.c linux-libre-2.6.34-gnu1/drivers/gpio/langwell_gpio.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/langwell_gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/langwell_gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 struct lnw_gpio_register {
 	u32	GPLR[2];
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/Makefile linux-libre-2.6.34-gnu1/drivers/gpio/Makefile
--- linux-libre-2.6.33-gnu1/drivers/gpio/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,8 @@ obj-$(CONFIG_GPIOLIB)		+= gpiolib.o
 obj-$(CONFIG_GPIO_ADP5520)	+= adp5520-gpio.o
 obj-$(CONFIG_GPIO_ADP5588)	+= adp5588-gpio.o
 obj-$(CONFIG_GPIO_LANGWELL)	+= langwell_gpio.o
+obj-$(CONFIG_GPIO_MAX730X)	+= max730x.o
+obj-$(CONFIG_GPIO_MAX7300)	+= max7300.o
 obj-$(CONFIG_GPIO_MAX7301)	+= max7301.o
 obj-$(CONFIG_GPIO_MAX732X)	+= max732x.o
 obj-$(CONFIG_GPIO_MC33880)	+= mc33880.o
@@ -20,5 +22,9 @@ obj-$(CONFIG_GPIO_UCB1400)	+= ucb1400_gp
 obj-$(CONFIG_GPIO_XILINX)	+= xilinx_gpio.o
 obj-$(CONFIG_GPIO_CS5535)	+= cs5535-gpio.o
 obj-$(CONFIG_GPIO_BT8XX)	+= bt8xxgpio.o
+obj-$(CONFIG_GPIO_IT8761E)	+= it8761e_gpio.o
 obj-$(CONFIG_GPIO_VR41XX)	+= vr41xx_giu.o
 obj-$(CONFIG_GPIO_WM831X)	+= wm831x-gpio.o
+obj-$(CONFIG_GPIO_WM8350)	+= wm8350-gpiolib.o
+obj-$(CONFIG_GPIO_WM8994)	+= wm8994-gpio.o
+obj-$(CONFIG_GPIO_SCH)		+= sch_gpio.o
\ No newline at end of file
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/max7300.c linux-libre-2.6.34-gnu1/drivers/gpio/max7300.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/max7300.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/max7300.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,95 @@
+/*
+ * drivers/gpio/max7300.c
+ *
+ * Copyright (C) 2009 Wolfram Sang, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Check max730x.c for further details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/i2c.h>
+#include <linux/spi/max7301.h>
+#include <linux/slab.h>
+
+static int max7300_i2c_write(struct device *dev, unsigned int reg,
+				unsigned int val)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+
+	return i2c_smbus_write_byte_data(client, reg, val);
+}
+
+static int max7300_i2c_read(struct device *dev, unsigned int reg)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int __devinit max7300_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct max7301 *ts;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter,
+			I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	ts = kzalloc(sizeof(struct max7301), GFP_KERNEL);
+	if (!ts)
+		return -ENOMEM;
+
+	ts->read = max7300_i2c_read;
+	ts->write = max7300_i2c_write;
+	ts->dev = &client->dev;
+
+	ret = __max730x_probe(ts);
+	if (ret)
+		kfree(ts);
+	return ret;
+}
+
+static int __devexit max7300_remove(struct i2c_client *client)
+{
+	return __max730x_remove(&client->dev);
+}
+
+static const struct i2c_device_id max7300_id[] = {
+	{ "max7300", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, max7300_id);
+
+static struct i2c_driver max7300_driver = {
+	.driver = {
+		.name = "max7300",
+		.owner = THIS_MODULE,
+	},
+	.probe = max7300_probe,
+	.remove = __devexit_p(max7300_remove),
+	.id_table = max7300_id,
+};
+
+static int __init max7300_init(void)
+{
+	return i2c_add_driver(&max7300_driver);
+}
+subsys_initcall(max7300_init);
+
+static void __exit max7300_exit(void)
+{
+	i2c_del_driver(&max7300_driver);
+}
+module_exit(max7300_exit);
+
+MODULE_AUTHOR("Wolfram Sang");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MAX7300 GPIO-Expander");
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/max7301.c linux-libre-2.6.34-gnu1/drivers/gpio/max7301.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/max7301.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/max7301.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,98 +1,42 @@
-/**
+/*
  * drivers/gpio/max7301.c
  *
  * Copyright (C) 2006 Juergen Beisert, Pengutronix
  * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
+ * Copyright (C) 2009 Wolfram Sang, Pengutronix
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- * The Maxim's MAX7301 device is an SPI driven GPIO expander. There are
- * 28 GPIOs. 8 of them can trigger an interrupt. See datasheet for more
- * details
- * Note:
- * - DIN must be stable at the rising edge of clock.
- * - when writing:
- *   - always clock in 16 clocks at once
- *   - at DIN: D15 first, D0 last
- *   - D0..D7 = databyte, D8..D14 = commandbyte
- *   - D15 = low -> write command
- * - when reading
- *   - always clock in 16 clocks at once
- *   - at DIN: D15 first, D0 last
- *   - D0..D7 = dummy, D8..D14 = register address
- *   - D15 = high -> read command
- *   - raise CS and assert it again
- *   - always clock in 16 clocks at once
- *   - at DOUT: D15 first, D0 last
- *   - D0..D7 contains the data from the first cycle
- *
- * The driver exports a standard gpiochip interface
+ * Check max730x.c for further details.
  */
 
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/max7301.h>
-#include <linux/gpio.h>
-
-#define DRIVER_NAME "max7301"
-
-/*
- * Pin configurations, see MAX7301 datasheet page 6
- */
-#define PIN_CONFIG_MASK 0x03
-#define PIN_CONFIG_IN_PULLUP 0x03
-#define PIN_CONFIG_IN_WO_PULLUP 0x02
-#define PIN_CONFIG_OUT 0x01
-
-#define PIN_NUMBER 28
 
-
-/*
- * Some registers must be read back to modify.
- * To save time we cache them here in memory
- */
-struct max7301 {
-	struct mutex	lock;
-	u8		port_config[8];	/* field 0 is unused */
-	u32		out_level;	/* cached output levels */
-	struct gpio_chip chip;
-	struct spi_device *spi;
-};
-
-/**
- * max7301_write - Write a new register content
- * @spi: The SPI device
- * @reg: Register offset
- * @val: Value to write
- *
- * A write to the MAX7301 means one message with one transfer
- *
- * Returns 0 if successful or a negative value on error
- */
-static int max7301_write(struct spi_device *spi, unsigned int reg, unsigned int val)
+/* A write to the MAX7301 means one message with one transfer */
+static int max7301_spi_write(struct device *dev, unsigned int reg,
+				unsigned int val)
 {
+	struct spi_device *spi = to_spi_device(dev);
 	u16 word = ((reg & 0x7F) << 8) | (val & 0xFF);
+
 	return spi_write(spi, (const u8 *)&word, sizeof(word));
 }
 
-/**
- * max7301_read - Read back register content
- * @spi: The SPI device
- * @reg: Register offset
- *
- * A read from the MAX7301 means two transfers; here, one message each
- *
- * Returns positive 8 bit value from device if successful or a
- * negative value on error
- */
-static int max7301_read(struct spi_device *spi, unsigned int reg)
+/* A read from the MAX7301 means two transfers; here, one message each */
+
+static int max7301_spi_read(struct device *dev, unsigned int reg)
 {
 	int ret;
 	u16 word;
+	struct spi_device *spi = to_spi_device(dev);
 
 	word = 0x8000 | (reg << 8);
 	ret = spi_write(spi, (const u8 *)&word, sizeof(word));
@@ -108,125 +52,13 @@ static int max7301_read(struct spi_devic
 	return word & 0xff;
 }
 
-static int max7301_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-	struct max7301 *ts = container_of(chip, struct max7301, chip);
-	u8 *config;
-	int ret;
-
-	/* First 4 pins are unused in the controller */
-	offset += 4;
-
-	config = &ts->port_config[offset >> 2];
-
-	mutex_lock(&ts->lock);
-
-	/* Standard GPIO API doesn't support pull-ups, has to be extended.
-	 * Hard-coding no pollup for now. */
-	*config = (*config & ~(3 << (offset & 3))) | (1 << (offset & 3));
-
-	ret = max7301_write(ts->spi, 0x08 + (offset >> 2), *config);
-
-	mutex_unlock(&ts->lock);
-
-	return ret;
-}
-
-static int __max7301_set(struct max7301 *ts, unsigned offset, int value)
-{
-	if (value) {
-		ts->out_level |= 1 << offset;
-		return max7301_write(ts->spi, 0x20 + offset, 0x01);
-	} else {
-		ts->out_level &= ~(1 << offset);
-		return max7301_write(ts->spi, 0x20 + offset, 0x00);
-	}
-}
-
-static int max7301_direction_output(struct gpio_chip *chip, unsigned offset,
-				    int value)
-{
-	struct max7301 *ts = container_of(chip, struct max7301, chip);
-	u8 *config;
-	int ret;
-
-	/* First 4 pins are unused in the controller */
-	offset += 4;
-
-	config = &ts->port_config[offset >> 2];
-
-	mutex_lock(&ts->lock);
-
-	*config = (*config & ~(3 << (offset & 3))) | (1 << (offset & 3));
-
-	ret = __max7301_set(ts, offset, value);
-
-	if (!ret)
-		ret = max7301_write(ts->spi, 0x08 + (offset >> 2), *config);
-
-	mutex_unlock(&ts->lock);
-
-	return ret;
-}
-
-static int max7301_get(struct gpio_chip *chip, unsigned offset)
-{
-	struct max7301 *ts = container_of(chip, struct max7301, chip);
-	int config, level = -EINVAL;
-
-	/* First 4 pins are unused in the controller */
-	offset += 4;
-
-	mutex_lock(&ts->lock);
-
-	config = (ts->port_config[offset >> 2] >> ((offset & 3) * 2)) & 3;
-
-	switch (config) {
-	case 1:
-		/* Output: return cached level */
-		level =  !!(ts->out_level & (1 << offset));
-		break;
-	case 2:
-	case 3:
-		/* Input: read out */
-		level = max7301_read(ts->spi, 0x20 + offset) & 0x01;
-	}
-	mutex_unlock(&ts->lock);
-
-	return level;
-}
-
-static void max7301_set(struct gpio_chip *chip, unsigned offset, int value)
-{
-	struct max7301 *ts = container_of(chip, struct max7301, chip);
-
-	/* First 4 pins are unused in the controller */
-	offset += 4;
-
-	mutex_lock(&ts->lock);
-
-	__max7301_set(ts, offset, value);
-
-	mutex_unlock(&ts->lock);
-}
-
 static int __devinit max7301_probe(struct spi_device *spi)
 {
 	struct max7301 *ts;
-	struct max7301_platform_data *pdata;
-	int i, ret;
-
-	pdata = spi->dev.platform_data;
-	if (!pdata || !pdata->base) {
-		dev_dbg(&spi->dev, "incorrect or missing platform data\n");
-		return -EINVAL;
-	}
+	int ret;
 
-	/*
-	 * bits_per_word cannot be configured in platform data
-	 */
+	/* bits_per_word cannot be configured in platform data */
 	spi->bits_per_word = 16;
-
 	ret = spi_setup(spi);
 	if (ret < 0)
 		return ret;
@@ -235,90 +67,35 @@ static int __devinit max7301_probe(struc
 	if (!ts)
 		return -ENOMEM;
 
-	mutex_init(&ts->lock);
-
-	dev_set_drvdata(&spi->dev, ts);
-
-	/* Power up the chip and disable IRQ output */
-	max7301_write(spi, 0x04, 0x01);
-
-	ts->spi = spi;
-
-	ts->chip.label = DRIVER_NAME,
-
-	ts->chip.direction_input = max7301_direction_input;
-	ts->chip.get = max7301_get;
-	ts->chip.direction_output = max7301_direction_output;
-	ts->chip.set = max7301_set;
-
-	ts->chip.base = pdata->base;
-	ts->chip.ngpio = PIN_NUMBER;
-	ts->chip.can_sleep = 1;
-	ts->chip.dev = &spi->dev;
-	ts->chip.owner = THIS_MODULE;
-
-	/*
-	 * tristate all pins in hardware and cache the
-	 * register values for later use.
-	 */
-	for (i = 1; i < 8; i++) {
-		int j;
-		/* 0xAA means input with internal pullup disabled */
-		max7301_write(spi, 0x08 + i, 0xAA);
-		ts->port_config[i] = 0xAA;
-		for (j = 0; j < 4; j++) {
-			int offset = (i - 1) * 4 + j;
-			ret = max7301_direction_input(&ts->chip, offset);
-			if (ret)
-				goto exit_destroy;
-		}
-	}
+	ts->read = max7301_spi_read;
+	ts->write = max7301_spi_write;
+	ts->dev = &spi->dev;
 
-	ret = gpiochip_add(&ts->chip);
+	ret = __max730x_probe(ts);
 	if (ret)
-		goto exit_destroy;
-
-	return ret;
-
-exit_destroy:
-	dev_set_drvdata(&spi->dev, NULL);
-	mutex_destroy(&ts->lock);
-	kfree(ts);
+		kfree(ts);
 	return ret;
 }
 
 static int __devexit max7301_remove(struct spi_device *spi)
 {
-	struct max7301 *ts;
-	int ret;
-
-	ts = dev_get_drvdata(&spi->dev);
-	if (ts == NULL)
-		return -ENODEV;
-
-	dev_set_drvdata(&spi->dev, NULL);
-
-	/* Power down the chip and disable IRQ output */
-	max7301_write(spi, 0x04, 0x00);
-
-	ret = gpiochip_remove(&ts->chip);
-	if (!ret) {
-		mutex_destroy(&ts->lock);
-		kfree(ts);
-	} else
-		dev_err(&spi->dev, "Failed to remove the GPIO controller: %d\n",
-			ret);
-
-	return ret;
+	return __max730x_remove(&spi->dev);
 }
 
+static const struct spi_device_id max7301_id[] = {
+	{ "max7301", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(spi, max7301_id);
+
 static struct spi_driver max7301_driver = {
 	.driver = {
-		.name		= DRIVER_NAME,
-		.owner		= THIS_MODULE,
+		.name = "max7301",
+		.owner = THIS_MODULE,
 	},
-	.probe		= max7301_probe,
-	.remove		= __devexit_p(max7301_remove),
+	.probe = max7301_probe,
+	.remove = __devexit_p(max7301_remove),
+	.id_table = max7301_id,
 };
 
 static int __init max7301_init(void)
@@ -336,7 +113,6 @@ static void __exit max7301_exit(void)
 }
 module_exit(max7301_exit);
 
-MODULE_AUTHOR("Juergen Beisert");
+MODULE_AUTHOR("Juergen Beisert, Wolfram Sang");
 MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("MAX7301 SPI based GPIO-Expander");
-MODULE_ALIAS("spi:" DRIVER_NAME);
+MODULE_DESCRIPTION("MAX7301 GPIO-Expander");
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/max730x.c linux-libre-2.6.34-gnu1/drivers/gpio/max730x.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/max730x.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/max730x.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,249 @@
+/**
+ * drivers/gpio/max7301.c
+ *
+ * Copyright (C) 2006 Juergen Beisert, Pengutronix
+ * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
+ * Copyright (C) 2009 Wolfram Sang, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The Maxim MAX7300/1 device is an I2C/SPI driven GPIO expander. There are
+ * 28 GPIOs. 8 of them can trigger an interrupt. See datasheet for more
+ * details
+ * Note:
+ * - DIN must be stable at the rising edge of clock.
+ * - when writing:
+ *   - always clock in 16 clocks at once
+ *   - at DIN: D15 first, D0 last
+ *   - D0..D7 = databyte, D8..D14 = commandbyte
+ *   - D15 = low -> write command
+ * - when reading
+ *   - always clock in 16 clocks at once
+ *   - at DIN: D15 first, D0 last
+ *   - D0..D7 = dummy, D8..D14 = register address
+ *   - D15 = high -> read command
+ *   - raise CS and assert it again
+ *   - always clock in 16 clocks at once
+ *   - at DOUT: D15 first, D0 last
+ *   - D0..D7 contains the data from the first cycle
+ *
+ * The driver exports a standard gpiochip interface
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/spi/max7301.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+
+/*
+ * Pin configurations, see MAX7301 datasheet page 6
+ */
+#define PIN_CONFIG_MASK 0x03
+#define PIN_CONFIG_IN_PULLUP 0x03
+#define PIN_CONFIG_IN_WO_PULLUP 0x02
+#define PIN_CONFIG_OUT 0x01
+
+#define PIN_NUMBER 28
+
+static int max7301_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct max7301 *ts = container_of(chip, struct max7301, chip);
+	u8 *config;
+	u8 offset_bits;
+	int ret;
+
+	/* First 4 pins are unused in the controller */
+	offset += 4;
+	offset_bits = (offset & 3) << 1;
+
+	config = &ts->port_config[offset >> 2];
+
+	mutex_lock(&ts->lock);
+
+	/* Standard GPIO API doesn't support pull-ups, has to be extended.
+	 * Hard-coding no pollup for now. */
+	*config = (*config & ~(PIN_CONFIG_MASK << offset_bits))
+			   | (PIN_CONFIG_IN_WO_PULLUP << offset_bits);
+
+	ret = ts->write(ts->dev, 0x08 + (offset >> 2), *config);
+
+	mutex_unlock(&ts->lock);
+
+	return ret;
+}
+
+static int __max7301_set(struct max7301 *ts, unsigned offset, int value)
+{
+	if (value) {
+		ts->out_level |= 1 << offset;
+		return ts->write(ts->dev, 0x20 + offset, 0x01);
+	} else {
+		ts->out_level &= ~(1 << offset);
+		return ts->write(ts->dev, 0x20 + offset, 0x00);
+	}
+}
+
+static int max7301_direction_output(struct gpio_chip *chip, unsigned offset,
+				    int value)
+{
+	struct max7301 *ts = container_of(chip, struct max7301, chip);
+	u8 *config;
+	u8 offset_bits;
+	int ret;
+
+	/* First 4 pins are unused in the controller */
+	offset += 4;
+	offset_bits = (offset & 3) << 1;
+
+	config = &ts->port_config[offset >> 2];
+
+	mutex_lock(&ts->lock);
+
+	*config = (*config & ~(PIN_CONFIG_MASK << offset_bits))
+			   | (PIN_CONFIG_OUT << offset_bits);
+
+	ret = __max7301_set(ts, offset, value);
+
+	if (!ret)
+		ret = ts->write(ts->dev, 0x08 + (offset >> 2), *config);
+
+	mutex_unlock(&ts->lock);
+
+	return ret;
+}
+
+static int max7301_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct max7301 *ts = container_of(chip, struct max7301, chip);
+	int config, level = -EINVAL;
+
+	/* First 4 pins are unused in the controller */
+	offset += 4;
+
+	mutex_lock(&ts->lock);
+
+	config = (ts->port_config[offset >> 2] >> ((offset & 3) << 1))
+			& PIN_CONFIG_MASK;
+
+	switch (config) {
+	case PIN_CONFIG_OUT:
+		/* Output: return cached level */
+		level =  !!(ts->out_level & (1 << offset));
+		break;
+	case PIN_CONFIG_IN_WO_PULLUP:
+	case PIN_CONFIG_IN_PULLUP:
+		/* Input: read out */
+		level = ts->read(ts->dev, 0x20 + offset) & 0x01;
+	}
+	mutex_unlock(&ts->lock);
+
+	return level;
+}
+
+static void max7301_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct max7301 *ts = container_of(chip, struct max7301, chip);
+
+	/* First 4 pins are unused in the controller */
+	offset += 4;
+
+	mutex_lock(&ts->lock);
+
+	__max7301_set(ts, offset, value);
+
+	mutex_unlock(&ts->lock);
+}
+
+int __devinit __max730x_probe(struct max7301 *ts)
+{
+	struct device *dev = ts->dev;
+	struct max7301_platform_data *pdata;
+	int i, ret;
+
+	pdata = dev->platform_data;
+	if (!pdata || !pdata->base) {
+		dev_err(dev, "incorrect or missing platform data\n");
+		return -EINVAL;
+	}
+
+	mutex_init(&ts->lock);
+	dev_set_drvdata(dev, ts);
+
+	/* Power up the chip and disable IRQ output */
+	ts->write(dev, 0x04, 0x01);
+
+	ts->chip.label = dev->driver->name;
+
+	ts->chip.direction_input = max7301_direction_input;
+	ts->chip.get = max7301_get;
+	ts->chip.direction_output = max7301_direction_output;
+	ts->chip.set = max7301_set;
+
+	ts->chip.base = pdata->base;
+	ts->chip.ngpio = PIN_NUMBER;
+	ts->chip.can_sleep = 1;
+	ts->chip.dev = dev;
+	ts->chip.owner = THIS_MODULE;
+
+	/*
+	 * tristate all pins in hardware and cache the
+	 * register values for later use.
+	 */
+	for (i = 1; i < 8; i++) {
+		int j;
+		/* 0xAA means input with internal pullup disabled */
+		ts->write(dev, 0x08 + i, 0xAA);
+		ts->port_config[i] = 0xAA;
+		for (j = 0; j < 4; j++) {
+			int offset = (i - 1) * 4 + j;
+			ret = max7301_direction_input(&ts->chip, offset);
+			if (ret)
+				goto exit_destroy;
+		}
+	}
+
+	ret = gpiochip_add(&ts->chip);
+	if (ret)
+		goto exit_destroy;
+
+	return ret;
+
+exit_destroy:
+	dev_set_drvdata(dev, NULL);
+	mutex_destroy(&ts->lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(__max730x_probe);
+
+int __devexit __max730x_remove(struct device *dev)
+{
+	struct max7301 *ts = dev_get_drvdata(dev);
+	int ret;
+
+	if (ts == NULL)
+		return -ENODEV;
+
+	dev_set_drvdata(dev, NULL);
+
+	/* Power down the chip and disable IRQ output */
+	ts->write(dev, 0x04, 0x00);
+
+	ret = gpiochip_remove(&ts->chip);
+	if (!ret) {
+		mutex_destroy(&ts->lock);
+		kfree(ts);
+	} else
+		dev_err(dev, "Failed to remove GPIO controller: %d\n", ret);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(__max730x_remove);
+
+MODULE_AUTHOR("Juergen Beisert, Wolfram Sang");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MAX730x GPIO-Expanders, generic parts");
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/mc33880.c linux-libre-2.6.34-gnu1/drivers/gpio/mc33880.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/mc33880.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/mc33880.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/mc33880.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "mc33880"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/mcp23s08.c linux-libre-2.6.34-gnu1/drivers/gpio/mcp23s08.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/mcp23s08.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/mcp23s08.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/mcp23s08.h>
+#include <linux/slab.h>
 
 
 /* Registers are all 8 bits wide.
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/pca953x.c linux-libre-2.6.34-gnu1/drivers/gpio/pca953x.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/pca953x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/pca953x.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,8 +14,11 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pca953x.h>
+#include <linux/slab.h>
 #ifdef CONFIG_OF_GPIO
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
@@ -26,23 +29,28 @@
 #define PCA953X_INVERT         2
 #define PCA953X_DIRECTION      3
 
+#define PCA953X_GPIOS	       0x00FF
+#define PCA953X_INT	       0x0100
+
 static const struct i2c_device_id pca953x_id[] = {
-	{ "pca9534", 8, },
-	{ "pca9535", 16, },
+	{ "pca9534", 8  | PCA953X_INT, },
+	{ "pca9535", 16 | PCA953X_INT, },
 	{ "pca9536", 4, },
-	{ "pca9537", 4, },
-	{ "pca9538", 8, },
-	{ "pca9539", 16, },
-	{ "pca9554", 8, },
-	{ "pca9555", 16, },
+	{ "pca9537", 4  | PCA953X_INT, },
+	{ "pca9538", 8  | PCA953X_INT, },
+	{ "pca9539", 16 | PCA953X_INT, },
+	{ "pca9554", 8  | PCA953X_INT, },
+	{ "pca9555", 16 | PCA953X_INT, },
 	{ "pca9556", 8, },
 	{ "pca9557", 8, },
 
 	{ "max7310", 8, },
-	{ "max7315", 8, },
-	{ "pca6107", 8, },
-	{ "tca6408", 8, },
-	{ "tca6416", 16, },
+	{ "max7312", 16 | PCA953X_INT, },
+	{ "max7313", 16 | PCA953X_INT, },
+	{ "max7315", 8  | PCA953X_INT, },
+	{ "pca6107", 8  | PCA953X_INT, },
+	{ "tca6408", 8  | PCA953X_INT, },
+	{ "tca6416", 16 | PCA953X_INT, },
 	/* NYET:  { "tca6424", 24, }, */
 	{ }
 };
@@ -53,6 +61,15 @@ struct pca953x_chip {
 	uint16_t reg_output;
 	uint16_t reg_direction;
 
+#ifdef CONFIG_GPIO_PCA953X_IRQ
+	struct mutex irq_lock;
+	uint16_t irq_mask;
+	uint16_t irq_stat;
+	uint16_t irq_trig_raise;
+	uint16_t irq_trig_fall;
+	int	 irq_base;
+#endif
+
 	struct i2c_client *client;
 	struct pca953x_platform_data *dyn_pdata;
 	struct gpio_chip gpio_chip;
@@ -202,6 +219,222 @@ static void pca953x_setup_gpio(struct pc
 	gc->names = chip->names;
 }
 
+#ifdef CONFIG_GPIO_PCA953X_IRQ
+static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off)
+{
+	struct pca953x_chip *chip;
+
+	chip = container_of(gc, struct pca953x_chip, gpio_chip);
+	return chip->irq_base + off;
+}
+
+static void pca953x_irq_mask(unsigned int irq)
+{
+	struct pca953x_chip *chip = get_irq_chip_data(irq);
+
+	chip->irq_mask &= ~(1 << (irq - chip->irq_base));
+}
+
+static void pca953x_irq_unmask(unsigned int irq)
+{
+	struct pca953x_chip *chip = get_irq_chip_data(irq);
+
+	chip->irq_mask |= 1 << (irq - chip->irq_base);
+}
+
+static void pca953x_irq_bus_lock(unsigned int irq)
+{
+	struct pca953x_chip *chip = get_irq_chip_data(irq);
+
+	mutex_lock(&chip->irq_lock);
+}
+
+static void pca953x_irq_bus_sync_unlock(unsigned int irq)
+{
+	struct pca953x_chip *chip = get_irq_chip_data(irq);
+	uint16_t new_irqs;
+	uint16_t level;
+
+	/* Look for any newly setup interrupt */
+	new_irqs = chip->irq_trig_fall | chip->irq_trig_raise;
+	new_irqs &= ~chip->reg_direction;
+
+	while (new_irqs) {
+		level = __ffs(new_irqs);
+		pca953x_gpio_direction_input(&chip->gpio_chip, level);
+		new_irqs &= ~(1 << level);
+	}
+
+	mutex_unlock(&chip->irq_lock);
+}
+
+static int pca953x_irq_set_type(unsigned int irq, unsigned int type)
+{
+	struct pca953x_chip *chip = get_irq_chip_data(irq);
+	uint16_t level = irq - chip->irq_base;
+	uint16_t mask = 1 << level;
+
+	if (!(type & IRQ_TYPE_EDGE_BOTH)) {
+		dev_err(&chip->client->dev, "irq %d: unsupported type %d\n",
+			irq, type);
+		return -EINVAL;
+	}
+
+	if (type & IRQ_TYPE_EDGE_FALLING)
+		chip->irq_trig_fall |= mask;
+	else
+		chip->irq_trig_fall &= ~mask;
+
+	if (type & IRQ_TYPE_EDGE_RISING)
+		chip->irq_trig_raise |= mask;
+	else
+		chip->irq_trig_raise &= ~mask;
+
+	return 0;
+}
+
+static struct irq_chip pca953x_irq_chip = {
+	.name			= "pca953x",
+	.mask			= pca953x_irq_mask,
+	.unmask			= pca953x_irq_unmask,
+	.bus_lock		= pca953x_irq_bus_lock,
+	.bus_sync_unlock	= pca953x_irq_bus_sync_unlock,
+	.set_type		= pca953x_irq_set_type,
+};
+
+static uint16_t pca953x_irq_pending(struct pca953x_chip *chip)
+{
+	uint16_t cur_stat;
+	uint16_t old_stat;
+	uint16_t pending;
+	uint16_t trigger;
+	int ret;
+
+	ret = pca953x_read_reg(chip, PCA953X_INPUT, &cur_stat);
+	if (ret)
+		return 0;
+
+	/* Remove output pins from the equation */
+	cur_stat &= chip->reg_direction;
+
+	old_stat = chip->irq_stat;
+	trigger = (cur_stat ^ old_stat) & chip->irq_mask;
+
+	if (!trigger)
+		return 0;
+
+	chip->irq_stat = cur_stat;
+
+	pending = (old_stat & chip->irq_trig_fall) |
+		  (cur_stat & chip->irq_trig_raise);
+	pending &= trigger;
+
+	return pending;
+}
+
+static irqreturn_t pca953x_irq_handler(int irq, void *devid)
+{
+	struct pca953x_chip *chip = devid;
+	uint16_t pending;
+	uint16_t level;
+
+	pending = pca953x_irq_pending(chip);
+
+	if (!pending)
+		return IRQ_HANDLED;
+
+	do {
+		level = __ffs(pending);
+		handle_nested_irq(level + chip->irq_base);
+
+		pending &= ~(1 << level);
+	} while (pending);
+
+	return IRQ_HANDLED;
+}
+
+static int pca953x_irq_setup(struct pca953x_chip *chip,
+			     const struct i2c_device_id *id)
+{
+	struct i2c_client *client = chip->client;
+	struct pca953x_platform_data *pdata = client->dev.platform_data;
+	int ret;
+
+	if (pdata->irq_base && (id->driver_data & PCA953X_INT)) {
+		int lvl;
+
+		ret = pca953x_read_reg(chip, PCA953X_INPUT,
+				       &chip->irq_stat);
+		if (ret)
+			goto out_failed;
+
+		/*
+		 * There is no way to know which GPIO line generated the
+		 * interrupt.  We have to rely on the previous read for
+		 * this purpose.
+		 */
+		chip->irq_stat &= chip->reg_direction;
+		chip->irq_base = pdata->irq_base;
+		mutex_init(&chip->irq_lock);
+
+		for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) {
+			int irq = lvl + chip->irq_base;
+
+			set_irq_chip_data(irq, chip);
+			set_irq_chip_and_handler(irq, &pca953x_irq_chip,
+						 handle_edge_irq);
+			set_irq_nested_thread(irq, 1);
+#ifdef CONFIG_ARM
+			set_irq_flags(irq, IRQF_VALID);
+#else
+			set_irq_noprobe(irq);
+#endif
+		}
+
+		ret = request_threaded_irq(client->irq,
+					   NULL,
+					   pca953x_irq_handler,
+					   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+					   dev_name(&client->dev), chip);
+		if (ret) {
+			dev_err(&client->dev, "failed to request irq %d\n",
+				client->irq);
+			goto out_failed;
+		}
+
+		chip->gpio_chip.to_irq = pca953x_gpio_to_irq;
+	}
+
+	return 0;
+
+out_failed:
+	chip->irq_base = 0;
+	return ret;
+}
+
+static void pca953x_irq_teardown(struct pca953x_chip *chip)
+{
+	if (chip->irq_base)
+		free_irq(chip->client->irq, chip);
+}
+#else /* CONFIG_GPIO_PCA953X_IRQ */
+static int pca953x_irq_setup(struct pca953x_chip *chip,
+			     const struct i2c_device_id *id)
+{
+	struct i2c_client *client = chip->client;
+	struct pca953x_platform_data *pdata = client->dev.platform_data;
+
+	if (pdata->irq_base && (id->driver_data & PCA953X_INT))
+		dev_warn(&client->dev, "interrupt support not compiled in\n");
+
+	return 0;
+}
+
+static void pca953x_irq_teardown(struct pca953x_chip *chip)
+{
+}
+#endif
+
 /*
  * Handlers for alternative sources of platform_data
  */
@@ -286,7 +519,7 @@ static int __devinit pca953x_probe(struc
 	/* initialize cached registers from their original values.
 	 * we can't share this chip with another i2c master.
 	 */
-	pca953x_setup_gpio(chip, id->driver_data);
+	pca953x_setup_gpio(chip, id->driver_data & PCA953X_GPIOS);
 
 	ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
 	if (ret)
@@ -301,6 +534,9 @@ static int __devinit pca953x_probe(struc
 	if (ret)
 		goto out_failed;
 
+	ret = pca953x_irq_setup(chip, id);
+	if (ret)
+		goto out_failed;
 
 	ret = gpiochip_add(&chip->gpio_chip);
 	if (ret)
@@ -317,6 +553,7 @@ static int __devinit pca953x_probe(struc
 	return 0;
 
 out_failed:
+	pca953x_irq_teardown(chip);
 	kfree(chip->dyn_pdata);
 	kfree(chip);
 	return ret;
@@ -345,6 +582,7 @@ static int pca953x_remove(struct i2c_cli
 		return ret;
 	}
 
+	pca953x_irq_teardown(chip);
 	kfree(chip->dyn_pdata);
 	kfree(chip);
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/pl061.c linux-libre-2.6.34-gnu1/drivers/gpio/pl061.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/pl061.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/pl061.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/device.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/pl061.h>
+#include <linux/slab.h>
 
 #define GPIODIR 0x400
 #define GPIOIS  0x404
@@ -90,6 +91,12 @@ static int pl061_direction_output(struct
 	gpiodir = readb(chip->base + GPIODIR);
 	gpiodir |= 1 << offset;
 	writeb(gpiodir, chip->base + GPIODIR);
+
+	/*
+	 * gpio value is set again, because pl061 doesn't allow to set value of
+	 * a gpio pin before configuring it in OUT mode.
+	 */
+	writeb(!!value << offset, chip->base + (1 << (offset + 2)));
 	spin_unlock_irqrestore(&chip->lock, flags);
 
 	return 0;
@@ -182,7 +189,7 @@ static int pl061_irq_type(unsigned irq,
 		gpioibe &= ~(1 << offset);
 		if (trigger & IRQ_TYPE_EDGE_RISING)
 			gpioiev |= 1 << offset;
-		else
+		else if (trigger & IRQ_TYPE_EDGE_FALLING)
 			gpioiev &= ~(1 << offset);
 	}
 	writeb(gpioibe, chip->base + GPIOIBE);
@@ -203,7 +210,7 @@ static struct irq_chip pl061_irqchip = {
 
 static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
 {
-	struct list_head *chip_list = get_irq_chip_data(irq);
+	struct list_head *chip_list = get_irq_data(irq);
 	struct list_head *ptr;
 	struct pl061_gpio *chip;
 
@@ -219,7 +226,7 @@ static void pl061_irq_handler(unsigned i
 		if (pending == 0)
 			continue;
 
-		for_each_bit(offset, &pending, PL061_GPIO_NR)
+		for_each_set_bit(offset, &pending, PL061_GPIO_NR)
 			generic_handle_irq(pl061_to_irq(&chip->gc, offset));
 	}
 	desc->chip->unmask(irq);
@@ -296,9 +303,9 @@ static int __init pl061_probe(struct amb
 			goto iounmap;
 		}
 		INIT_LIST_HEAD(chip_list);
-		set_irq_chip_data(irq, chip_list);
+		set_irq_data(irq, chip_list);
 	} else
-		chip_list = get_irq_chip_data(irq);
+		chip_list = get_irq_data(irq);
 	list_add(&chip->list, chip_list);
 
 	for (i = 0; i < PL061_GPIO_NR; i++) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/sch_gpio.c linux-libre-2.6.34-gnu1/drivers/gpio/sch_gpio.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/sch_gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/sch_gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,295 @@
+/*
+ *  sch_gpio.c - GPIO interface for Intel Poulsbo SCH
+ *
+ *  Copyright (c) 2010 CompuLab Ltd
+ *  Author: Denis Turischev <denis@compulab.co.il>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License 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; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/acpi.h>
+#include <linux/platform_device.h>
+
+#include <linux/gpio.h>
+
+static DEFINE_SPINLOCK(gpio_lock);
+
+#define CGEN	(0x00)
+#define CGIO	(0x04)
+#define CGLV	(0x08)
+
+#define RGEN	(0x20)
+#define RGIO	(0x24)
+#define RGLV	(0x28)
+
+static unsigned short gpio_ba;
+
+static int sch_gpio_core_direction_in(struct gpio_chip *gc, unsigned  gpio_num)
+{
+	u8 curr_dirs;
+	unsigned short offset, bit;
+
+	spin_lock(&gpio_lock);
+
+	offset = CGIO + gpio_num / 8;
+	bit = gpio_num % 8;
+
+	curr_dirs = inb(gpio_ba + offset);
+
+	if (!(curr_dirs & (1 << bit)))
+		outb(curr_dirs | (1 << bit), gpio_ba + offset);
+
+	spin_unlock(&gpio_lock);
+	return 0;
+}
+
+static int sch_gpio_core_get(struct gpio_chip *gc, unsigned gpio_num)
+{
+	int res;
+	unsigned short offset, bit;
+
+	offset = CGLV + gpio_num / 8;
+	bit = gpio_num % 8;
+
+	res = !!(inb(gpio_ba + offset) & (1 << bit));
+	return res;
+}
+
+static void sch_gpio_core_set(struct gpio_chip *gc, unsigned gpio_num, int val)
+{
+	u8 curr_vals;
+	unsigned short offset, bit;
+
+	spin_lock(&gpio_lock);
+
+	offset = CGLV + gpio_num / 8;
+	bit = gpio_num % 8;
+
+	curr_vals = inb(gpio_ba + offset);
+
+	if (val)
+		outb(curr_vals | (1 << bit), gpio_ba + offset);
+	else
+		outb((curr_vals & ~(1 << bit)), gpio_ba + offset);
+	spin_unlock(&gpio_lock);
+}
+
+static int sch_gpio_core_direction_out(struct gpio_chip *gc,
+					unsigned gpio_num, int val)
+{
+	u8 curr_dirs;
+	unsigned short offset, bit;
+
+	sch_gpio_core_set(gc, gpio_num, val);
+
+	spin_lock(&gpio_lock);
+
+	offset = CGIO + gpio_num / 8;
+	bit = gpio_num % 8;
+
+	curr_dirs = inb(gpio_ba + offset);
+	if (curr_dirs & (1 << bit))
+		outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
+
+	spin_unlock(&gpio_lock);
+	return 0;
+}
+
+static struct gpio_chip sch_gpio_core = {
+	.label			= "sch_gpio_core",
+	.owner			= THIS_MODULE,
+	.direction_input	= sch_gpio_core_direction_in,
+	.get			= sch_gpio_core_get,
+	.direction_output	= sch_gpio_core_direction_out,
+	.set			= sch_gpio_core_set,
+};
+
+static int sch_gpio_resume_direction_in(struct gpio_chip *gc,
+					unsigned gpio_num)
+{
+	u8 curr_dirs;
+
+	spin_lock(&gpio_lock);
+
+	curr_dirs = inb(gpio_ba + RGIO);
+
+	if (!(curr_dirs & (1 << gpio_num)))
+		outb(curr_dirs | (1 << gpio_num) , gpio_ba + RGIO);
+
+	spin_unlock(&gpio_lock);
+	return 0;
+}
+
+static int sch_gpio_resume_get(struct gpio_chip *gc, unsigned gpio_num)
+{
+	return !!(inb(gpio_ba + RGLV) & (1 << gpio_num));
+}
+
+static void sch_gpio_resume_set(struct gpio_chip *gc,
+				unsigned gpio_num, int val)
+{
+	u8 curr_vals;
+
+	spin_lock(&gpio_lock);
+
+	curr_vals = inb(gpio_ba + RGLV);
+
+	if (val)
+		outb(curr_vals | (1 << gpio_num), gpio_ba + RGLV);
+	else
+		outb((curr_vals & ~(1 << gpio_num)), gpio_ba + RGLV);
+
+	spin_unlock(&gpio_lock);
+}
+
+static int sch_gpio_resume_direction_out(struct gpio_chip *gc,
+					unsigned gpio_num, int val)
+{
+	u8 curr_dirs;
+
+	sch_gpio_resume_set(gc, gpio_num, val);
+
+	spin_lock(&gpio_lock);
+
+	curr_dirs = inb(gpio_ba + RGIO);
+	if (curr_dirs & (1 << gpio_num))
+		outb(curr_dirs & ~(1 << gpio_num), gpio_ba + RGIO);
+
+	spin_unlock(&gpio_lock);
+	return 0;
+}
+
+static struct gpio_chip sch_gpio_resume = {
+	.label			= "sch_gpio_resume",
+	.owner			= THIS_MODULE,
+	.direction_input	= sch_gpio_resume_direction_in,
+	.get			= sch_gpio_resume_get,
+	.direction_output	= sch_gpio_resume_direction_out,
+	.set			= sch_gpio_resume_set,
+};
+
+static int __devinit sch_gpio_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	int err;
+
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (!res)
+		return -EBUSY;
+
+	if (!request_region(res->start, resource_size(res), pdev->name))
+		return -EBUSY;
+
+	gpio_ba = res->start;
+
+	sch_gpio_core.base = 0;
+	sch_gpio_core.ngpio = 10;
+	sch_gpio_core.dev = &pdev->dev;
+
+	sch_gpio_resume.base = 10;
+	sch_gpio_resume.ngpio = 4;
+	sch_gpio_resume.dev = &pdev->dev;
+
+	err = gpiochip_add(&sch_gpio_core);
+	if (err < 0)
+		goto err_sch_gpio_core;
+
+	err = gpiochip_add(&sch_gpio_resume);
+	if (err < 0)
+		goto err_sch_gpio_resume;
+
+	/*
+	 * GPIO[6:0] enabled by default
+	 * GPIO7 is configured by the CMC as SLPIOVR
+	 * Enable GPIO[9:8] core powered gpios explicitly
+	 */
+	outb(0x3, gpio_ba + CGEN + 1);
+	/*
+	 * SUS_GPIO[2:0] enabled by default
+	 * Enable SUS_GPIO3 resume powered gpio explicitly
+	 */
+	outb(0x8, gpio_ba + RGEN);
+
+	return 0;
+
+err_sch_gpio_resume:
+	err = gpiochip_remove(&sch_gpio_core);
+	if (err)
+		dev_err(&pdev->dev, "%s failed, %d\n",
+				"gpiochip_remove()", err);
+
+err_sch_gpio_core:
+	release_region(res->start, resource_size(res));
+	gpio_ba = 0;
+
+	return err;
+}
+
+static int __devexit sch_gpio_remove(struct platform_device *pdev)
+{
+	struct resource *res;
+	if (gpio_ba) {
+		int err;
+
+		err  = gpiochip_remove(&sch_gpio_core);
+		if (err)
+			dev_err(&pdev->dev, "%s failed, %d\n",
+				"gpiochip_remove()", err);
+		err = gpiochip_remove(&sch_gpio_resume);
+		if (err)
+			dev_err(&pdev->dev, "%s failed, %d\n",
+				"gpiochip_remove()", err);
+
+		res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+
+		release_region(res->start, resource_size(res));
+		gpio_ba = 0;
+
+		return err;
+	}
+
+	return 0;
+}
+
+static struct platform_driver sch_gpio_driver = {
+	.driver = {
+		.name = "sch_gpio",
+		.owner = THIS_MODULE,
+	},
+	.probe		= sch_gpio_probe,
+	.remove		= __devexit_p(sch_gpio_remove),
+};
+
+static int __init sch_gpio_init(void)
+{
+	return platform_driver_register(&sch_gpio_driver);
+}
+
+static void __exit sch_gpio_exit(void)
+{
+	platform_driver_unregister(&sch_gpio_driver);
+}
+
+module_init(sch_gpio_init);
+module_exit(sch_gpio_exit);
+
+MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
+MODULE_DESCRIPTION("GPIO interface for Intel Poulsbo SCH");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sch_gpio");
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/timbgpio.c linux-libre-2.6.34-gnu1/drivers/gpio/timbgpio.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/timbgpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/timbgpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,9 +23,11 @@
 #include <linux/module.h>
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
+#include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/timb_gpio.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "timb-gpio"
 
@@ -37,6 +39,8 @@
 #define TGPIO_ICR	0x14
 #define TGPIO_FLR	0x18
 #define TGPIO_LVR	0x1c
+#define TGPIO_VER	0x20
+#define TGPIO_BFLR	0x24
 
 struct timbgpio {
 	void __iomem		*membase;
@@ -125,17 +129,24 @@ static int timbgpio_irq_type(unsigned ir
 	struct timbgpio *tgpio = get_irq_chip_data(irq);
 	int offset = irq - tgpio->irq_base;
 	unsigned long flags;
-	u32 lvr, flr;
+	u32 lvr, flr, bflr = 0;
+	u32 ver;
+	int ret = 0;
 
 	if (offset < 0 || offset > tgpio->gpio.ngpio)
 		return -EINVAL;
 
+	ver = ioread32(tgpio->membase + TGPIO_VER);
+
 	spin_lock_irqsave(&tgpio->lock, flags);
 
 	lvr = ioread32(tgpio->membase + TGPIO_LVR);
 	flr = ioread32(tgpio->membase + TGPIO_FLR);
+	if (ver > 2)
+		bflr = ioread32(tgpio->membase + TGPIO_BFLR);
 
 	if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
+		bflr &= ~(1 << offset);
 		flr &= ~(1 << offset);
 		if (trigger & IRQ_TYPE_LEVEL_HIGH)
 			lvr |= 1 << offset;
@@ -143,25 +154,34 @@ static int timbgpio_irq_type(unsigned ir
 			lvr &= ~(1 << offset);
 	}
 
-	if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
-		return -EINVAL;
-	else {
+	if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
+		if (ver < 3) {
+			ret = -EINVAL;
+			goto out;
+		}
+		else {
+			flr |= 1 << offset;
+			bflr |= 1 << offset;
+		}
+	} else {
+		bflr &= ~(1 << offset);
 		flr |= 1 << offset;
-		/* opposite compared to the datasheet, but it mirrors the
-		 * reality
-		 */
 		if (trigger & IRQ_TYPE_EDGE_FALLING)
-			lvr |= 1 << offset;
-		else
 			lvr &= ~(1 << offset);
+		else
+			lvr |= 1 << offset;
 	}
 
 	iowrite32(lvr, tgpio->membase + TGPIO_LVR);
 	iowrite32(flr, tgpio->membase + TGPIO_FLR);
+	if (ver > 2)
+		iowrite32(bflr, tgpio->membase + TGPIO_BFLR);
+
 	iowrite32(1 << offset, tgpio->membase + TGPIO_ICR);
-	spin_unlock_irqrestore(&tgpio->lock, flags);
 
-	return 0;
+out:
+	spin_unlock_irqrestore(&tgpio->lock, flags);
+	return ret;
 }
 
 static void timbgpio_irq(unsigned int irq, struct irq_desc *desc)
@@ -174,7 +194,7 @@ static void timbgpio_irq(unsigned int ir
 	ipr = ioread32(tgpio->membase + TGPIO_IPR);
 	iowrite32(ipr, tgpio->membase + TGPIO_ICR);
 
-	for_each_bit(offset, &ipr, tgpio->gpio.ngpio)
+	for_each_set_bit(offset, &ipr, tgpio->gpio.ngpio)
 		generic_handle_irq(timbgpio_to_irq(&tgpio->gpio, offset));
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/twl4030-gpio.c linux-libre-2.6.34-gnu1/drivers/gpio/twl4030-gpio.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/twl4030-gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/twl4030-gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,6 @@
 #include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
-#include <linux/slab.h>
 
 #include <linux/i2c/twl.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/wm831x-gpio.c linux-libre-2.6.34-gnu1/drivers/gpio/wm831x-gpio.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/wm831x-gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/wm831x-gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/gpio.h>
 #include <linux/mfd/core.h>
@@ -38,10 +39,14 @@ static int wm831x_gpio_direction_in(stru
 {
 	struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
 	struct wm831x *wm831x = wm831x_gpio->wm831x;
+	int val = WM831X_GPN_DIR;
+
+	if (wm831x->has_gpio_ena)
+		val |= WM831X_GPN_TRI;
 
 	return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
-			       WM831X_GPN_DIR | WM831X_GPN_TRI,
-			       WM831X_GPN_DIR);
+			       WM831X_GPN_DIR | WM831X_GPN_TRI |
+			       WM831X_GPN_FN_MASK, val);
 }
 
 static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -60,23 +65,36 @@ static int wm831x_gpio_get(struct gpio_c
 		return 0;
 }
 
-static int wm831x_gpio_direction_out(struct gpio_chip *chip,
-				     unsigned offset, int value)
+static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
 	struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
 	struct wm831x *wm831x = wm831x_gpio->wm831x;
 
-	return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
-			       WM831X_GPN_DIR | WM831X_GPN_TRI, 0);
+	wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset,
+			value << offset);
 }
 
-static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+static int wm831x_gpio_direction_out(struct gpio_chip *chip,
+				     unsigned offset, int value)
 {
 	struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
 	struct wm831x *wm831x = wm831x_gpio->wm831x;
+	int val = 0;
+	int ret;
 
-	wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset,
-			value << offset);
+	if (wm831x->has_gpio_ena)
+		val |= WM831X_GPN_TRI;
+
+	ret = wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
+			      WM831X_GPN_DIR | WM831X_GPN_TRI |
+			      WM831X_GPN_FN_MASK, val);
+	if (ret < 0)
+		return ret;
+
+	/* Can only set GPIO state once it's in output mode */
+	wm831x_gpio_set(chip, offset, value);
+
+	return 0;
 }
 
 static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
@@ -95,7 +113,7 @@ static void wm831x_gpio_dbg_show(struct
 {
 	struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
 	struct wm831x *wm831x = wm831x_gpio->wm831x;
-	int i;
+	int i, tristated;
 
 	for (i = 0; i < chip->ngpio; i++) {
 		int gpio = i + chip->base;
@@ -162,15 +180,19 @@ static void wm831x_gpio_dbg_show(struct
 			break;
 		}
 
+		tristated = reg & WM831X_GPN_TRI;
+		if (wm831x->has_gpio_ena)
+			tristated = !tristated;
+
 		seq_printf(s, " %s %s %s %s%s\n"
 			   "                                  %s%s (0x%4x)\n",
 			   reg & WM831X_GPN_DIR ? "in" : "out",
 			   wm831x_gpio_get(chip, i) ? "high" : "low",
 			   pull,
 			   powerdomain,
-			   reg & WM831X_GPN_POL ? " inverted" : "",
+			   reg & WM831X_GPN_POL ? "" : " inverted",
 			   reg & WM831X_GPN_OD ? "open-drain" : "CMOS",
-			   reg & WM831X_GPN_TRI ? " tristated" : "",
+			   tristated ? " tristated" : "",
 			   reg);
 	}
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/wm8350-gpiolib.c linux-libre-2.6.34-gnu1/drivers/gpio/wm8350-gpiolib.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/wm8350-gpiolib.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/wm8350-gpiolib.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,182 @@
+/*
+ * wm835x-gpiolib.c  --  gpiolib support for Wolfson WM835x PMICs
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/mfd/core.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+
+#include <linux/mfd/wm8350/core.h>
+#include <linux/mfd/wm8350/gpio.h>
+
+struct wm8350_gpio_data {
+	struct wm8350 *wm8350;
+	struct gpio_chip gpio_chip;
+};
+
+static inline struct wm8350_gpio_data *to_wm8350_gpio(struct gpio_chip *chip)
+{
+	return container_of(chip, struct wm8350_gpio_data, gpio_chip);
+}
+
+static int wm8350_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
+{
+	struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
+	struct wm8350 *wm8350 = wm8350_gpio->wm8350;
+
+	return wm8350_set_bits(wm8350, WM8350_GPIO_CONFIGURATION_I_O,
+			       1 << offset);
+}
+
+static int wm8350_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
+	struct wm8350 *wm8350 = wm8350_gpio->wm8350;
+	int ret;
+
+	ret = wm8350_reg_read(wm8350, WM8350_GPIO_LEVEL);
+	if (ret < 0)
+		return ret;
+
+	if (ret & (1 << offset))
+		return 1;
+	else
+		return 0;
+}
+
+static void wm8350_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
+	struct wm8350 *wm8350 = wm8350_gpio->wm8350;
+
+	if (value)
+		wm8350_set_bits(wm8350, WM8350_GPIO_LEVEL, 1 << offset);
+	else
+		wm8350_clear_bits(wm8350, WM8350_GPIO_LEVEL, 1 << offset);
+}
+
+static int wm8350_gpio_direction_out(struct gpio_chip *chip,
+				     unsigned offset, int value)
+{
+	struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
+	struct wm8350 *wm8350 = wm8350_gpio->wm8350;
+	int ret;
+
+	ret = wm8350_clear_bits(wm8350, WM8350_GPIO_CONFIGURATION_I_O,
+				1 << offset);
+	if (ret < 0)
+		return ret;
+
+	/* Don't have an atomic direction/value setup */
+	wm8350_gpio_set(chip, offset, value);
+
+	return 0;
+}
+
+static int wm8350_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
+	struct wm8350 *wm8350 = wm8350_gpio->wm8350;
+
+	if (!wm8350->irq_base)
+		return -EINVAL;
+
+	return wm8350->irq_base + WM8350_IRQ_GPIO(offset);
+}
+
+static struct gpio_chip template_chip = {
+	.label			= "wm8350",
+	.owner			= THIS_MODULE,
+	.direction_input	= wm8350_gpio_direction_in,
+	.get			= wm8350_gpio_get,
+	.direction_output	= wm8350_gpio_direction_out,
+	.set			= wm8350_gpio_set,
+	.to_irq			= wm8350_gpio_to_irq,
+	.can_sleep		= 1,
+};
+
+static int __devinit wm8350_gpio_probe(struct platform_device *pdev)
+{
+	struct wm8350 *wm8350 = dev_get_drvdata(pdev->dev.parent);
+	struct wm8350_platform_data *pdata = wm8350->dev->platform_data;
+	struct wm8350_gpio_data *wm8350_gpio;
+	int ret;
+
+	wm8350_gpio = kzalloc(sizeof(*wm8350_gpio), GFP_KERNEL);
+	if (wm8350_gpio == NULL)
+		return -ENOMEM;
+
+	wm8350_gpio->wm8350 = wm8350;
+	wm8350_gpio->gpio_chip = template_chip;
+	wm8350_gpio->gpio_chip.ngpio = 13;
+	wm8350_gpio->gpio_chip.dev = &pdev->dev;
+	if (pdata && pdata->gpio_base)
+		wm8350_gpio->gpio_chip.base = pdata->gpio_base;
+	else
+		wm8350_gpio->gpio_chip.base = -1;
+
+	ret = gpiochip_add(&wm8350_gpio->gpio_chip);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Could not register gpiochip, %d\n",
+			ret);
+		goto err;
+	}
+
+	platform_set_drvdata(pdev, wm8350_gpio);
+
+	return ret;
+
+err:
+	kfree(wm8350_gpio);
+	return ret;
+}
+
+static int __devexit wm8350_gpio_remove(struct platform_device *pdev)
+{
+	struct wm8350_gpio_data *wm8350_gpio = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = gpiochip_remove(&wm8350_gpio->gpio_chip);
+	if (ret == 0)
+		kfree(wm8350_gpio);
+
+	return ret;
+}
+
+static struct platform_driver wm8350_gpio_driver = {
+	.driver.name	= "wm8350-gpio",
+	.driver.owner	= THIS_MODULE,
+	.probe		= wm8350_gpio_probe,
+	.remove		= __devexit_p(wm8350_gpio_remove),
+};
+
+static int __init wm8350_gpio_init(void)
+{
+	return platform_driver_register(&wm8350_gpio_driver);
+}
+subsys_initcall(wm8350_gpio_init);
+
+static void __exit wm8350_gpio_exit(void)
+{
+	platform_driver_unregister(&wm8350_gpio_driver);
+}
+module_exit(wm8350_gpio_exit);
+
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("GPIO interface for WM8350 PMICs");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm8350-gpio");
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/wm8994-gpio.c linux-libre-2.6.34-gnu1/drivers/gpio/wm8994-gpio.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/wm8994-gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/wm8994-gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,205 @@
+/*
+ * wm8994-gpio.c  --  gpiolib support for Wolfson WM8994
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/mfd/core.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+
+#include <linux/mfd/wm8994/core.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/mfd/wm8994/gpio.h>
+#include <linux/mfd/wm8994/registers.h>
+
+struct wm8994_gpio {
+	struct wm8994 *wm8994;
+	struct gpio_chip gpio_chip;
+};
+
+static inline struct wm8994_gpio *to_wm8994_gpio(struct gpio_chip *chip)
+{
+	return container_of(chip, struct wm8994_gpio, gpio_chip);
+}
+
+static int wm8994_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
+{
+	struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
+	struct wm8994 *wm8994 = wm8994_gpio->wm8994;
+
+	return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset,
+			       WM8994_GPN_DIR, WM8994_GPN_DIR);
+}
+
+static int wm8994_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
+	struct wm8994 *wm8994 = wm8994_gpio->wm8994;
+	int ret;
+
+	ret = wm8994_reg_read(wm8994, WM8994_GPIO_1 + offset);
+	if (ret < 0)
+		return ret;
+
+	if (ret & WM8994_GPN_LVL)
+		return 1;
+	else
+		return 0;
+}
+
+static int wm8994_gpio_direction_out(struct gpio_chip *chip,
+				     unsigned offset, int value)
+{
+	struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
+	struct wm8994 *wm8994 = wm8994_gpio->wm8994;
+
+	return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset,
+			       WM8994_GPN_DIR, 0);
+}
+
+static void wm8994_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
+	struct wm8994 *wm8994 = wm8994_gpio->wm8994;
+
+	if (value)
+		value = WM8994_GPN_LVL;
+
+	wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, WM8994_GPN_LVL, value);
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void wm8994_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+	struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
+	struct wm8994 *wm8994 = wm8994_gpio->wm8994;
+	int i;
+
+	for (i = 0; i < chip->ngpio; i++) {
+		int gpio = i + chip->base;
+		int reg;
+		const char *label;
+
+		/* We report the GPIO even if it's not requested since
+		 * we're also reporting things like alternate
+		 * functions which apply even when the GPIO is not in
+		 * use as a GPIO.
+		 */
+		label = gpiochip_is_requested(chip, i);
+		if (!label)
+			label = "Unrequested";
+
+		seq_printf(s, " gpio-%-3d (%-20.20s) ", gpio, label);
+
+		reg = wm8994_reg_read(wm8994, WM8994_GPIO_1 + i);
+		if (reg < 0) {
+			dev_err(wm8994->dev,
+				"GPIO control %d read failed: %d\n",
+				gpio, reg);
+			seq_printf(s, "\n");
+			continue;
+		}
+
+		/* No decode yet; note that GPIO2 is special */
+		seq_printf(s, "(%x)\n", reg);
+	}
+}
+#else
+#define wm8994_gpio_dbg_show NULL
+#endif
+
+static struct gpio_chip template_chip = {
+	.label			= "wm8994",
+	.owner			= THIS_MODULE,
+	.direction_input	= wm8994_gpio_direction_in,
+	.get			= wm8994_gpio_get,
+	.direction_output	= wm8994_gpio_direction_out,
+	.set			= wm8994_gpio_set,
+	.dbg_show		= wm8994_gpio_dbg_show,
+	.can_sleep		= 1,
+};
+
+static int __devinit wm8994_gpio_probe(struct platform_device *pdev)
+{
+	struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent);
+	struct wm8994_pdata *pdata = wm8994->dev->platform_data;
+	struct wm8994_gpio *wm8994_gpio;
+	int ret;
+
+	wm8994_gpio = kzalloc(sizeof(*wm8994_gpio), GFP_KERNEL);
+	if (wm8994_gpio == NULL)
+		return -ENOMEM;
+
+	wm8994_gpio->wm8994 = wm8994;
+	wm8994_gpio->gpio_chip = template_chip;
+	wm8994_gpio->gpio_chip.ngpio = WM8994_GPIO_MAX;
+	wm8994_gpio->gpio_chip.dev = &pdev->dev;
+	if (pdata && pdata->gpio_base)
+		wm8994_gpio->gpio_chip.base = pdata->gpio_base;
+	else
+		wm8994_gpio->gpio_chip.base = -1;
+
+	ret = gpiochip_add(&wm8994_gpio->gpio_chip);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Could not register gpiochip, %d\n",
+			ret);
+		goto err;
+	}
+
+	platform_set_drvdata(pdev, wm8994_gpio);
+
+	return ret;
+
+err:
+	kfree(wm8994_gpio);
+	return ret;
+}
+
+static int __devexit wm8994_gpio_remove(struct platform_device *pdev)
+{
+	struct wm8994_gpio *wm8994_gpio = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = gpiochip_remove(&wm8994_gpio->gpio_chip);
+	if (ret == 0)
+		kfree(wm8994_gpio);
+
+	return ret;
+}
+
+static struct platform_driver wm8994_gpio_driver = {
+	.driver.name	= "wm8994-gpio",
+	.driver.owner	= THIS_MODULE,
+	.probe		= wm8994_gpio_probe,
+	.remove		= __devexit_p(wm8994_gpio_remove),
+};
+
+static int __init wm8994_gpio_init(void)
+{
+	return platform_driver_register(&wm8994_gpio_driver);
+}
+subsys_initcall(wm8994_gpio_init);
+
+static void __exit wm8994_gpio_exit(void)
+{
+	platform_driver_unregister(&wm8994_gpio_driver);
+}
+module_exit(wm8994_gpio_exit);
+
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("GPIO interface for WM8994");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm8994-gpio");
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpio/xilinx_gpio.c linux-libre-2.6.34-gnu1/drivers/gpio/xilinx_gpio.c
--- linux-libre-2.6.33-gnu1/drivers/gpio/xilinx_gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpio/xilinx_gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/of_gpio.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 /* Register Offset Definitions */
 #define XGPIO_DATA_OFFSET   (0x0)	/* Data register  */
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_agpsupport.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_agpsupport.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_agpsupport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_agpsupport.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 
 #include "drmP.h"
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #if __OS_HAS_AGP
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_buffer.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_buffer.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_buffer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_buffer.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,184 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Pauli Nieminen.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ **************************************************************************/
+/*
+ * Multipart buffer for coping data which is larger than the page size.
+ *
+ * Authors:
+ * Pauli Nieminen <suokkos-at-gmail-dot-com>
+ */
+
+#include "drm_buffer.h"
+
+/**
+ * Allocate the drm buffer object.
+ *
+ *   buf: Pointer to a pointer where the object is stored.
+ *   size: The number of bytes to allocate.
+ */
+int drm_buffer_alloc(struct drm_buffer **buf, int size)
+{
+	int nr_pages = size / PAGE_SIZE + 1;
+	int idx;
+
+	/* Allocating pointer table to end of structure makes drm_buffer
+	 * variable sized */
+	*buf = kzalloc(sizeof(struct drm_buffer) + nr_pages*sizeof(char *),
+			GFP_KERNEL);
+
+	if (*buf == NULL) {
+		DRM_ERROR("Failed to allocate drm buffer object to hold"
+				" %d bytes in %d pages.\n",
+				size, nr_pages);
+		return -ENOMEM;
+	}
+
+	(*buf)->size = size;
+
+	for (idx = 0; idx < nr_pages; ++idx) {
+
+		(*buf)->data[idx] =
+			kmalloc(min(PAGE_SIZE, size - idx * PAGE_SIZE),
+				GFP_KERNEL);
+
+
+		if ((*buf)->data[idx] == NULL) {
+			DRM_ERROR("Failed to allocate %dth page for drm"
+					" buffer with %d bytes and %d pages.\n",
+					idx + 1, size, nr_pages);
+			goto error_out;
+		}
+
+	}
+
+	return 0;
+
+error_out:
+
+	/* Only last element can be null pointer so check for it first. */
+	if ((*buf)->data[idx])
+		kfree((*buf)->data[idx]);
+
+	for (--idx; idx >= 0; --idx)
+		kfree((*buf)->data[idx]);
+
+	kfree(*buf);
+	return -ENOMEM;
+}
+EXPORT_SYMBOL(drm_buffer_alloc);
+
+/**
+ * Copy the user data to the begin of the buffer and reset the processing
+ * iterator.
+ *
+ *   user_data: A pointer the data that is copied to the buffer.
+ *   size: The Number of bytes to copy.
+ */
+extern int drm_buffer_copy_from_user(struct drm_buffer *buf,
+		void __user *user_data, int size)
+{
+	int nr_pages = size / PAGE_SIZE + 1;
+	int idx;
+
+	if (size > buf->size) {
+		DRM_ERROR("Requesting to copy %d bytes to a drm buffer with"
+				" %d bytes space\n",
+				size, buf->size);
+		return -EFAULT;
+	}
+
+	for (idx = 0; idx < nr_pages; ++idx) {
+
+		if (DRM_COPY_FROM_USER(buf->data[idx],
+			user_data + idx * PAGE_SIZE,
+			min(PAGE_SIZE, size - idx * PAGE_SIZE))) {
+			DRM_ERROR("Failed to copy user data (%p) to drm buffer"
+					" (%p) %dth page.\n",
+					user_data, buf, idx);
+			return -EFAULT;
+
+		}
+	}
+	buf->iterator = 0;
+	return 0;
+}
+EXPORT_SYMBOL(drm_buffer_copy_from_user);
+
+/**
+ * Free the drm buffer object
+ */
+void drm_buffer_free(struct drm_buffer *buf)
+{
+
+	if (buf != NULL) {
+
+		int nr_pages = buf->size / PAGE_SIZE + 1;
+		int idx;
+		for (idx = 0; idx < nr_pages; ++idx)
+			kfree(buf->data[idx]);
+
+		kfree(buf);
+	}
+}
+EXPORT_SYMBOL(drm_buffer_free);
+
+/**
+ * Read an object from buffer that may be split to multiple parts. If object
+ * is not split function just returns the pointer to object in buffer. But in
+ * case of split object data is copied to given stack object that is suplied
+ * by caller.
+ *
+ * The processing location of the buffer is also advanced to the next byte
+ * after the object.
+ *
+ *   objsize: The size of the objet in bytes.
+ *   stack_obj: A pointer to a memory location where object can be copied.
+ */
+void *drm_buffer_read_object(struct drm_buffer *buf,
+		int objsize, void *stack_obj)
+{
+	int idx = drm_buffer_index(buf);
+	int page = drm_buffer_page(buf);
+	void *obj = 0;
+
+	if (idx + objsize <= PAGE_SIZE) {
+		obj = &buf->data[page][idx];
+	} else {
+		/* The object is split which forces copy to temporary object.*/
+		int beginsz = PAGE_SIZE - idx;
+		memcpy(stack_obj, &buf->data[page][idx], beginsz);
+
+		memcpy(stack_obj + beginsz, &buf->data[page + 1][0],
+				objsize - beginsz);
+
+		obj = stack_obj;
+	}
+
+	drm_buffer_advance(buf, objsize);
+	return obj;
+}
+EXPORT_SYMBOL(drm_buffer_read_object);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_bufs.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_bufs.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_bufs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_bufs.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
  */
 
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/log2.h>
 #include <asm/shmparam.h>
 #include "drmP.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_crtc.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_crtc.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_crtc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_crtc.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
  *      Jesse Barnes <jesse.barnes@intel.com>
  */
 #include <linux/list.h>
+#include <linux/slab.h>
 #include "drm.h"
 #include "drmP.h"
 #include "drm_crtc.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_crtc_helper.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_crtc_helper.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_crtc_helper.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_crtc_helper.c	2010-05-16 17:17:36.000000000 -0400
@@ -104,6 +104,7 @@ int drm_helper_probe_single_connector_mo
 	if (connector->status == connector_status_disconnected) {
 		DRM_DEBUG_KMS("%s is disconnected\n",
 			  drm_get_connector_name(connector));
+		drm_mode_connector_update_edid_property(connector, NULL);
 		goto prune;
 	}
 
@@ -836,11 +837,7 @@ int drm_crtc_helper_set_config(struct dr
 			mode_changed = true;
 		} else if (set->fb == NULL) {
 			mode_changed = true;
-		} else if ((set->fb->bits_per_pixel !=
-			 set->crtc->fb->bits_per_pixel) ||
-			 set->fb->depth != set->crtc->fb->depth)
-			fb_changed = true;
-		else
+		} else
 			fb_changed = true;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_debugfs.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_debugfs.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_debugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_debugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "drmP.h"
 
 #if defined(CONFIG_DEBUG_FS)
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_dp_i2c_helper.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_dp_i2c_helper.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_dp_i2c_helper.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_dp_i2c_helper.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_drv.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_drv.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_drv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,7 @@
  */
 
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm_core.h"
 
@@ -125,28 +126,28 @@ static struct drm_ioctl_desc drm_ioctls[
 
 	DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 
-	DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, 0),
-	DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
 
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW)
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED)
 };
 
 #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_edid.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_edid.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_edid.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_edid.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
 #include "drmP.h"
@@ -60,8 +61,7 @@
 #define EDID_QUIRK_FIRST_DETAILED_PREFERRED	(1 << 5)
 /* use +hsync +vsync for detailed mode */
 #define EDID_QUIRK_DETAILED_SYNC_PP		(1 << 6)
-/* define the number of Extension EDID block */
-#define MAX_EDID_EXT_NUM 4
+
 
 #define LEVEL_DMT	0
 #define LEVEL_GTF	1
@@ -85,6 +85,8 @@ static struct edid_quirk {
 
 	/* Envision Peripherals, Inc. EN-7100e */
 	{ "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH },
+	/* Envision EN2028 */
+	{ "EPI", 8232, EDID_QUIRK_PREFER_LARGE_60 },
 
 	/* Funai Electronics PM36B */
 	{ "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 |
@@ -114,14 +116,14 @@ static const u8 edid_header[] = {
 };
 
 /**
- * edid_is_valid - sanity check EDID data
+ * drm_edid_is_valid - sanity check EDID data
  * @edid: EDID data
  *
  * Sanity check the EDID block by looking at the header, the version number
  * and the checksum.  Return 0 if the EDID doesn't check out, or 1 if it's
  * valid.
  */
-static bool edid_is_valid(struct edid *edid)
+bool drm_edid_is_valid(struct edid *edid)
 {
 	int i, score = 0;
 	u8 csum = 0;
@@ -163,6 +165,7 @@ bad:
 	}
 	return 0;
 }
+EXPORT_SYMBOL(drm_edid_is_valid);
 
 /**
  * edid_vendor - match a string against EDID's obfuscated vendor field
@@ -707,15 +710,6 @@ static struct drm_display_mode *drm_mode
 	mode->vsync_end = mode->vsync_start + vsync_pulse_width;
 	mode->vtotal = mode->vdisplay + vblank;
 
-	/* perform the basic check for the detailed timing */
-	if (mode->hsync_end > mode->htotal ||
-		mode->vsync_end > mode->vtotal) {
-		drm_mode_destroy(dev, mode);
-		DRM_DEBUG_KMS("Incorrect detailed timing. "
-				"Sync is beyond the blank.\n");
-		return NULL;
-	}
-
 	/* Some EDIDs have bogus h/vtotal values */
 	if (mode->hsync_end > mode->htotal)
 		mode->htotal = mode->hsync_end + 1;
@@ -1112,8 +1106,8 @@ static int add_detailed_info_eedid(struc
 	}
 
 	/* Chose real EDID extension number */
-	edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ?
-		       MAX_EDID_EXT_NUM : edid->extensions;
+	edid_ext_num = edid->extensions > DRM_MAX_EDID_EXT_NUM ?
+		DRM_MAX_EDID_EXT_NUM : edid->extensions;
 
 	/* Find CEA extension */
 	for (i = 0; i < edid_ext_num; i++) {
@@ -1195,7 +1189,7 @@ static int drm_ddc_read_edid(struct drm_
 	for (i = 0; i < 4; i++) {
 		if (drm_do_probe_ddc_edid(adapter, buf, len))
 			return -1;
-		if (edid_is_valid((struct edid *)buf))
+		if (drm_edid_is_valid((struct edid *)buf))
 			return 0;
 	}
 
@@ -1220,7 +1214,7 @@ struct edid *drm_get_edid(struct drm_con
 	int ret;
 	struct edid *edid;
 
-	edid = kmalloc(EDID_LENGTH * (MAX_EDID_EXT_NUM + 1),
+	edid = kmalloc(EDID_LENGTH * (DRM_MAX_EDID_EXT_NUM + 1),
 		       GFP_KERNEL);
 	if (edid == NULL) {
 		dev_warn(&connector->dev->pdev->dev,
@@ -1238,14 +1232,14 @@ struct edid *drm_get_edid(struct drm_con
 	if (edid->extensions != 0) {
 		int edid_ext_num = edid->extensions;
 
-		if (edid_ext_num > MAX_EDID_EXT_NUM) {
+		if (edid_ext_num > DRM_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);
+				 edid_ext_num, DRM_MAX_EDID_EXT_NUM,
+				 DRM_MAX_EDID_EXT_NUM);
 			/* Reset EDID extension number to be read */
-			edid_ext_num = MAX_EDID_EXT_NUM;
+			edid_ext_num = DRM_MAX_EDID_EXT_NUM;
 		}
 		/* Read EDID including extensions too */
 		ret = drm_ddc_read_edid(connector, adapter, (char *)edid,
@@ -1288,8 +1282,8 @@ bool drm_detect_hdmi_monitor(struct edid
 		goto end;
 
 	/* Chose real EDID extension number */
-	edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ?
-		       MAX_EDID_EXT_NUM : edid->extensions;
+	edid_ext_num = edid->extensions > DRM_MAX_EDID_EXT_NUM ?
+		       DRM_MAX_EDID_EXT_NUM : edid->extensions;
 
 	/* Find CEA extension */
 	for (i = 0; i < edid_ext_num; i++) {
@@ -1346,7 +1340,7 @@ int drm_add_edid_modes(struct drm_connec
 	if (edid == NULL) {
 		return 0;
 	}
-	if (!edid_is_valid(edid)) {
+	if (!drm_edid_is_valid(edid)) {
 		dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
 			 drm_get_connector_name(connector));
 		return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_fb_helper.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_fb_helper.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_fb_helper.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_fb_helper.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,9 @@
  *      Dave Airlie <airlied@linux.ie>
  *      Jesse Barnes <jesse.barnes@intel.com>
  */
+#include <linux/kernel.h>
 #include <linux/sysrq.h>
+#include <linux/slab.h>
 #include <linux/fb.h>
 #include "drmP.h"
 #include "drm_crtc.h"
@@ -50,21 +52,6 @@ int drm_fb_helper_add_connector(struct d
 }
 EXPORT_SYMBOL(drm_fb_helper_add_connector);
 
-static int my_atoi(const char *name)
-{
-	int val = 0;
-
-	for (;; name++) {
-		switch (*name) {
-		case '0' ... '9':
-			val = 10*val+(*name-'0');
-			break;
-		default:
-			return val;
-		}
-	}
-}
-
 /**
  * drm_fb_helper_connector_parse_command_line - parse command line for connector
  * @connector - connector to parse line for
@@ -111,7 +98,7 @@ static bool drm_fb_helper_connector_pars
 			namelen = i;
 			if (!refresh_specified && !bpp_specified &&
 			    !yres_specified) {
-				refresh = my_atoi(&name[i+1]);
+				refresh = simple_strtol(&name[i+1], NULL, 10);
 				refresh_specified = 1;
 				if (cvt || rb)
 					cvt = 0;
@@ -121,7 +108,7 @@ static bool drm_fb_helper_connector_pars
 		case '-':
 			namelen = i;
 			if (!bpp_specified && !yres_specified) {
-				bpp = my_atoi(&name[i+1]);
+				bpp = simple_strtol(&name[i+1], NULL, 10);
 				bpp_specified = 1;
 				if (cvt || rb)
 					cvt = 0;
@@ -130,7 +117,7 @@ static bool drm_fb_helper_connector_pars
 			break;
 		case 'x':
 			if (!yres_specified) {
-				yres = my_atoi(&name[i+1]);
+				yres = simple_strtol(&name[i+1], NULL, 10);
 				yres_specified = 1;
 			} else
 				goto done;
@@ -170,7 +157,7 @@ static bool drm_fb_helper_connector_pars
 		}
 	}
 	if (i < 0 && yres_specified) {
-		xres = my_atoi(name);
+		xres = simple_strtol(name, NULL, 10);
 		res_specified = 1;
 	}
 done:
@@ -297,6 +284,8 @@ static struct sysrq_key_op sysrq_drm_fb_
 	.help_msg = "force-fb(V)",
 	.action_msg = "Restore framebuffer console",
 };
+#else
+static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };
 #endif
 
 static void drm_fb_helper_on(struct fb_info *info)
@@ -694,7 +683,7 @@ int drm_fb_helper_set_par(struct fb_info
 	int i;
 
 	if (var->pixclock != 0) {
-		DRM_ERROR("PIXEL CLCOK SET\n");
+		DRM_ERROR("PIXEL CLOCK SET\n");
 		return -EINVAL;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_fops.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_fops.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_fops.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_fops.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 
 #include "drmP.h"
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 
 static int drm_open_helper(struct inode *inode, struct file *filp,
@@ -140,14 +141,16 @@ int drm_open(struct inode *inode, struct
 		spin_unlock(&dev->count_lock);
 	}
 out:
-	mutex_lock(&dev->struct_mutex);
-	if (minor->type == DRM_MINOR_LEGACY) {
-		BUG_ON((dev->dev_mapping != NULL) &&
-			(dev->dev_mapping != inode->i_mapping));
-		if (dev->dev_mapping == NULL)
-			dev->dev_mapping = inode->i_mapping;
+	if (!retcode) {
+		mutex_lock(&dev->struct_mutex);
+		if (minor->type == DRM_MINOR_LEGACY) {
+			if (dev->dev_mapping == NULL)
+				dev->dev_mapping = inode->i_mapping;
+			else if (dev->dev_mapping != inode->i_mapping)
+				retcode = -ENODEV;
+		}
+		mutex_unlock(&dev->struct_mutex);
 	}
-	mutex_unlock(&dev->struct_mutex);
 
 	return retcode;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_gem.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_gem.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_gem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_gem.c	2010-05-16 17:17:36.000000000 -0400
@@ -192,9 +192,7 @@ drm_gem_handle_delete(struct drm_file *f
 	idr_remove(&filp->object_idr, handle);
 	spin_unlock(&filp->table_lock);
 
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_handle_unreference(obj);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_handle_unreference_unlocked(obj);
 
 	return 0;
 }
@@ -325,9 +323,7 @@ again:
 	}
 
 err:
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(obj);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(obj);
 	return ret;
 }
 
@@ -358,9 +354,7 @@ drm_gem_open_ioctl(struct drm_device *de
 		return -ENOENT;
 
 	ret = drm_gem_handle_create(file_priv, obj, &handle);
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(obj);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(obj);
 	if (ret)
 		return ret;
 
@@ -390,7 +384,7 @@ drm_gem_object_release_handle(int id, vo
 {
 	struct drm_gem_object *obj = ptr;
 
-	drm_gem_object_handle_unreference(obj);
+	drm_gem_object_handle_unreference_unlocked(obj);
 
 	return 0;
 }
@@ -403,16 +397,25 @@ drm_gem_object_release_handle(int id, vo
 void
 drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
 {
-	mutex_lock(&dev->struct_mutex);
 	idr_for_each(&file_private->object_idr,
 		     &drm_gem_object_release_handle, NULL);
 
 	idr_destroy(&file_private->object_idr);
-	mutex_unlock(&dev->struct_mutex);
+}
+
+static void
+drm_gem_object_free_common(struct drm_gem_object *obj)
+{
+	struct drm_device *dev = obj->dev;
+	fput(obj->filp);
+	atomic_dec(&dev->object_count);
+	atomic_sub(obj->size, &dev->object_memory);
+	kfree(obj);
 }
 
 /**
  * Called after the last reference to the object has been lost.
+ * Must be called holding struct_ mutex
  *
  * Frees the object
  */
@@ -427,14 +430,40 @@ drm_gem_object_free(struct kref *kref)
 	if (dev->driver->gem_free_object != NULL)
 		dev->driver->gem_free_object(obj);
 
-	fput(obj->filp);
-	atomic_dec(&dev->object_count);
-	atomic_sub(obj->size, &dev->object_memory);
-	kfree(obj);
+	drm_gem_object_free_common(obj);
 }
 EXPORT_SYMBOL(drm_gem_object_free);
 
 /**
+ * Called after the last reference to the object has been lost.
+ * Must be called without holding struct_mutex
+ *
+ * Frees the object
+ */
+void
+drm_gem_object_free_unlocked(struct kref *kref)
+{
+	struct drm_gem_object *obj = (struct drm_gem_object *) kref;
+	struct drm_device *dev = obj->dev;
+
+	if (dev->driver->gem_free_object_unlocked != NULL)
+		dev->driver->gem_free_object_unlocked(obj);
+	else if (dev->driver->gem_free_object != NULL) {
+		mutex_lock(&dev->struct_mutex);
+		dev->driver->gem_free_object(obj);
+		mutex_unlock(&dev->struct_mutex);
+	}
+
+	drm_gem_object_free_common(obj);
+}
+EXPORT_SYMBOL(drm_gem_object_free_unlocked);
+
+static void drm_gem_object_ref_bug(struct kref *list_kref)
+{
+	BUG();
+}
+
+/**
  * Called after the last handle to the object has been closed
  *
  * Removes any name for the object. Note that this must be
@@ -458,8 +487,10 @@ drm_gem_object_handle_free(struct kref *
 		/*
 		 * The object name held a reference to this object, drop
 		 * that now.
+		*
+		* This cannot be the last reference, since the handle holds one too.
 		 */
-		drm_gem_object_unreference(obj);
+		kref_put(&obj->refcount, drm_gem_object_ref_bug);
 	} else
 		spin_unlock(&dev->object_name_lock);
 
@@ -477,11 +508,8 @@ EXPORT_SYMBOL(drm_gem_vm_open);
 void drm_gem_vm_close(struct vm_area_struct *vma)
 {
 	struct drm_gem_object *obj = vma->vm_private_data;
-	struct drm_device *dev = obj->dev;
 
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(obj);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(obj);
 }
 EXPORT_SYMBOL(drm_gem_vm_close);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_hashtab.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_hashtab.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_hashtab.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_hashtab.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include "drmP.h"
 #include "drm_hashtab.h"
 #include <linux/hash.h>
+#include <linux/slab.h>
 
 int drm_ht_create(struct drm_open_hash *ht, unsigned int order)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_irq.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_irq.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include "drmP.h"
 
 #include <linux/interrupt.h>	/* For task queue support */
+#include <linux/slab.h>
 
 #include <linux/vgaarb.h>
 /**
@@ -475,6 +476,7 @@ void drm_vblank_off(struct drm_device *d
 	unsigned long irqflags;
 
 	spin_lock_irqsave(&dev->vbl_lock, irqflags);
+	dev->driver->disable_vblank(dev, crtc);
 	DRM_WAKEUP(&dev->vbl_queue[crtc]);
 	dev->vblank_enabled[crtc] = 0;
 	dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_memory.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_memory.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_memory.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_memory.c	2010-05-16 17:17:36.000000000 -0400
@@ -77,7 +77,7 @@ static void *agp_remap(unsigned long off
 		    && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=
 		    (offset + size))
 			break;
-	if (!agpmem)
+	if (&agpmem->head == &dev->agp->memory)
 		return NULL;
 
 	/*
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_pci.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_pci.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include "drmP.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_proc.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_proc.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
  */
 
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "drmP.h"
 
 /***************************************************
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_scatter.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_scatter.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_scatter.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_scatter.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
  */
 
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include "drmP.h"
 
 #define DEBUG_SCATTER 0
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_stub.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_stub.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_stub.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_stub.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm_core.h"
 
@@ -515,8 +516,6 @@ void drm_put_dev(struct drm_device *dev)
 	}
 	driver = dev->driver;
 
-	drm_vblank_cleanup(dev);
-
 	drm_lastclose(dev);
 
 	if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
@@ -536,6 +535,8 @@ void drm_put_dev(struct drm_device *dev)
 		dev->agp = NULL;
 	}
 
+	drm_vblank_cleanup(dev);
+
 	list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
 		drm_rmmap(dev, r_list->map);
 	drm_ht_remove(&dev->map_hash);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_sysfs.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 
 #include <linux/device.h>
 #include <linux/kdev_t.h>
+#include <linux/gfp.h>
 #include <linux/err.h>
 
 #include "drm_sysfs.h"
@@ -70,19 +71,17 @@ static int drm_class_resume(struct devic
 	return 0;
 }
 
-/* Display the version of drm_core. This doesn't work right in current design */
-static ssize_t version_show(struct class *dev, char *buf)
-{
-	return sprintf(buf, "%s %d.%d.%d %s\n", CORE_NAME, CORE_MAJOR,
-		       CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
-}
-
 static char *drm_devnode(struct device *dev, mode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev));
 }
 
-static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
+static CLASS_ATTR_STRING(version, S_IRUGO,
+		CORE_NAME " "
+		__stringify(CORE_MAJOR) "."
+		__stringify(CORE_MINOR) "."
+		__stringify(CORE_PATCHLEVEL) " "
+		CORE_DATE);
 
 /**
  * drm_sysfs_create - create a struct drm_sysfs_class structure
@@ -109,7 +108,7 @@ struct class *drm_sysfs_create(struct mo
 	class->suspend = drm_class_suspend;
 	class->resume = drm_class_resume;
 
-	err = class_create_file(class, &class_attr_version);
+	err = class_create_file(class, &class_attr_version.attr);
 	if (err)
 		goto err_out_class;
 
@@ -132,7 +131,7 @@ void drm_sysfs_destroy(void)
 {
 	if ((drm_class == NULL) || (IS_ERR(drm_class)))
 		return;
-	class_remove_file(drm_class, &class_attr_version);
+	class_remove_file(drm_class, &class_attr_version.attr);
 	class_destroy(drm_class);
 }
 
@@ -355,7 +354,10 @@ static struct bin_attribute edid_attr =
 int drm_sysfs_connector_add(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
-	int ret = 0, i, j;
+	int attr_cnt = 0;
+	int opt_cnt = 0;
+	int i;
+	int ret = 0;
 
 	/* We shouldn't get called more than once for the same connector */
 	BUG_ON(device_is_registered(&connector->kdev));
@@ -378,8 +380,8 @@ int drm_sysfs_connector_add(struct drm_c
 
 	/* Standard attributes */
 
-	for (i = 0; i < ARRAY_SIZE(connector_attrs); i++) {
-		ret = device_create_file(&connector->kdev, &connector_attrs[i]);
+	for (attr_cnt = 0; attr_cnt < ARRAY_SIZE(connector_attrs); attr_cnt++) {
+		ret = device_create_file(&connector->kdev, &connector_attrs[attr_cnt]);
 		if (ret)
 			goto err_out_files;
 	}
@@ -395,8 +397,8 @@ int drm_sysfs_connector_add(struct drm_c
 		case DRM_MODE_CONNECTOR_SVIDEO:
 		case DRM_MODE_CONNECTOR_Component:
 		case DRM_MODE_CONNECTOR_TV:
-			for (i = 0; i < ARRAY_SIZE(connector_attrs_opt1); i++) {
-				ret = device_create_file(&connector->kdev, &connector_attrs_opt1[i]);
+			for (opt_cnt = 0; opt_cnt < ARRAY_SIZE(connector_attrs_opt1); opt_cnt++) {
+				ret = device_create_file(&connector->kdev, &connector_attrs_opt1[opt_cnt]);
 				if (ret)
 					goto err_out_files;
 			}
@@ -415,10 +417,10 @@ int drm_sysfs_connector_add(struct drm_c
 	return 0;
 
 err_out_files:
-	if (i > 0)
-		for (j = 0; j < i; j++)
-			device_remove_file(&connector->kdev,
-					   &connector_attrs[i]);
+	for (i = 0; i < opt_cnt; i++)
+		device_remove_file(&connector->kdev, &connector_attrs_opt1[i]);
+	for (i = 0; i < attr_cnt; i++)
+		device_remove_file(&connector->kdev, &connector_attrs[i]);
 	device_unregister(&connector->kdev);
 
 out:
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_vm.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_vm.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_vm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/drm_vm.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include "drmP.h"
 #if defined(__ia64__)
 #include <linux/efi.h>
+#include <linux/slab.h>
 #endif
 
 static void drm_vm_open(struct vm_area_struct *vma);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i810/i810_dma.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i810/i810_dma.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i810/i810_dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i810/i810_dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include "i810_drv.h"
 #include <linux/interrupt.h>	/* For task queue support */
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
 
 #define I810_BUF_FREE		2
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i830/i830_dma.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i830/i830_dma.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i830/i830_dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i830/i830_dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/interrupt.h>	/* For task queue support */
 #include <linux/pagemap.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 #define I830_BUF_FREE		2
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_debugfs.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_debugfs.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_debugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_debugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
@@ -162,7 +163,7 @@ static int i915_interrupt_info(struct se
 	struct drm_device *dev = node->minor->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
 
-	if (!IS_IRONLAKE(dev)) {
+	if (!HAS_PCH_SPLIT(dev)) {
 		seq_printf(m, "Interrupt enable:    %08x\n",
 			   I915_READ(IER));
 		seq_printf(m, "Interrupt identity:  %08x\n",
@@ -225,7 +226,7 @@ static int i915_gem_fence_regs_info(stru
 		} else {
 			struct drm_i915_gem_object *obj_priv;
 
-			obj_priv = obj->driver_private;
+			obj_priv = to_intel_bo(obj);
 			seq_printf(m, "Fenced object[%2d] = %p: %s "
 				   "%08x %08zx %08x %s %08x %08x %d",
 				   i, obj, get_pin_flag(obj_priv),
@@ -350,6 +351,36 @@ static int i915_ringbuffer_info(struct s
 	return 0;
 }
 
+static const char *pin_flag(int pinned)
+{
+	if (pinned > 0)
+		return " P";
+	else if (pinned < 0)
+		return " p";
+	else
+		return "";
+}
+
+static const char *tiling_flag(int tiling)
+{
+	switch (tiling) {
+	default:
+	case I915_TILING_NONE: return "";
+	case I915_TILING_X: return " X";
+	case I915_TILING_Y: return " Y";
+	}
+}
+
+static const char *dirty_flag(int dirty)
+{
+	return dirty ? " dirty" : "";
+}
+
+static const char *purgeable_flag(int purgeable)
+{
+	return purgeable ? " purgeable" : "";
+}
+
 static int i915_error_state(struct seq_file *m, void *unused)
 {
 	struct drm_info_node *node = (struct drm_info_node *) m->private;
@@ -357,6 +388,7 @@ static int i915_error_state(struct seq_f
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	struct drm_i915_error_state *error;
 	unsigned long flags;
+	int i, page, offset, elt;
 
 	spin_lock_irqsave(&dev_priv->error_lock, flags);
 	if (!dev_priv->first_error) {
@@ -368,6 +400,7 @@ static int i915_error_state(struct seq_f
 
 	seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec,
 		   error->time.tv_usec);
+	seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device);
 	seq_printf(m, "EIR: 0x%08x\n", error->eir);
 	seq_printf(m, "  PGTBL_ER: 0x%08x\n", error->pgtbl_er);
 	seq_printf(m, "  INSTPM: 0x%08x\n", error->instpm);
@@ -379,6 +412,59 @@ static int i915_error_state(struct seq_f
 		seq_printf(m, "  INSTPS: 0x%08x\n", error->instps);
 		seq_printf(m, "  INSTDONE1: 0x%08x\n", error->instdone1);
 	}
+	seq_printf(m, "seqno: 0x%08x\n", error->seqno);
+
+	if (error->active_bo_count) {
+		seq_printf(m, "Buffers [%d]:\n", error->active_bo_count);
+
+		for (i = 0; i < error->active_bo_count; i++) {
+			seq_printf(m, "  %08x %8zd %08x %08x %08x%s%s%s%s",
+				   error->active_bo[i].gtt_offset,
+				   error->active_bo[i].size,
+				   error->active_bo[i].read_domains,
+				   error->active_bo[i].write_domain,
+				   error->active_bo[i].seqno,
+				   pin_flag(error->active_bo[i].pinned),
+				   tiling_flag(error->active_bo[i].tiling),
+				   dirty_flag(error->active_bo[i].dirty),
+				   purgeable_flag(error->active_bo[i].purgeable));
+
+			if (error->active_bo[i].name)
+				seq_printf(m, " (name: %d)", error->active_bo[i].name);
+			if (error->active_bo[i].fence_reg != I915_FENCE_REG_NONE)
+				seq_printf(m, " (fence: %d)", error->active_bo[i].fence_reg);
+
+			seq_printf(m, "\n");
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(error->batchbuffer); i++) {
+		if (error->batchbuffer[i]) {
+			struct drm_i915_error_object *obj = error->batchbuffer[i];
+
+			seq_printf(m, "--- gtt_offset = 0x%08x\n", obj->gtt_offset);
+			offset = 0;
+			for (page = 0; page < obj->page_count; page++) {
+				for (elt = 0; elt < PAGE_SIZE/4; elt++) {
+					seq_printf(m, "%08x :  %08x\n", offset, obj->pages[page][elt]);
+					offset += 4;
+				}
+			}
+		}
+	}
+
+	if (error->ringbuffer) {
+		struct drm_i915_error_object *obj = error->ringbuffer;
+
+		seq_printf(m, "--- ringbuffer = 0x%08x\n", obj->gtt_offset);
+		offset = 0;
+		for (page = 0; page < obj->page_count; page++) {
+			for (elt = 0; elt < PAGE_SIZE/4; elt++) {
+				seq_printf(m, "%08x :  %08x\n", offset, obj->pages[page][elt]);
+				offset += 4;
+			}
+		}
+	}
 
 out:
 	spin_unlock_irqrestore(&dev_priv->error_lock, flags);
@@ -386,6 +472,165 @@ out:
 	return 0;
 }
 
+static int i915_rstdby_delays(struct seq_file *m, void *unused)
+{
+	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;
+	u16 crstanddelay = I915_READ16(CRSTANDVID);
+
+	seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f));
+
+	return 0;
+}
+
+static int i915_cur_delayinfo(struct seq_file *m, void *unused)
+{
+	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;
+	u16 rgvswctl = I915_READ16(MEMSWCTL);
+
+	seq_printf(m, "Last command: 0x%01x\n", (rgvswctl >> 13) & 0x3);
+	seq_printf(m, "Command status: %d\n", (rgvswctl >> 12) & 1);
+	seq_printf(m, "P%d DELAY 0x%02x\n", (rgvswctl >> 8) & 0xf,
+		   rgvswctl & 0x3f);
+
+	return 0;
+}
+
+static int i915_delayfreq_table(struct seq_file *m, void *unused)
+{
+	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;
+	u32 delayfreq;
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		delayfreq = I915_READ(PXVFREQ_BASE + i * 4);
+		seq_printf(m, "P%02dVIDFREQ: 0x%08x\n", i, delayfreq);
+	}
+
+	return 0;
+}
+
+static inline int MAP_TO_MV(int map)
+{
+	return 1250 - (map * 25);
+}
+
+static int i915_inttoext_table(struct seq_file *m, void *unused)
+{
+	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;
+	u32 inttoext;
+	int i;
+
+	for (i = 1; i <= 32; i++) {
+		inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4);
+		seq_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext);
+	}
+
+	return 0;
+}
+
+static int i915_drpc_info(struct seq_file *m, void *unused)
+{
+	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;
+	u32 rgvmodectl = I915_READ(MEMMODECTL);
+
+	seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ?
+		   "yes" : "no");
+	seq_printf(m, "Boost freq: %d\n",
+		   (rgvmodectl & MEMMODE_BOOST_FREQ_MASK) >>
+		   MEMMODE_BOOST_FREQ_SHIFT);
+	seq_printf(m, "HW control enabled: %s\n",
+		   rgvmodectl & MEMMODE_HWIDLE_EN ? "yes" : "no");
+	seq_printf(m, "SW control enabled: %s\n",
+		   rgvmodectl & MEMMODE_SWMODE_EN ? "yes" : "no");
+	seq_printf(m, "Gated voltage change: %s\n",
+		   rgvmodectl & MEMMODE_RCLK_GATE ? "yes" : "no");
+	seq_printf(m, "Starting frequency: P%d\n",
+		   (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT);
+	seq_printf(m, "Max frequency: P%d\n",
+		   (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT);
+	seq_printf(m, "Min frequency: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK));
+
+	return 0;
+}
+
+static int i915_fbc_status(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_crtc *crtc;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	bool fbc_enabled = false;
+
+	if (!dev_priv->display.fbc_enabled) {
+		seq_printf(m, "FBC unsupported on this chipset\n");
+		return 0;
+	}
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		if (!crtc->enabled)
+			continue;
+		if (dev_priv->display.fbc_enabled(crtc))
+			fbc_enabled = true;
+	}
+
+	if (fbc_enabled) {
+		seq_printf(m, "FBC enabled\n");
+	} else {
+		seq_printf(m, "FBC disabled: ");
+		switch (dev_priv->no_fbc_reason) {
+		case FBC_STOLEN_TOO_SMALL:
+			seq_printf(m, "not enough stolen memory");
+			break;
+		case FBC_UNSUPPORTED_MODE:
+			seq_printf(m, "mode not supported");
+			break;
+		case FBC_MODE_TOO_LARGE:
+			seq_printf(m, "mode too large");
+			break;
+		case FBC_BAD_PLANE:
+			seq_printf(m, "FBC unsupported on plane");
+			break;
+		case FBC_NOT_TILED:
+			seq_printf(m, "scanout buffer not tiled");
+			break;
+		default:
+			seq_printf(m, "unknown reason");
+		}
+		seq_printf(m, "\n");
+	}
+	return 0;
+}
+
+static int i915_sr_status(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	bool sr_enabled = false;
+
+	if (IS_I965G(dev) || IS_I945G(dev) || IS_I945GM(dev))
+		sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN;
+	else if (IS_I915GM(dev))
+		sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN;
+	else if (IS_PINEVIEW(dev))
+		sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN;
+
+	seq_printf(m, "self-refresh: %s\n", sr_enabled ? "enabled" :
+		   "disabled");
+
+	return 0;
+}
+
 static int
 i915_wedged_open(struct inode *inode,
 		 struct file *filp)
@@ -503,6 +748,13 @@ static struct drm_info_list i915_debugfs
 	{"i915_ringbuffer_info", i915_ringbuffer_info, 0},
 	{"i915_batchbuffers", i915_batchbuffer_info, 0},
 	{"i915_error_state", i915_error_state, 0},
+	{"i915_rstdby_delays", i915_rstdby_delays, 0},
+	{"i915_cur_delayinfo", i915_cur_delayinfo, 0},
+	{"i915_delayfreq_table", i915_delayfreq_table, 0},
+	{"i915_inttoext_table", i915_inttoext_table, 0},
+	{"i915_drpc_info", i915_drpc_info, 0},
+	{"i915_fbc_status", i915_fbc_status, 0},
+	{"i915_sr_status", i915_sr_status, 0},
 };
 #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_dma.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_dma.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,10 @@
 #include "i915_drv.h"
 #include "i915_trace.h"
 #include <linux/vgaarb.h>
+#include <linux/acpi.h>
+#include <linux/pnp.h>
+#include <linux/vga_switcheroo.h>
+#include <linux/slab.h>
 
 /* Really want an OS-independent resettable timer.  Would like to have
  * this loop run for (eg) 3 sec, but have the timer reset every time
@@ -933,6 +937,120 @@ static int i915_get_bridge_dev(struct dr
 	return 0;
 }
 
+#define MCHBAR_I915 0x44
+#define MCHBAR_I965 0x48
+#define MCHBAR_SIZE (4*4096)
+
+#define DEVEN_REG 0x54
+#define   DEVEN_MCHBAR_EN (1 << 28)
+
+/* Allocate space for the MCH regs if needed, return nonzero on error */
+static int
+intel_alloc_mchbar_resource(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
+	u32 temp_lo, temp_hi = 0;
+	u64 mchbar_addr;
+	int ret = 0;
+
+	if (IS_I965G(dev))
+		pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi);
+	pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo);
+	mchbar_addr = ((u64)temp_hi << 32) | temp_lo;
+
+	/* If ACPI doesn't have it, assume we need to allocate it ourselves */
+#ifdef CONFIG_PNP
+	if (mchbar_addr &&
+	    pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) {
+		ret = 0;
+		goto out;
+	}
+#endif
+
+	/* Get some space for it */
+	ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res,
+				     MCHBAR_SIZE, MCHBAR_SIZE,
+				     PCIBIOS_MIN_MEM,
+				     0,   pcibios_align_resource,
+				     dev_priv->bridge_dev);
+	if (ret) {
+		DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret);
+		dev_priv->mch_res.start = 0;
+		goto out;
+	}
+
+	if (IS_I965G(dev))
+		pci_write_config_dword(dev_priv->bridge_dev, reg + 4,
+				       upper_32_bits(dev_priv->mch_res.start));
+
+	pci_write_config_dword(dev_priv->bridge_dev, reg,
+			       lower_32_bits(dev_priv->mch_res.start));
+out:
+	return ret;
+}
+
+/* Setup MCHBAR if possible, return true if we should disable it again */
+static void
+intel_setup_mchbar(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
+	u32 temp;
+	bool enabled;
+
+	dev_priv->mchbar_need_disable = false;
+
+	if (IS_I915G(dev) || IS_I915GM(dev)) {
+		pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
+		enabled = !!(temp & DEVEN_MCHBAR_EN);
+	} else {
+		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
+		enabled = temp & 1;
+	}
+
+	/* If it's already enabled, don't have to do anything */
+	if (enabled)
+		return;
+
+	if (intel_alloc_mchbar_resource(dev))
+		return;
+
+	dev_priv->mchbar_need_disable = true;
+
+	/* Space is allocated or reserved, so enable it. */
+	if (IS_I915G(dev) || IS_I915GM(dev)) {
+		pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG,
+				       temp | DEVEN_MCHBAR_EN);
+	} else {
+		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
+		pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1);
+	}
+}
+
+static void
+intel_teardown_mchbar(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
+	u32 temp;
+
+	if (dev_priv->mchbar_need_disable) {
+		if (IS_I915G(dev) || IS_I915GM(dev)) {
+			pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
+			temp &= ~DEVEN_MCHBAR_EN;
+			pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, temp);
+		} else {
+			pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
+			temp &= ~1;
+			pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp);
+		}
+	}
+
+	if (dev_priv->mch_res.start)
+		release_resource(&dev_priv->mch_res);
+}
+
 /**
  * i915_probe_agp - get AGP bootup configuration
  * @pdev: PCI device
@@ -978,59 +1096,123 @@ static int i915_probe_agp(struct drm_dev
 	 * Some of the preallocated space is taken by the GTT
 	 * and popup.  GTT is 1K per MB of aperture size, and popup is 4K.
 	 */
-	if (IS_G4X(dev) || IS_PINEVIEW(dev) || IS_IRONLAKE(dev))
+	if (IS_G4X(dev) || IS_PINEVIEW(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev))
 		overhead = 4096;
 	else
 		overhead = (*aperture_size / 1024) + 4096;
 
-	switch (tmp & INTEL_GMCH_GMS_MASK) {
-	case INTEL_855_GMCH_GMS_DISABLED:
-		DRM_ERROR("video memory is disabled\n");
-		return -1;
-	case INTEL_855_GMCH_GMS_STOLEN_1M:
-		stolen = 1 * 1024 * 1024;
-		break;
-	case INTEL_855_GMCH_GMS_STOLEN_4M:
-		stolen = 4 * 1024 * 1024;
-		break;
-	case INTEL_855_GMCH_GMS_STOLEN_8M:
-		stolen = 8 * 1024 * 1024;
-		break;
-	case INTEL_855_GMCH_GMS_STOLEN_16M:
-		stolen = 16 * 1024 * 1024;
-		break;
-	case INTEL_855_GMCH_GMS_STOLEN_32M:
-		stolen = 32 * 1024 * 1024;
-		break;
-	case INTEL_915G_GMCH_GMS_STOLEN_48M:
-		stolen = 48 * 1024 * 1024;
-		break;
-	case INTEL_915G_GMCH_GMS_STOLEN_64M:
-		stolen = 64 * 1024 * 1024;
-		break;
-	case INTEL_GMCH_GMS_STOLEN_128M:
-		stolen = 128 * 1024 * 1024;
-		break;
-	case INTEL_GMCH_GMS_STOLEN_256M:
-		stolen = 256 * 1024 * 1024;
-		break;
-	case INTEL_GMCH_GMS_STOLEN_96M:
-		stolen = 96 * 1024 * 1024;
-		break;
-	case INTEL_GMCH_GMS_STOLEN_160M:
-		stolen = 160 * 1024 * 1024;
-		break;
-	case INTEL_GMCH_GMS_STOLEN_224M:
-		stolen = 224 * 1024 * 1024;
-		break;
-	case INTEL_GMCH_GMS_STOLEN_352M:
-		stolen = 352 * 1024 * 1024;
-		break;
-	default:
-		DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n",
-			tmp & INTEL_GMCH_GMS_MASK);
-		return -1;
+	if (IS_GEN6(dev)) {
+		/* SNB has memory control reg at 0x50.w */
+		pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &tmp);
+
+		switch (tmp & SNB_GMCH_GMS_STOLEN_MASK) {
+		case INTEL_855_GMCH_GMS_DISABLED:
+			DRM_ERROR("video memory is disabled\n");
+			return -1;
+		case SNB_GMCH_GMS_STOLEN_32M:
+			stolen = 32 * 1024 * 1024;
+			break;
+		case SNB_GMCH_GMS_STOLEN_64M:
+			stolen = 64 * 1024 * 1024;
+			break;
+		case SNB_GMCH_GMS_STOLEN_96M:
+			stolen = 96 * 1024 * 1024;
+			break;
+		case SNB_GMCH_GMS_STOLEN_128M:
+			stolen = 128 * 1024 * 1024;
+			break;
+		case SNB_GMCH_GMS_STOLEN_160M:
+			stolen = 160 * 1024 * 1024;
+			break;
+		case SNB_GMCH_GMS_STOLEN_192M:
+			stolen = 192 * 1024 * 1024;
+			break;
+		case SNB_GMCH_GMS_STOLEN_224M:
+			stolen = 224 * 1024 * 1024;
+			break;
+		case SNB_GMCH_GMS_STOLEN_256M:
+			stolen = 256 * 1024 * 1024;
+			break;
+		case SNB_GMCH_GMS_STOLEN_288M:
+			stolen = 288 * 1024 * 1024;
+			break;
+		case SNB_GMCH_GMS_STOLEN_320M:
+			stolen = 320 * 1024 * 1024;
+			break;
+		case SNB_GMCH_GMS_STOLEN_352M:
+			stolen = 352 * 1024 * 1024;
+			break;
+		case SNB_GMCH_GMS_STOLEN_384M:
+			stolen = 384 * 1024 * 1024;
+			break;
+		case SNB_GMCH_GMS_STOLEN_416M:
+			stolen = 416 * 1024 * 1024;
+			break;
+		case SNB_GMCH_GMS_STOLEN_448M:
+			stolen = 448 * 1024 * 1024;
+			break;
+		case SNB_GMCH_GMS_STOLEN_480M:
+			stolen = 480 * 1024 * 1024;
+			break;
+		case SNB_GMCH_GMS_STOLEN_512M:
+			stolen = 512 * 1024 * 1024;
+			break;
+		default:
+			DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n",
+				  tmp & SNB_GMCH_GMS_STOLEN_MASK);
+			return -1;
+		}
+	} else {
+		switch (tmp & INTEL_GMCH_GMS_MASK) {
+		case INTEL_855_GMCH_GMS_DISABLED:
+			DRM_ERROR("video memory is disabled\n");
+			return -1;
+		case INTEL_855_GMCH_GMS_STOLEN_1M:
+			stolen = 1 * 1024 * 1024;
+			break;
+		case INTEL_855_GMCH_GMS_STOLEN_4M:
+			stolen = 4 * 1024 * 1024;
+			break;
+		case INTEL_855_GMCH_GMS_STOLEN_8M:
+			stolen = 8 * 1024 * 1024;
+			break;
+		case INTEL_855_GMCH_GMS_STOLEN_16M:
+			stolen = 16 * 1024 * 1024;
+			break;
+		case INTEL_855_GMCH_GMS_STOLEN_32M:
+			stolen = 32 * 1024 * 1024;
+			break;
+		case INTEL_915G_GMCH_GMS_STOLEN_48M:
+			stolen = 48 * 1024 * 1024;
+			break;
+		case INTEL_915G_GMCH_GMS_STOLEN_64M:
+			stolen = 64 * 1024 * 1024;
+			break;
+		case INTEL_GMCH_GMS_STOLEN_128M:
+			stolen = 128 * 1024 * 1024;
+			break;
+		case INTEL_GMCH_GMS_STOLEN_256M:
+			stolen = 256 * 1024 * 1024;
+			break;
+		case INTEL_GMCH_GMS_STOLEN_96M:
+			stolen = 96 * 1024 * 1024;
+			break;
+		case INTEL_GMCH_GMS_STOLEN_160M:
+			stolen = 160 * 1024 * 1024;
+			break;
+		case INTEL_GMCH_GMS_STOLEN_224M:
+			stolen = 224 * 1024 * 1024;
+			break;
+		case INTEL_GMCH_GMS_STOLEN_352M:
+			stolen = 352 * 1024 * 1024;
+			break;
+		default:
+			DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n",
+				  tmp & INTEL_GMCH_GMS_MASK);
+			return -1;
+		}
 	}
+
 	*preallocated_size = stolen - overhead;
 	*start = overhead;
 
@@ -1064,7 +1246,7 @@ static unsigned long i915_gtt_to_phys(st
 	int gtt_offset, gtt_size;
 
 	if (IS_I965G(dev)) {
-		if (IS_G4X(dev) || IS_IRONLAKE(dev)) {
+		if (IS_G4X(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev)) {
 			gtt_offset = 2*1024*1024;
 			gtt_size = 2*1024*1024;
 		} else {
@@ -1133,6 +1315,7 @@ static void i915_setup_compression(struc
 	/* Leave 1M for line length buffer & misc. */
 	compressed_fb = drm_mm_search_free(&dev_priv->vram, size, 4096, 0);
 	if (!compressed_fb) {
+		dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL;
 		i915_warn_stolen(dev);
 		return;
 	}
@@ -1140,6 +1323,7 @@ static void i915_setup_compression(struc
 	compressed_fb = drm_mm_get_block(compressed_fb, size, 4096);
 	if (!compressed_fb) {
 		i915_warn_stolen(dev);
+		dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL;
 		return;
 	}
 
@@ -1173,6 +1357,8 @@ static void i915_setup_compression(struc
 
 	dev_priv->cfb_size = size;
 
+	dev_priv->compressed_fb = compressed_fb;
+
 	if (IS_GM45(dev)) {
 		g4x_disable_fbc(dev);
 		I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
@@ -1180,12 +1366,22 @@ static void i915_setup_compression(struc
 		i8xx_disable_fbc(dev);
 		I915_WRITE(FBC_CFB_BASE, cfb_base);
 		I915_WRITE(FBC_LL_BASE, ll_base);
+		dev_priv->compressed_llb = compressed_llb;
 	}
 
 	DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base,
 		  ll_base, size >> 20);
 }
 
+static void i915_cleanup_compression(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	drm_mm_put_block(dev_priv->compressed_fb);
+	if (!IS_GM45(dev))
+		drm_mm_put_block(dev_priv->compressed_llb);
+}
+
 /* true = enable decode, false = disable decoder */
 static unsigned int i915_vga_set_decode(void *cookie, bool state)
 {
@@ -1199,6 +1395,32 @@ static unsigned int i915_vga_set_decode(
 		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
 }
 
+static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
+	if (state == VGA_SWITCHEROO_ON) {
+		printk(KERN_INFO "i915: switched off\n");
+		/* i915 resume handler doesn't set to D0 */
+		pci_set_power_state(dev->pdev, PCI_D0);
+		i915_resume(dev);
+	} else {
+		printk(KERN_ERR "i915: switched off\n");
+		i915_suspend(dev, pmm);
+	}
+}
+
+static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	bool can_switch;
+
+	spin_lock(&dev->count_lock);
+	can_switch = (dev->open_count == 0);
+	spin_unlock(&dev->count_lock);
+	return can_switch;
+}
+
 static int i915_load_modeset_init(struct drm_device *dev,
 				  unsigned long prealloc_start,
 				  unsigned long prealloc_size,
@@ -1260,6 +1482,12 @@ static int i915_load_modeset_init(struct
 	if (ret)
 		goto destroy_ringbuffer;
 
+	ret = vga_switcheroo_register_client(dev->pdev,
+					     i915_switcheroo_set_state,
+					     i915_switcheroo_can_switch);
+	if (ret)
+		goto destroy_ringbuffer;
+
 	intel_modeset_init(dev);
 
 	ret = drm_irq_install(dev);
@@ -1281,7 +1509,9 @@ static int i915_load_modeset_init(struct
 	return 0;
 
 destroy_ringbuffer:
+	mutex_lock(&dev->struct_mutex);
 	i915_gem_cleanup_ringbuffer(dev);
+	mutex_unlock(&dev->struct_mutex);
 out:
 	return ret;
 }
@@ -1445,11 +1675,14 @@ int i915_driver_load(struct drm_device *
 
 	dev->driver->get_vblank_counter = i915_get_vblank_counter;
 	dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
-	if (IS_G4X(dev) || IS_IRONLAKE(dev)) {
+	if (IS_G4X(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev)) {
 		dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
 		dev->driver->get_vblank_counter = gm45_get_vblank_counter;
 	}
 
+	/* Try to make sure MCHBAR is enabled before poking at it */
+	intel_setup_mchbar(dev);
+
 	i915_gem_load(dev);
 
 	/* Init HWS */
@@ -1523,6 +1756,8 @@ int i915_driver_unload(struct drm_device
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
+	i915_destroy_error_state(dev);
+
 	destroy_workqueue(dev_priv->wq);
 	del_timer_sync(&dev_priv->hangcheck_timer);
 
@@ -1544,6 +1779,7 @@ int i915_driver_unload(struct drm_device
 			dev_priv->child_dev_num = 0;
 		}
 		drm_irq_uninstall(dev);
+		vga_switcheroo_unregister_client(dev->pdev);
 		vga_client_register(dev->pdev, NULL, NULL, NULL);
 	}
 
@@ -1563,12 +1799,16 @@ int i915_driver_unload(struct drm_device
 		mutex_lock(&dev->struct_mutex);
 		i915_gem_cleanup_ringbuffer(dev);
 		mutex_unlock(&dev->struct_mutex);
+		if (I915_HAS_FBC(dev) && i915_powersave)
+			i915_cleanup_compression(dev);
 		drm_mm_takedown(&dev_priv->vram);
 		i915_gem_lastclose(dev);
 
 		intel_cleanup_overlay(dev);
 	}
 
+	intel_teardown_mchbar(dev);
+
 	pci_dev_put(dev_priv->bridge_dev);
 	kfree(dev->dev_private);
 
@@ -1611,6 +1851,7 @@ void i915_driver_lastclose(struct drm_de
 
 	if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) {
 		drm_fb_helper_restore();
+		vga_switcheroo_process_delayed_switch();
 		return;
 	}
 
@@ -1655,29 +1896,29 @@ struct drm_ioctl_desc i915_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE,  i915_vblank_pipe_get, DRM_AUTH ),
 	DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-	DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-	DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
-	DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
-	DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-	DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-	DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0),
-	DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0),
-	DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0),
-	DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0),
-	DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, 0),
-	DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0),
-	DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0),
-	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),
-	DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, 0),
-	DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW),
-	DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW),
+	DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 };
 
 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_drv.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_drv.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_drv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,7 @@ unsigned int i915_lvds_downclock = 0;
 module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400);
 
 static struct drm_driver driver;
+extern int intel_agp_enabled;
 
 #define INTEL_VGA_DEVICE(id, info) {		\
 	.class = PCI_CLASS_DISPLAY_VGA << 8,	\
@@ -68,7 +69,8 @@ const static struct intel_device_info in
 };
 
 const static struct intel_device_info intel_i85x_info = {
-	.is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1,
+	.is_i8xx = 1, .is_i85x = 1, .is_mobile = 1,
+	.cursor_needs_physical = 1,
 };
 
 const static struct intel_device_info intel_i865g_info = {
@@ -79,14 +81,14 @@ const static struct intel_device_info in
 	.is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1,
 };
 const static struct intel_device_info intel_i915gm_info = {
-	.is_i9xx = 1,  .is_mobile = 1, .has_fbc = 1,
+	.is_i9xx = 1,  .is_mobile = 1,
 	.cursor_needs_physical = 1,
 };
 const static struct intel_device_info intel_i945g_info = {
 	.is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1,
 };
 const static struct intel_device_info intel_i945gm_info = {
-	.is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1,
+	.is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1,
 	.has_hotplug = 1, .cursor_needs_physical = 1,
 };
 
@@ -136,11 +138,21 @@ const static struct intel_device_info in
 	.has_hotplug = 1,
 };
 
+const static struct intel_device_info intel_sandybridge_d_info = {
+	.is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1,
+	.has_hotplug = 1, .is_gen6 = 1,
+};
+
+const static struct intel_device_info intel_sandybridge_m_info = {
+	.is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1,
+	.has_hotplug = 1, .is_gen6 = 1,
+};
+
 const static struct pci_device_id pciidlist[] = {
 	INTEL_VGA_DEVICE(0x3577, &intel_i830_info),
 	INTEL_VGA_DEVICE(0x2562, &intel_845g_info),
 	INTEL_VGA_DEVICE(0x3582, &intel_i85x_info),
-	INTEL_VGA_DEVICE(0x35e8, &intel_i85x_info),
+	INTEL_VGA_DEVICE(0x358e, &intel_i85x_info),
 	INTEL_VGA_DEVICE(0x2572, &intel_i865g_info),
 	INTEL_VGA_DEVICE(0x2582, &intel_i915g_info),
 	INTEL_VGA_DEVICE(0x258a, &intel_i915g_info),
@@ -167,6 +179,8 @@ const static struct pci_device_id pciidl
 	INTEL_VGA_DEVICE(0xa011, &intel_pineview_info),
 	INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info),
 	INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info),
+	INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info),
+	INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info),
 	{0, 0, 0}
 };
 
@@ -201,7 +215,7 @@ static int i915_drm_freeze(struct drm_de
 	return 0;
 }
 
-static int i915_suspend(struct drm_device *dev, pm_message_t state)
+int i915_suspend(struct drm_device *dev, pm_message_t state)
 {
 	int error;
 
@@ -255,7 +269,7 @@ static int i915_drm_thaw(struct drm_devi
 	return error;
 }
 
-static int i915_resume(struct drm_device *dev)
+int i915_resume(struct drm_device *dev)
 {
 	if (pci_enable_device(dev->pdev))
 		return -EIO;
@@ -348,7 +362,7 @@ int i965_reset(struct drm_device *dev, u
 	    !dev_priv->mm.suspended) {
 		drm_i915_ring_buffer_t *ring = &dev_priv->ring;
 		struct drm_gem_object *obj = ring->ring_obj;
-		struct drm_i915_gem_object *obj_priv = obj->driver_private;
+		struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 		dev_priv->mm.suspended = 0;
 
 		/* Stop the ring if it's running. */
@@ -546,6 +560,11 @@ static struct drm_driver driver = {
 
 static int __init i915_init(void)
 {
+	if (!intel_agp_enabled) {
+		DRM_ERROR("drm/i915 can't work without intel_agp module!\n");
+		return -ENODEV;
+	}
+
 	driver.num_ioctls = i915_max_ioctl;
 
 	i915_gem_shrinker_init();
@@ -571,6 +590,11 @@ static int __init i915_init(void)
 		driver.driver_features &= ~DRIVER_MODESET;
 #endif
 
+	if (!(driver.driver_features & DRIVER_MODESET)) {
+		driver.suspend = i915_suspend;
+		driver.resume = i915_resume;
+	}
+
 	return drm_init(&driver);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_drv.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_drv.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_drv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_drv.h	2010-05-16 17:17:36.000000000 -0400
@@ -150,7 +150,27 @@ struct drm_i915_error_state {
 	u32 instps;
 	u32 instdone1;
 	u32 seqno;
+	u64 bbaddr;
 	struct timeval time;
+	struct drm_i915_error_object {
+		int page_count;
+		u32 gtt_offset;
+		u32 *pages[0];
+	} *ringbuffer, *batchbuffer[2];
+	struct drm_i915_error_buffer {
+		size_t size;
+		u32 name;
+		u32 seqno;
+		u32 gtt_offset;
+		u32 read_domains;
+		u32 write_domain;
+		u32 fence_reg;
+		s32 pinned:2;
+		u32 tiling:2;
+		u32 dirty:1;
+		u32 purgeable:1;
+	} *active_bo;
+	u32 active_bo_count;
 };
 
 struct drm_i915_display_funcs {
@@ -175,6 +195,7 @@ struct intel_overlay;
 struct intel_device_info {
 	u8 is_mobile : 1;
 	u8 is_i8xx : 1;
+	u8 is_i85x : 1;
 	u8 is_i915g : 1;
 	u8 is_i9xx : 1;
 	u8 is_i945gm : 1;
@@ -185,6 +206,7 @@ struct intel_device_info {
 	u8 is_g4x : 1;
 	u8 is_pineview : 1;
 	u8 is_ironlake : 1;
+	u8 is_gen6 : 1;
 	u8 has_fbc : 1;
 	u8 has_rc6 : 1;
 	u8 has_pipe_cxsr : 1;
@@ -192,6 +214,14 @@ struct intel_device_info {
 	u8 cursor_needs_physical : 1;
 };
 
+enum no_fbc_reason {
+	FBC_STOLEN_TOO_SMALL, /* not enough space to hold compressed buffers */
+	FBC_UNSUPPORTED_MODE, /* interlace or doublescanned mode */
+	FBC_MODE_TOO_LARGE, /* mode too large for compression */
+	FBC_BAD_PLANE, /* fbc not supported on plane */
+	FBC_NOT_TILED, /* buffer not tiled */
+};
+
 typedef struct drm_i915_private {
 	struct drm_device *dev;
 
@@ -206,11 +236,14 @@ typedef struct drm_i915_private {
 
 	drm_dma_handle_t *status_page_dmah;
 	void *hw_status_page;
+	void *seqno_page;
 	dma_addr_t dma_status_page;
 	uint32_t counter;
 	unsigned int status_gfx_addr;
+	unsigned int seqno_gfx_addr;
 	drm_local_map_t hws_map;
 	struct drm_gem_object *hws_obj;
+	struct drm_gem_object *seqno_obj;
 	struct drm_gem_object *pwrctx;
 
 	struct resource mch_res;
@@ -452,6 +485,7 @@ typedef struct drm_i915_private {
 	u32 savePIPEB_DATA_N1;
 	u32 savePIPEB_LINK_M1;
 	u32 savePIPEB_LINK_N1;
+	u32 saveMCHBAR_RENDER_STANDBY;
 
 	struct {
 		struct drm_mm gtt_space;
@@ -581,6 +615,8 @@ typedef struct drm_i915_private {
 	/* Reclocking support */
 	bool render_reclock_avail;
 	bool lvds_downclock_avail;
+	/* indicate whether the LVDS EDID is OK */
+	bool lvds_edid_good;
 	/* indicates the reduced downclock for LVDS*/
 	int lvds_downclock;
 	struct work_struct idle_work;
@@ -590,6 +626,17 @@ typedef struct drm_i915_private {
 	int child_dev_num;
 	struct child_device_config *child_dev;
 	struct drm_connector *int_lvds_connector;
+
+	bool mchbar_need_disable;
+
+	u8 cur_delay;
+	u8 min_delay;
+	u8 max_delay;
+
+	enum no_fbc_reason no_fbc_reason;
+
+	struct drm_mm_node *compressed_fb;
+	struct drm_mm_node *compressed_llb;
 } drm_i915_private_t;
 
 /** driver private structure attached to each drm_gem_object */
@@ -693,6 +740,8 @@ struct drm_i915_gem_object {
 	atomic_t pending_flip;
 };
 
+#define to_intel_bo(x) ((struct drm_i915_gem_object *) (x)->driver_private)
+
 /**
  * Request queue structure.
  *
@@ -736,6 +785,8 @@ extern unsigned int i915_fbpercrtc;
 extern unsigned int i915_powersave;
 extern unsigned int i915_lvds_downclock;
 
+extern int i915_suspend(struct drm_device *dev, pm_message_t state);
+extern int i915_resume(struct drm_device *dev);
 extern void i915_save_display(struct drm_device *dev);
 extern void i915_restore_display(struct drm_device *dev);
 extern int i915_master_create(struct drm_device *dev, struct drm_master *master);
@@ -761,6 +812,7 @@ extern int i965_reset(struct drm_device
 
 /* i915_irq.c */
 void i915_hangcheck_elapsed(unsigned long data);
+void i915_destroy_error_state(struct drm_device *dev);
 extern int i915_irq_emit(struct drm_device *dev, void *data,
 			 struct drm_file *file_priv);
 extern int i915_irq_wait(struct drm_device *dev, void *data,
@@ -897,7 +949,8 @@ void i915_gem_object_do_bit_17_swizzle(s
 void i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj);
 bool i915_tiling_ok(struct drm_device *dev, int stride, int size,
 		    int tiling_mode);
-bool i915_obj_fenceable(struct drm_device *dev, struct drm_gem_object *obj);
+bool i915_gem_object_fence_offset_ok(struct drm_gem_object *obj,
+				     int tiling_mode);
 
 /* i915_gem_debug.c */
 void i915_gem_dump_object(struct drm_gem_object *obj, int len,
@@ -1024,9 +1077,9 @@ extern int i915_wait_ring(struct drm_dev
 
 #define IS_I830(dev)		((dev)->pci_device == 0x3577)
 #define IS_845G(dev)		((dev)->pci_device == 0x2562)
-#define IS_I85X(dev)		((dev)->pci_device == 0x3582)
+#define IS_I85X(dev)		(INTEL_INFO(dev)->is_i85x)
 #define IS_I865G(dev)		((dev)->pci_device == 0x2572)
-#define IS_I8XX(dev)		(INTEL_INFO(dev)->is_i8xx)
+#define IS_GEN2(dev)		(INTEL_INFO(dev)->is_i8xx)
 #define IS_I915G(dev)		(INTEL_INFO(dev)->is_i915g)
 #define IS_I915GM(dev)		((dev)->pci_device == 0x2592)
 #define IS_I945G(dev)		((dev)->pci_device == 0x2772)
@@ -1043,8 +1096,28 @@ extern int i915_wait_ring(struct drm_dev
 #define IS_IRONLAKE_M(dev)	((dev)->pci_device == 0x0046)
 #define IS_IRONLAKE(dev)	(INTEL_INFO(dev)->is_ironlake)
 #define IS_I9XX(dev)		(INTEL_INFO(dev)->is_i9xx)
+#define IS_GEN6(dev)		(INTEL_INFO(dev)->is_gen6)
 #define IS_MOBILE(dev)		(INTEL_INFO(dev)->is_mobile)
 
+#define IS_GEN3(dev)	(IS_I915G(dev) ||			\
+			 IS_I915GM(dev) ||			\
+			 IS_I945G(dev) ||			\
+			 IS_I945GM(dev) ||			\
+			 IS_G33(dev) || \
+			 IS_PINEVIEW(dev))
+#define IS_GEN4(dev)	((dev)->pci_device == 0x2972 ||		\
+			 (dev)->pci_device == 0x2982 ||		\
+			 (dev)->pci_device == 0x2992 ||		\
+			 (dev)->pci_device == 0x29A2 ||		\
+			 (dev)->pci_device == 0x2A02 ||		\
+			 (dev)->pci_device == 0x2A12 ||		\
+			 (dev)->pci_device == 0x2E02 ||		\
+			 (dev)->pci_device == 0x2E12 ||		\
+			 (dev)->pci_device == 0x2E22 ||		\
+			 (dev)->pci_device == 0x2E32 ||		\
+			 (dev)->pci_device == 0x2A42 ||		\
+			 (dev)->pci_device == 0x2E42)
+
 #define I915_NEED_GFX_HWS(dev)	(INTEL_INFO(dev)->need_gfx_hws)
 
 /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
@@ -1067,6 +1140,10 @@ extern int i915_wait_ring(struct drm_dev
 #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc)
 #define I915_HAS_RC6(dev) (INTEL_INFO(dev)->has_rc6)
 
+#define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) ||	\
+			    IS_GEN6(dev))
+#define HAS_PIPE_CONTROL(dev) (IS_IRONLAKE(dev) || IS_GEN6(dev))
+
 #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_gem.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_gem.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_gem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_gem.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include "i915_drv.h"
 #include "i915_trace.h"
 #include "intel_drv.h"
+#include <linux/slab.h>
 #include <linux/swap.h>
 #include <linux/pci.h>
 
@@ -128,9 +129,7 @@ i915_gem_create_ioctl(struct drm_device
 		return -ENOMEM;
 
 	ret = drm_gem_handle_create(file_priv, obj, &handle);
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_handle_unreference(obj);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_handle_unreference_unlocked(obj);
 
 	if (ret)
 		return ret;
@@ -164,7 +163,7 @@ fast_shmem_read(struct page **pages,
 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;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
 	return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 &&
 		obj_priv->tiling_mode != I915_TILING_NONE;
@@ -265,7 +264,7 @@ i915_gem_shmem_pread_fast(struct drm_dev
 			  struct drm_i915_gem_pread *args,
 			  struct drm_file *file_priv)
 {
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	ssize_t remain;
 	loff_t offset, page_base;
 	char __user *user_data;
@@ -286,7 +285,7 @@ i915_gem_shmem_pread_fast(struct drm_dev
 	if (ret != 0)
 		goto fail_put_pages;
 
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 	offset = args->offset;
 
 	while (remain > 0) {
@@ -355,7 +354,7 @@ i915_gem_shmem_pread_slow(struct drm_dev
 			  struct drm_i915_gem_pread *args,
 			  struct drm_file *file_priv)
 {
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	struct mm_struct *mm = current->mm;
 	struct page **user_pages;
 	ssize_t remain;
@@ -404,7 +403,7 @@ i915_gem_shmem_pread_slow(struct drm_dev
 	if (ret != 0)
 		goto fail_put_pages;
 
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 	offset = args->offset;
 
 	while (remain > 0) {
@@ -480,7 +479,7 @@ i915_gem_pread_ioctl(struct drm_device *
 	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
 	if (obj == NULL)
 		return -EBADF;
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 
 	/* Bounds check source.
 	 *
@@ -488,7 +487,7 @@ i915_gem_pread_ioctl(struct drm_device *
 	 */
 	if (args->offset > obj->size || args->size > obj->size ||
 	    args->offset + args->size > obj->size) {
-		drm_gem_object_unreference(obj);
+		drm_gem_object_unreference_unlocked(obj);
 		return -EINVAL;
 	}
 
@@ -501,7 +500,7 @@ i915_gem_pread_ioctl(struct drm_device *
 							file_priv);
 	}
 
-	drm_gem_object_unreference(obj);
+	drm_gem_object_unreference_unlocked(obj);
 
 	return ret;
 }
@@ -582,7 +581,7 @@ i915_gem_gtt_pwrite_fast(struct drm_devi
 			 struct drm_i915_gem_pwrite *args,
 			 struct drm_file *file_priv)
 {
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	ssize_t remain;
 	loff_t offset, page_base;
@@ -606,7 +605,7 @@ i915_gem_gtt_pwrite_fast(struct drm_devi
 	if (ret)
 		goto fail;
 
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 	offset = obj_priv->gtt_offset + args->offset;
 
 	while (remain > 0) {
@@ -656,7 +655,7 @@ i915_gem_gtt_pwrite_slow(struct drm_devi
 			 struct drm_i915_gem_pwrite *args,
 			 struct drm_file *file_priv)
 {
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	ssize_t remain;
 	loff_t gtt_page_base, offset;
@@ -700,7 +699,7 @@ i915_gem_gtt_pwrite_slow(struct drm_devi
 	if (ret)
 		goto out_unpin_object;
 
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 	offset = obj_priv->gtt_offset + args->offset;
 
 	while (remain > 0) {
@@ -762,7 +761,7 @@ i915_gem_shmem_pwrite_fast(struct drm_de
 			   struct drm_i915_gem_pwrite *args,
 			   struct drm_file *file_priv)
 {
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	ssize_t remain;
 	loff_t offset, page_base;
 	char __user *user_data;
@@ -782,7 +781,7 @@ i915_gem_shmem_pwrite_fast(struct drm_de
 	if (ret != 0)
 		goto fail_put_pages;
 
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 	offset = args->offset;
 	obj_priv->dirty = 1;
 
@@ -830,7 +829,7 @@ i915_gem_shmem_pwrite_slow(struct drm_de
 			   struct drm_i915_gem_pwrite *args,
 			   struct drm_file *file_priv)
 {
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	struct mm_struct *mm = current->mm;
 	struct page **user_pages;
 	ssize_t remain;
@@ -878,7 +877,7 @@ i915_gem_shmem_pwrite_slow(struct drm_de
 	if (ret != 0)
 		goto fail_put_pages;
 
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 	offset = args->offset;
 	obj_priv->dirty = 1;
 
@@ -953,7 +952,7 @@ i915_gem_pwrite_ioctl(struct drm_device
 	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
 	if (obj == NULL)
 		return -EBADF;
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 
 	/* Bounds check destination.
 	 *
@@ -961,7 +960,7 @@ i915_gem_pwrite_ioctl(struct drm_device
 	 */
 	if (args->offset > obj->size || args->size > obj->size ||
 	    args->offset + args->size > obj->size) {
-		drm_gem_object_unreference(obj);
+		drm_gem_object_unreference_unlocked(obj);
 		return -EINVAL;
 	}
 
@@ -995,7 +994,7 @@ i915_gem_pwrite_ioctl(struct drm_device
 		DRM_INFO("pwrite failed %d\n", ret);
 #endif
 
-	drm_gem_object_unreference(obj);
+	drm_gem_object_unreference_unlocked(obj);
 
 	return ret;
 }
@@ -1035,7 +1034,7 @@ i915_gem_set_domain_ioctl(struct drm_dev
 	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
 	if (obj == NULL)
 		return -EBADF;
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 
 	mutex_lock(&dev->struct_mutex);
 
@@ -1097,7 +1096,7 @@ i915_gem_sw_finish_ioctl(struct drm_devi
 	DRM_INFO("%s: sw_finish %d (%p %zd)\n",
 		 __func__, args->handle, obj, obj->size);
 #endif
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 
 	/* Pinned buffers may be scanout, so flush the cache */
 	if (obj_priv->pin_count)
@@ -1138,9 +1137,7 @@ i915_gem_mmap_ioctl(struct drm_device *d
 		       PROT_READ | PROT_WRITE, MAP_SHARED,
 		       args->offset);
 	up_write(&current->mm->mmap_sem);
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(obj);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(obj);
 	if (IS_ERR((void *)addr))
 		return addr;
 
@@ -1170,7 +1167,7 @@ int i915_gem_fault(struct vm_area_struct
 	struct drm_gem_object *obj = vma->vm_private_data;
 	struct drm_device *dev = obj->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	pgoff_t page_offset;
 	unsigned long pfn;
 	int ret = 0;
@@ -1237,7 +1234,7 @@ i915_gem_create_mmap_offset(struct drm_g
 {
 	struct drm_device *dev = obj->dev;
 	struct drm_gem_mm *mm = dev->mm_private;
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	struct drm_map_list *list;
 	struct drm_local_map *map;
 	int ret = 0;
@@ -1308,7 +1305,7 @@ void
 i915_gem_release_mmap(struct drm_gem_object *obj)
 {
 	struct drm_device *dev = obj->dev;
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
 	if (dev->dev_mapping)
 		unmap_mapping_range(dev->dev_mapping,
@@ -1319,7 +1316,7 @@ static void
 i915_gem_free_mmap_offset(struct drm_gem_object *obj)
 {
 	struct drm_device *dev = obj->dev;
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	struct drm_gem_mm *mm = dev->mm_private;
 	struct drm_map_list *list;
 
@@ -1350,7 +1347,7 @@ static uint32_t
 i915_gem_get_gtt_alignment(struct drm_gem_object *obj)
 {
 	struct drm_device *dev = obj->dev;
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	int start, i;
 
 	/*
@@ -1409,7 +1406,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_devic
 
 	mutex_lock(&dev->struct_mutex);
 
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 
 	if (obj_priv->madv != I915_MADV_WILLNEED) {
 		DRM_ERROR("Attempting to mmap a purgeable buffer\n");
@@ -1453,7 +1450,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_devic
 void
 i915_gem_object_put_pages(struct drm_gem_object *obj)
 {
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	int page_count = obj->size / PAGE_SIZE;
 	int i;
 
@@ -1470,9 +1467,6 @@ i915_gem_object_put_pages(struct drm_gem
 		obj_priv->dirty = 0;
 
 	for (i = 0; i < page_count; i++) {
-		if (obj_priv->pages[i] == NULL)
-			break;
-
 		if (obj_priv->dirty)
 			set_page_dirty(obj_priv->pages[i]);
 
@@ -1492,7 +1486,7 @@ i915_gem_object_move_to_active(struct dr
 {
 	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;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
 	/* Add a reference if we're newly entering the active list. */
 	if (!obj_priv->active) {
@@ -1512,7 +1506,7 @@ i915_gem_object_move_to_flushing(struct
 {
 	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;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
 	BUG_ON(!obj_priv->active);
 	list_move_tail(&obj_priv->list, &dev_priv->mm.flushing_list);
@@ -1523,7 +1517,7 @@ i915_gem_object_move_to_flushing(struct
 static void
 i915_gem_object_truncate(struct drm_gem_object *obj)
 {
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	struct inode *inode;
 
 	inode = obj->filp->f_path.dentry->d_inode;
@@ -1544,7 +1538,7 @@ i915_gem_object_move_to_inactive(struct
 {
 	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;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
 	i915_verify_inactive(dev, __FILE__, __LINE__);
 	if (obj_priv->pin_count != 0)
@@ -1562,6 +1556,45 @@ i915_gem_object_move_to_inactive(struct
 	i915_verify_inactive(dev, __FILE__, __LINE__);
 }
 
+static void
+i915_gem_process_flushing_list(struct drm_device *dev,
+			       uint32_t flush_domains, uint32_t seqno)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj_priv, *next;
+
+	list_for_each_entry_safe(obj_priv, next,
+				 &dev_priv->mm.gpu_write_list,
+				 gpu_write_list) {
+		struct drm_gem_object *obj = obj_priv->obj;
+
+		if ((obj->write_domain & flush_domains) ==
+		    obj->write_domain) {
+			uint32_t old_write_domain = obj->write_domain;
+
+			obj->write_domain = 0;
+			list_del_init(&obj_priv->gpu_write_list);
+			i915_gem_object_move_to_active(obj, seqno);
+
+			/* update the fence lru list */
+			if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
+				list_move_tail(&obj_priv->fence_list,
+						&dev_priv->mm.fence_list);
+
+			trace_i915_gem_object_change_domain(obj,
+							    obj->read_domains,
+							    old_write_domain);
+		}
+	}
+}
+
+#define PIPE_CONTROL_FLUSH(addr)					\
+	OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |		\
+		 PIPE_CONTROL_DEPTH_STALL);				\
+	OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT);			\
+	OUT_RING(0);							\
+	OUT_RING(0);							\
+
 /**
  * Creates a new sequence number, emitting a write of it to the status page
  * plus an interrupt, which will trigger i915_user_interrupt_handler.
@@ -1596,13 +1629,47 @@ i915_add_request(struct drm_device *dev,
 	if (dev_priv->mm.next_gem_seqno == 0)
 		dev_priv->mm.next_gem_seqno++;
 
-	BEGIN_LP_RING(4);
-	OUT_RING(MI_STORE_DWORD_INDEX);
-	OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
-	OUT_RING(seqno);
+	if (HAS_PIPE_CONTROL(dev)) {
+		u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;
 
-	OUT_RING(MI_USER_INTERRUPT);
-	ADVANCE_LP_RING();
+		/*
+		 * Workaround qword write incoherence by flushing the
+		 * PIPE_NOTIFY buffers out to memory before requesting
+		 * an interrupt.
+		 */
+		BEGIN_LP_RING(32);
+		OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+			 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
+		OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+		OUT_RING(seqno);
+		OUT_RING(0);
+		PIPE_CONTROL_FLUSH(scratch_addr);
+		scratch_addr += 128; /* write to separate cachelines */
+		PIPE_CONTROL_FLUSH(scratch_addr);
+		scratch_addr += 128;
+		PIPE_CONTROL_FLUSH(scratch_addr);
+		scratch_addr += 128;
+		PIPE_CONTROL_FLUSH(scratch_addr);
+		scratch_addr += 128;
+		PIPE_CONTROL_FLUSH(scratch_addr);
+		scratch_addr += 128;
+		PIPE_CONTROL_FLUSH(scratch_addr);
+		OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+			 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
+			 PIPE_CONTROL_NOTIFY);
+		OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+		OUT_RING(seqno);
+		OUT_RING(0);
+		ADVANCE_LP_RING();
+	} else {
+		BEGIN_LP_RING(4);
+		OUT_RING(MI_STORE_DWORD_INDEX);
+		OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+		OUT_RING(seqno);
+
+		OUT_RING(MI_USER_INTERRUPT);
+		ADVANCE_LP_RING();
+	}
 
 	DRM_DEBUG_DRIVER("%d\n", seqno);
 
@@ -1620,29 +1687,8 @@ i915_add_request(struct drm_device *dev,
 	/* Associate any objects on the flushing list matching the write
 	 * domain we're flushing with our flush.
 	 */
-	if (flush_domains != 0) {
-		struct drm_i915_gem_object *obj_priv, *next;
-
-		list_for_each_entry_safe(obj_priv, next,
-					 &dev_priv->mm.gpu_write_list,
-					 gpu_write_list) {
-			struct drm_gem_object *obj = obj_priv->obj;
-
-			if ((obj->write_domain & flush_domains) ==
-			    obj->write_domain) {
-				uint32_t old_write_domain = obj->write_domain;
-
-				obj->write_domain = 0;
-				list_del_init(&obj_priv->gpu_write_list);
-				i915_gem_object_move_to_active(obj, seqno);
-
-				trace_i915_gem_object_change_domain(obj,
-								    obj->read_domains,
-								    old_write_domain);
-			}
-		}
-
-	}
+	if (flush_domains != 0) 
+		i915_gem_process_flushing_list(dev, flush_domains, seqno);
 
 	if (!dev_priv->mm.suspended) {
 		mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
@@ -1747,7 +1793,10 @@ i915_get_gem_seqno(struct drm_device *de
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
 
-	return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
+	if (HAS_PIPE_CONTROL(dev))
+		return ((volatile u32 *)(dev_priv->seqno_page))[0];
+	else
+		return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
 }
 
 /**
@@ -1822,7 +1871,7 @@ i915_do_wait_request(struct drm_device *
 		return -EIO;
 
 	if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
-		if (IS_IRONLAKE(dev))
+		if (HAS_PCH_SPLIT(dev))
 			ier = I915_READ(DEIER) | I915_READ(GTIER);
 		else
 			ier = I915_READ(IER);
@@ -1960,7 +2009,7 @@ static int
 i915_gem_object_wait_rendering(struct drm_gem_object *obj)
 {
 	struct drm_device *dev = obj->dev;
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	int ret;
 
 	/* This function only exists to support waiting for existing rendering,
@@ -1991,7 +2040,8 @@ int
 i915_gem_object_unbind(struct drm_gem_object *obj)
 {
 	struct drm_device *dev = obj->dev;
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	int ret = 0;
 
 #if WATCH_BUF
@@ -2046,8 +2096,10 @@ i915_gem_object_unbind(struct drm_gem_ob
 	}
 
 	/* Remove ourselves from the LRU list if present. */
+	spin_lock(&dev_priv->mm.active_list_lock);
 	if (!list_empty(&obj_priv->list))
 		list_del_init(&obj_priv->list);
+	spin_unlock(&dev_priv->mm.active_list_lock);
 
 	if (i915_gem_object_is_purgeable(obj_priv))
 		i915_gem_object_truncate(obj);
@@ -2085,11 +2137,34 @@ i915_gem_find_inactive_object(struct drm
 }
 
 static int
+i915_gpu_idle(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	bool lists_empty;
+	uint32_t seqno;
+
+	spin_lock(&dev_priv->mm.active_list_lock);
+	lists_empty = 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)
+		return 0;
+
+	/* Flush everything onto the inactive list. */
+	i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS);
+	seqno = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS);
+	if (seqno == 0)
+		return -ENOMEM;
+
+	return i915_wait_request(dev, seqno);
+}
+
+static int
 i915_gem_evict_everything(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	int ret;
-	uint32_t seqno;
 	bool lists_empty;
 
 	spin_lock(&dev_priv->mm.active_list_lock);
@@ -2102,12 +2177,7 @@ i915_gem_evict_everything(struct drm_dev
 		return -ENOSPC;
 
 	/* Flush everything (on to the inactive lists) and evict */
-	i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS);
-	seqno = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS);
-	if (seqno == 0)
-		return -ENOMEM;
-
-	ret = i915_wait_request(dev, seqno);
+	ret = i915_gpu_idle(dev);
 	if (ret)
 		return ret;
 
@@ -2147,7 +2217,7 @@ i915_gem_evict_something(struct drm_devi
 #if WATCH_LRU
 			DRM_INFO("%s: evicting %p\n", __func__, obj);
 #endif
-			obj_priv = obj->driver_private;
+			obj_priv = to_intel_bo(obj);
 			BUG_ON(obj_priv->pin_count != 0);
 			BUG_ON(obj_priv->active);
 
@@ -2199,11 +2269,6 @@ i915_gem_evict_something(struct drm_devi
 				seqno = i915_add_request(dev, NULL, obj->write_domain);
 				if (seqno == 0)
 					return -ENOMEM;
-
-				ret = i915_wait_request(dev, seqno);
-				if (ret)
-					return ret;
-
 				continue;
 			}
 		}
@@ -2223,12 +2288,11 @@ int
 i915_gem_object_get_pages(struct drm_gem_object *obj,
 			  gfp_t gfpmask)
 {
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	int page_count, i;
 	struct address_space *mapping;
 	struct inode *inode;
 	struct page *page;
-	int ret;
 
 	if (obj_priv->pages_refcount++ != 0)
 		return 0;
@@ -2251,11 +2315,9 @@ i915_gem_object_get_pages(struct drm_gem
 					   mapping_gfp_mask (mapping) |
 					   __GFP_COLD |
 					   gfpmask);
-		if (IS_ERR(page)) {
-			ret = PTR_ERR(page);
-			i915_gem_object_put_pages(obj);
-			return ret;
-		}
+		if (IS_ERR(page))
+			goto err_pages;
+
 		obj_priv->pages[i] = page;
 	}
 
@@ -2263,6 +2325,37 @@ i915_gem_object_get_pages(struct drm_gem
 		i915_gem_object_do_bit_17_swizzle(obj);
 
 	return 0;
+
+err_pages:
+	while (i--)
+		page_cache_release(obj_priv->pages[i]);
+
+	drm_free_large(obj_priv->pages);
+	obj_priv->pages = NULL;
+	obj_priv->pages_refcount--;
+	return PTR_ERR(page);
+}
+
+static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg)
+{
+	struct drm_gem_object *obj = reg->obj;
+	struct drm_device *dev = obj->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
+	int regnum = obj_priv->fence_reg;
+	uint64_t val;
+
+	val = (uint64_t)((obj_priv->gtt_offset + obj->size - 4096) &
+		    0xfffff000) << 32;
+	val |= obj_priv->gtt_offset & 0xfffff000;
+	val |= (uint64_t)((obj_priv->stride / 128) - 1) <<
+		SANDYBRIDGE_FENCE_PITCH_SHIFT;
+
+	if (obj_priv->tiling_mode == I915_TILING_Y)
+		val |= 1 << I965_FENCE_TILING_Y_SHIFT;
+	val |= I965_FENCE_REG_VALID;
+
+	I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (regnum * 8), val);
 }
 
 static void i965_write_fence_reg(struct drm_i915_fence_reg *reg)
@@ -2270,7 +2363,7 @@ static void i965_write_fence_reg(struct
 	struct drm_gem_object *obj = reg->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;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	int regnum = obj_priv->fence_reg;
 	uint64_t val;
 
@@ -2290,7 +2383,7 @@ static void i915_write_fence_reg(struct
 	struct drm_gem_object *obj = reg->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;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	int regnum = obj_priv->fence_reg;
 	int tile_width;
 	uint32_t fence_reg, val;
@@ -2313,6 +2406,12 @@ static void i915_write_fence_reg(struct
 	pitch_val = obj_priv->stride / tile_width;
 	pitch_val = ffs(pitch_val) - 1;
 
+	if (obj_priv->tiling_mode == I915_TILING_Y &&
+	    HAS_128_BYTE_Y_TILING(dev))
+		WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL);
+	else
+		WARN_ON(pitch_val > I915_FENCE_MAX_PITCH_VAL);
+
 	val = obj_priv->gtt_offset;
 	if (obj_priv->tiling_mode == I915_TILING_Y)
 		val |= 1 << I830_FENCE_TILING_Y_SHIFT;
@@ -2332,7 +2431,7 @@ static void i830_write_fence_reg(struct
 	struct drm_gem_object *obj = reg->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;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	int regnum = obj_priv->fence_reg;
 	uint32_t val;
 	uint32_t pitch_val;
@@ -2361,6 +2460,58 @@ static void i830_write_fence_reg(struct
 	I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val);
 }
 
+static int i915_find_fence_reg(struct drm_device *dev)
+{
+	struct drm_i915_fence_reg *reg = NULL;
+	struct drm_i915_gem_object *obj_priv = NULL;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_gem_object *obj = NULL;
+	int i, avail, ret;
+
+	/* First try to find a free reg */
+	avail = 0;
+	for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) {
+		reg = &dev_priv->fence_regs[i];
+		if (!reg->obj)
+			return i;
+
+		obj_priv = to_intel_bo(reg->obj);
+		if (!obj_priv->pin_count)
+		    avail++;
+	}
+
+	if (avail == 0)
+		return -ENOSPC;
+
+	/* None available, try to steal one or wait for a user to finish */
+	i = I915_FENCE_REG_NONE;
+	list_for_each_entry(obj_priv, &dev_priv->mm.fence_list,
+			    fence_list) {
+		obj = obj_priv->obj;
+
+		if (obj_priv->pin_count)
+			continue;
+
+		/* found one! */
+		i = obj_priv->fence_reg;
+		break;
+	}
+
+	BUG_ON(i == I915_FENCE_REG_NONE);
+
+	/* We only have a reference on obj from the active list. put_fence_reg
+	 * might drop that one, causing a use-after-free in it. So hold a
+	 * private reference to obj like the other callers of put_fence_reg
+	 * (set_tiling ioctl) do. */
+	drm_gem_object_reference(obj);
+	ret = i915_gem_object_put_fence_reg(obj);
+	drm_gem_object_unreference(obj);
+	if (ret != 0)
+		return ret;
+
+	return i;
+}
+
 /**
  * i915_gem_object_get_fence_reg - set up a fence reg for an object
  * @obj: object to map through a fence reg
@@ -2379,10 +2530,9 @@ i915_gem_object_get_fence_reg(struct drm
 {
 	struct drm_device *dev = obj->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	struct drm_i915_fence_reg *reg = NULL;
-	struct drm_i915_gem_object *old_obj_priv = NULL;
-	int i, ret, avail;
+	int ret;
 
 	/* Just update our place in the LRU if our fence is getting used. */
 	if (obj_priv->fence_reg != I915_FENCE_REG_NONE) {
@@ -2410,86 +2560,27 @@ i915_gem_object_get_fence_reg(struct drm
 		break;
 	}
 
-	/* First try to find a free reg */
-	avail = 0;
-	for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) {
-		reg = &dev_priv->fence_regs[i];
-		if (!reg->obj)
-			break;
-
-		old_obj_priv = reg->obj->driver_private;
-		if (!old_obj_priv->pin_count)
-		    avail++;
-	}
-
-	/* None available, try to steal one or wait for a user to finish */
-	if (i == dev_priv->num_fence_regs) {
-		struct drm_gem_object *old_obj = NULL;
-
-		if (avail == 0)
-			return -ENOSPC;
-
-		list_for_each_entry(old_obj_priv, &dev_priv->mm.fence_list,
-				    fence_list) {
-			old_obj = old_obj_priv->obj;
-
-			if (old_obj_priv->pin_count)
-				continue;
-
-			/* Take a reference, as otherwise the wait_rendering
-			 * below may cause the object to get freed out from
-			 * under us.
-			 */
-			drm_gem_object_reference(old_obj);
-
-			/* i915 uses fences for GPU access to tiled buffers */
-			if (IS_I965G(dev) || !old_obj_priv->active)
-				break;
-
-			/* This brings the object to the head of the LRU if it
-			 * had been written to.  The only way this should
-			 * result in us waiting longer than the expected
-			 * optimal amount of time is if there was a
-			 * fence-using buffer later that was read-only.
-			 */
-			i915_gem_object_flush_gpu_write_domain(old_obj);
-			ret = i915_gem_object_wait_rendering(old_obj);
-			if (ret != 0) {
-				drm_gem_object_unreference(old_obj);
-				return ret;
-			}
-
-			break;
-		}
-
-		/*
-		 * Zap this virtual mapping so we can set up a fence again
-		 * for this object next time we need it.
-		 */
-		i915_gem_release_mmap(old_obj);
-
-		i = old_obj_priv->fence_reg;
-		reg = &dev_priv->fence_regs[i];
-
-		old_obj_priv->fence_reg = I915_FENCE_REG_NONE;
-		list_del_init(&old_obj_priv->fence_list);
-
-		drm_gem_object_unreference(old_obj);
-	}
+	ret = i915_find_fence_reg(dev);
+	if (ret < 0)
+		return ret;
 
-	obj_priv->fence_reg = i;
+	obj_priv->fence_reg = ret;
+	reg = &dev_priv->fence_regs[obj_priv->fence_reg];
 	list_add_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list);
 
 	reg->obj = obj;
 
-	if (IS_I965G(dev))
+	if (IS_GEN6(dev))
+		sandybridge_write_fence_reg(reg);
+	else if (IS_I965G(dev))
 		i965_write_fence_reg(reg);
 	else if (IS_I9XX(dev))
 		i915_write_fence_reg(reg);
 	else
 		i830_write_fence_reg(reg);
 
-	trace_i915_gem_object_get_fence(obj, i, obj_priv->tiling_mode);
+	trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg,
+			obj_priv->tiling_mode);
 
 	return 0;
 }
@@ -2506,11 +2597,14 @@ i915_gem_clear_fence_reg(struct drm_gem_
 {
 	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;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
-	if (IS_I965G(dev))
+	if (IS_GEN6(dev)) {
+		I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 +
+			     (obj_priv->fence_reg * 8), 0);
+	} else if (IS_I965G(dev)) {
 		I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0);
-	else {
+	} else {
 		uint32_t fence_reg;
 
 		if (obj_priv->fence_reg < 8)
@@ -2539,11 +2633,17 @@ int
 i915_gem_object_put_fence_reg(struct drm_gem_object *obj)
 {
 	struct drm_device *dev = obj->dev;
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
 	if (obj_priv->fence_reg == I915_FENCE_REG_NONE)
 		return 0;
 
+	/* If we've changed tiling, GTT-mappings of the object
+	 * need to re-fault to ensure that the correct fence register
+	 * setup is in place.
+	 */
+	i915_gem_release_mmap(obj);
+
 	/* On the i915, GPU access to tiled buffers is via a fence,
 	 * therefore we must wait for any outstanding access to complete
 	 * before clearing the fence.
@@ -2552,12 +2652,12 @@ i915_gem_object_put_fence_reg(struct drm
 		int ret;
 
 		i915_gem_object_flush_gpu_write_domain(obj);
-		i915_gem_object_flush_gtt_write_domain(obj);
 		ret = i915_gem_object_wait_rendering(obj);
 		if (ret != 0)
 			return ret;
 	}
 
+	i915_gem_object_flush_gtt_write_domain(obj);
 	i915_gem_clear_fence_reg (obj);
 
 	return 0;
@@ -2571,7 +2671,7 @@ i915_gem_object_bind_to_gtt(struct drm_g
 {
 	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;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	struct drm_mm_node *free_space;
 	gfp_t gfpmask =  __GFP_NORETRY | __GFP_NOWARN;
 	int ret;
@@ -2678,7 +2778,7 @@ i915_gem_object_bind_to_gtt(struct drm_g
 void
 i915_gem_clflush_object(struct drm_gem_object *obj)
 {
-	struct drm_i915_gem_object	*obj_priv = obj->driver_private;
+	struct drm_i915_gem_object	*obj_priv = to_intel_bo(obj);
 
 	/* If we don't have a page list set up, then we're not pinned
 	 * to GPU, and we can ignore the cache flush because it'll happen
@@ -2697,7 +2797,6 @@ static void
 i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
 {
 	struct drm_device *dev = obj->dev;
-	uint32_t seqno;
 	uint32_t old_write_domain;
 
 	if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0)
@@ -2706,9 +2805,8 @@ i915_gem_object_flush_gpu_write_domain(s
 	/* Queue the GPU write cache flushing we need. */
 	old_write_domain = obj->write_domain;
 	i915_gem_flush(dev, 0, obj->write_domain);
-	seqno = i915_add_request(dev, NULL, obj->write_domain);
+	(void) i915_add_request(dev, NULL, obj->write_domain);
 	BUG_ON(obj->write_domain);
-	i915_gem_object_move_to_active(obj, seqno);
 
 	trace_i915_gem_object_change_domain(obj,
 					    obj->read_domains,
@@ -2781,7 +2879,7 @@ i915_gem_object_flush_write_domain(struc
 int
 i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
 {
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	uint32_t old_write_domain, old_read_domains;
 	int ret;
 
@@ -2831,7 +2929,7 @@ int
 i915_gem_object_set_to_display_plane(struct drm_gem_object *obj)
 {
 	struct drm_device *dev = obj->dev;
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	uint32_t old_write_domain, old_read_domains;
 	int ret;
 
@@ -3044,7 +3142,7 @@ static void
 i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
 {
 	struct drm_device		*dev = obj->dev;
-	struct drm_i915_gem_object	*obj_priv = obj->driver_private;
+	struct drm_i915_gem_object	*obj_priv = to_intel_bo(obj);
 	uint32_t			invalidate_domains = 0;
 	uint32_t			flush_domains = 0;
 	uint32_t			old_read_domains;
@@ -3129,7 +3227,7 @@ 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_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
 	if (!obj_priv->page_cpu_valid)
 		return;
@@ -3169,7 +3267,7 @@ static int
 i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
 					  uint64_t offset, uint64_t size)
 {
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	uint32_t old_read_domains;
 	int i, ret;
 
@@ -3238,7 +3336,7 @@ i915_gem_object_pin_and_relocate(struct
 {
 	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;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	int i, ret;
 	void __iomem *reloc_page;
 	bool need_fence;
@@ -3247,7 +3345,8 @@ i915_gem_object_pin_and_relocate(struct
 	             obj_priv->tiling_mode != I915_TILING_NONE;
 
 	/* Check fence reg constraints and rebind if necessary */
-	if (need_fence && !i915_obj_fenceable(dev, obj))
+	if (need_fence && !i915_gem_object_fence_offset_ok(obj,
+	    obj_priv->tiling_mode))
 		i915_gem_object_unbind(obj);
 
 	/* Choose the GTT offset for our buffer and put it there. */
@@ -3288,7 +3387,7 @@ i915_gem_object_pin_and_relocate(struct
 			i915_gem_object_unpin(obj);
 			return -EBADF;
 		}
-		target_obj_priv = target_obj->driver_private;
+		target_obj_priv = to_intel_bo(target_obj);
 
 #if WATCH_RELOC
 		DRM_INFO("%s: obj %p offset %08x target %d "
@@ -3317,6 +3416,16 @@ i915_gem_object_pin_and_relocate(struct
 		}
 
 		/* Validate that the target is in a valid r/w GPU domain */
+		if (reloc->write_domain & (reloc->write_domain - 1)) {
+			DRM_ERROR("reloc with multiple write domains: "
+				  "obj %p target %d offset %d "
+				  "read %08x write %08x",
+				  obj, reloc->target_handle,
+				  (int) reloc->offset,
+				  reloc->read_domains,
+				  reloc->write_domain);
+			return -EINVAL;
+		}
 		if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||
 		    reloc->read_domains & I915_GEM_DOMAIN_CPU) {
 			DRM_ERROR("reloc with read/write CPU domains: "
@@ -3630,7 +3739,7 @@ i915_gem_wait_for_pending_flip(struct dr
 		prepare_to_wait(&dev_priv->pending_flip_queue,
 				&wait, TASK_INTERRUPTIBLE);
 		for (i = 0; i < count; i++) {
-			obj_priv = object_list[i]->driver_private;
+			obj_priv = to_intel_bo(object_list[i]);
 			if (atomic_read(&obj_priv->pending_flip) > 0)
 				break;
 		}
@@ -3739,7 +3848,7 @@ i915_gem_do_execbuffer(struct drm_device
 			goto err;
 		}
 
-		obj_priv = object_list[i]->driver_private;
+		obj_priv = to_intel_bo(object_list[i]);
 		if (obj_priv->in_execbuffer) {
 			DRM_ERROR("Object %p appears more than once in object list\n",
 				   object_list[i]);
@@ -3865,7 +3974,7 @@ i915_gem_do_execbuffer(struct drm_device
 
 	for (i = 0; i < args->buffer_count; i++) {
 		struct drm_gem_object *obj = object_list[i];
-		struct drm_i915_gem_object *obj_priv = obj->driver_private;
+		struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 		uint32_t old_write_domain = obj->write_domain;
 
 		obj->write_domain = obj->pending_write_domain;
@@ -3940,7 +4049,7 @@ err:
 
 	for (i = 0; i < args->buffer_count; i++) {
 		if (object_list[i]) {
-			obj_priv = object_list[i]->driver_private;
+			obj_priv = to_intel_bo(object_list[i]);
 			obj_priv->in_execbuffer = false;
 		}
 		drm_gem_object_unreference(object_list[i]);
@@ -4118,7 +4227,7 @@ int
 i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
 {
 	struct drm_device *dev = obj->dev;
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	int ret;
 
 	i915_verify_inactive(dev, __FILE__, __LINE__);
@@ -4151,7 +4260,7 @@ i915_gem_object_unpin(struct drm_gem_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;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
 	i915_verify_inactive(dev, __FILE__, __LINE__);
 	obj_priv->pin_count--;
@@ -4191,7 +4300,7 @@ i915_gem_pin_ioctl(struct drm_device *de
 		mutex_unlock(&dev->struct_mutex);
 		return -EBADF;
 	}
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 
 	if (obj_priv->madv != I915_MADV_WILLNEED) {
 		DRM_ERROR("Attempting to pin a purgeable buffer\n");
@@ -4248,7 +4357,7 @@ i915_gem_unpin_ioctl(struct drm_device *
 		return -EBADF;
 	}
 
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 	if (obj_priv->pin_filp != file_priv) {
 		DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n",
 			  args->handle);
@@ -4290,7 +4399,7 @@ i915_gem_busy_ioctl(struct drm_device *d
 	 */
 	i915_gem_retire_requests(dev);
 
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 	/* Don't count being on the flushing list against the object being
 	 * done.  Otherwise, a buffer left on the flushing list but not getting
 	 * flushed (because nobody's flushing that domain) won't ever return
@@ -4336,7 +4445,7 @@ i915_gem_madvise_ioctl(struct drm_device
 	}
 
 	mutex_lock(&dev->struct_mutex);
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 
 	if (obj_priv->pin_count) {
 		drm_gem_object_unreference(obj);
@@ -4397,7 +4506,7 @@ int i915_gem_init_object(struct drm_gem_
 void i915_gem_free_object(struct drm_gem_object *obj)
 {
 	struct drm_device *dev = obj->dev;
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
 	trace_i915_gem_object_destroy(obj);
 
@@ -4445,8 +4554,7 @@ int
 i915_gem_idle(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	uint32_t seqno, cur_seqno, last_seqno;
-	int stuck, ret;
+	int ret;
 
 	mutex_lock(&dev->struct_mutex);
 
@@ -4455,116 +4563,80 @@ i915_gem_idle(struct drm_device *dev)
 		return 0;
 	}
 
-	/* Hack!  Don't let anybody do execbuf while we don't control the chip.
-	 * We need to replace this with a semaphore, or something.
-	 */
-	dev_priv->mm.suspended = 1;
-	del_timer(&dev_priv->hangcheck_timer);
-
-	/* Cancel the retire work handler, wait for it to finish if running
-	 */
-	mutex_unlock(&dev->struct_mutex);
-	cancel_delayed_work_sync(&dev_priv->mm.retire_work);
-	mutex_lock(&dev->struct_mutex);
-
-	i915_kernel_lost_context(dev);
-
-	/* Flush the GPU along with all non-CPU write domains
-	 */
-	i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS);
-	seqno = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS);
-
-	if (seqno == 0) {
+	ret = i915_gpu_idle(dev);
+	if (ret) {
 		mutex_unlock(&dev->struct_mutex);
-		return -ENOMEM;
+		return ret;
 	}
 
-	dev_priv->mm.waiting_gem_seqno = seqno;
-	last_seqno = 0;
-	stuck = 0;
-	for (;;) {
-		cur_seqno = i915_get_gem_seqno(dev);
-		if (i915_seqno_passed(cur_seqno, seqno))
-			break;
-		if (last_seqno == cur_seqno) {
-			if (stuck++ > 100) {
-				DRM_ERROR("hardware wedged\n");
-				atomic_set(&dev_priv->mm.wedged, 1);
-				DRM_WAKEUP(&dev_priv->irq_queue);
-				break;
-			}
+	/* Under UMS, be paranoid and evict. */
+	if (!drm_core_check_feature(dev, DRIVER_MODESET)) {
+		ret = i915_gem_evict_from_inactive_list(dev);
+		if (ret) {
+			mutex_unlock(&dev->struct_mutex);
+			return ret;
 		}
-		msleep(10);
-		last_seqno = cur_seqno;
-	}
-	dev_priv->mm.waiting_gem_seqno = 0;
-
-	i915_gem_retire_requests(dev);
-
-	spin_lock(&dev_priv->mm.active_list_lock);
-	if (!atomic_read(&dev_priv->mm.wedged)) {
-		/* Active and flushing should now be empty as we've
-		 * waited for a sequence higher than any pending execbuffer
-		 */
-		WARN_ON(!list_empty(&dev_priv->mm.active_list));
-		WARN_ON(!list_empty(&dev_priv->mm.flushing_list));
-		/* Request should now be empty as we've also waited
-		 * for the last request in the list
-		 */
-		WARN_ON(!list_empty(&dev_priv->mm.request_list));
 	}
 
-	/* Empty the active and flushing lists to inactive.  If there's
-	 * anything left at this point, it means that we're wedged and
-	 * nothing good's going to happen by leaving them there.  So strip
-	 * the GPU domains and just stuff them onto inactive.
+	/* Hack!  Don't let anybody do execbuf while we don't control the chip.
+	 * We need to replace this with a semaphore, or something.
+	 * And not confound mm.suspended!
 	 */
-	while (!list_empty(&dev_priv->mm.active_list)) {
-		struct drm_gem_object *obj;
-		uint32_t old_write_domain;
+	dev_priv->mm.suspended = 1;
+	del_timer(&dev_priv->hangcheck_timer);
 
-		obj = list_first_entry(&dev_priv->mm.active_list,
-				       struct drm_i915_gem_object,
-				       list)->obj;
-		old_write_domain = obj->write_domain;
-		obj->write_domain &= ~I915_GEM_GPU_DOMAINS;
-		i915_gem_object_move_to_inactive(obj);
+	i915_kernel_lost_context(dev);
+	i915_gem_cleanup_ringbuffer(dev);
 
-		trace_i915_gem_object_change_domain(obj,
-						    obj->read_domains,
-						    old_write_domain);
-	}
-	spin_unlock(&dev_priv->mm.active_list_lock);
+	mutex_unlock(&dev->struct_mutex);
 
-	while (!list_empty(&dev_priv->mm.flushing_list)) {
-		struct drm_gem_object *obj;
-		uint32_t old_write_domain;
+	/* Cancel the retire work handler, which should be idle now. */
+	cancel_delayed_work_sync(&dev_priv->mm.retire_work);
 
-		obj = list_first_entry(&dev_priv->mm.flushing_list,
-				       struct drm_i915_gem_object,
-				       list)->obj;
-		old_write_domain = obj->write_domain;
-		obj->write_domain &= ~I915_GEM_GPU_DOMAINS;
-		i915_gem_object_move_to_inactive(obj);
+	return 0;
+}
 
-		trace_i915_gem_object_change_domain(obj,
-						    obj->read_domains,
-						    old_write_domain);
+/*
+ * 965+ support PIPE_CONTROL commands, which provide finer grained control
+ * over cache flushing.
+ */
+static int
+i915_gem_init_pipe_control(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_gem_object *obj;
+	struct drm_i915_gem_object *obj_priv;
+	int ret;
+
+	obj = drm_gem_object_alloc(dev, 4096);
+	if (obj == NULL) {
+		DRM_ERROR("Failed to allocate seqno page\n");
+		ret = -ENOMEM;
+		goto err;
 	}
+	obj_priv = to_intel_bo(obj);
+	obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
 
+	ret = i915_gem_object_pin(obj, 4096);
+	if (ret)
+		goto err_unref;
 
-	/* Move all inactive buffers out of the GTT. */
-	ret = i915_gem_evict_from_inactive_list(dev);
-	WARN_ON(!list_empty(&dev_priv->mm.inactive_list));
-	if (ret) {
-		mutex_unlock(&dev->struct_mutex);
-		return ret;
-	}
+	dev_priv->seqno_gfx_addr = obj_priv->gtt_offset;
+	dev_priv->seqno_page =  kmap(obj_priv->pages[0]);
+	if (dev_priv->seqno_page == NULL)
+		goto err_unpin;
 
-	i915_gem_cleanup_ringbuffer(dev);
-	mutex_unlock(&dev->struct_mutex);
+	dev_priv->seqno_obj = obj;
+	memset(dev_priv->seqno_page, 0, PAGE_SIZE);
 
 	return 0;
+
+err_unpin:
+	i915_gem_object_unpin(obj);
+err_unref:
+	drm_gem_object_unreference(obj);
+err:
+	return ret;
 }
 
 static int
@@ -4584,15 +4656,16 @@ i915_gem_init_hws(struct drm_device *dev
 	obj = drm_gem_object_alloc(dev, 4096);
 	if (obj == NULL) {
 		DRM_ERROR("Failed to allocate status page\n");
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto err;
 	}
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 	obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
 
 	ret = i915_gem_object_pin(obj, 4096);
 	if (ret != 0) {
 		drm_gem_object_unreference(obj);
-		return ret;
+		goto err_unref;
 	}
 
 	dev_priv->status_gfx_addr = obj_priv->gtt_offset;
@@ -4601,17 +4674,52 @@ i915_gem_init_hws(struct drm_device *dev
 	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));
-		i915_gem_object_unpin(obj);
-		drm_gem_object_unreference(obj);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto err_unpin;
 	}
+
+	if (HAS_PIPE_CONTROL(dev)) {
+		ret = i915_gem_init_pipe_control(dev);
+		if (ret)
+			goto err_unpin;
+	}
+
 	dev_priv->hws_obj = obj;
 	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
-	I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
-	I915_READ(HWS_PGA); /* posting read */
+	if (IS_GEN6(dev)) {
+		I915_WRITE(HWS_PGA_GEN6, dev_priv->status_gfx_addr);
+		I915_READ(HWS_PGA_GEN6); /* posting read */
+	} else {
+		I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
+		I915_READ(HWS_PGA); /* posting read */
+	}
 	DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
 
 	return 0;
+
+err_unpin:
+	i915_gem_object_unpin(obj);
+err_unref:
+	drm_gem_object_unreference(obj);
+err:
+	return 0;
+}
+
+static void
+i915_gem_cleanup_pipe_control(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_gem_object *obj;
+	struct drm_i915_gem_object *obj_priv;
+
+	obj = dev_priv->seqno_obj;
+	obj_priv = to_intel_bo(obj);
+	kunmap(obj_priv->pages[0]);
+	i915_gem_object_unpin(obj);
+	drm_gem_object_unreference(obj);
+	dev_priv->seqno_obj = NULL;
+
+	dev_priv->seqno_page = NULL;
 }
 
 static void
@@ -4625,7 +4733,7 @@ i915_gem_cleanup_hws(struct drm_device *
 		return;
 
 	obj = dev_priv->hws_obj;
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 
 	kunmap(obj_priv->pages[0]);
 	i915_gem_object_unpin(obj);
@@ -4635,6 +4743,9 @@ i915_gem_cleanup_hws(struct drm_device *
 	memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
 	dev_priv->hw_status_page = NULL;
 
+	if (HAS_PIPE_CONTROL(dev))
+		i915_gem_cleanup_pipe_control(dev);
+
 	/* Write high address into HWS_PGA when disabling. */
 	I915_WRITE(HWS_PGA, 0x1ffff000);
 }
@@ -4659,7 +4770,7 @@ i915_gem_init_ringbuffer(struct drm_devi
 		i915_gem_cleanup_hws(dev);
 		return -ENOMEM;
 	}
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 
 	ret = i915_gem_object_pin(obj, 4096);
 	if (ret != 0) {
@@ -4745,6 +4856,11 @@ i915_gem_init_ringbuffer(struct drm_devi
 			ring->space += ring->Size;
 	}
 
+	if (IS_I9XX(dev) && !IS_GEN3(dev)) {
+		I915_WRITE(MI_MODE,
+			   (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH);
+	}
+
 	return 0;
 }
 
@@ -4850,7 +4966,8 @@ i915_gem_load(struct drm_device *dev)
 	spin_unlock(&shrink_list_lock);
 
 	/* Old X drivers will take 0-2 for front, back, depth buffers */
-	dev_priv->fence_reg_start = 3;
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		dev_priv->fence_reg_start = 3;
 
 	if (IS_I965G(dev) || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
 		dev_priv->num_fence_regs = 16;
@@ -4946,7 +5063,7 @@ void i915_gem_detach_phys_object(struct
 	int ret;
 	int page_count;
 
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 	if (!obj_priv->phys_obj)
 		return;
 
@@ -4985,7 +5102,7 @@ i915_gem_attach_phys_object(struct drm_d
 	if (id > I915_MAX_PHYS_OBJECT)
 		return -EINVAL;
 
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 
 	if (obj_priv->phys_obj) {
 		if (obj_priv->phys_obj->id == id)
@@ -5036,7 +5153,7 @@ i915_gem_phys_pwrite(struct drm_device *
 		     struct drm_i915_gem_pwrite *args,
 		     struct drm_file *file_priv)
 {
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	void *obj_addr;
 	int ret;
 	char __user *user_data;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_gem_debug.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_gem_debug.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_gem_debug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_gem_debug.c	2010-05-16 17:17:36.000000000 -0400
@@ -72,7 +72,7 @@ void
 i915_gem_dump_object(struct drm_gem_object *obj, int len,
 		     const char *where, uint32_t mark)
 {
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	int page;
 
 	DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset);
@@ -137,7 +137,7 @@ void
 i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle)
 {
 	struct drm_device *dev = obj->dev;
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	int page;
 	uint32_t *gtt_mapping;
 	uint32_t *backing_map = NULL;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_gem_tiling.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_gem_tiling.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_gem_tiling.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_gem_tiling.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,8 +25,6 @@
  *
  */
 
-#include <linux/acpi.h>
-#include <linux/pnp.h>
 #include "linux/string.h"
 #include "linux/bitops.h"
 #include "drmP.h"
@@ -83,120 +81,6 @@
  * to match what the GPU expects.
  */
 
-#define MCHBAR_I915 0x44
-#define MCHBAR_I965 0x48
-#define MCHBAR_SIZE (4*4096)
-
-#define DEVEN_REG 0x54
-#define   DEVEN_MCHBAR_EN (1 << 28)
-
-/* Allocate space for the MCH regs if needed, return nonzero on error */
-static int
-intel_alloc_mchbar_resource(struct drm_device *dev)
-{
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
-	u32 temp_lo, temp_hi = 0;
-	u64 mchbar_addr;
-	int ret = 0;
-
-	if (IS_I965G(dev))
-		pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi);
-	pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo);
-	mchbar_addr = ((u64)temp_hi << 32) | temp_lo;
-
-	/* If ACPI doesn't have it, assume we need to allocate it ourselves */
-#ifdef CONFIG_PNP
-	if (mchbar_addr &&
-	    pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) {
-		ret = 0;
-		goto out;
-	}
-#endif
-
-	/* Get some space for it */
-	ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res,
-				     MCHBAR_SIZE, MCHBAR_SIZE,
-				     PCIBIOS_MIN_MEM,
-				     0,   pcibios_align_resource,
-				     dev_priv->bridge_dev);
-	if (ret) {
-		DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret);
-		dev_priv->mch_res.start = 0;
-		goto out;
-	}
-
-	if (IS_I965G(dev))
-		pci_write_config_dword(dev_priv->bridge_dev, reg + 4,
-				       upper_32_bits(dev_priv->mch_res.start));
-
-	pci_write_config_dword(dev_priv->bridge_dev, reg,
-			       lower_32_bits(dev_priv->mch_res.start));
-out:
-	return ret;
-}
-
-/* Setup MCHBAR if possible, return true if we should disable it again */
-static bool
-intel_setup_mchbar(struct drm_device *dev)
-{
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
-	u32 temp;
-	bool need_disable = false, enabled;
-
-	if (IS_I915G(dev) || IS_I915GM(dev)) {
-		pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
-		enabled = !!(temp & DEVEN_MCHBAR_EN);
-	} else {
-		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
-		enabled = temp & 1;
-	}
-
-	/* If it's already enabled, don't have to do anything */
-	if (enabled)
-		goto out;
-
-	if (intel_alloc_mchbar_resource(dev))
-		goto out;
-
-	need_disable = true;
-
-	/* Space is allocated or reserved, so enable it. */
-	if (IS_I915G(dev) || IS_I915GM(dev)) {
-		pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG,
-				       temp | DEVEN_MCHBAR_EN);
-	} else {
-		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
-		pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1);
-	}
-out:
-	return need_disable;
-}
-
-static void
-intel_teardown_mchbar(struct drm_device *dev, bool disable)
-{
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
-	u32 temp;
-
-	if (disable) {
-		if (IS_I915G(dev) || IS_I915GM(dev)) {
-			pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
-			temp &= ~DEVEN_MCHBAR_EN;
-			pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, temp);
-		} else {
-			pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
-			temp &= ~1;
-			pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp);
-		}
-	}
-
-	if (dev_priv->mch_res.start)
-		release_resource(&dev_priv->mch_res);
-}
-
 /**
  * Detects bit 6 swizzling of address lookup between IGD access and CPU
  * access through main memory.
@@ -207,9 +91,8 @@ i915_gem_detect_bit_6_swizzle(struct drm
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
 	uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
-	bool need_disable;
 
-	if (IS_IRONLAKE(dev)) {
+	if (IS_IRONLAKE(dev) || IS_GEN6(dev)) {
 		/* On Ironlake whatever DRAM config, GPU always do
 		 * same swizzling setup.
 		 */
@@ -224,9 +107,6 @@ i915_gem_detect_bit_6_swizzle(struct drm
 	} else if (IS_MOBILE(dev)) {
 		uint32_t dcc;
 
-		/* Try to make sure MCHBAR is enabled before poking at it */
-		need_disable = intel_setup_mchbar(dev);
-
 		/* 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,
@@ -266,8 +146,6 @@ i915_gem_detect_bit_6_swizzle(struct drm
 			swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
 			swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
 		}
-
-		intel_teardown_mchbar(dev, need_disable);
 	} else {
 		/* The 965, G33, and newer, have a very flexible memory
 		 * configuration.  It will enable dual-channel mode
@@ -302,39 +180,6 @@ i915_gem_detect_bit_6_swizzle(struct drm
 	dev_priv->mm.bit_6_swizzle_y = swizzle_y;
 }
 
-
-/**
- * Returns whether an object is currently fenceable.  If not, it may need
- * to be unbound and have its pitch adjusted.
- */
-bool
-i915_obj_fenceable(struct drm_device *dev, struct drm_gem_object *obj)
-{
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
-
-	if (IS_I965G(dev)) {
-		/* The 965 can have fences at any page boundary. */
-		if (obj->size & 4095)
-			return false;
-		return true;
-	} else if (IS_I9XX(dev)) {
-		if (obj_priv->gtt_offset & ~I915_FENCE_START_MASK)
-			return false;
-	} else {
-		if (obj_priv->gtt_offset & ~I830_FENCE_START_MASK)
-			return false;
-	}
-
-	/* Power of two sized... */
-	if (obj->size & (obj->size - 1))
-		return false;
-
-	/* Objects must be size aligned as well */
-	if (obj_priv->gtt_offset & (obj->size - 1))
-		return false;
-	return true;
-}
-
 /* Check pitch constriants for all chips & tiling formats */
 bool
 i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
@@ -357,21 +202,17 @@ i915_tiling_ok(struct drm_device *dev, i
 		 * 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))
+	} else if (IS_GEN3(dev) || IS_GEN2(dev)) {
+		if (stride > 8192)
 			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;
+		if (IS_GEN3(dev)) {
+			if (size > I830_FENCE_MAX_SIZE_VAL << 20)
+				return false;
+		} else {
+			if (size > I830_FENCE_MAX_SIZE_VAL << 19)
+				return false;
+		}
 	}
 
 	/* 965+ just needs multiples of tile width */
@@ -391,11 +232,11 @@ i915_tiling_ok(struct drm_device *dev, i
 	return true;
 }
 
-static bool
+bool
 i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode)
 {
 	struct drm_device *dev = obj->dev;
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
 	if (obj_priv->gtt_space == NULL)
 		return true;
@@ -435,12 +276,10 @@ i915_gem_set_tiling(struct drm_device *d
 	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
 	if (obj == NULL)
 		return -EINVAL;
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 
 	if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) {
-		mutex_lock(&dev->struct_mutex);
-		drm_gem_object_unreference(obj);
-		mutex_unlock(&dev->struct_mutex);
+		drm_gem_object_unreference_unlocked(obj);
 		return -EINVAL;
 	}
 
@@ -482,9 +321,12 @@ i915_gem_set_tiling(struct drm_device *d
 		 * need to ensure that any fence register is cleared.
 		 */
 		if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode))
-		    ret = i915_gem_object_unbind(obj);
+			ret = i915_gem_object_unbind(obj);
+		else if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
+			ret = i915_gem_object_put_fence_reg(obj);
 		else
-		    ret = i915_gem_object_put_fence_reg(obj);
+			i915_gem_release_mmap(obj);
+
 		if (ret != 0) {
 			WARN(ret != -ERESTARTSYS,
 			     "failed to reset object for tiling switch");
@@ -493,12 +335,6 @@ i915_gem_set_tiling(struct drm_device *d
 			goto err;
 		}
 
-		/* If we've changed tiling, GTT-mappings of the object
-		 * need to re-fault to ensure that the correct fence register
-		 * setup is in place.
-		 */
-		i915_gem_release_mmap(obj);
-
 		obj_priv->tiling_mode = args->tiling_mode;
 		obj_priv->stride = args->stride;
 	}
@@ -524,7 +360,7 @@ i915_gem_get_tiling(struct drm_device *d
 	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
 	if (obj == NULL)
 		return -EINVAL;
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 
 	mutex_lock(&dev->struct_mutex);
 
@@ -587,7 +423,7 @@ i915_gem_object_do_bit_17_swizzle(struct
 {
 	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;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	int page_count = obj->size >> PAGE_SHIFT;
 	int i;
 
@@ -616,7 +452,7 @@ i915_gem_object_save_bit_17_swizzle(stru
 {
 	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;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	int page_count = obj->size >> PAGE_SHIFT;
 	int i;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_irq.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_irq.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
  */
 
 #include <linux/sysrq.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
@@ -166,7 +167,7 @@ void intel_enable_asle (struct drm_devic
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		ironlake_enable_display_irq(dev_priv, DE_GSE);
 	else
 		i915_enable_pipestat(dev_priv, 1,
@@ -259,16 +260,67 @@ static void i915_hotplug_work_func(struc
 
 	if (mode_config->num_connector) {
 		list_for_each_entry(connector, &mode_config->connector_list, head) {
-			struct intel_output *intel_output = to_intel_output(connector);
+			struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 	
-			if (intel_output->hot_plug)
-				(*intel_output->hot_plug) (intel_output);
+			if (intel_encoder->hot_plug)
+				(*intel_encoder->hot_plug) (intel_encoder);
 		}
 	}
 	/* Just fire off a uevent and let userspace tell us what to do */
 	drm_sysfs_hotplug_event(dev);
 }
 
+static void i915_handle_rps_change(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	u32 busy_up, busy_down, max_avg, min_avg;
+	u16 rgvswctl;
+	u8 new_delay = dev_priv->cur_delay;
+
+	I915_WRITE(MEMINTRSTS, I915_READ(MEMINTRSTS) & ~MEMINT_EVAL_CHG);
+	busy_up = I915_READ(RCPREVBSYTUPAVG);
+	busy_down = I915_READ(RCPREVBSYTDNAVG);
+	max_avg = I915_READ(RCBMAXAVG);
+	min_avg = I915_READ(RCBMINAVG);
+
+	/* Handle RCS change request from hw */
+	if (busy_up > max_avg) {
+		if (dev_priv->cur_delay != dev_priv->max_delay)
+			new_delay = dev_priv->cur_delay - 1;
+		if (new_delay < dev_priv->max_delay)
+			new_delay = dev_priv->max_delay;
+	} else if (busy_down < min_avg) {
+		if (dev_priv->cur_delay != dev_priv->min_delay)
+			new_delay = dev_priv->cur_delay + 1;
+		if (new_delay > dev_priv->min_delay)
+			new_delay = dev_priv->min_delay;
+	}
+
+	DRM_DEBUG("rps change requested: %d -> %d\n",
+		  dev_priv->cur_delay, new_delay);
+
+	rgvswctl = I915_READ(MEMSWCTL);
+	if (rgvswctl & MEMCTL_CMD_STS) {
+		DRM_ERROR("gpu busy, RCS change rejected\n");
+		return; /* still busy with another command */
+	}
+
+	/* Program the new state */
+	rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) |
+		(new_delay << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM;
+	I915_WRITE(MEMSWCTL, rgvswctl);
+	POSTING_READ(MEMSWCTL);
+
+	rgvswctl |= MEMCTL_CMD_STS;
+	I915_WRITE(MEMSWCTL, rgvswctl);
+
+	dev_priv->cur_delay = new_delay;
+
+	DRM_DEBUG("rps changed\n");
+
+	return;
+}
+
 irqreturn_t ironlake_irq_handler(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -297,7 +349,7 @@ irqreturn_t ironlake_irq_handler(struct
 				READ_BREADCRUMB(dev_priv);
 	}
 
-	if (gt_iir & GT_USER_INTERRUPT) {
+	if (gt_iir & GT_PIPE_NOTIFY) {
 		u32 seqno = i915_get_gem_seqno(dev);
 		dev_priv->mm.irq_gem_seqno = seqno;
 		trace_i915_gem_request_complete(dev, seqno);
@@ -331,6 +383,11 @@ irqreturn_t ironlake_irq_handler(struct
 		queue_work(dev_priv->wq, &dev_priv->hotplug_work);
 	}
 
+	if (de_iir & DE_PCU_EVENT) {
+		I915_WRITE(MEMINTRSTS, I915_READ(MEMINTRSTS));
+		i915_handle_rps_change(dev);
+	}
+
 	/* should clear PCH hotplug event before clear CPU irq */
 	I915_WRITE(SDEIIR, pch_iir);
 	I915_WRITE(GTIIR, gt_iir);
@@ -376,6 +433,125 @@ static void i915_error_work_func(struct
 	}
 }
 
+static struct drm_i915_error_object *
+i915_error_object_create(struct drm_device *dev,
+			 struct drm_gem_object *src)
+{
+	struct drm_i915_error_object *dst;
+	struct drm_i915_gem_object *src_priv;
+	int page, page_count;
+
+	if (src == NULL)
+		return NULL;
+
+	src_priv = to_intel_bo(src);
+	if (src_priv->pages == NULL)
+		return NULL;
+
+	page_count = src->size / PAGE_SIZE;
+
+	dst = kmalloc(sizeof(*dst) + page_count * sizeof (u32 *), GFP_ATOMIC);
+	if (dst == NULL)
+		return NULL;
+
+	for (page = 0; page < page_count; page++) {
+		void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC);
+		unsigned long flags;
+
+		if (d == NULL)
+			goto unwind;
+		local_irq_save(flags);
+		s = kmap_atomic(src_priv->pages[page], KM_IRQ0);
+		memcpy(d, s, PAGE_SIZE);
+		kunmap_atomic(s, KM_IRQ0);
+		local_irq_restore(flags);
+		dst->pages[page] = d;
+	}
+	dst->page_count = page_count;
+	dst->gtt_offset = src_priv->gtt_offset;
+
+	return dst;
+
+unwind:
+	while (page--)
+		kfree(dst->pages[page]);
+	kfree(dst);
+	return NULL;
+}
+
+static void
+i915_error_object_free(struct drm_i915_error_object *obj)
+{
+	int page;
+
+	if (obj == NULL)
+		return;
+
+	for (page = 0; page < obj->page_count; page++)
+		kfree(obj->pages[page]);
+
+	kfree(obj);
+}
+
+static void
+i915_error_state_free(struct drm_device *dev,
+		      struct drm_i915_error_state *error)
+{
+	i915_error_object_free(error->batchbuffer[0]);
+	i915_error_object_free(error->batchbuffer[1]);
+	i915_error_object_free(error->ringbuffer);
+	kfree(error->active_bo);
+	kfree(error);
+}
+
+static u32
+i915_get_bbaddr(struct drm_device *dev, u32 *ring)
+{
+	u32 cmd;
+
+	if (IS_I830(dev) || IS_845G(dev))
+		cmd = MI_BATCH_BUFFER;
+	else if (IS_I965G(dev))
+		cmd = (MI_BATCH_BUFFER_START | (2 << 6) |
+		       MI_BATCH_NON_SECURE_I965);
+	else
+		cmd = (MI_BATCH_BUFFER_START | (2 << 6));
+
+	return ring[0] == cmd ? ring[1] : 0;
+}
+
+static u32
+i915_ringbuffer_last_batch(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 head, bbaddr;
+	u32 *ring;
+
+	/* Locate the current position in the ringbuffer and walk back
+	 * to find the most recently dispatched batch buffer.
+	 */
+	bbaddr = 0;
+	head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
+	ring = (u32 *)(dev_priv->ring.virtual_start + head);
+
+	while (--ring >= (u32 *)dev_priv->ring.virtual_start) {
+		bbaddr = i915_get_bbaddr(dev, ring);
+		if (bbaddr)
+			break;
+	}
+
+	if (bbaddr == 0) {
+		ring = (u32 *)(dev_priv->ring.virtual_start + dev_priv->ring.Size);
+		while (--ring >= (u32 *)dev_priv->ring.virtual_start) {
+			bbaddr = i915_get_bbaddr(dev, ring);
+			if (bbaddr)
+				break;
+		}
+	}
+
+	return bbaddr;
+}
+
 /**
  * i915_capture_error_state - capture an error record for later analysis
  * @dev: drm device
@@ -388,19 +564,26 @@ static void i915_error_work_func(struct
 static void i915_capture_error_state(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj_priv;
 	struct drm_i915_error_state *error;
+	struct drm_gem_object *batchbuffer[2];
 	unsigned long flags;
+	u32 bbaddr;
+	int count;
 
 	spin_lock_irqsave(&dev_priv->error_lock, flags);
-	if (dev_priv->first_error)
-		goto out;
+	error = dev_priv->first_error;
+	spin_unlock_irqrestore(&dev_priv->error_lock, flags);
+	if (error)
+		return;
 
 	error = kmalloc(sizeof(*error), GFP_ATOMIC);
 	if (!error) {
-		DRM_DEBUG_DRIVER("out ot memory, not capturing error state\n");
-		goto out;
+		DRM_DEBUG_DRIVER("out of memory, not capturing error state\n");
+		return;
 	}
 
+	error->seqno = i915_get_gem_seqno(dev);
 	error->eir = I915_READ(EIR);
 	error->pgtbl_er = I915_READ(PGTBL_ER);
 	error->pipeastat = I915_READ(PIPEASTAT);
@@ -411,6 +594,7 @@ static void i915_capture_error_state(str
 		error->ipehr = I915_READ(IPEHR);
 		error->instdone = I915_READ(INSTDONE);
 		error->acthd = I915_READ(ACTHD);
+		error->bbaddr = 0;
 	} else {
 		error->ipeir = I915_READ(IPEIR_I965);
 		error->ipehr = I915_READ(IPEHR_I965);
@@ -418,14 +602,101 @@ static void i915_capture_error_state(str
 		error->instps = I915_READ(INSTPS);
 		error->instdone1 = I915_READ(INSTDONE1);
 		error->acthd = I915_READ(ACTHD_I965);
+		error->bbaddr = I915_READ64(BB_ADDR);
 	}
 
-	do_gettimeofday(&error->time);
+	bbaddr = i915_ringbuffer_last_batch(dev);
 
-	dev_priv->first_error = error;
+	/* Grab the current batchbuffer, most likely to have crashed. */
+	batchbuffer[0] = NULL;
+	batchbuffer[1] = NULL;
+	count = 0;
+	list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) {
+		struct drm_gem_object *obj = obj_priv->obj;
 
-out:
+		if (batchbuffer[0] == NULL &&
+		    bbaddr >= obj_priv->gtt_offset &&
+		    bbaddr < obj_priv->gtt_offset + obj->size)
+			batchbuffer[0] = obj;
+
+		if (batchbuffer[1] == NULL &&
+		    error->acthd >= obj_priv->gtt_offset &&
+		    error->acthd < obj_priv->gtt_offset + obj->size &&
+		    batchbuffer[0] != obj)
+			batchbuffer[1] = obj;
+
+		count++;
+	}
+
+	/* We need to copy these to an anonymous buffer as the simplest
+	 * method to avoid being overwritten by userpace.
+	 */
+	error->batchbuffer[0] = i915_error_object_create(dev, batchbuffer[0]);
+	error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]);
+
+	/* Record the ringbuffer */
+	error->ringbuffer = i915_error_object_create(dev, dev_priv->ring.ring_obj);
+
+	/* Record buffers on the active list. */
+	error->active_bo = NULL;
+	error->active_bo_count = 0;
+
+	if (count)
+		error->active_bo = kmalloc(sizeof(*error->active_bo)*count,
+					   GFP_ATOMIC);
+
+	if (error->active_bo) {
+		int i = 0;
+		list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) {
+			struct drm_gem_object *obj = obj_priv->obj;
+
+			error->active_bo[i].size = obj->size;
+			error->active_bo[i].name = obj->name;
+			error->active_bo[i].seqno = obj_priv->last_rendering_seqno;
+			error->active_bo[i].gtt_offset = obj_priv->gtt_offset;
+			error->active_bo[i].read_domains = obj->read_domains;
+			error->active_bo[i].write_domain = obj->write_domain;
+			error->active_bo[i].fence_reg = obj_priv->fence_reg;
+			error->active_bo[i].pinned = 0;
+			if (obj_priv->pin_count > 0)
+				error->active_bo[i].pinned = 1;
+			if (obj_priv->user_pin_count > 0)
+				error->active_bo[i].pinned = -1;
+			error->active_bo[i].tiling = obj_priv->tiling_mode;
+			error->active_bo[i].dirty = obj_priv->dirty;
+			error->active_bo[i].purgeable = obj_priv->madv != I915_MADV_WILLNEED;
+
+			if (++i == count)
+				break;
+		}
+		error->active_bo_count = i;
+	}
+
+	do_gettimeofday(&error->time);
+
+	spin_lock_irqsave(&dev_priv->error_lock, flags);
+	if (dev_priv->first_error == NULL) {
+		dev_priv->first_error = error;
+		error = NULL;
+	}
 	spin_unlock_irqrestore(&dev_priv->error_lock, flags);
+
+	if (error)
+		i915_error_state_free(dev, error);
+}
+
+void i915_destroy_error_state(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_error_state *error;
+
+	spin_lock(&dev_priv->error_lock);
+	error = dev_priv->first_error;
+	dev_priv->first_error = NULL;
+	spin_unlock(&dev_priv->error_lock);
+
+	if (error)
+		i915_error_state_free(dev, error);
 }
 
 /**
@@ -576,7 +847,7 @@ irqreturn_t i915_driver_irq_handler(DRM_
 
 	atomic_inc(&dev_priv->irq_received);
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		return ironlake_irq_handler(dev);
 
 	iir = I915_READ(IIR);
@@ -737,8 +1008,8 @@ void i915_user_irq_get(struct drm_device
 
 	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
 	if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) {
-		if (IS_IRONLAKE(dev))
-			ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
+		if (HAS_PCH_SPLIT(dev))
+			ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
 		else
 			i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
 	}
@@ -753,8 +1024,8 @@ void i915_user_irq_put(struct drm_device
 	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
 	BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
 	if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
-		if (IS_IRONLAKE(dev))
-			ironlake_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
+		if (HAS_PCH_SPLIT(dev))
+			ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
 		else
 			i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
 	}
@@ -861,7 +1132,7 @@ int i915_enable_vblank(struct drm_device
 		return -EINVAL;
 
 	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		ironlake_enable_display_irq(dev_priv, (pipe == 0) ? 
 					    DE_PIPEA_VBLANK: DE_PIPEB_VBLANK);
 	else if (IS_I965G(dev))
@@ -883,7 +1154,7 @@ void i915_disable_vblank(struct drm_devi
 	unsigned long irqflags;
 
 	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		ironlake_disable_display_irq(dev_priv, (pipe == 0) ? 
 					     DE_PIPEA_VBLANK: DE_PIPEB_VBLANK);
 	else
@@ -897,7 +1168,7 @@ void i915_enable_interrupt (struct drm_d
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (!IS_IRONLAKE(dev))
+	if (!HAS_PCH_SPLIT(dev))
 		opregion_enable_asle(dev);
 	dev_priv->irq_enabled = 1;
 }
@@ -973,7 +1244,11 @@ void i915_hangcheck_elapsed(unsigned lon
 	struct drm_device *dev = (struct drm_device *)data;
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	uint32_t acthd;
-       
+
+	/* No reset support on this chip yet. */
+	if (IS_GEN6(dev))
+		return;
+
 	if (!IS_I965G(dev))
 		acthd = I915_READ(ACTHD);
 	else
@@ -1034,7 +1309,7 @@ static int ironlake_irq_postinstall(stru
 	/* enable kind of interrupts always enabled */
 	u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
 			   DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE;
-	u32 render_mask = GT_USER_INTERRUPT;
+	u32 render_mask = GT_PIPE_NOTIFY;
 	u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
 			   SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
 
@@ -1064,6 +1339,13 @@ static int ironlake_irq_postinstall(stru
 	I915_WRITE(SDEIER, dev_priv->pch_irq_enable_reg);
 	(void) I915_READ(SDEIER);
 
+	if (IS_IRONLAKE_M(dev)) {
+		/* Clear & enable PCU event interrupts */
+		I915_WRITE(DEIIR, DE_PCU_EVENT);
+		I915_WRITE(DEIER, I915_READ(DEIER) | DE_PCU_EVENT);
+		ironlake_enable_display_irq(dev_priv, DE_PCU_EVENT);
+	}
+
 	return 0;
 }
 
@@ -1076,7 +1358,7 @@ void i915_driver_irq_preinstall(struct d
 	INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
 	INIT_WORK(&dev_priv->error_work, i915_error_work_func);
 
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		ironlake_irq_preinstall(dev);
 		return;
 	}
@@ -1108,7 +1390,7 @@ int i915_driver_irq_postinstall(struct d
 
 	dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		return ironlake_irq_postinstall(dev);
 
 	/* Unmask the interrupts that we always want on. */
@@ -1196,7 +1478,7 @@ void i915_driver_irq_uninstall(struct dr
 
 	dev_priv->vblank_pipe = 0;
 
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		ironlake_irq_uninstall(dev);
 		return;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_opregion.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_opregion.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_opregion.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_opregion.c	2010-05-16 17:17:36.000000000 -0400
@@ -382,8 +382,57 @@ static void intel_didl_outputs(struct dr
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_opregion *opregion = &dev_priv->opregion;
 	struct drm_connector *connector;
+	acpi_handle handle;
+	struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL;
+	unsigned long long device_id;
+	acpi_status status;
 	int i = 0;
 
+	handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
+	if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev)))
+		return;
+
+	if (acpi_is_video_device(acpi_dev))
+		acpi_video_bus = acpi_dev;
+	else {
+		list_for_each_entry(acpi_cdev, &acpi_dev->children, node) {
+			if (acpi_is_video_device(acpi_cdev)) {
+				acpi_video_bus = acpi_cdev;
+				break;
+			}
+		}
+	}
+
+	if (!acpi_video_bus) {
+		printk(KERN_WARNING "No ACPI video bus found\n");
+		return;
+	}
+
+	list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) {
+		if (i >= 8) {
+			dev_printk (KERN_ERR, &dev->pdev->dev,
+				    "More than 8 outputs detected\n");
+			return;
+		}
+		status =
+			acpi_evaluate_integer(acpi_cdev->handle, "_ADR",
+						NULL, &device_id);
+		if (ACPI_SUCCESS(status)) {
+			if (!device_id)
+				goto blind_set;
+			opregion->acpi->didl[i] = (u32)(device_id & 0x0f0f);
+			i++;
+		}
+	}
+
+end:
+	/* If fewer than 8 outputs, the list must be null terminated */
+	if (i < 8)
+		opregion->acpi->didl[i] = 0;
+	return;
+
+blind_set:
+	i = 0;
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 		int output_type = ACPI_OTHER_OUTPUT;
 		if (i >= 8) {
@@ -416,10 +465,7 @@ static void intel_didl_outputs(struct dr
 		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;
+	goto end;
 }
 
 int intel_opregion_init(struct drm_device *dev, int resume)
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_reg.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_reg.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_reg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_reg.h	2010-05-16 17:17:36.000000000 -0400
@@ -53,6 +53,25 @@
 #define INTEL_GMCH_GMS_STOLEN_224M	(0xc << 4)
 #define INTEL_GMCH_GMS_STOLEN_352M	(0xd << 4)
 
+#define SNB_GMCH_CTRL	0x50
+#define SNB_GMCH_GMS_STOLEN_MASK	0xF8
+#define SNB_GMCH_GMS_STOLEN_32M		(1 << 3)
+#define SNB_GMCH_GMS_STOLEN_64M		(2 << 3)
+#define SNB_GMCH_GMS_STOLEN_96M		(3 << 3)
+#define SNB_GMCH_GMS_STOLEN_128M	(4 << 3)
+#define SNB_GMCH_GMS_STOLEN_160M	(5 << 3)
+#define SNB_GMCH_GMS_STOLEN_192M	(6 << 3)
+#define SNB_GMCH_GMS_STOLEN_224M	(7 << 3)
+#define SNB_GMCH_GMS_STOLEN_256M	(8 << 3)
+#define SNB_GMCH_GMS_STOLEN_288M	(9 << 3)
+#define SNB_GMCH_GMS_STOLEN_320M	(0xa << 3)
+#define SNB_GMCH_GMS_STOLEN_352M	(0xb << 3)
+#define SNB_GMCH_GMS_STOLEN_384M	(0xc << 3)
+#define SNB_GMCH_GMS_STOLEN_416M	(0xd << 3)
+#define SNB_GMCH_GMS_STOLEN_448M	(0xe << 3)
+#define SNB_GMCH_GMS_STOLEN_480M	(0xf << 3)
+#define SNB_GMCH_GMS_STOLEN_512M	(0x10 << 3)
+
 /* PCI config space */
 
 #define HPLLCC	0xc0 /* 855 only */
@@ -61,6 +80,7 @@
 #define   GC_CLOCK_100_200		(1 << 0)
 #define   GC_CLOCK_100_133		(2 << 0)
 #define   GC_CLOCK_166_250		(3 << 0)
+#define GCFGC2	0xda
 #define GCFGC	0xf0 /* 915+ only */
 #define   GC_LOW_FREQUENCY_ENABLE	(1 << 7)
 #define   GC_DISPLAY_CLOCK_190_200_MHZ	(0 << 4)
@@ -210,6 +230,16 @@
 #define   ASYNC_FLIP                (1<<22)
 #define   DISPLAY_PLANE_A           (0<<20)
 #define   DISPLAY_PLANE_B           (1<<20)
+#define GFX_OP_PIPE_CONTROL	((0x3<<29)|(0x3<<27)|(0x2<<24)|2)
+#define   PIPE_CONTROL_QW_WRITE	(1<<14)
+#define   PIPE_CONTROL_DEPTH_STALL (1<<13)
+#define   PIPE_CONTROL_WC_FLUSH	(1<<12)
+#define   PIPE_CONTROL_IS_FLUSH	(1<<11) /* MBZ on Ironlake */
+#define   PIPE_CONTROL_TC_FLUSH (1<<10) /* GM45+ only */
+#define   PIPE_CONTROL_ISP_DIS	(1<<9)
+#define   PIPE_CONTROL_NOTIFY	(1<<8)
+#define   PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */
+#define   PIPE_CONTROL_STALL_EN	(1<<1) /* in addr word, Ironlake+ only */
 
 /*
  * Fence registers
@@ -221,7 +251,7 @@
 #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   I915_FENCE_MAX_PITCH_VAL	4
 #define   I830_FENCE_MAX_PITCH_VAL	6
 #define   I830_FENCE_MAX_SIZE_VAL	(1<<8)
 
@@ -234,6 +264,9 @@
 #define   I965_FENCE_REG_VALID		(1<<0)
 #define   I965_FENCE_MAX_PITCH_VAL	0x0400
 
+#define FENCE_REG_SANDYBRIDGE_0		0x100000
+#define   SANDYBRIDGE_FENCE_PITCH_SHIFT	32
+
 /*
  * Instruction and interrupt control regs
  */
@@ -265,6 +298,7 @@
 #define INSTDONE1	0x0207c /* 965+ only */
 #define ACTHD_I965	0x02074
 #define HWS_PGA		0x02080
+#define HWS_PGA_GEN6	0x04080
 #define HWS_ADDRESS_MASK	0xfffff000
 #define HWS_START_ADDRESS_SHIFT	4
 #define PWRCTXA		0x2088 /* 965GM+ only */
@@ -274,6 +308,10 @@
 #define INSTDONE	0x02090
 #define NOPID		0x02094
 #define HWSTAM		0x02098
+
+#define MI_MODE		0x0209c
+# define VS_TIMER_DISPATCH				(1 << 6)
+
 #define SCPD0		0x0209c /* 915+ only */
 #define IER		0x020a0
 #define IIR		0x020a4
@@ -282,7 +320,7 @@
 #define   I915_PIPE_CONTROL_NOTIFY_INTERRUPT		(1<<18)
 #define   I915_DISPLAY_PORT_INTERRUPT			(1<<17)
 #define   I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT	(1<<15)
-#define   I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT	(1<<14)
+#define   I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT	(1<<14) /* p-state */
 #define   I915_HWB_OOM_INTERRUPT			(1<<13)
 #define   I915_SYNC_STATUS_INTERRUPT			(1<<12)
 #define   I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT	(1<<11)
@@ -306,11 +344,14 @@
 #define   I915_ERROR_MEMORY_REFRESH			(1<<1)
 #define   I915_ERROR_INSTRUCTION			(1<<0)
 #define INSTPM	        0x020c0
+#define   INSTPM_SELF_EN (1<<12) /* 915GM only */
 #define ACTHD	        0x020c8
 #define FW_BLC		0x020d8
 #define FW_BLC2	 	0x020dc
 #define FW_BLC_SELF	0x020e0 /* 915+ only */
-#define   FW_BLC_SELF_EN (1<<15)
+#define   FW_BLC_SELF_EN_MASK      (1<<31)
+#define   FW_BLC_SELF_FIFO_MASK    (1<<16) /* 945 only */
+#define   FW_BLC_SELF_EN           (1<<15) /* 945 only */
 #define MM_BURST_LENGTH     0x00700000
 #define MM_FIFO_WATERMARK   0x0001F000
 #define LM_BURST_LENGTH     0x00000700
@@ -324,6 +365,7 @@
 #define   CM0_COLOR_EVICT_DISABLE (1<<3)
 #define   CM0_DEPTH_WRITE_DISABLE (1<<1)
 #define   CM0_RC_OP_FLUSH_DISABLE (1<<0)
+#define BB_ADDR		0x02140 /* 8 bytes */
 #define GFX_FLSH_CNTL	0x02170 /* 915+ only */
 
 
@@ -338,7 +380,7 @@
 #define   FBC_CTL_PERIODIC	(1<<30)
 #define   FBC_CTL_INTERVAL_SHIFT (16)
 #define   FBC_CTL_UNCOMPRESSIBLE (1<<14)
-#define   FBC_C3_IDLE		(1<<13)
+#define   FBC_CTL_C3_IDLE	(1<<13)
 #define   FBC_CTL_STRIDE_SHIFT	(5)
 #define   FBC_CTL_FENCENO	(1<<0)
 #define FBC_COMMAND		0x0320c
@@ -784,10 +826,144 @@
 #define CLKCFG_MEM_800					(3 << 4)
 #define CLKCFG_MEM_MASK					(7 << 4)
 
-/** GM965 GM45 render standby register */
-#define MCHBAR_RENDER_STANDBY	0x111B8
+#define CRSTANDVID		0x11100
+#define PXVFREQ_BASE		0x11110 /* P[0-15]VIDFREQ (0x1114c) (Ironlake) */
+#define   PXVFREQ_PX_MASK	0x7f000000
+#define   PXVFREQ_PX_SHIFT	24
+#define VIDFREQ_BASE		0x11110
+#define VIDFREQ1		0x11110 /* VIDFREQ1-4 (0x1111c) (Cantiga) */
+#define VIDFREQ2		0x11114
+#define VIDFREQ3		0x11118
+#define VIDFREQ4		0x1111c
+#define   VIDFREQ_P0_MASK	0x1f000000
+#define   VIDFREQ_P0_SHIFT	24
+#define   VIDFREQ_P0_CSCLK_MASK	0x00f00000
+#define   VIDFREQ_P0_CSCLK_SHIFT 20
+#define   VIDFREQ_P0_CRCLK_MASK	0x000f0000
+#define   VIDFREQ_P0_CRCLK_SHIFT 16
+#define   VIDFREQ_P1_MASK	0x00001f00
+#define   VIDFREQ_P1_SHIFT	8
+#define   VIDFREQ_P1_CSCLK_MASK	0x000000f0
+#define   VIDFREQ_P1_CSCLK_SHIFT 4
+#define   VIDFREQ_P1_CRCLK_MASK	0x0000000f
+#define INTTOEXT_BASE_ILK	0x11300
+#define INTTOEXT_BASE		0x11120 /* INTTOEXT1-8 (0x1113c) */
+#define   INTTOEXT_MAP3_SHIFT	24
+#define   INTTOEXT_MAP3_MASK	(0x1f << INTTOEXT_MAP3_SHIFT)
+#define   INTTOEXT_MAP2_SHIFT	16
+#define   INTTOEXT_MAP2_MASK	(0x1f << INTTOEXT_MAP2_SHIFT)
+#define   INTTOEXT_MAP1_SHIFT	8
+#define   INTTOEXT_MAP1_MASK	(0x1f << INTTOEXT_MAP1_SHIFT)
+#define   INTTOEXT_MAP0_SHIFT	0
+#define   INTTOEXT_MAP0_MASK	(0x1f << INTTOEXT_MAP0_SHIFT)
+#define MEMSWCTL		0x11170 /* Ironlake only */
+#define   MEMCTL_CMD_MASK	0xe000
+#define   MEMCTL_CMD_SHIFT	13
+#define   MEMCTL_CMD_RCLK_OFF	0
+#define   MEMCTL_CMD_RCLK_ON	1
+#define   MEMCTL_CMD_CHFREQ	2
+#define   MEMCTL_CMD_CHVID	3
+#define   MEMCTL_CMD_VMMOFF	4
+#define   MEMCTL_CMD_VMMON	5
+#define   MEMCTL_CMD_STS	(1<<12) /* write 1 triggers command, clears
+					   when command complete */
+#define   MEMCTL_FREQ_MASK	0x0f00 /* jitter, from 0-15 */
+#define   MEMCTL_FREQ_SHIFT	8
+#define   MEMCTL_SFCAVM		(1<<7)
+#define   MEMCTL_TGT_VID_MASK	0x007f
+#define MEMIHYST		0x1117c
+#define MEMINTREN		0x11180 /* 16 bits */
+#define   MEMINT_RSEXIT_EN	(1<<8)
+#define   MEMINT_CX_SUPR_EN	(1<<7)
+#define   MEMINT_CONT_BUSY_EN	(1<<6)
+#define   MEMINT_AVG_BUSY_EN	(1<<5)
+#define   MEMINT_EVAL_CHG_EN	(1<<4)
+#define   MEMINT_MON_IDLE_EN	(1<<3)
+#define   MEMINT_UP_EVAL_EN	(1<<2)
+#define   MEMINT_DOWN_EVAL_EN	(1<<1)
+#define   MEMINT_SW_CMD_EN	(1<<0)
+#define MEMINTRSTR		0x11182 /* 16 bits */
+#define   MEM_RSEXIT_MASK	0xc000
+#define   MEM_RSEXIT_SHIFT	14
+#define   MEM_CONT_BUSY_MASK	0x3000
+#define   MEM_CONT_BUSY_SHIFT	12
+#define   MEM_AVG_BUSY_MASK	0x0c00
+#define   MEM_AVG_BUSY_SHIFT	10
+#define   MEM_EVAL_CHG_MASK	0x0300
+#define   MEM_EVAL_BUSY_SHIFT	8
+#define   MEM_MON_IDLE_MASK	0x00c0
+#define   MEM_MON_IDLE_SHIFT	6
+#define   MEM_UP_EVAL_MASK	0x0030
+#define   MEM_UP_EVAL_SHIFT	4
+#define   MEM_DOWN_EVAL_MASK	0x000c
+#define   MEM_DOWN_EVAL_SHIFT	2
+#define   MEM_SW_CMD_MASK	0x0003
+#define   MEM_INT_STEER_GFX	0
+#define   MEM_INT_STEER_CMR	1
+#define   MEM_INT_STEER_SMI	2
+#define   MEM_INT_STEER_SCI	3
+#define MEMINTRSTS		0x11184
+#define   MEMINT_RSEXIT		(1<<7)
+#define   MEMINT_CONT_BUSY	(1<<6)
+#define   MEMINT_AVG_BUSY	(1<<5)
+#define   MEMINT_EVAL_CHG	(1<<4)
+#define   MEMINT_MON_IDLE	(1<<3)
+#define   MEMINT_UP_EVAL	(1<<2)
+#define   MEMINT_DOWN_EVAL	(1<<1)
+#define   MEMINT_SW_CMD		(1<<0)
+#define MEMMODECTL		0x11190
+#define   MEMMODE_BOOST_EN	(1<<31)
+#define   MEMMODE_BOOST_FREQ_MASK 0x0f000000 /* jitter for boost, 0-15 */
+#define   MEMMODE_BOOST_FREQ_SHIFT 24
+#define   MEMMODE_IDLE_MODE_MASK 0x00030000
+#define   MEMMODE_IDLE_MODE_SHIFT 16
+#define   MEMMODE_IDLE_MODE_EVAL 0
+#define   MEMMODE_IDLE_MODE_CONT 1
+#define   MEMMODE_HWIDLE_EN	(1<<15)
+#define   MEMMODE_SWMODE_EN	(1<<14)
+#define   MEMMODE_RCLK_GATE	(1<<13)
+#define   MEMMODE_HW_UPDATE	(1<<12)
+#define   MEMMODE_FSTART_MASK	0x00000f00 /* starting jitter, 0-15 */
+#define   MEMMODE_FSTART_SHIFT	8
+#define   MEMMODE_FMAX_MASK	0x000000f0 /* max jitter, 0-15 */
+#define   MEMMODE_FMAX_SHIFT	4
+#define   MEMMODE_FMIN_MASK	0x0000000f /* min jitter, 0-15 */
+#define RCBMAXAVG		0x1119c
+#define MEMSWCTL2		0x1119e /* Cantiga only */
+#define   SWMEMCMD_RENDER_OFF	(0 << 13)
+#define   SWMEMCMD_RENDER_ON	(1 << 13)
+#define   SWMEMCMD_SWFREQ	(2 << 13)
+#define   SWMEMCMD_TARVID	(3 << 13)
+#define   SWMEMCMD_VRM_OFF	(4 << 13)
+#define   SWMEMCMD_VRM_ON	(5 << 13)
+#define   CMDSTS		(1<<12)
+#define   SFCAVM		(1<<11)
+#define   SWFREQ_MASK		0x0380 /* P0-7 */
+#define   SWFREQ_SHIFT		7
+#define   TARVID_MASK		0x001f
+#define MEMSTAT_CTG		0x111a0
+#define RCBMINAVG		0x111a0
+#define RCUPEI			0x111b0
+#define RCDNEI			0x111b4
+#define MCHBAR_RENDER_STANDBY		0x111b8
 #define   RCX_SW_EXIT		(1<<23)
 #define   RSX_STATUS_MASK	0x00700000
+#define VIDCTL			0x111c0
+#define VIDSTS			0x111c8
+#define VIDSTART		0x111cc /* 8 bits */
+#define MEMSTAT_ILK			0x111f8
+#define   MEMSTAT_VID_MASK	0x7f00
+#define   MEMSTAT_VID_SHIFT	8
+#define   MEMSTAT_PSTATE_MASK	0x00f8
+#define   MEMSTAT_PSTATE_SHIFT  3
+#define   MEMSTAT_MON_ACTV	(1<<2)
+#define   MEMSTAT_SRC_CTL_MASK	0x0003
+#define   MEMSTAT_SRC_CTL_CORE	0
+#define   MEMSTAT_SRC_CTL_TRB	1
+#define   MEMSTAT_SRC_CTL_THM	2
+#define   MEMSTAT_SRC_CTL_STDBY 3
+#define RCPREVBSYTUPAVG		0x113b8
+#define RCPREVBSYTDNAVG		0x113bc
 #define PEG_BAND_GAP_DATA	0x14d68
 
 /*
@@ -2010,6 +2186,14 @@
 #define DISPLAY_PORT_PLL_BIOS_1         0x46010
 #define DISPLAY_PORT_PLL_BIOS_2         0x46014
 
+#define PCH_DSPCLK_GATE_D	0x42020
+# define DPFDUNIT_CLOCK_GATE_DISABLE		(1 << 7)
+# define DPARBUNIT_CLOCK_GATE_DISABLE		(1 << 5)
+
+#define PCH_3DCGDIS0		0x46020
+# define MARIUNIT_CLOCK_GATE_DISABLE		(1 << 18)
+# define SVSMUNIT_CLOCK_GATE_DISABLE		(1 << 1)
+
 #define FDI_PLL_FREQ_CTL        0x46030
 #define  FDI_PLL_FREQ_CHANGE_REQUEST    (1<<24)
 #define  FDI_PLL_FREQ_LOCK_LIMIT_MASK   0xfff00
@@ -2111,6 +2295,7 @@
 #define DEIER   0x4400c
 
 /* GT interrupt */
+#define GT_PIPE_NOTIFY		(1 << 4)
 #define GT_SYNC_STATUS          (1 << 2)
 #define GT_USER_INTERRUPT       (1 << 0)
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_suspend.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_suspend.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_suspend.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/i915_suspend.c	2010-05-16 17:17:36.000000000 -0400
@@ -682,6 +682,8 @@ void i915_restore_display(struct drm_dev
 		I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
 		I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR);
 		I915_WRITE(PCH_PP_CONTROL, dev_priv->savePP_CONTROL);
+		I915_WRITE(MCHBAR_RENDER_STANDBY,
+			   dev_priv->saveMCHBAR_RENDER_STANDBY);
 	} else {
 		I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
 		I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
@@ -745,11 +747,16 @@ int i915_save_state(struct drm_device *d
 		dev_priv->saveGTIMR = I915_READ(GTIMR);
 		dev_priv->saveFDI_RXA_IMR = I915_READ(FDI_RXA_IMR);
 		dev_priv->saveFDI_RXB_IMR = I915_READ(FDI_RXB_IMR);
+		dev_priv->saveMCHBAR_RENDER_STANDBY =
+			I915_READ(MCHBAR_RENDER_STANDBY);
 	} else {
 		dev_priv->saveIER = I915_READ(IER);
 		dev_priv->saveIMR = I915_READ(IMR);
 	}
 
+	if (IS_IRONLAKE_M(dev))
+		ironlake_disable_drps(dev);
+
 	/* Cache mode state */
 	dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
 
@@ -820,6 +827,9 @@ int i915_restore_state(struct drm_device
 	/* Clock gating state */
 	intel_init_clock_gating(dev);
 
+	if (IS_IRONLAKE_M(dev))
+		ironlake_enable_drps(dev);
+
 	/* Cache mode state */
 	I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_bios.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_bios.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_bios.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_bios.c	2010-05-16 17:17:36.000000000 -0400
@@ -247,6 +247,7 @@ static void
 parse_general_features(struct drm_i915_private *dev_priv,
 		       struct bdb_header *bdb)
 {
+	struct drm_device *dev = dev_priv->dev;
 	struct bdb_general_features *general;
 
 	/* Set sensible defaults in case we can't find the general block */
@@ -263,7 +264,7 @@ parse_general_features(struct drm_i915_p
 			if (IS_I85X(dev_priv->dev))
 				dev_priv->lvds_ssc_freq =
 					general->ssc_freq ? 66 : 48;
-			else if (IS_IRONLAKE(dev_priv->dev))
+			else if (IS_IRONLAKE(dev_priv->dev) || IS_GEN6(dev))
 				dev_priv->lvds_ssc_freq =
 					general->ssc_freq ? 100 : 120;
 			else
@@ -416,8 +417,9 @@ parse_edp(struct drm_i915_private *dev_p
 	edp = find_section(bdb, BDB_EDP);
 	if (!edp) {
 		if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp_support) {
-			DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported,\
-				       assume 18bpp panel color depth.\n");
+			DRM_DEBUG_KMS("No eDP BDB found but eDP panel "
+				      "supported, assume 18bpp panel color "
+				      "depth.\n");
 			dev_priv->edp_bpp = 18;
 		}
 		return;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_crt.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_crt.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_crt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_crt.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc.h"
@@ -39,7 +40,7 @@ static void intel_crt_dpms(struct drm_en
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 temp, reg;
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		reg = PCH_ADPA;
 	else
 		reg = ADPA;
@@ -113,7 +114,7 @@ static void intel_crt_mode_set(struct dr
 	else
 		dpll_md_reg = DPLL_B_MD;
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		adpa_reg = PCH_ADPA;
 	else
 		adpa_reg = ADPA;
@@ -122,7 +123,7 @@ static void intel_crt_mode_set(struct dr
 	 * Disable separate mode multiplier used when cloning SDVO to CRT
 	 * XXX this needs to be adjusted when we really are cloning
 	 */
-	if (IS_I965G(dev) && !IS_IRONLAKE(dev)) {
+	if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) {
 		dpll_md = I915_READ(dpll_md_reg);
 		I915_WRITE(dpll_md_reg,
 			   dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
@@ -136,11 +137,11 @@ static void intel_crt_mode_set(struct dr
 
 	if (intel_crtc->pipe == 0) {
 		adpa |= ADPA_PIPE_A_SELECT;
-		if (!IS_IRONLAKE(dev))
+		if (!HAS_PCH_SPLIT(dev))
 			I915_WRITE(BCLRPAT_A, 0);
 	} else {
 		adpa |= ADPA_PIPE_B_SELECT;
-		if (!IS_IRONLAKE(dev))
+		if (!HAS_PCH_SPLIT(dev))
 			I915_WRITE(BCLRPAT_B, 0);
 	}
 
@@ -202,7 +203,7 @@ static bool intel_crt_detect_hotplug(str
 	u32 hotplug_en;
 	int i, tries = 0;
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		return intel_ironlake_crt_detect_hotplug(connector);
 
 	/*
@@ -246,19 +247,19 @@ static bool intel_crt_detect_hotplug(str
 
 static bool intel_crt_detect_ddc(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
 	/* CRT should always be at 0, but check anyway */
-	if (intel_output->type != INTEL_OUTPUT_ANALOG)
+	if (intel_encoder->type != INTEL_OUTPUT_ANALOG)
 		return false;
 
-	return intel_ddc_probe(intel_output);
+	return intel_ddc_probe(intel_encoder);
 }
 
 static enum drm_connector_status
-intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)
+intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
 {
-	struct drm_encoder *encoder = &intel_output->enc;
+	struct drm_encoder *encoder = &intel_encoder->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);
@@ -386,8 +387,8 @@ intel_crt_load_detect(struct drm_crtc *c
 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 intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct drm_encoder *encoder = &intel_encoder->enc;
 	struct drm_crtc *crtc;
 	int dpms_mode;
 	enum drm_connector_status status;
@@ -404,13 +405,13 @@ static enum drm_connector_status intel_c
 
 	/* for pre-945g platforms use load detect */
 	if (encoder->crtc && encoder->crtc->enabled) {
-		status = intel_crt_load_detect(encoder->crtc, intel_output);
+		status = intel_crt_load_detect(encoder->crtc, intel_encoder);
 	} else {
-		crtc = intel_get_load_detect_pipe(intel_output,
+		crtc = intel_get_load_detect_pipe(intel_encoder,
 						  NULL, &dpms_mode);
 		if (crtc) {
-			status = intel_crt_load_detect(crtc, intel_output);
-			intel_release_load_detect_pipe(intel_output, dpms_mode);
+			status = intel_crt_load_detect(crtc, intel_encoder);
+			intel_release_load_detect_pipe(intel_encoder, dpms_mode);
 		} else
 			status = connector_status_unknown;
 	}
@@ -420,9 +421,9 @@ static enum drm_connector_status intel_c
 
 static void intel_crt_destroy(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-	intel_i2c_destroy(intel_output->ddc_bus);
+	intel_i2c_destroy(intel_encoder->ddc_bus);
 	drm_sysfs_connector_remove(connector);
 	drm_connector_cleanup(connector);
 	kfree(connector);
@@ -431,28 +432,28 @@ static void intel_crt_destroy(struct drm
 static int intel_crt_get_modes(struct drm_connector *connector)
 {
 	int ret;
-	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 	struct i2c_adapter *ddcbus;
 	struct drm_device *dev = connector->dev;
 
 
-	ret = intel_ddc_get_modes(intel_output);
+	ret = intel_ddc_get_modes(intel_encoder);
 	if (ret || !IS_G4X(dev))
 		goto end;
 
-	ddcbus = intel_output->ddc_bus;
+	ddcbus = intel_encoder->ddc_bus;
 	/* Try to probe digital port for output in DVI-I -> VGA mode. */
-	intel_output->ddc_bus =
+	intel_encoder->ddc_bus =
 		intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D");
 
-	if (!intel_output->ddc_bus) {
-		intel_output->ddc_bus = ddcbus;
+	if (!intel_encoder->ddc_bus) {
+		intel_encoder->ddc_bus = ddcbus;
 		dev_printk(KERN_ERR, &connector->dev->pdev->dev,
 			   "DDC bus registration failed for CRTDDC_D.\n");
 		goto end;
 	}
 	/* Try to get modes by GPIOD port */
-	ret = intel_ddc_get_modes(intel_output);
+	ret = intel_ddc_get_modes(intel_encoder);
 	intel_i2c_destroy(ddcbus);
 
 end:
@@ -505,26 +506,26 @@ static const struct drm_encoder_funcs in
 void intel_crt_init(struct drm_device *dev)
 {
 	struct drm_connector *connector;
-	struct intel_output *intel_output;
+	struct intel_encoder *intel_encoder;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 i2c_reg;
 
-	intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
-	if (!intel_output)
+	intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL);
+	if (!intel_encoder)
 		return;
 
-	connector = &intel_output->base;
-	drm_connector_init(dev, &intel_output->base,
+	connector = &intel_encoder->base;
+	drm_connector_init(dev, &intel_encoder->base,
 			   &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
 
-	drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs,
+	drm_encoder_init(dev, &intel_encoder->enc, &intel_crt_enc_funcs,
 			 DRM_MODE_ENCODER_DAC);
 
-	drm_mode_connector_attach_encoder(&intel_output->base,
-					  &intel_output->enc);
+	drm_mode_connector_attach_encoder(&intel_encoder->base,
+					  &intel_encoder->enc);
 
 	/* Set up the DDC bus. */
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		i2c_reg = PCH_GPIOA;
 	else {
 		i2c_reg = GPIOA;
@@ -532,22 +533,22 @@ void intel_crt_init(struct drm_device *d
 		if (dev_priv->crt_ddc_bus != 0)
 			i2c_reg = dev_priv->crt_ddc_bus;
 	}
-	intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
-	if (!intel_output->ddc_bus) {
+	intel_encoder->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
+	if (!intel_encoder->ddc_bus) {
 		dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
 			   "failed.\n");
 		return;
 	}
 
-	intel_output->type = INTEL_OUTPUT_ANALOG;
-	intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+	intel_encoder->type = INTEL_OUTPUT_ANALOG;
+	intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
 				   (1 << INTEL_ANALOG_CLONE_BIT) |
 				   (1 << INTEL_SDVO_LVDS_CLONE_BIT);
-	intel_output->crtc_mask = (1 << 0) | (1 << 1);
+	intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
 	connector->interlace_allowed = 0;
 	connector->doublescan_allowed = 0;
 
-	drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs);
+	drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs);
 	drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
 
 	drm_sysfs_connector_add(connector);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_display.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_display.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_display.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_display.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/input.h>
 #include <linux/i2c.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "intel_drv.h"
 #include "i915_drm.h"
@@ -232,7 +233,7 @@ struct intel_limit {
 #define G4X_P2_DISPLAY_PORT_FAST           10
 #define G4X_P2_DISPLAY_PORT_LIMIT          0
 
-/* Ironlake */
+/* Ironlake / Sandybridge */
 /* as we calculate clock using (register_value + 2) for
    N/M1/M2, so here the range value for them is (actual_value-2).
  */
@@ -690,7 +691,7 @@ static const intel_limit_t *intel_limit(
 	struct drm_device *dev = crtc->dev;
 	const intel_limit_t *limit;
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		limit = intel_ironlake_limit(crtc);
 	else if (IS_G4X(dev)) {
 		limit = intel_g4x_limit(crtc);
@@ -746,16 +747,16 @@ bool intel_pipe_has_type (struct drm_crt
     list_for_each_entry(l_entry, &mode_config->connector_list, head) {
 	    if (l_entry->encoder &&
 	        l_entry->encoder->crtc == crtc) {
-		    struct intel_output *intel_output = to_intel_output(l_entry);
-		    if (intel_output->type == type)
+		    struct intel_encoder *intel_encoder = to_intel_encoder(l_entry);
+		    if (intel_encoder->type == type)
 			    return true;
 	    }
     }
     return false;
 }
 
-struct drm_connector *
-intel_pipe_get_output (struct drm_crtc *crtc)
+static struct drm_connector *
+intel_pipe_get_connector (struct drm_crtc *crtc)
 {
     struct drm_device *dev = crtc->dev;
     struct drm_mode_config *mode_config = &dev->mode_config;
@@ -886,7 +887,7 @@ intel_g4x_find_best_PLL(const intel_limi
 	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
 		int lvds_reg;
 
-		if (IS_IRONLAKE(dev))
+		if (HAS_PCH_SPLIT(dev))
 			lvds_reg = PCH_LVDS;
 		else
 			lvds_reg = LVDS;
@@ -1002,7 +1003,7 @@ static void i8xx_enable_fbc(struct drm_c
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_framebuffer *fb = crtc->fb;
 	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
-	struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	int plane, i;
 	u32 fbc_ctl, fbc_ctl2;
@@ -1032,7 +1033,7 @@ static void i8xx_enable_fbc(struct drm_c
 	/* enable it... */
 	fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC;
 	if (IS_I945GM(dev))
-		fbc_ctl |= FBC_C3_IDLE; /* 945 needs special SR handling */
+		fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */
 	fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT;
 	fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
 	if (obj_priv->tiling_mode != I915_TILING_NONE)
@@ -1079,7 +1080,7 @@ static void g4x_enable_fbc(struct drm_cr
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_framebuffer *fb = crtc->fb;
 	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
-	struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA :
 		     DPFC_CTL_PLANEB);
@@ -1175,7 +1176,7 @@ static void intel_update_fbc(struct drm_
 		return;
 
 	intel_fb = to_intel_framebuffer(fb);
-	obj_priv = intel_fb->obj->driver_private;
+	obj_priv = to_intel_bo(intel_fb->obj);
 
 	/*
 	 * If FBC is already on, we just have to verify that we can
@@ -1188,25 +1189,30 @@ static void intel_update_fbc(struct drm_
 	if (intel_fb->obj->size > dev_priv->cfb_size) {
 		DRM_DEBUG_KMS("framebuffer too large, disabling "
 				"compression\n");
+		dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL;
 		goto out_disable;
 	}
 	if ((mode->flags & DRM_MODE_FLAG_INTERLACE) ||
 	    (mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
 		DRM_DEBUG_KMS("mode incompatible with compression, "
 				"disabling\n");
+		dev_priv->no_fbc_reason = FBC_UNSUPPORTED_MODE;
 		goto out_disable;
 	}
 	if ((mode->hdisplay > 2048) ||
 	    (mode->vdisplay > 1536)) {
 		DRM_DEBUG_KMS("mode too large for compression, disabling\n");
+		dev_priv->no_fbc_reason = FBC_MODE_TOO_LARGE;
 		goto out_disable;
 	}
 	if ((IS_I915GM(dev) || IS_I945GM(dev)) && plane != 0) {
 		DRM_DEBUG_KMS("plane not 0, disabling compression\n");
+		dev_priv->no_fbc_reason = FBC_BAD_PLANE;
 		goto out_disable;
 	}
 	if (obj_priv->tiling_mode != I915_TILING_X) {
 		DRM_DEBUG_KMS("framebuffer not tiled, disabling compression\n");
+		dev_priv->no_fbc_reason = FBC_NOT_TILED;
 		goto out_disable;
 	}
 
@@ -1237,7 +1243,7 @@ out_disable:
 static int
 intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
 {
-	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 	u32 alignment;
 	int ret;
 
@@ -1317,7 +1323,7 @@ intel_pipe_set_base(struct drm_crtc *crt
 
 	intel_fb = to_intel_framebuffer(crtc->fb);
 	obj = intel_fb->obj;
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 
 	mutex_lock(&dev->struct_mutex);
 	ret = intel_pin_and_fence_fb_obj(dev, obj);
@@ -1366,7 +1372,7 @@ intel_pipe_set_base(struct drm_crtc *crt
 			dspcntr &= ~DISPPLANE_TILED;
 	}
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		/* must disable */
 		dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
 
@@ -1395,7 +1401,7 @@ intel_pipe_set_base(struct drm_crtc *crt
 
 	if (old_fb) {
 		intel_fb = to_intel_framebuffer(old_fb);
-		obj_priv = intel_fb->obj->driver_private;
+		obj_priv = to_intel_bo(intel_fb->obj);
 		i915_gem_object_unpin(intel_fb->obj);
 	}
 	intel_increase_pllclock(crtc, true);
@@ -1427,7 +1433,7 @@ static void i915_disable_vga (struct drm
 	u8 sr1;
 	u32 vga_reg;
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		vga_reg = CPU_VGACNTRL;
 	else
 		vga_reg = VGACNTRL;
@@ -2111,7 +2117,7 @@ static bool intel_crtc_mode_fixup(struct
 				  struct drm_display_mode *adjusted_mode)
 {
 	struct drm_device *dev = crtc->dev;
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		/* FDI link clock is fixed at 2.7G */
 		if (mode->clock * 3 > 27000 * 4)
 			return MODE_CLOCK_HIGH;
@@ -2757,11 +2763,22 @@ static void i9xx_update_wm(struct drm_de
 		srwm = total_size - sr_entries;
 		if (srwm < 0)
 			srwm = 1;
-		I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f));
+
+		if (IS_I945G(dev) || IS_I945GM(dev))
+			I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_FIFO_MASK | (srwm & 0xff));
+		else if (IS_I915GM(dev)) {
+			/* 915M has a smaller SRWM field */
+			I915_WRITE(FW_BLC_SELF, srwm & 0x3f);
+			I915_WRITE(INSTPM, I915_READ(INSTPM) | INSTPM_SELF_EN);
+		}
 	} else {
 		/* Turn off self refresh if both pipes are enabled */
-		I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
-					& ~FW_BLC_SELF_EN);
+		if (IS_I945G(dev) || IS_I945GM(dev)) {
+			I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
+				   & ~FW_BLC_SELF_EN);
+		} else if (IS_I915GM(dev)) {
+			I915_WRITE(INSTPM, I915_READ(INSTPM) & ~INSTPM_SELF_EN);
+		}
 	}
 
 	DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
@@ -2900,7 +2917,7 @@ static int intel_crtc_mode_set(struct dr
 	int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;
 	int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;
 	int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
-	int refclk, num_outputs = 0;
+	int refclk, num_connectors = 0;
 	intel_clock_t clock, reduced_clock;
 	u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf;
 	bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false;
@@ -2926,19 +2943,19 @@ static int intel_crtc_mode_set(struct dr
 	drm_vblank_pre_modeset(dev, pipe);
 
 	list_for_each_entry(connector, &mode_config->connector_list, head) {
-		struct intel_output *intel_output = to_intel_output(connector);
+		struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
 		if (!connector->encoder || connector->encoder->crtc != crtc)
 			continue;
 
-		switch (intel_output->type) {
+		switch (intel_encoder->type) {
 		case INTEL_OUTPUT_LVDS:
 			is_lvds = true;
 			break;
 		case INTEL_OUTPUT_SDVO:
 		case INTEL_OUTPUT_HDMI:
 			is_sdvo = true;
-			if (intel_output->needs_tv_clock)
+			if (intel_encoder->needs_tv_clock)
 				is_tv = true;
 			break;
 		case INTEL_OUTPUT_DVO:
@@ -2958,16 +2975,16 @@ static int intel_crtc_mode_set(struct dr
 			break;
 		}
 
-		num_outputs++;
+		num_connectors++;
 	}
 
-	if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) {
+	if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) {
 		refclk = dev_priv->lvds_ssc_freq * 1000;
 		DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
 					refclk / 1000);
 	} else if (IS_I9XX(dev)) {
 		refclk = 96000;
-		if (IS_IRONLAKE(dev))
+		if (HAS_PCH_SPLIT(dev))
 			refclk = 120000; /* 120Mhz refclk */
 	} else {
 		refclk = 48000;
@@ -3025,15 +3042,15 @@ static int intel_crtc_mode_set(struct dr
 	}
 
 	/* FDI link */
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		int lane, link_bw, bpp;
 		/* eDP doesn't require FDI link, so just set DP M/N
 		   according to current link config */
 		if (is_edp) {
 			struct drm_connector *edp;
 			target_clock = mode->clock;
-			edp = intel_pipe_get_output(crtc);
-			intel_edp_link_config(to_intel_output(edp),
+			edp = intel_pipe_get_connector(crtc);
+			intel_edp_link_config(to_intel_encoder(edp),
 					&lane, &link_bw);
 		} else {
 			/* DP over FDI requires target mode clock
@@ -3102,7 +3119,7 @@ static int intel_crtc_mode_set(struct dr
 	 * PCH B stepping, previous chipset stepping should be
 	 * ignoring this setting.
 	 */
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		temp = I915_READ(PCH_DREF_CONTROL);
 		/* Always enable nonspread source */
 		temp &= ~DREF_NONSPREAD_SOURCE_MASK;
@@ -3149,7 +3166,7 @@ static int intel_crtc_mode_set(struct dr
 				reduced_clock.m2;
 	}
 
-	if (!IS_IRONLAKE(dev))
+	if (!HAS_PCH_SPLIT(dev))
 		dpll = DPLL_VGA_MODE_DIS;
 
 	if (IS_I9XX(dev)) {
@@ -3162,7 +3179,7 @@ static int intel_crtc_mode_set(struct dr
 			sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
 			if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
 				dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
-			else if (IS_IRONLAKE(dev))
+			else if (HAS_PCH_SPLIT(dev))
 				dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
 		}
 		if (is_dp)
@@ -3174,7 +3191,7 @@ static int intel_crtc_mode_set(struct dr
 		else {
 			dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
 			/* also FPA1 */
-			if (IS_IRONLAKE(dev))
+			if (HAS_PCH_SPLIT(dev))
 				dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
 			if (IS_G4X(dev) && has_reduced_clock)
 				dpll |= (1 << (reduced_clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
@@ -3193,7 +3210,7 @@ static int intel_crtc_mode_set(struct dr
 			dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
 			break;
 		}
-		if (IS_I965G(dev) && !IS_IRONLAKE(dev))
+		if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev))
 			dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
 	} else {
 		if (is_lvds) {
@@ -3214,7 +3231,7 @@ static int intel_crtc_mode_set(struct dr
 		/* XXX: just matching BIOS for now */
 		/*	dpll |= PLL_REF_INPUT_TVCLKINBC; */
 		dpll |= 3;
-	else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2)
+	else if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2)
 		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
 	else
 		dpll |= PLL_REF_INPUT_DREFCLK;
@@ -3227,7 +3244,7 @@ static int intel_crtc_mode_set(struct dr
 
 	/* Ironlake's plane is forced to pipe, bit 24 is to
 	   enable color space conversion */
-	if (!IS_IRONLAKE(dev)) {
+	if (!HAS_PCH_SPLIT(dev)) {
 		if (pipe == 0)
 			dspcntr &= ~DISPPLANE_SEL_PIPE_MASK;
 		else
@@ -3254,14 +3271,14 @@ static int intel_crtc_mode_set(struct dr
 
 
 	/* Disable the panel fitter if it was on our pipe */
-	if (!IS_IRONLAKE(dev) && intel_panel_fitter_pipe(dev) == pipe)
+	if (!HAS_PCH_SPLIT(dev) && intel_panel_fitter_pipe(dev) == pipe)
 		I915_WRITE(PFIT_CONTROL, 0);
 
 	DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
 	drm_mode_debug_printmodeline(mode);
 
 	/* assign to Ironlake registers */
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		fp_reg = pch_fp_reg;
 		dpll_reg = pch_dpll_reg;
 	}
@@ -3282,7 +3299,7 @@ static int intel_crtc_mode_set(struct dr
 	if (is_lvds) {
 		u32 lvds;
 
-		if (IS_IRONLAKE(dev))
+		if (HAS_PCH_SPLIT(dev))
 			lvds_reg = PCH_LVDS;
 
 		lvds = I915_READ(lvds_reg);
@@ -3304,12 +3321,12 @@ static int intel_crtc_mode_set(struct dr
 		/* set the dithering flag */
 		if (IS_I965G(dev)) {
 			if (dev_priv->lvds_dither) {
-				if (IS_IRONLAKE(dev))
+				if (HAS_PCH_SPLIT(dev))
 					pipeconf |= PIPE_ENABLE_DITHER;
 				else
 					lvds |= LVDS_ENABLE_DITHER;
 			} else {
-				if (IS_IRONLAKE(dev))
+				if (HAS_PCH_SPLIT(dev))
 					pipeconf &= ~PIPE_ENABLE_DITHER;
 				else
 					lvds &= ~LVDS_ENABLE_DITHER;
@@ -3328,7 +3345,7 @@ static int intel_crtc_mode_set(struct dr
 		/* Wait for the clocks to stabilize. */
 		udelay(150);
 
-		if (IS_I965G(dev) && !IS_IRONLAKE(dev)) {
+		if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) {
 			if (is_sdvo) {
 				sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
 				I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
@@ -3375,14 +3392,14 @@ static int intel_crtc_mode_set(struct dr
 	/* pipesrc and dspsize control the size that is scaled from, which should
 	 * always be the user's requested size.
 	 */
-	if (!IS_IRONLAKE(dev)) {
+	if (!HAS_PCH_SPLIT(dev)) {
 		I915_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) |
 				(mode->hdisplay - 1));
 		I915_WRITE(dsppos_reg, 0);
 	}
 	I915_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
 
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		I915_WRITE(data_m1_reg, TU_SIZE(m_n.tu) | m_n.gmch_m);
 		I915_WRITE(data_n1_reg, TU_SIZE(m_n.tu) | m_n.gmch_n);
 		I915_WRITE(link_m1_reg, m_n.link_m);
@@ -3438,7 +3455,7 @@ void intel_crtc_load_lut(struct drm_crtc
 		return;
 
 	/* use legacy palette for Ironlake */
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		palreg = (intel_crtc->pipe == 0) ? LGC_PALETTE_A :
 						   LGC_PALETTE_B;
 
@@ -3494,7 +3511,7 @@ static int intel_crtc_cursor_set(struct
 	if (!bo)
 		return -ENOENT;
 
-	obj_priv = bo->driver_private;
+	obj_priv = to_intel_bo(bo);
 
 	if (bo->size < width * height * 4) {
 		DRM_ERROR("buffer is to small\n");
@@ -3553,11 +3570,10 @@ static int intel_crtc_cursor_set(struct
 	intel_crtc->cursor_bo = bo;
 
 	return 0;
-fail:
-	mutex_lock(&dev->struct_mutex);
 fail_locked:
-	drm_gem_object_unreference(bo);
 	mutex_unlock(&dev->struct_mutex);
+fail:
+	drm_gem_object_unreference_unlocked(bo);
 	return ret;
 }
 
@@ -3639,9 +3655,9 @@ static void intel_crtc_gamma_set(struct
  * detection.
  *
  * It will be up to the load-detect code to adjust the pipe as appropriate for
- * its requirements.  The pipe will be connected to no other outputs.
+ * its requirements.  The pipe will be connected to no other encoders.
  *
- * Currently this code will only succeed if there is a pipe with no outputs
+ * Currently this code will only succeed if there is a pipe with no encoders
  * configured for it.  In the future, it could choose to temporarily disable
  * some outputs to free up a pipe for its use.
  *
@@ -3654,14 +3670,14 @@ static struct drm_display_mode load_dete
 		 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 };
 
-struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
+struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
 					    struct drm_display_mode *mode,
 					    int *dpms_mode)
 {
 	struct intel_crtc *intel_crtc;
 	struct drm_crtc *possible_crtc;
 	struct drm_crtc *supported_crtc =NULL;
-	struct drm_encoder *encoder = &intel_output->enc;
+	struct drm_encoder *encoder = &intel_encoder->enc;
 	struct drm_crtc *crtc = NULL;
 	struct drm_device *dev = encoder->dev;
 	struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
@@ -3713,8 +3729,8 @@ struct drm_crtc *intel_get_load_detect_p
 	}
 
 	encoder->crtc = crtc;
-	intel_output->base.encoder = encoder;
-	intel_output->load_detect_temp = true;
+	intel_encoder->base.encoder = encoder;
+	intel_encoder->load_detect_temp = true;
 
 	intel_crtc = to_intel_crtc(crtc);
 	*dpms_mode = intel_crtc->dpms_mode;
@@ -3739,23 +3755,23 @@ struct drm_crtc *intel_get_load_detect_p
 	return crtc;
 }
 
-void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode)
+void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpms_mode)
 {
-	struct drm_encoder *encoder = &intel_output->enc;
+	struct drm_encoder *encoder = &intel_encoder->enc;
 	struct drm_device *dev = encoder->dev;
 	struct drm_crtc *crtc = encoder->crtc;
 	struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
 	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 
-	if (intel_output->load_detect_temp) {
+	if (intel_encoder->load_detect_temp) {
 		encoder->crtc = NULL;
-		intel_output->base.encoder = NULL;
-		intel_output->load_detect_temp = false;
+		intel_encoder->base.encoder = NULL;
+		intel_encoder->load_detect_temp = false;
 		crtc->enabled = drm_helper_crtc_in_use(crtc);
 		drm_helper_disable_unused_functions(dev);
 	}
 
-	/* Switch crtc and output back off if necessary */
+	/* Switch crtc and encoder back off if necessary */
 	if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) {
 		if (encoder->crtc == crtc)
 			encoder_funcs->dpms(encoder, dpms_mode);
@@ -3922,7 +3938,7 @@ static void intel_increase_pllclock(stru
 	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
 	int dpll = I915_READ(dpll_reg);
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		return;
 
 	if (!dev_priv->lvds_downclock_avail)
@@ -3961,7 +3977,7 @@ static void intel_decrease_pllclock(stru
 	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
 	int dpll = I915_READ(dpll_reg);
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		return;
 
 	if (!dev_priv->lvds_downclock_avail)
@@ -4011,6 +4027,11 @@ static void intel_idle_update(struct wor
 
 	mutex_lock(&dev->struct_mutex);
 
+	if (IS_I945G(dev) || IS_I945GM(dev)) {
+		DRM_DEBUG_DRIVER("enable memory self refresh on 945\n");
+		I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN);
+	}
+
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		/* Skip inactive CRTCs */
 		if (!crtc->fb)
@@ -4044,9 +4065,17 @@ void intel_mark_busy(struct drm_device *
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		return;
 
-	if (!dev_priv->busy)
+	if (!dev_priv->busy) {
+		if (IS_I945G(dev) || IS_I945GM(dev)) {
+			u32 fw_blc_self;
+
+			DRM_DEBUG_DRIVER("disable memory self refresh on 945\n");
+			fw_blc_self = I915_READ(FW_BLC_SELF);
+			fw_blc_self &= ~FW_BLC_SELF_EN;
+			I915_WRITE(FW_BLC_SELF, fw_blc_self | FW_BLC_SELF_EN_MASK);
+		}
 		dev_priv->busy = true;
-	else
+	} else
 		mod_timer(&dev_priv->idle_timer, jiffies +
 			  msecs_to_jiffies(GPU_IDLE_TIMEOUT));
 
@@ -4058,6 +4087,14 @@ void intel_mark_busy(struct drm_device *
 		intel_fb = to_intel_framebuffer(crtc->fb);
 		if (intel_fb->obj == obj) {
 			if (!intel_crtc->busy) {
+				if (IS_I945G(dev) || IS_I945GM(dev)) {
+					u32 fw_blc_self;
+
+					DRM_DEBUG_DRIVER("disable memory self refresh on 945\n");
+					fw_blc_self = I915_READ(FW_BLC_SELF);
+					fw_blc_self &= ~FW_BLC_SELF_EN;
+					I915_WRITE(FW_BLC_SELF, fw_blc_self | FW_BLC_SELF_EN_MASK);
+				}
 				/* Non-busy -> busy, upclock */
 				intel_increase_pllclock(crtc, true);
 				intel_crtc->busy = true;
@@ -4119,7 +4156,7 @@ void intel_finish_page_flip(struct drm_d
 	work = intel_crtc->unpin_work;
 	if (work == NULL || !work->pending) {
 		if (work && !work->pending) {
-			obj_priv = work->pending_flip_obj->driver_private;
+			obj_priv = to_intel_bo(work->pending_flip_obj);
 			DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n",
 					 obj_priv,
 					 atomic_read(&obj_priv->pending_flip));
@@ -4144,7 +4181,7 @@ void intel_finish_page_flip(struct drm_d
 
 	spin_unlock_irqrestore(&dev->event_lock, flags);
 
-	obj_priv = work->pending_flip_obj->driver_private;
+	obj_priv = to_intel_bo(work->pending_flip_obj);
 
 	/* Initial scanout buffer will have a 0 pending flip count */
 	if ((atomic_read(&obj_priv->pending_flip) == 0) ||
@@ -4215,7 +4252,7 @@ static int intel_crtc_page_flip(struct d
 	ret = intel_pin_and_fence_fb_obj(dev, obj);
 	if (ret != 0) {
 		DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
-			  obj->driver_private);
+			  to_intel_bo(obj));
 		kfree(work);
 		intel_crtc->unpin_work = NULL;
 		mutex_unlock(&dev->struct_mutex);
@@ -4229,7 +4266,7 @@ static int intel_crtc_page_flip(struct d
 	crtc->fb = fb;
 	i915_gem_object_flush_write_domain(obj);
 	drm_vblank_get(dev, intel_crtc->pipe);
-	obj_priv = obj->driver_private;
+	obj_priv = to_intel_bo(obj);
 	atomic_inc(&obj_priv->pending_flip);
 	work->pending_flip_obj = obj;
 
@@ -4362,8 +4399,8 @@ static int intel_connector_clones(struct
 	int entry = 0;
 
         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		struct intel_output *intel_output = to_intel_output(connector);
-		if (type_mask & intel_output->clone_mask)
+		struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+		if (type_mask & intel_encoder->clone_mask)
 			index_mask |= (1 << entry);
 		entry++;
 	}
@@ -4382,7 +4419,7 @@ static void intel_setup_outputs(struct d
 	if (IS_MOBILE(dev) && !IS_I830(dev))
 		intel_lvds_init(dev);
 
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		int found;
 
 		if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED))
@@ -4451,19 +4488,19 @@ static void intel_setup_outputs(struct d
 			DRM_DEBUG_KMS("probing DP_D\n");
 			intel_dp_init(dev, DP_D);
 		}
-	} else if (IS_I8XX(dev))
+	} else if (IS_GEN2(dev))
 		intel_dvo_init(dev);
 
 	if (SUPPORTS_TV(dev))
 		intel_tv_init(dev);
 
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		struct intel_output *intel_output = to_intel_output(connector);
-		struct drm_encoder *encoder = &intel_output->enc;
+		struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+		struct drm_encoder *encoder = &intel_encoder->enc;
 
-		encoder->possible_crtcs = intel_output->crtc_mask;
+		encoder->possible_crtcs = intel_encoder->crtc_mask;
 		encoder->possible_clones = intel_connector_clones(dev,
-						intel_output->clone_mask);
+						intel_encoder->clone_mask);
 	}
 }
 
@@ -4476,9 +4513,7 @@ static void intel_user_framebuffer_destr
 		intelfb_remove(dev, fb);
 
 	drm_framebuffer_cleanup(fb);
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(intel_fb->obj);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(intel_fb->obj);
 
 	kfree(intel_fb);
 }
@@ -4541,9 +4576,7 @@ intel_user_framebuffer_create(struct drm
 
 	ret = intel_framebuffer_create(dev, mode_cmd, &fb, obj);
 	if (ret) {
-		mutex_lock(&dev->struct_mutex);
-		drm_gem_object_unreference(obj);
-		mutex_unlock(&dev->struct_mutex);
+		drm_gem_object_unreference_unlocked(obj);
 		return NULL;
 	}
 
@@ -4591,6 +4624,91 @@ err_unref:
 	return NULL;
 }
 
+void ironlake_enable_drps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 rgvmodectl = I915_READ(MEMMODECTL), rgvswctl;
+	u8 fmax, fmin, fstart, vstart;
+	int i = 0;
+
+	/* 100ms RC evaluation intervals */
+	I915_WRITE(RCUPEI, 100000);
+	I915_WRITE(RCDNEI, 100000);
+
+	/* Set max/min thresholds to 90ms and 80ms respectively */
+	I915_WRITE(RCBMAXAVG, 90000);
+	I915_WRITE(RCBMINAVG, 80000);
+
+	I915_WRITE(MEMIHYST, 1);
+
+	/* Set up min, max, and cur for interrupt handling */
+	fmax = (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT;
+	fmin = (rgvmodectl & MEMMODE_FMIN_MASK);
+	fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >>
+		MEMMODE_FSTART_SHIFT;
+	vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >>
+		PXVFREQ_PX_SHIFT;
+
+	dev_priv->max_delay = fstart; /* can't go to fmax w/o IPS */
+	dev_priv->min_delay = fmin;
+	dev_priv->cur_delay = fstart;
+
+	I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN);
+
+	/*
+	 * Interrupts will be enabled in ironlake_irq_postinstall
+	 */
+
+	I915_WRITE(VIDSTART, vstart);
+	POSTING_READ(VIDSTART);
+
+	rgvmodectl |= MEMMODE_SWMODE_EN;
+	I915_WRITE(MEMMODECTL, rgvmodectl);
+
+	while (I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) {
+		if (i++ > 100) {
+			DRM_ERROR("stuck trying to change perf mode\n");
+			break;
+		}
+		msleep(1);
+	}
+	msleep(1);
+
+	rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) |
+		(fstart << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM;
+	I915_WRITE(MEMSWCTL, rgvswctl);
+	POSTING_READ(MEMSWCTL);
+
+	rgvswctl |= MEMCTL_CMD_STS;
+	I915_WRITE(MEMSWCTL, rgvswctl);
+}
+
+void ironlake_disable_drps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 rgvswctl;
+	u8 fstart;
+
+	/* Ack interrupts, disable EFC interrupt */
+	I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN);
+	I915_WRITE(MEMINTRSTS, MEMINT_EVAL_CHG);
+	I915_WRITE(DEIER, I915_READ(DEIER) & ~DE_PCU_EVENT);
+	I915_WRITE(DEIIR, DE_PCU_EVENT);
+	I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT);
+
+	/* Go back to the starting frequency */
+	fstart = (I915_READ(MEMMODECTL) & MEMMODE_FSTART_MASK) >>
+		MEMMODE_FSTART_SHIFT;
+	rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) |
+		(fstart << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM;
+	I915_WRITE(MEMSWCTL, rgvswctl);
+	msleep(1);
+	rgvswctl |= MEMCTL_CMD_STS;
+	I915_WRITE(MEMSWCTL, rgvswctl);
+	msleep(1);
+
+}
+
 void intel_init_clock_gating(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -4599,7 +4717,21 @@ void intel_init_clock_gating(struct drm_
 	 * Disable clock gating reported to work incorrectly according to the
 	 * specs, but enable as much else as we can.
 	 */
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
+		uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
+
+		if (IS_IRONLAKE(dev)) {
+			/* Required for FBC */
+			dspclk_gate |= DPFDUNIT_CLOCK_GATE_DISABLE;
+			/* Required for CxSR */
+			dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE;
+
+			I915_WRITE(PCH_3DCGDIS0,
+				   MARIUNIT_CLOCK_GATE_DISABLE |
+				   SVSMUNIT_CLOCK_GATE_DISABLE);
+		}
+
+		I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
 		return;
 	} else if (IS_G4X(dev)) {
 		uint32_t dspclk_gate;
@@ -4647,14 +4779,14 @@ void intel_init_clock_gating(struct drm_
 		struct drm_i915_gem_object *obj_priv = NULL;
 
 		if (dev_priv->pwrctx) {
-			obj_priv = dev_priv->pwrctx->driver_private;
+			obj_priv = to_intel_bo(dev_priv->pwrctx);
 		} else {
 			struct drm_gem_object *pwrctx;
 
 			pwrctx = intel_alloc_power_context(dev);
 			if (pwrctx) {
 				dev_priv->pwrctx = pwrctx;
-				obj_priv = pwrctx->driver_private;
+				obj_priv = to_intel_bo(pwrctx);
 			}
 		}
 
@@ -4672,7 +4804,7 @@ static void intel_init_display(struct dr
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	/* We always want a DPMS function */
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		dev_priv->display.dpms = ironlake_crtc_dpms;
 	else
 		dev_priv->display.dpms = i9xx_crtc_dpms;
@@ -4683,7 +4815,7 @@ static void intel_init_display(struct dr
 			dev_priv->display.fbc_enabled = g4x_fbc_enabled;
 			dev_priv->display.enable_fbc = g4x_enable_fbc;
 			dev_priv->display.disable_fbc = g4x_disable_fbc;
-		} else if (IS_I965GM(dev) || IS_I945GM(dev) || IS_I915GM(dev)) {
+		} else if (IS_I965GM(dev)) {
 			dev_priv->display.fbc_enabled = i8xx_fbc_enabled;
 			dev_priv->display.enable_fbc = i8xx_enable_fbc;
 			dev_priv->display.disable_fbc = i8xx_disable_fbc;
@@ -4715,23 +4847,24 @@ static void intel_init_display(struct dr
 			i830_get_display_clock_speed;
 
 	/* For FIFO watermark updates */
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		dev_priv->display.update_wm = NULL;
 	else if (IS_G4X(dev))
 		dev_priv->display.update_wm = g4x_update_wm;
 	else if (IS_I965G(dev))
 		dev_priv->display.update_wm = i965_update_wm;
-	else if (IS_I9XX(dev) || IS_MOBILE(dev)) {
+	else if (IS_I9XX(dev)) {
 		dev_priv->display.update_wm = i9xx_update_wm;
 		dev_priv->display.get_fifo_size = i9xx_get_fifo_size;
+	} else if (IS_I85X(dev)) {
+		dev_priv->display.update_wm = i9xx_update_wm;
+		dev_priv->display.get_fifo_size = i85x_get_fifo_size;
 	} else {
-		if (IS_I85X(dev))
-			dev_priv->display.get_fifo_size = i85x_get_fifo_size;
-		else if (IS_845G(dev))
+		dev_priv->display.update_wm = i830_update_wm;
+		if (IS_845G(dev))
 			dev_priv->display.get_fifo_size = i845_get_fifo_size;
 		else
 			dev_priv->display.get_fifo_size = i830_get_fifo_size;
-		dev_priv->display.update_wm = i830_update_wm;
 	}
 }
 
@@ -4774,11 +4907,6 @@ void intel_modeset_init(struct drm_devic
 	DRM_DEBUG_KMS("%d display pipe%s available.\n",
 		  num_pipe, num_pipe > 1 ? "s" : "");
 
-	if (IS_I85X(dev))
-		pci_read_config_word(dev->pdev, HPLLCC, &dev_priv->orig_clock);
-	else if (IS_I9XX(dev) || IS_G4X(dev))
-		pci_read_config_word(dev->pdev, GCFGC, &dev_priv->orig_clock);
-
 	for (i = 0; i < num_pipe; i++) {
 		intel_crtc_init(dev, i);
 	}
@@ -4787,6 +4915,9 @@ void intel_modeset_init(struct drm_devic
 
 	intel_init_clock_gating(dev);
 
+	if (IS_IRONLAKE_M(dev))
+		ironlake_enable_drps(dev);
+
 	INIT_WORK(&dev_priv->idle_work, intel_idle_update);
 	setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
 		    (unsigned long)dev);
@@ -4827,13 +4958,16 @@ void intel_modeset_cleanup(struct drm_de
 	if (dev_priv->pwrctx) {
 		struct drm_i915_gem_object *obj_priv;
 
-		obj_priv = dev_priv->pwrctx->driver_private;
+		obj_priv = to_intel_bo(dev_priv->pwrctx);
 		I915_WRITE(PWRCTXA, obj_priv->gtt_offset &~ PWRCTX_EN);
 		I915_READ(PWRCTXA);
 		i915_gem_object_unpin(dev_priv->pwrctx);
 		drm_gem_object_unreference(dev_priv->pwrctx);
 	}
 
+	if (IS_IRONLAKE_M(dev))
+		ironlake_disable_drps(dev);
+
 	mutex_unlock(&dev->struct_mutex);
 
 	drm_mode_config_cleanup(dev);
@@ -4845,9 +4979,9 @@ void intel_modeset_cleanup(struct drm_de
 */
 struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-	return &intel_output->enc;
+	return &intel_encoder->enc;
 }
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_dp.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_dp.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_dp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_dp.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc.h"
@@ -54,23 +55,23 @@ struct intel_dp_priv {
 	uint8_t link_bw;
 	uint8_t lane_count;
 	uint8_t dpcd[4];
-	struct intel_output *intel_output;
+	struct intel_encoder *intel_encoder;
 	struct i2c_adapter adapter;
 	struct i2c_algo_dp_aux_data algo;
 };
 
 static void
-intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
+intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
 		    uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]);
 
 static void
-intel_dp_link_down(struct intel_output *intel_output, uint32_t DP);
+intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP);
 
 void
-intel_edp_link_config (struct intel_output *intel_output,
+intel_edp_link_config (struct intel_encoder *intel_encoder,
 		int *lane_num, int *link_bw)
 {
-	struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+	struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
 
 	*lane_num = dp_priv->lane_count;
 	if (dp_priv->link_bw == DP_LINK_BW_1_62)
@@ -80,9 +81,9 @@ intel_edp_link_config (struct intel_outp
 }
 
 static int
-intel_dp_max_lane_count(struct intel_output *intel_output)
+intel_dp_max_lane_count(struct intel_encoder *intel_encoder)
 {
-	struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+	struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
 	int max_lane_count = 4;
 
 	if (dp_priv->dpcd[0] >= 0x11) {
@@ -98,9 +99,9 @@ intel_dp_max_lane_count(struct intel_out
 }
 
 static int
-intel_dp_max_link_bw(struct intel_output *intel_output)
+intel_dp_max_link_bw(struct intel_encoder *intel_encoder)
 {
-	struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+	struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
 	int max_link_bw = dp_priv->dpcd[1];
 
 	switch (max_link_bw) {
@@ -126,11 +127,11 @@ intel_dp_link_clock(uint8_t link_bw)
 /* I think this is a fiction */
 static int
 intel_dp_link_required(struct drm_device *dev,
-		       struct intel_output *intel_output, int pixel_clock)
+		       struct intel_encoder *intel_encoder, int pixel_clock)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (IS_eDP(intel_output))
+	if (IS_eDP(intel_encoder))
 		return (pixel_clock * dev_priv->edp_bpp) / 8;
 	else
 		return pixel_clock * 3;
@@ -140,11 +141,11 @@ static int
 intel_dp_mode_valid(struct drm_connector *connector,
 		    struct drm_display_mode *mode)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output));
-	int max_lanes = intel_dp_max_lane_count(intel_output);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder));
+	int max_lanes = intel_dp_max_lane_count(intel_encoder);
 
-	if (intel_dp_link_required(connector->dev, intel_output, mode->clock)
+	if (intel_dp_link_required(connector->dev, intel_encoder, mode->clock)
 			> max_link_clock * max_lanes)
 		return MODE_CLOCK_HIGH;
 
@@ -208,13 +209,13 @@ intel_hrawclk(struct drm_device *dev)
 }
 
 static int
-intel_dp_aux_ch(struct intel_output *intel_output,
+intel_dp_aux_ch(struct intel_encoder *intel_encoder,
 		uint8_t *send, int send_bytes,
 		uint8_t *recv, int recv_size)
 {
-	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 	uint32_t output_reg = dp_priv->output_reg;
-	struct drm_device *dev = intel_output->base.dev;
+	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t ch_ctl = output_reg + 0x10;
 	uint32_t ch_data = ch_ctl + 4;
@@ -229,9 +230,9 @@ intel_dp_aux_ch(struct intel_output *int
 	 * and would like to run at 2MHz. So, take the
 	 * hrawclk value and divide by 2 and use that
 	 */
-	if (IS_eDP(intel_output))
+	if (IS_eDP(intel_encoder))
 		aux_clock_divider = 225; /* eDP input clock at 450Mhz */
-	else if (IS_IRONLAKE(dev))
+	else if (HAS_PCH_SPLIT(dev))
 		aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */
 	else
 		aux_clock_divider = intel_hrawclk(dev) / 2;
@@ -312,7 +313,7 @@ intel_dp_aux_ch(struct intel_output *int
 
 /* Write data to the aux channel in native mode */
 static int
-intel_dp_aux_native_write(struct intel_output *intel_output,
+intel_dp_aux_native_write(struct intel_encoder *intel_encoder,
 			  uint16_t address, uint8_t *send, int send_bytes)
 {
 	int ret;
@@ -329,7 +330,7 @@ intel_dp_aux_native_write(struct intel_o
 	memcpy(&msg[4], send, send_bytes);
 	msg_bytes = send_bytes + 4;
 	for (;;) {
-		ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, &ack, 1);
+		ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1);
 		if (ret < 0)
 			return ret;
 		if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
@@ -344,15 +345,15 @@ intel_dp_aux_native_write(struct intel_o
 
 /* Write a single byte to the aux channel in native mode */
 static int
-intel_dp_aux_native_write_1(struct intel_output *intel_output,
+intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder,
 			    uint16_t address, uint8_t byte)
 {
-	return intel_dp_aux_native_write(intel_output, address, &byte, 1);
+	return intel_dp_aux_native_write(intel_encoder, address, &byte, 1);
 }
 
 /* read bytes from a native aux channel */
 static int
-intel_dp_aux_native_read(struct intel_output *intel_output,
+intel_dp_aux_native_read(struct intel_encoder *intel_encoder,
 			 uint16_t address, uint8_t *recv, int recv_bytes)
 {
 	uint8_t msg[4];
@@ -371,7 +372,7 @@ intel_dp_aux_native_read(struct intel_ou
 	reply_bytes = recv_bytes + 1;
 
 	for (;;) {
-		ret = intel_dp_aux_ch(intel_output, msg, msg_bytes,
+		ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes,
 				      reply, reply_bytes);
 		if (ret == 0)
 			return -EPROTO;
@@ -397,7 +398,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *
 	struct intel_dp_priv *dp_priv = container_of(adapter,
 						     struct intel_dp_priv,
 						     adapter);
-	struct intel_output *intel_output = dp_priv->intel_output;
+	struct intel_encoder *intel_encoder = dp_priv->intel_encoder;
 	uint16_t address = algo_data->address;
 	uint8_t msg[5];
 	uint8_t reply[2];
@@ -436,7 +437,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *
 	}
 
 	for (;;) {
-	  ret = intel_dp_aux_ch(intel_output,
+	  ret = intel_dp_aux_ch(intel_encoder,
 				msg, msg_bytes,
 				reply, reply_bytes);
 		if (ret < 0) {
@@ -464,9 +465,9 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *
 }
 
 static int
-intel_dp_i2c_init(struct intel_output *intel_output, const char *name)
+intel_dp_i2c_init(struct intel_encoder *intel_encoder, const char *name)
 {
-	struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+	struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
 
 	DRM_DEBUG_KMS("i2c_init %s\n", name);
 	dp_priv->algo.running = false;
@@ -479,7 +480,7 @@ intel_dp_i2c_init(struct intel_output *i
 	strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1);
 	dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0';
 	dp_priv->adapter.algo_data = &dp_priv->algo;
-	dp_priv->adapter.dev.parent = &intel_output->base.kdev;
+	dp_priv->adapter.dev.parent = &intel_encoder->base.kdev;
 	
 	return i2c_dp_aux_add_bus(&dp_priv->adapter);
 }
@@ -488,18 +489,18 @@ static bool
 intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
 		    struct drm_display_mode *adjusted_mode)
 {
-	struct intel_output *intel_output = enc_to_intel_output(encoder);
-	struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
 	int lane_count, clock;
-	int max_lane_count = intel_dp_max_lane_count(intel_output);
-	int max_clock = intel_dp_max_link_bw(intel_output) == DP_LINK_BW_2_7 ? 1 : 0;
+	int max_lane_count = intel_dp_max_lane_count(intel_encoder);
+	int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0;
 	static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
 	for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
 		for (clock = 0; clock <= max_clock; clock++) {
 			int link_avail = intel_dp_link_clock(bws[clock]) * lane_count;
 
-			if (intel_dp_link_required(encoder->dev, intel_output, mode->clock)
+			if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock)
 					<= link_avail) {
 				dp_priv->link_bw = bws[clock];
 				dp_priv->lane_count = lane_count;
@@ -561,16 +562,16 @@ intel_dp_set_m_n(struct drm_crtc *crtc,
 	struct intel_dp_m_n m_n;
 
 	/*
-	 * Find the lane count in the intel_output private
+	 * Find the lane count in the intel_encoder private
 	 */
 	list_for_each_entry(connector, &mode_config->connector_list, head) {
-		struct intel_output *intel_output = to_intel_output(connector);
-		struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+		struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+		struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
 		if (!connector->encoder || connector->encoder->crtc != crtc)
 			continue;
 
-		if (intel_output->type == INTEL_OUTPUT_DISPLAYPORT) {
+		if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
 			lane_count = dp_priv->lane_count;
 			break;
 		}
@@ -584,7 +585,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc,
 	intel_dp_compute_m_n(3, lane_count,
 			     mode->clock, adjusted_mode->clock, &m_n);
 
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		if (intel_crtc->pipe == 0) {
 			I915_WRITE(TRANSA_DATA_M1,
 				   ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) |
@@ -625,9 +626,9 @@ static void
 intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
 		  struct drm_display_mode *adjusted_mode)
 {
-	struct intel_output *intel_output = enc_to_intel_output(encoder);
-	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
-	struct drm_crtc *crtc = intel_output->enc.crtc;
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+	struct drm_crtc *crtc = intel_encoder->enc.crtc;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
 	dp_priv->DP = (DP_LINK_TRAIN_OFF |
@@ -666,7 +667,7 @@ intel_dp_mode_set(struct drm_encoder *en
 	if (intel_crtc->pipe == 1)
 		dp_priv->DP |= DP_PIPEB_SELECT;
 
-	if (IS_eDP(intel_output)) {
+	if (IS_eDP(intel_encoder)) {
 		/* don't miss out required setting for eDP */
 		dp_priv->DP |= DP_PLL_ENABLE;
 		if (adjusted_mode->clock < 200000)
@@ -701,22 +702,22 @@ static void ironlake_edp_backlight_off (
 static void
 intel_dp_dpms(struct drm_encoder *encoder, int mode)
 {
-	struct intel_output *intel_output = enc_to_intel_output(encoder);
-	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
-	struct drm_device *dev = intel_output->base.dev;
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t dp_reg = I915_READ(dp_priv->output_reg);
 
 	if (mode != DRM_MODE_DPMS_ON) {
 		if (dp_reg & DP_PORT_EN) {
-			intel_dp_link_down(intel_output, dp_priv->DP);
-			if (IS_eDP(intel_output))
+			intel_dp_link_down(intel_encoder, dp_priv->DP);
+			if (IS_eDP(intel_encoder))
 				ironlake_edp_backlight_off(dev);
 		}
 	} else {
 		if (!(dp_reg & DP_PORT_EN)) {
-			intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
-			if (IS_eDP(intel_output))
+			intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
+			if (IS_eDP(intel_encoder))
 				ironlake_edp_backlight_on(dev);
 		}
 	}
@@ -728,12 +729,12 @@ intel_dp_dpms(struct drm_encoder *encode
  * link status information
  */
 static bool
-intel_dp_get_link_status(struct intel_output *intel_output,
+intel_dp_get_link_status(struct intel_encoder *intel_encoder,
 			 uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
 	int ret;
 
-	ret = intel_dp_aux_native_read(intel_output,
+	ret = intel_dp_aux_native_read(intel_encoder,
 				       DP_LANE0_1_STATUS,
 				       link_status, DP_LINK_STATUS_SIZE);
 	if (ret != DP_LINK_STATUS_SIZE)
@@ -751,13 +752,13 @@ intel_dp_link_status(uint8_t link_status
 static void
 intel_dp_save(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct drm_device *dev = intel_output->base.dev;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
 	dp_priv->save_DP = I915_READ(dp_priv->output_reg);
-	intel_dp_aux_native_read(intel_output, DP_LINK_BW_SET,
+	intel_dp_aux_native_read(intel_encoder, DP_LINK_BW_SET,
 				 dp_priv->save_link_configuration,
 				 sizeof (dp_priv->save_link_configuration));
 }
@@ -824,7 +825,7 @@ intel_dp_pre_emphasis_max(uint8_t voltag
 }
 
 static void
-intel_get_adjust_train(struct intel_output *intel_output,
+intel_get_adjust_train(struct intel_encoder *intel_encoder,
 		       uint8_t link_status[DP_LINK_STATUS_SIZE],
 		       int lane_count,
 		       uint8_t train_set[4])
@@ -941,15 +942,15 @@ intel_channel_eq_ok(uint8_t link_status[
 }
 
 static bool
-intel_dp_set_link_train(struct intel_output *intel_output,
+intel_dp_set_link_train(struct intel_encoder *intel_encoder,
 			uint32_t dp_reg_value,
 			uint8_t dp_train_pat,
 			uint8_t train_set[4],
 			bool first)
 {
-	struct drm_device *dev = intel_output->base.dev;
+	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 	int ret;
 
 	I915_WRITE(dp_priv->output_reg, dp_reg_value);
@@ -957,11 +958,11 @@ intel_dp_set_link_train(struct intel_out
 	if (first)
 		intel_wait_for_vblank(dev);
 
-	intel_dp_aux_native_write_1(intel_output,
+	intel_dp_aux_native_write_1(intel_encoder,
 				    DP_TRAINING_PATTERN_SET,
 				    dp_train_pat);
 
-	ret = intel_dp_aux_native_write(intel_output,
+	ret = intel_dp_aux_native_write(intel_encoder,
 					DP_TRAINING_LANE0_SET, train_set, 4);
 	if (ret != 4)
 		return false;
@@ -970,12 +971,12 @@ intel_dp_set_link_train(struct intel_out
 }
 
 static void
-intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
+intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
 		    uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE])
 {
-	struct drm_device *dev = intel_output->base.dev;
+	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 	uint8_t	train_set[4];
 	uint8_t link_status[DP_LINK_STATUS_SIZE];
 	int i;
@@ -986,7 +987,7 @@ intel_dp_link_train(struct intel_output
 	int tries;
 
 	/* Write the link configuration data */
-	intel_dp_aux_native_write(intel_output, 0x100,
+	intel_dp_aux_native_write(intel_encoder, 0x100,
 				  link_configuration, DP_LINK_CONFIGURATION_SIZE);
 
 	DP |= DP_PORT_EN;
@@ -1000,14 +1001,14 @@ intel_dp_link_train(struct intel_output
 		uint32_t    signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count);
 		DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
 
-		if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_1,
+		if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_1,
 					     DP_TRAINING_PATTERN_1, train_set, first))
 			break;
 		first = false;
 		/* Set training pattern 1 */
 
 		udelay(100);
-		if (!intel_dp_get_link_status(intel_output, link_status))
+		if (!intel_dp_get_link_status(intel_encoder, link_status))
 			break;
 
 		if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) {
@@ -1032,7 +1033,7 @@ intel_dp_link_train(struct intel_output
 		voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
 		/* Compute new train_set as requested by target */
-		intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set);
+		intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
 	}
 
 	/* channel equalization */
@@ -1044,13 +1045,13 @@ intel_dp_link_train(struct intel_output
 		DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
 
 		/* channel eq pattern */
-		if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_2,
+		if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_2,
 					     DP_TRAINING_PATTERN_2, train_set,
 					     false))
 			break;
 
 		udelay(400);
-		if (!intel_dp_get_link_status(intel_output, link_status))
+		if (!intel_dp_get_link_status(intel_encoder, link_status))
 			break;
 
 		if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) {
@@ -1063,26 +1064,26 @@ intel_dp_link_train(struct intel_output
 			break;
 
 		/* Compute new train_set as requested by target */
-		intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set);
+		intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
 		++tries;
 	}
 
 	I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF);
 	POSTING_READ(dp_priv->output_reg);
-	intel_dp_aux_native_write_1(intel_output,
+	intel_dp_aux_native_write_1(intel_encoder,
 				    DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE);
 }
 
 static void
-intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
+intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP)
 {
-	struct drm_device *dev = intel_output->base.dev;
+	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
 	DRM_DEBUG_KMS("\n");
 
-	if (IS_eDP(intel_output)) {
+	if (IS_eDP(intel_encoder)) {
 		DP &= ~DP_PLL_ENABLE;
 		I915_WRITE(dp_priv->output_reg, DP);
 		POSTING_READ(dp_priv->output_reg);
@@ -1095,7 +1096,7 @@ intel_dp_link_down(struct intel_output *
 
 	udelay(17000);
 
-	if (IS_eDP(intel_output))
+	if (IS_eDP(intel_encoder))
 		DP |= DP_LINK_TRAIN_OFF;
 	I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN);
 	POSTING_READ(dp_priv->output_reg);
@@ -1104,13 +1105,13 @@ intel_dp_link_down(struct intel_output *
 static void
 intel_dp_restore(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
 	if (dp_priv->save_DP & DP_PORT_EN)
-		intel_dp_link_train(intel_output, dp_priv->save_DP, dp_priv->save_link_configuration);
+		intel_dp_link_train(intel_encoder, dp_priv->save_DP, dp_priv->save_link_configuration);
 	else
-		intel_dp_link_down(intel_output,  dp_priv->save_DP);
+		intel_dp_link_down(intel_encoder,  dp_priv->save_DP);
 }
 
 /*
@@ -1123,32 +1124,32 @@ intel_dp_restore(struct drm_connector *c
  */
 
 static void
-intel_dp_check_link_status(struct intel_output *intel_output)
+intel_dp_check_link_status(struct intel_encoder *intel_encoder)
 {
-	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 	uint8_t link_status[DP_LINK_STATUS_SIZE];
 
-	if (!intel_output->enc.crtc)
+	if (!intel_encoder->enc.crtc)
 		return;
 
-	if (!intel_dp_get_link_status(intel_output, link_status)) {
-		intel_dp_link_down(intel_output, dp_priv->DP);
+	if (!intel_dp_get_link_status(intel_encoder, link_status)) {
+		intel_dp_link_down(intel_encoder, dp_priv->DP);
 		return;
 	}
 
 	if (!intel_channel_eq_ok(link_status, dp_priv->lane_count))
-		intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
+		intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
 }
 
 static enum drm_connector_status
 ironlake_dp_detect(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 	enum drm_connector_status status;
 
 	status = connector_status_disconnected;
-	if (intel_dp_aux_native_read(intel_output,
+	if (intel_dp_aux_native_read(intel_encoder,
 				     0x000, dp_priv->dpcd,
 				     sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
 	{
@@ -1167,16 +1168,16 @@ ironlake_dp_detect(struct drm_connector
 static enum drm_connector_status
 intel_dp_detect(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct drm_device *dev = intel_output->base.dev;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 	uint32_t temp, bit;
 	enum drm_connector_status status;
 
 	dp_priv->has_audio = false;
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		return ironlake_dp_detect(connector);
 
 	temp = I915_READ(PORT_HOTPLUG_EN);
@@ -1209,7 +1210,7 @@ intel_dp_detect(struct drm_connector *co
 		return connector_status_disconnected;
 
 	status = connector_status_disconnected;
-	if (intel_dp_aux_native_read(intel_output,
+	if (intel_dp_aux_native_read(intel_encoder,
 				     0x000, dp_priv->dpcd,
 				     sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
 	{
@@ -1221,20 +1222,20 @@ intel_dp_detect(struct drm_connector *co
 
 static int intel_dp_get_modes(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct drm_device *dev = intel_output->base.dev;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int ret;
 
 	/* We should parse the EDID data and find out if it has an audio sink
 	 */
 
-	ret = intel_ddc_get_modes(intel_output);
+	ret = intel_ddc_get_modes(intel_encoder);
 	if (ret)
 		return ret;
 
 	/* if eDP has no EDID, try to use fixed panel mode from VBT */
-	if (IS_eDP(intel_output)) {
+	if (IS_eDP(intel_encoder)) {
 		if (dev_priv->panel_fixed_mode != NULL) {
 			struct drm_display_mode *mode;
 			mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
@@ -1248,13 +1249,13 @@ static int intel_dp_get_modes(struct drm
 static void
 intel_dp_destroy (struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-	if (intel_output->i2c_bus)
-		intel_i2c_destroy(intel_output->i2c_bus);
+	if (intel_encoder->i2c_bus)
+		intel_i2c_destroy(intel_encoder->i2c_bus);
 	drm_sysfs_connector_remove(connector);
 	drm_connector_cleanup(connector);
-	kfree(intel_output);
+	kfree(intel_encoder);
 }
 
 static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
@@ -1290,12 +1291,12 @@ static const struct drm_encoder_funcs in
 };
 
 void
-intel_dp_hot_plug(struct intel_output *intel_output)
+intel_dp_hot_plug(struct intel_encoder *intel_encoder)
 {
-	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
 	if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON)
-		intel_dp_check_link_status(intel_output);
+		intel_dp_check_link_status(intel_encoder);
 }
 
 void
@@ -1303,53 +1304,53 @@ intel_dp_init(struct drm_device *dev, in
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_connector *connector;
-	struct intel_output *intel_output;
+	struct intel_encoder *intel_encoder;
 	struct intel_dp_priv *dp_priv;
 	const char *name = NULL;
 
-	intel_output = kcalloc(sizeof(struct intel_output) + 
+	intel_encoder = kcalloc(sizeof(struct intel_encoder) +
 			       sizeof(struct intel_dp_priv), 1, GFP_KERNEL);
-	if (!intel_output)
+	if (!intel_encoder)
 		return;
 
-	dp_priv = (struct intel_dp_priv *)(intel_output + 1);
+	dp_priv = (struct intel_dp_priv *)(intel_encoder + 1);
 
-	connector = &intel_output->base;
+	connector = &intel_encoder->base;
 	drm_connector_init(dev, connector, &intel_dp_connector_funcs,
 			   DRM_MODE_CONNECTOR_DisplayPort);
 	drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
 
 	if (output_reg == DP_A)
-		intel_output->type = INTEL_OUTPUT_EDP;
+		intel_encoder->type = INTEL_OUTPUT_EDP;
 	else
-		intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
+		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
 
 	if (output_reg == DP_B || output_reg == PCH_DP_B)
-		intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
+		intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
 	else if (output_reg == DP_C || output_reg == PCH_DP_C)
-		intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
+		intel_encoder->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
 	else if (output_reg == DP_D || output_reg == PCH_DP_D)
-		intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
+		intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
 
-	if (IS_eDP(intel_output))
-		intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
+	if (IS_eDP(intel_encoder))
+		intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
 
-	intel_output->crtc_mask = (1 << 0) | (1 << 1);
+	intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
 	connector->interlace_allowed = true;
 	connector->doublescan_allowed = 0;
 
-	dp_priv->intel_output = intel_output;
+	dp_priv->intel_encoder = intel_encoder;
 	dp_priv->output_reg = output_reg;
 	dp_priv->has_audio = false;
 	dp_priv->dpms_mode = DRM_MODE_DPMS_ON;
-	intel_output->dev_priv = dp_priv;
+	intel_encoder->dev_priv = dp_priv;
 
-	drm_encoder_init(dev, &intel_output->enc, &intel_dp_enc_funcs,
+	drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs,
 			 DRM_MODE_ENCODER_TMDS);
-	drm_encoder_helper_add(&intel_output->enc, &intel_dp_helper_funcs);
+	drm_encoder_helper_add(&intel_encoder->enc, &intel_dp_helper_funcs);
 
-	drm_mode_connector_attach_encoder(&intel_output->base,
-					  &intel_output->enc);
+	drm_mode_connector_attach_encoder(&intel_encoder->base,
+					  &intel_encoder->enc);
 	drm_sysfs_connector_add(connector);
 
 	/* Set up the DDC bus. */
@@ -1377,10 +1378,10 @@ intel_dp_init(struct drm_device *dev, in
 			break;
 	}
 
-	intel_dp_i2c_init(intel_output, name);
+	intel_dp_i2c_init(intel_encoder, name);
 
-	intel_output->ddc_bus = &dp_priv->adapter;
-	intel_output->hot_plug = intel_dp_hot_plug;
+	intel_encoder->ddc_bus = &dp_priv->adapter;
+	intel_encoder->hot_plug = intel_dp_hot_plug;
 
 	if (output_reg == DP_A) {
 		/* initialize panel mode from VBT if available for eDP */
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_drv.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_drv.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_drv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_drv.h	2010-05-16 17:17:36.000000000 -0400
@@ -95,7 +95,7 @@ struct intel_framebuffer {
 };
 
 
-struct intel_output {
+struct intel_encoder {
 	struct drm_connector base;
 
 	struct drm_encoder enc;
@@ -105,7 +105,7 @@ struct intel_output {
 	bool load_detect_temp;
 	bool needs_tv_clock;
 	void *dev_priv;
-	void (*hot_plug)(struct intel_output *);
+	void (*hot_plug)(struct intel_encoder *);
 	int crtc_mask;
 	int clone_mask;
 };
@@ -152,15 +152,15 @@ struct intel_crtc {
 };
 
 #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
-#define to_intel_output(x) container_of(x, struct intel_output, base)
-#define enc_to_intel_output(x) container_of(x, struct intel_output, enc)
+#define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
+#define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc)
 #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
 
 struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
 				     const char *name);
 void intel_i2c_destroy(struct i2c_adapter *adapter);
-int intel_ddc_get_modes(struct intel_output *intel_output);
-extern bool intel_ddc_probe(struct intel_output *intel_output);
+int intel_ddc_get_modes(struct intel_encoder *intel_encoder);
+extern bool intel_ddc_probe(struct intel_encoder *intel_encoder);
 void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
 void intel_i2c_reset_gmbus(struct drm_device *dev);
 
@@ -175,7 +175,7 @@ extern void intel_dp_init(struct drm_dev
 void
 intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 		 struct drm_display_mode *adjusted_mode);
-extern void intel_edp_link_config (struct intel_output *, int *, int *);
+extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
 
 
 extern int intel_panel_fitter_pipe (struct drm_device *dev);
@@ -191,10 +191,10 @@ int intel_get_pipe_from_crtc_id(struct d
 				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,
+extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
 						   struct drm_display_mode *mode,
 						   int *dpms_mode);
-extern void intel_release_load_detect_pipe(struct intel_output *intel_output,
+extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
 					   int dpms_mode);
 
 extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB);
@@ -209,6 +209,8 @@ extern void intel_crtc_fb_gamma_set(stru
 extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
 				    u16 *blue, int regno);
 extern void intel_init_clock_gating(struct drm_device *dev);
+extern void ironlake_enable_drps(struct drm_device *dev);
+extern void ironlake_disable_drps(struct drm_device *dev);
 
 extern int intel_framebuffer_create(struct drm_device *dev,
 				    struct drm_mode_fb_cmd *mode_cmd,
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_dvo.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_dvo.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_dvo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_dvo.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
  *	Eric Anholt <eric@anholt.net>
  */
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc.h"
@@ -79,8 +80,8 @@ static struct intel_dvo_device intel_dvo
 static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
 {
 	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
-	struct intel_output *intel_output = enc_to_intel_output(encoder);
-	struct intel_dvo_device *dvo = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 	u32 dvo_reg = dvo->dvo_reg;
 	u32 temp = I915_READ(dvo_reg);
 
@@ -98,8 +99,8 @@ static void intel_dvo_dpms(struct drm_en
 static void intel_dvo_save(struct drm_connector *connector)
 {
 	struct drm_i915_private *dev_priv = connector->dev->dev_private;
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_dvo_device *dvo = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
 	/* Each output should probably just save the registers it touches,
 	 * but for now, use more overkill.
@@ -114,8 +115,8 @@ static void intel_dvo_save(struct drm_co
 static void intel_dvo_restore(struct drm_connector *connector)
 {
 	struct drm_i915_private *dev_priv = connector->dev->dev_private;
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_dvo_device *dvo = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
 	dvo->dev_ops->restore(dvo);
 
@@ -127,8 +128,8 @@ static void intel_dvo_restore(struct drm
 static int intel_dvo_mode_valid(struct drm_connector *connector,
 				struct drm_display_mode *mode)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_dvo_device *dvo = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
 	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 		return MODE_NO_DBLESCAN;
@@ -149,8 +150,8 @@ static bool intel_dvo_mode_fixup(struct
 				 struct drm_display_mode *mode,
 				 struct drm_display_mode *adjusted_mode)
 {
-	struct intel_output *intel_output = enc_to_intel_output(encoder);
-	struct intel_dvo_device *dvo = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
 	/* If we have timings from the BIOS for the panel, put them in
 	 * to the adjusted mode.  The CRTC will be set up for this mode,
@@ -185,8 +186,8 @@ static void intel_dvo_mode_set(struct dr
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
-	struct intel_output *intel_output = enc_to_intel_output(encoder);
-	struct intel_dvo_device *dvo = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 	int pipe = intel_crtc->pipe;
 	u32 dvo_val;
 	u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg;
@@ -240,23 +241,23 @@ static void intel_dvo_mode_set(struct dr
  */
 static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_dvo_device *dvo = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
 	return dvo->dev_ops->detect(dvo);
 }
 
 static int intel_dvo_get_modes(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_dvo_device *dvo = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
 	/* We should probably have an i2c driver get_modes function for those
 	 * devices which will have a fixed set of modes determined by the chip
 	 * (TV-out, for example), but for now with just TMDS and LVDS,
 	 * that's not the case.
 	 */
-	intel_ddc_get_modes(intel_output);
+	intel_ddc_get_modes(intel_encoder);
 	if (!list_empty(&connector->probed_modes))
 		return 1;
 
@@ -274,8 +275,8 @@ static int intel_dvo_get_modes(struct dr
 
 static void intel_dvo_destroy (struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_dvo_device *dvo = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
 	if (dvo) {
 		if (dvo->dev_ops->destroy)
@@ -285,13 +286,13 @@ static void intel_dvo_destroy (struct dr
 		/* no need, in i830_dvoices[] now */
 		//kfree(dvo);
 	}
-	if (intel_output->i2c_bus)
-		intel_i2c_destroy(intel_output->i2c_bus);
-	if (intel_output->ddc_bus)
-		intel_i2c_destroy(intel_output->ddc_bus);
+	if (intel_encoder->i2c_bus)
+		intel_i2c_destroy(intel_encoder->i2c_bus);
+	if (intel_encoder->ddc_bus)
+		intel_i2c_destroy(intel_encoder->ddc_bus);
 	drm_sysfs_connector_remove(connector);
 	drm_connector_cleanup(connector);
-	kfree(intel_output);
+	kfree(intel_encoder);
 }
 
 #ifdef RANDR_GET_CRTC_INTERFACE
@@ -299,8 +300,8 @@ static struct drm_crtc *intel_dvo_get_cr
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_dvo_device *dvo = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 	int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT);
 
 	return intel_pipe_to_crtc(pScrn, pipe);
@@ -351,8 +352,8 @@ intel_dvo_get_current_mode (struct drm_c
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_dvo_device *dvo = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 	uint32_t dvo_reg = dvo->dvo_reg;
 	uint32_t dvo_val = I915_READ(dvo_reg);
 	struct drm_display_mode *mode = NULL;
@@ -382,24 +383,24 @@ intel_dvo_get_current_mode (struct drm_c
 
 void intel_dvo_init(struct drm_device *dev)
 {
-	struct intel_output *intel_output;
+	struct intel_encoder *intel_encoder;
 	struct intel_dvo_device *dvo;
 	struct i2c_adapter *i2cbus = NULL;
 	int ret = 0;
 	int i;
 	int encoder_type = DRM_MODE_ENCODER_NONE;
-	intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL);
-	if (!intel_output)
+	intel_encoder = kzalloc (sizeof(struct intel_encoder), GFP_KERNEL);
+	if (!intel_encoder)
 		return;
 
 	/* Set up the DDC bus */
-	intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
-	if (!intel_output->ddc_bus)
+	intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
+	if (!intel_encoder->ddc_bus)
 		goto free_intel;
 
 	/* Now, try to find a controller */
 	for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
-		struct drm_connector *connector = &intel_output->base;
+		struct drm_connector *connector = &intel_encoder->base;
 		int gpio;
 
 		dvo = &intel_dvo_devices[i];
@@ -434,11 +435,11 @@ void intel_dvo_init(struct drm_device *d
 		if (!ret)
 			continue;
 
-		intel_output->type = INTEL_OUTPUT_DVO;
-		intel_output->crtc_mask = (1 << 0) | (1 << 1);
+		intel_encoder->type = INTEL_OUTPUT_DVO;
+		intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
 		switch (dvo->type) {
 		case INTEL_DVO_CHIP_TMDS:
-			intel_output->clone_mask =
+			intel_encoder->clone_mask =
 				(1 << INTEL_DVO_TMDS_CLONE_BIT) |
 				(1 << INTEL_ANALOG_CLONE_BIT);
 			drm_connector_init(dev, connector,
@@ -447,7 +448,7 @@ void intel_dvo_init(struct drm_device *d
 			encoder_type = DRM_MODE_ENCODER_TMDS;
 			break;
 		case INTEL_DVO_CHIP_LVDS:
-			intel_output->clone_mask =
+			intel_encoder->clone_mask =
 				(1 << INTEL_DVO_LVDS_CLONE_BIT);
 			drm_connector_init(dev, connector,
 					   &intel_dvo_connector_funcs,
@@ -462,16 +463,16 @@ void intel_dvo_init(struct drm_device *d
 		connector->interlace_allowed = false;
 		connector->doublescan_allowed = false;
 
-		intel_output->dev_priv = dvo;
-		intel_output->i2c_bus = i2cbus;
+		intel_encoder->dev_priv = dvo;
+		intel_encoder->i2c_bus = i2cbus;
 
-		drm_encoder_init(dev, &intel_output->enc,
+		drm_encoder_init(dev, &intel_encoder->enc,
 				 &intel_dvo_enc_funcs, encoder_type);
-		drm_encoder_helper_add(&intel_output->enc,
+		drm_encoder_helper_add(&intel_encoder->enc,
 				       &intel_dvo_helper_funcs);
 
-		drm_mode_connector_attach_encoder(&intel_output->base,
-						  &intel_output->enc);
+		drm_mode_connector_attach_encoder(&intel_encoder->base,
+						  &intel_encoder->enc);
 		if (dvo->type == INTEL_DVO_CHIP_LVDS) {
 			/* For our LVDS chipsets, we should hopefully be able
 			 * to dig the fixed panel mode out of the BIOS data.
@@ -489,10 +490,10 @@ void intel_dvo_init(struct drm_device *d
 		return;
 	}
 
-	intel_i2c_destroy(intel_output->ddc_bus);
+	intel_i2c_destroy(intel_encoder->ddc_bus);
 	/* Didn't find a chip, so tear down. */
 	if (i2cbus != NULL)
 		intel_i2c_destroy(i2cbus);
 free_intel:
-	kfree(intel_output);
+	kfree(intel_encoder);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_fb.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_fb.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,11 +30,11 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/tty.h>
-#include <linux/slab.h>
 #include <linux/sysrq.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/init.h>
+#include <linux/vga_switcheroo.h>
 
 #include "drmP.h"
 #include "drm.h"
@@ -144,7 +144,7 @@ static int intelfb_create(struct drm_dev
 		ret = -ENOMEM;
 		goto out;
 	}
-	obj_priv = fbo->driver_private;
+	obj_priv = to_intel_bo(fbo);
 
 	mutex_lock(&dev->struct_mutex);
 
@@ -235,6 +235,7 @@ static int intelfb_create(struct drm_dev
 			obj_priv->gtt_offset, fbo);
 
 	mutex_unlock(&dev->struct_mutex);
+	vga_switcheroo_client_fb_set(dev->pdev, info);
 	return 0;
 
 out_unpin:
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_hdmi.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_hdmi.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_hdmi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_hdmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include "drmP.h"
 #include "drm.h"
@@ -50,8 +51,8 @@ static void intel_hdmi_mode_set(struct d
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc = encoder->crtc;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct intel_output *intel_output = enc_to_intel_output(encoder);
-	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
 	u32 sdvox;
 
 	sdvox = SDVO_ENCODING_HDMI |
@@ -73,8 +74,8 @@ static void intel_hdmi_dpms(struct drm_e
 {
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_output *intel_output = enc_to_intel_output(encoder);
-	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
 	u32 temp;
 
 	temp = I915_READ(hdmi_priv->sdvox_reg);
@@ -82,7 +83,7 @@ static void intel_hdmi_dpms(struct drm_e
 	/* HW workaround, need to toggle enable bit off and on for 12bpc, but
 	 * we do this anyway which shows more stable in testing.
 	 */
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE);
 		POSTING_READ(hdmi_priv->sdvox_reg);
 	}
@@ -99,7 +100,7 @@ static void intel_hdmi_dpms(struct drm_e
 	/* HW workaround, need to write this twice for issue that may result
 	 * in first write getting masked.
 	 */
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		I915_WRITE(hdmi_priv->sdvox_reg, temp);
 		POSTING_READ(hdmi_priv->sdvox_reg);
 	}
@@ -109,8 +110,8 @@ static void intel_hdmi_save(struct drm_c
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
 
 	hdmi_priv->save_SDVOX = I915_READ(hdmi_priv->sdvox_reg);
 }
@@ -119,8 +120,8 @@ static void intel_hdmi_restore(struct dr
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
 
 	I915_WRITE(hdmi_priv->sdvox_reg, hdmi_priv->save_SDVOX);
 	POSTING_READ(hdmi_priv->sdvox_reg);
@@ -150,21 +151,21 @@ static bool intel_hdmi_mode_fixup(struct
 static enum drm_connector_status
 intel_hdmi_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 intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
 	struct edid *edid = NULL;
 	enum drm_connector_status status = connector_status_disconnected;
 
 	hdmi_priv->has_hdmi_sink = false;
-	edid = drm_get_edid(&intel_output->base,
-			    intel_output->ddc_bus);
+	edid = drm_get_edid(&intel_encoder->base,
+			    intel_encoder->ddc_bus);
 
 	if (edid) {
 		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
 			status = connector_status_connected;
 			hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
 		}
-		intel_output->base.display_info.raw_edid = NULL;
+		intel_encoder->base.display_info.raw_edid = NULL;
 		kfree(edid);
 	}
 
@@ -173,24 +174,24 @@ intel_hdmi_detect(struct drm_connector *
 
 static int intel_hdmi_get_modes(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
 	/* We should parse the EDID data and find out if it's an HDMI sink so
 	 * we can send audio to it.
 	 */
 
-	return intel_ddc_get_modes(intel_output);
+	return intel_ddc_get_modes(intel_encoder);
 }
 
 static void intel_hdmi_destroy(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-	if (intel_output->i2c_bus)
-		intel_i2c_destroy(intel_output->i2c_bus);
+	if (intel_encoder->i2c_bus)
+		intel_i2c_destroy(intel_encoder->i2c_bus);
 	drm_sysfs_connector_remove(connector);
 	drm_connector_cleanup(connector);
-	kfree(intel_output);
+	kfree(intel_encoder);
 }
 
 static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
@@ -229,63 +230,63 @@ void intel_hdmi_init(struct drm_device *
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_connector *connector;
-	struct intel_output *intel_output;
+	struct intel_encoder *intel_encoder;
 	struct intel_hdmi_priv *hdmi_priv;
 
-	intel_output = kcalloc(sizeof(struct intel_output) +
+	intel_encoder = kcalloc(sizeof(struct intel_encoder) +
 			       sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL);
-	if (!intel_output)
+	if (!intel_encoder)
 		return;
-	hdmi_priv = (struct intel_hdmi_priv *)(intel_output + 1);
+	hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1);
 
-	connector = &intel_output->base;
+	connector = &intel_encoder->base;
 	drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
 			   DRM_MODE_CONNECTOR_HDMIA);
 	drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
 
-	intel_output->type = INTEL_OUTPUT_HDMI;
+	intel_encoder->type = INTEL_OUTPUT_HDMI;
 
 	connector->interlace_allowed = 0;
 	connector->doublescan_allowed = 0;
-	intel_output->crtc_mask = (1 << 0) | (1 << 1);
+	intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
 
 	/* Set up the DDC bus. */
 	if (sdvox_reg == SDVOB) {
-		intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
-		intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
+		intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
+		intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
 		dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
 	} else if (sdvox_reg == SDVOC) {
-		intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
-		intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
+		intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
+		intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
 		dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
 	} else if (sdvox_reg == HDMIB) {
-		intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
-		intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
+		intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
+		intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
 								"HDMIB");
 		dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
 	} else if (sdvox_reg == HDMIC) {
-		intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
-		intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
+		intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
+		intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
 								"HDMIC");
 		dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
 	} else if (sdvox_reg == HDMID) {
-		intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
-		intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
+		intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
+		intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
 								"HDMID");
 		dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
 	}
-	if (!intel_output->ddc_bus)
+	if (!intel_encoder->ddc_bus)
 		goto err_connector;
 
 	hdmi_priv->sdvox_reg = sdvox_reg;
-	intel_output->dev_priv = hdmi_priv;
+	intel_encoder->dev_priv = hdmi_priv;
 
-	drm_encoder_init(dev, &intel_output->enc, &intel_hdmi_enc_funcs,
+	drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs,
 			 DRM_MODE_ENCODER_TMDS);
-	drm_encoder_helper_add(&intel_output->enc, &intel_hdmi_helper_funcs);
+	drm_encoder_helper_add(&intel_encoder->enc, &intel_hdmi_helper_funcs);
 
-	drm_mode_connector_attach_encoder(&intel_output->base,
-					  &intel_output->enc);
+	drm_mode_connector_attach_encoder(&intel_encoder->base,
+					  &intel_encoder->enc);
 	drm_sysfs_connector_add(connector);
 
 	/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
@@ -301,7 +302,7 @@ void intel_hdmi_init(struct drm_device *
 
 err_connector:
 	drm_connector_cleanup(connector);
-	kfree(intel_output);
+	kfree(intel_encoder);
 
 	return;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_i2c.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_i2c.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
  *	Eric Anholt <eric@anholt.net>
  */
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/i2c-id.h>
 #include <linux/i2c-algo-bit.h>
 #include "drmP.h"
@@ -128,7 +129,7 @@ intel_i2c_reset_gmbus(struct drm_device
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		I915_WRITE(PCH_GMBUS0, 0);
 	} else {
 		I915_WRITE(GMBUS0, 0);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_lvds.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_lvds.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_lvds.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_lvds.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <acpi/button.h>
 #include <linux/dmi.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc.h"
@@ -56,7 +57,7 @@ static void intel_lvds_set_backlight(str
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 blc_pwm_ctl, reg;
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		reg = BLC_PWM_CPU_CTL;
 	else
 		reg = BLC_PWM_CTL;
@@ -74,7 +75,7 @@ static u32 intel_lvds_get_max_backlight(
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 reg;
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		reg = BLC_PWM_PCH_CTL2;
 	else
 		reg = BLC_PWM_CTL;
@@ -89,17 +90,22 @@ static u32 intel_lvds_get_max_backlight(
 static void intel_lvds_set_power(struct drm_device *dev, bool on)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 pp_status, ctl_reg, status_reg;
+	u32 pp_status, ctl_reg, status_reg, lvds_reg;
 
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		ctl_reg = PCH_PP_CONTROL;
 		status_reg = PCH_PP_STATUS;
+		lvds_reg = PCH_LVDS;
 	} else {
 		ctl_reg = PP_CONTROL;
 		status_reg = PP_STATUS;
+		lvds_reg = LVDS;
 	}
 
 	if (on) {
+		I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN);
+		POSTING_READ(lvds_reg);
+
 		I915_WRITE(ctl_reg, I915_READ(ctl_reg) |
 			   POWER_TARGET_ON);
 		do {
@@ -115,6 +121,9 @@ static void intel_lvds_set_power(struct
 		do {
 			pp_status = I915_READ(status_reg);
 		} while (pp_status & PP_ON);
+
+		I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN);
+		POSTING_READ(lvds_reg);
 	}
 }
 
@@ -137,7 +146,7 @@ static void intel_lvds_save(struct drm_c
 	u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg;
 	u32 pwm_ctl_reg;
 
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		pp_on_reg = PCH_PP_ON_DELAYS;
 		pp_off_reg = PCH_PP_OFF_DELAYS;
 		pp_ctl_reg = PCH_PP_CONTROL;
@@ -174,7 +183,7 @@ static void intel_lvds_restore(struct dr
 	u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg;
 	u32 pwm_ctl_reg;
 
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		pp_on_reg = PCH_PP_ON_DELAYS;
 		pp_off_reg = PCH_PP_OFF_DELAYS;
 		pp_ctl_reg = PCH_PP_CONTROL;
@@ -230,8 +239,8 @@ static bool intel_lvds_mode_fixup(struct
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
 	struct drm_encoder *tmp_encoder;
-	struct intel_output *intel_output = enc_to_intel_output(encoder);
-	struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
 	u32 pfit_control = 0, pfit_pgm_ratios = 0;
 	int left_border = 0, right_border = 0, top_border = 0;
 	int bottom_border = 0;
@@ -297,7 +306,7 @@ static bool intel_lvds_mode_fixup(struct
 	}
 
 	/* full screen scale for now */
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		goto out;
 
 	/* 965+ wants fuzzy fitting */
@@ -327,7 +336,7 @@ static bool intel_lvds_mode_fixup(struct
 	 * to register description and PRM.
 	 * Change the value here to see the borders for debugging
 	 */
-	if (!IS_IRONLAKE(dev)) {
+	if (!HAS_PCH_SPLIT(dev)) {
 		I915_WRITE(BCLRPAT_A, 0);
 		I915_WRITE(BCLRPAT_B, 0);
 	}
@@ -548,7 +557,7 @@ static void intel_lvds_prepare(struct dr
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 reg;
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		reg = BLC_PWM_CPU_CTL;
 	else
 		reg = BLC_PWM_CTL;
@@ -578,8 +587,8 @@ static void intel_lvds_mode_set(struct d
 {
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_output *intel_output = enc_to_intel_output(encoder);
-	struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
 
 	/*
 	 * The LVDS pin pair will already have been turned on in the
@@ -587,7 +596,7 @@ static void intel_lvds_mode_set(struct d
 	 * settings.
 	 */
 
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		return;
 
 	/*
@@ -599,53 +608,6 @@ static void intel_lvds_mode_set(struct d
 	I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control);
 }
 
-/* Some lid devices report incorrect lid status, assume they're connected */
-static const struct dmi_system_id bad_lid_status[] = {
-	{
-		.ident = "Compaq nx9020",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-			DMI_MATCH(DMI_BOARD_NAME, "3084"),
-		},
-	},
-	{
-		.ident = "Samsung SX20S",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"),
-			DMI_MATCH(DMI_BOARD_NAME, "SX20S"),
-		},
-	},
-	{
-		.ident = "Aspire One",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire one"),
-		},
-	},
-	{
-		.ident = "Aspire 1810T",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1810T"),
-		},
-	},
-	{
-		.ident = "PC-81005",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "MALATA"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"),
-		},
-	},
-	{
-		.ident = "Clevo M5x0N",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
-			DMI_MATCH(DMI_BOARD_NAME, "M5x0N"),
-		},
-	},
-	{ }
-};
-
 /**
  * Detect the LVDS connection.
  *
@@ -655,10 +617,14 @@ static const struct dmi_system_id bad_li
  */
 static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector)
 {
+	struct drm_device *dev = connector->dev;
 	enum drm_connector_status status = connector_status_connected;
 
-	if (!dmi_check_system(bad_lid_status) && !acpi_lid_open())
-		status = connector_status_disconnected;
+	/* ACPI lid methods were generally unreliable in this generation, so
+	 * don't even bother.
+	 */
+	if (IS_GEN2(dev) || IS_GEN3(dev))
+		return connector_status_connected;
 
 	return status;
 }
@@ -669,14 +635,16 @@ static enum drm_connector_status intel_l
 static int intel_lvds_get_modes(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
-	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int ret = 0;
 
-	ret = intel_ddc_get_modes(intel_output);
+	if (dev_priv->lvds_edid_good) {
+		ret = intel_ddc_get_modes(intel_encoder);
 
-	if (ret)
-		return ret;
+		if (ret)
+			return ret;
+	}
 
 	/* Didn't get an EDID, so
 	 * Set wide sync ranges so we get all modes
@@ -749,11 +717,11 @@ static int intel_lid_notify(struct notif
 static void intel_lvds_destroy(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
-	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (intel_output->ddc_bus)
-		intel_i2c_destroy(intel_output->ddc_bus);
+	if (intel_encoder->ddc_bus)
+		intel_i2c_destroy(intel_encoder->ddc_bus);
 	if (dev_priv->lid_notifier.notifier_call)
 		acpi_lid_notifier_unregister(&dev_priv->lid_notifier);
 	drm_sysfs_connector_remove(connector);
@@ -766,13 +734,13 @@ static int intel_lvds_set_property(struc
 				   uint64_t value)
 {
 	struct drm_device *dev = connector->dev;
-	struct intel_output *intel_output =
-			to_intel_output(connector);
+	struct intel_encoder *intel_encoder =
+			to_intel_encoder(connector);
 
 	if (property == dev->mode_config.scaling_mode_property &&
 				connector->encoder) {
 		struct drm_crtc *crtc = connector->encoder->crtc;
-		struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
+		struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
 		if (value == DRM_MODE_SCALE_NONE) {
 			DRM_DEBUG_KMS("no scaling not supported\n");
 			return 0;
@@ -892,6 +860,14 @@ static const struct dmi_system_id intel_
 			DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),
 		},
 	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Clientron U800",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "U800"),
+		},
+	},
 
 	{ }	/* terminating entry */
 };
@@ -1002,7 +978,7 @@ static int lvds_is_present_in_vbt(struct
 void intel_lvds_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_output *intel_output;
+	struct intel_encoder *intel_encoder;
 	struct drm_connector *connector;
 	struct drm_encoder *encoder;
 	struct drm_display_mode *scan; /* *modes, *bios_mode; */
@@ -1020,7 +996,7 @@ void intel_lvds_init(struct drm_device *
 		return;
 	}
 
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
 			return;
 		if (dev_priv->edp_support) {
@@ -1030,40 +1006,40 @@ void intel_lvds_init(struct drm_device *
 		gpio = PCH_GPIOC;
 	}
 
-	intel_output = kzalloc(sizeof(struct intel_output) +
+	intel_encoder = kzalloc(sizeof(struct intel_encoder) +
 				sizeof(struct intel_lvds_priv), GFP_KERNEL);
-	if (!intel_output) {
+	if (!intel_encoder) {
 		return;
 	}
 
-	connector = &intel_output->base;
-	encoder = &intel_output->enc;
-	drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs,
+	connector = &intel_encoder->base;
+	encoder = &intel_encoder->enc;
+	drm_connector_init(dev, &intel_encoder->base, &intel_lvds_connector_funcs,
 			   DRM_MODE_CONNECTOR_LVDS);
 
-	drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs,
+	drm_encoder_init(dev, &intel_encoder->enc, &intel_lvds_enc_funcs,
 			 DRM_MODE_ENCODER_LVDS);
 
-	drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
-	intel_output->type = INTEL_OUTPUT_LVDS;
+	drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);
+	intel_encoder->type = INTEL_OUTPUT_LVDS;
 
-	intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
-	intel_output->crtc_mask = (1 << 1);
+	intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
+	intel_encoder->crtc_mask = (1 << 1);
 	drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
 	drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
 	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 	connector->interlace_allowed = false;
 	connector->doublescan_allowed = false;
 
-	lvds_priv = (struct intel_lvds_priv *)(intel_output + 1);
-	intel_output->dev_priv = lvds_priv;
+	lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1);
+	intel_encoder->dev_priv = lvds_priv;
 	/* create the scaling mode property */
 	drm_mode_create_scaling_mode_property(dev);
 	/*
 	 * the initial panel fitting mode will be FULL_SCREEN.
 	 */
 
-	drm_connector_attach_property(&intel_output->base,
+	drm_connector_attach_property(&intel_encoder->base,
 				      dev->mode_config.scaling_mode_property,
 				      DRM_MODE_SCALE_FULLSCREEN);
 	lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN;
@@ -1078,8 +1054,8 @@ void intel_lvds_init(struct drm_device *
 	 */
 
 	/* Set up the DDC bus. */
-	intel_output->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C");
-	if (!intel_output->ddc_bus) {
+	intel_encoder->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C");
+	if (!intel_encoder->ddc_bus) {
 		dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
 			   "failed.\n");
 		goto failed;
@@ -1089,7 +1065,10 @@ void intel_lvds_init(struct drm_device *
 	 * Attempt to get the fixed panel mode from DDC.  Assume that the
 	 * preferred mode is the right one.
 	 */
-	intel_ddc_get_modes(intel_output);
+	dev_priv->lvds_edid_good = true;
+
+	if (!intel_ddc_get_modes(intel_encoder))
+		dev_priv->lvds_edid_good = false;
 
 	list_for_each_entry(scan, &connector->probed_modes, head) {
 		mutex_lock(&dev->mode_config.mutex);
@@ -1123,7 +1102,7 @@ void intel_lvds_init(struct drm_device *
 	 */
 
 	/* Ironlake: FIXME if still fail, not try pipe mode now */
-	if (IS_IRONLAKE(dev))
+	if (HAS_PCH_SPLIT(dev))
 		goto failed;
 
 	lvds = I915_READ(LVDS);
@@ -1144,7 +1123,7 @@ void intel_lvds_init(struct drm_device *
 		goto failed;
 
 out:
-	if (IS_IRONLAKE(dev)) {
+	if (HAS_PCH_SPLIT(dev)) {
 		u32 pwm;
 		/* make sure PWM is enabled */
 		pwm = I915_READ(BLC_PWM_CPU_CTL2);
@@ -1167,9 +1146,9 @@ out:
 
 failed:
 	DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
-	if (intel_output->ddc_bus)
-		intel_i2c_destroy(intel_output->ddc_bus);
+	if (intel_encoder->ddc_bus)
+		intel_i2c_destroy(intel_encoder->ddc_bus);
 	drm_connector_cleanup(connector);
 	drm_encoder_cleanup(encoder);
-	kfree(intel_output);
+	kfree(intel_encoder);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_modes.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_modes.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_modes.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_modes.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/fb.h>
 #include "drmP.h"
@@ -33,7 +34,7 @@
  * intel_ddc_probe
  *
  */
-bool intel_ddc_probe(struct intel_output *intel_output)
+bool intel_ddc_probe(struct intel_encoder *intel_encoder)
 {
 	u8 out_buf[] = { 0x0, 0x0};
 	u8 buf[2];
@@ -53,9 +54,9 @@ bool intel_ddc_probe(struct intel_output
 		}
 	};
 
-	intel_i2c_quirk_set(intel_output->base.dev, true);
-	ret = i2c_transfer(intel_output->ddc_bus, msgs, 2);
-	intel_i2c_quirk_set(intel_output->base.dev, false);
+	intel_i2c_quirk_set(intel_encoder->base.dev, true);
+	ret = i2c_transfer(intel_encoder->ddc_bus, msgs, 2);
+	intel_i2c_quirk_set(intel_encoder->base.dev, false);
 	if (ret == 2)
 		return true;
 
@@ -68,19 +69,19 @@ bool intel_ddc_probe(struct intel_output
  *
  * Fetch the EDID information from @connector using the DDC bus.
  */
-int intel_ddc_get_modes(struct intel_output *intel_output)
+int intel_ddc_get_modes(struct intel_encoder *intel_encoder)
 {
 	struct edid *edid;
 	int ret = 0;
 
-	intel_i2c_quirk_set(intel_output->base.dev, true);
-	edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus);
-	intel_i2c_quirk_set(intel_output->base.dev, false);
+	intel_i2c_quirk_set(intel_encoder->base.dev, true);
+	edid = drm_get_edid(&intel_encoder->base, intel_encoder->ddc_bus);
+	intel_i2c_quirk_set(intel_encoder->base.dev, false);
 	if (edid) {
-		drm_mode_connector_update_edid_property(&intel_output->base,
+		drm_mode_connector_update_edid_property(&intel_encoder->base,
 							edid);
-		ret = drm_add_edid_modes(&intel_output->base, edid);
-		intel_output->base.display_info.raw_edid = NULL;
+		ret = drm_add_edid_modes(&intel_encoder->base, edid);
+		intel_encoder->base.display_info.raw_edid = NULL;
 		kfree(edid);
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_overlay.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_overlay.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_overlay.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_overlay.c	2010-05-16 17:17:36.000000000 -0400
@@ -172,7 +172,7 @@ struct overlay_registers {
 #define OFC_UPDATE		0x1
 
 #define OVERLAY_NONPHYSICAL(dev) (IS_G33(dev) || IS_I965G(dev))
-#define OVERLAY_EXISTS(dev) (!IS_G4X(dev) && !IS_IRONLAKE(dev))
+#define OVERLAY_EXISTS(dev) (!IS_G4X(dev) && !IS_IRONLAKE(dev) && !IS_GEN6(dev))
 
 
 static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
@@ -199,16 +199,11 @@ static struct overlay_registers *intel_o
 
 static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay)
 {
-	struct drm_device *dev = overlay->dev;
-        drm_i915_private_t *dev_priv = dev->dev_private;
-
 	if (OVERLAY_NONPHYSICAL(overlay->dev))
 		io_mapping_unmap_atomic(overlay->virt_addr);
 
 	overlay->virt_addr = NULL;
 
-	I915_READ(OVADD); /* flush wc cashes */
-
 	return;
 }
 
@@ -225,9 +220,7 @@ static int intel_overlay_on(struct intel
 	overlay->active = 1;
 	overlay->hw_wedged = NEEDS_WAIT_FOR_FLIP;
 
-	BEGIN_LP_RING(6);
-	OUT_RING(MI_FLUSH);
-	OUT_RING(MI_NOOP);
+	BEGIN_LP_RING(4);
 	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON);
 	OUT_RING(overlay->flip_addr | OFC_UPDATE);
 	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
@@ -267,9 +260,7 @@ static void intel_overlay_continue(struc
 	if (tmp & (1 << 17))
 		DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
 
-	BEGIN_LP_RING(4);
-	OUT_RING(MI_FLUSH);
-	OUT_RING(MI_NOOP);
+	BEGIN_LP_RING(2);
 	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
 	OUT_RING(flip_addr);
         ADVANCE_LP_RING();
@@ -338,9 +329,7 @@ static int intel_overlay_off(struct inte
 	/* wait for overlay to go idle */
 	overlay->hw_wedged = SWITCH_OFF_STAGE_1;
 
-	BEGIN_LP_RING(6);
-	OUT_RING(MI_FLUSH);
-	OUT_RING(MI_NOOP);
+	BEGIN_LP_RING(4);
 	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
 	OUT_RING(flip_addr);
         OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
@@ -358,9 +347,7 @@ static int intel_overlay_off(struct inte
 	/* turn overlay off */
 	overlay->hw_wedged = SWITCH_OFF_STAGE_2;
 
-	BEGIN_LP_RING(6);
-        OUT_RING(MI_FLUSH);
-        OUT_RING(MI_NOOP);
+	BEGIN_LP_RING(4);
         OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
 	OUT_RING(flip_addr);
         OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
@@ -435,9 +422,7 @@ int intel_overlay_recover_from_interrupt
 
 			overlay->hw_wedged = SWITCH_OFF_STAGE_2;
 
-			BEGIN_LP_RING(6);
-			OUT_RING(MI_FLUSH);
-			OUT_RING(MI_NOOP);
+			BEGIN_LP_RING(4);
 			OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
 			OUT_RING(flip_addr);
 			OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
@@ -739,7 +724,7 @@ int intel_overlay_do_put_image(struct in
 	int ret, tmp_width;
 	struct overlay_registers *regs;
 	bool scale_changed = false;
-	struct drm_i915_gem_object *bo_priv = new_bo->driver_private;
+	struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo);
 	struct drm_device *dev = overlay->dev;
 
 	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
@@ -824,7 +809,7 @@ int intel_overlay_do_put_image(struct in
 	intel_overlay_continue(overlay, scale_changed);
 
 	overlay->old_vid_bo = overlay->vid_bo;
-	overlay->vid_bo = new_bo->driver_private;
+	overlay->vid_bo = to_intel_bo(new_bo);
 
 	return 0;
 
@@ -1083,14 +1068,18 @@ int intel_overlay_put_image(struct drm_d
 
 	drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
                         DRM_MODE_OBJECT_CRTC);
-	if (!drmmode_obj)
-		return -ENOENT;
+	if (!drmmode_obj) {
+		ret = -ENOENT;
+		goto out_free;
+	}
 	crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
 
 	new_bo = drm_gem_object_lookup(dev, file_priv,
 			put_image_rec->bo_handle);
-	if (!new_bo)
-		return -ENOENT;
+	if (!new_bo) {
+		ret = -ENOENT;
+		goto out_free;
+	}
 
 	mutex_lock(&dev->mode_config.mutex);
 	mutex_lock(&dev->struct_mutex);
@@ -1179,7 +1168,8 @@ int intel_overlay_put_image(struct drm_d
 out_unlock:
 	mutex_unlock(&dev->struct_mutex);
 	mutex_unlock(&dev->mode_config.mutex);
-	drm_gem_object_unreference(new_bo);
+	drm_gem_object_unreference_unlocked(new_bo);
+out_free:
 	kfree(params);
 
 	return ret;
@@ -1354,7 +1344,7 @@ void intel_setup_overlay(struct drm_devi
 	reg_bo = drm_gem_object_alloc(dev, PAGE_SIZE);
 	if (!reg_bo)
 		goto out_free;
-	overlay->reg_bo = reg_bo->driver_private;
+	overlay->reg_bo = to_intel_bo(reg_bo);
 
 	if (OVERLAY_NONPHYSICAL(dev)) {
 		ret = i915_gem_object_pin(reg_bo, PAGE_SIZE);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_sdvo.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_sdvo.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_sdvo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_sdvo.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
  *	Eric Anholt <eric@anholt.net>
  */
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include "drmP.h"
 #include "drm.h"
@@ -35,6 +36,7 @@
 #include "i915_drm.h"
 #include "i915_drv.h"
 #include "intel_sdvo_regs.h"
+#include <linux/dmi.h>
 
 static char *tv_format_names[] = {
 	"NTSC_M"   , "NTSC_J"  , "NTSC_443",
@@ -52,7 +54,7 @@ struct intel_sdvo_priv {
 	u8 slave_addr;
 
 	/* Register for the SDVO device: SDVOB or SDVOC */
-	int output_device;
+	int sdvo_reg;
 
 	/* Active outputs controlled by this SDVO output */
 	uint16_t controlled_output;
@@ -122,7 +124,7 @@ struct intel_sdvo_priv {
 	 */
 	struct intel_sdvo_encode encode;
 
-	/* DDC bus used by this SDVO output */
+	/* DDC bus used by this SDVO encoder */
 	uint8_t ddc_bus;
 
 	/* Mac mini hack -- use the same DDC as the analog connector */
@@ -160,22 +162,22 @@ struct intel_sdvo_priv {
 };
 
 static bool
-intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags);
+intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags);
 
 /**
  * Writes the SDVOB or SDVOC with the given value, but always writes both
  * SDVOB and SDVOC to work around apparent hardware issues (according to
  * comments in the BIOS).
  */
-static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
+static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val)
 {
-	struct drm_device *dev = intel_output->base.dev;
+	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_sdvo_priv   *sdvo_priv = intel_output->dev_priv;
+	struct intel_sdvo_priv   *sdvo_priv = intel_encoder->dev_priv;
 	u32 bval = val, cval = val;
 	int i;
 
-	if (sdvo_priv->output_device == SDVOB) {
+	if (sdvo_priv->sdvo_reg == SDVOB) {
 		cval = I915_READ(SDVOC);
 	} else {
 		bval = I915_READ(SDVOB);
@@ -194,10 +196,10 @@ static void intel_sdvo_write_sdvox(struc
 	}
 }
 
-static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
+static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr,
 				 u8 *ch)
 {
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	u8 out_buf[2];
 	u8 buf[2];
 	int ret;
@@ -220,7 +222,7 @@ static bool intel_sdvo_read_byte(struct
 	out_buf[0] = addr;
 	out_buf[1] = 0;
 
-	if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2)
+	if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2)
 	{
 		*ch = buf[0];
 		return true;
@@ -230,10 +232,10 @@ static bool intel_sdvo_read_byte(struct
 	return false;
 }
 
-static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
+static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr,
 				  u8 ch)
 {
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	u8 out_buf[2];
 	struct i2c_msg msgs[] = {
 		{
@@ -247,7 +249,7 @@ static bool intel_sdvo_write_byte(struct
 	out_buf[0] = addr;
 	out_buf[1] = ch;
 
-	if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1)
+	if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1)
 	{
 		return true;
 	}
@@ -351,13 +353,13 @@ static const struct _sdvo_cmd_name {
     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA),
 };
 
-#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
-#define SDVO_PRIV(output)   ((struct intel_sdvo_priv *) (output)->dev_priv)
+#define SDVO_NAME(dev_priv) ((dev_priv)->sdvo_reg == SDVOB ? "SDVOB" : "SDVOC")
+#define SDVO_PRIV(encoder)   ((struct intel_sdvo_priv *) (encoder)->dev_priv)
 
-static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
+static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd,
 				   void *args, int args_len)
 {
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	int i;
 
 	DRM_DEBUG_KMS("%s: W: %02X ",
@@ -377,19 +379,19 @@ static void intel_sdvo_debug_write(struc
 	DRM_LOG_KMS("\n");
 }
 
-static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd,
+static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd,
 				 void *args, int args_len)
 {
 	int i;
 
-	intel_sdvo_debug_write(intel_output, cmd, args, args_len);
+	intel_sdvo_debug_write(intel_encoder, cmd, args, args_len);
 
 	for (i = 0; i < args_len; i++) {
-		intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0 - i,
+		intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i,
 				      ((u8*)args)[i]);
 	}
 
-	intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd);
+	intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd);
 }
 
 static const char *cmd_status_names[] = {
@@ -402,11 +404,11 @@ static const char *cmd_status_names[] =
 	"Scaling not supported"
 };
 
-static void intel_sdvo_debug_response(struct intel_output *intel_output,
+static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder,
 				      void *response, int response_len,
 				      u8 status)
 {
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	int i;
 
 	DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv));
@@ -421,7 +423,7 @@ static void intel_sdvo_debug_response(st
 	DRM_LOG_KMS("\n");
 }
 
-static u8 intel_sdvo_read_response(struct intel_output *intel_output,
+static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder,
 				   void *response, int response_len)
 {
 	int i;
@@ -431,16 +433,16 @@ static u8 intel_sdvo_read_response(struc
 	while (retry--) {
 		/* Read the command response */
 		for (i = 0; i < response_len; i++) {
-			intel_sdvo_read_byte(intel_output,
+			intel_sdvo_read_byte(intel_encoder,
 					     SDVO_I2C_RETURN_0 + i,
 					     &((u8 *)response)[i]);
 		}
 
 		/* read the return status */
-		intel_sdvo_read_byte(intel_output, SDVO_I2C_CMD_STATUS,
+		intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS,
 				     &status);
 
-		intel_sdvo_debug_response(intel_output, response, response_len,
+		intel_sdvo_debug_response(intel_encoder, response, response_len,
 					  status);
 		if (status != SDVO_CMD_STATUS_PENDING)
 			return status;
@@ -468,10 +470,10 @@ static int intel_sdvo_get_pixel_multipli
  * another I2C transaction after issuing the DDC bus switch, it will be
  * switched to the internal SDVO register.
  */
-static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
+static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder,
 					      u8 target)
 {
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	u8 out_buf[2], cmd_buf[2], ret_value[2], ret;
 	struct i2c_msg msgs[] = {
 		{
@@ -495,10 +497,10 @@ static void intel_sdvo_set_control_bus_s
 		},
 	};
 
-	intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
+	intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
 					&target, 1);
 	/* write the DDC switch command argument */
-	intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target);
+	intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target);
 
 	out_buf[0] = SDVO_I2C_OPCODE;
 	out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH;
@@ -507,7 +509,7 @@ static void intel_sdvo_set_control_bus_s
 	ret_value[0] = 0;
 	ret_value[1] = 0;
 
-	ret = i2c_transfer(intel_output->i2c_bus, msgs, 3);
+	ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3);
 	if (ret != 3) {
 		/* failure in I2C transfer */
 		DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
@@ -521,7 +523,7 @@ static void intel_sdvo_set_control_bus_s
 	return;
 }
 
-static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1)
+static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1)
 {
 	struct intel_sdvo_set_target_input_args targets = {0};
 	u8 status;
@@ -532,10 +534,10 @@ static bool intel_sdvo_set_target_input(
 	if (target_1)
 		targets.target_1 = 1;
 
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_INPUT, &targets,
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets,
 			     sizeof(targets));
 
-	status = intel_sdvo_read_response(intel_output, NULL, 0);
+	status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
 	return (status == SDVO_CMD_STATUS_SUCCESS);
 }
@@ -546,13 +548,13 @@ static bool intel_sdvo_set_target_input(
  * This function is making an assumption about the layout of the response,
  * which should be checked against the docs.
  */
-static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, bool *input_1, bool *input_2)
+static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2)
 {
 	struct intel_sdvo_get_trained_inputs_response response;
 	u8 status;
 
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
-	status = intel_sdvo_read_response(intel_output, &response, sizeof(response));
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
+	status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response));
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return false;
 
@@ -561,29 +563,29 @@ static bool intel_sdvo_get_trained_input
 	return true;
 }
 
-static bool intel_sdvo_get_active_outputs(struct intel_output *intel_output,
+static bool intel_sdvo_get_active_outputs(struct intel_encoder *intel_encoder,
 					  u16 *outputs)
 {
 	u8 status;
 
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
-	status = intel_sdvo_read_response(intel_output, outputs, sizeof(*outputs));
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
+	status = intel_sdvo_read_response(intel_encoder, outputs, sizeof(*outputs));
 
 	return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_set_active_outputs(struct intel_output *intel_output,
+static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder,
 					  u16 outputs)
 {
 	u8 status;
 
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
 			     sizeof(outputs));
-	status = intel_sdvo_read_response(intel_output, NULL, 0);
+	status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 	return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output,
+static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder,
 					       int mode)
 {
 	u8 status, state = SDVO_ENCODER_STATE_ON;
@@ -603,24 +605,24 @@ static bool intel_sdvo_set_encoder_power
 		break;
 	}
 
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
 			     sizeof(state));
-	status = intel_sdvo_read_response(intel_output, NULL, 0);
+	status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
 	return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_output,
+static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder,
 						   int *clock_min,
 						   int *clock_max)
 {
 	struct intel_sdvo_pixel_clock_range clocks;
 	u8 status;
 
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
 			     NULL, 0);
 
-	status = intel_sdvo_read_response(intel_output, &clocks, sizeof(clocks));
+	status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks));
 
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return false;
@@ -632,31 +634,31 @@ static bool intel_sdvo_get_input_pixel_c
 	return true;
 }
 
-static bool intel_sdvo_set_target_output(struct intel_output *intel_output,
+static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder,
 					 u16 outputs)
 {
 	u8 status;
 
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
 			     sizeof(outputs));
 
-	status = intel_sdvo_read_response(intel_output, NULL, 0);
+	status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 	return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
+static bool intel_sdvo_get_timing(struct intel_encoder *intel_encoder, u8 cmd,
 				  struct intel_sdvo_dtd *dtd)
 {
 	u8 status;
 
-	intel_sdvo_write_cmd(intel_output, cmd, NULL, 0);
-	status = intel_sdvo_read_response(intel_output, &dtd->part1,
+	intel_sdvo_write_cmd(intel_encoder, cmd, NULL, 0);
+	status = intel_sdvo_read_response(intel_encoder, &dtd->part1,
 					  sizeof(dtd->part1));
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return false;
 
-	intel_sdvo_write_cmd(intel_output, cmd + 1, NULL, 0);
-	status = intel_sdvo_read_response(intel_output, &dtd->part2,
+	intel_sdvo_write_cmd(intel_encoder, cmd + 1, NULL, 0);
+	status = intel_sdvo_read_response(intel_encoder, &dtd->part2,
 					  sizeof(dtd->part2));
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return false;
@@ -664,60 +666,60 @@ static bool intel_sdvo_get_timing(struct
 	return true;
 }
 
-static bool intel_sdvo_get_input_timing(struct intel_output *intel_output,
+static bool intel_sdvo_get_input_timing(struct intel_encoder *intel_encoder,
 					 struct intel_sdvo_dtd *dtd)
 {
-	return intel_sdvo_get_timing(intel_output,
+	return intel_sdvo_get_timing(intel_encoder,
 				     SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
 }
 
-static bool intel_sdvo_get_output_timing(struct intel_output *intel_output,
+static bool intel_sdvo_get_output_timing(struct intel_encoder *intel_encoder,
 					 struct intel_sdvo_dtd *dtd)
 {
-	return intel_sdvo_get_timing(intel_output,
+	return intel_sdvo_get_timing(intel_encoder,
 				     SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd);
 }
 
-static bool intel_sdvo_set_timing(struct intel_output *intel_output, u8 cmd,
+static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd,
 				  struct intel_sdvo_dtd *dtd)
 {
 	u8 status;
 
-	intel_sdvo_write_cmd(intel_output, cmd, &dtd->part1, sizeof(dtd->part1));
-	status = intel_sdvo_read_response(intel_output, NULL, 0);
+	intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1));
+	status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return false;
 
-	intel_sdvo_write_cmd(intel_output, cmd + 1, &dtd->part2, sizeof(dtd->part2));
-	status = intel_sdvo_read_response(intel_output, NULL, 0);
+	intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2));
+	status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return false;
 
 	return true;
 }
 
-static bool intel_sdvo_set_input_timing(struct intel_output *intel_output,
+static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder,
 					 struct intel_sdvo_dtd *dtd)
 {
-	return intel_sdvo_set_timing(intel_output,
+	return intel_sdvo_set_timing(intel_encoder,
 				     SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
 }
 
-static bool intel_sdvo_set_output_timing(struct intel_output *intel_output,
+static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder,
 					 struct intel_sdvo_dtd *dtd)
 {
-	return intel_sdvo_set_timing(intel_output,
+	return intel_sdvo_set_timing(intel_encoder,
 				     SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
 }
 
 static bool
-intel_sdvo_create_preferred_input_timing(struct intel_output *output,
+intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder,
 					 uint16_t clock,
 					 uint16_t width,
 					 uint16_t height)
 {
 	struct intel_sdvo_preferred_input_timing_args args;
-	struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	uint8_t status;
 
 	memset(&args, 0, sizeof(args));
@@ -731,32 +733,33 @@ intel_sdvo_create_preferred_input_timing
 	    sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height))
 		args.scaled = 1;
 
-	intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
+	intel_sdvo_write_cmd(intel_encoder,
+			     SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
 			     &args, sizeof(args));
-	status = intel_sdvo_read_response(output, NULL, 0);
+	status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return false;
 
 	return true;
 }
 
-static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output,
+static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder,
 						  struct intel_sdvo_dtd *dtd)
 {
 	bool status;
 
-	intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
 			     NULL, 0);
 
-	status = intel_sdvo_read_response(output, &dtd->part1,
+	status = intel_sdvo_read_response(intel_encoder, &dtd->part1,
 					  sizeof(dtd->part1));
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return false;
 
-	intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
 			     NULL, 0);
 
-	status = intel_sdvo_read_response(output, &dtd->part2,
+	status = intel_sdvo_read_response(intel_encoder, &dtd->part2,
 					  sizeof(dtd->part2));
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return false;
@@ -764,12 +767,12 @@ static bool intel_sdvo_get_preferred_inp
 	return false;
 }
 
-static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
+static int intel_sdvo_get_clock_rate_mult(struct intel_encoder *intel_encoder)
 {
 	u8 response, status;
 
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
-	status = intel_sdvo_read_response(intel_output, &response, 1);
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
+	status = intel_sdvo_read_response(intel_encoder, &response, 1);
 
 	if (status != SDVO_CMD_STATUS_SUCCESS) {
 		DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n");
@@ -781,12 +784,12 @@ static int intel_sdvo_get_clock_rate_mul
 	return response;
 }
 
-static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 val)
+static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val)
 {
 	u8 status;
 
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
-	status = intel_sdvo_read_response(intel_output, NULL, 0);
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
+	status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return false;
 
@@ -875,13 +878,13 @@ static void intel_sdvo_get_mode_from_dtd
 		mode->flags |= DRM_MODE_FLAG_PVSYNC;
 }
 
-static bool intel_sdvo_get_supp_encode(struct intel_output *output,
+static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder,
 				       struct intel_sdvo_encode *encode)
 {
 	uint8_t status;
 
-	intel_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
-	status = intel_sdvo_read_response(output, encode, sizeof(*encode));
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
+	status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode));
 	if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */
 		memset(encode, 0, sizeof(*encode));
 		return false;
@@ -890,29 +893,30 @@ static bool intel_sdvo_get_supp_encode(s
 	return true;
 }
 
-static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode)
+static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder,
+				  uint8_t mode)
 {
 	uint8_t status;
 
-	intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1);
-	status = intel_sdvo_read_response(output, NULL, 0);
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1);
+	status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
 	return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_set_colorimetry(struct intel_output *output,
+static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder,
 				       uint8_t mode)
 {
 	uint8_t status;
 
-	intel_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
-	status = intel_sdvo_read_response(output, NULL, 0);
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
+	status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
 	return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
 #if 0
-static void intel_sdvo_dump_hdmi_buf(struct intel_output *output)
+static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder)
 {
 	int i, j;
 	uint8_t set_buf_index[2];
@@ -921,43 +925,45 @@ static void intel_sdvo_dump_hdmi_buf(str
 	uint8_t buf[48];
 	uint8_t *pos;
 
-	intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0);
-	intel_sdvo_read_response(output, &av_split, 1);
+	intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0);
+	intel_sdvo_read_response(encoder, &av_split, 1);
 
 	for (i = 0; i <= av_split; i++) {
 		set_buf_index[0] = i; set_buf_index[1] = 0;
-		intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX,
+		intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX,
 				     set_buf_index, 2);
-		intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
-		intel_sdvo_read_response(output, &buf_size, 1);
+		intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
+		intel_sdvo_read_response(encoder, &buf_size, 1);
 
 		pos = buf;
 		for (j = 0; j <= buf_size; j += 8) {
-			intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA,
+			intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_DATA,
 					     NULL, 0);
-			intel_sdvo_read_response(output, pos, 8);
+			intel_sdvo_read_response(encoder, pos, 8);
 			pos += 8;
 		}
 	}
 }
 #endif
 
-static void intel_sdvo_set_hdmi_buf(struct intel_output *output, int index,
-				uint8_t *data, int8_t size, uint8_t tx_rate)
+static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder,
+				    int index,
+				    uint8_t *data, int8_t size, uint8_t tx_rate)
 {
     uint8_t set_buf_index[2];
 
     set_buf_index[0] = index;
     set_buf_index[1] = 0;
 
-    intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2);
+    intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_INDEX,
+			 set_buf_index, 2);
 
     for (; size > 0; size -= 8) {
-	intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8);
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_DATA, data, 8);
 	data += 8;
     }
 
-    intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
+    intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
 }
 
 static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size)
@@ -1032,7 +1038,7 @@ struct dip_infoframe {
 	} __attribute__ ((packed)) u;
 } __attribute__((packed));
 
-static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
+static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder,
 					 struct drm_display_mode * mode)
 {
 	struct dip_infoframe avi_if = {
@@ -1043,15 +1049,16 @@ static void intel_sdvo_set_avi_infoframe
 
 	avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if,
 						    4 + avi_if.len);
-	intel_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len,
+	intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if,
+				4 + avi_if.len,
 				SDVO_HBUF_TX_VSYNC);
 }
 
-static void intel_sdvo_set_tv_format(struct intel_output *output)
+static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder)
 {
 
 	struct intel_sdvo_tv_format format;
-	struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	uint32_t format_map, i;
 	uint8_t status;
 
@@ -1064,10 +1071,10 @@ static void intel_sdvo_set_tv_format(str
 	memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ?
 			sizeof(format) : sizeof(format_map));
 
-	intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map,
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format_map,
 			     sizeof(format));
 
-	status = intel_sdvo_read_response(output, NULL, 0);
+	status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		DRM_DEBUG_KMS("%s: Failed to set TV format\n",
 			  SDVO_NAME(sdvo_priv));
@@ -1077,8 +1084,8 @@ static bool intel_sdvo_mode_fixup(struct
 				  struct drm_display_mode *mode,
 				  struct drm_display_mode *adjusted_mode)
 {
-	struct intel_output *output = enc_to_intel_output(encoder);
-	struct intel_sdvo_priv *dev_priv = output->dev_priv;
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	struct intel_sdvo_priv *dev_priv = intel_encoder->dev_priv;
 
 	if (dev_priv->is_tv) {
 		struct intel_sdvo_dtd output_dtd;
@@ -1093,22 +1100,22 @@ static bool intel_sdvo_mode_fixup(struct
 
 		/* Set output timings */
 		intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
-		intel_sdvo_set_target_output(output,
+		intel_sdvo_set_target_output(intel_encoder,
 					     dev_priv->controlled_output);
-		intel_sdvo_set_output_timing(output, &output_dtd);
+		intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
 
 		/* Set the input timing to the screen. Assume always input 0. */
-		intel_sdvo_set_target_input(output, true, false);
+		intel_sdvo_set_target_input(intel_encoder, true, false);
 
 
-		success = intel_sdvo_create_preferred_input_timing(output,
+		success = intel_sdvo_create_preferred_input_timing(intel_encoder,
 								   mode->clock / 10,
 								   mode->hdisplay,
 								   mode->vdisplay);
 		if (success) {
 			struct intel_sdvo_dtd input_dtd;
 
-			intel_sdvo_get_preferred_input_timing(output,
+			intel_sdvo_get_preferred_input_timing(intel_encoder,
 							     &input_dtd);
 			intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
 			dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
@@ -1131,16 +1138,16 @@ static bool intel_sdvo_mode_fixup(struct
 		intel_sdvo_get_dtd_from_mode(&output_dtd,
 				dev_priv->sdvo_lvds_fixed_mode);
 
-		intel_sdvo_set_target_output(output,
+		intel_sdvo_set_target_output(intel_encoder,
 					     dev_priv->controlled_output);
-		intel_sdvo_set_output_timing(output, &output_dtd);
+		intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
 
 		/* Set the input timing to the screen. Assume always input 0. */
-		intel_sdvo_set_target_input(output, true, false);
+		intel_sdvo_set_target_input(intel_encoder, true, false);
 
 
 		success = intel_sdvo_create_preferred_input_timing(
-				output,
+				intel_encoder,
 				mode->clock / 10,
 				mode->hdisplay,
 				mode->vdisplay);
@@ -1148,7 +1155,7 @@ static bool intel_sdvo_mode_fixup(struct
 		if (success) {
 			struct intel_sdvo_dtd input_dtd;
 
-			intel_sdvo_get_preferred_input_timing(output,
+			intel_sdvo_get_preferred_input_timing(intel_encoder,
 							     &input_dtd);
 			intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
 			dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
@@ -1180,8 +1187,8 @@ static void intel_sdvo_mode_set(struct d
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc = encoder->crtc;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct intel_output *output = enc_to_intel_output(encoder);
-	struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	u32 sdvox = 0;
 	int sdvo_pixel_multiply;
 	struct intel_sdvo_in_out_map in_out;
@@ -1200,12 +1207,12 @@ static void intel_sdvo_mode_set(struct d
 	in_out.in0 = sdvo_priv->controlled_output;
 	in_out.in1 = 0;
 
-	intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP,
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP,
 			     &in_out, sizeof(in_out));
-	status = intel_sdvo_read_response(output, NULL, 0);
+	status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
 	if (sdvo_priv->is_hdmi) {
-		intel_sdvo_set_avi_infoframe(output, mode);
+		intel_sdvo_set_avi_infoframe(intel_encoder, mode);
 		sdvox |= SDVO_AUDIO_ENABLE;
 	}
 
@@ -1222,16 +1229,16 @@ static void intel_sdvo_mode_set(struct d
 	 */
 	if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) {
 		/* Set the output timing to the screen */
-		intel_sdvo_set_target_output(output,
+		intel_sdvo_set_target_output(intel_encoder,
 					     sdvo_priv->controlled_output);
-		intel_sdvo_set_output_timing(output, &input_dtd);
+		intel_sdvo_set_output_timing(intel_encoder, &input_dtd);
 	}
 
 	/* Set the input timing to the screen. Assume always input 0. */
-	intel_sdvo_set_target_input(output, true, false);
+	intel_sdvo_set_target_input(intel_encoder, true, false);
 
 	if (sdvo_priv->is_tv)
-		intel_sdvo_set_tv_format(output);
+		intel_sdvo_set_tv_format(intel_encoder);
 
 	/* 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
@@ -1239,29 +1246,29 @@ static void intel_sdvo_mode_set(struct d
 	 * output the preferred timing, and we don't support that currently.
 	 */
 #if 0
-	success = intel_sdvo_create_preferred_input_timing(output, clock,
+	success = intel_sdvo_create_preferred_input_timing(encoder, clock,
 							   width, height);
 	if (success) {
 		struct intel_sdvo_dtd *input_dtd;
 
-		intel_sdvo_get_preferred_input_timing(output, &input_dtd);
-		intel_sdvo_set_input_timing(output, &input_dtd);
+		intel_sdvo_get_preferred_input_timing(encoder, &input_dtd);
+		intel_sdvo_set_input_timing(encoder, &input_dtd);
 	}
 #else
-	intel_sdvo_set_input_timing(output, &input_dtd);
+	intel_sdvo_set_input_timing(intel_encoder, &input_dtd);
 #endif
 
 	switch (intel_sdvo_get_pixel_multiplier(mode)) {
 	case 1:
-		intel_sdvo_set_clock_rate_mult(output,
+		intel_sdvo_set_clock_rate_mult(intel_encoder,
 					       SDVO_CLOCK_RATE_MULT_1X);
 		break;
 	case 2:
-		intel_sdvo_set_clock_rate_mult(output,
+		intel_sdvo_set_clock_rate_mult(intel_encoder,
 					       SDVO_CLOCK_RATE_MULT_2X);
 		break;
 	case 4:
-		intel_sdvo_set_clock_rate_mult(output,
+		intel_sdvo_set_clock_rate_mult(intel_encoder,
 					       SDVO_CLOCK_RATE_MULT_4X);
 		break;
 	}
@@ -1272,8 +1279,8 @@ static void intel_sdvo_mode_set(struct d
 			SDVO_VSYNC_ACTIVE_HIGH |
 			SDVO_HSYNC_ACTIVE_HIGH;
 	} else {
-		sdvox |= I915_READ(sdvo_priv->output_device);
-		switch (sdvo_priv->output_device) {
+		sdvox |= I915_READ(sdvo_priv->sdvo_reg);
+		switch (sdvo_priv->sdvo_reg) {
 		case SDVOB:
 			sdvox &= SDVOB_PRESERVE_MASK;
 			break;
@@ -1297,26 +1304,26 @@ static void intel_sdvo_mode_set(struct d
 
 	if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL)
 		sdvox |= SDVO_STALL_SELECT;
-	intel_sdvo_write_sdvox(output, sdvox);
+	intel_sdvo_write_sdvox(intel_encoder, sdvox);
 }
 
 static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
 {
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_output *intel_output = enc_to_intel_output(encoder);
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	u32 temp;
 
 	if (mode != DRM_MODE_DPMS_ON) {
-		intel_sdvo_set_active_outputs(intel_output, 0);
+		intel_sdvo_set_active_outputs(intel_encoder, 0);
 		if (0)
-			intel_sdvo_set_encoder_power_state(intel_output, mode);
+			intel_sdvo_set_encoder_power_state(intel_encoder, mode);
 
 		if (mode == DRM_MODE_DPMS_OFF) {
-			temp = I915_READ(sdvo_priv->output_device);
+			temp = I915_READ(sdvo_priv->sdvo_reg);
 			if ((temp & SDVO_ENABLE) != 0) {
-				intel_sdvo_write_sdvox(intel_output, temp & ~SDVO_ENABLE);
+				intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE);
 			}
 		}
 	} else {
@@ -1324,13 +1331,13 @@ static void intel_sdvo_dpms(struct drm_e
 		int i;
 		u8 status;
 
-		temp = I915_READ(sdvo_priv->output_device);
+		temp = I915_READ(sdvo_priv->sdvo_reg);
 		if ((temp & SDVO_ENABLE) == 0)
-			intel_sdvo_write_sdvox(intel_output, temp | SDVO_ENABLE);
+			intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE);
 		for (i = 0; i < 2; i++)
 		  intel_wait_for_vblank(dev);
 
-		status = intel_sdvo_get_trained_inputs(intel_output, &input1,
+		status = intel_sdvo_get_trained_inputs(intel_encoder, &input1,
 						       &input2);
 
 
@@ -1344,8 +1351,8 @@ static void intel_sdvo_dpms(struct drm_e
 		}
 
 		if (0)
-			intel_sdvo_set_encoder_power_state(intel_output, mode);
-		intel_sdvo_set_active_outputs(intel_output, sdvo_priv->controlled_output);
+			intel_sdvo_set_encoder_power_state(intel_encoder, mode);
+		intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->controlled_output);
 	}
 	return;
 }
@@ -1354,22 +1361,22 @@ static void intel_sdvo_save(struct drm_c
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	int o;
 
-	sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_output);
-	intel_sdvo_get_active_outputs(intel_output, &sdvo_priv->save_active_outputs);
+	sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_encoder);
+	intel_sdvo_get_active_outputs(intel_encoder, &sdvo_priv->save_active_outputs);
 
 	if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
-		intel_sdvo_set_target_input(intel_output, true, false);
-		intel_sdvo_get_input_timing(intel_output,
+		intel_sdvo_set_target_input(intel_encoder, true, false);
+		intel_sdvo_get_input_timing(intel_encoder,
 					    &sdvo_priv->save_input_dtd_1);
 	}
 
 	if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
-		intel_sdvo_set_target_input(intel_output, false, true);
-		intel_sdvo_get_input_timing(intel_output,
+		intel_sdvo_set_target_input(intel_encoder, false, true);
+		intel_sdvo_get_input_timing(intel_encoder,
 					    &sdvo_priv->save_input_dtd_2);
 	}
 
@@ -1378,8 +1385,8 @@ static void intel_sdvo_save(struct drm_c
 	        u16  this_output = (1 << o);
 		if (sdvo_priv->caps.output_flags & this_output)
 		{
-			intel_sdvo_set_target_output(intel_output, this_output);
-			intel_sdvo_get_output_timing(intel_output,
+			intel_sdvo_set_target_output(intel_encoder, this_output);
+			intel_sdvo_get_output_timing(intel_encoder,
 						     &sdvo_priv->save_output_dtd[o]);
 		}
 	}
@@ -1387,66 +1394,66 @@ static void intel_sdvo_save(struct drm_c
 		/* XXX: Save TV format/enhancements. */
 	}
 
-	sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device);
+	sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->sdvo_reg);
 }
 
 static void intel_sdvo_restore(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	int o;
 	int i;
 	bool input1, input2;
 	u8 status;
 
-	intel_sdvo_set_active_outputs(intel_output, 0);
+	intel_sdvo_set_active_outputs(intel_encoder, 0);
 
 	for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
 	{
 		u16  this_output = (1 << o);
 		if (sdvo_priv->caps.output_flags & this_output) {
-			intel_sdvo_set_target_output(intel_output, this_output);
-			intel_sdvo_set_output_timing(intel_output, &sdvo_priv->save_output_dtd[o]);
+			intel_sdvo_set_target_output(intel_encoder, this_output);
+			intel_sdvo_set_output_timing(intel_encoder, &sdvo_priv->save_output_dtd[o]);
 		}
 	}
 
 	if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
-		intel_sdvo_set_target_input(intel_output, true, false);
-		intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_1);
+		intel_sdvo_set_target_input(intel_encoder, true, false);
+		intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_1);
 	}
 
 	if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
-		intel_sdvo_set_target_input(intel_output, false, true);
-		intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_2);
+		intel_sdvo_set_target_input(intel_encoder, false, true);
+		intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_2);
 	}
 
-	intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult);
+	intel_sdvo_set_clock_rate_mult(intel_encoder, sdvo_priv->save_sdvo_mult);
 
 	if (sdvo_priv->is_tv) {
 		/* XXX: Restore TV format/enhancements. */
 	}
 
-	intel_sdvo_write_sdvox(intel_output, sdvo_priv->save_SDVOX);
+	intel_sdvo_write_sdvox(intel_encoder, sdvo_priv->save_SDVOX);
 
 	if (sdvo_priv->save_SDVOX & SDVO_ENABLE)
 	{
 		for (i = 0; i < 2; i++)
 			intel_wait_for_vblank(dev);
-		status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2);
+		status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, &input2);
 		if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
 			DRM_DEBUG_KMS("First %s output reported failure to "
 					"sync\n", SDVO_NAME(sdvo_priv));
 	}
 
-	intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs);
+	intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->save_active_outputs);
 }
 
 static int intel_sdvo_mode_valid(struct drm_connector *connector,
 				 struct drm_display_mode *mode)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 
 	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 		return MODE_NO_DBLESCAN;
@@ -1471,12 +1478,12 @@ static int intel_sdvo_mode_valid(struct
 	return MODE_OK;
 }
 
-static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struct intel_sdvo_caps *caps)
+static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps)
 {
 	u8 status;
 
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
-	status = intel_sdvo_read_response(intel_output, caps, sizeof(*caps));
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
+	status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps));
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return false;
 
@@ -1486,22 +1493,22 @@ static bool intel_sdvo_get_capabilities(
 struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)
 {
 	struct drm_connector *connector = NULL;
-	struct intel_output *iout = NULL;
+	struct intel_encoder *iout = NULL;
 	struct intel_sdvo_priv *sdvo;
 
 	/* find the sdvo connector */
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		iout = to_intel_output(connector);
+		iout = to_intel_encoder(connector);
 
 		if (iout->type != INTEL_OUTPUT_SDVO)
 			continue;
 
 		sdvo = iout->dev_priv;
 
-		if (sdvo->output_device == SDVOB && sdvoB)
+		if (sdvo->sdvo_reg == SDVOB && sdvoB)
 			return connector;
 
-		if (sdvo->output_device == SDVOC && !sdvoB)
+		if (sdvo->sdvo_reg == SDVOC && !sdvoB)
 			return connector;
 
 	}
@@ -1513,16 +1520,16 @@ int intel_sdvo_supports_hotplug(struct d
 {
 	u8 response[2];
 	u8 status;
-	struct intel_output *intel_output;
+	struct intel_encoder *intel_encoder;
 	DRM_DEBUG_KMS("\n");
 
 	if (!connector)
 		return 0;
 
-	intel_output = to_intel_output(connector);
+	intel_encoder = to_intel_encoder(connector);
 
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
-	status = intel_sdvo_read_response(intel_output, &response, 2);
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
+	status = intel_sdvo_read_response(intel_encoder, &response, 2);
 
 	if (response[0] !=0)
 		return 1;
@@ -1534,30 +1541,30 @@ void intel_sdvo_set_hotplug(struct drm_c
 {
 	u8 response[2];
 	u8 status;
-	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
-	intel_sdvo_read_response(intel_output, &response, 2);
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
+	intel_sdvo_read_response(intel_encoder, &response, 2);
 
 	if (on) {
-		intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
-		status = intel_sdvo_read_response(intel_output, &response, 2);
+		intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
+		status = intel_sdvo_read_response(intel_encoder, &response, 2);
 
-		intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
+		intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
 	} else {
 		response[0] = 0;
 		response[1] = 0;
-		intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
+		intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
 	}
 
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
-	intel_sdvo_read_response(intel_output, &response, 2);
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
+	intel_sdvo_read_response(intel_encoder, &response, 2);
 }
 
 static bool
-intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
+intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder)
 {
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	int caps = 0;
 
 	if (sdvo_priv->caps.output_flags &
@@ -1591,11 +1598,11 @@ static struct drm_connector *
 intel_find_analog_connector(struct drm_device *dev)
 {
 	struct drm_connector *connector;
-	struct intel_output *intel_output;
+	struct intel_encoder *intel_encoder;
 
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		intel_output = to_intel_output(connector);
-		if (intel_output->type == INTEL_OUTPUT_ANALOG)
+		intel_encoder = to_intel_encoder(connector);
+		if (intel_encoder->type == INTEL_OUTPUT_ANALOG)
 			return connector;
 	}
 	return NULL;
@@ -1620,16 +1627,16 @@ intel_analog_is_connected(struct drm_dev
 enum drm_connector_status
 intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	enum drm_connector_status status = connector_status_connected;
 	struct edid *edid = NULL;
 
-	edid = drm_get_edid(&intel_output->base,
-			    intel_output->ddc_bus);
+	edid = drm_get_edid(&intel_encoder->base,
+			    intel_encoder->ddc_bus);
 
 	/* This is only applied to SDVO cards with multiple outputs */
-	if (edid == NULL && intel_sdvo_multifunc_encoder(intel_output)) {
+	if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) {
 		uint8_t saved_ddc, temp_ddc;
 		saved_ddc = sdvo_priv->ddc_bus;
 		temp_ddc = sdvo_priv->ddc_bus >> 1;
@@ -1639,8 +1646,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_c
 		 */
 		while(temp_ddc > 1) {
 			sdvo_priv->ddc_bus = temp_ddc;
-			edid = drm_get_edid(&intel_output->base,
-				intel_output->ddc_bus);
+			edid = drm_get_edid(&intel_encoder->base,
+				intel_encoder->ddc_bus);
 			if (edid) {
 				/*
 				 * When we can get the EDID, maybe it is the
@@ -1659,8 +1666,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_c
 	 */
 	if (edid == NULL &&
 	    sdvo_priv->analog_ddc_bus &&
-	    !intel_analog_is_connected(intel_output->base.dev))
-		edid = drm_get_edid(&intel_output->base,
+	    !intel_analog_is_connected(intel_encoder->base.dev))
+		edid = drm_get_edid(&intel_encoder->base,
 				    sdvo_priv->analog_ddc_bus);
 	if (edid != NULL) {
 		/* Don't report the output as connected if it's a DVI-I
@@ -1675,7 +1682,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_c
 		}
 
 		kfree(edid);
-		intel_output->base.display_info.raw_edid = NULL;
+		intel_encoder->base.display_info.raw_edid = NULL;
 
 	} else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
 		status = connector_status_disconnected;
@@ -1687,16 +1694,16 @@ static enum drm_connector_status intel_s
 {
 	uint16_t response;
 	u8 status;
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 
-	intel_sdvo_write_cmd(intel_output,
+	intel_sdvo_write_cmd(intel_encoder,
 			     SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
 	if (sdvo_priv->is_tv) {
 		/* add 30ms delay when the output type is SDVO-TV */
 		mdelay(30);
 	}
-	status = intel_sdvo_read_response(intel_output, &response, 2);
+	status = intel_sdvo_read_response(intel_encoder, &response, 2);
 
 	DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);
 
@@ -1706,10 +1713,10 @@ static enum drm_connector_status intel_s
 	if (response == 0)
 		return connector_status_disconnected;
 
-	if (intel_sdvo_multifunc_encoder(intel_output) &&
+	if (intel_sdvo_multifunc_encoder(intel_encoder) &&
 		sdvo_priv->attached_output != response) {
 		if (sdvo_priv->controlled_output != response &&
-			intel_sdvo_output_setup(intel_output, response) != true)
+			intel_sdvo_output_setup(intel_encoder, response) != true)
 			return connector_status_unknown;
 		sdvo_priv->attached_output = response;
 	}
@@ -1718,12 +1725,12 @@ static enum drm_connector_status intel_s
 
 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;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	int num_modes;
 
 	/* set the bus switch and get the modes */
-	num_modes = intel_ddc_get_modes(intel_output);
+	num_modes = intel_ddc_get_modes(intel_encoder);
 
 	/*
 	 * Mac mini hack.  On this device, the DVI-I connector shares one DDC
@@ -1733,17 +1740,17 @@ static void intel_sdvo_get_ddc_modes(str
 	 */
 	if (num_modes == 0 &&
 	    sdvo_priv->analog_ddc_bus &&
-	    !intel_analog_is_connected(intel_output->base.dev)) {
+	    !intel_analog_is_connected(intel_encoder->base.dev)) {
 		struct i2c_adapter *digital_ddc_bus;
 
 		/* Switch to the analog ddc bus and try that
 		 */
-		digital_ddc_bus = intel_output->ddc_bus;
-		intel_output->ddc_bus = sdvo_priv->analog_ddc_bus;
+		digital_ddc_bus = intel_encoder->ddc_bus;
+		intel_encoder->ddc_bus = sdvo_priv->analog_ddc_bus;
 
-		(void) intel_ddc_get_modes(intel_output);
+		(void) intel_ddc_get_modes(intel_encoder);
 
-		intel_output->ddc_bus = digital_ddc_bus;
+		intel_encoder->ddc_bus = digital_ddc_bus;
 	}
 }
 
@@ -1814,7 +1821,7 @@ struct drm_display_mode sdvo_tv_modes[]
 
 static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
 {
-	struct intel_output *output = to_intel_output(connector);
+	struct intel_encoder *output = to_intel_encoder(connector);
 	struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
 	struct intel_sdvo_sdtv_resolution_request tv_res;
 	uint32_t reply = 0, format_map = 0;
@@ -1856,9 +1863,9 @@ static void intel_sdvo_get_tv_modes(stru
 
 static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 	struct drm_i915_private *dev_priv = connector->dev->dev_private;
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	struct drm_display_mode *newmode;
 
 	/*
@@ -1866,7 +1873,7 @@ static void intel_sdvo_get_lvds_modes(st
 	 * Assume that the preferred modes are
 	 * arranged in priority order.
 	 */
-	intel_ddc_get_modes(intel_output);
+	intel_ddc_get_modes(intel_encoder);
 	if (list_empty(&connector->probed_modes) == false)
 		goto end;
 
@@ -1895,7 +1902,7 @@ end:
 
 static int intel_sdvo_get_modes(struct drm_connector *connector)
 {
-	struct intel_output *output = to_intel_output(connector);
+	struct intel_encoder *output = to_intel_encoder(connector);
 	struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
 
 	if (sdvo_priv->is_tv)
@@ -1913,8 +1920,8 @@ static int intel_sdvo_get_modes(struct d
 static
 void intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	struct drm_device *dev = connector->dev;
 
 	if (sdvo_priv->is_tv) {
@@ -1951,13 +1958,13 @@ void intel_sdvo_destroy_enhance_property
 
 static void intel_sdvo_destroy(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 
-	if (intel_output->i2c_bus)
-		intel_i2c_destroy(intel_output->i2c_bus);
-	if (intel_output->ddc_bus)
-		intel_i2c_destroy(intel_output->ddc_bus);
+	if (intel_encoder->i2c_bus)
+		intel_i2c_destroy(intel_encoder->i2c_bus);
+	if (intel_encoder->ddc_bus)
+		intel_i2c_destroy(intel_encoder->ddc_bus);
 	if (sdvo_priv->analog_ddc_bus)
 		intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
 
@@ -1975,7 +1982,7 @@ static void intel_sdvo_destroy(struct dr
 	drm_sysfs_connector_remove(connector);
 	drm_connector_cleanup(connector);
 
-	kfree(intel_output);
+	kfree(intel_encoder);
 }
 
 static int
@@ -1983,9 +1990,9 @@ intel_sdvo_set_property(struct drm_conne
 			struct drm_property *property,
 			uint64_t val)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
-	struct drm_encoder *encoder = &intel_output->enc;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
+	struct drm_encoder *encoder = &intel_encoder->enc;
 	struct drm_crtc *crtc = encoder->crtc;
 	int ret = 0;
 	bool changed = false;
@@ -2093,8 +2100,8 @@ intel_sdvo_set_property(struct drm_conne
 			sdvo_priv->cur_brightness = temp_value;
 		}
 		if (cmd) {
-			intel_sdvo_write_cmd(intel_output, cmd, &temp_value, 2);
-			status = intel_sdvo_read_response(intel_output,
+			intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2);
+			status = intel_sdvo_read_response(intel_encoder,
 								NULL, 0);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO command \n");
@@ -2189,7 +2196,7 @@ intel_sdvo_select_ddc_bus(struct intel_s
 }
 
 static bool
-intel_sdvo_get_digital_encoding_mode(struct intel_output *output)
+intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output)
 {
 	struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
 	uint8_t status;
@@ -2203,42 +2210,42 @@ intel_sdvo_get_digital_encoding_mode(str
 	return true;
 }
 
-static struct intel_output *
-intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan)
+static struct intel_encoder *
+intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan)
 {
 	struct drm_device *dev = chan->drm_dev;
 	struct drm_connector *connector;
-	struct intel_output *intel_output = NULL;
+	struct intel_encoder *intel_encoder = NULL;
 
 	list_for_each_entry(connector,
 			&dev->mode_config.connector_list, head) {
-		if (to_intel_output(connector)->ddc_bus == &chan->adapter) {
-			intel_output = to_intel_output(connector);
+		if (to_intel_encoder(connector)->ddc_bus == &chan->adapter) {
+			intel_encoder = to_intel_encoder(connector);
 			break;
 		}
 	}
-	return intel_output;
+	return intel_encoder;
 }
 
 static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap,
 				  struct i2c_msg msgs[], int num)
 {
-	struct intel_output *intel_output;
+	struct intel_encoder *intel_encoder;
 	struct intel_sdvo_priv *sdvo_priv;
 	struct i2c_algo_bit_data *algo_data;
 	const struct i2c_algorithm *algo;
 
 	algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data;
-	intel_output =
-		intel_sdvo_chan_to_intel_output(
+	intel_encoder =
+		intel_sdvo_chan_to_intel_encoder(
 				(struct intel_i2c_chan *)(algo_data->data));
-	if (intel_output == NULL)
+	if (intel_encoder == NULL)
 		return -EINVAL;
 
-	sdvo_priv = intel_output->dev_priv;
-	algo = intel_output->i2c_bus->algo;
+	sdvo_priv = intel_encoder->dev_priv;
+	algo = intel_encoder->i2c_bus->algo;
 
-	intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
+	intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_priv->ddc_bus);
 	return algo->master_xfer(i2c_adap, msgs, num);
 }
 
@@ -2247,12 +2254,12 @@ static struct i2c_algorithm intel_sdvo_i
 };
 
 static u8
-intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device)
+intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct sdvo_device_mapping *my_mapping, *other_mapping;
 
-	if (output_device == SDVOB) {
+	if (sdvo_reg == SDVOB) {
 		my_mapping = &dev_priv->sdvo_mappings[0];
 		other_mapping = &dev_priv->sdvo_mappings[1];
 	} else {
@@ -2277,22 +2284,41 @@ intel_sdvo_get_slave_addr(struct drm_dev
 	/* No SDVO device info is found for another DVO port,
 	 * so use mapping assumption we had before BIOS parsing.
 	 */
-	if (output_device == SDVOB)
+	if (sdvo_reg == SDVOB)
 		return 0x70;
 	else
 		return 0x72;
 }
 
+static int intel_sdvo_bad_tv_callback(const struct dmi_system_id *id)
+{
+	DRM_DEBUG_KMS("Ignoring bad SDVO TV connector for %s\n", id->ident);
+	return 1;
+}
+
+static struct dmi_system_id intel_sdvo_bad_tv[] = {
+	{
+		.callback = intel_sdvo_bad_tv_callback,
+		.ident = "IntelG45/ICH10R/DME1737",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM CORPORATION"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "4800784"),
+		},
+	},
+
+	{ }	/* terminating entry */
+};
+
 static bool
-intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
+intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags)
 {
-	struct drm_connector *connector = &intel_output->base;
-	struct drm_encoder *encoder = &intel_output->enc;
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct drm_connector *connector = &intel_encoder->base;
+	struct drm_encoder *encoder = &intel_encoder->enc;
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	bool ret = true, registered = false;
 
 	sdvo_priv->is_tv = false;
-	intel_output->needs_tv_clock = false;
+	intel_encoder->needs_tv_clock = false;
 	sdvo_priv->is_lvds = false;
 
 	if (device_is_registered(&connector->kdev)) {
@@ -2310,40 +2336,41 @@ intel_sdvo_output_setup(struct intel_out
 		encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
 		connector->connector_type = DRM_MODE_CONNECTOR_DVID;
 
-		if (intel_sdvo_get_supp_encode(intel_output,
+		if (intel_sdvo_get_supp_encode(intel_encoder,
 					       &sdvo_priv->encode) &&
-		    intel_sdvo_get_digital_encoding_mode(intel_output) &&
+		    intel_sdvo_get_digital_encoding_mode(intel_encoder) &&
 		    sdvo_priv->is_hdmi) {
 			/* enable hdmi encoding mode if supported */
-			intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI);
-			intel_sdvo_set_colorimetry(intel_output,
+			intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI);
+			intel_sdvo_set_colorimetry(intel_encoder,
 						   SDVO_COLORIMETRY_RGB256);
 			connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
-			intel_output->clone_mask =
+			intel_encoder->clone_mask =
 					(1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
 					(1 << INTEL_ANALOG_CLONE_BIT);
 		}
-	} else if (flags & SDVO_OUTPUT_SVID0) {
+	} else if ((flags & SDVO_OUTPUT_SVID0) &&
+		   !dmi_check_system(intel_sdvo_bad_tv)) {
 
 		sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0;
 		encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
 		connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
 		sdvo_priv->is_tv = true;
-		intel_output->needs_tv_clock = true;
-		intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
+		intel_encoder->needs_tv_clock = true;
+		intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
 	} else if (flags & SDVO_OUTPUT_RGB0) {
 
 		sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
 		encoder->encoder_type = DRM_MODE_ENCODER_DAC;
 		connector->connector_type = DRM_MODE_CONNECTOR_VGA;
-		intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+		intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
 					(1 << INTEL_ANALOG_CLONE_BIT);
 	} else if (flags & SDVO_OUTPUT_RGB1) {
 
 		sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
 		encoder->encoder_type = DRM_MODE_ENCODER_DAC;
 		connector->connector_type = DRM_MODE_CONNECTOR_VGA;
-		intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+		intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
 					(1 << INTEL_ANALOG_CLONE_BIT);
 	} else if (flags & SDVO_OUTPUT_CVBS0) {
 
@@ -2351,15 +2378,15 @@ intel_sdvo_output_setup(struct intel_out
 		encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
 		connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
 		sdvo_priv->is_tv = true;
-		intel_output->needs_tv_clock = true;
-		intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
+		intel_encoder->needs_tv_clock = true;
+		intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
 	} else if (flags & SDVO_OUTPUT_LVDS0) {
 
 		sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
 		encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
 		connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
 		sdvo_priv->is_lvds = true;
-		intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
+		intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
 					(1 << INTEL_SDVO_LVDS_CLONE_BIT);
 	} else if (flags & SDVO_OUTPUT_LVDS1) {
 
@@ -2367,7 +2394,7 @@ intel_sdvo_output_setup(struct intel_out
 		encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
 		connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
 		sdvo_priv->is_lvds = true;
-		intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
+		intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
 					(1 << INTEL_SDVO_LVDS_CLONE_BIT);
 	} else {
 
@@ -2380,7 +2407,7 @@ intel_sdvo_output_setup(struct intel_out
 			      bytes[0], bytes[1]);
 		ret = false;
 	}
-	intel_output->crtc_mask = (1 << 0) | (1 << 1);
+	intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
 
 	if (ret && registered)
 		ret = drm_sysfs_connector_add(connector) == 0 ? true : false;
@@ -2392,18 +2419,18 @@ intel_sdvo_output_setup(struct intel_out
 
 static void intel_sdvo_tv_create_property(struct drm_connector *connector)
 {
-      struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+      struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	struct intel_sdvo_tv_format format;
 	uint32_t format_map, i;
 	uint8_t status;
 
-	intel_sdvo_set_target_output(intel_output,
+	intel_sdvo_set_target_output(intel_encoder,
 				     sdvo_priv->controlled_output);
 
-	intel_sdvo_write_cmd(intel_output,
+	intel_sdvo_write_cmd(intel_encoder,
 			     SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0);
-	status = intel_sdvo_read_response(intel_output,
+	status = intel_sdvo_read_response(intel_encoder,
 					  &format, sizeof(format));
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return;
@@ -2441,16 +2468,16 @@ static void intel_sdvo_tv_create_propert
 
 static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 	struct intel_sdvo_enhancements_reply sdvo_data;
 	struct drm_device *dev = connector->dev;
 	uint8_t status;
 	uint16_t response, data_value[2];
 
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
+	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
 						NULL, 0);
-	status = intel_sdvo_read_response(intel_output, &sdvo_data,
+	status = intel_sdvo_read_response(intel_encoder, &sdvo_data,
 					sizeof(sdvo_data));
 	if (status != SDVO_CMD_STATUS_SUCCESS) {
 		DRM_DEBUG_KMS(" incorrect response is returned\n");
@@ -2466,18 +2493,18 @@ static void intel_sdvo_create_enhance_pr
 		 * property
 		 */
 		if (sdvo_data.overscan_h) {
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&data_value, 4);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO max "
 						"h_overscan\n");
 				return;
 			}
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_OVERSCAN_H, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&response, 2);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n");
@@ -2507,18 +2534,18 @@ static void intel_sdvo_create_enhance_pr
 					data_value[0], data_value[1], response);
 		}
 		if (sdvo_data.overscan_v) {
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&data_value, 4);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO max "
 						"v_overscan\n");
 				return;
 			}
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_OVERSCAN_V, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&response, 2);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n");
@@ -2548,17 +2575,17 @@ static void intel_sdvo_create_enhance_pr
 					data_value[0], data_value[1], response);
 		}
 		if (sdvo_data.position_h) {
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_MAX_POSITION_H, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&data_value, 4);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n");
 				return;
 			}
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_POSITION_H, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&response, 2);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n");
@@ -2579,17 +2606,17 @@ static void intel_sdvo_create_enhance_pr
 					data_value[0], data_value[1], response);
 		}
 		if (sdvo_data.position_v) {
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_MAX_POSITION_V, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&data_value, 4);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n");
 				return;
 			}
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_POSITION_V, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&response, 2);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n");
@@ -2612,17 +2639,17 @@ static void intel_sdvo_create_enhance_pr
 	}
 	if (sdvo_priv->is_tv) {
 		if (sdvo_data.saturation) {
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_MAX_SATURATION, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&data_value, 4);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO Max sat\n");
 				return;
 			}
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_SATURATION, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&response, 2);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO get sat\n");
@@ -2644,17 +2671,17 @@ static void intel_sdvo_create_enhance_pr
 					data_value[0], data_value[1], response);
 		}
 		if (sdvo_data.contrast) {
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_MAX_CONTRAST, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&data_value, 4);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n");
 				return;
 			}
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_CONTRAST, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&response, 2);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO get contrast\n");
@@ -2675,17 +2702,17 @@ static void intel_sdvo_create_enhance_pr
 					data_value[0], data_value[1], response);
 		}
 		if (sdvo_data.hue) {
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_MAX_HUE, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&data_value, 4);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO Max hue\n");
 				return;
 			}
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_HUE, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&response, 2);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO get hue\n");
@@ -2708,17 +2735,17 @@ static void intel_sdvo_create_enhance_pr
 	}
 	if (sdvo_priv->is_tv || sdvo_priv->is_lvds) {
 		if (sdvo_data.brightness) {
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&data_value, 4);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO Max bright\n");
 				return;
 			}
-			intel_sdvo_write_cmd(intel_output,
+			intel_sdvo_write_cmd(intel_encoder,
 				SDVO_CMD_GET_BRIGHTNESS, NULL, 0);
-			status = intel_sdvo_read_response(intel_output,
+			status = intel_sdvo_read_response(intel_encoder,
 				&response, 2);
 			if (status != SDVO_CMD_STATUS_SUCCESS) {
 				DRM_DEBUG_KMS("Incorrect SDVO get brigh\n");
@@ -2743,81 +2770,81 @@ static void intel_sdvo_create_enhance_pr
 	return;
 }
 
-bool intel_sdvo_init(struct drm_device *dev, int output_device)
+bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_connector *connector;
-	struct intel_output *intel_output;
+	struct intel_encoder *intel_encoder;
 	struct intel_sdvo_priv *sdvo_priv;
 
 	u8 ch[0x40];
 	int i;
 
-	intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
-	if (!intel_output) {
+	intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
+	if (!intel_encoder) {
 		return false;
 	}
 
-	sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
-	sdvo_priv->output_device = output_device;
+	sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1);
+	sdvo_priv->sdvo_reg = sdvo_reg;
 
-	intel_output->dev_priv = sdvo_priv;
-	intel_output->type = INTEL_OUTPUT_SDVO;
+	intel_encoder->dev_priv = sdvo_priv;
+	intel_encoder->type = INTEL_OUTPUT_SDVO;
 
 	/* setup the DDC bus. */
-	if (output_device == SDVOB)
-		intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
+	if (sdvo_reg == SDVOB)
+		intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
 	else
-		intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
+		intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
 
-	if (!intel_output->i2c_bus)
+	if (!intel_encoder->i2c_bus)
 		goto err_inteloutput;
 
-	sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device);
+	sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg);
 
 	/* Save the bit-banging i2c functionality for use by the DDC wrapper */
-	intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality;
+	intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality;
 
 	/* 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])) {
+		if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) {
 			DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n",
-					output_device == SDVOB ? 'B' : 'C');
+					sdvo_reg == SDVOB ? 'B' : 'C');
 			goto err_i2c;
 		}
 	}
 
 	/* setup the DDC bus. */
-	if (output_device == SDVOB) {
-		intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
+	if (sdvo_reg == SDVOB) {
+		intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
 		sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
 						"SDVOB/VGA DDC BUS");
 		dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;
 	} else {
-		intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
+		intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
 		sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
 						"SDVOC/VGA DDC BUS");
 		dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;
 	}
 
-	if (intel_output->ddc_bus == NULL)
+	if (intel_encoder->ddc_bus == NULL)
 		goto err_i2c;
 
 	/* Wrap with our custom algo which switches to DDC mode */
-	intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
+	intel_encoder->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
 
 	/* In default case sdvo lvds is false */
-	intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
+	intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps);
 
-	if (intel_sdvo_output_setup(intel_output,
+	if (intel_sdvo_output_setup(intel_encoder,
 				    sdvo_priv->caps.output_flags) != true) {
 		DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
-			  output_device == SDVOB ? 'B' : 'C');
+			  sdvo_reg == SDVOB ? 'B' : 'C');
 		goto err_i2c;
 	}
 
 
-	connector = &intel_output->base;
+	connector = &intel_encoder->base;
 	drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
 			   connector->connector_type);
 
@@ -2826,12 +2853,12 @@ bool intel_sdvo_init(struct drm_device *
 	connector->doublescan_allowed = 0;
 	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 
-	drm_encoder_init(dev, &intel_output->enc,
-			&intel_sdvo_enc_funcs, intel_output->enc.encoder_type);
+	drm_encoder_init(dev, &intel_encoder->enc,
+			&intel_sdvo_enc_funcs, intel_encoder->enc.encoder_type);
 
-	drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
+	drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs);
 
-	drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
+	drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);
 	if (sdvo_priv->is_tv)
 		intel_sdvo_tv_create_property(connector);
 
@@ -2843,9 +2870,9 @@ bool intel_sdvo_init(struct drm_device *
 	intel_sdvo_select_ddc_bus(sdvo_priv);
 
 	/* Set the input timing to the screen. Assume always input 0. */
-	intel_sdvo_set_target_input(intel_output, true, false);
+	intel_sdvo_set_target_input(intel_encoder, true, false);
 
-	intel_sdvo_get_input_pixel_clock_range(intel_output,
+	intel_sdvo_get_input_pixel_clock_range(intel_encoder,
 					       &sdvo_priv->pixel_clock_min,
 					       &sdvo_priv->pixel_clock_max);
 
@@ -2872,12 +2899,12 @@ bool intel_sdvo_init(struct drm_device *
 err_i2c:
 	if (sdvo_priv->analog_ddc_bus != NULL)
 		intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
-	if (intel_output->ddc_bus != NULL)
-		intel_i2c_destroy(intel_output->ddc_bus);
-	if (intel_output->i2c_bus != NULL)
-		intel_i2c_destroy(intel_output->i2c_bus);
+	if (intel_encoder->ddc_bus != NULL)
+		intel_i2c_destroy(intel_encoder->ddc_bus);
+	if (intel_encoder->i2c_bus != NULL)
+		intel_i2c_destroy(intel_encoder->i2c_bus);
 err_inteloutput:
-	kfree(intel_output);
+	kfree(intel_encoder);
 
 	return false;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_tv.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_tv.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_tv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/i915/intel_tv.c	2010-05-16 17:17:36.000000000 -0400
@@ -921,8 +921,8 @@ intel_tv_save(struct drm_connector *conn
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
 	int i;
 
 	tv_priv->save_TV_H_CTL_1 = I915_READ(TV_H_CTL_1);
@@ -971,8 +971,8 @@ intel_tv_restore(struct drm_connector *c
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
 	struct drm_crtc *crtc = connector->encoder->crtc;
 	struct intel_crtc *intel_crtc;
 	int i;
@@ -1068,9 +1068,9 @@ intel_tv_mode_lookup (char *tv_format)
 }
 
 static const struct tv_mode *
-intel_tv_mode_find (struct intel_output *intel_output)
+intel_tv_mode_find (struct intel_encoder *intel_encoder)
 {
-	struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+	struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
 
 	return intel_tv_mode_lookup(tv_priv->tv_format);
 }
@@ -1078,8 +1078,8 @@ intel_tv_mode_find (struct intel_output
 static enum drm_mode_status
 intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
 
 	/* Ensure TV refresh is close to desired refresh */
 	if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
@@ -1095,8 +1095,8 @@ intel_tv_mode_fixup(struct drm_encoder *
 {
 	struct drm_device *dev = encoder->dev;
 	struct drm_mode_config *drm_config = &dev->mode_config;
-	struct intel_output *intel_output = enc_to_intel_output(encoder);
-	const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output);
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder);
 	struct drm_encoder *other_encoder;
 
 	if (!tv_mode)
@@ -1121,9 +1121,9 @@ intel_tv_mode_set(struct drm_encoder *en
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc = encoder->crtc;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct intel_output *intel_output = enc_to_intel_output(encoder);
-	struct intel_tv_priv *tv_priv = intel_output->dev_priv;
-	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+	struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
 	u32 tv_ctl;
 	u32 hctl1, hctl2, hctl3;
 	u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
@@ -1360,9 +1360,9 @@ static const struct drm_display_mode rep
  * \return false if TV is disconnected.
  */
 static int
-intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
+intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
 {
-	struct drm_encoder *encoder = &intel_output->enc;
+	struct drm_encoder *encoder = &intel_encoder->enc;
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	unsigned long irqflags;
@@ -1441,9 +1441,9 @@ intel_tv_detect_type (struct drm_crtc *c
  */
 static void intel_tv_find_better_format(struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_tv_priv *tv_priv = intel_output->dev_priv;
-	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
 	int i;
 
 	if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
@@ -1475,9 +1475,9 @@ intel_tv_detect(struct drm_connector *co
 {
 	struct drm_crtc *crtc;
 	struct drm_display_mode mode;
-	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 intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+	struct drm_encoder *encoder = &intel_encoder->enc;
 	int dpms_mode;
 	int type = tv_priv->type;
 
@@ -1485,12 +1485,12 @@ intel_tv_detect(struct drm_connector *co
 	drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
 
 	if (encoder->crtc && encoder->crtc->enabled) {
-		type = intel_tv_detect_type(encoder->crtc, intel_output);
+		type = intel_tv_detect_type(encoder->crtc, intel_encoder);
 	} else {
-		crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode);
+		crtc = intel_get_load_detect_pipe(intel_encoder, &mode, &dpms_mode);
 		if (crtc) {
-			type = intel_tv_detect_type(crtc, intel_output);
-			intel_release_load_detect_pipe(intel_output, dpms_mode);
+			type = intel_tv_detect_type(crtc, intel_encoder);
+			intel_release_load_detect_pipe(intel_encoder, dpms_mode);
 		} else
 			type = -1;
 	}
@@ -1525,8 +1525,8 @@ static void
 intel_tv_chose_preferred_modes(struct drm_connector *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);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
 
 	if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
 		mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
@@ -1550,8 +1550,8 @@ static int
 intel_tv_get_modes(struct drm_connector *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);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
 	int j, count = 0;
 	u64 tmp;
 
@@ -1604,11 +1604,11 @@ intel_tv_get_modes(struct drm_connector
 static void
 intel_tv_destroy (struct drm_connector *connector)
 {
-	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
 	drm_sysfs_connector_remove(connector);
 	drm_connector_cleanup(connector);
-	kfree(intel_output);
+	kfree(intel_encoder);
 }
 
 
@@ -1617,9 +1617,9 @@ intel_tv_set_property(struct drm_connect
 		      uint64_t val)
 {
 	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 intel_encoder *intel_encoder = to_intel_encoder(connector);
+	struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+	struct drm_encoder *encoder = &intel_encoder->enc;
 	struct drm_crtc *crtc = encoder->crtc;
 	int ret = 0;
 	bool changed = false;
@@ -1740,7 +1740,7 @@ intel_tv_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_connector *connector;
-	struct intel_output *intel_output;
+	struct intel_encoder *intel_encoder;
 	struct intel_tv_priv *tv_priv;
 	u32 tv_dac_on, tv_dac_off, save_tv_dac;
 	char **tv_format_names;
@@ -1780,28 +1780,28 @@ intel_tv_init(struct drm_device *dev)
 	    (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
 		return;
 
-	intel_output = kzalloc(sizeof(struct intel_output) +
+	intel_encoder = kzalloc(sizeof(struct intel_encoder) +
 			       sizeof(struct intel_tv_priv), GFP_KERNEL);
-	if (!intel_output) {
+	if (!intel_encoder) {
 		return;
 	}
 
-	connector = &intel_output->base;
+	connector = &intel_encoder->base;
 
 	drm_connector_init(dev, connector, &intel_tv_connector_funcs,
 			   DRM_MODE_CONNECTOR_SVIDEO);
 
-	drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs,
+	drm_encoder_init(dev, &intel_encoder->enc, &intel_tv_enc_funcs,
 			 DRM_MODE_ENCODER_TVDAC);
 
-	drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
-	tv_priv = (struct intel_tv_priv *)(intel_output + 1);
-	intel_output->type = INTEL_OUTPUT_TVOUT;
-	intel_output->crtc_mask = (1 << 0) | (1 << 1);
-	intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT);
-	intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1));
-	intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
-	intel_output->dev_priv = tv_priv;
+	drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);
+	tv_priv = (struct intel_tv_priv *)(intel_encoder + 1);
+	intel_encoder->type = INTEL_OUTPUT_TVOUT;
+	intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
+	intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT);
+	intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1));
+	intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
+	intel_encoder->dev_priv = tv_priv;
 	tv_priv->type = DRM_MODE_CONNECTOR_Unknown;
 
 	/* BIOS margin values */
@@ -1812,7 +1812,7 @@ intel_tv_init(struct drm_device *dev)
 
 	tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
 
-	drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs);
+	drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs);
 	drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
 	connector->interlace_allowed = false;
 	connector->doublescan_allowed = false;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/Makefile linux-libre-2.6.34-gnu1/drivers/gpu/drm/Makefile
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
 
 ccflags-y := -Iinclude/drm
 
-drm-y       :=	drm_auth.o drm_bufs.o drm_cache.o \
+drm-y       :=	drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
 		drm_context.o drm_dma.o drm_drawable.o \
 		drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
 		drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/Makefile linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/Makefile
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -12,17 +12,17 @@ nouveau-y := nouveau_drv.o nouveau_state
              nouveau_dp.o nouveau_grctx.o \
              nv04_timer.o \
              nv04_mc.o nv40_mc.o nv50_mc.o \
-             nv04_fb.o nv10_fb.o nv40_fb.o \
+             nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \
              nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \
              nv04_graph.o nv10_graph.o nv20_graph.o \
              nv40_graph.o nv50_graph.o \
-             nv40_grctx.o \
+             nv40_grctx.o nv50_grctx.o \
              nv04_instmem.o nv50_instmem.o \
              nv50_crtc.o nv50_dac.o nv50_sor.o \
              nv50_cursor.o nv50_display.o nv50_fbcon.o \
              nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \
              nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \
-             nv17_gpio.o
+             nv17_gpio.o nv50_gpio.o
 
 nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o
 nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_acpi.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_acpi.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_acpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_acpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,6 @@
 #include <linux/pci.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 
@@ -11,6 +12,8 @@
 #include "nouveau_drm.h"
 #include "nv50_display.h"
 
+#include <linux/vga_switcheroo.h>
+
 #define NOUVEAU_DSM_SUPPORTED 0x00
 #define NOUVEAU_DSM_SUPPORTED_FUNCTIONS 0x00
 
@@ -28,31 +31,30 @@
 #define NOUVEAU_DSM_POWER_SPEED 0x01
 #define NOUVEAU_DSM_POWER_STAMINA 0x02
 
-static int nouveau_dsm(struct drm_device *dev, int func, int arg, int *result)
-{
-	static char muid[] = {
-		0xA0, 0xA0, 0x95, 0x9D, 0x60, 0x00, 0x48, 0x4D,
-		0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4,
-	};
+static struct nouveau_dsm_priv {
+	bool dsm_detected;
+	acpi_handle dhandle;
+	acpi_handle dsm_handle;
+} nouveau_dsm_priv;
 
-	struct pci_dev *pdev = dev->pdev;
-	struct acpi_handle *handle;
+static const char nouveau_dsm_muid[] = {
+	0xA0, 0xA0, 0x95, 0x9D, 0x60, 0x00, 0x48, 0x4D,
+	0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4,
+};
+
+static int nouveau_dsm(acpi_handle handle, int func, int arg, int *result)
+{
 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
 	struct acpi_object_list input;
 	union acpi_object params[4];
 	union acpi_object *obj;
 	int err;
 
-	handle = DEVICE_ACPI_HANDLE(&pdev->dev);
-
-	if (!handle)
-		return -ENODEV;
-
 	input.count = 4;
 	input.pointer = params;
 	params[0].type = ACPI_TYPE_BUFFER;
-	params[0].buffer.length = sizeof(muid);
-	params[0].buffer.pointer = (char *)muid;
+	params[0].buffer.length = sizeof(nouveau_dsm_muid);
+	params[0].buffer.pointer = (char *)nouveau_dsm_muid;
 	params[1].type = ACPI_TYPE_INTEGER;
 	params[1].integer.value = 0x00000102;
 	params[2].type = ACPI_TYPE_INTEGER;
@@ -62,7 +64,7 @@ static int nouveau_dsm(struct drm_device
 
 	err = acpi_evaluate_object(handle, "_DSM", &input, &output);
 	if (err) {
-		NV_INFO(dev, "failed to evaluate _DSM: %d\n", err);
+		printk(KERN_INFO "failed to evaluate _DSM: %d\n", err);
 		return err;
 	}
 
@@ -86,40 +88,119 @@ static int nouveau_dsm(struct drm_device
 	return 0;
 }
 
-int nouveau_hybrid_setup(struct drm_device *dev)
+static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id)
 {
-	int result;
+	return nouveau_dsm(handle, NOUVEAU_DSM_LED, mux_id, NULL);
+}
 
-	if (nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_STATE,
-								&result))
-		return -ENODEV;
+static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switcheroo_state state)
+{
+	int arg;
+	if (state == VGA_SWITCHEROO_ON)
+		arg = NOUVEAU_DSM_POWER_SPEED;
+	else
+		arg = NOUVEAU_DSM_POWER_STAMINA;
+	nouveau_dsm(handle, NOUVEAU_DSM_POWER, arg, NULL);
+	return 0;
+}
 
-	NV_INFO(dev, "_DSM hardware status gave 0x%x\n", result);
+static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id)
+{
+	if (id == VGA_SWITCHEROO_IGD)
+		return nouveau_dsm_switch_mux(nouveau_dsm_priv.dsm_handle, NOUVEAU_DSM_LED_STAMINA);
+	else
+		return nouveau_dsm_switch_mux(nouveau_dsm_priv.dsm_handle, NOUVEAU_DSM_LED_SPEED);
+}
 
-	if (result) { /* Ensure that the external GPU is enabled */
-		nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_SPEED, NULL);
-		nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_SPEED,
-									NULL);
-	} else { /* Stamina mode - disable the external GPU */
-		nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_STAMINA,
-									NULL);
-		nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_STAMINA,
-									NULL);
-	}
+static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id,
+				   enum vga_switcheroo_state state)
+{
+	if (id == VGA_SWITCHEROO_IGD)
+		return 0;
+
+	return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dsm_handle, state);
+}
 
+static int nouveau_dsm_init(void)
+{
 	return 0;
 }
 
-bool nouveau_dsm_probe(struct drm_device *dev)
+static int nouveau_dsm_get_client_id(struct pci_dev *pdev)
 {
-	int support = 0;
+	if (nouveau_dsm_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
+		return VGA_SWITCHEROO_IGD;
+	else
+		return VGA_SWITCHEROO_DIS;
+}
 
-	if (nouveau_dsm(dev, NOUVEAU_DSM_SUPPORTED,
-				NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &support))
+static struct vga_switcheroo_handler nouveau_dsm_handler = {
+	.switchto = nouveau_dsm_switchto,
+	.power_state = nouveau_dsm_power_state,
+	.init = nouveau_dsm_init,
+	.get_client_id = nouveau_dsm_get_client_id,
+};
+
+static bool nouveau_dsm_pci_probe(struct pci_dev *pdev)
+{
+	acpi_handle dhandle, nvidia_handle;
+	acpi_status status;
+	int ret;
+	uint32_t result;
+
+	dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
+	if (!dhandle)
 		return false;
+	status = acpi_get_handle(dhandle, "_DSM", &nvidia_handle);
+	if (ACPI_FAILURE(status)) {
+		return false;
+	}
 
-	if (!support)
+	ret= nouveau_dsm(nvidia_handle, NOUVEAU_DSM_SUPPORTED,
+			 NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result);
+	if (ret < 0)
 		return false;
 
+	nouveau_dsm_priv.dhandle = dhandle;
+	nouveau_dsm_priv.dsm_handle = nvidia_handle;
 	return true;
 }
+
+static bool nouveau_dsm_detect(void)
+{
+	char acpi_method_name[255] = { 0 };
+	struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
+	struct pci_dev *pdev = NULL;
+	int has_dsm = 0;
+	int vga_count = 0;
+	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
+		vga_count++;
+
+		has_dsm |= (nouveau_dsm_pci_probe(pdev) == true);
+	}
+
+	if (vga_count == 2 && has_dsm) {
+		acpi_get_name(nouveau_dsm_priv.dsm_handle, ACPI_FULL_PATHNAME, &buffer);
+		printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n",
+		       acpi_method_name);
+		nouveau_dsm_priv.dsm_detected = true;
+		return true;
+	}
+	return false;
+}
+
+void nouveau_register_dsm_handler(void)
+{
+	bool r;
+
+	r = nouveau_dsm_detect();
+	if (!r)
+		return;
+
+	vga_switcheroo_register_handler(&nouveau_dsm_handler);
+}
+
+void nouveau_unregister_dsm_handler(void)
+{
+	vga_switcheroo_unregister_handler();
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_backlight.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_backlight.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_backlight.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_backlight.c	2010-05-16 17:17:36.000000000 -0400
@@ -89,19 +89,21 @@ static struct backlight_ops nv50_bl_ops
 
 static int nouveau_nv40_backlight_init(struct drm_device *dev)
 {
+	struct backlight_properties props;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct backlight_device *bd;
 
 	if (!(nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK))
 		return 0;
 
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = 31;
 	bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev,
-				       &nv40_bl_ops);
+				       &nv40_bl_ops, &props);
 	if (IS_ERR(bd))
 		return PTR_ERR(bd);
 
 	dev_priv->backlight = bd;
-	bd->props.max_brightness = 31;
 	bd->props.brightness = nv40_get_intensity(bd);
 	backlight_update_status(bd);
 
@@ -110,19 +112,21 @@ static int nouveau_nv40_backlight_init(s
 
 static int nouveau_nv50_backlight_init(struct drm_device *dev)
 {
+	struct backlight_properties props;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct backlight_device *bd;
 
 	if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT))
 		return 0;
 
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = 1025;
 	bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev,
-				       &nv50_bl_ops);
+				       &nv50_bl_ops, &props);
 	if (IS_ERR(bd))
 		return PTR_ERR(bd);
 
 	dev_priv->backlight = bd;
-	bd->props.max_brightness = 1025;
 	bd->props.brightness = nv50_get_intensity(bd);
 	backlight_update_status(bd);
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.c	2010-05-16 17:17:36.000000000 -0400
@@ -311,11 +311,11 @@ valid_reg(struct nvbios *bios, uint32_t
 
 	/* C51 has misaligned regs on purpose. Marvellous */
 	if (reg & 0x2 ||
-	    (reg & 0x1 && dev_priv->VBIOS.pub.chip_version != 0x51))
+	    (reg & 0x1 && dev_priv->vbios.chip_version != 0x51))
 		NV_ERROR(dev, "======= misaligned reg 0x%08X =======\n", reg);
 
 	/* warn on C51 regs that haven't been verified accessible in tracing */
-	if (reg & 0x1 && dev_priv->VBIOS.pub.chip_version == 0x51 &&
+	if (reg & 0x1 && dev_priv->vbios.chip_version == 0x51 &&
 	    reg != 0x130d && reg != 0x1311 && reg != 0x60081d)
 		NV_WARN(dev, "=== C51 misaligned reg 0x%08X not verified ===\n",
 			reg);
@@ -420,7 +420,7 @@ bios_wr32(struct nvbios *bios, uint32_t
 	LOG_OLD_VALUE(bios_rd32(bios, reg));
 	BIOSLOG(bios, "	Write: Reg: 0x%08X, Data: 0x%08X\n", reg, data);
 
-	if (dev_priv->VBIOS.execute) {
+	if (dev_priv->vbios.execute) {
 		still_alive();
 		nv_wr32(bios->dev, reg, data);
 	}
@@ -647,7 +647,7 @@ nv50_pll_set(struct drm_device *dev, uin
 	reg0 = (reg0 & 0xfff8ffff) | (pll.log2P << 16);
 	reg1 = (reg1 & 0xffff0000) | (pll.N1 << 8) | pll.M1;
 
-	if (dev_priv->VBIOS.execute) {
+	if (dev_priv->vbios.execute) {
 		still_alive();
 		nv_wr32(dev, reg + 4, reg1);
 		nv_wr32(dev, reg + 0, reg0);
@@ -689,7 +689,7 @@ setPLL(struct nvbios *bios, uint32_t reg
 static int dcb_entry_idx_from_crtchead(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 
 	/*
 	 * For the results of this function to be correct, CR44 must have been
@@ -700,7 +700,7 @@ static int dcb_entry_idx_from_crtchead(s
 
 	uint8_t dcb_entry = NVReadVgaCrtc5758(dev, bios->state.crtchead, 0);
 
-	if (dcb_entry > bios->bdcb.dcb.entries) {
+	if (dcb_entry > bios->dcb.entries) {
 		NV_ERROR(dev, "CR58 doesn't have a valid DCB entry currently "
 				"(%02X)\n", dcb_entry);
 		dcb_entry = 0x7f;	/* unused / invalid marker */
@@ -713,25 +713,26 @@ static struct nouveau_i2c_chan *
 init_i2c_device_find(struct drm_device *dev, int i2c_index)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct bios_parsed_dcb *bdcb = &dev_priv->VBIOS.bdcb;
+	struct dcb_table *dcb = &dev_priv->vbios.dcb;
 
 	if (i2c_index == 0xff) {
 		/* note: dcb_entry_idx_from_crtchead needs pre-script set-up */
 		int idx = dcb_entry_idx_from_crtchead(dev), shift = 0;
-		int default_indices = bdcb->i2c_default_indices;
+		int default_indices = dcb->i2c_default_indices;
 
-		if (idx != 0x7f && bdcb->dcb.entry[idx].i2c_upper_default)
+		if (idx != 0x7f && dcb->entry[idx].i2c_upper_default)
 			shift = 4;
 
 		i2c_index = (default_indices >> shift) & 0xf;
 	}
 	if (i2c_index == 0x80)	/* g80+ */
-		i2c_index = bdcb->i2c_default_indices & 0xf;
+		i2c_index = dcb->i2c_default_indices & 0xf;
 
 	return nouveau_i2c_find(dev, i2c_index);
 }
 
-static uint32_t get_tmds_index_reg(struct drm_device *dev, uint8_t mlv)
+static uint32_t
+get_tmds_index_reg(struct drm_device *dev, uint8_t mlv)
 {
 	/*
 	 * For mlv < 0x80, it is an index into a table of TMDS base addresses.
@@ -744,6 +745,7 @@ static uint32_t get_tmds_index_reg(struc
 	 */
 
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->vbios;
 	const int pramdac_offset[13] = {
 		0, 0, 0x8, 0, 0x2000, 0, 0, 0, 0x2008, 0, 0, 0, 0x2000 };
 	const uint32_t pramdac_table[4] = {
@@ -756,13 +758,12 @@ static uint32_t get_tmds_index_reg(struc
 		dcb_entry = dcb_entry_idx_from_crtchead(dev);
 		if (dcb_entry == 0x7f)
 			return 0;
-		dacoffset = pramdac_offset[
-				dev_priv->VBIOS.bdcb.dcb.entry[dcb_entry].or];
+		dacoffset = pramdac_offset[bios->dcb.entry[dcb_entry].or];
 		if (mlv == 0x81)
 			dacoffset ^= 8;
 		return 0x6808b0 + dacoffset;
 	} else {
-		if (mlv > ARRAY_SIZE(pramdac_table)) {
+		if (mlv >= ARRAY_SIZE(pramdac_table)) {
 			NV_ERROR(dev, "Magic Lookup Value too big (%02X)\n",
 									mlv);
 			return 0;
@@ -2572,48 +2573,34 @@ init_gpio(struct nvbios *bios, uint16_t
 	 * each GPIO according to various values listed in each entry
 	 */
 
-	const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
 	const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
-	const uint8_t *gpio_table = &bios->data[bios->bdcb.gpio_table_ptr];
-	const uint8_t *gpio_entry;
 	int i;
 
-	if (!iexec->execute)
-		return 1;
-
-	if (bios->bdcb.version != 0x40) {
-		NV_ERROR(bios->dev, "DCB table not version 4.0\n");
-		return 0;
-	}
-
-	if (!bios->bdcb.gpio_table_ptr) {
-		NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n");
-		return 0;
+	if (dev_priv->card_type != NV_50) {
+		NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n");
+		return -ENODEV;
 	}
 
-	gpio_entry = gpio_table + gpio_table[1];
-	for (i = 0; i < gpio_table[2]; i++, gpio_entry += gpio_table[3]) {
-		uint32_t entry = ROM32(gpio_entry[0]), r, s, v;
-		int line = (entry & 0x0000001f);
+	if (!iexec->execute)
+		return 1;
 
-		BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, entry);
+	for (i = 0; i < bios->dcb.gpio.entries; i++) {
+		struct dcb_gpio_entry *gpio = &bios->dcb.gpio.entry[i];
+		uint32_t r, s, v;
 
-		if ((entry & 0x0000ff00) == 0x0000ff00)
-			continue;
+		BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry);
 
-		r = nv50_gpio_reg[line >> 3];
-		s = (line & 0x07) << 2;
-		v = bios_rd32(bios, r) & ~(0x00000003 << s);
-		if (entry & 0x01000000)
-			v |= (((entry & 0x60000000) >> 29) ^ 2) << s;
-		else
-			v |= (((entry & 0x18000000) >> 27) ^ 2) << s;
-		bios_wr32(bios, r, v);
+		nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default);
 
-		r = nv50_gpio_ctl[line >> 4];
-		s = (line & 0x0f);
+		/* The NVIDIA binary driver doesn't appear to actually do
+		 * any of this, my VBIOS does however.
+		 */
+		/* Not a clue, needs de-magicing */
+		r = nv50_gpio_ctl[gpio->line >> 4];
+		s = (gpio->line & 0x0f);
 		v = bios_rd32(bios, r) & ~(0x00010001 << s);
-		switch ((entry & 0x06000000) >> 25) {
+		switch ((gpio->entry & 0x06000000) >> 25) {
 		case 1:
 			v |= (0x00000001 << s);
 			break;
@@ -3123,7 +3110,7 @@ run_digital_op_script(struct drm_device
 		      struct dcb_entry *dcbent, int head, bool dl)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	struct init_exec iexec = {true, false};
 
 	NV_TRACE(dev, "0x%04X: Parsing digital output script table\n",
@@ -3140,7 +3127,7 @@ run_digital_op_script(struct drm_device
 static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	uint8_t sub = bios->data[bios->fp.xlated_entry + script] + (bios->fp.link_c_increment && dcbent->or & OUTPUT_C ? 1 : 0);
 	uint16_t scriptofs = ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]);
 
@@ -3194,10 +3181,9 @@ static int run_lvds_table(struct drm_dev
 	 * of a list of pxclks and script pointers.
 	 */
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	unsigned int outputset = (dcbent->or == 4) ? 1 : 0;
 	uint16_t scriptptr = 0, clktable;
-	uint8_t clktableptr = 0;
 
 	/*
 	 * For now we assume version 3.0 table - g80 support will need some
@@ -3216,26 +3202,29 @@ static int run_lvds_table(struct drm_dev
 		scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]);
 		break;
 	case LVDS_RESET:
+		clktable = bios->fp.lvdsmanufacturerpointer + 15;
+		if (dcbent->or == 4)
+			clktable += 8;
+
 		if (dcbent->lvdsconf.use_straps_for_mode) {
 			if (bios->fp.dual_link)
-				clktableptr += 2;
-			if (bios->fp.BITbit1)
-				clktableptr++;
+				clktable += 4;
+			if (bios->fp.if_is_24bit)
+				clktable += 2;
 		} else {
 			/* using EDID */
-			uint8_t fallback = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
-			int fallbackcmpval = (dcbent->or == 4) ? 4 : 1;
+			int cmpval_24bit = (dcbent->or == 4) ? 4 : 1;
 
 			if (bios->fp.dual_link) {
-				clktableptr += 2;
-				fallbackcmpval *= 2;
+				clktable += 4;
+				cmpval_24bit <<= 1;
 			}
-			if (fallbackcmpval & fallback)
-				clktableptr++;
+
+			if (bios->fp.strapless_is_24bit & cmpval_24bit)
+				clktable += 2;
 		}
 
-		/* adding outputset * 8 may not be correct */
-		clktable = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 15 + clktableptr * 2 + outputset * 8]);
+		clktable = ROM16(bios->data[clktable]);
 		if (!clktable) {
 			NV_ERROR(dev, "Pixel clock comparison table not found\n");
 			return -ENOENT;
@@ -3261,7 +3250,7 @@ int call_lvds_script(struct drm_device *
 	 */
 
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	uint8_t lvds_ver = bios->data[bios->fp.lvdsmanufacturerpointer];
 	uint32_t sel_clk_binding, sel_clk;
 	int ret;
@@ -3395,7 +3384,7 @@ static int parse_fp_mode_table(struct dr
 #ifndef __powerpc__
 		NV_ERROR(dev, "Pointer to flat panel table invalid\n");
 #endif
-		bios->pub.digital_min_front_porch = 0x4b;
+		bios->digital_min_front_porch = 0x4b;
 		return 0;
 	}
 
@@ -3428,7 +3417,7 @@ static int parse_fp_mode_table(struct dr
 		 * fptable[4] is the minimum
 		 * RAMDAC_FP_HCRTC -> RAMDAC_FP_HSYNC_START gap
 		 */
-		bios->pub.digital_min_front_porch = fptable[4];
+		bios->digital_min_front_porch = fptable[4];
 		ofs = -7;
 		break;
 	default:
@@ -3467,7 +3456,7 @@ static int parse_fp_mode_table(struct dr
 
 	/* nv4x cards need both a strap value and fpindex of 0xf to use DDC */
 	if (lth.lvds_ver > 0x10)
-		bios->pub.fp_no_ddc = fpstrapping != 0xf || fpindex != 0xf;
+		bios->fp_no_ddc = fpstrapping != 0xf || fpindex != 0xf;
 
 	/*
 	 * If either the strap or xlated fpindex value are 0xf there is no
@@ -3491,7 +3480,7 @@ static int parse_fp_mode_table(struct dr
 bool nouveau_bios_fp_mode(struct drm_device *dev, struct drm_display_mode *mode)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	uint8_t *mode_entry = &bios->data[bios->fp.mode_ptr];
 
 	if (!mode)	/* just checking whether we can produce a mode */
@@ -3544,7 +3533,7 @@ int nouveau_bios_parse_lvds_table(struct
 	 * at which modes should be set up in the dual link style.
 	 *
 	 * Following the header, the BMP (ver 0xa) table has several records,
-	 * indexed by a seperate xlat table, indexed in turn by the fp strap in
+	 * indexed by a separate xlat table, indexed in turn by the fp strap in
 	 * EXTDEV_BOOT. Each record had a config byte, followed by 6 script
 	 * numbers for use by INIT_SUB which controlled panel init and power,
 	 * and finally a dword of ms to sleep between power off and on
@@ -3562,11 +3551,11 @@ int nouveau_bios_parse_lvds_table(struct
 	 * until later, when this function should be called with non-zero pxclk
 	 */
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	int fpstrapping = get_fp_strap(dev, bios), lvdsmanufacturerindex = 0;
 	struct lvdstableheader lth;
 	uint16_t lvdsofs;
-	int ret, chip_version = bios->pub.chip_version;
+	int ret, chip_version = bios->chip_version;
 
 	ret = parse_lvds_manufacturer_table_header(dev, bios, &lth);
 	if (ret)
@@ -3637,37 +3626,40 @@ int nouveau_bios_parse_lvds_table(struct
 		*if_is_24bit = bios->data[lvdsofs] & 16;
 		break;
 	case 0x30:
-		/*
-		 * My money would be on there being a 24 bit interface bit in
-		 * this table, but I have no example of a laptop bios with a
-		 * 24 bit panel to confirm that. Hence we shout loudly if any
-		 * bit other than bit 0 is set (I've not even seen bit 1)
-		 */
-		if (bios->data[lvdsofs] > 1)
-			NV_ERROR(dev,
-				 "You have a very unusual laptop display; please report it\n");
+	case 0x40:
 		/*
 		 * No sign of the "power off for reset" or "reset for panel
 		 * on" bits, but it's safer to assume we should
 		 */
 		bios->fp.power_off_for_reset = true;
 		bios->fp.reset_after_pclk_change = true;
+
 		/*
 		 * It's ok lvdsofs is wrong for nv4x edid case; dual_link is
-		 * over-written, and BITbit1 isn't used
+		 * over-written, and if_is_24bit isn't used
 		 */
 		bios->fp.dual_link = bios->data[lvdsofs] & 1;
-		bios->fp.BITbit1 = bios->data[lvdsofs] & 2;
-		bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
-		break;
-	case 0x40:
-		bios->fp.dual_link = bios->data[lvdsofs] & 1;
 		bios->fp.if_is_24bit = bios->data[lvdsofs] & 2;
 		bios->fp.strapless_is_24bit = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
 		bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
 		break;
 	}
 
+	/* Dell Latitude D620 reports a too-high value for the dual-link
+	 * transition freq, causing us to program the panel incorrectly.
+	 *
+	 * It doesn't appear the VBIOS actually uses its transition freq
+	 * (90000kHz), instead it uses the "Number of LVDS channels" field
+	 * out of the panel ID structure (http://www.spwg.org/).
+	 *
+	 * For the moment, a quirk will do :)
+	 */
+	if ((dev->pdev->device == 0x01d7) &&
+	    (dev->pdev->subsystem_vendor == 0x1028) &&
+	    (dev->pdev->subsystem_device == 0x01c2)) {
+		bios->fp.duallink_transition_clk = 80000;
+	}
+
 	/* set dual_link flag for EDID case */
 	if (pxclk && (chip_version < 0x25 || chip_version > 0x28))
 		bios->fp.dual_link = (pxclk >= bios->fp.duallink_transition_clk);
@@ -3682,7 +3674,7 @@ bios_output_config_match(struct drm_devi
 			 uint16_t record, int record_len, int record_nr)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	uint32_t entry;
 	uint16_t table;
 	int i, v;
@@ -3716,7 +3708,7 @@ nouveau_bios_dp_table(struct drm_device
 		      int *length)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	uint8_t *table;
 
 	if (!bios->display.dp_table_ptr) {
@@ -3725,7 +3717,7 @@ nouveau_bios_dp_table(struct drm_device
 	}
 	table = &bios->data[bios->display.dp_table_ptr];
 
-	if (table[0] != 0x21) {
+	if (table[0] != 0x20 && table[0] != 0x21) {
 		NV_ERROR(dev, "DisplayPort table version 0x%02x unknown\n",
 			 table[0]);
 		return NULL;
@@ -3765,7 +3757,7 @@ nouveau_bios_run_display_table(struct dr
 	 */
 
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	uint8_t *table = &bios->data[bios->display.script_table_ptr];
 	uint8_t *otable = NULL;
 	uint16_t script;
@@ -3918,8 +3910,8 @@ int run_tmds_table(struct drm_device *de
 	 */
 
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
-	int cv = bios->pub.chip_version;
+	struct nvbios *bios = &dev_priv->vbios;
+	int cv = bios->chip_version;
 	uint16_t clktable = 0, scriptptr;
 	uint32_t sel_clk_binding, sel_clk;
 
@@ -3978,8 +3970,8 @@ int get_pll_limits(struct drm_device *de
 	 */
 
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
-	int cv = bios->pub.chip_version, pllindex = 0;
+	struct nvbios *bios = &dev_priv->vbios;
+	int cv = bios->chip_version, pllindex = 0;
 	uint8_t pll_lim_ver = 0, headerlen = 0, recordlen = 0, entries = 0;
 	uint32_t crystal_strap_mask, crystal_straps;
 
@@ -4332,7 +4324,7 @@ static void parse_bios_version(struct dr
 	 */
 
 	bios->major_version = bios->data[offset + 3];
-	bios->pub.chip_version = bios->data[offset + 2];
+	bios->chip_version = bios->data[offset + 2];
 	NV_TRACE(dev, "Bios version %02x.%02x.%02x.%02x\n",
 		 bios->data[offset + 3], bios->data[offset + 2],
 		 bios->data[offset + 1], bios->data[offset]);
@@ -4402,7 +4394,7 @@ static int parse_bit_A_tbl_entry(struct
 	}
 
 	/* First entry is normal dac, 2nd tv-out perhaps? */
-	bios->pub.dactestval = ROM32(bios->data[load_table_ptr + headerlen]) & 0x3ff;
+	bios->dactestval = ROM32(bios->data[load_table_ptr + headerlen]) & 0x3ff;
 
 	return 0;
 }
@@ -4526,8 +4518,8 @@ static int parse_bit_i_tbl_entry(struct
 		return -ENOSYS;
 	}
 
-	bios->pub.dactestval = ROM32(bios->data[daccmpoffset + dacheaderlen]);
-	bios->pub.tvdactestval = ROM32(bios->data[daccmpoffset + dacheaderlen + 4]);
+	bios->dactestval = ROM32(bios->data[daccmpoffset + dacheaderlen]);
+	bios->tvdactestval = ROM32(bios->data[daccmpoffset + dacheaderlen + 4]);
 
 	return 0;
 }
@@ -4796,11 +4788,11 @@ static int parse_bmp_structure(struct dr
 	uint16_t legacy_scripts_offset, legacy_i2c_offset;
 
 	/* load needed defaults in case we can't parse this info */
-	bios->bdcb.dcb.i2c[0].write = NV_CIO_CRE_DDC_WR__INDEX;
-	bios->bdcb.dcb.i2c[0].read = NV_CIO_CRE_DDC_STATUS__INDEX;
-	bios->bdcb.dcb.i2c[1].write = NV_CIO_CRE_DDC0_WR__INDEX;
-	bios->bdcb.dcb.i2c[1].read = NV_CIO_CRE_DDC0_STATUS__INDEX;
-	bios->pub.digital_min_front_porch = 0x4b;
+	bios->dcb.i2c[0].write = NV_CIO_CRE_DDC_WR__INDEX;
+	bios->dcb.i2c[0].read = NV_CIO_CRE_DDC_STATUS__INDEX;
+	bios->dcb.i2c[1].write = NV_CIO_CRE_DDC0_WR__INDEX;
+	bios->dcb.i2c[1].read = NV_CIO_CRE_DDC0_STATUS__INDEX;
+	bios->digital_min_front_porch = 0x4b;
 	bios->fmaxvco = 256000;
 	bios->fminvco = 128000;
 	bios->fp.duallink_transition_clk = 90000;
@@ -4907,10 +4899,10 @@ static int parse_bmp_structure(struct dr
 	bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset];
 	bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1];
 	bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2];
-	bios->bdcb.dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4];
-	bios->bdcb.dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5];
-	bios->bdcb.dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6];
-	bios->bdcb.dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7];
+	bios->dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4];
+	bios->dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5];
+	bios->dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6];
+	bios->dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7];
 
 	if (bmplength > 74) {
 		bios->fmaxvco = ROM32(bmp[67]);
@@ -4984,7 +4976,8 @@ read_dcb_i2c_entry(struct drm_device *de
 		else
 			NV_WARN(dev,
 				"DCB I2C table has more entries than indexable "
-				"(%d entries, max index 15)\n", i2ctable[2]);
+				"(%d entries, max %d)\n", i2ctable[2],
+				DCB_MAX_NUM_I2C_ENTRIES);
 		entry_len = i2ctable[3];
 		/* [4] is i2c_default_indices, read in parse_dcb_table() */
 	}
@@ -5000,8 +4993,8 @@ read_dcb_i2c_entry(struct drm_device *de
 
 	if (index == 0xf)
 		return 0;
-	if (index > i2c_entries) {
-		NV_ERROR(dev, "DCB I2C index too big (%d > %d)\n",
+	if (index >= i2c_entries) {
+		NV_ERROR(dev, "DCB I2C index too big (%d >= %d)\n",
 			 index, i2ctable[2]);
 		return -ENOENT;
 	}
@@ -5036,7 +5029,7 @@ read_dcb_i2c_entry(struct drm_device *de
 static struct dcb_gpio_entry *
 new_gpio_entry(struct nvbios *bios)
 {
-	struct parsed_dcb_gpio *gpio = &bios->bdcb.gpio;
+	struct dcb_gpio_table *gpio = &bios->dcb.gpio;
 
 	return &gpio->entry[gpio->entries++];
 }
@@ -5045,14 +5038,14 @@ struct dcb_gpio_entry *
 nouveau_bios_gpio_entry(struct drm_device *dev, enum dcb_gpio_tag tag)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	int i;
 
-	for (i = 0; i < bios->bdcb.gpio.entries; i++) {
-		if (bios->bdcb.gpio.entry[i].tag != tag)
+	for (i = 0; i < bios->dcb.gpio.entries; i++) {
+		if (bios->dcb.gpio.entry[i].tag != tag)
 			continue;
 
-		return &bios->bdcb.gpio.entry[i];
+		return &bios->dcb.gpio.entry[i];
 	}
 
 	return NULL;
@@ -5075,32 +5068,32 @@ parse_dcb30_gpio_entry(struct nvbios *bi
 	gpio->tag = tag;
 	gpio->line = line;
 	gpio->invert = flags != 4;
+	gpio->entry = ent;
 }
 
 static void
 parse_dcb40_gpio_entry(struct nvbios *bios, uint16_t offset)
 {
+	uint32_t entry = ROM32(bios->data[offset]);
 	struct dcb_gpio_entry *gpio;
-	uint32_t ent = ROM32(bios->data[offset]);
-	uint8_t line = ent & 0x1f,
-		tag = ent >> 8 & 0xff;
 
-	if (tag == 0xff)
+	if ((entry & 0x0000ff00) == 0x0000ff00)
 		return;
 
 	gpio = new_gpio_entry(bios);
-
-	/* Currently unused, we may need more fields parsed at some
-	 * point. */
-	gpio->tag = tag;
-	gpio->line = line;
+	gpio->tag = (entry & 0x0000ff00) >> 8;
+	gpio->line = (entry & 0x0000001f) >> 0;
+	gpio->state_default = (entry & 0x01000000) >> 24;
+	gpio->state[0] = (entry & 0x18000000) >> 27;
+	gpio->state[1] = (entry & 0x60000000) >> 29;
+	gpio->entry = entry;
 }
 
 static void
 parse_dcb_gpio_table(struct nvbios *bios)
 {
 	struct drm_device *dev = bios->dev;
-	uint16_t gpio_table_ptr = bios->bdcb.gpio_table_ptr;
+	uint16_t gpio_table_ptr = bios->dcb.gpio_table_ptr;
 	uint8_t *gpio_table = &bios->data[gpio_table_ptr];
 	int header_len = gpio_table[1],
 	    entries = gpio_table[2],
@@ -5108,7 +5101,7 @@ parse_dcb_gpio_table(struct nvbios *bios
 	void (*parse_entry)(struct nvbios *, uint16_t) = NULL;
 	int i;
 
-	if (bios->bdcb.version >= 0x40) {
+	if (bios->dcb.version >= 0x40) {
 		if (gpio_table_ptr && entry_len != 4) {
 			NV_WARN(dev, "Invalid DCB GPIO table entry length.\n");
 			return;
@@ -5116,7 +5109,7 @@ parse_dcb_gpio_table(struct nvbios *bios
 
 		parse_entry = parse_dcb40_gpio_entry;
 
-	} else if (bios->bdcb.version >= 0x30) {
+	} else if (bios->dcb.version >= 0x30) {
 		if (gpio_table_ptr && entry_len != 2) {
 			NV_WARN(dev, "Invalid DCB GPIO table entry length.\n");
 			return;
@@ -5124,7 +5117,7 @@ parse_dcb_gpio_table(struct nvbios *bios
 
 		parse_entry = parse_dcb30_gpio_entry;
 
-	} else if (bios->bdcb.version >= 0x22) {
+	} else if (bios->dcb.version >= 0x22) {
 		/*
 		 * DCBs older than v3.0 don't really have a GPIO
 		 * table, instead they keep some GPIO info at fixed
@@ -5158,30 +5151,82 @@ struct dcb_connector_table_entry *
 nouveau_bios_connector_entry(struct drm_device *dev, int index)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	struct dcb_connector_table_entry *cte;
 
-	if (index >= bios->bdcb.connector.entries)
+	if (index >= bios->dcb.connector.entries)
 		return NULL;
 
-	cte = &bios->bdcb.connector.entry[index];
+	cte = &bios->dcb.connector.entry[index];
 	if (cte->type == 0xff)
 		return NULL;
 
 	return cte;
 }
 
+static enum dcb_connector_type
+divine_connector_type(struct nvbios *bios, int index)
+{
+	struct dcb_table *dcb = &bios->dcb;
+	unsigned encoders = 0, type = DCB_CONNECTOR_NONE;
+	int i;
+
+	for (i = 0; i < dcb->entries; i++) {
+		if (dcb->entry[i].connector == index)
+			encoders |= (1 << dcb->entry[i].type);
+	}
+
+	if (encoders & (1 << OUTPUT_DP)) {
+		if (encoders & (1 << OUTPUT_TMDS))
+			type = DCB_CONNECTOR_DP;
+		else
+			type = DCB_CONNECTOR_eDP;
+	} else
+	if (encoders & (1 << OUTPUT_TMDS)) {
+		if (encoders & (1 << OUTPUT_ANALOG))
+			type = DCB_CONNECTOR_DVI_I;
+		else
+			type = DCB_CONNECTOR_DVI_D;
+	} else
+	if (encoders & (1 << OUTPUT_ANALOG)) {
+		type = DCB_CONNECTOR_VGA;
+	} else
+	if (encoders & (1 << OUTPUT_LVDS)) {
+		type = DCB_CONNECTOR_LVDS;
+	} else
+	if (encoders & (1 << OUTPUT_TV)) {
+		type = DCB_CONNECTOR_TV_0;
+	}
+
+	return type;
+}
+
+static void
+apply_dcb_connector_quirks(struct nvbios *bios, int idx)
+{
+	struct dcb_connector_table_entry *cte = &bios->dcb.connector.entry[idx];
+	struct drm_device *dev = bios->dev;
+
+	/* Gigabyte NX85T */
+	if ((dev->pdev->device == 0x0421) &&
+	    (dev->pdev->subsystem_vendor == 0x1458) &&
+	    (dev->pdev->subsystem_device == 0x344c)) {
+		if (cte->type == DCB_CONNECTOR_HDMI_1)
+			cte->type = DCB_CONNECTOR_DVI_I;
+	}
+}
+
 static void
 parse_dcb_connector_table(struct nvbios *bios)
 {
 	struct drm_device *dev = bios->dev;
-	struct dcb_connector_table *ct = &bios->bdcb.connector;
+	struct dcb_connector_table *ct = &bios->dcb.connector;
 	struct dcb_connector_table_entry *cte;
-	uint8_t *conntab = &bios->data[bios->bdcb.connector_table_ptr];
+	uint8_t *conntab = &bios->data[bios->dcb.connector_table_ptr];
 	uint8_t *entry;
 	int i;
 
-	if (!bios->bdcb.connector_table_ptr) {
+	if (!bios->dcb.connector_table_ptr) {
 		NV_DEBUG_KMS(dev, "No DCB connector table present\n");
 		return;
 	}
@@ -5199,12 +5244,14 @@ parse_dcb_connector_table(struct nvbios
 	entry = conntab + conntab[1];
 	cte = &ct->entry[0];
 	for (i = 0; i < conntab[2]; i++, entry += conntab[3], cte++) {
+		cte->index = i;
 		if (conntab[3] == 2)
 			cte->entry = ROM16(entry[0]);
 		else
 			cte->entry = ROM32(entry[0]);
+
 		cte->type  = (cte->entry & 0x000000ff) >> 0;
-		cte->index = (cte->entry & 0x00000f00) >> 8;
+		cte->index2 = (cte->entry & 0x00000f00) >> 8;
 		switch (cte->entry & 0x00033000) {
 		case 0x00001000:
 			cte->gpio_tag = 0x07;
@@ -5226,12 +5273,43 @@ parse_dcb_connector_table(struct nvbios
 		if (cte->type == 0xff)
 			continue;
 
+		apply_dcb_connector_quirks(bios, i);
+
 		NV_INFO(dev, "  %d: 0x%08x: type 0x%02x idx %d tag 0x%02x\n",
 			i, cte->entry, cte->type, cte->index, cte->gpio_tag);
+
+		/* check for known types, fallback to guessing the type
+		 * from attached encoders if we hit an unknown.
+		 */
+		switch (cte->type) {
+		case DCB_CONNECTOR_VGA:
+		case DCB_CONNECTOR_TV_0:
+		case DCB_CONNECTOR_TV_1:
+		case DCB_CONNECTOR_TV_3:
+		case DCB_CONNECTOR_DVI_I:
+		case DCB_CONNECTOR_DVI_D:
+		case DCB_CONNECTOR_LVDS:
+		case DCB_CONNECTOR_DP:
+		case DCB_CONNECTOR_eDP:
+		case DCB_CONNECTOR_HDMI_0:
+		case DCB_CONNECTOR_HDMI_1:
+			break;
+		default:
+			cte->type = divine_connector_type(bios, cte->index);
+			NV_WARN(dev, "unknown type, using 0x%02x\n", cte->type);
+			break;
+		}
+
+		if (nouveau_override_conntype) {
+			int type = divine_connector_type(bios, cte->index);
+			if (type != cte->type)
+				NV_WARN(dev, " -> type 0x%02x\n", cte->type);
+		}
+
 	}
 }
 
-static struct dcb_entry *new_dcb_entry(struct parsed_dcb *dcb)
+static struct dcb_entry *new_dcb_entry(struct dcb_table *dcb)
 {
 	struct dcb_entry *entry = &dcb->entry[dcb->entries];
 
@@ -5241,7 +5319,7 @@ static struct dcb_entry *new_dcb_entry(s
 	return entry;
 }
 
-static void fabricate_vga_output(struct parsed_dcb *dcb, int i2c, int heads)
+static void fabricate_vga_output(struct dcb_table *dcb, int i2c, int heads)
 {
 	struct dcb_entry *entry = new_dcb_entry(dcb);
 
@@ -5252,7 +5330,7 @@ static void fabricate_vga_output(struct
 	/* "or" mostly unused in early gen crt modesetting, 0 is fine */
 }
 
-static void fabricate_dvi_i_output(struct parsed_dcb *dcb, bool twoHeads)
+static void fabricate_dvi_i_output(struct dcb_table *dcb, bool twoHeads)
 {
 	struct dcb_entry *entry = new_dcb_entry(dcb);
 
@@ -5279,7 +5357,7 @@ static void fabricate_dvi_i_output(struc
 #endif
 }
 
-static void fabricate_tv_output(struct parsed_dcb *dcb, bool twoHeads)
+static void fabricate_tv_output(struct dcb_table *dcb, bool twoHeads)
 {
 	struct dcb_entry *entry = new_dcb_entry(dcb);
 
@@ -5290,13 +5368,13 @@ static void fabricate_tv_output(struct p
 }
 
 static bool
-parse_dcb20_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb,
+parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
 		  uint32_t conn, uint32_t conf, struct dcb_entry *entry)
 {
 	entry->type = conn & 0xf;
 	entry->i2c_index = (conn >> 4) & 0xf;
 	entry->heads = (conn >> 8) & 0xf;
-	if (bdcb->version >= 0x40)
+	if (dcb->version >= 0x40)
 		entry->connector = (conn >> 12) & 0xf;
 	entry->bus = (conn >> 16) & 0xf;
 	entry->location = (conn >> 20) & 0x3;
@@ -5314,7 +5392,7 @@ parse_dcb20_entry(struct drm_device *dev
 		 * Although the rest of a CRT conf dword is usually
 		 * zeros, mac biosen have stuff there so we must mask
 		 */
-		entry->crtconf.maxfreq = (bdcb->version < 0x30) ?
+		entry->crtconf.maxfreq = (dcb->version < 0x30) ?
 					 (conf & 0xffff) * 10 :
 					 (conf & 0xff) * 10000;
 		break;
@@ -5323,7 +5401,7 @@ parse_dcb20_entry(struct drm_device *dev
 		uint32_t mask;
 		if (conf & 0x1)
 			entry->lvdsconf.use_straps_for_mode = true;
-		if (bdcb->version < 0x22) {
+		if (dcb->version < 0x22) {
 			mask = ~0xd;
 			/*
 			 * The laptop in bug 14567 lies and claims to not use
@@ -5347,7 +5425,7 @@ parse_dcb20_entry(struct drm_device *dev
 			 * Until we even try to use these on G8x, it's
 			 * useless reporting unknown bits.  They all are.
 			 */
-			if (bdcb->version >= 0x40)
+			if (dcb->version >= 0x40)
 				break;
 
 			NV_ERROR(dev, "Unknown LVDS configuration bits, "
@@ -5357,7 +5435,7 @@ parse_dcb20_entry(struct drm_device *dev
 		}
 	case OUTPUT_TV:
 	{
-		if (bdcb->version >= 0x30)
+		if (dcb->version >= 0x30)
 			entry->tvconf.has_component_output = conf & (0x8 << 4);
 		else
 			entry->tvconf.has_component_output = false;
@@ -5384,8 +5462,10 @@ parse_dcb20_entry(struct drm_device *dev
 		break;
 	case 0xe:
 		/* weird g80 mobile type that "nv" treats as a terminator */
-		bdcb->dcb.entries--;
+		dcb->entries--;
 		return false;
+	default:
+		break;
 	}
 
 	/* unsure what DCB version introduces this, 3.0? */
@@ -5396,7 +5476,7 @@ parse_dcb20_entry(struct drm_device *dev
 }
 
 static bool
-parse_dcb15_entry(struct drm_device *dev, struct parsed_dcb *dcb,
+parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb,
 		  uint32_t conn, uint32_t conf, struct dcb_entry *entry)
 {
 	switch (conn & 0x0000000f) {
@@ -5462,27 +5542,27 @@ parse_dcb15_entry(struct drm_device *dev
 	return true;
 }
 
-static bool parse_dcb_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb,
+static bool parse_dcb_entry(struct drm_device *dev, struct dcb_table *dcb,
 			    uint32_t conn, uint32_t conf)
 {
-	struct dcb_entry *entry = new_dcb_entry(&bdcb->dcb);
+	struct dcb_entry *entry = new_dcb_entry(dcb);
 	bool ret;
 
-	if (bdcb->version >= 0x20)
-		ret = parse_dcb20_entry(dev, bdcb, conn, conf, entry);
+	if (dcb->version >= 0x20)
+		ret = parse_dcb20_entry(dev, dcb, conn, conf, entry);
 	else
-		ret = parse_dcb15_entry(dev, &bdcb->dcb, conn, conf, entry);
+		ret = parse_dcb15_entry(dev, dcb, conn, conf, entry);
 	if (!ret)
 		return ret;
 
-	read_dcb_i2c_entry(dev, bdcb->version, bdcb->i2c_table,
-			   entry->i2c_index, &bdcb->dcb.i2c[entry->i2c_index]);
+	read_dcb_i2c_entry(dev, dcb->version, dcb->i2c_table,
+			   entry->i2c_index, &dcb->i2c[entry->i2c_index]);
 
 	return true;
 }
 
 static
-void merge_like_dcb_entries(struct drm_device *dev, struct parsed_dcb *dcb)
+void merge_like_dcb_entries(struct drm_device *dev, struct dcb_table *dcb)
 {
 	/*
 	 * DCB v2.0 lists each output combination separately.
@@ -5534,8 +5614,7 @@ static int
 parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct bios_parsed_dcb *bdcb = &bios->bdcb;
-	struct parsed_dcb *dcb;
+	struct dcb_table *dcb = &bios->dcb;
 	uint16_t dcbptr = 0, i2ctabptr = 0;
 	uint8_t *dcbtable;
 	uint8_t headerlen = 0x4, entries = DCB_MAX_NUM_ENTRIES;
@@ -5543,9 +5622,6 @@ parse_dcb_table(struct drm_device *dev,
 	int recordlength = 8, confofs = 4;
 	int i;
 
-	dcb = bios->pub.dcb = &bdcb->dcb;
-	dcb->entries = 0;
-
 	/* get the offset from 0x36 */
 	if (dev_priv->card_type > NV_04) {
 		dcbptr = ROM16(bios->data[0x36]);
@@ -5567,21 +5643,21 @@ parse_dcb_table(struct drm_device *dev,
 	dcbtable = &bios->data[dcbptr];
 
 	/* get DCB version */
-	bdcb->version = dcbtable[0];
+	dcb->version = dcbtable[0];
 	NV_TRACE(dev, "Found Display Configuration Block version %d.%d\n",
-		 bdcb->version >> 4, bdcb->version & 0xf);
+		 dcb->version >> 4, dcb->version & 0xf);
 
-	if (bdcb->version >= 0x20) { /* NV17+ */
+	if (dcb->version >= 0x20) { /* NV17+ */
 		uint32_t sig;
 
-		if (bdcb->version >= 0x30) { /* NV40+ */
+		if (dcb->version >= 0x30) { /* NV40+ */
 			headerlen = dcbtable[1];
 			entries = dcbtable[2];
 			recordlength = dcbtable[3];
 			i2ctabptr = ROM16(dcbtable[4]);
 			sig = ROM32(dcbtable[6]);
-			bdcb->gpio_table_ptr = ROM16(dcbtable[10]);
-			bdcb->connector_table_ptr = ROM16(dcbtable[20]);
+			dcb->gpio_table_ptr = ROM16(dcbtable[10]);
+			dcb->connector_table_ptr = ROM16(dcbtable[20]);
 		} else {
 			i2ctabptr = ROM16(dcbtable[2]);
 			sig = ROM32(dcbtable[4]);
@@ -5593,7 +5669,7 @@ parse_dcb_table(struct drm_device *dev,
 					"signature (%08X)\n", sig);
 			return -EINVAL;
 		}
-	} else if (bdcb->version >= 0x15) { /* some NV11 and NV20 */
+	} else if (dcb->version >= 0x15) { /* some NV11 and NV20 */
 		char sig[8] = { 0 };
 
 		strncpy(sig, (char *)&dcbtable[-7], 7);
@@ -5641,14 +5717,11 @@ parse_dcb_table(struct drm_device *dev,
 	if (!i2ctabptr)
 		NV_WARN(dev, "No pointer to DCB I2C port table\n");
 	else {
-		bdcb->i2c_table = &bios->data[i2ctabptr];
-		if (bdcb->version >= 0x30)
-			bdcb->i2c_default_indices = bdcb->i2c_table[4];
+		dcb->i2c_table = &bios->data[i2ctabptr];
+		if (dcb->version >= 0x30)
+			dcb->i2c_default_indices = dcb->i2c_table[4];
 	}
 
-	parse_dcb_gpio_table(bios);
-	parse_dcb_connector_table(bios);
-
 	if (entries > DCB_MAX_NUM_ENTRIES)
 		entries = DCB_MAX_NUM_ENTRIES;
 
@@ -5673,7 +5746,7 @@ parse_dcb_table(struct drm_device *dev,
 		NV_TRACEWARN(dev, "Raw DCB entry %d: %08x %08x\n",
 			     dcb->entries, connection, config);
 
-		if (!parse_dcb_entry(dev, bdcb, connection, config))
+		if (!parse_dcb_entry(dev, dcb, connection, config))
 			break;
 	}
 
@@ -5681,18 +5754,22 @@ parse_dcb_table(struct drm_device *dev,
 	 * apart for v2.1+ not being known for requiring merging, this
 	 * guarantees dcbent->index is the index of the entry in the rom image
 	 */
-	if (bdcb->version < 0x21)
+	if (dcb->version < 0x21)
 		merge_like_dcb_entries(dev, dcb);
 
-	return dcb->entries ? 0 : -ENXIO;
+	if (!dcb->entries)
+		return -ENXIO;
+
+	parse_dcb_gpio_table(bios);
+	parse_dcb_connector_table(bios);
+	return 0;
 }
 
 static void
 fixup_legacy_connector(struct nvbios *bios)
 {
-	struct bios_parsed_dcb *bdcb = &bios->bdcb;
-	struct parsed_dcb *dcb = &bdcb->dcb;
-	int high = 0, i;
+	struct dcb_table *dcb = &bios->dcb;
+	int i, i2c, i2c_conn[DCB_MAX_NUM_I2C_ENTRIES] = { };
 
 	/*
 	 * DCB 3.0 also has the table in most cases, but there are some cards
@@ -5700,9 +5777,11 @@ fixup_legacy_connector(struct nvbios *bi
 	 * indices are all 0.  We don't need the connector indices on pre-G80
 	 * chips (yet?) so limit the use to DCB 4.0 and above.
 	 */
-	if (bdcb->version >= 0x40)
+	if (dcb->version >= 0x40)
 		return;
 
+	dcb->connector.entries = 0;
+
 	/*
 	 * No known connector info before v3.0, so make it up.  the rule here
 	 * is: anything on the same i2c bus is considered to be on the same
@@ -5710,37 +5789,38 @@ fixup_legacy_connector(struct nvbios *bi
 	 * its own unique connector index.
 	 */
 	for (i = 0; i < dcb->entries; i++) {
-		if (dcb->entry[i].i2c_index == 0xf)
-			continue;
-
 		/*
 		 * Ignore the I2C index for on-chip TV-out, as there
 		 * are cards with bogus values (nv31m in bug 23212),
 		 * and it's otherwise useless.
 		 */
 		if (dcb->entry[i].type == OUTPUT_TV &&
-		    dcb->entry[i].location == DCB_LOC_ON_CHIP) {
+		    dcb->entry[i].location == DCB_LOC_ON_CHIP)
 			dcb->entry[i].i2c_index = 0xf;
+		i2c = dcb->entry[i].i2c_index;
+
+		if (i2c_conn[i2c]) {
+			dcb->entry[i].connector = i2c_conn[i2c] - 1;
 			continue;
 		}
 
-		dcb->entry[i].connector = dcb->entry[i].i2c_index;
-		if (dcb->entry[i].connector > high)
-			high = dcb->entry[i].connector;
+		dcb->entry[i].connector = dcb->connector.entries++;
+		if (i2c != 0xf)
+			i2c_conn[i2c] = dcb->connector.entries;
 	}
 
-	for (i = 0; i < dcb->entries; i++) {
-		if (dcb->entry[i].i2c_index != 0xf)
-			continue;
-
-		dcb->entry[i].connector = ++high;
+	/* Fake the connector table as well as just connector indices */
+	for (i = 0; i < dcb->connector.entries; i++) {
+		dcb->connector.entry[i].index = i;
+		dcb->connector.entry[i].type = divine_connector_type(bios, i);
+		dcb->connector.entry[i].gpio_tag = 0xff;
 	}
 }
 
 static void
 fixup_legacy_i2c(struct nvbios *bios)
 {
-	struct parsed_dcb *dcb = &bios->bdcb.dcb;
+	struct dcb_table *dcb = &bios->dcb;
 	int i;
 
 	for (i = 0; i < dcb->entries; i++) {
@@ -5826,7 +5906,7 @@ static int load_nv17_hw_sequencer_ucode(
 uint8_t *nouveau_bios_embedded_edid(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	const uint8_t edid_sig[] = {
 			0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
 	uint16_t offset = 0;
@@ -5859,7 +5939,7 @@ nouveau_bios_run_init_table(struct drm_d
 			    struct dcb_entry *dcbent)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	struct init_exec iexec = { true, false };
 
 	mutex_lock(&bios->lock);
@@ -5872,7 +5952,7 @@ nouveau_bios_run_init_table(struct drm_d
 static bool NVInitVBIOS(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 
 	memset(bios, 0, sizeof(struct nvbios));
 	mutex_init(&bios->lock);
@@ -5888,7 +5968,7 @@ static bool NVInitVBIOS(struct drm_devic
 static int nouveau_parse_vbios_struct(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	const uint8_t bit_signature[] = { 0xff, 0xb8, 'B', 'I', 'T' };
 	const uint8_t bmp_signature[] = { 0xff, 0x7f, 'N', 'V', 0x0 };
 	int offset;
@@ -5915,7 +5995,7 @@ int
 nouveau_run_vbios_init(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	int i, ret = 0;
 
 	NVLockVgaCrtcs(dev, false);
@@ -5946,9 +6026,9 @@ nouveau_run_vbios_init(struct drm_device
 	}
 
 	if (dev_priv->card_type >= NV_50) {
-		for (i = 0; i < bios->bdcb.dcb.entries; i++) {
+		for (i = 0; i < bios->dcb.entries; i++) {
 			nouveau_bios_run_display_table(dev,
-						       &bios->bdcb.dcb.entry[i],
+						       &bios->dcb.entry[i],
 						       0, 0);
 		}
 	}
@@ -5962,11 +6042,11 @@ static void
 nouveau_bios_i2c_devices_takedown(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	struct dcb_i2c_entry *entry;
 	int i;
 
-	entry = &bios->bdcb.dcb.i2c[0];
+	entry = &bios->dcb.i2c[0];
 	for (i = 0; i < DCB_MAX_NUM_I2C_ENTRIES; i++, entry++)
 		nouveau_i2c_fini(dev, entry);
 }
@@ -5975,13 +6055,11 @@ int
 nouveau_bios_init(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	uint32_t saved_nv_pextdev_boot_0;
 	bool was_locked;
 	int ret;
 
-	dev_priv->vbios = &bios->pub;
-
 	if (!NVInitVBIOS(dev))
 		return -ENODEV;
 
@@ -6023,10 +6101,8 @@ nouveau_bios_init(struct drm_device *dev
 	bios_wr32(bios, NV_PEXTDEV_BOOT_0, saved_nv_pextdev_boot_0);
 
 	ret = nouveau_run_vbios_init(dev);
-	if (ret) {
-		dev_priv->vbios = NULL;
+	if (ret)
 		return ret;
-	}
 
 	/* feature_byte on BMP is poor, but init always sets CR4B */
 	was_locked = NVLockVgaCrtcs(dev, false);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.h	2010-05-16 17:17:36.000000000 -0400
@@ -34,9 +34,71 @@
 
 #define DCB_LOC_ON_CHIP 0
 
+struct dcb_i2c_entry {
+	uint8_t port_type;
+	uint8_t read, write;
+	struct nouveau_i2c_chan *chan;
+};
+
+enum dcb_gpio_tag {
+	DCB_GPIO_TVDAC0 = 0xc,
+	DCB_GPIO_TVDAC1 = 0x2d,
+};
+
+struct dcb_gpio_entry {
+	enum dcb_gpio_tag tag;
+	int line;
+	bool invert;
+	uint32_t entry;
+	uint8_t state_default;
+	uint8_t state[2];
+};
+
+struct dcb_gpio_table {
+	int entries;
+	struct dcb_gpio_entry entry[DCB_MAX_NUM_GPIO_ENTRIES];
+};
+
+enum dcb_connector_type {
+	DCB_CONNECTOR_VGA = 0x00,
+	DCB_CONNECTOR_TV_0 = 0x10,
+	DCB_CONNECTOR_TV_1 = 0x11,
+	DCB_CONNECTOR_TV_3 = 0x13,
+	DCB_CONNECTOR_DVI_I = 0x30,
+	DCB_CONNECTOR_DVI_D = 0x31,
+	DCB_CONNECTOR_LVDS = 0x40,
+	DCB_CONNECTOR_DP = 0x46,
+	DCB_CONNECTOR_eDP = 0x47,
+	DCB_CONNECTOR_HDMI_0 = 0x60,
+	DCB_CONNECTOR_HDMI_1 = 0x61,
+	DCB_CONNECTOR_NONE = 0xff
+};
+
+struct dcb_connector_table_entry {
+	uint8_t index;
+	uint32_t entry;
+	enum dcb_connector_type type;
+	uint8_t index2;
+	uint8_t gpio_tag;
+};
+
+struct dcb_connector_table {
+	int entries;
+	struct dcb_connector_table_entry entry[DCB_MAX_NUM_CONNECTOR_ENTRIES];
+};
+
+enum dcb_type {
+	OUTPUT_ANALOG = 0,
+	OUTPUT_TV = 1,
+	OUTPUT_TMDS = 2,
+	OUTPUT_LVDS = 3,
+	OUTPUT_DP = 6,
+	OUTPUT_ANY = -1
+};
+
 struct dcb_entry {
 	int index;	/* may not be raw dcb index if merging has happened */
-	uint8_t type;
+	enum dcb_type type;
 	uint8_t i2c_index;
 	uint8_t heads;
 	uint8_t connector;
@@ -71,69 +133,22 @@ struct dcb_entry {
 	bool i2c_upper_default;
 };
 
-struct dcb_i2c_entry {
-	uint8_t port_type;
-	uint8_t read, write;
-	struct nouveau_i2c_chan *chan;
-};
+struct dcb_table {
+	uint8_t version;
 
-struct parsed_dcb {
 	int entries;
 	struct dcb_entry entry[DCB_MAX_NUM_ENTRIES];
-	struct dcb_i2c_entry i2c[DCB_MAX_NUM_I2C_ENTRIES];
-};
-
-enum dcb_gpio_tag {
-	DCB_GPIO_TVDAC0 = 0xc,
-	DCB_GPIO_TVDAC1 = 0x2d,
-};
-
-struct dcb_gpio_entry {
-	enum dcb_gpio_tag tag;
-	int line;
-	bool invert;
-};
-
-struct parsed_dcb_gpio {
-	int entries;
-	struct dcb_gpio_entry entry[DCB_MAX_NUM_GPIO_ENTRIES];
-};
-
-struct dcb_connector_table_entry {
-	uint32_t entry;
-	uint8_t type;
-	uint8_t index;
-	uint8_t gpio_tag;
-};
-
-struct dcb_connector_table {
-	int entries;
-	struct dcb_connector_table_entry entry[DCB_MAX_NUM_CONNECTOR_ENTRIES];
-};
-
-struct bios_parsed_dcb {
-	uint8_t version;
-
-	struct parsed_dcb dcb;
 
 	uint8_t *i2c_table;
 	uint8_t i2c_default_indices;
+	struct dcb_i2c_entry i2c[DCB_MAX_NUM_I2C_ENTRIES];
 
 	uint16_t gpio_table_ptr;
-	struct parsed_dcb_gpio gpio;
+	struct dcb_gpio_table gpio;
 	uint16_t connector_table_ptr;
 	struct dcb_connector_table connector;
 };
 
-enum nouveau_encoder_type {
-	OUTPUT_ANALOG = 0,
-	OUTPUT_TV = 1,
-	OUTPUT_TMDS = 2,
-	OUTPUT_LVDS = 3,
-	OUTPUT_DP = 6,
-	OUTPUT_ANY = -1
-};
-
 enum nouveau_or {
 	OUTPUT_A = (1 << 0),
 	OUTPUT_B = (1 << 1),
@@ -190,8 +205,8 @@ struct pll_lims {
 	int refclk;
 };
 
-struct nouveau_bios_info {
-	struct parsed_dcb *dcb;
+struct nvbios {
+	struct drm_device *dev;
 
 	uint8_t chip_version;
 
@@ -199,11 +214,6 @@ struct nouveau_bios_info {
 	uint32_t tvdactestval;
 	uint8_t digital_min_front_porch;
 	bool fp_no_ddc;
-};
-
-struct nvbios {
-	struct drm_device *dev;
-	struct nouveau_bios_info pub;
 
 	struct mutex lock;
 
@@ -234,7 +244,7 @@ struct nvbios {
 	uint16_t some_script_ptr; /* BIT I + 14 */
 	uint16_t init96_tbl_ptr; /* BIT I + 16 */
 
-	struct bios_parsed_dcb bdcb;
+	struct dcb_table dcb;
 
 	struct {
 		int crtchead;
@@ -260,7 +270,6 @@ struct nvbios {
 		bool reset_after_pclk_change;
 		bool dual_link;
 		bool link_c_increment;
-		bool BITbit1;
 		bool if_is_24bit;
 		int duallink_transition_clk;
 		uint8_t strapless_is_24bit;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_bo.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_bo.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_bo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_bo.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include "nouveau_dma.h"
 
 #include <linux/log2.h>
+#include <linux/slab.h>
 
 static void
 nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
@@ -71,7 +72,7 @@ nouveau_bo_fixup_align(struct drm_device
 	 * many small buffers.
 	 */
 	if (dev_priv->card_type == NV_50) {
-		uint32_t block_size = nouveau_mem_fb_amount(dev) >> 15;
+		uint32_t block_size = dev_priv->vram_size >> 15;
 		int i;
 
 		switch (tile_flags) {
@@ -153,7 +154,7 @@ nouveau_bo_new(struct drm_device *dev, s
 
 	nvbo->placement.fpfn = 0;
 	nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0;
-	nouveau_bo_placement_set(nvbo, flags);
+	nouveau_bo_placement_set(nvbo, flags, 0);
 
 	nvbo->channel = chan;
 	ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size,
@@ -172,26 +173,33 @@ nouveau_bo_new(struct drm_device *dev, s
 	return 0;
 }
 
+static void
+set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags)
+{
+	*n = 0;
+
+	if (type & TTM_PL_FLAG_VRAM)
+		pl[(*n)++] = TTM_PL_FLAG_VRAM | flags;
+	if (type & TTM_PL_FLAG_TT)
+		pl[(*n)++] = TTM_PL_FLAG_TT | flags;
+	if (type & TTM_PL_FLAG_SYSTEM)
+		pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags;
+}
+
 void
-nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t memtype)
+nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy)
 {
-	int n = 0;
+	struct ttm_placement *pl = &nvbo->placement;
+	uint32_t flags = TTM_PL_MASK_CACHING |
+		(nvbo->pin_refcnt ? TTM_PL_FLAG_NO_EVICT : 0);
 
-	if (memtype & TTM_PL_FLAG_VRAM)
-		nvbo->placements[n++] = TTM_PL_FLAG_VRAM | TTM_PL_MASK_CACHING;
-	if (memtype & TTM_PL_FLAG_TT)
-		nvbo->placements[n++] = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
-	if (memtype & TTM_PL_FLAG_SYSTEM)
-		nvbo->placements[n++] = TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING;
-	nvbo->placement.placement = nvbo->placements;
-	nvbo->placement.busy_placement = nvbo->placements;
-	nvbo->placement.num_placement = n;
-	nvbo->placement.num_busy_placement = n;
+	pl->placement = nvbo->placements;
+	set_placement_list(nvbo->placements, &pl->num_placement,
+			   type, flags);
 
-	if (nvbo->pin_refcnt) {
-		while (n--)
-			nvbo->placements[n] |= TTM_PL_FLAG_NO_EVICT;
-	}
+	pl->busy_placement = nvbo->busy_placements;
+	set_placement_list(nvbo->busy_placements, &pl->num_busy_placement,
+			   type | busy, flags);
 }
 
 int
@@ -199,7 +207,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo,
 {
 	struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
 	struct ttm_buffer_object *bo = &nvbo->bo;
-	int ret, i;
+	int ret;
 
 	if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) {
 		NV_ERROR(nouveau_bdev(bo->bdev)->dev,
@@ -215,9 +223,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo,
 	if (ret)
 		goto out;
 
-	nouveau_bo_placement_set(nvbo, memtype);
-	for (i = 0; i < nvbo->placement.num_placement; i++)
-		nvbo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
+	nouveau_bo_placement_set(nvbo, memtype, 0);
 
 	ret = ttm_bo_validate(bo, &nvbo->placement, false, false);
 	if (ret == 0) {
@@ -244,7 +250,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo
 {
 	struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
 	struct ttm_buffer_object *bo = &nvbo->bo;
-	int ret, i;
+	int ret;
 
 	if (--nvbo->pin_refcnt)
 		return 0;
@@ -253,8 +259,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo
 	if (ret)
 		return ret;
 
-	for (i = 0; i < nvbo->placement.num_placement; i++)
-		nvbo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT;
+	nouveau_bo_placement_set(nvbo, bo->mem.placement, 0);
 
 	ret = ttm_bo_validate(bo, &nvbo->placement, false, false);
 	if (ret == 0) {
@@ -395,8 +400,8 @@ nouveau_bo_init_mem_type(struct ttm_bo_d
 		man->io_addr = NULL;
 		man->io_offset = drm_get_resource_start(dev, 1);
 		man->io_size = drm_get_resource_len(dev, 1);
-		if (man->io_size > nouveau_mem_fb_amount(dev))
-			man->io_size = nouveau_mem_fb_amount(dev);
+		if (man->io_size > dev_priv->vram_size)
+			man->io_size = dev_priv->vram_size;
 
 		man->gpu_offset = dev_priv->vm_vram_base;
 		break;
@@ -439,11 +444,11 @@ nouveau_bo_evict_flags(struct ttm_buffer
 
 	switch (bo->mem.mem_type) {
 	case TTM_PL_VRAM:
-		nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT |
+		nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT,
 					 TTM_PL_FLAG_SYSTEM);
 		break;
 	default:
-		nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM);
+		nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM, 0);
 		break;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_calc.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_calc.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_calc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_calc.c	2010-05-16 17:17:36.000000000 -0400
@@ -274,7 +274,7 @@ getMNP_single(struct drm_device *dev, st
 	 * returns calculated clock
 	 */
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	int cv = dev_priv->vbios->chip_version;
+	int cv = dev_priv->vbios.chip_version;
 	int minvco = pll_lim->vco1.minfreq, maxvco = pll_lim->vco1.maxfreq;
 	int minM = pll_lim->vco1.min_m, maxM = pll_lim->vco1.max_m;
 	int minN = pll_lim->vco1.min_n, maxN = pll_lim->vco1.max_n;
@@ -373,7 +373,7 @@ getMNP_double(struct drm_device *dev, st
 	 * returns calculated clock
 	 */
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	int chip_version = dev_priv->vbios->chip_version;
+	int chip_version = dev_priv->vbios.chip_version;
 	int minvco1 = pll_lim->vco1.minfreq, maxvco1 = pll_lim->vco1.maxfreq;
 	int minvco2 = pll_lim->vco2.minfreq, maxvco2 = pll_lim->vco2.maxfreq;
 	int minU1 = pll_lim->vco1.min_inputfreq, minU2 = pll_lim->vco2.min_inputfreq;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_channel.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_channel.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_channel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_channel.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,22 +35,27 @@ nouveau_channel_pushbuf_ctxdma_init(stru
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_bo *pb = chan->pushbuf_bo;
 	struct nouveau_gpuobj *pushbuf = NULL;
-	uint32_t start = pb->bo.mem.mm_node->start << PAGE_SHIFT;
 	int ret;
 
+	if (dev_priv->card_type >= NV_50) {
+		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
+					     dev_priv->vm_end, NV_DMA_ACCESS_RO,
+					     NV_DMA_TARGET_AGP, &pushbuf);
+		chan->pushbuf_base = pb->bo.offset;
+	} else
 	if (pb->bo.mem.mem_type == TTM_PL_TT) {
 		ret = nouveau_gpuobj_gart_dma_new(chan, 0,
 						  dev_priv->gart_info.aper_size,
 						  NV_DMA_ACCESS_RO, &pushbuf,
 						  NULL);
-		chan->pushbuf_base = start;
+		chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT;
 	} else
 	if (dev_priv->card_type != NV_04) {
 		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
 					     dev_priv->fb_available_size,
 					     NV_DMA_ACCESS_RO,
 					     NV_DMA_TARGET_VIDMEM, &pushbuf);
-		chan->pushbuf_base = start;
+		chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT;
 	} else {
 		/* NV04 cmdbuf hack, from original ddx.. not sure of it's
 		 * exact reason for existing :)  PCI access to cmdbuf in
@@ -61,7 +66,7 @@ nouveau_channel_pushbuf_ctxdma_init(stru
 					     dev_priv->fb_available_size,
 					     NV_DMA_ACCESS_RO,
 					     NV_DMA_TARGET_PCI, &pushbuf);
-		chan->pushbuf_base = start;
+		chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT;
 	}
 
 	ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, &chan->pushbuf);
@@ -137,7 +142,6 @@ nouveau_channel_alloc(struct drm_device
 					   GFP_KERNEL);
 	if (!dev_priv->fifos[channel])
 		return -ENOMEM;
-	dev_priv->fifo_alloc_count++;
 	chan = dev_priv->fifos[channel];
 	INIT_LIST_HEAD(&chan->nvsw.vbl_wait);
 	INIT_LIST_HEAD(&chan->fence.pending);
@@ -275,9 +279,18 @@ nouveau_channel_free(struct nouveau_chan
 	 */
 	nouveau_fence_fini(chan);
 
-	/* Ensure the channel is no longer active on the GPU */
+	/* This will prevent pfifo from switching channels. */
 	pfifo->reassign(dev, false);
 
+	/* We want to give pgraph a chance to idle and get rid of all potential
+	 * errors. We need to do this before the lock, otherwise the irq handler
+	 * is unable to process them.
+	 */
+	if (pgraph->channel(dev) == chan)
+		nouveau_wait_for_idle(dev);
+
+	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
+
 	pgraph->fifo_access(dev, false);
 	if (pgraph->channel(dev) == chan)
 		pgraph->unload_context(dev);
@@ -293,6 +306,8 @@ nouveau_channel_free(struct nouveau_chan
 
 	pfifo->reassign(dev, true);
 
+	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
+
 	/* Release the channel's resources */
 	nouveau_gpuobj_ref_del(dev, &chan->pushbuf);
 	if (chan->pushbuf_bo) {
@@ -305,7 +320,6 @@ nouveau_channel_free(struct nouveau_chan
 		iounmap(chan->user);
 
 	dev_priv->fifos[chan->id] = NULL;
-	dev_priv->fifo_alloc_count--;
 	kfree(chan);
 }
 
@@ -369,6 +383,14 @@ nouveau_ioctl_fifo_alloc(struct drm_devi
 		return ret;
 	init->channel  = chan->id;
 
+	if (chan->dma.ib_max)
+		init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM |
+					NOUVEAU_GEM_DOMAIN_GART;
+	else if (chan->pushbuf_bo->bo.mem.mem_type == TTM_PL_VRAM)
+		init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM;
+	else
+		init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART;
+
 	init->subchan[0].handle = NvM2MF;
 	if (dev_priv->card_type < NV_50)
 		init->subchan[0].grclass = 0x0039;
@@ -408,7 +430,6 @@ nouveau_ioctl_fifo_free(struct drm_devic
  ***********************************/
 
 struct drm_ioctl_desc nouveau_ioctls[] = {
-	DRM_IOCTL_DEF(DRM_NOUVEAU_CARD_INIT, nouveau_ioctl_card_init, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 	DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH),
@@ -418,13 +439,9 @@ struct drm_ioctl_desc nouveau_ioctls[] =
 	DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF_CALL, nouveau_gem_ioctl_pushbuf_call, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PIN, nouveau_gem_ioctl_pin, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_UNPIN, nouveau_gem_ioctl_unpin, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF_CALL2, nouveau_gem_ioctl_pushbuf_call2, DRM_AUTH),
 };
 
 int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.c	2010-05-16 17:17:36.000000000 -0400
@@ -218,7 +218,7 @@ nouveau_connector_set_encoder(struct drm
 			connector->interlace_allowed = true;
 	}
 
-	if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
+	if (nv_connector->dcb->type == DCB_CONNECTOR_DVI_I) {
 		drm_connector_property_set_value(connector,
 			dev->mode_config.dvi_i_subconnector_property,
 			nv_encoder->dcb->type == OUTPUT_TMDS ?
@@ -236,15 +236,17 @@ nouveau_connector_detect(struct drm_conn
 	struct nouveau_i2c_chan *i2c;
 	int type, flags;
 
-	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
+	if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS)
 		nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
 	if (nv_encoder && nv_connector->native_mode) {
+		unsigned status = connector_status_connected;
+
 #ifdef CONFIG_ACPI
 		if (!nouveau_ignorelid && !acpi_lid_open())
-			return connector_status_disconnected;
+			status = connector_status_unknown;
 #endif
 		nouveau_connector_set_encoder(connector, nv_encoder);
-		return connector_status_connected;
+		return status;
 	}
 
 	/* Cleanup the previous EDID block. */
@@ -279,7 +281,7 @@ nouveau_connector_detect(struct drm_conn
 		 * same i2c channel so the value returned from ddc_detect
 		 * isn't necessarily correct.
 		 */
-		if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
+		if (nv_connector->dcb->type == DCB_CONNECTOR_DVI_I) {
 			if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL)
 				type = OUTPUT_TMDS;
 			else
@@ -300,7 +302,7 @@ nouveau_connector_detect(struct drm_conn
 
 detect_analog:
 	nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG);
-	if (!nv_encoder)
+	if (!nv_encoder && !nouveau_tv_disable)
 		nv_encoder = find_encoder_by_type(connector, OUTPUT_TV);
 	if (nv_encoder) {
 		struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
@@ -321,11 +323,11 @@ detect_analog:
 static void
 nouveau_connector_force(struct drm_connector *connector)
 {
-	struct drm_device *dev = connector->dev;
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
 	struct nouveau_encoder *nv_encoder;
 	int type;
 
-	if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
+	if (nv_connector->dcb->type == DCB_CONNECTOR_DVI_I) {
 		if (connector->force == DRM_FORCE_ON_DIGITAL)
 			type = OUTPUT_TMDS;
 		else
@@ -335,7 +337,7 @@ nouveau_connector_force(struct drm_conne
 
 	nv_encoder = find_encoder_by_type(connector, type);
 	if (!nv_encoder) {
-		NV_ERROR(dev, "can't find encoder to force %s on!\n",
+		NV_ERROR(connector->dev, "can't find encoder to force %s on!\n",
 			 drm_get_connector_name(connector));
 		connector->status = connector_status_disconnected;
 		return;
@@ -369,7 +371,7 @@ nouveau_connector_set_property(struct dr
 		}
 
 		/* LVDS always needs gpu scaling */
-		if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS &&
+		if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS &&
 		    value == DRM_MODE_SCALE_NONE)
 			return -EINVAL;
 
@@ -535,7 +537,7 @@ nouveau_connector_get_modes(struct drm_c
 	/* If we're not LVDS, destroy the previous native mode, the attached
 	 * monitor could have changed.
 	 */
-	if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS &&
+	if (nv_connector->dcb->type != DCB_CONNECTOR_LVDS &&
 	    nv_connector->native_mode) {
 		drm_mode_destroy(dev, nv_connector->native_mode);
 		nv_connector->native_mode = NULL;
@@ -563,7 +565,7 @@ nouveau_connector_get_modes(struct drm_c
 		ret = get_slave_funcs(nv_encoder)->
 			get_modes(to_drm_encoder(nv_encoder), connector);
 
-	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
+	if (nv_encoder->dcb->type == OUTPUT_LVDS)
 		ret += nouveau_connector_scaler_modes_add(connector);
 
 	return ret;
@@ -613,6 +615,9 @@ nouveau_connector_mode_valid(struct drm_
 
 		clock *= 3;
 		break;
+	default:
+		BUG_ON(1);
+		return MODE_BAD;
 	}
 
 	if (clock < min_clock)
@@ -680,7 +685,7 @@ nouveau_connector_create_lvds(struct drm
 	/* Firstly try getting EDID over DDC, if allowed and I2C channel
 	 * is available.
 	 */
-	if (!dev_priv->VBIOS.pub.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf)
+	if (!dev_priv->vbios.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf)
 		i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
 
 	if (i2c) {
@@ -695,7 +700,7 @@ nouveau_connector_create_lvds(struct drm
 	 */
 	if (!nv_connector->edid && nouveau_bios_fp_mode(dev, &native) &&
 	     (nv_encoder->dcb->lvdsconf.use_straps_for_mode ||
-	      dev_priv->VBIOS.pub.fp_no_ddc)) {
+	      dev_priv->vbios.fp_no_ddc)) {
 		nv_connector->native_mode = drm_mode_duplicate(dev, &native);
 		goto out;
 	}
@@ -704,7 +709,7 @@ nouveau_connector_create_lvds(struct drm
 	 * stored for the panel stored in them.
 	 */
 	if (!nv_connector->edid && !nv_connector->native_mode &&
-	    !dev_priv->VBIOS.pub.fp_no_ddc) {
+	    !dev_priv->vbios.fp_no_ddc) {
 		struct edid *edid =
 			(struct edid *)nouveau_bios_embedded_edid(dev);
 		if (edid) {
@@ -739,46 +744,66 @@ out:
 }
 
 int
-nouveau_connector_create(struct drm_device *dev, int index, int type)
+nouveau_connector_create(struct drm_device *dev,
+			 struct dcb_connector_table_entry *dcb)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_connector *nv_connector = NULL;
 	struct drm_connector *connector;
 	struct drm_encoder *encoder;
-	int ret;
+	int ret, type;
 
 	NV_DEBUG_KMS(dev, "\n");
 
-	nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
-	if (!nv_connector)
-		return -ENOMEM;
-	nv_connector->dcb = nouveau_bios_connector_entry(dev, index);
-	connector = &nv_connector->base;
-
-	switch (type) {
-	case DRM_MODE_CONNECTOR_VGA:
+	switch (dcb->type) {
+	case DCB_CONNECTOR_NONE:
+		return 0;
+	case DCB_CONNECTOR_VGA:
 		NV_INFO(dev, "Detected a VGA connector\n");
+		type = DRM_MODE_CONNECTOR_VGA;
 		break;
-	case DRM_MODE_CONNECTOR_DVID:
-		NV_INFO(dev, "Detected a DVI-D connector\n");
+	case DCB_CONNECTOR_TV_0:
+	case DCB_CONNECTOR_TV_1:
+	case DCB_CONNECTOR_TV_3:
+		NV_INFO(dev, "Detected a TV connector\n");
+		type = DRM_MODE_CONNECTOR_TV;
 		break;
-	case DRM_MODE_CONNECTOR_DVII:
+	case DCB_CONNECTOR_DVI_I:
 		NV_INFO(dev, "Detected a DVI-I connector\n");
+		type = DRM_MODE_CONNECTOR_DVII;
 		break;
-	case DRM_MODE_CONNECTOR_LVDS:
-		NV_INFO(dev, "Detected a LVDS connector\n");
+	case DCB_CONNECTOR_DVI_D:
+		NV_INFO(dev, "Detected a DVI-D connector\n");
+		type = DRM_MODE_CONNECTOR_DVID;
 		break;
-	case DRM_MODE_CONNECTOR_TV:
-		NV_INFO(dev, "Detected a TV connector\n");
+	case DCB_CONNECTOR_HDMI_0:
+	case DCB_CONNECTOR_HDMI_1:
+		NV_INFO(dev, "Detected a HDMI connector\n");
+		type = DRM_MODE_CONNECTOR_HDMIA;
 		break;
-	case DRM_MODE_CONNECTOR_DisplayPort:
+	case DCB_CONNECTOR_LVDS:
+		NV_INFO(dev, "Detected a LVDS connector\n");
+		type = DRM_MODE_CONNECTOR_LVDS;
+		break;
+	case DCB_CONNECTOR_DP:
 		NV_INFO(dev, "Detected a DisplayPort connector\n");
+		type = DRM_MODE_CONNECTOR_DisplayPort;
 		break;
-	default:
-		NV_ERROR(dev, "Unknown connector, this is not good.\n");
+	case DCB_CONNECTOR_eDP:
+		NV_INFO(dev, "Detected an eDP connector\n");
+		type = DRM_MODE_CONNECTOR_eDP;
 		break;
+	default:
+		NV_ERROR(dev, "unknown connector type: 0x%02x!!\n", dcb->type);
+		return -EINVAL;
 	}
 
+	nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
+	if (!nv_connector)
+		return -ENOMEM;
+	nv_connector->dcb = dcb;
+	connector = &nv_connector->base;
+
 	/* defaults, will get overridden in detect() */
 	connector->interlace_allowed = false;
 	connector->doublescan_allowed = false;
@@ -786,55 +811,65 @@ nouveau_connector_create(struct drm_devi
 	drm_connector_init(dev, connector, &nouveau_connector_funcs, type);
 	drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
 
+	/* attach encoders */
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+		if (nv_encoder->dcb->connector != dcb->index)
+			continue;
+
+		if (get_slave_funcs(nv_encoder))
+			get_slave_funcs(nv_encoder)->create_resources(encoder, connector);
+
+		drm_mode_connector_attach_encoder(connector, encoder);
+	}
+
+	if (!connector->encoder_ids[0]) {
+		NV_WARN(dev, "  no encoders, ignoring\n");
+		drm_connector_cleanup(connector);
+		kfree(connector);
+		return 0;
+	}
+
 	/* Init DVI-I specific properties */
-	if (type == DRM_MODE_CONNECTOR_DVII) {
+	if (dcb->type == DCB_CONNECTOR_DVI_I) {
 		drm_mode_create_dvi_i_properties(dev);
 		drm_connector_attach_property(connector, dev->mode_config.dvi_i_subconnector_property, 0);
 		drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0);
 	}
 
-	if (type != DRM_MODE_CONNECTOR_LVDS)
+	if (dcb->type != DCB_CONNECTOR_LVDS)
 		nv_connector->use_dithering = false;
 
-	if (type == DRM_MODE_CONNECTOR_DVID ||
-	    type == DRM_MODE_CONNECTOR_DVII ||
-	    type == DRM_MODE_CONNECTOR_LVDS ||
-	    type == DRM_MODE_CONNECTOR_DisplayPort) {
-		nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN;
-
-		drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property,
-					      nv_connector->scaling_mode);
-		drm_connector_attach_property(connector, dev->mode_config.dithering_mode_property,
-					      nv_connector->use_dithering ? DRM_MODE_DITHERING_ON
-					      : DRM_MODE_DITHERING_OFF);
-
-	} else {
-		nv_connector->scaling_mode = DRM_MODE_SCALE_NONE;
-
-		if (type == DRM_MODE_CONNECTOR_VGA  &&
-				dev_priv->card_type >= NV_50) {
+	switch (dcb->type) {
+	case DCB_CONNECTOR_VGA:
+		if (dev_priv->card_type >= NV_50) {
 			drm_connector_attach_property(connector,
 					dev->mode_config.scaling_mode_property,
 					nv_connector->scaling_mode);
 		}
-	}
-
-	/* attach encoders */
-	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
-
-		if (nv_encoder->dcb->connector != index)
-			continue;
-
-		if (get_slave_funcs(nv_encoder))
-			get_slave_funcs(nv_encoder)->create_resources(encoder, connector);
+		/* fall-through */
+	case DCB_CONNECTOR_TV_0:
+	case DCB_CONNECTOR_TV_1:
+	case DCB_CONNECTOR_TV_3:
+		nv_connector->scaling_mode = DRM_MODE_SCALE_NONE;
+		break;
+	default:
+		nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN;
 
-		drm_mode_connector_attach_encoder(connector, encoder);
+		drm_connector_attach_property(connector,
+				dev->mode_config.scaling_mode_property,
+				nv_connector->scaling_mode);
+		drm_connector_attach_property(connector,
+				dev->mode_config.dithering_mode_property,
+				nv_connector->use_dithering ?
+				DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF);
+		break;
 	}
 
 	drm_sysfs_connector_add(connector);
 
-	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
+	if (dcb->type == DCB_CONNECTOR_LVDS) {
 		ret = nouveau_connector_create_lvds(dev, connector);
 		if (ret) {
 			connector->funcs->destroy(connector);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.h	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,7 @@ static inline struct nouveau_connector *
 	return container_of(con, struct nouveau_connector, base);
 }
 
-int nouveau_connector_create(struct drm_device *dev, int i2c_index, int type);
+int nouveau_connector_create(struct drm_device *,
+			     struct dcb_connector_table_entry *);
 
 #endif /* __NOUVEAU_CONNECTOR_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_debugfs.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_debugfs.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_debugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_debugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,12 +47,23 @@ nouveau_debugfs_channel_info(struct seq_
 	seq_printf(m, "           cur: 0x%08x\n", chan->dma.cur << 2);
 	seq_printf(m, "           put: 0x%08x\n", chan->dma.put << 2);
 	seq_printf(m, "          free: 0x%08x\n", chan->dma.free << 2);
+	if (chan->dma.ib_max) {
+		seq_printf(m, "        ib max: 0x%08x\n", chan->dma.ib_max);
+		seq_printf(m, "        ib put: 0x%08x\n", chan->dma.ib_put);
+		seq_printf(m, "       ib free: 0x%08x\n", chan->dma.ib_free);
+	}
 
 	seq_printf(m, "gpu fifo state:\n");
 	seq_printf(m, "           get: 0x%08x\n",
 					nvchan_rd32(chan, chan->user_get));
 	seq_printf(m, "           put: 0x%08x\n",
 					nvchan_rd32(chan, chan->user_put));
+	if (chan->dma.ib_max) {
+		seq_printf(m, "        ib get: 0x%08x\n",
+			   nvchan_rd32(chan, 0x88));
+		seq_printf(m, "        ib put: 0x%08x\n",
+			   nvchan_rd32(chan, 0x8c));
+	}
 
 	seq_printf(m, "last fence    : %d\n", chan->fence.sequence);
 	seq_printf(m, "last signalled: %d\n", chan->fence.sequence_ack);
@@ -126,16 +137,28 @@ nouveau_debugfs_memory_info(struct seq_f
 {
 	struct drm_info_node *node = (struct drm_info_node *) m->private;
 	struct drm_minor *minor = node->minor;
-	struct drm_device *dev = minor->dev;
+	struct drm_nouveau_private *dev_priv = minor->dev->dev_private;
 
-	seq_printf(m, "VRAM total: %dKiB\n",
-		   (int)(nouveau_mem_fb_amount(dev) >> 10));
+	seq_printf(m, "VRAM total: %dKiB\n", (int)(dev_priv->vram_size >> 10));
+	return 0;
+}
+
+static int
+nouveau_debugfs_vbios_image(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_nouveau_private *dev_priv = node->minor->dev->dev_private;
+	int i;
+
+	for (i = 0; i < dev_priv->vbios.length; i++)
+		seq_printf(m, "%c", dev_priv->vbios.data[i]);
 	return 0;
 }
 
 static struct drm_info_list nouveau_debugfs_list[] = {
 	{ "chipset", nouveau_debugfs_chipset_info, 0, NULL },
 	{ "memory", nouveau_debugfs_memory_info, 0, NULL },
+	{ "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL },
 };
 #define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list)
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_display.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_display.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_display.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_display.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,11 +39,8 @@ nouveau_user_framebuffer_destroy(struct
 	if (drm_fb->fbdev)
 		nouveau_fbcon_remove(dev, drm_fb);
 
-	if (fb->nvbo) {
-		mutex_lock(&dev->struct_mutex);
-		drm_gem_object_unreference(fb->nvbo->gem);
-		mutex_unlock(&dev->struct_mutex);
-	}
+	if (fb->nvbo)
+		drm_gem_object_unreference_unlocked(fb->nvbo->gem);
 
 	drm_framebuffer_cleanup(drm_fb);
 	kfree(fb);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,22 @@
 void
 nouveau_dma_pre_init(struct nouveau_channel *chan)
 {
-	chan->dma.max  = (chan->pushbuf_bo->bo.mem.size >> 2) - 2;
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+	struct nouveau_bo *pushbuf = chan->pushbuf_bo;
+
+	if (dev_priv->card_type == NV_50) {
+		const int ib_size = pushbuf->bo.mem.size / 2;
+
+		chan->dma.ib_base = (pushbuf->bo.mem.size - ib_size) >> 2;
+		chan->dma.ib_max = (ib_size / 8) - 1;
+		chan->dma.ib_put = 0;
+		chan->dma.ib_free = chan->dma.ib_max - chan->dma.ib_put;
+
+		chan->dma.max = (pushbuf->bo.mem.size - ib_size) >> 2;
+	} else {
+		chan->dma.max  = (pushbuf->bo.mem.size >> 2) - 2;
+	}
+
 	chan->dma.put  = 0;
 	chan->dma.cur  = chan->dma.put;
 	chan->dma.free = chan->dma.max - chan->dma.cur;
@@ -162,12 +177,106 @@ READ_GET(struct nouveau_channel *chan, u
 	return (val - chan->pushbuf_base) >> 2;
 }
 
+void
+nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo,
+	      int delta, int length)
+{
+	struct nouveau_bo *pb = chan->pushbuf_bo;
+	uint64_t offset = bo->bo.offset + delta;
+	int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
+
+	BUG_ON(chan->dma.ib_free < 1);
+	nouveau_bo_wr32(pb, ip++, lower_32_bits(offset));
+	nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8);
+
+	chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max;
+
+	DRM_MEMORYBARRIER();
+	/* Flush writes. */
+	nouveau_bo_rd32(pb, 0);
+
+	nvchan_wr32(chan, 0x8c, chan->dma.ib_put);
+	chan->dma.ib_free--;
+}
+
+static int
+nv50_dma_push_wait(struct nouveau_channel *chan, int count)
+{
+	uint32_t cnt = 0, prev_get = 0;
+
+	while (chan->dma.ib_free < count) {
+		uint32_t get = nvchan_rd32(chan, 0x88);
+		if (get != prev_get) {
+			prev_get = get;
+			cnt = 0;
+		}
+
+		if ((++cnt & 0xff) == 0) {
+			DRM_UDELAY(1);
+			if (cnt > 100000)
+				return -EBUSY;
+		}
+
+		chan->dma.ib_free = get - chan->dma.ib_put;
+		if (chan->dma.ib_free <= 0)
+			chan->dma.ib_free += chan->dma.ib_max + 1;
+	}
+
+	return 0;
+}
+
+static int
+nv50_dma_wait(struct nouveau_channel *chan, int slots, int count)
+{
+	uint32_t cnt = 0, prev_get = 0;
+	int ret;
+
+	ret = nv50_dma_push_wait(chan, slots + 1);
+	if (unlikely(ret))
+		return ret;
+
+	while (chan->dma.free < count) {
+		int get = READ_GET(chan, &prev_get, &cnt);
+		if (unlikely(get < 0)) {
+			if (get == -EINVAL)
+				continue;
+
+			return get;
+		}
+
+		if (get <= chan->dma.cur) {
+			chan->dma.free = chan->dma.max - chan->dma.cur;
+			if (chan->dma.free >= count)
+				break;
+
+			FIRE_RING(chan);
+			do {
+				get = READ_GET(chan, &prev_get, &cnt);
+				if (unlikely(get < 0)) {
+					if (get == -EINVAL)
+						continue;
+					return get;
+				}
+			} while (get == 0);
+			chan->dma.cur = 0;
+			chan->dma.put = 0;
+		}
+
+		chan->dma.free = get - chan->dma.cur - 1;
+	}
+
+	return 0;
+}
+
 int
-nouveau_dma_wait(struct nouveau_channel *chan, int size)
+nouveau_dma_wait(struct nouveau_channel *chan, int slots, int size)
 {
 	uint32_t prev_get = 0, cnt = 0;
 	int get;
 
+	if (chan->dma.ib_max)
+		return nv50_dma_wait(chan, slots, size);
+
 	while (chan->dma.free < size) {
 		get = READ_GET(chan, &prev_get, &cnt);
 		if (unlikely(get == -EBUSY))
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.h	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,9 @@
 #define NOUVEAU_DMA_DEBUG 0
 #endif
 
+void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *,
+		   int delta, int length);
+
 /*
  * There's a hw race condition where you can't jump to your PUT offset,
  * to avoid this we jump to offset + SKIPS and fill the difference with
@@ -96,13 +99,11 @@ enum {
 static __must_check inline int
 RING_SPACE(struct nouveau_channel *chan, int size)
 {
-	if (chan->dma.free < size) {
-		int ret;
+	int ret;
 
-		ret = nouveau_dma_wait(chan, size);
-		if (ret)
-			return ret;
-	}
+	ret = nouveau_dma_wait(chan, 1, size);
+	if (ret)
+		return ret;
 
 	chan->dma.free -= size;
 	return 0;
@@ -146,7 +147,13 @@ FIRE_RING(struct nouveau_channel *chan)
 		return;
 	chan->accel_done = true;
 
-	WRITE_PUT(chan->dma.cur);
+	if (chan->dma.ib_max) {
+		nv50_dma_push(chan, chan->pushbuf_bo, chan->dma.put << 2,
+			      (chan->dma.cur - chan->dma.put) << 2);
+	} else {
+		WRITE_PUT(chan->dma.cur);
+	}
+
 	chan->dma.put = chan->dma.cur;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_dp.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_dp.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_dp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_dp.c	2010-05-16 17:17:36.000000000 -0400
@@ -483,7 +483,7 @@ nouveau_dp_auxch(struct nouveau_i2c_chan
 	ctrl |= (cmd << NV50_AUXCH_CTRL_CMD_SHIFT);
 	ctrl |= ((data_nr - 1) << NV50_AUXCH_CTRL_LEN_SHIFT);
 
-	for (;;) {
+	for (i = 0; i < 16; i++) {
 		nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x80000000);
 		nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl);
 		nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x00010000);
@@ -502,6 +502,12 @@ nouveau_dp_auxch(struct nouveau_i2c_chan
 			break;
 	}
 
+	if (i == 16) {
+		NV_ERROR(dev, "auxch DEFER too many times, bailing\n");
+		ret = -EREMOTEIO;
+		goto out;
+	}
+
 	if (cmd & 1) {
 		if ((stat & NV50_AUXCH_STAT_COUNT) != data_nr) {
 			ret = -EREMOTEIO;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -75,14 +75,22 @@ MODULE_PARM_DESC(ignorelid, "Ignore ACPI
 int nouveau_ignorelid = 0;
 module_param_named(ignorelid, nouveau_ignorelid, int, 0400);
 
-MODULE_PARM_DESC(noagp, "Disable all acceleration");
+MODULE_PARM_DESC(noaccel, "Disable all acceleration");
 int nouveau_noaccel = 0;
 module_param_named(noaccel, nouveau_noaccel, int, 0400);
 
-MODULE_PARM_DESC(noagp, "Disable fbcon acceleration");
+MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");
 int nouveau_nofbaccel = 0;
 module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400);
 
+MODULE_PARM_DESC(override_conntype, "Ignore DCB connector type");
+int nouveau_override_conntype = 0;
+module_param_named(override_conntype, nouveau_override_conntype, int, 0400);
+
+MODULE_PARM_DESC(tv_disable, "Disable TV-out detection\n");
+int nouveau_tv_disable = 0;
+module_param_named(tv_disable, nouveau_tv_disable, int, 0400);
+
 MODULE_PARM_DESC(tv_norm, "Default TV norm.\n"
 		 "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n"
 		 "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n"
@@ -135,7 +143,7 @@ nouveau_pci_remove(struct pci_dev *pdev)
 	drm_put_dev(dev);
 }
 
-static int
+int
 nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
@@ -154,9 +162,11 @@ nouveau_pci_suspend(struct pci_dev *pdev
 	if (pm_state.event == PM_EVENT_PRETHAW)
 		return 0;
 
+	NV_INFO(dev, "Disabling fbcon acceleration...\n");
 	fbdev_flags = dev_priv->fbdev_info->flags;
 	dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
 
+	NV_INFO(dev, "Unpinning framebuffer(s)...\n");
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		struct nouveau_framebuffer *nouveau_fb;
 
@@ -233,7 +243,7 @@ out_abort:
 	return ret;
 }
 
-static int
+int
 nouveau_pci_resume(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
@@ -402,8 +412,10 @@ static int __init nouveau_init(void)
 			nouveau_modeset = 1;
 	}
 
-	if (nouveau_modeset == 1)
+	if (nouveau_modeset == 1) {
 		driver.driver_features |= DRIVER_MODESET;
+		nouveau_register_dsm_handler();
+	}
 
 	return drm_init(&driver);
 }
@@ -411,6 +423,7 @@ static int __init nouveau_init(void)
 static void __exit nouveau_exit(void)
 {
 	drm_exit(&driver);
+	nouveau_unregister_dsm_handler();
 }
 
 module_init(nouveau_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.h	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,7 @@
 
 #define DRIVER_MAJOR		0
 #define DRIVER_MINOR		0
-#define DRIVER_PATCHLEVEL	15
+#define DRIVER_PATCHLEVEL	16
 
 #define NOUVEAU_FAMILY   0x0000FFFF
 #define NOUVEAU_FLAGS    0xFFFF0000
@@ -76,6 +76,7 @@ struct nouveau_bo {
 	struct ttm_buffer_object bo;
 	struct ttm_placement placement;
 	u32 placements[3];
+	u32 busy_placements[3];
 	struct ttm_bo_kmap_obj kmap;
 	struct list_head head;
 
@@ -83,6 +84,7 @@ struct nouveau_bo {
 	struct drm_file *reserved_by;
 	struct list_head entry;
 	int pbbo_index;
+	bool validate_mapped;
 
 	struct nouveau_channel *channel;
 
@@ -239,6 +241,11 @@ struct nouveau_channel {
 		int cur;
 		int put;
 		/* access via pushbuf_bo */
+
+		int ib_base;
+		int ib_max;
+		int ib_free;
+		int ib_put;
 	} dma;
 
 	uint32_t sw_subchannel[8];
@@ -513,6 +520,7 @@ struct drm_nouveau_private {
 
 	struct workqueue_struct *wq;
 	struct work_struct irq_work;
+	struct work_struct hpd_work;
 
 	struct list_head vbl_waiting;
 
@@ -527,12 +535,14 @@ struct drm_nouveau_private {
 
 	struct fb_info *fbdev_info;
 
-	int fifo_alloc_count;
 	struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR];
 
 	struct nouveau_engine engine;
 	struct nouveau_channel *channel;
 
+	/* For PFIFO and PGRAPH. */
+	spinlock_t context_switch_lock;
+
 	/* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */
 	struct nouveau_gpuobj *ramht;
 	uint32_t ramin_rsvd_vram;
@@ -544,12 +554,6 @@ struct drm_nouveau_private {
 	uint32_t ramro_offset;
 	uint32_t ramro_size;
 
-	/* base physical adresses */
-	uint64_t fb_phys;
-	uint64_t fb_available_size;
-	uint64_t fb_mappable_pages;
-	uint64_t fb_aper_free;
-
 	struct {
 		enum {
 			NOUVEAU_GART_NONE = 0,
@@ -563,10 +567,6 @@ struct drm_nouveau_private {
 		struct nouveau_gpuobj *sg_ctxdma;
 		struct page *sg_dummy_page;
 		dma_addr_t sg_dummy_bus;
-
-		/* nottm hack */
-		struct drm_ttm_backend *sg_be;
-		unsigned long sg_handle;
 	} gart_info;
 
 	/* nv10-nv40 tiling regions */
@@ -575,6 +575,16 @@ struct drm_nouveau_private {
 		spinlock_t lock;
 	} tile;
 
+	/* VRAM/fb configuration */
+	uint64_t vram_size;
+	uint64_t vram_sys_base;
+
+	uint64_t fb_phys;
+	uint64_t fb_available_size;
+	uint64_t fb_mappable_pages;
+	uint64_t fb_aper_free;
+	int fb_mtrr;
+
 	/* G8x/G9x virtual address space */
 	uint64_t vm_gart_base;
 	uint64_t vm_gart_size;
@@ -583,10 +593,6 @@ struct drm_nouveau_private {
 	uint64_t vm_end;
 	struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR];
 	int vm_vram_pt_nr;
-	uint64_t vram_sys_base;
-
-	/* the mtrr covering the FB */
-	int fb_mtrr;
 
 	struct mem_block *ramin_heap;
 
@@ -596,8 +602,7 @@ struct drm_nouveau_private {
 
 	struct list_head gpuobj_list;
 
-	struct nvbios VBIOS;
-	struct nouveau_bios_info *vbios;
+	struct nvbios vbios;
 
 	struct nv04_mode_state mode_reg;
 	struct nv04_mode_state saved_reg;
@@ -606,15 +611,10 @@ struct drm_nouveau_private {
 	uint32_t dac_users[4];
 
 	struct nouveau_suspend_resume {
-		uint32_t fifo_mode;
-		uint32_t graph_ctx_control;
-		uint32_t graph_state;
 		uint32_t *ramin_copy;
-		uint64_t ramin_size;
 	} susres;
 
 	struct backlight_device *backlight;
-	bool acpi_dsm;
 
 	struct nouveau_channel *evo;
 
@@ -674,6 +674,7 @@ extern int nouveau_uscript_tmds;
 extern int nouveau_vram_pushbuf;
 extern int nouveau_vram_notify;
 extern int nouveau_fbpercrtc;
+extern int nouveau_tv_disable;
 extern char *nouveau_tv_norm;
 extern int nouveau_reg_debug;
 extern char *nouveau_vbios;
@@ -681,6 +682,10 @@ extern int nouveau_ctxfw;
 extern int nouveau_ignorelid;
 extern int nouveau_nofbaccel;
 extern int nouveau_noaccel;
+extern int nouveau_override_conntype;
+
+extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state);
+extern int nouveau_pci_resume(struct pci_dev *pdev);
 
 /* nouveau_state.c */
 extern void nouveau_preclose(struct drm_device *dev, struct drm_file *);
@@ -696,12 +701,6 @@ extern bool nouveau_wait_until(struct dr
 			       uint32_t reg, uint32_t mask, uint32_t val);
 extern bool nouveau_wait_for_idle(struct drm_device *);
 extern int  nouveau_card_init(struct drm_device *);
-extern int  nouveau_ioctl_card_init(struct drm_device *, void *data,
-				    struct drm_file *);
-extern int  nouveau_ioctl_suspend(struct drm_device *, void *data,
-				  struct drm_file *);
-extern int  nouveau_ioctl_resume(struct drm_device *, void *data,
-				 struct drm_file *);
 
 /* nouveau_mem.c */
 extern int  nouveau_mem_init_heap(struct mem_block **, uint64_t start,
@@ -711,7 +710,7 @@ extern struct mem_block *nouveau_mem_all
 						 struct drm_file *, int tail);
 extern void nouveau_mem_takedown(struct mem_block **heap);
 extern void nouveau_mem_free_block(struct mem_block *);
-extern uint64_t nouveau_mem_fb_amount(struct drm_device *);
+extern int  nouveau_mem_detect(struct drm_device *dev);
 extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap);
 extern int  nouveau_mem_init(struct drm_device *);
 extern int  nouveau_mem_init_agp(struct drm_device *);
@@ -845,21 +844,15 @@ nouveau_debugfs_channel_fini(struct nouv
 /* nouveau_dma.c */
 extern void nouveau_dma_pre_init(struct nouveau_channel *);
 extern int  nouveau_dma_init(struct nouveau_channel *);
-extern int  nouveau_dma_wait(struct nouveau_channel *, int size);
+extern int  nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
 
 /* nouveau_acpi.c */
-#ifdef CONFIG_ACPI
-extern int nouveau_hybrid_setup(struct drm_device *dev);
-extern bool nouveau_dsm_probe(struct drm_device *dev);
+#if defined(CONFIG_ACPI)
+void nouveau_register_dsm_handler(void);
+void nouveau_unregister_dsm_handler(void);
 #else
-static inline int nouveau_hybrid_setup(struct drm_device *dev)
-{
-	return 0;
-}
-static inline bool nouveau_dsm_probe(struct drm_device *dev)
-{
-	return false;
-}
+static inline void nouveau_register_dsm_handler(void) {}
+static inline void nouveau_unregister_dsm_handler(void) {}
 #endif
 
 /* nouveau_backlight.c */
@@ -928,6 +921,10 @@ extern void nv40_fb_takedown(struct drm_
 extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t,
 				      uint32_t, uint32_t);
 
+/* nv50_fb.c */
+extern int  nv50_fb_init(struct drm_device *);
+extern void nv50_fb_takedown(struct drm_device *);
+
 /* nv04_fifo.c */
 extern int  nv04_fifo_init(struct drm_device *);
 extern void nv04_fifo_disable(struct drm_device *);
@@ -1027,6 +1024,7 @@ extern void nv50_graph_destroy_context(s
 extern int  nv50_graph_load_context(struct nouveau_channel *);
 extern int  nv50_graph_unload_context(struct drm_device *);
 extern void nv50_graph_context_switch(struct drm_device *);
+extern int  nv50_grctx_init(struct nouveau_grctx *);
 
 /* nouveau_grctx.c */
 extern int  nouveau_grctx_prog_load(struct drm_device *);
@@ -1119,7 +1117,8 @@ extern int nouveau_bo_pin(struct nouveau
 extern int nouveau_bo_unpin(struct nouveau_bo *);
 extern int nouveau_bo_map(struct nouveau_bo *);
 extern void nouveau_bo_unmap(struct nouveau_bo *);
-extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t memtype);
+extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t type,
+				     uint32_t busy);
 extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index);
 extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val);
 extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index);
@@ -1152,16 +1151,6 @@ extern int nouveau_gem_ioctl_new(struct
 				 struct drm_file *);
 extern int nouveau_gem_ioctl_pushbuf(struct drm_device *, void *,
 				     struct drm_file *);
-extern int nouveau_gem_ioctl_pushbuf_call(struct drm_device *, void *,
-					  struct drm_file *);
-extern int nouveau_gem_ioctl_pushbuf_call2(struct drm_device *, void *,
-					   struct drm_file *);
-extern int nouveau_gem_ioctl_pin(struct drm_device *, void *,
-				 struct drm_file *);
-extern int nouveau_gem_ioctl_unpin(struct drm_device *, void *,
-				   struct drm_file *);
-extern int nouveau_gem_ioctl_tile(struct drm_device *, void *,
-				  struct drm_file *);
 extern int nouveau_gem_ioctl_cpu_prep(struct drm_device *, void *,
 				      struct drm_file *);
 extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *,
@@ -1173,6 +1162,10 @@ extern int nouveau_gem_ioctl_info(struct
 int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
 int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
 
+/* nv50_gpio.c */
+int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
+int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
+
 #ifndef ioread32_native
 #ifdef __BIG_ENDIAN
 #define ioread16_native ioread16be
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_encoder.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_encoder.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_encoder.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_encoder.h	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,7 @@ struct nouveau_encoder {
 
 	union {
 		struct {
+			int mc_unknown;
 			int dpcd_version;
 			int link_nr;
 			int link_bw;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_fbcon.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_fbcon.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_fbcon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_fbcon.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,12 +30,12 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/tty.h>
-#include <linux/slab.h>
 #include <linux/sysrq.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/screen_info.h>
+#include <linux/vga_switcheroo.h>
 
 #include "drmP.h"
 #include "drm.h"
@@ -370,6 +370,7 @@ nouveau_fbcon_create(struct drm_device *
 						nvbo->bo.offset, nvbo);
 
 	mutex_unlock(&dev->struct_mutex);
+	vga_switcheroo_client_fb_set(dev->pdev, info);
 	return 0;
 
 out_unref:
@@ -401,10 +402,8 @@ nouveau_fbcon_remove(struct drm_device *
 
 		unregister_framebuffer(info);
 		nouveau_bo_unmap(nouveau_fb->nvbo);
-		mutex_lock(&dev->struct_mutex);
-		drm_gem_object_unreference(nouveau_fb->nvbo->gem);
+		drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem);
 		nouveau_fb->nvbo = NULL;
-		mutex_unlock(&dev->struct_mutex);
 		if (par)
 			drm_fb_helper_free(&par->helper);
 		framebuffer_release(info);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_gem.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_gem.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_gem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_gem.c	2010-05-16 17:17:36.000000000 -0400
@@ -167,12 +167,10 @@ nouveau_gem_ioctl_new(struct drm_device
 
 	ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle);
 out:
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_handle_unreference(nvbo->gem);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_handle_unreference_unlocked(nvbo->gem);
 
 	if (ret)
-		drm_gem_object_unreference(nvbo->gem);
+		drm_gem_object_unreference_unlocked(nvbo->gem);
 	return ret;
 }
 
@@ -182,40 +180,35 @@ nouveau_gem_set_domain(struct drm_gem_ob
 {
 	struct nouveau_bo *nvbo = gem->driver_private;
 	struct ttm_buffer_object *bo = &nvbo->bo;
-	uint64_t flags;
+	uint32_t domains = valid_domains &
+		(write_domains ? write_domains : read_domains);
+	uint32_t pref_flags = 0, valid_flags = 0;
 
-	if (!valid_domains || (!read_domains && !write_domains))
+	if (!domains)
 		return -EINVAL;
 
-	if (write_domains) {
-		if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
-		    (write_domains & NOUVEAU_GEM_DOMAIN_VRAM))
-			flags = TTM_PL_FLAG_VRAM;
-		else
-		if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) &&
-		    (write_domains & NOUVEAU_GEM_DOMAIN_GART))
-			flags = TTM_PL_FLAG_TT;
-		else
-			return -EINVAL;
-	} else {
-		if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
-		    (read_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
-		    bo->mem.mem_type == TTM_PL_VRAM)
-			flags = TTM_PL_FLAG_VRAM;
-		else
-		if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) &&
-		    (read_domains & NOUVEAU_GEM_DOMAIN_GART) &&
-		    bo->mem.mem_type == TTM_PL_TT)
-			flags = TTM_PL_FLAG_TT;
-		else
-		if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
-		    (read_domains & NOUVEAU_GEM_DOMAIN_VRAM))
-			flags = TTM_PL_FLAG_VRAM;
-		else
-			flags = TTM_PL_FLAG_TT;
-	}
+	if (valid_domains & NOUVEAU_GEM_DOMAIN_VRAM)
+		valid_flags |= TTM_PL_FLAG_VRAM;
+
+	if (valid_domains & NOUVEAU_GEM_DOMAIN_GART)
+		valid_flags |= TTM_PL_FLAG_TT;
+
+	if ((domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
+	    bo->mem.mem_type == TTM_PL_VRAM)
+		pref_flags |= TTM_PL_FLAG_VRAM;
+
+	else if ((domains & NOUVEAU_GEM_DOMAIN_GART) &&
+		 bo->mem.mem_type == TTM_PL_TT)
+		pref_flags |= TTM_PL_FLAG_TT;
+
+	else if (domains & NOUVEAU_GEM_DOMAIN_VRAM)
+		pref_flags |= TTM_PL_FLAG_VRAM;
+
+	else
+		pref_flags |= TTM_PL_FLAG_TT;
+
+	nouveau_bo_placement_set(nvbo, pref_flags, valid_flags);
 
-	nouveau_bo_placement_set(nvbo, flags);
 	return 0;
 }
 
@@ -243,6 +236,11 @@ validate_fini_list(struct list_head *lis
 			nouveau_fence_unref((void *)&prev_fence);
 		}
 
+		if (unlikely(nvbo->validate_mapped)) {
+			ttm_bo_kunmap(&nvbo->kmap);
+			nvbo->validate_mapped = false;
+		}
+
 		list_del(&nvbo->entry);
 		nvbo->reserved_by = NULL;
 		ttm_bo_unreserve(&nvbo->bo);
@@ -302,11 +300,14 @@ retry:
 			if (ret == -EAGAIN)
 				ret = ttm_bo_wait_unreserved(&nvbo->bo, false);
 			drm_gem_object_unreference(gem);
-			if (ret)
+			if (ret) {
+				NV_ERROR(dev, "fail reserve\n");
 				return ret;
+			}
 			goto retry;
 		}
 
+		b->user_priv = (uint64_t)(unsigned long)nvbo;
 		nvbo->reserved_by = file_priv;
 		nvbo->pbbo_index = i;
 		if ((b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
@@ -336,8 +337,10 @@ retry:
 			}
 
 			ret = ttm_bo_wait_cpu(&nvbo->bo, false);
-			if (ret)
+			if (ret) {
+				NV_ERROR(dev, "fail wait_cpu\n");
 				return ret;
+			}
 			goto retry;
 		}
 	}
@@ -351,6 +354,7 @@ validate_list(struct nouveau_channel *ch
 {
 	struct drm_nouveau_gem_pushbuf_bo __user *upbbo =
 				(void __force __user *)(uintptr_t)user_pbbo_ptr;
+	struct drm_device *dev = chan->dev;
 	struct nouveau_bo *nvbo;
 	int ret, relocs = 0;
 
@@ -362,39 +366,46 @@ validate_list(struct nouveau_channel *ch
 			spin_lock(&nvbo->bo.lock);
 			ret = ttm_bo_wait(&nvbo->bo, false, false, false);
 			spin_unlock(&nvbo->bo.lock);
-			if (unlikely(ret))
+			if (unlikely(ret)) {
+				NV_ERROR(dev, "fail wait other chan\n");
 				return ret;
+			}
 		}
 
 		ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains,
 					     b->write_domains,
 					     b->valid_domains);
-		if (unlikely(ret))
+		if (unlikely(ret)) {
+			NV_ERROR(dev, "fail set_domain\n");
 			return ret;
+		}
 
 		nvbo->channel = chan;
 		ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement,
 				      false, false);
 		nvbo->channel = NULL;
-		if (unlikely(ret))
+		if (unlikely(ret)) {
+			NV_ERROR(dev, "fail ttm_validate\n");
 			return ret;
+		}
 
-		if (nvbo->bo.offset == b->presumed_offset &&
+		if (nvbo->bo.offset == b->presumed.offset &&
 		    ((nvbo->bo.mem.mem_type == TTM_PL_VRAM &&
-		      b->presumed_domain & NOUVEAU_GEM_DOMAIN_VRAM) ||
+		      b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) ||
 		     (nvbo->bo.mem.mem_type == TTM_PL_TT &&
-		      b->presumed_domain & NOUVEAU_GEM_DOMAIN_GART)))
+		      b->presumed.domain & NOUVEAU_GEM_DOMAIN_GART)))
 			continue;
 
 		if (nvbo->bo.mem.mem_type == TTM_PL_TT)
-			b->presumed_domain = NOUVEAU_GEM_DOMAIN_GART;
+			b->presumed.domain = NOUVEAU_GEM_DOMAIN_GART;
 		else
-			b->presumed_domain = NOUVEAU_GEM_DOMAIN_VRAM;
-		b->presumed_offset = nvbo->bo.offset;
-		b->presumed_ok = 0;
+			b->presumed.domain = NOUVEAU_GEM_DOMAIN_VRAM;
+		b->presumed.offset = nvbo->bo.offset;
+		b->presumed.valid = 0;
 		relocs++;
 
-		if (DRM_COPY_TO_USER(&upbbo[nvbo->pbbo_index], b, sizeof(*b)))
+		if (DRM_COPY_TO_USER(&upbbo[nvbo->pbbo_index].presumed,
+				     &b->presumed, sizeof(b->presumed)))
 			return -EFAULT;
 	}
 
@@ -408,6 +419,7 @@ nouveau_gem_pushbuf_validate(struct nouv
 			     uint64_t user_buffers, int nr_buffers,
 			     struct validate_op *op, int *apply_relocs)
 {
+	struct drm_device *dev = chan->dev;
 	int ret, relocs = 0;
 
 	INIT_LIST_HEAD(&op->vram_list);
@@ -418,11 +430,14 @@ nouveau_gem_pushbuf_validate(struct nouv
 		return 0;
 
 	ret = validate_init(chan, file_priv, pbbo, nr_buffers, op);
-	if (unlikely(ret))
+	if (unlikely(ret)) {
+		NV_ERROR(dev, "validate_init\n");
 		return ret;
+	}
 
 	ret = validate_list(chan, &op->vram_list, pbbo, user_buffers);
 	if (unlikely(ret < 0)) {
+		NV_ERROR(dev, "validate vram_list\n");
 		validate_fini(op, NULL);
 		return ret;
 	}
@@ -430,6 +445,7 @@ nouveau_gem_pushbuf_validate(struct nouv
 
 	ret = validate_list(chan, &op->gart_list, pbbo, user_buffers);
 	if (unlikely(ret < 0)) {
+		NV_ERROR(dev, "validate gart_list\n");
 		validate_fini(op, NULL);
 		return ret;
 	}
@@ -437,6 +453,7 @@ nouveau_gem_pushbuf_validate(struct nouv
 
 	ret = validate_list(chan, &op->both_list, pbbo, user_buffers);
 	if (unlikely(ret < 0)) {
+		NV_ERROR(dev, "validate both_list\n");
 		validate_fini(op, NULL);
 		return ret;
 	}
@@ -465,59 +482,82 @@ u_memcpya(uint64_t user, unsigned nmemb,
 }
 
 static int
-nouveau_gem_pushbuf_reloc_apply(struct nouveau_channel *chan, int nr_bo,
-				struct drm_nouveau_gem_pushbuf_bo *bo,
-				unsigned nr_relocs, uint64_t ptr_relocs,
-				unsigned nr_dwords, unsigned first_dword,
-				uint32_t *pushbuf, bool is_iomem)
+nouveau_gem_pushbuf_reloc_apply(struct drm_device *dev,
+				struct drm_nouveau_gem_pushbuf *req,
+				struct drm_nouveau_gem_pushbuf_bo *bo)
 {
 	struct drm_nouveau_gem_pushbuf_reloc *reloc = NULL;
-	struct drm_device *dev = chan->dev;
 	int ret = 0;
 	unsigned i;
 
-	reloc = u_memcpya(ptr_relocs, nr_relocs, sizeof(*reloc));
+	reloc = u_memcpya(req->relocs, req->nr_relocs, sizeof(*reloc));
 	if (IS_ERR(reloc))
 		return PTR_ERR(reloc);
 
-	for (i = 0; i < nr_relocs; i++) {
+	for (i = 0; i < req->nr_relocs; i++) {
 		struct drm_nouveau_gem_pushbuf_reloc *r = &reloc[i];
 		struct drm_nouveau_gem_pushbuf_bo *b;
+		struct nouveau_bo *nvbo;
 		uint32_t data;
 
-		if (r->bo_index >= nr_bo || r->reloc_index < first_dword ||
-		    r->reloc_index >= first_dword + nr_dwords) {
-			NV_ERROR(dev, "Bad relocation %d\n", i);
-			NV_ERROR(dev, "  bo: %d max %d\n", r->bo_index, nr_bo);
-			NV_ERROR(dev, "  id: %d max %d\n", r->reloc_index, nr_dwords);
+		if (unlikely(r->bo_index > req->nr_buffers)) {
+			NV_ERROR(dev, "reloc bo index invalid\n");
 			ret = -EINVAL;
 			break;
 		}
 
 		b = &bo[r->bo_index];
-		if (b->presumed_ok)
+		if (b->presumed.valid)
 			continue;
 
+		if (unlikely(r->reloc_bo_index > req->nr_buffers)) {
+			NV_ERROR(dev, "reloc container bo index invalid\n");
+			ret = -EINVAL;
+			break;
+		}
+		nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv;
+
+		if (unlikely(r->reloc_bo_offset + 4 >
+			     nvbo->bo.mem.num_pages << PAGE_SHIFT)) {
+			NV_ERROR(dev, "reloc outside of bo\n");
+			ret = -EINVAL;
+			break;
+		}
+
+		if (!nvbo->kmap.virtual) {
+			ret = ttm_bo_kmap(&nvbo->bo, 0, nvbo->bo.mem.num_pages,
+					  &nvbo->kmap);
+			if (ret) {
+				NV_ERROR(dev, "failed kmap for reloc\n");
+				break;
+			}
+			nvbo->validate_mapped = true;
+		}
+
 		if (r->flags & NOUVEAU_GEM_RELOC_LOW)
-			data = b->presumed_offset + r->data;
+			data = b->presumed.offset + r->data;
 		else
 		if (r->flags & NOUVEAU_GEM_RELOC_HIGH)
-			data = (b->presumed_offset + r->data) >> 32;
+			data = (b->presumed.offset + r->data) >> 32;
 		else
 			data = r->data;
 
 		if (r->flags & NOUVEAU_GEM_RELOC_OR) {
-			if (b->presumed_domain == NOUVEAU_GEM_DOMAIN_GART)
+			if (b->presumed.domain == NOUVEAU_GEM_DOMAIN_GART)
 				data |= r->tor;
 			else
 				data |= r->vor;
 		}
 
-		if (is_iomem)
-			iowrite32_native(data, (void __force __iomem *)
-						&pushbuf[r->reloc_index]);
-		else
-			pushbuf[r->reloc_index] = data;
+		spin_lock(&nvbo->bo.lock);
+		ret = ttm_bo_wait(&nvbo->bo, false, false, false);
+		spin_unlock(&nvbo->bo.lock);
+		if (ret) {
+			NV_ERROR(dev, "reloc wait_idle failed: %d\n", ret);
+			break;
+		}
+
+		nouveau_bo_wr32(nvbo, r->reloc_bo_offset >> 2, data);
 	}
 
 	kfree(reloc);
@@ -528,127 +568,50 @@ int
 nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
 			  struct drm_file *file_priv)
 {
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct drm_nouveau_gem_pushbuf *req = data;
-	struct drm_nouveau_gem_pushbuf_bo *bo = NULL;
+	struct drm_nouveau_gem_pushbuf_push *push;
+	struct drm_nouveau_gem_pushbuf_bo *bo;
 	struct nouveau_channel *chan;
 	struct validate_op op;
-	struct nouveau_fence* fence = 0;
-	uint32_t *pushbuf = NULL;
-	int ret = 0, do_reloc = 0, i;
+	struct nouveau_fence *fence = 0;
+	int i, j, ret = 0, do_reloc = 0;
 
 	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
 	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan);
 
-	if (req->nr_dwords >= chan->dma.max ||
-	    req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS ||
-	    req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS) {
-		NV_ERROR(dev, "Pushbuf config exceeds limits:\n");
-		NV_ERROR(dev, "  dwords : %d max %d\n", req->nr_dwords,
-			 chan->dma.max - 1);
-		NV_ERROR(dev, "  buffers: %d max %d\n", req->nr_buffers,
-			 NOUVEAU_GEM_MAX_BUFFERS);
-		NV_ERROR(dev, "  relocs : %d max %d\n", req->nr_relocs,
-			 NOUVEAU_GEM_MAX_RELOCS);
-		return -EINVAL;
-	}
-
-	pushbuf = u_memcpya(req->dwords, req->nr_dwords, sizeof(uint32_t));
-	if (IS_ERR(pushbuf))
-		return PTR_ERR(pushbuf);
-
-	bo = u_memcpya(req->buffers, req->nr_buffers, sizeof(*bo));
-	if (IS_ERR(bo)) {
-		kfree(pushbuf);
-		return PTR_ERR(bo);
-	}
-
-	mutex_lock(&dev->struct_mutex);
-
-	/* Validate buffer list */
-	ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers,
-					   req->nr_buffers, &op, &do_reloc);
-	if (ret)
-		goto out;
-
-	/* Apply any relocations that are required */
-	if (do_reloc) {
-		ret = nouveau_gem_pushbuf_reloc_apply(chan, req->nr_buffers,
-						      bo, req->nr_relocs,
-						      req->relocs,
-						      req->nr_dwords, 0,
-						      pushbuf, false);
-		if (ret)
-			goto out;
-	}
-
-	/* Emit push buffer to the hw
-	 */
-	ret = RING_SPACE(chan, req->nr_dwords);
-	if (ret)
-		goto out;
-
-	OUT_RINGp(chan, pushbuf, req->nr_dwords);
+	req->vram_available = dev_priv->fb_aper_free;
+	req->gart_available = dev_priv->gart_info.aper_free;
+	if (unlikely(req->nr_push == 0))
+		goto out_next;
 
-	ret = nouveau_fence_new(chan, &fence, true);
-	if (ret) {
-		NV_ERROR(dev, "error fencing pushbuf: %d\n", ret);
-		WIND_RING(chan);
-		goto out;
+	if (unlikely(req->nr_push > NOUVEAU_GEM_MAX_PUSH)) {
+		NV_ERROR(dev, "pushbuf push count exceeds limit: %d max %d\n",
+			 req->nr_push, NOUVEAU_GEM_MAX_PUSH);
+		return -EINVAL;
 	}
 
-	if (nouveau_gem_pushbuf_sync(chan)) {
-		ret = nouveau_fence_wait(fence, NULL, false, false);
-		if (ret) {
-			for (i = 0; i < req->nr_dwords; i++)
-				NV_ERROR(dev, "0x%08x\n", pushbuf[i]);
-			NV_ERROR(dev, "^^ above push buffer is fail :(\n");
-		}
+	if (unlikely(req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS)) {
+		NV_ERROR(dev, "pushbuf bo count exceeds limit: %d max %d\n",
+			 req->nr_buffers, NOUVEAU_GEM_MAX_BUFFERS);
+		return -EINVAL;
 	}
 
-out:
-	validate_fini(&op, fence);
-	nouveau_fence_unref((void**)&fence);
-	mutex_unlock(&dev->struct_mutex);
-	kfree(pushbuf);
-	kfree(bo);
-	return ret;
-}
-
-#define PUSHBUF_CAL (dev_priv->card_type >= NV_20)
-
-int
-nouveau_gem_ioctl_pushbuf_call(struct drm_device *dev, void *data,
-			       struct drm_file *file_priv)
-{
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct drm_nouveau_gem_pushbuf_call *req = data;
-	struct drm_nouveau_gem_pushbuf_bo *bo = NULL;
-	struct nouveau_channel *chan;
-	struct drm_gem_object *gem;
-	struct nouveau_bo *pbbo;
-	struct validate_op op;
-	struct nouveau_fence* fence = 0;
-	int i, ret = 0, do_reloc = 0;
-
-	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
-	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan);
-
-	if (unlikely(req->handle == 0))
-		goto out_next;
-
-	if (req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS ||
-	    req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS) {
-		NV_ERROR(dev, "Pushbuf config exceeds limits:\n");
-		NV_ERROR(dev, "  buffers: %d max %d\n", req->nr_buffers,
-			 NOUVEAU_GEM_MAX_BUFFERS);
-		NV_ERROR(dev, "  relocs : %d max %d\n", req->nr_relocs,
-			 NOUVEAU_GEM_MAX_RELOCS);
+	if (unlikely(req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS)) {
+		NV_ERROR(dev, "pushbuf reloc count exceeds limit: %d max %d\n",
+			 req->nr_relocs, NOUVEAU_GEM_MAX_RELOCS);
 		return -EINVAL;
 	}
 
+	push = u_memcpya(req->push, req->nr_push, sizeof(*push));
+	if (IS_ERR(push))
+		return PTR_ERR(push);
+
 	bo = u_memcpya(req->buffers, req->nr_buffers, sizeof(*bo));
-	if (IS_ERR(bo))
+	if (IS_ERR(bo)) {
+		kfree(push);
 		return PTR_ERR(bo);
+	}
 
 	mutex_lock(&dev->struct_mutex);
 
@@ -660,122 +623,84 @@ nouveau_gem_ioctl_pushbuf_call(struct dr
 		goto out;
 	}
 
-	/* Validate DMA push buffer */
-	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
-	if (!gem) {
-		NV_ERROR(dev, "Unknown pb handle 0x%08x\n", req->handle);
-		ret = -EINVAL;
-		goto out;
-	}
-	pbbo = nouveau_gem_object(gem);
-
-	if ((req->offset & 3) || req->nr_dwords < 2 ||
-	    (unsigned long)req->offset > (unsigned long)pbbo->bo.mem.size ||
-	    (unsigned long)req->nr_dwords >
-	     ((unsigned long)(pbbo->bo.mem.size - req->offset ) >> 2)) {
-		NV_ERROR(dev, "pb call misaligned or out of bounds: "
-			      "%d + %d * 4 > %ld\n",
-			 req->offset, req->nr_dwords, pbbo->bo.mem.size);
-		ret = -EINVAL;
-		drm_gem_object_unreference(gem);
-		goto out;
-	}
-
-	ret = ttm_bo_reserve(&pbbo->bo, false, false, true,
-			     chan->fence.sequence);
-	if (ret) {
-		NV_ERROR(dev, "resv pb: %d\n", ret);
-		drm_gem_object_unreference(gem);
-		goto out;
-	}
-
-	nouveau_bo_placement_set(pbbo, 1 << chan->pushbuf_bo->bo.mem.mem_type);
-	ret = ttm_bo_validate(&pbbo->bo, &pbbo->placement, false, false);
-	if (ret) {
-		NV_ERROR(dev, "validate pb: %d\n", ret);
-		ttm_bo_unreserve(&pbbo->bo);
-		drm_gem_object_unreference(gem);
-		goto out;
-	}
-
-	list_add_tail(&pbbo->entry, &op.both_list);
-
-	/* If presumed return address doesn't match, we need to map the
-	 * push buffer and fix it..
-	 */
-	if (!PUSHBUF_CAL) {
-		uint32_t retaddy;
-
-		if (chan->dma.free < 4 + NOUVEAU_DMA_SKIPS) {
-			ret = nouveau_dma_wait(chan, 4 + NOUVEAU_DMA_SKIPS);
-			if (ret) {
-				NV_ERROR(dev, "jmp_space: %d\n", ret);
-				goto out;
-			}
-		}
-
-		retaddy  = chan->pushbuf_base + ((chan->dma.cur + 2) << 2);
-		retaddy |= 0x20000000;
-		if (retaddy != req->suffix0) {
-			req->suffix0 = retaddy;
-			do_reloc = 1;
-		}
-	}
-
 	/* Apply any relocations that are required */
 	if (do_reloc) {
-		void *pbvirt;
-		bool is_iomem;
-		ret = ttm_bo_kmap(&pbbo->bo, 0, pbbo->bo.mem.num_pages,
-				  &pbbo->kmap);
+		ret = nouveau_gem_pushbuf_reloc_apply(dev, req, bo);
 		if (ret) {
-			NV_ERROR(dev, "kmap pb: %d\n", ret);
+			NV_ERROR(dev, "reloc apply: %d\n", ret);
 			goto out;
 		}
+	}
 
-		pbvirt = ttm_kmap_obj_virtual(&pbbo->kmap, &is_iomem);
-		ret = nouveau_gem_pushbuf_reloc_apply(chan, req->nr_buffers, bo,
-						      req->nr_relocs,
-						      req->relocs,
-						      req->nr_dwords,
-						      req->offset / 4,
-						      pbvirt, is_iomem);
-
-		if (!PUSHBUF_CAL) {
-			nouveau_bo_wr32(pbbo,
-					req->offset / 4 + req->nr_dwords - 2,
-					req->suffix0);
-		}
-
-		ttm_bo_kunmap(&pbbo->kmap);
+	if (chan->dma.ib_max) {
+		ret = nouveau_dma_wait(chan, req->nr_push + 1, 6);
 		if (ret) {
-			NV_ERROR(dev, "reloc apply: %d\n", ret);
+			NV_INFO(dev, "nv50cal_space: %d\n", ret);
 			goto out;
 		}
-	}
 
-	if (PUSHBUF_CAL) {
-		ret = RING_SPACE(chan, 2);
+		for (i = 0; i < req->nr_push; i++) {
+			struct nouveau_bo *nvbo = (void *)(unsigned long)
+				bo[push[i].bo_index].user_priv;
+
+			nv50_dma_push(chan, nvbo, push[i].offset,
+				      push[i].length);
+		}
+	} else
+	if (dev_priv->card_type >= NV_20) {
+		ret = RING_SPACE(chan, req->nr_push * 2);
 		if (ret) {
 			NV_ERROR(dev, "cal_space: %d\n", ret);
 			goto out;
 		}
-		OUT_RING(chan, ((pbbo->bo.mem.mm_node->start << PAGE_SHIFT) +
-				  req->offset) | 2);
-		OUT_RING(chan, 0);
+
+		for (i = 0; i < req->nr_push; i++) {
+			struct nouveau_bo *nvbo = (void *)(unsigned long)
+				bo[push[i].bo_index].user_priv;
+			struct drm_mm_node *mem = nvbo->bo.mem.mm_node;
+
+			OUT_RING(chan, ((mem->start << PAGE_SHIFT) +
+					push[i].offset) | 2);
+			OUT_RING(chan, 0);
+		}
 	} else {
-		ret = RING_SPACE(chan, 2 + NOUVEAU_DMA_SKIPS);
+		ret = RING_SPACE(chan, req->nr_push * (2 + NOUVEAU_DMA_SKIPS));
 		if (ret) {
 			NV_ERROR(dev, "jmp_space: %d\n", ret);
 			goto out;
 		}
-		OUT_RING(chan, ((pbbo->bo.mem.mm_node->start << PAGE_SHIFT) +
-				  req->offset) | 0x20000000);
-		OUT_RING(chan, 0);
 
-		/* Space the jumps apart with NOPs. */
-		for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
+		for (i = 0; i < req->nr_push; i++) {
+			struct nouveau_bo *nvbo = (void *)(unsigned long)
+				bo[push[i].bo_index].user_priv;
+			struct drm_mm_node *mem = nvbo->bo.mem.mm_node;
+			uint32_t cmd;
+
+			cmd = chan->pushbuf_base + ((chan->dma.cur + 2) << 2);
+			cmd |= 0x20000000;
+			if (unlikely(cmd != req->suffix0)) {
+				if (!nvbo->kmap.virtual) {
+					ret = ttm_bo_kmap(&nvbo->bo, 0,
+							  nvbo->bo.mem.
+							  num_pages,
+							  &nvbo->kmap);
+					if (ret) {
+						WIND_RING(chan);
+						goto out;
+					}
+					nvbo->validate_mapped = true;
+				}
+
+				nouveau_bo_wr32(nvbo, (push[i].offset +
+						push[i].length - 8) / 4, cmd);
+			}
+
+			OUT_RING(chan, ((mem->start << PAGE_SHIFT) +
+					push[i].offset) | 0x20000000);
 			OUT_RING(chan, 0);
+			for (j = 0; j < NOUVEAU_DMA_SKIPS; j++)
+				OUT_RING(chan, 0);
+		}
 	}
 
 	ret = nouveau_fence_new(chan, &fence, true);
@@ -790,9 +715,14 @@ out:
 	nouveau_fence_unref((void**)&fence);
 	mutex_unlock(&dev->struct_mutex);
 	kfree(bo);
+	kfree(push);
 
 out_next:
-	if (PUSHBUF_CAL) {
+	if (chan->dma.ib_max) {
+		req->suffix0 = 0x00000000;
+		req->suffix1 = 0x00000000;
+	} else
+	if (dev_priv->card_type >= NV_20) {
 		req->suffix0 = 0x00020000;
 		req->suffix1 = 0x00000000;
 	} else {
@@ -804,19 +734,6 @@ out_next:
 	return ret;
 }
 
-int
-nouveau_gem_ioctl_pushbuf_call2(struct drm_device *dev, void *data,
-				struct drm_file *file_priv)
-{
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct drm_nouveau_gem_pushbuf_call *req = data;
-
-	req->vram_available = dev_priv->fb_aper_free;
-	req->gart_available = dev_priv->gart_info.aper_free;
-
-	return nouveau_gem_ioctl_pushbuf_call(dev, data, file_priv);
-}
-
 static inline uint32_t
 domain_to_ttm(struct nouveau_bo *nvbo, uint32_t domain)
 {
@@ -831,74 +748,6 @@ domain_to_ttm(struct nouveau_bo *nvbo, u
 }
 
 int
-nouveau_gem_ioctl_pin(struct drm_device *dev, void *data,
-		      struct drm_file *file_priv)
-{
-	struct drm_nouveau_gem_pin *req = data;
-	struct drm_gem_object *gem;
-	struct nouveau_bo *nvbo;
-	int ret = 0;
-
-	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
-
-	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-		NV_ERROR(dev, "pin only allowed without kernel modesetting\n");
-		return -EINVAL;
-	}
-
-	if (!DRM_SUSER(DRM_CURPROC))
-		return -EPERM;
-
-	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
-	if (!gem)
-		return -EINVAL;
-	nvbo = nouveau_gem_object(gem);
-
-	ret = nouveau_bo_pin(nvbo, domain_to_ttm(nvbo, req->domain));
-	if (ret)
-		goto out;
-
-	req->offset = nvbo->bo.offset;
-	if (nvbo->bo.mem.mem_type == TTM_PL_TT)
-		req->domain = NOUVEAU_GEM_DOMAIN_GART;
-	else
-		req->domain = NOUVEAU_GEM_DOMAIN_VRAM;
-
-out:
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(gem);
-	mutex_unlock(&dev->struct_mutex);
-
-	return ret;
-}
-
-int
-nouveau_gem_ioctl_unpin(struct drm_device *dev, void *data,
-			struct drm_file *file_priv)
-{
-	struct drm_nouveau_gem_pin *req = data;
-	struct drm_gem_object *gem;
-	int ret;
-
-	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
-
-	if (drm_core_check_feature(dev, DRIVER_MODESET))
-		return -EINVAL;
-
-	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
-	if (!gem)
-		return -EINVAL;
-
-	ret = nouveau_bo_unpin(nouveau_gem_object(gem));
-
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(gem);
-	mutex_unlock(&dev->struct_mutex);
-
-	return ret;
-}
-
-int
 nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
 			   struct drm_file *file_priv)
 {
@@ -935,9 +784,7 @@ nouveau_gem_ioctl_cpu_prep(struct drm_de
 	}
 
 out:
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(gem);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(gem);
 	return ret;
 }
 
@@ -965,9 +812,7 @@ nouveau_gem_ioctl_cpu_fini(struct drm_de
 	ret = 0;
 
 out:
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(gem);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(gem);
 	return ret;
 }
 
@@ -986,9 +831,7 @@ nouveau_gem_ioctl_info(struct drm_device
 		return -EINVAL;
 
 	ret = nouveau_gem_info(gem, req);
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(gem);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(gem);
 	return ret;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_grctx.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_grctx.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_grctx.c	2013-05-03 12:03:17.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_grctx.c	2013-05-03 09:44:27.000000000 -0400
@@ -23,6 +23,7 @@
  */
 
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #include "drmP.h"
 #include "nouveau_drv.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_hw.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_hw.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_hw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_hw.c	2010-05-16 17:17:36.000000000 -0400
@@ -160,7 +160,7 @@ static void
 setPLL_single(struct drm_device *dev, uint32_t reg, struct nouveau_pll_vals *pv)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	int chip_version = dev_priv->vbios->chip_version;
+	int chip_version = dev_priv->vbios.chip_version;
 	uint32_t oldpll = NVReadRAMDAC(dev, 0, reg);
 	int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff;
 	uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1;
@@ -216,7 +216,7 @@ setPLL_double_highregs(struct drm_device
 		       struct nouveau_pll_vals *pv)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	int chip_version = dev_priv->vbios->chip_version;
+	int chip_version = dev_priv->vbios.chip_version;
 	bool nv3035 = chip_version == 0x30 || chip_version == 0x35;
 	uint32_t reg2 = reg1 + ((reg1 == NV_RAMDAC_VPLL2) ? 0x5c : 0x70);
 	uint32_t oldpll1 = NVReadRAMDAC(dev, 0, reg1);
@@ -374,7 +374,7 @@ nouveau_hw_setpll(struct drm_device *dev
 		  struct nouveau_pll_vals *pv)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	int cv = dev_priv->vbios->chip_version;
+	int cv = dev_priv->vbios.chip_version;
 
 	if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
 	    cv >= 0x40) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_i2c.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_i2c.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -254,16 +254,16 @@ struct nouveau_i2c_chan *
 nouveau_i2c_find(struct drm_device *dev, int index)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 
-	if (index > DCB_MAX_NUM_I2C_ENTRIES)
+	if (index >= DCB_MAX_NUM_I2C_ENTRIES)
 		return NULL;
 
-	if (!bios->bdcb.dcb.i2c[index].chan) {
-		if (nouveau_i2c_init(dev, &bios->bdcb.dcb.i2c[index], index))
+	if (!bios->dcb.i2c[index].chan) {
+		if (nouveau_i2c_init(dev, &bios->dcb.i2c[index], index))
 			return NULL;
 	}
 
-	return bios->bdcb.dcb.i2c[index].chan;
+	return bios->dcb.i2c[index].chan;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_irq.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_irq.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,6 +51,7 @@ nouveau_irq_preinstall(struct drm_device
 
 	if (dev_priv->card_type == NV_50) {
 		INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh);
+		INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh);
 		INIT_LIST_HEAD(&dev_priv->vbl_waiting);
 	}
 }
@@ -311,6 +312,31 @@ nouveau_print_bitfield_names_(uint32_t v
 #define nouveau_print_bitfield_names(val, namelist) \
 	nouveau_print_bitfield_names_((val), (namelist), ARRAY_SIZE(namelist))
 
+struct nouveau_enum_names {
+	uint32_t value;
+	const char *name;
+};
+
+static void
+nouveau_print_enum_names_(uint32_t value,
+				const struct nouveau_enum_names *namelist,
+				const int namelist_len)
+{
+	/*
+	 * Caller must have already printed the KERN_* log level for us.
+	 * Also the caller is responsible for adding the newline.
+	 */
+	int i;
+	for (i = 0; i < namelist_len; ++i) {
+		if (value == namelist[i].value) {
+			printk("%s", namelist[i].name);
+			return;
+		}
+	}
+	printk("unknown value 0x%08x", value);
+}
+#define nouveau_print_enum_names(val, namelist) \
+	nouveau_print_enum_names_((val), (namelist), ARRAY_SIZE(namelist))
 
 static int
 nouveau_graph_chid_from_grctx(struct drm_device *dev)
@@ -427,14 +453,16 @@ nouveau_graph_dump_trap_info(struct drm_
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	uint32_t nsource = trap->nsource, nstatus = trap->nstatus;
 
-	NV_INFO(dev, "%s - nSource:", id);
-	nouveau_print_bitfield_names(nsource, nsource_names);
-	printk(", nStatus:");
-	if (dev_priv->card_type < NV_10)
-		nouveau_print_bitfield_names(nstatus, nstatus_names);
-	else
-		nouveau_print_bitfield_names(nstatus, nstatus_names_nv10);
-	printk("\n");
+	if (dev_priv->card_type < NV_50) {
+		NV_INFO(dev, "%s - nSource:", id);
+		nouveau_print_bitfield_names(nsource, nsource_names);
+		printk(", nStatus:");
+		if (dev_priv->card_type < NV_10)
+			nouveau_print_bitfield_names(nstatus, nstatus_names);
+		else
+			nouveau_print_bitfield_names(nstatus, nstatus_names_nv10);
+		printk("\n");
+	}
 
 	NV_INFO(dev, "%s - Ch %d/%d Class 0x%04x Mthd 0x%04x "
 					"Data 0x%08x:0x%08x\n",
@@ -578,27 +606,502 @@ nouveau_pgraph_irq_handler(struct drm_de
 }
 
 static void
+nv50_pfb_vm_trap(struct drm_device *dev, int display, const char *name)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t trap[6];
+	int i, ch;
+	uint32_t idx = nv_rd32(dev, 0x100c90);
+	if (idx & 0x80000000) {
+		idx &= 0xffffff;
+		if (display) {
+			for (i = 0; i < 6; i++) {
+				nv_wr32(dev, 0x100c90, idx | i << 24);
+				trap[i] = nv_rd32(dev, 0x100c94);
+			}
+			for (ch = 0; ch < dev_priv->engine.fifo.channels; ch++) {
+				struct nouveau_channel *chan = dev_priv->fifos[ch];
+
+				if (!chan || !chan->ramin)
+					continue;
+
+				if (trap[1] == chan->ramin->instance >> 12)
+					break;
+			}
+			NV_INFO(dev, "%s - VM: Trapped %s at %02x%04x%04x status %08x %08x channel %d\n",
+					name, (trap[5]&0x100?"read":"write"),
+					trap[5]&0xff, trap[4]&0xffff,
+					trap[3]&0xffff, trap[0], trap[2], ch);
+		}
+		nv_wr32(dev, 0x100c90, idx | 0x80000000);
+	} else if (display) {
+		NV_INFO(dev, "%s - no VM fault?\n", name);
+	}
+}
+
+static struct nouveau_enum_names nv50_mp_exec_error_names[] =
+{
+	{ 3, "STACK_UNDERFLOW" },
+	{ 4, "QUADON_ACTIVE" },
+	{ 8, "TIMEOUT" },
+	{ 0x10, "INVALID_OPCODE" },
+	{ 0x40, "BREAKPOINT" },
+};
+
+static void
+nv50_pgraph_mp_trap(struct drm_device *dev, int tpid, int display)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t units = nv_rd32(dev, 0x1540);
+	uint32_t addr, mp10, status, pc, oplow, ophigh;
+	int i;
+	int mps = 0;
+	for (i = 0; i < 4; i++) {
+		if (!(units & 1 << (i+24)))
+			continue;
+		if (dev_priv->chipset < 0xa0)
+			addr = 0x408200 + (tpid << 12) + (i << 7);
+		else
+			addr = 0x408100 + (tpid << 11) + (i << 7);
+		mp10 = nv_rd32(dev, addr + 0x10);
+		status = nv_rd32(dev, addr + 0x14);
+		if (!status)
+			continue;
+		if (display) {
+			nv_rd32(dev, addr + 0x20);
+			pc = nv_rd32(dev, addr + 0x24);
+			oplow = nv_rd32(dev, addr + 0x70);
+			ophigh= nv_rd32(dev, addr + 0x74);
+			NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - "
+					"TP %d MP %d: ", tpid, i);
+			nouveau_print_enum_names(status,
+					nv50_mp_exec_error_names);
+			printk(" at %06x warp %d, opcode %08x %08x\n",
+					pc&0xffffff, pc >> 24,
+					oplow, ophigh);
+		}
+		nv_wr32(dev, addr + 0x10, mp10);
+		nv_wr32(dev, addr + 0x14, 0);
+		mps++;
+	}
+	if (!mps && display)
+		NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - TP %d: "
+				"No MPs claiming errors?\n", tpid);
+}
+
+static void
+nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t ustatus_old,
+		uint32_t ustatus_new, int display, const char *name)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int tps = 0;
+	uint32_t units = nv_rd32(dev, 0x1540);
+	int i, r;
+	uint32_t ustatus_addr, ustatus;
+	for (i = 0; i < 16; i++) {
+		if (!(units & (1 << i)))
+			continue;
+		if (dev_priv->chipset < 0xa0)
+			ustatus_addr = ustatus_old + (i << 12);
+		else
+			ustatus_addr = ustatus_new + (i << 11);
+		ustatus = nv_rd32(dev, ustatus_addr) & 0x7fffffff;
+		if (!ustatus)
+			continue;
+		tps++;
+		switch (type) {
+		case 6: /* texture error... unknown for now */
+			nv50_pfb_vm_trap(dev, display, name);
+			if (display) {
+				NV_ERROR(dev, "magic set %d:\n", i);
+				for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4)
+					NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
+						nv_rd32(dev, r));
+			}
+			break;
+		case 7: /* MP error */
+			if (ustatus & 0x00010000) {
+				nv50_pgraph_mp_trap(dev, i, display);
+				ustatus &= ~0x00010000;
+			}
+			break;
+		case 8: /* TPDMA error */
+			{
+			uint32_t e0c = nv_rd32(dev, ustatus_addr + 4);
+			uint32_t e10 = nv_rd32(dev, ustatus_addr + 8);
+			uint32_t e14 = nv_rd32(dev, ustatus_addr + 0xc);
+			uint32_t e18 = nv_rd32(dev, ustatus_addr + 0x10);
+			uint32_t e1c = nv_rd32(dev, ustatus_addr + 0x14);
+			uint32_t e20 = nv_rd32(dev, ustatus_addr + 0x18);
+			uint32_t e24 = nv_rd32(dev, ustatus_addr + 0x1c);
+			nv50_pfb_vm_trap(dev, display, name);
+			/* 2d engine destination */
+			if (ustatus & 0x00000010) {
+				if (display) {
+					NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - Unknown fault at address %02x%08x\n",
+							i, e14, e10);
+					NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
+							i, e0c, e18, e1c, e20, e24);
+				}
+				ustatus &= ~0x00000010;
+			}
+			/* Render target */
+			if (ustatus & 0x00000040) {
+				if (display) {
+					NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - Unknown fault at address %02x%08x\n",
+							i, e14, e10);
+					NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
+							i, e0c, e18, e1c, e20, e24);
+				}
+				ustatus &= ~0x00000040;
+			}
+			/* CUDA memory: l[], g[] or stack. */
+			if (ustatus & 0x00000080) {
+				if (display) {
+					if (e18 & 0x80000000) {
+						/* g[] read fault? */
+						NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global read fault at address %02x%08x\n",
+								i, e14, e10 | ((e18 >> 24) & 0x1f));
+						e18 &= ~0x1f000000;
+					} else if (e18 & 0xc) {
+						/* g[] write fault? */
+						NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global write fault at address %02x%08x\n",
+								i, e14, e10 | ((e18 >> 7) & 0x1f));
+						e18 &= ~0x00000f80;
+					} else {
+						NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Unknown CUDA fault at address %02x%08x\n",
+								i, e14, e10);
+					}
+					NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
+							i, e0c, e18, e1c, e20, e24);
+				}
+				ustatus &= ~0x00000080;
+			}
+			}
+			break;
+		}
+		if (ustatus) {
+			if (display)
+				NV_INFO(dev, "%s - TP%d: Unhandled ustatus 0x%08x\n", name, i, ustatus);
+		}
+		nv_wr32(dev, ustatus_addr, 0xc0000000);
+	}
+
+	if (!tps && display)
+		NV_INFO(dev, "%s - No TPs claiming errors?\n", name);
+}
+
+static void
+nv50_pgraph_trap_handler(struct drm_device *dev)
+{
+	struct nouveau_pgraph_trap trap;
+	uint32_t status = nv_rd32(dev, 0x400108);
+	uint32_t ustatus;
+	int display = nouveau_ratelimit();
+
+
+	if (!status && display) {
+		nouveau_graph_trap_info(dev, &trap);
+		nouveau_graph_dump_trap_info(dev, "PGRAPH_TRAP", &trap);
+		NV_INFO(dev, "PGRAPH_TRAP - no units reporting traps?\n");
+	}
+
+	/* DISPATCH: Relays commands to other units and handles NOTIFY,
+	 * COND, QUERY. If you get a trap from it, the command is still stuck
+	 * in DISPATCH and you need to do something about it. */
+	if (status & 0x001) {
+		ustatus = nv_rd32(dev, 0x400804) & 0x7fffffff;
+		if (!ustatus && display) {
+			NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - no ustatus?\n");
+		}
+
+		/* Known to be triggered by screwed up NOTIFY and COND... */
+		if (ustatus & 0x00000001) {
+			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_FAULT");
+			nv_wr32(dev, 0x400500, 0);
+			if (nv_rd32(dev, 0x400808) & 0x80000000) {
+				if (display) {
+					if (nouveau_graph_trapped_channel(dev, &trap.channel))
+						trap.channel = -1;
+					trap.class = nv_rd32(dev, 0x400814);
+					trap.mthd = nv_rd32(dev, 0x400808) & 0x1ffc;
+					trap.subc = (nv_rd32(dev, 0x400808) >> 16) & 0x7;
+					trap.data = nv_rd32(dev, 0x40080c);
+					trap.data2 = nv_rd32(dev, 0x400810);
+					nouveau_graph_dump_trap_info(dev,
+							"PGRAPH_TRAP_DISPATCH_FAULT", &trap);
+					NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - 400808: %08x\n", nv_rd32(dev, 0x400808));
+					NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - 400848: %08x\n", nv_rd32(dev, 0x400848));
+				}
+				nv_wr32(dev, 0x400808, 0);
+			} else if (display) {
+				NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - No stuck command?\n");
+			}
+			nv_wr32(dev, 0x4008e8, nv_rd32(dev, 0x4008e8) & 3);
+			nv_wr32(dev, 0x400848, 0);
+			ustatus &= ~0x00000001;
+		}
+		if (ustatus & 0x00000002) {
+			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_QUERY");
+			nv_wr32(dev, 0x400500, 0);
+			if (nv_rd32(dev, 0x40084c) & 0x80000000) {
+				if (display) {
+					if (nouveau_graph_trapped_channel(dev, &trap.channel))
+						trap.channel = -1;
+					trap.class = nv_rd32(dev, 0x400814);
+					trap.mthd = nv_rd32(dev, 0x40084c) & 0x1ffc;
+					trap.subc = (nv_rd32(dev, 0x40084c) >> 16) & 0x7;
+					trap.data = nv_rd32(dev, 0x40085c);
+					trap.data2 = 0;
+					nouveau_graph_dump_trap_info(dev,
+							"PGRAPH_TRAP_DISPATCH_QUERY", &trap);
+					NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_QUERY - 40084c: %08x\n", nv_rd32(dev, 0x40084c));
+				}
+				nv_wr32(dev, 0x40084c, 0);
+			} else if (display) {
+				NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_QUERY - No stuck command?\n");
+			}
+			ustatus &= ~0x00000002;
+		}
+		if (ustatus && display)
+			NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - Unhandled ustatus 0x%08x\n", ustatus);
+		nv_wr32(dev, 0x400804, 0xc0000000);
+		nv_wr32(dev, 0x400108, 0x001);
+		status &= ~0x001;
+	}
+
+	/* TRAPs other than dispatch use the "normal" trap regs. */
+	if (status && display) {
+		nouveau_graph_trap_info(dev, &trap);
+		nouveau_graph_dump_trap_info(dev,
+				"PGRAPH_TRAP", &trap);
+	}
+
+	/* M2MF: Memory to memory copy engine. */
+	if (status & 0x002) {
+		ustatus = nv_rd32(dev, 0x406800) & 0x7fffffff;
+		if (!ustatus && display) {
+			NV_INFO(dev, "PGRAPH_TRAP_M2MF - no ustatus?\n");
+		}
+		if (ustatus & 0x00000001) {
+			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_NOTIFY");
+			ustatus &= ~0x00000001;
+		}
+		if (ustatus & 0x00000002) {
+			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_IN");
+			ustatus &= ~0x00000002;
+		}
+		if (ustatus & 0x00000004) {
+			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_OUT");
+			ustatus &= ~0x00000004;
+		}
+		NV_INFO (dev, "PGRAPH_TRAP_M2MF - %08x %08x %08x %08x\n",
+				nv_rd32(dev, 0x406804),
+				nv_rd32(dev, 0x406808),
+				nv_rd32(dev, 0x40680c),
+				nv_rd32(dev, 0x406810));
+		if (ustatus && display)
+			NV_INFO(dev, "PGRAPH_TRAP_M2MF - Unhandled ustatus 0x%08x\n", ustatus);
+		/* No sane way found yet -- just reset the bugger. */
+		nv_wr32(dev, 0x400040, 2);
+		nv_wr32(dev, 0x400040, 0);
+		nv_wr32(dev, 0x406800, 0xc0000000);
+		nv_wr32(dev, 0x400108, 0x002);
+		status &= ~0x002;
+	}
+
+	/* VFETCH: Fetches data from vertex buffers. */
+	if (status & 0x004) {
+		ustatus = nv_rd32(dev, 0x400c04) & 0x7fffffff;
+		if (!ustatus && display) {
+			NV_INFO(dev, "PGRAPH_TRAP_VFETCH - no ustatus?\n");
+		}
+		if (ustatus & 0x00000001) {
+			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_VFETCH_FAULT");
+			NV_INFO (dev, "PGRAPH_TRAP_VFETCH_FAULT - %08x %08x %08x %08x\n",
+					nv_rd32(dev, 0x400c00),
+					nv_rd32(dev, 0x400c08),
+					nv_rd32(dev, 0x400c0c),
+					nv_rd32(dev, 0x400c10));
+			ustatus &= ~0x00000001;
+		}
+		if (ustatus && display)
+			NV_INFO(dev, "PGRAPH_TRAP_VFETCH - Unhandled ustatus 0x%08x\n", ustatus);
+		nv_wr32(dev, 0x400c04, 0xc0000000);
+		nv_wr32(dev, 0x400108, 0x004);
+		status &= ~0x004;
+	}
+
+	/* STRMOUT: DirectX streamout / OpenGL transform feedback. */
+	if (status & 0x008) {
+		ustatus = nv_rd32(dev, 0x401800) & 0x7fffffff;
+		if (!ustatus && display) {
+			NV_INFO(dev, "PGRAPH_TRAP_STRMOUT - no ustatus?\n");
+		}
+		if (ustatus & 0x00000001) {
+			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_STRMOUT_FAULT");
+			NV_INFO (dev, "PGRAPH_TRAP_STRMOUT_FAULT - %08x %08x %08x %08x\n",
+					nv_rd32(dev, 0x401804),
+					nv_rd32(dev, 0x401808),
+					nv_rd32(dev, 0x40180c),
+					nv_rd32(dev, 0x401810));
+			ustatus &= ~0x00000001;
+		}
+		if (ustatus && display)
+			NV_INFO(dev, "PGRAPH_TRAP_STRMOUT - Unhandled ustatus 0x%08x\n", ustatus);
+		/* No sane way found yet -- just reset the bugger. */
+		nv_wr32(dev, 0x400040, 0x80);
+		nv_wr32(dev, 0x400040, 0);
+		nv_wr32(dev, 0x401800, 0xc0000000);
+		nv_wr32(dev, 0x400108, 0x008);
+		status &= ~0x008;
+	}
+
+	/* CCACHE: Handles code and c[] caches and fills them. */
+	if (status & 0x010) {
+		ustatus = nv_rd32(dev, 0x405018) & 0x7fffffff;
+		if (!ustatus && display) {
+			NV_INFO(dev, "PGRAPH_TRAP_CCACHE - no ustatus?\n");
+		}
+		if (ustatus & 0x00000001) {
+			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_CCACHE_FAULT");
+			NV_INFO (dev, "PGRAPH_TRAP_CCACHE_FAULT - %08x %08x %08x %08x %08x %08x %08x\n",
+					nv_rd32(dev, 0x405800),
+					nv_rd32(dev, 0x405804),
+					nv_rd32(dev, 0x405808),
+					nv_rd32(dev, 0x40580c),
+					nv_rd32(dev, 0x405810),
+					nv_rd32(dev, 0x405814),
+					nv_rd32(dev, 0x40581c));
+			ustatus &= ~0x00000001;
+		}
+		if (ustatus && display)
+			NV_INFO(dev, "PGRAPH_TRAP_CCACHE - Unhandled ustatus 0x%08x\n", ustatus);
+		nv_wr32(dev, 0x405018, 0xc0000000);
+		nv_wr32(dev, 0x400108, 0x010);
+		status &= ~0x010;
+	}
+
+	/* Unknown, not seen yet... 0x402000 is the only trap status reg
+	 * remaining, so try to handle it anyway. Perhaps related to that
+	 * unknown DMA slot on tesla? */
+	if (status & 0x20) {
+		nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_UNKC04");
+		ustatus = nv_rd32(dev, 0x402000) & 0x7fffffff;
+		if (display)
+			NV_INFO(dev, "PGRAPH_TRAP_UNKC04 - Unhandled ustatus 0x%08x\n", ustatus);
+		nv_wr32(dev, 0x402000, 0xc0000000);
+		/* no status modifiction on purpose */
+	}
+
+	/* TEXTURE: CUDA texturing units */
+	if (status & 0x040) {
+		nv50_pgraph_tp_trap (dev, 6, 0x408900, 0x408600, display,
+				"PGRAPH_TRAP_TEXTURE");
+		nv_wr32(dev, 0x400108, 0x040);
+		status &= ~0x040;
+	}
+
+	/* MP: CUDA execution engines. */
+	if (status & 0x080) {
+		nv50_pgraph_tp_trap (dev, 7, 0x408314, 0x40831c, display,
+				"PGRAPH_TRAP_MP");
+		nv_wr32(dev, 0x400108, 0x080);
+		status &= ~0x080;
+	}
+
+	/* TPDMA:  Handles TP-initiated uncached memory accesses:
+	 * l[], g[], stack, 2d surfaces, render targets. */
+	if (status & 0x100) {
+		nv50_pgraph_tp_trap (dev, 8, 0x408e08, 0x408708, display,
+				"PGRAPH_TRAP_TPDMA");
+		nv_wr32(dev, 0x400108, 0x100);
+		status &= ~0x100;
+	}
+
+	if (status) {
+		if (display)
+			NV_INFO(dev, "PGRAPH_TRAP - Unknown trap 0x%08x\n",
+				status);
+		nv_wr32(dev, 0x400108, status);
+	}
+}
+
+/* There must be a *lot* of these. Will take some time to gather them up. */
+static struct nouveau_enum_names nv50_data_error_names[] =
+{
+	{ 4,	"INVALID_VALUE" },
+	{ 5,	"INVALID_ENUM" },
+	{ 8,	"INVALID_OBJECT" },
+	{ 0xc,	"INVALID_BITFIELD" },
+	{ 0x28,	"MP_NO_REG_SPACE" },
+	{ 0x2b,	"MP_BLOCK_SIZE_MISMATCH" },
+};
+
+static void
 nv50_pgraph_irq_handler(struct drm_device *dev)
 {
+	struct nouveau_pgraph_trap trap;
+	int unhandled = 0;
 	uint32_t status;
 
 	while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) {
-		uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
-
+		/* NOTIFY: You've set a NOTIFY an a command and it's done. */
 		if (status & 0x00000001) {
-			nouveau_pgraph_intr_notify(dev, nsource);
+			nouveau_graph_trap_info(dev, &trap);
+			if (nouveau_ratelimit())
+				nouveau_graph_dump_trap_info(dev,
+						"PGRAPH_NOTIFY", &trap);
 			status &= ~0x00000001;
 			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001);
 		}
 
-		if (status & 0x00000010) {
-			nouveau_pgraph_intr_error(dev, nsource |
-					NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD);
+		/* COMPUTE_QUERY: Purpose and exact cause unknown, happens
+		 * when you write 0x200 to 0x50c0 method 0x31c. */
+		if (status & 0x00000002) {
+			nouveau_graph_trap_info(dev, &trap);
+			if (nouveau_ratelimit())
+				nouveau_graph_dump_trap_info(dev,
+						"PGRAPH_COMPUTE_QUERY", &trap);
+			status &= ~0x00000002;
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000002);
+		}
 
+		/* Unknown, never seen: 0x4 */
+
+		/* ILLEGAL_MTHD: You used a wrong method for this class. */
+		if (status & 0x00000010) {
+			nouveau_graph_trap_info(dev, &trap);
+			if (nouveau_pgraph_intr_swmthd(dev, &trap))
+				unhandled = 1;
+			if (unhandled && nouveau_ratelimit())
+				nouveau_graph_dump_trap_info(dev,
+						"PGRAPH_ILLEGAL_MTHD", &trap);
 			status &= ~0x00000010;
 			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010);
 		}
 
+		/* ILLEGAL_CLASS: You used a wrong class. */
+		if (status & 0x00000020) {
+			nouveau_graph_trap_info(dev, &trap);
+			if (nouveau_ratelimit())
+				nouveau_graph_dump_trap_info(dev,
+						"PGRAPH_ILLEGAL_CLASS", &trap);
+			status &= ~0x00000020;
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000020);
+		}
+
+		/* DOUBLE_NOTIFY: You tried to set a NOTIFY on another NOTIFY. */
+		if (status & 0x00000040) {
+			nouveau_graph_trap_info(dev, &trap);
+			if (nouveau_ratelimit())
+				nouveau_graph_dump_trap_info(dev,
+						"PGRAPH_DOUBLE_NOTIFY", &trap);
+			status &= ~0x00000040;
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000040);
+		}
+
+		/* CONTEXT_SWITCH: PGRAPH needs us to load a new context */
 		if (status & 0x00001000) {
 			nv_wr32(dev, 0x400500, 0x00000000);
 			nv_wr32(dev, NV03_PGRAPH_INTR,
@@ -613,49 +1116,59 @@ nv50_pgraph_irq_handler(struct drm_devic
 			status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
 		}
 
-		if (status & 0x00100000) {
-			nouveau_pgraph_intr_error(dev, nsource |
-					NV03_PGRAPH_NSOURCE_DATA_ERROR);
+		/* BUFFER_NOTIFY: Your m2mf transfer finished */
+		if (status & 0x00010000) {
+			nouveau_graph_trap_info(dev, &trap);
+			if (nouveau_ratelimit())
+				nouveau_graph_dump_trap_info(dev,
+						"PGRAPH_BUFFER_NOTIFY", &trap);
+			status &= ~0x00010000;
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00010000);
+		}
 
+		/* DATA_ERROR: Invalid value for this method, or invalid
+		 * state in current PGRAPH context for this operation */
+		if (status & 0x00100000) {
+			nouveau_graph_trap_info(dev, &trap);
+			if (nouveau_ratelimit()) {
+				nouveau_graph_dump_trap_info(dev,
+						"PGRAPH_DATA_ERROR", &trap);
+				NV_INFO (dev, "PGRAPH_DATA_ERROR - ");
+				nouveau_print_enum_names(nv_rd32(dev, 0x400110),
+						nv50_data_error_names);
+				printk("\n");
+			}
 			status &= ~0x00100000;
 			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000);
 		}
 
+		/* TRAP: Something bad happened in the middle of command
+		 * execution.  Has a billion types, subtypes, and even
+		 * subsubtypes. */
 		if (status & 0x00200000) {
-			int r;
-
-			nouveau_pgraph_intr_error(dev, nsource |
-					NV03_PGRAPH_NSOURCE_PROTECTION_ERROR);
-
-			NV_ERROR(dev, "magic set 1:\n");
-			for (r = 0x408900; r <= 0x408910; r += 4)
-				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
-					nv_rd32(dev, r));
-			nv_wr32(dev, 0x408900,
-				nv_rd32(dev, 0x408904) | 0xc0000000);
-			for (r = 0x408e08; r <= 0x408e24; r += 4)
-				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
-							nv_rd32(dev, r));
-			nv_wr32(dev, 0x408e08,
-				nv_rd32(dev, 0x408e08) | 0xc0000000);
-
-			NV_ERROR(dev, "magic set 2:\n");
-			for (r = 0x409900; r <= 0x409910; r += 4)
-				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
-					nv_rd32(dev, r));
-			nv_wr32(dev, 0x409900,
-				nv_rd32(dev, 0x409904) | 0xc0000000);
-			for (r = 0x409e08; r <= 0x409e24; r += 4)
-				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
-					nv_rd32(dev, r));
-			nv_wr32(dev, 0x409e08,
-				nv_rd32(dev, 0x409e08) | 0xc0000000);
-
+			nv50_pgraph_trap_handler(dev);
 			status &= ~0x00200000;
-			nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource);
 			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000);
 		}
 
+		/* Unknown, never seen: 0x00400000 */
+
+		/* SINGLE_STEP: Happens on every method if you turned on
+		 * single stepping in 40008c */
+		if (status & 0x01000000) {
+			nouveau_graph_trap_info(dev, &trap);
+			if (nouveau_ratelimit())
+				nouveau_graph_dump_trap_info(dev,
+						"PGRAPH_SINGLE_STEP", &trap);
+			status &= ~0x01000000;
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x01000000);
+		}
+
+		/* 0x02000000 happens when you pause a ctxprog...
+		 * but the only way this can happen that I know is by
+		 * poking the relevant MMIO register, and we don't
+		 * do that. */
+
 		if (status) {
 			NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n",
 				status);
@@ -672,7 +1185,8 @@ nv50_pgraph_irq_handler(struct drm_devic
 	}
 
 	nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING);
-	nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31));
+	if (nv_rd32(dev, 0x400824) & (1 << 31))
+		nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31));
 }
 
 static void
@@ -691,11 +1205,14 @@ nouveau_irq_handler(DRM_IRQ_ARGS)
 	struct drm_device *dev = (struct drm_device *)arg;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	uint32_t status, fbdev_flags = 0;
+	unsigned long flags;
 
 	status = nv_rd32(dev, NV03_PMC_INTR_0);
 	if (!status)
 		return IRQ_NONE;
 
+	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
+
 	if (dev_priv->fbdev_info) {
 		fbdev_flags = dev_priv->fbdev_info->flags;
 		dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
@@ -733,5 +1250,7 @@ nouveau_irq_handler(DRM_IRQ_ARGS)
 	if (dev_priv->fbdev_info)
 		dev_priv->fbdev_info->flags = fbdev_flags;
 
+	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
+
 	return IRQ_HANDLED;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_mem.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_mem.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_mem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_mem.c	2010-05-16 17:17:36.000000000 -0400
@@ -347,6 +347,20 @@ nv50_mem_vm_bind_linear(struct drm_devic
 		return -EBUSY;
 	}
 
+	nv_wr32(dev, 0x100c80, 0x00040001);
+	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+		return -EBUSY;
+	}
+
+	nv_wr32(dev, 0x100c80, 0x00060001);
+	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+		return -EBUSY;
+	}
+
 	return 0;
 }
 
@@ -387,6 +401,20 @@ nv50_mem_vm_unbind(struct drm_device *de
 	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
 		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
 		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+		return;
+	}
+
+	nv_wr32(dev, 0x100c80, 0x00040001);
+	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+		return;
+	}
+
+	nv_wr32(dev, 0x100c80, 0x00060001);
+	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
 	}
 }
 
@@ -449,9 +477,30 @@ void nouveau_mem_close(struct drm_device
 	}
 }
 
-/*XXX won't work on BSD because of pci_read_config_dword */
 static uint32_t
-nouveau_mem_fb_amount_igp(struct drm_device *dev)
+nouveau_mem_detect_nv04(struct drm_device *dev)
+{
+	uint32_t boot0 = nv_rd32(dev, NV03_BOOT_0);
+
+	if (boot0 & 0x00000100)
+		return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024;
+
+	switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) {
+	case NV04_BOOT_0_RAM_AMOUNT_32MB:
+		return 32 * 1024 * 1024;
+	case NV04_BOOT_0_RAM_AMOUNT_16MB:
+		return 16 * 1024 * 1024;
+	case NV04_BOOT_0_RAM_AMOUNT_8MB:
+		return 8 * 1024 * 1024;
+	case NV04_BOOT_0_RAM_AMOUNT_4MB:
+		return 4 * 1024 * 1024;
+	}
+
+	return 0;
+}
+
+static uint32_t
+nouveau_mem_detect_nforce(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct pci_dev *bridge;
@@ -463,11 +512,11 @@ nouveau_mem_fb_amount_igp(struct drm_dev
 		return 0;
 	}
 
-	if (dev_priv->flags&NV_NFORCE) {
+	if (dev_priv->flags & NV_NFORCE) {
 		pci_read_config_dword(bridge, 0x7C, &mem);
 		return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024;
 	} else
-	if (dev_priv->flags&NV_NFORCE2) {
+	if (dev_priv->flags & NV_NFORCE2) {
 		pci_read_config_dword(bridge, 0x84, &mem);
 		return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024;
 	}
@@ -477,50 +526,32 @@ nouveau_mem_fb_amount_igp(struct drm_dev
 }
 
 /* returns the amount of FB ram in bytes */
-uint64_t nouveau_mem_fb_amount(struct drm_device *dev)
+int
+nouveau_mem_detect(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	uint32_t boot0;
 
-	switch (dev_priv->card_type) {
-	case NV_04:
-		boot0 = nv_rd32(dev, NV03_BOOT_0);
-		if (boot0 & 0x00000100)
-			return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024;
+	if (dev_priv->card_type == NV_04) {
+		dev_priv->vram_size = nouveau_mem_detect_nv04(dev);
+	} else
+	if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
+		dev_priv->vram_size = nouveau_mem_detect_nforce(dev);
+	} else {
+		dev_priv->vram_size  = nv_rd32(dev, NV04_FIFO_DATA);
+		dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK;
+		if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
+			dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12;
+	}
 
-		switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) {
-		case NV04_BOOT_0_RAM_AMOUNT_32MB:
-			return 32 * 1024 * 1024;
-		case NV04_BOOT_0_RAM_AMOUNT_16MB:
-			return 16 * 1024 * 1024;
-		case NV04_BOOT_0_RAM_AMOUNT_8MB:
-			return 8 * 1024 * 1024;
-		case NV04_BOOT_0_RAM_AMOUNT_4MB:
-			return 4 * 1024 * 1024;
-		}
-		break;
-	case NV_10:
-	case NV_20:
-	case NV_30:
-	case NV_40:
-	case NV_50:
-	default:
-		if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
-			return nouveau_mem_fb_amount_igp(dev);
-		} else {
-			uint64_t mem;
-			mem = (nv_rd32(dev, NV04_FIFO_DATA) &
-					NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >>
-					NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT;
-			return mem * 1024 * 1024;
-		}
-		break;
+	NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20));
+	if (dev_priv->vram_sys_base) {
+		NV_INFO(dev, "Stolen system memory at: 0x%010llx\n",
+			dev_priv->vram_sys_base);
 	}
 
-	NV_ERROR(dev,
-		"Unable to detect video ram size. Please report your setup to "
-							DRIVER_EMAIL "\n");
-	return 0;
+	if (dev_priv->vram_size)
+		return 0;
+	return -ENOMEM;
 }
 
 #if __OS_HAS_AGP
@@ -631,15 +662,12 @@ nouveau_mem_init(struct drm_device *dev)
 	spin_lock_init(&dev_priv->ttm.bo_list_lock);
 	spin_lock_init(&dev_priv->tile.lock);
 
-	dev_priv->fb_available_size = nouveau_mem_fb_amount(dev);
-
+	dev_priv->fb_available_size = dev_priv->vram_size;
 	dev_priv->fb_mappable_pages = dev_priv->fb_available_size;
 	if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1))
 		dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1);
 	dev_priv->fb_mappable_pages >>= PAGE_SHIFT;
 
-	NV_INFO(dev, "%d MiB VRAM\n", (int)(dev_priv->fb_available_size >> 20));
-
 	/* remove reserved space at end of vram from available amount */
 	dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram;
 	dev_priv->fb_aper_free = dev_priv->fb_available_size;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_notifier.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_notifier.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_notifier.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_notifier.c	2010-05-16 17:17:36.000000000 -0400
@@ -61,11 +61,8 @@ nouveau_notifier_init_channel(struct nou
 
 	chan->notifier_bo = ntfy;
 out_err:
-	if (ret) {
-		mutex_lock(&dev->struct_mutex);
-		drm_gem_object_unreference(ntfy->gem);
-		mutex_unlock(&dev->struct_mutex);
-	}
+	if (ret)
+		drm_gem_object_unreference_unlocked(ntfy->gem);
 
 	return ret;
 }
@@ -81,8 +78,8 @@ nouveau_notifier_takedown_channel(struct
 	nouveau_bo_unmap(chan->notifier_bo);
 	mutex_lock(&dev->struct_mutex);
 	nouveau_bo_unpin(chan->notifier_bo);
-	drm_gem_object_unreference(chan->notifier_bo->gem);
 	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(chan->notifier_bo->gem);
 	nouveau_mem_takedown(&chan->notifier_heap);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_sgdma.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_sgdma.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_sgdma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_sgdma.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 #include "drmP.h"
 #include "nouveau_drv.h"
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 
 #define NV_CTXDMA_PAGE_SHIFT 12
 #define NV_CTXDMA_PAGE_SIZE  (1 << NV_CTXDMA_PAGE_SHIFT)
@@ -171,6 +172,24 @@ nouveau_sgdma_unbind(struct ttm_backend
 	}
 	dev_priv->engine.instmem.finish_access(nvbe->dev);
 
+	if (dev_priv->card_type == NV_50) {
+		nv_wr32(dev, 0x100c80, 0x00050001);
+		if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+			NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+			NV_ERROR(dev, "0x100c80 = 0x%08x\n",
+						nv_rd32(dev, 0x100c80));
+			return -EBUSY;
+		}
+
+		nv_wr32(dev, 0x100c80, 0x00000001);
+		if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+			NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+			NV_ERROR(dev, "0x100c80 = 0x%08x\n",
+						nv_rd32(dev, 0x100c80));
+			return -EBUSY;
+		}
+	}
+
 	nvbe->bound = false;
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_state.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_state.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_state.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nouveau_state.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,17 +24,18 @@
  */
 
 #include <linux/swab.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "drm_sarea.h"
 #include "drm_crtc_helper.h"
 #include <linux/vgaarb.h>
+#include <linux/vga_switcheroo.h>
 
 #include "nouveau_drv.h"
 #include "nouveau_drm.h"
 #include "nv50_display.h"
 
-static int nouveau_stub_init(struct drm_device *dev) { return 0; }
 static void nouveau_stub_takedown(struct drm_device *dev) {}
 
 static int nouveau_init_engine_ptrs(struct drm_device *dev)
@@ -276,8 +277,8 @@ static int nouveau_init_engine_ptrs(stru
 		engine->timer.init		= nv04_timer_init;
 		engine->timer.read		= nv04_timer_read;
 		engine->timer.takedown		= nv04_timer_takedown;
-		engine->fb.init			= nouveau_stub_init;
-		engine->fb.takedown		= nouveau_stub_takedown;
+		engine->fb.init			= nv50_fb_init;
+		engine->fb.takedown		= nv50_fb_takedown;
 		engine->graph.grclass		= nv50_graph_grclass;
 		engine->graph.init		= nv50_graph_init;
 		engine->graph.takedown		= nv50_graph_takedown;
@@ -340,7 +341,7 @@ nouveau_card_init_channel(struct drm_dev
 
 	gpuobj = NULL;
 	ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
-				     0, nouveau_mem_fb_amount(dev),
+				     0, dev_priv->vram_size,
 				     NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM,
 				     &gpuobj);
 	if (ret)
@@ -371,6 +372,30 @@ out_err:
 	return ret;
 }
 
+static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
+					 enum vga_switcheroo_state state)
+{
+	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
+	if (state == VGA_SWITCHEROO_ON) {
+		printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
+		nouveau_pci_resume(pdev);
+	} else {
+		printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
+		nouveau_pci_suspend(pdev, pmm);
+	}
+}
+
+static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	bool can_switch;
+
+	spin_lock(&dev->count_lock);
+	can_switch = (dev->open_count == 0);
+	spin_unlock(&dev->count_lock);
+	return can_switch;
+}
+
 int
 nouveau_card_init(struct drm_device *dev)
 {
@@ -384,6 +409,8 @@ nouveau_card_init(struct drm_device *dev
 		return 0;
 
 	vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
+	vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state,
+				       nouveau_switcheroo_can_switch);
 
 	/* Initialise internal driver API hooks */
 	ret = nouveau_init_engine_ptrs(dev);
@@ -391,6 +418,7 @@ nouveau_card_init(struct drm_device *dev
 		goto out;
 	engine = &dev_priv->engine;
 	dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;
+	spin_lock_init(&dev_priv->context_switch_lock);
 
 	/* Parse BIOS tables / Run init tables if card not POSTed */
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
@@ -399,6 +427,10 @@ nouveau_card_init(struct drm_device *dev
 			goto out;
 	}
 
+	ret = nouveau_mem_detect(dev);
+	if (ret)
+		goto out_bios;
+
 	ret = nouveau_gpuobj_early_init(dev);
 	if (ret)
 		goto out_bios;
@@ -474,7 +506,7 @@ nouveau_card_init(struct drm_device *dev
 		else
 			ret = nv04_display_create(dev);
 		if (ret)
-			goto out_irq;
+			goto out_channel;
 	}
 
 	ret = nouveau_backlight_init(dev);
@@ -488,6 +520,11 @@ nouveau_card_init(struct drm_device *dev
 
 	return 0;
 
+out_channel:
+	if (dev_priv->channel) {
+		nouveau_channel_free(dev_priv->channel);
+		dev_priv->channel = NULL;
+	}
 out_irq:
 	drm_irq_uninstall(dev);
 out_fifo:
@@ -505,6 +542,7 @@ out_mc:
 out_gpuobj:
 	nouveau_gpuobj_takedown(dev);
 out_mem:
+	nouveau_sgdma_takedown(dev);
 	nouveau_mem_close(dev);
 out_instmem:
 	engine->instmem.takedown(dev);
@@ -617,11 +655,6 @@ int nouveau_load(struct drm_device *dev,
 	NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
 		 dev->pci_vendor, dev->pci_device, dev->pdev->class);
 
-	dev_priv->acpi_dsm = nouveau_dsm_probe(dev);
-
-	if (dev_priv->acpi_dsm)
-		nouveau_hybrid_setup(dev);
-
 	dev_priv->wq = create_workqueue("nouveau");
 	if (!dev_priv->wq)
 		return -EINVAL;
@@ -776,13 +809,6 @@ int nouveau_unload(struct drm_device *de
 	return 0;
 }
 
-int
-nouveau_ioctl_card_init(struct drm_device *dev, void *data,
-			struct drm_file *file_priv)
-{
-	return nouveau_card_init(dev);
-}
-
 int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
 						struct drm_file *file_priv)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_crtc.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv04_crtc.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_crtc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv04_crtc.c	2010-05-16 17:17:36.000000000 -0400
@@ -230,9 +230,9 @@ nv_crtc_mode_set_vga(struct drm_crtc *cr
 	struct drm_framebuffer *fb = crtc->fb;
 
 	/* Calculate our timings */
-	int horizDisplay	= (mode->crtc_hdisplay >> 3) 	- 1;
-	int horizStart		= (mode->crtc_hsync_start >> 3) 	- 1;
-	int horizEnd		= (mode->crtc_hsync_end >> 3) 	- 1;
+	int horizDisplay	= (mode->crtc_hdisplay >> 3)		- 1;
+	int horizStart		= (mode->crtc_hsync_start >> 3) 	+ 1;
+	int horizEnd		= (mode->crtc_hsync_end >> 3)		+ 1;
 	int horizTotal		= (mode->crtc_htotal >> 3)		- 5;
 	int horizBlankStart	= (mode->crtc_hdisplay >> 3)		- 1;
 	int horizBlankEnd	= (mode->crtc_htotal >> 3)		- 1;
@@ -926,9 +926,7 @@ nv04_crtc_cursor_set(struct drm_crtc *cr
 	nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset);
 	nv_crtc->cursor.show(nv_crtc, true);
 out:
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(gem);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(gem);
 	return ret;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_dac.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv04_dac.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_dac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv04_dac.c	2010-05-16 17:17:36.000000000 -0400
@@ -230,13 +230,13 @@ uint32_t nv17_dac_sample_load(struct drm
 	if (dcb->type == OUTPUT_TV) {
 		testval = RGB_TEST_DATA(0xa0, 0xa0, 0xa0);
 
-		if (dev_priv->vbios->tvdactestval)
-			testval = dev_priv->vbios->tvdactestval;
+		if (dev_priv->vbios.tvdactestval)
+			testval = dev_priv->vbios.tvdactestval;
 	} else {
 		testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */
 
-		if (dev_priv->vbios->dactestval)
-			testval = dev_priv->vbios->dactestval;
+		if (dev_priv->vbios.dactestval)
+			testval = dev_priv->vbios.dactestval;
 	}
 
 	saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_dfp.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv04_dfp.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_dfp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv04_dfp.c	2010-05-16 17:17:36.000000000 -0400
@@ -269,10 +269,10 @@ static void nv04_dfp_mode_set(struct drm
 	regp->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1;
 	if (!nv_gf4_disp_arch(dev) ||
 	    (output_mode->hsync_start - output_mode->hdisplay) >=
-					dev_priv->vbios->digital_min_front_porch)
+					dev_priv->vbios.digital_min_front_porch)
 		regp->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay;
 	else
-		regp->fp_horiz_regs[FP_CRTC] = output_mode->hsync_start - dev_priv->vbios->digital_min_front_porch - 1;
+		regp->fp_horiz_regs[FP_CRTC] = output_mode->hsync_start - dev_priv->vbios.digital_min_front_porch - 1;
 	regp->fp_horiz_regs[FP_SYNC_START] = output_mode->hsync_start - 1;
 	regp->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1;
 	regp->fp_horiz_regs[FP_VALID_START] = output_mode->hskew;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_display.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv04_display.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_display.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv04_display.c	2010-05-16 17:17:36.000000000 -0400
@@ -93,10 +93,9 @@ int
 nv04_display_create(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct parsed_dcb *dcb = dev_priv->vbios->dcb;
+	struct dcb_table *dcb = &dev_priv->vbios.dcb;
 	struct drm_encoder *encoder;
 	struct drm_crtc *crtc;
-	uint16_t connector[16] = { 0 };
 	int i, ret;
 
 	NV_DEBUG_KMS(dev, "\n");
@@ -154,52 +153,10 @@ nv04_display_create(struct drm_device *d
 
 		if (ret)
 			continue;
-
-		connector[dcbent->connector] |= (1 << dcbent->type);
 	}
 
-	for (i = 0; i < dcb->entries; i++) {
-		struct dcb_entry *dcbent = &dcb->entry[i];
-		uint16_t encoders;
-		int type;
-
-		encoders = connector[dcbent->connector];
-		if (!(encoders & (1 << dcbent->type)))
-			continue;
-		connector[dcbent->connector] = 0;
-
-		switch (dcbent->type) {
-		case OUTPUT_ANALOG:
-			if (!MULTIPLE_ENCODERS(encoders))
-				type = DRM_MODE_CONNECTOR_VGA;
-			else
-				type = DRM_MODE_CONNECTOR_DVII;
-			break;
-		case OUTPUT_TMDS:
-			if (!MULTIPLE_ENCODERS(encoders))
-				type = DRM_MODE_CONNECTOR_DVID;
-			else
-				type = DRM_MODE_CONNECTOR_DVII;
-			break;
-		case OUTPUT_LVDS:
-			type = DRM_MODE_CONNECTOR_LVDS;
-#if 0
-			/* don't create i2c adapter when lvds ddc not allowed */
-			if (dcbent->lvdsconf.use_straps_for_mode ||
-			    dev_priv->vbios->fp_no_ddc)
-				i2c_index = 0xf;
-#endif
-			break;
-		case OUTPUT_TV:
-			type = DRM_MODE_CONNECTOR_TV;
-			break;
-		default:
-			type = DRM_MODE_CONNECTOR_Unknown;
-			continue;
-		}
-
-		nouveau_connector_create(dev, dcbent->connector, type);
-	}
+	for (i = 0; i < dcb->connector.entries; i++)
+		nouveau_connector_create(dev, &dcb->connector.entry[i]);
 
 	/* Save previous state */
 	NVLockVgaCrtcs(dev, false);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_fbcon.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv04_fbcon.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_fbcon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv04_fbcon.c	2010-05-16 17:17:36.000000000 -0400
@@ -118,8 +118,8 @@ nv04_fbcon_imageblit(struct fb_info *inf
 		return;
 	}
 
-	width = (image->width + 31) & ~31;
-	dsize = (width * image->height) >> 5;
+	width = ALIGN(image->width, 8);
+	dsize = ALIGN(width * image->height, 32) >> 5;
 
 	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
 	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
@@ -136,8 +136,8 @@ nv04_fbcon_imageblit(struct fb_info *inf
 			 ((image->dx + image->width) & 0xffff));
 	OUT_RING(chan, bg);
 	OUT_RING(chan, fg);
-	OUT_RING(chan, (image->height << 16) | image->width);
 	OUT_RING(chan, (image->height << 16) | width);
+	OUT_RING(chan, (image->height << 16) | image->width);
 	OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
 
 	while (dsize) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_fifo.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv04_fifo.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_fifo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv04_fifo.c	2010-05-16 17:17:36.000000000 -0400
@@ -117,6 +117,7 @@ nv04_fifo_create_context(struct nouveau_
 {
 	struct drm_device *dev = chan->dev;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	unsigned long flags;
 	int ret;
 
 	ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(chan->id), ~0,
@@ -127,6 +128,8 @@ nv04_fifo_create_context(struct nouveau_
 	if (ret)
 		return ret;
 
+	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
+
 	/* Setup initial state */
 	dev_priv->engine.instmem.prepare_access(dev, true);
 	RAMFC_WR(DMA_PUT, chan->pushbuf_base);
@@ -144,6 +147,8 @@ nv04_fifo_create_context(struct nouveau_
 	/* enable the fifo dma operation */
 	nv_wr32(dev, NV04_PFIFO_MODE,
 		nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id));
+
+	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_tv.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv04_tv.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_tv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv04_tv.c	2010-05-16 17:17:36.000000000 -0400
@@ -262,7 +262,7 @@ int nv04_tv_create(struct drm_device *de
 	nv_encoder->or = ffs(entry->or) - 1;
 
 	/* Run the slave-specific initialization */
-	adap = &dev_priv->vbios->dcb->i2c[i2c_index].chan->adapter;
+	adap = &dev_priv->vbios.dcb.i2c[i2c_index].chan->adapter;
 
 	was_locked = NVLockVgaCrtcs(dev, false);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv17_tv.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv17_tv.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv17_tv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv17_tv.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,8 +45,8 @@ static uint32_t nv42_tv_sample_load(stru
 
 #define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20)
 	testval = RGB_TEST_DATA(0x82, 0xeb, 0x82);
-	if (dev_priv->vbios->tvdactestval)
-		testval = dev_priv->vbios->tvdactestval;
+	if (dev_priv->vbios.tvdactestval)
+		testval = dev_priv->vbios.tvdactestval;
 
 	dacclk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
 	head = (dacclk & 0x100) >> 8;
@@ -367,7 +367,7 @@ static void nv17_tv_prepare(struct drm_e
 			     !enc->crtc &&
 			     nv04_dfp_get_bound_head(dev, dcb) == head) {
 				nv04_dfp_bind_head(dev, dcb, head ^ 1,
-						dev_priv->VBIOS.fp.dual_link);
+						dev_priv->vbios.fp.dual_link);
 			}
 		}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv40_fifo.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv40_fifo.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv40_fifo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv40_fifo.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@ nv40_fifo_create_context(struct nouveau_
 	struct drm_device *dev = chan->dev;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	uint32_t fc = NV40_RAMFC(chan->id);
+	unsigned long flags;
 	int ret;
 
 	ret = nouveau_gpuobj_new_fake(dev, NV40_RAMFC(chan->id), ~0,
@@ -45,6 +46,8 @@ nv40_fifo_create_context(struct nouveau_
 	if (ret)
 		return ret;
 
+	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
+
 	dev_priv->engine.instmem.prepare_access(dev, true);
 	nv_wi32(dev, fc +  0, chan->pushbuf_base);
 	nv_wi32(dev, fc +  4, chan->pushbuf_base);
@@ -63,6 +66,8 @@ nv40_fifo_create_context(struct nouveau_
 	/* enable the fifo dma operation */
 	nv_wr32(dev, NV04_PFIFO_MODE,
 		nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id));
+
+	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
 	return 0;
 }
 
@@ -273,7 +278,7 @@ nv40_fifo_init_ramxx(struct drm_device *
 	default:
 		nv_wr32(dev, 0x2230, 0);
 		nv_wr32(dev, NV40_PFIFO_RAMFC,
-			((nouveau_mem_fb_amount(dev) - 512 * 1024 +
+			((dev_priv->vram_size - 512 * 1024 +
 			  dev_priv->ramfc_offset) >> 16) | (3 << 16));
 		break;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv40_graph.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv40_graph.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv40_graph.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv40_graph.c	2010-05-16 17:17:36.000000000 -0400
@@ -335,6 +335,27 @@ nv40_graph_init(struct drm_device *dev)
 	nv_wr32(dev, 0x400b38, 0x2ffff800);
 	nv_wr32(dev, 0x400b3c, 0x00006000);
 
+	/* Tiling related stuff. */
+	switch (dev_priv->chipset) {
+	case 0x44:
+	case 0x4a:
+		nv_wr32(dev, 0x400bc4, 0x1003d888);
+		nv_wr32(dev, 0x400bbc, 0xb7a7b500);
+		break;
+	case 0x46:
+		nv_wr32(dev, 0x400bc4, 0x0000e024);
+		nv_wr32(dev, 0x400bbc, 0xb7a7b520);
+		break;
+	case 0x4c:
+	case 0x4e:
+	case 0x67:
+		nv_wr32(dev, 0x400bc4, 0x1003d888);
+		nv_wr32(dev, 0x400bbc, 0xb7a7b540);
+		break;
+	default:
+		break;
+	}
+
 	/* Turn all the tiling regions off. */
 	for (i = 0; i < pfb->num_tiles; i++)
 		nv40_graph_set_region_tiling(dev, i, 0, 0, 0);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_crtc.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_crtc.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_crtc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_crtc.c	2010-05-16 17:17:36.000000000 -0400
@@ -358,9 +358,7 @@ nv50_crtc_cursor_set(struct drm_crtc *cr
 	nv_crtc->cursor.show(nv_crtc, true);
 
 out:
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(gem);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(gem);
 	return ret;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_dac.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_dac.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_dac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_dac.c	2010-05-16 17:17:36.000000000 -0400
@@ -79,8 +79,8 @@ nv50_dac_detect(struct drm_encoder *enco
 	}
 
 	/* Use bios provided value if possible. */
-	if (dev_priv->vbios->dactestval) {
-		load_pattern = dev_priv->vbios->dactestval;
+	if (dev_priv->vbios.dactestval) {
+		load_pattern = dev_priv->vbios.dactestval;
 		NV_DEBUG_KMS(dev, "Using bios provided load_pattern of %d\n",
 			  load_pattern);
 	} else {
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_display.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_display.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_display.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_display.c	2010-05-16 17:17:36.000000000 -0400
@@ -143,7 +143,7 @@ nv50_evo_channel_new(struct drm_device *
 	}
 
 	ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoVRAM, 0, 0x19,
-				  0, nouveau_mem_fb_amount(dev));
+				  0, dev_priv->vram_size);
 	if (ret) {
 		nv50_evo_channel_del(pchan);
 		return ret;
@@ -231,7 +231,7 @@ nv50_display_init(struct drm_device *dev
 	/* This used to be in crtc unblank, but seems out of place there. */
 	nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0);
 	/* RAM is clamped to 256 MiB. */
-	ram_amount = nouveau_mem_fb_amount(dev);
+	ram_amount = dev_priv->vram_size;
 	NV_DEBUG_KMS(dev, "ram_amount %d\n", ram_amount);
 	if (ram_amount > 256*1024*1024)
 		ram_amount = 256*1024*1024;
@@ -370,9 +370,7 @@ nv50_display_init(struct drm_device *dev
 		struct nouveau_connector *conn = nouveau_connector(connector);
 		struct dcb_gpio_entry *gpio;
 
-		if (connector->connector_type != DRM_MODE_CONNECTOR_DVII &&
-		    connector->connector_type != DRM_MODE_CONNECTOR_DVID &&
-		    connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
+		if (conn->dcb->gpio_tag == 0xff)
 			continue;
 
 		gpio = nouveau_bios_gpio_entry(dev, conn->dcb->gpio_tag);
@@ -465,8 +463,7 @@ static int nv50_display_disable(struct d
 int nv50_display_create(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct parsed_dcb *dcb = dev_priv->vbios->dcb;
-	uint32_t connector[16] = {};
+	struct dcb_table *dcb = &dev_priv->vbios.dcb;
 	int ret, i;
 
 	NV_DEBUG_KMS(dev, "\n");
@@ -522,49 +519,20 @@ int nv50_display_create(struct drm_devic
 			NV_WARN(dev, "DCB encoder %d unknown\n", entry->type);
 			continue;
 		}
-
-		connector[entry->connector] |= (1 << entry->type);
 	}
 
-	/* It appears that DCB 3.0+ VBIOS has a connector table, however,
-	 * I'm not 100% certain how to decode it correctly yet so just
-	 * look at what encoders are present on each connector index and
-	 * attempt to derive the connector type from that.
-	 */
-	for (i = 0 ; i < dcb->entries; i++) {
-		struct dcb_entry *entry = &dcb->entry[i];
-		uint16_t encoders;
-		int type;
-
-		encoders = connector[entry->connector];
-		if (!(encoders & (1 << entry->type)))
-			continue;
-		connector[entry->connector] = 0;
-
-		if (encoders & (1 << OUTPUT_DP)) {
-			type = DRM_MODE_CONNECTOR_DisplayPort;
-		} else if (encoders & (1 << OUTPUT_TMDS)) {
-			if (encoders & (1 << OUTPUT_ANALOG))
-				type = DRM_MODE_CONNECTOR_DVII;
-			else
-				type = DRM_MODE_CONNECTOR_DVID;
-		} else if (encoders & (1 << OUTPUT_ANALOG)) {
-			type = DRM_MODE_CONNECTOR_VGA;
-		} else if (encoders & (1 << OUTPUT_LVDS)) {
-			type = DRM_MODE_CONNECTOR_LVDS;
-		} else {
-			type = DRM_MODE_CONNECTOR_Unknown;
-		}
-
-		if (type == DRM_MODE_CONNECTOR_Unknown)
+	for (i = 0 ; i < dcb->connector.entries; i++) {
+		if (i != 0 && dcb->connector.entry[i].index2 ==
+			      dcb->connector.entry[i - 1].index2)
 			continue;
-
-		nouveau_connector_create(dev, entry->connector, type);
+		nouveau_connector_create(dev, &dcb->connector.entry[i]);
 	}
 
 	ret = nv50_display_init(dev);
-	if (ret)
+	if (ret) {
+		nv50_display_destroy(dev);
 		return ret;
+	}
 
 	return 0;
 }
@@ -667,8 +635,8 @@ nv50_display_irq_head(struct drm_device
 		return -1;
 	}
 
-	for (i = 0; i < dev_priv->vbios->dcb->entries; i++) {
-		struct dcb_entry *dcbent = &dev_priv->vbios->dcb->entry[i];
+	for (i = 0; i < dev_priv->vbios.dcb.entries; i++) {
+		struct dcb_entry *dcbent = &dev_priv->vbios.dcb.entry[i];
 
 		if (dcbent->type != type)
 			continue;
@@ -692,7 +660,7 @@ nv50_display_script_select(struct drm_de
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_connector *nv_connector = NULL;
 	struct drm_encoder *encoder;
-	struct nvbios *bios = &dev_priv->VBIOS;
+	struct nvbios *bios = &dev_priv->vbios;
 	uint32_t mc, script = 0, or;
 
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
@@ -710,7 +678,7 @@ nv50_display_script_select(struct drm_de
 	switch (dcbent->type) {
 	case OUTPUT_LVDS:
 		script = (mc >> 8) & 0xf;
-		if (bios->pub.fp_no_ddc) {
+		if (bios->fp_no_ddc) {
 			if (bios->fp.dual_link)
 				script |= 0x0100;
 			if (bios->fp.if_is_24bit)
@@ -919,10 +887,12 @@ nv50_display_error_handler(struct drm_de
 	nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000);
 }
 
-static void
-nv50_display_irq_hotplug(struct drm_device *dev)
+void
+nv50_display_irq_hotplug_bh(struct work_struct *work)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_nouveau_private *dev_priv =
+		container_of(work, struct drm_nouveau_private, hpd_work);
+	struct drm_device *dev = dev_priv->dev;
 	struct drm_connector *connector;
 	const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
 	uint32_t unplug_mask, plug_mask, change_mask;
@@ -983,8 +953,10 @@ nv50_display_irq_handler(struct drm_devi
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	uint32_t delayed = 0;
 
-	while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG)
-		nv50_display_irq_hotplug(dev);
+	if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) {
+		if (!work_pending(&dev_priv->hpd_work))
+			queue_work(dev_priv->wq, &dev_priv->hpd_work);
+	}
 
 	while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) {
 		uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_display.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_display.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_display.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_display.h	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 
 void nv50_display_irq_handler(struct drm_device *dev);
 void nv50_display_irq_handler_bh(struct work_struct *work);
+void nv50_display_irq_hotplug_bh(struct work_struct *work);
 int nv50_display_init(struct drm_device *dev);
 int nv50_display_create(struct drm_device *dev);
 int nv50_display_destroy(struct drm_device *dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_fb.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_fb.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_fb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,32 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv50_fb_init(struct drm_device *dev)
+{
+	/* This is needed to get meaningful information from 100c90
+	 * on traps. No idea what these values mean exactly. */
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	switch (dev_priv->chipset) {
+	case 0x50:
+		nv_wr32(dev, 0x100c90, 0x0707ff);
+		break;
+	case 0xa5:
+	case 0xa8:
+		nv_wr32(dev, 0x100c90, 0x0d0fff);
+		break;
+	default:
+		nv_wr32(dev, 0x100c90, 0x1d07ff);
+		break;
+	}
+
+	return 0;
+}
+
+void
+nv50_fb_takedown(struct drm_device *dev)
+{
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_fbcon.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_fbcon.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_fbcon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_fbcon.c	2010-05-16 17:17:36.000000000 -0400
@@ -109,7 +109,7 @@ nv50_fbcon_imageblit(struct fb_info *inf
 		return;
 	}
 
-	width = (image->width + 31) & ~31;
+	width = ALIGN(image->width, 32);
 	dwords = (width * image->height) >> 5;
 
 	BEGIN_RING(chan, NvSub2D, 0x0814, 2);
@@ -157,8 +157,11 @@ nv50_fbcon_accel_init(struct fb_info *in
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_channel *chan = dev_priv->channel;
 	struct nouveau_gpuobj *eng2d = NULL;
+	uint64_t fb;
 	int ret, format;
 
+	fb = info->fix.smem_start - dev_priv->fb_phys + dev_priv->vm_vram_base;
+
 	switch (info->var.bits_per_pixel) {
 	case 8:
 		format = 0xf3;
@@ -233,7 +236,7 @@ nv50_fbcon_accel_init(struct fb_info *in
 	BEGIN_RING(chan, NvSub2D, 0x0808, 3);
 	OUT_RING(chan, 0);
 	OUT_RING(chan, 0);
-	OUT_RING(chan, 0);
+	OUT_RING(chan, 1);
 	BEGIN_RING(chan, NvSub2D, 0x081c, 1);
 	OUT_RING(chan, 1);
 	BEGIN_RING(chan, NvSub2D, 0x0840, 4);
@@ -248,9 +251,8 @@ nv50_fbcon_accel_init(struct fb_info *in
 	OUT_RING(chan, info->fix.line_length);
 	OUT_RING(chan, info->var.xres_virtual);
 	OUT_RING(chan, info->var.yres_virtual);
-	OUT_RING(chan, 0);
-	OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys +
-			 dev_priv->vm_vram_base);
+	OUT_RING(chan, upper_32_bits(fb));
+	OUT_RING(chan, lower_32_bits(fb));
 	BEGIN_RING(chan, NvSub2D, 0x0230, 2);
 	OUT_RING(chan, format);
 	OUT_RING(chan, 1);
@@ -258,9 +260,8 @@ nv50_fbcon_accel_init(struct fb_info *in
 	OUT_RING(chan, info->fix.line_length);
 	OUT_RING(chan, info->var.xres_virtual);
 	OUT_RING(chan, info->var.yres_virtual);
-	OUT_RING(chan, 0);
-	OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys +
-			 dev_priv->vm_vram_base);
+	OUT_RING(chan, upper_32_bits(fb));
+	OUT_RING(chan, lower_32_bits(fb));
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_fifo.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_fifo.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_fifo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_fifo.c	2010-05-16 17:17:36.000000000 -0400
@@ -243,6 +243,7 @@ nv50_fifo_create_context(struct nouveau_
 	struct drm_device *dev = chan->dev;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_gpuobj *ramfc = NULL;
+	unsigned long flags;
 	int ret;
 
 	NV_DEBUG(dev, "ch%d\n", chan->id);
@@ -278,19 +279,21 @@ nv50_fifo_create_context(struct nouveau_
 			return ret;
 	}
 
+	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
+
 	dev_priv->engine.instmem.prepare_access(dev, true);
 
-	nv_wo32(dev, ramfc, 0x08/4, chan->pushbuf_base);
-	nv_wo32(dev, ramfc, 0x10/4, chan->pushbuf_base);
 	nv_wo32(dev, ramfc, 0x48/4, chan->pushbuf->instance >> 4);
 	nv_wo32(dev, ramfc, 0x80/4, (0xc << 24) | (chan->ramht->instance >> 4));
-	nv_wo32(dev, ramfc, 0x3c/4, 0x00086078);
 	nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff);
 	nv_wo32(dev, ramfc, 0x60/4, 0x7fffffff);
 	nv_wo32(dev, ramfc, 0x40/4, 0x00000000);
 	nv_wo32(dev, ramfc, 0x7c/4, 0x30000001);
 	nv_wo32(dev, ramfc, 0x78/4, 0x00000000);
-	nv_wo32(dev, ramfc, 0x4c/4, 0xffffffff);
+	nv_wo32(dev, ramfc, 0x3c/4, 0x403f6078);
+	nv_wo32(dev, ramfc, 0x50/4, chan->pushbuf_base +
+				    chan->dma.ib_base * 4);
+	nv_wo32(dev, ramfc, 0x54/4, drm_order(chan->dma.ib_max + 1) << 16);
 
 	if (!IS_G80) {
 		nv_wo32(dev, chan->ramin->gpuobj, 0, chan->id);
@@ -306,10 +309,12 @@ nv50_fifo_create_context(struct nouveau_
 	ret = nv50_fifo_channel_enable(dev, chan->id, false);
 	if (ret) {
 		NV_ERROR(dev, "error enabling ch%d: %d\n", chan->id, ret);
+		spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
 		nouveau_gpuobj_ref_del(dev, &chan->ramfc);
 		return ret;
 	}
 
+	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_gpio.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_gpio.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2010 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_hw.h"
+
+static int
+nv50_gpio_location(struct dcb_gpio_entry *gpio, uint32_t *reg, uint32_t *shift)
+{
+	const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
+
+	if (gpio->line > 32)
+		return -EINVAL;
+
+	*reg = nv50_gpio_reg[gpio->line >> 3];
+	*shift = (gpio->line & 7) << 2;
+	return 0;
+}
+
+int
+nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag)
+{
+	struct dcb_gpio_entry *gpio;
+	uint32_t r, s, v;
+
+	gpio = nouveau_bios_gpio_entry(dev, tag);
+	if (!gpio)
+		return -ENOENT;
+
+	if (nv50_gpio_location(gpio, &r, &s))
+		return -EINVAL;
+
+	v = nv_rd32(dev, r) >> (s + 2);
+	return ((v & 1) == (gpio->state[1] & 1));
+}
+
+int
+nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state)
+{
+	struct dcb_gpio_entry *gpio;
+	uint32_t r, s, v;
+
+	gpio = nouveau_bios_gpio_entry(dev, tag);
+	if (!gpio)
+		return -ENOENT;
+
+	if (nv50_gpio_location(gpio, &r, &s))
+		return -EINVAL;
+
+	v  = nv_rd32(dev, r) & ~(0x3 << s);
+	v |= (gpio->state[state] ^ 2) << s;
+	nv_wr32(dev, r, v);
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_graph.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_graph.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_graph.c	2013-05-03 12:03:19.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_graph.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,7 @@
 #include "drm.h"
 #include "nouveau_drv.h"
 
-/*(DEBLOBBED)*/
+#include "nouveau_grctx.h"
 
 #define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50)
 
@@ -56,6 +56,10 @@ nv50_graph_init_intr(struct drm_device *
 static void
 nv50_graph_init_regs__nv(struct drm_device *dev)
 {
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t units = nv_rd32(dev, 0x1540);
+	int i;
+
 	NV_DEBUG(dev, "\n");
 
 	nv_wr32(dev, 0x400804, 0xc0000000);
@@ -65,6 +69,20 @@ nv50_graph_init_regs__nv(struct drm_devi
 	nv_wr32(dev, 0x405018, 0xc0000000);
 	nv_wr32(dev, 0x402000, 0xc0000000);
 
+	for (i = 0; i < 16; i++) {
+		if (units & 1 << i) {
+			if (dev_priv->chipset < 0xa0) {
+				nv_wr32(dev, 0x408900 + (i << 12), 0xc0000000);
+				nv_wr32(dev, 0x408e08 + (i << 12), 0xc0000000);
+				nv_wr32(dev, 0x408314 + (i << 12), 0xc0000000);
+			} else {
+				nv_wr32(dev, 0x408600 + (i << 11), 0xc0000000);
+				nv_wr32(dev, 0x408708 + (i << 11), 0xc0000000);
+				nv_wr32(dev, 0x40831c + (i << 11), 0xc0000000);
+			}
+		}
+	}
+
 	nv_wr32(dev, 0x400108, 0xffffffff);
 
 	nv_wr32(dev, 0x400824, 0x00004000);
@@ -88,9 +106,34 @@ nv50_graph_init_ctxctl(struct drm_device
 
 	NV_DEBUG(dev, "\n");
 
-	nouveau_grctx_prog_load(dev);
-	if (!dev_priv->engine.graph.ctxprog)
-		dev_priv->engine.graph.accel_blocked = true;
+	if (nouveau_ctxfw) {
+		nouveau_grctx_prog_load(dev);
+		dev_priv->engine.graph.grctx_size = 0x70000;
+	}
+	if (!dev_priv->engine.graph.ctxprog) {
+		struct nouveau_grctx ctx = {};
+		uint32_t *cp = kmalloc(512 * 4, GFP_KERNEL);
+		int i;
+		if (!cp) {
+			NV_ERROR(dev, "Couldn't alloc ctxprog! Disabling acceleration.\n");
+			dev_priv->engine.graph.accel_blocked = true;
+			return 0;
+		}
+		ctx.dev = dev;
+		ctx.mode = NOUVEAU_GRCTX_PROG;
+		ctx.data = cp;
+		ctx.ctxprog_max = 512;
+		if (!nv50_grctx_init(&ctx)) {
+			dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
+
+			nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
+			for (i = 0; i < ctx.ctxprog_len; i++)
+				nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
+		} else {
+			dev_priv->engine.graph.accel_blocked = true;
+		}
+		kfree(cp);
+	}
 
 	nv_wr32(dev, 0x400320, 4);
 	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0);
@@ -170,13 +213,13 @@ nv50_graph_create_context(struct nouveau
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_gpuobj *ramin = chan->ramin->gpuobj;
 	struct nouveau_gpuobj *ctx;
-	uint32_t grctx_size = 0x70000;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
 	int hdr, ret;
 
 	NV_DEBUG(dev, "ch%d\n", chan->id);
 
-	ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, grctx_size, 0x1000,
-				     NVOBJ_FLAG_ZERO_ALLOC |
+	ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size,
+				     0x1000, NVOBJ_FLAG_ZERO_ALLOC |
 				     NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx);
 	if (ret)
 		return ret;
@@ -186,7 +229,7 @@ nv50_graph_create_context(struct nouveau
 	dev_priv->engine.instmem.prepare_access(dev, true);
 	nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002);
 	nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance +
-					   grctx_size - 1);
+					   pgraph->grctx_size - 1);
 	nv_wo32(dev, ramin, (hdr + 0x08)/4, chan->ramin_grctx->instance);
 	nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0);
 	nv_wo32(dev, ramin, (hdr + 0x10)/4, 0);
@@ -194,12 +237,16 @@ nv50_graph_create_context(struct nouveau
 	dev_priv->engine.instmem.finish_access(dev);
 
 	dev_priv->engine.instmem.prepare_access(dev, true);
-	nouveau_grctx_vals_load(dev, ctx);
+	if (!pgraph->ctxprog) {
+		struct nouveau_grctx ctx = {};
+		ctx.dev = chan->dev;
+		ctx.mode = NOUVEAU_GRCTX_VALS;
+		ctx.data = chan->ramin_grctx->gpuobj;
+		nv50_grctx_init(&ctx);
+	} else {
+		nouveau_grctx_vals_load(dev, ctx);
+	}
 	nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12);
-	if ((dev_priv->chipset & 0xf0) == 0xa0)
-		nv_wo32(dev, ctx, 0x00004/4, 0x00000000);
-	else
-		nv_wo32(dev, ctx, 0x0011c/4, 0x00000000);
 	dev_priv->engine.instmem.finish_access(dev);
 
 	return 0;
@@ -363,9 +410,10 @@ struct nouveau_pgraph_object_class nv50_
 	{ 0x5039, false, NULL }, /* m2mf */
 	{ 0x502d, false, NULL }, /* 2d */
 	{ 0x50c0, false, NULL }, /* compute */
+	{ 0x85c0, false, NULL }, /* compute (nva3, nva5, nva8) */
 	{ 0x5097, false, NULL }, /* tesla (nv50) */
-	{ 0x8297, false, NULL }, /* tesla (nv80/nv90) */
-	{ 0x8397, false, NULL }, /* tesla (nva0) */
-	{ 0x8597, false, NULL }, /* tesla (nva8) */
+	{ 0x8297, false, NULL }, /* tesla (nv8x/nv9x) */
+	{ 0x8397, false, NULL }, /* tesla (nva0, nvaa, nvac) */
+	{ 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */
 	{}
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_grctx.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_grctx.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_grctx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_grctx.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,2383 @@
+/*
+ * Copyright 2009 Marcin KoÅ›cielnicki
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define CP_FLAG_CLEAR                 0
+#define CP_FLAG_SET                   1
+#define CP_FLAG_SWAP_DIRECTION        ((0 * 32) + 0)
+#define CP_FLAG_SWAP_DIRECTION_LOAD   0
+#define CP_FLAG_SWAP_DIRECTION_SAVE   1
+#define CP_FLAG_UNK01                 ((0 * 32) + 1)
+#define CP_FLAG_UNK01_CLEAR           0
+#define CP_FLAG_UNK01_SET             1
+#define CP_FLAG_UNK03                 ((0 * 32) + 3)
+#define CP_FLAG_UNK03_CLEAR           0
+#define CP_FLAG_UNK03_SET             1
+#define CP_FLAG_USER_SAVE             ((0 * 32) + 5)
+#define CP_FLAG_USER_SAVE_NOT_PENDING 0
+#define CP_FLAG_USER_SAVE_PENDING     1
+#define CP_FLAG_USER_LOAD             ((0 * 32) + 6)
+#define CP_FLAG_USER_LOAD_NOT_PENDING 0
+#define CP_FLAG_USER_LOAD_PENDING     1
+#define CP_FLAG_UNK0B                 ((0 * 32) + 0xb)
+#define CP_FLAG_UNK0B_CLEAR           0
+#define CP_FLAG_UNK0B_SET             1
+#define CP_FLAG_UNK1D                 ((0 * 32) + 0x1d)
+#define CP_FLAG_UNK1D_CLEAR           0
+#define CP_FLAG_UNK1D_SET             1
+#define CP_FLAG_UNK20                 ((1 * 32) + 0)
+#define CP_FLAG_UNK20_CLEAR           0
+#define CP_FLAG_UNK20_SET             1
+#define CP_FLAG_STATUS                ((2 * 32) + 0)
+#define CP_FLAG_STATUS_BUSY           0
+#define CP_FLAG_STATUS_IDLE           1
+#define CP_FLAG_AUTO_SAVE             ((2 * 32) + 4)
+#define CP_FLAG_AUTO_SAVE_NOT_PENDING 0
+#define CP_FLAG_AUTO_SAVE_PENDING     1
+#define CP_FLAG_AUTO_LOAD             ((2 * 32) + 5)
+#define CP_FLAG_AUTO_LOAD_NOT_PENDING 0
+#define CP_FLAG_AUTO_LOAD_PENDING     1
+#define CP_FLAG_NEWCTX                ((2 * 32) + 10)
+#define CP_FLAG_NEWCTX_BUSY           0
+#define CP_FLAG_NEWCTX_DONE           1
+#define CP_FLAG_XFER                  ((2 * 32) + 11)
+#define CP_FLAG_XFER_IDLE             0
+#define CP_FLAG_XFER_BUSY             1
+#define CP_FLAG_ALWAYS                ((2 * 32) + 13)
+#define CP_FLAG_ALWAYS_FALSE          0
+#define CP_FLAG_ALWAYS_TRUE           1
+#define CP_FLAG_INTR                  ((2 * 32) + 15)
+#define CP_FLAG_INTR_NOT_PENDING      0
+#define CP_FLAG_INTR_PENDING          1
+
+#define CP_CTX                   0x00100000
+#define CP_CTX_COUNT             0x000f0000
+#define CP_CTX_COUNT_SHIFT               16
+#define CP_CTX_REG               0x00003fff
+#define CP_LOAD_SR               0x00200000
+#define CP_LOAD_SR_VALUE         0x000fffff
+#define CP_BRA                   0x00400000
+#define CP_BRA_IP                0x0001ff00
+#define CP_BRA_IP_SHIFT                   8
+#define CP_BRA_IF_CLEAR          0x00000080
+#define CP_BRA_FLAG              0x0000007f
+#define CP_WAIT                  0x00500000
+#define CP_WAIT_SET              0x00000080
+#define CP_WAIT_FLAG             0x0000007f
+#define CP_SET                   0x00700000
+#define CP_SET_1                 0x00000080
+#define CP_SET_FLAG              0x0000007f
+#define CP_NEWCTX                0x00600004
+#define CP_NEXT_TO_SWAP          0x00600005
+#define CP_SET_CONTEXT_POINTER   0x00600006
+#define CP_SET_XFER_POINTER      0x00600007
+#define CP_ENABLE                0x00600009
+#define CP_END                   0x0060000c
+#define CP_NEXT_TO_CURRENT       0x0060000d
+#define CP_DISABLE1              0x0090ffff
+#define CP_DISABLE2              0x0091ffff
+#define CP_XFER_1      0x008000ff
+#define CP_XFER_2      0x008800ff
+#define CP_SEEK_1      0x00c000ff
+#define CP_SEEK_2      0x00c800ff
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_grctx.h"
+
+/*
+ * This code deals with PGRAPH contexts on NV50 family cards. Like NV40, it's
+ * the GPU itself that does context-switching, but it needs a special
+ * microcode to do it. And it's the driver's task to supply this microcode,
+ * further known as ctxprog, as well as the initial context values, known
+ * as ctxvals.
+ *
+ * Without ctxprog, you cannot switch contexts. Not even in software, since
+ * the majority of context [xfer strands] isn't accessible directly. You're
+ * stuck with a single channel, and you also suffer all the problems resulting
+ * from missing ctxvals, since you cannot load them.
+ *
+ * Without ctxvals, you're stuck with PGRAPH's default context. It's enough to
+ * run 2d operations, but trying to utilise 3d or CUDA will just lock you up,
+ * since you don't have... some sort of needed setup.
+ *
+ * Nouveau will just disable acceleration if not given ctxprog + ctxvals, since
+ * it's too much hassle to handle no-ctxprog as a special case.
+ */
+
+/*
+ * How ctxprogs work.
+ *
+ * The ctxprog is written in its own kind of microcode, with very small and
+ * crappy set of available commands. You upload it to a small [512 insns]
+ * area of memory on PGRAPH, and it'll be run when PFIFO wants PGRAPH to
+ * switch channel. or when the driver explicitely requests it. Stuff visible
+ * to ctxprog consists of: PGRAPH MMIO registers, PGRAPH context strands,
+ * the per-channel context save area in VRAM [known as ctxvals or grctx],
+ * 4 flags registers, a scratch register, two grctx pointers, plus many
+ * random poorly-understood details.
+ *
+ * When ctxprog runs, it's supposed to check what operations are asked of it,
+ * save old context if requested, optionally reset PGRAPH and switch to the
+ * new channel, and load the new context. Context consists of three major
+ * parts: subset of MMIO registers and two "xfer areas".
+ */
+
+/* TODO:
+ *  - document unimplemented bits compared to nvidia
+ *  - NVAx: make a TP subroutine, use it.
+ *  - use 0x4008fc instead of 0x1540?
+ */
+
+enum cp_label {
+	cp_check_load = 1,
+	cp_setup_auto_load,
+	cp_setup_load,
+	cp_setup_save,
+	cp_swap_state,
+	cp_prepare_exit,
+	cp_exit,
+};
+
+static void nv50_graph_construct_mmio(struct nouveau_grctx *ctx);
+static void nv50_graph_construct_xfer1(struct nouveau_grctx *ctx);
+static void nv50_graph_construct_xfer2(struct nouveau_grctx *ctx);
+
+/* Main function: construct the ctxprog skeleton, call the other functions. */
+
+int
+nv50_grctx_init(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+
+	switch (dev_priv->chipset) {
+	case 0x50:
+	case 0x84:
+	case 0x86:
+	case 0x92:
+	case 0x94:
+	case 0x96:
+	case 0x98:
+	case 0xa0:
+	case 0xa3:
+	case 0xa5:
+	case 0xa8:
+	case 0xaa:
+	case 0xac:
+		break;
+	default:
+		NV_ERROR(ctx->dev, "I don't know how to make a ctxprog for "
+				   "your NV%x card.\n", dev_priv->chipset);
+		NV_ERROR(ctx->dev, "Disabling acceleration. Please contact "
+				   "the devs.\n");
+		return -ENOSYS;
+	}
+	/* decide whether we're loading/unloading the context */
+	cp_bra (ctx, AUTO_SAVE, PENDING, cp_setup_save);
+	cp_bra (ctx, USER_SAVE, PENDING, cp_setup_save);
+
+	cp_name(ctx, cp_check_load);
+	cp_bra (ctx, AUTO_LOAD, PENDING, cp_setup_auto_load);
+	cp_bra (ctx, USER_LOAD, PENDING, cp_setup_load);
+	cp_bra (ctx, ALWAYS, TRUE, cp_exit);
+
+	/* setup for context load */
+	cp_name(ctx, cp_setup_auto_load);
+	cp_out (ctx, CP_DISABLE1);
+	cp_out (ctx, CP_DISABLE2);
+	cp_out (ctx, CP_ENABLE);
+	cp_out (ctx, CP_NEXT_TO_SWAP);
+	cp_set (ctx, UNK01, SET);
+	cp_name(ctx, cp_setup_load);
+	cp_out (ctx, CP_NEWCTX);
+	cp_wait(ctx, NEWCTX, BUSY);
+	cp_set (ctx, UNK1D, CLEAR);
+	cp_set (ctx, SWAP_DIRECTION, LOAD);
+	cp_bra (ctx, UNK0B, SET, cp_prepare_exit);
+	cp_bra (ctx, ALWAYS, TRUE, cp_swap_state);
+
+	/* setup for context save */
+	cp_name(ctx, cp_setup_save);
+	cp_set (ctx, UNK1D, SET);
+	cp_wait(ctx, STATUS, BUSY);
+	cp_wait(ctx, INTR, PENDING);
+	cp_bra (ctx, STATUS, BUSY, cp_setup_save);
+	cp_set (ctx, UNK01, SET);
+	cp_set (ctx, SWAP_DIRECTION, SAVE);
+
+	/* general PGRAPH state */
+	cp_name(ctx, cp_swap_state);
+	cp_set (ctx, UNK03, SET);
+	cp_pos (ctx, 0x00004/4);
+	cp_ctx (ctx, 0x400828, 1); /* needed. otherwise, flickering happens. */
+	cp_pos (ctx, 0x00100/4);
+	nv50_graph_construct_mmio(ctx);
+	nv50_graph_construct_xfer1(ctx);
+	nv50_graph_construct_xfer2(ctx);
+
+	cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_check_load);
+
+	cp_set (ctx, UNK20, SET);
+	cp_set (ctx, SWAP_DIRECTION, SAVE); /* no idea why this is needed, but fixes at least one lockup. */
+	cp_lsr (ctx, ctx->ctxvals_base);
+	cp_out (ctx, CP_SET_XFER_POINTER);
+	cp_lsr (ctx, 4);
+	cp_out (ctx, CP_SEEK_1);
+	cp_out (ctx, CP_XFER_1);
+	cp_wait(ctx, XFER, BUSY);
+
+	/* pre-exit state updates */
+	cp_name(ctx, cp_prepare_exit);
+	cp_set (ctx, UNK01, CLEAR);
+	cp_set (ctx, UNK03, CLEAR);
+	cp_set (ctx, UNK1D, CLEAR);
+
+	cp_bra (ctx, USER_SAVE, PENDING, cp_exit);
+	cp_out (ctx, CP_NEXT_TO_CURRENT);
+
+	cp_name(ctx, cp_exit);
+	cp_set (ctx, USER_SAVE, NOT_PENDING);
+	cp_set (ctx, USER_LOAD, NOT_PENDING);
+	cp_out (ctx, CP_END);
+	ctx->ctxvals_pos += 0x400; /* padding... no idea why you need it */
+
+	return 0;
+}
+
+/*
+ * Constructs MMIO part of ctxprog and ctxvals. Just a matter of knowing which
+ * registers to save/restore and the default values for them.
+ */
+
+static void
+nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	int i, j;
+	int offset, base;
+	uint32_t units = nv_rd32 (ctx->dev, 0x1540);
+
+	/* 0800: DISPATCH */
+	cp_ctx(ctx, 0x400808, 7);
+	gr_def(ctx, 0x400814, 0x00000030);
+	cp_ctx(ctx, 0x400834, 0x32);
+	if (dev_priv->chipset == 0x50) {
+		gr_def(ctx, 0x400834, 0xff400040);
+		gr_def(ctx, 0x400838, 0xfff00080);
+		gr_def(ctx, 0x40083c, 0xfff70090);
+		gr_def(ctx, 0x400840, 0xffe806a8);
+	}
+	gr_def(ctx, 0x400844, 0x00000002);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		gr_def(ctx, 0x400894, 0x00001000);
+	gr_def(ctx, 0x4008e8, 0x00000003);
+	gr_def(ctx, 0x4008ec, 0x00001000);
+	if (dev_priv->chipset == 0x50)
+		cp_ctx(ctx, 0x400908, 0xb);
+	else if (dev_priv->chipset < 0xa0)
+		cp_ctx(ctx, 0x400908, 0xc);
+	else
+		cp_ctx(ctx, 0x400908, 0xe);
+
+	if (dev_priv->chipset >= 0xa0)
+		cp_ctx(ctx, 0x400b00, 0x1);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) {
+		cp_ctx(ctx, 0x400b10, 0x1);
+		gr_def(ctx, 0x400b10, 0x0001629d);
+		cp_ctx(ctx, 0x400b20, 0x1);
+		gr_def(ctx, 0x400b20, 0x0001629d);
+	}
+
+	/* 0C00: VFETCH */
+	cp_ctx(ctx, 0x400c08, 0x2);
+	gr_def(ctx, 0x400c08, 0x0000fe0c);
+
+	/* 1000 */
+	if (dev_priv->chipset < 0xa0) {
+		cp_ctx(ctx, 0x401008, 0x4);
+		gr_def(ctx, 0x401014, 0x00001000);
+	} else if (dev_priv->chipset == 0xa0 || dev_priv->chipset >= 0xaa) {
+		cp_ctx(ctx, 0x401008, 0x5);
+		gr_def(ctx, 0x401018, 0x00001000);
+	} else {
+		cp_ctx(ctx, 0x401008, 0x5);
+		gr_def(ctx, 0x401018, 0x00004000);
+	}
+
+	/* 1400 */
+	cp_ctx(ctx, 0x401400, 0x8);
+	cp_ctx(ctx, 0x401424, 0x3);
+	if (dev_priv->chipset == 0x50)
+		gr_def(ctx, 0x40142c, 0x0001fd87);
+	else
+		gr_def(ctx, 0x40142c, 0x00000187);
+	cp_ctx(ctx, 0x401540, 0x5);
+	gr_def(ctx, 0x401550, 0x00001018);
+
+	/* 1800: STREAMOUT */
+	cp_ctx(ctx, 0x401814, 0x1);
+	gr_def(ctx, 0x401814, 0x000000ff);
+	if (dev_priv->chipset == 0x50) {
+		cp_ctx(ctx, 0x40181c, 0xe);
+		gr_def(ctx, 0x401850, 0x00000004);
+	} else if (dev_priv->chipset < 0xa0) {
+		cp_ctx(ctx, 0x40181c, 0xf);
+		gr_def(ctx, 0x401854, 0x00000004);
+	} else {
+		cp_ctx(ctx, 0x40181c, 0x13);
+		gr_def(ctx, 0x401864, 0x00000004);
+	}
+
+	/* 1C00 */
+	cp_ctx(ctx, 0x401c00, 0x1);
+	switch (dev_priv->chipset) {
+	case 0x50:
+		gr_def(ctx, 0x401c00, 0x0001005f);
+		break;
+	case 0x84:
+	case 0x86:
+	case 0x94:
+		gr_def(ctx, 0x401c00, 0x044d00df);
+		break;
+	case 0x92:
+	case 0x96:
+	case 0x98:
+	case 0xa0:
+	case 0xaa:
+	case 0xac:
+		gr_def(ctx, 0x401c00, 0x042500df);
+		break;
+	case 0xa3:
+	case 0xa5:
+	case 0xa8:
+		gr_def(ctx, 0x401c00, 0x142500df);
+		break;
+	}
+
+	/* 2400 */
+	cp_ctx(ctx, 0x402400, 0x1);
+	if (dev_priv->chipset == 0x50)
+		cp_ctx(ctx, 0x402408, 0x1);
+	else
+		cp_ctx(ctx, 0x402408, 0x2);
+	gr_def(ctx, 0x402408, 0x00000600);
+
+	/* 2800 */
+	cp_ctx(ctx, 0x402800, 0x1);
+	if (dev_priv->chipset == 0x50)
+		gr_def(ctx, 0x402800, 0x00000006);
+
+	/* 2C00 */
+	cp_ctx(ctx, 0x402c08, 0x6);
+	if (dev_priv->chipset != 0x50)
+		gr_def(ctx, 0x402c14, 0x01000000);
+	gr_def(ctx, 0x402c18, 0x000000ff);
+	if (dev_priv->chipset == 0x50)
+		cp_ctx(ctx, 0x402ca0, 0x1);
+	else
+		cp_ctx(ctx, 0x402ca0, 0x2);
+	if (dev_priv->chipset < 0xa0)
+		gr_def(ctx, 0x402ca0, 0x00000400);
+	else if (dev_priv->chipset == 0xa0 || dev_priv->chipset >= 0xaa)
+		gr_def(ctx, 0x402ca0, 0x00000800);
+	else
+		gr_def(ctx, 0x402ca0, 0x00000400);
+	cp_ctx(ctx, 0x402cac, 0x4);
+
+	/* 3000 */
+	cp_ctx(ctx, 0x403004, 0x1);
+	gr_def(ctx, 0x403004, 0x00000001);
+
+	/* 3404 */
+	if (dev_priv->chipset >= 0xa0) {
+		cp_ctx(ctx, 0x403404, 0x1);
+		gr_def(ctx, 0x403404, 0x00000001);
+	}
+
+	/* 5000 */
+	cp_ctx(ctx, 0x405000, 0x1);
+	switch (dev_priv->chipset) {
+	case 0x50:
+		gr_def(ctx, 0x405000, 0x00300080);
+		break;
+	case 0x84:
+	case 0xa0:
+	case 0xa3:
+	case 0xa5:
+	case 0xa8:
+	case 0xaa:
+	case 0xac:
+		gr_def(ctx, 0x405000, 0x000e0080);
+		break;
+	case 0x86:
+	case 0x92:
+	case 0x94:
+	case 0x96:
+	case 0x98:
+		gr_def(ctx, 0x405000, 0x00000080);
+		break;
+	}
+	cp_ctx(ctx, 0x405014, 0x1);
+	gr_def(ctx, 0x405014, 0x00000004);
+	cp_ctx(ctx, 0x40501c, 0x1);
+	cp_ctx(ctx, 0x405024, 0x1);
+	cp_ctx(ctx, 0x40502c, 0x1);
+
+	/* 5400 or maybe 4800 */
+	if (dev_priv->chipset == 0x50) {
+		offset = 0x405400;
+		cp_ctx(ctx, 0x405400, 0xea);
+	} else if (dev_priv->chipset < 0x94) {
+		offset = 0x405400;
+		cp_ctx(ctx, 0x405400, 0xcb);
+	} else if (dev_priv->chipset < 0xa0) {
+		offset = 0x405400;
+		cp_ctx(ctx, 0x405400, 0xcc);
+	} else if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) {
+		offset = 0x404800;
+		cp_ctx(ctx, 0x404800, 0xda);
+	} else {
+		offset = 0x405400;
+		cp_ctx(ctx, 0x405400, 0xd4);
+	}
+	gr_def(ctx, offset + 0x0c, 0x00000002);
+	gr_def(ctx, offset + 0x10, 0x00000001);
+	if (dev_priv->chipset >= 0x94)
+		offset += 4;
+	gr_def(ctx, offset + 0x1c, 0x00000001);
+	gr_def(ctx, offset + 0x20, 0x00000100);
+	gr_def(ctx, offset + 0x38, 0x00000002);
+	gr_def(ctx, offset + 0x3c, 0x00000001);
+	gr_def(ctx, offset + 0x40, 0x00000001);
+	gr_def(ctx, offset + 0x50, 0x00000001);
+	gr_def(ctx, offset + 0x54, 0x003fffff);
+	gr_def(ctx, offset + 0x58, 0x00001fff);
+	gr_def(ctx, offset + 0x60, 0x00000001);
+	gr_def(ctx, offset + 0x64, 0x00000001);
+	gr_def(ctx, offset + 0x6c, 0x00000001);
+	gr_def(ctx, offset + 0x70, 0x00000001);
+	gr_def(ctx, offset + 0x74, 0x00000001);
+	gr_def(ctx, offset + 0x78, 0x00000004);
+	gr_def(ctx, offset + 0x7c, 0x00000001);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		offset += 4;
+	gr_def(ctx, offset + 0x80, 0x00000001);
+	gr_def(ctx, offset + 0x84, 0x00000001);
+	gr_def(ctx, offset + 0x88, 0x00000007);
+	gr_def(ctx, offset + 0x8c, 0x00000001);
+	gr_def(ctx, offset + 0x90, 0x00000007);
+	gr_def(ctx, offset + 0x94, 0x00000001);
+	gr_def(ctx, offset + 0x98, 0x00000001);
+	gr_def(ctx, offset + 0x9c, 0x00000001);
+	if (dev_priv->chipset == 0x50) {
+		 gr_def(ctx, offset + 0xb0, 0x00000001);
+		 gr_def(ctx, offset + 0xb4, 0x00000001);
+		 gr_def(ctx, offset + 0xbc, 0x00000001);
+		 gr_def(ctx, offset + 0xc0, 0x0000000a);
+		 gr_def(ctx, offset + 0xd0, 0x00000040);
+		 gr_def(ctx, offset + 0xd8, 0x00000002);
+		 gr_def(ctx, offset + 0xdc, 0x00000100);
+		 gr_def(ctx, offset + 0xe0, 0x00000001);
+		 gr_def(ctx, offset + 0xe4, 0x00000100);
+		 gr_def(ctx, offset + 0x100, 0x00000001);
+		 gr_def(ctx, offset + 0x124, 0x00000004);
+		 gr_def(ctx, offset + 0x13c, 0x00000001);
+		 gr_def(ctx, offset + 0x140, 0x00000100);
+		 gr_def(ctx, offset + 0x148, 0x00000001);
+		 gr_def(ctx, offset + 0x154, 0x00000100);
+		 gr_def(ctx, offset + 0x158, 0x00000001);
+		 gr_def(ctx, offset + 0x15c, 0x00000100);
+		 gr_def(ctx, offset + 0x164, 0x00000001);
+		 gr_def(ctx, offset + 0x170, 0x00000100);
+		 gr_def(ctx, offset + 0x174, 0x00000001);
+		 gr_def(ctx, offset + 0x17c, 0x00000001);
+		 gr_def(ctx, offset + 0x188, 0x00000002);
+		 gr_def(ctx, offset + 0x190, 0x00000001);
+		 gr_def(ctx, offset + 0x198, 0x00000001);
+		 gr_def(ctx, offset + 0x1ac, 0x00000003);
+		 offset += 0xd0;
+	} else {
+		gr_def(ctx, offset + 0xb0, 0x00000001);
+		gr_def(ctx, offset + 0xb4, 0x00000100);
+		gr_def(ctx, offset + 0xbc, 0x00000001);
+		gr_def(ctx, offset + 0xc8, 0x00000100);
+		gr_def(ctx, offset + 0xcc, 0x00000001);
+		gr_def(ctx, offset + 0xd0, 0x00000100);
+		gr_def(ctx, offset + 0xd8, 0x00000001);
+		gr_def(ctx, offset + 0xe4, 0x00000100);
+	}
+	gr_def(ctx, offset + 0xf8, 0x00000004);
+	gr_def(ctx, offset + 0xfc, 0x00000070);
+	gr_def(ctx, offset + 0x100, 0x00000080);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		offset += 4;
+	gr_def(ctx, offset + 0x114, 0x0000000c);
+	if (dev_priv->chipset == 0x50)
+		offset -= 4;
+	gr_def(ctx, offset + 0x11c, 0x00000008);
+	gr_def(ctx, offset + 0x120, 0x00000014);
+	if (dev_priv->chipset == 0x50) {
+		gr_def(ctx, offset + 0x124, 0x00000026);
+		offset -= 0x18;
+	} else {
+		gr_def(ctx, offset + 0x128, 0x00000029);
+		gr_def(ctx, offset + 0x12c, 0x00000027);
+		gr_def(ctx, offset + 0x130, 0x00000026);
+		gr_def(ctx, offset + 0x134, 0x00000008);
+		gr_def(ctx, offset + 0x138, 0x00000004);
+		gr_def(ctx, offset + 0x13c, 0x00000027);
+	}
+	gr_def(ctx, offset + 0x148, 0x00000001);
+	gr_def(ctx, offset + 0x14c, 0x00000002);
+	gr_def(ctx, offset + 0x150, 0x00000003);
+	gr_def(ctx, offset + 0x154, 0x00000004);
+	gr_def(ctx, offset + 0x158, 0x00000005);
+	gr_def(ctx, offset + 0x15c, 0x00000006);
+	gr_def(ctx, offset + 0x160, 0x00000007);
+	gr_def(ctx, offset + 0x164, 0x00000001);
+	gr_def(ctx, offset + 0x1a8, 0x000000cf);
+	if (dev_priv->chipset == 0x50)
+		offset -= 4;
+	gr_def(ctx, offset + 0x1d8, 0x00000080);
+	gr_def(ctx, offset + 0x1dc, 0x00000004);
+	gr_def(ctx, offset + 0x1e0, 0x00000004);
+	if (dev_priv->chipset == 0x50)
+		offset -= 4;
+	else
+		gr_def(ctx, offset + 0x1e4, 0x00000003);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) {
+		gr_def(ctx, offset + 0x1ec, 0x00000003);
+		offset += 8;
+	}
+	gr_def(ctx, offset + 0x1e8, 0x00000001);
+	if (dev_priv->chipset == 0x50)
+		offset -= 4;
+	gr_def(ctx, offset + 0x1f4, 0x00000012);
+	gr_def(ctx, offset + 0x1f8, 0x00000010);
+	gr_def(ctx, offset + 0x1fc, 0x0000000c);
+	gr_def(ctx, offset + 0x200, 0x00000001);
+	gr_def(ctx, offset + 0x210, 0x00000004);
+	gr_def(ctx, offset + 0x214, 0x00000002);
+	gr_def(ctx, offset + 0x218, 0x00000004);
+	if (dev_priv->chipset >= 0xa0)
+		offset += 4;
+	gr_def(ctx, offset + 0x224, 0x003fffff);
+	gr_def(ctx, offset + 0x228, 0x00001fff);
+	if (dev_priv->chipset == 0x50)
+		offset -= 0x20;
+	else if (dev_priv->chipset >= 0xa0) {
+		gr_def(ctx, offset + 0x250, 0x00000001);
+		gr_def(ctx, offset + 0x254, 0x00000001);
+		gr_def(ctx, offset + 0x258, 0x00000002);
+		offset += 0x10;
+	}
+	gr_def(ctx, offset + 0x250, 0x00000004);
+	gr_def(ctx, offset + 0x254, 0x00000014);
+	gr_def(ctx, offset + 0x258, 0x00000001);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		offset += 4;
+	gr_def(ctx, offset + 0x264, 0x00000002);
+	if (dev_priv->chipset >= 0xa0)
+		offset += 8;
+	gr_def(ctx, offset + 0x270, 0x00000001);
+	gr_def(ctx, offset + 0x278, 0x00000002);
+	gr_def(ctx, offset + 0x27c, 0x00001000);
+	if (dev_priv->chipset == 0x50)
+		offset -= 0xc;
+	else {
+		gr_def(ctx, offset + 0x280, 0x00000e00);
+		gr_def(ctx, offset + 0x284, 0x00001000);
+		gr_def(ctx, offset + 0x288, 0x00001e00);
+	}
+	gr_def(ctx, offset + 0x290, 0x00000001);
+	gr_def(ctx, offset + 0x294, 0x00000001);
+	gr_def(ctx, offset + 0x298, 0x00000001);
+	gr_def(ctx, offset + 0x29c, 0x00000001);
+	gr_def(ctx, offset + 0x2a0, 0x00000001);
+	gr_def(ctx, offset + 0x2b0, 0x00000200);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) {
+		gr_def(ctx, offset + 0x2b4, 0x00000200);
+		offset += 4;
+	}
+	if (dev_priv->chipset < 0xa0) {
+		gr_def(ctx, offset + 0x2b8, 0x00000001);
+		gr_def(ctx, offset + 0x2bc, 0x00000070);
+		gr_def(ctx, offset + 0x2c0, 0x00000080);
+		gr_def(ctx, offset + 0x2cc, 0x00000001);
+		gr_def(ctx, offset + 0x2d0, 0x00000070);
+		gr_def(ctx, offset + 0x2d4, 0x00000080);
+	} else {
+		gr_def(ctx, offset + 0x2b8, 0x00000001);
+		gr_def(ctx, offset + 0x2bc, 0x000000f0);
+		gr_def(ctx, offset + 0x2c0, 0x000000ff);
+		gr_def(ctx, offset + 0x2cc, 0x00000001);
+		gr_def(ctx, offset + 0x2d0, 0x000000f0);
+		gr_def(ctx, offset + 0x2d4, 0x000000ff);
+		gr_def(ctx, offset + 0x2dc, 0x00000009);
+		offset += 4;
+	}
+	gr_def(ctx, offset + 0x2e4, 0x00000001);
+	gr_def(ctx, offset + 0x2e8, 0x000000cf);
+	gr_def(ctx, offset + 0x2f0, 0x00000001);
+	gr_def(ctx, offset + 0x300, 0x000000cf);
+	gr_def(ctx, offset + 0x308, 0x00000002);
+	gr_def(ctx, offset + 0x310, 0x00000001);
+	gr_def(ctx, offset + 0x318, 0x00000001);
+	gr_def(ctx, offset + 0x320, 0x000000cf);
+	gr_def(ctx, offset + 0x324, 0x000000cf);
+	gr_def(ctx, offset + 0x328, 0x00000001);
+
+	/* 6000? */
+	if (dev_priv->chipset == 0x50)
+		cp_ctx(ctx, 0x4063e0, 0x1);
+
+	/* 6800: M2MF */
+	if (dev_priv->chipset < 0x90) {
+		cp_ctx(ctx, 0x406814, 0x2b);
+		gr_def(ctx, 0x406818, 0x00000f80);
+		gr_def(ctx, 0x406860, 0x007f0080);
+		gr_def(ctx, 0x40689c, 0x007f0080);
+	} else {
+		cp_ctx(ctx, 0x406814, 0x4);
+		if (dev_priv->chipset == 0x98)
+			gr_def(ctx, 0x406818, 0x00000f80);
+		else
+			gr_def(ctx, 0x406818, 0x00001f80);
+		if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+			gr_def(ctx, 0x40681c, 0x00000030);
+		cp_ctx(ctx, 0x406830, 0x3);
+	}
+
+	/* 7000: per-ROP group state */
+	for (i = 0; i < 8; i++) {
+		if (units & (1<<(i+16))) {
+			cp_ctx(ctx, 0x407000 + (i<<8), 3);
+			if (dev_priv->chipset == 0x50)
+				gr_def(ctx, 0x407000 + (i<<8), 0x1b74f820);
+			else if (dev_priv->chipset != 0xa5)
+				gr_def(ctx, 0x407000 + (i<<8), 0x3b74f821);
+			else
+				gr_def(ctx, 0x407000 + (i<<8), 0x7b74f821);
+			gr_def(ctx, 0x407004 + (i<<8), 0x89058001);
+
+			if (dev_priv->chipset == 0x50) {
+				cp_ctx(ctx, 0x407010 + (i<<8), 1);
+			} else if (dev_priv->chipset < 0xa0) {
+				cp_ctx(ctx, 0x407010 + (i<<8), 2);
+				gr_def(ctx, 0x407010 + (i<<8), 0x00001000);
+				gr_def(ctx, 0x407014 + (i<<8), 0x0000001f);
+			} else {
+				cp_ctx(ctx, 0x407010 + (i<<8), 3);
+				gr_def(ctx, 0x407010 + (i<<8), 0x00001000);
+				if (dev_priv->chipset != 0xa5)
+					gr_def(ctx, 0x407014 + (i<<8), 0x000000ff);
+				else
+					gr_def(ctx, 0x407014 + (i<<8), 0x000001ff);
+			}
+
+			cp_ctx(ctx, 0x407080 + (i<<8), 4);
+			if (dev_priv->chipset != 0xa5)
+				gr_def(ctx, 0x407080 + (i<<8), 0x027c10fa);
+			else
+				gr_def(ctx, 0x407080 + (i<<8), 0x827c10fa);
+			if (dev_priv->chipset == 0x50)
+				gr_def(ctx, 0x407084 + (i<<8), 0x000000c0);
+			else
+				gr_def(ctx, 0x407084 + (i<<8), 0x400000c0);
+			gr_def(ctx, 0x407088 + (i<<8), 0xb7892080);
+
+			if (dev_priv->chipset < 0xa0)
+				cp_ctx(ctx, 0x407094 + (i<<8), 1);
+			else if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa)
+				cp_ctx(ctx, 0x407094 + (i<<8), 3);
+			else {
+				cp_ctx(ctx, 0x407094 + (i<<8), 4);
+				gr_def(ctx, 0x4070a0 + (i<<8), 1);
+			}
+		}
+	}
+
+	cp_ctx(ctx, 0x407c00, 0x3);
+	if (dev_priv->chipset < 0x90)
+		gr_def(ctx, 0x407c00, 0x00010040);
+	else if (dev_priv->chipset < 0xa0)
+		gr_def(ctx, 0x407c00, 0x00390040);
+	else
+		gr_def(ctx, 0x407c00, 0x003d0040);
+	gr_def(ctx, 0x407c08, 0x00000022);
+	if (dev_priv->chipset >= 0xa0) {
+		cp_ctx(ctx, 0x407c10, 0x3);
+		cp_ctx(ctx, 0x407c20, 0x1);
+		cp_ctx(ctx, 0x407c2c, 0x1);
+	}
+
+	if (dev_priv->chipset < 0xa0) {
+		cp_ctx(ctx, 0x407d00, 0x9);
+	} else {
+		cp_ctx(ctx, 0x407d00, 0x15);
+	}
+	if (dev_priv->chipset == 0x98)
+		gr_def(ctx, 0x407d08, 0x00380040);
+	else {
+		if (dev_priv->chipset < 0x90)
+			gr_def(ctx, 0x407d08, 0x00010040);
+		else if (dev_priv->chipset < 0xa0)
+			gr_def(ctx, 0x407d08, 0x00390040);
+		else
+			gr_def(ctx, 0x407d08, 0x003d0040);
+		gr_def(ctx, 0x407d0c, 0x00000022);
+	}
+
+	/* 8000+: per-TP state */
+	for (i = 0; i < 10; i++) {
+		if (units & (1<<i)) {
+			if (dev_priv->chipset < 0xa0)
+				base = 0x408000 + (i<<12);
+			else
+				base = 0x408000 + (i<<11);
+			if (dev_priv->chipset < 0xa0)
+				offset = base + 0xc00;
+			else
+				offset = base + 0x80;
+			cp_ctx(ctx, offset + 0x00, 1);
+			gr_def(ctx, offset + 0x00, 0x0000ff0a);
+			cp_ctx(ctx, offset + 0x08, 1);
+
+			/* per-MP state */
+			for (j = 0; j < (dev_priv->chipset < 0xa0 ? 2 : 4); j++) {
+				if (!(units & (1 << (j+24)))) continue;
+				if (dev_priv->chipset < 0xa0)
+					offset = base + 0x200 + (j<<7);
+				else
+					offset = base + 0x100 + (j<<7);
+				cp_ctx(ctx, offset, 0x20);
+				gr_def(ctx, offset + 0x00, 0x01800000);
+				gr_def(ctx, offset + 0x04, 0x00160000);
+				gr_def(ctx, offset + 0x08, 0x01800000);
+				gr_def(ctx, offset + 0x18, 0x0003ffff);
+				switch (dev_priv->chipset) {
+				case 0x50:
+					gr_def(ctx, offset + 0x1c, 0x00080000);
+					break;
+				case 0x84:
+					gr_def(ctx, offset + 0x1c, 0x00880000);
+					break;
+				case 0x86:
+					gr_def(ctx, offset + 0x1c, 0x008c0000);
+					break;
+				case 0x92:
+				case 0x96:
+				case 0x98:
+					gr_def(ctx, offset + 0x1c, 0x118c0000);
+					break;
+				case 0x94:
+					gr_def(ctx, offset + 0x1c, 0x10880000);
+					break;
+				case 0xa0:
+				case 0xa5:
+					gr_def(ctx, offset + 0x1c, 0x310c0000);
+					break;
+				case 0xa3:
+				case 0xa8:
+				case 0xaa:
+				case 0xac:
+					gr_def(ctx, offset + 0x1c, 0x300c0000);
+					break;
+				}
+				gr_def(ctx, offset + 0x40, 0x00010401);
+				if (dev_priv->chipset == 0x50)
+					gr_def(ctx, offset + 0x48, 0x00000040);
+				else
+					gr_def(ctx, offset + 0x48, 0x00000078);
+				gr_def(ctx, offset + 0x50, 0x000000bf);
+				gr_def(ctx, offset + 0x58, 0x00001210);
+				if (dev_priv->chipset == 0x50)
+					gr_def(ctx, offset + 0x5c, 0x00000080);
+				else
+					gr_def(ctx, offset + 0x5c, 0x08000080);
+				if (dev_priv->chipset >= 0xa0)
+					gr_def(ctx, offset + 0x68, 0x0000003e);
+			}
+
+			if (dev_priv->chipset < 0xa0)
+				cp_ctx(ctx, base + 0x300, 0x4);
+			else
+				cp_ctx(ctx, base + 0x300, 0x5);
+			if (dev_priv->chipset == 0x50)
+				gr_def(ctx, base + 0x304, 0x00007070);
+			else if (dev_priv->chipset < 0xa0)
+				gr_def(ctx, base + 0x304, 0x00027070);
+			else if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa)
+				gr_def(ctx, base + 0x304, 0x01127070);
+			else
+				gr_def(ctx, base + 0x304, 0x05127070);
+
+			if (dev_priv->chipset < 0xa0)
+				cp_ctx(ctx, base + 0x318, 1);
+			else
+				cp_ctx(ctx, base + 0x320, 1);
+			if (dev_priv->chipset == 0x50)
+				gr_def(ctx, base + 0x318, 0x0003ffff);
+			else if (dev_priv->chipset < 0xa0)
+				gr_def(ctx, base + 0x318, 0x03ffffff);
+			else
+				gr_def(ctx, base + 0x320, 0x07ffffff);
+
+			if (dev_priv->chipset < 0xa0)
+				cp_ctx(ctx, base + 0x324, 5);
+			else
+				cp_ctx(ctx, base + 0x328, 4);
+
+			if (dev_priv->chipset < 0xa0) {
+				cp_ctx(ctx, base + 0x340, 9);
+				offset = base + 0x340;
+			} else if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa) {
+				cp_ctx(ctx, base + 0x33c, 0xb);
+				offset = base + 0x344;
+			} else {
+				cp_ctx(ctx, base + 0x33c, 0xd);
+				offset = base + 0x344;
+			}
+			gr_def(ctx, offset + 0x0, 0x00120407);
+			gr_def(ctx, offset + 0x4, 0x05091507);
+			if (dev_priv->chipset == 0x84)
+				gr_def(ctx, offset + 0x8, 0x05100202);
+			else
+				gr_def(ctx, offset + 0x8, 0x05010202);
+			gr_def(ctx, offset + 0xc, 0x00030201);
+			if (dev_priv->chipset == 0xa3)
+				cp_ctx(ctx, base + 0x36c, 1);
+
+			cp_ctx(ctx, base + 0x400, 2);
+			gr_def(ctx, base + 0x404, 0x00000040);
+			cp_ctx(ctx, base + 0x40c, 2);
+			gr_def(ctx, base + 0x40c, 0x0d0c0b0a);
+			gr_def(ctx, base + 0x410, 0x00141210);
+
+			if (dev_priv->chipset < 0xa0)
+				offset = base + 0x800;
+			else
+				offset = base + 0x500;
+			cp_ctx(ctx, offset, 6);
+			gr_def(ctx, offset + 0x0, 0x000001f0);
+			gr_def(ctx, offset + 0x4, 0x00000001);
+			gr_def(ctx, offset + 0x8, 0x00000003);
+			if (dev_priv->chipset == 0x50 || dev_priv->chipset >= 0xaa)
+				gr_def(ctx, offset + 0xc, 0x00008000);
+			gr_def(ctx, offset + 0x14, 0x00039e00);
+			cp_ctx(ctx, offset + 0x1c, 2);
+			if (dev_priv->chipset == 0x50)
+				gr_def(ctx, offset + 0x1c, 0x00000040);
+			else
+				gr_def(ctx, offset + 0x1c, 0x00000100);
+			gr_def(ctx, offset + 0x20, 0x00003800);
+
+			if (dev_priv->chipset >= 0xa0) {
+				cp_ctx(ctx, base + 0x54c, 2);
+				if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa)
+					gr_def(ctx, base + 0x54c, 0x003fe006);
+				else
+					gr_def(ctx, base + 0x54c, 0x003fe007);
+				gr_def(ctx, base + 0x550, 0x003fe000);
+			}
+
+			if (dev_priv->chipset < 0xa0)
+				offset = base + 0xa00;
+			else
+				offset = base + 0x680;
+			cp_ctx(ctx, offset, 1);
+			gr_def(ctx, offset, 0x00404040);
+
+			if (dev_priv->chipset < 0xa0)
+				offset = base + 0xe00;
+			else
+				offset = base + 0x700;
+			cp_ctx(ctx, offset, 2);
+			if (dev_priv->chipset < 0xa0)
+				gr_def(ctx, offset, 0x0077f005);
+			else if (dev_priv->chipset == 0xa5)
+				gr_def(ctx, offset, 0x6cf7f007);
+			else if (dev_priv->chipset == 0xa8)
+				gr_def(ctx, offset, 0x6cfff007);
+			else if (dev_priv->chipset == 0xac)
+				gr_def(ctx, offset, 0x0cfff007);
+			else
+				gr_def(ctx, offset, 0x0cf7f007);
+			if (dev_priv->chipset == 0x50)
+				gr_def(ctx, offset + 0x4, 0x00007fff);
+			else if (dev_priv->chipset < 0xa0)
+				gr_def(ctx, offset + 0x4, 0x003f7fff);
+			else
+				gr_def(ctx, offset + 0x4, 0x02bf7fff);
+			cp_ctx(ctx, offset + 0x2c, 1);
+			if (dev_priv->chipset == 0x50) {
+				cp_ctx(ctx, offset + 0x50, 9);
+				gr_def(ctx, offset + 0x54, 0x000003ff);
+				gr_def(ctx, offset + 0x58, 0x00000003);
+				gr_def(ctx, offset + 0x5c, 0x00000003);
+				gr_def(ctx, offset + 0x60, 0x000001ff);
+				gr_def(ctx, offset + 0x64, 0x0000001f);
+				gr_def(ctx, offset + 0x68, 0x0000000f);
+				gr_def(ctx, offset + 0x6c, 0x0000000f);
+			} else if(dev_priv->chipset < 0xa0) {
+				cp_ctx(ctx, offset + 0x50, 1);
+				cp_ctx(ctx, offset + 0x70, 1);
+			} else {
+				cp_ctx(ctx, offset + 0x50, 1);
+				cp_ctx(ctx, offset + 0x60, 5);
+			}
+		}
+	}
+}
+
+/*
+ * xfer areas. These are a pain.
+ *
+ * There are 2 xfer areas: the first one is big and contains all sorts of
+ * stuff, the second is small and contains some per-TP context.
+ *
+ * Each area is split into 8 "strands". The areas, when saved to grctx,
+ * are made of 8-word blocks. Each block contains a single word from
+ * each strand. The strands are independent of each other, their
+ * addresses are unrelated to each other, and data in them is closely
+ * packed together. The strand layout varies a bit between cards: here
+ * and there, a single word is thrown out in the middle and the whole
+ * strand is offset by a bit from corresponding one on another chipset.
+ * For this reason, addresses of stuff in strands are almost useless.
+ * Knowing sequence of stuff and size of gaps between them is much more
+ * useful, and that's how we build the strands in our generator.
+ *
+ * NVA0 takes this mess to a whole new level by cutting the old strands
+ * into a few dozen pieces [known as genes], rearranging them randomly,
+ * and putting them back together to make new strands. Hopefully these
+ * genes correspond more or less directly to the same PGRAPH subunits
+ * as in 400040 register.
+ *
+ * The most common value in default context is 0, and when the genes
+ * are separated by 0's, gene bounduaries are quite speculative...
+ * some of them can be clearly deduced, others can be guessed, and yet
+ * others won't be resolved without figuring out the real meaning of
+ * given ctxval. For the same reason, ending point of each strand
+ * is unknown. Except for strand 0, which is the longest strand and
+ * its end corresponds to end of the whole xfer.
+ *
+ * An unsolved mystery is the seek instruction: it takes an argument
+ * in bits 8-18, and that argument is clearly the place in strands to
+ * seek to... but the offsets don't seem to correspond to offsets as
+ * seen in grctx. Perhaps there's another, real, not randomly-changing
+ * addressing in strands, and the xfer insn just happens to skip over
+ * the unused bits? NV10-NV30 PIPE comes to mind...
+ *
+ * As far as I know, there's no way to access the xfer areas directly
+ * without the help of ctxprog.
+ */
+
+static inline void
+xf_emit(struct nouveau_grctx *ctx, int num, uint32_t val) {
+	int i;
+	if (val && ctx->mode == NOUVEAU_GRCTX_VALS)
+		for (i = 0; i < num; i++)
+			nv_wo32(ctx->dev, ctx->data, ctx->ctxvals_pos + (i << 3), val);
+	ctx->ctxvals_pos += num << 3;
+}
+
+/* Gene declarations... */
+
+static void nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx);
+static void nv50_graph_construct_gene_unk1(struct nouveau_grctx *ctx);
+static void nv50_graph_construct_gene_unk2(struct nouveau_grctx *ctx);
+static void nv50_graph_construct_gene_unk3(struct nouveau_grctx *ctx);
+static void nv50_graph_construct_gene_unk4(struct nouveau_grctx *ctx);
+static void nv50_graph_construct_gene_unk5(struct nouveau_grctx *ctx);
+static void nv50_graph_construct_gene_unk6(struct nouveau_grctx *ctx);
+static void nv50_graph_construct_gene_unk7(struct nouveau_grctx *ctx);
+static void nv50_graph_construct_gene_unk8(struct nouveau_grctx *ctx);
+static void nv50_graph_construct_gene_unk9(struct nouveau_grctx *ctx);
+static void nv50_graph_construct_gene_unk10(struct nouveau_grctx *ctx);
+static void nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx);
+static void nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx);
+
+static void
+nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	int i;
+	int offset;
+	int size = 0;
+	uint32_t units = nv_rd32 (ctx->dev, 0x1540);
+
+	offset = (ctx->ctxvals_pos+0x3f)&~0x3f;
+	ctx->ctxvals_base = offset;
+
+	if (dev_priv->chipset < 0xa0) {
+		/* Strand 0 */
+		ctx->ctxvals_pos = offset;
+		switch (dev_priv->chipset) {
+		case 0x50:
+			xf_emit(ctx, 0x99, 0);
+			break;
+		case 0x84:
+		case 0x86:
+			xf_emit(ctx, 0x384, 0);
+			break;
+		case 0x92:
+		case 0x94:
+		case 0x96:
+		case 0x98:
+			xf_emit(ctx, 0x380, 0);
+			break;
+		}
+		nv50_graph_construct_gene_m2mf (ctx);
+		switch (dev_priv->chipset) {
+		case 0x50:
+		case 0x84:
+		case 0x86:
+		case 0x98:
+			xf_emit(ctx, 0x4c4, 0);
+			break;
+		case 0x92:
+		case 0x94:
+		case 0x96:
+			xf_emit(ctx, 0x984, 0);
+			break;
+		}
+		nv50_graph_construct_gene_unk5(ctx);
+		if (dev_priv->chipset == 0x50)
+			xf_emit(ctx, 0xa, 0);
+		else
+			xf_emit(ctx, 0xb, 0);
+		nv50_graph_construct_gene_unk4(ctx);
+		nv50_graph_construct_gene_unk3(ctx);
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+
+		/* Strand 1 */
+		ctx->ctxvals_pos = offset + 0x1;
+		nv50_graph_construct_gene_unk6(ctx);
+		nv50_graph_construct_gene_unk7(ctx);
+		nv50_graph_construct_gene_unk8(ctx);
+		switch (dev_priv->chipset) {
+		case 0x50:
+		case 0x92:
+			xf_emit(ctx, 0xfb, 0);
+			break;
+		case 0x84:
+			xf_emit(ctx, 0xd3, 0);
+			break;
+		case 0x94:
+		case 0x96:
+			xf_emit(ctx, 0xab, 0);
+			break;
+		case 0x86:
+		case 0x98:
+			xf_emit(ctx, 0x6b, 0);
+			break;
+		}
+		xf_emit(ctx, 2, 0x4e3bfdf);
+		xf_emit(ctx, 4, 0);
+		xf_emit(ctx, 1, 0x0fac6881);
+		xf_emit(ctx, 0xb, 0);
+		xf_emit(ctx, 2, 0x4e3bfdf);
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+
+		/* Strand 2 */
+		ctx->ctxvals_pos = offset + 0x2;
+		switch (dev_priv->chipset) {
+		case 0x50:
+		case 0x92:
+			xf_emit(ctx, 0xa80, 0);
+			break;
+		case 0x84:
+			xf_emit(ctx, 0xa7e, 0);
+			break;
+		case 0x94:
+		case 0x96:
+			xf_emit(ctx, 0xa7c, 0);
+			break;
+		case 0x86:
+		case 0x98:
+			xf_emit(ctx, 0xa7a, 0);
+			break;
+		}
+		xf_emit(ctx, 1, 0x3fffff);
+		xf_emit(ctx, 2, 0);
+		xf_emit(ctx, 1, 0x1fff);
+		xf_emit(ctx, 0xe, 0);
+		nv50_graph_construct_gene_unk9(ctx);
+		nv50_graph_construct_gene_unk2(ctx);
+		nv50_graph_construct_gene_unk1(ctx);
+		nv50_graph_construct_gene_unk10(ctx);
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+
+		/* Strand 3: per-ROP group state */
+		ctx->ctxvals_pos = offset + 3;
+		for (i = 0; i < 6; i++)
+			if (units & (1 << (i + 16)))
+				nv50_graph_construct_gene_ropc(ctx);
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+
+		/* Strands 4-7: per-TP state */
+		for (i = 0; i < 4; i++) {
+			ctx->ctxvals_pos = offset + 4 + i;
+			if (units & (1 << (2 * i)))
+				nv50_graph_construct_xfer_tp(ctx);
+			if (units & (1 << (2 * i + 1)))
+				nv50_graph_construct_xfer_tp(ctx);
+			if ((ctx->ctxvals_pos-offset)/8 > size)
+				size = (ctx->ctxvals_pos-offset)/8;
+		}
+	} else {
+		/* Strand 0 */
+		ctx->ctxvals_pos = offset;
+		if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+			xf_emit(ctx, 0x385, 0);
+		else
+			xf_emit(ctx, 0x384, 0);
+		nv50_graph_construct_gene_m2mf(ctx);
+		xf_emit(ctx, 0x950, 0);
+		nv50_graph_construct_gene_unk10(ctx);
+		xf_emit(ctx, 1, 0x0fac6881);
+		if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) {
+			xf_emit(ctx, 1, 1);
+			xf_emit(ctx, 3, 0);
+		}
+		nv50_graph_construct_gene_unk8(ctx);
+		if (dev_priv->chipset == 0xa0)
+			xf_emit(ctx, 0x189, 0);
+		else if (dev_priv->chipset == 0xa3)
+			xf_emit(ctx, 0xd5, 0);
+		else if (dev_priv->chipset == 0xa5)
+			xf_emit(ctx, 0x99, 0);
+		else if (dev_priv->chipset == 0xaa)
+			xf_emit(ctx, 0x65, 0);
+		else
+			xf_emit(ctx, 0x6d, 0);
+		nv50_graph_construct_gene_unk9(ctx);
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+
+		/* Strand 1 */
+		ctx->ctxvals_pos = offset + 1;
+		nv50_graph_construct_gene_unk1(ctx);
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+
+		/* Strand 2 */
+		ctx->ctxvals_pos = offset + 2;
+		if (dev_priv->chipset == 0xa0) {
+			nv50_graph_construct_gene_unk2(ctx);
+		}
+		xf_emit(ctx, 0x36, 0);
+		nv50_graph_construct_gene_unk5(ctx);
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+
+		/* Strand 3 */
+		ctx->ctxvals_pos = offset + 3;
+		xf_emit(ctx, 1, 0);
+		xf_emit(ctx, 1, 1);
+		nv50_graph_construct_gene_unk6(ctx);
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+
+		/* Strand 4 */
+		ctx->ctxvals_pos = offset + 4;
+		if (dev_priv->chipset == 0xa0)
+			xf_emit(ctx, 0xa80, 0);
+		else if (dev_priv->chipset == 0xa3)
+			xf_emit(ctx, 0xa7c, 0);
+		else
+			xf_emit(ctx, 0xa7a, 0);
+		xf_emit(ctx, 1, 0x3fffff);
+		xf_emit(ctx, 2, 0);
+		xf_emit(ctx, 1, 0x1fff);
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+
+		/* Strand 5 */
+		ctx->ctxvals_pos = offset + 5;
+		xf_emit(ctx, 1, 0);
+		xf_emit(ctx, 1, 0x0fac6881);
+		xf_emit(ctx, 0xb, 0);
+		xf_emit(ctx, 2, 0x4e3bfdf);
+		xf_emit(ctx, 3, 0);
+		if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+			xf_emit(ctx, 1, 0x11);
+		xf_emit(ctx, 1, 0);
+		xf_emit(ctx, 2, 0x4e3bfdf);
+		xf_emit(ctx, 2, 0);
+		if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+			xf_emit(ctx, 1, 0x11);
+		xf_emit(ctx, 1, 0);
+		for (i = 0; i < 8; i++)
+			if (units & (1<<(i+16)))
+				nv50_graph_construct_gene_ropc(ctx);
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+
+		/* Strand 6 */
+		ctx->ctxvals_pos = offset + 6;
+		nv50_graph_construct_gene_unk3(ctx);
+		xf_emit(ctx, 0xb, 0);
+		nv50_graph_construct_gene_unk4(ctx);
+		nv50_graph_construct_gene_unk7(ctx);
+		if (units & (1 << 0))
+			nv50_graph_construct_xfer_tp(ctx);
+		if (units & (1 << 1))
+			nv50_graph_construct_xfer_tp(ctx);
+		if (units & (1 << 2))
+			nv50_graph_construct_xfer_tp(ctx);
+		if (units & (1 << 3))
+			nv50_graph_construct_xfer_tp(ctx);
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+
+		/* Strand 7 */
+		ctx->ctxvals_pos = offset + 7;
+		if (dev_priv->chipset == 0xa0) {
+			if (units & (1 << 4))
+				nv50_graph_construct_xfer_tp(ctx);
+			if (units & (1 << 5))
+				nv50_graph_construct_xfer_tp(ctx);
+			if (units & (1 << 6))
+				nv50_graph_construct_xfer_tp(ctx);
+			if (units & (1 << 7))
+				nv50_graph_construct_xfer_tp(ctx);
+			if (units & (1 << 8))
+				nv50_graph_construct_xfer_tp(ctx);
+			if (units & (1 << 9))
+				nv50_graph_construct_xfer_tp(ctx);
+		} else {
+			nv50_graph_construct_gene_unk2(ctx);
+		}
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+	}
+
+	ctx->ctxvals_pos = offset + size * 8;
+	ctx->ctxvals_pos = (ctx->ctxvals_pos+0x3f)&~0x3f;
+	cp_lsr (ctx, offset);
+	cp_out (ctx, CP_SET_XFER_POINTER);
+	cp_lsr (ctx, size);
+	cp_out (ctx, CP_SEEK_1);
+	cp_out (ctx, CP_XFER_1);
+	cp_wait(ctx, XFER, BUSY);
+}
+
+/*
+ * non-trivial demagiced parts of ctx init go here
+ */
+
+static void
+nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx)
+{
+	/* m2mf state */
+	xf_emit (ctx, 1, 0);		/* DMA_NOTIFY instance >> 4 */
+	xf_emit (ctx, 1, 0);		/* DMA_BUFFER_IN instance >> 4 */
+	xf_emit (ctx, 1, 0);		/* DMA_BUFFER_OUT instance >> 4 */
+	xf_emit (ctx, 1, 0);		/* OFFSET_IN */
+	xf_emit (ctx, 1, 0);		/* OFFSET_OUT */
+	xf_emit (ctx, 1, 0);		/* PITCH_IN */
+	xf_emit (ctx, 1, 0);		/* PITCH_OUT */
+	xf_emit (ctx, 1, 0);		/* LINE_LENGTH */
+	xf_emit (ctx, 1, 0);		/* LINE_COUNT */
+	xf_emit (ctx, 1, 0x21);		/* FORMAT: bits 0-4 INPUT_INC, bits 5-9 OUTPUT_INC */
+	xf_emit (ctx, 1, 1);		/* LINEAR_IN */
+	xf_emit (ctx, 1, 0x2);		/* TILING_MODE_IN: bits 0-2 y tiling, bits 3-5 z tiling */
+	xf_emit (ctx, 1, 0x100);	/* TILING_PITCH_IN */
+	xf_emit (ctx, 1, 0x100);	/* TILING_HEIGHT_IN */
+	xf_emit (ctx, 1, 1);		/* TILING_DEPTH_IN */
+	xf_emit (ctx, 1, 0);		/* TILING_POSITION_IN_Z */
+	xf_emit (ctx, 1, 0);		/* TILING_POSITION_IN */
+	xf_emit (ctx, 1, 1);		/* LINEAR_OUT */
+	xf_emit (ctx, 1, 0x2);		/* TILING_MODE_OUT: bits 0-2 y tiling, bits 3-5 z tiling */
+	xf_emit (ctx, 1, 0x100);	/* TILING_PITCH_OUT */
+	xf_emit (ctx, 1, 0x100);	/* TILING_HEIGHT_OUT */
+	xf_emit (ctx, 1, 1);		/* TILING_DEPTH_OUT */
+	xf_emit (ctx, 1, 0);		/* TILING_POSITION_OUT_Z */
+	xf_emit (ctx, 1, 0);		/* TILING_POSITION_OUT */
+	xf_emit (ctx, 1, 0);		/* OFFSET_IN_HIGH */
+	xf_emit (ctx, 1, 0);		/* OFFSET_OUT_HIGH */
+}
+
+static void
+nv50_graph_construct_gene_unk1(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	/* end of area 2 on pre-NVA0, area 1 on NVAx */
+	xf_emit(ctx, 2, 4);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x80);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 1, 0x80c14);
+	xf_emit(ctx, 1, 0);
+	if (dev_priv->chipset == 0x50)
+		xf_emit(ctx, 1, 0x3ff);
+	else
+		xf_emit(ctx, 1, 0x7ff);
+	switch (dev_priv->chipset) {
+	case 0x50:
+	case 0x86:
+	case 0x98:
+	case 0xaa:
+	case 0xac:
+		xf_emit(ctx, 0x542, 0);
+		break;
+	case 0x84:
+	case 0x92:
+	case 0x94:
+	case 0x96:
+		xf_emit(ctx, 0x942, 0);
+		break;
+	case 0xa0:
+	case 0xa3:
+		xf_emit(ctx, 0x2042, 0);
+		break;
+	case 0xa5:
+	case 0xa8:
+		xf_emit(ctx, 0x842, 0);
+		break;
+	}
+	xf_emit(ctx, 2, 4);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x80);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x27);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x26);
+	xf_emit(ctx, 3, 0);
+}
+
+static void
+nv50_graph_construct_gene_unk10(struct nouveau_grctx *ctx)
+{
+	/* end of area 2 on pre-NVA0, area 1 on NVAx */
+	xf_emit(ctx, 0x10, 0x04000000);
+	xf_emit(ctx, 0x24, 0);
+	xf_emit(ctx, 2, 0x04e3bfdf);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 0x1fe21);
+}
+
+static void
+nv50_graph_construct_gene_unk2(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	/* middle of area 2 on pre-NVA0, beginning of area 2 on NVA0, area 7 on >NVA0 */
+	if (dev_priv->chipset != 0x50) {
+		xf_emit(ctx, 5, 0);
+		xf_emit(ctx, 1, 0x80c14);
+		xf_emit(ctx, 2, 0);
+		xf_emit(ctx, 1, 0x804);
+		xf_emit(ctx, 1, 0);
+		xf_emit(ctx, 2, 4);
+		xf_emit(ctx, 1, 0x8100c12);
+	}
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 2, 4);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x10);
+	if (dev_priv->chipset == 0x50)
+		xf_emit(ctx, 3, 0);
+	else
+		xf_emit(ctx, 4, 0);
+	xf_emit(ctx, 1, 0x804);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0x1a);
+	if (dev_priv->chipset != 0x50)
+		xf_emit(ctx, 1, 0x7f);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0x80c14);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x8100c12);
+	xf_emit(ctx, 2, 4);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x10);
+	xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0x8100c12);
+	xf_emit(ctx, 6, 0);
+	if (dev_priv->chipset == 0x50)
+		xf_emit(ctx, 1, 0x3ff);
+	else
+		xf_emit(ctx, 1, 0x7ff);
+	xf_emit(ctx, 1, 0x80c14);
+	xf_emit(ctx, 0x38, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 0x10);
+	xf_emit(ctx, 0x38, 0);
+	xf_emit(ctx, 2, 0x88);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 0x16, 0);
+	xf_emit(ctx, 1, 0x26);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 0x3f800000);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 4, 0);
+	else
+		xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 0x1a);
+	xf_emit(ctx, 1, 0x10);
+	if (dev_priv->chipset != 0x50)
+		xf_emit(ctx, 0x28, 0);
+	else
+		xf_emit(ctx, 0x25, 0);
+	xf_emit(ctx, 1, 0x52);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x26);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 2, 4);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x1a);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 0x00ffff00);
+	xf_emit(ctx, 1, 0);
+}
+
+static void
+nv50_graph_construct_gene_unk3(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	/* end of area 0 on pre-NVA0, beginning of area 6 on NVAx */
+	xf_emit(ctx, 1, 0x3f);
+	xf_emit(ctx, 0xa, 0);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 2, 0x04000000);
+	xf_emit(ctx, 8, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 4);
+	if (dev_priv->chipset == 0x50)
+		xf_emit(ctx, 0x10, 0);
+	else
+		xf_emit(ctx, 0x11, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0x1001);
+	xf_emit(ctx, 4, 0xffff);
+	xf_emit(ctx, 0x20, 0);
+	xf_emit(ctx, 0x10, 0x3f800000);
+	xf_emit(ctx, 1, 0x10);
+	if (dev_priv->chipset == 0x50)
+		xf_emit(ctx, 1, 0);
+	else
+		xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 3);
+	xf_emit(ctx, 2, 0);
+}
+
+static void
+nv50_graph_construct_gene_unk4(struct nouveau_grctx *ctx)
+{
+	/* middle of area 0 on pre-NVA0, middle of area 6 on NVAx */
+	xf_emit(ctx, 2, 0x04000000);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x80);
+	xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 0x80);
+	xf_emit(ctx, 1, 0);
+}
+
+static void
+nv50_graph_construct_gene_unk5(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	/* middle of area 0 on pre-NVA0 [after m2mf], end of area 2 on NVAx */
+	xf_emit(ctx, 2, 4);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 0x1c4d, 0);
+	else
+		xf_emit(ctx, 0x1c4b, 0);
+	xf_emit(ctx, 2, 4);
+	xf_emit(ctx, 1, 0x8100c12);
+	if (dev_priv->chipset != 0x50)
+		xf_emit(ctx, 1, 3);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x8100c12);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x80c14);
+	xf_emit(ctx, 1, 1);
+	if (dev_priv->chipset >= 0xa0)
+		xf_emit(ctx, 2, 4);
+	xf_emit(ctx, 1, 0x80c14);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 0x8100c12);
+	xf_emit(ctx, 1, 0x27);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 0x3c1, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 0x16, 0);
+	xf_emit(ctx, 1, 0x8100c12);
+	xf_emit(ctx, 1, 0);
+}
+
+static void
+nv50_graph_construct_gene_unk6(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	/* beginning of area 1 on pre-NVA0 [after m2mf], area 3 on NVAx */
+	xf_emit(ctx, 4, 0);
+	xf_emit(ctx, 1, 0xf);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 8, 0);
+	else
+		xf_emit(ctx, 4, 0);
+	xf_emit(ctx, 1, 0x20);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 0x11, 0);
+	else if (dev_priv->chipset >= 0xa0)
+		xf_emit(ctx, 0xf, 0);
+	else
+		xf_emit(ctx, 0xe, 0);
+	xf_emit(ctx, 1, 0x1a);
+	xf_emit(ctx, 0xd, 0);
+	xf_emit(ctx, 2, 4);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 1, 8);
+	xf_emit(ctx, 1, 0);
+	if (dev_priv->chipset == 0x50)
+		xf_emit(ctx, 1, 0x3ff);
+	else
+		xf_emit(ctx, 1, 0x7ff);
+	if (dev_priv->chipset == 0xa8)
+		xf_emit(ctx, 1, 0x1e00);
+	xf_emit(ctx, 0xc, 0);
+	xf_emit(ctx, 1, 0xf);
+	if (dev_priv->chipset == 0x50)
+		xf_emit(ctx, 0x125, 0);
+	else if (dev_priv->chipset < 0xa0)
+		xf_emit(ctx, 0x126, 0);
+	else if (dev_priv->chipset == 0xa0 || dev_priv->chipset >= 0xaa)
+		xf_emit(ctx, 0x124, 0);
+	else
+		xf_emit(ctx, 0x1f7, 0);
+	xf_emit(ctx, 1, 0xf);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 3, 0);
+	else
+		xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 0xa1, 0);
+	else
+		xf_emit(ctx, 0x5a, 0);
+	xf_emit(ctx, 1, 0xf);
+	if (dev_priv->chipset < 0xa0)
+		xf_emit(ctx, 0x834, 0);
+	else if (dev_priv->chipset == 0xa0)
+		xf_emit(ctx, 0x1873, 0);
+	else if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 0x8ba, 0);
+	else
+		xf_emit(ctx, 0x833, 0);
+	xf_emit(ctx, 1, 0xf);
+	xf_emit(ctx, 0xf, 0);
+}
+
+static void
+nv50_graph_construct_gene_unk7(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	/* middle of area 1 on pre-NVA0 [after m2mf], middle of area 6 on NVAx */
+	xf_emit(ctx, 2, 0);
+	if (dev_priv->chipset == 0x50)
+		xf_emit(ctx, 2, 1);
+	else
+		xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 2, 0x100);
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 8);
+	xf_emit(ctx, 5, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 3, 1);
+	xf_emit(ctx, 1, 0xcf);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 6, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 3, 1);
+	xf_emit(ctx, 4, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0x15);
+	xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 0x4444480);
+	xf_emit(ctx, 0x37, 0);
+}
+
+static void
+nv50_graph_construct_gene_unk8(struct nouveau_grctx *ctx)
+{
+	/* middle of area 1 on pre-NVA0 [after m2mf], middle of area 0 on NVAx */
+	xf_emit(ctx, 4, 0);
+	xf_emit(ctx, 1, 0x8100c12);
+	xf_emit(ctx, 4, 0);
+	xf_emit(ctx, 1, 0x100);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 0x10001);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x10001);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0x10001);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 1, 2);
+}
+
+static void
+nv50_graph_construct_gene_unk9(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	/* middle of area 2 on pre-NVA0 [after m2mf], end of area 0 on NVAx */
+	xf_emit(ctx, 1, 0x3f800000);
+	xf_emit(ctx, 6, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 1, 0x1a);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 0x12, 0);
+	xf_emit(ctx, 1, 0x00ffff00);
+	xf_emit(ctx, 6, 0);
+	xf_emit(ctx, 1, 0xf);
+	xf_emit(ctx, 7, 0);
+	xf_emit(ctx, 1, 0x0fac6881);
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 0xf, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 2, 0);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 1, 3);
+	else if (dev_priv->chipset >= 0xa0)
+		xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 2, 0x04000000);
+	xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 5);
+	xf_emit(ctx, 1, 0x52);
+	if (dev_priv->chipset == 0x50) {
+		xf_emit(ctx, 0x13, 0);
+	} else {
+		xf_emit(ctx, 4, 0);
+		xf_emit(ctx, 1, 1);
+		if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+			xf_emit(ctx, 0x11, 0);
+		else
+			xf_emit(ctx, 0x10, 0);
+	}
+	xf_emit(ctx, 0x10, 0x3f800000);
+	xf_emit(ctx, 1, 0x10);
+	xf_emit(ctx, 0x26, 0);
+	xf_emit(ctx, 1, 0x8100c12);
+	xf_emit(ctx, 1, 5);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 4, 0xffff);
+	if (dev_priv->chipset != 0x50)
+		xf_emit(ctx, 1, 3);
+	if (dev_priv->chipset < 0xa0)
+		xf_emit(ctx, 0x1f, 0);
+	else if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 0xc, 0);
+	else
+		xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 0x00ffff00);
+	xf_emit(ctx, 1, 0x1a);
+	if (dev_priv->chipset != 0x50) {
+		xf_emit(ctx, 1, 0);
+		xf_emit(ctx, 1, 3);
+	}
+	if (dev_priv->chipset < 0xa0)
+		xf_emit(ctx, 0x26, 0);
+	else
+		xf_emit(ctx, 0x3c, 0);
+	xf_emit(ctx, 1, 0x102);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 4, 4);
+	if (dev_priv->chipset >= 0xa0)
+		xf_emit(ctx, 8, 0);
+	xf_emit(ctx, 2, 4);
+	xf_emit(ctx, 1, 0);
+	if (dev_priv->chipset == 0x50)
+		xf_emit(ctx, 1, 0x3ff);
+	else
+		xf_emit(ctx, 1, 0x7ff);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x102);
+	xf_emit(ctx, 9, 0);
+	xf_emit(ctx, 4, 4);
+	xf_emit(ctx, 0x2c, 0);
+}
+
+static void
+nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	int magic2;
+	if (dev_priv->chipset == 0x50) {
+		magic2 = 0x00003e60;
+	} else if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa) {
+		magic2 = 0x001ffe67;
+	} else {
+		magic2 = 0x00087e67;
+	}
+	xf_emit(ctx, 8, 0);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, magic2);
+	xf_emit(ctx, 4, 0);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 7, 0);
+	if (dev_priv->chipset >= 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 1, 0x15);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0x10);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 4, 0);
+	if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x92 || dev_priv->chipset == 0x98 || dev_priv->chipset >= 0xa0) {
+		xf_emit(ctx, 1, 4);
+		xf_emit(ctx, 1, 0x400);
+		xf_emit(ctx, 1, 0x300);
+		xf_emit(ctx, 1, 0x1001);
+		if (dev_priv->chipset != 0xa0) {
+			if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+				xf_emit(ctx, 1, 0);
+			else
+				xf_emit(ctx, 1, 0x15);
+		}
+		xf_emit(ctx, 3, 0);
+	}
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 8, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0x10);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 0x13, 0);
+	xf_emit(ctx, 1, 0x10);
+	xf_emit(ctx, 0x10, 0);
+	xf_emit(ctx, 0x10, 0x3f800000);
+	xf_emit(ctx, 0x19, 0);
+	xf_emit(ctx, 1, 0x10);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x3f);
+	xf_emit(ctx, 6, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	if (dev_priv->chipset >= 0xa0) {
+		xf_emit(ctx, 2, 0);
+		xf_emit(ctx, 1, 0x1001);
+		xf_emit(ctx, 0xb, 0);
+	} else {
+		xf_emit(ctx, 0xc, 0);
+	}
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 7, 0);
+	xf_emit(ctx, 1, 0xf);
+	xf_emit(ctx, 7, 0);
+	xf_emit(ctx, 1, 0x11);
+	if (dev_priv->chipset == 0x50)
+		xf_emit(ctx, 4, 0);
+	else
+		xf_emit(ctx, 6, 0);
+	xf_emit(ctx, 3, 1);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, magic2);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x0fac6881);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) {
+		xf_emit(ctx, 1, 0);
+		xf_emit(ctx, 0x18, 1);
+		xf_emit(ctx, 8, 2);
+		xf_emit(ctx, 8, 1);
+		xf_emit(ctx, 8, 2);
+		xf_emit(ctx, 8, 1);
+		xf_emit(ctx, 3, 0);
+		xf_emit(ctx, 1, 1);
+		xf_emit(ctx, 5, 0);
+		xf_emit(ctx, 1, 1);
+		xf_emit(ctx, 0x16, 0);
+	} else {
+		if (dev_priv->chipset >= 0xa0)
+			xf_emit(ctx, 0x1b, 0);
+		else
+			xf_emit(ctx, 0x15, 0);
+	}
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 2, 1);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 2, 1);
+	if (dev_priv->chipset >= 0xa0)
+		xf_emit(ctx, 4, 0);
+	else
+		xf_emit(ctx, 3, 0);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) {
+		xf_emit(ctx, 0x10, 1);
+		xf_emit(ctx, 8, 2);
+		xf_emit(ctx, 0x10, 1);
+		xf_emit(ctx, 8, 2);
+		xf_emit(ctx, 8, 1);
+		xf_emit(ctx, 3, 0);
+	}
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 0x5b, 0);
+}
+
+static void
+nv50_graph_construct_xfer_tp_x1(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	int magic3;
+	if (dev_priv->chipset == 0x50)
+		magic3 = 0x1000;
+	else if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x98 || dev_priv->chipset >= 0xa8)
+		magic3 = 0x1e00;
+	else
+		magic3 = 0;
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 4);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 0x24, 0);
+	else if (dev_priv->chipset >= 0xa0)
+		xf_emit(ctx, 0x14, 0);
+	else
+		xf_emit(ctx, 0x15, 0);
+	xf_emit(ctx, 2, 4);
+	if (dev_priv->chipset >= 0xa0)
+		xf_emit(ctx, 1, 0x03020100);
+	else
+		xf_emit(ctx, 1, 0x00608080);
+	xf_emit(ctx, 4, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 2, 4);
+	xf_emit(ctx, 1, 0x80);
+	if (magic3)
+		xf_emit(ctx, 1, magic3);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 0x24, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 1, 0x80);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 1, 0x03020100);
+	xf_emit(ctx, 1, 3);
+	if (magic3)
+		xf_emit(ctx, 1, magic3);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 4, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 1, 3);
+	xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 4);
+	if (dev_priv->chipset == 0x94 || dev_priv->chipset == 0x96)
+		xf_emit(ctx, 0x1024, 0);
+	else if (dev_priv->chipset < 0xa0)
+		xf_emit(ctx, 0xa24, 0);
+	else if (dev_priv->chipset == 0xa0 || dev_priv->chipset >= 0xaa)
+		xf_emit(ctx, 0x214, 0);
+	else
+		xf_emit(ctx, 0x414, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 1, 3);
+	xf_emit(ctx, 2, 0);
+}
+
+static void
+nv50_graph_construct_xfer_tp_x2(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	int magic1, magic2;
+	if (dev_priv->chipset == 0x50) {
+		magic1 = 0x3ff;
+		magic2 = 0x00003e60;
+	} else if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa) {
+		magic1 = 0x7ff;
+		magic2 = 0x001ffe67;
+	} else {
+		magic1 = 0x7ff;
+		magic2 = 0x00087e67;
+	}
+	xf_emit(ctx, 3, 0);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 0xc, 0);
+	xf_emit(ctx, 1, 0xf);
+	xf_emit(ctx, 0xb, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 4, 0xffff);
+	xf_emit(ctx, 8, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 5, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 2, 0);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) {
+		xf_emit(ctx, 1, 3);
+		xf_emit(ctx, 1, 0);
+	} else if (dev_priv->chipset >= 0xa0)
+		xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 0xa, 0);
+	xf_emit(ctx, 2, 1);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 2, 1);
+	xf_emit(ctx, 1, 2);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) {
+		xf_emit(ctx, 1, 0);
+		xf_emit(ctx, 0x18, 1);
+		xf_emit(ctx, 8, 2);
+		xf_emit(ctx, 8, 1);
+		xf_emit(ctx, 8, 2);
+		xf_emit(ctx, 8, 1);
+		xf_emit(ctx, 1, 0);
+	}
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 7, 0);
+	xf_emit(ctx, 1, 0x0fac6881);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 3, 0xcf);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 0xa, 0);
+	xf_emit(ctx, 2, 1);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 2, 1);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 8, 1);
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 7, 0);
+	xf_emit(ctx, 1, 0x0fac6881);
+	xf_emit(ctx, 1, 0xf);
+	xf_emit(ctx, 7, 0);
+	xf_emit(ctx, 1, magic2);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 0x11);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 2, 1);
+	else
+		xf_emit(ctx, 1, 1);
+	if(dev_priv->chipset == 0x50)
+		xf_emit(ctx, 1, 0);
+	else
+		xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 5, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 4, 0);
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 7, 0);
+	xf_emit(ctx, 1, 0x0fac6881);
+	xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, magic1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 2, 0);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 0x28, 0);
+	xf_emit(ctx, 8, 8);
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 7, 0);
+	xf_emit(ctx, 1, 0x0fac6881);
+	xf_emit(ctx, 8, 0x400);
+	xf_emit(ctx, 8, 0x300);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0xf);
+	xf_emit(ctx, 7, 0);
+	xf_emit(ctx, 1, 0x20);
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 1, 0x100);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 0x40);
+	xf_emit(ctx, 1, 0x100);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 3);
+	xf_emit(ctx, 4, 0);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, magic2);
+	xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 1, 0x0fac6881);
+	xf_emit(ctx, 9, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 4, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0x400);
+	xf_emit(ctx, 1, 0x300);
+	xf_emit(ctx, 1, 0x1001);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 4, 0);
+	else
+		xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 7, 0);
+	xf_emit(ctx, 1, 0x0fac6881);
+	xf_emit(ctx, 1, 0xf);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) {
+		xf_emit(ctx, 0x15, 0);
+		xf_emit(ctx, 1, 1);
+		xf_emit(ctx, 3, 0);
+	} else
+		xf_emit(ctx, 0x17, 0);
+	if (dev_priv->chipset >= 0xa0)
+		xf_emit(ctx, 1, 0x0fac6881);
+	xf_emit(ctx, 1, magic2);
+	xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 2, 1);
+	xf_emit(ctx, 3, 0);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 2, 1);
+	else
+		xf_emit(ctx, 1, 1);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 2, 0);
+	else if (dev_priv->chipset != 0x50)
+		xf_emit(ctx, 1, 0);
+}
+
+static void
+nv50_graph_construct_xfer_tp_x3(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	if (dev_priv->chipset == 0x50)
+		xf_emit(ctx, 2, 0);
+	else
+		xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 0x2a712488);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x4085c000);
+	xf_emit(ctx, 1, 0x40);
+	xf_emit(ctx, 1, 0x100);
+	xf_emit(ctx, 1, 0x10100);
+	xf_emit(ctx, 1, 0x02800000);
+}
+
+static void
+nv50_graph_construct_xfer_tp_x4(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	xf_emit(ctx, 2, 0x04e3bfdf);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x00ffff00);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 2, 1);
+	else
+		xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 0x00ffff00);
+	xf_emit(ctx, 8, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0x30201000);
+	xf_emit(ctx, 1, 0x70605040);
+	xf_emit(ctx, 1, 0xb8a89888);
+	xf_emit(ctx, 1, 0xf8e8d8c8);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x1a);
+}
+
+static void
+nv50_graph_construct_xfer_tp_x5(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 0xfac6881);
+	xf_emit(ctx, 4, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 2, 1);
+	xf_emit(ctx, 2, 0);
+	xf_emit(ctx, 1, 1);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 0xb, 0);
+	else
+		xf_emit(ctx, 0xa, 0);
+	xf_emit(ctx, 8, 1);
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 7, 0);
+	xf_emit(ctx, 1, 0xfac6881);
+	xf_emit(ctx, 1, 0xf);
+	xf_emit(ctx, 7, 0);
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 1, 1);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) {
+		xf_emit(ctx, 6, 0);
+		xf_emit(ctx, 1, 1);
+		xf_emit(ctx, 6, 0);
+	} else {
+		xf_emit(ctx, 0xb, 0);
+	}
+}
+
+static void
+nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	if (dev_priv->chipset < 0xa0) {
+		nv50_graph_construct_xfer_tp_x1(ctx);
+		nv50_graph_construct_xfer_tp_x2(ctx);
+		nv50_graph_construct_xfer_tp_x3(ctx);
+		if (dev_priv->chipset == 0x50)
+			xf_emit(ctx, 0xf, 0);
+		else
+			xf_emit(ctx, 0x12, 0);
+		nv50_graph_construct_xfer_tp_x4(ctx);
+	} else {
+		nv50_graph_construct_xfer_tp_x3(ctx);
+		if (dev_priv->chipset < 0xaa)
+			xf_emit(ctx, 0xc, 0);
+		else
+			xf_emit(ctx, 0xa, 0);
+		nv50_graph_construct_xfer_tp_x2(ctx);
+		nv50_graph_construct_xfer_tp_x5(ctx);
+		nv50_graph_construct_xfer_tp_x4(ctx);
+		nv50_graph_construct_xfer_tp_x1(ctx);
+	}
+}
+
+static void
+nv50_graph_construct_xfer_tp2(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	int i, mpcnt;
+	if (dev_priv->chipset == 0x98 || dev_priv->chipset == 0xaa)
+		mpcnt = 1;
+	else if (dev_priv->chipset < 0xa0 || dev_priv->chipset >= 0xa8)
+		mpcnt = 2;
+	else
+		mpcnt = 3;
+	for (i = 0; i < mpcnt; i++) {
+		xf_emit(ctx, 1, 0);
+		xf_emit(ctx, 1, 0x80);
+		xf_emit(ctx, 1, 0x80007004);
+		xf_emit(ctx, 1, 0x04000400);
+		if (dev_priv->chipset >= 0xa0)
+			xf_emit(ctx, 1, 0xc0);
+		xf_emit(ctx, 1, 0x1000);
+		xf_emit(ctx, 2, 0);
+		if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x98 || dev_priv->chipset >= 0xa8) {
+			xf_emit(ctx, 1, 0xe00);
+			xf_emit(ctx, 1, 0x1e00);
+		}
+		xf_emit(ctx, 1, 1);
+		xf_emit(ctx, 2, 0);
+		if (dev_priv->chipset == 0x50)
+			xf_emit(ctx, 2, 0x1000);
+		xf_emit(ctx, 1, 1);
+		xf_emit(ctx, 1, 0);
+		xf_emit(ctx, 1, 4);
+		xf_emit(ctx, 1, 2);
+		if (dev_priv->chipset >= 0xaa)
+			xf_emit(ctx, 0xb, 0);
+		else if (dev_priv->chipset >= 0xa0)
+			xf_emit(ctx, 0xc, 0);
+		else
+			xf_emit(ctx, 0xa, 0);
+	}
+	xf_emit(ctx, 1, 0x08100c12);
+	xf_emit(ctx, 1, 0);
+	if (dev_priv->chipset >= 0xa0) {
+		xf_emit(ctx, 1, 0x1fe21);
+	}
+	xf_emit(ctx, 5, 0);
+	xf_emit(ctx, 4, 0xffff);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 2, 0x10001);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 0x1fe21);
+	xf_emit(ctx, 1, 0);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 4, 0);
+	xf_emit(ctx, 1, 0x08100c12);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 8, 0);
+	xf_emit(ctx, 1, 0xfac6881);
+	xf_emit(ctx, 1, 0);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa)
+		xf_emit(ctx, 1, 3);
+	xf_emit(ctx, 3, 0);
+	xf_emit(ctx, 1, 4);
+	xf_emit(ctx, 9, 0);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 2, 1);
+	xf_emit(ctx, 1, 2);
+	xf_emit(ctx, 3, 1);
+	xf_emit(ctx, 1, 0);
+	if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) {
+		xf_emit(ctx, 8, 2);
+		xf_emit(ctx, 0x10, 1);
+		xf_emit(ctx, 8, 2);
+		xf_emit(ctx, 0x18, 1);
+		xf_emit(ctx, 3, 0);
+	}
+	xf_emit(ctx, 1, 4);
+	if (dev_priv->chipset == 0x50)
+		xf_emit(ctx, 0x3a0, 0);
+	else if (dev_priv->chipset < 0x94)
+		xf_emit(ctx, 0x3a2, 0);
+	else if (dev_priv->chipset == 0x98 || dev_priv->chipset == 0xaa)
+		xf_emit(ctx, 0x39f, 0);
+	else
+		xf_emit(ctx, 0x3a3, 0);
+	xf_emit(ctx, 1, 0x11);
+	xf_emit(ctx, 1, 0);
+	xf_emit(ctx, 1, 1);
+	xf_emit(ctx, 0x2d, 0);
+}
+
+static void
+nv50_graph_construct_xfer2(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	int i;
+	uint32_t offset;
+	uint32_t units = nv_rd32 (ctx->dev, 0x1540);
+	int size = 0;
+
+	offset = (ctx->ctxvals_pos+0x3f)&~0x3f;
+
+	if (dev_priv->chipset < 0xa0) {
+		for (i = 0; i < 8; i++) {
+			ctx->ctxvals_pos = offset + i;
+			if (i == 0)
+				xf_emit(ctx, 1, 0x08100c12);
+			if (units & (1 << i))
+				nv50_graph_construct_xfer_tp2(ctx);
+			if ((ctx->ctxvals_pos-offset)/8 > size)
+				size = (ctx->ctxvals_pos-offset)/8;
+		}
+	} else {
+		/* Strand 0: TPs 0, 1 */
+		ctx->ctxvals_pos = offset;
+		xf_emit(ctx, 1, 0x08100c12);
+		if (units & (1 << 0))
+			nv50_graph_construct_xfer_tp2(ctx);
+		if (units & (1 << 1))
+			nv50_graph_construct_xfer_tp2(ctx);
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+
+		/* Strand 0: TPs 2, 3 */
+		ctx->ctxvals_pos = offset + 1;
+		if (units & (1 << 2))
+			nv50_graph_construct_xfer_tp2(ctx);
+		if (units & (1 << 3))
+			nv50_graph_construct_xfer_tp2(ctx);
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+
+		/* Strand 0: TPs 4, 5, 6 */
+		ctx->ctxvals_pos = offset + 2;
+		if (units & (1 << 4))
+			nv50_graph_construct_xfer_tp2(ctx);
+		if (units & (1 << 5))
+			nv50_graph_construct_xfer_tp2(ctx);
+		if (units & (1 << 6))
+			nv50_graph_construct_xfer_tp2(ctx);
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+
+		/* Strand 0: TPs 7, 8, 9 */
+		ctx->ctxvals_pos = offset + 3;
+		if (units & (1 << 7))
+			nv50_graph_construct_xfer_tp2(ctx);
+		if (units & (1 << 8))
+			nv50_graph_construct_xfer_tp2(ctx);
+		if (units & (1 << 9))
+			nv50_graph_construct_xfer_tp2(ctx);
+		if ((ctx->ctxvals_pos-offset)/8 > size)
+			size = (ctx->ctxvals_pos-offset)/8;
+	}
+	ctx->ctxvals_pos = offset + size * 8;
+	ctx->ctxvals_pos = (ctx->ctxvals_pos+0x3f)&~0x3f;
+	cp_lsr (ctx, offset);
+	cp_out (ctx, CP_SET_XFER_POINTER);
+	cp_lsr (ctx, size);
+	cp_out (ctx, CP_SEEK_2);
+	cp_out (ctx, CP_XFER_2);
+	cp_wait(ctx, XFER, BUSY);
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_instmem.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_instmem.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_instmem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_instmem.c	2010-05-16 17:17:36.000000000 -0400
@@ -63,9 +63,10 @@ nv50_instmem_init(struct drm_device *dev
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_channel *chan;
 	uint32_t c_offset, c_size, c_ramfc, c_vmpd, c_base, pt_size;
+	uint32_t save_nv001700;
+	uint64_t v;
 	struct nv50_instmem_priv *priv;
 	int ret, i;
-	uint32_t v, save_nv001700;
 
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv)
@@ -76,17 +77,12 @@ nv50_instmem_init(struct drm_device *dev
 	for (i = 0x1700; i <= 0x1710; i += 4)
 		priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i);
 
-	if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
-		dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12;
-	else
-		dev_priv->vram_sys_base = 0;
-
 	/* Reserve the last MiB of VRAM, we should probably try to avoid
 	 * setting up the below tables over the top of the VBIOS image at
 	 * some point.
 	 */
 	dev_priv->ramin_rsvd_vram = 1 << 20;
-	c_offset = nouveau_mem_fb_amount(dev) - dev_priv->ramin_rsvd_vram;
+	c_offset = dev_priv->vram_size - dev_priv->ramin_rsvd_vram;
 	c_size   = 128 << 10;
 	c_vmpd   = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x1400 : 0x200;
 	c_ramfc  = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x0 : 0x20;
@@ -106,7 +102,7 @@ nv50_instmem_init(struct drm_device *dev
 	dev_priv->vm_gart_size = NV50_VM_BLOCK;
 
 	dev_priv->vm_vram_base = dev_priv->vm_gart_base + dev_priv->vm_gart_size;
-	dev_priv->vm_vram_size = nouveau_mem_fb_amount(dev);
+	dev_priv->vm_vram_size = dev_priv->vram_size;
 	if (dev_priv->vm_vram_size > NV50_VM_MAX_VRAM)
 		dev_priv->vm_vram_size = NV50_VM_MAX_VRAM;
 	dev_priv->vm_vram_size = roundup(dev_priv->vm_vram_size, NV50_VM_BLOCK);
@@ -189,8 +185,8 @@ nv50_instmem_init(struct drm_device *dev
 
 	i = 0;
 	while (v < dev_priv->vram_sys_base + c_offset + c_size) {
-		BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v);
-		BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000);
+		BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, lower_32_bits(v));
+		BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, upper_32_bits(v));
 		v += 0x1000;
 		i += 8;
 	}
@@ -390,7 +386,7 @@ nv50_instmem_populate(struct drm_device
 	if (gpuobj->im_backing)
 		return -EINVAL;
 
-	*sz = (*sz + (NV50_INSTMEM_PAGE_SIZE-1)) & ~(NV50_INSTMEM_PAGE_SIZE-1);
+	*sz = ALIGN(*sz, NV50_INSTMEM_PAGE_SIZE);
 	if (*sz == 0)
 		return -EINVAL;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_sor.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_sor.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_sor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/nouveau/nv50_sor.c	2010-05-16 17:17:36.000000000 -0400
@@ -211,7 +211,7 @@ nv50_sor_mode_set(struct drm_encoder *en
 			mode_ctl = 0x0200;
 		break;
 	case OUTPUT_DP:
-		mode_ctl |= 0x00050000;
+		mode_ctl |= (nv_encoder->dp.mc_unknown << 16);
 		if (nv_encoder->dcb->sorconf.link & 1)
 			mode_ctl |= 0x00000800;
 		else
@@ -274,6 +274,7 @@ static const struct drm_encoder_funcs nv
 int
 nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
 {
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_encoder *nv_encoder = NULL;
 	struct drm_encoder *encoder;
 	bool dum;
@@ -319,5 +320,27 @@ nv50_sor_create(struct drm_device *dev,
 	encoder->possible_crtcs = entry->heads;
 	encoder->possible_clones = 0;
 
+	if (nv_encoder->dcb->type == OUTPUT_DP) {
+		uint32_t mc, or = nv_encoder->or;
+
+		if (dev_priv->chipset < 0x90 ||
+		    dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0)
+			mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(or));
+		else
+			mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(or));
+
+		switch ((mc & 0x00000f00) >> 8) {
+		case 8:
+		case 9:
+			nv_encoder->dp.mc_unknown = (mc & 0x000f0000) >> 16;
+			break;
+		default:
+			break;
+		}
+
+		if (!nv_encoder->dp.mc_unknown)
+			nv_encoder->dp.mc_unknown = 5;
+	}
+
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/r128/r128_cce.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/r128/r128_cce.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/r128/r128_cce.c	2013-05-03 12:03:37.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/r128/r128_cce.c	2013-05-03 09:44:32.000000000 -0400
@@ -31,6 +31,7 @@
 
 #include <linux/firmware.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include "drmP.h"
 #include "drm.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atombios_crtc.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/atombios_crtc.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atombios_crtc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/atombios_crtc.c	2010-05-16 17:17:36.000000000 -0400
@@ -245,21 +245,25 @@ void atombios_crtc_dpms(struct drm_crtc
 
 	switch (mode) {
 	case DRM_MODE_DPMS_ON:
-		atombios_enable_crtc(crtc, 1);
+		atombios_enable_crtc(crtc, ATOM_ENABLE);
 		if (ASIC_IS_DCE3(rdev))
-			atombios_enable_crtc_memreq(crtc, 1);
-		atombios_blank_crtc(crtc, 0);
-		drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
+			atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
+		atombios_blank_crtc(crtc, ATOM_DISABLE);
+		/* XXX re-enable when interrupt support is added */
+		if (!ASIC_IS_DCE4(rdev))
+			drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
 		radeon_crtc_load_lut(crtc);
 		break;
 	case DRM_MODE_DPMS_STANDBY:
 	case DRM_MODE_DPMS_SUSPEND:
 	case DRM_MODE_DPMS_OFF:
-		drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
-		atombios_blank_crtc(crtc, 1);
+		/* XXX re-enable when interrupt support is added */
+		if (!ASIC_IS_DCE4(rdev))
+			drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
+		atombios_blank_crtc(crtc, ATOM_ENABLE);
 		if (ASIC_IS_DCE3(rdev))
-			atombios_enable_crtc_memreq(crtc, 0);
-		atombios_enable_crtc(crtc, 0);
+			atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
+		atombios_enable_crtc(crtc, ATOM_DISABLE);
 		break;
 	}
 }
@@ -349,7 +353,55 @@ static void atombios_crtc_set_timing(str
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
-static void atombios_set_ss(struct drm_crtc *crtc, int enable)
+static void atombios_disable_ss(struct drm_crtc *crtc)
+{
+	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	u32 ss_cntl;
+
+	if (ASIC_IS_DCE4(rdev)) {
+		switch (radeon_crtc->pll_id) {
+		case ATOM_PPLL1:
+			ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL);
+			ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
+			WREG32(EVERGREEN_P1PLL_SS_CNTL, ss_cntl);
+			break;
+		case ATOM_PPLL2:
+			ss_cntl = RREG32(EVERGREEN_P2PLL_SS_CNTL);
+			ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
+			WREG32(EVERGREEN_P2PLL_SS_CNTL, ss_cntl);
+			break;
+		case ATOM_DCPLL:
+		case ATOM_PPLL_INVALID:
+			return;
+		}
+	} else if (ASIC_IS_AVIVO(rdev)) {
+		switch (radeon_crtc->pll_id) {
+		case ATOM_PPLL1:
+			ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL);
+			ss_cntl &= ~1;
+			WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl);
+			break;
+		case ATOM_PPLL2:
+			ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL);
+			ss_cntl &= ~1;
+			WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl);
+			break;
+		case ATOM_DCPLL:
+		case ATOM_PPLL_INVALID:
+			return;
+		}
+	}
+}
+
+
+union atom_enable_ss {
+	ENABLE_LVDS_SS_PARAMETERS legacy;
+	ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;
+};
+
+static void atombios_enable_ss(struct drm_crtc *crtc)
 {
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
@@ -358,11 +410,14 @@ static void atombios_set_ss(struct drm_c
 	struct radeon_encoder *radeon_encoder = NULL;
 	struct radeon_encoder_atom_dig *dig = NULL;
 	int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
-	ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION args;
-	ENABLE_LVDS_SS_PARAMETERS legacy_args;
+	union atom_enable_ss args;
 	uint16_t percentage = 0;
 	uint8_t type = 0, step = 0, delay = 0, range = 0;
 
+	/* XXX add ss support for DCE4 */
+	if (ASIC_IS_DCE4(rdev))
+		return;
+
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 		if (encoder->crtc == crtc) {
 			radeon_encoder = to_radeon_encoder(encoder);
@@ -375,9 +430,9 @@ static void atombios_set_ss(struct drm_c
 					step = dig->ss->step;
 					delay = dig->ss->delay;
 					range = dig->ss->range;
-				} else if (enable)
+				} else
 					return;
-			} else if (enable)
+			} else
 				return;
 			break;
 		}
@@ -386,29 +441,28 @@ static void atombios_set_ss(struct drm_c
 	if (!radeon_encoder)
 		return;
 
+	memset(&args, 0, sizeof(args));
 	if (ASIC_IS_AVIVO(rdev)) {
-		memset(&args, 0, sizeof(args));
-		args.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
-		args.ucSpreadSpectrumType = type;
-		args.ucSpreadSpectrumStep = step;
-		args.ucSpreadSpectrumDelay = delay;
-		args.ucSpreadSpectrumRange = range;
-		args.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
-		args.ucEnable = enable;
-		atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+		args.v1.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
+		args.v1.ucSpreadSpectrumType = type;
+		args.v1.ucSpreadSpectrumStep = step;
+		args.v1.ucSpreadSpectrumDelay = delay;
+		args.v1.ucSpreadSpectrumRange = range;
+		args.v1.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
+		args.v1.ucEnable = ATOM_ENABLE;
 	} else {
-		memset(&legacy_args, 0, sizeof(legacy_args));
-		legacy_args.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
-		legacy_args.ucSpreadSpectrumType = type;
-		legacy_args.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2;
-		legacy_args.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4;
-		legacy_args.ucEnable = enable;
-		atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&legacy_args);
+		args.legacy.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
+		args.legacy.ucSpreadSpectrumType = type;
+		args.legacy.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2;
+		args.legacy.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4;
+		args.legacy.ucEnable = ATOM_ENABLE;
 	}
+	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
 union adjust_pixel_clock {
 	ADJUST_DISPLAY_PLL_PS_ALLOCATION v1;
+	ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3;
 };
 
 static u32 atombios_adjust_pll(struct drm_crtc *crtc,
@@ -420,10 +474,24 @@ static u32 atombios_adjust_pll(struct dr
 	struct drm_encoder *encoder = NULL;
 	struct radeon_encoder *radeon_encoder = NULL;
 	u32 adjusted_clock = mode->clock;
+	int encoder_mode = 0;
 
 	/* reset the pll flags */
 	pll->flags = 0;
 
+	/* select the PLL algo */
+	if (ASIC_IS_AVIVO(rdev)) {
+		if (radeon_new_pll == 0)
+			pll->algo = PLL_ALGO_LEGACY;
+		else
+			pll->algo = PLL_ALGO_NEW;
+	} else {
+		if (radeon_new_pll == 1)
+			pll->algo = PLL_ALGO_NEW;
+		else
+			pll->algo = PLL_ALGO_LEGACY;
+	}
+
 	if (ASIC_IS_AVIVO(rdev)) {
 		if ((rdev->family == CHIP_RS600) ||
 		    (rdev->family == CHIP_RS690) ||
@@ -448,10 +516,15 @@ static u32 atombios_adjust_pll(struct dr
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 		if (encoder->crtc == crtc) {
 			radeon_encoder = to_radeon_encoder(encoder);
+			encoder_mode = atombios_get_encoder_mode(encoder);
 			if (ASIC_IS_AVIVO(rdev)) {
 				/* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
 				if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
 					adjusted_clock = mode->clock * 2;
+				if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
+					pll->algo = PLL_ALGO_LEGACY;
+					pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
+				}
 			} else {
 				if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
 					pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
@@ -468,17 +541,13 @@ static u32 atombios_adjust_pll(struct dr
 	 */
 	if (ASIC_IS_DCE3(rdev)) {
 		union adjust_pixel_clock args;
-		struct radeon_encoder_atom_dig *dig;
 		u8 frev, crev;
 		int index;
 
-		if (!radeon_encoder->enc_priv)
-			return adjusted_clock;
-		dig = radeon_encoder->enc_priv;
-
 		index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
-		atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
-				      &crev);
+		if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
+					   &crev))
+			return adjusted_clock;
 
 		memset(&args, 0, sizeof(args));
 
@@ -489,12 +558,56 @@ static u32 atombios_adjust_pll(struct dr
 			case 2:
 				args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
 				args.v1.ucTransmitterID = radeon_encoder->encoder_id;
-				args.v1.ucEncodeMode = atombios_get_encoder_mode(encoder);
+				args.v1.ucEncodeMode = encoder_mode;
 
 				atom_execute_table(rdev->mode_info.atom_context,
 						   index, (uint32_t *)&args);
 				adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10;
 				break;
+			case 3:
+				args.v3.sInput.usPixelClock = cpu_to_le16(mode->clock / 10);
+				args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
+				args.v3.sInput.ucEncodeMode = encoder_mode;
+				args.v3.sInput.ucDispPllConfig = 0;
+				if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
+					struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+
+					if (encoder_mode == ATOM_ENCODER_MODE_DP)
+						args.v3.sInput.ucDispPllConfig |=
+							DISPPLL_CONFIG_COHERENT_MODE;
+					else {
+						if (dig->coherent_mode)
+							args.v3.sInput.ucDispPllConfig |=
+								DISPPLL_CONFIG_COHERENT_MODE;
+						if (mode->clock > 165000)
+							args.v3.sInput.ucDispPllConfig |=
+								DISPPLL_CONFIG_DUAL_LINK;
+					}
+				} else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+					/* may want to enable SS on DP/eDP eventually */
+					/*args.v3.sInput.ucDispPllConfig |=
+						DISPPLL_CONFIG_SS_ENABLE;*/
+					if (encoder_mode == ATOM_ENCODER_MODE_DP)
+						args.v3.sInput.ucDispPllConfig |=
+							DISPPLL_CONFIG_COHERENT_MODE;
+					else {
+						if (mode->clock > 165000)
+							args.v3.sInput.ucDispPllConfig |=
+								DISPPLL_CONFIG_DUAL_LINK;
+					}
+				}
+				atom_execute_table(rdev->mode_info.atom_context,
+						   index, (uint32_t *)&args);
+				adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
+				if (args.v3.sOutput.ucRefDiv) {
+					pll->flags |= RADEON_PLL_USE_REF_DIV;
+					pll->reference_div = args.v3.sOutput.ucRefDiv;
+				}
+				if (args.v3.sOutput.ucPostDiv) {
+					pll->flags |= RADEON_PLL_USE_POST_DIV;
+					pll->post_div = args.v3.sOutput.ucPostDiv;
+				}
+				break;
 			default:
 				DRM_ERROR("Unknown table version %d %d\n", frev, crev);
 				return adjusted_clock;
@@ -513,9 +626,48 @@ union set_pixel_clock {
 	PIXEL_CLOCK_PARAMETERS v1;
 	PIXEL_CLOCK_PARAMETERS_V2 v2;
 	PIXEL_CLOCK_PARAMETERS_V3 v3;
+	PIXEL_CLOCK_PARAMETERS_V5 v5;
 };
 
-void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
+static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	u8 frev, crev;
+	int index;
+	union set_pixel_clock args;
+
+	memset(&args, 0, sizeof(args));
+
+	index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
+	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
+				   &crev))
+		return;
+
+	switch (frev) {
+	case 1:
+		switch (crev) {
+		case 5:
+			/* if the default dcpll clock is specified,
+			 * SetPixelClock provides the dividers
+			 */
+			args.v5.ucCRTC = ATOM_CRTC_INVALID;
+			args.v5.usPixelClock = rdev->clock.default_dispclk;
+			args.v5.ucPpll = ATOM_DCPLL;
+			break;
+		default:
+			DRM_ERROR("Unknown table version %d %d\n", frev, crev);
+			return;
+		}
+		break;
+	default:
+		DRM_ERROR("Unknown table version %d %d\n", frev, crev);
+		return;
+	}
+	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
+static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
 {
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
@@ -529,12 +681,14 @@ void atombios_crtc_set_pll(struct drm_cr
 	u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
 	struct radeon_pll *pll;
 	u32 adjusted_clock;
+	int encoder_mode = 0;
 
 	memset(&args, 0, sizeof(args));
 
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 		if (encoder->crtc == crtc) {
 			radeon_encoder = to_radeon_encoder(encoder);
+			encoder_mode = atombios_get_encoder_mode(encoder);
 			break;
 		}
 	}
@@ -542,30 +696,29 @@ void atombios_crtc_set_pll(struct drm_cr
 	if (!radeon_encoder)
 		return;
 
-	if (radeon_crtc->crtc_id == 0)
+	switch (radeon_crtc->pll_id) {
+	case ATOM_PPLL1:
 		pll = &rdev->clock.p1pll;
-	else
+		break;
+	case ATOM_PPLL2:
 		pll = &rdev->clock.p2pll;
+		break;
+	case ATOM_DCPLL:
+	case ATOM_PPLL_INVALID:
+		pll = &rdev->clock.dcpll;
+		break;
+	}
 
 	/* adjust pixel clock as needed */
 	adjusted_clock = atombios_adjust_pll(crtc, mode, pll);
 
-	if (ASIC_IS_AVIVO(rdev)) {
-		if (radeon_new_pll)
-			radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock,
-						 &fb_div, &frac_fb_div,
-						 &ref_div, &post_div);
-		else
-			radeon_compute_pll(pll, adjusted_clock, &pll_clock,
-					   &fb_div, &frac_fb_div,
-					   &ref_div, &post_div);
-	} else
-		radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
-				   &ref_div, &post_div);
+	radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
+			   &ref_div, &post_div);
 
 	index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
-	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
-			      &crev);
+	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
+				   &crev))
+		return;
 
 	switch (frev) {
 	case 1:
@@ -576,8 +729,7 @@ void atombios_crtc_set_pll(struct drm_cr
 			args.v1.usFbDiv = cpu_to_le16(fb_div);
 			args.v1.ucFracFbDiv = frac_fb_div;
 			args.v1.ucPostDiv = post_div;
-			args.v1.ucPpll =
-			    radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
+			args.v1.ucPpll = radeon_crtc->pll_id;
 			args.v1.ucCRTC = radeon_crtc->crtc_id;
 			args.v1.ucRefDivSrc = 1;
 			break;
@@ -587,8 +739,7 @@ void atombios_crtc_set_pll(struct drm_cr
 			args.v2.usFbDiv = cpu_to_le16(fb_div);
 			args.v2.ucFracFbDiv = frac_fb_div;
 			args.v2.ucPostDiv = post_div;
-			args.v2.ucPpll =
-			    radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
+			args.v2.ucPpll = radeon_crtc->pll_id;
 			args.v2.ucCRTC = radeon_crtc->crtc_id;
 			args.v2.ucRefDivSrc = 1;
 			break;
@@ -598,12 +749,22 @@ void atombios_crtc_set_pll(struct drm_cr
 			args.v3.usFbDiv = cpu_to_le16(fb_div);
 			args.v3.ucFracFbDiv = frac_fb_div;
 			args.v3.ucPostDiv = post_div;
-			args.v3.ucPpll =
-			    radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
-			args.v3.ucMiscInfo = (radeon_crtc->crtc_id << 2);
+			args.v3.ucPpll = radeon_crtc->pll_id;
+			args.v3.ucMiscInfo = (radeon_crtc->pll_id << 2);
 			args.v3.ucTransmitterId = radeon_encoder->encoder_id;
-			args.v3.ucEncoderMode =
-			    atombios_get_encoder_mode(encoder);
+			args.v3.ucEncoderMode = encoder_mode;
+			break;
+		case 5:
+			args.v5.ucCRTC = radeon_crtc->crtc_id;
+			args.v5.usPixelClock = cpu_to_le16(mode->clock / 10);
+			args.v5.ucRefDiv = ref_div;
+			args.v5.usFbDiv = cpu_to_le16(fb_div);
+			args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
+			args.v5.ucPostDiv = post_div;
+			args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
+			args.v5.ucTransmitterID = radeon_encoder->encoder_id;
+			args.v5.ucEncoderMode = encoder_mode;
+			args.v5.ucPpll = radeon_crtc->pll_id;
 			break;
 		default:
 			DRM_ERROR("Unknown table version %d %d\n", frev, crev);
@@ -618,6 +779,140 @@ void atombios_crtc_set_pll(struct drm_cr
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
+static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y,
+				   struct drm_framebuffer *old_fb)
+{
+	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_framebuffer *radeon_fb;
+	struct drm_gem_object *obj;
+	struct radeon_bo *rbo;
+	uint64_t fb_location;
+	uint32_t fb_format, fb_pitch_pixels, tiling_flags;
+	int r;
+
+	/* no fb bound */
+	if (!crtc->fb) {
+		DRM_DEBUG("No FB bound\n");
+		return 0;
+	}
+
+	radeon_fb = to_radeon_framebuffer(crtc->fb);
+
+	/* Pin framebuffer & get tilling informations */
+	obj = radeon_fb->obj;
+	rbo = obj->driver_private;
+	r = radeon_bo_reserve(rbo, false);
+	if (unlikely(r != 0))
+		return r;
+	r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
+	if (unlikely(r != 0)) {
+		radeon_bo_unreserve(rbo);
+		return -EINVAL;
+	}
+	radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
+	radeon_bo_unreserve(rbo);
+
+	switch (crtc->fb->bits_per_pixel) {
+	case 8:
+		fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) |
+			     EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED));
+		break;
+	case 15:
+		fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
+			     EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555));
+		break;
+	case 16:
+		fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
+			     EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565));
+		break;
+	case 24:
+	case 32:
+		fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
+			     EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888));
+		break;
+	default:
+		DRM_ERROR("Unsupported screen depth %d\n",
+			  crtc->fb->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	switch (radeon_crtc->crtc_id) {
+	case 0:
+		WREG32(AVIVO_D1VGA_CONTROL, 0);
+		break;
+	case 1:
+		WREG32(AVIVO_D2VGA_CONTROL, 0);
+		break;
+	case 2:
+		WREG32(EVERGREEN_D3VGA_CONTROL, 0);
+		break;
+	case 3:
+		WREG32(EVERGREEN_D4VGA_CONTROL, 0);
+		break;
+	case 4:
+		WREG32(EVERGREEN_D5VGA_CONTROL, 0);
+		break;
+	case 5:
+		WREG32(EVERGREEN_D6VGA_CONTROL, 0);
+		break;
+	default:
+		break;
+	}
+
+	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
+	       upper_32_bits(fb_location));
+	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
+	       upper_32_bits(fb_location));
+	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
+	       (u32)fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
+	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
+	       (u32) fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
+	WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
+
+	WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
+	WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
+	WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0);
+	WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0);
+	WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width);
+	WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height);
+
+	fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8);
+	WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
+	WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
+
+	WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
+	       crtc->mode.vdisplay);
+	x &= ~3;
+	y &= ~1;
+	WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
+	       (x << 16) | y);
+	WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
+	       (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
+
+	if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
+		WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset,
+		       EVERGREEN_INTERLEAVE_EN);
+	else
+		WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
+
+	if (old_fb && old_fb != crtc->fb) {
+		radeon_fb = to_radeon_framebuffer(old_fb);
+		rbo = radeon_fb->obj->driver_private;
+		r = radeon_bo_reserve(rbo, false);
+		if (unlikely(r != 0))
+			return r;
+		radeon_bo_unpin(rbo);
+		radeon_bo_unreserve(rbo);
+	}
+
+	/* Bytes per pixel may have changed */
+	radeon_bandwidth_update(rdev);
+
+	return 0;
+}
+
 static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y,
 			       struct drm_framebuffer *old_fb)
 {
@@ -755,7 +1050,9 @@ int atombios_crtc_set_base(struct drm_cr
 	struct drm_device *dev = crtc->dev;
 	struct radeon_device *rdev = dev->dev_private;
 
-	if (ASIC_IS_AVIVO(rdev))
+	if (ASIC_IS_DCE4(rdev))
+		return evergreen_crtc_set_base(crtc, x, y, old_fb);
+	else if (ASIC_IS_AVIVO(rdev))
 		return avivo_crtc_set_base(crtc, x, y, old_fb);
 	else
 		return radeon_crtc_set_base(crtc, x, y, old_fb);
@@ -785,6 +1082,46 @@ static void radeon_legacy_atom_fixup(str
 	}
 }
 
+static int radeon_atom_pick_pll(struct drm_crtc *crtc)
+{
+	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct drm_encoder *test_encoder;
+	struct drm_crtc *test_crtc;
+	uint32_t pll_in_use = 0;
+
+	if (ASIC_IS_DCE4(rdev)) {
+		/* if crtc is driving DP and we have an ext clock, use that */
+		list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
+			if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
+				if (atombios_get_encoder_mode(test_encoder) == ATOM_ENCODER_MODE_DP) {
+					if (rdev->clock.dp_extclk)
+						return ATOM_PPLL_INVALID;
+				}
+			}
+		}
+
+		/* otherwise, pick one of the plls */
+		list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+			struct radeon_crtc *radeon_test_crtc;
+
+			if (crtc == test_crtc)
+				continue;
+
+			radeon_test_crtc = to_radeon_crtc(test_crtc);
+			if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) &&
+			    (radeon_test_crtc->pll_id <= ATOM_PPLL2))
+				pll_in_use |= (1 << radeon_test_crtc->pll_id);
+		}
+		if (!(pll_in_use & 1))
+			return ATOM_PPLL1;
+		return ATOM_PPLL2;
+	} else
+		return radeon_crtc->crtc_id;
+
+}
+
 int atombios_crtc_mode_set(struct drm_crtc *crtc,
 			   struct drm_display_mode *mode,
 			   struct drm_display_mode *adjusted_mode,
@@ -796,19 +1133,24 @@ int atombios_crtc_mode_set(struct drm_cr
 
 	/* TODO color tiling */
 
-	atombios_set_ss(crtc, 0);
+	atombios_disable_ss(crtc);
+	/* always set DCPLL */
+	if (ASIC_IS_DCE4(rdev))
+		atombios_crtc_set_dcpll(crtc);
 	atombios_crtc_set_pll(crtc, adjusted_mode);
-	atombios_set_ss(crtc, 1);
-	atombios_crtc_set_timing(crtc, adjusted_mode);
+	atombios_enable_ss(crtc);
 
-	if (ASIC_IS_AVIVO(rdev))
-		atombios_crtc_set_base(crtc, x, y, old_fb);
+	if (ASIC_IS_DCE4(rdev))
+		atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
+	else if (ASIC_IS_AVIVO(rdev))
+		atombios_crtc_set_timing(crtc, adjusted_mode);
 	else {
+		atombios_crtc_set_timing(crtc, adjusted_mode);
 		if (radeon_crtc->crtc_id == 0)
 			atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
-		atombios_crtc_set_base(crtc, x, y, old_fb);
 		radeon_legacy_atom_fixup(crtc);
 	}
+	atombios_crtc_set_base(crtc, x, y, old_fb);
 	atombios_overscan_setup(crtc, mode, adjusted_mode);
 	atombios_scaler_setup(crtc);
 	return 0;
@@ -825,14 +1167,19 @@ static bool atombios_crtc_mode_fixup(str
 
 static void atombios_crtc_prepare(struct drm_crtc *crtc)
 {
-	atombios_lock_crtc(crtc, 1);
+	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+
+	/* pick pll */
+	radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
+
+	atombios_lock_crtc(crtc, ATOM_ENABLE);
 	atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 }
 
 static void atombios_crtc_commit(struct drm_crtc *crtc)
 {
 	atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
-	atombios_lock_crtc(crtc, 0);
+	atombios_lock_crtc(crtc, ATOM_DISABLE);
 }
 
 static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
@@ -848,8 +1195,37 @@ static const struct drm_crtc_helper_func
 void radeon_atombios_init_crtc(struct drm_device *dev,
 			       struct radeon_crtc *radeon_crtc)
 {
-	if (radeon_crtc->crtc_id == 1)
-		radeon_crtc->crtc_offset =
-		    AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
+	struct radeon_device *rdev = dev->dev_private;
+
+	if (ASIC_IS_DCE4(rdev)) {
+		switch (radeon_crtc->crtc_id) {
+		case 0:
+		default:
+			radeon_crtc->crtc_offset = EVERGREEN_CRTC0_REGISTER_OFFSET;
+			break;
+		case 1:
+			radeon_crtc->crtc_offset = EVERGREEN_CRTC1_REGISTER_OFFSET;
+			break;
+		case 2:
+			radeon_crtc->crtc_offset = EVERGREEN_CRTC2_REGISTER_OFFSET;
+			break;
+		case 3:
+			radeon_crtc->crtc_offset = EVERGREEN_CRTC3_REGISTER_OFFSET;
+			break;
+		case 4:
+			radeon_crtc->crtc_offset = EVERGREEN_CRTC4_REGISTER_OFFSET;
+			break;
+		case 5:
+			radeon_crtc->crtc_offset = EVERGREEN_CRTC5_REGISTER_OFFSET;
+			break;
+		}
+	} else {
+		if (radeon_crtc->crtc_id == 1)
+			radeon_crtc->crtc_offset =
+				AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
+		else
+			radeon_crtc->crtc_offset = 0;
+	}
+	radeon_crtc->pll_id = -1;
 	drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atombios_dp.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/atombios_dp.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atombios_dp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/atombios_dp.c	2010-05-16 17:17:36.000000000 -0400
@@ -321,6 +321,10 @@ static void dp_get_adjust_train(u8 link_
 		train_set[lane] = v | p;
 }
 
+union aux_channel_transaction {
+	PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1;
+	PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2;
+};
 
 /* radeon aux chan functions */
 bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
@@ -329,7 +333,7 @@ bool radeon_process_aux_ch(struct radeon
 {
 	struct drm_device *dev = chan->dev;
 	struct radeon_device *rdev = dev->dev_private;
-	PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args;
+	union aux_channel_transaction args;
 	int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
 	unsigned char *base;
 	int retry_count = 0;
@@ -341,31 +345,33 @@ bool radeon_process_aux_ch(struct radeon
 retry:
 	memcpy(base, req_bytes, num_bytes);
 
-	args.lpAuxRequest = 0;
-	args.lpDataOut = 16;
-	args.ucDataOutLen = 0;
-	args.ucChannelID = chan->rec.i2c_id;
-	args.ucDelay = delay / 10;
+	args.v1.lpAuxRequest = 0;
+	args.v1.lpDataOut = 16;
+	args.v1.ucDataOutLen = 0;
+	args.v1.ucChannelID = chan->rec.i2c_id;
+	args.v1.ucDelay = delay / 10;
+	if (ASIC_IS_DCE4(rdev))
+		args.v2.ucHPD_ID = chan->rec.hpd_id;
 
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 
-	if (args.ucReplyStatus && !args.ucDataOutLen) {
-		if (args.ucReplyStatus == 0x20 && retry_count++ < 10)
+	if (args.v1.ucReplyStatus && !args.v1.ucDataOutLen) {
+		if (args.v1.ucReplyStatus == 0x20 && retry_count++ < 10)
 			goto retry;
 		DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n",
 			  req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3],
-			  chan->rec.i2c_id, args.ucReplyStatus, retry_count);
+			  chan->rec.i2c_id, args.v1.ucReplyStatus, retry_count);
 		return false;
 	}
 
-	if (args.ucDataOutLen && read_byte && read_buf_len) {
-		if (read_buf_len < args.ucDataOutLen) {
+	if (args.v1.ucDataOutLen && read_byte && read_buf_len) {
+		if (read_buf_len < args.v1.ucDataOutLen) {
 			DRM_ERROR("Buffer to small for return answer %d %d\n",
-				  read_buf_len, args.ucDataOutLen);
+				  read_buf_len, args.v1.ucDataOutLen);
 			return false;
 		}
 		{
-			int len = min(read_buf_len, args.ucDataOutLen);
+			int len = min(read_buf_len, args.v1.ucDataOutLen);
 			memcpy(read_byte, base + 16, len);
 		}
 	}
@@ -626,12 +632,19 @@ void dp_link_train(struct drm_encoder *e
 	dp_set_link_bw_lanes(radeon_connector, link_configuration);
 	/* disable downspread on the sink */
 	dp_set_downspread(radeon_connector, 0);
-	/* start training on the source */
-	radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START,
-				  dig_connector->dp_clock, enc_id, 0);
-	/* set training pattern 1 on the source */
-	radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
-				  dig_connector->dp_clock, enc_id, 0);
+	if (ASIC_IS_DCE4(rdev)) {
+		/* start training on the source */
+		atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_START);
+		/* set training pattern 1 on the source */
+		atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1);
+	} else {
+		/* start training on the source */
+		radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START,
+					  dig_connector->dp_clock, enc_id, 0);
+		/* set training pattern 1 on the source */
+		radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
+					  dig_connector->dp_clock, enc_id, 0);
+	}
 
 	/* set initial vs/emph */
 	memset(train_set, 0, 4);
@@ -691,8 +704,11 @@ void dp_link_train(struct drm_encoder *e
 	/* set training pattern 2 on the sink */
 	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2);
 	/* set training pattern 2 on the source */
-	radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
-				  dig_connector->dp_clock, enc_id, 1);
+	if (ASIC_IS_DCE4(rdev))
+		atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2);
+	else
+		radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
+					  dig_connector->dp_clock, enc_id, 1);
 
 	/* channel equalization loop */
 	tries = 0;
@@ -731,8 +747,12 @@ void dp_link_train(struct drm_encoder *e
 	/* disable the training pattern on the sink */
 	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE);
 
-	radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
-				  dig_connector->dp_clock, enc_id, 0);
+	/* disable the training pattern on the source */
+	if (ASIC_IS_DCE4(rdev))
+		atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE);
+	else
+		radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
+					  dig_connector->dp_clock, enc_id, 0);
 }
 
 int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atombios.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/atombios.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atombios.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/atombios.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2007 Advanced Micro Devices, Inc.
+ * Copyright 2006-2007 Advanced Micro Devices, Inc.  
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -20,10 +20,12 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 
-/****************************************************************************/
+
+/****************************************************************************/	
 /*Portion I: Definitions  shared between VBIOS and Driver                   */
 /****************************************************************************/
 
+
 #ifndef _ATOMBIOS_H
 #define _ATOMBIOS_H
 
@@ -40,39 +42,46 @@
 #endif
 
 #ifdef _H2INC
-#ifndef ULONG
-typedef unsigned long ULONG;
-#endif
+  #ifndef ULONG 
+    typedef unsigned long ULONG;
+  #endif
 
-#ifndef UCHAR
-typedef unsigned char UCHAR;
-#endif
+  #ifndef UCHAR
+    typedef unsigned char UCHAR;
+  #endif
 
-#ifndef USHORT
-typedef unsigned short USHORT;
-#endif
+  #ifndef USHORT 
+    typedef unsigned short USHORT;
+  #endif
 #endif
-
-#define ATOM_DAC_A            0
+      
+#define ATOM_DAC_A            0 
 #define ATOM_DAC_B            1
 #define ATOM_EXT_DAC          2
 
 #define ATOM_CRTC1            0
 #define ATOM_CRTC2            1
+#define ATOM_CRTC3            2
+#define ATOM_CRTC4            3
+#define ATOM_CRTC5            4
+#define ATOM_CRTC6            5
+#define ATOM_CRTC_INVALID     0xFF
 
 #define ATOM_DIGA             0
 #define ATOM_DIGB             1
 
 #define ATOM_PPLL1            0
 #define ATOM_PPLL2            1
+#define ATOM_DCPLL            2
+#define ATOM_PPLL_INVALID     0xFF
 
 #define ATOM_SCALER1          0
 #define ATOM_SCALER2          1
 
-#define ATOM_SCALER_DISABLE   0
-#define ATOM_SCALER_CENTER    1
-#define ATOM_SCALER_EXPANSION 2
-#define ATOM_SCALER_MULTI_EX  3
+#define ATOM_SCALER_DISABLE   0   
+#define ATOM_SCALER_CENTER    1   
+#define ATOM_SCALER_EXPANSION 2   
+#define ATOM_SCALER_MULTI_EX  3   
 
 #define ATOM_DISABLE          0
 #define ATOM_ENABLE           1
@@ -82,6 +91,7 @@ typedef unsigned short USHORT;
 #define ATOM_LCD_SELFTEST_START									(ATOM_DISABLE+5)
 #define ATOM_LCD_SELFTEST_STOP									(ATOM_ENABLE+5)
 #define ATOM_ENCODER_INIT			                  (ATOM_DISABLE+7)
+#define ATOM_GET_STATUS                         (ATOM_DISABLE+8)
 
 #define ATOM_BLANKING         1
 #define ATOM_BLANKING_OFF     0
@@ -114,7 +124,7 @@ typedef unsigned short USHORT;
 #define ATOM_DAC2_CV          ATOM_DAC1_CV
 #define ATOM_DAC2_NTSC        ATOM_DAC1_NTSC
 #define ATOM_DAC2_PAL         ATOM_DAC1_PAL
-
+ 
 #define ATOM_PM_ON            0
 #define ATOM_PM_STANDBY       1
 #define ATOM_PM_SUSPEND       2
@@ -134,6 +144,7 @@ typedef unsigned short USHORT;
 #define ATOM_PANEL_MISC_TEMPORAL           0x00000040
 #define ATOM_PANEL_MISC_API_ENABLED        0x00000080
 
+
 #define MEMTYPE_DDR1              "DDR1"
 #define MEMTYPE_DDR2              "DDR2"
 #define MEMTYPE_DDR3              "DDR3"
@@ -145,19 +156,19 @@ typedef unsigned short USHORT;
 
 /* Maximum size of that FireGL flag string */
 
-#define ATOM_FIREGL_FLAG_STRING     "FGL"	/* Flag used to enable FireGL Support */
-#define ATOM_MAX_SIZE_OF_FIREGL_FLAG_STRING  3	/* sizeof( ATOM_FIREGL_FLAG_STRING ) */
+#define ATOM_FIREGL_FLAG_STRING     "FGL"             //Flag used to enable FireGL Support
+#define ATOM_MAX_SIZE_OF_FIREGL_FLAG_STRING  3        //sizeof( ATOM_FIREGL_FLAG_STRING )
 
-#define ATOM_FAKE_DESKTOP_STRING    "DSK"	/* Flag used to enable mobile ASIC on Desktop */
-#define ATOM_MAX_SIZE_OF_FAKE_DESKTOP_STRING  ATOM_MAX_SIZE_OF_FIREGL_FLAG_STRING
+#define ATOM_FAKE_DESKTOP_STRING    "DSK"             //Flag used to enable mobile ASIC on Desktop
+#define ATOM_MAX_SIZE_OF_FAKE_DESKTOP_STRING  ATOM_MAX_SIZE_OF_FIREGL_FLAG_STRING 
 
-#define ATOM_M54T_FLAG_STRING       "M54T"	/* Flag used to enable M54T Support */
-#define ATOM_MAX_SIZE_OF_M54T_FLAG_STRING    4	/* sizeof( ATOM_M54T_FLAG_STRING ) */
+#define ATOM_M54T_FLAG_STRING       "M54T"            //Flag used to enable M54T Support
+#define ATOM_MAX_SIZE_OF_M54T_FLAG_STRING    4        //sizeof( ATOM_M54T_FLAG_STRING )
 
 #define HW_ASSISTED_I2C_STATUS_FAILURE          2
 #define HW_ASSISTED_I2C_STATUS_SUCCESS          1
 
-#pragma pack(1)			/* BIOS data must use byte aligment */
+#pragma pack(1)                                       /* BIOS data must use byte aligment */
 
 /*  Define offset to location of ROM header. */
 
@@ -165,367 +176,410 @@ typedef unsigned short USHORT;
 #define OFFSET_TO_ATOM_ROM_IMAGE_SIZE				    0x00000002L
 
 #define OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE    0x94
-#define MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE   20	/* including the terminator 0x0! */
+#define MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE   20    /* including the terminator 0x0! */
 #define	OFFSET_TO_GET_ATOMBIOS_STRINGS_NUMBER		0x002f
 #define	OFFSET_TO_GET_ATOMBIOS_STRINGS_START		0x006e
 
 /* Common header for all ROM Data tables.
-  Every table pointed  _ATOM_MASTER_DATA_TABLE has this common header.
+  Every table pointed  _ATOM_MASTER_DATA_TABLE has this common header. 
   And the pointer actually points to this header. */
 
-typedef struct _ATOM_COMMON_TABLE_HEADER {
-	USHORT usStructureSize;
-	UCHAR ucTableFormatRevision;	/*Change it when the Parser is not backward compatible */
-	UCHAR ucTableContentRevision;	/*Change it only when the table needs to change but the firmware */
-	/*Image can't be updated, while Driver needs to carry the new table! */
-} ATOM_COMMON_TABLE_HEADER;
+typedef struct _ATOM_COMMON_TABLE_HEADER
+{
+  USHORT usStructureSize;
+  UCHAR  ucTableFormatRevision;   /*Change it when the Parser is not backward compatible */
+  UCHAR  ucTableContentRevision;  /*Change it only when the table needs to change but the firmware */
+                                  /*Image can't be updated, while Driver needs to carry the new table! */
+}ATOM_COMMON_TABLE_HEADER;
 
-typedef struct _ATOM_ROM_HEADER {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	UCHAR uaFirmWareSignature[4];	/*Signature to distinguish between Atombios and non-atombios,
-					   atombios should init it as "ATOM", don't change the position */
-	USHORT usBiosRuntimeSegmentAddress;
-	USHORT usProtectedModeInfoOffset;
-	USHORT usConfigFilenameOffset;
-	USHORT usCRC_BlockOffset;
-	USHORT usBIOS_BootupMessageOffset;
-	USHORT usInt10Offset;
-	USHORT usPciBusDevInitCode;
-	USHORT usIoBaseAddress;
-	USHORT usSubsystemVendorID;
-	USHORT usSubsystemID;
-	USHORT usPCI_InfoOffset;
-	USHORT usMasterCommandTableOffset;	/*Offset for SW to get all command table offsets, Don't change the position */
-	USHORT usMasterDataTableOffset;	/*Offset for SW to get all data table offsets, Don't change the position */
-	UCHAR ucExtendedFunctionCode;
-	UCHAR ucReserved;
-} ATOM_ROM_HEADER;
+typedef struct _ATOM_ROM_HEADER
+{
+  ATOM_COMMON_TABLE_HEADER		sHeader;
+  UCHAR	 uaFirmWareSignature[4];    /*Signature to distinguish between Atombios and non-atombios, 
+                                      atombios should init it as "ATOM", don't change the position */
+  USHORT usBiosRuntimeSegmentAddress;
+  USHORT usProtectedModeInfoOffset;
+  USHORT usConfigFilenameOffset;
+  USHORT usCRC_BlockOffset;
+  USHORT usBIOS_BootupMessageOffset;
+  USHORT usInt10Offset;
+  USHORT usPciBusDevInitCode;
+  USHORT usIoBaseAddress;
+  USHORT usSubsystemVendorID;
+  USHORT usSubsystemID;
+  USHORT usPCI_InfoOffset; 
+  USHORT usMasterCommandTableOffset; /*Offset for SW to get all command table offsets, Don't change the position */
+  USHORT usMasterDataTableOffset;   /*Offset for SW to get all data table offsets, Don't change the position */
+  UCHAR  ucExtendedFunctionCode;
+  UCHAR  ucReserved;
+}ATOM_ROM_HEADER;
 
 /*==============================Command Table Portion==================================== */
 
 #ifdef	UEFI_BUILD
-#define	UTEMP	USHORT
-#define	USHORT	void*
+	#define	UTEMP	USHORT
+	#define	USHORT	void*
 #endif
 
-typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES {
-	USHORT ASIC_Init;	/* Function Table, used by various SW components,latest version 1.1 */
-	USHORT GetDisplaySurfaceSize;	/* Atomic Table,  Used by Bios when enabling HW ICON */
-	USHORT ASIC_RegistersInit;	/* Atomic Table,  indirectly used by various SW components,called from ASIC_Init */
-	USHORT VRAM_BlockVenderDetection;	/* Atomic Table,  used only by Bios */
-	USHORT DIGxEncoderControl;	/* Only used by Bios */
-	USHORT MemoryControllerInit;	/* Atomic Table,  indirectly used by various SW components,called from ASIC_Init */
-	USHORT EnableCRTCMemReq;	/* Function Table,directly used by various SW components,latest version 2.1 */
-	USHORT MemoryParamAdjust;	/* Atomic Table,  indirectly used by various SW components,called from SetMemoryClock if needed */
-	USHORT DVOEncoderControl;	/* Function Table,directly used by various SW components,latest version 1.2 */
-	USHORT GPIOPinControl;	/* Atomic Table,  only used by Bios */
-	USHORT SetEngineClock;	/*Function Table,directly used by various SW components,latest version 1.1 */
-	USHORT SetMemoryClock;	/* Function Table,directly used by various SW components,latest version 1.1 */
-	USHORT SetPixelClock;	/*Function Table,directly used by various SW components,latest version 1.2 */
-	USHORT DynamicClockGating;	/* Atomic Table,  indirectly used by various SW components,called from ASIC_Init */
-	USHORT ResetMemoryDLL;	/* Atomic Table,  indirectly used by various SW components,called from SetMemoryClock */
-	USHORT ResetMemoryDevice;	/* Atomic Table,  indirectly used by various SW components,called from SetMemoryClock */
-	USHORT MemoryPLLInit;
-	USHORT AdjustDisplayPll;	/* only used by Bios */
-	USHORT AdjustMemoryController;	/* Atomic Table,  indirectly used by various SW components,called from SetMemoryClock */
-	USHORT EnableASIC_StaticPwrMgt;	/* Atomic Table,  only used by Bios */
-	USHORT ASIC_StaticPwrMgtStatusChange;	/* Obsolete, only used by Bios */
-	USHORT DAC_LoadDetection;	/* Atomic Table,  directly used by various SW components,latest version 1.2 */
-	USHORT LVTMAEncoderControl;	/* Atomic Table,directly used by various SW components,latest version 1.3 */
-	USHORT LCD1OutputControl;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT DAC1EncoderControl;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT DAC2EncoderControl;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT DVOOutputControl;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT CV1OutputControl;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT GetConditionalGoldenSetting;	/* only used by Bios */
-	USHORT TVEncoderControl;	/* Function Table,directly used by various SW components,latest version 1.1 */
-	USHORT TMDSAEncoderControl;	/* Atomic Table,  directly used by various SW components,latest version 1.3 */
-	USHORT LVDSEncoderControl;	/* Atomic Table,  directly used by various SW components,latest version 1.3 */
-	USHORT TV1OutputControl;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT EnableScaler;	/* Atomic Table,  used only by Bios */
-	USHORT BlankCRTC;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT EnableCRTC;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT GetPixelClock;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT EnableVGA_Render;	/* Function Table,directly used by various SW components,latest version 1.1 */
-	USHORT EnableVGA_Access;	/* Obsolete ,     only used by Bios */
-	USHORT SetCRTC_Timing;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT SetCRTC_OverScan;	/* Atomic Table,  used by various SW components,latest version 1.1 */
-	USHORT SetCRTC_Replication;	/* Atomic Table,  used only by Bios */
-	USHORT SelectCRTC_Source;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT EnableGraphSurfaces;	/* Atomic Table,  used only by Bios */
-	USHORT UpdateCRTC_DoubleBufferRegisters;
-	USHORT LUT_AutoFill;	/* Atomic Table,  only used by Bios */
-	USHORT EnableHW_IconCursor;	/* Atomic Table,  only used by Bios */
-	USHORT GetMemoryClock;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT GetEngineClock;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT SetCRTC_UsingDTDTiming;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT ExternalEncoderControl;	/* Atomic Table,  directly used by various SW components,latest version 2.1 */
-	USHORT LVTMAOutputControl;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT VRAM_BlockDetectionByStrap;	/* Atomic Table,  used only by Bios */
-	USHORT MemoryCleanUp;	/* Atomic Table,  only used by Bios */
-	USHORT ProcessI2cChannelTransaction;	/* Function Table,only used by Bios */
-	USHORT WriteOneByteToHWAssistedI2C;	/* Function Table,indirectly used by various SW components */
-	USHORT ReadHWAssistedI2CStatus;	/* Atomic Table,  indirectly used by various SW components */
-	USHORT SpeedFanControl;	/* Function Table,indirectly used by various SW components,called from ASIC_Init */
-	USHORT PowerConnectorDetection;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT MC_Synchronization;	/* Atomic Table,  indirectly used by various SW components,called from SetMemoryClock */
-	USHORT ComputeMemoryEnginePLL;	/* Atomic Table,  indirectly used by various SW components,called from SetMemory/EngineClock */
-	USHORT MemoryRefreshConversion;	/* Atomic Table,  indirectly used by various SW components,called from SetMemory or SetEngineClock */
-	USHORT VRAM_GetCurrentInfoBlock;	/* Atomic Table,  used only by Bios */
-	USHORT DynamicMemorySettings;	/* Atomic Table,  indirectly used by various SW components,called from SetMemoryClock */
-	USHORT MemoryTraining;	/* Atomic Table,  used only by Bios */
-	USHORT EnableSpreadSpectrumOnPPLL;	/* Atomic Table,  directly used by various SW components,latest version 1.2 */
-	USHORT TMDSAOutputControl;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT SetVoltage;	/* Function Table,directly and/or indirectly used by various SW components,latest version 1.1 */
-	USHORT DAC1OutputControl;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT DAC2OutputControl;	/* Atomic Table,  directly used by various SW components,latest version 1.1 */
-	USHORT SetupHWAssistedI2CStatus;	/* Function Table,only used by Bios, obsolete soon.Switch to use "ReadEDIDFromHWAssistedI2C" */
-	USHORT ClockSource;	/* Atomic Table,  indirectly used by various SW components,called from ASIC_Init */
-	USHORT MemoryDeviceInit;	/* Atomic Table,  indirectly used by various SW components,called from SetMemoryClock */
-	USHORT EnableYUV;	/* Atomic Table,  indirectly used by various SW components,called from EnableVGARender */
-	USHORT DIG1EncoderControl;	/* Atomic Table,directly used by various SW components,latest version 1.1 */
-	USHORT DIG2EncoderControl;	/* Atomic Table,directly used by various SW components,latest version 1.1 */
-	USHORT DIG1TransmitterControl;	/* Atomic Table,directly used by various SW components,latest version 1.1 */
-	USHORT DIG2TransmitterControl;	/* Atomic Table,directly used by various SW components,latest version 1.1 */
-	USHORT ProcessAuxChannelTransaction;	/* Function Table,only used by Bios */
-	USHORT DPEncoderService;	/* Function Table,only used by Bios */
-} ATOM_MASTER_LIST_OF_COMMAND_TABLES;
+typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{
+  USHORT ASIC_Init;                              //Function Table, used by various SW components,latest version 1.1
+  USHORT GetDisplaySurfaceSize;                  //Atomic Table,  Used by Bios when enabling HW ICON
+  USHORT ASIC_RegistersInit;                     //Atomic Table,  indirectly used by various SW components,called from ASIC_Init
+  USHORT VRAM_BlockVenderDetection;              //Atomic Table,  used only by Bios
+  USHORT DIGxEncoderControl;										 //Only used by Bios
+  USHORT MemoryControllerInit;                   //Atomic Table,  indirectly used by various SW components,called from ASIC_Init
+  USHORT EnableCRTCMemReq;                       //Function Table,directly used by various SW components,latest version 2.1
+  USHORT MemoryParamAdjust; 										 //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock if needed
+  USHORT DVOEncoderControl;                      //Function Table,directly used by various SW components,latest version 1.2
+  USHORT GPIOPinControl;												 //Atomic Table,  only used by Bios
+  USHORT SetEngineClock;                         //Function Table,directly used by various SW components,latest version 1.1
+  USHORT SetMemoryClock;                         //Function Table,directly used by various SW components,latest version 1.1
+  USHORT SetPixelClock;                          //Function Table,directly used by various SW components,latest version 1.2  
+  USHORT DynamicClockGating;                     //Atomic Table,  indirectly used by various SW components,called from ASIC_Init
+  USHORT ResetMemoryDLL;                         //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock
+  USHORT ResetMemoryDevice;                      //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock
+  USHORT MemoryPLLInit;
+  USHORT AdjustDisplayPll;												//only used by Bios
+  USHORT AdjustMemoryController;                 //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock                
+  USHORT EnableASIC_StaticPwrMgt;                //Atomic Table,  only used by Bios
+  USHORT ASIC_StaticPwrMgtStatusChange;          //Obsolete ,     only used by Bios   
+  USHORT DAC_LoadDetection;                      //Atomic Table,  directly used by various SW components,latest version 1.2  
+  USHORT LVTMAEncoderControl;                    //Atomic Table,directly used by various SW components,latest version 1.3
+  USHORT LCD1OutputControl;                      //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT DAC1EncoderControl;                     //Atomic Table,  directly used by various SW components,latest version 1.1  
+  USHORT DAC2EncoderControl;                     //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT DVOOutputControl;                       //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT CV1OutputControl;                       //Atomic Table,  Atomic Table,  Obsolete from Ry6xx, use DAC2 Output instead 
+  USHORT GetConditionalGoldenSetting;            //only used by Bios
+  USHORT TVEncoderControl;                       //Function Table,directly used by various SW components,latest version 1.1
+  USHORT TMDSAEncoderControl;                    //Atomic Table,  directly used by various SW components,latest version 1.3
+  USHORT LVDSEncoderControl;                     //Atomic Table,  directly used by various SW components,latest version 1.3
+  USHORT TV1OutputControl;                       //Atomic Table,  Obsolete from Ry6xx, use DAC2 Output instead
+  USHORT EnableScaler;                           //Atomic Table,  used only by Bios
+  USHORT BlankCRTC;                              //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT EnableCRTC;                             //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT GetPixelClock;                          //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT EnableVGA_Render;                       //Function Table,directly used by various SW components,latest version 1.1
+  USHORT GetSCLKOverMCLKRatio;                   //Atomic Table,  only used by Bios
+  USHORT SetCRTC_Timing;                         //Atomic Table,  directly used by various SW components,latest version 1.1
+  USHORT SetCRTC_OverScan;                       //Atomic Table,  used by various SW components,latest version 1.1 
+  USHORT SetCRTC_Replication;                    //Atomic Table,  used only by Bios
+  USHORT SelectCRTC_Source;                      //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT EnableGraphSurfaces;                    //Atomic Table,  used only by Bios
+  USHORT UpdateCRTC_DoubleBufferRegisters;
+  USHORT LUT_AutoFill;                           //Atomic Table,  only used by Bios
+  USHORT EnableHW_IconCursor;                    //Atomic Table,  only used by Bios
+  USHORT GetMemoryClock;                         //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT GetEngineClock;                         //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT SetCRTC_UsingDTDTiming;                 //Atomic Table,  directly used by various SW components,latest version 1.1
+  USHORT ExternalEncoderControl;                 //Atomic Table,  directly used by various SW components,latest version 2.1
+  USHORT LVTMAOutputControl;                     //Atomic Table,  directly used by various SW components,latest version 1.1
+  USHORT VRAM_BlockDetectionByStrap;             //Atomic Table,  used only by Bios
+  USHORT MemoryCleanUp;                          //Atomic Table,  only used by Bios    
+  USHORT ProcessI2cChannelTransaction;           //Function Table,only used by Bios
+  USHORT WriteOneByteToHWAssistedI2C;            //Function Table,indirectly used by various SW components 
+  USHORT ReadHWAssistedI2CStatus;                //Atomic Table,  indirectly used by various SW components
+  USHORT SpeedFanControl;                        //Function Table,indirectly used by various SW components,called from ASIC_Init
+  USHORT PowerConnectorDetection;                //Atomic Table,  directly used by various SW components,latest version 1.1
+  USHORT MC_Synchronization;                     //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock
+  USHORT ComputeMemoryEnginePLL;                 //Atomic Table,  indirectly used by various SW components,called from SetMemory/EngineClock
+  USHORT MemoryRefreshConversion;                //Atomic Table,  indirectly used by various SW components,called from SetMemory or SetEngineClock
+  USHORT VRAM_GetCurrentInfoBlock;               //Atomic Table,  used only by Bios
+  USHORT DynamicMemorySettings;                  //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock
+  USHORT MemoryTraining;                         //Atomic Table,  used only by Bios
+  USHORT EnableSpreadSpectrumOnPPLL;             //Atomic Table,  directly used by various SW components,latest version 1.2
+  USHORT TMDSAOutputControl;                     //Atomic Table,  directly used by various SW components,latest version 1.1
+  USHORT SetVoltage;                             //Function Table,directly and/or indirectly used by various SW components,latest version 1.1
+  USHORT DAC1OutputControl;                      //Atomic Table,  directly used by various SW components,latest version 1.1
+  USHORT DAC2OutputControl;                      //Atomic Table,  directly used by various SW components,latest version 1.1
+  USHORT SetupHWAssistedI2CStatus;               //Function Table,only used by Bios, obsolete soon.Switch to use "ReadEDIDFromHWAssistedI2C"
+  USHORT ClockSource;                            //Atomic Table,  indirectly used by various SW components,called from ASIC_Init
+  USHORT MemoryDeviceInit;                       //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock
+  USHORT EnableYUV;                              //Atomic Table,  indirectly used by various SW components,called from EnableVGARender
+  USHORT DIG1EncoderControl;                     //Atomic Table,directly used by various SW components,latest version 1.1
+  USHORT DIG2EncoderControl;                     //Atomic Table,directly used by various SW components,latest version 1.1
+  USHORT DIG1TransmitterControl;                 //Atomic Table,directly used by various SW components,latest version 1.1
+  USHORT DIG2TransmitterControl;	               //Atomic Table,directly used by various SW components,latest version 1.1 
+  USHORT ProcessAuxChannelTransaction;					 //Function Table,only used by Bios
+  USHORT DPEncoderService;											 //Function Table,only used by Bios
+}ATOM_MASTER_LIST_OF_COMMAND_TABLES;   
 
-/*  For backward compatible */
+// For backward compatible 
 #define ReadEDIDFromHWAssistedI2C                ProcessI2cChannelTransaction
 #define UNIPHYTransmitterControl						     DIG1TransmitterControl
 #define LVTMATransmitterControl							     DIG2TransmitterControl
 #define SetCRTC_DPM_State                        GetConditionalGoldenSetting
 #define SetUniphyInstance                        ASIC_StaticPwrMgtStatusChange
+#define HPDInterruptService                      ReadHWAssistedI2CStatus
+#define EnableVGA_Access                         GetSCLKOverMCLKRatio
 
-typedef struct _ATOM_MASTER_COMMAND_TABLE {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ATOM_MASTER_LIST_OF_COMMAND_TABLES ListOfCommandTables;
-} ATOM_MASTER_COMMAND_TABLE;
+typedef struct _ATOM_MASTER_COMMAND_TABLE
+{
+  ATOM_COMMON_TABLE_HEADER           sHeader;
+  ATOM_MASTER_LIST_OF_COMMAND_TABLES ListOfCommandTables;
+}ATOM_MASTER_COMMAND_TABLE;
 
-/****************************************************************************/
-/*  Structures used in every command table */
-/****************************************************************************/
-typedef struct _ATOM_TABLE_ATTRIBUTE {
+/****************************************************************************/	
+// Structures used in every command table
+/****************************************************************************/	
+typedef struct _ATOM_TABLE_ATTRIBUTE
+{
 #if ATOM_BIG_ENDIAN
-	USHORT UpdatedByUtility:1;	/* [15]=Table updated by utility flag */
-	USHORT PS_SizeInBytes:7;	/* [14:8]=Size of parameter space in Bytes (multiple of a dword), */
-	USHORT WS_SizeInBytes:8;	/* [7:0]=Size of workspace in Bytes (in multiple of a dword), */
+  USHORT  UpdatedByUtility:1;         //[15]=Table updated by utility flag
+  USHORT  PS_SizeInBytes:7;           //[14:8]=Size of parameter space in Bytes (multiple of a dword), 
+  USHORT  WS_SizeInBytes:8;           //[7:0]=Size of workspace in Bytes (in multiple of a dword), 
 #else
-	USHORT WS_SizeInBytes:8;	/* [7:0]=Size of workspace in Bytes (in multiple of a dword), */
-	USHORT PS_SizeInBytes:7;	/* [14:8]=Size of parameter space in Bytes (multiple of a dword), */
-	USHORT UpdatedByUtility:1;	/* [15]=Table updated by utility flag */
+  USHORT  WS_SizeInBytes:8;           //[7:0]=Size of workspace in Bytes (in multiple of a dword), 
+  USHORT  PS_SizeInBytes:7;           //[14:8]=Size of parameter space in Bytes (multiple of a dword), 
+  USHORT  UpdatedByUtility:1;         //[15]=Table updated by utility flag
 #endif
-} ATOM_TABLE_ATTRIBUTE;
+}ATOM_TABLE_ATTRIBUTE;
 
-typedef union _ATOM_TABLE_ATTRIBUTE_ACCESS {
-	ATOM_TABLE_ATTRIBUTE sbfAccess;
-	USHORT susAccess;
-} ATOM_TABLE_ATTRIBUTE_ACCESS;
+typedef union _ATOM_TABLE_ATTRIBUTE_ACCESS
+{
+  ATOM_TABLE_ATTRIBUTE sbfAccess;
+  USHORT               susAccess;
+}ATOM_TABLE_ATTRIBUTE_ACCESS;
 
-/****************************************************************************/
-/*  Common header for all command tables. */
-/*  Every table pointed by _ATOM_MASTER_COMMAND_TABLE has this common header. */
-/*  And the pointer actually points to this header. */
-/****************************************************************************/
-typedef struct _ATOM_COMMON_ROM_COMMAND_TABLE_HEADER {
-	ATOM_COMMON_TABLE_HEADER CommonHeader;
-	ATOM_TABLE_ATTRIBUTE TableAttribute;
-} ATOM_COMMON_ROM_COMMAND_TABLE_HEADER;
+/****************************************************************************/	
+// Common header for all command tables.
+// Every table pointed by _ATOM_MASTER_COMMAND_TABLE has this common header. 
+// And the pointer actually points to this header.
+/****************************************************************************/	
+typedef struct _ATOM_COMMON_ROM_COMMAND_TABLE_HEADER
+{
+  ATOM_COMMON_TABLE_HEADER CommonHeader;
+  ATOM_TABLE_ATTRIBUTE     TableAttribute;	
+}ATOM_COMMON_ROM_COMMAND_TABLE_HEADER;
 
-/****************************************************************************/
-/*  Structures used by ComputeMemoryEnginePLLTable */
-/****************************************************************************/
+/****************************************************************************/	
+// Structures used by ComputeMemoryEnginePLLTable
+/****************************************************************************/	
 #define COMPUTE_MEMORY_PLL_PARAM        1
 #define COMPUTE_ENGINE_PLL_PARAM        2
 
-typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS {
-	ULONG ulClock;		/* When returen, it's the re-calculated clock based on given Fb_div Post_Div and ref_div */
-	UCHAR ucAction;		/* 0:reserved //1:Memory //2:Engine */
-	UCHAR ucReserved;	/* may expand to return larger Fbdiv later */
-	UCHAR ucFbDiv;		/* return value */
-	UCHAR ucPostDiv;	/* return value */
-} COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS;
+typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS
+{
+  ULONG   ulClock;        //When returen, it's the re-calculated clock based on given Fb_div Post_Div and ref_div
+  UCHAR   ucAction;       //0:reserved //1:Memory //2:Engine  
+  UCHAR   ucReserved;     //may expand to return larger Fbdiv later
+  UCHAR   ucFbDiv;        //return value
+  UCHAR   ucPostDiv;      //return value
+}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS;
 
-typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 {
-	ULONG ulClock;		/* When return, [23:0] return real clock */
-	UCHAR ucAction;		/* 0:reserved;COMPUTE_MEMORY_PLL_PARAM:Memory;COMPUTE_ENGINE_PLL_PARAM:Engine. it return ref_div to be written to register */
-	USHORT usFbDiv;		/* return Feedback value to be written to register */
-	UCHAR ucPostDiv;	/* return post div to be written to register */
-} COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2;
+typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2
+{
+  ULONG   ulClock;        //When return, [23:0] return real clock 
+  UCHAR   ucAction;       //0:reserved;COMPUTE_MEMORY_PLL_PARAM:Memory;COMPUTE_ENGINE_PLL_PARAM:Engine. it return ref_div to be written to register
+  USHORT  usFbDiv;		    //return Feedback value to be written to register
+  UCHAR   ucPostDiv;      //return post div to be written to register
+}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2;
 #define COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION   COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS
 
-#define SET_CLOCK_FREQ_MASK                     0x00FFFFFF	/* Clock change tables only take bit [23:0] as the requested clock value */
-#define USE_NON_BUS_CLOCK_MASK                  0x01000000	/* Applicable to both memory and engine clock change, when set, it uses another clock as the temporary clock (engine uses memory and vice versa) */
-#define USE_MEMORY_SELF_REFRESH_MASK            0x02000000	/* Only applicable to memory clock change, when set, using memory self refresh during clock transition */
-#define SKIP_INTERNAL_MEMORY_PARAMETER_CHANGE   0x04000000	/* Only applicable to memory clock change, when set, the table will skip predefined internal memory parameter change */
-#define FIRST_TIME_CHANGE_CLOCK									0x08000000	/* Applicable to both memory and engine clock change,when set, it means this is 1st time to change clock after ASIC bootup */
-#define SKIP_SW_PROGRAM_PLL											0x10000000	/* Applicable to both memory and engine clock change, when set, it means the table will not program SPLL/MPLL */
+
+#define SET_CLOCK_FREQ_MASK                     0x00FFFFFF  //Clock change tables only take bit [23:0] as the requested clock value
+#define USE_NON_BUS_CLOCK_MASK                  0x01000000  //Applicable to both memory and engine clock change, when set, it uses another clock as the temporary clock (engine uses memory and vice versa)
+#define USE_MEMORY_SELF_REFRESH_MASK            0x02000000	//Only applicable to memory clock change, when set, using memory self refresh during clock transition
+#define SKIP_INTERNAL_MEMORY_PARAMETER_CHANGE   0x04000000  //Only applicable to memory clock change, when set, the table will skip predefined internal memory parameter change
+#define FIRST_TIME_CHANGE_CLOCK									0x08000000	//Applicable to both memory and engine clock change,when set, it means this is 1st time to change clock after ASIC bootup
+#define SKIP_SW_PROGRAM_PLL											0x10000000	//Applicable to both memory and engine clock change, when set, it means the table will not program SPLL/MPLL
 #define USE_SS_ENABLED_PIXEL_CLOCK  USE_NON_BUS_CLOCK_MASK
 
-#define b3USE_NON_BUS_CLOCK_MASK                  0x01	/* Applicable to both memory and engine clock change, when set, it uses another clock as the temporary clock (engine uses memory and vice versa) */
-#define b3USE_MEMORY_SELF_REFRESH                 0x02	/* Only applicable to memory clock change, when set, using memory self refresh during clock transition */
-#define b3SKIP_INTERNAL_MEMORY_PARAMETER_CHANGE   0x04	/* Only applicable to memory clock change, when set, the table will skip predefined internal memory parameter change */
-#define b3FIRST_TIME_CHANGE_CLOCK									0x08	/* Applicable to both memory and engine clock change,when set, it means this is 1st time to change clock after ASIC bootup */
-#define b3SKIP_SW_PROGRAM_PLL											0x10	/* Applicable to both memory and engine clock change, when set, it means the table will not program SPLL/MPLL */
+#define b3USE_NON_BUS_CLOCK_MASK                  0x01       //Applicable to both memory and engine clock change, when set, it uses another clock as the temporary clock (engine uses memory and vice versa)
+#define b3USE_MEMORY_SELF_REFRESH                 0x02	     //Only applicable to memory clock change, when set, using memory self refresh during clock transition
+#define b3SKIP_INTERNAL_MEMORY_PARAMETER_CHANGE   0x04       //Only applicable to memory clock change, when set, the table will skip predefined internal memory parameter change
+#define b3FIRST_TIME_CHANGE_CLOCK									0x08       //Applicable to both memory and engine clock change,when set, it means this is 1st time to change clock after ASIC bootup
+#define b3SKIP_SW_PROGRAM_PLL											0x10			 //Applicable to both memory and engine clock change, when set, it means the table will not program SPLL/MPLL
 
-typedef struct _ATOM_COMPUTE_CLOCK_FREQ {
+typedef struct _ATOM_COMPUTE_CLOCK_FREQ
+{
 #if ATOM_BIG_ENDIAN
-	ULONG ulComputeClockFlag:8;	/*  =1: COMPUTE_MEMORY_PLL_PARAM, =2: COMPUTE_ENGINE_PLL_PARAM */
-	ULONG ulClockFreq:24;	/*  in unit of 10kHz */
+  ULONG ulComputeClockFlag:8;                 // =1: COMPUTE_MEMORY_PLL_PARAM, =2: COMPUTE_ENGINE_PLL_PARAM
+  ULONG ulClockFreq:24;                       // in unit of 10kHz
 #else
-	ULONG ulClockFreq:24;	/*  in unit of 10kHz */
-	ULONG ulComputeClockFlag:8;	/*  =1: COMPUTE_MEMORY_PLL_PARAM, =2: COMPUTE_ENGINE_PLL_PARAM */
+  ULONG ulClockFreq:24;                       // in unit of 10kHz
+  ULONG ulComputeClockFlag:8;                 // =1: COMPUTE_MEMORY_PLL_PARAM, =2: COMPUTE_ENGINE_PLL_PARAM
 #endif
-} ATOM_COMPUTE_CLOCK_FREQ;
+}ATOM_COMPUTE_CLOCK_FREQ;
 
-typedef struct _ATOM_S_MPLL_FB_DIVIDER {
-	USHORT usFbDivFrac;
-	USHORT usFbDiv;
-} ATOM_S_MPLL_FB_DIVIDER;
+typedef struct _ATOM_S_MPLL_FB_DIVIDER
+{
+  USHORT usFbDivFrac;  
+  USHORT usFbDiv;  
+}ATOM_S_MPLL_FB_DIVIDER;
 
-typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 {
-	union {
-		ATOM_COMPUTE_CLOCK_FREQ ulClock;	/* Input Parameter */
-		ATOM_S_MPLL_FB_DIVIDER ulFbDiv;	/* Output Parameter */
-	};
-	UCHAR ucRefDiv;		/* Output Parameter */
-	UCHAR ucPostDiv;	/* Output Parameter */
-	UCHAR ucCntlFlag;	/* Output Parameter */
-	UCHAR ucReserved;
-} COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3;
+typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3
+{
+  union
+  {
+    ATOM_COMPUTE_CLOCK_FREQ  ulClock;         //Input Parameter
+    ATOM_S_MPLL_FB_DIVIDER   ulFbDiv;         //Output Parameter
+  };
+  UCHAR   ucRefDiv;                           //Output Parameter      
+  UCHAR   ucPostDiv;                          //Output Parameter      
+  UCHAR   ucCntlFlag;                         //Output Parameter      
+  UCHAR   ucReserved;
+}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3;
 
-/*  ucCntlFlag */
+// ucCntlFlag
 #define ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN          1
 #define ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE            2
 #define ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE         4
+#define ATOM_PLL_CNTL_FLAG_SPLL_ISPARE_9						8
 
-typedef struct _DYNAMICE_MEMORY_SETTINGS_PARAMETER {
-	ATOM_COMPUTE_CLOCK_FREQ ulClock;
-	ULONG ulReserved[2];
-} DYNAMICE_MEMORY_SETTINGS_PARAMETER;
 
-typedef struct _DYNAMICE_ENGINE_SETTINGS_PARAMETER {
-	ATOM_COMPUTE_CLOCK_FREQ ulClock;
-	ULONG ulMemoryClock;
-	ULONG ulReserved;
-} DYNAMICE_ENGINE_SETTINGS_PARAMETER;
+// V4 are only used for APU which PLL outside GPU
+typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4
+{
+#if ATOM_BIG_ENDIAN
+  ULONG  ucPostDiv;          //return parameter: post divider which is used to program to register directly
+  ULONG  ulClock:24;         //Input= target clock, output = actual clock 
+#else
+  ULONG  ulClock:24;         //Input= target clock, output = actual clock 
+  ULONG  ucPostDiv;          //return parameter: post divider which is used to program to register directly
+#endif
+}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4;
 
-/****************************************************************************/
-/*  Structures used by SetEngineClockTable */
-/****************************************************************************/
-typedef struct _SET_ENGINE_CLOCK_PARAMETERS {
-	ULONG ulTargetEngineClock;	/* In 10Khz unit */
-} SET_ENGINE_CLOCK_PARAMETERS;
+typedef struct _DYNAMICE_MEMORY_SETTINGS_PARAMETER
+{
+  ATOM_COMPUTE_CLOCK_FREQ ulClock;
+  ULONG ulReserved[2];
+}DYNAMICE_MEMORY_SETTINGS_PARAMETER;
 
-typedef struct _SET_ENGINE_CLOCK_PS_ALLOCATION {
-	ULONG ulTargetEngineClock;	/* In 10Khz unit */
-	COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved;
-} SET_ENGINE_CLOCK_PS_ALLOCATION;
+typedef struct _DYNAMICE_ENGINE_SETTINGS_PARAMETER
+{
+  ATOM_COMPUTE_CLOCK_FREQ ulClock;
+  ULONG ulMemoryClock;
+  ULONG ulReserved;
+}DYNAMICE_ENGINE_SETTINGS_PARAMETER;
 
-/****************************************************************************/
-/*  Structures used by SetMemoryClockTable */
-/****************************************************************************/
-typedef struct _SET_MEMORY_CLOCK_PARAMETERS {
-	ULONG ulTargetMemoryClock;	/* In 10Khz unit */
-} SET_MEMORY_CLOCK_PARAMETERS;
+/****************************************************************************/	
+// Structures used by SetEngineClockTable
+/****************************************************************************/	
+typedef struct _SET_ENGINE_CLOCK_PARAMETERS
+{
+  ULONG ulTargetEngineClock;          //In 10Khz unit
+}SET_ENGINE_CLOCK_PARAMETERS;
 
-typedef struct _SET_MEMORY_CLOCK_PS_ALLOCATION {
-	ULONG ulTargetMemoryClock;	/* In 10Khz unit */
-	COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved;
-} SET_MEMORY_CLOCK_PS_ALLOCATION;
+typedef struct _SET_ENGINE_CLOCK_PS_ALLOCATION
+{
+  ULONG ulTargetEngineClock;          //In 10Khz unit
+  COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved;
+}SET_ENGINE_CLOCK_PS_ALLOCATION;
 
-/****************************************************************************/
-/*  Structures used by ASIC_Init.ctb */
-/****************************************************************************/
-typedef struct _ASIC_INIT_PARAMETERS {
-	ULONG ulDefaultEngineClock;	/* In 10Khz unit */
-	ULONG ulDefaultMemoryClock;	/* In 10Khz unit */
-} ASIC_INIT_PARAMETERS;
+/****************************************************************************/	
+// Structures used by SetMemoryClockTable
+/****************************************************************************/	
+typedef struct _SET_MEMORY_CLOCK_PARAMETERS
+{
+  ULONG ulTargetMemoryClock;          //In 10Khz unit
+}SET_MEMORY_CLOCK_PARAMETERS;
 
-typedef struct _ASIC_INIT_PS_ALLOCATION {
-	ASIC_INIT_PARAMETERS sASICInitClocks;
-	SET_ENGINE_CLOCK_PS_ALLOCATION sReserved;	/* Caller doesn't need to init this structure */
-} ASIC_INIT_PS_ALLOCATION;
+typedef struct _SET_MEMORY_CLOCK_PS_ALLOCATION
+{
+  ULONG ulTargetMemoryClock;          //In 10Khz unit
+  COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved;
+}SET_MEMORY_CLOCK_PS_ALLOCATION;
 
-/****************************************************************************/
-/*  Structure used by DynamicClockGatingTable.ctb */
-/****************************************************************************/
-typedef struct _DYNAMIC_CLOCK_GATING_PARAMETERS {
-	UCHAR ucEnable;		/*  ATOM_ENABLE or ATOM_DISABLE */
-	UCHAR ucPadding[3];
-} DYNAMIC_CLOCK_GATING_PARAMETERS;
+/****************************************************************************/	
+// Structures used by ASIC_Init.ctb
+/****************************************************************************/	
+typedef struct _ASIC_INIT_PARAMETERS
+{
+  ULONG ulDefaultEngineClock;         //In 10Khz unit
+  ULONG ulDefaultMemoryClock;         //In 10Khz unit
+}ASIC_INIT_PARAMETERS;
+
+typedef struct _ASIC_INIT_PS_ALLOCATION
+{
+  ASIC_INIT_PARAMETERS sASICInitClocks;
+  SET_ENGINE_CLOCK_PS_ALLOCATION sReserved; //Caller doesn't need to init this structure
+}ASIC_INIT_PS_ALLOCATION;
+
+/****************************************************************************/	
+// Structure used by DynamicClockGatingTable.ctb
+/****************************************************************************/	
+typedef struct _DYNAMIC_CLOCK_GATING_PARAMETERS 
+{
+  UCHAR ucEnable;                     // ATOM_ENABLE or ATOM_DISABLE
+  UCHAR ucPadding[3];
+}DYNAMIC_CLOCK_GATING_PARAMETERS;
 #define  DYNAMIC_CLOCK_GATING_PS_ALLOCATION  DYNAMIC_CLOCK_GATING_PARAMETERS
 
-/****************************************************************************/
-/*  Structure used by EnableASIC_StaticPwrMgtTable.ctb */
-/****************************************************************************/
-typedef struct _ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS {
-	UCHAR ucEnable;		/*  ATOM_ENABLE or ATOM_DISABLE */
-	UCHAR ucPadding[3];
-} ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS;
+/****************************************************************************/	
+// Structure used by EnableASIC_StaticPwrMgtTable.ctb
+/****************************************************************************/	
+typedef struct _ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS
+{
+  UCHAR ucEnable;                     // ATOM_ENABLE or ATOM_DISABLE
+  UCHAR ucPadding[3];
+}ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS;
 #define ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION  ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS
 
-/****************************************************************************/
-/*  Structures used by DAC_LoadDetectionTable.ctb */
-/****************************************************************************/
-typedef struct _DAC_LOAD_DETECTION_PARAMETERS {
-	USHORT usDeviceID;	/* {ATOM_DEVICE_CRTx_SUPPORT,ATOM_DEVICE_TVx_SUPPORT,ATOM_DEVICE_CVx_SUPPORT} */
-	UCHAR ucDacType;	/* {ATOM_DAC_A,ATOM_DAC_B, ATOM_EXT_DAC} */
-	UCHAR ucMisc;		/* Valid only when table revision =1.3 and above */
-} DAC_LOAD_DETECTION_PARAMETERS;
+/****************************************************************************/	
+// Structures used by DAC_LoadDetectionTable.ctb
+/****************************************************************************/	
+typedef struct _DAC_LOAD_DETECTION_PARAMETERS
+{
+  USHORT usDeviceID;                  //{ATOM_DEVICE_CRTx_SUPPORT,ATOM_DEVICE_TVx_SUPPORT,ATOM_DEVICE_CVx_SUPPORT}
+  UCHAR  ucDacType;                   //{ATOM_DAC_A,ATOM_DAC_B, ATOM_EXT_DAC}
+  UCHAR  ucMisc;											//Valid only when table revision =1.3 and above
+}DAC_LOAD_DETECTION_PARAMETERS;
 
-/*  DAC_LOAD_DETECTION_PARAMETERS.ucMisc */
+// DAC_LOAD_DETECTION_PARAMETERS.ucMisc
 #define DAC_LOAD_MISC_YPrPb						0x01
 
-typedef struct _DAC_LOAD_DETECTION_PS_ALLOCATION {
-	DAC_LOAD_DETECTION_PARAMETERS sDacload;
-	ULONG Reserved[2];	/*  Don't set this one, allocation for EXT DAC */
-} DAC_LOAD_DETECTION_PS_ALLOCATION;
+typedef struct _DAC_LOAD_DETECTION_PS_ALLOCATION
+{
+  DAC_LOAD_DETECTION_PARAMETERS            sDacload;
+  ULONG                                    Reserved[2];// Don't set this one, allocation for EXT DAC
+}DAC_LOAD_DETECTION_PS_ALLOCATION;
 
-/****************************************************************************/
-/*  Structures used by DAC1EncoderControlTable.ctb and DAC2EncoderControlTable.ctb */
-/****************************************************************************/
-typedef struct _DAC_ENCODER_CONTROL_PARAMETERS {
-	USHORT usPixelClock;	/*  in 10KHz; for bios convenient */
-	UCHAR ucDacStandard;	/*  See definition of ATOM_DACx_xxx, For DEC3.0, bit 7 used as internal flag to indicate DAC2 (==1) or DAC1 (==0) */
-	UCHAR ucAction;		/*  0: turn off encoder */
-	/*  1: setup and turn on encoder */
-	/*  7: ATOM_ENCODER_INIT Initialize DAC */
-} DAC_ENCODER_CONTROL_PARAMETERS;
+/****************************************************************************/	
+// Structures used by DAC1EncoderControlTable.ctb and DAC2EncoderControlTable.ctb
+/****************************************************************************/	
+typedef struct _DAC_ENCODER_CONTROL_PARAMETERS 
+{
+  USHORT usPixelClock;                // in 10KHz; for bios convenient
+  UCHAR  ucDacStandard;               // See definition of ATOM_DACx_xxx, For DEC3.0, bit 7 used as internal flag to indicate DAC2 (==1) or DAC1 (==0)
+  UCHAR  ucAction;                    // 0: turn off encoder
+                                      // 1: setup and turn on encoder
+                                      // 7: ATOM_ENCODER_INIT Initialize DAC
+}DAC_ENCODER_CONTROL_PARAMETERS;
 
 #define DAC_ENCODER_CONTROL_PS_ALLOCATION  DAC_ENCODER_CONTROL_PARAMETERS
 
-/****************************************************************************/
-/*  Structures used by DIG1EncoderControlTable */
-/*                     DIG2EncoderControlTable */
-/*                     ExternalEncoderControlTable */
-/****************************************************************************/
-typedef struct _DIG_ENCODER_CONTROL_PARAMETERS {
-	USHORT usPixelClock;	/*  in 10KHz; for bios convenient */
-	UCHAR ucConfig;
-	/*  [2] Link Select: */
-	/*  =0: PHY linkA if bfLane<3 */
-	/*  =1: PHY linkB if bfLanes<3 */
-	/*  =0: PHY linkA+B if bfLanes=3 */
-	/*  [3] Transmitter Sel */
-	/*  =0: UNIPHY or PCIEPHY */
-	/*  =1: LVTMA */
-	UCHAR ucAction;		/*  =0: turn off encoder */
-	/*  =1: turn on encoder */
-	UCHAR ucEncoderMode;
-	/*  =0: DP   encoder */
-	/*  =1: LVDS encoder */
-	/*  =2: DVI  encoder */
-	/*  =3: HDMI encoder */
-	/*  =4: SDVO encoder */
-	UCHAR ucLaneNum;	/*  how many lanes to enable */
-	UCHAR ucReserved[2];
-} DIG_ENCODER_CONTROL_PARAMETERS;
+/****************************************************************************/	
+// Structures used by DIG1EncoderControlTable
+//                    DIG2EncoderControlTable
+//                    ExternalEncoderControlTable
+/****************************************************************************/	
+typedef struct _DIG_ENCODER_CONTROL_PARAMETERS
+{
+  USHORT usPixelClock;		// in 10KHz; for bios convenient
+  UCHAR  ucConfig;		  
+                            // [2] Link Select:
+                            // =0: PHY linkA if bfLane<3
+                            // =1: PHY linkB if bfLanes<3
+                            // =0: PHY linkA+B if bfLanes=3
+                            // [3] Transmitter Sel
+                            // =0: UNIPHY or PCIEPHY
+                            // =1: LVTMA 					
+  UCHAR ucAction;           // =0: turn off encoder					
+                            // =1: turn on encoder			
+  UCHAR ucEncoderMode;
+                            // =0: DP   encoder      
+                            // =1: LVDS encoder          
+                            // =2: DVI  encoder  
+                            // =3: HDMI encoder
+                            // =4: SDVO encoder
+  UCHAR ucLaneNum;          // how many lanes to enable
+  UCHAR ucReserved[2];
+}DIG_ENCODER_CONTROL_PARAMETERS;
 #define DIG_ENCODER_CONTROL_PS_ALLOCATION			  DIG_ENCODER_CONTROL_PARAMETERS
 #define EXTERNAL_ENCODER_CONTROL_PARAMETER			DIG_ENCODER_CONTROL_PARAMETERS
 
-/* ucConfig */
+//ucConfig
 #define ATOM_ENCODER_CONFIG_DPLINKRATE_MASK				0x01
 #define ATOM_ENCODER_CONFIG_DPLINKRATE_1_62GHZ		0x00
 #define ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ		0x01
@@ -539,52 +593,57 @@ typedef struct _DIG_ENCODER_CONTROL_PARA
 #define ATOM_ENCODER_CONFIG_LVTMA								  0x08
 #define ATOM_ENCODER_CONFIG_TRANSMITTER1				  0x00
 #define ATOM_ENCODER_CONFIG_TRANSMITTER2				  0x08
-#define ATOM_ENCODER_CONFIG_DIGB								  0x80	/*  VBIOS Internal use, outside SW should set this bit=0 */
-/*  ucAction */
-/*  ATOM_ENABLE:  Enable Encoder */
-/*  ATOM_DISABLE: Disable Encoder */
+#define ATOM_ENCODER_CONFIG_DIGB								  0x80			// VBIOS Internal use, outside SW should set this bit=0
+// ucAction
+// ATOM_ENABLE:  Enable Encoder
+// ATOM_DISABLE: Disable Encoder
 
-/* ucEncoderMode */
+//ucEncoderMode
 #define ATOM_ENCODER_MODE_DP											0
 #define ATOM_ENCODER_MODE_LVDS										1
 #define ATOM_ENCODER_MODE_DVI											2
 #define ATOM_ENCODER_MODE_HDMI										3
 #define ATOM_ENCODER_MODE_SDVO										4
+#define ATOM_ENCODER_MODE_DP_AUDIO                5
 #define ATOM_ENCODER_MODE_TV											13
 #define ATOM_ENCODER_MODE_CV											14
 #define ATOM_ENCODER_MODE_CRT											15
 
-typedef struct _ATOM_DIG_ENCODER_CONFIG_V2 {
+typedef struct _ATOM_DIG_ENCODER_CONFIG_V2
+{
 #if ATOM_BIG_ENDIAN
-	UCHAR ucReserved1:2;
-	UCHAR ucTransmitterSel:2;	/*  =0: UniphyAB, =1: UniphyCD  =2: UniphyEF */
-	UCHAR ucLinkSel:1;	/*  =0: linkA/C/E =1: linkB/D/F */
-	UCHAR ucReserved:1;
-	UCHAR ucDPLinkRate:1;	/*  =0: 1.62Ghz, =1: 2.7Ghz */
+    UCHAR ucReserved1:2;
+    UCHAR ucTransmitterSel:2;     // =0: UniphyAB, =1: UniphyCD  =2: UniphyEF
+    UCHAR ucLinkSel:1;            // =0: linkA/C/E =1: linkB/D/F
+    UCHAR ucReserved:1;
+    UCHAR ucDPLinkRate:1;         // =0: 1.62Ghz, =1: 2.7Ghz
 #else
-	UCHAR ucDPLinkRate:1;	/*  =0: 1.62Ghz, =1: 2.7Ghz */
-	UCHAR ucReserved:1;
-	UCHAR ucLinkSel:1;	/*  =0: linkA/C/E =1: linkB/D/F */
-	UCHAR ucTransmitterSel:2;	/*  =0: UniphyAB, =1: UniphyCD  =2: UniphyEF */
-	UCHAR ucReserved1:2;
+    UCHAR ucDPLinkRate:1;         // =0: 1.62Ghz, =1: 2.7Ghz
+    UCHAR ucReserved:1;
+    UCHAR ucLinkSel:1;            // =0: linkA/C/E =1: linkB/D/F
+    UCHAR ucTransmitterSel:2;     // =0: UniphyAB, =1: UniphyCD  =2: UniphyEF
+    UCHAR ucReserved1:2;
 #endif
-} ATOM_DIG_ENCODER_CONFIG_V2;
+}ATOM_DIG_ENCODER_CONFIG_V2;
 
-typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V2 {
-	USHORT usPixelClock;	/*  in 10KHz; for bios convenient */
-	ATOM_DIG_ENCODER_CONFIG_V2 acConfig;
-	UCHAR ucAction;
-	UCHAR ucEncoderMode;
-	/*  =0: DP   encoder */
-	/*  =1: LVDS encoder */
-	/*  =2: DVI  encoder */
-	/*  =3: HDMI encoder */
-	/*  =4: SDVO encoder */
-	UCHAR ucLaneNum;	/*  how many lanes to enable */
-	UCHAR ucReserved[2];
-} DIG_ENCODER_CONTROL_PARAMETERS_V2;
 
-/* ucConfig */
+typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V2
+{
+  USHORT usPixelClock;      // in 10KHz; for bios convenient
+  ATOM_DIG_ENCODER_CONFIG_V2 acConfig;
+  UCHAR ucAction;                                       
+  UCHAR ucEncoderMode;
+                            // =0: DP   encoder      
+                            // =1: LVDS encoder          
+                            // =2: DVI  encoder  
+                            // =3: HDMI encoder
+                            // =4: SDVO encoder
+  UCHAR ucLaneNum;          // how many lanes to enable
+  UCHAR ucStatus;           // = DP_LINK_TRAINING_COMPLETE or DP_LINK_TRAINING_INCOMPLETE, only used by VBIOS with command ATOM_ENCODER_CMD_QUERY_DP_LINK_TRAINING_STATUS
+  UCHAR ucReserved;
+}DIG_ENCODER_CONTROL_PARAMETERS_V2;
+
+//ucConfig
 #define ATOM_ENCODER_CONFIG_V2_DPLINKRATE_MASK				0x01
 #define ATOM_ENCODER_CONFIG_V2_DPLINKRATE_1_62GHZ		  0x00
 #define ATOM_ENCODER_CONFIG_V2_DPLINKRATE_2_70GHZ		  0x01
@@ -596,58 +655,122 @@ typedef struct _DIG_ENCODER_CONTROL_PARA
 #define ATOM_ENCODER_CONFIG_V2_TRANSMITTER2				    0x08
 #define ATOM_ENCODER_CONFIG_V2_TRANSMITTER3				    0x10
 
-/****************************************************************************/
-/*  Structures used by UNIPHYTransmitterControlTable */
-/*                     LVTMATransmitterControlTable */
-/*                     DVOOutputControlTable */
-/****************************************************************************/
-typedef struct _ATOM_DP_VS_MODE {
-	UCHAR ucLaneSel;
-	UCHAR ucLaneSet;
-} ATOM_DP_VS_MODE;
+// ucAction:
+// ATOM_DISABLE
+// ATOM_ENABLE
+#define ATOM_ENCODER_CMD_DP_LINK_TRAINING_START       0x08
+#define ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1    0x09
+#define ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2    0x0a
+#define ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE    0x0b
+#define ATOM_ENCODER_CMD_DP_VIDEO_OFF                 0x0c
+#define ATOM_ENCODER_CMD_DP_VIDEO_ON                  0x0d
+#define ATOM_ENCODER_CMD_QUERY_DP_LINK_TRAINING_STATUS    0x0e
+#define ATOM_ENCODER_CMD_SETUP                        0x0f
 
-typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS {
-	union {
-		USHORT usPixelClock;	/*  in 10KHz; for bios convenient */
-		USHORT usInitInfo;	/*  when init uniphy,lower 8bit is used for connector type defined in objectid.h */
-		ATOM_DP_VS_MODE asMode;	/*  DP Voltage swing mode */
+// ucStatus
+#define ATOM_ENCODER_STATUS_LINK_TRAINING_COMPLETE    0x10
+#define ATOM_ENCODER_STATUS_LINK_TRAINING_INCOMPLETE  0x00
+
+// Following function ENABLE sub-function will be used by driver when TMDS/HDMI/LVDS is used, disable function will be used by driver
+typedef struct _ATOM_DIG_ENCODER_CONFIG_V3
+{
+#if ATOM_BIG_ENDIAN
+    UCHAR ucReserved1:1;
+    UCHAR ucDigSel:3;             // =0: DIGA/B/C/D/E/F
+    UCHAR ucReserved:3;
+    UCHAR ucDPLinkRate:1;         // =0: 1.62Ghz, =1: 2.7Ghz
+#else
+    UCHAR ucDPLinkRate:1;         // =0: 1.62Ghz, =1: 2.7Ghz
+    UCHAR ucReserved:3;
+    UCHAR ucDigSel:3;             // =0: DIGA/B/C/D/E/F
+    UCHAR ucReserved1:1;
+#endif
+}ATOM_DIG_ENCODER_CONFIG_V3;
+
+#define ATOM_ENCODER_CONFIG_V3_ENCODER_SEL					  0x70
+
+
+typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V3
+{
+  USHORT usPixelClock;      // in 10KHz; for bios convenient
+  ATOM_DIG_ENCODER_CONFIG_V3 acConfig;
+  UCHAR ucAction;                              
+  UCHAR ucEncoderMode;
+                            // =0: DP   encoder      
+                            // =1: LVDS encoder          
+                            // =2: DVI  encoder  
+                            // =3: HDMI encoder
+                            // =4: SDVO encoder
+                            // =5: DP audio
+  UCHAR ucLaneNum;          // how many lanes to enable
+  UCHAR ucBitPerColor;      // only valid for DP mode when ucAction = ATOM_ENCODER_CMD_SETUP
+  UCHAR ucReserved;
+}DIG_ENCODER_CONTROL_PARAMETERS_V3;
+
+
+// define ucBitPerColor: 
+#define PANEL_BPC_UNDEFINE                               0x00
+#define PANEL_6BIT_PER_COLOR                             0x01 
+#define PANEL_8BIT_PER_COLOR                             0x02
+#define PANEL_10BIT_PER_COLOR                            0x03
+#define PANEL_12BIT_PER_COLOR                            0x04
+#define PANEL_16BIT_PER_COLOR                            0x05
+
+/****************************************************************************/	
+// Structures used by UNIPHYTransmitterControlTable
+//                    LVTMATransmitterControlTable
+//                    DVOOutputControlTable
+/****************************************************************************/	
+typedef struct _ATOM_DP_VS_MODE
+{
+  UCHAR ucLaneSel;
+  UCHAR ucLaneSet;
+}ATOM_DP_VS_MODE;
+
+typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS
+{
+	union
+	{
+  USHORT usPixelClock;		// in 10KHz; for bios convenient
+	USHORT usInitInfo;			// when init uniphy,lower 8bit is used for connector type defined in objectid.h
+  ATOM_DP_VS_MODE asMode; // DP Voltage swing mode
 	};
-	UCHAR ucConfig;
-	/*  [0]=0: 4 lane Link, */
-	/*     =1: 8 lane Link ( Dual Links TMDS ) */
-	/*  [1]=0: InCoherent mode */
-	/*     =1: Coherent Mode */
-	/*  [2] Link Select: */
-	/*  =0: PHY linkA   if bfLane<3 */
-	/*  =1: PHY linkB   if bfLanes<3 */
-	/*  =0: PHY linkA+B if bfLanes=3 */
-	/*  [5:4]PCIE lane Sel */
-	/*  =0: lane 0~3 or 0~7 */
-	/*  =1: lane 4~7 */
-	/*  =2: lane 8~11 or 8~15 */
-	/*  =3: lane 12~15 */
-	UCHAR ucAction;		/*  =0: turn off encoder */
-	/*  =1: turn on encoder */
-	UCHAR ucReserved[4];
-} DIG_TRANSMITTER_CONTROL_PARAMETERS;
+  UCHAR ucConfig;
+													// [0]=0: 4 lane Link,      
+													//    =1: 8 lane Link ( Dual Links TMDS ) 
+                          // [1]=0: InCoherent mode   
+													//    =1: Coherent Mode										
+													// [2] Link Select:
+  												// =0: PHY linkA   if bfLane<3
+													// =1: PHY linkB   if bfLanes<3
+		  										// =0: PHY linkA+B if bfLanes=3		
+                          // [5:4]PCIE lane Sel
+                          // =0: lane 0~3 or 0~7
+                          // =1: lane 4~7
+                          // =2: lane 8~11 or 8~15
+                          // =3: lane 12~15 
+	UCHAR ucAction;				  // =0: turn off encoder					
+	                        // =1: turn on encoder			
+  UCHAR ucReserved[4];
+}DIG_TRANSMITTER_CONTROL_PARAMETERS;
 
-#define DIG_TRANSMITTER_CONTROL_PS_ALLOCATION		DIG_TRANSMITTER_CONTROL_PARAMETERS
+#define DIG_TRANSMITTER_CONTROL_PS_ALLOCATION		DIG_TRANSMITTER_CONTROL_PARAMETERS					
 
-/* ucInitInfo */
-#define ATOM_TRAMITTER_INITINFO_CONNECTOR_MASK	0x00ff
+//ucInitInfo
+#define ATOM_TRAMITTER_INITINFO_CONNECTOR_MASK	0x00ff			
 
-/* ucConfig */
+//ucConfig 
 #define ATOM_TRANSMITTER_CONFIG_8LANE_LINK			0x01
 #define ATOM_TRANSMITTER_CONFIG_COHERENT				0x02
 #define ATOM_TRANSMITTER_CONFIG_LINK_SEL_MASK		0x04
 #define ATOM_TRANSMITTER_CONFIG_LINKA						0x00
 #define ATOM_TRANSMITTER_CONFIG_LINKB						0x04
-#define ATOM_TRANSMITTER_CONFIG_LINKA_B					0x00
+#define ATOM_TRANSMITTER_CONFIG_LINKA_B					0x00			
 #define ATOM_TRANSMITTER_CONFIG_LINKB_A					0x04
 
-#define ATOM_TRANSMITTER_CONFIG_ENCODER_SEL_MASK	0x08	/*  only used when ATOM_TRANSMITTER_ACTION_ENABLE */
-#define ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER		0x00	/*  only used when ATOM_TRANSMITTER_ACTION_ENABLE */
-#define ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER		0x08	/*  only used when ATOM_TRANSMITTER_ACTION_ENABLE */
+#define ATOM_TRANSMITTER_CONFIG_ENCODER_SEL_MASK	0x08			// only used when ATOM_TRANSMITTER_ACTION_ENABLE
+#define ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER		0x00				// only used when ATOM_TRANSMITTER_ACTION_ENABLE
+#define ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER		0x08				// only used when ATOM_TRANSMITTER_ACTION_ENABLE
 
 #define ATOM_TRANSMITTER_CONFIG_CLKSRC_MASK			0x30
 #define ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL			0x00
@@ -661,7 +784,7 @@ typedef struct _DIG_TRANSMITTER_CONTROL_
 #define ATOM_TRANSMITTER_CONFIG_LANE_8_15				0x80
 #define ATOM_TRANSMITTER_CONFIG_LANE_12_15			0xc0
 
-/* ucAction */
+//ucAction
 #define ATOM_TRANSMITTER_ACTION_DISABLE					       0
 #define ATOM_TRANSMITTER_ACTION_ENABLE					       1
 #define ATOM_TRANSMITTER_ACTION_LCD_BLOFF				       2
@@ -674,93 +797,168 @@ typedef struct _DIG_TRANSMITTER_CONTROL_
 #define ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT		       9
 #define ATOM_TRANSMITTER_ACTION_SETUP						       10
 #define ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH           11
+#define ATOM_TRANSMITTER_ACTION_POWER_ON               12
+#define ATOM_TRANSMITTER_ACTION_POWER_OFF              13
 
-/*  Following are used for DigTransmitterControlTable ver1.2 */
-typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V2 {
+// Following are used for DigTransmitterControlTable ver1.2
+typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V2
+{
 #if ATOM_BIG_ENDIAN
-	UCHAR ucTransmitterSel:2;	/* bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) */
-	/*         =1 Dig Transmitter 2 ( Uniphy CD ) */
-	/*         =2 Dig Transmitter 3 ( Uniphy EF ) */
-	UCHAR ucReserved:1;
-	UCHAR fDPConnector:1;	/* bit4=0: DP connector  =1: None DP connector */
-	UCHAR ucEncoderSel:1;	/* bit3=0: Data/Clk path source from DIGA( DIG inst0 ). =1: Data/clk path source from DIGB ( DIG inst1 ) */
-	UCHAR ucLinkSel:1;	/* bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E */
-	/*     =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F */
+  UCHAR ucTransmitterSel:2;         //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB )
+                                    //        =1 Dig Transmitter 2 ( Uniphy CD )
+                                    //        =2 Dig Transmitter 3 ( Uniphy EF )
+  UCHAR ucReserved:1;               
+  UCHAR fDPConnector:1;             //bit4=0: DP connector  =1: None DP connector
+  UCHAR ucEncoderSel:1;             //bit3=0: Data/Clk path source from DIGA( DIG inst0 ). =1: Data/clk path source from DIGB ( DIG inst1 )
+  UCHAR ucLinkSel:1;                //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E
+                                    //    =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F
 
-	UCHAR fCoherentMode:1;	/* bit1=1: Coherent Mode ( for DVI/HDMI mode ) */
-	UCHAR fDualLinkConnector:1;	/* bit0=1: Dual Link DVI connector */
+  UCHAR fCoherentMode:1;            //bit1=1: Coherent Mode ( for DVI/HDMI mode )
+  UCHAR fDualLinkConnector:1;       //bit0=1: Dual Link DVI connector
 #else
-	UCHAR fDualLinkConnector:1;	/* bit0=1: Dual Link DVI connector */
-	UCHAR fCoherentMode:1;	/* bit1=1: Coherent Mode ( for DVI/HDMI mode ) */
-	UCHAR ucLinkSel:1;	/* bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E */
-	/*     =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F */
-	UCHAR ucEncoderSel:1;	/* bit3=0: Data/Clk path source from DIGA( DIG inst0 ). =1: Data/clk path source from DIGB ( DIG inst1 ) */
-	UCHAR fDPConnector:1;	/* bit4=0: DP connector  =1: None DP connector */
-	UCHAR ucReserved:1;
-	UCHAR ucTransmitterSel:2;	/* bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) */
-	/*         =1 Dig Transmitter 2 ( Uniphy CD ) */
-	/*         =2 Dig Transmitter 3 ( Uniphy EF ) */
+  UCHAR fDualLinkConnector:1;       //bit0=1: Dual Link DVI connector
+  UCHAR fCoherentMode:1;            //bit1=1: Coherent Mode ( for DVI/HDMI mode )
+  UCHAR ucLinkSel:1;                //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E
+                                    //    =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F
+  UCHAR ucEncoderSel:1;             //bit3=0: Data/Clk path source from DIGA( DIG inst0 ). =1: Data/clk path source from DIGB ( DIG inst1 )
+  UCHAR fDPConnector:1;             //bit4=0: DP connector  =1: None DP connector
+  UCHAR ucReserved:1;               
+  UCHAR ucTransmitterSel:2;         //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB )
+                                    //        =1 Dig Transmitter 2 ( Uniphy CD )
+                                    //        =2 Dig Transmitter 3 ( Uniphy EF )
 #endif
-} ATOM_DIG_TRANSMITTER_CONFIG_V2;
+}ATOM_DIG_TRANSMITTER_CONFIG_V2;
 
-/* ucConfig */
-/* Bit0 */
+//ucConfig 
+//Bit0
 #define ATOM_TRANSMITTER_CONFIG_V2_DUAL_LINK_CONNECTOR			0x01
 
-/* Bit1 */
+//Bit1
 #define ATOM_TRANSMITTER_CONFIG_V2_COHERENT				          0x02
 
-/* Bit2 */
+//Bit2
 #define ATOM_TRANSMITTER_CONFIG_V2_LINK_SEL_MASK		        0x04
-#define ATOM_TRANSMITTER_CONFIG_V2_LINKA			            0x00
+#define ATOM_TRANSMITTER_CONFIG_V2_LINKA  			            0x00
 #define ATOM_TRANSMITTER_CONFIG_V2_LINKB				            0x04
 
-/*  Bit3 */
+// Bit3
 #define ATOM_TRANSMITTER_CONFIG_V2_ENCODER_SEL_MASK	        0x08
-#define ATOM_TRANSMITTER_CONFIG_V2_DIG1_ENCODER		          0x00	/*  only used when ucAction == ATOM_TRANSMITTER_ACTION_ENABLE or ATOM_TRANSMITTER_ACTION_SETUP */
-#define ATOM_TRANSMITTER_CONFIG_V2_DIG2_ENCODER		          0x08	/*  only used when ucAction == ATOM_TRANSMITTER_ACTION_ENABLE or ATOM_TRANSMITTER_ACTION_SETUP */
+#define ATOM_TRANSMITTER_CONFIG_V2_DIG1_ENCODER		          0x00				// only used when ucAction == ATOM_TRANSMITTER_ACTION_ENABLE or ATOM_TRANSMITTER_ACTION_SETUP
+#define ATOM_TRANSMITTER_CONFIG_V2_DIG2_ENCODER		          0x08				// only used when ucAction == ATOM_TRANSMITTER_ACTION_ENABLE or ATOM_TRANSMITTER_ACTION_SETUP
 
-/*  Bit4 */
+// Bit4
 #define ATOM_TRASMITTER_CONFIG_V2_DP_CONNECTOR			        0x10
 
-/*  Bit7:6 */
+// Bit7:6
 #define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER_SEL_MASK     0xC0
-#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER1			0x00	/* AB */
-#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER2			0x40	/* CD */
-#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER3			0x80	/* EF */
+#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER1           	0x00	//AB
+#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER2           	0x40	//CD
+#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER3           	0x80	//EF
 
-typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 {
-	union {
-		USHORT usPixelClock;	/*  in 10KHz; for bios convenient */
-		USHORT usInitInfo;	/*  when init uniphy,lower 8bit is used for connector type defined in objectid.h */
-		ATOM_DP_VS_MODE asMode;	/*  DP Voltage swing mode */
+typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V2
+{
+	union
+	{
+  USHORT usPixelClock;		// in 10KHz; for bios convenient
+	USHORT usInitInfo;			// when init uniphy,lower 8bit is used for connector type defined in objectid.h
+  ATOM_DP_VS_MODE asMode; // DP Voltage swing mode
 	};
-	ATOM_DIG_TRANSMITTER_CONFIG_V2 acConfig;
-	UCHAR ucAction;		/*  define as ATOM_TRANSMITER_ACTION_XXX */
-	UCHAR ucReserved[4];
-} DIG_TRANSMITTER_CONTROL_PARAMETERS_V2;
+  ATOM_DIG_TRANSMITTER_CONFIG_V2 acConfig;
+	UCHAR ucAction;				  // define as ATOM_TRANSMITER_ACTION_XXX
+  UCHAR ucReserved[4];
+}DIG_TRANSMITTER_CONTROL_PARAMETERS_V2;
 
-/****************************************************************************/
-/*  Structures used by DAC1OuputControlTable */
-/*                     DAC2OuputControlTable */
-/*                     LVTMAOutputControlTable  (Before DEC30) */
-/*                     TMDSAOutputControlTable  (Before DEC30) */
-/****************************************************************************/
-typedef struct _DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS {
-	UCHAR ucAction;		/*  Possible input:ATOM_ENABLE||ATOMDISABLE */
-	/*  When the display is LCD, in addition to above: */
-	/*  ATOM_LCD_BLOFF|| ATOM_LCD_BLON ||ATOM_LCD_BL_BRIGHTNESS_CONTROL||ATOM_LCD_SELFTEST_START|| */
-	/*  ATOM_LCD_SELFTEST_STOP */
+typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V3
+{
+#if ATOM_BIG_ENDIAN
+  UCHAR ucTransmitterSel:2;         //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB )
+                                    //        =1 Dig Transmitter 2 ( Uniphy CD )
+                                    //        =2 Dig Transmitter 3 ( Uniphy EF )
+  UCHAR ucRefClkSource:2;           //bit5:4: PPLL1 =0, PPLL2=1, EXT_CLK=2
+  UCHAR ucEncoderSel:1;             //bit3=0: Data/Clk path source from DIGA/C/E. =1: Data/clk path source from DIGB/D/F
+  UCHAR ucLinkSel:1;                //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E
+                                    //    =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F
+  UCHAR fCoherentMode:1;            //bit1=1: Coherent Mode ( for DVI/HDMI mode )
+  UCHAR fDualLinkConnector:1;       //bit0=1: Dual Link DVI connector
+#else
+  UCHAR fDualLinkConnector:1;       //bit0=1: Dual Link DVI connector
+  UCHAR fCoherentMode:1;            //bit1=1: Coherent Mode ( for DVI/HDMI mode )
+  UCHAR ucLinkSel:1;                //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E
+                                    //    =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F
+  UCHAR ucEncoderSel:1;             //bit3=0: Data/Clk path source from DIGA/C/E. =1: Data/clk path source from DIGB/D/F
+  UCHAR ucRefClkSource:2;           //bit5:4: PPLL1 =0, PPLL2=1, EXT_CLK=2
+  UCHAR ucTransmitterSel:2;         //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB )
+                                    //        =1 Dig Transmitter 2 ( Uniphy CD )
+                                    //        =2 Dig Transmitter 3 ( Uniphy EF )
+#endif
+}ATOM_DIG_TRANSMITTER_CONFIG_V3;
 
-	UCHAR aucPadding[3];	/*  padding to DWORD aligned */
-} DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS;
+typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V3
+{
+	union
+	{
+    USHORT usPixelClock;		// in 10KHz; for bios convenient
+	  USHORT usInitInfo;			// when init uniphy,lower 8bit is used for connector type defined in objectid.h
+    ATOM_DP_VS_MODE asMode; // DP Voltage swing mode
+	};
+  ATOM_DIG_TRANSMITTER_CONFIG_V3 acConfig;
+	UCHAR ucAction;				    // define as ATOM_TRANSMITER_ACTION_XXX
+  UCHAR ucLaneNum;
+  UCHAR ucReserved[3];
+}DIG_TRANSMITTER_CONTROL_PARAMETERS_V3;
+
+//ucConfig 
+//Bit0
+#define ATOM_TRANSMITTER_CONFIG_V3_DUAL_LINK_CONNECTOR			0x01
+
+//Bit1
+#define ATOM_TRANSMITTER_CONFIG_V3_COHERENT				          0x02
+
+//Bit2
+#define ATOM_TRANSMITTER_CONFIG_V3_LINK_SEL_MASK		        0x04
+#define ATOM_TRANSMITTER_CONFIG_V3_LINKA  			            0x00
+#define ATOM_TRANSMITTER_CONFIG_V3_LINKB				            0x04
+
+// Bit3
+#define ATOM_TRANSMITTER_CONFIG_V3_ENCODER_SEL_MASK	        0x08
+#define ATOM_TRANSMITTER_CONFIG_V3_DIG1_ENCODER		          0x00
+#define ATOM_TRANSMITTER_CONFIG_V3_DIG2_ENCODER		          0x08
+
+// Bit5:4
+#define ATOM_TRASMITTER_CONFIG_V3_REFCLK_SEL_MASK 	        0x30
+#define ATOM_TRASMITTER_CONFIG_V3_P1PLL          		        0x00
+#define ATOM_TRASMITTER_CONFIG_V3_P2PLL		                  0x10
+#define ATOM_TRASMITTER_CONFIG_V3_REFCLK_SRC_EXT            0x20
+
+// Bit7:6
+#define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER_SEL_MASK     0xC0
+#define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER1           	0x00	//AB
+#define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER2           	0x40	//CD
+#define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER3           	0x80	//EF
+
+/****************************************************************************/	
+// Structures used by DAC1OuputControlTable
+//                    DAC2OuputControlTable
+//                    LVTMAOutputControlTable  (Before DEC30)
+//                    TMDSAOutputControlTable  (Before DEC30)
+/****************************************************************************/	
+typedef struct _DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS
+{
+  UCHAR  ucAction;                    // Possible input:ATOM_ENABLE||ATOMDISABLE
+                                      // When the display is LCD, in addition to above:
+                                      // ATOM_LCD_BLOFF|| ATOM_LCD_BLON ||ATOM_LCD_BL_BRIGHTNESS_CONTROL||ATOM_LCD_SELFTEST_START||
+                                      // ATOM_LCD_SELFTEST_STOP
+                                      
+  UCHAR  aucPadding[3];               // padding to DWORD aligned
+}DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS;
 
 #define DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS
 
-#define CRT1_OUTPUT_CONTROL_PARAMETERS     DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS
+
+#define CRT1_OUTPUT_CONTROL_PARAMETERS     DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS 
 #define CRT1_OUTPUT_CONTROL_PS_ALLOCATION  DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION
 
-#define CRT2_OUTPUT_CONTROL_PARAMETERS     DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS
+#define CRT2_OUTPUT_CONTROL_PARAMETERS     DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS 
 #define CRT2_OUTPUT_CONTROL_PS_ALLOCATION  DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION
 
 #define CV1_OUTPUT_CONTROL_PARAMETERS      DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS
@@ -782,397 +980,550 @@ typedef struct _DISPLAY_DEVICE_OUTPUT_CO
 #define DVO_OUTPUT_CONTROL_PS_ALLOCATION   DIG_TRANSMITTER_CONTROL_PS_ALLOCATION
 #define DVO_OUTPUT_CONTROL_PARAMETERS_V3	 DIG_TRANSMITTER_CONTROL_PARAMETERS
 
-/****************************************************************************/
-/*  Structures used by BlankCRTCTable */
-/****************************************************************************/
-typedef struct _BLANK_CRTC_PARAMETERS {
-	UCHAR ucCRTC;		/*  ATOM_CRTC1 or ATOM_CRTC2 */
-	UCHAR ucBlanking;	/*  ATOM_BLANKING or ATOM_BLANKINGOFF */
-	USHORT usBlackColorRCr;
-	USHORT usBlackColorGY;
-	USHORT usBlackColorBCb;
-} BLANK_CRTC_PARAMETERS;
+/****************************************************************************/	
+// Structures used by BlankCRTCTable
+/****************************************************************************/	
+typedef struct _BLANK_CRTC_PARAMETERS
+{
+  UCHAR  ucCRTC;                    	// ATOM_CRTC1 or ATOM_CRTC2
+  UCHAR  ucBlanking;                  // ATOM_BLANKING or ATOM_BLANKINGOFF
+  USHORT usBlackColorRCr;
+  USHORT usBlackColorGY;
+  USHORT usBlackColorBCb;
+}BLANK_CRTC_PARAMETERS;
 #define BLANK_CRTC_PS_ALLOCATION    BLANK_CRTC_PARAMETERS
 
-/****************************************************************************/
-/*  Structures used by EnableCRTCTable */
-/*                     EnableCRTCMemReqTable */
-/*                     UpdateCRTC_DoubleBufferRegistersTable */
-/****************************************************************************/
-typedef struct _ENABLE_CRTC_PARAMETERS {
-	UCHAR ucCRTC;		/*  ATOM_CRTC1 or ATOM_CRTC2 */
-	UCHAR ucEnable;		/*  ATOM_ENABLE or ATOM_DISABLE */
-	UCHAR ucPadding[2];
-} ENABLE_CRTC_PARAMETERS;
+/****************************************************************************/	
+// Structures used by EnableCRTCTable
+//                    EnableCRTCMemReqTable
+//                    UpdateCRTC_DoubleBufferRegistersTable
+/****************************************************************************/	
+typedef struct _ENABLE_CRTC_PARAMETERS
+{
+  UCHAR ucCRTC;                    	  // ATOM_CRTC1 or ATOM_CRTC2
+  UCHAR ucEnable;                     // ATOM_ENABLE or ATOM_DISABLE 
+  UCHAR ucPadding[2];
+}ENABLE_CRTC_PARAMETERS;
 #define ENABLE_CRTC_PS_ALLOCATION   ENABLE_CRTC_PARAMETERS
 
-/****************************************************************************/
-/*  Structures used by SetCRTC_OverScanTable */
-/****************************************************************************/
-typedef struct _SET_CRTC_OVERSCAN_PARAMETERS {
-	USHORT usOverscanRight;	/*  right */
-	USHORT usOverscanLeft;	/*  left */
-	USHORT usOverscanBottom;	/*  bottom */
-	USHORT usOverscanTop;	/*  top */
-	UCHAR ucCRTC;		/*  ATOM_CRTC1 or ATOM_CRTC2 */
-	UCHAR ucPadding[3];
-} SET_CRTC_OVERSCAN_PARAMETERS;
+/****************************************************************************/	
+// Structures used by SetCRTC_OverScanTable
+/****************************************************************************/	
+typedef struct _SET_CRTC_OVERSCAN_PARAMETERS
+{
+  USHORT usOverscanRight;             // right
+  USHORT usOverscanLeft;              // left
+  USHORT usOverscanBottom;            // bottom
+  USHORT usOverscanTop;               // top
+  UCHAR  ucCRTC;                      // ATOM_CRTC1 or ATOM_CRTC2
+  UCHAR  ucPadding[3];
+}SET_CRTC_OVERSCAN_PARAMETERS;
 #define SET_CRTC_OVERSCAN_PS_ALLOCATION  SET_CRTC_OVERSCAN_PARAMETERS
 
-/****************************************************************************/
-/*  Structures used by SetCRTC_ReplicationTable */
-/****************************************************************************/
-typedef struct _SET_CRTC_REPLICATION_PARAMETERS {
-	UCHAR ucH_Replication;	/*  horizontal replication */
-	UCHAR ucV_Replication;	/*  vertical replication */
-	UCHAR usCRTC;		/*  ATOM_CRTC1 or ATOM_CRTC2 */
-	UCHAR ucPadding;
-} SET_CRTC_REPLICATION_PARAMETERS;
+/****************************************************************************/	
+// Structures used by SetCRTC_ReplicationTable
+/****************************************************************************/	
+typedef struct _SET_CRTC_REPLICATION_PARAMETERS
+{
+  UCHAR ucH_Replication;              // horizontal replication
+  UCHAR ucV_Replication;              // vertical replication
+  UCHAR usCRTC;                       // ATOM_CRTC1 or ATOM_CRTC2
+  UCHAR ucPadding;
+}SET_CRTC_REPLICATION_PARAMETERS;
 #define SET_CRTC_REPLICATION_PS_ALLOCATION  SET_CRTC_REPLICATION_PARAMETERS
 
-/****************************************************************************/
-/*  Structures used by SelectCRTC_SourceTable */
-/****************************************************************************/
-typedef struct _SELECT_CRTC_SOURCE_PARAMETERS {
-	UCHAR ucCRTC;		/*  ATOM_CRTC1 or ATOM_CRTC2 */
-	UCHAR ucDevice;		/*  ATOM_DEVICE_CRT1|ATOM_DEVICE_CRT2|.... */
-	UCHAR ucPadding[2];
-} SELECT_CRTC_SOURCE_PARAMETERS;
+/****************************************************************************/	
+// Structures used by SelectCRTC_SourceTable
+/****************************************************************************/	
+typedef struct _SELECT_CRTC_SOURCE_PARAMETERS
+{
+  UCHAR ucCRTC;                    	  // ATOM_CRTC1 or ATOM_CRTC2
+  UCHAR ucDevice;                     // ATOM_DEVICE_CRT1|ATOM_DEVICE_CRT2|....
+  UCHAR ucPadding[2];
+}SELECT_CRTC_SOURCE_PARAMETERS;
 #define SELECT_CRTC_SOURCE_PS_ALLOCATION  SELECT_CRTC_SOURCE_PARAMETERS
 
-typedef struct _SELECT_CRTC_SOURCE_PARAMETERS_V2 {
-	UCHAR ucCRTC;		/*  ATOM_CRTC1 or ATOM_CRTC2 */
-	UCHAR ucEncoderID;	/*  DAC1/DAC2/TVOUT/DIG1/DIG2/DVO */
-	UCHAR ucEncodeMode;	/*  Encoding mode, only valid when using DIG1/DIG2/DVO */
-	UCHAR ucPadding;
-} SELECT_CRTC_SOURCE_PARAMETERS_V2;
+typedef struct _SELECT_CRTC_SOURCE_PARAMETERS_V2
+{
+  UCHAR ucCRTC;                    	  // ATOM_CRTC1 or ATOM_CRTC2
+  UCHAR ucEncoderID;                  // DAC1/DAC2/TVOUT/DIG1/DIG2/DVO
+  UCHAR ucEncodeMode;									// Encoding mode, only valid when using DIG1/DIG2/DVO
+  UCHAR ucPadding;
+}SELECT_CRTC_SOURCE_PARAMETERS_V2;
 
-/* ucEncoderID */
-/* #define ASIC_INT_DAC1_ENCODER_ID                                              0x00 */
-/* #define ASIC_INT_TV_ENCODER_ID                                                                        0x02 */
-/* #define ASIC_INT_DIG1_ENCODER_ID                                                              0x03 */
-/* #define ASIC_INT_DAC2_ENCODER_ID                                                              0x04 */
-/* #define ASIC_EXT_TV_ENCODER_ID                                                                        0x06 */
-/* #define ASIC_INT_DVO_ENCODER_ID                                                                       0x07 */
-/* #define ASIC_INT_DIG2_ENCODER_ID                                                              0x09 */
-/* #define ASIC_EXT_DIG_ENCODER_ID                                                                       0x05 */
+//ucEncoderID
+//#define ASIC_INT_DAC1_ENCODER_ID    						0x00 
+//#define ASIC_INT_TV_ENCODER_ID									0x02
+//#define ASIC_INT_DIG1_ENCODER_ID								0x03
+//#define ASIC_INT_DAC2_ENCODER_ID								0x04
+//#define ASIC_EXT_TV_ENCODER_ID									0x06
+//#define ASIC_INT_DVO_ENCODER_ID									0x07
+//#define ASIC_INT_DIG2_ENCODER_ID								0x09
+//#define ASIC_EXT_DIG_ENCODER_ID									0x05
 
-/* ucEncodeMode */
-/* #define ATOM_ENCODER_MODE_DP                                                                          0 */
-/* #define ATOM_ENCODER_MODE_LVDS                                                                        1 */
-/* #define ATOM_ENCODER_MODE_DVI                                                                         2 */
-/* #define ATOM_ENCODER_MODE_HDMI                                                                        3 */
-/* #define ATOM_ENCODER_MODE_SDVO                                                                        4 */
-/* #define ATOM_ENCODER_MODE_TV                                                                          13 */
-/* #define ATOM_ENCODER_MODE_CV                                                                          14 */
-/* #define ATOM_ENCODER_MODE_CRT                                                                         15 */
+//ucEncodeMode
+//#define ATOM_ENCODER_MODE_DP										0
+//#define ATOM_ENCODER_MODE_LVDS									1
+//#define ATOM_ENCODER_MODE_DVI										2
+//#define ATOM_ENCODER_MODE_HDMI									3
+//#define ATOM_ENCODER_MODE_SDVO									4
+//#define ATOM_ENCODER_MODE_TV										13
+//#define ATOM_ENCODER_MODE_CV										14
+//#define ATOM_ENCODER_MODE_CRT										15
 
-/****************************************************************************/
-/*  Structures used by SetPixelClockTable */
-/*                     GetPixelClockTable */
-/****************************************************************************/
-/* Major revision=1., Minor revision=1 */
-typedef struct _PIXEL_CLOCK_PARAMETERS {
-	USHORT usPixelClock;	/*  in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) */
-	/*  0 means disable PPLL */
-	USHORT usRefDiv;	/*  Reference divider */
-	USHORT usFbDiv;		/*  feedback divider */
-	UCHAR ucPostDiv;	/*  post divider */
-	UCHAR ucFracFbDiv;	/*  fractional feedback divider */
-	UCHAR ucPpll;		/*  ATOM_PPLL1 or ATOM_PPL2 */
-	UCHAR ucRefDivSrc;	/*  ATOM_PJITTER or ATO_NONPJITTER */
-	UCHAR ucCRTC;		/*  Which CRTC uses this Ppll */
-	UCHAR ucPadding;
-} PIXEL_CLOCK_PARAMETERS;
+/****************************************************************************/	
+// Structures used by SetPixelClockTable
+//                    GetPixelClockTable 
+/****************************************************************************/	
+//Major revision=1., Minor revision=1
+typedef struct _PIXEL_CLOCK_PARAMETERS
+{
+  USHORT usPixelClock;                // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div)
+                                      // 0 means disable PPLL
+  USHORT usRefDiv;                    // Reference divider
+  USHORT usFbDiv;                     // feedback divider
+  UCHAR  ucPostDiv;                   // post divider	
+  UCHAR  ucFracFbDiv;                 // fractional feedback divider
+  UCHAR  ucPpll;                      // ATOM_PPLL1 or ATOM_PPL2
+  UCHAR  ucRefDivSrc;                 // ATOM_PJITTER or ATO_NONPJITTER
+  UCHAR  ucCRTC;                      // Which CRTC uses this Ppll
+  UCHAR  ucPadding;
+}PIXEL_CLOCK_PARAMETERS;
 
-/* Major revision=1., Minor revision=2, add ucMiscIfno */
-/* ucMiscInfo: */
+//Major revision=1., Minor revision=2, add ucMiscIfno
+//ucMiscInfo:
 #define MISC_FORCE_REPROG_PIXEL_CLOCK 0x1
 #define MISC_DEVICE_INDEX_MASK        0xF0
 #define MISC_DEVICE_INDEX_SHIFT       4
 
-typedef struct _PIXEL_CLOCK_PARAMETERS_V2 {
-	USHORT usPixelClock;	/*  in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) */
-	/*  0 means disable PPLL */
-	USHORT usRefDiv;	/*  Reference divider */
-	USHORT usFbDiv;		/*  feedback divider */
-	UCHAR ucPostDiv;	/*  post divider */
-	UCHAR ucFracFbDiv;	/*  fractional feedback divider */
-	UCHAR ucPpll;		/*  ATOM_PPLL1 or ATOM_PPL2 */
-	UCHAR ucRefDivSrc;	/*  ATOM_PJITTER or ATO_NONPJITTER */
-	UCHAR ucCRTC;		/*  Which CRTC uses this Ppll */
-	UCHAR ucMiscInfo;	/*  Different bits for different purpose, bit [7:4] as device index, bit[0]=Force prog */
-} PIXEL_CLOCK_PARAMETERS_V2;
+typedef struct _PIXEL_CLOCK_PARAMETERS_V2
+{
+  USHORT usPixelClock;                // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div)
+                                      // 0 means disable PPLL
+  USHORT usRefDiv;                    // Reference divider
+  USHORT usFbDiv;                     // feedback divider
+  UCHAR  ucPostDiv;                   // post divider	
+  UCHAR  ucFracFbDiv;                 // fractional feedback divider
+  UCHAR  ucPpll;                      // ATOM_PPLL1 or ATOM_PPL2
+  UCHAR  ucRefDivSrc;                 // ATOM_PJITTER or ATO_NONPJITTER
+  UCHAR  ucCRTC;                      // Which CRTC uses this Ppll
+  UCHAR  ucMiscInfo;                  // Different bits for different purpose, bit [7:4] as device index, bit[0]=Force prog
+}PIXEL_CLOCK_PARAMETERS_V2;
 
-/* Major revision=1., Minor revision=3, structure/definition change */
-/* ucEncoderMode: */
-/* ATOM_ENCODER_MODE_DP */
-/* ATOM_ENOCDER_MODE_LVDS */
-/* ATOM_ENOCDER_MODE_DVI */
-/* ATOM_ENOCDER_MODE_HDMI */
-/* ATOM_ENOCDER_MODE_SDVO */
-/* ATOM_ENCODER_MODE_TV                                                                          13 */
-/* ATOM_ENCODER_MODE_CV                                                                          14 */
-/* ATOM_ENCODER_MODE_CRT                                                                         15 */
+//Major revision=1., Minor revision=3, structure/definition change
+//ucEncoderMode:
+//ATOM_ENCODER_MODE_DP
+//ATOM_ENOCDER_MODE_LVDS
+//ATOM_ENOCDER_MODE_DVI
+//ATOM_ENOCDER_MODE_HDMI
+//ATOM_ENOCDER_MODE_SDVO
+//ATOM_ENCODER_MODE_TV										13
+//ATOM_ENCODER_MODE_CV										14
+//ATOM_ENCODER_MODE_CRT										15
 
-/* ucDVOConfig */
-/* #define DVO_ENCODER_CONFIG_RATE_SEL                                                   0x01 */
-/* #define DVO_ENCODER_CONFIG_DDR_SPEED                                          0x00 */
-/* #define DVO_ENCODER_CONFIG_SDR_SPEED                                          0x01 */
-/* #define DVO_ENCODER_CONFIG_OUTPUT_SEL                                         0x0c */
-/* #define DVO_ENCODER_CONFIG_LOW12BIT                                                   0x00 */
-/* #define DVO_ENCODER_CONFIG_UPPER12BIT                                         0x04 */
-/* #define DVO_ENCODER_CONFIG_24BIT                                                              0x08 */
+//ucDVOConfig
+//#define DVO_ENCODER_CONFIG_RATE_SEL							0x01
+//#define DVO_ENCODER_CONFIG_DDR_SPEED						0x00
+//#define DVO_ENCODER_CONFIG_SDR_SPEED						0x01
+//#define DVO_ENCODER_CONFIG_OUTPUT_SEL						0x0c
+//#define DVO_ENCODER_CONFIG_LOW12BIT							0x00
+//#define DVO_ENCODER_CONFIG_UPPER12BIT						0x04
+//#define DVO_ENCODER_CONFIG_24BIT								0x08
 
-/* ucMiscInfo: also changed, see below */
+//ucMiscInfo: also changed, see below
 #define PIXEL_CLOCK_MISC_FORCE_PROG_PPLL						0x01
 #define PIXEL_CLOCK_MISC_VGA_MODE										0x02
 #define PIXEL_CLOCK_MISC_CRTC_SEL_MASK							0x04
 #define PIXEL_CLOCK_MISC_CRTC_SEL_CRTC1							0x00
 #define PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2							0x04
 #define PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK			0x08
+#define PIXEL_CLOCK_MISC_REF_DIV_SRC                    0x10
+// V1.4 for RoadRunner
+#define PIXEL_CLOCK_V4_MISC_SS_ENABLE               0x10
+#define PIXEL_CLOCK_V4_MISC_COHERENT_MODE           0x20
 
-typedef struct _PIXEL_CLOCK_PARAMETERS_V3 {
-	USHORT usPixelClock;	/*  in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) */
-	/*  0 means disable PPLL. For VGA PPLL,make sure this value is not 0. */
-	USHORT usRefDiv;	/*  Reference divider */
-	USHORT usFbDiv;		/*  feedback divider */
-	UCHAR ucPostDiv;	/*  post divider */
-	UCHAR ucFracFbDiv;	/*  fractional feedback divider */
-	UCHAR ucPpll;		/*  ATOM_PPLL1 or ATOM_PPL2 */
-	UCHAR ucTransmitterId;	/*  graphic encoder id defined in objectId.h */
-	union {
-		UCHAR ucEncoderMode;	/*  encoder type defined as ATOM_ENCODER_MODE_DP/DVI/HDMI/ */
-		UCHAR ucDVOConfig;	/*  when use DVO, need to know SDR/DDR, 12bit or 24bit */
+typedef struct _PIXEL_CLOCK_PARAMETERS_V3
+{
+  USHORT usPixelClock;                // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div)
+                                      // 0 means disable PPLL. For VGA PPLL,make sure this value is not 0.
+  USHORT usRefDiv;                    // Reference divider
+  USHORT usFbDiv;                     // feedback divider
+  UCHAR  ucPostDiv;                   // post divider	
+  UCHAR  ucFracFbDiv;                 // fractional feedback divider
+  UCHAR  ucPpll;                      // ATOM_PPLL1 or ATOM_PPL2
+  UCHAR  ucTransmitterId;             // graphic encoder id defined in objectId.h
+	union
+	{
+  UCHAR  ucEncoderMode;               // encoder type defined as ATOM_ENCODER_MODE_DP/DVI/HDMI/
+	UCHAR  ucDVOConfig;									// when use DVO, need to know SDR/DDR, 12bit or 24bit
 	};
-	UCHAR ucMiscInfo;	/*  bit[0]=Force program, bit[1]= set pclk for VGA, b[2]= CRTC sel */
-	/*  bit[3]=0:use PPLL for dispclk source, =1: use engine clock for dispclock source */
-} PIXEL_CLOCK_PARAMETERS_V3;
+  UCHAR  ucMiscInfo;                  // bit[0]=Force program, bit[1]= set pclk for VGA, b[2]= CRTC sel
+                                      // bit[3]=0:use PPLL for dispclk source, =1: use engine clock for dispclock source
+                                      // bit[4]=0:use XTALIN as the source of reference divider,=1 use the pre-defined clock as the source of reference divider
+}PIXEL_CLOCK_PARAMETERS_V3;
 
 #define PIXEL_CLOCK_PARAMETERS_LAST			PIXEL_CLOCK_PARAMETERS_V2
 #define GET_PIXEL_CLOCK_PS_ALLOCATION		PIXEL_CLOCK_PARAMETERS_LAST
 
-/****************************************************************************/
-/*  Structures used by AdjustDisplayPllTable */
-/****************************************************************************/
-typedef struct _ADJUST_DISPLAY_PLL_PARAMETERS {
+typedef struct _PIXEL_CLOCK_PARAMETERS_V5
+{
+  UCHAR  ucCRTC;             // ATOM_CRTC1~6, indicate the CRTC controller to 
+                             // drive the pixel clock. not used for DCPLL case.
+  union{
+  UCHAR  ucReserved;
+  UCHAR  ucFracFbDiv;        // [gphan] temporary to prevent build problem.  remove it after driver code is changed.
+  };
+  USHORT usPixelClock;       // target the pixel clock to drive the CRTC timing
+                             // 0 means disable PPLL/DCPLL. 
+  USHORT usFbDiv;            // feedback divider integer part. 
+  UCHAR  ucPostDiv;          // post divider. 
+  UCHAR  ucRefDiv;           // Reference divider
+  UCHAR  ucPpll;             // ATOM_PPLL1/ATOM_PPLL2/ATOM_DCPLL
+  UCHAR  ucTransmitterID;    // ASIC encoder id defined in objectId.h, 
+                             // indicate which graphic encoder will be used. 
+  UCHAR  ucEncoderMode;      // Encoder mode: 
+  UCHAR  ucMiscInfo;         // bit[0]= Force program PPLL 
+                             // bit[1]= when VGA timing is used. 
+                             // bit[3:2]= HDMI panel bit depth: =0: 24bpp =1:30bpp, =2:32bpp
+                             // bit[4]= RefClock source for PPLL. 
+                             // =0: XTLAIN( default mode )
+	                           // =1: other external clock source, which is pre-defined
+                             //     by VBIOS depend on the feature required.
+                             // bit[7:5]: reserved.
+  ULONG  ulFbDivDecFrac;     // 20 bit feedback divider decimal fraction part, range from 1~999999 ( 0.000001 to 0.999999 )
+
+}PIXEL_CLOCK_PARAMETERS_V5;
+
+#define PIXEL_CLOCK_V5_MISC_FORCE_PROG_PPLL					0x01
+#define PIXEL_CLOCK_V5_MISC_VGA_MODE								0x02
+#define PIXEL_CLOCK_V5_MISC_HDMI_BPP_MASK           0x0c
+#define PIXEL_CLOCK_V5_MISC_HDMI_24BPP              0x00
+#define PIXEL_CLOCK_V5_MISC_HDMI_30BPP              0x04
+#define PIXEL_CLOCK_V5_MISC_HDMI_32BPP              0x08
+#define PIXEL_CLOCK_V5_MISC_REF_DIV_SRC             0x10
+
+typedef struct _GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V2
+{
+  PIXEL_CLOCK_PARAMETERS_V3 sDispClkInput;
+}GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V2;
+
+typedef struct _GET_DISP_PLL_STATUS_OUTPUT_PARAMETERS_V2
+{
+  UCHAR  ucStatus;
+  UCHAR  ucRefDivSrc;                 // =1: reference clock source from XTALIN, =0: source from PCIE ref clock
+  UCHAR  ucReserved[2];
+}GET_DISP_PLL_STATUS_OUTPUT_PARAMETERS_V2;
+
+typedef struct _GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V3
+{
+  PIXEL_CLOCK_PARAMETERS_V5 sDispClkInput;
+}GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V3;
+
+/****************************************************************************/	
+// Structures used by AdjustDisplayPllTable
+/****************************************************************************/	
+typedef struct _ADJUST_DISPLAY_PLL_PARAMETERS
+{
 	USHORT usPixelClock;
 	UCHAR ucTransmitterID;
 	UCHAR ucEncodeMode;
-	union {
-		UCHAR ucDVOConfig;	/* if DVO, need passing link rate and output 12bitlow or 24bit */
-		UCHAR ucConfig;	/* if none DVO, not defined yet */
+	union
+	{
+		UCHAR ucDVOConfig;									//if DVO, need passing link rate and output 12bitlow or 24bit
+		UCHAR ucConfig;											//if none DVO, not defined yet
 	};
 	UCHAR ucReserved[3];
-} ADJUST_DISPLAY_PLL_PARAMETERS;
+}ADJUST_DISPLAY_PLL_PARAMETERS;
 
 #define ADJUST_DISPLAY_CONFIG_SS_ENABLE       0x10
-
 #define ADJUST_DISPLAY_PLL_PS_ALLOCATION			ADJUST_DISPLAY_PLL_PARAMETERS
 
-/****************************************************************************/
-/*  Structures used by EnableYUVTable */
-/****************************************************************************/
-typedef struct _ENABLE_YUV_PARAMETERS {
-	UCHAR ucEnable;		/*  ATOM_ENABLE:Enable YUV or ATOM_DISABLE:Disable YUV (RGB) */
-	UCHAR ucCRTC;		/*  Which CRTC needs this YUV or RGB format */
-	UCHAR ucPadding[2];
-} ENABLE_YUV_PARAMETERS;
+typedef struct _ADJUST_DISPLAY_PLL_INPUT_PARAMETERS_V3
+{
+	USHORT usPixelClock;                    // target pixel clock
+	UCHAR ucTransmitterID;                  // transmitter id defined in objectid.h
+	UCHAR ucEncodeMode;                     // encoder mode: CRT, LVDS, DP, TMDS or HDMI
+  UCHAR ucDispPllConfig;                 // display pll configure parameter defined as following DISPPLL_CONFIG_XXXX
+	UCHAR ucReserved[3];
+}ADJUST_DISPLAY_PLL_INPUT_PARAMETERS_V3;
+
+// usDispPllConfig v1.2 for RoadRunner
+#define DISPPLL_CONFIG_DVO_RATE_SEL                0x0001     // need only when ucTransmitterID = DVO
+#define DISPPLL_CONFIG_DVO_DDR_SPEED               0x0000     // need only when ucTransmitterID = DVO
+#define DISPPLL_CONFIG_DVO_SDR_SPEED               0x0001     // need only when ucTransmitterID = DVO
+#define DISPPLL_CONFIG_DVO_OUTPUT_SEL              0x000c     // need only when ucTransmitterID = DVO
+#define DISPPLL_CONFIG_DVO_LOW12BIT                0x0000     // need only when ucTransmitterID = DVO
+#define DISPPLL_CONFIG_DVO_UPPER12BIT              0x0004     // need only when ucTransmitterID = DVO
+#define DISPPLL_CONFIG_DVO_24BIT                   0x0008     // need only when ucTransmitterID = DVO
+#define DISPPLL_CONFIG_SS_ENABLE                   0x0010     // Only used when ucEncoderMode = DP or LVDS
+#define DISPPLL_CONFIG_COHERENT_MODE               0x0020     // Only used when ucEncoderMode = TMDS or HDMI
+#define DISPPLL_CONFIG_DUAL_LINK                   0x0040     // Only used when ucEncoderMode = TMDS or LVDS
+
+
+typedef struct _ADJUST_DISPLAY_PLL_OUTPUT_PARAMETERS_V3
+{
+  ULONG ulDispPllFreq;                 // return display PPLL freq which is used to generate the pixclock, and related idclk, symclk etc
+  UCHAR ucRefDiv;                      // if it is none-zero, it is used to be calculated the other ppll parameter fb_divider and post_div ( if it is not given )
+  UCHAR ucPostDiv;                     // if it is none-zero, it is used to be calculated the other ppll parameter fb_divider
+  UCHAR ucReserved[2];  
+}ADJUST_DISPLAY_PLL_OUTPUT_PARAMETERS_V3;
+
+typedef struct _ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3
+{
+  union 
+  {
+    ADJUST_DISPLAY_PLL_INPUT_PARAMETERS_V3  sInput;
+    ADJUST_DISPLAY_PLL_OUTPUT_PARAMETERS_V3 sOutput;
+  };
+} ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3;
+
+/****************************************************************************/	
+// Structures used by EnableYUVTable
+/****************************************************************************/	
+typedef struct _ENABLE_YUV_PARAMETERS
+{
+  UCHAR ucEnable;                     // ATOM_ENABLE:Enable YUV or ATOM_DISABLE:Disable YUV (RGB)
+  UCHAR ucCRTC;                       // Which CRTC needs this YUV or RGB format
+  UCHAR ucPadding[2];
+}ENABLE_YUV_PARAMETERS;
 #define ENABLE_YUV_PS_ALLOCATION ENABLE_YUV_PARAMETERS
 
-/****************************************************************************/
-/*  Structures used by GetMemoryClockTable */
-/****************************************************************************/
-typedef struct _GET_MEMORY_CLOCK_PARAMETERS {
-	ULONG ulReturnMemoryClock;	/*  current memory speed in 10KHz unit */
+/****************************************************************************/	
+// Structures used by GetMemoryClockTable
+/****************************************************************************/	
+typedef struct _GET_MEMORY_CLOCK_PARAMETERS
+{
+  ULONG ulReturnMemoryClock;          // current memory speed in 10KHz unit
 } GET_MEMORY_CLOCK_PARAMETERS;
 #define GET_MEMORY_CLOCK_PS_ALLOCATION  GET_MEMORY_CLOCK_PARAMETERS
 
-/****************************************************************************/
-/*  Structures used by GetEngineClockTable */
-/****************************************************************************/
-typedef struct _GET_ENGINE_CLOCK_PARAMETERS {
-	ULONG ulReturnEngineClock;	/*  current engine speed in 10KHz unit */
+/****************************************************************************/	
+// Structures used by GetEngineClockTable
+/****************************************************************************/	
+typedef struct _GET_ENGINE_CLOCK_PARAMETERS
+{
+  ULONG ulReturnEngineClock;          // current engine speed in 10KHz unit
 } GET_ENGINE_CLOCK_PARAMETERS;
 #define GET_ENGINE_CLOCK_PS_ALLOCATION  GET_ENGINE_CLOCK_PARAMETERS
 
-/****************************************************************************/
-/*  Following Structures and constant may be obsolete */
-/****************************************************************************/
-/* Maxium 8 bytes,the data read in will be placed in the parameter space. */
-/* Read operaion successeful when the paramter space is non-zero, otherwise read operation failed */
-typedef struct _READ_EDID_FROM_HW_I2C_DATA_PARAMETERS {
-	USHORT usPrescale;	/* Ratio between Engine clock and I2C clock */
-	USHORT usVRAMAddress;	/* Adress in Frame Buffer where to pace raw EDID */
-	USHORT usStatus;	/* When use output: lower byte EDID checksum, high byte hardware status */
-	/* WHen use input:  lower byte as 'byte to read':currently limited to 128byte or 1byte */
-	UCHAR ucSlaveAddr;	/* Read from which slave */
-	UCHAR ucLineNumber;	/* Read from which HW assisted line */
-} READ_EDID_FROM_HW_I2C_DATA_PARAMETERS;
+/****************************************************************************/	
+// Following Structures and constant may be obsolete
+/****************************************************************************/	
+//Maxium 8 bytes,the data read in will be placed in the parameter space.
+//Read operaion successeful when the paramter space is non-zero, otherwise read operation failed
+typedef struct _READ_EDID_FROM_HW_I2C_DATA_PARAMETERS
+{
+  USHORT    usPrescale;         //Ratio between Engine clock and I2C clock
+  USHORT    usVRAMAddress;      //Adress in Frame Buffer where to pace raw EDID
+  USHORT    usStatus;           //When use output: lower byte EDID checksum, high byte hardware status
+                                //WHen use input:  lower byte as 'byte to read':currently limited to 128byte or 1byte
+  UCHAR     ucSlaveAddr;        //Read from which slave
+  UCHAR     ucLineNumber;       //Read from which HW assisted line
+}READ_EDID_FROM_HW_I2C_DATA_PARAMETERS;
 #define READ_EDID_FROM_HW_I2C_DATA_PS_ALLOCATION  READ_EDID_FROM_HW_I2C_DATA_PARAMETERS
 
+
 #define  ATOM_WRITE_I2C_FORMAT_PSOFFSET_PSDATABYTE                  0
 #define  ATOM_WRITE_I2C_FORMAT_PSOFFSET_PSTWODATABYTES              1
 #define  ATOM_WRITE_I2C_FORMAT_PSCOUNTER_PSOFFSET_IDDATABLOCK       2
 #define  ATOM_WRITE_I2C_FORMAT_PSCOUNTER_IDOFFSET_PLUS_IDDATABLOCK  3
 #define  ATOM_WRITE_I2C_FORMAT_IDCOUNTER_IDOFFSET_IDDATABLOCK       4
 
-typedef struct _WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS {
-	USHORT usPrescale;	/* Ratio between Engine clock and I2C clock */
-	USHORT usByteOffset;	/* Write to which byte */
-	/* Upper portion of usByteOffset is Format of data */
-	/* 1bytePS+offsetPS */
-	/* 2bytesPS+offsetPS */
-	/* blockID+offsetPS */
-	/* blockID+offsetID */
-	/* blockID+counterID+offsetID */
-	UCHAR ucData;		/* PS data1 */
-	UCHAR ucStatus;		/* Status byte 1=success, 2=failure, Also is used as PS data2 */
-	UCHAR ucSlaveAddr;	/* Write to which slave */
-	UCHAR ucLineNumber;	/* Write from which HW assisted line */
-} WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS;
+typedef struct _WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS
+{
+  USHORT    usPrescale;         //Ratio between Engine clock and I2C clock
+  USHORT    usByteOffset;       //Write to which byte
+                                //Upper portion of usByteOffset is Format of data 
+                                //1bytePS+offsetPS
+                                //2bytesPS+offsetPS
+                                //blockID+offsetPS
+                                //blockID+offsetID
+                                //blockID+counterID+offsetID
+  UCHAR     ucData;             //PS data1
+  UCHAR     ucStatus;           //Status byte 1=success, 2=failure, Also is used as PS data2
+  UCHAR     ucSlaveAddr;        //Write to which slave
+  UCHAR     ucLineNumber;       //Write from which HW assisted line
+}WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS;
 
 #define WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION  WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS
 
-typedef struct _SET_UP_HW_I2C_DATA_PARAMETERS {
-	USHORT usPrescale;	/* Ratio between Engine clock and I2C clock */
-	UCHAR ucSlaveAddr;	/* Write to which slave */
-	UCHAR ucLineNumber;	/* Write from which HW assisted line */
-} SET_UP_HW_I2C_DATA_PARAMETERS;
+typedef struct _SET_UP_HW_I2C_DATA_PARAMETERS
+{
+  USHORT    usPrescale;         //Ratio between Engine clock and I2C clock
+  UCHAR     ucSlaveAddr;        //Write to which slave
+  UCHAR     ucLineNumber;       //Write from which HW assisted line
+}SET_UP_HW_I2C_DATA_PARAMETERS;
+
 
 /**************************************************************************/
 #define SPEED_FAN_CONTROL_PS_ALLOCATION   WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS
 
-/****************************************************************************/
-/*  Structures used by PowerConnectorDetectionTable */
-/****************************************************************************/
-typedef struct _POWER_CONNECTOR_DETECTION_PARAMETERS {
-	UCHAR ucPowerConnectorStatus;	/* Used for return value 0: detected, 1:not detected */
-	UCHAR ucPwrBehaviorId;
-	USHORT usPwrBudget;	/* how much power currently boot to in unit of watt */
-} POWER_CONNECTOR_DETECTION_PARAMETERS;
+/****************************************************************************/	
+// Structures used by PowerConnectorDetectionTable
+/****************************************************************************/	
+typedef struct	_POWER_CONNECTOR_DETECTION_PARAMETERS
+{
+  UCHAR   ucPowerConnectorStatus;      //Used for return value 0: detected, 1:not detected
+	UCHAR   ucPwrBehaviorId;							
+	USHORT	usPwrBudget;								 //how much power currently boot to in unit of watt
+}POWER_CONNECTOR_DETECTION_PARAMETERS;
 
-typedef struct POWER_CONNECTOR_DETECTION_PS_ALLOCATION {
-	UCHAR ucPowerConnectorStatus;	/* Used for return value 0: detected, 1:not detected */
-	UCHAR ucReserved;
-	USHORT usPwrBudget;	/* how much power currently boot to in unit of watt */
-	WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved;
-} POWER_CONNECTOR_DETECTION_PS_ALLOCATION;
+typedef struct POWER_CONNECTOR_DETECTION_PS_ALLOCATION
+{                               
+  UCHAR   ucPowerConnectorStatus;      //Used for return value 0: detected, 1:not detected
+	UCHAR   ucReserved;
+	USHORT	usPwrBudget;								 //how much power currently boot to in unit of watt
+  WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION    sReserved;
+}POWER_CONNECTOR_DETECTION_PS_ALLOCATION;
 
 /****************************LVDS SS Command Table Definitions**********************/
 
-/****************************************************************************/
-/*  Structures used by EnableSpreadSpectrumOnPPLLTable */
-/****************************************************************************/
-typedef struct _ENABLE_LVDS_SS_PARAMETERS {
-	USHORT usSpreadSpectrumPercentage;
-	UCHAR ucSpreadSpectrumType;	/* Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD */
-	UCHAR ucSpreadSpectrumStepSize_Delay;	/* bits3:2 SS_STEP_SIZE; bit 6:4 SS_DELAY */
-	UCHAR ucEnable;		/* ATOM_ENABLE or ATOM_DISABLE */
-	UCHAR ucPadding[3];
-} ENABLE_LVDS_SS_PARAMETERS;
+/****************************************************************************/	
+// Structures used by EnableSpreadSpectrumOnPPLLTable
+/****************************************************************************/	
+typedef struct	_ENABLE_LVDS_SS_PARAMETERS
+{
+  USHORT  usSpreadSpectrumPercentage;       
+  UCHAR   ucSpreadSpectrumType;           //Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD
+  UCHAR   ucSpreadSpectrumStepSize_Delay; //bits3:2 SS_STEP_SIZE; bit 6:4 SS_DELAY
+  UCHAR   ucEnable;                       //ATOM_ENABLE or ATOM_DISABLE
+  UCHAR   ucPadding[3];
+}ENABLE_LVDS_SS_PARAMETERS;
 
-/* ucTableFormatRevision=1,ucTableContentRevision=2 */
-typedef struct _ENABLE_LVDS_SS_PARAMETERS_V2 {
-	USHORT usSpreadSpectrumPercentage;
-	UCHAR ucSpreadSpectrumType;	/* Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD */
-	UCHAR ucSpreadSpectrumStep;	/*  */
-	UCHAR ucEnable;		/* ATOM_ENABLE or ATOM_DISABLE */
-	UCHAR ucSpreadSpectrumDelay;
-	UCHAR ucSpreadSpectrumRange;
-	UCHAR ucPadding;
-} ENABLE_LVDS_SS_PARAMETERS_V2;
+//ucTableFormatRevision=1,ucTableContentRevision=2
+typedef struct	_ENABLE_LVDS_SS_PARAMETERS_V2
+{
+  USHORT  usSpreadSpectrumPercentage;       
+  UCHAR   ucSpreadSpectrumType;           //Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD
+  UCHAR   ucSpreadSpectrumStep;           //
+  UCHAR   ucEnable;                       //ATOM_ENABLE or ATOM_DISABLE
+  UCHAR   ucSpreadSpectrumDelay;
+  UCHAR   ucSpreadSpectrumRange;
+  UCHAR   ucPadding;
+}ENABLE_LVDS_SS_PARAMETERS_V2;
 
-/* This new structure is based on ENABLE_LVDS_SS_PARAMETERS but expands to SS on PPLL, so other devices can use SS. */
-typedef struct _ENABLE_SPREAD_SPECTRUM_ON_PPLL {
-	USHORT usSpreadSpectrumPercentage;
-	UCHAR ucSpreadSpectrumType;	/*  Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD */
-	UCHAR ucSpreadSpectrumStep;	/*  */
-	UCHAR ucEnable;		/*  ATOM_ENABLE or ATOM_DISABLE */
-	UCHAR ucSpreadSpectrumDelay;
-	UCHAR ucSpreadSpectrumRange;
-	UCHAR ucPpll;		/*  ATOM_PPLL1/ATOM_PPLL2 */
-} ENABLE_SPREAD_SPECTRUM_ON_PPLL;
+//This new structure is based on ENABLE_LVDS_SS_PARAMETERS but expands to SS on PPLL, so other devices can use SS.
+typedef struct	_ENABLE_SPREAD_SPECTRUM_ON_PPLL
+{
+  USHORT  usSpreadSpectrumPercentage;
+  UCHAR   ucSpreadSpectrumType;           // Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD
+  UCHAR   ucSpreadSpectrumStep;           //
+  UCHAR   ucEnable;                       // ATOM_ENABLE or ATOM_DISABLE
+  UCHAR   ucSpreadSpectrumDelay;
+  UCHAR   ucSpreadSpectrumRange;
+  UCHAR   ucPpll;												  // ATOM_PPLL1/ATOM_PPLL2
+}ENABLE_SPREAD_SPECTRUM_ON_PPLL;
+
+typedef struct _ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2
+{
+  USHORT  usSpreadSpectrumPercentage;
+  UCHAR   ucSpreadSpectrumType;	        // Bit[0]: 0-Down Spread,1-Center Spread. 
+                                        // Bit[1]: 1-Ext. 0-Int. 
+                                        // Bit[3:2]: =0 P1PLL =1 P2PLL =2 DCPLL
+                                        // Bits[7:4] reserved
+  UCHAR   ucEnable;	                    // ATOM_ENABLE or ATOM_DISABLE
+  USHORT  usSpreadSpectrumAmount;      	// Includes SS_AMOUNT_FBDIV[7:0] and SS_AMOUNT_NFRAC_SLIP[11:8]    
+  USHORT  usSpreadSpectrumStep;	        // SS_STEP_SIZE_DSFRAC
+}ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2;
+
+#define ATOM_PPLL_SS_TYPE_V2_DOWN_SPREAD      0x00
+#define ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD    0x01
+#define ATOM_PPLL_SS_TYPE_V2_EXT_SPREAD       0x02
+#define ATOM_PPLL_SS_TYPE_V2_PPLL_SEL_MASK    0x0c
+#define ATOM_PPLL_SS_TYPE_V2_P1PLL            0x00
+#define ATOM_PPLL_SS_TYPE_V2_P2PLL            0x04
+#define ATOM_PPLL_SS_TYPE_V2_DCPLL            0x08
+#define ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK     0x00FF
+#define ATOM_PPLL_SS_AMOUNT_V2_FBDIV_SHIFT    0
+#define ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK     0x0F00
+#define ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT    8
 
 #define ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION  ENABLE_SPREAD_SPECTRUM_ON_PPLL
 
 /**************************************************************************/
 
-typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION {
-	PIXEL_CLOCK_PARAMETERS sPCLKInput;
-	ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;	/* Caller doesn't need to init this portion */
-} SET_PIXEL_CLOCK_PS_ALLOCATION;
+typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION
+{
+  PIXEL_CLOCK_PARAMETERS sPCLKInput;
+  ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;//Caller doesn't need to init this portion 
+}SET_PIXEL_CLOCK_PS_ALLOCATION;
 
 #define ENABLE_VGA_RENDER_PS_ALLOCATION   SET_PIXEL_CLOCK_PS_ALLOCATION
 
-/****************************************************************************/
-/*  Structures used by ### */
-/****************************************************************************/
-typedef struct _MEMORY_TRAINING_PARAMETERS {
-	ULONG ulTargetMemoryClock;	/* In 10Khz unit */
-} MEMORY_TRAINING_PARAMETERS;
+/****************************************************************************/	
+// Structures used by ###
+/****************************************************************************/	
+typedef struct	_MEMORY_TRAINING_PARAMETERS
+{
+  ULONG ulTargetMemoryClock;          //In 10Khz unit
+}MEMORY_TRAINING_PARAMETERS;
 #define MEMORY_TRAINING_PS_ALLOCATION MEMORY_TRAINING_PARAMETERS
 
+
 /****************************LVDS and other encoder command table definitions **********************/
 
-/****************************************************************************/
-/*  Structures used by LVDSEncoderControlTable   (Before DCE30) */
-/*                     LVTMAEncoderControlTable  (Before DCE30) */
-/*                     TMDSAEncoderControlTable  (Before DCE30) */
-/****************************************************************************/
-typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS {
-	USHORT usPixelClock;	/*  in 10KHz; for bios convenient */
-	UCHAR ucMisc;		/*  bit0=0: Enable single link */
-	/*      =1: Enable dual link */
-	/*  Bit1=0: 666RGB */
-	/*      =1: 888RGB */
-	UCHAR ucAction;		/*  0: turn off encoder */
-	/*  1: setup and turn on encoder */
-} LVDS_ENCODER_CONTROL_PARAMETERS;
 
-#define LVDS_ENCODER_CONTROL_PS_ALLOCATION  LVDS_ENCODER_CONTROL_PARAMETERS
+/****************************************************************************/	
+// Structures used by LVDSEncoderControlTable   (Before DCE30)
+//                    LVTMAEncoderControlTable  (Before DCE30)
+//                    TMDSAEncoderControlTable  (Before DCE30)
+/****************************************************************************/	
+typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS
+{
+  USHORT usPixelClock;  // in 10KHz; for bios convenient
+  UCHAR  ucMisc;        // bit0=0: Enable single link
+                        //     =1: Enable dual link
+                        // Bit1=0: 666RGB
+                        //     =1: 888RGB
+  UCHAR  ucAction;      // 0: turn off encoder
+                        // 1: setup and turn on encoder
+}LVDS_ENCODER_CONTROL_PARAMETERS;
 
+#define LVDS_ENCODER_CONTROL_PS_ALLOCATION  LVDS_ENCODER_CONTROL_PARAMETERS
+   
 #define TMDS1_ENCODER_CONTROL_PARAMETERS    LVDS_ENCODER_CONTROL_PARAMETERS
 #define TMDS1_ENCODER_CONTROL_PS_ALLOCATION TMDS1_ENCODER_CONTROL_PARAMETERS
 
 #define TMDS2_ENCODER_CONTROL_PARAMETERS    TMDS1_ENCODER_CONTROL_PARAMETERS
 #define TMDS2_ENCODER_CONTROL_PS_ALLOCATION TMDS2_ENCODER_CONTROL_PARAMETERS
 
-/* ucTableFormatRevision=1,ucTableContentRevision=2 */
-typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS_V2 {
-	USHORT usPixelClock;	/*  in 10KHz; for bios convenient */
-	UCHAR ucMisc;		/*  see PANEL_ENCODER_MISC_xx definitions below */
-	UCHAR ucAction;		/*  0: turn off encoder */
-	/*  1: setup and turn on encoder */
-	UCHAR ucTruncate;	/*  bit0=0: Disable truncate */
-	/*      =1: Enable truncate */
-	/*  bit4=0: 666RGB */
-	/*      =1: 888RGB */
-	UCHAR ucSpatial;	/*  bit0=0: Disable spatial dithering */
-	/*      =1: Enable spatial dithering */
-	/*  bit4=0: 666RGB */
-	/*      =1: 888RGB */
-	UCHAR ucTemporal;	/*  bit0=0: Disable temporal dithering */
-	/*      =1: Enable temporal dithering */
-	/*  bit4=0: 666RGB */
-	/*      =1: 888RGB */
-	/*  bit5=0: Gray level 2 */
-	/*      =1: Gray level 4 */
-	UCHAR ucFRC;		/*  bit4=0: 25FRC_SEL pattern E */
-	/*      =1: 25FRC_SEL pattern F */
-	/*  bit6:5=0: 50FRC_SEL pattern A */
-	/*        =1: 50FRC_SEL pattern B */
-	/*        =2: 50FRC_SEL pattern C */
-	/*        =3: 50FRC_SEL pattern D */
-	/*  bit7=0: 75FRC_SEL pattern E */
-	/*      =1: 75FRC_SEL pattern F */
-} LVDS_ENCODER_CONTROL_PARAMETERS_V2;
 
-#define LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2  LVDS_ENCODER_CONTROL_PARAMETERS_V2
+//ucTableFormatRevision=1,ucTableContentRevision=2
+typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS_V2
+{
+  USHORT usPixelClock;  // in 10KHz; for bios convenient
+  UCHAR  ucMisc;        // see PANEL_ENCODER_MISC_xx defintions below
+  UCHAR  ucAction;      // 0: turn off encoder
+                        // 1: setup and turn on encoder
+  UCHAR  ucTruncate;    // bit0=0: Disable truncate
+                        //     =1: Enable truncate
+                        // bit4=0: 666RGB
+                        //     =1: 888RGB
+  UCHAR  ucSpatial;     // bit0=0: Disable spatial dithering
+                        //     =1: Enable spatial dithering
+                        // bit4=0: 666RGB
+                        //     =1: 888RGB
+  UCHAR  ucTemporal;    // bit0=0: Disable temporal dithering
+                        //     =1: Enable temporal dithering
+                        // bit4=0: 666RGB
+                        //     =1: 888RGB
+                        // bit5=0: Gray level 2
+                        //     =1: Gray level 4
+  UCHAR  ucFRC;         // bit4=0: 25FRC_SEL pattern E
+                        //     =1: 25FRC_SEL pattern F
+                        // bit6:5=0: 50FRC_SEL pattern A
+                        //       =1: 50FRC_SEL pattern B
+                        //       =2: 50FRC_SEL pattern C
+                        //       =3: 50FRC_SEL pattern D
+                        // bit7=0: 75FRC_SEL pattern E
+                        //     =1: 75FRC_SEL pattern F
+}LVDS_ENCODER_CONTROL_PARAMETERS_V2;
 
+#define LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2  LVDS_ENCODER_CONTROL_PARAMETERS_V2
+   
 #define TMDS1_ENCODER_CONTROL_PARAMETERS_V2    LVDS_ENCODER_CONTROL_PARAMETERS_V2
 #define TMDS1_ENCODER_CONTROL_PS_ALLOCATION_V2 TMDS1_ENCODER_CONTROL_PARAMETERS_V2
-
+  
 #define TMDS2_ENCODER_CONTROL_PARAMETERS_V2    TMDS1_ENCODER_CONTROL_PARAMETERS_V2
 #define TMDS2_ENCODER_CONTROL_PS_ALLOCATION_V2 TMDS2_ENCODER_CONTROL_PARAMETERS_V2
 
@@ -1185,38 +1536,42 @@ typedef struct _LVDS_ENCODER_CONTROL_PAR
 #define TMDS2_ENCODER_CONTROL_PARAMETERS_V3    LVDS_ENCODER_CONTROL_PARAMETERS_V3
 #define TMDS2_ENCODER_CONTROL_PS_ALLOCATION_V3 TMDS2_ENCODER_CONTROL_PARAMETERS_V3
 
-/****************************************************************************/
-/*  Structures used by ### */
-/****************************************************************************/
-typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS {
-	UCHAR ucEnable;		/*  Enable or Disable External TMDS encoder */
-	UCHAR ucMisc;		/*  Bit0=0:Enable Single link;=1:Enable Dual link;Bit1 {=0:666RGB, =1:888RGB} */
-	UCHAR ucPadding[2];
-} ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS;
+/****************************************************************************/	
+// Structures used by ###
+/****************************************************************************/	
+typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS
+{                               
+  UCHAR    ucEnable;            // Enable or Disable External TMDS encoder
+  UCHAR    ucMisc;              // Bit0=0:Enable Single link;=1:Enable Dual link;Bit1 {=0:666RGB, =1:888RGB}
+  UCHAR    ucPadding[2];
+}ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS;
 
-typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION {
-	ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS sXTmdsEncoder;
-	WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved;	/* Caller doesn't need to init this portion */
-} ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION;
+typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION
+{                               
+  ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS    sXTmdsEncoder;
+  WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION   sReserved;     //Caller doesn't need to init this portion
+}ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION;
 
 #define ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS_V2  LVDS_ENCODER_CONTROL_PARAMETERS_V2
 
-typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION_V2 {
-	ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS_V2 sXTmdsEncoder;
-	WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved;	/* Caller doesn't need to init this portion */
-} ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION_V2;
+typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION_V2
+{                               
+  ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS_V2    sXTmdsEncoder;
+  WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION      sReserved;     //Caller doesn't need to init this portion
+}ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION_V2;
 
-typedef struct _EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION {
-	DIG_ENCODER_CONTROL_PARAMETERS sDigEncoder;
-	WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved;
-} EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION;
+typedef struct _EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION
+{
+  DIG_ENCODER_CONTROL_PARAMETERS            sDigEncoder;
+  WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved;
+}EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION;
 
-/****************************************************************************/
-/*  Structures used by DVOEncoderControlTable */
-/****************************************************************************/
-/* ucTableFormatRevision=1,ucTableContentRevision=3 */
+/****************************************************************************/	
+// Structures used by DVOEncoderControlTable
+/****************************************************************************/	
+//ucTableFormatRevision=1,ucTableContentRevision=3
 
-/* ucDVOConfig: */
+//ucDVOConfig:
 #define DVO_ENCODER_CONFIG_RATE_SEL							0x01
 #define DVO_ENCODER_CONFIG_DDR_SPEED						0x00
 #define DVO_ENCODER_CONFIG_SDR_SPEED						0x01
@@ -1225,21 +1580,22 @@ typedef struct _EXTERNAL_ENCODER_CONTROL
 #define DVO_ENCODER_CONFIG_UPPER12BIT						0x04
 #define DVO_ENCODER_CONFIG_24BIT								0x08
 
-typedef struct _DVO_ENCODER_CONTROL_PARAMETERS_V3 {
-	USHORT usPixelClock;
-	UCHAR ucDVOConfig;
-	UCHAR ucAction;		/* ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT */
-	UCHAR ucReseved[4];
-} DVO_ENCODER_CONTROL_PARAMETERS_V3;
+typedef struct _DVO_ENCODER_CONTROL_PARAMETERS_V3
+{
+  USHORT usPixelClock; 
+  UCHAR  ucDVOConfig;
+  UCHAR  ucAction;														//ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT
+  UCHAR  ucReseved[4];
+}DVO_ENCODER_CONTROL_PARAMETERS_V3;
 #define DVO_ENCODER_CONTROL_PS_ALLOCATION_V3	DVO_ENCODER_CONTROL_PARAMETERS_V3
 
-/* ucTableFormatRevision=1 */
-/* ucTableContentRevision=3 structure is not changed but usMisc add bit 1 as another input for */
-/*  bit1=0: non-coherent mode */
-/*      =1: coherent mode */
+//ucTableFormatRevision=1
+//ucTableContentRevision=3 structure is not changed but usMisc add bit 1 as another input for 
+// bit1=0: non-coherent mode
+//     =1: coherent mode
 
-/* ========================================================================================== */
-/* Only change is here next time when changing encoder parameter definitions again! */
+//==========================================================================================
+//Only change is here next time when changing encoder parameter definitions again!
 #define LVDS_ENCODER_CONTROL_PARAMETERS_LAST     LVDS_ENCODER_CONTROL_PARAMETERS_V3
 #define LVDS_ENCODER_CONTROL_PS_ALLOCATION_LAST  LVDS_ENCODER_CONTROL_PARAMETERS_LAST
 
@@ -1252,7 +1608,7 @@ typedef struct _DVO_ENCODER_CONTROL_PARA
 #define DVO_ENCODER_CONTROL_PARAMETERS_LAST      DVO_ENCODER_CONTROL_PARAMETERS
 #define DVO_ENCODER_CONTROL_PS_ALLOCATION_LAST   DVO_ENCODER_CONTROL_PS_ALLOCATION
 
-/* ========================================================================================== */
+//==========================================================================================
 #define PANEL_ENCODER_MISC_DUAL                0x01
 #define PANEL_ENCODER_MISC_COHERENT            0x02
 #define	PANEL_ENCODER_MISC_TMDS_LINKB					 0x04
@@ -1281,159 +1637,159 @@ typedef struct _DVO_ENCODER_CONTROL_PARA
 #define PANEL_ENCODER_75FRC_E                  0x00
 #define PANEL_ENCODER_75FRC_F                  0x80
 
-/****************************************************************************/
-/*  Structures used by SetVoltageTable */
-/****************************************************************************/
+/****************************************************************************/	
+// Structures used by SetVoltageTable
+/****************************************************************************/	
 #define SET_VOLTAGE_TYPE_ASIC_VDDC             1
 #define SET_VOLTAGE_TYPE_ASIC_MVDDC            2
 #define SET_VOLTAGE_TYPE_ASIC_MVDDQ            3
 #define SET_VOLTAGE_TYPE_ASIC_VDDCI            4
 #define SET_VOLTAGE_INIT_MODE                  5
-#define SET_VOLTAGE_GET_MAX_VOLTAGE            6	/* Gets the Max. voltage for the soldered Asic */
+#define SET_VOLTAGE_GET_MAX_VOLTAGE            6					//Gets the Max. voltage for the soldered Asic
 
 #define SET_ASIC_VOLTAGE_MODE_ALL_SOURCE       0x1
 #define SET_ASIC_VOLTAGE_MODE_SOURCE_A         0x2
 #define SET_ASIC_VOLTAGE_MODE_SOURCE_B         0x4
 
 #define	SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE      0x0
-#define	SET_ASIC_VOLTAGE_MODE_GET_GPIOVAL      0x1
+#define	SET_ASIC_VOLTAGE_MODE_GET_GPIOVAL      0x1	
 #define	SET_ASIC_VOLTAGE_MODE_GET_GPIOMASK     0x2
 
-typedef struct _SET_VOLTAGE_PARAMETERS {
-	UCHAR ucVoltageType;	/*  To tell which voltage to set up, VDDC/MVDDC/MVDDQ */
-	UCHAR ucVoltageMode;	/*  To set all, to set source A or source B or ... */
-	UCHAR ucVoltageIndex;	/*  An index to tell which voltage level */
-	UCHAR ucReserved;
-} SET_VOLTAGE_PARAMETERS;
-
-typedef struct _SET_VOLTAGE_PARAMETERS_V2 {
-	UCHAR ucVoltageType;	/*  To tell which voltage to set up, VDDC/MVDDC/MVDDQ */
-	UCHAR ucVoltageMode;	/*  Not used, maybe use for state machine for differen power mode */
-	USHORT usVoltageLevel;	/*  real voltage level */
-} SET_VOLTAGE_PARAMETERS_V2;
-
-typedef struct _SET_VOLTAGE_PS_ALLOCATION {
-	SET_VOLTAGE_PARAMETERS sASICSetVoltage;
-	WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved;
-} SET_VOLTAGE_PS_ALLOCATION;
+typedef struct	_SET_VOLTAGE_PARAMETERS
+{
+  UCHAR    ucVoltageType;               // To tell which voltage to set up, VDDC/MVDDC/MVDDQ
+  UCHAR    ucVoltageMode;               // To set all, to set source A or source B or ...
+  UCHAR    ucVoltageIndex;              // An index to tell which voltage level
+  UCHAR    ucReserved;          
+}SET_VOLTAGE_PARAMETERS;
 
-/****************************************************************************/
-/*  Structures used by TVEncoderControlTable */
-/****************************************************************************/
-typedef struct _TV_ENCODER_CONTROL_PARAMETERS {
-	USHORT usPixelClock;	/*  in 10KHz; for bios convenient */
-	UCHAR ucTvStandard;	/*  See definition "ATOM_TV_NTSC ..." */
-	UCHAR ucAction;		/*  0: turn off encoder */
-	/*  1: setup and turn on encoder */
-} TV_ENCODER_CONTROL_PARAMETERS;
+typedef struct	_SET_VOLTAGE_PARAMETERS_V2
+{
+  UCHAR    ucVoltageType;               // To tell which voltage to set up, VDDC/MVDDC/MVDDQ
+  UCHAR    ucVoltageMode;               // Not used, maybe use for state machine for differen power mode
+  USHORT   usVoltageLevel;              // real voltage level
+}SET_VOLTAGE_PARAMETERS_V2;
 
-typedef struct _TV_ENCODER_CONTROL_PS_ALLOCATION {
-	TV_ENCODER_CONTROL_PARAMETERS sTVEncoder;
-	WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved;	/*  Don't set this one */
-} TV_ENCODER_CONTROL_PS_ALLOCATION;
+typedef struct _SET_VOLTAGE_PS_ALLOCATION
+{
+  SET_VOLTAGE_PARAMETERS sASICSetVoltage;
+  WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved;
+}SET_VOLTAGE_PS_ALLOCATION;
 
-/* ==============================Data Table Portion==================================== */
+/****************************************************************************/	
+// Structures used by TVEncoderControlTable
+/****************************************************************************/	
+typedef struct _TV_ENCODER_CONTROL_PARAMETERS
+{
+  USHORT usPixelClock;                // in 10KHz; for bios convenient
+  UCHAR  ucTvStandard;                // See definition "ATOM_TV_NTSC ..."
+  UCHAR  ucAction;                    // 0: turn off encoder
+                                      // 1: setup and turn on encoder
+}TV_ENCODER_CONTROL_PARAMETERS;
 
-#ifdef	UEFI_BUILD
-#define	UTEMP	USHORT
-#define	USHORT	void*
-#endif
+typedef struct _TV_ENCODER_CONTROL_PS_ALLOCATION
+{
+  TV_ENCODER_CONTROL_PARAMETERS sTVEncoder;          
+  WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION    sReserved; // Don't set this one
+}TV_ENCODER_CONTROL_PS_ALLOCATION;
 
-/****************************************************************************/
-/*  Structure used in Data.mtb */
-/****************************************************************************/
-typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES {
-	USHORT UtilityPipeLine;	/*  Offest for the utility to get parser info,Don't change this position! */
-	USHORT MultimediaCapabilityInfo;	/*  Only used by MM Lib,latest version 1.1, not configuable from Bios, need to include the table to build Bios */
-	USHORT MultimediaConfigInfo;	/*  Only used by MM Lib,latest version 2.1, not configuable from Bios, need to include the table to build Bios */
-	USHORT StandardVESA_Timing;	/*  Only used by Bios */
-	USHORT FirmwareInfo;	/*  Shared by various SW components,latest version 1.4 */
-	USHORT DAC_Info;	/*  Will be obsolete from R600 */
-	USHORT LVDS_Info;	/*  Shared by various SW components,latest version 1.1 */
-	USHORT TMDS_Info;	/*  Will be obsolete from R600 */
-	USHORT AnalogTV_Info;	/*  Shared by various SW components,latest version 1.1 */
-	USHORT SupportedDevicesInfo;	/*  Will be obsolete from R600 */
-	USHORT GPIO_I2C_Info;	/*  Shared by various SW components,latest version 1.2 will be used from R600 */
-	USHORT VRAM_UsageByFirmware;	/*  Shared by various SW components,latest version 1.3 will be used from R600 */
-	USHORT GPIO_Pin_LUT;	/*  Shared by various SW components,latest version 1.1 */
-	USHORT VESA_ToInternalModeLUT;	/*  Only used by Bios */
-	USHORT ComponentVideoInfo;	/*  Shared by various SW components,latest version 2.1 will be used from R600 */
-	USHORT PowerPlayInfo;	/*  Shared by various SW components,latest version 2.1,new design from R600 */
-	USHORT CompassionateData;	/*  Will be obsolete from R600 */
-	USHORT SaveRestoreInfo;	/*  Only used by Bios */
-	USHORT PPLL_SS_Info;	/*  Shared by various SW components,latest version 1.2, used to call SS_Info, change to new name because of int ASIC SS info */
-	USHORT OemInfo;		/*  Defined and used by external SW, should be obsolete soon */
-	USHORT XTMDS_Info;	/*  Will be obsolete from R600 */
-	USHORT MclkSS_Info;	/*  Shared by various SW components,latest version 1.1, only enabled when ext SS chip is used */
-	USHORT Object_Header;	/*  Shared by various SW components,latest version 1.1 */
-	USHORT IndirectIOAccess;	/*  Only used by Bios,this table position can't change at all!! */
-	USHORT MC_InitParameter;	/*  Only used by command table */
-	USHORT ASIC_VDDC_Info;	/*  Will be obsolete from R600 */
-	USHORT ASIC_InternalSS_Info;	/*  New tabel name from R600, used to be called "ASIC_MVDDC_Info" */
-	USHORT TV_VideoMode;	/*  Only used by command table */
-	USHORT VRAM_Info;	/*  Only used by command table, latest version 1.3 */
-	USHORT MemoryTrainingInfo;	/*  Used for VBIOS and Diag utility for memory training purpose since R600. the new table rev start from 2.1 */
-	USHORT IntegratedSystemInfo;	/*  Shared by various SW components */
-	USHORT ASIC_ProfilingInfo;	/*  New table name from R600, used to be called "ASIC_VDDCI_Info" for pre-R600 */
-	USHORT VoltageObjectInfo;	/*  Shared by various SW components, latest version 1.1 */
-	USHORT PowerSourceInfo;	/*  Shared by various SW components, latest versoin 1.1 */
-} ATOM_MASTER_LIST_OF_DATA_TABLES;
+//==============================Data Table Portion====================================
 
-#ifdef	UEFI_BUILD
-#define	USHORT	UTEMP
-#endif
+/****************************************************************************/	
+// Structure used in Data.mtb
+/****************************************************************************/	
+typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES
+{
+  USHORT        UtilityPipeLine;	        // Offest for the utility to get parser info,Don't change this position!
+  USHORT        MultimediaCapabilityInfo; // Only used by MM Lib,latest version 1.1, not configuable from Bios, need to include the table to build Bios 
+  USHORT        MultimediaConfigInfo;     // Only used by MM Lib,latest version 2.1, not configuable from Bios, need to include the table to build Bios
+  USHORT        StandardVESA_Timing;      // Only used by Bios
+  USHORT        FirmwareInfo;             // Shared by various SW components,latest version 1.4
+  USHORT        DAC_Info;                 // Will be obsolete from R600
+  USHORT        LVDS_Info;                // Shared by various SW components,latest version 1.1 
+  USHORT        TMDS_Info;                // Will be obsolete from R600
+  USHORT        AnalogTV_Info;            // Shared by various SW components,latest version 1.1 
+  USHORT        SupportedDevicesInfo;     // Will be obsolete from R600
+  USHORT        GPIO_I2C_Info;            // Shared by various SW components,latest version 1.2 will be used from R600           
+  USHORT        VRAM_UsageByFirmware;     // Shared by various SW components,latest version 1.3 will be used from R600
+  USHORT        GPIO_Pin_LUT;             // Shared by various SW components,latest version 1.1
+  USHORT        VESA_ToInternalModeLUT;   // Only used by Bios
+  USHORT        ComponentVideoInfo;       // Shared by various SW components,latest version 2.1 will be used from R600
+  USHORT        PowerPlayInfo;            // Shared by various SW components,latest version 2.1,new design from R600
+  USHORT        CompassionateData;        // Will be obsolete from R600
+  USHORT        SaveRestoreInfo;          // Only used by Bios
+  USHORT        PPLL_SS_Info;             // Shared by various SW components,latest version 1.2, used to call SS_Info, change to new name because of int ASIC SS info
+  USHORT        OemInfo;                  // Defined and used by external SW, should be obsolete soon
+  USHORT        XTMDS_Info;               // Will be obsolete from R600
+  USHORT        MclkSS_Info;              // Shared by various SW components,latest version 1.1, only enabled when ext SS chip is used
+  USHORT        Object_Header;            // Shared by various SW components,latest version 1.1
+  USHORT        IndirectIOAccess;         // Only used by Bios,this table position can't change at all!!
+  USHORT        MC_InitParameter;         // Only used by command table
+  USHORT        ASIC_VDDC_Info;						// Will be obsolete from R600
+  USHORT        ASIC_InternalSS_Info;			// New tabel name from R600, used to be called "ASIC_MVDDC_Info"
+  USHORT        TV_VideoMode;							// Only used by command table
+  USHORT        VRAM_Info;								// Only used by command table, latest version 1.3
+  USHORT        MemoryTrainingInfo;				// Used for VBIOS and Diag utility for memory training purpose since R600. the new table rev start from 2.1
+  USHORT        IntegratedSystemInfo;			// Shared by various SW components
+  USHORT        ASIC_ProfilingInfo;				// New table name from R600, used to be called "ASIC_VDDCI_Info" for pre-R600
+  USHORT        VoltageObjectInfo;				// Shared by various SW components, latest version 1.1
+	USHORT				PowerSourceInfo;					// Shared by various SW components, latest versoin 1.1
+}ATOM_MASTER_LIST_OF_DATA_TABLES;
 
-typedef struct _ATOM_MASTER_DATA_TABLE {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ATOM_MASTER_LIST_OF_DATA_TABLES ListOfDataTables;
-} ATOM_MASTER_DATA_TABLE;
+typedef struct _ATOM_MASTER_DATA_TABLE
+{ 
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  ATOM_MASTER_LIST_OF_DATA_TABLES   ListOfDataTables;
+}ATOM_MASTER_DATA_TABLE;
 
-/****************************************************************************/
-/*  Structure used in MultimediaCapabilityInfoTable */
-/****************************************************************************/
-typedef struct _ATOM_MULTIMEDIA_CAPABILITY_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ULONG ulSignature;	/*  HW info table signature string "$ATI" */
-	UCHAR ucI2C_Type;	/*  I2C type (normal GP_IO, ImpactTV GP_IO, Dedicated I2C pin, etc) */
-	UCHAR ucTV_OutInfo;	/*  Type of TV out supported (3:0) and video out crystal frequency (6:4) and TV data port (7) */
-	UCHAR ucVideoPortInfo;	/*  Provides the video port capabilities */
-	UCHAR ucHostPortInfo;	/*  Provides host port configuration information */
-} ATOM_MULTIMEDIA_CAPABILITY_INFO;
+/****************************************************************************/	
+// Structure used in MultimediaCapabilityInfoTable
+/****************************************************************************/	
+typedef struct _ATOM_MULTIMEDIA_CAPABILITY_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  ULONG                    ulSignature;      // HW info table signature string "$ATI"
+  UCHAR                    ucI2C_Type;       // I2C type (normal GP_IO, ImpactTV GP_IO, Dedicated I2C pin, etc)
+  UCHAR                    ucTV_OutInfo;     // Type of TV out supported (3:0) and video out crystal frequency (6:4) and TV data port (7)
+  UCHAR                    ucVideoPortInfo;  // Provides the video port capabilities
+  UCHAR                    ucHostPortInfo;   // Provides host port configuration information
+}ATOM_MULTIMEDIA_CAPABILITY_INFO;
 
-/****************************************************************************/
-/*  Structure used in MultimediaConfigInfoTable */
-/****************************************************************************/
-typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ULONG ulSignature;	/*  MM info table signature sting "$MMT" */
-	UCHAR ucTunerInfo;	/*  Type of tuner installed on the adapter (4:0) and video input for tuner (7:5) */
-	UCHAR ucAudioChipInfo;	/*  List the audio chip type (3:0) product type (4) and OEM revision (7:5) */
-	UCHAR ucProductID;	/*  Defines as OEM ID or ATI board ID dependent on product type setting */
-	UCHAR ucMiscInfo1;	/*  Tuner voltage (1:0) HW teletext support (3:2) FM audio decoder (5:4) reserved (6) audio scrambling (7) */
-	UCHAR ucMiscInfo2;	/*  I2S input config (0) I2S output config (1) I2S Audio Chip (4:2) SPDIF Output Config (5) reserved (7:6) */
-	UCHAR ucMiscInfo3;	/*  Video Decoder Type (3:0) Video In Standard/Crystal (7:4) */
-	UCHAR ucMiscInfo4;	/*  Video Decoder Host Config (2:0) reserved (7:3) */
-	UCHAR ucVideoInput0Info;	/*  Video Input 0 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) */
-	UCHAR ucVideoInput1Info;	/*  Video Input 1 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) */
-	UCHAR ucVideoInput2Info;	/*  Video Input 2 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) */
-	UCHAR ucVideoInput3Info;	/*  Video Input 3 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) */
-	UCHAR ucVideoInput4Info;	/*  Video Input 4 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) */
-} ATOM_MULTIMEDIA_CONFIG_INFO;
+/****************************************************************************/	
+// Structure used in MultimediaConfigInfoTable
+/****************************************************************************/	
+typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;
+  ULONG                    ulSignature;      // MM info table signature sting "$MMT"
+  UCHAR                    ucTunerInfo;      // Type of tuner installed on the adapter (4:0) and video input for tuner (7:5)
+  UCHAR                    ucAudioChipInfo;  // List the audio chip type (3:0) product type (4) and OEM revision (7:5)
+  UCHAR                    ucProductID;      // Defines as OEM ID or ATI board ID dependent on product type setting
+  UCHAR                    ucMiscInfo1;      // Tuner voltage (1:0) HW teletext support (3:2) FM audio decoder (5:4) reserved (6) audio scrambling (7)
+  UCHAR                    ucMiscInfo2;      // I2S input config (0) I2S output config (1) I2S Audio Chip (4:2) SPDIF Output Config (5) reserved (7:6)
+  UCHAR                    ucMiscInfo3;      // Video Decoder Type (3:0) Video In Standard/Crystal (7:4)
+  UCHAR                    ucMiscInfo4;      // Video Decoder Host Config (2:0) reserved (7:3)
+  UCHAR                    ucVideoInput0Info;// Video Input 0 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6)
+  UCHAR                    ucVideoInput1Info;// Video Input 1 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6)
+  UCHAR                    ucVideoInput2Info;// Video Input 2 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6)
+  UCHAR                    ucVideoInput3Info;// Video Input 3 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6)
+  UCHAR                    ucVideoInput4Info;// Video Input 4 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6)
+}ATOM_MULTIMEDIA_CONFIG_INFO;
 
-/****************************************************************************/
-/*  Structures used in FirmwareInfoTable */
-/****************************************************************************/
+/****************************************************************************/	
+// Structures used in FirmwareInfoTable
+/****************************************************************************/	
 
-/*  usBIOSCapability Definition: */
-/*  Bit 0 = 0: Bios image is not Posted, =1:Bios image is Posted; */
-/*  Bit 1 = 0: Dual CRTC is not supported, =1: Dual CRTC is supported; */
-/*  Bit 2 = 0: Extended Desktop is not supported, =1: Extended Desktop is supported; */
-/*  Others: Reserved */
+// usBIOSCapability Defintion:
+// Bit 0 = 0: Bios image is not Posted, =1:Bios image is Posted; 
+// Bit 1 = 0: Dual CRTC is not supported, =1: Dual CRTC is supported; 
+// Bit 2 = 0: Extended Desktop is not supported, =1: Extended Desktop is supported; 
+// Others: Reserved
 #define ATOM_BIOS_INFO_ATOM_FIRMWARE_POSTED         0x0001
 #define ATOM_BIOS_INFO_DUAL_CRTC_SUPPORT            0x0002
 #define ATOM_BIOS_INFO_EXTENDED_DESKTOP_SUPPORT     0x0004
-#define ATOM_BIOS_INFO_MEMORY_CLOCK_SS_SUPPORT      0x0008
-#define ATOM_BIOS_INFO_ENGINE_CLOCK_SS_SUPPORT      0x0010
+#define ATOM_BIOS_INFO_MEMORY_CLOCK_SS_SUPPORT      0x0008		// (valid from v1.1 ~v1.4):=1: memclk SS enable, =0 memclk SS disable. 
+#define ATOM_BIOS_INFO_ENGINE_CLOCK_SS_SUPPORT      0x0010		// (valid from v1.1 ~v1.4):=1: engclk SS enable, =0 engclk SS disable. 
 #define ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU         0x0020
 #define ATOM_BIOS_INFO_WMI_SUPPORT                  0x0040
 #define ATOM_BIOS_INFO_PPMODE_ASSIGNGED_BY_SYSTEM   0x0080
@@ -1441,242 +1797,292 @@ typedef struct _ATOM_MULTIMEDIA_CONFIG_I
 #define ATOM_BIOS_INFO_HYPERMEMORY_SIZE_MASK        0x1E00
 #define ATOM_BIOS_INFO_VPOST_WITHOUT_FIRST_MODE_SET 0x2000
 #define ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE  0x4000
+#define ATOM_BIOS_INFO_MEMORY_CLOCK_EXT_SS_SUPPORT  0x0008		// (valid from v2.1 ): =1: memclk ss enable with external ss chip
+#define ATOM_BIOS_INFO_ENGINE_CLOCK_EXT_SS_SUPPORT  0x0010		// (valid from v2.1 ): =1: engclk ss enable with external ss chip
 
 #ifndef _H2INC
 
-/* Please don't add or expand this bitfield structure below, this one will retire soon.! */
-typedef struct _ATOM_FIRMWARE_CAPABILITY {
+//Please don't add or expand this bitfield structure below, this one will retire soon.!
+typedef struct _ATOM_FIRMWARE_CAPABILITY
+{
 #if ATOM_BIG_ENDIAN
-	USHORT Reserved:3;
-	USHORT HyperMemory_Size:4;
-	USHORT HyperMemory_Support:1;
-	USHORT PPMode_Assigned:1;
-	USHORT WMI_SUPPORT:1;
-	USHORT GPUControlsBL:1;
-	USHORT EngineClockSS_Support:1;
-	USHORT MemoryClockSS_Support:1;
-	USHORT ExtendedDesktopSupport:1;
-	USHORT DualCRTC_Support:1;
-	USHORT FirmwarePosted:1;
+  USHORT Reserved:3;
+  USHORT HyperMemory_Size:4;
+  USHORT HyperMemory_Support:1;
+  USHORT PPMode_Assigned:1;
+  USHORT WMI_SUPPORT:1;
+  USHORT GPUControlsBL:1;
+  USHORT EngineClockSS_Support:1;
+  USHORT MemoryClockSS_Support:1;
+  USHORT ExtendedDesktopSupport:1;
+  USHORT DualCRTC_Support:1;
+  USHORT FirmwarePosted:1;
 #else
-	USHORT FirmwarePosted:1;
-	USHORT DualCRTC_Support:1;
-	USHORT ExtendedDesktopSupport:1;
-	USHORT MemoryClockSS_Support:1;
-	USHORT EngineClockSS_Support:1;
-	USHORT GPUControlsBL:1;
-	USHORT WMI_SUPPORT:1;
-	USHORT PPMode_Assigned:1;
-	USHORT HyperMemory_Support:1;
-	USHORT HyperMemory_Size:4;
-	USHORT Reserved:3;
+  USHORT FirmwarePosted:1;
+  USHORT DualCRTC_Support:1;
+  USHORT ExtendedDesktopSupport:1;
+  USHORT MemoryClockSS_Support:1;
+  USHORT EngineClockSS_Support:1;
+  USHORT GPUControlsBL:1;
+  USHORT WMI_SUPPORT:1;
+  USHORT PPMode_Assigned:1;
+  USHORT HyperMemory_Support:1;
+  USHORT HyperMemory_Size:4;
+  USHORT Reserved:3;
 #endif
-} ATOM_FIRMWARE_CAPABILITY;
+}ATOM_FIRMWARE_CAPABILITY;
 
-typedef union _ATOM_FIRMWARE_CAPABILITY_ACCESS {
-	ATOM_FIRMWARE_CAPABILITY sbfAccess;
-	USHORT susAccess;
-} ATOM_FIRMWARE_CAPABILITY_ACCESS;
+typedef union _ATOM_FIRMWARE_CAPABILITY_ACCESS
+{
+  ATOM_FIRMWARE_CAPABILITY sbfAccess;
+  USHORT                   susAccess;
+}ATOM_FIRMWARE_CAPABILITY_ACCESS;
 
 #else
 
-typedef union _ATOM_FIRMWARE_CAPABILITY_ACCESS {
-	USHORT susAccess;
-} ATOM_FIRMWARE_CAPABILITY_ACCESS;
+typedef union _ATOM_FIRMWARE_CAPABILITY_ACCESS
+{
+  USHORT                   susAccess;
+}ATOM_FIRMWARE_CAPABILITY_ACCESS;
 
 #endif
 
-typedef struct _ATOM_FIRMWARE_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ULONG ulFirmwareRevision;
-	ULONG ulDefaultEngineClock;	/* In 10Khz unit */
-	ULONG ulDefaultMemoryClock;	/* In 10Khz unit */
-	ULONG ulDriverTargetEngineClock;	/* In 10Khz unit */
-	ULONG ulDriverTargetMemoryClock;	/* In 10Khz unit */
-	ULONG ulMaxEngineClockPLL_Output;	/* In 10Khz unit */
-	ULONG ulMaxMemoryClockPLL_Output;	/* In 10Khz unit */
-	ULONG ulMaxPixelClockPLL_Output;	/* In 10Khz unit */
-	ULONG ulASICMaxEngineClock;	/* In 10Khz unit */
-	ULONG ulASICMaxMemoryClock;	/* In 10Khz unit */
-	UCHAR ucASICMaxTemperature;
-	UCHAR ucPadding[3];	/* Don't use them */
-	ULONG aulReservedForBIOS[3];	/* Don't use them */
-	USHORT usMinEngineClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMaxEngineClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMinEngineClockPLL_Output;	/* In 10Khz unit */
-	USHORT usMinMemoryClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMaxMemoryClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMinMemoryClockPLL_Output;	/* In 10Khz unit */
-	USHORT usMaxPixelClock;	/* In 10Khz unit, Max.  Pclk */
-	USHORT usMinPixelClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMaxPixelClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMinPixelClockPLL_Output;	/* In 10Khz unit, the definitions above can't change!!! */
-	ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability;
-	USHORT usReferenceClock;	/* In 10Khz unit */
-	USHORT usPM_RTS_Location;	/* RTS PM4 starting location in ROM in 1Kb unit */
-	UCHAR ucPM_RTS_StreamSize;	/* RTS PM4 packets in Kb unit */
-	UCHAR ucDesign_ID;	/* Indicate what is the board design */
-	UCHAR ucMemoryModule_ID;	/* Indicate what is the board design */
-} ATOM_FIRMWARE_INFO;
+typedef struct _ATOM_FIRMWARE_INFO
+{
+  ATOM_COMMON_TABLE_HEADER        sHeader; 
+  ULONG                           ulFirmwareRevision;
+  ULONG                           ulDefaultEngineClock;       //In 10Khz unit
+  ULONG                           ulDefaultMemoryClock;       //In 10Khz unit
+  ULONG                           ulDriverTargetEngineClock;  //In 10Khz unit
+  ULONG                           ulDriverTargetMemoryClock;  //In 10Khz unit
+  ULONG                           ulMaxEngineClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxMemoryClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxPixelClockPLL_Output;  //In 10Khz unit
+  ULONG                           ulASICMaxEngineClock;       //In 10Khz unit
+  ULONG                           ulASICMaxMemoryClock;       //In 10Khz unit
+  UCHAR                           ucASICMaxTemperature;
+  UCHAR                           ucPadding[3];               //Don't use them
+  ULONG                           aulReservedForBIOS[3];      //Don't use them
+  USHORT                          usMinEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Output; //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Output; //In 10Khz unit
+  USHORT                          usMaxPixelClock;            //In 10Khz unit, Max.  Pclk
+  USHORT                          usMinPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMaxPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMinPixelClockPLL_Output;  //In 10Khz unit, the definitions above can't change!!!
+  ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability;
+  USHORT                          usReferenceClock;           //In 10Khz unit	
+  USHORT                          usPM_RTS_Location;          //RTS PM4 starting location in ROM in 1Kb unit 
+  UCHAR                           ucPM_RTS_StreamSize;        //RTS PM4 packets in Kb unit
+  UCHAR                           ucDesign_ID;                //Indicate what is the board design
+  UCHAR                           ucMemoryModule_ID;          //Indicate what is the board design
+}ATOM_FIRMWARE_INFO;
 
-typedef struct _ATOM_FIRMWARE_INFO_V1_2 {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ULONG ulFirmwareRevision;
-	ULONG ulDefaultEngineClock;	/* In 10Khz unit */
-	ULONG ulDefaultMemoryClock;	/* In 10Khz unit */
-	ULONG ulDriverTargetEngineClock;	/* In 10Khz unit */
-	ULONG ulDriverTargetMemoryClock;	/* In 10Khz unit */
-	ULONG ulMaxEngineClockPLL_Output;	/* In 10Khz unit */
-	ULONG ulMaxMemoryClockPLL_Output;	/* In 10Khz unit */
-	ULONG ulMaxPixelClockPLL_Output;	/* In 10Khz unit */
-	ULONG ulASICMaxEngineClock;	/* In 10Khz unit */
-	ULONG ulASICMaxMemoryClock;	/* In 10Khz unit */
-	UCHAR ucASICMaxTemperature;
-	UCHAR ucMinAllowedBL_Level;
-	UCHAR ucPadding[2];	/* Don't use them */
-	ULONG aulReservedForBIOS[2];	/* Don't use them */
-	ULONG ulMinPixelClockPLL_Output;	/* In 10Khz unit */
-	USHORT usMinEngineClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMaxEngineClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMinEngineClockPLL_Output;	/* In 10Khz unit */
-	USHORT usMinMemoryClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMaxMemoryClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMinMemoryClockPLL_Output;	/* In 10Khz unit */
-	USHORT usMaxPixelClock;	/* In 10Khz unit, Max.  Pclk */
-	USHORT usMinPixelClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMaxPixelClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMinPixelClockPLL_Output;	/* In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output */
-	ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability;
-	USHORT usReferenceClock;	/* In 10Khz unit */
-	USHORT usPM_RTS_Location;	/* RTS PM4 starting location in ROM in 1Kb unit */
-	UCHAR ucPM_RTS_StreamSize;	/* RTS PM4 packets in Kb unit */
-	UCHAR ucDesign_ID;	/* Indicate what is the board design */
-	UCHAR ucMemoryModule_ID;	/* Indicate what is the board design */
-} ATOM_FIRMWARE_INFO_V1_2;
+typedef struct _ATOM_FIRMWARE_INFO_V1_2
+{
+  ATOM_COMMON_TABLE_HEADER        sHeader; 
+  ULONG                           ulFirmwareRevision;
+  ULONG                           ulDefaultEngineClock;       //In 10Khz unit
+  ULONG                           ulDefaultMemoryClock;       //In 10Khz unit
+  ULONG                           ulDriverTargetEngineClock;  //In 10Khz unit
+  ULONG                           ulDriverTargetMemoryClock;  //In 10Khz unit
+  ULONG                           ulMaxEngineClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxMemoryClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxPixelClockPLL_Output;  //In 10Khz unit
+  ULONG                           ulASICMaxEngineClock;       //In 10Khz unit
+  ULONG                           ulASICMaxMemoryClock;       //In 10Khz unit
+  UCHAR                           ucASICMaxTemperature;
+  UCHAR                           ucMinAllowedBL_Level;
+  UCHAR                           ucPadding[2];               //Don't use them
+  ULONG                           aulReservedForBIOS[2];      //Don't use them
+  ULONG                           ulMinPixelClockPLL_Output;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Output; //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Output; //In 10Khz unit
+  USHORT                          usMaxPixelClock;            //In 10Khz unit, Max.  Pclk
+  USHORT                          usMinPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMaxPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMinPixelClockPLL_Output;  //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output
+  ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability;
+  USHORT                          usReferenceClock;           //In 10Khz unit	
+  USHORT                          usPM_RTS_Location;          //RTS PM4 starting location in ROM in 1Kb unit 
+  UCHAR                           ucPM_RTS_StreamSize;        //RTS PM4 packets in Kb unit
+  UCHAR                           ucDesign_ID;                //Indicate what is the board design
+  UCHAR                           ucMemoryModule_ID;          //Indicate what is the board design
+}ATOM_FIRMWARE_INFO_V1_2;
 
-typedef struct _ATOM_FIRMWARE_INFO_V1_3 {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ULONG ulFirmwareRevision;
-	ULONG ulDefaultEngineClock;	/* In 10Khz unit */
-	ULONG ulDefaultMemoryClock;	/* In 10Khz unit */
-	ULONG ulDriverTargetEngineClock;	/* In 10Khz unit */
-	ULONG ulDriverTargetMemoryClock;	/* In 10Khz unit */
-	ULONG ulMaxEngineClockPLL_Output;	/* In 10Khz unit */
-	ULONG ulMaxMemoryClockPLL_Output;	/* In 10Khz unit */
-	ULONG ulMaxPixelClockPLL_Output;	/* In 10Khz unit */
-	ULONG ulASICMaxEngineClock;	/* In 10Khz unit */
-	ULONG ulASICMaxMemoryClock;	/* In 10Khz unit */
-	UCHAR ucASICMaxTemperature;
-	UCHAR ucMinAllowedBL_Level;
-	UCHAR ucPadding[2];	/* Don't use them */
-	ULONG aulReservedForBIOS;	/* Don't use them */
-	ULONG ul3DAccelerationEngineClock;	/* In 10Khz unit */
-	ULONG ulMinPixelClockPLL_Output;	/* In 10Khz unit */
-	USHORT usMinEngineClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMaxEngineClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMinEngineClockPLL_Output;	/* In 10Khz unit */
-	USHORT usMinMemoryClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMaxMemoryClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMinMemoryClockPLL_Output;	/* In 10Khz unit */
-	USHORT usMaxPixelClock;	/* In 10Khz unit, Max.  Pclk */
-	USHORT usMinPixelClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMaxPixelClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMinPixelClockPLL_Output;	/* In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output */
-	ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability;
-	USHORT usReferenceClock;	/* In 10Khz unit */
-	USHORT usPM_RTS_Location;	/* RTS PM4 starting location in ROM in 1Kb unit */
-	UCHAR ucPM_RTS_StreamSize;	/* RTS PM4 packets in Kb unit */
-	UCHAR ucDesign_ID;	/* Indicate what is the board design */
-	UCHAR ucMemoryModule_ID;	/* Indicate what is the board design */
-} ATOM_FIRMWARE_INFO_V1_3;
+typedef struct _ATOM_FIRMWARE_INFO_V1_3
+{
+  ATOM_COMMON_TABLE_HEADER        sHeader; 
+  ULONG                           ulFirmwareRevision;
+  ULONG                           ulDefaultEngineClock;       //In 10Khz unit
+  ULONG                           ulDefaultMemoryClock;       //In 10Khz unit
+  ULONG                           ulDriverTargetEngineClock;  //In 10Khz unit
+  ULONG                           ulDriverTargetMemoryClock;  //In 10Khz unit
+  ULONG                           ulMaxEngineClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxMemoryClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxPixelClockPLL_Output;  //In 10Khz unit
+  ULONG                           ulASICMaxEngineClock;       //In 10Khz unit
+  ULONG                           ulASICMaxMemoryClock;       //In 10Khz unit
+  UCHAR                           ucASICMaxTemperature;
+  UCHAR                           ucMinAllowedBL_Level;
+  UCHAR                           ucPadding[2];               //Don't use them
+  ULONG                           aulReservedForBIOS;         //Don't use them
+  ULONG                           ul3DAccelerationEngineClock;//In 10Khz unit
+  ULONG                           ulMinPixelClockPLL_Output;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Output; //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Output; //In 10Khz unit
+  USHORT                          usMaxPixelClock;            //In 10Khz unit, Max.  Pclk
+  USHORT                          usMinPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMaxPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMinPixelClockPLL_Output;  //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output
+  ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability;
+  USHORT                          usReferenceClock;           //In 10Khz unit	
+  USHORT                          usPM_RTS_Location;          //RTS PM4 starting location in ROM in 1Kb unit 
+  UCHAR                           ucPM_RTS_StreamSize;        //RTS PM4 packets in Kb unit
+  UCHAR                           ucDesign_ID;                //Indicate what is the board design
+  UCHAR                           ucMemoryModule_ID;          //Indicate what is the board design
+}ATOM_FIRMWARE_INFO_V1_3;
 
-typedef struct _ATOM_FIRMWARE_INFO_V1_4 {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ULONG ulFirmwareRevision;
-	ULONG ulDefaultEngineClock;	/* In 10Khz unit */
-	ULONG ulDefaultMemoryClock;	/* In 10Khz unit */
-	ULONG ulDriverTargetEngineClock;	/* In 10Khz unit */
-	ULONG ulDriverTargetMemoryClock;	/* In 10Khz unit */
-	ULONG ulMaxEngineClockPLL_Output;	/* In 10Khz unit */
-	ULONG ulMaxMemoryClockPLL_Output;	/* In 10Khz unit */
-	ULONG ulMaxPixelClockPLL_Output;	/* In 10Khz unit */
-	ULONG ulASICMaxEngineClock;	/* In 10Khz unit */
-	ULONG ulASICMaxMemoryClock;	/* In 10Khz unit */
-	UCHAR ucASICMaxTemperature;
-	UCHAR ucMinAllowedBL_Level;
-	USHORT usBootUpVDDCVoltage;	/* In MV unit */
-	USHORT usLcdMinPixelClockPLL_Output;	/*  In MHz unit */
-	USHORT usLcdMaxPixelClockPLL_Output;	/*  In MHz unit */
-	ULONG ul3DAccelerationEngineClock;	/* In 10Khz unit */
-	ULONG ulMinPixelClockPLL_Output;	/* In 10Khz unit */
-	USHORT usMinEngineClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMaxEngineClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMinEngineClockPLL_Output;	/* In 10Khz unit */
-	USHORT usMinMemoryClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMaxMemoryClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMinMemoryClockPLL_Output;	/* In 10Khz unit */
-	USHORT usMaxPixelClock;	/* In 10Khz unit, Max.  Pclk */
-	USHORT usMinPixelClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMaxPixelClockPLL_Input;	/* In 10Khz unit */
-	USHORT usMinPixelClockPLL_Output;	/* In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output */
-	ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability;
-	USHORT usReferenceClock;	/* In 10Khz unit */
-	USHORT usPM_RTS_Location;	/* RTS PM4 starting location in ROM in 1Kb unit */
-	UCHAR ucPM_RTS_StreamSize;	/* RTS PM4 packets in Kb unit */
-	UCHAR ucDesign_ID;	/* Indicate what is the board design */
-	UCHAR ucMemoryModule_ID;	/* Indicate what is the board design */
-} ATOM_FIRMWARE_INFO_V1_4;
+typedef struct _ATOM_FIRMWARE_INFO_V1_4
+{
+  ATOM_COMMON_TABLE_HEADER        sHeader; 
+  ULONG                           ulFirmwareRevision;
+  ULONG                           ulDefaultEngineClock;       //In 10Khz unit
+  ULONG                           ulDefaultMemoryClock;       //In 10Khz unit
+  ULONG                           ulDriverTargetEngineClock;  //In 10Khz unit
+  ULONG                           ulDriverTargetMemoryClock;  //In 10Khz unit
+  ULONG                           ulMaxEngineClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxMemoryClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxPixelClockPLL_Output;  //In 10Khz unit
+  ULONG                           ulASICMaxEngineClock;       //In 10Khz unit
+  ULONG                           ulASICMaxMemoryClock;       //In 10Khz unit
+  UCHAR                           ucASICMaxTemperature;
+  UCHAR                           ucMinAllowedBL_Level;
+  USHORT                          usBootUpVDDCVoltage;        //In MV unit
+  USHORT                          usLcdMinPixelClockPLL_Output; // In MHz unit
+  USHORT                          usLcdMaxPixelClockPLL_Output; // In MHz unit
+  ULONG                           ul3DAccelerationEngineClock;//In 10Khz unit
+  ULONG                           ulMinPixelClockPLL_Output;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Output; //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Output; //In 10Khz unit
+  USHORT                          usMaxPixelClock;            //In 10Khz unit, Max.  Pclk
+  USHORT                          usMinPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMaxPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMinPixelClockPLL_Output;  //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output
+  ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability;
+  USHORT                          usReferenceClock;           //In 10Khz unit	
+  USHORT                          usPM_RTS_Location;          //RTS PM4 starting location in ROM in 1Kb unit 
+  UCHAR                           ucPM_RTS_StreamSize;        //RTS PM4 packets in Kb unit
+  UCHAR                           ucDesign_ID;                //Indicate what is the board design
+  UCHAR                           ucMemoryModule_ID;          //Indicate what is the board design
+}ATOM_FIRMWARE_INFO_V1_4;
 
-#define ATOM_FIRMWARE_INFO_LAST  ATOM_FIRMWARE_INFO_V1_4
+//the structure below to be used from Cypress
+typedef struct _ATOM_FIRMWARE_INFO_V2_1
+{
+  ATOM_COMMON_TABLE_HEADER        sHeader; 
+  ULONG                           ulFirmwareRevision;
+  ULONG                           ulDefaultEngineClock;       //In 10Khz unit
+  ULONG                           ulDefaultMemoryClock;       //In 10Khz unit
+  ULONG                           ulReserved1;
+  ULONG                           ulReserved2;
+  ULONG                           ulMaxEngineClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxMemoryClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxPixelClockPLL_Output;  //In 10Khz unit
+  ULONG                           ulBinaryAlteredInfo;        //Was ulASICMaxEngineClock
+  ULONG                           ulDefaultDispEngineClkFreq; //In 10Khz unit
+  UCHAR                           ucReserved1;                //Was ucASICMaxTemperature;
+  UCHAR                           ucMinAllowedBL_Level;
+  USHORT                          usBootUpVDDCVoltage;        //In MV unit
+  USHORT                          usLcdMinPixelClockPLL_Output; // In MHz unit
+  USHORT                          usLcdMaxPixelClockPLL_Output; // In MHz unit
+  ULONG                           ulReserved4;                //Was ulAsicMaximumVoltage
+  ULONG                           ulMinPixelClockPLL_Output;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Output; //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Output; //In 10Khz unit
+  USHORT                          usMaxPixelClock;            //In 10Khz unit, Max.  Pclk
+  USHORT                          usMinPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMaxPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMinPixelClockPLL_Output;  //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output
+  ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability;
+  USHORT                          usCoreReferenceClock;       //In 10Khz unit	
+  USHORT                          usMemoryReferenceClock;     //In 10Khz unit	
+  USHORT                          usUniphyDPModeExtClkFreq;   //In 10Khz unit, if it is 0, In DP Mode Uniphy Input clock from internal PPLL, otherwise Input clock from external Spread clock
+  UCHAR                           ucMemoryModule_ID;          //Indicate what is the board design
+  UCHAR                           ucReserved4[3];
+}ATOM_FIRMWARE_INFO_V2_1;
 
-/****************************************************************************/
-/*  Structures used in IntegratedSystemInfoTable */
-/****************************************************************************/
+
+#define ATOM_FIRMWARE_INFO_LAST  ATOM_FIRMWARE_INFO_V2_1
+
+/****************************************************************************/	
+// Structures used in IntegratedSystemInfoTable
+/****************************************************************************/	
 #define IGP_CAP_FLAG_DYNAMIC_CLOCK_EN      0x2
 #define IGP_CAP_FLAG_AC_CARD               0x4
 #define IGP_CAP_FLAG_SDVO_CARD             0x8
 #define IGP_CAP_FLAG_POSTDIV_BY_2_MODE     0x10
 
-typedef struct _ATOM_INTEGRATED_SYSTEM_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ULONG ulBootUpEngineClock;	/* in 10kHz unit */
-	ULONG ulBootUpMemoryClock;	/* in 10kHz unit */
-	ULONG ulMaxSystemMemoryClock;	/* in 10kHz unit */
-	ULONG ulMinSystemMemoryClock;	/* in 10kHz unit */
-	UCHAR ucNumberOfCyclesInPeriodHi;
-	UCHAR ucLCDTimingSel;	/* =0:not valid.!=0 sel this timing descriptor from LCD EDID. */
-	USHORT usReserved1;
-	USHORT usInterNBVoltageLow;	/* An intermidiate PMW value to set the voltage */
-	USHORT usInterNBVoltageHigh;	/* Another intermidiate PMW value to set the voltage */
-	ULONG ulReserved[2];
+typedef struct _ATOM_INTEGRATED_SYSTEM_INFO
+{
+  ATOM_COMMON_TABLE_HEADER        sHeader; 
+  ULONG	                          ulBootUpEngineClock;		    //in 10kHz unit
+  ULONG	                          ulBootUpMemoryClock;		    //in 10kHz unit
+  ULONG	                          ulMaxSystemMemoryClock;	    //in 10kHz unit
+  ULONG	                          ulMinSystemMemoryClock;	    //in 10kHz unit
+  UCHAR                           ucNumberOfCyclesInPeriodHi;
+  UCHAR                           ucLCDTimingSel;             //=0:not valid.!=0 sel this timing descriptor from LCD EDID.
+  USHORT                          usReserved1;
+  USHORT                          usInterNBVoltageLow;        //An intermidiate PMW value to set the voltage 
+  USHORT                          usInterNBVoltageHigh;       //Another intermidiate PMW value to set the voltage 
+  ULONG	                          ulReserved[2];
 
-	USHORT usFSBClock;	/* In MHz unit */
-	USHORT usCapabilityFlag;	/* Bit0=1 indicates the fake HDMI support,Bit1=0/1 for Dynamic clocking dis/enable */
-	/* Bit[3:2]== 0:No PCIE card, 1:AC card, 2:SDVO card */
-	/* Bit[4]==1: P/2 mode, ==0: P/1 mode */
-	USHORT usPCIENBCfgReg7;	/* bit[7:0]=MUX_Sel, bit[9:8]=MUX_SEL_LEVEL2, bit[10]=Lane_Reversal */
-	USHORT usK8MemoryClock;	/* in MHz unit */
-	USHORT usK8SyncStartDelay;	/* in 0.01 us unit */
-	USHORT usK8DataReturnTime;	/* in 0.01 us unit */
-	UCHAR ucMaxNBVoltage;
-	UCHAR ucMinNBVoltage;
-	UCHAR ucMemoryType;	/* [7:4]=1:DDR1;=2:DDR2;=3:DDR3.[3:0] is reserved */
-	UCHAR ucNumberOfCyclesInPeriod;	/* CG.FVTHROT_PWM_CTRL_REG0.NumberOfCyclesInPeriod */
-	UCHAR ucStartingPWM_HighTime;	/* CG.FVTHROT_PWM_CTRL_REG0.StartingPWM_HighTime */
-	UCHAR ucHTLinkWidth;	/* 16 bit vs. 8 bit */
-	UCHAR ucMaxNBVoltageHigh;
-	UCHAR ucMinNBVoltageHigh;
-} ATOM_INTEGRATED_SYSTEM_INFO;
+  USHORT	                        usFSBClock;			            //In MHz unit
+  USHORT                          usCapabilityFlag;		        //Bit0=1 indicates the fake HDMI support,Bit1=0/1 for Dynamic clocking dis/enable
+																                              //Bit[3:2]== 0:No PCIE card, 1:AC card, 2:SDVO card
+                                                              //Bit[4]==1: P/2 mode, ==0: P/1 mode
+  USHORT	                        usPCIENBCfgReg7;				    //bit[7:0]=MUX_Sel, bit[9:8]=MUX_SEL_LEVEL2, bit[10]=Lane_Reversal
+  USHORT	                        usK8MemoryClock;            //in MHz unit
+  USHORT	                        usK8SyncStartDelay;         //in 0.01 us unit
+  USHORT	                        usK8DataReturnTime;         //in 0.01 us unit
+  UCHAR                           ucMaxNBVoltage;
+  UCHAR                           ucMinNBVoltage;
+  UCHAR                           ucMemoryType;					      //[7:4]=1:DDR1;=2:DDR2;=3:DDR3.[3:0] is reserved
+  UCHAR                           ucNumberOfCyclesInPeriod;		//CG.FVTHROT_PWM_CTRL_REG0.NumberOfCyclesInPeriod 
+  UCHAR                           ucStartingPWM_HighTime;     //CG.FVTHROT_PWM_CTRL_REG0.StartingPWM_HighTime
+  UCHAR                           ucHTLinkWidth;              //16 bit vs. 8 bit
+  UCHAR                           ucMaxNBVoltageHigh;    
+  UCHAR                           ucMinNBVoltageHigh;
+}ATOM_INTEGRATED_SYSTEM_INFO;
 
 /* Explanation on entries in ATOM_INTEGRATED_SYSTEM_INFO
-ulBootUpMemoryClock:    For Intel IGP,it's the UMA system memory clock
+ulBootUpMemoryClock:    For Intel IGP,it's the UMA system memory clock 
                         For AMD IGP,it's 0 if no SidePort memory installed or it's the boot-up SidePort memory clock
 ulMaxSystemMemoryClock: For Intel IGP,it's the Max freq from memory SPD if memory runs in ASYNC mode or otherwise (SYNC mode) it's 0
                         For AMD IGP,for now this can be 0
-ulMinSystemMemoryClock: For Intel IGP,it's 133MHz if memory runs in ASYNC mode or otherwise (SYNC mode) it's 0
+ulMinSystemMemoryClock: For Intel IGP,it's 133MHz if memory runs in ASYNC mode or otherwise (SYNC mode) it's 0 
                         For AMD IGP,for now this can be 0
 
-usFSBClock:             For Intel IGP,it's FSB Freq
+usFSBClock:             For Intel IGP,it's FSB Freq 
                         For AMD IGP,it's HT Link Speed
 
 usK8MemoryClock:        For AMD IGP only. For RevF CPU, set it to 200
@@ -1687,98 +2093,113 @@ VC:Voltage Control
 ucMaxNBVoltage:         Voltage regulator dependent PWM value. Low 8 bits of the value for the max voltage.Set this one to 0xFF if VC without PWM. Set this to 0x0 if no VC at all.
 ucMinNBVoltage:         Voltage regulator dependent PWM value. Low 8 bits of the value for the min voltage.Set this one to 0x00 if VC without PWM or no VC at all.
 
-ucNumberOfCyclesInPeriod:   Indicate how many cycles when PWM duty is 100%. low 8 bits of the value.
-ucNumberOfCyclesInPeriodHi: Indicate how many cycles when PWM duty is 100%. high 8 bits of the value.If the PWM has an inverter,set bit [7]==1,otherwise set it 0
+ucNumberOfCyclesInPeriod:   Indicate how many cycles when PWM duty is 100%. low 8 bits of the value. 
+ucNumberOfCyclesInPeriodHi: Indicate how many cycles when PWM duty is 100%. high 8 bits of the value.If the PWM has an inverter,set bit [7]==1,otherwise set it 0 
 
 ucMaxNBVoltageHigh:     Voltage regulator dependent PWM value. High 8 bits of  the value for the max voltage.Set this one to 0xFF if VC without PWM. Set this to 0x0 if no VC at all.
 ucMinNBVoltageHigh:     Voltage regulator dependent PWM value. High 8 bits of the value for the min voltage.Set this one to 0x00 if VC without PWM or no VC at all.
 
+
 usInterNBVoltageLow:    Voltage regulator dependent PWM value. The value makes the the voltage >=Min NB voltage but <=InterNBVoltageHigh. Set this to 0x0000 if VC without PWM or no VC at all.
 usInterNBVoltageHigh:   Voltage regulator dependent PWM value. The value makes the the voltage >=InterNBVoltageLow but <=Max NB voltage.Set this to 0x0000 if VC without PWM or no VC at all.
 */
 
+
 /*
 The following IGP table is introduced from RS780, which is supposed to be put by SBIOS in FB before IGP VBIOS starts VPOST;
-Then VBIOS will copy the whole structure to its image so all GPU SW components can access this data structure to get whatever they need.
+Then VBIOS will copy the whole structure to its image so all GPU SW components can access this data structure to get whatever they need. 
 The enough reservation should allow us to never change table revisions. Whenever needed, a GPU SW component can use reserved portion for new data entries.
 
 SW components can access the IGP system infor structure in the same way as before
 */
 
-typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ULONG ulBootUpEngineClock;	/* in 10kHz unit */
-	ULONG ulReserved1[2];	/* must be 0x0 for the reserved */
-	ULONG ulBootUpUMAClock;	/* in 10kHz unit */
-	ULONG ulBootUpSidePortClock;	/* in 10kHz unit */
-	ULONG ulMinSidePortClock;	/* in 10kHz unit */
-	ULONG ulReserved2[6];	/* must be 0x0 for the reserved */
-	ULONG ulSystemConfig;	/* see explanation below */
-	ULONG ulBootUpReqDisplayVector;
-	ULONG ulOtherDisplayMisc;
-	ULONG ulDDISlot1Config;
-	ULONG ulDDISlot2Config;
-	UCHAR ucMemoryType;	/* [3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved */
-	UCHAR ucUMAChannelNumber;
-	UCHAR ucDockingPinBit;
-	UCHAR ucDockingPinPolarity;
-	ULONG ulDockingPinCFGInfo;
-	ULONG ulCPUCapInfo;
-	USHORT usNumberOfCyclesInPeriod;
-	USHORT usMaxNBVoltage;
-	USHORT usMinNBVoltage;
-	USHORT usBootUpNBVoltage;
-	ULONG ulHTLinkFreq;	/* in 10Khz */
-	USHORT usMinHTLinkWidth;
-	USHORT usMaxHTLinkWidth;
-	USHORT usUMASyncStartDelay;
-	USHORT usUMADataReturnTime;
-	USHORT usLinkStatusZeroTime;
-	USHORT usReserved;
-	ULONG ulHighVoltageHTLinkFreq;	/*  in 10Khz */
-	ULONG ulLowVoltageHTLinkFreq;	/*  in 10Khz */
-	USHORT usMaxUpStreamHTLinkWidth;
-	USHORT usMaxDownStreamHTLinkWidth;
-	USHORT usMinUpStreamHTLinkWidth;
-	USHORT usMinDownStreamHTLinkWidth;
-	ULONG ulReserved3[97];	/* must be 0x0 */
-} ATOM_INTEGRATED_SYSTEM_INFO_V2;
+
+typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V2
+{
+  ATOM_COMMON_TABLE_HEADER   sHeader;
+  ULONG	                     ulBootUpEngineClock;       //in 10kHz unit
+  ULONG			     ulReserved1[2];            //must be 0x0 for the reserved
+  ULONG	                     ulBootUpUMAClock;          //in 10kHz unit
+  ULONG	                     ulBootUpSidePortClock;     //in 10kHz unit
+  ULONG	                     ulMinSidePortClock;        //in 10kHz unit
+  ULONG			     ulReserved2[6];            //must be 0x0 for the reserved
+  ULONG                      ulSystemConfig;            //see explanation below
+  ULONG                      ulBootUpReqDisplayVector;
+  ULONG                      ulOtherDisplayMisc;
+  ULONG                      ulDDISlot1Config;
+  ULONG                      ulDDISlot2Config;
+  UCHAR                      ucMemoryType;              //[3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved
+  UCHAR                      ucUMAChannelNumber;
+  UCHAR                      ucDockingPinBit;
+  UCHAR                      ucDockingPinPolarity;
+  ULONG                      ulDockingPinCFGInfo;
+  ULONG                      ulCPUCapInfo;
+  USHORT                     usNumberOfCyclesInPeriod;
+  USHORT                     usMaxNBVoltage;
+  USHORT                     usMinNBVoltage;
+  USHORT                     usBootUpNBVoltage;
+  ULONG                      ulHTLinkFreq;              //in 10Khz
+  USHORT                     usMinHTLinkWidth;
+  USHORT                     usMaxHTLinkWidth;
+  USHORT                     usUMASyncStartDelay;
+  USHORT                     usUMADataReturnTime;
+  USHORT                     usLinkStatusZeroTime;
+  USHORT                     usDACEfuse;				//for storing badgap value (for RS880 only)
+  ULONG                      ulHighVoltageHTLinkFreq;     // in 10Khz
+  ULONG                      ulLowVoltageHTLinkFreq;      // in 10Khz
+  USHORT                     usMaxUpStreamHTLinkWidth;
+  USHORT                     usMaxDownStreamHTLinkWidth;
+  USHORT                     usMinUpStreamHTLinkWidth;
+  USHORT                     usMinDownStreamHTLinkWidth;
+  USHORT                     usFirmwareVersion;         //0 means FW is not supported. Otherwise it's the FW version loaded by SBIOS and driver should enable FW.
+  USHORT                     usFullT0Time;             // Input to calculate minimum HT link change time required by NB P-State. Unit is 0.01us.
+  ULONG                      ulReserved3[96];          //must be 0x0
+}ATOM_INTEGRATED_SYSTEM_INFO_V2;   
 
 /*
 ulBootUpEngineClock:   Boot-up Engine Clock in 10Khz;
 ulBootUpUMAClock:      Boot-up UMA Clock in 10Khz; it must be 0x0 when UMA is not present
 ulBootUpSidePortClock: Boot-up SidePort Clock in 10Khz; it must be 0x0 when SidePort Memory is not present,this could be equal to or less than maximum supported Sideport memory clock
 
-ulSystemConfig:
-Bit[0]=1: PowerExpress mode =0 Non-PowerExpress mode;
+ulSystemConfig:  
+Bit[0]=1: PowerExpress mode =0 Non-PowerExpress mode; 
 Bit[1]=1: system boots up at AMD overdrived state or user customized  mode. In this case, driver will just stick to this boot-up mode. No other PowerPlay state
       =0: system boots up at driver control state. Power state depends on PowerPlay table.
 Bit[2]=1: PWM method is used on NB voltage control. =0: GPIO method is used.
 Bit[3]=1: Only one power state(Performance) will be supported.
       =0: Multiple power states supported from PowerPlay table.
-Bit[4]=1: CLMC is supported and enabled on current system.
-      =0: CLMC is not supported or enabled on current system. SBIOS need to support HT link/freq change through ATIF interface.
-Bit[5]=1: Enable CDLW for all driver control power states. Max HT width is from SBIOS, while Min HT width is determined by display requirement.
+Bit[4]=1: CLMC is supported and enabled on current system. 
+      =0: CLMC is not supported or enabled on current system. SBIOS need to support HT link/freq change through ATIF interface.  
+Bit[5]=1: Enable CDLW for all driver control power states. Max HT width is from SBIOS, while Min HT width is determined by display requirement.  
       =0: CDLW is disabled. If CLMC is enabled case, Min HT width will be set equal to Max HT width. If CLMC disabled case, Max HT width will be applied.
 Bit[6]=1: High Voltage requested for all power states. In this case, voltage will be forced at 1.1v and powerplay table voltage drop/throttling request will be ignored.
       =0: Voltage settings is determined by powerplay table.
 Bit[7]=1: Enable CLMC as hybrid Mode. CDLD and CILR will be disabled in this case and we're using legacy C1E. This is workaround for CPU(Griffin) performance issue.
       =0: Enable CLMC as regular mode, CDLD and CILR will be enabled.
+Bit[8]=1: CDLF is supported and enabled on current system.
+      =0: CDLF is not supported or enabled on current system.
+Bit[9]=1: DLL Shut Down feature is enabled on current system.
+      =0: DLL Shut Down feature is not enabled or supported on current system.
 
 ulBootUpReqDisplayVector: This dword is a bit vector indicates what display devices are requested during boot-up. Refer to ATOM_DEVICE_xxx_SUPPORT for the bit vector definitions.
 
 ulOtherDisplayMisc: [15:8]- Bootup LCD Expansion selection; 0-center, 1-full panel size expansion;
-			              [7:0] - BootupTV standard selection; This is a bit vector to indicate what TV standards are supported by the system. Refer to ucTVSuppportedStd definition;
+			              [7:0] - BootupTV standard selection; This is a bit vector to indicate what TV standards are supported by the system. Refer to ucTVSupportedStd definition;
 
 ulDDISlot1Config: Describes the PCIE lane configuration on this DDI PCIE slot (ADD2 card) or connector (Mobile design).
       [3:0]  - Bit vector to indicate PCIE lane config of the DDI slot/connector on chassis (bit 0=1 lane 3:0; bit 1=1 lane 7:4; bit 2=1 lane 11:8; bit 3=1 lane 15:12)
-			[7:4]  - Bit vector to indicate PCIE lane config of the same DDI slot/connector on docking station (bit 0=1 lane 3:0; bit 1=1 lane 7:4; bit 2=1 lane 11:8; bit 3=1 lane 15:12)
-			[15:8] - Lane configuration attribute;
+			[7:4]  - Bit vector to indicate PCIE lane config of the same DDI slot/connector on docking station (bit 4=1 lane 3:0; bit 5=1 lane 7:4; bit 6=1 lane 11:8; bit 7=1 lane 15:12)
+      When a DDI connector is not "paired" (meaming two connections mutualexclusive on chassis or docking, only one of them can be connected at one time.
+      in both chassis and docking, SBIOS has to duplicate the same PCIE lane info from chassis to docking or vice versa. For example:
+      one DDI connector is only populated in docking with PCIE lane 8-11, but there is no paired connection on chassis, SBIOS has to copy bit 6 to bit 2.
+
+			[15:8] - Lane configuration attribute; 
       [23:16]- Connector type, possible value:
                CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D
                CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D
                CONNECTOR_OBJECT_ID_HDMI_TYPE_A
                CONNECTOR_OBJECT_ID_DISPLAYPORT
+               CONNECTOR_OBJECT_ID_eDP
 			[31:24]- Reserved
 
 ulDDISlot2Config: Same as Slot1.
@@ -1787,29 +2208,31 @@ For IGP, Hypermemory is the only memory
 
 ucUMAChannelNumber:  how many channels for the UMA;
 
-ulDockingPinCFGInfo: [15:0]-Bus/Device/Function # to CFG to read this Docking Pin; [31:16]-reg offset in CFG to read this pin
+ulDockingPinCFGInfo: [15:0]-Bus/Device/Function # to CFG to read this Docking Pin; [31:16]-reg offset in CFG to read this pin 
 ucDockingPinBit:     which bit in this register to read the pin status;
 ucDockingPinPolarity:Polarity of the pin when docked;
 
 ulCPUCapInfo:        [7:0]=1:Griffin;[7:0]=2:Greyhound;[7:0]=3:K8, other bits reserved for now and must be 0x0
 
 usNumberOfCyclesInPeriod:Indicate how many cycles when PWM duty is 100%.
-usMaxNBVoltage:Max. voltage control value in either PWM or GPIO mode.
+
+usMaxNBVoltage:Max. voltage control value in either PWM or GPIO mode. 
 usMinNBVoltage:Min. voltage control value in either PWM or GPIO mode.
                     GPIO mode: both usMaxNBVoltage & usMinNBVoltage have a valid value ulSystemConfig.SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE=0
                     PWM mode: both usMaxNBVoltage & usMinNBVoltage have a valid value ulSystemConfig.SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE=1
                     GPU SW don't control mode: usMaxNBVoltage & usMinNBVoltage=0 and no care about ulSystemConfig.SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE
+
 usBootUpNBVoltage:Boot-up voltage regulator dependent PWM value.
 
 ulHTLinkFreq:       Bootup HT link Frequency in 10Khz.
-usMinHTLinkWidth:   Bootup minimum HT link width. If CDLW disabled, this is equal to usMaxHTLinkWidth.
-                    If CDLW enabled, both upstream and downstream width should be the same during bootup.
-usMaxHTLinkWidth:   Bootup maximum HT link width. If CDLW disabled, this is equal to usMinHTLinkWidth.
+usMinHTLinkWidth:   Bootup minimum HT link width. If CDLW disabled, this is equal to usMaxHTLinkWidth. 
                     If CDLW enabled, both upstream and downstream width should be the same during bootup.
+usMaxHTLinkWidth:   Bootup maximum HT link width. If CDLW disabled, this is equal to usMinHTLinkWidth. 
+                    If CDLW enabled, both upstream and downstream width should be the same during bootup.  
 
-usUMASyncStartDelay: Memory access latency, required for watermark calculation
+usUMASyncStartDelay: Memory access latency, required for watermark calculation 
 usUMADataReturnTime: Memory access latency, required for watermark calculation
-usLinkStatusZeroTime:Memory access latency required for watermark calculation, set this to 0x0 for K8 CPU, set a proper value in 0.01 the unit of us
+usLinkStatusZeroTime:Memory access latency required for watermark calculation, set this to 0x0 for K8 CPU, set a proper value in 0.01 the unit of us 
 for Griffin or Greyhound. SBIOS needs to convert to actual time by:
                      if T0Ttime [5:4]=00b, then usLinkStatusZeroTime=T0Ttime [3:0]*0.1us (0.0 to 1.5us)
                      if T0Ttime [5:4]=01b, then usLinkStatusZeroTime=T0Ttime [3:0]*0.5us (0.0 to 7.5us)
@@ -1817,7 +2240,7 @@ for Griffin or Greyhound. SBIOS needs to
                      if T0Ttime [5:4]=11b, and T0Ttime [3:0]=0x0 to 0xa, then usLinkStatusZeroTime=T0Ttime [3:0]*20us (0.0 to 200us)
 
 ulHighVoltageHTLinkFreq:     HT link frequency for power state with low voltage. If boot up runs in HT1, this must be 0.
-                             This must be less than or equal to ulHTLinkFreq(bootup frequency).
+                             This must be less than or equal to ulHTLinkFreq(bootup frequency). 
 ulLowVoltageHTLinkFreq:      HT link frequency for power state with low voltage or voltage scaling 1.0v~1.1v. If boot up runs in HT1, this must be 0.
                              This must be less than or equal to ulHighVoltageHTLinkFreq.
 
@@ -1827,14 +2250,17 @@ usMinUpStreamHTLinkWidth:    Asymmetric
 usMinDownStreamHTLinkWidth:  same as above.
 */
 
+
 #define SYSTEM_CONFIG_POWEREXPRESS_ENABLE                 0x00000001
 #define SYSTEM_CONFIG_RUN_AT_OVERDRIVE_ENGINE             0x00000002
-#define SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE                  0x00000004
+#define SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE                  0x00000004 
 #define SYSTEM_CONFIG_PERFORMANCE_POWERSTATE_ONLY         0x00000008
 #define SYSTEM_CONFIG_CLMC_ENABLED                        0x00000010
 #define SYSTEM_CONFIG_CDLW_ENABLED                        0x00000020
 #define SYSTEM_CONFIG_HIGH_VOLTAGE_REQUESTED              0x00000040
 #define SYSTEM_CONFIG_CLMC_HYBRID_MODE_ENABLED            0x00000080
+#define SYSTEM_CONFIG_CDLF_ENABLED                        0x00000100
+#define SYSTEM_CONFIG_DLL_SHUTDOWN_ENABLED                0x00000200
 
 #define IGP_DDI_SLOT_LANE_CONFIG_MASK                     0x000000FF
 
@@ -1851,6 +2277,41 @@ usMinDownStreamHTLinkWidth:  same as abo
 
 #define IGP_DDI_SLOT_CONNECTOR_TYPE_MASK                  0x00FF0000
 
+// IntegratedSystemInfoTable new Rev is V5 after V2, because of the real rev of V2 is v1.4. This rev is used for RR
+typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V5
+{
+  ATOM_COMMON_TABLE_HEADER   sHeader;
+  ULONG	                     ulBootUpEngineClock;       //in 10kHz unit
+  ULONG                      ulDentistVCOFreq;          //Dentist VCO clock in 10kHz unit, the source of GPU SCLK, LCLK, UCLK and VCLK. 
+  ULONG                      ulLClockFreq;              //GPU Lclk freq in 10kHz unit, have relationship with NCLK in NorthBridge
+  ULONG	                     ulBootUpUMAClock;          //in 10kHz unit
+  ULONG                      ulReserved1[8];            //must be 0x0 for the reserved
+  ULONG                      ulBootUpReqDisplayVector;
+  ULONG                      ulOtherDisplayMisc;
+  ULONG                      ulReserved2[4];            //must be 0x0 for the reserved
+  ULONG                      ulSystemConfig;            //TBD
+  ULONG                      ulCPUCapInfo;              //TBD
+  USHORT                     usMaxNBVoltage;            //high NB voltage, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse;
+  USHORT                     usMinNBVoltage;            //low NB voltage, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse;
+  USHORT                     usBootUpNBVoltage;         //boot up NB voltage
+  UCHAR                      ucHtcTmpLmt;               //bit [22:16] of D24F3x64 Hardware Thermal Control (HTC) Register, may not be needed, TBD
+  UCHAR                      ucTjOffset;                //bit [28:22] of D24F3xE4 Thermtrip Status Register,may not be needed, TBD
+  ULONG                      ulReserved3[4];            //must be 0x0 for the reserved
+  ULONG                      ulDDISlot1Config;          //see above ulDDISlot1Config definition
+  ULONG                      ulDDISlot2Config;
+  ULONG                      ulDDISlot3Config;
+  ULONG                      ulDDISlot4Config;
+  ULONG                      ulReserved4[4];            //must be 0x0 for the reserved
+  UCHAR                      ucMemoryType;              //[3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved
+  UCHAR                      ucUMAChannelNumber;
+  USHORT                     usReserved;
+  ULONG                      ulReserved5[4];            //must be 0x0 for the reserved
+  ULONG                      ulCSR_M3_ARB_CNTL_DEFAULT[10];//arrays with values for CSR M3 arbiter for default
+  ULONG                      ulCSR_M3_ARB_CNTL_UVD[10]; //arrays with values for CSR M3 arbiter for UVD playback
+  ULONG                      ulCSR_M3_ARB_CNTL_FS3D[10];//arrays with values for CSR M3 arbiter for Full Screen 3D applications
+  ULONG                      ulReserved6[61];           //must be 0x0
+}ATOM_INTEGRATED_SYSTEM_INFO_V5;   
+
 #define ATOM_CRT_INT_ENCODER1_INDEX                       0x00000000
 #define ATOM_LCD_INT_ENCODER1_INDEX                       0x00000001
 #define ATOM_TV_INT_ENCODER1_INDEX                        0x00000002
@@ -1866,8 +2327,8 @@ usMinDownStreamHTLinkWidth:  same as abo
 #define ATOM_DFP_INT_ENCODER3_INDEX                       0x0000000C
 #define ATOM_DFP_INT_ENCODER4_INDEX                       0x0000000D
 
-/*  define ASIC internal encoder id ( bit vector ) */
-#define ASIC_INT_DAC1_ENCODER_ID											0x00
+// define ASIC internal encoder id ( bit vector ), used for CRTC_SourceSelTable
+#define ASIC_INT_DAC1_ENCODER_ID    											0x00 
 #define ASIC_INT_TV_ENCODER_ID														0x02
 #define ASIC_INT_DIG1_ENCODER_ID													0x03
 #define ASIC_INT_DAC2_ENCODER_ID													0x04
@@ -1875,10 +2336,24 @@ usMinDownStreamHTLinkWidth:  same as abo
 #define ASIC_INT_DVO_ENCODER_ID														0x07
 #define ASIC_INT_DIG2_ENCODER_ID													0x09
 #define ASIC_EXT_DIG_ENCODER_ID														0x05
+#define ASIC_EXT_DIG2_ENCODER_ID													0x08
+#define ASIC_INT_DIG3_ENCODER_ID													0x0a
+#define ASIC_INT_DIG4_ENCODER_ID													0x0b
+#define ASIC_INT_DIG5_ENCODER_ID													0x0c
+#define ASIC_INT_DIG6_ENCODER_ID													0x0d
 
-/* define Encoder attribute */
+//define Encoder attribute
 #define ATOM_ANALOG_ENCODER																0
-#define ATOM_DIGITAL_ENCODER															1
+#define ATOM_DIGITAL_ENCODER															1		
+#define ATOM_DP_ENCODER															      2		
+
+#define ATOM_ENCODER_ENUM_MASK                            0x70
+#define ATOM_ENCODER_ENUM_ID1                             0x00
+#define ATOM_ENCODER_ENUM_ID2                             0x10
+#define ATOM_ENCODER_ENUM_ID3                             0x20
+#define ATOM_ENCODER_ENUM_ID4                             0x30
+#define ATOM_ENCODER_ENUM_ID5                             0x40 
+#define ATOM_ENCODER_ENUM_ID6                             0x50
 
 #define ATOM_DEVICE_CRT1_INDEX                            0x00000000
 #define ATOM_DEVICE_LCD1_INDEX                            0x00000001
@@ -1886,45 +2361,40 @@ usMinDownStreamHTLinkWidth:  same as abo
 #define ATOM_DEVICE_DFP1_INDEX                            0x00000003
 #define ATOM_DEVICE_CRT2_INDEX                            0x00000004
 #define ATOM_DEVICE_LCD2_INDEX                            0x00000005
-#define ATOM_DEVICE_TV2_INDEX                             0x00000006
+#define ATOM_DEVICE_DFP6_INDEX                            0x00000006
 #define ATOM_DEVICE_DFP2_INDEX                            0x00000007
 #define ATOM_DEVICE_CV_INDEX                              0x00000008
-#define ATOM_DEVICE_DFP3_INDEX														0x00000009
-#define ATOM_DEVICE_DFP4_INDEX														0x0000000A
-#define ATOM_DEVICE_DFP5_INDEX														0x0000000B
+#define ATOM_DEVICE_DFP3_INDEX                            0x00000009
+#define ATOM_DEVICE_DFP4_INDEX                            0x0000000A
+#define ATOM_DEVICE_DFP5_INDEX                            0x0000000B
+
 #define ATOM_DEVICE_RESERVEDC_INDEX                       0x0000000C
 #define ATOM_DEVICE_RESERVEDD_INDEX                       0x0000000D
 #define ATOM_DEVICE_RESERVEDE_INDEX                       0x0000000E
 #define ATOM_DEVICE_RESERVEDF_INDEX                       0x0000000F
 #define ATOM_MAX_SUPPORTED_DEVICE_INFO                    (ATOM_DEVICE_DFP3_INDEX+1)
 #define ATOM_MAX_SUPPORTED_DEVICE_INFO_2                  ATOM_MAX_SUPPORTED_DEVICE_INFO
-#define ATOM_MAX_SUPPORTED_DEVICE_INFO_3                  (ATOM_DEVICE_DFP5_INDEX + 1)
+#define ATOM_MAX_SUPPORTED_DEVICE_INFO_3                  (ATOM_DEVICE_DFP5_INDEX + 1 )
 
 #define ATOM_MAX_SUPPORTED_DEVICE                         (ATOM_DEVICE_RESERVEDF_INDEX+1)
 
-#define ATOM_DEVICE_CRT1_SUPPORT                          (0x1L << ATOM_DEVICE_CRT1_INDEX)
-#define ATOM_DEVICE_LCD1_SUPPORT                          (0x1L << ATOM_DEVICE_LCD1_INDEX)
-#define ATOM_DEVICE_TV1_SUPPORT                           (0x1L << ATOM_DEVICE_TV1_INDEX)
-#define ATOM_DEVICE_DFP1_SUPPORT                          (0x1L << ATOM_DEVICE_DFP1_INDEX)
-#define ATOM_DEVICE_CRT2_SUPPORT                          (0x1L << ATOM_DEVICE_CRT2_INDEX)
-#define ATOM_DEVICE_LCD2_SUPPORT                          (0x1L << ATOM_DEVICE_LCD2_INDEX)
-#define ATOM_DEVICE_TV2_SUPPORT                           (0x1L << ATOM_DEVICE_TV2_INDEX)
-#define ATOM_DEVICE_DFP2_SUPPORT                          (0x1L << ATOM_DEVICE_DFP2_INDEX)
-#define ATOM_DEVICE_CV_SUPPORT                            (0x1L << ATOM_DEVICE_CV_INDEX)
-#define ATOM_DEVICE_DFP3_SUPPORT													(0x1L << ATOM_DEVICE_DFP3_INDEX)
-#define ATOM_DEVICE_DFP4_SUPPORT													(0x1L << ATOM_DEVICE_DFP4_INDEX )
-#define ATOM_DEVICE_DFP5_SUPPORT													(0x1L << ATOM_DEVICE_DFP5_INDEX)
+#define ATOM_DEVICE_CRT1_SUPPORT                          (0x1L << ATOM_DEVICE_CRT1_INDEX )
+#define ATOM_DEVICE_LCD1_SUPPORT                          (0x1L << ATOM_DEVICE_LCD1_INDEX )
+#define ATOM_DEVICE_TV1_SUPPORT                           (0x1L << ATOM_DEVICE_TV1_INDEX  )
+#define ATOM_DEVICE_DFP1_SUPPORT                          (0x1L << ATOM_DEVICE_DFP1_INDEX )
+#define ATOM_DEVICE_CRT2_SUPPORT                          (0x1L << ATOM_DEVICE_CRT2_INDEX )
+#define ATOM_DEVICE_LCD2_SUPPORT                          (0x1L << ATOM_DEVICE_LCD2_INDEX )
+#define ATOM_DEVICE_DFP6_SUPPORT                          (0x1L << ATOM_DEVICE_DFP6_INDEX )
+#define ATOM_DEVICE_DFP2_SUPPORT                          (0x1L << ATOM_DEVICE_DFP2_INDEX )
+#define ATOM_DEVICE_CV_SUPPORT                            (0x1L << ATOM_DEVICE_CV_INDEX   )
+#define ATOM_DEVICE_DFP3_SUPPORT                          (0x1L << ATOM_DEVICE_DFP3_INDEX )
+#define ATOM_DEVICE_DFP4_SUPPORT                          (0x1L << ATOM_DEVICE_DFP4_INDEX )
+#define ATOM_DEVICE_DFP5_SUPPORT                          (0x1L << ATOM_DEVICE_DFP5_INDEX )
 
-#define ATOM_DEVICE_CRT_SUPPORT \
-	(ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_CRT2_SUPPORT)
-#define ATOM_DEVICE_DFP_SUPPORT \
-	(ATOM_DEVICE_DFP1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT | \
-	 ATOM_DEVICE_DFP3_SUPPORT | ATOM_DEVICE_DFP4_SUPPORT | \
-	 ATOM_DEVICE_DFP5_SUPPORT)
-#define ATOM_DEVICE_TV_SUPPORT \
-	(ATOM_DEVICE_TV1_SUPPORT  | ATOM_DEVICE_TV2_SUPPORT)
-#define ATOM_DEVICE_LCD_SUPPORT \
-	(ATOM_DEVICE_LCD1_SUPPORT | ATOM_DEVICE_LCD2_SUPPORT)
+#define ATOM_DEVICE_CRT_SUPPORT                           (ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_CRT2_SUPPORT)
+#define ATOM_DEVICE_DFP_SUPPORT                           (ATOM_DEVICE_DFP1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT |  ATOM_DEVICE_DFP3_SUPPORT | ATOM_DEVICE_DFP4_SUPPORT | ATOM_DEVICE_DFP5_SUPPORT | ATOM_DEVICE_DFP6_SUPPORT)
+#define ATOM_DEVICE_TV_SUPPORT                            (ATOM_DEVICE_TV1_SUPPORT)
+#define ATOM_DEVICE_LCD_SUPPORT                           (ATOM_DEVICE_LCD1_SUPPORT | ATOM_DEVICE_LCD2_SUPPORT)
 
 #define ATOM_DEVICE_CONNECTOR_TYPE_MASK                   0x000000F0
 #define ATOM_DEVICE_CONNECTOR_TYPE_SHIFT                  0x00000004
@@ -1942,6 +2412,7 @@ usMinDownStreamHTLinkWidth:  same as abo
 #define ATOM_DEVICE_CONNECTOR_CASE_1                      0x0000000E
 #define ATOM_DEVICE_CONNECTOR_DISPLAYPORT                 0x0000000F
 
+
 #define ATOM_DEVICE_DAC_INFO_MASK                         0x0000000F
 #define ATOM_DEVICE_DAC_INFO_SHIFT                        0x00000000
 #define ATOM_DEVICE_DAC_INFO_NODAC                        0x00000000
@@ -1958,139 +2429,150 @@ usMinDownStreamHTLinkWidth:  same as abo
 #define ATOM_DEVICE_I2C_ID_SHIFT                          0x00000004
 #define ATOM_DEVICE_I2C_ID_IS_FOR_NON_MM_USE              0x00000001
 #define ATOM_DEVICE_I2C_ID_IS_FOR_MM_USE                  0x00000002
-#define ATOM_DEVICE_I2C_ID_IS_FOR_SDVO_USE                0x00000003	/* For IGP RS600 */
-#define ATOM_DEVICE_I2C_ID_IS_FOR_DAC_SCL                 0x00000004	/* For IGP RS690 */
+#define ATOM_DEVICE_I2C_ID_IS_FOR_SDVO_USE                0x00000003    //For IGP RS600
+#define ATOM_DEVICE_I2C_ID_IS_FOR_DAC_SCL                 0x00000004    //For IGP RS690
 
 #define ATOM_DEVICE_I2C_HARDWARE_CAP_MASK                 0x00000080
 #define ATOM_DEVICE_I2C_HARDWARE_CAP_SHIFT                0x00000007
 #define	ATOM_DEVICE_USES_SOFTWARE_ASSISTED_I2C            0x00000000
 #define	ATOM_DEVICE_USES_HARDWARE_ASSISTED_I2C            0x00000001
 
-/*   usDeviceSupport: */
-/*   Bits0       = 0 - no CRT1 support= 1- CRT1 is supported */
-/*   Bit 1       = 0 - no LCD1 support= 1- LCD1 is supported */
-/*   Bit 2       = 0 - no TV1  support= 1- TV1  is supported */
-/*   Bit 3       = 0 - no DFP1 support= 1- DFP1 is supported */
-/*   Bit 4       = 0 - no CRT2 support= 1- CRT2 is supported */
-/*   Bit 5       = 0 - no LCD2 support= 1- LCD2 is supported */
-/*   Bit 6       = 0 - no TV2  support= 1- TV2  is supported */
-/*   Bit 7       = 0 - no DFP2 support= 1- DFP2 is supported */
-/*   Bit 8       = 0 - no CV   support= 1- CV   is supported */
-/*   Bit 9       = 0 - no DFP3 support= 1- DFP3 is supported */
-/*   Byte1 (Supported Device Info) */
-/*   Bit 0       = = 0 - no CV support= 1- CV is supported */
-/*  */
-/*  */
+//  usDeviceSupport:
+//  Bits0	= 0 - no CRT1 support= 1- CRT1 is supported
+//  Bit 1	= 0 - no LCD1 support= 1- LCD1 is supported
+//  Bit 2	= 0 - no TV1  support= 1- TV1  is supported
+//  Bit 3	= 0 - no DFP1 support= 1- DFP1 is supported
+//  Bit 4	= 0 - no CRT2 support= 1- CRT2 is supported
+//  Bit 5	= 0 - no LCD2 support= 1- LCD2 is supported
+//  Bit 6	= 0 - no DFP6 support= 1- DFP6 is supported
+//  Bit 7	= 0 - no DFP2 support= 1- DFP2 is supported
+//  Bit 8	= 0 - no CV   support= 1- CV   is supported
+//  Bit 9	= 0 - no DFP3 support= 1- DFP3 is supported
+//  Bit 10      = 0 - no DFP4 support= 1- DFP4 is supported
+//  Bit 11      = 0 - no DFP5 support= 1- DFP5 is supported
+//   
+//  
 
-/*               ucI2C_ConfigID */
-/*     [7:0] - I2C LINE Associate ID */
-/*           = 0   - no I2C */
-/*     [7]               -       HW_Cap        = 1,  [6:0]=HW assisted I2C ID(HW line selection) */
-/*                           =   0,  [6:0]=SW assisted I2C ID */
-/*     [6-4]     - HW_ENGINE_ID  =       1,  HW engine for NON multimedia use */
-/*                           =   2,      HW engine for Multimedia use */
-/*                           =   3-7     Reserved for future I2C engines */
-/*               [3-0] - I2C_LINE_MUX  = A Mux number when it's HW assisted I2C or GPIO ID when it's SW I2C */
+/****************************************************************************/
+/* Structure used in MclkSS_InfoTable                                       */
+/****************************************************************************/
+//		ucI2C_ConfigID
+//    [7:0] - I2C LINE Associate ID
+//          = 0   - no I2C
+//    [7]		-	HW_Cap        =	1,  [6:0]=HW assisted I2C ID(HW line selection)
+//                          =	0,  [6:0]=SW assisted I2C ID
+//    [6-4]	- HW_ENGINE_ID  =	1,  HW engine for NON multimedia use
+//                          =	2,	HW engine for Multimedia use
+//                          =	3-7	Reserved for future I2C engines
+//		[3-0] - I2C_LINE_MUX  = A Mux number when it's HW assisted I2C or GPIO ID when it's SW I2C
 
-typedef struct _ATOM_I2C_ID_CONFIG {
+typedef struct _ATOM_I2C_ID_CONFIG
+{
 #if ATOM_BIG_ENDIAN
-	UCHAR bfHW_Capable:1;
-	UCHAR bfHW_EngineID:3;
-	UCHAR bfI2C_LineMux:4;
+  UCHAR   bfHW_Capable:1;
+  UCHAR   bfHW_EngineID:3;
+  UCHAR   bfI2C_LineMux:4;
 #else
-	UCHAR bfI2C_LineMux:4;
-	UCHAR bfHW_EngineID:3;
-	UCHAR bfHW_Capable:1;
+  UCHAR   bfI2C_LineMux:4;
+  UCHAR   bfHW_EngineID:3;
+  UCHAR   bfHW_Capable:1;
 #endif
-} ATOM_I2C_ID_CONFIG;
+}ATOM_I2C_ID_CONFIG;
 
-typedef union _ATOM_I2C_ID_CONFIG_ACCESS {
-	ATOM_I2C_ID_CONFIG sbfAccess;
-	UCHAR ucAccess;
-} ATOM_I2C_ID_CONFIG_ACCESS;
+typedef union _ATOM_I2C_ID_CONFIG_ACCESS
+{
+  ATOM_I2C_ID_CONFIG sbfAccess;
+  UCHAR              ucAccess;
+}ATOM_I2C_ID_CONFIG_ACCESS;
+   
 
-/****************************************************************************/
-/*  Structure used in GPIO_I2C_InfoTable */
-/****************************************************************************/
-typedef struct _ATOM_GPIO_I2C_ASSIGMENT {
-	USHORT usClkMaskRegisterIndex;
-	USHORT usClkEnRegisterIndex;
-	USHORT usClkY_RegisterIndex;
-	USHORT usClkA_RegisterIndex;
-	USHORT usDataMaskRegisterIndex;
-	USHORT usDataEnRegisterIndex;
-	USHORT usDataY_RegisterIndex;
-	USHORT usDataA_RegisterIndex;
-	ATOM_I2C_ID_CONFIG_ACCESS sucI2cId;
-	UCHAR ucClkMaskShift;
-	UCHAR ucClkEnShift;
-	UCHAR ucClkY_Shift;
-	UCHAR ucClkA_Shift;
-	UCHAR ucDataMaskShift;
-	UCHAR ucDataEnShift;
-	UCHAR ucDataY_Shift;
-	UCHAR ucDataA_Shift;
-	UCHAR ucReserved1;
-	UCHAR ucReserved2;
-} ATOM_GPIO_I2C_ASSIGMENT;
+/****************************************************************************/	
+// Structure used in GPIO_I2C_InfoTable
+/****************************************************************************/	
+typedef struct _ATOM_GPIO_I2C_ASSIGMENT
+{
+  USHORT                    usClkMaskRegisterIndex;
+  USHORT                    usClkEnRegisterIndex;
+  USHORT                    usClkY_RegisterIndex;
+  USHORT                    usClkA_RegisterIndex;
+  USHORT                    usDataMaskRegisterIndex;
+  USHORT                    usDataEnRegisterIndex;
+  USHORT                    usDataY_RegisterIndex;
+  USHORT                    usDataA_RegisterIndex;
+  ATOM_I2C_ID_CONFIG_ACCESS sucI2cId;
+  UCHAR                     ucClkMaskShift;
+  UCHAR                     ucClkEnShift;
+  UCHAR                     ucClkY_Shift;
+  UCHAR                     ucClkA_Shift;
+  UCHAR                     ucDataMaskShift;
+  UCHAR                     ucDataEnShift;
+  UCHAR                     ucDataY_Shift;
+  UCHAR                     ucDataA_Shift;
+  UCHAR                     ucReserved1;
+  UCHAR                     ucReserved2;
+}ATOM_GPIO_I2C_ASSIGMENT;
 
-typedef struct _ATOM_GPIO_I2C_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ATOM_GPIO_I2C_ASSIGMENT asGPIO_Info[ATOM_MAX_SUPPORTED_DEVICE];
-} ATOM_GPIO_I2C_INFO;
+typedef struct _ATOM_GPIO_I2C_INFO
+{ 
+  ATOM_COMMON_TABLE_HEADER	sHeader;
+  ATOM_GPIO_I2C_ASSIGMENT   asGPIO_Info[ATOM_MAX_SUPPORTED_DEVICE];
+}ATOM_GPIO_I2C_INFO;
 
-/****************************************************************************/
-/*  Common Structure used in other structures */
-/****************************************************************************/
+/****************************************************************************/	
+// Common Structure used in other structures
+/****************************************************************************/	
 
 #ifndef _H2INC
-
-/* Please don't add or expand this bitfield structure below, this one will retire soon.! */
-typedef struct _ATOM_MODE_MISC_INFO {
+  
+//Please don't add or expand this bitfield structure below, this one will retire soon.!
+typedef struct _ATOM_MODE_MISC_INFO
+{ 
 #if ATOM_BIG_ENDIAN
-	USHORT Reserved:6;
-	USHORT RGB888:1;
-	USHORT DoubleClock:1;
-	USHORT Interlace:1;
-	USHORT CompositeSync:1;
-	USHORT V_ReplicationBy2:1;
-	USHORT H_ReplicationBy2:1;
-	USHORT VerticalCutOff:1;
-	USHORT VSyncPolarity:1;	/* 0=Active High, 1=Active Low */
-	USHORT HSyncPolarity:1;	/* 0=Active High, 1=Active Low */
-	USHORT HorizontalCutOff:1;
+  USHORT Reserved:6;
+  USHORT RGB888:1;
+  USHORT DoubleClock:1;
+  USHORT Interlace:1;
+  USHORT CompositeSync:1;
+  USHORT V_ReplicationBy2:1;
+  USHORT H_ReplicationBy2:1;
+  USHORT VerticalCutOff:1;
+  USHORT VSyncPolarity:1;      //0=Active High, 1=Active Low
+  USHORT HSyncPolarity:1;      //0=Active High, 1=Active Low
+  USHORT HorizontalCutOff:1;
 #else
-	USHORT HorizontalCutOff:1;
-	USHORT HSyncPolarity:1;	/* 0=Active High, 1=Active Low */
-	USHORT VSyncPolarity:1;	/* 0=Active High, 1=Active Low */
-	USHORT VerticalCutOff:1;
-	USHORT H_ReplicationBy2:1;
-	USHORT V_ReplicationBy2:1;
-	USHORT CompositeSync:1;
-	USHORT Interlace:1;
-	USHORT DoubleClock:1;
-	USHORT RGB888:1;
-	USHORT Reserved:6;
+  USHORT HorizontalCutOff:1;
+  USHORT HSyncPolarity:1;      //0=Active High, 1=Active Low
+  USHORT VSyncPolarity:1;      //0=Active High, 1=Active Low
+  USHORT VerticalCutOff:1;
+  USHORT H_ReplicationBy2:1;
+  USHORT V_ReplicationBy2:1;
+  USHORT CompositeSync:1;
+  USHORT Interlace:1;
+  USHORT DoubleClock:1;
+  USHORT RGB888:1;
+  USHORT Reserved:6;           
 #endif
-} ATOM_MODE_MISC_INFO;
-
-typedef union _ATOM_MODE_MISC_INFO_ACCESS {
-	ATOM_MODE_MISC_INFO sbfAccess;
-	USHORT usAccess;
-} ATOM_MODE_MISC_INFO_ACCESS;
-
+}ATOM_MODE_MISC_INFO;
+  
+typedef union _ATOM_MODE_MISC_INFO_ACCESS
+{ 
+  ATOM_MODE_MISC_INFO sbfAccess;
+  USHORT              usAccess;
+}ATOM_MODE_MISC_INFO_ACCESS;
+  
 #else
-
-typedef union _ATOM_MODE_MISC_INFO_ACCESS {
-	USHORT usAccess;
-} ATOM_MODE_MISC_INFO_ACCESS;
-
+  
+typedef union _ATOM_MODE_MISC_INFO_ACCESS
+{ 
+  USHORT              usAccess;
+}ATOM_MODE_MISC_INFO_ACCESS;
+   
 #endif
 
-/*  usModeMiscInfo- */
+// usModeMiscInfo-
 #define ATOM_H_CUTOFF           0x01
-#define ATOM_HSYNC_POLARITY     0x02	/* 0=Active High, 1=Active Low */
-#define ATOM_VSYNC_POLARITY     0x04	/* 0=Active High, 1=Active Low */
+#define ATOM_HSYNC_POLARITY     0x02             //0=Active High, 1=Active Low
+#define ATOM_VSYNC_POLARITY     0x04             //0=Active High, 1=Active Low
 #define ATOM_V_CUTOFF           0x08
 #define ATOM_H_REPLICATIONBY2   0x10
 #define ATOM_V_REPLICATIONBY2   0x20
@@ -2099,10 +2581,10 @@ typedef union _ATOM_MODE_MISC_INFO_ACCES
 #define ATOM_DOUBLE_CLOCK_MODE  0x100
 #define ATOM_RGB888_MODE        0x200
 
-/* usRefreshRate- */
+//usRefreshRate-
 #define ATOM_REFRESH_43         43
 #define ATOM_REFRESH_47         47
-#define ATOM_REFRESH_56         56
+#define ATOM_REFRESH_56         56	
 #define ATOM_REFRESH_60         60
 #define ATOM_REFRESH_65         65
 #define ATOM_REFRESH_70         70
@@ -2110,192 +2592,233 @@ typedef union _ATOM_MODE_MISC_INFO_ACCES
 #define ATOM_REFRESH_75         75
 #define ATOM_REFRESH_85         85
 
-/*  ATOM_MODE_TIMING data are exactly the same as VESA timing data. */
-/*  Translation from EDID to ATOM_MODE_TIMING, use the following formula. */
-/*  */
-/*       VESA_HTOTAL                     =       VESA_ACTIVE + 2* VESA_BORDER + VESA_BLANK */
-/*                                               =       EDID_HA + EDID_HBL */
-/*       VESA_HDISP                      =       VESA_ACTIVE     =       EDID_HA */
-/*       VESA_HSYNC_START        =       VESA_ACTIVE + VESA_BORDER + VESA_FRONT_PORCH */
-/*                                               =       EDID_HA + EDID_HSO */
-/*       VESA_HSYNC_WIDTH        =       VESA_HSYNC_TIME =       EDID_HSPW */
-/*       VESA_BORDER                     =       EDID_BORDER */
+// ATOM_MODE_TIMING data are exactly the same as VESA timing data.
+// Translation from EDID to ATOM_MODE_TIMING, use the following formula.
+//
+//	VESA_HTOTAL			=	VESA_ACTIVE + 2* VESA_BORDER + VESA_BLANK
+//						=	EDID_HA + EDID_HBL
+//	VESA_HDISP			=	VESA_ACTIVE	=	EDID_HA
+//	VESA_HSYNC_START	=	VESA_ACTIVE + VESA_BORDER + VESA_FRONT_PORCH
+//						=	EDID_HA + EDID_HSO
+//	VESA_HSYNC_WIDTH	=	VESA_HSYNC_TIME	=	EDID_HSPW
+//	VESA_BORDER			=	EDID_BORDER
 
-/****************************************************************************/
-/*  Structure used in SetCRTC_UsingDTDTimingTable */
-/****************************************************************************/
-typedef struct _SET_CRTC_USING_DTD_TIMING_PARAMETERS {
-	USHORT usH_Size;
-	USHORT usH_Blanking_Time;
-	USHORT usV_Size;
-	USHORT usV_Blanking_Time;
-	USHORT usH_SyncOffset;
-	USHORT usH_SyncWidth;
-	USHORT usV_SyncOffset;
-	USHORT usV_SyncWidth;
-	ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo;
-	UCHAR ucH_Border;	/*  From DFP EDID */
-	UCHAR ucV_Border;
-	UCHAR ucCRTC;		/*  ATOM_CRTC1 or ATOM_CRTC2 */
-	UCHAR ucPadding[3];
-} SET_CRTC_USING_DTD_TIMING_PARAMETERS;
+/****************************************************************************/	
+// Structure used in SetCRTC_UsingDTDTimingTable
+/****************************************************************************/	
+typedef struct _SET_CRTC_USING_DTD_TIMING_PARAMETERS
+{
+  USHORT  usH_Size;
+  USHORT  usH_Blanking_Time;
+  USHORT  usV_Size;
+  USHORT  usV_Blanking_Time;			
+  USHORT  usH_SyncOffset;
+  USHORT  usH_SyncWidth;
+  USHORT  usV_SyncOffset;
+  USHORT  usV_SyncWidth;
+  ATOM_MODE_MISC_INFO_ACCESS  susModeMiscInfo;  
+  UCHAR   ucH_Border;         // From DFP EDID
+  UCHAR   ucV_Border;
+  UCHAR   ucCRTC;             // ATOM_CRTC1 or ATOM_CRTC2  
+  UCHAR   ucPadding[3];
+}SET_CRTC_USING_DTD_TIMING_PARAMETERS;
 
-/****************************************************************************/
-/*  Structure used in SetCRTC_TimingTable */
-/****************************************************************************/
-typedef struct _SET_CRTC_TIMING_PARAMETERS {
-	USHORT usH_Total;	/*  horizontal total */
-	USHORT usH_Disp;	/*  horizontal display */
-	USHORT usH_SyncStart;	/*  horozontal Sync start */
-	USHORT usH_SyncWidth;	/*  horizontal Sync width */
-	USHORT usV_Total;	/*  vertical total */
-	USHORT usV_Disp;	/*  vertical display */
-	USHORT usV_SyncStart;	/*  vertical Sync start */
-	USHORT usV_SyncWidth;	/*  vertical Sync width */
-	ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo;
-	UCHAR ucCRTC;		/*  ATOM_CRTC1 or ATOM_CRTC2 */
-	UCHAR ucOverscanRight;	/*  right */
-	UCHAR ucOverscanLeft;	/*  left */
-	UCHAR ucOverscanBottom;	/*  bottom */
-	UCHAR ucOverscanTop;	/*  top */
-	UCHAR ucReserved;
-} SET_CRTC_TIMING_PARAMETERS;
+/****************************************************************************/	
+// Structure used in SetCRTC_TimingTable
+/****************************************************************************/	
+typedef struct _SET_CRTC_TIMING_PARAMETERS
+{
+  USHORT                      usH_Total;        // horizontal total
+  USHORT                      usH_Disp;         // horizontal display
+  USHORT                      usH_SyncStart;    // horozontal Sync start
+  USHORT                      usH_SyncWidth;    // horizontal Sync width
+  USHORT                      usV_Total;        // vertical total
+  USHORT                      usV_Disp;         // vertical display
+  USHORT                      usV_SyncStart;    // vertical Sync start
+  USHORT                      usV_SyncWidth;    // vertical Sync width
+  ATOM_MODE_MISC_INFO_ACCESS  susModeMiscInfo;
+  UCHAR                       ucCRTC;           // ATOM_CRTC1 or ATOM_CRTC2
+  UCHAR                       ucOverscanRight;  // right
+  UCHAR                       ucOverscanLeft;   // left
+  UCHAR                       ucOverscanBottom; // bottom
+  UCHAR                       ucOverscanTop;    // top
+  UCHAR                       ucReserved;
+}SET_CRTC_TIMING_PARAMETERS;
 #define SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION SET_CRTC_TIMING_PARAMETERS
 
-/****************************************************************************/
-/*  Structure used in StandardVESA_TimingTable */
-/*                    AnalogTV_InfoTable */
-/*                    ComponentVideoInfoTable */
-/****************************************************************************/
-typedef struct _ATOM_MODE_TIMING {
-	USHORT usCRTC_H_Total;
-	USHORT usCRTC_H_Disp;
-	USHORT usCRTC_H_SyncStart;
-	USHORT usCRTC_H_SyncWidth;
-	USHORT usCRTC_V_Total;
-	USHORT usCRTC_V_Disp;
-	USHORT usCRTC_V_SyncStart;
-	USHORT usCRTC_V_SyncWidth;
-	USHORT usPixelClock;	/* in 10Khz unit */
-	ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo;
-	USHORT usCRTC_OverscanRight;
-	USHORT usCRTC_OverscanLeft;
-	USHORT usCRTC_OverscanBottom;
-	USHORT usCRTC_OverscanTop;
-	USHORT usReserve;
-	UCHAR ucInternalModeNumber;
-	UCHAR ucRefreshRate;
-} ATOM_MODE_TIMING;
+/****************************************************************************/	
+// Structure used in StandardVESA_TimingTable
+//                   AnalogTV_InfoTable 
+//                   ComponentVideoInfoTable
+/****************************************************************************/	
+typedef struct _ATOM_MODE_TIMING
+{
+  USHORT  usCRTC_H_Total;
+  USHORT  usCRTC_H_Disp;
+  USHORT  usCRTC_H_SyncStart;
+  USHORT  usCRTC_H_SyncWidth;
+  USHORT  usCRTC_V_Total;
+  USHORT  usCRTC_V_Disp;
+  USHORT  usCRTC_V_SyncStart;
+  USHORT  usCRTC_V_SyncWidth;
+  USHORT  usPixelClock;					                 //in 10Khz unit
+  ATOM_MODE_MISC_INFO_ACCESS  susModeMiscInfo;
+  USHORT  usCRTC_OverscanRight;
+  USHORT  usCRTC_OverscanLeft;
+  USHORT  usCRTC_OverscanBottom;
+  USHORT  usCRTC_OverscanTop;
+  USHORT  usReserve;
+  UCHAR   ucInternalModeNumber;
+  UCHAR   ucRefreshRate;
+}ATOM_MODE_TIMING;
 
-typedef struct _ATOM_DTD_FORMAT {
-	USHORT usPixClk;
-	USHORT usHActive;
-	USHORT usHBlanking_Time;
-	USHORT usVActive;
-	USHORT usVBlanking_Time;
-	USHORT usHSyncOffset;
-	USHORT usHSyncWidth;
-	USHORT usVSyncOffset;
-	USHORT usVSyncWidth;
-	USHORT usImageHSize;
-	USHORT usImageVSize;
-	UCHAR ucHBorder;
-	UCHAR ucVBorder;
-	ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo;
-	UCHAR ucInternalModeNumber;
-	UCHAR ucRefreshRate;
-} ATOM_DTD_FORMAT;
+typedef struct _ATOM_DTD_FORMAT
+{
+  USHORT  usPixClk;
+  USHORT  usHActive;
+  USHORT  usHBlanking_Time;
+  USHORT  usVActive;
+  USHORT  usVBlanking_Time;			
+  USHORT  usHSyncOffset;
+  USHORT  usHSyncWidth;
+  USHORT  usVSyncOffset;
+  USHORT  usVSyncWidth;
+  USHORT  usImageHSize;
+  USHORT  usImageVSize;
+  UCHAR   ucHBorder;
+  UCHAR   ucVBorder;
+  ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo;
+  UCHAR   ucInternalModeNumber;
+  UCHAR   ucRefreshRate;
+}ATOM_DTD_FORMAT;
 
-/****************************************************************************/
-/*  Structure used in LVDS_InfoTable */
-/*   * Need a document to describe this table */
-/****************************************************************************/
+/****************************************************************************/	
+// Structure used in LVDS_InfoTable 
+//  * Need a document to describe this table
+/****************************************************************************/	
 #define SUPPORTED_LCD_REFRESHRATE_30Hz          0x0004
 #define SUPPORTED_LCD_REFRESHRATE_40Hz          0x0008
 #define SUPPORTED_LCD_REFRESHRATE_50Hz          0x0010
 #define SUPPORTED_LCD_REFRESHRATE_60Hz          0x0020
 
-/* Once DAL sees this CAP is set, it will read EDID from LCD on its own instead of using sLCDTiming in ATOM_LVDS_INFO_V12. */
-/* Other entries in ATOM_LVDS_INFO_V12 are still valid/useful to DAL */
-#define	LCDPANEL_CAP_READ_EDID									0x1
+//ucTableFormatRevision=1
+//ucTableContentRevision=1
+typedef struct _ATOM_LVDS_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  ATOM_DTD_FORMAT     sLCDTiming;
+  USHORT              usModePatchTableOffset;
+  USHORT              usSupportedRefreshRate;     //Refer to panel info table in ATOMBIOS extension Spec.
+  USHORT              usOffDelayInMs;
+  UCHAR               ucPowerSequenceDigOntoDEin10Ms;
+  UCHAR               ucPowerSequenceDEtoBLOnin10Ms;
+  UCHAR               ucLVDS_Misc;               // Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level}
+                                                 // Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888}
+                                                 // Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled}
+                                                 // Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled}
+  UCHAR               ucPanelDefaultRefreshRate;
+  UCHAR               ucPanelIdentification;
+  UCHAR               ucSS_Id;
+}ATOM_LVDS_INFO;
 
-/* ucTableFormatRevision=1 */
-/* ucTableContentRevision=1 */
-typedef struct _ATOM_LVDS_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ATOM_DTD_FORMAT sLCDTiming;
-	USHORT usModePatchTableOffset;
-	USHORT usSupportedRefreshRate;	/* Refer to panel info table in ATOMBIOS extension Spec. */
-	USHORT usOffDelayInMs;
-	UCHAR ucPowerSequenceDigOntoDEin10Ms;
-	UCHAR ucPowerSequenceDEtoBLOnin10Ms;
-	UCHAR ucLVDS_Misc;	/*  Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level} */
-	/*  Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888} */
-	/*  Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled} */
-	/*  Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled} */
-	UCHAR ucPanelDefaultRefreshRate;
-	UCHAR ucPanelIdentification;
-	UCHAR ucSS_Id;
-} ATOM_LVDS_INFO;
+//ucTableFormatRevision=1
+//ucTableContentRevision=2
+typedef struct _ATOM_LVDS_INFO_V12
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  ATOM_DTD_FORMAT     sLCDTiming;
+  USHORT              usExtInfoTableOffset;
+  USHORT              usSupportedRefreshRate;     //Refer to panel info table in ATOMBIOS extension Spec.
+  USHORT              usOffDelayInMs;
+  UCHAR               ucPowerSequenceDigOntoDEin10Ms;
+  UCHAR               ucPowerSequenceDEtoBLOnin10Ms;
+  UCHAR               ucLVDS_Misc;               // Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level}
+                                                 // Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888}
+                                                 // Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled}
+                                                 // Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled}
+  UCHAR               ucPanelDefaultRefreshRate;
+  UCHAR               ucPanelIdentification;
+  UCHAR               ucSS_Id;
+  USHORT              usLCDVenderID;
+  USHORT              usLCDProductID;
+  UCHAR               ucLCDPanel_SpecialHandlingCap; 
+	UCHAR								ucPanelInfoSize;					//  start from ATOM_DTD_FORMAT to end of panel info, include ExtInfoTable
+  UCHAR               ucReserved[2];
+}ATOM_LVDS_INFO_V12;
+
+//Definitions for ucLCDPanel_SpecialHandlingCap:
+
+//Once DAL sees this CAP is set, it will read EDID from LCD on its own instead of using sLCDTiming in ATOM_LVDS_INFO_V12. 
+//Other entries in ATOM_LVDS_INFO_V12 are still valid/useful to DAL 
+#define	LCDPANEL_CAP_READ_EDID                  0x1
+
+//If a design supports DRR (dynamic refresh rate) on internal panels (LVDS or EDP), this cap is set in ucLCDPanel_SpecialHandlingCap together
+//with multiple supported refresh rates@usSupportedRefreshRate. This cap should not be set when only slow refresh rate is supported (static
+//refresh rate switch by SW. This is only valid from ATOM_LVDS_INFO_V12
+#define	LCDPANEL_CAP_DRR_SUPPORTED              0x2
+
+//Use this cap bit for a quick reference whether an embadded panel (LCD1 ) is LVDS or eDP.
+#define	LCDPANEL_CAP_eDP                        0x4
+
+
+//Color Bit Depth definition in EDID V1.4 @BYTE 14h
+//Bit 6  5  4
+                              //      0  0  0  -  Color bit depth is undefined
+                              //      0  0  1  -  6 Bits per Primary Color
+                              //      0  1  0  -  8 Bits per Primary Color
+                              //      0  1  1  - 10 Bits per Primary Color
+                              //      1  0  0  - 12 Bits per Primary Color
+                              //      1  0  1  - 14 Bits per Primary Color
+                              //      1  1  0  - 16 Bits per Primary Color
+                              //      1  1  1  - Reserved
+
+#define PANEL_COLOR_BIT_DEPTH_MASK    0x70
+
+// Bit7:{=0:Random Dithering disabled;1 Random Dithering enabled}   
+#define PANEL_RANDOM_DITHER   0x80
+#define PANEL_RANDOM_DITHER_MASK   0x80
 
-/* ucTableFormatRevision=1 */
-/* ucTableContentRevision=2 */
-typedef struct _ATOM_LVDS_INFO_V12 {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ATOM_DTD_FORMAT sLCDTiming;
-	USHORT usExtInfoTableOffset;
-	USHORT usSupportedRefreshRate;	/* Refer to panel info table in ATOMBIOS extension Spec. */
-	USHORT usOffDelayInMs;
-	UCHAR ucPowerSequenceDigOntoDEin10Ms;
-	UCHAR ucPowerSequenceDEtoBLOnin10Ms;
-	UCHAR ucLVDS_Misc;	/*  Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level} */
-	/*  Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888} */
-	/*  Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled} */
-	/*  Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled} */
-	UCHAR ucPanelDefaultRefreshRate;
-	UCHAR ucPanelIdentification;
-	UCHAR ucSS_Id;
-	USHORT usLCDVenderID;
-	USHORT usLCDProductID;
-	UCHAR ucLCDPanel_SpecialHandlingCap;
-	UCHAR ucPanelInfoSize;	/*   start from ATOM_DTD_FORMAT to end of panel info, include ExtInfoTable */
-	UCHAR ucReserved[2];
-} ATOM_LVDS_INFO_V12;
 
 #define ATOM_LVDS_INFO_LAST  ATOM_LVDS_INFO_V12
 
-typedef struct _ATOM_PATCH_RECORD_MODE {
-	UCHAR ucRecordType;
-	USHORT usHDisp;
-	USHORT usVDisp;
-} ATOM_PATCH_RECORD_MODE;
+typedef struct  _ATOM_PATCH_RECORD_MODE
+{
+  UCHAR     ucRecordType;
+  USHORT    usHDisp;
+  USHORT    usVDisp;
+}ATOM_PATCH_RECORD_MODE;
 
-typedef struct _ATOM_LCD_RTS_RECORD {
-	UCHAR ucRecordType;
-	UCHAR ucRTSValue;
-} ATOM_LCD_RTS_RECORD;
+typedef struct  _ATOM_LCD_RTS_RECORD
+{
+  UCHAR     ucRecordType;
+  UCHAR     ucRTSValue;
+}ATOM_LCD_RTS_RECORD;
 
-/* !! If the record below exits, it shoud always be the first record for easy use in command table!!! */
-typedef struct _ATOM_LCD_MODE_CONTROL_CAP {
-	UCHAR ucRecordType;
-	USHORT usLCDCap;
-} ATOM_LCD_MODE_CONTROL_CAP;
+//!! If the record below exits, it shoud always be the first record for easy use in command table!!! 
+// The record below is only used when LVDS_Info is present. From ATOM_LVDS_INFO_V12, use ucLCDPanel_SpecialHandlingCap instead.
+typedef struct  _ATOM_LCD_MODE_CONTROL_CAP
+{
+  UCHAR     ucRecordType;
+  USHORT    usLCDCap;
+}ATOM_LCD_MODE_CONTROL_CAP;
 
 #define LCD_MODE_CAP_BL_OFF                   1
 #define LCD_MODE_CAP_CRTC_OFF                 2
 #define LCD_MODE_CAP_PANEL_OFF                4
 
-typedef struct _ATOM_FAKE_EDID_PATCH_RECORD {
-	UCHAR ucRecordType;
-	UCHAR ucFakeEDIDLength;
-	UCHAR ucFakeEDIDString[1];	/*  This actually has ucFakeEdidLength elements. */
+typedef struct _ATOM_FAKE_EDID_PATCH_RECORD
+{
+  UCHAR ucRecordType;
+  UCHAR ucFakeEDIDLength;
+  UCHAR ucFakeEDIDString[1];    // This actually has ucFakeEdidLength elements.
 } ATOM_FAKE_EDID_PATCH_RECORD;
 
-typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD {
-	UCHAR ucRecordType;
-	USHORT usHSize;
-	USHORT usVSize;
-} ATOM_PANEL_RESOLUTION_PATCH_RECORD;
+typedef struct  _ATOM_PANEL_RESOLUTION_PATCH_RECORD
+{
+   UCHAR    ucRecordType;
+   USHORT		usHSize;
+   USHORT		usVSize;
+}ATOM_PANEL_RESOLUTION_PATCH_RECORD;
 
 #define LCD_MODE_PATCH_RECORD_MODE_TYPE       1
 #define LCD_RTS_RECORD_TYPE                   2
@@ -2306,21 +2829,25 @@ typedef struct _ATOM_PANEL_RESOLUTION_PA
 
 /****************************Spread Spectrum Info Table Definitions **********************/
 
-/* ucTableFormatRevision=1 */
-/* ucTableContentRevision=2 */
-typedef struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT {
-	USHORT usSpreadSpectrumPercentage;
-	UCHAR ucSpreadSpectrumType;	/* Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD */
-	UCHAR ucSS_Step;
-	UCHAR ucSS_Delay;
-	UCHAR ucSS_Id;
-	UCHAR ucRecommendedRef_Div;
-	UCHAR ucSS_Range;	/* it was reserved for V11 */
-} ATOM_SPREAD_SPECTRUM_ASSIGNMENT;
+//ucTableFormatRevision=1
+//ucTableContentRevision=2
+typedef struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT
+{
+  USHORT              usSpreadSpectrumPercentage; 
+  UCHAR               ucSpreadSpectrumType;	    //Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Bit2=1: PCIE REFCLK SS =0 iternal PPLL SS  Others:TBD
+  UCHAR               ucSS_Step;
+  UCHAR               ucSS_Delay;
+  UCHAR               ucSS_Id;
+  UCHAR               ucRecommendedRef_Div;
+  UCHAR               ucSS_Range;               //it was reserved for V11
+}ATOM_SPREAD_SPECTRUM_ASSIGNMENT;
 
 #define ATOM_MAX_SS_ENTRY                      16
-#define ATOM_DP_SS_ID1												 0x0f1	/*  SS modulation freq=30k */
-#define ATOM_DP_SS_ID2												 0x0f2	/*  SS modulation freq=33k */
+#define ATOM_DP_SS_ID1												 0x0f1			// SS ID for internal DP stream at 2.7Ghz. if ATOM_DP_SS_ID2 does not exist in SS_InfoTable, it is used for internal DP stream at 1.62Ghz as well. 
+#define ATOM_DP_SS_ID2												 0x0f2			// SS ID for internal DP stream at 1.62Ghz, if it exists in SS_InfoTable. 
+#define ATOM_LVLINK_2700MHz_SS_ID              0x0f3      // SS ID for LV link translator chip at 2.7Ghz
+#define ATOM_LVLINK_1620MHz_SS_ID              0x0f4      // SS ID for LV link translator chip at 1.62Ghz
+
 
 #define ATOM_SS_DOWN_SPREAD_MODE_MASK          0x00000000
 #define ATOM_SS_DOWN_SPREAD_MODE               0x00000000
@@ -2329,29 +2856,30 @@ typedef struct _ATOM_SPREAD_SPECTRUM_ASS
 #define ATOM_INTERNAL_SS_MASK                  0x00000000
 #define ATOM_EXTERNAL_SS_MASK                  0x00000002
 #define EXEC_SS_STEP_SIZE_SHIFT                2
-#define EXEC_SS_DELAY_SHIFT                    4
+#define EXEC_SS_DELAY_SHIFT                    4    
 #define ACTIVEDATA_TO_BLON_DELAY_SHIFT         4
 
-typedef struct _ATOM_SPREAD_SPECTRUM_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ATOM_SPREAD_SPECTRUM_ASSIGNMENT asSS_Info[ATOM_MAX_SS_ENTRY];
-} ATOM_SPREAD_SPECTRUM_INFO;
+typedef struct _ATOM_SPREAD_SPECTRUM_INFO
+{ 
+  ATOM_COMMON_TABLE_HEADER	sHeader;
+  ATOM_SPREAD_SPECTRUM_ASSIGNMENT   asSS_Info[ATOM_MAX_SS_ENTRY];
+}ATOM_SPREAD_SPECTRUM_INFO;
 
-/****************************************************************************/
-/*  Structure used in AnalogTV_InfoTable (Top level) */
-/****************************************************************************/
-/* ucTVBootUpDefaultStd definiton: */
+/****************************************************************************/	
+// Structure used in AnalogTV_InfoTable (Top level)
+/****************************************************************************/	
+//ucTVBootUpDefaultStd definiton:
 
-/* ATOM_TV_NTSC                1 */
-/* ATOM_TV_NTSCJ               2 */
-/* ATOM_TV_PAL                 3 */
-/* ATOM_TV_PALM                4 */
-/* ATOM_TV_PALCN               5 */
-/* ATOM_TV_PALN                6 */
-/* ATOM_TV_PAL60               7 */
-/* ATOM_TV_SECAM               8 */
+//ATOM_TV_NTSC                1
+//ATOM_TV_NTSCJ               2
+//ATOM_TV_PAL                 3
+//ATOM_TV_PALM                4
+//ATOM_TV_PALCN               5
+//ATOM_TV_PALN                6
+//ATOM_TV_PAL60               7
+//ATOM_TV_SECAM               8
 
-/* ucTVSuppportedStd definition: */
+//ucTVSupportedStd definition:
 #define NTSC_SUPPORT          0x1
 #define NTSCJ_SUPPORT         0x2
 
@@ -2364,46 +2892,58 @@ typedef struct _ATOM_SPREAD_SPECTRUM_INF
 
 #define MAX_SUPPORTED_TV_TIMING    2
 
-typedef struct _ATOM_ANALOG_TV_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	UCHAR ucTV_SupportedStandard;
-	UCHAR ucTV_BootUpDefaultStandard;
-	UCHAR ucExt_TV_ASIC_ID;
-	UCHAR ucExt_TV_ASIC_SlaveAddr;
-	/*ATOM_DTD_FORMAT          aModeTimings[MAX_SUPPORTED_TV_TIMING]; */
-	ATOM_MODE_TIMING aModeTimings[MAX_SUPPORTED_TV_TIMING];
-} ATOM_ANALOG_TV_INFO;
+typedef struct _ATOM_ANALOG_TV_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  UCHAR                    ucTV_SupportedStandard;
+  UCHAR                    ucTV_BootUpDefaultStandard; 
+  UCHAR                    ucExt_TV_ASIC_ID;
+  UCHAR                    ucExt_TV_ASIC_SlaveAddr;
+  /*ATOM_DTD_FORMAT          aModeTimings[MAX_SUPPORTED_TV_TIMING];*/
+  ATOM_MODE_TIMING         aModeTimings[MAX_SUPPORTED_TV_TIMING];
+}ATOM_ANALOG_TV_INFO;
 
 #define MAX_SUPPORTED_TV_TIMING_V1_2    3
 
-typedef struct _ATOM_ANALOG_TV_INFO_V1_2 {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	UCHAR                    ucTV_SupportedStandard;
-	UCHAR                    ucTV_BootUpDefaultStandard;
-	UCHAR                    ucExt_TV_ASIC_ID;
-	UCHAR                    ucExt_TV_ASIC_SlaveAddr;
-	ATOM_DTD_FORMAT          aModeTimings[MAX_SUPPORTED_TV_TIMING];
-} ATOM_ANALOG_TV_INFO_V1_2;
+typedef struct _ATOM_ANALOG_TV_INFO_V1_2
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  UCHAR                    ucTV_SupportedStandard;
+  UCHAR                    ucTV_BootUpDefaultStandard; 
+  UCHAR                    ucExt_TV_ASIC_ID;
+  UCHAR                    ucExt_TV_ASIC_SlaveAddr;
+  ATOM_DTD_FORMAT          aModeTimings[MAX_SUPPORTED_TV_TIMING_V1_2];
+}ATOM_ANALOG_TV_INFO_V1_2;
+
+typedef struct _ATOM_DPCD_INFO
+{
+  UCHAR   ucRevisionNumber;        //10h : Revision 1.0; 11h : Revision 1.1   
+  UCHAR   ucMaxLinkRate;           //06h : 1.62Gbps per lane; 0Ah = 2.7Gbps per lane
+  UCHAR   ucMaxLane;               //Bits 4:0 = MAX_LANE_COUNT (1/2/4). Bit 7 = ENHANCED_FRAME_CAP 
+  UCHAR   ucMaxDownSpread;         //Bit0 = 0: No Down spread; Bit0 = 1: 0.5% (Subject to change according to DP spec)
+}ATOM_DPCD_INFO;
+
+#define ATOM_DPCD_MAX_LANE_MASK    0x1F
 
 /**************************************************************************/
-/*  VRAM usage and their definitions */
+// VRAM usage and their defintions
 
-/*  One chunk of VRAM used by Bios are for HWICON surfaces,EDID data. */
-/*  Current Mode timing and Dail Timing and/or STD timing data EACH device. They can be broken down as below. */
-/*  All the addresses below are the offsets from the frame buffer start.They all MUST be Dword aligned! */
-/*  To driver: The physical address of this memory portion=mmFB_START(4K aligned)+ATOMBIOS_VRAM_USAGE_START_ADDR+ATOM_x_ADDR */
-/*  To Bios:  ATOMBIOS_VRAM_USAGE_START_ADDR+ATOM_x_ADDR->MM_INDEX */
+// One chunk of VRAM used by Bios are for HWICON surfaces,EDID data.
+// Current Mode timing and Dail Timing and/or STD timing data EACH device. They can be broken down as below.
+// All the addresses below are the offsets from the frame buffer start.They all MUST be Dword aligned!
+// To driver: The physical address of this memory portion=mmFB_START(4K aligned)+ATOMBIOS_VRAM_USAGE_START_ADDR+ATOM_x_ADDR
+// To Bios:  ATOMBIOS_VRAM_USAGE_START_ADDR+ATOM_x_ADDR->MM_INDEX 
 
 #ifndef VESA_MEMORY_IN_64K_BLOCK
-#define VESA_MEMORY_IN_64K_BLOCK        0x100	/* 256*64K=16Mb (Max. VESA memory is 16Mb!) */
+#define VESA_MEMORY_IN_64K_BLOCK        0x100       //256*64K=16Mb (Max. VESA memory is 16Mb!)
 #endif
 
-#define ATOM_EDID_RAW_DATASIZE          256	/* In Bytes */
-#define ATOM_HWICON_SURFACE_SIZE        4096	/* In Bytes */
+#define ATOM_EDID_RAW_DATASIZE          256         //In Bytes
+#define ATOM_HWICON_SURFACE_SIZE        4096        //In Bytes
 #define ATOM_HWICON_INFOTABLE_SIZE      32
 #define MAX_DTD_MODE_IN_VRAM            6
-#define ATOM_DTD_MODE_SUPPORT_TBL_SIZE  (MAX_DTD_MODE_IN_VRAM*28)	/* 28= (SIZEOF ATOM_DTD_FORMAT) */
-#define ATOM_STD_MODE_SUPPORT_TBL_SIZE  (32*8)	/* 32 is a predefined number,8= (SIZEOF ATOM_STD_FORMAT) */
+#define ATOM_DTD_MODE_SUPPORT_TBL_SIZE  (MAX_DTD_MODE_IN_VRAM*28)    //28= (SIZEOF ATOM_DTD_FORMAT) 
+#define ATOM_STD_MODE_SUPPORT_TBL_SIZE  32*8                         //32 is a predefined number,8= (SIZEOF ATOM_STD_FORMAT)
 #define DFP_ENCODER_TYPE_OFFSET					0x80
 #define DP_ENCODER_LANE_NUM_OFFSET			0x84
 #define DP_ENCODER_LINK_RATE_OFFSET			0x88
@@ -2417,7 +2957,7 @@ typedef struct _ATOM_ANALOG_TV_INFO_V1_2
 
 #define ATOM_LCD1_EDID_ADDR             (ATOM_CRT1_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE)
 #define ATOM_LCD1_DTD_MODE_TBL_ADDR     (ATOM_LCD1_EDID_ADDR + ATOM_EDID_RAW_DATASIZE)
-#define ATOM_LCD1_STD_MODE_TBL_ADDR	(ATOM_LCD1_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
+#define ATOM_LCD1_STD_MODE_TBL_ADDR   	(ATOM_LCD1_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
 
 #define ATOM_TV1_DTD_MODE_TBL_ADDR      (ATOM_LCD1_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE)
 
@@ -2431,13 +2971,13 @@ typedef struct _ATOM_ANALOG_TV_INFO_V1_2
 
 #define ATOM_LCD2_EDID_ADDR             (ATOM_CRT2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE)
 #define ATOM_LCD2_DTD_MODE_TBL_ADDR     (ATOM_LCD2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE)
-#define ATOM_LCD2_STD_MODE_TBL_ADDR	(ATOM_LCD2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
+#define ATOM_LCD2_STD_MODE_TBL_ADDR   	(ATOM_LCD2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
 
-#define ATOM_TV2_EDID_ADDR              (ATOM_LCD2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE)
-#define ATOM_TV2_DTD_MODE_TBL_ADDR      (ATOM_TV2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE)
-#define ATOM_TV2_STD_MODE_TBL_ADDR	  (ATOM_TV2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
+#define ATOM_DFP6_EDID_ADDR             (ATOM_LCD2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE)
+#define ATOM_DFP6_DTD_MODE_TBL_ADDR     (ATOM_DFP6_EDID_ADDR + ATOM_EDID_RAW_DATASIZE)
+#define ATOM_DFP6_STD_MODE_TBL_ADDR     (ATOM_DFP6_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
 
-#define ATOM_DFP2_EDID_ADDR             (ATOM_TV2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE)
+#define ATOM_DFP2_EDID_ADDR             (ATOM_DFP6_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE)
 #define ATOM_DFP2_DTD_MODE_TBL_ADDR     (ATOM_DFP2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE)
 #define ATOM_DFP2_STD_MODE_TBL_ADDR     (ATOM_DFP2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
 
@@ -2457,533 +2997,850 @@ typedef struct _ATOM_ANALOG_TV_INFO_V1_2
 #define ATOM_DFP5_DTD_MODE_TBL_ADDR     (ATOM_DFP5_EDID_ADDR + ATOM_EDID_RAW_DATASIZE)
 #define ATOM_DFP5_STD_MODE_TBL_ADDR     (ATOM_DFP5_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
 
-#define ATOM_DP_TRAINING_TBL_ADDR	(ATOM_DFP5_STD_MODE_TBL_ADDR+ATOM_STD_MODE_SUPPORT_TBL_SIZE)
+#define ATOM_DP_TRAINING_TBL_ADDR				(ATOM_DFP5_STD_MODE_TBL_ADDR+ATOM_STD_MODE_SUPPORT_TBL_SIZE)       
 
-#define ATOM_STACK_STORAGE_START        (ATOM_DP_TRAINING_TBL_ADDR + 256)
-#define ATOM_STACK_STORAGE_END          (ATOM_STACK_STORAGE_START + 512)
+#define ATOM_STACK_STORAGE_START        (ATOM_DP_TRAINING_TBL_ADDR+256)       
+#define ATOM_STACK_STORAGE_END          ATOM_STACK_STORAGE_START+512        
 
-/* The size below is in Kb! */
+//The size below is in Kb!
 #define ATOM_VRAM_RESERVE_SIZE         ((((ATOM_STACK_STORAGE_END - ATOM_HWICON1_SURFACE_ADDR)>>10)+4)&0xFFFC)
-
+   
 #define	ATOM_VRAM_OPERATION_FLAGS_MASK         0xC0000000L
 #define ATOM_VRAM_OPERATION_FLAGS_SHIFT        30
 #define	ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION   0x1
 #define	ATOM_VRAM_BLOCK_NEEDS_RESERVATION      0x0
 
-/***********************************************************************************/
-/*  Structure used in VRAM_UsageByFirmwareTable */
-/*  Note1: This table is filled by SetBiosReservationStartInFB in CoreCommSubs.asm */
-/*         at running time. */
-/*  note2: From RV770, the memory is more than 32bit addressable, so we will change */
-/*         ucTableFormatRevision=1,ucTableContentRevision=4, the strcuture remains */
-/*         exactly same as 1.1 and 1.2 (1.3 is never in use), but ulStartAddrUsedByFirmware */
-/*         (in offset to start of memory address) is KB aligned instead of byte aligend. */
-/***********************************************************************************/
+/***********************************************************************************/	
+// Structure used in VRAM_UsageByFirmwareTable
+// Note1: This table is filled by SetBiosReservationStartInFB in CoreCommSubs.asm
+//        at running time.   
+// note2: From RV770, the memory is more than 32bit addressable, so we will change 
+//        ucTableFormatRevision=1,ucTableContentRevision=4, the strcuture remains 
+//        exactly same as 1.1 and 1.2 (1.3 is never in use), but ulStartAddrUsedByFirmware 
+//        (in offset to start of memory address) is KB aligned instead of byte aligend.
+/***********************************************************************************/	
+// Note3:
+/* If we change usReserved to "usFBUsedbyDrvInKB", then to VBIOS this usFBUsedbyDrvInKB is a predefined, unchanged constant across VGA or non VGA adapter,
+for CAIL, The size of FB access area is known, only thing missing is the Offset of FB Access area, so we can  have:
+
+If (ulStartAddrUsedByFirmware!=0)
+FBAccessAreaOffset= ulStartAddrUsedByFirmware - usFBUsedbyDrvInKB;
+Reserved area has been claimed by VBIOS including this FB access area; CAIL doesn't need to reserve any extra area for this purpose
+else	//Non VGA case
+ if (FB_Size<=2Gb)
+    FBAccessAreaOffset= FB_Size - usFBUsedbyDrvInKB;
+ else
+	  FBAccessAreaOffset= Aper_Size - usFBUsedbyDrvInKB
+
+CAIL needs to claim an reserved area defined by FBAccessAreaOffset and usFBUsedbyDrvInKB in non VGA case.*/
+
 #define ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO			1
 
-typedef struct _ATOM_FIRMWARE_VRAM_RESERVE_INFO {
-	ULONG ulStartAddrUsedByFirmware;
-	USHORT usFirmwareUseInKb;
-	USHORT usReserved;
-} ATOM_FIRMWARE_VRAM_RESERVE_INFO;
+typedef struct _ATOM_FIRMWARE_VRAM_RESERVE_INFO
+{
+  ULONG   ulStartAddrUsedByFirmware;
+  USHORT  usFirmwareUseInKb;
+  USHORT  usReserved;
+}ATOM_FIRMWARE_VRAM_RESERVE_INFO;
 
-typedef struct _ATOM_VRAM_USAGE_BY_FIRMWARE {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ATOM_FIRMWARE_VRAM_RESERVE_INFO
-	    asFirmwareVramReserveInfo[ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO];
-} ATOM_VRAM_USAGE_BY_FIRMWARE;
+typedef struct _ATOM_VRAM_USAGE_BY_FIRMWARE
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  ATOM_FIRMWARE_VRAM_RESERVE_INFO	asFirmwareVramReserveInfo[ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO];
+}ATOM_VRAM_USAGE_BY_FIRMWARE;
 
-/****************************************************************************/
-/*  Structure used in GPIO_Pin_LUTTable */
-/****************************************************************************/
-typedef struct _ATOM_GPIO_PIN_ASSIGNMENT {
-	USHORT usGpioPin_AIndex;
-	UCHAR ucGpioPinBitShift;
-	UCHAR ucGPIO_ID;
-} ATOM_GPIO_PIN_ASSIGNMENT;
+// change verion to 1.5, when allow driver to allocate the vram area for command table access. 
+typedef struct _ATOM_FIRMWARE_VRAM_RESERVE_INFO_V1_5
+{
+  ULONG   ulStartAddrUsedByFirmware;
+  USHORT  usFirmwareUseInKb;
+  USHORT  usFBUsedByDrvInKb;
+}ATOM_FIRMWARE_VRAM_RESERVE_INFO_V1_5;
 
-typedef struct _ATOM_GPIO_PIN_LUT {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ATOM_GPIO_PIN_ASSIGNMENT asGPIO_Pin[1];
-} ATOM_GPIO_PIN_LUT;
+typedef struct _ATOM_VRAM_USAGE_BY_FIRMWARE_V1_5
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  ATOM_FIRMWARE_VRAM_RESERVE_INFO_V1_5	asFirmwareVramReserveInfo[ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO];
+}ATOM_VRAM_USAGE_BY_FIRMWARE_V1_5;
 
-/****************************************************************************/
-/*  Structure used in ComponentVideoInfoTable */
-/****************************************************************************/
+/****************************************************************************/	
+// Structure used in GPIO_Pin_LUTTable
+/****************************************************************************/	
+typedef struct _ATOM_GPIO_PIN_ASSIGNMENT
+{
+  USHORT                   usGpioPin_AIndex;
+  UCHAR                    ucGpioPinBitShift;
+  UCHAR                    ucGPIO_ID;
+}ATOM_GPIO_PIN_ASSIGNMENT;
+
+typedef struct _ATOM_GPIO_PIN_LUT
+{
+  ATOM_COMMON_TABLE_HEADER  sHeader;
+  ATOM_GPIO_PIN_ASSIGNMENT	asGPIO_Pin[1];
+}ATOM_GPIO_PIN_LUT;
+
+/****************************************************************************/	
+// Structure used in ComponentVideoInfoTable	
+/****************************************************************************/	
 #define GPIO_PIN_ACTIVE_HIGH          0x1
 
 #define MAX_SUPPORTED_CV_STANDARDS    5
 
-/*  definitions for ATOM_D_INFO.ucSettings */
-#define ATOM_GPIO_SETTINGS_BITSHIFT_MASK  0x1F	/*  [4:0] */
-#define ATOM_GPIO_SETTINGS_RESERVED_MASK  0x60	/*  [6:5] = must be zeroed out */
-#define ATOM_GPIO_SETTINGS_ACTIVE_MASK    0x80	/*  [7] */
+// definitions for ATOM_D_INFO.ucSettings
+#define ATOM_GPIO_SETTINGS_BITSHIFT_MASK  0x1F    // [4:0]
+#define ATOM_GPIO_SETTINGS_RESERVED_MASK  0x60    // [6:5] = must be zeroed out
+#define ATOM_GPIO_SETTINGS_ACTIVE_MASK    0x80    // [7]
 
-typedef struct _ATOM_GPIO_INFO {
-	USHORT usAOffset;
-	UCHAR ucSettings;
-	UCHAR ucReserved;
-} ATOM_GPIO_INFO;
+typedef struct _ATOM_GPIO_INFO
+{
+  USHORT  usAOffset;
+  UCHAR   ucSettings;
+  UCHAR   ucReserved;
+}ATOM_GPIO_INFO;
 
-/*  definitions for ATOM_COMPONENT_VIDEO_INFO.ucMiscInfo (bit vector) */
+// definitions for ATOM_COMPONENT_VIDEO_INFO.ucMiscInfo (bit vector)
 #define ATOM_CV_RESTRICT_FORMAT_SELECTION           0x2
 
-/*  definitions for ATOM_COMPONENT_VIDEO_INFO.uc480i/uc480p/uc720p/uc1080i */
-#define ATOM_GPIO_DEFAULT_MODE_EN                   0x80	/* [7]; */
-#define ATOM_GPIO_SETTING_PERMODE_MASK              0x7F	/* [6:0] */
+// definitions for ATOM_COMPONENT_VIDEO_INFO.uc480i/uc480p/uc720p/uc1080i
+#define ATOM_GPIO_DEFAULT_MODE_EN                   0x80 //[7];
+#define ATOM_GPIO_SETTING_PERMODE_MASK              0x7F //[6:0]
 
-/*  definitions for ATOM_COMPONENT_VIDEO_INFO.ucLetterBoxMode */
-/* Line 3 out put 5V. */
-#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_A       0x01	/* represent gpio 3 state for 16:9 */
-#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_B       0x02	/* represent gpio 4 state for 16:9 */
-#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_SHIFT   0x0
+// definitions for ATOM_COMPONENT_VIDEO_INFO.ucLetterBoxMode
+//Line 3 out put 5V.
+#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_A       0x01     //represent gpio 3 state for 16:9
+#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_B       0x02     //represent gpio 4 state for 16:9
+#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_SHIFT   0x0   
 
-/* Line 3 out put 2.2V */
-#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_A 0x04	/* represent gpio 3 state for 4:3 Letter box */
-#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_B 0x08	/* represent gpio 4 state for 4:3 Letter box */
-#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_SHIFT 0x2
+//Line 3 out put 2.2V              
+#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_A 0x04     //represent gpio 3 state for 4:3 Letter box
+#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_B 0x08     //represent gpio 4 state for 4:3 Letter box
+#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_SHIFT 0x2     
 
-/* Line 3 out put 0V */
-#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_A        0x10	/* represent gpio 3 state for 4:3 */
-#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_B        0x20	/* represent gpio 4 state for 4:3 */
-#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_SHIFT    0x4
+//Line 3 out put 0V
+#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_A        0x10     //represent gpio 3 state for 4:3
+#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_B        0x20     //represent gpio 4 state for 4:3
+#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_SHIFT    0x4 
 
-#define ATOM_CV_LINE3_ASPECTRATIO_MASK              0x3F	/*  bit [5:0] */
+#define ATOM_CV_LINE3_ASPECTRATIO_MASK              0x3F     // bit [5:0]
 
-#define ATOM_CV_LINE3_ASPECTRATIO_EXIST             0x80	/* bit 7 */
+#define ATOM_CV_LINE3_ASPECTRATIO_EXIST             0x80     //bit 7
 
-/* GPIO bit index in gpio setting per mode value, also represend the block no. in gpio blocks. */
-#define ATOM_GPIO_INDEX_LINE3_ASPECRATIO_GPIO_A   3	/* bit 3 in uc480i/uc480p/uc720p/uc1080i, which represend the default gpio bit setting for the mode. */
-#define ATOM_GPIO_INDEX_LINE3_ASPECRATIO_GPIO_B   4	/* bit 4 in uc480i/uc480p/uc720p/uc1080i, which represend the default gpio bit setting for the mode. */
+//GPIO bit index in gpio setting per mode value, also represend the block no. in gpio blocks.
+#define ATOM_GPIO_INDEX_LINE3_ASPECRATIO_GPIO_A   3   //bit 3 in uc480i/uc480p/uc720p/uc1080i, which represend the default gpio bit setting for the mode.
+#define ATOM_GPIO_INDEX_LINE3_ASPECRATIO_GPIO_B   4   //bit 4 in uc480i/uc480p/uc720p/uc1080i, which represend the default gpio bit setting for the mode.
 
-typedef struct _ATOM_COMPONENT_VIDEO_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	USHORT usMask_PinRegisterIndex;
-	USHORT usEN_PinRegisterIndex;
-	USHORT usY_PinRegisterIndex;
-	USHORT usA_PinRegisterIndex;
-	UCHAR ucBitShift;
-	UCHAR ucPinActiveState;	/* ucPinActiveState: Bit0=1 active high, =0 active low */
-	ATOM_DTD_FORMAT sReserved;	/*  must be zeroed out */
-	UCHAR ucMiscInfo;
-	UCHAR uc480i;
-	UCHAR uc480p;
-	UCHAR uc720p;
-	UCHAR uc1080i;
-	UCHAR ucLetterBoxMode;
-	UCHAR ucReserved[3];
-	UCHAR ucNumOfWbGpioBlocks;	/* For Component video D-Connector support. If zere, NTSC type connector */
-	ATOM_GPIO_INFO aWbGpioStateBlock[MAX_SUPPORTED_CV_STANDARDS];
-	ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_CV_STANDARDS];
-} ATOM_COMPONENT_VIDEO_INFO;
 
-/* ucTableFormatRevision=2 */
-/* ucTableContentRevision=1 */
-typedef struct _ATOM_COMPONENT_VIDEO_INFO_V21 {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	UCHAR ucMiscInfo;
-	UCHAR uc480i;
-	UCHAR uc480p;
-	UCHAR uc720p;
-	UCHAR uc1080i;
-	UCHAR ucReserved;
-	UCHAR ucLetterBoxMode;
-	UCHAR ucNumOfWbGpioBlocks;	/* For Component video D-Connector support. If zere, NTSC type connector */
-	ATOM_GPIO_INFO aWbGpioStateBlock[MAX_SUPPORTED_CV_STANDARDS];
-	ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_CV_STANDARDS];
-} ATOM_COMPONENT_VIDEO_INFO_V21;
+typedef struct _ATOM_COMPONENT_VIDEO_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;
+  USHORT             usMask_PinRegisterIndex;
+  USHORT             usEN_PinRegisterIndex;
+  USHORT             usY_PinRegisterIndex;
+  USHORT             usA_PinRegisterIndex;
+  UCHAR              ucBitShift;
+  UCHAR              ucPinActiveState;  //ucPinActiveState: Bit0=1 active high, =0 active low
+  ATOM_DTD_FORMAT    sReserved;         // must be zeroed out
+  UCHAR              ucMiscInfo;
+  UCHAR              uc480i;
+  UCHAR              uc480p;
+  UCHAR              uc720p;
+  UCHAR              uc1080i;
+  UCHAR              ucLetterBoxMode;
+  UCHAR              ucReserved[3];
+  UCHAR              ucNumOfWbGpioBlocks; //For Component video D-Connector support. If zere, NTSC type connector
+  ATOM_GPIO_INFO     aWbGpioStateBlock[MAX_SUPPORTED_CV_STANDARDS];
+  ATOM_DTD_FORMAT    aModeTimings[MAX_SUPPORTED_CV_STANDARDS];
+}ATOM_COMPONENT_VIDEO_INFO;
+
+//ucTableFormatRevision=2
+//ucTableContentRevision=1
+typedef struct _ATOM_COMPONENT_VIDEO_INFO_V21
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;
+  UCHAR              ucMiscInfo;
+  UCHAR              uc480i;
+  UCHAR              uc480p;
+  UCHAR              uc720p;
+  UCHAR              uc1080i;
+  UCHAR              ucReserved;
+  UCHAR              ucLetterBoxMode;
+  UCHAR              ucNumOfWbGpioBlocks; //For Component video D-Connector support. If zere, NTSC type connector
+  ATOM_GPIO_INFO     aWbGpioStateBlock[MAX_SUPPORTED_CV_STANDARDS];
+  ATOM_DTD_FORMAT    aModeTimings[MAX_SUPPORTED_CV_STANDARDS];
+}ATOM_COMPONENT_VIDEO_INFO_V21;
 
 #define ATOM_COMPONENT_VIDEO_INFO_LAST  ATOM_COMPONENT_VIDEO_INFO_V21
 
-/****************************************************************************/
-/*  Structure used in object_InfoTable */
-/****************************************************************************/
-typedef struct _ATOM_OBJECT_HEADER {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	USHORT usDeviceSupport;
-	USHORT usConnectorObjectTableOffset;
-	USHORT usRouterObjectTableOffset;
-	USHORT usEncoderObjectTableOffset;
-	USHORT usProtectionObjectTableOffset;	/* only available when Protection block is independent. */
-	USHORT usDisplayPathTableOffset;
-} ATOM_OBJECT_HEADER;
+/****************************************************************************/	
+// Structure used in object_InfoTable
+/****************************************************************************/	
+typedef struct _ATOM_OBJECT_HEADER
+{ 
+  ATOM_COMMON_TABLE_HEADER	sHeader;
+  USHORT                    usDeviceSupport;
+  USHORT                    usConnectorObjectTableOffset;
+  USHORT                    usRouterObjectTableOffset;
+  USHORT                    usEncoderObjectTableOffset;
+  USHORT                    usProtectionObjectTableOffset; //only available when Protection block is independent.
+  USHORT                    usDisplayPathTableOffset;
+}ATOM_OBJECT_HEADER;
 
-typedef struct _ATOM_DISPLAY_OBJECT_PATH {
-	USHORT usDeviceTag;	/* supported device */
-	USHORT usSize;		/* the size of ATOM_DISPLAY_OBJECT_PATH */
-	USHORT usConnObjectId;	/* Connector Object ID */
-	USHORT usGPUObjectId;	/* GPU ID */
-	USHORT usGraphicObjIds[1];	/* 1st Encoder Obj source from GPU to last Graphic Obj destinate to connector. */
-} ATOM_DISPLAY_OBJECT_PATH;
+typedef struct _ATOM_OBJECT_HEADER_V3
+{ 
+  ATOM_COMMON_TABLE_HEADER	sHeader;
+  USHORT                    usDeviceSupport;
+  USHORT                    usConnectorObjectTableOffset;
+  USHORT                    usRouterObjectTableOffset;
+  USHORT                    usEncoderObjectTableOffset;
+  USHORT                    usProtectionObjectTableOffset; //only available when Protection block is independent.
+  USHORT                    usDisplayPathTableOffset;
+  USHORT                    usMiscObjectTableOffset;
+}ATOM_OBJECT_HEADER_V3;
 
-typedef struct _ATOM_DISPLAY_OBJECT_PATH_TABLE {
-	UCHAR ucNumOfDispPath;
-	UCHAR ucVersion;
-	UCHAR ucPadding[2];
-	ATOM_DISPLAY_OBJECT_PATH asDispPath[1];
-} ATOM_DISPLAY_OBJECT_PATH_TABLE;
+typedef struct  _ATOM_DISPLAY_OBJECT_PATH
+{
+  USHORT    usDeviceTag;                                   //supported device 
+  USHORT    usSize;                                        //the size of ATOM_DISPLAY_OBJECT_PATH
+  USHORT    usConnObjectId;                                //Connector Object ID 
+  USHORT    usGPUObjectId;                                 //GPU ID 
+  USHORT    usGraphicObjIds[1];                             //1st Encoder Obj source from GPU to last Graphic Obj destinate to connector.
+}ATOM_DISPLAY_OBJECT_PATH;
 
-typedef struct _ATOM_OBJECT	/* each object has this structure */
+typedef struct _ATOM_DISPLAY_OBJECT_PATH_TABLE
 {
-	USHORT usObjectID;
-	USHORT usSrcDstTableOffset;
-	USHORT usRecordOffset;	/* this pointing to a bunch of records defined below */
-	USHORT usReserved;
-} ATOM_OBJECT;
+  UCHAR                           ucNumOfDispPath;
+  UCHAR                           ucVersion;
+  UCHAR                           ucPadding[2];
+  ATOM_DISPLAY_OBJECT_PATH        asDispPath[1];
+}ATOM_DISPLAY_OBJECT_PATH_TABLE;
 
-typedef struct _ATOM_OBJECT_TABLE	/* Above 4 object table offset pointing to a bunch of objects all have this structure */
+
+typedef struct _ATOM_OBJECT                                //each object has this structure    
 {
-	UCHAR ucNumberOfObjects;
-	UCHAR ucPadding[3];
-	ATOM_OBJECT asObjects[1];
-} ATOM_OBJECT_TABLE;
+  USHORT              usObjectID;
+  USHORT              usSrcDstTableOffset;
+  USHORT              usRecordOffset;                     //this pointing to a bunch of records defined below
+  USHORT              usReserved;
+}ATOM_OBJECT;
 
-typedef struct _ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT	/* usSrcDstTableOffset pointing to this structure */
+typedef struct _ATOM_OBJECT_TABLE                         //Above 4 object table offset pointing to a bunch of objects all have this structure     
 {
-	UCHAR ucNumberOfSrc;
-	USHORT usSrcObjectID[1];
-	UCHAR ucNumberOfDst;
-	USHORT usDstObjectID[1];
-} ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT;
+  UCHAR               ucNumberOfObjects;
+  UCHAR               ucPadding[3];
+  ATOM_OBJECT         asObjects[1];
+}ATOM_OBJECT_TABLE;
 
-/* Related definitions, all records are differnt but they have a commond header */
-typedef struct _ATOM_COMMON_RECORD_HEADER {
-	UCHAR ucRecordType;	/* An emun to indicate the record type */
-	UCHAR ucRecordSize;	/* The size of the whole record in byte */
-} ATOM_COMMON_RECORD_HEADER;
+typedef struct _ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT         //usSrcDstTableOffset pointing to this structure
+{
+  UCHAR               ucNumberOfSrc;
+  USHORT              usSrcObjectID[1];
+  UCHAR               ucNumberOfDst;
+  USHORT              usDstObjectID[1];
+}ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT;
 
-#define ATOM_I2C_RECORD_TYPE                           1
+
+//Two definitions below are for OPM on MXM module designs
+
+#define EXT_HPDPIN_LUTINDEX_0                   0
+#define EXT_HPDPIN_LUTINDEX_1                   1
+#define EXT_HPDPIN_LUTINDEX_2                   2
+#define EXT_HPDPIN_LUTINDEX_3                   3
+#define EXT_HPDPIN_LUTINDEX_4                   4
+#define EXT_HPDPIN_LUTINDEX_5                   5
+#define EXT_HPDPIN_LUTINDEX_6                   6
+#define EXT_HPDPIN_LUTINDEX_7                   7
+#define MAX_NUMBER_OF_EXT_HPDPIN_LUT_ENTRIES   (EXT_HPDPIN_LUTINDEX_7+1)
+
+#define EXT_AUXDDC_LUTINDEX_0                   0
+#define EXT_AUXDDC_LUTINDEX_1                   1
+#define EXT_AUXDDC_LUTINDEX_2                   2
+#define EXT_AUXDDC_LUTINDEX_3                   3
+#define EXT_AUXDDC_LUTINDEX_4                   4
+#define EXT_AUXDDC_LUTINDEX_5                   5
+#define EXT_AUXDDC_LUTINDEX_6                   6
+#define EXT_AUXDDC_LUTINDEX_7                   7
+#define MAX_NUMBER_OF_EXT_AUXDDC_LUT_ENTRIES   (EXT_AUXDDC_LUTINDEX_7+1)
+
+typedef struct _EXT_DISPLAY_PATH
+{
+  USHORT  usDeviceTag;                    //A bit vector to show what devices are supported 
+  USHORT  usDeviceACPIEnum;               //16bit device ACPI id. 
+  USHORT  usDeviceConnector;              //A physical connector for displays to plug in, using object connector definitions
+  UCHAR   ucExtAUXDDCLutIndex;            //An index into external AUX/DDC channel LUT
+  UCHAR   ucExtHPDPINLutIndex;            //An index into external HPD pin LUT
+  USHORT  usExtEncoderObjId;              //external encoder object id
+  USHORT  usReserved[3]; 
+}EXT_DISPLAY_PATH;
+   
+#define NUMBER_OF_UCHAR_FOR_GUID          16
+#define MAX_NUMBER_OF_EXT_DISPLAY_PATH    7
+
+typedef  struct _ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;
+  UCHAR                    ucGuid [NUMBER_OF_UCHAR_FOR_GUID];     // a GUID is a 16 byte long string
+  EXT_DISPLAY_PATH         sPath[MAX_NUMBER_OF_EXT_DISPLAY_PATH]; // total of fixed 7 entries.
+  UCHAR                    ucChecksum;                            // a  simple Checksum of the sum of whole structure equal to 0x0. 
+  UCHAR                    Reserved [7];                          // for potential expansion
+}ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO;
+
+//Related definitions, all records are differnt but they have a commond header
+typedef struct _ATOM_COMMON_RECORD_HEADER
+{
+  UCHAR               ucRecordType;                      //An emun to indicate the record type
+  UCHAR               ucRecordSize;                      //The size of the whole record in byte
+}ATOM_COMMON_RECORD_HEADER;
+
+
+#define ATOM_I2C_RECORD_TYPE                           1         
 #define ATOM_HPD_INT_RECORD_TYPE                       2
 #define ATOM_OUTPUT_PROTECTION_RECORD_TYPE             3
 #define ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE          4
-#define	ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD_TYPE	     5	/* Obsolete, switch to use GPIO_CNTL_RECORD_TYPE */
-#define ATOM_ENCODER_FPGA_CONTROL_RECORD_TYPE          6	/* Obsolete, switch to use GPIO_CNTL_RECORD_TYPE */
+#define	ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD_TYPE	     5 //Obsolete, switch to use GPIO_CNTL_RECORD_TYPE
+#define ATOM_ENCODER_FPGA_CONTROL_RECORD_TYPE          6 //Obsolete, switch to use GPIO_CNTL_RECORD_TYPE
 #define ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD_TYPE      7
-#define ATOM_JTAG_RECORD_TYPE                          8	/* Obsolete, switch to use GPIO_CNTL_RECORD_TYPE */
+#define ATOM_JTAG_RECORD_TYPE                          8 //Obsolete, switch to use GPIO_CNTL_RECORD_TYPE
 #define ATOM_OBJECT_GPIO_CNTL_RECORD_TYPE              9
 #define ATOM_ENCODER_DVO_CF_RECORD_TYPE               10
 #define ATOM_CONNECTOR_CF_RECORD_TYPE                 11
 #define	ATOM_CONNECTOR_HARDCODE_DTD_RECORD_TYPE	      12
 #define ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD_TYPE  13
-#define ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE				14
-#define ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE					15
+#define ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE	      14
+#define ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE	15
+#define ATOM_CONNECTOR_HPDPIN_LUT_RECORD_TYPE          16 //This is for the case when connectors are not known to object table
+#define ATOM_CONNECTOR_AUXDDC_LUT_RECORD_TYPE          17 //This is for the case when connectors are not known to object table
+#define ATOM_OBJECT_LINK_RECORD_TYPE                   18 //Once this record is present under one object, it indicats the oobject is linked to another obj described by the record
+#define ATOM_CONNECTOR_REMOTE_CAP_RECORD_TYPE          19
 
-/* Must be updated when new record type is added,equal to that record definition! */
-#define ATOM_MAX_OBJECT_RECORD_NUMBER             ATOM_CONNECTOR_CF_RECORD_TYPE
 
-typedef struct _ATOM_I2C_RECORD {
-	ATOM_COMMON_RECORD_HEADER sheader;
-	ATOM_I2C_ID_CONFIG sucI2cId;
-	UCHAR ucI2CAddr;	/* The slave address, it's 0 when the record is attached to connector for DDC */
-} ATOM_I2C_RECORD;
+//Must be updated when new record type is added,equal to that record definition!
+#define ATOM_MAX_OBJECT_RECORD_NUMBER             ATOM_CONNECTOR_REMOTE_CAP_RECORD_TYPE
 
-typedef struct _ATOM_HPD_INT_RECORD {
-	ATOM_COMMON_RECORD_HEADER sheader;
-	UCHAR ucHPDIntGPIOID;	/* Corresponding block in GPIO_PIN_INFO table gives the pin info */
-	UCHAR ucPlugged_PinState;
-} ATOM_HPD_INT_RECORD;
+typedef struct  _ATOM_I2C_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  ATOM_I2C_ID_CONFIG          sucI2cId; 
+  UCHAR                       ucI2CAddr;              //The slave address, it's 0 when the record is attached to connector for DDC
+}ATOM_I2C_RECORD;
 
-typedef struct _ATOM_OUTPUT_PROTECTION_RECORD {
-	ATOM_COMMON_RECORD_HEADER sheader;
-	UCHAR ucProtectionFlag;
-	UCHAR ucReserved;
-} ATOM_OUTPUT_PROTECTION_RECORD;
+typedef struct  _ATOM_HPD_INT_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR                       ucHPDIntGPIOID;         //Corresponding block in GPIO_PIN_INFO table gives the pin info           
+  UCHAR                       ucPlugged_PinState;
+}ATOM_HPD_INT_RECORD;
 
-typedef struct _ATOM_CONNECTOR_DEVICE_TAG {
-	ULONG ulACPIDeviceEnum;	/* Reserved for now */
-	USHORT usDeviceID;	/* This Id is same as "ATOM_DEVICE_XXX_SUPPORT" */
-	USHORT usPadding;
-} ATOM_CONNECTOR_DEVICE_TAG;
 
-typedef struct _ATOM_CONNECTOR_DEVICE_TAG_RECORD {
-	ATOM_COMMON_RECORD_HEADER sheader;
-	UCHAR ucNumberOfDevice;
-	UCHAR ucReserved;
-	ATOM_CONNECTOR_DEVICE_TAG asDeviceTag[1];	/* This Id is same as "ATOM_DEVICE_XXX_SUPPORT", 1 is only for allocation */
-} ATOM_CONNECTOR_DEVICE_TAG_RECORD;
+typedef struct  _ATOM_OUTPUT_PROTECTION_RECORD 
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR                       ucProtectionFlag;
+  UCHAR                       ucReserved;
+}ATOM_OUTPUT_PROTECTION_RECORD;
 
-typedef struct _ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD {
-	ATOM_COMMON_RECORD_HEADER sheader;
-	UCHAR ucConfigGPIOID;
-	UCHAR ucConfigGPIOState;	/* Set to 1 when it's active high to enable external flow in */
-	UCHAR ucFlowinGPIPID;
-	UCHAR ucExtInGPIPID;
-} ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD;
+typedef struct  _ATOM_CONNECTOR_DEVICE_TAG
+{
+  ULONG                       ulACPIDeviceEnum;       //Reserved for now
+  USHORT                      usDeviceID;             //This Id is same as "ATOM_DEVICE_XXX_SUPPORT"
+  USHORT                      usPadding;
+}ATOM_CONNECTOR_DEVICE_TAG;
 
-typedef struct _ATOM_ENCODER_FPGA_CONTROL_RECORD {
-	ATOM_COMMON_RECORD_HEADER sheader;
-	UCHAR ucCTL1GPIO_ID;
-	UCHAR ucCTL1GPIOState;	/* Set to 1 when it's active high */
-	UCHAR ucCTL2GPIO_ID;
-	UCHAR ucCTL2GPIOState;	/* Set to 1 when it's active high */
-	UCHAR ucCTL3GPIO_ID;
-	UCHAR ucCTL3GPIOState;	/* Set to 1 when it's active high */
-	UCHAR ucCTLFPGA_IN_ID;
-	UCHAR ucPadding[3];
-} ATOM_ENCODER_FPGA_CONTROL_RECORD;
+typedef struct  _ATOM_CONNECTOR_DEVICE_TAG_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR                       ucNumberOfDevice;
+  UCHAR                       ucReserved;
+  ATOM_CONNECTOR_DEVICE_TAG   asDeviceTag[1];         //This Id is same as "ATOM_DEVICE_XXX_SUPPORT", 1 is only for allocation
+}ATOM_CONNECTOR_DEVICE_TAG_RECORD;
 
-typedef struct _ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD {
-	ATOM_COMMON_RECORD_HEADER sheader;
-	UCHAR ucGPIOID;		/* Corresponding block in GPIO_PIN_INFO table gives the pin info */
-	UCHAR ucTVActiveState;	/* Indicating when the pin==0 or 1 when TV is connected */
-} ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD;
 
-typedef struct _ATOM_JTAG_RECORD {
-	ATOM_COMMON_RECORD_HEADER sheader;
-	UCHAR ucTMSGPIO_ID;
-	UCHAR ucTMSGPIOState;	/* Set to 1 when it's active high */
-	UCHAR ucTCKGPIO_ID;
-	UCHAR ucTCKGPIOState;	/* Set to 1 when it's active high */
-	UCHAR ucTDOGPIO_ID;
-	UCHAR ucTDOGPIOState;	/* Set to 1 when it's active high */
-	UCHAR ucTDIGPIO_ID;
-	UCHAR ucTDIGPIOState;	/* Set to 1 when it's active high */
-	UCHAR ucPadding[2];
-} ATOM_JTAG_RECORD;
+typedef struct  _ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR						            ucConfigGPIOID;
+  UCHAR						            ucConfigGPIOState;	    //Set to 1 when it's active high to enable external flow in
+  UCHAR                       ucFlowinGPIPID;
+  UCHAR                       ucExtInGPIPID;
+}ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD;
 
-/* The following generic object gpio pin control record type will replace JTAG_RECORD/FPGA_CONTROL_RECORD/DVI_EXT_INPUT_RECORD above gradually */
-typedef struct _ATOM_GPIO_PIN_CONTROL_PAIR {
-	UCHAR ucGPIOID;		/*  GPIO_ID, find the corresponding ID in GPIO_LUT table */
-	UCHAR ucGPIO_PinState;	/*  Pin state showing how to set-up the pin */
-} ATOM_GPIO_PIN_CONTROL_PAIR;
+typedef struct  _ATOM_ENCODER_FPGA_CONTROL_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR                       ucCTL1GPIO_ID;
+  UCHAR                       ucCTL1GPIOState;        //Set to 1 when it's active high
+  UCHAR                       ucCTL2GPIO_ID;
+  UCHAR                       ucCTL2GPIOState;        //Set to 1 when it's active high
+  UCHAR                       ucCTL3GPIO_ID;
+  UCHAR                       ucCTL3GPIOState;        //Set to 1 when it's active high
+  UCHAR                       ucCTLFPGA_IN_ID;
+  UCHAR                       ucPadding[3];
+}ATOM_ENCODER_FPGA_CONTROL_RECORD;
 
-typedef struct _ATOM_OBJECT_GPIO_CNTL_RECORD {
-	ATOM_COMMON_RECORD_HEADER sheader;
-	UCHAR ucFlags;		/*  Future expnadibility */
-	UCHAR ucNumberOfPins;	/*  Number of GPIO pins used to control the object */
-	ATOM_GPIO_PIN_CONTROL_PAIR asGpio[1];	/*  the real gpio pin pair determined by number of pins ucNumberOfPins */
-} ATOM_OBJECT_GPIO_CNTL_RECORD;
+typedef struct  _ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR                       ucGPIOID;               //Corresponding block in GPIO_PIN_INFO table gives the pin info 
+  UCHAR                       ucTVActiveState;        //Indicating when the pin==0 or 1 when TV is connected
+}ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD;
 
-/* Definitions for GPIO pin state */
+typedef struct  _ATOM_JTAG_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR                       ucTMSGPIO_ID;
+  UCHAR                       ucTMSGPIOState;         //Set to 1 when it's active high
+  UCHAR                       ucTCKGPIO_ID;
+  UCHAR                       ucTCKGPIOState;         //Set to 1 when it's active high
+  UCHAR                       ucTDOGPIO_ID;
+  UCHAR                       ucTDOGPIOState;         //Set to 1 when it's active high
+  UCHAR                       ucTDIGPIO_ID;
+  UCHAR                       ucTDIGPIOState;         //Set to 1 when it's active high
+  UCHAR                       ucPadding[2];
+}ATOM_JTAG_RECORD;
+
+
+//The following generic object gpio pin control record type will replace JTAG_RECORD/FPGA_CONTROL_RECORD/DVI_EXT_INPUT_RECORD above gradually
+typedef struct _ATOM_GPIO_PIN_CONTROL_PAIR
+{
+  UCHAR                       ucGPIOID;               // GPIO_ID, find the corresponding ID in GPIO_LUT table
+  UCHAR                       ucGPIO_PinState;        // Pin state showing how to set-up the pin
+}ATOM_GPIO_PIN_CONTROL_PAIR;
+
+typedef struct  _ATOM_OBJECT_GPIO_CNTL_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR                       ucFlags;                // Future expnadibility
+  UCHAR                       ucNumberOfPins;         // Number of GPIO pins used to control the object
+  ATOM_GPIO_PIN_CONTROL_PAIR  asGpio[1];              // the real gpio pin pair determined by number of pins ucNumberOfPins
+}ATOM_OBJECT_GPIO_CNTL_RECORD;
+
+//Definitions for GPIO pin state 
 #define GPIO_PIN_TYPE_INPUT             0x00
 #define GPIO_PIN_TYPE_OUTPUT            0x10
 #define GPIO_PIN_TYPE_HW_CONTROL        0x20
 
-/* For GPIO_PIN_TYPE_OUTPUT the following is defined */
+//For GPIO_PIN_TYPE_OUTPUT the following is defined 
 #define GPIO_PIN_OUTPUT_STATE_MASK      0x01
 #define GPIO_PIN_OUTPUT_STATE_SHIFT     0
 #define GPIO_PIN_STATE_ACTIVE_LOW       0x0
 #define GPIO_PIN_STATE_ACTIVE_HIGH      0x1
 
-typedef struct _ATOM_ENCODER_DVO_CF_RECORD {
-	ATOM_COMMON_RECORD_HEADER sheader;
-	ULONG ulStrengthControl;	/*  DVOA strength control for CF */
-	UCHAR ucPadding[2];
-} ATOM_ENCODER_DVO_CF_RECORD;
+// Indexes to GPIO array in GLSync record 
+#define ATOM_GPIO_INDEX_GLSYNC_REFCLK    0
+#define ATOM_GPIO_INDEX_GLSYNC_HSYNC     1
+#define ATOM_GPIO_INDEX_GLSYNC_VSYNC     2
+#define ATOM_GPIO_INDEX_GLSYNC_SWAP_REQ  3
+#define ATOM_GPIO_INDEX_GLSYNC_SWAP_GNT  4
+#define ATOM_GPIO_INDEX_GLSYNC_INTERRUPT 5
+#define ATOM_GPIO_INDEX_GLSYNC_V_RESET   6
+#define ATOM_GPIO_INDEX_GLSYNC_MAX       7
 
-/*  value for ATOM_CONNECTOR_CF_RECORD.ucConnectedDvoBundle */
+typedef struct  _ATOM_ENCODER_DVO_CF_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  ULONG                       ulStrengthControl;      // DVOA strength control for CF
+  UCHAR                       ucPadding[2];
+}ATOM_ENCODER_DVO_CF_RECORD;
+
+// value for ATOM_CONNECTOR_CF_RECORD.ucConnectedDvoBundle
 #define ATOM_CONNECTOR_CF_RECORD_CONNECTED_UPPER12BITBUNDLEA   1
 #define ATOM_CONNECTOR_CF_RECORD_CONNECTED_LOWER12BITBUNDLEB   2
 
-typedef struct _ATOM_CONNECTOR_CF_RECORD {
-	ATOM_COMMON_RECORD_HEADER sheader;
-	USHORT usMaxPixClk;
-	UCHAR ucFlowCntlGpioId;
-	UCHAR ucSwapCntlGpioId;
-	UCHAR ucConnectedDvoBundle;
-	UCHAR ucPadding;
-} ATOM_CONNECTOR_CF_RECORD;
+typedef struct  _ATOM_CONNECTOR_CF_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  USHORT                      usMaxPixClk;
+  UCHAR                       ucFlowCntlGpioId;
+  UCHAR                       ucSwapCntlGpioId;
+  UCHAR                       ucConnectedDvoBundle;
+  UCHAR                       ucPadding;
+}ATOM_CONNECTOR_CF_RECORD;
 
-typedef struct _ATOM_CONNECTOR_HARDCODE_DTD_RECORD {
-	ATOM_COMMON_RECORD_HEADER sheader;
-	ATOM_DTD_FORMAT asTiming;
-} ATOM_CONNECTOR_HARDCODE_DTD_RECORD;
+typedef struct  _ATOM_CONNECTOR_HARDCODE_DTD_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+	ATOM_DTD_FORMAT							asTiming;
+}ATOM_CONNECTOR_HARDCODE_DTD_RECORD;
 
-typedef struct _ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD {
-	ATOM_COMMON_RECORD_HEADER sheader;	/* ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD_TYPE */
-	UCHAR ucSubConnectorType;	/* CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D|X_ID_DUAL_LINK_DVI_D|HDMI_TYPE_A */
-	UCHAR ucReserved;
-} ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD;
+typedef struct _ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;                //ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD_TYPE
+  UCHAR                       ucSubConnectorType;     //CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D|X_ID_DUAL_LINK_DVI_D|HDMI_TYPE_A
+  UCHAR                       ucReserved;
+}ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD;
 
-typedef struct _ATOM_ROUTER_DDC_PATH_SELECT_RECORD {
-	ATOM_COMMON_RECORD_HEADER sheader;
-	UCHAR ucMuxType;	/* decide the number of ucMuxState, =0, no pin state, =1: single state with complement, >1: multiple state */
-	UCHAR ucMuxControlPin;
-	UCHAR ucMuxState[2];	/* for alligment purpose */
-} ATOM_ROUTER_DDC_PATH_SELECT_RECORD;
 
-typedef struct _ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD {
-	ATOM_COMMON_RECORD_HEADER sheader;
-	UCHAR ucMuxType;
-	UCHAR ucMuxControlPin;
-	UCHAR ucMuxState[2];	/* for alligment purpose */
-} ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD;
+typedef struct _ATOM_ROUTER_DDC_PATH_SELECT_RECORD
+{
+	ATOM_COMMON_RECORD_HEADER   sheader;                
+	UCHAR												ucMuxType;							//decide the number of ucMuxState, =0, no pin state, =1: single state with complement, >1: multiple state
+	UCHAR												ucMuxControlPin;
+	UCHAR												ucMuxState[2];					//for alligment purpose
+}ATOM_ROUTER_DDC_PATH_SELECT_RECORD;
 
-/*  define ucMuxType */
+typedef struct _ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD
+{
+	ATOM_COMMON_RECORD_HEADER   sheader;                
+	UCHAR												ucMuxType;
+	UCHAR												ucMuxControlPin;
+	UCHAR												ucMuxState[2];					//for alligment purpose
+}ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD;
+
+// define ucMuxType
 #define ATOM_ROUTER_MUX_PIN_STATE_MASK								0x0f
 #define ATOM_ROUTER_MUX_PIN_SINGLE_STATE_COMPLEMENT		0x01
 
-/****************************************************************************/
-/*  ASIC voltage data table */
-/****************************************************************************/
-typedef struct _ATOM_VOLTAGE_INFO_HEADER {
-	USHORT usVDDCBaseLevel;	/* In number of 50mv unit */
-	USHORT usReserved;	/* For possible extension table offset */
-	UCHAR ucNumOfVoltageEntries;
-	UCHAR ucBytesPerVoltageEntry;
-	UCHAR ucVoltageStep;	/* Indicating in how many mv increament is one step, 0.5mv unit */
-	UCHAR ucDefaultVoltageEntry;
-	UCHAR ucVoltageControlI2cLine;
-	UCHAR ucVoltageControlAddress;
-	UCHAR ucVoltageControlOffset;
-} ATOM_VOLTAGE_INFO_HEADER;
+typedef struct _ATOM_CONNECTOR_HPDPIN_LUT_RECORD     //record for ATOM_CONNECTOR_HPDPIN_LUT_RECORD_TYPE
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR                       ucHPDPINMap[MAX_NUMBER_OF_EXT_HPDPIN_LUT_ENTRIES];  //An fixed size array which maps external pins to internal GPIO_PIN_INFO table 
+}ATOM_CONNECTOR_HPDPIN_LUT_RECORD;
 
-typedef struct _ATOM_VOLTAGE_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ATOM_VOLTAGE_INFO_HEADER viHeader;
-	UCHAR ucVoltageEntries[64];	/* 64 is for allocation, the actual number of entry is present at ucNumOfVoltageEntries*ucBytesPerVoltageEntry */
-} ATOM_VOLTAGE_INFO;
+typedef struct _ATOM_CONNECTOR_AUXDDC_LUT_RECORD  //record for ATOM_CONNECTOR_AUXDDC_LUT_RECORD_TYPE
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  ATOM_I2C_ID_CONFIG          ucAUXDDCMap[MAX_NUMBER_OF_EXT_AUXDDC_LUT_ENTRIES];  //An fixed size array which maps external pins to internal DDC ID
+}ATOM_CONNECTOR_AUXDDC_LUT_RECORD;
 
-typedef struct _ATOM_VOLTAGE_FORMULA {
-	USHORT usVoltageBaseLevel;	/*  In number of 1mv unit */
-	USHORT usVoltageStep;	/*  Indicating in how many mv increament is one step, 1mv unit */
-	UCHAR ucNumOfVoltageEntries;	/*  Number of Voltage Entry, which indicate max Voltage */
-	UCHAR ucFlag;		/*  bit0=0 :step is 1mv =1 0.5mv */
-	UCHAR ucBaseVID;	/*  if there is no lookup table, VID= BaseVID + ( Vol - BaseLevle ) /VoltageStep */
-	UCHAR ucReserved;
-	UCHAR ucVIDAdjustEntries[32];	/*  32 is for allocation, the actual number of entry is present at ucNumOfVoltageEntries */
-} ATOM_VOLTAGE_FORMULA;
+typedef struct _ATOM_OBJECT_LINK_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  USHORT                      usObjectID;         //could be connector, encorder or other object in object.h
+}ATOM_OBJECT_LINK_RECORD;
 
-typedef struct _ATOM_VOLTAGE_CONTROL {
-	UCHAR ucVoltageControlId;	/* Indicate it is controlled by I2C or GPIO or HW state machine */
-	UCHAR ucVoltageControlI2cLine;
-	UCHAR ucVoltageControlAddress;
-	UCHAR ucVoltageControlOffset;
-	USHORT usGpioPin_AIndex;	/* GPIO_PAD register index */
-	UCHAR ucGpioPinBitShift[9];	/* at most 8 pin support 255 VIDs, termintate with 0xff */
-	UCHAR ucReserved;
-} ATOM_VOLTAGE_CONTROL;
+typedef struct _ATOM_CONNECTOR_REMOTE_CAP_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  USHORT                      usReserved;
+}ATOM_CONNECTOR_REMOTE_CAP_RECORD;
 
-/*  Define ucVoltageControlId */
+/****************************************************************************/	
+// ASIC voltage data table
+/****************************************************************************/	
+typedef struct  _ATOM_VOLTAGE_INFO_HEADER
+{
+   USHORT   usVDDCBaseLevel;                //In number of 50mv unit
+   USHORT   usReserved;                     //For possible extension table offset
+   UCHAR    ucNumOfVoltageEntries;
+   UCHAR    ucBytesPerVoltageEntry;
+   UCHAR    ucVoltageStep;                  //Indicating in how many mv increament is one step, 0.5mv unit
+   UCHAR    ucDefaultVoltageEntry;
+   UCHAR    ucVoltageControlI2cLine;
+   UCHAR    ucVoltageControlAddress;
+   UCHAR    ucVoltageControlOffset;
+}ATOM_VOLTAGE_INFO_HEADER;
+
+typedef struct  _ATOM_VOLTAGE_INFO
+{
+   ATOM_COMMON_TABLE_HEADER	sHeader; 
+   ATOM_VOLTAGE_INFO_HEADER viHeader;
+   UCHAR    ucVoltageEntries[64];            //64 is for allocation, the actual number of entry is present at ucNumOfVoltageEntries*ucBytesPerVoltageEntry
+}ATOM_VOLTAGE_INFO;
+
+
+typedef struct  _ATOM_VOLTAGE_FORMULA
+{
+   USHORT   usVoltageBaseLevel;             // In number of 1mv unit
+   USHORT   usVoltageStep;                  // Indicating in how many mv increament is one step, 1mv unit
+	 UCHAR		ucNumOfVoltageEntries;					// Number of Voltage Entry, which indicate max Voltage
+	 UCHAR		ucFlag;													// bit0=0 :step is 1mv =1 0.5mv
+	 UCHAR		ucBaseVID;											// if there is no lookup table, VID= BaseVID + ( Vol - BaseLevle ) /VoltageStep
+	 UCHAR		ucReserved;
+	 UCHAR		ucVIDAdjustEntries[32];					// 32 is for allocation, the actual number of entry is present at ucNumOfVoltageEntries
+}ATOM_VOLTAGE_FORMULA;
+
+typedef struct  _VOLTAGE_LUT_ENTRY
+{
+	 USHORT		usVoltageCode;									// The Voltage ID, either GPIO or I2C code
+	 USHORT		usVoltageValue;									// The corresponding Voltage Value, in mV
+}VOLTAGE_LUT_ENTRY;
+
+typedef struct  _ATOM_VOLTAGE_FORMULA_V2
+{
+	 UCHAR		ucNumOfVoltageEntries;					// Number of Voltage Entry, which indicate max Voltage
+	 UCHAR		ucReserved[3];
+	 VOLTAGE_LUT_ENTRY asVIDAdjustEntries[32];// 32 is for allocation, the actual number of entries is in ucNumOfVoltageEntries
+}ATOM_VOLTAGE_FORMULA_V2;
+
+typedef struct _ATOM_VOLTAGE_CONTROL
+{
+	UCHAR		 ucVoltageControlId;							//Indicate it is controlled by I2C or GPIO or HW state machine		
+  UCHAR    ucVoltageControlI2cLine;
+  UCHAR    ucVoltageControlAddress;
+  UCHAR    ucVoltageControlOffset;	 	
+  USHORT   usGpioPin_AIndex;								//GPIO_PAD register index
+  UCHAR    ucGpioPinBitShift[9];						//at most 8 pin support 255 VIDs, termintate with 0xff
+	UCHAR		 ucReserved;
+}ATOM_VOLTAGE_CONTROL;
+
+// Define ucVoltageControlId
 #define	VOLTAGE_CONTROLLED_BY_HW							0x00
 #define	VOLTAGE_CONTROLLED_BY_I2C_MASK				0x7F
 #define	VOLTAGE_CONTROLLED_BY_GPIO						0x80
-#define	VOLTAGE_CONTROL_ID_LM64								0x01	/* I2C control, used for R5xx Core Voltage */
-#define	VOLTAGE_CONTROL_ID_DAC								0x02	/* I2C control, used for R5xx/R6xx MVDDC,MVDDQ or VDDCI */
-#define	VOLTAGE_CONTROL_ID_VT116xM						0x03	/* I2C control, used for R6xx Core Voltage */
-#define VOLTAGE_CONTROL_ID_DS4402							0x04
+#define	VOLTAGE_CONTROL_ID_LM64								0x01									//I2C control, used for R5xx Core Voltage
+#define	VOLTAGE_CONTROL_ID_DAC								0x02									//I2C control, used for R5xx/R6xx MVDDC,MVDDQ or VDDCI
+#define	VOLTAGE_CONTROL_ID_VT116xM						0x03									//I2C control, used for R6xx Core Voltage
+#define VOLTAGE_CONTROL_ID_DS4402							0x04									
 
-typedef struct _ATOM_VOLTAGE_OBJECT {
-	UCHAR ucVoltageType;	/* Indicate Voltage Source: VDDC, MVDDC, MVDDQ or MVDDCI */
-	UCHAR ucSize;		/* Size of Object */
-	ATOM_VOLTAGE_CONTROL asControl;	/* describ how to control */
-	ATOM_VOLTAGE_FORMULA asFormula;	/* Indicate How to convert real Voltage to VID */
-} ATOM_VOLTAGE_OBJECT;
+typedef struct  _ATOM_VOLTAGE_OBJECT
+{
+ 	 UCHAR		ucVoltageType;									//Indicate Voltage Source: VDDC, MVDDC, MVDDQ or MVDDCI	 
+	 UCHAR		ucSize;													//Size of Object	
+	 ATOM_VOLTAGE_CONTROL			asControl;			//describ how to control 	 
+ 	 ATOM_VOLTAGE_FORMULA			asFormula;			//Indicate How to convert real Voltage to VID 
+}ATOM_VOLTAGE_OBJECT;
 
-typedef struct _ATOM_VOLTAGE_OBJECT_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ATOM_VOLTAGE_OBJECT asVoltageObj[3];	/* Info for Voltage control */
-} ATOM_VOLTAGE_OBJECT_INFO;
+typedef struct  _ATOM_VOLTAGE_OBJECT_V2
+{
+ 	 UCHAR		ucVoltageType;									//Indicate Voltage Source: VDDC, MVDDC, MVDDQ or MVDDCI	 
+	 UCHAR		ucSize;													//Size of Object	
+	 ATOM_VOLTAGE_CONTROL			asControl;			//describ how to control 	 
+ 	 ATOM_VOLTAGE_FORMULA_V2	asFormula;			//Indicate How to convert real Voltage to VID 
+}ATOM_VOLTAGE_OBJECT_V2;
 
-typedef struct _ATOM_LEAKID_VOLTAGE {
-	UCHAR ucLeakageId;
-	UCHAR ucReserved;
-	USHORT usVoltage;
-} ATOM_LEAKID_VOLTAGE;
+typedef struct  _ATOM_VOLTAGE_OBJECT_INFO
+{
+   ATOM_COMMON_TABLE_HEADER	sHeader; 
+	 ATOM_VOLTAGE_OBJECT			asVoltageObj[3];	//Info for Voltage control	  	 
+}ATOM_VOLTAGE_OBJECT_INFO;
 
-typedef struct _ATOM_ASIC_PROFILE_VOLTAGE {
-	UCHAR ucProfileId;
-	UCHAR ucReserved;
-	USHORT usSize;
-	USHORT usEfuseSpareStartAddr;
-	USHORT usFuseIndex[8];	/* from LSB to MSB, Max 8bit,end of 0xffff if less than 8 efuse id, */
-	ATOM_LEAKID_VOLTAGE asLeakVol[2];	/* Leakid and relatd voltage */
-} ATOM_ASIC_PROFILE_VOLTAGE;
+typedef struct  _ATOM_VOLTAGE_OBJECT_INFO_V2
+{
+   ATOM_COMMON_TABLE_HEADER	sHeader; 
+	 ATOM_VOLTAGE_OBJECT_V2			asVoltageObj[3];	//Info for Voltage control	  	 
+}ATOM_VOLTAGE_OBJECT_INFO_V2;
 
-/* ucProfileId */
-#define	ATOM_ASIC_PROFILE_ID_EFUSE_VOLTAGE			1
+typedef struct  _ATOM_LEAKID_VOLTAGE
+{
+	UCHAR		ucLeakageId;
+	UCHAR		ucReserved;
+	USHORT	usVoltage;
+}ATOM_LEAKID_VOLTAGE;
+
+typedef struct  _ATOM_ASIC_PROFILE_VOLTAGE
+{
+	UCHAR		ucProfileId;
+	UCHAR		ucReserved;
+	USHORT	usSize;
+	USHORT	usEfuseSpareStartAddr;
+	USHORT	usFuseIndex[8];												//from LSB to MSB, Max 8bit,end of 0xffff if less than 8 efuse id, 
+	ATOM_LEAKID_VOLTAGE					asLeakVol[2];			//Leakid and relatd voltage
+}ATOM_ASIC_PROFILE_VOLTAGE;
+
+//ucProfileId
+#define	ATOM_ASIC_PROFILE_ID_EFUSE_VOLTAGE			1		
 #define	ATOM_ASIC_PROFILE_ID_EFUSE_PERFORMANCE_VOLTAGE			1
 #define	ATOM_ASIC_PROFILE_ID_EFUSE_THERMAL_VOLTAGE					2
 
-typedef struct _ATOM_ASIC_PROFILING_INFO {
-	ATOM_COMMON_TABLE_HEADER asHeader;
-	ATOM_ASIC_PROFILE_VOLTAGE asVoltage;
-} ATOM_ASIC_PROFILING_INFO;
+typedef struct  _ATOM_ASIC_PROFILING_INFO
+{
+  ATOM_COMMON_TABLE_HEADER			asHeader; 
+	ATOM_ASIC_PROFILE_VOLTAGE			asVoltage;
+}ATOM_ASIC_PROFILING_INFO;
 
-typedef struct _ATOM_POWER_SOURCE_OBJECT {
-	UCHAR ucPwrSrcId;	/*  Power source */
-	UCHAR ucPwrSensorType;	/*  GPIO, I2C or none */
-	UCHAR ucPwrSensId;	/*  if GPIO detect, it is GPIO id,  if I2C detect, it is I2C id */
-	UCHAR ucPwrSensSlaveAddr;	/*  Slave address if I2C detect */
-	UCHAR ucPwrSensRegIndex;	/*  I2C register Index if I2C detect */
-	UCHAR ucPwrSensRegBitMask;	/*  detect which bit is used if I2C detect */
-	UCHAR ucPwrSensActiveState;	/*  high active or low active */
-	UCHAR ucReserve[3];	/*  reserve */
-	USHORT usSensPwr;	/*  in unit of watt */
-} ATOM_POWER_SOURCE_OBJECT;
+typedef struct _ATOM_POWER_SOURCE_OBJECT
+{
+	UCHAR	ucPwrSrcId;													// Power source
+	UCHAR	ucPwrSensorType;										// GPIO, I2C or none
+	UCHAR	ucPwrSensId;											  // if GPIO detect, it is GPIO id,  if I2C detect, it is I2C id
+	UCHAR	ucPwrSensSlaveAddr;									// Slave address if I2C detect
+	UCHAR ucPwrSensRegIndex;									// I2C register Index if I2C detect
+	UCHAR ucPwrSensRegBitMask;								// detect which bit is used if I2C detect
+	UCHAR	ucPwrSensActiveState;								// high active or low active
+	UCHAR	ucReserve[3];												// reserve		
+	USHORT usSensPwr;													// in unit of watt
+}ATOM_POWER_SOURCE_OBJECT;
 
-typedef struct _ATOM_POWER_SOURCE_INFO {
-	ATOM_COMMON_TABLE_HEADER asHeader;
-	UCHAR asPwrbehave[16];
-	ATOM_POWER_SOURCE_OBJECT asPwrObj[1];
-} ATOM_POWER_SOURCE_INFO;
+typedef struct _ATOM_POWER_SOURCE_INFO
+{
+		ATOM_COMMON_TABLE_HEADER		asHeader;
+		UCHAR												asPwrbehave[16];
+		ATOM_POWER_SOURCE_OBJECT		asPwrObj[1];
+}ATOM_POWER_SOURCE_INFO;
 
-/* Define ucPwrSrcId */
+
+//Define ucPwrSrcId
 #define POWERSOURCE_PCIE_ID1						0x00
 #define POWERSOURCE_6PIN_CONNECTOR_ID1	0x01
 #define POWERSOURCE_8PIN_CONNECTOR_ID1	0x02
 #define POWERSOURCE_6PIN_CONNECTOR_ID2	0x04
 #define POWERSOURCE_8PIN_CONNECTOR_ID2	0x08
 
-/* define ucPwrSensorId */
+//define ucPwrSensorId
 #define POWER_SENSOR_ALWAYS							0x00
 #define POWER_SENSOR_GPIO								0x01
 #define POWER_SENSOR_I2C								0x02
 
+typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V6
+{
+  ATOM_COMMON_TABLE_HEADER   sHeader;
+  ULONG  ulBootUpEngineClock;
+  ULONG  ulDentistVCOFreq;          
+  ULONG  ulBootUpUMAClock;          
+  ULONG  ulReserved1[8];            
+  ULONG  ulBootUpReqDisplayVector;
+  ULONG  ulOtherDisplayMisc;
+  ULONG  ulGPUCapInfo;
+  ULONG  ulReserved2[3];            
+  ULONG  ulSystemConfig;            
+  ULONG  ulCPUCapInfo;              
+  USHORT usMaxNBVoltage;  
+  USHORT usMinNBVoltage;  
+  USHORT usBootUpNBVoltage;         
+  USHORT usExtDispConnInfoOffset;  
+  UCHAR  ucHtcTmpLmt;   
+  UCHAR  ucTjOffset;    
+  UCHAR  ucMemoryType;  
+  UCHAR  ucUMAChannelNumber;
+  ULONG  ulCSR_M3_ARB_CNTL_DEFAULT[10];  
+  ULONG  ulCSR_M3_ARB_CNTL_UVD[10]; 
+  ULONG  ulCSR_M3_ARB_CNTL_FS3D[10];
+  ULONG  ulReserved3[42]; 
+  ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO sExtDispConnInfo;   
+}ATOM_INTEGRATED_SYSTEM_INFO_V6;   
+
+/**********************************************************************************************************************
+// ATOM_INTEGRATED_SYSTEM_INFO_V6 Description
+//ulBootUpEngineClock:              VBIOS bootup Engine clock frequency, in 10kHz unit. 
+//ulDentistVCOFreq:                 Dentist VCO clock in 10kHz unit. 
+//ulBootUpUMAClock:                 System memory boot up clock frequency in 10Khz unit. 
+//ulReserved1[8]                    Reserved by now, must be 0x0. 
+//ulBootUpReqDisplayVector	        VBIOS boot up display IDs
+//                                  ATOM_DEVICE_CRT1_SUPPORT                  0x0001
+//                                  ATOM_DEVICE_CRT2_SUPPORT                  0x0010
+//                                  ATOM_DEVICE_DFP1_SUPPORT                  0x0008 
+//                                  ATOM_DEVICE_DFP6_SUPPORT                  0x0040 
+//                                  ATOM_DEVICE_DFP2_SUPPORT                  0x0080       
+//                                  ATOM_DEVICE_DFP3_SUPPORT                  0x0200       
+//                                  ATOM_DEVICE_DFP4_SUPPORT                  0x0400        
+//                                  ATOM_DEVICE_DFP5_SUPPORT                  0x0800
+//                                  ATOM_DEVICE_LCD1_SUPPORT                  0x0002
+//ulOtherDisplayMisc      	        Other display related flags, not defined yet. 
+//ulGPUCapInfo                      TBD
+//ulReserved2[3]                    must be 0x0 for the reserved.
+//ulSystemConfig                    TBD
+//ulCPUCapInfo                      TBD
+//usMaxNBVoltage                    High NB voltage in unit of mv, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse. 
+//usMinNBVoltage                    Low NB voltage in unit of mv, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse.
+//usBootUpNBVoltage                 Boot up NB voltage in unit of mv.
+//ucHtcTmpLmt                       Bit [22:16] of D24F3x64 Thermal Control (HTC) Register.
+//ucTjOffset                        Bit [28:22] of D24F3xE4 Thermtrip Status Register,may not be needed.
+//ucMemoryType                      [3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved.
+//ucUMAChannelNumber      	        System memory channel numbers. 
+//usExtDispConnectionInfoOffset     ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO offset relative to beginning of this table. 
+//ulCSR_M3_ARB_CNTL_DEFAULT[10]     Arrays with values for CSR M3 arbiter for default
+//ulCSR_M3_ARB_CNTL_UVD[10]         Arrays with values for CSR M3 arbiter for UVD playback.
+//ulCSR_M3_ARB_CNTL_FS3D[10]        Arrays with values for CSR M3 arbiter for Full Screen 3D applications.
+**********************************************************************************************************************/
+
 /**************************************************************************/
-/*  This portion is only used when ext thermal chip or engine/memory clock SS chip is populated on a design */
-/* Memory SS Info Table */
-/* Define Memory Clock SS chip ID */
+// This portion is only used when ext thermal chip or engine/memory clock SS chip is populated on a design
+//Memory SS Info Table
+//Define Memory Clock SS chip ID
 #define ICS91719  1
 #define ICS91720  2
 
-/* Define one structure to inform SW a "block of data" writing to external SS chip via I2C protocol */
-typedef struct _ATOM_I2C_DATA_RECORD {
-	UCHAR ucNunberOfBytes;	/* Indicates how many bytes SW needs to write to the external ASIC for one block, besides to "Start" and "Stop" */
-	UCHAR ucI2CData[1];	/* I2C data in bytes, should be less than 16 bytes usually */
-} ATOM_I2C_DATA_RECORD;
+//Define one structure to inform SW a "block of data" writing to external SS chip via I2C protocol
+typedef struct _ATOM_I2C_DATA_RECORD
+{
+  UCHAR         ucNunberOfBytes;                                              //Indicates how many bytes SW needs to write to the external ASIC for one block, besides to "Start" and "Stop"
+  UCHAR         ucI2CData[1];                                                 //I2C data in bytes, should be less than 16 bytes usually
+}ATOM_I2C_DATA_RECORD;
 
-/* Define one structure to inform SW how many blocks of data writing to external SS chip via I2C protocol, in addition to other information */
-typedef struct _ATOM_I2C_DEVICE_SETUP_INFO {
-	ATOM_I2C_ID_CONFIG_ACCESS sucI2cId;	/* I2C line and HW/SW assisted cap. */
-	UCHAR ucSSChipID;	/* SS chip being used */
-	UCHAR ucSSChipSlaveAddr;	/* Slave Address to set up this SS chip */
-	UCHAR ucNumOfI2CDataRecords;	/* number of data block */
-	ATOM_I2C_DATA_RECORD asI2CData[1];
-} ATOM_I2C_DEVICE_SETUP_INFO;
 
-/* ========================================================================================== */
-typedef struct _ATOM_ASIC_MVDD_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ATOM_I2C_DEVICE_SETUP_INFO asI2CSetup[1];
-} ATOM_ASIC_MVDD_INFO;
+//Define one structure to inform SW how many blocks of data writing to external SS chip via I2C protocol, in addition to other information
+typedef struct _ATOM_I2C_DEVICE_SETUP_INFO
+{
+  ATOM_I2C_ID_CONFIG_ACCESS       sucI2cId;               //I2C line and HW/SW assisted cap.
+  UCHAR		                        ucSSChipID;             //SS chip being used
+  UCHAR		                        ucSSChipSlaveAddr;      //Slave Address to set up this SS chip
+  UCHAR                           ucNumOfI2CDataRecords;  //number of data block
+  ATOM_I2C_DATA_RECORD            asI2CData[1];  
+}ATOM_I2C_DEVICE_SETUP_INFO;
 
-/* ========================================================================================== */
+//==========================================================================================
+typedef struct  _ATOM_ASIC_MVDD_INFO
+{
+  ATOM_COMMON_TABLE_HEADER	      sHeader; 
+  ATOM_I2C_DEVICE_SETUP_INFO      asI2CSetup[1];
+}ATOM_ASIC_MVDD_INFO;
+
+//==========================================================================================
 #define ATOM_MCLK_SS_INFO         ATOM_ASIC_MVDD_INFO
 
-/* ========================================================================================== */
+//==========================================================================================
 /**************************************************************************/
 
-typedef struct _ATOM_ASIC_SS_ASSIGNMENT {
-	ULONG ulTargetClockRange;	/* Clock Out frequence (VCO ), in unit of 10Khz */
-	USHORT usSpreadSpectrumPercentage;	/* in unit of 0.01% */
-	USHORT usSpreadRateInKhz;	/* in unit of kHz, modulation freq */
-	UCHAR ucClockIndication;	/* Indicate which clock source needs SS */
-	UCHAR ucSpreadSpectrumMode;	/* Bit1=0 Down Spread,=1 Center Spread. */
-	UCHAR ucReserved[2];
-} ATOM_ASIC_SS_ASSIGNMENT;
+typedef struct _ATOM_ASIC_SS_ASSIGNMENT
+{
+	ULONG								ulTargetClockRange;						//Clock Out frequence (VCO ), in unit of 10Khz
+  USHORT              usSpreadSpectrumPercentage;		//in unit of 0.01%
+	USHORT							usSpreadRateInKhz;						//in unit of kHz, modulation freq
+  UCHAR               ucClockIndication;					  //Indicate which clock source needs SS
+	UCHAR								ucSpreadSpectrumMode;					//Bit1=0 Down Spread,=1 Center Spread.
+	UCHAR								ucReserved[2];
+}ATOM_ASIC_SS_ASSIGNMENT;
 
-/* Define ucSpreadSpectrumType */
+//Define ucClockIndication, SW uses the IDs below to search if the SS is requried/enabled on a clock branch/signal type.
+//SS is not required or enabled if a match is not found.
 #define ASIC_INTERNAL_MEMORY_SS			1
 #define ASIC_INTERNAL_ENGINE_SS			2
-#define ASIC_INTERNAL_UVD_SS				3
+#define ASIC_INTERNAL_UVD_SS        3
+#define ASIC_INTERNAL_SS_ON_TMDS    4
+#define ASIC_INTERNAL_SS_ON_HDMI    5
+#define ASIC_INTERNAL_SS_ON_LVDS    6
+#define ASIC_INTERNAL_SS_ON_DP      7
+#define ASIC_INTERNAL_SS_ON_DCPLL   8
 
-typedef struct _ATOM_ASIC_INTERNAL_SS_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ATOM_ASIC_SS_ASSIGNMENT asSpreadSpectrum[4];
-} ATOM_ASIC_INTERNAL_SS_INFO;
+typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V2
+{
+	ULONG								ulTargetClockRange;						//For mem/engine/uvd, Clock Out frequence (VCO ), in unit of 10Khz
+                                                    //For TMDS/HDMI/LVDS, it is pixel clock , for DP, it is link clock ( 27000 or 16200 )
+  USHORT              usSpreadSpectrumPercentage;		//in unit of 0.01%
+	USHORT							usSpreadRateIn10Hz;						//in unit of 10Hz, modulation freq
+  UCHAR               ucClockIndication;					  //Indicate which clock source needs SS
+	UCHAR								ucSpreadSpectrumMode;					//Bit0=0 Down Spread,=1 Center Spread, bit1=0: internal SS bit1=1: external SS
+	UCHAR								ucReserved[2];
+}ATOM_ASIC_SS_ASSIGNMENT_V2;
 
-/* ==============================Scratch Pad Definition Portion=============================== */
+//ucSpreadSpectrumMode
+//#define ATOM_SS_DOWN_SPREAD_MODE_MASK          0x00000000
+//#define ATOM_SS_DOWN_SPREAD_MODE               0x00000000
+//#define ATOM_SS_CENTRE_SPREAD_MODE_MASK        0x00000001
+//#define ATOM_SS_CENTRE_SPREAD_MODE             0x00000001
+//#define ATOM_INTERNAL_SS_MASK                  0x00000000
+//#define ATOM_EXTERNAL_SS_MASK                  0x00000002
+
+typedef struct _ATOM_ASIC_INTERNAL_SS_INFO
+{
+  ATOM_COMMON_TABLE_HEADER	      sHeader; 
+  ATOM_ASIC_SS_ASSIGNMENT		      asSpreadSpectrum[4];
+}ATOM_ASIC_INTERNAL_SS_INFO;
+
+typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V2
+{
+  ATOM_COMMON_TABLE_HEADER	      sHeader; 
+  ATOM_ASIC_SS_ASSIGNMENT_V2		  asSpreadSpectrum[1];      //this is point only. 
+}ATOM_ASIC_INTERNAL_SS_INFO_V2;
+
+typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V3
+{
+	ULONG								ulTargetClockRange;						//For mem/engine/uvd, Clock Out frequence (VCO ), in unit of 10Khz
+                                                    //For TMDS/HDMI/LVDS, it is pixel clock , for DP, it is link clock ( 27000 or 16200 )
+  USHORT              usSpreadSpectrumPercentage;		//in unit of 0.01%
+	USHORT							usSpreadRateIn10Hz;						//in unit of 10Hz, modulation freq
+  UCHAR               ucClockIndication;					  //Indicate which clock source needs SS
+	UCHAR								ucSpreadSpectrumMode;					//Bit0=0 Down Spread,=1 Center Spread, bit1=0: internal SS bit1=1: external SS
+	UCHAR								ucReserved[2];
+}ATOM_ASIC_SS_ASSIGNMENT_V3;
+
+typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3
+{
+  ATOM_COMMON_TABLE_HEADER	      sHeader; 
+  ATOM_ASIC_SS_ASSIGNMENT_V3		  asSpreadSpectrum[1];      //this is pointer only. 
+}ATOM_ASIC_INTERNAL_SS_INFO_V3;
+
+
+//==============================Scratch Pad Definition Portion===============================
 #define ATOM_DEVICE_CONNECT_INFO_DEF  0
 #define ATOM_ROM_LOCATION_DEF         1
 #define ATOM_TV_STANDARD_DEF          2
@@ -2995,7 +3852,8 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_I2C_CHANNEL_STATUS_DEF   8
 #define ATOM_I2C_CHANNEL_STATUS1_DEF  9
 
-/*  BIOS_0_SCRATCH Definition */
+
+// BIOS_0_SCRATCH Definition 
 #define ATOM_S0_CRT1_MONO               0x00000001L
 #define ATOM_S0_CRT1_COLOR              0x00000002L
 #define ATOM_S0_CRT1_MASK               (ATOM_S0_CRT1_MONO+ATOM_S0_CRT1_COLOR)
@@ -3008,6 +3866,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S0_CV_DIN_A                0x00000020L
 #define ATOM_S0_CV_MASK_A               (ATOM_S0_CV_A+ATOM_S0_CV_DIN_A)
 
+
 #define ATOM_S0_CRT2_MONO               0x00000100L
 #define ATOM_S0_CRT2_COLOR              0x00000200L
 #define ATOM_S0_CRT2_MASK               (ATOM_S0_CRT2_MONO+ATOM_S0_CRT2_COLOR)
@@ -3025,28 +3884,27 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S0_DFP2                    0x00020000L
 #define ATOM_S0_LCD1                    0x00040000L
 #define ATOM_S0_LCD2                    0x00080000L
-#define ATOM_S0_TV2                     0x00100000L
-#define ATOM_S0_DFP3			0x00200000L
-#define ATOM_S0_DFP4			0x00400000L
-#define ATOM_S0_DFP5			0x00800000L
+#define ATOM_S0_DFP6                    0x00100000L
+#define ATOM_S0_DFP3                    0x00200000L
+#define ATOM_S0_DFP4                    0x00400000L
+#define ATOM_S0_DFP5                    0x00800000L
 
-#define ATOM_S0_DFP_MASK \
-	(ATOM_S0_DFP1 | ATOM_S0_DFP2 | ATOM_S0_DFP3 | ATOM_S0_DFP4 | ATOM_S0_DFP5)
+#define ATOM_S0_DFP_MASK                ATOM_S0_DFP1 | ATOM_S0_DFP2 | ATOM_S0_DFP3 | ATOM_S0_DFP4 | ATOM_S0_DFP5 | ATOM_S0_DFP6
 
-#define ATOM_S0_FAD_REGISTER_BUG        0x02000000L	/*  If set, indicates we are running a PCIE asic with */
-						    /*  the FAD/HDP reg access bug.  Bit is read by DAL */
+#define ATOM_S0_FAD_REGISTER_BUG        0x02000000L // If set, indicates we are running a PCIE asic with 
+                                                    // the FAD/HDP reg access bug.  Bit is read by DAL, this is obsolete from RV5xx
 
 #define ATOM_S0_THERMAL_STATE_MASK      0x1C000000L
 #define ATOM_S0_THERMAL_STATE_SHIFT     26
 
 #define ATOM_S0_SYSTEM_POWER_STATE_MASK 0xE0000000L
-#define ATOM_S0_SYSTEM_POWER_STATE_SHIFT 29
+#define ATOM_S0_SYSTEM_POWER_STATE_SHIFT 29 
 
 #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_AC     1
 #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_DC     2
 #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LITEAC 3
 
-/* Byte aligned definition for BIOS usage */
+//Byte aligned defintion for BIOS usage
 #define ATOM_S0_CRT1_MONOb0             0x01
 #define ATOM_S0_CRT1_COLORb0            0x02
 #define ATOM_S0_CRT1_MASKb0             (ATOM_S0_CRT1_MONOb0+ATOM_S0_CRT1_COLORb0)
@@ -3076,8 +3934,11 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S0_DFP2b2                  0x02
 #define ATOM_S0_LCD1b2                  0x04
 #define ATOM_S0_LCD2b2                  0x08
-#define ATOM_S0_TV2b2                   0x10
-#define ATOM_S0_DFP3b2									0x20
+#define ATOM_S0_DFP6b2                  0x10
+#define ATOM_S0_DFP3b2                  0x20
+#define ATOM_S0_DFP4b2                  0x40
+#define ATOM_S0_DFP5b2                  0x80
+
 
 #define ATOM_S0_THERMAL_STATE_MASKb3    0x1C
 #define ATOM_S0_THERMAL_STATE_SHIFTb3   2
@@ -3085,43 +3946,20 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S0_SYSTEM_POWER_STATE_MASKb3 0xE0
 #define ATOM_S0_LCD1_SHIFT              18
 
-/*  BIOS_1_SCRATCH Definition */
+// BIOS_1_SCRATCH Definition
 #define ATOM_S1_ROM_LOCATION_MASK       0x0000FFFFL
 #define ATOM_S1_PCI_BUS_DEV_MASK        0xFFFF0000L
 
-/*       BIOS_2_SCRATCH Definition */
+//	BIOS_2_SCRATCH Definition
 #define ATOM_S2_TV1_STANDARD_MASK       0x0000000FL
 #define ATOM_S2_CURRENT_BL_LEVEL_MASK   0x0000FF00L
 #define ATOM_S2_CURRENT_BL_LEVEL_SHIFT  8
 
-#define ATOM_S2_CRT1_DPMS_STATE         0x00010000L
-#define ATOM_S2_LCD1_DPMS_STATE	        0x00020000L
-#define ATOM_S2_TV1_DPMS_STATE          0x00040000L
-#define ATOM_S2_DFP1_DPMS_STATE         0x00080000L
-#define ATOM_S2_CRT2_DPMS_STATE         0x00100000L
-#define ATOM_S2_LCD2_DPMS_STATE         0x00200000L
-#define ATOM_S2_TV2_DPMS_STATE          0x00400000L
-#define ATOM_S2_DFP2_DPMS_STATE         0x00800000L
-#define ATOM_S2_CV_DPMS_STATE           0x01000000L
-#define ATOM_S2_DFP3_DPMS_STATE					0x02000000L
-#define ATOM_S2_DFP4_DPMS_STATE					0x04000000L
-#define ATOM_S2_DFP5_DPMS_STATE					0x08000000L
-
-#define ATOM_S2_DFP_DPM_STATE \
-	(ATOM_S2_DFP1_DPMS_STATE | ATOM_S2_DFP2_DPMS_STATE | \
-	 ATOM_S2_DFP3_DPMS_STATE | ATOM_S2_DFP4_DPMS_STATE | \
-	 ATOM_S2_DFP5_DPMS_STATE)
-
-#define ATOM_S2_DEVICE_DPMS_STATE \
-	(ATOM_S2_CRT1_DPMS_STATE + ATOM_S2_LCD1_DPMS_STATE + \
-	 ATOM_S2_TV1_DPMS_STATE + ATOM_S2_DFP_DPMS_STATE + \
-	 ATOM_S2_CRT2_DPMS_STATE + ATOM_S2_LCD2_DPMS_STATE + \
-	 ATOM_S2_TV2_DPMS_STATE + ATOM_S2_CV_DPMS_STATE)
-
 #define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASK       0x0C000000L
 #define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASK_SHIFT 26
 #define ATOM_S2_FORCEDLOWPWRMODE_STATE_CHANGE     0x10000000L
 
+#define ATOM_S2_DEVICE_DPMS_STATE       0x00010000L
 #define ATOM_S2_VRI_BRIGHT_ENABLE       0x20000000L
 
 #define ATOM_S2_DISPLAY_ROTATION_0_DEGREE     0x0
@@ -3131,21 +3969,11 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S2_DISPLAY_ROTATION_DEGREE_SHIFT 30
 #define ATOM_S2_DISPLAY_ROTATION_ANGLE_MASK   0xC0000000L
 
-/* Byte aligned definition for BIOS usage */
+
+//Byte aligned defintion for BIOS usage
 #define ATOM_S2_TV1_STANDARD_MASKb0     0x0F
 #define ATOM_S2_CURRENT_BL_LEVEL_MASKb1 0xFF
-#define ATOM_S2_CRT1_DPMS_STATEb2       0x01
-#define ATOM_S2_LCD1_DPMS_STATEb2       0x02
-#define ATOM_S2_TV1_DPMS_STATEb2        0x04
-#define ATOM_S2_DFP1_DPMS_STATEb2       0x08
-#define ATOM_S2_CRT2_DPMS_STATEb2       0x10
-#define ATOM_S2_LCD2_DPMS_STATEb2       0x20
-#define ATOM_S2_TV2_DPMS_STATEb2        0x40
-#define ATOM_S2_DFP2_DPMS_STATEb2       0x80
-#define ATOM_S2_CV_DPMS_STATEb3         0x01
-#define ATOM_S2_DFP3_DPMS_STATEb3				0x02
-#define ATOM_S2_DFP4_DPMS_STATEb3				0x04
-#define ATOM_S2_DFP5_DPMS_STATEb3				0x08
+#define ATOM_S2_DEVICE_DPMS_STATEb2     0x01
 
 #define ATOM_S2_DEVICE_DPMS_MASKw1      0x3FF
 #define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASKb3     0x0C
@@ -3153,21 +3981,22 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S2_VRI_BRIGHT_ENABLEb3     0x20
 #define ATOM_S2_ROTATION_STATE_MASKb3   0xC0
 
-/*  BIOS_3_SCRATCH Definition */
+
+// BIOS_3_SCRATCH Definition
 #define ATOM_S3_CRT1_ACTIVE             0x00000001L
 #define ATOM_S3_LCD1_ACTIVE             0x00000002L
 #define ATOM_S3_TV1_ACTIVE              0x00000004L
 #define ATOM_S3_DFP1_ACTIVE             0x00000008L
 #define ATOM_S3_CRT2_ACTIVE             0x00000010L
 #define ATOM_S3_LCD2_ACTIVE             0x00000020L
-#define ATOM_S3_TV2_ACTIVE              0x00000040L
+#define ATOM_S3_DFP6_ACTIVE             0x00000040L
 #define ATOM_S3_DFP2_ACTIVE             0x00000080L
 #define ATOM_S3_CV_ACTIVE               0x00000100L
 #define ATOM_S3_DFP3_ACTIVE							0x00000200L
 #define ATOM_S3_DFP4_ACTIVE							0x00000400L
 #define ATOM_S3_DFP5_ACTIVE							0x00000800L
 
-#define ATOM_S3_DEVICE_ACTIVE_MASK      0x000003FFL
+#define ATOM_S3_DEVICE_ACTIVE_MASK      0x00000FFFL
 
 #define ATOM_S3_LCD_FULLEXPANSION_ACTIVE         0x00001000L
 #define ATOM_S3_LCD_EXPANSION_ASPEC_RATIO_ACTIVE 0x00002000L
@@ -3178,7 +4007,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S3_DFP1_CRTC_ACTIVE        0x00080000L
 #define ATOM_S3_CRT2_CRTC_ACTIVE        0x00100000L
 #define ATOM_S3_LCD2_CRTC_ACTIVE        0x00200000L
-#define ATOM_S3_TV2_CRTC_ACTIVE         0x00400000L
+#define ATOM_S3_DFP6_CRTC_ACTIVE        0x00400000L
 #define ATOM_S3_DFP2_CRTC_ACTIVE        0x00800000L
 #define ATOM_S3_CV_CRTC_ACTIVE          0x01000000L
 #define ATOM_S3_DFP3_CRTC_ACTIVE				0x02000000L
@@ -3187,17 +4016,18 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 
 #define ATOM_S3_DEVICE_CRTC_ACTIVE_MASK 0x0FFF0000L
 #define ATOM_S3_ASIC_GUI_ENGINE_HUNG    0x20000000L
+//Below two definitions are not supported in pplib, but in the old powerplay in DAL
 #define ATOM_S3_ALLOW_FAST_PWR_SWITCH   0x40000000L
 #define ATOM_S3_RQST_GPU_USE_MIN_PWR    0x80000000L
 
-/* Byte aligned definition for BIOS usage */
+//Byte aligned defintion for BIOS usage
 #define ATOM_S3_CRT1_ACTIVEb0           0x01
 #define ATOM_S3_LCD1_ACTIVEb0           0x02
 #define ATOM_S3_TV1_ACTIVEb0            0x04
 #define ATOM_S3_DFP1_ACTIVEb0           0x08
 #define ATOM_S3_CRT2_ACTIVEb0           0x10
 #define ATOM_S3_LCD2_ACTIVEb0           0x20
-#define ATOM_S3_TV2_ACTIVEb0            0x40
+#define ATOM_S3_DFP6_ACTIVEb0           0x40
 #define ATOM_S3_DFP2_ACTIVEb0           0x80
 #define ATOM_S3_CV_ACTIVEb1             0x01
 #define ATOM_S3_DFP3_ACTIVEb1						0x02
@@ -3212,7 +4042,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S3_DFP1_CRTC_ACTIVEb2      0x08
 #define ATOM_S3_CRT2_CRTC_ACTIVEb2      0x10
 #define ATOM_S3_LCD2_CRTC_ACTIVEb2      0x20
-#define ATOM_S3_TV2_CRTC_ACTIVEb2       0x40
+#define ATOM_S3_DFP6_CRTC_ACTIVEb2      0x40
 #define ATOM_S3_DFP2_CRTC_ACTIVEb2      0x80
 #define ATOM_S3_CV_CRTC_ACTIVEb3        0x01
 #define ATOM_S3_DFP3_CRTC_ACTIVEb3			0x02
@@ -3221,35 +4051,31 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 
 #define ATOM_S3_ACTIVE_CRTC2w1          0xFFF
 
-#define ATOM_S3_ASIC_GUI_ENGINE_HUNGb3	0x20
-#define ATOM_S3_ALLOW_FAST_PWR_SWITCHb3 0x40
-#define ATOM_S3_RQST_GPU_USE_MIN_PWRb3  0x80
-
-/*  BIOS_4_SCRATCH Definition */
+// BIOS_4_SCRATCH Definition
 #define ATOM_S4_LCD1_PANEL_ID_MASK      0x000000FFL
 #define ATOM_S4_LCD1_REFRESH_MASK       0x0000FF00L
 #define ATOM_S4_LCD1_REFRESH_SHIFT      8
 
-/* Byte aligned definition for BIOS usage */
+//Byte aligned defintion for BIOS usage
 #define ATOM_S4_LCD1_PANEL_ID_MASKb0	  0x0FF
 #define ATOM_S4_LCD1_REFRESH_MASKb1		  ATOM_S4_LCD1_PANEL_ID_MASKb0
 #define ATOM_S4_VRAM_INFO_MASKb2        ATOM_S4_LCD1_PANEL_ID_MASKb0
 
-/*  BIOS_5_SCRATCH Definition, BIOS_5_SCRATCH is used by Firmware only !!!! */
+// BIOS_5_SCRATCH Definition, BIOS_5_SCRATCH is used by Firmware only !!!!
 #define ATOM_S5_DOS_REQ_CRT1b0          0x01
 #define ATOM_S5_DOS_REQ_LCD1b0          0x02
 #define ATOM_S5_DOS_REQ_TV1b0           0x04
 #define ATOM_S5_DOS_REQ_DFP1b0          0x08
 #define ATOM_S5_DOS_REQ_CRT2b0          0x10
 #define ATOM_S5_DOS_REQ_LCD2b0          0x20
-#define ATOM_S5_DOS_REQ_TV2b0           0x40
+#define ATOM_S5_DOS_REQ_DFP6b0          0x40
 #define ATOM_S5_DOS_REQ_DFP2b0          0x80
 #define ATOM_S5_DOS_REQ_CVb1            0x01
 #define ATOM_S5_DOS_REQ_DFP3b1					0x02
 #define ATOM_S5_DOS_REQ_DFP4b1					0x04
 #define ATOM_S5_DOS_REQ_DFP5b1					0x08
 
-#define ATOM_S5_DOS_REQ_DEVICEw0        0x03FF
+#define ATOM_S5_DOS_REQ_DEVICEw0        0x0FFF
 
 #define ATOM_S5_DOS_REQ_CRT1            0x0001
 #define ATOM_S5_DOS_REQ_LCD1            0x0002
@@ -3257,22 +4083,21 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S5_DOS_REQ_DFP1            0x0008
 #define ATOM_S5_DOS_REQ_CRT2            0x0010
 #define ATOM_S5_DOS_REQ_LCD2            0x0020
-#define ATOM_S5_DOS_REQ_TV2             0x0040
+#define ATOM_S5_DOS_REQ_DFP6            0x0040
 #define ATOM_S5_DOS_REQ_DFP2            0x0080
 #define ATOM_S5_DOS_REQ_CV              0x0100
-#define ATOM_S5_DOS_REQ_DFP3						0x0200
-#define ATOM_S5_DOS_REQ_DFP4						0x0400
-#define ATOM_S5_DOS_REQ_DFP5						0x0800
+#define ATOM_S5_DOS_REQ_DFP3            0x0200
+#define ATOM_S5_DOS_REQ_DFP4            0x0400
+#define ATOM_S5_DOS_REQ_DFP5            0x0800
 
 #define ATOM_S5_DOS_FORCE_CRT1b2        ATOM_S5_DOS_REQ_CRT1b0
 #define ATOM_S5_DOS_FORCE_TV1b2         ATOM_S5_DOS_REQ_TV1b0
 #define ATOM_S5_DOS_FORCE_CRT2b2        ATOM_S5_DOS_REQ_CRT2b0
 #define ATOM_S5_DOS_FORCE_CVb3          ATOM_S5_DOS_REQ_CVb1
-#define ATOM_S5_DOS_FORCE_DEVICEw1 \
-	(ATOM_S5_DOS_FORCE_CRT1b2 + ATOM_S5_DOS_FORCE_TV1b2 + \
-	 ATOM_S5_DOS_FORCE_CRT2b2 + (ATOM_S5_DOS_FORCE_CVb3 << 8))
+#define ATOM_S5_DOS_FORCE_DEVICEw1      (ATOM_S5_DOS_FORCE_CRT1b2+ATOM_S5_DOS_FORCE_TV1b2+ATOM_S5_DOS_FORCE_CRT2b2+\
+                                        (ATOM_S5_DOS_FORCE_CVb3<<8))
 
-/*  BIOS_6_SCRATCH Definition */
+// BIOS_6_SCRATCH Definition
 #define ATOM_S6_DEVICE_CHANGE           0x00000001L
 #define ATOM_S6_SCALER_CHANGE           0x00000002L
 #define ATOM_S6_LID_CHANGE              0x00000004L
@@ -3285,11 +4110,11 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S6_HW_I2C_BUSY_STATE       0x00000200L
 #define ATOM_S6_THERMAL_STATE_CHANGE    0x00000400L
 #define ATOM_S6_INTERRUPT_SET_BY_BIOS   0x00000800L
-#define ATOM_S6_REQ_LCD_EXPANSION_FULL         0x00001000L	/* Normal expansion Request bit for LCD */
-#define ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIO  0x00002000L	/* Aspect ratio expansion Request bit for LCD */
+#define ATOM_S6_REQ_LCD_EXPANSION_FULL         0x00001000L //Normal expansion Request bit for LCD
+#define ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIO  0x00002000L //Aspect ratio expansion Request bit for LCD
 
-#define ATOM_S6_DISPLAY_STATE_CHANGE    0x00004000L	/* This bit is recycled when ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE is set,previously it's SCL2_H_expansion */
-#define ATOM_S6_I2C_STATE_CHANGE        0x00008000L	/* This bit is recycled,when ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE is set,previously it's SCL2_V_expansion */
+#define ATOM_S6_DISPLAY_STATE_CHANGE    0x00004000L        //This bit is recycled when ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE is set,previously it's SCL2_H_expansion
+#define ATOM_S6_I2C_STATE_CHANGE        0x00008000L        //This bit is recycled,when ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE is set,previously it's SCL2_V_expansion
 
 #define ATOM_S6_ACC_REQ_CRT1            0x00010000L
 #define ATOM_S6_ACC_REQ_LCD1            0x00020000L
@@ -3297,7 +4122,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S6_ACC_REQ_DFP1            0x00080000L
 #define ATOM_S6_ACC_REQ_CRT2            0x00100000L
 #define ATOM_S6_ACC_REQ_LCD2            0x00200000L
-#define ATOM_S6_ACC_REQ_TV2             0x00400000L
+#define ATOM_S6_ACC_REQ_DFP6            0x00400000L
 #define ATOM_S6_ACC_REQ_DFP2            0x00800000L
 #define ATOM_S6_ACC_REQ_CV              0x01000000L
 #define ATOM_S6_ACC_REQ_DFP3						0x02000000L
@@ -3310,7 +4135,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S6_VRI_BRIGHTNESS_CHANGE       0x40000000L
 #define ATOM_S6_CONFIG_DISPLAY_CHANGE_MASK  0x80000000L
 
-/* Byte aligned definition for BIOS usage */
+//Byte aligned defintion for BIOS usage
 #define ATOM_S6_DEVICE_CHANGEb0         0x01
 #define ATOM_S6_SCALER_CHANGEb0         0x02
 #define ATOM_S6_LID_CHANGEb0            0x04
@@ -3320,11 +4145,11 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S6_LID_STATEb0             0x40
 #define ATOM_S6_DOCK_STATEb0            0x80
 #define ATOM_S6_CRITICAL_STATEb1        0x01
-#define ATOM_S6_HW_I2C_BUSY_STATEb1     0x02
+#define ATOM_S6_HW_I2C_BUSY_STATEb1     0x02  
 #define ATOM_S6_THERMAL_STATE_CHANGEb1  0x04
 #define ATOM_S6_INTERRUPT_SET_BY_BIOSb1 0x08
-#define ATOM_S6_REQ_LCD_EXPANSION_FULLb1        0x10
-#define ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIOb1 0x20
+#define ATOM_S6_REQ_LCD_EXPANSION_FULLb1        0x10    
+#define ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIOb1 0x20 
 
 #define ATOM_S6_ACC_REQ_CRT1b2          0x01
 #define ATOM_S6_ACC_REQ_LCD1b2          0x02
@@ -3332,12 +4157,12 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S6_ACC_REQ_DFP1b2          0x08
 #define ATOM_S6_ACC_REQ_CRT2b2          0x10
 #define ATOM_S6_ACC_REQ_LCD2b2          0x20
-#define ATOM_S6_ACC_REQ_TV2b2           0x40
+#define ATOM_S6_ACC_REQ_DFP6b2          0x40
 #define ATOM_S6_ACC_REQ_DFP2b2          0x80
 #define ATOM_S6_ACC_REQ_CVb3            0x01
-#define ATOM_S6_ACC_REQ_DFP3b3					0x02
-#define ATOM_S6_ACC_REQ_DFP4b3					0x04
-#define ATOM_S6_ACC_REQ_DFP5b3					0x08
+#define ATOM_S6_ACC_REQ_DFP3b3          0x02
+#define ATOM_S6_ACC_REQ_DFP4b3          0x04
+#define ATOM_S6_ACC_REQ_DFP5b3          0x08
 
 #define ATOM_S6_ACC_REQ_DEVICEw1        ATOM_S5_DOS_REQ_DEVICEw0
 #define ATOM_S6_SYSTEM_POWER_MODE_CHANGEb3 0x10
@@ -3366,7 +4191,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S6_VRI_BRIGHTNESS_CHANGE_SHIFT     30
 #define ATOM_S6_CONFIG_DISPLAY_CHANGE_SHIFT     31
 
-/*  BIOS_7_SCRATCH Definition, BIOS_7_SCRATCH is used by Firmware only !!!! */
+// BIOS_7_SCRATCH Definition, BIOS_7_SCRATCH is used by Firmware only !!!!
 #define ATOM_S7_DOS_MODE_TYPEb0             0x03
 #define ATOM_S7_DOS_MODE_VGAb0              0x00
 #define ATOM_S7_DOS_MODE_VESAb0             0x01
@@ -3378,220 +4203,194 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 
 #define ATOM_S7_DOS_8BIT_DAC_EN_SHIFT       8
 
-/*  BIOS_8_SCRATCH Definition */
+// BIOS_8_SCRATCH Definition
 #define ATOM_S8_I2C_CHANNEL_BUSY_MASK       0x00000FFFF
-#define ATOM_S8_I2C_HW_ENGINE_BUSY_MASK     0x0FFFF0000
+#define ATOM_S8_I2C_HW_ENGINE_BUSY_MASK     0x0FFFF0000   
 
 #define ATOM_S8_I2C_CHANNEL_BUSY_SHIFT      0
 #define ATOM_S8_I2C_ENGINE_BUSY_SHIFT       16
 
-/*  BIOS_9_SCRATCH Definition */
-#ifndef ATOM_S9_I2C_CHANNEL_COMPLETED_MASK
+// BIOS_9_SCRATCH Definition
+#ifndef ATOM_S9_I2C_CHANNEL_COMPLETED_MASK 
 #define ATOM_S9_I2C_CHANNEL_COMPLETED_MASK  0x0000FFFF
 #endif
-#ifndef ATOM_S9_I2C_CHANNEL_ABORTED_MASK
+#ifndef ATOM_S9_I2C_CHANNEL_ABORTED_MASK  
 #define ATOM_S9_I2C_CHANNEL_ABORTED_MASK    0xFFFF0000
 #endif
-#ifndef ATOM_S9_I2C_CHANNEL_COMPLETED_SHIFT
+#ifndef ATOM_S9_I2C_CHANNEL_COMPLETED_SHIFT 
 #define ATOM_S9_I2C_CHANNEL_COMPLETED_SHIFT 0
 #endif
-#ifndef ATOM_S9_I2C_CHANNEL_ABORTED_SHIFT
+#ifndef ATOM_S9_I2C_CHANNEL_ABORTED_SHIFT   
 #define ATOM_S9_I2C_CHANNEL_ABORTED_SHIFT   16
 #endif
 
+ 
 #define ATOM_FLAG_SET                         0x20
 #define ATOM_FLAG_CLEAR                       0
-#define CLEAR_ATOM_S6_ACC_MODE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_ACC_MODE_SHIFT | ATOM_FLAG_CLEAR)
-#define SET_ATOM_S6_DEVICE_CHANGE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_DEVICE_CHANGE_SHIFT | ATOM_FLAG_SET)
-#define SET_ATOM_S6_VRI_BRIGHTNESS_CHANGE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_VRI_BRIGHTNESS_CHANGE_SHIFT | ATOM_FLAG_SET)
-#define SET_ATOM_S6_SCALER_CHANGE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_SCALER_CHANGE_SHIFT | ATOM_FLAG_SET)
-#define SET_ATOM_S6_LID_CHANGE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_LID_CHANGE_SHIFT | ATOM_FLAG_SET)
+#define CLEAR_ATOM_S6_ACC_MODE                ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_ACC_MODE_SHIFT | ATOM_FLAG_CLEAR)
+#define SET_ATOM_S6_DEVICE_CHANGE             ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DEVICE_CHANGE_SHIFT | ATOM_FLAG_SET)
+#define SET_ATOM_S6_VRI_BRIGHTNESS_CHANGE     ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_VRI_BRIGHTNESS_CHANGE_SHIFT | ATOM_FLAG_SET)
+#define SET_ATOM_S6_SCALER_CHANGE             ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_SCALER_CHANGE_SHIFT | ATOM_FLAG_SET)
+#define SET_ATOM_S6_LID_CHANGE                ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_LID_CHANGE_SHIFT | ATOM_FLAG_SET)
 
-#define SET_ATOM_S6_LID_STATE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) |\
-	 ATOM_S6_LID_STATE_SHIFT | ATOM_FLAG_SET)
-#define CLEAR_ATOM_S6_LID_STATE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_LID_STATE_SHIFT | ATOM_FLAG_CLEAR)
+#define SET_ATOM_S6_LID_STATE                 ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_LID_STATE_SHIFT | ATOM_FLAG_SET)
+#define CLEAR_ATOM_S6_LID_STATE               ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_LID_STATE_SHIFT | ATOM_FLAG_CLEAR)
 
-#define SET_ATOM_S6_DOCK_CHANGE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8)| \
-	 ATOM_S6_DOCKING_CHANGE_SHIFT | ATOM_FLAG_SET)
-#define SET_ATOM_S6_DOCK_STATE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_DOCK_STATE_SHIFT | ATOM_FLAG_SET)
-#define CLEAR_ATOM_S6_DOCK_STATE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_DOCK_STATE_SHIFT | ATOM_FLAG_CLEAR)
+#define SET_ATOM_S6_DOCK_CHANGE			          ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DOCKING_CHANGE_SHIFT | ATOM_FLAG_SET)
+#define SET_ATOM_S6_DOCK_STATE                ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DOCK_STATE_SHIFT | ATOM_FLAG_SET)
+#define CLEAR_ATOM_S6_DOCK_STATE              ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DOCK_STATE_SHIFT | ATOM_FLAG_CLEAR)
 
-#define SET_ATOM_S6_THERMAL_STATE_CHANGE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_THERMAL_STATE_CHANGE_SHIFT | ATOM_FLAG_SET)
-#define SET_ATOM_S6_SYSTEM_POWER_MODE_CHANGE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_SYSTEM_POWER_MODE_CHANGE_SHIFT | ATOM_FLAG_SET)
-#define SET_ATOM_S6_INTERRUPT_SET_BY_BIOS \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_INTERRUPT_SET_BY_BIOS_SHIFT | ATOM_FLAG_SET)
+#define SET_ATOM_S6_THERMAL_STATE_CHANGE      ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_THERMAL_STATE_CHANGE_SHIFT | ATOM_FLAG_SET)
+#define SET_ATOM_S6_SYSTEM_POWER_MODE_CHANGE  ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_SYSTEM_POWER_MODE_CHANGE_SHIFT | ATOM_FLAG_SET)
+#define SET_ATOM_S6_INTERRUPT_SET_BY_BIOS     ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_INTERRUPT_SET_BY_BIOS_SHIFT | ATOM_FLAG_SET)
 
-#define SET_ATOM_S6_CRITICAL_STATE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_CRITICAL_STATE_SHIFT | ATOM_FLAG_SET)
-#define CLEAR_ATOM_S6_CRITICAL_STATE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_CRITICAL_STATE_SHIFT | ATOM_FLAG_CLEAR)
+#define SET_ATOM_S6_CRITICAL_STATE            ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_CRITICAL_STATE_SHIFT | ATOM_FLAG_SET)
+#define CLEAR_ATOM_S6_CRITICAL_STATE          ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_CRITICAL_STATE_SHIFT | ATOM_FLAG_CLEAR)
 
-#define SET_ATOM_S6_REQ_SCALER \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_REQ_SCALER_SHIFT | ATOM_FLAG_SET)
-#define CLEAR_ATOM_S6_REQ_SCALER \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_REQ_SCALER_SHIFT | ATOM_FLAG_CLEAR )
+#define SET_ATOM_S6_REQ_SCALER                ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_SHIFT | ATOM_FLAG_SET)  
+#define CLEAR_ATOM_S6_REQ_SCALER              ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_SHIFT | ATOM_FLAG_CLEAR )
 
-#define SET_ATOM_S6_REQ_SCALER_ARATIO \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_REQ_SCALER_ARATIO_SHIFT | ATOM_FLAG_SET )
-#define CLEAR_ATOM_S6_REQ_SCALER_ARATIO \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_REQ_SCALER_ARATIO_SHIFT | ATOM_FLAG_CLEAR )
+#define SET_ATOM_S6_REQ_SCALER_ARATIO         ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_ARATIO_SHIFT | ATOM_FLAG_SET )
+#define CLEAR_ATOM_S6_REQ_SCALER_ARATIO       ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_ARATIO_SHIFT | ATOM_FLAG_CLEAR )
 
-#define SET_ATOM_S6_I2C_STATE_CHANGE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_I2C_STATE_CHANGE_SHIFT | ATOM_FLAG_SET )
+#define SET_ATOM_S6_I2C_STATE_CHANGE          ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_I2C_STATE_CHANGE_SHIFT | ATOM_FLAG_SET )
 
-#define SET_ATOM_S6_DISPLAY_STATE_CHANGE \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_DISPLAY_STATE_CHANGE_SHIFT | ATOM_FLAG_SET )
+#define SET_ATOM_S6_DISPLAY_STATE_CHANGE      ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DISPLAY_STATE_CHANGE_SHIFT | ATOM_FLAG_SET )
 
-#define SET_ATOM_S6_DEVICE_RECONFIG \
-	((ATOM_ACC_CHANGE_INFO_DEF << 8) | \
-	 ATOM_S6_CONFIG_DISPLAY_CHANGE_SHIFT | ATOM_FLAG_SET)
-#define CLEAR_ATOM_S0_LCD1 \
-	((ATOM_DEVICE_CONNECT_INFO_DEF << 8 ) | \
-	 ATOM_S0_LCD1_SHIFT | ATOM_FLAG_CLEAR )
-#define SET_ATOM_S7_DOS_8BIT_DAC_EN \
-	((ATOM_DOS_MODE_INFO_DEF << 8) | \
-	 ATOM_S7_DOS_8BIT_DAC_EN_SHIFT | ATOM_FLAG_SET )
-#define CLEAR_ATOM_S7_DOS_8BIT_DAC_EN \
-	((ATOM_DOS_MODE_INFO_DEF << 8) | \
-	 ATOM_S7_DOS_8BIT_DAC_EN_SHIFT | ATOM_FLAG_CLEAR )
+#define SET_ATOM_S6_DEVICE_RECONFIG           ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_CONFIG_DISPLAY_CHANGE_SHIFT | ATOM_FLAG_SET)
+#define CLEAR_ATOM_S0_LCD1                    ((ATOM_DEVICE_CONNECT_INFO_DEF << 8 )|  ATOM_S0_LCD1_SHIFT | ATOM_FLAG_CLEAR )
+#define SET_ATOM_S7_DOS_8BIT_DAC_EN           ((ATOM_DOS_MODE_INFO_DEF << 8 )|ATOM_S7_DOS_8BIT_DAC_EN_SHIFT | ATOM_FLAG_SET )
+#define CLEAR_ATOM_S7_DOS_8BIT_DAC_EN         ((ATOM_DOS_MODE_INFO_DEF << 8 )|ATOM_S7_DOS_8BIT_DAC_EN_SHIFT | ATOM_FLAG_CLEAR )
 
-/****************************************************************************/
-/* Portion II: Definitinos only used in Driver */
+/****************************************************************************/	
+//Portion II: Definitinos only used in Driver
 /****************************************************************************/
 
-/*  Macros used by driver */
+// Macros used by driver
+#ifdef __cplusplus
+#define GetIndexIntoMasterTable(MasterOrData, FieldName) ((reinterpret_cast<char*>(&(static_cast<ATOM_MASTER_LIST_OF_##MasterOrData##_TABLES*>(0))->FieldName)-static_cast<char*>(0))/sizeof(USHORT))
 
-#define	GetIndexIntoMasterTable(MasterOrData, FieldName) (((char *)(&((ATOM_MASTER_LIST_OF_##MasterOrData##_TABLES *)0)->FieldName)-(char *)0)/sizeof(USHORT))
+#define GET_COMMAND_TABLE_COMMANDSET_REVISION(TABLE_HEADER_OFFSET) (((static_cast<ATOM_COMMON_TABLE_HEADER*>(TABLE_HEADER_OFFSET))->ucTableFormatRevision )&0x3F)
+#define GET_COMMAND_TABLE_PARAMETER_REVISION(TABLE_HEADER_OFFSET)  (((static_cast<ATOM_COMMON_TABLE_HEADER*>(TABLE_HEADER_OFFSET))->ucTableContentRevision)&0x3F)
+#else // not __cplusplus
+#define	GetIndexIntoMasterTable(MasterOrData, FieldName) (((char*)(&((ATOM_MASTER_LIST_OF_##MasterOrData##_TABLES*)0)->FieldName)-(char*)0)/sizeof(USHORT))
 
 #define GET_COMMAND_TABLE_COMMANDSET_REVISION(TABLE_HEADER_OFFSET) ((((ATOM_COMMON_TABLE_HEADER*)TABLE_HEADER_OFFSET)->ucTableFormatRevision)&0x3F)
 #define GET_COMMAND_TABLE_PARAMETER_REVISION(TABLE_HEADER_OFFSET)  ((((ATOM_COMMON_TABLE_HEADER*)TABLE_HEADER_OFFSET)->ucTableContentRevision)&0x3F)
+#endif // __cplusplus
 
 #define GET_DATA_TABLE_MAJOR_REVISION GET_COMMAND_TABLE_COMMANDSET_REVISION
 #define GET_DATA_TABLE_MINOR_REVISION GET_COMMAND_TABLE_PARAMETER_REVISION
 
-/****************************************************************************/
-/* Portion III: Definitinos only used in VBIOS */
+/****************************************************************************/	
+//Portion III: Definitinos only used in VBIOS
 /****************************************************************************/
 #define ATOM_DAC_SRC					0x80
 #define ATOM_SRC_DAC1					0
 #define ATOM_SRC_DAC2					0x80
 
-#ifdef	UEFI_BUILD
-#define	USHORT	UTEMP
-#endif
-
-typedef struct _MEMORY_PLLINIT_PARAMETERS {
-	ULONG ulTargetMemoryClock;	/* In 10Khz unit */
-	UCHAR ucAction;		/* not define yet */
-	UCHAR ucFbDiv_Hi;	/* Fbdiv Hi byte */
-	UCHAR ucFbDiv;		/* FB value */
-	UCHAR ucPostDiv;	/* Post div */
-} MEMORY_PLLINIT_PARAMETERS;
+typedef struct _MEMORY_PLLINIT_PARAMETERS
+{
+  ULONG ulTargetMemoryClock; //In 10Khz unit
+  UCHAR   ucAction;					 //not define yet
+  UCHAR   ucFbDiv_Hi;				 //Fbdiv Hi byte
+  UCHAR   ucFbDiv;					 //FB value
+  UCHAR   ucPostDiv;				 //Post div
+}MEMORY_PLLINIT_PARAMETERS;
 
 #define MEMORY_PLLINIT_PS_ALLOCATION  MEMORY_PLLINIT_PARAMETERS
 
-#define	GPIO_PIN_WRITE													0x01
+
+#define	GPIO_PIN_WRITE													0x01			
 #define	GPIO_PIN_READ														0x00
 
-typedef struct _GPIO_PIN_CONTROL_PARAMETERS {
-	UCHAR ucGPIO_ID;	/* return value, read from GPIO pins */
-	UCHAR ucGPIOBitShift;	/* define which bit in uGPIOBitVal need to be update */
-	UCHAR ucGPIOBitVal;	/* Set/Reset corresponding bit defined in ucGPIOBitMask */
-	UCHAR ucAction;		/* =GPIO_PIN_WRITE: Read; =GPIO_PIN_READ: Write */
-} GPIO_PIN_CONTROL_PARAMETERS;
+typedef struct  _GPIO_PIN_CONTROL_PARAMETERS
+{
+  UCHAR ucGPIO_ID;           //return value, read from GPIO pins
+  UCHAR ucGPIOBitShift;	     //define which bit in uGPIOBitVal need to be update 
+	UCHAR ucGPIOBitVal;		     //Set/Reset corresponding bit defined in ucGPIOBitMask
+  UCHAR ucAction;				     //=GPIO_PIN_WRITE: Read; =GPIO_PIN_READ: Write
+}GPIO_PIN_CONTROL_PARAMETERS;
 
-typedef struct _ENABLE_SCALER_PARAMETERS {
-	UCHAR ucScaler;		/*  ATOM_SCALER1, ATOM_SCALER2 */
-	UCHAR ucEnable;		/*  ATOM_SCALER_DISABLE or ATOM_SCALER_CENTER or ATOM_SCALER_EXPANSION */
-	UCHAR ucTVStandard;	/*  */
-	UCHAR ucPadding[1];
-} ENABLE_SCALER_PARAMETERS;
-#define ENABLE_SCALER_PS_ALLOCATION ENABLE_SCALER_PARAMETERS
+typedef struct _ENABLE_SCALER_PARAMETERS
+{
+  UCHAR ucScaler;            // ATOM_SCALER1, ATOM_SCALER2
+  UCHAR ucEnable;            // ATOM_SCALER_DISABLE or ATOM_SCALER_CENTER or ATOM_SCALER_EXPANSION
+  UCHAR ucTVStandard;        // 
+  UCHAR ucPadding[1];
+}ENABLE_SCALER_PARAMETERS; 
+#define ENABLE_SCALER_PS_ALLOCATION ENABLE_SCALER_PARAMETERS 
 
-/* ucEnable: */
+//ucEnable:
 #define SCALER_BYPASS_AUTO_CENTER_NO_REPLICATION    0
 #define SCALER_BYPASS_AUTO_CENTER_AUTO_REPLICATION  1
 #define SCALER_ENABLE_2TAP_ALPHA_MODE               2
 #define SCALER_ENABLE_MULTITAP_MODE                 3
 
-typedef struct _ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS {
-	ULONG usHWIconHorzVertPosn;	/*  Hardware Icon Vertical position */
-	UCHAR ucHWIconVertOffset;	/*  Hardware Icon Vertical offset */
-	UCHAR ucHWIconHorzOffset;	/*  Hardware Icon Horizontal offset */
-	UCHAR ucSelection;	/*  ATOM_CURSOR1 or ATOM_ICON1 or ATOM_CURSOR2 or ATOM_ICON2 */
-	UCHAR ucEnable;		/*  ATOM_ENABLE or ATOM_DISABLE */
-} ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS;
+typedef struct _ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS
+{
+  ULONG  usHWIconHorzVertPosn;        // Hardware Icon Vertical position
+  UCHAR  ucHWIconVertOffset;          // Hardware Icon Vertical offset
+  UCHAR  ucHWIconHorzOffset;          // Hardware Icon Horizontal offset
+  UCHAR  ucSelection;                 // ATOM_CURSOR1 or ATOM_ICON1 or ATOM_CURSOR2 or ATOM_ICON2
+  UCHAR  ucEnable;                    // ATOM_ENABLE or ATOM_DISABLE
+}ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS;
 
-typedef struct _ENABLE_HARDWARE_ICON_CURSOR_PS_ALLOCATION {
-	ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS sEnableIcon;
-	ENABLE_CRTC_PARAMETERS sReserved;
-} ENABLE_HARDWARE_ICON_CURSOR_PS_ALLOCATION;
+typedef struct _ENABLE_HARDWARE_ICON_CURSOR_PS_ALLOCATION
+{
+  ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS  sEnableIcon;
+  ENABLE_CRTC_PARAMETERS                  sReserved;  
+}ENABLE_HARDWARE_ICON_CURSOR_PS_ALLOCATION;
 
-typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS {
-	USHORT usHight;		/*  Image Hight */
-	USHORT usWidth;		/*  Image Width */
-	UCHAR ucSurface;	/*  Surface 1 or 2 */
-	UCHAR ucPadding[3];
-} ENABLE_GRAPH_SURFACE_PARAMETERS;
+typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS
+{
+  USHORT usHight;                     // Image Hight
+  USHORT usWidth;                     // Image Width
+  UCHAR  ucSurface;                   // Surface 1 or 2	
+  UCHAR  ucPadding[3];
+}ENABLE_GRAPH_SURFACE_PARAMETERS;
 
-typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS_V1_2 {
-	USHORT usHight;		/*  Image Hight */
-	USHORT usWidth;		/*  Image Width */
-	UCHAR ucSurface;	/*  Surface 1 or 2 */
-	UCHAR ucEnable;		/*  ATOM_ENABLE or ATOM_DISABLE */
-	UCHAR ucPadding[2];
-} ENABLE_GRAPH_SURFACE_PARAMETERS_V1_2;
+typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS_V1_2
+{
+  USHORT usHight;                     // Image Hight
+  USHORT usWidth;                     // Image Width
+  UCHAR  ucSurface;                   // Surface 1 or 2
+  UCHAR  ucEnable;                    // ATOM_ENABLE or ATOM_DISABLE
+  UCHAR  ucPadding[2];
+}ENABLE_GRAPH_SURFACE_PARAMETERS_V1_2;
 
-typedef struct _ENABLE_GRAPH_SURFACE_PS_ALLOCATION {
-	ENABLE_GRAPH_SURFACE_PARAMETERS sSetSurface;
-	ENABLE_YUV_PS_ALLOCATION sReserved;	/*  Don't set this one */
-} ENABLE_GRAPH_SURFACE_PS_ALLOCATION;
+typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS_V1_3
+{
+  USHORT usHight;                     // Image Hight
+  USHORT usWidth;                     // Image Width
+  UCHAR  ucSurface;                   // Surface 1 or 2
+  UCHAR  ucEnable;                    // ATOM_ENABLE or ATOM_DISABLE
+  USHORT usDeviceId;                  // Active Device Id for this surface. If no device, set to 0. 
+}ENABLE_GRAPH_SURFACE_PARAMETERS_V1_3;
 
-typedef struct _MEMORY_CLEAN_UP_PARAMETERS {
-	USHORT usMemoryStart;	/* in 8Kb boundry, offset from memory base address */
-	USHORT usMemorySize;	/* 8Kb blocks aligned */
-} MEMORY_CLEAN_UP_PARAMETERS;
+typedef struct _ENABLE_GRAPH_SURFACE_PS_ALLOCATION
+{
+  ENABLE_GRAPH_SURFACE_PARAMETERS sSetSurface;          
+  ENABLE_YUV_PS_ALLOCATION        sReserved; // Don't set this one
+}ENABLE_GRAPH_SURFACE_PS_ALLOCATION;
+
+typedef struct _MEMORY_CLEAN_UP_PARAMETERS
+{
+  USHORT  usMemoryStart;                //in 8Kb boundry, offset from memory base address
+  USHORT  usMemorySize;                 //8Kb blocks aligned
+}MEMORY_CLEAN_UP_PARAMETERS;
 #define MEMORY_CLEAN_UP_PS_ALLOCATION MEMORY_CLEAN_UP_PARAMETERS
 
-typedef struct _GET_DISPLAY_SURFACE_SIZE_PARAMETERS {
-	USHORT usX_Size;	/* When use as input parameter, usX_Size indicates which CRTC */
-	USHORT usY_Size;
-} GET_DISPLAY_SURFACE_SIZE_PARAMETERS;
+typedef struct  _GET_DISPLAY_SURFACE_SIZE_PARAMETERS
+{
+  USHORT  usX_Size;                     //When use as input parameter, usX_Size indicates which CRTC                 
+  USHORT  usY_Size;
+}GET_DISPLAY_SURFACE_SIZE_PARAMETERS; 
 
-typedef struct _INDIRECT_IO_ACCESS {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	UCHAR IOAccessSequence[256];
+typedef struct _INDIRECT_IO_ACCESS
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  UCHAR                    IOAccessSequence[256];
 } INDIRECT_IO_ACCESS;
 
 #define INDIRECT_READ              0x00
@@ -3615,93 +4414,108 @@ typedef struct _INDIRECT_IO_ACCESS {
 #define INDIRECT_IO_NBMISC_READ    INDIRECT_IO_NBMISC | INDIRECT_READ
 #define INDIRECT_IO_NBMISC_WRITE   INDIRECT_IO_NBMISC | INDIRECT_WRITE
 
-typedef struct _ATOM_OEM_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ATOM_I2C_ID_CONFIG_ACCESS sucI2cId;
-} ATOM_OEM_INFO;
+typedef struct _ATOM_OEM_INFO
+{ 
+  ATOM_COMMON_TABLE_HEADER	sHeader;
+  ATOM_I2C_ID_CONFIG_ACCESS sucI2cId;
+}ATOM_OEM_INFO;
 
-typedef struct _ATOM_TV_MODE {
-	UCHAR ucVMode_Num;	/* Video mode number */
-	UCHAR ucTV_Mode_Num;	/* Internal TV mode number */
-} ATOM_TV_MODE;
+typedef struct _ATOM_TV_MODE
+{
+   UCHAR	ucVMode_Num;			  //Video mode number
+   UCHAR	ucTV_Mode_Num;			//Internal TV mode number
+}ATOM_TV_MODE;
 
-typedef struct _ATOM_BIOS_INT_TVSTD_MODE {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	USHORT usTV_Mode_LUT_Offset;	/*  Pointer to standard to internal number conversion table */
-	USHORT usTV_FIFO_Offset;	/*  Pointer to FIFO entry table */
-	USHORT usNTSC_Tbl_Offset;	/*  Pointer to SDTV_Mode_NTSC table */
-	USHORT usPAL_Tbl_Offset;	/*  Pointer to SDTV_Mode_PAL table */
-	USHORT usCV_Tbl_Offset;	/*  Pointer to SDTV_Mode_PAL table */
-} ATOM_BIOS_INT_TVSTD_MODE;
+typedef struct _ATOM_BIOS_INT_TVSTD_MODE
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+   USHORT	usTV_Mode_LUT_Offset;	// Pointer to standard to internal number conversion table
+   USHORT	usTV_FIFO_Offset;		  // Pointer to FIFO entry table
+   USHORT	usNTSC_Tbl_Offset;		// Pointer to SDTV_Mode_NTSC table
+   USHORT	usPAL_Tbl_Offset;		  // Pointer to SDTV_Mode_PAL table 
+   USHORT	usCV_Tbl_Offset;		  // Pointer to SDTV_Mode_PAL table 
+}ATOM_BIOS_INT_TVSTD_MODE;
 
-typedef struct _ATOM_TV_MODE_SCALER_PTR {
-	USHORT ucFilter0_Offset;	/* Pointer to filter format 0 coefficients */
-	USHORT usFilter1_Offset;	/* Pointer to filter format 0 coefficients */
-	UCHAR ucTV_Mode_Num;
-} ATOM_TV_MODE_SCALER_PTR;
 
-typedef struct _ATOM_STANDARD_VESA_TIMING {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ATOM_DTD_FORMAT aModeTimings[16];	/*  16 is not the real array number, just for initial allocation */
-} ATOM_STANDARD_VESA_TIMING;
+typedef struct _ATOM_TV_MODE_SCALER_PTR
+{
+   USHORT	ucFilter0_Offset;		//Pointer to filter format 0 coefficients
+   USHORT	usFilter1_Offset;		//Pointer to filter format 0 coefficients
+   UCHAR	ucTV_Mode_Num;
+}ATOM_TV_MODE_SCALER_PTR;
 
-typedef struct _ATOM_STD_FORMAT {
-	USHORT usSTD_HDisp;
-	USHORT usSTD_VDisp;
-	USHORT usSTD_RefreshRate;
-	USHORT usReserved;
-} ATOM_STD_FORMAT;
+typedef struct _ATOM_STANDARD_VESA_TIMING
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  ATOM_DTD_FORMAT 				 aModeTimings[16];      // 16 is not the real array number, just for initial allocation
+}ATOM_STANDARD_VESA_TIMING;
 
-typedef struct _ATOM_VESA_TO_EXTENDED_MODE {
-	USHORT usVESA_ModeNumber;
-	USHORT usExtendedModeNumber;
-} ATOM_VESA_TO_EXTENDED_MODE;
 
-typedef struct _ATOM_VESA_TO_INTENAL_MODE_LUT {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	ATOM_VESA_TO_EXTENDED_MODE asVESA_ToExtendedModeInfo[76];
-} ATOM_VESA_TO_INTENAL_MODE_LUT;
+typedef struct _ATOM_STD_FORMAT
+{ 
+  USHORT    usSTD_HDisp;
+  USHORT    usSTD_VDisp;
+  USHORT    usSTD_RefreshRate;
+  USHORT    usReserved;
+}ATOM_STD_FORMAT;
+
+typedef struct _ATOM_VESA_TO_EXTENDED_MODE
+{
+  USHORT  usVESA_ModeNumber;
+  USHORT  usExtendedModeNumber;
+}ATOM_VESA_TO_EXTENDED_MODE;
+
+typedef struct _ATOM_VESA_TO_INTENAL_MODE_LUT
+{ 
+  ATOM_COMMON_TABLE_HEADER   sHeader;  
+  ATOM_VESA_TO_EXTENDED_MODE asVESA_ToExtendedModeInfo[76];
+}ATOM_VESA_TO_INTENAL_MODE_LUT;
 
 /*************** ATOM Memory Related Data Structure ***********************/
-typedef struct _ATOM_MEMORY_VENDOR_BLOCK {
-	UCHAR ucMemoryType;
-	UCHAR ucMemoryVendor;
-	UCHAR ucAdjMCId;
-	UCHAR ucDynClkId;
-	ULONG ulDllResetClkRange;
-} ATOM_MEMORY_VENDOR_BLOCK;
+typedef struct _ATOM_MEMORY_VENDOR_BLOCK{
+	UCHAR												ucMemoryType;
+	UCHAR												ucMemoryVendor;
+	UCHAR												ucAdjMCId;
+	UCHAR												ucDynClkId;
+	ULONG												ulDllResetClkRange;
+}ATOM_MEMORY_VENDOR_BLOCK;
 
-typedef struct _ATOM_MEMORY_SETTING_ID_CONFIG {
+
+typedef struct _ATOM_MEMORY_SETTING_ID_CONFIG{
 #if ATOM_BIG_ENDIAN
-	ULONG ucMemBlkId:8;
-	ULONG ulMemClockRange:24;
+	ULONG												ucMemBlkId:8;
+	ULONG												ulMemClockRange:24;
 #else
-	ULONG ulMemClockRange:24;
-	ULONG ucMemBlkId:8;
+	ULONG												ulMemClockRange:24;
+	ULONG												ucMemBlkId:8;
 #endif
-} ATOM_MEMORY_SETTING_ID_CONFIG;
+}ATOM_MEMORY_SETTING_ID_CONFIG;
 
-typedef union _ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS {
-	ATOM_MEMORY_SETTING_ID_CONFIG slAccess;
-	ULONG ulAccess;
-} ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS;
+typedef union _ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS
+{
+  ATOM_MEMORY_SETTING_ID_CONFIG slAccess;
+  ULONG                         ulAccess;
+}ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS;
 
-typedef struct _ATOM_MEMORY_SETTING_DATA_BLOCK {
-	ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS ulMemoryID;
-	ULONG aulMemData[1];
-} ATOM_MEMORY_SETTING_DATA_BLOCK;
 
-typedef struct _ATOM_INIT_REG_INDEX_FORMAT {
-	USHORT usRegIndex;	/*  MC register index */
-	UCHAR ucPreRegDataLength;	/*  offset in ATOM_INIT_REG_DATA_BLOCK.saRegDataBuf */
-} ATOM_INIT_REG_INDEX_FORMAT;
+typedef struct _ATOM_MEMORY_SETTING_DATA_BLOCK{
+	ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS			ulMemoryID;
+	ULONG															        aulMemData[1];
+}ATOM_MEMORY_SETTING_DATA_BLOCK;
 
-typedef struct _ATOM_INIT_REG_BLOCK {
-	USHORT usRegIndexTblSize;	/* size of asRegIndexBuf */
-	USHORT usRegDataBlkSize;	/* size of ATOM_MEMORY_SETTING_DATA_BLOCK */
-	ATOM_INIT_REG_INDEX_FORMAT asRegIndexBuf[1];
-	ATOM_MEMORY_SETTING_DATA_BLOCK asRegDataBuf[1];
-} ATOM_INIT_REG_BLOCK;
+
+typedef struct _ATOM_INIT_REG_INDEX_FORMAT{
+	 USHORT											usRegIndex;                                     // MC register index
+	 UCHAR											ucPreRegDataLength;                             // offset in ATOM_INIT_REG_DATA_BLOCK.saRegDataBuf
+}ATOM_INIT_REG_INDEX_FORMAT;
+
+
+typedef struct _ATOM_INIT_REG_BLOCK{
+	USHORT													usRegIndexTblSize;													//size of asRegIndexBuf
+	USHORT													usRegDataBlkSize;														//size of ATOM_MEMORY_SETTING_DATA_BLOCK
+	ATOM_INIT_REG_INDEX_FORMAT			asRegIndexBuf[1];
+	ATOM_MEMORY_SETTING_DATA_BLOCK	asRegDataBuf[1];
+}ATOM_INIT_REG_BLOCK;
 
 #define END_OF_REG_INDEX_BLOCK  0x0ffff
 #define END_OF_REG_DATA_BLOCK   0x00000000
@@ -3716,16 +4530,19 @@ typedef struct _ATOM_INIT_REG_BLOCK {
 #define INDEX_ACCESS_RANGE_END		    (INDEX_ACCESS_RANGE_BEGIN + 1)
 #define VALUE_INDEX_ACCESS_SINGLE	    (INDEX_ACCESS_RANGE_END + 1)
 
-typedef struct _ATOM_MC_INIT_PARAM_TABLE {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	USHORT usAdjustARB_SEQDataOffset;
-	USHORT usMCInitMemTypeTblOffset;
-	USHORT usMCInitCommonTblOffset;
-	USHORT usMCInitPowerDownTblOffset;
-	ULONG ulARB_SEQDataBuf[32];
-	ATOM_INIT_REG_BLOCK asMCInitMemType;
-	ATOM_INIT_REG_BLOCK asMCInitCommon;
-} ATOM_MC_INIT_PARAM_TABLE;
+
+typedef struct _ATOM_MC_INIT_PARAM_TABLE
+{ 
+  ATOM_COMMON_TABLE_HEADER		sHeader;
+  USHORT											usAdjustARB_SEQDataOffset;
+  USHORT											usMCInitMemTypeTblOffset;
+  USHORT											usMCInitCommonTblOffset;
+  USHORT											usMCInitPowerDownTblOffset;
+	ULONG												ulARB_SEQDataBuf[32];
+	ATOM_INIT_REG_BLOCK					asMCInitMemType;
+	ATOM_INIT_REG_BLOCK					asMCInitCommon;
+}ATOM_MC_INIT_PARAM_TABLE;
+
 
 #define _4Mx16              0x2
 #define _4Mx32              0x3
@@ -3751,221 +4568,272 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE
 
 #define QIMONDA             INFINEON
 #define PROMOS              MOSEL
+#define KRETON              INFINEON
 
-/* ///////////Support for GDDR5 MC uCode to reside in upper 64K of ROM///////////// */
+/////////////Support for GDDR5 MC uCode to reside in upper 64K of ROM/////////////
 
 #define UCODE_ROM_START_ADDRESS		0x1c000
-#define	UCODE_SIGNATURE			0x4375434d	/*  'MCuC' - MC uCode */
+#define	UCODE_SIGNATURE			0x4375434d // 'MCuC' - MC uCode
 
-/* uCode block header for reference */
+//uCode block header for reference
 
-typedef struct _MCuCodeHeader {
-	ULONG ulSignature;
-	UCHAR ucRevision;
-	UCHAR ucChecksum;
-	UCHAR ucReserved1;
-	UCHAR ucReserved2;
-	USHORT usParametersLength;
-	USHORT usUCodeLength;
-	USHORT usReserved1;
-	USHORT usReserved2;
+typedef struct _MCuCodeHeader
+{
+  ULONG  ulSignature;
+  UCHAR  ucRevision;
+  UCHAR  ucChecksum;
+  UCHAR  ucReserved1;
+  UCHAR  ucReserved2;
+  USHORT usParametersLength;
+  USHORT usUCodeLength;
+  USHORT usReserved1;
+  USHORT usReserved2;
 } MCuCodeHeader;
 
-/* //////////////////////////////////////////////////////////////////////////////// */
+//////////////////////////////////////////////////////////////////////////////////
 
 #define ATOM_MAX_NUMBER_OF_VRAM_MODULE	16
 
 #define ATOM_VRAM_MODULE_MEMORY_VENDOR_ID_MASK	0xF
-typedef struct _ATOM_VRAM_MODULE_V1 {
-	ULONG ulReserved;
-	USHORT usEMRSValue;
-	USHORT usMRSValue;
-	USHORT usReserved;
-	UCHAR ucExtMemoryID;	/*  An external indicator (by hardcode, callback or pin) to tell what is the current memory module */
-	UCHAR ucMemoryType;	/*  [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] reserved; */
-	UCHAR ucMemoryVenderID;	/*  Predefined,never change across designs or memory type/vender */
-	UCHAR ucMemoryDeviceCfg;	/*  [7:4]=0x0:4M;=0x1:8M;=0x2:16M;0x3:32M....[3:0]=0x0:x4;=0x1:x8;=0x2:x16;=0x3:x32... */
-	UCHAR ucRow;		/*  Number of Row,in power of 2; */
-	UCHAR ucColumn;		/*  Number of Column,in power of 2; */
-	UCHAR ucBank;		/*  Nunber of Bank; */
-	UCHAR ucRank;		/*  Number of Rank, in power of 2 */
-	UCHAR ucChannelNum;	/*  Number of channel; */
-	UCHAR ucChannelConfig;	/*  [3:0]=Indication of what channel combination;[4:7]=Channel bit width, in number of 2 */
-	UCHAR ucDefaultMVDDQ_ID;	/*  Default MVDDQ setting for this memory block, ID linking to MVDDQ info table to find real set-up data; */
-	UCHAR ucDefaultMVDDC_ID;	/*  Default MVDDC setting for this memory block, ID linking to MVDDC info table to find real set-up data; */
-	UCHAR ucReserved[2];
-} ATOM_VRAM_MODULE_V1;
+typedef struct _ATOM_VRAM_MODULE_V1
+{
+  ULONG                      ulReserved;
+  USHORT                     usEMRSValue;  
+  USHORT                     usMRSValue;
+  USHORT                     usReserved;
+  UCHAR                      ucExtMemoryID;     // An external indicator (by hardcode, callback or pin) to tell what is the current memory module
+  UCHAR                      ucMemoryType;      // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] reserved;
+  UCHAR                      ucMemoryVenderID;  // Predefined,never change across designs or memory type/vender 
+  UCHAR                      ucMemoryDeviceCfg; // [7:4]=0x0:4M;=0x1:8M;=0x2:16M;0x3:32M....[3:0]=0x0:x4;=0x1:x8;=0x2:x16;=0x3:x32...
+  UCHAR                      ucRow;             // Number of Row,in power of 2;
+  UCHAR                      ucColumn;          // Number of Column,in power of 2;
+  UCHAR                      ucBank;            // Nunber of Bank;
+  UCHAR                      ucRank;            // Number of Rank, in power of 2
+  UCHAR                      ucChannelNum;      // Number of channel;
+  UCHAR                      ucChannelConfig;   // [3:0]=Indication of what channel combination;[4:7]=Channel bit width, in number of 2
+  UCHAR                      ucDefaultMVDDQ_ID; // Default MVDDQ setting for this memory block, ID linking to MVDDQ info table to find real set-up data;
+  UCHAR                      ucDefaultMVDDC_ID; // Default MVDDC setting for this memory block, ID linking to MVDDC info table to find real set-up data;
+  UCHAR                      ucReserved[2];
+}ATOM_VRAM_MODULE_V1;
 
-typedef struct _ATOM_VRAM_MODULE_V2 {
-	ULONG ulReserved;
-	ULONG ulFlags;		/*  To enable/disable functionalities based on memory type */
-	ULONG ulEngineClock;	/*  Override of default engine clock for particular memory type */
-	ULONG ulMemoryClock;	/*  Override of default memory clock for particular memory type */
-	USHORT usEMRS2Value;	/*  EMRS2 Value is used for GDDR2 and GDDR4 memory type */
-	USHORT usEMRS3Value;	/*  EMRS3 Value is used for GDDR2 and GDDR4 memory type */
-	USHORT usEMRSValue;
-	USHORT usMRSValue;
-	USHORT usReserved;
-	UCHAR ucExtMemoryID;	/*  An external indicator (by hardcode, callback or pin) to tell what is the current memory module */
-	UCHAR ucMemoryType;	/*  [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] - must not be used for now; */
-	UCHAR ucMemoryVenderID;	/*  Predefined,never change across designs or memory type/vender. If not predefined, vendor detection table gets executed */
-	UCHAR ucMemoryDeviceCfg;	/*  [7:4]=0x0:4M;=0x1:8M;=0x2:16M;0x3:32M....[3:0]=0x0:x4;=0x1:x8;=0x2:x16;=0x3:x32... */
-	UCHAR ucRow;		/*  Number of Row,in power of 2; */
-	UCHAR ucColumn;		/*  Number of Column,in power of 2; */
-	UCHAR ucBank;		/*  Nunber of Bank; */
-	UCHAR ucRank;		/*  Number of Rank, in power of 2 */
-	UCHAR ucChannelNum;	/*  Number of channel; */
-	UCHAR ucChannelConfig;	/*  [3:0]=Indication of what channel combination;[4:7]=Channel bit width, in number of 2 */
-	UCHAR ucDefaultMVDDQ_ID;	/*  Default MVDDQ setting for this memory block, ID linking to MVDDQ info table to find real set-up data; */
-	UCHAR ucDefaultMVDDC_ID;	/*  Default MVDDC setting for this memory block, ID linking to MVDDC info table to find real set-up data; */
-	UCHAR ucRefreshRateFactor;
-	UCHAR ucReserved[3];
-} ATOM_VRAM_MODULE_V2;
 
-typedef struct _ATOM_MEMORY_TIMING_FORMAT {
-	ULONG ulClkRange;	/*  memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing */
-	union {
-		USHORT usMRS;	/*  mode register */
-		USHORT usDDR3_MR0;
-	};
-	union {
-		USHORT usEMRS;	/*  extended mode register */
-		USHORT usDDR3_MR1;
-	};
-	UCHAR ucCL;		/*  CAS latency */
-	UCHAR ucWL;		/*  WRITE Latency */
-	UCHAR uctRAS;		/*  tRAS */
-	UCHAR uctRC;		/*  tRC */
-	UCHAR uctRFC;		/*  tRFC */
-	UCHAR uctRCDR;		/*  tRCDR */
-	UCHAR uctRCDW;		/*  tRCDW */
-	UCHAR uctRP;		/*  tRP */
-	UCHAR uctRRD;		/*  tRRD */
-	UCHAR uctWR;		/*  tWR */
-	UCHAR uctWTR;		/*  tWTR */
-	UCHAR uctPDIX;		/*  tPDIX */
-	UCHAR uctFAW;		/*  tFAW */
-	UCHAR uctAOND;		/*  tAOND */
-	union {
-		struct {
-			UCHAR ucflag;	/*  flag to control memory timing calculation. bit0= control EMRS2 Infineon */
-			UCHAR ucReserved;
-		};
-		USHORT usDDR3_MR2;
-	};
-} ATOM_MEMORY_TIMING_FORMAT;
+typedef struct _ATOM_VRAM_MODULE_V2
+{
+  ULONG                      ulReserved;
+  ULONG                      ulFlags;     			// To enable/disable functionalities based on memory type
+  ULONG                      ulEngineClock;     // Override of default engine clock for particular memory type
+  ULONG                      ulMemoryClock;     // Override of default memory clock for particular memory type
+  USHORT                     usEMRS2Value;      // EMRS2 Value is used for GDDR2 and GDDR4 memory type
+  USHORT                     usEMRS3Value;      // EMRS3 Value is used for GDDR2 and GDDR4 memory type
+  USHORT                     usEMRSValue;  
+  USHORT                     usMRSValue;
+  USHORT                     usReserved;
+  UCHAR                      ucExtMemoryID;     // An external indicator (by hardcode, callback or pin) to tell what is the current memory module
+  UCHAR                      ucMemoryType;      // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] - must not be used for now;
+  UCHAR                      ucMemoryVenderID;  // Predefined,never change across designs or memory type/vender. If not predefined, vendor detection table gets executed
+  UCHAR                      ucMemoryDeviceCfg; // [7:4]=0x0:4M;=0x1:8M;=0x2:16M;0x3:32M....[3:0]=0x0:x4;=0x1:x8;=0x2:x16;=0x3:x32...
+  UCHAR                      ucRow;             // Number of Row,in power of 2;
+  UCHAR                      ucColumn;          // Number of Column,in power of 2;
+  UCHAR                      ucBank;            // Nunber of Bank;
+  UCHAR                      ucRank;            // Number of Rank, in power of 2
+  UCHAR                      ucChannelNum;      // Number of channel;
+  UCHAR                      ucChannelConfig;   // [3:0]=Indication of what channel combination;[4:7]=Channel bit width, in number of 2
+  UCHAR                      ucDefaultMVDDQ_ID; // Default MVDDQ setting for this memory block, ID linking to MVDDQ info table to find real set-up data;
+  UCHAR                      ucDefaultMVDDC_ID; // Default MVDDC setting for this memory block, ID linking to MVDDC info table to find real set-up data;
+  UCHAR                      ucRefreshRateFactor;
+  UCHAR                      ucReserved[3];
+}ATOM_VRAM_MODULE_V2;
 
-typedef struct _ATOM_MEMORY_TIMING_FORMAT_V1 {
-	ULONG ulClkRange;	/*  memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing */
-	USHORT usMRS;		/*  mode register */
-	USHORT usEMRS;		/*  extended mode register */
-	UCHAR ucCL;		/*  CAS latency */
-	UCHAR ucWL;		/*  WRITE Latency */
-	UCHAR uctRAS;		/*  tRAS */
-	UCHAR uctRC;		/*  tRC */
-	UCHAR uctRFC;		/*  tRFC */
-	UCHAR uctRCDR;		/*  tRCDR */
-	UCHAR uctRCDW;		/*  tRCDW */
-	UCHAR uctRP;		/*  tRP */
-	UCHAR uctRRD;		/*  tRRD */
-	UCHAR uctWR;		/*  tWR */
-	UCHAR uctWTR;		/*  tWTR */
-	UCHAR uctPDIX;		/*  tPDIX */
-	UCHAR uctFAW;		/*  tFAW */
-	UCHAR uctAOND;		/*  tAOND */
-	UCHAR ucflag;		/*  flag to control memory timing calculation. bit0= control EMRS2 Infineon */
-/* ///////////////////////GDDR parameters/////////////////////////////////// */
-	UCHAR uctCCDL;		/*  */
-	UCHAR uctCRCRL;		/*  */
-	UCHAR uctCRCWL;		/*  */
-	UCHAR uctCKE;		/*  */
-	UCHAR uctCKRSE;		/*  */
-	UCHAR uctCKRSX;		/*  */
-	UCHAR uctFAW32;		/*  */
-	UCHAR ucReserved1;	/*  */
-	UCHAR ucReserved2;	/*  */
-	UCHAR ucTerminator;
-} ATOM_MEMORY_TIMING_FORMAT_V1;
 
-typedef struct _ATOM_MEMORY_FORMAT {
-	ULONG ulDllDisClock;	/*  memory DLL will be disable when target memory clock is below this clock */
-	union {
-		USHORT usEMRS2Value;	/*  EMRS2 Value is used for GDDR2 and GDDR4 memory type */
-		USHORT usDDR3_Reserved;	/*  Not used for DDR3 memory */
-	};
-	union {
-		USHORT usEMRS3Value;	/*  EMRS3 Value is used for GDDR2 and GDDR4 memory type */
-		USHORT usDDR3_MR3;	/*  Used for DDR3 memory */
-	};
-	UCHAR ucMemoryType;	/*  [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] - must not be used for now; */
-	UCHAR ucMemoryVenderID;	/*  Predefined,never change across designs or memory type/vender. If not predefined, vendor detection table gets executed */
-	UCHAR ucRow;		/*  Number of Row,in power of 2; */
-	UCHAR ucColumn;		/*  Number of Column,in power of 2; */
-	UCHAR ucBank;		/*  Nunber of Bank; */
-	UCHAR ucRank;		/*  Number of Rank, in power of 2 */
-	UCHAR ucBurstSize;	/*  burst size, 0= burst size=4  1= burst size=8 */
-	UCHAR ucDllDisBit;	/*  position of DLL Enable/Disable bit in EMRS ( Extended Mode Register ) */
-	UCHAR ucRefreshRateFactor;	/*  memory refresh rate in unit of ms */
-	UCHAR ucDensity;	/*  _8Mx32, _16Mx32, _16Mx16, _32Mx16 */
-	UCHAR ucPreamble;	/* [7:4] Write Preamble, [3:0] Read Preamble */
-	UCHAR ucMemAttrib;	/*  Memory Device Addribute, like RDBI/WDBI etc */
-	ATOM_MEMORY_TIMING_FORMAT asMemTiming[5];	/* Memory Timing block sort from lower clock to higher clock */
-} ATOM_MEMORY_FORMAT;
+typedef	struct _ATOM_MEMORY_TIMING_FORMAT
+{
+	ULONG											 ulClkRange;				// memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing 	
+  union{
+	  USHORT										 usMRS;							// mode register						
+    USHORT                     usDDR3_MR0;
+  };
+  union{
+	  USHORT										 usEMRS;						// extended mode register
+    USHORT                     usDDR3_MR1;
+  };
+	UCHAR											 ucCL;							// CAS latency
+	UCHAR											 ucWL;							// WRITE Latency				
+	UCHAR											 uctRAS;						// tRAS
+	UCHAR											 uctRC;							// tRC	
+	UCHAR											 uctRFC;						// tRFC
+	UCHAR											 uctRCDR;						// tRCDR	
+	UCHAR											 uctRCDW;						// tRCDW
+	UCHAR											 uctRP;							// tRP
+	UCHAR											 uctRRD;						// tRRD	
+	UCHAR											 uctWR;							// tWR
+	UCHAR											 uctWTR;						// tWTR
+	UCHAR											 uctPDIX;						// tPDIX
+	UCHAR											 uctFAW;						// tFAW
+	UCHAR											 uctAOND;						// tAOND
+  union 
+  {
+    struct {
+	    UCHAR											 ucflag;						// flag to control memory timing calculation. bit0= control EMRS2 Infineon 
+	    UCHAR											 ucReserved;						
+    };
+    USHORT                   usDDR3_MR2;
+  };
+}ATOM_MEMORY_TIMING_FORMAT;
 
-typedef struct _ATOM_VRAM_MODULE_V3 {
-	ULONG ulChannelMapCfg;	/*  board dependent paramenter:Channel combination */
-	USHORT usSize;		/*  size of ATOM_VRAM_MODULE_V3 */
-	USHORT usDefaultMVDDQ;	/*  board dependent parameter:Default Memory Core Voltage */
-	USHORT usDefaultMVDDC;	/*  board dependent parameter:Default Memory IO Voltage */
-	UCHAR ucExtMemoryID;	/*  An external indicator (by hardcode, callback or pin) to tell what is the current memory module */
-	UCHAR ucChannelNum;	/*  board dependent parameter:Number of channel; */
-	UCHAR ucChannelSize;	/*  board dependent parameter:32bit or 64bit */
-	UCHAR ucVREFI;		/*  board dependnt parameter: EXT or INT +160mv to -140mv */
-	UCHAR ucNPL_RT;		/*  board dependent parameter:NPL round trip delay, used for calculate memory timing parameters */
-	UCHAR ucFlag;		/*  To enable/disable functionalities based on memory type */
-	ATOM_MEMORY_FORMAT asMemory;	/*  describ all of video memory parameters from memory spec */
-} ATOM_VRAM_MODULE_V3;
 
-/* ATOM_VRAM_MODULE_V3.ucNPL_RT */
+typedef	struct _ATOM_MEMORY_TIMING_FORMAT_V1
+{
+	ULONG											 ulClkRange;				// memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing 	
+	USHORT										 usMRS;							// mode register						
+	USHORT										 usEMRS;						// extended mode register
+	UCHAR											 ucCL;							// CAS latency
+	UCHAR											 ucWL;							// WRITE Latency				
+	UCHAR											 uctRAS;						// tRAS
+	UCHAR											 uctRC;							// tRC	
+	UCHAR											 uctRFC;						// tRFC
+	UCHAR											 uctRCDR;						// tRCDR	
+	UCHAR											 uctRCDW;						// tRCDW
+	UCHAR											 uctRP;							// tRP
+	UCHAR											 uctRRD;						// tRRD	
+	UCHAR											 uctWR;							// tWR
+	UCHAR											 uctWTR;						// tWTR
+	UCHAR											 uctPDIX;						// tPDIX
+	UCHAR											 uctFAW;						// tFAW
+	UCHAR											 uctAOND;						// tAOND
+	UCHAR											 ucflag;						// flag to control memory timing calculation. bit0= control EMRS2 Infineon 
+////////////////////////////////////GDDR parameters///////////////////////////////////
+	UCHAR											 uctCCDL;						// 
+	UCHAR											 uctCRCRL;						// 
+	UCHAR											 uctCRCWL;						// 
+	UCHAR											 uctCKE;						// 
+	UCHAR											 uctCKRSE;						// 
+	UCHAR											 uctCKRSX;						// 
+	UCHAR											 uctFAW32;						// 
+	UCHAR											 ucMR5lo;					// 
+	UCHAR											 ucMR5hi;					// 
+	UCHAR											 ucTerminator;
+}ATOM_MEMORY_TIMING_FORMAT_V1;
+
+typedef	struct _ATOM_MEMORY_TIMING_FORMAT_V2
+{
+	ULONG											 ulClkRange;				// memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing 	
+	USHORT										 usMRS;							// mode register						
+	USHORT										 usEMRS;						// extended mode register
+	UCHAR											 ucCL;							// CAS latency
+	UCHAR											 ucWL;							// WRITE Latency				
+	UCHAR											 uctRAS;						// tRAS
+	UCHAR											 uctRC;							// tRC	
+	UCHAR											 uctRFC;						// tRFC
+	UCHAR											 uctRCDR;						// tRCDR	
+	UCHAR											 uctRCDW;						// tRCDW
+	UCHAR											 uctRP;							// tRP
+	UCHAR											 uctRRD;						// tRRD	
+	UCHAR											 uctWR;							// tWR
+	UCHAR											 uctWTR;						// tWTR
+	UCHAR											 uctPDIX;						// tPDIX
+	UCHAR											 uctFAW;						// tFAW
+	UCHAR											 uctAOND;						// tAOND
+	UCHAR											 ucflag;						// flag to control memory timing calculation. bit0= control EMRS2 Infineon 
+////////////////////////////////////GDDR parameters///////////////////////////////////
+	UCHAR											 uctCCDL;						// 
+	UCHAR											 uctCRCRL;						// 
+	UCHAR											 uctCRCWL;						// 
+	UCHAR											 uctCKE;						// 
+	UCHAR											 uctCKRSE;						// 
+	UCHAR											 uctCKRSX;						// 
+	UCHAR											 uctFAW32;						// 
+	UCHAR											 ucMR4lo;					// 
+	UCHAR											 ucMR4hi;					// 
+	UCHAR											 ucMR5lo;					// 
+	UCHAR											 ucMR5hi;					// 
+	UCHAR											 ucTerminator;
+	UCHAR											 ucReserved;	
+}ATOM_MEMORY_TIMING_FORMAT_V2;
+
+typedef	struct _ATOM_MEMORY_FORMAT
+{
+	ULONG											 ulDllDisClock;			// memory DLL will be disable when target memory clock is below this clock
+  union{
+    USHORT                     usEMRS2Value;      // EMRS2 Value is used for GDDR2 and GDDR4 memory type
+    USHORT                     usDDR3_Reserved;   // Not used for DDR3 memory
+  };
+  union{
+    USHORT                     usEMRS3Value;      // EMRS3 Value is used for GDDR2 and GDDR4 memory type
+    USHORT                     usDDR3_MR3;        // Used for DDR3 memory
+  };
+  UCHAR                      ucMemoryType;      // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] - must not be used for now;
+  UCHAR                      ucMemoryVenderID;  // Predefined,never change across designs or memory type/vender. If not predefined, vendor detection table gets executed
+  UCHAR                      ucRow;             // Number of Row,in power of 2;
+  UCHAR                      ucColumn;          // Number of Column,in power of 2;
+  UCHAR                      ucBank;            // Nunber of Bank;
+  UCHAR                      ucRank;            // Number of Rank, in power of 2
+	UCHAR											 ucBurstSize;				// burst size, 0= burst size=4  1= burst size=8
+  UCHAR                      ucDllDisBit;				// position of DLL Enable/Disable bit in EMRS ( Extended Mode Register )
+  UCHAR                      ucRefreshRateFactor;	// memory refresh rate in unit of ms	
+	UCHAR											 ucDensity;					// _8Mx32, _16Mx32, _16Mx16, _32Mx16
+	UCHAR											 ucPreamble;				//[7:4] Write Preamble, [3:0] Read Preamble
+  UCHAR											 ucMemAttrib;				// Memory Device Addribute, like RDBI/WDBI etc
+	ATOM_MEMORY_TIMING_FORMAT	 asMemTiming[5];		//Memory Timing block sort from lower clock to higher clock
+}ATOM_MEMORY_FORMAT;
+
+
+typedef struct _ATOM_VRAM_MODULE_V3
+{
+	ULONG											 ulChannelMapCfg;		// board dependent paramenter:Channel combination
+	USHORT										 usSize;						// size of ATOM_VRAM_MODULE_V3
+  USHORT                     usDefaultMVDDQ;		// board dependent parameter:Default Memory Core Voltage
+  USHORT                     usDefaultMVDDC;		// board dependent parameter:Default Memory IO Voltage
+	UCHAR                      ucExtMemoryID;     // An external indicator (by hardcode, callback or pin) to tell what is the current memory module
+  UCHAR                      ucChannelNum;      // board dependent parameter:Number of channel;
+	UCHAR											 ucChannelSize;			// board dependent parameter:32bit or 64bit	
+	UCHAR											 ucVREFI;						// board dependnt parameter: EXT or INT +160mv to -140mv
+	UCHAR											 ucNPL_RT;					// board dependent parameter:NPL round trip delay, used for calculate memory timing parameters
+	UCHAR											 ucFlag;						// To enable/disable functionalities based on memory type
+	ATOM_MEMORY_FORMAT				 asMemory;					// describ all of video memory parameters from memory spec
+}ATOM_VRAM_MODULE_V3;
+
+
+//ATOM_VRAM_MODULE_V3.ucNPL_RT
 #define NPL_RT_MASK															0x0f
 #define BATTERY_ODT_MASK												0xc0
 
 #define ATOM_VRAM_MODULE		 ATOM_VRAM_MODULE_V3
 
-typedef struct _ATOM_VRAM_MODULE_V4 {
-	ULONG ulChannelMapCfg;	/*  board dependent parameter: Channel combination */
-	USHORT usModuleSize;	/*  size of ATOM_VRAM_MODULE_V4, make it easy for VBIOS to look for next entry of VRAM_MODULE */
-	USHORT usPrivateReserved;	/*  BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! */
-	/*  MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) */
-	USHORT usReserved;
-	UCHAR ucExtMemoryID;	/*  An external indicator (by hardcode, callback or pin) to tell what is the current memory module */
-	UCHAR ucMemoryType;	/*  [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4; 0x5:DDR5 [3:0] - Must be 0x0 for now; */
-	UCHAR ucChannelNum;	/*  Number of channels present in this module config */
-	UCHAR ucChannelWidth;	/*  0 - 32 bits; 1 - 64 bits */
-	UCHAR ucDensity;	/*  _8Mx32, _16Mx32, _16Mx16, _32Mx16 */
-	UCHAR ucFlag;		/*  To enable/disable functionalities based on memory type */
-	UCHAR ucMisc;		/*  bit0: 0 - single rank; 1 - dual rank;   bit2: 0 - burstlength 4, 1 - burstlength 8 */
-	UCHAR ucVREFI;		/*  board dependent parameter */
-	UCHAR ucNPL_RT;		/*  board dependent parameter:NPL round trip delay, used for calculate memory timing parameters */
-	UCHAR ucPreamble;	/*  [7:4] Write Preamble, [3:0] Read Preamble */
-	UCHAR ucMemorySize;	/*  BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! */
-	/*  Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros */
-	UCHAR ucReserved[3];
+typedef struct _ATOM_VRAM_MODULE_V4
+{
+  ULONG	  ulChannelMapCfg;	                // board dependent parameter: Channel combination
+  USHORT  usModuleSize;                     // size of ATOM_VRAM_MODULE_V4, make it easy for VBIOS to look for next entry of VRAM_MODULE
+  USHORT  usPrivateReserved;                // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!!
+                                            // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS)
+  USHORT  usReserved;
+  UCHAR   ucExtMemoryID;    		            // An external indicator (by hardcode, callback or pin) to tell what is the current memory module
+  UCHAR   ucMemoryType;                     // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4; 0x5:DDR5 [3:0] - Must be 0x0 for now;
+  UCHAR   ucChannelNum;                     // Number of channels present in this module config
+  UCHAR   ucChannelWidth;                   // 0 - 32 bits; 1 - 64 bits
+	UCHAR   ucDensity;                        // _8Mx32, _16Mx32, _16Mx16, _32Mx16
+	UCHAR	  ucFlag;						                // To enable/disable functionalities based on memory type
+	UCHAR	  ucMisc;						                // bit0: 0 - single rank; 1 - dual rank;   bit2: 0 - burstlength 4, 1 - burstlength 8
+  UCHAR		ucVREFI;                          // board dependent parameter
+  UCHAR   ucNPL_RT;                         // board dependent parameter:NPL round trip delay, used for calculate memory timing parameters
+  UCHAR		ucPreamble;                       // [7:4] Write Preamble, [3:0] Read Preamble
+  UCHAR   ucMemorySize;                     // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!!
+                                            // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros
+  UCHAR   ucReserved[3];
 
-/* compare with V3, we flat the struct by merging ATOM_MEMORY_FORMAT (as is) into V4 as the same level */
-	union {
-		USHORT usEMRS2Value;	/*  EMRS2 Value is used for GDDR2 and GDDR4 memory type */
-		USHORT usDDR3_Reserved;
-	};
-	union {
-		USHORT usEMRS3Value;	/*  EMRS3 Value is used for GDDR2 and GDDR4 memory type */
-		USHORT usDDR3_MR3;	/*  Used for DDR3 memory */
-	};
-	UCHAR ucMemoryVenderID;	/*  Predefined, If not predefined, vendor detection table gets executed */
-	UCHAR ucRefreshRateFactor;	/*  [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms) */
-	UCHAR ucReserved2[2];
-	ATOM_MEMORY_TIMING_FORMAT asMemTiming[5];	/* Memory Timing block sort from lower clock to higher clock */
-} ATOM_VRAM_MODULE_V4;
+//compare with V3, we flat the struct by merging ATOM_MEMORY_FORMAT (as is) into V4 as the same level
+  union{
+    USHORT	usEMRS2Value;                   // EMRS2 Value is used for GDDR2 and GDDR4 memory type
+    USHORT  usDDR3_Reserved;
+  };
+  union{
+    USHORT	usEMRS3Value;                   // EMRS3 Value is used for GDDR2 and GDDR4 memory type
+    USHORT  usDDR3_MR3;                     // Used for DDR3 memory
+  };  
+  UCHAR   ucMemoryVenderID;  		            // Predefined, If not predefined, vendor detection table gets executed
+  UCHAR	  ucRefreshRateFactor;              // [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms)
+  UCHAR   ucReserved2[2];
+  ATOM_MEMORY_TIMING_FORMAT  asMemTiming[5];//Memory Timing block sort from lower clock to higher clock
+}ATOM_VRAM_MODULE_V4;
 
 #define VRAM_MODULE_V4_MISC_RANK_MASK       0x3
 #define VRAM_MODULE_V4_MISC_DUAL_RANK       0x1
@@ -3973,96 +4841,139 @@ typedef struct _ATOM_VRAM_MODULE_V4 {
 #define VRAM_MODULE_V4_MISC_BL8             0x4
 #define VRAM_MODULE_V4_MISC_DUAL_CS         0x10
 
-typedef struct _ATOM_VRAM_MODULE_V5 {
-	ULONG ulChannelMapCfg;	/*  board dependent parameter: Channel combination */
-	USHORT usModuleSize;	/*  size of ATOM_VRAM_MODULE_V4, make it easy for VBIOS to look for next entry of VRAM_MODULE */
-	USHORT usPrivateReserved;	/*  BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! */
-	/*  MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) */
-	USHORT usReserved;
-	UCHAR ucExtMemoryID;	/*  An external indicator (by hardcode, callback or pin) to tell what is the current memory module */
-	UCHAR ucMemoryType;	/*  [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4; 0x5:DDR5 [3:0] - Must be 0x0 for now; */
-	UCHAR ucChannelNum;	/*  Number of channels present in this module config */
-	UCHAR ucChannelWidth;	/*  0 - 32 bits; 1 - 64 bits */
-	UCHAR ucDensity;	/*  _8Mx32, _16Mx32, _16Mx16, _32Mx16 */
-	UCHAR ucFlag;		/*  To enable/disable functionalities based on memory type */
-	UCHAR ucMisc;		/*  bit0: 0 - single rank; 1 - dual rank;   bit2: 0 - burstlength 4, 1 - burstlength 8 */
-	UCHAR ucVREFI;		/*  board dependent parameter */
-	UCHAR ucNPL_RT;		/*  board dependent parameter:NPL round trip delay, used for calculate memory timing parameters */
-	UCHAR ucPreamble;	/*  [7:4] Write Preamble, [3:0] Read Preamble */
-	UCHAR ucMemorySize;	/*  BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! */
-	/*  Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros */
-	UCHAR ucReserved[3];
+typedef struct _ATOM_VRAM_MODULE_V5
+{
+  ULONG	  ulChannelMapCfg;	                // board dependent parameter: Channel combination
+  USHORT  usModuleSize;                     // size of ATOM_VRAM_MODULE_V4, make it easy for VBIOS to look for next entry of VRAM_MODULE
+  USHORT  usPrivateReserved;                // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!!
+                                            // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS)
+  USHORT  usReserved;
+  UCHAR   ucExtMemoryID;    		            // An external indicator (by hardcode, callback or pin) to tell what is the current memory module
+  UCHAR   ucMemoryType;                     // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4; 0x5:DDR5 [3:0] - Must be 0x0 for now;
+  UCHAR   ucChannelNum;                     // Number of channels present in this module config
+  UCHAR   ucChannelWidth;                   // 0 - 32 bits; 1 - 64 bits
+	UCHAR   ucDensity;                        // _8Mx32, _16Mx32, _16Mx16, _32Mx16
+	UCHAR	  ucFlag;						                // To enable/disable functionalities based on memory type
+	UCHAR	  ucMisc;						                // bit0: 0 - single rank; 1 - dual rank;   bit2: 0 - burstlength 4, 1 - burstlength 8
+  UCHAR		ucVREFI;                          // board dependent parameter
+  UCHAR   ucNPL_RT;                         // board dependent parameter:NPL round trip delay, used for calculate memory timing parameters
+  UCHAR		ucPreamble;                       // [7:4] Write Preamble, [3:0] Read Preamble
+  UCHAR   ucMemorySize;                     // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!!
+                                            // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros
+  UCHAR   ucReserved[3];
 
-/* compare with V3, we flat the struct by merging ATOM_MEMORY_FORMAT (as is) into V4 as the same level */
-	USHORT usEMRS2Value;	/*  EMRS2 Value is used for GDDR2 and GDDR4 memory type */
-	USHORT usEMRS3Value;	/*  EMRS3 Value is used for GDDR2 and GDDR4 memory type */
-	UCHAR ucMemoryVenderID;	/*  Predefined, If not predefined, vendor detection table gets executed */
-	UCHAR ucRefreshRateFactor;	/*  [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms) */
-	UCHAR ucFIFODepth;	/*  FIFO depth supposes to be detected during vendor detection, but if we dont do vendor detection we have to hardcode FIFO Depth */
-	UCHAR ucCDR_Bandwidth;	/*  [0:3]=Read CDR bandwidth, [4:7] - Write CDR Bandwidth */
-	ATOM_MEMORY_TIMING_FORMAT_V1 asMemTiming[5];	/* Memory Timing block sort from lower clock to higher clock */
-} ATOM_VRAM_MODULE_V5;
+//compare with V3, we flat the struct by merging ATOM_MEMORY_FORMAT (as is) into V4 as the same level
+  USHORT	usEMRS2Value;      		            // EMRS2 Value is used for GDDR2 and GDDR4 memory type
+  USHORT	usEMRS3Value;      		            // EMRS3 Value is used for GDDR2 and GDDR4 memory type
+  UCHAR   ucMemoryVenderID;  		            // Predefined, If not predefined, vendor detection table gets executed
+  UCHAR	  ucRefreshRateFactor;              // [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms)
+  UCHAR	  ucFIFODepth;			                // FIFO depth supposes to be detected during vendor detection, but if we dont do vendor detection we have to hardcode FIFO Depth
+  UCHAR   ucCDR_Bandwidth;		   // [0:3]=Read CDR bandwidth, [4:7] - Write CDR Bandwidth
+  ATOM_MEMORY_TIMING_FORMAT_V1  asMemTiming[5];//Memory Timing block sort from lower clock to higher clock
+}ATOM_VRAM_MODULE_V5;
 
-typedef struct _ATOM_VRAM_INFO_V2 {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	UCHAR ucNumOfVRAMModule;
-	ATOM_VRAM_MODULE aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE];	/*  just for allocation, real number of blocks is in ucNumOfVRAMModule; */
-} ATOM_VRAM_INFO_V2;
+typedef struct _ATOM_VRAM_MODULE_V6
+{
+  ULONG	  ulChannelMapCfg;	                // board dependent parameter: Channel combination
+  USHORT  usModuleSize;                     // size of ATOM_VRAM_MODULE_V4, make it easy for VBIOS to look for next entry of VRAM_MODULE
+  USHORT  usPrivateReserved;                // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!!
+                                            // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS)
+  USHORT  usReserved;
+  UCHAR   ucExtMemoryID;    		            // An external indicator (by hardcode, callback or pin) to tell what is the current memory module
+  UCHAR   ucMemoryType;                     // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4; 0x5:DDR5 [3:0] - Must be 0x0 for now;
+  UCHAR   ucChannelNum;                     // Number of channels present in this module config
+  UCHAR   ucChannelWidth;                   // 0 - 32 bits; 1 - 64 bits
+	UCHAR   ucDensity;                        // _8Mx32, _16Mx32, _16Mx16, _32Mx16
+	UCHAR	  ucFlag;						                // To enable/disable functionalities based on memory type
+	UCHAR	  ucMisc;						                // bit0: 0 - single rank; 1 - dual rank;   bit2: 0 - burstlength 4, 1 - burstlength 8
+  UCHAR		ucVREFI;                          // board dependent parameter
+  UCHAR   ucNPL_RT;                         // board dependent parameter:NPL round trip delay, used for calculate memory timing parameters
+  UCHAR		ucPreamble;                       // [7:4] Write Preamble, [3:0] Read Preamble
+  UCHAR   ucMemorySize;                     // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!!
+                                            // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros
+  UCHAR   ucReserved[3];
+
+//compare with V3, we flat the struct by merging ATOM_MEMORY_FORMAT (as is) into V4 as the same level
+  USHORT	usEMRS2Value;      		            // EMRS2 Value is used for GDDR2 and GDDR4 memory type
+  USHORT	usEMRS3Value;      		            // EMRS3 Value is used for GDDR2 and GDDR4 memory type
+  UCHAR   ucMemoryVenderID;  		            // Predefined, If not predefined, vendor detection table gets executed
+  UCHAR	  ucRefreshRateFactor;              // [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms)
+  UCHAR	  ucFIFODepth;			                // FIFO depth supposes to be detected during vendor detection, but if we dont do vendor detection we have to hardcode FIFO Depth
+  UCHAR   ucCDR_Bandwidth;		   // [0:3]=Read CDR bandwidth, [4:7] - Write CDR Bandwidth
+  ATOM_MEMORY_TIMING_FORMAT_V2  asMemTiming[5];//Memory Timing block sort from lower clock to higher clock
+}ATOM_VRAM_MODULE_V6;
 
-typedef struct _ATOM_VRAM_INFO_V3 {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	USHORT usMemAdjustTblOffset;	/*  offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting */
-	USHORT usMemClkPatchTblOffset;	/*      offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting */
-	USHORT usRerseved;
-	UCHAR aVID_PinsShift[9];	/*  8 bit strap maximum+terminator */
-	UCHAR ucNumOfVRAMModule;
-	ATOM_VRAM_MODULE aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE];	/*  just for allocation, real number of blocks is in ucNumOfVRAMModule; */
-	ATOM_INIT_REG_BLOCK asMemPatch;	/*  for allocation */
-	/*      ATOM_INIT_REG_BLOCK                              aMemAdjust; */
-} ATOM_VRAM_INFO_V3;
+
+
+typedef struct _ATOM_VRAM_INFO_V2
+{
+  ATOM_COMMON_TABLE_HEADER   sHeader;
+  UCHAR                      ucNumOfVRAMModule;
+  ATOM_VRAM_MODULE           aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE];      // just for allocation, real number of blocks is in ucNumOfVRAMModule;
+}ATOM_VRAM_INFO_V2;
+
+typedef struct _ATOM_VRAM_INFO_V3
+{
+  ATOM_COMMON_TABLE_HEADER   sHeader;
+	USHORT										 usMemAdjustTblOffset;													 // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting
+	USHORT										 usMemClkPatchTblOffset;												 //	offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting
+	USHORT										 usRerseved;
+	UCHAR           	         aVID_PinsShift[9];															 // 8 bit strap maximum+terminator
+  UCHAR                      ucNumOfVRAMModule;
+  ATOM_VRAM_MODULE		       aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE];      // just for allocation, real number of blocks is in ucNumOfVRAMModule;
+	ATOM_INIT_REG_BLOCK				 asMemPatch;																		 // for allocation
+																																						 //	ATOM_INIT_REG_BLOCK				 aMemAdjust;
+}ATOM_VRAM_INFO_V3;
 
 #define	ATOM_VRAM_INFO_LAST	     ATOM_VRAM_INFO_V3
 
-typedef struct _ATOM_VRAM_INFO_V4 {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	USHORT usMemAdjustTblOffset;	/*  offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting */
-	USHORT usMemClkPatchTblOffset;	/*      offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting */
-	USHORT usRerseved;
-	UCHAR ucMemDQ7_0ByteRemap;	/*  DQ line byte remap, =0: Memory Data line BYTE0, =1: BYTE1, =2: BYTE2, =3: BYTE3 */
-	ULONG ulMemDQ7_0BitRemap;	/*  each DQ line ( 7~0) use 3bits, like: DQ0=Bit[2:0], DQ1:[5:3], ... DQ7:[23:21] */
-	UCHAR ucReservde[4];
-	UCHAR ucNumOfVRAMModule;
-	ATOM_VRAM_MODULE_V4 aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE];	/*  just for allocation, real number of blocks is in ucNumOfVRAMModule; */
-	ATOM_INIT_REG_BLOCK asMemPatch;	/*  for allocation */
-	/*      ATOM_INIT_REG_BLOCK                              aMemAdjust; */
-} ATOM_VRAM_INFO_V4;
+typedef struct _ATOM_VRAM_INFO_V4
+{
+  ATOM_COMMON_TABLE_HEADER   sHeader;
+	USHORT										 usMemAdjustTblOffset;													 // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting
+	USHORT										 usMemClkPatchTblOffset;												 //	offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting
+	USHORT										 usRerseved;
+	UCHAR           	         ucMemDQ7_0ByteRemap;													   // DQ line byte remap, =0: Memory Data line BYTE0, =1: BYTE1, =2: BYTE2, =3: BYTE3
+  ULONG                      ulMemDQ7_0BitRemap;                             // each DQ line ( 7~0) use 3bits, like: DQ0=Bit[2:0], DQ1:[5:3], ... DQ7:[23:21]
+  UCHAR                      ucReservde[4]; 
+  UCHAR                      ucNumOfVRAMModule;
+  ATOM_VRAM_MODULE_V4		     aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE];      // just for allocation, real number of blocks is in ucNumOfVRAMModule;
+	ATOM_INIT_REG_BLOCK				 asMemPatch;																		 // for allocation
+																																						 //	ATOM_INIT_REG_BLOCK				 aMemAdjust;
+}ATOM_VRAM_INFO_V4;
 
-typedef struct _ATOM_VRAM_GPIO_DETECTION_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	UCHAR aVID_PinsShift[9];	/* 8 bit strap maximum+terminator */
-} ATOM_VRAM_GPIO_DETECTION_INFO;
+typedef struct _ATOM_VRAM_GPIO_DETECTION_INFO
+{
+  ATOM_COMMON_TABLE_HEADER   sHeader;
+  UCHAR           	         aVID_PinsShift[9];   //8 bit strap maximum+terminator
+}ATOM_VRAM_GPIO_DETECTION_INFO;
 
-typedef struct _ATOM_MEMORY_TRAINING_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	UCHAR ucTrainingLoop;
-	UCHAR ucReserved[3];
-	ATOM_INIT_REG_BLOCK asMemTrainingSetting;
-} ATOM_MEMORY_TRAINING_INFO;
 
-typedef struct SW_I2C_CNTL_DATA_PARAMETERS {
-	UCHAR ucControl;
-	UCHAR ucData;
-	UCHAR ucSatus;
-	UCHAR ucTemp;
+typedef struct _ATOM_MEMORY_TRAINING_INFO
+{
+	ATOM_COMMON_TABLE_HEADER   sHeader;
+	UCHAR											 ucTrainingLoop;
+	UCHAR											 ucReserved[3];
+	ATOM_INIT_REG_BLOCK				 asMemTrainingSetting;
+}ATOM_MEMORY_TRAINING_INFO;
+
+
+typedef struct SW_I2C_CNTL_DATA_PARAMETERS
+{
+  UCHAR    ucControl;
+  UCHAR    ucData; 
+  UCHAR    ucSatus; 
+  UCHAR    ucTemp; 
 } SW_I2C_CNTL_DATA_PARAMETERS;
 
 #define SW_I2C_CNTL_DATA_PS_ALLOCATION  SW_I2C_CNTL_DATA_PARAMETERS
 
-typedef struct _SW_I2C_IO_DATA_PARAMETERS {
-	USHORT GPIO_Info;
-	UCHAR ucAct;
-	UCHAR ucData;
-} SW_I2C_IO_DATA_PARAMETERS;
+typedef struct _SW_I2C_IO_DATA_PARAMETERS
+{                               
+  USHORT   GPIO_Info;
+  UCHAR    ucAct; 
+  UCHAR    ucData; 
+ } SW_I2C_IO_DATA_PARAMETERS;
 
 #define SW_I2C_IO_DATA_PS_ALLOCATION  SW_I2C_IO_DATA_PARAMETERS
 
@@ -4087,127 +4998,136 @@ typedef struct _SW_I2C_IO_DATA_PARAMETER
 #define SW_I2C_CNTL_CLOSE     5
 #define SW_I2C_CNTL_WRITE1BIT 6
 
-/* ==============================VESA definition Portion=============================== */
+//==============================VESA definition Portion===============================
 #define VESA_OEM_PRODUCT_REV			            '01.00'
-#define VESA_MODE_ATTRIBUTE_MODE_SUPPORT	     0xBB	/* refer to VBE spec p.32, no TTY support */
+#define VESA_MODE_ATTRIBUTE_MODE_SUPPORT	     0xBB	//refer to VBE spec p.32, no TTY support
 #define VESA_MODE_WIN_ATTRIBUTE						     7
 #define VESA_WIN_SIZE											     64
 
-typedef struct _PTR_32_BIT_STRUCTURE {
-	USHORT Offset16;
-	USHORT Segment16;
+typedef struct _PTR_32_BIT_STRUCTURE
+{
+	USHORT	Offset16;			
+	USHORT	Segment16;				
 } PTR_32_BIT_STRUCTURE;
 
-typedef union _PTR_32_BIT_UNION {
-	PTR_32_BIT_STRUCTURE SegmentOffset;
-	ULONG Ptr32_Bit;
+typedef union _PTR_32_BIT_UNION
+{
+	PTR_32_BIT_STRUCTURE	SegmentOffset;
+	ULONG					        Ptr32_Bit;
 } PTR_32_BIT_UNION;
 
-typedef struct _VBE_1_2_INFO_BLOCK_UPDATABLE {
-	UCHAR VbeSignature[4];
-	USHORT VbeVersion;
-	PTR_32_BIT_UNION OemStringPtr;
-	UCHAR Capabilities[4];
-	PTR_32_BIT_UNION VideoModePtr;
-	USHORT TotalMemory;
+typedef struct _VBE_1_2_INFO_BLOCK_UPDATABLE
+{
+	UCHAR				      VbeSignature[4];
+	USHORT				    VbeVersion;
+	PTR_32_BIT_UNION	OemStringPtr;
+	UCHAR				      Capabilities[4];
+	PTR_32_BIT_UNION	VideoModePtr;
+	USHORT				    TotalMemory;
 } VBE_1_2_INFO_BLOCK_UPDATABLE;
 
-typedef struct _VBE_2_0_INFO_BLOCK_UPDATABLE {
-	VBE_1_2_INFO_BLOCK_UPDATABLE CommonBlock;
-	USHORT OemSoftRev;
-	PTR_32_BIT_UNION OemVendorNamePtr;
-	PTR_32_BIT_UNION OemProductNamePtr;
-	PTR_32_BIT_UNION OemProductRevPtr;
+
+typedef struct _VBE_2_0_INFO_BLOCK_UPDATABLE
+{
+	VBE_1_2_INFO_BLOCK_UPDATABLE	CommonBlock;
+	USHORT							    OemSoftRev;
+	PTR_32_BIT_UNION				OemVendorNamePtr;
+	PTR_32_BIT_UNION				OemProductNamePtr;
+	PTR_32_BIT_UNION				OemProductRevPtr;
 } VBE_2_0_INFO_BLOCK_UPDATABLE;
 
-typedef union _VBE_VERSION_UNION {
-	VBE_2_0_INFO_BLOCK_UPDATABLE VBE_2_0_InfoBlock;
-	VBE_1_2_INFO_BLOCK_UPDATABLE VBE_1_2_InfoBlock;
+typedef union _VBE_VERSION_UNION
+{
+	VBE_2_0_INFO_BLOCK_UPDATABLE	VBE_2_0_InfoBlock;
+	VBE_1_2_INFO_BLOCK_UPDATABLE	VBE_1_2_InfoBlock;
 } VBE_VERSION_UNION;
 
-typedef struct _VBE_INFO_BLOCK {
-	VBE_VERSION_UNION UpdatableVBE_Info;
-	UCHAR Reserved[222];
-	UCHAR OemData[256];
+typedef struct _VBE_INFO_BLOCK
+{
+	VBE_VERSION_UNION			UpdatableVBE_Info;
+	UCHAR						      Reserved[222];
+	UCHAR						      OemData[256];
 } VBE_INFO_BLOCK;
 
-typedef struct _VBE_FP_INFO {
-	USHORT HSize;
-	USHORT VSize;
-	USHORT FPType;
-	UCHAR RedBPP;
-	UCHAR GreenBPP;
-	UCHAR BlueBPP;
-	UCHAR ReservedBPP;
-	ULONG RsvdOffScrnMemSize;
-	ULONG RsvdOffScrnMEmPtr;
-	UCHAR Reserved[14];
+typedef struct _VBE_FP_INFO
+{
+  USHORT	HSize;
+	USHORT	VSize;
+	USHORT	FPType;
+	UCHAR		RedBPP;
+	UCHAR		GreenBPP;
+	UCHAR		BlueBPP;
+	UCHAR		ReservedBPP;
+	ULONG		RsvdOffScrnMemSize;
+	ULONG		RsvdOffScrnMEmPtr;
+	UCHAR		Reserved[14];
 } VBE_FP_INFO;
 
-typedef struct _VESA_MODE_INFO_BLOCK {
-/*  Mandatory information for all VBE revisions */
-	USHORT ModeAttributes;	/*                  dw      ?       ; mode attributes */
-	UCHAR WinAAttributes;	/*                    db      ?       ; window A attributes */
-	UCHAR WinBAttributes;	/*                    db      ?       ; window B attributes */
-	USHORT WinGranularity;	/*                    dw      ?       ; window granularity */
-	USHORT WinSize;		/*                    dw      ?       ; window size */
-	USHORT WinASegment;	/*                    dw      ?       ; window A start segment */
-	USHORT WinBSegment;	/*                    dw      ?       ; window B start segment */
-	ULONG WinFuncPtr;	/*                    dd      ?       ; real mode pointer to window function */
-	USHORT BytesPerScanLine;	/*                    dw      ?       ; bytes per scan line */
+typedef struct _VESA_MODE_INFO_BLOCK
+{
+// Mandatory information for all VBE revisions
+  USHORT    ModeAttributes;  //			dw	?	; mode attributes
+	UCHAR     WinAAttributes;  //			db	?	; window A attributes
+	UCHAR     WinBAttributes;  //			db	?	; window B attributes
+	USHORT    WinGranularity;  //			dw	?	; window granularity
+	USHORT    WinSize;         //			dw	?	; window size
+	USHORT    WinASegment;     //			dw	?	; window A start segment
+	USHORT    WinBSegment;     //			dw	?	; window B start segment
+	ULONG     WinFuncPtr;      //			dd	?	; real mode pointer to window function
+	USHORT    BytesPerScanLine;//			dw	?	; bytes per scan line
 
-/* ; Mandatory information for VBE 1.2 and above */
-	USHORT XResolution;	/*                         dw      ?       ; horizontal resolution in pixels or characters */
-	USHORT YResolution;	/*                   dw      ?       ; vertical resolution in pixels or characters */
-	UCHAR XCharSize;	/*                   db      ?       ; character cell width in pixels */
-	UCHAR YCharSize;	/*                   db      ?       ; character cell height in pixels */
-	UCHAR NumberOfPlanes;	/*                   db      ?       ; number of memory planes */
-	UCHAR BitsPerPixel;	/*                   db      ?       ; bits per pixel */
-	UCHAR NumberOfBanks;	/*                   db      ?       ; number of banks */
-	UCHAR MemoryModel;	/*                   db      ?       ; memory model type */
-	UCHAR BankSize;		/*                   db      ?       ; bank size in KB */
-	UCHAR NumberOfImagePages;	/*            db    ?       ; number of images */
-	UCHAR ReservedForPageFunction;	/* db  1       ; reserved for page function */
+//; Mandatory information for VBE 1.2 and above
+  USHORT    XResolution;      //			dw	?	; horizontal resolution in pixels or characters
+	USHORT    YResolution;      //			dw	?	; vertical resolution in pixels or characters
+	UCHAR     XCharSize;        //			db	?	; character cell width in pixels
+	UCHAR     YCharSize;        //			db	?	; character cell height in pixels
+	UCHAR     NumberOfPlanes;   //			db	?	; number of memory planes
+	UCHAR     BitsPerPixel;     //			db	?	; bits per pixel
+	UCHAR     NumberOfBanks;    //			db	?	; number of banks
+	UCHAR     MemoryModel;      //			db	?	; memory model type
+	UCHAR     BankSize;         //			db	?	; bank size in KB
+	UCHAR     NumberOfImagePages;//		  db	?	; number of images
+	UCHAR     ReservedForPageFunction;//db	1	; reserved for page function
 
-/* ; Direct Color fields(required for direct/6 and YUV/7 memory models) */
-	UCHAR RedMaskSize;	/*           db      ?       ; size of direct color red mask in bits */
-	UCHAR RedFieldPosition;	/*           db      ?       ; bit position of lsb of red mask */
-	UCHAR GreenMaskSize;	/*           db      ?       ; size of direct color green mask in bits */
-	UCHAR GreenFieldPosition;	/*           db      ?       ; bit position of lsb of green mask */
-	UCHAR BlueMaskSize;	/*           db      ?       ; size of direct color blue mask in bits */
-	UCHAR BlueFieldPosition;	/*           db      ?       ; bit position of lsb of blue mask */
-	UCHAR RsvdMaskSize;	/*           db      ?       ; size of direct color reserved mask in bits */
-	UCHAR RsvdFieldPosition;	/*           db      ?       ; bit position of lsb of reserved mask */
-	UCHAR DirectColorModeInfo;	/*           db      ?       ; direct color mode attributes */
+//; Direct Color fields(required for direct/6 and YUV/7 memory models)
+	UCHAR			RedMaskSize;        //		db	?	; size of direct color red mask in bits
+	UCHAR			RedFieldPosition;   //		db	?	; bit position of lsb of red mask
+	UCHAR			GreenMaskSize;      //		db	?	; size of direct color green mask in bits
+	UCHAR			GreenFieldPosition; //		db	?	; bit position of lsb of green mask
+	UCHAR			BlueMaskSize;       //		db	?	; size of direct color blue mask in bits
+	UCHAR			BlueFieldPosition;  //		db	?	; bit position of lsb of blue mask
+	UCHAR			RsvdMaskSize;       //		db	?	; size of direct color reserved mask in bits
+	UCHAR			RsvdFieldPosition;  //		db	?	; bit position of lsb of reserved mask
+	UCHAR			DirectColorModeInfo;//		db	?	; direct color mode attributes
 
-/* ; Mandatory information for VBE 2.0 and above */
-	ULONG PhysBasePtr;	/*           dd      ?       ; physical address for flat memory frame buffer */
-	ULONG Reserved_1;	/*           dd      0       ; reserved - always set to 0 */
-	USHORT Reserved_2;	/*     dw    0       ; reserved - always set to 0 */
+//; Mandatory information for VBE 2.0 and above
+	ULONG			PhysBasePtr;        //		dd	?	; physical address for flat memory frame buffer
+	ULONG			Reserved_1;         //		dd	0	; reserved - always set to 0
+	USHORT		Reserved_2;         //	  dw	0	; reserved - always set to 0
 
-/* ; Mandatory information for VBE 3.0 and above */
-	USHORT LinBytesPerScanLine;	/*         dw      ?       ; bytes per scan line for linear modes */
-	UCHAR BnkNumberOfImagePages;	/*         db      ?       ; number of images for banked modes */
-	UCHAR LinNumberOfImagPages;	/*         db      ?       ; number of images for linear modes */
-	UCHAR LinRedMaskSize;	/*         db      ?       ; size of direct color red mask(linear modes) */
-	UCHAR LinRedFieldPosition;	/*         db      ?       ; bit position of lsb of red mask(linear modes) */
-	UCHAR LinGreenMaskSize;	/*         db      ?       ; size of direct color green mask(linear modes) */
-	UCHAR LinGreenFieldPosition;	/*         db      ?       ; bit position of lsb of green mask(linear modes) */
-	UCHAR LinBlueMaskSize;	/*         db      ?       ; size of direct color blue mask(linear modes) */
-	UCHAR LinBlueFieldPosition;	/*         db      ?       ; bit position of lsb of blue mask(linear modes) */
-	UCHAR LinRsvdMaskSize;	/*         db      ?       ; size of direct color reserved mask(linear modes) */
-	UCHAR LinRsvdFieldPosition;	/*         db      ?       ; bit position of lsb of reserved mask(linear modes) */
-	ULONG MaxPixelClock;	/*         dd      ?       ; maximum pixel clock(in Hz) for graphics mode */
-	UCHAR Reserved;		/*         db      190 dup (0) */
+//; Mandatory information for VBE 3.0 and above
+	USHORT		LinBytesPerScanLine;  //	dw	?	; bytes per scan line for linear modes
+	UCHAR			BnkNumberOfImagePages;//	db	?	; number of images for banked modes
+	UCHAR			LinNumberOfImagPages; //	db	?	; number of images for linear modes
+	UCHAR			LinRedMaskSize;       //	db	?	; size of direct color red mask(linear modes)
+	UCHAR			LinRedFieldPosition;  //	db	?	; bit position of lsb of red mask(linear modes)
+	UCHAR			LinGreenMaskSize;     //	db	?	; size of direct color green mask(linear modes)
+	UCHAR			LinGreenFieldPosition;//	db	?	; bit position of lsb of green mask(linear modes)
+	UCHAR			LinBlueMaskSize;      //	db	?	; size of direct color blue mask(linear modes)
+	UCHAR			LinBlueFieldPosition; //	db	?	; bit position of lsb of blue mask(linear modes)
+	UCHAR			LinRsvdMaskSize;      //	db	?	; size of direct color reserved mask(linear modes)
+	UCHAR			LinRsvdFieldPosition; //	db	?	; bit position of lsb of reserved mask(linear modes)
+	ULONG			MaxPixelClock;        //	dd	?	; maximum pixel clock(in Hz) for graphics mode
+	UCHAR			Reserved;             //	db	190 dup (0)
 } VESA_MODE_INFO_BLOCK;
 
-/*  BIOS function CALLS */
-#define ATOM_BIOS_EXTENDED_FUNCTION_CODE        0xA0	/*  ATI Extended Function code */
+// BIOS function CALLS
+#define ATOM_BIOS_EXTENDED_FUNCTION_CODE        0xA0	        // ATI Extended Function code
 #define ATOM_BIOS_FUNCTION_COP_MODE             0x00
 #define ATOM_BIOS_FUNCTION_SHORT_QUERY1         0x04
 #define ATOM_BIOS_FUNCTION_SHORT_QUERY2         0x05
 #define ATOM_BIOS_FUNCTION_SHORT_QUERY3         0x06
-#define ATOM_BIOS_FUNCTION_GET_DDC              0x0B
+#define ATOM_BIOS_FUNCTION_GET_DDC              0x0B   
 #define ATOM_BIOS_FUNCTION_ASIC_DSTATE          0x0E
 #define ATOM_BIOS_FUNCTION_DEBUG_PLAY           0x0F
 #define ATOM_BIOS_FUNCTION_STV_STD              0x16
@@ -4217,100 +5137,135 @@ typedef struct _VESA_MODE_INFO_BLOCK {
 #define ATOM_BIOS_FUNCTION_PANEL_CONTROL        0x82
 #define ATOM_BIOS_FUNCTION_OLD_DEVICE_DET       0x83
 #define ATOM_BIOS_FUNCTION_OLD_DEVICE_SWITCH    0x84
-#define ATOM_BIOS_FUNCTION_HW_ICON              0x8A
+#define ATOM_BIOS_FUNCTION_HW_ICON              0x8A 
 #define ATOM_BIOS_FUNCTION_SET_CMOS             0x8B
-#define SUB_FUNCTION_UPDATE_DISPLAY_INFO        0x8000	/*  Sub function 80 */
-#define SUB_FUNCTION_UPDATE_EXPANSION_INFO      0x8100	/*  Sub function 80 */
+#define SUB_FUNCTION_UPDATE_DISPLAY_INFO        0x8000          // Sub function 80
+#define SUB_FUNCTION_UPDATE_EXPANSION_INFO      0x8100          // Sub function 80
 
 #define ATOM_BIOS_FUNCTION_DISPLAY_INFO         0x8D
 #define ATOM_BIOS_FUNCTION_DEVICE_ON_OFF        0x8E
-#define ATOM_BIOS_FUNCTION_VIDEO_STATE          0x8F
-#define ATOM_SUB_FUNCTION_GET_CRITICAL_STATE    0x0300	/*  Sub function 03 */
-#define ATOM_SUB_FUNCTION_GET_LIDSTATE          0x0700	/*  Sub function 7 */
-#define ATOM_SUB_FUNCTION_THERMAL_STATE_NOTICE  0x1400	/*  Notify caller the current thermal state */
-#define ATOM_SUB_FUNCTION_CRITICAL_STATE_NOTICE 0x8300	/*  Notify caller the current critical state */
-#define ATOM_SUB_FUNCTION_SET_LIDSTATE          0x8500	/*  Sub function 85 */
-#define ATOM_SUB_FUNCTION_GET_REQ_DISPLAY_FROM_SBIOS_MODE 0x8900	/*  Sub function 89 */
-#define ATOM_SUB_FUNCTION_INFORM_ADC_SUPPORT    0x9400	/*  Notify caller that ADC is supported */
+#define ATOM_BIOS_FUNCTION_VIDEO_STATE          0x8F 
+#define ATOM_SUB_FUNCTION_GET_CRITICAL_STATE    0x0300          // Sub function 03  
+#define ATOM_SUB_FUNCTION_GET_LIDSTATE          0x0700          // Sub function 7
+#define ATOM_SUB_FUNCTION_THERMAL_STATE_NOTICE  0x1400          // Notify caller the current thermal state
+#define ATOM_SUB_FUNCTION_CRITICAL_STATE_NOTICE 0x8300          // Notify caller the current critical state
+#define ATOM_SUB_FUNCTION_SET_LIDSTATE          0x8500          // Sub function 85
+#define ATOM_SUB_FUNCTION_GET_REQ_DISPLAY_FROM_SBIOS_MODE 0x8900// Sub function 89
+#define ATOM_SUB_FUNCTION_INFORM_ADC_SUPPORT    0x9400          // Notify caller that ADC is supported
+     
 
-#define ATOM_BIOS_FUNCTION_VESA_DPMS            0x4F10	/*  Set DPMS */
-#define ATOM_SUB_FUNCTION_SET_DPMS              0x0001	/*  BL: Sub function 01 */
-#define ATOM_SUB_FUNCTION_GET_DPMS              0x0002	/*  BL: Sub function 02 */
-#define ATOM_PARAMETER_VESA_DPMS_ON             0x0000	/*  BH Parameter for DPMS ON. */
-#define ATOM_PARAMETER_VESA_DPMS_STANDBY        0x0100	/*  BH Parameter for DPMS STANDBY */
-#define ATOM_PARAMETER_VESA_DPMS_SUSPEND        0x0200	/*  BH Parameter for DPMS SUSPEND */
-#define ATOM_PARAMETER_VESA_DPMS_OFF            0x0400	/*  BH Parameter for DPMS OFF */
-#define ATOM_PARAMETER_VESA_DPMS_REDUCE_ON      0x0800	/*  BH Parameter for DPMS REDUCE ON (NOT SUPPORTED) */
+#define ATOM_BIOS_FUNCTION_VESA_DPMS            0x4F10          // Set DPMS 
+#define ATOM_SUB_FUNCTION_SET_DPMS              0x0001          // BL: Sub function 01 
+#define ATOM_SUB_FUNCTION_GET_DPMS              0x0002          // BL: Sub function 02 
+#define ATOM_PARAMETER_VESA_DPMS_ON             0x0000          // BH Parameter for DPMS ON.  
+#define ATOM_PARAMETER_VESA_DPMS_STANDBY        0x0100          // BH Parameter for DPMS STANDBY  
+#define ATOM_PARAMETER_VESA_DPMS_SUSPEND        0x0200          // BH Parameter for DPMS SUSPEND
+#define ATOM_PARAMETER_VESA_DPMS_OFF            0x0400          // BH Parameter for DPMS OFF
+#define ATOM_PARAMETER_VESA_DPMS_REDUCE_ON      0x0800          // BH Parameter for DPMS REDUCE ON (NOT SUPPORTED)
 
 #define ATOM_BIOS_RETURN_CODE_MASK              0x0000FF00L
 #define ATOM_BIOS_REG_HIGH_MASK                 0x0000FF00L
 #define ATOM_BIOS_REG_LOW_MASK                  0x000000FFL
 
-/*  structure used for VBIOS only */
+// structure used for VBIOS only
 
-/* DispOutInfoTable */
-typedef struct _ASIC_TRANSMITTER_INFO {
+//DispOutInfoTable
+typedef struct _ASIC_TRANSMITTER_INFO
+{
 	USHORT usTransmitterObjId;
 	USHORT usSupportDevice;
-	UCHAR ucTransmitterCmdTblId;
-	UCHAR ucConfig;
-	UCHAR ucEncoderID;	/* available 1st encoder ( default ) */
-	UCHAR ucOptionEncoderID;	/* available 2nd encoder ( optional ) */
-	UCHAR uc2ndEncoderID;
-	UCHAR ucReserved;
-} ASIC_TRANSMITTER_INFO;
+  UCHAR  ucTransmitterCmdTblId;
+	UCHAR  ucConfig;
+	UCHAR  ucEncoderID;					 //available 1st encoder ( default )
+	UCHAR  ucOptionEncoderID;    //available 2nd encoder ( optional )
+	UCHAR  uc2ndEncoderID;
+	UCHAR  ucReserved;
+}ASIC_TRANSMITTER_INFO;
 
-typedef struct _ASIC_ENCODER_INFO {
+typedef struct _ASIC_ENCODER_INFO
+{
 	UCHAR ucEncoderID;
 	UCHAR ucEncoderConfig;
-	USHORT usEncoderCmdTblId;
-} ASIC_ENCODER_INFO;
+  USHORT usEncoderCmdTblId;
+}ASIC_ENCODER_INFO;
 
-typedef struct _ATOM_DISP_OUT_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
+typedef struct _ATOM_DISP_OUT_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
 	USHORT ptrTransmitterInfo;
 	USHORT ptrEncoderInfo;
-	ASIC_TRANSMITTER_INFO asTransmitterInfo[1];
-	ASIC_ENCODER_INFO asEncoderInfo[1];
-} ATOM_DISP_OUT_INFO;
+	ASIC_TRANSMITTER_INFO  asTransmitterInfo[1];
+	ASIC_ENCODER_INFO      asEncoderInfo[1];
+}ATOM_DISP_OUT_INFO;
 
-/*  DispDevicePriorityInfo */
-typedef struct _ATOM_DISPLAY_DEVICE_PRIORITY_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
+typedef struct _ATOM_DISP_OUT_INFO_V2
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+	USHORT ptrTransmitterInfo;
+	USHORT ptrEncoderInfo;
+  USHORT ptrMainCallParserFar;                  // direct address of main parser call in VBIOS binary. 
+	ASIC_TRANSMITTER_INFO  asTransmitterInfo[1];
+	ASIC_ENCODER_INFO      asEncoderInfo[1];
+}ATOM_DISP_OUT_INFO_V2;
+
+// DispDevicePriorityInfo
+typedef struct _ATOM_DISPLAY_DEVICE_PRIORITY_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
 	USHORT asDevicePriority[16];
-} ATOM_DISPLAY_DEVICE_PRIORITY_INFO;
+}ATOM_DISPLAY_DEVICE_PRIORITY_INFO;
 
-/* ProcessAuxChannelTransactionTable */
-typedef struct _PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS {
-	USHORT lpAuxRequest;
-	USHORT lpDataOut;
-	UCHAR ucChannelID;
-	union {
-		UCHAR ucReplyStatus;
-		UCHAR ucDelay;
+//ProcessAuxChannelTransactionTable
+typedef struct _PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS
+{
+	USHORT	lpAuxRequest;
+	USHORT  lpDataOut;
+	UCHAR		ucChannelID;
+	union
+	{
+  UCHAR   ucReplyStatus;
+	UCHAR   ucDelay;
 	};
-	UCHAR ucDataOutLen;
-	UCHAR ucReserved;
-} PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS;
+  UCHAR   ucDataOutLen;
+	UCHAR   ucReserved;
+}PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS;
+
+//ProcessAuxChannelTransactionTable
+typedef struct _PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2
+{
+	USHORT	lpAuxRequest;
+	USHORT  lpDataOut;
+	UCHAR		ucChannelID;
+	union
+	{
+  UCHAR   ucReplyStatus;
+	UCHAR   ucDelay;
+	};
+  UCHAR   ucDataOutLen;
+	UCHAR   ucHPD_ID;                                       //=0: HPD1, =1: HPD2, =2: HPD3, =3: HPD4, =4: HPD5, =5: HPD6
+}PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2;
 
 #define PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION			PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS
 
-/* GetSinkType */
+//GetSinkType
 
-typedef struct _DP_ENCODER_SERVICE_PARAMETERS {
+typedef struct _DP_ENCODER_SERVICE_PARAMETERS
+{
 	USHORT ucLinkClock;
-	union {
-		UCHAR ucConfig;	/*  for DP training command */
-		UCHAR ucI2cId;	/*  use for GET_SINK_TYPE command */
+	union 
+	{
+	UCHAR ucConfig;				// for DP training command
+	UCHAR ucI2cId;				// use for GET_SINK_TYPE command
 	};
 	UCHAR ucAction;
 	UCHAR ucStatus;
 	UCHAR ucLaneNum;
 	UCHAR ucReserved[2];
-} DP_ENCODER_SERVICE_PARAMETERS;
+}DP_ENCODER_SERVICE_PARAMETERS;
 
-/*  ucAction */
+// ucAction
 #define ATOM_DP_ACTION_GET_SINK_TYPE							0x01
+/* obselete */
 #define ATOM_DP_ACTION_TRAINING_START							0x02
 #define ATOM_DP_ACTION_TRAINING_COMPLETE					0x03
 #define ATOM_DP_ACTION_TRAINING_PATTERN_SEL				0x04
@@ -4318,7 +5273,7 @@ typedef struct _DP_ENCODER_SERVICE_PARAM
 #define ATOM_DP_ACTION_GET_VSWING_PREEMP					0x06
 #define ATOM_DP_ACTION_BLANKING                   0x07
 
-/*  ucConfig */
+// ucConfig
 #define ATOM_DP_CONFIG_ENCODER_SEL_MASK						0x03
 #define ATOM_DP_CONFIG_DIG1_ENCODER								0x00
 #define ATOM_DP_CONFIG_DIG2_ENCODER								0x01
@@ -4326,14 +5281,14 @@ typedef struct _DP_ENCODER_SERVICE_PARAM
 #define ATOM_DP_CONFIG_LINK_SEL_MASK							0x04
 #define ATOM_DP_CONFIG_LINK_A											0x00
 #define ATOM_DP_CONFIG_LINK_B											0x04
-
+/* /obselete */
 #define DP_ENCODER_SERVICE_PS_ALLOCATION				WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS
 
-/*  DP_TRAINING_TABLE */
-#define DPCD_SET_LINKRATE_LANENUM_PATTERN1_TBL_ADDR				ATOM_DP_TRAINING_TBL_ADDR
+// DP_TRAINING_TABLE
+#define DPCD_SET_LINKRATE_LANENUM_PATTERN1_TBL_ADDR				ATOM_DP_TRAINING_TBL_ADDR		
 #define DPCD_SET_SS_CNTL_TBL_ADDR													(ATOM_DP_TRAINING_TBL_ADDR + 8 )
-#define DPCD_SET_LANE_VSWING_PREEMP_TBL_ADDR							(ATOM_DP_TRAINING_TBL_ADDR + 16)
-#define DPCD_SET_TRAINING_PATTERN0_TBL_ADDR								(ATOM_DP_TRAINING_TBL_ADDR + 24)
+#define DPCD_SET_LANE_VSWING_PREEMP_TBL_ADDR							(ATOM_DP_TRAINING_TBL_ADDR + 16 )
+#define DPCD_SET_TRAINING_PATTERN0_TBL_ADDR								(ATOM_DP_TRAINING_TBL_ADDR + 24 )
 #define DPCD_SET_TRAINING_PATTERN2_TBL_ADDR								(ATOM_DP_TRAINING_TBL_ADDR + 32)
 #define DPCD_GET_LINKRATE_LANENUM_SS_TBL_ADDR							(ATOM_DP_TRAINING_TBL_ADDR + 40)
 #define	DPCD_GET_LANE_STATUS_ADJUST_TBL_ADDR							(ATOM_DP_TRAINING_TBL_ADDR + 48)
@@ -4341,183 +5296,241 @@ typedef struct _DP_ENCODER_SERVICE_PARAM
 #define DP_I2C_AUX_DDC_WRITE_TBL_ADDR											(ATOM_DP_TRAINING_TBL_ADDR + 64)
 #define DP_I2C_AUX_DDC_READ_START_TBL_ADDR								(ATOM_DP_TRAINING_TBL_ADDR + 72)
 #define DP_I2C_AUX_DDC_READ_TBL_ADDR											(ATOM_DP_TRAINING_TBL_ADDR + 76)
-#define DP_I2C_AUX_DDC_READ_END_TBL_ADDR									(ATOM_DP_TRAINING_TBL_ADDR + 80)
+#define DP_I2C_AUX_DDC_WRITE_END_TBL_ADDR                 (ATOM_DP_TRAINING_TBL_ADDR + 80) 
+#define DP_I2C_AUX_DDC_READ_END_TBL_ADDR									(ATOM_DP_TRAINING_TBL_ADDR + 84)
 
-typedef struct _PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS {
-	UCHAR ucI2CSpeed;
-	union {
-		UCHAR ucRegIndex;
-		UCHAR ucStatus;
+typedef struct _PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS
+{
+	UCHAR   ucI2CSpeed;
+ 	union
+	{
+   UCHAR ucRegIndex;
+   UCHAR ucStatus;
 	};
-	USHORT lpI2CDataOut;
-	UCHAR ucFlag;
-	UCHAR ucTransBytes;
-	UCHAR ucSlaveAddr;
-	UCHAR ucLineNumber;
-} PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS;
+	USHORT  lpI2CDataOut;
+  UCHAR   ucFlag;               
+  UCHAR   ucTransBytes;
+  UCHAR   ucSlaveAddr;
+  UCHAR   ucLineNumber;
+}PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS;
 
 #define PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION       PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS
 
-/* ucFlag */
+//ucFlag
 #define HW_I2C_WRITE        1
 #define HW_I2C_READ         0
+#define I2C_2BYTE_ADDR      0x02
 
+typedef struct _SET_HWBLOCK_INSTANCE_PARAMETER_V2
+{
+   UCHAR ucHWBlkInst;                // HW block instance, 0, 1, 2, ...
+   UCHAR ucReserved[3]; 
+}SET_HWBLOCK_INSTANCE_PARAMETER_V2;
+
+#define HWBLKINST_INSTANCE_MASK       0x07
+#define HWBLKINST_HWBLK_MASK          0xF0
+#define HWBLKINST_HWBLK_SHIFT         0x04
+
+//ucHWBlock
+#define SELECT_DISP_ENGINE            0
+#define SELECT_DISP_PLL               1
+#define SELECT_DCIO_UNIPHY_LINK0      2
+#define SELECT_DCIO_UNIPHY_LINK1      3
+#define SELECT_DCIO_IMPCAL            4
+#define SELECT_DCIO_DIG               6
+#define SELECT_CRTC_PIXEL_RATE        7
+
+/****************************************************************************/	
+//Portion VI: Definitinos for vbios MC scratch registers that driver used
 /****************************************************************************/
-/* Portion VI: Definitinos being oboselete */
+
+#define MC_MISC0__MEMORY_TYPE_MASK    0xF0000000
+#define MC_MISC0__MEMORY_TYPE__GDDR1  0x10000000
+#define MC_MISC0__MEMORY_TYPE__DDR2   0x20000000
+#define MC_MISC0__MEMORY_TYPE__GDDR3  0x30000000
+#define MC_MISC0__MEMORY_TYPE__GDDR4  0x40000000
+#define MC_MISC0__MEMORY_TYPE__GDDR5  0x50000000
+#define MC_MISC0__MEMORY_TYPE__DDR3   0xB0000000
+
+/****************************************************************************/	
+//Portion VI: Definitinos being oboselete
 /****************************************************************************/
 
-/* ========================================================================================== */
-/* Remove the definitions below when driver is ready! */
-typedef struct _ATOM_DAC_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	USHORT usMaxFrequency;	/*  in 10kHz unit */
-	USHORT usReserved;
-} ATOM_DAC_INFO;
+//==========================================================================================
+//Remove the definitions below when driver is ready!
+typedef struct _ATOM_DAC_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  USHORT                   usMaxFrequency;      // in 10kHz unit
+  USHORT                   usReserved;
+}ATOM_DAC_INFO;
 
-typedef struct _COMPASSIONATE_DATA {
-	ATOM_COMMON_TABLE_HEADER sHeader;
 
-	/* ==============================  DAC1 portion */
-	UCHAR ucDAC1_BG_Adjustment;
-	UCHAR ucDAC1_DAC_Adjustment;
-	USHORT usDAC1_FORCE_Data;
-	/* ==============================  DAC2 portion */
-	UCHAR ucDAC2_CRT2_BG_Adjustment;
-	UCHAR ucDAC2_CRT2_DAC_Adjustment;
-	USHORT usDAC2_CRT2_FORCE_Data;
-	USHORT usDAC2_CRT2_MUX_RegisterIndex;
-	UCHAR ucDAC2_CRT2_MUX_RegisterInfo;	/* Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low */
-	UCHAR ucDAC2_NTSC_BG_Adjustment;
-	UCHAR ucDAC2_NTSC_DAC_Adjustment;
-	USHORT usDAC2_TV1_FORCE_Data;
-	USHORT usDAC2_TV1_MUX_RegisterIndex;
-	UCHAR ucDAC2_TV1_MUX_RegisterInfo;	/* Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low */
-	UCHAR ucDAC2_CV_BG_Adjustment;
-	UCHAR ucDAC2_CV_DAC_Adjustment;
-	USHORT usDAC2_CV_FORCE_Data;
-	USHORT usDAC2_CV_MUX_RegisterIndex;
-	UCHAR ucDAC2_CV_MUX_RegisterInfo;	/* Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low */
-	UCHAR ucDAC2_PAL_BG_Adjustment;
-	UCHAR ucDAC2_PAL_DAC_Adjustment;
-	USHORT usDAC2_TV2_FORCE_Data;
-} COMPASSIONATE_DATA;
+typedef struct  _COMPASSIONATE_DATA           
+{
+  ATOM_COMMON_TABLE_HEADER sHeader; 
+
+  //==============================  DAC1 portion
+  UCHAR   ucDAC1_BG_Adjustment;
+  UCHAR   ucDAC1_DAC_Adjustment;
+  USHORT  usDAC1_FORCE_Data;
+  //==============================  DAC2 portion
+  UCHAR   ucDAC2_CRT2_BG_Adjustment;
+  UCHAR   ucDAC2_CRT2_DAC_Adjustment;
+  USHORT  usDAC2_CRT2_FORCE_Data;
+  USHORT  usDAC2_CRT2_MUX_RegisterIndex;
+  UCHAR   ucDAC2_CRT2_MUX_RegisterInfo;     //Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low
+  UCHAR   ucDAC2_NTSC_BG_Adjustment;
+  UCHAR   ucDAC2_NTSC_DAC_Adjustment;
+  USHORT  usDAC2_TV1_FORCE_Data;
+  USHORT  usDAC2_TV1_MUX_RegisterIndex;
+  UCHAR   ucDAC2_TV1_MUX_RegisterInfo;      //Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low
+  UCHAR   ucDAC2_CV_BG_Adjustment;
+  UCHAR   ucDAC2_CV_DAC_Adjustment;
+  USHORT  usDAC2_CV_FORCE_Data;
+  USHORT  usDAC2_CV_MUX_RegisterIndex;
+  UCHAR   ucDAC2_CV_MUX_RegisterInfo;       //Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low
+  UCHAR   ucDAC2_PAL_BG_Adjustment;
+  UCHAR   ucDAC2_PAL_DAC_Adjustment;
+  USHORT  usDAC2_TV2_FORCE_Data;
+}COMPASSIONATE_DATA;
 
 /****************************Supported Device Info Table Definitions**********************/
-/*   ucConnectInfo: */
-/*     [7:4] - connector type */
-/*       = 1   - VGA connector */
-/*       = 2   - DVI-I */
-/*       = 3   - DVI-D */
-/*       = 4   - DVI-A */
-/*       = 5   - SVIDEO */
-/*       = 6   - COMPOSITE */
-/*       = 7   - LVDS */
-/*       = 8   - DIGITAL LINK */
-/*       = 9   - SCART */
-/*       = 0xA - HDMI_type A */
-/*       = 0xB - HDMI_type B */
-/*       = 0xE - Special case1 (DVI+DIN) */
-/*       Others=TBD */
-/*     [3:0] - DAC Associated */
-/*       = 0   - no DAC */
-/*       = 1   - DACA */
-/*       = 2   - DACB */
-/*       = 3   - External DAC */
-/*       Others=TBD */
-/*  */
+//  ucConnectInfo:
+//    [7:4] - connector type
+//      = 1   - VGA connector   
+//      = 2   - DVI-I
+//      = 3   - DVI-D
+//      = 4   - DVI-A
+//      = 5   - SVIDEO
+//      = 6   - COMPOSITE
+//      = 7   - LVDS
+//      = 8   - DIGITAL LINK
+//      = 9   - SCART
+//      = 0xA - HDMI_type A
+//      = 0xB - HDMI_type B
+//      = 0xE - Special case1 (DVI+DIN)
+//      Others=TBD
+//    [3:0] - DAC Associated
+//      = 0   - no DAC
+//      = 1   - DACA
+//      = 2   - DACB
+//      = 3   - External DAC
+//      Others=TBD
+//    
 
-typedef struct _ATOM_CONNECTOR_INFO {
+typedef struct _ATOM_CONNECTOR_INFO
+{
 #if ATOM_BIG_ENDIAN
-	UCHAR bfConnectorType:4;
-	UCHAR bfAssociatedDAC:4;
+  UCHAR   bfConnectorType:4;
+  UCHAR   bfAssociatedDAC:4;
 #else
-	UCHAR bfAssociatedDAC:4;
-	UCHAR bfConnectorType:4;
+  UCHAR   bfAssociatedDAC:4;
+  UCHAR   bfConnectorType:4;
 #endif
-} ATOM_CONNECTOR_INFO;
+}ATOM_CONNECTOR_INFO;
 
-typedef union _ATOM_CONNECTOR_INFO_ACCESS {
-	ATOM_CONNECTOR_INFO sbfAccess;
-	UCHAR ucAccess;
-} ATOM_CONNECTOR_INFO_ACCESS;
+typedef union _ATOM_CONNECTOR_INFO_ACCESS
+{
+  ATOM_CONNECTOR_INFO sbfAccess;
+  UCHAR               ucAccess;
+}ATOM_CONNECTOR_INFO_ACCESS;
 
-typedef struct _ATOM_CONNECTOR_INFO_I2C {
-	ATOM_CONNECTOR_INFO_ACCESS sucConnectorInfo;
-	ATOM_I2C_ID_CONFIG_ACCESS sucI2cId;
-} ATOM_CONNECTOR_INFO_I2C;
+typedef struct _ATOM_CONNECTOR_INFO_I2C
+{
+  ATOM_CONNECTOR_INFO_ACCESS sucConnectorInfo;
+  ATOM_I2C_ID_CONFIG_ACCESS  sucI2cId;
+}ATOM_CONNECTOR_INFO_I2C;
 
-typedef struct _ATOM_SUPPORTED_DEVICES_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	USHORT usDeviceSupport;
-	ATOM_CONNECTOR_INFO_I2C asConnInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO];
-} ATOM_SUPPORTED_DEVICES_INFO;
+
+typedef struct _ATOM_SUPPORTED_DEVICES_INFO
+{ 
+  ATOM_COMMON_TABLE_HEADER	sHeader;
+  USHORT                    usDeviceSupport;
+  ATOM_CONNECTOR_INFO_I2C   asConnInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO];
+}ATOM_SUPPORTED_DEVICES_INFO;
 
 #define NO_INT_SRC_MAPPED       0xFF
 
-typedef struct _ATOM_CONNECTOR_INC_SRC_BITMAP {
-	UCHAR ucIntSrcBitmap;
-} ATOM_CONNECTOR_INC_SRC_BITMAP;
+typedef struct _ATOM_CONNECTOR_INC_SRC_BITMAP
+{
+  UCHAR   ucIntSrcBitmap;
+}ATOM_CONNECTOR_INC_SRC_BITMAP;
 
-typedef struct _ATOM_SUPPORTED_DEVICES_INFO_2 {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	USHORT usDeviceSupport;
-	ATOM_CONNECTOR_INFO_I2C asConnInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_2];
-	ATOM_CONNECTOR_INC_SRC_BITMAP
-	    asIntSrcInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_2];
-} ATOM_SUPPORTED_DEVICES_INFO_2;
+typedef struct _ATOM_SUPPORTED_DEVICES_INFO_2
+{ 
+  ATOM_COMMON_TABLE_HEADER      sHeader;
+  USHORT                        usDeviceSupport;
+  ATOM_CONNECTOR_INFO_I2C       asConnInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_2];
+  ATOM_CONNECTOR_INC_SRC_BITMAP asIntSrcInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_2];
+}ATOM_SUPPORTED_DEVICES_INFO_2;
 
-typedef struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	USHORT usDeviceSupport;
-	ATOM_CONNECTOR_INFO_I2C asConnInfo[ATOM_MAX_SUPPORTED_DEVICE];
-	ATOM_CONNECTOR_INC_SRC_BITMAP asIntSrcInfo[ATOM_MAX_SUPPORTED_DEVICE];
-} ATOM_SUPPORTED_DEVICES_INFO_2d1;
+typedef struct _ATOM_SUPPORTED_DEVICES_INFO_2d1
+{ 
+  ATOM_COMMON_TABLE_HEADER      sHeader;
+  USHORT                        usDeviceSupport;
+  ATOM_CONNECTOR_INFO_I2C       asConnInfo[ATOM_MAX_SUPPORTED_DEVICE];
+  ATOM_CONNECTOR_INC_SRC_BITMAP asIntSrcInfo[ATOM_MAX_SUPPORTED_DEVICE];
+}ATOM_SUPPORTED_DEVICES_INFO_2d1;
 
 #define ATOM_SUPPORTED_DEVICES_INFO_LAST ATOM_SUPPORTED_DEVICES_INFO_2d1
 
-typedef struct _ATOM_MISC_CONTROL_INFO {
-	USHORT usFrequency;
-	UCHAR ucPLL_ChargePump;	/*  PLL charge-pump gain control */
-	UCHAR ucPLL_DutyCycle;	/*  PLL duty cycle control */
-	UCHAR ucPLL_VCO_Gain;	/*  PLL VCO gain control */
-	UCHAR ucPLL_VoltageSwing;	/*  PLL driver voltage swing control */
-} ATOM_MISC_CONTROL_INFO;
+
+
+typedef struct _ATOM_MISC_CONTROL_INFO
+{
+   USHORT usFrequency;
+   UCHAR  ucPLL_ChargePump;				                // PLL charge-pump gain control
+   UCHAR  ucPLL_DutyCycle;				                // PLL duty cycle control
+   UCHAR  ucPLL_VCO_Gain;				                  // PLL VCO gain control
+   UCHAR  ucPLL_VoltageSwing;			                // PLL driver voltage swing control
+}ATOM_MISC_CONTROL_INFO;  
+
 
 #define ATOM_MAX_MISC_INFO       4
 
-typedef struct _ATOM_TMDS_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	USHORT usMaxFrequency;	/*  in 10Khz */
-	ATOM_MISC_CONTROL_INFO asMiscInfo[ATOM_MAX_MISC_INFO];
-} ATOM_TMDS_INFO;
+typedef struct _ATOM_TMDS_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  USHORT							usMaxFrequency;             // in 10Khz
+  ATOM_MISC_CONTROL_INFO				asMiscInfo[ATOM_MAX_MISC_INFO];
+}ATOM_TMDS_INFO;
 
-typedef struct _ATOM_ENCODER_ANALOG_ATTRIBUTE {
-	UCHAR ucTVStandard;	/* Same as TV standards defined above, */
-	UCHAR ucPadding[1];
-} ATOM_ENCODER_ANALOG_ATTRIBUTE;
 
-typedef struct _ATOM_ENCODER_DIGITAL_ATTRIBUTE {
-	UCHAR ucAttribute;	/* Same as other digital encoder attributes defined above */
-	UCHAR ucPadding[1];
-} ATOM_ENCODER_DIGITAL_ATTRIBUTE;
+typedef struct _ATOM_ENCODER_ANALOG_ATTRIBUTE
+{
+  UCHAR ucTVStandard;     //Same as TV standards defined above, 
+  UCHAR ucPadding[1];
+}ATOM_ENCODER_ANALOG_ATTRIBUTE;
 
-typedef union _ATOM_ENCODER_ATTRIBUTE {
-	ATOM_ENCODER_ANALOG_ATTRIBUTE sAlgAttrib;
-	ATOM_ENCODER_DIGITAL_ATTRIBUTE sDigAttrib;
-} ATOM_ENCODER_ATTRIBUTE;
+typedef struct _ATOM_ENCODER_DIGITAL_ATTRIBUTE
+{
+  UCHAR ucAttribute;      //Same as other digital encoder attributes defined above
+  UCHAR ucPadding[1];		
+}ATOM_ENCODER_DIGITAL_ATTRIBUTE;
 
-typedef struct _DVO_ENCODER_CONTROL_PARAMETERS {
-	USHORT usPixelClock;
-	USHORT usEncoderID;
-	UCHAR ucDeviceType;	/* Use ATOM_DEVICE_xxx1_Index to indicate device type only. */
-	UCHAR ucAction;		/* ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT */
-	ATOM_ENCODER_ATTRIBUTE usDevAttr;
-} DVO_ENCODER_CONTROL_PARAMETERS;
+typedef union _ATOM_ENCODER_ATTRIBUTE
+{
+  ATOM_ENCODER_ANALOG_ATTRIBUTE sAlgAttrib;
+  ATOM_ENCODER_DIGITAL_ATTRIBUTE sDigAttrib;
+}ATOM_ENCODER_ATTRIBUTE;
+
+
+typedef struct _DVO_ENCODER_CONTROL_PARAMETERS
+{
+  USHORT usPixelClock; 
+  USHORT usEncoderID; 
+  UCHAR  ucDeviceType;												//Use ATOM_DEVICE_xxx1_Index to indicate device type only.	
+  UCHAR  ucAction;														//ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT
+  ATOM_ENCODER_ATTRIBUTE usDevAttr;     		
+}DVO_ENCODER_CONTROL_PARAMETERS;
+
+typedef struct _DVO_ENCODER_CONTROL_PS_ALLOCATION
+{                               
+  DVO_ENCODER_CONTROL_PARAMETERS    sDVOEncoder;
+  WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION      sReserved;     //Caller doesn't need to init this portion
+}DVO_ENCODER_CONTROL_PS_ALLOCATION;
 
-typedef struct _DVO_ENCODER_CONTROL_PS_ALLOCATION {
-	DVO_ENCODER_CONTROL_PARAMETERS sDVOEncoder;
-	WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved;	/* Caller doesn't need to init this portion */
-} DVO_ENCODER_CONTROL_PS_ALLOCATION;
 
 #define ATOM_XTMDS_ASIC_SI164_ID        1
 #define ATOM_XTMDS_ASIC_SI178_ID        2
@@ -4526,27 +5539,30 @@ typedef struct _DVO_ENCODER_CONTROL_PS_A
 #define ATOM_XTMDS_SUPPORTED_DUALLINK   0x00000002
 #define ATOM_XTMDS_MVPU_FPGA            0x00000004
 
-typedef struct _ATOM_XTMDS_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	USHORT usSingleLinkMaxFrequency;
-	ATOM_I2C_ID_CONFIG_ACCESS sucI2cId;	/* Point the ID on which I2C is used to control external chip */
-	UCHAR ucXtransimitterID;
-	UCHAR ucSupportedLink;	/*  Bit field, bit0=1, single link supported;bit1=1,dual link supported */
-	UCHAR ucSequnceAlterID;	/*  Even with the same external TMDS asic, it's possible that the program seqence alters */
-	/*  due to design. This ID is used to alert driver that the sequence is not "standard"! */
-	UCHAR ucMasterAddress;	/*  Address to control Master xTMDS Chip */
-	UCHAR ucSlaveAddress;	/*  Address to control Slave xTMDS Chip */
-} ATOM_XTMDS_INFO;
+                           
+typedef struct _ATOM_XTMDS_INFO
+{
+  ATOM_COMMON_TABLE_HEADER   sHeader;  
+  USHORT                     usSingleLinkMaxFrequency; 
+  ATOM_I2C_ID_CONFIG_ACCESS  sucI2cId;           //Point the ID on which I2C is used to control external chip
+  UCHAR                      ucXtransimitterID;          
+  UCHAR                      ucSupportedLink;    // Bit field, bit0=1, single link supported;bit1=1,dual link supported
+  UCHAR                      ucSequnceAlterID;   // Even with the same external TMDS asic, it's possible that the program seqence alters 
+                                                 // due to design. This ID is used to alert driver that the sequence is not "standard"!              
+  UCHAR                      ucMasterAddress;    // Address to control Master xTMDS Chip
+  UCHAR                      ucSlaveAddress;     // Address to control Slave xTMDS Chip
+}ATOM_XTMDS_INFO;
 
-typedef struct _DFP_DPMS_STATUS_CHANGE_PARAMETERS {
-	UCHAR ucEnable;		/*  ATOM_ENABLE=On or ATOM_DISABLE=Off */
-	UCHAR ucDevice;		/*  ATOM_DEVICE_DFP1_INDEX.... */
-	UCHAR ucPadding[2];
-} DFP_DPMS_STATUS_CHANGE_PARAMETERS;
+typedef struct _DFP_DPMS_STATUS_CHANGE_PARAMETERS
+{  
+  UCHAR ucEnable;                     // ATOM_ENABLE=On or ATOM_DISABLE=Off
+  UCHAR ucDevice;                     // ATOM_DEVICE_DFP1_INDEX....
+  UCHAR ucPadding[2];             
+}DFP_DPMS_STATUS_CHANGE_PARAMETERS;
 
 /****************************Legacy Power Play Table Definitions **********************/
 
-/* Definitions for ulPowerPlayMiscInfo */
+//Definitions for ulPowerPlayMiscInfo
 #define ATOM_PM_MISCINFO_SPLIT_CLOCK                     0x00000000L
 #define ATOM_PM_MISCINFO_USING_MCLK_SRC                  0x00000001L
 #define ATOM_PM_MISCINFO_USING_SCLK_SRC                  0x00000002L
@@ -4558,8 +5574,8 @@ typedef struct _DFP_DPMS_STATUS_CHANGE_P
 
 #define ATOM_PM_MISCINFO_ENGINE_CLOCK_CONTRL_EN          0x00000020L
 #define ATOM_PM_MISCINFO_MEMORY_CLOCK_CONTRL_EN          0x00000040L
-#define ATOM_PM_MISCINFO_PROGRAM_VOLTAGE                 0x00000080L	/* When this bit set, ucVoltageDropIndex is not an index for GPIO pin, but a voltage ID that SW needs program */
-
+#define ATOM_PM_MISCINFO_PROGRAM_VOLTAGE                 0x00000080L  //When this bit set, ucVoltageDropIndex is not an index for GPIO pin, but a voltage ID that SW needs program  
+ 
 #define ATOM_PM_MISCINFO_ASIC_REDUCED_SPEED_SCLK_EN      0x00000100L
 #define ATOM_PM_MISCINFO_ASIC_DYNAMIC_VOLTAGE_EN         0x00000200L
 #define ATOM_PM_MISCINFO_ASIC_SLEEP_MODE_EN              0x00000400L
@@ -4569,22 +5585,22 @@ typedef struct _DFP_DPMS_STATUS_CHANGE_P
 #define ATOM_PM_MISCINFO_LOW_LCD_REFRESH_RATE            0x00004000L
 
 #define ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE             0x00008000L
-#define ATOM_PM_MISCINFO_OVER_CLOCK_MODE                 0x00010000L
+#define ATOM_PM_MISCINFO_OVER_CLOCK_MODE                 0x00010000L 
 #define ATOM_PM_MISCINFO_OVER_DRIVE_MODE                 0x00020000L
 #define ATOM_PM_MISCINFO_POWER_SAVING_MODE               0x00040000L
 #define ATOM_PM_MISCINFO_THERMAL_DIODE_MODE              0x00080000L
 
-#define ATOM_PM_MISCINFO_FRAME_MODULATION_MASK           0x00300000L	/* 0-FM Disable, 1-2 level FM, 2-4 level FM, 3-Reserved */
-#define ATOM_PM_MISCINFO_FRAME_MODULATION_SHIFT          20
+#define ATOM_PM_MISCINFO_FRAME_MODULATION_MASK           0x00300000L  //0-FM Disable, 1-2 level FM, 2-4 level FM, 3-Reserved
+#define ATOM_PM_MISCINFO_FRAME_MODULATION_SHIFT          20 
 
 #define ATOM_PM_MISCINFO_DYN_CLK_3D_IDLE                 0x00400000L
 #define ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_2      0x00800000L
 #define ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_4      0x01000000L
-#define ATOM_PM_MISCINFO_DYNAMIC_HDP_BLOCK_EN            0x02000000L	/* When set, Dynamic */
-#define ATOM_PM_MISCINFO_DYNAMIC_MC_HOST_BLOCK_EN        0x04000000L	/* When set, Dynamic */
-#define ATOM_PM_MISCINFO_3D_ACCELERATION_EN              0x08000000L	/* When set, This mode is for acceleated 3D mode */
+#define ATOM_PM_MISCINFO_DYNAMIC_HDP_BLOCK_EN            0x02000000L  //When set, Dynamic 
+#define ATOM_PM_MISCINFO_DYNAMIC_MC_HOST_BLOCK_EN        0x04000000L  //When set, Dynamic
+#define ATOM_PM_MISCINFO_3D_ACCELERATION_EN              0x08000000L  //When set, This mode is for acceleated 3D mode
 
-#define ATOM_PM_MISCINFO_POWERPLAY_SETTINGS_GROUP_MASK   0x70000000L	/* 1-Optimal Battery Life Group, 2-High Battery, 3-Balanced, 4-High Performance, 5- Optimal Performance (Default state with Default clocks) */
+#define ATOM_PM_MISCINFO_POWERPLAY_SETTINGS_GROUP_MASK   0x70000000L  //1-Optimal Battery Life Group, 2-High Battery, 3-Balanced, 4-High Performance, 5- Optimal Performance (Default state with Default clocks) 
 #define ATOM_PM_MISCINFO_POWERPLAY_SETTINGS_GROUP_SHIFT  28
 #define ATOM_PM_MISCINFO_ENABLE_BACK_BIAS                0x80000000L
 
@@ -4594,55 +5610,59 @@ typedef struct _DFP_DPMS_STATUS_CHANGE_P
 #define ATOM_PM_MISCINFO2_FS3D_OVERDRIVE_INFO            0x00000008L
 #define ATOM_PM_MISCINFO2_FORCEDLOWPWR_MODE              0x00000010L
 #define ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN       0x00000020L
-#define ATOM_PM_MISCINFO2_VIDEO_PLAYBACK_CAPABLE         0x00000040L	/* If this bit is set in multi-pp mode, then driver will pack up one with the minior power consumption. */
-								      /* If it's not set in any pp mode, driver will use its default logic to pick a pp mode in video playback */
+#define ATOM_PM_MISCINFO2_VIDEO_PLAYBACK_CAPABLE         0x00000040L  //If this bit is set in multi-pp mode, then driver will pack up one with the minior power consumption. 
+                                                                      //If it's not set in any pp mode, driver will use its default logic to pick a pp mode in video playback
 #define ATOM_PM_MISCINFO2_NOT_VALID_ON_DC                0x00000080L
 #define ATOM_PM_MISCINFO2_STUTTER_MODE_EN                0x00000100L
-#define ATOM_PM_MISCINFO2_UVD_SUPPORT_MODE               0x00000200L
+#define ATOM_PM_MISCINFO2_UVD_SUPPORT_MODE               0x00000200L 
 
-/* ucTableFormatRevision=1 */
-/* ucTableContentRevision=1 */
-typedef struct _ATOM_POWERMODE_INFO {
-	ULONG ulMiscInfo;	/* The power level should be arranged in ascending order */
-	ULONG ulReserved1;	/*  must set to 0 */
-	ULONG ulReserved2;	/*  must set to 0 */
-	USHORT usEngineClock;
-	USHORT usMemoryClock;
-	UCHAR ucVoltageDropIndex;	/*  index to GPIO table */
-	UCHAR ucSelectedPanel_RefreshRate;	/*  panel refresh rate */
-	UCHAR ucMinTemperature;
-	UCHAR ucMaxTemperature;
-	UCHAR ucNumPciELanes;	/*  number of PCIE lanes */
-} ATOM_POWERMODE_INFO;
+//ucTableFormatRevision=1
+//ucTableContentRevision=1
+typedef struct  _ATOM_POWERMODE_INFO
+{
+  ULONG     ulMiscInfo;                 //The power level should be arranged in ascending order
+  ULONG     ulReserved1;                // must set to 0
+  ULONG     ulReserved2;                // must set to 0
+  USHORT    usEngineClock;
+  USHORT    usMemoryClock;
+  UCHAR     ucVoltageDropIndex;         // index to GPIO table
+  UCHAR     ucSelectedPanel_RefreshRate;// panel refresh rate
+  UCHAR     ucMinTemperature;
+  UCHAR     ucMaxTemperature;
+  UCHAR     ucNumPciELanes;             // number of PCIE lanes
+}ATOM_POWERMODE_INFO;
 
-/* ucTableFormatRevision=2 */
-/* ucTableContentRevision=1 */
-typedef struct _ATOM_POWERMODE_INFO_V2 {
-	ULONG ulMiscInfo;	/* The power level should be arranged in ascending order */
-	ULONG ulMiscInfo2;
-	ULONG ulEngineClock;
-	ULONG ulMemoryClock;
-	UCHAR ucVoltageDropIndex;	/*  index to GPIO table */
-	UCHAR ucSelectedPanel_RefreshRate;	/*  panel refresh rate */
-	UCHAR ucMinTemperature;
-	UCHAR ucMaxTemperature;
-	UCHAR ucNumPciELanes;	/*  number of PCIE lanes */
-} ATOM_POWERMODE_INFO_V2;
+//ucTableFormatRevision=2
+//ucTableContentRevision=1
+typedef struct  _ATOM_POWERMODE_INFO_V2
+{
+  ULONG     ulMiscInfo;                 //The power level should be arranged in ascending order
+  ULONG     ulMiscInfo2;                
+  ULONG     ulEngineClock;                
+  ULONG     ulMemoryClock;
+  UCHAR     ucVoltageDropIndex;         // index to GPIO table
+  UCHAR     ucSelectedPanel_RefreshRate;// panel refresh rate
+  UCHAR     ucMinTemperature;
+  UCHAR     ucMaxTemperature;
+  UCHAR     ucNumPciELanes;             // number of PCIE lanes
+}ATOM_POWERMODE_INFO_V2;
+
+//ucTableFormatRevision=2
+//ucTableContentRevision=2
+typedef struct  _ATOM_POWERMODE_INFO_V3
+{
+  ULONG     ulMiscInfo;                 //The power level should be arranged in ascending order
+  ULONG     ulMiscInfo2;                
+  ULONG     ulEngineClock;                
+  ULONG     ulMemoryClock;
+  UCHAR     ucVoltageDropIndex;         // index to Core (VDDC) votage table
+  UCHAR     ucSelectedPanel_RefreshRate;// panel refresh rate
+  UCHAR     ucMinTemperature;
+  UCHAR     ucMaxTemperature;
+  UCHAR     ucNumPciELanes;             // number of PCIE lanes
+  UCHAR     ucVDDCI_VoltageDropIndex;   // index to VDDCI votage table
+}ATOM_POWERMODE_INFO_V3;
 
-/* ucTableFormatRevision=2 */
-/* ucTableContentRevision=2 */
-typedef struct _ATOM_POWERMODE_INFO_V3 {
-	ULONG ulMiscInfo;	/* The power level should be arranged in ascending order */
-	ULONG ulMiscInfo2;
-	ULONG ulEngineClock;
-	ULONG ulMemoryClock;
-	UCHAR ucVoltageDropIndex;	/*  index to Core (VDDC) votage table */
-	UCHAR ucSelectedPanel_RefreshRate;	/*  panel refresh rate */
-	UCHAR ucMinTemperature;
-	UCHAR ucMaxTemperature;
-	UCHAR ucNumPciELanes;	/*  number of PCIE lanes */
-	UCHAR ucVDDCI_VoltageDropIndex;	/*  index to VDDCI votage table */
-} ATOM_POWERMODE_INFO_V3;
 
 #define ATOM_MAX_NUMBEROF_POWER_BLOCK  8
 
@@ -4655,40 +5675,44 @@ typedef struct _ATOM_POWERMODE_INFO_V3 {
 #define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_MUA6649   0x04
 #define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_LM64      0x05
 #define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_F75375    0x06
-#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_ASC7512   0x07	/*  Andigilog */
+#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_ASC7512   0x07	// Andigilog
 
-typedef struct _ATOM_POWERPLAY_INFO {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	UCHAR ucOverdriveThermalController;
-	UCHAR ucOverdriveI2cLine;
-	UCHAR ucOverdriveIntBitmap;
-	UCHAR ucOverdriveControllerAddress;
-	UCHAR ucSizeOfPowerModeEntry;
-	UCHAR ucNumOfPowerModeEntries;
-	ATOM_POWERMODE_INFO asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK];
-} ATOM_POWERPLAY_INFO;
 
-typedef struct _ATOM_POWERPLAY_INFO_V2 {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	UCHAR ucOverdriveThermalController;
-	UCHAR ucOverdriveI2cLine;
-	UCHAR ucOverdriveIntBitmap;
-	UCHAR ucOverdriveControllerAddress;
-	UCHAR ucSizeOfPowerModeEntry;
-	UCHAR ucNumOfPowerModeEntries;
-	ATOM_POWERMODE_INFO_V2 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK];
-} ATOM_POWERPLAY_INFO_V2;
+typedef struct  _ATOM_POWERPLAY_INFO
+{
+  ATOM_COMMON_TABLE_HEADER	sHeader; 
+  UCHAR    ucOverdriveThermalController;
+  UCHAR    ucOverdriveI2cLine;
+  UCHAR    ucOverdriveIntBitmap;
+  UCHAR    ucOverdriveControllerAddress;
+  UCHAR    ucSizeOfPowerModeEntry;
+  UCHAR    ucNumOfPowerModeEntries;
+  ATOM_POWERMODE_INFO asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK];
+}ATOM_POWERPLAY_INFO;
 
-typedef struct _ATOM_POWERPLAY_INFO_V3 {
-	ATOM_COMMON_TABLE_HEADER sHeader;
-	UCHAR ucOverdriveThermalController;
-	UCHAR ucOverdriveI2cLine;
-	UCHAR ucOverdriveIntBitmap;
-	UCHAR ucOverdriveControllerAddress;
-	UCHAR ucSizeOfPowerModeEntry;
-	UCHAR ucNumOfPowerModeEntries;
-	ATOM_POWERMODE_INFO_V3 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK];
-} ATOM_POWERPLAY_INFO_V3;
+typedef struct  _ATOM_POWERPLAY_INFO_V2
+{
+  ATOM_COMMON_TABLE_HEADER	sHeader; 
+  UCHAR    ucOverdriveThermalController;
+  UCHAR    ucOverdriveI2cLine;
+  UCHAR    ucOverdriveIntBitmap;
+  UCHAR    ucOverdriveControllerAddress;
+  UCHAR    ucSizeOfPowerModeEntry;
+  UCHAR    ucNumOfPowerModeEntries;
+  ATOM_POWERMODE_INFO_V2 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK];
+}ATOM_POWERPLAY_INFO_V2;
+  
+typedef struct  _ATOM_POWERPLAY_INFO_V3
+{
+  ATOM_COMMON_TABLE_HEADER	sHeader; 
+  UCHAR    ucOverdriveThermalController;
+  UCHAR    ucOverdriveI2cLine;
+  UCHAR    ucOverdriveIntBitmap;
+  UCHAR    ucOverdriveControllerAddress;
+  UCHAR    ucSizeOfPowerModeEntry;
+  UCHAR    ucNumOfPowerModeEntries;
+  ATOM_POWERMODE_INFO_V3 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK];
+}ATOM_POWERPLAY_INFO_V3;
 
 /* New PPlib */
 /**************************************************************************/
@@ -4873,40 +5897,42 @@ typedef struct _ATOM_PPLIB_RS780_CLOCK_I
       UCHAR  ucMaxHTLinkWidth;            // From SBIOS - {2, 4, 8, 16}
       UCHAR  ucMinHTLinkWidth;            // From SBIOS - {2, 4, 8, 16}. Effective only if CDLW enabled. Minimum down stream width could be bigger as display BW requriement.
       USHORT usHTLinkFreq;                // See definition ATOM_PPLIB_RS780_HTLINKFREQ_xxx or in MHz(>=200).
-      ULONG  ulFlags;
+      ULONG  ulFlags; 
 } ATOM_PPLIB_RS780_CLOCK_INFO;
 
-#define ATOM_PPLIB_RS780_VOLTAGE_NONE       0
-#define ATOM_PPLIB_RS780_VOLTAGE_LOW        1
-#define ATOM_PPLIB_RS780_VOLTAGE_HIGH       2
-#define ATOM_PPLIB_RS780_VOLTAGE_VARIABLE   3
+#define ATOM_PPLIB_RS780_VOLTAGE_NONE       0 
+#define ATOM_PPLIB_RS780_VOLTAGE_LOW        1 
+#define ATOM_PPLIB_RS780_VOLTAGE_HIGH       2 
+#define ATOM_PPLIB_RS780_VOLTAGE_VARIABLE   3 
 
 #define ATOM_PPLIB_RS780_SPMCLK_NONE        0   // We cannot change the side port memory clock, leave it as it is.
 #define ATOM_PPLIB_RS780_SPMCLK_LOW         1
 #define ATOM_PPLIB_RS780_SPMCLK_HIGH        2
 
-#define ATOM_PPLIB_RS780_HTLINKFREQ_NONE       0
-#define ATOM_PPLIB_RS780_HTLINKFREQ_LOW        1
-#define ATOM_PPLIB_RS780_HTLINKFREQ_HIGH       2
+#define ATOM_PPLIB_RS780_HTLINKFREQ_NONE       0 
+#define ATOM_PPLIB_RS780_HTLINKFREQ_LOW        1 
+#define ATOM_PPLIB_RS780_HTLINKFREQ_HIGH       2 
 
 /**************************************************************************/
 
-/*  Following definitions are for compatiblity issue in different SW components. */
+
+// Following definitions are for compatiblity issue in different SW components. 
 #define ATOM_MASTER_DATA_TABLE_REVISION   0x01
-#define Object_Info												Object_Header
+#define Object_Info												Object_Header			
 #define	AdjustARB_SEQ											MC_InitParameter
 #define	VRAM_GPIO_DetectionInfo						VoltageObjectInfo
-#define	ASIC_VDDCI_Info                   ASIC_ProfilingInfo
+#define	ASIC_VDDCI_Info                   ASIC_ProfilingInfo														
 #define ASIC_MVDDQ_Info										MemoryTrainingInfo
-#define SS_Info                           PPLL_SS_Info
+#define SS_Info                           PPLL_SS_Info                      
 #define ASIC_MVDDC_Info                   ASIC_InternalSS_Info
 #define DispDevicePriorityInfo						SaveRestoreInfo
 #define DispOutInfo												TV_VideoMode
 
+
 #define ATOM_ENCODER_OBJECT_TABLE         ATOM_OBJECT_TABLE
 #define ATOM_CONNECTOR_OBJECT_TABLE       ATOM_OBJECT_TABLE
 
-/* New device naming, remove them when both DAL/VBIOS is ready */
+//New device naming, remove them when both DAL/VBIOS is ready
 #define DFP2I_OUTPUT_CONTROL_PARAMETERS    CRT1_OUTPUT_CONTROL_PARAMETERS
 #define DFP2I_OUTPUT_CONTROL_PS_ALLOCATION DFP2I_OUTPUT_CONTROL_PARAMETERS
 
@@ -4921,7 +5947,7 @@ typedef struct _ATOM_PPLIB_RS780_CLOCK_I
 
 #define ATOM_DEVICE_DFP1I_INDEX            ATOM_DEVICE_DFP1_INDEX
 #define ATOM_DEVICE_DFP1X_INDEX            ATOM_DEVICE_DFP2_INDEX
-
+ 
 #define ATOM_DEVICE_DFP2I_INDEX            0x00000009
 #define ATOM_DEVICE_DFP2I_SUPPORT          (0x1L << ATOM_DEVICE_DFP2I_INDEX)
 
@@ -4939,7 +5965,7 @@ typedef struct _ATOM_PPLIB_RS780_CLOCK_I
 
 #define ATOM_S3_DFP2I_ACTIVEb1             0x02
 
-#define ATOM_S3_DFP1I_ACTIVE               ATOM_S3_DFP1_ACTIVE
+#define ATOM_S3_DFP1I_ACTIVE               ATOM_S3_DFP1_ACTIVE 
 #define ATOM_S3_DFP1X_ACTIVE               ATOM_S3_DFP2_ACTIVE
 
 #define ATOM_S3_DFP2I_ACTIVE               0x00000200L
@@ -4958,14 +5984,14 @@ typedef struct _ATOM_PPLIB_RS780_CLOCK_I
 #define ATOM_S6_ACC_REQ_DFP2Ib3            0x02
 #define ATOM_S6_ACC_REQ_DFP2I              0x02000000L
 
-#define TMDS1XEncoderControl               DVOEncoderControl
+#define TMDS1XEncoderControl               DVOEncoderControl           
 #define DFP1XOutputControl                 DVOOutputControl
 
 #define ExternalDFPOutputControl           DFP1XOutputControl
 #define EnableExternalTMDS_Encoder         TMDS1XEncoderControl
 
 #define DFP1IOutputControl                 TMDSAOutputControl
-#define DFP2IOutputControl                 LVTMAOutputControl
+#define DFP2IOutputControl                 LVTMAOutputControl      
 
 #define DAC1_ENCODER_CONTROL_PARAMETERS    DAC_ENCODER_CONTROL_PARAMETERS
 #define DAC1_ENCODER_CONTROL_PS_ALLOCATION DAC_ENCODER_CONTROL_PS_ALLOCATION
@@ -4974,7 +6000,7 @@ typedef struct _ATOM_PPLIB_RS780_CLOCK_I
 #define DAC2_ENCODER_CONTROL_PS_ALLOCATION DAC_ENCODER_CONTROL_PS_ALLOCATION
 
 #define ucDac1Standard  ucDacStandard
-#define ucDac2Standard  ucDacStandard
+#define ucDac2Standard  ucDacStandard  
 
 #define TMDS1EncoderControl TMDSAEncoderControl
 #define TMDS2EncoderControl LVTMAEncoderControl
@@ -4984,12 +6010,56 @@ typedef struct _ATOM_PPLIB_RS780_CLOCK_I
 #define CRT1OutputControl   DAC1OutputControl
 #define CRT2OutputControl   DAC2OutputControl
 
-/* These two lines will be removed for sure in a few days, will follow up with Michael V. */
+//These two lines will be removed for sure in a few days, will follow up with Michael V.
 #define EnableLVDS_SS   EnableSpreadSpectrumOnPPLL
-#define ENABLE_LVDS_SS_PARAMETERS_V3  ENABLE_SPREAD_SPECTRUM_ON_PPLL
+#define ENABLE_LVDS_SS_PARAMETERS_V3  ENABLE_SPREAD_SPECTRUM_ON_PPLL  
+
+//#define ATOM_S2_CRT1_DPMS_STATE         0x00010000L
+//#define ATOM_S2_LCD1_DPMS_STATE	        ATOM_S2_CRT1_DPMS_STATE
+//#define ATOM_S2_TV1_DPMS_STATE          ATOM_S2_CRT1_DPMS_STATE
+//#define ATOM_S2_DFP1_DPMS_STATE         ATOM_S2_CRT1_DPMS_STATE
+//#define ATOM_S2_CRT2_DPMS_STATE         ATOM_S2_CRT1_DPMS_STATE
+
+#define ATOM_S6_ACC_REQ_TV2             0x00400000L
+#define ATOM_DEVICE_TV2_INDEX           0x00000006
+#define ATOM_DEVICE_TV2_SUPPORT         (0x1L << ATOM_DEVICE_TV2_INDEX)
+#define ATOM_S0_TV2                     0x00100000L
+#define ATOM_S3_TV2_ACTIVE              ATOM_S3_DFP6_ACTIVE
+#define ATOM_S3_TV2_CRTC_ACTIVE         ATOM_S3_DFP6_CRTC_ACTIVE
+
+//
+#define ATOM_S2_CRT1_DPMS_STATE         0x00010000L
+#define ATOM_S2_LCD1_DPMS_STATE	        0x00020000L
+#define ATOM_S2_TV1_DPMS_STATE          0x00040000L
+#define ATOM_S2_DFP1_DPMS_STATE         0x00080000L
+#define ATOM_S2_CRT2_DPMS_STATE         0x00100000L
+#define ATOM_S2_LCD2_DPMS_STATE         0x00200000L
+#define ATOM_S2_TV2_DPMS_STATE          0x00400000L
+#define ATOM_S2_DFP2_DPMS_STATE         0x00800000L
+#define ATOM_S2_CV_DPMS_STATE           0x01000000L
+#define ATOM_S2_DFP3_DPMS_STATE					0x02000000L
+#define ATOM_S2_DFP4_DPMS_STATE					0x04000000L
+#define ATOM_S2_DFP5_DPMS_STATE					0x08000000L
+
+#define ATOM_S2_CRT1_DPMS_STATEb2       0x01
+#define ATOM_S2_LCD1_DPMS_STATEb2       0x02
+#define ATOM_S2_TV1_DPMS_STATEb2        0x04
+#define ATOM_S2_DFP1_DPMS_STATEb2       0x08
+#define ATOM_S2_CRT2_DPMS_STATEb2       0x10
+#define ATOM_S2_LCD2_DPMS_STATEb2       0x20
+#define ATOM_S2_TV2_DPMS_STATEb2        0x40
+#define ATOM_S2_DFP2_DPMS_STATEb2       0x80
+#define ATOM_S2_CV_DPMS_STATEb3         0x01
+#define ATOM_S2_DFP3_DPMS_STATEb3				0x02
+#define ATOM_S2_DFP4_DPMS_STATEb3				0x04
+#define ATOM_S2_DFP5_DPMS_STATEb3				0x08
+
+#define ATOM_S3_ASIC_GUI_ENGINE_HUNGb3	0x20
+#define ATOM_S3_ALLOW_FAST_PWR_SWITCHb3 0x40
+#define ATOM_S3_RQST_GPU_USE_MIN_PWRb3  0x80
 
 /*********************************************************************************/
 
-#pragma pack()			/*  BIOS data must use byte aligment */
+#pragma pack() // BIOS data must use byte aligment
 
 #endif /* _ATOMBIOS_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atom.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/atom.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/atom.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #define ATOM_DEBUG
@@ -52,15 +53,17 @@
 
 typedef struct {
 	struct atom_context *ctx;
-
 	uint32_t *ps, *ws;
 	int ps_shift;
 	uint16_t start;
+	unsigned last_jump;
+	unsigned long last_jump_jiffies;
+	bool abort;
 } atom_exec_context;
 
 int atom_debug = 0;
-static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params);
-void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params);
+static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params);
+int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params);
 
 static uint32_t atom_arg_mask[8] =
     { 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000,
@@ -604,12 +607,17 @@ static void atom_op_beep(atom_exec_conte
 static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg)
 {
 	int idx = U8((*ptr)++);
+	int r = 0;
+
 	if (idx < ATOM_TABLE_NAMES_CNT)
 		SDEBUG("   table: %d (%s)\n", idx, atom_table_names[idx]);
 	else
 		SDEBUG("   table: %d\n", idx);
 	if (U16(ctx->ctx->cmd_table + 4 + 2 * idx))
-		atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
+		r = atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
+	if (r) {
+		ctx->abort = true;
+	}
 }
 
 static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg)
@@ -673,6 +681,8 @@ static void atom_op_eot(atom_exec_contex
 static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
 {
 	int execute = 0, target = U16(*ptr);
+	unsigned long cjiffies;
+
 	(*ptr) += 2;
 	switch (arg) {
 	case ATOM_COND_ABOVE:
@@ -700,8 +710,25 @@ static void atom_op_jump(atom_exec_conte
 	if (arg != ATOM_COND_ALWAYS)
 		SDEBUG("   taken: %s\n", execute ? "yes" : "no");
 	SDEBUG("   target: 0x%04X\n", target);
-	if (execute)
+	if (execute) {
+		if (ctx->last_jump == (ctx->start + target)) {
+			cjiffies = jiffies;
+			if (time_after(cjiffies, ctx->last_jump_jiffies)) {
+				cjiffies -= ctx->last_jump_jiffies;
+				if ((jiffies_to_msecs(cjiffies) > 1000)) {
+					DRM_ERROR("atombios stuck in loop for more than 1sec aborting\n");
+					ctx->abort = true;
+				}
+			} else {
+				/* jiffies wrap around we will just wait a little longer */
+				ctx->last_jump_jiffies = jiffies;
+			}
+		} else {
+			ctx->last_jump = ctx->start + target;
+			ctx->last_jump_jiffies = jiffies;
+		}
 		*ptr = ctx->start + target;
+	}
 }
 
 static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg)
@@ -881,13 +908,16 @@ static void atom_op_shl(atom_exec_contex
 	uint8_t attr = U8((*ptr)++), shift;
 	uint32_t saved, dst;
 	int dptr = *ptr;
-	attr &= 0x38;
-	attr |= atom_def_dst[attr >> 3] << 6;
+	uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
 	SDEBUG("   dst: ");
 	dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+	/* op needs to full dst value */
+	dst = saved;
 	shift = atom_get_src(ctx, attr, ptr);
 	SDEBUG("   shift: %d\n", shift);
 	dst <<= shift;
+	dst &= atom_arg_mask[dst_align];
+	dst >>= atom_arg_shift[dst_align];
 	SDEBUG("   dst: ");
 	atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
@@ -897,13 +927,16 @@ static void atom_op_shr(atom_exec_contex
 	uint8_t attr = U8((*ptr)++), shift;
 	uint32_t saved, dst;
 	int dptr = *ptr;
-	attr &= 0x38;
-	attr |= atom_def_dst[attr >> 3] << 6;
+	uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
 	SDEBUG("   dst: ");
 	dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+	/* op needs to full dst value */
+	dst = saved;
 	shift = atom_get_src(ctx, attr, ptr);
 	SDEBUG("   shift: %d\n", shift);
 	dst >>= shift;
+	dst &= atom_arg_mask[dst_align];
+	dst >>= atom_arg_shift[dst_align];
 	SDEBUG("   dst: ");
 	atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
@@ -1108,15 +1141,16 @@ static struct {
 	atom_op_shr, ATOM_ARG_MC}, {
 atom_op_debug, 0},};
 
-static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params)
+static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params)
 {
 	int base = CU16(ctx->cmd_table + 4 + 2 * index);
 	int len, ws, ps, ptr;
 	unsigned char op;
 	atom_exec_context ectx;
+	int ret = 0;
 
 	if (!base)
-		return;
+		return -EINVAL;
 
 	len = CU16(base + ATOM_CT_SIZE_PTR);
 	ws = CU8(base + ATOM_CT_WS_PTR);
@@ -1129,6 +1163,8 @@ static void atom_execute_table_locked(st
 	ectx.ps_shift = ps / 4;
 	ectx.start = base;
 	ectx.ps = params;
+	ectx.abort = false;
+	ectx.last_jump = 0;
 	if (ws)
 		ectx.ws = kzalloc(4 * ws, GFP_KERNEL);
 	else
@@ -1141,6 +1177,12 @@ static void atom_execute_table_locked(st
 			SDEBUG("%s @ 0x%04X\n", atom_op_names[op], ptr - 1);
 		else
 			SDEBUG("[%d] @ 0x%04X\n", op, ptr - 1);
+		if (ectx.abort) {
+			DRM_ERROR("atombios stuck executing %04X (len %d, WS %d, PS %d) @ 0x%04X\n",
+				base, len, ws, ps, ptr - 1);
+			ret = -EINVAL;
+			goto free;
+		}
 
 		if (op < ATOM_OP_CNT && op > 0)
 			opcode_table[op].func(&ectx, &ptr,
@@ -1154,12 +1196,16 @@ static void atom_execute_table_locked(st
 	debug_depth--;
 	SDEBUG("<<\n");
 
+free:
 	if (ws)
 		kfree(ectx.ws);
+	return ret;
 }
 
-void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
+int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
 {
+	int r;
+
 	mutex_lock(&ctx->mutex);
 	/* reset reg block */
 	ctx->reg_block = 0;
@@ -1167,8 +1213,9 @@ void atom_execute_table(struct atom_cont
 	ctx->fb_base = 0;
 	/* reset io mode */
 	ctx->io_mode = ATOM_IO_MM;
-	atom_execute_table_locked(ctx, index, params);
+	r = atom_execute_table_locked(ctx, index, params);
 	mutex_unlock(&ctx->mutex);
+	return r;
 }
 
 static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 };
@@ -1252,9 +1299,7 @@ int atom_asic_init(struct atom_context *
 
 	if (!CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_INIT))
 		return 1;
-	atom_execute_table(ctx, ATOM_CMD_INIT, ps);
-
-	return 0;
+	return atom_execute_table(ctx, ATOM_CMD_INIT, ps);
 }
 
 void atom_destroy(struct atom_context *ctx)
@@ -1264,12 +1309,16 @@ void atom_destroy(struct atom_context *c
 	kfree(ctx);
 }
 
-void atom_parse_data_header(struct atom_context *ctx, int index,
+bool atom_parse_data_header(struct atom_context *ctx, int index,
 			    uint16_t * size, uint8_t * frev, uint8_t * crev,
 			    uint16_t * data_start)
 {
 	int offset = index * 2 + 4;
 	int idx = CU16(ctx->data_table + offset);
+	u16 *mdt = (u16 *)(ctx->bios + ctx->data_table + 4);
+
+	if (!mdt[index])
+		return false;
 
 	if (size)
 		*size = CU16(idx);
@@ -1278,38 +1327,42 @@ void atom_parse_data_header(struct atom_
 	if (crev)
 		*crev = CU8(idx + 3);
 	*data_start = idx;
-	return;
+	return true;
 }
 
-void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
+bool atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
 			   uint8_t * crev)
 {
 	int offset = index * 2 + 4;
 	int idx = CU16(ctx->cmd_table + offset);
+	u16 *mct = (u16 *)(ctx->bios + ctx->cmd_table + 4);
+
+	if (!mct[index])
+		return false;
 
 	if (frev)
 		*frev = CU8(idx + 2);
 	if (crev)
 		*crev = CU8(idx + 3);
-	return;
+	return true;
 }
 
 int atom_allocate_fb_scratch(struct atom_context *ctx)
 {
 	int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware);
 	uint16_t data_offset;
-	int usage_bytes;
+	int usage_bytes = 0;
 	struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage;
 
-	atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset);
-
-	firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
+	if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
+		firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
 
-	DRM_DEBUG("atom firmware requested %08x %dkb\n",
-		  firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
-		  firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
+		DRM_DEBUG("atom firmware requested %08x %dkb\n",
+			  firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
+			  firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
 
-	usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
+		usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
+	}
 	if (usage_bytes == 0)
 		usage_bytes = 20 * 1024;
 	/* allocate some scratch memory */
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atom.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/atom.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atom.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/atom.h	2010-05-16 17:17:36.000000000 -0400
@@ -140,11 +140,13 @@ struct atom_context {
 extern int atom_debug;
 
 struct atom_context *atom_parse(struct card_info *, void *);
-void atom_execute_table(struct atom_context *, int, uint32_t *);
+int atom_execute_table(struct atom_context *, int, uint32_t *);
 int atom_asic_init(struct atom_context *);
 void atom_destroy(struct atom_context *);
-void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start);
-void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev);
+bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size,
+			    uint8_t *frev, uint8_t *crev, uint16_t *data_start);
+bool atom_parse_cmd_header(struct atom_context *ctx, int index,
+			   uint8_t *frev, uint8_t *crev);
 int atom_allocate_fb_scratch(struct atom_context *ctx);
 #include "atom-types.h"
 #include "atombios.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/avivod.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/avivod.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/avivod.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/avivod.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,11 +30,13 @@
 
 #define	D1CRTC_CONTROL					0x6080
 #define		CRTC_EN						(1 << 0)
+#define	D1CRTC_STATUS					0x609c
 #define	D1CRTC_UPDATE_LOCK				0x60E8
 #define	D1GRPH_PRIMARY_SURFACE_ADDRESS			0x6110
 #define	D1GRPH_SECONDARY_SURFACE_ADDRESS		0x6118
 
 #define	D2CRTC_CONTROL					0x6880
+#define	D2CRTC_STATUS					0x689c
 #define	D2CRTC_UPDATE_LOCK				0x68E8
 #define	D2GRPH_PRIMARY_SURFACE_ADDRESS			0x6910
 #define	D2GRPH_SECONDARY_SURFACE_ADDRESS		0x6918
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/evergreen.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/evergreen.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/evergreen.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/evergreen.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,765 @@
+/*
+ * Copyright 2010 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Alex Deucher
+ */
+#include <linux/firmware.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include "drmP.h"
+#include "radeon.h"
+#include "radeon_asic.h"
+#include "radeon_drm.h"
+#include "rv770d.h"
+#include "atom.h"
+#include "avivod.h"
+#include "evergreen_reg.h"
+
+static void evergreen_gpu_init(struct radeon_device *rdev);
+void evergreen_fini(struct radeon_device *rdev);
+
+bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
+{
+	bool connected = false;
+	/* XXX */
+	return connected;
+}
+
+void evergreen_hpd_set_polarity(struct radeon_device *rdev,
+				enum radeon_hpd_id hpd)
+{
+	/* XXX */
+}
+
+void evergreen_hpd_init(struct radeon_device *rdev)
+{
+	/* XXX */
+}
+
+
+void evergreen_bandwidth_update(struct radeon_device *rdev)
+{
+	/* XXX */
+}
+
+void evergreen_hpd_fini(struct radeon_device *rdev)
+{
+	/* XXX */
+}
+
+static int evergreen_mc_wait_for_idle(struct radeon_device *rdev)
+{
+	unsigned i;
+	u32 tmp;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		/* read MC_STATUS */
+		tmp = RREG32(SRBM_STATUS) & 0x1F00;
+		if (!tmp)
+			return 0;
+		udelay(1);
+	}
+	return -1;
+}
+
+/*
+ * GART
+ */
+int evergreen_pcie_gart_enable(struct radeon_device *rdev)
+{
+	u32 tmp;
+	int r, i;
+
+	if (rdev->gart.table.vram.robj == NULL) {
+		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
+		return -EINVAL;
+	}
+	r = radeon_gart_table_vram_pin(rdev);
+	if (r)
+		return r;
+	radeon_gart_restore(rdev);
+	/* Setup L2 cache */
+	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
+				ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
+				EFFECTIVE_L2_QUEUE_SIZE(7));
+	WREG32(VM_L2_CNTL2, 0);
+	WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
+	/* Setup TLB control */
+	tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
+		SYSTEM_ACCESS_MODE_NOT_IN_SYS |
+		SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
+		EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
+	WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
+	WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
+	WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
+	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
+	WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
+	WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
+	WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
+				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
+	WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
+			(u32)(rdev->dummy_page.addr >> 12));
+	for (i = 1; i < 7; i++)
+		WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
+
+	r600_pcie_gart_tlb_flush(rdev);
+	rdev->gart.ready = true;
+	return 0;
+}
+
+void evergreen_pcie_gart_disable(struct radeon_device *rdev)
+{
+	u32 tmp;
+	int i, r;
+
+	/* Disable all tables */
+	for (i = 0; i < 7; i++)
+		WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
+
+	/* Setup L2 cache */
+	WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING |
+				EFFECTIVE_L2_QUEUE_SIZE(7));
+	WREG32(VM_L2_CNTL2, 0);
+	WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
+	/* Setup TLB control */
+	tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
+	WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
+	WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
+	WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
+	if (rdev->gart.table.vram.robj) {
+		r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+		if (likely(r == 0)) {
+			radeon_bo_kunmap(rdev->gart.table.vram.robj);
+			radeon_bo_unpin(rdev->gart.table.vram.robj);
+			radeon_bo_unreserve(rdev->gart.table.vram.robj);
+		}
+	}
+}
+
+void evergreen_pcie_gart_fini(struct radeon_device *rdev)
+{
+	evergreen_pcie_gart_disable(rdev);
+	radeon_gart_table_vram_free(rdev);
+	radeon_gart_fini(rdev);
+}
+
+
+void evergreen_agp_enable(struct radeon_device *rdev)
+{
+	u32 tmp;
+	int i;
+
+	/* Setup L2 cache */
+	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
+				ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
+				EFFECTIVE_L2_QUEUE_SIZE(7));
+	WREG32(VM_L2_CNTL2, 0);
+	WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
+	/* Setup TLB control */
+	tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
+		SYSTEM_ACCESS_MODE_NOT_IN_SYS |
+		SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
+		EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
+	WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
+	WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
+	WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
+	for (i = 0; i < 7; i++)
+		WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
+}
+
+static void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save)
+{
+	save->vga_control[0] = RREG32(D1VGA_CONTROL);
+	save->vga_control[1] = RREG32(D2VGA_CONTROL);
+	save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL);
+	save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL);
+	save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL);
+	save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL);
+	save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
+	save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
+	save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET);
+	save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
+	save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET);
+	save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
+	save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET);
+	save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
+
+	/* Stop all video */
+	WREG32(VGA_RENDER_CONTROL, 0);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
+	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
+
+	WREG32(D1VGA_CONTROL, 0);
+	WREG32(D2VGA_CONTROL, 0);
+	WREG32(EVERGREEN_D3VGA_CONTROL, 0);
+	WREG32(EVERGREEN_D4VGA_CONTROL, 0);
+	WREG32(EVERGREEN_D5VGA_CONTROL, 0);
+	WREG32(EVERGREEN_D6VGA_CONTROL, 0);
+}
+
+static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
+{
+	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET,
+	       upper_32_bits(rdev->mc.vram_start));
+	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET,
+	       upper_32_bits(rdev->mc.vram_start));
+	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET,
+	       (u32)rdev->mc.vram_start);
+	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET,
+	       (u32)rdev->mc.vram_start);
+
+	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET,
+	       upper_32_bits(rdev->mc.vram_start));
+	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET,
+	       upper_32_bits(rdev->mc.vram_start));
+	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET,
+	       (u32)rdev->mc.vram_start);
+	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET,
+	       (u32)rdev->mc.vram_start);
+
+	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
+	       upper_32_bits(rdev->mc.vram_start));
+	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
+	       upper_32_bits(rdev->mc.vram_start));
+	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET,
+	       (u32)rdev->mc.vram_start);
+	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET,
+	       (u32)rdev->mc.vram_start);
+
+	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET,
+	       upper_32_bits(rdev->mc.vram_start));
+	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET,
+	       upper_32_bits(rdev->mc.vram_start));
+	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET,
+	       (u32)rdev->mc.vram_start);
+	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET,
+	       (u32)rdev->mc.vram_start);
+
+	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET,
+	       upper_32_bits(rdev->mc.vram_start));
+	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET,
+	       upper_32_bits(rdev->mc.vram_start));
+	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET,
+	       (u32)rdev->mc.vram_start);
+	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET,
+	       (u32)rdev->mc.vram_start);
+
+	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET,
+	       upper_32_bits(rdev->mc.vram_start));
+	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET,
+	       upper_32_bits(rdev->mc.vram_start));
+	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET,
+	       (u32)rdev->mc.vram_start);
+	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET,
+	       (u32)rdev->mc.vram_start);
+
+	WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start));
+	WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);
+	/* Unlock host access */
+	WREG32(VGA_HDP_CONTROL, save->vga_hdp_control);
+	mdelay(1);
+	/* Restore video state */
+	WREG32(D1VGA_CONTROL, save->vga_control[0]);
+	WREG32(D2VGA_CONTROL, save->vga_control[1]);
+	WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]);
+	WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]);
+	WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]);
+	WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
+	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]);
+	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]);
+	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]);
+	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]);
+	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]);
+	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
+	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
+	WREG32(VGA_RENDER_CONTROL, save->vga_render_control);
+}
+
+static void evergreen_mc_program(struct radeon_device *rdev)
+{
+	struct evergreen_mc_save save;
+	u32 tmp;
+	int i, j;
+
+	/* Initialize HDP */
+	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
+		WREG32((0x2c14 + j), 0x00000000);
+		WREG32((0x2c18 + j), 0x00000000);
+		WREG32((0x2c1c + j), 0x00000000);
+		WREG32((0x2c20 + j), 0x00000000);
+		WREG32((0x2c24 + j), 0x00000000);
+	}
+	WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
+
+	evergreen_mc_stop(rdev, &save);
+	if (evergreen_mc_wait_for_idle(rdev)) {
+		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
+	}
+	/* Lockout access through VGA aperture*/
+	WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
+	/* Update configuration */
+	if (rdev->flags & RADEON_IS_AGP) {
+		if (rdev->mc.vram_start < rdev->mc.gtt_start) {
+			/* VRAM before AGP */
+			WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
+				rdev->mc.vram_start >> 12);
+			WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
+				rdev->mc.gtt_end >> 12);
+		} else {
+			/* VRAM after AGP */
+			WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
+				rdev->mc.gtt_start >> 12);
+			WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
+				rdev->mc.vram_end >> 12);
+		}
+	} else {
+		WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
+			rdev->mc.vram_start >> 12);
+		WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
+			rdev->mc.vram_end >> 12);
+	}
+	WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+	tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
+	tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
+	WREG32(MC_VM_FB_LOCATION, tmp);
+	WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
+	WREG32(HDP_NONSURFACE_INFO, (2 << 7));
+	WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF);
+	if (rdev->flags & RADEON_IS_AGP) {
+		WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16);
+		WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16);
+		WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
+	} else {
+		WREG32(MC_VM_AGP_BASE, 0);
+		WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
+		WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
+	}
+	if (evergreen_mc_wait_for_idle(rdev)) {
+		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
+	}
+	evergreen_mc_resume(rdev, &save);
+	/* we need to own VRAM, so turn off the VGA renderer here
+	 * to stop it overwriting our objects */
+	rv515_vga_render_disable(rdev);
+}
+
+#if 0
+/*
+ * CP.
+ */
+static void evergreen_cp_stop(struct radeon_device *rdev)
+{
+	/* XXX */
+}
+
+
+static int evergreen_cp_load_microcode(struct radeon_device *rdev)
+{
+	/* XXX */
+
+	return 0;
+}
+
+
+/*
+ * Core functions
+ */
+static u32 evergreen_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
+						  u32 num_backends,
+						  u32 backend_disable_mask)
+{
+	u32 backend_map = 0;
+
+	return backend_map;
+}
+#endif
+
+static void evergreen_gpu_init(struct radeon_device *rdev)
+{
+	/* XXX */
+}
+
+int evergreen_mc_init(struct radeon_device *rdev)
+{
+	u32 tmp;
+	int chansize, numchan;
+
+	/* Get VRAM informations */
+	rdev->mc.vram_is_ddr = true;
+	tmp = RREG32(MC_ARB_RAMCFG);
+	if (tmp & CHANSIZE_OVERRIDE) {
+		chansize = 16;
+	} else if (tmp & CHANSIZE_MASK) {
+		chansize = 64;
+	} else {
+		chansize = 32;
+	}
+	tmp = RREG32(MC_SHARED_CHMAP);
+	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
+	case 0:
+	default:
+		numchan = 1;
+		break;
+	case 1:
+		numchan = 2;
+		break;
+	case 2:
+		numchan = 4;
+		break;
+	case 3:
+		numchan = 8;
+		break;
+	}
+	rdev->mc.vram_width = numchan * chansize;
+	/* Could aper size report 0 ? */
+	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
+	rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+	/* Setup GPU memory space */
+	/* size in MB on evergreen */
+	rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
+	rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
+	rdev->mc.visible_vram_size = rdev->mc.aper_size;
+	/* FIXME remove this once we support unmappable VRAM */
+	if (rdev->mc.mc_vram_size > rdev->mc.aper_size) {
+		rdev->mc.mc_vram_size = rdev->mc.aper_size;
+		rdev->mc.real_vram_size = rdev->mc.aper_size;
+	}
+	r600_vram_gtt_location(rdev, &rdev->mc);
+	radeon_update_bandwidth_info(rdev);
+
+	return 0;
+}
+
+int evergreen_gpu_reset(struct radeon_device *rdev)
+{
+	/* FIXME: implement for evergreen */
+	return 0;
+}
+
+static int evergreen_startup(struct radeon_device *rdev)
+{
+#if 0
+	int r;
+
+	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
+		r = r600_init_microcode(rdev);
+		if (r) {
+			DRM_ERROR("Failed to load firmware!\n");
+			return r;
+		}
+	}
+#endif
+	evergreen_mc_program(rdev);
+#if 0
+	if (rdev->flags & RADEON_IS_AGP) {
+		evergreem_agp_enable(rdev);
+	} else {
+		r = evergreen_pcie_gart_enable(rdev);
+		if (r)
+			return r;
+	}
+#endif
+	evergreen_gpu_init(rdev);
+#if 0
+	if (!rdev->r600_blit.shader_obj) {
+		r = r600_blit_init(rdev);
+		if (r) {
+			DRM_ERROR("radeon: failed blitter (%d).\n", r);
+			return r;
+		}
+	}
+
+	r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+	if (unlikely(r != 0))
+		return r;
+	r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
+			&rdev->r600_blit.shader_gpu_addr);
+	radeon_bo_unreserve(rdev->r600_blit.shader_obj);
+	if (r) {
+		DRM_ERROR("failed to pin blit object %d\n", r);
+		return r;
+	}
+
+	/* Enable IRQ */
+	r = r600_irq_init(rdev);
+	if (r) {
+		DRM_ERROR("radeon: IH init failed (%d).\n", r);
+		radeon_irq_kms_fini(rdev);
+		return r;
+	}
+	r600_irq_set(rdev);
+
+	r = radeon_ring_init(rdev, rdev->cp.ring_size);
+	if (r)
+		return r;
+	r = evergreen_cp_load_microcode(rdev);
+	if (r)
+		return r;
+	r = r600_cp_resume(rdev);
+	if (r)
+		return r;
+	/* write back buffer are not vital so don't worry about failure */
+	r600_wb_enable(rdev);
+#endif
+	return 0;
+}
+
+int evergreen_resume(struct radeon_device *rdev)
+{
+	int r;
+
+	/* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
+	 * posting will perform necessary task to bring back GPU into good
+	 * shape.
+	 */
+	/* post card */
+	atom_asic_init(rdev->mode_info.atom_context);
+	/* Initialize clocks */
+	r = radeon_clocks_init(rdev);
+	if (r) {
+		return r;
+	}
+
+	r = evergreen_startup(rdev);
+	if (r) {
+		DRM_ERROR("r600 startup failed on resume\n");
+		return r;
+	}
+#if 0
+	r = r600_ib_test(rdev);
+	if (r) {
+		DRM_ERROR("radeon: failled testing IB (%d).\n", r);
+		return r;
+	}
+#endif
+	return r;
+
+}
+
+int evergreen_suspend(struct radeon_device *rdev)
+{
+#if 0
+	int r;
+
+	/* FIXME: we should wait for ring to be empty */
+	r700_cp_stop(rdev);
+	rdev->cp.ready = false;
+	r600_wb_disable(rdev);
+	evergreen_pcie_gart_disable(rdev);
+	/* unpin shaders bo */
+	r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+	if (likely(r == 0)) {
+		radeon_bo_unpin(rdev->r600_blit.shader_obj);
+		radeon_bo_unreserve(rdev->r600_blit.shader_obj);
+	}
+#endif
+	return 0;
+}
+
+static bool evergreen_card_posted(struct radeon_device *rdev)
+{
+	u32 reg;
+
+	/* first check CRTCs */
+	reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) |
+		RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) |
+		RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) |
+		RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) |
+		RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) |
+		RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
+	if (reg & EVERGREEN_CRTC_MASTER_EN)
+		return true;
+
+	/* then check MEM_SIZE, in case the crtcs are off */
+	if (RREG32(CONFIG_MEMSIZE))
+		return true;
+
+	return false;
+}
+
+/* Plan is to move initialization in that function and use
+ * helper function so that radeon_device_init pretty much
+ * do nothing more than calling asic specific function. This
+ * should also allow to remove a bunch of callback function
+ * like vram_info.
+ */
+int evergreen_init(struct radeon_device *rdev)
+{
+	int r;
+
+	r = radeon_dummy_page_init(rdev);
+	if (r)
+		return r;
+	/* This don't do much */
+	r = radeon_gem_init(rdev);
+	if (r)
+		return r;
+	/* Read BIOS */
+	if (!radeon_get_bios(rdev)) {
+		if (ASIC_IS_AVIVO(rdev))
+			return -EINVAL;
+	}
+	/* Must be an ATOMBIOS */
+	if (!rdev->is_atom_bios) {
+		dev_err(rdev->dev, "Expecting atombios for R600 GPU\n");
+		return -EINVAL;
+	}
+	r = radeon_atombios_init(rdev);
+	if (r)
+		return r;
+	/* Post card if necessary */
+	if (!evergreen_card_posted(rdev)) {
+		if (!rdev->bios) {
+			dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
+			return -EINVAL;
+		}
+		DRM_INFO("GPU not posted. posting now...\n");
+		atom_asic_init(rdev->mode_info.atom_context);
+	}
+	/* Initialize scratch registers */
+	r600_scratch_init(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
+	/* Initialize clocks */
+	radeon_get_clock_info(rdev->ddev);
+	r = radeon_clocks_init(rdev);
+	if (r)
+		return r;
+	/* Initialize power management */
+	radeon_pm_init(rdev);
+	/* Fence driver */
+	r = radeon_fence_driver_init(rdev);
+	if (r)
+		return r;
+	/* initialize AGP */
+	if (rdev->flags & RADEON_IS_AGP) {
+		r = radeon_agp_init(rdev);
+		if (r)
+			radeon_agp_disable(rdev);
+	}
+	/* initialize memory controller */
+	r = evergreen_mc_init(rdev);
+	if (r)
+		return r;
+	/* Memory manager */
+	r = radeon_bo_init(rdev);
+	if (r)
+		return r;
+#if 0
+	r = radeon_irq_kms_init(rdev);
+	if (r)
+		return r;
+
+	rdev->cp.ring_obj = NULL;
+	r600_ring_init(rdev, 1024 * 1024);
+
+	rdev->ih.ring_obj = NULL;
+	r600_ih_ring_init(rdev, 64 * 1024);
+
+	r = r600_pcie_gart_init(rdev);
+	if (r)
+		return r;
+#endif
+	rdev->accel_working = false;
+	r = evergreen_startup(rdev);
+	if (r) {
+		evergreen_suspend(rdev);
+		/*r600_wb_fini(rdev);*/
+		/*radeon_ring_fini(rdev);*/
+		/*evergreen_pcie_gart_fini(rdev);*/
+		rdev->accel_working = false;
+	}
+	if (rdev->accel_working) {
+		r = radeon_ib_pool_init(rdev);
+		if (r) {
+			DRM_ERROR("radeon: failed initializing IB pool (%d).\n", r);
+			rdev->accel_working = false;
+		}
+		r = r600_ib_test(rdev);
+		if (r) {
+			DRM_ERROR("radeon: failed testing IB (%d).\n", r);
+			rdev->accel_working = false;
+		}
+	}
+	return 0;
+}
+
+void evergreen_fini(struct radeon_device *rdev)
+{
+	radeon_pm_fini(rdev);
+	evergreen_suspend(rdev);
+#if 0
+	r600_blit_fini(rdev);
+	r600_irq_fini(rdev);
+	radeon_irq_kms_fini(rdev);
+	radeon_ring_fini(rdev);
+	r600_wb_fini(rdev);
+	evergreen_pcie_gart_fini(rdev);
+#endif
+	radeon_gem_fini(rdev);
+	radeon_fence_driver_fini(rdev);
+	radeon_clocks_fini(rdev);
+	radeon_agp_fini(rdev);
+	radeon_bo_fini(rdev);
+	radeon_atombios_fini(rdev);
+	kfree(rdev->bios);
+	rdev->bios = NULL;
+	radeon_dummy_page_fini(rdev);
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/evergreen_reg.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/evergreen_reg.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/evergreen_reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/evergreen_reg.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2010 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Alex Deucher
+ */
+#ifndef __EVERGREEN_REG_H__
+#define __EVERGREEN_REG_H__
+
+/* evergreen */
+#define EVERGREEN_VGA_MEMORY_BASE_ADDRESS               0x310
+#define EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH          0x324
+#define EVERGREEN_D3VGA_CONTROL                         0x3e0
+#define EVERGREEN_D4VGA_CONTROL                         0x3e4
+#define EVERGREEN_D5VGA_CONTROL                         0x3e8
+#define EVERGREEN_D6VGA_CONTROL                         0x3ec
+
+#define EVERGREEN_P1PLL_SS_CNTL                         0x414
+#define EVERGREEN_P2PLL_SS_CNTL                         0x454
+#       define EVERGREEN_PxPLL_SS_EN                    (1 << 12)
+/* GRPH blocks at 0x6800, 0x7400, 0x10000, 0x10c00, 0x11800, 0x12400 */
+#define EVERGREEN_GRPH_ENABLE                           0x6800
+#define EVERGREEN_GRPH_CONTROL                          0x6804
+#       define EVERGREEN_GRPH_DEPTH(x)                  (((x) & 0x3) << 0)
+#       define EVERGREEN_GRPH_DEPTH_8BPP                0
+#       define EVERGREEN_GRPH_DEPTH_16BPP               1
+#       define EVERGREEN_GRPH_DEPTH_32BPP               2
+#       define EVERGREEN_GRPH_FORMAT(x)                 (((x) & 0x7) << 8)
+/* 8 BPP */
+#       define EVERGREEN_GRPH_FORMAT_INDEXED            0
+/* 16 BPP */
+#       define EVERGREEN_GRPH_FORMAT_ARGB1555           0
+#       define EVERGREEN_GRPH_FORMAT_ARGB565            1
+#       define EVERGREEN_GRPH_FORMAT_ARGB4444           2
+#       define EVERGREEN_GRPH_FORMAT_AI88               3
+#       define EVERGREEN_GRPH_FORMAT_MONO16             4
+#       define EVERGREEN_GRPH_FORMAT_BGRA5551           5
+/* 32 BPP */
+#       define EVERGREEN_GRPH_FORMAT_ARGB8888           0
+#       define EVERGREEN_GRPH_FORMAT_ARGB2101010        1
+#       define EVERGREEN_GRPH_FORMAT_32BPP_DIG          2
+#       define EVERGREEN_GRPH_FORMAT_8B_ARGB2101010     3
+#       define EVERGREEN_GRPH_FORMAT_BGRA1010102        4
+#       define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102     5
+#       define EVERGREEN_GRPH_FORMAT_RGB111110          6
+#       define EVERGREEN_GRPH_FORMAT_BGR101111          7
+#define EVERGREEN_GRPH_SWAP_CONTROL                     0x680c
+#       define EVERGREEN_GRPH_ENDIAN_SWAP(x)            (((x) & 0x3) << 0)
+#       define EVERGREEN_GRPH_ENDIAN_NONE               0
+#       define EVERGREEN_GRPH_ENDIAN_8IN16              1
+#       define EVERGREEN_GRPH_ENDIAN_8IN32              2
+#       define EVERGREEN_GRPH_ENDIAN_8IN64              3
+#       define EVERGREEN_GRPH_RED_CROSSBAR(x)           (((x) & 0x3) << 4)
+#       define EVERGREEN_GRPH_RED_SEL_R                 0
+#       define EVERGREEN_GRPH_RED_SEL_G                 1
+#       define EVERGREEN_GRPH_RED_SEL_B                 2
+#       define EVERGREEN_GRPH_RED_SEL_A                 3
+#       define EVERGREEN_GRPH_GREEN_CROSSBAR(x)         (((x) & 0x3) << 6)
+#       define EVERGREEN_GRPH_GREEN_SEL_G               0
+#       define EVERGREEN_GRPH_GREEN_SEL_B               1
+#       define EVERGREEN_GRPH_GREEN_SEL_A               2
+#       define EVERGREEN_GRPH_GREEN_SEL_R               3
+#       define EVERGREEN_GRPH_BLUE_CROSSBAR(x)          (((x) & 0x3) << 8)
+#       define EVERGREEN_GRPH_BLUE_SEL_B                0
+#       define EVERGREEN_GRPH_BLUE_SEL_A                1
+#       define EVERGREEN_GRPH_BLUE_SEL_R                2
+#       define EVERGREEN_GRPH_BLUE_SEL_G                3
+#       define EVERGREEN_GRPH_ALPHA_CROSSBAR(x)         (((x) & 0x3) << 10)
+#       define EVERGREEN_GRPH_ALPHA_SEL_A               0
+#       define EVERGREEN_GRPH_ALPHA_SEL_R               1
+#       define EVERGREEN_GRPH_ALPHA_SEL_G               2
+#       define EVERGREEN_GRPH_ALPHA_SEL_B               3
+#define EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS          0x6810
+#define EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS        0x6814
+#       define EVERGREEN_GRPH_DFQ_ENABLE                (1 << 0)
+#       define EVERGREEN_GRPH_SURFACE_ADDRESS_MASK      0xffffff00
+#define EVERGREEN_GRPH_PITCH                            0x6818
+#define EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH     0x681c
+#define EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH   0x6820
+#define EVERGREEN_GRPH_SURFACE_OFFSET_X                 0x6824
+#define EVERGREEN_GRPH_SURFACE_OFFSET_Y                 0x6828
+#define EVERGREEN_GRPH_X_START                          0x682c
+#define EVERGREEN_GRPH_Y_START                          0x6830
+#define EVERGREEN_GRPH_X_END                            0x6834
+#define EVERGREEN_GRPH_Y_END                            0x6838
+
+/* CUR blocks at 0x6998, 0x7598, 0x10198, 0x10d98, 0x11998, 0x12598 */
+#define EVERGREEN_CUR_CONTROL                           0x6998
+#       define EVERGREEN_CURSOR_EN                      (1 << 0)
+#       define EVERGREEN_CURSOR_MODE(x)                 (((x) & 0x3) << 8)
+#       define EVERGREEN_CURSOR_MONO                    0
+#       define EVERGREEN_CURSOR_24_1                    1
+#       define EVERGREEN_CURSOR_24_8_PRE_MULT           2
+#       define EVERGREEN_CURSOR_24_8_UNPRE_MULT         3
+#       define EVERGREEN_CURSOR_2X_MAGNIFY              (1 << 16)
+#       define EVERGREEN_CURSOR_FORCE_MC_ON             (1 << 20)
+#       define EVERGREEN_CURSOR_URGENT_CONTROL(x)       (((x) & 0x7) << 24)
+#       define EVERGREEN_CURSOR_URGENT_ALWAYS           0
+#       define EVERGREEN_CURSOR_URGENT_1_8              1
+#       define EVERGREEN_CURSOR_URGENT_1_4              2
+#       define EVERGREEN_CURSOR_URGENT_3_8              3
+#       define EVERGREEN_CURSOR_URGENT_1_2              4
+#define EVERGREEN_CUR_SURFACE_ADDRESS                   0x699c
+#       define EVERGREEN_CUR_SURFACE_ADDRESS_MASK       0xfffff000
+#define EVERGREEN_CUR_SIZE                              0x69a0
+#define EVERGREEN_CUR_SURFACE_ADDRESS_HIGH              0x69a4
+#define EVERGREEN_CUR_POSITION                          0x69a8
+#define EVERGREEN_CUR_HOT_SPOT                          0x69ac
+#define EVERGREEN_CUR_COLOR1                            0x69b0
+#define EVERGREEN_CUR_COLOR2                            0x69b4
+#define EVERGREEN_CUR_UPDATE                            0x69b8
+#       define EVERGREEN_CURSOR_UPDATE_PENDING          (1 << 0)
+#       define EVERGREEN_CURSOR_UPDATE_TAKEN            (1 << 1)
+#       define EVERGREEN_CURSOR_UPDATE_LOCK             (1 << 16)
+#       define EVERGREEN_CURSOR_DISABLE_MULTIPLE_UPDATE (1 << 24)
+
+/* LUT blocks at 0x69e0, 0x75e0, 0x101e0, 0x10de0, 0x119e0, 0x125e0 */
+#define EVERGREEN_DC_LUT_RW_MODE                        0x69e0
+#define EVERGREEN_DC_LUT_RW_INDEX                       0x69e4
+#define EVERGREEN_DC_LUT_SEQ_COLOR                      0x69e8
+#define EVERGREEN_DC_LUT_PWL_DATA                       0x69ec
+#define EVERGREEN_DC_LUT_30_COLOR                       0x69f0
+#define EVERGREEN_DC_LUT_VGA_ACCESS_ENABLE              0x69f4
+#define EVERGREEN_DC_LUT_WRITE_EN_MASK                  0x69f8
+#define EVERGREEN_DC_LUT_AUTOFILL                       0x69fc
+#define EVERGREEN_DC_LUT_CONTROL                        0x6a00
+#define EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE              0x6a04
+#define EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN             0x6a08
+#define EVERGREEN_DC_LUT_BLACK_OFFSET_RED               0x6a0c
+#define EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE              0x6a10
+#define EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN             0x6a14
+#define EVERGREEN_DC_LUT_WHITE_OFFSET_RED               0x6a18
+
+#define EVERGREEN_DATA_FORMAT                           0x6b00
+#       define EVERGREEN_INTERLEAVE_EN                  (1 << 0)
+#define EVERGREEN_DESKTOP_HEIGHT                        0x6b04
+
+#define EVERGREEN_VIEWPORT_START                        0x6d70
+#define EVERGREEN_VIEWPORT_SIZE                         0x6d74
+
+/* display controller offsets used for crtc/cur/lut/grph/viewport/etc. */
+#define EVERGREEN_CRTC0_REGISTER_OFFSET                 (0x6df0 - 0x6df0)
+#define EVERGREEN_CRTC1_REGISTER_OFFSET                 (0x79f0 - 0x6df0)
+#define EVERGREEN_CRTC2_REGISTER_OFFSET                 (0x105f0 - 0x6df0)
+#define EVERGREEN_CRTC3_REGISTER_OFFSET                 (0x111f0 - 0x6df0)
+#define EVERGREEN_CRTC4_REGISTER_OFFSET                 (0x11df0 - 0x6df0)
+#define EVERGREEN_CRTC5_REGISTER_OFFSET                 (0x129f0 - 0x6df0)
+
+/* CRTC blocks at 0x6df0, 0x79f0, 0x105f0, 0x111f0, 0x11df0, 0x129f0 */
+#define EVERGREEN_CRTC_CONTROL                          0x6e70
+#       define EVERGREEN_CRTC_MASTER_EN                 (1 << 0)
+#define EVERGREEN_CRTC_UPDATE_LOCK                      0x6ed4
+
+#define EVERGREEN_DC_GPIO_HPD_MASK                      0x64b0
+#define EVERGREEN_DC_GPIO_HPD_A                         0x64b4
+#define EVERGREEN_DC_GPIO_HPD_EN                        0x64b8
+#define EVERGREEN_DC_GPIO_HPD_Y                         0x64bc
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/Makefile linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/Makefile
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,9 @@ $(obj)/r420_reg_safe.h: $(src)/reg_srcs/
 $(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable
 	$(call if_changed,mkregtable)
 
+$(obj)/r600_reg_safe.h: $(src)/reg_srcs/r600 $(obj)/mkregtable
+	$(call if_changed,mkregtable)
+
 $(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h
 
 $(obj)/r200.o: $(obj)/r200_reg_safe.h
@@ -42,10 +45,12 @@ $(obj)/r420.o: $(obj)/r420_reg_safe.h
 
 $(obj)/rs600.o: $(obj)/rs600_reg_safe.h
 
+$(obj)/r600_cs.o: $(obj)/r600_reg_safe.h
+
 radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \
 	radeon_irq.o r300_cmdbuf.o r600_cp.o
 # add KMS driver
-radeon-y += radeon_device.o radeon_kms.o \
+radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
 	radeon_atombios.o radeon_agp.o atombios_crtc.o radeon_combios.o \
 	atom.o radeon_fence.o radeon_ttm.o radeon_object.o radeon_gart.o \
 	radeon_legacy_crtc.o radeon_legacy_encoders.o radeon_connectors.o \
@@ -54,8 +59,10 @@ radeon-y += radeon_device.o radeon_kms.o
 	radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \
 	rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \
 	r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \
-	r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o
+	r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \
+	evergreen.o
 
 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
+radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
 
 obj-$(CONFIG_DRM_RADEON)+= radeon.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r100.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r100.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r100.c	2013-05-03 12:03:44.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r100.c	2013-05-03 09:44:38.000000000 -0400
@@ -26,11 +26,13 @@
  *          Jerome Glisse
  */
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_drm.h"
 #include "radeon_reg.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "r100d.h"
 #include "rs100d.h"
 #include "rv200d.h"
@@ -191,13 +193,13 @@ int r100_pci_gart_enable(struct radeon_d
 {
 	uint32_t tmp;
 
+	radeon_gart_restore(rdev);
 	/* discard memory request outside of configured range */
 	tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS;
 	WREG32(RADEON_AIC_CNTL, tmp);
 	/* set address range for PCI address translate */
-	WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_location);
-	tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
-	WREG32(RADEON_AIC_HI_ADDR, tmp);
+	WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_start);
+	WREG32(RADEON_AIC_HI_ADDR, rdev->mc.gtt_end);
 	/* set PCI GART page-table base address */
 	WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr);
 	tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN;
@@ -229,9 +231,9 @@ int r100_pci_gart_set_page(struct radeon
 
 void r100_pci_gart_fini(struct radeon_device *rdev)
 {
+	radeon_gart_fini(rdev);
 	r100_pci_gart_disable(rdev);
 	radeon_gart_table_ram_free(rdev);
-	radeon_gart_fini(rdev);
 }
 
 int r100_irq_set(struct radeon_device *rdev)
@@ -306,9 +308,13 @@ int r100_irq_process(struct radeon_devic
 		/* Vertical blank interrupts */
 		if (status & RADEON_CRTC_VBLANK_STAT) {
 			drm_handle_vblank(rdev->ddev, 0);
+			rdev->pm.vblank_sync = true;
+			wake_up(&rdev->irq.vblank_queue);
 		}
 		if (status & RADEON_CRTC2_VBLANK_STAT) {
 			drm_handle_vblank(rdev->ddev, 1);
+			rdev->pm.vblank_sync = true;
+			wake_up(&rdev->irq.vblank_queue);
 		}
 		if (status & RADEON_FP_DETECT_STAT) {
 			queue_hotplug = true;
@@ -360,8 +366,8 @@ void r100_fence_ring_emit(struct radeon_
 	radeon_ring_write(rdev, PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0));
 	radeon_ring_write(rdev, RADEON_RB3D_ZC_FLUSH_ALL);
 	/* Wait until IDLE & CLEAN */
-	radeon_ring_write(rdev, PACKET0(0x1720, 0));
-	radeon_ring_write(rdev, (1 << 16) | (1 << 17));
+	radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0));
+	radeon_ring_write(rdev, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
 	radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0));
 	radeon_ring_write(rdev, rdev->config.r100.hdp_cntl |
 				RADEON_HDP_READ_BUFFER_INVALIDATE);
@@ -733,6 +739,8 @@ int r100_cp_init(struct radeon_device *r
 	udelay(10);
 	rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
 	rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR);
+	/* protect against crazy HW on resume */
+	rdev->cp.wptr &= rdev->cp.ptr_mask;
 	/* Set cp mode to bus mastering & enable cp*/
 	WREG32(RADEON_CP_CSQ_MODE,
 	       REG_SET(RADEON_INDIRECT2_START, indirect2_start) |
@@ -1695,7 +1703,7 @@ int r100_gui_wait_for_idle(struct radeon
 	}
 	for (i = 0; i < rdev->usec_timeout; i++) {
 		tmp = RREG32(RADEON_RBBM_STATUS);
-		if (!(tmp & (1 << 31))) {
+		if (!(tmp & RADEON_RBBM_ACTIVE)) {
 			return 0;
 		}
 		DRM_UDELAY(1);
@@ -1710,8 +1718,8 @@ int r100_mc_wait_for_idle(struct radeon_
 
 	for (i = 0; i < rdev->usec_timeout; i++) {
 		/* read MC_STATUS */
-		tmp = RREG32(0x0150);
-		if (tmp & (1 << 2)) {
+		tmp = RREG32(RADEON_MC_STATUS);
+		if (tmp & RADEON_MC_IDLE) {
 			return 0;
 		}
 		DRM_UDELAY(1);
@@ -1784,7 +1792,7 @@ int r100_gpu_reset(struct radeon_device
 	}
 	/* Check if GPU is idle */
 	status = RREG32(RADEON_RBBM_STATUS);
-	if (status & (1 << 31)) {
+	if (status & RADEON_RBBM_ACTIVE) {
 		DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status);
 		return -1;
 	}
@@ -1794,6 +1802,10 @@ int r100_gpu_reset(struct radeon_device
 
 void r100_set_common_regs(struct radeon_device *rdev)
 {
+	struct drm_device *dev = rdev->ddev;
+	bool force_dac2 = false;
+	u32 tmp;
+
 	/* set these so they don't interfere with anything */
 	WREG32(RADEON_OV0_SCALE_CNTL, 0);
 	WREG32(RADEON_SUBPIC_CNTL, 0);
@@ -1802,6 +1814,74 @@ void r100_set_common_regs(struct radeon_
 	WREG32(RADEON_DVI_I2C_CNTL_1, 0);
 	WREG32(RADEON_CAP0_TRIG_CNTL, 0);
 	WREG32(RADEON_CAP1_TRIG_CNTL, 0);
+
+	/* always set up dac2 on rn50 and some rv100 as lots
+	 * of servers seem to wire it up to a VGA port but
+	 * don't report it in the bios connector
+	 * table.
+	 */
+	switch (dev->pdev->device) {
+		/* RN50 */
+	case 0x515e:
+	case 0x5969:
+		force_dac2 = true;
+		break;
+		/* RV100*/
+	case 0x5159:
+	case 0x515a:
+		/* DELL triple head servers */
+		if ((dev->pdev->subsystem_vendor == 0x1028 /* DELL */) &&
+		    ((dev->pdev->subsystem_device == 0x016c) ||
+		     (dev->pdev->subsystem_device == 0x016d) ||
+		     (dev->pdev->subsystem_device == 0x016e) ||
+		     (dev->pdev->subsystem_device == 0x016f) ||
+		     (dev->pdev->subsystem_device == 0x0170) ||
+		     (dev->pdev->subsystem_device == 0x017d) ||
+		     (dev->pdev->subsystem_device == 0x017e) ||
+		     (dev->pdev->subsystem_device == 0x0183) ||
+		     (dev->pdev->subsystem_device == 0x018a) ||
+		     (dev->pdev->subsystem_device == 0x019a)))
+			force_dac2 = true;
+		break;
+	}
+
+	if (force_dac2) {
+		u32 disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG);
+		u32 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
+		u32 dac2_cntl = RREG32(RADEON_DAC_CNTL2);
+
+		/* For CRT on DAC2, don't turn it on if BIOS didn't
+		   enable it, even it's detected.
+		*/
+
+		/* force it to crtc0 */
+		dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL;
+		dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
+		disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
+
+		/* set up the TV DAC */
+		tv_dac_cntl &= ~(RADEON_TV_DAC_PEDESTAL |
+				 RADEON_TV_DAC_STD_MASK |
+				 RADEON_TV_DAC_RDACPD |
+				 RADEON_TV_DAC_GDACPD |
+				 RADEON_TV_DAC_BDACPD |
+				 RADEON_TV_DAC_BGADJ_MASK |
+				 RADEON_TV_DAC_DACADJ_MASK);
+		tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
+				RADEON_TV_DAC_NHOLD |
+				RADEON_TV_DAC_STD_PS2 |
+				(0x58 << 16));
+
+		WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+		WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
+		WREG32(RADEON_DAC_CNTL2, dac2_cntl);
+	}
+
+	/* switch PM block to ACPI mode */
+	tmp = RREG32_PLL(RADEON_PLL_PWRMGT_CNTL);
+	tmp &= ~RADEON_PM_MODE_SEL;
+	WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp);
+
 }
 
 /*
@@ -1883,17 +1963,20 @@ static u32 r100_get_accessible_vram(stru
 void r100_vram_init_sizes(struct radeon_device *rdev)
 {
 	u64 config_aper_size;
-	u32 accessible;
 
+	/* work out accessible VRAM */
+	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
+	rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+	rdev->mc.visible_vram_size = r100_get_accessible_vram(rdev);
+	/* FIXME we don't use the second aperture yet when we could use it */
+	if (rdev->mc.visible_vram_size > rdev->mc.aper_size)
+		rdev->mc.visible_vram_size = rdev->mc.aper_size;
 	config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE);
-
 	if (rdev->flags & RADEON_IS_IGP) {
 		uint32_t tom;
 		/* read NB_TOM to get the amount of ram stolen for the GPU */
 		tom = RREG32(RADEON_NB_TOM);
 		rdev->mc.real_vram_size = (((tom >> 16) - (tom & 0xffff) + 1) << 16);
-		/* for IGPs we need to keep VRAM where it was put by the BIOS */
-		rdev->mc.vram_location = (tom & 0xffff) << 16;
 		WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
 		rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
 	} else {
@@ -1905,30 +1988,19 @@ void r100_vram_init_sizes(struct radeon_
 			rdev->mc.real_vram_size = 8192 * 1024;
 			WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
 		}
-		/* let driver place VRAM */
-		rdev->mc.vram_location = 0xFFFFFFFFUL;
-		 /* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM - 
-		  * Novell bug 204882 + along with lots of ubuntu ones */
+		/* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM - 
+		 * Novell bug 204882 + along with lots of ubuntu ones
+		 */
 		if (config_aper_size > rdev->mc.real_vram_size)
 			rdev->mc.mc_vram_size = config_aper_size;
 		else
 			rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
 	}
-
-	/* work out accessible VRAM */
-	accessible = r100_get_accessible_vram(rdev);
-
-	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-	rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
-
-	if (accessible > rdev->mc.aper_size)
-		accessible = rdev->mc.aper_size;
-
-	if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
+	/* FIXME remove this once we support unmappable VRAM */
+	if (rdev->mc.mc_vram_size > rdev->mc.aper_size) {
 		rdev->mc.mc_vram_size = rdev->mc.aper_size;
-
-	if (rdev->mc.real_vram_size > rdev->mc.aper_size)
 		rdev->mc.real_vram_size = rdev->mc.aper_size;
+	}
 }
 
 void r100_vga_set_state(struct radeon_device *rdev, bool state)
@@ -1945,11 +2017,19 @@ void r100_vga_set_state(struct radeon_de
 	WREG32(RADEON_CONFIG_CNTL, temp);
 }
 
-void r100_vram_info(struct radeon_device *rdev)
+void r100_mc_init(struct radeon_device *rdev)
 {
-	r100_vram_get_type(rdev);
+	u64 base;
 
+	r100_vram_get_type(rdev);
 	r100_vram_init_sizes(rdev);
+	base = rdev->mc.aper_base;
+	if (rdev->flags & RADEON_IS_IGP)
+		base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
+	radeon_vram_location(rdev, &rdev->mc, base);
+	if (!(rdev->flags & RADEON_IS_AGP))
+		radeon_gtt_location(rdev, &rdev->mc);
+	radeon_update_bandwidth_info(rdev);
 }
 
 
@@ -2313,6 +2393,8 @@ void r100_bandwidth_update(struct radeon
 	uint32_t pixel_bytes1 = 0;
 	uint32_t pixel_bytes2 = 0;
 
+	radeon_update_display_priority(rdev);
+
 	if (rdev->mode_info.crtcs[0]->base.enabled) {
 		mode1 = &rdev->mode_info.crtcs[0]->base.mode;
 		pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8;
@@ -2341,11 +2423,8 @@ void r100_bandwidth_update(struct radeon
 	/*
 	 * determine is there is enough bw for current mode
 	 */
-	mclk_ff.full = rfixed_const(rdev->clock.default_mclk);
-	temp_ff.full = rfixed_const(100);
-	mclk_ff.full = rfixed_div(mclk_ff, temp_ff);
-	sclk_ff.full = rfixed_const(rdev->clock.default_sclk);
-	sclk_ff.full = rfixed_div(sclk_ff, temp_ff);
+	sclk_ff = rdev->pm.sclk;
+	mclk_ff = rdev->pm.mclk;
 
 	temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1);
 	temp_ff.full = rfixed_const(temp);
@@ -2806,7 +2885,7 @@ static int r100_cs_track_texture_check(s
 {
 	struct radeon_bo *robj;
 	unsigned long size;
-	unsigned u, i, w, h;
+	unsigned u, i, w, h, d;
 	int ret;
 
 	for (u = 0; u < track->num_texture; u++) {
@@ -2838,20 +2917,25 @@ static int r100_cs_track_texture_check(s
 			h = h / (1 << i);
 			if (track->textures[u].roundup_h)
 				h = roundup_pow_of_two(h);
+			if (track->textures[u].tex_coord_type == 1) {
+				d = (1 << track->textures[u].txdepth) / (1 << i);
+				if (!d)
+					d = 1;
+			} else {
+				d = 1;
+			}
 			if (track->textures[u].compress_format) {
 
-				size += r100_track_compress_size(track->textures[u].compress_format, w, h);
+				size += r100_track_compress_size(track->textures[u].compress_format, w, h) * d;
 				/* compressed textures are block based */
 			} else
-				size += w * h;
+				size += w * h * d;
 		}
 		size *= track->textures[u].cpp;
 
 		switch (track->textures[u].tex_coord_type) {
 		case 0:
-			break;
 		case 1:
-			size *= (1 << track->textures[u].txdepth);
 			break;
 		case 2:
 			if (track->separate_cube) {
@@ -2885,7 +2969,7 @@ int r100_cs_track_check(struct radeon_de
 
 	for (i = 0; i < track->num_cb; i++) {
 		if (track->cb[i].robj == NULL) {
-			if (!(track->fastfill || track->color_channel_mask ||
+			if (!(track->zb_cb_clear || track->color_channel_mask ||
 			      track->blend_read_enable)) {
 				continue;
 			}
@@ -2922,7 +3006,11 @@ int r100_cs_track_check(struct radeon_de
 		}
 	}
 	prim_walk = (track->vap_vf_cntl >> 4) & 0x3;
-	nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
+	if (track->vap_vf_cntl & (1 << 14)) {
+		nverts = track->vap_alt_nverts;
+	} else {
+		nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
+	}
 	switch (prim_walk) {
 	case 1:
 		for (i = 0; i < track->num_arrays; i++) {
@@ -3220,10 +3308,9 @@ void r100_mc_stop(struct radeon_device *
 void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save)
 {
 	/* Update base address for crtc */
-	WREG32(R_00023C_DISPLAY_BASE_ADDR, rdev->mc.vram_location);
+	WREG32(R_00023C_DISPLAY_BASE_ADDR, rdev->mc.vram_start);
 	if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
-		WREG32(R_00033C_CRTC2_DISPLAY_BASE_ADDR,
-				rdev->mc.vram_location);
+		WREG32(R_00033C_CRTC2_DISPLAY_BASE_ADDR, rdev->mc.vram_start);
 	}
 	/* Restore CRTC registers */
 	WREG8(R_0003C2_GENMO_WT, save->GENMO_WT);
@@ -3369,6 +3456,7 @@ int r100_suspend(struct radeon_device *r
 
 void r100_fini(struct radeon_device *rdev)
 {
+	radeon_pm_fini(rdev);
 	r100_cp_fini(rdev);
 	r100_wb_fini(rdev);
 	r100_ib_fini(rdev);
@@ -3384,32 +3472,6 @@ void r100_fini(struct radeon_device *rde
 	rdev->bios = NULL;
 }
 
-int r100_mc_init(struct radeon_device *rdev)
-{
-	int r;
-	u32 tmp;
-
-	/* Setup GPU memory space */
-	rdev->mc.vram_location = 0xFFFFFFFFUL;
-	rdev->mc.gtt_location = 0xFFFFFFFFUL;
-	if (rdev->flags & RADEON_IS_IGP) {
-		tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM));
-		rdev->mc.vram_location = tmp << 16;
-	}
-	if (rdev->flags & RADEON_IS_AGP) {
-		r = radeon_agp_init(rdev);
-		if (r) {
-			radeon_agp_disable(rdev);
-		} else {
-			rdev->mc.gtt_location = rdev->mc.agp_base;
-		}
-	}
-	r = radeon_mc_setup(rdev);
-	if (r)
-		return r;
-	return 0;
-}
-
 int r100_init(struct radeon_device *rdev)
 {
 	int r;
@@ -3452,12 +3514,15 @@ int r100_init(struct radeon_device *rdev
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
 	radeon_pm_init(rdev);
-	/* Get vram informations */
-	r100_vram_info(rdev);
-	/* Initialize memory controller (also test AGP) */
-	r = r100_mc_init(rdev);
-	if (r)
-		return r;
+	/* initialize AGP */
+	if (rdev->flags & RADEON_IS_AGP) {
+		r = radeon_agp_init(rdev);
+		if (r) {
+			radeon_agp_disable(rdev);
+		}
+	}
+	/* initialize VRAM */
+	r100_mc_init(rdev);
 	/* Fence driver */
 	r = radeon_fence_driver_init(rdev);
 	if (r)
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r100_track.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r100_track.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r100_track.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r100_track.h	2010-05-16 17:17:36.000000000 -0400
@@ -64,6 +64,7 @@ struct r100_cs_track {
 	unsigned			maxy;
 	unsigned			vtx_size;
 	unsigned			vap_vf_cntl;
+	unsigned			vap_alt_nverts;
 	unsigned			immd_dwords;
 	unsigned			num_arrays;
 	unsigned			max_indx;
@@ -74,7 +75,7 @@ struct r100_cs_track {
 	struct r100_cs_track_texture	textures[R300_TRACK_MAX_TEXTURE];
 	bool				z_enabled;
 	bool                            separate_cube;
-	bool				fastfill;
+	bool				zb_cb_clear;
 	bool				blend_read_enable;
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r200.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r200.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r200.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r200.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,9 @@
 #include "radeon_drm.h"
 #include "radeon_reg.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 
+#include "r100d.h"
 #include "r200_reg_safe.h"
 
 #include "r100_track.h"
@@ -79,6 +81,51 @@ static int r200_get_vtx_size_0(uint32_t
 	return vtx_size;
 }
 
+int r200_copy_dma(struct radeon_device *rdev,
+		  uint64_t src_offset,
+		  uint64_t dst_offset,
+		  unsigned num_pages,
+		  struct radeon_fence *fence)
+{
+	uint32_t size;
+	uint32_t cur_size;
+	int i, num_loops;
+	int r = 0;
+
+	/* radeon pitch is /64 */
+	size = num_pages << PAGE_SHIFT;
+	num_loops = DIV_ROUND_UP(size, 0x1FFFFF);
+	r = radeon_ring_lock(rdev, num_loops * 4 + 64);
+	if (r) {
+		DRM_ERROR("radeon: moving bo (%d).\n", r);
+		return r;
+	}
+	/* Must wait for 2D idle & clean before DMA or hangs might happen */
+	radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0));
+	radeon_ring_write(rdev, (1 << 16));
+	for (i = 0; i < num_loops; i++) {
+		cur_size = size;
+		if (cur_size > 0x1FFFFF) {
+			cur_size = 0x1FFFFF;
+		}
+		size -= cur_size;
+		radeon_ring_write(rdev, PACKET0(0x720, 2));
+		radeon_ring_write(rdev, src_offset);
+		radeon_ring_write(rdev, dst_offset);
+		radeon_ring_write(rdev, cur_size | (1 << 31) | (1 << 30));
+		src_offset += cur_size;
+		dst_offset += cur_size;
+	}
+	radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0));
+	radeon_ring_write(rdev, RADEON_WAIT_DMA_GUI_IDLE);
+	if (fence) {
+		r = radeon_fence_emit(rdev, fence);
+	}
+	radeon_ring_unlock_commit(rdev);
+	return r;
+}
+
+
 static int r200_get_vtx_size_1(uint32_t vtx_fmt_1)
 {
 	int vtx_size, i, tex_size;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r300.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r300.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r300.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r300.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,10 +26,12 @@
  *          Jerome Glisse
  */
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_reg.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "radeon_drm.h"
 #include "r100_track.h"
 #include "r300d.h"
@@ -117,18 +119,19 @@ int rv370_pcie_gart_enable(struct radeon
 	r = radeon_gart_table_vram_pin(rdev);
 	if (r)
 		return r;
+	radeon_gart_restore(rdev);
 	/* discard memory request outside of configured range */
 	tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
 	WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
-	WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_location);
-	tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - RADEON_GPU_PAGE_SIZE;
+	WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_start);
+	tmp = rdev->mc.gtt_end & ~RADEON_GPU_PAGE_MASK;
 	WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, tmp);
 	WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0);
 	WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0);
 	table_addr = rdev->gart.table_addr;
 	WREG32_PCIE(RADEON_PCIE_TX_GART_BASE, table_addr);
 	/* FIXME: setup default page */
-	WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, rdev->mc.vram_location);
+	WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, rdev->mc.vram_start);
 	WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_HI, 0);
 	/* Clear error */
 	WREG32_PCIE(0x18, 0);
@@ -163,9 +166,9 @@ void rv370_pcie_gart_disable(struct rade
 
 void rv370_pcie_gart_fini(struct radeon_device *rdev)
 {
+	radeon_gart_fini(rdev);
 	rv370_pcie_gart_disable(rdev);
 	radeon_gart_table_vram_free(rdev);
-	radeon_gart_fini(rdev);
 }
 
 void r300_fence_ring_emit(struct radeon_device *rdev,
@@ -174,18 +177,20 @@ void r300_fence_ring_emit(struct radeon_
 	/* Who ever call radeon_fence_emit should call ring_lock and ask
 	 * for enough space (today caller are ib schedule and buffer move) */
 	/* Write SC register so SC & US assert idle */
-	radeon_ring_write(rdev, PACKET0(0x43E0, 0));
+	radeon_ring_write(rdev, PACKET0(R300_RE_SCISSORS_TL, 0));
 	radeon_ring_write(rdev, 0);
-	radeon_ring_write(rdev, PACKET0(0x43E4, 0));
+	radeon_ring_write(rdev, PACKET0(R300_RE_SCISSORS_BR, 0));
 	radeon_ring_write(rdev, 0);
 	/* Flush 3D cache */
-	radeon_ring_write(rdev, PACKET0(0x4E4C, 0));
-	radeon_ring_write(rdev, (2 << 0));
-	radeon_ring_write(rdev, PACKET0(0x4F18, 0));
-	radeon_ring_write(rdev, (1 << 0));
+	radeon_ring_write(rdev, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
+	radeon_ring_write(rdev, R300_RB3D_DC_FLUSH);
+	radeon_ring_write(rdev, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0));
+	radeon_ring_write(rdev, R300_ZC_FLUSH);
 	/* Wait until IDLE & CLEAN */
-	radeon_ring_write(rdev, PACKET0(0x1720, 0));
-	radeon_ring_write(rdev, (1 << 17) | (1 << 16)  | (1 << 9));
+	radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0));
+	radeon_ring_write(rdev, (RADEON_WAIT_3D_IDLECLEAN |
+				 RADEON_WAIT_2D_IDLECLEAN |
+				 RADEON_WAIT_DMA_GUI_IDLE));
 	radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0));
 	radeon_ring_write(rdev, rdev->config.r300.hdp_cntl |
 				RADEON_HDP_READ_BUFFER_INVALIDATE);
@@ -198,50 +203,6 @@ void r300_fence_ring_emit(struct radeon_
 	radeon_ring_write(rdev, RADEON_SW_INT_FIRE);
 }
 
-int r300_copy_dma(struct radeon_device *rdev,
-		  uint64_t src_offset,
-		  uint64_t dst_offset,
-		  unsigned num_pages,
-		  struct radeon_fence *fence)
-{
-	uint32_t size;
-	uint32_t cur_size;
-	int i, num_loops;
-	int r = 0;
-
-	/* radeon pitch is /64 */
-	size = num_pages << PAGE_SHIFT;
-	num_loops = DIV_ROUND_UP(size, 0x1FFFFF);
-	r = radeon_ring_lock(rdev, num_loops * 4 + 64);
-	if (r) {
-		DRM_ERROR("radeon: moving bo (%d).\n", r);
-		return r;
-	}
-	/* Must wait for 2D idle & clean before DMA or hangs might happen */
-	radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0 ));
-	radeon_ring_write(rdev, (1 << 16));
-	for (i = 0; i < num_loops; i++) {
-		cur_size = size;
-		if (cur_size > 0x1FFFFF) {
-			cur_size = 0x1FFFFF;
-		}
-		size -= cur_size;
-		radeon_ring_write(rdev, PACKET0(0x720, 2));
-		radeon_ring_write(rdev, src_offset);
-		radeon_ring_write(rdev, dst_offset);
-		radeon_ring_write(rdev, cur_size | (1 << 31) | (1 << 30));
-		src_offset += cur_size;
-		dst_offset += cur_size;
-	}
-	radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0));
-	radeon_ring_write(rdev, RADEON_WAIT_DMA_GUI_IDLE);
-	if (fence) {
-		r = radeon_fence_emit(rdev, fence);
-	}
-	radeon_ring_unlock_commit(rdev);
-	return r;
-}
-
 void r300_ring_start(struct radeon_device *rdev)
 {
 	unsigned gb_tile_config;
@@ -281,8 +242,8 @@ void r300_ring_start(struct radeon_devic
 	radeon_ring_write(rdev,
 			  RADEON_WAIT_2D_IDLECLEAN |
 			  RADEON_WAIT_3D_IDLECLEAN);
-	radeon_ring_write(rdev, PACKET0(0x170C, 0));
-	radeon_ring_write(rdev, 1 << 31);
+	radeon_ring_write(rdev, PACKET0(R300_DST_PIPE_CONFIG, 0));
+	radeon_ring_write(rdev, R300_PIPE_AUTO_CONFIG);
 	radeon_ring_write(rdev, PACKET0(R300_GB_SELECT, 0));
 	radeon_ring_write(rdev, 0);
 	radeon_ring_write(rdev, PACKET0(R300_GB_ENABLE, 0));
@@ -349,8 +310,8 @@ int r300_mc_wait_for_idle(struct radeon_
 
 	for (i = 0; i < rdev->usec_timeout; i++) {
 		/* read MC_STATUS */
-		tmp = RREG32(0x0150);
-		if (tmp & (1 << 4)) {
+		tmp = RREG32(RADEON_MC_STATUS);
+		if (tmp & R300_MC_IDLE) {
 			return 0;
 		}
 		DRM_UDELAY(1);
@@ -363,12 +324,12 @@ void r300_gpu_init(struct radeon_device
 	uint32_t gb_tile_config, tmp;
 
 	r100_hdp_reset(rdev);
-	/* FIXME: rv380 one pipes ? */
-	if ((rdev->family == CHIP_R300) || (rdev->family == CHIP_R350)) {
+	if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) ||
+	    (rdev->family == CHIP_R350 && rdev->pdev->device != 0x4148)) {
 		/* r300,r350 */
 		rdev->num_gb_pipes = 2;
 	} else {
-		/* rv350,rv370,rv380 */
+		/* rv350,rv370,rv380,r300 AD, r350 AH */
 		rdev->num_gb_pipes = 1;
 	}
 	rdev->num_z_pipes = 1;
@@ -395,8 +356,8 @@ void r300_gpu_init(struct radeon_device
 		       "programming pipes. Bad things might happen.\n");
 	}
 
-	tmp = RREG32(0x170C);
-	WREG32(0x170C, tmp | (1 << 31));
+	tmp = RREG32(R300_DST_PIPE_CONFIG);
+	WREG32(R300_DST_PIPE_CONFIG, tmp | R300_PIPE_AUTO_CONFIG);
 
 	WREG32(R300_RB2D_DSTCACHE_MODE,
 	       R300_DC_AUTOFLUSH_ENABLE |
@@ -437,8 +398,8 @@ int r300_ga_reset(struct radeon_device *
 			/* GA still busy soft reset it */
 			WREG32(0x429C, 0x200);
 			WREG32(R300_VAP_PVS_STATE_FLUSH_REG, 0);
-			WREG32(0x43E0, 0);
-			WREG32(0x43E4, 0);
+			WREG32(R300_RE_SCISSORS_TL, 0);
+			WREG32(R300_RE_SCISSORS_BR, 0);
 			WREG32(0x24AC, 0);
 		}
 		/* Wait to prevent race in RBBM_STATUS */
@@ -488,7 +449,7 @@ int r300_gpu_reset(struct radeon_device
 	}
 	/* Check if GPU is idle */
 	status = RREG32(RADEON_RBBM_STATUS);
-	if (status & (1 << 31)) {
+	if (status & RADEON_RBBM_ACTIVE) {
 		DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status);
 		return -1;
 	}
@@ -500,13 +461,13 @@ int r300_gpu_reset(struct radeon_device
 /*
  * r300,r350,rv350,rv380 VRAM info
  */
-void r300_vram_info(struct radeon_device *rdev)
+void r300_mc_init(struct radeon_device *rdev)
 {
-	uint32_t tmp;
+	u64 base;
+	u32 tmp;
 
 	/* DDR for all card after R300 & IGP */
 	rdev->mc.vram_is_ddr = true;
-
 	tmp = RREG32(RADEON_MEM_CNTL);
 	tmp &= R300_MEM_NUM_CHANNELS_MASK;
 	switch (tmp) {
@@ -515,8 +476,14 @@ void r300_vram_info(struct radeon_device
 	case 2: rdev->mc.vram_width = 256; break;
 	default:  rdev->mc.vram_width = 128; break;
 	}
-
 	r100_vram_init_sizes(rdev);
+	base = rdev->mc.aper_base;
+	if (rdev->flags & RADEON_IS_IGP)
+		base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
+	radeon_vram_location(rdev, &rdev->mc, base);
+	if (!(rdev->flags & RADEON_IS_AGP))
+		radeon_gtt_location(rdev, &rdev->mc);
+	radeon_update_bandwidth_info(rdev);
 }
 
 void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes)
@@ -578,6 +545,40 @@ void rv370_set_pcie_lanes(struct radeon_
 
 }
 
+int rv370_get_pcie_lanes(struct radeon_device *rdev)
+{
+	u32 link_width_cntl;
+
+	if (rdev->flags & RADEON_IS_IGP)
+		return 0;
+
+	if (!(rdev->flags & RADEON_IS_PCIE))
+		return 0;
+
+	/* FIXME wait for idle */
+
+	if (rdev->family < CHIP_R600)
+		link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
+	else
+		link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
+
+	switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) {
+	case RADEON_PCIE_LC_LINK_WIDTH_X0:
+		return 0;
+	case RADEON_PCIE_LC_LINK_WIDTH_X1:
+		return 1;
+	case RADEON_PCIE_LC_LINK_WIDTH_X2:
+		return 2;
+	case RADEON_PCIE_LC_LINK_WIDTH_X4:
+		return 4;
+	case RADEON_PCIE_LC_LINK_WIDTH_X8:
+		return 8;
+	case RADEON_PCIE_LC_LINK_WIDTH_X16:
+	default:
+		return 16;
+	}
+}
+
 #if defined(CONFIG_DEBUG_FS)
 static int rv370_debugfs_pcie_gart_info(struct seq_file *m, void *data)
 {
@@ -707,6 +708,8 @@ static int r300_packet0_check(struct rad
 			tile_flags |= R300_TXO_MACRO_TILE;
 		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
 			tile_flags |= R300_TXO_MICRO_TILE;
+		else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
+			tile_flags |= R300_TXO_MICRO_TILE_SQUARE;
 
 		tmp = idx_value + ((u32)reloc->lobj.gpu_offset);
 		tmp |= tile_flags;
@@ -726,6 +729,12 @@ static int r300_packet0_check(struct rad
 		/* VAP_VF_MAX_VTX_INDX */
 		track->max_indx = idx_value & 0x00FFFFFFUL;
 		break;
+	case 0x2088:
+		/* VAP_ALT_NUM_VERTICES - only valid on r500 */
+		if (p->rdev->family < CHIP_RV515)
+			goto fail;
+		track->vap_alt_nverts = idx_value & 0xFFFFFF;
+		break;
 	case 0x43E4:
 		/* SC_SCISSOR1 */
 		track->maxy = ((idx_value >> 13) & 0x1FFF) + 1;
@@ -757,11 +766,12 @@ static int r300_packet0_check(struct rad
 			tile_flags |= R300_COLOR_TILE_ENABLE;
 		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
 			tile_flags |= R300_COLOR_MICROTILE_ENABLE;
+		else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
+			tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE;
 
 		tmp = idx_value & ~(0x7 << 16);
 		tmp |= tile_flags;
 		ib[idx] = tmp;
-
 		i = (reg - 0x4E38) >> 2;
 		track->cb[i].pitch = idx_value & 0x3FFE;
 		switch (((idx_value >> 21) & 0xF)) {
@@ -828,7 +838,9 @@ static int r300_packet0_check(struct rad
 		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
 			tile_flags |= R300_DEPTHMACROTILE_ENABLE;
 		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-			tile_flags |= R300_DEPTHMICROTILE_TILED;;
+			tile_flags |= R300_DEPTHMICROTILE_TILED;
+		else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
+			tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE;
 
 		tmp = idx_value & ~(0x7 << 16);
 		tmp |= tile_flags;
@@ -1032,7 +1044,7 @@ static int r300_packet0_check(struct rad
 		break;
 	case 0x4d1c:
 		/* ZB_BW_CNTL */
-		track->fastfill = !!(idx_value & (1 << 2));
+		track->zb_cb_clear = !!(idx_value & (1 << 5));
 		break;
 	case 0x4e04:
 		/* RB3D_BLENDCNTL */
@@ -1044,11 +1056,13 @@ static int r300_packet0_check(struct rad
 			break;
 		/* fallthrough do not move */
 	default:
-		printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
-		       reg, idx);
-		return -EINVAL;
+		goto fail;
 	}
 	return 0;
+fail:
+	printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
+	       reg, idx);
+	return -EINVAL;
 }
 
 static int r300_packet3_check(struct radeon_cs_parser *p,
@@ -1330,6 +1344,7 @@ int r300_suspend(struct radeon_device *r
 
 void r300_fini(struct radeon_device *rdev)
 {
+	radeon_pm_fini(rdev);
 	r100_cp_fini(rdev);
 	r100_wb_fini(rdev);
 	r100_ib_fini(rdev);
@@ -1387,12 +1402,15 @@ int r300_init(struct radeon_device *rdev
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
 	radeon_pm_init(rdev);
-	/* Get vram informations */
-	r300_vram_info(rdev);
-	/* Initialize memory controller (also test AGP) */
-	r = r420_mc_init(rdev);
-	if (r)
-		return r;
+	/* initialize AGP */
+	if (rdev->flags & RADEON_IS_AGP) {
+		r = radeon_agp_init(rdev);
+		if (r) {
+			radeon_agp_disable(rdev);
+		}
+	}
+	/* initialize memory controller */
+	r300_mc_init(rdev);
 	/* Fence driver */
 	r = radeon_fence_driver_init(rdev);
 	if (r)
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r300_cmdbuf.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r300_cmdbuf.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r300_cmdbuf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r300_cmdbuf.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 
 #include "drmP.h"
 #include "drm.h"
+#include "drm_buffer.h"
 #include "radeon_drm.h"
 #include "radeon_drv.h"
 #include "r300_reg.h"
@@ -299,46 +300,42 @@ static __inline__ int r300_emit_carefull
 	int reg;
 	int sz;
 	int i;
-	int values[64];
+	u32 *value;
 	RING_LOCALS;
 
 	sz = header.packet0.count;
 	reg = (header.packet0.reghi << 8) | header.packet0.reglo;
 
 	if ((sz > 64) || (sz < 0)) {
-		DRM_ERROR
-		    ("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n",
-		     reg, sz);
+		DRM_ERROR("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n",
+			 reg, sz);
 		return -EINVAL;
 	}
+
 	for (i = 0; i < sz; i++) {
-		values[i] = ((int *)cmdbuf->buf)[i];
 		switch (r300_reg_flags[(reg >> 2) + i]) {
 		case MARK_SAFE:
 			break;
 		case MARK_CHECK_OFFSET:
-			if (!radeon_check_offset(dev_priv, (u32) values[i])) {
-				DRM_ERROR
-				    ("Offset failed range check (reg=%04x sz=%d)\n",
-				     reg, sz);
+			value = drm_buffer_pointer_to_dword(cmdbuf->buffer, i);
+			if (!radeon_check_offset(dev_priv, *value)) {
+				DRM_ERROR("Offset failed range check (reg=%04x sz=%d)\n",
+					 reg, sz);
 				return -EINVAL;
 			}
 			break;
 		default:
 			DRM_ERROR("Register %04x failed check as flag=%02x\n",
-				  reg + i * 4, r300_reg_flags[(reg >> 2) + i]);
+				reg + i * 4, r300_reg_flags[(reg >> 2) + i]);
 			return -EINVAL;
 		}
 	}
 
 	BEGIN_RING(1 + sz);
 	OUT_RING(CP_PACKET0(reg, sz - 1));
-	OUT_RING_TABLE(values, sz);
+	OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
 	ADVANCE_RING();
 
-	cmdbuf->buf += sz * 4;
-	cmdbuf->bufsz -= sz * 4;
-
 	return 0;
 }
 
@@ -362,7 +359,7 @@ static __inline__ int r300_emit_packet0(
 	if (!sz)
 		return 0;
 
-	if (sz * 4 > cmdbuf->bufsz)
+	if (sz * 4 > drm_buffer_unprocessed(cmdbuf->buffer))
 		return -EINVAL;
 
 	if (reg + sz * 4 >= 0x10000) {
@@ -380,12 +377,9 @@ static __inline__ int r300_emit_packet0(
 
 	BEGIN_RING(1 + sz);
 	OUT_RING(CP_PACKET0(reg, sz - 1));
-	OUT_RING_TABLE((int *)cmdbuf->buf, sz);
+	OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
 	ADVANCE_RING();
 
-	cmdbuf->buf += sz * 4;
-	cmdbuf->bufsz -= sz * 4;
-
 	return 0;
 }
 
@@ -407,7 +401,7 @@ static __inline__ int r300_emit_vpu(drm_
 
 	if (!sz)
 		return 0;
-	if (sz * 16 > cmdbuf->bufsz)
+	if (sz * 16 > drm_buffer_unprocessed(cmdbuf->buffer))
 		return -EINVAL;
 
 	/* VAP is very sensitive so we purge cache before we program it
@@ -426,7 +420,7 @@ static __inline__ int r300_emit_vpu(drm_
 	BEGIN_RING(3 + sz * 4);
 	OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr);
 	OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1));
-	OUT_RING_TABLE((int *)cmdbuf->buf, sz * 4);
+	OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz * 4);
 	ADVANCE_RING();
 
 	BEGIN_RING(2);
@@ -434,9 +428,6 @@ static __inline__ int r300_emit_vpu(drm_
 	OUT_RING(0);
 	ADVANCE_RING();
 
-	cmdbuf->buf += sz * 16;
-	cmdbuf->bufsz -= sz * 16;
-
 	return 0;
 }
 
@@ -449,14 +440,14 @@ static __inline__ int r300_emit_clear(dr
 {
 	RING_LOCALS;
 
-	if (8 * 4 > cmdbuf->bufsz)
+	if (8 * 4 > drm_buffer_unprocessed(cmdbuf->buffer))
 		return -EINVAL;
 
 	BEGIN_RING(10);
 	OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8));
 	OUT_RING(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING |
 		 (1 << R300_PRIM_NUM_VERTICES_SHIFT));
-	OUT_RING_TABLE((int *)cmdbuf->buf, 8);
+	OUT_RING_DRM_BUFFER(cmdbuf->buffer, 8);
 	ADVANCE_RING();
 
 	BEGIN_RING(4);
@@ -468,9 +459,6 @@ static __inline__ int r300_emit_clear(dr
 	/* set flush flag */
 	dev_priv->track_flush |= RADEON_FLUSH_EMITED;
 
-	cmdbuf->buf += 8 * 4;
-	cmdbuf->bufsz -= 8 * 4;
-
 	return 0;
 }
 
@@ -480,28 +468,29 @@ static __inline__ int r300_emit_3d_load_
 {
 	int count, i, k;
 #define MAX_ARRAY_PACKET  64
-	u32 payload[MAX_ARRAY_PACKET];
+	u32 *data;
 	u32 narrays;
 	RING_LOCALS;
 
-	count = (header >> 16) & 0x3fff;
+	count = (header & RADEON_CP_PACKET_COUNT_MASK) >> 16;
 
 	if ((count + 1) > MAX_ARRAY_PACKET) {
 		DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
 			  count);
 		return -EINVAL;
 	}
-	memset(payload, 0, MAX_ARRAY_PACKET * 4);
-	memcpy(payload, cmdbuf->buf + 4, (count + 1) * 4);
-
 	/* carefully check packet contents */
 
-	narrays = payload[0];
+	/* We have already read the header so advance the buffer. */
+	drm_buffer_advance(cmdbuf->buffer, 4);
+
+	narrays = *(u32 *)drm_buffer_pointer_to_dword(cmdbuf->buffer, 0);
 	k = 0;
 	i = 1;
 	while ((k < narrays) && (i < (count + 1))) {
 		i++;		/* skip attribute field */
-		if (!radeon_check_offset(dev_priv, payload[i])) {
+		data = drm_buffer_pointer_to_dword(cmdbuf->buffer, i);
+		if (!radeon_check_offset(dev_priv, *data)) {
 			DRM_ERROR
 			    ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
 			     k, i);
@@ -512,7 +501,8 @@ static __inline__ int r300_emit_3d_load_
 		if (k == narrays)
 			break;
 		/* have one more to process, they come in pairs */
-		if (!radeon_check_offset(dev_priv, payload[i])) {
+		data = drm_buffer_pointer_to_dword(cmdbuf->buffer, i);
+		if (!radeon_check_offset(dev_priv, *data)) {
 			DRM_ERROR
 			    ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
 			     k, i);
@@ -533,30 +523,30 @@ static __inline__ int r300_emit_3d_load_
 
 	BEGIN_RING(count + 2);
 	OUT_RING(header);
-	OUT_RING_TABLE(payload, count + 1);
+	OUT_RING_DRM_BUFFER(cmdbuf->buffer, count + 1);
 	ADVANCE_RING();
 
-	cmdbuf->buf += (count + 2) * 4;
-	cmdbuf->bufsz -= (count + 2) * 4;
-
 	return 0;
 }
 
 static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
 					     drm_radeon_kcmd_buffer_t *cmdbuf)
 {
-	u32 *cmd = (u32 *) cmdbuf->buf;
+	u32 *cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0);
 	int count, ret;
 	RING_LOCALS;
 
-	count=(cmd[0]>>16) & 0x3fff;
 
-	if (cmd[0] & 0x8000) {
-		u32 offset;
+	count = (*cmd & RADEON_CP_PACKET_COUNT_MASK) >> 16;
 
-		if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
+	if (*cmd & 0x8000) {
+		u32 offset;
+		u32 *cmd1 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1);
+		if (*cmd1 & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
 			      | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
-			offset = cmd[2] << 10;
+
+			u32 *cmd2 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 2);
+			offset = *cmd2 << 10;
 			ret = !radeon_check_offset(dev_priv, offset);
 			if (ret) {
 				DRM_ERROR("Invalid bitblt first offset is %08X\n", offset);
@@ -564,9 +554,10 @@ static __inline__ int r300_emit_bitblt_m
 			}
 		}
 
-		if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
-		    (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
-			offset = cmd[3] << 10;
+		if ((*cmd1 & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
+		    (*cmd1 & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
+			u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3);
+			offset = *cmd3 << 10;
 			ret = !radeon_check_offset(dev_priv, offset);
 			if (ret) {
 				DRM_ERROR("Invalid bitblt second offset is %08X\n", offset);
@@ -577,28 +568,25 @@ static __inline__ int r300_emit_bitblt_m
 	}
 
 	BEGIN_RING(count+2);
-	OUT_RING(cmd[0]);
-	OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
+	OUT_RING_DRM_BUFFER(cmdbuf->buffer, count + 2);
 	ADVANCE_RING();
 
-	cmdbuf->buf += (count+2)*4;
-	cmdbuf->bufsz -= (count+2)*4;
-
 	return 0;
 }
 
 static __inline__ int r300_emit_draw_indx_2(drm_radeon_private_t *dev_priv,
 					    drm_radeon_kcmd_buffer_t *cmdbuf)
 {
-	u32 *cmd;
+	u32 *cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0);
+	u32 *cmd1 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1);
 	int count;
 	int expected_count;
 	RING_LOCALS;
 
-	cmd = (u32 *) cmdbuf->buf;
-	count = (cmd[0]>>16) & 0x3fff;
-	expected_count = cmd[1] >> 16;
-	if (!(cmd[1] & R300_VAP_VF_CNTL__INDEX_SIZE_32bit))
+	count = (*cmd & RADEON_CP_PACKET_COUNT_MASK) >> 16;
+
+	expected_count = *cmd1 >> 16;
+	if (!(*cmd1 & R300_VAP_VF_CNTL__INDEX_SIZE_32bit))
 		expected_count = (expected_count+1)/2;
 
 	if (count && count != expected_count) {
@@ -608,55 +596,53 @@ static __inline__ int r300_emit_draw_ind
 	}
 
 	BEGIN_RING(count+2);
-	OUT_RING(cmd[0]);
-	OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
+	OUT_RING_DRM_BUFFER(cmdbuf->buffer, count + 2);
 	ADVANCE_RING();
 
-	cmdbuf->buf += (count+2)*4;
-	cmdbuf->bufsz -= (count+2)*4;
-
 	if (!count) {
-		drm_r300_cmd_header_t header;
+		drm_r300_cmd_header_t stack_header, *header;
+		u32 *cmd1, *cmd2, *cmd3;
 
-		if (cmdbuf->bufsz < 4*4 + sizeof(header)) {
+		if (drm_buffer_unprocessed(cmdbuf->buffer)
+				< 4*4 + sizeof(stack_header)) {
 			DRM_ERROR("3D_DRAW_INDX_2: expect subsequent INDX_BUFFER, but stream is too short.\n");
 			return -EINVAL;
 		}
 
-		header.u = *(unsigned int *)cmdbuf->buf;
+		header = drm_buffer_read_object(cmdbuf->buffer,
+				sizeof(stack_header), &stack_header);
 
-		cmdbuf->buf += sizeof(header);
-		cmdbuf->bufsz -= sizeof(header);
-		cmd = (u32 *) cmdbuf->buf;
+		cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0);
+		cmd1 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1);
+		cmd2 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 2);
+		cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3);
 
-		if (header.header.cmd_type != R300_CMD_PACKET3 ||
-		    header.packet3.packet != R300_CMD_PACKET3_RAW ||
-		    cmd[0] != CP_PACKET3(RADEON_CP_INDX_BUFFER, 2)) {
+		if (header->header.cmd_type != R300_CMD_PACKET3 ||
+		    header->packet3.packet != R300_CMD_PACKET3_RAW ||
+		    *cmd != CP_PACKET3(RADEON_CP_INDX_BUFFER, 2)) {
 			DRM_ERROR("3D_DRAW_INDX_2: expect subsequent INDX_BUFFER.\n");
 			return -EINVAL;
 		}
 
-		if ((cmd[1] & 0x8000ffff) != 0x80000810) {
-			DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
+		if ((*cmd1 & 0x8000ffff) != 0x80000810) {
+			DRM_ERROR("Invalid indx_buffer reg address %08X\n",
+					*cmd1);
 			return -EINVAL;
 		}
-		if (!radeon_check_offset(dev_priv, cmd[2])) {
-			DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
+		if (!radeon_check_offset(dev_priv, *cmd2)) {
+			DRM_ERROR("Invalid indx_buffer offset is %08X\n",
+					*cmd2);
 			return -EINVAL;
 		}
-		if (cmd[3] != expected_count) {
+		if (*cmd3 != expected_count) {
 			DRM_ERROR("INDX_BUFFER: buffer size %i, expected %i\n",
-				cmd[3], expected_count);
+				*cmd3, expected_count);
 			return -EINVAL;
 		}
 
 		BEGIN_RING(4);
-		OUT_RING(cmd[0]);
-		OUT_RING_TABLE((int *)(cmdbuf->buf + 4), 3);
+		OUT_RING_DRM_BUFFER(cmdbuf->buffer, 4);
 		ADVANCE_RING();
-
-		cmdbuf->buf += 4*4;
-		cmdbuf->bufsz -= 4*4;
 	}
 
 	return 0;
@@ -665,39 +651,39 @@ static __inline__ int r300_emit_draw_ind
 static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
 					    drm_radeon_kcmd_buffer_t *cmdbuf)
 {
-	u32 header;
+	u32 *header;
 	int count;
 	RING_LOCALS;
 
-	if (4 > cmdbuf->bufsz)
+	if (4 > drm_buffer_unprocessed(cmdbuf->buffer))
 		return -EINVAL;
 
 	/* Fixme !! This simply emits a packet without much checking.
 	   We need to be smarter. */
 
 	/* obtain first word - actual packet3 header */
-	header = *(u32 *) cmdbuf->buf;
+	header = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0);
 
 	/* Is it packet 3 ? */
-	if ((header >> 30) != 0x3) {
-		DRM_ERROR("Not a packet3 header (0x%08x)\n", header);
+	if ((*header >> 30) != 0x3) {
+		DRM_ERROR("Not a packet3 header (0x%08x)\n", *header);
 		return -EINVAL;
 	}
 
-	count = (header >> 16) & 0x3fff;
+	count = (*header >> 16) & 0x3fff;
 
 	/* Check again now that we know how much data to expect */
-	if ((count + 2) * 4 > cmdbuf->bufsz) {
+	if ((count + 2) * 4 > drm_buffer_unprocessed(cmdbuf->buffer)) {
 		DRM_ERROR
 		    ("Expected packet3 of length %d but have only %d bytes left\n",
-		     (count + 2) * 4, cmdbuf->bufsz);
+		     (count + 2) * 4, drm_buffer_unprocessed(cmdbuf->buffer));
 		return -EINVAL;
 	}
 
 	/* Is it a packet type we know about ? */
-	switch (header & 0xff00) {
+	switch (*header & 0xff00) {
 	case RADEON_3D_LOAD_VBPNTR:	/* load vertex array pointers */
-		return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, header);
+		return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, *header);
 
 	case RADEON_CNTL_BITBLT_MULTI:
 		return r300_emit_bitblt_multi(dev_priv, cmdbuf);
@@ -723,18 +709,14 @@ static __inline__ int r300_emit_raw_pack
 		/* these packets are safe */
 		break;
 	default:
-		DRM_ERROR("Unknown packet3 header (0x%08x)\n", header);
+		DRM_ERROR("Unknown packet3 header (0x%08x)\n", *header);
 		return -EINVAL;
 	}
 
 	BEGIN_RING(count + 2);
-	OUT_RING(header);
-	OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
+	OUT_RING_DRM_BUFFER(cmdbuf->buffer, count + 2);
 	ADVANCE_RING();
 
-	cmdbuf->buf += (count + 2) * 4;
-	cmdbuf->bufsz -= (count + 2) * 4;
-
 	return 0;
 }
 
@@ -748,8 +730,7 @@ static __inline__ int r300_emit_packet3(
 {
 	int n;
 	int ret;
-	char *orig_buf = cmdbuf->buf;
-	int orig_bufsz = cmdbuf->bufsz;
+	int orig_iter = cmdbuf->buffer->iterator;
 
 	/* This is a do-while-loop so that we run the interior at least once,
 	 * even if cmdbuf->nbox is 0. Compare r300_emit_cliprects for rationale.
@@ -761,8 +742,7 @@ static __inline__ int r300_emit_packet3(
 			if (ret)
 				return ret;
 
-			cmdbuf->buf = orig_buf;
-			cmdbuf->bufsz = orig_bufsz;
+			cmdbuf->buffer->iterator = orig_iter;
 		}
 
 		switch (header.packet3.packet) {
@@ -785,9 +765,9 @@ static __inline__ int r300_emit_packet3(
 			break;
 
 		default:
-			DRM_ERROR("bad packet3 type %i at %p\n",
+			DRM_ERROR("bad packet3 type %i at byte %d\n",
 				  header.packet3.packet,
-				  cmdbuf->buf - sizeof(header));
+				  cmdbuf->buffer->iterator - (int)sizeof(header));
 			return -EINVAL;
 		}
 
@@ -923,12 +903,13 @@ static int r300_scratch(drm_radeon_priva
 			drm_r300_cmd_header_t header)
 {
 	u32 *ref_age_base;
-	u32 i, buf_idx, h_pending;
-	u64 ptr_addr;
+	u32 i, *buf_idx, h_pending;
+	u64 *ptr_addr;
+	u64 stack_ptr_addr;
 	RING_LOCALS;
 
-	if (cmdbuf->bufsz <
-	    (sizeof(u64) + header.scratch.n_bufs * sizeof(buf_idx))) {
+	if (drm_buffer_unprocessed(cmdbuf->buffer) <
+	    (sizeof(u64) + header.scratch.n_bufs * sizeof(*buf_idx))) {
 		return -EINVAL;
 	}
 
@@ -938,36 +919,35 @@ static int r300_scratch(drm_radeon_priva
 
 	dev_priv->scratch_ages[header.scratch.reg]++;
 
-	ptr_addr = get_unaligned((u64 *)cmdbuf->buf);
-	ref_age_base = (u32 *)(unsigned long)ptr_addr;
-
-	cmdbuf->buf += sizeof(u64);
-	cmdbuf->bufsz -= sizeof(u64);
+	ptr_addr = drm_buffer_read_object(cmdbuf->buffer,
+			sizeof(stack_ptr_addr), &stack_ptr_addr);
+	ref_age_base = (u32 *)(unsigned long)get_unaligned(ptr_addr);
 
 	for (i=0; i < header.scratch.n_bufs; i++) {
-		buf_idx = *(u32 *)cmdbuf->buf;
-		buf_idx *= 2; /* 8 bytes per buf */
+		buf_idx = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0);
+		*buf_idx *= 2; /* 8 bytes per buf */
 
-		if (DRM_COPY_TO_USER(ref_age_base + buf_idx, &dev_priv->scratch_ages[header.scratch.reg], sizeof(u32))) {
+		if (DRM_COPY_TO_USER(ref_age_base + *buf_idx,
+				&dev_priv->scratch_ages[header.scratch.reg],
+				sizeof(u32)))
 			return -EINVAL;
-		}
 
-		if (DRM_COPY_FROM_USER(&h_pending, ref_age_base + buf_idx + 1, sizeof(u32))) {
+		if (DRM_COPY_FROM_USER(&h_pending,
+				ref_age_base + *buf_idx + 1,
+				sizeof(u32)))
 			return -EINVAL;
-		}
 
-		if (h_pending == 0) {
+		if (h_pending == 0)
 			return -EINVAL;
-		}
 
 		h_pending--;
 
-		if (DRM_COPY_TO_USER(ref_age_base + buf_idx + 1, &h_pending, sizeof(u32))) {
+		if (DRM_COPY_TO_USER(ref_age_base + *buf_idx + 1,
+					&h_pending,
+					sizeof(u32)))
 			return -EINVAL;
-		}
 
-		cmdbuf->buf += sizeof(buf_idx);
-		cmdbuf->bufsz -= sizeof(buf_idx);
+		drm_buffer_advance(cmdbuf->buffer, sizeof(*buf_idx));
 	}
 
 	BEGIN_RING(2);
@@ -1009,19 +989,16 @@ static inline int r300_emit_r500fp(drm_r
 	DRM_DEBUG("r500fp %d %d type: %d\n", sz, addr, type);
 	if (!sz)
 		return 0;
-	if (sz * stride * 4 > cmdbuf->bufsz)
+	if (sz * stride * 4 > drm_buffer_unprocessed(cmdbuf->buffer))
 		return -EINVAL;
 
 	BEGIN_RING(3 + sz * stride);
 	OUT_RING_REG(R500_GA_US_VECTOR_INDEX, addr);
 	OUT_RING(CP_PACKET0_TABLE(R500_GA_US_VECTOR_DATA, sz * stride - 1));
-	OUT_RING_TABLE((int *)cmdbuf->buf, sz * stride);
+	OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz * stride);
 
 	ADVANCE_RING();
 
-	cmdbuf->buf += sz * stride * 4;
-	cmdbuf->bufsz -= sz * stride * 4;
-
 	return 0;
 }
 
@@ -1053,19 +1030,18 @@ int r300_do_cp_cmdbuf(struct drm_device
 			goto cleanup;
 	}
 
-	while (cmdbuf->bufsz >= sizeof(drm_r300_cmd_header_t)) {
+	while (drm_buffer_unprocessed(cmdbuf->buffer)
+			>= sizeof(drm_r300_cmd_header_t)) {
 		int idx;
-		drm_r300_cmd_header_t header;
-
-		header.u = *(unsigned int *)cmdbuf->buf;
+		drm_r300_cmd_header_t *header, stack_header;
 
-		cmdbuf->buf += sizeof(header);
-		cmdbuf->bufsz -= sizeof(header);
+		header = drm_buffer_read_object(cmdbuf->buffer,
+				sizeof(stack_header), &stack_header);
 
-		switch (header.header.cmd_type) {
+		switch (header->header.cmd_type) {
 		case R300_CMD_PACKET0:
 			DRM_DEBUG("R300_CMD_PACKET0\n");
-			ret = r300_emit_packet0(dev_priv, cmdbuf, header);
+			ret = r300_emit_packet0(dev_priv, cmdbuf, *header);
 			if (ret) {
 				DRM_ERROR("r300_emit_packet0 failed\n");
 				goto cleanup;
@@ -1074,7 +1050,7 @@ int r300_do_cp_cmdbuf(struct drm_device
 
 		case R300_CMD_VPU:
 			DRM_DEBUG("R300_CMD_VPU\n");
-			ret = r300_emit_vpu(dev_priv, cmdbuf, header);
+			ret = r300_emit_vpu(dev_priv, cmdbuf, *header);
 			if (ret) {
 				DRM_ERROR("r300_emit_vpu failed\n");
 				goto cleanup;
@@ -1083,7 +1059,7 @@ int r300_do_cp_cmdbuf(struct drm_device
 
 		case R300_CMD_PACKET3:
 			DRM_DEBUG("R300_CMD_PACKET3\n");
-			ret = r300_emit_packet3(dev_priv, cmdbuf, header);
+			ret = r300_emit_packet3(dev_priv, cmdbuf, *header);
 			if (ret) {
 				DRM_ERROR("r300_emit_packet3 failed\n");
 				goto cleanup;
@@ -1117,8 +1093,8 @@ int r300_do_cp_cmdbuf(struct drm_device
 				int i;
 				RING_LOCALS;
 
-				BEGIN_RING(header.delay.count);
-				for (i = 0; i < header.delay.count; i++)
+				BEGIN_RING(header->delay.count);
+				for (i = 0; i < header->delay.count; i++)
 					OUT_RING(RADEON_CP_PACKET2);
 				ADVANCE_RING();
 			}
@@ -1126,7 +1102,7 @@ int r300_do_cp_cmdbuf(struct drm_device
 
 		case R300_CMD_DMA_DISCARD:
 			DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
-			idx = header.dma.buf_idx;
+			idx = header->dma.buf_idx;
 			if (idx < 0 || idx >= dma->buf_count) {
 				DRM_ERROR("buffer index %d (of %d max)\n",
 					  idx, dma->buf_count - 1);
@@ -1149,12 +1125,12 @@ int r300_do_cp_cmdbuf(struct drm_device
 
 		case R300_CMD_WAIT:
 			DRM_DEBUG("R300_CMD_WAIT\n");
-			r300_cmd_wait(dev_priv, header);
+			r300_cmd_wait(dev_priv, *header);
 			break;
 
 		case R300_CMD_SCRATCH:
 			DRM_DEBUG("R300_CMD_SCRATCH\n");
-			ret = r300_scratch(dev_priv, cmdbuf, header);
+			ret = r300_scratch(dev_priv, cmdbuf, *header);
 			if (ret) {
 				DRM_ERROR("r300_scratch failed\n");
 				goto cleanup;
@@ -1168,16 +1144,16 @@ int r300_do_cp_cmdbuf(struct drm_device
 				goto cleanup;
 			}
 			DRM_DEBUG("R300_CMD_R500FP\n");
-			ret = r300_emit_r500fp(dev_priv, cmdbuf, header);
+			ret = r300_emit_r500fp(dev_priv, cmdbuf, *header);
 			if (ret) {
 				DRM_ERROR("r300_emit_r500fp failed\n");
 				goto cleanup;
 			}
 			break;
 		default:
-			DRM_ERROR("bad cmd_type %i at %p\n",
-				  header.header.cmd_type,
-				  cmdbuf->buf - sizeof(header));
+			DRM_ERROR("bad cmd_type %i at byte %d\n",
+				  header->header.cmd_type,
+				  cmdbuf->buffer->iterator - (int)sizeof(*header));
 			ret = -EINVAL;
 			goto cleanup;
 		}
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r300_reg.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r300_reg.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r300_reg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r300_reg.h	2010-05-16 17:17:36.000000000 -0400
@@ -952,6 +952,7 @@
 #       define R300_TXO_ENDIAN_HALFDW_SWAP       (3 << 0)
 #       define R300_TXO_MACRO_TILE               (1 << 2)
 #       define R300_TXO_MICRO_TILE               (1 << 3)
+#       define R300_TXO_MICRO_TILE_SQUARE        (2 << 3)
 #       define R300_TXO_OFFSET_MASK              0xffffffe0
 #       define R300_TXO_OFFSET_SHIFT             5
 	/* END: Guess from R200 */
@@ -1360,6 +1361,7 @@
 #       define R300_COLORPITCH_MASK              0x00001FF8 /* GUESS */
 #       define R300_COLOR_TILE_ENABLE            (1 << 16) /* GUESS */
 #       define R300_COLOR_MICROTILE_ENABLE       (1 << 17) /* GUESS */
+#       define R300_COLOR_MICROTILE_SQUARE_ENABLE (2 << 17)
 #       define R300_COLOR_ENDIAN_NO_SWAP         (0 << 18) /* GUESS */
 #       define R300_COLOR_ENDIAN_WORD_SWAP       (1 << 18) /* GUESS */
 #       define R300_COLOR_ENDIAN_DWORD_SWAP      (2 << 18) /* GUESS */
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r420.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r420.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r420.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r420.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,9 +26,11 @@
  *          Jerome Glisse
  */
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "radeon_reg.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "atom.h"
 #include "r100d.h"
 #include "r420d.h"
@@ -40,28 +42,6 @@ static void r420_set_reg_safe(struct rad
 	rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r420_reg_safe_bm);
 }
 
-int r420_mc_init(struct radeon_device *rdev)
-{
-	int r;
-
-	/* Setup GPU memory space */
-	rdev->mc.vram_location = 0xFFFFFFFFUL;
-	rdev->mc.gtt_location = 0xFFFFFFFFUL;
-	if (rdev->flags & RADEON_IS_AGP) {
-		r = radeon_agp_init(rdev);
-		if (r) {
-			radeon_agp_disable(rdev);
-		} else {
-			rdev->mc.gtt_location = rdev->mc.agp_base;
-		}
-	}
-	r = radeon_mc_setup(rdev);
-	if (r) {
-		return r;
-	}
-	return 0;
-}
-
 void r420_pipes_init(struct radeon_device *rdev)
 {
 	unsigned tmp;
@@ -69,7 +49,8 @@ void r420_pipes_init(struct radeon_devic
 	unsigned num_pipes;
 
 	/* GA_ENHANCE workaround TCL deadlock issue */
-	WREG32(0x4274, (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3));
+	WREG32(R300_GA_ENHANCE, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL |
+	       (1 << 2) | (1 << 3));
 	/* add idle wait as per freedesktop.org bug 24041 */
 	if (r100_gui_wait_for_idle(rdev)) {
 		printk(KERN_WARNING "Failed to wait GUI idle while "
@@ -78,6 +59,12 @@ void r420_pipes_init(struct radeon_devic
 	/* get max number of pipes */
 	gb_pipe_select = RREG32(0x402C);
 	num_pipes = ((gb_pipe_select >> 12) & 3) + 1;
+
+	/* SE chips have 1 pipe */
+	if ((rdev->pdev->device == 0x5e4c) ||
+	    (rdev->pdev->device == 0x5e4f))
+		num_pipes = 1;
+
 	rdev->num_gb_pipes = num_pipes;
 	tmp = 0;
 	switch (num_pipes) {
@@ -97,17 +84,17 @@ void r420_pipes_init(struct radeon_devic
 		tmp = (7 << 1);
 		break;
 	}
-	WREG32(0x42C8, (1 << num_pipes) - 1);
+	WREG32(R500_SU_REG_DEST, (1 << num_pipes) - 1);
 	/* Sub pixel 1/12 so we can have 4K rendering according to doc */
-	tmp |= (1 << 4) | (1 << 0);
-	WREG32(0x4018, tmp);
+	tmp |= R300_TILE_SIZE_16 | R300_ENABLE_TILING;
+	WREG32(R300_GB_TILE_CONFIG, tmp);
 	if (r100_gui_wait_for_idle(rdev)) {
 		printk(KERN_WARNING "Failed to wait GUI idle while "
 		       "programming pipes. Bad things might happen.\n");
 	}
 
-	tmp = RREG32(0x170C);
-	WREG32(0x170C, tmp | (1 << 31));
+	tmp = RREG32(R300_DST_PIPE_CONFIG);
+	WREG32(R300_DST_PIPE_CONFIG, tmp | R300_PIPE_AUTO_CONFIG);
 
 	WREG32(R300_RB2D_DSTCACHE_MODE,
 	       RREG32(R300_RB2D_DSTCACHE_MODE) |
@@ -287,6 +274,7 @@ int r420_suspend(struct radeon_device *r
 
 void r420_fini(struct radeon_device *rdev)
 {
+	radeon_pm_fini(rdev);
 	r100_cp_fini(rdev);
 	r100_wb_fini(rdev);
 	r100_ib_fini(rdev);
@@ -348,13 +336,15 @@ int r420_init(struct radeon_device *rdev
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
 	radeon_pm_init(rdev);
-	/* Get vram informations */
-	r300_vram_info(rdev);
-	/* Initialize memory controller (also test AGP) */
-	r = r420_mc_init(rdev);
-	if (r) {
-		return r;
+	/* initialize AGP */
+	if (rdev->flags & RADEON_IS_AGP) {
+		r = radeon_agp_init(rdev);
+		if (r) {
+			radeon_agp_disable(rdev);
+		}
 	}
+	/* initialize memory controller */
+	r300_mc_init(rdev);
 	r420_debugfs(rdev);
 	/* Fence driver */
 	r = radeon_fence_driver_init(rdev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r500_reg.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r500_reg.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r500_reg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r500_reg.h	2010-05-16 17:17:36.000000000 -0400
@@ -717,54 +717,62 @@
 #define AVIVO_DVOA_BIT_DEPTH_CONTROL			0x7988
 
 #define AVIVO_DC_GPIO_HPD_A                 0x7e94
+#define AVIVO_DC_GPIO_HPD_Y                 0x7e9c
 
-#define AVIVO_GPIO_0                        0x7e30
-#define AVIVO_GPIO_1                        0x7e40
-#define AVIVO_GPIO_2                        0x7e50
-#define AVIVO_GPIO_3                        0x7e60
+#define AVIVO_DC_I2C_STATUS1				0x7d30
+#	define AVIVO_DC_I2C_DONE			(1 << 0)
+#	define AVIVO_DC_I2C_NACK			(1 << 1)
+#	define AVIVO_DC_I2C_HALT			(1 << 2)
+#	define AVIVO_DC_I2C_GO			        (1 << 3)
+#define AVIVO_DC_I2C_RESET 				0x7d34
+#	define AVIVO_DC_I2C_SOFT_RESET			(1 << 0)
+#	define AVIVO_DC_I2C_ABORT			(1 << 8)
+#define AVIVO_DC_I2C_CONTROL1 				0x7d38
+#	define AVIVO_DC_I2C_START			(1 << 0)
+#	define AVIVO_DC_I2C_STOP			(1 << 1)
+#	define AVIVO_DC_I2C_RECEIVE			(1 << 2)
+#	define AVIVO_DC_I2C_EN			        (1 << 8)
+#	define AVIVO_DC_I2C_PIN_SELECT(x)		((x) << 16)
+#	define AVIVO_SEL_DDC1			        0
+#	define AVIVO_SEL_DDC2			        1
+#	define AVIVO_SEL_DDC3			        2
+#define AVIVO_DC_I2C_CONTROL2 				0x7d3c
+#	define AVIVO_DC_I2C_ADDR_COUNT(x)		((x) << 0)
+#	define AVIVO_DC_I2C_DATA_COUNT(x)		((x) << 8)
+#define AVIVO_DC_I2C_CONTROL3 				0x7d40
+#	define AVIVO_DC_I2C_DATA_DRIVE_EN		(1 << 0)
+#	define AVIVO_DC_I2C_DATA_DRIVE_SEL		(1 << 1)
+#	define AVIVO_DC_I2C_CLK_DRIVE_EN		(1 << 7)
+#	define AVIVO_DC_I2C_RD_INTRA_BYTE_DELAY(x)      ((x) << 8)
+#	define AVIVO_DC_I2C_WR_INTRA_BYTE_DELAY(x)	((x) << 16)
+#	define AVIVO_DC_I2C_TIME_LIMIT(x)		((x) << 24)
+#define AVIVO_DC_I2C_DATA 				0x7d44
+#define AVIVO_DC_I2C_INTERRUPT_CONTROL 			0x7d48
+#	define AVIVO_DC_I2C_INTERRUPT_STATUS		(1 << 0)
+#	define AVIVO_DC_I2C_INTERRUPT_AK		(1 << 8)
+#	define AVIVO_DC_I2C_INTERRUPT_ENABLE		(1 << 16)
+#define AVIVO_DC_I2C_ARBITRATION 			0x7d50
+#	define AVIVO_DC_I2C_SW_WANTS_TO_USE_I2C		(1 << 0)
+#	define AVIVO_DC_I2C_SW_CAN_USE_I2C		(1 << 1)
+#	define AVIVO_DC_I2C_SW_DONE_USING_I2C		(1 << 8)
+#	define AVIVO_DC_I2C_HW_NEEDS_I2C		(1 << 9)
+#	define AVIVO_DC_I2C_ABORT_HDCP_I2C		(1 << 16)
+#	define AVIVO_DC_I2C_HW_USING_I2C		(1 << 17)
 
-#define AVIVO_DC_GPIO_HPD_Y                 0x7e9c
+#define AVIVO_DC_GPIO_DDC1_MASK 		        0x7e40
+#define AVIVO_DC_GPIO_DDC1_A 		                0x7e44
+#define AVIVO_DC_GPIO_DDC1_EN 		                0x7e48
+#define AVIVO_DC_GPIO_DDC1_Y 		                0x7e4c
 
-#define AVIVO_I2C_STATUS					0x7d30
-#	define AVIVO_I2C_STATUS_DONE				(1 << 0)
-#	define AVIVO_I2C_STATUS_NACK				(1 << 1)
-#	define AVIVO_I2C_STATUS_HALT				(1 << 2)
-#	define AVIVO_I2C_STATUS_GO				(1 << 3)
-#	define AVIVO_I2C_STATUS_MASK				0x7
-/* If radeon_mm_i2c is to be believed, this is HALT, NACK, and maybe
- * DONE? */
-#	define AVIVO_I2C_STATUS_CMD_RESET			0x7
-#	define AVIVO_I2C_STATUS_CMD_WAIT			(1 << 3)
-#define AVIVO_I2C_STOP						0x7d34
-#define AVIVO_I2C_START_CNTL				0x7d38
-#	define AVIVO_I2C_START						(1 << 8)
-#	define AVIVO_I2C_CONNECTOR0					(0 << 16)
-#	define AVIVO_I2C_CONNECTOR1					(1 << 16)
-#define R520_I2C_START (1<<0)
-#define R520_I2C_STOP (1<<1)
-#define R520_I2C_RX (1<<2)
-#define R520_I2C_EN (1<<8)
-#define R520_I2C_DDC1 (0<<16)
-#define R520_I2C_DDC2 (1<<16)
-#define R520_I2C_DDC3 (2<<16)
-#define R520_I2C_DDC_MASK (3<<16)
-#define AVIVO_I2C_CONTROL2					0x7d3c
-#	define AVIVO_I2C_7D3C_SIZE_SHIFT			8
-#	define AVIVO_I2C_7D3C_SIZE_MASK				(0xf << 8)
-#define AVIVO_I2C_CONTROL3						0x7d40
-/* Reading is done 4 bytes at a time: read the bottom 8 bits from
- * 7d44, four times in a row.
- * Writing is a little more complex.  First write DATA with
- * 0xnnnnnnzz, then 0xnnnnnnyy, where nnnnnn is some non-deterministic
- * magic number, zz is, I think, the slave address, and yy is the byte
- * you want to write. */
-#define AVIVO_I2C_DATA						0x7d44
-#define R520_I2C_ADDR_COUNT_MASK (0x7)
-#define R520_I2C_DATA_COUNT_SHIFT (8)
-#define R520_I2C_DATA_COUNT_MASK (0xF00)
-#define AVIVO_I2C_CNTL						0x7d50
-#	define AVIVO_I2C_EN							(1 << 0)
-#	define AVIVO_I2C_RESET						(1 << 8)
+#define AVIVO_DC_GPIO_DDC2_MASK 		        0x7e50
+#define AVIVO_DC_GPIO_DDC2_A 		                0x7e54
+#define AVIVO_DC_GPIO_DDC2_EN 		                0x7e58
+#define AVIVO_DC_GPIO_DDC2_Y 		                0x7e5c
+
+#define AVIVO_DC_GPIO_DDC3_MASK 		        0x7e60
+#define AVIVO_DC_GPIO_DDC3_A 		                0x7e64
+#define AVIVO_DC_GPIO_DDC3_EN 		                0x7e68
+#define AVIVO_DC_GPIO_DDC3_Y 		                0x7e6c
 
 #define AVIVO_DISP_INTERRUPT_STATUS                             0x7edc
 #       define AVIVO_D1_VBLANK_INTERRUPT                        (1 << 4)
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r520.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r520.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r520.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r520.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
  */
 #include "drmP.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "atom.h"
 #include "r520d.h"
 
@@ -119,19 +120,15 @@ static void r520_vram_get_type(struct ra
 		rdev->mc.vram_width *= 2;
 }
 
-void r520_vram_info(struct radeon_device *rdev)
+void r520_mc_init(struct radeon_device *rdev)
 {
-	fixed20_12 a;
 
 	r520_vram_get_type(rdev);
-
 	r100_vram_init_sizes(rdev);
-	/* FIXME: we should enforce default clock in case GPU is not in
-	 * default setup
-	 */
-	a.full = rfixed_const(100);
-	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
-	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+	radeon_vram_location(rdev, &rdev->mc, 0);
+	if (!(rdev->flags & RADEON_IS_AGP))
+		radeon_gtt_location(rdev, &rdev->mc);
+	radeon_update_bandwidth_info(rdev);
 }
 
 void r520_mc_program(struct radeon_device *rdev)
@@ -267,12 +264,15 @@ int r520_init(struct radeon_device *rdev
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
 	radeon_pm_init(rdev);
-	/* Get vram informations */
-	r520_vram_info(rdev);
-	/* Initialize memory controller (also test AGP) */
-	r = r420_mc_init(rdev);
-	if (r)
-		return r;
+	/* initialize AGP */
+	if (rdev->flags & RADEON_IS_AGP) {
+		r = radeon_agp_init(rdev);
+		if (r) {
+			radeon_agp_disable(rdev);
+		}
+	}
+	/* initialize memory controller */
+	r520_mc_init(rdev);
 	rv515_debugfs(rdev);
 	/* Fence driver */
 	r = radeon_fence_driver_init(rdev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_audio.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_audio.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_audio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_audio.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,7 +35,7 @@
  */
 static int r600_audio_chipset_supported(struct radeon_device *rdev)
 {
-	return (rdev->family >= CHIP_R600 && rdev->family < CHIP_RV710)
+	return (rdev->family >= CHIP_R600 && rdev->family < CHIP_CEDAR)
 		|| rdev->family == CHIP_RS600
 		|| rdev->family == CHIP_RS690
 		|| rdev->family == CHIP_RS740;
@@ -147,15 +147,23 @@ static void r600_audio_update_hdmi(unsig
 }
 
 /*
+ * turn on/off audio engine
+ */
+static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable)
+{
+	DRM_INFO("%s audio support", enable ? "Enabling" : "Disabling");
+	WREG32_P(R600_AUDIO_ENABLE, enable ? 0x81000000 : 0x0, ~0x81000000);
+}
+
+/*
  * initialize the audio vars and register the update timer
  */
 int r600_audio_init(struct radeon_device *rdev)
 {
-	if (!r600_audio_chipset_supported(rdev))
+	if (!radeon_audio || !r600_audio_chipset_supported(rdev))
 		return 0;
 
-	DRM_INFO("%s audio support", radeon_audio ? "Enabling" : "Disabling");
-	WREG32_P(R600_AUDIO_ENABLE, radeon_audio ? 0x81000000 : 0x0, ~0x81000000);
+	r600_audio_engine_enable(rdev, true);
 
 	rdev->audio_channels = -1;
 	rdev->audio_rate = -1;
@@ -174,41 +182,6 @@ int r600_audio_init(struct radeon_device
 }
 
 /*
- * determin how the encoders and audio interface is wired together
- */
-int r600_audio_tmds_index(struct drm_encoder *encoder)
-{
-	struct drm_device *dev = encoder->dev;
-	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-	struct drm_encoder *other;
-
-	switch (radeon_encoder->encoder_id) {
-	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-		return 0;
-
-	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-		/* special case check if an TMDS1 is present */
-		list_for_each_entry(other, &dev->mode_config.encoder_list, head) {
-			if (to_radeon_encoder(other)->encoder_id ==
-				ENCODER_OBJECT_ID_INTERNAL_TMDS1)
-				return 1;
-		}
-		return 0;
-
-	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-		return 1;
-
-	default:
-		DRM_ERROR("Unsupported encoder type 0x%02X\n",
-			  radeon_encoder->encoder_id);
-		return -1;
-	}
-}
-
-/*
  * atach the audio codec to the clock source of the encoder
  */
 void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
@@ -216,6 +189,7 @@ void r600_audio_set_clock(struct drm_enc
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 	int base_rate = 48000;
 
 	switch (radeon_encoder->encoder_id) {
@@ -223,32 +197,34 @@ void r600_audio_set_clock(struct drm_enc
 	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
 		WREG32_P(R600_AUDIO_TIMING, 0, ~0x301);
 		break;
-
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 		WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301);
 		break;
-
 	default:
 		DRM_ERROR("Unsupported encoder type 0x%02X\n",
 			  radeon_encoder->encoder_id);
 		return;
 	}
 
-	switch (r600_audio_tmds_index(encoder)) {
+	switch (dig->dig_encoder) {
 	case 0:
-		WREG32(R600_AUDIO_PLL1_MUL, base_rate*50);
-		WREG32(R600_AUDIO_PLL1_DIV, clock*100);
+		WREG32(R600_AUDIO_PLL1_MUL, base_rate * 50);
+		WREG32(R600_AUDIO_PLL1_DIV, clock * 100);
 		WREG32(R600_AUDIO_CLK_SRCSEL, 0);
 		break;
 
 	case 1:
-		WREG32(R600_AUDIO_PLL2_MUL, base_rate*50);
-		WREG32(R600_AUDIO_PLL2_DIV, clock*100);
+		WREG32(R600_AUDIO_PLL2_MUL, base_rate * 50);
+		WREG32(R600_AUDIO_PLL2_DIV, clock * 100);
 		WREG32(R600_AUDIO_CLK_SRCSEL, 1);
 		break;
+	default:
+		dev_err(rdev->dev, "Unsupported DIG on encoder 0x%02X\n",
+			  radeon_encoder->encoder_id);
+		return;
 	}
 }
 
@@ -258,9 +234,10 @@ void r600_audio_set_clock(struct drm_enc
  */
 void r600_audio_fini(struct radeon_device *rdev)
 {
-	if (!r600_audio_chipset_supported(rdev))
+	if (!radeon_audio || !r600_audio_chipset_supported(rdev))
 		return;
 
 	del_timer(&rdev->audio_timer);
-	WREG32_P(R600_AUDIO_ENABLE, 0x0, ~0x81000000);
+
+	r600_audio_engine_enable(rdev, false);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_blit.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_blit.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_blit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_blit.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,7 +49,7 @@ set_render_target(drm_radeon_private_t *
 	RING_LOCALS;
 	DRM_DEBUG("\n");
 
-	h = (h + 7) & ~7;
+	h = ALIGN(h, 8);
 	if (h < 8)
 		h = 8;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_blit_kms.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_blit_kms.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_blit_kms.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_blit_kms.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,7 @@ set_render_target(struct radeon_device *
 	u32 cb_color_info;
 	int pitch, slice;
 
-	h = (h + 7) & ~7;
+	h = ALIGN(h, 8);
 	if (h < 8)
 		h = 8;
 
@@ -396,15 +396,13 @@ set_default_state(struct radeon_device *
 				    NUM_ES_STACK_ENTRIES(num_es_stack_entries));
 
 	/* emit an IB pointing at default state */
-	dwords = (rdev->r600_blit.state_len + 0xf) & ~0xf;
+	dwords = ALIGN(rdev->r600_blit.state_len, 0x10);
 	gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset;
 	radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
 	radeon_ring_write(rdev, gpu_addr & 0xFFFFFFFC);
 	radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF);
 	radeon_ring_write(rdev, dwords);
 
-	radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0));
-	radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT);
 	/* SQ config */
 	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 6));
 	radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
@@ -578,9 +576,9 @@ int r600_blit_prepare_copy(struct radeon
 	ring_size = num_loops * dwords_per_loop;
 	/* set default  + shaders */
 	ring_size += 40; /* shaders + def state */
-	ring_size += 7; /* fence emit for VB IB */
+	ring_size += 10; /* fence emit for VB IB */
 	ring_size += 5; /* done copy */
-	ring_size += 7; /* fence emit for done copy */
+	ring_size += 10; /* fence emit for done copy */
 	r = radeon_ring_lock(rdev, ring_size);
 	if (r)
 		return r;
@@ -594,13 +592,6 @@ void r600_blit_done_copy(struct radeon_d
 {
 	int r;
 
-	radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0));
-	radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT);
-	/* wait for 3D idle clean */
-	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
-	radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
-	radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit);
-
 	if (rdev->r600_blit.vb_ib)
 		r600_vb_ib_put(rdev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_blit_shaders.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_blit_shaders.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_blit_shaders.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_blit_shaders.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,42 @@
+/*
+ * Copyright 2009 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *     Alex Deucher <alexander.deucher@amd.com>
+ */
 
 #include <linux/types.h>
 #include <linux/kernel.h>
 
+/*
+ * R6xx+ cards need to use the 3D engine to blit data which requires
+ * quite a bit of hw state setup.  Rather than pull the whole 3D driver
+ * (which normally generates the 3D state) into the DRM, we opt to use
+ * statically generated state tables.  The regsiter state and shaders
+ * were hand generated to support blitting functionality.  See the 3D
+ * driver or documentation for descriptions of the registers and
+ * shader instructions.
+ */
+
 const u32 r6xx_default_state[] =
 {
 	0xc0002400,
@@ -9,11 +44,6 @@ const u32 r6xx_default_state[] =
 	0xc0012800,
 	0x80000000,
 	0x80000000,
-	0xc0004600,
-	0x00000016,
-	0xc0016800,
-	0x00000010,
-	0x00028000,
 	0xc0016800,
 	0x00000010,
 	0x00008000,
@@ -531,11 +561,6 @@ const u32 r7xx_default_state[] =
 	0xc0012800,
 	0x80000000,
 	0x80000000,
-	0xc0004600,
-	0x00000016,
-	0xc0016800,
-	0x00000010,
-	0x00028000,
 	0xc0016800,
 	0x00000010,
 	0x00008000,
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600.c	2013-05-03 12:03:47.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600.c	2013-05-03 09:44:41.000000000 -0400
@@ -25,12 +25,14 @@
  *          Alex Deucher
  *          Jerome Glisse
  */
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/firmware.h>
 #include <linux/platform_device.h>
 #include "drmP.h"
 #include "radeon_drm.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "radeon_mode.h"
 #include "r600d.h"
 #include "atom.h"
@@ -332,23 +334,14 @@ void r600_hpd_fini(struct radeon_device
 /*
  * R600 PCIE GART
  */
-int r600_gart_clear_page(struct radeon_device *rdev, int i)
-{
-	void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
-	u64 pte;
-
-	if (i < 0 || i > rdev->gart.num_gpu_pages)
-		return -EINVAL;
-	pte = 0;
-	writeq(pte, ((void __iomem *)ptr) + (i * 8));
-	return 0;
-}
-
 void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
 {
 	unsigned i;
 	u32 tmp;
 
+	/* flush hdp cache so updates hit vram */
+	WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
+
 	WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12);
 	WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12);
 	WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1));
@@ -395,6 +388,7 @@ int r600_pcie_gart_enable(struct radeon_
 	r = radeon_gart_table_vram_pin(rdev);
 	if (r)
 		return r;
+	radeon_gart_restore(rdev);
 
 	/* Setup L2 cache */
 	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
@@ -478,9 +472,9 @@ void r600_pcie_gart_disable(struct radeo
 
 void r600_pcie_gart_fini(struct radeon_device *rdev)
 {
+	radeon_gart_fini(rdev);
 	r600_pcie_gart_disable(rdev);
 	radeon_gart_table_vram_free(rdev);
-	radeon_gart_fini(rdev);
 }
 
 void r600_agp_enable(struct radeon_device *rdev)
@@ -598,9 +592,70 @@ static void r600_mc_program(struct radeo
 	rv515_vga_render_disable(rdev);
 }
 
+/**
+ * r600_vram_gtt_location - try to find VRAM & GTT location
+ * @rdev: radeon device structure holding all necessary informations
+ * @mc: memory controller structure holding memory informations
+ *
+ * Function will place try to place VRAM at same place as in CPU (PCI)
+ * address space as some GPU seems to have issue when we reprogram at
+ * different address space.
+ *
+ * If there is not enough space to fit the unvisible VRAM after the
+ * aperture then we limit the VRAM size to the aperture.
+ *
+ * If we are using AGP then place VRAM adjacent to AGP aperture are we need
+ * them to be in one from GPU point of view so that we can program GPU to
+ * catch access outside them (weird GPU policy see ??).
+ *
+ * This function will never fails, worst case are limiting VRAM or GTT.
+ *
+ * Note: GTT start, end, size should be initialized before calling this
+ * function on AGP platform.
+ */
+void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
+{
+	u64 size_bf, size_af;
+
+	if (mc->mc_vram_size > 0xE0000000) {
+		/* leave room for at least 512M GTT */
+		dev_warn(rdev->dev, "limiting VRAM\n");
+		mc->real_vram_size = 0xE0000000;
+		mc->mc_vram_size = 0xE0000000;
+	}
+	if (rdev->flags & RADEON_IS_AGP) {
+		size_bf = mc->gtt_start;
+		size_af = 0xFFFFFFFF - mc->gtt_end + 1;
+		if (size_bf > size_af) {
+			if (mc->mc_vram_size > size_bf) {
+				dev_warn(rdev->dev, "limiting VRAM\n");
+				mc->real_vram_size = size_bf;
+				mc->mc_vram_size = size_bf;
+			}
+			mc->vram_start = mc->gtt_start - mc->mc_vram_size;
+		} else {
+			if (mc->mc_vram_size > size_af) {
+				dev_warn(rdev->dev, "limiting VRAM\n");
+				mc->real_vram_size = size_af;
+				mc->mc_vram_size = size_af;
+			}
+			mc->vram_start = mc->gtt_end;
+		}
+		mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
+		dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
+				mc->mc_vram_size >> 20, mc->vram_start,
+				mc->vram_end, mc->real_vram_size >> 20);
+	} else {
+		u64 base = 0;
+		if (rdev->flags & RADEON_IS_IGP)
+			base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
+		radeon_vram_location(rdev, &rdev->mc, base);
+		radeon_gtt_location(rdev, mc);
+	}
+}
+
 int r600_mc_init(struct radeon_device *rdev)
 {
-	fixed20_12 a;
 	u32 tmp;
 	int chansize, numchan;
 
@@ -637,75 +692,17 @@ int r600_mc_init(struct radeon_device *r
 	/* Setup GPU memory space */
 	rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
 	rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
-
-	if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
+	rdev->mc.visible_vram_size = rdev->mc.aper_size;
+	/* FIXME remove this once we support unmappable VRAM */
+	if (rdev->mc.mc_vram_size > rdev->mc.aper_size) {
 		rdev->mc.mc_vram_size = rdev->mc.aper_size;
-
-	if (rdev->mc.real_vram_size > rdev->mc.aper_size)
 		rdev->mc.real_vram_size = rdev->mc.aper_size;
-
-	if (rdev->flags & RADEON_IS_AGP) {
-		/* gtt_size is setup by radeon_agp_init */
-		rdev->mc.gtt_location = rdev->mc.agp_base;
-		tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size;
-		/* Try to put vram before or after AGP because we
-		 * we want SYSTEM_APERTURE to cover both VRAM and
-		 * AGP so that GPU can catch out of VRAM/AGP access
-		 */
-		if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) {
-			/* Enough place before */
-			rdev->mc.vram_location = rdev->mc.gtt_location -
-							rdev->mc.mc_vram_size;
-		} else if (tmp > rdev->mc.mc_vram_size) {
-			/* Enough place after */
-			rdev->mc.vram_location = rdev->mc.gtt_location +
-							rdev->mc.gtt_size;
-		} else {
-			/* Try to setup VRAM then AGP might not
-			 * not work on some card
-			 */
-			rdev->mc.vram_location = 0x00000000UL;
-			rdev->mc.gtt_location = rdev->mc.mc_vram_size;
-		}
-	} else {
-		rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
-		rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) &
-							0xFFFF) << 24;
-		tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size;
-		if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
-			/* Enough place after vram */
-			rdev->mc.gtt_location = tmp;
-		} else if (rdev->mc.vram_location >= rdev->mc.gtt_size) {
-			/* Enough place before vram */
-			rdev->mc.gtt_location = 0;
-		} else {
-			/* Not enough place after or before shrink
-			 * gart size
-			 */
-			if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) {
-				rdev->mc.gtt_location = 0;
-				rdev->mc.gtt_size = rdev->mc.vram_location;
-			} else {
-				rdev->mc.gtt_location = tmp;
-				rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp;
-			}
-		}
-		rdev->mc.gtt_location = rdev->mc.mc_vram_size;
 	}
-	rdev->mc.vram_start = rdev->mc.vram_location;
-	rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
-	rdev->mc.gtt_start = rdev->mc.gtt_location;
-	rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
-	/* FIXME: we should enforce default clock in case GPU is not in
-	 * default setup
-	 */
-	a.full = rfixed_const(100);
-	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
-	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+	r600_vram_gtt_location(rdev, &rdev->mc);
 
 	if (rdev->flags & RADEON_IS_IGP)
 		rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
-
+	radeon_update_bandwidth_info(rdev);
 	return 0;
 }
 
@@ -960,6 +957,9 @@ void r600_gpu_init(struct radeon_device
 {
 	u32 tiling_config;
 	u32 ramcfg;
+	u32 backend_map;
+	u32 cc_rb_backend_disable;
+	u32 cc_gc_shader_pipe_config;
 	u32 tmp;
 	int i, j;
 	u32 sq_config;
@@ -1069,8 +1069,11 @@ void r600_gpu_init(struct radeon_device
 	default:
 		break;
 	}
+	rdev->config.r600.tiling_npipes = rdev->config.r600.max_tile_pipes;
+	rdev->config.r600.tiling_nbanks = 4 << ((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT);
 	tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT);
 	tiling_config |= GROUP_SIZE(0);
+	rdev->config.r600.tiling_group_size = 256;
 	tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT;
 	if (tmp > 3) {
 		tiling_config |= ROW_TILING(3);
@@ -1080,24 +1083,34 @@ void r600_gpu_init(struct radeon_device
 		tiling_config |= SAMPLE_SPLIT(tmp);
 	}
 	tiling_config |= BANK_SWAPS(1);
-	tmp = r600_get_tile_pipe_to_backend_map(rdev->config.r600.max_tile_pipes,
-						rdev->config.r600.max_backends,
-						(0xff << rdev->config.r600.max_backends) & 0xff);
-	tiling_config |= BACKEND_MAP(tmp);
+
+	cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000;
+	cc_rb_backend_disable |=
+		BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << rdev->config.r600.max_backends) & R6XX_MAX_BACKENDS_MASK);
+
+	cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00;
+	cc_gc_shader_pipe_config |=
+		INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << rdev->config.r600.max_pipes) & R6XX_MAX_PIPES_MASK);
+	cc_gc_shader_pipe_config |=
+		INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << rdev->config.r600.max_simds) & R6XX_MAX_SIMDS_MASK);
+
+	backend_map = r600_get_tile_pipe_to_backend_map(rdev->config.r600.max_tile_pipes,
+							(R6XX_MAX_BACKENDS -
+							 r600_count_pipe_bits((cc_rb_backend_disable &
+									       R6XX_MAX_BACKENDS_MASK) >> 16)),
+							(cc_rb_backend_disable >> 16));
+
+	tiling_config |= BACKEND_MAP(backend_map);
 	WREG32(GB_TILING_CONFIG, tiling_config);
 	WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff);
 	WREG32(HDP_TILING_CONFIG, tiling_config & 0xffff);
 
-	tmp = BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << rdev->config.r600.max_backends) & R6XX_MAX_BACKENDS_MASK);
-	WREG32(CC_RB_BACKEND_DISABLE, tmp);
-
 	/* Setup pipes */
-	tmp = INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << rdev->config.r600.max_pipes) & R6XX_MAX_PIPES_MASK);
-	tmp |= INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << rdev->config.r600.max_simds) & R6XX_MAX_SIMDS_MASK);
-	WREG32(CC_GC_SHADER_PIPE_CONFIG, tmp);
-	WREG32(GC_USER_SHADER_PIPE_CONFIG, tmp);
+	WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
+	WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+	WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
 
-	tmp = R6XX_MAX_BACKENDS - r600_count_pipe_bits(tmp & INACTIVE_QD_PIPES_MASK);
+	tmp = R6XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8);
 	WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK);
 	WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((tmp * 4) - 2) & VTX_REUSE_DEPTH_MASK);
 
@@ -1762,12 +1775,17 @@ void r600_fence_ring_emit(struct radeon_
 			  struct radeon_fence *fence)
 {
 	/* Also consider EVENT_WRITE_EOP.  it handles the interrupts + timestamps + events */
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0));
+	radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT);
+	/* wait for 3D idle clean */
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+	radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit);
 	/* Emit fence sequence & fire IRQ */
 	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
 	radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
 	radeon_ring_write(rdev, fence->seq);
-	radeon_ring_write(rdev, PACKET0(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0));
-	radeon_ring_write(rdev, 1);
 	/* CP_INTERRUPT packet 3 no longer exists, use packet 0 */
 	radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0));
 	radeon_ring_write(rdev, RB_INT_STAT);
@@ -2078,6 +2096,7 @@ int r600_init(struct radeon_device *rdev
 
 void r600_fini(struct radeon_device *rdev)
 {
+	radeon_pm_fini(rdev);
 	r600_audio_fini(rdev);
 	r600_blit_fini(rdev);
 	r600_cp_fini(rdev);
@@ -2357,19 +2376,19 @@ static void r600_disable_interrupt_state
 		WREG32(DC_HPD4_INT_CONTROL, tmp);
 		if (ASIC_IS_DCE32(rdev)) {
 			tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY;
-			WREG32(DC_HPD5_INT_CONTROL, 0);
+			WREG32(DC_HPD5_INT_CONTROL, tmp);
 			tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY;
-			WREG32(DC_HPD6_INT_CONTROL, 0);
+			WREG32(DC_HPD6_INT_CONTROL, tmp);
 		}
 	} else {
 		WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
 		WREG32(DACB_AUTODETECT_INT_CONTROL, 0);
 		tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
-		WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, 0);
+		WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
 		tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
-		WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, 0);
+		WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
 		tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
-		WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, 0);
+		WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
 	}
 }
 
@@ -2724,6 +2743,8 @@ restart_ih:
 			case 0: /* D1 vblank */
 				if (disp_int & LB_D1_VBLANK_INTERRUPT) {
 					drm_handle_vblank(rdev->ddev, 0);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 					disp_int &= ~LB_D1_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D1 vblank\n");
 				}
@@ -2744,6 +2765,8 @@ restart_ih:
 			case 0: /* D2 vblank */
 				if (disp_int & LB_D2_VBLANK_INTERRUPT) {
 					drm_handle_vblank(rdev->ddev, 1);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 					disp_int &= ~LB_D2_VBLANK_INTERRUPT;
 					DRM_DEBUG("IH: D2 vblank\n");
 				}
@@ -2791,14 +2814,14 @@ restart_ih:
 				break;
 			case 10:
 				if (disp_int_cont2 & DC_HPD5_INTERRUPT) {
-					disp_int_cont &= ~DC_HPD5_INTERRUPT;
+					disp_int_cont2 &= ~DC_HPD5_INTERRUPT;
 					queue_hotplug = true;
 					DRM_DEBUG("IH: HPD5\n");
 				}
 				break;
 			case 12:
 				if (disp_int_cont2 & DC_HPD6_INTERRUPT) {
-					disp_int_cont &= ~DC_HPD6_INTERRUPT;
+					disp_int_cont2 &= ~DC_HPD6_INTERRUPT;
 					queue_hotplug = true;
 					DRM_DEBUG("IH: HPD6\n");
 				}
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_cp.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_cp.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_cp.c	2013-05-03 12:03:49.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_cp.c	2013-05-03 09:44:44.000000000 -0400
@@ -715,8 +715,8 @@ static void r600_gfx_init(struct drm_dev
 	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 cc_rb_backend_disable;
+	u32 cc_gc_shader_pipe_config;
 	u32 ramcfg;
 
 	/* setup chip specs */
@@ -838,29 +838,44 @@ static void r600_gfx_init(struct drm_dev
 
 	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_rb_backend_disable = RADEON_READ(R600_CC_RB_BACKEND_DISABLE) & 0x00ff0000;
+	cc_rb_backend_disable |=
+		R600_BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R6XX_MAX_BACKENDS_MASK);
 
-	cc_gc_shader_pipe_config =
+	cc_gc_shader_pipe_config = RADEON_READ(R600_CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00;
+	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);
+	backend_map = r600_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes,
+							(R6XX_MAX_BACKENDS -
+							 r600_count_pipe_bits((cc_rb_backend_disable &
+									       R6XX_MAX_BACKENDS_MASK) >> 16)),
+							(cc_rb_backend_disable >> 16));
+	gb_tiling_config |= R600_BACKEND_MAP(backend_map);
 
 	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));
+	if (gb_tiling_config & 0xc0) {
+		dev_priv->r600_group_size = 512;
+	} else {
+		dev_priv->r600_group_size = 256;
+	}
+	dev_priv->r600_npipes = 1 << ((gb_tiling_config >> 1) & 0x7);
+	if (gb_tiling_config & 0x30) {
+		dev_priv->r600_nbanks = 8;
+	} else {
+		dev_priv->r600_nbanks = 4;
+	}
 
 	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);
+		R6XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK) >> 8);
 	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);
 
@@ -1132,7 +1147,8 @@ static void r600_gfx_init(struct drm_dev
 
 }
 
-static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
+static u32 r700_get_tile_pipe_to_backend_map(drm_radeon_private_t *dev_priv,
+					     u32 num_tile_pipes,
 					     u32 num_backends,
 					     u32 backend_disable_mask)
 {
@@ -1143,6 +1159,7 @@ static u32 r700_get_tile_pipe_to_backend
 	u32 swizzle_pipe[R7XX_MAX_PIPES];
 	u32 cur_backend;
 	u32 i;
+	bool force_no_swizzle;
 
 	if (num_tile_pipes > R7XX_MAX_PIPES)
 		num_tile_pipes = R7XX_MAX_PIPES;
@@ -1172,6 +1189,18 @@ static u32 r700_get_tile_pipe_to_backend
 	if (enabled_backends_count != num_backends)
 		num_backends = enabled_backends_count;
 
+	switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+	case CHIP_RV770:
+	case CHIP_RV730:
+		force_no_swizzle = false;
+		break;
+	case CHIP_RV710:
+	case CHIP_RV740:
+	default:
+		force_no_swizzle = true;
+		break;
+	}
+
 	memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES);
 	switch (num_tile_pipes) {
 	case 1:
@@ -1182,49 +1211,100 @@ static u32 r700_get_tile_pipe_to_backend
 		swizzle_pipe[1] = 1;
 		break;
 	case 3:
-		swizzle_pipe[0] = 0;
-		swizzle_pipe[1] = 2;
-		swizzle_pipe[2] = 1;
+		if (force_no_swizzle) {
+			swizzle_pipe[0] = 0;
+			swizzle_pipe[1] = 1;
+			swizzle_pipe[2] = 2;
+		} else {
+			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;
+		if (force_no_swizzle) {
+			swizzle_pipe[0] = 0;
+			swizzle_pipe[1] = 1;
+			swizzle_pipe[2] = 2;
+			swizzle_pipe[3] = 3;
+		} else {
+			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;
+		if (force_no_swizzle) {
+			swizzle_pipe[0] = 0;
+			swizzle_pipe[1] = 1;
+			swizzle_pipe[2] = 2;
+			swizzle_pipe[3] = 3;
+			swizzle_pipe[4] = 4;
+		} else {
+			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;
+		if (force_no_swizzle) {
+			swizzle_pipe[0] = 0;
+			swizzle_pipe[1] = 1;
+			swizzle_pipe[2] = 2;
+			swizzle_pipe[3] = 3;
+			swizzle_pipe[4] = 4;
+			swizzle_pipe[5] = 5;
+		} else {
+			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;
+		if (force_no_swizzle) {
+			swizzle_pipe[0] = 0;
+			swizzle_pipe[1] = 1;
+			swizzle_pipe[2] = 2;
+			swizzle_pipe[3] = 3;
+			swizzle_pipe[4] = 4;
+			swizzle_pipe[5] = 5;
+			swizzle_pipe[6] = 6;
+		} else {
+			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;
+		if (force_no_swizzle) {
+			swizzle_pipe[0] = 0;
+			swizzle_pipe[1] = 1;
+			swizzle_pipe[2] = 2;
+			swizzle_pipe[3] = 3;
+			swizzle_pipe[4] = 4;
+			swizzle_pipe[5] = 5;
+			swizzle_pipe[6] = 6;
+			swizzle_pipe[7] = 7;
+		} else {
+			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;
 	}
 
@@ -1245,8 +1325,10 @@ static void r700_gfx_init(struct drm_dev
 			  drm_radeon_private_t *dev_priv)
 {
 	int i, j, num_qd_pipes;
+	u32 ta_aux_cntl;
 	u32 sx_debug_1;
 	u32 smx_dc_ctl0;
+	u32 db_debug3;
 	u32 num_gs_verts_per_thread;
 	u32 vgt_gs_per_es;
 	u32 gs_prim_buffer_depth = 0;
@@ -1257,8 +1339,8 @@ static void r700_gfx_init(struct drm_dev
 	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 cc_rb_backend_disable;
+	u32 cc_gc_shader_pipe_config;
 	u32 mc_arb_ramcfg;
 	u32 db_debug4;
 
@@ -1409,25 +1491,41 @@ static void r700_gfx_init(struct drm_dev
 
 	gb_tiling_config |= R600_BANK_SWAPS(1);
 
-	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV740)
-		backend_map = 0x28;
-	else
-		backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes,
-								dev_priv->r600_max_backends,
-								(0xff << dev_priv->r600_max_backends) & 0xff);
-	gb_tiling_config |= R600_BACKEND_MAP(backend_map);
+	cc_rb_backend_disable = RADEON_READ(R600_CC_RB_BACKEND_DISABLE) & 0x00ff0000;
+	cc_rb_backend_disable |=
+		R600_BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R7XX_MAX_BACKENDS_MASK);
 
-	cc_gc_shader_pipe_config =
+	cc_gc_shader_pipe_config = RADEON_READ(R600_CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00;
+	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);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV740)
+		backend_map = 0x28;
+	else
+		backend_map = r700_get_tile_pipe_to_backend_map(dev_priv,
+								dev_priv->r600_max_tile_pipes,
+								(R7XX_MAX_BACKENDS -
+								 r600_count_pipe_bits((cc_rb_backend_disable &
+										       R7XX_MAX_BACKENDS_MASK) >> 16)),
+								(cc_rb_backend_disable >> 16));
+	gb_tiling_config |= R600_BACKEND_MAP(backend_map);
 
 	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));
+	if (gb_tiling_config & 0xc0) {
+		dev_priv->r600_group_size = 512;
+	} else {
+		dev_priv->r600_group_size = 256;
+	}
+	dev_priv->r600_npipes = 1 << ((gb_tiling_config >> 1) & 0x7);
+	if (gb_tiling_config & 0x30) {
+		dev_priv->r600_nbanks = 8;
+	} else {
+		dev_priv->r600_nbanks = 4;
+	}
 
 	RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE,      cc_rb_backend_disable);
 	RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG,   cc_gc_shader_pipe_config);
@@ -1440,7 +1538,7 @@ static void r700_gfx_init(struct drm_dev
 	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);
+		R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK) >> 8);
 	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);
 
@@ -1450,10 +1548,8 @@ static void r700_gfx_init(struct drm_dev
 
 	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));
+	ta_aux_cntl = RADEON_READ(R600_TA_CNTL_AUX);
+	RADEON_WRITE(R600_TA_CNTL_AUX, ta_aux_cntl | R600_DISABLE_CUBE_ANISO);
 
 	sx_debug_1 = RADEON_READ(R700_SX_DEBUG_1);
 	sx_debug_1 |= R700_ENABLE_NEW_SMX_ADDRESS;
@@ -1464,14 +1560,28 @@ static void r700_gfx_init(struct drm_dev
 	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_RV740)
+		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_debug3 = RADEON_READ(R700_DB_DEBUG3);
+	db_debug3 &= ~R700_DB_CLK_OFF_DELAY(0x1f);
+	switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+	case CHIP_RV770:
+	case CHIP_RV740:
+		db_debug3 |= R700_DB_CLK_OFF_DELAY(0x1f);
+		break;
+	case CHIP_RV710:
+	case CHIP_RV730:
+	default:
+		db_debug3 |= R700_DB_CLK_OFF_DELAY(2);
+		break;
+	}
+	RADEON_WRITE(R700_DB_DEBUG3, db_debug3);
+
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) != CHIP_RV770) {
 		db_debug4 = RADEON_READ(RV700_DB_DEBUG4);
 		db_debug4 |= RV700_DISABLE_TILE_COVERED_FOR_PS_ITER;
 		RADEON_WRITE(RV700_DB_DEBUG4, db_debug4);
@@ -1500,10 +1610,10 @@ static void r700_gfx_init(struct drm_dev
 			    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:
+		sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x1);
+		break;
 	case CHIP_RV740:
 	default:
 		sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x4);
@@ -2510,3 +2620,12 @@ out:
 	mutex_unlock(&dev_priv->cs_mutex);
 	return r;
 }
+
+void r600_cs_legacy_get_tiling_conf(struct drm_device *dev, u32 *npipes, u32 *nbanks, u32 *group_size)
+{
+	struct drm_radeon_private *dev_priv = dev->dev_private;
+
+	*npipes = dev_priv->r600_npipes;
+	*nbanks = dev_priv->r600_nbanks;
+	*group_size = dev_priv->r600_group_size;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_cs.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_cs.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include "drmP.h"
 #include "radeon.h"
 #include "r600d.h"
+#include "r600_reg_safe.h"
 
 static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p,
 					struct radeon_cs_reloc **cs_reloc);
@@ -35,11 +36,316 @@ static int r600_cs_packet_next_reloc_nom
 					struct radeon_cs_reloc **cs_reloc);
 typedef int (*next_reloc_t)(struct radeon_cs_parser*, struct radeon_cs_reloc**);
 static next_reloc_t r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_mm;
+extern void r600_cs_legacy_get_tiling_conf(struct drm_device *dev, u32 *npipes, u32 *nbanks, u32 *group_size);
+
 
 struct r600_cs_track {
-	u32	cb_color0_base_last;
+	/* configuration we miror so that we use same code btw kms/ums */
+	u32			group_size;
+	u32			nbanks;
+	u32			npipes;
+	/* value we track */
+	u32			sq_config;
+	u32			nsamples;
+	u32			cb_color_base_last[8];
+	struct radeon_bo	*cb_color_bo[8];
+	u32			cb_color_bo_offset[8];
+	struct radeon_bo	*cb_color_frag_bo[8];
+	struct radeon_bo	*cb_color_tile_bo[8];
+	u32			cb_color_info[8];
+	u32			cb_color_size_idx[8];
+	u32			cb_target_mask;
+	u32			cb_shader_mask;
+	u32			cb_color_size[8];
+	u32			vgt_strmout_en;
+	u32			vgt_strmout_buffer_en;
+	u32			db_depth_control;
+	u32			db_depth_info;
+	u32			db_depth_size_idx;
+	u32			db_depth_view;
+	u32			db_depth_size;
+	u32			db_offset;
+	struct radeon_bo	*db_bo;
 };
 
+static inline int r600_bpe_from_format(u32 *bpe, u32 format)
+{
+	switch (format) {
+	case V_038004_COLOR_8:
+	case V_038004_COLOR_4_4:
+	case V_038004_COLOR_3_3_2:
+	case V_038004_FMT_1:
+		*bpe = 1;
+		break;
+	case V_038004_COLOR_16:
+	case V_038004_COLOR_16_FLOAT:
+	case V_038004_COLOR_8_8:
+	case V_038004_COLOR_5_6_5:
+	case V_038004_COLOR_6_5_5:
+	case V_038004_COLOR_1_5_5_5:
+	case V_038004_COLOR_4_4_4_4:
+	case V_038004_COLOR_5_5_5_1:
+		*bpe = 2;
+		break;
+	case V_038004_FMT_8_8_8:
+		*bpe = 3;
+		break;
+	case V_038004_COLOR_32:
+	case V_038004_COLOR_32_FLOAT:
+	case V_038004_COLOR_16_16:
+	case V_038004_COLOR_16_16_FLOAT:
+	case V_038004_COLOR_8_24:
+	case V_038004_COLOR_8_24_FLOAT:
+	case V_038004_COLOR_24_8:
+	case V_038004_COLOR_24_8_FLOAT:
+	case V_038004_COLOR_10_11_11:
+	case V_038004_COLOR_10_11_11_FLOAT:
+	case V_038004_COLOR_11_11_10:
+	case V_038004_COLOR_11_11_10_FLOAT:
+	case V_038004_COLOR_2_10_10_10:
+	case V_038004_COLOR_8_8_8_8:
+	case V_038004_COLOR_10_10_10_2:
+	case V_038004_FMT_5_9_9_9_SHAREDEXP:
+	case V_038004_FMT_32_AS_8:
+	case V_038004_FMT_32_AS_8_8:
+		*bpe = 4;
+		break;
+	case V_038004_COLOR_X24_8_32_FLOAT:
+	case V_038004_COLOR_32_32:
+	case V_038004_COLOR_32_32_FLOAT:
+	case V_038004_COLOR_16_16_16_16:
+	case V_038004_COLOR_16_16_16_16_FLOAT:
+		*bpe = 8;
+		break;
+	case V_038004_FMT_16_16_16:
+	case V_038004_FMT_16_16_16_FLOAT:
+		*bpe = 6;
+		break;
+	case V_038004_FMT_32_32_32:
+	case V_038004_FMT_32_32_32_FLOAT:
+		*bpe = 12;
+		break;
+	case V_038004_COLOR_32_32_32_32:
+	case V_038004_COLOR_32_32_32_32_FLOAT:
+		*bpe = 16;
+		break;
+	case V_038004_FMT_GB_GR:
+	case V_038004_FMT_BG_RG:
+	case V_038004_COLOR_INVALID:
+		*bpe = 16;
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void r600_cs_track_init(struct r600_cs_track *track)
+{
+	int i;
+
+	/* assume DX9 mode */
+	track->sq_config = DX9_CONSTS;
+	for (i = 0; i < 8; i++) {
+		track->cb_color_base_last[i] = 0;
+		track->cb_color_size[i] = 0;
+		track->cb_color_size_idx[i] = 0;
+		track->cb_color_info[i] = 0;
+		track->cb_color_bo[i] = NULL;
+		track->cb_color_bo_offset[i] = 0xFFFFFFFF;
+	}
+	track->cb_target_mask = 0xFFFFFFFF;
+	track->cb_shader_mask = 0xFFFFFFFF;
+	track->db_bo = NULL;
+	/* assume the biggest format and that htile is enabled */
+	track->db_depth_info = 7 | (1 << 25);
+	track->db_depth_view = 0xFFFFC000;
+	track->db_depth_size = 0xFFFFFFFF;
+	track->db_depth_size_idx = 0;
+	track->db_depth_control = 0xFFFFFFFF;
+}
+
+static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
+{
+	struct r600_cs_track *track = p->track;
+	u32 bpe = 0, pitch, slice_tile_max, size, tmp, height;
+	volatile u32 *ib = p->ib->ptr;
+
+	if (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
+		dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n");
+		return -EINVAL;
+	}
+	size = radeon_bo_size(track->cb_color_bo[i]);
+	if (r600_bpe_from_format(&bpe, G_0280A0_FORMAT(track->cb_color_info[i]))) {
+		dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08X)\n",
+			 __func__, __LINE__, G_0280A0_FORMAT(track->cb_color_info[i]),
+			i, track->cb_color_info[i]);
+		return -EINVAL;
+	}
+	pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) << 3;
+	slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1;
+	if (!pitch) {
+		dev_warn(p->dev, "%s:%d cb pitch (%d) for %d invalid (0x%08X)\n",
+			__func__, __LINE__, pitch, i, track->cb_color_size[i]);
+		return -EINVAL;
+	}
+	height = size / (pitch * bpe);
+	if (height > 8192)
+		height = 8192;
+	switch (G_0280A0_ARRAY_MODE(track->cb_color_info[i])) {
+	case V_0280A0_ARRAY_LINEAR_GENERAL:
+	case V_0280A0_ARRAY_LINEAR_ALIGNED:
+		if (pitch & 0x3f) {
+			dev_warn(p->dev, "%s:%d cb pitch (%d x %d = %d) invalid\n",
+				__func__, __LINE__, pitch, bpe, pitch * bpe);
+			return -EINVAL;
+		}
+		if ((pitch * bpe) & (track->group_size - 1)) {
+			dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
+				__func__, __LINE__, pitch);
+			return -EINVAL;
+		}
+		break;
+	case V_0280A0_ARRAY_1D_TILED_THIN1:
+		if ((pitch * 8 * bpe * track->nsamples) & (track->group_size - 1)) {
+			dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
+				__func__, __LINE__, pitch);
+			return -EINVAL;
+		}
+		height &= ~0x7;
+		if (!height)
+			height = 8;
+		break;
+	case V_0280A0_ARRAY_2D_TILED_THIN1:
+		if (pitch & ((8 * track->nbanks) - 1)) {
+			dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
+				__func__, __LINE__, pitch);
+			return -EINVAL;
+		}
+		tmp = pitch * 8 * bpe * track->nsamples;
+		tmp = tmp / track->nbanks;
+		if (tmp & (track->group_size - 1)) {
+			dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
+				__func__, __LINE__, pitch);
+			return -EINVAL;
+		}
+		height &= ~((16 * track->npipes) - 1);
+		if (!height)
+			height = 16 * track->npipes;
+		break;
+	default:
+		dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
+			G_0280A0_ARRAY_MODE(track->cb_color_info[i]), i,
+			track->cb_color_info[i]);
+		return -EINVAL;
+	}
+	/* check offset */
+	tmp = height * pitch;
+	if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
+		dev_warn(p->dev, "%s offset[%d] %d to big\n", __func__, i, track->cb_color_bo_offset[i]);
+		return -EINVAL;
+	}
+	/* limit max tile */
+	tmp = (height * pitch) >> 6;
+	if (tmp < slice_tile_max)
+		slice_tile_max = tmp;
+	tmp = S_028060_PITCH_TILE_MAX((pitch >> 3) - 1) |
+		S_028060_SLICE_TILE_MAX(slice_tile_max - 1);
+	ib[track->cb_color_size_idx[i]] = tmp;
+	return 0;
+}
+
+static int r600_cs_track_check(struct radeon_cs_parser *p)
+{
+	struct r600_cs_track *track = p->track;
+	u32 tmp;
+	int r, i;
+	volatile u32 *ib = p->ib->ptr;
+
+	/* on legacy kernel we don't perform advanced check */
+	if (p->rdev == NULL)
+		return 0;
+	/* we don't support out buffer yet */
+	if (track->vgt_strmout_en || track->vgt_strmout_buffer_en) {
+		dev_warn(p->dev, "this kernel doesn't support SMX output buffer\n");
+		return -EINVAL;
+	}
+	/* check that we have a cb for each enabled target, we don't check
+	 * shader_mask because it seems mesa isn't always setting it :(
+	 */
+	tmp = track->cb_target_mask;
+	for (i = 0; i < 8; i++) {
+		if ((tmp >> (i * 4)) & 0xF) {
+			/* at least one component is enabled */
+			if (track->cb_color_bo[i] == NULL) {
+				dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n",
+					__func__, __LINE__, track->cb_target_mask, track->cb_shader_mask, i);
+				return -EINVAL;
+			}
+			/* perform rewrite of CB_COLOR[0-7]_SIZE */
+			r = r600_cs_track_validate_cb(p, i);
+			if (r)
+				return r;
+		}
+	}
+	/* Check depth buffer */
+	if (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
+		G_028800_Z_ENABLE(track->db_depth_control)) {
+		u32 nviews, bpe, ntiles;
+		if (track->db_bo == NULL) {
+			dev_warn(p->dev, "z/stencil with no depth buffer\n");
+			return -EINVAL;
+		}
+		if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) {
+			dev_warn(p->dev, "this kernel doesn't support z/stencil htile\n");
+			return -EINVAL;
+		}
+		switch (G_028010_FORMAT(track->db_depth_info)) {
+		case V_028010_DEPTH_16:
+			bpe = 2;
+			break;
+		case V_028010_DEPTH_X8_24:
+		case V_028010_DEPTH_8_24:
+		case V_028010_DEPTH_X8_24_FLOAT:
+		case V_028010_DEPTH_8_24_FLOAT:
+		case V_028010_DEPTH_32_FLOAT:
+			bpe = 4;
+			break;
+		case V_028010_DEPTH_X24_8_32_FLOAT:
+			bpe = 8;
+			break;
+		default:
+			dev_warn(p->dev, "z/stencil with invalid format %d\n", G_028010_FORMAT(track->db_depth_info));
+			return -EINVAL;
+		}
+		if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) {
+			if (!track->db_depth_size_idx) {
+				dev_warn(p->dev, "z/stencil buffer size not set\n");
+				return -EINVAL;
+			}
+			printk_once(KERN_WARNING "You have old & broken userspace please consider updating mesa\n");
+			tmp = radeon_bo_size(track->db_bo) - track->db_offset;
+			tmp = (tmp / bpe) >> 6;
+			if (!tmp) {
+				dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %ld)\n",
+						track->db_depth_size, bpe, track->db_offset,
+						radeon_bo_size(track->db_bo));
+				return -EINVAL;
+			}
+			ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF);
+		} else {
+			ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
+			nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
+			tmp = ntiles * bpe * 64 * nviews;
+			if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) {
+				dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %d have %ld)\n",
+						track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset,
+						radeon_bo_size(track->db_bo));
+				return -EINVAL;
+			}
+		}
+	}
+	return 0;
+}
+
 /**
  * r600_cs_packet_parse() - parse cp packet and point ib index to next packet
  * @parser:	parser structure holding parsing context.
@@ -359,6 +665,385 @@ static int r600_cs_parse_packet0(struct
 	return 0;
 }
 
+/**
+ * r600_cs_check_reg() - check if register is authorized or not
+ * @parser: parser structure holding parsing context
+ * @reg: register we are testing
+ * @idx: index into the cs buffer
+ *
+ * This function will test against r600_reg_safe_bm and return 0
+ * if register is safe. If register is not flag as safe this function
+ * will test it against a list of register needind special handling.
+ */
+static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
+{
+	struct r600_cs_track *track = (struct r600_cs_track *)p->track;
+	struct radeon_cs_reloc *reloc;
+	u32 last_reg = ARRAY_SIZE(r600_reg_safe_bm);
+	u32 m, i, tmp, *ib;
+	int r;
+
+	i = (reg >> 7);
+	if (i > last_reg) {
+		dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
+		return -EINVAL;
+	}
+	m = 1 << ((reg >> 2) & 31);
+	if (!(r600_reg_safe_bm[i] & m))
+		return 0;
+	ib = p->ib->ptr;
+	switch (reg) {
+	/* force following reg to 0 in an attemp to disable out buffer
+	 * which will need us to better understand how it works to perform
+	 * security check on it (Jerome)
+	 */
+	case R_0288A8_SQ_ESGS_RING_ITEMSIZE:
+	case R_008C44_SQ_ESGS_RING_SIZE:
+	case R_0288B0_SQ_ESTMP_RING_ITEMSIZE:
+	case R_008C54_SQ_ESTMP_RING_SIZE:
+	case R_0288C0_SQ_FBUF_RING_ITEMSIZE:
+	case R_008C74_SQ_FBUF_RING_SIZE:
+	case R_0288B4_SQ_GSTMP_RING_ITEMSIZE:
+	case R_008C5C_SQ_GSTMP_RING_SIZE:
+	case R_0288AC_SQ_GSVS_RING_ITEMSIZE:
+	case R_008C4C_SQ_GSVS_RING_SIZE:
+	case R_0288BC_SQ_PSTMP_RING_ITEMSIZE:
+	case R_008C6C_SQ_PSTMP_RING_SIZE:
+	case R_0288C4_SQ_REDUC_RING_ITEMSIZE:
+	case R_008C7C_SQ_REDUC_RING_SIZE:
+	case R_0288B8_SQ_VSTMP_RING_ITEMSIZE:
+	case R_008C64_SQ_VSTMP_RING_SIZE:
+	case R_0288C8_SQ_GS_VERT_ITEMSIZE:
+		/* get value to populate the IB don't remove */
+		tmp =radeon_get_ib_value(p, idx);
+		ib[idx] = 0;
+		break;
+	case SQ_CONFIG:
+		track->sq_config = radeon_get_ib_value(p, idx);
+		break;
+	case R_028800_DB_DEPTH_CONTROL:
+		track->db_depth_control = radeon_get_ib_value(p, idx);
+		break;
+	case R_028010_DB_DEPTH_INFO:
+		track->db_depth_info = radeon_get_ib_value(p, idx);
+		break;
+	case R_028004_DB_DEPTH_VIEW:
+		track->db_depth_view = radeon_get_ib_value(p, idx);
+		break;
+	case R_028000_DB_DEPTH_SIZE:
+		track->db_depth_size = radeon_get_ib_value(p, idx);
+		track->db_depth_size_idx = idx;
+		break;
+	case R_028AB0_VGT_STRMOUT_EN:
+		track->vgt_strmout_en = radeon_get_ib_value(p, idx);
+		break;
+	case R_028B20_VGT_STRMOUT_BUFFER_EN:
+		track->vgt_strmout_buffer_en = radeon_get_ib_value(p, idx);
+		break;
+	case R_028238_CB_TARGET_MASK:
+		track->cb_target_mask = radeon_get_ib_value(p, idx);
+		break;
+	case R_02823C_CB_SHADER_MASK:
+		track->cb_shader_mask = radeon_get_ib_value(p, idx);
+		break;
+	case R_028C04_PA_SC_AA_CONFIG:
+		tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx));
+		track->nsamples = 1 << tmp;
+		break;
+	case R_0280A0_CB_COLOR0_INFO:
+	case R_0280A4_CB_COLOR1_INFO:
+	case R_0280A8_CB_COLOR2_INFO:
+	case R_0280AC_CB_COLOR3_INFO:
+	case R_0280B0_CB_COLOR4_INFO:
+	case R_0280B4_CB_COLOR5_INFO:
+	case R_0280B8_CB_COLOR6_INFO:
+	case R_0280BC_CB_COLOR7_INFO:
+		tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4;
+		track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
+		break;
+	case R_028060_CB_COLOR0_SIZE:
+	case R_028064_CB_COLOR1_SIZE:
+	case R_028068_CB_COLOR2_SIZE:
+	case R_02806C_CB_COLOR3_SIZE:
+	case R_028070_CB_COLOR4_SIZE:
+	case R_028074_CB_COLOR5_SIZE:
+	case R_028078_CB_COLOR6_SIZE:
+	case R_02807C_CB_COLOR7_SIZE:
+		tmp = (reg - R_028060_CB_COLOR0_SIZE) / 4;
+		track->cb_color_size[tmp] = radeon_get_ib_value(p, idx);
+		track->cb_color_size_idx[tmp] = idx;
+		break;
+		/* This register were added late, there is userspace
+		 * which does provide relocation for those but set
+		 * 0 offset. In order to avoid breaking old userspace
+		 * we detect this and set address to point to last
+		 * CB_COLOR0_BASE, note that if userspace doesn't set
+		 * CB_COLOR0_BASE before this register we will report
+		 * error. Old userspace always set CB_COLOR0_BASE
+		 * before any of this.
+		 */
+	case R_0280E0_CB_COLOR0_FRAG:
+	case R_0280E4_CB_COLOR1_FRAG:
+	case R_0280E8_CB_COLOR2_FRAG:
+	case R_0280EC_CB_COLOR3_FRAG:
+	case R_0280F0_CB_COLOR4_FRAG:
+	case R_0280F4_CB_COLOR5_FRAG:
+	case R_0280F8_CB_COLOR6_FRAG:
+	case R_0280FC_CB_COLOR7_FRAG:
+		tmp = (reg - R_0280E0_CB_COLOR0_FRAG) / 4;
+		if (!r600_cs_packet_next_is_pkt3_nop(p)) {
+			if (!track->cb_color_base_last[tmp]) {
+				dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg);
+				return -EINVAL;
+			}
+			ib[idx] = track->cb_color_base_last[tmp];
+			printk_once(KERN_WARNING "You have old & broken userspace "
+					"please consider updating mesa & xf86-video-ati\n");
+			track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp];
+		} else {
+			r = r600_cs_packet_next_reloc(p, &reloc);
+			if (r) {
+				dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
+				return -EINVAL;
+			}
+			ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+			track->cb_color_frag_bo[tmp] = reloc->robj;
+		}
+		break;
+	case R_0280C0_CB_COLOR0_TILE:
+	case R_0280C4_CB_COLOR1_TILE:
+	case R_0280C8_CB_COLOR2_TILE:
+	case R_0280CC_CB_COLOR3_TILE:
+	case R_0280D0_CB_COLOR4_TILE:
+	case R_0280D4_CB_COLOR5_TILE:
+	case R_0280D8_CB_COLOR6_TILE:
+	case R_0280DC_CB_COLOR7_TILE:
+		tmp = (reg - R_0280C0_CB_COLOR0_TILE) / 4;
+		if (!r600_cs_packet_next_is_pkt3_nop(p)) {
+			if (!track->cb_color_base_last[tmp]) {
+				dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg);
+				return -EINVAL;
+			}
+			ib[idx] = track->cb_color_base_last[tmp];
+			printk_once(KERN_WARNING "You have old & broken userspace "
+					"please consider updating mesa & xf86-video-ati\n");
+			track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp];
+		} else {
+			r = r600_cs_packet_next_reloc(p, &reloc);
+			if (r) {
+				dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
+				return -EINVAL;
+			}
+			ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+			track->cb_color_tile_bo[tmp] = reloc->robj;
+		}
+		break;
+	case CB_COLOR0_BASE:
+	case CB_COLOR1_BASE:
+	case CB_COLOR2_BASE:
+	case CB_COLOR3_BASE:
+	case CB_COLOR4_BASE:
+	case CB_COLOR5_BASE:
+	case CB_COLOR6_BASE:
+	case CB_COLOR7_BASE:
+		r = r600_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			dev_warn(p->dev, "bad SET_CONTEXT_REG "
+					"0x%04X\n", reg);
+			return -EINVAL;
+		}
+		tmp = (reg - CB_COLOR0_BASE) / 4;
+		track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx);
+		ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+		track->cb_color_base_last[tmp] = ib[idx];
+		track->cb_color_bo[tmp] = reloc->robj;
+		break;
+	case DB_DEPTH_BASE:
+		r = r600_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			dev_warn(p->dev, "bad SET_CONTEXT_REG "
+					"0x%04X\n", reg);
+			return -EINVAL;
+		}
+		track->db_offset = radeon_get_ib_value(p, idx);
+		ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+		track->db_bo = reloc->robj;
+		break;
+	case DB_HTILE_DATA_BASE:
+	case SQ_PGM_START_FS:
+	case SQ_PGM_START_ES:
+	case SQ_PGM_START_VS:
+	case SQ_PGM_START_GS:
+	case SQ_PGM_START_PS:
+	case SQ_ALU_CONST_CACHE_GS_0:
+	case SQ_ALU_CONST_CACHE_GS_1:
+	case SQ_ALU_CONST_CACHE_GS_2:
+	case SQ_ALU_CONST_CACHE_GS_3:
+	case SQ_ALU_CONST_CACHE_GS_4:
+	case SQ_ALU_CONST_CACHE_GS_5:
+	case SQ_ALU_CONST_CACHE_GS_6:
+	case SQ_ALU_CONST_CACHE_GS_7:
+	case SQ_ALU_CONST_CACHE_GS_8:
+	case SQ_ALU_CONST_CACHE_GS_9:
+	case SQ_ALU_CONST_CACHE_GS_10:
+	case SQ_ALU_CONST_CACHE_GS_11:
+	case SQ_ALU_CONST_CACHE_GS_12:
+	case SQ_ALU_CONST_CACHE_GS_13:
+	case SQ_ALU_CONST_CACHE_GS_14:
+	case SQ_ALU_CONST_CACHE_GS_15:
+	case SQ_ALU_CONST_CACHE_PS_0:
+	case SQ_ALU_CONST_CACHE_PS_1:
+	case SQ_ALU_CONST_CACHE_PS_2:
+	case SQ_ALU_CONST_CACHE_PS_3:
+	case SQ_ALU_CONST_CACHE_PS_4:
+	case SQ_ALU_CONST_CACHE_PS_5:
+	case SQ_ALU_CONST_CACHE_PS_6:
+	case SQ_ALU_CONST_CACHE_PS_7:
+	case SQ_ALU_CONST_CACHE_PS_8:
+	case SQ_ALU_CONST_CACHE_PS_9:
+	case SQ_ALU_CONST_CACHE_PS_10:
+	case SQ_ALU_CONST_CACHE_PS_11:
+	case SQ_ALU_CONST_CACHE_PS_12:
+	case SQ_ALU_CONST_CACHE_PS_13:
+	case SQ_ALU_CONST_CACHE_PS_14:
+	case SQ_ALU_CONST_CACHE_PS_15:
+	case SQ_ALU_CONST_CACHE_VS_0:
+	case SQ_ALU_CONST_CACHE_VS_1:
+	case SQ_ALU_CONST_CACHE_VS_2:
+	case SQ_ALU_CONST_CACHE_VS_3:
+	case SQ_ALU_CONST_CACHE_VS_4:
+	case SQ_ALU_CONST_CACHE_VS_5:
+	case SQ_ALU_CONST_CACHE_VS_6:
+	case SQ_ALU_CONST_CACHE_VS_7:
+	case SQ_ALU_CONST_CACHE_VS_8:
+	case SQ_ALU_CONST_CACHE_VS_9:
+	case SQ_ALU_CONST_CACHE_VS_10:
+	case SQ_ALU_CONST_CACHE_VS_11:
+	case SQ_ALU_CONST_CACHE_VS_12:
+	case SQ_ALU_CONST_CACHE_VS_13:
+	case SQ_ALU_CONST_CACHE_VS_14:
+	case SQ_ALU_CONST_CACHE_VS_15:
+		r = r600_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			dev_warn(p->dev, "bad SET_CONTEXT_REG "
+					"0x%04X\n", reg);
+			return -EINVAL;
+		}
+		ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+		break;
+	default:
+		dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static inline unsigned minify(unsigned size, unsigned levels)
+{
+	size = size >> levels;
+	if (size < 1)
+		size = 1;
+	return size;
+}
+
+static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels,
+				unsigned w0, unsigned h0, unsigned d0, unsigned bpe,
+				unsigned *l0_size, unsigned *mipmap_size)
+{
+	unsigned offset, i, level, face;
+	unsigned width, height, depth, rowstride, size;
+
+	w0 = minify(w0, 0);
+	h0 = minify(h0, 0);
+	d0 = minify(d0, 0);
+	for(i = 0, offset = 0, level = blevel; i < nlevels; i++, level++) {
+		width = minify(w0, i);
+		height = minify(h0, i);
+		depth = minify(d0, i);
+		for(face = 0; face < nfaces; face++) {
+			rowstride = ((width * bpe) + 255) & ~255;
+			size = height * rowstride * depth;
+			offset += size;
+			offset = (offset + 0x1f) & ~0x1f;
+		}
+	}
+	*l0_size = (((w0 * bpe) + 255) & ~255) * h0 * d0;
+	*mipmap_size = offset;
+	if (!blevel)
+		*mipmap_size -= *l0_size;
+	if (!nlevels)
+		*mipmap_size = *l0_size;
+}
+
+/**
+ * r600_check_texture_resource() - check if register is authorized or not
+ * @p: parser structure holding parsing context
+ * @idx: index into the cs buffer
+ * @texture: texture's bo structure
+ * @mipmap: mipmap's bo structure
+ *
+ * This function will check that the resource has valid field and that
+ * the texture and mipmap bo object are big enough to cover this resource.
+ */
+static inline int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
+						struct radeon_bo *texture,
+						struct radeon_bo *mipmap)
+{
+	u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0;
+	u32 word0, word1, l0_size, mipmap_size;
+
+	/* on legacy kernel we don't perform advanced check */
+	if (p->rdev == NULL)
+		return 0;
+	word0 = radeon_get_ib_value(p, idx + 0);
+	word1 = radeon_get_ib_value(p, idx + 1);
+	w0 = G_038000_TEX_WIDTH(word0) + 1;
+	h0 = G_038004_TEX_HEIGHT(word1) + 1;
+	d0 = G_038004_TEX_DEPTH(word1);
+	nfaces = 1;
+	switch (G_038000_DIM(word0)) {
+	case V_038000_SQ_TEX_DIM_1D:
+	case V_038000_SQ_TEX_DIM_2D:
+	case V_038000_SQ_TEX_DIM_3D:
+		break;
+	case V_038000_SQ_TEX_DIM_CUBEMAP:
+		nfaces = 6;
+		break;
+	case V_038000_SQ_TEX_DIM_1D_ARRAY:
+	case V_038000_SQ_TEX_DIM_2D_ARRAY:
+	case V_038000_SQ_TEX_DIM_2D_MSAA:
+	case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA:
+	default:
+		dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0));
+		return -EINVAL;
+	}
+	if (r600_bpe_from_format(&bpe,  G_038004_DATA_FORMAT(word1))) {
+		dev_warn(p->dev, "%s:%d texture invalid format %d\n",
+			 __func__, __LINE__, G_038004_DATA_FORMAT(word1));
+		return -EINVAL;
+	}
+	word0 = radeon_get_ib_value(p, idx + 4);
+	word1 = radeon_get_ib_value(p, idx + 5);
+	blevel = G_038010_BASE_LEVEL(word0);
+	nlevels = G_038014_LAST_LEVEL(word1);
+	r600_texture_size(nfaces, blevel, nlevels, w0, h0, d0, bpe, &l0_size, &mipmap_size);
+	/* using get ib will give us the offset into the texture bo */
+	word0 = radeon_get_ib_value(p, idx + 2);
+	if ((l0_size + word0) > radeon_bo_size(texture)) {
+		dev_warn(p->dev, "texture bo too small (%d %d %d %d -> %d have %ld)\n",
+			w0, h0, bpe, word0, l0_size, radeon_bo_size(texture));
+		return -EINVAL;
+	}
+	/* using get ib will give us the offset into the mipmap bo */
+	word0 = radeon_get_ib_value(p, idx + 3);
+	if ((mipmap_size + word0) > radeon_bo_size(mipmap)) {
+		dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n",
+			w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture));
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static int r600_packet3_check(struct radeon_cs_parser *p,
 				struct radeon_cs_packet *pkt)
 {
@@ -408,12 +1093,22 @@ static int r600_packet3_check(struct rad
 		}
 		ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff);
 		ib[idx+1] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+		r = r600_cs_track_check(p);
+		if (r) {
+			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
+			return r;
+		}
 		break;
 	case PACKET3_DRAW_INDEX_AUTO:
 		if (pkt->count != 1) {
 			DRM_ERROR("bad DRAW_INDEX_AUTO\n");
 			return -EINVAL;
 		}
+		r = r600_cs_track_check(p);
+		if (r) {
+			dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
+			return r;
+		}
 		break;
 	case PACKET3_DRAW_INDEX_IMMD_BE:
 	case PACKET3_DRAW_INDEX_IMMD:
@@ -421,6 +1116,11 @@ static int r600_packet3_check(struct rad
 			DRM_ERROR("bad DRAW_INDEX_IMMD\n");
 			return -EINVAL;
 		}
+		r = r600_cs_track_check(p);
+		if (r) {
+			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
+			return r;
+		}
 		break;
 	case PACKET3_WAIT_REG_MEM:
 		if (pkt->count != 5) {
@@ -493,30 +1193,9 @@ static int r600_packet3_check(struct rad
 		}
 		for (i = 0; i < pkt->count; i++) {
 			reg = start_reg + (4 * i);
-			switch (reg) {
-			case SQ_ESGS_RING_BASE:
-			case SQ_GSVS_RING_BASE:
-			case SQ_ESTMP_RING_BASE:
-			case SQ_GSTMP_RING_BASE:
-			case SQ_VSTMP_RING_BASE:
-			case SQ_PSTMP_RING_BASE:
-			case SQ_FBUF_RING_BASE:
-			case SQ_REDUC_RING_BASE:
-			case SX_MEMORY_EXPORT_BASE:
-				r = r600_cs_packet_next_reloc(p, &reloc);
-				if (r) {
-					DRM_ERROR("bad SET_CONFIG_REG "
-							"0x%04X\n", reg);
-					return -EINVAL;
-				}
-				ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
-				break;
-			case CP_COHER_BASE:
-				/* use PACKET3_SURFACE_SYNC */
-				return -EINVAL;
-			default:
-				break;
-			}
+			r = r600_cs_check_reg(p, reg, idx+1+i);
+			if (r)
+				return r;
 		}
 		break;
 	case PACKET3_SET_CONTEXT_REG:
@@ -530,106 +1209,9 @@ static int r600_packet3_check(struct rad
 		}
 		for (i = 0; i < pkt->count; i++) {
 			reg = start_reg + (4 * i);
-			switch (reg) {
-			/* This register were added late, there is userspace
-			 * which does provide relocation for those but set
-			 * 0 offset. In order to avoid breaking old userspace
-			 * we detect this and set address to point to last
-			 * CB_COLOR0_BASE, note that if userspace doesn't set
-			 * CB_COLOR0_BASE before this register we will report
-			 * error. Old userspace always set CB_COLOR0_BASE
-			 * before any of this.
-			 */
-			case R_0280E0_CB_COLOR0_FRAG:
-			case R_0280E4_CB_COLOR1_FRAG:
-			case R_0280E8_CB_COLOR2_FRAG:
-			case R_0280EC_CB_COLOR3_FRAG:
-			case R_0280F0_CB_COLOR4_FRAG:
-			case R_0280F4_CB_COLOR5_FRAG:
-			case R_0280F8_CB_COLOR6_FRAG:
-			case R_0280FC_CB_COLOR7_FRAG:
-			case R_0280C0_CB_COLOR0_TILE:
-			case R_0280C4_CB_COLOR1_TILE:
-			case R_0280C8_CB_COLOR2_TILE:
-			case R_0280CC_CB_COLOR3_TILE:
-			case R_0280D0_CB_COLOR4_TILE:
-			case R_0280D4_CB_COLOR5_TILE:
-			case R_0280D8_CB_COLOR6_TILE:
-			case R_0280DC_CB_COLOR7_TILE:
-				if (!r600_cs_packet_next_is_pkt3_nop(p)) {
-					if (!track->cb_color0_base_last) {
-						dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg);
-						return -EINVAL;
-					}
-					ib[idx+1+i] = track->cb_color0_base_last;
-					printk_once(KERN_WARNING "radeon: You have old & broken userspace "
-						"please consider updating mesa & xf86-video-ati\n");
-				} else {
-					r = r600_cs_packet_next_reloc(p, &reloc);
-					if (r) {
-						dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
-						return -EINVAL;
-					}
-					ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
-				}
-				break;
-			case DB_DEPTH_BASE:
-			case DB_HTILE_DATA_BASE:
-			case CB_COLOR0_BASE:
-				r = r600_cs_packet_next_reloc(p, &reloc);
-				if (r) {
-					DRM_ERROR("bad SET_CONTEXT_REG "
-							"0x%04X\n", reg);
-					return -EINVAL;
-				}
-				ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
-				track->cb_color0_base_last = ib[idx+1+i];
-				break;
-			case CB_COLOR1_BASE:
-			case CB_COLOR2_BASE:
-			case CB_COLOR3_BASE:
-			case CB_COLOR4_BASE:
-			case CB_COLOR5_BASE:
-			case CB_COLOR6_BASE:
-			case CB_COLOR7_BASE:
-			case SQ_PGM_START_FS:
-			case SQ_PGM_START_ES:
-			case SQ_PGM_START_VS:
-			case SQ_PGM_START_GS:
-			case SQ_PGM_START_PS:
-				r = r600_cs_packet_next_reloc(p, &reloc);
-				if (r) {
-					DRM_ERROR("bad SET_CONTEXT_REG "
-							"0x%04X\n", reg);
-					return -EINVAL;
-				}
-				ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
-				break;
-			case VGT_DMA_BASE:
-			case VGT_DMA_BASE_HI:
-				/* These should be handled by DRAW_INDEX packet 3 */
-			case VGT_STRMOUT_BASE_OFFSET_0:
-			case VGT_STRMOUT_BASE_OFFSET_1:
-			case VGT_STRMOUT_BASE_OFFSET_2:
-			case VGT_STRMOUT_BASE_OFFSET_3:
-			case VGT_STRMOUT_BASE_OFFSET_HI_0:
-			case VGT_STRMOUT_BASE_OFFSET_HI_1:
-			case VGT_STRMOUT_BASE_OFFSET_HI_2:
-			case VGT_STRMOUT_BASE_OFFSET_HI_3:
-			case VGT_STRMOUT_BUFFER_BASE_0:
-			case VGT_STRMOUT_BUFFER_BASE_1:
-			case VGT_STRMOUT_BUFFER_BASE_2:
-			case VGT_STRMOUT_BUFFER_BASE_3:
-			case VGT_STRMOUT_BUFFER_OFFSET_0:
-			case VGT_STRMOUT_BUFFER_OFFSET_1:
-			case VGT_STRMOUT_BUFFER_OFFSET_2:
-			case VGT_STRMOUT_BUFFER_OFFSET_3:
-				/* These should be handled by STRMOUT_BUFFER packet 3 */
-				DRM_ERROR("bad context reg: 0x%08x\n", reg);
-				return -EINVAL;
-			default:
-				break;
-			}
+			r = r600_cs_check_reg(p, reg, idx+1+i);
+			if (r)
+				return r;
 		}
 		break;
 	case PACKET3_SET_RESOURCE:
@@ -646,6 +1228,9 @@ static int r600_packet3_check(struct rad
 			return -EINVAL;
 		}
 		for (i = 0; i < (pkt->count / 7); i++) {
+			struct radeon_bo *texture, *mipmap;
+			u32 size, offset;
+
 			switch (G__SQ_VTX_CONSTANT_TYPE(radeon_get_ib_value(p, idx+(i*7)+6+1))) {
 			case SQ_TEX_VTX_VALID_TEXTURE:
 				/* tex base */
@@ -655,6 +1240,7 @@ static int r600_packet3_check(struct rad
 					return -EINVAL;
 				}
 				ib[idx+1+(i*7)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+				texture = reloc->robj;
 				/* tex mip base */
 				r = r600_cs_packet_next_reloc(p, &reloc);
 				if (r) {
@@ -662,6 +1248,11 @@ static int r600_packet3_check(struct rad
 					return -EINVAL;
 				}
 				ib[idx+1+(i*7)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+				mipmap = reloc->robj;
+				r = r600_check_texture_resource(p,  idx+(i*7)+1,
+						texture, mipmap);
+				if (r)
+					return r;
 				break;
 			case SQ_TEX_VTX_VALID_BUFFER:
 				/* vtx base */
@@ -670,6 +1261,13 @@ static int r600_packet3_check(struct rad
 					DRM_ERROR("bad SET_RESOURCE\n");
 					return -EINVAL;
 				}
+				offset = radeon_get_ib_value(p, idx+1+(i*7)+0);
+				size = radeon_get_ib_value(p, idx+1+(i*7)+1);
+				if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) {
+					/* force size to size of the buffer */
+					dev_warn(p->dev, "vbo resource seems too big for the bo\n");
+					ib[idx+1+(i*7)+1] = radeon_bo_size(reloc->robj);
+				}
 				ib[idx+1+(i*7)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff);
 				ib[idx+1+(i*7)+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
 				break;
@@ -682,13 +1280,15 @@ static int r600_packet3_check(struct rad
 		}
 		break;
 	case PACKET3_SET_ALU_CONST:
-		start_reg = (idx_value << 2) + PACKET3_SET_ALU_CONST_OFFSET;
-		end_reg = 4 * pkt->count + start_reg - 4;
-		if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) ||
-		    (start_reg >= PACKET3_SET_ALU_CONST_END) ||
-		    (end_reg >= PACKET3_SET_ALU_CONST_END)) {
-			DRM_ERROR("bad SET_ALU_CONST\n");
-			return -EINVAL;
+		if (track->sq_config & DX9_CONSTS) {
+			start_reg = (idx_value << 2) + PACKET3_SET_ALU_CONST_OFFSET;
+			end_reg = 4 * pkt->count + start_reg - 4;
+			if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) ||
+			    (start_reg >= PACKET3_SET_ALU_CONST_END) ||
+			    (end_reg >= PACKET3_SET_ALU_CONST_END)) {
+				DRM_ERROR("bad SET_ALU_CONST\n");
+				return -EINVAL;
+			}
 		}
 		break;
 	case PACKET3_SET_BOOL_CONST:
@@ -760,11 +1360,28 @@ int r600_cs_parse(struct radeon_cs_parse
 	struct r600_cs_track *track;
 	int r;
 
-	track = kzalloc(sizeof(*track), GFP_KERNEL);
-	p->track = track;
+	if (p->track == NULL) {
+		/* initialize tracker, we are in kms */
+		track = kzalloc(sizeof(*track), GFP_KERNEL);
+		if (track == NULL)
+			return -ENOMEM;
+		r600_cs_track_init(track);
+		if (p->rdev->family < CHIP_RV770) {
+			track->npipes = p->rdev->config.r600.tiling_npipes;
+			track->nbanks = p->rdev->config.r600.tiling_nbanks;
+			track->group_size = p->rdev->config.r600.tiling_group_size;
+		} else if (p->rdev->family <= CHIP_RV740) {
+			track->npipes = p->rdev->config.rv770.tiling_npipes;
+			track->nbanks = p->rdev->config.rv770.tiling_nbanks;
+			track->group_size = p->rdev->config.rv770.tiling_group_size;
+		}
+		p->track = track;
+	}
 	do {
 		r = r600_cs_packet_parse(p, &pkt, p->idx);
 		if (r) {
+			kfree(p->track);
+			p->track = NULL;
 			return r;
 		}
 		p->idx += pkt.count + 2;
@@ -779,9 +1396,13 @@ int r600_cs_parse(struct radeon_cs_parse
 			break;
 		default:
 			DRM_ERROR("Unknown packet type %d !\n", pkt.type);
+			kfree(p->track);
+			p->track = NULL;
 			return -EINVAL;
 		}
 		if (r) {
+			kfree(p->track);
+			p->track = NULL;
 			return r;
 		}
 	} while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
@@ -791,6 +1412,8 @@ int r600_cs_parse(struct radeon_cs_parse
 		mdelay(1);
 	}
 #endif
+	kfree(p->track);
+	p->track = NULL;
 	return 0;
 }
 
@@ -833,9 +1456,16 @@ int r600_cs_legacy(struct drm_device *de
 {
 	struct radeon_cs_parser parser;
 	struct radeon_cs_chunk *ib_chunk;
-	struct radeon_ib	fake_ib;
+	struct radeon_ib fake_ib;
+	struct r600_cs_track *track;
 	int r;
 
+	/* initialize tracker */
+	track = kzalloc(sizeof(*track), GFP_KERNEL);
+	if (track == NULL)
+		return -ENOMEM;
+	r600_cs_track_init(track);
+	r600_cs_legacy_get_tiling_conf(dev, &track->npipes, &track->nbanks, &track->group_size);
 	/* initialize parser */
 	memset(&parser, 0, sizeof(struct radeon_cs_parser));
 	parser.filp = filp;
@@ -843,6 +1473,7 @@ int r600_cs_legacy(struct drm_device *de
 	parser.rdev = NULL;
 	parser.family = family;
 	parser.ib = &fake_ib;
+	parser.track = track;
 	fake_ib.ptr = ib;
 	r = radeon_cs_parser_init(&parser, data);
 	if (r) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600d.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600d.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600d.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600d.h	2010-05-16 17:17:36.000000000 -0400
@@ -77,6 +77,55 @@
 #define CB_COLOR0_FRAG                                  0x280e0
 #define CB_COLOR0_MASK                                  0x28100
 
+#define SQ_ALU_CONST_CACHE_PS_0				0x28940
+#define SQ_ALU_CONST_CACHE_PS_1				0x28944
+#define SQ_ALU_CONST_CACHE_PS_2				0x28948
+#define SQ_ALU_CONST_CACHE_PS_3				0x2894c
+#define SQ_ALU_CONST_CACHE_PS_4				0x28950
+#define SQ_ALU_CONST_CACHE_PS_5				0x28954
+#define SQ_ALU_CONST_CACHE_PS_6				0x28958
+#define SQ_ALU_CONST_CACHE_PS_7				0x2895c
+#define SQ_ALU_CONST_CACHE_PS_8				0x28960
+#define SQ_ALU_CONST_CACHE_PS_9				0x28964
+#define SQ_ALU_CONST_CACHE_PS_10			0x28968
+#define SQ_ALU_CONST_CACHE_PS_11			0x2896c
+#define SQ_ALU_CONST_CACHE_PS_12			0x28970
+#define SQ_ALU_CONST_CACHE_PS_13			0x28974
+#define SQ_ALU_CONST_CACHE_PS_14			0x28978
+#define SQ_ALU_CONST_CACHE_PS_15			0x2897c
+#define SQ_ALU_CONST_CACHE_VS_0				0x28980
+#define SQ_ALU_CONST_CACHE_VS_1				0x28984
+#define SQ_ALU_CONST_CACHE_VS_2				0x28988
+#define SQ_ALU_CONST_CACHE_VS_3				0x2898c
+#define SQ_ALU_CONST_CACHE_VS_4				0x28990
+#define SQ_ALU_CONST_CACHE_VS_5				0x28994
+#define SQ_ALU_CONST_CACHE_VS_6				0x28998
+#define SQ_ALU_CONST_CACHE_VS_7				0x2899c
+#define SQ_ALU_CONST_CACHE_VS_8				0x289a0
+#define SQ_ALU_CONST_CACHE_VS_9				0x289a4
+#define SQ_ALU_CONST_CACHE_VS_10			0x289a8
+#define SQ_ALU_CONST_CACHE_VS_11			0x289ac
+#define SQ_ALU_CONST_CACHE_VS_12			0x289b0
+#define SQ_ALU_CONST_CACHE_VS_13			0x289b4
+#define SQ_ALU_CONST_CACHE_VS_14			0x289b8
+#define SQ_ALU_CONST_CACHE_VS_15			0x289bc
+#define SQ_ALU_CONST_CACHE_GS_0				0x289c0
+#define SQ_ALU_CONST_CACHE_GS_1				0x289c4
+#define SQ_ALU_CONST_CACHE_GS_2				0x289c8
+#define SQ_ALU_CONST_CACHE_GS_3				0x289cc
+#define SQ_ALU_CONST_CACHE_GS_4				0x289d0
+#define SQ_ALU_CONST_CACHE_GS_5				0x289d4
+#define SQ_ALU_CONST_CACHE_GS_6				0x289d8
+#define SQ_ALU_CONST_CACHE_GS_7				0x289dc
+#define SQ_ALU_CONST_CACHE_GS_8				0x289e0
+#define SQ_ALU_CONST_CACHE_GS_9				0x289e4
+#define SQ_ALU_CONST_CACHE_GS_10			0x289e8
+#define SQ_ALU_CONST_CACHE_GS_11			0x289ec
+#define SQ_ALU_CONST_CACHE_GS_12			0x289f0
+#define SQ_ALU_CONST_CACHE_GS_13			0x289f4
+#define SQ_ALU_CONST_CACHE_GS_14			0x289f8
+#define SQ_ALU_CONST_CACHE_GS_15			0x289fc
+
 #define	CONFIG_MEMSIZE					0x5428
 #define CONFIG_CNTL					0x5424
 #define	CP_STAT						0x8680
@@ -883,6 +932,16 @@
 
 #define R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL		0x5480
 
+#define R_028C04_PA_SC_AA_CONFIG                     0x028C04
+#define   S_028C04_MSAA_NUM_SAMPLES(x)                 (((x) & 0x3) << 0)
+#define   G_028C04_MSAA_NUM_SAMPLES(x)                 (((x) >> 0) & 0x3)
+#define   C_028C04_MSAA_NUM_SAMPLES                    0xFFFFFFFC
+#define   S_028C04_AA_MASK_CENTROID_DTMN(x)            (((x) & 0x1) << 4)
+#define   G_028C04_AA_MASK_CENTROID_DTMN(x)            (((x) >> 4) & 0x1)
+#define   C_028C04_AA_MASK_CENTROID_DTMN               0xFFFFFFEF
+#define   S_028C04_MAX_SAMPLE_DIST(x)                  (((x) & 0xF) << 13)
+#define   G_028C04_MAX_SAMPLE_DIST(x)                  (((x) >> 13) & 0xF)
+#define   C_028C04_MAX_SAMPLE_DIST                     0xFFFE1FFF
 #define R_0280E0_CB_COLOR0_FRAG                      0x0280E0
 #define   S_0280E0_BASE_256B(x)                        (((x) & 0xFFFFFFFF) << 0)
 #define   G_0280E0_BASE_256B(x)                        (((x) >> 0) & 0xFFFFFFFF)
@@ -905,6 +964,461 @@
 #define R_0280D4_CB_COLOR5_TILE                      0x0280D4
 #define R_0280D8_CB_COLOR6_TILE                      0x0280D8
 #define R_0280DC_CB_COLOR7_TILE                      0x0280DC
-
+#define R_0280A0_CB_COLOR0_INFO                      0x0280A0
+#define   S_0280A0_ENDIAN(x)                           (((x) & 0x3) << 0)
+#define   G_0280A0_ENDIAN(x)                           (((x) >> 0) & 0x3)
+#define   C_0280A0_ENDIAN                              0xFFFFFFFC
+#define   S_0280A0_FORMAT(x)                           (((x) & 0x3F) << 2)
+#define   G_0280A0_FORMAT(x)                           (((x) >> 2) & 0x3F)
+#define   C_0280A0_FORMAT                              0xFFFFFF03
+#define     V_0280A0_COLOR_INVALID                     0x00000000
+#define     V_0280A0_COLOR_8                           0x00000001
+#define     V_0280A0_COLOR_4_4                         0x00000002
+#define     V_0280A0_COLOR_3_3_2                       0x00000003
+#define     V_0280A0_COLOR_16                          0x00000005
+#define     V_0280A0_COLOR_16_FLOAT                    0x00000006
+#define     V_0280A0_COLOR_8_8                         0x00000007
+#define     V_0280A0_COLOR_5_6_5                       0x00000008
+#define     V_0280A0_COLOR_6_5_5                       0x00000009
+#define     V_0280A0_COLOR_1_5_5_5                     0x0000000A
+#define     V_0280A0_COLOR_4_4_4_4                     0x0000000B
+#define     V_0280A0_COLOR_5_5_5_1                     0x0000000C
+#define     V_0280A0_COLOR_32                          0x0000000D
+#define     V_0280A0_COLOR_32_FLOAT                    0x0000000E
+#define     V_0280A0_COLOR_16_16                       0x0000000F
+#define     V_0280A0_COLOR_16_16_FLOAT                 0x00000010
+#define     V_0280A0_COLOR_8_24                        0x00000011
+#define     V_0280A0_COLOR_8_24_FLOAT                  0x00000012
+#define     V_0280A0_COLOR_24_8                        0x00000013
+#define     V_0280A0_COLOR_24_8_FLOAT                  0x00000014
+#define     V_0280A0_COLOR_10_11_11                    0x00000015
+#define     V_0280A0_COLOR_10_11_11_FLOAT              0x00000016
+#define     V_0280A0_COLOR_11_11_10                    0x00000017
+#define     V_0280A0_COLOR_11_11_10_FLOAT              0x00000018
+#define     V_0280A0_COLOR_2_10_10_10                  0x00000019
+#define     V_0280A0_COLOR_8_8_8_8                     0x0000001A
+#define     V_0280A0_COLOR_10_10_10_2                  0x0000001B
+#define     V_0280A0_COLOR_X24_8_32_FLOAT              0x0000001C
+#define     V_0280A0_COLOR_32_32                       0x0000001D
+#define     V_0280A0_COLOR_32_32_FLOAT                 0x0000001E
+#define     V_0280A0_COLOR_16_16_16_16                 0x0000001F
+#define     V_0280A0_COLOR_16_16_16_16_FLOAT           0x00000020
+#define     V_0280A0_COLOR_32_32_32_32                 0x00000022
+#define     V_0280A0_COLOR_32_32_32_32_FLOAT           0x00000023
+#define   S_0280A0_ARRAY_MODE(x)                       (((x) & 0xF) << 8)
+#define   G_0280A0_ARRAY_MODE(x)                       (((x) >> 8) & 0xF)
+#define   C_0280A0_ARRAY_MODE                          0xFFFFF0FF
+#define     V_0280A0_ARRAY_LINEAR_GENERAL              0x00000000
+#define     V_0280A0_ARRAY_LINEAR_ALIGNED              0x00000001
+#define     V_0280A0_ARRAY_1D_TILED_THIN1              0x00000002
+#define     V_0280A0_ARRAY_2D_TILED_THIN1              0x00000004
+#define   S_0280A0_NUMBER_TYPE(x)                      (((x) & 0x7) << 12)
+#define   G_0280A0_NUMBER_TYPE(x)                      (((x) >> 12) & 0x7)
+#define   C_0280A0_NUMBER_TYPE                         0xFFFF8FFF
+#define   S_0280A0_READ_SIZE(x)                        (((x) & 0x1) << 15)
+#define   G_0280A0_READ_SIZE(x)                        (((x) >> 15) & 0x1)
+#define   C_0280A0_READ_SIZE                           0xFFFF7FFF
+#define   S_0280A0_COMP_SWAP(x)                        (((x) & 0x3) << 16)
+#define   G_0280A0_COMP_SWAP(x)                        (((x) >> 16) & 0x3)
+#define   C_0280A0_COMP_SWAP                           0xFFFCFFFF
+#define   S_0280A0_TILE_MODE(x)                        (((x) & 0x3) << 18)
+#define   G_0280A0_TILE_MODE(x)                        (((x) >> 18) & 0x3)
+#define   C_0280A0_TILE_MODE                           0xFFF3FFFF
+#define   S_0280A0_BLEND_CLAMP(x)                      (((x) & 0x1) << 20)
+#define   G_0280A0_BLEND_CLAMP(x)                      (((x) >> 20) & 0x1)
+#define   C_0280A0_BLEND_CLAMP                         0xFFEFFFFF
+#define   S_0280A0_CLEAR_COLOR(x)                      (((x) & 0x1) << 21)
+#define   G_0280A0_CLEAR_COLOR(x)                      (((x) >> 21) & 0x1)
+#define   C_0280A0_CLEAR_COLOR                         0xFFDFFFFF
+#define   S_0280A0_BLEND_BYPASS(x)                     (((x) & 0x1) << 22)
+#define   G_0280A0_BLEND_BYPASS(x)                     (((x) >> 22) & 0x1)
+#define   C_0280A0_BLEND_BYPASS                        0xFFBFFFFF
+#define   S_0280A0_BLEND_FLOAT32(x)                    (((x) & 0x1) << 23)
+#define   G_0280A0_BLEND_FLOAT32(x)                    (((x) >> 23) & 0x1)
+#define   C_0280A0_BLEND_FLOAT32                       0xFF7FFFFF
+#define   S_0280A0_SIMPLE_FLOAT(x)                     (((x) & 0x1) << 24)
+#define   G_0280A0_SIMPLE_FLOAT(x)                     (((x) >> 24) & 0x1)
+#define   C_0280A0_SIMPLE_FLOAT                        0xFEFFFFFF
+#define   S_0280A0_ROUND_MODE(x)                       (((x) & 0x1) << 25)
+#define   G_0280A0_ROUND_MODE(x)                       (((x) >> 25) & 0x1)
+#define   C_0280A0_ROUND_MODE                          0xFDFFFFFF
+#define   S_0280A0_TILE_COMPACT(x)                     (((x) & 0x1) << 26)
+#define   G_0280A0_TILE_COMPACT(x)                     (((x) >> 26) & 0x1)
+#define   C_0280A0_TILE_COMPACT                        0xFBFFFFFF
+#define   S_0280A0_SOURCE_FORMAT(x)                    (((x) & 0x1) << 27)
+#define   G_0280A0_SOURCE_FORMAT(x)                    (((x) >> 27) & 0x1)
+#define   C_0280A0_SOURCE_FORMAT                       0xF7FFFFFF
+#define R_0280A4_CB_COLOR1_INFO                      0x0280A4
+#define R_0280A8_CB_COLOR2_INFO                      0x0280A8
+#define R_0280AC_CB_COLOR3_INFO                      0x0280AC
+#define R_0280B0_CB_COLOR4_INFO                      0x0280B0
+#define R_0280B4_CB_COLOR5_INFO                      0x0280B4
+#define R_0280B8_CB_COLOR6_INFO                      0x0280B8
+#define R_0280BC_CB_COLOR7_INFO                      0x0280BC
+#define R_028060_CB_COLOR0_SIZE                      0x028060
+#define   S_028060_PITCH_TILE_MAX(x)                   (((x) & 0x3FF) << 0)
+#define   G_028060_PITCH_TILE_MAX(x)                   (((x) >> 0) & 0x3FF)
+#define   C_028060_PITCH_TILE_MAX                      0xFFFFFC00
+#define   S_028060_SLICE_TILE_MAX(x)                   (((x) & 0xFFFFF) << 10)
+#define   G_028060_SLICE_TILE_MAX(x)                   (((x) >> 10) & 0xFFFFF)
+#define   C_028060_SLICE_TILE_MAX                      0xC00003FF
+#define R_028064_CB_COLOR1_SIZE                      0x028064
+#define R_028068_CB_COLOR2_SIZE                      0x028068
+#define R_02806C_CB_COLOR3_SIZE                      0x02806C
+#define R_028070_CB_COLOR4_SIZE                      0x028070
+#define R_028074_CB_COLOR5_SIZE                      0x028074
+#define R_028078_CB_COLOR6_SIZE                      0x028078
+#define R_02807C_CB_COLOR7_SIZE                      0x02807C
+#define R_028238_CB_TARGET_MASK                      0x028238
+#define   S_028238_TARGET0_ENABLE(x)                   (((x) & 0xF) << 0)
+#define   G_028238_TARGET0_ENABLE(x)                   (((x) >> 0) & 0xF)
+#define   C_028238_TARGET0_ENABLE                      0xFFFFFFF0
+#define   S_028238_TARGET1_ENABLE(x)                   (((x) & 0xF) << 4)
+#define   G_028238_TARGET1_ENABLE(x)                   (((x) >> 4) & 0xF)
+#define   C_028238_TARGET1_ENABLE                      0xFFFFFF0F
+#define   S_028238_TARGET2_ENABLE(x)                   (((x) & 0xF) << 8)
+#define   G_028238_TARGET2_ENABLE(x)                   (((x) >> 8) & 0xF)
+#define   C_028238_TARGET2_ENABLE                      0xFFFFF0FF
+#define   S_028238_TARGET3_ENABLE(x)                   (((x) & 0xF) << 12)
+#define   G_028238_TARGET3_ENABLE(x)                   (((x) >> 12) & 0xF)
+#define   C_028238_TARGET3_ENABLE                      0xFFFF0FFF
+#define   S_028238_TARGET4_ENABLE(x)                   (((x) & 0xF) << 16)
+#define   G_028238_TARGET4_ENABLE(x)                   (((x) >> 16) & 0xF)
+#define   C_028238_TARGET4_ENABLE                      0xFFF0FFFF
+#define   S_028238_TARGET5_ENABLE(x)                   (((x) & 0xF) << 20)
+#define   G_028238_TARGET5_ENABLE(x)                   (((x) >> 20) & 0xF)
+#define   C_028238_TARGET5_ENABLE                      0xFF0FFFFF
+#define   S_028238_TARGET6_ENABLE(x)                   (((x) & 0xF) << 24)
+#define   G_028238_TARGET6_ENABLE(x)                   (((x) >> 24) & 0xF)
+#define   C_028238_TARGET6_ENABLE                      0xF0FFFFFF
+#define   S_028238_TARGET7_ENABLE(x)                   (((x) & 0xF) << 28)
+#define   G_028238_TARGET7_ENABLE(x)                   (((x) >> 28) & 0xF)
+#define   C_028238_TARGET7_ENABLE                      0x0FFFFFFF
+#define R_02823C_CB_SHADER_MASK                      0x02823C
+#define   S_02823C_OUTPUT0_ENABLE(x)                   (((x) & 0xF) << 0)
+#define   G_02823C_OUTPUT0_ENABLE(x)                   (((x) >> 0) & 0xF)
+#define   C_02823C_OUTPUT0_ENABLE                      0xFFFFFFF0
+#define   S_02823C_OUTPUT1_ENABLE(x)                   (((x) & 0xF) << 4)
+#define   G_02823C_OUTPUT1_ENABLE(x)                   (((x) >> 4) & 0xF)
+#define   C_02823C_OUTPUT1_ENABLE                      0xFFFFFF0F
+#define   S_02823C_OUTPUT2_ENABLE(x)                   (((x) & 0xF) << 8)
+#define   G_02823C_OUTPUT2_ENABLE(x)                   (((x) >> 8) & 0xF)
+#define   C_02823C_OUTPUT2_ENABLE                      0xFFFFF0FF
+#define   S_02823C_OUTPUT3_ENABLE(x)                   (((x) & 0xF) << 12)
+#define   G_02823C_OUTPUT3_ENABLE(x)                   (((x) >> 12) & 0xF)
+#define   C_02823C_OUTPUT3_ENABLE                      0xFFFF0FFF
+#define   S_02823C_OUTPUT4_ENABLE(x)                   (((x) & 0xF) << 16)
+#define   G_02823C_OUTPUT4_ENABLE(x)                   (((x) >> 16) & 0xF)
+#define   C_02823C_OUTPUT4_ENABLE                      0xFFF0FFFF
+#define   S_02823C_OUTPUT5_ENABLE(x)                   (((x) & 0xF) << 20)
+#define   G_02823C_OUTPUT5_ENABLE(x)                   (((x) >> 20) & 0xF)
+#define   C_02823C_OUTPUT5_ENABLE                      0xFF0FFFFF
+#define   S_02823C_OUTPUT6_ENABLE(x)                   (((x) & 0xF) << 24)
+#define   G_02823C_OUTPUT6_ENABLE(x)                   (((x) >> 24) & 0xF)
+#define   C_02823C_OUTPUT6_ENABLE                      0xF0FFFFFF
+#define   S_02823C_OUTPUT7_ENABLE(x)                   (((x) & 0xF) << 28)
+#define   G_02823C_OUTPUT7_ENABLE(x)                   (((x) >> 28) & 0xF)
+#define   C_02823C_OUTPUT7_ENABLE                      0x0FFFFFFF
+#define R_028AB0_VGT_STRMOUT_EN                      0x028AB0
+#define   S_028AB0_STREAMOUT(x)                        (((x) & 0x1) << 0)
+#define   G_028AB0_STREAMOUT(x)                        (((x) >> 0) & 0x1)
+#define   C_028AB0_STREAMOUT                           0xFFFFFFFE
+#define R_028B20_VGT_STRMOUT_BUFFER_EN               0x028B20
+#define   S_028B20_BUFFER_0_EN(x)                      (((x) & 0x1) << 0)
+#define   G_028B20_BUFFER_0_EN(x)                      (((x) >> 0) & 0x1)
+#define   C_028B20_BUFFER_0_EN                         0xFFFFFFFE
+#define   S_028B20_BUFFER_1_EN(x)                      (((x) & 0x1) << 1)
+#define   G_028B20_BUFFER_1_EN(x)                      (((x) >> 1) & 0x1)
+#define   C_028B20_BUFFER_1_EN                         0xFFFFFFFD
+#define   S_028B20_BUFFER_2_EN(x)                      (((x) & 0x1) << 2)
+#define   G_028B20_BUFFER_2_EN(x)                      (((x) >> 2) & 0x1)
+#define   C_028B20_BUFFER_2_EN                         0xFFFFFFFB
+#define   S_028B20_BUFFER_3_EN(x)                      (((x) & 0x1) << 3)
+#define   G_028B20_BUFFER_3_EN(x)                      (((x) >> 3) & 0x1)
+#define   C_028B20_BUFFER_3_EN                         0xFFFFFFF7
+#define   S_028B20_SIZE(x)                             (((x) & 0xFFFFFFFF) << 0)
+#define   G_028B20_SIZE(x)                             (((x) >> 0) & 0xFFFFFFFF)
+#define   C_028B20_SIZE                                0x00000000
+#define R_038000_SQ_TEX_RESOURCE_WORD0_0             0x038000
+#define   S_038000_DIM(x)                              (((x) & 0x7) << 0)
+#define   G_038000_DIM(x)                              (((x) >> 0) & 0x7)
+#define   C_038000_DIM                                 0xFFFFFFF8
+#define     V_038000_SQ_TEX_DIM_1D                     0x00000000
+#define     V_038000_SQ_TEX_DIM_2D                     0x00000001
+#define     V_038000_SQ_TEX_DIM_3D                     0x00000002
+#define     V_038000_SQ_TEX_DIM_CUBEMAP                0x00000003
+#define     V_038000_SQ_TEX_DIM_1D_ARRAY               0x00000004
+#define     V_038000_SQ_TEX_DIM_2D_ARRAY               0x00000005
+#define     V_038000_SQ_TEX_DIM_2D_MSAA                0x00000006
+#define     V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA          0x00000007
+#define   S_038000_TILE_MODE(x)                        (((x) & 0xF) << 3)
+#define   G_038000_TILE_MODE(x)                        (((x) >> 3) & 0xF)
+#define   C_038000_TILE_MODE                           0xFFFFFF87
+#define   S_038000_TILE_TYPE(x)                        (((x) & 0x1) << 7)
+#define   G_038000_TILE_TYPE(x)                        (((x) >> 7) & 0x1)
+#define   C_038000_TILE_TYPE                           0xFFFFFF7F
+#define   S_038000_PITCH(x)                            (((x) & 0x7FF) << 8)
+#define   G_038000_PITCH(x)                            (((x) >> 8) & 0x7FF)
+#define   C_038000_PITCH                               0xFFF800FF
+#define   S_038000_TEX_WIDTH(x)                        (((x) & 0x1FFF) << 19)
+#define   G_038000_TEX_WIDTH(x)                        (((x) >> 19) & 0x1FFF)
+#define   C_038000_TEX_WIDTH                           0x0007FFFF
+#define R_038004_SQ_TEX_RESOURCE_WORD1_0             0x038004
+#define   S_038004_TEX_HEIGHT(x)                       (((x) & 0x1FFF) << 0)
+#define   G_038004_TEX_HEIGHT(x)                       (((x) >> 0) & 0x1FFF)
+#define   C_038004_TEX_HEIGHT                          0xFFFFE000
+#define   S_038004_TEX_DEPTH(x)                        (((x) & 0x1FFF) << 13)
+#define   G_038004_TEX_DEPTH(x)                        (((x) >> 13) & 0x1FFF)
+#define   C_038004_TEX_DEPTH                           0xFC001FFF
+#define   S_038004_DATA_FORMAT(x)                      (((x) & 0x3F) << 26)
+#define   G_038004_DATA_FORMAT(x)                      (((x) >> 26) & 0x3F)
+#define   C_038004_DATA_FORMAT                         0x03FFFFFF
+#define     V_038004_COLOR_INVALID                     0x00000000
+#define     V_038004_COLOR_8                           0x00000001
+#define     V_038004_COLOR_4_4                         0x00000002
+#define     V_038004_COLOR_3_3_2                       0x00000003
+#define     V_038004_COLOR_16                          0x00000005
+#define     V_038004_COLOR_16_FLOAT                    0x00000006
+#define     V_038004_COLOR_8_8                         0x00000007
+#define     V_038004_COLOR_5_6_5                       0x00000008
+#define     V_038004_COLOR_6_5_5                       0x00000009
+#define     V_038004_COLOR_1_5_5_5                     0x0000000A
+#define     V_038004_COLOR_4_4_4_4                     0x0000000B
+#define     V_038004_COLOR_5_5_5_1                     0x0000000C
+#define     V_038004_COLOR_32                          0x0000000D
+#define     V_038004_COLOR_32_FLOAT                    0x0000000E
+#define     V_038004_COLOR_16_16                       0x0000000F
+#define     V_038004_COLOR_16_16_FLOAT                 0x00000010
+#define     V_038004_COLOR_8_24                        0x00000011
+#define     V_038004_COLOR_8_24_FLOAT                  0x00000012
+#define     V_038004_COLOR_24_8                        0x00000013
+#define     V_038004_COLOR_24_8_FLOAT                  0x00000014
+#define     V_038004_COLOR_10_11_11                    0x00000015
+#define     V_038004_COLOR_10_11_11_FLOAT              0x00000016
+#define     V_038004_COLOR_11_11_10                    0x00000017
+#define     V_038004_COLOR_11_11_10_FLOAT              0x00000018
+#define     V_038004_COLOR_2_10_10_10                  0x00000019
+#define     V_038004_COLOR_8_8_8_8                     0x0000001A
+#define     V_038004_COLOR_10_10_10_2                  0x0000001B
+#define     V_038004_COLOR_X24_8_32_FLOAT              0x0000001C
+#define     V_038004_COLOR_32_32                       0x0000001D
+#define     V_038004_COLOR_32_32_FLOAT                 0x0000001E
+#define     V_038004_COLOR_16_16_16_16                 0x0000001F
+#define     V_038004_COLOR_16_16_16_16_FLOAT           0x00000020
+#define     V_038004_COLOR_32_32_32_32                 0x00000022
+#define     V_038004_COLOR_32_32_32_32_FLOAT           0x00000023
+#define     V_038004_FMT_1                             0x00000025
+#define     V_038004_FMT_GB_GR                         0x00000027
+#define     V_038004_FMT_BG_RG                         0x00000028
+#define     V_038004_FMT_32_AS_8                       0x00000029
+#define     V_038004_FMT_32_AS_8_8                     0x0000002A
+#define     V_038004_FMT_5_9_9_9_SHAREDEXP             0x0000002B
+#define     V_038004_FMT_8_8_8                         0x0000002C
+#define     V_038004_FMT_16_16_16                      0x0000002D
+#define     V_038004_FMT_16_16_16_FLOAT                0x0000002E
+#define     V_038004_FMT_32_32_32                      0x0000002F
+#define     V_038004_FMT_32_32_32_FLOAT                0x00000030
+#define R_038010_SQ_TEX_RESOURCE_WORD4_0             0x038010
+#define   S_038010_FORMAT_COMP_X(x)                    (((x) & 0x3) << 0)
+#define   G_038010_FORMAT_COMP_X(x)                    (((x) >> 0) & 0x3)
+#define   C_038010_FORMAT_COMP_X                       0xFFFFFFFC
+#define   S_038010_FORMAT_COMP_Y(x)                    (((x) & 0x3) << 2)
+#define   G_038010_FORMAT_COMP_Y(x)                    (((x) >> 2) & 0x3)
+#define   C_038010_FORMAT_COMP_Y                       0xFFFFFFF3
+#define   S_038010_FORMAT_COMP_Z(x)                    (((x) & 0x3) << 4)
+#define   G_038010_FORMAT_COMP_Z(x)                    (((x) >> 4) & 0x3)
+#define   C_038010_FORMAT_COMP_Z                       0xFFFFFFCF
+#define   S_038010_FORMAT_COMP_W(x)                    (((x) & 0x3) << 6)
+#define   G_038010_FORMAT_COMP_W(x)                    (((x) >> 6) & 0x3)
+#define   C_038010_FORMAT_COMP_W                       0xFFFFFF3F
+#define   S_038010_NUM_FORMAT_ALL(x)                   (((x) & 0x3) << 8)
+#define   G_038010_NUM_FORMAT_ALL(x)                   (((x) >> 8) & 0x3)
+#define   C_038010_NUM_FORMAT_ALL                      0xFFFFFCFF
+#define   S_038010_SRF_MODE_ALL(x)                     (((x) & 0x1) << 10)
+#define   G_038010_SRF_MODE_ALL(x)                     (((x) >> 10) & 0x1)
+#define   C_038010_SRF_MODE_ALL                        0xFFFFFBFF
+#define   S_038010_FORCE_DEGAMMA(x)                    (((x) & 0x1) << 11)
+#define   G_038010_FORCE_DEGAMMA(x)                    (((x) >> 11) & 0x1)
+#define   C_038010_FORCE_DEGAMMA                       0xFFFFF7FF
+#define   S_038010_ENDIAN_SWAP(x)                      (((x) & 0x3) << 12)
+#define   G_038010_ENDIAN_SWAP(x)                      (((x) >> 12) & 0x3)
+#define   C_038010_ENDIAN_SWAP                         0xFFFFCFFF
+#define   S_038010_REQUEST_SIZE(x)                     (((x) & 0x3) << 14)
+#define   G_038010_REQUEST_SIZE(x)                     (((x) >> 14) & 0x3)
+#define   C_038010_REQUEST_SIZE                        0xFFFF3FFF
+#define   S_038010_DST_SEL_X(x)                        (((x) & 0x7) << 16)
+#define   G_038010_DST_SEL_X(x)                        (((x) >> 16) & 0x7)
+#define   C_038010_DST_SEL_X                           0xFFF8FFFF
+#define   S_038010_DST_SEL_Y(x)                        (((x) & 0x7) << 19)
+#define   G_038010_DST_SEL_Y(x)                        (((x) >> 19) & 0x7)
+#define   C_038010_DST_SEL_Y                           0xFFC7FFFF
+#define   S_038010_DST_SEL_Z(x)                        (((x) & 0x7) << 22)
+#define   G_038010_DST_SEL_Z(x)                        (((x) >> 22) & 0x7)
+#define   C_038010_DST_SEL_Z                           0xFE3FFFFF
+#define   S_038010_DST_SEL_W(x)                        (((x) & 0x7) << 25)
+#define   G_038010_DST_SEL_W(x)                        (((x) >> 25) & 0x7)
+#define   C_038010_DST_SEL_W                           0xF1FFFFFF
+#define   S_038010_BASE_LEVEL(x)                       (((x) & 0xF) << 28)
+#define   G_038010_BASE_LEVEL(x)                       (((x) >> 28) & 0xF)
+#define   C_038010_BASE_LEVEL                          0x0FFFFFFF
+#define R_038014_SQ_TEX_RESOURCE_WORD5_0             0x038014
+#define   S_038014_LAST_LEVEL(x)                       (((x) & 0xF) << 0)
+#define   G_038014_LAST_LEVEL(x)                       (((x) >> 0) & 0xF)
+#define   C_038014_LAST_LEVEL                          0xFFFFFFF0
+#define   S_038014_BASE_ARRAY(x)                       (((x) & 0x1FFF) << 4)
+#define   G_038014_BASE_ARRAY(x)                       (((x) >> 4) & 0x1FFF)
+#define   C_038014_BASE_ARRAY                          0xFFFE000F
+#define   S_038014_LAST_ARRAY(x)                       (((x) & 0x1FFF) << 17)
+#define   G_038014_LAST_ARRAY(x)                       (((x) >> 17) & 0x1FFF)
+#define   C_038014_LAST_ARRAY                          0xC001FFFF
+#define R_0288A8_SQ_ESGS_RING_ITEMSIZE               0x0288A8
+#define   S_0288A8_ITEMSIZE(x)                         (((x) & 0x7FFF) << 0)
+#define   G_0288A8_ITEMSIZE(x)                         (((x) >> 0) & 0x7FFF)
+#define   C_0288A8_ITEMSIZE                            0xFFFF8000
+#define R_008C44_SQ_ESGS_RING_SIZE                   0x008C44
+#define   S_008C44_MEM_SIZE(x)                         (((x) & 0xFFFFFFFF) << 0)
+#define   G_008C44_MEM_SIZE(x)                         (((x) >> 0) & 0xFFFFFFFF)
+#define   C_008C44_MEM_SIZE                            0x00000000
+#define R_0288B0_SQ_ESTMP_RING_ITEMSIZE              0x0288B0
+#define   S_0288B0_ITEMSIZE(x)                         (((x) & 0x7FFF) << 0)
+#define   G_0288B0_ITEMSIZE(x)                         (((x) >> 0) & 0x7FFF)
+#define   C_0288B0_ITEMSIZE                            0xFFFF8000
+#define R_008C54_SQ_ESTMP_RING_SIZE                  0x008C54
+#define   S_008C54_MEM_SIZE(x)                         (((x) & 0xFFFFFFFF) << 0)
+#define   G_008C54_MEM_SIZE(x)                         (((x) >> 0) & 0xFFFFFFFF)
+#define   C_008C54_MEM_SIZE                            0x00000000
+#define R_0288C0_SQ_FBUF_RING_ITEMSIZE               0x0288C0
+#define   S_0288C0_ITEMSIZE(x)                         (((x) & 0x7FFF) << 0)
+#define   G_0288C0_ITEMSIZE(x)                         (((x) >> 0) & 0x7FFF)
+#define   C_0288C0_ITEMSIZE                            0xFFFF8000
+#define R_008C74_SQ_FBUF_RING_SIZE                   0x008C74
+#define   S_008C74_MEM_SIZE(x)                         (((x) & 0xFFFFFFFF) << 0)
+#define   G_008C74_MEM_SIZE(x)                         (((x) >> 0) & 0xFFFFFFFF)
+#define   C_008C74_MEM_SIZE                            0x00000000
+#define R_0288B4_SQ_GSTMP_RING_ITEMSIZE              0x0288B4
+#define   S_0288B4_ITEMSIZE(x)                         (((x) & 0x7FFF) << 0)
+#define   G_0288B4_ITEMSIZE(x)                         (((x) >> 0) & 0x7FFF)
+#define   C_0288B4_ITEMSIZE                            0xFFFF8000
+#define R_008C5C_SQ_GSTMP_RING_SIZE                  0x008C5C
+#define   S_008C5C_MEM_SIZE(x)                         (((x) & 0xFFFFFFFF) << 0)
+#define   G_008C5C_MEM_SIZE(x)                         (((x) >> 0) & 0xFFFFFFFF)
+#define   C_008C5C_MEM_SIZE                            0x00000000
+#define R_0288AC_SQ_GSVS_RING_ITEMSIZE               0x0288AC
+#define   S_0288AC_ITEMSIZE(x)                         (((x) & 0x7FFF) << 0)
+#define   G_0288AC_ITEMSIZE(x)                         (((x) >> 0) & 0x7FFF)
+#define   C_0288AC_ITEMSIZE                            0xFFFF8000
+#define R_008C4C_SQ_GSVS_RING_SIZE                   0x008C4C
+#define   S_008C4C_MEM_SIZE(x)                         (((x) & 0xFFFFFFFF) << 0)
+#define   G_008C4C_MEM_SIZE(x)                         (((x) >> 0) & 0xFFFFFFFF)
+#define   C_008C4C_MEM_SIZE                            0x00000000
+#define R_0288BC_SQ_PSTMP_RING_ITEMSIZE              0x0288BC
+#define   S_0288BC_ITEMSIZE(x)                         (((x) & 0x7FFF) << 0)
+#define   G_0288BC_ITEMSIZE(x)                         (((x) >> 0) & 0x7FFF)
+#define   C_0288BC_ITEMSIZE                            0xFFFF8000
+#define R_008C6C_SQ_PSTMP_RING_SIZE                  0x008C6C
+#define   S_008C6C_MEM_SIZE(x)                         (((x) & 0xFFFFFFFF) << 0)
+#define   G_008C6C_MEM_SIZE(x)                         (((x) >> 0) & 0xFFFFFFFF)
+#define   C_008C6C_MEM_SIZE                            0x00000000
+#define R_0288C4_SQ_REDUC_RING_ITEMSIZE              0x0288C4
+#define   S_0288C4_ITEMSIZE(x)                         (((x) & 0x7FFF) << 0)
+#define   G_0288C4_ITEMSIZE(x)                         (((x) >> 0) & 0x7FFF)
+#define   C_0288C4_ITEMSIZE                            0xFFFF8000
+#define R_008C7C_SQ_REDUC_RING_SIZE                  0x008C7C
+#define   S_008C7C_MEM_SIZE(x)                         (((x) & 0xFFFFFFFF) << 0)
+#define   G_008C7C_MEM_SIZE(x)                         (((x) >> 0) & 0xFFFFFFFF)
+#define   C_008C7C_MEM_SIZE                            0x00000000
+#define R_0288B8_SQ_VSTMP_RING_ITEMSIZE              0x0288B8
+#define   S_0288B8_ITEMSIZE(x)                         (((x) & 0x7FFF) << 0)
+#define   G_0288B8_ITEMSIZE(x)                         (((x) >> 0) & 0x7FFF)
+#define   C_0288B8_ITEMSIZE                            0xFFFF8000
+#define R_008C64_SQ_VSTMP_RING_SIZE                  0x008C64
+#define   S_008C64_MEM_SIZE(x)                         (((x) & 0xFFFFFFFF) << 0)
+#define   G_008C64_MEM_SIZE(x)                         (((x) >> 0) & 0xFFFFFFFF)
+#define   C_008C64_MEM_SIZE                            0x00000000
+#define R_0288C8_SQ_GS_VERT_ITEMSIZE                 0x0288C8
+#define   S_0288C8_ITEMSIZE(x)                         (((x) & 0x7FFF) << 0)
+#define   G_0288C8_ITEMSIZE(x)                         (((x) >> 0) & 0x7FFF)
+#define   C_0288C8_ITEMSIZE                            0xFFFF8000
+#define R_028010_DB_DEPTH_INFO                       0x028010
+#define   S_028010_FORMAT(x)                           (((x) & 0x7) << 0)
+#define   G_028010_FORMAT(x)                           (((x) >> 0) & 0x7)
+#define   C_028010_FORMAT                              0xFFFFFFF8
+#define     V_028010_DEPTH_INVALID                     0x00000000
+#define     V_028010_DEPTH_16                          0x00000001
+#define     V_028010_DEPTH_X8_24                       0x00000002
+#define     V_028010_DEPTH_8_24                        0x00000003
+#define     V_028010_DEPTH_X8_24_FLOAT                 0x00000004
+#define     V_028010_DEPTH_8_24_FLOAT                  0x00000005
+#define     V_028010_DEPTH_32_FLOAT                    0x00000006
+#define     V_028010_DEPTH_X24_8_32_FLOAT              0x00000007
+#define   S_028010_READ_SIZE(x)                        (((x) & 0x1) << 3)
+#define   G_028010_READ_SIZE(x)                        (((x) >> 3) & 0x1)
+#define   C_028010_READ_SIZE                           0xFFFFFFF7
+#define   S_028010_ARRAY_MODE(x)                       (((x) & 0xF) << 15)
+#define   G_028010_ARRAY_MODE(x)                       (((x) >> 15) & 0xF)
+#define   C_028010_ARRAY_MODE                          0xFFF87FFF
+#define   S_028010_TILE_SURFACE_ENABLE(x)              (((x) & 0x1) << 25)
+#define   G_028010_TILE_SURFACE_ENABLE(x)              (((x) >> 25) & 0x1)
+#define   C_028010_TILE_SURFACE_ENABLE                 0xFDFFFFFF
+#define   S_028010_TILE_COMPACT(x)                     (((x) & 0x1) << 26)
+#define   G_028010_TILE_COMPACT(x)                     (((x) >> 26) & 0x1)
+#define   C_028010_TILE_COMPACT                        0xFBFFFFFF
+#define   S_028010_ZRANGE_PRECISION(x)                 (((x) & 0x1) << 31)
+#define   G_028010_ZRANGE_PRECISION(x)                 (((x) >> 31) & 0x1)
+#define   C_028010_ZRANGE_PRECISION                    0x7FFFFFFF
+#define R_028000_DB_DEPTH_SIZE                       0x028000
+#define   S_028000_PITCH_TILE_MAX(x)                   (((x) & 0x3FF) << 0)
+#define   G_028000_PITCH_TILE_MAX(x)                   (((x) >> 0) & 0x3FF)
+#define   C_028000_PITCH_TILE_MAX                      0xFFFFFC00
+#define   S_028000_SLICE_TILE_MAX(x)                   (((x) & 0xFFFFF) << 10)
+#define   G_028000_SLICE_TILE_MAX(x)                   (((x) >> 10) & 0xFFFFF)
+#define   C_028000_SLICE_TILE_MAX                      0xC00003FF
+#define R_028004_DB_DEPTH_VIEW                       0x028004
+#define   S_028004_SLICE_START(x)                      (((x) & 0x7FF) << 0)
+#define   G_028004_SLICE_START(x)                      (((x) >> 0) & 0x7FF)
+#define   C_028004_SLICE_START                         0xFFFFF800
+#define   S_028004_SLICE_MAX(x)                        (((x) & 0x7FF) << 13)
+#define   G_028004_SLICE_MAX(x)                        (((x) >> 13) & 0x7FF)
+#define   C_028004_SLICE_MAX                           0xFF001FFF
+#define R_028800_DB_DEPTH_CONTROL                    0x028800
+#define   S_028800_STENCIL_ENABLE(x)                   (((x) & 0x1) << 0)
+#define   G_028800_STENCIL_ENABLE(x)                   (((x) >> 0) & 0x1)
+#define   C_028800_STENCIL_ENABLE                      0xFFFFFFFE
+#define   S_028800_Z_ENABLE(x)                         (((x) & 0x1) << 1)
+#define   G_028800_Z_ENABLE(x)                         (((x) >> 1) & 0x1)
+#define   C_028800_Z_ENABLE                            0xFFFFFFFD
+#define   S_028800_Z_WRITE_ENABLE(x)                   (((x) & 0x1) << 2)
+#define   G_028800_Z_WRITE_ENABLE(x)                   (((x) >> 2) & 0x1)
+#define   C_028800_Z_WRITE_ENABLE                      0xFFFFFFFB
+#define   S_028800_ZFUNC(x)                            (((x) & 0x7) << 4)
+#define   G_028800_ZFUNC(x)                            (((x) >> 4) & 0x7)
+#define   C_028800_ZFUNC                               0xFFFFFF8F
+#define   S_028800_BACKFACE_ENABLE(x)                  (((x) & 0x1) << 7)
+#define   G_028800_BACKFACE_ENABLE(x)                  (((x) >> 7) & 0x1)
+#define   C_028800_BACKFACE_ENABLE                     0xFFFFFF7F
+#define   S_028800_STENCILFUNC(x)                      (((x) & 0x7) << 8)
+#define   G_028800_STENCILFUNC(x)                      (((x) >> 8) & 0x7)
+#define   C_028800_STENCILFUNC                         0xFFFFF8FF
+#define   S_028800_STENCILFAIL(x)                      (((x) & 0x7) << 11)
+#define   G_028800_STENCILFAIL(x)                      (((x) >> 11) & 0x7)
+#define   C_028800_STENCILFAIL                         0xFFFFC7FF
+#define   S_028800_STENCILZPASS(x)                     (((x) & 0x7) << 14)
+#define   G_028800_STENCILZPASS(x)                     (((x) >> 14) & 0x7)
+#define   C_028800_STENCILZPASS                        0xFFFE3FFF
+#define   S_028800_STENCILZFAIL(x)                     (((x) & 0x7) << 17)
+#define   G_028800_STENCILZFAIL(x)                     (((x) >> 17) & 0x7)
+#define   C_028800_STENCILZFAIL                        0xFFF1FFFF
+#define   S_028800_STENCILFUNC_BF(x)                   (((x) & 0x7) << 20)
+#define   G_028800_STENCILFUNC_BF(x)                   (((x) >> 20) & 0x7)
+#define   C_028800_STENCILFUNC_BF                      0xFF8FFFFF
+#define   S_028800_STENCILFAIL_BF(x)                   (((x) & 0x7) << 23)
+#define   G_028800_STENCILFAIL_BF(x)                   (((x) >> 23) & 0x7)
+#define   C_028800_STENCILFAIL_BF                      0xFC7FFFFF
+#define   S_028800_STENCILZPASS_BF(x)                  (((x) & 0x7) << 26)
+#define   G_028800_STENCILZPASS_BF(x)                  (((x) >> 26) & 0x7)
+#define   C_028800_STENCILZPASS_BF                     0xE3FFFFFF
+#define   S_028800_STENCILZFAIL_BF(x)                  (((x) & 0x7) << 29)
+#define   G_028800_STENCILZFAIL_BF(x)                  (((x) >> 29) & 0x7)
+#define   C_028800_STENCILZFAIL_BF                     0x1FFFFFFF
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_hdmi.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_hdmi.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_hdmi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_hdmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,13 +42,13 @@ enum r600_hdmi_color_format {
  */
 enum r600_hdmi_iec_status_bits {
 	AUDIO_STATUS_DIG_ENABLE   = 0x01,
-	AUDIO_STATUS_V	    = 0x02,
-	AUDIO_STATUS_VCFG	 = 0x04,
+	AUDIO_STATUS_V            = 0x02,
+	AUDIO_STATUS_VCFG         = 0x04,
 	AUDIO_STATUS_EMPHASIS     = 0x08,
 	AUDIO_STATUS_COPYRIGHT    = 0x10,
 	AUDIO_STATUS_NONAUDIO     = 0x20,
 	AUDIO_STATUS_PROFESSIONAL = 0x40,
-	AUDIO_STATUS_LEVEL	= 0x80
+	AUDIO_STATUS_LEVEL        = 0x80
 };
 
 struct {
@@ -85,7 +85,7 @@ struct {
 static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq)
 {
 	if (*CTS == 0)
-		*CTS = clock*N/(128*freq)*1000;
+		*CTS = clock * N / (128 * freq) * 1000;
 	DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n",
 		  N, *CTS, freq);
 }
@@ -131,11 +131,11 @@ static void r600_hdmi_infoframe_checksum
 					 uint8_t length,
 					 uint8_t *frame)
 {
-    int i;
-    frame[0] = packetType + versionNumber + length;
-    for (i = 1; i <= length; i++)
-	frame[0] += frame[i];
-    frame[0] = 0x100 - frame[0];
+	int i;
+	frame[0] = packetType + versionNumber + length;
+	for (i = 1; i <= length; i++)
+		frame[0] += frame[i];
+	frame[0] = 0x100 - frame[0];
 }
 
 /*
@@ -314,6 +314,9 @@ void r600_hdmi_setmode(struct drm_encode
 	struct radeon_device *rdev = dev->dev_private;
 	uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
 
+	if (ASIC_IS_DCE4(rdev))
+		return;
+
 	if (!offset)
 		return;
 
@@ -417,90 +420,147 @@ void r600_hdmi_update_audio_settings(str
 	WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000);
 }
 
-/*
- * enable/disable the HDMI engine
- */
-void r600_hdmi_enable(struct drm_encoder *encoder, int enable)
+static int r600_hdmi_find_free_block(struct drm_device *dev)
+{
+	struct radeon_device *rdev = dev->dev_private;
+	struct drm_encoder *encoder;
+	struct radeon_encoder *radeon_encoder;
+	bool free_blocks[3] = { true, true, true };
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		radeon_encoder = to_radeon_encoder(encoder);
+		switch (radeon_encoder->hdmi_offset) {
+		case R600_HDMI_BLOCK1:
+			free_blocks[0] = false;
+			break;
+		case R600_HDMI_BLOCK2:
+			free_blocks[1] = false;
+			break;
+		case R600_HDMI_BLOCK3:
+			free_blocks[2] = false;
+			break;
+		}
+	}
+
+	if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690) {
+		return free_blocks[0] ? R600_HDMI_BLOCK1 : 0;
+	} else if (rdev->family >= CHIP_R600) {
+		if (free_blocks[0])
+			return R600_HDMI_BLOCK1;
+		else if (free_blocks[1])
+			return R600_HDMI_BLOCK2;
+	}
+	return 0;
+}
+
+static void r600_hdmi_assign_block(struct drm_encoder *encoder)
 {
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-	uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
+	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 
-	if (!offset)
+	if (!dig) {
+		dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n");
 		return;
+	}
 
-	DRM_DEBUG("%s HDMI interface @ 0x%04X\n", enable ? "Enabling" : "Disabling", offset);
+	if (ASIC_IS_DCE4(rdev)) {
+		/* TODO */
+	} else if (ASIC_IS_DCE3(rdev)) {
+		radeon_encoder->hdmi_offset = dig->dig_encoder ?
+			R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1;
+		if (ASIC_IS_DCE32(rdev))
+			radeon_encoder->hdmi_config_offset = dig->dig_encoder ?
+				R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1;
+	} else if (rdev->family >= CHIP_R600) {
+		radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev);
+	}
+}
 
-	/* some version of atombios ignore the enable HDMI flag
-	 * so enabling/disabling HDMI was moved here for TMDS1+2 */
-	switch (radeon_encoder->encoder_id) {
-	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-		WREG32_P(AVIVO_TMDSA_CNTL, enable ? 0x4 : 0x0, ~0x4);
-		WREG32(offset+R600_HDMI_ENABLE, enable ? 0x101 : 0x0);
-		break;
+/*
+ * enable the HDMI engine
+ */
+void r600_hdmi_enable(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 
-	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-		WREG32_P(AVIVO_LVTMA_CNTL, enable ? 0x4 : 0x0, ~0x4);
-		WREG32(offset+R600_HDMI_ENABLE, enable ? 0x105 : 0x0);
-		break;
+	if (ASIC_IS_DCE4(rdev))
+		return;
 
-	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-		/* This part is doubtfull in my opinion */
-		WREG32(offset+R600_HDMI_ENABLE, enable ? 0x110 : 0x0);
-		break;
+	if (!radeon_encoder->hdmi_offset) {
+		r600_hdmi_assign_block(encoder);
+		if (!radeon_encoder->hdmi_offset) {
+			dev_warn(rdev->dev, "Could not find HDMI block for "
+				"0x%x encoder\n", radeon_encoder->encoder_id);
+			return;
+		}
+	}
 
-	default:
-		DRM_ERROR("unknown HDMI output type\n");
-		break;
+	if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) {
+		WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1);
+	} else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
+		int offset = radeon_encoder->hdmi_offset;
+		switch (radeon_encoder->encoder_id) {
+		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+			WREG32_P(AVIVO_TMDSA_CNTL, 0x4, ~0x4);
+			WREG32(offset + R600_HDMI_ENABLE, 0x101);
+			break;
+		case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+			WREG32_P(AVIVO_LVTMA_CNTL, 0x4, ~0x4);
+			WREG32(offset + R600_HDMI_ENABLE, 0x105);
+			break;
+		default:
+			dev_err(rdev->dev, "Unknown HDMI output type\n");
+			break;
+		}
 	}
+
+	DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n",
+		radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
 }
 
 /*
- * determin at which register offset the HDMI encoder is
+ * disable the HDMI engine
  */
-void r600_hdmi_init(struct drm_encoder *encoder)
+void r600_hdmi_disable(struct drm_encoder *encoder)
 {
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 
-	switch (radeon_encoder->encoder_id) {
-	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-		radeon_encoder->hdmi_offset = R600_HDMI_TMDS1;
-		break;
+	if (ASIC_IS_DCE4(rdev))
+		return;
 
-	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-		switch (r600_audio_tmds_index(encoder)) {
-		case 0:
-			radeon_encoder->hdmi_offset = R600_HDMI_TMDS1;
+	if (!radeon_encoder->hdmi_offset) {
+		dev_err(rdev->dev, "Disabling not enabled HDMI\n");
+		return;
+	}
+
+	DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n",
+		radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
+
+	if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) {
+		WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1);
+	} else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
+		int offset = radeon_encoder->hdmi_offset;
+		switch (radeon_encoder->encoder_id) {
+		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+			WREG32_P(AVIVO_TMDSA_CNTL, 0, ~0x4);
+			WREG32(offset + R600_HDMI_ENABLE, 0);
 			break;
-		case 1:
-			radeon_encoder->hdmi_offset = R600_HDMI_TMDS2;
+		case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+			WREG32_P(AVIVO_LVTMA_CNTL, 0, ~0x4);
+			WREG32(offset + R600_HDMI_ENABLE, 0);
 			break;
 		default:
-			radeon_encoder->hdmi_offset = 0;
+			dev_err(rdev->dev, "Unknown HDMI output type\n");
 			break;
 		}
-	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-		radeon_encoder->hdmi_offset = R600_HDMI_TMDS2;
-		break;
-
-	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-		radeon_encoder->hdmi_offset = R600_HDMI_DIG;
-		break;
-
-	default:
-		radeon_encoder->hdmi_offset = 0;
-		break;
 	}
 
-	DRM_DEBUG("using HDMI engine at offset 0x%04X for encoder 0x%x\n",
-		  radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
-
-	/* TODO: make this configureable */
-	radeon_encoder->hdmi_audio_workaround = 0;
+	radeon_encoder->hdmi_offset = 0;
+	radeon_encoder->hdmi_config_offset = 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_reg.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_reg.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_reg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/r600_reg.h	2010-05-16 17:17:36.000000000 -0400
@@ -152,9 +152,9 @@
 #define R600_AUDIO_STATUS_BITS            0x73d8
 
 /* HDMI base register addresses */
-#define R600_HDMI_TMDS1                   0x7400
-#define R600_HDMI_TMDS2                   0x7700
-#define R600_HDMI_DIG                     0x7800
+#define R600_HDMI_BLOCK1                  0x7400
+#define R600_HDMI_BLOCK2                  0x7700
+#define R600_HDMI_BLOCK3                  0x7800
 
 /* HDMI registers */
 #define R600_HDMI_ENABLE           0x00
@@ -185,4 +185,8 @@
 #define R600_HDMI_AUDIO_DEBUG_2    0xe8
 #define R600_HDMI_AUDIO_DEBUG_3    0xec
 
+/* HDMI additional config base register addresses */
+#define R600_HDMI_CONFIG1                 0x7600
+#define R600_HDMI_CONFIG2                 0x7a00
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_agp.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_agp.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_agp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_agp.c	2010-05-16 17:17:36.000000000 -0400
@@ -134,12 +134,10 @@ int radeon_agp_init(struct radeon_device
 	int ret;
 
 	/* Acquire AGP. */
-	if (!rdev->ddev->agp->acquired) {
-		ret = drm_agp_acquire(rdev->ddev);
-		if (ret) {
-			DRM_ERROR("Unable to acquire AGP: %d\n", ret);
-			return ret;
-		}
+	ret = drm_agp_acquire(rdev->ddev);
+	if (ret) {
+		DRM_ERROR("Unable to acquire AGP: %d\n", ret);
+		return ret;
 	}
 
 	ret = drm_agp_info(rdev->ddev, &info);
@@ -237,6 +235,10 @@ int radeon_agp_init(struct radeon_device
 
 	rdev->mc.agp_base = rdev->ddev->agp->agp_info.aper_base;
 	rdev->mc.gtt_size = rdev->ddev->agp->agp_info.aper_size << 20;
+	rdev->mc.gtt_start = rdev->mc.agp_base;
+	rdev->mc.gtt_end = rdev->mc.gtt_start + rdev->mc.gtt_size - 1;
+	dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n",
+		rdev->mc.gtt_size >> 20, rdev->mc.gtt_start, rdev->mc.gtt_end);
 
 	/* workaround some hw issues */
 	if (rdev->family < CHIP_R200) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_asic.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_asic.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_asic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_asic.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,772 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ *          Alex Deucher
+ *          Jerome Glisse
+ */
+
+#include <linux/console.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/radeon_drm.h>
+#include <linux/vgaarb.h>
+#include <linux/vga_switcheroo.h>
+#include "radeon_reg.h"
+#include "radeon.h"
+#include "radeon_asic.h"
+#include "atom.h"
+
+/*
+ * Registers accessors functions.
+ */
+static uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg)
+{
+	DRM_ERROR("Invalid callback to read register 0x%04X\n", reg);
+	BUG_ON(1);
+	return 0;
+}
+
+static void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
+{
+	DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n",
+		  reg, v);
+	BUG_ON(1);
+}
+
+static void radeon_register_accessor_init(struct radeon_device *rdev)
+{
+	rdev->mc_rreg = &radeon_invalid_rreg;
+	rdev->mc_wreg = &radeon_invalid_wreg;
+	rdev->pll_rreg = &radeon_invalid_rreg;
+	rdev->pll_wreg = &radeon_invalid_wreg;
+	rdev->pciep_rreg = &radeon_invalid_rreg;
+	rdev->pciep_wreg = &radeon_invalid_wreg;
+
+	/* Don't change order as we are overridding accessor. */
+	if (rdev->family < CHIP_RV515) {
+		rdev->pcie_reg_mask = 0xff;
+	} else {
+		rdev->pcie_reg_mask = 0x7ff;
+	}
+	/* FIXME: not sure here */
+	if (rdev->family <= CHIP_R580) {
+		rdev->pll_rreg = &r100_pll_rreg;
+		rdev->pll_wreg = &r100_pll_wreg;
+	}
+	if (rdev->family >= CHIP_R420) {
+		rdev->mc_rreg = &r420_mc_rreg;
+		rdev->mc_wreg = &r420_mc_wreg;
+	}
+	if (rdev->family >= CHIP_RV515) {
+		rdev->mc_rreg = &rv515_mc_rreg;
+		rdev->mc_wreg = &rv515_mc_wreg;
+	}
+	if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) {
+		rdev->mc_rreg = &rs400_mc_rreg;
+		rdev->mc_wreg = &rs400_mc_wreg;
+	}
+	if (rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) {
+		rdev->mc_rreg = &rs690_mc_rreg;
+		rdev->mc_wreg = &rs690_mc_wreg;
+	}
+	if (rdev->family == CHIP_RS600) {
+		rdev->mc_rreg = &rs600_mc_rreg;
+		rdev->mc_wreg = &rs600_mc_wreg;
+	}
+	if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) {
+		rdev->pciep_rreg = &r600_pciep_rreg;
+		rdev->pciep_wreg = &r600_pciep_wreg;
+	}
+}
+
+
+/* helper to disable agp */
+void radeon_agp_disable(struct radeon_device *rdev)
+{
+	rdev->flags &= ~RADEON_IS_AGP;
+	if (rdev->family >= CHIP_R600) {
+		DRM_INFO("Forcing AGP to PCIE mode\n");
+		rdev->flags |= RADEON_IS_PCIE;
+	} else if (rdev->family >= CHIP_RV515 ||
+			rdev->family == CHIP_RV380 ||
+			rdev->family == CHIP_RV410 ||
+			rdev->family == CHIP_R423) {
+		DRM_INFO("Forcing AGP to PCIE mode\n");
+		rdev->flags |= RADEON_IS_PCIE;
+		rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
+		rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
+	} else {
+		DRM_INFO("Forcing AGP to PCI mode\n");
+		rdev->flags |= RADEON_IS_PCI;
+		rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
+		rdev->asic->gart_set_page = &r100_pci_gart_set_page;
+	}
+	rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+}
+
+/*
+ * ASIC
+ */
+static struct radeon_asic r100_asic = {
+	.init = &r100_init,
+	.fini = &r100_fini,
+	.suspend = &r100_suspend,
+	.resume = &r100_resume,
+	.vga_set_state = &r100_vga_set_state,
+	.gpu_reset = &r100_gpu_reset,
+	.gart_tlb_flush = &r100_pci_gart_tlb_flush,
+	.gart_set_page = &r100_pci_gart_set_page,
+	.cp_commit = &r100_cp_commit,
+	.ring_start = &r100_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.irq_set = &r100_irq_set,
+	.irq_process = &r100_irq_process,
+	.get_vblank_counter = &r100_get_vblank_counter,
+	.fence_ring_emit = &r100_fence_ring_emit,
+	.cs_parse = &r100_cs_parse,
+	.copy_blit = &r100_copy_blit,
+	.copy_dma = NULL,
+	.copy = &r100_copy_blit,
+	.get_engine_clock = &radeon_legacy_get_engine_clock,
+	.set_engine_clock = &radeon_legacy_set_engine_clock,
+	.get_memory_clock = &radeon_legacy_get_memory_clock,
+	.set_memory_clock = NULL,
+	.get_pcie_lanes = NULL,
+	.set_pcie_lanes = NULL,
+	.set_clock_gating = &radeon_legacy_set_clock_gating,
+	.set_surface_reg = r100_set_surface_reg,
+	.clear_surface_reg = r100_clear_surface_reg,
+	.bandwidth_update = &r100_bandwidth_update,
+	.hpd_init = &r100_hpd_init,
+	.hpd_fini = &r100_hpd_fini,
+	.hpd_sense = &r100_hpd_sense,
+	.hpd_set_polarity = &r100_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r200_asic = {
+	.init = &r100_init,
+	.fini = &r100_fini,
+	.suspend = &r100_suspend,
+	.resume = &r100_resume,
+	.vga_set_state = &r100_vga_set_state,
+	.gpu_reset = &r100_gpu_reset,
+	.gart_tlb_flush = &r100_pci_gart_tlb_flush,
+	.gart_set_page = &r100_pci_gart_set_page,
+	.cp_commit = &r100_cp_commit,
+	.ring_start = &r100_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.irq_set = &r100_irq_set,
+	.irq_process = &r100_irq_process,
+	.get_vblank_counter = &r100_get_vblank_counter,
+	.fence_ring_emit = &r100_fence_ring_emit,
+	.cs_parse = &r100_cs_parse,
+	.copy_blit = &r100_copy_blit,
+	.copy_dma = &r200_copy_dma,
+	.copy = &r100_copy_blit,
+	.get_engine_clock = &radeon_legacy_get_engine_clock,
+	.set_engine_clock = &radeon_legacy_set_engine_clock,
+	.get_memory_clock = &radeon_legacy_get_memory_clock,
+	.set_memory_clock = NULL,
+	.set_pcie_lanes = NULL,
+	.set_clock_gating = &radeon_legacy_set_clock_gating,
+	.set_surface_reg = r100_set_surface_reg,
+	.clear_surface_reg = r100_clear_surface_reg,
+	.bandwidth_update = &r100_bandwidth_update,
+	.hpd_init = &r100_hpd_init,
+	.hpd_fini = &r100_hpd_fini,
+	.hpd_sense = &r100_hpd_sense,
+	.hpd_set_polarity = &r100_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r300_asic = {
+	.init = &r300_init,
+	.fini = &r300_fini,
+	.suspend = &r300_suspend,
+	.resume = &r300_resume,
+	.vga_set_state = &r100_vga_set_state,
+	.gpu_reset = &r300_gpu_reset,
+	.gart_tlb_flush = &r100_pci_gart_tlb_flush,
+	.gart_set_page = &r100_pci_gart_set_page,
+	.cp_commit = &r100_cp_commit,
+	.ring_start = &r300_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.irq_set = &r100_irq_set,
+	.irq_process = &r100_irq_process,
+	.get_vblank_counter = &r100_get_vblank_counter,
+	.fence_ring_emit = &r300_fence_ring_emit,
+	.cs_parse = &r300_cs_parse,
+	.copy_blit = &r100_copy_blit,
+	.copy_dma = &r200_copy_dma,
+	.copy = &r100_copy_blit,
+	.get_engine_clock = &radeon_legacy_get_engine_clock,
+	.set_engine_clock = &radeon_legacy_set_engine_clock,
+	.get_memory_clock = &radeon_legacy_get_memory_clock,
+	.set_memory_clock = NULL,
+	.get_pcie_lanes = &rv370_get_pcie_lanes,
+	.set_pcie_lanes = &rv370_set_pcie_lanes,
+	.set_clock_gating = &radeon_legacy_set_clock_gating,
+	.set_surface_reg = r100_set_surface_reg,
+	.clear_surface_reg = r100_clear_surface_reg,
+	.bandwidth_update = &r100_bandwidth_update,
+	.hpd_init = &r100_hpd_init,
+	.hpd_fini = &r100_hpd_fini,
+	.hpd_sense = &r100_hpd_sense,
+	.hpd_set_polarity = &r100_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r300_asic_pcie = {
+	.init = &r300_init,
+	.fini = &r300_fini,
+	.suspend = &r300_suspend,
+	.resume = &r300_resume,
+	.vga_set_state = &r100_vga_set_state,
+	.gpu_reset = &r300_gpu_reset,
+	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
+	.gart_set_page = &rv370_pcie_gart_set_page,
+	.cp_commit = &r100_cp_commit,
+	.ring_start = &r300_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.irq_set = &r100_irq_set,
+	.irq_process = &r100_irq_process,
+	.get_vblank_counter = &r100_get_vblank_counter,
+	.fence_ring_emit = &r300_fence_ring_emit,
+	.cs_parse = &r300_cs_parse,
+	.copy_blit = &r100_copy_blit,
+	.copy_dma = &r200_copy_dma,
+	.copy = &r100_copy_blit,
+	.get_engine_clock = &radeon_legacy_get_engine_clock,
+	.set_engine_clock = &radeon_legacy_set_engine_clock,
+	.get_memory_clock = &radeon_legacy_get_memory_clock,
+	.set_memory_clock = NULL,
+	.set_pcie_lanes = &rv370_set_pcie_lanes,
+	.set_clock_gating = &radeon_legacy_set_clock_gating,
+	.set_surface_reg = r100_set_surface_reg,
+	.clear_surface_reg = r100_clear_surface_reg,
+	.bandwidth_update = &r100_bandwidth_update,
+	.hpd_init = &r100_hpd_init,
+	.hpd_fini = &r100_hpd_fini,
+	.hpd_sense = &r100_hpd_sense,
+	.hpd_set_polarity = &r100_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r420_asic = {
+	.init = &r420_init,
+	.fini = &r420_fini,
+	.suspend = &r420_suspend,
+	.resume = &r420_resume,
+	.vga_set_state = &r100_vga_set_state,
+	.gpu_reset = &r300_gpu_reset,
+	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
+	.gart_set_page = &rv370_pcie_gart_set_page,
+	.cp_commit = &r100_cp_commit,
+	.ring_start = &r300_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.irq_set = &r100_irq_set,
+	.irq_process = &r100_irq_process,
+	.get_vblank_counter = &r100_get_vblank_counter,
+	.fence_ring_emit = &r300_fence_ring_emit,
+	.cs_parse = &r300_cs_parse,
+	.copy_blit = &r100_copy_blit,
+	.copy_dma = &r200_copy_dma,
+	.copy = &r100_copy_blit,
+	.get_engine_clock = &radeon_atom_get_engine_clock,
+	.set_engine_clock = &radeon_atom_set_engine_clock,
+	.get_memory_clock = &radeon_atom_get_memory_clock,
+	.set_memory_clock = &radeon_atom_set_memory_clock,
+	.get_pcie_lanes = &rv370_get_pcie_lanes,
+	.set_pcie_lanes = &rv370_set_pcie_lanes,
+	.set_clock_gating = &radeon_atom_set_clock_gating,
+	.set_surface_reg = r100_set_surface_reg,
+	.clear_surface_reg = r100_clear_surface_reg,
+	.bandwidth_update = &r100_bandwidth_update,
+	.hpd_init = &r100_hpd_init,
+	.hpd_fini = &r100_hpd_fini,
+	.hpd_sense = &r100_hpd_sense,
+	.hpd_set_polarity = &r100_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic rs400_asic = {
+	.init = &rs400_init,
+	.fini = &rs400_fini,
+	.suspend = &rs400_suspend,
+	.resume = &rs400_resume,
+	.vga_set_state = &r100_vga_set_state,
+	.gpu_reset = &r300_gpu_reset,
+	.gart_tlb_flush = &rs400_gart_tlb_flush,
+	.gart_set_page = &rs400_gart_set_page,
+	.cp_commit = &r100_cp_commit,
+	.ring_start = &r300_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.irq_set = &r100_irq_set,
+	.irq_process = &r100_irq_process,
+	.get_vblank_counter = &r100_get_vblank_counter,
+	.fence_ring_emit = &r300_fence_ring_emit,
+	.cs_parse = &r300_cs_parse,
+	.copy_blit = &r100_copy_blit,
+	.copy_dma = &r200_copy_dma,
+	.copy = &r100_copy_blit,
+	.get_engine_clock = &radeon_legacy_get_engine_clock,
+	.set_engine_clock = &radeon_legacy_set_engine_clock,
+	.get_memory_clock = &radeon_legacy_get_memory_clock,
+	.set_memory_clock = NULL,
+	.get_pcie_lanes = NULL,
+	.set_pcie_lanes = NULL,
+	.set_clock_gating = &radeon_legacy_set_clock_gating,
+	.set_surface_reg = r100_set_surface_reg,
+	.clear_surface_reg = r100_clear_surface_reg,
+	.bandwidth_update = &r100_bandwidth_update,
+	.hpd_init = &r100_hpd_init,
+	.hpd_fini = &r100_hpd_fini,
+	.hpd_sense = &r100_hpd_sense,
+	.hpd_set_polarity = &r100_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic rs600_asic = {
+	.init = &rs600_init,
+	.fini = &rs600_fini,
+	.suspend = &rs600_suspend,
+	.resume = &rs600_resume,
+	.vga_set_state = &r100_vga_set_state,
+	.gpu_reset = &r300_gpu_reset,
+	.gart_tlb_flush = &rs600_gart_tlb_flush,
+	.gart_set_page = &rs600_gart_set_page,
+	.cp_commit = &r100_cp_commit,
+	.ring_start = &r300_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.irq_set = &rs600_irq_set,
+	.irq_process = &rs600_irq_process,
+	.get_vblank_counter = &rs600_get_vblank_counter,
+	.fence_ring_emit = &r300_fence_ring_emit,
+	.cs_parse = &r300_cs_parse,
+	.copy_blit = &r100_copy_blit,
+	.copy_dma = &r200_copy_dma,
+	.copy = &r100_copy_blit,
+	.get_engine_clock = &radeon_atom_get_engine_clock,
+	.set_engine_clock = &radeon_atom_set_engine_clock,
+	.get_memory_clock = &radeon_atom_get_memory_clock,
+	.set_memory_clock = &radeon_atom_set_memory_clock,
+	.get_pcie_lanes = NULL,
+	.set_pcie_lanes = NULL,
+	.set_clock_gating = &radeon_atom_set_clock_gating,
+	.set_surface_reg = r100_set_surface_reg,
+	.clear_surface_reg = r100_clear_surface_reg,
+	.bandwidth_update = &rs600_bandwidth_update,
+	.hpd_init = &rs600_hpd_init,
+	.hpd_fini = &rs600_hpd_fini,
+	.hpd_sense = &rs600_hpd_sense,
+	.hpd_set_polarity = &rs600_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic rs690_asic = {
+	.init = &rs690_init,
+	.fini = &rs690_fini,
+	.suspend = &rs690_suspend,
+	.resume = &rs690_resume,
+	.vga_set_state = &r100_vga_set_state,
+	.gpu_reset = &r300_gpu_reset,
+	.gart_tlb_flush = &rs400_gart_tlb_flush,
+	.gart_set_page = &rs400_gart_set_page,
+	.cp_commit = &r100_cp_commit,
+	.ring_start = &r300_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.irq_set = &rs600_irq_set,
+	.irq_process = &rs600_irq_process,
+	.get_vblank_counter = &rs600_get_vblank_counter,
+	.fence_ring_emit = &r300_fence_ring_emit,
+	.cs_parse = &r300_cs_parse,
+	.copy_blit = &r100_copy_blit,
+	.copy_dma = &r200_copy_dma,
+	.copy = &r200_copy_dma,
+	.get_engine_clock = &radeon_atom_get_engine_clock,
+	.set_engine_clock = &radeon_atom_set_engine_clock,
+	.get_memory_clock = &radeon_atom_get_memory_clock,
+	.set_memory_clock = &radeon_atom_set_memory_clock,
+	.get_pcie_lanes = NULL,
+	.set_pcie_lanes = NULL,
+	.set_clock_gating = &radeon_atom_set_clock_gating,
+	.set_surface_reg = r100_set_surface_reg,
+	.clear_surface_reg = r100_clear_surface_reg,
+	.bandwidth_update = &rs690_bandwidth_update,
+	.hpd_init = &rs600_hpd_init,
+	.hpd_fini = &rs600_hpd_fini,
+	.hpd_sense = &rs600_hpd_sense,
+	.hpd_set_polarity = &rs600_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic rv515_asic = {
+	.init = &rv515_init,
+	.fini = &rv515_fini,
+	.suspend = &rv515_suspend,
+	.resume = &rv515_resume,
+	.vga_set_state = &r100_vga_set_state,
+	.gpu_reset = &rv515_gpu_reset,
+	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
+	.gart_set_page = &rv370_pcie_gart_set_page,
+	.cp_commit = &r100_cp_commit,
+	.ring_start = &rv515_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.irq_set = &rs600_irq_set,
+	.irq_process = &rs600_irq_process,
+	.get_vblank_counter = &rs600_get_vblank_counter,
+	.fence_ring_emit = &r300_fence_ring_emit,
+	.cs_parse = &r300_cs_parse,
+	.copy_blit = &r100_copy_blit,
+	.copy_dma = &r200_copy_dma,
+	.copy = &r100_copy_blit,
+	.get_engine_clock = &radeon_atom_get_engine_clock,
+	.set_engine_clock = &radeon_atom_set_engine_clock,
+	.get_memory_clock = &radeon_atom_get_memory_clock,
+	.set_memory_clock = &radeon_atom_set_memory_clock,
+	.get_pcie_lanes = &rv370_get_pcie_lanes,
+	.set_pcie_lanes = &rv370_set_pcie_lanes,
+	.set_clock_gating = &radeon_atom_set_clock_gating,
+	.set_surface_reg = r100_set_surface_reg,
+	.clear_surface_reg = r100_clear_surface_reg,
+	.bandwidth_update = &rv515_bandwidth_update,
+	.hpd_init = &rs600_hpd_init,
+	.hpd_fini = &rs600_hpd_fini,
+	.hpd_sense = &rs600_hpd_sense,
+	.hpd_set_polarity = &rs600_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r520_asic = {
+	.init = &r520_init,
+	.fini = &rv515_fini,
+	.suspend = &rv515_suspend,
+	.resume = &r520_resume,
+	.vga_set_state = &r100_vga_set_state,
+	.gpu_reset = &rv515_gpu_reset,
+	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
+	.gart_set_page = &rv370_pcie_gart_set_page,
+	.cp_commit = &r100_cp_commit,
+	.ring_start = &rv515_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.irq_set = &rs600_irq_set,
+	.irq_process = &rs600_irq_process,
+	.get_vblank_counter = &rs600_get_vblank_counter,
+	.fence_ring_emit = &r300_fence_ring_emit,
+	.cs_parse = &r300_cs_parse,
+	.copy_blit = &r100_copy_blit,
+	.copy_dma = &r200_copy_dma,
+	.copy = &r100_copy_blit,
+	.get_engine_clock = &radeon_atom_get_engine_clock,
+	.set_engine_clock = &radeon_atom_set_engine_clock,
+	.get_memory_clock = &radeon_atom_get_memory_clock,
+	.set_memory_clock = &radeon_atom_set_memory_clock,
+	.get_pcie_lanes = &rv370_get_pcie_lanes,
+	.set_pcie_lanes = &rv370_set_pcie_lanes,
+	.set_clock_gating = &radeon_atom_set_clock_gating,
+	.set_surface_reg = r100_set_surface_reg,
+	.clear_surface_reg = r100_clear_surface_reg,
+	.bandwidth_update = &rv515_bandwidth_update,
+	.hpd_init = &rs600_hpd_init,
+	.hpd_fini = &rs600_hpd_fini,
+	.hpd_sense = &rs600_hpd_sense,
+	.hpd_set_polarity = &rs600_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r600_asic = {
+	.init = &r600_init,
+	.fini = &r600_fini,
+	.suspend = &r600_suspend,
+	.resume = &r600_resume,
+	.cp_commit = &r600_cp_commit,
+	.vga_set_state = &r600_vga_set_state,
+	.gpu_reset = &r600_gpu_reset,
+	.gart_tlb_flush = &r600_pcie_gart_tlb_flush,
+	.gart_set_page = &rs600_gart_set_page,
+	.ring_test = &r600_ring_test,
+	.ring_ib_execute = &r600_ring_ib_execute,
+	.irq_set = &r600_irq_set,
+	.irq_process = &r600_irq_process,
+	.get_vblank_counter = &rs600_get_vblank_counter,
+	.fence_ring_emit = &r600_fence_ring_emit,
+	.cs_parse = &r600_cs_parse,
+	.copy_blit = &r600_copy_blit,
+	.copy_dma = &r600_copy_blit,
+	.copy = &r600_copy_blit,
+	.get_engine_clock = &radeon_atom_get_engine_clock,
+	.set_engine_clock = &radeon_atom_set_engine_clock,
+	.get_memory_clock = &radeon_atom_get_memory_clock,
+	.set_memory_clock = &radeon_atom_set_memory_clock,
+	.get_pcie_lanes = &rv370_get_pcie_lanes,
+	.set_pcie_lanes = NULL,
+	.set_clock_gating = NULL,
+	.set_surface_reg = r600_set_surface_reg,
+	.clear_surface_reg = r600_clear_surface_reg,
+	.bandwidth_update = &rv515_bandwidth_update,
+	.hpd_init = &r600_hpd_init,
+	.hpd_fini = &r600_hpd_fini,
+	.hpd_sense = &r600_hpd_sense,
+	.hpd_set_polarity = &r600_hpd_set_polarity,
+	.ioctl_wait_idle = r600_ioctl_wait_idle,
+};
+
+static struct radeon_asic rs780_asic = {
+	.init = &r600_init,
+	.fini = &r600_fini,
+	.suspend = &r600_suspend,
+	.resume = &r600_resume,
+	.cp_commit = &r600_cp_commit,
+	.vga_set_state = &r600_vga_set_state,
+	.gpu_reset = &r600_gpu_reset,
+	.gart_tlb_flush = &r600_pcie_gart_tlb_flush,
+	.gart_set_page = &rs600_gart_set_page,
+	.ring_test = &r600_ring_test,
+	.ring_ib_execute = &r600_ring_ib_execute,
+	.irq_set = &r600_irq_set,
+	.irq_process = &r600_irq_process,
+	.get_vblank_counter = &rs600_get_vblank_counter,
+	.fence_ring_emit = &r600_fence_ring_emit,
+	.cs_parse = &r600_cs_parse,
+	.copy_blit = &r600_copy_blit,
+	.copy_dma = &r600_copy_blit,
+	.copy = &r600_copy_blit,
+	.get_engine_clock = &radeon_atom_get_engine_clock,
+	.set_engine_clock = &radeon_atom_set_engine_clock,
+	.get_memory_clock = NULL,
+	.set_memory_clock = NULL,
+	.get_pcie_lanes = NULL,
+	.set_pcie_lanes = NULL,
+	.set_clock_gating = NULL,
+	.set_surface_reg = r600_set_surface_reg,
+	.clear_surface_reg = r600_clear_surface_reg,
+	.bandwidth_update = &rs690_bandwidth_update,
+	.hpd_init = &r600_hpd_init,
+	.hpd_fini = &r600_hpd_fini,
+	.hpd_sense = &r600_hpd_sense,
+	.hpd_set_polarity = &r600_hpd_set_polarity,
+	.ioctl_wait_idle = r600_ioctl_wait_idle,
+};
+
+static struct radeon_asic rv770_asic = {
+	.init = &rv770_init,
+	.fini = &rv770_fini,
+	.suspend = &rv770_suspend,
+	.resume = &rv770_resume,
+	.cp_commit = &r600_cp_commit,
+	.gpu_reset = &rv770_gpu_reset,
+	.vga_set_state = &r600_vga_set_state,
+	.gart_tlb_flush = &r600_pcie_gart_tlb_flush,
+	.gart_set_page = &rs600_gart_set_page,
+	.ring_test = &r600_ring_test,
+	.ring_ib_execute = &r600_ring_ib_execute,
+	.irq_set = &r600_irq_set,
+	.irq_process = &r600_irq_process,
+	.get_vblank_counter = &rs600_get_vblank_counter,
+	.fence_ring_emit = &r600_fence_ring_emit,
+	.cs_parse = &r600_cs_parse,
+	.copy_blit = &r600_copy_blit,
+	.copy_dma = &r600_copy_blit,
+	.copy = &r600_copy_blit,
+	.get_engine_clock = &radeon_atom_get_engine_clock,
+	.set_engine_clock = &radeon_atom_set_engine_clock,
+	.get_memory_clock = &radeon_atom_get_memory_clock,
+	.set_memory_clock = &radeon_atom_set_memory_clock,
+	.get_pcie_lanes = &rv370_get_pcie_lanes,
+	.set_pcie_lanes = NULL,
+	.set_clock_gating = &radeon_atom_set_clock_gating,
+	.set_surface_reg = r600_set_surface_reg,
+	.clear_surface_reg = r600_clear_surface_reg,
+	.bandwidth_update = &rv515_bandwidth_update,
+	.hpd_init = &r600_hpd_init,
+	.hpd_fini = &r600_hpd_fini,
+	.hpd_sense = &r600_hpd_sense,
+	.hpd_set_polarity = &r600_hpd_set_polarity,
+	.ioctl_wait_idle = r600_ioctl_wait_idle,
+};
+
+static struct radeon_asic evergreen_asic = {
+	.init = &evergreen_init,
+	.fini = &evergreen_fini,
+	.suspend = &evergreen_suspend,
+	.resume = &evergreen_resume,
+	.cp_commit = NULL,
+	.gpu_reset = &evergreen_gpu_reset,
+	.vga_set_state = &r600_vga_set_state,
+	.gart_tlb_flush = &r600_pcie_gart_tlb_flush,
+	.gart_set_page = &rs600_gart_set_page,
+	.ring_test = NULL,
+	.ring_ib_execute = NULL,
+	.irq_set = NULL,
+	.irq_process = NULL,
+	.get_vblank_counter = NULL,
+	.fence_ring_emit = NULL,
+	.cs_parse = NULL,
+	.copy_blit = NULL,
+	.copy_dma = NULL,
+	.copy = NULL,
+	.get_engine_clock = &radeon_atom_get_engine_clock,
+	.set_engine_clock = &radeon_atom_set_engine_clock,
+	.get_memory_clock = &radeon_atom_get_memory_clock,
+	.set_memory_clock = &radeon_atom_set_memory_clock,
+	.set_pcie_lanes = NULL,
+	.set_clock_gating = NULL,
+	.set_surface_reg = r600_set_surface_reg,
+	.clear_surface_reg = r600_clear_surface_reg,
+	.bandwidth_update = &evergreen_bandwidth_update,
+	.hpd_init = &evergreen_hpd_init,
+	.hpd_fini = &evergreen_hpd_fini,
+	.hpd_sense = &evergreen_hpd_sense,
+	.hpd_set_polarity = &evergreen_hpd_set_polarity,
+};
+
+int radeon_asic_init(struct radeon_device *rdev)
+{
+	radeon_register_accessor_init(rdev);
+	switch (rdev->family) {
+	case CHIP_R100:
+	case CHIP_RV100:
+	case CHIP_RS100:
+	case CHIP_RV200:
+	case CHIP_RS200:
+		rdev->asic = &r100_asic;
+		break;
+	case CHIP_R200:
+	case CHIP_RV250:
+	case CHIP_RS300:
+	case CHIP_RV280:
+		rdev->asic = &r200_asic;
+		break;
+	case CHIP_R300:
+	case CHIP_R350:
+	case CHIP_RV350:
+	case CHIP_RV380:
+		if (rdev->flags & RADEON_IS_PCIE)
+			rdev->asic = &r300_asic_pcie;
+		else
+			rdev->asic = &r300_asic;
+		break;
+	case CHIP_R420:
+	case CHIP_R423:
+	case CHIP_RV410:
+		rdev->asic = &r420_asic;
+		break;
+	case CHIP_RS400:
+	case CHIP_RS480:
+		rdev->asic = &rs400_asic;
+		break;
+	case CHIP_RS600:
+		rdev->asic = &rs600_asic;
+		break;
+	case CHIP_RS690:
+	case CHIP_RS740:
+		rdev->asic = &rs690_asic;
+		break;
+	case CHIP_RV515:
+		rdev->asic = &rv515_asic;
+		break;
+	case CHIP_R520:
+	case CHIP_RV530:
+	case CHIP_RV560:
+	case CHIP_RV570:
+	case CHIP_R580:
+		rdev->asic = &r520_asic;
+		break;
+	case CHIP_R600:
+	case CHIP_RV610:
+	case CHIP_RV630:
+	case CHIP_RV620:
+	case CHIP_RV635:
+	case CHIP_RV670:
+		rdev->asic = &r600_asic;
+		break;
+	case CHIP_RS780:
+	case CHIP_RS880:
+		rdev->asic = &rs780_asic;
+		break;
+	case CHIP_RV770:
+	case CHIP_RV730:
+	case CHIP_RV710:
+	case CHIP_RV740:
+		rdev->asic = &rv770_asic;
+		break;
+	case CHIP_CEDAR:
+	case CHIP_REDWOOD:
+	case CHIP_JUNIPER:
+	case CHIP_CYPRESS:
+	case CHIP_HEMLOCK:
+		rdev->asic = &evergreen_asic;
+		break;
+	default:
+		/* FIXME: not supported yet */
+		return -EINVAL;
+	}
+
+	if (rdev->flags & RADEON_IS_IGP) {
+		rdev->asic->get_memory_clock = NULL;
+		rdev->asic->set_memory_clock = NULL;
+	}
+
+	/* set the number of crtcs */
+	if (rdev->flags & RADEON_SINGLE_CRTC)
+		rdev->num_crtc = 1;
+	else {
+		if (ASIC_IS_DCE4(rdev))
+			rdev->num_crtc = 6;
+		else
+			rdev->num_crtc = 2;
+	}
+
+	return 0;
+}
+
+/*
+ * Wrapper around modesetting bits. Move to radeon_clocks.c?
+ */
+int radeon_clocks_init(struct radeon_device *rdev)
+{
+	int r;
+
+	r = radeon_static_clocks_init(rdev->ddev);
+	if (r) {
+		return r;
+	}
+	DRM_INFO("Clocks initialized !\n");
+	return 0;
+}
+
+void radeon_clocks_fini(struct radeon_device *rdev)
+{
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_asic.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_asic.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_asic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_asic.h	2010-05-16 17:17:36.000000000 -0400
@@ -43,12 +43,20 @@ void radeon_atom_set_memory_clock(struct
 void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
 
 /*
- * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
+ * r100,rv100,rs100,rv200,rs200
  */
-extern int r100_init(struct radeon_device *rdev);
-extern void r100_fini(struct radeon_device *rdev);
-extern int r100_suspend(struct radeon_device *rdev);
-extern int r100_resume(struct radeon_device *rdev);
+struct r100_mc_save {
+	u32	GENMO_WT;
+	u32	CRTC_EXT_CNTL;
+	u32	CRTC_GEN_CNTL;
+	u32	CRTC2_GEN_CNTL;
+	u32	CUR_OFFSET;
+	u32	CUR2_OFFSET;
+};
+int r100_init(struct radeon_device *rdev);
+void r100_fini(struct radeon_device *rdev);
+int r100_suspend(struct radeon_device *rdev);
+int r100_resume(struct radeon_device *rdev);
 uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg);
 void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 void r100_vga_set_state(struct radeon_device *rdev, bool state);
@@ -73,7 +81,7 @@ int r100_copy_blit(struct radeon_device
 int r100_set_surface_reg(struct radeon_device *rdev, int reg,
 			 uint32_t tiling_flags, uint32_t pitch,
 			 uint32_t offset, uint32_t obj_size);
-int r100_clear_surface_reg(struct radeon_device *rdev, int reg);
+void r100_clear_surface_reg(struct radeon_device *rdev, int reg);
 void r100_bandwidth_update(struct radeon_device *rdev);
 void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
 int r100_ring_test(struct radeon_device *rdev);
@@ -82,44 +90,51 @@ void r100_hpd_fini(struct radeon_device
 bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
 void r100_hpd_set_polarity(struct radeon_device *rdev,
 			   enum radeon_hpd_id hpd);
+int r100_debugfs_rbbm_init(struct radeon_device *rdev);
+int r100_debugfs_cp_init(struct radeon_device *rdev);
+void r100_cp_disable(struct radeon_device *rdev);
+int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
+void r100_cp_fini(struct radeon_device *rdev);
+int r100_pci_gart_init(struct radeon_device *rdev);
+void r100_pci_gart_fini(struct radeon_device *rdev);
+int r100_pci_gart_enable(struct radeon_device *rdev);
+void r100_pci_gart_disable(struct radeon_device *rdev);
+int r100_debugfs_mc_info_init(struct radeon_device *rdev);
+int r100_gui_wait_for_idle(struct radeon_device *rdev);
+void r100_ib_fini(struct radeon_device *rdev);
+int r100_ib_init(struct radeon_device *rdev);
+void r100_irq_disable(struct radeon_device *rdev);
+void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save);
+void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save);
+void r100_vram_init_sizes(struct radeon_device *rdev);
+void r100_wb_disable(struct radeon_device *rdev);
+void r100_wb_fini(struct radeon_device *rdev);
+int r100_wb_init(struct radeon_device *rdev);
+void r100_hdp_reset(struct radeon_device *rdev);
+int r100_rb2d_reset(struct radeon_device *rdev);
+int r100_cp_reset(struct radeon_device *rdev);
+void r100_vga_render_disable(struct radeon_device *rdev);
+int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
+					 struct radeon_cs_packet *pkt,
+					 struct radeon_bo *robj);
+int r100_cs_parse_packet0(struct radeon_cs_parser *p,
+			  struct radeon_cs_packet *pkt,
+			  const unsigned *auth, unsigned n,
+			  radeon_packet0_check_t check);
+int r100_cs_packet_parse(struct radeon_cs_parser *p,
+			 struct radeon_cs_packet *pkt,
+			 unsigned idx);
+void r100_enable_bm(struct radeon_device *rdev);
+void r100_set_common_regs(struct radeon_device *rdev);
 
-static struct radeon_asic r100_asic = {
-	.init = &r100_init,
-	.fini = &r100_fini,
-	.suspend = &r100_suspend,
-	.resume = &r100_resume,
-	.vga_set_state = &r100_vga_set_state,
-	.gpu_reset = &r100_gpu_reset,
-	.gart_tlb_flush = &r100_pci_gart_tlb_flush,
-	.gart_set_page = &r100_pci_gart_set_page,
-	.cp_commit = &r100_cp_commit,
-	.ring_start = &r100_ring_start,
-	.ring_test = &r100_ring_test,
-	.ring_ib_execute = &r100_ring_ib_execute,
-	.irq_set = &r100_irq_set,
-	.irq_process = &r100_irq_process,
-	.get_vblank_counter = &r100_get_vblank_counter,
-	.fence_ring_emit = &r100_fence_ring_emit,
-	.cs_parse = &r100_cs_parse,
-	.copy_blit = &r100_copy_blit,
-	.copy_dma = NULL,
-	.copy = &r100_copy_blit,
-	.get_engine_clock = &radeon_legacy_get_engine_clock,
-	.set_engine_clock = &radeon_legacy_set_engine_clock,
-	.get_memory_clock = &radeon_legacy_get_memory_clock,
-	.set_memory_clock = NULL,
-	.set_pcie_lanes = NULL,
-	.set_clock_gating = &radeon_legacy_set_clock_gating,
-	.set_surface_reg = r100_set_surface_reg,
-	.clear_surface_reg = r100_clear_surface_reg,
-	.bandwidth_update = &r100_bandwidth_update,
-	.hpd_init = &r100_hpd_init,
-	.hpd_fini = &r100_hpd_fini,
-	.hpd_sense = &r100_hpd_sense,
-	.hpd_set_polarity = &r100_hpd_set_polarity,
-	.ioctl_wait_idle = NULL,
-};
-
+/*
+ * r200,rv250,rs300,rv280
+ */
+extern int r200_copy_dma(struct radeon_device *rdev,
+			uint64_t src_offset,
+			uint64_t dst_offset,
+			unsigned num_pages,
+			struct radeon_fence *fence);
 
 /*
  * r300,r350,rv350,rv380
@@ -138,47 +153,7 @@ extern int rv370_pcie_gart_set_page(stru
 extern uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg);
 extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes);
-extern int r300_copy_dma(struct radeon_device *rdev,
-			uint64_t src_offset,
-			uint64_t dst_offset,
-			unsigned num_pages,
-			struct radeon_fence *fence);
-static struct radeon_asic r300_asic = {
-	.init = &r300_init,
-	.fini = &r300_fini,
-	.suspend = &r300_suspend,
-	.resume = &r300_resume,
-	.vga_set_state = &r100_vga_set_state,
-	.gpu_reset = &r300_gpu_reset,
-	.gart_tlb_flush = &r100_pci_gart_tlb_flush,
-	.gart_set_page = &r100_pci_gart_set_page,
-	.cp_commit = &r100_cp_commit,
-	.ring_start = &r300_ring_start,
-	.ring_test = &r100_ring_test,
-	.ring_ib_execute = &r100_ring_ib_execute,
-	.irq_set = &r100_irq_set,
-	.irq_process = &r100_irq_process,
-	.get_vblank_counter = &r100_get_vblank_counter,
-	.fence_ring_emit = &r300_fence_ring_emit,
-	.cs_parse = &r300_cs_parse,
-	.copy_blit = &r100_copy_blit,
-	.copy_dma = &r300_copy_dma,
-	.copy = &r100_copy_blit,
-	.get_engine_clock = &radeon_legacy_get_engine_clock,
-	.set_engine_clock = &radeon_legacy_set_engine_clock,
-	.get_memory_clock = &radeon_legacy_get_memory_clock,
-	.set_memory_clock = NULL,
-	.set_pcie_lanes = &rv370_set_pcie_lanes,
-	.set_clock_gating = &radeon_legacy_set_clock_gating,
-	.set_surface_reg = r100_set_surface_reg,
-	.clear_surface_reg = r100_clear_surface_reg,
-	.bandwidth_update = &r100_bandwidth_update,
-	.hpd_init = &r100_hpd_init,
-	.hpd_fini = &r100_hpd_fini,
-	.hpd_sense = &r100_hpd_sense,
-	.hpd_set_polarity = &r100_hpd_set_polarity,
-	.ioctl_wait_idle = NULL,
-};
+extern int rv370_get_pcie_lanes(struct radeon_device *rdev);
 
 /*
  * r420,r423,rv410
@@ -187,43 +162,6 @@ extern int r420_init(struct radeon_devic
 extern void r420_fini(struct radeon_device *rdev);
 extern int r420_suspend(struct radeon_device *rdev);
 extern int r420_resume(struct radeon_device *rdev);
-static struct radeon_asic r420_asic = {
-	.init = &r420_init,
-	.fini = &r420_fini,
-	.suspend = &r420_suspend,
-	.resume = &r420_resume,
-	.vga_set_state = &r100_vga_set_state,
-	.gpu_reset = &r300_gpu_reset,
-	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
-	.gart_set_page = &rv370_pcie_gart_set_page,
-	.cp_commit = &r100_cp_commit,
-	.ring_start = &r300_ring_start,
-	.ring_test = &r100_ring_test,
-	.ring_ib_execute = &r100_ring_ib_execute,
-	.irq_set = &r100_irq_set,
-	.irq_process = &r100_irq_process,
-	.get_vblank_counter = &r100_get_vblank_counter,
-	.fence_ring_emit = &r300_fence_ring_emit,
-	.cs_parse = &r300_cs_parse,
-	.copy_blit = &r100_copy_blit,
-	.copy_dma = &r300_copy_dma,
-	.copy = &r100_copy_blit,
-	.get_engine_clock = &radeon_atom_get_engine_clock,
-	.set_engine_clock = &radeon_atom_set_engine_clock,
-	.get_memory_clock = &radeon_atom_get_memory_clock,
-	.set_memory_clock = &radeon_atom_set_memory_clock,
-	.set_pcie_lanes = &rv370_set_pcie_lanes,
-	.set_clock_gating = &radeon_atom_set_clock_gating,
-	.set_surface_reg = r100_set_surface_reg,
-	.clear_surface_reg = r100_clear_surface_reg,
-	.bandwidth_update = &r100_bandwidth_update,
-	.hpd_init = &r100_hpd_init,
-	.hpd_fini = &r100_hpd_fini,
-	.hpd_sense = &r100_hpd_sense,
-	.hpd_set_polarity = &r100_hpd_set_polarity,
-	.ioctl_wait_idle = NULL,
-};
-
 
 /*
  * rs400,rs480
@@ -236,43 +174,6 @@ void rs400_gart_tlb_flush(struct radeon_
 int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
 uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg);
 void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
-static struct radeon_asic rs400_asic = {
-	.init = &rs400_init,
-	.fini = &rs400_fini,
-	.suspend = &rs400_suspend,
-	.resume = &rs400_resume,
-	.vga_set_state = &r100_vga_set_state,
-	.gpu_reset = &r300_gpu_reset,
-	.gart_tlb_flush = &rs400_gart_tlb_flush,
-	.gart_set_page = &rs400_gart_set_page,
-	.cp_commit = &r100_cp_commit,
-	.ring_start = &r300_ring_start,
-	.ring_test = &r100_ring_test,
-	.ring_ib_execute = &r100_ring_ib_execute,
-	.irq_set = &r100_irq_set,
-	.irq_process = &r100_irq_process,
-	.get_vblank_counter = &r100_get_vblank_counter,
-	.fence_ring_emit = &r300_fence_ring_emit,
-	.cs_parse = &r300_cs_parse,
-	.copy_blit = &r100_copy_blit,
-	.copy_dma = &r300_copy_dma,
-	.copy = &r100_copy_blit,
-	.get_engine_clock = &radeon_legacy_get_engine_clock,
-	.set_engine_clock = &radeon_legacy_set_engine_clock,
-	.get_memory_clock = &radeon_legacy_get_memory_clock,
-	.set_memory_clock = NULL,
-	.set_pcie_lanes = NULL,
-	.set_clock_gating = &radeon_legacy_set_clock_gating,
-	.set_surface_reg = r100_set_surface_reg,
-	.clear_surface_reg = r100_clear_surface_reg,
-	.bandwidth_update = &r100_bandwidth_update,
-	.hpd_init = &r100_hpd_init,
-	.hpd_fini = &r100_hpd_fini,
-	.hpd_sense = &r100_hpd_sense,
-	.hpd_set_polarity = &r100_hpd_set_polarity,
-	.ioctl_wait_idle = NULL,
-};
-
 
 /*
  * rs600.
@@ -295,42 +196,6 @@ bool rs600_hpd_sense(struct radeon_devic
 void rs600_hpd_set_polarity(struct radeon_device *rdev,
 			    enum radeon_hpd_id hpd);
 
-static struct radeon_asic rs600_asic = {
-	.init = &rs600_init,
-	.fini = &rs600_fini,
-	.suspend = &rs600_suspend,
-	.resume = &rs600_resume,
-	.vga_set_state = &r100_vga_set_state,
-	.gpu_reset = &r300_gpu_reset,
-	.gart_tlb_flush = &rs600_gart_tlb_flush,
-	.gart_set_page = &rs600_gart_set_page,
-	.cp_commit = &r100_cp_commit,
-	.ring_start = &r300_ring_start,
-	.ring_test = &r100_ring_test,
-	.ring_ib_execute = &r100_ring_ib_execute,
-	.irq_set = &rs600_irq_set,
-	.irq_process = &rs600_irq_process,
-	.get_vblank_counter = &rs600_get_vblank_counter,
-	.fence_ring_emit = &r300_fence_ring_emit,
-	.cs_parse = &r300_cs_parse,
-	.copy_blit = &r100_copy_blit,
-	.copy_dma = &r300_copy_dma,
-	.copy = &r100_copy_blit,
-	.get_engine_clock = &radeon_atom_get_engine_clock,
-	.set_engine_clock = &radeon_atom_set_engine_clock,
-	.get_memory_clock = &radeon_atom_get_memory_clock,
-	.set_memory_clock = &radeon_atom_set_memory_clock,
-	.set_pcie_lanes = NULL,
-	.set_clock_gating = &radeon_atom_set_clock_gating,
-	.bandwidth_update = &rs600_bandwidth_update,
-	.hpd_init = &rs600_hpd_init,
-	.hpd_fini = &rs600_hpd_fini,
-	.hpd_sense = &rs600_hpd_sense,
-	.hpd_set_polarity = &rs600_hpd_set_polarity,
-	.ioctl_wait_idle = NULL,
-};
-
-
 /*
  * rs690,rs740
  */
@@ -341,43 +206,6 @@ int rs690_suspend(struct radeon_device *
 uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg);
 void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 void rs690_bandwidth_update(struct radeon_device *rdev);
-static struct radeon_asic rs690_asic = {
-	.init = &rs690_init,
-	.fini = &rs690_fini,
-	.suspend = &rs690_suspend,
-	.resume = &rs690_resume,
-	.vga_set_state = &r100_vga_set_state,
-	.gpu_reset = &r300_gpu_reset,
-	.gart_tlb_flush = &rs400_gart_tlb_flush,
-	.gart_set_page = &rs400_gart_set_page,
-	.cp_commit = &r100_cp_commit,
-	.ring_start = &r300_ring_start,
-	.ring_test = &r100_ring_test,
-	.ring_ib_execute = &r100_ring_ib_execute,
-	.irq_set = &rs600_irq_set,
-	.irq_process = &rs600_irq_process,
-	.get_vblank_counter = &rs600_get_vblank_counter,
-	.fence_ring_emit = &r300_fence_ring_emit,
-	.cs_parse = &r300_cs_parse,
-	.copy_blit = &r100_copy_blit,
-	.copy_dma = &r300_copy_dma,
-	.copy = &r300_copy_dma,
-	.get_engine_clock = &radeon_atom_get_engine_clock,
-	.set_engine_clock = &radeon_atom_set_engine_clock,
-	.get_memory_clock = &radeon_atom_get_memory_clock,
-	.set_memory_clock = &radeon_atom_set_memory_clock,
-	.set_pcie_lanes = NULL,
-	.set_clock_gating = &radeon_atom_set_clock_gating,
-	.set_surface_reg = r100_set_surface_reg,
-	.clear_surface_reg = r100_clear_surface_reg,
-	.bandwidth_update = &rs690_bandwidth_update,
-	.hpd_init = &rs600_hpd_init,
-	.hpd_fini = &rs600_hpd_fini,
-	.hpd_sense = &rs600_hpd_sense,
-	.hpd_set_polarity = &rs600_hpd_set_polarity,
-	.ioctl_wait_idle = NULL,
-};
-
 
 /*
  * rv515
@@ -393,85 +221,12 @@ void rv515_pcie_wreg(struct radeon_devic
 void rv515_bandwidth_update(struct radeon_device *rdev);
 int rv515_resume(struct radeon_device *rdev);
 int rv515_suspend(struct radeon_device *rdev);
-static struct radeon_asic rv515_asic = {
-	.init = &rv515_init,
-	.fini = &rv515_fini,
-	.suspend = &rv515_suspend,
-	.resume = &rv515_resume,
-	.vga_set_state = &r100_vga_set_state,
-	.gpu_reset = &rv515_gpu_reset,
-	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
-	.gart_set_page = &rv370_pcie_gart_set_page,
-	.cp_commit = &r100_cp_commit,
-	.ring_start = &rv515_ring_start,
-	.ring_test = &r100_ring_test,
-	.ring_ib_execute = &r100_ring_ib_execute,
-	.irq_set = &rs600_irq_set,
-	.irq_process = &rs600_irq_process,
-	.get_vblank_counter = &rs600_get_vblank_counter,
-	.fence_ring_emit = &r300_fence_ring_emit,
-	.cs_parse = &r300_cs_parse,
-	.copy_blit = &r100_copy_blit,
-	.copy_dma = &r300_copy_dma,
-	.copy = &r100_copy_blit,
-	.get_engine_clock = &radeon_atom_get_engine_clock,
-	.set_engine_clock = &radeon_atom_set_engine_clock,
-	.get_memory_clock = &radeon_atom_get_memory_clock,
-	.set_memory_clock = &radeon_atom_set_memory_clock,
-	.set_pcie_lanes = &rv370_set_pcie_lanes,
-	.set_clock_gating = &radeon_atom_set_clock_gating,
-	.set_surface_reg = r100_set_surface_reg,
-	.clear_surface_reg = r100_clear_surface_reg,
-	.bandwidth_update = &rv515_bandwidth_update,
-	.hpd_init = &rs600_hpd_init,
-	.hpd_fini = &rs600_hpd_fini,
-	.hpd_sense = &rs600_hpd_sense,
-	.hpd_set_polarity = &rs600_hpd_set_polarity,
-	.ioctl_wait_idle = NULL,
-};
-
 
 /*
  * r520,rv530,rv560,rv570,r580
  */
 int r520_init(struct radeon_device *rdev);
 int r520_resume(struct radeon_device *rdev);
-static struct radeon_asic r520_asic = {
-	.init = &r520_init,
-	.fini = &rv515_fini,
-	.suspend = &rv515_suspend,
-	.resume = &r520_resume,
-	.vga_set_state = &r100_vga_set_state,
-	.gpu_reset = &rv515_gpu_reset,
-	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
-	.gart_set_page = &rv370_pcie_gart_set_page,
-	.cp_commit = &r100_cp_commit,
-	.ring_start = &rv515_ring_start,
-	.ring_test = &r100_ring_test,
-	.ring_ib_execute = &r100_ring_ib_execute,
-	.irq_set = &rs600_irq_set,
-	.irq_process = &rs600_irq_process,
-	.get_vblank_counter = &rs600_get_vblank_counter,
-	.fence_ring_emit = &r300_fence_ring_emit,
-	.cs_parse = &r300_cs_parse,
-	.copy_blit = &r100_copy_blit,
-	.copy_dma = &r300_copy_dma,
-	.copy = &r100_copy_blit,
-	.get_engine_clock = &radeon_atom_get_engine_clock,
-	.set_engine_clock = &radeon_atom_set_engine_clock,
-	.get_memory_clock = &radeon_atom_get_memory_clock,
-	.set_memory_clock = &radeon_atom_set_memory_clock,
-	.set_pcie_lanes = &rv370_set_pcie_lanes,
-	.set_clock_gating = &radeon_atom_set_clock_gating,
-	.set_surface_reg = r100_set_surface_reg,
-	.clear_surface_reg = r100_clear_surface_reg,
-	.bandwidth_update = &rv515_bandwidth_update,
-	.hpd_init = &rs600_hpd_init,
-	.hpd_fini = &rs600_hpd_fini,
-	.hpd_sense = &rs600_hpd_sense,
-	.hpd_set_polarity = &rs600_hpd_set_polarity,
-	.ioctl_wait_idle = NULL,
-};
 
 /*
  * r600,rv610,rv630,rv620,rv635,rv670,rs780,rs880
@@ -501,7 +256,7 @@ int r600_gpu_reset(struct radeon_device
 int r600_set_surface_reg(struct radeon_device *rdev, int reg,
 			 uint32_t tiling_flags, uint32_t pitch,
 			 uint32_t offset, uint32_t obj_size);
-int r600_clear_surface_reg(struct radeon_device *rdev, int reg);
+void r600_clear_surface_reg(struct radeon_device *rdev, int reg);
 void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
 int r600_ring_test(struct radeon_device *rdev);
 int r600_copy_blit(struct radeon_device *rdev,
@@ -514,42 +269,6 @@ void r600_hpd_set_polarity(struct radeon
 			   enum radeon_hpd_id hpd);
 extern void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo);
 
-static struct radeon_asic r600_asic = {
-	.init = &r600_init,
-	.fini = &r600_fini,
-	.suspend = &r600_suspend,
-	.resume = &r600_resume,
-	.cp_commit = &r600_cp_commit,
-	.vga_set_state = &r600_vga_set_state,
-	.gpu_reset = &r600_gpu_reset,
-	.gart_tlb_flush = &r600_pcie_gart_tlb_flush,
-	.gart_set_page = &rs600_gart_set_page,
-	.ring_test = &r600_ring_test,
-	.ring_ib_execute = &r600_ring_ib_execute,
-	.irq_set = &r600_irq_set,
-	.irq_process = &r600_irq_process,
-	.get_vblank_counter = &rs600_get_vblank_counter,
-	.fence_ring_emit = &r600_fence_ring_emit,
-	.cs_parse = &r600_cs_parse,
-	.copy_blit = &r600_copy_blit,
-	.copy_dma = &r600_copy_blit,
-	.copy = &r600_copy_blit,
-	.get_engine_clock = &radeon_atom_get_engine_clock,
-	.set_engine_clock = &radeon_atom_set_engine_clock,
-	.get_memory_clock = &radeon_atom_get_memory_clock,
-	.set_memory_clock = &radeon_atom_set_memory_clock,
-	.set_pcie_lanes = NULL,
-	.set_clock_gating = &radeon_atom_set_clock_gating,
-	.set_surface_reg = r600_set_surface_reg,
-	.clear_surface_reg = r600_clear_surface_reg,
-	.bandwidth_update = &rv515_bandwidth_update,
-	.hpd_init = &r600_hpd_init,
-	.hpd_fini = &r600_hpd_fini,
-	.hpd_sense = &r600_hpd_sense,
-	.hpd_set_polarity = &r600_hpd_set_polarity,
-	.ioctl_wait_idle = r600_ioctl_wait_idle,
-};
-
 /*
  * rv770,rv730,rv710,rv740
  */
@@ -559,40 +278,18 @@ int rv770_suspend(struct radeon_device *
 int rv770_resume(struct radeon_device *rdev);
 int rv770_gpu_reset(struct radeon_device *rdev);
 
-static struct radeon_asic rv770_asic = {
-	.init = &rv770_init,
-	.fini = &rv770_fini,
-	.suspend = &rv770_suspend,
-	.resume = &rv770_resume,
-	.cp_commit = &r600_cp_commit,
-	.gpu_reset = &rv770_gpu_reset,
-	.vga_set_state = &r600_vga_set_state,
-	.gart_tlb_flush = &r600_pcie_gart_tlb_flush,
-	.gart_set_page = &rs600_gart_set_page,
-	.ring_test = &r600_ring_test,
-	.ring_ib_execute = &r600_ring_ib_execute,
-	.irq_set = &r600_irq_set,
-	.irq_process = &r600_irq_process,
-	.get_vblank_counter = &rs600_get_vblank_counter,
-	.fence_ring_emit = &r600_fence_ring_emit,
-	.cs_parse = &r600_cs_parse,
-	.copy_blit = &r600_copy_blit,
-	.copy_dma = &r600_copy_blit,
-	.copy = &r600_copy_blit,
-	.get_engine_clock = &radeon_atom_get_engine_clock,
-	.set_engine_clock = &radeon_atom_set_engine_clock,
-	.get_memory_clock = &radeon_atom_get_memory_clock,
-	.set_memory_clock = &radeon_atom_set_memory_clock,
-	.set_pcie_lanes = NULL,
-	.set_clock_gating = &radeon_atom_set_clock_gating,
-	.set_surface_reg = r600_set_surface_reg,
-	.clear_surface_reg = r600_clear_surface_reg,
-	.bandwidth_update = &rv515_bandwidth_update,
-	.hpd_init = &r600_hpd_init,
-	.hpd_fini = &r600_hpd_fini,
-	.hpd_sense = &r600_hpd_sense,
-	.hpd_set_polarity = &r600_hpd_set_polarity,
-	.ioctl_wait_idle = r600_ioctl_wait_idle,
-};
-
+/*
+ * evergreen
+ */
+int evergreen_init(struct radeon_device *rdev);
+void evergreen_fini(struct radeon_device *rdev);
+int evergreen_suspend(struct radeon_device *rdev);
+int evergreen_resume(struct radeon_device *rdev);
+int evergreen_gpu_reset(struct radeon_device *rdev);
+void evergreen_bandwidth_update(struct radeon_device *rdev);
+void evergreen_hpd_init(struct radeon_device *rdev);
+void evergreen_hpd_fini(struct radeon_device *rdev);
+bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
+void evergreen_hpd_set_polarity(struct radeon_device *rdev,
+				enum radeon_hpd_id hpd);
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_atombios.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_atombios.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_atombios.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_atombios.c	2010-05-16 17:17:36.000000000 -0400
@@ -69,52 +69,54 @@ static inline struct radeon_i2c_bus_rec
 	struct radeon_i2c_bus_rec i2c;
 	int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
 	struct _ATOM_GPIO_I2C_INFO *i2c_info;
-	uint16_t data_offset;
-	int i;
+	uint16_t data_offset, size;
+	int i, num_indices;
 
 	memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
 	i2c.valid = false;
 
-	atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset);
-
-	i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
+	if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
+		i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
 
+		num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
+			sizeof(ATOM_GPIO_I2C_ASSIGMENT);
 
-	for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
-		gpio = &i2c_info->asGPIO_Info[i];
+		for (i = 0; i < num_indices; i++) {
+			gpio = &i2c_info->asGPIO_Info[i];
 
-		if (gpio->sucI2cId.ucAccess == id) {
-			i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
-			i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
-			i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
-			i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
-			i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
-			i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
-			i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
-			i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
-			i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
-			i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
-			i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
-			i2c.en_data_mask = (1 << gpio->ucDataEnShift);
-			i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
-			i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
-			i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
-			i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
+			if (gpio->sucI2cId.ucAccess == id) {
+				i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
+				i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
+				i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
+				i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
+				i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
+				i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
+				i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
+				i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
+				i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
+				i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
+				i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
+				i2c.en_data_mask = (1 << gpio->ucDataEnShift);
+				i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
+				i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
+				i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
+				i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
 
-			if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
-				i2c.hw_capable = true;
-			else
-				i2c.hw_capable = false;
+				if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
+					i2c.hw_capable = true;
+				else
+					i2c.hw_capable = false;
 
-			if (gpio->sucI2cId.ucAccess == 0xa0)
-				i2c.mm_i2c = true;
-			else
-				i2c.mm_i2c = false;
+				if (gpio->sucI2cId.ucAccess == 0xa0)
+					i2c.mm_i2c = true;
+				else
+					i2c.mm_i2c = false;
 
-			i2c.i2c_id = gpio->sucI2cId.ucAccess;
+				i2c.i2c_id = gpio->sucI2cId.ucAccess;
 
-			i2c.valid = true;
-			break;
+				i2c.valid = true;
+				break;
+			}
 		}
 	}
 
@@ -135,20 +137,21 @@ static inline struct radeon_gpio_rec rad
 	memset(&gpio, 0, sizeof(struct radeon_gpio_rec));
 	gpio.valid = false;
 
-	atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset);
-
-	gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
+	if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
+		gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
 
-	num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
+		num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
+			sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
 
-	for (i = 0; i < num_indices; i++) {
-		pin = &gpio_info->asGPIO_Pin[i];
-		if (id == pin->ucGPIO_ID) {
-			gpio.id = pin->ucGPIO_ID;
-			gpio.reg = pin->usGpioPin_AIndex * 4;
-			gpio.mask = (1 << pin->ucGpioPinBitShift);
-			gpio.valid = true;
-			break;
+		for (i = 0; i < num_indices; i++) {
+			pin = &gpio_info->asGPIO_Pin[i];
+			if (id == pin->ucGPIO_ID) {
+				gpio.id = pin->ucGPIO_ID;
+				gpio.reg = pin->usGpioPin_AIndex * 4;
+				gpio.mask = (1 << pin->ucGpioPinBitShift);
+				gpio.valid = true;
+				break;
+			}
 		}
 	}
 
@@ -159,8 +162,15 @@ static struct radeon_hpd radeon_atom_get
 							    struct radeon_gpio_rec *gpio)
 {
 	struct radeon_hpd hpd;
+	u32 reg;
+
+	if (ASIC_IS_DCE4(rdev))
+		reg = EVERGREEN_DC_GPIO_HPD_A;
+	else
+		reg = AVIVO_DC_GPIO_HPD_A;
+
 	hpd.gpio = *gpio;
-	if (gpio->reg == AVIVO_DC_GPIO_HPD_A) {
+	if (gpio->reg == reg) {
 		switch(gpio->mask) {
 		case (1 << 0):
 			hpd.hpd = RADEON_HPD_1;
@@ -257,6 +267,8 @@ static bool radeon_atom_apply_quirks(str
 		if ((supported_device == ATOM_DEVICE_CRT1_SUPPORT) ||
 		    (supported_device == ATOM_DEVICE_DFP2_SUPPORT))
 			return false;
+		if (supported_device == ATOM_DEVICE_CRT2_SUPPORT)
+			*line_mux = 0x90;
 	}
 
 	/* ASUS HD 3600 XT board lists the DVI port as HDMI */
@@ -388,9 +400,7 @@ bool radeon_get_atom_connector_info_from
 	struct radeon_gpio_rec gpio;
 	struct radeon_hpd hpd;
 
-	atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
-
-	if (data_offset == 0)
+	if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
 		return false;
 
 	if (crev < 2)
@@ -442,37 +452,43 @@ bool radeon_get_atom_connector_info_from
 				    GetIndexIntoMasterTable(DATA,
 							    IntegratedSystemInfo);
 
-				atom_parse_data_header(ctx, index, &size, &frev,
-						       &crev, &igp_offset);
+				if (atom_parse_data_header(ctx, index, &size, &frev,
+							   &crev, &igp_offset)) {
 
-				if (crev >= 2) {
-					igp_obj =
-					    (ATOM_INTEGRATED_SYSTEM_INFO_V2
-					     *) (ctx->bios + igp_offset);
+					if (crev >= 2) {
+						igp_obj =
+							(ATOM_INTEGRATED_SYSTEM_INFO_V2
+							 *) (ctx->bios + igp_offset);
 
-					if (igp_obj) {
-						uint32_t slot_config, ct;
+						if (igp_obj) {
+							uint32_t slot_config, ct;
 
-						if (con_obj_num == 1)
-							slot_config =
-							    igp_obj->
-							    ulDDISlot1Config;
-						else
-							slot_config =
-							    igp_obj->
-							    ulDDISlot2Config;
+							if (con_obj_num == 1)
+								slot_config =
+									igp_obj->
+									ulDDISlot1Config;
+							else
+								slot_config =
+									igp_obj->
+									ulDDISlot2Config;
 
-						ct = (slot_config >> 16) & 0xff;
-						connector_type =
-						    object_connector_convert
-						    [ct];
-						connector_object_id = ct;
-						igp_lane_info =
-						    slot_config & 0xffff;
+							ct = (slot_config >> 16) & 0xff;
+							connector_type =
+								object_connector_convert
+								[ct];
+							connector_object_id = ct;
+							igp_lane_info =
+								slot_config & 0xffff;
+						} else
+							continue;
 					} else
 						continue;
-				} else
-					continue;
+				} else {
+					igp_lane_info = 0;
+					connector_type =
+						object_connector_convert[con_obj_id];
+					connector_object_id = con_obj_id;
+				}
 			} else {
 				igp_lane_info = 0;
 				connector_type =
@@ -574,6 +590,9 @@ bool radeon_get_atom_connector_info_from
 				ddc_bus.valid = false;
 			}
 
+			/* needed for aux chan transactions */
+			ddc_bus.hpd_id = hpd.hpd ? (hpd.hpd - 1) : 0;
+
 			conn_id = le16_to_cpu(path->usConnObjectId);
 
 			if (!radeon_atom_apply_quirks
@@ -617,20 +636,23 @@ static uint16_t atombios_get_connector_o
 		uint8_t frev, crev;
 		ATOM_XTMDS_INFO *xtmds;
 
-		atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
-		xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset);
+		if (atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) {
+			xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset);
 
-		if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) {
-			if (connector_type == DRM_MODE_CONNECTOR_DVII)
-				return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
-			else
-				return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
-		} else {
-			if (connector_type == DRM_MODE_CONNECTOR_DVII)
-				return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
-			else
-				return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
-		}
+			if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) {
+				if (connector_type == DRM_MODE_CONNECTOR_DVII)
+					return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
+				else
+					return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
+			} else {
+				if (connector_type == DRM_MODE_CONNECTOR_DVII)
+					return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
+				else
+					return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
+			}
+		} else
+			return supported_devices_connector_object_id_convert
+				[connector_type];
 	} else {
 		return supported_devices_connector_object_id_convert
 			[connector_type];
@@ -662,7 +684,8 @@ bool radeon_get_atom_connector_info_from
 	int i, j, max_device;
 	struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE];
 
-	atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
+	if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
+		return false;
 
 	supported_devices =
 	    (union atom_supported_devices *)(ctx->bios + data_offset);
@@ -838,6 +861,7 @@ union firmware_info {
 	ATOM_FIRMWARE_INFO_V1_2 info_12;
 	ATOM_FIRMWARE_INFO_V1_3 info_13;
 	ATOM_FIRMWARE_INFO_V1_4 info_14;
+	ATOM_FIRMWARE_INFO_V2_1 info_21;
 };
 
 bool radeon_atom_get_clock_info(struct drm_device *dev)
@@ -849,18 +873,16 @@ bool radeon_atom_get_clock_info(struct d
 	uint8_t frev, crev;
 	struct radeon_pll *p1pll = &rdev->clock.p1pll;
 	struct radeon_pll *p2pll = &rdev->clock.p2pll;
+	struct radeon_pll *dcpll = &rdev->clock.dcpll;
 	struct radeon_pll *spll = &rdev->clock.spll;
 	struct radeon_pll *mpll = &rdev->clock.mpll;
 	uint16_t data_offset;
 
-	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
-			       &crev, &data_offset);
-
-	firmware_info =
-	    (union firmware_info *)(mode_info->atom_context->bios +
-				    data_offset);
-
-	if (firmware_info) {
+	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset)) {
+		firmware_info =
+			(union firmware_info *)(mode_info->atom_context->bios +
+						data_offset);
 		/* pixel clocks */
 		p1pll->reference_freq =
 		    le16_to_cpu(firmware_info->info.usReferenceClock);
@@ -875,6 +897,20 @@ bool radeon_atom_get_clock_info(struct d
 		p1pll->pll_out_max =
 		    le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
 
+		if (crev >= 4) {
+			p1pll->lcd_pll_out_min =
+				le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100;
+			if (p1pll->lcd_pll_out_min == 0)
+				p1pll->lcd_pll_out_min = p1pll->pll_out_min;
+			p1pll->lcd_pll_out_max =
+				le16_to_cpu(firmware_info->info_14.usLcdMaxPixelClockPLL_Output) * 100;
+			if (p1pll->lcd_pll_out_max == 0)
+				p1pll->lcd_pll_out_max = p1pll->pll_out_max;
+		} else {
+			p1pll->lcd_pll_out_min = p1pll->pll_out_min;
+			p1pll->lcd_pll_out_max = p1pll->pll_out_max;
+		}
+
 		if (p1pll->pll_out_min == 0) {
 			if (ASIC_IS_AVIVO(rdev))
 				p1pll->pll_out_min = 64800;
@@ -951,8 +987,19 @@ bool radeon_atom_get_clock_info(struct d
 		rdev->clock.default_mclk =
 		    le32_to_cpu(firmware_info->info.ulDefaultMemoryClock);
 
+		if (ASIC_IS_DCE4(rdev)) {
+			rdev->clock.default_dispclk =
+				le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq);
+			if (rdev->clock.default_dispclk == 0)
+				rdev->clock.default_dispclk = 60000; /* 600 Mhz */
+			rdev->clock.dp_extclk =
+				le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);
+		}
+		*dcpll = *p1pll;
+
 		return true;
 	}
+
 	return false;
 }
 
@@ -969,13 +1016,10 @@ bool radeon_atombios_sideport_present(st
 	u8 frev, crev;
 	u16 data_offset;
 
-	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
-			       &crev, &data_offset);
-
-	igp_info = (union igp_info *)(mode_info->atom_context->bios +
+	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset)) {
+		igp_info = (union igp_info *)(mode_info->atom_context->bios +
 				      data_offset);
-
-	if (igp_info) {
 		switch (crev) {
 		case 1:
 			if (igp_info->info.ucMemoryType & 0xf0)
@@ -1006,14 +1050,12 @@ bool radeon_atombios_get_tmds_info(struc
 	uint16_t maxfreq;
 	int i;
 
-	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
-			       &crev, &data_offset);
-
-	tmds_info =
-	    (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios +
-				       data_offset);
+	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset)) {
+		tmds_info =
+			(struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios +
+						   data_offset);
 
-	if (tmds_info) {
 		maxfreq = le16_to_cpu(tmds_info->usMaxFrequency);
 		for (i = 0; i < 4; i++) {
 			tmds->tmds_pll[i].freq =
@@ -1062,13 +1104,11 @@ static struct radeon_atom_ss *radeon_ato
 	if (id > ATOM_MAX_SS_ENTRY)
 		return NULL;
 
-	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
-			       &crev, &data_offset);
-
-	ss_info =
-	    (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset);
+	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset)) {
+		ss_info =
+			(struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset);
 
-	if (ss_info) {
 		ss =
 		    kzalloc(sizeof(struct radeon_atom_ss), GFP_KERNEL);
 
@@ -1109,13 +1149,10 @@ struct radeon_encoder_atom_dig *radeon_a
 	uint8_t frev, crev;
 	struct radeon_encoder_atom_dig *lvds = NULL;
 
-	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
-			       &crev, &data_offset);
-
-	lvds_info =
-	    (union lvds_info *)(mode_info->atom_context->bios + data_offset);
-
-	if (lvds_info) {
+	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset)) {
+		lvds_info =
+			(union lvds_info *)(mode_info->atom_context->bios + data_offset);
 		lvds =
 		    kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL);
 
@@ -1161,6 +1198,18 @@ struct radeon_encoder_atom_dig *radeon_a
 
 		lvds->ss = radeon_atombios_get_ss_info(encoder, lvds_info->info.ucSS_Id);
 
+		if (ASIC_IS_AVIVO(rdev)) {
+			if (radeon_new_pll == 0)
+				lvds->pll_algo = PLL_ALGO_LEGACY;
+			else
+				lvds->pll_algo = PLL_ALGO_NEW;
+		} else {
+			if (radeon_new_pll == 1)
+				lvds->pll_algo = PLL_ALGO_NEW;
+			else
+				lvds->pll_algo = PLL_ALGO_LEGACY;
+		}
+
 		encoder->native_mode = lvds->native_mode;
 	}
 	return lvds;
@@ -1179,11 +1228,11 @@ radeon_atombios_get_primary_dac_info(str
 	uint8_t bg, dac;
 	struct radeon_encoder_primary_dac *p_dac = NULL;
 
-	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
-
-	dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset);
+	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset)) {
+		dac_info = (struct _COMPASSIONATE_DATA *)
+			(mode_info->atom_context->bios + data_offset);
 
-	if (dac_info) {
 		p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL);
 
 		if (!p_dac)
@@ -1208,12 +1257,14 @@ bool radeon_atom_get_tv_timings(struct r
 	u8 frev, crev;
 	u16 data_offset, misc;
 
-	atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset);
+	if (!atom_parse_data_header(mode_info->atom_context, data_index, NULL,
+				    &frev, &crev, &data_offset))
+		return false;
 
 	switch (crev) {
 	case 1:
 		tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);
-		if (index > MAX_SUPPORTED_TV_TIMING)
+		if (index >= MAX_SUPPORTED_TV_TIMING)
 			return false;
 
 		mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
@@ -1251,7 +1302,7 @@ bool radeon_atom_get_tv_timings(struct r
 		break;
 	case 2:
 		tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset);
-		if (index > MAX_SUPPORTED_TV_TIMING_V1_2)
+		if (index >= MAX_SUPPORTED_TV_TIMING_V1_2)
 			return false;
 
 		dtd_timings = &tv_info_v1_2->aModeTimings[index];
@@ -1300,47 +1351,50 @@ radeon_atombios_get_tv_info(struct radeo
 	struct _ATOM_ANALOG_TV_INFO *tv_info;
 	enum radeon_tv_std tv_std = TV_STD_NTSC;
 
-	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
+	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset)) {
 
-	tv_info = (struct _ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);
+		tv_info = (struct _ATOM_ANALOG_TV_INFO *)
+			(mode_info->atom_context->bios + data_offset);
 
-	switch (tv_info->ucTV_BootUpDefaultStandard) {
-	case ATOM_TV_NTSC:
-		tv_std = TV_STD_NTSC;
-		DRM_INFO("Default TV standard: NTSC\n");
-		break;
-	case ATOM_TV_NTSCJ:
-		tv_std = TV_STD_NTSC_J;
-		DRM_INFO("Default TV standard: NTSC-J\n");
-		break;
-	case ATOM_TV_PAL:
-		tv_std = TV_STD_PAL;
-		DRM_INFO("Default TV standard: PAL\n");
-		break;
-	case ATOM_TV_PALM:
-		tv_std = TV_STD_PAL_M;
-		DRM_INFO("Default TV standard: PAL-M\n");
-		break;
-	case ATOM_TV_PALN:
-		tv_std = TV_STD_PAL_N;
-		DRM_INFO("Default TV standard: PAL-N\n");
-		break;
-	case ATOM_TV_PALCN:
-		tv_std = TV_STD_PAL_CN;
-		DRM_INFO("Default TV standard: PAL-CN\n");
-		break;
-	case ATOM_TV_PAL60:
-		tv_std = TV_STD_PAL_60;
-		DRM_INFO("Default TV standard: PAL-60\n");
-		break;
-	case ATOM_TV_SECAM:
-		tv_std = TV_STD_SECAM;
-		DRM_INFO("Default TV standard: SECAM\n");
-		break;
-	default:
-		tv_std = TV_STD_NTSC;
-		DRM_INFO("Unknown TV standard; defaulting to NTSC\n");
-		break;
+		switch (tv_info->ucTV_BootUpDefaultStandard) {
+		case ATOM_TV_NTSC:
+			tv_std = TV_STD_NTSC;
+			DRM_INFO("Default TV standard: NTSC\n");
+			break;
+		case ATOM_TV_NTSCJ:
+			tv_std = TV_STD_NTSC_J;
+			DRM_INFO("Default TV standard: NTSC-J\n");
+			break;
+		case ATOM_TV_PAL:
+			tv_std = TV_STD_PAL;
+			DRM_INFO("Default TV standard: PAL\n");
+			break;
+		case ATOM_TV_PALM:
+			tv_std = TV_STD_PAL_M;
+			DRM_INFO("Default TV standard: PAL-M\n");
+			break;
+		case ATOM_TV_PALN:
+			tv_std = TV_STD_PAL_N;
+			DRM_INFO("Default TV standard: PAL-N\n");
+			break;
+		case ATOM_TV_PALCN:
+			tv_std = TV_STD_PAL_CN;
+			DRM_INFO("Default TV standard: PAL-CN\n");
+			break;
+		case ATOM_TV_PAL60:
+			tv_std = TV_STD_PAL_60;
+			DRM_INFO("Default TV standard: PAL-60\n");
+			break;
+		case ATOM_TV_SECAM:
+			tv_std = TV_STD_SECAM;
+			DRM_INFO("Default TV standard: SECAM\n");
+			break;
+		default:
+			tv_std = TV_STD_NTSC;
+			DRM_INFO("Unknown TV standard; defaulting to NTSC\n");
+			break;
+		}
 	}
 	return tv_std;
 }
@@ -1358,11 +1412,12 @@ radeon_atombios_get_tv_dac_info(struct r
 	uint8_t bg, dac;
 	struct radeon_encoder_tv_dac *tv_dac = NULL;
 
-	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
+	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset)) {
 
-	dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset);
+		dac_info = (struct _COMPASSIONATE_DATA *)
+			(mode_info->atom_context->bios + data_offset);
 
-	if (dac_info) {
 		tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL);
 
 		if (!tv_dac)
@@ -1385,20 +1440,424 @@ radeon_atombios_get_tv_dac_info(struct r
 	return tv_dac;
 }
 
-void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable)
+static const char *thermal_controller_names[] = {
+	"NONE",
+	"LM63",
+	"ADM1032",
+	"ADM1030",
+	"MUA6649",
+	"LM64",
+	"F75375",
+	"ASC7512",
+};
+
+static const char *pp_lib_thermal_controller_names[] = {
+	"NONE",
+	"LM63",
+	"ADM1032",
+	"ADM1030",
+	"MUA6649",
+	"LM64",
+	"F75375",
+	"RV6xx",
+	"RV770",
+	"ADT7473",
+};
+
+union power_info {
+	struct _ATOM_POWERPLAY_INFO info;
+	struct _ATOM_POWERPLAY_INFO_V2 info_2;
+	struct _ATOM_POWERPLAY_INFO_V3 info_3;
+	struct _ATOM_PPLIB_POWERPLAYTABLE info_4;
+};
+
+void radeon_atombios_get_power_modes(struct radeon_device *rdev)
 {
-	DYNAMIC_CLOCK_GATING_PS_ALLOCATION args;
-	int index = GetIndexIntoMasterTable(COMMAND, DynamicClockGating);
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
+	u16 data_offset;
+	u8 frev, crev;
+	u32 misc, misc2 = 0, sclk, mclk;
+	union power_info *power_info;
+	struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
+	struct _ATOM_PPLIB_STATE *power_state;
+	int num_modes = 0, i, j;
+	int state_index = 0, mode_index = 0;
+	struct radeon_i2c_bus_rec i2c_bus;
 
-	args.ucEnable = enable;
+	rdev->pm.default_power_state = NULL;
 
-	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset)) {
+		power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
+		if (frev < 4) {
+			/* add the i2c bus for thermal/fan chip */
+			if (power_info->info.ucOverdriveThermalController > 0) {
+				DRM_INFO("Possible %s thermal controller at 0x%02x\n",
+					 thermal_controller_names[power_info->info.ucOverdriveThermalController],
+					 power_info->info.ucOverdriveControllerAddress >> 1);
+				i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine);
+				rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal");
+			}
+			num_modes = power_info->info.ucNumOfPowerModeEntries;
+			if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK)
+				num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK;
+			for (i = 0; i < num_modes; i++) {
+				rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
+				switch (frev) {
+				case 1:
+					rdev->pm.power_state[state_index].num_clock_modes = 1;
+					rdev->pm.power_state[state_index].clock_info[0].mclk =
+						le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock);
+					rdev->pm.power_state[state_index].clock_info[0].sclk =
+						le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock);
+					/* skip invalid modes */
+					if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
+					    (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
+						continue;
+					/* skip overclock modes for now */
+					if ((rdev->pm.power_state[state_index].clock_info[0].mclk >
+					     rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) ||
+					    (rdev->pm.power_state[state_index].clock_info[0].sclk >
+					     rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN))
+						continue;
+					rdev->pm.power_state[state_index].non_clock_info.pcie_lanes =
+						power_info->info.asPowerPlayInfo[i].ucNumPciELanes;
+					misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo);
+					if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) {
+						rdev->pm.power_state[state_index].clock_info[0].voltage.type =
+							VOLTAGE_GPIO;
+						rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
+							radeon_lookup_gpio(rdev,
+							power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex);
+						if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)
+							rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
+								true;
+						else
+							rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
+								false;
+					} else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) {
+						rdev->pm.power_state[state_index].clock_info[0].voltage.type =
+							VOLTAGE_VDDC;
+						rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =
+							power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex;
+					}
+					/* order matters! */
+					if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_POWERSAVE;
+					if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_BATTERY;
+					if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_BATTERY;
+					if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_BALANCED;
+					if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_PERFORMANCE;
+					if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) {
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_DEFAULT;
+						rdev->pm.default_power_state = &rdev->pm.power_state[state_index];
+						rdev->pm.power_state[state_index].default_clock_mode =
+							&rdev->pm.power_state[state_index].clock_info[0];
+					}
+					state_index++;
+					break;
+				case 2:
+					rdev->pm.power_state[state_index].num_clock_modes = 1;
+					rdev->pm.power_state[state_index].clock_info[0].mclk =
+						le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock);
+					rdev->pm.power_state[state_index].clock_info[0].sclk =
+						le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock);
+					/* skip invalid modes */
+					if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
+					    (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
+						continue;
+					/* skip overclock modes for now */
+					if ((rdev->pm.power_state[state_index].clock_info[0].mclk >
+					     rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) ||
+					    (rdev->pm.power_state[state_index].clock_info[0].sclk >
+					     rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN))
+						continue;
+					rdev->pm.power_state[state_index].non_clock_info.pcie_lanes =
+						power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes;
+					misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo);
+					misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2);
+					if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) {
+						rdev->pm.power_state[state_index].clock_info[0].voltage.type =
+							VOLTAGE_GPIO;
+						rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
+							radeon_lookup_gpio(rdev,
+							power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex);
+						if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)
+							rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
+								true;
+						else
+							rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
+								false;
+					} else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) {
+						rdev->pm.power_state[state_index].clock_info[0].voltage.type =
+							VOLTAGE_VDDC;
+						rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =
+							power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex;
+					}
+					/* order matters! */
+					if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_POWERSAVE;
+					if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_BATTERY;
+					if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_BATTERY;
+					if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_BALANCED;
+					if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_PERFORMANCE;
+					if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_BALANCED;
+					if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) {
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_DEFAULT;
+						rdev->pm.default_power_state = &rdev->pm.power_state[state_index];
+						rdev->pm.power_state[state_index].default_clock_mode =
+							&rdev->pm.power_state[state_index].clock_info[0];
+					}
+					state_index++;
+					break;
+				case 3:
+					rdev->pm.power_state[state_index].num_clock_modes = 1;
+					rdev->pm.power_state[state_index].clock_info[0].mclk =
+						le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock);
+					rdev->pm.power_state[state_index].clock_info[0].sclk =
+						le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock);
+					/* skip invalid modes */
+					if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
+					    (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
+						continue;
+					/* skip overclock modes for now */
+					if ((rdev->pm.power_state[state_index].clock_info[0].mclk >
+					     rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) ||
+					    (rdev->pm.power_state[state_index].clock_info[0].sclk >
+					     rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN))
+						continue;
+					rdev->pm.power_state[state_index].non_clock_info.pcie_lanes =
+						power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes;
+					misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo);
+					misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2);
+					if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) {
+						rdev->pm.power_state[state_index].clock_info[0].voltage.type =
+							VOLTAGE_GPIO;
+						rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
+							radeon_lookup_gpio(rdev,
+							power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex);
+						if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)
+							rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
+								true;
+						else
+							rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
+								false;
+					} else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) {
+						rdev->pm.power_state[state_index].clock_info[0].voltage.type =
+							VOLTAGE_VDDC;
+						rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =
+							power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex;
+						if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) {
+							rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled =
+								true;
+							rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id =
+							power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex;
+						}
+					}
+					/* order matters! */
+					if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_POWERSAVE;
+					if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_BATTERY;
+					if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_BATTERY;
+					if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_BALANCED;
+					if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_PERFORMANCE;
+					if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE)
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_BALANCED;
+					if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) {
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_DEFAULT;
+						rdev->pm.default_power_state = &rdev->pm.power_state[state_index];
+						rdev->pm.power_state[state_index].default_clock_mode =
+							&rdev->pm.power_state[state_index].clock_info[0];
+					}
+					state_index++;
+					break;
+				}
+			}
+		} else if (frev == 4) {
+			/* add the i2c bus for thermal/fan chip */
+			/* no support for internal controller yet */
+			if (power_info->info_4.sThermalController.ucType > 0) {
+				if ((power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) ||
+				    (power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_RV770)) {
+					DRM_INFO("Internal thermal controller %s fan control\n",
+						 (power_info->info_4.sThermalController.ucFanParameters &
+						  ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
+				} else {
+					DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n",
+						 pp_lib_thermal_controller_names[power_info->info_4.sThermalController.ucType],
+						 power_info->info_4.sThermalController.ucI2cAddress >> 1,
+						 (power_info->info_4.sThermalController.ucFanParameters &
+						  ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
+					i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info_4.sThermalController.ucI2cLine);
+					rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal");
+				}
+			}
+			for (i = 0; i < power_info->info_4.ucNumStates; i++) {
+				mode_index = 0;
+				power_state = (struct _ATOM_PPLIB_STATE *)
+					(mode_info->atom_context->bios +
+					 data_offset +
+					 le16_to_cpu(power_info->info_4.usStateArrayOffset) +
+					 i * power_info->info_4.ucStateEntrySize);
+				non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
+					(mode_info->atom_context->bios +
+					 data_offset +
+					 le16_to_cpu(power_info->info_4.usNonClockInfoArrayOffset) +
+					 (power_state->ucNonClockStateIndex *
+					  power_info->info_4.ucNonClockSize));
+				for (j = 0; j < (power_info->info_4.ucStateEntrySize - 1); j++) {
+					if (rdev->flags & RADEON_IS_IGP) {
+						struct _ATOM_PPLIB_RS780_CLOCK_INFO *clock_info =
+							(struct _ATOM_PPLIB_RS780_CLOCK_INFO *)
+							(mode_info->atom_context->bios +
+							 data_offset +
+							 le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) +
+							 (power_state->ucClockStateIndices[j] *
+							  power_info->info_4.ucClockInfoSize));
+						sclk = le16_to_cpu(clock_info->usLowEngineClockLow);
+						sclk |= clock_info->ucLowEngineClockHigh << 16;
+						rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
+						/* skip invalid modes */
+						if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)
+							continue;
+						/* skip overclock modes for now */
+						if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk >
+						    rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)
+							continue;
+						rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
+							VOLTAGE_SW;
+						rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
+							clock_info->usVDDC;
+						mode_index++;
+					} else {
+						struct _ATOM_PPLIB_R600_CLOCK_INFO *clock_info =
+							(struct _ATOM_PPLIB_R600_CLOCK_INFO *)
+							(mode_info->atom_context->bios +
+							 data_offset +
+							 le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) +
+							 (power_state->ucClockStateIndices[j] *
+							  power_info->info_4.ucClockInfoSize));
+						sclk = le16_to_cpu(clock_info->usEngineClockLow);
+						sclk |= clock_info->ucEngineClockHigh << 16;
+						mclk = le16_to_cpu(clock_info->usMemoryClockLow);
+						mclk |= clock_info->ucMemoryClockHigh << 16;
+						rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
+						rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
+						/* skip invalid modes */
+						if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) ||
+						    (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0))
+							continue;
+						/* skip overclock modes for now */
+						if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk >
+						     rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) ||
+						    (rdev->pm.power_state[state_index].clock_info[mode_index].sclk >
+						     rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN))
+							continue;
+						rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
+							VOLTAGE_SW;
+						rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
+							clock_info->usVDDC;
+						mode_index++;
+					}
+				}
+				rdev->pm.power_state[state_index].num_clock_modes = mode_index;
+				if (mode_index) {
+					misc = le32_to_cpu(non_clock_info->ulCapsAndSettings);
+					misc2 = le16_to_cpu(non_clock_info->usClassification);
+					rdev->pm.power_state[state_index].non_clock_info.pcie_lanes =
+						((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >>
+						ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;
+					switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) {
+					case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY:
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_BATTERY;
+						break;
+					case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED:
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_BALANCED;
+						break;
+					case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE:
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_PERFORMANCE;
+						break;
+					}
+					if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) {
+						rdev->pm.power_state[state_index].type =
+							POWER_STATE_TYPE_DEFAULT;
+						rdev->pm.default_power_state = &rdev->pm.power_state[state_index];
+						rdev->pm.power_state[state_index].default_clock_mode =
+							&rdev->pm.power_state[state_index].clock_info[mode_index - 1];
+					}
+					state_index++;
+				}
+			}
+		}
+	} else {
+		/* XXX figure out some good default low power mode for cards w/out power tables */
+	}
+
+	if (rdev->pm.default_power_state == NULL) {
+		/* add the default mode */
+		rdev->pm.power_state[state_index].type =
+			POWER_STATE_TYPE_DEFAULT;
+		rdev->pm.power_state[state_index].num_clock_modes = 1;
+		rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
+		rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
+		rdev->pm.power_state[state_index].default_clock_mode =
+			&rdev->pm.power_state[state_index].clock_info[0];
+		rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
+		if (rdev->asic->get_pcie_lanes)
+			rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = radeon_get_pcie_lanes(rdev);
+		else
+			rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = 16;
+		rdev->pm.default_power_state = &rdev->pm.power_state[state_index];
+		state_index++;
+	}
+	rdev->pm.num_power_states = state_index;
+
+	rdev->pm.current_power_state = rdev->pm.default_power_state;
+	rdev->pm.current_clock_mode =
+		rdev->pm.default_power_state->default_clock_mode;
 }
 
-void radeon_atom_static_pwrmgt_setup(struct radeon_device *rdev, int enable)
+void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable)
 {
-	ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION args;
-	int index = GetIndexIntoMasterTable(COMMAND, EnableASIC_StaticPwrMgt);
+	DYNAMIC_CLOCK_GATING_PS_ALLOCATION args;
+	int index = GetIndexIntoMasterTable(COMMAND, DynamicClockGating);
 
 	args.ucEnable = enable;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_atpx_handler.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_atpx_handler.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_atpx_handler.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_atpx_handler.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2010 Red Hat Inc.
+ * Author : Dave Airlie <airlied@redhat.com>
+ *
+ * Licensed under GPLv2
+ *
+ * ATPX support for both Intel/ATI
+ */
+#include <linux/vga_switcheroo.h>
+#include <linux/slab.h>
+#include <acpi/acpi.h>
+#include <acpi/acpi_bus.h>
+#include <linux/pci.h>
+
+#define ATPX_VERSION 0
+#define ATPX_GPU_PWR 2
+#define ATPX_MUX_SELECT 3
+
+#define ATPX_INTEGRATED 0
+#define ATPX_DISCRETE 1
+
+#define ATPX_MUX_IGD 0
+#define ATPX_MUX_DISCRETE 1
+
+static struct radeon_atpx_priv {
+	bool atpx_detected;
+	/* handle for device - and atpx */
+	acpi_handle dhandle;
+	acpi_handle atpx_handle;
+	acpi_handle atrm_handle;
+} radeon_atpx_priv;
+
+/* retrieve the ROM in 4k blocks */
+static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
+			    int offset, int len)
+{
+	acpi_status status;
+	union acpi_object atrm_arg_elements[2], *obj;
+	struct acpi_object_list atrm_arg;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
+
+	atrm_arg.count = 2;
+	atrm_arg.pointer = &atrm_arg_elements[0];
+
+	atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
+	atrm_arg_elements[0].integer.value = offset;
+
+	atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
+	atrm_arg_elements[1].integer.value = len;
+
+	status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
+	if (ACPI_FAILURE(status)) {
+		printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
+		return -ENODEV;
+	}
+
+	obj = (union acpi_object *)buffer.pointer;
+	memcpy(bios+offset, obj->buffer.pointer, len);
+	kfree(buffer.pointer);
+	return len;
+}
+
+bool radeon_atrm_supported(struct pci_dev *pdev)
+{
+	/* get the discrete ROM only via ATRM */
+	if (!radeon_atpx_priv.atpx_detected)
+		return false;
+
+	if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
+		return false;
+	return true;
+}
+
+
+int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len)
+{
+	return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset, len);
+}
+
+static int radeon_atpx_get_version(acpi_handle handle)
+{
+	acpi_status status;
+	union acpi_object atpx_arg_elements[2], *obj;
+	struct acpi_object_list atpx_arg;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+	atpx_arg.count = 2;
+	atpx_arg.pointer = &atpx_arg_elements[0];
+
+	atpx_arg_elements[0].type = ACPI_TYPE_INTEGER;
+	atpx_arg_elements[0].integer.value = ATPX_VERSION;
+
+	atpx_arg_elements[1].type = ACPI_TYPE_INTEGER;
+	atpx_arg_elements[1].integer.value = ATPX_VERSION;
+
+	status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer);
+	if (ACPI_FAILURE(status)) {
+		printk("%s: failed to call ATPX: %s\n", __func__, acpi_format_exception(status));
+		return -ENOSYS;
+	}
+	obj = (union acpi_object *)buffer.pointer;
+	if (obj && (obj->type == ACPI_TYPE_BUFFER))
+		printk(KERN_INFO "radeon atpx: version is %d\n", *((u8 *)(obj->buffer.pointer) + 2));
+	kfree(buffer.pointer);
+	return 0;
+}
+
+static int radeon_atpx_execute(acpi_handle handle, int cmd_id, u16 value)
+{
+	acpi_status status;
+	union acpi_object atpx_arg_elements[2];
+	struct acpi_object_list atpx_arg;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	uint8_t buf[4] = {0};
+
+	if (!handle)
+		return -EINVAL;
+
+	atpx_arg.count = 2;
+	atpx_arg.pointer = &atpx_arg_elements[0];
+
+	atpx_arg_elements[0].type = ACPI_TYPE_INTEGER;
+	atpx_arg_elements[0].integer.value = cmd_id;
+
+	buf[2] = value & 0xff;
+	buf[3] = (value >> 8) & 0xff;
+
+	atpx_arg_elements[1].type = ACPI_TYPE_BUFFER;
+	atpx_arg_elements[1].buffer.length = 4;
+	atpx_arg_elements[1].buffer.pointer = buf;
+
+	status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer);
+	if (ACPI_FAILURE(status)) {
+		printk("%s: failed to call ATPX: %s\n", __func__, acpi_format_exception(status));
+		return -ENOSYS;
+	}
+	kfree(buffer.pointer);
+
+	return 0;
+}
+
+static int radeon_atpx_set_discrete_state(acpi_handle handle, int state)
+{
+	return radeon_atpx_execute(handle, ATPX_GPU_PWR, state);
+}
+
+static int radeon_atpx_switch_mux(acpi_handle handle, int mux_id)
+{
+	return radeon_atpx_execute(handle, ATPX_MUX_SELECT, mux_id);
+}
+
+
+static int radeon_atpx_switchto(enum vga_switcheroo_client_id id)
+{
+	if (id == VGA_SWITCHEROO_IGD)
+		radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 0);
+	else
+		radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 1);
+	return 0;
+}
+
+static int radeon_atpx_power_state(enum vga_switcheroo_client_id id,
+				   enum vga_switcheroo_state state)
+{
+	/* on w500 ACPI can't change intel gpu state */
+	if (id == VGA_SWITCHEROO_IGD)
+		return 0;
+
+	radeon_atpx_set_discrete_state(radeon_atpx_priv.atpx_handle, state);
+	return 0;
+}
+
+static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
+{
+	acpi_handle dhandle, atpx_handle, atrm_handle;
+	acpi_status status;
+
+	dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
+	if (!dhandle)
+		return false;
+
+	status = acpi_get_handle(dhandle, "ATPX", &atpx_handle);
+	if (ACPI_FAILURE(status))
+		return false;
+
+	status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
+	if (ACPI_FAILURE(status))
+		return false;
+
+	radeon_atpx_priv.dhandle = dhandle;
+	radeon_atpx_priv.atpx_handle = atpx_handle;
+	radeon_atpx_priv.atrm_handle = atrm_handle;
+	return true;
+}
+
+static int radeon_atpx_init(void)
+{
+	/* set up the ATPX handle */
+
+	radeon_atpx_get_version(radeon_atpx_priv.atpx_handle);
+	return 0;
+}
+
+static int radeon_atpx_get_client_id(struct pci_dev *pdev)
+{
+	if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
+		return VGA_SWITCHEROO_IGD;
+	else
+		return VGA_SWITCHEROO_DIS;
+}
+
+static struct vga_switcheroo_handler radeon_atpx_handler = {
+	.switchto = radeon_atpx_switchto,
+	.power_state = radeon_atpx_power_state,
+	.init = radeon_atpx_init,
+	.get_client_id = radeon_atpx_get_client_id,
+};
+
+static bool radeon_atpx_detect(void)
+{
+	char acpi_method_name[255] = { 0 };
+	struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
+	struct pci_dev *pdev = NULL;
+	bool has_atpx = false;
+	int vga_count = 0;
+
+	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
+		vga_count++;
+
+		has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
+	}
+
+	if (has_atpx && vga_count == 2) {
+		acpi_get_name(radeon_atpx_priv.atpx_handle, ACPI_FULL_PATHNAME, &buffer);
+		printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n",
+		       acpi_method_name);
+		radeon_atpx_priv.atpx_detected = true;
+		return true;
+	}
+	return false;
+}
+
+void radeon_register_atpx_handler(void)
+{
+	bool r;
+
+	/* detect if we have any ATPX + 2 VGA in the system */
+	r = radeon_atpx_detect();
+	if (!r)
+		return;
+
+	vga_switcheroo_register_handler(&radeon_atpx_handler);
+}
+
+void radeon_unregister_atpx_handler(void)
+{
+	vga_switcheroo_unregister_handler();
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_bios.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_bios.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_bios.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_bios.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,8 @@
 #include "radeon.h"
 #include "atom.h"
 
+#include <linux/vga_switcheroo.h>
+#include <linux/slab.h>
 /*
  * BIOS.
  */
@@ -62,7 +64,7 @@ static bool igp_read_bios_from_vram(stru
 		iounmap(bios);
 		return false;
 	}
-	memcpy(rdev->bios, bios, size);
+	memcpy_fromio(rdev->bios, bios, size);
 	iounmap(bios);
 	return true;
 }
@@ -93,6 +95,38 @@ static bool radeon_read_bios(struct rade
 	return true;
 }
 
+/* ATRM is used to get the BIOS on the discrete cards in
+ * dual-gpu systems.
+ */
+static bool radeon_atrm_get_bios(struct radeon_device *rdev)
+{
+	int ret;
+	int size = 64 * 1024;
+	int i;
+
+	if (!radeon_atrm_supported(rdev->pdev))
+		return false;
+
+	rdev->bios = kmalloc(size, GFP_KERNEL);
+	if (!rdev->bios) {
+		DRM_ERROR("Unable to allocate bios\n");
+		return false;
+	}
+
+	for (i = 0; i < size / ATRM_BIOS_PAGE; i++) {
+		ret = radeon_atrm_get_bios_chunk(rdev->bios,
+						 (i * ATRM_BIOS_PAGE),
+						 ATRM_BIOS_PAGE);
+		if (ret <= 0)
+			break;
+	}
+
+	if (i == 0 || rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) {
+		kfree(rdev->bios);
+		return false;
+	}
+	return true;
+}
 static bool r700_read_disabled_bios(struct radeon_device *rdev)
 {
 	uint32_t viph_control;
@@ -388,16 +422,16 @@ static bool radeon_read_disabled_bios(st
 		return legacy_read_disabled_bios(rdev);
 }
 
+
 bool radeon_get_bios(struct radeon_device *rdev)
 {
 	bool r;
 	uint16_t tmp;
 
-	if (rdev->flags & RADEON_IS_IGP) {
+	r = radeon_atrm_get_bios(rdev);
+	if (r == false)
 		r = igp_read_bios_from_vram(rdev);
-		if (r == false)
-			r = radeon_read_bios(rdev);
-	} else
+	if (r == false)
 		r = radeon_read_bios(rdev);
 	if (r == false) {
 		r = radeon_read_disabled_bios(rdev);
@@ -408,6 +442,13 @@ bool radeon_get_bios(struct radeon_devic
 		return false;
 	}
 	if (rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) {
+		printk("BIOS signature incorrect %x %x\n", rdev->bios[0], rdev->bios[1]);
+		goto free_bios;
+	}
+
+	tmp = RBIOS16(0x18);
+	if (RBIOS8(tmp + 0x14) != 0x0) {
+		DRM_INFO("Not an x86 BIOS ROM, not using.\n");
 		goto free_bios;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_clocks.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_clocks.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_clocks.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_clocks.c	2010-05-16 17:17:36.000000000 -0400
@@ -96,6 +96,7 @@ void radeon_get_clock_info(struct drm_de
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_pll *p1pll = &rdev->clock.p1pll;
 	struct radeon_pll *p2pll = &rdev->clock.p2pll;
+	struct radeon_pll *dcpll = &rdev->clock.dcpll;
 	struct radeon_pll *spll = &rdev->clock.spll;
 	struct radeon_pll *mpll = &rdev->clock.mpll;
 	int ret;
@@ -204,6 +205,17 @@ void radeon_get_clock_info(struct drm_de
 		p2pll->max_frac_feedback_div = 0;
 	}
 
+	/* dcpll is DCE4 only */
+	dcpll->min_post_div = 2;
+	dcpll->max_post_div = 0x7f;
+	dcpll->min_frac_feedback_div = 0;
+	dcpll->max_frac_feedback_div = 9;
+	dcpll->min_ref_div = 2;
+	dcpll->max_ref_div = 0x3ff;
+	dcpll->min_feedback_div = 4;
+	dcpll->max_feedback_div = 0xfff;
+	dcpll->best_vco = 0;
+
 	p1pll->min_ref_div = 2;
 	p1pll->max_ref_div = 0x3ff;
 	p1pll->min_feedback_div = 4;
@@ -846,8 +858,10 @@ int radeon_static_clocks_init(struct drm
 	/* XXX make sure engine is idle */
 
 	if (radeon_dynclks != -1) {
-		if (radeon_dynclks)
-			radeon_set_clock_gating(rdev, 1);
+		if (radeon_dynclks) {
+			if (rdev->asic->set_clock_gating)
+				radeon_set_clock_gating(rdev, 1);
+		}
 	}
 	radeon_apply_clock_quirks(rdev);
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_combios.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_combios.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_combios.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_combios.c	2010-05-16 17:17:36.000000000 -0400
@@ -150,6 +150,9 @@ static uint16_t combios_get_table_offset
 	int rev;
 	uint16_t offset = 0, check_offset;
 
+	if (!rdev->bios)
+		return 0;
+
 	switch (table) {
 		/* absolute offset tables */
 	case COMBIOS_ASIC_INIT_1_TABLE:
@@ -443,6 +446,39 @@ static uint16_t combios_get_table_offset
 
 }
 
+bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev)
+{
+	int edid_info;
+	struct edid *edid;
+	edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE);
+	if (!edid_info)
+		return false;
+
+	edid = kmalloc(EDID_LENGTH * (DRM_MAX_EDID_EXT_NUM + 1),
+		       GFP_KERNEL);
+	if (edid == NULL)
+		return false;
+
+	memcpy((unsigned char *)edid,
+	       (unsigned char *)(rdev->bios + edid_info), EDID_LENGTH);
+
+	if (!drm_edid_is_valid(edid)) {
+		kfree(edid);
+		return false;
+	}
+
+	rdev->mode_info.bios_hardcoded_edid = edid;
+	return true;
+}
+
+struct edid *
+radeon_combios_get_hardcoded_edid(struct radeon_device *rdev)
+{
+	if (rdev->mode_info.bios_hardcoded_edid)
+		return rdev->mode_info.bios_hardcoded_edid;
+	return NULL;
+}
+
 static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev,
 						       int ddc_line)
 {
@@ -486,9 +522,62 @@ static struct radeon_i2c_bus_rec combios
 		i2c.y_data_reg = ddc_line;
 	}
 
-	if (rdev->family < CHIP_R200)
-		i2c.hw_capable = false;
-	else {
+	switch (rdev->family) {
+	case CHIP_R100:
+	case CHIP_RV100:
+	case CHIP_RS100:
+	case CHIP_RV200:
+	case CHIP_RS200:
+	case CHIP_RS300:
+		switch (ddc_line) {
+		case RADEON_GPIO_DVI_DDC:
+			i2c.hw_capable = true;
+			break;
+		default:
+			i2c.hw_capable = false;
+			break;
+		}
+		break;
+	case CHIP_R200:
+		switch (ddc_line) {
+		case RADEON_GPIO_DVI_DDC:
+		case RADEON_GPIO_MONID:
+			i2c.hw_capable = true;
+			break;
+		default:
+			i2c.hw_capable = false;
+			break;
+		}
+		break;
+	case CHIP_RV250:
+	case CHIP_RV280:
+		switch (ddc_line) {
+		case RADEON_GPIO_VGA_DDC:
+		case RADEON_GPIO_DVI_DDC:
+		case RADEON_GPIO_CRT2_DDC:
+			i2c.hw_capable = true;
+			break;
+		default:
+			i2c.hw_capable = false;
+			break;
+		}
+		break;
+	case CHIP_R300:
+	case CHIP_R350:
+		switch (ddc_line) {
+		case RADEON_GPIO_VGA_DDC:
+		case RADEON_GPIO_DVI_DDC:
+			i2c.hw_capable = true;
+			break;
+		default:
+			i2c.hw_capable = false;
+			break;
+		}
+		break;
+	case CHIP_RV350:
+	case CHIP_RV380:
+	case CHIP_RS400:
+	case CHIP_RS480:
 		switch (ddc_line) {
 		case RADEON_GPIO_VGA_DDC:
 		case RADEON_GPIO_DVI_DDC:
@@ -504,9 +593,14 @@ static struct radeon_i2c_bus_rec combios
 			i2c.hw_capable = false;
 			break;
 		}
+		break;
+	default:
+		i2c.hw_capable = false;
+		break;
 	}
 	i2c.mm_i2c = false;
 	i2c.i2c_id = 0;
+	i2c.hpd_id = 0;
 
 	if (ddc_line)
 		i2c.valid = true;
@@ -527,9 +621,6 @@ bool radeon_combios_get_clock_info(struc
 	int8_t rev;
 	uint16_t sclk, mclk;
 
-	if (rdev->bios == NULL)
-		return false;
-
 	pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE);
 	if (pll_info) {
 		rev = RBIOS8(pll_info);
@@ -539,6 +630,8 @@ bool radeon_combios_get_clock_info(struc
 		p1pll->reference_div = RBIOS16(pll_info + 0x10);
 		p1pll->pll_out_min = RBIOS32(pll_info + 0x12);
 		p1pll->pll_out_max = RBIOS32(pll_info + 0x16);
+		p1pll->lcd_pll_out_min = p1pll->pll_out_min;
+		p1pll->lcd_pll_out_max = p1pll->pll_out_max;
 
 		if (rev > 9) {
 			p1pll->pll_in_min = RBIOS32(pll_info + 0x36);
@@ -654,9 +747,6 @@ struct radeon_encoder_primary_dac *radeo
 	if (!p_dac)
 		return NULL;
 
-	if (rdev->bios == NULL)
-		goto out;
-
 	/* check CRT table */
 	dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
 	if (dac_info) {
@@ -670,10 +760,11 @@ struct radeon_encoder_primary_dac *radeo
 			dac = RBIOS8(dac_info + 0x3) & 0xf;
 			p_dac->ps2_pdac_adj = (bg << 8) | (dac);
 		}
-		found = 1;
+		/* if the values are all zeros, use the table */
+		if (p_dac->ps2_pdac_adj)
+			found = 1;
 	}
 
-out:
 	if (!found) /* fallback to defaults */
 		radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac);
 
@@ -687,9 +778,6 @@ radeon_combios_get_tv_info(struct radeon
 	uint16_t tv_info;
 	enum radeon_tv_std tv_std = TV_STD_NTSC;
 
-	if (rdev->bios == NULL)
-		return tv_std;
-
 	tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
 	if (tv_info) {
 		if (RBIOS8(tv_info + 6) == 'T') {
@@ -793,9 +881,6 @@ struct radeon_encoder_tv_dac *radeon_com
 	if (!tv_dac)
 		return NULL;
 
-	if (rdev->bios == NULL)
-		goto out;
-
 	/* first check TV table */
 	dac_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
 	if (dac_info) {
@@ -812,7 +897,9 @@ struct radeon_encoder_tv_dac *radeon_com
 			bg = RBIOS8(dac_info + 0x10) & 0xf;
 			dac = RBIOS8(dac_info + 0x11) & 0xf;
 			tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
-			found = 1;
+			/* if the values are all zeros, use the table */
+			if (tv_dac->ps2_tvdac_adj)
+				found = 1;
 		} else if (rev > 1) {
 			bg = RBIOS8(dac_info + 0xc) & 0xf;
 			dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf;
@@ -825,7 +912,9 @@ struct radeon_encoder_tv_dac *radeon_com
 			bg = RBIOS8(dac_info + 0xe) & 0xf;
 			dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf;
 			tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
-			found = 1;
+			/* if the values are all zeros, use the table */
+			if (tv_dac->ps2_tvdac_adj)
+				found = 1;
 		}
 		tv_dac->tv_std = radeon_combios_get_tv_info(rdev);
 	}
@@ -842,7 +931,9 @@ struct radeon_encoder_tv_dac *radeon_com
 				    (bg << 16) | (dac << 20);
 				tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
 				tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
-				found = 1;
+				/* if the values are all zeros, use the table */
+				if (tv_dac->ps2_tvdac_adj)
+					found = 1;
 			} else {
 				bg = RBIOS8(dac_info + 0x4) & 0xf;
 				dac = RBIOS8(dac_info + 0x5) & 0xf;
@@ -850,14 +941,15 @@ struct radeon_encoder_tv_dac *radeon_com
 				    (bg << 16) | (dac << 20);
 				tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
 				tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
-				found = 1;
+				/* if the values are all zeros, use the table */
+				if (tv_dac->ps2_tvdac_adj)
+					found = 1;
 			}
 		} else {
 			DRM_INFO("No TV DAC info found in BIOS\n");
 		}
 	}
 
-out:
 	if (!found) /* fallback to defaults */
 		radeon_legacy_get_tv_dac_info_from_table(rdev, tv_dac);
 
@@ -945,11 +1037,6 @@ struct radeon_encoder_lvds *radeon_combi
 	int tmp, i;
 	struct radeon_encoder_lvds *lvds = NULL;
 
-	if (rdev->bios == NULL) {
-		lvds = radeon_legacy_get_lvds_info_from_regs(rdev);
-		goto out;
-	}
-
 	lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
 
 	if (lcd_info) {
@@ -1050,7 +1137,7 @@ struct radeon_encoder_lvds *radeon_combi
 		DRM_INFO("No panel info found in BIOS\n");
 		lvds = radeon_legacy_get_lvds_info_from_regs(rdev);
 	}
-out:
+
 	if (lvds)
 		encoder->native_mode = lvds->native_mode;
 	return lvds;
@@ -1102,9 +1189,6 @@ bool radeon_legacy_get_tmds_info_from_co
 	int i, n;
 	uint8_t ver;
 
-	if (rdev->bios == NULL)
-		return false;
-
 	tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
 
 	if (tmds_info) {
@@ -1184,9 +1268,6 @@ bool radeon_legacy_get_ext_tmds_info_fro
 	enum radeon_combios_ddc gpio;
 	struct radeon_i2c_bus_rec i2c_bus;
 
-	if (rdev->bios == NULL)
-		return false;
-
 	tmds->i2c_bus = NULL;
 	if (rdev->flags & RADEON_IS_IGP) {
 		offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE);
@@ -1253,7 +1334,10 @@ bool radeon_legacy_get_ext_tmds_info_fro
 				tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
 				break;
 			case DDC_LCD: /* MM i2c */
-				DRM_ERROR("MM i2c requires hw i2c engine\n");
+				i2c_bus.valid = true;
+				i2c_bus.hw_capable = true;
+				i2c_bus.mm_i2c = true;
+				tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
 				break;
 			default:
 				DRM_ERROR("Unsupported gpio %d\n", gpio);
@@ -1279,47 +1363,47 @@ bool radeon_get_legacy_connector_info_fr
 	rdev->mode_info.connector_table = radeon_connector_table;
 	if (rdev->mode_info.connector_table == CT_NONE) {
 #ifdef CONFIG_PPC_PMAC
-		if (machine_is_compatible("PowerBook3,3")) {
+		if (of_machine_is_compatible("PowerBook3,3")) {
 			/* powerbook with VGA */
 			rdev->mode_info.connector_table = CT_POWERBOOK_VGA;
-		} else if (machine_is_compatible("PowerBook3,4") ||
-			   machine_is_compatible("PowerBook3,5")) {
+		} else if (of_machine_is_compatible("PowerBook3,4") ||
+			   of_machine_is_compatible("PowerBook3,5")) {
 			/* powerbook with internal tmds */
 			rdev->mode_info.connector_table = CT_POWERBOOK_INTERNAL;
-		} else if (machine_is_compatible("PowerBook5,1") ||
-			   machine_is_compatible("PowerBook5,2") ||
-			   machine_is_compatible("PowerBook5,3") ||
-			   machine_is_compatible("PowerBook5,4") ||
-			   machine_is_compatible("PowerBook5,5")) {
+		} else if (of_machine_is_compatible("PowerBook5,1") ||
+			   of_machine_is_compatible("PowerBook5,2") ||
+			   of_machine_is_compatible("PowerBook5,3") ||
+			   of_machine_is_compatible("PowerBook5,4") ||
+			   of_machine_is_compatible("PowerBook5,5")) {
 			/* powerbook with external single link tmds (sil164) */
 			rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL;
-		} else if (machine_is_compatible("PowerBook5,6")) {
+		} else if (of_machine_is_compatible("PowerBook5,6")) {
 			/* powerbook with external dual or single link tmds */
 			rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL;
-		} else if (machine_is_compatible("PowerBook5,7") ||
-			   machine_is_compatible("PowerBook5,8") ||
-			   machine_is_compatible("PowerBook5,9")) {
+		} else if (of_machine_is_compatible("PowerBook5,7") ||
+			   of_machine_is_compatible("PowerBook5,8") ||
+			   of_machine_is_compatible("PowerBook5,9")) {
 			/* PowerBook6,2 ? */
 			/* powerbook with external dual link tmds (sil1178?) */
 			rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL;
-		} else if (machine_is_compatible("PowerBook4,1") ||
-			   machine_is_compatible("PowerBook4,2") ||
-			   machine_is_compatible("PowerBook4,3") ||
-			   machine_is_compatible("PowerBook6,3") ||
-			   machine_is_compatible("PowerBook6,5") ||
-			   machine_is_compatible("PowerBook6,7")) {
+		} else if (of_machine_is_compatible("PowerBook4,1") ||
+			   of_machine_is_compatible("PowerBook4,2") ||
+			   of_machine_is_compatible("PowerBook4,3") ||
+			   of_machine_is_compatible("PowerBook6,3") ||
+			   of_machine_is_compatible("PowerBook6,5") ||
+			   of_machine_is_compatible("PowerBook6,7")) {
 			/* ibook */
 			rdev->mode_info.connector_table = CT_IBOOK;
-		} else if (machine_is_compatible("PowerMac4,4")) {
+		} else if (of_machine_is_compatible("PowerMac4,4")) {
 			/* emac */
 			rdev->mode_info.connector_table = CT_EMAC;
-		} else if (machine_is_compatible("PowerMac10,1")) {
+		} else if (of_machine_is_compatible("PowerMac10,1")) {
 			/* mini with internal tmds */
 			rdev->mode_info.connector_table = CT_MINI_INTERNAL;
-		} else if (machine_is_compatible("PowerMac10,2")) {
+		} else if (of_machine_is_compatible("PowerMac10,2")) {
 			/* mini with external tmds */
 			rdev->mode_info.connector_table = CT_MINI_EXTERNAL;
-		} else if (machine_is_compatible("PowerMac12,1")) {
+		} else if (of_machine_is_compatible("PowerMac12,1")) {
 			/* PowerMac8,1 ? */
 			/* imac g5 isight */
 			rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT;
@@ -1909,9 +1993,6 @@ bool radeon_get_legacy_connector_info_fr
 	struct radeon_i2c_bus_rec ddc_i2c;
 	struct radeon_hpd hpd;
 
-	if (rdev->bios == NULL)
-		return false;
-
 	conn_info = combios_get_table_offset(dev, COMBIOS_CONNECTOR_INFO_TABLE);
 	if (conn_info) {
 		for (i = 0; i < 4; i++) {
@@ -2278,6 +2359,115 @@ bool radeon_get_legacy_connector_info_fr
 	return true;
 }
 
+void radeon_combios_get_power_modes(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	u16 offset, misc, misc2 = 0;
+	u8 rev, blocks, tmp;
+	int state_index = 0;
+
+	rdev->pm.default_power_state = NULL;
+
+	if (rdev->flags & RADEON_IS_MOBILITY) {
+		offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE);
+		if (offset) {
+			rev = RBIOS8(offset);
+			blocks = RBIOS8(offset + 0x2);
+			/* power mode 0 tends to be the only valid one */
+			rdev->pm.power_state[state_index].num_clock_modes = 1;
+			rdev->pm.power_state[state_index].clock_info[0].mclk = RBIOS32(offset + 0x5 + 0x2);
+			rdev->pm.power_state[state_index].clock_info[0].sclk = RBIOS32(offset + 0x5 + 0x6);
+			if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
+			    (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
+				goto default_mode;
+			/* skip overclock modes for now */
+			if ((rdev->pm.power_state[state_index].clock_info[0].mclk >
+			     rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) ||
+			    (rdev->pm.power_state[state_index].clock_info[0].sclk >
+			     rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN))
+				goto default_mode;
+			rdev->pm.power_state[state_index].type =
+				POWER_STATE_TYPE_BATTERY;
+			misc = RBIOS16(offset + 0x5 + 0x0);
+			if (rev > 4)
+				misc2 = RBIOS16(offset + 0x5 + 0xe);
+			if (misc & 0x4) {
+				rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO;
+				if (misc & 0x8)
+					rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
+						true;
+				else
+					rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
+						false;
+				rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = true;
+				if (rev < 6) {
+					rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg =
+						RBIOS16(offset + 0x5 + 0xb) * 4;
+					tmp = RBIOS8(offset + 0x5 + 0xd);
+					rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp);
+				} else {
+					u8 entries = RBIOS8(offset + 0x5 + 0xb);
+					u16 voltage_table_offset = RBIOS16(offset + 0x5 + 0xc);
+					if (entries && voltage_table_offset) {
+						rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg =
+							RBIOS16(voltage_table_offset) * 4;
+						tmp = RBIOS8(voltage_table_offset + 0x2);
+						rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp);
+					} else
+						rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = false;
+				}
+				switch ((misc2 & 0x700) >> 8) {
+				case 0:
+				default:
+					rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 0;
+					break;
+				case 1:
+					rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 33;
+					break;
+				case 2:
+					rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 66;
+					break;
+				case 3:
+					rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 99;
+					break;
+				case 4:
+					rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 132;
+					break;
+				}
+			} else
+				rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
+			if (rev > 6)
+				rdev->pm.power_state[state_index].non_clock_info.pcie_lanes =
+					RBIOS8(offset + 0x5 + 0x10);
+			state_index++;
+		} else {
+			/* XXX figure out some good default low power mode for mobility cards w/out power tables */
+		}
+	} else {
+		/* XXX figure out some good default low power mode for desktop cards */
+	}
+
+default_mode:
+	/* add the default mode */
+	rdev->pm.power_state[state_index].type =
+		POWER_STATE_TYPE_DEFAULT;
+	rdev->pm.power_state[state_index].num_clock_modes = 1;
+	rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
+	rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
+	rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0];
+	rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
+	if (rdev->asic->get_pcie_lanes)
+		rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = radeon_get_pcie_lanes(rdev);
+	else
+		rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = 16;
+	rdev->pm.default_power_state = &rdev->pm.power_state[state_index];
+	rdev->pm.num_power_states = state_index + 1;
+
+	rdev->pm.current_power_state = rdev->pm.default_power_state;
+	rdev->pm.current_clock_mode =
+		rdev->pm.default_power_state->default_clock_mode;
+}
+
 void radeon_external_tmds_setup(struct drm_encoder *encoder)
 {
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
@@ -2289,23 +2479,21 @@ void radeon_external_tmds_setup(struct d
 	switch (tmds->dvo_chip) {
 	case DVO_SIL164:
 		/* sil 164 */
-		radeon_i2c_do_lock(tmds->i2c_bus, 1);
-		radeon_i2c_sw_put_byte(tmds->i2c_bus,
-				       tmds->slave_addr,
-				       0x08, 0x30);
-		radeon_i2c_sw_put_byte(tmds->i2c_bus,
+		radeon_i2c_put_byte(tmds->i2c_bus,
+				    tmds->slave_addr,
+				    0x08, 0x30);
+		radeon_i2c_put_byte(tmds->i2c_bus,
 				       tmds->slave_addr,
 				       0x09, 0x00);
-		radeon_i2c_sw_put_byte(tmds->i2c_bus,
-				       tmds->slave_addr,
-				       0x0a, 0x90);
-		radeon_i2c_sw_put_byte(tmds->i2c_bus,
-				       tmds->slave_addr,
-				       0x0c, 0x89);
-		radeon_i2c_sw_put_byte(tmds->i2c_bus,
+		radeon_i2c_put_byte(tmds->i2c_bus,
+				    tmds->slave_addr,
+				    0x0a, 0x90);
+		radeon_i2c_put_byte(tmds->i2c_bus,
+				    tmds->slave_addr,
+				    0x0c, 0x89);
+		radeon_i2c_put_byte(tmds->i2c_bus,
 				       tmds->slave_addr,
 				       0x08, 0x3b);
-		radeon_i2c_do_lock(tmds->i2c_bus, 0);
 		break;
 	case DVO_SIL1178:
 		/* sil 1178 - untested */
@@ -2338,9 +2526,6 @@ bool radeon_combios_external_tmds_setup(
 	uint32_t reg, val, and_mask, or_mask;
 	struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
 
-	if (rdev->bios == NULL)
-		return false;
-
 	if (!tmds)
 		return false;
 
@@ -2390,11 +2575,9 @@ bool radeon_combios_external_tmds_setup(
 						index++;
 						val = RBIOS8(index);
 						index++;
-						radeon_i2c_do_lock(tmds->i2c_bus, 1);
-						radeon_i2c_sw_put_byte(tmds->i2c_bus,
-								       slave_addr,
-								       reg, val);
-						radeon_i2c_do_lock(tmds->i2c_bus, 0);
+						radeon_i2c_put_byte(tmds->i2c_bus,
+								    slave_addr,
+								    reg, val);
 						break;
 					default:
 						DRM_ERROR("Unknown id %d\n", id >> 13);
@@ -2447,11 +2630,9 @@ bool radeon_combios_external_tmds_setup(
 					reg = id & 0x1fff;
 					val = RBIOS8(index);
 					index += 1;
-					radeon_i2c_do_lock(tmds->i2c_bus, 1);
-					radeon_i2c_sw_put_byte(tmds->i2c_bus,
-							       tmds->slave_addr,
-							       reg, val);
-					radeon_i2c_do_lock(tmds->i2c_bus, 0);
+					radeon_i2c_put_byte(tmds->i2c_bus,
+							    tmds->slave_addr,
+							    reg, val);
 					break;
 				default:
 					DRM_ERROR("Unknown id %d\n", id >> 13);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_connectors.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_connectors.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_connectors.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_connectors.c	2010-05-16 17:17:36.000000000 -0400
@@ -162,12 +162,14 @@ radeon_connector_analog_encoder_conflict
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_connector *conflict;
+	struct radeon_connector *radeon_conflict;
 	int i;
 
 	list_for_each_entry(conflict, &dev->mode_config.connector_list, head) {
 		if (conflict == connector)
 			continue;
 
+		radeon_conflict = to_radeon_connector(conflict);
 		for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
 			if (conflict->encoder_ids[i] == 0)
 				break;
@@ -177,6 +179,9 @@ radeon_connector_analog_encoder_conflict
 				if (conflict->status != connector_status_connected)
 					continue;
 
+				if (radeon_conflict->use_digital)
+					continue;
+
 				if (priority == true) {
 					DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict));
 					DRM_INFO("in favor of %s\n", drm_get_connector_name(connector));
@@ -287,6 +292,7 @@ int radeon_connector_set_property(struct
 
 	if (property == rdev->mode_info.coherent_mode_property) {
 		struct radeon_encoder_atom_dig *dig;
+		bool new_coherent_mode;
 
 		/* need to find digital encoder on connector */
 		encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
@@ -299,8 +305,11 @@ int radeon_connector_set_property(struct
 			return 0;
 
 		dig = radeon_encoder->enc_priv;
-		dig->coherent_mode = val ? true : false;
-		radeon_property_change_mode(&radeon_encoder->base);
+		new_coherent_mode = val ? true : false;
+		if (dig->coherent_mode != new_coherent_mode) {
+			dig->coherent_mode = new_coherent_mode;
+			radeon_property_change_mode(&radeon_encoder->base);
+		}
 	}
 
 	if (property == rdev->mode_info.tv_std_property) {
@@ -315,7 +324,7 @@ int radeon_connector_set_property(struct
 		radeon_encoder = to_radeon_encoder(encoder);
 		if (!radeon_encoder->enc_priv)
 			return 0;
-		if (rdev->is_atom_bios) {
+		if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) {
 			struct radeon_encoder_atom_dac *dac_int;
 			dac_int = radeon_encoder->enc_priv;
 			dac_int->tv_std = val;
@@ -479,10 +488,8 @@ static enum drm_connector_status radeon_
 		ret = connector_status_connected;
 	else {
 		if (radeon_connector->ddc_bus) {
-			radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 			radeon_connector->edid = drm_get_edid(&radeon_connector->base,
 							      &radeon_connector->ddc_bus->adapter);
-			radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 			if (radeon_connector->edid)
 				ret = connector_status_connected;
 		}
@@ -587,19 +594,14 @@ static enum drm_connector_status radeon_
 	if (!encoder)
 		ret = connector_status_disconnected;
 
-	if (radeon_connector->ddc_bus) {
-		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
+	if (radeon_connector->ddc_bus)
 		dret = radeon_ddc_probe(radeon_connector);
-		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
-	}
 	if (dret) {
 		if (radeon_connector->edid) {
 			kfree(radeon_connector->edid);
 			radeon_connector->edid = NULL;
 		}
-		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 		radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
-		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 
 		if (!radeon_connector->edid) {
 			DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
@@ -744,19 +746,14 @@ static enum drm_connector_status radeon_
 	enum drm_connector_status ret = connector_status_disconnected;
 	bool dret = false;
 
-	if (radeon_connector->ddc_bus) {
-		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
+	if (radeon_connector->ddc_bus)
 		dret = radeon_ddc_probe(radeon_connector);
-		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
-	}
 	if (dret) {
 		if (radeon_connector->edid) {
 			kfree(radeon_connector->edid);
 			radeon_connector->edid = NULL;
 		}
-		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 		radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
-		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 
 		if (!radeon_connector->edid) {
 			DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
@@ -988,12 +985,10 @@ static enum drm_connector_status radeon_
 			ret = connector_status_connected;
 		}
 	} else {
-		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 		if (radeon_ddc_probe(radeon_connector)) {
 			radeon_dig_connector->dp_sink_type = sink_type;
 			ret = connector_status_connected;
 		}
-		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 	}
 
 	return ret;
@@ -1321,6 +1316,8 @@ radeon_add_legacy_connector(struct drm_d
 			radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
 			if (!radeon_connector->ddc_bus)
 				goto failed;
+		}
+		if (connector_type == DRM_MODE_CONNECTOR_DVII) {
 			radeon_connector->dac_load_detect = true;
 			drm_connector_attach_property(&radeon_connector->base,
 						      rdev->mode_info.load_detect_property,
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_cp.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_cp.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_cp.c	2013-05-03 12:03:41.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_cp.c	2013-05-03 09:44:35.000000000 -0400
@@ -411,8 +411,9 @@ static int radeon_do_wait_for_idle(drm_r
 	return -EBUSY;
 }
 
-static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
+static void radeon_init_pipes(struct drm_device *dev)
 {
+	drm_radeon_private_t *dev_priv = dev->dev_private;
 	uint32_t gb_tile_config, gb_pipe_sel = 0;
 
 	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) {
@@ -428,13 +429,19 @@ static void radeon_init_pipes(drm_radeon
 	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) {
 		gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT);
 		dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
+		/* SE cards have 1 pipe */
+		if ((dev->pdev->device == 0x5e4c) ||
+		    (dev->pdev->device == 0x5e4f))
+			dev_priv->num_gb_pipes = 1;
 	} else {
 		/* R3xx */
-		if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) ||
-		    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) {
+		if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300 &&
+		     dev->pdev->device != 0x4144) ||
+		    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350 &&
+		     dev->pdev->device != 0x4148)) {
 			dev_priv->num_gb_pipes = 2;
 		} else {
-			/* R3Vxx */
+			/* RV3xx/R300 AD/R350 AH */
 			dev_priv->num_gb_pipes = 1;
 		}
 	}
@@ -730,7 +737,7 @@ static int radeon_do_engine_reset(struct
 
 	/* setup the raster pipes */
 	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300)
-	    radeon_init_pipes(dev_priv);
+	    radeon_init_pipes(dev);
 
 	/* Reset the CP ring */
 	radeon_do_cp_reset(dev_priv);
@@ -1638,6 +1645,7 @@ static int radeon_do_resume_cp(struct dr
 	radeon_cp_load_microcode(dev_priv);
 	radeon_cp_init_ring_buffer(dev, dev_priv, file_priv);
 
+	dev_priv->have_z_offset = 0;
 	radeon_do_engine_reset(dev);
 	radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_cs.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_cs.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -193,11 +193,10 @@ static void radeon_cs_parser_fini(struct
 		radeon_bo_list_fence(&parser->validated, parser->ib->fence);
 	}
 	radeon_bo_list_unreserve(&parser->validated);
-	for (i = 0; i < parser->nrelocs; i++) {
-		if (parser->relocs[i].gobj) {
-			mutex_lock(&parser->rdev->ddev->struct_mutex);
-			drm_gem_object_unreference(parser->relocs[i].gobj);
-			mutex_unlock(&parser->rdev->ddev->struct_mutex);
+	if (parser->relocs != NULL) {
+		for (i = 0; i < parser->nrelocs; i++) {
+			if (parser->relocs[i].gobj)
+				drm_gem_object_unreference_unlocked(parser->relocs[i].gobj);
 		}
 	}
 	kfree(parser->track);
@@ -246,7 +245,8 @@ int radeon_cs_ioctl(struct drm_device *d
 	}
 	r = radeon_cs_parser_relocs(&parser);
 	if (r) {
-		DRM_ERROR("Failed to parse relocation !\n");
+		if (r != -ERESTARTSYS)
+			DRM_ERROR("Failed to parse relocation %d!\n", r);
 		radeon_cs_parser_fini(&parser, r);
 		mutex_unlock(&rdev->cs_mutex);
 		return r;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_cursor.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_cursor.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_cursor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_cursor.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,7 +36,14 @@ static void radeon_lock_cursor(struct dr
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 	uint32_t cur_lock;
 
-	if (ASIC_IS_AVIVO(rdev)) {
+	if (ASIC_IS_DCE4(rdev)) {
+		cur_lock = RREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset);
+		if (lock)
+			cur_lock |= EVERGREEN_CURSOR_UPDATE_LOCK;
+		else
+			cur_lock &= ~EVERGREEN_CURSOR_UPDATE_LOCK;
+		WREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock);
+	} else if (ASIC_IS_AVIVO(rdev)) {
 		cur_lock = RREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset);
 		if (lock)
 			cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK;
@@ -58,7 +65,10 @@ static void radeon_hide_cursor(struct dr
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 	struct radeon_device *rdev = crtc->dev->dev_private;
 
-	if (ASIC_IS_AVIVO(rdev)) {
+	if (ASIC_IS_DCE4(rdev)) {
+		WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset);
+		WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT));
+	} else if (ASIC_IS_AVIVO(rdev)) {
 		WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset);
 		WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
 	} else {
@@ -81,10 +91,14 @@ static void radeon_show_cursor(struct dr
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 	struct radeon_device *rdev = crtc->dev->dev_private;
 
-	if (ASIC_IS_AVIVO(rdev)) {
+	if (ASIC_IS_DCE4(rdev)) {
+		WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset);
+		WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN |
+		       EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT));
+	} else if (ASIC_IS_AVIVO(rdev)) {
 		WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset);
 		WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN |
-			     (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
+		       (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
 	} else {
 		switch (radeon_crtc->crtc_id) {
 		case 0:
@@ -109,7 +123,10 @@ static void radeon_set_cursor(struct drm
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 	struct radeon_device *rdev = crtc->dev->dev_private;
 
-	if (ASIC_IS_AVIVO(rdev)) {
+	if (ASIC_IS_DCE4(rdev)) {
+		WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, 0);
+		WREG32(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr);
+	} else if (ASIC_IS_AVIVO(rdev)) {
 		if (rdev->family >= CHIP_RV770) {
 			if (radeon_crtc->crtc_id)
 				WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH, 0);
@@ -169,17 +186,13 @@ int radeon_crtc_cursor_set(struct drm_cr
 unpin:
 	if (radeon_crtc->cursor_bo) {
 		radeon_gem_object_unpin(radeon_crtc->cursor_bo);
-		mutex_lock(&crtc->dev->struct_mutex);
-		drm_gem_object_unreference(radeon_crtc->cursor_bo);
-		mutex_unlock(&crtc->dev->struct_mutex);
+		drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo);
 	}
 
 	radeon_crtc->cursor_bo = obj;
 	return 0;
 fail:
-	mutex_lock(&crtc->dev->struct_mutex);
-	drm_gem_object_unreference(obj);
-	mutex_unlock(&crtc->dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(obj);
 
 	return 0;
 }
@@ -201,7 +214,20 @@ int radeon_crtc_cursor_move(struct drm_c
 		yorigin = CURSOR_HEIGHT - 1;
 
 	radeon_lock_cursor(crtc, true);
-	if (ASIC_IS_AVIVO(rdev)) {
+	if (ASIC_IS_DCE4(rdev)) {
+		/* cursors are offset into the total surface */
+		x += crtc->x;
+		y += crtc->y;
+		DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y);
+
+		/* XXX: check if evergreen has the same issues as avivo chips */
+		WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset,
+		       ((xorigin ? 0 : x) << 16) |
+		       (yorigin ? 0 : y));
+		WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin);
+		WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset,
+		       ((radeon_crtc->cursor_width - 1) << 16) | (radeon_crtc->cursor_height - 1));
+	} else if (ASIC_IS_AVIVO(rdev)) {
 		int w = radeon_crtc->cursor_width;
 		int i = 0;
 		struct drm_crtc *crtc_p;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_device.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_device.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_device.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_device.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,15 +26,64 @@
  *          Jerome Glisse
  */
 #include <linux/console.h>
+#include <linux/slab.h>
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/radeon_drm.h>
 #include <linux/vgaarb.h>
+#include <linux/vga_switcheroo.h>
 #include "radeon_reg.h"
 #include "radeon.h"
-#include "radeon_asic.h"
 #include "atom.h"
 
+static const char radeon_family_name[][16] = {
+	"R100",
+	"RV100",
+	"RS100",
+	"RV200",
+	"RS200",
+	"R200",
+	"RV250",
+	"RS300",
+	"RV280",
+	"R300",
+	"R350",
+	"RV350",
+	"RV380",
+	"R420",
+	"R423",
+	"RV410",
+	"RS400",
+	"RS480",
+	"RS600",
+	"RS690",
+	"RS740",
+	"RV515",
+	"R520",
+	"RV530",
+	"RV560",
+	"RV570",
+	"R580",
+	"R600",
+	"RV610",
+	"RV630",
+	"RV670",
+	"RV620",
+	"RV635",
+	"RS780",
+	"RS880",
+	"RV770",
+	"RV730",
+	"RV710",
+	"RV740",
+	"CEDAR",
+	"REDWOOD",
+	"JUNIPER",
+	"CYPRESS",
+	"HEMLOCK",
+	"LAST",
+};
+
 /*
  * Clear GPU surface registers.
  */
@@ -100,80 +149,103 @@ void radeon_scratch_free(struct radeon_d
 	}
 }
 
-/*
- * MC common functions
+/**
+ * radeon_vram_location - try to find VRAM location
+ * @rdev: radeon device structure holding all necessary informations
+ * @mc: memory controller structure holding memory informations
+ * @base: base address at which to put VRAM
+ *
+ * Function will place try to place VRAM at base address provided
+ * as parameter (which is so far either PCI aperture address or
+ * for IGP TOM base address).
+ *
+ * If there is not enough space to fit the unvisible VRAM in the 32bits
+ * address space then we limit the VRAM size to the aperture.
+ *
+ * If we are using AGP and if the AGP aperture doesn't allow us to have
+ * room for all the VRAM than we restrict the VRAM to the PCI aperture
+ * size and print a warning.
+ *
+ * This function will never fails, worst case are limiting VRAM.
+ *
+ * Note: GTT start, end, size should be initialized before calling this
+ * function on AGP platform.
+ *
+ * Note: We don't explictly enforce VRAM start to be aligned on VRAM size,
+ * this shouldn't be a problem as we are using the PCI aperture as a reference.
+ * Otherwise this would be needed for rv280, all r3xx, and all r4xx, but
+ * not IGP.
+ *
+ * Note: we use mc_vram_size as on some board we need to program the mc to
+ * cover the whole aperture even if VRAM size is inferior to aperture size
+ * Novell bug 204882 + along with lots of ubuntu ones
+ *
+ * Note: when limiting vram it's safe to overwritte real_vram_size because
+ * we are not in case where real_vram_size is inferior to mc_vram_size (ie
+ * note afected by bogus hw of Novell bug 204882 + along with lots of ubuntu
+ * ones)
+ *
+ * Note: IGP TOM addr should be the same as the aperture addr, we don't
+ * explicitly check for that thought.
+ *
+ * FIXME: when reducing VRAM size align new size on power of 2.
  */
-int radeon_mc_setup(struct radeon_device *rdev)
+void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base)
 {
-	uint32_t tmp;
+	mc->vram_start = base;
+	if (mc->mc_vram_size > (0xFFFFFFFF - base + 1)) {
+		dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n");
+		mc->real_vram_size = mc->aper_size;
+		mc->mc_vram_size = mc->aper_size;
+	}
+	mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
+	if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_end <= mc->gtt_end) {
+		dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n");
+		mc->real_vram_size = mc->aper_size;
+		mc->mc_vram_size = mc->aper_size;
+	}
+	mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
+	dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
+			mc->mc_vram_size >> 20, mc->vram_start,
+			mc->vram_end, mc->real_vram_size >> 20);
+}
 
-	/* Some chips have an "issue" with the memory controller, the
-	 * location must be aligned to the size. We just align it down,
-	 * too bad if we walk over the top of system memory, we don't
-	 * use DMA without a remapped anyway.
-	 * Affected chips are rv280, all r3xx, and all r4xx, but not IGP
-	 */
-	/* FGLRX seems to setup like this, VRAM a 0, then GART.
-	 */
-	/*
-	 * Note: from R6xx the address space is 40bits but here we only
-	 * use 32bits (still have to see a card which would exhaust 4G
-	 * address space).
-	 */
-	if (rdev->mc.vram_location != 0xFFFFFFFFUL) {
-		/* vram location was already setup try to put gtt after
-		 * if it fits */
-		tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size;
-		tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1);
-		if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
-			rdev->mc.gtt_location = tmp;
-		} else {
-			if (rdev->mc.gtt_size >= rdev->mc.vram_location) {
-				printk(KERN_ERR "[drm] GTT too big to fit "
-				       "before or after vram location.\n");
-				return -EINVAL;
-			}
-			rdev->mc.gtt_location = 0;
-		}
-	} else if (rdev->mc.gtt_location != 0xFFFFFFFFUL) {
-		/* gtt location was already setup try to put vram before
-		 * if it fits */
-		if (rdev->mc.mc_vram_size < rdev->mc.gtt_location) {
-			rdev->mc.vram_location = 0;
-		} else {
-			tmp = rdev->mc.gtt_location + rdev->mc.gtt_size;
-			tmp += (rdev->mc.mc_vram_size - 1);
-			tmp &= ~(rdev->mc.mc_vram_size - 1);
-			if ((0xFFFFFFFFUL - tmp) >= rdev->mc.mc_vram_size) {
-				rdev->mc.vram_location = tmp;
-			} else {
-				printk(KERN_ERR "[drm] vram too big to fit "
-				       "before or after GTT location.\n");
-				return -EINVAL;
-			}
+/**
+ * radeon_gtt_location - try to find GTT location
+ * @rdev: radeon device structure holding all necessary informations
+ * @mc: memory controller structure holding memory informations
+ *
+ * Function will place try to place GTT before or after VRAM.
+ *
+ * If GTT size is bigger than space left then we ajust GTT size.
+ * Thus function will never fails.
+ *
+ * FIXME: when reducing GTT size align new size on power of 2.
+ */
+void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
+{
+	u64 size_af, size_bf;
+
+	size_af = 0xFFFFFFFF - mc->vram_end;
+	size_bf = mc->vram_start;
+	if (size_bf > size_af) {
+		if (mc->gtt_size > size_bf) {
+			dev_warn(rdev->dev, "limiting GTT\n");
+			mc->gtt_size = size_bf;
 		}
+		mc->gtt_start = mc->vram_start - mc->gtt_size;
 	} else {
-		rdev->mc.vram_location = 0;
-		tmp = rdev->mc.mc_vram_size;
-		tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1);
-		rdev->mc.gtt_location = tmp;
+		if (mc->gtt_size > size_af) {
+			dev_warn(rdev->dev, "limiting GTT\n");
+			mc->gtt_size = size_af;
+		}
+		mc->gtt_start = mc->vram_end + 1;
 	}
-	rdev->mc.vram_start = rdev->mc.vram_location;
-	rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
-	rdev->mc.gtt_start = rdev->mc.gtt_location;
-	rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
-	DRM_INFO("radeon: VRAM %uM\n", (unsigned)(rdev->mc.mc_vram_size >> 20));
-	DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n",
-		 (unsigned)rdev->mc.vram_location,
-		 (unsigned)(rdev->mc.vram_location + rdev->mc.mc_vram_size - 1));
-	DRM_INFO("radeon: GTT %uM\n", (unsigned)(rdev->mc.gtt_size >> 20));
-	DRM_INFO("radeon: GTT from 0x%08X to 0x%08X\n",
-		 (unsigned)rdev->mc.gtt_location,
-		 (unsigned)(rdev->mc.gtt_location + rdev->mc.gtt_size - 1));
-	return 0;
+	mc->gtt_end = mc->gtt_start + mc->gtt_size - 1;
+	dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n",
+			mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end);
 }
 
-
 /*
  * GPU helpers function.
  */
@@ -182,7 +254,16 @@ bool radeon_card_posted(struct radeon_de
 	uint32_t reg;
 
 	/* first check CRTCs */
-	if (ASIC_IS_AVIVO(rdev)) {
+	if (ASIC_IS_DCE4(rdev)) {
+		reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) |
+			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) |
+			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) |
+			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) |
+			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) |
+			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
+		if (reg & EVERGREEN_CRTC_MASTER_EN)
+			return true;
+	} else if (ASIC_IS_AVIVO(rdev)) {
 		reg = RREG32(AVIVO_D1CRTC_CONTROL) |
 		      RREG32(AVIVO_D2CRTC_CONTROL);
 		if (reg & AVIVO_CRTC_EN) {
@@ -209,6 +290,36 @@ bool radeon_card_posted(struct radeon_de
 
 }
 
+void radeon_update_bandwidth_info(struct radeon_device *rdev)
+{
+	fixed20_12 a;
+	u32 sclk, mclk;
+
+	if (rdev->flags & RADEON_IS_IGP) {
+		sclk = radeon_get_engine_clock(rdev);
+		mclk = rdev->clock.default_mclk;
+
+		a.full = rfixed_const(100);
+		rdev->pm.sclk.full = rfixed_const(sclk);
+		rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+		rdev->pm.mclk.full = rfixed_const(mclk);
+		rdev->pm.mclk.full = rfixed_div(rdev->pm.mclk, a);
+
+		a.full = rfixed_const(16);
+		/* core_bandwidth = sclk(Mhz) * 16 */
+		rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a);
+	} else {
+		sclk = radeon_get_engine_clock(rdev);
+		mclk = radeon_get_memory_clock(rdev);
+
+		a.full = rfixed_const(100);
+		rdev->pm.sclk.full = rfixed_const(sclk);
+		rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+		rdev->pm.mclk.full = rfixed_const(mclk);
+		rdev->pm.mclk.full = rfixed_div(rdev->pm.mclk, a);
+	}
+}
+
 bool radeon_boot_test_post_card(struct radeon_device *rdev)
 {
 	if (radeon_card_posted(rdev))
@@ -229,6 +340,8 @@ bool radeon_boot_test_post_card(struct r
 
 int radeon_dummy_page_init(struct radeon_device *rdev)
 {
+	if (rdev->dummy_page.page)
+		return 0;
 	rdev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO);
 	if (rdev->dummy_page.page == NULL)
 		return -ENOMEM;
@@ -253,173 +366,6 @@ void radeon_dummy_page_fini(struct radeo
 }
 
 
-/*
- * Registers accessors functions.
- */
-uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg)
-{
-	DRM_ERROR("Invalid callback to read register 0x%04X\n", reg);
-	BUG_ON(1);
-	return 0;
-}
-
-void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
-{
-	DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n",
-		  reg, v);
-	BUG_ON(1);
-}
-
-void radeon_register_accessor_init(struct radeon_device *rdev)
-{
-	rdev->mc_rreg = &radeon_invalid_rreg;
-	rdev->mc_wreg = &radeon_invalid_wreg;
-	rdev->pll_rreg = &radeon_invalid_rreg;
-	rdev->pll_wreg = &radeon_invalid_wreg;
-	rdev->pciep_rreg = &radeon_invalid_rreg;
-	rdev->pciep_wreg = &radeon_invalid_wreg;
-
-	/* Don't change order as we are overridding accessor. */
-	if (rdev->family < CHIP_RV515) {
-		rdev->pcie_reg_mask = 0xff;
-	} else {
-		rdev->pcie_reg_mask = 0x7ff;
-	}
-	/* FIXME: not sure here */
-	if (rdev->family <= CHIP_R580) {
-		rdev->pll_rreg = &r100_pll_rreg;
-		rdev->pll_wreg = &r100_pll_wreg;
-	}
-	if (rdev->family >= CHIP_R420) {
-		rdev->mc_rreg = &r420_mc_rreg;
-		rdev->mc_wreg = &r420_mc_wreg;
-	}
-	if (rdev->family >= CHIP_RV515) {
-		rdev->mc_rreg = &rv515_mc_rreg;
-		rdev->mc_wreg = &rv515_mc_wreg;
-	}
-	if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) {
-		rdev->mc_rreg = &rs400_mc_rreg;
-		rdev->mc_wreg = &rs400_mc_wreg;
-	}
-	if (rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) {
-		rdev->mc_rreg = &rs690_mc_rreg;
-		rdev->mc_wreg = &rs690_mc_wreg;
-	}
-	if (rdev->family == CHIP_RS600) {
-		rdev->mc_rreg = &rs600_mc_rreg;
-		rdev->mc_wreg = &rs600_mc_wreg;
-	}
-	if (rdev->family >= CHIP_R600) {
-		rdev->pciep_rreg = &r600_pciep_rreg;
-		rdev->pciep_wreg = &r600_pciep_wreg;
-	}
-}
-
-
-/*
- * ASIC
- */
-int radeon_asic_init(struct radeon_device *rdev)
-{
-	radeon_register_accessor_init(rdev);
-	switch (rdev->family) {
-	case CHIP_R100:
-	case CHIP_RV100:
-	case CHIP_RS100:
-	case CHIP_RV200:
-	case CHIP_RS200:
-	case CHIP_R200:
-	case CHIP_RV250:
-	case CHIP_RS300:
-	case CHIP_RV280:
-		rdev->asic = &r100_asic;
-		break;
-	case CHIP_R300:
-	case CHIP_R350:
-	case CHIP_RV350:
-	case CHIP_RV380:
-		rdev->asic = &r300_asic;
-		if (rdev->flags & RADEON_IS_PCIE) {
-			rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
-			rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
-		}
-		break;
-	case CHIP_R420:
-	case CHIP_R423:
-	case CHIP_RV410:
-		rdev->asic = &r420_asic;
-		break;
-	case CHIP_RS400:
-	case CHIP_RS480:
-		rdev->asic = &rs400_asic;
-		break;
-	case CHIP_RS600:
-		rdev->asic = &rs600_asic;
-		break;
-	case CHIP_RS690:
-	case CHIP_RS740:
-		rdev->asic = &rs690_asic;
-		break;
-	case CHIP_RV515:
-		rdev->asic = &rv515_asic;
-		break;
-	case CHIP_R520:
-	case CHIP_RV530:
-	case CHIP_RV560:
-	case CHIP_RV570:
-	case CHIP_R580:
-		rdev->asic = &r520_asic;
-		break;
-	case CHIP_R600:
-	case CHIP_RV610:
-	case CHIP_RV630:
-	case CHIP_RV620:
-	case CHIP_RV635:
-	case CHIP_RV670:
-	case CHIP_RS780:
-	case CHIP_RS880:
-		rdev->asic = &r600_asic;
-		break;
-	case CHIP_RV770:
-	case CHIP_RV730:
-	case CHIP_RV710:
-	case CHIP_RV740:
-		rdev->asic = &rv770_asic;
-		break;
-	default:
-		/* FIXME: not supported yet */
-		return -EINVAL;
-	}
-
-	if (rdev->flags & RADEON_IS_IGP) {
-		rdev->asic->get_memory_clock = NULL;
-		rdev->asic->set_memory_clock = NULL;
-	}
-
-	return 0;
-}
-
-
-/*
- * Wrapper around modesetting bits.
- */
-int radeon_clocks_init(struct radeon_device *rdev)
-{
-	int r;
-
-	r = radeon_static_clocks_init(rdev->ddev);
-	if (r) {
-		return r;
-	}
-	DRM_INFO("Clocks initialized !\n");
-	return 0;
-}
-
-void radeon_clocks_fini(struct radeon_device *rdev)
-{
-}
-
 /* ATOM accessor methods */
 static uint32_t cail_pll_read(struct card_info *info, uint32_t reg)
 {
@@ -524,29 +470,6 @@ static unsigned int radeon_vga_set_decod
 		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
 }
 
-void radeon_agp_disable(struct radeon_device *rdev)
-{
-	rdev->flags &= ~RADEON_IS_AGP;
-	if (rdev->family >= CHIP_R600) {
-		DRM_INFO("Forcing AGP to PCIE mode\n");
-		rdev->flags |= RADEON_IS_PCIE;
-	} else if (rdev->family >= CHIP_RV515 ||
-			rdev->family == CHIP_RV380 ||
-			rdev->family == CHIP_RV410 ||
-			rdev->family == CHIP_R423) {
-		DRM_INFO("Forcing AGP to PCIE mode\n");
-		rdev->flags |= RADEON_IS_PCIE;
-		rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
-		rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
-	} else {
-		DRM_INFO("Forcing AGP to PCI mode\n");
-		rdev->flags |= RADEON_IS_PCI;
-		rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
-		rdev->asic->gart_set_page = &r100_pci_gart_set_page;
-	}
-	rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
-}
-
 void radeon_check_arguments(struct radeon_device *rdev)
 {
 	/* vramlimit must be a power of two */
@@ -613,6 +536,36 @@ void radeon_check_arguments(struct radeo
 	}
 }
 
+static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	struct radeon_device *rdev = dev->dev_private;
+	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
+	if (state == VGA_SWITCHEROO_ON) {
+		printk(KERN_INFO "radeon: switched on\n");
+		/* don't suspend or resume card normally */
+		rdev->powered_down = false;
+		radeon_resume_kms(dev);
+	} else {
+		printk(KERN_INFO "radeon: switched off\n");
+		radeon_suspend_kms(dev, pmm);
+		/* don't suspend or resume card normally */
+		rdev->powered_down = true;
+	}
+}
+
+static bool radeon_switcheroo_can_switch(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	bool can_switch;
+
+	spin_lock(&dev->count_lock);
+	can_switch = (dev->open_count == 0);
+	spin_unlock(&dev->count_lock);
+	return can_switch;
+}
+
+
 int radeon_device_init(struct radeon_device *rdev,
 		       struct drm_device *ddev,
 		       struct pci_dev *pdev,
@@ -621,7 +574,6 @@ int radeon_device_init(struct radeon_dev
 	int r;
 	int dma_bits;
 
-	DRM_INFO("radeon: Initializing kernel modesetting.\n");
 	rdev->shutdown = false;
 	rdev->dev = &pdev->dev;
 	rdev->ddev = ddev;
@@ -633,16 +585,23 @@ int radeon_device_init(struct radeon_dev
 	rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
 	rdev->gpu_lockup = false;
 	rdev->accel_working = false;
+
+	DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n",
+		radeon_family_name[rdev->family], pdev->vendor, pdev->device);
+
 	/* mutex initialization are all done here so we
 	 * can recall function without having locking issues */
 	mutex_init(&rdev->cs_mutex);
 	mutex_init(&rdev->ib_pool.mutex);
 	mutex_init(&rdev->cp.mutex);
+	mutex_init(&rdev->dc_hw_i2c_mutex);
 	if (rdev->family >= CHIP_R600)
 		spin_lock_init(&rdev->ih.lock);
 	mutex_init(&rdev->gem.mutex);
+	mutex_init(&rdev->pm.mutex);
 	rwlock_init(&rdev->fence_drv.lock);
 	INIT_LIST_HEAD(&rdev->gem.objects);
+	init_waitqueue_head(&rdev->irq.vblank_queue);
 
 	/* setup workqueue */
 	rdev->wq = create_workqueue("radeon");
@@ -655,6 +614,14 @@ int radeon_device_init(struct radeon_dev
 		return r;
 	radeon_check_arguments(rdev);
 
+	/* all of the newer IGP chips have an internal gart
+	 * However some rs4xx report as AGP, so remove that here.
+	 */
+	if ((rdev->family >= CHIP_RS400) &&
+	    (rdev->flags & RADEON_IS_IGP)) {
+		rdev->flags &= ~RADEON_IS_AGP;
+	}
+
 	if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) {
 		radeon_agp_disable(rdev);
 	}
@@ -692,6 +659,9 @@ int radeon_device_init(struct radeon_dev
 	/* this will fail for cards that aren't VGA class devices, just
 	 * ignore it */
 	vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
+	vga_switcheroo_register_client(rdev->pdev,
+				       radeon_switcheroo_set_state,
+				       radeon_switcheroo_can_switch);
 
 	r = radeon_init(rdev);
 	if (r)
@@ -723,6 +693,7 @@ void radeon_device_fini(struct radeon_de
 	rdev->shutdown = true;
 	radeon_fini(rdev);
 	destroy_workqueue(rdev->wq);
+	vga_switcheroo_unregister_client(rdev->pdev);
 	vga_client_register(rdev->pdev, NULL, NULL, NULL);
 	iounmap(rdev->rmmio);
 	rdev->rmmio = NULL;
@@ -746,6 +717,8 @@ int radeon_suspend_kms(struct drm_device
 	}
 	rdev = dev->dev_private;
 
+	if (rdev->powered_down)
+		return 0;
 	/* unpin the front buffers */
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb);
@@ -791,6 +764,9 @@ int radeon_resume_kms(struct drm_device
 {
 	struct radeon_device *rdev = dev->dev_private;
 
+	if (rdev->powered_down)
+		return 0;
+
 	acquire_console_sem();
 	pci_set_power_state(dev->pdev, PCI_D0);
 	pci_restore_state(dev->pdev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_display.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_display.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_display.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_display.c	2010-05-16 17:17:36.000000000 -0400
@@ -68,6 +68,36 @@ static void avivo_crtc_load_lut(struct d
 	WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id);
 }
 
+static void evergreen_crtc_load_lut(struct drm_crtc *crtc)
+{
+	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	int i;
+
+	DRM_DEBUG("%d\n", radeon_crtc->crtc_id);
+	WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0);
+
+	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
+	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0);
+	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0);
+
+	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff);
+	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
+	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
+
+	WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0);
+	WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
+
+	WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
+	for (i = 0; i < 256; i++) {
+		WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
+		       (radeon_crtc->lut_r[i] << 20) |
+		       (radeon_crtc->lut_g[i] << 10) |
+		       (radeon_crtc->lut_b[i] << 0));
+	}
+}
+
 static void legacy_crtc_load_lut(struct drm_crtc *crtc)
 {
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
@@ -100,7 +130,9 @@ void radeon_crtc_load_lut(struct drm_crt
 	if (!crtc->enabled)
 		return;
 
-	if (ASIC_IS_AVIVO(rdev))
+	if (ASIC_IS_DCE4(rdev))
+		evergreen_crtc_load_lut(crtc);
+	else if (ASIC_IS_AVIVO(rdev))
 		avivo_crtc_load_lut(crtc);
 	else
 		legacy_crtc_load_lut(crtc);
@@ -336,10 +368,9 @@ static bool radeon_setup_enc_conn(struct
 
 	if (rdev->bios) {
 		if (rdev->is_atom_bios) {
-			if (rdev->family >= CHIP_R600)
+			ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
+			if (ret == false)
 				ret = radeon_get_atom_connector_info_from_object_table(dev);
-			else
-				ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
 		} else {
 			ret = radeon_get_legacy_connector_info_from_bios(dev);
 			if (ret == false)
@@ -361,6 +392,8 @@ static bool radeon_setup_enc_conn(struct
 
 int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
 {
+	struct drm_device *dev = radeon_connector->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
 	int ret = 0;
 
 	if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
@@ -373,11 +406,11 @@ int radeon_ddc_get_modes(struct radeon_c
 	if (!radeon_connector->ddc_bus)
 		return -1;
 	if (!radeon_connector->edid) {
-		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 		radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
-		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 	}
-
+	/* some servers provide a hardcoded edid in rom for KVMs */
+	if (!radeon_connector->edid)
+		radeon_connector->edid = radeon_combios_get_hardcoded_edid(rdev);
 	if (radeon_connector->edid) {
 		drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid);
 		ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid);
@@ -395,9 +428,7 @@ static int radeon_ddc_dump(struct drm_co
 
 	if (!radeon_connector->ddc_bus)
 		return -1;
-	radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 	edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter);
-	radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 	if (edid) {
 		kfree(edid);
 	}
@@ -414,13 +445,13 @@ static inline uint32_t radeon_div(uint64
 	return n;
 }
 
-void radeon_compute_pll(struct radeon_pll *pll,
-			uint64_t freq,
-			uint32_t *dot_clock_p,
-			uint32_t *fb_div_p,
-			uint32_t *frac_fb_div_p,
-			uint32_t *ref_div_p,
-			uint32_t *post_div_p)
+static void radeon_compute_pll_legacy(struct radeon_pll *pll,
+				      uint64_t freq,
+				      uint32_t *dot_clock_p,
+				      uint32_t *fb_div_p,
+				      uint32_t *frac_fb_div_p,
+				      uint32_t *ref_div_p,
+				      uint32_t *post_div_p)
 {
 	uint32_t min_ref_div = pll->min_ref_div;
 	uint32_t max_ref_div = pll->max_ref_div;
@@ -437,10 +468,19 @@ void radeon_compute_pll(struct radeon_pl
 	uint32_t best_error = 0xffffffff;
 	uint32_t best_vco_diff = 1;
 	uint32_t post_div;
+	u32 pll_out_min, pll_out_max;
 
 	DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);
 	freq = freq * 1000;
 
+	if (pll->flags & RADEON_PLL_IS_LCD) {
+		pll_out_min = pll->lcd_pll_out_min;
+		pll_out_max = pll->lcd_pll_out_max;
+	} else {
+		pll_out_min = pll->pll_out_min;
+		pll_out_max = pll->pll_out_max;
+	}
+
 	if (pll->flags & RADEON_PLL_USE_REF_DIV)
 		min_ref_div = max_ref_div = pll->reference_div;
 	else {
@@ -504,10 +544,10 @@ void radeon_compute_pll(struct radeon_pl
 				tmp = (uint64_t)pll->reference_freq * feedback_div;
 				vco = radeon_div(tmp, ref_div);
 
-				if (vco < pll->pll_out_min) {
+				if (vco < pll_out_min) {
 					min_feed_div = feedback_div + 1;
 					continue;
-				} else if (vco > pll->pll_out_max) {
+				} else if (vco > pll_out_max) {
 					max_feed_div = feedback_div;
 					continue;
 				}
@@ -580,95 +620,212 @@ void radeon_compute_pll(struct radeon_pl
 	*post_div_p = best_post_div;
 }
 
-void radeon_compute_pll_avivo(struct radeon_pll *pll,
-			      uint64_t freq,
-			      uint32_t *dot_clock_p,
-			      uint32_t *fb_div_p,
-			      uint32_t *frac_fb_div_p,
-			      uint32_t *ref_div_p,
-			      uint32_t *post_div_p)
+static bool
+calc_fb_div(struct radeon_pll *pll,
+	    uint32_t freq,
+            uint32_t post_div,
+            uint32_t ref_div,
+            uint32_t *fb_div,
+            uint32_t *fb_div_frac)
 {
-	fixed20_12 m, n, frac_n, p, f_vco, f_pclk, best_freq;
-	fixed20_12 pll_out_max, pll_out_min;
-	fixed20_12 pll_in_max, pll_in_min;
-	fixed20_12 reference_freq;
-	fixed20_12 error, ffreq, a, b;
+	fixed20_12 feedback_divider, a, b;
+	u32 vco_freq;
+
+	vco_freq = freq * post_div;
+	/* feedback_divider = vco_freq * ref_div / pll->reference_freq; */
+	a.full = rfixed_const(pll->reference_freq);
+	feedback_divider.full = rfixed_const(vco_freq);
+	feedback_divider.full = rfixed_div(feedback_divider, a);
+	a.full = rfixed_const(ref_div);
+	feedback_divider.full = rfixed_mul(feedback_divider, a);
+
+	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
+		/* feedback_divider = floor((feedback_divider * 10.0) + 0.5) * 0.1; */
+		a.full = rfixed_const(10);
+		feedback_divider.full = rfixed_mul(feedback_divider, a);
+		feedback_divider.full += rfixed_const_half(0);
+		feedback_divider.full = rfixed_floor(feedback_divider);
+		feedback_divider.full = rfixed_div(feedback_divider, a);
+
+		/* *fb_div = floor(feedback_divider); */
+		a.full = rfixed_floor(feedback_divider);
+		*fb_div = rfixed_trunc(a);
+		/* *fb_div_frac = fmod(feedback_divider, 1.0) * 10.0; */
+		a.full = rfixed_const(10);
+		b.full = rfixed_mul(feedback_divider, a);
+
+		feedback_divider.full = rfixed_floor(feedback_divider);
+		feedback_divider.full = rfixed_mul(feedback_divider, a);
+		feedback_divider.full = b.full - feedback_divider.full;
+		*fb_div_frac = rfixed_trunc(feedback_divider);
+	} else {
+		/* *fb_div = floor(feedback_divider + 0.5); */
+		feedback_divider.full += rfixed_const_half(0);
+		feedback_divider.full = rfixed_floor(feedback_divider);
+
+		*fb_div = rfixed_trunc(feedback_divider);
+		*fb_div_frac = 0;
+	}
+
+	if (((*fb_div) < pll->min_feedback_div) || ((*fb_div) > pll->max_feedback_div))
+		return false;
+	else
+		return true;
+}
+
+static bool
+calc_fb_ref_div(struct radeon_pll *pll,
+		uint32_t freq,
+		uint32_t post_div,
+		uint32_t *fb_div,
+                uint32_t *fb_div_frac,
+                uint32_t *ref_div)
+{
+	fixed20_12 ffreq, max_error, error, pll_out, a;
+	u32 vco;
+	u32 pll_out_min, pll_out_max;
+
+	if (pll->flags & RADEON_PLL_IS_LCD) {
+		pll_out_min = pll->lcd_pll_out_min;
+		pll_out_max = pll->lcd_pll_out_max;
+	} else {
+		pll_out_min = pll->pll_out_min;
+		pll_out_max = pll->pll_out_max;
+	}
 
-	pll_out_max.full = rfixed_const(pll->pll_out_max);
-	pll_out_min.full = rfixed_const(pll->pll_out_min);
-	pll_in_max.full = rfixed_const(pll->pll_in_max);
-	pll_in_min.full = rfixed_const(pll->pll_in_min);
-	reference_freq.full = rfixed_const(pll->reference_freq);
-	do_div(freq, 10);
 	ffreq.full = rfixed_const(freq);
-	error.full = rfixed_const(100 * 100);
+	/* max_error = ffreq * 0.0025; */
+	a.full = rfixed_const(400);
+	max_error.full = rfixed_div(ffreq, a);
 
-	/* max p */
-	p.full = rfixed_div(pll_out_max, ffreq);
-	p.full = rfixed_floor(p);
+	for ((*ref_div) = pll->min_ref_div; (*ref_div) < pll->max_ref_div; ++(*ref_div)) {
+		if (calc_fb_div(pll, freq, post_div, (*ref_div), fb_div, fb_div_frac)) {
+			vco = pll->reference_freq * (((*fb_div) * 10) + (*fb_div_frac));
+			vco = vco / ((*ref_div) * 10);
 
-	/* min m */
-	m.full = rfixed_div(reference_freq, pll_in_max);
-	m.full = rfixed_ceil(m);
+			if ((vco < pll_out_min) || (vco > pll_out_max))
+				continue;
 
-	while (1) {
-		n.full = rfixed_div(ffreq, reference_freq);
-		n.full = rfixed_mul(n, m);
-		n.full = rfixed_mul(n, p);
+			/* pll_out = vco / post_div; */
+			a.full = rfixed_const(post_div);
+			pll_out.full = rfixed_const(vco);
+			pll_out.full = rfixed_div(pll_out, a);
 
-		f_vco.full = rfixed_div(n, m);
-		f_vco.full = rfixed_mul(f_vco, reference_freq);
+			if (pll_out.full >= ffreq.full) {
+				error.full = pll_out.full - ffreq.full;
+				if (error.full <= max_error.full)
+					return true;
+			}
+		}
+	}
+	return false;
+}
 
-		f_pclk.full = rfixed_div(f_vco, p);
+static void radeon_compute_pll_new(struct radeon_pll *pll,
+				   uint64_t freq,
+				   uint32_t *dot_clock_p,
+				   uint32_t *fb_div_p,
+				   uint32_t *frac_fb_div_p,
+				   uint32_t *ref_div_p,
+				   uint32_t *post_div_p)
+{
+	u32 fb_div = 0, fb_div_frac = 0, post_div = 0, ref_div = 0;
+	u32 best_freq = 0, vco_frequency;
+	u32 pll_out_min, pll_out_max;
 
-		if (f_pclk.full > ffreq.full)
-			error.full = f_pclk.full - ffreq.full;
-		else
-			error.full = ffreq.full - f_pclk.full;
-		error.full = rfixed_div(error, f_pclk);
-		a.full = rfixed_const(100 * 100);
-		error.full = rfixed_mul(error, a);
+	if (pll->flags & RADEON_PLL_IS_LCD) {
+		pll_out_min = pll->lcd_pll_out_min;
+		pll_out_max = pll->lcd_pll_out_max;
+	} else {
+		pll_out_min = pll->pll_out_min;
+		pll_out_max = pll->pll_out_max;
+	}
 
-		a.full = rfixed_mul(m, p);
-		a.full = rfixed_div(n, a);
-		best_freq.full = rfixed_mul(reference_freq, a);
+	/* freq = freq / 10; */
+	do_div(freq, 10);
 
-		if (rfixed_trunc(error) < 25)
-			break;
+	if (pll->flags & RADEON_PLL_USE_POST_DIV) {
+		post_div = pll->post_div;
+		if ((post_div < pll->min_post_div) || (post_div > pll->max_post_div))
+			goto done;
 
-		a.full = rfixed_const(1);
-		m.full = m.full + a.full;
-		a.full = rfixed_div(reference_freq, m);
-		if (a.full >= pll_in_min.full)
-			continue;
+		vco_frequency = freq * post_div;
+		if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max))
+			goto done;
 
-		m.full = rfixed_div(reference_freq, pll_in_max);
-		m.full = rfixed_ceil(m);
-		a.full= rfixed_const(1);
-		p.full = p.full - a.full;
-		a.full = rfixed_mul(p, ffreq);
-		if (a.full >= pll_out_min.full)
-			continue;
-		else {
-			DRM_ERROR("Unable to find pll dividers\n");
-			break;
+		if (pll->flags & RADEON_PLL_USE_REF_DIV) {
+			ref_div = pll->reference_div;
+			if ((ref_div < pll->min_ref_div) || (ref_div > pll->max_ref_div))
+				goto done;
+			if (!calc_fb_div(pll, freq, post_div, ref_div, &fb_div, &fb_div_frac))
+				goto done;
+		}
+	} else {
+		for (post_div = pll->max_post_div; post_div >= pll->min_post_div; --post_div) {
+			if (pll->flags & RADEON_PLL_LEGACY) {
+				if ((post_div == 5) ||
+				    (post_div == 7) ||
+				    (post_div == 9) ||
+				    (post_div == 10) ||
+				    (post_div == 11))
+					continue;
+			}
+
+			if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1))
+				continue;
+
+			vco_frequency = freq * post_div;
+			if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max))
+				continue;
+			if (pll->flags & RADEON_PLL_USE_REF_DIV) {
+				ref_div = pll->reference_div;
+				if ((ref_div < pll->min_ref_div) || (ref_div > pll->max_ref_div))
+					goto done;
+				if (calc_fb_div(pll, freq, post_div, ref_div, &fb_div, &fb_div_frac))
+					break;
+			} else {
+				if (calc_fb_ref_div(pll, freq, post_div, &fb_div, &fb_div_frac, &ref_div))
+					break;
+			}
 		}
 	}
 
-	a.full = rfixed_const(10);
-	b.full = rfixed_mul(n, a);
+	best_freq = pll->reference_freq * 10 * fb_div;
+	best_freq += pll->reference_freq * fb_div_frac;
+	best_freq = best_freq / (ref_div * post_div);
 
-	frac_n.full = rfixed_floor(n);
-	frac_n.full = rfixed_mul(frac_n, a);
-	frac_n.full = b.full - frac_n.full;
+done:
+	if (best_freq == 0)
+		DRM_ERROR("Couldn't find valid PLL dividers\n");
 
-	*dot_clock_p = rfixed_trunc(best_freq);
-	*fb_div_p = rfixed_trunc(n);
-	*frac_fb_div_p = rfixed_trunc(frac_n);
-	*ref_div_p = rfixed_trunc(m);
-	*post_div_p = rfixed_trunc(p);
+	*dot_clock_p = best_freq / 10;
+	*fb_div_p = fb_div;
+	*frac_fb_div_p = fb_div_frac;
+	*ref_div_p = ref_div;
+	*post_div_p = post_div;
 
-	DRM_DEBUG("%u %d.%d, %d, %d\n", *dot_clock_p * 10, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p);
+	DRM_DEBUG("%u %d.%d, %d, %d\n", *dot_clock_p, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p);
+}
+
+void radeon_compute_pll(struct radeon_pll *pll,
+			uint64_t freq,
+			uint32_t *dot_clock_p,
+			uint32_t *fb_div_p,
+			uint32_t *frac_fb_div_p,
+			uint32_t *ref_div_p,
+			uint32_t *post_div_p)
+{
+	switch (pll->algo) {
+	case PLL_ALGO_NEW:
+		radeon_compute_pll_new(pll, freq, dot_clock_p, fb_div_p,
+				       frac_fb_div_p, ref_div_p, post_div_p);
+		break;
+	case PLL_ALGO_LEGACY:
+	default:
+		radeon_compute_pll_legacy(pll, freq, dot_clock_p, fb_div_p,
+					  frac_fb_div_p, ref_div_p, post_div_p);
+		break;
+	}
 }
 
 static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
@@ -679,11 +836,8 @@ static void radeon_user_framebuffer_dest
 	if (fb->fbdev)
 		radeonfb_remove(dev, fb);
 
-	if (radeon_fb->obj) {
-		mutex_lock(&dev->struct_mutex);
-		drm_gem_object_unreference(radeon_fb->obj);
-		mutex_unlock(&dev->struct_mutex);
-	}
+	if (radeon_fb->obj)
+		drm_gem_object_unreference_unlocked(radeon_fb->obj);
 	drm_framebuffer_cleanup(fb);
 	kfree(radeon_fb);
 }
@@ -817,9 +971,26 @@ static int radeon_modeset_create_props(s
 	return 0;
 }
 
+void radeon_update_display_priority(struct radeon_device *rdev)
+{
+	/* adjustment options for the display watermarks */
+	if ((radeon_disp_priority == 0) || (radeon_disp_priority > 2)) {
+		/* set display priority to high for r3xx, rv515 chips
+		 * this avoids flickering due to underflow to the
+		 * display controllers during heavy acceleration.
+		 */
+		if (ASIC_IS_R300(rdev) || (rdev->family == CHIP_RV515))
+			rdev->disp_priority = 2;
+		else
+			rdev->disp_priority = 0;
+	} else
+		rdev->disp_priority = radeon_disp_priority;
+
+}
+
 int radeon_modeset_init(struct radeon_device *rdev)
 {
-	int num_crtc = 2, i;
+	int i;
 	int ret;
 
 	drm_mode_config_init(rdev->ddev);
@@ -842,11 +1013,14 @@ int radeon_modeset_init(struct radeon_de
 		return ret;
 	}
 
-	if (rdev->flags & RADEON_SINGLE_CRTC)
-		num_crtc = 1;
+	/* check combios for a valid hardcoded EDID - Sun servers */
+	if (!rdev->is_atom_bios) {
+		/* check for hardcoded EDID in BIOS */
+		radeon_combios_check_hardcoded_edid(rdev);
+	}
 
 	/* allocate crtcs */
-	for (i = 0; i < num_crtc; i++) {
+	for (i = 0; i < rdev->num_crtc; i++) {
 		radeon_crtc_init(rdev->ddev, i);
 	}
 
@@ -863,6 +1037,8 @@ int radeon_modeset_init(struct radeon_de
 
 void radeon_modeset_fini(struct radeon_device *rdev)
 {
+	kfree(rdev->mode_info.bios_hardcoded_edid);
+
 	if (rdev->mode_info.mode_config_initialized) {
 		radeon_hpd_fini(rdev);
 		drm_mode_config_cleanup(rdev->ddev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_drv.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_drv.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_drv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,9 +40,13 @@
 
 /*
  * KMS wrapper.
+ * - 2.0.0 - initial interface
+ * - 2.1.0 - add square tiling interface
+ * - 2.2.0 - add r6xx/r7xx const buffer support
+ * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs
  */
 #define KMS_DRIVER_MAJOR	2
-#define KMS_DRIVER_MINOR	0
+#define KMS_DRIVER_MINOR	3
 #define KMS_DRIVER_PATCHLEVEL	0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
@@ -86,8 +90,11 @@ int radeon_benchmarking = 0;
 int radeon_testing = 0;
 int radeon_connector_table = 0;
 int radeon_tv = 1;
-int radeon_new_pll = 1;
+int radeon_new_pll = -1;
+int radeon_dynpm = -1;
 int radeon_audio = 1;
+int radeon_disp_priority = 0;
+int radeon_hw_i2c = 0;
 
 MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
 module_param_named(no_wb, radeon_no_wb, int, 0444);
@@ -122,12 +129,21 @@ module_param_named(connector_table, rade
 MODULE_PARM_DESC(tv, "TV enable (0 = disable)");
 module_param_named(tv, radeon_tv, int, 0444);
 
-MODULE_PARM_DESC(new_pll, "Select new PLL code for AVIVO chips");
+MODULE_PARM_DESC(new_pll, "Select new PLL code");
 module_param_named(new_pll, radeon_new_pll, int, 0444);
 
+MODULE_PARM_DESC(dynpm, "Disable/Enable dynamic power management (1 = enable)");
+module_param_named(dynpm, radeon_dynpm, int, 0444);
+
 MODULE_PARM_DESC(audio, "Audio enable (0 = disable)");
 module_param_named(audio, radeon_audio, int, 0444);
 
+MODULE_PARM_DESC(disp_priority, "Display Priority (0 = auto, 1 = normal, 2 = high)");
+module_param_named(disp_priority, radeon_disp_priority, int, 0444);
+
+MODULE_PARM_DESC(hw_i2c, "hw i2c engine enable (0 = disable)");
+module_param_named(hw_i2c, radeon_hw_i2c, int, 0444);
+
 static int radeon_suspend(struct drm_device *dev, pm_message_t state)
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -200,6 +216,7 @@ static struct drm_driver driver_old = {
 		 .mmap = drm_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
+		 .read = drm_read,
 #ifdef CONFIG_COMPAT
 		 .compat_ioctl = radeon_compat_ioctl,
 #endif
@@ -288,6 +305,7 @@ static struct drm_driver kms_driver = {
 		 .mmap = radeon_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
+		 .read = drm_read,
 #ifdef CONFIG_COMPAT
 		 .compat_ioctl = radeon_kms_compat_ioctl,
 #endif
@@ -339,6 +357,7 @@ static int __init radeon_init(void)
 		driver = &kms_driver;
 		driver->driver_features |= DRIVER_MODESET;
 		driver->num_ioctls = radeon_max_kms_ioctl;
+		radeon_register_atpx_handler();
 	}
 	/* if the vga console setting is enabled still
 	 * let modprobe override it */
@@ -348,6 +367,7 @@ static int __init radeon_init(void)
 static void __exit radeon_exit(void)
 {
 	drm_exit(driver);
+	radeon_unregister_atpx_handler();
 }
 
 module_init(radeon_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_drv.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_drv.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_drv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_drv.h	2010-05-16 17:17:36.000000000 -0400
@@ -107,9 +107,10 @@
  * 1.30- Add support for occlusion queries
  * 1.31- Add support for num Z pipes from GET_PARAM
  * 1.32- fixes for rv740 setup
+ * 1.33- Add r6xx/r7xx const buffer support
  */
 #define DRIVER_MAJOR		1
-#define DRIVER_MINOR		32
+#define DRIVER_MINOR		33
 #define DRIVER_PATCHLEVEL	0
 
 enum radeon_cp_microcode_version {
@@ -268,6 +269,8 @@ typedef struct drm_radeon_private {
 
 	u32 scratch_ages[5];
 
+	int have_z_offset;
+
 	/* starting from here on, data is preserved accross an open */
 	uint32_t flags;		/* see radeon_chip_flags */
 	resource_size_t fb_aper_offset;
@@ -295,6 +298,9 @@ typedef struct drm_radeon_private {
 	int r700_sc_prim_fifo_size;
 	int r700_sc_hiz_tile_fifo_size;
 	int r700_sc_earlyz_tile_fifo_fize;
+	int r600_group_size;
+	int r600_npipes;
+	int r600_nbanks;
 
 	struct mutex cs_mutex;
 	u32 cs_id_scnt;
@@ -310,9 +316,11 @@ typedef struct drm_radeon_buf_priv {
 	u32 age;
 } drm_radeon_buf_priv_t;
 
+struct drm_buffer;
+
 typedef struct drm_radeon_kcmd_buffer {
 	int bufsz;
-	char *buf;
+	struct drm_buffer *buffer;
 	int nbox;
 	struct drm_clip_rect __user *boxes;
 } drm_radeon_kcmd_buffer_t;
@@ -455,6 +463,15 @@ extern void r600_blit_swap(struct drm_de
 			   int sx, int sy, int dx, int dy,
 			   int w, int h, int src_pitch, int dst_pitch, int cpp);
 
+/* atpx handler */
+#if defined(CONFIG_VGA_SWITCHEROO)
+void radeon_register_atpx_handler(void);
+void radeon_unregister_atpx_handler(void);
+#else
+static inline void radeon_register_atpx_handler(void) {}
+static inline void radeon_unregister_atpx_handler(void) {}
+#endif
+
 /* Flags for stats.boxes
  */
 #define RADEON_BOX_DMA_IDLE      0x1
@@ -2122,4 +2139,32 @@ extern void radeon_commit_ring(drm_radeo
 	write &= mask;						\
 } while (0)
 
+/**
+ * Copy given number of dwords from drm buffer to the ring buffer.
+ */
+#define OUT_RING_DRM_BUFFER(buf, sz) do {				\
+	int _size = (sz) * 4;						\
+	struct drm_buffer *_buf = (buf);				\
+	int _part_size;							\
+	while (_size > 0) {						\
+		_part_size = _size;					\
+									\
+		if (write + _part_size/4 > mask)			\
+			_part_size = ((mask + 1) - write)*4;		\
+									\
+		if (drm_buffer_index(_buf) + _part_size > PAGE_SIZE)	\
+			_part_size = PAGE_SIZE - drm_buffer_index(_buf);\
+									\
+									\
+									\
+		memcpy(ring + write, &_buf->data[drm_buffer_page(_buf)]	\
+			[drm_buffer_index(_buf)], _part_size);		\
+									\
+		_size -= _part_size;					\
+		write = (write + _part_size/4) & mask;			\
+		drm_buffer_advance(_buf, _part_size);			\
+	}								\
+} while (0)
+
+
 #endif				/* __RADEON_DRV_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_encoders.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_encoders.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_encoders.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_encoders.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,7 +53,7 @@ static uint32_t radeon_encoder_clones(st
 	/* DVO requires 2x ppll clocks depending on tmds chip */
 	if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT)
 		return index_mask;
-	
+
 	count = -1;
 	list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) {
 		struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder);
@@ -228,6 +228,79 @@ radeon_get_connector_for_encoder(struct
 	return NULL;
 }
 
+static struct radeon_connector_atom_dig *
+radeon_get_atom_connector_priv_from_encoder(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct drm_connector *connector;
+	struct radeon_connector *radeon_connector;
+	struct radeon_connector_atom_dig *dig_connector;
+
+	if (!rdev->is_atom_bios)
+		return NULL;
+
+	connector = radeon_get_connector_for_encoder(encoder);
+	if (!connector)
+		return NULL;
+
+	radeon_connector = to_radeon_connector(connector);
+
+	if (!radeon_connector->con_priv)
+		return NULL;
+
+	dig_connector = radeon_connector->con_priv;
+
+	return dig_connector;
+}
+
+void radeon_panel_mode_fixup(struct drm_encoder *encoder,
+			     struct drm_display_mode *adjusted_mode)
+{
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+	unsigned hblank = native_mode->htotal - native_mode->hdisplay;
+	unsigned vblank = native_mode->vtotal - native_mode->vdisplay;
+	unsigned hover = native_mode->hsync_start - native_mode->hdisplay;
+	unsigned vover = native_mode->vsync_start - native_mode->vdisplay;
+	unsigned hsync_width = native_mode->hsync_end - native_mode->hsync_start;
+	unsigned vsync_width = native_mode->vsync_end - native_mode->vsync_start;
+
+	adjusted_mode->clock = native_mode->clock;
+	adjusted_mode->flags = native_mode->flags;
+
+	if (ASIC_IS_AVIVO(rdev)) {
+		adjusted_mode->hdisplay = native_mode->hdisplay;
+		adjusted_mode->vdisplay = native_mode->vdisplay;
+	}
+
+	adjusted_mode->htotal = native_mode->hdisplay + hblank;
+	adjusted_mode->hsync_start = native_mode->hdisplay + hover;
+	adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width;
+
+	adjusted_mode->vtotal = native_mode->vdisplay + vblank;
+	adjusted_mode->vsync_start = native_mode->vdisplay + vover;
+	adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width;
+
+	drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
+
+	if (ASIC_IS_AVIVO(rdev)) {
+		adjusted_mode->crtc_hdisplay = native_mode->hdisplay;
+		adjusted_mode->crtc_vdisplay = native_mode->vdisplay;
+	}
+
+	adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank;
+	adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover;
+	adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width;
+
+	adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank;
+	adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover;
+	adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width;
+
+}
+
 static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
 				   struct drm_display_mode *mode,
 				   struct drm_display_mode *adjusted_mode)
@@ -236,6 +309,9 @@ static bool radeon_atom_mode_fixup(struc
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
 
+	/* adjust pm to upcoming mode change */
+	radeon_pm_compute_clocks(rdev);
+
 	/* set the active encoder to connector routing */
 	radeon_encoder_set_active_device(encoder);
 	drm_mode_set_crtcinfo(adjusted_mode, 0);
@@ -246,18 +322,8 @@ static bool radeon_atom_mode_fixup(struc
 		adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
 
 	/* get the native mode for LVDS */
-	if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
-		struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
-		int mode_id = adjusted_mode->base.id;
-		*adjusted_mode = *native_mode;
-		if (!ASIC_IS_AVIVO(rdev)) {
-			adjusted_mode->hdisplay = mode->hdisplay;
-			adjusted_mode->vdisplay = mode->vdisplay;
-			adjusted_mode->crtc_hdisplay = mode->hdisplay;
-			adjusted_mode->crtc_vdisplay = mode->vdisplay;
-		}
-		adjusted_mode->base.id = mode_id;
-	}
+	if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT))
+		radeon_panel_mode_fixup(encoder, adjusted_mode);
 
 	/* get the native mode for TV */
 	if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
@@ -273,7 +339,7 @@ static bool radeon_atom_mode_fixup(struc
 	}
 
 	if (ASIC_IS_DCE3(rdev) &&
-	    (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT))) {
+	    (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT))) {
 		struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
 		radeon_dp_set_link_config(connector, mode);
 	}
@@ -288,12 +354,8 @@ atombios_dac_setup(struct drm_encoder *e
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	DAC_ENCODER_CONTROL_PS_ALLOCATION args;
-	int index = 0, num = 0;
+	int index = 0;
 	struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
-	enum radeon_tv_std tv_std = TV_STD_NTSC;
-
-	if (dac_info->tv_std)
-		tv_std = dac_info->tv_std;
 
 	memset(&args, 0, sizeof(args));
 
@@ -301,12 +363,10 @@ atombios_dac_setup(struct drm_encoder *e
 	case ENCODER_OBJECT_ID_INTERNAL_DAC1:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
 		index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
-		num = 1;
 		break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC2:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
 		index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
-		num = 2;
 		break;
 	}
 
@@ -317,7 +377,7 @@ atombios_dac_setup(struct drm_encoder *e
 	else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
 		args.ucDacStandard = ATOM_DAC1_CV;
 	else {
-		switch (tv_std) {
+		switch (dac_info->tv_std) {
 		case TV_STD_PAL:
 		case TV_STD_PAL_M:
 		case TV_STD_SCART_PAL:
@@ -348,10 +408,6 @@ atombios_tv_setup(struct drm_encoder *en
 	TV_ENCODER_CONTROL_PS_ALLOCATION args;
 	int index = 0;
 	struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
-	enum radeon_tv_std tv_std = TV_STD_NTSC;
-
-	if (dac_info->tv_std)
-		tv_std = dac_info->tv_std;
 
 	memset(&args, 0, sizeof(args));
 
@@ -362,7 +418,7 @@ atombios_tv_setup(struct drm_encoder *en
 	if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
 		args.sTVEncoder.ucTvStandard = ATOM_TV_CV;
 	else {
-		switch (tv_std) {
+		switch (dac_info->tv_std) {
 		case TV_STD_NTSC:
 			args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
 			break;
@@ -458,34 +514,20 @@ atombios_digital_setup(struct drm_encode
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+	struct radeon_connector_atom_dig *dig_connector =
+		radeon_get_atom_connector_priv_from_encoder(encoder);
 	union lvds_encoder_control args;
 	int index = 0;
 	int hdmi_detected = 0;
 	uint8_t frev, crev;
-	struct radeon_encoder_atom_dig *dig;
-	struct drm_connector *connector;
-	struct radeon_connector *radeon_connector;
-	struct radeon_connector_atom_dig *dig_connector;
-
-	connector = radeon_get_connector_for_encoder(encoder);
-	if (!connector)
-		return;
-
-	radeon_connector = to_radeon_connector(connector);
 
-	if (!radeon_encoder->enc_priv)
-		return;
-
-	dig = radeon_encoder->enc_priv;
-
-	if (!radeon_connector->con_priv)
+	if (!dig || !dig_connector)
 		return;
 
-	if (drm_detect_hdmi_monitor(radeon_connector->edid))
+	if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI)
 		hdmi_detected = 1;
 
-	dig_connector = radeon_connector->con_priv;
-
 	memset(&args, 0, sizeof(args));
 
 	switch (radeon_encoder->encoder_id) {
@@ -504,7 +546,8 @@ atombios_digital_setup(struct drm_encode
 		break;
 	}
 
-	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
+	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+		return;
 
 	switch (frev) {
 	case 1:
@@ -578,7 +621,6 @@ atombios_digital_setup(struct drm_encode
 	}
 
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-	r600_hdmi_enable(encoder, hdmi_detected);
 }
 
 int
@@ -586,7 +628,7 @@ atombios_get_encoder_mode(struct drm_enc
 {
 	struct drm_connector *connector;
 	struct radeon_connector *radeon_connector;
-	struct radeon_connector_atom_dig *radeon_dig_connector;
+	struct radeon_connector_atom_dig *dig_connector;
 
 	connector = radeon_get_connector_for_encoder(encoder);
 	if (!connector)
@@ -617,9 +659,9 @@ atombios_get_encoder_mode(struct drm_enc
 		break;
 	case DRM_MODE_CONNECTOR_DisplayPort:
 	case DRM_MODE_CONNECTOR_eDP:
-		radeon_dig_connector = radeon_connector->con_priv;
-		if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
-		    (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
+		dig_connector = radeon_connector->con_priv;
+		if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
+		    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
 			return ATOM_ENCODER_MODE_DP;
 		else if (drm_detect_hdmi_monitor(radeon_connector->edid))
 			return ATOM_ENCODER_MODE_HDMI;
@@ -656,6 +698,18 @@ atombios_get_encoder_mode(struct drm_enc
  * - 2 DIG encoder blocks.
  * DIG1/2 can drive UNIPHY0/1/2 link A or link B
  *
+ * DCE 4.0
+ * - 3 DIG transmitter blocks UNPHY0/1/2 (links A and B).
+ * Supports up to 6 digital outputs
+ * - 6 DIG encoder blocks.
+ * - DIG to PHY mapping is hardcoded
+ * DIG1 drives UNIPHY0 link A, A+B
+ * DIG2 drives UNIPHY0 link B
+ * DIG3 drives UNIPHY1 link A, A+B
+ * DIG4 drives UNIPHY1 link B
+ * DIG5 drives UNIPHY2 link A, A+B
+ * DIG6 drives UNIPHY2 link B
+ *
  * Routing
  * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links)
  * Examples:
@@ -664,88 +718,78 @@ atombios_get_encoder_mode(struct drm_enc
  * crtc0 -> dig1 -> UNIPHY2 link  A   -> LVDS
  * crtc1 -> dig2 -> UNIPHY1 link  B+A -> TMDS/HDMI
  */
-static void
+
+union dig_encoder_control {
+	DIG_ENCODER_CONTROL_PS_ALLOCATION v1;
+	DIG_ENCODER_CONTROL_PARAMETERS_V2 v2;
+	DIG_ENCODER_CONTROL_PARAMETERS_V3 v3;
+};
+
+void
 atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
 {
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-	DIG_ENCODER_CONTROL_PS_ALLOCATION args;
-	int index = 0, num = 0;
+	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+	struct radeon_connector_atom_dig *dig_connector =
+		radeon_get_atom_connector_priv_from_encoder(encoder);
+	union dig_encoder_control args;
+	int index = 0;
 	uint8_t frev, crev;
-	struct radeon_encoder_atom_dig *dig;
-	struct drm_connector *connector;
-	struct radeon_connector *radeon_connector;
-	struct radeon_connector_atom_dig *dig_connector;
 
-	connector = radeon_get_connector_for_encoder(encoder);
-	if (!connector)
+	if (!dig || !dig_connector)
 		return;
 
-	radeon_connector = to_radeon_connector(connector);
-
-	if (!radeon_connector->con_priv)
-		return;
+	memset(&args, 0, sizeof(args));
 
-	dig_connector = radeon_connector->con_priv;
+	if (ASIC_IS_DCE4(rdev))
+		index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl);
+	else {
+		if (dig->dig_encoder)
+			index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
+		else
+			index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+	}
 
-	if (!radeon_encoder->enc_priv)
+	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
 		return;
 
-	dig = radeon_encoder->enc_priv;
-
-	memset(&args, 0, sizeof(args));
+	args.v1.ucAction = action;
+	args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+	args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder);
 
-	if (dig->dig_encoder)
-		index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
+	if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
+		if (dig_connector->dp_clock == 270000)
+			args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
+		args.v1.ucLaneNum = dig_connector->dp_lane_count;
+	} else if (radeon_encoder->pixel_clock > 165000)
+		args.v1.ucLaneNum = 8;
 	else
-		index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
-	num = dig->dig_encoder + 1;
-
-	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
-
-	args.ucAction = action;
-	args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+		args.v1.ucLaneNum = 4;
 
-	if (ASIC_IS_DCE32(rdev)) {
+	if (ASIC_IS_DCE4(rdev)) {
+		args.v3.acConfig.ucDigSel = dig->dig_encoder;
+		args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+	} else {
 		switch (radeon_encoder->encoder_id) {
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-			args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
+			args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
 			break;
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-			args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
+		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+			args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
 			break;
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-			args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
-			break;
-		}
-	} else {
-		switch (radeon_encoder->encoder_id) {
-		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-			args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1;
-			break;
-		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-			args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2;
+			args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
 			break;
 		}
+		if (dig_connector->linkb)
+			args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
+		else
+			args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
 	}
 
-	args.ucEncoderMode = atombios_get_encoder_mode(encoder);
-
-	if (args.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
-		if (dig_connector->dp_clock == 270000)
-			args.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
-		args.ucLaneNum = dig_connector->dp_lane_count;
-	} else if (radeon_encoder->pixel_clock > 165000)
-		args.ucLaneNum = 8;
-	else
-		args.ucLaneNum = 4;
-
-	if (dig_connector->linkb)
-		args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
-	else
-		args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
-
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 
 }
@@ -753,6 +797,7 @@ atombios_dig_encoder_setup(struct drm_en
 union dig_transmitter_control {
 	DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1;
 	DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;
+	DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3;
 };
 
 void
@@ -761,37 +806,29 @@ atombios_dig_transmitter_setup(struct dr
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-	union dig_transmitter_control args;
-	int index = 0, num = 0;
-	uint8_t frev, crev;
-	struct radeon_encoder_atom_dig *dig;
+	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+	struct radeon_connector_atom_dig *dig_connector =
+		radeon_get_atom_connector_priv_from_encoder(encoder);
 	struct drm_connector *connector;
 	struct radeon_connector *radeon_connector;
-	struct radeon_connector_atom_dig *dig_connector;
+	union dig_transmitter_control args;
+	int index = 0;
+	uint8_t frev, crev;
 	bool is_dp = false;
+	int pll_id = 0;
 
-	connector = radeon_get_connector_for_encoder(encoder);
-	if (!connector)
+	if (!dig || !dig_connector)
 		return;
 
+	connector = radeon_get_connector_for_encoder(encoder);
 	radeon_connector = to_radeon_connector(connector);
 
-	if (!radeon_encoder->enc_priv)
-		return;
-
-	dig = radeon_encoder->enc_priv;
-
-	if (!radeon_connector->con_priv)
-		return;
-
-	dig_connector = radeon_connector->con_priv;
-
 	if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP)
 		is_dp = true;
 
 	memset(&args, 0, sizeof(args));
 
-	if (ASIC_IS_DCE32(rdev))
+	if (ASIC_IS_DCE32(rdev) || ASIC_IS_DCE4(rdev))
 		index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
 	else {
 		switch (radeon_encoder->encoder_id) {
@@ -804,7 +841,8 @@ atombios_dig_transmitter_setup(struct dr
 		}
 	}
 
-	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
+	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+		return;
 
 	args.v1.ucAction = action;
 	if (action == ATOM_TRANSMITTER_ACTION_INIT) {
@@ -821,24 +859,66 @@ atombios_dig_transmitter_setup(struct dr
 		else
 			args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
 	}
-	if (ASIC_IS_DCE32(rdev)) {
-		if (dig->dig_encoder == 1)
-			args.v2.acConfig.ucEncoderSel = 1;
+	if (ASIC_IS_DCE4(rdev)) {
+		if (is_dp)
+			args.v3.ucLaneNum = dig_connector->dp_lane_count;
+		else if (radeon_encoder->pixel_clock > 165000)
+			args.v3.ucLaneNum = 8;
+		else
+			args.v3.ucLaneNum = 4;
+
+		if (dig_connector->linkb) {
+			args.v3.acConfig.ucLinkSel = 1;
+			args.v3.acConfig.ucEncoderSel = 1;
+		}
+
+		/* Select the PLL for the PHY
+		 * DP PHY should be clocked from external src if there is
+		 * one.
+		 */
+		if (encoder->crtc) {
+			struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
+			pll_id = radeon_crtc->pll_id;
+		}
+		if (is_dp && rdev->clock.dp_extclk)
+			args.v3.acConfig.ucRefClkSource = 2; /* external src */
+		else
+			args.v3.acConfig.ucRefClkSource = pll_id;
+
+		switch (radeon_encoder->encoder_id) {
+		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+			args.v3.acConfig.ucTransmitterSel = 0;
+			break;
+		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+			args.v3.acConfig.ucTransmitterSel = 1;
+			break;
+		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+			args.v3.acConfig.ucTransmitterSel = 2;
+			break;
+		}
+
+		if (is_dp)
+			args.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */
+		else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
+			if (dig->coherent_mode)
+				args.v3.acConfig.fCoherentMode = 1;
+			if (radeon_encoder->pixel_clock > 165000)
+				args.v3.acConfig.fDualLinkConnector = 1;
+		}
+	} else if (ASIC_IS_DCE32(rdev)) {
+		args.v2.acConfig.ucEncoderSel = dig->dig_encoder;
 		if (dig_connector->linkb)
 			args.v2.acConfig.ucLinkSel = 1;
 
 		switch (radeon_encoder->encoder_id) {
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
 			args.v2.acConfig.ucTransmitterSel = 0;
-			num = 0;
 			break;
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 			args.v2.acConfig.ucTransmitterSel = 1;
-			num = 1;
 			break;
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
 			args.v2.acConfig.ucTransmitterSel = 2;
-			num = 2;
 			break;
 		}
 
@@ -847,9 +927,10 @@ atombios_dig_transmitter_setup(struct dr
 		else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
 			if (dig->coherent_mode)
 				args.v2.acConfig.fCoherentMode = 1;
+			if (radeon_encoder->pixel_clock > 165000)
+				args.v2.acConfig.fDualLinkConnector = 1;
 		}
 	} else {
-
 		args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
 
 		if (dig->dig_encoder)
@@ -857,31 +938,25 @@ atombios_dig_transmitter_setup(struct dr
 		else
 			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
 
-		switch (radeon_encoder->encoder_id) {
-		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-			if (rdev->flags & RADEON_IS_IGP) {
-				if (radeon_encoder->pixel_clock > 165000) {
-					if (dig_connector->igp_lane_info & 0x3)
-						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
-					else if (dig_connector->igp_lane_info & 0xc)
-						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
-				} else {
-					if (dig_connector->igp_lane_info & 0x1)
-						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-					else if (dig_connector->igp_lane_info & 0x2)
-						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
-					else if (dig_connector->igp_lane_info & 0x4)
-						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
-					else if (dig_connector->igp_lane_info & 0x8)
-						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
-				}
+		if ((rdev->flags & RADEON_IS_IGP) &&
+		    (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) {
+			if (is_dp || (radeon_encoder->pixel_clock <= 165000)) {
+				if (dig_connector->igp_lane_info & 0x1)
+					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+				else if (dig_connector->igp_lane_info & 0x2)
+					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
+				else if (dig_connector->igp_lane_info & 0x4)
+					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
+				else if (dig_connector->igp_lane_info & 0x8)
+					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
+			} else {
+				if (dig_connector->igp_lane_info & 0x3)
+					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
+				else if (dig_connector->igp_lane_info & 0xc)
+					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
 			}
-			break;
 		}
 
-		if (radeon_encoder->pixel_clock > 165000)
-			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
-
 		if (dig_connector->linkb)
 			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;
 		else
@@ -892,6 +967,8 @@ atombios_dig_transmitter_setup(struct dr
 		else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
 			if (dig->coherent_mode)
 				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
+			if (radeon_encoder->pixel_clock > 165000)
+				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
 		}
 	}
 
@@ -998,16 +1075,25 @@ radeon_atom_encoder_dpms(struct drm_enco
 	if (is_dig) {
 		switch (mode) {
 		case DRM_MODE_DPMS_ON:
-			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
-			{
+			if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
 				struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+
 				dp_link_train(encoder, connector);
+				if (ASIC_IS_DCE4(rdev))
+					atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON);
 			}
+			if (!ASIC_IS_DCE4(rdev))
+				atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
 			break;
 		case DRM_MODE_DPMS_STANDBY:
 		case DRM_MODE_DPMS_SUSPEND:
 		case DRM_MODE_DPMS_OFF:
-			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
+			if (!ASIC_IS_DCE4(rdev))
+				atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
+			if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
+				if (ASIC_IS_DCE4(rdev))
+					atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF);
+			}
 			break;
 		}
 	} else {
@@ -1024,9 +1110,12 @@ radeon_atom_encoder_dpms(struct drm_enco
 		atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 	}
 	radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
+
+	/* adjust pm to dpms change */
+	radeon_pm_compute_clocks(rdev);
 }
 
-union crtc_sourc_param {
+union crtc_source_param {
 	SELECT_CRTC_SOURCE_PS_ALLOCATION v1;
 	SELECT_CRTC_SOURCE_PARAMETERS_V2 v2;
 };
@@ -1038,14 +1127,15 @@ atombios_set_encoder_crtc_source(struct
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
-	union crtc_sourc_param args;
+	union crtc_source_param args;
 	int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
 	uint8_t frev, crev;
 	struct radeon_encoder_atom_dig *dig;
 
 	memset(&args, 0, sizeof(args));
 
-	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
+	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+		return;
 
 	switch (frev) {
 	case 1:
@@ -1107,10 +1197,26 @@ atombios_set_encoder_crtc_source(struct
 			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 				dig = radeon_encoder->enc_priv;
-				if (dig->dig_encoder)
-					args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
-				else
+				switch (dig->dig_encoder) {
+				case 0:
 					args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
+					break;
+				case 1:
+					args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
+					break;
+				case 2:
+					args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID;
+					break;
+				case 3:
+					args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID;
+					break;
+				case 4:
+					args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID;
+					break;
+				case 5:
+					args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID;
+					break;
+				}
 				break;
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
 				args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
@@ -1141,6 +1247,9 @@ atombios_set_encoder_crtc_source(struct
 	}
 
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+	/* update scratch regs with new routing */
+	radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
 }
 
 static void
@@ -1167,6 +1276,7 @@ atombios_apply_encoder_quirks(struct drm
 	}
 
 	/* set scaler clears this on some chips */
+	/* XXX check DCE4 */
 	if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) {
 		if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE))
 			WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
@@ -1183,6 +1293,33 @@ static int radeon_atom_pick_dig_encoder(
 	struct drm_encoder *test_encoder;
 	struct radeon_encoder_atom_dig *dig;
 	uint32_t dig_enc_in_use = 0;
+
+	if (ASIC_IS_DCE4(rdev)) {
+		struct radeon_connector_atom_dig *dig_connector =
+			radeon_get_atom_connector_priv_from_encoder(encoder);
+
+		switch (radeon_encoder->encoder_id) {
+		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+			if (dig_connector->linkb)
+				return 1;
+			else
+				return 0;
+			break;
+		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+			if (dig_connector->linkb)
+				return 3;
+			else
+				return 2;
+			break;
+		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+			if (dig_connector->linkb)
+				return 5;
+			else
+				return 4;
+			break;
+		}
+	}
+
 	/* on DCE32 and encoder can driver any block so just crtc id */
 	if (ASIC_IS_DCE32(rdev)) {
 		return radeon_crtc->crtc_id;
@@ -1223,20 +1360,10 @@ radeon_atom_encoder_mode_set(struct drm_
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-	struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
 
-	if (radeon_encoder->active_device &
-	    (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
-		struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
-		if (dig)
-			dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder);
-	}
 	radeon_encoder->pixel_clock = adjusted_mode->clock;
 
-	radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
-	atombios_set_encoder_crtc_source(encoder);
-
-	if (ASIC_IS_AVIVO(rdev)) {
+	if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) {
 		if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
 			atombios_yuv_setup(encoder, true);
 		else
@@ -1254,15 +1381,26 @@ radeon_atom_encoder_mode_set(struct drm_
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-		/* disable the encoder and transmitter */
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
-		atombios_dig_encoder_setup(encoder, ATOM_DISABLE);
+		if (ASIC_IS_DCE4(rdev)) {
+			/* disable the transmitter */
+			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
+			/* setup and enable the encoder */
+			atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP);
 
-		/* setup and enable the encoder and transmitter */
-		atombios_dig_encoder_setup(encoder, ATOM_ENABLE);
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+			/* init and enable the transmitter */
+			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
+			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+		} else {
+			/* disable the encoder and transmitter */
+			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
+			atombios_dig_encoder_setup(encoder, ATOM_DISABLE);
+
+			/* setup and enable the encoder and transmitter */
+			atombios_dig_encoder_setup(encoder, ATOM_ENABLE);
+			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
+			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
+			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+		}
 		break;
 	case ENCODER_OBJECT_ID_INTERNAL_DDI:
 		atombios_ddia_setup(encoder, ATOM_ENABLE);
@@ -1276,13 +1414,20 @@ radeon_atom_encoder_mode_set(struct drm_
 	case ENCODER_OBJECT_ID_INTERNAL_DAC2:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
 		atombios_dac_setup(encoder, ATOM_ENABLE);
-		if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
-			atombios_tv_setup(encoder, ATOM_ENABLE);
+		if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) {
+			if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
+				atombios_tv_setup(encoder, ATOM_ENABLE);
+			else
+				atombios_tv_setup(encoder, ATOM_DISABLE);
+		}
 		break;
 	}
 	atombios_apply_encoder_quirks(encoder, adjusted_mode);
 
-	r600_hdmi_setmode(encoder, adjusted_mode);
+	if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
+		r600_hdmi_enable(encoder);
+		r600_hdmi_setmode(encoder, adjusted_mode);
+	}
 }
 
 static bool
@@ -1302,7 +1447,8 @@ atombios_dac_load_detect(struct drm_enco
 
 		memset(&args, 0, sizeof(args));
 
-		atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
+		if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+			return false;
 
 		args.sDacload.ucMisc = 0;
 
@@ -1376,8 +1522,20 @@ radeon_atom_dac_detect(struct drm_encode
 
 static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
 {
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+
+	if (radeon_encoder->active_device &
+	    (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
+		struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+		if (dig)
+			dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder);
+	}
+
 	radeon_atom_output_lock(encoder, true);
 	radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+
+	/* this is needed for the pll/ss setup to work correctly in some cases */
+	atombios_set_encoder_crtc_source(encoder);
 }
 
 static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
@@ -1393,6 +1551,8 @@ static void radeon_atom_encoder_disable(
 	radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
 
 	if (radeon_encoder_is_digital(encoder)) {
+		if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI)
+			r600_hdmi_disable(encoder);
 		dig = radeon_encoder->enc_priv;
 		dig->dig_encoder = -1;
 	}
@@ -1433,12 +1593,14 @@ static const struct drm_encoder_funcs ra
 struct radeon_encoder_atom_dac *
 radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder)
 {
+	struct drm_device *dev = radeon_encoder->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL);
 
 	if (!dac)
 		return NULL;
 
-	dac->tv_std = TV_STD_NTSC;
+	dac->tv_std = radeon_atombios_get_tv_info(rdev);
 	return dac;
 }
 
@@ -1480,10 +1642,18 @@ radeon_add_atom_encoder(struct drm_devic
 		return;
 
 	encoder = &radeon_encoder->base;
-	if (rdev->flags & RADEON_SINGLE_CRTC)
+	switch (rdev->num_crtc) {
+	case 1:
 		encoder->possible_crtcs = 0x1;
-	else
+		break;
+	case 2:
+	default:
 		encoder->possible_crtcs = 0x3;
+		break;
+	case 6:
+		encoder->possible_crtcs = 0x3f;
+		break;
+	}
 
 	radeon_encoder->enc_priv = NULL;
 
@@ -1508,6 +1678,7 @@ radeon_add_atom_encoder(struct drm_devic
 		break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC1:
 		drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
+		radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder);
 		drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
 		break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC2:
@@ -1535,6 +1706,4 @@ radeon_add_atom_encoder(struct drm_devic
 		drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
 		break;
 	}
-
-	r600_hdmi_init(encoder);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_family.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_family.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_family.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_family.h	2010-05-16 17:17:36.000000000 -0400
@@ -36,7 +36,7 @@
  * Radeon chip families
  */
 enum radeon_family {
-	CHIP_R100,
+	CHIP_R100 = 0,
 	CHIP_RV100,
 	CHIP_RS100,
 	CHIP_RV200,
@@ -75,6 +75,11 @@ enum radeon_family {
 	CHIP_RV730,
 	CHIP_RV710,
 	CHIP_RV740,
+	CHIP_CEDAR,
+	CHIP_REDWOOD,
+	CHIP_JUNIPER,
+	CHIP_CYPRESS,
+	CHIP_HEMLOCK,
 	CHIP_LAST,
 };
 
@@ -94,4 +99,5 @@ enum radeon_chip_flags {
 	RADEON_IS_PCI = 0x00800000UL,
 	RADEON_IS_IGPGART = 0x01000000UL,
 };
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_fb.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_fb.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
      */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/fb.h>
 
 #include "drmP.h"
@@ -39,6 +40,8 @@
 
 #include "drm_fb_helper.h"
 
+#include <linux/vga_switcheroo.h>
+
 struct radeon_fb_device {
 	struct drm_fb_helper helper;
 	struct radeon_framebuffer	*rfb;
@@ -148,7 +151,6 @@ int radeonfb_create(struct drm_device *d
 	unsigned long tmp;
 	bool fb_tiled = false; /* useful for testing */
 	u32 tiling_flags = 0;
-	int crtc_count;
 
 	mode_cmd.width = surface_width;
 	mode_cmd.height = surface_height;
@@ -239,11 +241,7 @@ int radeonfb_create(struct drm_device *d
 	rfbdev = info->par;
 	rfbdev->helper.funcs = &radeon_fb_helper_funcs;
 	rfbdev->helper.dev = dev;
-	if (rdev->flags & RADEON_SINGLE_CRTC)
-		crtc_count = 1;
-	else
-		crtc_count = 2;
-	ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, crtc_count,
+	ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, rdev->num_crtc,
 					    RADEONFB_CONN_LIMIT);
 	if (ret)
 		goto out_unref;
@@ -257,7 +255,7 @@ int radeonfb_create(struct drm_device *d
 	info->flags = FBINFO_DEFAULT;
 	info->fbops = &radeonfb_ops;
 
-	tmp = fb_gpuaddr - rdev->mc.vram_location;
+	tmp = fb_gpuaddr - rdev->mc.vram_start;
 	info->fix.smem_start = rdev->mc.aper_base + tmp;
 	info->fix.smem_len = size;
 	info->screen_base = fbptr;
@@ -291,6 +289,7 @@ int radeonfb_create(struct drm_device *d
 	rfbdev->rdev = rdev;
 
 	mutex_unlock(&rdev->ddev->struct_mutex);
+	vga_switcheroo_client_fb_set(rdev->ddev->pdev, info);
 	return 0;
 
 out_unref:
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_fence.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_fence.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_fence.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_fence.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/wait.h>
 #include <linux/list.h>
 #include <linux/kref.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_reg.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_gart.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_gart.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_gart.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_gart.c	2010-05-16 17:17:36.000000000 -0400
@@ -139,6 +139,7 @@ void radeon_gart_unbind(struct radeon_de
 	unsigned t;
 	unsigned p;
 	int i, j;
+	u64 page_base;
 
 	if (!rdev->gart.ready) {
 		WARN(1, "trying to unbind memory to unitialized GART !\n");
@@ -151,9 +152,11 @@ void radeon_gart_unbind(struct radeon_de
 			pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p],
 				       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
 			rdev->gart.pages[p] = NULL;
-			rdev->gart.pages_addr[p] = 0;
+			rdev->gart.pages_addr[p] = rdev->dummy_page.addr;
+			page_base = rdev->gart.pages_addr[p];
 			for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
-				radeon_gart_set_page(rdev, t, 0);
+				radeon_gart_set_page(rdev, t, page_base);
+				page_base += RADEON_GPU_PAGE_SIZE;
 			}
 		}
 	}
@@ -199,8 +202,26 @@ int radeon_gart_bind(struct radeon_devic
 	return 0;
 }
 
+void radeon_gart_restore(struct radeon_device *rdev)
+{
+	int i, j, t;
+	u64 page_base;
+
+	for (i = 0, t = 0; i < rdev->gart.num_cpu_pages; i++) {
+		page_base = rdev->gart.pages_addr[i];
+		for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
+			radeon_gart_set_page(rdev, t, page_base);
+			page_base += RADEON_GPU_PAGE_SIZE;
+		}
+	}
+	mb();
+	radeon_gart_tlb_flush(rdev);
+}
+
 int radeon_gart_init(struct radeon_device *rdev)
 {
+	int r, i;
+
 	if (rdev->gart.pages) {
 		return 0;
 	}
@@ -209,6 +230,9 @@ int radeon_gart_init(struct radeon_devic
 		DRM_ERROR("Page size is smaller than GPU page size!\n");
 		return -EINVAL;
 	}
+	r = radeon_dummy_page_init(rdev);
+	if (r)
+		return r;
 	/* Compute table size */
 	rdev->gart.num_cpu_pages = rdev->mc.gtt_size / PAGE_SIZE;
 	rdev->gart.num_gpu_pages = rdev->mc.gtt_size / RADEON_GPU_PAGE_SIZE;
@@ -227,6 +251,10 @@ int radeon_gart_init(struct radeon_devic
 		radeon_gart_fini(rdev);
 		return -ENOMEM;
 	}
+	/* set GART entry to point to the dummy page by default */
+	for (i = 0; i < rdev->gart.num_cpu_pages; i++) {
+		rdev->gart.pages_addr[i] = rdev->dummy_page.addr;
+	}
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_gem.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_gem.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_gem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_gem.c	2010-05-16 17:17:36.000000000 -0400
@@ -69,9 +69,7 @@ int radeon_gem_object_create(struct rade
 		if (r != -ERESTARTSYS)
 			DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n",
 				  size, initial_domain, alignment, r);
-		mutex_lock(&rdev->ddev->struct_mutex);
-		drm_gem_object_unreference(gobj);
-		mutex_unlock(&rdev->ddev->struct_mutex);
+		drm_gem_object_unreference_unlocked(gobj);
 		return r;
 	}
 	gobj->driver_private = robj;
@@ -202,14 +200,10 @@ int radeon_gem_create_ioctl(struct drm_d
 	}
 	r = drm_gem_handle_create(filp, gobj, &handle);
 	if (r) {
-		mutex_lock(&dev->struct_mutex);
-		drm_gem_object_unreference(gobj);
-		mutex_unlock(&dev->struct_mutex);
+		drm_gem_object_unreference_unlocked(gobj);
 		return r;
 	}
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_handle_unreference(gobj);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_handle_unreference_unlocked(gobj);
 	args->handle = handle;
 	return 0;
 }
@@ -236,9 +230,7 @@ int radeon_gem_set_domain_ioctl(struct d
 
 	r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain);
 
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(gobj);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(gobj);
 	return r;
 }
 
@@ -255,9 +247,7 @@ int radeon_gem_mmap_ioctl(struct drm_dev
 	}
 	robj = gobj->driver_private;
 	args->addr_ptr = radeon_bo_mmap_offset(robj);
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(gobj);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(gobj);
 	return 0;
 }
 
@@ -288,9 +278,7 @@ int radeon_gem_busy_ioctl(struct drm_dev
 	default:
 		break;
 	}
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(gobj);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(gobj);
 	return r;
 }
 
@@ -311,9 +299,7 @@ int radeon_gem_wait_idle_ioctl(struct dr
 	/* callback hw specific functions if any */
 	if (robj->rdev->asic->ioctl_wait_idle)
 		robj->rdev->asic->ioctl_wait_idle(robj->rdev, robj);
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(gobj);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(gobj);
 	return r;
 }
 
@@ -331,9 +317,7 @@ int radeon_gem_set_tiling_ioctl(struct d
 		return -EINVAL;
 	robj = gobj->driver_private;
 	r = radeon_bo_set_tiling_flags(robj, args->tiling_flags, args->pitch);
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(gobj);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(gobj);
 	return r;
 }
 
@@ -356,8 +340,6 @@ int radeon_gem_get_tiling_ioctl(struct d
 	radeon_bo_get_tiling_flags(rbo, &args->tiling_flags, &args->pitch);
 	radeon_bo_unreserve(rbo);
 out:
-	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_unreference(gobj);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(gobj);
 	return r;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon.h	2010-05-16 17:17:36.000000000 -0400
@@ -89,7 +89,10 @@ extern int radeon_testing;
 extern int radeon_connector_table;
 extern int radeon_tv;
 extern int radeon_new_pll;
+extern int radeon_dynpm;
 extern int radeon_audio;
+extern int radeon_disp_priority;
+extern int radeon_hw_i2c;
 
 /*
  * Copy from radeon_drv.h so we don't have to include both and have conflicting
@@ -118,6 +121,21 @@ struct radeon_device;
 /*
  * BIOS.
  */
+#define ATRM_BIOS_PAGE 4096
+
+#if defined(CONFIG_VGA_SWITCHEROO)
+bool radeon_atrm_supported(struct pci_dev *pdev);
+int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len);
+#else
+static inline bool radeon_atrm_supported(struct pci_dev *pdev)
+{
+	return false;
+}
+
+static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){
+	return -EINVAL;
+}
+#endif
 bool radeon_get_bios(struct radeon_device *rdev);
 
 
@@ -138,17 +156,24 @@ void radeon_dummy_page_fini(struct radeo
 struct radeon_clock {
 	struct radeon_pll p1pll;
 	struct radeon_pll p2pll;
+	struct radeon_pll dcpll;
 	struct radeon_pll spll;
 	struct radeon_pll mpll;
 	/* 10 Khz units */
 	uint32_t default_mclk;
 	uint32_t default_sclk;
+	uint32_t default_dispclk;
+	uint32_t dp_extclk;
 };
 
 /*
  * Power management
  */
 int radeon_pm_init(struct radeon_device *rdev);
+void radeon_pm_fini(struct radeon_device *rdev);
+void radeon_pm_compute_clocks(struct radeon_device *rdev);
+void radeon_combios_get_power_modes(struct radeon_device *rdev);
+void radeon_atombios_get_power_modes(struct radeon_device *rdev);
 
 /*
  * Fences.
@@ -275,6 +300,7 @@ union radeon_gart_table {
 };
 
 #define RADEON_GPU_PAGE_SIZE 4096
+#define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1)
 
 struct radeon_gart {
 	dma_addr_t			table_addr;
@@ -309,21 +335,19 @@ struct radeon_mc {
 	/* for some chips with <= 32MB we need to lie
 	 * about vram size near mc fb location */
 	u64			mc_vram_size;
-	u64			gtt_location;
+	u64			visible_vram_size;
 	u64			gtt_size;
 	u64			gtt_start;
 	u64			gtt_end;
-	u64			vram_location;
 	u64			vram_start;
 	u64			vram_end;
 	unsigned		vram_width;
 	u64			real_vram_size;
 	int			vram_mtrr;
 	bool			vram_is_ddr;
-	bool                    igp_sideport_enabled;
+	bool			igp_sideport_enabled;
 };
 
-int radeon_mc_setup(struct radeon_device *rdev);
 bool radeon_combios_sideport_present(struct radeon_device *rdev);
 bool radeon_atombios_sideport_present(struct radeon_device *rdev);
 
@@ -348,6 +372,7 @@ struct radeon_irq {
 	bool		sw_int;
 	/* FIXME: use a define max crtc rather than hardcode it */
 	bool		crtc_vblank_int[2];
+	wait_queue_head_t	vblank_queue;
 	/* FIXME: use defines for max hpd/dacs */
 	bool            hpd[6];
 	spinlock_t sw_lock;
@@ -379,6 +404,7 @@ struct radeon_ib {
 struct radeon_ib_pool {
 	struct mutex		mutex;
 	struct radeon_bo	*robj;
+	struct list_head	bogus_ib;
 	struct radeon_ib	ibs[RADEON_IB_POOL_SIZE];
 	bool			ready;
 	unsigned		head_id;
@@ -433,6 +459,7 @@ int radeon_ib_schedule(struct radeon_dev
 int radeon_ib_pool_init(struct radeon_device *rdev);
 void radeon_ib_pool_fini(struct radeon_device *rdev);
 int radeon_ib_test(struct radeon_device *rdev);
+extern void radeon_ib_bogus_add(struct radeon_device *rdev, struct radeon_ib *ib);
 /* Ring access between begin & end cannot sleep */
 void radeon_ring_free_size(struct radeon_device *rdev);
 int radeon_ring_lock(struct radeon_device *rdev, unsigned ndw);
@@ -570,7 +597,100 @@ struct radeon_wb {
  * Equation between gpu/memory clock and available bandwidth is hw dependent
  * (type of memory, bus size, efficiency, ...)
  */
+enum radeon_pm_state {
+	PM_STATE_DISABLED,
+	PM_STATE_MINIMUM,
+	PM_STATE_PAUSED,
+	PM_STATE_ACTIVE
+};
+enum radeon_pm_action {
+	PM_ACTION_NONE,
+	PM_ACTION_MINIMUM,
+	PM_ACTION_DOWNCLOCK,
+	PM_ACTION_UPCLOCK
+};
+
+enum radeon_voltage_type {
+	VOLTAGE_NONE = 0,
+	VOLTAGE_GPIO,
+	VOLTAGE_VDDC,
+	VOLTAGE_SW
+};
+
+enum radeon_pm_state_type {
+	POWER_STATE_TYPE_DEFAULT,
+	POWER_STATE_TYPE_POWERSAVE,
+	POWER_STATE_TYPE_BATTERY,
+	POWER_STATE_TYPE_BALANCED,
+	POWER_STATE_TYPE_PERFORMANCE,
+};
+
+enum radeon_pm_clock_mode_type {
+	POWER_MODE_TYPE_DEFAULT,
+	POWER_MODE_TYPE_LOW,
+	POWER_MODE_TYPE_MID,
+	POWER_MODE_TYPE_HIGH,
+};
+
+struct radeon_voltage {
+	enum radeon_voltage_type type;
+	/* gpio voltage */
+	struct radeon_gpio_rec gpio;
+	u32 delay; /* delay in usec from voltage drop to sclk change */
+	bool active_high; /* voltage drop is active when bit is high */
+	/* VDDC voltage */
+	u8 vddc_id; /* index into vddc voltage table */
+	u8 vddci_id; /* index into vddci voltage table */
+	bool vddci_enabled;
+	/* r6xx+ sw */
+	u32 voltage;
+};
+
+struct radeon_pm_non_clock_info {
+	/* pcie lanes */
+	int pcie_lanes;
+	/* standardized non-clock flags */
+	u32 flags;
+};
+
+struct radeon_pm_clock_info {
+	/* memory clock */
+	u32 mclk;
+	/* engine clock */
+	u32 sclk;
+	/* voltage info */
+	struct radeon_voltage voltage;
+	/* standardized clock flags - not sure we'll need these */
+	u32 flags;
+};
+
+struct radeon_power_state {
+	enum radeon_pm_state_type type;
+	/* XXX: use a define for num clock modes */
+	struct radeon_pm_clock_info clock_info[8];
+	/* number of valid clock modes in this power state */
+	int num_clock_modes;
+	struct radeon_pm_clock_info *default_clock_mode;
+	/* non clock info about this state */
+	struct radeon_pm_non_clock_info non_clock_info;
+	bool voltage_drop_active;
+};
+
+/*
+ * Some modes are overclocked by very low value, accept them
+ */
+#define RADEON_MODE_OVERCLOCK_MARGIN 500 /* 5 MHz */
+
 struct radeon_pm {
+	struct mutex		mutex;
+	struct delayed_work	idle_work;
+	enum radeon_pm_state	state;
+	enum radeon_pm_action	planned_action;
+	unsigned long		action_timeout;
+	bool 			downclocked;
+	int			active_crtcs;
+	int			req_vblank;
+	bool			vblank_sync;
 	fixed20_12		max_bandwidth;
 	fixed20_12		igp_sideport_mclk;
 	fixed20_12		igp_system_mclk;
@@ -581,7 +701,18 @@ struct radeon_pm {
 	fixed20_12		ht_bandwidth;
 	fixed20_12		core_bandwidth;
 	fixed20_12		sclk;
+	fixed20_12		mclk;
 	fixed20_12		needed_bandwidth;
+	/* XXX: use a define for num power modes */
+	struct radeon_power_state power_state[8];
+	/* number of valid power states */
+	int                     num_power_states;
+	struct radeon_power_state *current_power_state;
+	struct radeon_pm_clock_info *current_clock_mode;
+	struct radeon_power_state *requested_power_state;
+	struct radeon_pm_clock_info *requested_clock_mode;
+	struct radeon_power_state *default_power_state;
+	struct radeon_i2c_chan *i2c_bus;
 };
 
 
@@ -604,8 +735,6 @@ int radeon_debugfs_add_files(struct rade
 			     struct drm_info_list *files,
 			     unsigned nfiles);
 int radeon_debugfs_fence_init(struct radeon_device *rdev);
-int r100_debugfs_rbbm_init(struct radeon_device *rdev);
-int r100_debugfs_cp_init(struct radeon_device *rdev);
 
 
 /*
@@ -651,12 +780,13 @@ struct radeon_asic {
 	void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock);
 	uint32_t (*get_memory_clock)(struct radeon_device *rdev);
 	void (*set_memory_clock)(struct radeon_device *rdev, uint32_t mem_clock);
+	int (*get_pcie_lanes)(struct radeon_device *rdev);
 	void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes);
 	void (*set_clock_gating)(struct radeon_device *rdev, int enable);
 	int (*set_surface_reg)(struct radeon_device *rdev, int reg,
 			       uint32_t tiling_flags, uint32_t pitch,
 			       uint32_t offset, uint32_t obj_size);
-	int (*clear_surface_reg)(struct radeon_device *rdev, int reg);
+	void (*clear_surface_reg)(struct radeon_device *rdev, int reg);
 	void (*bandwidth_update)(struct radeon_device *rdev);
 	void (*hpd_init)(struct radeon_device *rdev);
 	void (*hpd_fini)(struct radeon_device *rdev);
@@ -701,6 +831,9 @@ struct r600_asic {
 	unsigned sx_max_export_pos_size;
 	unsigned sx_max_export_smx_size;
 	unsigned sq_num_cf_insts;
+	unsigned tiling_nbanks;
+	unsigned tiling_npipes;
+	unsigned tiling_group_size;
 };
 
 struct rv770_asic {
@@ -721,6 +854,9 @@ struct rv770_asic {
 	unsigned sc_prim_fifo_size;
 	unsigned sc_hiz_tile_fifo_size;
 	unsigned sc_earlyz_tile_fifo_fize;
+	unsigned tiling_nbanks;
+	unsigned tiling_npipes;
+	unsigned tiling_group_size;
 };
 
 union radeon_asic_config {
@@ -730,6 +866,12 @@ union radeon_asic_config {
 	struct rv770_asic	rv770;
 };
 
+/*
+ * asic initizalization from radeon_asic.c
+ */
+void radeon_agp_disable(struct radeon_device *rdev);
+int radeon_asic_init(struct radeon_device *rdev);
+
 
 /*
  * IOCTL.
@@ -830,6 +972,8 @@ struct radeon_device {
 	struct r600_ih ih; /* r6/700 interrupt ring */
 	struct workqueue_struct *wq;
 	struct work_struct hotplug_work;
+	int num_crtc; /* number of crtcs */
+	struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */
 
 	/* audio stuff */
 	struct timer_list	audio_timer;
@@ -838,6 +982,8 @@ struct radeon_device {
 	int			audio_bits_per_sample;
 	uint8_t			audio_status_bits;
 	uint8_t			audio_category_code;
+
+	bool powered_down;
 };
 
 int radeon_device_init(struct radeon_device *rdev,
@@ -895,6 +1041,8 @@ static inline void r100_mm_wreg(struct r
 #define WREG32_MC(reg, v) rdev->mc_wreg(rdev, (reg), (v))
 #define RREG32_PCIE(reg) rv370_pcie_rreg(rdev, (reg))
 #define WREG32_PCIE(reg, v) rv370_pcie_wreg(rdev, (reg), (v))
+#define RREG32_PCIE_P(reg) rdev->pciep_rreg(rdev, (reg))
+#define WREG32_PCIE_P(reg, v) rdev->pciep_wreg(rdev, (reg), (v))
 #define WREG32_P(reg, val, mask)				\
 	do {							\
 		uint32_t tmp_ = RREG32(reg);			\
@@ -956,7 +1104,7 @@ void r100_pll_errata_after_index(struct
 #define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600))
 #define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620))
 #define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730))
-
+#define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR))
 
 /*
  * BIOS helpers.
@@ -1015,6 +1163,7 @@ static inline void radeon_ring_write(str
 #define radeon_set_engine_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
 #define radeon_get_memory_clock(rdev) (rdev)->asic->get_memory_clock((rdev))
 #define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_memory_clock((rdev), (e))
+#define radeon_get_pcie_lanes(rdev) (rdev)->asic->get_pcie_lanes((rdev))
 #define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l))
 #define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e))
 #define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->set_surface_reg((rdev), (r), (f), (p), (o), (s)))
@@ -1029,9 +1178,12 @@ static inline void radeon_ring_write(str
 /* AGP */
 extern void radeon_agp_disable(struct radeon_device *rdev);
 extern int radeon_gart_table_vram_pin(struct radeon_device *rdev);
+extern void radeon_gart_restore(struct radeon_device *rdev);
 extern int radeon_modeset_init(struct radeon_device *rdev);
 extern void radeon_modeset_fini(struct radeon_device *rdev);
 extern bool radeon_card_posted(struct radeon_device *rdev);
+extern void radeon_update_bandwidth_info(struct radeon_device *rdev);
+extern void radeon_update_display_priority(struct radeon_device *rdev);
 extern bool radeon_boot_test_post_card(struct radeon_device *rdev);
 extern int radeon_clocks_init(struct radeon_device *rdev);
 extern void radeon_clocks_fini(struct radeon_device *rdev);
@@ -1042,53 +1194,12 @@ extern void radeon_legacy_set_clock_gati
 extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
 extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain);
 extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo);
+extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base);
+extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
+extern int radeon_resume_kms(struct drm_device *dev);
+extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state);
 
 /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
-struct r100_mc_save {
-	u32	GENMO_WT;
-	u32	CRTC_EXT_CNTL;
-	u32	CRTC_GEN_CNTL;
-	u32	CRTC2_GEN_CNTL;
-	u32	CUR_OFFSET;
-	u32	CUR2_OFFSET;
-};
-extern void r100_cp_disable(struct radeon_device *rdev);
-extern int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
-extern void r100_cp_fini(struct radeon_device *rdev);
-extern void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
-extern int r100_pci_gart_init(struct radeon_device *rdev);
-extern void r100_pci_gart_fini(struct radeon_device *rdev);
-extern int r100_pci_gart_enable(struct radeon_device *rdev);
-extern void r100_pci_gart_disable(struct radeon_device *rdev);
-extern int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
-extern int r100_debugfs_mc_info_init(struct radeon_device *rdev);
-extern int r100_gui_wait_for_idle(struct radeon_device *rdev);
-extern void r100_ib_fini(struct radeon_device *rdev);
-extern int r100_ib_init(struct radeon_device *rdev);
-extern void r100_irq_disable(struct radeon_device *rdev);
-extern int r100_irq_set(struct radeon_device *rdev);
-extern void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save);
-extern void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save);
-extern void r100_vram_init_sizes(struct radeon_device *rdev);
-extern void r100_wb_disable(struct radeon_device *rdev);
-extern void r100_wb_fini(struct radeon_device *rdev);
-extern int r100_wb_init(struct radeon_device *rdev);
-extern void r100_hdp_reset(struct radeon_device *rdev);
-extern int r100_rb2d_reset(struct radeon_device *rdev);
-extern int r100_cp_reset(struct radeon_device *rdev);
-extern void r100_vga_render_disable(struct radeon_device *rdev);
-extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
-						struct radeon_cs_packet *pkt,
-						struct radeon_bo *robj);
-extern int r100_cs_parse_packet0(struct radeon_cs_parser *p,
-				struct radeon_cs_packet *pkt,
-				const unsigned *auth, unsigned n,
-				radeon_packet0_check_t check);
-extern int r100_cs_packet_parse(struct radeon_cs_parser *p,
-				struct radeon_cs_packet *pkt,
-				unsigned idx);
-extern void r100_enable_bm(struct radeon_device *rdev);
-extern void r100_set_common_regs(struct radeon_device *rdev);
 
 /* rv200,rv250,rv280 */
 extern void r200_set_safe_registers(struct radeon_device *rdev);
@@ -1096,7 +1207,7 @@ extern void r200_set_safe_registers(stru
 /* r300,r350,rv350,rv370,rv380 */
 extern void r300_set_reg_safe(struct radeon_device *rdev);
 extern void r300_mc_program(struct radeon_device *rdev);
-extern void r300_vram_info(struct radeon_device *rdev);
+extern void r300_mc_init(struct radeon_device *rdev);
 extern void r300_clock_startup(struct radeon_device *rdev);
 extern int r300_mc_wait_for_idle(struct radeon_device *rdev);
 extern int rv370_pcie_gart_init(struct radeon_device *rdev);
@@ -1105,7 +1216,6 @@ extern int rv370_pcie_gart_enable(struct
 extern void rv370_pcie_gart_disable(struct radeon_device *rdev);
 
 /* r420,r423,rv410 */
-extern int r420_mc_init(struct radeon_device *rdev);
 extern u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg);
 extern void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v);
 extern int r420_debugfs_pipes_info_init(struct radeon_device *rdev);
@@ -1147,13 +1257,13 @@ extern void rs690_line_buffer_adjust(str
 					struct drm_display_mode *mode2);
 
 /* r600, rv610, rv630, rv620, rv635, rv670, rs780, rs880 */
+extern void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
 extern bool r600_card_posted(struct radeon_device *rdev);
 extern void r600_cp_stop(struct radeon_device *rdev);
 extern void r600_ring_init(struct radeon_device *rdev, unsigned ring_size);
 extern int r600_cp_resume(struct radeon_device *rdev);
 extern void r600_cp_fini(struct radeon_device *rdev);
 extern int r600_count_pipe_bits(uint32_t val);
-extern int r600_gart_clear_page(struct radeon_device *rdev, int i);
 extern int r600_mc_wait_for_idle(struct radeon_device *rdev);
 extern int r600_pcie_gart_init(struct radeon_device *rdev);
 extern void r600_pcie_gart_tlb_flush(struct radeon_device *rdev);
@@ -1179,7 +1289,8 @@ extern int r600_audio_tmds_index(struct
 extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock);
 extern void r600_audio_fini(struct radeon_device *rdev);
 extern void r600_hdmi_init(struct drm_encoder *encoder);
-extern void r600_hdmi_enable(struct drm_encoder *encoder, int enable);
+extern void r600_hdmi_enable(struct drm_encoder *encoder);
+extern void r600_hdmi_disable(struct drm_encoder *encoder);
 extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
 extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder);
 extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
@@ -1189,6 +1300,14 @@ extern void r600_hdmi_update_audio_setti
 					    uint8_t status_bits,
 					    uint8_t category_code);
 
+/* evergreen */
+struct evergreen_mc_save {
+	u32 vga_control[6];
+	u32 vga_render_control;
+	u32 vga_hdp_control;
+	u32 crtc_control[6];
+};
+
 #include "radeon_object.h"
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_i2c.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_i2c.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include "drmP.h"
 #include "radeon_drm.h"
 #include "radeon.h"
+#include "atom.h"
 
 /**
  * radeon_ddc_probe
@@ -58,8 +59,9 @@ bool radeon_ddc_probe(struct radeon_conn
 	return false;
 }
 
+/* bit banging i2c */
 
-void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)
+static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)
 {
 	struct radeon_device *rdev = i2c->dev->dev_private;
 	struct radeon_i2c_bus_rec *rec = &i2c->rec;
@@ -71,13 +73,25 @@ void radeon_i2c_do_lock(struct radeon_i2
 	 */
 	if (rec->hw_capable) {
 		if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) {
-			if (rec->a_clk_reg == RADEON_GPIO_MONID) {
+			u32 reg;
+
+			if (rdev->family >= CHIP_RV350)
+				reg = RADEON_GPIO_MONID;
+			else if ((rdev->family == CHIP_R300) ||
+				 (rdev->family == CHIP_R350))
+				reg = RADEON_GPIO_DVI_DDC;
+			else
+				reg = RADEON_GPIO_CRT2_DDC;
+
+			mutex_lock(&rdev->dc_hw_i2c_mutex);
+			if (rec->a_clk_reg == reg) {
 				WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
 							       R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1)));
 			} else {
 				WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
 							       R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3)));
 			}
+			mutex_unlock(&rdev->dc_hw_i2c_mutex);
 		}
 	}
 
@@ -168,10 +182,692 @@ static void set_data(void *i2c_priv, int
 	WREG32(rec->en_data_reg, val);
 }
 
+static int pre_xfer(struct i2c_adapter *i2c_adap)
+{
+	struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
+
+	radeon_i2c_do_lock(i2c, 1);
+
+	return 0;
+}
+
+static void post_xfer(struct i2c_adapter *i2c_adap)
+{
+	struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
+
+	radeon_i2c_do_lock(i2c, 0);
+}
+
+/* hw i2c */
+
+static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)
+{
+	u32 sclk = radeon_get_engine_clock(rdev);
+	u32 prescale = 0;
+	u32 nm;
+	u8 n, m, loop;
+	int i2c_clock;
+
+	switch (rdev->family) {
+	case CHIP_R100:
+	case CHIP_RV100:
+	case CHIP_RS100:
+	case CHIP_RV200:
+	case CHIP_RS200:
+	case CHIP_R200:
+	case CHIP_RV250:
+	case CHIP_RS300:
+	case CHIP_RV280:
+	case CHIP_R300:
+	case CHIP_R350:
+	case CHIP_RV350:
+		i2c_clock = 60;
+		nm = (sclk * 10) / (i2c_clock * 4);
+		for (loop = 1; loop < 255; loop++) {
+			if ((nm / loop) < loop)
+				break;
+		}
+		n = loop - 1;
+		m = loop - 2;
+		prescale = m | (n << 8);
+		break;
+	case CHIP_RV380:
+	case CHIP_RS400:
+	case CHIP_RS480:
+	case CHIP_R420:
+	case CHIP_R423:
+	case CHIP_RV410:
+		prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128;
+		break;
+	case CHIP_RS600:
+	case CHIP_RS690:
+	case CHIP_RS740:
+		/* todo */
+		break;
+	case CHIP_RV515:
+	case CHIP_R520:
+	case CHIP_RV530:
+	case CHIP_RV560:
+	case CHIP_RV570:
+	case CHIP_R580:
+		i2c_clock = 50;
+		if (rdev->family == CHIP_R520)
+			prescale = (127 << 8) + ((sclk * 10) / (4 * 127 * i2c_clock));
+		else
+			prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128;
+		break;
+	case CHIP_R600:
+	case CHIP_RV610:
+	case CHIP_RV630:
+	case CHIP_RV670:
+		/* todo */
+		break;
+	case CHIP_RV620:
+	case CHIP_RV635:
+	case CHIP_RS780:
+	case CHIP_RS880:
+	case CHIP_RV770:
+	case CHIP_RV730:
+	case CHIP_RV710:
+	case CHIP_RV740:
+		/* todo */
+		break;
+	case CHIP_CEDAR:
+	case CHIP_REDWOOD:
+	case CHIP_JUNIPER:
+	case CHIP_CYPRESS:
+	case CHIP_HEMLOCK:
+		/* todo */
+		break;
+	default:
+		DRM_ERROR("i2c: unhandled radeon chip\n");
+		break;
+	}
+	return prescale;
+}
+
+
+/* hw i2c engine for r1xx-4xx hardware
+ * hw can buffer up to 15 bytes
+ */
+static int r100_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
+			    struct i2c_msg *msgs, int num)
+{
+	struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
+	struct radeon_device *rdev = i2c->dev->dev_private;
+	struct radeon_i2c_bus_rec *rec = &i2c->rec;
+	struct i2c_msg *p;
+	int i, j, k, ret = num;
+	u32 prescale;
+	u32 i2c_cntl_0, i2c_cntl_1, i2c_data;
+	u32 tmp, reg;
+
+	mutex_lock(&rdev->dc_hw_i2c_mutex);
+	/* take the pm lock since we need a constant sclk */
+	mutex_lock(&rdev->pm.mutex);
+
+	prescale = radeon_get_i2c_prescale(rdev);
+
+	reg = ((prescale << RADEON_I2C_PRESCALE_SHIFT) |
+	       RADEON_I2C_DRIVE_EN |
+	       RADEON_I2C_START |
+	       RADEON_I2C_STOP |
+	       RADEON_I2C_GO);
+
+	if (rdev->is_atom_bios) {
+		tmp = RREG32(RADEON_BIOS_6_SCRATCH);
+		WREG32(RADEON_BIOS_6_SCRATCH, tmp | ATOM_S6_HW_I2C_BUSY_STATE);
+	}
+
+	if (rec->mm_i2c) {
+		i2c_cntl_0 = RADEON_I2C_CNTL_0;
+		i2c_cntl_1 = RADEON_I2C_CNTL_1;
+		i2c_data = RADEON_I2C_DATA;
+	} else {
+		i2c_cntl_0 = RADEON_DVI_I2C_CNTL_0;
+		i2c_cntl_1 = RADEON_DVI_I2C_CNTL_1;
+		i2c_data = RADEON_DVI_I2C_DATA;
+
+		switch (rdev->family) {
+		case CHIP_R100:
+		case CHIP_RV100:
+		case CHIP_RS100:
+		case CHIP_RV200:
+		case CHIP_RS200:
+		case CHIP_RS300:
+			switch (rec->mask_clk_reg) {
+			case RADEON_GPIO_DVI_DDC:
+				/* no gpio select bit */
+				break;
+			default:
+				DRM_ERROR("gpio not supported with hw i2c\n");
+				ret = -EINVAL;
+				goto done;
+			}
+			break;
+		case CHIP_R200:
+			/* only bit 4 on r200 */
+			switch (rec->mask_clk_reg) {
+			case RADEON_GPIO_DVI_DDC:
+				reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1);
+				break;
+			case RADEON_GPIO_MONID:
+				reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3);
+				break;
+			default:
+				DRM_ERROR("gpio not supported with hw i2c\n");
+				ret = -EINVAL;
+				goto done;
+			}
+			break;
+		case CHIP_RV250:
+		case CHIP_RV280:
+			/* bits 3 and 4 */
+			switch (rec->mask_clk_reg) {
+			case RADEON_GPIO_DVI_DDC:
+				reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1);
+				break;
+			case RADEON_GPIO_VGA_DDC:
+				reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC2);
+				break;
+			case RADEON_GPIO_CRT2_DDC:
+				reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3);
+				break;
+			default:
+				DRM_ERROR("gpio not supported with hw i2c\n");
+				ret = -EINVAL;
+				goto done;
+			}
+			break;
+		case CHIP_R300:
+		case CHIP_R350:
+			/* only bit 4 on r300/r350 */
+			switch (rec->mask_clk_reg) {
+			case RADEON_GPIO_VGA_DDC:
+				reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1);
+				break;
+			case RADEON_GPIO_DVI_DDC:
+				reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3);
+				break;
+			default:
+				DRM_ERROR("gpio not supported with hw i2c\n");
+				ret = -EINVAL;
+				goto done;
+			}
+			break;
+		case CHIP_RV350:
+		case CHIP_RV380:
+		case CHIP_R420:
+		case CHIP_R423:
+		case CHIP_RV410:
+		case CHIP_RS400:
+		case CHIP_RS480:
+			/* bits 3 and 4 */
+			switch (rec->mask_clk_reg) {
+			case RADEON_GPIO_VGA_DDC:
+				reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1);
+				break;
+			case RADEON_GPIO_DVI_DDC:
+				reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC2);
+				break;
+			case RADEON_GPIO_MONID:
+				reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3);
+				break;
+			default:
+				DRM_ERROR("gpio not supported with hw i2c\n");
+				ret = -EINVAL;
+				goto done;
+			}
+			break;
+		default:
+			DRM_ERROR("unsupported asic\n");
+			ret = -EINVAL;
+			goto done;
+			break;
+		}
+	}
+
+	/* check for bus probe */
+	p = &msgs[0];
+	if ((num == 1) && (p->len == 0)) {
+		WREG32(i2c_cntl_0, (RADEON_I2C_DONE |
+				    RADEON_I2C_NACK |
+				    RADEON_I2C_HALT |
+				    RADEON_I2C_SOFT_RST));
+		WREG32(i2c_data, (p->addr << 1) & 0xff);
+		WREG32(i2c_data, 0);
+		WREG32(i2c_cntl_1, ((1 << RADEON_I2C_DATA_COUNT_SHIFT) |
+				    (1 << RADEON_I2C_ADDR_COUNT_SHIFT) |
+				    RADEON_I2C_EN |
+				    (48 << RADEON_I2C_TIME_LIMIT_SHIFT)));
+		WREG32(i2c_cntl_0, reg);
+		for (k = 0; k < 32; k++) {
+			udelay(10);
+			tmp = RREG32(i2c_cntl_0);
+			if (tmp & RADEON_I2C_GO)
+				continue;
+			tmp = RREG32(i2c_cntl_0);
+			if (tmp & RADEON_I2C_DONE)
+				break;
+			else {
+				DRM_DEBUG("i2c write error 0x%08x\n", tmp);
+				WREG32(i2c_cntl_0, tmp | RADEON_I2C_ABORT);
+				ret = -EIO;
+				goto done;
+			}
+		}
+		goto done;
+	}
+
+	for (i = 0; i < num; i++) {
+		p = &msgs[i];
+		for (j = 0; j < p->len; j++) {
+			if (p->flags & I2C_M_RD) {
+				WREG32(i2c_cntl_0, (RADEON_I2C_DONE |
+						    RADEON_I2C_NACK |
+						    RADEON_I2C_HALT |
+						    RADEON_I2C_SOFT_RST));
+				WREG32(i2c_data, ((p->addr << 1) & 0xff) | 0x1);
+				WREG32(i2c_cntl_1, ((1 << RADEON_I2C_DATA_COUNT_SHIFT) |
+						    (1 << RADEON_I2C_ADDR_COUNT_SHIFT) |
+						    RADEON_I2C_EN |
+						    (48 << RADEON_I2C_TIME_LIMIT_SHIFT)));
+				WREG32(i2c_cntl_0, reg | RADEON_I2C_RECEIVE);
+				for (k = 0; k < 32; k++) {
+					udelay(10);
+					tmp = RREG32(i2c_cntl_0);
+					if (tmp & RADEON_I2C_GO)
+						continue;
+					tmp = RREG32(i2c_cntl_0);
+					if (tmp & RADEON_I2C_DONE)
+						break;
+					else {
+						DRM_DEBUG("i2c read error 0x%08x\n", tmp);
+						WREG32(i2c_cntl_0, tmp | RADEON_I2C_ABORT);
+						ret = -EIO;
+						goto done;
+					}
+				}
+				p->buf[j] = RREG32(i2c_data) & 0xff;
+			} else {
+				WREG32(i2c_cntl_0, (RADEON_I2C_DONE |
+						    RADEON_I2C_NACK |
+						    RADEON_I2C_HALT |
+						    RADEON_I2C_SOFT_RST));
+				WREG32(i2c_data, (p->addr << 1) & 0xff);
+				WREG32(i2c_data, p->buf[j]);
+				WREG32(i2c_cntl_1, ((1 << RADEON_I2C_DATA_COUNT_SHIFT) |
+						    (1 << RADEON_I2C_ADDR_COUNT_SHIFT) |
+						    RADEON_I2C_EN |
+						    (48 << RADEON_I2C_TIME_LIMIT_SHIFT)));
+				WREG32(i2c_cntl_0, reg);
+				for (k = 0; k < 32; k++) {
+					udelay(10);
+					tmp = RREG32(i2c_cntl_0);
+					if (tmp & RADEON_I2C_GO)
+						continue;
+					tmp = RREG32(i2c_cntl_0);
+					if (tmp & RADEON_I2C_DONE)
+						break;
+					else {
+						DRM_DEBUG("i2c write error 0x%08x\n", tmp);
+						WREG32(i2c_cntl_0, tmp | RADEON_I2C_ABORT);
+						ret = -EIO;
+						goto done;
+					}
+				}
+			}
+		}
+	}
+
+done:
+	WREG32(i2c_cntl_0, 0);
+	WREG32(i2c_cntl_1, 0);
+	WREG32(i2c_cntl_0, (RADEON_I2C_DONE |
+			    RADEON_I2C_NACK |
+			    RADEON_I2C_HALT |
+			    RADEON_I2C_SOFT_RST));
+
+	if (rdev->is_atom_bios) {
+		tmp = RREG32(RADEON_BIOS_6_SCRATCH);
+		tmp &= ~ATOM_S6_HW_I2C_BUSY_STATE;
+		WREG32(RADEON_BIOS_6_SCRATCH, tmp);
+	}
+
+	mutex_unlock(&rdev->pm.mutex);
+	mutex_unlock(&rdev->dc_hw_i2c_mutex);
+
+	return ret;
+}
+
+/* hw i2c engine for r5xx hardware
+ * hw can buffer up to 15 bytes
+ */
+static int r500_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
+			    struct i2c_msg *msgs, int num)
+{
+	struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
+	struct radeon_device *rdev = i2c->dev->dev_private;
+	struct radeon_i2c_bus_rec *rec = &i2c->rec;
+	struct i2c_msg *p;
+	int i, j, remaining, current_count, buffer_offset, ret = num;
+	u32 prescale;
+	u32 tmp, reg;
+	u32 saved1, saved2;
+
+	mutex_lock(&rdev->dc_hw_i2c_mutex);
+	/* take the pm lock since we need a constant sclk */
+	mutex_lock(&rdev->pm.mutex);
+
+	prescale = radeon_get_i2c_prescale(rdev);
+
+	/* clear gpio mask bits */
+	tmp = RREG32(rec->mask_clk_reg);
+	tmp &= ~rec->mask_clk_mask;
+	WREG32(rec->mask_clk_reg, tmp);
+	tmp = RREG32(rec->mask_clk_reg);
+
+	tmp = RREG32(rec->mask_data_reg);
+	tmp &= ~rec->mask_data_mask;
+	WREG32(rec->mask_data_reg, tmp);
+	tmp = RREG32(rec->mask_data_reg);
+
+	/* clear pin values */
+	tmp = RREG32(rec->a_clk_reg);
+	tmp &= ~rec->a_clk_mask;
+	WREG32(rec->a_clk_reg, tmp);
+	tmp = RREG32(rec->a_clk_reg);
+
+	tmp = RREG32(rec->a_data_reg);
+	tmp &= ~rec->a_data_mask;
+	WREG32(rec->a_data_reg, tmp);
+	tmp = RREG32(rec->a_data_reg);
+
+	/* set the pins to input */
+	tmp = RREG32(rec->en_clk_reg);
+	tmp &= ~rec->en_clk_mask;
+	WREG32(rec->en_clk_reg, tmp);
+	tmp = RREG32(rec->en_clk_reg);
+
+	tmp = RREG32(rec->en_data_reg);
+	tmp &= ~rec->en_data_mask;
+	WREG32(rec->en_data_reg, tmp);
+	tmp = RREG32(rec->en_data_reg);
+
+	/* */
+	tmp = RREG32(RADEON_BIOS_6_SCRATCH);
+	WREG32(RADEON_BIOS_6_SCRATCH, tmp | ATOM_S6_HW_I2C_BUSY_STATE);
+	saved1 = RREG32(AVIVO_DC_I2C_CONTROL1);
+	saved2 = RREG32(0x494);
+	WREG32(0x494, saved2 | 0x1);
+
+	WREG32(AVIVO_DC_I2C_ARBITRATION, AVIVO_DC_I2C_SW_WANTS_TO_USE_I2C);
+	for (i = 0; i < 50; i++) {
+		udelay(1);
+		if (RREG32(AVIVO_DC_I2C_ARBITRATION) & AVIVO_DC_I2C_SW_CAN_USE_I2C)
+			break;
+	}
+	if (i == 50) {
+		DRM_ERROR("failed to get i2c bus\n");
+		ret = -EBUSY;
+		goto done;
+	}
+
+	reg = AVIVO_DC_I2C_START | AVIVO_DC_I2C_STOP | AVIVO_DC_I2C_EN;
+	switch (rec->mask_clk_reg) {
+	case AVIVO_DC_GPIO_DDC1_MASK:
+		reg |= AVIVO_DC_I2C_PIN_SELECT(AVIVO_SEL_DDC1);
+		break;
+	case AVIVO_DC_GPIO_DDC2_MASK:
+		reg |= AVIVO_DC_I2C_PIN_SELECT(AVIVO_SEL_DDC2);
+		break;
+	case AVIVO_DC_GPIO_DDC3_MASK:
+		reg |= AVIVO_DC_I2C_PIN_SELECT(AVIVO_SEL_DDC3);
+		break;
+	default:
+		DRM_ERROR("gpio not supported with hw i2c\n");
+		ret = -EINVAL;
+		goto done;
+	}
+
+	/* check for bus probe */
+	p = &msgs[0];
+	if ((num == 1) && (p->len == 0)) {
+		WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE |
+					      AVIVO_DC_I2C_NACK |
+					      AVIVO_DC_I2C_HALT));
+		WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET);
+		udelay(1);
+		WREG32(AVIVO_DC_I2C_RESET, 0);
+
+		WREG32(AVIVO_DC_I2C_DATA, (p->addr << 1) & 0xff);
+		WREG32(AVIVO_DC_I2C_DATA, 0);
+
+		WREG32(AVIVO_DC_I2C_CONTROL3, AVIVO_DC_I2C_TIME_LIMIT(48));
+		WREG32(AVIVO_DC_I2C_CONTROL2, (AVIVO_DC_I2C_ADDR_COUNT(1) |
+					       AVIVO_DC_I2C_DATA_COUNT(1) |
+					       (prescale << 16)));
+		WREG32(AVIVO_DC_I2C_CONTROL1, reg);
+		WREG32(AVIVO_DC_I2C_STATUS1, AVIVO_DC_I2C_GO);
+		for (j = 0; j < 200; j++) {
+			udelay(50);
+			tmp = RREG32(AVIVO_DC_I2C_STATUS1);
+			if (tmp & AVIVO_DC_I2C_GO)
+				continue;
+			tmp = RREG32(AVIVO_DC_I2C_STATUS1);
+			if (tmp & AVIVO_DC_I2C_DONE)
+				break;
+			else {
+				DRM_DEBUG("i2c write error 0x%08x\n", tmp);
+				WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_ABORT);
+				ret = -EIO;
+				goto done;
+			}
+		}
+		goto done;
+	}
+
+	for (i = 0; i < num; i++) {
+		p = &msgs[i];
+		remaining = p->len;
+		buffer_offset = 0;
+		if (p->flags & I2C_M_RD) {
+			while (remaining) {
+				if (remaining > 15)
+					current_count = 15;
+				else
+					current_count = remaining;
+				WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE |
+							      AVIVO_DC_I2C_NACK |
+							      AVIVO_DC_I2C_HALT));
+				WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET);
+				udelay(1);
+				WREG32(AVIVO_DC_I2C_RESET, 0);
+
+				WREG32(AVIVO_DC_I2C_DATA, ((p->addr << 1) & 0xff) | 0x1);
+				WREG32(AVIVO_DC_I2C_CONTROL3, AVIVO_DC_I2C_TIME_LIMIT(48));
+				WREG32(AVIVO_DC_I2C_CONTROL2, (AVIVO_DC_I2C_ADDR_COUNT(1) |
+							       AVIVO_DC_I2C_DATA_COUNT(current_count) |
+							       (prescale << 16)));
+				WREG32(AVIVO_DC_I2C_CONTROL1, reg | AVIVO_DC_I2C_RECEIVE);
+				WREG32(AVIVO_DC_I2C_STATUS1, AVIVO_DC_I2C_GO);
+				for (j = 0; j < 200; j++) {
+					udelay(50);
+					tmp = RREG32(AVIVO_DC_I2C_STATUS1);
+					if (tmp & AVIVO_DC_I2C_GO)
+						continue;
+					tmp = RREG32(AVIVO_DC_I2C_STATUS1);
+					if (tmp & AVIVO_DC_I2C_DONE)
+						break;
+					else {
+						DRM_DEBUG("i2c read error 0x%08x\n", tmp);
+						WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_ABORT);
+						ret = -EIO;
+						goto done;
+					}
+				}
+				for (j = 0; j < current_count; j++)
+					p->buf[buffer_offset + j] = RREG32(AVIVO_DC_I2C_DATA) & 0xff;
+				remaining -= current_count;
+				buffer_offset += current_count;
+			}
+		} else {
+			while (remaining) {
+				if (remaining > 15)
+					current_count = 15;
+				else
+					current_count = remaining;
+				WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE |
+							      AVIVO_DC_I2C_NACK |
+							      AVIVO_DC_I2C_HALT));
+				WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET);
+				udelay(1);
+				WREG32(AVIVO_DC_I2C_RESET, 0);
+
+				WREG32(AVIVO_DC_I2C_DATA, (p->addr << 1) & 0xff);
+				for (j = 0; j < current_count; j++)
+					WREG32(AVIVO_DC_I2C_DATA, p->buf[buffer_offset + j]);
+
+				WREG32(AVIVO_DC_I2C_CONTROL3, AVIVO_DC_I2C_TIME_LIMIT(48));
+				WREG32(AVIVO_DC_I2C_CONTROL2, (AVIVO_DC_I2C_ADDR_COUNT(1) |
+							       AVIVO_DC_I2C_DATA_COUNT(current_count) |
+							       (prescale << 16)));
+				WREG32(AVIVO_DC_I2C_CONTROL1, reg);
+				WREG32(AVIVO_DC_I2C_STATUS1, AVIVO_DC_I2C_GO);
+				for (j = 0; j < 200; j++) {
+					udelay(50);
+					tmp = RREG32(AVIVO_DC_I2C_STATUS1);
+					if (tmp & AVIVO_DC_I2C_GO)
+						continue;
+					tmp = RREG32(AVIVO_DC_I2C_STATUS1);
+					if (tmp & AVIVO_DC_I2C_DONE)
+						break;
+					else {
+						DRM_DEBUG("i2c write error 0x%08x\n", tmp);
+						WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_ABORT);
+						ret = -EIO;
+						goto done;
+					}
+				}
+				remaining -= current_count;
+				buffer_offset += current_count;
+			}
+		}
+	}
+
+done:
+	WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE |
+				      AVIVO_DC_I2C_NACK |
+				      AVIVO_DC_I2C_HALT));
+	WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET);
+	udelay(1);
+	WREG32(AVIVO_DC_I2C_RESET, 0);
+
+	WREG32(AVIVO_DC_I2C_ARBITRATION, AVIVO_DC_I2C_SW_DONE_USING_I2C);
+	WREG32(AVIVO_DC_I2C_CONTROL1, saved1);
+	WREG32(0x494, saved2);
+	tmp = RREG32(RADEON_BIOS_6_SCRATCH);
+	tmp &= ~ATOM_S6_HW_I2C_BUSY_STATE;
+	WREG32(RADEON_BIOS_6_SCRATCH, tmp);
+
+	mutex_unlock(&rdev->pm.mutex);
+	mutex_unlock(&rdev->dc_hw_i2c_mutex);
+
+	return ret;
+}
+
+static int radeon_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
+			      struct i2c_msg *msgs, int num)
+{
+	struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
+	struct radeon_device *rdev = i2c->dev->dev_private;
+	struct radeon_i2c_bus_rec *rec = &i2c->rec;
+	int ret = 0;
+
+	switch (rdev->family) {
+	case CHIP_R100:
+	case CHIP_RV100:
+	case CHIP_RS100:
+	case CHIP_RV200:
+	case CHIP_RS200:
+	case CHIP_R200:
+	case CHIP_RV250:
+	case CHIP_RS300:
+	case CHIP_RV280:
+	case CHIP_R300:
+	case CHIP_R350:
+	case CHIP_RV350:
+	case CHIP_RV380:
+	case CHIP_R420:
+	case CHIP_R423:
+	case CHIP_RV410:
+	case CHIP_RS400:
+	case CHIP_RS480:
+		ret = r100_hw_i2c_xfer(i2c_adap, msgs, num);
+		break;
+	case CHIP_RS600:
+	case CHIP_RS690:
+	case CHIP_RS740:
+		/* XXX fill in hw i2c implementation */
+		break;
+	case CHIP_RV515:
+	case CHIP_R520:
+	case CHIP_RV530:
+	case CHIP_RV560:
+	case CHIP_RV570:
+	case CHIP_R580:
+		if (rec->mm_i2c)
+			ret = r100_hw_i2c_xfer(i2c_adap, msgs, num);
+		else
+			ret = r500_hw_i2c_xfer(i2c_adap, msgs, num);
+		break;
+	case CHIP_R600:
+	case CHIP_RV610:
+	case CHIP_RV630:
+	case CHIP_RV670:
+		/* XXX fill in hw i2c implementation */
+		break;
+	case CHIP_RV620:
+	case CHIP_RV635:
+	case CHIP_RS780:
+	case CHIP_RS880:
+	case CHIP_RV770:
+	case CHIP_RV730:
+	case CHIP_RV710:
+	case CHIP_RV740:
+		/* XXX fill in hw i2c implementation */
+		break;
+	case CHIP_CEDAR:
+	case CHIP_REDWOOD:
+	case CHIP_JUNIPER:
+	case CHIP_CYPRESS:
+	case CHIP_HEMLOCK:
+		/* XXX fill in hw i2c implementation */
+		break;
+	default:
+		DRM_ERROR("i2c: unhandled radeon chip\n");
+		ret = -EIO;
+		break;
+	}
+
+	return ret;
+}
+
+static u32 radeon_hw_i2c_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm radeon_i2c_algo = {
+	.master_xfer = radeon_hw_i2c_xfer,
+	.functionality = radeon_hw_i2c_func,
+};
+
 struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
 					  struct radeon_i2c_bus_rec *rec,
 					  const char *name)
 {
+	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_i2c_chan *i2c;
 	int ret;
 
@@ -179,24 +875,43 @@ struct radeon_i2c_chan *radeon_i2c_creat
 	if (i2c == NULL)
 		return NULL;
 
+	i2c->rec = *rec;
 	i2c->adapter.owner = THIS_MODULE;
 	i2c->dev = dev;
 	i2c_set_adapdata(&i2c->adapter, i2c);
-	i2c->adapter.algo_data = &i2c->algo.bit;
-	i2c->algo.bit.setsda = set_data;
-	i2c->algo.bit.setscl = set_clock;
-	i2c->algo.bit.getsda = get_data;
-	i2c->algo.bit.getscl = get_clock;
-	i2c->algo.bit.udelay = 20;
-	/* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always
-	 * make this, 2 jiffies is a lot more reliable */
-	i2c->algo.bit.timeout = 2;
-	i2c->algo.bit.data = i2c;
-	i2c->rec = *rec;
-	ret = i2c_bit_add_bus(&i2c->adapter);
-	if (ret) {
-		DRM_INFO("Failed to register i2c %s\n", name);
-		goto out_free;
+	if (rec->mm_i2c ||
+	    (rec->hw_capable &&
+	     radeon_hw_i2c &&
+	     ((rdev->family <= CHIP_RS480) ||
+	      ((rdev->family >= CHIP_RV515) && (rdev->family <= CHIP_R580))))) {
+		/* set the radeon hw i2c adapter */
+		sprintf(i2c->adapter.name, "Radeon i2c hw bus %s", name);
+		i2c->adapter.algo = &radeon_i2c_algo;
+		ret = i2c_add_adapter(&i2c->adapter);
+		if (ret) {
+			DRM_ERROR("Failed to register hw i2c %s\n", name);
+			goto out_free;
+		}
+	} else {
+		/* set the radeon bit adapter */
+		sprintf(i2c->adapter.name, "Radeon i2c bit bus %s", name);
+		i2c->adapter.algo_data = &i2c->algo.bit;
+		i2c->algo.bit.pre_xfer = pre_xfer;
+		i2c->algo.bit.post_xfer = post_xfer;
+		i2c->algo.bit.setsda = set_data;
+		i2c->algo.bit.setscl = set_clock;
+		i2c->algo.bit.getsda = get_data;
+		i2c->algo.bit.getscl = get_clock;
+		i2c->algo.bit.udelay = 20;
+		/* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always
+		 * make this, 2 jiffies is a lot more reliable */
+		i2c->algo.bit.timeout = 2;
+		i2c->algo.bit.data = i2c;
+		ret = i2c_bit_add_bus(&i2c->adapter);
+		if (ret) {
+			DRM_ERROR("Failed to register bit i2c %s\n", name);
+			goto out_free;
+		}
 	}
 
 	return i2c;
@@ -237,12 +952,10 @@ out_free:
 
 }
 
-
 void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)
 {
 	if (!i2c)
 		return;
-
 	i2c_del_adapter(&i2c->adapter);
 	kfree(i2c);
 }
@@ -252,10 +965,10 @@ struct drm_encoder *radeon_best_encoder(
 	return NULL;
 }
 
-void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus,
-			    u8 slave_addr,
-			    u8 addr,
-			    u8 *val)
+void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus,
+			 u8 slave_addr,
+			 u8 addr,
+			 u8 *val)
 {
 	u8 out_buf[2];
 	u8 in_buf[2];
@@ -286,10 +999,10 @@ void radeon_i2c_sw_get_byte(struct radeo
 	}
 }
 
-void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c_bus,
-			    u8 slave_addr,
-			    u8 addr,
-			    u8 val)
+void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus,
+			 u8 slave_addr,
+			 u8 addr,
+			 u8 val)
 {
 	uint8_t out_buf[2];
 	struct i2c_msg msg = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_irq_kms.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_irq_kms.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_irq_kms.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_irq_kms.c	2010-05-16 17:17:36.000000000 -0400
@@ -67,9 +67,10 @@ void radeon_driver_irq_preinstall_kms(st
 
 	/* Disable *all* interrupts */
 	rdev->irq.sw_int = false;
-	for (i = 0; i < 2; i++) {
+	for (i = 0; i < rdev->num_crtc; i++)
 		rdev->irq.crtc_vblank_int[i] = false;
-	}
+	for (i = 0; i < 6; i++)
+		rdev->irq.hpd[i] = false;
 	radeon_irq_set(rdev);
 	/* Clear bits */
 	radeon_irq_process(rdev);
@@ -95,34 +96,29 @@ void radeon_driver_irq_uninstall_kms(str
 	}
 	/* Disable *all* interrupts */
 	rdev->irq.sw_int = false;
-	for (i = 0; i < 2; i++) {
+	for (i = 0; i < rdev->num_crtc; i++)
 		rdev->irq.crtc_vblank_int[i] = false;
+	for (i = 0; i < 6; i++)
 		rdev->irq.hpd[i] = false;
-	}
 	radeon_irq_set(rdev);
 }
 
 int radeon_irq_kms_init(struct radeon_device *rdev)
 {
 	int r = 0;
-	int num_crtc = 2;
 
-	if (rdev->flags & RADEON_SINGLE_CRTC)
-		num_crtc = 1;
 	spin_lock_init(&rdev->irq.sw_lock);
-	r = drm_vblank_init(rdev->ddev, num_crtc);
+	r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
 	if (r) {
 		return r;
 	}
 	/* enable msi */
 	rdev->msi_enabled = 0;
-	/* MSIs don't seem to work on my rs780;
-	 * not sure about rs880 or other rs780s.
-	 * Needs more investigation.
+	/* MSIs don't seem to work reliably on all IGP
+	 * chips.  Disable MSI on them for now.
 	 */
 	if ((rdev->family >= CHIP_RV380) &&
-	    (rdev->family != CHIP_RS780) &&
-	    (rdev->family != CHIP_RS880)) {
+	    (!(rdev->flags & RADEON_IS_IGP))) {
 		int ret = pci_enable_msi(rdev->pdev);
 		if (!ret) {
 			rdev->msi_enabled = 1;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_kms.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_kms.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_kms.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_kms.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,9 @@
 #include "radeon.h"
 #include "radeon_drm.h"
 
+#include <linux/vga_switcheroo.h>
+#include <linux/slab.h>
+
 int radeon_driver_unload_kms(struct drm_device *dev)
 {
 	struct radeon_device *rdev = dev->dev_private;
@@ -136,6 +139,7 @@ int radeon_driver_firstopen_kms(struct d
 
 void radeon_driver_lastclose_kms(struct drm_device *dev)
 {
+	vga_switcheroo_process_delayed_switch();
 }
 
 int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
@@ -161,7 +165,7 @@ u32 radeon_get_vblank_counter_kms(struct
 {
 	struct radeon_device *rdev = dev->dev_private;
 
-	if (crtc < 0 || crtc > 1) {
+	if (crtc < 0 || crtc >= rdev->num_crtc) {
 		DRM_ERROR("Invalid crtc %d\n", crtc);
 		return -EINVAL;
 	}
@@ -173,7 +177,7 @@ int radeon_enable_vblank_kms(struct drm_
 {
 	struct radeon_device *rdev = dev->dev_private;
 
-	if (crtc < 0 || crtc > 1) {
+	if (crtc < 0 || crtc >= rdev->num_crtc) {
 		DRM_ERROR("Invalid crtc %d\n", crtc);
 		return -EINVAL;
 	}
@@ -187,7 +191,7 @@ void radeon_disable_vblank_kms(struct dr
 {
 	struct radeon_device *rdev = dev->dev_private;
 
-	if (crtc < 0 || crtc > 1) {
+	if (crtc < 0 || crtc >= rdev->num_crtc) {
 		DRM_ERROR("Invalid crtc %d\n", crtc);
 		return;
 	}
@@ -276,17 +280,17 @@ struct drm_ioctl_desc radeon_ioctls_kms[
 	DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc_kms, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free_kms, DRM_AUTH),
 	/* KMS */
-	DRM_IOCTL_DEF(DRM_RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED),
 };
 int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_legacy_crtc.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_legacy_crtc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_legacy_crtc.c	2010-05-16 17:17:36.000000000 -0400
@@ -403,7 +403,7 @@ int radeon_crtc_set_base(struct drm_crtc
 
 	/* if scanout was in GTT this really wouldn't work */
 	/* crtc offset is from display base addr not FB location */
-	radeon_crtc->legacy_display_base_addr = rdev->mc.vram_location;
+	radeon_crtc->legacy_display_base_addr = rdev->mc.vram_start;
 
 	base -= radeon_crtc->legacy_display_base_addr;
 
@@ -582,29 +582,6 @@ static bool radeon_set_crtc_timing(struc
 				   ? RADEON_CRTC_V_SYNC_POL
 				   : 0));
 
-	/* TODO -> Dell Server */
-	if (0) {
-		uint32_t disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG);
-		uint32_t tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
-		uint32_t dac2_cntl = RREG32(RADEON_DAC_CNTL2);
-		uint32_t crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
-
-		dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL;
-		dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
-
-		/* For CRT on DAC2, don't turn it on if BIOS didn't
-		   enable it, even it's detected.
-		*/
-		disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
-		tv_dac_cntl &= ~((1<<2) | (3<<8) | (7<<24) | (0xff<<16));
-		tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16));
-
-		WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
-		WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
-		WREG32(RADEON_DAC_CNTL2, dac2_cntl);
-		WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
-	}
-
 	if (radeon_crtc->crtc_id) {
 		uint32_t crtc2_gen_cntl;
 		uint32_t disp2_merge_cntl;
@@ -626,6 +603,10 @@ static bool radeon_set_crtc_timing(struc
 				      ? RADEON_CRTC2_INTERLACE_EN
 				      : 0));
 
+		/* rs4xx chips seem to like to have the crtc enabled when the timing is set */
+		if ((rdev->family == CHIP_RS400) || (rdev->family == CHIP_RS480))
+			crtc2_gen_cntl |= RADEON_CRTC2_EN;
+
 		disp2_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL);
 		disp2_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN;
 
@@ -653,6 +634,10 @@ static bool radeon_set_crtc_timing(struc
 				    ? RADEON_CRTC_INTERLACE_EN
 				    : 0));
 
+		/* rs4xx chips seem to like to have the crtc enabled when the timing is set */
+		if ((rdev->family == CHIP_RS400) || (rdev->family == CHIP_RS480))
+			crtc_gen_cntl |= RADEON_CRTC_EN;
+
 		crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
 		crtc_ext_cntl |= (RADEON_XCRT_CNT_EN |
 				  RADEON_CRTC_VSYNC_DIS |
@@ -726,6 +711,10 @@ static void radeon_set_pll(struct drm_cr
 		pll = &rdev->clock.p1pll;
 
 	pll->flags = RADEON_PLL_LEGACY;
+	if (radeon_new_pll == 1)
+		pll->algo = PLL_ALGO_NEW;
+	else
+		pll->algo = PLL_ALGO_LEGACY;
 
 	if (mode->clock > 200000) /* range limits??? */
 		pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_legacy_encoders.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_legacy_encoders.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_legacy_encoders.c	2010-05-16 17:17:36.000000000 -0400
@@ -115,6 +115,9 @@ static void radeon_legacy_lvds_dpms(stru
 		radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
 	else
 		radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
+
+	/* adjust pm to dpms change */
+	radeon_pm_compute_clocks(rdev);
 }
 
 static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder)
@@ -214,22 +217,19 @@ static bool radeon_legacy_mode_fixup(str
 				     struct drm_display_mode *adjusted_mode)
 {
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+
+	/* adjust pm to upcoming mode change */
+	radeon_pm_compute_clocks(rdev);
 
 	/* set the active encoder to connector routing */
 	radeon_encoder_set_active_device(encoder);
 	drm_mode_set_crtcinfo(adjusted_mode, 0);
 
 	/* get the native mode for LVDS */
-	if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
-		struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
-		int mode_id = adjusted_mode->base.id;
-		*adjusted_mode = *native_mode;
-		adjusted_mode->hdisplay = mode->hdisplay;
-		adjusted_mode->vdisplay = mode->vdisplay;
-		adjusted_mode->crtc_hdisplay = mode->hdisplay;
-		adjusted_mode->crtc_vdisplay = mode->vdisplay;
-		adjusted_mode->base.id = mode_id;
-	}
+	if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT))
+		radeon_panel_mode_fixup(encoder, adjusted_mode);
 
 	return true;
 }
@@ -285,6 +285,9 @@ static void radeon_legacy_primary_dac_dp
 		radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
 	else
 		radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
+
+	/* adjust pm to dpms change */
+	radeon_pm_compute_clocks(rdev);
 }
 
 static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder)
@@ -470,6 +473,9 @@ static void radeon_legacy_tmds_int_dpms(
 		radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
 	else
 		radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
+
+	/* adjust pm to dpms change */
+	radeon_pm_compute_clocks(rdev);
 }
 
 static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder)
@@ -635,6 +641,9 @@ static void radeon_legacy_tmds_ext_dpms(
 		radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
 	else
 		radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
+
+	/* adjust pm to dpms change */
+	radeon_pm_compute_clocks(rdev);
 }
 
 static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder)
@@ -813,8 +822,8 @@ static void radeon_legacy_tv_dac_dpms(st
 				crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
 
 			if (rdev->family == CHIP_R420 ||
-					rdev->family == CHIP_R423 ||
-					rdev->family == CHIP_RV410)
+			    rdev->family == CHIP_R423 ||
+			    rdev->family == CHIP_RV410)
 				tv_dac_cntl |= (R420_TV_DAC_RDACPD |
 						R420_TV_DAC_GDACPD |
 						R420_TV_DAC_BDACPD |
@@ -842,6 +851,9 @@ static void radeon_legacy_tv_dac_dpms(st
 		radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
 	else
 		radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
+
+	/* adjust pm to dpms change */
+	radeon_pm_compute_clocks(rdev);
 }
 
 static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder)
@@ -887,35 +899,43 @@ static void radeon_legacy_tv_dac_mode_se
 	if (rdev->family != CHIP_R200) {
 		tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
 		if (rdev->family == CHIP_R420 ||
-				rdev->family == CHIP_R423 ||
-				rdev->family == CHIP_RV410) {
+		    rdev->family == CHIP_R423 ||
+		    rdev->family == CHIP_RV410) {
 			tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
-					RADEON_TV_DAC_BGADJ_MASK |
-					R420_TV_DAC_DACADJ_MASK |
-					R420_TV_DAC_RDACPD |
-					R420_TV_DAC_GDACPD |
-					R420_TV_DAC_BDACPD |
-					R420_TV_DAC_TVENABLE);
+					 RADEON_TV_DAC_BGADJ_MASK |
+					 R420_TV_DAC_DACADJ_MASK |
+					 R420_TV_DAC_RDACPD |
+					 R420_TV_DAC_GDACPD |
+					 R420_TV_DAC_BDACPD |
+					 R420_TV_DAC_TVENABLE);
 		} else {
 			tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
-					RADEON_TV_DAC_BGADJ_MASK |
-					RADEON_TV_DAC_DACADJ_MASK |
-					RADEON_TV_DAC_RDACPD |
-					RADEON_TV_DAC_GDACPD |
-					RADEON_TV_DAC_BDACPD);
+					 RADEON_TV_DAC_BGADJ_MASK |
+					 RADEON_TV_DAC_DACADJ_MASK |
+					 RADEON_TV_DAC_RDACPD |
+					 RADEON_TV_DAC_GDACPD |
+					 RADEON_TV_DAC_BDACPD);
 		}
 
-		/*  FIXME TV */
-		if (tv_dac) {
-			struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
-			tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
-					RADEON_TV_DAC_NHOLD |
-					RADEON_TV_DAC_STD_PS2 |
-					tv_dac->ps2_tvdac_adj);
+		tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD;
+
+		if (is_tv) {
+			if (tv_dac->tv_std == TV_STD_NTSC ||
+			    tv_dac->tv_std == TV_STD_NTSC_J ||
+			    tv_dac->tv_std == TV_STD_PAL_M ||
+			    tv_dac->tv_std == TV_STD_PAL_60)
+				tv_dac_cntl |= tv_dac->ntsc_tvdac_adj;
+			else
+				tv_dac_cntl |= tv_dac->pal_tvdac_adj;
+
+			if (tv_dac->tv_std == TV_STD_NTSC ||
+			    tv_dac->tv_std == TV_STD_NTSC_J)
+				tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
+			else
+				tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
 		} else
-			tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
-					RADEON_TV_DAC_NHOLD |
-					RADEON_TV_DAC_STD_PS2);
+			tv_dac_cntl |= (RADEON_TV_DAC_STD_PS2 |
+					tv_dac->ps2_tvdac_adj);
 
 		WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_legacy_tv.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_legacy_tv.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_legacy_tv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_legacy_tv.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,6 +57,10 @@
 #define NTSC_TV_PLL_N_14 693
 #define NTSC_TV_PLL_P_14 7
 
+#define PAL_TV_PLL_M_14 19
+#define PAL_TV_PLL_N_14 353
+#define PAL_TV_PLL_P_14 5
+
 #define VERT_LEAD_IN_LINES 2
 #define FRAC_BITS 0xe
 #define FRAC_MASK 0x3fff
@@ -205,9 +209,24 @@ static const struct radeon_tv_mode_const
 		630627,             /* defRestart */
 		347,                /* crtcPLL_N */
 		14,                 /* crtcPLL_M */
-			8,                  /* crtcPLL_postDiv */
+		8,                  /* crtcPLL_postDiv */
 		1022,               /* pixToTV */
 	},
+	{ /* PAL timing for 14 Mhz ref clk */
+		800,                /* horResolution */
+		600,                /* verResolution */
+		TV_STD_PAL,         /* standard */
+		1131,               /* horTotal */
+		742,                /* verTotal */
+		813,                /* horStart */
+		840,                /* horSyncStart */
+		633,                /* verSyncStart */
+		708369,             /* defRestart */
+		211,                /* crtcPLL_N */
+		9,                  /* crtcPLL_M */
+		8,                  /* crtcPLL_postDiv */
+		759,                /* pixToTV */
+	},
 };
 
 #define N_AVAILABLE_MODES ARRAY_SIZE(available_tv_modes)
@@ -242,7 +261,7 @@ static const struct radeon_tv_mode_const
 		if (pll->reference_freq == 2700)
 			const_ptr = &available_tv_modes[1];
 		else
-			const_ptr = &available_tv_modes[1]; /* FIX ME */
+			const_ptr = &available_tv_modes[3];
 	}
 	return const_ptr;
 }
@@ -685,9 +704,9 @@ void radeon_legacy_tv_mode_set(struct dr
 			n = PAL_TV_PLL_N_27;
 			p = PAL_TV_PLL_P_27;
 		} else {
-			m = PAL_TV_PLL_M_27;
-			n = PAL_TV_PLL_N_27;
-			p = PAL_TV_PLL_P_27;
+			m = PAL_TV_PLL_M_14;
+			n = PAL_TV_PLL_N_14;
+			p = PAL_TV_PLL_P_14;
 		}
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_mode.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_mode.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_mode.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_mode.h	2010-05-16 17:17:36.000000000 -0400
@@ -83,6 +83,8 @@ struct radeon_i2c_bus_rec {
 	bool valid;
 	/* id used by atom */
 	uint8_t i2c_id;
+	/* id used by atom */
+	uint8_t hpd_id;
 	/* can be used with hw i2c engine */
 	bool hw_capable;
 	/* uses multi-media i2c engine */
@@ -113,6 +115,7 @@ struct radeon_tmds_pll {
 
 #define RADEON_MAX_BIOS_CONNECTOR 16
 
+/* pll flags */
 #define RADEON_PLL_USE_BIOS_DIVS        (1 << 0)
 #define RADEON_PLL_NO_ODD_POST_DIV      (1 << 1)
 #define RADEON_PLL_USE_REF_DIV          (1 << 2)
@@ -126,6 +129,13 @@ struct radeon_tmds_pll {
 #define RADEON_PLL_USE_FRAC_FB_DIV      (1 << 10)
 #define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11)
 #define RADEON_PLL_USE_POST_DIV         (1 << 12)
+#define RADEON_PLL_IS_LCD               (1 << 13)
+
+/* pll algo */
+enum radeon_pll_algo {
+	PLL_ALGO_LEGACY,
+	PLL_ALGO_NEW
+};
 
 struct radeon_pll {
 	/* reference frequency */
@@ -140,6 +150,8 @@ struct radeon_pll {
 	uint32_t pll_in_max;
 	uint32_t pll_out_min;
 	uint32_t pll_out_max;
+	uint32_t lcd_pll_out_min;
+	uint32_t lcd_pll_out_max;
 	uint32_t best_vco;
 
 	/* divider limits */
@@ -157,14 +169,16 @@ struct radeon_pll {
 
 	/* pll id */
 	uint32_t id;
+	/* pll algo */
+	enum radeon_pll_algo algo;
 };
 
 struct radeon_i2c_chan {
 	struct i2c_adapter adapter;
 	struct drm_device *dev;
 	union {
-		struct i2c_algo_dp_aux_data dp;
 		struct i2c_algo_bit_data bit;
+		struct i2c_algo_dp_aux_data dp;
 	} algo;
 	struct radeon_i2c_bus_rec rec;
 };
@@ -193,7 +207,7 @@ struct radeon_mode_info {
 	struct card_info *atom_card_info;
 	enum radeon_connector_table connector_table;
 	bool mode_config_initialized;
-	struct radeon_crtc *crtcs[2];
+	struct radeon_crtc *crtcs[6];
 	/* DVI-I properties */
 	struct drm_property *coherent_mode_property;
 	/* DAC enable load detect */
@@ -202,7 +216,8 @@ struct radeon_mode_info {
 	struct drm_property *tv_std_property;
 	/* legacy TMDS PLL detect */
 	struct drm_property *tmds_pll_property;
-
+	/* hardcoded DFP edid from BIOS */
+	struct edid *bios_hardcoded_edid;
 };
 
 #define MAX_H_CODE_TIMING_LEN 32
@@ -237,6 +252,7 @@ struct radeon_crtc {
 	fixed20_12 vsc;
 	fixed20_12 hsc;
 	struct drm_display_mode native_mode;
+	int pll_id;
 };
 
 struct radeon_encoder_primary_dac {
@@ -303,6 +319,7 @@ struct radeon_encoder_atom_dig {
 	/* atom lvds */
 	uint32_t lvds_misc;
 	uint16_t panel_pwr_delay;
+	enum radeon_pll_algo pll_algo;
 	struct radeon_atom_ss *ss;
 	/* panel mode */
 	struct drm_display_mode native_mode;
@@ -323,6 +340,7 @@ struct radeon_encoder {
 	struct drm_display_mode native_mode;
 	void *enc_priv;
 	int hdmi_offset;
+	int hdmi_config_offset;
 	int hdmi_audio_workaround;
 	int hdmi_buffer_status;
 };
@@ -398,6 +416,7 @@ extern void dp_link_train(struct drm_enc
 			  struct drm_connector *connector);
 extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
 extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
+extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action);
 extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
 					   int action, uint8_t lane_num,
 					   uint8_t lane_set);
@@ -411,14 +430,14 @@ extern struct radeon_i2c_chan *radeon_i2
 						 struct radeon_i2c_bus_rec *rec,
 						 const char *name);
 extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c);
-extern void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus,
-				   u8 slave_addr,
-				   u8 addr,
-				   u8 *val);
-extern void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c,
-				   u8 slave_addr,
-				   u8 addr,
-				   u8 val);
+extern void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus,
+				u8 slave_addr,
+				u8 addr,
+				u8 *val);
+extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c,
+				u8 slave_addr,
+				u8 addr,
+				u8 val);
 extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector);
 extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
 
@@ -432,14 +451,6 @@ extern void radeon_compute_pll(struct ra
 			       uint32_t *ref_div_p,
 			       uint32_t *post_div_p);
 
-extern void radeon_compute_pll_avivo(struct radeon_pll *pll,
-				     uint64_t freq,
-				     uint32_t *dot_clock_p,
-				     uint32_t *fb_div_p,
-				     uint32_t *frac_fb_div_p,
-				     uint32_t *ref_div_p,
-				     uint32_t *post_div_p);
-
 extern void radeon_setup_encoder_clones(struct drm_device *dev);
 
 struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index);
@@ -473,6 +484,9 @@ extern int radeon_crtc_cursor_set(struct
 extern int radeon_crtc_cursor_move(struct drm_crtc *crtc,
 				   int x, int y);
 
+extern bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev);
+extern struct edid *
+radeon_combios_get_hardcoded_edid(struct radeon_device *rdev);
 extern bool radeon_atom_get_clock_info(struct drm_device *dev);
 extern bool radeon_combios_get_clock_info(struct drm_device *dev);
 extern struct radeon_encoder_atom_dig *
@@ -531,7 +545,6 @@ void radeon_atombios_init_crtc(struct dr
 			       struct radeon_crtc *radeon_crtc);
 void radeon_legacy_init_crtc(struct drm_device *dev,
 			     struct radeon_crtc *radeon_crtc);
-extern void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state);
 
 void radeon_get_clock_info(struct drm_device *dev);
 
@@ -545,6 +558,8 @@ extern int radeon_static_clocks_init(str
 bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
 					struct drm_display_mode *mode,
 					struct drm_display_mode *adjusted_mode);
+void radeon_panel_mode_fixup(struct drm_encoder *encoder,
+			     struct drm_display_mode *adjusted_mode);
 void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc);
 
 /* legacy tv */
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_object.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_object.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_object.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_object.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
  *    Dave Airlie
  */
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <drm/drmP.h>
 #include "radeon_drm.h"
 #include "radeon.h"
@@ -178,7 +179,6 @@ int radeon_bo_pin(struct radeon_bo *bo,
 {
 	int r, i;
 
-	radeon_ttm_placement_from_domain(bo, domain);
 	if (bo->pin_count) {
 		bo->pin_count++;
 		if (gpu_addr)
@@ -186,6 +186,10 @@ int radeon_bo_pin(struct radeon_bo *bo,
 		return 0;
 	}
 	radeon_ttm_placement_from_domain(bo, domain);
+	if (domain == RADEON_GEM_DOMAIN_VRAM) {
+		/* force to pin into visible video ram */
+		bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> PAGE_SHIFT;
+	}
 	for (i = 0; i < bo->placement.num_placement; i++)
 		bo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
 	r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_pm.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_pm.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_pm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,21 +18,441 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  *
  * Authors: RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com>
+ *          Alex Deucher <alexdeucher@gmail.com>
  */
 #include "drmP.h"
 #include "radeon.h"
+#include "avivod.h"
 
-int radeon_debugfs_pm_init(struct radeon_device *rdev);
+#define RADEON_IDLE_LOOP_MS 100
+#define RADEON_RECLOCK_DELAY_MS 200
+#define RADEON_WAIT_VBLANK_TIMEOUT 200
+
+static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish);
+static void radeon_pm_set_clocks_locked(struct radeon_device *rdev);
+static void radeon_pm_set_clocks(struct radeon_device *rdev);
+static void radeon_pm_idle_work_handler(struct work_struct *work);
+static int radeon_debugfs_pm_init(struct radeon_device *rdev);
+
+static const char *pm_state_names[4] = {
+	"PM_STATE_DISABLED",
+	"PM_STATE_MINIMUM",
+	"PM_STATE_PAUSED",
+	"PM_STATE_ACTIVE"
+};
+
+static const char *pm_state_types[5] = {
+	"Default",
+	"Powersave",
+	"Battery",
+	"Balanced",
+	"Performance",
+};
+
+static void radeon_print_power_mode_info(struct radeon_device *rdev)
+{
+	int i, j;
+	bool is_default;
+
+	DRM_INFO("%d Power State(s)\n", rdev->pm.num_power_states);
+	for (i = 0; i < rdev->pm.num_power_states; i++) {
+		if (rdev->pm.default_power_state == &rdev->pm.power_state[i])
+			is_default = true;
+		else
+			is_default = false;
+		DRM_INFO("State %d %s %s\n", i,
+			 pm_state_types[rdev->pm.power_state[i].type],
+			 is_default ? "(default)" : "");
+		if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP))
+			DRM_INFO("\t%d PCIE Lanes\n", rdev->pm.power_state[i].non_clock_info.pcie_lanes);
+		DRM_INFO("\t%d Clock Mode(s)\n", rdev->pm.power_state[i].num_clock_modes);
+		for (j = 0; j < rdev->pm.power_state[i].num_clock_modes; j++) {
+			if (rdev->flags & RADEON_IS_IGP)
+				DRM_INFO("\t\t%d engine: %d\n",
+					 j,
+					 rdev->pm.power_state[i].clock_info[j].sclk * 10);
+			else
+				DRM_INFO("\t\t%d engine/memory: %d/%d\n",
+					 j,
+					 rdev->pm.power_state[i].clock_info[j].sclk * 10,
+					 rdev->pm.power_state[i].clock_info[j].mclk * 10);
+		}
+	}
+}
+
+static struct radeon_power_state * radeon_pick_power_state(struct radeon_device *rdev,
+							   enum radeon_pm_state_type type)
+{
+	int i, j;
+	enum radeon_pm_state_type wanted_types[2];
+	int wanted_count;
+
+	switch (type) {
+	case POWER_STATE_TYPE_DEFAULT:
+	default:
+		return rdev->pm.default_power_state;
+	case POWER_STATE_TYPE_POWERSAVE:
+		if (rdev->flags & RADEON_IS_MOBILITY) {
+			wanted_types[0] = POWER_STATE_TYPE_POWERSAVE;
+			wanted_types[1] = POWER_STATE_TYPE_BATTERY;
+			wanted_count = 2;
+		} else {
+			wanted_types[0] = POWER_STATE_TYPE_PERFORMANCE;
+			wanted_count = 1;
+		}
+		break;
+	case POWER_STATE_TYPE_BATTERY:
+		if (rdev->flags & RADEON_IS_MOBILITY) {
+			wanted_types[0] = POWER_STATE_TYPE_BATTERY;
+			wanted_types[1] = POWER_STATE_TYPE_POWERSAVE;
+			wanted_count = 2;
+		} else {
+			wanted_types[0] = POWER_STATE_TYPE_PERFORMANCE;
+			wanted_count = 1;
+		}
+		break;
+	case POWER_STATE_TYPE_BALANCED:
+	case POWER_STATE_TYPE_PERFORMANCE:
+		wanted_types[0] = type;
+		wanted_count = 1;
+		break;
+	}
+
+	for (i = 0; i < wanted_count; i++) {
+		for (j = 0; j < rdev->pm.num_power_states; j++) {
+			if (rdev->pm.power_state[j].type == wanted_types[i])
+				return &rdev->pm.power_state[j];
+		}
+	}
+
+	return rdev->pm.default_power_state;
+}
+
+static struct radeon_pm_clock_info * radeon_pick_clock_mode(struct radeon_device *rdev,
+							    struct radeon_power_state *power_state,
+							    enum radeon_pm_clock_mode_type type)
+{
+	switch (type) {
+	case POWER_MODE_TYPE_DEFAULT:
+	default:
+		return power_state->default_clock_mode;
+	case POWER_MODE_TYPE_LOW:
+		return &power_state->clock_info[0];
+	case POWER_MODE_TYPE_MID:
+		if (power_state->num_clock_modes > 2)
+			return &power_state->clock_info[1];
+		else
+			return &power_state->clock_info[0];
+		break;
+	case POWER_MODE_TYPE_HIGH:
+		return &power_state->clock_info[power_state->num_clock_modes - 1];
+	}
+
+}
+
+static void radeon_get_power_state(struct radeon_device *rdev,
+				   enum radeon_pm_action action)
+{
+	switch (action) {
+	case PM_ACTION_MINIMUM:
+		rdev->pm.requested_power_state = radeon_pick_power_state(rdev, POWER_STATE_TYPE_BATTERY);
+		rdev->pm.requested_clock_mode =
+			radeon_pick_clock_mode(rdev, rdev->pm.requested_power_state, POWER_MODE_TYPE_LOW);
+		break;
+	case PM_ACTION_DOWNCLOCK:
+		rdev->pm.requested_power_state = radeon_pick_power_state(rdev, POWER_STATE_TYPE_POWERSAVE);
+		rdev->pm.requested_clock_mode =
+			radeon_pick_clock_mode(rdev, rdev->pm.requested_power_state, POWER_MODE_TYPE_MID);
+		break;
+	case PM_ACTION_UPCLOCK:
+		rdev->pm.requested_power_state = radeon_pick_power_state(rdev, POWER_STATE_TYPE_DEFAULT);
+		rdev->pm.requested_clock_mode =
+			radeon_pick_clock_mode(rdev, rdev->pm.requested_power_state, POWER_MODE_TYPE_HIGH);
+		break;
+	case PM_ACTION_NONE:
+	default:
+		DRM_ERROR("Requested mode for not defined action\n");
+		return;
+	}
+	DRM_INFO("Requested: e: %d m: %d p: %d\n",
+		 rdev->pm.requested_clock_mode->sclk,
+		 rdev->pm.requested_clock_mode->mclk,
+		 rdev->pm.requested_power_state->non_clock_info.pcie_lanes);
+}
+
+static inline void radeon_sync_with_vblank(struct radeon_device *rdev)
+{
+	if (rdev->pm.active_crtcs) {
+		rdev->pm.vblank_sync = false;
+		wait_event_timeout(
+			rdev->irq.vblank_queue, rdev->pm.vblank_sync,
+			msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT));
+	}
+}
+
+static void radeon_set_power_state(struct radeon_device *rdev)
+{
+	/* if *_clock_mode are the same, *_power_state are as well */
+	if (rdev->pm.requested_clock_mode == rdev->pm.current_clock_mode)
+		return;
+
+	DRM_INFO("Setting: e: %d m: %d p: %d\n",
+		 rdev->pm.requested_clock_mode->sclk,
+		 rdev->pm.requested_clock_mode->mclk,
+		 rdev->pm.requested_power_state->non_clock_info.pcie_lanes);
+
+	/* set pcie lanes */
+	/* TODO */
+
+	/* set voltage */
+	/* TODO */
+
+	/* set engine clock */
+	radeon_sync_with_vblank(rdev);
+	radeon_pm_debug_check_in_vbl(rdev, false);
+	radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk);
+	radeon_pm_debug_check_in_vbl(rdev, true);
+
+#if 0
+	/* set memory clock */
+	if (rdev->asic->set_memory_clock) {
+		radeon_sync_with_vblank(rdev);
+		radeon_pm_debug_check_in_vbl(rdev, false);
+		radeon_set_memory_clock(rdev, rdev->pm.requested_clock_mode->mclk);
+		radeon_pm_debug_check_in_vbl(rdev, true);
+	}
+#endif
+
+	rdev->pm.current_power_state = rdev->pm.requested_power_state;
+	rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode;
+}
 
 int radeon_pm_init(struct radeon_device *rdev)
 {
+	rdev->pm.state = PM_STATE_DISABLED;
+	rdev->pm.planned_action = PM_ACTION_NONE;
+	rdev->pm.downclocked = false;
+
+	if (rdev->bios) {
+		if (rdev->is_atom_bios)
+			radeon_atombios_get_power_modes(rdev);
+		else
+			radeon_combios_get_power_modes(rdev);
+		radeon_print_power_mode_info(rdev);
+	}
+
 	if (radeon_debugfs_pm_init(rdev)) {
 		DRM_ERROR("Failed to register debugfs file for PM!\n");
 	}
 
+	INIT_DELAYED_WORK(&rdev->pm.idle_work, radeon_pm_idle_work_handler);
+
+	if (radeon_dynpm != -1 && radeon_dynpm) {
+		rdev->pm.state = PM_STATE_PAUSED;
+		DRM_INFO("radeon: dynamic power management enabled\n");
+	}
+
+	DRM_INFO("radeon: power management initialized\n");
+
 	return 0;
 }
 
+void radeon_pm_fini(struct radeon_device *rdev)
+{
+	if (rdev->pm.i2c_bus)
+		radeon_i2c_destroy(rdev->pm.i2c_bus);
+}
+
+void radeon_pm_compute_clocks(struct radeon_device *rdev)
+{
+	struct drm_device *ddev = rdev->ddev;
+	struct drm_connector *connector;
+	struct radeon_crtc *radeon_crtc;
+	int count = 0;
+
+	if (rdev->pm.state == PM_STATE_DISABLED)
+		return;
+
+	mutex_lock(&rdev->pm.mutex);
+
+	rdev->pm.active_crtcs = 0;
+	list_for_each_entry(connector,
+		&ddev->mode_config.connector_list, head) {
+		if (connector->encoder &&
+		    connector->encoder->crtc &&
+		    connector->dpms != DRM_MODE_DPMS_OFF) {
+			radeon_crtc = to_radeon_crtc(connector->encoder->crtc);
+			rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id);
+			++count;
+		}
+	}
+
+	if (count > 1) {
+		if (rdev->pm.state == PM_STATE_ACTIVE) {
+			cancel_delayed_work(&rdev->pm.idle_work);
+
+			rdev->pm.state = PM_STATE_PAUSED;
+			rdev->pm.planned_action = PM_ACTION_UPCLOCK;
+			if (rdev->pm.downclocked)
+				radeon_pm_set_clocks(rdev);
+
+			DRM_DEBUG("radeon: dynamic power management deactivated\n");
+		}
+	} else if (count == 1) {
+		/* TODO: Increase clocks if needed for current mode */
+
+		if (rdev->pm.state == PM_STATE_MINIMUM) {
+			rdev->pm.state = PM_STATE_ACTIVE;
+			rdev->pm.planned_action = PM_ACTION_UPCLOCK;
+			radeon_pm_set_clocks(rdev);
+
+			queue_delayed_work(rdev->wq, &rdev->pm.idle_work,
+				msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
+		}
+		else if (rdev->pm.state == PM_STATE_PAUSED) {
+			rdev->pm.state = PM_STATE_ACTIVE;
+			queue_delayed_work(rdev->wq, &rdev->pm.idle_work,
+				msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
+			DRM_DEBUG("radeon: dynamic power management activated\n");
+		}
+	}
+	else { /* count == 0 */
+		if (rdev->pm.state != PM_STATE_MINIMUM) {
+			cancel_delayed_work(&rdev->pm.idle_work);
+
+			rdev->pm.state = PM_STATE_MINIMUM;
+			rdev->pm.planned_action = PM_ACTION_MINIMUM;
+			radeon_pm_set_clocks(rdev);
+		}
+	}
+
+	mutex_unlock(&rdev->pm.mutex);
+}
+
+static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish)
+{
+	u32 stat_crtc1 = 0, stat_crtc2 = 0;
+	bool in_vbl = true;
+
+	if (ASIC_IS_AVIVO(rdev)) {
+		if (rdev->pm.active_crtcs & (1 << 0)) {
+			stat_crtc1 = RREG32(D1CRTC_STATUS);
+			if (!(stat_crtc1 & 1))
+				in_vbl = false;
+		}
+		if (rdev->pm.active_crtcs & (1 << 1)) {
+			stat_crtc2 = RREG32(D2CRTC_STATUS);
+			if (!(stat_crtc2 & 1))
+				in_vbl = false;
+		}
+	}
+	if (in_vbl == false)
+		DRM_INFO("not in vbl for pm change %08x %08x at %s\n", stat_crtc1,
+			 stat_crtc2, finish ? "exit" : "entry");
+	return in_vbl;
+}
+static void radeon_pm_set_clocks_locked(struct radeon_device *rdev)
+{
+	/*radeon_fence_wait_last(rdev);*/
+	switch (rdev->pm.planned_action) {
+	case PM_ACTION_UPCLOCK:
+		rdev->pm.downclocked = false;
+		break;
+	case PM_ACTION_DOWNCLOCK:
+		rdev->pm.downclocked = true;
+		break;
+	case PM_ACTION_MINIMUM:
+		break;
+	case PM_ACTION_NONE:
+		DRM_ERROR("%s: PM_ACTION_NONE\n", __func__);
+		break;
+	}
+
+	radeon_set_power_state(rdev);
+	rdev->pm.planned_action = PM_ACTION_NONE;
+}
+
+static void radeon_pm_set_clocks(struct radeon_device *rdev)
+{
+	radeon_get_power_state(rdev, rdev->pm.planned_action);
+	mutex_lock(&rdev->cp.mutex);
+
+	if (rdev->pm.active_crtcs & (1 << 0)) {
+		rdev->pm.req_vblank |= (1 << 0);
+		drm_vblank_get(rdev->ddev, 0);
+	}
+	if (rdev->pm.active_crtcs & (1 << 1)) {
+		rdev->pm.req_vblank |= (1 << 1);
+		drm_vblank_get(rdev->ddev, 1);
+	}
+	radeon_pm_set_clocks_locked(rdev);
+	if (rdev->pm.req_vblank & (1 << 0)) {
+		rdev->pm.req_vblank &= ~(1 << 0);
+		drm_vblank_put(rdev->ddev, 0);
+	}
+	if (rdev->pm.req_vblank & (1 << 1)) {
+		rdev->pm.req_vblank &= ~(1 << 1);
+		drm_vblank_put(rdev->ddev, 1);
+	}
+
+	mutex_unlock(&rdev->cp.mutex);
+}
+
+static void radeon_pm_idle_work_handler(struct work_struct *work)
+{
+	struct radeon_device *rdev;
+	rdev = container_of(work, struct radeon_device,
+				pm.idle_work.work);
+
+	mutex_lock(&rdev->pm.mutex);
+	if (rdev->pm.state == PM_STATE_ACTIVE) {
+		unsigned long irq_flags;
+		int not_processed = 0;
+
+		read_lock_irqsave(&rdev->fence_drv.lock, irq_flags);
+		if (!list_empty(&rdev->fence_drv.emited)) {
+			struct list_head *ptr;
+			list_for_each(ptr, &rdev->fence_drv.emited) {
+				/* count up to 3, that's enought info */
+				if (++not_processed >= 3)
+					break;
+			}
+		}
+		read_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
+
+		if (not_processed >= 3) { /* should upclock */
+			if (rdev->pm.planned_action == PM_ACTION_DOWNCLOCK) {
+				rdev->pm.planned_action = PM_ACTION_NONE;
+			} else if (rdev->pm.planned_action == PM_ACTION_NONE &&
+				rdev->pm.downclocked) {
+				rdev->pm.planned_action =
+					PM_ACTION_UPCLOCK;
+				rdev->pm.action_timeout = jiffies +
+				msecs_to_jiffies(RADEON_RECLOCK_DELAY_MS);
+			}
+		} else if (not_processed == 0) { /* should downclock */
+			if (rdev->pm.planned_action == PM_ACTION_UPCLOCK) {
+				rdev->pm.planned_action = PM_ACTION_NONE;
+			} else if (rdev->pm.planned_action == PM_ACTION_NONE &&
+				!rdev->pm.downclocked) {
+				rdev->pm.planned_action =
+					PM_ACTION_DOWNCLOCK;
+				rdev->pm.action_timeout = jiffies +
+				msecs_to_jiffies(RADEON_RECLOCK_DELAY_MS);
+			}
+		}
+
+		if (rdev->pm.planned_action != PM_ACTION_NONE &&
+		    jiffies > rdev->pm.action_timeout) {
+			radeon_pm_set_clocks(rdev);
+		}
+	}
+	mutex_unlock(&rdev->pm.mutex);
+
+	queue_delayed_work(rdev->wq, &rdev->pm.idle_work,
+					msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
+}
+
 /*
  * Debugfs info
  */
@@ -44,11 +464,14 @@ static int radeon_debugfs_pm_info(struct
 	struct drm_device *dev = node->minor->dev;
 	struct radeon_device *rdev = dev->dev_private;
 
+	seq_printf(m, "state: %s\n", pm_state_names[rdev->pm.state]);
 	seq_printf(m, "default engine clock: %u0 kHz\n", rdev->clock.default_sclk);
 	seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev));
 	seq_printf(m, "default memory clock: %u0 kHz\n", rdev->clock.default_mclk);
 	if (rdev->asic->get_memory_clock)
 		seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev));
+	if (rdev->asic->get_pcie_lanes)
+		seq_printf(m, "PCIE lanes: %d\n", radeon_get_pcie_lanes(rdev));
 
 	return 0;
 }
@@ -58,7 +481,7 @@ static struct drm_info_list radeon_pm_in
 };
 #endif
 
-int radeon_debugfs_pm_init(struct radeon_device *rdev)
+static int radeon_debugfs_pm_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
 	return radeon_debugfs_add_files(rdev, radeon_pm_info_list, ARRAY_SIZE(radeon_pm_info_list));
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_reg.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_reg.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_reg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_reg.h	2010-05-16 17:17:36.000000000 -0400
@@ -54,7 +54,7 @@
 #include "r300_reg.h"
 #include "r500_reg.h"
 #include "r600_reg.h"
-
+#include "evergreen_reg.h"
 
 #define RADEON_MC_AGP_LOCATION		0x014c
 #define		RADEON_MC_AGP_START_MASK	0x0000FFFF
@@ -346,6 +346,7 @@
 #       define RADEON_TVPLL_PWRMGT_OFF      (1 << 30)
 #       define RADEON_TVCLK_TURNOFF         (1 << 31)
 #define RADEON_PLL_PWRMGT_CNTL              0x0015 /* PLL */
+#	define RADEON_PM_MODE_SEL           (1 << 13)
 #       define RADEON_TCL_BYPASS_DISABLE    (1 << 20)
 #define RADEON_CLR_CMP_CLR_3D               0x1a24
 #define RADEON_CLR_CMP_CLR_DST              0x15c8
@@ -1060,32 +1061,38 @@
 
        /* Multimedia I2C bus */
 #define RADEON_I2C_CNTL_0		    0x0090
-#define RADEON_I2C_DONE                     (1 << 0)
-#define RADEON_I2C_NACK                     (1 << 1)
-#define RADEON_I2C_HALT                     (1 << 2)
-#define RADEON_I2C_SOFT_RST                 (1 << 5)
-#define RADEON_I2C_DRIVE_EN                 (1 << 6)
-#define RADEON_I2C_DRIVE_SEL                (1 << 7)
-#define RADEON_I2C_START                    (1 << 8)
-#define RADEON_I2C_STOP                     (1 << 9)
-#define RADEON_I2C_RECEIVE                  (1 << 10)
-#define RADEON_I2C_ABORT                    (1 << 11)
-#define RADEON_I2C_GO                       (1 << 12)
-#define RADEON_I2C_PRESCALE_SHIFT           16
+#       define RADEON_I2C_DONE              (1 << 0)
+#       define RADEON_I2C_NACK              (1 << 1)
+#       define RADEON_I2C_HALT              (1 << 2)
+#       define RADEON_I2C_SOFT_RST          (1 << 5)
+#       define RADEON_I2C_DRIVE_EN          (1 << 6)
+#       define RADEON_I2C_DRIVE_SEL         (1 << 7)
+#       define RADEON_I2C_START             (1 << 8)
+#       define RADEON_I2C_STOP              (1 << 9)
+#       define RADEON_I2C_RECEIVE           (1 << 10)
+#       define RADEON_I2C_ABORT             (1 << 11)
+#       define RADEON_I2C_GO                (1 << 12)
+#       define RADEON_I2C_PRESCALE_SHIFT    16
 #define RADEON_I2C_CNTL_1                   0x0094
-#define RADEON_I2C_DATA_COUNT_SHIFT         0
-#define RADEON_I2C_ADDR_COUNT_SHIFT         4
-#define RADEON_I2C_INTRA_BYTE_DELAY_SHIFT   8
-#define RADEON_I2C_SEL                      (1 << 16)
-#define RADEON_I2C_EN                       (1 << 17)
-#define RADEON_I2C_TIME_LIMIT_SHIFT         24
+#       define RADEON_I2C_DATA_COUNT_SHIFT  0
+#       define RADEON_I2C_ADDR_COUNT_SHIFT  4
+#       define RADEON_I2C_INTRA_BYTE_DELAY_SHIFT   8
+#       define RADEON_I2C_SEL               (1 << 16)
+#       define RADEON_I2C_EN                (1 << 17)
+#       define RADEON_I2C_TIME_LIMIT_SHIFT  24
 #define RADEON_I2C_DATA			    0x0098
 
 #define RADEON_DVI_I2C_CNTL_0		    0x02e0
 #       define R200_DVI_I2C_PIN_SEL(x)      ((x) << 3)
-#       define R200_SEL_DDC1                0 /* 0x60 - VGA_DDC */
-#       define R200_SEL_DDC2                1 /* 0x64 - DVI_DDC */
-#       define R200_SEL_DDC3                2 /* 0x68 - MONID_DDC */
+#       define R200_SEL_DDC1                0 /* depends on asic */
+#       define R200_SEL_DDC2                1 /* depends on asic */
+#       define R200_SEL_DDC3                2 /* depends on asic */
+#	define RADEON_SW_WANTS_TO_USE_DVI_I2C (1 << 13)
+#	define RADEON_SW_CAN_USE_DVI_I2C      (1 << 13)
+#	define RADEON_SW_DONE_USING_DVI_I2C   (1 << 14)
+#	define RADEON_HW_NEEDS_DVI_I2C        (1 << 14)
+#	define RADEON_ABORT_HW_DVI_I2C        (1 << 15)
+#	define RADEON_HW_USING_DVI_I2C        (1 << 15)
 #define RADEON_DVI_I2C_CNTL_1               0x02e4
 #define RADEON_DVI_I2C_DATA		    0x02e8
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_ring.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_ring.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_ring.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_ring.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
  *          Jerome Glisse
  */
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "radeon_drm.h"
 #include "radeon_reg.h"
@@ -34,6 +35,36 @@
 
 int radeon_debugfs_ib_init(struct radeon_device *rdev);
 
+void radeon_ib_bogus_cleanup(struct radeon_device *rdev)
+{
+	struct radeon_ib *ib, *n;
+
+	list_for_each_entry_safe(ib, n, &rdev->ib_pool.bogus_ib, list) {
+		list_del(&ib->list);
+		vfree(ib->ptr);
+		kfree(ib);
+	}
+}
+
+void radeon_ib_bogus_add(struct radeon_device *rdev, struct radeon_ib *ib)
+{
+	struct radeon_ib *bib;
+
+	bib = kmalloc(sizeof(*bib), GFP_KERNEL);
+	if (bib == NULL)
+		return;
+	bib->ptr = vmalloc(ib->length_dw * 4);
+	if (bib->ptr == NULL) {
+		kfree(bib);
+		return;
+	}
+	memcpy(bib->ptr, ib->ptr, ib->length_dw * 4);
+	bib->length_dw = ib->length_dw;
+	mutex_lock(&rdev->ib_pool.mutex);
+	list_add_tail(&bib->list, &rdev->ib_pool.bogus_ib);
+	mutex_unlock(&rdev->ib_pool.mutex);
+}
+
 /*
  * IB.
  */
@@ -142,6 +173,7 @@ int radeon_ib_pool_init(struct radeon_de
 
 	if (rdev->ib_pool.robj)
 		return 0;
+	INIT_LIST_HEAD(&rdev->ib_pool.bogus_ib);
 	/* Allocate 1M object buffer */
 	r = radeon_bo_create(rdev, NULL,  RADEON_IB_POOL_SIZE*64*1024,
 				true, RADEON_GEM_DOMAIN_GTT,
@@ -192,6 +224,8 @@ void radeon_ib_pool_fini(struct radeon_d
 		return;
 	}
 	mutex_lock(&rdev->ib_pool.mutex);
+	radeon_ib_bogus_cleanup(rdev);
+
 	if (rdev->ib_pool.robj) {
 		r = radeon_bo_reserve(rdev->ib_pool.robj, false);
 		if (likely(r == 0)) {
@@ -349,15 +383,49 @@ static int radeon_debugfs_ib_info(struct
 	return 0;
 }
 
+static int radeon_debugfs_ib_bogus_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct radeon_device *rdev = node->info_ent->data;
+	struct radeon_ib *ib;
+	unsigned i;
+
+	mutex_lock(&rdev->ib_pool.mutex);
+	if (list_empty(&rdev->ib_pool.bogus_ib)) {
+		mutex_unlock(&rdev->ib_pool.mutex);
+		seq_printf(m, "no bogus IB recorded\n");
+		return 0;
+	}
+	ib = list_first_entry(&rdev->ib_pool.bogus_ib, struct radeon_ib, list);
+	list_del_init(&ib->list);
+	mutex_unlock(&rdev->ib_pool.mutex);
+	seq_printf(m, "IB size %05u dwords\n", ib->length_dw);
+	for (i = 0; i < ib->length_dw; i++) {
+		seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]);
+	}
+	vfree(ib->ptr);
+	kfree(ib);
+	return 0;
+}
+
 static struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE];
 static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32];
+
+static struct drm_info_list radeon_debugfs_ib_bogus_info_list[] = {
+	{"radeon_ib_bogus", radeon_debugfs_ib_bogus_info, 0, NULL},
+};
 #endif
 
 int radeon_debugfs_ib_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
 	unsigned i;
+	int r;
 
+	radeon_debugfs_ib_bogus_info_list[0].data = rdev;
+	r = radeon_debugfs_add_files(rdev, radeon_debugfs_ib_bogus_info_list, 1);
+	if (r)
+		return r;
 	for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
 		sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i);
 		radeon_debugfs_ib_list[i].name = radeon_debugfs_ib_names[i];
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_state.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_state.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_state.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_state.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 
 #include "drmP.h"
 #include "drm.h"
+#include "drm_buffer.h"
 #include "drm_sarea.h"
 #include "radeon_drm.h"
 #include "radeon_drv.h"
@@ -91,21 +92,27 @@ static __inline__ int radeon_check_and_f
 static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
 						     dev_priv,
 						     struct drm_file *file_priv,
-						     int id, u32 *data)
+						     int id, struct drm_buffer *buf)
 {
+	u32 *data;
 	switch (id) {
 
 	case RADEON_EMIT_PP_MISC:
-		if (radeon_check_and_fixup_offset(dev_priv, file_priv,
-		    &data[(RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4])) {
+		data = drm_buffer_pointer_to_dword(buf,
+			(RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4);
+
+		if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) {
 			DRM_ERROR("Invalid depth buffer offset\n");
 			return -EINVAL;
 		}
+		dev_priv->have_z_offset = 1;
 		break;
 
 	case RADEON_EMIT_PP_CNTL:
-		if (radeon_check_and_fixup_offset(dev_priv, file_priv,
-		    &data[(RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4])) {
+		data = drm_buffer_pointer_to_dword(buf,
+			(RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4);
+
+		if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) {
 			DRM_ERROR("Invalid colour buffer offset\n");
 			return -EINVAL;
 		}
@@ -117,8 +124,8 @@ static __inline__ int radeon_check_and_f
 	case R200_EMIT_PP_TXOFFSET_3:
 	case R200_EMIT_PP_TXOFFSET_4:
 	case R200_EMIT_PP_TXOFFSET_5:
-		if (radeon_check_and_fixup_offset(dev_priv, file_priv,
-						  &data[0])) {
+		data = drm_buffer_pointer_to_dword(buf, 0);
+		if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) {
 			DRM_ERROR("Invalid R200 texture offset\n");
 			return -EINVAL;
 		}
@@ -127,8 +134,9 @@ static __inline__ int radeon_check_and_f
 	case RADEON_EMIT_PP_TXFILTER_0:
 	case RADEON_EMIT_PP_TXFILTER_1:
 	case RADEON_EMIT_PP_TXFILTER_2:
-		if (radeon_check_and_fixup_offset(dev_priv, file_priv,
-		    &data[(RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4])) {
+		data = drm_buffer_pointer_to_dword(buf,
+			(RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4);
+		if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) {
 			DRM_ERROR("Invalid R100 texture offset\n");
 			return -EINVAL;
 		}
@@ -142,9 +150,10 @@ static __inline__ int radeon_check_and_f
 	case R200_EMIT_PP_CUBIC_OFFSETS_5:{
 			int i;
 			for (i = 0; i < 5; i++) {
+				data = drm_buffer_pointer_to_dword(buf, i);
 				if (radeon_check_and_fixup_offset(dev_priv,
 								  file_priv,
-								  &data[i])) {
+								  data)) {
 					DRM_ERROR
 					    ("Invalid R200 cubic texture offset\n");
 					return -EINVAL;
@@ -158,9 +167,10 @@ static __inline__ int radeon_check_and_f
 	case RADEON_EMIT_PP_CUBIC_OFFSETS_T2:{
 			int i;
 			for (i = 0; i < 5; i++) {
+				data = drm_buffer_pointer_to_dword(buf, i);
 				if (radeon_check_and_fixup_offset(dev_priv,
 								  file_priv,
-								  &data[i])) {
+								  data)) {
 					DRM_ERROR
 					    ("Invalid R100 cubic texture offset\n");
 					return -EINVAL;
@@ -269,23 +279,24 @@ static __inline__ int radeon_check_and_f
 						     cmdbuf,
 						     unsigned int *cmdsz)
 {
-	u32 *cmd = (u32 *) cmdbuf->buf;
+	u32 *cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0);
 	u32 offset, narrays;
 	int count, i, k;
 
-	*cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16);
+	count = ((*cmd & RADEON_CP_PACKET_COUNT_MASK) >> 16);
+	*cmdsz = 2 + count;
 
-	if ((cmd[0] & 0xc0000000) != RADEON_CP_PACKET3) {
+	if ((*cmd & 0xc0000000) != RADEON_CP_PACKET3) {
 		DRM_ERROR("Not a type 3 packet\n");
 		return -EINVAL;
 	}
 
-	if (4 * *cmdsz > cmdbuf->bufsz) {
+	if (4 * *cmdsz > drm_buffer_unprocessed(cmdbuf->buffer)) {
 		DRM_ERROR("Packet size larger than size of data provided\n");
 		return -EINVAL;
 	}
 
-	switch(cmd[0] & 0xff00) {
+	switch (*cmd & 0xff00) {
 	/* XXX Are there old drivers needing other packets? */
 
 	case RADEON_3D_DRAW_IMMD:
@@ -312,7 +323,6 @@ static __inline__ int radeon_check_and_f
 		break;
 
 	case RADEON_3D_LOAD_VBPNTR:
-		count = (cmd[0] >> 16) & 0x3fff;
 
 		if (count > 18) { /* 12 arrays max */
 			DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
@@ -321,13 +331,16 @@ static __inline__ int radeon_check_and_f
 		}
 
 		/* carefully check packet contents */
-		narrays = cmd[1] & ~0xc000;
+		cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1);
+
+		narrays = *cmd & ~0xc000;
 		k = 0;
 		i = 2;
 		while ((k < narrays) && (i < (count + 2))) {
 			i++;		/* skip attribute field */
+			cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, i);
 			if (radeon_check_and_fixup_offset(dev_priv, file_priv,
-							  &cmd[i])) {
+							  cmd)) {
 				DRM_ERROR
 				    ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
 				     k, i);
@@ -338,8 +351,10 @@ static __inline__ int radeon_check_and_f
 			if (k == narrays)
 				break;
 			/* have one more to process, they come in pairs */
+			cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, i);
+
 			if (radeon_check_and_fixup_offset(dev_priv,
-							  file_priv, &cmd[i]))
+							  file_priv, cmd))
 			{
 				DRM_ERROR
 				    ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
@@ -363,7 +378,9 @@ static __inline__ int radeon_check_and_f
 			DRM_ERROR("Invalid 3d packet for r200-class chip\n");
 			return -EINVAL;
 		}
-		if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[1])) {
+
+		cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1);
+		if (radeon_check_and_fixup_offset(dev_priv, file_priv, cmd)) {
 				DRM_ERROR("Invalid rndr_gen_indx offset\n");
 				return -EINVAL;
 		}
@@ -374,12 +391,15 @@ static __inline__ int radeon_check_and_f
 			DRM_ERROR("Invalid 3d packet for r100-class chip\n");
 			return -EINVAL;
 		}
-		if ((cmd[1] & 0x8000ffff) != 0x80000810) {
-			DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
+
+		cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1);
+		if ((*cmd & 0x8000ffff) != 0x80000810) {
+			DRM_ERROR("Invalid indx_buffer reg address %08X\n", *cmd);
 			return -EINVAL;
 		}
-		if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[2])) {
-			DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
+		cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 2);
+		if (radeon_check_and_fixup_offset(dev_priv, file_priv, cmd)) {
+			DRM_ERROR("Invalid indx_buffer offset is %08X\n", *cmd);
 			return -EINVAL;
 		}
 		break;
@@ -388,31 +408,34 @@ static __inline__ int radeon_check_and_f
 	case RADEON_CNTL_PAINT_MULTI:
 	case RADEON_CNTL_BITBLT_MULTI:
 		/* MSB of opcode: next DWORD GUI_CNTL */
-		if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
+		cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1);
+		if (*cmd & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
 			      | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
-			offset = cmd[2] << 10;
+			u32 *cmd2 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 2);
+			offset = *cmd2 << 10;
 			if (radeon_check_and_fixup_offset
 			    (dev_priv, file_priv, &offset)) {
 				DRM_ERROR("Invalid first packet offset\n");
 				return -EINVAL;
 			}
-			cmd[2] = (cmd[2] & 0xffc00000) | offset >> 10;
+			*cmd2 = (*cmd2 & 0xffc00000) | offset >> 10;
 		}
 
-		if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
-		    (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
-			offset = cmd[3] << 10;
+		if ((*cmd & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
+		    (*cmd & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
+			u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3);
+			offset = *cmd3 << 10;
 			if (radeon_check_and_fixup_offset
 			    (dev_priv, file_priv, &offset)) {
 				DRM_ERROR("Invalid second packet offset\n");
 				return -EINVAL;
 			}
-			cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10;
+			*cmd3 = (*cmd3 & 0xffc00000) | offset >> 10;
 		}
 		break;
 
 	default:
-		DRM_ERROR("Invalid packet type %x\n", cmd[0] & 0xff00);
+		DRM_ERROR("Invalid packet type %x\n", *cmd & 0xff00);
 		return -EINVAL;
 	}
 
@@ -876,6 +899,11 @@ static void radeon_cp_dispatch_clear(str
 		if (tmp & RADEON_BACK)
 			flags |= RADEON_FRONT;
 	}
+	if (flags & (RADEON_DEPTH|RADEON_STENCIL)) {
+		if (!dev_priv->have_z_offset)
+			printk_once(KERN_ERR "radeon: illegal depth clear request. Buggy mesa detected - please update.\n");
+		flags &= ~(RADEON_DEPTH | RADEON_STENCIL);
+	}
 
 	if (flags & (RADEON_FRONT | RADEON_BACK)) {
 
@@ -1065,7 +1093,7 @@ static void radeon_cp_dispatch_clear(str
 					/* judging by the first tile offset needed, could possibly
 					   directly address/clear 4x4 tiles instead of 8x2 * 4x4
 					   macro tiles, though would still need clear mask for
-					   right/bottom if truely 4x4 granularity is desired ? */
+					   right/bottom if truly 4x4 granularity is desired ? */
 					OUT_RING(tileoffset * 16);
 					/* the number of tiles to clear */
 					OUT_RING(nrtilesx + 1);
@@ -2611,7 +2639,6 @@ static int radeon_emit_packets(drm_radeo
 {
 	int id = (int)header.packet.packet_id;
 	int sz, reg;
-	int *data = (int *)cmdbuf->buf;
 	RING_LOCALS;
 
 	if (id >= RADEON_MAX_STATE_PACKETS)
@@ -2620,23 +2647,22 @@ static int radeon_emit_packets(drm_radeo
 	sz = packet[id].len;
 	reg = packet[id].start;
 
-	if (sz * sizeof(int) > cmdbuf->bufsz) {
+	if (sz * sizeof(u32) > drm_buffer_unprocessed(cmdbuf->buffer)) {
 		DRM_ERROR("Packet size provided larger than data provided\n");
 		return -EINVAL;
 	}
 
-	if (radeon_check_and_fixup_packets(dev_priv, file_priv, id, data)) {
+	if (radeon_check_and_fixup_packets(dev_priv, file_priv, id,
+				cmdbuf->buffer)) {
 		DRM_ERROR("Packet verification failed\n");
 		return -EINVAL;
 	}
 
 	BEGIN_RING(sz + 1);
 	OUT_RING(CP_PACKET0(reg, (sz - 1)));
-	OUT_RING_TABLE(data, sz);
+	OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
 	ADVANCE_RING();
 
-	cmdbuf->buf += sz * sizeof(int);
-	cmdbuf->bufsz -= sz * sizeof(int);
 	return 0;
 }
 
@@ -2653,10 +2679,8 @@ static __inline__ int radeon_emit_scalar
 	OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0));
 	OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
 	OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1));
-	OUT_RING_TABLE(cmdbuf->buf, sz);
+	OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
 	ADVANCE_RING();
-	cmdbuf->buf += sz * sizeof(int);
-	cmdbuf->bufsz -= sz * sizeof(int);
 	return 0;
 }
 
@@ -2675,10 +2699,8 @@ static __inline__ int radeon_emit_scalar
 	OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0));
 	OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
 	OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1));
-	OUT_RING_TABLE(cmdbuf->buf, sz);
+	OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
 	ADVANCE_RING();
-	cmdbuf->buf += sz * sizeof(int);
-	cmdbuf->bufsz -= sz * sizeof(int);
 	return 0;
 }
 
@@ -2696,11 +2718,9 @@ static __inline__ int radeon_emit_vector
 	OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
 	OUT_RING(start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
 	OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
-	OUT_RING_TABLE(cmdbuf->buf, sz);
+	OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
 	ADVANCE_RING();
 
-	cmdbuf->buf += sz * sizeof(int);
-	cmdbuf->bufsz -= sz * sizeof(int);
 	return 0;
 }
 
@@ -2714,7 +2734,7 @@ static __inline__ int radeon_emit_veclin
 
         if (!sz)
                 return 0;
-        if (sz * 4 > cmdbuf->bufsz)
+	if (sz * 4 > drm_buffer_unprocessed(cmdbuf->buffer))
                 return -EINVAL;
 
 	BEGIN_RING(5 + sz);
@@ -2722,11 +2742,9 @@ static __inline__ int radeon_emit_veclin
 	OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
 	OUT_RING(start | (1 << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
 	OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
-	OUT_RING_TABLE(cmdbuf->buf, sz);
+	OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
 	ADVANCE_RING();
 
-	cmdbuf->buf += sz * sizeof(int);
-	cmdbuf->bufsz -= sz * sizeof(int);
 	return 0;
 }
 
@@ -2748,11 +2766,9 @@ static int radeon_emit_packet3(struct dr
 	}
 
 	BEGIN_RING(cmdsz);
-	OUT_RING_TABLE(cmdbuf->buf, cmdsz);
+	OUT_RING_DRM_BUFFER(cmdbuf->buffer, cmdsz);
 	ADVANCE_RING();
 
-	cmdbuf->buf += cmdsz * 4;
-	cmdbuf->bufsz -= cmdsz * 4;
 	return 0;
 }
 
@@ -2805,16 +2821,16 @@ static int radeon_emit_packet3_cliprect(
 		}
 
 		BEGIN_RING(cmdsz);
-		OUT_RING_TABLE(cmdbuf->buf, cmdsz);
+		OUT_RING_DRM_BUFFER(cmdbuf->buffer, cmdsz);
 		ADVANCE_RING();
 
 	} while (++i < cmdbuf->nbox);
 	if (cmdbuf->nbox == 1)
 		cmdbuf->nbox = 0;
 
+	return 0;
       out:
-	cmdbuf->buf += cmdsz * 4;
-	cmdbuf->bufsz -= cmdsz * 4;
+	drm_buffer_advance(cmdbuf->buffer, cmdsz * 4);
 	return 0;
 }
 
@@ -2847,16 +2863,16 @@ static int radeon_emit_wait(struct drm_d
 	return 0;
 }
 
-static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv)
+static int radeon_cp_cmdbuf(struct drm_device *dev, void *data,
+		struct drm_file *file_priv)
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	struct drm_device_dma *dma = dev->dma;
 	struct drm_buf *buf = NULL;
+	drm_radeon_cmd_header_t stack_header;
 	int idx;
 	drm_radeon_kcmd_buffer_t *cmdbuf = data;
-	drm_radeon_cmd_header_t header;
-	int orig_nbox, orig_bufsz;
-	char *kbuf = NULL;
+	int orig_nbox;
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
@@ -2871,18 +2887,20 @@ static int radeon_cp_cmdbuf(struct drm_d
 	 * races between checking values and using those values in other code,
 	 * and simply to avoid a lot of function calls to copy in data.
 	 */
-	orig_bufsz = cmdbuf->bufsz;
-	if (orig_bufsz != 0) {
-		kbuf = kmalloc(cmdbuf->bufsz, GFP_KERNEL);
-		if (kbuf == NULL)
-			return -ENOMEM;
-		if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf->buf,
-				       cmdbuf->bufsz)) {
-			kfree(kbuf);
-			return -EFAULT;
+	if (cmdbuf->bufsz != 0) {
+		int rv;
+		void __user *buffer = cmdbuf->buffer;
+		rv = drm_buffer_alloc(&cmdbuf->buffer, cmdbuf->bufsz);
+		if (rv)
+			return rv;
+		rv = drm_buffer_copy_from_user(cmdbuf->buffer, buffer,
+						cmdbuf->bufsz);
+		if (rv) {
+			drm_buffer_free(cmdbuf->buffer);
+			return rv;
 		}
-		cmdbuf->buf = kbuf;
-	}
+	} else
+		goto done;
 
 	orig_nbox = cmdbuf->nbox;
 
@@ -2890,24 +2908,23 @@ static int radeon_cp_cmdbuf(struct drm_d
 		int temp;
 		temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf);
 
-		if (orig_bufsz != 0)
-			kfree(kbuf);
+		drm_buffer_free(cmdbuf->buffer);
 
 		return temp;
 	}
 
 	/* microcode_version != r300 */
-	while (cmdbuf->bufsz >= sizeof(header)) {
+	while (drm_buffer_unprocessed(cmdbuf->buffer) >= sizeof(stack_header)) {
 
-		header.i = *(int *)cmdbuf->buf;
-		cmdbuf->buf += sizeof(header);
-		cmdbuf->bufsz -= sizeof(header);
+		drm_radeon_cmd_header_t *header;
+		header = drm_buffer_read_object(cmdbuf->buffer,
+				sizeof(stack_header), &stack_header);
 
-		switch (header.header.cmd_type) {
+		switch (header->header.cmd_type) {
 		case RADEON_CMD_PACKET:
 			DRM_DEBUG("RADEON_CMD_PACKET\n");
 			if (radeon_emit_packets
-			    (dev_priv, file_priv, header, cmdbuf)) {
+			    (dev_priv, file_priv, *header, cmdbuf)) {
 				DRM_ERROR("radeon_emit_packets failed\n");
 				goto err;
 			}
@@ -2915,7 +2932,7 @@ static int radeon_cp_cmdbuf(struct drm_d
 
 		case RADEON_CMD_SCALARS:
 			DRM_DEBUG("RADEON_CMD_SCALARS\n");
-			if (radeon_emit_scalars(dev_priv, header, cmdbuf)) {
+			if (radeon_emit_scalars(dev_priv, *header, cmdbuf)) {
 				DRM_ERROR("radeon_emit_scalars failed\n");
 				goto err;
 			}
@@ -2923,7 +2940,7 @@ static int radeon_cp_cmdbuf(struct drm_d
 
 		case RADEON_CMD_VECTORS:
 			DRM_DEBUG("RADEON_CMD_VECTORS\n");
-			if (radeon_emit_vectors(dev_priv, header, cmdbuf)) {
+			if (radeon_emit_vectors(dev_priv, *header, cmdbuf)) {
 				DRM_ERROR("radeon_emit_vectors failed\n");
 				goto err;
 			}
@@ -2931,7 +2948,7 @@ static int radeon_cp_cmdbuf(struct drm_d
 
 		case RADEON_CMD_DMA_DISCARD:
 			DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
-			idx = header.dma.buf_idx;
+			idx = header->dma.buf_idx;
 			if (idx < 0 || idx >= dma->buf_count) {
 				DRM_ERROR("buffer index %d (of %d max)\n",
 					  idx, dma->buf_count - 1);
@@ -2968,7 +2985,7 @@ static int radeon_cp_cmdbuf(struct drm_d
 
 		case RADEON_CMD_SCALARS2:
 			DRM_DEBUG("RADEON_CMD_SCALARS2\n");
-			if (radeon_emit_scalars2(dev_priv, header, cmdbuf)) {
+			if (radeon_emit_scalars2(dev_priv, *header, cmdbuf)) {
 				DRM_ERROR("radeon_emit_scalars2 failed\n");
 				goto err;
 			}
@@ -2976,37 +2993,36 @@ static int radeon_cp_cmdbuf(struct drm_d
 
 		case RADEON_CMD_WAIT:
 			DRM_DEBUG("RADEON_CMD_WAIT\n");
-			if (radeon_emit_wait(dev, header.wait.flags)) {
+			if (radeon_emit_wait(dev, header->wait.flags)) {
 				DRM_ERROR("radeon_emit_wait failed\n");
 				goto err;
 			}
 			break;
 		case RADEON_CMD_VECLINEAR:
 			DRM_DEBUG("RADEON_CMD_VECLINEAR\n");
-			if (radeon_emit_veclinear(dev_priv, header, cmdbuf)) {
+			if (radeon_emit_veclinear(dev_priv, *header, cmdbuf)) {
 				DRM_ERROR("radeon_emit_veclinear failed\n");
 				goto err;
 			}
 			break;
 
 		default:
-			DRM_ERROR("bad cmd_type %d at %p\n",
-				  header.header.cmd_type,
-				  cmdbuf->buf - sizeof(header));
+			DRM_ERROR("bad cmd_type %d at byte %d\n",
+				  header->header.cmd_type,
+				  cmdbuf->buffer->iterator);
 			goto err;
 		}
 	}
 
-	if (orig_bufsz != 0)
-		kfree(kbuf);
+	drm_buffer_free(cmdbuf->buffer);
 
+      done:
 	DRM_DEBUG("DONE\n");
 	COMMIT_RING();
 	return 0;
 
       err:
-	if (orig_bufsz != 0)
-		kfree(kbuf);
+	drm_buffer_free(cmdbuf->buffer);
 	return -EINVAL;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_test.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_test.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_test.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_test.c	2010-05-16 17:17:36.000000000 -0400
@@ -186,7 +186,7 @@ void radeon_test_moves(struct radeon_dev
 		radeon_bo_kunmap(gtt_obj[i]);
 
 		DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n",
-			 gtt_addr - rdev->mc.gtt_location);
+			 gtt_addr - rdev->mc.gtt_start);
 	}
 
 out_cleanup:
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_ttm.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_ttm.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_ttm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/radeon_ttm.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <drm/drmP.h>
 #include <drm/radeon_drm.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "radeon_reg.h"
 #include "radeon.h"
 
@@ -150,7 +151,7 @@ static int radeon_init_mem_type(struct t
 		man->default_caching = TTM_PL_FLAG_CACHED;
 		break;
 	case TTM_PL_TT:
-		man->gpu_offset = rdev->mc.gtt_location;
+		man->gpu_offset = rdev->mc.gtt_start;
 		man->available_caching = TTM_PL_MASK_CACHING;
 		man->default_caching = TTM_PL_FLAG_CACHED;
 		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA;
@@ -180,7 +181,7 @@ static int radeon_init_mem_type(struct t
 		break;
 	case TTM_PL_VRAM:
 		/* "On-card" video ram */
-		man->gpu_offset = rdev->mc.vram_location;
+		man->gpu_offset = rdev->mc.vram_start;
 		man->flags = TTM_MEMTYPE_FLAG_FIXED |
 			     TTM_MEMTYPE_FLAG_NEEDS_IOREMAP |
 			     TTM_MEMTYPE_FLAG_MAPPABLE;
@@ -262,10 +263,10 @@ static int radeon_move_blit(struct ttm_b
 
 	switch (old_mem->mem_type) {
 	case TTM_PL_VRAM:
-		old_start += rdev->mc.vram_location;
+		old_start += rdev->mc.vram_start;
 		break;
 	case TTM_PL_TT:
-		old_start += rdev->mc.gtt_location;
+		old_start += rdev->mc.gtt_start;
 		break;
 	default:
 		DRM_ERROR("Unknown placement %d\n", old_mem->mem_type);
@@ -273,10 +274,10 @@ static int radeon_move_blit(struct ttm_b
 	}
 	switch (new_mem->mem_type) {
 	case TTM_PL_VRAM:
-		new_start += rdev->mc.vram_location;
+		new_start += rdev->mc.vram_start;
 		break;
 	case TTM_PL_TT:
-		new_start += rdev->mc.gtt_location;
+		new_start += rdev->mc.gtt_start;
 		break;
 	default:
 		DRM_ERROR("Unknown placement %d\n", old_mem->mem_type);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/r300 linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/reg_srcs/r300
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/r300	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/reg_srcs/r300	2010-05-16 17:17:36.000000000 -0400
@@ -125,6 +125,8 @@ r300 0x4f60
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/r420 linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/reg_srcs/r420
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/r420	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/reg_srcs/r420	2010-05-16 17:17:36.000000000 -0400
@@ -125,6 +125,8 @@ r420 0x4f60
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/r600 linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/reg_srcs/r600
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/r600	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/reg_srcs/r600	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,762 @@
+r600 0x9400
+0x000287A0 R7xx_CB_SHADER_CONTROL
+0x00028230 R7xx_PA_SC_EDGERULE
+0x000286C8 R7xx_SPI_THREAD_GROUPING
+0x00008D8C R7xx_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ
+0x000088C4 VGT_CACHE_INVALIDATION
+0x00028A50 VGT_ENHANCE
+0x000088CC VGT_ES_PER_GS
+0x00028A2C VGT_GROUP_DECR
+0x00028A28 VGT_GROUP_FIRST_DECR
+0x00028A24 VGT_GROUP_PRIM_TYPE
+0x00028A30 VGT_GROUP_VECT_0_CNTL
+0x00028A38 VGT_GROUP_VECT_0_FMT_CNTL
+0x00028A34 VGT_GROUP_VECT_1_CNTL
+0x00028A3C VGT_GROUP_VECT_1_FMT_CNTL
+0x00028A40 VGT_GS_MODE
+0x00028A6C VGT_GS_OUT_PRIM_TYPE
+0x000088C8 VGT_GS_PER_ES
+0x000088E8 VGT_GS_PER_VS
+0x000088D4 VGT_GS_VERTEX_REUSE
+0x00028A14 VGT_HOS_CNTL
+0x00028A18 VGT_HOS_MAX_TESS_LEVEL
+0x00028A1C VGT_HOS_MIN_TESS_LEVEL
+0x00028A20 VGT_HOS_REUSE_DEPTH
+0x0000895C VGT_INDEX_TYPE
+0x00028408 VGT_INDX_OFFSET
+0x00028AA0 VGT_INSTANCE_STEP_RATE_0
+0x00028AA4 VGT_INSTANCE_STEP_RATE_1
+0x00028400 VGT_MAX_VTX_INDX
+0x00028404 VGT_MIN_VTX_INDX
+0x00028A94 VGT_MULTI_PRIM_IB_RESET_EN
+0x0002840C VGT_MULTI_PRIM_IB_RESET_INDX
+0x00008970 VGT_NUM_INDICES
+0x00008974 VGT_NUM_INSTANCES
+0x00028A10 VGT_OUTPUT_PATH_CNTL
+0x00028A84 VGT_PRIMITIVEID_EN
+0x00008958 VGT_PRIMITIVE_TYPE
+0x00028AB4 VGT_REUSE_OFF
+0x00028AB8 VGT_VTX_CNT_EN
+0x000088B0 VGT_VTX_VECT_EJECT_REG
+0x00028810 PA_CL_CLIP_CNTL
+0x00008A14 PA_CL_ENHANCE
+0x00028C14 PA_CL_GB_HORZ_CLIP_ADJ
+0x00028C18 PA_CL_GB_HORZ_DISC_ADJ
+0x00028C0C PA_CL_GB_VERT_CLIP_ADJ
+0x00028C10 PA_CL_GB_VERT_DISC_ADJ
+0x00028820 PA_CL_NANINF_CNTL
+0x00028E1C PA_CL_POINT_CULL_RAD
+0x00028E18 PA_CL_POINT_SIZE
+0x00028E10 PA_CL_POINT_X_RAD
+0x00028E14 PA_CL_POINT_Y_RAD
+0x00028E2C PA_CL_UCP_0_W
+0x00028E3C PA_CL_UCP_1_W
+0x00028E4C PA_CL_UCP_2_W
+0x00028E5C PA_CL_UCP_3_W
+0x00028E6C PA_CL_UCP_4_W
+0x00028E7C PA_CL_UCP_5_W
+0x00028E20 PA_CL_UCP_0_X
+0x00028E30 PA_CL_UCP_1_X
+0x00028E40 PA_CL_UCP_2_X
+0x00028E50 PA_CL_UCP_3_X
+0x00028E60 PA_CL_UCP_4_X
+0x00028E70 PA_CL_UCP_5_X
+0x00028E24 PA_CL_UCP_0_Y
+0x00028E34 PA_CL_UCP_1_Y
+0x00028E44 PA_CL_UCP_2_Y
+0x00028E54 PA_CL_UCP_3_Y
+0x00028E64 PA_CL_UCP_4_Y
+0x00028E74 PA_CL_UCP_5_Y
+0x00028E28 PA_CL_UCP_0_Z
+0x00028E38 PA_CL_UCP_1_Z
+0x00028E48 PA_CL_UCP_2_Z
+0x00028E58 PA_CL_UCP_3_Z
+0x00028E68 PA_CL_UCP_4_Z
+0x00028E78 PA_CL_UCP_5_Z
+0x00028440 PA_CL_VPORT_XOFFSET_0
+0x00028458 PA_CL_VPORT_XOFFSET_1
+0x00028470 PA_CL_VPORT_XOFFSET_2
+0x00028488 PA_CL_VPORT_XOFFSET_3
+0x000284A0 PA_CL_VPORT_XOFFSET_4
+0x000284B8 PA_CL_VPORT_XOFFSET_5
+0x000284D0 PA_CL_VPORT_XOFFSET_6
+0x000284E8 PA_CL_VPORT_XOFFSET_7
+0x00028500 PA_CL_VPORT_XOFFSET_8
+0x00028518 PA_CL_VPORT_XOFFSET_9
+0x00028530 PA_CL_VPORT_XOFFSET_10
+0x00028548 PA_CL_VPORT_XOFFSET_11
+0x00028560 PA_CL_VPORT_XOFFSET_12
+0x00028578 PA_CL_VPORT_XOFFSET_13
+0x00028590 PA_CL_VPORT_XOFFSET_14
+0x000285A8 PA_CL_VPORT_XOFFSET_15
+0x0002843C PA_CL_VPORT_XSCALE_0
+0x00028454 PA_CL_VPORT_XSCALE_1
+0x0002846C PA_CL_VPORT_XSCALE_2
+0x00028484 PA_CL_VPORT_XSCALE_3
+0x0002849C PA_CL_VPORT_XSCALE_4
+0x000284B4 PA_CL_VPORT_XSCALE_5
+0x000284CC PA_CL_VPORT_XSCALE_6
+0x000284E4 PA_CL_VPORT_XSCALE_7
+0x000284FC PA_CL_VPORT_XSCALE_8
+0x00028514 PA_CL_VPORT_XSCALE_9
+0x0002852C PA_CL_VPORT_XSCALE_10
+0x00028544 PA_CL_VPORT_XSCALE_11
+0x0002855C PA_CL_VPORT_XSCALE_12
+0x00028574 PA_CL_VPORT_XSCALE_13
+0x0002858C PA_CL_VPORT_XSCALE_14
+0x000285A4 PA_CL_VPORT_XSCALE_15
+0x00028448 PA_CL_VPORT_YOFFSET_0
+0x00028460 PA_CL_VPORT_YOFFSET_1
+0x00028478 PA_CL_VPORT_YOFFSET_2
+0x00028490 PA_CL_VPORT_YOFFSET_3
+0x000284A8 PA_CL_VPORT_YOFFSET_4
+0x000284C0 PA_CL_VPORT_YOFFSET_5
+0x000284D8 PA_CL_VPORT_YOFFSET_6
+0x000284F0 PA_CL_VPORT_YOFFSET_7
+0x00028508 PA_CL_VPORT_YOFFSET_8
+0x00028520 PA_CL_VPORT_YOFFSET_9
+0x00028538 PA_CL_VPORT_YOFFSET_10
+0x00028550 PA_CL_VPORT_YOFFSET_11
+0x00028568 PA_CL_VPORT_YOFFSET_12
+0x00028580 PA_CL_VPORT_YOFFSET_13
+0x00028598 PA_CL_VPORT_YOFFSET_14
+0x000285B0 PA_CL_VPORT_YOFFSET_15
+0x00028444 PA_CL_VPORT_YSCALE_0
+0x0002845C PA_CL_VPORT_YSCALE_1
+0x00028474 PA_CL_VPORT_YSCALE_2
+0x0002848C PA_CL_VPORT_YSCALE_3
+0x000284A4 PA_CL_VPORT_YSCALE_4
+0x000284BC PA_CL_VPORT_YSCALE_5
+0x000284D4 PA_CL_VPORT_YSCALE_6
+0x000284EC PA_CL_VPORT_YSCALE_7
+0x00028504 PA_CL_VPORT_YSCALE_8
+0x0002851C PA_CL_VPORT_YSCALE_9
+0x00028534 PA_CL_VPORT_YSCALE_10
+0x0002854C PA_CL_VPORT_YSCALE_11
+0x00028564 PA_CL_VPORT_YSCALE_12
+0x0002857C PA_CL_VPORT_YSCALE_13
+0x00028594 PA_CL_VPORT_YSCALE_14
+0x000285AC PA_CL_VPORT_YSCALE_15
+0x00028450 PA_CL_VPORT_ZOFFSET_0
+0x00028468 PA_CL_VPORT_ZOFFSET_1
+0x00028480 PA_CL_VPORT_ZOFFSET_2
+0x00028498 PA_CL_VPORT_ZOFFSET_3
+0x000284B0 PA_CL_VPORT_ZOFFSET_4
+0x000284C8 PA_CL_VPORT_ZOFFSET_5
+0x000284E0 PA_CL_VPORT_ZOFFSET_6
+0x000284F8 PA_CL_VPORT_ZOFFSET_7
+0x00028510 PA_CL_VPORT_ZOFFSET_8
+0x00028528 PA_CL_VPORT_ZOFFSET_9
+0x00028540 PA_CL_VPORT_ZOFFSET_10
+0x00028558 PA_CL_VPORT_ZOFFSET_11
+0x00028570 PA_CL_VPORT_ZOFFSET_12
+0x00028588 PA_CL_VPORT_ZOFFSET_13
+0x000285A0 PA_CL_VPORT_ZOFFSET_14
+0x000285B8 PA_CL_VPORT_ZOFFSET_15
+0x0002844C PA_CL_VPORT_ZSCALE_0
+0x00028464 PA_CL_VPORT_ZSCALE_1
+0x0002847C PA_CL_VPORT_ZSCALE_2
+0x00028494 PA_CL_VPORT_ZSCALE_3
+0x000284AC PA_CL_VPORT_ZSCALE_4
+0x000284C4 PA_CL_VPORT_ZSCALE_5
+0x000284DC PA_CL_VPORT_ZSCALE_6
+0x000284F4 PA_CL_VPORT_ZSCALE_7
+0x0002850C PA_CL_VPORT_ZSCALE_8
+0x00028524 PA_CL_VPORT_ZSCALE_9
+0x0002853C PA_CL_VPORT_ZSCALE_10
+0x00028554 PA_CL_VPORT_ZSCALE_11
+0x0002856C PA_CL_VPORT_ZSCALE_12
+0x00028584 PA_CL_VPORT_ZSCALE_13
+0x0002859C PA_CL_VPORT_ZSCALE_14
+0x000285B4 PA_CL_VPORT_ZSCALE_15
+0x0002881C PA_CL_VS_OUT_CNTL
+0x00028818 PA_CL_VTE_CNTL
+0x00028C48 PA_SC_AA_MASK
+0x00008B40 PA_SC_AA_SAMPLE_LOCS_2S
+0x00008B44 PA_SC_AA_SAMPLE_LOCS_4S
+0x00008B48 PA_SC_AA_SAMPLE_LOCS_8S_WD0
+0x00008B4C PA_SC_AA_SAMPLE_LOCS_8S_WD1
+0x00028C20 PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX
+0x00028C1C PA_SC_AA_SAMPLE_LOCS_MCTX
+0x00028214 PA_SC_CLIPRECT_0_BR
+0x0002821C PA_SC_CLIPRECT_1_BR
+0x00028224 PA_SC_CLIPRECT_2_BR
+0x0002822C PA_SC_CLIPRECT_3_BR
+0x00028210 PA_SC_CLIPRECT_0_TL
+0x00028218 PA_SC_CLIPRECT_1_TL
+0x00028220 PA_SC_CLIPRECT_2_TL
+0x00028228 PA_SC_CLIPRECT_3_TL
+0x0002820C PA_SC_CLIPRECT_RULE
+0x00008BF0 PA_SC_ENHANCE
+0x00028244 PA_SC_GENERIC_SCISSOR_BR
+0x00028240 PA_SC_GENERIC_SCISSOR_TL
+0x00028C00 PA_SC_LINE_CNTL
+0x00028A0C PA_SC_LINE_STIPPLE
+0x00008B10 PA_SC_LINE_STIPPLE_STATE
+0x00028A4C PA_SC_MODE_CNTL
+0x00028A48 PA_SC_MPASS_PS_CNTL
+0x00008B20 PA_SC_MULTI_CHIP_CNTL
+0x00028034 PA_SC_SCREEN_SCISSOR_BR
+0x00028030 PA_SC_SCREEN_SCISSOR_TL
+0x00028254 PA_SC_VPORT_SCISSOR_0_BR
+0x0002825C PA_SC_VPORT_SCISSOR_1_BR
+0x00028264 PA_SC_VPORT_SCISSOR_2_BR
+0x0002826C PA_SC_VPORT_SCISSOR_3_BR
+0x00028274 PA_SC_VPORT_SCISSOR_4_BR
+0x0002827C PA_SC_VPORT_SCISSOR_5_BR
+0x00028284 PA_SC_VPORT_SCISSOR_6_BR
+0x0002828C PA_SC_VPORT_SCISSOR_7_BR
+0x00028294 PA_SC_VPORT_SCISSOR_8_BR
+0x0002829C PA_SC_VPORT_SCISSOR_9_BR
+0x000282A4 PA_SC_VPORT_SCISSOR_10_BR
+0x000282AC PA_SC_VPORT_SCISSOR_11_BR
+0x000282B4 PA_SC_VPORT_SCISSOR_12_BR
+0x000282BC PA_SC_VPORT_SCISSOR_13_BR
+0x000282C4 PA_SC_VPORT_SCISSOR_14_BR
+0x000282CC PA_SC_VPORT_SCISSOR_15_BR
+0x00028250 PA_SC_VPORT_SCISSOR_0_TL
+0x00028258 PA_SC_VPORT_SCISSOR_1_TL
+0x00028260 PA_SC_VPORT_SCISSOR_2_TL
+0x00028268 PA_SC_VPORT_SCISSOR_3_TL
+0x00028270 PA_SC_VPORT_SCISSOR_4_TL
+0x00028278 PA_SC_VPORT_SCISSOR_5_TL
+0x00028280 PA_SC_VPORT_SCISSOR_6_TL
+0x00028288 PA_SC_VPORT_SCISSOR_7_TL
+0x00028290 PA_SC_VPORT_SCISSOR_8_TL
+0x00028298 PA_SC_VPORT_SCISSOR_9_TL
+0x000282A0 PA_SC_VPORT_SCISSOR_10_TL
+0x000282A8 PA_SC_VPORT_SCISSOR_11_TL
+0x000282B0 PA_SC_VPORT_SCISSOR_12_TL
+0x000282B8 PA_SC_VPORT_SCISSOR_13_TL
+0x000282C0 PA_SC_VPORT_SCISSOR_14_TL
+0x000282C8 PA_SC_VPORT_SCISSOR_15_TL
+0x000282D4 PA_SC_VPORT_ZMAX_0
+0x000282DC PA_SC_VPORT_ZMAX_1
+0x000282E4 PA_SC_VPORT_ZMAX_2
+0x000282EC PA_SC_VPORT_ZMAX_3
+0x000282F4 PA_SC_VPORT_ZMAX_4
+0x000282FC PA_SC_VPORT_ZMAX_5
+0x00028304 PA_SC_VPORT_ZMAX_6
+0x0002830C PA_SC_VPORT_ZMAX_7
+0x00028314 PA_SC_VPORT_ZMAX_8
+0x0002831C PA_SC_VPORT_ZMAX_9
+0x00028324 PA_SC_VPORT_ZMAX_10
+0x0002832C PA_SC_VPORT_ZMAX_11
+0x00028334 PA_SC_VPORT_ZMAX_12
+0x0002833C PA_SC_VPORT_ZMAX_13
+0x00028344 PA_SC_VPORT_ZMAX_14
+0x0002834C PA_SC_VPORT_ZMAX_15
+0x000282D0 PA_SC_VPORT_ZMIN_0
+0x000282D8 PA_SC_VPORT_ZMIN_1
+0x000282E0 PA_SC_VPORT_ZMIN_2
+0x000282E8 PA_SC_VPORT_ZMIN_3
+0x000282F0 PA_SC_VPORT_ZMIN_4
+0x000282F8 PA_SC_VPORT_ZMIN_5
+0x00028300 PA_SC_VPORT_ZMIN_6
+0x00028308 PA_SC_VPORT_ZMIN_7
+0x00028310 PA_SC_VPORT_ZMIN_8
+0x00028318 PA_SC_VPORT_ZMIN_9
+0x00028320 PA_SC_VPORT_ZMIN_10
+0x00028328 PA_SC_VPORT_ZMIN_11
+0x00028330 PA_SC_VPORT_ZMIN_12
+0x00028338 PA_SC_VPORT_ZMIN_13
+0x00028340 PA_SC_VPORT_ZMIN_14
+0x00028348 PA_SC_VPORT_ZMIN_15
+0x00028200 PA_SC_WINDOW_OFFSET
+0x00028208 PA_SC_WINDOW_SCISSOR_BR
+0x00028204 PA_SC_WINDOW_SCISSOR_TL
+0x00028A08 PA_SU_LINE_CNTL
+0x00028A04 PA_SU_POINT_MINMAX
+0x00028A00 PA_SU_POINT_SIZE
+0x00028E0C PA_SU_POLY_OFFSET_BACK_OFFSET
+0x00028E08 PA_SU_POLY_OFFSET_BACK_SCALE
+0x00028DFC PA_SU_POLY_OFFSET_CLAMP
+0x00028DF8 PA_SU_POLY_OFFSET_DB_FMT_CNTL
+0x00028E04 PA_SU_POLY_OFFSET_FRONT_OFFSET
+0x00028E00 PA_SU_POLY_OFFSET_FRONT_SCALE
+0x00028814 PA_SU_SC_MODE_CNTL
+0x00028C08 PA_SU_VTX_CNTL
+0x00008C04 SQ_GPR_RESOURCE_MGMT_1
+0x00008C08 SQ_GPR_RESOURCE_MGMT_2
+0x00008C10 SQ_STACK_RESOURCE_MGMT_1
+0x00008C14 SQ_STACK_RESOURCE_MGMT_2
+0x00008C0C SQ_THREAD_RESOURCE_MGMT
+0x00028380 SQ_VTX_SEMANTIC_0
+0x00028384 SQ_VTX_SEMANTIC_1
+0x00028388 SQ_VTX_SEMANTIC_2
+0x0002838C SQ_VTX_SEMANTIC_3
+0x00028390 SQ_VTX_SEMANTIC_4
+0x00028394 SQ_VTX_SEMANTIC_5
+0x00028398 SQ_VTX_SEMANTIC_6
+0x0002839C SQ_VTX_SEMANTIC_7
+0x000283A0 SQ_VTX_SEMANTIC_8
+0x000283A4 SQ_VTX_SEMANTIC_9
+0x000283A8 SQ_VTX_SEMANTIC_10
+0x000283AC SQ_VTX_SEMANTIC_11
+0x000283B0 SQ_VTX_SEMANTIC_12
+0x000283B4 SQ_VTX_SEMANTIC_13
+0x000283B8 SQ_VTX_SEMANTIC_14
+0x000283BC SQ_VTX_SEMANTIC_15
+0x000283C0 SQ_VTX_SEMANTIC_16
+0x000283C4 SQ_VTX_SEMANTIC_17
+0x000283C8 SQ_VTX_SEMANTIC_18
+0x000283CC SQ_VTX_SEMANTIC_19
+0x000283D0 SQ_VTX_SEMANTIC_20
+0x000283D4 SQ_VTX_SEMANTIC_21
+0x000283D8 SQ_VTX_SEMANTIC_22
+0x000283DC SQ_VTX_SEMANTIC_23
+0x000283E0 SQ_VTX_SEMANTIC_24
+0x000283E4 SQ_VTX_SEMANTIC_25
+0x000283E8 SQ_VTX_SEMANTIC_26
+0x000283EC SQ_VTX_SEMANTIC_27
+0x000283F0 SQ_VTX_SEMANTIC_28
+0x000283F4 SQ_VTX_SEMANTIC_29
+0x000283F8 SQ_VTX_SEMANTIC_30
+0x000283FC SQ_VTX_SEMANTIC_31
+0x000288E0 SQ_VTX_SEMANTIC_CLEAR
+0x0003CFF4 SQ_VTX_START_INST_LOC
+0x000281C0 SQ_ALU_CONST_BUFFER_SIZE_GS_0
+0x000281C4 SQ_ALU_CONST_BUFFER_SIZE_GS_1
+0x000281C8 SQ_ALU_CONST_BUFFER_SIZE_GS_2
+0x000281CC SQ_ALU_CONST_BUFFER_SIZE_GS_3
+0x000281D0 SQ_ALU_CONST_BUFFER_SIZE_GS_4
+0x000281D4 SQ_ALU_CONST_BUFFER_SIZE_GS_5
+0x000281D8 SQ_ALU_CONST_BUFFER_SIZE_GS_6
+0x000281DC SQ_ALU_CONST_BUFFER_SIZE_GS_7
+0x000281E0 SQ_ALU_CONST_BUFFER_SIZE_GS_8
+0x000281E4 SQ_ALU_CONST_BUFFER_SIZE_GS_9
+0x000281E8 SQ_ALU_CONST_BUFFER_SIZE_GS_10
+0x000281EC SQ_ALU_CONST_BUFFER_SIZE_GS_11
+0x000281F0 SQ_ALU_CONST_BUFFER_SIZE_GS_12
+0x000281F4 SQ_ALU_CONST_BUFFER_SIZE_GS_13
+0x000281F8 SQ_ALU_CONST_BUFFER_SIZE_GS_14
+0x000281FC SQ_ALU_CONST_BUFFER_SIZE_GS_15
+0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0
+0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1
+0x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2
+0x0002814C SQ_ALU_CONST_BUFFER_SIZE_PS_3
+0x00028150 SQ_ALU_CONST_BUFFER_SIZE_PS_4
+0x00028154 SQ_ALU_CONST_BUFFER_SIZE_PS_5
+0x00028158 SQ_ALU_CONST_BUFFER_SIZE_PS_6
+0x0002815C SQ_ALU_CONST_BUFFER_SIZE_PS_7
+0x00028160 SQ_ALU_CONST_BUFFER_SIZE_PS_8
+0x00028164 SQ_ALU_CONST_BUFFER_SIZE_PS_9
+0x00028168 SQ_ALU_CONST_BUFFER_SIZE_PS_10
+0x0002816C SQ_ALU_CONST_BUFFER_SIZE_PS_11
+0x00028170 SQ_ALU_CONST_BUFFER_SIZE_PS_12
+0x00028174 SQ_ALU_CONST_BUFFER_SIZE_PS_13
+0x00028178 SQ_ALU_CONST_BUFFER_SIZE_PS_14
+0x0002817C SQ_ALU_CONST_BUFFER_SIZE_PS_15
+0x00028180 SQ_ALU_CONST_BUFFER_SIZE_VS_0
+0x00028184 SQ_ALU_CONST_BUFFER_SIZE_VS_1
+0x00028188 SQ_ALU_CONST_BUFFER_SIZE_VS_2
+0x0002818C SQ_ALU_CONST_BUFFER_SIZE_VS_3
+0x00028190 SQ_ALU_CONST_BUFFER_SIZE_VS_4
+0x00028194 SQ_ALU_CONST_BUFFER_SIZE_VS_5
+0x00028198 SQ_ALU_CONST_BUFFER_SIZE_VS_6
+0x0002819C SQ_ALU_CONST_BUFFER_SIZE_VS_7
+0x000281A0 SQ_ALU_CONST_BUFFER_SIZE_VS_8
+0x000281A4 SQ_ALU_CONST_BUFFER_SIZE_VS_9
+0x000281A8 SQ_ALU_CONST_BUFFER_SIZE_VS_10
+0x000281AC SQ_ALU_CONST_BUFFER_SIZE_VS_11
+0x000281B0 SQ_ALU_CONST_BUFFER_SIZE_VS_12
+0x000281B4 SQ_ALU_CONST_BUFFER_SIZE_VS_13
+0x000281B8 SQ_ALU_CONST_BUFFER_SIZE_VS_14
+0x000281BC SQ_ALU_CONST_BUFFER_SIZE_VS_15
+0x000288D8 SQ_PGM_CF_OFFSET_ES
+0x000288DC SQ_PGM_CF_OFFSET_FS
+0x000288D4 SQ_PGM_CF_OFFSET_GS
+0x000288CC SQ_PGM_CF_OFFSET_PS
+0x000288D0 SQ_PGM_CF_OFFSET_VS
+0x00028854 SQ_PGM_EXPORTS_PS
+0x00028890 SQ_PGM_RESOURCES_ES
+0x000288A4 SQ_PGM_RESOURCES_FS
+0x0002887C SQ_PGM_RESOURCES_GS
+0x00028850 SQ_PGM_RESOURCES_PS
+0x00028868 SQ_PGM_RESOURCES_VS
+0x00009100 SPI_CONFIG_CNTL
+0x0000913C SPI_CONFIG_CNTL_1
+0x000286DC SPI_FOG_CNTL
+0x000286E4 SPI_FOG_FUNC_BIAS
+0x000286E0 SPI_FOG_FUNC_SCALE
+0x000286D8 SPI_INPUT_Z
+0x000286D4 SPI_INTERP_CONTROL_0
+0x00028644 SPI_PS_INPUT_CNTL_0
+0x00028648 SPI_PS_INPUT_CNTL_1
+0x0002864C SPI_PS_INPUT_CNTL_2
+0x00028650 SPI_PS_INPUT_CNTL_3
+0x00028654 SPI_PS_INPUT_CNTL_4
+0x00028658 SPI_PS_INPUT_CNTL_5
+0x0002865C SPI_PS_INPUT_CNTL_6
+0x00028660 SPI_PS_INPUT_CNTL_7
+0x00028664 SPI_PS_INPUT_CNTL_8
+0x00028668 SPI_PS_INPUT_CNTL_9
+0x0002866C SPI_PS_INPUT_CNTL_10
+0x00028670 SPI_PS_INPUT_CNTL_11
+0x00028674 SPI_PS_INPUT_CNTL_12
+0x00028678 SPI_PS_INPUT_CNTL_13
+0x0002867C SPI_PS_INPUT_CNTL_14
+0x00028680 SPI_PS_INPUT_CNTL_15
+0x00028684 SPI_PS_INPUT_CNTL_16
+0x00028688 SPI_PS_INPUT_CNTL_17
+0x0002868C SPI_PS_INPUT_CNTL_18
+0x00028690 SPI_PS_INPUT_CNTL_19
+0x00028694 SPI_PS_INPUT_CNTL_20
+0x00028698 SPI_PS_INPUT_CNTL_21
+0x0002869C SPI_PS_INPUT_CNTL_22
+0x000286A0 SPI_PS_INPUT_CNTL_23
+0x000286A4 SPI_PS_INPUT_CNTL_24
+0x000286A8 SPI_PS_INPUT_CNTL_25
+0x000286AC SPI_PS_INPUT_CNTL_26
+0x000286B0 SPI_PS_INPUT_CNTL_27
+0x000286B4 SPI_PS_INPUT_CNTL_28
+0x000286B8 SPI_PS_INPUT_CNTL_29
+0x000286BC SPI_PS_INPUT_CNTL_30
+0x000286C0 SPI_PS_INPUT_CNTL_31
+0x000286CC SPI_PS_IN_CONTROL_0
+0x000286D0 SPI_PS_IN_CONTROL_1
+0x000286C4 SPI_VS_OUT_CONFIG
+0x00028614 SPI_VS_OUT_ID_0
+0x00028618 SPI_VS_OUT_ID_1
+0x0002861C SPI_VS_OUT_ID_2
+0x00028620 SPI_VS_OUT_ID_3
+0x00028624 SPI_VS_OUT_ID_4
+0x00028628 SPI_VS_OUT_ID_5
+0x0002862C SPI_VS_OUT_ID_6
+0x00028630 SPI_VS_OUT_ID_7
+0x00028634 SPI_VS_OUT_ID_8
+0x00028638 SPI_VS_OUT_ID_9
+0x00028438 SX_ALPHA_REF
+0x00028410 SX_ALPHA_TEST_CONTROL
+0x00028350 SX_MISC
+0x00009604 TC_INVALIDATE
+0x00009400 TD_FILTER4
+0x00009404 TD_FILTER4_1
+0x00009408 TD_FILTER4_2
+0x0000940C TD_FILTER4_3
+0x00009410 TD_FILTER4_4
+0x00009414 TD_FILTER4_5
+0x00009418 TD_FILTER4_6
+0x0000941C TD_FILTER4_7
+0x00009420 TD_FILTER4_8
+0x00009424 TD_FILTER4_9
+0x00009428 TD_FILTER4_10
+0x0000942C TD_FILTER4_11
+0x00009430 TD_FILTER4_12
+0x00009434 TD_FILTER4_13
+0x00009438 TD_FILTER4_14
+0x0000943C TD_FILTER4_15
+0x00009440 TD_FILTER4_16
+0x00009444 TD_FILTER4_17
+0x00009448 TD_FILTER4_18
+0x0000944C TD_FILTER4_19
+0x00009450 TD_FILTER4_20
+0x00009454 TD_FILTER4_21
+0x00009458 TD_FILTER4_22
+0x0000945C TD_FILTER4_23
+0x00009460 TD_FILTER4_24
+0x00009464 TD_FILTER4_25
+0x00009468 TD_FILTER4_26
+0x0000946C TD_FILTER4_27
+0x00009470 TD_FILTER4_28
+0x00009474 TD_FILTER4_29
+0x00009478 TD_FILTER4_30
+0x0000947C TD_FILTER4_31
+0x00009480 TD_FILTER4_32
+0x00009484 TD_FILTER4_33
+0x00009488 TD_FILTER4_34
+0x0000948C TD_FILTER4_35
+0x0000A80C TD_GS_SAMPLER0_BORDER_ALPHA
+0x0000A81C TD_GS_SAMPLER1_BORDER_ALPHA
+0x0000A82C TD_GS_SAMPLER2_BORDER_ALPHA
+0x0000A83C TD_GS_SAMPLER3_BORDER_ALPHA
+0x0000A84C TD_GS_SAMPLER4_BORDER_ALPHA
+0x0000A85C TD_GS_SAMPLER5_BORDER_ALPHA
+0x0000A86C TD_GS_SAMPLER6_BORDER_ALPHA
+0x0000A87C TD_GS_SAMPLER7_BORDER_ALPHA
+0x0000A88C TD_GS_SAMPLER8_BORDER_ALPHA
+0x0000A89C TD_GS_SAMPLER9_BORDER_ALPHA
+0x0000A8AC TD_GS_SAMPLER10_BORDER_ALPHA
+0x0000A8BC TD_GS_SAMPLER11_BORDER_ALPHA
+0x0000A8CC TD_GS_SAMPLER12_BORDER_ALPHA
+0x0000A8DC TD_GS_SAMPLER13_BORDER_ALPHA
+0x0000A8EC TD_GS_SAMPLER14_BORDER_ALPHA
+0x0000A8FC TD_GS_SAMPLER15_BORDER_ALPHA
+0x0000A90C TD_GS_SAMPLER16_BORDER_ALPHA
+0x0000A91C TD_GS_SAMPLER17_BORDER_ALPHA
+0x0000A808 TD_GS_SAMPLER0_BORDER_BLUE
+0x0000A818 TD_GS_SAMPLER1_BORDER_BLUE
+0x0000A828 TD_GS_SAMPLER2_BORDER_BLUE
+0x0000A838 TD_GS_SAMPLER3_BORDER_BLUE
+0x0000A848 TD_GS_SAMPLER4_BORDER_BLUE
+0x0000A858 TD_GS_SAMPLER5_BORDER_BLUE
+0x0000A868 TD_GS_SAMPLER6_BORDER_BLUE
+0x0000A878 TD_GS_SAMPLER7_BORDER_BLUE
+0x0000A888 TD_GS_SAMPLER8_BORDER_BLUE
+0x0000A898 TD_GS_SAMPLER9_BORDER_BLUE
+0x0000A8A8 TD_GS_SAMPLER10_BORDER_BLUE
+0x0000A8B8 TD_GS_SAMPLER11_BORDER_BLUE
+0x0000A8C8 TD_GS_SAMPLER12_BORDER_BLUE
+0x0000A8D8 TD_GS_SAMPLER13_BORDER_BLUE
+0x0000A8E8 TD_GS_SAMPLER14_BORDER_BLUE
+0x0000A8F8 TD_GS_SAMPLER15_BORDER_BLUE
+0x0000A908 TD_GS_SAMPLER16_BORDER_BLUE
+0x0000A918 TD_GS_SAMPLER17_BORDER_BLUE
+0x0000A804 TD_GS_SAMPLER0_BORDER_GREEN
+0x0000A814 TD_GS_SAMPLER1_BORDER_GREEN
+0x0000A824 TD_GS_SAMPLER2_BORDER_GREEN
+0x0000A834 TD_GS_SAMPLER3_BORDER_GREEN
+0x0000A844 TD_GS_SAMPLER4_BORDER_GREEN
+0x0000A854 TD_GS_SAMPLER5_BORDER_GREEN
+0x0000A864 TD_GS_SAMPLER6_BORDER_GREEN
+0x0000A874 TD_GS_SAMPLER7_BORDER_GREEN
+0x0000A884 TD_GS_SAMPLER8_BORDER_GREEN
+0x0000A894 TD_GS_SAMPLER9_BORDER_GREEN
+0x0000A8A4 TD_GS_SAMPLER10_BORDER_GREEN
+0x0000A8B4 TD_GS_SAMPLER11_BORDER_GREEN
+0x0000A8C4 TD_GS_SAMPLER12_BORDER_GREEN
+0x0000A8D4 TD_GS_SAMPLER13_BORDER_GREEN
+0x0000A8E4 TD_GS_SAMPLER14_BORDER_GREEN
+0x0000A8F4 TD_GS_SAMPLER15_BORDER_GREEN
+0x0000A904 TD_GS_SAMPLER16_BORDER_GREEN
+0x0000A914 TD_GS_SAMPLER17_BORDER_GREEN
+0x0000A800 TD_GS_SAMPLER0_BORDER_RED
+0x0000A810 TD_GS_SAMPLER1_BORDER_RED
+0x0000A820 TD_GS_SAMPLER2_BORDER_RED
+0x0000A830 TD_GS_SAMPLER3_BORDER_RED
+0x0000A840 TD_GS_SAMPLER4_BORDER_RED
+0x0000A850 TD_GS_SAMPLER5_BORDER_RED
+0x0000A860 TD_GS_SAMPLER6_BORDER_RED
+0x0000A870 TD_GS_SAMPLER7_BORDER_RED
+0x0000A880 TD_GS_SAMPLER8_BORDER_RED
+0x0000A890 TD_GS_SAMPLER9_BORDER_RED
+0x0000A8A0 TD_GS_SAMPLER10_BORDER_RED
+0x0000A8B0 TD_GS_SAMPLER11_BORDER_RED
+0x0000A8C0 TD_GS_SAMPLER12_BORDER_RED
+0x0000A8D0 TD_GS_SAMPLER13_BORDER_RED
+0x0000A8E0 TD_GS_SAMPLER14_BORDER_RED
+0x0000A8F0 TD_GS_SAMPLER15_BORDER_RED
+0x0000A900 TD_GS_SAMPLER16_BORDER_RED
+0x0000A910 TD_GS_SAMPLER17_BORDER_RED
+0x0000A40C TD_PS_SAMPLER0_BORDER_ALPHA
+0x0000A41C TD_PS_SAMPLER1_BORDER_ALPHA
+0x0000A42C TD_PS_SAMPLER2_BORDER_ALPHA
+0x0000A43C TD_PS_SAMPLER3_BORDER_ALPHA
+0x0000A44C TD_PS_SAMPLER4_BORDER_ALPHA
+0x0000A45C TD_PS_SAMPLER5_BORDER_ALPHA
+0x0000A46C TD_PS_SAMPLER6_BORDER_ALPHA
+0x0000A47C TD_PS_SAMPLER7_BORDER_ALPHA
+0x0000A48C TD_PS_SAMPLER8_BORDER_ALPHA
+0x0000A49C TD_PS_SAMPLER9_BORDER_ALPHA
+0x0000A4AC TD_PS_SAMPLER10_BORDER_ALPHA
+0x0000A4BC TD_PS_SAMPLER11_BORDER_ALPHA
+0x0000A4CC TD_PS_SAMPLER12_BORDER_ALPHA
+0x0000A4DC TD_PS_SAMPLER13_BORDER_ALPHA
+0x0000A4EC TD_PS_SAMPLER14_BORDER_ALPHA
+0x0000A4FC TD_PS_SAMPLER15_BORDER_ALPHA
+0x0000A50C TD_PS_SAMPLER16_BORDER_ALPHA
+0x0000A51C TD_PS_SAMPLER17_BORDER_ALPHA
+0x0000A408 TD_PS_SAMPLER0_BORDER_BLUE
+0x0000A418 TD_PS_SAMPLER1_BORDER_BLUE
+0x0000A428 TD_PS_SAMPLER2_BORDER_BLUE
+0x0000A438 TD_PS_SAMPLER3_BORDER_BLUE
+0x0000A448 TD_PS_SAMPLER4_BORDER_BLUE
+0x0000A458 TD_PS_SAMPLER5_BORDER_BLUE
+0x0000A468 TD_PS_SAMPLER6_BORDER_BLUE
+0x0000A478 TD_PS_SAMPLER7_BORDER_BLUE
+0x0000A488 TD_PS_SAMPLER8_BORDER_BLUE
+0x0000A498 TD_PS_SAMPLER9_BORDER_BLUE
+0x0000A4A8 TD_PS_SAMPLER10_BORDER_BLUE
+0x0000A4B8 TD_PS_SAMPLER11_BORDER_BLUE
+0x0000A4C8 TD_PS_SAMPLER12_BORDER_BLUE
+0x0000A4D8 TD_PS_SAMPLER13_BORDER_BLUE
+0x0000A4E8 TD_PS_SAMPLER14_BORDER_BLUE
+0x0000A4F8 TD_PS_SAMPLER15_BORDER_BLUE
+0x0000A508 TD_PS_SAMPLER16_BORDER_BLUE
+0x0000A518 TD_PS_SAMPLER17_BORDER_BLUE
+0x0000A404 TD_PS_SAMPLER0_BORDER_GREEN
+0x0000A414 TD_PS_SAMPLER1_BORDER_GREEN
+0x0000A424 TD_PS_SAMPLER2_BORDER_GREEN
+0x0000A434 TD_PS_SAMPLER3_BORDER_GREEN
+0x0000A444 TD_PS_SAMPLER4_BORDER_GREEN
+0x0000A454 TD_PS_SAMPLER5_BORDER_GREEN
+0x0000A464 TD_PS_SAMPLER6_BORDER_GREEN
+0x0000A474 TD_PS_SAMPLER7_BORDER_GREEN
+0x0000A484 TD_PS_SAMPLER8_BORDER_GREEN
+0x0000A494 TD_PS_SAMPLER9_BORDER_GREEN
+0x0000A4A4 TD_PS_SAMPLER10_BORDER_GREEN
+0x0000A4B4 TD_PS_SAMPLER11_BORDER_GREEN
+0x0000A4C4 TD_PS_SAMPLER12_BORDER_GREEN
+0x0000A4D4 TD_PS_SAMPLER13_BORDER_GREEN
+0x0000A4E4 TD_PS_SAMPLER14_BORDER_GREEN
+0x0000A4F4 TD_PS_SAMPLER15_BORDER_GREEN
+0x0000A504 TD_PS_SAMPLER16_BORDER_GREEN
+0x0000A514 TD_PS_SAMPLER17_BORDER_GREEN
+0x0000A400 TD_PS_SAMPLER0_BORDER_RED
+0x0000A410 TD_PS_SAMPLER1_BORDER_RED
+0x0000A420 TD_PS_SAMPLER2_BORDER_RED
+0x0000A430 TD_PS_SAMPLER3_BORDER_RED
+0x0000A440 TD_PS_SAMPLER4_BORDER_RED
+0x0000A450 TD_PS_SAMPLER5_BORDER_RED
+0x0000A460 TD_PS_SAMPLER6_BORDER_RED
+0x0000A470 TD_PS_SAMPLER7_BORDER_RED
+0x0000A480 TD_PS_SAMPLER8_BORDER_RED
+0x0000A490 TD_PS_SAMPLER9_BORDER_RED
+0x0000A4A0 TD_PS_SAMPLER10_BORDER_RED
+0x0000A4B0 TD_PS_SAMPLER11_BORDER_RED
+0x0000A4C0 TD_PS_SAMPLER12_BORDER_RED
+0x0000A4D0 TD_PS_SAMPLER13_BORDER_RED
+0x0000A4E0 TD_PS_SAMPLER14_BORDER_RED
+0x0000A4F0 TD_PS_SAMPLER15_BORDER_RED
+0x0000A500 TD_PS_SAMPLER16_BORDER_RED
+0x0000A510 TD_PS_SAMPLER17_BORDER_RED
+0x0000AA00 TD_PS_SAMPLER0_CLEARTYPE_KERNEL
+0x0000AA04 TD_PS_SAMPLER1_CLEARTYPE_KERNEL
+0x0000AA08 TD_PS_SAMPLER2_CLEARTYPE_KERNEL
+0x0000AA0C TD_PS_SAMPLER3_CLEARTYPE_KERNEL
+0x0000AA10 TD_PS_SAMPLER4_CLEARTYPE_KERNEL
+0x0000AA14 TD_PS_SAMPLER5_CLEARTYPE_KERNEL
+0x0000AA18 TD_PS_SAMPLER6_CLEARTYPE_KERNEL
+0x0000AA1C TD_PS_SAMPLER7_CLEARTYPE_KERNEL
+0x0000AA20 TD_PS_SAMPLER8_CLEARTYPE_KERNEL
+0x0000AA24 TD_PS_SAMPLER9_CLEARTYPE_KERNEL
+0x0000AA28 TD_PS_SAMPLER10_CLEARTYPE_KERNEL
+0x0000AA2C TD_PS_SAMPLER11_CLEARTYPE_KERNEL
+0x0000AA30 TD_PS_SAMPLER12_CLEARTYPE_KERNEL
+0x0000AA34 TD_PS_SAMPLER13_CLEARTYPE_KERNEL
+0x0000AA38 TD_PS_SAMPLER14_CLEARTYPE_KERNEL
+0x0000AA3C TD_PS_SAMPLER15_CLEARTYPE_KERNEL
+0x0000AA40 TD_PS_SAMPLER16_CLEARTYPE_KERNEL
+0x0000AA44 TD_PS_SAMPLER17_CLEARTYPE_KERNEL
+0x0000A60C TD_VS_SAMPLER0_BORDER_ALPHA
+0x0000A61C TD_VS_SAMPLER1_BORDER_ALPHA
+0x0000A62C TD_VS_SAMPLER2_BORDER_ALPHA
+0x0000A63C TD_VS_SAMPLER3_BORDER_ALPHA
+0x0000A64C TD_VS_SAMPLER4_BORDER_ALPHA
+0x0000A65C TD_VS_SAMPLER5_BORDER_ALPHA
+0x0000A66C TD_VS_SAMPLER6_BORDER_ALPHA
+0x0000A67C TD_VS_SAMPLER7_BORDER_ALPHA
+0x0000A68C TD_VS_SAMPLER8_BORDER_ALPHA
+0x0000A69C TD_VS_SAMPLER9_BORDER_ALPHA
+0x0000A6AC TD_VS_SAMPLER10_BORDER_ALPHA
+0x0000A6BC TD_VS_SAMPLER11_BORDER_ALPHA
+0x0000A6CC TD_VS_SAMPLER12_BORDER_ALPHA
+0x0000A6DC TD_VS_SAMPLER13_BORDER_ALPHA
+0x0000A6EC TD_VS_SAMPLER14_BORDER_ALPHA
+0x0000A6FC TD_VS_SAMPLER15_BORDER_ALPHA
+0x0000A70C TD_VS_SAMPLER16_BORDER_ALPHA
+0x0000A71C TD_VS_SAMPLER17_BORDER_ALPHA
+0x0000A608 TD_VS_SAMPLER0_BORDER_BLUE
+0x0000A618 TD_VS_SAMPLER1_BORDER_BLUE
+0x0000A628 TD_VS_SAMPLER2_BORDER_BLUE
+0x0000A638 TD_VS_SAMPLER3_BORDER_BLUE
+0x0000A648 TD_VS_SAMPLER4_BORDER_BLUE
+0x0000A658 TD_VS_SAMPLER5_BORDER_BLUE
+0x0000A668 TD_VS_SAMPLER6_BORDER_BLUE
+0x0000A678 TD_VS_SAMPLER7_BORDER_BLUE
+0x0000A688 TD_VS_SAMPLER8_BORDER_BLUE
+0x0000A698 TD_VS_SAMPLER9_BORDER_BLUE
+0x0000A6A8 TD_VS_SAMPLER10_BORDER_BLUE
+0x0000A6B8 TD_VS_SAMPLER11_BORDER_BLUE
+0x0000A6C8 TD_VS_SAMPLER12_BORDER_BLUE
+0x0000A6D8 TD_VS_SAMPLER13_BORDER_BLUE
+0x0000A6E8 TD_VS_SAMPLER14_BORDER_BLUE
+0x0000A6F8 TD_VS_SAMPLER15_BORDER_BLUE
+0x0000A708 TD_VS_SAMPLER16_BORDER_BLUE
+0x0000A718 TD_VS_SAMPLER17_BORDER_BLUE
+0x0000A604 TD_VS_SAMPLER0_BORDER_GREEN
+0x0000A614 TD_VS_SAMPLER1_BORDER_GREEN
+0x0000A624 TD_VS_SAMPLER2_BORDER_GREEN
+0x0000A634 TD_VS_SAMPLER3_BORDER_GREEN
+0x0000A644 TD_VS_SAMPLER4_BORDER_GREEN
+0x0000A654 TD_VS_SAMPLER5_BORDER_GREEN
+0x0000A664 TD_VS_SAMPLER6_BORDER_GREEN
+0x0000A674 TD_VS_SAMPLER7_BORDER_GREEN
+0x0000A684 TD_VS_SAMPLER8_BORDER_GREEN
+0x0000A694 TD_VS_SAMPLER9_BORDER_GREEN
+0x0000A6A4 TD_VS_SAMPLER10_BORDER_GREEN
+0x0000A6B4 TD_VS_SAMPLER11_BORDER_GREEN
+0x0000A6C4 TD_VS_SAMPLER12_BORDER_GREEN
+0x0000A6D4 TD_VS_SAMPLER13_BORDER_GREEN
+0x0000A6E4 TD_VS_SAMPLER14_BORDER_GREEN
+0x0000A6F4 TD_VS_SAMPLER15_BORDER_GREEN
+0x0000A704 TD_VS_SAMPLER16_BORDER_GREEN
+0x0000A714 TD_VS_SAMPLER17_BORDER_GREEN
+0x0000A600 TD_VS_SAMPLER0_BORDER_RED
+0x0000A610 TD_VS_SAMPLER1_BORDER_RED
+0x0000A620 TD_VS_SAMPLER2_BORDER_RED
+0x0000A630 TD_VS_SAMPLER3_BORDER_RED
+0x0000A640 TD_VS_SAMPLER4_BORDER_RED
+0x0000A650 TD_VS_SAMPLER5_BORDER_RED
+0x0000A660 TD_VS_SAMPLER6_BORDER_RED
+0x0000A670 TD_VS_SAMPLER7_BORDER_RED
+0x0000A680 TD_VS_SAMPLER8_BORDER_RED
+0x0000A690 TD_VS_SAMPLER9_BORDER_RED
+0x0000A6A0 TD_VS_SAMPLER10_BORDER_RED
+0x0000A6B0 TD_VS_SAMPLER11_BORDER_RED
+0x0000A6C0 TD_VS_SAMPLER12_BORDER_RED
+0x0000A6D0 TD_VS_SAMPLER13_BORDER_RED
+0x0000A6E0 TD_VS_SAMPLER14_BORDER_RED
+0x0000A6F0 TD_VS_SAMPLER15_BORDER_RED
+0x0000A700 TD_VS_SAMPLER16_BORDER_RED
+0x0000A710 TD_VS_SAMPLER17_BORDER_RED
+0x00009508 TA_CNTL_AUX
+0x0002802C DB_DEPTH_CLEAR
+0x00028D24 DB_HTILE_SURFACE
+0x00028D34 DB_PREFETCH_LIMIT
+0x00028D30 DB_PRELOAD_CONTROL
+0x00028D0C DB_RENDER_CONTROL
+0x00028D10 DB_RENDER_OVERRIDE
+0x0002880C DB_SHADER_CONTROL
+0x00028D2C DB_SRESULTS_COMPARE_STATE1
+0x00028430 DB_STENCILREFMASK
+0x00028434 DB_STENCILREFMASK_BF
+0x00028028 DB_STENCIL_CLEAR
+0x00028780 CB_BLEND0_CONTROL
+0x00028784 CB_BLEND1_CONTROL
+0x00028788 CB_BLEND2_CONTROL
+0x0002878C CB_BLEND3_CONTROL
+0x00028790 CB_BLEND4_CONTROL
+0x00028794 CB_BLEND5_CONTROL
+0x00028798 CB_BLEND6_CONTROL
+0x0002879C CB_BLEND7_CONTROL
+0x00028804 CB_BLEND_CONTROL
+0x00028420 CB_BLEND_ALPHA
+0x0002841C CB_BLEND_BLUE
+0x00028418 CB_BLEND_GREEN
+0x00028414 CB_BLEND_RED
+0x0002812C CB_CLEAR_ALPHA
+0x00028128 CB_CLEAR_BLUE
+0x00028124 CB_CLEAR_GREEN
+0x00028120 CB_CLEAR_RED
+0x00028C30 CB_CLRCMP_CONTROL
+0x00028C38 CB_CLRCMP_DST
+0x00028C3C CB_CLRCMP_MSK
+0x00028C34 CB_CLRCMP_SRC
+0x00028100 CB_COLOR0_MASK
+0x00028104 CB_COLOR1_MASK
+0x00028108 CB_COLOR2_MASK
+0x0002810C CB_COLOR3_MASK
+0x00028110 CB_COLOR4_MASK
+0x00028114 CB_COLOR5_MASK
+0x00028118 CB_COLOR6_MASK
+0x0002811C CB_COLOR7_MASK
+0x00028080 CB_COLOR0_VIEW
+0x00028084 CB_COLOR1_VIEW
+0x00028088 CB_COLOR2_VIEW
+0x0002808C CB_COLOR3_VIEW
+0x00028090 CB_COLOR4_VIEW
+0x00028094 CB_COLOR5_VIEW
+0x00028098 CB_COLOR6_VIEW
+0x0002809C CB_COLOR7_VIEW
+0x00028808 CB_COLOR_CONTROL
+0x0002842C CB_FOG_BLUE
+0x00028428 CB_FOG_GREEN
+0x00028424 CB_FOG_RED
+0x00008040 WAIT_UNTIL
+0x00009714 VC_ENHANCE
+0x00009830 DB_DEBUG
+0x00009838 DB_WATERMARKS
+0x00028D28 DB_SRESULTS_COMPARE_STATE0
+0x00028D44 DB_ALPHA_TO_MASK
+0x00009700 VC_CNTL
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/rs600 linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/reg_srcs/rs600
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/rs600	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/reg_srcs/rs600	2010-05-16 17:17:36.000000000 -0400
@@ -125,6 +125,8 @@ rs600 0x6d40
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/rv515 linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/reg_srcs/rv515
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/rv515	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/reg_srcs/rv515	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@ rv515 0x6d40
 0x1DA8 VAP_VPORT_ZSCALE
 0x1DAC VAP_VPORT_ZOFFSET
 0x2080 VAP_CNTL
+0x208C VAP_INDEX_OFFSET
 0x2090 VAP_OUT_VTX_FMT_0
 0x2094 VAP_OUT_VTX_FMT_1
 0x20B0 VAP_VTE_CNTL
@@ -158,6 +159,8 @@ rv515 0x6d40
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs400.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rs400.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs400.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rs400.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,8 +26,10 @@
  *          Jerome Glisse
  */
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <drm/drmP.h>
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "rs400d.h"
 
 /* This files gather functions specifics to : rs400,rs480 */
@@ -113,6 +115,7 @@ int rs400_gart_enable(struct radeon_devi
 	uint32_t size_reg;
 	uint32_t tmp;
 
+	radeon_gart_restore(rdev);
 	tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH);
 	tmp |= RS690_DIS_OUT_OF_PCI_GART_ACCESS;
 	WREG32_MC(RS690_AIC_CTRL_SCRATCH, tmp);
@@ -150,9 +153,8 @@ int rs400_gart_enable(struct radeon_devi
 		WREG32(RADEON_AGP_BASE, 0xFFFFFFFF);
 		WREG32(RS480_AGP_BASE_2, 0);
 	}
-	tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
-	tmp = REG_SET(RS690_MC_AGP_TOP, tmp >> 16);
-	tmp |= REG_SET(RS690_MC_AGP_START, rdev->mc.gtt_location >> 16);
+	tmp = REG_SET(RS690_MC_AGP_TOP, rdev->mc.gtt_end >> 16);
+	tmp |= REG_SET(RS690_MC_AGP_START, rdev->mc.gtt_start >> 16);
 	if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) {
 		WREG32_MC(RS690_MCCFG_AGP_LOCATION, tmp);
 		tmp = RREG32(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;
@@ -202,9 +204,9 @@ void rs400_gart_disable(struct radeon_de
 
 void rs400_gart_fini(struct radeon_device *rdev)
 {
+	radeon_gart_fini(rdev);
 	rs400_gart_disable(rdev);
 	radeon_gart_table_ram_free(rdev);
-	radeon_gart_fini(rdev);
 }
 
 int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
@@ -251,14 +253,20 @@ void rs400_gpu_init(struct radeon_device
 	}
 }
 
-void rs400_vram_info(struct radeon_device *rdev)
+void rs400_mc_init(struct radeon_device *rdev)
 {
+	u64 base;
+
 	rs400_gart_adjust_size(rdev);
+	rdev->mc.igp_sideport_enabled = radeon_combios_sideport_present(rdev);
 	/* DDR for all card after R300 & IGP */
 	rdev->mc.vram_is_ddr = true;
 	rdev->mc.vram_width = 128;
-
 	r100_vram_init_sizes(rdev);
+	base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
+	radeon_vram_location(rdev, &rdev->mc, base);
+	radeon_gtt_location(rdev, &rdev->mc);
+	radeon_update_bandwidth_info(rdev);
 }
 
 uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg)
@@ -362,22 +370,6 @@ static int rs400_debugfs_pcie_gart_info_
 #endif
 }
 
-static int rs400_mc_init(struct radeon_device *rdev)
-{
-	int r;
-	u32 tmp;
-
-	/* Setup GPU memory space */
-	tmp = RREG32(R_00015C_NB_TOM);
-	rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16;
-	rdev->mc.gtt_location = 0xFFFFFFFFUL;
-	r = radeon_mc_setup(rdev);
-	rdev->mc.igp_sideport_enabled = radeon_combios_sideport_present(rdev);
-	if (r)
-		return r;
-	return 0;
-}
-
 void rs400_mc_program(struct radeon_device *rdev)
 {
 	struct r100_mc_save save;
@@ -399,6 +391,8 @@ static int rs400_startup(struct radeon_d
 {
 	int r;
 
+	r100_set_common_regs(rdev);
+
 	rs400_mc_program(rdev);
 	/* Resume clock */
 	r300_clock_startup(rdev);
@@ -464,6 +458,7 @@ int rs400_suspend(struct radeon_device *
 
 void rs400_fini(struct radeon_device *rdev)
 {
+	radeon_pm_fini(rdev);
 	r100_cp_fini(rdev);
 	r100_wb_fini(rdev);
 	r100_ib_fini(rdev);
@@ -516,12 +511,8 @@ int rs400_init(struct radeon_device *rde
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
 	radeon_pm_init(rdev);
-	/* Get vram informations */
-	rs400_vram_info(rdev);
-	/* Initialize memory controller (also test AGP) */
-	r = rs400_mc_init(rdev);
-	if (r)
-		return r;
+	/* initialize memory controller */
+	rs400_mc_init(rdev);
 	/* Fence driver */
 	r = radeon_fence_driver_init(rdev);
 	if (r)
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs600.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rs600.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs600.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rs600.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
  */
 #include "drmP.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "atom.h"
 #include "rs600d.h"
 
@@ -45,23 +46,6 @@
 void rs600_gpu_init(struct radeon_device *rdev);
 int rs600_mc_wait_for_idle(struct radeon_device *rdev);
 
-int rs600_mc_init(struct radeon_device *rdev)
-{
-	/* read back the MC value from the hw */
-	int r;
-	u32 tmp;
-
-	/* Setup GPU memory space */
-	tmp = RREG32_MC(R_000004_MC_FB_LOCATION);
-	rdev->mc.vram_location = G_000004_MC_FB_START(tmp) << 16;
-	rdev->mc.gtt_location = 0xffffffffUL;
-	r = radeon_mc_setup(rdev);
-	rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
-	if (r)
-		return r;
-	return 0;
-}
-
 /* hpd for digital panel detect/disconnect */
 bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
 {
@@ -175,7 +159,7 @@ void rs600_gart_tlb_flush(struct radeon_
 	WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
 
 	tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
-	tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) & S_000100_INVALIDATE_L2_CACHE(1);
+	tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) | S_000100_INVALIDATE_L2_CACHE(1);
 	WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
 
 	tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
@@ -213,6 +197,7 @@ int rs600_gart_enable(struct radeon_devi
 	r = radeon_gart_table_vram_pin(rdev);
 	if (r)
 		return r;
+	radeon_gart_restore(rdev);
 	/* Enable bus master */
 	tmp = RREG32(R_00004C_BUS_CNTL) & C_00004C_BUS_MASTER_DIS;
 	WREG32(R_00004C_BUS_CNTL, tmp);
@@ -283,9 +268,9 @@ void rs600_gart_disable(struct radeon_de
 
 void rs600_gart_fini(struct radeon_device *rdev)
 {
+	radeon_gart_fini(rdev);
 	rs600_gart_disable(rdev);
 	radeon_gart_table_vram_free(rdev);
-	radeon_gart_fini(rdev);
 }
 
 #define R600_PTE_VALID     (1 << 0)
@@ -406,10 +391,16 @@ int rs600_irq_process(struct radeon_devi
 		if (G_000044_SW_INT(status))
 			radeon_fence_process(rdev);
 		/* Vertical blank interrupts */
-		if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int))
+		if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) {
 			drm_handle_vblank(rdev->ddev, 0);
-		if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int))
+			rdev->pm.vblank_sync = true;
+			wake_up(&rdev->irq.vblank_queue);
+		}
+		if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) {
 			drm_handle_vblank(rdev->ddev, 1);
+			rdev->pm.vblank_sync = true;
+			wake_up(&rdev->irq.vblank_queue);
+		}
 		if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) {
 			queue_hotplug = true;
 			DRM_DEBUG("HPD1\n");
@@ -470,27 +461,52 @@ void rs600_gpu_init(struct radeon_device
 		dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
 }
 
-void rs600_vram_info(struct radeon_device *rdev)
+void rs600_mc_init(struct radeon_device *rdev)
 {
+	u64 base;
+
+	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
+	rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
 	rdev->mc.vram_is_ddr = true;
 	rdev->mc.vram_width = 128;
-
 	rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
 	rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
-
-	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-	rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
-
-	if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
-		rdev->mc.mc_vram_size = rdev->mc.aper_size;
-
-	if (rdev->mc.real_vram_size > rdev->mc.aper_size)
-		rdev->mc.real_vram_size = rdev->mc.aper_size;
+	rdev->mc.visible_vram_size = rdev->mc.aper_size;
+	rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
+	base = RREG32_MC(R_000004_MC_FB_LOCATION);
+	base = G_000004_MC_FB_START(base) << 16;
+	rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
+	radeon_vram_location(rdev, &rdev->mc, base);
+	radeon_gtt_location(rdev, &rdev->mc);
+	radeon_update_bandwidth_info(rdev);
 }
 
 void rs600_bandwidth_update(struct radeon_device *rdev)
 {
-	/* FIXME: implement, should this be like rs690 ? */
+	struct drm_display_mode *mode0 = NULL;
+	struct drm_display_mode *mode1 = NULL;
+	u32 d1mode_priority_a_cnt, d2mode_priority_a_cnt;
+	/* FIXME: implement full support */
+
+	radeon_update_display_priority(rdev);
+
+	if (rdev->mode_info.crtcs[0]->base.enabled)
+		mode0 = &rdev->mode_info.crtcs[0]->base.mode;
+	if (rdev->mode_info.crtcs[1]->base.enabled)
+		mode1 = &rdev->mode_info.crtcs[1]->base.mode;
+
+	rs690_line_buffer_adjust(rdev, mode0, mode1);
+
+	if (rdev->disp_priority == 2) {
+		d1mode_priority_a_cnt = RREG32(R_006548_D1MODE_PRIORITY_A_CNT);
+		d2mode_priority_a_cnt = RREG32(R_006D48_D2MODE_PRIORITY_A_CNT);
+		d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
+		d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
+		WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
+		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
+	}
 }
 
 uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg)
@@ -610,6 +626,7 @@ int rs600_suspend(struct radeon_device *
 
 void rs600_fini(struct radeon_device *rdev)
 {
+	radeon_pm_fini(rdev);
 	r100_cp_fini(rdev);
 	r100_wb_fini(rdev);
 	r100_ib_fini(rdev);
@@ -661,12 +678,8 @@ int rs600_init(struct radeon_device *rde
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
 	radeon_pm_init(rdev);
-	/* Get vram informations */
-	rs600_vram_info(rdev);
-	/* Initialize memory controller (also test AGP) */
-	r = rs600_mc_init(rdev);
-	if (r)
-		return r;
+	/* initialize memory controller */
+	rs600_mc_init(rdev);
 	rs600_debugfs(rdev);
 	/* Fence driver */
 	r = radeon_fence_driver_init(rdev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs600d.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rs600d.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs600d.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rs600d.h	2010-05-16 17:17:36.000000000 -0400
@@ -535,4 +535,57 @@
 #define   G_00016C_INVALIDATE_L1_TLB(x)                (((x) >> 20) & 0x1)
 #define   C_00016C_INVALIDATE_L1_TLB                   0xFFEFFFFF
 
+#define R_006548_D1MODE_PRIORITY_A_CNT               0x006548
+#define   S_006548_D1MODE_PRIORITY_MARK_A(x)           (((x) & 0x7FFF) << 0)
+#define   G_006548_D1MODE_PRIORITY_MARK_A(x)           (((x) >> 0) & 0x7FFF)
+#define   C_006548_D1MODE_PRIORITY_MARK_A              0xFFFF8000
+#define   S_006548_D1MODE_PRIORITY_A_OFF(x)            (((x) & 0x1) << 16)
+#define   G_006548_D1MODE_PRIORITY_A_OFF(x)            (((x) >> 16) & 0x1)
+#define   C_006548_D1MODE_PRIORITY_A_OFF               0xFFFEFFFF
+#define   S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) & 0x1) << 20)
+#define   G_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) >> 20) & 0x1)
+#define   C_006548_D1MODE_PRIORITY_A_ALWAYS_ON         0xFFEFFFFF
+#define   S_006548_D1MODE_PRIORITY_A_FORCE_MASK(x)     (((x) & 0x1) << 24)
+#define   G_006548_D1MODE_PRIORITY_A_FORCE_MASK(x)     (((x) >> 24) & 0x1)
+#define   C_006548_D1MODE_PRIORITY_A_FORCE_MASK        0xFEFFFFFF
+#define R_00654C_D1MODE_PRIORITY_B_CNT               0x00654C
+#define   S_00654C_D1MODE_PRIORITY_MARK_B(x)           (((x) & 0x7FFF) << 0)
+#define   G_00654C_D1MODE_PRIORITY_MARK_B(x)           (((x) >> 0) & 0x7FFF)
+#define   C_00654C_D1MODE_PRIORITY_MARK_B              0xFFFF8000
+#define   S_00654C_D1MODE_PRIORITY_B_OFF(x)            (((x) & 0x1) << 16)
+#define   G_00654C_D1MODE_PRIORITY_B_OFF(x)            (((x) >> 16) & 0x1)
+#define   C_00654C_D1MODE_PRIORITY_B_OFF               0xFFFEFFFF
+#define   S_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x)      (((x) & 0x1) << 20)
+#define   G_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x)      (((x) >> 20) & 0x1)
+#define   C_00654C_D1MODE_PRIORITY_B_ALWAYS_ON         0xFFEFFFFF
+#define   S_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x)     (((x) & 0x1) << 24)
+#define   G_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x)     (((x) >> 24) & 0x1)
+#define   C_00654C_D1MODE_PRIORITY_B_FORCE_MASK        0xFEFFFFFF
+#define R_006D48_D2MODE_PRIORITY_A_CNT               0x006D48
+#define   S_006D48_D2MODE_PRIORITY_MARK_A(x)           (((x) & 0x7FFF) << 0)
+#define   G_006D48_D2MODE_PRIORITY_MARK_A(x)           (((x) >> 0) & 0x7FFF)
+#define   C_006D48_D2MODE_PRIORITY_MARK_A              0xFFFF8000
+#define   S_006D48_D2MODE_PRIORITY_A_OFF(x)            (((x) & 0x1) << 16)
+#define   G_006D48_D2MODE_PRIORITY_A_OFF(x)            (((x) >> 16) & 0x1)
+#define   C_006D48_D2MODE_PRIORITY_A_OFF               0xFFFEFFFF
+#define   S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) & 0x1) << 20)
+#define   G_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) >> 20) & 0x1)
+#define   C_006D48_D2MODE_PRIORITY_A_ALWAYS_ON         0xFFEFFFFF
+#define   S_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x)     (((x) & 0x1) << 24)
+#define   G_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x)     (((x) >> 24) & 0x1)
+#define   C_006D48_D2MODE_PRIORITY_A_FORCE_MASK        0xFEFFFFFF
+#define R_006D4C_D2MODE_PRIORITY_B_CNT               0x006D4C
+#define   S_006D4C_D2MODE_PRIORITY_MARK_B(x)           (((x) & 0x7FFF) << 0)
+#define   G_006D4C_D2MODE_PRIORITY_MARK_B(x)           (((x) >> 0) & 0x7FFF)
+#define   C_006D4C_D2MODE_PRIORITY_MARK_B              0xFFFF8000
+#define   S_006D4C_D2MODE_PRIORITY_B_OFF(x)            (((x) & 0x1) << 16)
+#define   G_006D4C_D2MODE_PRIORITY_B_OFF(x)            (((x) >> 16) & 0x1)
+#define   C_006D4C_D2MODE_PRIORITY_B_OFF               0xFFFEFFFF
+#define   S_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x)      (((x) & 0x1) << 20)
+#define   G_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x)      (((x) >> 20) & 0x1)
+#define   C_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON         0xFFEFFFFF
+#define   S_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x)     (((x) & 0x1) << 24)
+#define   G_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x)     (((x) >> 24) & 0x1)
+#define   C_006D4C_D2MODE_PRIORITY_B_FORCE_MASK        0xFEFFFFFF
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs690.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rs690.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs690.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rs690.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
  */
 #include "drmP.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "atom.h"
 #include "rs690d.h"
 
@@ -57,42 +58,57 @@ static void rs690_gpu_init(struct radeon
 	}
 }
 
+union igp_info {
+	struct _ATOM_INTEGRATED_SYSTEM_INFO info;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_v2;
+};
+
 void rs690_pm_info(struct radeon_device *rdev)
 {
 	int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
-	struct _ATOM_INTEGRATED_SYSTEM_INFO *info;
-	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *info_v2;
-	void *ptr;
+	union igp_info *info;
 	uint16_t data_offset;
 	uint8_t frev, crev;
 	fixed20_12 tmp;
 
-	atom_parse_data_header(rdev->mode_info.atom_context, index, NULL,
-			       &frev, &crev, &data_offset);
-	ptr = rdev->mode_info.atom_context->bios + data_offset;
-	info = (struct _ATOM_INTEGRATED_SYSTEM_INFO *)ptr;
-	info_v2 = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *)ptr;
-	/* Get various system informations from bios */
-	switch (crev) {
-	case 1:
-		tmp.full = rfixed_const(100);
-		rdev->pm.igp_sideport_mclk.full = rfixed_const(info->ulBootUpMemoryClock);
-		rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
-		rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->usK8MemoryClock));
-		rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->usFSBClock));
-		rdev->pm.igp_ht_link_width.full = rfixed_const(info->ucHTLinkWidth);
-		break;
-	case 2:
-		tmp.full = rfixed_const(100);
-		rdev->pm.igp_sideport_mclk.full = rfixed_const(info_v2->ulBootUpSidePortClock);
-		rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
-		rdev->pm.igp_system_mclk.full = rfixed_const(info_v2->ulBootUpUMAClock);
-		rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
-		rdev->pm.igp_ht_link_clk.full = rfixed_const(info_v2->ulHTLinkFreq);
-		rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp);
-		rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info_v2->usMinHTLinkWidth));
-		break;
-	default:
+	if (atom_parse_data_header(rdev->mode_info.atom_context, index, NULL,
+				   &frev, &crev, &data_offset)) {
+		info = (union igp_info *)(rdev->mode_info.atom_context->bios + data_offset);
+
+		/* Get various system informations from bios */
+		switch (crev) {
+		case 1:
+			tmp.full = rfixed_const(100);
+			rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info.ulBootUpMemoryClock);
+			rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
+			rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->info.usK8MemoryClock));
+			rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->info.usFSBClock));
+			rdev->pm.igp_ht_link_width.full = rfixed_const(info->info.ucHTLinkWidth);
+			break;
+		case 2:
+			tmp.full = rfixed_const(100);
+			rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info_v2.ulBootUpSidePortClock);
+			rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
+			rdev->pm.igp_system_mclk.full = rfixed_const(info->info_v2.ulBootUpUMAClock);
+			rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
+			rdev->pm.igp_ht_link_clk.full = rfixed_const(info->info_v2.ulHTLinkFreq);
+			rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp);
+			rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth));
+			break;
+		default:
+			tmp.full = rfixed_const(100);
+			/* We assume the slower possible clock ie worst case */
+			/* DDR 333Mhz */
+			rdev->pm.igp_sideport_mclk.full = rfixed_const(333);
+			/* FIXME: system clock ? */
+			rdev->pm.igp_system_mclk.full = rfixed_const(100);
+			rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
+			rdev->pm.igp_ht_link_clk.full = rfixed_const(200);
+			rdev->pm.igp_ht_link_width.full = rfixed_const(8);
+			DRM_ERROR("No integrated system info for your GPU, using safe default\n");
+			break;
+		}
+	} else {
 		tmp.full = rfixed_const(100);
 		/* We assume the slower possible clock ie worst case */
 		/* DDR 333Mhz */
@@ -103,7 +119,6 @@ void rs690_pm_info(struct radeon_device
 		rdev->pm.igp_ht_link_clk.full = rfixed_const(200);
 		rdev->pm.igp_ht_link_width.full = rfixed_const(8);
 		DRM_ERROR("No integrated system info for your GPU, using safe default\n");
-		break;
 	}
 	/* Compute various bandwidth */
 	/* k8_bandwidth = (memory_clk / 2) * 2 * 8 * 0.5 = memory_clk * 4  */
@@ -129,53 +144,25 @@ void rs690_pm_info(struct radeon_device
 	rdev->pm.sideport_bandwidth.full = rfixed_div(rdev->pm.sideport_bandwidth, tmp);
 }
 
-void rs690_vram_info(struct radeon_device *rdev)
+void rs690_mc_init(struct radeon_device *rdev)
 {
-	fixed20_12 a;
+	u64 base;
 
 	rs400_gart_adjust_size(rdev);
-
 	rdev->mc.vram_is_ddr = true;
 	rdev->mc.vram_width = 128;
-
 	rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
 	rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
-
 	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
 	rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
-
-	if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
-		rdev->mc.mc_vram_size = rdev->mc.aper_size;
-
-	if (rdev->mc.real_vram_size > rdev->mc.aper_size)
-		rdev->mc.real_vram_size = rdev->mc.aper_size;
-
+	rdev->mc.visible_vram_size = rdev->mc.aper_size;
+	base = RREG32_MC(R_000100_MCCFG_FB_LOCATION);
+	base = G_000100_MC_FB_START(base) << 16;
 	rs690_pm_info(rdev);
-	/* FIXME: we should enforce default clock in case GPU is not in
-	 * default setup
-	 */
-	a.full = rfixed_const(100);
-	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
-	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
-	a.full = rfixed_const(16);
-	/* core_bandwidth = sclk(Mhz) * 16 */
-	rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a);
-}
-
-static int rs690_mc_init(struct radeon_device *rdev)
-{
-	int r;
-	u32 tmp;
-
-	/* Setup GPU memory space */
-	tmp = RREG32_MC(R_000100_MCCFG_FB_LOCATION);
-	rdev->mc.vram_location = G_000100_MC_FB_START(tmp) << 16;
-	rdev->mc.gtt_location = 0xFFFFFFFFUL;
-	r = radeon_mc_setup(rdev);
 	rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
-	if (r)
-		return r;
-	return 0;
+	radeon_vram_location(rdev, &rdev->mc, base);
+	radeon_gtt_location(rdev, &rdev->mc);
+	radeon_update_bandwidth_info(rdev);
 }
 
 void rs690_line_buffer_adjust(struct radeon_device *rdev,
@@ -413,10 +400,12 @@ void rs690_bandwidth_update(struct radeo
 	struct drm_display_mode *mode1 = NULL;
 	struct rs690_watermark wm0;
 	struct rs690_watermark wm1;
-	u32 tmp;
+	u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt;
 	fixed20_12 priority_mark02, priority_mark12, fill_rate;
 	fixed20_12 a, b;
 
+	radeon_update_display_priority(rdev);
+
 	if (rdev->mode_info.crtcs[0]->base.enabled)
 		mode0 = &rdev->mode_info.crtcs[0]->base.mode;
 	if (rdev->mode_info.crtcs[1]->base.enabled)
@@ -426,7 +415,8 @@ void rs690_bandwidth_update(struct radeo
 	 * modes if the user specifies HIGH for displaypriority
 	 * option.
 	 */
-	if (rdev->disp_priority == 2) {
+	if ((rdev->disp_priority == 2) &&
+	    ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740))) {
 		tmp = RREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER);
 		tmp &= C_000104_MC_DISP0R_INIT_LAT;
 		tmp &= C_000104_MC_DISP1R_INIT_LAT;
@@ -501,10 +491,16 @@ void rs690_bandwidth_update(struct radeo
 			priority_mark12.full = 0;
 		if (wm1.priority_mark_max.full > priority_mark12.full)
 			priority_mark12.full = wm1.priority_mark_max.full;
-		WREG32(R_006548_D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
-		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
-		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
-		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
+		d1mode_priority_a_cnt = rfixed_trunc(priority_mark02);
+		d2mode_priority_a_cnt = rfixed_trunc(priority_mark12);
+		if (rdev->disp_priority == 2) {
+			d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
+			d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
+		}
+		WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
+		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
 	} else if (mode0) {
 		if (rfixed_trunc(wm0.dbpp) > 64)
 			a.full = rfixed_mul(wm0.dbpp, wm0.num_line_pair);
@@ -531,8 +527,11 @@ void rs690_bandwidth_update(struct radeo
 			priority_mark02.full = 0;
 		if (wm0.priority_mark_max.full > priority_mark02.full)
 			priority_mark02.full = wm0.priority_mark_max.full;
-		WREG32(R_006548_D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
-		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
+		d1mode_priority_a_cnt = rfixed_trunc(priority_mark02);
+		if (rdev->disp_priority == 2)
+			d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
+		WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
 		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT,
 			S_006D48_D2MODE_PRIORITY_A_OFF(1));
 		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT,
@@ -563,12 +562,15 @@ void rs690_bandwidth_update(struct radeo
 			priority_mark12.full = 0;
 		if (wm1.priority_mark_max.full > priority_mark12.full)
 			priority_mark12.full = wm1.priority_mark_max.full;
+		d2mode_priority_a_cnt = rfixed_trunc(priority_mark12);
+		if (rdev->disp_priority == 2)
+			d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
 		WREG32(R_006548_D1MODE_PRIORITY_A_CNT,
 			S_006548_D1MODE_PRIORITY_A_OFF(1));
 		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT,
 			S_00654C_D1MODE_PRIORITY_B_OFF(1));
-		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
-		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
+		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
 	}
 }
 
@@ -676,6 +678,7 @@ int rs690_suspend(struct radeon_device *
 
 void rs690_fini(struct radeon_device *rdev)
 {
+	radeon_pm_fini(rdev);
 	r100_cp_fini(rdev);
 	r100_wb_fini(rdev);
 	r100_ib_fini(rdev);
@@ -728,12 +731,8 @@ int rs690_init(struct radeon_device *rde
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
 	radeon_pm_init(rdev);
-	/* Get vram informations */
-	rs690_vram_info(rdev);
-	/* Initialize memory controller (also test AGP) */
-	r = rs690_mc_init(rdev);
-	if (r)
-		return r;
+	/* initialize memory controller */
+	rs690_mc_init(rdev);
 	rv515_debugfs(rdev);
 	/* Fence driver */
 	r = radeon_fence_driver_init(rdev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs690d.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rs690d.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs690d.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rs690d.h	2010-05-16 17:17:36.000000000 -0400
@@ -182,6 +182,9 @@
 #define   S_006548_D1MODE_PRIORITY_A_OFF(x)            (((x) & 0x1) << 16)
 #define   G_006548_D1MODE_PRIORITY_A_OFF(x)            (((x) >> 16) & 0x1)
 #define   C_006548_D1MODE_PRIORITY_A_OFF               0xFFFEFFFF
+#define   S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) & 0x1) << 20)
+#define   G_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) >> 20) & 0x1)
+#define   C_006548_D1MODE_PRIORITY_A_ALWAYS_ON         0xFFEFFFFF
 #define   S_006548_D1MODE_PRIORITY_A_FORCE_MASK(x)     (((x) & 0x1) << 24)
 #define   G_006548_D1MODE_PRIORITY_A_FORCE_MASK(x)     (((x) >> 24) & 0x1)
 #define   C_006548_D1MODE_PRIORITY_A_FORCE_MASK        0xFEFFFFFF
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rv515.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rv515.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rv515.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rv515.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,9 +26,11 @@
  *          Jerome Glisse
  */
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "rv515d.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "atom.h"
 #include "rv515_reg_safe.h"
 
@@ -277,19 +279,15 @@ static void rv515_vram_get_type(struct r
 	}
 }
 
-void rv515_vram_info(struct radeon_device *rdev)
+void rv515_mc_init(struct radeon_device *rdev)
 {
-	fixed20_12 a;
 
 	rv515_vram_get_type(rdev);
-
 	r100_vram_init_sizes(rdev);
-	/* FIXME: we should enforce default clock in case GPU is not in
-	 * default setup
-	 */
-	a.full = rfixed_const(100);
-	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
-	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+	radeon_vram_location(rdev, &rdev->mc, 0);
+	if (!(rdev->flags & RADEON_IS_AGP))
+		radeon_gtt_location(rdev, &rdev->mc);
+	radeon_update_bandwidth_info(rdev);
 }
 
 uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg)
@@ -537,6 +535,7 @@ void rv515_set_safe_registers(struct rad
 
 void rv515_fini(struct radeon_device *rdev)
 {
+	radeon_pm_fini(rdev);
 	r100_cp_fini(rdev);
 	r100_wb_fini(rdev);
 	r100_ib_fini(rdev);
@@ -587,12 +586,15 @@ int rv515_init(struct radeon_device *rde
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
 	radeon_pm_init(rdev);
-	/* Get vram informations */
-	rv515_vram_info(rdev);
-	/* Initialize memory controller (also test AGP) */
-	r = r420_mc_init(rdev);
-	if (r)
-		return r;
+	/* initialize AGP */
+	if (rdev->flags & RADEON_IS_AGP) {
+		r = radeon_agp_init(rdev);
+		if (r) {
+			radeon_agp_disable(rdev);
+		}
+	}
+	/* initialize memory controller */
+	rv515_mc_init(rdev);
 	rv515_debugfs(rdev);
 	/* Fence driver */
 	r = radeon_fence_driver_init(rdev);
@@ -1015,7 +1017,7 @@ void rv515_bandwidth_avivo_update(struct
 	struct drm_display_mode *mode1 = NULL;
 	struct rv515_watermark wm0;
 	struct rv515_watermark wm1;
-	u32 tmp;
+	u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt;
 	fixed20_12 priority_mark02, priority_mark12, fill_rate;
 	fixed20_12 a, b;
 
@@ -1083,10 +1085,16 @@ void rv515_bandwidth_avivo_update(struct
 			priority_mark12.full = 0;
 		if (wm1.priority_mark_max.full > priority_mark12.full)
 			priority_mark12.full = wm1.priority_mark_max.full;
-		WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
-		WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
-		WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
-		WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
+		d1mode_priority_a_cnt = rfixed_trunc(priority_mark02);
+		d2mode_priority_a_cnt = rfixed_trunc(priority_mark12);
+		if (rdev->disp_priority == 2) {
+			d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
+			d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
+		}
+		WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+		WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
+		WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+		WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
 	} else if (mode0) {
 		if (rfixed_trunc(wm0.dbpp) > 64)
 			a.full = rfixed_div(wm0.dbpp, wm0.num_line_pair);
@@ -1113,8 +1121,11 @@ void rv515_bandwidth_avivo_update(struct
 			priority_mark02.full = 0;
 		if (wm0.priority_mark_max.full > priority_mark02.full)
 			priority_mark02.full = wm0.priority_mark_max.full;
-		WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
-		WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
+		d1mode_priority_a_cnt = rfixed_trunc(priority_mark02);
+		if (rdev->disp_priority == 2)
+			d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
+		WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+		WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
 		WREG32(D2MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
 		WREG32(D2MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
 	} else {
@@ -1143,10 +1154,13 @@ void rv515_bandwidth_avivo_update(struct
 			priority_mark12.full = 0;
 		if (wm1.priority_mark_max.full > priority_mark12.full)
 			priority_mark12.full = wm1.priority_mark_max.full;
+		d2mode_priority_a_cnt = rfixed_trunc(priority_mark12);
+		if (rdev->disp_priority == 2)
+			d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
 		WREG32(D1MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
 		WREG32(D1MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
-		WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
-		WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
+		WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+		WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
 	}
 }
 
@@ -1156,6 +1170,8 @@ void rv515_bandwidth_update(struct radeo
 	struct drm_display_mode *mode0 = NULL;
 	struct drm_display_mode *mode1 = NULL;
 
+	radeon_update_display_priority(rdev);
+
 	if (rdev->mode_info.crtcs[0]->base.enabled)
 		mode0 = &rdev->mode_info.crtcs[0]->base.mode;
 	if (rdev->mode_info.crtcs[1]->base.enabled)
@@ -1165,7 +1181,8 @@ void rv515_bandwidth_update(struct radeo
 	 * modes if the user specifies HIGH for displaypriority
 	 * option.
 	 */
-	if (rdev->disp_priority == 2) {
+	if ((rdev->disp_priority == 2) &&
+	    (rdev->family == CHIP_RV515)) {
 		tmp = RREG32_MC(MC_MISC_LAT_TIMER);
 		tmp &= ~MC_DISP1R_INIT_LAT_MASK;
 		tmp &= ~MC_DISP0R_INIT_LAT_MASK;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rv770.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rv770.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rv770.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rv770.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,8 +27,10 @@
  */
 #include <linux/firmware.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "radeon_drm.h"
 #include "rv770d.h"
 #include "atom.h"
@@ -56,6 +58,7 @@ int rv770_pcie_gart_enable(struct radeon
 	r = radeon_gart_table_vram_pin(rdev);
 	if (r)
 		return r;
+	radeon_gart_restore(rdev);
 	/* Setup L2 cache */
 	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
 				ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
@@ -124,9 +127,9 @@ void rv770_pcie_gart_disable(struct rade
 
 void rv770_pcie_gart_fini(struct radeon_device *rdev)
 {
+	radeon_gart_fini(rdev);
 	rv770_pcie_gart_disable(rdev);
 	radeon_gart_table_vram_free(rdev);
-	radeon_gart_fini(rdev);
 }
 
 
@@ -273,9 +276,10 @@ static int rv770_cp_load_microcode(struc
 /*
  * Core functions
  */
-static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
-						u32 num_backends,
-						u32 backend_disable_mask)
+static u32 r700_get_tile_pipe_to_backend_map(struct radeon_device *rdev,
+					     u32 num_tile_pipes,
+					     u32 num_backends,
+					     u32 backend_disable_mask)
 {
 	u32 backend_map = 0;
 	u32 enabled_backends_mask;
@@ -284,6 +288,7 @@ static u32 r700_get_tile_pipe_to_backend
 	u32 swizzle_pipe[R7XX_MAX_PIPES];
 	u32 cur_backend;
 	u32 i;
+	bool force_no_swizzle;
 
 	if (num_tile_pipes > R7XX_MAX_PIPES)
 		num_tile_pipes = R7XX_MAX_PIPES;
@@ -313,6 +318,18 @@ static u32 r700_get_tile_pipe_to_backend
 	if (enabled_backends_count != num_backends)
 		num_backends = enabled_backends_count;
 
+	switch (rdev->family) {
+	case CHIP_RV770:
+	case CHIP_RV730:
+		force_no_swizzle = false;
+		break;
+	case CHIP_RV710:
+	case CHIP_RV740:
+	default:
+		force_no_swizzle = true;
+		break;
+	}
+
 	memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES);
 	switch (num_tile_pipes) {
 	case 1:
@@ -323,49 +340,100 @@ static u32 r700_get_tile_pipe_to_backend
 		swizzle_pipe[1] = 1;
 		break;
 	case 3:
-		swizzle_pipe[0] = 0;
-		swizzle_pipe[1] = 2;
-		swizzle_pipe[2] = 1;
+		if (force_no_swizzle) {
+			swizzle_pipe[0] = 0;
+			swizzle_pipe[1] = 1;
+			swizzle_pipe[2] = 2;
+		} else {
+			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;
+		if (force_no_swizzle) {
+			swizzle_pipe[0] = 0;
+			swizzle_pipe[1] = 1;
+			swizzle_pipe[2] = 2;
+			swizzle_pipe[3] = 3;
+		} else {
+			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;
+		if (force_no_swizzle) {
+			swizzle_pipe[0] = 0;
+			swizzle_pipe[1] = 1;
+			swizzle_pipe[2] = 2;
+			swizzle_pipe[3] = 3;
+			swizzle_pipe[4] = 4;
+		} else {
+			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;
+		if (force_no_swizzle) {
+			swizzle_pipe[0] = 0;
+			swizzle_pipe[1] = 1;
+			swizzle_pipe[2] = 2;
+			swizzle_pipe[3] = 3;
+			swizzle_pipe[4] = 4;
+			swizzle_pipe[5] = 5;
+		} else {
+			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;
+		if (force_no_swizzle) {
+			swizzle_pipe[0] = 0;
+			swizzle_pipe[1] = 1;
+			swizzle_pipe[2] = 2;
+			swizzle_pipe[3] = 3;
+			swizzle_pipe[4] = 4;
+			swizzle_pipe[5] = 5;
+			swizzle_pipe[6] = 6;
+		} else {
+			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;
+		if (force_no_swizzle) {
+			swizzle_pipe[0] = 0;
+			swizzle_pipe[1] = 1;
+			swizzle_pipe[2] = 2;
+			swizzle_pipe[3] = 3;
+			swizzle_pipe[4] = 4;
+			swizzle_pipe[5] = 5;
+			swizzle_pipe[6] = 6;
+			swizzle_pipe[7] = 7;
+		} else {
+			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;
 	}
 
@@ -385,8 +453,10 @@ static u32 r700_get_tile_pipe_to_backend
 static void rv770_gpu_init(struct radeon_device *rdev)
 {
 	int i, j, num_qd_pipes;
+	u32 ta_aux_cntl;
 	u32 sx_debug_1;
 	u32 smx_dc_ctl0;
+	u32 db_debug3;
 	u32 num_gs_verts_per_thread;
 	u32 vgt_gs_per_es;
 	u32 gs_prim_buffer_depth = 0;
@@ -515,6 +585,7 @@ static void rv770_gpu_init(struct radeon
 
 	switch (rdev->config.rv770.max_tile_pipes) {
 	case 1:
+	default:
 		gb_tiling_config |= PIPE_TILING(0);
 		break;
 	case 2:
@@ -526,16 +597,17 @@ static void rv770_gpu_init(struct radeon
 	case 8:
 		gb_tiling_config |= PIPE_TILING(3);
 		break;
-	default:
-		break;
 	}
+	rdev->config.rv770.tiling_npipes = rdev->config.rv770.max_tile_pipes;
 
 	if (rdev->family == CHIP_RV770)
 		gb_tiling_config |= BANK_TILING(1);
 	else
 		gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT);
+	rdev->config.rv770.tiling_nbanks = 4 << ((gb_tiling_config >> 4) & 0x3);
 
 	gb_tiling_config |= GROUP_SIZE(0);
+	rdev->config.rv770.tiling_group_size = 256;
 
 	if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) {
 		gb_tiling_config |= ROW_TILING(3);
@@ -549,21 +621,27 @@ static void rv770_gpu_init(struct radeon
 
 	gb_tiling_config |= BANK_SWAPS(1);
 
-	if (rdev->family == CHIP_RV740)
-		backend_map = 0x28;
-	else
-		backend_map = r700_get_tile_pipe_to_backend_map(rdev->config.rv770.max_tile_pipes,
-								rdev->config.rv770.max_backends,
-								(0xff << rdev->config.rv770.max_backends) & 0xff);
-	gb_tiling_config |= BACKEND_MAP(backend_map);
+	cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000;
+	cc_rb_backend_disable |=
+		BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << rdev->config.rv770.max_backends) & R7XX_MAX_BACKENDS_MASK);
 
-	cc_gc_shader_pipe_config =
+	cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00;
+	cc_gc_shader_pipe_config |=
 		INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << rdev->config.rv770.max_pipes) & R7XX_MAX_PIPES_MASK);
 	cc_gc_shader_pipe_config |=
 		INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << rdev->config.rv770.max_simds) & R7XX_MAX_SIMDS_MASK);
 
-	cc_rb_backend_disable =
-		BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << rdev->config.rv770.max_backends) & R7XX_MAX_BACKENDS_MASK);
+	if (rdev->family == CHIP_RV740)
+		backend_map = 0x28;
+	else
+		backend_map = r700_get_tile_pipe_to_backend_map(rdev,
+								rdev->config.rv770.max_tile_pipes,
+								(R7XX_MAX_BACKENDS -
+								 r600_count_pipe_bits((cc_rb_backend_disable &
+										       R7XX_MAX_BACKENDS_MASK) >> 16)),
+								(cc_rb_backend_disable >> 16));
+	gb_tiling_config |= BACKEND_MAP(backend_map);
+
 
 	WREG32(GB_TILING_CONFIG, gb_tiling_config);
 	WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
@@ -572,15 +650,15 @@ static void rv770_gpu_init(struct radeon
 	WREG32(CC_RB_BACKEND_DISABLE,      cc_rb_backend_disable);
 	WREG32(CC_GC_SHADER_PIPE_CONFIG,   cc_gc_shader_pipe_config);
 	WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+	WREG32(CC_SYS_RB_BACKEND_DISABLE,  cc_rb_backend_disable);
 
-	WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable);
 	WREG32(CGTS_SYS_TCC_DISABLE, 0);
 	WREG32(CGTS_TCC_DISABLE, 0);
 	WREG32(CGTS_USER_SYS_TCC_DISABLE, 0);
 	WREG32(CGTS_USER_TCC_DISABLE, 0);
 
 	num_qd_pipes =
-		R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK);
+		R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8);
 	WREG32(VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & DEALLOC_DIST_MASK);
 	WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & VTX_REUSE_DEPTH_MASK);
 
@@ -590,10 +668,8 @@ static void rv770_gpu_init(struct radeon
 
 	WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30));
 
-	WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO |
-			     SYNC_GRADIENT |
-			     SYNC_WALKER |
-			     SYNC_ALIGNER));
+	ta_aux_cntl = RREG32(TA_CNTL_AUX);
+	WREG32(TA_CNTL_AUX, ta_aux_cntl | DISABLE_CUBE_ANISO);
 
 	sx_debug_1 = RREG32(SX_DEBUG_1);
 	sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
@@ -604,14 +680,28 @@ static void rv770_gpu_init(struct radeon
 	smx_dc_ctl0 |= CACHE_DEPTH((rdev->config.rv770.sx_num_of_sets * 64) - 1);
 	WREG32(SMX_DC_CTL0, smx_dc_ctl0);
 
-	WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) |
-			       GS_FLUSH_CTL(4) |
-			       ACK_FLUSH_CTL(3) |
-			       SYNC_FLUSH_CTL));
+	if (rdev->family != CHIP_RV740)
+		WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) |
+				       GS_FLUSH_CTL(4) |
+				       ACK_FLUSH_CTL(3) |
+				       SYNC_FLUSH_CTL));
 
-	if (rdev->family == CHIP_RV770)
-		WREG32(DB_DEBUG3, DB_CLK_OFF_DELAY(0x1f));
-	else {
+	db_debug3 = RREG32(DB_DEBUG3);
+	db_debug3 &= ~DB_CLK_OFF_DELAY(0x1f);
+	switch (rdev->family) {
+	case CHIP_RV770:
+	case CHIP_RV740:
+		db_debug3 |= DB_CLK_OFF_DELAY(0x1f);
+		break;
+	case CHIP_RV710:
+	case CHIP_RV730:
+	default:
+		db_debug3 |= DB_CLK_OFF_DELAY(2);
+		break;
+	}
+	WREG32(DB_DEBUG3, db_debug3);
+
+	if (rdev->family != CHIP_RV770) {
 		db_debug4 = RREG32(DB_DEBUG4);
 		db_debug4 |= DISABLE_TILE_COVERED_FOR_PS_ITER;
 		WREG32(DB_DEBUG4, db_debug4);
@@ -640,10 +730,10 @@ static void rv770_gpu_init(struct radeon
 			    ALU_UPDATE_FIFO_HIWATER(0x8));
 	switch (rdev->family) {
 	case CHIP_RV770:
-		sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x1);
-		break;
 	case CHIP_RV730:
 	case CHIP_RV710:
+		sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x1);
+		break;
 	case CHIP_RV740:
 	default:
 		sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x4);
@@ -779,7 +869,6 @@ static void rv770_gpu_init(struct radeon
 
 int rv770_mc_init(struct radeon_device *rdev)
 {
-	fixed20_12 a;
 	u32 tmp;
 	int chansize, numchan;
 
@@ -816,53 +905,18 @@ int rv770_mc_init(struct radeon_device *
 	/* Setup GPU memory space */
 	rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
 	rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
-
-	if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
+	rdev->mc.visible_vram_size = rdev->mc.aper_size;
+	/* FIXME remove this once we support unmappable VRAM */
+	if (rdev->mc.mc_vram_size > rdev->mc.aper_size) {
 		rdev->mc.mc_vram_size = rdev->mc.aper_size;
-
-	if (rdev->mc.real_vram_size > rdev->mc.aper_size)
 		rdev->mc.real_vram_size = rdev->mc.aper_size;
-
-	if (rdev->flags & RADEON_IS_AGP) {
-		/* gtt_size is setup by radeon_agp_init */
-		rdev->mc.gtt_location = rdev->mc.agp_base;
-		tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size;
-		/* Try to put vram before or after AGP because we
-		 * we want SYSTEM_APERTURE to cover both VRAM and
-		 * AGP so that GPU can catch out of VRAM/AGP access
-		 */
-		if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) {
-			/* Enough place before */
-			rdev->mc.vram_location = rdev->mc.gtt_location -
-							rdev->mc.mc_vram_size;
-		} else if (tmp > rdev->mc.mc_vram_size) {
-			/* Enough place after */
-			rdev->mc.vram_location = rdev->mc.gtt_location +
-							rdev->mc.gtt_size;
-		} else {
-			/* Try to setup VRAM then AGP might not
-			 * not work on some card
-			 */
-			rdev->mc.vram_location = 0x00000000UL;
-			rdev->mc.gtt_location = rdev->mc.mc_vram_size;
-		}
-	} else {
-		rdev->mc.vram_location = 0x00000000UL;
-		rdev->mc.gtt_location = rdev->mc.mc_vram_size;
-		rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
 	}
-	rdev->mc.vram_start = rdev->mc.vram_location;
-	rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
-	rdev->mc.gtt_start = rdev->mc.gtt_location;
-	rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
-	/* FIXME: we should enforce default clock in case GPU is not in
-	 * default setup
-	 */
-	a.full = rfixed_const(100);
-	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
-	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+	r600_vram_gtt_location(rdev, &rdev->mc);
+	radeon_update_bandwidth_info(rdev);
+
 	return 0;
 }
+
 int rv770_gpu_reset(struct radeon_device *rdev)
 {
 	/* FIXME: implement any rv770 specific bits */
@@ -959,6 +1013,13 @@ int rv770_resume(struct radeon_device *r
 		DRM_ERROR("radeon: failled testing IB (%d).\n", r);
 		return r;
 	}
+
+	r = r600_audio_init(rdev);
+	if (r) {
+		dev_err(rdev->dev, "radeon: audio init failed\n");
+		return r;
+	}
+
 	return r;
 
 }
@@ -967,6 +1028,7 @@ int rv770_suspend(struct radeon_device *
 {
 	int r;
 
+	r600_audio_fini(rdev);
 	/* FIXME: we should wait for ring to be empty */
 	r700_cp_stop(rdev);
 	rdev->cp.ready = false;
@@ -1038,6 +1100,7 @@ int rv770_init(struct radeon_device *rde
 	r = radeon_fence_driver_init(rdev);
 	if (r)
 		return r;
+	/* initialize AGP */
 	if (rdev->flags & RADEON_IS_AGP) {
 		r = radeon_agp_init(rdev);
 		if (r)
@@ -1089,11 +1152,19 @@ int rv770_init(struct radeon_device *rde
 			}
 		}
 	}
+
+	r = r600_audio_init(rdev);
+	if (r) {
+		dev_err(rdev->dev, "radeon: audio init failed\n");
+		return r;
+	}
+
 	return 0;
 }
 
 void rv770_fini(struct radeon_device *rdev)
 {
+	radeon_pm_fini(rdev);
 	r600_blit_fini(rdev);
 	r600_cp_fini(rdev);
 	r600_wb_fini(rdev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rv770d.h linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rv770d.h
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rv770d.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/radeon/rv770d.h	2010-05-16 17:17:36.000000000 -0400
@@ -343,4 +343,6 @@
 
 #define	WAIT_UNTIL					0x8040
 
+#define	SRBM_STATUS				        0x0E50
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_agp_backend.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/ttm/ttm_agp_backend.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_agp_backend.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/ttm/ttm_agp_backend.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include "ttm/ttm_placement.h"
 #include <linux/agp_backend.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 #include <asm/agp.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_bo.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/ttm/ttm_bo.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_bo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/ttm/ttm_bo.c	2010-05-16 17:17:36.000000000 -0400
@@ -128,7 +128,7 @@ static struct attribute *ttm_bo_global_a
 	NULL
 };
 
-static struct sysfs_ops ttm_bo_global_ops = {
+static const struct sysfs_ops ttm_bo_global_ops = {
 	.show = &ttm_bo_global_show
 };
 
@@ -1425,8 +1425,8 @@ int ttm_bo_global_init(struct ttm_global
 
 	atomic_set(&glob->bo_count, 0);
 
-	kobject_init(&glob->kobj, &ttm_bo_glob_kobj_type);
-	ret = kobject_add(&glob->kobj, ttm_get_kobj(), "buffer_objects");
+	ret = kobject_init_and_add(
+		&glob->kobj, &ttm_bo_glob_kobj_type, ttm_get_kobj(), "buffer_objects");
 	if (unlikely(ret != 0))
 		kobject_put(&glob->kobj);
 	return ret;
@@ -1716,40 +1716,12 @@ int ttm_bo_wait(struct ttm_buffer_object
 }
 EXPORT_SYMBOL(ttm_bo_wait);
 
-void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo)
-{
-	atomic_set(&bo->reserved, 0);
-	wake_up_all(&bo->event_queue);
-}
-
-int ttm_bo_block_reservation(struct ttm_buffer_object *bo, bool interruptible,
-			     bool no_wait)
-{
-	int ret;
-
-	while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) {
-		if (no_wait)
-			return -EBUSY;
-		else if (interruptible) {
-			ret = wait_event_interruptible
-			    (bo->event_queue, atomic_read(&bo->reserved) == 0);
-			if (unlikely(ret != 0))
-				return ret;
-		} else {
-			wait_event(bo->event_queue,
-				   atomic_read(&bo->reserved) == 0);
-		}
-	}
-	return 0;
-}
-
 int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait)
 {
 	int ret = 0;
 
 	/*
-	 * Using ttm_bo_reserve instead of ttm_bo_block_reservation
-	 * makes sure the lru lists are updated.
+	 * Using ttm_bo_reserve makes sure the lru lists are updated.
 	 */
 
 	ret = ttm_bo_reserve(bo, true, no_wait, false, 0);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_bo_util.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/ttm/ttm_bo_util.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_bo_util.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/ttm/ttm_bo_util.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/io.h>
 #include <linux/highmem.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/module.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_lock.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/ttm/ttm_lock.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_lock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/ttm/ttm_lock.c	2010-05-16 17:17:36.000000000 -0400
@@ -204,7 +204,6 @@ static int __ttm_vt_unlock(struct ttm_lo
 	lock->flags &= ~TTM_VT_LOCK;
 	wake_up_all(&lock->queue);
 	spin_unlock(&lock->lock);
-	printk(KERN_INFO TTM_PFX "vt unlock.\n");
 
 	return ret;
 }
@@ -265,10 +264,8 @@ int ttm_vt_lock(struct ttm_lock *lock,
 				   ttm_lock_type, &ttm_vt_lock_remove, NULL);
 	if (ret)
 		(void)__ttm_vt_unlock(lock);
-	else {
+	else
 		lock->vt_holder = tfile;
-		printk(KERN_INFO TTM_PFX "vt lock.\n");
-	}
 
 	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_memory.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/ttm/ttm_memory.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_memory.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/ttm/ttm_memory.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/wait.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #define TTM_MEMORY_ALLOC_RETRIES 4
 
@@ -152,7 +153,7 @@ static struct attribute *ttm_mem_zone_at
 	NULL
 };
 
-static struct sysfs_ops ttm_mem_zone_ops = {
+static const struct sysfs_ops ttm_mem_zone_ops = {
 	.show = &ttm_mem_zone_show,
 	.store = &ttm_mem_zone_store
 };
@@ -260,8 +261,8 @@ static int ttm_mem_init_kernel_zone(stru
 	zone->used_mem = 0;
 	zone->glob = glob;
 	glob->zone_kernel = zone;
-	kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type);
-	ret = kobject_add(&zone->kobj, &glob->kobj, zone->name);
+	ret = kobject_init_and_add(
+		&zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name);
 	if (unlikely(ret != 0)) {
 		kobject_put(&zone->kobj);
 		return ret;
@@ -296,8 +297,8 @@ static int ttm_mem_init_highmem_zone(str
 	zone->used_mem = 0;
 	zone->glob = glob;
 	glob->zone_highmem = zone;
-	kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type);
-	ret = kobject_add(&zone->kobj, &glob->kobj, zone->name);
+	ret = kobject_init_and_add(
+		&zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name);
 	if (unlikely(ret != 0)) {
 		kobject_put(&zone->kobj);
 		return ret;
@@ -343,8 +344,8 @@ static int ttm_mem_init_dma32_zone(struc
 	zone->used_mem = 0;
 	zone->glob = glob;
 	glob->zone_dma32 = zone;
-	kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type);
-	ret = kobject_add(&zone->kobj, &glob->kobj, zone->name);
+	ret = kobject_init_and_add(
+		&zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name);
 	if (unlikely(ret != 0)) {
 		kobject_put(&zone->kobj);
 		return ret;
@@ -365,10 +366,8 @@ int ttm_mem_global_init(struct ttm_mem_g
 	glob->swap_queue = create_singlethread_workqueue("ttm_swap");
 	INIT_WORK(&glob->work, ttm_shrink_work);
 	init_waitqueue_head(&glob->queue);
-	kobject_init(&glob->kobj, &ttm_mem_glob_kobj_type);
-	ret = kobject_add(&glob->kobj,
-			  ttm_get_kobj(),
-			  "memory_accounting");
+	ret = kobject_init_and_add(
+		&glob->kobj, &ttm_mem_glob_kobj_type, ttm_get_kobj(), "memory_accounting");
 	if (unlikely(ret != 0)) {
 		kobject_put(&glob->kobj);
 		return ret;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_tt.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/ttm/ttm_tt.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_tt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/ttm/ttm_tt.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,13 +28,14 @@
  * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
  */
 
-#include <linux/vmalloc.h>
 #include <linux/sched.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/file.h>
 #include <linux/swap.h>
+#include <linux/slab.h>
 #include "drm_cache.h"
+#include "drm_mem_util.h"
 #include "ttm/ttm_module.h"
 #include "ttm/ttm_bo_driver.h"
 #include "ttm/ttm_placement.h"
@@ -43,32 +44,15 @@ static int ttm_tt_swapin(struct ttm_tt *
 
 /**
  * Allocates storage for pointers to the pages that back the ttm.
- *
- * Uses kmalloc if possible. Otherwise falls back to vmalloc.
  */
 static void ttm_tt_alloc_page_directory(struct ttm_tt *ttm)
 {
-	unsigned long size = ttm->num_pages * sizeof(*ttm->pages);
-	ttm->pages = NULL;
-
-	if (size <= PAGE_SIZE)
-		ttm->pages = kzalloc(size, GFP_KERNEL);
-
-	if (!ttm->pages) {
-		ttm->pages = vmalloc_user(size);
-		if (ttm->pages)
-			ttm->page_flags |= TTM_PAGE_FLAG_VMALLOC;
-	}
+	ttm->pages = drm_calloc_large(ttm->num_pages, sizeof(*ttm->pages));
 }
 
 static void ttm_tt_free_page_directory(struct ttm_tt *ttm)
 {
-	if (ttm->page_flags & TTM_PAGE_FLAG_VMALLOC) {
-		vfree(ttm->pages);
-		ttm->page_flags &= ~TTM_PAGE_FLAG_VMALLOC;
-	} else {
-		kfree(ttm->pages);
-	}
+	drm_free_large(ttm->pages);
 	ttm->pages = NULL;
 }
 
@@ -480,7 +464,7 @@ static int ttm_tt_swapin(struct ttm_tt *
 	void *from_virtual;
 	void *to_virtual;
 	int i;
-	int ret;
+	int ret = -ENOMEM;
 
 	if (ttm->page_flags & TTM_PAGE_FLAG_USER) {
 		ret = ttm_tt_set_user(ttm, ttm->tsk, ttm->start,
@@ -499,8 +483,10 @@ static int ttm_tt_swapin(struct ttm_tt *
 
 	for (i = 0; i < ttm->num_pages; ++i) {
 		from_page = read_mapping_page(swap_space, i, NULL);
-		if (IS_ERR(from_page))
+		if (IS_ERR(from_page)) {
+			ret = PTR_ERR(from_page);
 			goto out_err;
+		}
 		to_page = __ttm_tt_get_page(ttm, i);
 		if (unlikely(to_page == NULL))
 			goto out_err;
@@ -523,7 +509,7 @@ static int ttm_tt_swapin(struct ttm_tt *
 	return 0;
 out_err:
 	ttm_tt_free_alloced_pages(ttm);
-	return -ENOMEM;
+	return ret;
 }
 
 int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage)
@@ -535,6 +521,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, s
 	void *from_virtual;
 	void *to_virtual;
 	int i;
+	int ret = -ENOMEM;
 
 	BUG_ON(ttm->state != tt_unbound && ttm->state != tt_unpopulated);
 	BUG_ON(ttm->caching_state != tt_cached);
@@ -557,7 +544,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, s
 						0);
 		if (unlikely(IS_ERR(swap_storage))) {
 			printk(KERN_ERR "Failed allocating swap storage.\n");
-			return -ENOMEM;
+			return PTR_ERR(swap_storage);
 		}
 	} else
 		swap_storage = persistant_swap_storage;
@@ -569,9 +556,10 @@ int ttm_tt_swapout(struct ttm_tt *ttm, s
 		if (unlikely(from_page == NULL))
 			continue;
 		to_page = read_mapping_page(swap_space, i, NULL);
-		if (unlikely(to_page == NULL))
+		if (unlikely(IS_ERR(to_page))) {
+			ret = PTR_ERR(to_page);
 			goto out_err;
-
+		}
 		preempt_disable();
 		from_virtual = kmap_atomic(from_page, KM_USER0);
 		to_virtual = kmap_atomic(to_page, KM_USER1);
@@ -595,5 +583,5 @@ out_err:
 	if (!persistant_swap_storage)
 		fput(swap_storage);
 
-	return -ENOMEM;
+	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/via/via_dmablit.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/via/via_dmablit.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/via/via_dmablit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/via/via_dmablit.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include "via_dmablit.h"
 
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 
 #define VIA_PGDN(x)	     (((unsigned long)(x)) & PAGE_MASK)
 #define VIA_PGOFF(x)	    (((unsigned long)(x)) & ~PAGE_MASK)
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/via/via_irq.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/via/via_irq.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/via/via_irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/via/via_irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -150,7 +150,7 @@ irqreturn_t via_driver_irq_handler(DRM_I
 		cur_irq++;
 	}
 
-	/* Acknowlege interrupts */
+	/* Acknowledge interrupts */
 	VIA_WRITE(VIA_REG_INTERRUPT, status);
 
 
@@ -165,7 +165,7 @@ static __inline__ void viadrv_acknowledg
 	u32 status;
 
 	if (dev_priv) {
-		/* Acknowlege interrupts */
+		/* Acknowledge interrupts */
 		status = VIA_READ(VIA_REG_INTERRUPT);
 		VIA_WRITE(VIA_REG_INTERRUPT, status |
 			  dev_priv->irq_pending_mask);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/via/via_video.c linux-libre-2.6.34-gnu1/drivers/gpu/drm/via/via_video.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/via/via_video.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/via/via_video.c	2010-05-16 17:17:36.000000000 -0400
@@ -75,7 +75,7 @@ int via_decoder_futex(struct drm_device
 
 	DRM_DEBUG("\n");
 
-	if (fx->lock > VIA_NR_XVMC_LOCKS)
+	if (fx->lock >= VIA_NR_XVMC_LOCKS)
 		return -EFAULT;
 
 	lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx->lock);
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/Kconfig linux-libre-2.6.34-gnu1/drivers/gpu/drm/vmwgfx/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/drm/vmwgfx/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 config DRM_VMWGFX
 	tristate "DRM driver for VMware Virtual GPU"
-	depends on DRM && PCI
+	depends on DRM && PCI && FB
 	select FB_DEFERRED_IO
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/vga/Kconfig linux-libre-2.6.34-gnu1/drivers/gpu/vga/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/gpu/vga/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/vga/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -8,3 +8,22 @@ config VGA_ARB
 	  are accessed at same time they need some kind of coordination. Please
 	  see Documentation/vgaarbiter.txt for more details. Select this to
 	  enable VGA arbiter.
+
+config VGA_ARB_MAX_GPUS
+	int "Maximum number of GPUs"
+	default 16
+	depends on VGA_ARB
+	help
+	  Reserves space in the kernel to maintain resource locking for
+	  multiple GPUS.  The overhead for each GPU is very small.
+
+config VGA_SWITCHEROO
+	bool "Laptop Hybrid Grapics - GPU switching support"
+	depends on X86
+	depends on ACPI
+	help
+	  Many laptops released in 2008/9/10 have two gpus with a multiplxer
+	  to switch between them. This adds support for dynamic switching when
+          X isn't running and delayed switching until the next logoff. This
+	  features is called hybrid graphics, ATI PowerXpress, and Nvidia
+	  HybridPower.
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/vga/Makefile linux-libre-2.6.34-gnu1/drivers/gpu/vga/Makefile
--- linux-libre-2.6.33-gnu1/drivers/gpu/vga/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/vga/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1 +1,2 @@
 obj-$(CONFIG_VGA_ARB)  += vgaarb.o
+obj-$(CONFIG_VGA_SWITCHEROO) += vga_switcheroo.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/vga/vgaarb.c linux-libre-2.6.34-gnu1/drivers/gpu/vga/vgaarb.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/vga/vgaarb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/vga/vgaarb.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/spinlock.h>
 #include <linux/poll.h>
 #include <linux/miscdevice.h>
+#include <linux/slab.h>
 
 #include <linux/uaccess.h>
 
@@ -688,7 +689,7 @@ EXPORT_SYMBOL(vga_client_register);
  * the arbiter.
  */
 
-#define MAX_USER_CARDS         16
+#define MAX_USER_CARDS         CONFIG_VGA_ARB_MAX_GPUS
 #define PCI_INVALID_CARD       ((struct pci_dev *)-1UL)
 
 /*
@@ -954,6 +955,7 @@ static ssize_t vga_arb_write(struct file
 		}
 
 	} else if (strncmp(curr_pos, "target ", 7) == 0) {
+		struct pci_bus *pbus;
 		unsigned int domain, bus, devfn;
 		struct vga_device *vgadev;
 
@@ -969,18 +971,31 @@ static ssize_t vga_arb_write(struct file
 				ret_val = -EPROTO;
 				goto done;
 			}
+			pr_devel("vgaarb: %s ==> %x:%x:%x.%x\n", curr_pos,
+				domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
 
-			pdev = pci_get_bus_and_slot(bus, devfn);
+			pbus = pci_find_bus(domain, bus);
+			pr_devel("vgaarb: pbus %p\n", pbus);
+			if (pbus == NULL) {
+				pr_err("vgaarb: invalid PCI domain and/or bus address %x:%x\n",
+					domain, bus);
+				ret_val = -ENODEV;
+				goto done;
+			}
+			pdev = pci_get_slot(pbus, devfn);
+			pr_devel("vgaarb: pdev %p\n", pdev);
 			if (!pdev) {
-				pr_info("vgaarb: invalid PCI address!\n");
+				pr_err("vgaarb: invalid PCI address %x:%x\n",
+					bus, devfn);
 				ret_val = -ENODEV;
 				goto done;
 			}
 		}
 
 		vgadev = vgadev_find(pdev);
+		pr_devel("vgaarb: vgadev %p\n", vgadev);
 		if (vgadev == NULL) {
-			pr_info("vgaarb: this pci device is not a vga device\n");
+			pr_err("vgaarb: this pci device is not a vga device\n");
 			pci_dev_put(pdev);
 			ret_val = -ENODEV;
 			goto done;
@@ -998,7 +1013,8 @@ static ssize_t vga_arb_write(struct file
 			}
 		}
 		if (i == MAX_USER_CARDS) {
-			pr_err("vgaarb: maximum user cards number reached!\n");
+			pr_err("vgaarb: maximum user cards (%d) number reached!\n",
+				MAX_USER_CARDS);
 			pci_dev_put(pdev);
 			/* XXX: which value to return? */
 			ret_val =  -ENOMEM;
diff -druNp linux-libre-2.6.33-gnu1/drivers/gpu/vga/vga_switcheroo.c linux-libre-2.6.34-gnu1/drivers/gpu/vga/vga_switcheroo.c
--- linux-libre-2.6.33-gnu1/drivers/gpu/vga/vga_switcheroo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/gpu/vga/vga_switcheroo.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2010 Red Hat Inc.
+ * Author : Dave Airlie <airlied@redhat.com>
+ *
+ *
+ * Licensed under GPLv2
+ *
+ * vga_switcheroo.c - Support for laptop with dual GPU using one set of outputs
+
+ Switcher interface - methods require for ATPX and DCM
+ - switchto - this throws the output MUX switch
+ - discrete_set_power - sets the power state for the discrete card
+
+ GPU driver interface
+ - set_gpu_state - this should do the equiv of s/r for the card
+		  - this should *not* set the discrete power state
+ - switch_check  - check if the device is in a position to switch now
+ */
+
+#include <linux/module.h>
+#include <linux/dmi.h>
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/fb.h>
+
+#include <linux/pci.h>
+#include <linux/vga_switcheroo.h>
+
+struct vga_switcheroo_client {
+	struct pci_dev *pdev;
+	struct fb_info *fb_info;
+	int pwr_state;
+	void (*set_gpu_state)(struct pci_dev *pdev, enum vga_switcheroo_state);
+	bool (*can_switch)(struct pci_dev *pdev);
+	int id;
+	bool active;
+};
+
+static DEFINE_MUTEX(vgasr_mutex);
+
+struct vgasr_priv {
+
+	bool active;
+	bool delayed_switch_active;
+	enum vga_switcheroo_client_id delayed_client_id;
+
+	struct dentry *debugfs_root;
+	struct dentry *switch_file;
+
+	int registered_clients;
+	struct vga_switcheroo_client clients[VGA_SWITCHEROO_MAX_CLIENTS];
+
+	struct vga_switcheroo_handler *handler;
+};
+
+static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv);
+static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv);
+
+/* only one switcheroo per system */
+static struct vgasr_priv vgasr_priv;
+
+int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler)
+{
+	mutex_lock(&vgasr_mutex);
+	if (vgasr_priv.handler) {
+		mutex_unlock(&vgasr_mutex);
+		return -EINVAL;
+	}
+
+	vgasr_priv.handler = handler;
+	mutex_unlock(&vgasr_mutex);
+	return 0;
+}
+EXPORT_SYMBOL(vga_switcheroo_register_handler);
+
+void vga_switcheroo_unregister_handler(void)
+{
+	mutex_lock(&vgasr_mutex);
+	vgasr_priv.handler = NULL;
+	mutex_unlock(&vgasr_mutex);
+}
+EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
+
+static void vga_switcheroo_enable(void)
+{
+	int i;
+	int ret;
+	/* call the handler to init */
+	vgasr_priv.handler->init();
+
+	for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
+		ret = vgasr_priv.handler->get_client_id(vgasr_priv.clients[i].pdev);
+		if (ret < 0)
+			return;
+
+		vgasr_priv.clients[i].id = ret;
+	}
+	vga_switcheroo_debugfs_init(&vgasr_priv);
+	vgasr_priv.active = true;
+}
+
+int vga_switcheroo_register_client(struct pci_dev *pdev,
+				   void (*set_gpu_state)(struct pci_dev *pdev, enum vga_switcheroo_state),
+				   bool (*can_switch)(struct pci_dev *pdev))
+{
+	int index;
+
+	mutex_lock(&vgasr_mutex);
+	/* don't do IGD vs DIS here */
+	if (vgasr_priv.registered_clients & 1)
+		index = 1;
+	else
+		index = 0;
+
+	vgasr_priv.clients[index].pwr_state = VGA_SWITCHEROO_ON;
+	vgasr_priv.clients[index].pdev = pdev;
+	vgasr_priv.clients[index].set_gpu_state = set_gpu_state;
+	vgasr_priv.clients[index].can_switch = can_switch;
+	vgasr_priv.clients[index].id = -1;
+	if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
+		vgasr_priv.clients[index].active = true;
+
+	vgasr_priv.registered_clients |= (1 << index);
+
+	/* if we get two clients + handler */
+	if (vgasr_priv.registered_clients == 0x3 && vgasr_priv.handler) {
+		printk(KERN_INFO "vga_switcheroo: enabled\n");
+		vga_switcheroo_enable();
+	}
+	mutex_unlock(&vgasr_mutex);
+	return 0;
+}
+EXPORT_SYMBOL(vga_switcheroo_register_client);
+
+void vga_switcheroo_unregister_client(struct pci_dev *pdev)
+{
+	int i;
+
+	mutex_lock(&vgasr_mutex);
+	for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
+		if (vgasr_priv.clients[i].pdev == pdev) {
+			vgasr_priv.registered_clients &= ~(1 << i);
+			break;
+		}
+	}
+
+	printk(KERN_INFO "vga_switcheroo: disabled\n");
+	vga_switcheroo_debugfs_fini(&vgasr_priv);
+	vgasr_priv.active = false;
+	mutex_unlock(&vgasr_mutex);
+}
+EXPORT_SYMBOL(vga_switcheroo_unregister_client);
+
+void vga_switcheroo_client_fb_set(struct pci_dev *pdev,
+				 struct fb_info *info)
+{
+	int i;
+
+	mutex_lock(&vgasr_mutex);
+	for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
+		if (vgasr_priv.clients[i].pdev == pdev) {
+			vgasr_priv.clients[i].fb_info = info;
+			break;
+		}
+	}
+	mutex_unlock(&vgasr_mutex);
+}
+EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
+
+static int vga_switcheroo_show(struct seq_file *m, void *v)
+{
+	int i;
+	mutex_lock(&vgasr_mutex);
+	for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
+		seq_printf(m, "%d:%c:%s:%s\n", i,
+			   vgasr_priv.clients[i].active ? '+' : ' ',
+			   vgasr_priv.clients[i].pwr_state ? "Pwr" : "Off",
+			   pci_name(vgasr_priv.clients[i].pdev));
+	}
+	mutex_unlock(&vgasr_mutex);
+	return 0;
+}
+
+static int vga_switcheroo_debugfs_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, vga_switcheroo_show, NULL);
+}
+
+static int vga_switchon(struct vga_switcheroo_client *client)
+{
+	int ret;
+
+	ret = vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_ON);
+	/* call the driver callback to turn on device */
+	client->set_gpu_state(client->pdev, VGA_SWITCHEROO_ON);
+	client->pwr_state = VGA_SWITCHEROO_ON;
+	return 0;
+}
+
+static int vga_switchoff(struct vga_switcheroo_client *client)
+{
+	/* call the driver callback to turn off device */
+	client->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF);
+	vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_OFF);
+	client->pwr_state = VGA_SWITCHEROO_OFF;
+	return 0;
+}
+
+static int vga_switchto(struct vga_switcheroo_client *new_client)
+{
+	int ret;
+	int i;
+	struct vga_switcheroo_client *active = NULL;
+
+	if (new_client->active == true)
+		return 0;
+
+	for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
+		if (vgasr_priv.clients[i].active == true) {
+			active = &vgasr_priv.clients[i];
+			break;
+		}
+	}
+	if (!active)
+		return 0;
+
+	/* power up the first device */
+	ret = pci_enable_device(new_client->pdev);
+	if (ret)
+		return ret;
+
+	if (new_client->pwr_state == VGA_SWITCHEROO_OFF)
+		vga_switchon(new_client);
+
+	/* swap shadow resource to denote boot VGA device has changed so X starts on new device */
+	active->active = false;
+
+	active->pdev->resource[PCI_ROM_RESOURCE].flags &= ~IORESOURCE_ROM_SHADOW;
+	new_client->pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
+
+	if (new_client->fb_info) {
+		struct fb_event event;
+		event.info = new_client->fb_info;
+		fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
+	}
+
+	ret = vgasr_priv.handler->switchto(new_client->id);
+	if (ret)
+		return ret;
+
+	if (active->pwr_state == VGA_SWITCHEROO_ON)
+		vga_switchoff(active);
+
+	new_client->active = true;
+	return 0;
+}
+
+static ssize_t
+vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
+			     size_t cnt, loff_t *ppos)
+{
+	char usercmd[64];
+	const char *pdev_name;
+	int i, ret;
+	bool delay = false, can_switch;
+	int client_id = -1;
+	struct vga_switcheroo_client *client = NULL;
+
+	if (cnt > 63)
+		cnt = 63;
+
+	if (copy_from_user(usercmd, ubuf, cnt))
+		return -EFAULT;
+
+	mutex_lock(&vgasr_mutex);
+
+	if (!vgasr_priv.active) {
+		cnt = -EINVAL;
+		goto out;
+	}
+
+	/* pwr off the device not in use */
+	if (strncmp(usercmd, "OFF", 3) == 0) {
+		for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
+			if (vgasr_priv.clients[i].active)
+				continue;
+			if (vgasr_priv.clients[i].pwr_state == VGA_SWITCHEROO_ON)
+				vga_switchoff(&vgasr_priv.clients[i]);
+		}
+		goto out;
+	}
+	/* pwr on the device not in use */
+	if (strncmp(usercmd, "ON", 2) == 0) {
+		for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
+			if (vgasr_priv.clients[i].active)
+				continue;
+			if (vgasr_priv.clients[i].pwr_state == VGA_SWITCHEROO_OFF)
+				vga_switchon(&vgasr_priv.clients[i]);
+		}
+		goto out;
+	}
+
+	/* request a delayed switch - test can we switch now */
+	if (strncmp(usercmd, "DIGD", 4) == 0) {
+		client_id = VGA_SWITCHEROO_IGD;
+		delay = true;
+	}
+
+	if (strncmp(usercmd, "DDIS", 4) == 0) {
+		client_id = VGA_SWITCHEROO_DIS;
+		delay = true;
+	}
+
+	if (strncmp(usercmd, "IGD", 3) == 0)
+		client_id = VGA_SWITCHEROO_IGD;
+
+	if (strncmp(usercmd, "DIS", 3) == 0)
+		client_id = VGA_SWITCHEROO_DIS;
+
+	if (client_id == -1)
+		goto out;
+
+	for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
+		if (vgasr_priv.clients[i].id == client_id) {
+			client = &vgasr_priv.clients[i];
+			break;
+		}
+	}
+
+	vgasr_priv.delayed_switch_active = false;
+	/* okay we want a switch - test if devices are willing to switch */
+	can_switch = true;
+	for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
+		can_switch = vgasr_priv.clients[i].can_switch(vgasr_priv.clients[i].pdev);
+		if (can_switch == false) {
+			printk(KERN_ERR "vga_switcheroo: client %d refused switch\n", i);
+			break;
+		}
+	}
+
+	if (can_switch == false && delay == false)
+		goto out;
+
+	if (can_switch == true) {
+		pdev_name = pci_name(client->pdev);
+		ret = vga_switchto(client);
+		if (ret)
+			printk(KERN_ERR "vga_switcheroo: switching failed %d\n", ret);
+	} else {
+		printk(KERN_INFO "vga_switcheroo: setting delayed switch to client %d\n", client->id);
+		vgasr_priv.delayed_switch_active = true;
+		vgasr_priv.delayed_client_id = client_id;
+
+		/* we should at least power up the card to
+		   make the switch faster */
+		if (client->pwr_state == VGA_SWITCHEROO_OFF)
+			vga_switchon(client);
+	}
+
+out:
+	mutex_unlock(&vgasr_mutex);
+	return cnt;
+}
+
+static const struct file_operations vga_switcheroo_debugfs_fops = {
+	.owner = THIS_MODULE,
+	.open = vga_switcheroo_debugfs_open,
+	.write = vga_switcheroo_debugfs_write,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv)
+{
+	if (priv->switch_file) {
+		debugfs_remove(priv->switch_file);
+		priv->switch_file = NULL;
+	}
+	if (priv->debugfs_root) {
+		debugfs_remove(priv->debugfs_root);
+		priv->debugfs_root = NULL;
+	}
+}
+
+static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv)
+{
+	/* already initialised */
+	if (priv->debugfs_root)
+		return 0;
+	priv->debugfs_root = debugfs_create_dir("vgaswitcheroo", NULL);
+
+	if (!priv->debugfs_root) {
+		printk(KERN_ERR "vga_switcheroo: Cannot create /sys/kernel/debug/vgaswitcheroo\n");
+		goto fail;
+	}
+
+	priv->switch_file = debugfs_create_file("switch", 0644,
+						priv->debugfs_root, NULL, &vga_switcheroo_debugfs_fops);
+	if (!priv->switch_file) {
+		printk(KERN_ERR "vga_switcheroo: cannot create /sys/kernel/debug/vgaswitcheroo/switch\n");
+		goto fail;
+	}
+	return 0;
+fail:
+	vga_switcheroo_debugfs_fini(priv);
+	return -1;
+}
+
+int vga_switcheroo_process_delayed_switch(void)
+{
+	struct vga_switcheroo_client *client = NULL;
+	const char *pdev_name;
+	bool can_switch = true;
+	int i;
+	int ret;
+	int err = -EINVAL;
+
+	mutex_lock(&vgasr_mutex);
+	if (!vgasr_priv.delayed_switch_active)
+		goto err;
+
+	printk(KERN_INFO "vga_switcheroo: processing delayed switch to %d\n", vgasr_priv.delayed_client_id);
+
+	for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
+		if (vgasr_priv.clients[i].id == vgasr_priv.delayed_client_id)
+			client = &vgasr_priv.clients[i];
+		can_switch = vgasr_priv.clients[i].can_switch(vgasr_priv.clients[i].pdev);
+		if (can_switch == false) {
+			printk(KERN_ERR "vga_switcheroo: client %d refused switch\n", i);
+			break;
+		}
+	}
+
+	if (can_switch == false || client == NULL)
+		goto err;
+
+	pdev_name = pci_name(client->pdev);
+	ret = vga_switchto(client);
+	if (ret)
+		printk(KERN_ERR "vga_switcheroo: delayed switching failed %d\n", ret);
+
+	vgasr_priv.delayed_switch_active = false;
+	err = 0;
+err:
+	mutex_unlock(&vgasr_mutex);
+	return err;
+}
+EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-3m-pct.c linux-libre-2.6.34-gnu1/drivers/hid/hid-3m-pct.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-3m-pct.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-3m-pct.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,291 @@
+/*
+ *  HID driver for 3M PCT multitouch panels
+ *
+ *  Copyright (c) 2009 Stephane Chatty <chatty@enac.fr>
+ *
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+
+MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
+MODULE_DESCRIPTION("3M PCT multitouch panels");
+MODULE_LICENSE("GPL");
+
+#include "hid-ids.h"
+
+struct mmm_finger {
+	__s32 x, y;
+	__u8 rank;
+	bool touch, valid;
+};
+
+struct mmm_data {
+	struct mmm_finger f[10];
+	__u8 curid, num;
+	bool touch, valid;
+};
+
+static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	switch (usage->hid & HID_USAGE_PAGE) {
+
+	case HID_UP_BUTTON:
+		return -1;
+
+	case HID_UP_GENDESK:
+		switch (usage->hid) {
+		case HID_GD_X:
+			hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_POSITION_X);
+			/* touchscreen emulation */
+			input_set_abs_params(hi->input, ABS_X,
+						field->logical_minimum,
+						field->logical_maximum, 0, 0);
+			return 1;
+		case HID_GD_Y:
+			hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_POSITION_Y);
+			/* touchscreen emulation */
+			input_set_abs_params(hi->input, ABS_Y,
+						field->logical_minimum,
+						field->logical_maximum, 0, 0);
+			return 1;
+		}
+		return 0;
+
+	case HID_UP_DIGITIZER:
+		switch (usage->hid) {
+		/* we do not want to map these: no input-oriented meaning */
+		case 0x14:
+		case 0x23:
+		case HID_DG_INPUTMODE:
+		case HID_DG_DEVICEINDEX:
+		case HID_DG_CONTACTCOUNT:
+		case HID_DG_CONTACTMAX:
+		case HID_DG_INRANGE:
+		case HID_DG_CONFIDENCE:
+			return -1;
+		case HID_DG_TIPSWITCH:
+			/* touchscreen emulation */
+			hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
+			return 1;
+		case HID_DG_CONTACTID:
+			hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_TRACKING_ID);
+			return 1;
+		}
+		/* let hid-input decide for the others */
+		return 0;
+
+	case 0xff000000:
+		/* we do not want to map these: no input-oriented meaning */
+		return -1;
+	}
+
+	return 0;
+}
+
+static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	if (usage->type == EV_KEY || usage->type == EV_ABS)
+		clear_bit(usage->code, *bit);
+
+	return 0;
+}
+
+/*
+ * this function is called when a whole packet has been received and processed,
+ * so that it can decide what to send to the input layer.
+ */
+static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
+{
+	struct mmm_finger *oldest = 0;
+	bool pressed = false, released = false;
+	int i;
+
+	/*
+	 * we need to iterate on all fingers to decide if we have a press
+	 * or a release event in our touchscreen emulation.
+	 */
+	for (i = 0; i < 10; ++i) {
+		struct mmm_finger *f = &md->f[i];
+		if (!f->valid) {
+			/* this finger is just placeholder data, ignore */
+		} else if (f->touch) {
+			/* this finger is on the screen */
+			input_event(input, EV_ABS, ABS_MT_TRACKING_ID, i);
+			input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x);
+			input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y);
+			input_mt_sync(input);
+			/*
+			 * touchscreen emulation: maintain the age rank
+			 * of this finger, decide if we have a press
+			 */
+			if (f->rank == 0) {
+				f->rank = ++(md->num);
+				if (f->rank == 1)
+					pressed = true;
+			}
+			if (f->rank == 1)
+				oldest = f;
+		} else {
+			/* this finger took off the screen */
+			/* touchscreen emulation: maintain age rank of others */
+			int j;
+
+			for (j = 0; j < 10; ++j) {
+				struct mmm_finger *g = &md->f[j];
+				if (g->rank > f->rank) {
+					g->rank--;
+					if (g->rank == 1)
+						oldest = g;
+				}
+			}
+			f->rank = 0;
+			--(md->num);
+			if (md->num == 0)
+				released = true;
+		}
+		f->valid = 0;
+	}
+
+	/* touchscreen emulation */
+	if (oldest) {
+		if (pressed)
+			input_event(input, EV_KEY, BTN_TOUCH, 1);
+		input_event(input, EV_ABS, ABS_X, oldest->x);
+		input_event(input, EV_ABS, ABS_Y, oldest->y);
+	} else if (released) {
+		input_event(input, EV_KEY, BTN_TOUCH, 0);
+	}
+}
+
+/*
+ * this function is called upon all reports
+ * so that we can accumulate contact point information,
+ * and call input_mt_sync after each point.
+ */
+static int mmm_event(struct hid_device *hid, struct hid_field *field,
+				struct hid_usage *usage, __s32 value)
+{
+	struct mmm_data *md = hid_get_drvdata(hid);
+	/*
+	 * strangely, this function can be called before
+	 * field->hidinput is initialized!
+	 */
+	if (hid->claimed & HID_CLAIMED_INPUT) {
+		struct input_dev *input = field->hidinput->input;
+		switch (usage->hid) {
+		case HID_DG_TIPSWITCH:
+			md->touch = value;
+			break;
+		case HID_DG_CONFIDENCE:
+			md->valid = value;
+			break;
+		case HID_DG_CONTACTID:
+			if (md->valid) {
+				md->curid = value;
+				md->f[value].touch = md->touch;
+				md->f[value].valid = 1;
+			}
+			break;
+		case HID_GD_X:
+			if (md->valid)
+				md->f[md->curid].x = value;
+			break;
+		case HID_GD_Y:
+			if (md->valid)
+				md->f[md->curid].y = value;
+			break;
+		case HID_DG_CONTACTCOUNT:
+			mmm_filter_event(md, input);
+			break;
+		}
+	}
+
+	/* we have handled the hidinput part, now remains hiddev */
+	if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
+		hid->hiddev_hid_event(hid, field, usage, value);
+
+	return 1;
+}
+
+static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+	int ret;
+	struct mmm_data *md;
+
+	md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL);
+	if (!md) {
+		dev_err(&hdev->dev, "cannot allocate 3M data\n");
+		return -ENOMEM;
+	}
+	hid_set_drvdata(hdev, md);
+
+	ret = hid_parse(hdev);
+	if (!ret)
+		ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+
+	if (ret)
+		kfree(md);
+	return ret;
+}
+
+static void mmm_remove(struct hid_device *hdev)
+{
+	hid_hw_stop(hdev);
+	kfree(hid_get_drvdata(hdev));
+	hid_set_drvdata(hdev, NULL);
+}
+
+static const struct hid_device_id mmm_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, mmm_devices);
+
+static const struct hid_usage_id mmm_grabbed_usages[] = {
+	{ HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
+	{ HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
+};
+
+static struct hid_driver mmm_driver = {
+	.name = "3m-pct",
+	.id_table = mmm_devices,
+	.probe = mmm_probe,
+	.remove = mmm_remove,
+	.input_mapping = mmm_input_mapping,
+	.input_mapped = mmm_input_mapped,
+	.usage_table = mmm_grabbed_usages,
+	.event = mmm_event,
+};
+
+static int __init mmm_init(void)
+{
+	return hid_register_driver(&mmm_driver);
+}
+
+static void __exit mmm_exit(void)
+{
+	hid_unregister_driver(&mmm_driver);
+}
+
+module_init(mmm_init);
+module_exit(mmm_exit);
+MODULE_LICENSE("GPL");
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-a4tech.c linux-libre-2.6.34-gnu1/drivers/hid/hid-a4tech.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-a4tech.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-a4tech.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/input.h>
 #include <linux/hid.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "hid-ids.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-apple.c linux-libre-2.6.34-gnu1/drivers/hid/hid-apple.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-apple.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-apple.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "hid-ids.h"
@@ -40,6 +41,11 @@ module_param(fnmode, uint, 0644);
 MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, "
 		"[1] = fkeyslast, 2 = fkeysfirst)");
 
+static unsigned int iso_layout = 1;
+module_param(iso_layout, uint, 0644);
+MODULE_PARM_DESC(iso_layout, "Enable/Disable hardcoded ISO-layout of the keyboard. "
+		"(0 = disabled, [1] = enabled)");
+
 struct apple_sc {
 	unsigned long quirks;
 	unsigned int fn_on;
@@ -199,11 +205,13 @@ static int hidinput_apple_event(struct h
 		}
 	}
 
-	if (asc->quirks & APPLE_ISO_KEYBOARD) {
-		trans = apple_find_translation(apple_iso_keyboard, usage->code);
-		if (trans) {
-			input_event(input, usage->type, trans->to, value);
-			return 1;
+        if (iso_layout) {
+		if (asc->quirks & APPLE_ISO_KEYBOARD) {
+			trans = apple_find_translation(apple_iso_keyboard, usage->code);
+			if (trans) {
+				input_event(input, usage->type, trans->to, value);
+				return 1;
+			}
 		}
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-cherry.c linux-libre-2.6.34-gnu1/drivers/hid/hid-cherry.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-cherry.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-cherry.c	2010-05-16 17:17:36.000000000 -0400
@@ -59,6 +59,7 @@ static int ch_input_mapping(struct hid_d
 
 static const struct hid_device_id ch_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, ch_devices);
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-core.c linux-libre-2.6.34-gnu1/drivers/hid/hid-core.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
  *  Copyright (c) 1999 Andreas Gal
  *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
  *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- *  Copyright (c) 2006-2007 Jiri Kosina
+ *  Copyright (c) 2006-2010 Jiri Kosina
  */
 
 /*
@@ -51,7 +51,7 @@ EXPORT_SYMBOL_GPL(hid_debug);
  * Register a new report for a device.
  */
 
-static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id)
+struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id)
 {
 	struct hid_report_enum *report_enum = device->report_enum + type;
 	struct hid_report *report;
@@ -75,6 +75,7 @@ static struct hid_report *hid_register_r
 
 	return report;
 }
+EXPORT_SYMBOL_GPL(hid_register_report);
 
 /*
  * Register a new field for this report.
@@ -387,7 +388,8 @@ static int hid_parser_local(struct hid_p
 	__u32 data;
 	unsigned n;
 
-	if (item->size == 0) {
+	/* Local delimiter could have value 0, which allows size to be 0 */
+	if (item->size == 0 && item->tag != HID_LOCAL_ITEM_TAG_DELIMITER) {
 		dbg_hid("item data expected for local item\n");
 		return -1;
 	}
@@ -1041,13 +1043,8 @@ void hid_report_raw_event(struct hid_dev
 
 	if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
 		hid->hiddev_report_event(hid, report);
-	if (hid->claimed & HID_CLAIMED_HIDRAW) {
-		/* numbered reports need to be passed with the report num */
-		if (report_enum->numbered)
-			hidraw_report_event(hid, data - 1, size + 1);
-		else
-			hidraw_report_event(hid, data, size);
-	}
+	if (hid->claimed & HID_CLAIMED_HIDRAW)
+		hidraw_report_event(hid, data, size);
 
 	for (a = 0; a < report->maxfield; a++)
 		hid_input_field(hid, report->field[a], cdata, interrupt);
@@ -1248,11 +1245,13 @@ EXPORT_SYMBOL_GPL(hid_disconnect);
 
 /* a list of devices for which there is a specialized driver on HID bus */
 static const struct hid_device_id hid_blacklist[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) },
@@ -1292,6 +1291,7 @@ static const struct hid_device_id hid_bl
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
@@ -1324,6 +1324,7 @@ static const struct hid_device_id hid_bl
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940) },
 	{ 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) },
@@ -1337,16 +1338,22 @@ static const struct hid_device_id hid_bl
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
@@ -1543,8 +1550,9 @@ static const struct hid_device_id hid_ig
 	{ HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM)},
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2)},
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT)},
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)},
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)},
 	{ HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) },
@@ -1661,8 +1669,6 @@ static const struct hid_device_id hid_ig
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-debug.c linux-libre-2.6.34-gnu1/drivers/hid/hid-debug.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-debug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-debug.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/poll.h>
 
@@ -564,10 +565,10 @@ void hid_debug_event(struct hid_device *
 	struct hid_debug_list *list;
 
 	list_for_each_entry(list, &hdev->debug_list, node) {
-		for (i = 0; i <= strlen(buf); i++)
-			list->hid_debug_buf[(list->tail + i) % (HID_DEBUG_BUFSIZE - 1)] =
+		for (i = 0; i < strlen(buf); i++)
+			list->hid_debug_buf[(list->tail + i) % HID_DEBUG_BUFSIZE] =
 				buf[i];
-		list->tail = (list->tail + i) % (HID_DEBUG_BUFSIZE - 1);
+		list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE;
         }
 }
 EXPORT_SYMBOL_GPL(hid_debug_event);
@@ -864,13 +865,13 @@ static const char **names[EV_MAX + 1] =
 	[EV_SND] = sounds,			[EV_REP] = repeats,
 };
 
-void hid_resolv_event(__u8 type, __u16 code, struct seq_file *f) {
-
+static void hid_resolv_event(__u8 type, __u16 code, struct seq_file *f)
+{
 	seq_printf(f, "%s.%s", events[type] ? events[type] : "?",
 		names[type] ? (names[type][code] ? names[type][code] : "?") : "?");
 }
 
-void hid_dump_input_mapping(struct hid_device *hid, struct seq_file *f)
+static void hid_dump_input_mapping(struct hid_device *hid, struct seq_file *f)
 {
 	int i, j, k;
 	struct hid_report *report;
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-drff.c linux-libre-2.6.34-gnu1/drivers/hid/hid-drff.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-drff.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-drff.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
  */
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-gaff.c linux-libre-2.6.34-gnu1/drivers/hid/hid-gaff.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-gaff.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-gaff.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
  */
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
 #include "hid-ids.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-gyration.c linux-libre-2.6.34-gnu1/drivers/hid/hid-gyration.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-gyration.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-gyration.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,10 +53,13 @@ static int gyration_input_mapping(struct
 static int gyration_event(struct hid_device *hdev, struct hid_field *field,
 		struct hid_usage *usage, __s32 value)
 {
-	struct input_dev *input = field->hidinput->input;
+
+	if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput)
+		return 0;
 
 	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK &&
 			(usage->hid & 0xff) == 0x82) {
+		struct input_dev *input = field->hidinput->input;
 		input_event(input, usage->type, usage->code, 1);
 		input_sync(input);
 		input_event(input, usage->type, usage->code, 0);
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-ids.h linux-libre-2.6.34-gnu1/drivers/hid/hid-ids.h
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-ids.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-ids.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,9 @@
 #ifndef HID_IDS_H_FILE
 #define HID_IDS_H_FILE
 
+#define USB_VENDOR_ID_3M		0x0596
+#define USB_DEVICE_ID_3M1968		0x0500
+
 #define USB_VENDOR_ID_A4TECH		0x09da
 #define USB_DEVICE_ID_A4TECH_WCP32PU	0x0006
 #define USB_DEVICE_ID_A4TECH_X5_005D	0x000a
@@ -56,6 +59,7 @@
 
 #define USB_VENDOR_ID_APPLE		0x05ac
 #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE	0x0304
+#define USB_DEVICE_ID_APPLE_MAGICMOUSE	0x030d
 #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI	0x020e
 #define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO	0x020f
 #define USB_DEVICE_ID_APPLE_GEYSER_ANSI	0x0214
@@ -96,9 +100,12 @@
 #define USB_DEVICE_ID_APPLE_ATV_IRCONTROL	0x8241
 #define USB_DEVICE_ID_APPLE_IRCONTROL4	0x8242
 
-#define USB_VENDOR_ID_ASUS		0x0b05
-#define USB_DEVICE_ID_ASUS_LCM		0x1726
-#define USB_DEVICE_ID_ASUS_LCM2		0x175b
+#define USB_VENDOR_ID_ASUS		0x0486
+#define USB_DEVICE_ID_ASUS_T91MT	0x0185
+
+#define USB_VENDOR_ID_ASUSTEK		0x0b05
+#define USB_DEVICE_ID_ASUSTEK_LCM	0x1726
+#define USB_DEVICE_ID_ASUSTEK_LCM2	0x175b
 
 #define USB_VENDOR_ID_ATEN		0x0557
 #define USB_DEVICE_ID_ATEN_UC100KM	0x2004
@@ -124,6 +131,7 @@
 
 #define USB_VENDOR_ID_CHERRY		0x046a
 #define USB_DEVICE_ID_CHERRY_CYMOTION	0x0023
+#define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR	0x0027
 
 #define USB_VENDOR_ID_CHIC		0x05fe
 #define USB_DEVICE_ID_CHIC_GAMEPAD	0x0014
@@ -169,6 +177,9 @@
 #define USB_VENDOR_ID_ESSENTIAL_REALITY	0x0d7f
 #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
 
+#define USB_VENDOR_ID_ETURBOTOUCH	0x22b9
+#define USB_DEVICE_ID_ETURBOTOUCH	0x0006
+
 #define USB_VENDOR_ID_ETT		0x0664
 #define USB_DEVICE_ID_TC5UH		0x0309
 
@@ -303,6 +314,7 @@
 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2	0xc219
 #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D	0xc283
 #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO	0xc286
+#define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940	0xc287
 #define USB_DEVICE_ID_LOGITECH_WHEEL	0xc294
 #define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG	0xc293
 #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL	0xc295
@@ -365,6 +377,9 @@
 #define USB_VENDOR_ID_ONTRAK		0x0a07
 #define USB_DEVICE_ID_ONTRAK_ADU100	0x0064
 
+#define USB_VENDOR_ID_ORTEK		0x05a4
+#define USB_DEVICE_ID_ORTEK_WKB2000	0x2000
+
 #define USB_VENDOR_ID_PANJIT		0x134c
 
 #define USB_VENDOR_ID_PANTHERLORD	0x0810
@@ -382,9 +397,16 @@
 #define USB_VENDOR_ID_POWERCOM		0x0d9f
 #define USB_DEVICE_ID_POWERCOM_UPS	0x0002
 
+#define USB_VENDOR_ID_PRODIGE		0x05af
+#define USB_DEVICE_ID_PRODIGE_CORDLESS	0x3062
+
 #define USB_VENDOR_ID_SAITEK		0x06a3
 #define USB_DEVICE_ID_SAITEK_RUMBLEPAD	0xff17
 
+#define USB_VENDOR_ID_QUANTA		0x0408
+#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH	0x3000
+#define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN	0x3001
+
 #define USB_VENDOR_ID_SAMSUNG		0x0419
 #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE	0x0001
 
@@ -396,18 +418,20 @@
 #define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST	0x0034
 #define USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST	0x0046
 
+#define USB_VENDOR_ID_STANTUM		0x1f87
+#define USB_DEVICE_ID_MTP		0x0002
+
 #define USB_VENDOR_ID_SUN		0x0430
 #define USB_DEVICE_ID_RARITAN_KVM_DONGLE	0xcdab
 
 #define USB_VENDOR_ID_SUNPLUS		0x04fc
 #define USB_DEVICE_ID_SUNPLUS_WDESKTOP	0x05d8
 
-#define USB_VENDOR_ID_TENX		0x1130
-#define USB_DEVICE_ID_TENX_IBUDDY1	0x0001
-#define USB_DEVICE_ID_TENX_IBUDDY2	0x0002
-
 #define USB_VENDOR_ID_THRUSTMASTER	0x044f
 
+#define USB_VENDOR_ID_TOUCHPACK		0x1bfd
+#define USB_DEVICE_ID_TOUCHPACK_RTS	0x1688
+
 #define USB_VENDOR_ID_TOPMAX		0x0663
 #define USB_DEVICE_ID_TOPMAX_COBRAPAD	0x0103
 
@@ -422,6 +446,7 @@
 
 #define USB_VENDOR_ID_UCLOGIC		0x5543
 #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209	0x0042
+#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U	0x0003
 
 #define USB_VENDOR_ID_VERNIER		0x08f7
 #define USB_DEVICE_ID_VERNIER_LABPRO	0x0001
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-input.c linux-libre-2.6.34-gnu1/drivers/hid/hid-input.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-input.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-input.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  *  Copyright (c) 2000-2001 Vojtech Pavlik
- *  Copyright (c) 2006-2007 Jiri Kosina
+ *  Copyright (c) 2006-2010 Jiri Kosina
  *
  *  HID to Linux Input mapping
  */
@@ -68,22 +68,25 @@ static const struct {
 #define map_key_clear(c)	hid_map_usage_clear(hidinput, usage, &bit, \
 		&max, EV_KEY, (c))
 
-static inline int match_scancode(int code, int scancode)
+static inline int match_scancode(unsigned int code, unsigned int scancode)
 {
 	if (scancode == 0)
 		return 1;
-	return ((code & (HID_USAGE_PAGE | HID_USAGE)) == scancode);
+
+	return (code & (HID_USAGE_PAGE | HID_USAGE)) == scancode;
 }
 
-static inline int match_keycode(int code, int keycode)
+static inline int match_keycode(unsigned int code, unsigned int keycode)
 {
 	if (keycode == 0)
 		return 1;
-	return (code == keycode);
+
+	return code == keycode;
 }
 
 static struct hid_usage *hidinput_find_key(struct hid_device *hid,
-		int scancode, int keycode)
+					   unsigned int scancode,
+					   unsigned int keycode)
 {
 	int i, j, k;
 	struct hid_report *report;
@@ -105,8 +108,8 @@ static struct hid_usage *hidinput_find_k
 	return NULL;
 }
 
-static int hidinput_getkeycode(struct input_dev *dev, int scancode,
-				int *keycode)
+static int hidinput_getkeycode(struct input_dev *dev,
+			       unsigned int scancode, unsigned int *keycode)
 {
 	struct hid_device *hid = input_get_drvdata(dev);
 	struct hid_usage *usage;
@@ -119,16 +122,13 @@ static int hidinput_getkeycode(struct in
 	return -EINVAL;
 }
 
-static int hidinput_setkeycode(struct input_dev *dev, int scancode,
-				int keycode)
+static int hidinput_setkeycode(struct input_dev *dev,
+			       unsigned int scancode, unsigned int keycode)
 {
 	struct hid_device *hid = input_get_drvdata(dev);
 	struct hid_usage *usage;
 	int old_keycode;
 
-	if (keycode < 0 || keycode > KEY_MAX)
-		return -EINVAL;
-
 	usage = hidinput_find_key(hid, scancode, 0);
 	if (usage) {
 		old_keycode = usage->code;
@@ -193,12 +193,17 @@ static void hidinput_configure_usage(str
 		break;
 
 	case HID_UP_BUTTON:
-		code = ((usage->hid - 1) & 0xf);
+		code = ((usage->hid - 1) & HID_USAGE);
 
 		switch (field->application) {
 		case HID_GD_MOUSE:
 		case HID_GD_POINTER:  code += 0x110; break;
-		case HID_GD_JOYSTICK: code += 0x120; break;
+		case HID_GD_JOYSTICK:
+				      if (code <= 0xf)
+					      code += BTN_JOYSTICK;
+				      else
+					      code += BTN_TRIGGER_HAPPY;
+				      break;
 		case HID_GD_GAMEPAD:  code += 0x130; break;
 		default:
 			switch (field->physical) {
@@ -400,6 +405,7 @@ static void hidinput_configure_usage(str
 		case 0x192: map_key_clear(KEY_CALC);		break;
 		case 0x194: map_key_clear(KEY_FILE);		break;
 		case 0x196: map_key_clear(KEY_WWW);		break;
+		case 0x199: map_key_clear(KEY_CHAT);		break;
 		case 0x19c: map_key_clear(KEY_LOGOFF);		break;
 		case 0x19e: map_key_clear(KEY_COFFEE);		break;
 		case 0x1a6: map_key_clear(KEY_HELP);		break;
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-lg2ff.c linux-libre-2.6.34-gnu1/drivers/hid/hid-lg2ff.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-lg2ff.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-lg2ff.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-lg3ff.c linux-libre-2.6.34-gnu1/drivers/hid/hid-lg3ff.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-lg3ff.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-lg3ff.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,176 @@
+/*
+ *  Force feedback support for Logitech Flight System G940
+ *
+ *  Copyright (c) 2009 Gary Stein <LordCnidarian@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 "usbhid/usbhid.h"
+#include "hid-lg.h"
+
+/*
+ * G940 Theory of Operation (from experimentation)
+ *
+ * There are 63 fields (only 3 of them currently used)
+ * 0 - seems to be command field
+ * 1 - 30 deal with the x axis
+ * 31 -60 deal with the y axis
+ *
+ * Field 1 is x axis constant force
+ * Field 31 is y axis constant force
+ *
+ * other interesting fields 1,2,3,4 on x axis
+ * (same for 31,32,33,34 on y axis)
+ *
+ * 0 0 127 127 makes the joystick autocenter hard
+ *
+ * 127 0 127 127 makes the joystick loose on the right,
+ * but stops all movemnt left
+ *
+ * -127 0 -127 -127 makes the joystick loose on the left,
+ * but stops all movement right
+ *
+ * 0 0 -127 -127 makes the joystick rattle very hard
+ *
+ * I'm sure these are effects that I don't know enough about them
+ */
+
+struct lg3ff_device {
+	struct hid_report *report;
+};
+
+static int hid_lg3ff_play(struct input_dev *dev, void *data,
+			 struct ff_effect *effect)
+{
+	struct hid_device *hid = input_get_drvdata(dev);
+	struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+	struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
+	int x, y;
+
+/*
+ * Maxusage should always be 63 (maximum fields)
+ * likely a better way to ensure this data is clean
+ */
+	memset(report->field[0]->value, 0, sizeof(__s32)*report->field[0]->maxusage);
+
+	switch (effect->type) {
+	case FF_CONSTANT:
+/*
+ * Already clamped in ff_memless
+ * 0 is center (different then other logitech)
+ */
+		x = effect->u.ramp.start_level;
+		y = effect->u.ramp.end_level;
+
+		/* send command byte */
+		report->field[0]->value[0] = 0x51;
+
+/*
+ * Sign backwards from other Force3d pro
+ * which get recast here in two's complement 8 bits
+ */
+		report->field[0]->value[1] = (unsigned char)(-x);
+		report->field[0]->value[31] = (unsigned char)(-y);
+
+		usbhid_submit_report(hid, report, USB_DIR_OUT);
+		break;
+	}
+	return 0;
+}
+static void hid_lg3ff_set_autocenter(struct input_dev *dev, u16 magnitude)
+{
+	struct hid_device *hid = input_get_drvdata(dev);
+	struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+	struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
+
+/*
+ * Auto Centering probed from device
+ * NOTE: deadman's switch on G940 must be covered
+ * for effects to work
+ */
+	report->field[0]->value[0] = 0x51;
+	report->field[0]->value[1] = 0x00;
+	report->field[0]->value[2] = 0x00;
+	report->field[0]->value[3] = 0x7F;
+	report->field[0]->value[4] = 0x7F;
+	report->field[0]->value[31] = 0x00;
+	report->field[0]->value[32] = 0x00;
+	report->field[0]->value[33] = 0x7F;
+	report->field[0]->value[34] = 0x7F;
+
+	usbhid_submit_report(hid, report, USB_DIR_OUT);
+}
+
+
+static const signed short ff3_joystick_ac[] = {
+	FF_CONSTANT,
+	FF_AUTOCENTER,
+	-1
+};
+
+int lg3ff_init(struct hid_device *hid)
+{
+	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+	struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+	struct input_dev *dev = hidinput->input;
+	struct hid_report *report;
+	struct hid_field *field;
+	const signed short *ff_bits = ff3_joystick_ac;
+	int error;
+	int i;
+
+	/* Find the report to use */
+	if (list_empty(report_list)) {
+		err_hid("No output report found");
+		return -1;
+	}
+
+	/* Check that the report looks ok */
+	report = list_entry(report_list->next, struct hid_report, list);
+	if (!report) {
+		err_hid("NULL output report");
+		return -1;
+	}
+
+	field = report->field[0];
+	if (!field) {
+		err_hid("NULL field");
+		return -1;
+	}
+
+	/* Assume single fixed device G940 */
+	for (i = 0; ff_bits[i] >= 0; i++)
+		set_bit(ff_bits[i], dev->ffbit);
+
+	error = input_ff_create_memless(dev, NULL, hid_lg3ff_play);
+	if (error)
+		return error;
+
+	if (test_bit(FF_AUTOCENTER, dev->ffbit))
+		dev->ff->set_autocenter = hid_lg3ff_set_autocenter;
+
+	dev_info(&hid->dev, "Force feedback for Logitech Flight System G940 by "
+			"Gary Stein <LordCnidarian@gmail.com>\n");
+	return 0;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-lg.c linux-libre-2.6.34-gnu1/drivers/hid/hid-lg.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-lg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-lg.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #define LG_FF			0x200
 #define LG_FF2			0x400
 #define LG_RDESC_REL_ABS	0x800
+#define LG_FF3			0x1000
 
 /*
  * Certain Logitech keyboards send in report #3 keys which are far
@@ -266,7 +267,7 @@ static int lg_probe(struct hid_device *h
 		goto err_free;
 	}
 
-	if (quirks & (LG_FF | LG_FF2))
+	if (quirks & (LG_FF | LG_FF2 | LG_FF3))
 		connect_mask &= ~HID_CONNECT_FF;
 
 	ret = hid_hw_start(hdev, connect_mask);
@@ -279,6 +280,8 @@ static int lg_probe(struct hid_device *h
 		lgff_init(hdev);
 	if (quirks & LG_FF2)
 		lg2ff_init(hdev);
+	if (quirks & LG_FF3)
+		lg3ff_init(hdev);
 
 	return 0;
 err_free:
@@ -331,6 +334,8 @@ static const struct hid_device_id lg_dev
 		.driver_data = LG_FF },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
 		.driver_data = LG_FF2 },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940),
+		.driver_data = LG_FF3 },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR),
 		.driver_data = LG_RDESC_REL_ABS },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER),
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-lgff.c linux-libre-2.6.34-gnu1/drivers/hid/hid-lgff.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-lgff.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-lgff.c	2010-05-16 17:17:36.000000000 -0400
@@ -67,6 +67,7 @@ static const struct dev_type devices[] =
 	{ 0x046d, 0xc219, ff_rumble },
 	{ 0x046d, 0xc283, ff_joystick },
 	{ 0x046d, 0xc286, ff_joystick_ac },
+	{ 0x046d, 0xc287, ff_joystick_ac },
 	{ 0x046d, 0xc293, ff_joystick },
 	{ 0x046d, 0xc294, ff_wheel },
 	{ 0x046d, 0xc295, ff_joystick },
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-lg.h linux-libre-2.6.34-gnu1/drivers/hid/hid-lg.h
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-lg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-lg.h	2010-05-16 17:17:36.000000000 -0400
@@ -13,4 +13,10 @@ int lg2ff_init(struct hid_device *hdev);
 static inline int lg2ff_init(struct hid_device *hdev) { return -1; }
 #endif
 
+#ifdef CONFIG_LOGIG940_FF
+int lg3ff_init(struct hid_device *hdev);
+#else
+static inline int lg3ff_init(struct hid_device *hdev) { return -1; }
+#endif
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-magicmouse.c linux-libre-2.6.34-gnu1/drivers/hid/hid-magicmouse.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-magicmouse.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-magicmouse.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,453 @@
+/*
+ *   Apple "Magic" Wireless Mouse driver
+ *
+ *   Copyright (c) 2010 Michael Poole <mdpoole@troilus.org>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+
+#include "hid-ids.h"
+
+static bool emulate_3button = true;
+module_param(emulate_3button, bool, 0644);
+MODULE_PARM_DESC(emulate_3button, "Emulate a middle button");
+
+static int middle_button_start = -350;
+static int middle_button_stop = +350;
+
+static bool emulate_scroll_wheel = true;
+module_param(emulate_scroll_wheel, bool, 0644);
+MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel");
+
+static bool report_touches = true;
+module_param(report_touches, bool, 0644);
+MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)");
+
+static bool report_undeciphered;
+module_param(report_undeciphered, bool, 0644);
+MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event");
+
+#define TOUCH_REPORT_ID   0x29
+/* These definitions are not precise, but they're close enough.  (Bits
+ * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem
+ * to be some kind of bit mask -- 0x20 may be a near-field reading,
+ * and 0x40 is actual contact, and 0x10 may be a start/stop or change
+ * indication.)
+ */
+#define TOUCH_STATE_MASK  0xf0
+#define TOUCH_STATE_NONE  0x00
+#define TOUCH_STATE_START 0x30
+#define TOUCH_STATE_DRAG  0x40
+
+/**
+ * struct magicmouse_sc - Tracks Magic Mouse-specific data.
+ * @input: Input device through which we report events.
+ * @quirks: Currently unused.
+ * @last_timestamp: Timestamp from most recent (18-bit) touch report
+ *     (units of milliseconds over short windows, but seems to
+ *     increase faster when there are no touches).
+ * @delta_time: 18-bit difference between the two most recent touch
+ *     reports from the mouse.
+ * @ntouches: Number of touches in most recent touch report.
+ * @scroll_accel: Number of consecutive scroll motions.
+ * @scroll_jiffies: Time of last scroll motion.
+ * @touches: Most recent data for a touch, indexed by tracking ID.
+ * @tracking_ids: Mapping of current touch input data to @touches.
+ */
+struct magicmouse_sc {
+	struct input_dev *input;
+	unsigned long quirks;
+
+	int last_timestamp;
+	int delta_time;
+	int ntouches;
+	int scroll_accel;
+	unsigned long scroll_jiffies;
+
+	struct {
+		short x;
+		short y;
+		short scroll_y;
+		u8 size;
+	} touches[16];
+	int tracking_ids[16];
+};
+
+static int magicmouse_firm_touch(struct magicmouse_sc *msc)
+{
+	int touch = -1;
+	int ii;
+
+	/* If there is only one "firm" touch, set touch to its
+	 * tracking ID.
+	 */
+	for (ii = 0; ii < msc->ntouches; ii++) {
+		int idx = msc->tracking_ids[ii];
+		if (msc->touches[idx].size < 8) {
+			/* Ignore this touch. */
+		} else if (touch >= 0) {
+			touch = -1;
+			break;
+		} else {
+			touch = idx;
+		}
+	}
+
+	return touch;
+}
+
+static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state)
+{
+	int last_state = test_bit(BTN_LEFT, msc->input->key) << 0 |
+		test_bit(BTN_RIGHT, msc->input->key) << 1 |
+		test_bit(BTN_MIDDLE, msc->input->key) << 2;
+
+	if (emulate_3button) {
+		int id;
+
+		/* If some button was pressed before, keep it held
+		 * down.  Otherwise, if there's exactly one firm
+		 * touch, use that to override the mouse's guess.
+		 */
+		if (state == 0) {
+			/* The button was released. */
+		} else if (last_state != 0) {
+			state = last_state;
+		} else if ((id = magicmouse_firm_touch(msc)) >= 0) {
+			int x = msc->touches[id].x;
+			if (x < middle_button_start)
+				state = 1;
+			else if (x > middle_button_stop)
+				state = 2;
+			else
+				state = 4;
+		} /* else: we keep the mouse's guess */
+
+		input_report_key(msc->input, BTN_MIDDLE, state & 4);
+	}
+
+	input_report_key(msc->input, BTN_LEFT, state & 1);
+	input_report_key(msc->input, BTN_RIGHT, state & 2);
+
+	if (state != last_state)
+		msc->scroll_accel = 0;
+}
+
+static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata)
+{
+	struct input_dev *input = msc->input;
+	__s32 x_y = tdata[0] << 8 | tdata[1] << 16 | tdata[2] << 24;
+	int misc = tdata[5] | tdata[6] << 8;
+	int id = (misc >> 6) & 15;
+	int x = x_y << 12 >> 20;
+	int y = -(x_y >> 20);
+
+	/* Store tracking ID and other fields. */
+	msc->tracking_ids[raw_id] = id;
+	msc->touches[id].x = x;
+	msc->touches[id].y = y;
+	msc->touches[id].size = misc & 63;
+
+	/* If requested, emulate a scroll wheel by detecting small
+	 * vertical touch motions along the middle of the mouse.
+	 */
+	if (emulate_scroll_wheel &&
+	    middle_button_start < x && x < middle_button_stop) {
+		static const int accel_profile[] = {
+			256, 228, 192, 160, 128, 96, 64, 32,
+		};
+		unsigned long now = jiffies;
+		int step = msc->touches[id].scroll_y - y;
+
+		/* Reset acceleration after half a second. */
+		if (time_after(now, msc->scroll_jiffies + HZ / 2))
+			msc->scroll_accel = 0;
+
+		/* Calculate and apply the scroll motion. */
+		switch (tdata[7] & TOUCH_STATE_MASK) {
+		case TOUCH_STATE_START:
+			msc->touches[id].scroll_y = y;
+			msc->scroll_accel = min_t(int, msc->scroll_accel + 1,
+						ARRAY_SIZE(accel_profile) - 1);
+			break;
+		case TOUCH_STATE_DRAG:
+			step = step / accel_profile[msc->scroll_accel];
+			if (step != 0) {
+				msc->touches[id].scroll_y = y;
+				msc->scroll_jiffies = now;
+				input_report_rel(input, REL_WHEEL, step);
+			}
+			break;
+		}
+	}
+
+	/* Generate the input events for this touch. */
+	if (report_touches) {
+		int orientation = (misc >> 10) - 32;
+
+		input_report_abs(input, ABS_MT_TRACKING_ID, id);
+		input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]);
+		input_report_abs(input, ABS_MT_TOUCH_MINOR, tdata[4]);
+		input_report_abs(input, ABS_MT_ORIENTATION, orientation);
+		input_report_abs(input, ABS_MT_POSITION_X, x);
+		input_report_abs(input, ABS_MT_POSITION_Y, y);
+
+		if (report_undeciphered)
+			input_event(input, EV_MSC, MSC_RAW, tdata[7]);
+
+		input_mt_sync(input);
+	}
+}
+
+static int magicmouse_raw_event(struct hid_device *hdev,
+		struct hid_report *report, u8 *data, int size)
+{
+	struct magicmouse_sc *msc = hid_get_drvdata(hdev);
+	struct input_dev *input = msc->input;
+	int x, y, ts, ii, clicks;
+
+	switch (data[0]) {
+	case 0x10:
+		if (size != 6)
+			return 0;
+		x = (__s16)(data[2] | data[3] << 8);
+		y = (__s16)(data[4] | data[5] << 8);
+		clicks = data[1];
+		break;
+	case TOUCH_REPORT_ID:
+		/* Expect six bytes of prefix, and N*8 bytes of touch data. */
+		if (size < 6 || ((size - 6) % 8) != 0)
+			return 0;
+		ts = data[3] >> 6 | data[4] << 2 | data[5] << 10;
+		msc->delta_time = (ts - msc->last_timestamp) & 0x3ffff;
+		msc->last_timestamp = ts;
+		msc->ntouches = (size - 6) / 8;
+		for (ii = 0; ii < msc->ntouches; ii++)
+			magicmouse_emit_touch(msc, ii, data + ii * 8 + 6);
+		/* When emulating three-button mode, it is important
+		 * to have the current touch information before
+		 * generating a click event.
+		 */
+		x = (signed char)data[1];
+		y = (signed char)data[2];
+		clicks = data[3];
+		break;
+	case 0x20: /* Theoretically battery status (0-100), but I have
+		    * never seen it -- maybe it is only upon request.
+		    */
+	case 0x60: /* Unknown, maybe laser on/off. */
+	case 0x61: /* Laser reflection status change.
+		    * data[1]: 0 = spotted, 1 = lost
+		    */
+	default:
+		return 0;
+	}
+
+	magicmouse_emit_buttons(msc, clicks & 3);
+	input_report_rel(input, REL_X, x);
+	input_report_rel(input, REL_Y, y);
+	input_sync(input);
+	return 1;
+}
+
+static int magicmouse_input_open(struct input_dev *dev)
+{
+	struct hid_device *hid = input_get_drvdata(dev);
+
+	return hid->ll_driver->open(hid);
+}
+
+static void magicmouse_input_close(struct input_dev *dev)
+{
+	struct hid_device *hid = input_get_drvdata(dev);
+
+	hid->ll_driver->close(hid);
+}
+
+static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev)
+{
+	input_set_drvdata(input, hdev);
+	input->event = hdev->ll_driver->hidinput_input_event;
+	input->open = magicmouse_input_open;
+	input->close = magicmouse_input_close;
+
+	input->name = hdev->name;
+	input->phys = hdev->phys;
+	input->uniq = hdev->uniq;
+	input->id.bustype = hdev->bus;
+	input->id.vendor = hdev->vendor;
+	input->id.product = hdev->product;
+	input->id.version = hdev->version;
+	input->dev.parent = hdev->dev.parent;
+
+	__set_bit(EV_KEY, input->evbit);
+	__set_bit(BTN_LEFT, input->keybit);
+	__set_bit(BTN_RIGHT, input->keybit);
+	if (emulate_3button)
+		__set_bit(BTN_MIDDLE, input->keybit);
+	__set_bit(BTN_TOOL_FINGER, input->keybit);
+
+	__set_bit(EV_REL, input->evbit);
+	__set_bit(REL_X, input->relbit);
+	__set_bit(REL_Y, input->relbit);
+	if (emulate_scroll_wheel)
+		__set_bit(REL_WHEEL, input->relbit);
+
+	if (report_touches) {
+		__set_bit(EV_ABS, input->evbit);
+
+		input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0);
+		input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0);
+		input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0);
+		input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0);
+		input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358,
+				4, 0);
+		/* Note: Touch Y position from the device is inverted relative
+		 * to how pointer motion is reported (and relative to how USB
+		 * HID recommends the coordinates work).  This driver keeps
+		 * the origin at the same position, and just uses the additive
+		 * inverse of the reported Y.
+		 */
+		input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047,
+				4, 0);
+	}
+
+	if (report_undeciphered) {
+		__set_bit(EV_MSC, input->evbit);
+		__set_bit(MSC_RAW, input->mscbit);
+	}
+}
+
+static int magicmouse_probe(struct hid_device *hdev,
+	const struct hid_device_id *id)
+{
+	__u8 feature_1[] = { 0xd7, 0x01 };
+	__u8 feature_2[] = { 0xf8, 0x01, 0x32 };
+	struct input_dev *input;
+	struct magicmouse_sc *msc;
+	struct hid_report *report;
+	int ret;
+
+	msc = kzalloc(sizeof(*msc), GFP_KERNEL);
+	if (msc == NULL) {
+		dev_err(&hdev->dev, "can't alloc magicmouse descriptor\n");
+		return -ENOMEM;
+	}
+
+	msc->quirks = id->driver_data;
+	hid_set_drvdata(hdev, msc);
+
+	ret = hid_parse(hdev);
+	if (ret) {
+		dev_err(&hdev->dev, "magicmouse hid parse failed\n");
+		goto err_free;
+	}
+
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT);
+	if (ret) {
+		dev_err(&hdev->dev, "magicmouse hw start failed\n");
+		goto err_free;
+	}
+
+	report = hid_register_report(hdev, HID_INPUT_REPORT, TOUCH_REPORT_ID);
+	if (!report) {
+		dev_err(&hdev->dev, "unable to register touch report\n");
+		ret = -ENOMEM;
+		goto err_stop_hw;
+	}
+	report->size = 6;
+
+	ret = hdev->hid_output_raw_report(hdev, feature_1, sizeof(feature_1),
+			HID_FEATURE_REPORT);
+	if (ret != sizeof(feature_1)) {
+		dev_err(&hdev->dev, "unable to request touch data (1:%d)\n",
+				ret);
+		goto err_stop_hw;
+	}
+	ret = hdev->hid_output_raw_report(hdev, feature_2,
+			sizeof(feature_2), HID_FEATURE_REPORT);
+	if (ret != sizeof(feature_2)) {
+		dev_err(&hdev->dev, "unable to request touch data (2:%d)\n",
+				ret);
+		goto err_stop_hw;
+	}
+
+	input = input_allocate_device();
+	if (!input) {
+		dev_err(&hdev->dev, "can't alloc input device\n");
+		ret = -ENOMEM;
+		goto err_stop_hw;
+	}
+	magicmouse_setup_input(input, hdev);
+
+	ret = input_register_device(input);
+	if (ret) {
+		dev_err(&hdev->dev, "input device registration failed\n");
+		goto err_input;
+	}
+	msc->input = input;
+
+	return 0;
+err_input:
+	input_free_device(input);
+err_stop_hw:
+	hid_hw_stop(hdev);
+err_free:
+	kfree(msc);
+	return ret;
+}
+
+static void magicmouse_remove(struct hid_device *hdev)
+{
+	struct magicmouse_sc *msc = hid_get_drvdata(hdev);
+
+	hid_hw_stop(hdev);
+	input_unregister_device(msc->input);
+	kfree(msc);
+}
+
+static const struct hid_device_id magic_mice[] = {
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE),
+		.driver_data = 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, magic_mice);
+
+static struct hid_driver magicmouse_driver = {
+	.name = "magicmouse",
+	.id_table = magic_mice,
+	.probe = magicmouse_probe,
+	.remove = magicmouse_remove,
+	.raw_event = magicmouse_raw_event,
+};
+
+static int __init magicmouse_init(void)
+{
+	int ret;
+
+	ret = hid_register_driver(&magicmouse_driver);
+	if (ret)
+		printk(KERN_ERR "can't register magicmouse driver\n");
+
+	return ret;
+}
+
+static void __exit magicmouse_exit(void)
+{
+	hid_unregister_driver(&magicmouse_driver);
+}
+
+module_init(magicmouse_init);
+module_exit(magicmouse_exit);
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-mosart.c linux-libre-2.6.34-gnu1/drivers/hid/hid-mosart.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-mosart.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-mosart.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,274 @@
+/*
+ *  HID driver for the multitouch panel on the ASUS EeePC T91MT
+ *
+ *  Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr>
+ *  Copyright (c) 2010 Teemu Tuominen <teemu.tuominen@cybercom.com>
+ *
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include "usbhid/usbhid.h"
+
+MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
+MODULE_DESCRIPTION("MosArt dual-touch panel");
+MODULE_LICENSE("GPL");
+
+#include "hid-ids.h"
+
+struct mosart_data {
+	__u16 x, y;
+	__u8 id;
+	bool valid;		/* valid finger data, or just placeholder? */
+	bool first;		/* is this the first finger in this frame? */
+	bool activity_now;	/* at least one active finger in this frame? */
+	bool activity;		/* at least one active finger previously? */
+};
+
+static int mosart_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	switch (usage->hid & HID_USAGE_PAGE) {
+
+	case HID_UP_GENDESK:
+		switch (usage->hid) {
+		case HID_GD_X:
+			hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_POSITION_X);
+			/* touchscreen emulation */
+			input_set_abs_params(hi->input, ABS_X,
+						field->logical_minimum,
+						field->logical_maximum, 0, 0);
+			return 1;
+		case HID_GD_Y:
+			hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_POSITION_Y);
+			/* touchscreen emulation */
+			input_set_abs_params(hi->input, ABS_Y,
+						field->logical_minimum,
+						field->logical_maximum, 0, 0);
+			return 1;
+		}
+		return 0;
+
+	case HID_UP_DIGITIZER:
+		switch (usage->hid) {
+		case HID_DG_CONFIDENCE:
+		case HID_DG_TIPSWITCH:
+		case HID_DG_INPUTMODE:
+		case HID_DG_DEVICEINDEX:
+		case HID_DG_CONTACTCOUNT:
+		case HID_DG_CONTACTMAX:
+		case HID_DG_TIPPRESSURE:
+		case HID_DG_WIDTH:
+		case HID_DG_HEIGHT:
+			return -1;
+		case HID_DG_INRANGE:
+			/* touchscreen emulation */
+			hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
+			return 1;
+
+		case HID_DG_CONTACTID:
+			hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_TRACKING_ID);
+			return 1;
+
+		}
+		return 0;
+
+	case 0xff000000:
+		/* ignore HID features */
+		return -1;
+	}
+
+	return 0;
+}
+
+static int mosart_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	if (usage->type == EV_KEY || usage->type == EV_ABS)
+		clear_bit(usage->code, *bit);
+
+	return 0;
+}
+
+/*
+ * this function is called when a whole finger has been parsed,
+ * so that it can decide what to send to the input layer.
+ */
+static void mosart_filter_event(struct mosart_data *td, struct input_dev *input)
+{
+	td->first = !td->first; /* touchscreen emulation */
+
+	if (!td->valid) {
+		/*
+		 * touchscreen emulation: if no finger in this frame is valid
+		 * and there previously was finger activity, this is a release
+		 */ 
+		if (!td->first && !td->activity_now && td->activity) {
+			input_event(input, EV_KEY, BTN_TOUCH, 0);
+			td->activity = false;
+		}
+		return;
+	}
+
+	input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id);
+	input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x);
+	input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y);
+
+	input_mt_sync(input);
+	td->valid = false;
+
+	/* touchscreen emulation: if first active finger in this frame... */
+	if (!td->activity_now) {
+		/* if there was no previous activity, emit touch event */
+		if (!td->activity) {
+			input_event(input, EV_KEY, BTN_TOUCH, 1);
+			td->activity = true;
+		}
+		td->activity_now = true;
+		/* and in any case this is our preferred finger */
+		input_event(input, EV_ABS, ABS_X, td->x);
+		input_event(input, EV_ABS, ABS_Y, td->y);
+	}
+}
+
+
+static int mosart_event(struct hid_device *hid, struct hid_field *field,
+				struct hid_usage *usage, __s32 value)
+{
+	struct mosart_data *td = hid_get_drvdata(hid);
+
+	if (hid->claimed & HID_CLAIMED_INPUT) {
+		struct input_dev *input = field->hidinput->input;
+		switch (usage->hid) {
+		case HID_DG_INRANGE:
+			td->valid = !!value;
+			break;
+		case HID_GD_X:
+			td->x = value;
+			break;
+		case HID_GD_Y:
+			td->y = value;
+			mosart_filter_event(td, input);
+			break;
+		case HID_DG_CONTACTID:
+			td->id = value;
+			break;
+		case HID_DG_CONTACTCOUNT:
+			/* touch emulation: this is the last field in a frame */
+			td->first = false;
+			td->activity_now = false;
+			break;
+		case HID_DG_CONFIDENCE:
+		case HID_DG_TIPSWITCH:
+			/* avoid interference from generic hidinput handling */
+			break;
+
+		default:
+			/* fallback to the generic hidinput handling */
+			return 0;
+		}
+	}
+
+	/* we have handled the hidinput part, now remains hiddev */
+	if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
+		hid->hiddev_hid_event(hid, field, usage, value);
+
+	return 1;
+}
+
+static int mosart_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+	int ret;
+	struct mosart_data *td;
+
+
+	td = kmalloc(sizeof(struct mosart_data), GFP_KERNEL);
+	if (!td) {
+		dev_err(&hdev->dev, "cannot allocate MosArt data\n");
+		return -ENOMEM;
+	}
+	td->valid = false;
+	td->activity = false;
+	td->activity_now = false;
+	td->first = false;
+	hid_set_drvdata(hdev, td);
+
+	/* currently, it's better to have one evdev device only */
+#if 0
+	hdev->quirks |= HID_QUIRK_MULTI_INPUT;
+#endif
+
+	ret = hid_parse(hdev);
+	if (ret == 0)
+		ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+
+	if (ret == 0) {
+		struct hid_report_enum *re = hdev->report_enum
+						+ HID_FEATURE_REPORT;
+		struct hid_report *r = re->report_id_hash[7];
+
+		r->field[0]->value[0] = 0x02;
+		usbhid_submit_report(hdev, r, USB_DIR_OUT);
+	} else 
+		kfree(td);
+
+	return ret;
+}
+
+static void mosart_remove(struct hid_device *hdev)
+{
+	hid_hw_stop(hdev);
+	kfree(hid_get_drvdata(hdev));
+	hid_set_drvdata(hdev, NULL);
+}
+
+static const struct hid_device_id mosart_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, mosart_devices);
+
+static const struct hid_usage_id mosart_grabbed_usages[] = {
+	{ HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
+	{ HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
+};
+
+static struct hid_driver mosart_driver = {
+	.name = "mosart",
+	.id_table = mosart_devices,
+	.probe = mosart_probe,
+	.remove = mosart_remove,
+	.input_mapping = mosart_input_mapping,
+	.input_mapped = mosart_input_mapped,
+	.usage_table = mosart_grabbed_usages,
+	.event = mosart_event,
+};
+
+static int __init mosart_init(void)
+{
+	return hid_register_driver(&mosart_driver);
+}
+
+static void __exit mosart_exit(void)
+{
+	hid_unregister_driver(&mosart_driver);
+}
+
+module_init(mosart_init);
+module_exit(mosart_exit);
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-ntrig.c linux-libre-2.6.34-gnu1/drivers/hid/hid-ntrig.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-ntrig.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-ntrig.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,8 +1,8 @@
 /*
  *  HID driver for N-Trig touchscreens
  *
- *  Copyright (c) 2008 Rafi Rubin
- *  Copyright (c) 2009 Stephane Chatty
+ *  Copyright (c) 2008-2010 Rafi Rubin
+ *  Copyright (c) 2009-2010 Stephane Chatty
  *
  */
 
@@ -15,21 +15,28 @@
 
 #include <linux/device.h>
 #include <linux/hid.h>
+#include <linux/usb.h>
+#include "usbhid/usbhid.h"
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "hid-ids.h"
 
 #define NTRIG_DUPLICATE_USAGES	0x001
 
-#define nt_map_key_clear(c)	hid_map_usage_clear(hi, usage, bit, max, \
-					EV_KEY, (c))
-
 struct ntrig_data {
-	__s32 x, y, id, w, h;
-	char reading_a_point, found_contact_id;
-	char pen_active;
-	char finger_active;
-	char inverted;
+	/* Incoming raw values for a single contact */
+	__u16 x, y, w, h;
+	__u16 id;
+
+	bool tipswitch;
+	bool confidence;
+	bool first_contact_touch;
+
+	bool reading_mt;
+
+	__u8 mt_footer[4];
+	__u8 mt_foot_count;
 };
 
 /*
@@ -42,8 +49,11 @@ static int ntrig_input_mapping(struct hi
 		struct hid_field *field, struct hid_usage *usage,
 		unsigned long **bit, int *max)
 {
-	switch (usage->hid & HID_USAGE_PAGE) {
+	/* No special mappings needed for the pen and single touch */
+	if (field->physical)
+		return 0;
 
+	switch (usage->hid & HID_USAGE_PAGE) {
 	case HID_UP_GENDESK:
 		switch (usage->hid) {
 		case HID_GD_X:
@@ -66,18 +76,12 @@ static int ntrig_input_mapping(struct hi
 	case HID_UP_DIGITIZER:
 		switch (usage->hid) {
 		/* we do not want to map these for now */
-		case HID_DG_CONTACTID: /* value is useless */
+		case HID_DG_CONTACTID: /* Not trustworthy, squelch for now */
 		case HID_DG_INPUTMODE:
 		case HID_DG_DEVICEINDEX:
-		case HID_DG_CONTACTCOUNT:
 		case HID_DG_CONTACTMAX:
 			return -1;
 
-		/* original mapping by Rafi Rubin */
-		case HID_DG_CONFIDENCE:
-			nt_map_key_clear(BTN_TOOL_DOUBLETAP);
-			return 1;
-
 		/* width/height mapped on TouchMajor/TouchMinor/Orientation */
 		case HID_DG_WIDTH:
 			hid_map_usage(hi, usage, bit, max,
@@ -104,6 +108,10 @@ static int ntrig_input_mapped(struct hid
 		struct hid_field *field, struct hid_usage *usage,
 		unsigned long **bit, int *max)
 {
+	/* No special mappings needed for the pen and single touch */
+	if (field->physical)
+		return 0;
+
 	if (usage->type == EV_KEY || usage->type == EV_REL
 			|| usage->type == EV_ABS)
 		clear_bit(usage->code, *bit);
@@ -123,31 +131,34 @@ static int ntrig_event (struct hid_devic
 	struct input_dev *input = field->hidinput->input;
 	struct ntrig_data *nd = hid_get_drvdata(hid);
 
+	/* No special handling needed for the pen */
+	if (field->application == HID_DG_PEN)
+		return 0;
+
         if (hid->claimed & HID_CLAIMED_INPUT) {
 		switch (usage->hid) {
-
-		case HID_DG_INRANGE:
-			if (field->application & 0x3)
-				nd->pen_active = (value != 0);
-			else
-				nd->finger_active = (value != 0);
-			return 0;
-
-		case HID_DG_INVERT:
-			nd->inverted = value;
-			return 0;
-
+		case 0xff000001:
+			/* Tag indicating the start of a multitouch group */
+			nd->reading_mt = 1;
+			nd->first_contact_touch = 0;
+			break;
+		case HID_DG_TIPSWITCH:
+			nd->tipswitch = value;
+			/* Prevent emission of touch until validated */
+			return 1;
+		case HID_DG_CONFIDENCE:
+			nd->confidence = value;
+			break;
 		case HID_GD_X:
 			nd->x = value;
-			nd->reading_a_point = 1;
+			/* Clear the contact footer */
+			nd->mt_foot_count = 0;
 			break;
 		case HID_GD_Y:
 			nd->y = value;
 			break;
 		case HID_DG_CONTACTID:
 			nd->id = value;
-			/* we receive this only when in multitouch mode */
-			nd->found_contact_id = 1;
 			break;
 		case HID_DG_WIDTH:
 			nd->w = value;
@@ -159,33 +170,17 @@ static int ntrig_event (struct hid_devic
 			 * report received in a finger event. We want
 			 * to emit a normal (X, Y) position
 			 */
-			if (!nd->found_contact_id) {
-				if (nd->pen_active && nd->finger_active) {
-					input_report_key(input, BTN_TOOL_DOUBLETAP, 0);
-					input_report_key(input, BTN_TOOL_DOUBLETAP, 1);
-				}
-				input_event(input, EV_ABS, ABS_X, nd->x);
-				input_event(input, EV_ABS, ABS_Y, nd->y);
-			}
-			break;
-		case HID_DG_TIPPRESSURE:
-			/*
-			 * when in single touch mode, this is the last
-			 * report received in a pen event. We want
-			 * to emit a normal (X, Y) position
-			 */
-			if (! nd->found_contact_id) {
-				if (nd->pen_active && nd->finger_active) {
-					input_report_key(input,
-							nd->inverted ? BTN_TOOL_RUBBER : BTN_TOOL_PEN
-							, 0);
-					input_report_key(input,
-							nd->inverted ? BTN_TOOL_RUBBER : BTN_TOOL_PEN
-							, 1);
-				}
+			if (!nd->reading_mt) {
+				/*
+				 * TipSwitch indicates the presence of a
+				 * finger in single touch mode.
+				 */
+				input_report_key(input, BTN_TOUCH,
+						 nd->tipswitch);
+				input_report_key(input, BTN_TOOL_DOUBLETAP,
+						 nd->tipswitch);
 				input_event(input, EV_ABS, ABS_X, nd->x);
 				input_event(input, EV_ABS, ABS_Y, nd->y);
-				input_event(input, EV_ABS, ABS_PRESSURE, value);
 			}
 			break;
 		case 0xff000002:
@@ -195,10 +190,40 @@ static int ntrig_event (struct hid_devic
 			 * this usage tells if the contact point is real
 			 * or a placeholder
 			 */
-			if (!nd->reading_a_point || value != 1)
+
+			/* Shouldn't get more than 4 footer packets, so skip */
+			if (nd->mt_foot_count >= 4)
 				break;
+
+			nd->mt_footer[nd->mt_foot_count++] = value;
+
+			/* if the footer isn't complete break */
+			if (nd->mt_foot_count != 4)
+				break;
+
+			/* Pen activity signal, trigger end of touch. */
+			if (nd->mt_footer[2]) {
+				nd->confidence = 0;
+				break;
+			}
+
+			/* If the contact was invalid */
+			if (!(nd->confidence && nd->mt_footer[0])
+					|| nd->w <= 250
+					|| nd->h <= 190) {
+				nd->confidence = 0;
+				break;
+			}
+
 			/* emit a normal (X, Y) for the first point only */
 			if (nd->id == 0) {
+				/*
+				 * TipSwitch is superfluous in multitouch
+				 * mode.  The footer events tell us
+				 * if there is a finger on the screen or
+				 * not.
+				 */
+				nd->first_contact_touch = nd->confidence;
 				input_event(input, EV_ABS, ABS_X, nd->x);
 				input_event(input, EV_ABS, ABS_Y, nd->y);
 			}
@@ -220,8 +245,21 @@ static int ntrig_event (struct hid_devic
 						ABS_MT_TOUCH_MINOR, nd->w);
 			}
 			input_mt_sync(field->hidinput->input);
-			nd->reading_a_point = 0;
-			nd->found_contact_id = 0;
+			break;
+
+		case HID_DG_CONTACTCOUNT: /* End of a multitouch group */
+			if (!nd->reading_mt)
+				break;
+
+			nd->reading_mt = 0;
+
+			if (nd->first_contact_touch) {
+				input_report_key(input, BTN_TOOL_DOUBLETAP, 1);
+				input_report_key(input, BTN_TOUCH, 1);
+			} else {
+				input_report_key(input, BTN_TOOL_DOUBLETAP, 0);
+				input_report_key(input, BTN_TOUCH, 0);
+			}
 			break;
 
 		default:
@@ -231,8 +269,8 @@ static int ntrig_event (struct hid_devic
 	}
 
 	/* we have handled the hidinput part, now remains hiddev */
-        if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
-                hid->hiddev_hid_event(hid, field, usage, value);
+	if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_hid_event)
+		hid->hiddev_hid_event(hid, field, usage, value);
 
 	return 1;
 }
@@ -241,23 +279,75 @@ static int ntrig_probe(struct hid_device
 {
 	int ret;
 	struct ntrig_data *nd;
+	struct hid_input *hidinput;
+	struct input_dev *input;
+	struct hid_report *report;
+
+	if (id->driver_data)
+		hdev->quirks |= HID_QUIRK_MULTI_INPUT;
 
 	nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL);
 	if (!nd) {
 		dev_err(&hdev->dev, "cannot allocate N-Trig data\n");
 		return -ENOMEM;
 	}
-	nd->reading_a_point = 0;
-	nd->found_contact_id = 0;
+
+	nd->reading_mt = 0;
 	hid_set_drvdata(hdev, nd);
 
 	ret = hid_parse(hdev);
-	if (!ret)
-		ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+	if (ret) {
+		dev_err(&hdev->dev, "parse failed\n");
+		goto err_free;
+	}
+
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
+	if (ret) {
+		dev_err(&hdev->dev, "hw start failed\n");
+		goto err_free;
+	}
 
-	if (ret)
-		kfree (nd);
 
+	list_for_each_entry(hidinput, &hdev->inputs, list) {
+		if (hidinput->report->maxfield < 1)
+			continue;
+
+		input = hidinput->input;
+		switch (hidinput->report->field[0]->application) {
+		case HID_DG_PEN:
+			input->name = "N-Trig Pen";
+			break;
+		case HID_DG_TOUCHSCREEN:
+			/* These keys are redundant for fingers, clear them
+			 * to prevent incorrect identification */
+			__clear_bit(BTN_TOOL_PEN, input->keybit);
+			__clear_bit(BTN_TOOL_FINGER, input->keybit);
+			__clear_bit(BTN_0, input->keybit);
+			__set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
+			/*
+			 * The physical touchscreen (single touch)
+			 * input has a value for physical, whereas
+			 * the multitouch only has logical input
+			 * fields.
+			 */
+			input->name =
+				(hidinput->report->field[0]
+				 ->physical) ?
+				"N-Trig Touchscreen" :
+				"N-Trig MultiTouch";
+			break;
+		}
+	}
+
+	/* This is needed for devices with more recent firmware versions */
+	report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a];
+	if (report)
+		usbhid_submit_report(hdev, report, USB_DIR_OUT);
+
+
+	return 0;
+err_free:
+	kfree(nd);
 	return ret;
 }
 
@@ -276,7 +366,7 @@ MODULE_DEVICE_TABLE(hid, ntrig_devices);
 
 static const struct hid_usage_id ntrig_grabbed_usages[] = {
 	{ HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
-	{ HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
+	{ HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 }
 };
 
 static struct hid_driver ntrig_driver = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-ortek.c linux-libre-2.6.34-gnu1/drivers/hid/hid-ortek.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-ortek.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-ortek.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,56 @@
+/*
+ *  HID driver for Ortek WKB-2000 (wireless keyboard + mouse trackpad).
+ *  Fixes LogicalMaximum error in USB report description, see
+ *  http://bugzilla.kernel.org/show_bug.cgi?id=14787
+ *
+ *  Copyright (c) 2010 Johnathon Harris <jmharris@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/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+static void ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+		unsigned int rsize)
+{
+	if (rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x01) {
+		dev_info(&hdev->dev, "Fixing up Ortek WKB-2000 "
+				"report descriptor.\n");
+		rdesc[55] = 0x92;
+	}
+}
+
+static const struct hid_device_id ortek_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, ortek_devices);
+
+static struct hid_driver ortek_driver = {
+	.name = "ortek",
+	.id_table = ortek_devices,
+	.report_fixup = ortek_report_fixup
+};
+
+static int __init ortek_init(void)
+{
+	return hid_register_driver(&ortek_driver);
+}
+
+static void __exit ortek_exit(void)
+{
+	hid_unregister_driver(&ortek_driver);
+}
+
+module_init(ortek_init);
+module_exit(ortek_exit);
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-pl.c linux-libre-2.6.34-gnu1/drivers/hid/hid-pl.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-pl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-pl.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #define debug(format, arg...) pr_debug("hid-plff: " format "\n" , ## arg)
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-quanta.c linux-libre-2.6.34-gnu1/drivers/hid/hid-quanta.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-quanta.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-quanta.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,261 @@
+/*
+ *  HID driver for Quanta Optical Touch dual-touch panels
+ *
+ *  Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr>
+ *
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
+MODULE_DESCRIPTION("Quanta dual-touch panel");
+MODULE_LICENSE("GPL");
+
+#include "hid-ids.h"
+
+struct quanta_data {
+	__u16 x, y;
+	__u8 id;
+	bool valid;		/* valid finger data, or just placeholder? */
+	bool first;		/* is this the first finger in this frame? */
+	bool activity_now;	/* at least one active finger in this frame? */
+	bool activity;		/* at least one active finger previously? */
+};
+
+static int quanta_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	switch (usage->hid & HID_USAGE_PAGE) {
+
+	case HID_UP_GENDESK:
+		switch (usage->hid) {
+		case HID_GD_X:
+			hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_POSITION_X);
+			/* touchscreen emulation */
+			input_set_abs_params(hi->input, ABS_X,
+						field->logical_minimum,
+						field->logical_maximum, 0, 0);
+			return 1;
+		case HID_GD_Y:
+			hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_POSITION_Y);
+			/* touchscreen emulation */
+			input_set_abs_params(hi->input, ABS_Y,
+						field->logical_minimum,
+						field->logical_maximum, 0, 0);
+			return 1;
+		}
+		return 0;
+
+	case HID_UP_DIGITIZER:
+		switch (usage->hid) {
+		case HID_DG_CONFIDENCE:
+		case HID_DG_TIPSWITCH:
+		case HID_DG_INPUTMODE:
+		case HID_DG_DEVICEINDEX:
+		case HID_DG_CONTACTCOUNT:
+		case HID_DG_CONTACTMAX:
+		case HID_DG_TIPPRESSURE:
+		case HID_DG_WIDTH:
+		case HID_DG_HEIGHT:
+			return -1;
+		case HID_DG_INRANGE:
+			/* touchscreen emulation */
+			hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
+			return 1;
+		case HID_DG_CONTACTID:
+			hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_TRACKING_ID);
+			return 1;
+		}
+		return 0;
+
+	case 0xff000000:
+		/* ignore vendor-specific features */
+		return -1;
+	}
+
+	return 0;
+}
+
+static int quanta_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	if (usage->type == EV_KEY || usage->type == EV_ABS)
+		clear_bit(usage->code, *bit);
+
+	return 0;
+}
+
+/*
+ * this function is called when a whole finger has been parsed,
+ * so that it can decide what to send to the input layer.
+ */
+static void quanta_filter_event(struct quanta_data *td, struct input_dev *input)
+{
+	
+	td->first = !td->first; /* touchscreen emulation */
+
+	if (!td->valid) {
+		/*
+		 * touchscreen emulation: if no finger in this frame is valid
+		 * and there previously was finger activity, this is a release
+		 */ 
+		if (!td->first && !td->activity_now && td->activity) {
+			input_event(input, EV_KEY, BTN_TOUCH, 0);
+			td->activity = false;
+		}
+		return;
+	}
+
+	input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id);
+	input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x);
+	input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y);
+
+	input_mt_sync(input);
+	td->valid = false;
+
+	/* touchscreen emulation: if first active finger in this frame... */
+	if (!td->activity_now) {
+		/* if there was no previous activity, emit touch event */
+		if (!td->activity) {
+			input_event(input, EV_KEY, BTN_TOUCH, 1);
+			td->activity = true;
+		}
+		td->activity_now = true;
+		/* and in any case this is our preferred finger */
+		input_event(input, EV_ABS, ABS_X, td->x);
+		input_event(input, EV_ABS, ABS_Y, td->y);
+	}
+}
+
+
+static int quanta_event(struct hid_device *hid, struct hid_field *field,
+				struct hid_usage *usage, __s32 value)
+{
+	struct quanta_data *td = hid_get_drvdata(hid);
+
+	if (hid->claimed & HID_CLAIMED_INPUT) {
+		struct input_dev *input = field->hidinput->input;
+
+		switch (usage->hid) {
+		case HID_DG_INRANGE:
+			td->valid = !!value;
+			break;
+		case HID_GD_X:
+			td->x = value;
+			break;
+		case HID_GD_Y:
+			td->y = value;
+			quanta_filter_event(td, input);
+			break;
+		case HID_DG_CONTACTID:
+			td->id = value;
+			break;
+		case HID_DG_CONTACTCOUNT:
+			/* touch emulation: this is the last field in a frame */
+			td->first = false;
+			td->activity_now = false;
+			break;
+		case HID_DG_CONFIDENCE:
+		case HID_DG_TIPSWITCH:
+			/* avoid interference from generic hidinput handling */
+			break;
+
+		default:
+			/* fallback to the generic hidinput handling */
+			return 0;
+		}
+	}
+
+	/* we have handled the hidinput part, now remains hiddev */
+	if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
+		hid->hiddev_hid_event(hid, field, usage, value);
+
+	return 1;
+}
+
+static int quanta_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+	int ret;
+	struct quanta_data *td;
+
+	td = kmalloc(sizeof(struct quanta_data), GFP_KERNEL);
+	if (!td) {
+		dev_err(&hdev->dev, "cannot allocate Quanta Touch data\n");
+		return -ENOMEM;
+	}
+	td->valid = false;
+	td->activity = false;
+	td->activity_now = false;
+	td->first = false;
+	hid_set_drvdata(hdev, td);
+
+	ret = hid_parse(hdev);
+	if (!ret)
+		ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+
+	if (ret)
+		kfree(td);
+
+	return ret;
+}
+
+static void quanta_remove(struct hid_device *hdev)
+{
+	hid_hw_stop(hdev);
+	kfree(hid_get_drvdata(hdev));
+	hid_set_drvdata(hdev, NULL);
+}
+
+static const struct hid_device_id quanta_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
+			USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
+			USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, quanta_devices);
+
+static const struct hid_usage_id quanta_grabbed_usages[] = {
+	{ HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
+	{ HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
+};
+
+static struct hid_driver quanta_driver = {
+	.name = "quanta-touch",
+	.id_table = quanta_devices,
+	.probe = quanta_probe,
+	.remove = quanta_remove,
+	.input_mapping = quanta_input_mapping,
+	.input_mapped = quanta_input_mapped,
+	.usage_table = quanta_grabbed_usages,
+	.event = quanta_event,
+};
+
+static int __init quanta_init(void)
+{
+	return hid_register_driver(&quanta_driver);
+}
+
+static void __exit quanta_exit(void)
+{
+	hid_unregister_driver(&quanta_driver);
+}
+
+module_init(quanta_init);
+module_exit(quanta_exit);
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hidraw.c linux-libre-2.6.34-gnu1/drivers/hid/hidraw.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hidraw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hidraw.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/poll.h>
 #include <linux/device.h>
 #include <linux/major.h>
+#include <linux/slab.h>
 #include <linux/hid.h>
 #include <linux/mutex.h>
 #include <linux/sched.h>
@@ -134,7 +135,7 @@ static ssize_t hidraw_write(struct file
 		goto out;
 	}
 
-	ret = dev->hid_output_raw_report(dev, buf, count);
+	ret = dev->hid_output_raw_report(dev, buf, count, HID_OUTPUT_REPORT);
 out:
 	kfree(buf);
 	return ret;
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-sjoy.c linux-libre-2.6.34-gnu1/drivers/hid/hid-sjoy.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-sjoy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-sjoy.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 /* #define DEBUG */
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
 #include "hid-ids.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-sony.c linux-libre-2.6.34-gnu1/drivers/hid/hid-sony.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-sony.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-sony.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "hid-ids.h"
@@ -48,7 +49,7 @@ static void sony_report_fixup(struct hid
  * to "operational".  Without this, the ps3 controller will not report any
  * events.
  */
-static int sony_set_operational(struct hid_device *hdev)
+static int sony_set_operational_usb(struct hid_device *hdev)
 {
 	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
 	struct usb_device *dev = interface_to_usbdev(intf);
@@ -73,6 +74,12 @@ static int sony_set_operational(struct h
 	return ret;
 }
 
+static int sony_set_operational_bt(struct hid_device *hdev)
+{
+	unsigned char buf[] = { 0xf4,  0x42, 0x03, 0x00, 0x00 };
+	return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
+}
+
 static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
 	int ret;
@@ -81,7 +88,7 @@ static int sony_probe(struct hid_device
 
 	sc = kzalloc(sizeof(*sc), GFP_KERNEL);
 	if (sc == NULL) {
-		dev_err(&hdev->dev, "can't alloc apple descriptor\n");
+		dev_err(&hdev->dev, "can't alloc sony descriptor\n");
 		return -ENOMEM;
 	}
 
@@ -101,7 +108,17 @@ static int sony_probe(struct hid_device
 		goto err_free;
 	}
 
-	ret = sony_set_operational(hdev);
+	switch (hdev->bus) {
+	case BUS_USB:
+		ret = sony_set_operational_usb(hdev);
+		break;
+	case BUS_BLUETOOTH:
+		ret = sony_set_operational_bt(hdev);
+		break;
+	default:
+		ret = 0;
+	}
+
 	if (ret < 0)
 		goto err_stop;
 
@@ -121,6 +138,7 @@ static void sony_remove(struct hid_devic
 
 static const struct hid_device_id sony_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
 		.driver_data = VAIO_RDESC_CONSTANT },
 	{ }
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-stantum.c linux-libre-2.6.34-gnu1/drivers/hid/hid-stantum.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-stantum.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-stantum.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,284 @@
+/*
+ *  HID driver for Stantum multitouch panels
+ *
+ *  Copyright (c) 2009 Stephane Chatty <chatty@enac.fr>
+ *
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
+MODULE_DESCRIPTION("Stantum HID multitouch panels");
+MODULE_LICENSE("GPL");
+
+#include "hid-ids.h"
+
+struct stantum_data {
+	__s32 x, y, z, w, h;	/* x, y, pressure, width, height */
+	__u16 id;		/* touch id */
+	bool valid;		/* valid finger data, or just placeholder? */
+	bool first;		/* first finger in the HID packet? */
+	bool activity;		/* at least one active finger so far? */
+};
+
+static int stantum_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	switch (usage->hid & HID_USAGE_PAGE) {
+
+	case HID_UP_GENDESK:
+		switch (usage->hid) {
+		case HID_GD_X:
+			hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_POSITION_X);
+			/* touchscreen emulation */
+			input_set_abs_params(hi->input, ABS_X,
+						field->logical_minimum,
+						field->logical_maximum, 0, 0);
+			return 1;
+		case HID_GD_Y:
+			hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_POSITION_Y);
+			/* touchscreen emulation */
+			input_set_abs_params(hi->input, ABS_Y,
+						field->logical_minimum,
+						field->logical_maximum, 0, 0);
+			return 1;
+		}
+		return 0;
+
+	case HID_UP_DIGITIZER:
+		switch (usage->hid) {
+		case HID_DG_INRANGE:
+		case HID_DG_CONFIDENCE:
+		case HID_DG_INPUTMODE:
+		case HID_DG_DEVICEINDEX:
+		case HID_DG_CONTACTCOUNT:
+		case HID_DG_CONTACTMAX:
+			return -1;
+
+		case HID_DG_TIPSWITCH:
+			/* touchscreen emulation */
+			hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
+			return 1;
+
+		case HID_DG_WIDTH:
+			hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_TOUCH_MAJOR);
+			return 1;
+		case HID_DG_HEIGHT:
+			hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_TOUCH_MINOR);
+			input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
+					1, 1, 0, 0);
+			return 1;
+		case HID_DG_TIPPRESSURE:
+			hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_PRESSURE);
+			return 1;
+
+		case HID_DG_CONTACTID:
+			hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_TRACKING_ID);
+			return 1;
+
+		}
+		return 0;
+
+	case 0xff000000:
+		/* no input-oriented meaning */
+		return -1;
+	}
+
+	return 0;
+}
+
+static int stantum_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	if (usage->type == EV_KEY || usage->type == EV_ABS)
+		clear_bit(usage->code, *bit);
+
+	return 0;
+}
+
+/*
+ * this function is called when a whole finger has been parsed,
+ * so that it can decide what to send to the input layer.
+ */
+static void stantum_filter_event(struct stantum_data *sd,
+					struct input_dev *input)
+{
+	bool wide;
+
+	if (!sd->valid) {
+		/*
+		 * touchscreen emulation: if the first finger is not valid and
+		 * there previously was finger activity, this is a release
+		 */
+		if (sd->first && sd->activity) {
+			input_event(input, EV_KEY, BTN_TOUCH, 0);
+			sd->activity = false;
+		}
+		return;
+	}
+
+	input_event(input, EV_ABS, ABS_MT_TRACKING_ID, sd->id);
+	input_event(input, EV_ABS, ABS_MT_POSITION_X, sd->x);
+	input_event(input, EV_ABS, ABS_MT_POSITION_Y, sd->y);
+
+	wide = (sd->w > sd->h);
+	input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
+	input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, wide ? sd->w : sd->h);
+	input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, wide ? sd->h : sd->w);
+
+	input_event(input, EV_ABS, ABS_MT_PRESSURE, sd->z);
+
+	input_mt_sync(input);
+	sd->valid = false;
+
+	/* touchscreen emulation */
+	if (sd->first) {
+		if (!sd->activity) {
+			input_event(input, EV_KEY, BTN_TOUCH, 1);
+			sd->activity = true;
+		}
+		input_event(input, EV_ABS, ABS_X, sd->x);
+		input_event(input, EV_ABS, ABS_Y, sd->y);
+	}
+	sd->first = false;
+}
+
+
+static int stantum_event(struct hid_device *hid, struct hid_field *field,
+				struct hid_usage *usage, __s32 value)
+{
+	struct stantum_data *sd = hid_get_drvdata(hid);
+
+	if (hid->claimed & HID_CLAIMED_INPUT) {
+		struct input_dev *input = field->hidinput->input;
+
+		switch (usage->hid) {
+		case HID_DG_INRANGE:
+			/* this is the last field in a finger */
+			stantum_filter_event(sd, input);
+			break;
+		case HID_DG_WIDTH:
+			sd->w = value;
+			break;
+		case HID_DG_HEIGHT:
+			sd->h = value;
+			break;
+		case HID_GD_X:
+			sd->x = value;
+			break;
+		case HID_GD_Y:
+			sd->y = value;
+			break;
+		case HID_DG_TIPPRESSURE:
+			sd->z = value;
+			break;
+		case HID_DG_CONTACTID:
+			sd->id = value;
+			break;
+		case HID_DG_CONFIDENCE:
+			sd->valid = !!value;
+			break;
+		case 0xff000002:
+			/* this comes only before the first finger */
+			sd->first = true;
+			break;
+
+		default:
+			/* ignore the others */
+			return 1;
+		}
+	}
+
+	/* we have handled the hidinput part, now remains hiddev */
+	if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
+		hid->hiddev_hid_event(hid, field, usage, value);
+
+	return 1;
+}
+
+static int stantum_probe(struct hid_device *hdev,
+				const struct hid_device_id *id)
+{
+	int ret;
+	struct stantum_data *sd;
+
+	sd = kmalloc(sizeof(struct stantum_data), GFP_KERNEL);
+	if (!sd) {
+		dev_err(&hdev->dev, "cannot allocate Stantum data\n");
+		return -ENOMEM;
+	}
+	sd->valid = false;
+	sd->first = false;
+	sd->activity = false;
+	hid_set_drvdata(hdev, sd);
+
+	ret = hid_parse(hdev);
+	if (!ret)
+		ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+
+	if (ret)
+		kfree(sd);
+
+	return ret;
+}
+
+static void stantum_remove(struct hid_device *hdev)
+{
+	hid_hw_stop(hdev);
+	kfree(hid_get_drvdata(hdev));
+	hid_set_drvdata(hdev, NULL);
+}
+
+static const struct hid_device_id stantum_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, stantum_devices);
+
+static const struct hid_usage_id stantum_grabbed_usages[] = {
+	{ HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
+	{ HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
+};
+
+static struct hid_driver stantum_driver = {
+	.name = "stantum",
+	.id_table = stantum_devices,
+	.probe = stantum_probe,
+	.remove = stantum_remove,
+	.input_mapping = stantum_input_mapping,
+	.input_mapped = stantum_input_mapped,
+	.usage_table = stantum_grabbed_usages,
+	.event = stantum_event,
+};
+
+static int __init stantum_init(void)
+{
+	return hid_register_driver(&stantum_driver);
+}
+
+static void __exit stantum_exit(void)
+{
+	hid_unregister_driver(&stantum_driver);
+}
+
+module_init(stantum_init);
+module_exit(stantum_exit);
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-tmff.c linux-libre-2.6.34-gnu1/drivers/hid/hid-tmff.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-tmff.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-tmff.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 
 #include <linux/hid.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "hid-ids.h"
@@ -251,6 +252,8 @@ static const struct hid_device_id tm_dev
 		.driver_data = (unsigned long)ff_rumble },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651),	/* FGT Rumble Force Wheel */
 		.driver_data = (unsigned long)ff_rumble },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653),	/* RGT Force Feedback CLUTCH Raging Wheel */
+		.driver_data = (unsigned long)ff_joystick },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654),	/* FGT Force Feedback Wheel */
 		.driver_data = (unsigned long)ff_joystick },
 	{ }
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-wacom.c linux-libre-2.6.34-gnu1/drivers/hid/hid-wacom.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-wacom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-wacom.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "hid-ids.h"
 
@@ -156,7 +157,9 @@ static int wacom_probe(struct hid_device
 	struct hid_input *hidinput;
 	struct input_dev *input;
 	struct wacom_data *wdata;
+	char rep_data[2];
 	int ret;
+	int limit;
 
 	wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
 	if (wdata == NULL) {
@@ -166,6 +169,7 @@ static int wacom_probe(struct hid_device
 
 	hid_set_drvdata(hdev, wdata);
 
+	/* Parse the HID report now */
 	ret = hid_parse(hdev);
 	if (ret) {
 		dev_err(&hdev->dev, "parse failed\n");
@@ -178,6 +182,31 @@ static int wacom_probe(struct hid_device
 		goto err_free;
 	}
 
+	/*
+	 * Note that if the raw queries fail, it's not a hard failure and it
+	 * is safe to continue
+	 */
+
+	/* Set Wacom mode2 */
+	rep_data[0] = 0x03; rep_data[1] = 0x00;
+	limit = 3;
+	do {
+		ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
+				HID_FEATURE_REPORT);
+	} while (ret < 0 && limit-- > 0);
+	if (ret < 0)
+		dev_warn(&hdev->dev, "failed to poke device #1, %d\n", ret);
+
+	/* 0x06 - high reporting speed, 0x05 - low speed */
+	rep_data[0] = 0x06; rep_data[1] = 0x00;
+	limit = 3;
+	do {
+		ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
+				HID_FEATURE_REPORT);
+	} while (ret < 0 && limit-- > 0);
+	if (ret < 0)
+		dev_warn(&hdev->dev, "failed to poke device #2, %d\n", ret);
+
 	hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
 	input = hidinput->input;
 
@@ -248,7 +277,6 @@ static int __init wacom_init(void)
 	ret = hid_register_driver(&wacom_driver);
 	if (ret)
 		printk(KERN_ERR "can't register wacom driver\n");
-	printk(KERN_ERR "wacom driver registered\n");
 	return ret;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/hid-zpff.c linux-libre-2.6.34-gnu1/drivers/hid/hid-zpff.c
--- linux-libre-2.6.33-gnu1/drivers/hid/hid-zpff.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/hid-zpff.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 
 #include <linux/hid.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "hid-ids.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/Kconfig linux-libre-2.6.34-gnu1/drivers/hid/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/hid/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -55,6 +55,12 @@ source "drivers/hid/usbhid/Kconfig"
 menu "Special HID drivers"
 	depends on HID
 
+config HID_3M_PCT
+	tristate "3M PCT"
+	depends on USB_HID
+	---help---
+	Support for 3M PCT touch screens.
+
 config HID_A4TECH
 	tristate "A4 tech" if EMBEDDED
 	depends on USB_HID
@@ -183,6 +189,23 @@ config LOGIRUMBLEPAD2_FF
 	  Say Y here if you want to enable force feedback support for Logitech
 	  Rumblepad 2 devices.
 
+config LOGIG940_FF
+	bool "Logitech Flight System G940 force feedback support"
+	depends on HID_LOGITECH
+	select INPUT_FF_MEMLESS
+	help
+	  Say Y here if you want to enable force feedback support for Logitech
+	  Flight System G940 devices.
+
+config HID_MAGICMOUSE
+	tristate "Apple MagicMouse multi-touch support"
+	depends on BT_HIDP
+	---help---
+	Support for the Apple Magic Mouse multi-touch.
+
+	Say Y here if you want support for the multi-touch features of the
+	Apple Wireless "Magic" Mouse.
+
 config HID_MICROSOFT
 	tristate "Microsoft" if EMBEDDED
 	depends on USB_HID
@@ -190,6 +213,12 @@ config HID_MICROSOFT
 	---help---
 	Support for Microsoft devices that are not fully compliant with HID standard.
 
+config HID_MOSART
+	tristate "MosArt"
+	depends on USB_HID
+	---help---
+	Support for MosArt dual-touch panels.
+
 config HID_MONTEREY
 	tristate "Monterey" if EMBEDDED
 	depends on USB_HID
@@ -198,12 +227,18 @@ config HID_MONTEREY
 	Support for Monterey Genius KB29E.
 
 config HID_NTRIG
-	tristate "NTrig" if EMBEDDED
+	tristate "NTrig"
 	depends on USB_HID
-	default !EMBEDDED
 	---help---
 	Support for N-Trig touch screen.
 
+config HID_ORTEK
+	tristate "Ortek" if EMBEDDED
+	depends on USB_HID
+	default !EMBEDDED
+	---help---
+	Support for Ortek WKB-2000 wireless keyboard + mouse trackpad.
+
 config HID_PANTHERLORD
 	tristate "Pantherlord support" if EMBEDDED
 	depends on USB_HID
@@ -227,6 +262,12 @@ config HID_PETALYNX
 	---help---
 	Support for Petalynx Maxter remote control.
 
+config HID_QUANTA
+	tristate "Quanta Optical Touch"
+	depends on USB_HID
+	---help---
+	Support for Quanta Optical Touch dual-touch panels.
+
 config HID_SAMSUNG
 	tristate "Samsung" if EMBEDDED
 	depends on USB_HID
@@ -241,6 +282,12 @@ config HID_SONY
 	---help---
 	Support for Sony PS3 controller.
 
+config HID_STANTUM
+	tristate "Stantum"
+	depends on USB_HID
+	---help---
+	Support for Stantum multitouch panel.
+
 config HID_SUNPLUS
 	tristate "Sunplus" if EMBEDDED
 	depends on USB_HID
@@ -305,9 +352,8 @@ config THRUSTMASTER_FF
 	  Rumble Force or Force Feedback Wheel.
 
 config HID_WACOM
-	tristate "Wacom Bluetooth devices support" if EMBEDDED
+	tristate "Wacom Bluetooth devices support"
 	depends on BT_HIDP
-	default !EMBEDDED
 	---help---
 	Support for Wacom Graphire Bluetooth tablet.
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/Makefile linux-libre-2.6.34-gnu1/drivers/hid/Makefile
--- linux-libre-2.6.33-gnu1/drivers/hid/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,11 @@ endif
 ifdef CONFIG_LOGIRUMBLEPAD2_FF
 	hid-logitech-objs	+= hid-lg2ff.o
 endif
+ifdef CONFIG_LOGIG940_FF
+	hid-logitech-objs	+= hid-lg3ff.o
+endif
 
+obj-$(CONFIG_HID_3M_PCT)	+= hid-3m-pct.o
 obj-$(CONFIG_HID_A4TECH)	+= hid-a4tech.o
 obj-$(CONFIG_HID_APPLE)		+= hid-apple.o
 obj-$(CONFIG_HID_BELKIN)	+= hid-belkin.o
@@ -31,14 +35,19 @@ obj-$(CONFIG_HID_GYRATION)	+= hid-gyrati
 obj-$(CONFIG_HID_KENSINGTON)	+= hid-kensington.o
 obj-$(CONFIG_HID_KYE)		+= hid-kye.o
 obj-$(CONFIG_HID_LOGITECH)	+= hid-logitech.o
+obj-$(CONFIG_HID_MAGICMOUSE)    += hid-magicmouse.o
 obj-$(CONFIG_HID_MICROSOFT)	+= hid-microsoft.o
 obj-$(CONFIG_HID_MONTEREY)	+= hid-monterey.o
+obj-$(CONFIG_HID_MOSART)	+= hid-mosart.o
 obj-$(CONFIG_HID_NTRIG)		+= hid-ntrig.o
+obj-$(CONFIG_HID_ORTEK)		+= hid-ortek.o
+obj-$(CONFIG_HID_QUANTA)	+= hid-quanta.o
 obj-$(CONFIG_HID_PANTHERLORD)	+= hid-pl.o
 obj-$(CONFIG_HID_PETALYNX)	+= hid-petalynx.o
 obj-$(CONFIG_HID_SAMSUNG)	+= hid-samsung.o
 obj-$(CONFIG_HID_SMARTJOYPLUS)	+= hid-sjoy.o
 obj-$(CONFIG_HID_SONY)		+= hid-sony.o
+obj-$(CONFIG_HID_STANTUM)	+= hid-stantum.o
 obj-$(CONFIG_HID_SUNPLUS)	+= hid-sunplus.o
 obj-$(CONFIG_HID_GREENASIA)	+= hid-gaff.o
 obj-$(CONFIG_HID_THRUSTMASTER)	+= hid-tmff.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hid-core.c linux-libre-2.6.34-gnu1/drivers/hid/usbhid/hid-core.c
--- linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hid-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/usbhid/hid-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +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) 2007-2008 Oliver Neukum
- *  Copyright (c) 2006-2009 Jiri Kosina
+ *  Copyright (c) 2006-2010 Jiri Kosina
  */
 
 /*
@@ -316,6 +316,7 @@ static int hid_submit_out(struct hid_dev
 			err_hid("usb_submit_urb(out) failed");
 			return -1;
 		}
+		usbhid->last_out = jiffies;
 	} else {
 		/*
 		 * queue work to wake up the device.
@@ -377,6 +378,7 @@ static int hid_submit_ctrl(struct hid_de
 			err_hid("usb_submit_urb(ctrl) failed");
 			return -1;
 		}
+		usbhid->last_ctrl = jiffies;
 	} else {
 		/*
 		 * queue work to wake up the device.
@@ -512,9 +514,20 @@ static void __usbhid_submit_report(struc
 		usbhid->out[usbhid->outhead].report = report;
 		usbhid->outhead = head;
 
-		if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl))
+		if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) {
 			if (hid_submit_out(hid))
 				clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
+		} else {
+			/*
+			 * the queue is known to run
+			 * but an earlier request may be stuck
+			 * we may need to time out
+			 * no race because this is called under
+			 * spinlock
+			 */
+			if (time_after(jiffies, usbhid->last_out + HZ * 5))
+				usb_unlink_urb(usbhid->urbout);
+		}
 		return;
 	}
 
@@ -535,9 +548,20 @@ static void __usbhid_submit_report(struc
 	usbhid->ctrl[usbhid->ctrlhead].dir = dir;
 	usbhid->ctrlhead = head;
 
-	if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl))
+	if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) {
 		if (hid_submit_ctrl(hid))
 			clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
+	} else {
+		/*
+		 * the queue is known to run
+		 * but an earlier request may be stuck
+		 * we may need to time out
+		 * no race because this is called under
+		 * spinlock
+		 */
+		if (time_after(jiffies, usbhid->last_ctrl + HZ * 5))
+			usb_unlink_urb(usbhid->urbctrl);
+	}
 }
 
 void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
@@ -774,7 +798,8 @@ static int hid_alloc_buffers(struct usb_
 	return 0;
 }
 
-static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count)
+static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count,
+		unsigned char report_type)
 {
 	struct usbhid_device *usbhid = hid->driver_data;
 	struct usb_device *dev = hid_to_usb_dev(hid);
@@ -785,7 +810,7 @@ static int usbhid_output_raw_report(stru
 	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 		HID_REQ_SET_REPORT,
 		USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-		((HID_OUTPUT_REPORT + 1) << 8) | *buf,
+		((report_type + 1) << 8) | *buf,
 		interface->desc.bInterfaceNumber, buf + 1, count - 1,
 		USB_CTRL_SET_TIMEOUT);
 
@@ -974,16 +999,6 @@ 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->lock);
-
-	usbhid->intf = intf;
-	usbhid->ifnum = interface->desc.bInterfaceNumber;
-
 	usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
 	if (!usbhid->urbctrl) {
 		ret = -ENOMEM;
@@ -1154,6 +1169,14 @@ static int usbhid_probe(struct usb_inter
 
 	hid->driver_data = usbhid;
 	usbhid->hid = hid;
+	usbhid->intf = intf;
+	usbhid->ifnum = interface->desc.bInterfaceNumber;
+
+	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->lock);
 
 	ret = hid_add_device(hid);
 	if (ret) {
@@ -1342,7 +1365,7 @@ static int hid_reset_resume(struct usb_i
 
 #endif /* CONFIG_PM */
 
-static struct usb_device_id hid_usb_ids [] = {
+static const struct usb_device_id hid_usb_ids[] = {
 	{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
 		.bInterfaceClass = USB_INTERFACE_CLASS_HID },
 	{ }						/* Terminating entry */
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hiddev.c linux-libre-2.6.34-gnu1/drivers/hid/usbhid/hiddev.c
--- linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hiddev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/usbhid/hiddev.c	2010-05-16 17:17:36.000000000 -0400
@@ -265,9 +265,10 @@ static int hiddev_release(struct inode *
 static int hiddev_open(struct inode *inode, struct file *file)
 {
 	struct hiddev_list *list;
-	int res;
+	int res, i;
 
-	int i = iminor(inode) - HIDDEV_MINOR_BASE;
+	lock_kernel();
+	i = iminor(inode) - HIDDEV_MINOR_BASE;
 
 	if (i >= HIDDEV_MINORS || i < 0 || !hiddev_table[i])
 		return -ENODEV;
@@ -313,10 +314,12 @@ static int hiddev_open(struct inode *ino
 			usbhid_open(hid);
 		}
 
+	unlock_kernel();
 	return 0;
 bail:
 	file->private_data = NULL;
 	kfree(list);
+	unlock_kernel();
 	return res;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hid-pidff.c linux-libre-2.6.34-gnu1/drivers/hid/usbhid/hid-pidff.c
--- linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hid-pidff.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/usbhid/hid-pidff.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #define debug(format, arg...) pr_debug("hid-pidff: " format "\n" , ## arg)
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include <linux/hid.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hid-quirks.c linux-libre-2.6.34-gnu1/drivers/hid/usbhid/hid-quirks.c
--- linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hid-quirks.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/usbhid/hid-quirks.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
  */
 
 #include <linux/hid.h>
+#include <linux/slab.h>
 
 #include "../hid-ids.h"
 
@@ -43,8 +44,10 @@ static const struct hid_blacklist {
 
 	{ USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL },
 
+	{ USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
 	{ USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT },
+	{ USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT },
 
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
@@ -57,9 +60,12 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT },
+	{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
 	{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hid/usbhid/usbhid.h linux-libre-2.6.34-gnu1/drivers/hid/usbhid/usbhid.h
--- linux-libre-2.6.33-gnu1/drivers/hid/usbhid/usbhid.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hid/usbhid/usbhid.h	2010-05-16 17:17:36.000000000 -0400
@@ -80,12 +80,14 @@ struct usbhid_device {
 	unsigned char ctrlhead, ctrltail;                               /* Control fifo head & tail */
 	char *ctrlbuf;                                                  /* Control buffer */
 	dma_addr_t ctrlbuf_dma;                                         /* Control buffer dma */
+	unsigned long last_ctrl;						/* record of last output for timeouts */
 
 	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 */
+	unsigned long last_out;							/* record of last output for timeouts */
 
 	spinlock_t lock;						/* fifo spinlock */
 	unsigned long iofl;                                             /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/ad7414.c linux-libre-2.6.34-gnu1/drivers/hwmon/ad7414.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/ad7414.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/ad7414.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 
 
 /* AD7414 registers */
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/ad7418.c linux-libre-2.6.34-gnu1/drivers/hwmon/ad7418.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/ad7418.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/ad7418.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "lm75.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/adcxx.c linux-libre-2.6.34-gnu1/drivers/hwmon/adcxx.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/adcxx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/adcxx.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/sysfs.h>
@@ -62,18 +63,23 @@ static ssize_t adcxx_read(struct device
 	struct spi_device *spi = to_spi_device(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct adcxx *adc = dev_get_drvdata(&spi->dev);
-	u8 tx_buf[2] = { attr->index << 3 }; /* other bits are don't care */
+	u8 tx_buf[2];
 	u8 rx_buf[2];
 	int status;
-	int value;
+	u32 value;
 
 	if (mutex_lock_interruptible(&adc->lock))
 		return -ERESTARTSYS;
 
-	status = spi_write_then_read(spi, tx_buf, sizeof(tx_buf),
-					rx_buf, sizeof(rx_buf));
+	if (adc->channels == 1) {
+		status = spi_read(spi, rx_buf, sizeof(rx_buf));
+	} else {
+		tx_buf[0] = attr->index << 3; /* other bits are don't care */
+		status = spi_write_then_read(spi, tx_buf, sizeof(tx_buf),
+						rx_buf, sizeof(rx_buf));
+	}
 	if (status < 0) {
-		dev_warn(dev, "spi_write_then_read failed with status %d\n",
+		dev_warn(dev, "SPI synch. transfer failed with status %d\n",
 				status);
 		goto out;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/adt7411.c linux-libre-2.6.34-gnu1/drivers/hwmon/adt7411.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/adt7411.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/adt7411.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,367 @@
+/*
+ *  Driver for the ADT7411 (I2C/SPI 8 channel 10 bit ADC & temperature-sensor)
+ *
+ *  Copyright (C) 2008, 2010 Pengutronix
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  TODO: SPI, support for external temperature sensor
+ * 	  use power-down mode for suspend?, interrupt handling?
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/slab.h>
+
+#define ADT7411_REG_INT_TEMP_VDD_LSB		0x03
+#define ADT7411_REG_EXT_TEMP_AIN14_LSB		0x04
+#define ADT7411_REG_VDD_MSB			0x06
+#define ADT7411_REG_INT_TEMP_MSB		0x07
+#define ADT7411_REG_EXT_TEMP_AIN1_MSB		0x08
+
+#define ADT7411_REG_CFG1			0x18
+#define ADT7411_CFG1_START_MONITOR		(1 << 0)
+
+#define ADT7411_REG_CFG2			0x19
+#define ADT7411_CFG2_DISABLE_AVG		(1 << 5)
+
+#define ADT7411_REG_CFG3			0x1a
+#define ADT7411_CFG3_ADC_CLK_225		(1 << 0)
+#define ADT7411_CFG3_REF_VDD			(1 << 4)
+
+#define ADT7411_REG_DEVICE_ID			0x4d
+#define ADT7411_REG_MANUFACTURER_ID		0x4e
+
+#define ADT7411_DEVICE_ID			0x2
+#define ADT7411_MANUFACTURER_ID			0x41
+
+static const unsigned short normal_i2c[] = { 0x48, 0x4a, 0x4b, I2C_CLIENT_END };
+
+struct adt7411_data {
+	struct mutex device_lock;	/* for "atomic" device accesses */
+	struct mutex update_lock;
+	unsigned long next_update;
+	int vref_cached;
+	struct device *hwmon_dev;
+};
+
+/*
+ * When reading a register containing (up to 4) lsb, all associated
+ * msb-registers get locked by the hardware. After _one_ of those msb is read,
+ * _all_ are unlocked. In order to use this locking correctly, reading lsb/msb
+ * is protected here with a mutex, too.
+ */
+static int adt7411_read_10_bit(struct i2c_client *client, u8 lsb_reg,
+				u8 msb_reg, u8 lsb_shift)
+{
+	struct adt7411_data *data = i2c_get_clientdata(client);
+	int val, tmp;
+
+	mutex_lock(&data->device_lock);
+
+	val = i2c_smbus_read_byte_data(client, lsb_reg);
+	if (val < 0)
+		goto exit_unlock;
+
+	tmp = (val >> lsb_shift) & 3;
+	val = i2c_smbus_read_byte_data(client, msb_reg);
+
+	if (val >= 0)
+		val = (val << 2) | tmp;
+
+ exit_unlock:
+	mutex_unlock(&data->device_lock);
+
+	return val;
+}
+
+static int adt7411_modify_bit(struct i2c_client *client, u8 reg, u8 bit,
+				bool flag)
+{
+	struct adt7411_data *data = i2c_get_clientdata(client);
+	int ret, val;
+
+	mutex_lock(&data->device_lock);
+
+	ret = i2c_smbus_read_byte_data(client, reg);
+	if (ret < 0)
+		goto exit_unlock;
+
+	if (flag)
+		val = ret | bit;
+	else
+		val = ret & ~bit;
+
+	ret = i2c_smbus_write_byte_data(client, reg, val);
+
+ exit_unlock:
+	mutex_unlock(&data->device_lock);
+	return ret;
+}
+
+static ssize_t adt7411_show_vdd(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	int ret = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB,
+			ADT7411_REG_VDD_MSB, 2);
+
+	return ret < 0 ? ret : sprintf(buf, "%u\n", ret * 7000 / 1024);
+}
+
+static ssize_t adt7411_show_temp(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	int val = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB,
+			ADT7411_REG_INT_TEMP_MSB, 0);
+
+	if (val < 0)
+		return val;
+
+	val = val & 0x200 ? val - 0x400 : val; /* 10 bit signed */
+
+	return sprintf(buf, "%d\n", val * 250);
+}
+
+static ssize_t adt7411_show_input(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	int nr = to_sensor_dev_attr(attr)->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adt7411_data *data = i2c_get_clientdata(client);
+	int val;
+	u8 lsb_reg, lsb_shift;
+
+	mutex_lock(&data->update_lock);
+	if (time_after_eq(jiffies, data->next_update)) {
+		val = i2c_smbus_read_byte_data(client, ADT7411_REG_CFG3);
+		if (val < 0)
+			goto exit_unlock;
+
+		if (val & ADT7411_CFG3_REF_VDD) {
+			val = adt7411_read_10_bit(client,
+					ADT7411_REG_INT_TEMP_VDD_LSB,
+					ADT7411_REG_VDD_MSB, 2);
+			if (val < 0)
+				goto exit_unlock;
+
+			data->vref_cached = val * 7000 / 1024;
+		} else {
+			data->vref_cached = 2250;
+		}
+
+		data->next_update = jiffies + HZ;
+	}
+
+	lsb_reg = ADT7411_REG_EXT_TEMP_AIN14_LSB + (nr >> 2);
+	lsb_shift = 2 * (nr & 0x03);
+	val = adt7411_read_10_bit(client, lsb_reg,
+			ADT7411_REG_EXT_TEMP_AIN1_MSB + nr, lsb_shift);
+	if (val < 0)
+		goto exit_unlock;
+
+	val = sprintf(buf, "%u\n", val * data->vref_cached / 1024);
+ exit_unlock:
+	mutex_unlock(&data->update_lock);
+	return val;
+}
+
+static ssize_t adt7411_show_bit(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	int ret = i2c_smbus_read_byte_data(client, attr2->index);
+
+	return ret < 0 ? ret : sprintf(buf, "%u\n", !!(ret & attr2->nr));
+}
+
+static ssize_t adt7411_set_bit(struct device *dev,
+			       struct device_attribute *attr, const char *buf,
+			       size_t count)
+{
+	struct sensor_device_attribute_2 *s_attr2 = to_sensor_dev_attr_2(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adt7411_data *data = i2c_get_clientdata(client);
+	int ret;
+	unsigned long flag;
+
+	ret = strict_strtoul(buf, 0, &flag);
+	if (ret || flag > 1)
+		return -EINVAL;
+
+	ret = adt7411_modify_bit(client, s_attr2->index, s_attr2->nr, flag);
+
+	/* force update */
+	mutex_lock(&data->update_lock);
+	data->next_update = jiffies;
+	mutex_unlock(&data->update_lock);
+
+	return ret < 0 ? ret : count;
+}
+
+#define ADT7411_BIT_ATTR(__name, __reg, __bit) \
+	SENSOR_DEVICE_ATTR_2(__name, S_IRUGO | S_IWUSR, adt7411_show_bit, \
+	adt7411_set_bit, __bit, __reg)
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, adt7411_show_temp, NULL);
+static DEVICE_ATTR(in0_input, S_IRUGO, adt7411_show_vdd, NULL);
+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, adt7411_show_input, NULL, 0);
+static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, adt7411_show_input, NULL, 1);
+static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, adt7411_show_input, NULL, 2);
+static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, adt7411_show_input, NULL, 3);
+static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, adt7411_show_input, NULL, 4);
+static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, adt7411_show_input, NULL, 5);
+static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, adt7411_show_input, NULL, 6);
+static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, adt7411_show_input, NULL, 7);
+static ADT7411_BIT_ATTR(no_average, ADT7411_REG_CFG2, ADT7411_CFG2_DISABLE_AVG);
+static ADT7411_BIT_ATTR(fast_sampling, ADT7411_REG_CFG3, ADT7411_CFG3_ADC_CLK_225);
+static ADT7411_BIT_ATTR(adc_ref_vdd, ADT7411_REG_CFG3, ADT7411_CFG3_REF_VDD);
+
+static struct attribute *adt7411_attrs[] = {
+	&dev_attr_temp1_input.attr,
+	&dev_attr_in0_input.attr,
+	&sensor_dev_attr_in1_input.dev_attr.attr,
+	&sensor_dev_attr_in2_input.dev_attr.attr,
+	&sensor_dev_attr_in3_input.dev_attr.attr,
+	&sensor_dev_attr_in4_input.dev_attr.attr,
+	&sensor_dev_attr_in5_input.dev_attr.attr,
+	&sensor_dev_attr_in6_input.dev_attr.attr,
+	&sensor_dev_attr_in7_input.dev_attr.attr,
+	&sensor_dev_attr_in8_input.dev_attr.attr,
+	&sensor_dev_attr_no_average.dev_attr.attr,
+	&sensor_dev_attr_fast_sampling.dev_attr.attr,
+	&sensor_dev_attr_adc_ref_vdd.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group adt7411_attr_grp = {
+	.attrs = adt7411_attrs,
+};
+
+static int adt7411_detect(struct i2c_client *client,
+			  struct i2c_board_info *info)
+{
+	int val;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	val = i2c_smbus_read_byte_data(client, ADT7411_REG_MANUFACTURER_ID);
+	if (val < 0 || val != ADT7411_MANUFACTURER_ID) {
+		dev_dbg(&client->dev, "Wrong manufacturer ID. Got %d, "
+			"expected %d\n", val, ADT7411_MANUFACTURER_ID);
+		return -ENODEV;
+	}
+
+	val = i2c_smbus_read_byte_data(client, ADT7411_REG_DEVICE_ID);
+	if (val < 0 || val != ADT7411_DEVICE_ID) {
+		dev_dbg(&client->dev, "Wrong device ID. Got %d, "
+			"expected %d\n", val, ADT7411_DEVICE_ID);
+		return -ENODEV;
+	}
+
+	strlcpy(info->type, "adt7411", I2C_NAME_SIZE);
+
+	return 0;
+}
+
+static int __devinit adt7411_probe(struct i2c_client *client,
+				   const struct i2c_device_id *id)
+{
+	struct adt7411_data *data;
+	int ret;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, data);
+	mutex_init(&data->device_lock);
+	mutex_init(&data->update_lock);
+
+	ret = adt7411_modify_bit(client, ADT7411_REG_CFG1,
+				 ADT7411_CFG1_START_MONITOR, 1);
+	if (ret < 0)
+		goto exit_free;
+
+	/* force update on first occasion */
+	data->next_update = jiffies;
+
+	ret = sysfs_create_group(&client->dev.kobj, &adt7411_attr_grp);
+	if (ret)
+		goto exit_free;
+
+	data->hwmon_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		ret = PTR_ERR(data->hwmon_dev);
+		goto exit_remove;
+	}
+
+	dev_info(&client->dev, "successfully registered\n");
+
+	return 0;
+
+ exit_remove:
+	sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
+ exit_free:
+	i2c_set_clientdata(client, NULL);
+	kfree(data);
+	return ret;
+}
+
+static int __devexit adt7411_remove(struct i2c_client *client)
+{
+	struct adt7411_data *data = i2c_get_clientdata(client);
+
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
+	i2c_set_clientdata(client, NULL);
+	kfree(data);
+	return 0;
+}
+
+static const struct i2c_device_id adt7411_id[] = {
+	{ "adt7411", 0 },
+	{ }
+};
+
+static struct i2c_driver adt7411_driver = {
+	.driver		= {
+		.name		= "adt7411",
+	},
+	.probe  = adt7411_probe,
+	.remove	= __devexit_p(adt7411_remove),
+	.id_table = adt7411_id,
+	.detect = adt7411_detect,
+	.address_list = normal_i2c,
+	.class = I2C_CLASS_HWMON,
+};
+
+static int __init sensors_adt7411_init(void)
+{
+	return i2c_add_driver(&adt7411_driver);
+}
+module_init(sensors_adt7411_init)
+
+static void __exit sensors_adt7411_exit(void)
+{
+	i2c_del_driver(&adt7411_driver);
+}
+module_exit(sensors_adt7411_exit)
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de> and "
+	"Wolfram Sang <w.sang@pengutronix.de>");
+MODULE_DESCRIPTION("ADT7411 driver");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/adt7462.c linux-libre-2.6.34-gnu1/drivers/hwmon/adt7462.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/adt7462.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/adt7462.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END };
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/adt7470.c linux-libre-2.6.34-gnu1/drivers/hwmon/adt7470.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/adt7470.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/adt7470.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/delay.h>
 #include <linux/log2.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END };
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/adt7473.c linux-libre-2.6.34-gnu1/drivers/hwmon/adt7473.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/adt7473.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/adt7473.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1180 +0,0 @@
-/*
- * A hwmon driver for the Analog Devices ADT7473
- * Copyright (C) 2007 IBM
- *
- * Author: Darrick J. Wong <djwong@us.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You 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/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/delay.h>
-#include <linux/log2.h>
-
-/* Addresses to scan */
-static const unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, I2C_CLIENT_END };
-
-/* ADT7473 registers */
-#define ADT7473_REG_BASE_ADDR			0x20
-
-#define ADT7473_REG_VOLT_BASE_ADDR		0x21
-#define ADT7473_REG_VOLT_MIN_BASE_ADDR		0x46
-
-#define ADT7473_REG_TEMP_BASE_ADDR		0x25
-#define ADT7473_REG_TEMP_LIMITS_BASE_ADDR	0x4E
-#define ADT7473_REG_TEMP_TMIN_BASE_ADDR		0x67
-#define ADT7473_REG_TEMP_TMAX_BASE_ADDR		0x6A
-
-#define ADT7473_REG_FAN_BASE_ADDR		0x28
-#define ADT7473_REG_FAN_MIN_BASE_ADDR		0x54
-
-#define ADT7473_REG_PWM_BASE_ADDR		0x30
-#define	ADT7473_REG_PWM_MIN_BASE_ADDR		0x64
-#define ADT7473_REG_PWM_MAX_BASE_ADDR		0x38
-#define ADT7473_REG_PWM_BHVR_BASE_ADDR		0x5C
-#define		ADT7473_PWM_BHVR_MASK		0xE0
-#define		ADT7473_PWM_BHVR_SHIFT		5
-
-#define ADT7473_REG_CFG1			0x40
-#define 	ADT7473_CFG1_START		0x01
-#define		ADT7473_CFG1_READY		0x04
-#define ADT7473_REG_CFG2			0x73
-#define ADT7473_REG_CFG3			0x78
-#define ADT7473_REG_CFG4			0x7D
-#define		ADT7473_CFG4_MAX_DUTY_AT_OVT	0x08
-#define ADT7473_REG_CFG5			0x7C
-#define		ADT7473_CFG5_TEMP_TWOS		0x01
-#define		ADT7473_CFG5_TEMP_OFFSET	0x02
-
-#define ADT7473_REG_DEVICE			0x3D
-#define 	ADT7473_VENDOR			0x41
-#define ADT7473_REG_VENDOR			0x3E
-#define 	ADT7473_DEVICE			0x73
-#define ADT7473_REG_REVISION			0x3F
-#define 	ADT7473_REV_68			0x68
-#define 	ADT7473_REV_69			0x69
-
-#define ADT7473_REG_ALARM1			0x41
-#define		ADT7473_VCCP_ALARM		0x02
-#define		ADT7473_VCC_ALARM		0x04
-#define		ADT7473_R1T_ALARM		0x10
-#define		ADT7473_LT_ALARM		0x20
-#define		ADT7473_R2T_ALARM		0x40
-#define		ADT7473_OOL			0x80
-#define ADT7473_REG_ALARM2			0x42
-#define		ADT7473_OVT_ALARM		0x02
-#define		ADT7473_FAN1_ALARM		0x04
-#define		ADT7473_FAN2_ALARM		0x08
-#define		ADT7473_FAN3_ALARM		0x10
-#define		ADT7473_FAN4_ALARM		0x20
-#define		ADT7473_R1T_SHORT		0x40
-#define		ADT7473_R2T_SHORT		0x80
-
-#define ALARM2(x)	((x) << 8)
-
-#define ADT7473_VOLT_COUNT	2
-#define ADT7473_REG_VOLT(x)	(ADT7473_REG_VOLT_BASE_ADDR + (x))
-#define ADT7473_REG_VOLT_MIN(x)	(ADT7473_REG_VOLT_MIN_BASE_ADDR + ((x) * 2))
-#define ADT7473_REG_VOLT_MAX(x)	(ADT7473_REG_VOLT_MIN_BASE_ADDR + \
-				((x) * 2) + 1)
-
-#define ADT7473_TEMP_COUNT	3
-#define ADT7473_REG_TEMP(x)	(ADT7473_REG_TEMP_BASE_ADDR + (x))
-#define ADT7473_REG_TEMP_MIN(x) (ADT7473_REG_TEMP_LIMITS_BASE_ADDR + ((x) * 2))
-#define ADT7473_REG_TEMP_MAX(x) (ADT7473_REG_TEMP_LIMITS_BASE_ADDR + \
-				((x) * 2) + 1)
-#define ADT7473_REG_TEMP_TMIN(x)	(ADT7473_REG_TEMP_TMIN_BASE_ADDR + (x))
-#define ADT7473_REG_TEMP_TMAX(x)	(ADT7473_REG_TEMP_TMAX_BASE_ADDR + (x))
-
-#define ADT7473_FAN_COUNT	4
-#define ADT7473_REG_FAN(x)	(ADT7473_REG_FAN_BASE_ADDR + ((x) * 2))
-#define ADT7473_REG_FAN_MIN(x)	(ADT7473_REG_FAN_MIN_BASE_ADDR + ((x) * 2))
-
-#define ADT7473_PWM_COUNT	3
-#define ADT7473_REG_PWM(x)	(ADT7473_REG_PWM_BASE_ADDR + (x))
-#define ADT7473_REG_PWM_MAX(x)	(ADT7473_REG_PWM_MAX_BASE_ADDR + (x))
-#define ADT7473_REG_PWM_MIN(x)	(ADT7473_REG_PWM_MIN_BASE_ADDR + (x))
-#define ADT7473_REG_PWM_BHVR(x)	(ADT7473_REG_PWM_BHVR_BASE_ADDR + (x))
-
-/* How often do we reread sensors values? (In jiffies) */
-#define SENSOR_REFRESH_INTERVAL	(2 * HZ)
-
-/* How often do we reread sensor limit values? (In jiffies) */
-#define LIMIT_REFRESH_INTERVAL	(60 * HZ)
-
-/* datasheet says to divide this number by the fan reading to get fan rpm */
-#define FAN_PERIOD_TO_RPM(x)	((90000 * 60) / (x))
-#define FAN_RPM_TO_PERIOD	FAN_PERIOD_TO_RPM
-#define FAN_PERIOD_INVALID	65535
-#define FAN_DATA_VALID(x)	((x) && (x) != FAN_PERIOD_INVALID)
-
-struct adt7473_data {
-	struct device		*hwmon_dev;
-	struct attribute_group	attrs;
-	struct mutex		lock;
-	char			sensors_valid;
-	char			limits_valid;
-	unsigned long		sensors_last_updated;	/* In jiffies */
-	unsigned long		limits_last_updated;	/* In jiffies */
-
-	u8			volt[ADT7473_VOLT_COUNT];
-	s8			volt_min[ADT7473_VOLT_COUNT];
-	s8			volt_max[ADT7473_VOLT_COUNT];
-
-	s8			temp[ADT7473_TEMP_COUNT];
-	s8			temp_min[ADT7473_TEMP_COUNT];
-	s8			temp_max[ADT7473_TEMP_COUNT];
-	s8			temp_tmin[ADT7473_TEMP_COUNT];
-	/* This is called the !THERM limit in the datasheet */
-	s8			temp_tmax[ADT7473_TEMP_COUNT];
-
-	u16			fan[ADT7473_FAN_COUNT];
-	u16			fan_min[ADT7473_FAN_COUNT];
-
-	u8			pwm[ADT7473_PWM_COUNT];
-	u8			pwm_max[ADT7473_PWM_COUNT];
-	u8			pwm_min[ADT7473_PWM_COUNT];
-	u8			pwm_behavior[ADT7473_PWM_COUNT];
-
-	u8			temp_twos_complement;
-	u8			temp_offset;
-
-	u16			alarm;
-	u8			max_duty_at_overheat;
-};
-
-static int adt7473_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id);
-static int adt7473_detect(struct i2c_client *client,
-			  struct i2c_board_info *info);
-static int adt7473_remove(struct i2c_client *client);
-
-static const struct i2c_device_id adt7473_id[] = {
-	{ "adt7473", 0 },
-	{ }
-};
-
-static struct i2c_driver adt7473_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name	= "adt7473",
-	},
-	.probe		= adt7473_probe,
-	.remove		= adt7473_remove,
-	.id_table	= adt7473_id,
-	.detect		= adt7473_detect,
-	.address_list	= normal_i2c,
-};
-
-/*
- * 16-bit registers on the ADT7473 are low-byte first.  The data sheet says
- * that the low byte must be read before the high byte.
- */
-static inline int adt7473_read_word_data(struct i2c_client *client, u8 reg)
-{
-	u16 foo;
-	foo = i2c_smbus_read_byte_data(client, reg);
-	foo |= ((u16)i2c_smbus_read_byte_data(client, reg + 1) << 8);
-	return foo;
-}
-
-static inline int adt7473_write_word_data(struct i2c_client *client, u8 reg,
-					  u16 value)
-{
-	return i2c_smbus_write_byte_data(client, reg, value & 0xFF)
-	       && i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
-}
-
-static void adt7473_init_client(struct i2c_client *client)
-{
-	int reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG1);
-
-	if (!(reg & ADT7473_CFG1_READY)) {
-		dev_err(&client->dev, "Chip not ready.\n");
-	} else {
-		/* start monitoring */
-		i2c_smbus_write_byte_data(client, ADT7473_REG_CFG1,
-					  reg | ADT7473_CFG1_START);
-	}
-}
-
-static struct adt7473_data *adt7473_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7473_data *data = i2c_get_clientdata(client);
-	unsigned long local_jiffies = jiffies;
-	u8 cfg;
-	int i;
-
-	mutex_lock(&data->lock);
-	if (time_before(local_jiffies, data->sensors_last_updated +
-		SENSOR_REFRESH_INTERVAL)
-		&& data->sensors_valid)
-		goto no_sensor_update;
-
-	for (i = 0; i < ADT7473_VOLT_COUNT; i++)
-		data->volt[i] = i2c_smbus_read_byte_data(client,
-						ADT7473_REG_VOLT(i));
-
-	/* Determine temperature encoding */
-	cfg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG5);
-	data->temp_twos_complement = (cfg & ADT7473_CFG5_TEMP_TWOS);
-
-	/*
-	 * What does this do? it implies a variable temperature sensor
-	 * offset, but the datasheet doesn't say anything about this bit
-	 * and other parts of the datasheet imply that "offset64" mode
-	 * means that you shift temp values by -64 if the above bit was set.
-	 */
-	data->temp_offset = (cfg & ADT7473_CFG5_TEMP_OFFSET);
-
-	for (i = 0; i < ADT7473_TEMP_COUNT; i++)
-		data->temp[i] = i2c_smbus_read_byte_data(client,
-							 ADT7473_REG_TEMP(i));
-
-	for (i = 0; i < ADT7473_FAN_COUNT; i++)
-		data->fan[i] = adt7473_read_word_data(client,
-						ADT7473_REG_FAN(i));
-
-	for (i = 0; i < ADT7473_PWM_COUNT; i++)
-		data->pwm[i] = i2c_smbus_read_byte_data(client,
-						ADT7473_REG_PWM(i));
-
-	data->alarm = i2c_smbus_read_byte_data(client, ADT7473_REG_ALARM1);
-	if (data->alarm & ADT7473_OOL)
-		data->alarm |= ALARM2(i2c_smbus_read_byte_data(client,
-							 ADT7473_REG_ALARM2));
-
-	data->sensors_last_updated = local_jiffies;
-	data->sensors_valid = 1;
-
-no_sensor_update:
-	if (time_before(local_jiffies, data->limits_last_updated +
-		LIMIT_REFRESH_INTERVAL)
-		&& data->limits_valid)
-		goto out;
-
-	for (i = 0; i < ADT7473_VOLT_COUNT; i++) {
-		data->volt_min[i] = i2c_smbus_read_byte_data(client,
-						ADT7473_REG_VOLT_MIN(i));
-		data->volt_max[i] = i2c_smbus_read_byte_data(client,
-						ADT7473_REG_VOLT_MAX(i));
-	}
-
-	for (i = 0; i < ADT7473_TEMP_COUNT; i++) {
-		data->temp_min[i] = i2c_smbus_read_byte_data(client,
-						ADT7473_REG_TEMP_MIN(i));
-		data->temp_max[i] = i2c_smbus_read_byte_data(client,
-						ADT7473_REG_TEMP_MAX(i));
-		data->temp_tmin[i] = i2c_smbus_read_byte_data(client,
-						ADT7473_REG_TEMP_TMIN(i));
-		data->temp_tmax[i] = i2c_smbus_read_byte_data(client,
-						ADT7473_REG_TEMP_TMAX(i));
-	}
-
-	for (i = 0; i < ADT7473_FAN_COUNT; i++)
-		data->fan_min[i] = adt7473_read_word_data(client,
-						ADT7473_REG_FAN_MIN(i));
-
-	for (i = 0; i < ADT7473_PWM_COUNT; i++) {
-		data->pwm_max[i] = i2c_smbus_read_byte_data(client,
-						ADT7473_REG_PWM_MAX(i));
-		data->pwm_min[i] = i2c_smbus_read_byte_data(client,
-						ADT7473_REG_PWM_MIN(i));
-		data->pwm_behavior[i] = i2c_smbus_read_byte_data(client,
-						ADT7473_REG_PWM_BHVR(i));
-	}
-
-	i = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4);
-	data->max_duty_at_overheat = !!(i & ADT7473_CFG4_MAX_DUTY_AT_OVT);
-
-	data->limits_last_updated = local_jiffies;
-	data->limits_valid = 1;
-
-out:
-	mutex_unlock(&data->lock);
-	return data;
-}
-
-/*
- * Conversions
- */
-
-/* IN are scaled acording to built-in resistors */
-static const int adt7473_scaling[] = {  /* .001 Volts */
-	2250, 3300
-};
-#define SCALE(val, from, to)	(((val) * (to) + ((from) / 2)) / (from))
-
-static int decode_volt(int volt_index, u8 raw)
-{
-	return SCALE(raw, 192, adt7473_scaling[volt_index]);
-}
-
-static u8 encode_volt(int volt_index, int cooked)
-{
-	int raw = SCALE(cooked, adt7473_scaling[volt_index], 192);
-	return SENSORS_LIMIT(raw, 0, 255);
-}
-
-static ssize_t show_volt_min(struct device *dev,
-			     struct device_attribute *devattr,
-			     char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-	return sprintf(buf, "%d\n",
-		       decode_volt(attr->index, data->volt_min[attr->index]));
-}
-
-static ssize_t set_volt_min(struct device *dev,
-			    struct device_attribute *devattr,
-			    const char *buf,
-			    size_t count)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7473_data *data = i2c_get_clientdata(client);
-	long volt;
-
-	if (strict_strtol(buf, 10, &volt))
-		return -EINVAL;
-
-	volt = encode_volt(attr->index, volt);
-
-	mutex_lock(&data->lock);
-	data->volt_min[attr->index] = volt;
-	i2c_smbus_write_byte_data(client, ADT7473_REG_VOLT_MIN(attr->index),
-				  volt);
-	mutex_unlock(&data->lock);
-
-	return count;
-}
-
-static ssize_t show_volt_max(struct device *dev,
-			     struct device_attribute *devattr,
-			     char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-	return sprintf(buf, "%d\n",
-		       decode_volt(attr->index, data->volt_max[attr->index]));
-}
-
-static ssize_t set_volt_max(struct device *dev,
-			    struct device_attribute *devattr,
-			    const char *buf,
-			    size_t count)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7473_data *data = i2c_get_clientdata(client);
-	long volt;
-
-	if (strict_strtol(buf, 10, &volt))
-		return -EINVAL;
-
-	volt = encode_volt(attr->index, volt);
-
-	mutex_lock(&data->lock);
-	data->volt_max[attr->index] = volt;
-	i2c_smbus_write_byte_data(client, ADT7473_REG_VOLT_MAX(attr->index),
-				  volt);
-	mutex_unlock(&data->lock);
-
-	return count;
-}
-
-static ssize_t show_volt(struct device *dev, struct device_attribute *devattr,
-			 char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-
-	return sprintf(buf, "%d\n",
-		       decode_volt(attr->index, data->volt[attr->index]));
-}
-
-/*
- * This chip can report temperature data either as a two's complement
- * number in the range -128 to 127, or as an unsigned number that must
- * be offset by 64.
- */
-static int decode_temp(u8 twos_complement, u8 raw)
-{
-	return twos_complement ? (s8)raw : raw - 64;
-}
-
-static u8 encode_temp(u8 twos_complement, int cooked)
-{
-	u8 ret = twos_complement ? cooked & 0xFF : cooked + 64;
-	return SENSORS_LIMIT(ret, 0, 255);
-}
-
-static ssize_t show_temp_min(struct device *dev,
-			     struct device_attribute *devattr,
-			     char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-	return sprintf(buf, "%d\n", 1000 * decode_temp(
-						data->temp_twos_complement,
-						data->temp_min[attr->index]));
-}
-
-static ssize_t set_temp_min(struct device *dev,
-			    struct device_attribute *devattr,
-			    const char *buf,
-			    size_t count)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7473_data *data = i2c_get_clientdata(client);
-	long temp;
-
-	if (strict_strtol(buf, 10, &temp))
-		return -EINVAL;
-
-	temp = DIV_ROUND_CLOSEST(temp, 1000);
-	temp = encode_temp(data->temp_twos_complement, temp);
-
-	mutex_lock(&data->lock);
-	data->temp_min[attr->index] = temp;
-	i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_MIN(attr->index),
-				  temp);
-	mutex_unlock(&data->lock);
-
-	return count;
-}
-
-static ssize_t show_temp_max(struct device *dev,
-			     struct device_attribute *devattr,
-			     char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-	return sprintf(buf, "%d\n", 1000 * decode_temp(
-						data->temp_twos_complement,
-						data->temp_max[attr->index]));
-}
-
-static ssize_t set_temp_max(struct device *dev,
-			    struct device_attribute *devattr,
-			    const char *buf,
-			    size_t count)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7473_data *data = i2c_get_clientdata(client);
-	long temp;
-
-	if (strict_strtol(buf, 10, &temp))
-		return -EINVAL;
-
-	temp = DIV_ROUND_CLOSEST(temp, 1000);
-	temp = encode_temp(data->temp_twos_complement, temp);
-
-	mutex_lock(&data->lock);
-	data->temp_max[attr->index] = temp;
-	i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_MAX(attr->index),
-				  temp);
-	mutex_unlock(&data->lock);
-
-	return count;
-}
-
-static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
-			 char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-	return sprintf(buf, "%d\n", 1000 * decode_temp(
-						data->temp_twos_complement,
-						data->temp[attr->index]));
-}
-
-static ssize_t show_fan_min(struct device *dev,
-			    struct device_attribute *devattr,
-			    char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-
-	if (FAN_DATA_VALID(data->fan_min[attr->index]))
-		return sprintf(buf, "%d\n",
-			       FAN_PERIOD_TO_RPM(data->fan_min[attr->index]));
-	else
-		return sprintf(buf, "0\n");
-}
-
-static ssize_t set_fan_min(struct device *dev,
-			   struct device_attribute *devattr,
-			   const char *buf, size_t count)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7473_data *data = i2c_get_clientdata(client);
-	long temp;
-
-	if (strict_strtol(buf, 10, &temp) || !temp)
-		return -EINVAL;
-
-	temp = FAN_RPM_TO_PERIOD(temp);
-	temp = SENSORS_LIMIT(temp, 1, 65534);
-
-	mutex_lock(&data->lock);
-	data->fan_min[attr->index] = temp;
-	adt7473_write_word_data(client, ADT7473_REG_FAN_MIN(attr->index), temp);
-	mutex_unlock(&data->lock);
-
-	return count;
-}
-
-static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
-			char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-
-	if (FAN_DATA_VALID(data->fan[attr->index]))
-		return sprintf(buf, "%d\n",
-			       FAN_PERIOD_TO_RPM(data->fan[attr->index]));
-	else
-		return sprintf(buf, "0\n");
-}
-
-static ssize_t show_max_duty_at_crit(struct device *dev,
-				     struct device_attribute *devattr,
-				     char *buf)
-{
-	struct adt7473_data *data = adt7473_update_device(dev);
-	return sprintf(buf, "%d\n", data->max_duty_at_overheat);
-}
-
-static ssize_t set_max_duty_at_crit(struct device *dev,
-				    struct device_attribute *devattr,
-				    const char *buf,
-				    size_t count)
-{
-	u8 reg;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7473_data *data = i2c_get_clientdata(client);
-	long temp;
-
-	if (strict_strtol(buf, 10, &temp))
-		return -EINVAL;
-
-	mutex_lock(&data->lock);
-	data->max_duty_at_overheat = !!temp;
-	reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4);
-	if (temp)
-		reg |= ADT7473_CFG4_MAX_DUTY_AT_OVT;
-	else
-		reg &= ~ADT7473_CFG4_MAX_DUTY_AT_OVT;
-	i2c_smbus_write_byte_data(client, ADT7473_REG_CFG4, reg);
-	mutex_unlock(&data->lock);
-
-	return count;
-}
-
-static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
-			char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-	return sprintf(buf, "%d\n", data->pwm[attr->index]);
-}
-
-static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
-			const char *buf, size_t count)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7473_data *data = i2c_get_clientdata(client);
-	long temp;
-
-	if (strict_strtol(buf, 10, &temp))
-		return -EINVAL;
-
-	temp = SENSORS_LIMIT(temp, 0, 255);
-
-	mutex_lock(&data->lock);
-	data->pwm[attr->index] = temp;
-	i2c_smbus_write_byte_data(client, ADT7473_REG_PWM(attr->index), temp);
-	mutex_unlock(&data->lock);
-
-	return count;
-}
-
-static ssize_t show_pwm_max(struct device *dev,
-			    struct device_attribute *devattr,
-			    char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-	return sprintf(buf, "%d\n", data->pwm_max[attr->index]);
-}
-
-static ssize_t set_pwm_max(struct device *dev,
-			   struct device_attribute *devattr,
-			   const char *buf,
-			   size_t count)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7473_data *data = i2c_get_clientdata(client);
-	long temp;
-
-	if (strict_strtol(buf, 10, &temp))
-		return -EINVAL;
-
-	temp = SENSORS_LIMIT(temp, 0, 255);
-
-	mutex_lock(&data->lock);
-	data->pwm_max[attr->index] = temp;
-	i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_MAX(attr->index),
-				  temp);
-	mutex_unlock(&data->lock);
-
-	return count;
-}
-
-static ssize_t show_pwm_min(struct device *dev,
-			    struct device_attribute *devattr,
-			    char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-	return sprintf(buf, "%d\n", data->pwm_min[attr->index]);
-}
-
-static ssize_t set_pwm_min(struct device *dev,
-			   struct device_attribute *devattr,
-			   const char *buf,
-			   size_t count)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7473_data *data = i2c_get_clientdata(client);
-	long temp;
-
-	if (strict_strtol(buf, 10, &temp))
-		return -EINVAL;
-
-	temp = SENSORS_LIMIT(temp, 0, 255);
-
-	mutex_lock(&data->lock);
-	data->pwm_min[attr->index] = temp;
-	i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_MIN(attr->index),
-				  temp);
-	mutex_unlock(&data->lock);
-
-	return count;
-}
-
-static ssize_t show_temp_tmax(struct device *dev,
-			      struct device_attribute *devattr,
-			      char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-	return sprintf(buf, "%d\n", 1000 * decode_temp(
-						data->temp_twos_complement,
-						data->temp_tmax[attr->index]));
-}
-
-static ssize_t set_temp_tmax(struct device *dev,
-			     struct device_attribute *devattr,
-			     const char *buf,
-			     size_t count)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7473_data *data = i2c_get_clientdata(client);
-	long temp;
-
-	if (strict_strtol(buf, 10, &temp))
-		return -EINVAL;
-
-	temp = DIV_ROUND_CLOSEST(temp, 1000);
-	temp = encode_temp(data->temp_twos_complement, temp);
-
-	mutex_lock(&data->lock);
-	data->temp_tmax[attr->index] = temp;
-	i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_TMAX(attr->index),
-				  temp);
-	mutex_unlock(&data->lock);
-
-	return count;
-}
-
-static ssize_t show_temp_tmin(struct device *dev,
-			      struct device_attribute *devattr,
-			      char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-	return sprintf(buf, "%d\n", 1000 * decode_temp(
-						data->temp_twos_complement,
-						data->temp_tmin[attr->index]));
-}
-
-static ssize_t set_temp_tmin(struct device *dev,
-			     struct device_attribute *devattr,
-			     const char *buf,
-			     size_t count)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7473_data *data = i2c_get_clientdata(client);
-	long temp;
-
-	if (strict_strtol(buf, 10, &temp))
-		return -EINVAL;
-
-	temp = DIV_ROUND_CLOSEST(temp, 1000);
-	temp = encode_temp(data->temp_twos_complement, temp);
-
-	mutex_lock(&data->lock);
-	data->temp_tmin[attr->index] = temp;
-	i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_TMIN(attr->index),
-				  temp);
-	mutex_unlock(&data->lock);
-
-	return count;
-}
-
-static ssize_t show_pwm_enable(struct device *dev,
-			       struct device_attribute *devattr,
-			       char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-
-	switch (data->pwm_behavior[attr->index] >> ADT7473_PWM_BHVR_SHIFT) {
-	case 3:
-		return sprintf(buf, "0\n");
-	case 7:
-		return sprintf(buf, "1\n");
-	default:
-		return sprintf(buf, "2\n");
-	}
-}
-
-static ssize_t set_pwm_enable(struct device *dev,
-			      struct device_attribute *devattr,
-			      const char *buf,
-			      size_t count)
-{
-	u8 reg;
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7473_data *data = i2c_get_clientdata(client);
-	long temp;
-
-	if (strict_strtol(buf, 10, &temp))
-		return -EINVAL;
-
-	switch (temp) {
-	case 0:
-		temp = 3;
-		break;
-	case 1:
-		temp = 7;
-		break;
-	case 2:
-		/* Enter automatic mode with fans off */
-		temp = 4;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	mutex_lock(&data->lock);
-	reg = i2c_smbus_read_byte_data(client,
-				       ADT7473_REG_PWM_BHVR(attr->index));
-	reg = (temp << ADT7473_PWM_BHVR_SHIFT) |
-	      (reg & ~ADT7473_PWM_BHVR_MASK);
-	i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_BHVR(attr->index),
-				  reg);
-	data->pwm_behavior[attr->index] = reg;
-	mutex_unlock(&data->lock);
-
-	return count;
-}
-
-static ssize_t show_pwm_auto_temp(struct device *dev,
-				  struct device_attribute *devattr,
-				  char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-	int bhvr = data->pwm_behavior[attr->index] >> ADT7473_PWM_BHVR_SHIFT;
-
-	switch (bhvr) {
-	case 3:
-	case 4:
-	case 7:
-		return sprintf(buf, "0\n");
-	case 0:
-	case 1:
-	case 5:
-	case 6:
-		return sprintf(buf, "%d\n", bhvr + 1);
-	case 2:
-		return sprintf(buf, "4\n");
-	}
-	/* shouldn't ever get here */
-	BUG();
-}
-
-static ssize_t set_pwm_auto_temp(struct device *dev,
-				 struct device_attribute *devattr,
-				 const char *buf,
-				 size_t count)
-{
-	u8 reg;
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7473_data *data = i2c_get_clientdata(client);
-	long temp;
-
-	if (strict_strtol(buf, 10, &temp))
-		return -EINVAL;
-
-	switch (temp) {
-	case 1:
-	case 2:
-	case 6:
-	case 7:
-		temp--;
-		break;
-	case 0:
-		temp = 4;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	mutex_lock(&data->lock);
-	reg = i2c_smbus_read_byte_data(client,
-				       ADT7473_REG_PWM_BHVR(attr->index));
-	reg = (temp << ADT7473_PWM_BHVR_SHIFT) |
-	      (reg & ~ADT7473_PWM_BHVR_MASK);
-	i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_BHVR(attr->index),
-				  reg);
-	data->pwm_behavior[attr->index] = reg;
-	mutex_unlock(&data->lock);
-
-	return count;
-}
-
-static ssize_t show_alarm(struct device *dev,
-			  struct device_attribute *devattr,
-			  char *buf)
-{
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7473_data *data = adt7473_update_device(dev);
-
-	if (data->alarm & attr->index)
-		return sprintf(buf, "1\n");
-	else
-		return sprintf(buf, "0\n");
-}
-
-
-static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, show_volt_max,
-			  set_volt_max, 0);
-static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, show_volt_max,
-			  set_volt_max, 1);
-
-static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, show_volt_min,
-			  set_volt_min, 0);
-static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, show_volt_min,
-			  set_volt_min, 1);
-
-static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_volt, NULL, 0);
-static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_volt, NULL, 1);
-
-static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL,
-			  ADT7473_VCCP_ALARM);
-static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL,
-			  ADT7473_VCC_ALARM);
-
-static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max,
-			  set_temp_max, 0);
-static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max,
-			  set_temp_max, 1);
-static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max,
-			  set_temp_max, 2);
-
-static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min,
-			  set_temp_min, 0);
-static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min,
-			  set_temp_min, 1);
-static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_temp_min,
-			  set_temp_min, 2);
-
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
-static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
-static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
-
-static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL,
-			  ADT7473_R1T_ALARM | ALARM2(ADT7473_R1T_SHORT));
-static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL,
-			  ADT7473_LT_ALARM);
-static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL,
-			  ADT7473_R2T_ALARM | ALARM2(ADT7473_R2T_SHORT));
-
-static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
-			  set_fan_min, 0);
-static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min,
-			  set_fan_min, 1);
-static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min,
-			  set_fan_min, 2);
-static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min,
-			  set_fan_min, 3);
-
-static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
-static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
-static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
-static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3);
-
-static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL,
-			  ALARM2(ADT7473_FAN1_ALARM));
-static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL,
-			  ALARM2(ADT7473_FAN2_ALARM));
-static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL,
-			  ALARM2(ADT7473_FAN3_ALARM));
-static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL,
-			  ALARM2(ADT7473_FAN4_ALARM));
-
-static SENSOR_DEVICE_ATTR(pwm_use_point2_pwm_at_crit, S_IWUSR | S_IRUGO,
-			  show_max_duty_at_crit, set_max_duty_at_crit, 0);
-
-static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0);
-static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1);
-static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2);
-
-static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO,
-			  show_pwm_min, set_pwm_min, 0);
-static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO,
-			  show_pwm_min, set_pwm_min, 1);
-static SENSOR_DEVICE_ATTR(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO,
-			  show_pwm_min, set_pwm_min, 2);
-
-static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO,
-			  show_pwm_max, set_pwm_max, 0);
-static SENSOR_DEVICE_ATTR(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO,
-			  show_pwm_max, set_pwm_max, 1);
-static SENSOR_DEVICE_ATTR(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO,
-			  show_pwm_max, set_pwm_max, 2);
-
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IWUSR | S_IRUGO,
-			  show_temp_tmin, set_temp_tmin, 0);
-static SENSOR_DEVICE_ATTR(temp2_auto_point1_temp, S_IWUSR | S_IRUGO,
-			  show_temp_tmin, set_temp_tmin, 1);
-static SENSOR_DEVICE_ATTR(temp3_auto_point1_temp, S_IWUSR | S_IRUGO,
-			  show_temp_tmin, set_temp_tmin, 2);
-
-static SENSOR_DEVICE_ATTR(temp1_auto_point2_temp, S_IWUSR | S_IRUGO,
-			  show_temp_tmax, set_temp_tmax, 0);
-static SENSOR_DEVICE_ATTR(temp2_auto_point2_temp, S_IWUSR | S_IRUGO,
-			  show_temp_tmax, set_temp_tmax, 1);
-static SENSOR_DEVICE_ATTR(temp3_auto_point2_temp, S_IWUSR | S_IRUGO,
-			  show_temp_tmax, set_temp_tmax, 2);
-
-static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
-			  set_pwm_enable, 0);
-static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
-			  set_pwm_enable, 1);
-static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
-			  set_pwm_enable, 2);
-
-static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IWUSR | S_IRUGO,
-			  show_pwm_auto_temp, set_pwm_auto_temp, 0);
-static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IWUSR | S_IRUGO,
-			  show_pwm_auto_temp, set_pwm_auto_temp, 1);
-static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO,
-			  show_pwm_auto_temp, set_pwm_auto_temp, 2);
-
-static struct attribute *adt7473_attr[] =
-{
-	&sensor_dev_attr_in1_max.dev_attr.attr,
-	&sensor_dev_attr_in2_max.dev_attr.attr,
-	&sensor_dev_attr_in1_min.dev_attr.attr,
-	&sensor_dev_attr_in2_min.dev_attr.attr,
-	&sensor_dev_attr_in1_input.dev_attr.attr,
-	&sensor_dev_attr_in2_input.dev_attr.attr,
-	&sensor_dev_attr_in1_alarm.dev_attr.attr,
-	&sensor_dev_attr_in2_alarm.dev_attr.attr,
-
-	&sensor_dev_attr_temp1_max.dev_attr.attr,
-	&sensor_dev_attr_temp2_max.dev_attr.attr,
-	&sensor_dev_attr_temp3_max.dev_attr.attr,
-	&sensor_dev_attr_temp1_min.dev_attr.attr,
-	&sensor_dev_attr_temp2_min.dev_attr.attr,
-	&sensor_dev_attr_temp3_min.dev_attr.attr,
-	&sensor_dev_attr_temp1_input.dev_attr.attr,
-	&sensor_dev_attr_temp2_input.dev_attr.attr,
-	&sensor_dev_attr_temp3_input.dev_attr.attr,
-	&sensor_dev_attr_temp1_alarm.dev_attr.attr,
-	&sensor_dev_attr_temp2_alarm.dev_attr.attr,
-	&sensor_dev_attr_temp3_alarm.dev_attr.attr,
-	&sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr,
-	&sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr,
-	&sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr,
-	&sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr,
-	&sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr,
-	&sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr,
-
-	&sensor_dev_attr_fan1_min.dev_attr.attr,
-	&sensor_dev_attr_fan2_min.dev_attr.attr,
-	&sensor_dev_attr_fan3_min.dev_attr.attr,
-	&sensor_dev_attr_fan4_min.dev_attr.attr,
-	&sensor_dev_attr_fan1_input.dev_attr.attr,
-	&sensor_dev_attr_fan2_input.dev_attr.attr,
-	&sensor_dev_attr_fan3_input.dev_attr.attr,
-	&sensor_dev_attr_fan4_input.dev_attr.attr,
-	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
-	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
-	&sensor_dev_attr_fan3_alarm.dev_attr.attr,
-	&sensor_dev_attr_fan4_alarm.dev_attr.attr,
-
-	&sensor_dev_attr_pwm_use_point2_pwm_at_crit.dev_attr.attr,
-
-	&sensor_dev_attr_pwm1.dev_attr.attr,
-	&sensor_dev_attr_pwm2.dev_attr.attr,
-	&sensor_dev_attr_pwm3.dev_attr.attr,
-	&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
-	&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
-	&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
-	&sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
-	&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
-	&sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
-
-	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
-	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
-	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
-	&sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
-	&sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
-	&sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
-
-	NULL
-};
-
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int adt7473_detect(struct i2c_client *client,
-			  struct i2c_board_info *info)
-{
-	struct i2c_adapter *adapter = client->adapter;
-	int vendor, device, revision;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return -ENODEV;
-
-	vendor = i2c_smbus_read_byte_data(client, ADT7473_REG_VENDOR);
-	if (vendor != ADT7473_VENDOR)
-		return -ENODEV;
-
-	device = i2c_smbus_read_byte_data(client, ADT7473_REG_DEVICE);
-	if (device != ADT7473_DEVICE)
-		return -ENODEV;
-
-	revision = i2c_smbus_read_byte_data(client, ADT7473_REG_REVISION);
-	if (revision != ADT7473_REV_68 && revision != ADT7473_REV_69)
-		return -ENODEV;
-
-	strlcpy(info->type, "adt7473", I2C_NAME_SIZE);
-
-	return 0;
-}
-
-static int adt7473_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id)
-{
-	struct adt7473_data *data;
-	int err;
-
-	data = kzalloc(sizeof(struct adt7473_data), GFP_KERNEL);
-	if (!data) {
-		err = -ENOMEM;
-		goto exit;
-	}
-
-	i2c_set_clientdata(client, data);
-	mutex_init(&data->lock);
-
-	dev_info(&client->dev, "%s chip found\n", client->name);
-
-	/* Initialize the ADT7473 chip */
-	adt7473_init_client(client);
-
-	/* Register sysfs hooks */
-	data->attrs.attrs = adt7473_attr;
-	err = sysfs_create_group(&client->dev.kobj, &data->attrs);
-	if (err)
-		goto exit_free;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove;
-	}
-
-	return 0;
-
-exit_remove:
-	sysfs_remove_group(&client->dev.kobj, &data->attrs);
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-static int adt7473_remove(struct i2c_client *client)
-{
-	struct adt7473_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &data->attrs);
-	kfree(data);
-	return 0;
-}
-
-static int __init adt7473_init(void)
-{
-	pr_notice("The adt7473 driver is deprecated, please use the adt7475 "
-		  "driver instead\n");
-	return i2c_add_driver(&adt7473_driver);
-}
-
-static void __exit adt7473_exit(void)
-{
-	i2c_del_driver(&adt7473_driver);
-}
-
-MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
-MODULE_DESCRIPTION("ADT7473 driver");
-MODULE_LICENSE("GPL");
-
-module_init(adt7473_init);
-module_exit(adt7473_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/ams/ams-core.c linux-libre-2.6.34-gnu1/drivers/hwmon/ams/ams-core.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/ams/ams-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/ams/ams-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -213,7 +213,7 @@ int __init ams_init(void)
 	return -ENODEV;
 }
 
-void ams_exit(void)
+void ams_sensor_detach(void)
 {
 	/* Remove input device */
 	ams_input_exit();
@@ -221,9 +221,6 @@ void ams_exit(void)
 	/* Remove attributes */
 	device_remove_file(&ams_info.of_dev->dev, &dev_attr_current);
 
-	/* Shut down implementation */
-	ams_info.exit();
-
 	/* Flush interrupt worker
 	 *
 	 * We do this after ams_info.exit(), because an interrupt might
@@ -239,6 +236,12 @@ void ams_exit(void)
 	pmf_unregister_irq_client(&ams_freefall_client);
 }
 
+static void __exit ams_exit(void)
+{
+	/* Shut down implementation */
+	ams_info.exit();
+}
+
 MODULE_AUTHOR("Stelian Pop, Michael Hanselmann");
 MODULE_DESCRIPTION("Apple Motion Sensor driver");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/ams/ams.h linux-libre-2.6.34-gnu1/drivers/hwmon/ams/ams.h
--- linux-libre-2.6.33-gnu1/drivers/hwmon/ams/ams.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/ams/ams.h	2010-05-16 17:17:36.000000000 -0400
@@ -61,6 +61,7 @@ extern struct ams ams_info;
 
 extern void ams_sensors(s8 *x, s8 *y, s8 *z);
 extern int ams_sensor_attach(void);
+extern void ams_sensor_detach(void);
 
 extern int ams_pmu_init(struct device_node *np);
 extern int ams_i2c_init(struct device_node *np);
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/ams/ams-i2c.c linux-libre-2.6.34-gnu1/drivers/hwmon/ams/ams-i2c.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/ams/ams-i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/ams/ams-i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -238,6 +238,8 @@ static int ams_i2c_probe(struct i2c_clie
 static int ams_i2c_remove(struct i2c_client *client)
 {
 	if (ams_info.has_device) {
+		ams_sensor_detach();
+
 		/* Disable interrupts */
 		ams_i2c_set_irq(AMS_IRQ_ALL, 0);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/ams/ams-pmu.c linux-libre-2.6.34-gnu1/drivers/hwmon/ams/ams-pmu.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/ams/ams-pmu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/ams/ams-pmu.c	2010-05-16 17:17:36.000000000 -0400
@@ -133,6 +133,8 @@ static void ams_pmu_get_xyz(s8 *x, s8 *y
 
 static void ams_pmu_exit(void)
 {
+	ams_sensor_detach();
+
 	/* Disable interrupts */
 	ams_pmu_set_irq(AMS_IRQ_ALL, 0);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/applesmc.c linux-libre-2.6.34-gnu1/drivers/hwmon/applesmc.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/applesmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/applesmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -142,6 +142,12 @@ static const char *temperature_sensors_s
 	  "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S",
 	  "TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S",
 	  NULL },
+/* Set 17: iMac 9,1 */
+	{ "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TH0P", "TL0P",
+	  "TN0D", "TN0H", "TN0P", "TO0P", "Tm0P", "Tp0P", NULL },
+/* Set 18: MacBook Pro 2,2 */
+	{ "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0",
+	  "Th0H", "Th1H", "Tm0P", "Ts0P", NULL },
 };
 
 /* List of keys used to read/write fan speeds */
@@ -189,6 +195,9 @@ static unsigned int applesmc_acceleromet
 /* Indicates whether this computer has light sensors and keyboard backlight. */
 static unsigned int applesmc_light;
 
+/* The number of fans handled by the driver */
+static unsigned int fans_handled;
+
 /* Indicates which temperature sensors set to use. */
 static unsigned int applesmc_temperature_set;
 
@@ -1350,6 +1359,10 @@ static __initdata struct dmi_match_data
 	{ .accelerometer = 1, .light = 1, .temperature_set = 15 },
 /* MacPro3,1: temperature set 16 */
 	{ .accelerometer = 0, .light = 0, .temperature_set = 16 },
+/* iMac 9,1: light sensor only, temperature set 17 */
+	{ .accelerometer = 0, .light = 0, .temperature_set = 17 },
+/* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */
+	{ .accelerometer = 1, .light = 1, .temperature_set = 18 },
 };
 
 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
@@ -1375,6 +1388,10 @@ static __initdata struct dmi_system_id a
 	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
 	  DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
 		&applesmc_dmi_data[9]},
+	{ applesmc_dmi_match, "Apple MacBook Pro 2,2", {
+	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."),
+	  DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") },
+		&applesmc_dmi_data[18]},
 	{ applesmc_dmi_match, "Apple MacBook Pro", {
 	  DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
 	  DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
@@ -1415,6 +1432,10 @@ static __initdata struct dmi_system_id a
 	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
 	  DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
 		&applesmc_dmi_data[4]},
+	{ applesmc_dmi_match, "Apple iMac 9,1", {
+	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
+	  DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") },
+		&applesmc_dmi_data[17]},
 	{ applesmc_dmi_match, "Apple iMac 8", {
 	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
 	  DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
@@ -1474,39 +1495,24 @@ static int __init applesmc_init(void)
 
 	/* create fan files */
 	count = applesmc_get_fan_count();
-	if (count < 0) {
+	if (count < 0)
 		printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
-	} else {
+	else
 		printk(KERN_INFO "applesmc: %d fans found.\n", count);
 
-		switch (count) {
-		default:
-			printk(KERN_WARNING "applesmc: More than 4 fans found,"
-					" but at most 4 fans are supported"
-						" by the driver.\n");
-		case 4:
-			ret = sysfs_create_group(&pdev->dev.kobj,
-						 &fan_attribute_groups[3]);
-			if (ret)
-				goto out_key_enumeration;
-		case 3:
-			ret = sysfs_create_group(&pdev->dev.kobj,
-						 &fan_attribute_groups[2]);
-			if (ret)
-				goto out_key_enumeration;
-		case 2:
-			ret = sysfs_create_group(&pdev->dev.kobj,
-						 &fan_attribute_groups[1]);
-			if (ret)
-				goto out_key_enumeration;
-		case 1:
-			ret = sysfs_create_group(&pdev->dev.kobj,
-						 &fan_attribute_groups[0]);
-			if (ret)
-				goto out_fan_1;
-		case 0:
-			;
-		}
+	if (count > 4) {
+		count = 4;
+		printk(KERN_WARNING "applesmc: More than 4 fans found,"
+		       " but at most 4 fans are supported"
+		       " by the driver.\n");
+	}
+
+	while (fans_handled < count) {
+		ret = sysfs_create_group(&pdev->dev.kobj,
+					 &fan_attribute_groups[fans_handled]);
+		if (ret)
+			goto out_fans;
+		fans_handled++;
 	}
 
 	for (i = 0;
@@ -1575,10 +1581,10 @@ out_accelerometer:
 		applesmc_release_accelerometer();
 out_temperature:
 	sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
-	sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
-out_fan_1:
-	sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
-out_key_enumeration:
+out_fans:
+	while (fans_handled)
+		sysfs_remove_group(&pdev->dev.kobj,
+				   &fan_attribute_groups[--fans_handled]);
 	sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
 out_name:
 	sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
@@ -1604,8 +1610,9 @@ static void __exit applesmc_exit(void)
 	if (applesmc_accelerometer)
 		applesmc_release_accelerometer();
 	sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
-	sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
-	sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
+	while (fans_handled)
+		sysfs_remove_group(&pdev->dev.kobj,
+				   &fan_attribute_groups[--fans_handled]);
 	sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
 	sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
 	platform_device_unregister(pdev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/asc7621.c linux-libre-2.6.34-gnu1/drivers/hwmon/asc7621.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/asc7621.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/asc7621.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1254 @@
+/*
+ * asc7621.c - Part of lm_sensors, Linux kernel modules for hardware monitoring
+ * Copyright (c) 2007, 2010 George Joseph  <george.joseph@fairview5.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the 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>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = {
+	0x2c, 0x2d, 0x2e, I2C_CLIENT_END
+};
+
+enum asc7621_type {
+	asc7621,
+	asc7621a
+};
+
+#define INTERVAL_HIGH   (HZ + HZ / 2)
+#define INTERVAL_LOW    (1 * 60 * HZ)
+#define PRI_NONE        0
+#define PRI_LOW         1
+#define PRI_HIGH        2
+#define FIRST_CHIP      asc7621
+#define LAST_CHIP       asc7621a
+
+struct asc7621_chip {
+	char *name;
+	enum asc7621_type chip_type;
+	u8 company_reg;
+	u8 company_id;
+	u8 verstep_reg;
+	u8 verstep_id;
+	unsigned short *addresses;
+};
+
+static struct asc7621_chip asc7621_chips[] = {
+	{
+		.name = "asc7621",
+		.chip_type = asc7621,
+		.company_reg = 0x3e,
+		.company_id = 0x61,
+		.verstep_reg = 0x3f,
+		.verstep_id = 0x6c,
+		.addresses = normal_i2c,
+	 },
+	{
+		.name = "asc7621a",
+		.chip_type = asc7621a,
+		.company_reg = 0x3e,
+		.company_id = 0x61,
+		.verstep_reg = 0x3f,
+		.verstep_id = 0x6d,
+		.addresses = normal_i2c,
+	 },
+};
+
+/*
+ * Defines the highest register to be used, not the count.
+ * The actual count will probably be smaller because of gaps
+ * in the implementation (unused register locations).
+ * This define will safely set the array size of both the parameter
+ * and data arrays.
+ * This comes from the data sheet register description table.
+ */
+#define LAST_REGISTER 0xff
+
+struct asc7621_data {
+	struct i2c_client client;
+	struct device *class_dev;
+	struct mutex update_lock;
+	int valid;		/* !=0 if following fields are valid */
+	unsigned long last_high_reading;	/* In jiffies */
+	unsigned long last_low_reading;		/* In jiffies */
+	/*
+	 * Registers we care about occupy the corresponding index
+	 * in the array.  Registers we don't care about are left
+	 * at 0.
+	 */
+	u8 reg[LAST_REGISTER + 1];
+};
+
+/*
+ * Macro to get the parent asc7621_param structure
+ * from a sensor_device_attribute passed into the
+ * show/store functions.
+ */
+#define to_asc7621_param(_sda) \
+	container_of(_sda, struct asc7621_param, sda)
+
+/*
+ * Each parameter to be retrieved needs an asc7621_param structure
+ * allocated.  It contains the sensor_device_attribute structure
+ * and the control info needed to retrieve the value from the register map.
+ */
+struct asc7621_param {
+	struct sensor_device_attribute sda;
+	u8 priority;
+	u8 msb[3];
+	u8 lsb[3];
+	u8 mask[3];
+	u8 shift[3];
+};
+
+/*
+ * This is the map that ultimately indicates whether we'll be
+ * retrieving a register value or not, and at what frequency.
+ */
+static u8 asc7621_register_priorities[255];
+
+static struct asc7621_data *asc7621_update_device(struct device *dev);
+
+static inline u8 read_byte(struct i2c_client *client, u8 reg)
+{
+	int res = i2c_smbus_read_byte_data(client, reg);
+	if (res < 0) {
+		dev_err(&client->dev,
+			"Unable to read from register 0x%02x.\n", reg);
+		return 0;
+	};
+	return res & 0xff;
+}
+
+static inline int write_byte(struct i2c_client *client, u8 reg, u8 data)
+{
+	int res = i2c_smbus_write_byte_data(client, reg, data);
+	if (res < 0) {
+		dev_err(&client->dev,
+			"Unable to write value 0x%02x to register 0x%02x.\n",
+			data, reg);
+	};
+	return res;
+}
+
+/*
+ * Data Handlers
+ * Each function handles the formatting, storage
+ * and retrieval of like parameters.
+ */
+
+#define SETUP_SHOW_data_param(d, a) \
+	struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \
+	struct asc7621_data *data = asc7621_update_device(d); \
+	struct asc7621_param *param = to_asc7621_param(sda)
+
+#define SETUP_STORE_data_param(d, a) \
+	struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \
+	struct i2c_client *client = to_i2c_client(d); \
+	struct asc7621_data *data = i2c_get_clientdata(client); \
+	struct asc7621_param *param = to_asc7621_param(sda)
+
+/*
+ * u8 is just what it sounds like...an unsigned byte with no
+ * special formatting.
+ */
+static ssize_t show_u8(struct device *dev, struct device_attribute *attr,
+		       char *buf)
+{
+	SETUP_SHOW_data_param(dev, attr);
+
+	return sprintf(buf, "%u\n", data->reg[param->msb[0]]);
+}
+
+static ssize_t store_u8(struct device *dev, struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	SETUP_STORE_data_param(dev, attr);
+	long reqval;
+
+	if (strict_strtol(buf, 10, &reqval))
+		return -EINVAL;
+
+	reqval = SENSORS_LIMIT(reqval, 0, 255);
+
+	mutex_lock(&data->update_lock);
+	data->reg[param->msb[0]] = reqval;
+	write_byte(client, param->msb[0], reqval);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+/*
+ * Many of the config values occupy only a few bits of a register.
+ */
+static ssize_t show_bitmask(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	SETUP_SHOW_data_param(dev, attr);
+
+	return sprintf(buf, "%u\n",
+		       (data->reg[param->msb[0]] >> param->
+			shift[0]) & param->mask[0]);
+}
+
+static ssize_t store_bitmask(struct device *dev,
+			     struct device_attribute *attr,
+			     const char *buf, size_t count)
+{
+	SETUP_STORE_data_param(dev, attr);
+	long reqval;
+	u8 currval;
+
+	if (strict_strtol(buf, 10, &reqval))
+		return -EINVAL;
+
+	reqval = SENSORS_LIMIT(reqval, 0, param->mask[0]);
+
+	reqval = (reqval & param->mask[0]) << param->shift[0];
+
+	mutex_lock(&data->update_lock);
+	currval = read_byte(client, param->msb[0]);
+	reqval |= (currval & ~(param->mask[0] << param->shift[0]));
+	data->reg[param->msb[0]] = reqval;
+	write_byte(client, param->msb[0], reqval);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+/*
+ * 16 bit fan rpm values
+ * reported by the device as the number of 11.111us periods (90khz)
+ * between full fan rotations.  Therefore...
+ * RPM = (90000 * 60) / register value
+ */
+static ssize_t show_fan16(struct device *dev,
+			  struct device_attribute *attr, char *buf)
+{
+	SETUP_SHOW_data_param(dev, attr);
+	u16 regval;
+
+	mutex_lock(&data->update_lock);
+	regval = (data->reg[param->msb[0]] << 8) | data->reg[param->lsb[0]];
+	mutex_unlock(&data->update_lock);
+
+	return sprintf(buf, "%u\n",
+		       (regval == 0 ? -1 : (regval) ==
+			0xffff ? 0 : 5400000 / regval));
+}
+
+static ssize_t store_fan16(struct device *dev,
+			   struct device_attribute *attr, const char *buf,
+			   size_t count)
+{
+	SETUP_STORE_data_param(dev, attr);
+	long reqval;
+
+	if (strict_strtol(buf, 10, &reqval))
+		return -EINVAL;
+
+	/* If a minimum RPM of zero is requested, then we set the register to
+	   0xffff. This value allows the fan to be stopped completely without
+	   generating an alarm. */
+	reqval =
+	    (reqval <= 0 ? 0xffff : SENSORS_LIMIT(5400000 / reqval, 0, 0xfffe));
+
+	mutex_lock(&data->update_lock);
+	data->reg[param->msb[0]] = (reqval >> 8) & 0xff;
+	data->reg[param->lsb[0]] = reqval & 0xff;
+	write_byte(client, param->msb[0], data->reg[param->msb[0]]);
+	write_byte(client, param->lsb[0], data->reg[param->lsb[0]]);
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+/*
+ * Voltages are scaled in the device so that the nominal voltage
+ * is 3/4ths of the 0-255 range (i.e. 192).
+ * If all voltages are 'normal' then all voltage registers will
+ * read 0xC0.
+ *
+ * The data sheet provides us with the 3/4 scale value for each voltage
+ * which is stored in in_scaling.  The sda->index parameter value provides
+ * the index into in_scaling.
+ *
+ * NOTE: The chip expects the first 2 inputs be 2.5 and 2.25 volts
+ * respectively. That doesn't mean that's what the motherboard provides. :)
+ */
+
+static int asc7621_in_scaling[] = {
+	2500, 2250, 3300, 5000, 12000
+};
+
+static ssize_t show_in10(struct device *dev, struct device_attribute *attr,
+			 char *buf)
+{
+	SETUP_SHOW_data_param(dev, attr);
+	u16 regval;
+	u8 nr = sda->index;
+
+	mutex_lock(&data->update_lock);
+	regval = (data->reg[param->msb[0]] << 8) | (data->reg[param->lsb[0]]);
+	mutex_unlock(&data->update_lock);
+
+	/* The LSB value is a 2-bit scaling of the MSB's LSbit value. */
+	regval = (regval >> 6) * asc7621_in_scaling[nr] / (0xc0 << 2);
+
+	return sprintf(buf, "%u\n", regval);
+}
+
+/* 8 bit voltage values (the mins and maxs) */
+static ssize_t show_in8(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	SETUP_SHOW_data_param(dev, attr);
+	u8 nr = sda->index;
+
+	return sprintf(buf, "%u\n",
+		       ((data->reg[param->msb[0]] *
+			 asc7621_in_scaling[nr]) / 0xc0));
+}
+
+static ssize_t store_in8(struct device *dev, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	SETUP_STORE_data_param(dev, attr);
+	long reqval;
+	u8 nr = sda->index;
+
+	if (strict_strtol(buf, 10, &reqval))
+		return -EINVAL;
+
+	reqval = SENSORS_LIMIT(reqval, 0, 0xffff);
+
+	reqval = reqval * 0xc0 / asc7621_in_scaling[nr];
+
+	reqval = SENSORS_LIMIT(reqval, 0, 0xff);
+
+	mutex_lock(&data->update_lock);
+	data->reg[param->msb[0]] = reqval;
+	write_byte(client, param->msb[0], reqval);
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t show_temp8(struct device *dev,
+			  struct device_attribute *attr, char *buf)
+{
+	SETUP_SHOW_data_param(dev, attr);
+
+	return sprintf(buf, "%d\n", ((s8) data->reg[param->msb[0]]) * 1000);
+}
+
+static ssize_t store_temp8(struct device *dev,
+			   struct device_attribute *attr, const char *buf,
+			   size_t count)
+{
+	SETUP_STORE_data_param(dev, attr);
+	long reqval;
+	s8 temp;
+
+	if (strict_strtol(buf, 10, &reqval))
+		return -EINVAL;
+
+	reqval = SENSORS_LIMIT(reqval, -127000, 127000);
+
+	temp = reqval / 1000;
+
+	mutex_lock(&data->update_lock);
+	data->reg[param->msb[0]] = temp;
+	write_byte(client, param->msb[0], temp);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+/*
+ * Temperatures that occupy 2 bytes always have the whole
+ * number of degrees in the MSB with some part of the LSB
+ * indicating fractional degrees.
+ */
+
+/*   mmmmmmmm.llxxxxxx */
+static ssize_t show_temp10(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	SETUP_SHOW_data_param(dev, attr);
+	u8 msb, lsb;
+	int temp;
+
+	mutex_lock(&data->update_lock);
+	msb = data->reg[param->msb[0]];
+	lsb = (data->reg[param->lsb[0]] >> 6) & 0x03;
+	temp = (((s8) msb) * 1000) + (lsb * 250);
+	mutex_unlock(&data->update_lock);
+
+	return sprintf(buf, "%d\n", temp);
+}
+
+/*   mmmmmm.ll */
+static ssize_t show_temp62(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	SETUP_SHOW_data_param(dev, attr);
+	u8 regval = data->reg[param->msb[0]];
+	int temp = ((s8) (regval & 0xfc) * 1000) + ((regval & 0x03) * 250);
+
+	return sprintf(buf, "%d\n", temp);
+}
+
+static ssize_t store_temp62(struct device *dev,
+			    struct device_attribute *attr, const char *buf,
+			    size_t count)
+{
+	SETUP_STORE_data_param(dev, attr);
+	long reqval, i, f;
+	s8 temp;
+
+	if (strict_strtol(buf, 10, &reqval))
+		return -EINVAL;
+
+	reqval = SENSORS_LIMIT(reqval, -32000, 31750);
+	i = reqval / 1000;
+	f = reqval - (i * 1000);
+	temp = i << 2;
+	temp |= f / 250;
+
+	mutex_lock(&data->update_lock);
+	data->reg[param->msb[0]] = temp;
+	write_byte(client, param->msb[0], temp);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+/*
+ * The aSC7621 doesn't provide an "auto_point2".  Instead, you
+ * specify the auto_point1 and a range.  To keep with the sysfs
+ * hwmon specs, we synthesize the auto_point_2 from them.
+ */
+
+static u32 asc7621_range_map[] = {
+	2000, 2500, 3330, 4000, 5000, 6670, 8000, 10000,
+	13330, 16000, 20000, 26670, 32000, 40000, 53330, 80000,
+};
+
+static ssize_t show_ap2_temp(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	SETUP_SHOW_data_param(dev, attr);
+	long auto_point1;
+	u8 regval;
+	int temp;
+
+	mutex_lock(&data->update_lock);
+	auto_point1 = ((s8) data->reg[param->msb[1]]) * 1000;
+	regval =
+	    ((data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0]);
+	temp = auto_point1 + asc7621_range_map[SENSORS_LIMIT(regval, 0, 15)];
+	mutex_unlock(&data->update_lock);
+
+	return sprintf(buf, "%d\n", temp);
+
+}
+
+static ssize_t store_ap2_temp(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	SETUP_STORE_data_param(dev, attr);
+	long reqval, auto_point1;
+	int i;
+	u8 currval, newval = 0;
+
+	if (strict_strtol(buf, 10, &reqval))
+		return -EINVAL;
+
+	mutex_lock(&data->update_lock);
+	auto_point1 = data->reg[param->msb[1]] * 1000;
+	reqval = SENSORS_LIMIT(reqval, auto_point1 + 2000, auto_point1 + 80000);
+
+	for (i = ARRAY_SIZE(asc7621_range_map) - 1; i >= 0; i--) {
+		if (reqval >= auto_point1 + asc7621_range_map[i]) {
+			newval = i;
+			break;
+		}
+	}
+
+	newval = (newval & param->mask[0]) << param->shift[0];
+	currval = read_byte(client, param->msb[0]);
+	newval |= (currval & ~(param->mask[0] << param->shift[0]));
+	data->reg[param->msb[0]] = newval;
+	write_byte(client, param->msb[0], newval);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_pwm_ac(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	SETUP_SHOW_data_param(dev, attr);
+	u8 config, altbit, regval;
+	u8 map[] = {
+		0x01, 0x02, 0x04, 0x1f, 0x00, 0x06, 0x07, 0x10,
+		0x08, 0x0f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f
+	};
+
+	mutex_lock(&data->update_lock);
+	config = (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
+	altbit = (data->reg[param->msb[1]] >> param->shift[1]) & param->mask[1];
+	regval = config | (altbit << 3);
+	mutex_unlock(&data->update_lock);
+
+	return sprintf(buf, "%u\n", map[SENSORS_LIMIT(regval, 0, 15)]);
+}
+
+static ssize_t store_pwm_ac(struct device *dev,
+			    struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	SETUP_STORE_data_param(dev, attr);
+	unsigned long reqval;
+	u8 currval, config, altbit, newval;
+	u16 map[] = {
+		0x04, 0x00, 0x01, 0xff, 0x02, 0xff, 0x05, 0x06,
+		0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
+		0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,
+	};
+
+	if (strict_strtoul(buf, 10, &reqval))
+		return -EINVAL;
+
+	if (reqval > 31)
+		return -EINVAL;
+
+	reqval = map[reqval];
+	if (reqval == 0xff)
+		return -EINVAL;
+
+	config = reqval & 0x07;
+	altbit = (reqval >> 3) & 0x01;
+
+	config = (config & param->mask[0]) << param->shift[0];
+	altbit = (altbit & param->mask[1]) << param->shift[1];
+
+	mutex_lock(&data->update_lock);
+	currval = read_byte(client, param->msb[0]);
+	newval = config | (currval & ~(param->mask[0] << param->shift[0]));
+	newval = altbit | (newval & ~(param->mask[1] << param->shift[1]));
+	data->reg[param->msb[0]] = newval;
+	write_byte(client, param->msb[0], newval);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_pwm_enable(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	SETUP_SHOW_data_param(dev, attr);
+	u8 config, altbit, minoff, val, newval;
+
+	mutex_lock(&data->update_lock);
+	config = (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
+	altbit = (data->reg[param->msb[1]] >> param->shift[1]) & param->mask[1];
+	minoff = (data->reg[param->msb[2]] >> param->shift[2]) & param->mask[2];
+	mutex_unlock(&data->update_lock);
+
+	val = config | (altbit << 3);
+	newval = 0;
+
+	if (val == 3 || val >= 10)
+		newval = 255;
+	else if (val == 4)
+		newval = 0;
+	else if (val == 7)
+		newval = 1;
+	else if (minoff == 1)
+		newval = 2;
+	else
+		newval = 3;
+
+	return sprintf(buf, "%u\n", newval);
+}
+
+static ssize_t store_pwm_enable(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	SETUP_STORE_data_param(dev, attr);
+	long reqval;
+	u8 currval, config, altbit, newval, minoff = 255;
+
+	if (strict_strtol(buf, 10, &reqval))
+		return -EINVAL;
+
+	switch (reqval) {
+	case 0:
+		newval = 0x04;
+		break;
+	case 1:
+		newval = 0x07;
+		break;
+	case 2:
+		newval = 0x00;
+		minoff = 1;
+		break;
+	case 3:
+		newval = 0x00;
+		minoff = 0;
+		break;
+	case 255:
+		newval = 0x03;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	config = newval & 0x07;
+	altbit = (newval >> 3) & 0x01;
+
+	mutex_lock(&data->update_lock);
+	config = (config & param->mask[0]) << param->shift[0];
+	altbit = (altbit & param->mask[1]) << param->shift[1];
+	currval = read_byte(client, param->msb[0]);
+	newval = config | (currval & ~(param->mask[0] << param->shift[0]));
+	newval = altbit | (newval & ~(param->mask[1] << param->shift[1]));
+	data->reg[param->msb[0]] = newval;
+	write_byte(client, param->msb[0], newval);
+	if (minoff < 255) {
+		minoff = (minoff & param->mask[2]) << param->shift[2];
+		currval = read_byte(client, param->msb[2]);
+		newval =
+		    minoff | (currval & ~(param->mask[2] << param->shift[2]));
+		data->reg[param->msb[2]] = newval;
+		write_byte(client, param->msb[2], newval);
+	}
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+static u32 asc7621_pwm_freq_map[] = {
+	10, 15, 23, 30, 38, 47, 62, 94,
+	23000, 24000, 25000, 26000, 27000, 28000, 29000, 30000
+};
+
+static ssize_t show_pwm_freq(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	SETUP_SHOW_data_param(dev, attr);
+	u8 regval =
+	    (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
+
+	regval = SENSORS_LIMIT(regval, 0, 15);
+
+	return sprintf(buf, "%u\n", asc7621_pwm_freq_map[regval]);
+}
+
+static ssize_t store_pwm_freq(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	SETUP_STORE_data_param(dev, attr);
+	unsigned long reqval;
+	u8 currval, newval = 255;
+	int i;
+
+	if (strict_strtoul(buf, 10, &reqval))
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(asc7621_pwm_freq_map); i++) {
+		if (reqval == asc7621_pwm_freq_map[i]) {
+			newval = i;
+			break;
+		}
+	}
+	if (newval == 255)
+		return -EINVAL;
+
+	newval = (newval & param->mask[0]) << param->shift[0];
+
+	mutex_lock(&data->update_lock);
+	currval = read_byte(client, param->msb[0]);
+	newval |= (currval & ~(param->mask[0] << param->shift[0]));
+	data->reg[param->msb[0]] = newval;
+	write_byte(client, param->msb[0], newval);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+static u32 asc7621_pwm_auto_spinup_map[] =  {
+	0, 100, 250, 400, 700, 1000, 2000, 4000
+};
+
+static ssize_t show_pwm_ast(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	SETUP_SHOW_data_param(dev, attr);
+	u8 regval =
+	    (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
+
+	regval = SENSORS_LIMIT(regval, 0, 7);
+
+	return sprintf(buf, "%u\n", asc7621_pwm_auto_spinup_map[regval]);
+
+}
+
+static ssize_t store_pwm_ast(struct device *dev,
+			     struct device_attribute *attr,
+			     const char *buf, size_t count)
+{
+	SETUP_STORE_data_param(dev, attr);
+	long reqval;
+	u8 currval, newval = 255;
+	u32 i;
+
+	if (strict_strtol(buf, 10, &reqval))
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(asc7621_pwm_auto_spinup_map); i++) {
+		if (reqval == asc7621_pwm_auto_spinup_map[i]) {
+			newval = i;
+			break;
+		}
+	}
+	if (newval == 255)
+		return -EINVAL;
+
+	newval = (newval & param->mask[0]) << param->shift[0];
+
+	mutex_lock(&data->update_lock);
+	currval = read_byte(client, param->msb[0]);
+	newval |= (currval & ~(param->mask[0] << param->shift[0]));
+	data->reg[param->msb[0]] = newval;
+	write_byte(client, param->msb[0], newval);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+static u32 asc7621_temp_smoothing_time_map[] = {
+	35000, 17600, 11800, 7000, 4400, 3000, 1600, 800
+};
+
+static ssize_t show_temp_st(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	SETUP_SHOW_data_param(dev, attr);
+	u8 regval =
+	    (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
+	regval = SENSORS_LIMIT(regval, 0, 7);
+
+	return sprintf(buf, "%u\n", asc7621_temp_smoothing_time_map[regval]);
+}
+
+static ssize_t store_temp_st(struct device *dev,
+			     struct device_attribute *attr,
+			     const char *buf, size_t count)
+{
+	SETUP_STORE_data_param(dev, attr);
+	long reqval;
+	u8 currval, newval = 255;
+	u32 i;
+
+	if (strict_strtol(buf, 10, &reqval))
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(asc7621_temp_smoothing_time_map); i++) {
+		if (reqval == asc7621_temp_smoothing_time_map[i]) {
+			newval = i;
+			break;
+		}
+	}
+
+	if (newval == 255)
+		return -EINVAL;
+
+	newval = (newval & param->mask[0]) << param->shift[0];
+
+	mutex_lock(&data->update_lock);
+	currval = read_byte(client, param->msb[0]);
+	newval |= (currval & ~(param->mask[0] << param->shift[0]));
+	data->reg[param->msb[0]] = newval;
+	write_byte(client, param->msb[0], newval);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+/*
+ * End of data handlers
+ *
+ * These defines do nothing more than make the table easier
+ * to read when wrapped at column 80.
+ */
+
+/*
+ * Creates a variable length array inititalizer.
+ * VAA(1,3,5,7) would produce {1,3,5,7}
+ */
+#define VAA(args...) {args}
+
+#define PREAD(name, n, pri, rm, rl, m, s, r) \
+	{.sda = SENSOR_ATTR(name, S_IRUGO, show_##r, NULL, n), \
+	  .priority = pri, .msb[0] = rm, .lsb[0] = rl, .mask[0] = m, \
+	  .shift[0] = s,}
+
+#define PWRITE(name, n, pri, rm, rl, m, s, r) \
+	{.sda = SENSOR_ATTR(name, S_IRUGO | S_IWUSR, show_##r, store_##r, n), \
+	  .priority = pri, .msb[0] = rm, .lsb[0] = rl, .mask[0] = m, \
+	  .shift[0] = s,}
+
+/*
+ * PWRITEM assumes that the initializers for the .msb, .lsb, .mask and .shift
+ * were created using the VAA macro.
+ */
+#define PWRITEM(name, n, pri, rm, rl, m, s, r) \
+	{.sda = SENSOR_ATTR(name, S_IRUGO | S_IWUSR, show_##r, store_##r, n), \
+	  .priority = pri, .msb = rm, .lsb = rl, .mask = m, .shift = s,}
+
+static struct asc7621_param asc7621_params[] = {
+	PREAD(in0_input, 0, PRI_HIGH, 0x20, 0x13, 0, 0, in10),
+	PREAD(in1_input, 1, PRI_HIGH, 0x21, 0x18, 0, 0, in10),
+	PREAD(in2_input, 2, PRI_HIGH, 0x22, 0x11, 0, 0, in10),
+	PREAD(in3_input, 3, PRI_HIGH, 0x23, 0x12, 0, 0, in10),
+	PREAD(in4_input, 4, PRI_HIGH, 0x24, 0x14, 0, 0, in10),
+
+	PWRITE(in0_min, 0, PRI_LOW, 0x44, 0, 0, 0, in8),
+	PWRITE(in1_min, 1, PRI_LOW, 0x46, 0, 0, 0, in8),
+	PWRITE(in2_min, 2, PRI_LOW, 0x48, 0, 0, 0, in8),
+	PWRITE(in3_min, 3, PRI_LOW, 0x4a, 0, 0, 0, in8),
+	PWRITE(in4_min, 4, PRI_LOW, 0x4c, 0, 0, 0, in8),
+
+	PWRITE(in0_max, 0, PRI_LOW, 0x45, 0, 0, 0, in8),
+	PWRITE(in1_max, 1, PRI_LOW, 0x47, 0, 0, 0, in8),
+	PWRITE(in2_max, 2, PRI_LOW, 0x49, 0, 0, 0, in8),
+	PWRITE(in3_max, 3, PRI_LOW, 0x4b, 0, 0, 0, in8),
+	PWRITE(in4_max, 4, PRI_LOW, 0x4d, 0, 0, 0, in8),
+
+	PREAD(in0_alarm, 0, PRI_HIGH, 0x41, 0, 0x01, 0, bitmask),
+	PREAD(in1_alarm, 1, PRI_HIGH, 0x41, 0, 0x01, 1, bitmask),
+	PREAD(in2_alarm, 2, PRI_HIGH, 0x41, 0, 0x01, 2, bitmask),
+	PREAD(in3_alarm, 3, PRI_HIGH, 0x41, 0, 0x01, 3, bitmask),
+	PREAD(in4_alarm, 4, PRI_HIGH, 0x42, 0, 0x01, 0, bitmask),
+
+	PREAD(fan1_input, 0, PRI_HIGH, 0x29, 0x28, 0, 0, fan16),
+	PREAD(fan2_input, 1, PRI_HIGH, 0x2b, 0x2a, 0, 0, fan16),
+	PREAD(fan3_input, 2, PRI_HIGH, 0x2d, 0x2c, 0, 0, fan16),
+	PREAD(fan4_input, 3, PRI_HIGH, 0x2f, 0x2e, 0, 0, fan16),
+
+	PWRITE(fan1_min, 0, PRI_LOW, 0x55, 0x54, 0, 0, fan16),
+	PWRITE(fan2_min, 1, PRI_LOW, 0x57, 0x56, 0, 0, fan16),
+	PWRITE(fan3_min, 2, PRI_LOW, 0x59, 0x58, 0, 0, fan16),
+	PWRITE(fan4_min, 3, PRI_LOW, 0x5b, 0x5a, 0, 0, fan16),
+
+	PREAD(fan1_alarm, 0, PRI_HIGH, 0x42, 0, 0x01, 2, bitmask),
+	PREAD(fan2_alarm, 1, PRI_HIGH, 0x42, 0, 0x01, 3, bitmask),
+	PREAD(fan3_alarm, 2, PRI_HIGH, 0x42, 0, 0x01, 4, bitmask),
+	PREAD(fan4_alarm, 3, PRI_HIGH, 0x42, 0, 0x01, 5, bitmask),
+
+	PREAD(temp1_input, 0, PRI_HIGH, 0x25, 0x10, 0, 0, temp10),
+	PREAD(temp2_input, 1, PRI_HIGH, 0x26, 0x15, 0, 0, temp10),
+	PREAD(temp3_input, 2, PRI_HIGH, 0x27, 0x16, 0, 0, temp10),
+	PREAD(temp4_input, 3, PRI_HIGH, 0x33, 0x17, 0, 0, temp10),
+	PREAD(temp5_input, 4, PRI_HIGH, 0xf7, 0xf6, 0, 0, temp10),
+	PREAD(temp6_input, 5, PRI_HIGH, 0xf9, 0xf8, 0, 0, temp10),
+	PREAD(temp7_input, 6, PRI_HIGH, 0xfb, 0xfa, 0, 0, temp10),
+	PREAD(temp8_input, 7, PRI_HIGH, 0xfd, 0xfc, 0, 0, temp10),
+
+	PWRITE(temp1_min, 0, PRI_LOW, 0x4e, 0, 0, 0, temp8),
+	PWRITE(temp2_min, 1, PRI_LOW, 0x50, 0, 0, 0, temp8),
+	PWRITE(temp3_min, 2, PRI_LOW, 0x52, 0, 0, 0, temp8),
+	PWRITE(temp4_min, 3, PRI_LOW, 0x34, 0, 0, 0, temp8),
+
+	PWRITE(temp1_max, 0, PRI_LOW, 0x4f, 0, 0, 0, temp8),
+	PWRITE(temp2_max, 1, PRI_LOW, 0x51, 0, 0, 0, temp8),
+	PWRITE(temp3_max, 2, PRI_LOW, 0x53, 0, 0, 0, temp8),
+	PWRITE(temp4_max, 3, PRI_LOW, 0x35, 0, 0, 0, temp8),
+
+	PREAD(temp1_alarm, 0, PRI_HIGH, 0x41, 0, 0x01, 4, bitmask),
+	PREAD(temp2_alarm, 1, PRI_HIGH, 0x41, 0, 0x01, 5, bitmask),
+	PREAD(temp3_alarm, 2, PRI_HIGH, 0x41, 0, 0x01, 6, bitmask),
+	PREAD(temp4_alarm, 3, PRI_HIGH, 0x43, 0, 0x01, 0, bitmask),
+
+	PWRITE(temp1_source, 0, PRI_LOW, 0x02, 0, 0x07, 4, bitmask),
+	PWRITE(temp2_source, 1, PRI_LOW, 0x02, 0, 0x07, 0, bitmask),
+	PWRITE(temp3_source, 2, PRI_LOW, 0x03, 0, 0x07, 4, bitmask),
+	PWRITE(temp4_source, 3, PRI_LOW, 0x03, 0, 0x07, 0, bitmask),
+
+	PWRITE(temp1_smoothing_enable, 0, PRI_LOW, 0x62, 0, 0x01, 3, bitmask),
+	PWRITE(temp2_smoothing_enable, 1, PRI_LOW, 0x63, 0, 0x01, 7, bitmask),
+	PWRITE(temp3_smoothing_enable, 2, PRI_LOW, 0x63, 0, 0x01, 3, bitmask),
+	PWRITE(temp4_smoothing_enable, 3, PRI_LOW, 0x3c, 0, 0x01, 3, bitmask),
+
+	PWRITE(temp1_smoothing_time, 0, PRI_LOW, 0x62, 0, 0x07, 0, temp_st),
+	PWRITE(temp2_smoothing_time, 1, PRI_LOW, 0x63, 0, 0x07, 4, temp_st),
+	PWRITE(temp3_smoothing_time, 2, PRI_LOW, 0x63, 0, 0x07, 0, temp_st),
+	PWRITE(temp4_smoothing_time, 3, PRI_LOW, 0x3c, 0, 0x07, 0, temp_st),
+
+	PWRITE(temp1_auto_point1_temp_hyst, 0, PRI_LOW, 0x6d, 0, 0x0f, 4,
+	       bitmask),
+	PWRITE(temp2_auto_point1_temp_hyst, 1, PRI_LOW, 0x6d, 0, 0x0f, 0,
+	       bitmask),
+	PWRITE(temp3_auto_point1_temp_hyst, 2, PRI_LOW, 0x6e, 0, 0x0f, 4,
+	       bitmask),
+	PWRITE(temp4_auto_point1_temp_hyst, 3, PRI_LOW, 0x6e, 0, 0x0f, 0,
+	       bitmask),
+
+	PREAD(temp1_auto_point2_temp_hyst, 0, PRI_LOW, 0x6d, 0, 0x0f, 4,
+	      bitmask),
+	PREAD(temp2_auto_point2_temp_hyst, 1, PRI_LOW, 0x6d, 0, 0x0f, 0,
+	      bitmask),
+	PREAD(temp3_auto_point2_temp_hyst, 2, PRI_LOW, 0x6e, 0, 0x0f, 4,
+	      bitmask),
+	PREAD(temp4_auto_point2_temp_hyst, 3, PRI_LOW, 0x6e, 0, 0x0f, 0,
+	      bitmask),
+
+	PWRITE(temp1_auto_point1_temp, 0, PRI_LOW, 0x67, 0, 0, 0, temp8),
+	PWRITE(temp2_auto_point1_temp, 1, PRI_LOW, 0x68, 0, 0, 0, temp8),
+	PWRITE(temp3_auto_point1_temp, 2, PRI_LOW, 0x69, 0, 0, 0, temp8),
+	PWRITE(temp4_auto_point1_temp, 3, PRI_LOW, 0x3b, 0, 0, 0, temp8),
+
+	PWRITEM(temp1_auto_point2_temp, 0, PRI_LOW, VAA(0x5f, 0x67), VAA(0),
+		VAA(0x0f), VAA(4), ap2_temp),
+	PWRITEM(temp2_auto_point2_temp, 1, PRI_LOW, VAA(0x60, 0x68), VAA(0),
+		VAA(0x0f), VAA(4), ap2_temp),
+	PWRITEM(temp3_auto_point2_temp, 2, PRI_LOW, VAA(0x61, 0x69), VAA(0),
+		VAA(0x0f), VAA(4), ap2_temp),
+	PWRITEM(temp4_auto_point2_temp, 3, PRI_LOW, VAA(0x3c, 0x3b), VAA(0),
+		VAA(0x0f), VAA(4), ap2_temp),
+
+	PWRITE(temp1_crit, 0, PRI_LOW, 0x6a, 0, 0, 0, temp8),
+	PWRITE(temp2_crit, 1, PRI_LOW, 0x6b, 0, 0, 0, temp8),
+	PWRITE(temp3_crit, 2, PRI_LOW, 0x6c, 0, 0, 0, temp8),
+	PWRITE(temp4_crit, 3, PRI_LOW, 0x3d, 0, 0, 0, temp8),
+
+	PWRITE(temp5_enable, 4, PRI_LOW, 0x0e, 0, 0x01, 0, bitmask),
+	PWRITE(temp6_enable, 5, PRI_LOW, 0x0e, 0, 0x01, 1, bitmask),
+	PWRITE(temp7_enable, 6, PRI_LOW, 0x0e, 0, 0x01, 2, bitmask),
+	PWRITE(temp8_enable, 7, PRI_LOW, 0x0e, 0, 0x01, 3, bitmask),
+
+	PWRITE(remote1_offset, 0, PRI_LOW, 0x1c, 0, 0, 0, temp62),
+	PWRITE(remote2_offset, 1, PRI_LOW, 0x1d, 0, 0, 0, temp62),
+
+	PWRITE(pwm1, 0, PRI_HIGH, 0x30, 0, 0, 0, u8),
+	PWRITE(pwm2, 1, PRI_HIGH, 0x31, 0, 0, 0, u8),
+	PWRITE(pwm3, 2, PRI_HIGH, 0x32, 0, 0, 0, u8),
+
+	PWRITE(pwm1_invert, 0, PRI_LOW, 0x5c, 0, 0x01, 4, bitmask),
+	PWRITE(pwm2_invert, 1, PRI_LOW, 0x5d, 0, 0x01, 4, bitmask),
+	PWRITE(pwm3_invert, 2, PRI_LOW, 0x5e, 0, 0x01, 4, bitmask),
+
+	PWRITEM(pwm1_enable, 0, PRI_LOW, VAA(0x5c, 0x5c, 0x62), VAA(0, 0, 0),
+		VAA(0x07, 0x01, 0x01), VAA(5, 3, 5), pwm_enable),
+	PWRITEM(pwm2_enable, 1, PRI_LOW, VAA(0x5d, 0x5d, 0x62), VAA(0, 0, 0),
+		VAA(0x07, 0x01, 0x01), VAA(5, 3, 6), pwm_enable),
+	PWRITEM(pwm3_enable, 2, PRI_LOW, VAA(0x5e, 0x5e, 0x62), VAA(0, 0, 0),
+		VAA(0x07, 0x01, 0x01), VAA(5, 3, 7), pwm_enable),
+
+	PWRITEM(pwm1_auto_channels, 0, PRI_LOW, VAA(0x5c, 0x5c), VAA(0, 0),
+		VAA(0x07, 0x01), VAA(5, 3), pwm_ac),
+	PWRITEM(pwm2_auto_channels, 1, PRI_LOW, VAA(0x5d, 0x5d), VAA(0, 0),
+		VAA(0x07, 0x01), VAA(5, 3), pwm_ac),
+	PWRITEM(pwm3_auto_channels, 2, PRI_LOW, VAA(0x5e, 0x5e), VAA(0, 0),
+		VAA(0x07, 0x01), VAA(5, 3), pwm_ac),
+
+	PWRITE(pwm1_auto_point1_pwm, 0, PRI_LOW, 0x64, 0, 0, 0, u8),
+	PWRITE(pwm2_auto_point1_pwm, 1, PRI_LOW, 0x65, 0, 0, 0, u8),
+	PWRITE(pwm3_auto_point1_pwm, 2, PRI_LOW, 0x66, 0, 0, 0, u8),
+
+	PWRITE(pwm1_auto_point2_pwm, 0, PRI_LOW, 0x38, 0, 0, 0, u8),
+	PWRITE(pwm2_auto_point2_pwm, 1, PRI_LOW, 0x39, 0, 0, 0, u8),
+	PWRITE(pwm3_auto_point2_pwm, 2, PRI_LOW, 0x3a, 0, 0, 0, u8),
+
+	PWRITE(pwm1_freq, 0, PRI_LOW, 0x5f, 0, 0x0f, 0, pwm_freq),
+	PWRITE(pwm2_freq, 1, PRI_LOW, 0x60, 0, 0x0f, 0, pwm_freq),
+	PWRITE(pwm3_freq, 2, PRI_LOW, 0x61, 0, 0x0f, 0, pwm_freq),
+
+	PREAD(pwm1_auto_zone_assigned, 0, PRI_LOW, 0, 0, 0x03, 2, bitmask),
+	PREAD(pwm2_auto_zone_assigned, 1, PRI_LOW, 0, 0, 0x03, 4, bitmask),
+	PREAD(pwm3_auto_zone_assigned, 2, PRI_LOW, 0, 0, 0x03, 6, bitmask),
+
+	PWRITE(pwm1_auto_spinup_time, 0, PRI_LOW, 0x5c, 0, 0x07, 0, pwm_ast),
+	PWRITE(pwm2_auto_spinup_time, 1, PRI_LOW, 0x5d, 0, 0x07, 0, pwm_ast),
+	PWRITE(pwm3_auto_spinup_time, 2, PRI_LOW, 0x5e, 0, 0x07, 0, pwm_ast),
+
+	PWRITE(peci_enable, 0, PRI_LOW, 0x40, 0, 0x01, 4, bitmask),
+	PWRITE(peci_avg, 0, PRI_LOW, 0x36, 0, 0x07, 0, bitmask),
+	PWRITE(peci_domain, 0, PRI_LOW, 0x36, 0, 0x01, 3, bitmask),
+	PWRITE(peci_legacy, 0, PRI_LOW, 0x36, 0, 0x01, 4, bitmask),
+	PWRITE(peci_diode, 0, PRI_LOW, 0x0e, 0, 0x07, 4, bitmask),
+	PWRITE(peci_4domain, 0, PRI_LOW, 0x0e, 0, 0x01, 4, bitmask),
+
+};
+
+static struct asc7621_data *asc7621_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct asc7621_data *data = i2c_get_clientdata(client);
+	int i;
+
+/*
+ * The asc7621 chips guarantee consistent reads of multi-byte values
+ * regardless of the order of the reads.  No special logic is needed
+ * so we can just read the registers in whatever  order they appear
+ * in the asc7621_params array.
+ */
+
+	mutex_lock(&data->update_lock);
+
+	/* Read all the high priority registers */
+
+	if (!data->valid ||
+	    time_after(jiffies, data->last_high_reading + INTERVAL_HIGH)) {
+
+		for (i = 0; i < ARRAY_SIZE(asc7621_register_priorities); i++) {
+			if (asc7621_register_priorities[i] == PRI_HIGH) {
+				data->reg[i] =
+				    i2c_smbus_read_byte_data(client, i) & 0xff;
+			}
+		}
+		data->last_high_reading = jiffies;
+	};			/* last_reading */
+
+	/* Read all the low priority registers. */
+
+	if (!data->valid ||
+	    time_after(jiffies, data->last_low_reading + INTERVAL_LOW)) {
+
+		for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
+			if (asc7621_register_priorities[i] == PRI_LOW) {
+				data->reg[i] =
+				    i2c_smbus_read_byte_data(client, i) & 0xff;
+			}
+		}
+		data->last_low_reading = jiffies;
+	};			/* last_reading */
+
+	data->valid = 1;
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
+/*
+ * Standard detection and initialization below
+ *
+ * Helper function that checks if an address is valid
+ * for a particular chip.
+ */
+
+static inline int valid_address_for_chip(int chip_type, int address)
+{
+	int i;
+
+	for (i = 0; asc7621_chips[chip_type].addresses[i] != I2C_CLIENT_END;
+	     i++) {
+		if (asc7621_chips[chip_type].addresses[i] == address)
+			return 1;
+	}
+	return 0;
+}
+
+static void asc7621_init_client(struct i2c_client *client)
+{
+	int value;
+
+	/* Warn if part was not "READY" */
+
+	value = read_byte(client, 0x40);
+
+	if (value & 0x02) {
+		dev_err(&client->dev,
+			"Client (%d,0x%02x) config is locked.\n",
+			i2c_adapter_id(client->adapter), client->addr);
+	};
+	if (!(value & 0x04)) {
+		dev_err(&client->dev, "Client (%d,0x%02x) is not ready.\n",
+			i2c_adapter_id(client->adapter), client->addr);
+	};
+
+/*
+ * Start monitoring
+ *
+ * Try to clear LOCK, Set START, save everything else
+ */
+	value = (value & ~0x02) | 0x01;
+	write_byte(client, 0x40, value & 0xff);
+
+}
+
+static int
+asc7621_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	struct asc7621_data *data;
+	int i, err;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	data = kzalloc(sizeof(struct asc7621_data), GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, data);
+	data->valid = 0;
+	mutex_init(&data->update_lock);
+
+	/* Initialize the asc7621 chip */
+	asc7621_init_client(client);
+
+	/* Create the sysfs entries */
+	for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
+		err =
+		    device_create_file(&client->dev,
+				       &(asc7621_params[i].sda.dev_attr));
+		if (err)
+			goto exit_remove;
+	}
+
+	data->class_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(data->class_dev)) {
+		err = PTR_ERR(data->class_dev);
+		goto exit_remove;
+	}
+
+	return 0;
+
+exit_remove:
+	for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
+		device_remove_file(&client->dev,
+				   &(asc7621_params[i].sda.dev_attr));
+	}
+
+	i2c_set_clientdata(client, NULL);
+	kfree(data);
+	return err;
+}
+
+static int asc7621_detect(struct i2c_client *client,
+			  struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = client->adapter;
+	int company, verstep, chip_index;
+	struct device *dev;
+
+	dev = &client->dev;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	for (chip_index = FIRST_CHIP; chip_index <= LAST_CHIP; chip_index++) {
+
+		if (!valid_address_for_chip(chip_index, client->addr))
+			continue;
+
+		company = read_byte(client,
+			asc7621_chips[chip_index].company_reg);
+		verstep = read_byte(client,
+			asc7621_chips[chip_index].verstep_reg);
+
+		if (company == asc7621_chips[chip_index].company_id &&
+		    verstep == asc7621_chips[chip_index].verstep_id) {
+			strlcpy(client->name, asc7621_chips[chip_index].name,
+				I2C_NAME_SIZE);
+			strlcpy(info->type, asc7621_chips[chip_index].name,
+				I2C_NAME_SIZE);
+
+			dev_info(&adapter->dev, "Matched %s\n",
+				 asc7621_chips[chip_index].name);
+			return 0;
+		}
+	}
+
+	return -ENODEV;
+}
+
+static int asc7621_remove(struct i2c_client *client)
+{
+	struct asc7621_data *data = i2c_get_clientdata(client);
+	int i;
+
+	hwmon_device_unregister(data->class_dev);
+
+	for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
+		device_remove_file(&client->dev,
+				   &(asc7621_params[i].sda.dev_attr));
+	}
+
+	i2c_set_clientdata(client, NULL);
+	kfree(data);
+	return 0;
+}
+
+static const struct i2c_device_id asc7621_id[] = {
+	{"asc7621", asc7621},
+	{"asc7621a", asc7621a},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, asc7621_id);
+
+static struct i2c_driver asc7621_driver = {
+	.class = I2C_CLASS_HWMON,
+	.driver = {
+		.name = "asc7621",
+	},
+	.probe = asc7621_probe,
+	.remove = asc7621_remove,
+	.id_table = asc7621_id,
+	.detect = asc7621_detect,
+	.address_list = normal_i2c,
+};
+
+static int __init sm_asc7621_init(void)
+{
+	int i, j;
+/*
+ * Collect all the registers needed into a single array.
+ * This way, if a register isn't actually used for anything,
+ * we don't retrieve it.
+ */
+
+	for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
+		for (j = 0; j < ARRAY_SIZE(asc7621_params[i].msb); j++)
+			asc7621_register_priorities[asc7621_params[i].msb[j]] =
+			    asc7621_params[i].priority;
+		for (j = 0; j < ARRAY_SIZE(asc7621_params[i].lsb); j++)
+			asc7621_register_priorities[asc7621_params[i].lsb[j]] =
+			    asc7621_params[i].priority;
+	}
+	return i2c_add_driver(&asc7621_driver);
+}
+
+static void __exit sm_asc7621_exit(void)
+{
+	i2c_del_driver(&asc7621_driver);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("George Joseph");
+MODULE_DESCRIPTION("Andigilog aSC7621 and aSC7621a driver");
+
+module_init(sm_asc7621_init);
+module_exit(sm_asc7621_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/asus_atk0110.c linux-libre-2.6.34-gnu1/drivers/hwmon/asus_atk0110.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/asus_atk0110.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/asus_atk0110.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/hwmon.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <acpi/acpi.h>
 #include <acpi/acpixf.h>
@@ -1168,15 +1169,19 @@ static int atk_create_files(struct atk_d
 	int err;
 
 	list_for_each_entry(s, &data->sensor_list, list) {
+		sysfs_attr_init(&s->input_attr.attr);
 		err = device_create_file(data->hwmon_dev, &s->input_attr);
 		if (err)
 			return err;
+		sysfs_attr_init(&s->label_attr.attr);
 		err = device_create_file(data->hwmon_dev, &s->label_attr);
 		if (err)
 			return err;
+		sysfs_attr_init(&s->limit1_attr.attr);
 		err = device_create_file(data->hwmon_dev, &s->limit1_attr);
 		if (err)
 			return err;
+		sysfs_attr_init(&s->limit2_attr.attr);
 		err = device_create_file(data->hwmon_dev, &s->limit2_attr);
 		if (err)
 			return err;
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/atxp1.c linux-libre-2.6.34-gnu1/drivers/hwmon/atxp1.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/atxp1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/atxp1.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("System voltages control via Attansic ATXP1");
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/coretemp.c linux-libre-2.6.34-gnu1/drivers/hwmon/coretemp.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/coretemp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/coretemp.c	2010-05-16 17:17:36.000000000 -0400
@@ -228,7 +228,7 @@ static int __devinit adjust_tjmax(struct
 		if (err) {
 			dev_warn(dev,
 				 "Unable to access MSR 0xEE, for Tjmax, left"
-				 " at default");
+				 " at default\n");
 		} else if (eax & 0x40000000) {
 			tjmax = tjmax_ee;
 		}
@@ -466,7 +466,7 @@ static int __init coretemp_init(void)
 			   family 6 CPU */
 			if ((c->x86 == 0x6) && (c->x86_model > 0xf))
 				printk(KERN_WARNING DRVNAME ": Unknown CPU "
-					"model %x\n", c->x86_model);
+					"model 0x%x\n", c->x86_model);
 			continue;
 		}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/f75375s.c linux-libre-2.6.34-gnu1/drivers/hwmon/f75375s.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/f75375s.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/f75375s.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/f75375s.h>
+#include <linux/slab.h>
 
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END };
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/fschmd.c linux-libre-2.6.34-gnu1/drivers/hwmon/fschmd.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/fschmd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/fschmd.c	2010-05-16 17:17:36.000000000 -0400
@@ -267,7 +267,7 @@ struct fschmd_data {
 	struct list_head list; /* member of the watchdog_data_list */
 	struct kref kref;
 	struct miscdevice watchdog_miscdev;
-	int kind;
+	enum chips kind;
 	unsigned long watchdog_is_open;
 	char watchdog_expect_close;
 	char watchdog_name[10]; /* must be unique to avoid sysfs conflict */
@@ -325,8 +325,7 @@ static ssize_t show_in_value(struct devi
 	int index = to_sensor_dev_attr(devattr)->index;
 	struct fschmd_data *data = fschmd_update_device(dev);
 
-	/* fscher / fschrc - 1 as data->kind is an array index, not a chips */
-	if (data->kind == (fscher - 1) || data->kind >= (fschrc - 1))
+	if (data->kind == fscher || data->kind >= fschrc)
 		return sprintf(buf, "%d\n", (data->volt[index] * dmi_vref *
 			dmi_mult[index]) / 255 + dmi_offset[index]);
 	else
@@ -492,7 +491,7 @@ static ssize_t show_pwm_auto_point1_pwm(
 	int val = data->fan_min[index];
 
 	/* 0 = allow turning off (except on the syl), 1-255 = 50-100% */
-	if (val || data->kind == fscsyl - 1)
+	if (val || data->kind == fscsyl)
 		val = val / 2 + 128;
 
 	return sprintf(buf, "%d\n", val);
@@ -506,7 +505,7 @@ static ssize_t store_pwm_auto_point1_pwm
 	unsigned long v = simple_strtoul(buf, NULL, 10);
 
 	/* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */
-	if (v || data->kind == fscsyl - 1) {
+	if (v || data->kind == fscsyl) {
 		v = SENSORS_LIMIT(v, 128, 255);
 		v = (v - 128) * 2 + 1;
 	}
@@ -1037,7 +1036,7 @@ static int fschmd_detect(struct i2c_clie
 	else
 		return -ENODEV;
 
-	strlcpy(info->type, fschmd_id[kind - 1].name, I2C_NAME_SIZE);
+	strlcpy(info->type, fschmd_id[kind].name, I2C_NAME_SIZE);
 
 	return 0;
 }
@@ -1065,6 +1064,7 @@ static int fschmd_probe(struct i2c_clien
 	   (where the client is found through a data ptr instead of the
 	   otherway around) */
 	data->client = client;
+	data->kind = kind;
 
 	if (kind == fscpos) {
 		/* The Poseidon has hardwired temp limits, fill these
@@ -1085,9 +1085,6 @@ 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,
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/g760a.c linux-libre-2.6.34-gnu1/drivers/hwmon/g760a.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/g760a.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/g760a.c	2010-05-16 17:17:36.000000000 -0400
@@ -68,7 +68,7 @@ struct g760a_data {
 #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)
+static inline unsigned int rpm_from_cnt(u8 val, u32 clk, u16 div)
 {
 	return ((val == 0x00) ? 0 : ((clk*30)/(val*div)));
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/hp_accel.c linux-libre-2.6.34-gnu1/drivers/hwmon/hp_accel.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/hp_accel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/hp_accel.c	2010-05-16 17:17:36.000000000 -0400
@@ -217,6 +217,10 @@ static struct dmi_system_id lis3lv02d_dm
 	AXIS_DMI_MATCH("DV7", "HP Pavilion dv7", x_inverted),
 	AXIS_DMI_MATCH("HP8710", "HP Compaq 8710", y_inverted),
 	AXIS_DMI_MATCH("HDX18", "HP HDX 18", x_inverted),
+	AXIS_DMI_MATCH("HPB432x", "HP ProBook 432", xy_rotated_left),
+	AXIS_DMI_MATCH("HPB442x", "HP ProBook 442", xy_rotated_left),
+	AXIS_DMI_MATCH("HPB452x", "HP ProBook 452", y_inverted),
+	AXIS_DMI_MATCH("HPB522x", "HP ProBook 522", xy_swap),
 	{ NULL, }
 /* Laptop models without axis info (yet):
  * "NC6910" "HP Compaq 6910"
@@ -324,8 +328,8 @@ static int lis3lv02d_remove(struct acpi_
 	lis3lv02d_joystick_disable();
 	lis3lv02d_poweroff(&lis3_dev);
 
-	flush_work(&hpled_led.work);
 	led_classdev_unregister(&hpled_led.led_classdev);
+	flush_work(&hpled_led.work);
 
 	return lis3lv02d_remove_fs(&lis3_dev);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/i5k_amb.c linux-libre-2.6.34-gnu1/drivers/hwmon/i5k_amb.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/i5k_amb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/i5k_amb.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/log2.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #define DRVNAME "i5k_amb"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/ibmaem.c linux-libre-2.6.34-gnu1/drivers/hwmon/ibmaem.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/ibmaem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/ibmaem.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/kdev_t.h>
 #include <linux/spinlock.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/platform_device.h>
 #include <linux/math64.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/ibmpex.c linux-libre-2.6.34-gnu1/drivers/hwmon/ibmpex.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/ibmpex.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/ibmpex.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/jiffies.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #define REFRESH_INTERVAL	(2 * HZ)
 #define DRVNAME			"ibmpex"
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/it87.c linux-libre-2.6.34-gnu1/drivers/hwmon/it87.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/it87.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/it87.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,40 +1,40 @@
 /*
-    it87.c - Part of lm_sensors, Linux kernel modules for hardware
-             monitoring.
-
-    The IT8705F is an LPC-based Super I/O part that contains UARTs, a
-    parallel port, an IR port, a MIDI port, a floppy controller, etc., in
-    addition to an Environment Controller (Enhanced Hardware Monitor and
-    Fan Controller)
-
-    This driver supports only the Environment Controller in the IT8705F and
-    similar parts.  The other devices are supported by different drivers.
-
-    Supports: IT8705F  Super I/O chip w/LPC interface
-              IT8712F  Super I/O chip w/LPC interface
-              IT8716F  Super I/O chip w/LPC interface
-              IT8718F  Super I/O chip w/LPC interface
-              IT8720F  Super I/O chip w/LPC interface
-              IT8726F  Super I/O chip w/LPC interface
-              Sis950   A clone of the IT8705F
-
-    Copyright (C) 2001 Chris Gauthron
-    Copyright (C) 2005-2007 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.
-*/
+ *  it87.c - Part of lm_sensors, Linux kernel modules for hardware
+ *           monitoring.
+ *
+ *  The IT8705F is an LPC-based Super I/O part that contains UARTs, a
+ *  parallel port, an IR port, a MIDI port, a floppy controller, etc., in
+ *  addition to an Environment Controller (Enhanced Hardware Monitor and
+ *  Fan Controller)
+ *
+ *  This driver supports only the Environment Controller in the IT8705F and
+ *  similar parts.  The other devices are supported by different drivers.
+ *
+ *  Supports: IT8705F  Super I/O chip w/LPC interface
+ *            IT8712F  Super I/O chip w/LPC interface
+ *            IT8716F  Super I/O chip w/LPC interface
+ *            IT8718F  Super I/O chip w/LPC interface
+ *            IT8720F  Super I/O chip w/LPC interface
+ *            IT8726F  Super I/O chip w/LPC interface
+ *            Sis950   A clone of the IT8705F
+ *
+ *  Copyright (C) 2001 Chris Gauthron
+ *  Copyright (C) 2005-2010 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>
@@ -128,6 +128,7 @@ superio_exit(void)
 #define IT87_SIO_GPIO5_REG	0x29
 #define IT87_SIO_PINX2_REG	0x2c	/* Pin selection */
 #define IT87_SIO_VID_REG	0xfc	/* VID value */
+#define IT87_SIO_BEEP_PIN_REG	0xf6	/* Beep pin mapping */
 
 /* Update battery voltage after every reading if true */
 static int update_vbat;
@@ -187,9 +188,13 @@ static const u8 IT87_REG_FANX_MIN[]	= {
 
 #define IT87_REG_VIN_ENABLE    0x50
 #define IT87_REG_TEMP_ENABLE   0x51
+#define IT87_REG_BEEP_ENABLE   0x5c
 
 #define IT87_REG_CHIPID        0x58
 
+#define IT87_REG_AUTO_TEMP(nr, i) (0x60 + (nr) * 8 + (i))
+#define IT87_REG_AUTO_PWM(nr, i)  (0x65 + (nr) * 8 + (i))
+
 #define IN_TO_REG(val)  (SENSORS_LIMIT((((val) + 8)/16),0,255))
 #define IN_FROM_REG(val) ((val) * 16)
 
@@ -246,6 +251,7 @@ struct it87_sio_data {
 	/* Values read from Super-I/O config space */
 	u8 revision;
 	u8 vid_value;
+	u8 beep_pin;
 	/* Features skipped based on config or DMI */
 	u8 skip_vid;
 	u8 skip_fan;
@@ -279,9 +285,21 @@ struct it87_data {
 	u8 vid;			/* Register encoding, combined */
 	u8 vrm;
 	u32 alarms;		/* Register encoding, combined */
+	u8 beeps;		/* Register encoding */
 	u8 fan_main_ctrl;	/* Register value */
 	u8 fan_ctl;		/* Register value */
-	u8 manual_pwm_ctl[3];   /* manual PWM value set by user */
+
+	/* The following 3 arrays correspond to the same registers. The
+	 * meaning of bits 6-0 depends on the value of bit 7, and we want
+	 * to preserve settings on mode changes, so we have to track all
+	 * values separately. */
+	u8 pwm_ctrl[3];		/* Register value */
+	u8 pwm_duty[3];		/* Manual PWM value set by user (bit 6-0) */
+	u8 pwm_temp_map[3];	/* PWM to temp. chan. mapping (bits 1-0) */
+
+	/* Automatic fan speed control registers */
+	u8 auto_pwm[3][4];	/* [nr][3] is hard-coded */
+	s8 auto_temp[3][5];	/* [nr][0] is point1_temp_hyst */
 };
 
 static inline int has_16bit_fans(const struct it87_data *data)
@@ -296,6 +314,15 @@ static inline int has_16bit_fans(const s
 	    || data->type == it8720;
 }
 
+static inline int has_old_autopwm(const struct it87_data *data)
+{
+	/* The old automatic fan speed control interface is implemented
+	   by IT8705F chips up to revision F and IT8712F chips up to
+	   revision G. */
+	return (data->type == it87 && data->revision < 0x03)
+	    || (data->type == it8712 && data->revision < 0x08);
+}
+
 static int it87_probe(struct platform_device *pdev);
 static int __devexit it87_remove(struct platform_device *pdev);
 
@@ -352,7 +379,10 @@ static ssize_t set_in_min(struct device
 	int nr = sensor_attr->index;
 
 	struct it87_data *data = dev_get_drvdata(dev);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+
+	if (strict_strtoul(buf, 10, &val) < 0)
+		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[nr] = IN_TO_REG(val);
@@ -368,7 +398,10 @@ static ssize_t set_in_max(struct device
 	int nr = sensor_attr->index;
 
 	struct it87_data *data = dev_get_drvdata(dev);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+
+	if (strict_strtoul(buf, 10, &val) < 0)
+		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[nr] = IN_TO_REG(val);
@@ -441,7 +474,10 @@ static ssize_t set_temp_max(struct devic
 	int nr = sensor_attr->index;
 
 	struct it87_data *data = dev_get_drvdata(dev);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+
+	if (strict_strtol(buf, 10, &val) < 0)
+		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
 	data->temp_high[nr] = TEMP_TO_REG(val);
@@ -456,7 +492,10 @@ static ssize_t set_temp_min(struct devic
 	int nr = sensor_attr->index;
 
 	struct it87_data *data = dev_get_drvdata(dev);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+
+	if (strict_strtol(buf, 10, &val) < 0)
+		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
 	data->temp_low[nr] = TEMP_TO_REG(val);
@@ -483,8 +522,9 @@ static ssize_t show_sensor(struct device
 	int nr = sensor_attr->index;
 
 	struct it87_data *data = it87_update_device(dev);
-	u8 reg = data->sensor; /* In case the value is updated while we use it */
-	
+	u8 reg = data->sensor;		/* In case the value is updated while
+					   we use it */
+
 	if (reg & (1 << nr))
 		return sprintf(buf, "3\n");  /* thermal diode */
 	if (reg & (8 << nr))
@@ -498,12 +538,15 @@ static ssize_t set_sensor(struct device
 	int nr = sensor_attr->index;
 
 	struct it87_data *data = dev_get_drvdata(dev);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	u8 reg;
 
-	mutex_lock(&data->update_lock);
+	if (strict_strtol(buf, 10, &val) < 0)
+		return -EINVAL;
 
-	data->sensor &= ~(1 << nr);
-	data->sensor &= ~(8 << nr);
+	reg = it87_read_value(data, IT87_REG_TEMP_ENABLE);
+	reg &= ~(1 << nr);
+	reg &= ~(8 << nr);
 	if (val == 2) {	/* backwards compatibility */
 		dev_warn(dev, "Sensor type 2 is deprecated, please use 4 "
 			 "instead\n");
@@ -511,14 +554,16 @@ static ssize_t set_sensor(struct device
 	}
 	/* 3 = thermal diode; 4 = thermistor; 0 = disabled */
 	if (val == 3)
-	    data->sensor |= 1 << nr;
+		reg |= 1 << nr;
 	else if (val == 4)
-	    data->sensor |= 8 << nr;
-	else if (val != 0) {
-		mutex_unlock(&data->update_lock);
+		reg |= 8 << nr;
+	else if (val != 0)
 		return -EINVAL;
-	}
+
+	mutex_lock(&data->update_lock);
+	data->sensor = reg;
 	it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor);
+	data->valid = 0;	/* Force cache refresh */
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -531,6 +576,19 @@ show_sensor_offset(2);
 show_sensor_offset(3);
 
 /* 3 Fans */
+
+static int pwm_mode(const struct it87_data *data, int nr)
+{
+	int ctrl = data->fan_main_ctrl & (1 << nr);
+
+	if (ctrl == 0)					/* Full speed */
+		return 0;
+	if (data->pwm_ctrl[nr] & 0x80)			/* Automatic mode */
+		return 2;
+	else						/* Manual mode */
+		return 1;
+}
+
 static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
 		char *buf)
 {
@@ -538,7 +596,7 @@ static ssize_t show_fan(struct device *d
 	int nr = sensor_attr->index;
 
 	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr], 
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
 				DIV_FROM_REG(data->fan_div[nr])));
 }
 static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr,
@@ -548,8 +606,8 @@ static ssize_t show_fan_min(struct devic
 	int nr = sensor_attr->index;
 
 	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf,"%d\n",
-		FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])));
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
+				DIV_FROM_REG(data->fan_div[nr])));
 }
 static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
 		char *buf)
@@ -560,14 +618,14 @@ static ssize_t show_fan_div(struct devic
 	struct it87_data *data = it87_update_device(dev);
 	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
 }
-static ssize_t show_pwm_enable(struct device *dev, struct device_attribute *attr,
-		char *buf)
+static ssize_t show_pwm_enable(struct device *dev,
+		struct device_attribute *attr, char *buf)
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 
 	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf,"%d\n", (data->fan_main_ctrl & (1 << nr)) ? 1 : 0);
+	return sprintf(buf, "%d\n", pwm_mode(data, nr));
 }
 static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
 		char *buf)
@@ -576,7 +634,7 @@ static ssize_t show_pwm(struct device *d
 	int nr = sensor_attr->index;
 
 	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf,"%d\n", data->manual_pwm_ctl[nr]);
+	return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm_duty[nr]));
 }
 static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr,
 		char *buf)
@@ -593,15 +651,24 @@ static ssize_t set_fan_min(struct device
 	int nr = sensor_attr->index;
 
 	struct it87_data *data = dev_get_drvdata(dev);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
 	u8 reg;
 
+	if (strict_strtol(buf, 10, &val) < 0)
+		return -EINVAL;
+
 	mutex_lock(&data->update_lock);
 	reg = it87_read_value(data, IT87_REG_FAN_DIV);
 	switch (nr) {
-	case 0: data->fan_div[nr] = reg & 0x07; break;
-	case 1: data->fan_div[nr] = (reg >> 3) & 0x07; break;
-	case 2: data->fan_div[nr] = (reg & 0x40) ? 3 : 1; break;
+	case 0:
+		data->fan_div[nr] = reg & 0x07;
+		break;
+	case 1:
+		data->fan_div[nr] = (reg >> 3) & 0x07;
+		break;
+	case 2:
+		data->fan_div[nr] = (reg & 0x40) ? 3 : 1;
+		break;
 	}
 
 	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
@@ -616,10 +683,13 @@ static ssize_t set_fan_div(struct device
 	int nr = sensor_attr->index;
 
 	struct it87_data *data = dev_get_drvdata(dev);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
 	int min;
 	u8 old;
 
+	if (strict_strtoul(buf, 10, &val) < 0)
+		return -EINVAL;
+
 	mutex_lock(&data->update_lock);
 	old = it87_read_value(data, IT87_REG_FAN_DIV);
 
@@ -651,6 +721,32 @@ static ssize_t set_fan_div(struct device
 	mutex_unlock(&data->update_lock);
 	return count;
 }
+
+/* Returns 0 if OK, -EINVAL otherwise */
+static int check_trip_points(struct device *dev, int nr)
+{
+	const struct it87_data *data = dev_get_drvdata(dev);
+	int i, err = 0;
+
+	if (has_old_autopwm(data)) {
+		for (i = 0; i < 3; i++) {
+			if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1])
+				err = -EINVAL;
+		}
+		for (i = 0; i < 2; i++) {
+			if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1])
+				err = -EINVAL;
+		}
+	}
+
+	if (err) {
+		dev_err(dev, "Inconsistent trip points, not switching to "
+			"automatic mode\n");
+		dev_err(dev, "Adjust the trip points and try again\n");
+	}
+	return err;
+}
+
 static ssize_t set_pwm_enable(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
@@ -658,7 +754,16 @@ static ssize_t set_pwm_enable(struct dev
 	int nr = sensor_attr->index;
 
 	struct it87_data *data = dev_get_drvdata(dev);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+
+	if (strict_strtol(buf, 10, &val) < 0 || val < 0 || val > 2)
+		return -EINVAL;
+
+	/* Check trip points before switching to automatic mode */
+	if (val == 2) {
+		if (check_trip_points(dev, nr) < 0)
+			return -EINVAL;
+	}
 
 	mutex_lock(&data->update_lock);
 
@@ -669,16 +774,18 @@ static ssize_t set_pwm_enable(struct dev
 		it87_write_value(data, IT87_REG_FAN_CTL, tmp | (1 << nr));
 		/* set on/off mode */
 		data->fan_main_ctrl &= ~(1 << nr);
-		it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
-	} else if (val == 1) {
+		it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
+				 data->fan_main_ctrl);
+	} else {
+		if (val == 1)				/* Manual mode */
+			data->pwm_ctrl[nr] = data->pwm_duty[nr];
+		else					/* Automatic mode */
+			data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
+		it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
 		/* set SmartGuardian mode */
 		data->fan_main_ctrl |= (1 << nr);
-		it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
-		/* set saved pwm value, clear FAN_CTLX PWM mode bit */
-		it87_write_value(data, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
-	} else {
-		mutex_unlock(&data->update_lock);
-		return -EINVAL;
+		it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
+				 data->fan_main_ctrl);
 	}
 
 	mutex_unlock(&data->update_lock);
@@ -691,15 +798,19 @@ static ssize_t set_pwm(struct device *de
 	int nr = sensor_attr->index;
 
 	struct it87_data *data = dev_get_drvdata(dev);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
 
-	if (val < 0 || val > 255)
+	if (strict_strtol(buf, 10, &val) < 0 || val < 0 || val > 255)
 		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
-	data->manual_pwm_ctl[nr] = val;
-	if (data->fan_main_ctrl & (1 << nr))
-		it87_write_value(data, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
+	data->pwm_duty[nr] = PWM_TO_REG(val);
+	/* If we are in manual mode, write the duty cycle immediately;
+	 * otherwise, just store it for later use. */
+	if (!(data->pwm_ctrl[nr] & 0x80)) {
+		data->pwm_ctrl[nr] = data->pwm_duty[nr];
+		it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
+	}
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -707,9 +818,12 @@ static ssize_t set_pwm_freq(struct devic
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct it87_data *data = dev_get_drvdata(dev);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
 	int i;
 
+	if (strict_strtoul(buf, 10, &val) < 0)
+		return -EINVAL;
+
 	/* Search for the nearest available frequency */
 	for (i = 0; i < 7; i++) {
 		if (val > (pwm_freq[i] + pwm_freq[i+1]) / 2)
@@ -724,6 +838,132 @@ static ssize_t set_pwm_freq(struct devic
 
 	return count;
 }
+static ssize_t show_pwm_temp_map(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct it87_data *data = it87_update_device(dev);
+	int map;
+
+	if (data->pwm_temp_map[nr] < 3)
+		map = 1 << data->pwm_temp_map[nr];
+	else
+		map = 0;			/* Should never happen */
+	return sprintf(buf, "%d\n", map);
+}
+static ssize_t set_pwm_temp_map(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct it87_data *data = dev_get_drvdata(dev);
+	long val;
+	u8 reg;
+
+	/* This check can go away if we ever support automatic fan speed
+	   control on newer chips. */
+	if (!has_old_autopwm(data)) {
+		dev_notice(dev, "Mapping change disabled for safety reasons\n");
+		return -EINVAL;
+	}
+
+	if (strict_strtol(buf, 10, &val) < 0)
+		return -EINVAL;
+
+	switch (val) {
+	case (1 << 0):
+		reg = 0x00;
+		break;
+	case (1 << 1):
+		reg = 0x01;
+		break;
+	case (1 << 2):
+		reg = 0x02;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	mutex_lock(&data->update_lock);
+	data->pwm_temp_map[nr] = reg;
+	/* If we are in automatic mode, write the temp mapping immediately;
+	 * otherwise, just store it for later use. */
+	if (data->pwm_ctrl[nr] & 0x80) {
+		data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
+		it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
+	}
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_auto_pwm(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct it87_data *data = it87_update_device(dev);
+	struct sensor_device_attribute_2 *sensor_attr =
+			to_sensor_dev_attr_2(attr);
+	int nr = sensor_attr->nr;
+	int point = sensor_attr->index;
+
+	return sprintf(buf, "%d\n", PWM_FROM_REG(data->auto_pwm[nr][point]));
+}
+
+static ssize_t set_auto_pwm(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct it87_data *data = dev_get_drvdata(dev);
+	struct sensor_device_attribute_2 *sensor_attr =
+			to_sensor_dev_attr_2(attr);
+	int nr = sensor_attr->nr;
+	int point = sensor_attr->index;
+	long val;
+
+	if (strict_strtol(buf, 10, &val) < 0 || val < 0 || val > 255)
+		return -EINVAL;
+
+	mutex_lock(&data->update_lock);
+	data->auto_pwm[nr][point] = PWM_TO_REG(val);
+	it87_write_value(data, IT87_REG_AUTO_PWM(nr, point),
+			 data->auto_pwm[nr][point]);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_auto_temp(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct it87_data *data = it87_update_device(dev);
+	struct sensor_device_attribute_2 *sensor_attr =
+			to_sensor_dev_attr_2(attr);
+	int nr = sensor_attr->nr;
+	int point = sensor_attr->index;
+
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->auto_temp[nr][point]));
+}
+
+static ssize_t set_auto_temp(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct it87_data *data = dev_get_drvdata(dev);
+	struct sensor_device_attribute_2 *sensor_attr =
+			to_sensor_dev_attr_2(attr);
+	int nr = sensor_attr->nr;
+	int point = sensor_attr->index;
+	long val;
+
+	if (strict_strtol(buf, 10, &val) < 0 || val < -128000 || val > 127000)
+		return -EINVAL;
+
+	mutex_lock(&data->update_lock);
+	data->auto_temp[nr][point] = TEMP_TO_REG(val);
+	it87_write_value(data, IT87_REG_AUTO_TEMP(nr, point),
+			 data->auto_temp[nr][point]);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
 
 #define show_fan_offset(offset)					\
 static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,		\
@@ -744,7 +984,36 @@ static SENSOR_DEVICE_ATTR(pwm##offset, S
 		show_pwm, set_pwm, offset - 1);				\
 static DEVICE_ATTR(pwm##offset##_freq,					\
 		(offset == 1 ? S_IRUGO | S_IWUSR : S_IRUGO),		\
-		show_pwm_freq, (offset == 1 ? set_pwm_freq : NULL));
+		show_pwm_freq, (offset == 1 ? set_pwm_freq : NULL));	\
+static SENSOR_DEVICE_ATTR(pwm##offset##_auto_channels_temp,		\
+		S_IRUGO | S_IWUSR, show_pwm_temp_map, set_pwm_temp_map,	\
+		offset - 1);						\
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point1_pwm,		\
+		S_IRUGO | S_IWUSR, show_auto_pwm, set_auto_pwm,		\
+		offset - 1, 0);						\
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point2_pwm,		\
+		S_IRUGO | S_IWUSR, show_auto_pwm, set_auto_pwm,		\
+		offset - 1, 1);						\
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point3_pwm,		\
+		S_IRUGO | S_IWUSR, show_auto_pwm, set_auto_pwm,		\
+		offset - 1, 2);						\
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point4_pwm,		\
+		S_IRUGO, show_auto_pwm, NULL, offset - 1, 3);		\
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point1_temp,		\
+		S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp,	\
+		offset - 1, 1);						\
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point1_temp_hyst,	\
+		S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp,	\
+		offset - 1, 0);						\
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point2_temp,		\
+		S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp,	\
+		offset - 1, 2);						\
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point3_temp,		\
+		S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp,	\
+		offset - 1, 3);						\
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point4_temp,		\
+		S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp,	\
+		offset - 1, 4);
 
 show_pwm_offset(1);
 show_pwm_offset(2);
@@ -775,7 +1044,10 @@ static ssize_t set_fan16_min(struct devi
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	struct it87_data *data = dev_get_drvdata(dev);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+
+	if (strict_strtol(buf, 10, &val) < 0)
+		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] = FAN16_TO_REG(val);
@@ -805,7 +1077,8 @@ show_fan16_offset(4);
 show_fan16_offset(5);
 
 /* Alarms */
-static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
+		char *buf)
 {
 	struct it87_data *data = it87_update_device(dev);
 	return sprintf(buf, "%u\n", data->alarms);
@@ -836,27 +1109,78 @@ static SENSOR_DEVICE_ATTR(temp1_alarm, S
 static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17);
 static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 18);
 
-static ssize_t
-show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_beep(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	int bitnr = to_sensor_dev_attr(attr)->index;
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf, "%u\n", (data->beeps >> bitnr) & 1);
+}
+static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	int bitnr = to_sensor_dev_attr(attr)->index;
+	struct it87_data *data = dev_get_drvdata(dev);
+	long val;
+
+	if (strict_strtol(buf, 10, &val) < 0
+	 || (val != 0 && val != 1))
+		return -EINVAL;
+
+	mutex_lock(&data->update_lock);
+	data->beeps = it87_read_value(data, IT87_REG_BEEP_ENABLE);
+	if (val)
+		data->beeps |= (1 << bitnr);
+	else
+		data->beeps &= ~(1 << bitnr);
+	it87_write_value(data, IT87_REG_BEEP_ENABLE, data->beeps);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+static SENSOR_DEVICE_ATTR(in0_beep, S_IRUGO | S_IWUSR,
+			  show_beep, set_beep, 1);
+static SENSOR_DEVICE_ATTR(in1_beep, S_IRUGO, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in2_beep, S_IRUGO, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in3_beep, S_IRUGO, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in4_beep, S_IRUGO, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in5_beep, S_IRUGO, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in6_beep, S_IRUGO, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in7_beep, S_IRUGO, show_beep, NULL, 1);
+/* fanX_beep writability is set later */
+static SENSOR_DEVICE_ATTR(fan1_beep, S_IRUGO, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan2_beep, S_IRUGO, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan4_beep, S_IRUGO, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan5_beep, S_IRUGO, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR,
+			  show_beep, set_beep, 2);
+static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO, show_beep, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO, show_beep, NULL, 2);
+
+static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr,
+		char *buf)
 {
 	struct it87_data *data = dev_get_drvdata(dev);
 	return sprintf(buf, "%u\n", data->vrm);
 }
-static ssize_t
-store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
 {
 	struct it87_data *data = dev_get_drvdata(dev);
-	u32 val;
+	unsigned long val;
+
+	if (strict_strtoul(buf, 10, &val) < 0)
+		return -EINVAL;
 
-	val = simple_strtoul(buf, NULL, 10);
 	data->vrm = val;
 
 	return count;
 }
 static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
 
-static ssize_t
-show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr,
+		char *buf)
 {
 	struct it87_data *data = it87_update_device(dev);
 	return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
@@ -931,51 +1255,176 @@ static const struct attribute_group it87
 	.attrs = it87_attributes,
 };
 
-static struct attribute *it87_attributes_opt[] = {
+static struct attribute *it87_attributes_beep[] = {
+	&sensor_dev_attr_in0_beep.dev_attr.attr,
+	&sensor_dev_attr_in1_beep.dev_attr.attr,
+	&sensor_dev_attr_in2_beep.dev_attr.attr,
+	&sensor_dev_attr_in3_beep.dev_attr.attr,
+	&sensor_dev_attr_in4_beep.dev_attr.attr,
+	&sensor_dev_attr_in5_beep.dev_attr.attr,
+	&sensor_dev_attr_in6_beep.dev_attr.attr,
+	&sensor_dev_attr_in7_beep.dev_attr.attr,
+
+	&sensor_dev_attr_temp1_beep.dev_attr.attr,
+	&sensor_dev_attr_temp2_beep.dev_attr.attr,
+	&sensor_dev_attr_temp3_beep.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group it87_group_beep = {
+	.attrs = it87_attributes_beep,
+};
+
+static struct attribute *it87_attributes_fan16[5][3+1] = { {
 	&sensor_dev_attr_fan1_input16.dev_attr.attr,
 	&sensor_dev_attr_fan1_min16.dev_attr.attr,
+	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
+	NULL
+}, {
 	&sensor_dev_attr_fan2_input16.dev_attr.attr,
 	&sensor_dev_attr_fan2_min16.dev_attr.attr,
+	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
+	NULL
+}, {
 	&sensor_dev_attr_fan3_input16.dev_attr.attr,
 	&sensor_dev_attr_fan3_min16.dev_attr.attr,
+	&sensor_dev_attr_fan3_alarm.dev_attr.attr,
+	NULL
+}, {
 	&sensor_dev_attr_fan4_input16.dev_attr.attr,
 	&sensor_dev_attr_fan4_min16.dev_attr.attr,
+	&sensor_dev_attr_fan4_alarm.dev_attr.attr,
+	NULL
+}, {
 	&sensor_dev_attr_fan5_input16.dev_attr.attr,
 	&sensor_dev_attr_fan5_min16.dev_attr.attr,
+	&sensor_dev_attr_fan5_alarm.dev_attr.attr,
+	NULL
+} };
 
+static const struct attribute_group it87_group_fan16[5] = {
+	{ .attrs = it87_attributes_fan16[0] },
+	{ .attrs = it87_attributes_fan16[1] },
+	{ .attrs = it87_attributes_fan16[2] },
+	{ .attrs = it87_attributes_fan16[3] },
+	{ .attrs = it87_attributes_fan16[4] },
+};
+
+static struct attribute *it87_attributes_fan[3][4+1] = { {
 	&sensor_dev_attr_fan1_input.dev_attr.attr,
 	&sensor_dev_attr_fan1_min.dev_attr.attr,
 	&sensor_dev_attr_fan1_div.dev_attr.attr,
+	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
+	NULL
+}, {
 	&sensor_dev_attr_fan2_input.dev_attr.attr,
 	&sensor_dev_attr_fan2_min.dev_attr.attr,
 	&sensor_dev_attr_fan2_div.dev_attr.attr,
+	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
+	NULL
+}, {
 	&sensor_dev_attr_fan3_input.dev_attr.attr,
 	&sensor_dev_attr_fan3_min.dev_attr.attr,
 	&sensor_dev_attr_fan3_div.dev_attr.attr,
-
-	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
-	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
 	&sensor_dev_attr_fan3_alarm.dev_attr.attr,
-	&sensor_dev_attr_fan4_alarm.dev_attr.attr,
-	&sensor_dev_attr_fan5_alarm.dev_attr.attr,
+	NULL
+} };
+
+static const struct attribute_group it87_group_fan[3] = {
+	{ .attrs = it87_attributes_fan[0] },
+	{ .attrs = it87_attributes_fan[1] },
+	{ .attrs = it87_attributes_fan[2] },
+};
+
+static const struct attribute_group *
+it87_get_fan_group(const struct it87_data *data)
+{
+	return has_16bit_fans(data) ? it87_group_fan16 : it87_group_fan;
+}
 
+static struct attribute *it87_attributes_pwm[3][4+1] = { {
 	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
-	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
-	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
 	&sensor_dev_attr_pwm1.dev_attr.attr,
-	&sensor_dev_attr_pwm2.dev_attr.attr,
-	&sensor_dev_attr_pwm3.dev_attr.attr,
 	&dev_attr_pwm1_freq.attr,
+	&sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
+	NULL
+}, {
+	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
+	&sensor_dev_attr_pwm2.dev_attr.attr,
 	&dev_attr_pwm2_freq.attr,
+	&sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
+	NULL
+}, {
+	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
+	&sensor_dev_attr_pwm3.dev_attr.attr,
 	&dev_attr_pwm3_freq.attr,
+	&sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
+	NULL
+} };
 
+static const struct attribute_group it87_group_pwm[3] = {
+	{ .attrs = it87_attributes_pwm[0] },
+	{ .attrs = it87_attributes_pwm[1] },
+	{ .attrs = it87_attributes_pwm[2] },
+};
+
+static struct attribute *it87_attributes_autopwm[3][9+1] = { {
+	&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point1_temp_hyst.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr,
+	NULL
+}, {
+	&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point3_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point4_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point1_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point1_temp_hyst.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point4_temp.dev_attr.attr,
+	NULL
+}, {
+	&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm3_auto_point3_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm3_auto_point4_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm3_auto_point1_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm3_auto_point1_temp_hyst.dev_attr.attr,
+	&sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm3_auto_point3_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm3_auto_point4_temp.dev_attr.attr,
+	NULL
+} };
+
+static const struct attribute_group it87_group_autopwm[3] = {
+	{ .attrs = it87_attributes_autopwm[0] },
+	{ .attrs = it87_attributes_autopwm[1] },
+	{ .attrs = it87_attributes_autopwm[2] },
+};
+
+static struct attribute *it87_attributes_fan_beep[] = {
+	&sensor_dev_attr_fan1_beep.dev_attr.attr,
+	&sensor_dev_attr_fan2_beep.dev_attr.attr,
+	&sensor_dev_attr_fan3_beep.dev_attr.attr,
+	&sensor_dev_attr_fan4_beep.dev_attr.attr,
+	&sensor_dev_attr_fan5_beep.dev_attr.attr,
+};
+
+static struct attribute *it87_attributes_vid[] = {
 	&dev_attr_vrm.attr,
 	&dev_attr_cpu0_vid.attr,
 	NULL
 };
 
-static const struct attribute_group it87_group_opt = {
-	.attrs = it87_attributes_opt,
+static const struct attribute_group it87_group_vid = {
+	.attrs = it87_attributes_vid,
 };
 
 /* SuperIO detection - will change isa_address if a chip is found */
@@ -1035,6 +1484,10 @@ static int __init it87_find(unsigned sho
 	if (sio_data->type == it87) {
 		/* The IT8705F doesn't have VID pins at all */
 		sio_data->skip_vid = 1;
+
+		/* The IT8705F has a different LD number for GPIO */
+		superio_select(5);
+		sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
 	} else {
 		int reg;
 
@@ -1068,7 +1521,11 @@ static int __init it87_find(unsigned sho
 			pr_info("it87: in3 is VCC (+5V)\n");
 		if (reg & (1 << 1))
 			pr_info("it87: in7 is VCCH (+5V Stand-By)\n");
+
+		sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
 	}
+	if (sio_data->beep_pin)
+		pr_info("it87: Beeping is supported\n");
 
 	/* Disable specific features based on DMI strings */
 	board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
@@ -1093,14 +1550,46 @@ exit:
 	return err;
 }
 
+static void it87_remove_files(struct device *dev)
+{
+	struct it87_data *data = platform_get_drvdata(pdev);
+	struct it87_sio_data *sio_data = dev->platform_data;
+	const struct attribute_group *fan_group = it87_get_fan_group(data);
+	int i;
+
+	sysfs_remove_group(&dev->kobj, &it87_group);
+	if (sio_data->beep_pin)
+		sysfs_remove_group(&dev->kobj, &it87_group_beep);
+	for (i = 0; i < 5; i++) {
+		if (!(data->has_fan & (1 << i)))
+			continue;
+		sysfs_remove_group(&dev->kobj, &fan_group[i]);
+		if (sio_data->beep_pin)
+			sysfs_remove_file(&dev->kobj,
+					  it87_attributes_fan_beep[i]);
+	}
+	for (i = 0; i < 3; i++) {
+		if (sio_data->skip_pwm & (1 << 0))
+			continue;
+		sysfs_remove_group(&dev->kobj, &it87_group_pwm[i]);
+		if (has_old_autopwm(data))
+			sysfs_remove_group(&dev->kobj,
+					   &it87_group_autopwm[i]);
+	}
+	if (!sio_data->skip_vid)
+		sysfs_remove_group(&dev->kobj, &it87_group_vid);
+}
+
 static int __devinit it87_probe(struct platform_device *pdev)
 {
 	struct it87_data *data;
 	struct resource *res;
 	struct device *dev = &pdev->dev;
 	struct it87_sio_data *sio_data = dev->platform_data;
-	int err = 0;
+	const struct attribute_group *fan_group;
+	int err = 0, i;
 	int enable_pwm_interface;
+	int fan_beep_need_rw;
 	static const char *names[] = {
 		"it87",
 		"it8712",
@@ -1118,7 +1607,8 @@ static int __devinit it87_probe(struct p
 		goto ERROR0;
 	}
 
-	if (!(data = kzalloc(sizeof(struct it87_data), GFP_KERNEL))) {
+	data = kzalloc(sizeof(struct it87_data), GFP_KERNEL);
+	if (!data) {
 		err = -ENOMEM;
 		goto ERROR1;
 	}
@@ -1146,120 +1636,60 @@ static int __devinit it87_probe(struct p
 	it87_init_device(pdev);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&dev->kobj, &it87_group)))
+	err = sysfs_create_group(&dev->kobj, &it87_group);
+	if (err)
 		goto ERROR2;
 
+	if (sio_data->beep_pin) {
+		err = sysfs_create_group(&dev->kobj, &it87_group_beep);
+		if (err)
+			goto ERROR4;
+	}
+
 	/* Do not create fan files for disabled fans */
-	if (has_16bit_fans(data)) {
-		/* 16-bit tachometers */
-		if (data->has_fan & (1 << 0)) {
-			if ((err = device_create_file(dev,
-			     &sensor_dev_attr_fan1_input16.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan1_min16.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan1_alarm.dev_attr)))
-				goto ERROR4;
-		}
-		if (data->has_fan & (1 << 1)) {
-			if ((err = device_create_file(dev,
-			     &sensor_dev_attr_fan2_input16.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan2_min16.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan2_alarm.dev_attr)))
-				goto ERROR4;
-		}
-		if (data->has_fan & (1 << 2)) {
-			if ((err = device_create_file(dev,
-			     &sensor_dev_attr_fan3_input16.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan3_min16.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan3_alarm.dev_attr)))
-				goto ERROR4;
-		}
-		if (data->has_fan & (1 << 3)) {
-			if ((err = device_create_file(dev,
-			     &sensor_dev_attr_fan4_input16.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan4_min16.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan4_alarm.dev_attr)))
-				goto ERROR4;
-		}
-		if (data->has_fan & (1 << 4)) {
-			if ((err = device_create_file(dev,
-			     &sensor_dev_attr_fan5_input16.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan5_min16.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan5_alarm.dev_attr)))
-				goto ERROR4;
-		}
-	} else {
-		/* 8-bit tachometers with clock divider */
-		if (data->has_fan & (1 << 0)) {
-			if ((err = device_create_file(dev,
-			     &sensor_dev_attr_fan1_input.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan1_min.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan1_div.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan1_alarm.dev_attr)))
-				goto ERROR4;
-		}
-		if (data->has_fan & (1 << 1)) {
-			if ((err = device_create_file(dev,
-			     &sensor_dev_attr_fan2_input.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan2_min.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan2_div.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan2_alarm.dev_attr)))
-				goto ERROR4;
-		}
-		if (data->has_fan & (1 << 2)) {
-			if ((err = device_create_file(dev,
-			     &sensor_dev_attr_fan3_input.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan3_min.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan3_div.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_fan3_alarm.dev_attr)))
+	fan_group = it87_get_fan_group(data);
+	fan_beep_need_rw = 1;
+	for (i = 0; i < 5; i++) {
+		if (!(data->has_fan & (1 << i)))
+			continue;
+		err = sysfs_create_group(&dev->kobj, &fan_group[i]);
+		if (err)
+			goto ERROR4;
+
+		if (sio_data->beep_pin) {
+			err = sysfs_create_file(&dev->kobj,
+						it87_attributes_fan_beep[i]);
+			if (err)
 				goto ERROR4;
+			if (!fan_beep_need_rw)
+				continue;
+
+			/* As we have a single beep enable bit for all fans,
+			 * only the first enabled fan has a writable attribute
+			 * for it. */
+			if (sysfs_chmod_file(&dev->kobj,
+					     it87_attributes_fan_beep[i],
+					     S_IRUGO | S_IWUSR))
+				dev_dbg(dev, "chmod +w fan%d_beep failed\n",
+					i + 1);
+			fan_beep_need_rw = 0;
 		}
 	}
 
 	if (enable_pwm_interface) {
-		if (!(sio_data->skip_pwm & (1 << 0))) {
-			if ((err = device_create_file(dev,
-			     &sensor_dev_attr_pwm1_enable.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_pwm1.dev_attr))
-			 || (err = device_create_file(dev,
-			     &dev_attr_pwm1_freq)))
-				goto ERROR4;
-		}
-		if (!(sio_data->skip_pwm & (1 << 1))) {
-			if ((err = device_create_file(dev,
-			     &sensor_dev_attr_pwm2_enable.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_pwm2.dev_attr))
-			 || (err = device_create_file(dev,
-			     &dev_attr_pwm2_freq)))
+		for (i = 0; i < 3; i++) {
+			if (sio_data->skip_pwm & (1 << i))
+				continue;
+			err = sysfs_create_group(&dev->kobj,
+						 &it87_group_pwm[i]);
+			if (err)
 				goto ERROR4;
-		}
-		if (!(sio_data->skip_pwm & (1 << 2))) {
-			if ((err = device_create_file(dev,
-			     &sensor_dev_attr_pwm3_enable.dev_attr))
-			 || (err = device_create_file(dev,
-			     &sensor_dev_attr_pwm3.dev_attr))
-			 || (err = device_create_file(dev,
-			     &dev_attr_pwm3_freq)))
+
+			if (!has_old_autopwm(data))
+				continue;
+			err = sysfs_create_group(&dev->kobj,
+						 &it87_group_autopwm[i]);
+			if (err)
 				goto ERROR4;
 		}
 	}
@@ -1268,10 +1698,8 @@ static int __devinit it87_probe(struct p
 		data->vrm = vid_which_vrm();
 		/* VID reading from Super-I/O config space if available */
 		data->vid = sio_data->vid_value;
-		if ((err = device_create_file(dev,
-		     &dev_attr_vrm))
-		 || (err = device_create_file(dev,
-		     &dev_attr_cpu0_vid)))
+		err = sysfs_create_group(&dev->kobj, &it87_group_vid);
+		if (err)
 			goto ERROR4;
 	}
 
@@ -1284,8 +1712,7 @@ static int __devinit it87_probe(struct p
 	return 0;
 
 ERROR4:
-	sysfs_remove_group(&dev->kobj, &it87_group);
-	sysfs_remove_group(&dev->kobj, &it87_group_opt);
+	it87_remove_files(dev);
 ERROR2:
 	platform_set_drvdata(pdev, NULL);
 	kfree(data);
@@ -1300,8 +1727,7 @@ static int __devexit it87_remove(struct
 	struct it87_data *data = platform_get_drvdata(pdev);
 
 	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&pdev->dev.kobj, &it87_group);
-	sysfs_remove_group(&pdev->dev.kobj, &it87_group_opt);
+	it87_remove_files(&pdev->dev);
 
 	release_region(data->addr, IT87_EC_EXTENT);
 	platform_set_drvdata(pdev, NULL);
@@ -1387,15 +1813,18 @@ static void __devinit it87_init_device(s
 	int tmp, i;
 	u8 mask;
 
-	/* initialize to sane defaults:
-	 * - if the chip is in manual pwm mode, this will be overwritten with
-	 *   the actual settings on the chip (so in this case, initialization
-	 *   is not needed)
-	 * - if in automatic or on/off mode, we could switch to manual mode,
-	 *   read the registers and set manual_pwm_ctl accordingly, but currently
-	 *   this is not implemented, so we initialize to something sane */
+	/* For each PWM channel:
+	 * - If it is in automatic mode, setting to manual mode should set
+	 *   the fan to full speed by default.
+	 * - If it is in manual mode, we need a mapping to temperature
+	 *   channels to use when later setting to automatic mode later.
+	 *   Use a 1:1 mapping by default (we are clueless.)
+	 * In both cases, the value can (and should) be changed by the user
+	 * prior to switching to a different mode. */
 	for (i = 0; i < 3; i++) {
-		data->manual_pwm_ctl[i] = 0xff;
+		data->pwm_temp_map[i] = i;
+		data->pwm_duty[i] = 0x7f;	/* Full speed */
+		data->auto_pwm[i][3] = 0x7f;	/* Full speed, hard-coded */
 	}
 
 	/* Some chips seem to have default value 0xff for all limit
@@ -1414,14 +1843,10 @@ static void __devinit it87_init_device(s
 			it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127);
 	}
 
-	/* Check if temperature channels are reset manually or by some reason */
-	tmp = it87_read_value(data, IT87_REG_TEMP_ENABLE);
-	if ((tmp & 0x3f) == 0) {
-		/* Temp1,Temp3=thermistor; Temp2=thermal diode */
-		tmp = (tmp & 0xc0) | 0x2a;
-		it87_write_value(data, IT87_REG_TEMP_ENABLE, tmp);
-	}
-	data->sensor = tmp;
+	/* Temperature channels are not forcibly enabled, as they can be
+	 * set to two different sensor types and we can't guess which one
+	 * is correct for a given system. These channels can be enabled at
+	 * run-time through the temp{1-3}_type sysfs accessors if needed. */
 
 	/* Check if voltage monitors are reset manually or by some reason */
 	tmp = it87_read_value(data, IT87_REG_VIN_ENABLE);
@@ -1436,7 +1861,8 @@ static void __devinit it87_init_device(s
 	if ((data->fan_main_ctrl & mask) == 0) {
 		/* Enable all fan tachometers */
 		data->fan_main_ctrl |= mask;
-		it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
+		it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
+				 data->fan_main_ctrl);
 	}
 	data->has_fan = (data->fan_main_ctrl >> 4) & 0x07;
 
@@ -1461,30 +1887,32 @@ static void __devinit it87_init_device(s
 	/* Fan input pins may be used for alternative functions */
 	data->has_fan &= ~sio_data->skip_fan;
 
-	/* Set current fan mode registers and the default settings for the
-	 * other mode registers */
-	for (i = 0; i < 3; i++) {
-		if (data->fan_main_ctrl & (1 << i)) {
-			/* pwm mode */
-			tmp = it87_read_value(data, IT87_REG_PWM(i));
-			if (tmp & 0x80) {
-				/* automatic pwm - not yet implemented, but
-				 * leave the settings made by the BIOS alone
-				 * until a change is requested via the sysfs
-				 * interface */
-			} else {
-				/* manual pwm */
-				data->manual_pwm_ctl[i] = PWM_FROM_REG(tmp);
-			}
-		}
- 	}
-
 	/* Start monitoring */
 	it87_write_value(data, IT87_REG_CONFIG,
 			 (it87_read_value(data, IT87_REG_CONFIG) & 0x36)
 			 | (update_vbat ? 0x41 : 0x01));
 }
 
+static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
+{
+	data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr));
+	if (data->pwm_ctrl[nr] & 0x80)	/* Automatic mode */
+		data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
+	else				/* Manual mode */
+		data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
+
+	if (has_old_autopwm(data)) {
+		int i;
+
+		for (i = 0; i < 5 ; i++)
+			data->auto_temp[nr][i] = it87_read_value(data,
+						IT87_REG_AUTO_TEMP(nr, i));
+		for (i = 0; i < 3 ; i++)
+			data->auto_pwm[nr][i] = it87_read_value(data,
+						IT87_REG_AUTO_PWM(nr, i));
+	}
+}
+
 static struct it87_data *it87_update_device(struct device *dev)
 {
 	struct it87_data *data = dev_get_drvdata(dev);
@@ -1494,24 +1922,22 @@ static struct it87_data *it87_update_dev
 
 	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
 	    || !data->valid) {
-
 		if (update_vbat) {
 			/* Cleared after each update, so reenable.  Value
-		 	  returned by this read will be previous value */	
+			   returned by this read will be previous value */
 			it87_write_value(data, IT87_REG_CONFIG,
-			   it87_read_value(data, IT87_REG_CONFIG) | 0x40);
+				it87_read_value(data, IT87_REG_CONFIG) | 0x40);
 		}
 		for (i = 0; i <= 7; i++) {
 			data->in[i] =
-			    it87_read_value(data, IT87_REG_VIN(i));
+				it87_read_value(data, IT87_REG_VIN(i));
 			data->in_min[i] =
-			    it87_read_value(data, IT87_REG_VIN_MIN(i));
+				it87_read_value(data, IT87_REG_VIN_MIN(i));
 			data->in_max[i] =
-			    it87_read_value(data, IT87_REG_VIN_MAX(i));
+				it87_read_value(data, IT87_REG_VIN_MAX(i));
 		}
 		/* in8 (battery) has no limit registers */
-		data->in[8] =
-		    it87_read_value(data, IT87_REG_VIN(8));
+		data->in[8] = it87_read_value(data, IT87_REG_VIN(8));
 
 		for (i = 0; i < 5; i++) {
 			/* Skip disabled fans */
@@ -1519,7 +1945,7 @@ static struct it87_data *it87_update_dev
 				continue;
 
 			data->fan_min[i] =
-			    it87_read_value(data, IT87_REG_FAN_MIN[i]);
+				it87_read_value(data, IT87_REG_FAN_MIN[i]);
 			data->fan[i] = it87_read_value(data,
 				       IT87_REG_FAN[i]);
 			/* Add high byte if in 16-bit mode */
@@ -1532,11 +1958,11 @@ static struct it87_data *it87_update_dev
 		}
 		for (i = 0; i < 3; i++) {
 			data->temp[i] =
-			    it87_read_value(data, IT87_REG_TEMP(i));
+				it87_read_value(data, IT87_REG_TEMP(i));
 			data->temp_high[i] =
-			    it87_read_value(data, IT87_REG_TEMP_HIGH(i));
+				it87_read_value(data, IT87_REG_TEMP_HIGH(i));
 			data->temp_low[i] =
-			    it87_read_value(data, IT87_REG_TEMP_LOW(i));
+				it87_read_value(data, IT87_REG_TEMP_LOW(i));
 		}
 
 		/* Newer chips don't have clock dividers */
@@ -1551,9 +1977,13 @@ static struct it87_data *it87_update_dev
 			it87_read_value(data, IT87_REG_ALARM1) |
 			(it87_read_value(data, IT87_REG_ALARM2) << 8) |
 			(it87_read_value(data, IT87_REG_ALARM3) << 16);
+		data->beeps = it87_read_value(data, IT87_REG_BEEP_ENABLE);
+
 		data->fan_main_ctrl = it87_read_value(data,
 				IT87_REG_FAN_MAIN_CTRL);
 		data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL);
+		for (i = 0; i < 3; i++)
+			it87_update_pwm_ctrl(data, i);
 
 		data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE);
 		/* The 8705 does not have VID capability.
@@ -1628,7 +2058,7 @@ exit:
 static int __init sm_it87_init(void)
 {
 	int err;
-	unsigned short isa_address=0;
+	unsigned short isa_address = 0;
 	struct it87_sio_data sio_data;
 
 	memset(&sio_data, 0, sizeof(struct it87_sio_data));
@@ -1640,7 +2070,7 @@ static int __init sm_it87_init(void)
 		return err;
 
 	err = it87_device_add(isa_address, &sio_data);
-	if (err){
+	if (err) {
 		platform_driver_unregister(&it87_driver);
 		return err;
 	}
@@ -1661,7 +2091,8 @@ MODULE_DESCRIPTION("IT8705F/8712F/8716F/
 module_param(update_vbat, bool, 0);
 MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
 module_param(fix_pwm_polarity, bool, 0);
-MODULE_PARM_DESC(fix_pwm_polarity, "Force PWM polarity to active high (DANGEROUS)");
+MODULE_PARM_DESC(fix_pwm_polarity,
+		 "Force PWM polarity to active high (DANGEROUS)");
 MODULE_LICENSE("GPL");
 
 module_init(sm_it87_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/Kconfig linux-libre-2.6.34-gnu1/drivers/hwmon/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/hwmon/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -170,6 +170,16 @@ config SENSORS_ADM9240
 	  This driver can also be built as a module.  If so, the module
 	  will be called adm9240.
 
+config SENSORS_ADT7411
+	tristate "Analog Devices ADT7411"
+	depends on I2C && EXPERIMENTAL
+	help
+	  If you say yes here you get support for the Analog Devices
+	  ADT7411 voltage and temperature monitoring chip.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called adt7411.
+
 config SENSORS_ADT7462
 	tristate "Analog Devices ADT7462"
 	depends on I2C && EXPERIMENTAL
@@ -190,20 +200,6 @@ config SENSORS_ADT7470
 	  This driver can also be built as a module. If so, the module
 	  will be called adt7470.
 
-config SENSORS_ADT7473
-	tristate "Analog Devices ADT7473 (DEPRECATED)"
-	depends on I2C && EXPERIMENTAL
-	select SENSORS_ADT7475
-	help
-	  If you say yes here you get support for the Analog Devices
-	  ADT7473 temperature monitoring chips.
-
-	  This driver is deprecated, you should use the adt7475 driver
-	  instead.
-
-	  This driver can also be built as a module. If so, the module
-	  will be called adt7473.
-
 config SENSORS_ADT7475
 	tristate "Analog Devices ADT7473, ADT7475, ADT7476 and ADT7490"
 	depends on I2C && EXPERIMENTAL
@@ -216,6 +212,19 @@ config SENSORS_ADT7475
 	  This driver can also be build as a module.  If so, the module
 	  will be called adt7475.
 
+config SENSORS_ASC7621
+	tristate "Andigilog aSC7621"
+	depends on HWMON && I2C
+	help
+	  If you say yes here you get support for the aSC7621
+	  family of SMBus sensors chip found on most Intel X38, X48, X58,
+	  945, 965 and 975 desktop boards.  Currently supported chips:
+	  aSC7621
+	  aSC7621a
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called asc7621.
+
 config SENSORS_K8TEMP
 	tristate "AMD Athlon64/FX or Opteron temperature sensor"
 	depends on X86 && PCI && EXPERIMENTAL
@@ -563,9 +572,10 @@ config SENSORS_LM90
 	depends on I2C
 	help
 	  If you say yes here you get support for National Semiconductor LM90,
-	  LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, and Maxim
+	  LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, Maxim
 	  MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659,
-	  MAX6680, MAX6681 and MAX6692 sensor chips.
+	  MAX6680, MAX6681 and MAX6692, and Winbond/Nuvoton W83L771AWG/ASG
+	  sensor chips.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called lm90.
@@ -909,7 +919,8 @@ config SENSORS_W83793
 	select HWMON_VID
 	help
 	  If you say yes here you get support for the Winbond W83793
-	  hardware monitoring chip.
+	  hardware monitoring chip, including support for the integrated
+	  watchdog.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called w83793.
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/lm70.c linux-libre-2.6.34-gnu1/drivers/hwmon/lm70.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/lm70.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/lm70.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/mutex.h>
 #include <linux/mod_devicetable.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 
 
 #define DRVNAME		"lm70"
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/lm73.c linux-libre-2.6.34-gnu1/drivers/hwmon/lm73.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/lm73.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/lm73.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/lm90.c linux-libre-2.6.34-gnu1/drivers/hwmon/lm90.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/lm90.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/lm90.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * lm90.c - Part of lm_sensors, Linux kernel modules for hardware
  *          monitoring
- * Copyright (C) 2003-2009  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2003-2010  Jean Delvare <khali@linux-fr.org>
  *
  * Based on the lm83 driver. The LM90 is a sensor chip made by National
  * Semiconductor. It reports up to two temperatures (its own plus up to
@@ -93,7 +93,8 @@
 static const unsigned short normal_i2c[] = {
 	0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
 
-enum chips { lm90, adm1032, lm99, lm86, max6657, adt7461, max6680, max6646 };
+enum chips { lm90, adm1032, lm99, lm86, max6657, adt7461, max6680, max6646,
+	w83l771 };
 
 /*
  * The LM90 registers
@@ -151,6 +152,7 @@ static int lm90_detect(struct i2c_client
 static int lm90_probe(struct i2c_client *client,
 		      const struct i2c_device_id *id);
 static void lm90_init_client(struct i2c_client *client);
+static void lm90_alert(struct i2c_client *client, unsigned int flag);
 static int lm90_remove(struct i2c_client *client);
 static struct lm90_data *lm90_update_device(struct device *dev);
 
@@ -173,6 +175,7 @@ static const struct i2c_device_id lm90_i
 	{ "max6659", max6657 },
 	{ "max6680", max6680 },
 	{ "max6681", max6680 },
+	{ "w83l771", w83l771 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, lm90_id);
@@ -184,6 +187,7 @@ static struct i2c_driver lm90_driver = {
 	},
 	.probe		= lm90_probe,
 	.remove		= lm90_remove,
+	.alert		= lm90_alert,
 	.id_table	= lm90_id,
 	.detect		= lm90_detect,
 	.address_list	= normal_i2c,
@@ -201,6 +205,9 @@ struct lm90_data {
 	int kind;
 	int flags;
 
+	u8 config_orig;		/* Original configuration register value */
+	u8 alert_alarms;	/* Which alarm bits trigger ALERT# */
+
 	/* registers values */
 	s8 temp8[4];	/* 0: local low limit
 			   1: local high limit
@@ -758,6 +765,14 @@ static int lm90_detect(struct i2c_client
 		 && reg_convrate <= 0x07) {
 			name = "max6646";
 		}
+	} else
+	if (address == 0x4C
+	 && man_id == 0x5C) { /* Winbond/Nuvoton */
+		if ((chip_id & 0xFE) == 0x10 /* W83L771AWG/ASG */
+		 && (reg_config1 & 0x2A) == 0x00
+		 && reg_convrate <= 0x08) {
+			name = "w83l771";
+		}
 	}
 
 	if (!name) { /* identification failed */
@@ -794,6 +809,19 @@ static int lm90_probe(struct i2c_client
 			new_client->flags &= ~I2C_CLIENT_PEC;
 	}
 
+	/* Different devices have different alarm bits triggering the
+	 * ALERT# output */
+	switch (data->kind) {
+	case lm90:
+	case lm99:
+	case lm86:
+		data->alert_alarms = 0x7b;
+		break;
+	default:
+		data->alert_alarms = 0x7c;
+		break;
+	}
+
 	/* Initialize the LM90 chip */
 	lm90_init_client(new_client);
 
@@ -830,7 +858,7 @@ exit:
 
 static void lm90_init_client(struct i2c_client *client)
 {
-	u8 config, config_orig;
+	u8 config;
 	struct lm90_data *data = i2c_get_clientdata(client);
 
 	/*
@@ -842,7 +870,7 @@ static void lm90_init_client(struct i2c_
 		dev_warn(&client->dev, "Initialization failed!\n");
 		return;
 	}
-	config_orig = config;
+	data->config_orig = config;
 
 	/* Check Temperature Range Select */
 	if (data->kind == adt7461) {
@@ -860,7 +888,7 @@ static void lm90_init_client(struct i2c_
 	}
 
 	config &= 0xBF;	/* run */
-	if (config != config_orig) /* Only write if changed */
+	if (config != data->config_orig) /* Only write if changed */
 		i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config);
 }
 
@@ -875,10 +903,46 @@ static int lm90_remove(struct i2c_client
 		device_remove_file(&client->dev,
 				   &sensor_dev_attr_temp2_offset.dev_attr);
 
+	/* Restore initial configuration */
+	i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
+				  data->config_orig);
+
 	kfree(data);
 	return 0;
 }
 
+static void lm90_alert(struct i2c_client *client, unsigned int flag)
+{
+	struct lm90_data *data = i2c_get_clientdata(client);
+	u8 config, alarms;
+
+	lm90_read_reg(client, LM90_REG_R_STATUS, &alarms);
+	if ((alarms & 0x7f) == 0) {
+		dev_info(&client->dev, "Everything OK\n");
+	} else {
+		if (alarms & 0x61)
+			dev_warn(&client->dev,
+				 "temp%d out of range, please check!\n", 1);
+		if (alarms & 0x1a)
+			dev_warn(&client->dev,
+				 "temp%d out of range, please check!\n", 2);
+		if (alarms & 0x04)
+			dev_warn(&client->dev,
+				 "temp%d diode open, please check!\n", 2);
+
+		/* Disable ALERT# output, because these chips don't implement
+		  SMBus alert correctly; they should only hold the alert line
+		  low briefly. */
+		if ((data->kind == adm1032 || data->kind == adt7461)
+		 && (alarms & data->alert_alarms)) {
+			dev_dbg(&client->dev, "Disabling ALERT#\n");
+			lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
+			i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
+						  config | 0x80);
+		}
+	}
+}
+
 static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value)
 {
 	int err;
@@ -966,6 +1030,21 @@ static struct lm90_data *lm90_update_dev
 		}
 		lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms);
 
+		/* Re-enable ALERT# output if it was originally enabled and
+		 * relevant alarms are all clear */
+		if ((data->config_orig & 0x80) == 0
+		 && (data->alarms & data->alert_alarms) == 0) {
+			u8 config;
+
+			lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
+			if (config & 0x80) {
+				dev_dbg(&client->dev, "Re-enabling ALERT#\n");
+				i2c_smbus_write_byte_data(client,
+							  LM90_REG_W_CONFIG1,
+							  config & ~0x80);
+			}
+		}
+
 		data->last_updated = jiffies;
 		data->valid = 1;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/Makefile linux-libre-2.6.34-gnu1/drivers/hwmon/Makefile
--- linux-libre-2.6.33-gnu1/drivers/hwmon/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -29,12 +29,13 @@ obj-$(CONFIG_SENSORS_ADM1029)	+= adm1029
 obj-$(CONFIG_SENSORS_ADM1031)	+= adm1031.o
 obj-$(CONFIG_SENSORS_ADM9240)	+= adm9240.o
 obj-$(CONFIG_SENSORS_ADS7828)	+= ads7828.o
+obj-$(CONFIG_SENSORS_ADT7411)	+= adt7411.o
 obj-$(CONFIG_SENSORS_ADT7462)	+= adt7462.o
 obj-$(CONFIG_SENSORS_ADT7470)	+= adt7470.o
-obj-$(CONFIG_SENSORS_ADT7473)	+= adt7473.o
 obj-$(CONFIG_SENSORS_ADT7475)	+= adt7475.o
 obj-$(CONFIG_SENSORS_APPLESMC)	+= applesmc.o
 obj-$(CONFIG_SENSORS_AMS)	+= ams/
+obj-$(CONFIG_SENSORS_ASC7621)	+= asc7621.o
 obj-$(CONFIG_SENSORS_ATXP1)	+= atxp1.o
 obj-$(CONFIG_SENSORS_CORETEMP)	+= coretemp.o
 obj-$(CONFIG_SENSORS_DME1737)	+= dme1737.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/max1111.c linux-libre-2.6.34-gnu1/drivers/hwmon/max1111.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/max1111.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/max1111.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 
 #define MAX1111_TX_BUF_SIZE	1
 #define MAX1111_RX_BUF_SIZE	2
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/mc13783-adc.c linux-libre-2.6.34-gnu1/drivers/hwmon/mc13783-adc.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/mc13783-adc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/mc13783-adc.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/hwmon.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/err.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/sht15.c linux-libre-2.6.34-gnu1/drivers/hwmon/sht15.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/sht15.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/sht15.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/err.h>
 #include <linux/sht15.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include <asm/atomic.h>
 
 #define SHT15_MEASURE_TEMP	3
@@ -302,13 +303,13 @@ error_ret:
  **/
 static inline int sht15_calc_temp(struct sht15_data *data)
 {
-	int d1 = 0;
+	int d1 = temppoints[0].d1;
 	int i;
 
-	for (i = 1; i < ARRAY_SIZE(temppoints); i++)
+	for (i = ARRAY_SIZE(temppoints) - 1; i > 0; i--)
 		/* Find pointer to interpolate */
 		if (data->supply_uV > temppoints[i - 1].vdd) {
-			d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd)
+			d1 = (data->supply_uV - temppoints[i - 1].vdd)
 				* (temppoints[i].d1 - temppoints[i - 1].d1)
 				/ (temppoints[i].vdd - temppoints[i - 1].vdd)
 				+ temppoints[i - 1].d1;
@@ -541,7 +542,12 @@ static int __devinit sht15_probe(struct
 /* 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);
+		int voltage;
+
+		voltage = regulator_get_voltage(data->reg);
+		if (voltage)
+			data->supply_uV = voltage;
+
 		regulator_enable(data->reg);
 		/* setup a notifier block to update this if another device
 		 *  causes the voltage to change */
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/tmp401.c linux-libre-2.6.34-gnu1/drivers/hwmon/tmp401.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/tmp401.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/tmp401.c	2010-05-16 17:17:36.000000000 -0400
@@ -134,7 +134,7 @@ struct tmp401_data {
 	struct mutex update_lock;
 	char valid; /* zero until following fields are valid */
 	unsigned long last_updated; /* in jiffies */
-	int kind;
+	enum chips kind;
 
 	/* register values */
 	u8 status;
@@ -524,7 +524,7 @@ static int tmp401_detect(struct i2c_clie
 	if (reg > 15)
 		return -ENODEV;
 
-	strlcpy(info->type, tmp401_id[kind - 1].name, I2C_NAME_SIZE);
+	strlcpy(info->type, tmp401_id[kind].name, I2C_NAME_SIZE);
 
 	return 0;
 }
@@ -572,8 +572,7 @@ static int tmp401_probe(struct i2c_clien
 		goto exit_remove;
 	}
 
-	dev_info(&client->dev, "Detected TI %s chip\n",
-		 names[data->kind - 1]);
+	dev_info(&client->dev, "Detected TI %s chip\n", names[data->kind]);
 
 	return 0;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/tmp421.c linux-libre-2.6.34-gnu1/drivers/hwmon/tmp421.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/tmp421.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/tmp421.c	2010-05-16 17:17:36.000000000 -0400
@@ -61,9 +61,9 @@ static const u8 TMP421_TEMP_LSB[4]		= {
 #define TMP423_DEVICE_ID			0x23
 
 static const struct i2c_device_id tmp421_id[] = {
-	{ "tmp421", tmp421 },
-	{ "tmp422", tmp422 },
-	{ "tmp423", tmp423 },
+	{ "tmp421", 2 },
+	{ "tmp422", 3 },
+	{ "tmp423", 4 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, tmp421_id);
@@ -73,21 +73,23 @@ struct tmp421_data {
 	struct mutex update_lock;
 	char valid;
 	unsigned long last_updated;
-	int kind;
+	int channels;
 	u8 config;
 	s16 temp[4];
 };
 
 static int temp_from_s16(s16 reg)
 {
-	int temp = reg;
+	/* Mask out status bits */
+	int temp = reg & ~0xf;
 
 	return (temp * 1000 + 128) / 256;
 }
 
 static int temp_from_u16(u16 reg)
 {
-	int temp = reg;
+	/* Mask out status bits */
+	int temp = reg & ~0xf;
 
 	/* Add offset for extended temperature range. */
 	temp -= 64 * 256;
@@ -107,7 +109,7 @@ static struct tmp421_data *tmp421_update
 		data->config = i2c_smbus_read_byte_data(client,
 			TMP421_CONFIG_REG_1);
 
-		for (i = 0; i <= data->kind; i++) {
+		for (i = 0; i < data->channels; i++) {
 			data->temp[i] = i2c_smbus_read_byte_data(client,
 				TMP421_TEMP_MSB[i]) << 8;
 			data->temp[i] |= i2c_smbus_read_byte_data(client,
@@ -166,7 +168,7 @@ static mode_t tmp421_is_visible(struct k
 	devattr = container_of(a, struct device_attribute, attr);
 	index = to_sensor_dev_attr(devattr)->index;
 
-	if (data->kind > index)
+	if (index < data->channels)
 		return a->mode;
 
 	return 0;
@@ -252,9 +254,9 @@ static int tmp421_detect(struct i2c_clie
 		return -ENODEV;
 	}
 
-	strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE);
+	strlcpy(info->type, tmp421_id[kind].name, I2C_NAME_SIZE);
 	dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n",
-		 names[kind - 1], client->addr);
+		 names[kind], client->addr);
 
 	return 0;
 }
@@ -271,7 +273,7 @@ static int tmp421_probe(struct i2c_clien
 
 	i2c_set_clientdata(client, data);
 	mutex_init(&data->update_lock);
-	data->kind = id->driver_data;
+	data->channels = id->driver_data;
 
 	err = tmp421_init_client(client);
 	if (err)
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/vt8231.c linux-libre-2.6.34-gnu1/drivers/hwmon/vt8231.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/vt8231.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/vt8231.c	2010-05-16 17:17:36.000000000 -0400
@@ -948,8 +948,7 @@ static int __devinit vt8231_pci_probe(st
 
 	address = val & ~(VT8231_EXTENT - 1);
 	if (address == 0) {
-		dev_err(&dev->dev, "base address not set -\
-				 upgrade BIOS or use force_addr=0xaddr\n");
+		dev_err(&dev->dev, "base address not set - upgrade BIOS or use force_addr=0xaddr\n");
 		return -ENODEV;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/w83793.c linux-libre-2.6.34-gnu1/drivers/hwmon/w83793.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/w83793.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/w83793.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,10 @@
     Copyright (C) 2006 Winbond Electronics Corp.
                   Yuan Mu
                   Rudolf Marek <r.marek@assembler.cz>
+    Copyright (C) 2009-2010 Sven Anders <anders@anduras.de>, ANDURAS AG.
+		  Watchdog driver part
+		  (Based partially on fschmd driver,
+		   Copyright 2007-2008 by Hans de Goede)
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -35,6 +39,16 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/fs.h>
+#include <linux/watchdog.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/kref.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
+/* Default values */
+#define WATCHDOG_TIMEOUT 2	/* 2 minute default timeout */
 
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
@@ -51,6 +65,18 @@ static int reset;
 module_param(reset, bool, 0);
 MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
 
+static int timeout = WATCHDOG_TIMEOUT;	/* default timeout in minutes */
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout,
+	"Watchdog timeout in minutes. 2<= timeout <=255 (default="
+				__MODULE_STRING(WATCHDOG_TIMEOUT) ")");
+
+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) ")");
+
 /*
    Address 0x00, 0x0d, 0x0e, 0x0f in all three banks are reserved
    as ID, Bank Select registers
@@ -72,6 +98,11 @@ MODULE_PARM_DESC(reset, "Set to 1 to res
 #define W83793_REG_VID_LATCHB		0x08
 #define W83793_REG_VID_CTRL		0x59
 
+#define W83793_REG_WDT_LOCK		0x01
+#define W83793_REG_WDT_ENABLE		0x02
+#define W83793_REG_WDT_STATUS		0x03
+#define W83793_REG_WDT_TIMEOUT		0x04
+
 static u16 W83793_REG_TEMP_MODE[2] = { 0x5e, 0x5f };
 
 #define TEMP_READ	0
@@ -223,8 +254,37 @@ struct w83793_data {
 	u8 tolerance[3];	/* Temp tolerance(Smart Fan I/II) */
 	u8 sf2_pwm[6][7];	/* Smart FanII: Fan duty cycle */
 	u8 sf2_temp[6][7];	/* Smart FanII: Temp level point */
+
+	/* watchdog */
+	struct i2c_client *client;
+	struct mutex watchdog_lock;
+	struct list_head list; /* member of the watchdog_data_list */
+	struct kref kref;
+	struct miscdevice watchdog_miscdev;
+	unsigned long watchdog_is_open;
+	char watchdog_expect_close;
+	char watchdog_name[10]; /* must be unique to avoid sysfs conflict */
+	unsigned int watchdog_caused_reboot;
+	int watchdog_timeout; /* watchdog timeout in minutes */
 };
 
+/* Somewhat ugly :( global data pointer list with all devices, so that
+   we can find our device data as when using misc_register. There is no
+   other method to get to one's device data from the open file-op and
+   for usage in the reboot notifier callback. */
+static LIST_HEAD(watchdog_data_list);
+
+/* Note this lock not only protect list access, but also data.kref access */
+static DEFINE_MUTEX(watchdog_data_mutex);
+
+/* Release our data struct when we're detached from the i2c client *and* all
+   references to our watchdog device are released */
+static void w83793_release_resources(struct kref *ref)
+{
+	struct w83793_data *data = container_of(ref, struct w83793_data, kref);
+	kfree(data);
+}
+
 static u8 w83793_read_value(struct i2c_client *client, u16 reg);
 static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value);
 static int w83793_probe(struct i2c_client *client,
@@ -1063,14 +1123,349 @@ static void w83793_init_client(struct i2
 	/* Start monitoring */
 	w83793_write_value(client, W83793_REG_CONFIG,
 			   w83793_read_value(client, W83793_REG_CONFIG) | 0x01);
+}
+
+/*
+ * Watchdog routines
+ */
+
+static int watchdog_set_timeout(struct w83793_data *data, int timeout)
+{
+	int ret, mtimeout;
+
+	mtimeout = DIV_ROUND_UP(timeout, 60);
+
+	if (mtimeout > 255)
+		return -EINVAL;
+
+	mutex_lock(&data->watchdog_lock);
+	if (!data->client) {
+		ret = -ENODEV;
+		goto leave;
+	}
+
+	data->watchdog_timeout = mtimeout;
+
+	/* Set Timeout value (in Minutes) */
+	w83793_write_value(data->client, W83793_REG_WDT_TIMEOUT,
+			   data->watchdog_timeout);
+
+	ret = mtimeout * 60;
+
+leave:
+	mutex_unlock(&data->watchdog_lock);
+	return ret;
+}
+
+static int watchdog_get_timeout(struct w83793_data *data)
+{
+	int timeout;
+
+	mutex_lock(&data->watchdog_lock);
+	timeout = data->watchdog_timeout * 60;
+	mutex_unlock(&data->watchdog_lock);
+
+	return timeout;
+}
+
+static int watchdog_trigger(struct w83793_data *data)
+{
+	int ret = 0;
+
+	mutex_lock(&data->watchdog_lock);
+	if (!data->client) {
+		ret = -ENODEV;
+		goto leave;
+	}
+
+	/* Set Timeout value (in Minutes) */
+	w83793_write_value(data->client, W83793_REG_WDT_TIMEOUT,
+			   data->watchdog_timeout);
+
+leave:
+	mutex_unlock(&data->watchdog_lock);
+	return ret;
+}
+
+static int watchdog_enable(struct w83793_data *data)
+{
+	int ret = 0;
+
+	mutex_lock(&data->watchdog_lock);
+	if (!data->client) {
+		ret = -ENODEV;
+		goto leave;
+	}
+
+	/* Set initial timeout */
+	w83793_write_value(data->client, W83793_REG_WDT_TIMEOUT,
+			   data->watchdog_timeout);
+
+	/* Enable Soft Watchdog */
+	w83793_write_value(data->client, W83793_REG_WDT_LOCK, 0x55);
+
+leave:
+	mutex_unlock(&data->watchdog_lock);
+	return ret;
+}
+
+static int watchdog_disable(struct w83793_data *data)
+{
+	int ret = 0;
+
+	mutex_lock(&data->watchdog_lock);
+	if (!data->client) {
+		ret = -ENODEV;
+		goto leave;
+	}
+
+	/* Disable Soft Watchdog */
+	w83793_write_value(data->client, W83793_REG_WDT_LOCK, 0xAA);
+
+leave:
+	mutex_unlock(&data->watchdog_lock);
+	return ret;
+}
+
+static int watchdog_open(struct inode *inode, struct file *filp)
+{
+	struct w83793_data *pos, *data = NULL;
+	int watchdog_is_open;
+
+	/* We get called from drivers/char/misc.c with misc_mtx hold, and we
+	   call misc_register() from  w83793_probe() with watchdog_data_mutex
+	   hold, as misc_register() takes the misc_mtx lock, this is a possible
+	   deadlock, so we use mutex_trylock here. */
+	if (!mutex_trylock(&watchdog_data_mutex))
+		return -ERESTARTSYS;
+	list_for_each_entry(pos, &watchdog_data_list, list) {
+		if (pos->watchdog_miscdev.minor == iminor(inode)) {
+			data = pos;
+			break;
+		}
+	}
+
+	/* Check, if device is already open */
+	watchdog_is_open = test_and_set_bit(0, &data->watchdog_is_open);
+
+	/* Increase data reference counter (if not already done).
+	   Note we can never not have found data, so we don't check for this */
+	if (!watchdog_is_open)
+		kref_get(&data->kref);
+
+	mutex_unlock(&watchdog_data_mutex);
+
+	/* Check, if device is already open and possibly issue error */
+	if (watchdog_is_open)
+		return -EBUSY;
+
+	/* Enable Soft Watchdog */
+	watchdog_enable(data);
+
+	/* Store pointer to data into filp's private data */
+	filp->private_data = data;
+
+	return nonseekable_open(inode, filp);
+}
+
+static int watchdog_close(struct inode *inode, struct file *filp)
+{
+	struct w83793_data *data = filp->private_data;
+
+	if (data->watchdog_expect_close) {
+		watchdog_disable(data);
+		data->watchdog_expect_close = 0;
+	} else {
+		watchdog_trigger(data);
+		dev_crit(&data->client->dev,
+			"unexpected close, not stopping watchdog!\n");
+	}
+
+	clear_bit(0, &data->watchdog_is_open);
+
+	/* Decrease data reference counter */
+	mutex_lock(&watchdog_data_mutex);
+	kref_put(&data->kref, w83793_release_resources);
+	mutex_unlock(&watchdog_data_mutex);
+
+	return 0;
+}
+
+static ssize_t watchdog_write(struct file *filp, const char __user *buf,
+	size_t count, loff_t *offset)
+{
+	ssize_t ret;
+	struct w83793_data *data = filp->private_data;
+
+	if (count) {
+		if (!nowayout) {
+			size_t i;
+
+			/* Clear it in case it was set with a previous write */
+			data->watchdog_expect_close = 0;
+
+			for (i = 0; i != count; i++) {
+				char c;
+				if (get_user(c, buf + i))
+					return -EFAULT;
+				if (c == 'V')
+					data->watchdog_expect_close = 1;
+			}
+		}
+		ret = watchdog_trigger(data);
+		if (ret < 0)
+			return ret;
+	}
+	return count;
+}
 
+static int watchdog_ioctl(struct inode *inode, struct file *filp,
+			  unsigned int cmd, unsigned long arg)
+{
+	static struct watchdog_info ident = {
+		.options = WDIOF_KEEPALIVEPING |
+			   WDIOF_SETTIMEOUT |
+			   WDIOF_CARDRESET,
+		.identity = "w83793 watchdog"
+	};
+
+	int val, ret = 0;
+	struct w83793_data *data = filp->private_data;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		if (!nowayout)
+			ident.options |= WDIOF_MAGICCLOSE;
+		if (copy_to_user((void __user *)arg, &ident, sizeof(ident)))
+			ret = -EFAULT;
+		break;
+
+	case WDIOC_GETSTATUS:
+		val = data->watchdog_caused_reboot ? WDIOF_CARDRESET : 0;
+		ret = put_user(val, (int __user *)arg);
+		break;
+
+	case WDIOC_GETBOOTSTATUS:
+		ret = put_user(0, (int __user *)arg);
+		break;
+
+	case WDIOC_KEEPALIVE:
+		ret = watchdog_trigger(data);
+		break;
+
+	case WDIOC_GETTIMEOUT:
+		val = watchdog_get_timeout(data);
+		ret = put_user(val, (int __user *)arg);
+		break;
+
+	case WDIOC_SETTIMEOUT:
+		if (get_user(val, (int __user *)arg)) {
+			ret = -EFAULT;
+			break;
+		}
+		ret = watchdog_set_timeout(data, val);
+		if (ret > 0)
+			ret = put_user(ret, (int __user *)arg);
+		break;
+
+	case WDIOC_SETOPTIONS:
+		if (get_user(val, (int __user *)arg)) {
+			ret = -EFAULT;
+			break;
+		}
+
+		if (val & WDIOS_DISABLECARD)
+			ret = watchdog_disable(data);
+		else if (val & WDIOS_ENABLECARD)
+			ret = watchdog_enable(data);
+		else
+			ret = -EINVAL;
+
+		break;
+	default:
+		ret = -ENOTTY;
+	}
+
+	return ret;
+}
+
+static const struct file_operations watchdog_fops = {
+	.owner = THIS_MODULE,
+	.llseek = no_llseek,
+	.open = watchdog_open,
+	.release = watchdog_close,
+	.write = watchdog_write,
+	.ioctl = watchdog_ioctl,
+};
+
+/*
+ *	Notifier for system down
+ */
+
+static int watchdog_notify_sys(struct notifier_block *this, unsigned long code,
+			       void *unused)
+{
+	struct w83793_data *data = NULL;
+
+	if (code == SYS_DOWN || code == SYS_HALT) {
+
+		/* Disable each registered watchdog */
+		mutex_lock(&watchdog_data_mutex);
+		list_for_each_entry(data, &watchdog_data_list, list) {
+			if (data->watchdog_miscdev.minor)
+				watchdog_disable(data);
+		}
+		mutex_unlock(&watchdog_data_mutex);
+	}
+
+	return NOTIFY_DONE;
 }
 
+/*
+ *	The WDT needs to learn about soft shutdowns in order to
+ *	turn the timebomb registers off.
+ */
+
+static struct notifier_block watchdog_notifier = {
+	.notifier_call = watchdog_notify_sys,
+};
+
+/*
+ * Init / remove routines
+ */
+
 static int w83793_remove(struct i2c_client *client)
 {
 	struct w83793_data *data = i2c_get_clientdata(client);
 	struct device *dev = &client->dev;
-	int i;
+	int i, tmp;
+
+	/* Unregister the watchdog (if registered) */
+	if (data->watchdog_miscdev.minor) {
+		misc_deregister(&data->watchdog_miscdev);
+
+		if (data->watchdog_is_open) {
+			dev_warn(&client->dev,
+				"i2c client detached with watchdog open! "
+				"Stopping watchdog.\n");
+			watchdog_disable(data);
+		}
+
+		mutex_lock(&watchdog_data_mutex);
+		list_del(&data->list);
+		mutex_unlock(&watchdog_data_mutex);
+
+		/* Tell the watchdog code the client is gone */
+		mutex_lock(&data->watchdog_lock);
+		data->client = NULL;
+		mutex_unlock(&data->watchdog_lock);
+	}
+
+	/* Reset Configuration Register to Disable Watch Dog Registers */
+	tmp = w83793_read_value(client, W83793_REG_CONFIG);
+	w83793_write_value(client, W83793_REG_CONFIG, tmp & ~0x04);
+
+	unregister_reboot_notifier(&watchdog_notifier);
 
 	hwmon_device_unregister(data->hwmon_dev);
 
@@ -1099,7 +1494,10 @@ static int w83793_remove(struct i2c_clie
 	if (data->lm75[1] != NULL)
 		i2c_unregister_device(data->lm75[1]);
 
-	kfree(data);
+	/* Decrease data reference counter */
+	mutex_lock(&watchdog_data_mutex);
+	kref_put(&data->kref, w83793_release_resources);
+	mutex_unlock(&watchdog_data_mutex);
 
 	return 0;
 }
@@ -1203,6 +1601,7 @@ static int w83793_probe(struct i2c_clien
 			const struct i2c_device_id *id)
 {
 	struct device *dev = &client->dev;
+	const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 };
 	struct w83793_data *data;
 	int i, tmp, val, err;
 	int files_fan = ARRAY_SIZE(w83793_left_fan) / 7;
@@ -1218,6 +1617,14 @@ static int w83793_probe(struct i2c_clien
 	i2c_set_clientdata(client, data);
 	data->bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL);
 	mutex_init(&data->update_lock);
+	mutex_init(&data->watchdog_lock);
+	INIT_LIST_HEAD(&data->list);
+	kref_init(&data->kref);
+
+	/* Store client pointer in our data struct for watchdog usage
+	   (where the client is found through a data ptr instead of the
+	   otherway around) */
+	data->client = client;
 
 	err = w83793_detect_subclients(client);
 	if (err)
@@ -1380,8 +1787,77 @@ static int w83793_probe(struct i2c_clien
 		goto exit_remove;
 	}
 
+	/* Watchdog initialization */
+
+	/* Register boot notifier */
+	err = register_reboot_notifier(&watchdog_notifier);
+	if (err != 0) {
+		dev_err(&client->dev,
+			"cannot register reboot notifier (err=%d)\n", err);
+		goto exit_devunreg;
+	}
+
+	/* Enable Watchdog registers.
+	   Set Configuration Register to Enable Watch Dog Registers
+	   (Bit 2) = XXXX, X1XX. */
+	tmp = w83793_read_value(client, W83793_REG_CONFIG);
+	w83793_write_value(client, W83793_REG_CONFIG, tmp | 0x04);
+
+	/* Set the default watchdog timeout */
+	data->watchdog_timeout = timeout;
+
+	/* Check, if last reboot was caused by watchdog */
+	data->watchdog_caused_reboot =
+	  w83793_read_value(data->client, W83793_REG_WDT_STATUS) & 0x01;
+
+	/* Disable Soft Watchdog during initialiation */
+	watchdog_disable(data);
+
+	/* We take the data_mutex lock early so that watchdog_open() cannot
+	   run when misc_register() has completed, but we've not yet added
+	   our data to the watchdog_data_list (and set the default timeout) */
+	mutex_lock(&watchdog_data_mutex);
+	for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) {
+		/* Register our watchdog part */
+		snprintf(data->watchdog_name, sizeof(data->watchdog_name),
+			"watchdog%c", (i == 0) ? '\0' : ('0' + i));
+		data->watchdog_miscdev.name = data->watchdog_name;
+		data->watchdog_miscdev.fops = &watchdog_fops;
+		data->watchdog_miscdev.minor = watchdog_minors[i];
+
+		err = misc_register(&data->watchdog_miscdev);
+		if (err == -EBUSY)
+			continue;
+		if (err) {
+			data->watchdog_miscdev.minor = 0;
+			dev_err(&client->dev,
+				"Registering watchdog chardev: %d\n", err);
+			break;
+		}
+
+		list_add(&data->list, &watchdog_data_list);
+
+		dev_info(&client->dev,
+			"Registered watchdog chardev major 10, minor: %d\n",
+			watchdog_minors[i]);
+		break;
+	}
+	if (i == ARRAY_SIZE(watchdog_minors)) {
+		data->watchdog_miscdev.minor = 0;
+		dev_warn(&client->dev, "Couldn't register watchdog chardev "
+			"(due to no free minor)\n");
+	}
+
+	mutex_unlock(&watchdog_data_mutex);
+
 	return 0;
 
+	/* Unregister hwmon device */
+
+exit_devunreg:
+
+	hwmon_device_unregister(data->hwmon_dev);
+
 	/* Unregister sysfs hooks */
 
 exit_remove:
@@ -1628,7 +2104,7 @@ static void __exit sensors_w83793_exit(v
 	i2c_del_driver(&w83793_driver);
 }
 
-MODULE_AUTHOR("Yuan Mu");
+MODULE_AUTHOR("Yuan Mu, Sven Anders");
 MODULE_DESCRIPTION("w83793 driver");
 MODULE_LICENSE("GPL");
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/hwmon/wm831x-hwmon.c linux-libre-2.6.34-gnu1/drivers/hwmon/wm831x-hwmon.c
--- linux-libre-2.6.33-gnu1/drivers/hwmon/wm831x-hwmon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/hwmon/wm831x-hwmon.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/err.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/auxadc.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/algos/i2c-algo-bit.c linux-libre-2.6.34-gnu1/drivers/i2c/algos/i2c-algo-bit.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/algos/i2c-algo-bit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/algos/i2c-algo-bit.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
@@ -522,6 +521,12 @@ static int bit_xfer(struct i2c_adapter *
 	int i, ret;
 	unsigned short nak_ok;
 
+	if (adap->pre_xfer) {
+		ret = adap->pre_xfer(i2c_adap);
+		if (ret < 0)
+			return ret;
+	}
+
 	bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
 	i2c_start(adap);
 	for (i = 0; i < num; i++) {
@@ -570,6 +575,9 @@ static int bit_xfer(struct i2c_adapter *
 bailout:
 	bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");
 	i2c_stop(adap);
+
+	if (adap->post_xfer)
+		adap->post_xfer(i2c_adap);
 	return ret;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/algos/i2c-algo-pca.c linux-libre-2.6.34-gnu1/drivers/i2c/algos/i2c-algo-pca.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/algos/i2c-algo-pca.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/algos/i2c-algo-pca.c	2010-05-16 17:17:36.000000000 -0400
@@ -453,8 +453,6 @@ static int pca_init(struct i2c_adapter *
 		 */
 		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
 		 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/algos/i2c-algo-pcf.c linux-libre-2.6.34-gnu1/drivers/i2c/algos/i2c-algo-pcf.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/algos/i2c-algo-pcf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/algos/i2c-algo-pcf.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,7 +29,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/i2c.h>
@@ -176,7 +175,7 @@ static int pcf_init_8584 (struct i2c_alg
 	 */
 	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 */
+		return -ENXIO; /* definitely not PCF8584 */
 	}
 
 	/* load own address in S0, effective address is (own << 1) */
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ali1535.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-ali1535.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ali1535.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-ali1535.c	2010-05-16 17:17:36.000000000 -0400
@@ -480,7 +480,7 @@ static struct i2c_adapter ali1535_adapte
 	.algo		= &smbus_algorithm,
 };
 
-static struct pci_device_id ali1535_ids[] = {
+static const struct pci_device_id ali1535_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
 	{ },
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ali1563.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-ali1563.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ali1563.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-ali1563.c	2010-05-16 17:17:36.000000000 -0400
@@ -417,7 +417,7 @@ static void __devexit ali1563_remove(str
 	ali1563_shutdown(dev);
 }
 
-static struct pci_device_id __devinitdata ali1563_id_table[] = {
+static const struct pci_device_id ali1563_id_table[] __devinitconst = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1563) },
 	{},
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ali15x3.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-ali15x3.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ali15x3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-ali15x3.c	2010-05-16 17:17:36.000000000 -0400
@@ -477,7 +477,7 @@ static struct i2c_adapter ali15x3_adapte
 	.algo		= &smbus_algorithm,
 };
 
-static struct pci_device_id ali15x3_ids[] = {
+static const struct pci_device_id ali15x3_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
 	{ 0, }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-amd756.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-amd756.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-amd756.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-amd756.c	2010-05-16 17:17:36.000000000 -0400
@@ -308,7 +308,7 @@ static const char* chipname[] = {
 	"nVidia nForce", "AMD8111",
 };
 
-static struct pci_device_id amd756_ids[] = {
+static const struct pci_device_id amd756_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B),
 	  .driver_data = AMD756 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413),
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-amd8111.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-amd8111.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-amd8111.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-amd8111.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 MODULE_LICENSE("GPL");
@@ -351,7 +352,7 @@ static const struct i2c_algorithm smbus_
 };
 
 
-static struct pci_device_id amd8111_ids[] = {
+static const struct pci_device_id amd8111_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS2) },
 	{ 0, }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-bfin-twi.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-bfin-twi.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-bfin-twi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-bfin-twi.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/mm.h>
 #include <linux/timer.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-davinci.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-davinci.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-davinci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-davinci.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-designware.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-designware.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-designware.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-designware.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 /*
  * Registers offset
@@ -497,13 +498,13 @@ static int i2c_dw_handle_tx_abort(struct
 	int i;
 
 	if (abort_source & DW_IC_TX_ABRT_NOACK) {
-		for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
+		for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
 			dev_dbg(dev->dev,
 				"%s: %s\n", __func__, abort_sources[i]);
 		return -EREMOTEIO;
 	}
 
-	for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
+	for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
 		dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]);
 
 	if (abort_source & DW_IC_TX_ARB_LOST)
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-elektor.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-elektor.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-elektor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-elektor.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,7 +29,6 @@
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-gpio.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-gpio.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/i2c-gpio.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 
 #include <asm/gpio.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-highlander.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-highlander.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-highlander.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-highlander.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/completion.h>
 #include <linux/io.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #define SMCR		0x00
 #define SMCR_START	(1 << 0)
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-hydra.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-hydra.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-hydra.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-hydra.c	2010-05-16 17:17:36.000000000 -0400
@@ -105,7 +105,7 @@ static struct i2c_adapter hydra_adap = {
 	.algo_data	= &hydra_bit_data,
 };
 
-static struct pci_device_id hydra_ids[] = {
+static const struct pci_device_id hydra_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_HYDRA) },
 	{ 0, }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-i801.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-i801.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-i801.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-i801.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,8 @@
   Tolapai               0x5032     32     hard     yes     yes     yes
   ICH10                 0x3a30     32     hard     yes     yes     yes
   ICH10                 0x3a60     32     hard     yes     yes     yes
-  PCH                   0x3b30     32     hard     yes     yes     yes
+  3400/5 Series (PCH)   0x3b30     32     hard     yes     yes     yes
+  Cougar Point (PCH)    0x1c22     32     hard     yes     yes     yes
 
   Features supported by this driver:
   Software PEC                     no
@@ -415,9 +416,11 @@ static int i801_block_transaction(union
 		data->block[0] = 32;	/* max for SMBus block reads */
 	}
 
+	/* Experience has shown that the block buffer can only be used for
+	   SMBus (not I2C) block transactions, even though the datasheet
+	   doesn't mention this limitation. */
 	if ((i801_features & FEATURE_BLOCK_BUFFER)
-	 && !(command == I2C_SMBUS_I2C_BLOCK_DATA
-	      && read_write == I2C_SMBUS_READ)
+	 && command != I2C_SMBUS_I2C_BLOCK_DATA
 	 && i801_set_block_buffer_mode() == 0)
 		result = i801_block_transaction_by_block(data, read_write,
 							 hwpec);
@@ -561,7 +564,7 @@ static struct i2c_adapter i801_adapter =
 	.algo		= &smbus_algorithm,
 };
 
-static struct pci_device_id i801_ids[] = {
+static const struct pci_device_id i801_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) },
@@ -578,6 +581,7 @@ static struct pci_device_id i801_ids[] =
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PCH_SMBUS) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CPT_SMBUS) },
 	{ 0, }
 };
 
@@ -707,6 +711,7 @@ static int __devinit i801_probe(struct p
 	case PCI_DEVICE_ID_INTEL_ICH10_4:
 	case PCI_DEVICE_ID_INTEL_ICH10_5:
 	case PCI_DEVICE_ID_INTEL_PCH_SMBUS:
+	case PCI_DEVICE_ID_INTEL_CPT_SMBUS:
 		i801_features |= FEATURE_I2C_BLOCK_READ;
 		/* fall through */
 	case PCI_DEVICE_ID_INTEL_82801DB_3:
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-imx.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-imx.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-imx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-imx.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,7 @@
 #include <linux/sched.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include <mach/irqs.h>
 #include <mach/hardware.h>
@@ -145,10 +146,10 @@ static int i2c_imx_bus_busy(struct imx_i
 				"<%s> I2C Interrupted\n", __func__);
 			return -EINTR;
 		}
-		if (time_after(jiffies, orig_jiffies + HZ / 1000)) {
+		if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
 			dev_dbg(&i2c_imx->adapter.dev,
 				"<%s> I2C bus is busy\n", __func__);
-			return -EIO;
+			return -ETIMEDOUT;
 		}
 		schedule();
 	}
@@ -443,6 +444,8 @@ static int i2c_imx_xfer(struct i2c_adapt
 			result = i2c_imx_read(i2c_imx, &msgs[i]);
 		else
 			result = i2c_imx_write(i2c_imx, &msgs[i]);
+		if (result)
+			goto fail0;
 	}
 
 fail0:
@@ -627,7 +630,6 @@ static int __exit i2c_imx_remove(struct
 }
 
 static struct platform_driver i2c_imx_driver = {
-	.probe		= i2c_imx_probe,
 	.remove		= __exit_p(i2c_imx_remove),
 	.driver	= {
 		.name	= DRIVER_NAME,
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-isch.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-isch.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-isch.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-isch.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,7 @@
 */
 
 #include <linux/module.h>
-#include <linux/pci.h>
+#include <linux/platform_device.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/stddef.h>
@@ -46,12 +46,6 @@
 #define SMBHSTDAT1	(7 + sch_smba)
 #define SMBBLKDAT	(0x20 + sch_smba)
 
-/* count for request_region */
-#define SMBIOSIZE	64
-
-/* PCI Address Constants */
-#define SMBBA_SCH	0x40
-
 /* Other settings */
 #define MAX_TIMEOUT	500
 
@@ -63,7 +57,6 @@
 #define SCH_BLOCK_DATA		0x05
 
 static unsigned short sch_smba;
-static struct pci_driver sch_driver;
 static struct i2c_adapter sch_adapter;
 
 /*
@@ -256,37 +249,23 @@ static struct i2c_adapter sch_adapter =
 	.algo		= &smbus_algorithm,
 };
 
-static struct pci_device_id sch_ids[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) },
-	{ 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, sch_ids);
-
-static int __devinit sch_probe(struct pci_dev *dev,
-				const struct pci_device_id *id)
+static int __devinit smbus_sch_probe(struct platform_device *dev)
 {
+	struct resource *res;
 	int retval;
-	unsigned int smba;
 
-	pci_read_config_dword(dev, SMBBA_SCH, &smba);
-	if (!(smba & (1 << 31))) {
-		dev_err(&dev->dev, "SMBus I/O space disabled!\n");
-		return -ENODEV;
-	}
+	res = platform_get_resource(dev, IORESOURCE_IO, 0);
+	if (!res)
+		return -EBUSY;
 
-	sch_smba = (unsigned short)smba;
-	if (sch_smba == 0) {
-		dev_err(&dev->dev, "SMBus base address uninitialized!\n");
-		return -ENODEV;
-	}
-	if (acpi_check_region(sch_smba, SMBIOSIZE, sch_driver.name))
-		return -ENODEV;
-	if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) {
+	if (!request_region(res->start, resource_size(res), dev->name)) {
 		dev_err(&dev->dev, "SMBus region 0x%x already in use!\n",
 			sch_smba);
 		return -EBUSY;
 	}
+
+	sch_smba = res->start;
+
 	dev_dbg(&dev->dev, "SMBA = 0x%X\n", sch_smba);
 
 	/* set up the sysfs linkage to our parent device */
@@ -298,37 +277,43 @@ static int __devinit sch_probe(struct pc
 	retval = i2c_add_adapter(&sch_adapter);
 	if (retval) {
 		dev_err(&dev->dev, "Couldn't register adapter!\n");
-		release_region(sch_smba, SMBIOSIZE);
+		release_region(res->start, resource_size(res));
 		sch_smba = 0;
 	}
 
 	return retval;
 }
 
-static void __devexit sch_remove(struct pci_dev *dev)
+static int __devexit smbus_sch_remove(struct platform_device *pdev)
 {
+	struct resource *res;
 	if (sch_smba) {
 		i2c_del_adapter(&sch_adapter);
-		release_region(sch_smba, SMBIOSIZE);
+		res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+		release_region(res->start, resource_size(res));
 		sch_smba = 0;
 	}
+
+	return 0;
 }
 
-static struct pci_driver sch_driver = {
-	.name		= "isch_smbus",
-	.id_table	= sch_ids,
-	.probe		= sch_probe,
-	.remove		= __devexit_p(sch_remove),
+static struct platform_driver smbus_sch_driver = {
+	.driver = {
+		.name = "isch_smbus",
+		.owner = THIS_MODULE,
+	},
+	.probe		= smbus_sch_probe,
+	.remove		= __devexit_p(smbus_sch_remove),
 };
 
 static int __init i2c_sch_init(void)
 {
-	return pci_register_driver(&sch_driver);
+	return platform_driver_register(&smbus_sch_driver);
 }
 
 static void __exit i2c_sch_exit(void)
 {
-	pci_unregister_driver(&sch_driver);
+	platform_driver_unregister(&smbus_sch_driver);
 }
 
 MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>");
@@ -337,3 +322,4 @@ MODULE_LICENSE("GPL");
 
 module_init(i2c_sch_init);
 module_exit(i2c_sch_exit);
+MODULE_ALIAS("platform:isch_smbus");
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ixp2000.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-ixp2000.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ixp2000.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-ixp2000.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>	/* Pick up IXP2000-specific bits */
 #include <mach/gpio.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-mpc.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-mpc.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-mpc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-mpc.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/of_platform.h>
 #include <linux/of_i2c.h>
+#include <linux/slab.h>
 
 #include <linux/io.h>
 #include <linux/fsl_devices.h>
@@ -31,6 +32,9 @@
 
 #define DRV_NAME "mpc-i2c"
 
+#define MPC_I2C_CLOCK_LEGACY   0
+#define MPC_I2C_CLOCK_PRESERVE (~0U)
+
 #define MPC_I2C_FDR   0x04
 #define MPC_I2C_CR    0x08
 #define MPC_I2C_SR    0x0c
@@ -66,10 +70,9 @@ struct mpc_i2c_divider {
 	u16 fdr;	/* including dfsrr */
 };
 
-struct mpc_i2c_match_data {
-	void (*setclock)(struct device_node *node,
-			 struct mpc_i2c *i2c,
-			 u32 clock, u32 prescaler);
+struct mpc_i2c_data {
+	void (*setup)(struct device_node *node, struct mpc_i2c *i2c,
+		      u32 clock, u32 prescaler);
 	u32 prescaler;
 };
 
@@ -164,8 +167,8 @@ static int i2c_wait(struct mpc_i2c *i2c,
 	return 0;
 }
 
-#ifdef CONFIG_PPC_MPC52xx
-static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = {
+#if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_PPC_MPC512x)
+static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitconst = {
 	{20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23},
 	{28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02},
 	{36, 0x26}, {40, 0x27}, {44, 0x04}, {48, 0x28},
@@ -186,14 +189,15 @@ static const struct mpc_i2c_divider mpc_
 	{10240, 0x9d}, {12288, 0x9e}, {15360, 0x9f}
 };
 
-int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler)
+static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,
+					  int prescaler)
 {
 	const struct mpc_i2c_divider *div = NULL;
 	unsigned int pvr = mfspr(SPRN_PVR);
 	u32 divider;
 	int i;
 
-	if (!clock)
+	if (clock == MPC_I2C_CLOCK_LEGACY)
 		return -EINVAL;
 
 	/* Determine divider value */
@@ -215,12 +219,18 @@ int mpc_i2c_get_fdr_52xx(struct device_n
 	return div ? (int)div->fdr : -EINVAL;
 }
 
-static void mpc_i2c_setclock_52xx(struct device_node *node,
-				  struct mpc_i2c *i2c,
-				  u32 clock, u32 prescaler)
+static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
+					 struct mpc_i2c *i2c,
+					 u32 clock, u32 prescaler)
 {
 	int ret, fdr;
 
+	if (clock == MPC_I2C_CLOCK_PRESERVE) {
+		dev_dbg(i2c->dev, "using fdr %d\n",
+			readb(i2c->base + MPC_I2C_FDR));
+		return;
+	}
+
 	ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler);
 	fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */
 
@@ -229,16 +239,52 @@ static void mpc_i2c_setclock_52xx(struct
 	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)
+#else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */
+static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
+					 struct mpc_i2c *i2c,
+					 u32 clock, u32 prescaler)
 {
 }
-#endif /* CONFIG_PPC_MPC52xx*/
+#endif /* CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x */
+
+#ifdef CONFIG_PPC_MPC512x
+static void __devinit mpc_i2c_setup_512x(struct device_node *node,
+					 struct mpc_i2c *i2c,
+					 u32 clock, u32 prescaler)
+{
+	struct device_node *node_ctrl;
+	void __iomem *ctrl;
+	const u32 *pval;
+	u32 idx;
+
+	/* Enable I2C interrupts for mpc5121 */
+	node_ctrl = of_find_compatible_node(NULL, NULL,
+					    "fsl,mpc5121-i2c-ctrl");
+	if (node_ctrl) {
+		ctrl = of_iomap(node_ctrl, 0);
+		if (ctrl) {
+			/* Interrupt enable bits for i2c-0/1/2: bit 24/26/28 */
+			pval = of_get_property(node, "reg", NULL);
+			idx = (*pval & 0xff) / 0x20;
+			setbits32(ctrl, 1 << (24 + idx * 2));
+			iounmap(ctrl);
+		}
+		of_node_put(node_ctrl);
+	}
+
+	/* The clock setup for the 52xx works also fine for the 512x */
+	mpc_i2c_setup_52xx(node, i2c, clock, prescaler);
+}
+#else /* CONFIG_PPC_MPC512x */
+static void __devinit mpc_i2c_setup_512x(struct device_node *node,
+					 struct mpc_i2c *i2c,
+					 u32 clock, u32 prescaler)
+{
+}
+#endif /* CONFIG_PPC_MPC512x */
 
 #ifdef CONFIG_FSL_SOC
-static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = {
+static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] __devinitconst = {
 	{160, 0x0120}, {192, 0x0121}, {224, 0x0122}, {256, 0x0123},
 	{288, 0x0100}, {320, 0x0101}, {352, 0x0601}, {384, 0x0102},
 	{416, 0x0602}, {448, 0x0126}, {480, 0x0103}, {512, 0x0127},
@@ -258,7 +304,7 @@ static const struct mpc_i2c_divider mpc_
 	{49152, 0x011e}, {61440, 0x011f}
 };
 
-u32 mpc_i2c_get_sec_cfg_8xxx(void)
+static u32 __devinit mpc_i2c_get_sec_cfg_8xxx(void)
 {
 	struct device_node *node = NULL;
 	u32 __iomem *reg;
@@ -287,13 +333,14 @@ u32 mpc_i2c_get_sec_cfg_8xxx(void)
 	return val;
 }
 
-int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, u32 prescaler)
+static int __devinit 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)
+	if (clock == MPC_I2C_CLOCK_LEGACY)
 		return -EINVAL;
 
 	/* Determine proper divider value */
@@ -320,12 +367,19 @@ int mpc_i2c_get_fdr_8xxx(struct device_n
 	return div ? (int)div->fdr : -EINVAL;
 }
 
-static void mpc_i2c_setclock_8xxx(struct device_node *node,
-				  struct mpc_i2c *i2c,
-				  u32 clock, u32 prescaler)
+static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
+					 struct mpc_i2c *i2c,
+					 u32 clock, u32 prescaler)
 {
 	int ret, fdr;
 
+	if (clock == MPC_I2C_CLOCK_PRESERVE) {
+		dev_dbg(i2c->dev, "using dfsrr %d, fdr %d\n",
+			readb(i2c->base + MPC_I2C_DFSRR),
+			readb(i2c->base + MPC_I2C_FDR));
+		return;
+	}
+
 	ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler);
 	fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */
 
@@ -338,9 +392,9 @@ static void mpc_i2c_setclock_8xxx(struct
 }
 
 #else /* !CONFIG_FSL_SOC */
-static void mpc_i2c_setclock_8xxx(struct device_node *node,
-				  struct mpc_i2c *i2c,
-				  u32 clock, u32 prescaler)
+static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
+					 struct mpc_i2c *i2c,
+					 u32 clock, u32 prescaler)
 {
 }
 #endif /* CONFIG_FSL_SOC */
@@ -494,7 +548,7 @@ static int __devinit fsl_i2c_probe(struc
 {
 	struct mpc_i2c *i2c;
 	const u32 *prop;
-	u32 clock = 0;
+	u32 clock = MPC_I2C_CLOCK_LEGACY;
 	int result = 0;
 	int plen;
 
@@ -523,21 +577,21 @@ static int __devinit fsl_i2c_probe(struc
 		}
 	}
 
-	if (!of_get_property(op->node, "fsl,preserve-clocking", NULL)) {
+	if (of_get_property(op->node, "fsl,preserve-clocking", NULL)) {
+		clock = MPC_I2C_CLOCK_PRESERVE;
+	} else {
 		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);
-		}
+	if (match->data) {
+		struct mpc_i2c_data *data = match->data;
+		data->setup(op->node, i2c, clock, data->prescaler);
+	} else {
+		/* Backwards compatibility */
+		if (of_get_property(op->node, "dfsrr", NULL))
+			mpc_i2c_setup_8xxx(op->node, i2c, clock, 0);
 	}
 
 	dev_set_drvdata(&op->dev, i2c);
@@ -582,47 +636,42 @@ static int __devexit fsl_i2c_remove(stru
 	return 0;
 };
 
+static struct mpc_i2c_data mpc_i2c_data_512x __devinitdata = {
+	.setup = mpc_i2c_setup_512x,
+};
+
+static struct mpc_i2c_data mpc_i2c_data_52xx __devinitdata = {
+	.setup = mpc_i2c_setup_52xx,
+};
+
+static struct mpc_i2c_data mpc_i2c_data_8313 __devinitdata = {
+	.setup = mpc_i2c_setup_8xxx,
+};
+
+static struct mpc_i2c_data mpc_i2c_data_8543 __devinitdata = {
+	.setup = mpc_i2c_setup_8xxx,
+	.prescaler = 2,
+};
+
+static struct mpc_i2c_data mpc_i2c_data_8544 __devinitdata = {
+	.setup = mpc_i2c_setup_8xxx,
+	.prescaler = 3,
+};
+
 static const struct of_device_id mpc_i2c_of_match[] = {
-	{.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,
-		},
+	{.compatible = "mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
+	{.compatible = "fsl,mpc5200b-i2c", .data = &mpc_i2c_data_52xx, },
+	{.compatible = "fsl,mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
+	{.compatible = "fsl,mpc5121-i2c", .data = &mpc_i2c_data_512x, },
+	{.compatible = "fsl,mpc8313-i2c", .data = &mpc_i2c_data_8313, },
+	{.compatible = "fsl,mpc8543-i2c", .data = &mpc_i2c_data_8543, },
+	{.compatible = "fsl,mpc8544-i2c", .data = &mpc_i2c_data_8544, },
 	/* Backward compatibility */
-	},
 	{.compatible = "fsl-i2c", },
 	{},
 };
-
 MODULE_DEVICE_TABLE(of, mpc_i2c_of_match);
 
-
 /* Structure for a device driver */
 static struct of_platform_driver mpc_i2c_driver = {
 	.match_table	= mpc_i2c_of_match,
@@ -655,5 +704,5 @@ 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");
+		   "MPC824x/83xx/85xx/86xx/512x/52xx processors");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-mv64xxx.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-mv64xxx.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-mv64xxx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-mv64xxx.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  * or implied.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/i2c.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-nforce2.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-nforce2.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-nforce2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-nforce2.c	2010-05-16 17:17:36.000000000 -0400
@@ -56,6 +56,7 @@
 #include <linux/delay.h>
 #include <linux/dmi.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 MODULE_LICENSE("GPL");
@@ -308,7 +309,7 @@ static struct i2c_algorithm smbus_algori
 };
 
 
-static struct pci_device_id nforce2_ids[] = {
+static const struct pci_device_id nforce2_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) },
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-nomadik.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-nomadik.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-nomadik.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-nomadik.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,960 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson
+ * Copyright (C) 2009 STMicroelectronics
+ *
+ * I2C master mode controller driver, used in Nomadik 8815
+ * and Ux500 platforms.
+ *
+ * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
+ * Author: Sachin Verma <sachin.verma@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/i2c.h>
+
+#define DRIVER_NAME "nmk-i2c"
+
+/* I2C Controller register offsets */
+#define I2C_CR		(0x000)
+#define I2C_SCR		(0x004)
+#define I2C_HSMCR	(0x008)
+#define I2C_MCR		(0x00C)
+#define I2C_TFR		(0x010)
+#define I2C_SR		(0x014)
+#define I2C_RFR		(0x018)
+#define I2C_TFTR	(0x01C)
+#define I2C_RFTR	(0x020)
+#define I2C_DMAR	(0x024)
+#define I2C_BRCR	(0x028)
+#define I2C_IMSCR	(0x02C)
+#define I2C_RISR	(0x030)
+#define I2C_MISR	(0x034)
+#define I2C_ICR		(0x038)
+
+/* Control registers */
+#define I2C_CR_PE		(0x1 << 0)	/* Peripheral Enable */
+#define I2C_CR_OM		(0x3 << 1)	/* Operating mode */
+#define I2C_CR_SAM		(0x1 << 3)	/* Slave addressing mode */
+#define I2C_CR_SM		(0x3 << 4)	/* Speed mode */
+#define I2C_CR_SGCM		(0x1 << 6)	/* Slave general call mode */
+#define I2C_CR_FTX		(0x1 << 7)	/* Flush Transmit */
+#define I2C_CR_FRX		(0x1 << 8)	/* Flush Receive */
+#define I2C_CR_DMA_TX_EN	(0x1 << 9)	/* DMA Tx enable */
+#define I2C_CR_DMA_RX_EN	(0x1 << 10)	/* DMA Rx Enable */
+#define I2C_CR_DMA_SLE		(0x1 << 11)	/* DMA sync. logic enable */
+#define I2C_CR_LM		(0x1 << 12)	/* Loopback mode */
+#define I2C_CR_FON		(0x3 << 13)	/* Filtering on */
+#define I2C_CR_FS		(0x3 << 15)	/* Force stop enable */
+
+/* Master controller (MCR) register */
+#define I2C_MCR_OP		(0x1 << 0)	/* Operation */
+#define I2C_MCR_A7		(0x7f << 1)	/* 7-bit address */
+#define I2C_MCR_EA10		(0x7 << 8) 	/* 10-bit Extended address */
+#define I2C_MCR_SB		(0x1 << 11)	/* Extended address */
+#define I2C_MCR_AM		(0x3 << 12)	/* Address type */
+#define I2C_MCR_STOP		(0x1 << 14) 	/* Stop condition */
+#define I2C_MCR_LENGTH		(0x7ff << 15) 	/* Transaction length */
+
+/* Status register (SR) */
+#define I2C_SR_OP		(0x3 << 0)	/* Operation */
+#define I2C_SR_STATUS		(0x3 << 2)	/* controller status */
+#define I2C_SR_CAUSE		(0x7 << 4)	/* Abort cause */
+#define I2C_SR_TYPE		(0x3 << 7)	/* Receive type */
+#define I2C_SR_LENGTH		(0x7ff << 9)	/* Transfer length */
+
+/* Interrupt mask set/clear (IMSCR) bits */
+#define I2C_IT_TXFE 		(0x1 << 0)
+#define I2C_IT_TXFNE		(0x1 << 1)
+#define I2C_IT_TXFF		(0x1 << 2)
+#define I2C_IT_TXFOVR		(0x1 << 3)
+#define I2C_IT_RXFE		(0x1 << 4)
+#define I2C_IT_RXFNF		(0x1 << 5)
+#define I2C_IT_RXFF		(0x1 << 6)
+#define I2C_IT_RFSR		(0x1 << 16)
+#define I2C_IT_RFSE		(0x1 << 17)
+#define I2C_IT_WTSR		(0x1 << 18)
+#define I2C_IT_MTD		(0x1 << 19)
+#define I2C_IT_STD		(0x1 << 20)
+#define I2C_IT_MAL		(0x1 << 24)
+#define I2C_IT_BERR		(0x1 << 25)
+#define I2C_IT_MTDWS		(0x1 << 28)
+
+#define GEN_MASK(val, mask, sb)  (((val) << (sb)) & (mask))
+
+/* some bits in ICR are reserved */
+#define I2C_CLEAR_ALL_INTS	0x131f007f
+
+/* first three msb bits are reserved */
+#define IRQ_MASK(mask)		(mask & 0x1fffffff)
+
+/* maximum threshold value */
+#define MAX_I2C_FIFO_THRESHOLD	15
+
+enum i2c_status {
+	I2C_NOP,
+	I2C_ON_GOING,
+	I2C_OK,
+	I2C_ABORT
+};
+
+/* operation */
+enum i2c_operation {
+	I2C_NO_OPERATION = 0xff,
+	I2C_WRITE = 0x00,
+	I2C_READ = 0x01
+};
+
+/* controller response timeout in ms */
+#define I2C_TIMEOUT_MS	500
+
+/**
+ * struct i2c_nmk_client - client specific data
+ * @slave_adr: 7-bit slave address
+ * @count: no. bytes to be transfered
+ * @buffer: client data buffer
+ * @xfer_bytes: bytes transfered till now
+ * @operation: current I2C operation
+ */
+struct i2c_nmk_client {
+	unsigned short		slave_adr;
+	unsigned long		count;
+	unsigned char		*buffer;
+	unsigned long		xfer_bytes;
+	enum i2c_operation	operation;
+};
+
+/**
+ * struct nmk_i2c_dev - private data structure of the controller
+ * @pdev: parent platform device
+ * @adap: corresponding I2C adapter
+ * @irq: interrupt line for the controller
+ * @virtbase: virtual io memory area
+ * @clk: hardware i2c block clock
+ * @cfg: machine provided controller configuration
+ * @cli: holder of client specific data
+ * @stop: stop condition
+ * @xfer_complete: acknowledge completion for a I2C message
+ * @result: controller propogated result
+ */
+struct nmk_i2c_dev {
+	struct platform_device		*pdev;
+	struct i2c_adapter 		adap;
+	int 				irq;
+	void __iomem			*virtbase;
+	struct clk			*clk;
+	struct nmk_i2c_controller	cfg;
+	struct i2c_nmk_client		cli;
+	int 				stop;
+	struct completion		xfer_complete;
+	int 				result;
+};
+
+/* controller's abort causes */
+static const char *abort_causes[] = {
+	"no ack received after address transmission",
+	"no ack received during data phase",
+	"ack received after xmission of master code",
+	"master lost arbitration",
+	"slave restarts",
+	"slave reset",
+	"overflow, maxsize is 2047 bytes",
+};
+
+static inline void i2c_set_bit(void __iomem *reg, u32 mask)
+{
+	writel(readl(reg) | mask, reg);
+}
+
+static inline void i2c_clr_bit(void __iomem *reg, u32 mask)
+{
+	writel(readl(reg) & ~mask, reg);
+}
+
+/**
+ * flush_i2c_fifo() - This function flushes the I2C FIFO
+ * @dev: private data of I2C Driver
+ *
+ * This function flushes the I2C Tx and Rx FIFOs. It returns
+ * 0 on successful flushing of FIFO
+ */
+static int flush_i2c_fifo(struct nmk_i2c_dev *dev)
+{
+#define LOOP_ATTEMPTS 10
+	int i;
+	unsigned long timeout;
+
+	/*
+	 * flush the transmit and receive FIFO. The flushing
+	 * operation takes several cycles before to be completed.
+	 * On the completion, the I2C internal logic clears these
+	 * bits, until then no one must access Tx, Rx FIFO and
+	 * should poll on these bits waiting for the completion.
+	 */
+	writel((I2C_CR_FTX | I2C_CR_FRX), dev->virtbase + I2C_CR);
+
+	for (i = 0; i < LOOP_ATTEMPTS; i++) {
+		timeout = jiffies + msecs_to_jiffies(I2C_TIMEOUT_MS);
+
+		while (!time_after(jiffies, timeout)) {
+			if ((readl(dev->virtbase + I2C_CR) &
+				(I2C_CR_FTX | I2C_CR_FRX)) == 0)
+					return 0;
+		}
+	}
+
+	dev_err(&dev->pdev->dev, "flushing operation timed out "
+		"giving up after %d attempts", LOOP_ATTEMPTS);
+
+	return -ETIMEDOUT;
+}
+
+/**
+ * disable_all_interrupts() - Disable all interrupts of this I2c Bus
+ * @dev: private data of I2C Driver
+ */
+static void disable_all_interrupts(struct nmk_i2c_dev *dev)
+{
+	u32 mask = IRQ_MASK(0);
+	writel(mask, dev->virtbase + I2C_IMSCR);
+}
+
+/**
+ * clear_all_interrupts() - Clear all interrupts of I2C Controller
+ * @dev: private data of I2C Driver
+ */
+static void clear_all_interrupts(struct nmk_i2c_dev *dev)
+{
+	u32 mask;
+	mask = IRQ_MASK(I2C_CLEAR_ALL_INTS);
+	writel(mask, dev->virtbase + I2C_ICR);
+}
+
+/**
+ * init_hw() - initialize the I2C hardware
+ * @dev: private data of I2C Driver
+ */
+static int init_hw(struct nmk_i2c_dev *dev)
+{
+	int stat;
+
+	stat = flush_i2c_fifo(dev);
+	if (stat)
+		return stat;
+
+	/* disable the controller */
+	i2c_clr_bit(dev->virtbase + I2C_CR , I2C_CR_PE);
+
+	disable_all_interrupts(dev);
+
+	clear_all_interrupts(dev);
+
+	dev->cli.operation = I2C_NO_OPERATION;
+
+	return 0;
+}
+
+/* enable peripheral, master mode operation */
+#define DEFAULT_I2C_REG_CR 	((1 << 1) | I2C_CR_PE)
+
+/**
+ * load_i2c_mcr_reg() - load the MCR register
+ * @dev: private data of controller
+ */
+static u32 load_i2c_mcr_reg(struct nmk_i2c_dev *dev)
+{
+	u32 mcr = 0;
+
+	/* 7-bit address transaction */
+	mcr |= GEN_MASK(1, I2C_MCR_AM, 12);
+	mcr |= GEN_MASK(dev->cli.slave_adr, I2C_MCR_A7, 1);
+
+	/* start byte procedure not applied */
+	mcr |= GEN_MASK(0, I2C_MCR_SB, 11);
+
+	/* check the operation, master read/write? */
+	if (dev->cli.operation == I2C_WRITE)
+		mcr |= GEN_MASK(I2C_WRITE, I2C_MCR_OP, 0);
+	else
+		mcr |= GEN_MASK(I2C_READ, I2C_MCR_OP, 0);
+
+	/* stop or repeated start? */
+	if (dev->stop)
+		mcr |= GEN_MASK(1, I2C_MCR_STOP, 14);
+	else
+		mcr &= ~(GEN_MASK(1, I2C_MCR_STOP, 14));
+
+	mcr |= GEN_MASK(dev->cli.count, I2C_MCR_LENGTH, 15);
+
+	return mcr;
+}
+
+/**
+ * setup_i2c_controller() - setup the controller
+ * @dev: private data of controller
+ */
+static void setup_i2c_controller(struct nmk_i2c_dev *dev)
+{
+	u32 brcr1, brcr2;
+	u32 i2c_clk, div;
+
+	writel(0x0, dev->virtbase + I2C_CR);
+	writel(0x0, dev->virtbase + I2C_HSMCR);
+	writel(0x0, dev->virtbase + I2C_TFTR);
+	writel(0x0, dev->virtbase + I2C_RFTR);
+	writel(0x0, dev->virtbase + I2C_DMAR);
+
+	/*
+	 * set the slsu:
+	 *
+	 * slsu defines the data setup time after SCL clock
+	 * stretching in terms of i2c clk cycles. The
+	 * needed setup time for the three modes are 250ns,
+	 * 100ns, 10ns repectively thus leading to the values
+	 * of 14, 6, 2 for a 48 MHz i2c clk.
+	 */
+	writel(dev->cfg.slsu << 16, dev->virtbase + I2C_SCR);
+
+	i2c_clk = clk_get_rate(dev->clk);
+
+	/* fallback to std. mode if machine has not provided it */
+	if (dev->cfg.clk_freq == 0)
+		dev->cfg.clk_freq = 100000;
+
+	/*
+	 * The spec says, in case of std. mode the divider is
+	 * 2 whereas it is 3 for fast and fastplus mode of
+	 * operation. TODO - high speed support.
+	 */
+	div = (dev->cfg.clk_freq > 100000) ? 3 : 2;
+
+	/*
+	 * generate the mask for baud rate counters. The controller
+	 * has two baud rate counters. One is used for High speed
+	 * operation, and the other is for std, fast mode, fast mode
+	 * plus operation. Currently we do not supprt high speed mode
+	 * so set brcr1 to 0.
+	 */
+	brcr1 = 0 << 16;
+	brcr2 = (i2c_clk/(dev->cfg.clk_freq * div)) & 0xffff;
+
+	/* set the baud rate counter register */
+	writel((brcr1 | brcr2), dev->virtbase + I2C_BRCR);
+
+	/*
+	 * set the speed mode. Currently we support
+	 * only standard and fast mode of operation
+	 * TODO - support for fast mode plus (upto 1Mb/s)
+	 * and high speed (up to 3.4 Mb/s)
+	 */
+	if (dev->cfg.sm > I2C_FREQ_MODE_FAST) {
+		dev_err(&dev->pdev->dev, "do not support this mode "
+			"defaulting to std. mode\n");
+		brcr2 = i2c_clk/(100000 * 2) & 0xffff;
+		writel((brcr1 | brcr2), dev->virtbase + I2C_BRCR);
+		writel(I2C_FREQ_MODE_STANDARD << 4,
+				dev->virtbase + I2C_CR);
+	}
+	writel(dev->cfg.sm << 4, dev->virtbase + I2C_CR);
+
+	/* set the Tx and Rx FIFO threshold */
+	writel(dev->cfg.tft, dev->virtbase + I2C_TFTR);
+	writel(dev->cfg.rft, dev->virtbase + I2C_RFTR);
+}
+
+/**
+ * read_i2c() - Read from I2C client device
+ * @dev: private data of I2C Driver
+ *
+ * This function reads from i2c client device when controller is in
+ * master mode. There is a completion timeout. If there is no transfer
+ * before timeout error is returned.
+ */
+static int read_i2c(struct nmk_i2c_dev *dev)
+{
+	u32 status = 0;
+	u32 mcr;
+	u32 irq_mask = 0;
+	int timeout;
+
+	mcr = load_i2c_mcr_reg(dev);
+	writel(mcr, dev->virtbase + I2C_MCR);
+
+	/* load the current CR value */
+	writel(readl(dev->virtbase + I2C_CR) | DEFAULT_I2C_REG_CR,
+			dev->virtbase + I2C_CR);
+
+	/* enable the controller */
+	i2c_set_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
+
+	init_completion(&dev->xfer_complete);
+
+	/* enable interrupts by setting the mask */
+	irq_mask = (I2C_IT_RXFNF | I2C_IT_RXFF |
+			I2C_IT_MAL | I2C_IT_BERR);
+
+	if (dev->stop)
+		irq_mask |= I2C_IT_MTD;
+	else
+		irq_mask |= I2C_IT_MTDWS;
+
+	irq_mask = I2C_CLEAR_ALL_INTS & IRQ_MASK(irq_mask);
+
+	writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask,
+			dev->virtbase + I2C_IMSCR);
+
+	timeout = wait_for_completion_interruptible_timeout(
+		&dev->xfer_complete, msecs_to_jiffies(I2C_TIMEOUT_MS));
+
+	if (timeout < 0) {
+		dev_err(&dev->pdev->dev,
+			"wait_for_completion_interruptible_timeout"
+			"returned %d waiting for event\n", timeout);
+		status = timeout;
+	}
+
+	if (timeout == 0) {
+		/* controler has timedout, re-init the h/w */
+		dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n");
+		(void) init_hw(dev);
+		status = -ETIMEDOUT;
+	}
+
+	return status;
+}
+
+/**
+ * write_i2c() - Write data to I2C client.
+ * @dev: private data of I2C Driver
+ *
+ * This function writes data to I2C client
+ */
+static int write_i2c(struct nmk_i2c_dev *dev)
+{
+	u32 status = 0;
+	u32 mcr;
+	u32 irq_mask = 0;
+	int timeout;
+
+	mcr = load_i2c_mcr_reg(dev);
+
+	writel(mcr, dev->virtbase + I2C_MCR);
+
+	/* load the current CR value */
+	writel(readl(dev->virtbase + I2C_CR) | DEFAULT_I2C_REG_CR,
+			dev->virtbase + I2C_CR);
+
+	/* enable the controller */
+	i2c_set_bit(dev->virtbase + I2C_CR , I2C_CR_PE);
+
+	init_completion(&dev->xfer_complete);
+
+	/* enable interrupts by settings the masks */
+	irq_mask = (I2C_IT_TXFNE | I2C_IT_TXFOVR |
+			I2C_IT_MAL | I2C_IT_BERR);
+
+	/*
+	 * check if we want to transfer a single or multiple bytes, if so
+	 * set the MTDWS bit (Master Transaction Done Without Stop)
+	 * to start repeated start operation
+	 */
+	if (dev->stop)
+		irq_mask |= I2C_IT_MTD;
+	else
+		irq_mask |= I2C_IT_MTDWS;
+
+	irq_mask = I2C_CLEAR_ALL_INTS & IRQ_MASK(irq_mask);
+
+	writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask,
+			dev->virtbase + I2C_IMSCR);
+
+	timeout = wait_for_completion_interruptible_timeout(
+		&dev->xfer_complete, msecs_to_jiffies(I2C_TIMEOUT_MS));
+
+	if (timeout < 0) {
+		dev_err(&dev->pdev->dev,
+			"wait_for_completion_interruptible_timeout"
+			"returned %d waiting for event\n", timeout);
+		status = timeout;
+	}
+
+	if (timeout == 0) {
+		/* controler has timedout, re-init the h/w */
+		dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n");
+		(void) init_hw(dev);
+		status = -ETIMEDOUT;
+	}
+
+	return status;
+}
+
+/**
+ * nmk_i2c_xfer() - I2C transfer function used by kernel framework
+ * @i2c_adap 	- Adapter pointer to the controller
+ * @msgs[] - Pointer to data to be written.
+ * @num_msgs - Number of messages to be executed
+ *
+ * This is the function called by the generic kernel i2c_transfer()
+ * or i2c_smbus...() API calls. Note that this code is protected by the
+ * semaphore set in the kernel i2c_transfer() function.
+ *
+ * NOTE:
+ * READ TRANSFER : We impose a restriction of the first message to be the
+ * 		index message for any read transaction.
+ * 		- a no index is coded as '0',
+ * 		- 2byte big endian index is coded as '3'
+ * 		!!! msg[0].buf holds the actual index.
+ * 		This is compatible with generic messages of smbus emulator
+ * 		that send a one byte index.
+ * 		eg. a I2C transation to read 2 bytes from index 0
+ *			idx = 0;
+ *			msg[0].addr = client->addr;
+ *			msg[0].flags = 0x0;
+ *			msg[0].len = 1;
+ *			msg[0].buf = &idx;
+ *
+ *			msg[1].addr = client->addr;
+ *			msg[1].flags = I2C_M_RD;
+ *			msg[1].len = 2;
+ *			msg[1].buf = rd_buff
+ *			i2c_transfer(adap, msg, 2);
+ *
+ * WRITE TRANSFER : The I2C standard interface interprets all data as payload.
+ *		If you want to emulate an SMBUS write transaction put the
+ *		index as first byte(or first and second) in the payload.
+ *		eg. a I2C transation to write 2 bytes from index 1
+ *			wr_buff[0] = 0x1;
+ *			wr_buff[1] = 0x23;
+ *			wr_buff[2] = 0x46;
+ *			msg[0].flags = 0x0;
+ *			msg[0].len = 3;
+ *			msg[0].buf = wr_buff;
+ *			i2c_transfer(adap, msg, 1);
+ *
+ * To read or write a block of data (multiple bytes) using SMBUS emulation
+ * please use the i2c_smbus_read_i2c_block_data()
+ * or i2c_smbus_write_i2c_block_data() API
+ */
+static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
+		struct i2c_msg msgs[], int num_msgs)
+{
+	int status;
+	int i;
+	u32 cause;
+	struct nmk_i2c_dev *dev = i2c_get_adapdata(i2c_adap);
+
+	status = init_hw(dev);
+	if (status)
+		return status;
+
+	/* setup the i2c controller */
+	setup_i2c_controller(dev);
+
+	for (i = 0; i < num_msgs; i++) {
+		if (unlikely(msgs[i].flags & I2C_M_TEN)) {
+			dev_err(&dev->pdev->dev, "10 bit addressing"
+					"not supported\n");
+			return -EINVAL;
+		}
+		dev->cli.slave_adr	= msgs[i].addr;
+		dev->cli.buffer		= msgs[i].buf;
+		dev->cli.count		= msgs[i].len;
+		dev->stop = (i < (num_msgs - 1)) ? 0 : 1;
+		dev->result = 0;
+
+		if (msgs[i].flags & I2C_M_RD) {
+			/* it is a read operation */
+			dev->cli.operation = I2C_READ;
+			status = read_i2c(dev);
+		} else {
+			/* write operation */
+			dev->cli.operation = I2C_WRITE;
+			status = write_i2c(dev);
+		}
+		if (status || (dev->result)) {
+			/* get the abort cause */
+			cause =	(readl(dev->virtbase + I2C_SR) >> 4) & 0x7;
+			dev_err(&dev->pdev->dev, "error during I2C"
+					"message xfer: %d\n", cause);
+			dev_err(&dev->pdev->dev, "%s\n",
+				cause >= ARRAY_SIZE(abort_causes)
+				? "unknown reason" : abort_causes[cause]);
+			return status;
+		}
+		mdelay(1);
+	}
+	/* return the no. messages processed */
+	if (status)
+		return status;
+	else
+		return num_msgs;
+}
+
+/**
+ * disable_interrupts() - disable the interrupts
+ * @dev: private data of controller
+ */
+static int disable_interrupts(struct nmk_i2c_dev *dev, u32 irq)
+{
+	irq = IRQ_MASK(irq);
+	writel(readl(dev->virtbase + I2C_IMSCR) & ~(I2C_CLEAR_ALL_INTS & irq),
+			dev->virtbase + I2C_IMSCR);
+	return 0;
+}
+
+/**
+ * i2c_irq_handler() - interrupt routine
+ * @irq: interrupt number
+ * @arg: data passed to the handler
+ *
+ * This is the interrupt handler for the i2c driver. Currently
+ * it handles the major interrupts like Rx & Tx FIFO management
+ * interrupts, master transaction interrupts, arbitration and
+ * bus error interrupts. The rest of the interrupts are treated as
+ * unhandled.
+ */
+static irqreturn_t i2c_irq_handler(int irq, void *arg)
+{
+	struct nmk_i2c_dev *dev = arg;
+	u32 tft, rft;
+	u32 count;
+	u32 misr;
+	u32 src = 0;
+
+	/* load Tx FIFO and Rx FIFO threshold values */
+	tft = readl(dev->virtbase + I2C_TFTR);
+	rft = readl(dev->virtbase + I2C_RFTR);
+
+	/* read interrupt status register */
+	misr = readl(dev->virtbase + I2C_MISR);
+
+	src = __ffs(misr);
+	switch ((1 << src)) {
+
+	/* Transmit FIFO nearly empty interrupt */
+	case I2C_IT_TXFNE:
+	{
+		if (dev->cli.operation == I2C_READ) {
+			/*
+			 * in read operation why do we care for writing?
+			 * so disable the Transmit FIFO interrupt
+			 */
+			disable_interrupts(dev, I2C_IT_TXFNE);
+		} else {
+			for (count = (MAX_I2C_FIFO_THRESHOLD - tft - 2);
+					(count > 0) &&
+					(dev->cli.count != 0);
+					count--) {
+				/* write to the Tx FIFO */
+				writeb(*dev->cli.buffer,
+					dev->virtbase + I2C_TFR);
+				dev->cli.buffer++;
+				dev->cli.count--;
+				dev->cli.xfer_bytes++;
+			}
+			/*
+			 * if done, close the transfer by disabling the
+			 * corresponding TXFNE interrupt
+			 */
+			if (dev->cli.count == 0)
+				disable_interrupts(dev,	I2C_IT_TXFNE);
+		}
+	}
+	break;
+
+	/*
+	 * Rx FIFO nearly full interrupt.
+	 * This is set when the numer of entries in Rx FIFO is
+	 * greater or equal than the threshold value programmed
+	 * in RFT
+	 */
+	case I2C_IT_RXFNF:
+		for (count = rft; count > 0; count--) {
+			/* Read the Rx FIFO */
+			*dev->cli.buffer = readb(dev->virtbase + I2C_RFR);
+			dev->cli.buffer++;
+		}
+		dev->cli.count -= rft;
+		dev->cli.xfer_bytes += rft;
+		break;
+
+	/* Rx FIFO full */
+	case I2C_IT_RXFF:
+		for (count = MAX_I2C_FIFO_THRESHOLD; count > 0; count--) {
+			*dev->cli.buffer = readb(dev->virtbase + I2C_RFR);
+			dev->cli.buffer++;
+		}
+		dev->cli.count -= MAX_I2C_FIFO_THRESHOLD;
+		dev->cli.xfer_bytes += MAX_I2C_FIFO_THRESHOLD;
+		break;
+
+	/* Master Transaction Done with/without stop */
+	case I2C_IT_MTD:
+	case I2C_IT_MTDWS:
+		if (dev->cli.operation == I2C_READ) {
+			while (!readl(dev->virtbase + I2C_RISR) & I2C_IT_RXFE) {
+				if (dev->cli.count == 0)
+					break;
+				*dev->cli.buffer =
+					readb(dev->virtbase + I2C_RFR);
+				dev->cli.buffer++;
+				dev->cli.count--;
+				dev->cli.xfer_bytes++;
+			}
+		}
+
+		i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MTD);
+		i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MTDWS);
+
+		disable_interrupts(dev,
+				(I2C_IT_TXFNE | I2C_IT_TXFE | I2C_IT_TXFF
+					| I2C_IT_TXFOVR | I2C_IT_RXFNF
+					| I2C_IT_RXFF | I2C_IT_RXFE));
+
+		if (dev->cli.count) {
+			dev->result = -1;
+			dev_err(&dev->pdev->dev, "%lu bytes still remain to be"
+					"xfered\n", dev->cli.count);
+			(void) init_hw(dev);
+		}
+		complete(&dev->xfer_complete);
+
+		break;
+
+	/* Master Arbitration lost interrupt */
+	case I2C_IT_MAL:
+		dev->result = -1;
+		(void) init_hw(dev);
+
+		i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MAL);
+		complete(&dev->xfer_complete);
+
+		break;
+
+	/*
+	 * Bus Error interrupt.
+	 * This happens when an unexpected start/stop condition occurs
+	 * during the transaction.
+	 */
+	case I2C_IT_BERR:
+		dev->result = -1;
+		/* get the status */
+		if (((readl(dev->virtbase + I2C_SR) >> 2) & 0x3) == I2C_ABORT)
+			(void) init_hw(dev);
+
+		i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_BERR);
+		complete(&dev->xfer_complete);
+
+		break;
+
+	/*
+	 * Tx FIFO overrun interrupt.
+	 * This is set when a write operation in Tx FIFO is performed and
+	 * the Tx FIFO is full.
+	 */
+	case I2C_IT_TXFOVR:
+		dev->result = -1;
+		(void) init_hw(dev);
+
+		dev_err(&dev->pdev->dev, "Tx Fifo Over run\n");
+		complete(&dev->xfer_complete);
+
+		break;
+
+	/* unhandled interrupts by this driver - TODO*/
+	case I2C_IT_TXFE:
+	case I2C_IT_TXFF:
+	case I2C_IT_RXFE:
+	case I2C_IT_RFSR:
+	case I2C_IT_RFSE:
+	case I2C_IT_WTSR:
+	case I2C_IT_STD:
+		dev_err(&dev->pdev->dev, "unhandled Interrupt\n");
+		break;
+	default:
+		dev_err(&dev->pdev->dev, "spurious Interrupt..\n");
+		break;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static unsigned int nmk_i2c_functionality(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C
+		| I2C_FUNC_SMBUS_BYTE_DATA
+		| I2C_FUNC_SMBUS_WORD_DATA
+		| I2C_FUNC_SMBUS_I2C_BLOCK;
+}
+
+static const struct i2c_algorithm nmk_i2c_algo = {
+	.master_xfer	= nmk_i2c_xfer,
+	.functionality	= nmk_i2c_functionality
+};
+
+static int __devinit nmk_i2c_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct resource *res;
+	struct nmk_i2c_controller *pdata =
+			pdev->dev.platform_data;
+	struct nmk_i2c_dev	*dev;
+	struct i2c_adapter *adap;
+
+	dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL);
+	if (!dev) {
+		dev_err(&pdev->dev, "cannot allocate memory\n");
+		ret = -ENOMEM;
+		goto err_no_mem;
+	}
+
+	dev->pdev = pdev;
+	platform_set_drvdata(pdev, dev);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENOENT;
+		goto err_no_resource;
+	}
+
+	if (request_mem_region(res->start, resource_size(res),
+		DRIVER_NAME "I/O region") == 	NULL)	{
+		ret = -EBUSY;
+		goto err_no_region;
+	}
+
+	dev->virtbase = ioremap(res->start, resource_size(res));
+	if (!dev->virtbase) {
+		ret = -ENOMEM;
+		goto err_no_ioremap;
+	}
+
+	dev->irq = platform_get_irq(pdev, 0);
+	ret = request_irq(dev->irq, i2c_irq_handler, IRQF_DISABLED,
+				DRIVER_NAME, dev);
+	if (ret) {
+		dev_err(&pdev->dev, "cannot claim the irq %d\n", dev->irq);
+		goto err_irq;
+	}
+
+	dev->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(dev->clk)) {
+		dev_err(&pdev->dev, "could not get i2c clock\n");
+		ret = PTR_ERR(dev->clk);
+		goto err_no_clk;
+	}
+
+	clk_enable(dev->clk);
+
+	adap = &dev->adap;
+	adap->dev.parent = &pdev->dev;
+	adap->owner	= THIS_MODULE;
+	adap->class	= I2C_CLASS_HWMON | I2C_CLASS_SPD;
+	adap->algo	= &nmk_i2c_algo;
+
+	/* fetch the controller id */
+	adap->nr	= pdev->id;
+
+	/* fetch the controller configuration from machine */
+	dev->cfg.clk_freq = pdata->clk_freq;
+	dev->cfg.slsu	= pdata->slsu;
+	dev->cfg.tft	= pdata->tft;
+	dev->cfg.rft	= pdata->rft;
+	dev->cfg.sm	= pdata->sm;
+
+	i2c_set_adapdata(adap, dev);
+
+	ret = init_hw(dev);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "error in initializing i2c hardware\n");
+		goto err_init_hw;
+	}
+
+	dev_dbg(&pdev->dev, "initialize I2C%d bus on virtual "
+		"base %p\n", pdev->id, dev->virtbase);
+
+	ret = i2c_add_numbered_adapter(adap);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to add adapter\n");
+		goto err_add_adap;
+	}
+
+	return 0;
+
+ err_init_hw:
+	clk_disable(dev->clk);
+ err_add_adap:
+	clk_put(dev->clk);
+ err_no_clk:
+	free_irq(dev->irq, dev);
+ err_irq:
+	iounmap(dev->virtbase);
+ err_no_ioremap:
+	release_mem_region(res->start, resource_size(res));
+ err_no_region:
+	platform_set_drvdata(pdev, NULL);
+ err_no_resource:
+	kfree(dev);
+ err_no_mem:
+
+	return ret;
+}
+
+static int __devexit nmk_i2c_remove(struct platform_device *pdev)
+{
+	struct nmk_i2c_dev *dev = platform_get_drvdata(pdev);
+
+	i2c_del_adapter(&dev->adap);
+	flush_i2c_fifo(dev);
+	disable_all_interrupts(dev);
+	clear_all_interrupts(dev);
+	/* disable the controller */
+	i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
+	free_irq(dev->irq, dev);
+	iounmap(dev->virtbase);
+	clk_disable(dev->clk);
+	clk_put(dev->clk);
+	platform_set_drvdata(pdev, NULL);
+	kfree(dev);
+
+	return 0;
+}
+
+static struct platform_driver nmk_i2c_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = DRIVER_NAME,
+	},
+	.probe = nmk_i2c_probe,
+	.remove = __devexit_p(nmk_i2c_remove),
+};
+
+static int __init nmk_i2c_init(void)
+{
+	return platform_driver_register(&nmk_i2c_driver);
+}
+
+static void __exit nmk_i2c_exit(void)
+{
+	platform_driver_unregister(&nmk_i2c_driver);
+}
+
+subsys_initcall(nmk_i2c_init);
+module_exit(nmk_i2c_exit);
+
+MODULE_AUTHOR("Sachin Verma, Srinidhi KASAGAR");
+MODULE_DESCRIPTION("Nomadik/Ux500 I2C driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ocores.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-ocores.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ocores.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-ocores.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/interrupt.h>
 #include <linux/wait.h>
 #include <linux/i2c-ocores.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 struct ocores_i2c {
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-octeon.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-octeon.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-octeon.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-octeon.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,652 @@
+/*
+ * (C) Copyright 2009-2010
+ * Nokia Siemens Networks, michael.lawnick.ext@nsn.com
+ *
+ * Portions Copyright (C) 2010 Cavium Networks, Inc.
+ *
+ * This is a driver for the i2c adapter in Cavium Networks' OCTEON processors.
+ *
+ * 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/sched.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#include <asm/octeon/octeon.h>
+
+#define DRV_NAME "i2c-octeon"
+
+/* The previous out-of-tree version was implicitly version 1.0. */
+#define DRV_VERSION	"2.0"
+
+/* register offsets */
+#define SW_TWSI	 0x00
+#define TWSI_INT 0x10
+
+/* Controller command patterns */
+#define SW_TWSI_V               0x8000000000000000ull
+#define SW_TWSI_EOP_TWSI_DATA   0x0C00000100000000ull
+#define SW_TWSI_EOP_TWSI_CTL    0x0C00000200000000ull
+#define SW_TWSI_EOP_TWSI_CLKCTL 0x0C00000300000000ull
+#define SW_TWSI_EOP_TWSI_STAT   0x0C00000300000000ull
+#define SW_TWSI_EOP_TWSI_RST    0x0C00000700000000ull
+#define SW_TWSI_OP_TWSI_CLK     0x0800000000000000ull
+#define SW_TWSI_R               0x0100000000000000ull
+
+/* Controller command and status bits */
+#define TWSI_CTL_CE   0x80
+#define TWSI_CTL_ENAB 0x40
+#define TWSI_CTL_STA  0x20
+#define TWSI_CTL_STP  0x10
+#define TWSI_CTL_IFLG 0x08
+#define TWSI_CTL_AAK  0x04
+
+/* Some status values */
+#define STAT_START      0x08
+#define STAT_RSTART     0x10
+#define STAT_TXADDR_ACK 0x18
+#define STAT_TXDATA_ACK 0x28
+#define STAT_RXADDR_ACK 0x40
+#define STAT_RXDATA_ACK 0x50
+#define STAT_IDLE       0xF8
+
+struct octeon_i2c {
+	wait_queue_head_t queue;
+	struct i2c_adapter adap;
+	int irq;
+	int twsi_freq;
+	int sys_freq;
+	resource_size_t twsi_phys;
+	void __iomem *twsi_base;
+	resource_size_t regsize;
+	struct device *dev;
+};
+
+/**
+ * octeon_i2c_write_sw - write an I2C core register.
+ * @i2c: The struct octeon_i2c.
+ * @eop_reg: Register selector.
+ * @data: Value to be written.
+ *
+ * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
+ */
+static void octeon_i2c_write_sw(struct octeon_i2c *i2c,
+				u64 eop_reg,
+				u8 data)
+{
+	u64 tmp;
+
+	__raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI);
+	do {
+		tmp = __raw_readq(i2c->twsi_base + SW_TWSI);
+	} while ((tmp & SW_TWSI_V) != 0);
+}
+
+/**
+ * octeon_i2c_read_sw - write an I2C core register.
+ * @i2c: The struct octeon_i2c.
+ * @eop_reg: Register selector.
+ *
+ * Returns the data.
+ *
+ * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
+ */
+static u8 octeon_i2c_read_sw(struct octeon_i2c *i2c, u64 eop_reg)
+{
+	u64 tmp;
+
+	__raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI);
+	do {
+		tmp = __raw_readq(i2c->twsi_base + SW_TWSI);
+	} while ((tmp & SW_TWSI_V) != 0);
+
+	return tmp & 0xFF;
+}
+
+/**
+ * octeon_i2c_write_int - write the TWSI_INT register
+ * @i2c: The struct octeon_i2c.
+ * @data: Value to be written.
+ */
+static void octeon_i2c_write_int(struct octeon_i2c *i2c, u64 data)
+{
+	u64 tmp;
+
+	__raw_writeq(data, i2c->twsi_base + TWSI_INT);
+	tmp = __raw_readq(i2c->twsi_base + TWSI_INT);
+}
+
+/**
+ * octeon_i2c_int_enable - enable the TS interrupt.
+ * @i2c: The struct octeon_i2c.
+ *
+ * The interrupt will be asserted when there is non-STAT_IDLE state in
+ * the SW_TWSI_EOP_TWSI_STAT register.
+ */
+static void octeon_i2c_int_enable(struct octeon_i2c *i2c)
+{
+	octeon_i2c_write_int(i2c, 0x40);
+}
+
+/**
+ * octeon_i2c_int_disable - disable the TS interrupt.
+ * @i2c: The struct octeon_i2c.
+ */
+static void octeon_i2c_int_disable(struct octeon_i2c *i2c)
+{
+	octeon_i2c_write_int(i2c, 0);
+}
+
+/**
+ * octeon_i2c_unblock - unblock the bus.
+ * @i2c: The struct octeon_i2c.
+ *
+ * If there was a reset while a device was driving 0 to bus,
+ * bus is blocked. We toggle it free manually by some clock
+ * cycles and send a stop.
+ */
+static void octeon_i2c_unblock(struct octeon_i2c *i2c)
+{
+	int i;
+
+	dev_dbg(i2c->dev, "%s\n", __func__);
+	for (i = 0; i < 9; i++) {
+		octeon_i2c_write_int(i2c, 0x0);
+		udelay(5);
+		octeon_i2c_write_int(i2c, 0x200);
+		udelay(5);
+	}
+	octeon_i2c_write_int(i2c, 0x300);
+	udelay(5);
+	octeon_i2c_write_int(i2c, 0x100);
+	udelay(5);
+	octeon_i2c_write_int(i2c, 0x0);
+}
+
+/**
+ * octeon_i2c_isr - the interrupt service routine.
+ * @int: The irq, unused.
+ * @dev_id: Our struct octeon_i2c.
+ */
+static irqreturn_t octeon_i2c_isr(int irq, void *dev_id)
+{
+	struct octeon_i2c *i2c = dev_id;
+
+	octeon_i2c_int_disable(i2c);
+	wake_up_interruptible(&i2c->queue);
+
+	return IRQ_HANDLED;
+}
+
+
+static int octeon_i2c_test_iflg(struct octeon_i2c *i2c)
+{
+	return (octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_CTL) & TWSI_CTL_IFLG) != 0;
+}
+
+/**
+ * octeon_i2c_wait - wait for the IFLG to be set.
+ * @i2c: The struct octeon_i2c.
+ *
+ * Returns 0 on success, otherwise a negative errno.
+ */
+static int octeon_i2c_wait(struct octeon_i2c *i2c)
+{
+	int result;
+
+	octeon_i2c_int_enable(i2c);
+
+	result = wait_event_interruptible_timeout(i2c->queue,
+						  octeon_i2c_test_iflg(i2c),
+						  i2c->adap.timeout);
+
+	octeon_i2c_int_disable(i2c);
+
+	if (result < 0) {
+		dev_dbg(i2c->dev, "%s: wait interrupted\n", __func__);
+		return result;
+	} else if (result == 0) {
+		dev_dbg(i2c->dev, "%s: timeout\n", __func__);
+		result = -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+/**
+ * octeon_i2c_start - send START to the bus.
+ * @i2c: The struct octeon_i2c.
+ *
+ * Returns 0 on success, otherwise a negative errno.
+ */
+static int octeon_i2c_start(struct octeon_i2c *i2c)
+{
+	u8 data;
+	int result;
+
+	octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL,
+				TWSI_CTL_ENAB | TWSI_CTL_STA);
+
+	result = octeon_i2c_wait(i2c);
+	if (result) {
+		if (octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT) == STAT_IDLE) {
+			/*
+			 * Controller refused to send start flag May
+			 * be a client is holding SDA low - let's try
+			 * to free it.
+			 */
+			octeon_i2c_unblock(i2c);
+			octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL,
+					    TWSI_CTL_ENAB | TWSI_CTL_STA);
+
+			result = octeon_i2c_wait(i2c);
+		}
+		if (result)
+			return result;
+	}
+
+	data = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT);
+	if ((data != STAT_START) && (data != STAT_RSTART)) {
+		dev_err(i2c->dev, "%s: bad status (0x%x)\n", __func__, data);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
+ * octeon_i2c_stop - send STOP to the bus.
+ * @i2c: The struct octeon_i2c.
+ *
+ * Returns 0 on success, otherwise a negative errno.
+ */
+static int octeon_i2c_stop(struct octeon_i2c *i2c)
+{
+	u8 data;
+
+	octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL,
+			    TWSI_CTL_ENAB | TWSI_CTL_STP);
+
+	data = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT);
+
+	if (data != STAT_IDLE) {
+		dev_err(i2c->dev, "%s: bad status(0x%x)\n", __func__, data);
+		return -EIO;
+	}
+	return 0;
+}
+
+/**
+ * octeon_i2c_write - send data to the bus.
+ * @i2c: The struct octeon_i2c.
+ * @target: Target address.
+ * @data: Pointer to the data to be sent.
+ * @length: Length of the data.
+ *
+ * The address is sent over the bus, then the data.
+ *
+ * Returns 0 on success, otherwise a negative errno.
+ */
+static int octeon_i2c_write(struct octeon_i2c *i2c, int target,
+			    const u8 *data, int length)
+{
+	int i, result;
+	u8 tmp;
+
+	result = octeon_i2c_start(i2c);
+	if (result)
+		return result;
+
+	octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_DATA, target << 1);
+	octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB);
+
+	result = octeon_i2c_wait(i2c);
+	if (result)
+		return result;
+
+	for (i = 0; i < length; i++) {
+		tmp = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT);
+		if ((tmp != STAT_TXADDR_ACK) && (tmp != STAT_TXDATA_ACK)) {
+			dev_err(i2c->dev,
+				"%s: bad status before write (0x%x)\n",
+				__func__, tmp);
+			return -EIO;
+		}
+
+		octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_DATA, data[i]);
+		octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB);
+
+		result = octeon_i2c_wait(i2c);
+		if (result)
+			return result;
+	}
+
+	return 0;
+}
+
+/**
+ * octeon_i2c_read - receive data from the bus.
+ * @i2c: The struct octeon_i2c.
+ * @target: Target address.
+ * @data: Pointer to the location to store the datae .
+ * @length: Length of the data.
+ *
+ * The address is sent over the bus, then the data is read.
+ *
+ * Returns 0 on success, otherwise a negative errno.
+ */
+static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
+			   u8 *data, int length)
+{
+	int i, result;
+	u8 tmp;
+
+	if (length < 1)
+		return -EINVAL;
+
+	result = octeon_i2c_start(i2c);
+	if (result)
+		return result;
+
+	octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_DATA, (target<<1) | 1);
+	octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB);
+
+	result = octeon_i2c_wait(i2c);
+	if (result)
+		return result;
+
+	for (i = 0; i < length; i++) {
+		tmp = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT);
+		if ((tmp != STAT_RXDATA_ACK) && (tmp != STAT_RXADDR_ACK)) {
+			dev_err(i2c->dev,
+				"%s: bad status before read (0x%x)\n",
+				__func__, tmp);
+			return -EIO;
+		}
+
+		if (i+1 < length)
+			octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL,
+						TWSI_CTL_ENAB | TWSI_CTL_AAK);
+		else
+			octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL,
+						TWSI_CTL_ENAB);
+
+		result = octeon_i2c_wait(i2c);
+		if (result)
+			return result;
+
+		data[i] = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_DATA);
+	}
+	return 0;
+}
+
+/**
+ * octeon_i2c_xfer - The driver's master_xfer function.
+ * @adap: Pointer to the i2c_adapter structure.
+ * @msgs: Pointer to the messages to be processed.
+ * @num: Length of the MSGS array.
+ *
+ * Returns the number of messages processed, or a negative errno on
+ * failure.
+ */
+static int octeon_i2c_xfer(struct i2c_adapter *adap,
+			   struct i2c_msg *msgs,
+			   int num)
+{
+	struct i2c_msg *pmsg;
+	int i;
+	int ret = 0;
+	struct octeon_i2c *i2c = i2c_get_adapdata(adap);
+
+	for (i = 0; ret == 0 && i < num; i++) {
+		pmsg = &msgs[i];
+		dev_dbg(i2c->dev,
+			"Doing %s %d byte(s) to/from 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 = octeon_i2c_read(i2c, pmsg->addr, pmsg->buf,
+						pmsg->len);
+		else
+			ret = octeon_i2c_write(i2c, pmsg->addr, pmsg->buf,
+						pmsg->len);
+	}
+	octeon_i2c_stop(i2c);
+
+	return (ret != 0) ? ret : num;
+}
+
+static u32 octeon_i2c_functionality(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm octeon_i2c_algo = {
+	.master_xfer = octeon_i2c_xfer,
+	.functionality = octeon_i2c_functionality,
+};
+
+static struct i2c_adapter octeon_i2c_ops = {
+	.owner = THIS_MODULE,
+	.name = "OCTEON adapter",
+	.algo = &octeon_i2c_algo,
+	.timeout = 2,
+};
+
+/**
+ * octeon_i2c_setclock - Calculate and set clock divisors.
+ */
+static int __devinit octeon_i2c_setclock(struct octeon_i2c *i2c)
+{
+	int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff;
+	int thp = 0x18, mdiv = 2, ndiv = 0, delta_hz = 1000000;
+
+	for (ndiv_idx = 0; ndiv_idx < 8 && delta_hz != 0; ndiv_idx++) {
+		/*
+		 * An mdiv value of less than 2 seems to not work well
+		 * with ds1337 RTCs, so we constrain it to larger
+		 * values.
+		 */
+		for (mdiv_idx = 15; mdiv_idx >= 2 && delta_hz != 0; mdiv_idx--) {
+			/*
+			 * For given ndiv and mdiv values check the
+			 * two closest thp values.
+			 */
+			tclk = i2c->twsi_freq * (mdiv_idx + 1) * 10;
+			tclk *= (1 << ndiv_idx);
+			thp_base = (i2c->sys_freq / (tclk * 2)) - 1;
+			for (inc = 0; inc <= 1; inc++) {
+				thp_idx = thp_base + inc;
+				if (thp_idx < 5 || thp_idx > 0xff)
+					continue;
+
+				foscl = i2c->sys_freq / (2 * (thp_idx + 1));
+				foscl = foscl / (1 << ndiv_idx);
+				foscl = foscl / (mdiv_idx + 1) / 10;
+				diff = abs(foscl - i2c->twsi_freq);
+				if (diff < delta_hz) {
+					delta_hz = diff;
+					thp = thp_idx;
+					mdiv = mdiv_idx;
+					ndiv = ndiv_idx;
+				}
+			}
+		}
+	}
+	octeon_i2c_write_sw(i2c, SW_TWSI_OP_TWSI_CLK, thp);
+	octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CLKCTL, (mdiv << 3) | ndiv);
+
+	return 0;
+}
+
+static int __devinit octeon_i2c_initlowlevel(struct octeon_i2c *i2c)
+{
+	u8 status;
+	int tries;
+
+	/* disable high level controller, enable bus access */
+	octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB);
+
+	/* reset controller */
+	octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_RST, 0);
+
+	for (tries = 10; tries; tries--) {
+		udelay(1);
+		status = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT);
+		if (status == STAT_IDLE)
+			return 0;
+	}
+	dev_err(i2c->dev, "%s: TWSI_RST failed! (0x%x)\n", __func__, status);
+	return -EIO;
+}
+
+static int __devinit octeon_i2c_probe(struct platform_device *pdev)
+{
+	int irq, result = 0;
+	struct octeon_i2c *i2c;
+	struct octeon_i2c_data *i2c_data;
+	struct resource *res_mem;
+
+	/* All adaptors have an irq.  */
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
+	if (!i2c) {
+		dev_err(&pdev->dev, "kzalloc failed\n");
+		result = -ENOMEM;
+		goto out;
+	}
+	i2c->dev = &pdev->dev;
+	i2c_data = pdev->dev.platform_data;
+
+	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (res_mem == NULL) {
+		dev_err(i2c->dev, "found no memory resource\n");
+		result = -ENXIO;
+		goto fail_region;
+	}
+
+	if (i2c_data == NULL) {
+		dev_err(i2c->dev, "no I2C frequency data\n");
+		result = -ENXIO;
+		goto fail_region;
+	}
+
+	i2c->twsi_phys = res_mem->start;
+	i2c->regsize = resource_size(res_mem);
+	i2c->twsi_freq = i2c_data->i2c_freq;
+	i2c->sys_freq = i2c_data->sys_freq;
+
+	if (!request_mem_region(i2c->twsi_phys, i2c->regsize, res_mem->name)) {
+		dev_err(i2c->dev, "request_mem_region failed\n");
+		goto fail_region;
+	}
+	i2c->twsi_base = ioremap(i2c->twsi_phys, i2c->regsize);
+
+	init_waitqueue_head(&i2c->queue);
+
+	i2c->irq = irq;
+
+	result = request_irq(i2c->irq, octeon_i2c_isr, 0, DRV_NAME, i2c);
+	if (result < 0) {
+		dev_err(i2c->dev, "failed to attach interrupt\n");
+		goto fail_irq;
+	}
+
+	result = octeon_i2c_initlowlevel(i2c);
+	if (result) {
+		dev_err(i2c->dev, "init low level failed\n");
+		goto  fail_add;
+	}
+
+	result = octeon_i2c_setclock(i2c);
+	if (result) {
+		dev_err(i2c->dev, "clock init failed\n");
+		goto  fail_add;
+	}
+
+	i2c->adap = octeon_i2c_ops;
+	i2c->adap.dev.parent = &pdev->dev;
+	i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0;
+	i2c_set_adapdata(&i2c->adap, i2c);
+	platform_set_drvdata(pdev, i2c);
+
+	result = i2c_add_numbered_adapter(&i2c->adap);
+	if (result < 0) {
+		dev_err(i2c->dev, "failed to add adapter\n");
+		goto fail_add;
+	}
+
+	dev_info(i2c->dev, "version %s\n", DRV_VERSION);
+
+	return result;
+
+fail_add:
+	platform_set_drvdata(pdev, NULL);
+	free_irq(i2c->irq, i2c);
+fail_irq:
+	iounmap(i2c->twsi_base);
+	release_mem_region(i2c->twsi_phys, i2c->regsize);
+fail_region:
+	kfree(i2c);
+out:
+	return result;
+};
+
+static int __devexit octeon_i2c_remove(struct platform_device *pdev)
+{
+	struct octeon_i2c *i2c = platform_get_drvdata(pdev);
+
+	i2c_del_adapter(&i2c->adap);
+	platform_set_drvdata(pdev, NULL);
+	free_irq(i2c->irq, i2c);
+	iounmap(i2c->twsi_base);
+	release_mem_region(i2c->twsi_phys, i2c->regsize);
+	kfree(i2c);
+	return 0;
+};
+
+static struct platform_driver octeon_i2c_driver = {
+	.probe		= octeon_i2c_probe,
+	.remove		= __devexit_p(octeon_i2c_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= DRV_NAME,
+	},
+};
+
+static int __init octeon_i2c_init(void)
+{
+	int rv;
+
+	rv = platform_driver_register(&octeon_i2c_driver);
+	return rv;
+}
+
+static void __exit octeon_i2c_exit(void)
+{
+	platform_driver_unregister(&octeon_i2c_driver);
+}
+
+MODULE_AUTHOR("Michael Lawnick <michael.lawnick.ext@nsn.com>");
+MODULE_DESCRIPTION("I2C-Bus adapter for Cavium OCTEON processors");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+MODULE_ALIAS("platform:" DRV_NAME);
+
+module_init(octeon_i2c_init);
+module_exit(octeon_i2c_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-omap.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-omap.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-omap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-omap.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 /* I2C controller revisions */
 #define OMAP_I2C_REV_2			0x20
@@ -49,24 +50,24 @@
 #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
 
 #define OMAP_I2C_REV_REG		0x00
-#define OMAP_I2C_IE_REG			0x04
-#define OMAP_I2C_STAT_REG		0x08
-#define OMAP_I2C_IV_REG			0x0c
+#define OMAP_I2C_IE_REG			0x01
+#define OMAP_I2C_STAT_REG		0x02
+#define OMAP_I2C_IV_REG			0x03
 /* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */
-#define OMAP_I2C_WE_REG			0x0c
-#define OMAP_I2C_SYSS_REG		0x10
-#define OMAP_I2C_BUF_REG		0x14
-#define OMAP_I2C_CNT_REG		0x18
-#define OMAP_I2C_DATA_REG		0x1c
-#define OMAP_I2C_SYSC_REG		0x20
-#define OMAP_I2C_CON_REG		0x24
-#define OMAP_I2C_OA_REG			0x28
-#define OMAP_I2C_SA_REG			0x2c
-#define OMAP_I2C_PSC_REG		0x30
-#define OMAP_I2C_SCLL_REG		0x34
-#define OMAP_I2C_SCLH_REG		0x38
-#define OMAP_I2C_SYSTEST_REG		0x3c
-#define OMAP_I2C_BUFSTAT_REG		0x40
+#define OMAP_I2C_WE_REG			0x03
+#define OMAP_I2C_SYSS_REG		0x04
+#define OMAP_I2C_BUF_REG		0x05
+#define OMAP_I2C_CNT_REG		0x06
+#define OMAP_I2C_DATA_REG		0x07
+#define OMAP_I2C_SYSC_REG		0x08
+#define OMAP_I2C_CON_REG		0x09
+#define OMAP_I2C_OA_REG			0x0a
+#define OMAP_I2C_SA_REG			0x0b
+#define OMAP_I2C_PSC_REG		0x0c
+#define OMAP_I2C_SCLL_REG		0x0d
+#define OMAP_I2C_SCLH_REG		0x0e
+#define OMAP_I2C_SYSTEST_REG		0x0f
+#define OMAP_I2C_BUFSTAT_REG		0x10
 
 /* I2C Interrupt Enable Register (OMAP_I2C_IE): */
 #define OMAP_I2C_IE_XDR		(1 << 14)	/* TX Buffer drain int enable */
@@ -161,6 +162,7 @@ struct omap_i2c_dev {
 	struct device		*dev;
 	void __iomem		*base;		/* virtual */
 	int			irq;
+	int			reg_shift;      /* bit shift for I2C register addresses */
 	struct clk		*iclk;		/* Interface clock */
 	struct clk		*fclk;		/* Functional clock */
 	struct completion	cmd_complete;
@@ -189,12 +191,12 @@ struct omap_i2c_dev {
 static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
 				      int reg, u16 val)
 {
-	__raw_writew(val, i2c_dev->base + reg);
+	__raw_writew(val, i2c_dev->base + (reg << i2c_dev->reg_shift));
 }
 
 static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
 {
-	return __raw_readw(i2c_dev->base + reg);
+	return __raw_readw(i2c_dev->base + (reg << i2c_dev->reg_shift));
 }
 
 static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev)
@@ -849,7 +851,7 @@ static const struct i2c_algorithm omap_i
 	.functionality	= omap_i2c_func,
 };
 
-static int __init
+static int __devinit
 omap_i2c_probe(struct platform_device *pdev)
 {
 	struct omap_i2c_dev	*dev;
@@ -901,6 +903,11 @@ omap_i2c_probe(struct platform_device *p
 
 	platform_set_drvdata(pdev, dev);
 
+	if (cpu_is_omap7xx())
+		dev->reg_shift = 1;
+	else
+		dev->reg_shift = 2;
+
 	if ((r = omap_i2c_get_clocks(dev)) != 0)
 		goto err_iounmap;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-parport.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-parport.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-parport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-parport.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /* ------------------------------------------------------------------------ *
  * i2c-parport.c I2C bus over parallel port                                 *
  * ------------------------------------------------------------------------ *
-   Copyright (C) 2003-2007 Jean Delvare <khali@linux-fr.org>
+   Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org>
    
    Based on older i2c-philips-par.c driver
    Copyright (C) 1995-2000 Simon G. Vogl
@@ -27,9 +27,12 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 #include <linux/parport.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
+#include <linux/i2c-smbus.h>
+#include <linux/slab.h>
 #include "i2c-parport.h"
 
 /* ----- Device list ------------------------------------------------------ */
@@ -38,6 +41,8 @@ struct i2c_par {
 	struct pardevice *pdev;
 	struct i2c_adapter adapter;
 	struct i2c_algo_bit_data algo_data;
+	struct i2c_smbus_alert_setup alert_data;
+	struct i2c_client *ara;
 	struct i2c_par *next;
 };
 
@@ -143,6 +148,19 @@ static struct i2c_algo_bit_data parport_
 
 /* ----- I2c and parallel port call-back functions and structures --------- */
 
+void i2c_parport_irq(void *data)
+{
+	struct i2c_par *adapter = data;
+	struct i2c_client *ara = adapter->ara;
+
+	if (ara) {
+		dev_dbg(&ara->dev, "SMBus alert received\n");
+		i2c_handle_smbus_alert(ara);
+	} else
+		dev_dbg(&adapter->adapter.dev,
+			"SMBus alert received but no ARA client!\n");
+}
+
 static void i2c_parport_attach (struct parport *port)
 {
 	struct i2c_par *adapter;
@@ -154,8 +172,9 @@ static void i2c_parport_attach (struct p
 	}
 
 	pr_debug("i2c-parport: attaching to %s\n", port->name);
+	parport_disable_irq(port);
 	adapter->pdev = parport_register_device(port, "i2c-parport",
-		NULL, NULL, NULL, PARPORT_FLAG_EXCL, NULL);
+		NULL, NULL, i2c_parport_irq, PARPORT_FLAG_EXCL, adapter);
 	if (!adapter->pdev) {
 		printk(KERN_ERR "i2c-parport: Unable to register with parport\n");
 		goto ERROR0;
@@ -185,14 +204,29 @@ static void i2c_parport_attach (struct p
 	parport_setsda(port, 1);
 	parport_setscl(port, 1);
 	/* Other init if needed (power on...) */
-	if (adapter_parm[type].init.val)
+	if (adapter_parm[type].init.val) {
 		line_set(port, 1, &adapter_parm[type].init);
+		/* Give powered devices some time to settle */
+		msleep(100);
+	}
 
 	if (i2c_bit_add_bus(&adapter->adapter) < 0) {
 		printk(KERN_ERR "i2c-parport: Unable to register with I2C\n");
 		goto ERROR1;
 	}
 
+	/* Setup SMBus alert if supported */
+	if (adapter_parm[type].smbus_alert) {
+		adapter->alert_data.alert_edge_triggered = 1;
+		adapter->ara = i2c_setup_smbus_alert(&adapter->adapter,
+						     &adapter->alert_data);
+		if (adapter->ara)
+			parport_enable_irq(port);
+		else
+			printk(KERN_WARNING "i2c-parport: Failed to register "
+			       "ARA client\n");
+	}
+
 	/* Add the new adapter to the list */
 	adapter->next = adapter_list;
 	adapter_list = adapter;
@@ -213,6 +247,10 @@ static void i2c_parport_detach (struct p
 	for (prev = NULL, adapter = adapter_list; adapter;
 	     prev = adapter, adapter = adapter->next) {
 		if (adapter->pdev->port == port) {
+			if (adapter->ara) {
+				parport_disable_irq(port);
+				i2c_unregister_device(adapter->ara);
+			}
 			i2c_del_adapter(&adapter->adapter);
 
 			/* Un-init if needed (power off...) */
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-parport.h linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-parport.h
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-parport.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-parport.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /* ------------------------------------------------------------------------ *
  * i2c-parport.h I2C bus over parallel port                                 *
  * ------------------------------------------------------------------------ *
-   Copyright (C) 2003-2004 Jean Delvare <khali@linux-fr.org>
+   Copyright (C) 2003-2010 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
@@ -38,6 +38,7 @@ struct adapter_parm {
 	struct lineop getsda;
 	struct lineop getscl;
 	struct lineop init;
+	unsigned int smbus_alert:1;
 };
 
 static struct adapter_parm adapter_parm[] = {
@@ -73,6 +74,7 @@ static struct adapter_parm adapter_parm[
 		.setscl	= { 0x01, DATA, 1 },
 		.getsda	= { 0x10, STAT, 1 },
 		.init	= { 0xf0, DATA, 0 },
+		.smbus_alert = 1,
 	},
 	/* type 5: ADM1025, ADM1030 and ADM1031 evaluation boards */
 	{
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-parport-light.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-parport-light.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-parport-light.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-parport-light.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /* ------------------------------------------------------------------------ *
  * i2c-parport-light.c I2C bus over parallel port                           *
  * ------------------------------------------------------------------------ *
-   Copyright (C) 2003-2007 Jean Delvare <khali@linux-fr.org>
+   Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org>
    
    Based on older i2c-velleman.c driver
    Copyright (C) 1995-2000 Simon G. Vogl
@@ -27,10 +27,12 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/ioport.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
+#include <linux/i2c-smbus.h>
 #include <asm/io.h>
 #include "i2c-parport.h"
 
@@ -43,6 +45,10 @@ static u16 base;
 module_param(base, ushort, 0);
 MODULE_PARM_DESC(base, "Base I/O address");
 
+static int irq;
+module_param(irq, int, 0);
+MODULE_PARM_DESC(irq, "IRQ (optional)");
+
 /* ----- Low-level parallel port access ----------------------------------- */
 
 static inline void port_write(unsigned char p, unsigned char d)
@@ -119,6 +125,16 @@ static struct i2c_adapter parport_adapte
 	.name		= "Parallel port adapter (light)",
 };
 
+/* SMBus alert support */
+static struct i2c_smbus_alert_setup alert_data = {
+	.alert_edge_triggered	= 1,
+};
+static struct i2c_client *ara;
+static struct lineop parport_ctrl_irq = {
+	.val		= (1 << 4),
+	.port		= CTRL,
+};
+
 static int __devinit i2c_parport_probe(struct platform_device *pdev)
 {
 	int err;
@@ -127,18 +143,39 @@ static int __devinit i2c_parport_probe(s
 	parport_setsda(NULL, 1);
 	parport_setscl(NULL, 1);
 	/* Other init if needed (power on...) */
-	if (adapter_parm[type].init.val)
+	if (adapter_parm[type].init.val) {
 		line_set(1, &adapter_parm[type].init);
+		/* Give powered devices some time to settle */
+		msleep(100);
+	}
 
 	parport_adapter.dev.parent = &pdev->dev;
 	err = i2c_bit_add_bus(&parport_adapter);
-	if (err)
+	if (err) {
 		dev_err(&pdev->dev, "Unable to register with I2C\n");
-	return err;
+		return err;
+	}
+
+	/* Setup SMBus alert if supported */
+	if (adapter_parm[type].smbus_alert && irq) {
+		alert_data.irq = irq;
+		ara = i2c_setup_smbus_alert(&parport_adapter, &alert_data);
+		if (ara)
+			line_set(1, &parport_ctrl_irq);
+		else
+			dev_warn(&pdev->dev, "Failed to register ARA client\n");
+	}
+
+	return 0;
 }
 
 static int __devexit i2c_parport_remove(struct platform_device *pdev)
 {
+	if (ara) {
+		line_set(0, &parport_ctrl_irq);
+		i2c_unregister_device(ara);
+		ara = NULL;
+	}
 	i2c_del_adapter(&parport_adapter);
 
 	/* Un-init if needed (power off...) */
@@ -205,6 +242,9 @@ static int __init i2c_parport_init(void)
 	if (!request_region(base, 3, DRVNAME))
 		return -EBUSY;
 
+	if (irq != 0)
+		pr_info(DRVNAME ": using irq %d\n", irq);
+
         if (!adapter_parm[type].getscl.val)
 		parport_algo_data.getscl = NULL;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-pasemi.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-pasemi.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-pasemi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-pasemi.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/sched.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 static struct pci_driver pasemi_smb_driver;
@@ -400,7 +401,7 @@ static void __devexit pasemi_smb_remove(
 	kfree(smbus);
 }
 
-static struct pci_device_id pasemi_smb_ids[] = {
+static const struct pci_device_id pasemi_smb_ids[] = {
 	{ PCI_DEVICE(0x1959, 0xa003) },
 	{ 0, }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-piix4.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-piix4.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-piix4.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-piix4.c	2010-05-16 17:17:36.000000000 -0400
@@ -472,7 +472,7 @@ static struct i2c_adapter piix4_adapter
 	.algo		= &smbus_algorithm,
 };
 
-static struct pci_device_id piix4_ids[] = {
+static const struct pci_device_id piix4_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3) },
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-pnx.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-pnx.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-pnx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-pnx.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,15 +20,16 @@
 #include <linux/platform_device.h>
 #include <linux/i2c-pnx.h>
 #include <linux/io.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+
 #include <mach/hardware.h>
 #include <mach/i2c.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
 
 #define I2C_PNX_TIMEOUT		10 /* msec */
 #define I2C_PNX_SPEED_KHZ	100
 #define I2C_PNX_REGION_SIZE	0x100
-#define PNX_DEFAULT_FREQ	13 /* MHz */
 
 static inline int wait_timeout(long timeout, struct i2c_pnx_algo_data *data)
 {
@@ -50,22 +51,21 @@ static inline int wait_reset(long timeou
 	return (timeout <= 0);
 }
 
-static inline void i2c_pnx_arm_timer(struct i2c_adapter *adap)
+static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data)
 {
-	struct i2c_pnx_algo_data *data = adap->algo_data;
-	struct timer_list *timer = &data->mif.timer;
-	int expires = I2C_PNX_TIMEOUT / (1000 / HZ);
+	struct timer_list *timer = &alg_data->mif.timer;
+	unsigned long expires = msecs_to_jiffies(I2C_PNX_TIMEOUT);
 
 	if (expires <= 1)
 		expires = 2;
 
 	del_timer_sync(timer);
 
-	dev_dbg(&adap->dev, "Timer armed at %lu plus %u jiffies.\n",
+	dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %lu jiffies.\n",
 		jiffies, expires);
 
 	timer->expires = jiffies + expires;
-	timer->data = (unsigned long)adap;
+	timer->data = (unsigned long)&alg_data;
 
 	add_timer(timer);
 }
@@ -77,34 +77,34 @@ static inline void i2c_pnx_arm_timer(str
  *
  * Generate a START signal in the desired mode.
  */
-static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap)
+static int i2c_pnx_start(unsigned char slave_addr,
+	struct i2c_pnx_algo_data *alg_data)
 {
-	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
-
-	dev_dbg(&adap->dev, "%s(): addr 0x%x mode %d\n", __func__,
+	dev_dbg(&alg_data->adapter.dev, "%s(): addr 0x%x mode %d\n", __func__,
 		slave_addr, alg_data->mif.mode);
 
 	/* Check for 7 bit slave addresses only */
 	if (slave_addr & ~0x7f) {
-		dev_err(&adap->dev, "%s: Invalid slave address %x. "
-		       "Only 7-bit addresses are supported\n",
-		       adap->name, slave_addr);
+		dev_err(&alg_data->adapter.dev,
+			"%s: Invalid slave address %x. Only 7-bit addresses are supported\n",
+			alg_data->adapter.name, slave_addr);
 		return -EINVAL;
 	}
 
 	/* First, make sure bus is idle */
 	if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) {
 		/* Somebody else is monopolizing the bus */
-		dev_err(&adap->dev, "%s: Bus busy. Slave addr = %02x, "
-		       "cntrl = %x, stat = %x\n",
-		       adap->name, slave_addr,
-		       ioread32(I2C_REG_CTL(alg_data)),
-		       ioread32(I2C_REG_STS(alg_data)));
+		dev_err(&alg_data->adapter.dev,
+			"%s: Bus busy. Slave addr = %02x, cntrl = %x, stat = %x\n",
+			alg_data->adapter.name, slave_addr,
+			ioread32(I2C_REG_CTL(alg_data)),
+			ioread32(I2C_REG_STS(alg_data)));
 		return -EBUSY;
 	} else if (ioread32(I2C_REG_STS(alg_data)) & mstatus_afi) {
 		/* Sorry, we lost the bus */
-		dev_err(&adap->dev, "%s: Arbitration failure. "
-		       "Slave addr = %02x\n", adap->name, slave_addr);
+		dev_err(&alg_data->adapter.dev,
+		        "%s: Arbitration failure. Slave addr = %02x\n",
+			alg_data->adapter.name, slave_addr);
 		return -EIO;
 	}
 
@@ -115,14 +115,14 @@ static int i2c_pnx_start(unsigned char s
 	iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi,
 		  I2C_REG_STS(alg_data));
 
-	dev_dbg(&adap->dev, "%s(): sending %#x\n", __func__,
+	dev_dbg(&alg_data->adapter.dev, "%s(): sending %#x\n", __func__,
 		(slave_addr << 1) | start_bit | alg_data->mif.mode);
 
 	/* Write the slave address, START bit and R/W bit */
 	iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode,
 		  I2C_REG_TX(alg_data));
 
-	dev_dbg(&adap->dev, "%s(): exit\n", __func__);
+	dev_dbg(&alg_data->adapter.dev, "%s(): exit\n", __func__);
 
 	return 0;
 }
@@ -133,13 +133,12 @@ static int i2c_pnx_start(unsigned char s
  *
  * Generate a STOP signal to terminate the master transaction.
  */
-static void i2c_pnx_stop(struct i2c_adapter *adap)
+static void i2c_pnx_stop(struct i2c_pnx_algo_data *alg_data)
 {
-	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
 	/* Only 1 msec max timeout due to interrupt context */
 	long timeout = 1000;
 
-	dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
+	dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
 		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 	/* Write a STOP bit to TX FIFO */
@@ -153,7 +152,7 @@ static void i2c_pnx_stop(struct i2c_adap
 		timeout--;
 	}
 
-	dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
+	dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
 		__func__, ioread32(I2C_REG_STS(alg_data)));
 }
 
@@ -163,36 +162,32 @@ static void i2c_pnx_stop(struct i2c_adap
  *
  * Sends one byte of data to the slave
  */
-static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
+static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
 {
-	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
 	u32 val;
 
-	dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
+	dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
 		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 	if (alg_data->mif.len > 0) {
 		/* We still have something to talk about... */
 		val = *alg_data->mif.buf++;
 
-		if (alg_data->mif.len == 1) {
+		if (alg_data->mif.len == 1)
 			val |= stop_bit;
-			if (!alg_data->last)
-				val |= start_bit;
-		}
 
 		alg_data->mif.len--;
 		iowrite32(val, I2C_REG_TX(alg_data));
 
-		dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __func__,
-			val, alg_data->mif.len + 1);
+		dev_dbg(&alg_data->adapter.dev, "%s(): xmit %#x [%d]\n",
+			__func__, val, alg_data->mif.len + 1);
 
 		if (alg_data->mif.len == 0) {
 			if (alg_data->last) {
 				/* Wait until the STOP is seen. */
 				if (wait_timeout(I2C_PNX_TIMEOUT, alg_data))
-					dev_err(&adap->dev, "The bus is still "
-						"active after timeout\n");
+					dev_err(&alg_data->adapter.dev,
+						"The bus is still active after timeout\n");
 			}
 			/* Disable master interrupts */
 			iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
@@ -201,14 +196,15 @@ static int i2c_pnx_master_xmit(struct i2
 
 			del_timer_sync(&alg_data->mif.timer);
 
-			dev_dbg(&adap->dev, "%s(): Waking up xfer routine.\n",
+			dev_dbg(&alg_data->adapter.dev,
+				"%s(): Waking up xfer routine.\n",
 				__func__);
 
 			complete(&alg_data->mif.complete);
 		}
 	} else if (alg_data->mif.len == 0) {
 		/* zero-sized transfer */
-		i2c_pnx_stop(adap);
+		i2c_pnx_stop(alg_data);
 
 		/* Disable master interrupts. */
 		iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
@@ -217,13 +213,14 @@ static int i2c_pnx_master_xmit(struct i2
 
 		/* Stop timer. */
 		del_timer_sync(&alg_data->mif.timer);
-		dev_dbg(&adap->dev, "%s(): Waking up xfer routine after "
-			"zero-xfer.\n", __func__);
+		dev_dbg(&alg_data->adapter.dev,
+			"%s(): Waking up xfer routine after zero-xfer.\n",
+			__func__);
 
 		complete(&alg_data->mif.complete);
 	}
 
-	dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
+	dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
 		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 	return 0;
@@ -235,27 +232,25 @@ static int i2c_pnx_master_xmit(struct i2
  *
  * Reads one byte data from the slave
  */
-static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
+static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
 {
-	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
 	unsigned int val = 0;
 	u32 ctl = 0;
 
-	dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
+	dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
 		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 	/* Check, whether there is already data,
 	 * or we didn't 'ask' for it yet.
 	 */
 	if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) {
-		dev_dbg(&adap->dev, "%s(): Write dummy data to fill "
-			"Rx-fifo...\n", __func__);
+		dev_dbg(&alg_data->adapter.dev,
+			"%s(): Write dummy data to fill Rx-fifo...\n",
+			__func__);
 
 		if (alg_data->mif.len == 1) {
 			/* Last byte, do not acknowledge next rcv. */
 			val |= stop_bit;
-			if (!alg_data->last)
-				val |= start_bit;
 
 			/*
 			 * Enable interrupt RFDAIE (data in Rx fifo),
@@ -281,16 +276,16 @@ static int i2c_pnx_master_rcv(struct i2c
 	if (alg_data->mif.len > 0) {
 		val = ioread32(I2C_REG_RX(alg_data));
 		*alg_data->mif.buf++ = (u8) (val & 0xff);
-		dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __func__, val,
-			alg_data->mif.len);
+		dev_dbg(&alg_data->adapter.dev, "%s(): rcv 0x%x [%d]\n",
+			__func__, val, alg_data->mif.len);
 
 		alg_data->mif.len--;
 		if (alg_data->mif.len == 0) {
 			if (alg_data->last)
 				/* Wait until the STOP is seen. */
 				if (wait_timeout(I2C_PNX_TIMEOUT, alg_data))
-					dev_err(&adap->dev, "The bus is still "
-						"active after timeout\n");
+					dev_err(&alg_data->adapter.dev,
+						"The bus is still active after timeout\n");
 
 			/* Disable master interrupts */
 			ctl = ioread32(I2C_REG_CTL(alg_data));
@@ -304,7 +299,7 @@ static int i2c_pnx_master_rcv(struct i2c
 		}
 	}
 
-	dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
+	dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
 		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 	return 0;
@@ -312,11 +307,11 @@ static int i2c_pnx_master_rcv(struct i2c
 
 static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
 {
+	struct i2c_pnx_algo_data *alg_data = dev_id;
 	u32 stat, ctl;
-	struct i2c_adapter *adap = dev_id;
-	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
 
-	dev_dbg(&adap->dev, "%s(): mstat = %x mctrl = %x, mode = %d\n",
+	dev_dbg(&alg_data->adapter.dev,
+		"%s(): mstat = %x mctrl = %x, mode = %d\n",
 		__func__,
 		ioread32(I2C_REG_STS(alg_data)),
 		ioread32(I2C_REG_CTL(alg_data)),
@@ -339,10 +334,10 @@ static irqreturn_t i2c_pnx_interrupt(int
 		complete(&alg_data->mif.complete);
 	} else if (stat & mstatus_nai) {
 		/* Slave did not acknowledge, generate a STOP */
-		dev_dbg(&adap->dev, "%s(): "
-			"Slave did not acknowledge, generating a STOP.\n",
+		dev_dbg(&alg_data->adapter.dev,
+			"%s(): Slave did not acknowledge, generating a STOP.\n",
 			__func__);
-		i2c_pnx_stop(adap);
+		i2c_pnx_stop(alg_data);
 
 		/* Disable master interrupts. */
 		ctl = ioread32(I2C_REG_CTL(alg_data));
@@ -368,9 +363,9 @@ static irqreturn_t i2c_pnx_interrupt(int
 		 */
 		if ((stat & mstatus_drmi) || !(stat & mstatus_rfe)) {
 			if (alg_data->mif.mode == I2C_SMBUS_WRITE) {
-				i2c_pnx_master_xmit(adap);
+				i2c_pnx_master_xmit(alg_data);
 			} else if (alg_data->mif.mode == I2C_SMBUS_READ) {
-				i2c_pnx_master_rcv(adap);
+				i2c_pnx_master_rcv(alg_data);
 			}
 		}
 	}
@@ -379,7 +374,8 @@ static irqreturn_t i2c_pnx_interrupt(int
 	stat = ioread32(I2C_REG_STS(alg_data));
 	iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data));
 
-	dev_dbg(&adap->dev, "%s(): exiting, stat = %x ctrl = %x.\n",
+	dev_dbg(&alg_data->adapter.dev,
+		"%s(): exiting, stat = %x ctrl = %x.\n",
 		 __func__, ioread32(I2C_REG_STS(alg_data)),
 		 ioread32(I2C_REG_CTL(alg_data)));
 
@@ -388,14 +384,13 @@ static irqreturn_t i2c_pnx_interrupt(int
 
 static void i2c_pnx_timeout(unsigned long data)
 {
-	struct i2c_adapter *adap = (struct i2c_adapter *)data;
-	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+	struct i2c_pnx_algo_data *alg_data = (struct i2c_pnx_algo_data *)data;
 	u32 ctl;
 
-	dev_err(&adap->dev, "Master timed out. stat = %04x, cntrl = %04x. "
-	       "Resetting master...\n",
-	       ioread32(I2C_REG_STS(alg_data)),
-	       ioread32(I2C_REG_CTL(alg_data)));
+	dev_err(&alg_data->adapter.dev,
+		"Master timed out. stat = %04x, cntrl = %04x. Resetting master...\n",
+		ioread32(I2C_REG_STS(alg_data)),
+		ioread32(I2C_REG_CTL(alg_data)));
 
 	/* Reset master and disable interrupts */
 	ctl = ioread32(I2C_REG_CTL(alg_data));
@@ -409,15 +404,14 @@ static void i2c_pnx_timeout(unsigned lon
 	complete(&alg_data->mif.complete);
 }
 
-static inline void bus_reset_if_active(struct i2c_adapter *adap)
+static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data)
 {
-	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
 	u32 stat;
 
 	if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) {
-		dev_err(&adap->dev,
+		dev_err(&alg_data->adapter.dev,
 			"%s: Bus is still active after xfer. Reset it...\n",
-		       adap->name);
+			alg_data->adapter.name);
 		iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
 			  I2C_REG_CTL(alg_data));
 		wait_reset(I2C_PNX_TIMEOUT, alg_data);
@@ -451,10 +445,11 @@ i2c_pnx_xfer(struct i2c_adapter *adap, s
 	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
 	u32 stat = ioread32(I2C_REG_STS(alg_data));
 
-	dev_dbg(&adap->dev, "%s(): entering: %d messages, stat = %04x.\n",
+	dev_dbg(&alg_data->adapter.dev,
+		"%s(): entering: %d messages, stat = %04x.\n",
 		__func__, num, ioread32(I2C_REG_STS(alg_data)));
 
-	bus_reset_if_active(adap);
+	bus_reset_if_active(alg_data);
 
 	/* Process transactions in a loop. */
 	for (i = 0; rc >= 0 && i < num; i++) {
@@ -464,9 +459,9 @@ i2c_pnx_xfer(struct i2c_adapter *adap, s
 		addr = pmsg->addr;
 
 		if (pmsg->flags & I2C_M_TEN) {
-			dev_err(&adap->dev,
+			dev_err(&alg_data->adapter.dev,
 				"%s: 10 bits addr not supported!\n",
-				adap->name);
+				alg_data->adapter.name);
 			rc = -EINVAL;
 			break;
 		}
@@ -478,11 +473,10 @@ i2c_pnx_xfer(struct i2c_adapter *adap, s
 		alg_data->mif.ret = 0;
 		alg_data->last = (i == num - 1);
 
-		dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __func__,
-			alg_data->mif.mode,
-			alg_data->mif.len);
+		dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n",
+			__func__, alg_data->mif.mode, alg_data->mif.len);
 
-		i2c_pnx_arm_timer(adap);
+		i2c_pnx_arm_timer(alg_data);
 
 		/* initialize the completion var */
 		init_completion(&alg_data->mif.complete);
@@ -493,7 +487,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, s
 			  I2C_REG_CTL(alg_data));
 
 		/* Put start-code and slave-address on the bus. */
-		rc = i2c_pnx_start(addr, adap);
+		rc = i2c_pnx_start(addr, alg_data);
 		if (rc < 0)
 			break;
 
@@ -502,31 +496,32 @@ i2c_pnx_xfer(struct i2c_adapter *adap, s
 
 		if (!(rc = alg_data->mif.ret))
 			completed++;
-		dev_dbg(&adap->dev, "%s(): Complete, return code = %d.\n",
+		dev_dbg(&alg_data->adapter.dev,
+			"%s(): Complete, return code = %d.\n",
 			__func__, rc);
 
 		/* Clear TDI and AFI bits in case they are set. */
 		if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) {
-			dev_dbg(&adap->dev,
+			dev_dbg(&alg_data->adapter.dev,
 				"%s: TDI still set... clearing now.\n",
-			       adap->name);
+				alg_data->adapter.name);
 			iowrite32(stat, I2C_REG_STS(alg_data));
 		}
 		if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_afi) {
-			dev_dbg(&adap->dev,
+			dev_dbg(&alg_data->adapter.dev,
 				"%s: AFI still set... clearing now.\n",
-			       adap->name);
+				alg_data->adapter.name);
 			iowrite32(stat, I2C_REG_STS(alg_data));
 		}
 	}
 
-	bus_reset_if_active(adap);
+	bus_reset_if_active(alg_data);
 
 	/* Cleanup to be sure... */
 	alg_data->mif.buf = NULL;
 	alg_data->mif.len = 0;
 
-	dev_dbg(&adap->dev, "%s(): exiting, stat = %x\n",
+	dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n",
 		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 	if (completed != num)
@@ -545,69 +540,92 @@ static struct i2c_algorithm pnx_algorith
 	.functionality = i2c_pnx_func,
 };
 
+#ifdef CONFIG_PM
 static int i2c_pnx_controller_suspend(struct platform_device *pdev,
 				      pm_message_t state)
 {
-	struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev);
-	return i2c_pnx->suspend(pdev, state);
+	struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
+
+	/* FIXME: shouldn't this be clk_disable? */
+	clk_enable(alg_data->clk);
+
+	return 0;
 }
 
 static int i2c_pnx_controller_resume(struct platform_device *pdev)
 {
-	struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev);
-	return i2c_pnx->resume(pdev);
+	struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
+
+	return clk_enable(alg_data->clk);
 }
+#else
+#define i2c_pnx_controller_suspend	NULL
+#define i2c_pnx_controller_resume	NULL
+#endif
 
 static int __devinit i2c_pnx_probe(struct platform_device *pdev)
 {
 	unsigned long tmp;
 	int ret = 0;
 	struct i2c_pnx_algo_data *alg_data;
-	int freq_mhz;
+	unsigned long freq;
 	struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data;
 
-	if (!i2c_pnx || !i2c_pnx->adapter) {
+	if (!i2c_pnx || !i2c_pnx->name) {
 		dev_err(&pdev->dev, "%s: no platform data supplied\n",
 		       __func__);
 		ret = -EINVAL;
 		goto out;
 	}
 
-	platform_set_drvdata(pdev, i2c_pnx);
-
-	if (i2c_pnx->calculate_input_freq)
-		freq_mhz = i2c_pnx->calculate_input_freq(pdev);
-	else {
-		freq_mhz = PNX_DEFAULT_FREQ;
-		dev_info(&pdev->dev, "Setting bus frequency to default value: "
-		       "%d MHz\n", freq_mhz);
+	alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL);
+	if (!alg_data) {
+		ret = -ENOMEM;
+		goto err_kzalloc;
 	}
 
-	i2c_pnx->adapter->algo = &pnx_algorithm;
+	platform_set_drvdata(pdev, alg_data);
+
+	strlcpy(alg_data->adapter.name, i2c_pnx->name,
+		sizeof(alg_data->adapter.name));
+	alg_data->adapter.dev.parent = &pdev->dev;
+	alg_data->adapter.algo = &pnx_algorithm;
+	alg_data->adapter.algo_data = alg_data;
+	alg_data->adapter.nr = pdev->id;
+	alg_data->i2c_pnx = i2c_pnx;
+
+	alg_data->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(alg_data->clk)) {
+		ret = PTR_ERR(alg_data->clk);
+		goto out_drvdata;
+	}
 
-	alg_data = i2c_pnx->adapter->algo_data;
 	init_timer(&alg_data->mif.timer);
 	alg_data->mif.timer.function = i2c_pnx_timeout;
-	alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter;
+	alg_data->mif.timer.data = (unsigned long)alg_data;
 
 	/* Register I/O resource */
-	if (!request_mem_region(alg_data->base, I2C_PNX_REGION_SIZE,
+	if (!request_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE,
 				pdev->name)) {
 		dev_err(&pdev->dev,
 		       "I/O region 0x%08x for I2C already in use.\n",
-		       alg_data->base);
+		       i2c_pnx->base);
 		ret = -ENODEV;
-		goto out_drvdata;
+		goto out_clkget;
 	}
 
-	if (!(alg_data->ioaddr =
-			(u32)ioremap(alg_data->base, I2C_PNX_REGION_SIZE))) {
+	alg_data->ioaddr = ioremap(i2c_pnx->base, I2C_PNX_REGION_SIZE);
+	if (!alg_data->ioaddr) {
 		dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n");
 		ret = -ENOMEM;
 		goto out_release;
 	}
 
-	i2c_pnx->set_clock_run(pdev);
+	ret = clk_enable(alg_data->clk);
+	if (ret)
+		goto out_unmap;
+
+	freq = clk_get_rate(alg_data->clk);
 
 	/*
 	 * Clock Divisor High This value is the number of system clocks
@@ -620,45 +638,49 @@ static int __devinit i2c_pnx_probe(struc
 	 * the deglitching filter length.
 	 */
 
-	tmp = ((freq_mhz * 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;
+	tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;
+	if (tmp > 0x3FF)
+		tmp = 0x3FF;
 	iowrite32(tmp, I2C_REG_CKH(alg_data));
 	iowrite32(tmp, I2C_REG_CKL(alg_data));
 
 	iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data));
 	if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) {
 		ret = -ENODEV;
-		goto out_unmap;
+		goto out_clock;
 	}
 	init_completion(&alg_data->mif.complete);
 
-	ret = request_irq(alg_data->irq, i2c_pnx_interrupt,
-			0, pdev->name, i2c_pnx->adapter);
+	ret = request_irq(i2c_pnx->irq, i2c_pnx_interrupt,
+			0, pdev->name, alg_data);
 	if (ret)
 		goto out_clock;
 
 	/* Register this adapter with the I2C subsystem */
-	i2c_pnx->adapter->dev.parent = &pdev->dev;
-	i2c_pnx->adapter->nr = pdev->id;
-	ret = i2c_add_numbered_adapter(i2c_pnx->adapter);
+	ret = i2c_add_numbered_adapter(&alg_data->adapter);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "I2C: Failed to add bus\n");
 		goto out_irq;
 	}
 
 	dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
-	       i2c_pnx->adapter->name, alg_data->base, alg_data->irq);
+	       alg_data->adapter.name, i2c_pnx->base, i2c_pnx->irq);
 
 	return 0;
 
 out_irq:
-	free_irq(alg_data->irq, i2c_pnx->adapter);
+	free_irq(i2c_pnx->irq, alg_data);
 out_clock:
-	i2c_pnx->set_clock_stop(pdev);
+	clk_disable(alg_data->clk);
 out_unmap:
-	iounmap((void *)alg_data->ioaddr);
+	iounmap(alg_data->ioaddr);
 out_release:
-	release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE);
+	release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE);
+out_clkget:
+	clk_put(alg_data->clk);
 out_drvdata:
+	kfree(alg_data);
+err_kzalloc:
 	platform_set_drvdata(pdev, NULL);
 out:
 	return ret;
@@ -666,15 +688,16 @@ out:
 
 static int __devexit i2c_pnx_remove(struct platform_device *pdev)
 {
-	struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev);
-	struct i2c_adapter *adap = i2c_pnx->adapter;
-	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+	struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
+	struct i2c_pnx_data *i2c_pnx = alg_data->i2c_pnx;
 
-	free_irq(alg_data->irq, i2c_pnx->adapter);
-	i2c_del_adapter(adap);
-	i2c_pnx->set_clock_stop(pdev);
-	iounmap((void *)alg_data->ioaddr);
-	release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE);
+	free_irq(i2c_pnx->irq, alg_data);
+	i2c_del_adapter(&alg_data->adapter);
+	clk_disable(alg_data->clk);
+	iounmap(alg_data->ioaddr);
+	release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE);
+	clk_put(alg_data->clk);
+	kfree(alg_data);
 	platform_set_drvdata(pdev, NULL);
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-powermac.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-powermac.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-powermac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-powermac.c	2010-05-16 17:17:36.000000000 -0400
@@ -122,9 +122,14 @@ static s32 i2c_powermac_smbus_xfer(	stru
 
 	rc = pmac_i2c_xfer(bus, addrdir, subsize, subaddr, buf, len);
 	if (rc) {
-		dev_err(&adap->dev,
-			"I2C transfer at 0x%02x failed, size %d, err %d\n",
-			addrdir >> 1, size, rc);
+		if (rc == -ENXIO)
+			dev_dbg(&adap->dev,
+				"I2C transfer at 0x%02x failed, size %d, "
+				"err %d\n", addrdir >> 1, size, rc);
+		else
+			dev_err(&adap->dev,
+				"I2C transfer at 0x%02x failed, size %d, "
+				"err %d\n", addrdir >> 1, size, rc);
 		goto bail;
 	}
 
@@ -175,10 +180,16 @@ static int i2c_powermac_master_xfer(	str
 		goto bail;
 	}
 	rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len);
-	if (rc < 0)
-		dev_err(&adap->dev, "I2C %s 0x%02x failed, err %d\n",
-			addrdir & 1 ? "read from" : "write to", addrdir >> 1,
-			rc);
+	if (rc < 0) {
+		if (rc == -ENXIO)
+			dev_dbg(&adap->dev, "I2C %s 0x%02x failed, err %d\n",
+				addrdir & 1 ? "read from" : "write to",
+				addrdir >> 1, rc);
+		else
+			dev_err(&adap->dev, "I2C %s 0x%02x failed, err %d\n",
+				addrdir & 1 ? "read from" : "write to",
+				addrdir >> 1, rc);
+	}
  bail:
 	pmac_i2c_close(bus);
 	return rc < 0 ? rc : 1;
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-pxa.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-pxa.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-pxa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-pxa.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,7 @@
  *
  *  History:
  *    Apr 2002: Initial version [CS]
- *    Jun 2002: Properly seperated algo/adap [FB]
+ *    Jun 2002: Properly separated algo/adap [FB]
  *    Jan 2003: Fixed several bugs concerning interrupt handling [Kai-Uwe Bloem]
  *    Jan 2003: added limited signal handling [Kai-Uwe Bloem]
  *    Sep 2004: Major rework to ensure efficient bus handling [RMK]
@@ -33,6 +33,7 @@
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-s3c2410.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-s3c2410.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-s3c2410.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-s3c2410.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/cpufreq.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-scmi.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-scmi.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-scmi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-scmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@ struct acpi_smbus_cmi {
 	u8 cap_info:1;
 	u8 cap_read:1;
 	u8 cap_write:1;
+	struct smbus_methods_t *methods;
 };
 
 static const struct smbus_methods_t smbus_methods = {
@@ -41,10 +42,19 @@ static const struct smbus_methods_t smbu
 	.mt_sbw  = "_SBW",
 };
 
+/* Some IBM BIOSes omit the leading underscore */
+static const struct smbus_methods_t ibm_smbus_methods = {
+	.mt_info = "SBI_",
+	.mt_sbr  = "SBR_",
+	.mt_sbw  = "SBW_",
+};
+
 static const struct acpi_device_id acpi_smbus_cmi_ids[] = {
-	{"SMBUS01", 0},
+	{"SMBUS01", (kernel_ulong_t)&smbus_methods},
+	{ACPI_SMBUS_IBM_HID, (kernel_ulong_t)&ibm_smbus_methods},
 	{"", 0}
 };
+MODULE_DEVICE_TABLE(acpi, acpi_smbus_cmi_ids);
 
 #define ACPI_SMBUS_STATUS_OK			0x00
 #define ACPI_SMBUS_STATUS_FAIL			0x07
@@ -150,11 +160,11 @@ acpi_smbus_cmi_access(struct i2c_adapter
 
 	if (read_write == I2C_SMBUS_READ) {
 		protocol |= ACPI_SMBUS_PRTCL_READ;
-		method = smbus_methods.mt_sbr;
+		method = smbus_cmi->methods->mt_sbr;
 		input.count = 3;
 	} else {
 		protocol |= ACPI_SMBUS_PRTCL_WRITE;
-		method = smbus_methods.mt_sbw;
+		method = smbus_cmi->methods->mt_sbw;
 		input.count = 5;
 	}
 
@@ -290,13 +300,13 @@ static int acpi_smbus_cmi_add_cap(struct
 	union acpi_object *obj;
 	acpi_status status;
 
-	if (!strcmp(name, smbus_methods.mt_info)) {
+	if (!strcmp(name, smbus_cmi->methods->mt_info)) {
 		status = acpi_evaluate_object(smbus_cmi->handle,
-					smbus_methods.mt_info,
+					smbus_cmi->methods->mt_info,
 					NULL, &buffer);
 		if (ACPI_FAILURE(status)) {
 			ACPI_ERROR((AE_INFO, "Evaluating %s: %i",
-				   smbus_methods.mt_info, status));
+				   smbus_cmi->methods->mt_info, status));
 			return -EIO;
 		}
 
@@ -319,9 +329,9 @@ static int acpi_smbus_cmi_add_cap(struct
 
 		kfree(buffer.pointer);
 		smbus_cmi->cap_info = 1;
-	} else if (!strcmp(name, smbus_methods.mt_sbr))
+	} else if (!strcmp(name, smbus_cmi->methods->mt_sbr))
 		smbus_cmi->cap_read = 1;
-	else if (!strcmp(name, smbus_methods.mt_sbw))
+	else if (!strcmp(name, smbus_cmi->methods->mt_sbw))
 		smbus_cmi->cap_write = 1;
 	else
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported CMI method: %s\n",
@@ -349,6 +359,7 @@ static acpi_status acpi_smbus_cmi_query_
 static int acpi_smbus_cmi_add(struct acpi_device *device)
 {
 	struct acpi_smbus_cmi *smbus_cmi;
+	const struct acpi_device_id *id;
 
 	smbus_cmi = kzalloc(sizeof(struct acpi_smbus_cmi), GFP_KERNEL);
 	if (!smbus_cmi)
@@ -362,6 +373,11 @@ static int acpi_smbus_cmi_add(struct acp
 	smbus_cmi->cap_read = 0;
 	smbus_cmi->cap_write = 0;
 
+	for (id = acpi_smbus_cmi_ids; id->id[0]; id++)
+		if (!strcmp(id->id, acpi_device_hid(device)))
+			smbus_cmi->methods =
+				(struct smbus_methods_t *) id->driver_data;
+
 	acpi_walk_namespace(ACPI_TYPE_METHOD, smbus_cmi->handle, 1,
 			    acpi_smbus_cmi_query_methods, NULL, smbus_cmi, NULL);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-sh_mobile.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-sh_mobile.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-sh_mobile.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-sh_mobile.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 /* Transmit operation:                                                      */
 /*                                                                          */
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-simtec.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-simtec.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-simtec.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-simtec.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-sis5595.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-sis5595.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-sis5595.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-sis5595.c	2010-05-16 17:17:36.000000000 -0400
@@ -369,7 +369,7 @@ static struct i2c_adapter sis5595_adapte
 	.algo		= &smbus_algorithm,
 };
 
-static struct pci_device_id sis5595_ids[] __devinitdata = {
+static const struct pci_device_id sis5595_ids[] __devinitconst = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, 
 	{ 0, }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-sis630.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-sis630.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-sis630.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-sis630.c	2010-05-16 17:17:36.000000000 -0400
@@ -468,7 +468,7 @@ static struct i2c_adapter sis630_adapter
 	.algo		= &smbus_algorithm,
 };
 
-static struct pci_device_id sis630_ids[] __devinitdata = {
+static const struct pci_device_id sis630_ids[] __devinitconst = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
 	{ 0, }
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-sis96x.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-sis96x.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-sis96x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-sis96x.c	2010-05-16 17:17:36.000000000 -0400
@@ -245,7 +245,7 @@ static struct i2c_adapter sis96x_adapter
 	.algo		= &smbus_algorithm,
 };
 
-static struct pci_device_id sis96x_ids[] = {
+static const struct pci_device_id sis96x_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
 	{ 0, }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-stu300.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-stu300.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-stu300.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-stu300.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 /* the name of this kernel module */
 #define NAME "stu300"
@@ -497,7 +498,7 @@ static int stu300_set_clk(struct stu300_
 	int i = 0;
 
 	/* Locate the apropriate clock setting */
-	while (i < ARRAY_SIZE(stu300_clktable) &&
+	while (i < ARRAY_SIZE(stu300_clktable) - 1 &&
 	       stu300_clktable[i].rate < clkrate)
 		i++;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-tiny-usb.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-tiny-usb.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-tiny-usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-tiny-usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 /* include interfaces to usb layer */
@@ -31,11 +32,13 @@
 #define CMD_I2C_IO_BEGIN	(1<<0)
 #define CMD_I2C_IO_END		(1<<1)
 
-/* i2c bit delay, default is 10us -> 100kHz */
+/* i2c bit delay, default is 10us -> 100kHz max
+   (in practice, due to additional delays in the i2c bitbanging
+   code this results in a i2c clock of about 50kHz) */
 static unsigned short delay = 10;
 module_param(delay, ushort, 0);
-MODULE_PARM_DESC(delay, "bit delay in microseconds, "
-		 "e.g. 10 for 100kHz (default is 100kHz)");
+MODULE_PARM_DESC(delay, "bit delay in microseconds "
+		 "(default is 10us for 100kHz max)");
 
 static int usb_read(struct i2c_adapter *adapter, int cmd,
 		    int value, int index, void *data, int len);
@@ -137,7 +140,7 @@ static const struct i2c_algorithm usb_al
  * Future Technology Devices International Ltd., later a pair was
  * bought from EZPrototypes
  */
-static struct usb_device_id i2c_tiny_usb_table [] = {
+static const struct usb_device_id i2c_tiny_usb_table[] = {
 	{ USB_DEVICE(0x0403, 0xc631) },   /* FTDI */
 	{ USB_DEVICE(0x1c40, 0x0534) },   /* EZPrototypes */
 	{ }                               /* Terminating entry */
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-versatile.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-versatile.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-versatile.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-versatile.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/i2c-algo-bit.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-via.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-via.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-via.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-via.c	2010-05-16 17:17:36.000000000 -0400
@@ -89,7 +89,7 @@ static struct i2c_adapter vt586b_adapter
 };
 
 
-static struct pci_device_id vt586b_ids[] __devinitdata = {
+static const struct pci_device_id vt586b_ids[] __devinitconst = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3) },
 	{ 0, }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-viapro.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-viapro.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-viapro.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-viapro.c	2010-05-16 17:17:36.000000000 -0400
@@ -444,7 +444,7 @@ release_region:
 	return error;
 }
 
-static struct pci_device_id vt596_ids[] = {
+static const struct pci_device_id vt596_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596_3),
 	  .driver_data = SMBBA1 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596B_3),
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-xiic.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-xiic.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-xiic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/i2c-xiic.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,826 @@
+/*
+ * i2c-xiic.c
+ * Copyright (c) 2002-2007 Xilinx Inc.
+ * Copyright (c) 2009-2010 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This code was implemented by Mocean Laboratories AB when porting linux
+ * to the automotive development board Russellville. The copyright holder
+ * as seen in the header is Intel corporation.
+ * Mocean Laboratories forked off the GNU/Linux platform work into a
+ * separate company called Pelagicore AB, which commited the code to the
+ * kernel.
+ */
+
+/* Supports:
+ * Xilinx IIC
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/i2c-xiic.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#define DRIVER_NAME "xiic-i2c"
+
+enum xilinx_i2c_state {
+	STATE_DONE,
+	STATE_ERROR,
+	STATE_START
+};
+
+/**
+ * struct xiic_i2c - Internal representation of the XIIC I2C bus
+ * @base:	Memory base of the HW registers
+ * @wait:	Wait queue for callers
+ * @adap:	Kernel adapter representation
+ * @tx_msg:	Messages from above to be sent
+ * @lock:	Mutual exclusion
+ * @tx_pos:	Current pos in TX message
+ * @nmsgs:	Number of messages in tx_msg
+ * @state:	See STATE_
+ * @rx_msg:	Current RX message
+ * @rx_pos:	Position within current RX message
+ */
+struct xiic_i2c {
+	void __iomem		*base;
+	wait_queue_head_t	wait;
+	struct i2c_adapter	adap;
+	struct i2c_msg		*tx_msg;
+	spinlock_t		lock;
+	unsigned int 		tx_pos;
+	unsigned int		nmsgs;
+	enum xilinx_i2c_state	state;
+	struct i2c_msg		*rx_msg;
+	int			rx_pos;
+};
+
+
+#define XIIC_MSB_OFFSET 0
+#define XIIC_REG_OFFSET (0x100+XIIC_MSB_OFFSET)
+
+/*
+ * Register offsets in bytes from RegisterBase. Three is added to the
+ * base offset to access LSB (IBM style) of the word
+ */
+#define XIIC_CR_REG_OFFSET   (0x00+XIIC_REG_OFFSET)	/* Control Register   */
+#define XIIC_SR_REG_OFFSET   (0x04+XIIC_REG_OFFSET)	/* Status Register    */
+#define XIIC_DTR_REG_OFFSET  (0x08+XIIC_REG_OFFSET)	/* Data Tx Register   */
+#define XIIC_DRR_REG_OFFSET  (0x0C+XIIC_REG_OFFSET)	/* Data Rx Register   */
+#define XIIC_ADR_REG_OFFSET  (0x10+XIIC_REG_OFFSET)	/* Address Register   */
+#define XIIC_TFO_REG_OFFSET  (0x14+XIIC_REG_OFFSET)	/* Tx FIFO Occupancy  */
+#define XIIC_RFO_REG_OFFSET  (0x18+XIIC_REG_OFFSET)	/* Rx FIFO Occupancy  */
+#define XIIC_TBA_REG_OFFSET  (0x1C+XIIC_REG_OFFSET)	/* 10 Bit Address reg */
+#define XIIC_RFD_REG_OFFSET  (0x20+XIIC_REG_OFFSET)	/* Rx FIFO Depth reg  */
+#define XIIC_GPO_REG_OFFSET  (0x24+XIIC_REG_OFFSET)	/* Output Register    */
+
+/* Control Register masks */
+#define XIIC_CR_ENABLE_DEVICE_MASK        0x01	/* Device enable = 1      */
+#define XIIC_CR_TX_FIFO_RESET_MASK        0x02	/* Transmit FIFO reset=1  */
+#define XIIC_CR_MSMS_MASK                 0x04	/* Master starts Txing=1  */
+#define XIIC_CR_DIR_IS_TX_MASK            0x08	/* Dir of tx. Txing=1     */
+#define XIIC_CR_NO_ACK_MASK               0x10	/* Tx Ack. NO ack = 1     */
+#define XIIC_CR_REPEATED_START_MASK       0x20	/* Repeated start = 1     */
+#define XIIC_CR_GENERAL_CALL_MASK         0x40	/* Gen Call enabled = 1   */
+
+/* Status Register masks */
+#define XIIC_SR_GEN_CALL_MASK             0x01	/* 1=a mstr issued a GC   */
+#define XIIC_SR_ADDR_AS_SLAVE_MASK        0x02	/* 1=when addr as slave   */
+#define XIIC_SR_BUS_BUSY_MASK             0x04	/* 1 = bus is busy        */
+#define XIIC_SR_MSTR_RDING_SLAVE_MASK     0x08	/* 1=Dir: mstr <-- slave  */
+#define XIIC_SR_TX_FIFO_FULL_MASK         0x10	/* 1 = Tx FIFO full       */
+#define XIIC_SR_RX_FIFO_FULL_MASK         0x20	/* 1 = Rx FIFO full       */
+#define XIIC_SR_RX_FIFO_EMPTY_MASK        0x40	/* 1 = Rx FIFO empty      */
+#define XIIC_SR_TX_FIFO_EMPTY_MASK        0x80	/* 1 = Tx FIFO empty      */
+
+/* Interrupt Status Register masks    Interrupt occurs when...       */
+#define XIIC_INTR_ARB_LOST_MASK           0x01	/* 1 = arbitration lost   */
+#define XIIC_INTR_TX_ERROR_MASK           0x02	/* 1=Tx error/msg complete */
+#define XIIC_INTR_TX_EMPTY_MASK           0x04	/* 1 = Tx FIFO/reg empty  */
+#define XIIC_INTR_RX_FULL_MASK            0x08	/* 1=Rx FIFO/reg=OCY level */
+#define XIIC_INTR_BNB_MASK                0x10	/* 1 = Bus not busy       */
+#define XIIC_INTR_AAS_MASK                0x20	/* 1 = when addr as slave */
+#define XIIC_INTR_NAAS_MASK               0x40	/* 1 = not addr as slave  */
+#define XIIC_INTR_TX_HALF_MASK            0x80	/* 1 = TX FIFO half empty */
+
+/* The following constants specify the depth of the FIFOs */
+#define IIC_RX_FIFO_DEPTH         16	/* Rx fifo capacity               */
+#define IIC_TX_FIFO_DEPTH         16	/* Tx fifo capacity               */
+
+/* The following constants specify groups of interrupts that are typically
+ * enabled or disables at the same time
+ */
+#define XIIC_TX_INTERRUPTS                           \
+(XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)
+
+#define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS)
+
+/* The following constants are used with the following macros to specify the
+ * operation, a read or write operation.
+ */
+#define XIIC_READ_OPERATION  1
+#define XIIC_WRITE_OPERATION 0
+
+/*
+ * Tx Fifo upper bit masks.
+ */
+#define XIIC_TX_DYN_START_MASK            0x0100 /* 1 = Set dynamic start */
+#define XIIC_TX_DYN_STOP_MASK             0x0200 /* 1 = Set dynamic stop */
+
+/*
+ * The following constants define the register offsets for the Interrupt
+ * registers. There are some holes in the memory map for reserved addresses
+ * to allow other registers to be added and still match the memory map of the
+ * interrupt controller registers
+ */
+#define XIIC_DGIER_OFFSET    0x1C /* Device Global Interrupt Enable Register */
+#define XIIC_IISR_OFFSET     0x20 /* Interrupt Status Register */
+#define XIIC_IIER_OFFSET     0x28 /* Interrupt Enable Register */
+#define XIIC_RESETR_OFFSET   0x40 /* Reset Register */
+
+#define XIIC_RESET_MASK             0xAUL
+
+/*
+ * The following constant is used for the device global interrupt enable
+ * register, to enable all interrupts for the device, this is the only bit
+ * in the register
+ */
+#define XIIC_GINTR_ENABLE_MASK      0x80000000UL
+
+#define xiic_tx_space(i2c) ((i2c)->tx_msg->len - (i2c)->tx_pos)
+#define xiic_rx_space(i2c) ((i2c)->rx_msg->len - (i2c)->rx_pos)
+
+static void xiic_start_xfer(struct xiic_i2c *i2c);
+static void __xiic_start_xfer(struct xiic_i2c *i2c);
+
+static inline void xiic_setreg8(struct xiic_i2c *i2c, int reg, u8 value)
+{
+	iowrite8(value, i2c->base + reg);
+}
+
+static inline u8 xiic_getreg8(struct xiic_i2c *i2c, int reg)
+{
+	return ioread8(i2c->base + reg);
+}
+
+static inline void xiic_setreg16(struct xiic_i2c *i2c, int reg, u16 value)
+{
+	iowrite16(value, i2c->base + reg);
+}
+
+static inline void xiic_setreg32(struct xiic_i2c *i2c, int reg, int value)
+{
+	iowrite32(value, i2c->base + reg);
+}
+
+static inline int xiic_getreg32(struct xiic_i2c *i2c, int reg)
+{
+	return ioread32(i2c->base + reg);
+}
+
+static inline void xiic_irq_dis(struct xiic_i2c *i2c, u32 mask)
+{
+	u32 ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
+	xiic_setreg32(i2c, XIIC_IIER_OFFSET, ier & ~mask);
+}
+
+static inline void xiic_irq_en(struct xiic_i2c *i2c, u32 mask)
+{
+	u32 ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
+	xiic_setreg32(i2c, XIIC_IIER_OFFSET, ier | mask);
+}
+
+static inline void xiic_irq_clr(struct xiic_i2c *i2c, u32 mask)
+{
+	u32 isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET);
+	xiic_setreg32(i2c, XIIC_IISR_OFFSET, isr & mask);
+}
+
+static inline void xiic_irq_clr_en(struct xiic_i2c *i2c, u32 mask)
+{
+	xiic_irq_clr(i2c, mask);
+	xiic_irq_en(i2c, mask);
+}
+
+static void xiic_clear_rx_fifo(struct xiic_i2c *i2c)
+{
+	u8 sr;
+	for (sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET);
+		!(sr & XIIC_SR_RX_FIFO_EMPTY_MASK);
+		sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET))
+		xiic_getreg8(i2c, XIIC_DRR_REG_OFFSET);
+}
+
+static void xiic_reinit(struct xiic_i2c *i2c)
+{
+	xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK);
+
+	/* Set receive Fifo depth to maximum (zero based). */
+	xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, IIC_RX_FIFO_DEPTH - 1);
+
+	/* Reset Tx Fifo. */
+	xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_TX_FIFO_RESET_MASK);
+
+	/* Enable IIC Device, remove Tx Fifo reset & disable general call. */
+	xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_ENABLE_DEVICE_MASK);
+
+	/* make sure RX fifo is empty */
+	xiic_clear_rx_fifo(i2c);
+
+	/* Enable interrupts */
+	xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
+
+	xiic_irq_clr_en(i2c, XIIC_INTR_AAS_MASK | XIIC_INTR_ARB_LOST_MASK);
+}
+
+static void xiic_deinit(struct xiic_i2c *i2c)
+{
+	u8 cr;
+
+	xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK);
+
+	/* Disable IIC Device. */
+	cr = xiic_getreg8(i2c, XIIC_CR_REG_OFFSET);
+	xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, cr & ~XIIC_CR_ENABLE_DEVICE_MASK);
+}
+
+static void xiic_read_rx(struct xiic_i2c *i2c)
+{
+	u8 bytes_in_fifo;
+	int i;
+
+	bytes_in_fifo = xiic_getreg8(i2c, XIIC_RFO_REG_OFFSET) + 1;
+
+	dev_dbg(i2c->adap.dev.parent, "%s entry, bytes in fifo: %d, msg: %d"
+		", SR: 0x%x, CR: 0x%x\n",
+		__func__, bytes_in_fifo, xiic_rx_space(i2c),
+		xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
+		xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
+
+	if (bytes_in_fifo > xiic_rx_space(i2c))
+		bytes_in_fifo = xiic_rx_space(i2c);
+
+	for (i = 0; i < bytes_in_fifo; i++)
+		i2c->rx_msg->buf[i2c->rx_pos++] =
+			xiic_getreg8(i2c, XIIC_DRR_REG_OFFSET);
+
+	xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET,
+		(xiic_rx_space(i2c) > IIC_RX_FIFO_DEPTH) ?
+		IIC_RX_FIFO_DEPTH - 1 :  xiic_rx_space(i2c) - 1);
+}
+
+static int xiic_tx_fifo_space(struct xiic_i2c *i2c)
+{
+	/* return the actual space left in the FIFO */
+	return IIC_TX_FIFO_DEPTH - xiic_getreg8(i2c, XIIC_TFO_REG_OFFSET) - 1;
+}
+
+static void xiic_fill_tx_fifo(struct xiic_i2c *i2c)
+{
+	u8 fifo_space = xiic_tx_fifo_space(i2c);
+	int len = xiic_tx_space(i2c);
+
+	len = (len > fifo_space) ? fifo_space : len;
+
+	dev_dbg(i2c->adap.dev.parent, "%s entry, len: %d, fifo space: %d\n",
+		__func__, len, fifo_space);
+
+	while (len--) {
+		u16 data = i2c->tx_msg->buf[i2c->tx_pos++];
+		if ((xiic_tx_space(i2c) == 0) && (i2c->nmsgs == 1)) {
+			/* last message in transfer -> STOP */
+			data |= XIIC_TX_DYN_STOP_MASK;
+			dev_dbg(i2c->adap.dev.parent, "%s TX STOP\n", __func__);
+
+			xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
+		} else
+			xiic_setreg8(i2c, XIIC_DTR_REG_OFFSET, data);
+	}
+}
+
+static void xiic_wakeup(struct xiic_i2c *i2c, int code)
+{
+	i2c->tx_msg = NULL;
+	i2c->rx_msg = NULL;
+	i2c->nmsgs = 0;
+	i2c->state = code;
+	wake_up(&i2c->wait);
+}
+
+static void xiic_process(struct xiic_i2c *i2c)
+{
+	u32 pend, isr, ier;
+	u32 clr = 0;
+
+	/* Get the interrupt Status from the IPIF. There is no clearing of
+	 * interrupts in the IPIF. Interrupts must be cleared at the source.
+	 * To find which interrupts are pending; AND interrupts pending with
+	 * interrupts masked.
+	 */
+	isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET);
+	ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
+	pend = isr & ier;
+
+	dev_dbg(i2c->adap.dev.parent, "%s entry, IER: 0x%x, ISR: 0x%x, "
+		"pend: 0x%x, SR: 0x%x, msg: %p, nmsgs: %d\n",
+		__func__, ier, isr, pend, xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
+		i2c->tx_msg, i2c->nmsgs);
+
+	/* Do not processes a devices interrupts if the device has no
+	 * interrupts pending
+	 */
+	if (!pend)
+		return;
+
+	/* Service requesting interrupt */
+	if ((pend & XIIC_INTR_ARB_LOST_MASK) ||
+		((pend & XIIC_INTR_TX_ERROR_MASK) &&
+		!(pend & XIIC_INTR_RX_FULL_MASK))) {
+		/* bus arbritration lost, or...
+		 * Transmit error _OR_ RX completed
+		 * if this happens when RX_FULL is not set
+		 * this is probably a TX error
+		 */
+
+		dev_dbg(i2c->adap.dev.parent, "%s error\n", __func__);
+
+		/* dynamic mode seem to suffer from problems if we just flushes
+		 * fifos and the next message is a TX with len 0 (only addr)
+		 * reset the IP instead of just flush fifos
+		 */
+		xiic_reinit(i2c);
+
+		if (i2c->tx_msg)
+			xiic_wakeup(i2c, STATE_ERROR);
+
+	} else if (pend & XIIC_INTR_RX_FULL_MASK) {
+		/* Receive register/FIFO is full */
+
+		clr = XIIC_INTR_RX_FULL_MASK;
+		if (!i2c->rx_msg) {
+			dev_dbg(i2c->adap.dev.parent,
+				"%s unexpexted RX IRQ\n", __func__);
+			xiic_clear_rx_fifo(i2c);
+			goto out;
+		}
+
+		xiic_read_rx(i2c);
+		if (xiic_rx_space(i2c) == 0) {
+			/* this is the last part of the message */
+			i2c->rx_msg = NULL;
+
+			/* also clear TX error if there (RX complete) */
+			clr |= (isr & XIIC_INTR_TX_ERROR_MASK);
+
+			dev_dbg(i2c->adap.dev.parent,
+				"%s end of message, nmsgs: %d\n",
+				__func__, i2c->nmsgs);
+
+			/* send next message if this wasn't the last,
+			 * otherwise the transfer will be finialise when
+			 * receiving the bus not busy interrupt
+			 */
+			if (i2c->nmsgs > 1) {
+				i2c->nmsgs--;
+				i2c->tx_msg++;
+				dev_dbg(i2c->adap.dev.parent,
+					"%s will start next...\n", __func__);
+
+				__xiic_start_xfer(i2c);
+			}
+		}
+	} else if (pend & XIIC_INTR_BNB_MASK) {
+		/* IIC bus has transitioned to not busy */
+		clr = XIIC_INTR_BNB_MASK;
+
+		/* The bus is not busy, disable BusNotBusy interrupt */
+		xiic_irq_dis(i2c, XIIC_INTR_BNB_MASK);
+
+		if (!i2c->tx_msg)
+			goto out;
+
+		if ((i2c->nmsgs == 1) && !i2c->rx_msg &&
+			xiic_tx_space(i2c) == 0)
+			xiic_wakeup(i2c, STATE_DONE);
+		else
+			xiic_wakeup(i2c, STATE_ERROR);
+
+	} else if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) {
+		/* Transmit register/FIFO is empty or ½ empty */
+
+		clr = pend &
+			(XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK);
+
+		if (!i2c->tx_msg) {
+			dev_dbg(i2c->adap.dev.parent,
+				"%s unexpexted TX IRQ\n", __func__);
+			goto out;
+		}
+
+		xiic_fill_tx_fifo(i2c);
+
+		/* current message sent and there is space in the fifo */
+		if (!xiic_tx_space(i2c) && xiic_tx_fifo_space(i2c) >= 2) {
+			dev_dbg(i2c->adap.dev.parent,
+				"%s end of message sent, nmsgs: %d\n",
+				__func__, i2c->nmsgs);
+			if (i2c->nmsgs > 1) {
+				i2c->nmsgs--;
+				i2c->tx_msg++;
+				__xiic_start_xfer(i2c);
+			} else {
+				xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
+
+				dev_dbg(i2c->adap.dev.parent,
+					"%s Got TX IRQ but no more to do...\n",
+					__func__);
+			}
+		} else if (!xiic_tx_space(i2c) && (i2c->nmsgs == 1))
+			/* current frame is sent and is last,
+			 * make sure to disable tx half
+			 */
+			xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
+	} else {
+		/* got IRQ which is not acked */
+		dev_err(i2c->adap.dev.parent, "%s Got unexpected IRQ\n",
+			__func__);
+		clr = pend;
+	}
+out:
+	dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr);
+
+	xiic_setreg32(i2c, XIIC_IISR_OFFSET, clr);
+}
+
+static int xiic_bus_busy(struct xiic_i2c *i2c)
+{
+	u8 sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET);
+
+	return (sr & XIIC_SR_BUS_BUSY_MASK) ? -EBUSY : 0;
+}
+
+static int xiic_busy(struct xiic_i2c *i2c)
+{
+	int tries = 3;
+	int err;
+
+	if (i2c->tx_msg)
+		return -EBUSY;
+
+	/* for instance if previous transfer was terminated due to TX error
+	 * it might be that the bus is on it's way to become available
+	 * give it at most 3 ms to wake
+	 */
+	err = xiic_bus_busy(i2c);
+	while (err && tries--) {
+		mdelay(1);
+		err = xiic_bus_busy(i2c);
+	}
+
+	return err;
+}
+
+static void xiic_start_recv(struct xiic_i2c *i2c)
+{
+	u8 rx_watermark;
+	struct i2c_msg *msg = i2c->rx_msg = i2c->tx_msg;
+
+	/* Clear and enable Rx full interrupt. */
+	xiic_irq_clr_en(i2c, XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK);
+
+	/* we want to get all but last byte, because the TX_ERROR IRQ is used
+	 * to inidicate error ACK on the address, and negative ack on the last
+	 * received byte, so to not mix them receive all but last.
+	 * In the case where there is only one byte to receive
+	 * we can check if ERROR and RX full is set at the same time
+	 */
+	rx_watermark = msg->len;
+	if (rx_watermark > IIC_RX_FIFO_DEPTH)
+		rx_watermark = IIC_RX_FIFO_DEPTH;
+	xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, rx_watermark - 1);
+
+	if (!(msg->flags & I2C_M_NOSTART))
+		/* write the address */
+		xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET,
+			(msg->addr << 1) | XIIC_READ_OPERATION |
+			XIIC_TX_DYN_START_MASK);
+
+	xiic_irq_clr_en(i2c, XIIC_INTR_BNB_MASK);
+
+	xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET,
+		msg->len | ((i2c->nmsgs == 1) ? XIIC_TX_DYN_STOP_MASK : 0));
+	if (i2c->nmsgs == 1)
+		/* very last, enable bus not busy as well */
+		xiic_irq_clr_en(i2c, XIIC_INTR_BNB_MASK);
+
+	/* the message is tx:ed */
+	i2c->tx_pos = msg->len;
+}
+
+static void xiic_start_send(struct xiic_i2c *i2c)
+{
+	struct i2c_msg *msg = i2c->tx_msg;
+
+	xiic_irq_clr(i2c, XIIC_INTR_TX_ERROR_MASK);
+
+	dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, len: %d, "
+		"ISR: 0x%x, CR: 0x%x\n",
+		__func__, msg, msg->len, xiic_getreg32(i2c, XIIC_IISR_OFFSET),
+		xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
+
+	if (!(msg->flags & I2C_M_NOSTART)) {
+		/* write the address */
+		u16 data = ((msg->addr << 1) & 0xfe) | XIIC_WRITE_OPERATION |
+			XIIC_TX_DYN_START_MASK;
+		if ((i2c->nmsgs == 1) && msg->len == 0)
+			/* no data and last message -> add STOP */
+			data |= XIIC_TX_DYN_STOP_MASK;
+
+		xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
+	}
+
+	xiic_fill_tx_fifo(i2c);
+
+	/* Clear any pending Tx empty, Tx Error and then enable them. */
+	xiic_irq_clr_en(i2c, XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_ERROR_MASK |
+		XIIC_INTR_BNB_MASK);
+}
+
+static irqreturn_t xiic_isr(int irq, void *dev_id)
+{
+	struct xiic_i2c *i2c = dev_id;
+
+	spin_lock(&i2c->lock);
+	/* disable interrupts globally */
+	xiic_setreg32(i2c, XIIC_DGIER_OFFSET, 0);
+
+	dev_dbg(i2c->adap.dev.parent, "%s entry\n", __func__);
+
+	xiic_process(i2c);
+
+	xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
+	spin_unlock(&i2c->lock);
+
+	return IRQ_HANDLED;
+}
+
+static void __xiic_start_xfer(struct xiic_i2c *i2c)
+{
+	int first = 1;
+	int fifo_space = xiic_tx_fifo_space(i2c);
+	dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, fifos space: %d\n",
+		__func__, i2c->tx_msg, fifo_space);
+
+	if (!i2c->tx_msg)
+		return;
+
+	i2c->rx_pos = 0;
+	i2c->tx_pos = 0;
+	i2c->state = STATE_START;
+	while ((fifo_space >= 2) && (first || (i2c->nmsgs > 1))) {
+		if (!first) {
+			i2c->nmsgs--;
+			i2c->tx_msg++;
+			i2c->tx_pos = 0;
+		} else
+			first = 0;
+
+		if (i2c->tx_msg->flags & I2C_M_RD) {
+			/* we dont date putting several reads in the FIFO */
+			xiic_start_recv(i2c);
+			return;
+		} else {
+			xiic_start_send(i2c);
+			if (xiic_tx_space(i2c) != 0) {
+				/* the message could not be completely sent */
+				break;
+			}
+		}
+
+		fifo_space = xiic_tx_fifo_space(i2c);
+	}
+
+	/* there are more messages or the current one could not be completely
+	 * put into the FIFO, also enable the half empty interrupt
+	 */
+	if (i2c->nmsgs > 1 || xiic_tx_space(i2c))
+		xiic_irq_clr_en(i2c, XIIC_INTR_TX_HALF_MASK);
+
+}
+
+static void xiic_start_xfer(struct xiic_i2c *i2c)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&i2c->lock, flags);
+	xiic_reinit(i2c);
+	/* disable interrupts globally */
+	xiic_setreg32(i2c, XIIC_DGIER_OFFSET, 0);
+	spin_unlock_irqrestore(&i2c->lock, flags);
+
+	__xiic_start_xfer(i2c);
+	xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
+}
+
+static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+	struct xiic_i2c *i2c = i2c_get_adapdata(adap);
+	int err;
+
+	dev_dbg(adap->dev.parent, "%s entry SR: 0x%x\n", __func__,
+		xiic_getreg8(i2c, XIIC_SR_REG_OFFSET));
+
+	err = xiic_busy(i2c);
+	if (err)
+		return err;
+
+	i2c->tx_msg = msgs;
+	i2c->nmsgs = num;
+
+	xiic_start_xfer(i2c);
+
+	if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) ||
+		(i2c->state == STATE_DONE), HZ))
+		return (i2c->state == STATE_DONE) ? num : -EIO;
+	else {
+		i2c->tx_msg = NULL;
+		i2c->rx_msg = NULL;
+		i2c->nmsgs = 0;
+		return -ETIMEDOUT;
+	}
+}
+
+static u32 xiic_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm xiic_algorithm = {
+	.master_xfer	= xiic_xfer,
+	.functionality	= xiic_func,
+};
+
+static struct i2c_adapter xiic_adapter = {
+	.owner		= THIS_MODULE,
+	.name		= DRIVER_NAME,
+	.class		= I2C_CLASS_HWMON | I2C_CLASS_SPD,
+	.algo		= &xiic_algorithm,
+};
+
+
+static int __devinit xiic_i2c_probe(struct platform_device *pdev)
+{
+	struct xiic_i2c *i2c;
+	struct xiic_i2c_platform_data *pdata;
+	struct resource *res;
+	int ret, irq;
+	u8 i;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		goto resource_missing;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		goto resource_missing;
+
+	pdata = (struct xiic_i2c_platform_data *) pdev->dev.platform_data;
+	if (!pdata)
+		return -EINVAL;
+
+	i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
+	if (!i2c)
+		return -ENOMEM;
+
+	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
+		dev_err(&pdev->dev, "Memory region busy\n");
+		ret = -EBUSY;
+		goto request_mem_failed;
+	}
+
+	i2c->base = ioremap(res->start, resource_size(res));
+	if (!i2c->base) {
+		dev_err(&pdev->dev, "Unable to map registers\n");
+		ret = -EIO;
+		goto map_failed;
+	}
+
+	/* hook up driver to tree */
+	platform_set_drvdata(pdev, i2c);
+	i2c->adap = xiic_adapter;
+	i2c_set_adapdata(&i2c->adap, i2c);
+	i2c->adap.dev.parent = &pdev->dev;
+
+	xiic_reinit(i2c);
+
+	spin_lock_init(&i2c->lock);
+	init_waitqueue_head(&i2c->wait);
+	ret = request_irq(irq, xiic_isr, 0, pdev->name, i2c);
+	if (ret) {
+		dev_err(&pdev->dev, "Cannot claim IRQ\n");
+		goto request_irq_failed;
+	}
+
+	/* add i2c adapter to i2c tree */
+	ret = i2c_add_adapter(&i2c->adap);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to add adapter\n");
+		goto add_adapter_failed;
+	}
+
+	/* add in known devices to the bus */
+	for (i = 0; i < pdata->num_devices; i++)
+		i2c_new_device(&i2c->adap, pdata->devices + i);
+
+	return 0;
+
+add_adapter_failed:
+	free_irq(irq, i2c);
+request_irq_failed:
+	xiic_deinit(i2c);
+	iounmap(i2c->base);
+map_failed:
+	release_mem_region(res->start, resource_size(res));
+request_mem_failed:
+	kfree(i2c);
+
+	return ret;
+resource_missing:
+	dev_err(&pdev->dev, "IRQ or Memory resource is missing\n");
+	return -ENOENT;
+}
+
+static int __devexit xiic_i2c_remove(struct platform_device* pdev)
+{
+	struct xiic_i2c *i2c = platform_get_drvdata(pdev);
+	struct resource *res;
+
+	/* remove adapter & data */
+	i2c_del_adapter(&i2c->adap);
+
+	xiic_deinit(i2c);
+
+	platform_set_drvdata(pdev, NULL);
+
+	free_irq(platform_get_irq(pdev, 0), i2c);
+
+	iounmap(i2c->base);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res)
+		release_mem_region(res->start, resource_size(res));
+
+	kfree(i2c);
+
+	return 0;
+}
+
+
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:"DRIVER_NAME);
+
+static struct platform_driver xiic_i2c_driver = {
+	.probe   = xiic_i2c_probe,
+	.remove  = __devexit_p(xiic_i2c_remove),
+	.driver  = {
+		.owner = THIS_MODULE,
+		.name = DRIVER_NAME,
+	},
+};
+
+static int __init xiic_i2c_init(void)
+{
+	return platform_driver_register(&xiic_i2c_driver);
+}
+
+static void __exit xiic_i2c_exit(void)
+{
+	platform_driver_unregister(&xiic_i2c_driver);
+}
+
+module_init(xiic_i2c_init);
+module_exit(xiic_i2c_exit);
+
+MODULE_AUTHOR("info@mocean-labs.com");
+MODULE_DESCRIPTION("Xilinx I2C bus driver");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/Kconfig linux-libre-2.6.34-gnu1/drivers/i2c/busses/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -77,7 +77,7 @@ config I2C_AMD8111
 	  will be called i2c-amd8111.
 
 config I2C_I801
-	tristate "Intel 82801 (ICH)"
+	tristate "Intel 82801 (ICH/PCH)"
 	depends on PCI
 	help
 	  If you say yes to this option, support will be included for the Intel
@@ -97,7 +97,8 @@ config I2C_I801
 	    ICH9
 	    Tolapai
 	    ICH10
-	    PCH
+	    3400/5 Series (PCH)
+	    Cougar Point (PCH)
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-i801.
@@ -105,6 +106,8 @@ config I2C_I801
 config I2C_ISCH
 	tristate "Intel SCH SMBus 1.0"
 	depends on PCI
+	select MFD_CORE
+	select LPC_SCH
 	help
 	  Say Y here if you want to use SMBus controller on the Intel SCH
 	  based systems.
@@ -418,13 +421,12 @@ config I2C_IXP2000
 	  instead.
 
 config I2C_MPC
-	tristate "MPC107/824x/85xx/52xx/86xx"
+	tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
 	depends on PPC32
 	help
 	  If you say yes to this option, support will be included for the
-	  built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and
-	  MPC85xx/MPC8641 family processors. The driver may also work on 52xx
-	  family processors, though interrupts are known not to work.
+	  built-in I2C interface on the MPC107, Tsi107, MPC512x, MPC52xx,
+	  MPC8240, MPC8245, MPC83xx, MPC85xx and MPC8641 family processors.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-mpc.
@@ -439,6 +441,13 @@ config I2C_MV64XXX
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-mv64xxx.
 
+config I2C_NOMADIK
+	tristate "ST-Ericsson Nomadik/Ux500 I2C Controller"
+	depends on PLAT_NOMADIK
+	help
+	  If you say yes to this option, support will be included for the
+	  I2C interface from ST-Ericsson's Nomadik and Ux500 architectures.
+
 config I2C_OCORES
 	tristate "OpenCores I2C Controller"
 	depends on EXPERIMENTAL
@@ -564,12 +573,33 @@ config I2C_VERSATILE
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-versatile.
 
+config I2C_OCTEON
+	tristate "Cavium OCTEON I2C bus support"
+	depends on CPU_CAVIUM_OCTEON
+	help
+	  Say yes if you want to support the I2C serial bus on Cavium
+	  OCTEON SOC.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-octeon.
+
+config I2C_XILINX
+	tristate "Xilinx I2C Controller"
+	depends on EXPERIMENTAL && HAS_IOMEM
+	help
+	  If you say yes to this option, support will be included for the
+	  Xilinx I2C controller.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called xilinx_i2c.
+
 comment "External I2C/SMBus adapter drivers"
 
 config I2C_PARPORT
 	tristate "Parallel port adapter"
 	depends on PARPORT
 	select I2C_ALGOBIT
+	select I2C_SMBUS
 	help
 	  This supports parallel port I2C adapters such as the ones made by
 	  Philips or Velleman, Analog Devices evaluation boards, and more.
@@ -593,6 +623,7 @@ config I2C_PARPORT
 config I2C_PARPORT_LIGHT
 	tristate "Parallel port adapter (light)"
 	select I2C_ALGOBIT
+	select I2C_SMBUS
 	help
 	  This supports parallel port I2C adapters such as the ones made by
 	  Philips or Velleman, Analog Devices evaluation boards, and more.
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/Makefile linux-libre-2.6.34-gnu1/drivers/i2c/busses/Makefile
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@ obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
 obj-$(CONFIG_I2C_IXP2000)	+= i2c-ixp2000.o
 obj-$(CONFIG_I2C_MPC)		+= i2c-mpc.o
 obj-$(CONFIG_I2C_MV64XXX)	+= i2c-mv64xxx.o
+obj-$(CONFIG_I2C_NOMADIK)	+= i2c-nomadik.o
 obj-$(CONFIG_I2C_OCORES)	+= i2c-ocores.o
 obj-$(CONFIG_I2C_OMAP)		+= i2c-omap.o
 obj-$(CONFIG_I2C_PASEMI)	+= i2c-pasemi.o
@@ -54,6 +55,8 @@ obj-$(CONFIG_I2C_SH_MOBILE)	+= i2c-sh_mo
 obj-$(CONFIG_I2C_SIMTEC)	+= i2c-simtec.o
 obj-$(CONFIG_I2C_STU300)	+= i2c-stu300.o
 obj-$(CONFIG_I2C_VERSATILE)	+= i2c-versatile.o
+obj-$(CONFIG_I2C_OCTEON)	+= i2c-octeon.o
+obj-$(CONFIG_I2C_XILINX)	+= i2c-xiic.o
 
 # External I2C/SMBus adapter drivers
 obj-$(CONFIG_I2C_PARPORT)	+= i2c-parport.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/busses/scx200_acb.c linux-libre-2.6.34-gnu1/drivers/i2c/busses/scx200_acb.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/busses/scx200_acb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/busses/scx200_acb.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #include <linux/scx200.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/chips/Kconfig linux-libre-2.6.34-gnu1/drivers/i2c/chips/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/i2c/chips/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/chips/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,19 +0,0 @@
-#
-# Miscellaneous I2C chip drivers configuration
-#
-# *** DEPRECATED! Do not add new entries! See Makefile ***
-#
-
-menu "Miscellaneous I2C Chip support"
-
-config SENSORS_TSL2550
-	tristate "Taos TSL2550 ambient light sensor"
-	depends on EXPERIMENTAL
-	help
-	  If you say yes here you get support for the Taos TSL2550
-	  ambient light sensor.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called tsl2550.
-
-endmenu
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/chips/Makefile linux-libre-2.6.34-gnu1/drivers/i2c/chips/Makefile
--- linux-libre-2.6.33-gnu1/drivers/i2c/chips/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/chips/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,18 +0,0 @@
-#
-# Makefile for miscellaneous I2C chip drivers.
-#
-# Do not add new drivers to this directory! It is DEPRECATED.
-#
-# Device drivers are better grouped according to the functionality they
-# implement rather than to the bus they are connected to. In particular:
-# * Hardware monitoring chip drivers go to drivers/hwmon
-# * RTC chip drivers go to drivers/rtc
-# * I/O expander drivers go to drivers/gpio
-#
-
-obj-$(CONFIG_SENSORS_TSL2550)	+= tsl2550.o
-
-ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/chips/tsl2550.c linux-libre-2.6.34-gnu1/drivers/i2c/chips/tsl2550.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/chips/tsl2550.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/chips/tsl2550.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,473 +0,0 @@
-/*
- *  tsl2550.c - Linux kernel modules for ambient light sensor
- *
- *  Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
- *  Copyright (C) 2007 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>
-
-#define TSL2550_DRV_NAME	"tsl2550"
-#define DRIVER_VERSION		"1.2"
-
-/*
- * Defines
- */
-
-#define TSL2550_POWER_DOWN		0x00
-#define TSL2550_POWER_UP		0x03
-#define TSL2550_STANDARD_RANGE		0x18
-#define TSL2550_EXTENDED_RANGE		0x1d
-#define TSL2550_READ_ADC0		0x43
-#define TSL2550_READ_ADC1		0x83
-
-/*
- * Structs
- */
-
-struct tsl2550_data {
-	struct i2c_client *client;
-	struct mutex update_lock;
-
-	unsigned int power_state : 1;
-	unsigned int operating_mode : 1;
-};
-
-/*
- * Global data
- */
-
-static const u8 TSL2550_MODE_RANGE[2] = {
-	TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE,
-};
-
-/*
- * Management functions
- */
-
-static int tsl2550_set_operating_mode(struct i2c_client *client, int mode)
-{
-	struct tsl2550_data *data = i2c_get_clientdata(client);
-
-	int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]);
-
-	data->operating_mode = mode;
-
-	return ret;
-}
-
-static int tsl2550_set_power_state(struct i2c_client *client, int state)
-{
-	struct tsl2550_data *data = i2c_get_clientdata(client);
-	int ret;
-
-	if (state == 0)
-		ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN);
-	else {
-		ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
-
-		/* On power up we should reset operating mode also... */
-		tsl2550_set_operating_mode(client, data->operating_mode);
-	}
-
-	data->power_state = state;
-
-	return ret;
-}
-
-static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
-{
-	int ret;
-
-	ret = i2c_smbus_read_byte_data(client, cmd);
-	if (ret < 0)
-		return ret;
-	if (!(ret & 0x80))
-		return -EAGAIN;
-	return ret & 0x7f;	/* remove the "valid" bit */
-}
-
-/*
- * LUX calculation
- */
-
-#define	TSL2550_MAX_LUX		1846
-
-static const u8 ratio_lut[] = {
-	100, 100, 100, 100, 100, 100, 100, 100,
-	100, 100, 100, 100, 100, 100, 99, 99,
-	99, 99, 99, 99, 99, 99, 99, 99,
-	99, 99, 99, 98, 98, 98, 98, 98,
-	98, 98, 97, 97, 97, 97, 97, 96,
-	96, 96, 96, 95, 95, 95, 94, 94,
-	93, 93, 93, 92, 92, 91, 91, 90,
-	89, 89, 88, 87, 87, 86, 85, 84,
-	83, 82, 81, 80, 79, 78, 77, 75,
-	74, 73, 71, 69, 68, 66, 64, 62,
-	60, 58, 56, 54, 52, 49, 47, 44,
-	42, 41, 40, 40, 39, 39, 38, 38,
-	37, 37, 37, 36, 36, 36, 35, 35,
-	35, 35, 34, 34, 34, 34, 33, 33,
-	33, 33, 32, 32, 32, 32, 32, 31,
-	31, 31, 31, 31, 30, 30, 30, 30,
-	30,
-};
-
-static const u16 count_lut[] = {
-	0, 1, 2, 3, 4, 5, 6, 7,
-	8, 9, 10, 11, 12, 13, 14, 15,
-	16, 18, 20, 22, 24, 26, 28, 30,
-	32, 34, 36, 38, 40, 42, 44, 46,
-	49, 53, 57, 61, 65, 69, 73, 77,
-	81, 85, 89, 93, 97, 101, 105, 109,
-	115, 123, 131, 139, 147, 155, 163, 171,
-	179, 187, 195, 203, 211, 219, 227, 235,
-	247, 263, 279, 295, 311, 327, 343, 359,
-	375, 391, 407, 423, 439, 455, 471, 487,
-	511, 543, 575, 607, 639, 671, 703, 735,
-	767, 799, 831, 863, 895, 927, 959, 991,
-	1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
-	1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
-	2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
-	3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
-};
-
-/*
- * This function is described into Taos TSL2550 Designer's Notebook
- * pages 2, 3.
- */
-static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
-{
-	unsigned int lux;
-
-	/* Look up count from channel values */
-	u16 c0 = count_lut[ch0];
-	u16 c1 = count_lut[ch1];
-
-	/*
-	 * Calculate ratio.
-	 * Note: the "128" is a scaling factor
-	 */
-	u8 r = 128;
-
-	/* Avoid division by 0 and count 1 cannot be greater than count 0 */
-	if (c1 <= c0)
-		if (c0) {
-			r = c1 * 128 / c0;
-
-			/* Calculate LUX */
-			lux = ((c0 - c1) * ratio_lut[r]) / 256;
-		} else
-			lux = 0;
-	else
-		return -EAGAIN;
-
-	/* LUX range check */
-	return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
-}
-
-/*
- * SysFS support
- */
-
-static ssize_t tsl2550_show_power_state(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
-
-	return sprintf(buf, "%u\n", data->power_state);
-}
-
-static ssize_t tsl2550_store_power_state(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct tsl2550_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-	int ret;
-
-	if (val < 0 || val > 1)
-		return -EINVAL;
-
-	mutex_lock(&data->update_lock);
-	ret = tsl2550_set_power_state(client, val);
-	mutex_unlock(&data->update_lock);
-
-	if (ret < 0)
-		return ret;
-
-	return count;
-}
-
-static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
-		   tsl2550_show_power_state, tsl2550_store_power_state);
-
-static ssize_t tsl2550_show_operating_mode(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
-
-	return sprintf(buf, "%u\n", data->operating_mode);
-}
-
-static ssize_t tsl2550_store_operating_mode(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct tsl2550_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-	int ret;
-
-	if (val < 0 || val > 1)
-		return -EINVAL;
-
-	if (data->power_state == 0)
-		return -EBUSY;
-
-	mutex_lock(&data->update_lock);
-	ret = tsl2550_set_operating_mode(client, val);
-	mutex_unlock(&data->update_lock);
-
-	if (ret < 0)
-		return ret;
-
-	return count;
-}
-
-static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
-		   tsl2550_show_operating_mode, tsl2550_store_operating_mode);
-
-static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
-{
-	struct tsl2550_data *data = i2c_get_clientdata(client);
-	u8 ch0, ch1;
-	int ret;
-
-	ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
-	if (ret < 0)
-		return ret;
-	ch0 = ret;
-
-	ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
-	if (ret < 0)
-		return ret;
-	ch1 = ret;
-
-	/* Do the job */
-	ret = tsl2550_calculate_lux(ch0, ch1);
-	if (ret < 0)
-		return ret;
-	if (data->operating_mode == 1)
-		ret *= 5;
-
-	return sprintf(buf, "%d\n", ret);
-}
-
-static ssize_t tsl2550_show_lux1_input(struct device *dev,
-			struct device_attribute *attr, char *buf)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct tsl2550_data *data = i2c_get_clientdata(client);
-	int ret;
-
-	/* No LUX data if not operational */
-	if (!data->power_state)
-		return -EBUSY;
-
-	mutex_lock(&data->update_lock);
-	ret = __tsl2550_show_lux(client, buf);
-	mutex_unlock(&data->update_lock);
-
-	return ret;
-}
-
-static DEVICE_ATTR(lux1_input, S_IRUGO,
-		   tsl2550_show_lux1_input, NULL);
-
-static struct attribute *tsl2550_attributes[] = {
-	&dev_attr_power_state.attr,
-	&dev_attr_operating_mode.attr,
-	&dev_attr_lux1_input.attr,
-	NULL
-};
-
-static const struct attribute_group tsl2550_attr_group = {
-	.attrs = tsl2550_attributes,
-};
-
-/*
- * Initialization function
- */
-
-static int tsl2550_init_client(struct i2c_client *client)
-{
-	struct tsl2550_data *data = i2c_get_clientdata(client);
-	int err;
-
-	/*
-	 * Probe the chip. To do so we try to power up the device and then to
-	 * read back the 0x03 code
-	 */
-	err = i2c_smbus_read_byte_data(client, TSL2550_POWER_UP);
-	if (err < 0)
-		return err;
-	if (err != TSL2550_POWER_UP)
-		return -ENODEV;
-	data->power_state = 1;
-
-	/* Set the default operating mode */
-	err = i2c_smbus_write_byte(client,
-				   TSL2550_MODE_RANGE[data->operating_mode]);
-	if (err < 0)
-		return err;
-
-	return 0;
-}
-
-/*
- * I2C init/probing/exit functions
- */
-
-static struct i2c_driver tsl2550_driver;
-static int __devinit tsl2550_probe(struct i2c_client *client,
-				   const struct i2c_device_id *id)
-{
-	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-	struct tsl2550_data *data;
-	int *opmode, err = 0;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE
-					    | I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
-		err = -EIO;
-		goto exit;
-	}
-
-	data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
-	if (!data) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	data->client = client;
-	i2c_set_clientdata(client, data);
-
-	/* Check platform data */
-	opmode = client->dev.platform_data;
-	if (opmode) {
-		if (*opmode < 0 || *opmode > 1) {
-			dev_err(&client->dev, "invalid operating_mode (%d)\n",
-					*opmode);
-			err = -EINVAL;
-			goto exit_kfree;
-		}
-		data->operating_mode = *opmode;
-	} else
-		data->operating_mode = 0;	/* default mode is standard */
-	dev_info(&client->dev, "%s operating mode\n",
-			data->operating_mode ? "extended" : "standard");
-
-	mutex_init(&data->update_lock);
-
-	/* Initialize the TSL2550 chip */
-	err = tsl2550_init_client(client);
-	if (err)
-		goto exit_kfree;
-
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
-	if (err)
-		goto exit_kfree;
-
-	dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
-
-	return 0;
-
-exit_kfree:
-	kfree(data);
-exit:
-	return err;
-}
-
-static int __devexit tsl2550_remove(struct i2c_client *client)
-{
-	sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
-
-	/* Power down the device */
-	tsl2550_set_power_state(client, 0);
-
-	kfree(i2c_get_clientdata(client));
-
-	return 0;
-}
-
-#ifdef CONFIG_PM
-
-static int tsl2550_suspend(struct i2c_client *client, pm_message_t mesg)
-{
-	return tsl2550_set_power_state(client, 0);
-}
-
-static int tsl2550_resume(struct i2c_client *client)
-{
-	return tsl2550_set_power_state(client, 1);
-}
-
-#else
-
-#define tsl2550_suspend		NULL
-#define tsl2550_resume		NULL
-
-#endif /* CONFIG_PM */
-
-static const struct i2c_device_id tsl2550_id[] = {
-	{ "tsl2550", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, tsl2550_id);
-
-static struct i2c_driver tsl2550_driver = {
-	.driver = {
-		.name	= TSL2550_DRV_NAME,
-		.owner	= THIS_MODULE,
-	},
-	.suspend = tsl2550_suspend,
-	.resume	= tsl2550_resume,
-	.probe	= tsl2550_probe,
-	.remove	= __devexit_p(tsl2550_remove),
-	.id_table = tsl2550_id,
-};
-
-static int __init tsl2550_init(void)
-{
-	return i2c_add_driver(&tsl2550_driver);
-}
-
-static void __exit tsl2550_exit(void)
-{
-	i2c_del_driver(&tsl2550_driver);
-}
-
-MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
-MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
-
-module_init(tsl2550_init);
-module_exit(tsl2550_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/i2c-boardinfo.c linux-libre-2.6.34-gnu1/drivers/i2c/i2c-boardinfo.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/i2c-boardinfo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/i2c-boardinfo.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 
 #include <linux/kernel.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/rwsem.h>
 
 #include "i2c-core.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/i2c-core.c linux-libre-2.6.34-gnu1/drivers/i2c/i2c-core.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/i2c-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/i2c-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,17 +34,17 @@
 #include <linux/hardirq.h>
 #include <linux/irqflags.h>
 #include <linux/rwsem.h>
+#include <linux/pm_runtime.h>
 #include <asm/uaccess.h>
 
 #include "i2c-core.h"
 
 
-/* core_lock protects i2c_adapter_idr, userspace_devices, and guarantees
+/* core_lock protects i2c_adapter_idr, and guarantees
    that device detection, deletion of detected devices, and attach_adapter
    and detach_adapter calls are serialized */
 static DEFINE_MUTEX(core_lock);
 static DEFINE_IDR(i2c_adapter_idr);
-static LIST_HEAD(userspace_devices);
 
 static struct device_type i2c_client_type;
 static int i2c_check_addr(struct i2c_adapter *adapter, int addr);
@@ -116,8 +116,10 @@ static int i2c_device_probe(struct devic
 	dev_dbg(dev, "probe\n");
 
 	status = driver->probe(client, i2c_match_id(driver->id_table, client));
-	if (status)
+	if (status) {
 		client->driver = NULL;
+		i2c_set_clientdata(client, NULL);
+	}
 	return status;
 }
 
@@ -138,8 +140,10 @@ static int i2c_device_remove(struct devi
 		dev->driver = NULL;
 		status = 0;
 	}
-	if (status == 0)
+	if (status == 0) {
 		client->driver = NULL;
+		i2c_set_clientdata(client, NULL);
+	}
 	return status;
 }
 
@@ -184,6 +188,52 @@ static int i2c_device_pm_resume(struct d
 #define i2c_device_pm_resume	NULL
 #endif
 
+#ifdef CONFIG_PM_RUNTIME
+static int i2c_device_runtime_suspend(struct device *dev)
+{
+	const struct dev_pm_ops *pm;
+
+	if (!dev->driver)
+		return 0;
+	pm = dev->driver->pm;
+	if (!pm || !pm->runtime_suspend)
+		return 0;
+	return pm->runtime_suspend(dev);
+}
+
+static int i2c_device_runtime_resume(struct device *dev)
+{
+	const struct dev_pm_ops *pm;
+
+	if (!dev->driver)
+		return 0;
+	pm = dev->driver->pm;
+	if (!pm || !pm->runtime_resume)
+		return 0;
+	return pm->runtime_resume(dev);
+}
+
+static int i2c_device_runtime_idle(struct device *dev)
+{
+	const struct dev_pm_ops *pm = NULL;
+	int ret;
+
+	if (dev->driver)
+		pm = dev->driver->pm;
+	if (pm && pm->runtime_idle) {
+		ret = pm->runtime_idle(dev);
+		if (ret)
+			return ret;
+	}
+
+	return pm_runtime_suspend(dev);
+}
+#else
+#define i2c_device_runtime_suspend	NULL
+#define i2c_device_runtime_resume	NULL
+#define i2c_device_runtime_idle		NULL
+#endif
+
 static int i2c_device_suspend(struct device *dev, pm_message_t mesg)
 {
 	struct i2c_client *client = i2c_verify_client(dev);
@@ -251,6 +301,9 @@ static const struct attribute_group *i2c
 static const struct dev_pm_ops i2c_device_pm_ops = {
 	.suspend = i2c_device_pm_suspend,
 	.resume = i2c_device_pm_resume,
+	.runtime_suspend = i2c_device_runtime_suspend,
+	.runtime_resume = i2c_device_runtime_resume,
+	.runtime_idle = i2c_device_runtime_idle,
 };
 
 struct bus_type i2c_bus_type = {
@@ -488,9 +541,9 @@ i2c_sysfs_new_device(struct device *dev,
 		return -EEXIST;
 
 	/* Keep track of the added device */
-	mutex_lock(&core_lock);
-	list_add_tail(&client->detected, &userspace_devices);
-	mutex_unlock(&core_lock);
+	i2c_lock_adapter(adap);
+	list_add_tail(&client->detected, &adap->userspace_clients);
+	i2c_unlock_adapter(adap);
 	dev_info(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device",
 		 info.type, info.addr);
 
@@ -529,9 +582,10 @@ i2c_sysfs_delete_device(struct device *d
 
 	/* Make sure the device was added through sysfs */
 	res = -ENOENT;
-	mutex_lock(&core_lock);
-	list_for_each_entry_safe(client, next, &userspace_devices, detected) {
-		if (client->addr == addr && client->adapter == adap) {
+	i2c_lock_adapter(adap);
+	list_for_each_entry_safe(client, next, &adap->userspace_clients,
+				 detected) {
+		if (client->addr == addr) {
 			dev_info(dev, "%s: Deleting device %s at 0x%02hx\n",
 				 "delete_device", client->name, client->addr);
 
@@ -541,7 +595,7 @@ i2c_sysfs_delete_device(struct device *d
 			break;
 		}
 	}
-	mutex_unlock(&core_lock);
+	i2c_unlock_adapter(adap);
 
 	if (res < 0)
 		dev_err(dev, "%s: Can't find device in list\n",
@@ -623,6 +677,7 @@ static int i2c_register_adapter(struct i
 	}
 
 	rt_mutex_init(&adap->bus_lock);
+	INIT_LIST_HEAD(&adap->userspace_clients);
 
 	/* Set default timeout to 1 second if not already set */
 	if (adap->timeout == 0)
@@ -825,14 +880,15 @@ int i2c_del_adapter(struct i2c_adapter *
 		return res;
 
 	/* Remove devices instantiated from sysfs */
-	list_for_each_entry_safe(client, next, &userspace_devices, detected) {
-		if (client->adapter == adap) {
-			dev_dbg(&adap->dev, "Removing %s at 0x%x\n",
-				client->name, client->addr);
-			list_del(&client->detected);
-			i2c_unregister_device(client);
-		}
+	i2c_lock_adapter(adap);
+	list_for_each_entry_safe(client, next, &adap->userspace_clients,
+				 detected) {
+		dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name,
+			client->addr);
+		list_del(&client->detected);
+		i2c_unregister_device(client);
 	}
+	i2c_unlock_adapter(adap);
 
 	/* Detach any active clients. This can't fail, thus we do not
 	   checking the returned value. */
@@ -1133,7 +1189,7 @@ EXPORT_SYMBOL(i2c_transfer);
  * i2c_master_send - issue a single I2C message in master transmit mode
  * @client: Handle to slave device
  * @buf: Data that will be written to the slave
- * @count: How many bytes to write
+ * @count: How many bytes to write, must be less than 64k since msg.len is u16
  *
  * Returns negative errno, or else the number of bytes written.
  */
@@ -1160,7 +1216,7 @@ EXPORT_SYMBOL(i2c_master_send);
  * i2c_master_recv - issue a single I2C message in master receive mode
  * @client: Handle to slave device
  * @buf: Where to store data read from slave
- * @count: How many bytes to read
+ * @count: How many bytes to read, must be less than 64k since msg.len is u16
  *
  * Returns negative errno, or else the number of bytes read.
  */
@@ -1210,12 +1266,23 @@ static int i2c_detect_address(struct i2c
 		return 0;
 
 	/* Make sure there is something at this address */
-	if (i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) < 0)
-		return 0;
+	if (addr == 0x73 && (adapter->class & I2C_CLASS_HWMON)) {
+		/* Special probe for FSC hwmon chips */
+		union i2c_smbus_data dummy;
 
-	/* Prevent 24RF08 corruption */
-	if ((addr & ~0x0f) == 0x50)
-		i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL);
+		if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_READ, 0,
+				   I2C_SMBUS_BYTE_DATA, &dummy) < 0)
+			return 0;
+	} else {
+		if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0,
+				   I2C_SMBUS_QUICK, NULL) < 0)
+			return 0;
+
+		/* Prevent 24RF08 corruption */
+		if ((addr & ~0x0f) == 0x50)
+			i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0,
+				       I2C_SMBUS_QUICK, NULL);
+	}
 
 	/* Finally call the custom detection function */
 	memset(&info, 0, sizeof(struct i2c_board_info));
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/i2c-smbus.c linux-libre-2.6.34-gnu1/drivers/i2c/i2c-smbus.c
--- linux-libre-2.6.33-gnu1/drivers/i2c/i2c-smbus.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/i2c-smbus.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,263 @@
+/*
+ * i2c-smbus.c - SMBus extensions to the I2C protocol
+ *
+ * Copyright (C) 2008 David Brownell
+ * Copyright (C) 2010 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/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/i2c.h>
+#include <linux/i2c-smbus.h>
+#include <linux/slab.h>
+
+struct i2c_smbus_alert {
+	unsigned int		alert_edge_triggered:1;
+	int			irq;
+	struct work_struct	alert;
+	struct i2c_client	*ara;		/* Alert response address */
+};
+
+struct alert_data {
+	unsigned short		addr;
+	u8			flag:1;
+};
+
+/* If this is the alerting device, notify its driver */
+static int smbus_do_alert(struct device *dev, void *addrp)
+{
+	struct i2c_client *client = i2c_verify_client(dev);
+	struct alert_data *data = addrp;
+
+	if (!client || client->addr != data->addr)
+		return 0;
+	if (client->flags & I2C_CLIENT_TEN)
+		return 0;
+
+	/*
+	 * Drivers should either disable alerts, or provide at least
+	 * a minimal handler.  Lock so client->driver won't change.
+	 */
+	device_lock(dev);
+	if (client->driver) {
+		if (client->driver->alert)
+			client->driver->alert(client, data->flag);
+		else
+			dev_warn(&client->dev, "no driver alert()!\n");
+	} else
+		dev_dbg(&client->dev, "alert with no driver\n");
+	device_unlock(dev);
+
+	/* Stop iterating after we find the device */
+	return -EBUSY;
+}
+
+/*
+ * The alert IRQ handler needs to hand work off to a task which can issue
+ * SMBus calls, because those sleeping calls can't be made in IRQ context.
+ */
+static void smbus_alert(struct work_struct *work)
+{
+	struct i2c_smbus_alert *alert;
+	struct i2c_client *ara;
+	unsigned short prev_addr = 0;	/* Not a valid address */
+
+	alert = container_of(work, struct i2c_smbus_alert, alert);
+	ara = alert->ara;
+
+	for (;;) {
+		s32 status;
+		struct alert_data data;
+
+		/*
+		 * Devices with pending alerts reply in address order, low
+		 * to high, because of slave transmit arbitration.  After
+		 * responding, an SMBus device stops asserting SMBALERT#.
+		 *
+		 * Note that SMBus 2.0 reserves 10-bit addresess for future
+		 * use.  We neither handle them, nor try to use PEC here.
+		 */
+		status = i2c_smbus_read_byte(ara);
+		if (status < 0)
+			break;
+
+		data.flag = status & 1;
+		data.addr = status >> 1;
+
+		if (data.addr == prev_addr) {
+			dev_warn(&ara->dev, "Duplicate SMBALERT# from dev "
+				"0x%02x, skipping\n", data.addr);
+			break;
+		}
+		dev_dbg(&ara->dev, "SMBALERT# from dev 0x%02x, flag %d\n",
+			data.addr, data.flag);
+
+		/* Notify driver for the device which issued the alert */
+		device_for_each_child(&ara->adapter->dev, &data,
+				      smbus_do_alert);
+		prev_addr = data.addr;
+	}
+
+	/* We handled all alerts; re-enable level-triggered IRQs */
+	if (!alert->alert_edge_triggered)
+		enable_irq(alert->irq);
+}
+
+static irqreturn_t smbalert_irq(int irq, void *d)
+{
+	struct i2c_smbus_alert *alert = d;
+
+	/* Disable level-triggered IRQs until we handle them */
+	if (!alert->alert_edge_triggered)
+		disable_irq_nosync(irq);
+
+	schedule_work(&alert->alert);
+	return IRQ_HANDLED;
+}
+
+/* Setup SMBALERT# infrastructure */
+static int smbalert_probe(struct i2c_client *ara,
+			  const struct i2c_device_id *id)
+{
+	struct i2c_smbus_alert_setup *setup = ara->dev.platform_data;
+	struct i2c_smbus_alert *alert;
+	struct i2c_adapter *adapter = ara->adapter;
+	int res;
+
+	alert = kzalloc(sizeof(struct i2c_smbus_alert), GFP_KERNEL);
+	if (!alert)
+		return -ENOMEM;
+
+	alert->alert_edge_triggered = setup->alert_edge_triggered;
+	alert->irq = setup->irq;
+	INIT_WORK(&alert->alert, smbus_alert);
+	alert->ara = ara;
+
+	if (setup->irq > 0) {
+		res = devm_request_irq(&ara->dev, setup->irq, smbalert_irq,
+				       0, "smbus_alert", alert);
+		if (res) {
+			kfree(alert);
+			return res;
+		}
+	}
+
+	i2c_set_clientdata(ara, alert);
+	dev_info(&adapter->dev, "supports SMBALERT#, %s trigger\n",
+		 setup->alert_edge_triggered ? "edge" : "level");
+
+	return 0;
+}
+
+/* IRQ resource is managed so it is freed automatically */
+static int smbalert_remove(struct i2c_client *ara)
+{
+	struct i2c_smbus_alert *alert = i2c_get_clientdata(ara);
+
+	cancel_work_sync(&alert->alert);
+
+	i2c_set_clientdata(ara, NULL);
+	kfree(alert);
+	return 0;
+}
+
+static const struct i2c_device_id smbalert_ids[] = {
+	{ "smbus_alert", 0 },
+	{ /* LIST END */ }
+};
+MODULE_DEVICE_TABLE(i2c, smbalert_ids);
+
+static struct i2c_driver smbalert_driver = {
+	.driver = {
+		.name	= "smbus_alert",
+	},
+	.probe		= smbalert_probe,
+	.remove		= smbalert_remove,
+	.id_table	= smbalert_ids,
+};
+
+/**
+ * i2c_setup_smbus_alert - Setup SMBus alert support
+ * @adapter: the target adapter
+ * @setup: setup data for the SMBus alert handler
+ * Context: can sleep
+ *
+ * Setup handling of the SMBus alert protocol on a given I2C bus segment.
+ *
+ * Handling can be done either through our IRQ handler, or by the
+ * adapter (from its handler, periodic polling, or whatever).
+ *
+ * NOTE that if we manage the IRQ, we *MUST* know if it's level or
+ * edge triggered in order to hand it to the workqueue correctly.
+ * If triggering the alert seems to wedge the system, you probably
+ * should have said it's level triggered.
+ *
+ * This returns the ara client, which should be saved for later use with
+ * i2c_handle_smbus_alert() and ultimately i2c_unregister_device(); or NULL
+ * to indicate an error.
+ */
+struct i2c_client *i2c_setup_smbus_alert(struct i2c_adapter *adapter,
+					 struct i2c_smbus_alert_setup *setup)
+{
+	struct i2c_board_info ara_board_info = {
+		I2C_BOARD_INFO("smbus_alert", 0x0c),
+		.platform_data = setup,
+	};
+
+	return i2c_new_device(adapter, &ara_board_info);
+}
+EXPORT_SYMBOL_GPL(i2c_setup_smbus_alert);
+
+/**
+ * i2c_handle_smbus_alert - Handle an SMBus alert
+ * @ara: the ARA client on the relevant adapter
+ * Context: can't sleep
+ *
+ * Helper function to be called from an I2C bus driver's interrupt
+ * handler. It will schedule the alert work, in turn calling the
+ * corresponding I2C device driver's alert function.
+ *
+ * It is assumed that ara is a valid i2c client previously returned by
+ * i2c_setup_smbus_alert().
+ */
+int i2c_handle_smbus_alert(struct i2c_client *ara)
+{
+	struct i2c_smbus_alert *alert = i2c_get_clientdata(ara);
+
+	return schedule_work(&alert->alert);
+}
+EXPORT_SYMBOL_GPL(i2c_handle_smbus_alert);
+
+static int __init i2c_smbus_init(void)
+{
+	return i2c_add_driver(&smbalert_driver);
+}
+
+static void __exit i2c_smbus_exit(void)
+{
+	i2c_del_driver(&smbalert_driver);
+}
+
+module_init(i2c_smbus_init);
+module_exit(i2c_smbus_exit);
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("SMBus protocol extensions support");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/Kconfig linux-libre-2.6.34-gnu1/drivers/i2c/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/i2c/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -61,9 +61,18 @@ config I2C_HELPER_AUTO
 
 	  In doubt, say Y.
 
+config I2C_SMBUS
+	tristate "SMBus-specific protocols" if !I2C_HELPER_AUTO
+	help
+	  Say Y here if you want support for SMBus extensions to the I2C
+	  specification. At the moment, the only supported extension is
+	  the SMBus alert protocol.
+
+	  This support is also available as a module.  If so, the module
+	  will be called i2c-smbus.
+
 source drivers/i2c/algos/Kconfig
 source drivers/i2c/busses/Kconfig
-source drivers/i2c/chips/Kconfig
 
 config I2C_DEBUG_CORE
 	bool "I2C Core debugging messages"
@@ -87,13 +96,5 @@ config I2C_DEBUG_BUS
 	  debug messages to the system log.  Select this if you are having
 	  a problem with I2C support and want to see more of what is going
 	  on.
-
-config I2C_DEBUG_CHIP
-	bool "I2C Chip debugging messages"
-	help
-	  Say Y here if you want the I2C chip drivers to produce a bunch of
-	  debug messages to the system log.  Select this if you are having
-	  a problem with I2C support and want to see more of what is going
-	  on.
 
 endif # I2C
diff -druNp linux-libre-2.6.33-gnu1/drivers/i2c/Makefile linux-libre-2.6.34-gnu1/drivers/i2c/Makefile
--- linux-libre-2.6.33-gnu1/drivers/i2c/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/i2c/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -4,8 +4,9 @@
 
 obj-$(CONFIG_I2C_BOARDINFO)	+= i2c-boardinfo.o
 obj-$(CONFIG_I2C)		+= i2c-core.o
+obj-$(CONFIG_I2C_SMBUS)		+= i2c-smbus.o
 obj-$(CONFIG_I2C_CHARDEV)	+= i2c-dev.o
-obj-y				+= busses/ chips/ algos/
+obj-y				+= algos/ busses/
 
 ifeq ($(CONFIG_I2C_DEBUG_CORE),y)
 EXTRA_CFLAGS += -DDEBUG
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/aec62xx.c linux-libre-2.6.34-gnu1/drivers/ide/aec62xx.c
--- linux-libre-2.6.33-gnu1/drivers/ide/aec62xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/aec62xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -81,15 +81,15 @@ static u8 pci_bus_clock_list_ultra (u8 s
 	return chipset_table->ultra_settings;
 }
 
-static void aec6210_set_mode(ide_drive_t *drive, const u8 speed)
+static void aec6210_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	struct ide_host *host	= pci_get_drvdata(dev);
 	struct chipset_bus_clock_list_entry *bus_clock = host->host_priv;
 	u16 d_conf		= 0;
 	u8 ultra = 0, ultra_conf = 0;
 	u8 tmp0 = 0, tmp1 = 0, tmp2 = 0;
+	const u8 speed = drive->dma_mode;
 	unsigned long flags;
 
 	local_irq_save(flags);
@@ -109,15 +109,15 @@ static void aec6210_set_mode(ide_drive_t
 	local_irq_restore(flags);
 }
 
-static void aec6260_set_mode(ide_drive_t *drive, const u8 speed)
+static void aec6260_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	struct ide_host *host	= pci_get_drvdata(dev);
 	struct chipset_bus_clock_list_entry *bus_clock = host->host_priv;
 	u8 unit			= drive->dn & 1;
 	u8 tmp1 = 0, tmp2 = 0;
 	u8 ultra = 0, drive_conf = 0, ultra_conf = 0;
+	const u8 speed = drive->dma_mode;
 	unsigned long flags;
 
 	local_irq_save(flags);
@@ -134,9 +134,10 @@ static void aec6260_set_mode(ide_drive_t
 	local_irq_restore(flags);
 }
 
-static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void aec_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	drive->hwif->port_ops->set_dma_mode(drive, pio + XFER_PIO_0);
+	drive->dma_mode = drive->pio_mode;
+	hwif->port_ops->set_dma_mode(hwif, drive);
 }
 
 static int init_chipset_aec62xx(struct pci_dev *dev)
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ali14xx.c linux-libre-2.6.34-gnu1/drivers/ide/ali14xx.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ali14xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ali14xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -109,13 +109,14 @@ static DEFINE_SPINLOCK(ali14xx_lock);
  * This function computes timing parameters
  * and sets controller registers accordingly.
  */
-static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void ali14xx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	int driveNum;
 	int time1, time2;
 	u8 param1, param2, param3, param4;
 	unsigned long flags;
 	int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 	struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
 
 	/* calculate timing, according to PIO mode */
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/alim15x3.c linux-libre-2.6.34-gnu1/drivers/ide/alim15x3.c
--- linux-libre-2.6.33-gnu1/drivers/ide/alim15x3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/alim15x3.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,7 @@
  *  Copyright (C) 2002 Alan Cox
  *  ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw>
  *  Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
- *  Copyright (C) 2007 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+ *  Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
  *
  *  (U)DMA capable version of ali 1533/1543(C), 1535(D)
  *
@@ -48,61 +48,84 @@ static u8 m5229_revision;
 static u8 chip_is_1543c_e;
 static struct pci_dev *isa_dev;
 
+static void ali_fifo_control(ide_hwif_t *hwif, ide_drive_t *drive, int on)
+{
+	struct pci_dev *pdev = to_pci_dev(hwif->dev);
+	int pio_fifo = 0x54 + hwif->channel;
+	u8 fifo;
+	int shift = 4 * (drive->dn & 1);
+
+	pci_read_config_byte(pdev, pio_fifo, &fifo);
+	fifo &= ~(0x0F << shift);
+	fifo |= (on << shift);
+	pci_write_config_byte(pdev, pio_fifo, fifo);
+}
+
+static void ali_program_timings(ide_hwif_t *hwif, ide_drive_t *drive,
+				struct ide_timing *t, u8 ultra)
+{
+	struct pci_dev *dev = to_pci_dev(hwif->dev);
+	int port = hwif->channel ? 0x5c : 0x58;
+	int udmat = 0x56 + hwif->channel;
+	u8 unit = drive->dn & 1, udma;
+	int shift = 4 * unit;
+
+	/* Set up the UDMA */
+	pci_read_config_byte(dev, udmat, &udma);
+	udma &= ~(0x0F << shift);
+	udma |= ultra << shift;
+	pci_write_config_byte(dev, udmat, udma);
+
+	if (t == NULL)
+		return;
+
+	t->setup = clamp_val(t->setup, 1, 8) & 7;
+	t->act8b = clamp_val(t->act8b, 1, 8) & 7;
+	t->rec8b = clamp_val(t->rec8b, 1, 16) & 15;
+	t->active = clamp_val(t->active, 1, 8) & 7;
+	t->recover = clamp_val(t->recover, 1, 16) & 15;
+
+	pci_write_config_byte(dev, port, t->setup);
+	pci_write_config_byte(dev, port + 1, (t->act8b << 4) | t->rec8b);
+	pci_write_config_byte(dev, port + unit + 2,
+			      (t->active << 4) | t->recover);
+}
+
 /**
  *	ali_set_pio_mode	-	set host controller for PIO mode
+ *	@hwif: port
  *	@drive: drive
- *	@pio: PIO mode number
  *
  *	Program the controller for the given PIO mode.
  */
 
-static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void ali_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
-	struct pci_dev *dev = to_pci_dev(hwif->dev);
-	struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
-	int s_time = t->setup, a_time = t->active, c_time = t->cycle;
-	u8 s_clc, a_clc, r_clc;
-	unsigned long flags;
+	ide_drive_t *pair = ide_get_pair_dev(drive);
 	int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
-	int port = hwif->channel ? 0x5c : 0x58;
-	int portFIFO = hwif->channel ? 0x55 : 0x54;
-	u8 cd_dma_fifo = 0, unit = drive->dn & 1;
+	unsigned long T =  1000000 / bus_speed; /* PCI clock based */
+	struct ide_timing t;
 
-	if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8)
-		s_clc = 0;
-	if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8)
-		a_clc = 0;
+	ide_timing_compute(drive, drive->pio_mode, &t, T, 1);
+	if (pair) {
+		struct ide_timing p;
 
-	if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) {
-		r_clc = 1;
-	} else {
-		if (r_clc >= 16)
-			r_clc = 0;
+		ide_timing_compute(pair, pair->pio_mode, &p, T, 1);
+		ide_timing_merge(&p, &t, &t,
+			IDE_TIMING_SETUP | IDE_TIMING_8BIT);
+		if (pair->dma_mode) {
+			ide_timing_compute(pair, pair->dma_mode, &p, T, 1);
+			ide_timing_merge(&p, &t, &t,
+				IDE_TIMING_SETUP | IDE_TIMING_8BIT);
+		}
 	}
-	local_irq_save(flags);
-	
+
 	/* 
 	 * PIO mode => ATA FIFO on, ATAPI FIFO off
 	 */
-	pci_read_config_byte(dev, portFIFO, &cd_dma_fifo);
-	if (drive->media==ide_disk) {
-		if (unit) {
-			pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0x0F) | 0x50);
-		} else {
-			pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0xF0) | 0x05);
-		}
-	} else {
-		if (unit) {
-			pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0x0F);
-		} else {
-			pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0xF0);
-		}
-	}
-	
-	pci_write_config_byte(dev, port, s_clc);
-	pci_write_config_byte(dev, port + unit + 2, (a_clc << 4) | r_clc);
-	local_irq_restore(flags);
+	ali_fifo_control(hwif, drive, (drive->media == ide_disk) ? 0x05 : 0x00);
+
+	ali_program_timings(hwif, drive, &t, 0);
 }
 
 /**
@@ -132,44 +155,42 @@ static u8 ali_udma_filter(ide_drive_t *d
 
 /**
  *	ali_set_dma_mode	-	set host controller for DMA mode
+ *	@hwif: port
  *	@drive: drive
- *	@speed: DMA mode
  *
  *	Configure the hardware for the desired IDE transfer mode.
  */
 
-static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void ali_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
+	static u8 udma_timing[7] = { 0xC, 0xB, 0xA, 0x9, 0x8, 0xF, 0xD };
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
-	u8 speed1		= speed;
-	u8 unit			= drive->dn & 1;
+	ide_drive_t *pair	= ide_get_pair_dev(drive);
+	int bus_speed		= ide_pci_clk ? ide_pci_clk : 33;
+	unsigned long T		=  1000000 / bus_speed; /* PCI clock based */
+	const u8 speed		= drive->dma_mode;
 	u8 tmpbyte		= 0x00;
-	int m5229_udma		= (hwif->channel) ? 0x57 : 0x56;
-
-	if (speed == XFER_UDMA_6)
-		speed1 = 0x47;
+	struct ide_timing t;
 
 	if (speed < XFER_UDMA_0) {
-		u8 ultra_enable	= (unit) ? 0x7f : 0xf7;
-		/*
-		 * clear "ultra enable" bit
-		 */
-		pci_read_config_byte(dev, m5229_udma, &tmpbyte);
-		tmpbyte &= ultra_enable;
-		pci_write_config_byte(dev, m5229_udma, tmpbyte);
+		ide_timing_compute(drive, drive->dma_mode, &t, T, 1);
+		if (pair) {
+			struct ide_timing p;
 
-		/*
-		 * FIXME: Oh, my... DMA timings are never set.
-		 */
+			ide_timing_compute(pair, pair->pio_mode, &p, T, 1);
+			ide_timing_merge(&p, &t, &t,
+				IDE_TIMING_SETUP | IDE_TIMING_8BIT);
+			if (pair->dma_mode) {
+				ide_timing_compute(pair, pair->dma_mode,
+						&p, T, 1);
+				ide_timing_merge(&p, &t, &t,
+					IDE_TIMING_SETUP | IDE_TIMING_8BIT);
+			}
+		}
+		ali_program_timings(hwif, drive, &t, 0);
 	} else {
-		pci_read_config_byte(dev, m5229_udma, &tmpbyte);
-		tmpbyte &= (0x0f << ((1-unit) << 2));
-		/*
-		 * enable ultra dma and set timing
-		 */
-		tmpbyte |= ((0x08 | ((4-speed1)&0x07)) << (unit << 2));
-		pci_write_config_byte(dev, m5229_udma, tmpbyte);
+		ali_program_timings(hwif, drive, NULL,
+				udma_timing[speed - XFER_UDMA_0]);
 		if (speed >= XFER_UDMA_3) {
 			pci_read_config_byte(dev, 0x4b, &tmpbyte);
 			tmpbyte |= 1;
@@ -355,19 +376,13 @@ static int ali_cable_override(struct pci
  *
  *	This checks if the controller and the cable are capable
  *	of UDMA66 transfers. It doesn't check the drives.
- *	But see note 2 below!
- *
- *	FIXME: frobs bits that are not defined on newer ALi devicea
  */
 
 static u8 ali_cable_detect(ide_hwif_t *hwif)
 {
 	struct pci_dev *dev = to_pci_dev(hwif->dev);
-	unsigned long flags;
 	u8 cbl = ATA_CBL_PATA40, tmpbyte;
 
-	local_irq_save(flags);
-
 	if (m5229_revision >= 0xC2) {
 		/*
 		 * m5229 80-pin cable detection (from Host View)
@@ -387,8 +402,6 @@ static u8 ali_cable_detect(ide_hwif_t *h
 		}
 	}
 
-	local_irq_restore(flags);
-
 	return cbl;
 }
 
@@ -584,6 +597,6 @@ static void __exit ali15x3_ide_exit(void
 module_init(ali15x3_ide_init);
 module_exit(ali15x3_ide_exit);
 
-MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox");
+MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox, Bartlomiej Zolnierkiewicz");
 MODULE_DESCRIPTION("PCI driver module for ALi 15x3 IDE");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/amd74xx.c linux-libre-2.6.34-gnu1/drivers/ide/amd74xx.c
--- linux-libre-2.6.33-gnu1/drivers/ide/amd74xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/amd74xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,7 @@
  * IDE driver for Linux.
  *
  * Copyright (c) 2000-2002 Vojtech Pavlik
- * Copyright (c) 2007-2008 Bartlomiej Zolnierkiewicz
+ * Copyright (c) 2007-2010 Bartlomiej Zolnierkiewicz
  *
  * Based on the work of:
  *      Andre Hedrick
@@ -70,7 +70,8 @@ static void amd_set_speed(struct pci_dev
 	default: return;
 	}
 
-	pci_write_config_byte(dev, AMD_UDMA_TIMING + offset + (3 - dn), t);
+	if (timing->udma)
+		pci_write_config_byte(dev, AMD_UDMA_TIMING + offset + 3 - dn, t);
 }
 
 /*
@@ -78,14 +79,14 @@ static void amd_set_speed(struct pci_dev
  * to a desired transfer mode.  It also can be called by upper layers.
  */
 
-static void amd_set_drive(ide_drive_t *drive, const u8 speed)
+static void amd_set_drive(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	struct pci_dev *dev = to_pci_dev(hwif->dev);
 	ide_drive_t *peer = ide_get_pair_dev(drive);
 	struct ide_timing t, p;
 	int T, UT;
 	u8 udma_mask = hwif->ultra_mask;
+	const u8 speed = drive->dma_mode;
 
 	T = 1000000000 / amd_clock;
 	UT = (udma_mask == ATA_UDMA2) ? T : (T / 2);
@@ -93,7 +94,7 @@ static void amd_set_drive(ide_drive_t *d
 	ide_timing_compute(drive, speed, &t, T, UT);
 
 	if (peer) {
-		ide_timing_compute(peer, peer->current_speed, &p, T, UT);
+		ide_timing_compute(peer, peer->pio_mode, &p, T, UT);
 		ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
 	}
 
@@ -107,9 +108,10 @@ static void amd_set_drive(ide_drive_t *d
  * amd_set_pio_mode() is a callback from upper layers for PIO-only tuning.
  */
 
-static void amd_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void amd_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	amd_set_drive(drive, XFER_PIO_0 + pio);
+	drive->dma_mode = drive->pio_mode;
+	amd_set_drive(hwif, drive);
 }
 
 static void amd7409_cable_detect(struct pci_dev *dev)
@@ -340,6 +342,6 @@ static void __exit amd74xx_ide_exit(void
 module_init(amd74xx_ide_init);
 module_exit(amd74xx_ide_exit);
 
-MODULE_AUTHOR("Vojtech Pavlik");
+MODULE_AUTHOR("Vojtech Pavlik, Bartlomiej Zolnierkiewicz");
 MODULE_DESCRIPTION("AMD PCI IDE driver");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/at91_ide.c linux-libre-2.6.34-gnu1/drivers/ide/at91_ide.c
--- linux-libre-2.6.33-gnu1/drivers/ide/at91_ide.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/at91_ide.c	2010-05-16 17:17:36.000000000 -0400
@@ -172,11 +172,12 @@ static void at91_ide_output_data(ide_dri
 	leave_16bit(chipselect, mode);
 }
 
-static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void at91_ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	struct ide_timing *timing;
-	u8 chipselect = drive->hwif->select_data;
+	u8 chipselect = hwif->select_data;
 	int use_iordy = 0;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 
 	pdbg("chipselect %u pio %u\n", chipselect, pio);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/atiixp.c linux-libre-2.6.34-gnu1/drivers/ide/atiixp.c
--- linux-libre-2.6.33-gnu1/drivers/ide/atiixp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/atiixp.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,19 +42,20 @@ static DEFINE_SPINLOCK(atiixp_lock);
 
 /**
  *	atiixp_set_pio_mode	-	set host controller for PIO mode
+ *	@hwif: port
  *	@drive: drive
- *	@pio: PIO mode number
  *
  *	Set the interface PIO mode.
  */
 
-static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void atiixp_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
+	struct pci_dev *dev = to_pci_dev(hwif->dev);
 	unsigned long flags;
 	int timing_shift = (drive->dn ^ 1) * 8;
 	u32 pio_timing_data;
 	u16 pio_mode_data;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 
 	spin_lock_irqsave(&atiixp_lock, flags);
 
@@ -74,21 +75,22 @@ static void atiixp_set_pio_mode(ide_driv
 
 /**
  *	atiixp_set_dma_mode	-	set host controller for DMA mode
+ *	@hwif: port
  *	@drive: drive
- *	@speed: DMA mode
  *
  *	Set a ATIIXP host controller to the desired DMA mode.  This involves
  *	programming the right timing data into the PCI configuration space.
  */
 
-static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void atiixp_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
+	struct pci_dev *dev = to_pci_dev(hwif->dev);
 	unsigned long flags;
 	int timing_shift = (drive->dn ^ 1) * 8;
 	u32 tmp32;
 	u16 tmp16;
 	u16 udma_ctl = 0;
+	const u8 speed = drive->dma_mode;
 
 	spin_lock_irqsave(&atiixp_lock, flags);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/au1xxx-ide.c linux-libre-2.6.34-gnu1/drivers/ide/au1xxx-ide.c
--- linux-libre-2.6.33-gnu1/drivers/ide/au1xxx-ide.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/au1xxx-ide.c	2010-05-16 17:17:36.000000000 -0400
@@ -56,8 +56,8 @@ static inline void auide_insw(unsigned l
 	chan_tab_t *ctp;
 	au1x_ddma_desc_t *dp;
 
-	if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1, 
-			   DDMA_FLAGS_NOIE)) {
+	if (!au1xxx_dbdma_put_dest(ahwif->rx_chan, virt_to_phys(addr),
+				   count << 1, DDMA_FLAGS_NOIE)) {
 		printk(KERN_ERR "%s failed %d\n", __func__, __LINE__);
 		return;
 	}
@@ -74,8 +74,8 @@ static inline void auide_outsw(unsigned
 	chan_tab_t *ctp;
 	au1x_ddma_desc_t *dp;
 
-	if(!put_source_flags(ahwif->tx_chan, (void*)addr,
-			     count << 1, DDMA_FLAGS_NOIE)) {
+	if (!au1xxx_dbdma_put_source(ahwif->tx_chan, virt_to_phys(addr),
+				     count << 1, DDMA_FLAGS_NOIE)) {
 		printk(KERN_ERR "%s failed %d\n", __func__, __LINE__);
 		return;
 	}
@@ -99,12 +99,11 @@ static void au1xxx_output_data(ide_drive
 }
 #endif
 
-static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void au1xxx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);
 
-	/* set pio mode! */
-	switch(pio) {
+	switch (drive->pio_mode - XFER_PIO_0) {
 	case 0:
 		mem_sttime = SBC_IDE_TIMING(PIO0);
 
@@ -161,11 +160,11 @@ static void au1xxx_set_pio_mode(ide_driv
 	au_writel(mem_stcfg,MEM_STCFG2);
 }
 
-static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void auide_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);
 
-	switch(speed) {
+	switch (drive->dma_mode) {
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
 	case XFER_MW_DMA_2:
 		mem_sttime = SBC_IDE_TIMING(MDMA2);
@@ -246,17 +245,14 @@ static int auide_build_dmatable(ide_driv
 				flags = DDMA_FLAGS_NOIE;
 
 			if (iswrite) {
-				if(!put_source_flags(ahwif->tx_chan, 
-						     (void*) sg_virt(sg),
-						     tc, flags)) { 
+				if (!au1xxx_dbdma_put_source(ahwif->tx_chan,
+					sg_phys(sg), tc, flags)) {
 					printk(KERN_ERR "%s failed %d\n", 
 					       __func__, __LINE__);
 				}
-			} else 
-			{
-				if(!put_dest_flags(ahwif->rx_chan, 
-						   (void*) sg_virt(sg),
-						   tc, flags)) { 
+			} else  {
+				if (!au1xxx_dbdma_put_dest(ahwif->rx_chan,
+					sg_phys(sg), tc, flags)) {
 					printk(KERN_ERR "%s failed %d\n", 
 					       __func__, __LINE__);
 				}
@@ -300,8 +296,8 @@ static int auide_dma_test_irq(ide_drive_
 	 */
 	drive->waiting_for_dma++;
 	if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
-		printk(KERN_WARNING "%s: timeout waiting for ddma to \
-                                     complete\n", drive->name);
+		printk(KERN_WARNING "%s: timeout waiting for ddma to complete\n",
+		       drive->name);
 		return 1;
 	}
 	udelay(10);
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/cmd640.c linux-libre-2.6.34-gnu1/drivers/ide/cmd640.c
--- linux-libre-2.6.33-gnu1/drivers/ide/cmd640.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/cmd640.c	2010-05-16 17:17:36.000000000 -0400
@@ -572,9 +572,10 @@ static void cmd640_set_mode(ide_drive_t
 	program_drive_counts(drive, index);
 }
 
-static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void cmd640_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	unsigned int index = 0, cycle_time;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 	u8 b;
 
 	switch (pio) {
@@ -605,7 +606,7 @@ static void cmd640_set_pio_mode(ide_driv
 }
 #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
 
-static void cmd640_init_dev(ide_drive_t *drive)
+static void __init cmd640_init_dev(ide_drive_t *drive)
 {
 	unsigned int i = drive->hwif->channel * 2 + (drive->dn & 1);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/cmd64x.c linux-libre-2.6.34-gnu1/drivers/ide/cmd64x.c
--- linux-libre-2.6.33-gnu1/drivers/ide/cmd64x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/cmd64x.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
  * Copyright (C) 1998		David S. Miller (davem@redhat.com)
  *
  * Copyright (C) 1999-2002	Andre Hedrick <andre@linux-ide.org>
+ * Copyright (C) 2007-2010	Bartlomiej Zolnierkiewicz
  * Copyright (C) 2007,2009	MontaVista Software, Inc. <source@mvista.com>
  */
 
@@ -50,72 +51,42 @@
 #define UDIDETCR1	0x7B
 #define DTPR1		0x7C
 
-static u8 quantize_timing(int timing, int quant)
-{
-	return (timing + quant - 1) / quant;
-}
-
-/*
- * This routine calculates active/recovery counts and then writes them into
- * the chipset registers.
- */
-static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_time)
+static void cmd64x_program_timings(ide_drive_t *drive, u8 mode)
 {
+	ide_hwif_t *hwif = drive->hwif;
 	struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
-	int clock_time = 1000 / (ide_pci_clk ? ide_pci_clk : 33);
-	u8  cycle_count, active_count, recovery_count, drwtim;
+	int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
+	const unsigned long T = 1000000 / bus_speed;
 	static const u8 recovery_values[] =
 		{15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0};
+	static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
+	static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23};
 	static const u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM2, DRWTIM3};
+	struct ide_timing t;
+	u8 arttim = 0;
 
-	cycle_count	= quantize_timing( cycle_time, clock_time);
-	active_count	= quantize_timing(active_time, clock_time);
-	recovery_count	= cycle_count - active_count;
+	ide_timing_compute(drive, mode, &t, T, 0);
 
 	/*
 	 * In case we've got too long recovery phase, try to lengthen
 	 * the active phase
 	 */
-	if (recovery_count > 16) {
-		active_count += recovery_count - 16;
-		recovery_count = 16;
+	if (t.recover > 16) {
+		t.active += t.recover - 16;
+		t.recover = 16;
 	}
-	if (active_count > 16)		/* shouldn't actually happen... */
-	 	active_count = 16;
+	if (t.active > 16)		/* shouldn't actually happen... */
+		t.active = 16;
 
 	/*
 	 * Convert values to internal chipset representation
 	 */
-	recovery_count = recovery_values[recovery_count];
- 	active_count  &= 0x0f;
+	t.recover = recovery_values[t.recover];
+	t.active &= 0x0f;
 
 	/* Program the active/recovery counts into the DRWTIM register */
-	drwtim = (active_count << 4) | recovery_count;
-	(void) pci_write_config_byte(dev, drwtim_regs[drive->dn], drwtim);
-}
-
-/*
- * This routine writes into the chipset registers
- * PIO setup/active/recovery timings.
- */
-static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
-{
-	ide_hwif_t *hwif	= drive->hwif;
-	struct pci_dev *dev	= to_pci_dev(hwif->dev);
-	struct ide_timing *t	= ide_timing_find_mode(XFER_PIO_0 + pio);
-	unsigned long setup_count;
-	unsigned int cycle_time;
-	u8 arttim = 0;
-
-	static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
-	static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23};
-
-	cycle_time = ide_pio_cycle_time(drive, pio);
-
-	program_cycle_times(drive, cycle_time, t->active);
-
-	setup_count = quantize_timing(t->setup,
-			1000 / (ide_pci_clk ? ide_pci_clk : 33));
+	pci_write_config_byte(dev, drwtim_regs[drive->dn],
+			      (t.active << 4) | t.recover);
 
 	/*
 	 * The primary channel has individual address setup timing registers
@@ -126,15 +97,21 @@ static void cmd64x_tune_pio(ide_drive_t
 	if (hwif->channel) {
 		ide_drive_t *pair = ide_get_pair_dev(drive);
 
-		ide_set_drivedata(drive, (void *)setup_count);
+		if (pair) {
+			struct ide_timing tp;
 
-		if (pair)
-			setup_count = max_t(u8, setup_count,
-					(unsigned long)ide_get_drivedata(pair));
+			ide_timing_compute(pair, pair->pio_mode, &tp, T, 0);
+			ide_timing_merge(&t, &tp, &t, IDE_TIMING_SETUP);
+			if (pair->dma_mode) {
+				ide_timing_compute(pair, pair->dma_mode,
+						&tp, T, 0);
+				ide_timing_merge(&tp, &t, &t, IDE_TIMING_SETUP);
+			}
+		}
 	}
 
-	if (setup_count > 5)		/* shouldn't actually happen... */
-		setup_count = 5;
+	if (t.setup > 5)		/* shouldn't actually happen... */
+		t.setup = 5;
 
 	/*
 	 * Program the address setup clocks into the ARTTIM registers.
@@ -144,7 +121,7 @@ static void cmd64x_tune_pio(ide_drive_t
 	if (hwif->channel)
 		arttim &= ~ARTTIM23_INTR_CH1;
 	arttim &= ~0xc0;
-	arttim |= setup_values[setup_count];
+	arttim |= setup_values[t.setup];
 	(void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim);
 }
 
@@ -153,8 +130,10 @@ static void cmd64x_tune_pio(ide_drive_t
  * Special cases are 8: prefetch off, 9: prefetch on (both never worked)
  */
 
-static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void cmd64x_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
+
 	/*
 	 * Filter out the prefetch control values
 	 * to prevent PIO5 from being programmed
@@ -162,20 +141,18 @@ static void cmd64x_set_pio_mode(ide_driv
 	if (pio == 8 || pio == 9)
 		return;
 
-	cmd64x_tune_pio(drive, pio);
+	cmd64x_program_timings(drive, XFER_PIO_0 + pio);
 }
 
-static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void cmd64x_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	u8 unit			= drive->dn & 0x01;
 	u8 regU = 0, pciU	= hwif->channel ? UDIDETCR1 : UDIDETCR0;
+	const u8 speed		= drive->dma_mode;
 
-	if (speed >= XFER_SW_DMA_0) {
-		(void) pci_read_config_byte(dev, pciU, &regU);
-		regU &= ~(unit ? 0xCA : 0x35);
-	}
+	pci_read_config_byte(dev, pciU, &regU);
+	regU &= ~(unit ? 0xCA : 0x35);
 
 	switch(speed) {
 	case XFER_UDMA_5:
@@ -197,18 +174,13 @@ static void cmd64x_set_dma_mode(ide_driv
 		regU |= unit ? 0xC2 : 0x31;
 		break;
 	case XFER_MW_DMA_2:
-		program_cycle_times(drive, 120, 70);
-		break;
 	case XFER_MW_DMA_1:
-		program_cycle_times(drive, 150, 80);
-		break;
 	case XFER_MW_DMA_0:
-		program_cycle_times(drive, 480, 215);
+		cmd64x_program_timings(drive, speed);
 		break;
 	}
 
-	if (speed >= XFER_SW_DMA_0)
-		(void) pci_write_config_byte(dev, pciU, regU);
+	pci_write_config_byte(dev, pciU, regU);
 }
 
 static void cmd648_clear_irq(ide_drive_t *drive)
@@ -471,6 +443,6 @@ static void __exit cmd64x_ide_exit(void)
 module_init(cmd64x_ide_init);
 module_exit(cmd64x_ide_exit);
 
-MODULE_AUTHOR("Eddie Dost, David Miller, Andre Hedrick");
+MODULE_AUTHOR("Eddie Dost, David Miller, Andre Hedrick, Bartlomiej Zolnierkiewicz");
 MODULE_DESCRIPTION("PCI driver module for CMD64x IDE");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/cs5520.c linux-libre-2.6.34-gnu1/drivers/ide/cs5520.c
--- linux-libre-2.6.33-gnu1/drivers/ide/cs5520.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/cs5520.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,11 +57,11 @@ static struct pio_clocks cs5520_pio_cloc
 	{1, 2, 1}
 };
 
-static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void cs5520_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	struct pci_dev *pdev = to_pci_dev(hwif->dev);
 	int controller = drive->dn > 1 ? 1 : 0;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 
 	/* 8bit CAT/CRT - 8bit command timing for channel */
 	pci_write_config_byte(pdev, 0x62 + controller, 
@@ -81,11 +81,12 @@ static void cs5520_set_pio_mode(ide_driv
 		(cs5520_pio_clocks[pio].assert));
 }
 
-static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void cs5520_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	printk(KERN_ERR "cs55x0: bad ide timing.\n");
 
-	cs5520_set_pio_mode(drive, 0);
+	drive->pio_mode = XFER_PIO_0 + 0;
+	cs5520_set_pio_mode(hwif, drive);
 }
 
 static const struct ide_port_ops cs5520_port_ops = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/cs5530.c linux-libre-2.6.34-gnu1/drivers/ide/cs5530.c
--- linux-libre-2.6.33-gnu1/drivers/ide/cs5530.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/cs5530.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,8 +41,8 @@ static unsigned int cs5530_pio_timings[2
 
 /**
  *	cs5530_set_pio_mode	-	set host controller for PIO mode
+ *	@hwif: port
  *	@drive: drive
- *	@pio: PIO mode number
  *
  *	Handles setting of PIO mode for the chipset.
  *
@@ -50,10 +50,11 @@ static unsigned int cs5530_pio_timings[2
  *	will have valid default PIO timings set up before we get here.
  */
 
-static void cs5530_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void cs5530_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	unsigned long basereg = CS5530_BASEREG(drive->hwif);
+	unsigned long basereg = CS5530_BASEREG(hwif);
 	unsigned int format = (inl(basereg + 4) >> 31) & 1;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 
 	outl(cs5530_pio_timings[format][pio], basereg + ((drive->dn & 1)<<3));
 }
@@ -99,12 +100,12 @@ out:
 	return mask;
 }
 
-static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
+static void cs5530_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	unsigned long basereg;
 	unsigned int reg, timings = 0;
 
-	switch (mode) {
+	switch (drive->dma_mode) {
 		case XFER_UDMA_0:	timings = 0x00921250; break;
 		case XFER_UDMA_1:	timings = 0x00911140; break;
 		case XFER_UDMA_2:	timings = 0x00911030; break;
@@ -112,7 +113,7 @@ static void cs5530_set_dma_mode(ide_driv
 		case XFER_MW_DMA_1:	timings = 0x00012121; break;
 		case XFER_MW_DMA_2:	timings = 0x00002020; break;
 	}
-	basereg = CS5530_BASEREG(drive->hwif);
+	basereg = CS5530_BASEREG(hwif);
 	reg = inl(basereg + 4);			/* get drive0 config register */
 	timings |= reg & 0x80000000;		/* preserve PIO format bit */
 	if ((drive-> dn & 1) == 0) {		/* are we configuring drive0? */
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/cs5535.c linux-libre-2.6.34-gnu1/drivers/ide/cs5535.c
--- linux-libre-2.6.33-gnu1/drivers/ide/cs5535.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/cs5535.c	2010-05-16 17:17:36.000000000 -0400
@@ -86,7 +86,7 @@ static void cs5535_set_speed(ide_drive_t
 		cmd = pioa = speed - XFER_PIO_0;
 
 		if (pair) {
-			u8 piob = ide_get_best_pio_mode(pair, 255, 4);
+			u8 piob = pair->pio_mode - XFER_PIO_0;
 
 			if (piob < cmd)
 				cmd = piob;
@@ -129,28 +129,28 @@ static void cs5535_set_speed(ide_drive_t
 
 /**
  *	cs5535_set_dma_mode	-	set host controller for DMA mode
+ *	@hwif: port
  *	@drive: drive
- *	@speed: DMA mode
  *
  *	Programs the chipset for DMA mode.
  */
 
-static void cs5535_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void cs5535_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	cs5535_set_speed(drive, speed);
+	cs5535_set_speed(drive, drive->dma_mode);
 }
 
 /**
  *	cs5535_set_pio_mode	-	set host controller for PIO mode
+ *	@hwif: port
  *	@drive: drive
- *	@pio: PIO mode number
  *
  *	A callback from the upper layers for PIO-only tuning.
  */
 
-static void cs5535_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void cs5535_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	cs5535_set_speed(drive, XFER_PIO_0 + pio);
+	cs5535_set_speed(drive, drive->pio_mode);
 }
 
 static u8 cs5535_cable_detect(ide_hwif_t *hwif)
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/cs5536.c linux-libre-2.6.34-gnu1/drivers/ide/cs5536.c
--- linux-libre-2.6.33-gnu1/drivers/ide/cs5536.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/cs5536.c	2010-05-16 17:17:36.000000000 -0400
@@ -125,11 +125,11 @@ static u8 cs5536_cable_detect(ide_hwif_t
 
 /**
  *	cs5536_set_pio_mode		-	PIO timing setup
+ *	@hwif: ATA port
  *	@drive: ATA device
- *	@pio: PIO mode number
  */
 
-static void cs5536_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void cs5536_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	static const u8 drv_timings[5] = {
 		0x98, 0x55, 0x32, 0x21, 0x20,
@@ -143,15 +143,16 @@ static void cs5536_set_pio_mode(ide_driv
 		0x99, 0x92, 0x90, 0x22, 0x20,
 	};
 
-	struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
+	struct pci_dev *pdev = to_pci_dev(hwif->dev);
 	ide_drive_t *pair = ide_get_pair_dev(drive);
 	int cshift = (drive->dn & 1) ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
 	unsigned long timings = (unsigned long)ide_get_drivedata(drive);
 	u32 cast;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 	u8 cmd_pio = pio;
 
 	if (pair)
-		cmd_pio = min(pio, ide_get_best_pio_mode(pair, 255, 4));
+		cmd_pio = min_t(u8, pio, pair->pio_mode - XFER_PIO_0);
 
 	timings &= (IDE_DRV_MASK << 8);
 	timings |= drv_timings[pio];
@@ -172,11 +173,11 @@ static void cs5536_set_pio_mode(ide_driv
 
 /**
  *	cs5536_set_dma_mode		-	DMA timing setup
+ *	@hwif: ATA port
  *	@drive: ATA device
- *	@mode: DMA mode
  */
 
-static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)
+static void cs5536_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	static const u8 udma_timings[6] = {
 		0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6,
@@ -186,10 +187,11 @@ static void cs5536_set_dma_mode(ide_driv
 		0x67, 0x21, 0x20,
 	};
 
-	struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
+	struct pci_dev *pdev = to_pci_dev(hwif->dev);
 	int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT;
 	unsigned long timings = (unsigned long)ide_get_drivedata(drive);
 	u32 etc;
+	const u8 mode = drive->dma_mode;
 
 	cs5536_read(pdev, ETC, &etc);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/cy82c693.c linux-libre-2.6.34-gnu1/drivers/ide/cy82c693.c
--- linux-libre-2.6.33-gnu1/drivers/ide/cy82c693.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/cy82c693.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,43 +1,11 @@
 /*
  *  Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer
  *  Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator
+ *  Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
  *
  * CYPRESS CY82C693 chipset IDE controller
  *
  * The CY82C693 chipset is used on Digital's PC-Alpha 164SX boards.
- * Writing the driver was quite simple, since most of the job is
- * done by the generic pci-ide support.
- * The hard part was finding the CY82C693's datasheet on Cypress's
- * web page :-(. But Altavista solved this problem :-).
- *
- *
- * Notes:
- * - I recently got a 16.8G IBM DTTA, so I was able to test it with
- *   a large and fast disk - the results look great, so I'd say the
- *   driver is working fine :-)
- *   hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA
- * - this is my first linux driver, so there's probably a lot  of room
- *   for optimizations and bug fixing, so feel free to do it.
- * - if using PIO mode it's a good idea to set the PIO mode and
- *   32-bit I/O support (if possible), e.g. hdparm -p2 -c1 /dev/hda
- * - I had some problems with my IBM DHEA with PIO modes < 2
- *   (lost interrupts) ?????
- * - first tests with DMA look okay, they seem to work, but there is a
- *   problem with sound - the BusMaster IDE TimeOut should fixed this
- *
- * Ancient History:
- * AMH@1999-08-24: v0.34 init_cy82c693_chip moved to pci_init_cy82c693
- * ASK@1999-01-23: v0.33 made a few minor code clean ups
- *                       removed DMA clock speed setting by default
- *                       added boot message
- * ASK@1998-11-01: v0.32 added support to set BusMaster IDE TimeOut
- *                       added support to set DMA Controller Clock Speed
- * ASK@1998-10-31: v0.31 fixed problem with setting to high DMA modes
- *                       on some drives.
- * ASK@1998-10-29: v0.3 added support to set DMA modes
- * ASK@1998-10-28: v0.2 added support to set PIO modes
- * ASK@1998-10-27: v0.1 first version - chipset detection
- *
  */
 
 #include <linux/module.h>
@@ -81,87 +49,13 @@
 #define CY82_INDEX_CHANNEL1	0x31
 #define CY82_INDEX_TIMEOUT	0x32
 
-/* the min and max PCI bus speed in MHz - from datasheet */
-#define CY82C963_MIN_BUS_SPEED	25
-#define CY82C963_MAX_BUS_SPEED	33
-
-/* the struct for the PIO mode timings */
-typedef struct pio_clocks_s {
-	u8	address_time;	/* Address setup (clocks) */
-	u8	time_16r;	/* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */
-	u8	time_16w;	/* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */
-	u8	time_8;		/* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */
-} pio_clocks_t;
-
-/*
- * calc clocks using bus_speed
- * returns (rounded up) time in bus clocks for time in ns
- */
-static int calc_clk(int time, int bus_speed)
-{
-	int clocks;
-
-	clocks = (time*bus_speed+999)/1000 - 1;
-
-	if (clocks < 0)
-		clocks = 0;
-
-	if (clocks > 0x0F)
-		clocks = 0x0F;
-
-	return clocks;
-}
-
-/*
- * compute the values for the clock registers for PIO
- * mode and pci_clk [MHz] speed
- *
- * NOTE: for mode 0,1 and 2 drives 8-bit IDE command control registers are used
- *       for mode 3 and 4 drives 8 and 16-bit timings are the same
- *
- */
-static void compute_clocks(u8 pio, pio_clocks_t *p_pclk)
-{
-	struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
-	int clk1, clk2;
-	int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
-
-	/* we don't check against CY82C693's min and max speed,
-	 * so you can play with the idebus=xx parameter
-	 */
-
-	/* let's calc the address setup time clocks */
-	p_pclk->address_time = (u8)calc_clk(t->setup, bus_speed);
-
-	/* let's calc the active and recovery time clocks */
-	clk1 = calc_clk(t->active, bus_speed);
-
-	/* calc recovery timing */
-	clk2 = t->cycle - t->active - t->setup;
-
-	clk2 = calc_clk(clk2, bus_speed);
-
-	clk1 = (clk1<<4)|clk2;	/* combine active and recovery clocks */
-
-	/* note: we use the same values for 16bit IOR and IOW
-	 *	those are all the same, since I don't have other
-	 *	timings than those from ide-lib.c
-	 */
-
-	p_pclk->time_16r = (u8)clk1;
-	p_pclk->time_16w = (u8)clk1;
-
-	/* what are good values for 8bit ?? */
-	p_pclk->time_8 = (u8)clk1;
-}
-
 /*
  * set DMA mode a specific channel for CY82C693
  */
 
-static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
+static void cy82c693_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
+	const u8 mode = drive->dma_mode;
 	u8 single = (mode & 0x10) >> 4, index = 0, data = 0;
 
 	index = hwif->channel ? CY82_INDEX_CHANNEL1 : CY82_INDEX_CHANNEL0;
@@ -186,12 +80,14 @@ static void cy82c693_set_dma_mode(ide_dr
 	outb(data, CY82_DATA_PORT);
 }
 
-static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void cy82c693_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	struct pci_dev *dev = to_pci_dev(hwif->dev);
-	pio_clocks_t pclk;
+	int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
+	const unsigned long T = 1000000 / bus_speed;
 	unsigned int addrCtrl;
+	struct ide_timing t;
+	u8 time_16, time_8;
 
 	/* select primary or secondary channel */
 	if (hwif->index > 0) {  /* drive is on the secondary channel */
@@ -204,8 +100,12 @@ static void cy82c693_set_pio_mode(ide_dr
 		}
 	}
 
-	/* let's calc the values for this PIO mode */
-	compute_clocks(pio, &pclk);
+	ide_timing_compute(drive, drive->pio_mode, &t, T, 1);
+
+	time_16 = clamp_val(t.recover - 1, 0, 15) |
+		  (clamp_val(t.active - 1, 0, 15) << 4);
+	time_8 = clamp_val(t.act8b - 1, 0, 15) |
+		 (clamp_val(t.rec8b - 1, 0, 15) << 4);
 
 	/* now let's write  the clocks registers */
 	if ((drive->dn & 1) == 0) {
@@ -217,13 +117,13 @@ static void cy82c693_set_pio_mode(ide_dr
 		pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
 
 		addrCtrl &= (~0xF);
-		addrCtrl |= (unsigned int)pclk.address_time;
+		addrCtrl |= clamp_val(t.setup - 1, 0, 15);
 		pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
 
 		/* now let's set the remaining registers */
-		pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r);
-		pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w);
-		pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8);
+		pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, time_16);
+		pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, time_16);
+		pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, time_8);
 	} else {
 		/*
 		 * set slave drive
@@ -233,13 +133,13 @@ static void cy82c693_set_pio_mode(ide_dr
 		pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
 
 		addrCtrl &= (~0xF0);
-		addrCtrl |= ((unsigned int)pclk.address_time<<4);
+		addrCtrl |= (clamp_val(t.setup - 1, 0, 15) << 4);
 		pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
 
 		/* now let's set the remaining registers */
-		pci_write_config_byte(dev, CY82_IDE_SLAVE_IOR, pclk.time_16r);
-		pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, pclk.time_16w);
-		pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, pclk.time_8);
+		pci_write_config_byte(dev, CY82_IDE_SLAVE_IOR, time_16);
+		pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, time_16);
+		pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, time_8);
 	}
 }
 
@@ -325,6 +225,6 @@ static void __exit cy82c693_ide_exit(voi
 module_init(cy82c693_ide_init);
 module_exit(cy82c693_ide_exit);
 
-MODULE_AUTHOR("Andreas Krebs, Andre Hedrick");
+MODULE_AUTHOR("Andreas Krebs, Andre Hedrick, Bartlomiej Zolnierkiewicz");
 MODULE_DESCRIPTION("PCI driver module for the Cypress CY82C693 IDE");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/dtc2278.c linux-libre-2.6.34-gnu1/drivers/ide/dtc2278.c
--- linux-libre-2.6.33-gnu1/drivers/ide/dtc2278.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/dtc2278.c	2010-05-16 17:17:36.000000000 -0400
@@ -68,11 +68,11 @@ static void sub22 (char b, char c)
 
 static DEFINE_SPINLOCK(dtc2278_lock);
 
-static void dtc2278_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void dtc2278_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	unsigned long flags;
 
-	if (pio >= 3) {
+	if (drive->pio_mode >= XFER_PIO_3) {
 		spin_lock_irqsave(&dtc2278_lock, flags);
 		/*
 		 * This enables PIO mode4 (3?) on the first interface
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/hpt366.c linux-libre-2.6.34-gnu1/drivers/ide/hpt366.c
--- linux-libre-2.6.33-gnu1/drivers/ide/hpt366.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/hpt366.c	2010-05-16 17:17:36.000000000 -0400
@@ -128,6 +128,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ide.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -627,14 +628,14 @@ static u32 get_speed_setting(u8 speed, s
 	return info->timings->clock_table[info->clock][i];
 }
 
-static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed)
+static void hpt3xx_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	struct hpt_info *info	= hpt3xx_get_info(hwif->dev);
 	struct hpt_timings *t	= info->timings;
 	u8  itr_addr		= 0x40 + (drive->dn * 4);
 	u32 old_itr		= 0;
+	const u8 speed		= drive->dma_mode;
 	u32 new_itr		= get_speed_setting(speed, info);
 	u32 itr_mask		= speed < XFER_MW_DMA_0 ? t->pio_mask :
 				 (speed < XFER_UDMA_0   ? t->dma_mask :
@@ -651,9 +652,10 @@ static void hpt3xx_set_mode(ide_drive_t
 	pci_write_config_dword(dev, itr_addr, new_itr);
 }
 
-static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void hpt3xx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	hpt3xx_set_mode(drive, XFER_PIO_0 + pio);
+	drive->dma_mode = drive->pio_mode;
+	hpt3xx_set_mode(hwif, drive);
 }
 
 static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ht6560b.c linux-libre-2.6.34-gnu1/drivers/ide/ht6560b.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ht6560b.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ht6560b.c	2010-05-16 17:17:36.000000000 -0400
@@ -279,9 +279,10 @@ static void ht_set_prefetch(ide_drive_t
 #endif
 }
 
-static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void ht6560b_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	unsigned long flags, config;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 	u8 timing;
 	
 	switch (pio) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/icside.c linux-libre-2.6.34-gnu1/drivers/ide/icside.c
--- linux-libre-2.6.33-gnu1/drivers/ide/icside.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/icside.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,6 +65,8 @@ static struct cardinfo icside_cardinfo_v
 };
 
 struct icside_state {
+	unsigned int channel;
+	unsigned int enabled;
 	void __iomem *irq_port;
 	void __iomem *ioc_base;
 	unsigned int sel;
@@ -114,11 +116,18 @@ static void icside_irqenable_arcin_v6 (s
 	struct icside_state *state = ec->irq_data;
 	void __iomem *base = state->irq_port;
 
-	writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
-	readb(base + ICS_ARCIN_V6_INTROFFSET_2);
+	state->enabled = 1;
 
-	writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
-	readb(base + ICS_ARCIN_V6_INTROFFSET_1);
+	switch (state->channel) {
+	case 0:
+		writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
+		readb(base + ICS_ARCIN_V6_INTROFFSET_2);
+		break;
+	case 1:
+		writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
+		readb(base + ICS_ARCIN_V6_INTROFFSET_1);
+		break;
+	}
 }
 
 /* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
@@ -128,6 +137,8 @@ static void icside_irqdisable_arcin_v6 (
 {
 	struct icside_state *state = ec->irq_data;
 
+	state->enabled = 0;
+
 	readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
 	readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
 }
@@ -149,6 +160,44 @@ static const expansioncard_ops_t icside_
 	.irqpending	= icside_irqpending_arcin_v6,
 };
 
+/*
+ * Handle routing of interrupts.  This is called before
+ * we write the command to the drive.
+ */
+static void icside_maskproc(ide_drive_t *drive, int mask)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct expansion_card *ec = ECARD_DEV(hwif->dev);
+	struct icside_state *state = ecard_get_drvdata(ec);
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	state->channel = hwif->channel;
+
+	if (state->enabled && !mask) {
+		switch (hwif->channel) {
+		case 0:
+			writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
+			readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
+			break;
+		case 1:
+			writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
+			readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
+			break;
+		}
+	} else {
+		readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
+		readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
+	}
+
+	local_irq_restore(flags);
+}
+
+static const struct ide_port_ops icside_v6_no_dma_port_ops = {
+	.maskproc		= icside_maskproc,
+};
+
 #ifdef CONFIG_BLK_DEV_IDEDMA_ICS
 /*
  * SG-DMA support.
@@ -185,10 +234,11 @@ static const expansioncard_ops_t icside_
  *	MW1	80	50	50	150	C
  *	MW2	70	25	25	120	C
  */
-static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode)
+static void icside_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	unsigned long cycle_time;
 	int use_dma_info = 0;
+	const u8 xfer_mode = drive->dma_mode;
 
 	switch (xfer_mode) {
 	case XFER_MW_DMA_2:
@@ -228,6 +278,7 @@ static void icside_set_dma_mode(ide_driv
 
 static const struct ide_port_ops icside_v6_port_ops = {
 	.set_dma_mode		= icside_set_dma_mode,
+	.maskproc		= icside_maskproc,
 };
 
 static void icside_dma_host_set(ide_drive_t *drive, int on)
@@ -272,6 +323,11 @@ static int icside_dma_setup(ide_drive_t
 	BUG_ON(dma_channel_active(ec->dma));
 
 	/*
+	 * Ensure that we have the right interrupt routed.
+	 */
+	icside_maskproc(drive, 0);
+
+	/*
 	 * Route the DMA signals to the correct interface.
 	 */
 	writeb(state->sel | hwif->channel, state->ioc_base);
@@ -399,6 +455,7 @@ err_free:
 
 static const struct ide_port_info icside_v6_port_info __initdata = {
 	.init_dma		= icside_dma_off_init,
+	.port_ops		= &icside_v6_no_dma_port_ops,
 	.dma_ops		= &icside_v6_dma_ops,
 	.host_flags		= IDE_HFLAG_SERIALIZE | IDE_HFLAG_MMIO,
 	.mwdma_mask		= ATA_MWDMA2,
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-acpi.c linux-libre-2.6.34-gnu1/drivers/ide/ide-acpi.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-acpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-acpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <acpi/acpi.h>
 #include <linux/ide.h>
 #include <linux/pci.h>
@@ -108,11 +109,11 @@ bool ide_port_acpi(ide_hwif_t *hwif)
  * Returns 0 on success, <0 on error.
  */
 static int ide_get_dev_handle(struct device *dev, acpi_handle *handle,
-			       acpi_integer *pcidevfn)
+			       u64 *pcidevfn)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 	unsigned int bus, devnum, func;
-	acpi_integer addr;
+	u64 addr;
 	acpi_handle dev_handle;
 	acpi_status status;
 	struct acpi_device_info	*dinfo = NULL;
@@ -122,7 +123,7 @@ static int ide_get_dev_handle(struct dev
 	devnum = PCI_SLOT(pdev->devfn);
 	func = PCI_FUNC(pdev->devfn);
 	/* ACPI _ADR encoding for PCI bus: */
-	addr = (acpi_integer)(devnum << 16 | func);
+	addr = (u64)(devnum << 16 | func);
 
 	DEBPRINT("ENTER: pci %02x:%02x.%01x\n", bus, devnum, func);
 
@@ -169,7 +170,7 @@ static acpi_handle ide_acpi_hwif_get_han
 {
 	struct device		*dev = hwif->gendev.parent;
 	acpi_handle		uninitialized_var(dev_handle);
-	acpi_integer		pcidevfn;
+	u64			pcidevfn;
 	acpi_handle		chan_handle;
 	int			err;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-atapi.c linux-libre-2.6.34-gnu1/drivers/ide/ide-atapi.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-atapi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-atapi.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
 #include <linux/delay.h>
 #include <linux/ide.h>
 #include <linux/scatterlist.h>
+#include <linux/gfp.h>
 
 #include <scsi/scsi.h>
 
@@ -263,8 +264,8 @@ void ide_retry_pc(ide_drive_t *drive)
 	 * of it.  The failed command will be retried after sense data
 	 * is acquired.
 	 */
-	blk_requeue_request(failed_rq->q, failed_rq);
 	drive->hwif->rq = NULL;
+	ide_requeue_and_plug(drive, failed_rq);
 	if (ide_queue_sense_rq(drive, pc)) {
 		blk_start_request(failed_rq);
 		ide_complete_rq(drive, -EIO, blk_rq_bytes(failed_rq));
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide.c linux-libre-2.6.34-gnu1/drivers/ide/ide.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,7 +52,6 @@
 #include <linux/major.h>
 #include <linux/errno.h>
 #include <linux/genhd.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/ide.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-cd_ioctl.c linux-libre-2.6.34-gnu1/drivers/ide/ide-cd_ioctl.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-cd_ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-cd_ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 
 #include <linux/kernel.h>
 #include <linux/cdrom.h>
+#include <linux/gfp.h>
 #include <linux/ide.h>
 #include <scsi/scsi.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-cs.c linux-libre-2.6.34-gnu1/drivers/ide/ide-cs.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -121,19 +121,11 @@ static int ide_probe(struct pcmcia_devic
 static void ide_detach(struct pcmcia_device *link)
 {
     ide_info_t *info = link->priv;
-    ide_hwif_t *hwif = info->host->ports[0];
-    unsigned long data_addr, ctl_addr;
 
     dev_dbg(&link->dev, "ide_detach(0x%p)\n", link);
 
-    data_addr = hwif->io_ports.data_addr;
-    ctl_addr  = hwif->io_ports.ctl_addr;
-
     ide_release(link);
 
-    release_region(ctl_addr, 1);
-    release_region(data_addr, 8);
-
     kfree(info);
 } /* ide_detach */
 
@@ -354,12 +346,19 @@ static void ide_release(struct pcmcia_de
 
     dev_dbg(&link->dev, "ide_release(0x%p)\n", link);
 
-    if (info->ndev)
-	/* FIXME: if this fails we need to queue the cleanup somehow
-	   -- need to investigate the required PCMCIA magic */
+    if (info->ndev) {
+	ide_hwif_t *hwif = host->ports[0];
+	unsigned long data_addr, ctl_addr;
+
+	data_addr = hwif->io_ports.data_addr;
+	ctl_addr = hwif->io_ports.ctl_addr;
+
 	ide_host_remove(host);
+	info->ndev = 0;
 
-    info->ndev = 0;
+	release_region(ctl_addr, 1);
+	release_region(data_addr, 8);
+    }
 
     pcmcia_disable_device(link);
 } /* ide_release */
@@ -410,6 +409,8 @@ static struct pcmcia_device_id ide_ids[]
 	PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
 	PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
 	PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
+	PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 1GB", 0x2e6d1829, 0x55d5bffb),
+	PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 4GB", 0x2e6d1829, 0x531e7d10),
 	PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
 	PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),
 	PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
@@ -430,6 +431,8 @@ static struct pcmcia_device_id ide_ids[]
 	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
 	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
 	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
+	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF133", 0x709b1bf1, 0x7558f133),
+	PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS8GCF133", 0x709b1bf1, 0xb2f89b47),
 	PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
 	PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
 	PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-devsets.c linux-libre-2.6.34-gnu1/drivers/ide/ide-devsets.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-devsets.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-devsets.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,6 @@
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/ide.h>
 
 DEFINE_MUTEX(ide_setting_mtx);
@@ -105,15 +106,17 @@ static int set_pio_mode(ide_drive_t *dri
 		return -ENOSYS;
 
 	if (set_pio_mode_abuse(drive->hwif, arg)) {
+		drive->pio_mode = arg + XFER_PIO_0;
+
 		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);
+			port_ops->set_pio_mode(hwif, drive);
 			spin_unlock_irqrestore(&hwif->lock, flags);
 		} else
-			port_ops->set_pio_mode(drive, arg);
+			port_ops->set_pio_mode(hwif, drive);
 	} else {
 		int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-disk.c linux-libre-2.6.34-gnu1/drivers/ide/ide-disk.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-disk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-disk.c	2010-05-16 17:17:36.000000000 -0400
@@ -679,7 +679,7 @@ static void ide_disk_setup(ide_drive_t *
 		if (max_s > hwif->rqsize)
 			max_s = hwif->rqsize;
 
-		blk_queue_max_sectors(q, max_s);
+		blk_queue_max_hw_sectors(q, max_s);
 	}
 
 	printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name,
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-disk_proc.c linux-libre-2.6.34-gnu1/drivers/ide/ide-disk_proc.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-disk_proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-disk_proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,6 @@
 #include <linux/kernel.h>
 #include <linux/ide.h>
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 
 #include "ide-disk.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-dma.c linux-libre-2.6.34-gnu1/drivers/ide/ide-dma.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/ide.h>
 #include <linux/scatterlist.h>
@@ -492,6 +493,7 @@ ide_startstop_t ide_dma_timeout_retry(id
 	if (rq) {
 		hwif->rq = NULL;
 		rq->errors = 0;
+		ide_requeue_and_plug(drive, rq);
 	}
 	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-floppy.c linux-libre-2.6.34-gnu1/drivers/ide/ide-floppy.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-floppy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-floppy.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,6 @@
 #include <linux/major.h>
 #include <linux/errno.h>
 #include <linux/genhd.h>
-#include <linux/slab.h>
 #include <linux/cdrom.h>
 #include <linux/ide.h>
 #include <linux/hdreg.h>
@@ -486,7 +485,7 @@ static void ide_floppy_setup(ide_drive_t
 		drive->atapi_flags |= IDE_AFLAG_ZIP_DRIVE;
 		/* This value will be visible in the /proc/ide/hdx/settings */
 		drive->pc_delay = IDEFLOPPY_PC_DELAY;
-		blk_queue_max_sectors(drive->queue, 64);
+		blk_queue_max_hw_sectors(drive->queue, 64);
 	}
 
 	/*
@@ -494,7 +493,7 @@ static void ide_floppy_setup(ide_drive_t
 	 * nasty clicking noises without it, so please don't remove this.
 	 */
 	if (strncmp((char *)&id[ATA_ID_PROD], "IOMEGA Clik!", 11) == 0) {
-		blk_queue_max_sectors(drive->queue, 64);
+		blk_queue_max_hw_sectors(drive->queue, 64);
 		drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE;
 		/* IOMEGA Clik! drives do not support lock/unlock commands */
 		drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-gd.c linux-libre-2.6.34-gnu1/drivers/ide/ide-gd.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-gd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-gd.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 #include <linux/ide.h>
 #include <linux/hdreg.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 
 #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
 #define IDE_DISK_MINORS		(1 << PARTN_BITS)
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-io.c linux-libre-2.6.34-gnu1/drivers/ide/ide-io.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-io.c	2010-05-16 17:17:36.000000000 -0400
@@ -566,7 +566,7 @@ plug_device_2:
 		blk_plug_device(q);
 }
 
-static void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq)
+void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq)
 {
 	struct request_queue *q = drive->queue;
 	unsigned long flags;
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-ioctls.c linux-libre-2.6.34-gnu1/drivers/ide/ide-ioctls.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-ioctls.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-ioctls.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
 
 #include <linux/hdreg.h>
 #include <linux/ide.h>
+#include <linux/slab.h>
 
 static const struct ide_ioctl_devset ide_ioctl_settings[] = {
 { HDIO_GET_32BIT,	 HDIO_SET_32BIT,	&ide_devset_io_32bit  },
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-iops.c linux-libre-2.6.34-gnu1/drivers/ide/ide-iops.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-iops.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-iops.c	2010-05-16 17:17:36.000000000 -0400
@@ -231,7 +231,7 @@ u8 eighty_ninty_three(ide_drive_t *drive
 	u16 *id = drive->id;
 	int ivb = ide_in_drive_list(id, ivb_list);
 
-	if (hwif->cbl == ATA_CBL_PATA40_SHORT)
+	if (hwif->cbl == ATA_CBL_SATA || hwif->cbl == ATA_CBL_PATA40_SHORT)
 		return 1;
 
 	if (ivb)
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-park.c linux-libre-2.6.34-gnu1/drivers/ide/ide-park.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-park.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-park.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,5 @@
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/ide.h>
 #include <linux/jiffies.h>
 #include <linux/blkdev.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-pm.c linux-libre-2.6.34-gnu1/drivers/ide/ide-pm.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-pm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,5 @@
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/ide.h>
 
 int generic_ide_suspend(struct device *dev, pm_message_t mesg)
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-probe.c linux-libre-2.6.34-gnu1/drivers/ide/ide-probe.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-probe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-probe.c	2010-05-16 17:17:36.000000000 -0400
@@ -695,14 +695,8 @@ static int ide_probe_port(ide_hwif_t *hw
 	if (irqd)
 		disable_irq(hwif->irq);
 
-	rc = ide_port_wait_ready(hwif);
-	if (rc == -ENODEV) {
-		printk(KERN_INFO "%s: no devices on the port\n", hwif->name);
-		goto out;
-	} else if (rc == -EBUSY)
-		printk(KERN_ERR "%s: not ready before the probe\n", hwif->name);
-	else
-		rc = -ENODEV;
+	if (ide_port_wait_ready(hwif) == -EBUSY)
+		printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name);
 
 	/*
 	 * Second drive should only exist if first drive was found,
@@ -713,7 +707,7 @@ static int ide_probe_port(ide_hwif_t *hw
 		if (drive->dev_flags & IDE_DFLAG_PRESENT)
 			rc = 0;
 	}
-out:
+
 	/*
 	 * Use cached IRQ number. It might be (and is...) changed by probe
 	 * code above
@@ -774,7 +768,7 @@ static int ide_init_queue(ide_drive_t *d
 
 	if (hwif->rqsize < max_sectors)
 		max_sectors = hwif->rqsize;
-	blk_queue_max_sectors(q, max_sectors);
+	blk_queue_max_hw_sectors(q, max_sectors);
 
 #ifdef CONFIG_PCI
 	/* When we have an IOMMU, we may have a problem where pci_map_sg()
@@ -790,8 +784,7 @@ static int ide_init_queue(ide_drive_t *d
 		max_sg_entries >>= 1;
 #endif /* CONFIG_PCI */
 
-	blk_queue_max_hw_segments(q, max_sg_entries);
-	blk_queue_max_phys_segments(q, max_sg_entries);
+	blk_queue_max_segments(q, max_sg_entries);
 
 	/* assign drive queue */
 	drive->queue = q;
@@ -1043,6 +1036,8 @@ static void ide_port_init_devices(ide_hw
 		if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
 			drive->dev_flags |= IDE_DFLAG_NO_UNMASK;
 
+		drive->pio_mode = XFER_PIO_0;
+
 		if (port_ops && port_ops->init_dev)
 			port_ops->init_dev(drive);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-proc.c linux-libre-2.6.34-gnu1/drivers/ide/ide-proc.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/ctype.h>
 #include <linux/ide.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-tape.c linux-libre-2.6.34-gnu1/drivers/ide/ide-tape.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-tape.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-tape.c	2010-05-16 17:17:36.000000000 -0400
@@ -1365,7 +1365,7 @@ static int idetape_mtioctop(ide_drive_t
  * supported here, and not in the corresponding block interface. Our own
  * ide-tape ioctls are supported on both interfaces.
  */
-static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
+static long do_idetape_chrdev_ioctl(struct file *file,
 				unsigned int cmd, unsigned long arg)
 {
 	struct ide_tape_obj *tape = file->private_data;
@@ -1420,6 +1420,16 @@ static int idetape_chrdev_ioctl(struct i
 	}
 }
 
+static long idetape_chrdev_ioctl(struct file *file,
+				unsigned int cmd, unsigned long arg)
+{
+	long ret;
+	lock_kernel();
+	ret = do_idetape_chrdev_ioctl(file, cmd, arg);
+	unlock_kernel();
+	return ret;
+}
+
 /*
  * Do a mode sense page 0 with block descriptor and if it succeeds set the tape
  * block size with the reported value.
@@ -1888,7 +1898,7 @@ static const struct file_operations idet
 	.owner		= THIS_MODULE,
 	.read		= idetape_chrdev_read,
 	.write		= idetape_chrdev_write,
-	.ioctl		= idetape_chrdev_ioctl,
+	.unlocked_ioctl	= idetape_chrdev_ioctl,
 	.open		= idetape_chrdev_open,
 	.release	= idetape_chrdev_release,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-taskfile.c linux-libre-2.6.34-gnu1/drivers/ide/ide-taskfile.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-taskfile.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-taskfile.c	2010-05-16 17:17:36.000000000 -0400
@@ -428,13 +428,11 @@ int ide_raw_taskfile(ide_drive_t *drive,
 {
 	struct request *rq;
 	int error;
+	int rw = !(cmd->tf_flags & IDE_TFLAG_WRITE) ? READ : WRITE;
 
-	rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+	rq = blk_get_request(drive->queue, rw, __GFP_WAIT);
 	rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
 
-	if (cmd->tf_flags & IDE_TFLAG_WRITE)
-		rq->cmd_flags |= REQ_RW;
-
 	/*
 	 * (ks) We transfer currently only whole sectors.
 	 * This is suffient for now.  But, it would be great,
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-timings.c linux-libre-2.6.34-gnu1/drivers/ide/ide-timings.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-timings.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-timings.c	2010-05-16 17:17:36.000000000 -0400
@@ -166,12 +166,13 @@ int ide_timing_compute(ide_drive_t *driv
 	if (id[ATA_ID_FIELD_VALID] & 2) {	/* EIDE drive */
 		memset(&p, 0, sizeof(p));
 
-		if (speed <= XFER_PIO_2)
-			p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO];
-		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)
+		if (speed >= XFER_PIO_0 && speed < XFER_SW_DMA_0) {
+			if (speed <= XFER_PIO_2)
+				p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO];
+			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];
 
 		ide_timing_merge(&p, t, t, IDE_TIMING_CYCLE | IDE_TIMING_CYC8B);
@@ -185,11 +186,10 @@ int ide_timing_compute(ide_drive_t *driv
 	/*
 	 * Even in DMA/UDMA modes we still use PIO access for IDENTIFY,
 	 * S.M.A.R.T and some other commands. We have to ensure that the
-	 * DMA cycle timing is slower/equal than the fastest PIO timing.
+	 * DMA cycle timing is slower/equal than the current PIO timing.
 	 */
 	if (speed >= XFER_SW_DMA_0) {
-		u8 pio = ide_get_best_pio_mode(drive, 255, 5);
-		ide_timing_compute(drive, XFER_PIO_0 + pio, &p, T, UT);
+		ide_timing_compute(drive, drive->pio_mode, &p, T, UT);
 		ide_timing_merge(&p, t, t, IDE_TIMING_ALL);
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/ide-xfer-mode.c linux-libre-2.6.34-gnu1/drivers/ide/ide-xfer-mode.c
--- linux-libre-2.6.33-gnu1/drivers/ide/ide-xfer-mode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/ide-xfer-mode.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,7 +58,7 @@ EXPORT_SYMBOL(ide_xfer_verbose);
  *	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)
+static 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;
@@ -105,7 +105,6 @@ u8 ide_get_best_pio_mode(ide_drive_t *dr
 
 	return pio_mode;
 }
-EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
 
 int ide_pio_need_iordy(ide_drive_t *drive, const u8 pio)
 {
@@ -135,17 +134,20 @@ int ide_set_pio_mode(ide_drive_t *drive,
 	 * 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);
+		drive->pio_mode = mode;
+		port_ops->set_pio_mode(hwif, drive);
 		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);
+		drive->pio_mode = mode;
+		port_ops->set_pio_mode(hwif, drive);
 		return 0;
 	} else {
-		port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+		drive->pio_mode = mode;
+		port_ops->set_pio_mode(hwif, drive);
 		return ide_config_drive_speed(drive, mode);
 	}
 }
@@ -164,10 +166,12 @@ int ide_set_dma_mode(ide_drive_t *drive,
 	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);
+		drive->dma_mode = mode;
+		port_ops->set_dma_mode(hwif, drive);
 		return 0;
 	} else {
-		port_ops->set_dma_mode(drive, mode);
+		drive->dma_mode = mode;
+		port_ops->set_dma_mode(hwif, drive);
 		return ide_config_drive_speed(drive, mode);
 	}
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/it8172.c linux-libre-2.6.34-gnu1/drivers/ide/it8172.c
--- linux-libre-2.6.33-gnu1/drivers/ide/it8172.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/it8172.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,12 +37,12 @@
 
 #define DRV_NAME "IT8172"
 
-static void it8172_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void it8172_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	u16 drive_enables;
 	u32 drive_timing;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 
 	/*
 	 * The highest value of DIOR/DIOW pulse width and recovery time
@@ -77,14 +77,14 @@ static void it8172_set_pio_mode(ide_driv
 	pci_write_config_dword(dev, 0x44, drive_timing);
 }
 
-static void it8172_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void it8172_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	int a_speed		= 3 << (drive->dn * 4);
 	int u_flag		= 1 << drive->dn;
 	int u_speed		= 0;
 	u8 reg48, reg4a;
+	const u8 speed		= drive->dma_mode;
 
 	pci_read_config_byte(dev, 0x48, &reg48);
 	pci_read_config_byte(dev, 0x4a, &reg4a);
@@ -98,14 +98,14 @@ static void it8172_set_dma_mode(ide_driv
 		pci_write_config_byte(dev, 0x4a, reg4a | u_speed);
 	} else {
 		const u8 mwdma_to_pio[] = { 0, 3, 4 };
-		u8 pio;
 
 		pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
 		pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
 
-		pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
+		drive->pio_mode =
+			mwdma_to_pio[speed - XFER_MW_DMA_0] + XFER_PIO_0;
 
-		it8172_set_pio_mode(drive, pio);
+		it8172_set_pio_mode(hwif, drive);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/it8213.c linux-libre-2.6.34-gnu1/drivers/ide/it8213.c
--- linux-libre-2.6.33-gnu1/drivers/ide/it8213.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/it8213.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,15 +17,14 @@
 
 /**
  *	it8213_set_pio_mode	-	set host controller for PIO mode
+ *	@hwif: port
  *	@drive: drive
- *	@pio: PIO mode number
  *
  *	Set the interface PIO mode.
  */
 
-static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void it8213_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	int is_slave		= drive->dn & 1;
 	int master_port		= 0x40;
@@ -35,6 +34,7 @@ static void it8213_set_pio_mode(ide_driv
 	u8 slave_data;
 	static DEFINE_SPINLOCK(tune_lock);
 	int control = 0;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 
 	static const u8 timings[][2] = {
 					{ 0, 0 },
@@ -74,15 +74,14 @@ static void it8213_set_pio_mode(ide_driv
 
 /**
  *	it8213_set_dma_mode	-	set host controller for DMA mode
+ *	@hwif: port
  *	@drive: drive
- *	@speed: DMA mode
  *
  *	Tune the ITE chipset for the DMA mode.
  */
 
-static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void it8213_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	u8 maslave		= 0x40;
 	int a_speed		= 3 << (drive->dn * 4);
@@ -92,6 +91,7 @@ static void it8213_set_dma_mode(ide_driv
 	int u_speed		= 0;
 	u16			reg4042, reg4a;
 	u8			reg48, reg54, reg55;
+	const u8 speed		= drive->dma_mode;
 
 	pci_read_config_word(dev, maslave, &reg4042);
 	pci_read_config_byte(dev, 0x48, &reg48);
@@ -120,7 +120,6 @@ static void it8213_set_dma_mode(ide_driv
 			pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
 	} else {
 		const u8 mwdma_to_pio[] = { 0, 3, 4 };
-		u8 pio;
 
 		if (reg48 & u_flag)
 			pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
@@ -132,11 +131,12 @@ static void it8213_set_dma_mode(ide_driv
 			pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
 
 		if (speed >= XFER_MW_DMA_0)
-			pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
+			drive->pio_mode =
+				mwdma_to_pio[speed - XFER_MW_DMA_0] + XFER_PIO_0;
 		else
-			pio = 2; /* only SWDMA2 is allowed */
+			drive->pio_mode = XFER_PIO_2; /* for SWDMA2 */
 
-		it8213_set_pio_mode(drive, pio);
+		it8213_set_pio_mode(hwif, drive);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/it821x.c linux-libre-2.6.34-gnu1/drivers/ide/it821x.c
--- linux-libre-2.6.33-gnu1/drivers/ide/it821x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/it821x.c	2010-05-16 17:17:36.000000000 -0400
@@ -61,6 +61,7 @@
 
 #include <linux/types.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/ide.h>
 #include <linux/init.h>
@@ -228,18 +229,18 @@ static void it821x_clock_strategy(ide_dr
 
 /**
  *	it821x_set_pio_mode	-	set host controller for PIO mode
+ *	@hwif: port
  *	@drive: drive
- *	@pio: PIO mode number
  *
  *	Tune the host to the desired PIO mode taking into the consideration
  *	the maximum PIO mode supported by the other device on the cable.
  */
 
-static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void it821x_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
 	ide_drive_t *pair = ide_get_pair_dev(drive);
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 	u8 unit = drive->dn & 1, set_pio = pio;
 
 	/* Spec says 89 ref driver uses 88 */
@@ -252,7 +253,7 @@ static void it821x_set_pio_mode(ide_driv
 	 * on the cable.
 	 */
 	if (pair) {
-		u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4);
+		u8 pair_pio = pair->pio_mode - XFER_PIO_0;
 		/* trim PIO to the slowest of the master/slave */
 		if (pair_pio < set_pio)
 			set_pio = pair_pio;
@@ -393,14 +394,16 @@ static int it821x_dma_end(ide_drive_t *d
 
 /**
  *	it821x_set_dma_mode	-	set host controller for DMA mode
+ *	@hwif: port
  *	@drive: drive
- *	@speed: DMA mode
  *
  *	Tune the ITE chipset for the desired DMA mode.
  */
 
-static void it821x_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void it821x_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
+	const u8 speed = drive->dma_mode;
+
 	/*
 	 * MWDMA tuning is really hard because our MWDMA and PIO
 	 * timings are kept in the same place.  We can switch in the
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/jmicron.c linux-libre-2.6.34-gnu1/drivers/ide/jmicron.c
--- linux-libre-2.6.33-gnu1/drivers/ide/jmicron.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/jmicron.c	2010-05-16 17:17:36.000000000 -0400
@@ -80,19 +80,19 @@ static u8 jmicron_cable_detect(ide_hwif_
 	return ATA_CBL_PATA80;
 }
 
-static void jmicron_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void jmicron_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 }
 
 /**
  *	jmicron_set_dma_mode	-	set host controller for DMA mode
+ *	@hwif: port
  *	@drive: drive
- *	@mode: DMA mode
  *
  *	As the JMicron snoops for timings we don't need to do anything here.
  */
 
-static void jmicron_set_dma_mode(ide_drive_t *drive, const u8 mode)
+static void jmicron_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/opti621.c linux-libre-2.6.34-gnu1/drivers/ide/opti621.c
--- linux-libre-2.6.33-gnu1/drivers/ide/opti621.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/opti621.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,77 +8,6 @@
  * Jan Harkes <jaharkes@cwi.nl>,
  * Mark Lord <mlord@pobox.com>
  * Some parts of code are from ali14xx.c and from rz1000.c.
- *
- * OPTi is trademark of OPTi, Octek is trademark of Octek.
- *
- * I used docs from OPTi databook, from ftp.opti.com, file 9123-0002.ps
- * and disassembled/traced setupvic.exe (DOS program).
- * It increases kernel code about 2 kB.
- * I don't have this card no more, but I hope I can get some in case
- * of needed development.
- * My card is Octek PIDE 1.01 (on card) or OPTiViC (program).
- * It has a place for a secondary connector in circuit, but nothing
- * is there. Also BIOS says no address for
- * secondary controller (see bellow in ide_init_opti621).
- * I've only tested this on my system, which only has one disk.
- * It's Western Digital WDAC2850, with PIO mode 3. The PCI bus
- * is at 20 MHz (I have DX2/80, I tried PCI at 40, but I got random
- * lockups). I tried the OCTEK double speed CD-ROM and
- * it does not work! But I can't boot DOS also, so it's probably
- * hardware fault. I have connected Conner 80MB, the Seagate 850MB (no
- * problems) and Seagate 1GB (as slave, WD as master). My experiences
- * with the third, 1GB drive: I got 3MB/s (hdparm), but sometimes
- * it slows to about 100kB/s! I don't know why and I have
- * not this drive now, so I can't try it again.
- * I write this driver because I lost the paper ("manual") with
- * settings of jumpers on the card and I have to boot Linux with
- * Loadlin except LILO, cause I have to run the setupvic.exe program
- * already or I get disk errors (my test: rpm -Vf
- * /usr/X11R6/bin/XF86_SVGA - or any big file).
- * Some numbers from hdparm -t /dev/hda:
- * Timing buffer-cache reads:   32 MB in  3.02 seconds =10.60 MB/sec
- * Timing buffered disk reads:  16 MB in  5.52 seconds = 2.90 MB/sec
- * I have 4 Megs/s before, but I don't know why (maybe changes
- * in hdparm test).
- * After release of 0.1, I got some successful reports, so it might work.
- *
- * The main problem with OPTi is that some timings for master
- * and slave must be the same. For example, if you have master
- * PIO 3 and slave PIO 0, driver have to set some timings of
- * master for PIO 0. Second problem is that opti621_set_pio_mode
- * got only one drive to set, but have to set both drives.
- * This is solved in compute_pios. If you don't set
- * the second drive, compute_pios use ide_get_best_pio_mode
- * for autoselect mode (you can change it to PIO 0, if you want).
- * If you then set the second drive to another PIO, the old value
- * (automatically selected) will be overrided by yours.
- * There is a 25/33MHz switch in configuration
- * register, but driver is written for use at any frequency.
- *
- * Version 0.1, Nov 8, 1996
- * by Jaromir Koutek, for 2.1.8.
- * Initial version of driver.
- *
- * Version 0.2
- * Number 0.2 skipped.
- *
- * Version 0.3, Nov 29, 1997
- * by Mark Lord (probably), for 2.1.68
- * Updates for use with new IDE block driver.
- *
- * Version 0.4, Dec 14, 1997
- * by Jan Harkes
- * Fixed some errors and cleaned the code.
- *
- * Version 0.5, Jan 2, 1998
- * by Jaromir Koutek
- * Updates for use with (again) new IDE block driver.
- * Update of documentation.
- *
- * Version 0.6, Jan 2, 1999
- * by Jaromir Koutek
- * Reversed to version 0.3 of the driver, because
- * 0.5 doesn't work.
  */
 
 #include <linux/types.h>
@@ -133,12 +62,12 @@ static u8 read_reg(int reg)
 	return ret;
 }
 
-static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void opti621_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	ide_drive_t *pair = ide_get_pair_dev(drive);
 	unsigned long flags;
-	unsigned long mode = XFER_PIO_0 + pio, pair_mode;
+	unsigned long mode = drive->pio_mode, pair_mode;
+	const u8 pio = mode - XFER_PIO_0;
 	u8 tim, misc, addr_pio = pio, clk;
 
 	/* DRDY is default 2 (by OPTi Databook) */
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/palm_bk3710.c linux-libre-2.6.34-gnu1/drivers/ide/palm_bk3710.c
--- linux-libre-2.6.33-gnu1/drivers/ide/palm_bk3710.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/palm_bk3710.c	2010-05-16 17:17:36.000000000 -0400
@@ -166,7 +166,7 @@ static void palm_bk3710_setpiomode(void
 	writel(val32, base + BK3710_DATRCVR);
 
 	if (mate) {
-		u8 mode2 = ide_get_best_pio_mode(mate, 255, 4);
+		u8 mode2 = mate->pio_mode - XFER_PIO_0;
 
 		if (mode2 < mode)
 			mode = mode2;
@@ -188,10 +188,11 @@ static void palm_bk3710_setpiomode(void
 	writel(val32, base + BK3710_REGRCVR);
 }
 
-static void palm_bk3710_set_dma_mode(ide_drive_t *drive, u8 xferspeed)
+static void palm_bk3710_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	int is_slave = drive->dn & 1;
-	void __iomem *base = (void *)drive->hwif->dma_base;
+	void __iomem *base = (void *)hwif->dma_base;
+	const u8 xferspeed = drive->dma_mode;
 
 	if (xferspeed >= XFER_UDMA_0) {
 		palm_bk3710_setudmamode(base, is_slave,
@@ -203,12 +204,13 @@ static void palm_bk3710_set_dma_mode(ide
 	}
 }
 
-static void palm_bk3710_set_pio_mode(ide_drive_t *drive, u8 pio)
+static void palm_bk3710_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	unsigned int cycle_time;
 	int is_slave = drive->dn & 1;
 	ide_drive_t *mate;
-	void __iomem *base = (void *)drive->hwif->dma_base;
+	void __iomem *base = (void *)hwif->dma_base;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 
 	/*
 	 * Obtain the drive PIO data for tuning the Palm Chip registers
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/pdc202xx_new.c linux-libre-2.6.34-gnu1/drivers/ide/pdc202xx_new.c
--- linux-libre-2.6.33-gnu1/drivers/ide/pdc202xx_new.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/pdc202xx_new.c	2010-05-16 17:17:36.000000000 -0400
@@ -129,11 +129,11 @@ static struct udma_timing {
 	{ 0x1a, 0x01, 0xcb },	/* UDMA mode 6 */
 };
 
-static void pdcnew_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void pdcnew_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	u8 adj			= (drive->dn & 1) ? 0x08 : 0x00;
+	const u8 speed		= drive->dma_mode;
 
 	/*
 	 * IDE core issues SETFEATURES_XFER to the drive first (thanks to
@@ -167,11 +167,11 @@ static void pdcnew_set_dma_mode(ide_driv
  	}
 }
 
-static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void pdcnew_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	struct pci_dev *dev = to_pci_dev(hwif->dev);
 	u8 adj = (drive->dn & 1) ? 0x08 : 0x00;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 
 	if (max_dma_rate(dev) == 4) {
 		set_indexed_reg(hwif, 0x0c + adj, pio_timings[pio].reg0c);
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/pdc202xx_old.c linux-libre-2.6.34-gnu1/drivers/ide/pdc202xx_old.c
--- linux-libre-2.6.33-gnu1/drivers/ide/pdc202xx_old.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/pdc202xx_old.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1998-2002		Andre Hedrick <andre@linux-ide.org>
  *  Copyright (C) 2006-2007, 2009	MontaVista Software, Inc.
- *  Copyright (C) 2007			Bartlomiej Zolnierkiewicz
+ *  Copyright (C) 2007-2010		Bartlomiej Zolnierkiewicz
  *
  *  Portions Copyright (C) 1999 Promise Technology, Inc.
  *  Author: Frank Tiernan (frankt@promise.com)
@@ -21,23 +21,15 @@
 
 #define DRV_NAME "pdc202xx_old"
 
-static void pdc_old_disable_66MHz_clock(ide_hwif_t *);
-
-static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
+static void pdc202xx_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	u8 drive_pci		= 0x60 + (drive->dn << 2);
+	const u8 speed		= drive->dma_mode;
 
 	u8			AP = 0, BP = 0, CP = 0;
 	u8			TA = 0, TB = 0, TC = 0;
 
-	/*
-	 * TODO: do this once per channel
-	 */
-	if (dev->device != PCI_DEVICE_ID_PROMISE_20246)
-		pdc_old_disable_66MHz_clock(hwif);
-
 	pci_read_config_byte(dev, drive_pci,     &AP);
 	pci_read_config_byte(dev, drive_pci + 1, &BP);
 	pci_read_config_byte(dev, drive_pci + 2, &CP);
@@ -84,9 +76,10 @@ static void pdc202xx_set_mode(ide_drive_
 	}
 }
 
-static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void pdc202xx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	pdc202xx_set_mode(drive, XFER_PIO_0 + pio);
+	drive->dma_mode = drive->pio_mode;
+	pdc202xx_set_mode(hwif, drive);
 }
 
 static int pdc202xx_test_irq(ide_hwif_t *hwif)
@@ -100,13 +93,13 @@ static int pdc202xx_test_irq(ide_hwif_t
 		 * bit 7: error, bit 6: interrupting,
 		 * bit 5: FIFO full, bit 4: FIFO empty
 		 */
-		return ((sc1d & 0x50) == 0x40) ? 1 : 0;
+		return ((sc1d & 0x50) == 0x50) ? 1 : 0;
 	} else	{
 		/*
 		 * bit 3: error, bit 2: interrupting,
 		 * bit 1: FIFO full, bit 0: FIFO empty
 		 */
-		return ((sc1d & 0x05) == 0x04) ? 1 : 0;
+		return ((sc1d & 0x05) == 0x05) ? 1 : 0;
 	}
 }
 
@@ -145,6 +138,11 @@ static void pdc_old_disable_66MHz_clock(
 	outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
 }
 
+static void pdc2026x_init_hwif(ide_hwif_t *hwif)
+{
+	pdc_old_disable_66MHz_clock(hwif);
+}
+
 static void pdc202xx_dma_start(ide_drive_t *drive)
 {
 	if (drive->current_speed > XFER_UDMA_2)
@@ -261,6 +259,7 @@ static const struct ide_dma_ops pdc2026x
 	{ \
 		.name		= DRV_NAME, \
 		.init_chipset	= init_chipset_pdc202xx, \
+		.init_hwif	= pdc2026x_init_hwif, \
 		.port_ops	= &pdc2026x_port_ops, \
 		.dma_ops	= &pdc2026x_dma_ops, \
 		.host_flags	= IDE_HFLAGS_PDC202XX, \
@@ -356,6 +355,6 @@ static void __exit pdc202xx_ide_exit(voi
 module_init(pdc202xx_ide_init);
 module_exit(pdc202xx_ide_exit);
 
-MODULE_AUTHOR("Andre Hedrick, Frank Tiernan");
+MODULE_AUTHOR("Andre Hedrick, Frank Tiernan, Bartlomiej Zolnierkiewicz");
 MODULE_DESCRIPTION("PCI driver module for older Promise IDE");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/piix.c linux-libre-2.6.34-gnu1/drivers/ide/piix.c
--- linux-libre-2.6.33-gnu1/drivers/ide/piix.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/piix.c	2010-05-16 17:17:36.000000000 -0400
@@ -59,15 +59,14 @@ static int no_piix_dma;
 
 /**
  *	piix_set_pio_mode	-	set host controller for PIO mode
+ *	@port: port
  *	@drive: drive
- *	@pio: PIO mode number
  *
  *	Set the interface PIO mode based upon the settings done by AMI BIOS.
  */
 
-static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void piix_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	int is_slave		= drive->dn & 1;
 	int master_port		= hwif->channel ? 0x42 : 0x40;
@@ -77,6 +76,7 @@ static void piix_set_pio_mode(ide_drive_
 	u8 slave_data;
 	static DEFINE_SPINLOCK(tune_lock);
 	int control = 0;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 
 				     /* ISP  RTC */
 	static const u8 timings[][2]= {
@@ -127,16 +127,15 @@ static void piix_set_pio_mode(ide_drive_
 
 /**
  *	piix_set_dma_mode	-	set host controller for DMA mode
+ *	@hwif: port
  *	@drive: drive
- *	@speed: DMA mode
  *
  *	Set a PIIX host controller to the desired DMA mode.  This involves
  *	programming the right timing data into the PCI configuration space.
  */
 
-static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void piix_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	u8 maslave		= hwif->channel ? 0x42 : 0x40;
 	int a_speed		= 3 << (drive->dn * 4);
@@ -147,6 +146,7 @@ static void piix_set_dma_mode(ide_drive_
 	int			sitre;
 	u16			reg4042, reg4a;
 	u8			reg48, reg54, reg55;
+	const u8 speed		= drive->dma_mode;
 
 	pci_read_config_word(dev, maslave, &reg4042);
 	sitre = (reg4042 & 0x4000) ? 1 : 0;
@@ -176,7 +176,6 @@ static void piix_set_dma_mode(ide_drive_
 			pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
 	} else {
 		const u8 mwdma_to_pio[] = { 0, 3, 4 };
-		u8 pio;
 
 		if (reg48 & u_flag)
 			pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
@@ -188,11 +187,12 @@ static void piix_set_dma_mode(ide_drive_
 			pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
 
 		if (speed >= XFER_MW_DMA_0)
-			pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
+			drive->pio_mode =
+				mwdma_to_pio[speed - XFER_MW_DMA_0] + XFER_PIO_0;
 		else
-			pio = 2; /* only SWDMA2 is allowed */
+			drive->pio_mode = XFER_PIO_2; /* for SWDMA2 */
 
-		piix_set_pio_mode(drive, pio);
+		piix_set_pio_mode(hwif, drive);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/pmac.c linux-libre-2.6.34-gnu1/drivers/ide/pmac.c
--- linux-libre-2.6.33-gnu1/drivers/ide/pmac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/pmac.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/adb.h>
 #include <linux/pmu.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 #include <asm/prom.h>
 #include <asm/io.h>
@@ -496,12 +497,11 @@ static void pmac_write_devctl(ide_hwif_t
 /*
  * Old tuning functions (called on hdparm -p), sets up drive PIO timings
  */
-static void
-pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void pmac_ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	pmac_ide_hwif_t *pmif =
 		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 	struct ide_timing *tim = ide_timing_find_mode(XFER_PIO_0 + pio);
 	u32 *timings, t;
 	unsigned accessTicks, recTicks;
@@ -778,14 +778,14 @@ set_timings_mdma(ide_drive_t *drive, int
 #endif	
 }
 
-static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void pmac_ide_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	pmac_ide_hwif_t *pmif =
 		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
 	int ret = 0;
 	u32 *timings, *timings2, tl[2];
 	u8 unit = drive->dn & 1;
+	const u8 speed = drive->dma_mode;
 
 	timings = &pmif->timings[unit];
 	timings2 = &pmif->timings[unit+2];
@@ -1651,8 +1651,8 @@ pmac_ide_dma_test_irq (ide_drive_t *driv
 		if ((status & FLUSH) == 0)
 			break;
 		if (++timeout > 100) {
-			printk(KERN_WARNING "ide%d, ide_dma_test_irq \
-			timeout flushing channel\n", hwif->index);
+			printk(KERN_WARNING "ide%d, ide_dma_test_irq timeout flushing channel\n",
+			       hwif->index);
 			break;
 		}
 	}	
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/qd65xx.c linux-libre-2.6.34-gnu1/drivers/ide/qd65xx.c
--- linux-libre-2.6.33-gnu1/drivers/ide/qd65xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/qd65xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -189,15 +189,13 @@ static void qd_set_timing (ide_drive_t *
 	printk(KERN_DEBUG "%s: %#x\n", drive->name, timing);
 }
 
-static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void qd6500_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	u16 *id = drive->id;
 	int active_time   = 175;
 	int recovery_time = 415; /* worst case values from the dos driver */
 
-	/*
-	 * FIXME: use "pio" value
-	 */
+	/* FIXME: use drive->pio_mode value */
 	if (!qd_find_disk_type(drive, &active_time, &recovery_time) &&
 	    (id[ATA_ID_OLD_PIO_MODES] & 0xff) && (id[ATA_ID_FIELD_VALID] & 2) &&
 	    id[ATA_ID_EIDE_PIO] >= 240) {
@@ -211,9 +209,9 @@ static void qd6500_set_pio_mode(ide_driv
 				active_time, recovery_time));
 }
 
-static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void qd6580_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 	struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
 	unsigned int cycle_time;
 	int active_time   = 175;
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/rapide.c linux-libre-2.6.34-gnu1/drivers/ide/rapide.c
--- linux-libre-2.6.33-gnu1/drivers/ide/rapide.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/rapide.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/errno.h>
 #include <linux/ide.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/sc1200.c linux-libre-2.6.34-gnu1/drivers/ide/sc1200.c
--- linux-libre-2.6.33-gnu1/drivers/ide/sc1200.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/sc1200.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ide.h>
@@ -122,13 +123,13 @@ out:
 	return mask;
 }
 
-static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode)
+static void sc1200_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t		*hwif = drive->hwif;
 	struct pci_dev		*dev = to_pci_dev(hwif->dev);
 	unsigned int		reg, timings;
 	unsigned short		pci_clock;
 	unsigned int		basereg = hwif->channel ? 0x50 : 0x40;
+	const u8		mode = drive->dma_mode;
 
 	static const u32 udma_timing[3][3] = {
 		{ 0x00921250, 0x00911140, 0x00911030 },
@@ -193,10 +194,10 @@ static int sc1200_dma_end(ide_drive_t *d
  * will have valid default PIO timings set up before we get here.
  */
 
-static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void sc1200_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t	*hwif = drive->hwif;
 	int		mode = -1;
+	const u8	pio = drive->pio_mode - XFER_PIO_0;
 
 	/*
 	 * bad abuse of ->set_pio_mode interface
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/scc_pata.c linux-libre-2.6.34-gnu1/drivers/ide/scc_pata.c
--- linux-libre-2.6.33-gnu1/drivers/ide/scc_pata.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/scc_pata.c	2010-05-16 17:17:36.000000000 -0400
@@ -199,16 +199,15 @@ scc_ide_outsl(unsigned long port, void *
 
 /**
  *	scc_set_pio_mode	-	set host controller for PIO mode
+ *	@hwif: port
  *	@drive: drive
- *	@pio: PIO mode number
  *
  *	Load the timing settings for this device mode into the
  *	controller.
  */
 
-static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void scc_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	struct scc_ports *ports = ide_get_hwifdata(hwif);
 	unsigned long ctl_base = ports->ctl;
 	unsigned long cckctrl_port = ctl_base + 0xff0;
@@ -216,6 +215,7 @@ static void scc_set_pio_mode(ide_drive_t
 	unsigned long pioct_port = ctl_base + 0x004;
 	unsigned long reg;
 	int offset;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 
 	reg = in_be32((void __iomem *)cckctrl_port);
 	if (reg & CCKCTRL_ATACLKOEN) {
@@ -231,16 +231,15 @@ static void scc_set_pio_mode(ide_drive_t
 
 /**
  *	scc_set_dma_mode	-	set host controller for DMA mode
+ *	@hwif: port
  *	@drive: drive
- *	@speed: DMA mode
  *
  *	Load the timing settings for this device mode into the
  *	controller.
  */
 
-static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void scc_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	struct scc_ports *ports = ide_get_hwifdata(hwif);
 	unsigned long ctl_base = ports->ctl;
 	unsigned long cckctrl_port = ctl_base + 0xff0;
@@ -254,6 +253,7 @@ static void scc_set_dma_mode(ide_drive_t
 	int offset, idx;
 	unsigned long reg;
 	unsigned long jcactsel;
+	const u8 speed = drive->dma_mode;
 
 	reg = in_be32((void __iomem *)cckctrl_port);
 	if (reg & CCKCTRL_ATACLKOEN) {
@@ -872,20 +872,18 @@ static struct pci_driver scc_pci_driver
 	.remove = __devexit_p(scc_remove),
 };
 
-static int scc_ide_init(void)
+static int __init scc_ide_init(void)
 {
 	return ide_pci_register_driver(&scc_pci_driver);
 }
 
-module_init(scc_ide_init);
-/* -- No exit code?
-static void scc_ide_exit(void)
+static void __exit scc_ide_exit(void)
 {
-	ide_pci_unregister_driver(&scc_pci_driver);
+	pci_unregister_driver(&scc_pci_driver);
 }
-module_exit(scc_ide_exit);
- */
 
+module_init(scc_ide_init);
+module_exit(scc_ide_exit);
 
 MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/serverworks.c linux-libre-2.6.34-gnu1/drivers/ide/serverworks.c
--- linux-libre-2.6.33-gnu1/drivers/ide/serverworks.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/serverworks.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  * Copyright (C) 1998-2000 Michel Aubry
  * Copyright (C) 1998-2000 Andrzej Krzysztofowicz
  * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
- * Copyright (C)      2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
  * Portions copyright (c) 2001 Sun Microsystems
  *
  *
@@ -52,8 +52,6 @@ static const char *svwks_bad_ata100[] =
 	NULL
 };
 
-static struct pci_dev *isa_dev;
-
 static int check_in_drive_lists (ide_drive_t *drive, const char **list)
 {
 	char *m = (char *)&drive->id[ATA_ID_PROD];
@@ -67,26 +65,14 @@ static int check_in_drive_lists (ide_dri
 static u8 svwks_udma_filter(ide_drive_t *drive)
 {
 	struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
-	u8 mask = 0;
 
-	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE)
+	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE) {
 		return 0x1f;
-	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
-		u32 reg = 0;
-		if (isa_dev)
-			pci_read_config_dword(isa_dev, 0x64, &reg);
-			
-		/*
-		 *	Don't enable UDMA on disk devices for the moment
-		 */
-		if(drive->media == ide_disk)
-			return 0;
-		/* Check the OSB4 DMA33 enable bit */
-		return ((reg & 0x00004000) == 0x00004000) ? 0x07 : 0;
 	} else if (dev->revision < SVWKS_CSB5_REVISION_NEW) {
 		return 0x07;
-	} else if (dev->revision >= SVWKS_CSB5_REVISION_NEW) {
-		u8 btr = 0, mode;
+	} else {
+		u8 btr = 0, mode, mask;
+
 		pci_read_config_byte(dev, 0x5A, &btr);
 		mode = btr & 0x3;
 
@@ -101,13 +87,9 @@ static u8 svwks_udma_filter(ide_drive_t
 		case 1:	 mask = 0x07; break;
 		default: mask = 0x00; break;
 		}
-	}
-	if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
-	     (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) &&
-	    (!(PCI_FUNC(dev->devfn) & 1)))
-		mask = 0x1f;
 
-	return mask;
+		return mask;
+	}
 }
 
 static u8 svwks_csb_check (struct pci_dev *dev)
@@ -124,12 +106,13 @@ static u8 svwks_csb_check (struct pci_de
 	return 0;
 }
 
-static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void svwks_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
 	static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 };
 
-	struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
+	struct pci_dev *dev = to_pci_dev(hwif->dev);
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 
 	pci_write_config_byte(dev, drive_pci[drive->dn], pio_modes[pio]);
 
@@ -145,14 +128,14 @@ static void svwks_set_pio_mode(ide_drive
 	}
 }
 
-static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void svwks_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	static const u8 udma_modes[]		= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
 	static const u8 dma_modes[]		= { 0x77, 0x21, 0x20 };
 	static const u8 drive_pci2[]		= { 0x45, 0x44, 0x47, 0x46 };
 
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
+	const u8 speed		= drive->dma_mode;
 	u8 unit			= drive->dn & 1;
 
 	u8 ultra_enable	 = 0, ultra_timing = 0, dma_timing = 0;
@@ -185,8 +168,9 @@ static int init_chipset_svwks(struct pci
 
 	/* OSB4 : South Bridge and IDE */
 	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
-		isa_dev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
-			  PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL);
+		struct pci_dev *isa_dev =
+			pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
+					PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL);
 		if (isa_dev) {
 			pci_read_config_dword(isa_dev, 0x64, &reg);
 			reg &= ~0x00002000; /* disable 600ns interrupt mask */
@@ -195,6 +179,7 @@ static int init_chipset_svwks(struct pci
 					"enabled.\n", pci_name(dev));
 			reg |=  0x00004000; /* enable UDMA/33 support */
 			pci_write_config_dword(isa_dev, 0x64, reg);
+			pci_dev_put(isa_dev);
 		}
 	}
 
@@ -343,7 +328,6 @@ static u8 svwks_cable_detect(ide_hwif_t
 static const struct ide_port_ops osb4_port_ops = {
 	.set_pio_mode		= svwks_set_pio_mode,
 	.set_dma_mode		= svwks_set_dma_mode,
-	.udma_filter		= svwks_udma_filter,
 };
 
 static const struct ide_port_ops svwks_port_ops = {
@@ -460,6 +444,6 @@ static void __exit svwks_ide_exit(void)
 module_init(svwks_ide_init);
 module_exit(svwks_ide_exit);
 
-MODULE_AUTHOR("Michael Aubry. Andrzej Krzysztofowicz, Andre Hedrick");
+MODULE_AUTHOR("Michael Aubry. Andrzej Krzysztofowicz, Andre Hedrick, Bartlomiej Zolnierkiewicz");
 MODULE_DESCRIPTION("PCI driver module for Serverworks OSB4/CSB5/CSB6 IDE");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/sgiioc4.c linux-libre-2.6.34-gnu1/drivers/ide/sgiioc4.c
--- linux-libre-2.6.33-gnu1/drivers/ide/sgiioc4.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/sgiioc4.c	2010-05-16 17:17:36.000000000 -0400
@@ -255,7 +255,7 @@ static int sgiioc4_dma_end(ide_drive_t *
 	return dma_stat;
 }
 
-static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void sgiioc4_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/siimage.c linux-libre-2.6.34-gnu1/drivers/ide/siimage.c
--- linux-libre-2.6.33-gnu1/drivers/ide/siimage.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/siimage.c	2010-05-16 17:17:36.000000000 -0400
@@ -229,19 +229,18 @@ static u8 sil_sata_udma_filter(ide_drive
 
 /**
  *	sil_set_pio_mode	-	set host controller for PIO mode
+ *	@hwif: port
  *	@drive: drive
- *	@pio: PIO mode number
  *
  *	Load the timing settings for this device mode into the
  *	controller.
  */
 
-static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
+static void sil_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	static const u16 tf_speed[]   = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
 	static const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
 
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	ide_drive_t *pair	= ide_get_pair_dev(drive);
 	u32 speedt		= 0;
@@ -249,6 +248,7 @@ static void sil_set_pio_mode(ide_drive_t
 	unsigned long addr	= siimage_seldev(drive, 0x04);
 	unsigned long tfaddr	= siimage_selreg(hwif,	0x02);
 	unsigned long base	= (unsigned long)hwif->hwif_data;
+	const u8 pio		= drive->pio_mode - XFER_PIO_0;
 	u8 tf_pio		= pio;
 	u8 mmio			= (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
 	u8 addr_mask		= hwif->channel ? (mmio ? 0xF4 : 0x84)
@@ -258,7 +258,7 @@ static void sil_set_pio_mode(ide_drive_t
 
 	/* trim *taskfile* PIO to the slowest of the master/slave */
 	if (pair) {
-		u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4);
+		u8 pair_pio = pair->pio_mode - XFER_PIO_0;
 
 		if (pair_pio < tf_pio)
 			tf_pio = pair_pio;
@@ -289,19 +289,18 @@ static void sil_set_pio_mode(ide_drive_t
 
 /**
  *	sil_set_dma_mode	-	set host controller for DMA mode
+ *	@hwif: port
  *	@drive: drive
- *	@speed: DMA mode
  *
  *	Tune the SiI chipset for the desired DMA mode.
  */
 
-static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void sil_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	static const u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
 	static const u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };
 	static const u16 dma[]	 = { 0x2208, 0x10C2, 0x10C1 };
 
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	unsigned long base	= (unsigned long)hwif->hwif_data;
 	u16 ultra = 0, multi	= 0;
@@ -311,6 +310,7 @@ static void sil_set_dma_mode(ide_drive_t
 						: (mmio ? 0xB4 : 0x80);
 	unsigned long ma	= siimage_seldev(drive, 0x08);
 	unsigned long ua	= siimage_seldev(drive, 0x0C);
+	const u8 speed		= drive->dma_mode;
 
 	scsc  = sil_ioread8 (dev, base + (mmio ? 0x4A : 0x8A));
 	mode  = sil_ioread8 (dev, base + addr_mask);
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/sis5513.c linux-libre-2.6.34-gnu1/drivers/ide/sis5513.c
--- linux-libre-2.6.33-gnu1/drivers/ide/sis5513.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/sis5513.c	2010-05-16 17:17:36.000000000 -0400
@@ -290,10 +290,10 @@ static void config_drive_art_rwp(ide_dri
 		pci_write_config_byte(dev, 0x4b, rw_prefetch);
 }
 
-static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void sis_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	config_drive_art_rwp(drive);
-	sis_program_timings(drive, XFER_PIO_0 + pio);
+	sis_program_timings(drive, drive->pio_mode);
 }
 
 static void sis_ata133_program_udma_timings(ide_drive_t *drive, const u8 mode)
@@ -340,8 +340,10 @@ static void sis_program_udma_timings(ide
 		sis_ata33_program_udma_timings(drive, mode);
 }
 
-static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void sis_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
+	const u8 speed = drive->dma_mode;
+
 	if (speed >= XFER_UDMA_0)
 		sis_program_udma_timings(drive, speed);
 	else
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/sl82c105.c linux-libre-2.6.34-gnu1/drivers/ide/sl82c105.c
--- linux-libre-2.6.33-gnu1/drivers/ide/sl82c105.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/sl82c105.c	2010-05-16 17:17:36.000000000 -0400
@@ -63,12 +63,13 @@ static unsigned int get_pio_timings(ide_
 /*
  * Configure the chipset for PIO mode.
  */
-static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void sl82c105_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	struct pci_dev *dev	= to_pci_dev(drive->hwif->dev);
+	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	unsigned long timings	= (unsigned long)ide_get_drivedata(drive);
 	int reg			= 0x44 + drive->dn * 4;
 	u16 drv_ctrl;
+	const u8 pio		= drive->pio_mode - XFER_PIO_0;
 
 	drv_ctrl = get_pio_timings(drive, pio);
 
@@ -91,11 +92,12 @@ static void sl82c105_set_pio_mode(ide_dr
 /*
  * Configure the chipset for DMA mode.
  */
-static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void sl82c105_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
 	static u16 mwdma_timings[] = {0x0707, 0x0201, 0x0200};
 	unsigned long timings = (unsigned long)ide_get_drivedata(drive);
 	u16 drv_ctrl;
+	const u8 speed = drive->dma_mode;
 
 	drv_ctrl = mwdma_timings[speed - XFER_MW_DMA_0];
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/slc90e66.c linux-libre-2.6.34-gnu1/drivers/ide/slc90e66.c
--- linux-libre-2.6.33-gnu1/drivers/ide/slc90e66.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/slc90e66.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,9 +18,8 @@
 
 static DEFINE_SPINLOCK(slc90e66_lock);
 
-static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void slc90e66_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	int is_slave		= drive->dn & 1;
 	int master_port		= hwif->channel ? 0x42 : 0x40;
@@ -29,6 +28,8 @@ static void slc90e66_set_pio_mode(ide_dr
 	u16 master_data;
 	u8 slave_data;
 	int control = 0;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
+
 				     /* ISP  RTC */
 	static const u8 timings[][2] = {
 					{ 0, 0 },
@@ -71,14 +72,14 @@ static void slc90e66_set_pio_mode(ide_dr
 	spin_unlock_irqrestore(&slc90e66_lock, flags);
 }
 
-static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void slc90e66_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	u8 maslave		= hwif->channel ? 0x42 : 0x40;
 	int sitre = 0, a_speed	= 7 << (drive->dn * 4);
 	int u_speed = 0, u_flag = 1 << drive->dn;
 	u16			reg4042, reg44, reg48, reg4a;
+	const u8 speed		= drive->dma_mode;
 
 	pci_read_config_word(dev, maslave, &reg4042);
 	sitre = (reg4042 & 0x4000) ? 1 : 0;
@@ -98,7 +99,6 @@ static void slc90e66_set_dma_mode(ide_dr
 		}
 	} else {
 		const u8 mwdma_to_pio[] = { 0, 3, 4 };
-		u8 pio;
 
 		if (reg48 & u_flag)
 			pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
@@ -106,11 +106,12 @@ static void slc90e66_set_dma_mode(ide_dr
 			pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
 
 		if (speed >= XFER_MW_DMA_0)
-			pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
+			drive->pio_mode =
+				mwdma_to_pio[speed - XFER_MW_DMA_0] + XFER_PIO_0;
 		else
-			pio = 2; /* only SWDMA2 is allowed */
+			drive->pio_mode = XFER_PIO_2; /* for SWDMA2 */
 
-		slc90e66_set_pio_mode(drive, pio);
+		slc90e66_set_pio_mode(hwif, drive);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/tc86c001.c linux-libre-2.6.34-gnu1/drivers/ide/tc86c001.c
--- linux-libre-2.6.33-gnu1/drivers/ide/tc86c001.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/tc86c001.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,11 +13,11 @@
 
 #define DRV_NAME "tc86c001"
 
-static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed)
+static void tc86c001_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
 	unsigned long scr_port	= hwif->config_data + (drive->dn ? 0x02 : 0x00);
 	u16 mode, scr		= inw(scr_port);
+	const u8 speed		= drive->dma_mode;
 
 	switch (speed) {
 	case XFER_UDMA_4:	mode = 0x00c0; break;
@@ -41,9 +41,10 @@ static void tc86c001_set_mode(ide_drive_
 	outw(scr, scr_port);
 }
 
-static void tc86c001_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void tc86c001_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	tc86c001_set_mode(drive, XFER_PIO_0 + pio);
+	drive->dma_mode = drive->pio_mode;
+	tc86c001_set_mode(hwif, drive);
 }
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/triflex.c linux-libre-2.6.34-gnu1/drivers/ide/triflex.c
--- linux-libre-2.6.33-gnu1/drivers/ide/triflex.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/triflex.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,9 +34,8 @@
 
 #define DRV_NAME "triflex"
 
-static void triflex_set_mode(ide_drive_t *drive, const u8 speed)
+static void triflex_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	struct pci_dev *dev = to_pci_dev(hwif->dev);
 	u32 triflex_timings = 0;
 	u16 timing = 0;
@@ -44,7 +43,7 @@ static void triflex_set_mode(ide_drive_t
 
 	pci_read_config_dword(dev, channel_offset, &triflex_timings);
 
-	switch(speed) {
+	switch (drive->dma_mode) {
 		case XFER_MW_DMA_2:
 			timing = 0x0103; 
 			break;
@@ -82,9 +81,10 @@ static void triflex_set_mode(ide_drive_t
 	pci_write_config_dword(dev, channel_offset, triflex_timings);
 }
 
-static void triflex_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void triflex_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	triflex_set_mode(drive, XFER_PIO_0 + pio);
+	drive->dma_mode = drive->pio_mode;
+	triflex_set_mode(hwif, drive);
 }
 
 static const struct ide_port_ops triflex_port_ops = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/tx4938ide.c linux-libre-2.6.34-gnu1/drivers/ide/tx4938ide.c
--- linux-libre-2.6.33-gnu1/drivers/ide/tx4938ide.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/tx4938ide.c	2010-05-16 17:17:36.000000000 -0400
@@ -56,16 +56,15 @@ static void tx4938ide_tune_ebusc(unsigne
 		     &tx4938_ebuscptr->cr[ebus_ch]);
 }
 
-static void tx4938ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void tx4938ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	struct tx4938ide_platform_info *pdata = hwif->dev->platform_data;
-	u8 safe = pio;
+	u8 safe = drive->pio_mode - XFER_PIO_0;
 	ide_drive_t *pair;
 
 	pair = ide_get_pair_dev(drive);
 	if (pair)
-		safe = min(safe, ide_get_best_pio_mode(pair, 255, 5));
+		safe = min(safe, pair->pio_mode - XFER_PIO_0);
 	tx4938ide_tune_ebusc(pdata->ebus_ch, pdata->gbus_clock, safe);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/tx4939ide.c linux-libre-2.6.34-gnu1/drivers/ide/tx4939ide.c
--- linux-libre-2.6.33-gnu1/drivers/ide/tx4939ide.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/tx4939ide.c	2010-05-16 17:17:36.000000000 -0400
@@ -104,17 +104,17 @@ static void tx4939ide_writeb(u8 val, voi
 
 #define TX4939IDE_BASE(hwif)	((void __iomem *)(hwif)->extra_base)
 
-static void tx4939ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void tx4939ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	int is_slave = drive->dn;
 	u32 mask, val;
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 	u8 safe = pio;
 	ide_drive_t *pair;
 
 	pair = ide_get_pair_dev(drive);
 	if (pair)
-		safe = min(safe, ide_get_best_pio_mode(pair, 255, 4));
+		safe = min(safe, pair->pio_mode - XFER_PIO_0);
 	/*
 	 * Update Command Transfer Mode for master/slave and Data
 	 * Transfer Mode for this drive.
@@ -125,10 +125,10 @@ static void tx4939ide_set_pio_mode(ide_d
 	/* tx4939ide_tf_load_fixup() will set the Sys_Ctl register */
 }
 
-static void tx4939ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
+static void tx4939ide_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	u32 mask, val;
+	const u8 mode = drive->dma_mode;
 
 	/* Update Data Transfer Mode for this drive. */
 	if (mode >= XFER_UDMA_0)
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/umc8672.c linux-libre-2.6.34-gnu1/drivers/ide/umc8672.c
--- linux-libre-2.6.33-gnu1/drivers/ide/umc8672.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/umc8672.c	2010-05-16 17:17:36.000000000 -0400
@@ -104,10 +104,11 @@ static void umc_set_speeds(u8 speeds[])
 		speeds[0], speeds[1], speeds[2], speeds[3]);
 }
 
-static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void umc_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif, *mate = hwif->mate;
+	ide_hwif_t *mate = hwif->mate;
 	unsigned long uninitialized_var(flags);
+	const u8 pio = drive->pio_mode - XFER_PIO_0;
 
 	printk("%s: setting umc8672 to PIO mode%d (speed %d)\n",
 		drive->name, pio, pio_to_umc[pio]);
diff -druNp linux-libre-2.6.33-gnu1/drivers/ide/via82cxxx.c linux-libre-2.6.34-gnu1/drivers/ide/via82cxxx.c
--- linux-libre-2.6.33-gnu1/drivers/ide/via82cxxx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ide/via82cxxx.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *   vt8235, vt8237, vt8237a
  *
  * Copyright (c) 2000-2002 Vojtech Pavlik
- * Copyright (c) 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (c) 2007-2010 Bartlomiej Zolnierkiewicz
  *
  * Based on the work of:
  *	Michel Aubry
@@ -26,6 +26,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ide.h>
@@ -54,6 +55,11 @@
 #define VIA_NO_UNMASK		0x08 /* Doesn't work with IRQ unmasking on */
 #define VIA_BAD_ID		0x10 /* Has wrong vendor ID (0x1107) */
 #define VIA_BAD_AST		0x20 /* Don't touch Address Setup Timing */
+#define VIA_SATA_PATA		0x80 /* SATA/PATA combined configuration */
+
+enum {
+	VIA_IDFLAG_SINGLE = (1 << 1), /* single channel controller */
+};
 
 /*
  * VIA SouthBridge chips.
@@ -67,11 +73,13 @@ 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 },
+	{ "vx855",	PCI_DEVICE_ID_VIA_VX855,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
+	{ "vx800",	PCI_DEVICE_ID_VIA_VX800,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
+	{ "cx700",	PCI_DEVICE_ID_VIA_CX700,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
+	{ "vt8261",	PCI_DEVICE_ID_VIA_8261,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
 	{ "vt8237s",	PCI_DEVICE_ID_VIA_8237S,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
 	{ "vt6410",	PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+	{ "vt6415",	PCI_DEVICE_ID_VIA_6410,     0x00, 0xff, ATA_UDMA6, VIA_BAD_AST },
 	{ "vt8251",	PCI_DEVICE_ID_VIA_8251,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
 	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
 	{ "vt8237a",	PCI_DEVICE_ID_VIA_8237A,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
@@ -92,6 +100,7 @@ static struct via_isa_bridge {
 	{ "vt82c586",	PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f,      0x00, VIA_SET_FIFO },
 	{ "vt82c576",	PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f,      0x00, VIA_SET_FIFO | VIA_NO_UNMASK },
 	{ "vt82c576",	PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f,      0x00, VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
+	{ "vtxxxx",	PCI_DEVICE_ID_VIA_ANON,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
 	{ NULL }
 };
 
@@ -137,30 +146,45 @@ static void via_set_speed(ide_hwif_t *hw
 	case ATA_UDMA4: t = timing->udma ? (0xe8 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x0f; break;
 	case ATA_UDMA5: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break;
 	case ATA_UDMA6: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break;
-	default: return;
 	}
 
-	pci_write_config_byte(dev, VIA_UDMA_TIMING + (3 - dn), t);
+	/* Set UDMA unless device is not UDMA capable */
+	if (vdev->via_config->udma_mask) {
+		u8 udma_etc;
+
+		pci_read_config_byte(dev, VIA_UDMA_TIMING + 3 - dn, &udma_etc);
+
+		/* clear transfer mode bit */
+		udma_etc &= ~0x20;
+
+		if (timing->udma) {
+			/* preserve 80-wire cable detection bit */
+			udma_etc &= 0x10;
+			udma_etc |= t;
+		}
+
+		pci_write_config_byte(dev, VIA_UDMA_TIMING + 3 - dn, udma_etc);
+	}
 }
 
 /**
  *	via_set_drive		-	configure transfer mode
+ *	@hwif: port
  *	@drive: Drive to set up
- *	@speed: desired speed
  *
  *	via_set_drive() computes timing values configures the chipset to
  *	a desired transfer mode.  It also can be called by upper layers.
  */
 
-static void via_set_drive(ide_drive_t *drive, const u8 speed)
+static void via_set_drive(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	ide_drive_t *peer = ide_get_pair_dev(drive);
 	struct pci_dev *dev = to_pci_dev(hwif->dev);
 	struct ide_host *host = pci_get_drvdata(dev);
 	struct via82cxxx_dev *vdev = host->host_priv;
 	struct ide_timing t, p;
 	unsigned int T, UT;
+	const u8 speed = drive->dma_mode;
 
 	T = 1000000000 / via_clock;
 
@@ -175,7 +199,7 @@ static void via_set_drive(ide_drive_t *d
 	ide_timing_compute(drive, speed, &t, T, UT);
 
 	if (peer) {
-		ide_timing_compute(peer, peer->current_speed, &p, T, UT);
+		ide_timing_compute(peer, peer->pio_mode, &p, T, UT);
 		ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
 	}
 
@@ -184,22 +208,24 @@ static void via_set_drive(ide_drive_t *d
 
 /**
  *	via_set_pio_mode	-	set host controller for PIO mode
+ *	@hwif: port
  *	@drive: drive
- *	@pio: PIO mode number
  *
  *	A callback from the upper layers for PIO-only tuning.
  */
 
-static void via_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void via_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-	via_set_drive(drive, XFER_PIO_0 + pio);
+	drive->dma_mode = drive->pio_mode;
+	via_set_drive(hwif, drive);
 }
 
 static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
 {
 	struct via_isa_bridge *via_config;
 
-	for (via_config = via_isa_bridges; via_config->id; via_config++)
+	for (via_config = via_isa_bridges;
+	     via_config->id != PCI_DEVICE_ID_VIA_ANON; via_config++)
 		if ((*isa = pci_get_device(PCI_VENDOR_ID_VIA +
 			!!(via_config->flags & VIA_BAD_ID),
 			via_config->id, NULL))) {
@@ -362,6 +388,9 @@ static u8 via82cxxx_cable_detect(ide_hwi
 	if (via_cable_override(pdev))
 		return ATA_CBL_PATA40_SHORT;
 
+	if ((vdev->via_config->flags & VIA_SATA_PATA) && hwif->channel == 0)
+		return ATA_CBL_SATA;
+
 	if ((vdev->via_80w >> hwif->channel) & 1)
 		return ATA_CBL_PATA80;
 	else
@@ -402,11 +431,6 @@ static int __devinit via_init_one(struct
 	 * Find the ISA bridge and check we know what it is.
 	 */
 	via_config = via_config_find(&isa);
-	if (!via_config->id) {
-		printk(KERN_WARNING DRV_NAME " %s: unknown chipset, skipping\n",
-			pci_name(dev));
-		return -ENODEV;
-	}
 
 	/*
 	 * Print the boot message.
@@ -436,10 +460,13 @@ static int __devinit via_init_one(struct
 		via_clock = 33333;
 	}
 
-	if (idx == 0)
-		d.host_flags |= IDE_HFLAG_NO_AUTODMA;
-	else
+	if (idx == 1)
 		d.enablebits[1].reg = d.enablebits[0].reg = 0;
+	else
+		d.host_flags |= IDE_HFLAG_NO_AUTODMA;
+
+	if (idx == VIA_IDFLAG_SINGLE)
+		d.host_flags |= IDE_HFLAG_SINGLE;
 
 	if ((via_config->flags & VIA_NO_UNMASK) == 0)
 		d.host_flags |= IDE_HFLAG_UNMASK_IRQS;
@@ -475,8 +502,9 @@ 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_VX855_IDE), VIA_IDFLAG_SINGLE },
 	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410),      1 },
+	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6415),      1 },
 	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), 1 },
 	{ 0, },
 };
@@ -504,6 +532,6 @@ static void __exit via_ide_exit(void)
 module_init(via_ide_init);
 module_exit(via_ide_exit);
 
-MODULE_AUTHOR("Vojtech Pavlik, Michel Aubry, Jeff Garzik, Andre Hedrick");
+MODULE_AUTHOR("Vojtech Pavlik, Bartlomiej Zolnierkiewicz, Michel Aubry, Jeff Garzik, Andre Hedrick");
 MODULE_DESCRIPTION("PCI driver module for VIA IDE");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/idle/i7300_idle.c linux-libre-2.6.34-gnu1/drivers/idle/i7300_idle.c
--- linux-libre-2.6.33-gnu1/drivers/idle/i7300_idle.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/idle/i7300_idle.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/notifier.h>
 #include <linux/cpumask.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ieee1394/dma.c linux-libre-2.6.34-gnu1/drivers/ieee1394/dma.c
--- linux-libre-2.6.33-gnu1/drivers/ieee1394/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ieee1394/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/scatterlist.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ieee1394/nodemgr.c linux-libre-2.6.34-gnu1/drivers/ieee1394/nodemgr.c
--- linux-libre-2.6.33-gnu1/drivers/ieee1394/nodemgr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ieee1394/nodemgr.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/moduleparam.h>
 #include <linux/mutex.h>
 #include <linux/freezer.h>
-#include <linux/semaphore.h>
 #include <asm/atomic.h>
 
 #include "csr.h"
@@ -1397,9 +1396,9 @@ static int update_pdrv(struct device *de
 			pdrv = container_of(drv, struct hpsb_protocol_driver,
 					    driver);
 			if (pdrv->update) {
-				down(&ud->device.sem);
+				device_lock(&ud->device);
 				error = pdrv->update(ud);
-				up(&ud->device.sem);
+				device_unlock(&ud->device);
 			}
 			if (error)
 				device_release_driver(&ud->device);
diff -druNp linux-libre-2.6.33-gnu1/drivers/ieee1394/pcilynx.c linux-libre-2.6.34-gnu1/drivers/ieee1394/pcilynx.c
--- linux-libre-2.6.33-gnu1/drivers/ieee1394/pcilynx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ieee1394/pcilynx.c	2010-05-16 17:17:36.000000000 -0400
@@ -1452,7 +1452,7 @@ static int __devinit add_card(struct pci
                                 PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c");
                         } else {
                                 PRINT(KERN_INFO, lynx->id, "got bus info block from serial eeprom");
-				/* FIXME: probably we shoud rewrite the max_rec, max_ROM(1394a),
+				/* FIXME: probably we should rewrite the max_rec, max_ROM(1394a),
 				 * generation(1394a) and link_spd(1394a) field and recalculate
 				 * the CRC */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ieee1394/sbp2.c linux-libre-2.6.34-gnu1/drivers/ieee1394/sbp2.c
--- linux-libre-2.6.33-gnu1/drivers/ieee1394/sbp2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ieee1394/sbp2.c	2010-05-16 17:17:36.000000000 -0400
@@ -56,7 +56,6 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
-#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
@@ -2020,7 +2019,7 @@ static int sbp2scsi_slave_configure(stru
 	if (lu->workarounds & SBP2_WORKAROUND_POWER_CONDITION)
 		sdev->start_stop_pwr_cond = 1;
 	if (lu->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
-		blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512);
+		blk_queue_max_hw_sectors(sdev->request_queue, 128 * 1024 / 512);
 
 	blk_queue_max_segment_size(sdev->request_queue, SBP2_MAX_SEG_SIZE);
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/addr.c linux-libre-2.6.34-gnu1/drivers/infiniband/core/addr.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/addr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/addr.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 
 #include <linux/mutex.h>
 #include <linux/inetdevice.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <net/arp.h>
 #include <net/neighbour.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/cma.c linux-libre-2.6.34-gnu1/drivers/infiniband/core/cma.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/cma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/cma.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/random.h>
 #include <linux/idr.h>
 #include <linux/inetdevice.h>
+#include <linux/slab.h>
 
 #include <net/tcp.h>
 #include <net/ipv6.h>
@@ -1683,6 +1684,7 @@ int rdma_set_ib_paths(struct rdma_cm_id
 	}
 
 	memcpy(id->route.path_rec, path_rec, sizeof *path_rec * num_paths);
+	id->route.num_paths = num_paths;
 	return 0;
 err:
 	cma_comp_exch(id_priv, CMA_ROUTE_RESOLVED, CMA_ADDR_RESOLVED);
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/cm.c linux-libre-2.6.34-gnu1/drivers/infiniband/core/cm.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/cm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/cm.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/random.h>
 #include <linux/rbtree.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/workqueue.h>
 #include <linux/kdev_t.h>
@@ -3597,7 +3598,7 @@ static ssize_t cm_show_counter(struct ko
 		       atomic_long_read(&group->counter[cm_attr->index]));
 }
 
-static struct sysfs_ops cm_counter_ops = {
+static const struct sysfs_ops cm_counter_ops = {
 	.show = cm_show_counter
 };
 
@@ -3693,7 +3694,7 @@ static void cm_add_one(struct ib_device
 	cm_dev->device = device_create(&cm_class, &ib_device->dev,
 				       MKDEV(0, 0), NULL,
 				       "%s", ib_device->name);
-	if (!cm_dev->device) {
+	if (IS_ERR(cm_dev->device)) {
 		kfree(cm_dev);
 		return;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/iwcm.c linux-libre-2.6.34-gnu1/drivers/infiniband/core/iwcm.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/iwcm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/iwcm.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,7 @@
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
 #include <linux/completion.h>
+#include <linux/slab.h>
 
 #include <rdma/iw_cm.h>
 #include <rdma/ib_addr.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/mad.c linux-libre-2.6.34-gnu1/drivers/infiniband/core/mad.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/mad.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/mad.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
  *
  */
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <rdma/ib_cache.h>
 
 #include "mad_priv.h"
@@ -1193,10 +1194,7 @@ static int method_in_use(struct ib_mad_m
 {
 	int i;
 
-	for (i = find_first_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS);
-	     i < IB_MGMT_MAX_METHODS;
-	     i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,
-			       1+i)) {
+	for_each_set_bit(i, mad_reg_req->method_mask, IB_MGMT_MAX_METHODS) {
 		if ((*method)->agent[i]) {
 			printk(KERN_ERR PFX "Method %d already in use\n", i);
 			return -EINVAL;
@@ -1330,13 +1328,9 @@ static int add_nonoui_reg_req(struct ib_
 		goto error3;
 
 	/* Finally, add in methods being registered */
-	for (i = find_first_bit(mad_reg_req->method_mask,
-				IB_MGMT_MAX_METHODS);
-	     i < IB_MGMT_MAX_METHODS;
-	     i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,
-			       1+i)) {
+	for_each_set_bit(i, mad_reg_req->method_mask, IB_MGMT_MAX_METHODS)
 		(*method)->agent[i] = agent_priv;
-	}
+
 	return 0;
 
 error3:
@@ -1429,13 +1423,9 @@ check_in_use:
 		goto error4;
 
 	/* Finally, add in methods being registered */
-	for (i = find_first_bit(mad_reg_req->method_mask,
-				IB_MGMT_MAX_METHODS);
-	     i < IB_MGMT_MAX_METHODS;
-	     i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,
-			       1+i)) {
+	for_each_set_bit(i, mad_reg_req->method_mask, IB_MGMT_MAX_METHODS)
 		(*method)->agent[i] = agent_priv;
-	}
+
 	return 0;
 
 error4:
@@ -2964,6 +2954,9 @@ static void ib_mad_remove_device(struct
 {
 	int i, num_ports, cur_port;
 
+	if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
+		return;
+
 	if (device->node_type == RDMA_NODE_IB_SWITCH) {
 		num_ports = 1;
 		cur_port = 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/mad_rmpp.c linux-libre-2.6.34-gnu1/drivers/infiniband/core/mad_rmpp.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/mad_rmpp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/mad_rmpp.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,8 @@
  * SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "mad_priv.h"
 #include "mad_rmpp.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/multicast.c linux-libre-2.6.34-gnu1/drivers/infiniband/core/multicast.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/multicast.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/multicast.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/bitops.h>
 #include <linux/random.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/sysfs.c linux-libre-2.6.34-gnu1/drivers/infiniband/core/sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -79,7 +79,7 @@ static ssize_t port_attr_show(struct kob
 	return port_attr->show(p, port_attr, buf);
 }
 
-static struct sysfs_ops port_sysfs_ops = {
+static const struct sysfs_ops port_sysfs_ops = {
 	.show = port_attr_show
 };
 
@@ -461,6 +461,7 @@ alloc_group_attrs(ssize_t (*show)(struct
 		element->attr.attr.mode  = S_IRUGO;
 		element->attr.show       = show;
 		element->index		 = i;
+		sysfs_attr_init(&element->attr.attr);
 
 		tab_attr[i] = &element->attr.attr;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/ucma.c linux-libre-2.6.34-gnu1/drivers/infiniband/core/ucma.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/ucma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/ucma.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <linux/miscdevice.h>
+#include <linux/slab.h>
 
 #include <rdma/rdma_user_cm.h>
 #include <rdma/ib_marshall.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/ucm.c linux-libre-2.6.34-gnu1/drivers/infiniband/core/ucm.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/ucm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/ucm.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,7 @@
 #include <linux/cdev.h>
 #include <linux/idr.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
@@ -1215,15 +1216,18 @@ static void ib_ucm_release_dev(struct de
 
 	ucm_dev = container_of(dev, struct ib_ucm_device, dev);
 	cdev_del(&ucm_dev->cdev);
-	clear_bit(ucm_dev->devnum, dev_map);
+	if (ucm_dev->devnum < IB_UCM_MAX_DEVICES)
+		clear_bit(ucm_dev->devnum, dev_map);
+	else
+		clear_bit(ucm_dev->devnum - IB_UCM_MAX_DEVICES, dev_map);
 	kfree(ucm_dev);
 }
 
 static const struct file_operations ucm_fops = {
-	.owner 	 = THIS_MODULE,
-	.open 	 = ib_ucm_open,
+	.owner	 = THIS_MODULE,
+	.open	 = ib_ucm_open,
 	.release = ib_ucm_close,
-	.write 	 = ib_ucm_write,
+	.write	 = ib_ucm_write,
 	.poll    = ib_ucm_poll,
 };
 
@@ -1237,8 +1241,32 @@ static ssize_t show_ibdev(struct device
 }
 static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
 
+static dev_t overflow_maj;
+static DECLARE_BITMAP(overflow_map, IB_UCM_MAX_DEVICES);
+static int find_overflow_devnum(void)
+{
+	int ret;
+
+	if (!overflow_maj) {
+		ret = alloc_chrdev_region(&overflow_maj, 0, IB_UCM_MAX_DEVICES,
+					  "infiniband_cm");
+		if (ret) {
+			printk(KERN_ERR "ucm: couldn't register dynamic device number\n");
+			return ret;
+		}
+	}
+
+	ret = find_first_zero_bit(overflow_map, IB_UCM_MAX_DEVICES);
+	if (ret >= IB_UCM_MAX_DEVICES)
+		return -1;
+
+	return ret;
+}
+
 static void ib_ucm_add_one(struct ib_device *device)
 {
+	int devnum;
+	dev_t base;
 	struct ib_ucm_device *ucm_dev;
 
 	if (!device->alloc_ucontext ||
@@ -1251,16 +1279,25 @@ static void ib_ucm_add_one(struct ib_dev
 
 	ucm_dev->ib_dev = device;
 
-	ucm_dev->devnum = find_first_zero_bit(dev_map, IB_UCM_MAX_DEVICES);
-	if (ucm_dev->devnum >= IB_UCM_MAX_DEVICES)
-		goto err;
+	devnum = find_first_zero_bit(dev_map, IB_UCM_MAX_DEVICES);
+	if (devnum >= IB_UCM_MAX_DEVICES) {
+		devnum = find_overflow_devnum();
+		if (devnum < 0)
+			goto err;
 
-	set_bit(ucm_dev->devnum, dev_map);
+		ucm_dev->devnum = devnum + IB_UCM_MAX_DEVICES;
+		base = devnum + overflow_maj;
+		set_bit(devnum, overflow_map);
+	} else {
+		ucm_dev->devnum = devnum;
+		base = devnum + IB_UCM_BASE_DEV;
+		set_bit(devnum, dev_map);
+	}
 
 	cdev_init(&ucm_dev->cdev, &ucm_fops);
 	ucm_dev->cdev.owner = THIS_MODULE;
 	kobject_set_name(&ucm_dev->cdev.kobj, "ucm%d", ucm_dev->devnum);
-	if (cdev_add(&ucm_dev->cdev, IB_UCM_BASE_DEV + ucm_dev->devnum, 1))
+	if (cdev_add(&ucm_dev->cdev, base, 1))
 		goto err;
 
 	ucm_dev->dev.class = &cm_class;
@@ -1281,7 +1318,10 @@ err_dev:
 	device_unregister(&ucm_dev->dev);
 err_cdev:
 	cdev_del(&ucm_dev->cdev);
-	clear_bit(ucm_dev->devnum, dev_map);
+	if (ucm_dev->devnum < IB_UCM_MAX_DEVICES)
+		clear_bit(devnum, dev_map);
+	else
+		clear_bit(devnum, overflow_map);
 err:
 	kfree(ucm_dev);
 	return;
@@ -1297,11 +1337,8 @@ static void ib_ucm_remove_one(struct ib_
 	device_unregister(&ucm_dev->dev);
 }
 
-static ssize_t show_abi_version(struct class *class, char *buf)
-{
-	return sprintf(buf, "%d\n", IB_USER_CM_ABI_VERSION);
-}
-static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
+static CLASS_ATTR_STRING(abi_version, S_IRUGO,
+			 __stringify(IB_USER_CM_ABI_VERSION));
 
 static int __init ib_ucm_init(void)
 {
@@ -1314,7 +1351,7 @@ static int __init ib_ucm_init(void)
 		goto error1;
 	}
 
-	ret = class_create_file(&cm_class, &class_attr_abi_version);
+	ret = class_create_file(&cm_class, &class_attr_abi_version.attr);
 	if (ret) {
 		printk(KERN_ERR "ucm: couldn't create abi_version attribute\n");
 		goto error2;
@@ -1328,7 +1365,7 @@ static int __init ib_ucm_init(void)
 	return 0;
 
 error3:
-	class_remove_file(&cm_class, &class_attr_abi_version);
+	class_remove_file(&cm_class, &class_attr_abi_version.attr);
 error2:
 	unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES);
 error1:
@@ -1338,8 +1375,10 @@ error1:
 static void __exit ib_ucm_cleanup(void)
 {
 	ib_unregister_client(&ucm_client);
-	class_remove_file(&cm_class, &class_attr_abi_version);
+	class_remove_file(&cm_class, &class_attr_abi_version.attr);
 	unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES);
+	if (overflow_maj)
+		unregister_chrdev_region(overflow_maj, IB_UCM_MAX_DEVICES);
 	idr_destroy(&ctx_id_table);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/ud_header.c linux-libre-2.6.34-gnu1/drivers/infiniband/core/ud_header.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/ud_header.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/ud_header.c	2010-05-16 17:17:36.000000000 -0400
@@ -181,6 +181,7 @@ static const struct ib_field deth_table[
  * ib_ud_header_init - Initialize UD header structure
  * @payload_bytes:Length of packet payload
  * @grh_present:GRH flag (if non-zero, GRH will be included)
+ * @immediate_present: specify if immediate data should be used
  * @header:Structure to initialize
  *
  * ib_ud_header_init() initializes the lrh.link_version, lrh.link_next_header,
@@ -191,21 +192,13 @@ static const struct ib_field deth_table[
  */
 void ib_ud_header_init(int     		    payload_bytes,
 		       int    		    grh_present,
+		       int		    immediate_present,
 		       struct ib_ud_header *header)
 {
-	int header_len;
 	u16 packet_length;
 
 	memset(header, 0, sizeof *header);
 
-	header_len =
-		IB_LRH_BYTES  +
-		IB_BTH_BYTES  +
-		IB_DETH_BYTES;
-	if (grh_present) {
-		header_len += IB_GRH_BYTES;
-	}
-
 	header->lrh.link_version     = 0;
 	header->lrh.link_next_header =
 		grh_present ? IB_LNH_IBA_GLOBAL : IB_LNH_IBA_LOCAL;
@@ -231,7 +224,8 @@ void ib_ud_header_init(int     		    pay
 
 	header->lrh.packet_length = cpu_to_be16(packet_length);
 
-	if (header->immediate_present)
+	header->immediate_present	     = immediate_present;
+	if (immediate_present)
 		header->bth.opcode           = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE;
 	else
 		header->bth.opcode           = IB_OPCODE_UD_SEND_ONLY;
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/umem.c linux-libre-2.6.34-gnu1/drivers/infiniband/core/umem.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/umem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/umem.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/sched.h>
 #include <linux/hugetlb.h>
 #include <linux/dma-attrs.h>
+#include <linux/slab.h>
 
 #include "uverbs.h"
 
@@ -136,7 +137,7 @@ struct ib_umem *ib_umem_get(struct ib_uc
 	down_write(&current->mm->mmap_sem);
 
 	locked     = npages + current->mm->locked_vm;
-	lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
+	lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
 
 	if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) {
 		ret = -ENOMEM;
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/user_mad.c linux-libre-2.6.34-gnu1/drivers/infiniband/core/user_mad.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/user_mad.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/user_mad.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,7 @@
 #include <linux/compat.h>
 #include <linux/sched.h>
 #include <linux/semaphore.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
@@ -65,12 +66,9 @@ enum {
 };
 
 /*
- * Our lifetime rules for these structs are the following: each time a
- * device special file is opened, we look up the corresponding struct
- * ib_umad_port by minor in the umad_port[] table while holding the
- * port_lock.  If this lookup succeeds, we take a reference on the
- * ib_umad_port's struct ib_umad_device while still holding the
- * port_lock; if the lookup fails, we fail the open().  We drop these
+ * Our lifetime rules for these structs are the following:
+ * device special file is opened, we take a reference on the
+ * ib_umad_port's struct ib_umad_device. We drop these
  * references in the corresponding close().
  *
  * In addition to references coming from open character devices, there
@@ -78,19 +76,14 @@ enum {
  * module's reference taken when allocating the ib_umad_device in
  * ib_umad_add_one().
  *
- * When destroying an ib_umad_device, we clear all of its
- * ib_umad_ports from umad_port[] while holding port_lock before
- * dropping the module's reference to the ib_umad_device.  This is
- * always safe because any open() calls will either succeed and obtain
- * a reference before we clear the umad_port[] entries, or fail after
- * we clear the umad_port[] entries.
+ * When destroying an ib_umad_device, we drop the module's reference.
  */
 
 struct ib_umad_port {
-	struct cdev           *cdev;
+	struct cdev           cdev;
 	struct device	      *dev;
 
-	struct cdev           *sm_cdev;
+	struct cdev           sm_cdev;
 	struct device	      *sm_dev;
 	struct semaphore       sm_sem;
 
@@ -136,7 +129,6 @@ static struct class *umad_class;
 static const dev_t base_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE);
 
 static DEFINE_SPINLOCK(port_lock);
-static struct ib_umad_port *umad_port[IB_UMAD_MAX_PORTS];
 static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS);
 
 static void ib_umad_add_one(struct ib_device *device);
@@ -496,8 +488,8 @@ static ssize_t ib_umad_write(struct file
 		ah_attr.ah_flags = IB_AH_GRH;
 		memcpy(ah_attr.grh.dgid.raw, packet->mad.hdr.gid, 16);
 		ah_attr.grh.sgid_index	   = packet->mad.hdr.gid_index;
-		ah_attr.grh.flow_label 	   = be32_to_cpu(packet->mad.hdr.flow_label);
-		ah_attr.grh.hop_limit  	   = packet->mad.hdr.hop_limit;
+		ah_attr.grh.flow_label	   = be32_to_cpu(packet->mad.hdr.flow_label);
+		ah_attr.grh.hop_limit	   = packet->mad.hdr.hop_limit;
 		ah_attr.grh.traffic_class  = packet->mad.hdr.traffic_class;
 	}
 
@@ -528,9 +520,9 @@ static ssize_t ib_umad_write(struct file
 		goto err_ah;
 	}
 
-	packet->msg->ah 	= ah;
+	packet->msg->ah		= ah;
 	packet->msg->timeout_ms = packet->mad.hdr.timeout_ms;
-	packet->msg->retries 	= packet->mad.hdr.retries;
+	packet->msg->retries	= packet->mad.hdr.retries;
 	packet->msg->context[0] = packet;
 
 	/* Copy MAD header.  Any RMPP header is already in place. */
@@ -779,15 +771,11 @@ static long ib_umad_compat_ioctl(struct
 /*
  * ib_umad_open() does not need the BKL:
  *
- *  - umad_port[] accesses are protected by port_lock, the
- *    ib_umad_port structures are properly reference counted, and
+ *  - the ib_umad_port structures are properly reference counted, and
  *    everything else is purely local to the file being created, so
  *    races against other open calls are not a problem;
  *  - the ioctl method does not affect any global state outside of the
  *    file structure being operated on;
- *  - the port is added to umad_port[] as the last part of module
- *    initialization so the open method will either immediately run
- *    -ENXIO, or all required initialization will be done.
  */
 static int ib_umad_open(struct inode *inode, struct file *filp)
 {
@@ -795,13 +783,10 @@ static int ib_umad_open(struct inode *in
 	struct ib_umad_file *file;
 	int ret = 0;
 
-	spin_lock(&port_lock);
-	port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE];
+	port = container_of(inode->i_cdev, struct ib_umad_port, cdev);
 	if (port)
 		kref_get(&port->umad_dev->ref);
-	spin_unlock(&port_lock);
-
-	if (!port)
+	else
 		return -ENXIO;
 
 	mutex_lock(&port->file_mutex);
@@ -872,16 +857,16 @@ static int ib_umad_close(struct inode *i
 }
 
 static const struct file_operations umad_fops = {
-	.owner 	 	= THIS_MODULE,
-	.read 	 	= ib_umad_read,
-	.write 	 	= ib_umad_write,
-	.poll 	 	= ib_umad_poll,
+	.owner		= THIS_MODULE,
+	.read		= ib_umad_read,
+	.write		= ib_umad_write,
+	.poll		= ib_umad_poll,
 	.unlocked_ioctl = ib_umad_ioctl,
 #ifdef CONFIG_COMPAT
-	.compat_ioctl 	= ib_umad_compat_ioctl,
+	.compat_ioctl	= ib_umad_compat_ioctl,
 #endif
-	.open 	 	= ib_umad_open,
-	.release 	= ib_umad_close
+	.open		= ib_umad_open,
+	.release	= ib_umad_close
 };
 
 static int ib_umad_sm_open(struct inode *inode, struct file *filp)
@@ -892,13 +877,10 @@ static int ib_umad_sm_open(struct inode
 	};
 	int ret;
 
-	spin_lock(&port_lock);
-	port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE - IB_UMAD_MAX_PORTS];
+	port = container_of(inode->i_cdev, struct ib_umad_port, sm_cdev);
 	if (port)
 		kref_get(&port->umad_dev->ref);
-	spin_unlock(&port_lock);
-
-	if (!port)
+	else
 		return -ENXIO;
 
 	if (filp->f_flags & O_NONBLOCK) {
@@ -949,8 +931,8 @@ static int ib_umad_sm_close(struct inode
 }
 
 static const struct file_operations umad_sm_fops = {
-	.owner 	 = THIS_MODULE,
-	.open 	 = ib_umad_sm_open,
+	.owner	 = THIS_MODULE,
+	.open	 = ib_umad_sm_open,
 	.release = ib_umad_sm_close
 };
 
@@ -984,22 +966,54 @@ static ssize_t show_port(struct device *
 }
 static DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
 
-static ssize_t show_abi_version(struct class *class, char *buf)
+static CLASS_ATTR_STRING(abi_version, S_IRUGO,
+			 __stringify(IB_USER_MAD_ABI_VERSION));
+
+static dev_t overflow_maj;
+static DECLARE_BITMAP(overflow_map, IB_UMAD_MAX_PORTS);
+static int find_overflow_devnum(void)
 {
-	return sprintf(buf, "%d\n", IB_USER_MAD_ABI_VERSION);
+	int ret;
+
+	if (!overflow_maj) {
+		ret = alloc_chrdev_region(&overflow_maj, 0, IB_UMAD_MAX_PORTS * 2,
+					  "infiniband_mad");
+		if (ret) {
+			printk(KERN_ERR "user_mad: couldn't register dynamic device number\n");
+			return ret;
+		}
+	}
+
+	ret = find_first_zero_bit(overflow_map, IB_UMAD_MAX_PORTS);
+	if (ret >= IB_UMAD_MAX_PORTS)
+		return -1;
+
+	return ret;
 }
-static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
 
 static int ib_umad_init_port(struct ib_device *device, int port_num,
 			     struct ib_umad_port *port)
 {
+	int devnum;
+	dev_t base;
+
 	spin_lock(&port_lock);
-	port->dev_num = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS);
-	if (port->dev_num >= IB_UMAD_MAX_PORTS) {
+	devnum = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS);
+	if (devnum >= IB_UMAD_MAX_PORTS) {
 		spin_unlock(&port_lock);
-		return -1;
+		devnum = find_overflow_devnum();
+		if (devnum < 0)
+			return -1;
+
+		spin_lock(&port_lock);
+		port->dev_num = devnum + IB_UMAD_MAX_PORTS;
+		base = devnum + overflow_maj;
+		set_bit(devnum, overflow_map);
+	} else {
+		port->dev_num = devnum;
+		base = devnum + base_dev;
+		set_bit(devnum, dev_map);
 	}
-	set_bit(port->dev_num, dev_map);
 	spin_unlock(&port_lock);
 
 	port->ib_dev   = device;
@@ -1008,17 +1022,14 @@ static int ib_umad_init_port(struct ib_d
 	mutex_init(&port->file_mutex);
 	INIT_LIST_HEAD(&port->file_list);
 
-	port->cdev = cdev_alloc();
-	if (!port->cdev)
-		return -1;
-	port->cdev->owner = THIS_MODULE;
-	port->cdev->ops   = &umad_fops;
-	kobject_set_name(&port->cdev->kobj, "umad%d", port->dev_num);
-	if (cdev_add(port->cdev, base_dev + port->dev_num, 1))
+	cdev_init(&port->cdev, &umad_fops);
+	port->cdev.owner = THIS_MODULE;
+	kobject_set_name(&port->cdev.kobj, "umad%d", port->dev_num);
+	if (cdev_add(&port->cdev, base, 1))
 		goto err_cdev;
 
 	port->dev = device_create(umad_class, device->dma_device,
-				  port->cdev->dev, port,
+				  port->cdev.dev, port,
 				  "umad%d", port->dev_num);
 	if (IS_ERR(port->dev))
 		goto err_cdev;
@@ -1028,17 +1039,15 @@ static int ib_umad_init_port(struct ib_d
 	if (device_create_file(port->dev, &dev_attr_port))
 		goto err_dev;
 
-	port->sm_cdev = cdev_alloc();
-	if (!port->sm_cdev)
-		goto err_dev;
-	port->sm_cdev->owner = THIS_MODULE;
-	port->sm_cdev->ops   = &umad_sm_fops;
-	kobject_set_name(&port->sm_cdev->kobj, "issm%d", port->dev_num);
-	if (cdev_add(port->sm_cdev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
+	base += IB_UMAD_MAX_PORTS;
+	cdev_init(&port->sm_cdev, &umad_sm_fops);
+	port->sm_cdev.owner = THIS_MODULE;
+	kobject_set_name(&port->sm_cdev.kobj, "issm%d", port->dev_num);
+	if (cdev_add(&port->sm_cdev, base, 1))
 		goto err_sm_cdev;
 
 	port->sm_dev = device_create(umad_class, device->dma_device,
-				     port->sm_cdev->dev, port,
+				     port->sm_cdev.dev, port,
 				     "issm%d", port->dev_num);
 	if (IS_ERR(port->sm_dev))
 		goto err_sm_cdev;
@@ -1048,24 +1057,23 @@ static int ib_umad_init_port(struct ib_d
 	if (device_create_file(port->sm_dev, &dev_attr_port))
 		goto err_sm_dev;
 
-	spin_lock(&port_lock);
-	umad_port[port->dev_num] = port;
-	spin_unlock(&port_lock);
-
 	return 0;
 
 err_sm_dev:
-	device_destroy(umad_class, port->sm_cdev->dev);
+	device_destroy(umad_class, port->sm_cdev.dev);
 
 err_sm_cdev:
-	cdev_del(port->sm_cdev);
+	cdev_del(&port->sm_cdev);
 
 err_dev:
-	device_destroy(umad_class, port->cdev->dev);
+	device_destroy(umad_class, port->cdev.dev);
 
 err_cdev:
-	cdev_del(port->cdev);
-	clear_bit(port->dev_num, dev_map);
+	cdev_del(&port->cdev);
+	if (port->dev_num < IB_UMAD_MAX_PORTS)
+		clear_bit(devnum, dev_map);
+	else
+		clear_bit(devnum, overflow_map);
 
 	return -1;
 }
@@ -1079,15 +1087,11 @@ static void ib_umad_kill_port(struct ib_
 	dev_set_drvdata(port->dev,    NULL);
 	dev_set_drvdata(port->sm_dev, NULL);
 
-	device_destroy(umad_class, port->cdev->dev);
-	device_destroy(umad_class, port->sm_cdev->dev);
-
-	cdev_del(port->cdev);
-	cdev_del(port->sm_cdev);
+	device_destroy(umad_class, port->cdev.dev);
+	device_destroy(umad_class, port->sm_cdev.dev);
 
-	spin_lock(&port_lock);
-	umad_port[port->dev_num] = NULL;
-	spin_unlock(&port_lock);
+	cdev_del(&port->cdev);
+	cdev_del(&port->sm_cdev);
 
 	mutex_lock(&port->file_mutex);
 
@@ -1106,7 +1110,10 @@ static void ib_umad_kill_port(struct ib_
 
 	mutex_unlock(&port->file_mutex);
 
-	clear_bit(port->dev_num, dev_map);
+	if (port->dev_num < IB_UMAD_MAX_PORTS)
+		clear_bit(port->dev_num, dev_map);
+	else
+		clear_bit(port->dev_num - IB_UMAD_MAX_PORTS, overflow_map);
 }
 
 static void ib_umad_add_one(struct ib_device *device)
@@ -1185,7 +1192,7 @@ static int __init ib_umad_init(void)
 		goto out_chrdev;
 	}
 
-	ret = class_create_file(umad_class, &class_attr_abi_version);
+	ret = class_create_file(umad_class, &class_attr_abi_version.attr);
 	if (ret) {
 		printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n");
 		goto out_class;
@@ -1214,6 +1221,8 @@ static void __exit ib_umad_cleanup(void)
 	ib_unregister_client(&umad_client);
 	class_destroy(umad_class);
 	unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2);
+	if (overflow_maj)
+		unregister_chrdev_region(overflow_maj, IB_UMAD_MAX_PORTS * 2);
 }
 
 module_init(ib_umad_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/uverbs_cmd.c linux-libre-2.6.34-gnu1/drivers/infiniband/core/uverbs_cmd.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/uverbs_cmd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/uverbs_cmd.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 
 #include <linux/file.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
@@ -301,10 +302,15 @@ ssize_t ib_uverbs_get_context(struct ib_
 
 	resp.num_comp_vectors = file->device->num_comp_vectors;
 
-	filp = ib_uverbs_alloc_event_file(file, 1, &resp.async_fd);
+	ret = get_unused_fd();
+	if (ret < 0)
+		goto err_free;
+	resp.async_fd = ret;
+
+	filp = ib_uverbs_alloc_event_file(file, 1);
 	if (IS_ERR(filp)) {
 		ret = PTR_ERR(filp);
-		goto err_free;
+		goto err_fd;
 	}
 
 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
@@ -332,9 +338,11 @@ ssize_t ib_uverbs_get_context(struct ib_
 	return in_len;
 
 err_file:
-	put_unused_fd(resp.async_fd);
 	fput(filp);
 
+err_fd:
+	put_unused_fd(resp.async_fd);
+
 err_free:
 	ibdev->dealloc_ucontext(ucontext);
 
@@ -715,6 +723,7 @@ ssize_t ib_uverbs_create_comp_channel(st
 	struct ib_uverbs_create_comp_channel	   cmd;
 	struct ib_uverbs_create_comp_channel_resp  resp;
 	struct file				  *filp;
+	int ret;
 
 	if (out_len < sizeof resp)
 		return -ENOSPC;
@@ -722,9 +731,16 @@ ssize_t ib_uverbs_create_comp_channel(st
 	if (copy_from_user(&cmd, buf, sizeof cmd))
 		return -EFAULT;
 
-	filp = ib_uverbs_alloc_event_file(file, 0, &resp.fd);
-	if (IS_ERR(filp))
+	ret = get_unused_fd();
+	if (ret < 0)
+		return ret;
+	resp.fd = ret;
+
+	filp = ib_uverbs_alloc_event_file(file, 0);
+	if (IS_ERR(filp)) {
+		put_unused_fd(resp.fd);
 		return PTR_ERR(filp);
+	}
 
 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
 			 &resp, sizeof resp)) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/uverbs.h linux-libre-2.6.34-gnu1/drivers/infiniband/core/uverbs.h
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/uverbs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/uverbs.h	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@
 #include <linux/idr.h>
 #include <linux/mutex.h>
 #include <linux/completion.h>
+#include <linux/cdev.h>
 
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_umem.h>
@@ -69,23 +70,23 @@
 
 struct ib_uverbs_device {
 	struct kref				ref;
+	int					num_comp_vectors;
 	struct completion			comp;
-	int					devnum;
-	struct cdev			       *cdev;
 	struct device			       *dev;
 	struct ib_device		       *ib_dev;
-	int					num_comp_vectors;
+	int					devnum;
+	struct cdev			        cdev;
 };
 
 struct ib_uverbs_event_file {
 	struct kref				ref;
+	int					is_async;
 	struct ib_uverbs_file		       *uverbs_file;
 	spinlock_t				lock;
+	int					is_closed;
 	wait_queue_head_t			poll_wait;
 	struct fasync_struct		       *async_queue;
 	struct list_head			event_list;
-	int					is_async;
-	int					is_closed;
 };
 
 struct ib_uverbs_file {
@@ -145,7 +146,7 @@ extern struct idr ib_uverbs_srq_idr;
 void idr_remove_uobj(struct idr *idp, struct ib_uobject *uobj);
 
 struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
-					int is_async, int *fd);
+					int is_async);
 struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd);
 
 void ib_uverbs_release_ucq(struct ib_uverbs_file *file,
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/core/uverbs_main.c linux-libre-2.6.34-gnu1/drivers/infiniband/core/uverbs_main.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/core/uverbs_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/core/uverbs_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,8 +42,9 @@
 #include <linux/poll.h>
 #include <linux/sched.h>
 #include <linux/file.h>
-#include <linux/mount.h>
 #include <linux/cdev.h>
+#include <linux/anon_inodes.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
@@ -53,8 +54,6 @@ MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("InfiniBand userspace verbs access");
 MODULE_LICENSE("Dual BSD/GPL");
 
-#define INFINIBANDEVENTFS_MAGIC	0x49426576	/* "IBev" */
-
 enum {
 	IB_UVERBS_MAJOR       = 231,
 	IB_UVERBS_BASE_MINOR  = 192,
@@ -75,44 +74,41 @@ DEFINE_IDR(ib_uverbs_qp_idr);
 DEFINE_IDR(ib_uverbs_srq_idr);
 
 static DEFINE_SPINLOCK(map_lock);
-static struct ib_uverbs_device *dev_table[IB_UVERBS_MAX_DEVICES];
 static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES);
 
 static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
 				     const char __user *buf, int in_len,
 				     int out_len) = {
-	[IB_USER_VERBS_CMD_GET_CONTEXT]   	= ib_uverbs_get_context,
-	[IB_USER_VERBS_CMD_QUERY_DEVICE]  	= ib_uverbs_query_device,
-	[IB_USER_VERBS_CMD_QUERY_PORT]    	= ib_uverbs_query_port,
-	[IB_USER_VERBS_CMD_ALLOC_PD]      	= ib_uverbs_alloc_pd,
-	[IB_USER_VERBS_CMD_DEALLOC_PD]    	= ib_uverbs_dealloc_pd,
-	[IB_USER_VERBS_CMD_REG_MR]        	= ib_uverbs_reg_mr,
-	[IB_USER_VERBS_CMD_DEREG_MR]      	= ib_uverbs_dereg_mr,
+	[IB_USER_VERBS_CMD_GET_CONTEXT]		= ib_uverbs_get_context,
+	[IB_USER_VERBS_CMD_QUERY_DEVICE]	= ib_uverbs_query_device,
+	[IB_USER_VERBS_CMD_QUERY_PORT]		= ib_uverbs_query_port,
+	[IB_USER_VERBS_CMD_ALLOC_PD]		= ib_uverbs_alloc_pd,
+	[IB_USER_VERBS_CMD_DEALLOC_PD]		= ib_uverbs_dealloc_pd,
+	[IB_USER_VERBS_CMD_REG_MR]		= ib_uverbs_reg_mr,
+	[IB_USER_VERBS_CMD_DEREG_MR]		= ib_uverbs_dereg_mr,
 	[IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL] = ib_uverbs_create_comp_channel,
-	[IB_USER_VERBS_CMD_CREATE_CQ]     	= ib_uverbs_create_cq,
-	[IB_USER_VERBS_CMD_RESIZE_CQ]     	= ib_uverbs_resize_cq,
-	[IB_USER_VERBS_CMD_POLL_CQ]     	= ib_uverbs_poll_cq,
-	[IB_USER_VERBS_CMD_REQ_NOTIFY_CQ]     	= ib_uverbs_req_notify_cq,
-	[IB_USER_VERBS_CMD_DESTROY_CQ]    	= ib_uverbs_destroy_cq,
-	[IB_USER_VERBS_CMD_CREATE_QP]     	= ib_uverbs_create_qp,
-	[IB_USER_VERBS_CMD_QUERY_QP]     	= ib_uverbs_query_qp,
-	[IB_USER_VERBS_CMD_MODIFY_QP]     	= ib_uverbs_modify_qp,
-	[IB_USER_VERBS_CMD_DESTROY_QP]    	= ib_uverbs_destroy_qp,
-	[IB_USER_VERBS_CMD_POST_SEND]    	= ib_uverbs_post_send,
-	[IB_USER_VERBS_CMD_POST_RECV]    	= ib_uverbs_post_recv,
-	[IB_USER_VERBS_CMD_POST_SRQ_RECV]    	= ib_uverbs_post_srq_recv,
-	[IB_USER_VERBS_CMD_CREATE_AH]    	= ib_uverbs_create_ah,
-	[IB_USER_VERBS_CMD_DESTROY_AH]    	= ib_uverbs_destroy_ah,
-	[IB_USER_VERBS_CMD_ATTACH_MCAST]  	= ib_uverbs_attach_mcast,
-	[IB_USER_VERBS_CMD_DETACH_MCAST]  	= ib_uverbs_detach_mcast,
-	[IB_USER_VERBS_CMD_CREATE_SRQ]    	= ib_uverbs_create_srq,
-	[IB_USER_VERBS_CMD_MODIFY_SRQ]    	= ib_uverbs_modify_srq,
-	[IB_USER_VERBS_CMD_QUERY_SRQ]     	= ib_uverbs_query_srq,
-	[IB_USER_VERBS_CMD_DESTROY_SRQ]   	= ib_uverbs_destroy_srq,
+	[IB_USER_VERBS_CMD_CREATE_CQ]		= ib_uverbs_create_cq,
+	[IB_USER_VERBS_CMD_RESIZE_CQ]		= ib_uverbs_resize_cq,
+	[IB_USER_VERBS_CMD_POLL_CQ]		= ib_uverbs_poll_cq,
+	[IB_USER_VERBS_CMD_REQ_NOTIFY_CQ]	= ib_uverbs_req_notify_cq,
+	[IB_USER_VERBS_CMD_DESTROY_CQ]		= ib_uverbs_destroy_cq,
+	[IB_USER_VERBS_CMD_CREATE_QP]		= ib_uverbs_create_qp,
+	[IB_USER_VERBS_CMD_QUERY_QP]		= ib_uverbs_query_qp,
+	[IB_USER_VERBS_CMD_MODIFY_QP]		= ib_uverbs_modify_qp,
+	[IB_USER_VERBS_CMD_DESTROY_QP]		= ib_uverbs_destroy_qp,
+	[IB_USER_VERBS_CMD_POST_SEND]		= ib_uverbs_post_send,
+	[IB_USER_VERBS_CMD_POST_RECV]		= ib_uverbs_post_recv,
+	[IB_USER_VERBS_CMD_POST_SRQ_RECV]	= ib_uverbs_post_srq_recv,
+	[IB_USER_VERBS_CMD_CREATE_AH]		= ib_uverbs_create_ah,
+	[IB_USER_VERBS_CMD_DESTROY_AH]		= ib_uverbs_destroy_ah,
+	[IB_USER_VERBS_CMD_ATTACH_MCAST]	= ib_uverbs_attach_mcast,
+	[IB_USER_VERBS_CMD_DETACH_MCAST]	= ib_uverbs_detach_mcast,
+	[IB_USER_VERBS_CMD_CREATE_SRQ]		= ib_uverbs_create_srq,
+	[IB_USER_VERBS_CMD_MODIFY_SRQ]		= ib_uverbs_modify_srq,
+	[IB_USER_VERBS_CMD_QUERY_SRQ]		= ib_uverbs_query_srq,
+	[IB_USER_VERBS_CMD_DESTROY_SRQ]		= ib_uverbs_destroy_srq,
 };
 
-static struct vfsmount *uverbs_event_mnt;
-
 static void ib_uverbs_add_one(struct ib_device *device);
 static void ib_uverbs_remove_one(struct ib_device *device);
 
@@ -370,7 +366,7 @@ static int ib_uverbs_event_close(struct
 
 static const struct file_operations uverbs_event_fops = {
 	.owner	 = THIS_MODULE,
-	.read 	 = ib_uverbs_event_read,
+	.read	 = ib_uverbs_event_read,
 	.poll    = ib_uverbs_event_poll,
 	.release = ib_uverbs_event_close,
 	.fasync  = ib_uverbs_event_fasync
@@ -489,12 +485,10 @@ void ib_uverbs_event_handler(struct ib_e
 }
 
 struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
-					int is_async, int *fd)
+					int is_async)
 {
 	struct ib_uverbs_event_file *ev_file;
-	struct path path;
 	struct file *filp;
-	int ret;
 
 	ev_file = kmalloc(sizeof *ev_file, GFP_KERNEL);
 	if (!ev_file)
@@ -509,38 +503,12 @@ struct file *ib_uverbs_alloc_event_file(
 	ev_file->is_async    = is_async;
 	ev_file->is_closed   = 0;
 
-	*fd = get_unused_fd();
-	if (*fd < 0) {
-		ret = *fd;
-		goto err;
-	}
-
-	/*
-	 * fops_get() can't fail here, because we're coming from a
-	 * system call on a uverbs file, which will already have a
-	 * module reference.
-	 */
-	path.mnt = uverbs_event_mnt;
-	path.dentry = uverbs_event_mnt->mnt_root;
-	path_get(&path);
-	filp = alloc_file(&path, FMODE_READ, fops_get(&uverbs_event_fops));
-	if (!filp) {
-		ret = -ENFILE;
-		goto err_fd;
-	}
-
-	filp->private_data = ev_file;
+	filp = anon_inode_getfile("[infinibandevent]", &uverbs_event_fops,
+				  ev_file, O_RDONLY);
+	if (IS_ERR(filp))
+		kfree(ev_file);
 
 	return filp;
-
-err_fd:
-	fops_put(&uverbs_event_fops);
-	path_put(&path);
-	put_unused_fd(*fd);
-
-err:
-	kfree(ev_file);
-	return ERR_PTR(ret);
 }
 
 /*
@@ -617,14 +585,12 @@ static int ib_uverbs_mmap(struct file *f
 /*
  * ib_uverbs_open() does not need the BKL:
  *
- *  - dev_table[] accesses are protected by map_lock, the
- *    ib_uverbs_device structures are properly reference counted, and
+ *  - the ib_uverbs_device structures are properly reference counted and
  *    everything else is purely local to the file being created, so
  *    races against other open calls are not a problem;
  *  - there is no ioctl method to race against;
- *  - the device is added to dev_table[] as the last part of module
- *    initialization, the open method will either immediately run
- *    -ENXIO, or all required initialization will be done.
+ *  - the open method will either immediately run -ENXIO, or all
+ *    required initialization will be done.
  */
 static int ib_uverbs_open(struct inode *inode, struct file *filp)
 {
@@ -632,13 +598,10 @@ static int ib_uverbs_open(struct inode *
 	struct ib_uverbs_file *file;
 	int ret;
 
-	spin_lock(&map_lock);
-	dev = dev_table[iminor(inode) - IB_UVERBS_BASE_MINOR];
+	dev = container_of(inode->i_cdev, struct ib_uverbs_device, cdev);
 	if (dev)
 		kref_get(&dev->ref);
-	spin_unlock(&map_lock);
-
-	if (!dev)
+	else
 		return -ENXIO;
 
 	if (!try_module_get(dev->ib_dev->owner)) {
@@ -685,17 +648,17 @@ static int ib_uverbs_close(struct inode
 }
 
 static const struct file_operations uverbs_fops = {
-	.owner 	 = THIS_MODULE,
-	.write 	 = ib_uverbs_write,
-	.open 	 = ib_uverbs_open,
+	.owner	 = THIS_MODULE,
+	.write	 = ib_uverbs_write,
+	.open	 = ib_uverbs_open,
 	.release = ib_uverbs_close
 };
 
 static const struct file_operations uverbs_mmap_fops = {
-	.owner 	 = THIS_MODULE,
-	.write 	 = ib_uverbs_write,
+	.owner	 = THIS_MODULE,
+	.write	 = ib_uverbs_write,
 	.mmap    = ib_uverbs_mmap,
-	.open 	 = ib_uverbs_open,
+	.open	 = ib_uverbs_open,
 	.release = ib_uverbs_close
 };
 
@@ -729,14 +692,41 @@ static ssize_t show_dev_abi_version(stru
 }
 static DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL);
 
-static ssize_t show_abi_version(struct class *class, char *buf)
+static CLASS_ATTR_STRING(abi_version, S_IRUGO,
+			 __stringify(IB_USER_VERBS_ABI_VERSION));
+
+static dev_t overflow_maj;
+static DECLARE_BITMAP(overflow_map, IB_UVERBS_MAX_DEVICES);
+
+/*
+ * If we have more than IB_UVERBS_MAX_DEVICES, dynamically overflow by
+ * requesting a new major number and doubling the number of max devices we
+ * support. It's stupid, but simple.
+ */
+static int find_overflow_devnum(void)
 {
-	return sprintf(buf, "%d\n", IB_USER_VERBS_ABI_VERSION);
+	int ret;
+
+	if (!overflow_maj) {
+		ret = alloc_chrdev_region(&overflow_maj, 0, IB_UVERBS_MAX_DEVICES,
+					  "infiniband_verbs");
+		if (ret) {
+			printk(KERN_ERR "user_verbs: couldn't register dynamic device number\n");
+			return ret;
+		}
+	}
+
+	ret = find_first_zero_bit(overflow_map, IB_UVERBS_MAX_DEVICES);
+	if (ret >= IB_UVERBS_MAX_DEVICES)
+		return -1;
+
+	return ret;
 }
-static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
 
 static void ib_uverbs_add_one(struct ib_device *device)
 {
+	int devnum;
+	dev_t base;
 	struct ib_uverbs_device *uverbs_dev;
 
 	if (!device->alloc_ucontext)
@@ -750,28 +740,36 @@ static void ib_uverbs_add_one(struct ib_
 	init_completion(&uverbs_dev->comp);
 
 	spin_lock(&map_lock);
-	uverbs_dev->devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES);
-	if (uverbs_dev->devnum >= IB_UVERBS_MAX_DEVICES) {
+	devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES);
+	if (devnum >= IB_UVERBS_MAX_DEVICES) {
 		spin_unlock(&map_lock);
-		goto err;
+		devnum = find_overflow_devnum();
+		if (devnum < 0)
+			goto err;
+
+		spin_lock(&map_lock);
+		uverbs_dev->devnum = devnum + IB_UVERBS_MAX_DEVICES;
+		base = devnum + overflow_maj;
+		set_bit(devnum, overflow_map);
+	} else {
+		uverbs_dev->devnum = devnum;
+		base = devnum + IB_UVERBS_BASE_DEV;
+		set_bit(devnum, dev_map);
 	}
-	set_bit(uverbs_dev->devnum, dev_map);
 	spin_unlock(&map_lock);
 
 	uverbs_dev->ib_dev           = device;
 	uverbs_dev->num_comp_vectors = device->num_comp_vectors;
 
-	uverbs_dev->cdev = cdev_alloc();
-	if (!uverbs_dev->cdev)
-		goto err;
-	uverbs_dev->cdev->owner = THIS_MODULE;
-	uverbs_dev->cdev->ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops;
-	kobject_set_name(&uverbs_dev->cdev->kobj, "uverbs%d", uverbs_dev->devnum);
-	if (cdev_add(uverbs_dev->cdev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
+	cdev_init(&uverbs_dev->cdev, NULL);
+	uverbs_dev->cdev.owner = THIS_MODULE;
+	uverbs_dev->cdev.ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops;
+	kobject_set_name(&uverbs_dev->cdev.kobj, "uverbs%d", uverbs_dev->devnum);
+	if (cdev_add(&uverbs_dev->cdev, base, 1))
 		goto err_cdev;
 
 	uverbs_dev->dev = device_create(uverbs_class, device->dma_device,
-					uverbs_dev->cdev->dev, uverbs_dev,
+					uverbs_dev->cdev.dev, uverbs_dev,
 					"uverbs%d", uverbs_dev->devnum);
 	if (IS_ERR(uverbs_dev->dev))
 		goto err_cdev;
@@ -781,20 +779,19 @@ static void ib_uverbs_add_one(struct ib_
 	if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version))
 		goto err_class;
 
-	spin_lock(&map_lock);
-	dev_table[uverbs_dev->devnum] = uverbs_dev;
-	spin_unlock(&map_lock);
-
 	ib_set_client_data(device, &uverbs_client, uverbs_dev);
 
 	return;
 
 err_class:
-	device_destroy(uverbs_class, uverbs_dev->cdev->dev);
+	device_destroy(uverbs_class, uverbs_dev->cdev.dev);
 
 err_cdev:
-	cdev_del(uverbs_dev->cdev);
-	clear_bit(uverbs_dev->devnum, dev_map);
+	cdev_del(&uverbs_dev->cdev);
+	if (uverbs_dev->devnum < IB_UVERBS_MAX_DEVICES)
+		clear_bit(devnum, dev_map);
+	else
+		clear_bit(devnum, overflow_map);
 
 err:
 	kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
@@ -811,35 +808,19 @@ static void ib_uverbs_remove_one(struct
 		return;
 
 	dev_set_drvdata(uverbs_dev->dev, NULL);
-	device_destroy(uverbs_class, uverbs_dev->cdev->dev);
-	cdev_del(uverbs_dev->cdev);
-
-	spin_lock(&map_lock);
-	dev_table[uverbs_dev->devnum] = NULL;
-	spin_unlock(&map_lock);
+	device_destroy(uverbs_class, uverbs_dev->cdev.dev);
+	cdev_del(&uverbs_dev->cdev);
 
-	clear_bit(uverbs_dev->devnum, dev_map);
+	if (uverbs_dev->devnum < IB_UVERBS_MAX_DEVICES)
+		clear_bit(uverbs_dev->devnum, dev_map);
+	else
+		clear_bit(uverbs_dev->devnum - IB_UVERBS_MAX_DEVICES, overflow_map);
 
 	kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
 	wait_for_completion(&uverbs_dev->comp);
 	kfree(uverbs_dev);
 }
 
-static int uverbs_event_get_sb(struct file_system_type *fs_type, int flags,
-			       const char *dev_name, void *data,
-			       struct vfsmount *mnt)
-{
-	return get_sb_pseudo(fs_type, "infinibandevent:", NULL,
-			     INFINIBANDEVENTFS_MAGIC, mnt);
-}
-
-static struct file_system_type uverbs_event_fs = {
-	/* No owner field so module can be unloaded */
-	.name    = "infinibandeventfs",
-	.get_sb  = uverbs_event_get_sb,
-	.kill_sb = kill_litter_super
-};
-
 static int __init ib_uverbs_init(void)
 {
 	int ret;
@@ -858,39 +839,20 @@ static int __init ib_uverbs_init(void)
 		goto out_chrdev;
 	}
 
-	ret = class_create_file(uverbs_class, &class_attr_abi_version);
+	ret = class_create_file(uverbs_class, &class_attr_abi_version.attr);
 	if (ret) {
 		printk(KERN_ERR "user_verbs: couldn't create abi_version attribute\n");
 		goto out_class;
 	}
 
-	ret = register_filesystem(&uverbs_event_fs);
-	if (ret) {
-		printk(KERN_ERR "user_verbs: couldn't register infinibandeventfs\n");
-		goto out_class;
-	}
-
-	uverbs_event_mnt = kern_mount(&uverbs_event_fs);
-	if (IS_ERR(uverbs_event_mnt)) {
-		ret = PTR_ERR(uverbs_event_mnt);
-		printk(KERN_ERR "user_verbs: couldn't mount infinibandeventfs\n");
-		goto out_fs;
-	}
-
 	ret = ib_register_client(&uverbs_client);
 	if (ret) {
 		printk(KERN_ERR "user_verbs: couldn't register client\n");
-		goto out_mnt;
+		goto out_class;
 	}
 
 	return 0;
 
-out_mnt:
-	mntput(uverbs_event_mnt);
-
-out_fs:
-	unregister_filesystem(&uverbs_event_fs);
-
 out_class:
 	class_destroy(uverbs_class);
 
@@ -904,10 +866,10 @@ out:
 static void __exit ib_uverbs_cleanup(void)
 {
 	ib_unregister_client(&uverbs_client);
-	mntput(uverbs_event_mnt);
-	unregister_filesystem(&uverbs_event_fs);
 	class_destroy(uverbs_class);
 	unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
+	if (overflow_maj)
+		unregister_chrdev_region(overflow_maj, IB_UVERBS_MAX_DEVICES);
 	idr_destroy(&ib_uverbs_pd_idr);
 	idr_destroy(&ib_uverbs_mr_idr);
 	idr_destroy(&ib_uverbs_mw_idr);
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_alloc.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_alloc.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_alloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_alloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,6 @@
  */
 
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/bitmap.h>
 
 #include "c2.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,7 @@
 #include <linux/tcp.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_cm.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_cm.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_cm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_cm.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,8 @@
  * SOFTWARE.
  *
  */
+#include <linux/slab.h>
+
 #include "c2.h"
 #include "c2_wr.h"
 #include "c2_vq.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_cq.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_cq.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_cq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_cq.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,8 @@
  * SOFTWARE.
  *
  */
+#include <linux/gfp.h>
+
 #include "c2.h"
 #include "c2_vq.h"
 #include "c2_status.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_mm.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_mm.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_mm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_mm.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,8 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
+#include <linux/slab.h>
+
 #include "c2.h"
 #include "c2_vq.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_pd.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_pd.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_pd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_pd.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 
 #include "c2.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_provider.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_provider.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_provider.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_provider.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,6 +50,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/if_arp.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_qp.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_qp.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_qp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_qp.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 #include "c2.h"
 #include "c2_vq.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_rnic.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_rnic.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_rnic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/amso1100/c2_rnic.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,6 +51,7 @@
 #include <linux/mm.h>
 #include <linux/inet.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include <linux/route.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/cxio_dbg.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/cxio_dbg.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/cxio_dbg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/cxio_dbg.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
  */
 #ifdef DEBUG
 #include <linux/types.h>
+#include <linux/slab.h>
 #include "common.h"
 #include "cxgb3_ioctl.h"
 #include "cxio_hal.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/spinlock.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 
 #include "cxio_resource.h"
@@ -109,7 +110,6 @@ int cxio_hal_cq_op(struct cxio_rdev *rde
 		while (!CQ_VLD_ENTRY(rptr, cq->size_log2, cqe)) {
 			udelay(1);
 			if (i++ > 1000000) {
-				BUG_ON(1);
 				printk(KERN_ERR "%s: stalled rnic\n",
 				       rdev_p->dev_name);
 				return -EIO;
@@ -155,7 +155,7 @@ static int cxio_hal_clear_qp_ctx(struct
 	return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
 }
 
-int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq)
+int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq, int kernel)
 {
 	struct rdma_cq_setup setup;
 	int size = (1UL << (cq->size_log2)) * sizeof(struct t3_cqe);
@@ -163,12 +163,12 @@ int cxio_create_cq(struct cxio_rdev *rde
 	cq->cqid = cxio_hal_get_cqid(rdev_p->rscp);
 	if (!cq->cqid)
 		return -ENOMEM;
-	cq->sw_queue = kzalloc(size, GFP_KERNEL);
-	if (!cq->sw_queue)
-		return -ENOMEM;
-	cq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev),
-					     (1UL << (cq->size_log2)) *
-					     sizeof(struct t3_cqe),
+	if (kernel) {
+		cq->sw_queue = kzalloc(size, GFP_KERNEL);
+		if (!cq->sw_queue)
+			return -ENOMEM;
+	}
+	cq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev), size,
 					     &(cq->dma_addr), GFP_KERNEL);
 	if (!cq->queue) {
 		kfree(cq->sw_queue);
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.h linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.h
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.h	2010-05-16 17:17:36.000000000 -0400
@@ -53,7 +53,7 @@
 #define T3_MAX_PBL_SIZE 256
 #define T3_MAX_RQ_SIZE 1024
 #define T3_MAX_QP_DEPTH (T3_MAX_RQ_SIZE-1)
-#define T3_MAX_CQ_DEPTH 8192
+#define T3_MAX_CQ_DEPTH 262144
 #define T3_MAX_NUM_STAG (1<<15)
 #define T3_MAX_MR_SIZE 0x100000000ULL
 #define T3_PAGESIZE_MASK 0xffff000  /* 4KB-128MB */
@@ -157,7 +157,7 @@ int cxio_rdev_open(struct cxio_rdev *rde
 void cxio_rdev_close(struct cxio_rdev *rdev);
 int cxio_hal_cq_op(struct cxio_rdev *rdev, struct t3_cq *cq,
 		   enum t3_cq_opcode op, u32 credit);
-int cxio_create_cq(struct cxio_rdev *rdev, struct t3_cq *cq);
+int cxio_create_cq(struct cxio_rdev *rdev, struct t3_cq *cq, int kernel);
 int cxio_destroy_cq(struct cxio_rdev *rdev, struct t3_cq *cq);
 int cxio_resize_cq(struct cxio_rdev *rdev, struct t3_cq *cq);
 void cxio_release_ucontext(struct cxio_rdev *rdev, struct cxio_ucontext *uctx);
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/cxio_wr.h linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/cxio_wr.h
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/cxio_wr.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/cxio_wr.h	2010-05-16 17:17:36.000000000 -0400
@@ -730,7 +730,22 @@ struct t3_cq {
 
 static inline void cxio_set_wq_in_error(struct t3_wq *wq)
 {
-	wq->queue->wq_in_err.err = 1;
+	wq->queue->wq_in_err.err |= 1;
+}
+
+static inline void cxio_disable_wq_db(struct t3_wq *wq)
+{
+	wq->queue->wq_in_err.err |= 2;
+}
+
+static inline void cxio_enable_wq_db(struct t3_wq *wq)
+{
+	wq->queue->wq_in_err.err &= ~2;
+}
+
+static inline int cxio_wq_db_enabled(struct t3_wq *wq)
+{
+	return !(wq->queue->wq_in_err.err & 2);
 }
 
 static inline struct t3_cqe *cxio_next_hw_cqe(struct t3_cq *cq)
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/iwch.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/iwch.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,6 +65,46 @@ struct cxgb3_client t3c_client = {
 static LIST_HEAD(dev_list);
 static DEFINE_MUTEX(dev_mutex);
 
+static int disable_qp_db(int id, void *p, void *data)
+{
+	struct iwch_qp *qhp = p;
+
+	cxio_disable_wq_db(&qhp->wq);
+	return 0;
+}
+
+static int enable_qp_db(int id, void *p, void *data)
+{
+	struct iwch_qp *qhp = p;
+
+	if (data)
+		ring_doorbell(qhp->rhp->rdev.ctrl_qp.doorbell, qhp->wq.qpid);
+	cxio_enable_wq_db(&qhp->wq);
+	return 0;
+}
+
+static void disable_dbs(struct iwch_dev *rnicp)
+{
+	spin_lock_irq(&rnicp->lock);
+	idr_for_each(&rnicp->qpidr, disable_qp_db, NULL);
+	spin_unlock_irq(&rnicp->lock);
+}
+
+static void enable_dbs(struct iwch_dev *rnicp, int ring_db)
+{
+	spin_lock_irq(&rnicp->lock);
+	idr_for_each(&rnicp->qpidr, enable_qp_db,
+		     (void *)(unsigned long)ring_db);
+	spin_unlock_irq(&rnicp->lock);
+}
+
+static void iwch_db_drop_task(struct work_struct *work)
+{
+	struct iwch_dev *rnicp = container_of(work, struct iwch_dev,
+					      db_drop_task.work);
+	enable_dbs(rnicp, 1);
+}
+
 static void rnic_init(struct iwch_dev *rnicp)
 {
 	PDBG("%s iwch_dev %p\n", __func__,  rnicp);
@@ -72,6 +112,7 @@ static void rnic_init(struct iwch_dev *r
 	idr_init(&rnicp->qpidr);
 	idr_init(&rnicp->mmidr);
 	spin_lock_init(&rnicp->lock);
+	INIT_DELAYED_WORK(&rnicp->db_drop_task, iwch_db_drop_task);
 
 	rnicp->attr.max_qps = T3_MAX_NUM_QP - 32;
 	rnicp->attr.max_wrs = T3_MAX_QP_DEPTH;
@@ -147,6 +188,9 @@ static void close_rnic_dev(struct t3cdev
 	mutex_lock(&dev_mutex);
 	list_for_each_entry_safe(dev, tmp, &dev_list, entry) {
 		if (dev->rdev.t3cdev_p == tdev) {
+			dev->rdev.flags = CXIO_ERROR_FATAL;
+			synchronize_net();
+			cancel_delayed_work_sync(&dev->db_drop_task);
 			list_del(&dev->entry);
 			iwch_unregister_device(dev);
 			cxio_rdev_close(&dev->rdev);
@@ -165,7 +209,8 @@ static void iwch_event_handler(struct t3
 	struct cxio_rdev *rdev = tdev->ulp;
 	struct iwch_dev *rnicp;
 	struct ib_event event;
-	u32    portnum = port_id + 1;
+	u32 portnum = port_id + 1;
+	int dispatch = 0;
 
 	if (!rdev)
 		return;
@@ -173,22 +218,51 @@ static void iwch_event_handler(struct t3
 	switch (evt) {
 	case OFFLOAD_STATUS_DOWN: {
 		rdev->flags = CXIO_ERROR_FATAL;
+		synchronize_net();
 		event.event  = IB_EVENT_DEVICE_FATAL;
+		dispatch = 1;
 		break;
 		}
 	case OFFLOAD_PORT_DOWN: {
 		event.event  = IB_EVENT_PORT_ERR;
+		dispatch = 1;
 		break;
 		}
 	case OFFLOAD_PORT_UP: {
 		event.event  = IB_EVENT_PORT_ACTIVE;
+		dispatch = 1;
+		break;
+		}
+	case OFFLOAD_DB_FULL: {
+		disable_dbs(rnicp);
+		break;
+		}
+	case OFFLOAD_DB_EMPTY: {
+		enable_dbs(rnicp, 1);
+		break;
+		}
+	case OFFLOAD_DB_DROP: {
+		unsigned long delay = 1000;
+		unsigned short r;
+
+		disable_dbs(rnicp);
+		get_random_bytes(&r, 2);
+		delay += r & 1023;
+
+		/*
+		 * delay is between 1000-2023 usecs.
+		 */
+		schedule_delayed_work(&rnicp->db_drop_task,
+			usecs_to_jiffies(delay));
 		break;
 		}
 	}
 
-	event.device = &rnicp->ibdev;
-	event.element.port_num = portnum;
-	ib_dispatch_event(&event);
+	if (dispatch) {
+		event.device = &rnicp->ibdev;
+		event.element.port_num = portnum;
+		ib_dispatch_event(&event);
+	}
 
 	return;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch_cm.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/iwch_cm.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch_cm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/iwch_cm.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
  */
 #include <linux/module.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/skbuff.h>
 #include <linux/timer.h>
@@ -1371,15 +1372,8 @@ static int pass_accept_req(struct t3cdev
 	tim.mac_addr = req->dst_mac;
 	tim.vlan_tag = ntohs(req->vlan_tag);
 	if (tdev->ctl(tdev, GET_IFF_FROM_MAC, &tim) < 0 || !tim.dev) {
-		printk(KERN_ERR
-			"%s bad dst mac %02x %02x %02x %02x %02x %02x\n",
-			__func__,
-			req->dst_mac[0],
-			req->dst_mac[1],
-			req->dst_mac[2],
-			req->dst_mac[3],
-			req->dst_mac[4],
-			req->dst_mac[5]);
+		printk(KERN_ERR "%s bad dst mac %pM\n",
+			__func__, req->dst_mac);
 		goto reject;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch_ev.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/iwch_ev.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch_ev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/iwch_ev.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,7 +29,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/mman.h>
 #include <net/sock.h>
 #include "iwch_provider.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch.h linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/iwch.h
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/iwch.h	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/idr.h>
+#include <linux/workqueue.h>
 
 #include <rdma/ib_verbs.h>
 
@@ -110,6 +111,7 @@ struct iwch_dev {
 	struct idr mmidr;
 	spinlock_t lock;
 	struct list_head entry;
+	struct delayed_work db_drop_task;
 };
 
 static inline struct iwch_dev *to_iwch_dev(struct ib_device *ibdev)
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch_mem.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/iwch_mem.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch_mem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/iwch_mem.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 
 #include <rdma/iw_cm.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch_provider.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/iwch_provider.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch_provider.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/iwch_provider.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/ethtool.h>
 #include <linux/rtnetlink.h>
 #include <linux/inetdevice.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -187,7 +188,7 @@ static struct ib_cq *iwch_create_cq(stru
 	entries = roundup_pow_of_two(entries);
 	chp->cq.size_log2 = ilog2(entries);
 
-	if (cxio_create_cq(&rhp->rdev, &chp->cq)) {
+	if (cxio_create_cq(&rhp->rdev, &chp->cq, !ucontext)) {
 		kfree(chp);
 		return ERR_PTR(-ENOMEM);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch_qp.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/iwch_qp.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch_qp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/cxgb3/iwch_qp.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
  * SOFTWARE.
  */
 #include <linux/sched.h>
+#include <linux/gfp.h>
 #include "iwch_provider.h"
 #include "iwch.h"
 #include "iwch_cm.h"
@@ -452,7 +453,8 @@ int iwch_post_send(struct ib_qp *ibqp, s
 		++(qhp->wq.sq_wptr);
 	}
 	spin_unlock_irqrestore(&qhp->lock, flag);
-	ring_doorbell(qhp->wq.doorbell, qhp->wq.qpid);
+	if (cxio_wq_db_enabled(&qhp->wq))
+		ring_doorbell(qhp->wq.doorbell, qhp->wq.qpid);
 
 out:
 	if (err)
@@ -514,7 +516,8 @@ int iwch_post_receive(struct ib_qp *ibqp
 		num_wrs--;
 	}
 	spin_unlock_irqrestore(&qhp->lock, flag);
-	ring_doorbell(qhp->wq.doorbell, qhp->wq.qpid);
+	if (cxio_wq_db_enabled(&qhp->wq))
+		ring_doorbell(qhp->wq.doorbell, qhp->wq.qpid);
 
 out:
 	if (err)
@@ -597,7 +600,8 @@ int iwch_bind_mw(struct ib_qp *qp,
 	++(qhp->wq.sq_wptr);
 	spin_unlock_irqrestore(&qhp->lock, flag);
 
-	ring_doorbell(qhp->wq.doorbell, qhp->wq.qpid);
+	if (cxio_wq_db_enabled(&qhp->wq))
+		ring_doorbell(qhp->wq.doorbell, qhp->wq.qpid);
 
 	return err;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_av.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_av.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_av.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_av.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include "ehca_tools.h"
 #include "ehca_iverbs.h"
 #include "hcp_if.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_cq.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_cq.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_cq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_cq.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include "ehca_iverbs.h"
 #include "ehca_classes.h"
 #include "ehca_irq.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_hca.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_hca.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_hca.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_hca.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/gfp.h>
+
 #include "ehca_tools.h"
 #include "ehca_iverbs.h"
 #include "hcp_if.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_irq.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_irq.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include "ehca_classes.h"
 #include "ehca_irq.h"
 #include "ehca_iverbs.h"
@@ -548,11 +550,10 @@ void ehca_process_eq(struct ehca_shca *s
 	struct ehca_eq *eq = &shca->eq;
 	struct ehca_eqe_cache_entry *eqe_cache = eq->eqe_cache;
 	u64 eqe_value, ret;
-	unsigned long flags;
 	int eqe_cnt, i;
 	int eq_empty = 0;
 
-	spin_lock_irqsave(&eq->irq_spinlock, flags);
+	spin_lock(&eq->irq_spinlock);
 	if (is_irq) {
 		const int max_query_cnt = 100;
 		int query_cnt = 0;
@@ -643,7 +644,7 @@ void ehca_process_eq(struct ehca_shca *s
 	} while (1);
 
 unlock_irq_spinlock:
-	spin_unlock_irqrestore(&eq->irq_spinlock, flags);
+	spin_unlock(&eq->irq_spinlock);
 }
 
 void ehca_tasklet_eq(unsigned long data)
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_mrmw.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_mrmw.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_mrmw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_mrmw.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
 #include <rdma/ib_umem.h>
 
 #include "ehca_iverbs.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_pd.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_pd.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_pd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_pd.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include "ehca_tools.h"
 #include "ehca_iverbs.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_qes.h linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_qes.h
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_qes.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_qes.h	2010-05-16 17:17:36.000000000 -0400
@@ -46,7 +46,7 @@
 
 #include "ehca_tools.h"
 
-/* virtual scatter gather entry to specify remote adresses with length */
+/* virtual scatter gather entry to specify remote addresses with length */
 struct ehca_vsgentry {
 	u64 vaddr;
 	u32 lkey;
@@ -148,7 +148,7 @@ struct ehca_wqe {
 	u32 immediate_data;
 	union {
 		struct {
-			u64 remote_virtual_adress;
+			u64 remote_virtual_address;
 			u32 rkey;
 			u32 reserved;
 			u64 atomic_1st_op_dma_len;
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_qp.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_qp.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_qp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_qp.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include "ehca_classes.h"
 #include "ehca_tools.h"
 #include "ehca_qes.h"
@@ -55,9 +57,7 @@ static struct kmem_cache *qp_cache;
 /*
  * attributes not supported by query qp
  */
-#define QP_ATTR_QUERY_NOT_SUPPORTED (IB_QP_MAX_DEST_RD_ATOMIC | \
-				     IB_QP_MAX_QP_RD_ATOMIC   | \
-				     IB_QP_ACCESS_FLAGS       | \
+#define QP_ATTR_QUERY_NOT_SUPPORTED (IB_QP_ACCESS_FLAGS       | \
 				     IB_QP_EN_SQD_ASYNC_NOTIFY)
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_reqs.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_reqs.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_reqs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_reqs.c	2010-05-16 17:17:36.000000000 -0400
@@ -269,7 +269,7 @@ static inline int ehca_write_swqe(struct
 		/* no break is intentional here */
 	case IB_QPT_RC:
 		/* TODO: atomic not implemented */
-		wqe_p->u.nud.remote_virtual_adress =
+		wqe_p->u.nud.remote_virtual_address =
 			send_wr->wr.rdma.remote_addr;
 		wqe_p->u.nud.rkey = send_wr->wr.rdma.rkey;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_sqp.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_sqp.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_sqp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_sqp.c	2010-05-16 17:17:36.000000000 -0400
@@ -222,7 +222,7 @@ int ehca_process_mad(struct ib_device *i
 {
 	int ret;
 
-	if (!port_num || port_num > ibdev->phys_port_cnt)
+	if (!port_num || port_num > ibdev->phys_port_cnt || !in_wc)
 		return IB_MAD_RESULT_FAILURE;
 
 	/* accept only pma request */
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_uverbs.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_uverbs.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_uverbs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ehca_uverbs.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include "ehca_classes.h"
 #include "ehca_iverbs.h"
 #include "ehca_mrmw.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ipz_pt_fn.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ipz_pt_fn.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ipz_pt_fn.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ehca/ipz_pt_fn.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include "ehca_tools.h"
 #include "ipz_pt_fn.h"
 #include "ehca_classes.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_cq.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_cq.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_cq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_cq.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "ipath_verbs.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_dma.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_dma.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
  */
 
 #include <linux/scatterlist.h>
+#include <linux/gfp.h>
 #include <rdma/ib_verbs.h>
 
 #include "ipath_verbs.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_driver.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_driver.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_driver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_driver.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
 #include <linux/bitmap.h>
+#include <linux/slab.h>
 
 #include "ipath_kernel.h"
 #include "ipath_verbs.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_file_ops.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_file_ops.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_file_ops.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_file_ops.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/cdev.h>
 #include <linux/swap.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/io.h>
 #include <linux/jiffies.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_fs.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_fs.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_fs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_fs.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/pagemap.h>
 #include <linux/init.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
 
 #include "ipath_kernel.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_init_chip.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_init_chip.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_init_chip.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_init_chip.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 
 #include <linux/pci.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "ipath_kernel.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_mmap.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_mmap.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_mmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_mmap.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 
 #include <linux/module.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <asm/pgtable.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_mr.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_mr.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_mr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_mr.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,8 @@
  * SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include <rdma/ib_umem.h>
 #include <rdma/ib_pack.h>
 #include <rdma/ib_smi.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_qp.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_qp.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_qp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_qp.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 
 #include <linux/err.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "ipath_verbs.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_sdma.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_sdma.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_sdma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_sdma.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
  */
 
 #include <linux/spinlock.h>
+#include <linux/gfp.h>
 
 #include "ipath_kernel.h"
 #include "ipath_verbs.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_srq.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_srq.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_srq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_srq.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "ipath_verbs.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_user_pages.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_user_pages.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_user_pages.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_user_pages.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 
 #include <linux/mm.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #include "ipath_kernel.h"
@@ -59,8 +60,7 @@ static int __get_user_pages(unsigned lon
 	size_t got;
 	int ret;
 
-	lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >>
-		PAGE_SHIFT;
+	lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
 
 	if (num_pages > lock_limit) {
 		ret = -ENOMEM;
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_verbs.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_verbs.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_verbs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_verbs.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <rdma/ib_mad.h>
 #include <rdma/ib_user_verbs.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/utsname.h>
 #include <linux/rculist.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 
 #include <linux/rculist.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include "ipath_verbs.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/ah.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mlx4/ah.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/ah.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mlx4/ah.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,8 @@
  * SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "mlx4_ib.h"
 
 struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/cq.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mlx4/cq.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/cq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mlx4/cq.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 
 #include <linux/mlx4/cq.h>
 #include <linux/mlx4/qp.h>
+#include <linux/slab.h>
 
 #include "mlx4_ib.h"
 #include "user.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/mad.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mlx4/mad.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/mad.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mlx4/mad.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <rdma/ib_smi.h>
 
 #include <linux/mlx4/cmd.h>
+#include <linux/gfp.h>
 
 #include "mlx4_ib.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/main.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mlx4/main.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mlx4/main.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 
 #include <rdma/ib_smi.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/mr.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mlx4/mr.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/mr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mlx4/mr.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,8 @@
  * SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "mlx4_ib.h"
 
 static u32 convert_access(int acc)
@@ -238,7 +240,7 @@ struct ib_fast_reg_page_list *mlx4_ib_al
 	mfrpl->mapped_page_list = dma_alloc_coherent(&dev->dev->pdev->dev,
 						     size, &mfrpl->map,
 						     GFP_KERNEL);
-	if (!mfrpl->ibfrpl.page_list)
+	if (!mfrpl->mapped_page_list)
 		goto err_free;
 
 	WARN_ON(mfrpl->map & 0x3f);
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/qp.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mlx4/qp.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/qp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mlx4/qp.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
  */
 
 #include <linux/log2.h>
+#include <linux/slab.h>
 
 #include <rdma/ib_cache.h>
 #include <rdma/ib_pack.h>
@@ -1214,7 +1215,7 @@ out:
 static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr,
 			    void *wqe, unsigned *mlx_seg_len)
 {
-	struct ib_device *ib_dev = &to_mdev(sqp->qp.ibqp.device)->ib_dev;
+	struct ib_device *ib_dev = sqp->qp.ibqp.device;
 	struct mlx4_wqe_mlx_seg *mlx = wqe;
 	struct mlx4_wqe_inline_seg *inl = wqe + sizeof *mlx;
 	struct mlx4_ib_ah *ah = to_mah(wr->wr.ud.ah);
@@ -1228,7 +1229,7 @@ static int build_mlx_header(struct mlx4_
 	for (i = 0; i < wr->num_sge; ++i)
 		send_size += wr->sg_list[i].length;
 
-	ib_ud_header_init(send_size, mlx4_ib_ah_grh_present(ah), &sqp->ud_header);
+	ib_ud_header_init(send_size, mlx4_ib_ah_grh_present(ah), 0, &sqp->ud_header);
 
 	sqp->ud_header.lrh.service_level   =
 		be32_to_cpu(ah->av.sl_tclass_flowlabel) >> 28;
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/srq.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mlx4/srq.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/srq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mlx4/srq.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 
 #include <linux/mlx4/qp.h>
 #include <linux/mlx4/srq.h>
+#include <linux/slab.h>
 
 #include "mlx4_ib.h"
 #include "user.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_cmd.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_cmd.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_cmd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_cmd.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/pci.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <rdma/ib_mad.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_cq.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_cq.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_cq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_cq.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
  * SOFTWARE.
  */
 
+#include <linux/gfp.h>
 #include <linux/hardirq.h>
 #include <linux/sched.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_eq.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_eq.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_eq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_eq.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "mthca_dev.h"
 #include "mthca_cmd.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_main.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_main.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/errno.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
+#include <linux/gfp.h>
 
 #include "mthca_dev.h"
 #include "mthca_config_reg.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_mcg.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_mcg.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_mcg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_mcg.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,7 @@
  */
 
 #include <linux/string.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 
 #include "mthca_dev.h"
 #include "mthca_cmd.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_memfree.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_memfree.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_memfree.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_memfree.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/mm.h>
 #include <linux/scatterlist.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <asm/page.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_provider.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_provider.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_provider.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_provider.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <rdma/ib_user_verbs.h>
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 
 #include "mthca_dev.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_qp.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_qp.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mthca/mthca_qp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/mthca/mthca_qp.c	2010-05-16 17:17:36.000000000 -0400
@@ -1494,7 +1494,7 @@ static int build_mlx_header(struct mthca
 	u16 pkey;
 
 	ib_ud_header_init(256, /* assume a MAD */
-			  mthca_ah_grh_present(to_mah(wr->wr.ud.ah)),
+			  mthca_ah_grh_present(to_mah(wr->wr.ud.ah)), 0,
 			  &sqp->ud_header);
 
 	err = mthca_read_ah(dev, to_mah(wr->wr.ud.ah), &sqp->ud_header);
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,7 @@
 #include <linux/init.h>
 #include <linux/if_arp.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/byteorder.h>
@@ -110,6 +111,7 @@ static unsigned int sysfs_idx_addr;
 
 static struct pci_device_id nes_pci_table[] = {
 	{PCI_VENDOR_ID_NETEFFECT, PCI_DEVICE_ID_NETEFFECT_NE020, PCI_ANY_ID, PCI_ANY_ID},
+	{PCI_VENDOR_ID_NETEFFECT, PCI_DEVICE_ID_NETEFFECT_NE020_KR, PCI_ANY_ID, PCI_ANY_ID},
 	{0}
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_cm.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes_cm.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_cm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes_cm.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,6 +53,7 @@
 #include <linux/list.h>
 #include <linux/threads.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 #include <net/neighbour.h>
 #include <net/route.h>
@@ -67,8 +68,8 @@ u32 cm_packets_dropped;
 u32 cm_packets_retrans;
 u32 cm_packets_created;
 u32 cm_packets_received;
-u32 cm_listens_created;
-u32 cm_listens_destroyed;
+atomic_t cm_listens_created;
+atomic_t cm_listens_destroyed;
 u32 cm_backlog_drops;
 atomic_t cm_loopbacks;
 atomic_t cm_nodes_created;
@@ -1011,9 +1012,10 @@ static int mini_cm_dec_refcnt_listen(str
 					event.cm_info.loc_port =
 							 loopback->loc_port;
 					event.cm_info.cm_id = loopback->cm_id;
+					add_ref_cm_node(loopback);
+					loopback->state = NES_CM_STATE_CLOSED;
 					cm_event_connect_error(&event);
 					cm_node->state = NES_CM_STATE_LISTENER_DESTROYED;
-					loopback->state = NES_CM_STATE_CLOSED;
 
 					rem_ref_cm_node(cm_node->cm_core,
 							 cm_node);
@@ -1042,7 +1044,7 @@ static int mini_cm_dec_refcnt_listen(str
 		kfree(listener);
 		listener = NULL;
 		ret = 0;
-		cm_listens_destroyed++;
+		atomic_inc(&cm_listens_destroyed);
 	} else {
 		spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
 	}
@@ -3172,7 +3174,7 @@ int nes_create_listen(struct iw_cm_id *c
 			g_cm_core->api->stop_listener(g_cm_core, (void *)cm_node);
 			return err;
 		}
-		cm_listens_created++;
+		atomic_inc(&cm_listens_created);
 	}
 
 	cm_id->add_ref(cm_id);
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes.h linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes.h
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes.h	2010-05-16 17:17:36.000000000 -0400
@@ -64,8 +64,9 @@
  * NetEffect PCI vendor id and NE010 PCI device id.
  */
 #ifndef PCI_VENDOR_ID_NETEFFECT	/* not in pci.ids yet */
-#define PCI_VENDOR_ID_NETEFFECT       0x1678
-#define PCI_DEVICE_ID_NETEFFECT_NE020 0x0100
+#define PCI_VENDOR_ID_NETEFFECT          0x1678
+#define PCI_DEVICE_ID_NETEFFECT_NE020    0x0100
+#define PCI_DEVICE_ID_NETEFFECT_NE020_KR 0x0110
 #endif
 
 #define NE020_REV   4
@@ -193,8 +194,8 @@ extern u32 cm_packets_created;
 extern u32 cm_packets_received;
 extern u32 cm_packets_dropped;
 extern u32 cm_packets_retrans;
-extern u32 cm_listens_created;
-extern u32 cm_listens_destroyed;
+extern atomic_t cm_listens_created;
+extern atomic_t cm_listens_destroyed;
 extern u32 cm_backlog_drops;
 extern atomic_t cm_loopbacks;
 extern atomic_t cm_nodes_created;
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_hw.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes_hw.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_hw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes_hw.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/tcp.h>
 #include <linux/if_vlan.h>
 #include <linux/inet_lro.h>
+#include <linux/slab.h>
 
 #include "nes.h"
 
@@ -748,16 +749,28 @@ static int nes_init_serdes(struct nes_de
 
 	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
+		switch (nesadapter->phy_type[0]) {
+		case NES_PHY_TYPE_CX4:
+			if (wide_ppm_offset)
+				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000FFFAA);
+			else
+				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF);
+			break;
+		case NES_PHY_TYPE_KR:
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF);
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP0, 0x00000000);
+			break;
+		case NES_PHY_TYPE_PUMA_1G:
 			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF);
-
-		if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
 			sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0);
 			sds |= 0x00000100;
 			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds);
+			break;
+		default:
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF);
+			break;
 		}
+
 		if (!OneG_Mode)
 			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000);
 
@@ -778,6 +791,9 @@ static int nes_init_serdes(struct nes_de
 			if (wide_ppm_offset)
 				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000FFFAA);
 			break;
+		case NES_PHY_TYPE_KR:
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP1, 0x00000000);
+			break;
 		case NES_PHY_TYPE_PUMA_1G:
 			sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1);
 			sds |= 0x000000100;
@@ -1279,115 +1295,100 @@ int nes_destroy_cqp(struct nes_device *n
 
 
 /**
- * nes_init_phy
+ * nes_init_1g_phy
  */
-int nes_init_phy(struct nes_device *nesdev)
+int nes_init_1g_phy(struct nes_device *nesdev, u8 phy_type, u8 phy_index)
 {
-	struct nes_adapter *nesadapter = nesdev->nesadapter;
 	u32 counter = 0;
-	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;
-	u8  phy_type = nesadapter->phy_type[mac_index];
-	u8  phy_index = nesadapter->phy_index[mac_index];
+	int ret = 0;
 
-	if ((nesadapter->OneG_Mode) &&
-	    (phy_type != NES_PHY_TYPE_PUMA_1G)) {
-		nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index);
-		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, phy_index, &phy_data);
+	nes_write_1G_phy_reg(nesdev, 23, phy_index, 0xb000);
+
+	/* Reset the PHY */
+	nes_write_1G_phy_reg(nesdev, 0, phy_index, 0x8000);
+	udelay(100);
+	counter = 0;
+	do {
+		nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
+		if (counter++ > 100) {
+			ret = -1;
+			break;
 		}
+	} while (phy_data & 0x8000);
 
-		nes_read_1G_phy_reg(nesdev, 1, phy_index, &phy_data);
-		nes_write_1G_phy_reg(nesdev, 23, phy_index, 0xb000);
+	/* Setting no phy loopback */
+	phy_data &= 0xbfff;
+	phy_data |= 0x1140;
+	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);
 
-		/* Reset the PHY */
-		nes_write_1G_phy_reg(nesdev, 0, phy_index, 0x8000);
-		udelay(100);
-		counter = 0;
-		do {
-			nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
-			if (counter++ > 100)
-				break;
-		} while (phy_data & 0x8000);
+	/* Setting the interrupt mask */
+	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);
 
-		/* Setting no phy loopback */
-		phy_data &= 0xbfff;
-		phy_data |= 0x1140;
-		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);
+	/* turning on flow control */
+	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);
 
-		/* Setting the interrupt mask */
-		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);
+	/* Clear Half duplex */
+	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);
 
-		/* turning on flow control */
-		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, 0, phy_index, &phy_data);
+	nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data | 0x0300);
 
-		/* Clear Half duplex */
-		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);
+	return ret;
+}
 
-		nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
-		nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data | 0x0300);
 
-		return 0;
-	}
+/**
+ * nes_init_2025_phy
+ */
+int nes_init_2025_phy(struct nes_device *nesdev, u8 phy_type, u8 phy_index)
+{
+	u32 temp_phy_data = 0;
+	u32 temp_phy_data2 = 0;
+	u32 counter = 0;
+	u32 sds;
+	u32 mac_index = nesdev->mac_index;
+	int ret = 0;
+	unsigned int first_attempt = 1;
 
-	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)) {
-		u32 first_time = 1;
+	/* Check firmware heartbeat */
+	nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
+	temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+	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);
 
-		/* Check firmware heartbeat */
-		nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
+	if (temp_phy_data != temp_phy_data2) {
+		nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd);
 		temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
-		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);
+		if ((temp_phy_data & 0xff) > 0x20)
+			return 0;
+		printk(PFX "Reinitialize external PHY\n");
+	}
 
-		if (temp_phy_data != temp_phy_data2) {
-			nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd);
-			temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
-			if ((temp_phy_data & 0xff) > 0x20)
-				return 0;
-			printk(PFX "Reinitializing PHY\n");
-		}
+	/* no heartbeat, configure the PHY */
+	nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000);
+	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);
 
-		/* 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);
+	switch (phy_type) {
+	case NES_PHY_TYPE_ARGUS:
 		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, 0xc302, 0x000C);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0008);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0001);
 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc31a, 0x0098);
 		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0026, 0x0E00);
 
@@ -1395,71 +1396,151 @@ int nes_init_phy(struct nes_device *nesd
 		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);
+		break;
 
-		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0028, 0xA528);
+	case NES_PHY_TYPE_SFP_D:
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052);
+		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);
 
-		/* Bring PHY out of reset */
-		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0002);
+		/* 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);
+		break;
 
-		/* Check for heartbeat */
-		counter = 0;
-		mdelay(690);
+	case NES_PHY_TYPE_KR:
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x000C);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0010);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0013);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc31a, 0x0080);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0026, 0x0E00);
+
+		/* setup LEDs */
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd006, 0x000B);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd007, 0x0003);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd008, 0x0004);
+
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0022, 0x406D);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0023, 0x0020);
+		break;
+	}
+
+	nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0028, 0xA528);
+
+	/* Bring PHY out of reset */
+	nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0002);
+
+	/* 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) {
+			printk(PFX "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));
+
+	/* 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);
-		do {
-			if (counter++ > 150) {
-				printk(PFX "No PHY heartbeat\n");
+		if (counter++ > 300) {
+			if (((temp_phy_data & 0xff) == 0x0) && first_attempt) {
+				first_attempt = 0;
+				counter = 0;
+				/* reset AMCC PHY and try again */
+				nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x00c0);
+				nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x0040);
+				continue;
+			} else {
+				ret = 1;
 				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));
-
-		/* 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) {
-				if (((temp_phy_data & 0xff) == 0x0) && first_time) {
-					first_time = 0;
-					counter = 0;
-					/* reset AMCC PHY and try again */
-					nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x00c0);
-					nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x0040);
-					continue;
-				} else {
-					printk(PFX "PHY did not track\n");
-					break;
-				}
-			}
-			mdelay(10);
-		} while ((temp_phy_data & 0xff) < 0x30);
+		}
+		mdelay(10);
+	} while ((temp_phy_data & 0xff) < 0x30);
 
-		/* 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);
+	/* 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);
+	if (phy_type == NES_PHY_TYPE_KR) {
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00F, 0x000C);
+	} else {
 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00F, 0x0002);
 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc314, 0x0063);
+	}
 
-		/* 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);
+	/* 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))
-			;
+	counter = 0;
+	while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040)
+			&& (counter++ < 5000))
+		;
+
+	return ret;
+}
+
+
+/**
+ * nes_init_phy
+ */
+int nes_init_phy(struct nes_device *nesdev)
+{
+	struct nes_adapter *nesadapter = nesdev->nesadapter;
+	u32 mac_index = nesdev->mac_index;
+	u32 tx_config = 0;
+	unsigned long flags;
+	u8  phy_type = nesadapter->phy_type[mac_index];
+	u8  phy_index = nesadapter->phy_index[mac_index];
+	int ret = 0;
+
+	tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
+	if (phy_type == NES_PHY_TYPE_1G) {
+		/* setup 1G MDIO operation */
+		tx_config &= 0xFFFFFFE3;
+		tx_config |= 0x04;
+	} else {
+		/* setup 10G MDIO operation */
+		tx_config &= 0xFFFFFFE3;
+		tx_config |= 0x15;
 	}
-	return 0;
+	nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
+
+	spin_lock_irqsave(&nesdev->nesadapter->phy_lock, flags);
+
+	switch (phy_type) {
+	case NES_PHY_TYPE_1G:
+		ret = nes_init_1g_phy(nesdev, phy_type, phy_index);
+		break;
+	case NES_PHY_TYPE_ARGUS:
+	case NES_PHY_TYPE_SFP_D:
+	case NES_PHY_TYPE_KR:
+		ret = nes_init_2025_phy(nesdev, phy_type, phy_index);
+		break;
+	}
+
+	spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags);
+
+	return ret;
 }
 
 
@@ -1819,9 +1900,14 @@ void nes_destroy_nic_qp(struct nes_vnic
 	u16  wqe_fragment_index;
 	u64 wqe_frag;
 	u32 cqp_head;
+	u32 wqm_cfg0;
 	unsigned long flags;
 	int ret;
 
+	/* clear wqe stall before destroying NIC QP */
+	wqm_cfg0 = nes_read_indexed(nesdev, NES_IDX_WQM_CONFIG0);
+	nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG0, wqm_cfg0 & 0xFFFF7FFF);
+
 	/* Free remaining NIC receive buffers */
 	while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) {
 		nic_rqe   = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail];
@@ -1940,6 +2026,9 @@ void nes_destroy_nic_qp(struct nes_vnic
 
 	pci_free_consistent(nesdev->pcidev, nesvnic->nic_mem_size, nesvnic->nic_vbase,
 			nesvnic->nic_pbase);
+
+	/* restore old wqm_cfg0 value */
+	nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG0, wqm_cfg0);
 }
 
 /**
@@ -2460,23 +2549,9 @@ static void nes_process_mac_intr(struct
 			}
 		} else {
 			switch (nesadapter->phy_type[mac_index]) {
-			case NES_PHY_TYPE_IRIS:
-				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
-				temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
-				u32temp = 20;
-				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_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
-					__func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP");
-				break;
-
 			case NES_PHY_TYPE_ARGUS:
 			case NES_PHY_TYPE_SFP_D:
+			case NES_PHY_TYPE_KR:
 				/* 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);
@@ -3352,8 +3427,6 @@ static void nes_process_iwarp_aeqe(struc
 	u16 async_event_id;
 	u8 tcp_state;
 	u8 iwarp_state;
-	int must_disconn = 1;
-	int must_terminate = 0;
 	struct ib_event ibevent;
 
 	nes_debug(NES_DBG_AEQ, "\n");
@@ -3367,6 +3440,8 @@ static void nes_process_iwarp_aeqe(struc
 		BUG_ON(!context);
 	}
 
+	/* context is nesqp unless async_event_id == CQ ERROR */
+	nesqp = (struct nes_qp *)(unsigned long)context;
 	async_event_id = (u16)aeq_info;
 	tcp_state = (aeq_info & NES_AEQE_TCP_STATE_MASK) >> NES_AEQE_TCP_STATE_SHIFT;
 	iwarp_state = (aeq_info & NES_AEQE_IWARP_STATE_MASK) >> NES_AEQE_IWARP_STATE_SHIFT;
@@ -3378,8 +3453,6 @@ static void nes_process_iwarp_aeqe(struc
 
 	switch (async_event_id) {
 		case NES_AEQE_AEID_LLP_FIN_RECEIVED:
-			nesqp = (struct nes_qp *)(unsigned long)context;
-
 			if (nesqp->term_flags)
 				return; /* Ignore it, wait for close complete */
 
@@ -3394,79 +3467,48 @@ static void nes_process_iwarp_aeqe(struc
 						async_event_id, nesqp->last_aeq, tcp_state);
 			}
 
-			if ((tcp_state != NES_AEQE_TCP_STATE_CLOSE_WAIT) ||
-					(nesqp->ibqp_state != IB_QPS_RTS)) {
-				/* FIN Received but tcp state or IB state moved on,
-						should expect a	close complete */
-				return;
-			}
-
+			break;
 		case NES_AEQE_AEID_LLP_CLOSE_COMPLETE:
-			nesqp = (struct nes_qp *)(unsigned long)context;
 			if (nesqp->term_flags) {
 				nes_terminate_done(nesqp, 0);
 				return;
 			}
+			spin_lock_irqsave(&nesqp->lock, flags);
+			nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING;
+			spin_unlock_irqrestore(&nesqp->lock, flags);
+			nes_hw_modify_qp(nesdev, nesqp, NES_CQP_QP_IWARP_STATE_CLOSING, 0, 0);
+			nes_cm_disconn(nesqp);
+			break;
 
-		case NES_AEQE_AEID_LLP_CONNECTION_RESET:
 		case NES_AEQE_AEID_RESET_SENT:
-			nesqp = (struct nes_qp *)(unsigned long)context;
-			if (async_event_id == NES_AEQE_AEID_RESET_SENT) {
-				tcp_state = NES_AEQE_TCP_STATE_CLOSED;
-			}
+			tcp_state = NES_AEQE_TCP_STATE_CLOSED;
 			spin_lock_irqsave(&nesqp->lock, flags);
 			nesqp->hw_iwarp_state = iwarp_state;
 			nesqp->hw_tcp_state = tcp_state;
 			nesqp->last_aeq = async_event_id;
-
-			if ((tcp_state == NES_AEQE_TCP_STATE_CLOSED) ||
-					(tcp_state == NES_AEQE_TCP_STATE_TIME_WAIT)) {
-				nesqp->hte_added = 0;
-				next_iwarp_state = NES_CQP_QP_IWARP_STATE_ERROR | NES_CQP_QP_DEL_HTE;
-			}
-
-			if ((nesqp->ibqp_state == IB_QPS_RTS) &&
-					((tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) ||
-					(async_event_id == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
-				switch (nesqp->hw_iwarp_state) {
-					case NES_AEQE_IWARP_STATE_RTS:
-						next_iwarp_state = NES_CQP_QP_IWARP_STATE_CLOSING;
-						nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING;
-						break;
-					case NES_AEQE_IWARP_STATE_TERMINATE:
-						must_disconn = 0; /* terminate path takes care of disconn */
-						if (nesqp->term_flags == 0)
-							must_terminate = 1;
-						break;
-				}
-			} else {
-				if (async_event_id ==  NES_AEQE_AEID_LLP_FIN_RECEIVED) {
-					/* FIN Received but ib state not RTS,
-							close complete will be on its way */
-					must_disconn = 0;
-				}
-			}
+			nesqp->hte_added = 0;
 			spin_unlock_irqrestore(&nesqp->lock, flags);
+			next_iwarp_state = NES_CQP_QP_IWARP_STATE_ERROR | NES_CQP_QP_DEL_HTE;
+			nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0, 0);
+			nes_cm_disconn(nesqp);
+			break;
 
-			if (must_terminate)
-				nes_terminate_connection(nesdev, nesqp, aeqe, IB_EVENT_QP_FATAL);
-			else if (must_disconn) {
-				if (next_iwarp_state) {
-					nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u. next state = 0x%08X\n",
-						  nesqp->hwqp.qp_id, next_iwarp_state);
-					nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0, 0);
-				}
-				nes_cm_disconn(nesqp);
-			}
+		case NES_AEQE_AEID_LLP_CONNECTION_RESET:
+			if (atomic_read(&nesqp->close_timer_started))
+				return;
+			spin_lock_irqsave(&nesqp->lock, flags);
+			nesqp->hw_iwarp_state = iwarp_state;
+			nesqp->hw_tcp_state = tcp_state;
+			nesqp->last_aeq = async_event_id;
+			spin_unlock_irqrestore(&nesqp->lock, flags);
+			nes_cm_disconn(nesqp);
 			break;
 
 		case NES_AEQE_AEID_TERMINATE_SENT:
-			nesqp = (struct nes_qp *)(unsigned long)context;
 			nes_terminate_send_fin(nesdev, nesqp, aeqe);
 			break;
 
 		case NES_AEQE_AEID_LLP_TERMINATE_RECEIVED:
-			nesqp = (struct nes_qp *)(unsigned long)context;
 			nes_terminate_received(nesdev, nesqp, aeqe);
 			break;
 
@@ -3480,7 +3522,8 @@ static void nes_process_iwarp_aeqe(struc
 		case NES_AEQE_AEID_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER:
 		case NES_AEQE_AEID_AMP_BOUNDS_VIOLATION:
 		case NES_AEQE_AEID_AMP_TO_WRAP:
-			nesqp = (struct nes_qp *)(unsigned long)context;
+			printk(KERN_ERR PFX "QP[%u] async_event_id=0x%04X IB_EVENT_QP_ACCESS_ERR\n",
+					nesqp->hwqp.qp_id, async_event_id);
 			nes_terminate_connection(nesdev, nesqp, aeqe, IB_EVENT_QP_ACCESS_ERR);
 			break;
 
@@ -3488,7 +3531,6 @@ static void nes_process_iwarp_aeqe(struc
 		case NES_AEQE_AEID_LLP_SEGMENT_TOO_SMALL:
 		case NES_AEQE_AEID_DDP_UBE_INVALID_MO:
 		case NES_AEQE_AEID_DDP_UBE_INVALID_QN:
-			nesqp = (struct nes_qp *)(unsigned long)context;
 			if (iwarp_opcode(nesqp, aeq_info) > IWARP_OPCODE_TERM) {
 				aeq_info &= 0xffff0000;
 				aeq_info |= NES_AEQE_AEID_RDMAP_ROE_UNEXPECTED_OPCODE;
@@ -3530,7 +3572,8 @@ static void nes_process_iwarp_aeqe(struc
 		case NES_AEQE_AEID_STAG_ZERO_INVALID:
 		case NES_AEQE_AEID_ROE_INVALID_RDMA_READ_REQUEST:
 		case NES_AEQE_AEID_ROE_INVALID_RDMA_WRITE_OR_READ_RESP:
-			nesqp = (struct nes_qp *)(unsigned long)context;
+			printk(KERN_ERR PFX "QP[%u] async_event_id=0x%04X IB_EVENT_QP_FATAL\n",
+					nesqp->hwqp.qp_id, async_event_id);
 			nes_terminate_connection(nesdev, nesqp, aeqe, IB_EVENT_QP_FATAL);
 			break;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_hw.h linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes_hw.h
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes_hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -37,12 +37,12 @@
 
 #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_PHY_TYPE_KR	       9
 
 #define NES_MULTICAST_PF_MAX 8
 
@@ -160,6 +160,7 @@ enum indexed_regs {
 	NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_HI = 0x7004,
 	NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_LO = 0x7008,
 	NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_HI = 0x700c,
+	NES_IDX_WQM_CONFIG0 = 0x5000,
 	NES_IDX_WQM_CONFIG1 = 0x5004,
 	NES_IDX_CM_CONFIG = 0x5100,
 	NES_IDX_NIC_LOGPORT_TO_PHYPORT = 0x6000,
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_nic.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes_nic.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_nic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes_nic.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/if_arp.h>
 #include <linux/if_vlan.h>
 #include <linux/ethtool.h>
+#include <linux/slab.h>
 #include <net/tcp.h>
 
 #include <net/inet_common.h>
@@ -810,6 +811,20 @@ static int nes_netdev_set_mac_address(st
 }
 
 
+static void set_allmulti(struct nes_device *nesdev, u32 nic_active_bit)
+{
+	u32 nic_active;
+
+	nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL);
+	nic_active |= nic_active_bit;
+	nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active);
+	nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL);
+	nic_active &= ~nic_active_bit;
+	nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
+}
+
+#define get_addr(addrs, index) ((addrs) + (index) * ETH_ALEN)
+
 /**
  * nes_netdev_set_multicast_list
  */
@@ -818,7 +833,6 @@ static void nes_netdev_set_multicast_lis
 	struct nes_vnic *nesvnic = netdev_priv(netdev);
 	struct nes_device *nesdev = nesvnic->nesdev;
 	struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter;
-	struct dev_mc_list *multicast_addr;
 	u32 nic_active_bit;
 	u32 nic_active;
 	u32 perfect_filter_register_address;
@@ -831,6 +845,7 @@ static void nes_netdev_set_multicast_lis
 					nics_per_function, 4);
 	u8 max_pft_entries_avaiable = NES_PFT_SIZE - pft_entries_preallocated;
 	unsigned long flags;
+	int mc_count = netdev_mc_count(netdev);
 
 	spin_lock_irqsave(&nesadapter->resource_lock, flags);
 	nic_active_bit = 1 << nesvnic->nic_index;
@@ -845,12 +860,7 @@ static void nes_netdev_set_multicast_lis
 		mc_all_on = 1;
 	} else if ((netdev->flags & IFF_ALLMULTI) ||
 			   (nesvnic->nic_index > 3)) {
-		nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL);
-		nic_active |= nic_active_bit;
-		nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active);
-		nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL);
-		nic_active &= ~nic_active_bit;
-		nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
+		set_allmulti(nesdev, nic_active_bit);
 		mc_all_on = 1;
 	} else {
 		nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL);
@@ -862,19 +872,30 @@ static void nes_netdev_set_multicast_lis
 	}
 
 	nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscous = %d, All Multicast = %d.\n",
-		  netdev->mc_count, !!(netdev->flags & IFF_PROMISC),
+		  mc_count, !!(netdev->flags & IFF_PROMISC),
 		  !!(netdev->flags & IFF_ALLMULTI));
 	if (!mc_all_on) {
-		multicast_addr = netdev->mc_list;
+		char *addrs;
+		int i;
+		struct dev_mc_list *mcaddr;
+
+		addrs = kmalloc(ETH_ALEN * mc_count, GFP_ATOMIC);
+		if (!addrs) {
+			set_allmulti(nesdev, nic_active_bit);
+			goto unlock;
+		}
+		i = 0;
+		netdev_for_each_mc_addr(mcaddr, netdev)
+			memcpy(get_addr(addrs, i++),
+			       mcaddr->dmi_addr, ETH_ALEN);
+
 		perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW +
 						pft_entries_preallocated * 0x8;
-		for (mc_index = 0; mc_index < max_pft_entries_avaiable;
-		mc_index++) {
-			while (multicast_addr && nesvnic->mcrq_mcast_filter &&
+		for (i = 0, mc_index = 0; mc_index < max_pft_entries_avaiable;
+		     mc_index++) {
+			while (i < mc_count && nesvnic->mcrq_mcast_filter &&
 			((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic,
-					multicast_addr->dmi_addr)) == 0)) {
-				multicast_addr = multicast_addr->next;
-			}
+					get_addr(addrs, i++))) == 0));
 			if (mc_nic_index < 0)
 				mc_nic_index = nesvnic->nic_index;
 			while (nesadapter->pft_mcast_map[mc_index] < 16 &&
@@ -890,17 +911,19 @@ static void nes_netdev_set_multicast_lis
 			}
 			if (mc_index >= max_pft_entries_avaiable)
 				break;
-			if (multicast_addr) {
+			if (i < mc_count) {
+				char *addr = get_addr(addrs, i++);
+
 				nes_debug(NES_DBG_NIC_RX, "Assigning MC Address %pM to register 0x%04X nic_idx=%d\n",
-					  multicast_addr->dmi_addr,
+					  addr,
 					  perfect_filter_register_address+(mc_index * 8),
 					  mc_nic_index);
-				macaddr_high  = ((u16)multicast_addr->dmi_addr[0]) << 8;
-				macaddr_high += (u16)multicast_addr->dmi_addr[1];
-				macaddr_low   = ((u32)multicast_addr->dmi_addr[2]) << 24;
-				macaddr_low  += ((u32)multicast_addr->dmi_addr[3]) << 16;
-				macaddr_low  += ((u32)multicast_addr->dmi_addr[4]) << 8;
-				macaddr_low  += (u32)multicast_addr->dmi_addr[5];
+				macaddr_high  = ((u16) addr[0]) << 8;
+				macaddr_high += (u16) addr[1];
+				macaddr_low   = ((u32) addr[2]) << 24;
+				macaddr_low  += ((u32) addr[3]) << 16;
+				macaddr_low  += ((u32) addr[4]) << 8;
+				macaddr_low  += (u32) addr[5];
 				nes_write_indexed(nesdev,
 						perfect_filter_register_address+(mc_index * 8),
 						macaddr_low);
@@ -908,7 +931,6 @@ static void nes_netdev_set_multicast_lis
 						perfect_filter_register_address+4+(mc_index * 8),
 						(u32)macaddr_high | NES_MAC_ADDR_VALID |
 						((((u32)(1<<mc_nic_index)) << 16)));
-				multicast_addr = multicast_addr->next;
 				nesadapter->pft_mcast_map[mc_index] =
 							nesvnic->nic_index;
 			} else {
@@ -920,21 +942,13 @@ static void nes_netdev_set_multicast_lis
 				nesadapter->pft_mcast_map[mc_index] = 255;
 			}
 		}
+		kfree(addrs);
 		/* PFT is not large enough */
-		if (multicast_addr && multicast_addr->next) {
-			nic_active = nes_read_indexed(nesdev,
-						NES_IDX_NIC_MULTICAST_ALL);
-			nic_active |= nic_active_bit;
-			nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL,
-								nic_active);
-			nic_active = nes_read_indexed(nesdev,
-						NES_IDX_NIC_UNICAST_ALL);
-			nic_active &= ~nic_active_bit;
-			nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL,
-								nic_active);
-		}
+		if (i < mc_count)
+			set_allmulti(nesdev, nic_active_bit);
 	}
 
+unlock:
 	spin_unlock_irqrestore(&nesadapter->resource_lock, flags);
 }
 
@@ -1230,8 +1244,8 @@ static void nes_netdev_get_ethtool_stats
 	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] = atomic_read(&cm_listens_created);
+	target_stat_values[++index] = atomic_read(&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);
@@ -1461,9 +1475,9 @@ static int nes_netdev_get_settings(struc
 		}
 		return 0;
 	}
-	if ((phy_type == NES_PHY_TYPE_IRIS) ||
-	    (phy_type == NES_PHY_TYPE_ARGUS) ||
-	    (phy_type == NES_PHY_TYPE_SFP_D)) {
+	if ((phy_type == NES_PHY_TYPE_ARGUS) ||
+	    (phy_type == NES_PHY_TYPE_SFP_D) ||
+	    (phy_type == NES_PHY_TYPE_KR)) {
 		et_cmd->transceiver = XCVR_EXTERNAL;
 		et_cmd->port        = PORT_FIBRE;
 		et_cmd->supported   = SUPPORTED_FIBRE;
@@ -1582,9 +1596,7 @@ struct net_device *nes_netdev_init(struc
 	struct nes_vnic *nesvnic;
 	struct net_device *netdev;
 	struct nic_qp_map *curr_qp_map;
-	u32 u32temp;
-	u16 phy_data;
-	u16 temp_phy_data;
+	u8 phy_type = nesdev->nesadapter->phy_type[nesdev->mac_index];
 
 	netdev = alloc_etherdev(sizeof(struct nes_vnic));
 	if (!netdev) {
@@ -1692,66 +1704,51 @@ struct net_device *nes_netdev_init(struc
 
 	if ((nesdev->netdev_count == 0) &&
 	    ((PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index) ||
-	     ((nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) &&
+	     ((phy_type == NES_PHY_TYPE_PUMA_1G) &&
 	      (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) ||
 	       ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) {
-		/*
-		 * nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n",
-		 *		NES_IDX_PHY_PCS_CONTROL_STATUS0 + (0x200 * (nesvnic->logical_port & 1)));
-		 */
+		u32 u32temp;
+		u32 link_mask;
+		u32 link_val;
+
 		u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
 				(0x200 * (nesdev->mac_index & 1)));
-		if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_PUMA_1G) {
+		if (phy_type != NES_PHY_TYPE_PUMA_1G) {
 			u32temp |= 0x00200000;
 			nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
 				(0x200 * (nesdev->mac_index & 1)), u32temp);
 		}
 
-		u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
-				(0x200 * (nesdev->mac_index & 1)));
-
-		if ((u32temp&0x0f1f0000) == 0x0f0f0000) {
-			if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) {
-				nes_init_phy(nesdev);
-				nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1);
-				temp_phy_data = (u16)nes_read_indexed(nesdev,
-									NES_IDX_MAC_MDIO_CONTROL);
-				u32temp = 20;
-				do {
-					nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->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);
-				if (phy_data & 4) {
-					nes_debug(NES_DBG_INIT, "The Link is UP!!.\n");
-					nesvnic->linkup = 1;
-				} else {
-					nes_debug(NES_DBG_INIT, "The Link is DOWN!!.\n");
-				}
+		/* Check and set linkup here.  This is for back to back */
+		/* configuration where second port won't get link interrupt */
+		switch (phy_type) {
+		case NES_PHY_TYPE_PUMA_1G:
+			if (nesdev->mac_index < 2) {
+				link_mask = 0x01010000;
+				link_val = 0x01010000;
 			} else {
-				nes_debug(NES_DBG_INIT, "The Link is UP!!.\n");
-				nesvnic->linkup = 1;
-			}
-		} else if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) {
-			nes_debug(NES_DBG_INIT, "mac_index=%d, logical_port=%d, u32temp=0x%04X, PCI_FUNC=%d\n",
-				nesdev->mac_index, nesvnic->logical_port, u32temp, PCI_FUNC(nesdev->pcidev->devfn));
-			if (((nesdev->mac_index < 2) && ((u32temp&0x01010000) == 0x01010000)) ||
-			    ((nesdev->mac_index > 1) && ((u32temp&0x02020000) == 0x02020000)))  {
-				nes_debug(NES_DBG_INIT, "The Link is UP!!.\n");
-				nesvnic->linkup = 1;
+				link_mask = 0x02020000;
+				link_val = 0x02020000;
 			}
+			break;
+		default:
+			link_mask = 0x0f1f0000;
+			link_val = 0x0f0f0000;
+			break;
 		}
+
+		u32temp = nes_read_indexed(nesdev,
+					   NES_IDX_PHY_PCS_CONTROL_STATUS0 +
+					   (0x200 * (nesdev->mac_index & 1)));
+		if ((u32temp & link_mask) == link_val)
+			nesvnic->linkup = 1;
+
 		/* clear the MAC interrupt status, assumes direct logical to physical mapping */
 		u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index));
 		nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", u32temp);
 		nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index), u32temp);
 
-		if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_IRIS)
-			nes_init_phy(nesdev);
-
+		nes_init_phy(nesdev);
 	}
 
 	return netdev;
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_utils.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes_utils.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_utils.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes_utils.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/if_vlan.h>
+#include <linux/slab.h>
 #include <linux/crc32.h>
 #include <linux/in.h>
 #include <linux/ip.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_verbs.c linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes_verbs.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_verbs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/hw/nes/nes_verbs.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/moduleparam.h>
 #include <linux/random.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 
 #include <rdma/ib_verbs.h>
@@ -228,7 +229,7 @@ static int nes_bind_mw(struct ib_qp *ibq
 	/* Check for SQ overflow */
 	if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) {
 		spin_unlock_irqrestore(&nesqp->lock, flags);
-		return -EINVAL;
+		return -ENOMEM;
 	}
 
 	wqe = &nesqp->hwqp.sq_vbase[head];
@@ -1323,6 +1324,7 @@ static struct ib_qp *nes_create_qp(struc
 			nesqp->nesqp_context->aeq_token_low =  cpu_to_le32((u32)((unsigned long)(nesqp)));
 			nesqp->nesqp_context->aeq_token_high =  cpu_to_le32((u32)(upper_32_bits((unsigned long)(nesqp))));
 			nesqp->nesqp_context->ird_ord_sizes = cpu_to_le32(NES_QPCONTEXT_ORDIRD_ALSMM |
+					NES_QPCONTEXT_ORDIRD_AAH |
 					((((u32)nesadapter->max_irrq_wr) <<
 					NES_QPCONTEXT_ORDIRD_IRDSIZE_SHIFT) & NES_QPCONTEXT_ORDIRD_IRDSIZE_MASK));
 			if (disable_mpa_crc) {
@@ -2819,11 +2821,10 @@ static int nes_query_qp(struct ib_qp *ib
 	attr->cap.max_send_wr = nesqp->hwqp.sq_size;
 	attr->cap.max_recv_wr = nesqp->hwqp.rq_size;
 	attr->cap.max_recv_sge = 1;
-	if (nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) {
-		init_attr->cap.max_inline_data = 0;
-	} else {
-		init_attr->cap.max_inline_data = 64;
-	}
+	if (nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA)
+		attr->cap.max_inline_data = 0;
+	else
+		attr->cap.max_inline_data = 64;
 
 	init_attr->event_handler = nesqp->ibqp.event_handler;
 	init_attr->qp_context = nesqp->ibqp.qp_context;
@@ -3294,7 +3295,7 @@ static int nes_post_send(struct ib_qp *i
 
 		/* Check for SQ overflow */
 		if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) {
-			err = -EINVAL;
+			err = -ENOMEM;
 			break;
 		}
 
@@ -3577,7 +3578,7 @@ static int nes_post_recv(struct ib_qp *i
 		}
 		/* Check for RQ overflow */
 		if (((head + (2 * qsize) - nesqp->hwqp.rq_tail) % qsize) == (qsize - 1)) {
-			err = -EINVAL;
+			err = -ENOMEM;
 			break;
 		}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/Kconfig linux-libre-2.6.34-gnu1/drivers/infiniband/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/infiniband/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@ config INFINIBAND_USER_MAD
 
 config INFINIBAND_USER_ACCESS
 	tristate "InfiniBand userspace access (verbs and CM)"
+	select ANON_INODES
 	---help---
 	  Userspace InfiniBand access support.  This enables the
 	  kernel side of userspace verbs and the userspace
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_cm.c linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/ipoib/ipoib_cm.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <net/icmp.h>
 #include <linux/icmpv6.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "ipoib.h"
@@ -708,6 +709,7 @@ void ipoib_cm_send(struct net_device *de
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct ipoib_cm_tx_buf *tx_req;
 	u64 addr;
+	int rc;
 
 	if (unlikely(skb->len > tx->mtu)) {
 		ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
@@ -739,9 +741,10 @@ void ipoib_cm_send(struct net_device *de
 
 	tx_req->mapping = addr;
 
-	if (unlikely(post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1),
-			       addr, skb->len))) {
-		ipoib_warn(priv, "post_send failed\n");
+	rc = post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1),
+		       addr, skb->len);
+	if (unlikely(rc)) {
+		ipoib_warn(priv, "post_send failed, error %d\n", rc);
 		++dev->stats.tx_errors;
 		ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE);
 		dev_kfree_skb_any(skb);
@@ -752,6 +755,8 @@ void ipoib_cm_send(struct net_device *de
 		if (++priv->tx_outstanding == ipoib_sendq_size) {
 			ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n",
 				  tx->qp->qp_num);
+			if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP))
+				ipoib_warn(priv, "request notify on send CQ failed\n");
 			netif_stop_queue(dev);
 		}
 	}
@@ -1374,7 +1379,7 @@ static void ipoib_cm_skb_reap(struct wor
 			icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 		else if (skb->protocol == htons(ETH_P_IPV6))
-			icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, priv->dev);
+			icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
 #endif
 		dev_kfree_skb_any(skb);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,9 +55,7 @@ static int ipoib_get_coalesce(struct net
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 
 	coal->rx_coalesce_usecs = priv->ethtool.coalesce_usecs;
-	coal->tx_coalesce_usecs = priv->ethtool.coalesce_usecs;
 	coal->rx_max_coalesced_frames = priv->ethtool.max_coalesced_frames;
-	coal->tx_max_coalesced_frames = priv->ethtool.max_coalesced_frames;
 
 	return 0;
 }
@@ -69,10 +67,8 @@ static int ipoib_set_coalesce(struct net
 	int ret;
 
 	/*
-	 * Since IPoIB uses a single CQ for both rx and tx, we assume
-	 * that rx params dictate the configuration.  These values are
-	 * saved in the private data and returned when ipoib_get_coalesce()
-	 * is called.
+	 * These values are saved in the private data and returned
+	 * when ipoib_get_coalesce() is called
 	 */
 	if (coal->rx_coalesce_usecs       > 0xffff ||
 	    coal->rx_max_coalesced_frames > 0xffff)
@@ -85,8 +81,6 @@ static int ipoib_set_coalesce(struct net
 		return ret;
 	}
 
-	coal->tx_coalesce_usecs       = coal->rx_coalesce_usecs;
-	coal->tx_max_coalesced_frames = coal->rx_max_coalesced_frames;
 	priv->ethtool.coalesce_usecs       = coal->rx_coalesce_usecs;
 	priv->ethtool.max_coalesced_frames = coal->rx_max_coalesced_frames;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_fs.c linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/ipoib/ipoib_fs.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_fs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/ipoib/ipoib_fs.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 
 #include <linux/err.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 struct file_operations;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ib.c linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ib.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <linux/ip.h>
 #include <linux/tcp.h>
@@ -529,7 +530,7 @@ void ipoib_send(struct net_device *dev,
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct ipoib_tx_buf *tx_req;
-	int hlen;
+	int hlen, rc;
 	void *phead;
 
 	if (skb_is_gso(skb)) {
@@ -585,9 +586,10 @@ void ipoib_send(struct net_device *dev,
 		netif_stop_queue(dev);
 	}
 
-	if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
-			       address->ah, qpn, tx_req, phead, hlen))) {
-		ipoib_warn(priv, "post_send failed\n");
+	rc = post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
+		       address->ah, qpn, tx_req, phead, hlen);
+	if (unlikely(rc)) {
+		ipoib_warn(priv, "post_send failed, error %d\n", rc);
 		++dev->stats.tx_errors;
 		--priv->tx_outstanding;
 		ipoib_dma_unmap_tx(priv->ca, tx_req);
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_multicast.c linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/inetdevice.h>
 #include <linux/delay.h>
 #include <linux/completion.h>
+#include <linux/slab.h>
 
 #include <net/dst.h>
 
@@ -811,7 +812,7 @@ void ipoib_mcast_restart_task(struct wor
 		clear_bit(IPOIB_MCAST_FLAG_FOUND, &mcast->flags);
 
 	/* Mark all of the entries that are found or don't exist */
-	for (mclist = dev->mc_list; mclist; mclist = mclist->next) {
+	netdev_for_each_mc_addr(mclist, dev) {
 		union ib_gid mgid;
 
 		if (!ipoib_mcast_addr_is_valid(mclist->dmi_addr,
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_verbs.c linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_verbs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/ipoib/ipoib_verbs.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,8 @@
  * SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "ipoib.h"
 
 int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid, int set_qkey)
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_vlan.c linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_vlan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/ipoib/ipoib_vlan.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,6 @@
 #include <linux/module.h>
 
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/seq_file.h>
 
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.c linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.c	2010-05-16 17:17:36.000000000 -0400
@@ -56,6 +56,7 @@
 #include <linux/net.h>
 #include <linux/scatterlist.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <net/sock.h>
 
@@ -128,6 +129,28 @@ static int iscsi_iser_pdu_alloc(struct i
 	return 0;
 }
 
+int iser_initialize_task_headers(struct iscsi_task *task,
+						struct iser_tx_desc *tx_desc)
+{
+	struct iscsi_iser_conn *iser_conn = task->conn->dd_data;
+	struct iser_device     *device    = iser_conn->ib_conn->device;
+	struct iscsi_iser_task *iser_task = task->dd_data;
+	u64 dma_addr;
+
+	dma_addr = ib_dma_map_single(device->ib_device, (void *)tx_desc,
+				ISER_HEADERS_LEN, DMA_TO_DEVICE);
+	if (ib_dma_mapping_error(device->ib_device, dma_addr))
+		return -ENOMEM;
+
+	tx_desc->dma_addr = dma_addr;
+	tx_desc->tx_sg[0].addr   = tx_desc->dma_addr;
+	tx_desc->tx_sg[0].length = ISER_HEADERS_LEN;
+	tx_desc->tx_sg[0].lkey   = device->mr->lkey;
+
+	iser_task->headers_initialized	= 1;
+	iser_task->iser_conn		= iser_conn;
+	return 0;
+}
 /**
  * iscsi_iser_task_init - Initialize task
  * @task: iscsi task
@@ -137,17 +160,17 @@ static int iscsi_iser_pdu_alloc(struct i
 static int
 iscsi_iser_task_init(struct iscsi_task *task)
 {
-	struct iscsi_iser_conn *iser_conn  = task->conn->dd_data;
 	struct iscsi_iser_task *iser_task = task->dd_data;
 
+	if (!iser_task->headers_initialized)
+		if (iser_initialize_task_headers(task, &iser_task->desc))
+			return -ENOMEM;
+
 	/* mgmt task */
-	if (!task->sc) {
-		iser_task->desc.data = task->data;
+	if (!task->sc)
 		return 0;
-	}
 
 	iser_task->command_sent = 0;
-	iser_task->iser_conn    = iser_conn;
 	iser_task_rdma_init(iser_task);
 	return 0;
 }
@@ -168,7 +191,7 @@ iscsi_iser_mtask_xmit(struct iscsi_conn
 {
 	int error = 0;
 
-	iser_dbg("task deq [cid %d itt 0x%x]\n", conn->id, task->itt);
+	iser_dbg("mtask xmit [cid %d itt 0x%x]\n", conn->id, task->itt);
 
 	error = iser_send_control(conn, task);
 
@@ -178,9 +201,6 @@ iscsi_iser_mtask_xmit(struct iscsi_conn
 	 * - if yes, the task is recycled at iscsi_complete_pdu
 	 * - if no,  the task is recycled at iser_snd_completion
 	 */
-	if (error && error != -ENOBUFS)
-		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
-
 	return error;
 }
 
@@ -232,7 +252,7 @@ iscsi_iser_task_xmit(struct iscsi_task *
 			   task->imm_count, task->unsol_r2t.data_length);
 	}
 
-	iser_dbg("task deq [cid %d itt 0x%x]\n",
+	iser_dbg("ctask xmit [cid %d itt 0x%x]\n",
 		   conn->id, task->itt);
 
 	/* Send the cmd PDU */
@@ -248,8 +268,6 @@ iscsi_iser_task_xmit(struct iscsi_task *
 		error = iscsi_iser_task_xmit_unsol_data(conn, task);
 
  iscsi_iser_task_xmit_exit:
-	if (error && error != -ENOBUFS)
-		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
 	return error;
 }
 
@@ -283,7 +301,7 @@ iscsi_iser_conn_create(struct iscsi_cls_
 	 * due to issues with the login code re iser sematics
 	 * this not set in iscsi_conn_setup - FIXME
 	 */
-	conn->max_recv_dlength = 128;
+	conn->max_recv_dlength = ISER_RECV_DATA_SEG_LEN;
 
 	iser_conn = conn->dd_data;
 	conn->dd_data = iser_conn;
@@ -401,7 +419,7 @@ iscsi_iser_session_create(struct iscsi_e
 	struct Scsi_Host *shost;
 	struct iser_conn *ib_conn;
 
-	shost = iscsi_host_alloc(&iscsi_iser_sht, 0, 1);
+	shost = iscsi_host_alloc(&iscsi_iser_sht, 0, 0);
 	if (!shost)
 		return NULL;
 	shost->transportt = iscsi_iser_scsi_transport;
@@ -596,7 +614,7 @@ static struct scsi_host_template iscsi_i
 	.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,
+	.eh_target_reset_handler = iscsi_eh_recover_target,
 	.target_alloc		= iscsi_target_alloc,
 	.use_clustering         = DISABLE_CLUSTERING,
 	.proc_name              = "iscsi_iser",
@@ -675,7 +693,7 @@ static int __init iser_init(void)
 	memset(&ig, 0, sizeof(struct iser_global));
 
 	ig.desc_cache = kmem_cache_create("iser_descriptors",
-					  sizeof (struct iser_desc),
+					  sizeof(struct iser_tx_desc),
 					  0, SLAB_HWCACHE_ALIGN,
 					  NULL);
 	if (ig.desc_cache == NULL)
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.h linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.h
--- linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.h	2010-05-16 17:17:36.000000000 -0400
@@ -102,9 +102,9 @@
 #define ISER_MAX_TX_MISC_PDUS		6 /* NOOP_OUT(2), TEXT(1),         *
 					   * SCSI_TMFUNC(2), LOGOUT(1) */
 
-#define ISER_QP_MAX_RECV_DTOS		(ISCSI_DEF_XMIT_CMDS_MAX + \
-					ISER_MAX_RX_MISC_PDUS    +  \
-					ISER_MAX_TX_MISC_PDUS)
+#define ISER_QP_MAX_RECV_DTOS		(ISCSI_DEF_XMIT_CMDS_MAX)
+
+#define ISER_MIN_POSTED_RX		(ISCSI_DEF_XMIT_CMDS_MAX >> 2)
 
 /* the max TX (send) WR supported by the iSER QP is defined by                 *
  * max_send_wr = T * (1 + D) + C ; D is how many inflight dataouts we expect   *
@@ -132,6 +132,12 @@ struct iser_hdr {
 	__be64  read_va;
 } __attribute__((packed));
 
+/* Constant PDU lengths calculations */
+#define ISER_HEADERS_LEN  (sizeof(struct iser_hdr) + sizeof(struct iscsi_hdr))
+
+#define ISER_RECV_DATA_SEG_LEN	128
+#define ISER_RX_PAYLOAD_SIZE	(ISER_HEADERS_LEN + ISER_RECV_DATA_SEG_LEN)
+#define ISER_RX_LOGIN_SIZE	(ISER_HEADERS_LEN + ISCSI_DEF_MAX_RECV_SEG_LEN)
 
 /* Length of an object name string */
 #define ISER_OBJECT_NAME_SIZE		    64
@@ -187,51 +193,43 @@ struct iser_regd_buf {
 	struct iser_mem_reg     reg;        /* memory registration info        */
 	void                    *virt_addr;
 	struct iser_device      *device;    /* device->device for dma_unmap    */
-	u64                     dma_addr;   /* if non zero, addr for dma_unmap */
 	enum dma_data_direction direction;  /* direction for dma_unmap	       */
 	unsigned int            data_size;
-	atomic_t                ref_count;  /* refcount, freed when dec to 0   */
-};
-
-#define MAX_REGD_BUF_VECTOR_LEN	2
-
-struct iser_dto {
-	struct iscsi_iser_task *task;
-	struct iser_conn *ib_conn;
-	int                        notify_enable;
-
-	/* vector of registered buffers */
-	unsigned int               regd_vector_len;
-	struct iser_regd_buf       *regd[MAX_REGD_BUF_VECTOR_LEN];
-
-	/* offset into the registered buffer may be specified */
-	unsigned int               offset[MAX_REGD_BUF_VECTOR_LEN];
-
-	/* a smaller size may be specified, if 0, then full size is used */
-	unsigned int               used_sz[MAX_REGD_BUF_VECTOR_LEN];
 };
 
 enum iser_desc_type {
-	ISCSI_RX,
 	ISCSI_TX_CONTROL ,
 	ISCSI_TX_SCSI_COMMAND,
 	ISCSI_TX_DATAOUT
 };
 
-struct iser_desc {
+struct iser_tx_desc {
 	struct iser_hdr              iser_header;
 	struct iscsi_hdr             iscsi_header;
-	struct iser_regd_buf         hdr_regd_buf;
-	void                         *data;         /* used by RX & TX_CONTROL */
-	struct iser_regd_buf         data_regd_buf; /* used by RX & TX_CONTROL */
 	enum   iser_desc_type        type;
-	struct iser_dto              dto;
+	u64		             dma_addr;
+	/* sg[0] points to iser/iscsi headers, sg[1] optionally points to either
+	of immediate data, unsolicited data-out or control (login,text) */
+	struct ib_sge		     tx_sg[2];
+	int                          num_sge;
 };
 
+#define ISER_RX_PAD_SIZE	(256 - (ISER_RX_PAYLOAD_SIZE + \
+					sizeof(u64) + sizeof(struct ib_sge)))
+struct iser_rx_desc {
+	struct iser_hdr              iser_header;
+	struct iscsi_hdr             iscsi_header;
+	char		             data[ISER_RECV_DATA_SEG_LEN];
+	u64		             dma_addr;
+	struct ib_sge		     rx_sg;
+	char		             pad[ISER_RX_PAD_SIZE];
+} __attribute__((packed));
+
 struct iser_device {
 	struct ib_device             *ib_device;
 	struct ib_pd	             *pd;
-	struct ib_cq	             *cq;
+	struct ib_cq	             *rx_cq;
+	struct ib_cq	             *tx_cq;
 	struct ib_mr	             *mr;
 	struct tasklet_struct	     cq_tasklet;
 	struct list_head             ig_list; /* entry in ig devices list */
@@ -250,15 +248,18 @@ struct iser_conn {
 	struct ib_fmr_pool           *fmr_pool;     /* pool of IB FMRs         */
 	int                          disc_evt_flag; /* disconn event delivered */
 	wait_queue_head_t	     wait;          /* waitq for conn/disconn  */
-	atomic_t                     post_recv_buf_count; /* posted rx count   */
+	int                          post_recv_buf_count; /* posted rx count  */
 	atomic_t                     post_send_buf_count; /* posted tx count   */
-	atomic_t                     unexpected_pdu_count;/* count of received *
-							   * unexpected pdus   *
-							   * not yet retired   */
 	char 			     name[ISER_OBJECT_NAME_SIZE];
 	struct iser_page_vec         *page_vec;     /* represents SG to fmr maps*
 						     * maps serialized as tx is*/
 	struct list_head	     conn_list;       /* entry in ig conn list */
+
+	char  			     *login_buf;
+	u64 			     login_dma;
+	unsigned int 		     rx_desc_head;
+	struct iser_rx_desc	     *rx_descs;
+	struct ib_recv_wr	     rx_wr[ISER_MIN_POSTED_RX];
 };
 
 struct iscsi_iser_conn {
@@ -267,7 +268,7 @@ struct iscsi_iser_conn {
 };
 
 struct iscsi_iser_task {
-	struct iser_desc             desc;
+	struct iser_tx_desc          desc;
 	struct iscsi_iser_conn	     *iser_conn;
 	enum iser_task_status 	     status;
 	int                          command_sent;  /* set if command  sent  */
@@ -275,6 +276,7 @@ struct iscsi_iser_task {
 	struct iser_regd_buf         rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */
 	struct iser_data_buf         data[ISER_DIRS_NUM];     /* orig. data des*/
 	struct iser_data_buf         data_copy[ISER_DIRS_NUM];/* contig. copy  */
+	int                          headers_initialized;
 };
 
 struct iser_page_vec {
@@ -322,22 +324,17 @@ void iser_conn_put(struct iser_conn *ib_
 
 void iser_conn_terminate(struct iser_conn *ib_conn);
 
-void iser_rcv_completion(struct iser_desc *desc,
-			 unsigned long    dto_xfer_len);
+void iser_rcv_completion(struct iser_rx_desc *desc,
+			 unsigned long    dto_xfer_len,
+			struct iser_conn *ib_conn);
 
-void iser_snd_completion(struct iser_desc *desc);
+void iser_snd_completion(struct iser_tx_desc *desc, struct iser_conn *ib_conn);
 
 void iser_task_rdma_init(struct iscsi_iser_task *task);
 
 void iser_task_rdma_finalize(struct iscsi_iser_task *task);
 
-void iser_dto_buffs_release(struct iser_dto *dto);
-
-int  iser_regd_buff_release(struct iser_regd_buf *regd_buf);
-
-void iser_reg_single(struct iser_device      *device,
-		     struct iser_regd_buf    *regd_buf,
-		     enum dma_data_direction direction);
+void iser_free_rx_descriptors(struct iser_conn *ib_conn);
 
 void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *task,
 				     enum iser_data_dir         cmd_dir);
@@ -356,11 +353,9 @@ int  iser_reg_page_vec(struct iser_conn
 
 void iser_unreg_mem(struct iser_mem_reg *mem_reg);
 
-int  iser_post_recv(struct iser_desc *rx_desc);
-int  iser_post_send(struct iser_desc *tx_desc);
-
-int iser_conn_state_comp(struct iser_conn *ib_conn,
-			 enum iser_ib_conn_state comp);
+int  iser_post_recvl(struct iser_conn *ib_conn);
+int  iser_post_recvm(struct iser_conn *ib_conn, int count);
+int  iser_post_send(struct iser_conn *ib_conn, struct iser_tx_desc *tx_desc);
 
 int iser_dma_map_task_data(struct iscsi_iser_task *iser_task,
 			    struct iser_data_buf       *data,
@@ -368,4 +363,6 @@ int iser_dma_map_task_data(struct iscsi_
 			    enum   dma_data_direction  dma_dir);
 
 void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task);
+int  iser_initialize_task_headers(struct iscsi_task *task,
+			struct iser_tx_desc *tx_desc);
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iser_initiator.c linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/iser/iser_initiator.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iser_initiator.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/iser/iser_initiator.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,29 +39,6 @@
 
 #include "iscsi_iser.h"
 
-/* Constant PDU lengths calculations */
-#define ISER_TOTAL_HEADERS_LEN  (sizeof (struct iser_hdr) + \
-				 sizeof (struct iscsi_hdr))
-
-/* iser_dto_add_regd_buff - increments the reference count for *
- * the registered buffer & adds it to the DTO object           */
-static void iser_dto_add_regd_buff(struct iser_dto *dto,
-				   struct iser_regd_buf *regd_buf,
-				   unsigned long use_offset,
-				   unsigned long use_size)
-{
-	int add_idx;
-
-	atomic_inc(&regd_buf->ref_count);
-
-	add_idx = dto->regd_vector_len;
-	dto->regd[add_idx] = regd_buf;
-	dto->used_sz[add_idx] = use_size;
-	dto->offset[add_idx] = use_offset;
-
-	dto->regd_vector_len++;
-}
-
 /* Register user buffer memory and initialize passive rdma
  *  dto descriptor. Total data size is stored in
  *  iser_task->data[ISER_DIR_IN].data_len
@@ -122,9 +99,9 @@ iser_prepare_write_cmd(struct iscsi_task
 	struct iscsi_iser_task *iser_task = task->dd_data;
 	struct iser_regd_buf *regd_buf;
 	int err;
-	struct iser_dto *send_dto = &iser_task->desc.dto;
 	struct iser_hdr *hdr = &iser_task->desc.iser_header;
 	struct iser_data_buf *buf_out = &iser_task->data[ISER_DIR_OUT];
+	struct ib_sge *tx_dsg = &iser_task->desc.tx_sg[1];
 
 	err = iser_dma_map_task_data(iser_task,
 				     buf_out,
@@ -163,135 +140,100 @@ iser_prepare_write_cmd(struct iscsi_task
 	if (imm_sz > 0) {
 		iser_dbg("Cmd itt:%d, WRITE, adding imm.data sz: %d\n",
 			 task->itt, imm_sz);
-		iser_dto_add_regd_buff(send_dto,
-				       regd_buf,
-				       0,
-				       imm_sz);
+		tx_dsg->addr   = regd_buf->reg.va;
+		tx_dsg->length = imm_sz;
+		tx_dsg->lkey   = regd_buf->reg.lkey;
+		iser_task->desc.num_sge = 2;
 	}
 
 	return 0;
 }
 
-/**
- * iser_post_receive_control - allocates, initializes and posts receive DTO.
- */
-static int iser_post_receive_control(struct iscsi_conn *conn)
+/* creates a new tx descriptor and adds header regd buffer */
+static void iser_create_send_desc(struct iser_conn	*ib_conn,
+				  struct iser_tx_desc	*tx_desc)
 {
-	struct iscsi_iser_conn *iser_conn = conn->dd_data;
-	struct iser_desc     *rx_desc;
-	struct iser_regd_buf *regd_hdr;
-	struct iser_regd_buf *regd_data;
-	struct iser_dto      *recv_dto = NULL;
-	struct iser_device  *device = iser_conn->ib_conn->device;
-	int rx_data_size, err;
-	int posts, outstanding_unexp_pdus;
+	struct iser_device *device = ib_conn->device;
 
-	/* for the login sequence we must support rx of upto 8K; login is done
-	 * after conn create/bind (connect) and conn stop/bind (reconnect),
-	 * what's common for both schemes is that the connection is not started
-	 */
-	if (conn->c_stage != ISCSI_CONN_STARTED)
-		rx_data_size = ISCSI_DEF_MAX_RECV_SEG_LEN;
-	else /* FIXME till user space sets conn->max_recv_dlength correctly */
-		rx_data_size = 128;
+	ib_dma_sync_single_for_cpu(device->ib_device,
+		tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE);
 
-	outstanding_unexp_pdus =
-		atomic_xchg(&iser_conn->ib_conn->unexpected_pdu_count, 0);
+	memset(&tx_desc->iser_header, 0, sizeof(struct iser_hdr));
+	tx_desc->iser_header.flags = ISER_VER;
 
-	/*
-	 * in addition to the response buffer, replace those consumed by
-	 * unexpected pdus.
-	 */
-	for (posts = 0; posts < 1 + outstanding_unexp_pdus; posts++) {
-		rx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO);
-		if (rx_desc == NULL) {
-			iser_err("Failed to alloc desc for post recv %d\n",
-				 posts);
-			err = -ENOMEM;
-			goto post_rx_cache_alloc_failure;
-		}
-		rx_desc->type = ISCSI_RX;
-		rx_desc->data = kmalloc(rx_data_size, GFP_NOIO);
-		if (rx_desc->data == NULL) {
-			iser_err("Failed to alloc data buf for post recv %d\n",
-				 posts);
-			err = -ENOMEM;
-			goto post_rx_kmalloc_failure;
-		}
+	tx_desc->num_sge = 1;
 
-		recv_dto = &rx_desc->dto;
-		recv_dto->ib_conn = iser_conn->ib_conn;
-		recv_dto->regd_vector_len = 0;
+	if (tx_desc->tx_sg[0].lkey != device->mr->lkey) {
+		tx_desc->tx_sg[0].lkey = device->mr->lkey;
+		iser_dbg("sdesc %p lkey mismatch, fixing\n", tx_desc);
+	}
+}
 
-		regd_hdr = &rx_desc->hdr_regd_buf;
-		memset(regd_hdr, 0, sizeof(struct iser_regd_buf));
-		regd_hdr->device  = device;
-		regd_hdr->virt_addr  = rx_desc; /* == &rx_desc->iser_header */
-		regd_hdr->data_size  = ISER_TOTAL_HEADERS_LEN;
 
-		iser_reg_single(device, regd_hdr, DMA_FROM_DEVICE);
+int iser_alloc_rx_descriptors(struct iser_conn *ib_conn)
+{
+	int i, j;
+	u64 dma_addr;
+	struct iser_rx_desc *rx_desc;
+	struct ib_sge       *rx_sg;
+	struct iser_device  *device = ib_conn->device;
 
-		iser_dto_add_regd_buff(recv_dto, regd_hdr, 0, 0);
+	ib_conn->rx_descs = kmalloc(ISER_QP_MAX_RECV_DTOS *
+				sizeof(struct iser_rx_desc), GFP_KERNEL);
+	if (!ib_conn->rx_descs)
+		goto rx_desc_alloc_fail;
 
-		regd_data = &rx_desc->data_regd_buf;
-		memset(regd_data, 0, sizeof(struct iser_regd_buf));
-		regd_data->device  = device;
-		regd_data->virt_addr  = rx_desc->data;
-		regd_data->data_size  = rx_data_size;
+	rx_desc = ib_conn->rx_descs;
 
-		iser_reg_single(device, regd_data, DMA_FROM_DEVICE);
+	for (i = 0; i < ISER_QP_MAX_RECV_DTOS; i++, rx_desc++)  {
+		dma_addr = ib_dma_map_single(device->ib_device, (void *)rx_desc,
+					ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
+		if (ib_dma_mapping_error(device->ib_device, dma_addr))
+			goto rx_desc_dma_map_failed;
 
-		iser_dto_add_regd_buff(recv_dto, regd_data, 0, 0);
+		rx_desc->dma_addr = dma_addr;
 
-		err = iser_post_recv(rx_desc);
-		if (err) {
-			iser_err("Failed iser_post_recv for post %d\n", posts);
-			goto post_rx_post_recv_failure;
-		}
+		rx_sg = &rx_desc->rx_sg;
+		rx_sg->addr   = rx_desc->dma_addr;
+		rx_sg->length = ISER_RX_PAYLOAD_SIZE;
+		rx_sg->lkey   = device->mr->lkey;
 	}
-	/* all posts successful */
-	return 0;
 
-post_rx_post_recv_failure:
-	iser_dto_buffs_release(recv_dto);
-	kfree(rx_desc->data);
-post_rx_kmalloc_failure:
-	kmem_cache_free(ig.desc_cache, rx_desc);
-post_rx_cache_alloc_failure:
-	if (posts > 0) {
-		/*
-		 * response buffer posted, but did not replace all unexpected
-		 * pdu recv bufs. Ignore error, retry occurs next send
-		 */
-		outstanding_unexp_pdus -= (posts - 1);
-		err = 0;
-	}
-	atomic_add(outstanding_unexp_pdus,
-		   &iser_conn->ib_conn->unexpected_pdu_count);
+	ib_conn->rx_desc_head = 0;
+	return 0;
 
-	return err;
+rx_desc_dma_map_failed:
+	rx_desc = ib_conn->rx_descs;
+	for (j = 0; j < i; j++, rx_desc++)
+		ib_dma_unmap_single(device->ib_device, rx_desc->dma_addr,
+			ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
+	kfree(ib_conn->rx_descs);
+	ib_conn->rx_descs = NULL;
+rx_desc_alloc_fail:
+	iser_err("failed allocating rx descriptors / data buffers\n");
+	return -ENOMEM;
 }
 
-/* creates a new tx descriptor and adds header regd buffer */
-static void iser_create_send_desc(struct iscsi_iser_conn *iser_conn,
-				  struct iser_desc       *tx_desc)
+void iser_free_rx_descriptors(struct iser_conn *ib_conn)
 {
-	struct iser_regd_buf *regd_hdr = &tx_desc->hdr_regd_buf;
-	struct iser_dto      *send_dto = &tx_desc->dto;
-
-	memset(regd_hdr, 0, sizeof(struct iser_regd_buf));
-	regd_hdr->device  = iser_conn->ib_conn->device;
-	regd_hdr->virt_addr  = tx_desc; /* == &tx_desc->iser_header */
-	regd_hdr->data_size  = ISER_TOTAL_HEADERS_LEN;
+	int i;
+	struct iser_rx_desc *rx_desc;
+	struct iser_device *device = ib_conn->device;
 
-	send_dto->ib_conn         = iser_conn->ib_conn;
-	send_dto->notify_enable   = 1;
-	send_dto->regd_vector_len = 0;
+	if (ib_conn->login_buf) {
+		ib_dma_unmap_single(device->ib_device, ib_conn->login_dma,
+			ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE);
+		kfree(ib_conn->login_buf);
+	}
 
-	memset(&tx_desc->iser_header, 0, sizeof(struct iser_hdr));
-	tx_desc->iser_header.flags = ISER_VER;
+	if (!ib_conn->rx_descs)
+		return;
 
-	iser_dto_add_regd_buff(send_dto, regd_hdr, 0, 0);
+	rx_desc = ib_conn->rx_descs;
+	for (i = 0; i < ISER_QP_MAX_RECV_DTOS; i++, rx_desc++)
+		ib_dma_unmap_single(device->ib_device, rx_desc->dma_addr,
+			ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
+	kfree(ib_conn->rx_descs);
 }
 
 /**
@@ -301,46 +243,23 @@ int iser_conn_set_full_featured_mode(str
 {
 	struct iscsi_iser_conn *iser_conn = conn->dd_data;
 
-	int i;
-	/*
-	 * FIXME this value should be declared to the target during login with
-	 * the MaxOutstandingUnexpectedPDUs key when supported
-	 */
-	int initial_post_recv_bufs_num = ISER_MAX_RX_MISC_PDUS;
-
-	iser_dbg("Initially post: %d\n", initial_post_recv_bufs_num);
+	iser_dbg("Initially post: %d\n", ISER_MIN_POSTED_RX);
 
 	/* Check that there is no posted recv or send buffers left - */
 	/* they must be consumed during the login phase */
-	BUG_ON(atomic_read(&iser_conn->ib_conn->post_recv_buf_count) != 0);
+	BUG_ON(iser_conn->ib_conn->post_recv_buf_count != 0);
 	BUG_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0);
 
-	/* Initial post receive buffers */
-	for (i = 0; i < initial_post_recv_bufs_num; i++) {
-		if (iser_post_receive_control(conn) != 0) {
-			iser_err("Failed to post recv bufs at:%d conn:0x%p\n",
-				 i, conn);
-			return -ENOMEM;
-		}
-	}
-	iser_dbg("Posted %d post recv bufs, conn:0x%p\n", i, conn);
-	return 0;
-}
+	if (iser_alloc_rx_descriptors(iser_conn->ib_conn))
+		return -ENOMEM;
 
-static int
-iser_check_xmit(struct iscsi_conn *conn, void *task)
-{
-	struct iscsi_iser_conn *iser_conn = conn->dd_data;
+	/* Initial post receive buffers */
+	if (iser_post_recvm(iser_conn->ib_conn, ISER_MIN_POSTED_RX))
+		return -ENOMEM;
 
-	if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
-	    ISER_QP_MAX_REQ_DTOS) {
-		iser_dbg("%ld can't xmit task %p\n",jiffies,task);
-		return -ENOBUFS;
-	}
 	return 0;
 }
 
-
 /**
  * iser_send_command - send command PDU
  */
@@ -349,27 +268,18 @@ int iser_send_command(struct iscsi_conn
 {
 	struct iscsi_iser_conn *iser_conn = conn->dd_data;
 	struct iscsi_iser_task *iser_task = task->dd_data;
-	struct iser_dto *send_dto = NULL;
 	unsigned long edtl;
-	int err = 0;
+	int err;
 	struct iser_data_buf *data_buf;
 	struct iscsi_cmd *hdr =  (struct iscsi_cmd *)task->hdr;
 	struct scsi_cmnd *sc  =  task->sc;
-
-	if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
-		iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
-		return -EPERM;
-	}
-	if (iser_check_xmit(conn, task))
-		return -ENOBUFS;
+	struct iser_tx_desc *tx_desc = &iser_task->desc;
 
 	edtl = ntohl(hdr->data_length);
 
 	/* build the tx desc regd header and add it to the tx desc dto */
-	iser_task->desc.type = ISCSI_TX_SCSI_COMMAND;
-	send_dto = &iser_task->desc.dto;
-	send_dto->task = iser_task;
-	iser_create_send_desc(iser_conn, &iser_task->desc);
+	tx_desc->type = ISCSI_TX_SCSI_COMMAND;
+	iser_create_send_desc(iser_conn->ib_conn, tx_desc);
 
 	if (hdr->flags & ISCSI_FLAG_CMD_READ)
 		data_buf = &iser_task->data[ISER_DIR_IN];
@@ -398,23 +308,13 @@ int iser_send_command(struct iscsi_conn
 			goto send_command_error;
 	}
 
-	iser_reg_single(iser_conn->ib_conn->device,
-			send_dto->regd[0], DMA_TO_DEVICE);
-
-	if (iser_post_receive_control(conn) != 0) {
-		iser_err("post_recv failed!\n");
-		err = -ENOMEM;
-		goto send_command_error;
-	}
-
 	iser_task->status = ISER_TASK_STATUS_STARTED;
 
-	err = iser_post_send(&iser_task->desc);
+	err = iser_post_send(iser_conn->ib_conn, tx_desc);
 	if (!err)
 		return 0;
 
 send_command_error:
-	iser_dto_buffs_release(send_dto);
 	iser_err("conn %p failed task->itt %d err %d\n",conn, task->itt, err);
 	return err;
 }
@@ -428,20 +328,13 @@ int iser_send_data_out(struct iscsi_conn
 {
 	struct iscsi_iser_conn *iser_conn = conn->dd_data;
 	struct iscsi_iser_task *iser_task = task->dd_data;
-	struct iser_desc *tx_desc = NULL;
-	struct iser_dto *send_dto = NULL;
+	struct iser_tx_desc *tx_desc = NULL;
+	struct iser_regd_buf *regd_buf;
 	unsigned long buf_offset;
 	unsigned long data_seg_len;
 	uint32_t itt;
 	int err = 0;
-
-	if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
-		iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
-		return -EPERM;
-	}
-
-	if (iser_check_xmit(conn, task))
-		return -ENOBUFS;
+	struct ib_sge *tx_dsg;
 
 	itt = (__force uint32_t)hdr->itt;
 	data_seg_len = ntoh24(hdr->dlength);
@@ -450,28 +343,25 @@ int iser_send_data_out(struct iscsi_conn
 	iser_dbg("%s itt %d dseg_len %d offset %d\n",
 		 __func__,(int)itt,(int)data_seg_len,(int)buf_offset);
 
-	tx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO);
+	tx_desc = kmem_cache_zalloc(ig.desc_cache, GFP_ATOMIC);
 	if (tx_desc == NULL) {
 		iser_err("Failed to alloc desc for post dataout\n");
 		return -ENOMEM;
 	}
 
 	tx_desc->type = ISCSI_TX_DATAOUT;
+	tx_desc->iser_header.flags = ISER_VER;
 	memcpy(&tx_desc->iscsi_header, hdr, sizeof(struct iscsi_hdr));
 
-	/* build the tx desc regd header and add it to the tx desc dto */
-	send_dto = &tx_desc->dto;
-	send_dto->task = iser_task;
-	iser_create_send_desc(iser_conn, tx_desc);
-
-	iser_reg_single(iser_conn->ib_conn->device,
-			send_dto->regd[0], DMA_TO_DEVICE);
+	/* build the tx desc */
+	iser_initialize_task_headers(task, tx_desc);
 
-	/* all data was registered for RDMA, we can use the lkey */
-	iser_dto_add_regd_buff(send_dto,
-			       &iser_task->rdma_regd[ISER_DIR_OUT],
-			       buf_offset,
-			       data_seg_len);
+	regd_buf = &iser_task->rdma_regd[ISER_DIR_OUT];
+	tx_dsg = &tx_desc->tx_sg[1];
+	tx_dsg->addr    = regd_buf->reg.va + buf_offset;
+	tx_dsg->length  = data_seg_len;
+	tx_dsg->lkey    = regd_buf->reg.lkey;
+	tx_desc->num_sge = 2;
 
 	if (buf_offset + data_seg_len > iser_task->data[ISER_DIR_OUT].data_len) {
 		iser_err("Offset:%ld & DSL:%ld in Data-Out "
@@ -485,12 +375,11 @@ int iser_send_data_out(struct iscsi_conn
 		 itt, buf_offset, data_seg_len);
 
 
-	err = iser_post_send(tx_desc);
+	err = iser_post_send(iser_conn->ib_conn, tx_desc);
 	if (!err)
 		return 0;
 
 send_data_out_error:
-	iser_dto_buffs_release(send_dto);
 	kmem_cache_free(ig.desc_cache, tx_desc);
 	iser_err("conn %p failed err %d\n",conn, err);
 	return err;
@@ -501,64 +390,44 @@ int iser_send_control(struct iscsi_conn
 {
 	struct iscsi_iser_conn *iser_conn = conn->dd_data;
 	struct iscsi_iser_task *iser_task = task->dd_data;
-	struct iser_desc *mdesc = &iser_task->desc;
-	struct iser_dto *send_dto = NULL;
+	struct iser_tx_desc *mdesc = &iser_task->desc;
 	unsigned long data_seg_len;
 	int err = 0;
-	struct iser_regd_buf *regd_buf;
 	struct iser_device *device;
-	unsigned char opcode;
-
-	if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
-		iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
-		return -EPERM;
-	}
-
-	if (iser_check_xmit(conn, task))
-		return -ENOBUFS;
 
 	/* build the tx desc regd header and add it to the tx desc dto */
 	mdesc->type = ISCSI_TX_CONTROL;
-	send_dto = &mdesc->dto;
-	send_dto->task = NULL;
-	iser_create_send_desc(iser_conn, mdesc);
+	iser_create_send_desc(iser_conn->ib_conn, mdesc);
 
 	device = iser_conn->ib_conn->device;
 
-	iser_reg_single(device, send_dto->regd[0], DMA_TO_DEVICE);
-
 	data_seg_len = ntoh24(task->hdr->dlength);
 
 	if (data_seg_len > 0) {
-		regd_buf = &mdesc->data_regd_buf;
-		memset(regd_buf, 0, sizeof(struct iser_regd_buf));
-		regd_buf->device = device;
-		regd_buf->virt_addr = task->data;
-		regd_buf->data_size = task->data_count;
-		iser_reg_single(device, regd_buf,
-				DMA_TO_DEVICE);
-		iser_dto_add_regd_buff(send_dto, regd_buf,
-				       0,
-				       data_seg_len);
+		struct ib_sge *tx_dsg = &mdesc->tx_sg[1];
+		if (task != conn->login_task) {
+			iser_err("data present on non login task!!!\n");
+			goto send_control_error;
+		}
+		memcpy(iser_conn->ib_conn->login_buf, task->data,
+							task->data_count);
+		tx_dsg->addr    = iser_conn->ib_conn->login_dma;
+		tx_dsg->length  = data_seg_len;
+		tx_dsg->lkey    = device->mr->lkey;
+		mdesc->num_sge = 2;
 	}
 
-	opcode = task->hdr->opcode & ISCSI_OPCODE_MASK;
-
-	/* post recv buffer for response if one is expected */
-	if (!(opcode == ISCSI_OP_NOOP_OUT && task->hdr->itt == RESERVED_ITT)) {
-		if (iser_post_receive_control(conn) != 0) {
-			iser_err("post_rcv_buff failed!\n");
-			err = -ENOMEM;
+	if (task == conn->login_task) {
+		err = iser_post_recvl(iser_conn->ib_conn);
+		if (err)
 			goto send_control_error;
-		}
 	}
 
-	err = iser_post_send(mdesc);
+	err = iser_post_send(iser_conn->ib_conn, mdesc);
 	if (!err)
 		return 0;
 
 send_control_error:
-	iser_dto_buffs_release(send_dto);
 	iser_err("conn %p failed err %d\n",conn, err);
 	return err;
 }
@@ -566,104 +435,71 @@ send_control_error:
 /**
  * iser_rcv_dto_completion - recv DTO completion
  */
-void iser_rcv_completion(struct iser_desc *rx_desc,
-			 unsigned long dto_xfer_len)
+void iser_rcv_completion(struct iser_rx_desc *rx_desc,
+			 unsigned long rx_xfer_len,
+			 struct iser_conn *ib_conn)
 {
-	struct iser_dto *dto = &rx_desc->dto;
-	struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn;
-	struct iscsi_task *task;
-	struct iscsi_iser_task *iser_task;
+	struct iscsi_iser_conn *conn = ib_conn->iser_conn;
 	struct iscsi_hdr *hdr;
-	char   *rx_data = NULL;
-	int     rx_data_len = 0;
-	unsigned char opcode;
-
-	hdr = &rx_desc->iscsi_header;
-
-	iser_dbg("op 0x%x itt 0x%x\n", hdr->opcode,hdr->itt);
+	u64 rx_dma;
+	int rx_buflen, outstanding, count, err;
 
-	if (dto_xfer_len > ISER_TOTAL_HEADERS_LEN) { /* we have data */
-		rx_data_len = dto_xfer_len - ISER_TOTAL_HEADERS_LEN;
-		rx_data     = dto->regd[1]->virt_addr;
-		rx_data    += dto->offset[1];
+	/* differentiate between login to all other PDUs */
+	if ((char *)rx_desc == ib_conn->login_buf) {
+		rx_dma = ib_conn->login_dma;
+		rx_buflen = ISER_RX_LOGIN_SIZE;
+	} else {
+		rx_dma = rx_desc->dma_addr;
+		rx_buflen = ISER_RX_PAYLOAD_SIZE;
 	}
 
-	opcode = hdr->opcode & ISCSI_OPCODE_MASK;
+	ib_dma_sync_single_for_cpu(ib_conn->device->ib_device, rx_dma,
+			rx_buflen, DMA_FROM_DEVICE);
 
-	if (opcode == ISCSI_OP_SCSI_CMD_RSP) {
-		spin_lock(&conn->iscsi_conn->session->lock);
-		task = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt);
-		if (task)
-			__iscsi_get_task(task);
-		spin_unlock(&conn->iscsi_conn->session->lock);
+	hdr = &rx_desc->iscsi_header;
 
-		if (!task)
-			iser_err("itt can't be matched to task!!! "
-				 "conn %p opcode %d itt %d\n",
-				 conn->iscsi_conn, opcode, hdr->itt);
-		else {
-			iser_task = task->dd_data;
-			iser_dbg("itt %d task %p\n",hdr->itt, task);
-			iser_task->status = ISER_TASK_STATUS_COMPLETED;
-			iser_task_rdma_finalize(iser_task);
-			iscsi_put_task(task);
-		}
-	}
-	iser_dto_buffs_release(dto);
+	iser_dbg("op 0x%x itt 0x%x dlen %d\n", hdr->opcode,
+			hdr->itt, (int)(rx_xfer_len - ISER_HEADERS_LEN));
 
-	iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len);
+	iscsi_iser_recv(conn->iscsi_conn, hdr,
+		rx_desc->data, rx_xfer_len - ISER_HEADERS_LEN);
 
-	kfree(rx_desc->data);
-	kmem_cache_free(ig.desc_cache, rx_desc);
+	ib_dma_sync_single_for_device(ib_conn->device->ib_device, rx_dma,
+			rx_buflen, DMA_FROM_DEVICE);
 
 	/* decrementing conn->post_recv_buf_count only --after-- freeing the   *
 	 * task eliminates the need to worry on tasks which are completed in   *
 	 * parallel to the execution of iser_conn_term. So the code that waits *
 	 * for the posted rx bufs refcount to become zero handles everything   */
-	atomic_dec(&conn->ib_conn->post_recv_buf_count);
+	conn->ib_conn->post_recv_buf_count--;
 
-	/*
-	 * if an unexpected PDU was received then the recv wr consumed must
-	 * be replaced, this is done in the next send of a control-type PDU
-	 */
-	if (opcode == ISCSI_OP_NOOP_IN && hdr->itt == RESERVED_ITT) {
-		/* nop-in with itt = 0xffffffff */
-		atomic_inc(&conn->ib_conn->unexpected_pdu_count);
-	}
-	else if (opcode == ISCSI_OP_ASYNC_EVENT) {
-		/* asyncronous message */
-		atomic_inc(&conn->ib_conn->unexpected_pdu_count);
+	if (rx_dma == ib_conn->login_dma)
+		return;
+
+	outstanding = ib_conn->post_recv_buf_count;
+	if (outstanding + ISER_MIN_POSTED_RX <= ISER_QP_MAX_RECV_DTOS) {
+		count = min(ISER_QP_MAX_RECV_DTOS - outstanding,
+						ISER_MIN_POSTED_RX);
+		err = iser_post_recvm(ib_conn, count);
+		if (err)
+			iser_err("posting %d rx bufs err %d\n", count, err);
 	}
-	/* a reject PDU consumes the recv buf posted for the response */
 }
 
-void iser_snd_completion(struct iser_desc *tx_desc)
+void iser_snd_completion(struct iser_tx_desc *tx_desc,
+			struct iser_conn *ib_conn)
 {
-	struct iser_dto        *dto = &tx_desc->dto;
-	struct iser_conn       *ib_conn = dto->ib_conn;
-	struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn;
-	struct iscsi_conn      *conn = iser_conn->iscsi_conn;
 	struct iscsi_task *task;
-	int resume_tx = 0;
-
-	iser_dbg("Initiator, Data sent dto=0x%p\n", dto);
-
-	iser_dto_buffs_release(dto);
+	struct iser_device *device = ib_conn->device;
 
-	if (tx_desc->type == ISCSI_TX_DATAOUT)
+	if (tx_desc->type == ISCSI_TX_DATAOUT) {
+		ib_dma_unmap_single(device->ib_device, tx_desc->dma_addr,
+					ISER_HEADERS_LEN, DMA_TO_DEVICE);
 		kmem_cache_free(ig.desc_cache, tx_desc);
-
-	if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
-	    ISER_QP_MAX_REQ_DTOS)
-		resume_tx = 1;
+	}
 
 	atomic_dec(&ib_conn->post_send_buf_count);
 
-	if (resume_tx) {
-		iser_dbg("%ld resuming tx\n",jiffies);
-		iscsi_conn_queue_work(conn);
-	}
-
 	if (tx_desc->type == ISCSI_TX_CONTROL) {
 		/* this arithmetic is legal by libiscsi dd_data allocation */
 		task = (void *) ((long)(void *)tx_desc -
@@ -692,7 +528,6 @@ void iser_task_rdma_init(struct iscsi_is
 
 void iser_task_rdma_finalize(struct iscsi_iser_task *iser_task)
 {
-	int deferred;
 	int is_rdma_aligned = 1;
 	struct iser_regd_buf *regd;
 
@@ -710,32 +545,17 @@ void iser_task_rdma_finalize(struct iscs
 
 	if (iser_task->dir[ISER_DIR_IN]) {
 		regd = &iser_task->rdma_regd[ISER_DIR_IN];
-		deferred = iser_regd_buff_release(regd);
-		if (deferred) {
-			iser_err("%d references remain for BUF-IN rdma reg\n",
-				 atomic_read(&regd->ref_count));
-		}
+		if (regd->reg.is_fmr)
+			iser_unreg_mem(&regd->reg);
 	}
 
 	if (iser_task->dir[ISER_DIR_OUT]) {
 		regd = &iser_task->rdma_regd[ISER_DIR_OUT];
-		deferred = iser_regd_buff_release(regd);
-		if (deferred) {
-			iser_err("%d references remain for BUF-OUT rdma reg\n",
-				 atomic_read(&regd->ref_count));
-		}
+		if (regd->reg.is_fmr)
+			iser_unreg_mem(&regd->reg);
 	}
 
        /* if the data was unaligned, it was already unmapped and then copied */
        if (is_rdma_aligned)
 		iser_dma_unmap_task_data(iser_task);
 }
-
-void iser_dto_buffs_release(struct iser_dto *dto)
-{
-	int i;
-
-	for (i = 0; i < dto->regd_vector_len; i++)
-		iser_regd_buff_release(dto->regd[i]);
-}
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iser_memory.c linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/iser/iser_memory.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iser_memory.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/iser/iser_memory.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,62 +41,6 @@
 #define ISER_KMALLOC_THRESHOLD 0x20000 /* 128K - kmalloc limit */
 
 /**
- * Decrements the reference count for the
- * registered buffer & releases it
- *
- * returns 0 if released, 1 if deferred
- */
-int iser_regd_buff_release(struct iser_regd_buf *regd_buf)
-{
-	struct ib_device *dev;
-
-	if ((atomic_read(&regd_buf->ref_count) == 0) ||
-	    atomic_dec_and_test(&regd_buf->ref_count)) {
-		/* if we used the dma mr, unreg is just NOP */
-		if (regd_buf->reg.is_fmr)
-			iser_unreg_mem(&regd_buf->reg);
-
-		if (regd_buf->dma_addr) {
-			dev = regd_buf->device->ib_device;
-			ib_dma_unmap_single(dev,
-					 regd_buf->dma_addr,
-					 regd_buf->data_size,
-					 regd_buf->direction);
-		}
-		/* else this regd buf is associated with task which we */
-		/* dma_unmap_single/sg later */
-		return 0;
-	} else {
-		iser_dbg("Release deferred, regd.buff: 0x%p\n", regd_buf);
-		return 1;
-	}
-}
-
-/**
- * iser_reg_single - fills registered buffer descriptor with
- *		     registration information
- */
-void iser_reg_single(struct iser_device *device,
-		     struct iser_regd_buf *regd_buf,
-		     enum dma_data_direction direction)
-{
-	u64 dma_addr;
-
-	dma_addr = ib_dma_map_single(device->ib_device,
-				     regd_buf->virt_addr,
-				     regd_buf->data_size, direction);
-	BUG_ON(ib_dma_mapping_error(device->ib_device, dma_addr));
-
-	regd_buf->reg.lkey = device->mr->lkey;
-	regd_buf->reg.len  = regd_buf->data_size;
-	regd_buf->reg.va   = dma_addr;
-	regd_buf->reg.is_fmr = 0;
-
-	regd_buf->dma_addr  = dma_addr;
-	regd_buf->direction = direction;
-}
-
-/**
  * iser_start_rdma_unaligned_sg
  */
 static int iser_start_rdma_unaligned_sg(struct iscsi_iser_task *iser_task,
@@ -109,10 +53,10 @@ static int iser_start_rdma_unaligned_sg(
 	unsigned long  cmd_data_len = data->data_len;
 
 	if (cmd_data_len > ISER_KMALLOC_THRESHOLD)
-		mem = (void *)__get_free_pages(GFP_NOIO,
+		mem = (void *)__get_free_pages(GFP_ATOMIC,
 		      ilog2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT);
 	else
-		mem = kmalloc(cmd_data_len, GFP_NOIO);
+		mem = kmalloc(cmd_data_len, GFP_ATOMIC);
 
 	if (mem == NULL) {
 		iser_err("Failed to allocate mem size %d %d for copying sglist\n",
@@ -474,9 +418,5 @@ int iser_reg_rdma_mem(struct iscsi_iser_
 			return err;
 		}
 	}
-
-	/* take a reference on this regd buf such that it will not be released *
-	 * (eg in send dto completion) before we get the scsi response         */
-	atomic_inc(&regd_buf->ref_count);
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iser_verbs.c linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/iser/iser_verbs.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iser_verbs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/iser/iser_verbs.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,14 +32,14 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include "iscsi_iser.h"
 
 #define ISCSI_ISER_MAX_CONN	8
-#define ISER_MAX_CQ_LEN		((ISER_QP_MAX_RECV_DTOS + \
-				ISER_QP_MAX_REQ_DTOS) *   \
-				 ISCSI_ISER_MAX_CONN)
+#define ISER_MAX_RX_CQ_LEN	(ISER_QP_MAX_RECV_DTOS * ISCSI_ISER_MAX_CONN)
+#define ISER_MAX_TX_CQ_LEN	(ISER_QP_MAX_REQ_DTOS  * ISCSI_ISER_MAX_CONN)
 
 static void iser_cq_tasklet_fn(unsigned long data);
 static void iser_cq_callback(struct ib_cq *cq, void *cq_context);
@@ -67,15 +67,23 @@ static int iser_create_device_ib_res(str
 	if (IS_ERR(device->pd))
 		goto pd_err;
 
-	device->cq = ib_create_cq(device->ib_device,
+	device->rx_cq = ib_create_cq(device->ib_device,
 				  iser_cq_callback,
 				  iser_cq_event_callback,
 				  (void *)device,
-				  ISER_MAX_CQ_LEN, 0);
-	if (IS_ERR(device->cq))
-		goto cq_err;
+				  ISER_MAX_RX_CQ_LEN, 0);
+	if (IS_ERR(device->rx_cq))
+		goto rx_cq_err;
 
-	if (ib_req_notify_cq(device->cq, IB_CQ_NEXT_COMP))
+	device->tx_cq = ib_create_cq(device->ib_device,
+				  NULL, iser_cq_event_callback,
+				  (void *)device,
+				  ISER_MAX_TX_CQ_LEN, 0);
+
+	if (IS_ERR(device->tx_cq))
+		goto tx_cq_err;
+
+	if (ib_req_notify_cq(device->rx_cq, IB_CQ_NEXT_COMP))
 		goto cq_arm_err;
 
 	tasklet_init(&device->cq_tasklet,
@@ -93,8 +101,10 @@ static int iser_create_device_ib_res(str
 dma_mr_err:
 	tasklet_kill(&device->cq_tasklet);
 cq_arm_err:
-	ib_destroy_cq(device->cq);
-cq_err:
+	ib_destroy_cq(device->tx_cq);
+tx_cq_err:
+	ib_destroy_cq(device->rx_cq);
+rx_cq_err:
 	ib_dealloc_pd(device->pd);
 pd_err:
 	iser_err("failed to allocate an IB resource\n");
@@ -112,11 +122,13 @@ static void iser_free_device_ib_res(stru
 	tasklet_kill(&device->cq_tasklet);
 
 	(void)ib_dereg_mr(device->mr);
-	(void)ib_destroy_cq(device->cq);
+	(void)ib_destroy_cq(device->tx_cq);
+	(void)ib_destroy_cq(device->rx_cq);
 	(void)ib_dealloc_pd(device->pd);
 
 	device->mr = NULL;
-	device->cq = NULL;
+	device->tx_cq = NULL;
+	device->rx_cq = NULL;
 	device->pd = NULL;
 }
 
@@ -129,13 +141,23 @@ static int iser_create_ib_conn_res(struc
 {
 	struct iser_device	*device;
 	struct ib_qp_init_attr	init_attr;
-	int			ret;
+	int			ret = -ENOMEM;
 	struct ib_fmr_pool_param params;
 
 	BUG_ON(ib_conn->device == NULL);
 
 	device = ib_conn->device;
 
+	ib_conn->login_buf = kmalloc(ISER_RX_LOGIN_SIZE, GFP_KERNEL);
+	if (!ib_conn->login_buf) {
+		goto alloc_err;
+		ret = -ENOMEM;
+	}
+
+	ib_conn->login_dma = ib_dma_map_single(ib_conn->device->ib_device,
+				(void *)ib_conn->login_buf, ISER_RX_LOGIN_SIZE,
+				DMA_FROM_DEVICE);
+
 	ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) +
 				    (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)),
 				    GFP_KERNEL);
@@ -169,12 +191,12 @@ static int iser_create_ib_conn_res(struc
 
 	init_attr.event_handler = iser_qp_event_callback;
 	init_attr.qp_context	= (void *)ib_conn;
-	init_attr.send_cq	= device->cq;
-	init_attr.recv_cq	= device->cq;
+	init_attr.send_cq	= device->tx_cq;
+	init_attr.recv_cq	= device->rx_cq;
 	init_attr.cap.max_send_wr  = ISER_QP_MAX_REQ_DTOS;
 	init_attr.cap.max_recv_wr  = ISER_QP_MAX_RECV_DTOS;
-	init_attr.cap.max_send_sge = MAX_REGD_BUF_VECTOR_LEN;
-	init_attr.cap.max_recv_sge = 2;
+	init_attr.cap.max_send_sge = 2;
+	init_attr.cap.max_recv_sge = 1;
 	init_attr.sq_sig_type	= IB_SIGNAL_REQ_WR;
 	init_attr.qp_type	= IB_QPT_RC;
 
@@ -192,6 +214,7 @@ qp_err:
 	(void)ib_destroy_fmr_pool(ib_conn->fmr_pool);
 fmr_pool_err:
 	kfree(ib_conn->page_vec);
+	kfree(ib_conn->login_buf);
 alloc_err:
 	iser_err("unable to alloc mem or create resource, err %d\n", ret);
 	return ret;
@@ -278,17 +301,6 @@ static void iser_device_try_release(stru
 	mutex_unlock(&ig.device_list_mutex);
 }
 
-int iser_conn_state_comp(struct iser_conn *ib_conn,
-			enum iser_ib_conn_state comp)
-{
-	int ret;
-
-	spin_lock_bh(&ib_conn->lock);
-	ret = (ib_conn->state == comp);
-	spin_unlock_bh(&ib_conn->lock);
-	return ret;
-}
-
 static int iser_conn_state_comp_exch(struct iser_conn *ib_conn,
 				     enum iser_ib_conn_state comp,
 				     enum iser_ib_conn_state exch)
@@ -314,7 +326,7 @@ static void iser_conn_release(struct ise
 	mutex_lock(&ig.connlist_mutex);
 	list_del(&ib_conn->conn_list);
 	mutex_unlock(&ig.connlist_mutex);
-
+	iser_free_rx_descriptors(ib_conn);
 	iser_free_ib_conn_res(ib_conn);
 	ib_conn->device = NULL;
 	/* on EVENT_ADDR_ERROR there's no device yet for this conn */
@@ -442,7 +454,7 @@ static void iser_disconnected_handler(st
 				   ISCSI_ERR_CONN_FAILED);
 
 	/* Complete the termination process if no posts are pending */
-	if ((atomic_read(&ib_conn->post_recv_buf_count) == 0) &&
+	if (ib_conn->post_recv_buf_count == 0 &&
 	    (atomic_read(&ib_conn->post_send_buf_count) == 0)) {
 		ib_conn->state = ISER_CONN_DOWN;
 		wake_up_interruptible(&ib_conn->wait);
@@ -489,9 +501,8 @@ void iser_conn_init(struct iser_conn *ib
 {
 	ib_conn->state = ISER_CONN_INIT;
 	init_waitqueue_head(&ib_conn->wait);
-	atomic_set(&ib_conn->post_recv_buf_count, 0);
+	ib_conn->post_recv_buf_count = 0;
 	atomic_set(&ib_conn->post_send_buf_count, 0);
-	atomic_set(&ib_conn->unexpected_pdu_count, 0);
 	atomic_set(&ib_conn->refcount, 1);
 	INIT_LIST_HEAD(&ib_conn->conn_list);
 	spin_lock_init(&ib_conn->lock);
@@ -626,136 +637,97 @@ void iser_unreg_mem(struct iser_mem_reg
 	reg->mem_h = NULL;
 }
 
-/**
- * iser_dto_to_iov - builds IOV from a dto descriptor
- */
-static void iser_dto_to_iov(struct iser_dto *dto, struct ib_sge *iov, int iov_len)
+int iser_post_recvl(struct iser_conn *ib_conn)
 {
-	int		     i;
-	struct ib_sge	     *sge;
-	struct iser_regd_buf *regd_buf;
-
-	if (dto->regd_vector_len > iov_len) {
-		iser_err("iov size %d too small for posting dto of len %d\n",
-			 iov_len, dto->regd_vector_len);
-		BUG();
-	}
-
-	for (i = 0; i < dto->regd_vector_len; i++) {
-		sge	    = &iov[i];
-		regd_buf  = dto->regd[i];
-
-		sge->addr   = regd_buf->reg.va;
-		sge->length = regd_buf->reg.len;
-		sge->lkey   = regd_buf->reg.lkey;
+	struct ib_recv_wr rx_wr, *rx_wr_failed;
+	struct ib_sge	  sge;
+	int ib_ret;
 
-		if (dto->used_sz[i] > 0)  /* Adjust size */
-			sge->length = dto->used_sz[i];
+	sge.addr   = ib_conn->login_dma;
+	sge.length = ISER_RX_LOGIN_SIZE;
+	sge.lkey   = ib_conn->device->mr->lkey;
 
-		/* offset and length should not exceed the regd buf length */
-		if (sge->length + dto->offset[i] > regd_buf->reg.len) {
-			iser_err("Used len:%ld + offset:%d, exceed reg.buf.len:"
-				 "%ld in dto:0x%p [%d], va:0x%08lX\n",
-				 (unsigned long)sge->length, dto->offset[i],
-				 (unsigned long)regd_buf->reg.len, dto, i,
-				 (unsigned long)sge->addr);
-			BUG();
-		}
+	rx_wr.wr_id   = (unsigned long)ib_conn->login_buf;
+	rx_wr.sg_list = &sge;
+	rx_wr.num_sge = 1;
+	rx_wr.next    = NULL;
 
-		sge->addr += dto->offset[i]; /* Adjust offset */
+	ib_conn->post_recv_buf_count++;
+	ib_ret	= ib_post_recv(ib_conn->qp, &rx_wr, &rx_wr_failed);
+	if (ib_ret) {
+		iser_err("ib_post_recv failed ret=%d\n", ib_ret);
+		ib_conn->post_recv_buf_count--;
 	}
+	return ib_ret;
 }
 
-/**
- * iser_post_recv - Posts a receive buffer.
- *
- * returns 0 on success, -1 on failure
- */
-int iser_post_recv(struct iser_desc *rx_desc)
+int iser_post_recvm(struct iser_conn *ib_conn, int count)
 {
-	int		  ib_ret, ret_val = 0;
-	struct ib_recv_wr recv_wr, *recv_wr_failed;
-	struct ib_sge	  iov[2];
-	struct iser_conn  *ib_conn;
-	struct iser_dto   *recv_dto = &rx_desc->dto;
-
-	/* Retrieve conn */
-	ib_conn = recv_dto->ib_conn;
+	struct ib_recv_wr *rx_wr, *rx_wr_failed;
+	int i, ib_ret;
+	unsigned int my_rx_head = ib_conn->rx_desc_head;
+	struct iser_rx_desc *rx_desc;
 
-	iser_dto_to_iov(recv_dto, iov, 2);
+	for (rx_wr = ib_conn->rx_wr, i = 0; i < count; i++, rx_wr++) {
+		rx_desc		= &ib_conn->rx_descs[my_rx_head];
+		rx_wr->wr_id	= (unsigned long)rx_desc;
+		rx_wr->sg_list	= &rx_desc->rx_sg;
+		rx_wr->num_sge	= 1;
+		rx_wr->next	= rx_wr + 1;
+		my_rx_head = (my_rx_head + 1) & (ISER_QP_MAX_RECV_DTOS - 1);
+	}
 
-	recv_wr.next	= NULL;
-	recv_wr.sg_list = iov;
-	recv_wr.num_sge = recv_dto->regd_vector_len;
-	recv_wr.wr_id	= (unsigned long)rx_desc;
+	rx_wr--;
+	rx_wr->next = NULL; /* mark end of work requests list */
 
-	atomic_inc(&ib_conn->post_recv_buf_count);
-	ib_ret	= ib_post_recv(ib_conn->qp, &recv_wr, &recv_wr_failed);
+	ib_conn->post_recv_buf_count += count;
+	ib_ret	= ib_post_recv(ib_conn->qp, ib_conn->rx_wr, &rx_wr_failed);
 	if (ib_ret) {
 		iser_err("ib_post_recv failed ret=%d\n", ib_ret);
-		atomic_dec(&ib_conn->post_recv_buf_count);
-		ret_val = -1;
-	}
-
-	return ret_val;
+		ib_conn->post_recv_buf_count -= count;
+	} else
+		ib_conn->rx_desc_head = my_rx_head;
+	return ib_ret;
 }
 
+
 /**
  * iser_start_send - Initiate a Send DTO operation
  *
  * returns 0 on success, -1 on failure
  */
-int iser_post_send(struct iser_desc *tx_desc)
+int iser_post_send(struct iser_conn *ib_conn, struct iser_tx_desc *tx_desc)
 {
-	int		  ib_ret, ret_val = 0;
+	int		  ib_ret;
 	struct ib_send_wr send_wr, *send_wr_failed;
-	struct ib_sge	  iov[MAX_REGD_BUF_VECTOR_LEN];
-	struct iser_conn  *ib_conn;
-	struct iser_dto   *dto = &tx_desc->dto;
-
-	ib_conn = dto->ib_conn;
 
-	iser_dto_to_iov(dto, iov, MAX_REGD_BUF_VECTOR_LEN);
+	ib_dma_sync_single_for_device(ib_conn->device->ib_device,
+		tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE);
 
 	send_wr.next	   = NULL;
 	send_wr.wr_id	   = (unsigned long)tx_desc;
-	send_wr.sg_list	   = iov;
-	send_wr.num_sge	   = dto->regd_vector_len;
+	send_wr.sg_list	   = tx_desc->tx_sg;
+	send_wr.num_sge	   = tx_desc->num_sge;
 	send_wr.opcode	   = IB_WR_SEND;
-	send_wr.send_flags = dto->notify_enable ? IB_SEND_SIGNALED : 0;
+	send_wr.send_flags = IB_SEND_SIGNALED;
 
 	atomic_inc(&ib_conn->post_send_buf_count);
 
 	ib_ret = ib_post_send(ib_conn->qp, &send_wr, &send_wr_failed);
 	if (ib_ret) {
-		iser_err("Failed to start SEND DTO, dto: 0x%p, IOV len: %d\n",
-			 dto, dto->regd_vector_len);
 		iser_err("ib_post_send failed, ret:%d\n", ib_ret);
 		atomic_dec(&ib_conn->post_send_buf_count);
-		ret_val = -1;
 	}
-
-	return ret_val;
+	return ib_ret;
 }
 
-static void iser_handle_comp_error(struct iser_desc *desc)
+static void iser_handle_comp_error(struct iser_tx_desc *desc,
+				struct iser_conn *ib_conn)
 {
-	struct iser_dto  *dto     = &desc->dto;
-	struct iser_conn *ib_conn = dto->ib_conn;
-
-	iser_dto_buffs_release(dto);
-
-	if (desc->type == ISCSI_RX) {
-		kfree(desc->data);
+	if (desc && desc->type == ISCSI_TX_DATAOUT)
 		kmem_cache_free(ig.desc_cache, desc);
-		atomic_dec(&ib_conn->post_recv_buf_count);
-	} else { /* type is TX control/command/dataout */
-		if (desc->type == ISCSI_TX_DATAOUT)
-			kmem_cache_free(ig.desc_cache, desc);
-		atomic_dec(&ib_conn->post_send_buf_count);
-	}
 
-	if (atomic_read(&ib_conn->post_recv_buf_count) == 0 &&
+	if (ib_conn->post_recv_buf_count == 0 &&
 	    atomic_read(&ib_conn->post_send_buf_count) == 0) {
 		/* getting here when the state is UP means that the conn is *
 		 * being terminated asynchronously from the iSCSI layer's   *
@@ -774,32 +746,74 @@ static void iser_handle_comp_error(struc
 	}
 }
 
+static int iser_drain_tx_cq(struct iser_device  *device)
+{
+	struct ib_cq  *cq = device->tx_cq;
+	struct ib_wc  wc;
+	struct iser_tx_desc *tx_desc;
+	struct iser_conn *ib_conn;
+	int completed_tx = 0;
+
+	while (ib_poll_cq(cq, 1, &wc) == 1) {
+		tx_desc	= (struct iser_tx_desc *) (unsigned long) wc.wr_id;
+		ib_conn = wc.qp->qp_context;
+		if (wc.status == IB_WC_SUCCESS) {
+			if (wc.opcode == IB_WC_SEND)
+				iser_snd_completion(tx_desc, ib_conn);
+			else
+				iser_err("expected opcode %d got %d\n",
+					IB_WC_SEND, wc.opcode);
+		} else {
+			iser_err("tx id %llx status %d vend_err %x\n",
+				wc.wr_id, wc.status, wc.vendor_err);
+			atomic_dec(&ib_conn->post_send_buf_count);
+			iser_handle_comp_error(tx_desc, ib_conn);
+		}
+		completed_tx++;
+	}
+	return completed_tx;
+}
+
+
 static void iser_cq_tasklet_fn(unsigned long data)
 {
 	 struct iser_device  *device = (struct iser_device *)data;
-	 struct ib_cq	     *cq = device->cq;
+	 struct ib_cq	     *cq = device->rx_cq;
 	 struct ib_wc	     wc;
-	 struct iser_desc    *desc;
+	 struct iser_rx_desc *desc;
 	 unsigned long	     xfer_len;
+	struct iser_conn *ib_conn;
+	int completed_tx, completed_rx;
+	completed_tx = completed_rx = 0;
 
 	while (ib_poll_cq(cq, 1, &wc) == 1) {
-		desc	 = (struct iser_desc *) (unsigned long) wc.wr_id;
+		desc	 = (struct iser_rx_desc *) (unsigned long) wc.wr_id;
 		BUG_ON(desc == NULL);
-
+		ib_conn = wc.qp->qp_context;
 		if (wc.status == IB_WC_SUCCESS) {
-			if (desc->type == ISCSI_RX) {
+			if (wc.opcode == IB_WC_RECV) {
 				xfer_len = (unsigned long)wc.byte_len;
-				iser_rcv_completion(desc, xfer_len);
-			} else /* type == ISCSI_TX_CONTROL/SCSI_CMD/DOUT */
-				iser_snd_completion(desc);
+				iser_rcv_completion(desc, xfer_len, ib_conn);
+			} else
+				iser_err("expected opcode %d got %d\n",
+					IB_WC_RECV, wc.opcode);
 		} else {
-			iser_err("comp w. error op %d status %d\n",desc->type,wc.status);
-			iser_handle_comp_error(desc);
+			if (wc.status != IB_WC_WR_FLUSH_ERR)
+				iser_err("rx id %llx status %d vend_err %x\n",
+					wc.wr_id, wc.status, wc.vendor_err);
+			ib_conn->post_recv_buf_count--;
+			iser_handle_comp_error(NULL, ib_conn);
 		}
+		completed_rx++;
+		if (!(completed_rx & 63))
+			completed_tx += iser_drain_tx_cq(device);
 	}
 	/* #warning "it is assumed here that arming CQ only once its empty" *
 	 * " would not cause interrupts to be missed"                       */
 	ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
+
+	completed_tx += iser_drain_tx_cq(device);
+	iser_dbg("got %d rx %d tx completions\n", completed_rx, completed_tx);
 }
 
 static void iser_cq_callback(struct ib_cq *cq, void *cq_context)
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/srp/ib_srp.c linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/srp/ib_srp.c
--- linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/srp/ib_srp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/srp/ib_srp.c	2010-05-16 17:17:36.000000000 -0400
@@ -80,7 +80,8 @@ MODULE_PARM_DESC(mellanox_workarounds,
 
 static void srp_add_one(struct ib_device *device);
 static void srp_remove_one(struct ib_device *device);
-static void srp_completion(struct ib_cq *cq, void *target_ptr);
+static void srp_recv_completion(struct ib_cq *cq, void *target_ptr);
+static void srp_send_completion(struct ib_cq *cq, void *target_ptr);
 static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event);
 
 static struct scsi_transport_template *ib_srp_transport_template;
@@ -227,14 +228,21 @@ static int srp_create_target_ib(struct s
 	if (!init_attr)
 		return -ENOMEM;
 
-	target->cq = ib_create_cq(target->srp_host->srp_dev->dev,
-				  srp_completion, NULL, target, SRP_CQ_SIZE, 0);
-	if (IS_ERR(target->cq)) {
-		ret = PTR_ERR(target->cq);
-		goto out;
+	target->recv_cq = ib_create_cq(target->srp_host->srp_dev->dev,
+				       srp_recv_completion, NULL, target, SRP_RQ_SIZE, 0);
+	if (IS_ERR(target->recv_cq)) {
+		ret = PTR_ERR(target->recv_cq);
+		goto err;
 	}
 
-	ib_req_notify_cq(target->cq, IB_CQ_NEXT_COMP);
+	target->send_cq = ib_create_cq(target->srp_host->srp_dev->dev,
+				       srp_send_completion, NULL, target, SRP_SQ_SIZE, 0);
+	if (IS_ERR(target->send_cq)) {
+		ret = PTR_ERR(target->send_cq);
+		goto err_recv_cq;
+	}
+
+	ib_req_notify_cq(target->recv_cq, IB_CQ_NEXT_COMP);
 
 	init_attr->event_handler       = srp_qp_event;
 	init_attr->cap.max_send_wr     = SRP_SQ_SIZE;
@@ -243,24 +251,32 @@ static int srp_create_target_ib(struct s
 	init_attr->cap.max_send_sge    = 1;
 	init_attr->sq_sig_type         = IB_SIGNAL_ALL_WR;
 	init_attr->qp_type             = IB_QPT_RC;
-	init_attr->send_cq             = target->cq;
-	init_attr->recv_cq             = target->cq;
+	init_attr->send_cq             = target->send_cq;
+	init_attr->recv_cq             = target->recv_cq;
 
 	target->qp = ib_create_qp(target->srp_host->srp_dev->pd, init_attr);
 	if (IS_ERR(target->qp)) {
 		ret = PTR_ERR(target->qp);
-		ib_destroy_cq(target->cq);
-		goto out;
+		goto err_send_cq;
 	}
 
 	ret = srp_init_qp(target, target->qp);
-	if (ret) {
-		ib_destroy_qp(target->qp);
-		ib_destroy_cq(target->cq);
-		goto out;
-	}
+	if (ret)
+		goto err_qp;
 
-out:
+	kfree(init_attr);
+	return 0;
+
+err_qp:
+	ib_destroy_qp(target->qp);
+
+err_send_cq:
+	ib_destroy_cq(target->send_cq);
+
+err_recv_cq:
+	ib_destroy_cq(target->recv_cq);
+
+err:
 	kfree(init_attr);
 	return ret;
 }
@@ -270,7 +286,8 @@ static void srp_free_target_ib(struct sr
 	int i;
 
 	ib_destroy_qp(target->qp);
-	ib_destroy_cq(target->cq);
+	ib_destroy_cq(target->send_cq);
+	ib_destroy_cq(target->recv_cq);
 
 	for (i = 0; i < SRP_RQ_SIZE; ++i)
 		srp_free_iu(target->srp_host, target->rx_ring[i]);
@@ -568,7 +585,9 @@ static int srp_reconnect_target(struct s
 	if (ret)
 		goto err;
 
-	while (ib_poll_cq(target->cq, 1, &wc) > 0)
+	while (ib_poll_cq(target->recv_cq, 1, &wc) > 0)
+		; /* nothing */
+	while (ib_poll_cq(target->send_cq, 1, &wc) > 0)
 		; /* nothing */
 
 	spin_lock_irq(target->scsi_host->host_lock);
@@ -851,7 +870,7 @@ static void srp_handle_recv(struct srp_t
 	struct srp_iu *iu;
 	u8 opcode;
 
-	iu = target->rx_ring[wc->wr_id & ~SRP_OP_RECV];
+	iu = target->rx_ring[wc->wr_id];
 
 	dev = target->srp_host->srp_dev->dev;
 	ib_dma_sync_single_for_cpu(dev, iu->dma, target->max_ti_iu_len,
@@ -898,7 +917,7 @@ static void srp_handle_recv(struct srp_t
 				      DMA_FROM_DEVICE);
 }
 
-static void srp_completion(struct ib_cq *cq, void *target_ptr)
+static void srp_recv_completion(struct ib_cq *cq, void *target_ptr)
 {
 	struct srp_target_port *target = target_ptr;
 	struct ib_wc wc;
@@ -907,17 +926,31 @@ static void srp_completion(struct ib_cq
 	while (ib_poll_cq(cq, 1, &wc) > 0) {
 		if (wc.status) {
 			shost_printk(KERN_ERR, target->scsi_host,
-				     PFX "failed %s status %d\n",
-				     wc.wr_id & SRP_OP_RECV ? "receive" : "send",
+				     PFX "failed receive status %d\n",
 				     wc.status);
 			target->qp_in_error = 1;
 			break;
 		}
 
-		if (wc.wr_id & SRP_OP_RECV)
-			srp_handle_recv(target, &wc);
-		else
-			++target->tx_tail;
+		srp_handle_recv(target, &wc);
+	}
+}
+
+static void srp_send_completion(struct ib_cq *cq, void *target_ptr)
+{
+	struct srp_target_port *target = target_ptr;
+	struct ib_wc wc;
+
+	while (ib_poll_cq(cq, 1, &wc) > 0) {
+		if (wc.status) {
+			shost_printk(KERN_ERR, target->scsi_host,
+				     PFX "failed send status %d\n",
+				     wc.status);
+			target->qp_in_error = 1;
+			break;
+		}
+
+		++target->tx_tail;
 	}
 }
 
@@ -930,7 +963,7 @@ static int __srp_post_recv(struct srp_ta
 	int ret;
 
 	next 	 = target->rx_head & (SRP_RQ_SIZE - 1);
-	wr.wr_id = next | SRP_OP_RECV;
+	wr.wr_id = next;
 	iu 	 = target->rx_ring[next];
 
 	list.addr   = iu->dma;
@@ -970,6 +1003,8 @@ static struct srp_iu *__srp_get_tx_iu(st
 {
 	s32 min = (req_type == SRP_REQ_TASK_MGMT) ? 1 : 2;
 
+	srp_send_completion(target->send_cq, target);
+
 	if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE)
 		return NULL;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/srp/ib_srp.h linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/srp/ib_srp.h
--- linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/srp/ib_srp.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/infiniband/ulp/srp/ib_srp.h	2010-05-16 17:17:36.000000000 -0400
@@ -60,7 +60,6 @@ enum {
 	SRP_RQ_SHIFT    	= 6,
 	SRP_RQ_SIZE		= 1 << SRP_RQ_SHIFT,
 	SRP_SQ_SIZE		= SRP_RQ_SIZE - 1,
-	SRP_CQ_SIZE		= SRP_SQ_SIZE + SRP_RQ_SIZE,
 
 	SRP_TAG_TSK_MGMT	= 1 << (SRP_RQ_SHIFT + 1),
 
@@ -69,8 +68,6 @@ enum {
 	SRP_FMR_DIRTY_SIZE	= SRP_FMR_POOL_SIZE / 4
 };
 
-#define SRP_OP_RECV		(1 << 31)
-
 enum srp_target_state {
 	SRP_TARGET_LIVE,
 	SRP_TARGET_CONNECTING,
@@ -133,7 +130,8 @@ struct srp_target_port {
 	int			path_query_id;
 
 	struct ib_cm_id	       *cm_id;
-	struct ib_cq	       *cq;
+	struct ib_cq	       *recv_cq;
+	struct ib_cq	       *send_cq;
 	struct ib_qp	       *qp;
 
 	int			max_ti_iu_len;
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/evdev.c linux-libre-2.6.34-gnu1/drivers/input/evdev.c
--- linux-libre-2.6.33-gnu1/drivers/input/evdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/evdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -278,6 +278,8 @@ static int evdev_open(struct inode *inod
 		goto err_free_client;
 
 	file->private_data = client;
+	nonseekable_open(inode, file);
+
 	return 0;
 
  err_free_client:
@@ -513,7 +515,7 @@ static long evdev_do_ioctl(struct file *
 	struct input_absinfo abs;
 	struct ff_effect effect;
 	int __user *ip = (int __user *)p;
-	int i, t, u, v;
+	unsigned int i, t, u, v;
 	int error;
 
 	switch (cmd) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/ff-core.c linux-libre-2.6.34-gnu1/drivers/input/ff-core.c
--- linux-libre-2.6.33-gnu1/drivers/input/ff-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/ff-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 /*
  * Check that the effect_id is a valid effect and whether the user
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/ff-memless.c linux-libre-2.6.34-gnu1/drivers/input/ff-memless.c
--- linux-libre-2.6.33-gnu1/drivers/input/ff-memless.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/ff-memless.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 
 #define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg)
 
+#include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/gameport/emu10k1-gp.c linux-libre-2.6.34-gnu1/drivers/input/gameport/emu10k1-gp.c
--- linux-libre-2.6.33-gnu1/drivers/input/gameport/emu10k1-gp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/gameport/emu10k1-gp.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,7 +46,7 @@ struct emu {
 	int size;
 };
 
-static struct pci_device_id emu_tbl[] = {
+static const struct pci_device_id emu_tbl[] = {
 
 	{ 0x1102, 0x7002, PCI_ANY_ID, PCI_ANY_ID }, /* SB Live gameport */
 	{ 0x1102, 0x7003, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy gameport */
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/gameport/fm801-gp.c linux-libre-2.6.34-gnu1/drivers/input/gameport/fm801-gp.c
--- linux-libre-2.6.33-gnu1/drivers/input/gameport/fm801-gp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/gameport/fm801-gp.c	2010-05-16 17:17:36.000000000 -0400
@@ -140,7 +140,7 @@ static void __devexit fm801_gp_remove(st
 	}
 }
 
-static struct pci_device_id fm801_gp_id_table[] = {
+static const struct pci_device_id fm801_gp_id_table[] = {
 	{ PCI_VENDOR_ID_FORTEMEDIA, PCI_DEVICE_ID_FM801_GP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0  },
 	{ 0 }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/gameport/gameport.c linux-libre-2.6.34-gnu1/drivers/input/gameport/gameport.c
--- linux-libre-2.6.33-gnu1/drivers/input/gameport/gameport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/gameport/gameport.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,8 @@
  * the Free Software Foundation.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/stddef.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
@@ -190,9 +192,8 @@ static int gameport_bind_driver(struct g
 
 	error = device_bind_driver(&gameport->dev);
 	if (error) {
-		printk(KERN_WARNING
-			"gameport: device_bind_driver() failed "
-			"for %s (%s) and %s, error: %d\n",
+		dev_warn(&gameport->dev,
+			 "device_bind_driver() failed for %s (%s) and %s, error: %d\n",
 			gameport->phys, gameport->name,
 			drv->description, error);
 		drv->disconnect(gameport);
@@ -209,9 +210,9 @@ static void gameport_find_driver(struct
 
 	error = device_attach(&gameport->dev);
 	if (error < 0)
-		printk(KERN_WARNING
-			"gameport: device_attach() failed for %s (%s), error: %d\n",
-			gameport->phys, gameport->name, error);
+		dev_warn(&gameport->dev,
+			 "device_attach() failed for %s (%s), error: %d\n",
+			 gameport->phys, gameport->name, error);
 }
 
 
@@ -262,17 +263,14 @@ static int gameport_queue_event(void *ob
 
 	event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC);
 	if (!event) {
-		printk(KERN_ERR
-			"gameport: Not enough memory to queue event %d\n",
-			event_type);
+		pr_err("Not enough memory to queue event %d\n", event_type);
 		retval = -ENOMEM;
 		goto out;
 	}
 
 	if (!try_module_get(owner)) {
-		printk(KERN_WARNING
-			"gameport: Can't get module reference, dropping event %d\n",
-			event_type);
+		pr_warning("Can't get module reference, dropping event %d\n",
+			   event_type);
 		kfree(event);
 		retval = -EINVAL;
 		goto out;
@@ -298,14 +296,12 @@ static void gameport_free_event(struct g
 
 static void gameport_remove_duplicate_events(struct gameport_event *event)
 {
-	struct list_head *node, *next;
-	struct gameport_event *e;
+	struct gameport_event *e, *next;
 	unsigned long flags;
 
 	spin_lock_irqsave(&gameport_event_lock, flags);
 
-	list_for_each_safe(node, next, &gameport_event_list) {
-		e = list_entry(node, struct gameport_event, node);
+	list_for_each_entry_safe(e, next, &gameport_event_list, node) {
 		if (event->object == e->object) {
 			/*
 			 * If this event is of different type we should not
@@ -315,7 +311,7 @@ static void gameport_remove_duplicate_ev
 			if (event->type != e->type)
 				break;
 
-			list_del_init(node);
+			list_del_init(&e->node);
 			gameport_free_event(e);
 		}
 	}
@@ -325,23 +321,18 @@ static void gameport_remove_duplicate_ev
 
 static struct gameport_event *gameport_get_event(void)
 {
-	struct gameport_event *event;
-	struct list_head *node;
+	struct gameport_event *event = NULL;
 	unsigned long flags;
 
 	spin_lock_irqsave(&gameport_event_lock, flags);
 
-	if (list_empty(&gameport_event_list)) {
-		spin_unlock_irqrestore(&gameport_event_lock, flags);
-		return NULL;
+	if (!list_empty(&gameport_event_list)) {
+		event = list_first_entry(&gameport_event_list,
+					 struct gameport_event, node);
+		list_del_init(&event->node);
 	}
 
-	node = gameport_event_list.next;
-	event = list_entry(node, struct gameport_event, node);
-	list_del_init(node);
-
 	spin_unlock_irqrestore(&gameport_event_lock, flags);
-
 	return event;
 }
 
@@ -360,16 +351,14 @@ static void gameport_handle_event(void)
 	if ((event = gameport_get_event())) {
 
 		switch (event->type) {
-			case GAMEPORT_REGISTER_PORT:
-				gameport_add_port(event->object);
-				break;
 
-			case GAMEPORT_ATTACH_DRIVER:
-				gameport_attach_driver(event->object);
-				break;
+		case GAMEPORT_REGISTER_PORT:
+			gameport_add_port(event->object);
+			break;
 
-			default:
-				break;
+		case GAMEPORT_ATTACH_DRIVER:
+			gameport_attach_driver(event->object);
+			break;
 		}
 
 		gameport_remove_duplicate_events(event);
@@ -385,16 +374,14 @@ static void gameport_handle_event(void)
  */
 static void gameport_remove_pending_events(void *object)
 {
-	struct list_head *node, *next;
-	struct gameport_event *event;
+	struct gameport_event *event, *next;
 	unsigned long flags;
 
 	spin_lock_irqsave(&gameport_event_lock, flags);
 
-	list_for_each_safe(node, next, &gameport_event_list) {
-		event = list_entry(node, struct gameport_event, node);
+	list_for_each_entry_safe(event, next, &gameport_event_list, node) {
 		if (event->object == object) {
-			list_del_init(node);
+			list_del_init(&event->node);
 			gameport_free_event(event);
 		}
 	}
@@ -441,7 +428,6 @@ static int gameport_thread(void *nothing
 			kthread_should_stop() || !list_empty(&gameport_event_list));
 	} while (!kthread_should_stop());
 
-	printk(KERN_DEBUG "gameport: kgameportd exiting\n");
 	return 0;
 }
 
@@ -453,6 +439,7 @@ static int gameport_thread(void *nothing
 static ssize_t gameport_show_description(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct gameport *gameport = to_gameport_port(dev);
+
 	return sprintf(buf, "%s\n", gameport->name);
 }
 
@@ -521,7 +508,8 @@ static void gameport_init_port(struct ga
 
 	mutex_init(&gameport->drv_mutex);
 	device_initialize(&gameport->dev);
-	dev_set_name(&gameport->dev, "gameport%lu", (unsigned long)atomic_inc_return(&gameport_no) - 1);
+	dev_set_name(&gameport->dev, "gameport%lu",
+			(unsigned long)atomic_inc_return(&gameport_no) - 1);
 	gameport->dev.bus = &gameport_bus;
 	gameport->dev.release = gameport_release_port;
 	if (gameport->parent)
@@ -550,19 +538,17 @@ static void gameport_add_port(struct gam
 	list_add_tail(&gameport->node, &gameport_list);
 
 	if (gameport->io)
-		printk(KERN_INFO "gameport: %s is %s, io %#x, speed %dkHz\n",
-			gameport->name, gameport->phys, gameport->io, gameport->speed);
+		dev_info(&gameport->dev, "%s is %s, io %#x, speed %dkHz\n",
+			 gameport->name, gameport->phys, gameport->io, gameport->speed);
 	else
-		printk(KERN_INFO "gameport: %s is %s, speed %dkHz\n",
+		dev_info(&gameport->dev, "%s is %s, speed %dkHz\n",
 			gameport->name, gameport->phys, gameport->speed);
 
 	error = device_add(&gameport->dev);
 	if (error)
-		printk(KERN_ERR
-			"gameport: device_add() failed for %s (%s), error: %d\n",
+		dev_err(&gameport->dev,
+			"device_add() failed for %s (%s), error: %d\n",
 			gameport->phys, gameport->name, error);
-	else
-		gameport->registered = 1;
 }
 
 /*
@@ -584,10 +570,8 @@ static void gameport_destroy_port(struct
 		gameport->parent = NULL;
 	}
 
-	if (gameport->registered) {
+	if (device_is_registered(&gameport->dev))
 		device_del(&gameport->dev);
-		gameport->registered = 0;
-	}
 
 	list_del_init(&gameport->node);
 
@@ -705,8 +689,7 @@ static void gameport_attach_driver(struc
 
 	error = driver_attach(&drv->driver);
 	if (error)
-		printk(KERN_ERR
-			"gameport: driver_attach() failed for %s, error: %d\n",
+		pr_err("driver_attach() failed for %s, error: %d\n",
 			drv->driver.name, error);
 }
 
@@ -727,8 +710,7 @@ int __gameport_register_driver(struct ga
 
 	error = driver_register(&drv->driver);
 	if (error) {
-		printk(KERN_ERR
-			"gameport: driver_register() failed for %s, error: %d\n",
+		pr_err("driver_register() failed for %s, error: %d\n",
 			drv->driver.name, error);
 		return error;
 	}
@@ -828,7 +810,7 @@ static int __init gameport_init(void)
 
 	error = bus_register(&gameport_bus);
 	if (error) {
-		printk(KERN_ERR "gameport: failed to register gameport bus, error: %d\n", error);
+		pr_err("failed to register gameport bus, error: %d\n", error);
 		return error;
 	}
 
@@ -836,7 +818,7 @@ static int __init gameport_init(void)
 	if (IS_ERR(gameport_task)) {
 		bus_unregister(&gameport_bus);
 		error = PTR_ERR(gameport_task);
-		printk(KERN_ERR "gameport: Failed to start kgameportd, error: %d\n", error);
+		pr_err("Failed to start kgameportd, error: %d\n", error);
 		return error;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/gameport/lightning.c linux-libre-2.6.34-gnu1/drivers/input/gameport/lightning.c
--- linux-libre-2.6.33-gnu1/drivers/input/gameport/lightning.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/gameport/lightning.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/gameport.h>
-#include <linux/slab.h>
 
 #define L4_PORT			0x201
 #define L4_SELECT_ANALOG	0xa4
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/gameport/ns558.c linux-libre-2.6.34-gnu1/drivers/input/gameport/ns558.c
--- linux-libre-2.6.33-gnu1/drivers/input/gameport/ns558.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/gameport/ns558.c	2010-05-16 17:17:36.000000000 -0400
@@ -166,7 +166,7 @@ static int ns558_isa_probe(int io)
 
 #ifdef CONFIG_PNP
 
-static struct pnp_device_id pnp_devids[] = {
+static const struct pnp_device_id pnp_devids[] = {
 	{ .id = "@P@0001", .driver_data = 0 }, /* ALS 100 */
 	{ .id = "@P@0020", .driver_data = 0 }, /* ALS 200 */
 	{ .id = "@P@1001", .driver_data = 0 }, /* ALS 100+ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/input.c linux-libre-2.6.34-gnu1/drivers/input/input.c
--- linux-libre-2.6.33-gnu1/drivers/input/input.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/input.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/input.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/major.h>
 #include <linux/proc_fs.h>
@@ -87,12 +88,14 @@ static int input_defuzz_abs_event(int va
 }
 
 /*
- * Pass event through all open handles. This function is called with
+ * Pass event first through all filters and then, if event has not been
+ * filtered out, through all open handles. This function is called with
  * dev->event_lock held and interrupts disabled.
  */
 static void input_pass_event(struct input_dev *dev,
 			     unsigned int type, unsigned int code, int value)
 {
+	struct input_handler *handler;
 	struct input_handle *handle;
 
 	rcu_read_lock();
@@ -100,11 +103,25 @@ static void input_pass_event(struct inpu
 	handle = rcu_dereference(dev->grab);
 	if (handle)
 		handle->handler->event(handle, type, code, value);
-	else
-		list_for_each_entry_rcu(handle, &dev->h_list, d_node)
-			if (handle->open)
-				handle->handler->event(handle,
-							type, code, value);
+	else {
+		bool filtered = false;
+
+		list_for_each_entry_rcu(handle, &dev->h_list, d_node) {
+			if (!handle->open)
+				continue;
+
+			handler = handle->handler;
+			if (!handler->filter) {
+				if (filtered)
+					break;
+
+				handler->event(handle, type, code, value);
+
+			} else if (handler->filter(handle, type, code, value))
+				filtered = true;
+		}
+	}
+
 	rcu_read_unlock();
 }
 
@@ -566,7 +583,8 @@ static int input_fetch_keycode(struct in
 }
 
 static int input_default_getkeycode(struct input_dev *dev,
-				    int scancode, int *keycode)
+				    unsigned int scancode,
+				    unsigned int *keycode)
 {
 	if (!dev->keycodesize)
 		return -EINVAL;
@@ -580,7 +598,8 @@ static int input_default_getkeycode(stru
 }
 
 static int input_default_setkeycode(struct input_dev *dev,
-				    int scancode, int keycode)
+				    unsigned int scancode,
+				    unsigned int keycode)
 {
 	int old_keycode;
 	int i;
@@ -615,12 +634,12 @@ static int input_default_setkeycode(stru
 		}
 	}
 
-	clear_bit(old_keycode, dev->keybit);
-	set_bit(keycode, dev->keybit);
+	__clear_bit(old_keycode, dev->keybit);
+	__set_bit(keycode, dev->keybit);
 
 	for (i = 0; i < dev->keycodemax; i++) {
 		if (input_fetch_keycode(dev, i) == old_keycode) {
-			set_bit(old_keycode, dev->keybit);
+			__set_bit(old_keycode, dev->keybit);
 			break; /* Setting the bit twice is useless, so break */
 		}
 	}
@@ -638,12 +657,17 @@ static int input_default_setkeycode(stru
  * This function should be called by anyone interested in retrieving current
  * keymap. Presently keyboard and evdev handlers use it.
  */
-int input_get_keycode(struct input_dev *dev, int scancode, int *keycode)
+int input_get_keycode(struct input_dev *dev,
+		      unsigned int scancode, unsigned int *keycode)
 {
-	if (scancode < 0)
-		return -EINVAL;
+	unsigned long flags;
+	int retval;
 
-	return dev->getkeycode(dev, scancode, keycode);
+	spin_lock_irqsave(&dev->event_lock, flags);
+	retval = dev->getkeycode(dev, scancode, keycode);
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	return retval;
 }
 EXPORT_SYMBOL(input_get_keycode);
 
@@ -656,16 +680,14 @@ EXPORT_SYMBOL(input_get_keycode);
  * This function should be called by anyone needing to update current
  * keymap. Presently keyboard and evdev handlers use it.
  */
-int input_set_keycode(struct input_dev *dev, int scancode, int keycode)
+int input_set_keycode(struct input_dev *dev,
+		      unsigned int scancode, unsigned int keycode)
 {
 	unsigned long flags;
 	int old_keycode;
 	int retval;
 
-	if (scancode < 0)
-		return -EINVAL;
-
-	if (keycode < 0 || keycode > KEY_MAX)
+	if (keycode > KEY_MAX)
 		return -EINVAL;
 
 	spin_lock_irqsave(&dev->event_lock, flags);
@@ -678,6 +700,9 @@ int input_set_keycode(struct input_dev *
 	if (retval)
 		goto out;
 
+	/* Make sure KEY_RESERVED did not get enabled. */
+	__clear_bit(KEY_RESERVED, dev->keybit);
+
 	/*
 	 * Simulate keyup event if keycode is not present
 	 * in the keymap anymore
@@ -705,12 +730,13 @@ EXPORT_SYMBOL(input_set_keycode);
 		if (i != BITS_TO_LONGS(max)) \
 			continue;
 
-static const struct input_device_id *input_match_device(const struct input_device_id *id,
+static const struct input_device_id *input_match_device(struct input_handler *handler,
 							struct input_dev *dev)
 {
+	const struct input_device_id *id;
 	int i;
 
-	for (; id->flags || id->driver_info; id++) {
+	for (id = handler->id_table; id->flags || id->driver_info; id++) {
 
 		if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
 			if (id->bustype != dev->id.bustype)
@@ -738,7 +764,8 @@ static const struct input_device_id *inp
 		MATCH_BIT(ffbit,  FF_MAX);
 		MATCH_BIT(swbit,  SW_MAX);
 
-		return id;
+		if (!handler->match || handler->match(handler, dev))
+			return id;
 	}
 
 	return NULL;
@@ -749,10 +776,7 @@ static int input_attach_handler(struct i
 	const struct input_device_id *id;
 	int error;
 
-	if (handler->blacklist && input_match_device(handler->blacklist, dev))
-		return -ENODEV;
-
-	id = input_match_device(handler->id_table, dev);
+	id = input_match_device(handler, dev);
 	if (!id)
 		return -ENODEV;
 
@@ -988,6 +1012,8 @@ static int input_handlers_seq_show(struc
 	union input_seq_state *state = (union input_seq_state *)&seq->private;
 
 	seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name);
+	if (handler->filter)
+		seq_puts(seq, " (filter)");
 	if (handler->fops)
 		seq_printf(seq, " Minor=%d", handler->minor);
 	seq_putc(seq, '\n');
@@ -1551,6 +1577,25 @@ void input_set_capability(struct input_d
 }
 EXPORT_SYMBOL(input_set_capability);
 
+#define INPUT_CLEANSE_BITMASK(dev, type, bits)				\
+	do {								\
+		if (!test_bit(EV_##type, dev->evbit))			\
+			memset(dev->bits##bit, 0,			\
+				sizeof(dev->bits##bit));		\
+	} while (0)
+
+static void input_cleanse_bitmasks(struct input_dev *dev)
+{
+	INPUT_CLEANSE_BITMASK(dev, KEY, key);
+	INPUT_CLEANSE_BITMASK(dev, REL, rel);
+	INPUT_CLEANSE_BITMASK(dev, ABS, abs);
+	INPUT_CLEANSE_BITMASK(dev, MSC, msc);
+	INPUT_CLEANSE_BITMASK(dev, LED, led);
+	INPUT_CLEANSE_BITMASK(dev, SND, snd);
+	INPUT_CLEANSE_BITMASK(dev, FF, ff);
+	INPUT_CLEANSE_BITMASK(dev, SW, sw);
+}
+
 /**
  * input_register_device - register device with input core
  * @dev: device to be registered
@@ -1570,13 +1615,19 @@ int input_register_device(struct input_d
 	const char *path;
 	int error;
 
+	/* Every input device generates EV_SYN/SYN_REPORT events. */
 	__set_bit(EV_SYN, dev->evbit);
 
+	/* KEY_RESERVED is not supposed to be transmitted to userspace. */
+	__clear_bit(KEY_RESERVED, dev->keybit);
+
+	/* Make sure that bitmasks not mentioned in dev->evbit are clean. */
+	input_cleanse_bitmasks(dev);
+
 	/*
 	 * If delay and period are pre-set by the driver, then autorepeating
 	 * is handled by the driver itself and we don't do it in input.c.
 	 */
-
 	init_timer(&dev->timer);
 	if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {
 		dev->timer.data = (long) dev;
@@ -1776,7 +1827,16 @@ int input_register_handle(struct input_h
 	error = mutex_lock_interruptible(&dev->mutex);
 	if (error)
 		return error;
-	list_add_tail_rcu(&handle->d_node, &dev->h_list);
+
+	/*
+	 * Filters go to the head of the list, normal handlers
+	 * to the tail.
+	 */
+	if (handler->filter)
+		list_add_rcu(&handle->d_node, &dev->h_list);
+	else
+		list_add_tail_rcu(&handle->d_node, &dev->h_list);
+
 	mutex_unlock(&dev->mutex);
 
 	/*
@@ -1827,35 +1887,37 @@ static int input_open_file(struct inode
 	const struct file_operations *old_fops, *new_fops = NULL;
 	int err;
 
-	lock_kernel();
+	err = mutex_lock_interruptible(&input_mutex);
+	if (err)
+		return err;
+
 	/* No load-on-demand here? */
 	handler = input_table[iminor(inode) >> 5];
-	if (!handler || !(new_fops = fops_get(handler->fops))) {
-		err = -ENODEV;
-		goto out;
-	}
+	if (handler)
+		new_fops = fops_get(handler->fops);
+
+	mutex_unlock(&input_mutex);
 
 	/*
 	 * That's _really_ odd. Usually NULL ->open means "nothing special",
 	 * not "no device". Oh, well...
 	 */
-	if (!new_fops->open) {
+	if (!new_fops || !new_fops->open) {
 		fops_put(new_fops);
 		err = -ENODEV;
 		goto out;
 	}
+
 	old_fops = file->f_op;
 	file->f_op = new_fops;
 
 	err = new_fops->open(inode, file);
-
 	if (err) {
 		fops_put(file->f_op);
 		file->f_op = fops_get(old_fops);
 	}
 	fops_put(old_fops);
 out:
-	unlock_kernel();
 	return err;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/input-compat.h linux-libre-2.6.34-gnu1/drivers/input/input-compat.h
--- linux-libre-2.6.33-gnu1/drivers/input/input-compat.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/input-compat.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,8 +21,6 @@
    you why the ifdefs are needed? Think about it again. -AK */
 #ifdef CONFIG_X86_64
 #  define INPUT_COMPAT_TEST is_compat_task()
-#elif defined(CONFIG_IA64)
-#  define INPUT_COMPAT_TEST IS_IA32_PROCESS(task_pt_regs(current))
 #elif defined(CONFIG_S390)
 #  define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT)
 #elif defined(CONFIG_MIPS)
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/input-polldev.c linux-libre-2.6.34-gnu1/drivers/input/input-polldev.c
--- linux-libre-2.6.33-gnu1/drivers/input/input-polldev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/input-polldev.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  */
 
 #include <linux/jiffies.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/input-polldev.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/joydev.c linux-libre-2.6.34-gnu1/drivers/input/joydev.c
--- linux-libre-2.6.33-gnu1/drivers/input/joydev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/joydev.c	2010-05-16 17:17:36.000000000 -0400
@@ -286,6 +286,8 @@ static int joydev_open(struct inode *ino
 		goto err_free_client;
 
 	file->private_data = client;
+	nonseekable_open(inode, file);
+
 	return 0;
 
  err_free_client:
@@ -775,6 +777,20 @@ static void joydev_cleanup(struct joydev
 		input_close_device(handle);
 }
 
+
+static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
+{
+	/* Avoid touchpads and touchscreens */
+	if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
+		return false;
+
+	/* Avoid tablets, digitisers and similar devices */
+	if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit))
+		return false;
+
+	return true;
+}
+
 static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
 			  const struct input_device_id *id)
 {
@@ -894,22 +910,6 @@ static void joydev_disconnect(struct inp
 	put_device(&joydev->dev);
 }
 
-static const struct input_device_id joydev_blacklist[] = {
-	{
-		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
-				INPUT_DEVICE_ID_MATCH_KEYBIT,
-		.evbit = { BIT_MASK(EV_KEY) },
-		.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
-	},	/* 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 */
-};
-
 static const struct input_device_id joydev_ids[] = {
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
@@ -929,6 +929,24 @@ static const struct input_device_id joyd
 		.evbit = { BIT_MASK(EV_ABS) },
 		.absbit = { BIT_MASK(ABS_THROTTLE) },
 	},
+	{
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+				INPUT_DEVICE_ID_MATCH_KEYBIT,
+		.evbit = { BIT_MASK(EV_KEY) },
+		.keybit = {[BIT_WORD(BTN_JOYSTICK)] = BIT_MASK(BTN_JOYSTICK) },
+	},
+	{
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+				INPUT_DEVICE_ID_MATCH_KEYBIT,
+		.evbit = { BIT_MASK(EV_KEY) },
+		.keybit = { [BIT_WORD(BTN_GAMEPAD)] = BIT_MASK(BTN_GAMEPAD) },
+	},
+	{
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+				INPUT_DEVICE_ID_MATCH_KEYBIT,
+		.evbit = { BIT_MASK(EV_KEY) },
+		.keybit = { [BIT_WORD(BTN_TRIGGER_HAPPY)] = BIT_MASK(BTN_TRIGGER_HAPPY) },
+	},
 	{ }	/* Terminating entry */
 };
 
@@ -936,13 +954,13 @@ MODULE_DEVICE_TABLE(input, joydev_ids);
 
 static struct input_handler joydev_handler = {
 	.event		= joydev_event,
+	.match		= joydev_match,
 	.connect	= joydev_connect,
 	.disconnect	= joydev_disconnect,
 	.fops		= &joydev_fops,
 	.minor		= JOYDEV_MINOR_BASE,
 	.name		= "joydev",
 	.id_table	= joydev_ids,
-	.blacklist	= joydev_blacklist,
 };
 
 static int __init joydev_init(void)
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/joystick/db9.c linux-libre-2.6.34-gnu1/drivers/input/joystick/db9.c
--- linux-libre-2.6.33-gnu1/drivers/input/joystick/db9.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/joystick/db9.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/parport.h>
 #include <linux/input.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver");
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/joystick/gamecon.c linux-libre-2.6.34-gnu1/drivers/input/joystick/gamecon.c
--- linux-libre-2.6.33-gnu1/drivers/input/joystick/gamecon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/joystick/gamecon.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,8 @@
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/module.h>
@@ -37,6 +39,7 @@
 #include <linux/parport.h>
 #include <linux/input.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver");
@@ -61,48 +64,73 @@ MODULE_PARM_DESC(map3, "Describes third
 
 /* see also gs_psx_delay parameter in PSX support section */
 
-#define GC_SNES		1
-#define GC_NES		2
-#define GC_NES4		3
-#define GC_MULTI	4
-#define GC_MULTI2	5
-#define GC_N64		6
-#define GC_PSX		7
-#define GC_DDR		8
-#define GC_SNESMOUSE	9
-
-#define GC_MAX		9
+enum gc_type {
+	GC_NONE = 0,
+	GC_SNES,
+	GC_NES,
+	GC_NES4,
+	GC_MULTI,
+	GC_MULTI2,
+	GC_N64,
+	GC_PSX,
+	GC_DDR,
+	GC_SNESMOUSE,
+	GC_MAX
+};
 
 #define GC_REFRESH_TIME	HZ/100
 
+struct gc_pad {
+	struct input_dev *dev;
+	enum gc_type type;
+	char phys[32];
+};
+
 struct gc {
 	struct pardevice *pd;
+	struct gc_pad pads[GC_MAX_DEVICES];
 	struct input_dev *dev[GC_MAX_DEVICES];
 	struct timer_list timer;
-	unsigned char pads[GC_MAX + 1];
+	int pad_count[GC_MAX];
 	int used;
 	struct mutex mutex;
-	char phys[GC_MAX_DEVICES][32];
+};
+
+struct gc_subdev {
+	unsigned int idx;
 };
 
 static struct gc *gc_base[3];
 
-static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 };
+static const int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 };
+
+static const char *gc_names[] = {
+	NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick",
+	"Multisystem 2-button joystick", "N64 controller", "PSX controller",
+	"PSX DDR controller", "SNES mouse"
+};
 
-static char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick",
-				"Multisystem 2-button joystick", "N64 controller", "PSX controller",
-				"PSX DDR controller", "SNES mouse" };
 /*
  * N64 support.
  */
 
-static unsigned char gc_n64_bytes[] = { 0, 1, 13, 15, 14, 12, 10, 11, 2, 3 };
-static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_TRIGGER, BTN_START };
+static const unsigned char gc_n64_bytes[] = { 0, 1, 13, 15, 14, 12, 10, 11, 2, 3 };
+static const short gc_n64_btn[] = {
+	BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z,
+	BTN_TL, BTN_TR, BTN_TRIGGER, BTN_START
+};
 
 #define GC_N64_LENGTH		32		/* N64 bit length, not including stop bit */
-#define GC_N64_REQUEST_LENGTH	37		/* transmit request sequence is 9 bits long */
+#define GC_N64_STOP_LENGTH	5		/* Length of encoded stop bit */
+#define GC_N64_CMD_00		0x11111111UL
+#define GC_N64_CMD_01		0xd1111111UL
+#define GC_N64_CMD_03		0xdd111111UL
+#define GC_N64_CMD_1b		0xdd1dd111UL
+#define GC_N64_CMD_c0		0x111111ddUL
+#define GC_N64_CMD_80		0x1111111dUL
+#define GC_N64_STOP_BIT		0x1d		/* Encoded stop bit */
+#define GC_N64_REQUEST_DATA	GC_N64_CMD_01	/* the request data command */
 #define GC_N64_DELAY		133		/* delay between transmit request, and response ready (us) */
-#define GC_N64_REQUEST		0x1dd1111111ULL /* the request data command (encoded for 000000011) */
 #define GC_N64_DWS		3		/* delay between write segments (required for sound playback because of ISA DMA) */
 						/* GC_N64_DWS > 24 is known to fail */
 #define GC_N64_POWER_W		0xe2		/* power during write (transmit request) */
@@ -114,8 +142,40 @@ static short gc_n64_btn[] = { BTN_A, BTN
 #define GC_N64_CLOCK		0x02		/* clock bits for read */
 
 /*
+ * Used for rumble code.
+ */
+
+/* Send encoded command */
+static void gc_n64_send_command(struct gc *gc, unsigned long cmd,
+				unsigned char target)
+{
+	struct parport *port = gc->pd->port;
+	int i;
+
+	for (i = 0; i < GC_N64_LENGTH; i++) {
+		unsigned char data = (cmd >> i) & 1 ? target : 0;
+		parport_write_data(port, GC_N64_POWER_W | data);
+		udelay(GC_N64_DWS);
+	}
+}
+
+/* Send stop bit */
+static void gc_n64_send_stop_bit(struct gc *gc, unsigned char target)
+{
+	struct parport *port = gc->pd->port;
+	int i;
+
+	for (i = 0; i < GC_N64_STOP_LENGTH; i++) {
+		unsigned char data = (GC_N64_STOP_BIT >> i) & 1 ? target : 0;
+		parport_write_data(port, GC_N64_POWER_W | data);
+		udelay(GC_N64_DWS);
+	}
+}
+
+/*
  * gc_n64_read_packet() reads an N64 packet.
- * Each pad uses one bit per byte. So all pads connected to this port are read in parallel.
+ * Each pad uses one bit per byte. So all pads connected to this port
+ * are read in parallel.
  */
 
 static void gc_n64_read_packet(struct gc *gc, unsigned char *data)
@@ -128,14 +188,13 @@ static void gc_n64_read_packet(struct gc
  */
 
 	local_irq_save(flags);
-	for (i = 0; i < GC_N64_REQUEST_LENGTH; i++) {
-		parport_write_data(gc->pd->port, GC_N64_POWER_W | ((GC_N64_REQUEST >> i) & 1 ? GC_N64_OUT : 0));
-		udelay(GC_N64_DWS);
-	}
+	gc_n64_send_command(gc, GC_N64_REQUEST_DATA, GC_N64_OUT);
+	gc_n64_send_stop_bit(gc, GC_N64_OUT);
 	local_irq_restore(flags);
 
 /*
- * Wait for the pad response to be loaded into the 33-bit register of the adapter
+ * Wait for the pad response to be loaded into the 33-bit register
+ * of the adapter.
  */
 
 	udelay(GC_N64_DELAY);
@@ -146,13 +205,15 @@ static void gc_n64_read_packet(struct gc
 
 	for (i = 0; i < GC_N64_LENGTH; i++) {
 		parport_write_data(gc->pd->port, GC_N64_POWER_R);
+		udelay(2);
 		data[i] = parport_read_status(gc->pd->port);
 		parport_write_data(gc->pd->port, GC_N64_POWER_R | GC_N64_CLOCK);
 	 }
 
 /*
- * We must wait 200 ms here for the controller to reinitialize before the next read request.
- * No worries as long as gc_read is polled less frequently than this.
+ * We must wait 200 ms here for the controller to reinitialize before
+ * the next read request. No worries as long as gc_read is polled less
+ * frequently than this.
  */
 
 }
@@ -160,45 +221,112 @@ static void gc_n64_read_packet(struct gc
 static void gc_n64_process_packet(struct gc *gc)
 {
 	unsigned char data[GC_N64_LENGTH];
-	signed char axes[2];
 	struct input_dev *dev;
 	int i, j, s;
+	signed char x, y;
 
 	gc_n64_read_packet(gc, data);
 
 	for (i = 0; i < GC_MAX_DEVICES; i++) {
 
-		dev = gc->dev[i];
-		if (!dev)
+		if (gc->pads[i].type != GC_N64)
 			continue;
 
+		dev = gc->pads[i].dev;
 		s = gc_status_bit[i];
 
-		if (s & gc->pads[GC_N64] & ~(data[8] | data[9])) {
+		if (s & ~(data[8] | data[9])) {
 
-			axes[0] = axes[1] = 0;
+			x = y = 0;
 
 			for (j = 0; j < 8; j++) {
 				if (data[23 - j] & s)
-					axes[0] |= 1 << j;
+					x |= 1 << j;
 				if (data[31 - j] & s)
-					axes[1] |= 1 << j;
+					y |= 1 << j;
 			}
 
-			input_report_abs(dev, ABS_X,  axes[0]);
-			input_report_abs(dev, ABS_Y, -axes[1]);
+			input_report_abs(dev, ABS_X,  x);
+			input_report_abs(dev, ABS_Y, -y);
 
-			input_report_abs(dev, ABS_HAT0X, !(s & data[6]) - !(s & data[7]));
-			input_report_abs(dev, ABS_HAT0Y, !(s & data[4]) - !(s & data[5]));
+			input_report_abs(dev, ABS_HAT0X,
+					 !(s & data[6]) - !(s & data[7]));
+			input_report_abs(dev, ABS_HAT0Y,
+					 !(s & data[4]) - !(s & data[5]));
 
 			for (j = 0; j < 10; j++)
-				input_report_key(dev, gc_n64_btn[j], s & data[gc_n64_bytes[j]]);
+				input_report_key(dev, gc_n64_btn[j],
+						 s & data[gc_n64_bytes[j]]);
 
 			input_sync(dev);
 		}
 	}
 }
 
+static int gc_n64_play_effect(struct input_dev *dev, void *data,
+			      struct ff_effect *effect)
+{
+	int i;
+	unsigned long flags;
+	struct gc *gc = input_get_drvdata(dev);
+	struct gc_subdev *sdev = data;
+	unsigned char target = 1 << sdev->idx; /* select desired pin */
+
+	if (effect->type == FF_RUMBLE) {
+		struct ff_rumble_effect *rumble = &effect->u.rumble;
+		unsigned int cmd =
+			rumble->strong_magnitude || rumble->weak_magnitude ?
+			GC_N64_CMD_01 : GC_N64_CMD_00;
+
+		local_irq_save(flags);
+
+		/* Init Rumble - 0x03, 0x80, 0x01, (34)0x80 */
+		gc_n64_send_command(gc, GC_N64_CMD_03, target);
+		gc_n64_send_command(gc, GC_N64_CMD_80, target);
+		gc_n64_send_command(gc, GC_N64_CMD_01, target);
+		for (i = 0; i < 32; i++)
+			gc_n64_send_command(gc, GC_N64_CMD_80, target);
+		gc_n64_send_stop_bit(gc, target);
+
+		udelay(GC_N64_DELAY);
+
+		/* Now start or stop it - 0x03, 0xc0, 0zx1b, (32)0x01/0x00 */
+		gc_n64_send_command(gc, GC_N64_CMD_03, target);
+		gc_n64_send_command(gc, GC_N64_CMD_c0, target);
+		gc_n64_send_command(gc, GC_N64_CMD_1b, target);
+		for (i = 0; i < 32; i++)
+			gc_n64_send_command(gc, cmd, target);
+		gc_n64_send_stop_bit(gc, target);
+
+		local_irq_restore(flags);
+
+	}
+
+	return 0;
+}
+
+static int __init gc_n64_init_ff(struct input_dev *dev, int i)
+{
+	struct gc_subdev *sdev;
+	int err;
+
+	sdev = kmalloc(sizeof(*sdev), GFP_KERNEL);
+	if (!sdev)
+		return -ENOMEM;
+
+	sdev->idx = i;
+
+	input_set_capability(dev, EV_FF, FF_RUMBLE);
+
+	err = input_ff_create_memless(dev, sdev, gc_n64_play_effect);
+	if (err) {
+		kfree(sdev);
+		return err;
+	}
+
+	return 0;
+}
+
 /*
  * NES/SNES support.
  */
@@ -214,9 +342,11 @@ static void gc_n64_process_packet(struct
 #define GC_NES_CLOCK	0x01
 #define GC_NES_LATCH	0x02
 
-static unsigned char gc_nes_bytes[] = { 0, 1, 2, 3 };
-static unsigned char gc_snes_bytes[] = { 8, 0, 2, 3, 9, 1, 10, 11 };
-static short gc_snes_btn[] = { BTN_A, BTN_B, BTN_SELECT, BTN_START, BTN_X, BTN_Y, BTN_TL, BTN_TR };
+static const unsigned char gc_nes_bytes[] = { 0, 1, 2, 3 };
+static const unsigned char gc_snes_bytes[] = { 8, 0, 2, 3, 9, 1, 10, 11 };
+static const short gc_snes_btn[] = {
+	BTN_A, BTN_B, BTN_SELECT, BTN_START, BTN_X, BTN_Y, BTN_TL, BTN_TR
+};
 
 /*
  * gc_nes_read_packet() reads a NES/SNES packet.
@@ -244,40 +374,51 @@ static void gc_nes_read_packet(struct gc
 static void gc_nes_process_packet(struct gc *gc)
 {
 	unsigned char data[GC_SNESMOUSE_LENGTH];
+	struct gc_pad *pad;
 	struct input_dev *dev;
 	int i, j, s, len;
 	char x_rel, y_rel;
 
-	len = gc->pads[GC_SNESMOUSE] ? GC_SNESMOUSE_LENGTH :
-			(gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH);
+	len = gc->pad_count[GC_SNESMOUSE] ? GC_SNESMOUSE_LENGTH :
+			(gc->pad_count[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH);
 
 	gc_nes_read_packet(gc, len, data);
 
 	for (i = 0; i < GC_MAX_DEVICES; i++) {
 
+		pad = &gc->pads[i];
 		dev = gc->dev[i];
-		if (!dev)
-			continue;
-
 		s = gc_status_bit[i];
 
-		if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) {
+		switch (pad->type) {
+
+		case GC_NES:
+
 			input_report_abs(dev, ABS_X, !(s & data[6]) - !(s & data[7]));
 			input_report_abs(dev, ABS_Y, !(s & data[4]) - !(s & data[5]));
-		}
 
-		if (s & gc->pads[GC_NES])
 			for (j = 0; j < 4; j++)
-				input_report_key(dev, gc_snes_btn[j], s & data[gc_nes_bytes[j]]);
+				input_report_key(dev, gc_snes_btn[j],
+						 s & data[gc_nes_bytes[j]]);
+			input_sync(dev);
+			break;
+
+		case GC_SNES:
+
+			input_report_abs(dev, ABS_X, !(s & data[6]) - !(s & data[7]));
+			input_report_abs(dev, ABS_Y, !(s & data[4]) - !(s & data[5]));
 
-		if (s & gc->pads[GC_SNES])
 			for (j = 0; j < 8; j++)
-				input_report_key(dev, gc_snes_btn[j], s & data[gc_snes_bytes[j]]);
+				input_report_key(dev, gc_snes_btn[j],
+						 s & data[gc_snes_bytes[j]]);
+			input_sync(dev);
+			break;
 
-		if (s & gc->pads[GC_SNESMOUSE]) {
+		case GC_SNESMOUSE:
 			/*
-			 * The 4 unused bits from SNES controllers appear to be ID bits
-			 * so use them to make sure iwe are dealing with a mouse.
+			 * The 4 unused bits from SNES controllers appear
+			 * to be ID bits so use them to make sure we are
+			 * dealing with a mouse.
 			 * gamepad is connected. This is important since
 			 * my SNES gamepad sends 1's for bits 16-31, which
 			 * cause the mouse pointer to quickly move to the
@@ -310,9 +451,14 @@ static void gc_nes_process_packet(struct
 						y_rel = -y_rel;
 					input_report_rel(dev, REL_Y, y_rel);
 				}
+
+				input_sync(dev);
 			}
+			break;
+
+		default:
+			break;
 		}
-		input_sync(dev);
 	}
 }
 
@@ -340,29 +486,35 @@ static void gc_multi_read_packet(struct
 static void gc_multi_process_packet(struct gc *gc)
 {
 	unsigned char data[GC_MULTI2_LENGTH];
+	int data_len = gc->pad_count[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH;
+	struct gc_pad *pad;
 	struct input_dev *dev;
 	int i, s;
 
-	gc_multi_read_packet(gc, gc->pads[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH, data);
+	gc_multi_read_packet(gc, data_len, data);
 
 	for (i = 0; i < GC_MAX_DEVICES; i++) {
-
-		dev = gc->dev[i];
-		if (!dev)
-			continue;
-
+		pad = &gc->pads[i];
+		dev = pad->dev;
 		s = gc_status_bit[i];
 
-		if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) {
-			input_report_abs(dev, ABS_X,  !(s & data[2]) - !(s & data[3]));
-			input_report_abs(dev, ABS_Y,  !(s & data[0]) - !(s & data[1]));
-			input_report_key(dev, BTN_TRIGGER, s & data[4]);
-		}
-
-		if (s & gc->pads[GC_MULTI2])
+		switch (pad->type) {
+		case GC_MULTI2:
 			input_report_key(dev, BTN_THUMB, s & data[5]);
+			/* fall through */
 
-		input_sync(dev);
+		case GC_MULTI:
+			input_report_abs(dev, ABS_X,
+					 !(s & data[2]) - !(s & data[3]));
+			input_report_abs(dev, ABS_Y,
+					 !(s & data[0]) - !(s & data[1]));
+			input_report_key(dev, BTN_TRIGGER, s & data[4]);
+			input_sync(dev);
+			break;
+
+		default:
+			break;
+		}
 	}
 }
 
@@ -398,30 +550,41 @@ static int gc_psx_delay = GC_PSX_DELAY;
 module_param_named(psx_delay, gc_psx_delay, uint, 0);
 MODULE_PARM_DESC(psx_delay, "Delay when accessing Sony PSX controller (usecs)");
 
-static short gc_psx_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y };
-static short gc_psx_btn[] = { BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y,
-				BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR };
-static short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 };
+static const short gc_psx_abs[] = {
+	ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y
+};
+static const short gc_psx_btn[] = {
+	BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y,
+	BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR
+};
+static const short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 };
 
 /*
  * gc_psx_command() writes 8bit command and reads 8bit data from
  * the psx pad.
  */
 
-static void gc_psx_command(struct gc *gc, int b, unsigned char data[GC_MAX_DEVICES])
+static void gc_psx_command(struct gc *gc, int b, unsigned char *data)
 {
+	struct parport *port = gc->pd->port;
 	int i, j, cmd, read;
 
-	for (i = 0; i < GC_MAX_DEVICES; i++)
-		data[i] = 0;
+	memset(data, 0, GC_MAX_DEVICES);
 
 	for (i = 0; i < GC_PSX_LENGTH; i++, b >>= 1) {
 		cmd = (b & 1) ? GC_PSX_COMMAND : 0;
-		parport_write_data(gc->pd->port, cmd | GC_PSX_POWER);
+		parport_write_data(port, cmd | GC_PSX_POWER);
 		udelay(gc_psx_delay);
-		read = parport_read_status(gc->pd->port) ^ 0x80;
-		for (j = 0; j < GC_MAX_DEVICES; j++)
-			data[j] |= (read & gc_status_bit[j] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) ? (1 << i) : 0;
+
+		read = parport_read_status(port) ^ 0x80;
+
+		for (j = 0; j < GC_MAX_DEVICES; j++) {
+			struct gc_pad *pad = &gc->pads[i];
+
+			if (pad->type == GC_PSX || pad->type == GC_DDR)
+				data[j] |= (read & gc_status_bit[j]) ? (1 << i) : 0;
+		}
+
 		parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER);
 		udelay(gc_psx_delay);
 	}
@@ -432,31 +595,40 @@ static void gc_psx_command(struct gc *gc
  * device identifier code.
  */
 
-static void gc_psx_read_packet(struct gc *gc, unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES],
+static void gc_psx_read_packet(struct gc *gc,
+			       unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES],
 			       unsigned char id[GC_MAX_DEVICES])
 {
 	int i, j, max_len = 0;
 	unsigned long flags;
 	unsigned char data2[GC_MAX_DEVICES];
 
-	parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER);	/* Select pad */
+	/* Select pad */
+	parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER);
 	udelay(gc_psx_delay);
-	parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER);			/* Deselect, begin command */
+	/* Deselect, begin command */
+	parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER);
 	udelay(gc_psx_delay);
 
 	local_irq_save(flags);
 
-	gc_psx_command(gc, 0x01, data2);						/* Access pad */
-	gc_psx_command(gc, 0x42, id);							/* Get device ids */
-	gc_psx_command(gc, 0, data2);							/* Dump status */
+	gc_psx_command(gc, 0x01, data2);	/* Access pad */
+	gc_psx_command(gc, 0x42, id);		/* Get device ids */
+	gc_psx_command(gc, 0, data2);		/* Dump status */
 
-	for (i =0; i < GC_MAX_DEVICES; i++)								/* Find the longest pad */
-		if((gc_status_bit[i] & (gc->pads[GC_PSX] | gc->pads[GC_DDR]))
-			&& (GC_PSX_LEN(id[i]) > max_len)
-			&& (GC_PSX_LEN(id[i]) <= GC_PSX_BYTES))
+	/* Find the longest pad */
+	for (i = 0; i < GC_MAX_DEVICES; i++) {
+		struct gc_pad *pad = &gc->pads[i];
+
+		if ((pad->type == GC_PSX || pad->type == GC_DDR) &&
+		    GC_PSX_LEN(id[i]) > max_len &&
+		    GC_PSX_LEN(id[i]) <= GC_PSX_BYTES) {
 			max_len = GC_PSX_LEN(id[i]);
+		}
+	}
 
-	for (i = 0; i < max_len; i++) {						/* Read in all the data */
+	/* Read in all the data */
+	for (i = 0; i < max_len; i++) {
 		gc_psx_command(gc, 0, data2);
 		for (j = 0; j < GC_MAX_DEVICES; j++)
 			data[j][i] = data2[j];
@@ -466,86 +638,104 @@ static void gc_psx_read_packet(struct gc
 
 	parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER);
 
-	for(i = 0; i < GC_MAX_DEVICES; i++)								/* Set id's to the real value */
+	/* Set id's to the real value */
+	for (i = 0; i < GC_MAX_DEVICES; i++)
 		id[i] = GC_PSX_ID(id[i]);
 }
 
-static void gc_psx_process_packet(struct gc *gc)
+static void gc_psx_report_one(struct gc_pad *pad, unsigned char psx_type,
+			      unsigned char *data)
 {
-	unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES];
-	unsigned char id[GC_MAX_DEVICES];
-	struct input_dev *dev;
-	int i, j;
+	struct input_dev *dev = pad->dev;
+	int i;
 
-	gc_psx_read_packet(gc, data, id);
+	switch (psx_type) {
 
-	for (i = 0; i < GC_MAX_DEVICES; i++) {
+	case GC_PSX_RUMBLE:
 
-		dev = gc->dev[i];
-		if (!dev)
-			continue;
+		input_report_key(dev, BTN_THUMBL, ~data[0] & 0x04);
+		input_report_key(dev, BTN_THUMBR, ~data[0] & 0x02);
 
-		switch (id[i]) {
+	case GC_PSX_NEGCON:
+	case GC_PSX_ANALOG:
 
-			case GC_PSX_RUMBLE:
+		if (pad->type == GC_DDR) {
+			for (i = 0; i < 4; i++)
+				input_report_key(dev, gc_psx_ddr_btn[i],
+						 ~data[0] & (0x10 << i));
+		} else {
+			for (i = 0; i < 4; i++)
+				input_report_abs(dev, gc_psx_abs[i + 2],
+						 data[i + 2]);
 
-				input_report_key(dev, BTN_THUMBL, ~data[i][0] & 0x04);
-				input_report_key(dev, BTN_THUMBR, ~data[i][0] & 0x02);
+			input_report_abs(dev, ABS_X,
+				!!(data[0] & 0x80) * 128 + !(data[0] & 0x20) * 127);
+			input_report_abs(dev, ABS_Y,
+				!!(data[0] & 0x10) * 128 + !(data[0] & 0x40) * 127);
+		}
 
-			case GC_PSX_NEGCON:
-			case GC_PSX_ANALOG:
+		for (i = 0; i < 8; i++)
+			input_report_key(dev, gc_psx_btn[i], ~data[1] & (1 << i));
 
-				if (gc->pads[GC_DDR] & gc_status_bit[i]) {
-					for(j = 0; j < 4; j++)
-						input_report_key(dev, gc_psx_ddr_btn[j], ~data[i][0] & (0x10 << j));
-				} else {
-					for (j = 0; j < 4; j++)
-						input_report_abs(dev, gc_psx_abs[j + 2], data[i][j + 2]);
+		input_report_key(dev, BTN_START,  ~data[0] & 0x08);
+		input_report_key(dev, BTN_SELECT, ~data[0] & 0x01);
 
-					input_report_abs(dev, ABS_X, 128 + !(data[i][0] & 0x20) * 127 - !(data[i][0] & 0x80) * 128);
-					input_report_abs(dev, ABS_Y, 128 + !(data[i][0] & 0x40) * 127 - !(data[i][0] & 0x10) * 128);
-				}
+		input_sync(dev);
 
-				for (j = 0; j < 8; j++)
-					input_report_key(dev, gc_psx_btn[j], ~data[i][1] & (1 << j));
+		break;
 
-				input_report_key(dev, BTN_START,  ~data[i][0] & 0x08);
-				input_report_key(dev, BTN_SELECT, ~data[i][0] & 0x01);
+	case GC_PSX_NORMAL:
 
-				input_sync(dev);
+		if (pad->type == GC_DDR) {
+			for (i = 0; i < 4; i++)
+				input_report_key(dev, gc_psx_ddr_btn[i],
+						 ~data[0] & (0x10 << i));
+		} else {
+			input_report_abs(dev, ABS_X,
+				!!(data[0] & 0x80) * 128 + !(data[0] & 0x20) * 127);
+			input_report_abs(dev, ABS_Y,
+				!!(data[0] & 0x10) * 128 + !(data[0] & 0x40) * 127);
 
-				break;
+			/*
+			 * For some reason if the extra axes are left unset
+			 * they drift.
+			 * for (i = 0; i < 4; i++)
+				input_report_abs(dev, gc_psx_abs[i + 2], 128);
+			 * This needs to be debugged properly,
+			 * maybe fuzz processing needs to be done
+			 * in input_sync()
+			 *				 --vojtech
+			 */
+		}
 
-			case GC_PSX_NORMAL:
-				if (gc->pads[GC_DDR] & gc_status_bit[i]) {
-					for(j = 0; j < 4; j++)
-						input_report_key(dev, gc_psx_ddr_btn[j], ~data[i][0] & (0x10 << j));
-				} else {
-					input_report_abs(dev, ABS_X, 128 + !(data[i][0] & 0x20) * 127 - !(data[i][0] & 0x80) * 128);
-					input_report_abs(dev, ABS_Y, 128 + !(data[i][0] & 0x40) * 127 - !(data[i][0] & 0x10) * 128);
+		for (i = 0; i < 8; i++)
+			input_report_key(dev, gc_psx_btn[i], ~data[1] & (1 << i));
 
-					/* for some reason if the extra axes are left unset they drift */
-					/* for (j = 0; j < 4; j++)
-						input_report_abs(dev, gc_psx_abs[j + 2], 128);
-					 * This needs to be debugged properly,
-					 * maybe fuzz processing needs to be done in input_sync()
-					 *				 --vojtech
-					 */
-				}
+		input_report_key(dev, BTN_START,  ~data[0] & 0x08);
+		input_report_key(dev, BTN_SELECT, ~data[0] & 0x01);
 
-				for (j = 0; j < 8; j++)
-					input_report_key(dev, gc_psx_btn[j], ~data[i][1] & (1 << j));
+		input_sync(dev);
 
-				input_report_key(dev, BTN_START,  ~data[i][0] & 0x08);
-				input_report_key(dev, BTN_SELECT, ~data[i][0] & 0x01);
+		break;
 
-				input_sync(dev);
+	default: /* not a pad, ignore */
+		break;
+	}
+}
 
-				break;
+static void gc_psx_process_packet(struct gc *gc)
+{
+	unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES];
+	unsigned char id[GC_MAX_DEVICES];
+	struct gc_pad *pad;
+	int i;
 
-			case 0: /* not a pad, ignore */
-				break;
-		}
+	gc_psx_read_packet(gc, data, id);
+
+	for (i = 0; i < GC_MAX_DEVICES; i++) {
+		pad = &gc->pads[i];
+		if (pad->type == GC_PSX || pad->type == GC_DDR)
+			gc_psx_report_one(pad, id[i], data[i]);
 	}
 }
 
@@ -561,28 +751,31 @@ static void gc_timer(unsigned long priva
  * N64 pads - must be read first, any read confuses them for 200 us
  */
 
-	if (gc->pads[GC_N64])
+	if (gc->pad_count[GC_N64])
 		gc_n64_process_packet(gc);
 
 /*
  * NES and SNES pads or mouse
  */
 
-	if (gc->pads[GC_NES] || gc->pads[GC_SNES] || gc->pads[GC_SNESMOUSE])
+	if (gc->pad_count[GC_NES] ||
+	    gc->pad_count[GC_SNES] ||
+	    gc->pad_count[GC_SNESMOUSE]) {
 		gc_nes_process_packet(gc);
+	}
 
 /*
  * Multi and Multi2 joysticks
  */
 
-	if (gc->pads[GC_MULTI] || gc->pads[GC_MULTI2])
+	if (gc->pad_count[GC_MULTI] || gc->pad_count[GC_MULTI2])
 		gc_multi_process_packet(gc);
 
 /*
  * PSX controllers
  */
 
-	if (gc->pads[GC_PSX] || gc->pads[GC_DDR])
+	if (gc->pad_count[GC_PSX] || gc->pad_count[GC_DDR])
 		gc_psx_process_packet(gc);
 
 	mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME);
@@ -622,25 +815,29 @@ static void gc_close(struct input_dev *d
 
 static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
 {
+	struct gc_pad *pad = &gc->pads[idx];
 	struct input_dev *input_dev;
 	int i;
+	int err;
 
-	if (!pad_type)
-		return 0;
-
-	if (pad_type < 1 || pad_type > GC_MAX) {
-		printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", pad_type);
+	if (pad_type < 1 || pad_type >= GC_MAX) {
+		pr_err("Pad type %d unknown\n", pad_type);
 		return -EINVAL;
 	}
 
-	gc->dev[idx] = input_dev = input_allocate_device();
+	pad->dev = input_dev = input_allocate_device();
 	if (!input_dev) {
-		printk(KERN_ERR "gamecon.c: Not enough memory for input device\n");
+		pr_err("Not enough memory for input device\n");
 		return -ENOMEM;
 	}
 
+	pad->type = pad_type;
+
+	snprintf(pad->phys, sizeof(pad->phys),
+		 "%s/input%d", gc->pd->port->name, idx);
+
 	input_dev->name = gc_names[pad_type];
-	input_dev->phys = gc->phys[idx];
+	input_dev->phys = pad->phys;
 	input_dev->id.bustype = BUS_PARPORT;
 	input_dev->id.vendor = 0x0001;
 	input_dev->id.product = pad_type;
@@ -659,61 +856,76 @@ static int __init gc_setup_pad(struct gc
 	} else
 		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
 
-	gc->pads[0] |= gc_status_bit[idx];
-	gc->pads[pad_type] |= gc_status_bit[idx];
+	gc->pad_count[pad_type]++;
 
 	switch (pad_type) {
 
-		case GC_N64:
-			for (i = 0; i < 10; i++)
-				set_bit(gc_n64_btn[i], input_dev->keybit);
+	case GC_N64:
+		for (i = 0; i < 10; i++)
+			__set_bit(gc_n64_btn[i], input_dev->keybit);
 
-			for (i = 0; i < 2; i++) {
-				input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2);
-				input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0);
-			}
+		for (i = 0; i < 2; i++) {
+			input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2);
+			input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0);
+		}
 
-			break;
+		err = gc_n64_init_ff(input_dev, idx);
+		if (err) {
+			pr_warning("Failed to initiate rumble for N64 device %d\n", idx);
+			goto err_free_dev;
+		}
 
-		case GC_SNESMOUSE:
-			set_bit(BTN_LEFT, input_dev->keybit);
-			set_bit(BTN_RIGHT, input_dev->keybit);
-			set_bit(REL_X, input_dev->relbit);
-			set_bit(REL_Y, input_dev->relbit);
-			break;
+		break;
 
-		case GC_SNES:
-			for (i = 4; i < 8; i++)
-				set_bit(gc_snes_btn[i], input_dev->keybit);
-		case GC_NES:
-			for (i = 0; i < 4; i++)
-				set_bit(gc_snes_btn[i], input_dev->keybit);
-			break;
+	case GC_SNESMOUSE:
+		__set_bit(BTN_LEFT, input_dev->keybit);
+		__set_bit(BTN_RIGHT, input_dev->keybit);
+		__set_bit(REL_X, input_dev->relbit);
+		__set_bit(REL_Y, input_dev->relbit);
+		break;
 
-		case GC_MULTI2:
-			set_bit(BTN_THUMB, input_dev->keybit);
-		case GC_MULTI:
-			set_bit(BTN_TRIGGER, input_dev->keybit);
-			break;
+	case GC_SNES:
+		for (i = 4; i < 8; i++)
+			__set_bit(gc_snes_btn[i], input_dev->keybit);
+	case GC_NES:
+		for (i = 0; i < 4; i++)
+			__set_bit(gc_snes_btn[i], input_dev->keybit);
+		break;
 
-		case GC_PSX:
-			for (i = 0; i < 6; i++)
-				input_set_abs_params(input_dev, gc_psx_abs[i], 4, 252, 0, 2);
-			for (i = 0; i < 12; i++)
-				set_bit(gc_psx_btn[i], input_dev->keybit);
+	case GC_MULTI2:
+		__set_bit(BTN_THUMB, input_dev->keybit);
+	case GC_MULTI:
+		__set_bit(BTN_TRIGGER, input_dev->keybit);
+		break;
 
-			break;
+	case GC_PSX:
+		for (i = 0; i < 6; i++)
+			input_set_abs_params(input_dev,
+					     gc_psx_abs[i], 4, 252, 0, 2);
+		for (i = 0; i < 12; i++)
+			__set_bit(gc_psx_btn[i], input_dev->keybit);
 
-		case GC_DDR:
-			for (i = 0; i < 4; i++)
-				set_bit(gc_psx_ddr_btn[i], input_dev->keybit);
-			for (i = 0; i < 12; i++)
-				set_bit(gc_psx_btn[i], input_dev->keybit);
+		break;
 
-			break;
+	case GC_DDR:
+		for (i = 0; i < 4; i++)
+			__set_bit(gc_psx_ddr_btn[i], input_dev->keybit);
+		for (i = 0; i < 12; i++)
+			__set_bit(gc_psx_btn[i], input_dev->keybit);
+
+		break;
 	}
 
+	err = input_register_device(pad->dev);
+	if (err)
+		goto err_free_dev;
+
 	return 0;
+
+err_free_dev:
+	input_free_device(pad->dev);
+	pad->dev = NULL;
+	return err;
 }
 
 static struct gc __init *gc_probe(int parport, int *pads, int n_pads)
@@ -722,52 +934,47 @@ static struct gc __init *gc_probe(int pa
 	struct parport *pp;
 	struct pardevice *pd;
 	int i;
+	int count = 0;
 	int err;
 
 	pp = parport_find_number(parport);
 	if (!pp) {
-		printk(KERN_ERR "gamecon.c: no such parport\n");
+		pr_err("no such parport %d\n", parport);
 		err = -EINVAL;
 		goto err_out;
 	}
 
 	pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
 	if (!pd) {
-		printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n");
+		pr_err("parport busy already - lp.o loaded?\n");
 		err = -EBUSY;
 		goto err_put_pp;
 	}
 
 	gc = kzalloc(sizeof(struct gc), GFP_KERNEL);
 	if (!gc) {
-		printk(KERN_ERR "gamecon.c: Not enough memory\n");
+		pr_err("Not enough memory\n");
 		err = -ENOMEM;
 		goto err_unreg_pardev;
 	}
 
 	mutex_init(&gc->mutex);
 	gc->pd = pd;
-	init_timer(&gc->timer);
-	gc->timer.data = (long) gc;
-	gc->timer.function = gc_timer;
+	setup_timer(&gc->timer, gc_timer, (long) gc);
 
 	for (i = 0; i < n_pads && i < GC_MAX_DEVICES; i++) {
 		if (!pads[i])
 			continue;
 
-		snprintf(gc->phys[i], sizeof(gc->phys[i]),
-			 "%s/input%d", gc->pd->port->name, i);
 		err = gc_setup_pad(gc, i, pads[i]);
 		if (err)
 			goto err_unreg_devs;
 
-		err = input_register_device(gc->dev[i]);
-		if (err)
-			goto err_free_dev;
+		count++;
 	}
 
-	if (!gc->pads[0]) {
-		printk(KERN_ERR "gamecon.c: No valid devices specified\n");
+	if (count == 0) {
+		pr_err("No valid devices specified\n");
 		err = -EINVAL;
 		goto err_free_gc;
 	}
@@ -775,12 +982,10 @@ static struct gc __init *gc_probe(int pa
 	parport_put_port(pp);
 	return gc;
 
- err_free_dev:
-	input_free_device(gc->dev[i]);
  err_unreg_devs:
 	while (--i >= 0)
-		if (gc->dev[i])
-			input_unregister_device(gc->dev[i]);
+		if (gc->pads[i].dev)
+			input_unregister_device(gc->pads[i].dev);
  err_free_gc:
 	kfree(gc);
  err_unreg_pardev:
@@ -796,8 +1001,8 @@ static void gc_remove(struct gc *gc)
 	int i;
 
 	for (i = 0; i < GC_MAX_DEVICES; i++)
-		if (gc->dev[i])
-			input_unregister_device(gc->dev[i]);
+		if (gc->pads[i].dev)
+			input_unregister_device(gc->pads[i].dev);
 	parport_unregister_device(gc->pd);
 	kfree(gc);
 }
@@ -813,7 +1018,7 @@ static int __init gc_init(void)
 			continue;
 
 		if (gc_cfg[i].nargs < 2) {
-			printk(KERN_ERR "gamecon.c: at least one device must be specified\n");
+			pr_err("at least one device must be specified\n");
 			err = -EINVAL;
 			break;
 		}
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/joystick/iforce/iforce-main.c linux-libre-2.6.34-gnu1/drivers/input/joystick/iforce/iforce-main.c
--- linux-libre-2.6.33-gnu1/drivers/input/joystick/iforce/iforce-main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/joystick/iforce/iforce-main.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,6 +54,9 @@ static signed short btn_avb_wheel[] =
 static signed short abs_joystick[] =
 { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 };
 
+static signed short abs_joystick_rudder[] =
+{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, -1 };
+
 static signed short abs_avb_pegasus[] =
 { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y,
   ABS_HAT1X, ABS_HAT1Y, -1 };
@@ -76,8 +79,9 @@ static struct iforce_device iforce_devic
 	{ 0x061c, 0xc0a4, "ACT LABS Force RS",                          btn_wheel, abs_wheel, ff_iforce }, //?
 	{ 0x061c, 0xc084, "ACT LABS Force RS",				btn_wheel, abs_wheel, ff_iforce },
 	{ 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback",	btn_wheel, abs_wheel, ff_iforce }, //?
+	{ 0x06f8, 0x0001, "Guillemot Jet Leader Force Feedback",	btn_joystick, abs_joystick_rudder, ff_iforce },
 	{ 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel",	btn_wheel, abs_wheel, ff_iforce }, //?
-	{ 0x06f8, 0x0004, "Gullemot Jet Leader 3D",			btn_joystick, abs_joystick, ff_iforce }, //?
+	{ 0x06f8, 0xa302, "Guillemot Jet Leader 3D",			btn_joystick, abs_joystick, ff_iforce }, //?
 	{ 0x06d6, 0x29bc, "Trust Force Feedback Race Master",		btn_wheel, abs_wheel, ff_iforce },
 	{ 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]",		btn_joystick, abs_joystick, ff_iforce }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/joystick/iforce/iforce-usb.c linux-libre-2.6.34-gnu1/drivers/input/joystick/iforce/iforce-usb.c
--- linux-libre-2.6.33-gnu1/drivers/input/joystick/iforce/iforce-usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/joystick/iforce/iforce-usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -212,6 +212,7 @@ static struct usb_device_id iforce_usb_i
 	{ USB_DEVICE(0x061c, 0xc0a4) },         /* ACT LABS Force RS */
 	{ USB_DEVICE(0x061c, 0xc084) },         /* ACT LABS Force RS */
 	{ USB_DEVICE(0x06f8, 0x0001) },		/* Guillemot Race Leader Force Feedback */
+	{ USB_DEVICE(0x06f8, 0x0003) },		/* Guillemot Jet Leader Force Feedback */
 	{ USB_DEVICE(0x06f8, 0x0004) },		/* Guillemot Force Feedback Racing Wheel */
 	{ USB_DEVICE(0x06f8, 0xa302) },		/* Guillemot Jet Leader 3D */
 	{ }					/* Terminating entry */
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/joystick/Kconfig linux-libre-2.6.34-gnu1/drivers/input/joystick/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/input/joystick/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/joystick/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -221,6 +221,7 @@ config JOYSTICK_DB9
 config JOYSTICK_GAMECON
 	tristate "Multisystem, NES, SNES, N64, PSX joysticks and gamepads"
 	depends on PARPORT
+	select INPUT_FF_MEMLESS
 	---help---
 	  Say Y here if you have a Nintendo Entertainment System gamepad,
 	  Super Nintendo Entertainment System gamepad, Nintendo 64 gamepad,
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/joystick/turbografx.c linux-libre-2.6.34-gnu1/drivers/input/joystick/turbografx.c
--- linux-libre-2.6.33-gnu1/drivers/input/joystick/turbografx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/joystick/turbografx.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("TurboGraFX parallel port interface driver");
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/joystick/xpad.c linux-libre-2.6.34-gnu1/drivers/input/joystick/xpad.c
--- linux-libre-2.6.33-gnu1/drivers/input/joystick/xpad.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/joystick/xpad.c	2010-05-16 17:17:36.000000000 -0400
@@ -86,9 +86,8 @@
 
 /* xbox d-pads should map to buttons, as is required for DDR pads
    but we map them to axes when possible to simplify things */
-#define MAP_DPAD_TO_BUTTONS    0
-#define MAP_DPAD_TO_AXES       1
-#define MAP_DPAD_UNKNOWN       2
+#define MAP_DPAD_TO_BUTTONS		(1 << 0)
+#define MAP_TRIGGERS_TO_BUTTONS		(1 << 1)
 
 #define XTYPE_XBOX        0
 #define XTYPE_XBOX360     1
@@ -99,57 +98,61 @@ static int dpad_to_buttons;
 module_param(dpad_to_buttons, bool, S_IRUGO);
 MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads");
 
+static int triggers_to_buttons;
+module_param(triggers_to_buttons, bool, S_IRUGO);
+MODULE_PARM_DESC(triggers_to_buttons, "Map triggers to buttons rather than axes for unknown pads");
+
 static const struct xpad_device {
 	u16 idVendor;
 	u16 idProduct;
 	char *name;
-	u8 dpad_mapping;
+	u8 mapping;
 	u8 xtype;
 } xpad_device[] = {
-	{ 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+	{ 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", 0, XTYPE_XBOX },
+	{ 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX },
+	{ 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX },
+	{ 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX },
 	{ 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
 	{ 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
-	{ 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x046d, 0xc242, "Logitech Chillstream Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
-	{ 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+	{ 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
+	{ 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 },
+	{ 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX },
+	{ 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX },
+	{ 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX },
+	{ 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", 0, XTYPE_XBOX },
+	{ 0x0738, 0x4516, "Mad Catz Control Pad", 0, XTYPE_XBOX },
+	{ 0x0738, 0x4522, "Mad Catz LumiCON", 0, XTYPE_XBOX },
+	{ 0x0738, 0x4526, "Mad Catz Control Pad Pro", 0, XTYPE_XBOX },
+	{ 0x0738, 0x4536, "Mad Catz MicroCON", 0, XTYPE_XBOX },
 	{ 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
-	{ 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
-	{ 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
+	{ 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX },
+	{ 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
+	{ 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
 	{ 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
-	{ 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0c12, 0x880a, "Pelican Eclipse PL-2023", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
-	{ 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+	{ 0x0c12, 0x8802, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
+	{ 0x0c12, 0x880a, "Pelican Eclipse PL-2023", 0, XTYPE_XBOX },
+	{ 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
+	{ 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX },
+	{ 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX },
+	{ 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX },
+	{ 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", 0, XTYPE_XBOX },
+	{ 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX },
+	{ 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX },
+	{ 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
+	{ 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX },
+	{ 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX },
+	{ 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX },
+	{ 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", 0, XTYPE_XBOX },
 	{ 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
-	{ 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
+	{ 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", 0, XTYPE_XBOX360 },
 	{ 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
-	{ 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
-	{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
+	{ 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 },
+	{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
 	{ 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
-	{ 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
-	{ 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
-	{ 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN }
+	{ 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+	{ 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
+	{ 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
 };
 
 /* buttons shared with xbox and xbox360 */
@@ -165,13 +168,20 @@ static const signed short xpad_btn[] = {
 	-1			/* terminating entry */
 };
 
-/* only used if MAP_DPAD_TO_BUTTONS */
+/* used when dpad is mapped to nuttons */
 static const signed short xpad_btn_pad[] = {
 	BTN_LEFT, BTN_RIGHT,		/* d-pad left, right */
 	BTN_0, BTN_1,			/* d-pad up, down (XXX names??) */
 	-1				/* terminating entry */
 };
 
+/* used when triggers are mapped to buttons */
+static const signed short xpad_btn_triggers[] = {
+	BTN_TL2, BTN_TR2,		/* triggers left/right */
+	-1
+};
+
+
 static const signed short xpad360_btn[] = {  /* buttons for x360 controller */
 	BTN_TL, BTN_TR,		/* Button LB/RB */
 	BTN_MODE,		/* The big X button */
@@ -181,16 +191,21 @@ static const signed short xpad360_btn[]
 static const signed short xpad_abs[] = {
 	ABS_X, ABS_Y,		/* left stick */
 	ABS_RX, ABS_RY,		/* right stick */
-	ABS_Z, ABS_RZ,		/* triggers left/right */
 	-1			/* terminating entry */
 };
 
-/* only used if MAP_DPAD_TO_AXES */
+/* used when dpad is mapped to axes */
 static const signed short xpad_abs_pad[] = {
 	ABS_HAT0X, ABS_HAT0Y,	/* d-pad axes */
 	-1			/* terminating entry */
 };
 
+/* used when triggers are mapped to axes */
+static const signed short xpad_abs_triggers[] = {
+	ABS_Z, ABS_RZ,		/* triggers left/right */
+	-1
+};
+
 /* Xbox 360 has a vendor-specific class, so we cannot match it with only
  * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we
  * match against vendor id as well. Wired Xbox 360 devices have protocol 1,
@@ -246,7 +261,7 @@ struct usb_xpad {
 
 	char phys[64];			/* physical device path */
 
-	int dpad_mapping;		/* map d-pad to buttons or to axes */
+	int mapping;			/* map d-pad to buttons or to axes */
 	int xtype;			/* type of xbox device */
 };
 
@@ -277,20 +292,25 @@ static void xpad_process_packet(struct u
 			 ~(__s16) le16_to_cpup((__le16 *)(data + 18)));
 
 	/* triggers left/right */
-	input_report_abs(dev, ABS_Z, data[10]);
-	input_report_abs(dev, ABS_RZ, data[11]);
+	if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
+		input_report_key(dev, BTN_TL2, data[10]);
+		input_report_key(dev, BTN_TR2, data[11]);
+	} else {
+		input_report_abs(dev, ABS_Z, data[10]);
+		input_report_abs(dev, ABS_RZ, data[11]);
+	}
 
 	/* digital pad */
-	if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) {
-		input_report_abs(dev, ABS_HAT0X,
-				 !!(data[2] & 0x08) - !!(data[2] & 0x04));
-		input_report_abs(dev, ABS_HAT0Y,
-				 !!(data[2] & 0x02) - !!(data[2] & 0x01));
-	} else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ {
+	if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
 		input_report_key(dev, BTN_LEFT,  data[2] & 0x04);
 		input_report_key(dev, BTN_RIGHT, data[2] & 0x08);
 		input_report_key(dev, BTN_0,     data[2] & 0x01); /* up */
 		input_report_key(dev, BTN_1,     data[2] & 0x02); /* down */
+	} else {
+		input_report_abs(dev, ABS_HAT0X,
+				 !!(data[2] & 0x08) - !!(data[2] & 0x04));
+		input_report_abs(dev, ABS_HAT0Y,
+				 !!(data[2] & 0x02) - !!(data[2] & 0x01));
 	}
 
 	/* start/back buttons and stick press left/right */
@@ -328,17 +348,17 @@ static void xpad360_process_packet(struc
 	struct input_dev *dev = xpad->dev;
 
 	/* digital pad */
-	if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) {
-		input_report_abs(dev, ABS_HAT0X,
-				 !!(data[2] & 0x08) - !!(data[2] & 0x04));
-		input_report_abs(dev, ABS_HAT0Y,
-				 !!(data[2] & 0x02) - !!(data[2] & 0x01));
-	} else if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) {
+	if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
 		/* dpad as buttons (right, left, down, up) */
 		input_report_key(dev, BTN_LEFT, data[2] & 0x04);
 		input_report_key(dev, BTN_RIGHT, data[2] & 0x08);
 		input_report_key(dev, BTN_0, data[2] & 0x01);	/* up */
 		input_report_key(dev, BTN_1, data[2] & 0x02);	/* down */
+	} else {
+		input_report_abs(dev, ABS_HAT0X,
+				 !!(data[2] & 0x08) - !!(data[2] & 0x04));
+		input_report_abs(dev, ABS_HAT0Y,
+				 !!(data[2] & 0x02) - !!(data[2] & 0x01));
 	}
 
 	/* start/back buttons */
@@ -371,8 +391,13 @@ static void xpad360_process_packet(struc
 			 ~(__s16) le16_to_cpup((__le16 *)(data + 12)));
 
 	/* triggers left/right */
-	input_report_abs(dev, ABS_Z, data[4]);
-	input_report_abs(dev, ABS_RZ, data[5]);
+	if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
+		input_report_key(dev, BTN_TL2, data[4]);
+		input_report_key(dev, BTN_TR2, data[5]);
+	} else {
+		input_report_abs(dev, ABS_Z, data[4]);
+		input_report_abs(dev, ABS_RZ, data[5]);
+	}
 
 	input_sync(dev);
 }
@@ -505,7 +530,7 @@ static int xpad_init_output(struct usb_i
 	struct usb_endpoint_descriptor *ep_irq_out;
 	int error = -ENOMEM;
 
-	if (xpad->xtype != XTYPE_XBOX360)
+	if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX)
 		return 0;
 
 	xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN,
@@ -535,13 +560,13 @@ static int xpad_init_output(struct usb_i
 
 static void xpad_stop_output(struct usb_xpad *xpad)
 {
-	if (xpad->xtype == XTYPE_XBOX360)
+	if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX)
 		usb_kill_urb(xpad->irq_out);
 }
 
 static void xpad_deinit_output(struct usb_xpad *xpad)
 {
-	if (xpad->xtype == XTYPE_XBOX360) {
+	if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) {
 		usb_free_urb(xpad->irq_out);
 		usb_buffer_free(xpad->udev, XPAD_PKT_LEN,
 				xpad->odata, xpad->odata_dma);
@@ -554,24 +579,45 @@ static void xpad_stop_output(struct usb_
 #endif
 
 #ifdef CONFIG_JOYSTICK_XPAD_FF
-static int xpad_play_effect(struct input_dev *dev, void *data,
-			    struct ff_effect *effect)
+static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
 {
 	struct usb_xpad *xpad = input_get_drvdata(dev);
 
 	if (effect->type == FF_RUMBLE) {
 		__u16 strong = effect->u.rumble.strong_magnitude;
 		__u16 weak = effect->u.rumble.weak_magnitude;
-		xpad->odata[0] = 0x00;
-		xpad->odata[1] = 0x08;
-		xpad->odata[2] = 0x00;
-		xpad->odata[3] = strong / 256;
-		xpad->odata[4] = weak / 256;
-		xpad->odata[5] = 0x00;
-		xpad->odata[6] = 0x00;
-		xpad->odata[7] = 0x00;
-		xpad->irq_out->transfer_buffer_length = 8;
-		usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
+
+		switch (xpad->xtype) {
+
+		case XTYPE_XBOX:
+			xpad->odata[0] = 0x00;
+			xpad->odata[1] = 0x06;
+			xpad->odata[2] = 0x00;
+			xpad->odata[3] = strong / 256;	/* left actuator */
+			xpad->odata[4] = 0x00;
+			xpad->odata[5] = weak / 256;	/* right actuator */
+			xpad->irq_out->transfer_buffer_length = 6;
+
+			return usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
+
+		case XTYPE_XBOX360:
+			xpad->odata[0] = 0x00;
+			xpad->odata[1] = 0x08;
+			xpad->odata[2] = 0x00;
+			xpad->odata[3] = strong / 256;  /* left actuator? */
+			xpad->odata[4] = weak / 256;	/* right actuator? */
+			xpad->odata[5] = 0x00;
+			xpad->odata[6] = 0x00;
+			xpad->odata[7] = 0x00;
+			xpad->irq_out->transfer_buffer_length = 8;
+
+			return usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
+
+		default:
+			dbg("%s - rumble command sent to unsupported xpad type: %d",
+				__func__, xpad->xtype);
+			return -1;
+		}
 	}
 
 	return 0;
@@ -579,7 +625,7 @@ static int xpad_play_effect(struct input
 
 static int xpad_init_ff(struct usb_xpad *xpad)
 {
-	if (xpad->xtype != XTYPE_XBOX360)
+	if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX)
 		return 0;
 
 	input_set_capability(xpad->dev, EV_FF, FF_RUMBLE);
@@ -712,11 +758,11 @@ static void xpad_set_up_abs(struct input
 		input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128);
 		break;
 	case ABS_Z:
-	case ABS_RZ:	/* the triggers */
+	case ABS_RZ:	/* the triggers (if mapped to axes) */
 		input_set_abs_params(input_dev, abs, 0, 255, 0, 0);
 		break;
 	case ABS_HAT0X:
-	case ABS_HAT0Y:	/* the d-pad (only if MAP_DPAD_TO_AXES) */
+	case ABS_HAT0Y:	/* the d-pad (only if dpad is mapped to axes */
 		input_set_abs_params(input_dev, abs, -1, 1, 0, 0);
 		break;
 	}
@@ -752,10 +798,9 @@ static int xpad_probe(struct usb_interfa
 		goto fail2;
 
 	xpad->udev = udev;
-	xpad->dpad_mapping = xpad_device[i].dpad_mapping;
+	xpad->mapping = xpad_device[i].mapping;
 	xpad->xtype = xpad_device[i].xtype;
-	if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN)
-		xpad->dpad_mapping = !dpad_to_buttons;
+
 	if (xpad->xtype == XTYPE_UNKNOWN) {
 		if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
 			if (intf->cur_altsetting->desc.bInterfaceProtocol == 129)
@@ -764,7 +809,13 @@ static int xpad_probe(struct usb_interfa
 				xpad->xtype = XTYPE_XBOX360;
 		} else
 			xpad->xtype = XTYPE_XBOX;
+
+		if (dpad_to_buttons)
+			xpad->mapping |= MAP_DPAD_TO_BUTTONS;
+		if (triggers_to_buttons)
+			xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS;
 	}
+
 	xpad->dev = input_dev;
 	usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
 	strlcat(xpad->phys, "/input0", sizeof(xpad->phys));
@@ -781,25 +832,37 @@ static int xpad_probe(struct usb_interfa
 
 	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
-	/* set up buttons */
+	/* set up standard buttons and axes */
 	for (i = 0; xpad_common_btn[i] >= 0; i++)
-		set_bit(xpad_common_btn[i], input_dev->keybit);
-	if ((xpad->xtype == XTYPE_XBOX360) || (xpad->xtype == XTYPE_XBOX360W))
-		for (i = 0; xpad360_btn[i] >= 0; i++)
-			set_bit(xpad360_btn[i], input_dev->keybit);
-	else
-		for (i = 0; xpad_btn[i] >= 0; i++)
-			set_bit(xpad_btn[i], input_dev->keybit);
-	if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS)
-		for (i = 0; xpad_btn_pad[i] >= 0; i++)
-			set_bit(xpad_btn_pad[i], input_dev->keybit);
+		__set_bit(xpad_common_btn[i], input_dev->keybit);
 
-	/* set up axes */
 	for (i = 0; xpad_abs[i] >= 0; i++)
 		xpad_set_up_abs(input_dev, xpad_abs[i]);
-	if (xpad->dpad_mapping == MAP_DPAD_TO_AXES)
+
+	/* Now set up model-specific ones */
+	if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) {
+		for (i = 0; xpad360_btn[i] >= 0; i++)
+			__set_bit(xpad360_btn[i], input_dev->keybit);
+	} else {
+		for (i = 0; xpad_btn[i] >= 0; i++)
+			__set_bit(xpad_btn[i], input_dev->keybit);
+	}
+
+	if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
+		for (i = 0; xpad_btn_pad[i] >= 0; i++)
+			__set_bit(xpad_btn_pad[i], input_dev->keybit);
+	} else {
 		for (i = 0; xpad_abs_pad[i] >= 0; i++)
 		    xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
+	}
+
+	if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
+		for (i = 0; xpad_btn_triggers[i] >= 0; i++)
+			__set_bit(xpad_btn_triggers[i], input_dev->keybit);
+	} else {
+		for (i = 0; xpad_abs_triggers[i] >= 0; i++)
+			xpad_set_up_abs(input_dev, xpad_abs_triggers[i]);
+	}
 
 	error = xpad_init_output(intf, xpad);
 	if (error)
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/adp5520-keys.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/adp5520-keys.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/adp5520-keys.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/adp5520-keys.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/platform_device.h>
 #include <linux/input.h>
 #include <linux/mfd/adp5520.h>
+#include <linux/slab.h>
 
 struct adp5520_keys {
 	struct input_dev *input;
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/adp5588-keys.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/adp5588-keys.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/adp5588-keys.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/adp5588-keys.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 /*
  * File: drivers/input/keyboard/adp5588_keys.c
- * Description:  keypad driver for ADP5588 I2C QWERTY Keypad and IO Expander
+ * Description:  keypad driver for ADP5588 and ADP5587
+ *		 I2C QWERTY Keypad and IO Expander
  * Bugs: Enter bugs at http://blackfin.uclinux.org/
  *
  * Copyright (C) 2008-2009 Analog Devices Inc.
@@ -18,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/input.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include <linux/i2c/adp5588.h>
 
@@ -327,6 +329,7 @@ static const struct dev_pm_ops adp5588_d
 
 static const struct i2c_device_id adp5588_id[] = {
 	{ KBUILD_MODNAME, 0 },
+	{ "adp5587-keys", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, adp5588_id);
@@ -357,5 +360,5 @@ module_exit(adp5588_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("ADP5588 Keypad driver");
+MODULE_DESCRIPTION("ADP5588/87 Keypad driver");
 MODULE_ALIAS("platform:adp5588-keys");
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/atkbd.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/atkbd.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/atkbd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/atkbd.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,26 +40,26 @@ module_param_named(set, atkbd_set, int,
 MODULE_PARM_DESC(set, "Select keyboard code set (2 = default, 3 = PS/2 native)");
 
 #if defined(__i386__) || defined(__x86_64__) || defined(__hppa__)
-static int atkbd_reset;
+static bool atkbd_reset;
 #else
-static int atkbd_reset = 1;
+static bool atkbd_reset = true;
 #endif
 module_param_named(reset, atkbd_reset, bool, 0);
 MODULE_PARM_DESC(reset, "Reset keyboard during initialization");
 
-static int atkbd_softrepeat;
+static bool atkbd_softrepeat;
 module_param_named(softrepeat, atkbd_softrepeat, bool, 0);
 MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat");
 
-static int atkbd_softraw = 1;
+static bool atkbd_softraw = true;
 module_param_named(softraw, atkbd_softraw, bool, 0);
 MODULE_PARM_DESC(softraw, "Use software generated rawmode");
 
-static int atkbd_scroll;
+static bool atkbd_scroll;
 module_param_named(scroll, atkbd_scroll, bool, 0);
 MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards");
 
-static int atkbd_extra;
+static bool atkbd_extra;
 module_param_named(extra, atkbd_extra, bool, 0);
 MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards");
 
@@ -153,16 +153,16 @@ static const unsigned short atkbd_unxlat
 #define ATKBD_RET_HANGEUL	0xf2
 #define ATKBD_RET_ERR		0xff
 
-#define ATKBD_KEY_UNKNOWN	  0
+#define ATKBD_KEY_UNKNOWN	0
 #define ATKBD_KEY_NULL		255
 
-#define ATKBD_SCR_1		254
-#define ATKBD_SCR_2		253
-#define ATKBD_SCR_4		252
-#define ATKBD_SCR_8		251
-#define ATKBD_SCR_CLICK		250
-#define ATKBD_SCR_LEFT		249
-#define ATKBD_SCR_RIGHT		248
+#define ATKBD_SCR_1		0xfffe
+#define ATKBD_SCR_2		0xfffd
+#define ATKBD_SCR_4		0xfffc
+#define ATKBD_SCR_8		0xfffb
+#define ATKBD_SCR_CLICK		0xfffa
+#define ATKBD_SCR_LEFT		0xfff9
+#define ATKBD_SCR_RIGHT		0xfff8
 
 #define ATKBD_SPECIAL		ATKBD_SCR_RIGHT
 
@@ -177,7 +177,7 @@ static const unsigned short atkbd_unxlat
 #define ATKBD_XL_HANJA		0x20
 
 static const struct {
-	unsigned char keycode;
+	unsigned short keycode;
 	unsigned char set2;
 } atkbd_scroll_keys[] = {
 	{ ATKBD_SCR_1,     0xc5 },
@@ -206,18 +206,18 @@ struct atkbd {
 	unsigned short keycode[ATKBD_KEYMAP_SIZE];
 	DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE);
 	unsigned char set;
-	unsigned char translated;
-	unsigned char extra;
-	unsigned char write;
-	unsigned char softrepeat;
-	unsigned char softraw;
-	unsigned char scroll;
-	unsigned char enabled;
+	bool translated;
+	bool extra;
+	bool write;
+	bool softrepeat;
+	bool softraw;
+	bool scroll;
+	bool enabled;
 
 	/* Accessed only from interrupt */
 	unsigned char emul;
-	unsigned char resend;
-	unsigned char release;
+	bool resend;
+	bool release;
 	unsigned long xl_bit;
 	unsigned int last;
 	unsigned long time;
@@ -301,18 +301,18 @@ static const unsigned int xl_table[] = {
  * Checks if we should mangle the scancode to extract 'release' bit
  * in translated mode.
  */
-static int atkbd_need_xlate(unsigned long xl_bit, unsigned char code)
+static bool atkbd_need_xlate(unsigned long xl_bit, unsigned char code)
 {
 	int i;
 
 	if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1)
-		return 0;
+		return false;
 
 	for (i = 0; i < ARRAY_SIZE(xl_table); i++)
 		if (code == xl_table[i])
 			return test_bit(i, &xl_bit);
 
-	return 1;
+	return true;
 }
 
 /*
@@ -359,7 +359,7 @@ static unsigned int atkbd_compat_scancod
  */
 
 static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
-			unsigned int flags)
+				   unsigned int flags)
 {
 	struct atkbd *atkbd = serio_get_drvdata(serio);
 	struct input_dev *dev = atkbd->dev;
@@ -368,20 +368,18 @@ static irqreturn_t atkbd_interrupt(struc
 	int value;
 	unsigned short keycode;
 
-#ifdef ATKBD_DEBUG
-	printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
-#endif
+	dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, flags);
 
 #if !defined(__i386__) && !defined (__x86_64__)
 	if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) {
-		printk(KERN_WARNING "atkbd.c: frame/parity error: %02x\n", flags);
+		dev_warn(&serio->dev, "Frame/parity error: %02x\n", flags);
 		serio_write(serio, ATKBD_CMD_RESEND);
-		atkbd->resend = 1;
+		atkbd->resend = true;
 		goto out;
 	}
 
 	if (!flags && data == ATKBD_RET_ACK)
-		atkbd->resend = 0;
+		atkbd->resend = false;
 #endif
 
 	if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_ACK))
@@ -412,32 +410,32 @@ static irqreturn_t atkbd_interrupt(struc
 	}
 
 	switch (code) {
-		case ATKBD_RET_BAT:
-			atkbd->enabled = 0;
-			serio_reconnect(atkbd->ps2dev.serio);
-			goto out;
-		case ATKBD_RET_EMUL0:
-			atkbd->emul = 1;
-			goto out;
-		case ATKBD_RET_EMUL1:
-			atkbd->emul = 2;
-			goto out;
-		case ATKBD_RET_RELEASE:
-			atkbd->release = 1;
-			goto out;
-		case ATKBD_RET_ACK:
-		case ATKBD_RET_NAK:
-			if (printk_ratelimit())
-				printk(KERN_WARNING "atkbd.c: Spurious %s on %s. "
-				       "Some program might be trying access hardware directly.\n",
-				       data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
-			goto out;
-		case ATKBD_RET_ERR:
-			atkbd->err_count++;
-#ifdef ATKBD_DEBUG
-			printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
-#endif
-			goto out;
+	case ATKBD_RET_BAT:
+		atkbd->enabled = false;
+		serio_reconnect(atkbd->ps2dev.serio);
+		goto out;
+	case ATKBD_RET_EMUL0:
+		atkbd->emul = 1;
+		goto out;
+	case ATKBD_RET_EMUL1:
+		atkbd->emul = 2;
+		goto out;
+	case ATKBD_RET_RELEASE:
+		atkbd->release = true;
+		goto out;
+	case ATKBD_RET_ACK:
+	case ATKBD_RET_NAK:
+		if (printk_ratelimit())
+			dev_warn(&serio->dev,
+				 "Spurious %s on %s. "
+				 "Some program might be trying access hardware directly.\n",
+				 data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
+		goto out;
+	case ATKBD_RET_ERR:
+		atkbd->err_count++;
+		dev_dbg(&serio->dev, "Keyboard on %s reports too many keys pressed.\n",
+			serio->phys);
+		goto out;
 	}
 
 	code = atkbd_compat_scancode(atkbd, code);
@@ -451,71 +449,72 @@ static irqreturn_t atkbd_interrupt(struc
 		input_event(dev, EV_MSC, MSC_SCAN, code);
 
 	switch (keycode) {
-		case ATKBD_KEY_NULL:
-			break;
-		case ATKBD_KEY_UNKNOWN:
-			printk(KERN_WARNING
-			       "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n",
-			       atkbd->release ? "released" : "pressed",
-			       atkbd->translated ? "translated" : "raw",
-			       atkbd->set, code, serio->phys);
-			printk(KERN_WARNING
-			       "atkbd.c: Use 'setkeycodes %s%02x <keycode>' to make it known.\n",
-			       code & 0x80 ? "e0" : "", code & 0x7f);
-			input_sync(dev);
-			break;
-		case ATKBD_SCR_1:
-			scroll = 1 - atkbd->release * 2;
-			break;
-		case ATKBD_SCR_2:
-			scroll = 2 - atkbd->release * 4;
-			break;
-		case ATKBD_SCR_4:
-			scroll = 4 - atkbd->release * 8;
-			break;
-		case ATKBD_SCR_8:
-			scroll = 8 - atkbd->release * 16;
-			break;
-		case ATKBD_SCR_CLICK:
-			click = !atkbd->release;
-			break;
-		case ATKBD_SCR_LEFT:
-			hscroll = -1;
-			break;
-		case ATKBD_SCR_RIGHT:
-			hscroll = 1;
-			break;
-		default:
-			if (atkbd->release) {
-				value = 0;
-				atkbd->last = 0;
-			} else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) {
-				/* Workaround Toshiba laptop multiple keypress */
-				value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2;
-			} else {
-				value = 1;
-				atkbd->last = code;
-				atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2;
-			}
+	case ATKBD_KEY_NULL:
+		break;
+	case ATKBD_KEY_UNKNOWN:
+		dev_warn(&serio->dev,
+			 "Unknown key %s (%s set %d, code %#x on %s).\n",
+			 atkbd->release ? "released" : "pressed",
+			 atkbd->translated ? "translated" : "raw",
+			 atkbd->set, code, serio->phys);
+		dev_warn(&serio->dev,
+			 "Use 'setkeycodes %s%02x <keycode>' to make it known.\n",
+			 code & 0x80 ? "e0" : "", code & 0x7f);
+		input_sync(dev);
+		break;
+	case ATKBD_SCR_1:
+		scroll = 1;
+		break;
+	case ATKBD_SCR_2:
+		scroll = 2;
+		break;
+	case ATKBD_SCR_4:
+		scroll = 4;
+		break;
+	case ATKBD_SCR_8:
+		scroll = 8;
+		break;
+	case ATKBD_SCR_CLICK:
+		click = !atkbd->release;
+		break;
+	case ATKBD_SCR_LEFT:
+		hscroll = -1;
+		break;
+	case ATKBD_SCR_RIGHT:
+		hscroll = 1;
+		break;
+	default:
+		if (atkbd->release) {
+			value = 0;
+			atkbd->last = 0;
+		} else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) {
+			/* Workaround Toshiba laptop multiple keypress */
+			value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2;
+		} else {
+			value = 1;
+			atkbd->last = code;
+			atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2;
+		}
 
-			input_event(dev, EV_KEY, keycode, value);
-			input_sync(dev);
+		input_event(dev, EV_KEY, keycode, value);
+		input_sync(dev);
 
-			if (value && test_bit(code, atkbd->force_release_mask)) {
-				input_report_key(dev, keycode, 0);
-				input_sync(dev);
-			}
+		if (value && test_bit(code, atkbd->force_release_mask)) {
+			input_report_key(dev, keycode, 0);
+			input_sync(dev);
+		}
 	}
 
 	if (atkbd->scroll) {
 		if (click != -1)
 			input_report_key(dev, BTN_MIDDLE, click);
-		input_report_rel(dev, REL_WHEEL, scroll);
+		input_report_rel(dev, REL_WHEEL,
+				 atkbd->release ? -scroll : scroll);
 		input_report_rel(dev, REL_HWHEEL, hscroll);
 		input_sync(dev);
 	}
 
-	atkbd->release = 0;
+	atkbd->release = false;
 out:
 	return IRQ_HANDLED;
 }
@@ -634,17 +633,18 @@ static int atkbd_event(struct input_dev
 
 	switch (type) {
 
-		case EV_LED:
-			atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT);
-			return 0;
+	case EV_LED:
+		atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT);
+		return 0;
 
-		case EV_REP:
-			if (!atkbd->softrepeat)
-				atkbd_schedule_event_work(atkbd, ATKBD_REP_EVENT_BIT);
-			return 0;
-	}
+	case EV_REP:
+		if (!atkbd->softrepeat)
+			atkbd_schedule_event_work(atkbd, ATKBD_REP_EVENT_BIT);
+		return 0;
 
-	return -1;
+	default:
+		return -1;
+	}
 }
 
 /*
@@ -655,7 +655,7 @@ static int atkbd_event(struct input_dev
 static inline void atkbd_enable(struct atkbd *atkbd)
 {
 	serio_pause_rx(atkbd->ps2dev.serio);
-	atkbd->enabled = 1;
+	atkbd->enabled = true;
 	serio_continue_rx(atkbd->ps2dev.serio);
 }
 
@@ -667,7 +667,7 @@ static inline void atkbd_enable(struct a
 static inline void atkbd_disable(struct atkbd *atkbd)
 {
 	serio_pause_rx(atkbd->ps2dev.serio);
-	atkbd->enabled = 0;
+	atkbd->enabled = false;
 	serio_continue_rx(atkbd->ps2dev.serio);
 }
 
@@ -688,7 +688,9 @@ static int atkbd_probe(struct atkbd *atk
 
 	if (atkbd_reset)
 		if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_BAT))
-			printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", ps2dev->serio->phys);
+			dev_warn(&ps2dev->serio->dev,
+				 "keyboard reset failed on %s\n",
+				 ps2dev->serio->phys);
 
 /*
  * Then we check the keyboard ID. We should get 0xab83 under normal conditions.
@@ -718,8 +720,9 @@ static int atkbd_probe(struct atkbd *atk
 	atkbd->id = (param[0] << 8) | param[1];
 
 	if (atkbd->id == 0xaca1 && atkbd->translated) {
-		printk(KERN_ERR "atkbd.c: NCD terminal keyboards are only supported on non-translating\n");
-		printk(KERN_ERR "atkbd.c: controllers. Use i8042.direct=1 to disable translation.\n");
+		dev_err(&ps2dev->serio->dev,
+			"NCD terminal keyboards are only supported on non-translating controlelrs. "
+			"Use i8042.direct=1 to disable translation.\n");
 		return -1;
 	}
 
@@ -737,7 +740,7 @@ static int atkbd_select_set(struct atkbd
 	struct ps2dev *ps2dev = &atkbd->ps2dev;
 	unsigned char param[2];
 
-	atkbd->extra = 0;
+	atkbd->extra = false;
 /*
  * For known special keyboards we can go ahead and set the correct set.
  * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and
@@ -756,7 +759,7 @@ static int atkbd_select_set(struct atkbd
 	if (allow_extra) {
 		param[0] = 0x71;
 		if (!ps2_command(ps2dev, param, ATKBD_CMD_EX_ENABLE)) {
-			atkbd->extra = 1;
+			atkbd->extra = true;
 			return 2;
 		}
 	}
@@ -821,7 +824,8 @@ static int atkbd_activate(struct atkbd *
  */
 
 	if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) {
-		printk(KERN_ERR "atkbd.c: Failed to enable keyboard on %s\n",
+		dev_err(&ps2dev->serio->dev,
+			"Failed to enable keyboard on %s\n",
 			ps2dev->serio->phys);
 		return -1;
 	}
@@ -1070,9 +1074,13 @@ static void atkbd_set_device_attrs(struc
 	input_dev->keycodesize = sizeof(unsigned short);
 	input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
 
-	for (i = 0; i < ATKBD_KEYMAP_SIZE; i++)
-		if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
+	for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) {
+		if (atkbd->keycode[i] != KEY_RESERVED &&
+		    atkbd->keycode[i] != ATKBD_KEY_NULL &&
+		    atkbd->keycode[i] < ATKBD_SPECIAL) {
 			__set_bit(atkbd->keycode[i], input_dev->keybit);
+		}
+	}
 }
 
 /*
@@ -1100,12 +1108,14 @@ static int atkbd_connect(struct serio *s
 
 	switch (serio->id.type) {
 
-		case SERIO_8042_XL:
-			atkbd->translated = 1;
-		case SERIO_8042:
-			if (serio->write)
-				atkbd->write = 1;
-			break;
+	case SERIO_8042_XL:
+		atkbd->translated = true;
+		/* Fall through */
+
+	case SERIO_8042:
+		if (serio->write)
+			atkbd->write = true;
+		break;
 	}
 
 	atkbd->softraw = atkbd_softraw;
@@ -1113,7 +1123,7 @@ static int atkbd_connect(struct serio *s
 	atkbd->scroll = atkbd_scroll;
 
 	if (atkbd->softrepeat)
-		atkbd->softraw = 1;
+		atkbd->softraw = true;
 
 	serio_set_drvdata(serio, atkbd);
 
@@ -1172,7 +1182,8 @@ static int atkbd_reconnect(struct serio
 	int retval = -1;
 
 	if (!atkbd || !drv) {
-		printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n");
+		dev_dbg(&serio->dev,
+			"reconnect request, but serio is disconnected, ignoring...\n");
 		return -1;
 	}
 
@@ -1286,7 +1297,8 @@ static ssize_t atkbd_set_extra(struct at
 	struct input_dev *old_dev, *new_dev;
 	unsigned long value;
 	int err;
-	unsigned char old_extra, old_set;
+	bool old_extra;
+	unsigned char old_set;
 
 	if (!atkbd->write)
 		return -EIO;
@@ -1369,7 +1381,7 @@ static ssize_t atkbd_set_scroll(struct a
 	struct input_dev *old_dev, *new_dev;
 	unsigned long value;
 	int err;
-	unsigned char old_scroll;
+	bool old_scroll;
 
 	if (strict_strtoul(buf, 10, &value) || value > 1)
 		return -EINVAL;
@@ -1413,7 +1425,8 @@ static ssize_t atkbd_set_set(struct atkb
 	struct input_dev *old_dev, *new_dev;
 	unsigned long value;
 	int err;
-	unsigned char old_set, old_extra;
+	unsigned char old_set;
+	bool old_extra;
 
 	if (!atkbd->write)
 		return -EIO;
@@ -1463,7 +1476,7 @@ static ssize_t atkbd_set_softrepeat(stru
 	struct input_dev *old_dev, *new_dev;
 	unsigned long value;
 	int err;
-	unsigned char old_softrepeat, old_softraw;
+	bool old_softrepeat, old_softraw;
 
 	if (!atkbd->write)
 		return -EIO;
@@ -1483,7 +1496,7 @@ static ssize_t atkbd_set_softrepeat(stru
 		atkbd->dev = new_dev;
 		atkbd->softrepeat = value;
 		if (atkbd->softrepeat)
-			atkbd->softraw = 1;
+			atkbd->softraw = true;
 		atkbd_set_device_attrs(atkbd);
 
 		err = input_register_device(atkbd->dev);
@@ -1513,7 +1526,7 @@ static ssize_t atkbd_set_softraw(struct
 	struct input_dev *old_dev, *new_dev;
 	unsigned long value;
 	int err;
-	unsigned char old_softraw;
+	bool old_softraw;
 
 	if (strict_strtoul(buf, 10, &value) || value > 1)
 		return -EINVAL;
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/bf54x-keys.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/bf54x-keys.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/bf54x-keys.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/bf54x-keys.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/fs.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/pm.h>
 #include <linux/sysctl.h>
@@ -162,7 +163,7 @@ static irqreturn_t bfin_kpad_isr(int irq
 	input_sync(input);
 
 	if (bfin_kpad_get_keypressed(bf54x_kpad)) {
-		disable_irq(bf54x_kpad->irq);
+		disable_irq_nosync(bf54x_kpad->irq);
 		bf54x_kpad->lastkey = key;
 		mod_timer(&bf54x_kpad->timer,
 			  jiffies + bf54x_kpad->keyup_test_jiffies);
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/davinci_keyscan.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/davinci_keyscan.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/davinci_keyscan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/davinci_keyscan.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/ep93xx_keypad.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/ep93xx_keypad.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/ep93xx_keypad.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/ep93xx_keypad.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/input/matrix_keypad.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <mach/ep93xx_keypad.h>
@@ -69,7 +70,7 @@ struct ep93xx_keypad {
 
 	void __iomem *mmio_base;
 
-	unsigned int matrix_keycodes[EP93XX_MATRIX_SIZE];
+	unsigned short keycodes[EP93XX_MATRIX_SIZE];
 
 	int key1;
 	int key2;
@@ -79,24 +80,6 @@ struct ep93xx_keypad {
 	bool enabled;
 };
 
-static void ep93xx_keypad_build_keycode(struct ep93xx_keypad *keypad)
-{
-	struct ep93xx_keypad_platform_data *pdata = keypad->pdata;
-	struct input_dev *input_dev = keypad->input_dev;
-	unsigned int *key;
-	int i;
-
-	key = &pdata->matrix_key_map[0];
-	for (i = 0; i < pdata->matrix_key_map_size; i++, key++) {
-		int row = KEY_ROW(*key);
-		int col = KEY_COL(*key);
-		int code = KEY_VAL(*key);
-
-		keypad->matrix_keycodes[(row << 3) + col] = code;
-		__set_bit(code, input_dev->keybit);
-	}
-}
-
 static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id)
 {
 	struct ep93xx_keypad *keypad = dev_id;
@@ -107,10 +90,10 @@ static irqreturn_t ep93xx_keypad_irq_han
 	status = __raw_readl(keypad->mmio_base + KEY_REG);
 
 	keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT;
-	key1 = keypad->matrix_keycodes[keycode];
+	key1 = keypad->keycodes[keycode];
 
 	keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT;
-	key2 = keypad->matrix_keycodes[keycode];
+	key2 = keypad->keycodes[keycode];
 
 	if (status & KEY_REG_2KEYS) {
 		if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1)
@@ -256,6 +239,7 @@ static int ep93xx_keypad_resume(struct p
 static int __devinit ep93xx_keypad_probe(struct platform_device *pdev)
 {
 	struct ep93xx_keypad *keypad;
+	const struct matrix_keymap_data *keymap_data;
 	struct input_dev *input_dev;
 	struct resource *res;
 	int err;
@@ -270,6 +254,12 @@ static int __devinit ep93xx_keypad_probe
 		goto failed_free;
 	}
 
+	keymap_data = keypad->pdata->keymap_data;
+	if (!keymap_data) {
+		err = -EINVAL;
+		goto failed_free;
+	}
+
 	keypad->irq = platform_get_irq(pdev, 0);
 	if (!keypad->irq) {
 		err = -ENXIO;
@@ -317,9 +307,9 @@ static int __devinit ep93xx_keypad_probe
 	input_dev->open = ep93xx_keypad_open;
 	input_dev->close = ep93xx_keypad_close;
 	input_dev->dev.parent = &pdev->dev;
-	input_dev->keycode = keypad->matrix_keycodes;
-	input_dev->keycodesize = sizeof(keypad->matrix_keycodes[0]);
-	input_dev->keycodemax = ARRAY_SIZE(keypad->matrix_keycodes);
+	input_dev->keycode = keypad->keycodes;
+	input_dev->keycodesize = sizeof(keypad->keycodes[0]);
+	input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes);
 
 	input_set_drvdata(input_dev, keypad);
 
@@ -327,7 +317,8 @@ static int __devinit ep93xx_keypad_probe
 	if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT)
 		input_dev->evbit[0] |= BIT_MASK(EV_REP);
 
-	ep93xx_keypad_build_keycode(keypad);
+	matrix_keypad_build_keymap(keymap_data, 3,
+				   input_dev->keycode, input_dev->keybit);
 	platform_set_drvdata(pdev, keypad);
 
 	err = request_irq(keypad->irq, ep93xx_keypad_irq_handler,
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/gpio_keys.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/gpio_keys.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/gpio_keys.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/gpio_keys.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/irq.h>
 #include <linux/sched.h>
 #include <linux/pm.h>
+#include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
 #include <linux/delay.h>
@@ -30,13 +31,289 @@ struct gpio_button_data {
 	struct input_dev *input;
 	struct timer_list timer;
 	struct work_struct work;
+	bool disabled;
 };
 
 struct gpio_keys_drvdata {
 	struct input_dev *input;
+	struct mutex disable_lock;
+	unsigned int n_buttons;
 	struct gpio_button_data data[0];
 };
 
+/*
+ * SYSFS interface for enabling/disabling keys and switches:
+ *
+ * There are 4 attributes under /sys/devices/platform/gpio-keys/
+ *	keys [ro]              - bitmap of keys (EV_KEY) which can be
+ *	                         disabled
+ *	switches [ro]          - bitmap of switches (EV_SW) which can be
+ *	                         disabled
+ *	disabled_keys [rw]     - bitmap of keys currently disabled
+ *	disabled_switches [rw] - bitmap of switches currently disabled
+ *
+ * Userland can change these values and hence disable event generation
+ * for each key (or switch). Disabling a key means its interrupt line
+ * is disabled.
+ *
+ * For example, if we have following switches set up as gpio-keys:
+ *	SW_DOCK = 5
+ *	SW_CAMERA_LENS_COVER = 9
+ *	SW_KEYPAD_SLIDE = 10
+ *	SW_FRONT_PROXIMITY = 11
+ * This is read from switches:
+ *	11-9,5
+ * Next we want to disable proximity (11) and dock (5), we write:
+ *	11,5
+ * to file disabled_switches. Now proximity and dock IRQs are disabled.
+ * This can be verified by reading the file disabled_switches:
+ *	11,5
+ * If we now want to enable proximity (11) switch we write:
+ *	5
+ * to disabled_switches.
+ *
+ * We can disable only those keys which don't allow sharing the irq.
+ */
+
+/**
+ * get_n_events_by_type() - returns maximum number of events per @type
+ * @type: type of button (%EV_KEY, %EV_SW)
+ *
+ * Return value of this function can be used to allocate bitmap
+ * large enough to hold all bits for given type.
+ */
+static inline int get_n_events_by_type(int type)
+{
+	BUG_ON(type != EV_SW && type != EV_KEY);
+
+	return (type == EV_KEY) ? KEY_CNT : SW_CNT;
+}
+
+/**
+ * gpio_keys_disable_button() - disables given GPIO button
+ * @bdata: button data for button to be disabled
+ *
+ * Disables button pointed by @bdata. This is done by masking
+ * IRQ line. After this function is called, button won't generate
+ * input events anymore. Note that one can only disable buttons
+ * that don't share IRQs.
+ *
+ * Make sure that @bdata->disable_lock is locked when entering
+ * this function to avoid races when concurrent threads are
+ * disabling buttons at the same time.
+ */
+static void gpio_keys_disable_button(struct gpio_button_data *bdata)
+{
+	if (!bdata->disabled) {
+		/*
+		 * Disable IRQ and possible debouncing timer.
+		 */
+		disable_irq(gpio_to_irq(bdata->button->gpio));
+		if (bdata->button->debounce_interval)
+			del_timer_sync(&bdata->timer);
+
+		bdata->disabled = true;
+	}
+}
+
+/**
+ * gpio_keys_enable_button() - enables given GPIO button
+ * @bdata: button data for button to be disabled
+ *
+ * Enables given button pointed by @bdata.
+ *
+ * Make sure that @bdata->disable_lock is locked when entering
+ * this function to avoid races with concurrent threads trying
+ * to enable the same button at the same time.
+ */
+static void gpio_keys_enable_button(struct gpio_button_data *bdata)
+{
+	if (bdata->disabled) {
+		enable_irq(gpio_to_irq(bdata->button->gpio));
+		bdata->disabled = false;
+	}
+}
+
+/**
+ * gpio_keys_attr_show_helper() - fill in stringified bitmap of buttons
+ * @ddata: pointer to drvdata
+ * @buf: buffer where stringified bitmap is written
+ * @type: button type (%EV_KEY, %EV_SW)
+ * @only_disabled: does caller want only those buttons that are
+ *                 currently disabled or all buttons that can be
+ *                 disabled
+ *
+ * This function writes buttons that can be disabled to @buf. If
+ * @only_disabled is true, then @buf contains only those buttons
+ * that are currently disabled. Returns 0 on success or negative
+ * errno on failure.
+ */
+static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata,
+					  char *buf, unsigned int type,
+					  bool only_disabled)
+{
+	int n_events = get_n_events_by_type(type);
+	unsigned long *bits;
+	ssize_t ret;
+	int i;
+
+	bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL);
+	if (!bits)
+		return -ENOMEM;
+
+	for (i = 0; i < ddata->n_buttons; i++) {
+		struct gpio_button_data *bdata = &ddata->data[i];
+
+		if (bdata->button->type != type)
+			continue;
+
+		if (only_disabled && !bdata->disabled)
+			continue;
+
+		__set_bit(bdata->button->code, bits);
+	}
+
+	ret = bitmap_scnlistprintf(buf, PAGE_SIZE - 2, bits, n_events);
+	buf[ret++] = '\n';
+	buf[ret] = '\0';
+
+	kfree(bits);
+
+	return ret;
+}
+
+/**
+ * gpio_keys_attr_store_helper() - enable/disable buttons based on given bitmap
+ * @ddata: pointer to drvdata
+ * @buf: buffer from userspace that contains stringified bitmap
+ * @type: button type (%EV_KEY, %EV_SW)
+ *
+ * This function parses stringified bitmap from @buf and disables/enables
+ * GPIO buttons accordinly. Returns 0 on success and negative error
+ * on failure.
+ */
+static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
+					   const char *buf, unsigned int type)
+{
+	int n_events = get_n_events_by_type(type);
+	unsigned long *bits;
+	ssize_t error;
+	int i;
+
+	bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL);
+	if (!bits)
+		return -ENOMEM;
+
+	error = bitmap_parselist(buf, bits, n_events);
+	if (error)
+		goto out;
+
+	/* First validate */
+	for (i = 0; i < ddata->n_buttons; i++) {
+		struct gpio_button_data *bdata = &ddata->data[i];
+
+		if (bdata->button->type != type)
+			continue;
+
+		if (test_bit(bdata->button->code, bits) &&
+		    !bdata->button->can_disable) {
+			error = -EINVAL;
+			goto out;
+		}
+	}
+
+	mutex_lock(&ddata->disable_lock);
+
+	for (i = 0; i < ddata->n_buttons; i++) {
+		struct gpio_button_data *bdata = &ddata->data[i];
+
+		if (bdata->button->type != type)
+			continue;
+
+		if (test_bit(bdata->button->code, bits))
+			gpio_keys_disable_button(bdata);
+		else
+			gpio_keys_enable_button(bdata);
+	}
+
+	mutex_unlock(&ddata->disable_lock);
+
+out:
+	kfree(bits);
+	return error;
+}
+
+#define ATTR_SHOW_FN(name, type, only_disabled)				\
+static ssize_t gpio_keys_show_##name(struct device *dev,		\
+				     struct device_attribute *attr,	\
+				     char *buf)				\
+{									\
+	struct platform_device *pdev = to_platform_device(dev);		\
+	struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);	\
+									\
+	return gpio_keys_attr_show_helper(ddata, buf,			\
+					  type, only_disabled);		\
+}
+
+ATTR_SHOW_FN(keys, EV_KEY, false);
+ATTR_SHOW_FN(switches, EV_SW, false);
+ATTR_SHOW_FN(disabled_keys, EV_KEY, true);
+ATTR_SHOW_FN(disabled_switches, EV_SW, true);
+
+/*
+ * ATTRIBUTES:
+ *
+ * /sys/devices/platform/gpio-keys/keys [ro]
+ * /sys/devices/platform/gpio-keys/switches [ro]
+ */
+static DEVICE_ATTR(keys, S_IRUGO, gpio_keys_show_keys, NULL);
+static DEVICE_ATTR(switches, S_IRUGO, gpio_keys_show_switches, NULL);
+
+#define ATTR_STORE_FN(name, type)					\
+static ssize_t gpio_keys_store_##name(struct device *dev,		\
+				      struct device_attribute *attr,	\
+				      const char *buf,			\
+				      size_t count)			\
+{									\
+	struct platform_device *pdev = to_platform_device(dev);		\
+	struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);	\
+	ssize_t error;							\
+									\
+	error = gpio_keys_attr_store_helper(ddata, buf, type);		\
+	if (error)							\
+		return error;						\
+									\
+	return count;							\
+}
+
+ATTR_STORE_FN(disabled_keys, EV_KEY);
+ATTR_STORE_FN(disabled_switches, EV_SW);
+
+/*
+ * ATTRIBUTES:
+ *
+ * /sys/devices/platform/gpio-keys/disabled_keys [rw]
+ * /sys/devices/platform/gpio-keys/disables_switches [rw]
+ */
+static DEVICE_ATTR(disabled_keys, S_IWUSR | S_IRUGO,
+		   gpio_keys_show_disabled_keys,
+		   gpio_keys_store_disabled_keys);
+static DEVICE_ATTR(disabled_switches, S_IWUSR | S_IRUGO,
+		   gpio_keys_show_disabled_switches,
+		   gpio_keys_store_disabled_switches);
+
+static struct attribute *gpio_keys_attrs[] = {
+	&dev_attr_keys.attr,
+	&dev_attr_switches.attr,
+	&dev_attr_disabled_keys.attr,
+	&dev_attr_disabled_switches.attr,
+	NULL,
+};
+
+static struct attribute_group gpio_keys_attr_group = {
+	.attrs = gpio_keys_attrs,
+};
+
 static void gpio_keys_report_event(struct gpio_button_data *bdata)
 {
 	struct gpio_keys_button *button = bdata->button;
@@ -79,11 +356,13 @@ static irqreturn_t gpio_keys_isr(int irq
 	return IRQ_HANDLED;
 }
 
-static int __devinit gpio_keys_setup_key(struct device *dev,
+static int __devinit gpio_keys_setup_key(struct platform_device *pdev,
 					 struct gpio_button_data *bdata,
 					 struct gpio_keys_button *button)
 {
 	char *desc = button->desc ? button->desc : "gpio_keys";
+	struct device *dev = &pdev->dev;
+	unsigned long irqflags;
 	int irq, error;
 
 	setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata);
@@ -112,10 +391,15 @@ static int __devinit gpio_keys_setup_key
 		goto fail3;
 	}
 
-	error = request_irq(irq, gpio_keys_isr,
-			    IRQF_SHARED |
-			    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-			    desc, bdata);
+	irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
+	/*
+	 * If platform has specified that the button can be disabled,
+	 * we don't want it to share the interrupt line.
+	 */
+	if (!button->can_disable)
+		irqflags |= IRQF_SHARED;
+
+	error = request_irq(irq, gpio_keys_isr, irqflags, desc, bdata);
 	if (error) {
 		dev_err(dev, "Unable to claim irq %d; error %d\n",
 			irq, error);
@@ -149,6 +433,10 @@ static int __devinit gpio_keys_probe(str
 		goto fail1;
 	}
 
+	ddata->input = input;
+	ddata->n_buttons = pdata->nbuttons;
+	mutex_init(&ddata->disable_lock);
+
 	platform_set_drvdata(pdev, ddata);
 
 	input->name = pdev->name;
@@ -164,8 +452,6 @@ static int __devinit gpio_keys_probe(str
 	if (pdata->rep)
 		__set_bit(EV_REP, input->evbit);
 
-	ddata->input = input;
-
 	for (i = 0; i < pdata->nbuttons; i++) {
 		struct gpio_keys_button *button = &pdata->buttons[i];
 		struct gpio_button_data *bdata = &ddata->data[i];
@@ -174,7 +460,7 @@ static int __devinit gpio_keys_probe(str
 		bdata->input = input;
 		bdata->button = button;
 
-		error = gpio_keys_setup_key(dev, bdata, button);
+		error = gpio_keys_setup_key(pdev, bdata, button);
 		if (error)
 			goto fail2;
 
@@ -184,13 +470,20 @@ static int __devinit gpio_keys_probe(str
 		input_set_capability(input, type, button->code);
 	}
 
-	error = input_register_device(input);
+	error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group);
 	if (error) {
-		dev_err(dev, "Unable to register input device, "
-			"error: %d\n", error);
+		dev_err(dev, "Unable to export keys/switches, error: %d\n",
+			error);
 		goto fail2;
 	}
 
+	error = input_register_device(input);
+	if (error) {
+		dev_err(dev, "Unable to register input device, error: %d\n",
+			error);
+		goto fail3;
+	}
+
 	/* get current state of buttons */
 	for (i = 0; i < pdata->nbuttons; i++)
 		gpio_keys_report_event(&ddata->data[i]);
@@ -200,6 +493,8 @@ static int __devinit gpio_keys_probe(str
 
 	return 0;
 
+ fail3:
+	sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group);
  fail2:
 	while (--i >= 0) {
 		free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);
@@ -224,6 +519,8 @@ static int __devexit gpio_keys_remove(st
 	struct input_dev *input = ddata->input;
 	int i;
 
+	sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group);
+
 	device_init_wakeup(&pdev->dev, 0);
 
 	for (i = 0; i < pdata->nbuttons; i++) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/imx_keypad.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/imx_keypad.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/imx_keypad.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/imx_keypad.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,595 @@
+/*
+ * Driver for the IMX keypad port.
+ * Copyright (C) 2009 Alberto Panizzo <maramaopercheseimorto@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.
+ *
+ * <<Power management needs to be implemented>>.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+
+/*
+ * Keypad Controller registers (halfword)
+ */
+#define KPCR		0x00 /* Keypad Control Register */
+
+#define KPSR		0x02 /* Keypad Status Register */
+#define KBD_STAT_KPKD	(0x1 << 0) /* Key Press Interrupt Status bit (w1c) */
+#define KBD_STAT_KPKR	(0x1 << 1) /* Key Release Interrupt Status bit (w1c) */
+#define KBD_STAT_KDSC	(0x1 << 2) /* Key Depress Synch Chain Status bit (w1c)*/
+#define KBD_STAT_KRSS	(0x1 << 3) /* Key Release Synch Status bit (w1c)*/
+#define KBD_STAT_KDIE	(0x1 << 8) /* Key Depress Interrupt Enable Status bit */
+#define KBD_STAT_KRIE	(0x1 << 9) /* Key Release Interrupt Enable */
+#define KBD_STAT_KPPEN	(0x1 << 10) /* Keypad Clock Enable */
+
+#define KDDR		0x04 /* Keypad Data Direction Register */
+#define KPDR		0x06 /* Keypad Data Register */
+
+#define MAX_MATRIX_KEY_ROWS	8
+#define MAX_MATRIX_KEY_COLS	8
+#define MATRIX_ROW_SHIFT	3
+
+#define MAX_MATRIX_KEY_NUM	(MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS)
+
+struct imx_keypad {
+
+	struct clk *clk;
+	struct input_dev *input_dev;
+	void __iomem *mmio_base;
+
+	int			irq;
+	struct timer_list	check_matrix_timer;
+
+	/*
+	 * The matrix is stable only if no changes are detected after
+	 * IMX_KEYPAD_SCANS_FOR_STABILITY scans
+	 */
+#define IMX_KEYPAD_SCANS_FOR_STABILITY 3
+	int			stable_count;
+
+	bool			enabled;
+
+	/* Masks for enabled rows/cols */
+	unsigned short		rows_en_mask;
+	unsigned short		cols_en_mask;
+
+	unsigned short		keycodes[MAX_MATRIX_KEY_NUM];
+
+	/*
+	 * Matrix states:
+	 * -stable: achieved after a complete debounce process.
+	 * -unstable: used in the debouncing process.
+	 */
+	unsigned short		matrix_stable_state[MAX_MATRIX_KEY_COLS];
+	unsigned short		matrix_unstable_state[MAX_MATRIX_KEY_COLS];
+};
+
+/* Scan the matrix and return the new state in *matrix_volatile_state. */
+static void imx_keypad_scan_matrix(struct imx_keypad *keypad,
+				  unsigned short *matrix_volatile_state)
+{
+	int col;
+	unsigned short reg_val;
+
+	for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) {
+		if ((keypad->cols_en_mask & (1 << col)) == 0)
+			continue;
+		/*
+		 * Discharge keypad capacitance:
+		 * 2. write 1s on column data.
+		 * 3. configure columns as totem-pole to discharge capacitance.
+		 * 4. configure columns as open-drain.
+		 */
+		reg_val = readw(keypad->mmio_base + KPDR);
+		reg_val |= 0xff00;
+		writew(reg_val, keypad->mmio_base + KPDR);
+
+		reg_val = readw(keypad->mmio_base + KPCR);
+		reg_val &= ~((keypad->cols_en_mask & 0xff) << 8);
+		writew(reg_val, keypad->mmio_base + KPCR);
+
+		udelay(2);
+
+		reg_val = readw(keypad->mmio_base + KPCR);
+		reg_val |= (keypad->cols_en_mask & 0xff) << 8;
+		writew(reg_val, keypad->mmio_base + KPCR);
+
+		/*
+		 * 5. Write a single column to 0, others to 1.
+		 * 6. Sample row inputs and save data.
+		 * 7. Repeat steps 2 - 6 for remaining columns.
+		 */
+		reg_val = readw(keypad->mmio_base + KPDR);
+		reg_val &= ~(1 << (8 + col));
+		writew(reg_val, keypad->mmio_base + KPDR);
+
+		/*
+		 * Delay added to avoid propagating the 0 from column to row
+		 * when scanning.
+		 */
+		udelay(5);
+
+		/*
+		 * 1s in matrix_volatile_state[col] means key pressures
+		 * throw data from non enabled rows.
+		 */
+		reg_val = readw(keypad->mmio_base + KPDR);
+		matrix_volatile_state[col] = (~reg_val) & keypad->rows_en_mask;
+	}
+
+	/*
+	 * Return in standby mode:
+	 * 9. write 0s to columns
+	 */
+	reg_val = readw(keypad->mmio_base + KPDR);
+	reg_val &= 0x00ff;
+	writew(reg_val, keypad->mmio_base + KPDR);
+}
+
+/*
+ * Compare the new matrix state (volatile) with the stable one stored in
+ * keypad->matrix_stable_state and fire events if changes are detected.
+ */
+static void imx_keypad_fire_events(struct imx_keypad *keypad,
+				   unsigned short *matrix_volatile_state)
+{
+	struct input_dev *input_dev = keypad->input_dev;
+	int row, col;
+
+	for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) {
+		unsigned short bits_changed;
+		int code;
+
+		if ((keypad->cols_en_mask & (1 << col)) == 0)
+			continue; /* Column is not enabled */
+
+		bits_changed = keypad->matrix_stable_state[col] ^
+						matrix_volatile_state[col];
+
+		if (bits_changed == 0)
+			continue; /* Column does not contain changes */
+
+		for (row = 0; row < MAX_MATRIX_KEY_ROWS; row++) {
+			if ((keypad->rows_en_mask & (1 << row)) == 0)
+				continue; /* Row is not enabled */
+			if ((bits_changed & (1 << row)) == 0)
+				continue; /* Row does not contain changes */
+
+			code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT);
+			input_event(input_dev, EV_MSC, MSC_SCAN, code);
+			input_report_key(input_dev, keypad->keycodes[code],
+				matrix_volatile_state[col] & (1 << row));
+			dev_dbg(&input_dev->dev, "Event code: %d, val: %d",
+				keypad->keycodes[code],
+				matrix_volatile_state[col] & (1 << row));
+		}
+	}
+	input_sync(input_dev);
+}
+
+/*
+ * imx_keypad_check_for_events is the timer handler.
+ */
+static void imx_keypad_check_for_events(unsigned long data)
+{
+	struct imx_keypad *keypad = (struct imx_keypad *) data;
+	unsigned short matrix_volatile_state[MAX_MATRIX_KEY_COLS];
+	unsigned short reg_val;
+	bool state_changed, is_zero_matrix;
+	int i;
+
+	memset(matrix_volatile_state, 0, sizeof(matrix_volatile_state));
+
+	imx_keypad_scan_matrix(keypad, matrix_volatile_state);
+
+	state_changed = false;
+	for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) {
+		if ((keypad->cols_en_mask & (1 << i)) == 0)
+			continue;
+
+		if (keypad->matrix_unstable_state[i] ^ matrix_volatile_state[i]) {
+			state_changed = true;
+			break;
+		}
+	}
+
+	/*
+	 * If the matrix state is changed from the previous scan
+	 *   (Re)Begin the debouncing process, saving the new state in
+	 *    keypad->matrix_unstable_state.
+	 * else
+	 *   Increase the count of number of scans with a stable state.
+	 */
+	if (state_changed) {
+		memcpy(keypad->matrix_unstable_state, matrix_volatile_state,
+			sizeof(matrix_volatile_state));
+		keypad->stable_count = 0;
+	} else
+		keypad->stable_count++;
+
+	/*
+	 * If the matrix is not as stable as we want reschedule scan
+	 * in the near future.
+	 */
+	if (keypad->stable_count < IMX_KEYPAD_SCANS_FOR_STABILITY) {
+		mod_timer(&keypad->check_matrix_timer,
+			  jiffies + msecs_to_jiffies(10));
+		return;
+	}
+
+	/*
+	 * If the matrix state is stable, fire the events and save the new
+	 * stable state. Note, if the matrix is kept stable for longer
+	 * (keypad->stable_count > IMX_KEYPAD_SCANS_FOR_STABILITY) all
+	 * events have already been generated.
+	 */
+	if (keypad->stable_count == IMX_KEYPAD_SCANS_FOR_STABILITY) {
+		imx_keypad_fire_events(keypad, matrix_volatile_state);
+
+		memcpy(keypad->matrix_stable_state, matrix_volatile_state,
+			sizeof(matrix_volatile_state));
+	}
+
+	is_zero_matrix = true;
+	for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) {
+		if (matrix_volatile_state[i] != 0) {
+			is_zero_matrix = false;
+			break;
+		}
+	}
+
+
+	if (is_zero_matrix) {
+		/*
+		 * All keys have been released. Enable only the KDI
+		 * interrupt for future key presses (clear the KDI
+		 * status bit and its sync chain before that).
+		 */
+		reg_val = readw(keypad->mmio_base + KPSR);
+		reg_val |= KBD_STAT_KPKD | KBD_STAT_KDSC;
+		writew(reg_val, keypad->mmio_base + KPSR);
+
+		reg_val = readw(keypad->mmio_base + KPSR);
+		reg_val |= KBD_STAT_KDIE;
+		reg_val &= ~KBD_STAT_KRIE;
+		writew(reg_val, keypad->mmio_base + KPSR);
+	} else {
+		/*
+		 * Some keys are still pressed. Schedule a rescan in
+		 * attempt to detect multiple key presses and enable
+		 * the KRI interrupt to react quickly to key release
+		 * event.
+		 */
+		mod_timer(&keypad->check_matrix_timer,
+			  jiffies + msecs_to_jiffies(60));
+
+		reg_val = readw(keypad->mmio_base + KPSR);
+		reg_val |= KBD_STAT_KPKR | KBD_STAT_KRSS;
+		writew(reg_val, keypad->mmio_base + KPSR);
+
+		reg_val = readw(keypad->mmio_base + KPSR);
+		reg_val |= KBD_STAT_KRIE;
+		reg_val &= ~KBD_STAT_KDIE;
+		writew(reg_val, keypad->mmio_base + KPSR);
+	}
+}
+
+static irqreturn_t imx_keypad_irq_handler(int irq, void *dev_id)
+{
+	struct imx_keypad *keypad = dev_id;
+	unsigned short reg_val;
+
+	reg_val = readw(keypad->mmio_base + KPSR);
+
+	/* Disable both interrupt types */
+	reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE);
+	/* Clear interrupts status bits */
+	reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD;
+	writew(reg_val, keypad->mmio_base + KPSR);
+
+	if (keypad->enabled) {
+		/* The matrix is supposed to be changed */
+		keypad->stable_count = 0;
+
+		/* Schedule the scanning procedure near in the future */
+		mod_timer(&keypad->check_matrix_timer,
+			  jiffies + msecs_to_jiffies(2));
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void imx_keypad_config(struct imx_keypad *keypad)
+{
+	unsigned short reg_val;
+
+	/*
+	 * Include enabled rows in interrupt generation (KPCR[7:0])
+	 * Configure keypad columns as open-drain (KPCR[15:8])
+	 */
+	reg_val = readw(keypad->mmio_base + KPCR);
+	reg_val |= keypad->rows_en_mask & 0xff;		/* rows */
+	reg_val |= (keypad->cols_en_mask & 0xff) << 8;	/* cols */
+	writew(reg_val, keypad->mmio_base + KPCR);
+
+	/* Write 0's to KPDR[15:8] (Colums) */
+	reg_val = readw(keypad->mmio_base + KPDR);
+	reg_val &= 0x00ff;
+	writew(reg_val, keypad->mmio_base + KPDR);
+
+	/* Configure columns as output, rows as input (KDDR[15:0]) */
+	writew(0xff00, keypad->mmio_base + KDDR);
+
+	/*
+	 * Clear Key Depress and Key Release status bit.
+	 * Clear both synchronizer chain.
+	 */
+	reg_val = readw(keypad->mmio_base + KPSR);
+	reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD |
+		   KBD_STAT_KDSC | KBD_STAT_KRSS;
+	writew(reg_val, keypad->mmio_base + KPSR);
+
+	/* Enable KDI and disable KRI (avoid false release events). */
+	reg_val |= KBD_STAT_KDIE;
+	reg_val &= ~KBD_STAT_KRIE;
+	writew(reg_val, keypad->mmio_base + KPSR);
+}
+
+static void imx_keypad_inhibit(struct imx_keypad *keypad)
+{
+	unsigned short reg_val;
+
+	/* Inhibit KDI and KRI interrupts. */
+	reg_val = readw(keypad->mmio_base + KPSR);
+	reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE);
+	writew(reg_val, keypad->mmio_base + KPSR);
+
+	/* Colums as open drain and disable all rows */
+	writew(0xff00, keypad->mmio_base + KPCR);
+}
+
+static void imx_keypad_close(struct input_dev *dev)
+{
+	struct imx_keypad *keypad = input_get_drvdata(dev);
+
+	dev_dbg(&dev->dev, ">%s\n", __func__);
+
+	/* Mark keypad as being inactive */
+	keypad->enabled = false;
+	synchronize_irq(keypad->irq);
+	del_timer_sync(&keypad->check_matrix_timer);
+
+	imx_keypad_inhibit(keypad);
+
+	/* Disable clock unit */
+	clk_disable(keypad->clk);
+}
+
+static int imx_keypad_open(struct input_dev *dev)
+{
+	struct imx_keypad *keypad = input_get_drvdata(dev);
+
+	dev_dbg(&dev->dev, ">%s\n", __func__);
+
+	/* We became active from now */
+	keypad->enabled = true;
+
+	/* Enable the kpp clock */
+	clk_enable(keypad->clk);
+	imx_keypad_config(keypad);
+
+	/* Sanity control, not all the rows must be actived now. */
+	if ((readw(keypad->mmio_base + KPDR) & keypad->rows_en_mask) == 0) {
+		dev_err(&dev->dev,
+			"too many keys pressed, control pins initialisation\n");
+		goto open_err;
+	}
+
+	return 0;
+
+open_err:
+	imx_keypad_close(dev);
+	return -EIO;
+}
+
+static int __devinit imx_keypad_probe(struct platform_device *pdev)
+{
+	const struct matrix_keymap_data *keymap_data = pdev->dev.platform_data;
+	struct imx_keypad *keypad;
+	struct input_dev *input_dev;
+	struct resource *res;
+	int irq, error, i;
+
+	if (keymap_data == NULL) {
+		dev_err(&pdev->dev, "no keymap defined\n");
+		return -EINVAL;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "no irq defined in platform data\n");
+		return -EINVAL;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "no I/O memory defined in platform data\n");
+		return -EINVAL;
+	}
+
+	res = request_mem_region(res->start, resource_size(res), pdev->name);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "failed to request I/O memory\n");
+		return -EBUSY;
+	}
+
+	input_dev = input_allocate_device();
+	if (!input_dev) {
+		dev_err(&pdev->dev, "failed to allocate the input device\n");
+		error = -ENOMEM;
+		goto failed_rel_mem;
+	}
+
+	keypad = kzalloc(sizeof(struct imx_keypad), GFP_KERNEL);
+	if (!keypad) {
+		dev_err(&pdev->dev, "not enough memory for driver data\n");
+		error = -ENOMEM;
+		goto failed_free_input;
+	}
+
+	keypad->input_dev = input_dev;
+	keypad->irq = irq;
+	keypad->stable_count = 0;
+
+	setup_timer(&keypad->check_matrix_timer,
+		    imx_keypad_check_for_events, (unsigned long) keypad);
+
+	keypad->mmio_base = ioremap(res->start, resource_size(res));
+	if (keypad->mmio_base == NULL) {
+		dev_err(&pdev->dev, "failed to remap I/O memory\n");
+		error = -ENOMEM;
+		goto failed_free_priv;
+	}
+
+	keypad->clk = clk_get(&pdev->dev, "kpp");
+	if (IS_ERR(keypad->clk)) {
+		dev_err(&pdev->dev, "failed to get keypad clock\n");
+		error = PTR_ERR(keypad->clk);
+		goto failed_unmap;
+	}
+
+	/* Search for rows and cols enabled */
+	for (i = 0; i < keymap_data->keymap_size; i++) {
+		keypad->rows_en_mask |= 1 << KEY_ROW(keymap_data->keymap[i]);
+		keypad->cols_en_mask |= 1 << KEY_COL(keymap_data->keymap[i]);
+	}
+
+	if (keypad->rows_en_mask > ((1 << MAX_MATRIX_KEY_ROWS) - 1) ||
+	   keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) {
+		dev_err(&pdev->dev,
+			"invalid key data (too many rows or colums)\n");
+		error = -EINVAL;
+		goto failed_clock_put;
+	}
+	dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask);
+	dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask);
+
+	/* Init the Input device */
+	input_dev->name = pdev->name;
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->dev.parent = &pdev->dev;
+	input_dev->open = imx_keypad_open;
+	input_dev->close = imx_keypad_close;
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+	input_dev->keycode = keypad->keycodes;
+	input_dev->keycodesize = sizeof(keypad->keycodes[0]);
+	input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes);
+
+	matrix_keypad_build_keymap(keymap_data, MATRIX_ROW_SHIFT,
+				keypad->keycodes, input_dev->keybit);
+
+	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+	input_set_drvdata(input_dev, keypad);
+
+	/* Ensure that the keypad will stay dormant until opened */
+	imx_keypad_inhibit(keypad);
+
+	error = request_irq(irq, imx_keypad_irq_handler, IRQF_DISABLED,
+			    pdev->name, keypad);
+	if (error) {
+		dev_err(&pdev->dev, "failed to request IRQ\n");
+		goto failed_clock_put;
+	}
+
+	/* Register the input device */
+	error = input_register_device(input_dev);
+	if (error) {
+		dev_err(&pdev->dev, "failed to register input device\n");
+		goto failed_free_irq;
+	}
+
+	platform_set_drvdata(pdev, keypad);
+	device_init_wakeup(&pdev->dev, 1);
+
+	return 0;
+
+failed_free_irq:
+	free_irq(irq, pdev);
+failed_clock_put:
+	clk_put(keypad->clk);
+failed_unmap:
+	iounmap(keypad->mmio_base);
+failed_free_priv:
+	kfree(keypad);
+failed_free_input:
+	input_free_device(input_dev);
+failed_rel_mem:
+	release_mem_region(res->start, resource_size(res));
+	return error;
+}
+
+static int __devexit imx_keypad_remove(struct platform_device *pdev)
+{
+	struct imx_keypad *keypad = platform_get_drvdata(pdev);
+	struct resource *res;
+
+	dev_dbg(&pdev->dev, ">%s\n", __func__);
+
+	platform_set_drvdata(pdev, NULL);
+
+	input_unregister_device(keypad->input_dev);
+
+	free_irq(keypad->irq, keypad);
+	clk_put(keypad->clk);
+
+	iounmap(keypad->mmio_base);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, resource_size(res));
+
+	kfree(keypad);
+
+	return 0;
+}
+
+static struct platform_driver imx_keypad_driver = {
+	.driver		= {
+		.name	= "imx-keypad",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= imx_keypad_probe,
+	.remove		= __devexit_p(imx_keypad_remove),
+};
+
+static int __init imx_keypad_init(void)
+{
+	return platform_driver_register(&imx_keypad_driver);
+}
+
+static void __exit imx_keypad_exit(void)
+{
+	platform_driver_unregister(&imx_keypad_driver);
+}
+
+module_init(imx_keypad_init);
+module_exit(imx_keypad_exit);
+
+MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>");
+MODULE_DESCRIPTION("IMX Keypad Port Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:imx-keypad");
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/jornada680_kbd.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/jornada680_kbd.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/jornada680_kbd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/jornada680_kbd.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/delay.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/jornada720_kbd.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/jornada720_kbd.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/jornada720_kbd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/jornada720_kbd.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <mach/jornada720.h>
 #include <mach/hardware.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/Kconfig linux-libre-2.6.34-gnu1/drivers/input/keyboard/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -35,10 +35,10 @@ config KEYBOARD_ADP5520
 	  be called adp5520-keys.
 
 config KEYBOARD_ADP5588
-	tristate "ADP5588 I2C QWERTY Keypad and IO Expander"
+	tristate "ADP5588/87 I2C QWERTY Keypad and IO Expander"
 	depends on I2C
 	help
-	  Say Y here if you want to use a ADP5588 attached to your
+	  Say Y here if you want to use a ADP5588/87 attached to your
 	  system I2C bus.
 
 	  To compile this driver as a module, choose M here: the
@@ -144,13 +144,15 @@ config KEYBOARD_BFIN
 	  module will be called bf54x-keys.
 
 config KEYBOARD_CORGI
-	tristate "Corgi keyboard"
+	tristate "Corgi keyboard (deprecated)"
 	depends on PXA_SHARPSL
-	default y
 	help
 	  Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx
 	  series of PDAs.
 
+	  This driver is now deprecated, use generic GPIO based matrix
+	  keyboard driver instead.
+
 	  To compile this driver as a module, choose M here: the
 	  module will be called corgikbd.
 
@@ -292,6 +294,15 @@ config KEYBOARD_MAX7359
 	  To compile this driver as a module, choose M here: the
 	  module will be called max7359_keypad.
 
+config KEYBOARD_IMX
+	tristate "IMX keypad support"
+	depends on ARCH_MXC
+	help
+	  Enable support for IMX keypad port.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called imx_keypad.
+
 config KEYBOARD_NEWTON
 	tristate "Newton keyboard"
 	select SERIO
@@ -329,13 +340,15 @@ config KEYBOARD_PXA930_ROTARY
 	  module will be called pxa930_rotary.
 
 config KEYBOARD_SPITZ
-	tristate "Spitz keyboard"
+	tristate "Spitz keyboard (deprecated)"
 	depends on PXA_SHARPSL
-	default y
 	help
 	  Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000,
 	  SL-C3000 and Sl-C3100 series of PDAs.
 
+	  This driver is now deprecated, use generic GPIO based matrix
+	  keyboard driver instead.
+
 	  To compile this driver as a module, choose M here: the
 	  module will be called spitzkbd.
 
@@ -363,7 +376,7 @@ config KEYBOARD_SUNKBD
 
 config KEYBOARD_SH_KEYSC
 	tristate "SuperH KEYSC keypad support"
-	depends on SUPERH
+	depends on SUPERH || ARCH_SHMOBILE
 	help
 	  Say Y here if you want to use a keypad attached to the KEYSC block
 	  on SuperH processors such as sh7722 and sh7343.
@@ -402,12 +415,14 @@ config KEYBOARD_TWL4030
 	  module will be called twl4030_keypad.
 
 config KEYBOARD_TOSA
-	tristate "Tosa keyboard"
+	tristate "Tosa keyboard (deprecated)"
 	depends on MACH_TOSA
-	default y
 	help
 	  Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa)
 
+	  This driver is now deprecated, use generic GPIO based matrix
+	  keyboard driver instead.
+
 	  To compile this driver as a module, choose M here: the
 	  module will be called tosakbd.
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/lm8323.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/lm8323.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/lm8323.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/lm8323.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/input.h>
 #include <linux/leds.h>
 #include <linux/i2c/lm8323.h>
+#include <linux/slab.h>
 
 /* Commands to send to the chip. */
 #define LM8323_CMD_READ_ID		0x80 /* Read chip ID. */
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/locomokbd.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/locomokbd.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/locomokbd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/locomokbd.c	2010-05-16 17:17:36.000000000 -0400
@@ -192,11 +192,18 @@ static void locomokbd_scankeyboard(struc
 static irqreturn_t locomokbd_interrupt(int irq, void *dev_id)
 {
 	struct locomokbd *locomokbd = dev_id;
+	u16 r;
+
+	r = locomo_readl(locomokbd->base + LOCOMO_KIC);
+	if ((r & 0x0001) == 0)
+		return IRQ_HANDLED;
+
+	locomo_writel(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */
+
 	/** wait chattering delay **/
 	udelay(100);
 
 	locomokbd_scankeyboard(locomokbd);
-
 	return IRQ_HANDLED;
 }
 
@@ -210,6 +217,25 @@ static void locomokbd_timer_callback(uns
 	locomokbd_scankeyboard(locomokbd);
 }
 
+static int locomokbd_open(struct input_dev *dev)
+{
+	struct locomokbd *locomokbd = input_get_drvdata(dev);
+	u16 r;
+	
+	r = locomo_readl(locomokbd->base + LOCOMO_KIC) | 0x0010;
+	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
+	return 0;
+}
+
+static void locomokbd_close(struct input_dev *dev)
+{
+	struct locomokbd *locomokbd = input_get_drvdata(dev);
+	u16 r;
+	
+	r = locomo_readl(locomokbd->base + LOCOMO_KIC) & ~0x0010;
+	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
+}
+
 static int __devinit locomokbd_probe(struct locomo_dev *dev)
 {
 	struct locomokbd *locomokbd;
@@ -253,6 +279,8 @@ static int __devinit locomokbd_probe(str
 	input_dev->id.vendor = 0x0001;
 	input_dev->id.product = 0x0001;
 	input_dev->id.version = 0x0100;
+	input_dev->open = locomokbd_open;
+	input_dev->close = locomokbd_close;
 	input_dev->dev.parent = &dev->dev;
 
 	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
@@ -261,6 +289,8 @@ static int __devinit locomokbd_probe(str
 	input_dev->keycodesize = sizeof(locomokbd_keycode[0]);
 	input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode);
 
+	input_set_drvdata(input_dev, locomokbd);
+
 	memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
 	for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
 		set_bit(locomokbd->keycode[i], input_dev->keybit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/Makefile linux-libre-2.6.34-gnu1/drivers/input/keyboard/Makefile
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@ obj-$(CONFIG_KEYBOARD_EP93XX)		+= ep93xx
 obj-$(CONFIG_KEYBOARD_GPIO)		+= gpio_keys.o
 obj-$(CONFIG_KEYBOARD_HIL)		+= hil_kbd.o
 obj-$(CONFIG_KEYBOARD_HIL_OLD)		+= hilkbd.o
+obj-$(CONFIG_KEYBOARD_IMX)		+= imx_keypad.o
 obj-$(CONFIG_KEYBOARD_HP6XX)		+= jornada680_kbd.o
 obj-$(CONFIG_KEYBOARD_HP7XX)		+= jornada720_kbd.o
 obj-$(CONFIG_KEYBOARD_LKKBD)		+= lkkbd.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/matrix_keypad.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/matrix_keypad.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/matrix_keypad.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/matrix_keypad.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/gpio.h>
 #include <linux/input/matrix_keypad.h>
+#include <linux/slab.h>
 
 struct matrix_keypad {
 	const struct matrix_keypad_platform_data *pdata;
@@ -373,7 +374,9 @@ static int __devinit matrix_keypad_probe
 	input_dev->name		= pdev->name;
 	input_dev->id.bustype	= BUS_HOST;
 	input_dev->dev.parent	= &pdev->dev;
-	input_dev->evbit[0]	= BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+	input_dev->evbit[0]	= BIT_MASK(EV_KEY);
+	if (!pdata->no_autorepeat)
+		input_dev->evbit[0] |= BIT_MASK(EV_REP);
 	input_dev->open		= matrix_keypad_start;
 	input_dev->close	= matrix_keypad_stop;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/max7359_keypad.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/max7359_keypad.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/max7359_keypad.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/max7359_keypad.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 
 #include <linux/module.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/input/matrix_keypad.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/omap-keypad.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/omap-keypad.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/omap-keypad.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/omap-keypad.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <mach/gpio.h>
 #include <plat/keypad.h>
 #include <plat/menelaus.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/opencores-kbd.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/opencores-kbd.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/opencores-kbd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/opencores-kbd.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 struct opencores_kbd {
 	struct input_dev *input;
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/pxa27x_keypad.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/pxa27x_keypad.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/pxa27x_keypad.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/pxa27x_keypad.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/input/matrix_keypad.h>
+#include <linux/slab.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/pxa930_rotary.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/pxa930_rotary.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/pxa930_rotary.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/pxa930_rotary.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/input.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/pxa930_rotary.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/qt2160.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/qt2160.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/qt2160.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/qt2160.c	2010-05-16 17:17:36.000000000 -0400
@@ -362,7 +362,7 @@ static int __devexit qt2160_remove(struc
 	return 0;
 }
 
-static struct i2c_device_id qt2160_idtable[] = {
+static const struct i2c_device_id qt2160_idtable[] = {
 	{ "qt2160", 0, },
 	{ }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/sh_keysc.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/sh_keysc.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/sh_keysc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/sh_keysc.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,16 +19,10 @@
 #include <linux/platform_device.h>
 #include <linux/input.h>
 #include <linux/input/sh_keysc.h>
+#include <linux/bitmap.h>
 #include <linux/clk.h>
 #include <linux/io.h>
-
-#define KYCR1_OFFS   0x00
-#define KYCR2_OFFS   0x04
-#define KYINDR_OFFS  0x08
-#define KYOUTDR_OFFS 0x0c
-
-#define KYCR2_IRQ_LEVEL    0x10
-#define KYCR2_IRQ_DISABLED 0x00
+#include <linux/slab.h>
 
 static const struct {
 	unsigned char kymd, keyout, keyin;
@@ -36,84 +30,131 @@ static const struct {
 	[SH_KEYSC_MODE_1] = { 0, 6, 5 },
 	[SH_KEYSC_MODE_2] = { 1, 5, 6 },
 	[SH_KEYSC_MODE_3] = { 2, 4, 7 },
+	[SH_KEYSC_MODE_4] = { 3, 6, 6 },
+	[SH_KEYSC_MODE_5] = { 4, 6, 7 },
+	[SH_KEYSC_MODE_6] = { 5, 7, 7 },
 };
 
 struct sh_keysc_priv {
 	void __iomem *iomem_base;
 	struct clk *clk;
-	unsigned long last_keys;
+	DECLARE_BITMAP(last_keys, SH_KEYSC_MAXKEYS);
 	struct input_dev *input;
 	struct sh_keysc_info pdata;
 };
 
+#define KYCR1 0
+#define KYCR2 1
+#define KYINDR 2
+#define KYOUTDR 3
+
+#define KYCR2_IRQ_LEVEL    0x10
+#define KYCR2_IRQ_DISABLED 0x00
+
+static unsigned long sh_keysc_read(struct sh_keysc_priv *p, int reg_nr)
+{
+	return ioread16(p->iomem_base + (reg_nr << 2));
+}
+
+static void sh_keysc_write(struct sh_keysc_priv *p, int reg_nr,
+			   unsigned long value)
+{
+	iowrite16(value, p->iomem_base + (reg_nr << 2));
+}
+
+static void sh_keysc_level_mode(struct sh_keysc_priv *p,
+				unsigned long keys_set)
+{
+	struct sh_keysc_info *pdata = &p->pdata;
+
+	sh_keysc_write(p, KYOUTDR, 0);
+	sh_keysc_write(p, KYCR2, KYCR2_IRQ_LEVEL | (keys_set << 8));
+
+	if (pdata->kycr2_delay)
+		udelay(pdata->kycr2_delay);
+}
+
+static void sh_keysc_map_dbg(struct device *dev, unsigned long *map,
+			     const char *str)
+{
+	int k;
+
+	for (k = 0; k < BITS_TO_LONGS(SH_KEYSC_MAXKEYS); k++)
+		dev_dbg(dev, "%s[%d] 0x%lx\n", str, k, map[k]);
+}
+
 static irqreturn_t sh_keysc_isr(int irq, void *dev_id)
 {
 	struct platform_device *pdev = dev_id;
 	struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
 	struct sh_keysc_info *pdata = &priv->pdata;
-	unsigned long keys, keys1, keys0, mask;
+	int keyout_nr = sh_keysc_mode[pdata->mode].keyout;
+	int keyin_nr = sh_keysc_mode[pdata->mode].keyin;
+	DECLARE_BITMAP(keys, SH_KEYSC_MAXKEYS);
+	DECLARE_BITMAP(keys0, SH_KEYSC_MAXKEYS);
+	DECLARE_BITMAP(keys1, SH_KEYSC_MAXKEYS);
 	unsigned char keyin_set, tmp;
-	int i, k;
+	int i, k, n;
 
 	dev_dbg(&pdev->dev, "isr!\n");
 
-	keys1 = ~0;
-	keys0 = 0;
+	bitmap_fill(keys1, SH_KEYSC_MAXKEYS);
+	bitmap_zero(keys0, SH_KEYSC_MAXKEYS);
 
 	do {
-		keys = 0;
+		bitmap_zero(keys, SH_KEYSC_MAXKEYS);
 		keyin_set = 0;
 
-		iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS);
+		sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED);
 
-		for (i = 0; i < sh_keysc_mode[pdata->mode].keyout; i++) {
-			iowrite16(0xfff ^ (3 << (i * 2)),
-				  priv->iomem_base + KYOUTDR_OFFS);
+		for (i = 0; i < keyout_nr; i++) {
+			n = keyin_nr * i;
+
+			/* drive one KEYOUT pin low, read KEYIN pins */
+			sh_keysc_write(priv, KYOUTDR, 0xffff ^ (3 << (i * 2)));
 			udelay(pdata->delay);
-			tmp = ioread16(priv->iomem_base + KYINDR_OFFS);
-			keys |= tmp << (sh_keysc_mode[pdata->mode].keyin * i);
-			tmp ^= (1 << sh_keysc_mode[pdata->mode].keyin) - 1;
-			keyin_set |= tmp;
-		}
+			tmp = sh_keysc_read(priv, KYINDR);
 
-		iowrite16(0, priv->iomem_base + KYOUTDR_OFFS);
-		iowrite16(KYCR2_IRQ_LEVEL | (keyin_set << 8),
-			  priv->iomem_base + KYCR2_OFFS);
+			/* set bit if key press has been detected */
+			for (k = 0; k < keyin_nr; k++) {
+				if (tmp & (1 << k))
+					__set_bit(n + k, keys);
+			}
 
-		if (pdata->kycr2_delay)
-			udelay(pdata->kycr2_delay);
+			/* keep track of which KEYIN bits that have been set */
+			keyin_set |= tmp ^ ((1 << keyin_nr) - 1);
+		}
 
-		keys ^= ~0;
-		keys &= (1 << (sh_keysc_mode[pdata->mode].keyin *
-			       sh_keysc_mode[pdata->mode].keyout)) - 1;
-		keys1 &= keys;
-		keys0 |= keys;
+		sh_keysc_level_mode(priv, keyin_set);
 
-		dev_dbg(&pdev->dev, "keys 0x%08lx\n", keys);
+		bitmap_complement(keys, keys, SH_KEYSC_MAXKEYS);
+		bitmap_and(keys1, keys1, keys, SH_KEYSC_MAXKEYS);
+		bitmap_or(keys0, keys0, keys, SH_KEYSC_MAXKEYS);
 
-	} while (ioread16(priv->iomem_base + KYCR2_OFFS) & 0x01);
+		sh_keysc_map_dbg(&pdev->dev, keys, "keys");
 
-	dev_dbg(&pdev->dev, "last_keys 0x%08lx keys0 0x%08lx keys1 0x%08lx\n",
-		priv->last_keys, keys0, keys1);
+	} while (sh_keysc_read(priv, KYCR2) & 0x01);
+
+	sh_keysc_map_dbg(&pdev->dev, priv->last_keys, "last_keys");
+	sh_keysc_map_dbg(&pdev->dev, keys0, "keys0");
+	sh_keysc_map_dbg(&pdev->dev, keys1, "keys1");
 
 	for (i = 0; i < SH_KEYSC_MAXKEYS; i++) {
 		k = pdata->keycodes[i];
 		if (!k)
 			continue;
 
-		mask = 1 << i;
-
-		if (!((priv->last_keys ^ keys0) & mask))
+		if (test_bit(i, keys0) == test_bit(i, priv->last_keys))
 			continue;
 
-		if ((keys1 | keys0) & mask) {
+		if (test_bit(i, keys1) || test_bit(i, keys0)) {
 			input_event(priv->input, EV_KEY, k, 1);
-			priv->last_keys |= mask;
+			__set_bit(i, priv->last_keys);
 		}
 
-		if (!(keys1 & mask)) {
+		if (!test_bit(i, keys1)) {
 			input_event(priv->input, EV_KEY, k, 0);
-			priv->last_keys &= ~mask;
+			__clear_bit(i, priv->last_keys);
 		}
 
 	}
@@ -122,8 +163,6 @@ static irqreturn_t sh_keysc_isr(int irq,
 	return IRQ_HANDLED;
 }
 
-#define res_size(res) ((res)->end - (res)->start + 1)
-
 static int __devinit sh_keysc_probe(struct platform_device *pdev)
 {
 	struct sh_keysc_priv *priv;
@@ -164,7 +203,7 @@ static int __devinit sh_keysc_probe(stru
 	memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata));
 	pdata = &priv->pdata;
 
-	priv->iomem_base = ioremap_nocache(res->start, res_size(res));
+	priv->iomem_base = ioremap_nocache(res->start, resource_size(res));
 	if (priv->iomem_base == NULL) {
 		dev_err(&pdev->dev, "failed to remap I/O memory\n");
 		error = -ENXIO;
@@ -220,10 +259,9 @@ static int __devinit sh_keysc_probe(stru
 
 	clk_enable(priv->clk);
 
-	iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) |
-		  pdata->scan_timing, priv->iomem_base + KYCR1_OFFS);
-	iowrite16(0, priv->iomem_base + KYOUTDR_OFFS);
-	iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS);
+	sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) |
+		       pdata->scan_timing);
+	sh_keysc_level_mode(priv, 0);
 
 	device_init_wakeup(&pdev->dev, 1);
 
@@ -248,7 +286,7 @@ static int __devexit sh_keysc_remove(str
 {
 	struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
 
-	iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS);
+	sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED);
 
 	input_unregister_device(priv->input);
 	free_irq(platform_get_irq(pdev, 0), pdev);
@@ -270,7 +308,7 @@ static int sh_keysc_suspend(struct devic
 	int irq = platform_get_irq(pdev, 0);
 	unsigned short value;
 
-	value = ioread16(priv->iomem_base + KYCR1_OFFS);
+	value = sh_keysc_read(priv, KYCR1);
 
 	if (device_may_wakeup(dev)) {
 		value |= 0x80;
@@ -279,7 +317,7 @@ static int sh_keysc_suspend(struct devic
 		value &= ~0x80;
 	}
 
-	iowrite16(value, priv->iomem_base + KYCR1_OFFS);
+	sh_keysc_write(priv, KYCR1, value);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/tosakbd.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/tosakbd.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/tosakbd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/tosakbd.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/input.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include <mach/gpio.h>
 #include <mach/tosa.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/twl4030_keypad.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/twl4030_keypad.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/twl4030_keypad.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/twl4030_keypad.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/input.h>
 #include <linux/platform_device.h>
 #include <linux/i2c/twl.h>
+#include <linux/slab.h>
 
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/keyboard/w90p910_keypad.c linux-libre-2.6.34-gnu1/drivers/input/keyboard/w90p910_keypad.c
--- linux-libre-2.6.33-gnu1/drivers/input/keyboard/w90p910_keypad.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/keyboard/w90p910_keypad.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/w90p910_keypad.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/88pm860x_onkey.c linux-libre-2.6.34-gnu1/drivers/input/misc/88pm860x_onkey.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/88pm860x_onkey.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/88pm860x_onkey.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,156 @@
+/*
+ * 88pm860x_onkey.c - Marvell 88PM860x ONKEY driver
+ *
+ * Copyright (C) 2009-2010 Marvell International Ltd.
+ *      Haojian Zhuang <haojian.zhuang@marvell.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/88pm860x.h>
+#include <linux/slab.h>
+
+#define PM8607_WAKEUP		0x0b
+
+#define LONG_ONKEY_EN		(1 << 1)
+#define ONKEY_STATUS		(1 << 0)
+
+struct pm860x_onkey_info {
+	struct input_dev	*idev;
+	struct pm860x_chip	*chip;
+	struct i2c_client	*i2c;
+	struct device		*dev;
+	int			irq;
+};
+
+/* 88PM860x gives us an interrupt when ONKEY is held */
+static irqreturn_t pm860x_onkey_handler(int irq, void *data)
+{
+	struct pm860x_onkey_info *info = data;
+	int ret;
+
+	ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2);
+	ret &= ONKEY_STATUS;
+	input_report_key(info->idev, KEY_POWER, ret);
+	input_sync(info->idev);
+
+	/* Enable 8-second long onkey detection */
+	pm860x_set_bits(info->i2c, PM8607_WAKEUP, 3, LONG_ONKEY_EN);
+	return IRQ_HANDLED;
+}
+
+static int __devinit pm860x_onkey_probe(struct platform_device *pdev)
+{
+	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct pm860x_onkey_info *info;
+	int irq, ret;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "No IRQ resource!\n");
+		return -EINVAL;
+	}
+
+	info = kzalloc(sizeof(struct pm860x_onkey_info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+	info->chip = chip;
+	info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+	info->dev = &pdev->dev;
+	info->irq = irq + chip->irq_base;
+
+	info->idev = input_allocate_device();
+	if (!info->idev) {
+		dev_err(chip->dev, "Failed to allocate input dev\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	info->idev->name = "88pm860x_on";
+	info->idev->phys = "88pm860x_on/input0";
+	info->idev->id.bustype = BUS_I2C;
+	info->idev->dev.parent = &pdev->dev;
+	info->irq = irq;
+	info->idev->evbit[0] = BIT_MASK(EV_KEY);
+	info->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
+
+	ret = input_register_device(info->idev);
+	if (ret) {
+		dev_err(chip->dev, "Can't register input device: %d\n", ret);
+		goto out_reg;
+	}
+
+	ret = request_threaded_irq(info->irq, NULL, pm860x_onkey_handler,
+				   IRQF_ONESHOT, "onkey", info);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
+			info->irq, ret);
+		goto out_irq;
+	}
+
+	platform_set_drvdata(pdev, info);
+	return 0;
+
+out_irq:
+	input_unregister_device(info->idev);
+	kfree(info);
+	return ret;
+
+out_reg:
+	input_free_device(info->idev);
+out:
+	kfree(info);
+	return ret;
+}
+
+static int __devexit pm860x_onkey_remove(struct platform_device *pdev)
+{
+	struct pm860x_onkey_info *info = platform_get_drvdata(pdev);
+
+	free_irq(info->irq, info);
+	input_unregister_device(info->idev);
+	kfree(info);
+	return 0;
+}
+
+static struct platform_driver pm860x_onkey_driver = {
+	.driver		= {
+		.name	= "88pm860x-onkey",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= pm860x_onkey_probe,
+	.remove		= __devexit_p(pm860x_onkey_remove),
+};
+
+static int __init pm860x_onkey_init(void)
+{
+	return platform_driver_register(&pm860x_onkey_driver);
+}
+module_init(pm860x_onkey_init);
+
+static void __exit pm860x_onkey_exit(void)
+{
+	platform_driver_unregister(&pm860x_onkey_driver);
+}
+module_exit(pm860x_onkey_exit);
+
+MODULE_DESCRIPTION("Marvell 88PM860x ONKEY driver");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/apanel.c linux-libre-2.6.34-gnu1/drivers/input/misc/apanel.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/apanel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/apanel.c	2010-05-16 17:17:36.000000000 -0400
@@ -149,7 +149,7 @@ static void apanel_shutdown(struct i2c_c
 	apanel_remove(client);
 }
 
-static struct i2c_device_id apanel_id[] = {
+static const struct i2c_device_id apanel_id[] = {
 	{ "fujitsu_apanel", 0 },
 	{ }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/ati_remote2.c linux-libre-2.6.34-gnu1/drivers/input/misc/ati_remote2.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/ati_remote2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/ati_remote2.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/usb/input.h>
+#include <linux/slab.h>
 
 #define DRIVER_DESC    "ATI/Philips USB RF remote driver"
 #define DRIVER_VERSION "0.3"
@@ -474,10 +475,11 @@ static void ati_remote2_complete_key(str
 }
 
 static int ati_remote2_getkeycode(struct input_dev *idev,
-				  int scancode, int *keycode)
+				  unsigned int scancode, unsigned int *keycode)
 {
 	struct ati_remote2 *ar2 = input_get_drvdata(idev);
-	int index, mode;
+	unsigned int mode;
+	int index;
 
 	mode = scancode >> 8;
 	if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
@@ -491,10 +493,12 @@ static int ati_remote2_getkeycode(struct
 	return 0;
 }
 
-static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keycode)
+static int ati_remote2_setkeycode(struct input_dev *idev,
+				  unsigned int scancode, unsigned int keycode)
 {
 	struct ati_remote2 *ar2 = input_get_drvdata(idev);
-	int index, mode, old_keycode;
+	unsigned int mode, old_keycode;
+	int index;
 
 	mode = scancode >> 8;
 	if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
@@ -504,9 +508,6 @@ static int ati_remote2_setkeycode(struct
 	if (index < 0)
 		return -EINVAL;
 
-	if (keycode < KEY_RESERVED || keycode > KEY_MAX)
-		return -EINVAL;
-
 	old_keycode = ar2->keycode[mode][index];
 	ar2->keycode[mode][index] = keycode;
 	__set_bit(keycode, idev->keybit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/ati_remote.c linux-libre-2.6.34-gnu1/drivers/input/misc/ati_remote.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/ati_remote.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/ati_remote.c	2010-05-16 17:17:36.000000000 -0400
@@ -98,10 +98,12 @@
  * Module and Version Information, Module Parameters
  */
 
-#define ATI_REMOTE_VENDOR_ID	0x0bc7
-#define ATI_REMOTE_PRODUCT_ID	0x004
-#define LOLA_REMOTE_PRODUCT_ID	0x002
-#define MEDION_REMOTE_PRODUCT_ID 0x006
+#define ATI_REMOTE_VENDOR_ID		0x0bc7
+#define LOLA_REMOTE_PRODUCT_ID		0x0002
+#define LOLA2_REMOTE_PRODUCT_ID		0x0003
+#define ATI_REMOTE_PRODUCT_ID		0x0004
+#define NVIDIA_REMOTE_PRODUCT_ID	0x0005
+#define MEDION_REMOTE_PRODUCT_ID	0x0006
 
 #define DRIVER_VERSION	        "2.2.1"
 #define DRIVER_AUTHOR           "Torrey Hoffman <thoffman@arnor.net>"
@@ -142,8 +144,10 @@ MODULE_PARM_DESC(repeat_delay, "Delay be
 #define err(format, arg...) printk(KERN_ERR format , ## arg)
 
 static struct usb_device_id ati_remote_table[] = {
-	{ USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) },
 	{ USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) },
+	{ USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA2_REMOTE_PRODUCT_ID) },
+	{ USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) },
+	{ USB_DEVICE(ATI_REMOTE_VENDOR_ID, NVIDIA_REMOTE_PRODUCT_ID) },
 	{ USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID) },
 	{}	/* Terminating entry */
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/atlas_btns.c linux-libre-2.6.34-gnu1/drivers/input/misc/atlas_btns.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/atlas_btns.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/atlas_btns.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,7 +47,7 @@ static acpi_status acpi_atlas_button_set
 
 static acpi_status acpi_atlas_button_handler(u32 function,
 		      acpi_physical_address address,
-		      u32 bit_width, acpi_integer *value,
+		      u32 bit_width, u64 *value,
 		      void *handler_context, void *region_context)
 {
 	acpi_status status;
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/bfin_rotary.c linux-libre-2.6.34-gnu1/drivers/input/misc/bfin_rotary.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/bfin_rotary.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/bfin_rotary.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/pm.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 
 #include <asm/portmux.h>
 #include <asm/bfin_rotary.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/cobalt_btns.c linux-libre-2.6.34-gnu1/drivers/input/misc/cobalt_btns.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/cobalt_btns.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/cobalt_btns.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #define BUTTONS_POLL_INTERVAL	30	/* msec */
 #define BUTTONS_COUNT_THRESHOLD	3
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/dm355evm_keys.c linux-libre-2.6.34-gnu1/drivers/input/misc/dm355evm_keys.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/dm355evm_keys.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/dm355evm_keys.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
 #include <linux/platform_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/Kconfig linux-libre-2.6.34-gnu1/drivers/input/misc/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/input/misc/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,16 @@ menuconfig INPUT_MISC
 
 if INPUT_MISC
 
+config INPUT_88PM860X_ONKEY
+	tristate "88PM860x ONKEY support"
+	depends on MFD_88PM860X
+	help
+	  Support the ONKEY of Marvell 88PM860x PMICs as an input device
+	  reporting power button status.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called 88pm860x_onkey.
+
 config INPUT_PCSPKR
 	tristate "PC Speaker support"
 	depends on PCSPKR_PLATFORM
@@ -204,6 +214,17 @@ config INPUT_TWL4030_PWRBUTTON
 	  To compile this driver as a module, choose M here. The module will
 	  be called twl4030_pwrbutton.
 
+config INPUT_TWL4030_VIBRA
+	tristate "Support for TWL4030 Vibrator"
+	depends on TWL4030_CORE
+	select TWL4030_CODEC
+	select INPUT_FF_MEMLESS
+	help
+	  This option enables support for TWL4030 Vibrator Driver.
+
+	  To compile this driver as a module, choose M here. The module will
+	  be called twl4030_vibra.
+
 config INPUT_UINPUT
 	tristate "User level driver support"
 	help
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/Makefile linux-libre-2.6.34-gnu1/drivers/input/misc/Makefile
--- linux-libre-2.6.33-gnu1/drivers/input/misc/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
 
 # Each configuration option enables a list of files.
 
+obj-$(CONFIG_INPUT_88PM860X_ONKEY)	+= 88pm860x_onkey.o
 obj-$(CONFIG_INPUT_APANEL)		+= apanel.o
 obj-$(CONFIG_INPUT_ATI_REMOTE)		+= ati_remote.o
 obj-$(CONFIG_INPUT_ATI_REMOTE2)		+= ati_remote2.o
@@ -25,6 +26,7 @@ obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)
 obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
 obj-$(CONFIG_INPUT_SPARCSPKR)		+= sparcspkr.o
 obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON)	+= twl4030-pwrbutton.o
+obj-$(CONFIG_INPUT_TWL4030_VIBRA)	+= twl4030-vibra.o
 obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
 obj-$(CONFIG_INPUT_WINBOND_CIR)		+= winbond-cir.o
 obj-$(CONFIG_INPUT_WISTRON_BTNS)	+= wistron_btns.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/pcap_keys.c linux-libre-2.6.34-gnu1/drivers/input/misc/pcap_keys.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/pcap_keys.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/pcap_keys.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/input.h>
 #include <linux/mfd/ezx-pcap.h>
+#include <linux/slab.h>
 
 struct pcap_keys {
 	struct pcap_chip *pcap;
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/pcf50633-input.c linux-libre-2.6.34-gnu1/drivers/input/misc/pcf50633-input.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/pcf50633-input.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/pcf50633-input.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/pcf50633/core.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/rotary_encoder.c linux-libre-2.6.34-gnu1/drivers/input/misc/rotary_encoder.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/rotary_encoder.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/rotary_encoder.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/rotary_encoder.h>
+#include <linux/slab.h>
 
 #define DRV_NAME "rotary-encoder"
 
@@ -152,12 +153,26 @@ static int __devinit rotary_encoder_prob
 		goto exit_unregister_input;
 	}
 
+	err = gpio_direction_input(pdata->gpio_a);
+	if (err) {
+		dev_err(&pdev->dev, "unable to set GPIO %d for input\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;
 	}
+
+	err = gpio_direction_input(pdata->gpio_b);
+	if (err) {
+		dev_err(&pdev->dev, "unable to set GPIO %d for input\n",
+			pdata->gpio_b);
+		goto exit_free_gpio_a;
+	}
 
 	/* request the IRQs */
 	err = request_irq(encoder->irq_a, &rotary_encoder_irq,
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/sgi_btns.c linux-libre-2.6.34-gnu1/drivers/input/misc/sgi_btns.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/sgi_btns.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/sgi_btns.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_SGI_IP22
 #include <asm/sgi/ioc.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/sparcspkr.c linux-libre-2.6.34-gnu1/drivers/input/misc/sparcspkr.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/sparcspkr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/sparcspkr.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/of_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/twl4030-vibra.c linux-libre-2.6.34-gnu1/drivers/input/misc/twl4030-vibra.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/twl4030-vibra.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/twl4030-vibra.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,298 @@
+/*
+ * twl4030-vibra.c - TWL4030 Vibrator driver
+ *
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Written by Henrik Saari <henrik.saari@nokia.com>
+ * Updates by Felipe Balbi <felipe.balbi@nokia.com>
+ * Input by Jari Vanhala <ext-jari.vanhala@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/i2c/twl.h>
+#include <linux/mfd/twl4030-codec.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+
+/* MODULE ID2 */
+#define LEDEN		0x00
+
+/* ForceFeedback */
+#define EFFECT_DIR_180_DEG	0x8000 /* range is 0 - 0xFFFF */
+
+struct vibra_info {
+	struct device		*dev;
+	struct input_dev	*input_dev;
+
+	struct workqueue_struct *workqueue;
+	struct work_struct	play_work;
+
+	bool			enabled;
+	int			speed;
+	int			direction;
+
+	bool			coexist;
+};
+
+static void vibra_disable_leds(void)
+{
+	u8 reg;
+
+	/* Disable LEDA & LEDB, cannot be used with vibra (PWM) */
+	twl_i2c_read_u8(TWL4030_MODULE_LED, &reg, LEDEN);
+	reg &= ~0x03;
+	twl_i2c_write_u8(TWL4030_MODULE_LED, LEDEN, reg);
+}
+
+/* Powers H-Bridge and enables audio clk */
+static void vibra_enable(struct vibra_info *info)
+{
+	u8 reg;
+
+	twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER);
+
+	/* turn H-Bridge on */
+	twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+			&reg, TWL4030_REG_VIBRA_CTL);
+	twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+			 (reg | TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
+
+	twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL);
+
+	info->enabled = true;
+}
+
+static void vibra_disable(struct vibra_info *info)
+{
+	u8 reg;
+
+	/* Power down H-Bridge */
+	twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+			&reg, TWL4030_REG_VIBRA_CTL);
+	twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+			 (reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
+
+	twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);
+	twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL);
+
+	info->enabled = false;
+}
+
+static void vibra_play_work(struct work_struct *work)
+{
+	struct vibra_info *info = container_of(work,
+			struct vibra_info, play_work);
+	int dir;
+	int pwm;
+	u8 reg;
+
+	dir = info->direction;
+	pwm = info->speed;
+
+	twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+			&reg, TWL4030_REG_VIBRA_CTL);
+	if (pwm && (!info->coexist || !(reg & TWL4030_VIBRA_SEL))) {
+
+		if (!info->enabled)
+			vibra_enable(info);
+
+		/* set vibra rotation direction */
+		twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+				&reg, TWL4030_REG_VIBRA_CTL);
+		reg = (dir) ? (reg | TWL4030_VIBRA_DIR) :
+			(reg & ~TWL4030_VIBRA_DIR);
+		twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+				 reg, TWL4030_REG_VIBRA_CTL);
+
+		/* set PWM, 1 = max, 255 = min */
+		twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+				 256 - pwm, TWL4030_REG_VIBRA_SET);
+	} else {
+		if (info->enabled)
+			vibra_disable(info);
+	}
+}
+
+/*** Input/ForceFeedback ***/
+
+static int vibra_play(struct input_dev *input, void *data,
+		      struct ff_effect *effect)
+{
+	struct vibra_info *info = input_get_drvdata(input);
+
+	info->speed = effect->u.rumble.strong_magnitude >> 8;
+	if (!info->speed)
+		info->speed = effect->u.rumble.weak_magnitude >> 9;
+	info->direction = effect->direction < EFFECT_DIR_180_DEG ? 0 : 1;
+	queue_work(info->workqueue, &info->play_work);
+	return 0;
+}
+
+static int twl4030_vibra_open(struct input_dev *input)
+{
+	struct vibra_info *info = input_get_drvdata(input);
+
+	info->workqueue = create_singlethread_workqueue("vibra");
+	if (info->workqueue == NULL) {
+		dev_err(&input->dev, "couldn't create workqueue\n");
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static void twl4030_vibra_close(struct input_dev *input)
+{
+	struct vibra_info *info = input_get_drvdata(input);
+
+	cancel_work_sync(&info->play_work);
+	INIT_WORK(&info->play_work, vibra_play_work); /* cleanup */
+	destroy_workqueue(info->workqueue);
+	info->workqueue = NULL;
+
+	if (info->enabled)
+		vibra_disable(info);
+}
+
+/*** Module ***/
+#if CONFIG_PM
+static int twl4030_vibra_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct vibra_info *info = platform_get_drvdata(pdev);
+
+	if (info->enabled)
+		vibra_disable(info);
+
+	return 0;
+}
+
+static int twl4030_vibra_resume(struct device *dev)
+{
+	vibra_disable_leds();
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
+			 twl4030_vibra_suspend, twl4030_vibra_resume);
+#endif
+
+static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
+{
+	struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data;
+	struct vibra_info *info;
+	int ret;
+
+	if (!pdata) {
+		dev_dbg(&pdev->dev, "platform_data not available\n");
+		return -EINVAL;
+	}
+
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->dev = &pdev->dev;
+	info->coexist = pdata->coexist;
+	INIT_WORK(&info->play_work, vibra_play_work);
+
+	info->input_dev = input_allocate_device();
+	if (info->input_dev == NULL) {
+		dev_err(&pdev->dev, "couldn't allocate input device\n");
+		ret = -ENOMEM;
+		goto err_kzalloc;
+	}
+
+	input_set_drvdata(info->input_dev, info);
+
+	info->input_dev->name = "twl4030:vibrator";
+	info->input_dev->id.version = 1;
+	info->input_dev->dev.parent = pdev->dev.parent;
+	info->input_dev->open = twl4030_vibra_open;
+	info->input_dev->close = twl4030_vibra_close;
+	__set_bit(FF_RUMBLE, info->input_dev->ffbit);
+
+	ret = input_ff_create_memless(info->input_dev, NULL, vibra_play);
+	if (ret < 0) {
+		dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n");
+		goto err_ialloc;
+	}
+
+	ret = input_register_device(info->input_dev);
+	if (ret < 0) {
+		dev_dbg(&pdev->dev, "couldn't register input device\n");
+		goto err_iff;
+	}
+
+	vibra_disable_leds();
+
+	platform_set_drvdata(pdev, info);
+	return 0;
+
+err_iff:
+	input_ff_destroy(info->input_dev);
+err_ialloc:
+	input_free_device(info->input_dev);
+err_kzalloc:
+	kfree(info);
+	return ret;
+}
+
+static int __devexit twl4030_vibra_remove(struct platform_device *pdev)
+{
+	struct vibra_info *info = platform_get_drvdata(pdev);
+
+	/* this also free ff-memless and calls close if needed */
+	input_unregister_device(info->input_dev);
+	kfree(info);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver twl4030_vibra_driver = {
+	.probe		= twl4030_vibra_probe,
+	.remove		= __devexit_p(twl4030_vibra_remove),
+	.driver		= {
+		.name	= "twl4030_codec_vibra",
+		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	= &twl4030_vibra_pm_ops,
+#endif
+	},
+};
+
+static int __init twl4030_vibra_init(void)
+{
+	return platform_driver_register(&twl4030_vibra_driver);
+}
+module_init(twl4030_vibra_init);
+
+static void __exit twl4030_vibra_exit(void)
+{
+	platform_driver_unregister(&twl4030_vibra_driver);
+}
+module_exit(twl4030_vibra_exit);
+
+MODULE_ALIAS("platform:twl4030_codec_vibra");
+
+MODULE_DESCRIPTION("TWL4030 Vibra driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nokia Corporation");
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/uinput.c linux-libre-2.6.34-gnu1/drivers/input/misc/uinput.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/uinput.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/uinput.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,6 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
 #include <linux/uinput.h>
@@ -284,7 +283,6 @@ static int uinput_open(struct inode *ino
 	if (!newdev)
 		return -ENOMEM;
 
-	lock_kernel();
 	mutex_init(&newdev->mutex);
 	spin_lock_init(&newdev->requests_lock);
 	init_waitqueue_head(&newdev->requests_waitq);
@@ -292,7 +290,7 @@ static int uinput_open(struct inode *ino
 	newdev->state = UIST_NEW_DEVICE;
 
 	file->private_data = newdev;
-	unlock_kernel();
+	nonseekable_open(inode, file);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/winbond-cir.c linux-libre-2.6.34-gnu1/drivers/input/misc/winbond-cir.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/winbond-cir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/winbond-cir.c	2010-05-16 17:17:36.000000000 -0400
@@ -56,6 +56,7 @@
 #include <linux/io.h>
 #include <linux/bitrev.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 
 #define DRVNAME "winbond-cir"
 
@@ -385,26 +386,24 @@ wbcir_do_getkeycode(struct wbcir_data *d
 }
 
 static int
-wbcir_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+wbcir_getkeycode(struct input_dev *dev,
+		 unsigned int scancode, unsigned int *keycode)
 {
 	struct wbcir_data *data = input_get_drvdata(dev);
 
-	*keycode = (int)wbcir_do_getkeycode(data, (u32)scancode);
+	*keycode = wbcir_do_getkeycode(data, scancode);
 	return 0;
 }
 
 static int
-wbcir_setkeycode(struct input_dev *dev, int sscancode, int keycode)
+wbcir_setkeycode(struct input_dev *dev,
+		 unsigned int scancode, unsigned int keycode)
 {
 	struct wbcir_data *data = input_get_drvdata(dev);
 	struct wbcir_keyentry *keyentry;
 	struct wbcir_keyentry *new_keyentry;
 	unsigned long flags;
 	unsigned int old_keycode = KEY_RESERVED;
-	u32 scancode = (u32)sscancode;
-
-	if (keycode < 0 || keycode > KEY_MAX)
-		return -EINVAL;
 
 	new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL);
 	if (!new_keyentry)
@@ -538,6 +537,7 @@ wbcir_reset_irdata(struct wbcir_data *da
 	data->irdata_count = 0;
 	data->irdata_off = 0;
 	data->irdata_error = 0;
+	data->idle_count = 0;
 }
 
 /* Adds one bit of irdata */
@@ -1006,7 +1006,6 @@ wbcir_irq_handler(int irqno, void *cooki
 		}
 
 		wbcir_reset_irdata(data);
-		data->idle_count = 0;
 	}
 
 out:
@@ -1018,7 +1017,7 @@ out:
 
 /*****************************************************************************
  *
- * SUSPEND/RESUME FUNCTIONS
+ * SETUP/INIT/SUSPEND/RESUME FUNCTIONS
  *
  *****************************************************************************/
 
@@ -1197,7 +1196,16 @@ finish:
 	}
 
 	/* Disable interrupts */
+	wbcir_select_bank(data, WBCIR_BANK_0);
 	outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
+
+	/*
+	 * ACPI will set the HW disable bit for SP3 which means that the
+	 * output signals are left in an undefined state which may cause
+	 * spurious interrupts which we need to ignore until the hardware
+	 * is reinitialized.
+	 */
+	disable_irq(data->irq);
 }
 
 static int
@@ -1207,37 +1215,15 @@ wbcir_suspend(struct pnp_dev *device, pm
 	return 0;
 }
 
-static int
-wbcir_resume(struct pnp_dev *device)
-{
-	struct wbcir_data *data = pnp_get_drvdata(device);
-
-	/* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */
-	wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07);
-
-	/* Clear CEIR_EN */
-	wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01);
-
-	/* Enable interrupts */
-	wbcir_reset_irdata(data);
-	outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
-
-	return 0;
-}
-
-
-
-/*****************************************************************************
- *
- * SETUP/INIT FUNCTIONS
- *
- *****************************************************************************/
-
 static void
-wbcir_cfg_ceir(struct wbcir_data *data)
+wbcir_init_hw(struct wbcir_data *data)
 {
 	u8 tmp;
 
+	/* Disable interrupts */
+	wbcir_select_bank(data, WBCIR_BANK_0);
+	outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
+
 	/* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */
 	tmp = protocol << 4;
 	if (invert)
@@ -1264,6 +1250,93 @@ wbcir_cfg_ceir(struct wbcir_data *data)
 	 * set SP3_IRRX_SW to binary 01, helpfully not documented
 	 */
 	outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS);
+
+	/* Enable extended mode */
+	wbcir_select_bank(data, WBCIR_BANK_2);
+	outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1);
+
+	/*
+	 * Configure baud generator, IR data will be sampled at
+	 * a bitrate of: (24Mhz * prescaler) / (divisor * 16).
+	 *
+	 * The ECIR registers include a flag to change the
+	 * 24Mhz clock freq to 48Mhz.
+	 *
+	 * It's not documented in the specs, but fifo levels
+	 * other than 16 seems to be unsupported.
+	 */
+
+	/* prescaler 1.0, tx/rx fifo lvl 16 */
+	outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2);
+
+	/* Set baud divisor to generate one byte per bit/cell */
+	switch (protocol) {
+	case IR_PROTOCOL_RC5:
+		outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL);
+		break;
+	case IR_PROTOCOL_RC6:
+		outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL);
+		break;
+	case IR_PROTOCOL_NEC:
+		outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL);
+		break;
+	}
+	outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH);
+
+	/* Set CEIR mode */
+	wbcir_select_bank(data, WBCIR_BANK_0);
+	outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR);
+	inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */
+	inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */
+
+	/* Disable RX demod, run-length encoding/decoding, set freq span */
+	wbcir_select_bank(data, WBCIR_BANK_7);
+	outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG);
+
+	/* Disable timer */
+	wbcir_select_bank(data, WBCIR_BANK_4);
+	outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1);
+
+	/* Enable MSR interrupt, Clear AUX_IRX */
+	wbcir_select_bank(data, WBCIR_BANK_5);
+	outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2);
+
+	/* Disable CRC */
+	wbcir_select_bank(data, WBCIR_BANK_6);
+	outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3);
+
+	/* Set RX/TX (de)modulation freq, not really used */
+	wbcir_select_bank(data, WBCIR_BANK_7);
+	outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC);
+	outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC);
+
+	/* Set invert and pin direction */
+	if (invert)
+		outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4);
+	else
+		outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4);
+
+	/* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */
+	wbcir_select_bank(data, WBCIR_BANK_0);
+	outb(0x97, data->sbase + WBCIR_REG_SP3_FCR);
+
+	/* Clear AUX status bits */
+	outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
+
+	/* Enable interrupts */
+	wbcir_reset_irdata(data);
+	outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
+}
+
+static int
+wbcir_resume(struct pnp_dev *device)
+{
+	struct wbcir_data *data = pnp_get_drvdata(device);
+
+	wbcir_init_hw(data);
+	enable_irq(data->irq);
+
+	return 0;
 }
 
 static int __devinit
@@ -1393,86 +1466,7 @@ wbcir_probe(struct pnp_dev *device, cons
 
 	device_init_wakeup(&device->dev, 1);
 
-	wbcir_cfg_ceir(data);
-
-	/* Disable interrupts */
-	wbcir_select_bank(data, WBCIR_BANK_0);
-	outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
-
-	/* Enable extended mode */
-	wbcir_select_bank(data, WBCIR_BANK_2);
-	outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1);
-
-	/*
-	 * Configure baud generator, IR data will be sampled at
-	 * a bitrate of: (24Mhz * prescaler) / (divisor * 16).
-	 *
-	 * The ECIR registers include a flag to change the
-	 * 24Mhz clock freq to 48Mhz.
-	 *
-	 * It's not documented in the specs, but fifo levels
-	 * other than 16 seems to be unsupported.
-	 */
-
-	/* prescaler 1.0, tx/rx fifo lvl 16 */
-	outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2);
-
-	/* Set baud divisor to generate one byte per bit/cell */
-	switch (protocol) {
-	case IR_PROTOCOL_RC5:
-		outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL);
-		break;
-	case IR_PROTOCOL_RC6:
-		outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL);
-		break;
-	case IR_PROTOCOL_NEC:
-		outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL);
-		break;
-	}
-	outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH);
-
-	/* Set CEIR mode */
-	wbcir_select_bank(data, WBCIR_BANK_0);
-	outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR);
-	inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */
-	inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */
-
-	/* Disable RX demod, run-length encoding/decoding, set freq span */
-	wbcir_select_bank(data, WBCIR_BANK_7);
-	outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG);
-
-	/* Disable timer */
-	wbcir_select_bank(data, WBCIR_BANK_4);
-	outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1);
-
-	/* Enable MSR interrupt, Clear AUX_IRX */
-	wbcir_select_bank(data, WBCIR_BANK_5);
-	outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2);
-
-	/* Disable CRC */
-	wbcir_select_bank(data, WBCIR_BANK_6);
-	outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3);
-
-	/* Set RX/TX (de)modulation freq, not really used */
-	wbcir_select_bank(data, WBCIR_BANK_7);
-	outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC);
-	outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC);
-
-	/* Set invert and pin direction */
-	if (invert)
-		outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4);
-	else
-		outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4);
-
-	/* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */
-	wbcir_select_bank(data, WBCIR_BANK_0);
-	outb(0x97, data->sbase + WBCIR_REG_SP3_FCR);
-
-	/* Clear AUX status bits */
-	outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
-
-	/* Enable interrupts */
-	outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
+	wbcir_init_hw(data);
 
 	return 0;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/wistron_btns.c linux-libre-2.6.34-gnu1/drivers/input/misc/wistron_btns.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/wistron_btns.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/wistron_btns.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/preempt.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/platform_device.h>
 #include <linux/leds.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/wm831x-on.c linux-libre-2.6.34-gnu1/drivers/input/misc/wm831x-on.c
--- linux-libre-2.6.33-gnu1/drivers/input/misc/wm831x-on.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/wm831x-on.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/input.h>
@@ -97,8 +98,9 @@ static int __devinit wm831x_on_probe(str
 	wm831x_on->dev->phys = "wm831x_on/input0";
 	wm831x_on->dev->dev.parent = &pdev->dev;
 
-	ret = wm831x_request_irq(wm831x, irq, wm831x_on_irq,
-				 IRQF_TRIGGER_RISING, "wm831x_on", wm831x_on);
+	ret = request_threaded_irq(irq, NULL, wm831x_on_irq,
+				   IRQF_TRIGGER_RISING, "wm831x_on",
+				   wm831x_on);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret);
 		goto err_input_dev;
@@ -114,7 +116,7 @@ static int __devinit wm831x_on_probe(str
 	return 0;
 
 err_irq:
-	wm831x_free_irq(wm831x, irq, NULL);
+	free_irq(irq, wm831x_on);
 err_input_dev:
 	input_free_device(wm831x_on->dev);
 err:
@@ -127,7 +129,7 @@ static int __devexit wm831x_on_remove(st
 	struct wm831x_on *wm831x_on = platform_get_drvdata(pdev);
 	int irq = platform_get_irq(pdev, 0);
 
-	wm831x_free_irq(wm831x_on->wm831x, irq, wm831x_on);
+	free_irq(irq, wm831x_on);
 	cancel_delayed_work_sync(&wm831x_on->work);
 	input_unregister_device(wm831x_on->dev);
 	kfree(wm831x_on);
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/misc/yealink.h linux-libre-2.6.34-gnu1/drivers/input/misc/yealink.h
--- linux-libre-2.6.33-gnu1/drivers/input/misc/yealink.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/misc/yealink.h	2010-05-16 17:17:36.000000000 -0400
@@ -127,7 +127,7 @@ struct yld_ctl_packet {
  * yld_status struct.
  */
 
-/* LCD, each segment must be driven seperately.
+/* LCD, each segment must be driven separately.
  *
  * Layout:
  *
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/alps.c linux-libre-2.6.34-gnu1/drivers/input/mouse/alps.c
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/alps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/alps.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
  * the Free Software Foundation.
  */
 
+#include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/libps2.h>
@@ -63,6 +64,8 @@ static const struct alps_model_info alps
 	{ { 0x62, 0x02, 0x14 }, 0xcf, 0xcf,
 		ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
 	{ { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS },	  /* Dell Vostro 1400 */
+	{ { 0x52, 0x01, 0x14 }, 0xff, 0xff,
+		ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },	  /* Toshiba Tecra A11-11L */
 };
 
 /*
@@ -118,40 +121,27 @@ static void alps_report_buttons(struct p
 				struct input_dev *dev1, struct input_dev *dev2,
 				int left, int right, int middle)
 {
-	struct alps_data *priv = psmouse->private;
-	const struct alps_model_info *model = priv->i;
-
-	if (model->flags & ALPS_PS2_INTERLEAVED) {
-		struct input_dev *dev;
+	struct input_dev *dev;
 
-		/*
-		 * If shared button has already been reported on the
-		 * other device (dev2) then this event should be also
-		 * sent through that device.
-		 */
-		dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1;
-		input_report_key(dev, BTN_LEFT, left);
+	/*
+	 * If shared button has already been reported on the
+	 * other device (dev2) then this event should be also
+	 * sent through that device.
+	 */
+	dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1;
+	input_report_key(dev, BTN_LEFT, left);
 
-		dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1;
-		input_report_key(dev, BTN_RIGHT, right);
+	dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1;
+	input_report_key(dev, BTN_RIGHT, right);
 
-		dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1;
-		input_report_key(dev, BTN_MIDDLE, middle);
+	dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1;
+	input_report_key(dev, BTN_MIDDLE, middle);
 
-		/*
-		 * Sync the _other_ device now, we'll do the first
-		 * device later once we report the rest of the events.
-		 */
-		input_sync(dev2);
-	} else {
-		/*
-		 * For devices with non-interleaved packets we know what
-		 * device buttons belong to so we can simply report them.
-		 */
-		input_report_key(dev1, BTN_LEFT, left);
-		input_report_key(dev1, BTN_RIGHT, right);
-		input_report_key(dev1, BTN_MIDDLE, middle);
-	}
+	/*
+	 * Sync the _other_ device now, we'll do the first
+	 * device later once we report the rest of the events.
+	 */
+	input_sync(dev2);
 }
 
 static void alps_process_packet(struct psmouse *psmouse)
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/appletouch.c linux-libre-2.6.34-gnu1/drivers/input/mouse/appletouch.c
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/appletouch.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/appletouch.c	2010-05-16 17:17:36.000000000 -0400
@@ -205,8 +205,8 @@ struct atp {
 	bool			overflow_warned;
 	int			x_old;		/* last reported x/y, */
 	int			y_old;		/* used for smoothing */
-	signed char		xy_cur[ATP_XSENSORS + ATP_YSENSORS];
-	signed char		xy_old[ATP_XSENSORS + ATP_YSENSORS];
+	u8			xy_cur[ATP_XSENSORS + ATP_YSENSORS];
+	u8			xy_old[ATP_XSENSORS + ATP_YSENSORS];
 	int			xy_acc[ATP_XSENSORS + ATP_YSENSORS];
 	int			idlecount;	/* number of empty packets */
 	struct work_struct	work;
@@ -531,7 +531,7 @@ static void atp_complete_geyser_1_2(stru
 
 	for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {
 		/* accumulate the change */
-		signed char change = dev->xy_old[i] - dev->xy_cur[i];
+		int change = dev->xy_old[i] - dev->xy_cur[i];
 		dev->xy_acc[i] -= change;
 
 		/* prevent down drifting */
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/bcm5974.c linux-libre-2.6.34-gnu1/drivers/input/mouse/bcm5974.c
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/bcm5974.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/bcm5974.c	2010-05-16 17:17:36.000000000 -0400
@@ -803,7 +803,6 @@ static struct usb_driver bcm5974_driver
 	.disconnect		= bcm5974_disconnect,
 	.suspend		= bcm5974_suspend,
 	.resume			= bcm5974_resume,
-	.reset_resume		= bcm5974_resume,
 	.id_table		= bcm5974_table,
 	.supports_autosuspend	= 1,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/elantech.c linux-libre-2.6.34-gnu1/drivers/input/mouse/elantech.c
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/elantech.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/elantech.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/input.h>
 #include <linux/serio.h>
@@ -24,6 +25,10 @@
 			printk(KERN_DEBUG format, ##arg);	\
 	} while (0)
 
+static bool force_elantech;
+module_param_named(force_elantech, force_elantech, bool, 0644);
+MODULE_PARM_DESC(force_elantech, "Force the Elantech PS/2 protocol extension to be used, 1 = enabled, 0 = disabled (default).");
+
 /*
  * Send a Synaptics style sliced query command
  */
@@ -180,14 +185,18 @@ static void elantech_report_absolute_v1(
 	int fingers;
 	static int old_fingers;
 
-	if (etd->fw_version_maj == 0x01) {
-		/* byte 0:  D   U  p1  p2   1  p3   R   L
-		   byte 1:  f   0  th  tw  x9  x8  y9  y8 */
+	if (etd->fw_version < 0x020000) {
+		/*
+		 * byte 0:  D   U  p1  p2   1  p3   R   L
+		 * byte 1:  f   0  th  tw  x9  x8  y9  y8
+		 */
 		fingers = ((packet[1] & 0x80) >> 7) +
 				((packet[1] & 0x30) >> 4);
 	} else {
-		/* byte 0: n1  n0  p2  p1   1  p3   R   L
-		   byte 1:  0   0   0   0  x9  x8  y9  y8 */
+		/*
+		 * byte 0: n1  n0  p2  p1   1  p3   R   L
+		 * byte 1:  0   0   0   0  x9  x8  y9  y8
+		 */
 		fingers = (packet[0] & 0xc0) >> 6;
 	}
 
@@ -201,13 +210,15 @@ static void elantech_report_absolute_v1(
 
 	input_report_key(dev, BTN_TOUCH, fingers != 0);
 
-	/* byte 2: x7  x6  x5  x4  x3  x2  x1  x0
-	   byte 3: y7  y6  y5  y4  y3  y2  y1  y0 */
+	/*
+	 * byte 2: x7  x6  x5  x4  x3  x2  x1  x0
+	 * byte 3: y7  y6  y5  y4  y3  y2  y1  y0
+	 */
 	if (fingers) {
 		input_report_abs(dev, ABS_X,
 			((packet[1] & 0x0c) << 6) | packet[2]);
-		input_report_abs(dev, ABS_Y, ETP_YMAX_V1 -
-			(((packet[1] & 0x03) << 8) | packet[3]));
+		input_report_abs(dev, ABS_Y,
+			ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3]));
 	}
 
 	input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
@@ -216,7 +227,7 @@ static void elantech_report_absolute_v1(
 	input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
 	input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
 
-	if ((etd->fw_version_maj == 0x01) &&
+	if (etd->fw_version < 0x020000 &&
 	    (etd->capabilities & ETP_CAP_HAS_ROCKER)) {
 		/* rocker up */
 		input_report_key(dev, BTN_FORWARD, packet[0] & 0x40);
@@ -246,34 +257,47 @@ static void elantech_report_absolute_v2(
 
 	switch (fingers) {
 	case 1:
-		/* byte 1: x15 x14 x13 x12 x11 x10 x9  x8
-		   byte 2: x7  x6  x5  x4  x4  x2  x1  x0 */
-		input_report_abs(dev, ABS_X, (packet[1] << 8) | packet[2]);
-		/* byte 4: y15 y14 y13 y12 y11 y10 y8  y8
-		   byte 5: y7  y6  y5  y4  y3  y2  y1  y0 */
-		input_report_abs(dev, ABS_Y, ETP_YMAX_V2 -
-			((packet[4] << 8) | packet[5]));
+		/*
+		 * byte 1:  .   .   .   .   .  x10 x9  x8
+		 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
+		 */
+		input_report_abs(dev, ABS_X,
+			((packet[1] & 0x07) << 8) | packet[2]);
+		/*
+		 * byte 4:  .   .   .   .   .   .  y9  y8
+		 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
+		 */
+		input_report_abs(dev, ABS_Y,
+			ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5]));
 		break;
 
 	case 2:
-		/* The coordinate of each finger is reported separately with
-		   a lower resolution for two finger touches */
-		/* byte 0:  .   .  ay8 ax8  .   .   .   .
-		   byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 */
+		/*
+		 * The coordinate of each finger is reported separately
+		 * with a lower resolution for two finger touches:
+		 * byte 0:  .   .  ay8 ax8  .   .   .   .
+		 * byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0
+		 */
 		x1 = ((packet[0] & 0x10) << 4) | packet[1];
 		/* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */
 		y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]);
-		/* byte 3:  .   .  by8 bx8  .   .   .   .
-		   byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 */
+		/*
+		 * byte 3:  .   .  by8 bx8  .   .   .   .
+		 * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0
+		 */
 		x2 = ((packet[3] & 0x10) << 4) | packet[4];
 		/* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */
 		y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]);
-		/* For compatibility with the X Synaptics driver scale up one
-		   coordinate and report as ordinary mouse movent */
+		/*
+		 * For compatibility with the X Synaptics driver scale up
+		 * one coordinate and report as ordinary mouse movent
+		 */
 		input_report_abs(dev, ABS_X, x1 << 2);
 		input_report_abs(dev, ABS_Y, y1 << 2);
-		/* For compatibility with the proprietary X Elantech driver
-		   report both coordinates as hat coordinates */
+		/*
+		 * For compatibility with the proprietary X Elantech driver
+		 * report both coordinates as hat coordinates
+		 */
 		input_report_abs(dev, ABS_HAT0X, x1);
 		input_report_abs(dev, ABS_HAT0Y, y1);
 		input_report_abs(dev, ABS_HAT1X, x2);
@@ -297,7 +321,7 @@ static int elantech_check_parity_v1(stru
 	unsigned char p1, p2, p3;
 
 	/* Parity bits are placed differently */
-	if (etd->fw_version_maj == 0x01) {
+	if (etd->fw_version < 0x020000) {
 		/* byte 0:  D   U  p1  p2   1  p3   R   L */
 		p1 = (packet[0] & 0x20) >> 5;
 		p2 = (packet[0] & 0x10) >> 4;
@@ -433,7 +457,7 @@ static void elantech_set_input_params(st
 	switch (etd->hw_version) {
 	case 1:
 		/* Rocker button */
-		if ((etd->fw_version_maj == 0x01) &&
+		if (etd->fw_version < 0x020000 &&
 		    (etd->capabilities & ETP_CAP_HAS_ROCKER)) {
 			__set_bit(BTN_FORWARD, dev->keybit);
 			__set_bit(BTN_BACK, dev->keybit);
@@ -595,8 +619,12 @@ int elantech_detect(struct psmouse *psmo
 		 param[0], param[1], param[2]);
 
 	if (param[0] == 0 || param[1] != 0) {
-		pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n");
-		return -1;
+		if (!force_elantech) {
+			pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n");
+			return -1;
+		}
+
+		pr_debug("elantech.c: Probably not a real Elantech touchpad. Enabling anyway due to force_elantech.\n");
 	}
 
 	if (set_properties) {
@@ -658,14 +686,14 @@ int elantech_init(struct psmouse *psmous
 		pr_err("elantech.c: failed to query firmware version.\n");
 		goto init_fail;
 	}
-	etd->fw_version_maj = param[0];
-	etd->fw_version_min = param[2];
+
+	etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2];
 
 	/*
 	 * Assume every version greater than this is new EeePC style
 	 * hardware with 6 byte packets
 	 */
-	if (etd->fw_version_maj >= 0x02 && etd->fw_version_min >= 0x30) {
+	if (etd->fw_version >= 0x020030) {
 		etd->hw_version = 2;
 		/* For now show extra debug information */
 		etd->debug = 1;
@@ -675,8 +703,9 @@ int elantech_init(struct psmouse *psmous
 		etd->hw_version = 1;
 		etd->paritycheck = 1;
 	}
-	pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d\n",
-		etd->hw_version, etd->fw_version_maj, etd->fw_version_min);
+
+	pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d.%d\n",
+		etd->hw_version, param[0], param[1], param[2]);
 
 	if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) {
 		pr_err("elantech.c: failed to query capabilities.\n");
@@ -691,8 +720,8 @@ int elantech_init(struct psmouse *psmous
 	 * 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, "
+	if (etd->fw_version == 0x020022) {
+		pr_info("elantech.c: firmware version 2.0.34 detected, "
 			"enabling jumpy cursor workaround\n");
 		etd->jumpy_cursor = 1;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/elantech.h linux-libre-2.6.34-gnu1/drivers/input/mouse/elantech.h
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/elantech.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/elantech.h	2010-05-16 17:17:36.000000000 -0400
@@ -100,11 +100,10 @@ struct elantech_data {
 	unsigned char reg_26;
 	unsigned char debug;
 	unsigned char capabilities;
-	unsigned char fw_version_maj;
-	unsigned char fw_version_min;
-	unsigned char hw_version;
 	unsigned char paritycheck;
 	unsigned char jumpy_cursor;
+	unsigned char hw_version;
+	unsigned int  fw_version;
 	unsigned char parity[256];
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/hgpk.c linux-libre-2.6.34-gnu1/drivers/input/mouse/hgpk.c
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/hgpk.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/hgpk.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
  */
 
 #define DEBUG
+#include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/libps2.h>
@@ -68,10 +69,6 @@ module_param(post_interrupt_delay, int,
 MODULE_PARM_DESC(post_interrupt_delay,
 	"delay (ms) before recal after recal interrupt detected");
 
-static int autorecal = 1;
-module_param(autorecal, int, 0644);
-MODULE_PARM_DESC(autorecal, "enable recalibration in the driver");
-
 /*
  * When the touchpad gets ultra-sensitive, one can keep their finger 1/2"
  * above the pad and still have it send packets.  This causes a jump cursor
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/lifebook.c linux-libre-2.6.34-gnu1/drivers/input/mouse/lifebook.c
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/lifebook.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/lifebook.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/serio.h>
 #include <linux/libps2.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 
 #include "psmouse.h"
 #include "lifebook.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/psmouse-base.c linux-libre-2.6.34-gnu1/drivers/input/mouse/psmouse-base.c
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/psmouse-base.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/psmouse-base.c	2010-05-16 17:17:36.000000000 -0400
@@ -110,6 +110,7 @@ static struct workqueue_struct *kpsmouse
 struct psmouse_protocol {
 	enum psmouse_type type;
 	bool maxproto;
+	bool ignore_parity; /* Protocol should ignore parity errors from KBC */
 	const char *name;
 	const char *alias;
 	int (*detect)(struct psmouse *, bool);
@@ -288,7 +289,9 @@ static irqreturn_t psmouse_interrupt(str
 	if (psmouse->state == PSMOUSE_IGNORE)
 		goto out;
 
-	if (flags & (SERIO_PARITY|SERIO_TIMEOUT)) {
+	if (unlikely((flags & SERIO_TIMEOUT) ||
+		     ((flags & SERIO_PARITY) && !psmouse->ignore_parity))) {
+
 		if (psmouse->state == PSMOUSE_ACTIVATED)
 			printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n",
 				flags & SERIO_TIMEOUT ? " timeout" : "",
@@ -759,6 +762,7 @@ static const struct psmouse_protocol psm
 		.name		= "PS/2",
 		.alias		= "bare",
 		.maxproto	= true,
+		.ignore_parity	= true,
 		.detect		= ps2bare_detect,
 	},
 #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
@@ -786,6 +790,7 @@ static const struct psmouse_protocol psm
 		.name		= "ImPS/2",
 		.alias		= "imps",
 		.maxproto	= true,
+		.ignore_parity	= true,
 		.detect		= intellimouse_detect,
 	},
 	{
@@ -793,6 +798,7 @@ static const struct psmouse_protocol psm
 		.name		= "ImExPS/2",
 		.alias		= "exps",
 		.maxproto	= true,
+		.ignore_parity	= true,
 		.detect		= im_explorer_detect,
 	},
 #ifdef CONFIG_MOUSE_PS2_SYNAPTICS
@@ -1222,6 +1228,7 @@ static void psmouse_disconnect(struct se
 static int psmouse_switch_protocol(struct psmouse *psmouse,
 				   const struct psmouse_protocol *proto)
 {
+	const struct psmouse_protocol *selected_proto;
 	struct input_dev *input_dev = psmouse->dev;
 
 	input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
@@ -1245,9 +1252,14 @@ static int psmouse_switch_protocol(struc
 			return -1;
 
 		psmouse->type = proto->type;
-	} else
+		selected_proto = proto;
+	} else {
 		psmouse->type = psmouse_extensions(psmouse,
 						   psmouse_max_proto, true);
+		selected_proto = psmouse_protocol_by_type(psmouse->type);
+	}
+
+	psmouse->ignore_parity = selected_proto->ignore_parity;
 
 	/*
 	 * If mouse's packet size is 3 there is no point in polling the
@@ -1267,7 +1279,7 @@ static int psmouse_switch_protocol(struc
 		psmouse->resync_time = 0;
 
 	snprintf(psmouse->devname, sizeof(psmouse->devname), "%s %s %s",
-		 psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name);
+		 selected_proto->name, psmouse->vendor, psmouse->name);
 
 	input_dev->name = psmouse->devname;
 	input_dev->phys = psmouse->phys;
@@ -1382,6 +1394,7 @@ static int psmouse_reconnect(struct seri
 	struct psmouse *psmouse = serio_get_drvdata(serio);
 	struct psmouse *parent = NULL;
 	struct serio_driver *drv = serio->drv;
+	unsigned char type;
 	int rc = -1;
 
 	if (!drv || !psmouse) {
@@ -1401,10 +1414,15 @@ static int psmouse_reconnect(struct seri
 	if (psmouse->reconnect) {
 		if (psmouse->reconnect(psmouse))
 			goto out;
-	} else if (psmouse_probe(psmouse) < 0 ||
-		   psmouse->type != psmouse_extensions(psmouse,
-						psmouse_max_proto, false)) {
-		goto out;
+	} else {
+		psmouse_reset(psmouse);
+
+		if (psmouse_probe(psmouse) < 0)
+			goto out;
+
+		type = psmouse_extensions(psmouse, psmouse_max_proto, false);
+		if (psmouse->type != type)
+			goto out;
 	}
 
 	/* ok, the device type (and capabilities) match the old one,
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/psmouse.h linux-libre-2.6.34-gnu1/drivers/input/mouse/psmouse.h
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/psmouse.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/psmouse.h	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,7 @@ struct psmouse {
 	unsigned char pktcnt;
 	unsigned char pktsize;
 	unsigned char type;
+	bool ignore_parity;
 	bool acks_disable_command;
 	unsigned int model;
 	unsigned long last;
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/pxa930_trkball.c linux-libre-2.6.34-gnu1/drivers/input/mouse/pxa930_trkball.c
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/pxa930_trkball.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/pxa930_trkball.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <mach/pxa930_trkball.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/sentelic.c linux-libre-2.6.34-gnu1/drivers/input/mouse/sentelic.c
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/sentelic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/sentelic.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/libps2.h>
 #include <linux/serio.h>
 #include <linux/jiffies.h>
+#include <linux/slab.h>
 
 #include "psmouse.h"
 #include "sentelic.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/synaptics.c linux-libre-2.6.34-gnu1/drivers/input/mouse/synaptics.c
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/synaptics.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/synaptics.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/libps2.h>
+#include <linux/slab.h>
 #include "psmouse.h"
 #include "synaptics.h"
 
@@ -136,7 +137,8 @@ static int synaptics_capability(struct p
 	if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap))
 		return -1;
 	priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2];
-	priv->ext_cap = 0;
+	priv->ext_cap = priv->ext_cap_0c = 0;
+
 	if (!SYN_CAP_VALID(priv->capabilities))
 		return -1;
 
@@ -149,7 +151,7 @@ static int synaptics_capability(struct p
 	if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) {
 		if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) {
 			printk(KERN_ERR "Synaptics claims to have extended capabilities,"
-			       " but I'm not able to read them.");
+			       " but I'm not able to read them.\n");
 		} else {
 			priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2];
 
@@ -161,6 +163,16 @@ static int synaptics_capability(struct p
 				priv->ext_cap &= 0xff0fff;
 		}
 	}
+
+	if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 4) {
+		if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB_0C, cap)) {
+			printk(KERN_ERR "Synaptics claims to have extended capability 0x0c,"
+			       " but I'm not able to read it.\n");
+		} else {
+			priv->ext_cap_0c = (cap[0] << 16) | (cap[1] << 8) | cap[2];
+		}
+	}
+
 	return 0;
 }
 
@@ -347,7 +359,15 @@ static void synaptics_parse_hw_state(uns
 		hw->left  = (buf[0] & 0x01) ? 1 : 0;
 		hw->right = (buf[0] & 0x02) ? 1 : 0;
 
-		if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
+		if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
+			/*
+			 * Clickpad's button is transmitted as middle button,
+			 * however, since it is primary button, we will report
+			 * it as BTN_LEFT.
+			 */
+			hw->left = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
+
+		} else if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
 			hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
 			if (hw->w == 2)
 				hw->scroll = (signed char)(buf[1]);
@@ -592,6 +612,12 @@ static void set_input_params(struct inpu
 
 	dev->absres[ABS_X] = priv->x_res;
 	dev->absres[ABS_Y] = priv->y_res;
+
+	if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
+		/* Clickpads report only left button */
+		__clear_bit(BTN_RIGHT, dev->keybit);
+		__clear_bit(BTN_MIDDLE, dev->keybit);
+	}
 }
 
 static void synaptics_disconnect(struct psmouse *psmouse)
@@ -696,10 +722,10 @@ int synaptics_init(struct psmouse *psmou
 
 	priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
 
-	printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx\n",
+	printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n",
 		SYN_ID_MODEL(priv->identity),
 		SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity),
-		priv->model_id, priv->capabilities, priv->ext_cap);
+		priv->model_id, priv->capabilities, priv->ext_cap, priv->ext_cap_0c);
 
 	set_input_params(psmouse->dev, priv);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/synaptics.h linux-libre-2.6.34-gnu1/drivers/input/mouse/synaptics.h
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/synaptics.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/synaptics.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #define SYN_QUE_SERIAL_NUMBER_SUFFIX	0x07
 #define SYN_QUE_RESOLUTION		0x08
 #define SYN_QUE_EXT_CAPAB		0x09
+#define SYN_QUE_EXT_CAPAB_0C		0x0c
 
 /* synatics modes */
 #define SYN_BIT_ABSOLUTE_MODE		(1 << 7)
@@ -48,6 +49,8 @@
 #define SYN_CAP_VALID(c)		((((c) & 0x00ff00) >> 8) == 0x47)
 #define SYN_EXT_CAP_REQUESTS(c)		(((c) & 0x700000) >> 20)
 #define SYN_CAP_MULTI_BUTTON_NO(ec)	(((ec) & 0x00f000) >> 12)
+#define SYN_CAP_PRODUCT_ID(ec)		(((ec) & 0xff0000) >> 16)
+#define SYN_CAP_CLICKPAD(ex0c)		((ex0c) & 0x100100)
 
 /* synaptics modes query bits */
 #define SYN_MODE_ABSOLUTE(m)		((m) & (1 << 7))
@@ -96,6 +99,7 @@ struct synaptics_data {
 	unsigned long int model_id;		/* Model-ID */
 	unsigned long int capabilities;		/* Capabilities */
 	unsigned long int ext_cap;		/* Extended Capabilities */
+	unsigned long int ext_cap_0c;		/* Ext Caps from 0x0c query */
 	unsigned long int identity;		/* Identification */
 	int x_res;				/* X resolution in units/mm */
 	int y_res;				/* Y resolution in units/mm */
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/synaptics_i2c.c linux-libre-2.6.34-gnu1/drivers/input/mouse/synaptics_i2c.c
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/synaptics_i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/synaptics_i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/input.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME		"synaptics_i2c"
 /* maximum product id is 15 characters */
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/touchkit_ps2.c linux-libre-2.6.34-gnu1/drivers/input/mouse/touchkit_ps2.c
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/touchkit_ps2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/touchkit_ps2.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/slab.h>
 
 #include <linux/input.h>
 #include <linux/serio.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mouse/trackpoint.c linux-libre-2.6.34-gnu1/drivers/input/mouse/trackpoint.c
--- linux-libre-2.6.33-gnu1/drivers/input/mouse/trackpoint.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mouse/trackpoint.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  * Trademarks are the property of their respective owners.
  */
 
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/serio.h>
 #include <linux/module.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/mousedev.c linux-libre-2.6.34-gnu1/drivers/input/mousedev.c
--- linux-libre-2.6.33-gnu1/drivers/input/mousedev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/mousedev.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/poll.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -542,10 +541,8 @@ static int mousedev_open(struct inode *i
 	if (i >= MOUSEDEV_MINORS)
 		return -ENODEV;
 
-	lock_kernel();
 	error = mutex_lock_interruptible(&mousedev_table_mutex);
 	if (error) {
-		unlock_kernel();
 		return error;
 	}
 	mousedev = mousedev_table[i];
@@ -554,7 +551,6 @@ static int mousedev_open(struct inode *i
 	mutex_unlock(&mousedev_table_mutex);
 
 	if (!mousedev) {
-		unlock_kernel();
 		return -ENODEV;
 	}
 
@@ -575,7 +571,6 @@ static int mousedev_open(struct inode *i
 		goto err_free_client;
 
 	file->private_data = client;
-	unlock_kernel();
 	return 0;
 
  err_free_client:
@@ -583,7 +578,6 @@ static int mousedev_open(struct inode *i
 	kfree(client);
  err_put_mousedev:
 	put_device(&mousedev->dev);
-	unlock_kernel();
 	return error;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/serio/altera_ps2.c linux-libre-2.6.34-gnu1/drivers/input/serio/altera_ps2.c
--- linux-libre-2.6.33-gnu1/drivers/input/serio/altera_ps2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/serio/altera_ps2.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #define DRV_NAME "altera_ps2"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/serio/at32psif.c linux-libre-2.6.34-gnu1/drivers/input/serio/at32psif.c
--- linux-libre-2.6.33-gnu1/drivers/input/serio/at32psif.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/serio/at32psif.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 /* PSIF register offsets */
 #define PSIF_CR				0x00
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/serio/ct82c710.c linux-libre-2.6.34-gnu1/drivers/input/serio/ct82c710.c
--- linux-libre-2.6.33-gnu1/drivers/input/serio/ct82c710.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/serio/ct82c710.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/serio/gscps2.c linux-libre-2.6.34-gnu1/drivers/input/serio/gscps2.c
--- linux-libre-2.6.33-gnu1/drivers/input/serio/gscps2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/serio/gscps2.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/serio.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/serio/hil_mlc.c linux-libre-2.6.34-gnu1/drivers/input/serio/hil_mlc.c
--- linux-libre-2.6.33-gnu1/drivers/input/serio/hil_mlc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/serio/hil_mlc.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,6 +58,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/list.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/serio/i8042.c linux-libre-2.6.34-gnu1/drivers/input/serio/i8042.c
--- linux-libre-2.6.33-gnu1/drivers/input/serio/i8042.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/serio/i8042.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/rcupdate.h>
 #include <linux/platform_device.h>
 #include <linux/i8042.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
@@ -38,7 +39,7 @@ MODULE_PARM_DESC(noaux, "Do not probe or
 
 static bool i8042_nomux;
 module_param_named(nomux, i8042_nomux, bool, 0);
-MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present.");
+MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present.");
 
 static bool i8042_unlock;
 module_param_named(unlock, i8042_unlock, bool, 0);
@@ -430,7 +431,7 @@ static bool i8042_filter(unsigned char d
 	}
 
 	if (i8042_platform_filter && i8042_platform_filter(data, str, serio)) {
-		dbg("Filtered out by platfrom filter\n");
+		dbg("Filtered out by platform filter\n");
 		return true;
 	}
 
@@ -1386,6 +1387,8 @@ static int __init i8042_probe(struct pla
 {
 	int error;
 
+	i8042_platform_device = dev;
+
 	error = i8042_controller_selftest();
 	if (error)
 		return error;
@@ -1421,6 +1424,7 @@ static int __init i8042_probe(struct pla
 	i8042_free_aux_ports();	/* in case KBD failed but AUX not */
 	i8042_free_irqs();
 	i8042_controller_reset();
+	i8042_platform_device = NULL;
 
 	return error;
 }
@@ -1430,6 +1434,7 @@ static int __devexit i8042_remove(struct
 	i8042_unregister_ports();
 	i8042_free_irqs();
 	i8042_controller_reset();
+	i8042_platform_device = NULL;
 
 	return 0;
 }
@@ -1448,6 +1453,7 @@ static struct platform_driver i8042_driv
 
 static int __init i8042_init(void)
 {
+	struct platform_device *pdev;
 	int err;
 
 	dbg_init();
@@ -1460,31 +1466,18 @@ static int __init i8042_init(void)
 	if (err)
 		goto err_platform_exit;
 
-	i8042_platform_device = platform_device_alloc("i8042", -1);
-	if (!i8042_platform_device) {
-		err = -ENOMEM;
+	pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0);
+	if (IS_ERR(pdev)) {
+		err = PTR_ERR(pdev);
 		goto err_platform_exit;
 	}
 
-	err = platform_device_add(i8042_platform_device);
-	if (err)
-		goto err_free_device;
-
-	err = platform_driver_probe(&i8042_driver, i8042_probe);
-	if (err)
-		goto err_del_device;
-
 	panic_blink = i8042_panic_blink;
 
 	return 0;
 
- err_del_device:
-	platform_device_del(i8042_platform_device);
- err_free_device:
-	platform_device_put(i8042_platform_device);
  err_platform_exit:
 	i8042_platform_exit();
-
 	return err;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/serio/i8042-x86ia64io.h linux-libre-2.6.34-gnu1/drivers/input/serio/i8042-x86ia64io.h
--- linux-libre-2.6.33-gnu1/drivers/input/serio/i8042-x86ia64io.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/serio/i8042-x86ia64io.h	2010-05-16 17:17:36.000000000 -0400
@@ -442,6 +442,13 @@ static const struct dmi_system_id __init
 		},
 	},
 	{
+		/* Medion Akoya E1222 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "E122X"),
+		},
+	},
+	{
 		/* Mivvy M310 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"),
@@ -624,6 +631,9 @@ static int i8042_pnp_kbd_probe(struct pn
 		strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name));
 	}
 
+	/* Keyboard ports are always supposed to be wakeup-enabled */
+	device_set_wakeup_enable(&dev->dev, true);
+
 	i8042_pnp_kbd_devices++;
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/serio/libps2.c linux-libre-2.6.34-gnu1/drivers/input/serio/libps2.c
--- linux-libre-2.6.33-gnu1/drivers/input/serio/libps2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/serio/libps2.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/serio.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/serio/parkbd.c linux-libre-2.6.34-gnu1/drivers/input/serio/parkbd.c
--- linux-libre-2.6.33-gnu1/drivers/input/serio/parkbd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/serio/parkbd.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,7 @@
 
 #include <linux/module.h>
 #include <linux/parport.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/serio.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/serio/pcips2.c linux-libre-2.6.34-gnu1/drivers/input/serio/pcips2.c
--- linux-libre-2.6.33-gnu1/drivers/input/serio/pcips2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/serio/pcips2.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/ioport.h>
 #include <linux/input.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/serio.h>
 #include <linux/delay.h>
@@ -186,7 +187,7 @@ static void __devexit pcips2_remove(stru
 	pci_disable_device(dev);
 }
 
-static struct pci_device_id pcips2_ids[] = {
+static const struct pci_device_id pcips2_ids[] = {
 	{
 		.vendor		= 0x14f2,	/* MOBILITY */
 		.device		= 0x0123,	/* Keyboard */
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/serio/q40kbd.c linux-libre-2.6.34-gnu1/drivers/input/serio/q40kbd.c
--- linux-libre-2.6.33-gnu1/drivers/input/serio/q40kbd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/serio/q40kbd.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/err.h>
 #include <linux/bitops.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/serio/rpckbd.c linux-libre-2.6.34-gnu1/drivers/input/serio/rpckbd.c
--- linux-libre-2.6.33-gnu1/drivers/input/serio/rpckbd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/serio/rpckbd.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 #include <mach/hardware.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/serio/serio.c linux-libre-2.6.34-gnu1/drivers/input/serio/serio.c
--- linux-libre-2.6.33-gnu1/drivers/input/serio/serio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/serio/serio.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,8 @@
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/stddef.h>
 #include <linux/module.h>
 #include <linux/serio.h>
@@ -119,11 +121,10 @@ static int serio_bind_driver(struct seri
 
 		error = device_bind_driver(&serio->dev);
 		if (error) {
-			printk(KERN_WARNING
-				"serio: device_bind_driver() failed "
-				"for %s (%s) and %s, error: %d\n",
-				serio->phys, serio->name,
-				drv->description, error);
+			dev_warn(&serio->dev,
+				 "device_bind_driver() failed for %s (%s) and %s, error: %d\n",
+				 serio->phys, serio->name,
+				 drv->description, error);
 			serio_disconnect_driver(serio);
 			serio->dev.driver = NULL;
 			return error;
@@ -138,9 +139,9 @@ static void serio_find_driver(struct ser
 
 	error = device_attach(&serio->dev);
 	if (error < 0)
-		printk(KERN_WARNING
-			"serio: device_attach() failed for %s (%s), error: %d\n",
-			serio->phys, serio->name, error);
+		dev_warn(&serio->dev,
+			 "device_attach() failed for %s (%s), error: %d\n",
+			 serio->phys, serio->name, error);
 }
 
 
@@ -194,17 +195,14 @@ static int serio_queue_event(void *objec
 
 	event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC);
 	if (!event) {
-		printk(KERN_ERR
-			"serio: Not enough memory to queue event %d\n",
-			event_type);
+		pr_err("Not enough memory to queue event %d\n", event_type);
 		retval = -ENOMEM;
 		goto out;
 	}
 
 	if (!try_module_get(owner)) {
-		printk(KERN_WARNING
-			"serio: Can't get module reference, dropping event %d\n",
-			event_type);
+		pr_warning("Can't get module reference, dropping event %d\n",
+			   event_type);
 		kfree(event);
 		retval = -EINVAL;
 		goto out;
@@ -230,14 +228,12 @@ static void serio_free_event(struct seri
 
 static void serio_remove_duplicate_events(struct serio_event *event)
 {
-	struct list_head *node, *next;
-	struct serio_event *e;
+	struct serio_event *e, *next;
 	unsigned long flags;
 
 	spin_lock_irqsave(&serio_event_lock, flags);
 
-	list_for_each_safe(node, next, &serio_event_list) {
-		e = list_entry(node, struct serio_event, node);
+	list_for_each_entry_safe(e, next, &serio_event_list, node) {
 		if (event->object == e->object) {
 			/*
 			 * If this event is of different type we should not
@@ -247,7 +243,7 @@ static void serio_remove_duplicate_event
 			if (event->type != e->type)
 				break;
 
-			list_del_init(node);
+			list_del_init(&e->node);
 			serio_free_event(e);
 		}
 	}
@@ -258,23 +254,18 @@ static void serio_remove_duplicate_event
 
 static struct serio_event *serio_get_event(void)
 {
-	struct serio_event *event;
-	struct list_head *node;
+	struct serio_event *event = NULL;
 	unsigned long flags;
 
 	spin_lock_irqsave(&serio_event_lock, flags);
 
-	if (list_empty(&serio_event_list)) {
-		spin_unlock_irqrestore(&serio_event_lock, flags);
-		return NULL;
+	if (!list_empty(&serio_event_list)) {
+		event = list_first_entry(&serio_event_list,
+					 struct serio_event, node);
+		list_del_init(&event->node);
 	}
 
-	node = serio_event_list.next;
-	event = list_entry(node, struct serio_event, node);
-	list_del_init(node);
-
 	spin_unlock_irqrestore(&serio_event_lock, flags);
-
 	return event;
 }
 
@@ -287,29 +278,27 @@ static void serio_handle_event(void)
 	while ((event = serio_get_event())) {
 
 		switch (event->type) {
-			case SERIO_REGISTER_PORT:
-				serio_add_port(event->object);
-				break;
 
-			case SERIO_RECONNECT_PORT:
-				serio_reconnect_port(event->object);
-				break;
+		case SERIO_REGISTER_PORT:
+			serio_add_port(event->object);
+			break;
 
-			case SERIO_RESCAN_PORT:
-				serio_disconnect_port(event->object);
-				serio_find_driver(event->object);
-				break;
+		case SERIO_RECONNECT_PORT:
+			serio_reconnect_port(event->object);
+			break;
 
-			case SERIO_RECONNECT_CHAIN:
-				serio_reconnect_chain(event->object);
-				break;
+		case SERIO_RESCAN_PORT:
+			serio_disconnect_port(event->object);
+			serio_find_driver(event->object);
+			break;
 
-			case SERIO_ATTACH_DRIVER:
-				serio_attach_driver(event->object);
-				break;
+		case SERIO_RECONNECT_CHAIN:
+			serio_reconnect_chain(event->object);
+			break;
 
-			default:
-				break;
+		case SERIO_ATTACH_DRIVER:
+			serio_attach_driver(event->object);
+			break;
 		}
 
 		serio_remove_duplicate_events(event);
@@ -325,16 +314,14 @@ static void serio_handle_event(void)
  */
 static void serio_remove_pending_events(void *object)
 {
-	struct list_head *node, *next;
-	struct serio_event *event;
+	struct serio_event *event, *next;
 	unsigned long flags;
 
 	spin_lock_irqsave(&serio_event_lock, flags);
 
-	list_for_each_safe(node, next, &serio_event_list) {
-		event = list_entry(node, struct serio_event, node);
+	list_for_each_entry_safe(event, next, &serio_event_list, node) {
 		if (event->object == object) {
-			list_del_init(node);
+			list_del_init(&event->node);
 			serio_free_event(event);
 		}
 	}
@@ -380,7 +367,6 @@ static int serio_thread(void *nothing)
 			kthread_should_stop() || !list_empty(&serio_event_list));
 	} while (!kthread_should_stop());
 
-	printk(KERN_DEBUG "serio: kseriod exiting\n");
 	return 0;
 }
 
@@ -445,6 +431,11 @@ static struct attribute_group serio_id_a
 	.attrs	= serio_device_id_attrs,
 };
 
+static const struct attribute_group *serio_device_attr_groups[] = {
+	&serio_id_attr_group,
+	NULL
+};
+
 static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct serio *serio = to_serio_port(dev);
@@ -532,6 +523,7 @@ static void serio_init_port(struct serio
 			(long)atomic_inc_return(&serio_no) - 1);
 	serio->dev.bus = &serio_bus;
 	serio->dev.release = serio_release_port;
+	serio->dev.groups = serio_device_attr_groups;
 	if (serio->parent) {
 		serio->dev.parent = &serio->parent->dev;
 		serio->depth = serio->parent->depth + 1;
@@ -555,21 +547,15 @@ static void serio_add_port(struct serio
 	}
 
 	list_add_tail(&serio->node, &serio_list);
+
 	if (serio->start)
 		serio->start(serio);
+
 	error = device_add(&serio->dev);
 	if (error)
-		printk(KERN_ERR
-			"serio: device_add() failed for %s (%s), error: %d\n",
+		dev_err(&serio->dev,
+			"device_add() failed for %s (%s), error: %d\n",
 			serio->phys, serio->name, error);
-	else {
-		serio->registered = true;
-		error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group);
-		if (error)
-			printk(KERN_ERR
-				"serio: sysfs_create_group() failed for %s (%s), error: %d\n",
-				serio->phys, serio->name, error);
-	}
 }
 
 /*
@@ -596,11 +582,8 @@ static void serio_destroy_port(struct se
 		serio->parent = NULL;
 	}
 
-	if (serio->registered) {
-		sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group);
+	if (device_is_registered(&serio->dev))
 		device_del(&serio->dev);
-		serio->registered = false;
-	}
 
 	list_del_init(&serio->node);
 	serio_remove_pending_events(serio);
@@ -798,9 +781,8 @@ static void serio_attach_driver(struct s
 
 	error = driver_attach(&drv->driver);
 	if (error)
-		printk(KERN_WARNING
-			"serio: driver_attach() failed for %s with error %d\n",
-			drv->driver.name, error);
+		pr_warning("driver_attach() failed for %s with error %d\n",
+			   drv->driver.name, error);
 }
 
 int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name)
@@ -820,8 +802,7 @@ int __serio_register_driver(struct serio
 
 	error = driver_register(&drv->driver);
 	if (error) {
-		printk(KERN_ERR
-			"serio: driver_register() failed for %s, error: %d\n",
+		pr_err("driver_register() failed for %s, error: %d\n",
 			drv->driver.name, error);
 		return error;
 	}
@@ -987,7 +968,7 @@ irqreturn_t serio_interrupt(struct serio
 
         if (likely(serio->drv)) {
                 ret = serio->drv->interrupt(serio, data, dfl);
-	} else if (!dfl && serio->registered) {
+	} else if (!dfl && device_is_registered(&serio->dev)) {
 		serio_rescan(serio);
 		ret = IRQ_HANDLED;
 	}
@@ -1018,7 +999,7 @@ static int __init serio_init(void)
 
 	error = bus_register(&serio_bus);
 	if (error) {
-		printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error);
+		pr_err("Failed to register serio bus, error: %d\n", error);
 		return error;
 	}
 
@@ -1026,7 +1007,7 @@ static int __init serio_init(void)
 	if (IS_ERR(serio_task)) {
 		bus_unregister(&serio_bus);
 		error = PTR_ERR(serio_task);
-		printk(KERN_ERR "serio: Failed to start kseriod, error: %d\n", error);
+		pr_err("Failed to start kseriod, error: %d\n", error);
 		return error;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/serio/serio_raw.c linux-libre-2.6.34-gnu1/drivers/input/serio/serio_raw.c
--- linux-libre-2.6.33-gnu1/drivers/input/serio/serio_raw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/serio/serio_raw.c	2010-05-16 17:17:36.000000000 -0400
@@ -81,12 +81,12 @@ static int serio_raw_open(struct inode *
 	struct serio_raw_list *list;
 	int retval = 0;
 
-	lock_kernel();
 	retval = mutex_lock_interruptible(&serio_raw_mutex);
 	if (retval)
-		goto out_bkl;
+		return retval;
 
-	if (!(serio_raw = serio_raw_locate(iminor(inode)))) {
+	serio_raw = serio_raw_locate(iminor(inode));
+	if (!serio_raw) {
 		retval = -ENODEV;
 		goto out;
 	}
@@ -96,7 +96,8 @@ static int serio_raw_open(struct inode *
 		goto out;
 	}
 
-	if (!(list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) {
+	list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL);
+	if (!list) {
 		retval = -ENOMEM;
 		goto out;
 	}
@@ -109,8 +110,6 @@ static int serio_raw_open(struct inode *
 
 out:
 	mutex_unlock(&serio_raw_mutex);
-out_bkl:
-	unlock_kernel();
 	return retval;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/serio/xilinx_ps2.c linux-libre-2.6.34-gnu1/drivers/input/serio/xilinx_ps2.c
--- linux-libre-2.6.33-gnu1/drivers/input/serio/xilinx_ps2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/serio/xilinx_ps2.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/serio.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/io.h>
@@ -270,7 +271,7 @@ static int __devinit xps2_of_probe(struc
 	drvdata->irq = r_irq.start;
 
 	phys_addr = r_mem.start;
-	remap_size = r_mem.end - r_mem.start + 1;
+	remap_size = resource_size(&r_mem);
 	if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) {
 		dev_err(dev, "Couldn't lock memory region at 0x%08llX\n",
 			(unsigned long long)phys_addr);
@@ -344,7 +345,7 @@ static int __devexit xps2_of_remove(stru
 	if (of_address_to_resource(of_dev->node, 0, &r_mem))
 		dev_err(dev, "invalid address\n");
 	else
-		release_mem_region(r_mem.start, r_mem.end - r_mem.start + 1);
+		release_mem_region(r_mem.start, resource_size(&r_mem));
 
 	kfree(drvdata);
 
@@ -354,7 +355,7 @@ static int __devexit xps2_of_remove(stru
 }
 
 /* Match table for of_platform binding */
-static struct of_device_id xps2_of_match[] __devinitdata = {
+static const struct of_device_id xps2_of_match[] __devinitconst = {
 	{ .compatible = "xlnx,xps-ps2-1.00.a", },
 	{ /* end of list */ },
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/sparse-keymap.c linux-libre-2.6.34-gnu1/drivers/input/sparse-keymap.c
--- linux-libre-2.6.33-gnu1/drivers/input/sparse-keymap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/sparse-keymap.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
+#include <linux/slab.h>
 
 MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
 MODULE_DESCRIPTION("Generic support for sparse keymaps");
@@ -64,36 +65,39 @@ struct key_entry *sparse_keymap_entry_fr
 EXPORT_SYMBOL(sparse_keymap_entry_from_keycode);
 
 static int sparse_keymap_getkeycode(struct input_dev *dev,
-				    int scancode, int *keycode)
+				    unsigned int scancode,
+				    unsigned int *keycode)
 {
-	const struct key_entry *key =
-			sparse_keymap_entry_from_scancode(dev, scancode);
+	const struct key_entry *key;
 
-	if (key && key->type == KE_KEY) {
-		*keycode = key->keycode;
-		return 0;
+	if (dev->keycode) {
+		key = sparse_keymap_entry_from_scancode(dev, scancode);
+		if (key && key->type == KE_KEY) {
+			*keycode = key->keycode;
+			return 0;
+		}
 	}
 
 	return -EINVAL;
 }
 
 static int sparse_keymap_setkeycode(struct input_dev *dev,
-				    int scancode, int keycode)
+				    unsigned int scancode,
+				    unsigned int keycode)
 {
 	struct key_entry *key;
 	int old_keycode;
 
-	if (keycode < 0 || keycode > KEY_MAX)
-		return -EINVAL;
-
-	key = sparse_keymap_entry_from_scancode(dev, scancode);
-	if (key && key->type == KE_KEY) {
-		old_keycode = key->keycode;
-		key->keycode = keycode;
-		set_bit(keycode, dev->keybit);
-		if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
-			clear_bit(old_keycode, dev->keybit);
-		return 0;
+	if (dev->keycode) {
+		key = sparse_keymap_entry_from_scancode(dev, scancode);
+		if (key && key->type == KE_KEY) {
+			old_keycode = key->keycode;
+			key->keycode = keycode;
+			set_bit(keycode, dev->keybit);
+			if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
+				clear_bit(old_keycode, dev->keybit);
+			return 0;
+		}
 	}
 
 	return -EINVAL;
@@ -161,7 +165,7 @@ int sparse_keymap_setup(struct input_dev
 	return 0;
 
  err_out:
-	kfree(keymap);
+	kfree(map);
 	return error;
 
 }
@@ -173,14 +177,27 @@ EXPORT_SYMBOL(sparse_keymap_setup);
  *
  * This function is used to free memory allocated by sparse keymap
  * in an input device that was set up by sparse_keymap_setup().
+ * NOTE: It is safe to cal this function while input device is
+ * still registered (however the drivers should care not to try to
+ * use freed keymap and thus have to shut off interrups/polling
+ * before freeing the keymap).
  */
 void sparse_keymap_free(struct input_dev *dev)
 {
+	unsigned long flags;
+
+	/*
+	 * Take event lock to prevent racing with input_get_keycode()
+	 * and input_set_keycode() if we are called while input device
+	 * is still registered.
+	 */
+	spin_lock_irqsave(&dev->event_lock, flags);
+
 	kfree(dev->keycode);
 	dev->keycode = NULL;
 	dev->keycodemax = 0;
-	dev->getkeycode = NULL;
-	dev->setkeycode = NULL;
+
+	spin_unlock_irqrestore(&dev->event_lock, flags);
 }
 EXPORT_SYMBOL(sparse_keymap_free);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/tablet/aiptek.c linux-libre-2.6.34-gnu1/drivers/input/tablet/aiptek.c
--- linux-libre-2.6.33-gnu1/drivers/input/tablet/aiptek.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/tablet/aiptek.c	2010-05-16 17:17:36.000000000 -0400
@@ -362,7 +362,7 @@ static const int macroKeyEvents[] = {
 };
 
 /***********************************************************************
- * Map values to strings and back. Every map shoudl have the following
+ * Map values to strings and back. Every map should have the following
  * as its last element: { NULL, AIPTEK_INVALID_VALUE }.
  */
 #define AIPTEK_INVALID_VALUE	-1
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/tablet/gtco.c linux-libre-2.6.34-gnu1/drivers/input/tablet/gtco.c
--- linux-libre-2.6.33-gnu1/drivers/input/tablet/gtco.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/tablet/gtco.c	2010-05-16 17:17:36.000000000 -0400
@@ -92,7 +92,7 @@ Scott Hill shill@gtcocalcomp.com
 /* DATA STRUCTURES */
 
 /* Device table */
-static struct usb_device_id gtco_usbid_table [] = {
+static const struct usb_device_id gtco_usbid_table[] = {
 	{ USB_DEVICE(VENDOR_ID_GTCO, PID_400) },
 	{ USB_DEVICE(VENDOR_ID_GTCO, PID_401) },
 	{ USB_DEVICE(VENDOR_ID_GTCO, PID_1000) },
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom.h linux-libre-2.6.34-gnu1/drivers/input/tablet/wacom.h
--- linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/tablet/wacom.h	2010-05-16 17:17:36.000000000 -0400
@@ -85,6 +85,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/mod_devicetable.h>
 #include <linux/init.h>
 #include <linux/usb/input.h>
 #include <asm/unaligned.h>
@@ -120,6 +121,8 @@ struct wacom_combo {
 	struct urb *urb;
 };
 
+extern const struct usb_device_id wacom_ids[];
+
 extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo);
 extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data);
 extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data);
@@ -142,7 +145,5 @@ extern void input_dev_mo(struct input_de
 extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
 extern __u16 wacom_le16_to_cpu(unsigned char *data);
 extern __u16 wacom_be16_to_cpu(unsigned char *data);
-extern struct wacom_features *get_wacom_feature(const struct usb_device_id *id);
-extern const struct usb_device_id *get_device_table(void);
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom_sys.c linux-libre-2.6.34-gnu1/drivers/input/tablet/wacom_sys.c
--- linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom_sys.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/tablet/wacom_sys.c	2010-05-16 17:17:36.000000000 -0400
@@ -211,7 +211,8 @@ void input_dev_g(struct input_dev *input
 	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
 		BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) |
 		BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2);
-	input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
+	input_set_abs_params(input_dev, ABS_DISTANCE,
+			     0, wacom_wac->features.distance_max, 0, 0);
 }
 
 void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
@@ -261,7 +262,8 @@ void input_dev_i(struct input_dev *input
 		BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) |
 		BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) |
 		BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2);
-	input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
+	input_set_abs_params(input_dev, ABS_DISTANCE,
+			     0, wacom_wac->features.distance_max, 0, 0);
 	input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
 	input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
 	input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0);
@@ -282,17 +284,19 @@ void input_dev_pt(struct input_dev *inpu
 
 void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-	if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP ||
-	    wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) {
-		input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->x_phy, 0, 0);
-		input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->y_phy, 0, 0);
-		input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP);
+	struct wacom_features *features = &wacom_wac->features;
+
+	if (features->device_type == BTN_TOOL_DOUBLETAP ||
+	    features->device_type == BTN_TOOL_TRIPLETAP) {
+		input_set_abs_params(input_dev, ABS_RX, 0, features->x_phy, 0, 0);
+		input_set_abs_params(input_dev, ABS_RY, 0, features->y_phy, 0, 0);
+		__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
 	}
 }
 
 void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-	if (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) {
+	if (wacom_wac->features.device_type == BTN_TOOL_TRIPLETAP) {
 		input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP);
 		input_dev->evbit[0] |= BIT_MASK(EV_MSC);
 		input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
@@ -367,7 +371,7 @@ static int wacom_parse_hid(struct usb_in
 					} else if (pen) {
 						/* penabled only accepts exact bytes of data */
 						if (features->type == TABLETPC2FG)
-							features->pktlen = WACOM_PKGLEN_PENABLED;
+							features->pktlen = WACOM_PKGLEN_GRAPHIRE;
 						features->device_type = BTN_TOOL_PEN;
 						features->x_max =
 							wacom_le16_to_cpu(&report[i + 3]);
@@ -406,7 +410,7 @@ static int wacom_parse_hid(struct usb_in
 					} else if (pen) {
 						/* penabled only accepts exact bytes of data */
 						if (features->type == TABLETPC2FG)
-							features->pktlen = WACOM_PKGLEN_PENABLED;
+							features->pktlen = WACOM_PKGLEN_GRAPHIRE;
 						features->device_type = BTN_TOOL_PEN;
 						features->y_max =
 							wacom_le16_to_cpu(&report[i + 3]);
@@ -532,21 +536,38 @@ static int wacom_probe(struct usb_interf
 	struct wacom_wac *wacom_wac;
 	struct wacom_features *features;
 	struct input_dev *input_dev;
-	int error = -ENOMEM;
+	int error;
+
+	if (!id->driver_info)
+		return -EINVAL;
 
 	wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
 	wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL);
 	input_dev = input_allocate_device();
-	if (!wacom || !input_dev || !wacom_wac)
+	if (!wacom || !input_dev || !wacom_wac) {
+		error = -ENOMEM;
 		goto fail1;
+	}
 
-	wacom_wac->data = usb_buffer_alloc(dev, WACOM_PKGLEN_MAX, GFP_KERNEL, &wacom->data_dma);
-	if (!wacom_wac->data)
+	wacom_wac->features = *((struct wacom_features *)id->driver_info);
+	features = &wacom_wac->features;
+	if (features->pktlen > WACOM_PKGLEN_MAX) {
+		error = -EINVAL;
+		goto fail1;
+	}
+
+	wacom_wac->data = usb_buffer_alloc(dev, WACOM_PKGLEN_MAX,
+					   GFP_KERNEL, &wacom->data_dma);
+	if (!wacom_wac->data) {
+		error = -ENOMEM;
 		goto fail1;
+	}
 
 	wacom->irq = usb_alloc_urb(0, GFP_KERNEL);
-	if (!wacom->irq)
+	if (!wacom->irq) {
+		error = -ENOMEM;
 		goto fail2;
+	}
 
 	wacom->usbdev = dev;
 	wacom->dev = input_dev;
@@ -555,11 +576,6 @@ static int wacom_probe(struct usb_interf
 	usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
 	strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
 
-	wacom_wac->features = features = get_wacom_feature(id);
-	BUG_ON(features->pktlen > WACOM_PKGLEN_MAX);
-
-	input_dev->name = wacom_wac->features->name;
-	wacom->wacom_wac = wacom_wac;
 	usb_to_input_id(dev, &input_dev->id);
 
 	input_dev->dev.parent = &intf->dev;
@@ -576,6 +592,19 @@ static int wacom_probe(struct usb_interf
 	if (error)
 		goto fail2;
 
+	strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name));
+
+	if (features->type == TABLETPC || features->type == TABLETPC2FG) {
+		/* Append the device type to the name */
+		strlcat(wacom_wac->name,
+			features->device_type == BTN_TOOL_PEN ?
+				" Pen" : " Finger",
+			sizeof(wacom_wac->name));
+	}
+
+	input_dev->name = wacom_wac->name;
+	wacom->wacom_wac = wacom_wac;
+
 	input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH);
 
@@ -640,17 +669,19 @@ static int wacom_suspend(struct usb_inte
 static int wacom_resume(struct usb_interface *intf)
 {
 	struct wacom *wacom = usb_get_intfdata(intf);
-	struct wacom_features *features = wacom->wacom_wac->features;
+	struct wacom_features *features = &wacom->wacom_wac->features;
 	int rv;
 
 	mutex_lock(&wacom->lock);
-	if (wacom->open) {
+
+	/* switch to wacom mode first */
+	wacom_query_tablet_data(intf, features);
+
+	if (wacom->open)
 		rv = usb_submit_urb(wacom->irq, GFP_NOIO);
-		/* switch to wacom mode if needed */
-		if (!wacom_retrieve_hid_descriptor(intf, features))
-			wacom_query_tablet_data(intf, features);
-	} else
+	else
 		rv = 0;
+
 	mutex_unlock(&wacom->lock);
 
 	return rv;
@@ -663,6 +694,7 @@ static int wacom_reset_resume(struct usb
 
 static struct usb_driver wacom_driver = {
 	.name =		"wacom",
+	.id_table =	wacom_ids,
 	.probe =	wacom_probe,
 	.disconnect =	wacom_disconnect,
 	.suspend =	wacom_suspend,
@@ -674,7 +706,7 @@ static struct usb_driver wacom_driver =
 static int __init wacom_init(void)
 {
 	int result;
-	wacom_driver.id_table = get_device_table();
+
 	result = usb_register(&wacom_driver);
 	if (result == 0)
 		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom_wac.c linux-libre-2.6.34-gnu1/drivers/input/tablet/wacom_wac.c
--- linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom_wac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/tablet/wacom_wac.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,6 +55,7 @@ static int wacom_penpartner_irq(struct w
 
 static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
 {
+	struct wacom_features *features = &wacom->features;
 	unsigned char *data = wacom->data;
 	int prox, pressure;
 
@@ -68,9 +69,9 @@ static int wacom_pl_irq(struct wacom_wac
 	if (prox) {
 		wacom->id[0] = ERASER_DEVICE_ID;
 		pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
-		if (wacom->features->pressure_max > 255)
+		if (features->pressure_max > 255)
 			pressure = (pressure << 1) | ((data[4] >> 6) & 1);
-		pressure += (wacom->features->pressure_max + 1) / 2;
+		pressure += (features->pressure_max + 1) / 2;
 
 		/*
 		 * if going from out of proximity into proximity select between the eraser
@@ -152,6 +153,7 @@ static int wacom_ptu_irq(struct wacom_wa
 
 static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 {
+	struct wacom_features *features = &wacom->features;
 	unsigned char *data = wacom->data;
 	int x, y, rw;
 	static int penData = 0;
@@ -179,8 +181,7 @@ static int wacom_graphire_irq(struct wac
 
 			case 2: /* Mouse with wheel */
 				wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04);
-				if (wacom->features->type == WACOM_G4 ||
-						wacom->features->type == WACOM_MO) {
+				if (features->type == WACOM_G4 || features->type == WACOM_MO) {
 					rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03);
 					wacom_report_rel(wcombo, REL_WHEEL, -rw);
 				} else
@@ -192,8 +193,7 @@ static int wacom_graphire_irq(struct wac
 				wacom->id[0] = CURSOR_DEVICE_ID;
 				wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
 				wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
-				if (wacom->features->type == WACOM_G4 ||
-						wacom->features->type == WACOM_MO)
+				if (features->type == WACOM_G4 || features->type == WACOM_MO)
 					wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
 				else
 					wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
@@ -230,7 +230,7 @@ static int wacom_graphire_irq(struct wac
 	}
 
 	/* send pad data */
-	switch (wacom->features->type) {
+	switch (features->type) {
 	    case WACOM_G4:
 		if (data[7] & 0xf8) {
 			if (penData) {
@@ -300,11 +300,12 @@ static int wacom_graphire_irq(struct wac
 
 static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
 {
+	struct wacom_features *features = &wacom->features;
 	unsigned char *data = wacom->data;
 	int idx = 0;
 
 	/* tool number */
-	if (wacom->features->type == INTUOS)
+	if (features->type == INTUOS)
 		idx = data[1] & 0x01;
 
 	/* Enter report */
@@ -402,7 +403,7 @@ static int wacom_intuos_inout(struct wac
 			wacom_report_key(wcombo, BTN_STYLUS2, 0);
 			wacom_report_key(wcombo, BTN_TOUCH, 0);
 			wacom_report_abs(wcombo, ABS_WHEEL, 0);
-			if (wacom->features->type >= INTUOS3S)
+			if (features->type >= INTUOS3S)
 				wacom_report_abs(wcombo, ABS_Z, 0);
 		}
 		wacom_report_key(wcombo, wacom->tool[idx], 0);
@@ -416,13 +417,14 @@ static int wacom_intuos_inout(struct wac
 
 static void wacom_intuos_general(struct wacom_wac *wacom, void *wcombo)
 {
+	struct wacom_features *features = &wacom->features;
 	unsigned char *data = wacom->data;
 	unsigned int t;
 
 	/* general pen packet */
 	if ((data[1] & 0xb8) == 0xa0) {
 		t = (data[6] << 2) | ((data[7] >> 6) & 3);
-		if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L)
+		if (features->type >= INTUOS4S && features->type <= INTUOS4L)
 			t = (t << 1) | (data[1] & 1);
 		wacom_report_abs(wcombo, ABS_PRESSURE, t);
 		wacom_report_abs(wcombo, ABS_TILT_X,
@@ -446,6 +448,7 @@ static void wacom_intuos_general(struct
 
 static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
 {
+	struct wacom_features *features = &wacom->features;
 	unsigned char *data = wacom->data;
 	unsigned int t;
 	int idx = 0, result;
@@ -457,7 +460,7 @@ static int wacom_intuos_irq(struct wacom
 	}
 
 	/* tool number */
-	if (wacom->features->type == INTUOS)
+	if (features->type == INTUOS)
 		idx = data[1] & 0x01;
 
 	/* pad packets. Works as a second tool and is always in prox */
@@ -466,7 +469,7 @@ static int wacom_intuos_irq(struct wacom
 		if (wacom->tool[1] != BTN_TOOL_FINGER)
 			wacom->tool[1] = BTN_TOOL_FINGER;
 
-		if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) {
+		if (features->type >= INTUOS4S && features->type <= INTUOS4L) {
 			wacom_report_key(wcombo, BTN_0, (data[2] & 0x01));
 			wacom_report_key(wcombo, BTN_1, (data[3] & 0x01));
 			wacom_report_key(wcombo, BTN_2, (data[3] & 0x02));
@@ -480,7 +483,7 @@ static int wacom_intuos_irq(struct wacom
 				/* Out of proximity, clear wheel value. */
 				wacom_report_abs(wcombo, ABS_WHEEL, 0);
 			}
-			if (wacom->features->type != INTUOS4S) {
+			if (features->type != INTUOS4S) {
 				wacom_report_key(wcombo, BTN_7, (data[3] & 0x40));
 				wacom_report_key(wcombo, BTN_8, (data[3] & 0x80));
 			}
@@ -528,18 +531,20 @@ static int wacom_intuos_irq(struct wacom
 		return 0;
 
 	/* Only large Intuos support Lense Cursor */
-	if ((wacom->tool[idx] == BTN_TOOL_LENS)
-			&& ((wacom->features->type == INTUOS3)
-			|| (wacom->features->type == INTUOS3S)
-			|| (wacom->features->type == INTUOS4)
-			|| (wacom->features->type == INTUOS4S)))
+	if (wacom->tool[idx] == BTN_TOOL_LENS &&
+	    (features->type == INTUOS3 ||
+	     features->type == INTUOS3S ||
+	     features->type == INTUOS4 ||
+	     features->type == INTUOS4S)) {
+
 		return 0;
+	}
 
 	/* Cintiq doesn't send data when RDY bit isn't set */
-	if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40))
+	if (features->type == CINTIQ && !(data[1] & 0x40))
                  return 0;
 
-	if (wacom->features->type >= INTUOS3S) {
+	if (features->type >= INTUOS3S) {
 		wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
 		wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
 		wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
@@ -557,7 +562,7 @@ static int wacom_intuos_irq(struct wacom
 
 		if (data[1] & 0x02) {
 			/* Rotation packet */
-			if (wacom->features->type >= INTUOS3S) {
+			if (features->type >= INTUOS3S) {
 				/* I3 marker pen rotation */
 				t = (data[6] << 3) | ((data[7] >> 5) & 7);
 				t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
@@ -570,7 +575,7 @@ static int wacom_intuos_irq(struct wacom
 					((t - 1) / 2) : -t / 2);
 			}
 
-		} else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3S) {
+		} else if (!(data[1] & 0x10) && features->type < INTUOS3S) {
 			/* 4D mouse packet */
 			wacom_report_key(wcombo, BTN_LEFT,   data[8] & 0x01);
 			wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02);
@@ -583,7 +588,7 @@ static int wacom_intuos_irq(struct wacom
 
 		} else if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
 			/* I4 mouse */
-			if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) {
+			if (features->type >= INTUOS4S && features->type <= INTUOS4L) {
 				wacom_report_key(wcombo, BTN_LEFT,   data[6] & 0x01);
 				wacom_report_key(wcombo, BTN_MIDDLE, data[6] & 0x02);
 				wacom_report_key(wcombo, BTN_RIGHT,  data[6] & 0x04);
@@ -604,13 +609,13 @@ static int wacom_intuos_irq(struct wacom
 						 - ((data[8] & 0x02) >> 1));
 
 				/* I3 2D mouse side buttons */
-				if (wacom->features->type >= INTUOS3S && wacom->features->type <= INTUOS3L) {
+				if (features->type >= INTUOS3S && features->type <= INTUOS3L) {
 					wacom_report_key(wcombo, BTN_SIDE,   data[8] & 0x40);
 					wacom_report_key(wcombo, BTN_EXTRA,  data[8] & 0x20);
 				}
 			}
-		} else if ((wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L ||
-				wacom->features->type == INTUOS4L) &&
+		} else if ((features->type < INTUOS3S || features->type == INTUOS3L ||
+				features->type == INTUOS4L) &&
 			   wacom->tool[idx] == BTN_TOOL_LENS) {
 			/* Lens cursor packets */
 			wacom_report_key(wcombo, BTN_LEFT,   data[8] & 0x01);
@@ -718,6 +723,7 @@ static void wacom_tpc_touch_in(struct wa
 
 static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
 {
+	struct wacom_features *features = &wacom->features;
 	char *data = wacom->data;
 	int prox = 0, pressure, idx = -1;
 	static int stylusInProx, touchInProx = 1, touchOut;
@@ -791,7 +797,7 @@ static int wacom_tpc_irq(struct wacom_wa
 			wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
 			pressure = ((data[7] & 0x01) << 8) | data[6];
 			if (pressure < 0)
-				pressure = wacom->features->pressure_max + pressure + 1;
+				pressure = features->pressure_max + pressure + 1;
 			wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
 			wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
 		} else {
@@ -815,7 +821,7 @@ static int wacom_tpc_irq(struct wacom_wa
 
 int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo)
 {
-	switch (wacom_wac->features->type) {
+	switch (wacom_wac->features.type) {
 		case PENPARTNER:
 			return wacom_penpartner_irq(wacom_wac, wcombo);
 
@@ -853,7 +859,7 @@ int wacom_wac_irq(struct wacom_wac *waco
 
 void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-	switch (wacom_wac->features->type) {
+	switch (wacom_wac->features.type) {
 		case WACOM_MO:
 			input_dev_mo(input_dev, wacom_wac);
 		case WACOM_G4:
@@ -888,7 +894,7 @@ void wacom_init_input_dev(struct input_d
 			/* fall through */
 		case TABLETPC:
 			input_dev_tpc(input_dev, wacom_wac);
-			if (wacom_wac->features->device_type != BTN_TOOL_PEN)
+			if (wacom_wac->features.device_type != BTN_TOOL_PEN)
 				break;  /* no need to process stylus stuff */
 
 			/* fall through */
@@ -903,153 +909,201 @@ void wacom_init_input_dev(struct input_d
 	return;
 }
 
-static struct wacom_features wacom_features[] = {
-	{ "Wacom Penpartner",     WACOM_PKGLEN_PENPRTN,    5040,  3780,  255,  0, PENPARTNER },
-	{ "Wacom Graphire",       WACOM_PKGLEN_GRAPHIRE,  10206,  7422,  511, 63, GRAPHIRE },
-	{ "Wacom Graphire2 4x5",  WACOM_PKGLEN_GRAPHIRE,  10206,  7422,  511, 63, GRAPHIRE },
-	{ "Wacom Graphire2 5x7",  WACOM_PKGLEN_GRAPHIRE,  13918, 10206,  511, 63, GRAPHIRE },
-	{ "Wacom Graphire3",      WACOM_PKGLEN_GRAPHIRE,  10208,  7424,  511, 63, GRAPHIRE },
-	{ "Wacom Graphire3 6x8",  WACOM_PKGLEN_GRAPHIRE,  16704, 12064,  511, 63, GRAPHIRE },
-	{ "Wacom Graphire4 4x5",  WACOM_PKGLEN_GRAPHIRE,  10208,  7424,  511, 63, WACOM_G4 },
-	{ "Wacom Graphire4 6x8",  WACOM_PKGLEN_GRAPHIRE,  16704, 12064,  511, 63, WACOM_G4 },
-	{ "Wacom BambooFun 4x5",  WACOM_PKGLEN_BBFUN,     14760,  9225,  511, 63, WACOM_MO },
-	{ "Wacom BambooFun 6x8",  WACOM_PKGLEN_BBFUN,     21648, 13530,  511, 63, WACOM_MO },
-	{ "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE,  16704, 12064,  511, 63, GRAPHIRE },
-	{ "Wacom Volito",         WACOM_PKGLEN_GRAPHIRE,   5104,  3712,  511, 63, GRAPHIRE },
-	{ "Wacom PenStation2",    WACOM_PKGLEN_GRAPHIRE,   3250,  2320,  255, 63, GRAPHIRE },
-	{ "Wacom Volito2 4x5",    WACOM_PKGLEN_GRAPHIRE,   5104,  3712,  511, 63, GRAPHIRE },
-	{ "Wacom Volito2 2x3",    WACOM_PKGLEN_GRAPHIRE,   3248,  2320,  511, 63, GRAPHIRE },
-	{ "Wacom PenPartner2",    WACOM_PKGLEN_GRAPHIRE,   3250,  2320,  511, 63, GRAPHIRE },
-	{ "Wacom Bamboo",         WACOM_PKGLEN_BBFUN,     14760,  9225,  511, 63, WACOM_MO },
-	{ "Wacom Bamboo1",        WACOM_PKGLEN_GRAPHIRE,   5104,  3712,  511, 63, GRAPHIRE },
-	{ "Wacom Intuos 4x5",     WACOM_PKGLEN_INTUOS,    12700, 10600, 1023, 31, INTUOS },
-	{ "Wacom Intuos 6x8",     WACOM_PKGLEN_INTUOS,    20320, 16240, 1023, 31, INTUOS },
-	{ "Wacom Intuos 9x12",    WACOM_PKGLEN_INTUOS,    30480, 24060, 1023, 31, INTUOS },
-	{ "Wacom Intuos 12x12",   WACOM_PKGLEN_INTUOS,    30480, 31680, 1023, 31, INTUOS },
-	{ "Wacom Intuos 12x18",   WACOM_PKGLEN_INTUOS,    45720, 31680, 1023, 31, INTUOS },
-	{ "Wacom PL400",          WACOM_PKGLEN_GRAPHIRE,   5408,  4056,  255,  0, PL },
-	{ "Wacom PL500",          WACOM_PKGLEN_GRAPHIRE,   6144,  4608,  255,  0, PL },
-	{ "Wacom PL600",          WACOM_PKGLEN_GRAPHIRE,   6126,  4604,  255,  0, PL },
-	{ "Wacom PL600SX",        WACOM_PKGLEN_GRAPHIRE,   6260,  5016,  255,  0, PL },
-	{ "Wacom PL550",          WACOM_PKGLEN_GRAPHIRE,   6144,  4608,  511,  0, PL },
-	{ "Wacom PL800",          WACOM_PKGLEN_GRAPHIRE,   7220,  5780,  511,  0, PL },
-	{ "Wacom PL700",          WACOM_PKGLEN_GRAPHIRE,   6758,  5406,  511,  0, PL },
-	{ "Wacom PL510",          WACOM_PKGLEN_GRAPHIRE,   6282,  4762,  511,  0, PL },
-	{ "Wacom DTU710",         WACOM_PKGLEN_GRAPHIRE,  34080, 27660,  511,  0, PL },
-	{ "Wacom DTF521",         WACOM_PKGLEN_GRAPHIRE,   6282,  4762,  511,  0, PL },
-	{ "Wacom DTF720",         WACOM_PKGLEN_GRAPHIRE,   6858,  5506,  511,  0, PL },
-	{ "Wacom DTF720a",        WACOM_PKGLEN_GRAPHIRE,   6858,  5506,  511,  0, PL },
-	{ "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE,  20480, 15360,  511,  0, PTU },
-	{ "Wacom Intuos2 4x5",    WACOM_PKGLEN_INTUOS,    12700, 10600, 1023, 31, INTUOS },
-	{ "Wacom Intuos2 6x8",    WACOM_PKGLEN_INTUOS,    20320, 16240, 1023, 31, INTUOS },
-	{ "Wacom Intuos2 9x12",   WACOM_PKGLEN_INTUOS,    30480, 24060, 1023, 31, INTUOS },
-	{ "Wacom Intuos2 12x12",  WACOM_PKGLEN_INTUOS,    30480, 31680, 1023, 31, INTUOS },
-	{ "Wacom Intuos2 12x18",  WACOM_PKGLEN_INTUOS,    45720, 31680, 1023, 31, INTUOS },
-	{ "Wacom Intuos3 4x5",    WACOM_PKGLEN_INTUOS,    25400, 20320, 1023, 63, INTUOS3S },
-	{ "Wacom Intuos3 6x8",    WACOM_PKGLEN_INTUOS,    40640, 30480, 1023, 63, INTUOS3 },
-	{ "Wacom Intuos3 9x12",   WACOM_PKGLEN_INTUOS,    60960, 45720, 1023, 63, INTUOS3 },
-	{ "Wacom Intuos3 12x12",  WACOM_PKGLEN_INTUOS,    60960, 60960, 1023, 63, INTUOS3L },
-	{ "Wacom Intuos3 12x19",  WACOM_PKGLEN_INTUOS,    97536, 60960, 1023, 63, INTUOS3L },
-	{ "Wacom Intuos3 6x11",   WACOM_PKGLEN_INTUOS,    54204, 31750, 1023, 63, INTUOS3 },
-	{ "Wacom Intuos3 4x6",    WACOM_PKGLEN_INTUOS,    31496, 19685, 1023, 63, INTUOS3S },
-	{ "Wacom Intuos4 4x6",    WACOM_PKGLEN_INTUOS,    31496, 19685, 2047, 63, INTUOS4S },
-	{ "Wacom Intuos4 6x9",    WACOM_PKGLEN_INTUOS,    44704, 27940, 2047, 63, INTUOS4 },
-	{ "Wacom Intuos4 8x13",   WACOM_PKGLEN_INTUOS,    65024, 40640, 2047, 63, INTUOS4L },
-	{ "Wacom Intuos4 12x19",  WACOM_PKGLEN_INTUOS,    97536, 60960, 2047, 63, INTUOS4L },
-	{ "Wacom Cintiq 21UX",    WACOM_PKGLEN_INTUOS,    87200, 65600, 1023, 63, CINTIQ },
-	{ "Wacom Cintiq 20WSX",   WACOM_PKGLEN_INTUOS,    86680, 54180, 1023, 63, WACOM_BEE },
-	{ "Wacom Cintiq 12WX",    WACOM_PKGLEN_INTUOS,    53020, 33440, 1023, 63, WACOM_BEE },
-	{ "Wacom DTU1931",        WACOM_PKGLEN_GRAPHIRE,  37832, 30305,  511,  0, PL },
-	{ "Wacom ISDv4 90",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,  0, TABLETPC },
-	{ "Wacom ISDv4 93",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,  0, TABLETPC },
-	{ "Wacom ISDv4 9A",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,  0, TABLETPC },
-	{ "Wacom ISDv4 9F",       WACOM_PKGLEN_PENABLED,  26202, 16325,  255,  0, TABLETPC },
-	{ "Wacom ISDv4 E2",       WACOM_PKGLEN_TPC2FG,    26202, 16325,  255,  0, TABLETPC2FG },
-	{ "Wacom ISDv4 E3",       WACOM_PKGLEN_TPC2FG,    26202, 16325,  255,  0, TABLETPC2FG },
-	{ "Wacom Intuos2 6x8",    WACOM_PKGLEN_INTUOS,    20320, 16240, 1023, 31, INTUOS },
-	{ }
-};
+static const struct wacom_features wacom_features_0x00 =
+	{ "Wacom Penpartner",     WACOM_PKGLEN_PENPRTN,    5040,  3780,  255,  0, PENPARTNER };
+static const struct wacom_features wacom_features_0x10 =
+	{ "Wacom Graphire",       WACOM_PKGLEN_GRAPHIRE,  10206,  7422,  511, 63, GRAPHIRE };
+static const struct wacom_features wacom_features_0x11 =
+	{ "Wacom Graphire2 4x5",  WACOM_PKGLEN_GRAPHIRE,  10206,  7422,  511, 63, GRAPHIRE };
+static const struct wacom_features wacom_features_0x12 =
+	{ "Wacom Graphire2 5x7",  WACOM_PKGLEN_GRAPHIRE,  13918, 10206,  511, 63, GRAPHIRE };
+static const struct wacom_features wacom_features_0x13 =
+	{ "Wacom Graphire3",      WACOM_PKGLEN_GRAPHIRE,  10208,  7424,  511, 63, GRAPHIRE };
+static const struct wacom_features wacom_features_0x14 =
+	{ "Wacom Graphire3 6x8",  WACOM_PKGLEN_GRAPHIRE,  16704, 12064,  511, 63, GRAPHIRE };
+static const struct wacom_features wacom_features_0x15 =
+	{ "Wacom Graphire4 4x5",  WACOM_PKGLEN_GRAPHIRE,  10208,  7424,  511, 63, WACOM_G4 };
+static const struct wacom_features wacom_features_0x16 =
+	{ "Wacom Graphire4 6x8",  WACOM_PKGLEN_GRAPHIRE,  16704, 12064,  511, 63, WACOM_G4 };
+static const struct wacom_features wacom_features_0x17 =
+	{ "Wacom BambooFun 4x5",  WACOM_PKGLEN_BBFUN,     14760,  9225,  511, 63, WACOM_MO };
+static const struct wacom_features wacom_features_0x18 =
+	{ "Wacom BambooFun 6x8",  WACOM_PKGLEN_BBFUN,     21648, 13530,  511, 63, WACOM_MO };
+static const struct wacom_features wacom_features_0x19 =
+	{ "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE,  16704, 12064,  511, 63, GRAPHIRE };
+static const struct wacom_features wacom_features_0x60 =
+	{ "Wacom Volito",         WACOM_PKGLEN_GRAPHIRE,   5104,  3712,  511, 63, GRAPHIRE };
+static const struct wacom_features wacom_features_0x61 =
+	{ "Wacom PenStation2",    WACOM_PKGLEN_GRAPHIRE,   3250,  2320,  255, 63, GRAPHIRE };
+static const struct wacom_features wacom_features_0x62 =
+	{ "Wacom Volito2 4x5",    WACOM_PKGLEN_GRAPHIRE,   5104,  3712,  511, 63, GRAPHIRE };
+static const struct wacom_features wacom_features_0x63 =
+	{ "Wacom Volito2 2x3",    WACOM_PKGLEN_GRAPHIRE,   3248,  2320,  511, 63, GRAPHIRE };
+static const struct wacom_features wacom_features_0x64 =
+	{ "Wacom PenPartner2",    WACOM_PKGLEN_GRAPHIRE,   3250,  2320,  511, 63, GRAPHIRE };
+static const struct wacom_features wacom_features_0x65 =
+	{ "Wacom Bamboo",         WACOM_PKGLEN_BBFUN,     14760,  9225,  511, 63, WACOM_MO };
+static const struct wacom_features wacom_features_0x69 =
+	{ "Wacom Bamboo1",        WACOM_PKGLEN_GRAPHIRE,   5104,  3712,  511, 63, GRAPHIRE };
+static const struct wacom_features wacom_features_0x20 =
+	{ "Wacom Intuos 4x5",     WACOM_PKGLEN_INTUOS,    12700, 10600, 1023, 31, INTUOS };
+static const struct wacom_features wacom_features_0x21 =
+	{ "Wacom Intuos 6x8",     WACOM_PKGLEN_INTUOS,    20320, 16240, 1023, 31, INTUOS };
+static const struct wacom_features wacom_features_0x22 =
+	{ "Wacom Intuos 9x12",    WACOM_PKGLEN_INTUOS,    30480, 24060, 1023, 31, INTUOS };
+static const struct wacom_features wacom_features_0x23 =
+	{ "Wacom Intuos 12x12",   WACOM_PKGLEN_INTUOS,    30480, 31680, 1023, 31, INTUOS };
+static const struct wacom_features wacom_features_0x24 =
+	{ "Wacom Intuos 12x18",   WACOM_PKGLEN_INTUOS,    45720, 31680, 1023, 31, INTUOS };
+static const struct wacom_features wacom_features_0x30 =
+	{ "Wacom PL400",          WACOM_PKGLEN_GRAPHIRE,   5408,  4056,  255,  0, PL };
+static const struct wacom_features wacom_features_0x31 =
+	{ "Wacom PL500",          WACOM_PKGLEN_GRAPHIRE,   6144,  4608,  255,  0, PL };
+static const struct wacom_features wacom_features_0x32 =
+	{ "Wacom PL600",          WACOM_PKGLEN_GRAPHIRE,   6126,  4604,  255,  0, PL };
+static const struct wacom_features wacom_features_0x33 =
+	{ "Wacom PL600SX",        WACOM_PKGLEN_GRAPHIRE,   6260,  5016,  255,  0, PL };
+static const struct wacom_features wacom_features_0x34 =
+	{ "Wacom PL550",          WACOM_PKGLEN_GRAPHIRE,   6144,  4608,  511,  0, PL };
+static const struct wacom_features wacom_features_0x35 =
+	{ "Wacom PL800",          WACOM_PKGLEN_GRAPHIRE,   7220,  5780,  511,  0, PL };
+static const struct wacom_features wacom_features_0x37 =
+	{ "Wacom PL700",          WACOM_PKGLEN_GRAPHIRE,   6758,  5406,  511,  0, PL };
+static const struct wacom_features wacom_features_0x38 =
+	{ "Wacom PL510",          WACOM_PKGLEN_GRAPHIRE,   6282,  4762,  511,  0, PL };
+static const struct wacom_features wacom_features_0x39 =
+	{ "Wacom DTU710",         WACOM_PKGLEN_GRAPHIRE,  34080, 27660,  511,  0, PL };
+static const struct wacom_features wacom_features_0xC4 =
+	{ "Wacom DTF521",         WACOM_PKGLEN_GRAPHIRE,   6282,  4762,  511,  0, PL };
+static const struct wacom_features wacom_features_0xC0 =
+	{ "Wacom DTF720",         WACOM_PKGLEN_GRAPHIRE,   6858,  5506,  511,  0, PL };
+static const struct wacom_features wacom_features_0xC2 =
+	{ "Wacom DTF720a",        WACOM_PKGLEN_GRAPHIRE,   6858,  5506,  511,  0, PL };
+static const struct wacom_features wacom_features_0x03 =
+	{ "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE,  20480, 15360,  511,  0, PTU };
+static const struct wacom_features wacom_features_0x41 =
+	{ "Wacom Intuos2 4x5",    WACOM_PKGLEN_INTUOS,    12700, 10600, 1023, 31, INTUOS };
+static const struct wacom_features wacom_features_0x42 =
+	{ "Wacom Intuos2 6x8",    WACOM_PKGLEN_INTUOS,    20320, 16240, 1023, 31, INTUOS };
+static const struct wacom_features wacom_features_0x43 =
+	{ "Wacom Intuos2 9x12",   WACOM_PKGLEN_INTUOS,    30480, 24060, 1023, 31, INTUOS };
+static const struct wacom_features wacom_features_0x44 =
+	{ "Wacom Intuos2 12x12",  WACOM_PKGLEN_INTUOS,    30480, 31680, 1023, 31, INTUOS };
+static const struct wacom_features wacom_features_0x45 =
+	{ "Wacom Intuos2 12x18",  WACOM_PKGLEN_INTUOS,    45720, 31680, 1023, 31, INTUOS };
+static const struct wacom_features wacom_features_0xB0 =
+	{ "Wacom Intuos3 4x5",    WACOM_PKGLEN_INTUOS,    25400, 20320, 1023, 63, INTUOS3S };
+static const struct wacom_features wacom_features_0xB1 =
+	{ "Wacom Intuos3 6x8",    WACOM_PKGLEN_INTUOS,    40640, 30480, 1023, 63, INTUOS3 };
+static const struct wacom_features wacom_features_0xB2 =
+	{ "Wacom Intuos3 9x12",   WACOM_PKGLEN_INTUOS,    60960, 45720, 1023, 63, INTUOS3 };
+static const struct wacom_features wacom_features_0xB3 =
+	{ "Wacom Intuos3 12x12",  WACOM_PKGLEN_INTUOS,    60960, 60960, 1023, 63, INTUOS3L };
+static const struct wacom_features wacom_features_0xB4 =
+	{ "Wacom Intuos3 12x19",  WACOM_PKGLEN_INTUOS,    97536, 60960, 1023, 63, INTUOS3L };
+static const struct wacom_features wacom_features_0xB5 =
+	{ "Wacom Intuos3 6x11",   WACOM_PKGLEN_INTUOS,    54204, 31750, 1023, 63, INTUOS3 };
+static const struct wacom_features wacom_features_0xB7 =
+	{ "Wacom Intuos3 4x6",    WACOM_PKGLEN_INTUOS,    31496, 19685, 1023, 63, INTUOS3S };
+static const struct wacom_features wacom_features_0xB8 =
+	{ "Wacom Intuos4 4x6",    WACOM_PKGLEN_INTUOS,    31496, 19685, 2047, 63, INTUOS4S };
+static const struct wacom_features wacom_features_0xB9 =
+	{ "Wacom Intuos4 6x9",    WACOM_PKGLEN_INTUOS,    44704, 27940, 2047, 63, INTUOS4 };
+static const struct wacom_features wacom_features_0xBA =
+	{ "Wacom Intuos4 8x13",   WACOM_PKGLEN_INTUOS,    65024, 40640, 2047, 63, INTUOS4L };
+static const struct wacom_features wacom_features_0xBB =
+	{ "Wacom Intuos4 12x19",  WACOM_PKGLEN_INTUOS,    97536, 60960, 2047, 63, INTUOS4L };
+static const struct wacom_features wacom_features_0x3F =
+	{ "Wacom Cintiq 21UX",    WACOM_PKGLEN_INTUOS,    87200, 65600, 1023, 63, CINTIQ };
+static const struct wacom_features wacom_features_0xC5 =
+	{ "Wacom Cintiq 20WSX",   WACOM_PKGLEN_INTUOS,    86680, 54180, 1023, 63, WACOM_BEE };
+static const struct wacom_features wacom_features_0xC6 =
+	{ "Wacom Cintiq 12WX",    WACOM_PKGLEN_INTUOS,    53020, 33440, 1023, 63, WACOM_BEE };
+static const struct wacom_features wacom_features_0xC7 =
+	{ "Wacom DTU1931",        WACOM_PKGLEN_GRAPHIRE,  37832, 30305,  511,  0, PL };
+static const struct wacom_features wacom_features_0x90 =
+	{ "Wacom ISDv4 90",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,  0, TABLETPC };
+static const struct wacom_features wacom_features_0x93 =
+	{ "Wacom ISDv4 93",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,  0, TABLETPC };
+static const struct wacom_features wacom_features_0x9A =
+	{ "Wacom ISDv4 9A",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,  0, TABLETPC };
+static const struct wacom_features wacom_features_0x9F =
+	{ "Wacom ISDv4 9F",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,  0, TABLETPC };
+static const struct wacom_features wacom_features_0xE2 =
+	{ "Wacom ISDv4 E2",       WACOM_PKGLEN_TPC2FG,    26202, 16325,  255,  0, TABLETPC2FG };
+static const struct wacom_features wacom_features_0xE3 =
+	{ "Wacom ISDv4 E3",       WACOM_PKGLEN_TPC2FG,    26202, 16325,  255,  0, TABLETPC2FG };
+static const struct wacom_features wacom_features_0x47 =
+	{ "Wacom Intuos2 6x8",    WACOM_PKGLEN_INTUOS,    20320, 16240, 1023, 31, INTUOS };
 
-static struct usb_device_id wacom_ids[] = {
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x00) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x17) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x18) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x19) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x69) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x30) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x32) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC4) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC2) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB8) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB9) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBA) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBB) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC7) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x90) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x93) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9A) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9F) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xE2) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xE3) },
-	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) },
+#define USB_DEVICE_WACOM(prod)					\
+	USB_DEVICE(USB_VENDOR_ID_WACOM, prod),			\
+	.driver_info = (kernel_ulong_t)&wacom_features_##prod
+
+const struct usb_device_id wacom_ids[] = {
+	{ USB_DEVICE_WACOM(0x00) },
+	{ USB_DEVICE_WACOM(0x10) },
+	{ USB_DEVICE_WACOM(0x11) },
+	{ USB_DEVICE_WACOM(0x12) },
+	{ USB_DEVICE_WACOM(0x13) },
+	{ USB_DEVICE_WACOM(0x14) },
+	{ USB_DEVICE_WACOM(0x15) },
+	{ USB_DEVICE_WACOM(0x16) },
+	{ USB_DEVICE_WACOM(0x17) },
+	{ USB_DEVICE_WACOM(0x18) },
+	{ USB_DEVICE_WACOM(0x19) },
+	{ USB_DEVICE_WACOM(0x60) },
+	{ USB_DEVICE_WACOM(0x61) },
+	{ USB_DEVICE_WACOM(0x62) },
+	{ USB_DEVICE_WACOM(0x63) },
+	{ USB_DEVICE_WACOM(0x64) },
+	{ USB_DEVICE_WACOM(0x65) },
+	{ USB_DEVICE_WACOM(0x69) },
+	{ USB_DEVICE_WACOM(0x20) },
+	{ USB_DEVICE_WACOM(0x21) },
+	{ USB_DEVICE_WACOM(0x22) },
+	{ USB_DEVICE_WACOM(0x23) },
+	{ USB_DEVICE_WACOM(0x24) },
+	{ USB_DEVICE_WACOM(0x30) },
+	{ USB_DEVICE_WACOM(0x31) },
+	{ USB_DEVICE_WACOM(0x32) },
+	{ USB_DEVICE_WACOM(0x33) },
+	{ USB_DEVICE_WACOM(0x34) },
+	{ USB_DEVICE_WACOM(0x35) },
+	{ USB_DEVICE_WACOM(0x37) },
+	{ USB_DEVICE_WACOM(0x38) },
+	{ USB_DEVICE_WACOM(0x39) },
+	{ USB_DEVICE_WACOM(0xC4) },
+	{ USB_DEVICE_WACOM(0xC0) },
+	{ USB_DEVICE_WACOM(0xC2) },
+	{ USB_DEVICE_WACOM(0x03) },
+	{ USB_DEVICE_WACOM(0x41) },
+	{ USB_DEVICE_WACOM(0x42) },
+	{ USB_DEVICE_WACOM(0x43) },
+	{ USB_DEVICE_WACOM(0x44) },
+	{ USB_DEVICE_WACOM(0x45) },
+	{ USB_DEVICE_WACOM(0xB0) },
+	{ USB_DEVICE_WACOM(0xB1) },
+	{ USB_DEVICE_WACOM(0xB2) },
+	{ USB_DEVICE_WACOM(0xB3) },
+	{ USB_DEVICE_WACOM(0xB4) },
+	{ USB_DEVICE_WACOM(0xB5) },
+	{ USB_DEVICE_WACOM(0xB7) },
+	{ USB_DEVICE_WACOM(0xB8) },
+	{ USB_DEVICE_WACOM(0xB9) },
+	{ USB_DEVICE_WACOM(0xBA) },
+	{ USB_DEVICE_WACOM(0xBB) },
+	{ USB_DEVICE_WACOM(0x3F) },
+	{ USB_DEVICE_WACOM(0xC5) },
+	{ USB_DEVICE_WACOM(0xC6) },
+	{ USB_DEVICE_WACOM(0xC7) },
+	{ USB_DEVICE_WACOM(0x90) },
+	{ USB_DEVICE_WACOM(0x93) },
+	{ USB_DEVICE_WACOM(0x9A) },
+	{ USB_DEVICE_WACOM(0x9F) },
+	{ USB_DEVICE_WACOM(0xE2) },
+	{ USB_DEVICE_WACOM(0xE3) },
+	{ USB_DEVICE_WACOM(0x47) },
 	{ }
 };
-
-const struct usb_device_id *get_device_table(void)
-{
-        const struct usb_device_id *id_table = wacom_ids;
-
-        return id_table;
-}
-
-struct wacom_features * get_wacom_feature(const struct usb_device_id *id)
-{
-        int index = id - wacom_ids;
-        struct wacom_features *wf = &wacom_features[index];
-
-        return wf;
-}
-
 MODULE_DEVICE_TABLE(usb, wacom_ids);
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom_wac.h linux-libre-2.6.34-gnu1/drivers/input/tablet/wacom_wac.h
--- linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom_wac.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/tablet/wacom_wac.h	2010-05-16 17:17:36.000000000 -0400
@@ -15,11 +15,10 @@
 /* packet length for individual models */
 #define WACOM_PKGLEN_PENPRTN	 7
 #define WACOM_PKGLEN_GRAPHIRE	 8
-#define WACOM_PKGLEN_BBFUN 	 9
-#define WACOM_PKGLEN_INTUOS 	10
-#define WACOM_PKGLEN_PENABLED	 8
+#define WACOM_PKGLEN_BBFUN	 9
+#define WACOM_PKGLEN_INTUOS	10
 #define WACOM_PKGLEN_TPC1FG	 5
-#define WACOM_PKGLEN_TPC2FG 	14
+#define WACOM_PKGLEN_TPC2FG	14
 
 /* device IDs */
 #define STYLUS_DEVICE_ID	0x02
@@ -58,7 +57,7 @@ enum {
 };
 
 struct wacom_features {
-	char *name;
+	const char *name;
 	int pktlen;
 	int x_max;
 	int y_max;
@@ -73,11 +72,12 @@ struct wacom_features {
 };
 
 struct wacom_wac {
+	char name[64];
 	unsigned char *data;
-        int tool[2];
-        int id[2];
-        __u32 serial[2];
-	struct wacom_features *features;
+	int tool[2];
+	int id[2];
+	__u32 serial[2];
+	struct wacom_features features;
 };
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/88pm860x-ts.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/88pm860x-ts.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/88pm860x-ts.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/88pm860x-ts.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,237 @@
+/*
+ * Touchscreen driver for Marvell 88PM860x
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ * 	Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/mfd/88pm860x.h>
+#include <linux/slab.h>
+
+#define MEAS_LEN		(8)
+#define ACCURATE_BIT		(12)
+
+/* touch register */
+#define MEAS_EN3		(0x52)
+
+#define MEAS_TSIX_1		(0x8D)
+#define MEAS_TSIX_2		(0x8E)
+#define MEAS_TSIY_1		(0x8F)
+#define MEAS_TSIY_2		(0x90)
+#define MEAS_TSIZ1_1		(0x91)
+#define MEAS_TSIZ1_2		(0x92)
+#define MEAS_TSIZ2_1		(0x93)
+#define MEAS_TSIZ2_2		(0x94)
+
+/* bit definitions of touch */
+#define MEAS_PD_EN		(1 << 3)
+#define MEAS_TSIX_EN		(1 << 4)
+#define MEAS_TSIY_EN		(1 << 5)
+#define MEAS_TSIZ1_EN		(1 << 6)
+#define MEAS_TSIZ2_EN		(1 << 7)
+
+struct pm860x_touch {
+	struct input_dev *idev;
+	struct i2c_client *i2c;
+	struct pm860x_chip *chip;
+	int irq;
+	int res_x;		/* resistor of Xplate */
+};
+
+static irqreturn_t pm860x_touch_handler(int irq, void *data)
+{
+	struct pm860x_touch *touch = data;
+	struct pm860x_chip *chip = touch->chip;
+	unsigned char buf[MEAS_LEN];
+	int x, y, pen_down;
+	int z1, z2, rt = 0;
+	int ret;
+
+	ret = pm860x_bulk_read(touch->i2c, MEAS_TSIX_1, MEAS_LEN, buf);
+	if (ret < 0)
+		goto out;
+
+	pen_down = buf[1] & (1 << 6);
+	x = ((buf[0] & 0xFF) << 4) | (buf[1] & 0x0F);
+	y = ((buf[2] & 0xFF) << 4) | (buf[3] & 0x0F);
+	z1 = ((buf[4] & 0xFF) << 4) | (buf[5] & 0x0F);
+	z2 = ((buf[6] & 0xFF) << 4) | (buf[7] & 0x0F);
+
+	if (pen_down) {
+		if ((x != 0) && (z1 != 0) && (touch->res_x != 0)) {
+			rt = z2 / z1 - 1;
+			rt = (rt * touch->res_x * x) >> ACCURATE_BIT;
+			dev_dbg(chip->dev, "z1:%d, z2:%d, rt:%d\n",
+				z1, z2, rt);
+		}
+		input_report_abs(touch->idev, ABS_X, x);
+		input_report_abs(touch->idev, ABS_Y, y);
+		input_report_abs(touch->idev, ABS_PRESSURE, rt);
+		input_report_key(touch->idev, BTN_TOUCH, 1);
+		dev_dbg(chip->dev, "pen down at [%d, %d].\n", x, y);
+	} else {
+		input_report_abs(touch->idev, ABS_PRESSURE, 0);
+		input_report_key(touch->idev, BTN_TOUCH, 0);
+		dev_dbg(chip->dev, "pen release\n");
+	}
+	input_sync(touch->idev);
+
+out:
+	return IRQ_HANDLED;
+}
+
+static int pm860x_touch_open(struct input_dev *dev)
+{
+	struct pm860x_touch *touch = input_get_drvdata(dev);
+	int data, ret;
+
+	data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN
+		| MEAS_TSIZ1_EN | MEAS_TSIZ2_EN;
+	ret = pm860x_set_bits(touch->i2c, MEAS_EN3, data, data);
+	if (ret < 0)
+		goto out;
+	return 0;
+out:
+	return ret;
+}
+
+static void pm860x_touch_close(struct input_dev *dev)
+{
+	struct pm860x_touch *touch = input_get_drvdata(dev);
+	int data;
+
+	data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN
+		| MEAS_TSIZ1_EN | MEAS_TSIZ2_EN;
+	pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0);
+}
+
+static int __devinit pm860x_touch_probe(struct platform_device *pdev)
+{
+	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct pm860x_platform_data *pm860x_pdata =		\
+				pdev->dev.parent->platform_data;
+	struct pm860x_touch_pdata *pdata = NULL;
+	struct pm860x_touch *touch;
+	int irq, ret;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "No IRQ resource!\n");
+		return -EINVAL;
+	}
+
+	if (!pm860x_pdata) {
+		dev_err(&pdev->dev, "platform data is missing\n");
+		return -EINVAL;
+	}
+
+	pdata = pm860x_pdata->touch;
+	if (!pdata) {
+		dev_err(&pdev->dev, "touchscreen data is missing\n");
+		return -EINVAL;
+	}
+
+	touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
+	if (touch == NULL)
+		return -ENOMEM;
+	dev_set_drvdata(&pdev->dev, touch);
+
+	touch->idev = input_allocate_device();
+	if (touch->idev == NULL) {
+		dev_err(&pdev->dev, "Failed to allocate input device!\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	touch->idev->name = "88pm860x-touch";
+	touch->idev->phys = "88pm860x/input0";
+	touch->idev->id.bustype = BUS_I2C;
+	touch->idev->dev.parent = &pdev->dev;
+	touch->idev->open = pm860x_touch_open;
+	touch->idev->close = pm860x_touch_close;
+	touch->chip = chip;
+	touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+	touch->irq = irq + chip->irq_base;
+	touch->res_x = pdata->res_x;
+	input_set_drvdata(touch->idev, touch);
+
+	ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler,
+				   IRQF_ONESHOT, "touch", touch);
+	if (ret < 0)
+		goto out_irq;
+
+	__set_bit(EV_ABS, touch->idev->evbit);
+	__set_bit(ABS_X, touch->idev->absbit);
+	__set_bit(ABS_Y, touch->idev->absbit);
+	__set_bit(ABS_PRESSURE, touch->idev->absbit);
+	__set_bit(EV_SYN, touch->idev->evbit);
+	__set_bit(EV_KEY, touch->idev->evbit);
+	__set_bit(BTN_TOUCH, touch->idev->keybit);
+
+	input_set_abs_params(touch->idev, ABS_X, 0, 1 << ACCURATE_BIT, 0, 0);
+	input_set_abs_params(touch->idev, ABS_Y, 0, 1 << ACCURATE_BIT, 0, 0);
+	input_set_abs_params(touch->idev, ABS_PRESSURE, 0, 1 << ACCURATE_BIT,
+				0, 0);
+
+	ret = input_register_device(touch->idev);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to register touch!\n");
+		goto out_rg;
+	}
+
+	platform_set_drvdata(pdev, touch);
+	return 0;
+out_rg:
+	free_irq(touch->irq, touch);
+out_irq:
+	input_free_device(touch->idev);
+out:
+	kfree(touch);
+	return ret;
+}
+
+static int __devexit pm860x_touch_remove(struct platform_device *pdev)
+{
+	struct pm860x_touch *touch = platform_get_drvdata(pdev);
+
+	input_unregister_device(touch->idev);
+	free_irq(touch->irq, touch);
+	platform_set_drvdata(pdev, NULL);
+	kfree(touch);
+	return 0;
+}
+
+static struct platform_driver pm860x_touch_driver = {
+	.driver	= {
+		.name	= "88pm860x-touch",
+		.owner	= THIS_MODULE,
+	},
+	.probe	= pm860x_touch_probe,
+	.remove	= __devexit_p(pm860x_touch_remove),
+};
+
+static int __init pm860x_touch_init(void)
+{
+	return platform_driver_register(&pm860x_touch_driver);
+}
+module_init(pm860x_touch_init);
+
+static void __exit pm860x_touch_exit(void)
+{
+	platform_driver_unregister(&pm860x_touch_driver);
+}
+module_exit(pm860x_touch_exit);
+
+MODULE_DESCRIPTION("Touchscreen driver for Marvell Semiconductor 88PM860x");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:88pm860x-touch");
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/ad7877.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/ad7877.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/ad7877.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/ad7877.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,7 +46,7 @@
 #include <linux/spi/ad7877.h>
 #include <asm/irq.h>
 
-#define	TS_PEN_UP_TIMEOUT	msecs_to_jiffies(50)
+#define	TS_PEN_UP_TIMEOUT	msecs_to_jiffies(100)
 
 #define MAX_SPI_FREQ_HZ			20000000
 #define	MAX_12BIT			((1<<12)-1)
@@ -156,9 +156,14 @@ struct ser_req {
 	u16			reset;
 	u16			ref_on;
 	u16			command;
-	u16			sample;
 	struct spi_message	msg;
 	struct spi_transfer	xfer[6];
+
+	/*
+	 * DMA (thus cache coherency maintenance) requires the
+	 * transfer buffers to live in their own cache lines.
+	 */
+	u16 sample ____cacheline_aligned;
 };
 
 struct ad7877 {
@@ -182,8 +187,6 @@ struct ad7877 {
 	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;
 
@@ -195,6 +198,12 @@ struct ad7877 {
 	spinlock_t		lock;
 	struct timer_list	timer;		/* P: lock */
 	unsigned		pending:1;	/* P: lock */
+
+	/*
+	 * DMA (thus cache coherency maintenance) requires the
+	 * transfer buffers to live in their own cache lines.
+	 */
+	u16 conversion_data[AD7877_NR_SENSE] ____cacheline_aligned;
 };
 
 static int gpio3;
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/ads7846.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/ads7846.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/ads7846.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/ads7846.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
+#include <linux/regulator/consumer.h>
 #include <asm/irq.h>
 
 /*
@@ -35,6 +36,7 @@
  * TSC2046 is just newer ads7846 silicon.
  * Support for ads7843 tested on Atmel at91sam926x-EK.
  * Support for ads7845 has only been stubbed in.
+ * Support for Analog Devices AD7873 and AD7843 tested.
  *
  * IRQ handling needs a workaround because of a shortcoming in handling
  * edge triggered IRQs on some platforms like the OMAP1/2. These
@@ -85,6 +87,7 @@ struct ads7846 {
 	char			name[32];
 
 	struct spi_device	*spi;
+	struct regulator	*reg;
 
 #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE)
 	struct attribute_group	*attr_group;
@@ -788,6 +791,8 @@ static void ads7846_disable(struct ads78
 		}
 	}
 
+	regulator_disable(ts->reg);
+
 	/* we know the chip's in lowpower mode since we always
 	 * leave it that way after every request
 	 */
@@ -799,6 +804,8 @@ static void ads7846_enable(struct ads784
 	if (!ts->disabled)
 		return;
 
+	regulator_enable(ts->reg);
+
 	ts->disabled = 0;
 	ts->irq_disabled = 0;
 	enable_irq(ts->spi->irq);
@@ -815,6 +822,9 @@ static int ads7846_suspend(struct spi_de
 
 	spin_unlock_irq(&ts->lock);
 
+	if (device_may_wakeup(&ts->spi->dev))
+		enable_irq_wake(ts->spi->irq);
+
 	return 0;
 
 }
@@ -823,6 +833,9 @@ static int ads7846_resume(struct spi_dev
 {
 	struct ads7846 *ts = dev_get_drvdata(&spi->dev);
 
+	if (device_may_wakeup(&ts->spi->dev))
+		disable_irq_wake(ts->spi->irq);
+
 	spin_lock_irq(&ts->lock);
 
 	ts->is_suspended = 0;
@@ -978,6 +991,15 @@ static int __devinit ads7846_probe(struc
 
 	vref = pdata->keep_vref_on;
 
+	if (ts->model == 7873) {
+		/* The AD7873 is almost identical to the ADS7846
+		 * keep VREF off during differential/ratiometric
+		 * conversion modes
+		 */
+		ts->model = 7846;
+		vref = 0;
+	}
+
 	/* set up the transfers to read touchscreen state; this assumes we
 	 * use formula #2 for pressure, not #3.
 	 */
@@ -1139,6 +1161,19 @@ static int __devinit ads7846_probe(struc
 
 	ts->last_msg = m;
 
+	ts->reg = regulator_get(&spi->dev, "vcc");
+	if (IS_ERR(ts->reg)) {
+		dev_err(&spi->dev, "unable to get regulator: %ld\n",
+			PTR_ERR(ts->reg));
+		goto err_free_gpio;
+	}
+
+	err = regulator_enable(ts->reg);
+	if (err) {
+		dev_err(&spi->dev, "unable to enable regulator: %d\n", err);
+		goto err_put_regulator;
+	}
+
 	if (request_irq(spi->irq, ads7846_irq, IRQF_TRIGGER_FALLING,
 			spi->dev.driver->name, ts)) {
 		dev_info(&spi->dev,
@@ -1148,7 +1183,7 @@ static int __devinit ads7846_probe(struc
 				  spi->dev.driver->name, ts);
 		if (err) {
 			dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
-			goto err_free_gpio;
+			goto err_disable_regulator;
 		}
 	}
 
@@ -1172,6 +1207,8 @@ static int __devinit ads7846_probe(struc
 	if (err)
 		goto err_remove_attr_group;
 
+	device_init_wakeup(&spi->dev, pdata->wakeup);
+
 	return 0;
 
  err_remove_attr_group:
@@ -1180,6 +1217,10 @@ static int __devinit ads7846_probe(struc
 	ads784x_hwmon_unregister(spi, ts);
  err_free_irq:
 	free_irq(spi->irq, ts);
+ err_disable_regulator:
+	regulator_disable(ts->reg);
+ err_put_regulator:
+	regulator_put(ts->reg);
  err_free_gpio:
 	if (ts->gpio_pendown != -1)
 		gpio_free(ts->gpio_pendown);
@@ -1197,6 +1238,8 @@ static int __devexit ads7846_remove(stru
 {
 	struct ads7846		*ts = dev_get_drvdata(&spi->dev);
 
+	device_init_wakeup(&spi->dev, false);
+
 	ads784x_hwmon_unregister(spi, ts);
 	input_unregister_device(ts->input);
 
@@ -1208,6 +1251,9 @@ static int __devexit ads7846_remove(stru
 	/* suspend left the IRQ disabled */
 	enable_irq(ts->spi->irq);
 
+	regulator_disable(ts->reg);
+	regulator_put(ts->reg);
+
 	if (ts->gpio_pendown != -1)
 		gpio_free(ts->gpio_pendown);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/atmel-wm97xx.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/atmel-wm97xx.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/atmel-wm97xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/atmel-wm97xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/timer.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #define AC97C_ICA		0x10
 #define AC97C_CBRHR		0x30
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/da9034-ts.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/da9034-ts.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/da9034-ts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/da9034-ts.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/input.h>
 #include <linux/workqueue.h>
 #include <linux/mfd/da903x.h>
+#include <linux/slab.h>
 
 #define DA9034_MANUAL_CTRL	0x50
 #define DA9034_LDO_ADC_EN	(1 << 4)
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/eeti_ts.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/eeti_ts.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/eeti_ts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/eeti_ts.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/timer.h>
 #include <linux/gpio.h>
 #include <linux/input/eeti_ts.h>
+#include <linux/slab.h>
 
 static int flip_x;
 module_param(flip_x, bool, 0644);
@@ -123,14 +124,25 @@ static irqreturn_t eeti_ts_isr(int irq,
 	return IRQ_HANDLED;
 }
 
-static int eeti_ts_open(struct input_dev *dev)
+static void eeti_ts_start(struct eeti_ts_priv *priv)
 {
-	struct eeti_ts_priv *priv = input_get_drvdata(dev);
-
 	enable_irq(priv->irq);
 
 	/* Read the events once to arm the IRQ */
 	eeti_ts_read(&priv->work);
+}
+
+static void eeti_ts_stop(struct eeti_ts_priv *priv)
+{
+	disable_irq(priv->irq);
+	cancel_work_sync(&priv->work);
+}
+
+static int eeti_ts_open(struct input_dev *dev)
+{
+	struct eeti_ts_priv *priv = input_get_drvdata(dev);
+
+	eeti_ts_start(priv);
 
 	return 0;
 }
@@ -139,8 +151,7 @@ static void eeti_ts_close(struct input_d
 {
 	struct eeti_ts_priv *priv = input_get_drvdata(dev);
 
-	disable_irq(priv->irq);
-	cancel_work_sync(&priv->work);
+	eeti_ts_stop(priv);
 }
 
 static int __devinit eeti_ts_probe(struct i2c_client *client,
@@ -152,10 +163,12 @@ static int __devinit eeti_ts_probe(struc
 	unsigned int irq_flags;
 	int err = -ENOMEM;
 
-	/* In contrast to what's described in the datasheet, there seems
+	/*
+	 * In contrast to what's described in the datasheet, there seems
 	 * to be no way of probing the presence of that device using I2C
 	 * commands. So we need to blindly believe it is there, and wait
-	 * for interrupts to occur. */
+	 * for interrupts to occur.
+	 */
 
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv) {
@@ -211,9 +224,11 @@ static int __devinit eeti_ts_probe(struc
 		goto err2;
 	}
 
-	/* Disable the irq for now. It will be enabled once the input device
-	 * is opened. */
-	disable_irq(priv->irq);
+	/*
+	 * Disable the device for now. It will be enabled once the
+	 * input device is opened.
+	 */
+	eeti_ts_stop(priv);
 
 	device_init_wakeup(&client->dev, 0);
 	return 0;
@@ -234,6 +249,12 @@ static int __devexit eeti_ts_remove(stru
 	struct eeti_ts_priv *priv = i2c_get_clientdata(client);
 
 	free_irq(priv->irq, priv);
+	/*
+	 * eeti_ts_stop() leaves IRQ disabled. We need to re-enable it
+	 * so that device still works if we reload the driver.
+	 */
+	enable_irq(priv->irq);
+
 	input_unregister_device(priv->input);
 	i2c_set_clientdata(client, NULL);
 	kfree(priv);
@@ -245,6 +266,14 @@ static int __devexit eeti_ts_remove(stru
 static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg)
 {
 	struct eeti_ts_priv *priv = i2c_get_clientdata(client);
+	struct input_dev *input_dev = priv->input;
+
+	mutex_lock(&input_dev->mutex);
+
+	if (input_dev->users)
+		eeti_ts_stop(priv);
+
+	mutex_unlock(&input_dev->mutex);
 
 	if (device_may_wakeup(&client->dev))
 		enable_irq_wake(priv->irq);
@@ -255,10 +284,18 @@ static int eeti_ts_suspend(struct i2c_cl
 static int eeti_ts_resume(struct i2c_client *client)
 {
 	struct eeti_ts_priv *priv = i2c_get_clientdata(client);
+	struct input_dev *input_dev = priv->input;
 
 	if (device_may_wakeup(&client->dev))
 		disable_irq_wake(priv->irq);
 
+	mutex_lock(&input_dev->mutex);
+
+	if (input_dev->users)
+		eeti_ts_start(priv);
+
+	mutex_unlock(&input_dev->mutex);
+
 	return 0;
 }
 #else
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/elo.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/elo.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/elo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/elo.c	2010-05-16 17:17:36.000000000 -0400
@@ -72,45 +72,49 @@ static void elo_process_data_10(struct e
 	struct input_dev *dev = elo->dev;
 
 	elo->data[elo->idx] = data;
-	switch (elo->idx++) {
-		case 0:
-			elo->csum = 0xaa;
-			if (data != ELO10_LEAD_BYTE) {
-				pr_debug("elo: unsynchronized data: 0x%02x\n", data);
-				elo->idx = 0;
-			}
-			break;
 
-		case 9:
+	switch (elo->idx++) {
+	case 0:
+		elo->csum = 0xaa;
+		if (data != ELO10_LEAD_BYTE) {
+			dev_dbg(&elo->serio->dev,
+				"unsynchronized data: 0x%02x\n", data);
 			elo->idx = 0;
-			if (data != elo->csum) {
-				pr_debug("elo: bad checksum: 0x%02x, expected 0x%02x\n",
-					 data, elo->csum);
-				break;
-			}
-			if (elo->data[1] != elo->expected_packet) {
-				if (elo->data[1] != ELO10_TOUCH_PACKET)
-					pr_debug("elo: unexpected packet: 0x%02x\n",
-						 elo->data[1]);
-				break;
-			}
-			if (likely(elo->data[1] == ELO10_TOUCH_PACKET)) {
-				input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]);
-				input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]);
-				if (elo->data[2] & ELO10_PRESSURE)
-					input_report_abs(dev, ABS_PRESSURE,
-							(elo->data[8] << 8) | elo->data[7]);
-				input_report_key(dev, BTN_TOUCH, elo->data[2] & ELO10_TOUCH);
-				input_sync(dev);
-			} else if (elo->data[1] == ELO10_ACK_PACKET) {
-				if (elo->data[2] == '0')
-					elo->expected_packet = ELO10_TOUCH_PACKET;
-				complete(&elo->cmd_done);
-			} else {
-				memcpy(elo->response, &elo->data[1], ELO10_PACKET_LEN);
-				elo->expected_packet = ELO10_ACK_PACKET;
-			}
+		}
+		break;
+
+	case 9:
+		elo->idx = 0;
+		if (data != elo->csum) {
+			dev_dbg(&elo->serio->dev,
+				"bad checksum: 0x%02x, expected 0x%02x\n",
+				 data, elo->csum);
 			break;
+		}
+		if (elo->data[1] != elo->expected_packet) {
+			if (elo->data[1] != ELO10_TOUCH_PACKET)
+				dev_dbg(&elo->serio->dev,
+					"unexpected packet: 0x%02x\n",
+					 elo->data[1]);
+			break;
+		}
+		if (likely(elo->data[1] == ELO10_TOUCH_PACKET)) {
+			input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]);
+			input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]);
+			if (elo->data[2] & ELO10_PRESSURE)
+				input_report_abs(dev, ABS_PRESSURE,
+						(elo->data[8] << 8) | elo->data[7]);
+			input_report_key(dev, BTN_TOUCH, elo->data[2] & ELO10_TOUCH);
+			input_sync(dev);
+		} else if (elo->data[1] == ELO10_ACK_PACKET) {
+			if (elo->data[2] == '0')
+				elo->expected_packet = ELO10_TOUCH_PACKET;
+			complete(&elo->cmd_done);
+		} else {
+			memcpy(elo->response, &elo->data[1], ELO10_PACKET_LEN);
+			elo->expected_packet = ELO10_ACK_PACKET;
+		}
+		break;
 	}
 	elo->csum += data;
 }
@@ -123,42 +127,53 @@ static void elo_process_data_6(struct el
 
 	switch (elo->idx++) {
 
-		case 0: if ((data & 0xc0) != 0xc0) elo->idx = 0; break;
-		case 1: if ((data & 0xc0) != 0x80) elo->idx = 0; break;
-		case 2: if ((data & 0xc0) != 0x40) elo->idx = 0; break;
-
-		case 3:
-			if (data & 0xc0) {
-				elo->idx = 0;
-				break;
-			}
+	case 0:
+		if ((data & 0xc0) != 0xc0)
+			elo->idx = 0;
+		break;
 
-			input_report_abs(dev, ABS_X, ((elo->data[0] & 0x3f) << 6) | (elo->data[1] & 0x3f));
-			input_report_abs(dev, ABS_Y, ((elo->data[2] & 0x3f) << 6) | (elo->data[3] & 0x3f));
+	case 1:
+		if ((data & 0xc0) != 0x80)
+			elo->idx = 0;
+		break;
 
-			if (elo->id == 2) {
-				input_report_key(dev, BTN_TOUCH, 1);
-				input_sync(dev);
-				elo->idx = 0;
-			}
+	case 2:
+		if ((data & 0xc0) != 0x40)
+			elo->idx = 0;
+		break;
 
+	case 3:
+		if (data & 0xc0) {
+			elo->idx = 0;
 			break;
+		}
 
-		case 4:
-			if (data) {
-				input_sync(dev);
-				elo->idx = 0;
-			}
-			break;
+		input_report_abs(dev, ABS_X, ((elo->data[0] & 0x3f) << 6) | (elo->data[1] & 0x3f));
+		input_report_abs(dev, ABS_Y, ((elo->data[2] & 0x3f) << 6) | (elo->data[3] & 0x3f));
 
-		case 5:
-			if ((data & 0xf0) == 0) {
-				input_report_abs(dev, ABS_PRESSURE, elo->data[5]);
-				input_report_key(dev, BTN_TOUCH, !!elo->data[5]);
-			}
+		if (elo->id == 2) {
+			input_report_key(dev, BTN_TOUCH, 1);
 			input_sync(dev);
 			elo->idx = 0;
-			break;
+		}
+
+		break;
+
+	case 4:
+		if (data) {
+			input_sync(dev);
+			elo->idx = 0;
+		}
+		break;
+
+	case 5:
+		if ((data & 0xf0) == 0) {
+			input_report_abs(dev, ABS_PRESSURE, elo->data[5]);
+			input_report_key(dev, BTN_TOUCH, !!elo->data[5]);
+		}
+		input_sync(dev);
+		elo->idx = 0;
+		break;
 	}
 }
 
@@ -170,17 +185,17 @@ static void elo_process_data_3(struct el
 
 	switch (elo->idx++) {
 
-		case 0:
-			if ((data & 0x7f) != 0x01)
-				elo->idx = 0;
-			break;
-		case 2:
-			input_report_key(dev, BTN_TOUCH, !(elo->data[1] & 0x80));
-			input_report_abs(dev, ABS_X, elo->data[1]);
-			input_report_abs(dev, ABS_Y, elo->data[2]);
-			input_sync(dev);
+	case 0:
+		if ((data & 0x7f) != 0x01)
 			elo->idx = 0;
-			break;
+		break;
+	case 2:
+		input_report_key(dev, BTN_TOUCH, !(elo->data[1] & 0x80));
+		input_report_abs(dev, ABS_X, elo->data[1]);
+		input_report_abs(dev, ABS_Y, elo->data[2]);
+		input_sync(dev);
+		elo->idx = 0;
+		break;
 	}
 }
 
@@ -189,19 +204,19 @@ static irqreturn_t elo_interrupt(struct
 {
 	struct elo *elo = serio_get_drvdata(serio);
 
-	switch(elo->id) {
-		case 0:
-			elo_process_data_10(elo, data);
-			break;
+	switch (elo->id) {
+	case 0:
+		elo_process_data_10(elo, data);
+		break;
 
-		case 1:
-		case 2:
-			elo_process_data_6(elo, data);
-			break;
+	case 1:
+	case 2:
+		elo_process_data_6(elo, data);
+		break;
 
-		case 3:
-			elo_process_data_3(elo, data);
-			break;
+	case 3:
+		elo_process_data_3(elo, data);
+		break;
 	}
 
 	return IRQ_HANDLED;
@@ -261,10 +276,10 @@ static int elo_setup_10(struct elo *elo)
 	if (packet[3] & ELO10_PRESSURE)
 		input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
 
-	printk(KERN_INFO "elo: %sTouch touchscreen, fw: %02x.%02x, "
-		"features: 0x%02x, controller: 0x%02x\n",
-		elo_types[(packet[1] -'0') & 0x03],
-		packet[5], packet[4], packet[3], packet[7]);
+	dev_info(&elo->serio->dev,
+		 "%sTouch touchscreen, fw: %02x.%02x, features: 0x%02x, controller: 0x%02x\n",
+		 elo_types[(packet[1] -'0') & 0x03],
+		 packet[5], packet[4], packet[3], packet[7]);
 
 	return 0;
 }
@@ -330,24 +345,24 @@ static int elo_connect(struct serio *ser
 
 	switch (elo->id) {
 
-		case 0: /* 10-byte protocol */
-			if (elo_setup_10(elo))
-				goto fail3;
+	case 0: /* 10-byte protocol */
+		if (elo_setup_10(elo))
+			goto fail3;
 
-			break;
+		break;
 
-		case 1: /* 6-byte protocol */
-			input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0);
+	case 1: /* 6-byte protocol */
+		input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0);
 
-		case 2: /* 4-byte protocol */
-			input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
-			input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
-			break;
+	case 2: /* 4-byte protocol */
+		input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
+		input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
+		break;
 
-		case 3: /* 3-byte protocol */
-			input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0);
-			input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0);
-			break;
+	case 3: /* 3-byte protocol */
+		input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0);
+		input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0);
+		break;
 	}
 
 	err = input_register_device(elo->dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/jornada720_ts.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/jornada720_ts.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/jornada720_ts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/jornada720_ts.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <mach/jornada720.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/Kconfig linux-libre-2.6.34-gnu1/drivers/input/touchscreen/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -11,18 +11,31 @@ menuconfig INPUT_TOUCHSCREEN
 
 if INPUT_TOUCHSCREEN
 
+config TOUCHSCREEN_88PM860X
+	tristate "Marvell 88PM860x touchscreen"
+	depends on MFD_88PM860X
+	help
+	  Say Y here if you have a 88PM860x PMIC and want to enable
+	  support for the built-in touchscreen.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called 88pm860x-ts.
+
 config TOUCHSCREEN_ADS7846
-	tristate "ADS7846/TSC2046 and ADS7843 based touchscreens"
+	tristate "ADS7846/TSC2046/AD7873 and AD(S)7843 based touchscreens"
 	depends on SPI_MASTER
 	depends on HWMON = n || HWMON
 	help
 	  Say Y here if you have a touchscreen interface using the
-	  ADS7846/TSC2046 or ADS7843 controller, and your board-specific
-	  setup code includes that in its table of SPI devices.
+	  ADS7846/TSC2046/AD7873 or ADS7843/AD7843 controller,
+	  and your board-specific setup code includes that in its
+	  table of SPI devices.
 
 	  If HWMON is selected, and the driver is told the reference voltage
 	  on your board, you will also get hwmon interfaces for the voltage
-	  (and on ads7846/tsc2046, temperature) sensors of this chip.
+	  (and on ads7846/tsc2046/ad7873, temperature) sensors of this chip.
 
 	  If unsure, say N (but it's safe to say "Y").
 
@@ -90,7 +103,6 @@ config TOUCHSCREEN_CORGI
 	tristate "SharpSL (Corgi and Spitz series) touchscreen driver (DEPRECATED)"
 	depends on PXA_SHARPSL
 	select CORGI_SSP_DEPRECATED
-	default y
 	help
 	  Say Y here to enable the driver for the touchscreen on the
 	  Sharp SL-C7xx and SL-Cxx00 series of PDAs.
@@ -537,6 +549,11 @@ config TOUCHSCREEN_USB_ETT_TC5UH
 	bool "ET&T TC5UH touchscreen controler support" if EMBEDDED
 	depends on TOUCHSCREEN_USB_COMPOSITE
 
+config TOUCHSCREEN_USB_NEXIO
+	default y
+	bool "NEXIO/iNexio device support" if EMBEDDED
+	depends on TOUCHSCREEN_USB_COMPOSITE
+
 config TOUCHSCREEN_TOUCHIT213
 	tristate "Sahara TouchIT-213 touchscreen"
 	select SERIO
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/mainstone-wm97xx.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/mainstone-wm97xx.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/mainstone-wm97xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/mainstone-wm97xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -153,6 +153,9 @@ static int wm97xx_acc_pen_down(struct wm
 		if (pressure)
 			p = MODR;
 
+		dev_dbg(wm->dev, "Raw coordinates: x=%x, y=%x, p=%x\n",
+			x, y, p);
+
 		/* are samples valid */
 		if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X ||
 		    (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y ||
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/Makefile linux-libre-2.6.34-gnu1/drivers/input/touchscreen/Makefile
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
 
 wm97xx-ts-y := wm97xx-core.o
 
+obj-$(CONFIG_TOUCHSCREEN_88PM860X)	+= 88pm860x-ts.o
 obj-$(CONFIG_TOUCHSCREEN_AD7877)	+= ad7877.o
 obj-$(CONFIG_TOUCHSCREEN_AD7879)	+= ad7879.o
 obj-$(CONFIG_TOUCHSCREEN_ADS7846)	+= ads7846.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/mc13783_ts.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/mc13783_ts.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/mc13783_ts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/mc13783_ts.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/input.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #define MC13783_TS_NAME	"mc13783-ts"
@@ -44,7 +45,7 @@ static irqreturn_t mc13783_ts_handler(in
 {
 	struct mc13783_ts_priv *priv = data;
 
-	mc13783_ackirq(priv->mc13783, irq);
+	mc13783_irq_ack(priv->mc13783, irq);
 
 	/*
 	 * Kick off reading coordinates. Note that if work happens already
@@ -135,7 +136,7 @@ static int mc13783_ts_open(struct input_
 
 	mc13783_lock(priv->mc13783);
 
-	mc13783_ackirq(priv->mc13783, MC13783_IRQ_TS);
+	mc13783_irq_ack(priv->mc13783, MC13783_IRQ_TS);
 
 	ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_TS,
 		mc13783_ts_handler, MC13783_TS_NAME, priv);
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/mcs5000_ts.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/mcs5000_ts.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/mcs5000_ts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/mcs5000_ts.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 
 /* Registers */
 #define MCS5000_TS_STATUS		0x00
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/migor_ts.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/migor_ts.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/migor_ts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/migor_ts.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/i2c.h>
 #include <linux/timer.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/pcap_ts.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/pcap_ts.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/pcap_ts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/pcap_ts.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/pm.h>
 #include <linux/timer.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/s3c2410_ts.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/s3c2410_ts.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/s3c2410_ts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/s3c2410_ts.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/input.h>
 #include <linux/init.h>
@@ -128,27 +127,29 @@ static void touch_timer_fire(unsigned lo
 
 	down = get_down(data0, data1);
 
-	if (ts.count == (1 << ts.shift)) {
-		ts.xp >>= ts.shift;
-		ts.yp >>= ts.shift;
+	if (down) {
+		if (ts.count == (1 << ts.shift)) {
+			ts.xp >>= ts.shift;
+			ts.yp >>= ts.shift;
 
-		dev_dbg(ts.dev, "%s: X=%lu, Y=%lu, count=%d\n",
-			__func__, ts.xp, ts.yp, ts.count);
+			dev_dbg(ts.dev, "%s: X=%lu, Y=%lu, count=%d\n",
+				__func__, ts.xp, ts.yp, ts.count);
 
-		input_report_abs(ts.input, ABS_X, ts.xp);
-		input_report_abs(ts.input, ABS_Y, ts.yp);
+			input_report_abs(ts.input, ABS_X, ts.xp);
+			input_report_abs(ts.input, ABS_Y, ts.yp);
 
-		input_report_key(ts.input, BTN_TOUCH, 1);
-		input_sync(ts.input);
+			input_report_key(ts.input, BTN_TOUCH, 1);
+			input_sync(ts.input);
 
-		ts.xp = 0;
-		ts.yp = 0;
-		ts.count = 0;
-	}
+			ts.xp = 0;
+			ts.yp = 0;
+			ts.count = 0;
+		}
 
-	if (down) {
 		s3c_adc_start(ts.client, 0, 1 << ts.shift);
 	} else {
+		ts.xp = 0;
+		ts.yp = 0;
 		ts.count = 0;
 
 		input_report_key(ts.input, BTN_TOUCH, 0);
@@ -401,6 +402,7 @@ static int s3c2410ts_resume(struct devic
 	struct s3c2410_ts_mach_info *info = pdev->dev.platform_data;
 
 	clk_enable(ts.clock);
+	enable_irq(ts.irq_tc);
 
 	/* Initialise registers */
 	if ((info->delay & 0xffff) > 0)
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/tsc2007.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/tsc2007.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/tsc2007.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/tsc2007.c	2010-05-16 17:17:36.000000000 -0400
@@ -358,7 +358,7 @@ static int __devexit tsc2007_remove(stru
 	return 0;
 }
 
-static struct i2c_device_id tsc2007_idtable[] = {
+static const struct i2c_device_id tsc2007_idtable[] = {
 	{ "tsc2007", 0 },
 	{ }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/ucb1400_ts.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/ucb1400_ts.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/ucb1400_ts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/ucb1400_ts.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/suspend.h>
-#include <linux/slab.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/ucb1400.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/usbtouchscreen.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/usbtouchscreen.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/usbtouchscreen.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/usbtouchscreen.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
  *  - GoTop Super_Q2/GogoPen/PenPower tablets
  *  - JASTEC USB touch controller/DigiTech DTR-02U
  *  - Zytronic capacitive touchscreen
+ *  - NEXIO/iNexio
  *
  * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch>
  * Copyright (C) by Todd E. Johnson (mtouchusb.c)
@@ -95,6 +96,7 @@ struct usbtouch_device_info {
 
 	int  (*read_data)   (struct usbtouch_usb *usbtouch, unsigned char *pkt);
 	int  (*init)        (struct usbtouch_usb *usbtouch);
+	void (*exit)	    (struct usbtouch_usb *usbtouch);
 };
 
 /* a usbtouch device */
@@ -104,11 +106,12 @@ struct usbtouch_usb {
 	unsigned char *buffer;
 	int buf_len;
 	struct urb *irq;
-	struct usb_device *udev;
+	struct usb_interface *interface;
 	struct input_dev *input;
 	struct usbtouch_device_info *type;
 	char name[128];
 	char phys[64];
+	void *priv;
 
 	int x, y;
 	int touch, press;
@@ -133,6 +136,7 @@ enum {
 	DEVTYPE_E2I,
 	DEVTYPE_ZYTRONIC,
 	DEVTYPE_TC5UH,
+	DEVTYPE_NEXIO,
 };
 
 #define USB_DEVICE_HID_CLASS(vend, prod) \
@@ -144,7 +148,7 @@ enum {
 	.bInterfaceClass = USB_INTERFACE_CLASS_HID, \
 	.bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE
 
-static struct usb_device_id usbtouch_devices[] = {
+static const struct usb_device_id usbtouch_devices[] = {
 #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX
 	/* ignore the HID capable devices, handled by usbhid */
 	{USB_DEVICE_HID_CLASS(0x0eef, 0x0001), .driver_info = DEVTYPE_IGNORE},
@@ -222,6 +226,14 @@ static struct usb_device_id usbtouch_dev
 	{USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC5UH},
 #endif
 
+#ifdef CONFIG_TOUCHSCREEN_USB_NEXIO
+	/* data interface only */
+	{USB_DEVICE_AND_INTERFACE_INFO(0x10f0, 0x2002, 0x0a, 0x00, 0x00),
+		.driver_info = DEVTYPE_NEXIO},
+	{USB_DEVICE_AND_INTERFACE_INFO(0x1870, 0x0001, 0x0a, 0x00, 0x00),
+		.driver_info = DEVTYPE_NEXIO},
+#endif
+
 	{}
 };
 
@@ -234,8 +246,9 @@ static struct usb_device_id usbtouch_dev
 static int e2i_init(struct usbtouch_usb *usbtouch)
 {
 	int ret;
+	struct usb_device *udev = interface_to_usbdev(usbtouch->interface);
 
-	ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0),
+	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 	                      0x01, 0x02, 0x0000, 0x0081,
 	                      NULL, 0, USB_CTRL_SET_TIMEOUT);
 
@@ -344,8 +357,9 @@ static int mtouch_read_data(struct usbto
 static int mtouch_init(struct usbtouch_usb *usbtouch)
 {
 	int ret, i;
+	struct usb_device *udev = interface_to_usbdev(usbtouch->interface);
 
-	ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0),
+	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 	                      MTOUCHUSB_RESET,
 	                      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 	                      1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
@@ -356,7 +370,7 @@ static int mtouch_init(struct usbtouch_u
 	msleep(150);
 
 	for (i = 0; i < 3; i++) {
-		ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0),
+		ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 				      MTOUCHUSB_ASYNC_REPORT,
 				      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 				      1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT);
@@ -489,7 +503,7 @@ static int gunze_read_data(struct usbtou
 
 static int dmc_tsc10_init(struct usbtouch_usb *usbtouch)
 {
-	struct usb_device *dev = usbtouch->udev;
+	struct usb_device *dev = interface_to_usbdev(usbtouch->interface);
 	int ret = -ENOMEM;
 	unsigned char *buf;
 
@@ -690,6 +704,229 @@ static int zytronic_read_data(struct usb
 #endif
 
 /*****************************************************************************
+ * NEXIO Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_NEXIO
+
+#define NEXIO_TIMEOUT	5000
+#define NEXIO_BUFSIZE	1024
+#define NEXIO_THRESHOLD	50
+
+struct nexio_priv {
+	struct urb *ack;
+	unsigned char *ack_buf;
+};
+
+struct nexio_touch_packet {
+	u8	flags;		/* 0xe1 = touch, 0xe1 = release */
+	__be16	data_len;	/* total bytes of touch data */
+	__be16	x_len;		/* bytes for X axis */
+	__be16	y_len;		/* bytes for Y axis */
+	u8	data[];
+} __attribute__ ((packed));
+
+static unsigned char nexio_ack_pkt[2] = { 0xaa, 0x02 };
+static unsigned char nexio_init_pkt[4] = { 0x82, 0x04, 0x0a, 0x0f };
+
+static void nexio_ack_complete(struct urb *urb)
+{
+}
+
+static int nexio_init(struct usbtouch_usb *usbtouch)
+{
+	struct usb_device *dev = interface_to_usbdev(usbtouch->interface);
+	struct usb_host_interface *interface = usbtouch->interface->cur_altsetting;
+	struct nexio_priv *priv;
+	int ret = -ENOMEM;
+	int actual_len, i;
+	unsigned char *buf;
+	char *firmware_ver = NULL, *device_name = NULL;
+	int input_ep = 0, output_ep = 0;
+
+	/* find first input and output endpoint */
+	for (i = 0; i < interface->desc.bNumEndpoints; i++) {
+		if (!input_ep &&
+		    usb_endpoint_dir_in(&interface->endpoint[i].desc))
+			input_ep = interface->endpoint[i].desc.bEndpointAddress;
+		if (!output_ep &&
+		    usb_endpoint_dir_out(&interface->endpoint[i].desc))
+			output_ep = interface->endpoint[i].desc.bEndpointAddress;
+	}
+	if (!input_ep || !output_ep)
+		return -ENXIO;
+
+	buf = kmalloc(NEXIO_BUFSIZE, GFP_KERNEL);
+	if (!buf)
+		goto out_buf;
+
+	/* two empty reads */
+	for (i = 0; i < 2; i++) {
+		ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, input_ep),
+				   buf, NEXIO_BUFSIZE, &actual_len,
+				   NEXIO_TIMEOUT);
+		if (ret < 0)
+			goto out_buf;
+	}
+
+	/* send init command */
+	memcpy(buf, nexio_init_pkt, sizeof(nexio_init_pkt));
+	ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, output_ep),
+			   buf, sizeof(nexio_init_pkt), &actual_len,
+			   NEXIO_TIMEOUT);
+	if (ret < 0)
+		goto out_buf;
+
+	/* read replies */
+	for (i = 0; i < 3; i++) {
+		memset(buf, 0, NEXIO_BUFSIZE);
+		ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, input_ep),
+				   buf, NEXIO_BUFSIZE, &actual_len,
+				   NEXIO_TIMEOUT);
+		if (ret < 0 || actual_len < 1 || buf[1] != actual_len)
+			continue;
+		switch (buf[0]) {
+		case 0x83:	/* firmware version */
+			if (!firmware_ver)
+				firmware_ver = kstrdup(&buf[2], GFP_KERNEL);
+			break;
+		case 0x84:	/* device name */
+			if (!device_name)
+				device_name = kstrdup(&buf[2], GFP_KERNEL);
+			break;
+		}
+	}
+
+	printk(KERN_INFO "Nexio device: %s, firmware version: %s\n",
+	       device_name, firmware_ver);
+
+	kfree(firmware_ver);
+	kfree(device_name);
+
+	/* prepare ACK URB */
+	ret = -ENOMEM;
+
+	usbtouch->priv = kmalloc(sizeof(struct nexio_priv), GFP_KERNEL);
+	if (!usbtouch->priv)
+		goto out_buf;
+
+	priv = usbtouch->priv;
+
+	priv->ack_buf = kmalloc(sizeof(nexio_ack_pkt), GFP_KERNEL);
+	if (!priv->ack_buf)
+		goto err_priv;
+
+	memcpy(priv->ack_buf, nexio_ack_pkt, sizeof(nexio_ack_pkt));
+
+	priv->ack = usb_alloc_urb(0, GFP_KERNEL);
+	if (!priv->ack) {
+		dbg("%s - usb_alloc_urb failed: usbtouch->ack", __func__);
+		goto err_ack_buf;
+	}
+
+	usb_fill_bulk_urb(priv->ack, dev, usb_sndbulkpipe(dev, output_ep),
+			  priv->ack_buf, sizeof(nexio_ack_pkt),
+			  nexio_ack_complete, usbtouch);
+	ret = 0;
+	goto out_buf;
+
+err_ack_buf:
+	kfree(priv->ack_buf);
+err_priv:
+	kfree(priv);
+out_buf:
+	kfree(buf);
+	return ret;
+}
+
+static void nexio_exit(struct usbtouch_usb *usbtouch)
+{
+	struct nexio_priv *priv = usbtouch->priv;
+
+	usb_kill_urb(priv->ack);
+	usb_free_urb(priv->ack);
+	kfree(priv->ack_buf);
+	kfree(priv);
+}
+
+static int nexio_read_data(struct usbtouch_usb *usbtouch, unsigned char *pkt)
+{
+	int x, y, begin_x, begin_y, end_x, end_y, w, h, ret;
+	struct nexio_touch_packet *packet = (void *) pkt;
+	struct nexio_priv *priv = usbtouch->priv;
+
+	/* got touch data? */
+	if ((pkt[0] & 0xe0) != 0xe0)
+		return 0;
+
+	/* send ACK */
+	ret = usb_submit_urb(priv->ack, GFP_ATOMIC);
+
+	if (!usbtouch->type->max_xc) {
+		usbtouch->type->max_xc = 2 * be16_to_cpu(packet->x_len);
+		input_set_abs_params(usbtouch->input, ABS_X, 0,
+				     2 * be16_to_cpu(packet->x_len), 0, 0);
+		usbtouch->type->max_yc = 2 * be16_to_cpu(packet->y_len);
+		input_set_abs_params(usbtouch->input, ABS_Y, 0,
+				     2 * be16_to_cpu(packet->y_len), 0, 0);
+	}
+	/*
+	 * The device reports state of IR sensors on X and Y axes.
+	 * Each byte represents "darkness" percentage (0-100) of one element.
+	 * 17" touchscreen reports only 64 x 52 bytes so the resolution is low.
+	 * This also means that there's a limited multi-touch capability but
+	 * it's disabled (and untested) here as there's no X driver for that.
+	 */
+	begin_x = end_x = begin_y = end_y = -1;
+	for (x = 0; x < be16_to_cpu(packet->x_len); x++) {
+		if (begin_x == -1 && packet->data[x] > NEXIO_THRESHOLD) {
+			begin_x = x;
+			continue;
+		}
+		if (end_x == -1 && begin_x != -1 && packet->data[x] < NEXIO_THRESHOLD) {
+			end_x = x - 1;
+			for (y = be16_to_cpu(packet->x_len);
+			     y < be16_to_cpu(packet->data_len); y++) {
+				if (begin_y == -1 && packet->data[y] > NEXIO_THRESHOLD) {
+					begin_y = y - be16_to_cpu(packet->x_len);
+					continue;
+				}
+				if (end_y == -1 &&
+				    begin_y != -1 && packet->data[y] < NEXIO_THRESHOLD) {
+					end_y = y - 1 - be16_to_cpu(packet->x_len);
+					w = end_x - begin_x;
+					h = end_y - begin_y;
+#if 0
+					/* multi-touch */
+					input_report_abs(usbtouch->input,
+						    ABS_MT_TOUCH_MAJOR, max(w,h));
+					input_report_abs(usbtouch->input,
+						    ABS_MT_TOUCH_MINOR, min(x,h));
+					input_report_abs(usbtouch->input,
+						    ABS_MT_POSITION_X, 2*begin_x+w);
+					input_report_abs(usbtouch->input,
+						    ABS_MT_POSITION_Y, 2*begin_y+h);
+					input_report_abs(usbtouch->input,
+						    ABS_MT_ORIENTATION, w > h);
+					input_mt_sync(usbtouch->input);
+#endif
+					/* single touch */
+					usbtouch->x = 2 * begin_x + w;
+					usbtouch->y = 2 * begin_y + h;
+					usbtouch->touch = packet->flags & 0x01;
+					begin_y = end_y = -1;
+					return 1;
+				}
+			}
+			begin_x = end_x = -1;
+		}
+
+	}
+	return 0;
+}
+#endif
+
+
+/*****************************************************************************
  * the different device descriptors
  */
 #ifdef MULTI_PACKET
@@ -873,6 +1110,16 @@ static struct usbtouch_device_info usbto
 		.read_data	= tc5uh_read_data,
 	},
 #endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_NEXIO
+	[DEVTYPE_NEXIO] = {
+		.rept_size	= 128,
+		.irq_always	= true,
+		.read_data	= nexio_read_data,
+		.init		= nexio_init,
+		.exit		= nexio_exit,
+	},
+#endif
 };
 
 
@@ -998,6 +1245,7 @@ static void usbtouch_irq(struct urb *urb
 	case -ECONNRESET:
 	case -ENOENT:
 	case -ESHUTDOWN:
+	case -EPIPE:
 		/* this urb is terminated, clean up */
 		dbg("%s - urb shutting down with status: %d",
 		    __func__, urb->status);
@@ -1021,7 +1269,7 @@ static int usbtouch_open(struct input_de
 {
 	struct usbtouch_usb *usbtouch = input_get_drvdata(input);
 
-	usbtouch->irq->dev = usbtouch->udev;
+	usbtouch->irq->dev = interface_to_usbdev(usbtouch->interface);
 
 	if (!usbtouch->type->irq_always) {
 		if (usb_submit_urb(usbtouch->irq, GFP_KERNEL))
@@ -1048,13 +1296,23 @@ static void usbtouch_free_buffers(struct
 	kfree(usbtouch->buffer);
 }
 
+static struct usb_endpoint_descriptor *
+usbtouch_get_input_endpoint(struct usb_host_interface *interface)
+{
+	int i;
+
+	for (i = 0; i < interface->desc.bNumEndpoints; i++)
+		if (usb_endpoint_dir_in(&interface->endpoint[i].desc))
+			return &interface->endpoint[i].desc;
+
+	return NULL;
+}
 
 static int usbtouch_probe(struct usb_interface *intf,
 			  const struct usb_device_id *id)
 {
 	struct usbtouch_usb *usbtouch;
 	struct input_dev *input_dev;
-	struct usb_host_interface *interface;
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_device *udev = interface_to_usbdev(intf);
 	struct usbtouch_device_info *type;
@@ -1064,8 +1322,9 @@ static int usbtouch_probe(struct usb_int
 	if (id->driver_info == DEVTYPE_IGNORE)
 		return -ENODEV;
 
-	interface = intf->cur_altsetting;
-	endpoint = &interface->endpoint[0].desc;
+	endpoint = usbtouch_get_input_endpoint(intf->cur_altsetting);
+	if (!endpoint)
+		return -ENXIO;
 
 	usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL);
 	input_dev = input_allocate_device();
@@ -1094,7 +1353,7 @@ static int usbtouch_probe(struct usb_int
 		goto out_free_buffers;
 	}
 
-	usbtouch->udev = udev;
+	usbtouch->interface = intf;
 	usbtouch->input = input_dev;
 
 	if (udev->manufacturer)
@@ -1133,12 +1392,18 @@ static int usbtouch_probe(struct usb_int
 		input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press,
 		                     type->max_press, 0, 0);
 
-	usb_fill_int_urb(usbtouch->irq, usbtouch->udev,
-			 usb_rcvintpipe(usbtouch->udev, endpoint->bEndpointAddress),
+	if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT)
+		usb_fill_int_urb(usbtouch->irq, udev,
+			 usb_rcvintpipe(udev, endpoint->bEndpointAddress),
 			 usbtouch->data, type->rept_size,
 			 usbtouch_irq, usbtouch, endpoint->bInterval);
+	else
+		usb_fill_bulk_urb(usbtouch->irq, udev,
+			 usb_rcvbulkpipe(udev, endpoint->bEndpointAddress),
+			 usbtouch->data, type->rept_size,
+			 usbtouch_irq, usbtouch);
 
-	usbtouch->irq->dev = usbtouch->udev;
+	usbtouch->irq->dev = udev;
 	usbtouch->irq->transfer_dma = usbtouch->data_dma;
 	usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
@@ -1147,23 +1412,37 @@ static int usbtouch_probe(struct usb_int
 		err = type->init(usbtouch);
 		if (err) {
 			dbg("%s - type->init() failed, err: %d", __func__, err);
-			goto out_free_buffers;
+			goto out_free_urb;
 		}
 	}
 
 	err = input_register_device(usbtouch->input);
 	if (err) {
 		dbg("%s - input_register_device failed, err: %d", __func__, err);
-		goto out_free_buffers;
+		goto out_do_exit;
 	}
 
 	usb_set_intfdata(intf, usbtouch);
 
-	if (usbtouch->type->irq_always)
-		usb_submit_urb(usbtouch->irq, GFP_KERNEL);
+	if (usbtouch->type->irq_always) {
+		err = usb_submit_urb(usbtouch->irq, GFP_KERNEL);
+		if (err) {
+			err("%s - usb_submit_urb failed with result: %d",
+			    __func__, err);
+			goto out_unregister_input;
+		}
+	}
 
 	return 0;
 
+out_unregister_input:
+	input_unregister_device(input_dev);
+	input_dev = NULL;
+out_do_exit:
+	if (type->exit)
+		type->exit(usbtouch);
+out_free_urb:
+	usb_free_urb(usbtouch->irq);
 out_free_buffers:
 	usbtouch_free_buffers(udev, usbtouch);
 out_free:
@@ -1186,6 +1465,8 @@ static void usbtouch_disconnect(struct u
 	/* this will stop IO via close */
 	input_unregister_device(usbtouch->input);
 	usb_free_urb(usbtouch->irq);
+	if (usbtouch->type->exit)
+		usbtouch->type->exit(usbtouch);
 	usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch);
 	kfree(usbtouch);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/w90p910_ts.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/w90p910_ts.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/w90p910_ts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/w90p910_ts.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/clk.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 /* ADC controller bit defines */
 #define ADC_DELAY	0xf00
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/wm97xx-core.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/wm97xx-core.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/wm97xx-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/wm97xx-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,6 +48,7 @@
 #include <linux/wm97xx.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #define TS_NAME			"wm97xx"
 #define WM_CORE_VERSION		"1.00"
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/touchscreen/zylonite-wm97xx.c linux-libre-2.6.34-gnu1/drivers/input/touchscreen/zylonite-wm97xx.c
--- linux-libre-2.6.33-gnu1/drivers/input/touchscreen/zylonite-wm97xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/touchscreen/zylonite-wm97xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -118,6 +118,9 @@ static int wm97xx_acc_pen_down(struct wm
 		if (pressure)
 			p = MODR;
 
+		dev_dbg(wm->dev, "Raw coordinates: x=%x, y=%x, p=%x\n",
+			x, y, p);
+
 		/* are samples valid */
 		if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X ||
 		    (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y ||
diff -druNp linux-libre-2.6.33-gnu1/drivers/input/xen-kbdfront.c linux-libre-2.6.34-gnu1/drivers/input/xen-kbdfront.c
--- linux-libre-2.6.33-gnu1/drivers/input/xen-kbdfront.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/input/xen-kbdfront.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 
 #include <asm/xen/hypervisor.h>
 
@@ -321,7 +322,7 @@ InitWait:
 	}
 }
 
-static struct xenbus_device_id xenkbd_ids[] = {
+static const struct xenbus_device_id xenkbd_ids[] = {
 	{ "vkbd" },
 	{ "" }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/act2000/module.c linux-libre-2.6.34-gnu1/drivers/isdn/act2000/module.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/act2000/module.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/act2000/module.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include "act2000_isa.h"
 #include "capi.h"
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 static unsigned short act2000_isa_ports[] =
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/capi/capi.c linux-libre-2.6.34-gnu1/drivers/isdn/capi/capi.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/capi/capi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/capi/capi.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,16 +23,13 @@
 #include <linux/smp_lock.h>
 #include <linux/timer.h>
 #include <linux/wait.h>
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 #include <linux/tty.h>
-#ifdef CONFIG_PPP
 #include <linux/netdevice.h>
 #include <linux/ppp_defs.h>
 #include <linux/if_ppp.h>
-#endif /* CONFIG_PPP */
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 #include <linux/skbuff.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/poll.h>
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
@@ -41,35 +38,29 @@
 #include <linux/moduleparam.h>
 #include <linux/isdn/capiutil.h>
 #include <linux/isdn/capicmd.h>
-#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
-#include "capifs.h"
-#endif
 
-static char *revision = "$Revision: 1.1.2.7 $";
+#include "capifs.h"
 
 MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface");
 MODULE_AUTHOR("Carsten Paeth");
 MODULE_LICENSE("GPL");
 
-#undef _DEBUG_REFCOUNT		/* alloc/free and open/close debug */
 #undef _DEBUG_TTYFUNCS		/* call to tty_driver */
 #undef _DEBUG_DATAFLOW		/* data flow */
 
 /* -------- driver information -------------------------------------- */
 
 static struct class *capi_class;
-
 static int capi_major = 68;		/* allocated */
+
+module_param_named(major, capi_major, uint, 0);
+
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-#define CAPINC_NR_PORTS	32
+#define CAPINC_NR_PORTS		32
 #define CAPINC_MAX_PORTS	256
-static int capi_ttymajor = 191;
+
 static int capi_ttyminors = CAPINC_NR_PORTS;
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 
-module_param_named(major, capi_major, uint, 0);
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-module_param_named(ttymajor, capi_ttymajor, uint, 0);
 module_param_named(ttyminors, capi_ttyminors, uint, 0);
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 
@@ -83,53 +74,43 @@ module_param_named(ttyminors, capi_ttymi
 
 struct capidev;
 struct capincci;
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 struct capiminor;
 
-struct datahandle_queue {
+struct ackqueue_entry {
 	struct list_head	list;
 	u16			datahandle;
 };
 
 struct capiminor {
-	struct list_head list;
-	struct capincci  *nccip;
+	struct kref kref;
+
 	unsigned int      minor;
+	struct dentry *capifs_dentry;
 
-	struct capi20_appl *ap;
-	u32		 ncci;
-	u16		 datahandle;
-	u16		 msgid;
+	struct capi20_appl	*ap;
+	u32			ncci;
+	atomic_t		datahandle;
+	atomic_t		msgid;
 
-	struct tty_struct *tty;
+	struct tty_port port;
 	int                ttyinstop;
 	int                ttyoutstop;
-	struct sk_buff    *ttyskb;
-	atomic_t           ttyopencount;
 
-	struct sk_buff_head inqueue;
-	int                 inbytes;
-	struct sk_buff_head outqueue;
-	int                 outbytes;
+	struct sk_buff_head	inqueue;
+
+	struct sk_buff_head	outqueue;
+	int			outbytes;
+	struct sk_buff		*outskb;
+	spinlock_t		outlock;
 
 	/* transmit path */
 	struct list_head ackqueue;
 	int nack;
 	spinlock_t ackqlock;
 };
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
-
-/* FIXME: The following lock is a sledgehammer-workaround to a
- * locking issue with the capiminor (and maybe other) data structure(s).
- * Access to this data is done in a racy way and crashes the machine with
- * a FritzCard DSL driver; sooner or later. This is a workaround
- * which trades scalability vs stability, so it doesn't crash the kernel anymore.
- * The correct (and scalable) fix for the issue seems to require
- * an API change to the drivers... . */
-static DEFINE_SPINLOCK(workaround_lock);
 
 struct capincci {
-	struct capincci *next;
+	struct list_head list;
 	u32		 ncci;
 	struct capidev	*cdev;
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -146,28 +127,28 @@ struct capidev {
 	struct sk_buff_head recvqueue;
 	wait_queue_head_t recvwait;
 
-	struct capincci *nccis;
+	struct list_head nccis;
 
-	struct mutex ncci_list_mtx;
+	struct mutex lock;
 };
 
 /* -------- global variables ---------------------------------------- */
 
-static DEFINE_RWLOCK(capidev_list_lock);
+static DEFINE_MUTEX(capidev_list_lock);
 static LIST_HEAD(capidev_list);
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-static DEFINE_RWLOCK(capiminor_list_lock);
-static LIST_HEAD(capiminor_list);
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
+static DEFINE_SPINLOCK(capiminors_lock);
+static struct capiminor **capiminors;
+
+static struct tty_driver *capinc_tty_driver;
+
 /* -------- datahandles --------------------------------------------- */
 
-static int capincci_add_ack(struct capiminor *mp, u16 datahandle)
+static int capiminor_add_ack(struct capiminor *mp, u16 datahandle)
 {
-	struct datahandle_queue *n;
-	unsigned long flags;
+	struct ackqueue_entry *n;
 
 	n = kmalloc(sizeof(*n), GFP_ATOMIC);
 	if (unlikely(!n)) {
@@ -176,253 +157,246 @@ static int capincci_add_ack(struct capim
 	}
 	n->datahandle = datahandle;
 	INIT_LIST_HEAD(&n->list);
-	spin_lock_irqsave(&mp->ackqlock, flags);
+	spin_lock_bh(&mp->ackqlock);
 	list_add_tail(&n->list, &mp->ackqueue);
 	mp->nack++;
-	spin_unlock_irqrestore(&mp->ackqlock, flags);
+	spin_unlock_bh(&mp->ackqlock);
 	return 0;
 }
 
 static int capiminor_del_ack(struct capiminor *mp, u16 datahandle)
 {
-	struct datahandle_queue *p, *tmp;
-	unsigned long flags;
+	struct ackqueue_entry *p, *tmp;
 
-	spin_lock_irqsave(&mp->ackqlock, flags);
+	spin_lock_bh(&mp->ackqlock);
 	list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
  		if (p->datahandle == datahandle) {
 			list_del(&p->list);
-			kfree(p);
 			mp->nack--;
-			spin_unlock_irqrestore(&mp->ackqlock, flags);
+			spin_unlock_bh(&mp->ackqlock);
+			kfree(p);
 			return 0;
 		}
 	}
-	spin_unlock_irqrestore(&mp->ackqlock, flags);
+	spin_unlock_bh(&mp->ackqlock);
 	return -1;
 }
 
 static void capiminor_del_all_ack(struct capiminor *mp)
 {
-	struct datahandle_queue *p, *tmp;
-	unsigned long flags;
+	struct ackqueue_entry *p, *tmp;
 
-	spin_lock_irqsave(&mp->ackqlock, flags);
 	list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
 		list_del(&p->list);
 		kfree(p);
 		mp->nack--;
 	}
-	spin_unlock_irqrestore(&mp->ackqlock, flags);
 }
 
 
 /* -------- struct capiminor ---------------------------------------- */
 
+static const struct tty_port_operations capiminor_port_ops; /* we have none */
+
 static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
 {
-	struct capiminor *mp, *p;
-	unsigned int minor = 0;
-	unsigned long flags;
+	struct capiminor *mp;
+	struct device *dev;
+	unsigned int minor;
 
-	mp = kzalloc(sizeof(*mp), GFP_ATOMIC);
+	mp = kzalloc(sizeof(*mp), GFP_KERNEL);
   	if (!mp) {
   		printk(KERN_ERR "capi: can't alloc capiminor\n");
 		return NULL;
 	}
 
+	kref_init(&mp->kref);
+
 	mp->ap = ap;
 	mp->ncci = ncci;
-	mp->msgid = 0;
-	atomic_set(&mp->ttyopencount,0);
 	INIT_LIST_HEAD(&mp->ackqueue);
 	spin_lock_init(&mp->ackqlock);
 
 	skb_queue_head_init(&mp->inqueue);
 	skb_queue_head_init(&mp->outqueue);
+	spin_lock_init(&mp->outlock);
 
-	/* Allocate the least unused minor number.
-	 */
-	write_lock_irqsave(&capiminor_list_lock, flags);
-	if (list_empty(&capiminor_list))
-		list_add(&mp->list, &capiminor_list);
-	else {
-		list_for_each_entry(p, &capiminor_list, list) {
-			if (p->minor > minor)
-				break;
-			minor++;
-		}
-		
-		if (minor < capi_ttyminors) {
-			mp->minor = minor;
-			list_add(&mp->list, p->list.prev);
+	tty_port_init(&mp->port);
+	mp->port.ops = &capiminor_port_ops;
+
+	/* Allocate the least unused minor number. */
+	spin_lock(&capiminors_lock);
+	for (minor = 0; minor < capi_ttyminors; minor++)
+		if (!capiminors[minor]) {
+			capiminors[minor] = mp;
+			break;
 		}
-	}
-		write_unlock_irqrestore(&capiminor_list_lock, flags);
+	spin_unlock(&capiminors_lock);
 
-	if (!(minor < capi_ttyminors)) {
+	if (minor == capi_ttyminors) {
 		printk(KERN_NOTICE "capi: out of minors\n");
-			kfree(mp);
-		return NULL;
+		goto err_out1;
 	}
 
+	mp->minor = minor;
+
+	dev = tty_register_device(capinc_tty_driver, minor, NULL);
+	if (IS_ERR(dev))
+		goto err_out2;
+
 	return mp;
+
+err_out2:
+	spin_lock(&capiminors_lock);
+	capiminors[minor] = NULL;
+	spin_unlock(&capiminors_lock);
+
+err_out1:
+	kfree(mp);
+	return NULL;
 }
 
-static void capiminor_free(struct capiminor *mp)
+static void capiminor_destroy(struct kref *kref)
 {
-	unsigned long flags;
-
-	write_lock_irqsave(&capiminor_list_lock, flags);
-	list_del(&mp->list);
-	write_unlock_irqrestore(&capiminor_list_lock, flags);
+	struct capiminor *mp = container_of(kref, struct capiminor, kref);
 
-	kfree_skb(mp->ttyskb);
-	mp->ttyskb = NULL;
+	kfree_skb(mp->outskb);
 	skb_queue_purge(&mp->inqueue);
 	skb_queue_purge(&mp->outqueue);
 	capiminor_del_all_ack(mp);
 	kfree(mp);
 }
 
-static struct capiminor *capiminor_find(unsigned int minor)
+static struct capiminor *capiminor_get(unsigned int minor)
 {
-	struct list_head *l;
-	struct capiminor *p = NULL;
+	struct capiminor *mp;
 
-	read_lock(&capiminor_list_lock);
-	list_for_each(l, &capiminor_list) {
-		p = list_entry(l, struct capiminor, list);
-		if (p->minor == minor)
-			break;
-	}
-	read_unlock(&capiminor_list_lock);
-	if (l == &capiminor_list)
-		return NULL;
+	spin_lock(&capiminors_lock);
+	mp = capiminors[minor];
+	if (mp)
+		kref_get(&mp->kref);
+	spin_unlock(&capiminors_lock);
 
-	return p;
+	return mp;
+}
+
+static inline void capiminor_put(struct capiminor *mp)
+{
+	kref_put(&mp->kref, capiminor_destroy);
+}
+
+static void capiminor_free(struct capiminor *mp)
+{
+	tty_unregister_device(capinc_tty_driver, mp->minor);
+
+	spin_lock(&capiminors_lock);
+	capiminors[mp->minor] = NULL;
+	spin_unlock(&capiminors_lock);
+
+	capiminor_put(mp);
 }
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 
 /* -------- struct capincci ----------------------------------------- */
 
-static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci)
+static void capincci_alloc_minor(struct capidev *cdev, struct capincci *np)
 {
-	struct capincci *np, **pp;
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-	struct capiminor *mp = NULL;
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
+	struct capiminor *mp;
+	dev_t device;
 
-	np = kzalloc(sizeof(*np), GFP_ATOMIC);
-	if (!np)
-		return NULL;
-	np->ncci = ncci;
-	np->cdev = cdev;
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-	mp = NULL;
-	if (cdev->userflags & CAPIFLAG_HIGHJACKING)
-		mp = np->minorp = capiminor_alloc(&cdev->ap, ncci);
+	if (!(cdev->userflags & CAPIFLAG_HIGHJACKING))
+		return;
+
+	mp = np->minorp = capiminor_alloc(&cdev->ap, np->ncci);
 	if (mp) {
-		mp->nccip = np;
-#ifdef _DEBUG_REFCOUNT
-		printk(KERN_DEBUG "set mp->nccip\n");
-#endif
-#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
-		capifs_new_ncci(mp->minor, MKDEV(capi_ttymajor, mp->minor));
-#endif
+		device = MKDEV(capinc_tty_driver->major, mp->minor);
+		mp->capifs_dentry = capifs_new_ncci(mp->minor, device);
 	}
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
-	for (pp=&cdev->nccis; *pp; pp = &(*pp)->next)
-		;
-	*pp = np;
-        return np;
 }
 
-static void capincci_free(struct capidev *cdev, u32 ncci)
+static void capincci_free_minor(struct capincci *np)
 {
-	struct capincci *np, **pp;
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-	struct capiminor *mp;
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
+	struct capiminor *mp = np->minorp;
+	struct tty_struct *tty;
 
-	pp=&cdev->nccis;
-	while (*pp) {
-		np = *pp;
-		if (ncci == 0xffffffff || np->ncci == ncci) {
-			*pp = (*pp)->next;
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-			if ((mp = np->minorp) != NULL) {
-#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
-				capifs_free_ncci(mp->minor);
-#endif
-				if (mp->tty) {
-					mp->nccip = NULL;
-#ifdef _DEBUG_REFCOUNT
-					printk(KERN_DEBUG "reset mp->nccip\n");
-#endif
-					tty_hangup(mp->tty);
-				} else {
-					capiminor_free(mp);
-				}
-			}
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
-			kfree(np);
-			if (*pp == NULL) return;
-		} else {
-			pp = &(*pp)->next;
+	if (mp) {
+		capifs_free_ncci(mp->capifs_dentry);
+
+		tty = tty_port_tty_get(&mp->port);
+		if (tty) {
+			tty_vhangup(tty);
+			tty_kref_put(tty);
 		}
+
+		capiminor_free(mp);
 	}
 }
 
-static struct capincci *capincci_find(struct capidev *cdev, u32 ncci)
+static inline unsigned int capincci_minor_opencount(struct capincci *np)
 {
-	struct capincci *p;
+	struct capiminor *mp = np->minorp;
+	unsigned int count = 0;
+	struct tty_struct *tty;
 
-	for (p=cdev->nccis; p ; p = p->next) {
-		if (p->ncci == ncci)
-			break;
+	if (mp) {
+		tty = tty_port_tty_get(&mp->port);
+		if (tty) {
+			count = tty->count;
+			tty_kref_put(tty);
+		}
 	}
-	return p;
+	return count;
 }
 
-/* -------- struct capidev ------------------------------------------ */
+#else /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
 
-static struct capidev *capidev_alloc(void)
+static inline void
+capincci_alloc_minor(struct capidev *cdev, struct capincci *np) { }
+static inline void capincci_free_minor(struct capincci *np) { }
+
+static inline unsigned int capincci_minor_opencount(struct capincci *np)
 {
-	struct capidev *cdev;
-	unsigned long flags;
+	return 0;
+}
 
-	cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
-	if (!cdev)
+#endif /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
+
+static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci)
+{
+	struct capincci *np;
+
+	np = kzalloc(sizeof(*np), GFP_KERNEL);
+	if (!np)
 		return NULL;
+	np->ncci = ncci;
+	np->cdev = cdev;
 
-	mutex_init(&cdev->ncci_list_mtx);
-	skb_queue_head_init(&cdev->recvqueue);
-	init_waitqueue_head(&cdev->recvwait);
-	write_lock_irqsave(&capidev_list_lock, flags);
-	list_add_tail(&cdev->list, &capidev_list);
-	write_unlock_irqrestore(&capidev_list_lock, flags);
-        return cdev;
+	capincci_alloc_minor(cdev, np);
+
+	list_add_tail(&np->list, &cdev->nccis);
+
+	return np;
 }
 
-static void capidev_free(struct capidev *cdev)
+static void capincci_free(struct capidev *cdev, u32 ncci)
 {
-	unsigned long flags;
+	struct capincci *np, *tmp;
 
-	if (cdev->ap.applid) {
-		capi20_release(&cdev->ap);
-		cdev->ap.applid = 0;
-	}
-	skb_queue_purge(&cdev->recvqueue);
+	list_for_each_entry_safe(np, tmp, &cdev->nccis, list)
+		if (ncci == 0xffffffff || np->ncci == ncci) {
+			capincci_free_minor(np);
+			list_del(&np->list);
+			kfree(np);
+		}
+}
 
-	mutex_lock(&cdev->ncci_list_mtx);
-	capincci_free(cdev, 0xffffffff);
-	mutex_unlock(&cdev->ncci_list_mtx);
+static struct capincci *capincci_find(struct capidev *cdev, u32 ncci)
+{
+	struct capincci *np;
 
-	write_lock_irqsave(&capidev_list_lock, flags);
-	list_del(&cdev->list);
-	write_unlock_irqrestore(&capidev_list_lock, flags);
-	kfree(cdev);
+	list_for_each_entry(np, &cdev->nccis, list)
+		if (np->ncci == ncci)
+			return np;
+	return NULL;
 }
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -432,7 +406,7 @@ static struct sk_buff *
 gen_data_b3_resp_for(struct capiminor *mp, struct sk_buff *skb)
 {
 	struct sk_buff *nskb;
-	nskb = alloc_skb(CAPI_DATA_B3_RESP_LEN, GFP_ATOMIC);
+	nskb = alloc_skb(CAPI_DATA_B3_RESP_LEN, GFP_KERNEL);
 	if (nskb) {
 		u16 datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4+4+2);
 		unsigned char *s = skb_put(nskb, CAPI_DATA_B3_RESP_LEN);
@@ -440,7 +414,7 @@ gen_data_b3_resp_for(struct capiminor *m
 		capimsg_setu16(s, 2, mp->ap->applid);
 		capimsg_setu8 (s, 4, CAPI_DATA_B3);
 		capimsg_setu8 (s, 5, CAPI_RESP);
-		capimsg_setu16(s, 6, mp->msgid++);
+		capimsg_setu16(s, 6, atomic_inc_return(&mp->msgid));
 		capimsg_setu32(s, 8, mp->ncci);
 		capimsg_setu16(s, 12, datahandle);
 	}
@@ -449,122 +423,156 @@ gen_data_b3_resp_for(struct capiminor *m
 
 static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
 {
+	unsigned int datalen = skb->len - CAPIMSG_LEN(skb->data);
+	struct tty_struct *tty;
 	struct sk_buff *nskb;
-	int datalen;
 	u16 errcode, datahandle;
 	struct tty_ldisc *ld;
-	
-	datalen = skb->len - CAPIMSG_LEN(skb->data);
-	if (mp->tty == NULL)
-	{
+	int ret = -1;
+
+	tty = tty_port_tty_get(&mp->port);
+	if (!tty) {
 #ifdef _DEBUG_DATAFLOW
 		printk(KERN_DEBUG "capi: currently no receiver\n");
 #endif
 		return -1;
 	}
 	
-	ld = tty_ldisc_ref(mp->tty);
-	if (ld == NULL)
-		return -1;
+	ld = tty_ldisc_ref(tty);
+	if (!ld) {
+		/* fatal error, do not requeue */
+		ret = 0;
+		kfree_skb(skb);
+		goto deref_tty;
+	}
+
 	if (ld->ops->receive_buf == NULL) {
 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
 		printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n");
 #endif
-		goto bad;
+		/* fatal error, do not requeue */
+		goto free_skb;
 	}
 	if (mp->ttyinstop) {
 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
 		printk(KERN_DEBUG "capi: recv tty throttled\n");
 #endif
-		goto bad;
+		goto deref_ldisc;
 	}
-	if (mp->tty->receive_room < datalen) {
+
+	if (tty->receive_room < datalen) {
 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
 		printk(KERN_DEBUG "capi: no room in tty\n");
 #endif
-		goto bad;
+		goto deref_ldisc;
 	}
-	if ((nskb = gen_data_b3_resp_for(mp, skb)) == NULL) {
+
+	nskb = gen_data_b3_resp_for(mp, skb);
+	if (!nskb) {
 		printk(KERN_ERR "capi: gen_data_b3_resp failed\n");
-		goto bad;
+		goto deref_ldisc;
 	}
-	datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4);
+
+	datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4);
+
 	errcode = capi20_put_message(mp->ap, nskb);
-	if (errcode != CAPI_NOERROR) {
+
+	if (errcode == CAPI_NOERROR) {
+		skb_pull(skb, CAPIMSG_LEN(skb->data));
+#ifdef _DEBUG_DATAFLOW
+		printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
+					datahandle, skb->len);
+#endif
+		ld->ops->receive_buf(tty, skb->data, NULL, skb->len);
+	} else {
 		printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
 				errcode);
 		kfree_skb(nskb);
-		goto bad;
+
+		if (errcode == CAPI_SENDQUEUEFULL)
+			goto deref_ldisc;
 	}
-	(void)skb_pull(skb, CAPIMSG_LEN(skb->data));
-#ifdef _DEBUG_DATAFLOW
-	printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
-				datahandle, skb->len);
-#endif
-	ld->ops->receive_buf(mp->tty, skb->data, NULL, skb->len);
+
+free_skb:
+	ret = 0;
 	kfree_skb(skb);
+
+deref_ldisc:
 	tty_ldisc_deref(ld);
-	return 0;
-bad:
-	tty_ldisc_deref(ld);
-	return -1;
+
+deref_tty:
+	tty_kref_put(tty);
+	return ret;
 }
 
 static void handle_minor_recv(struct capiminor *mp)
 {
 	struct sk_buff *skb;
-	while ((skb = skb_dequeue(&mp->inqueue)) != NULL) {
-		unsigned int len = skb->len;
-		mp->inbytes -= len;
+
+	while ((skb = skb_dequeue(&mp->inqueue)) != NULL)
 		if (handle_recv_skb(mp, skb) < 0) {
 			skb_queue_head(&mp->inqueue, skb);
-			mp->inbytes += len;
 			return;
 		}
-	}
 }
 
-static int handle_minor_send(struct capiminor *mp)
+static void handle_minor_send(struct capiminor *mp)
 {
+	struct tty_struct *tty;
 	struct sk_buff *skb;
 	u16 len;
-	int count = 0;
 	u16 errcode;
 	u16 datahandle;
 
-	if (mp->tty && mp->ttyoutstop) {
+	tty = tty_port_tty_get(&mp->port);
+	if (!tty)
+		return;
+
+	if (mp->ttyoutstop) {
 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
 		printk(KERN_DEBUG "capi: send: tty stopped\n");
 #endif
-		return 0;
+		tty_kref_put(tty);
+		return;
 	}
 
-	while ((skb = skb_dequeue(&mp->outqueue)) != NULL) {
-		datahandle = mp->datahandle;
+	while (1) {
+		spin_lock_bh(&mp->outlock);
+		skb = __skb_dequeue(&mp->outqueue);
+		if (!skb) {
+			spin_unlock_bh(&mp->outlock);
+			break;
+		}
 		len = (u16)skb->len;
+		mp->outbytes -= len;
+		spin_unlock_bh(&mp->outlock);
+
+		datahandle = atomic_inc_return(&mp->datahandle);
 		skb_push(skb, CAPI_DATA_B3_REQ_LEN);
 		memset(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
 		capimsg_setu16(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
 		capimsg_setu16(skb->data, 2, mp->ap->applid);
 		capimsg_setu8 (skb->data, 4, CAPI_DATA_B3);
 		capimsg_setu8 (skb->data, 5, CAPI_REQ);
-		capimsg_setu16(skb->data, 6, mp->msgid++);
+		capimsg_setu16(skb->data, 6, atomic_inc_return(&mp->msgid));
 		capimsg_setu32(skb->data, 8, mp->ncci);	/* NCCI */
 		capimsg_setu32(skb->data, 12, (u32)(long)skb->data);/* Data32 */
 		capimsg_setu16(skb->data, 16, len);	/* Data length */
 		capimsg_setu16(skb->data, 18, datahandle);
 		capimsg_setu16(skb->data, 20, 0);	/* Flags */
 
-		if (capincci_add_ack(mp, datahandle) < 0) {
+		if (capiminor_add_ack(mp, datahandle) < 0) {
 			skb_pull(skb, CAPI_DATA_B3_REQ_LEN);
-			skb_queue_head(&mp->outqueue, skb);
-			return count;
+
+			spin_lock_bh(&mp->outlock);
+			__skb_queue_head(&mp->outqueue, skb);
+			mp->outbytes += len;
+			spin_unlock_bh(&mp->outlock);
+
+			break;
 		}
 		errcode = capi20_put_message(mp->ap, skb);
 		if (errcode == CAPI_NOERROR) {
-			mp->datahandle++;
-			count++;
-			mp->outbytes -= len;
 #ifdef _DEBUG_DATAFLOW
 			printk(KERN_DEBUG "capi: DATA_B3_REQ %u len=%u\n",
 							datahandle, len);
@@ -575,16 +583,20 @@ static int handle_minor_send(struct capi
 
 		if (errcode == CAPI_SENDQUEUEFULL) {
 			skb_pull(skb, CAPI_DATA_B3_REQ_LEN);
-			skb_queue_head(&mp->outqueue, skb);
+
+			spin_lock_bh(&mp->outlock);
+			__skb_queue_head(&mp->outqueue, skb);
+			mp->outbytes += len;
+			spin_unlock_bh(&mp->outlock);
+
 			break;
 		}
 
 		/* ups, drop packet */
 		printk(KERN_ERR "capi: put_message = %x\n", errcode);
-		mp->outbytes -= len;
 		kfree_skb(skb);
 	}
-	return count;
+	tty_kref_put(tty);
 }
 
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
@@ -594,65 +606,56 @@ static void capi_recv_message(struct cap
 {
 	struct capidev *cdev = ap->private;
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
+	struct tty_struct *tty;
 	struct capiminor *mp;
 	u16 datahandle;
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 	struct capincci *np;
-	u32 ncci;
-	unsigned long flags;
+
+	mutex_lock(&cdev->lock);
 
 	if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) {
 		u16 info = CAPIMSG_U16(skb->data, 12); // Info field
-		if ((info & 0xff00) == 0) {
-			mutex_lock(&cdev->ncci_list_mtx);
+		if ((info & 0xff00) == 0)
 			capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
-			mutex_unlock(&cdev->ncci_list_mtx);
-		}
 	}
-	if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND) {
-		mutex_lock(&cdev->ncci_list_mtx);
+	if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND)
 		capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
-		mutex_unlock(&cdev->ncci_list_mtx);
-	}
-	spin_lock_irqsave(&workaround_lock, flags);
+
 	if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) {
 		skb_queue_tail(&cdev->recvqueue, skb);
 		wake_up_interruptible(&cdev->recvwait);
-		spin_unlock_irqrestore(&workaround_lock, flags);
-		return;
+		goto unlock_out;
 	}
-	ncci = CAPIMSG_CONTROL(skb->data);
-	for (np = cdev->nccis; np && np->ncci != ncci; np = np->next)
-		;
+
+	np = capincci_find(cdev, CAPIMSG_CONTROL(skb->data));
 	if (!np) {
 		printk(KERN_ERR "BUG: capi_signal: ncci not found\n");
 		skb_queue_tail(&cdev->recvqueue, skb);
 		wake_up_interruptible(&cdev->recvwait);
-		spin_unlock_irqrestore(&workaround_lock, flags);
-		return;
+		goto unlock_out;
 	}
+
 #ifndef CONFIG_ISDN_CAPI_MIDDLEWARE
 	skb_queue_tail(&cdev->recvqueue, skb);
 	wake_up_interruptible(&cdev->recvwait);
+
 #else /* CONFIG_ISDN_CAPI_MIDDLEWARE */
+
 	mp = np->minorp;
 	if (!mp) {
 		skb_queue_tail(&cdev->recvqueue, skb);
 		wake_up_interruptible(&cdev->recvwait);
-		spin_unlock_irqrestore(&workaround_lock, flags);
-		return;
+		goto unlock_out;
 	}
-
-
 	if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
-		
 		datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2);
 #ifdef _DEBUG_DATAFLOW
 		printk(KERN_DEBUG "capi_signal: DATA_B3_IND %u len=%d\n",
 				datahandle, skb->len-CAPIMSG_LEN(skb->data));
 #endif
 		skb_queue_tail(&mp->inqueue, skb);
-		mp->inbytes += skb->len;
+
 		handle_minor_recv(mp);
 
 	} else if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF) {
@@ -664,10 +667,13 @@ static void capi_recv_message(struct cap
 				CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2));
 #endif
 		kfree_skb(skb);
-		(void)capiminor_del_ack(mp, datahandle);
-		if (mp->tty)
-			tty_wakeup(mp->tty);
-		(void)handle_minor_send(mp);
+		capiminor_del_ack(mp, datahandle);
+		tty = tty_port_tty_get(&mp->port);
+		if (tty) {
+			tty_wakeup(tty);
+			tty_kref_put(tty);
+		}
+		handle_minor_send(mp);
 
 	} else {
 		/* ups, let capi application handle it :-) */
@@ -675,7 +681,9 @@ static void capi_recv_message(struct cap
 		wake_up_interruptible(&cdev->recvwait);
 	}
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
-	spin_unlock_irqrestore(&workaround_lock, flags);
+
+unlock_out:
+	mutex_unlock(&cdev->lock);
 }
 
 /* -------- file_operations for capidev ----------------------------- */
@@ -686,24 +694,19 @@ capi_read(struct file *file, char __user
 	struct capidev *cdev = (struct capidev *)file->private_data;
 	struct sk_buff *skb;
 	size_t copied;
+	int err;
 
 	if (!cdev->ap.applid)
 		return -ENODEV;
 
-	if ((skb = skb_dequeue(&cdev->recvqueue)) == NULL) {
-
+	skb = skb_dequeue(&cdev->recvqueue);
+	if (!skb) {
 		if (file->f_flags & O_NONBLOCK)
 			return -EAGAIN;
-
-		for (;;) {
-			interruptible_sleep_on(&cdev->recvwait);
-			if ((skb = skb_dequeue(&cdev->recvqueue)) != NULL)
-				break;
-			if (signal_pending(current))
-				break;
-		}
-		if (skb == NULL)
-			return -ERESTARTNOHAND;
+		err = wait_event_interruptible(cdev->recvwait,
+				(skb = skb_dequeue(&cdev->recvqueue)));
+		if (err)
+			return err;
 	}
 	if (skb->len > count) {
 		skb_queue_head(&cdev->recvqueue, skb);
@@ -753,9 +756,9 @@ capi_write(struct file *file, const char
 	CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);
 
 	if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) {
-		mutex_lock(&cdev->ncci_list_mtx);
+		mutex_lock(&cdev->lock);
 		capincci_free(cdev, CAPIMSG_NCCI(skb->data));
-		mutex_unlock(&cdev->ncci_list_mtx);
+		mutex_unlock(&cdev->lock);
 	}
 
 	cdev->errcode = capi20_put_message(&cdev->ap, skb);
@@ -788,30 +791,35 @@ capi_ioctl(struct inode *inode, struct f
 	   unsigned int cmd, unsigned long arg)
 {
 	struct capidev *cdev = file->private_data;
-	struct capi20_appl *ap = &cdev->ap;
 	capi_ioctl_struct data;
 	int retval = -EINVAL;
 	void __user *argp = (void __user *)arg;
 
 	switch (cmd) {
 	case CAPI_REGISTER:
-		{
-			if (ap->applid)
-				return -EEXIST;
+		mutex_lock(&cdev->lock);
 
-			if (copy_from_user(&cdev->ap.rparam, argp,
-					   sizeof(struct capi_register_params)))
-				return -EFAULT;
-			
-			cdev->ap.private = cdev;
-			cdev->ap.recv_message = capi_recv_message;
-			cdev->errcode = capi20_register(ap);
-			if (cdev->errcode) {
-				ap->applid = 0;
-				return -EIO;
-			}
+		if (cdev->ap.applid) {
+			retval = -EEXIST;
+			goto register_out;
 		}
-		return (int)ap->applid;
+		if (copy_from_user(&cdev->ap.rparam, argp,
+				   sizeof(struct capi_register_params))) {
+			retval = -EFAULT;
+			goto register_out;
+		}
+		cdev->ap.private = cdev;
+		cdev->ap.recv_message = capi_recv_message;
+		cdev->errcode = capi20_register(&cdev->ap);
+		retval = (int)cdev->ap.applid;
+		if (cdev->errcode) {
+			cdev->ap.applid = 0;
+			retval = -EIO;
+		}
+
+register_out:
+		mutex_unlock(&cdev->lock);
+		return retval;
 
 	case CAPI_GET_VERSION:
 		{
@@ -910,101 +918,104 @@ capi_ioctl(struct inode *inode, struct f
 		return 0;
 
 	case CAPI_SET_FLAGS:
-	case CAPI_CLR_FLAGS:
-		{
-			unsigned userflags;
-			if (copy_from_user(&userflags, argp,
-					   sizeof(userflags)))
-				return -EFAULT;
-			if (cmd == CAPI_SET_FLAGS)
-				cdev->userflags |= userflags;
-			else
-				cdev->userflags &= ~userflags;
-		}
-		return 0;
+	case CAPI_CLR_FLAGS: {
+		unsigned userflags;
+
+		if (copy_from_user(&userflags, argp, sizeof(userflags)))
+			return -EFAULT;
 
+		mutex_lock(&cdev->lock);
+		if (cmd == CAPI_SET_FLAGS)
+			cdev->userflags |= userflags;
+		else
+			cdev->userflags &= ~userflags;
+		mutex_unlock(&cdev->lock);
+		return 0;
+	}
 	case CAPI_GET_FLAGS:
 		if (copy_to_user(argp, &cdev->userflags,
 				 sizeof(cdev->userflags)))
 			return -EFAULT;
 		return 0;
 
-	case CAPI_NCCI_OPENCOUNT:
-		{
-			struct capincci *nccip;
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-			struct capiminor *mp;
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
-			unsigned ncci;
-			int count = 0;
-			if (copy_from_user(&ncci, argp, sizeof(ncci)))
-				return -EFAULT;
+	case CAPI_NCCI_OPENCOUNT: {
+		struct capincci *nccip;
+		unsigned ncci;
+		int count = 0;
 
-			mutex_lock(&cdev->ncci_list_mtx);
-			if ((nccip = capincci_find(cdev, (u32) ncci)) == NULL) {
-				mutex_unlock(&cdev->ncci_list_mtx);
-				return 0;
-			}
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-			if ((mp = nccip->minorp) != NULL) {
-				count += atomic_read(&mp->ttyopencount);
-			}
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
-			mutex_unlock(&cdev->ncci_list_mtx);
-			return count;
-		}
-		return 0;
+		if (copy_from_user(&ncci, argp, sizeof(ncci)))
+			return -EFAULT;
+
+		mutex_lock(&cdev->lock);
+		nccip = capincci_find(cdev, (u32)ncci);
+		if (nccip)
+			count = capincci_minor_opencount(nccip);
+		mutex_unlock(&cdev->lock);
+		return count;
+	}
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-	case CAPI_NCCI_GETUNIT:
-		{
-			struct capincci *nccip;
-			struct capiminor *mp;
-			unsigned ncci;
-			int unit = 0;
-			if (copy_from_user(&ncci, argp,
-					   sizeof(ncci)))
-				return -EFAULT;
-			mutex_lock(&cdev->ncci_list_mtx);
-			nccip = capincci_find(cdev, (u32) ncci);
-			if (!nccip || (mp = nccip->minorp) == NULL) {
-				mutex_unlock(&cdev->ncci_list_mtx);
-				return -ESRCH;
-			}
-			unit = mp->minor;
-			mutex_unlock(&cdev->ncci_list_mtx);
-			return unit;
+	case CAPI_NCCI_GETUNIT: {
+		struct capincci *nccip;
+		struct capiminor *mp;
+		unsigned ncci;
+		int unit = -ESRCH;
+
+		if (copy_from_user(&ncci, argp, sizeof(ncci)))
+			return -EFAULT;
+
+		mutex_lock(&cdev->lock);
+		nccip = capincci_find(cdev, (u32)ncci);
+		if (nccip) {
+			mp = nccip->minorp;
+			if (mp)
+				unit = mp->minor;
 		}
-		return 0;
+		mutex_unlock(&cdev->lock);
+		return unit;
+	}
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
+
+	default:
+		return -EINVAL;
 	}
-	return -EINVAL;
 }
 
-static int
-capi_open(struct inode *inode, struct file *file)
+static int capi_open(struct inode *inode, struct file *file)
 {
-	int ret;
-	
-	lock_kernel();
-	if (file->private_data)
-		ret = -EEXIST;
-	else if ((file->private_data = capidev_alloc()) == NULL)
-		ret = -ENOMEM;
-	else
-		ret = nonseekable_open(inode, file);
-	unlock_kernel();
-	return ret;
+	struct capidev *cdev;
+
+	cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
+	if (!cdev)
+		return -ENOMEM;
+
+	mutex_init(&cdev->lock);
+	skb_queue_head_init(&cdev->recvqueue);
+	init_waitqueue_head(&cdev->recvwait);
+	INIT_LIST_HEAD(&cdev->nccis);
+	file->private_data = cdev;
+
+	mutex_lock(&capidev_list_lock);
+	list_add_tail(&cdev->list, &capidev_list);
+	mutex_unlock(&capidev_list_lock);
+
+	return nonseekable_open(inode, file);
 }
 
-static int
-capi_release(struct inode *inode, struct file *file)
+static int capi_release(struct inode *inode, struct file *file)
 {
-	struct capidev *cdev = (struct capidev *)file->private_data;
+	struct capidev *cdev = file->private_data;
 
-	capidev_free(cdev);
-	file->private_data = NULL;
-	
+	mutex_lock(&capidev_list_lock);
+	list_del(&cdev->list);
+	mutex_unlock(&capidev_list_lock);
+
+	if (cdev->ap.applid)
+		capi20_release(&cdev->ap);
+	skb_queue_purge(&cdev->recvqueue);
+	capincci_free(cdev, 0xffffffff);
+
+	kfree(cdev);
 	return 0;
 }
 
@@ -1023,182 +1034,159 @@ static const struct file_operations capi
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 /* -------- tty_operations for capincci ----------------------------- */
 
-static int capinc_tty_open(struct tty_struct * tty, struct file * file)
+static int
+capinc_tty_install(struct tty_driver *driver, struct tty_struct *tty)
 {
-	struct capiminor *mp;
-	unsigned long flags;
+	int idx = tty->index;
+	struct capiminor *mp = capiminor_get(idx);
+	int ret = tty_init_termios(tty);
 
-	if ((mp = capiminor_find(iminor(file->f_path.dentry->d_inode))) == NULL)
-		return -ENXIO;
-	if (mp->nccip == NULL)
-		return -ENXIO;
+	if (ret == 0) {
+		tty_driver_kref_get(driver);
+		tty->count++;
+		tty->driver_data = mp;
+		driver->ttys[idx] = tty;
+	} else
+		capiminor_put(mp);
+	return ret;
+}
 
-	tty->driver_data = (void *)mp;
+static void capinc_tty_cleanup(struct tty_struct *tty)
+{
+	struct capiminor *mp = tty->driver_data;
+	tty->driver_data = NULL;
+	capiminor_put(mp);
+}
+
+static int capinc_tty_open(struct tty_struct *tty, struct file *filp)
+{
+	struct capiminor *mp = tty->driver_data;
+	int err;
+
+	err = tty_port_open(&mp->port, tty, filp);
+	if (err)
+		return err;
 
-	spin_lock_irqsave(&workaround_lock, flags);
-	if (atomic_read(&mp->ttyopencount) == 0)
-		mp->tty = tty;
-	atomic_inc(&mp->ttyopencount);
-#ifdef _DEBUG_REFCOUNT
-	printk(KERN_DEBUG "capinc_tty_open ocount=%d\n", atomic_read(&mp->ttyopencount));
-#endif
 	handle_minor_recv(mp);
-	spin_unlock_irqrestore(&workaround_lock, flags);
 	return 0;
 }
 
-static void capinc_tty_close(struct tty_struct * tty, struct file * file)
+static void capinc_tty_close(struct tty_struct *tty, struct file *filp)
 {
-	struct capiminor *mp;
-
-	mp = (struct capiminor *)tty->driver_data;
-	if (mp)	{
-		if (atomic_dec_and_test(&mp->ttyopencount)) {
-#ifdef _DEBUG_REFCOUNT
-			printk(KERN_DEBUG "capinc_tty_close lastclose\n");
-#endif
-			tty->driver_data = NULL;
-			mp->tty = NULL;
-		}
-#ifdef _DEBUG_REFCOUNT
-		printk(KERN_DEBUG "capinc_tty_close ocount=%d\n", atomic_read(&mp->ttyopencount));
-#endif
-		if (mp->nccip == NULL)
-			capiminor_free(mp);
-	}
+	struct capiminor *mp = tty->driver_data;
 
-#ifdef _DEBUG_REFCOUNT
-	printk(KERN_DEBUG "capinc_tty_close\n");
-#endif
+	tty_port_close(&mp->port, tty, filp);
 }
 
-static int capinc_tty_write(struct tty_struct * tty,
+static int capinc_tty_write(struct tty_struct *tty,
 			    const unsigned char *buf, int count)
 {
-	struct capiminor *mp = (struct capiminor *)tty->driver_data;
+	struct capiminor *mp = tty->driver_data;
 	struct sk_buff *skb;
-	unsigned long flags;
 
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_tty_write(count=%d)\n", count);
 #endif
 
-	if (!mp || !mp->nccip) {
-#ifdef _DEBUG_TTYFUNCS
-		printk(KERN_DEBUG "capinc_tty_write: mp or mp->ncci NULL\n");
-#endif
-		return 0;
-	}
-
-	spin_lock_irqsave(&workaround_lock, flags);
-	skb = mp->ttyskb;
+	spin_lock_bh(&mp->outlock);
+	skb = mp->outskb;
 	if (skb) {
-		mp->ttyskb = NULL;
-		skb_queue_tail(&mp->outqueue, skb);
+		mp->outskb = NULL;
+		__skb_queue_tail(&mp->outqueue, skb);
 		mp->outbytes += skb->len;
 	}
 
 	skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+count, GFP_ATOMIC);
 	if (!skb) {
 		printk(KERN_ERR "capinc_tty_write: alloc_skb failed\n");
-		spin_unlock_irqrestore(&workaround_lock, flags);
+		spin_unlock_bh(&mp->outlock);
 		return -ENOMEM;
 	}
 
 	skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
 	memcpy(skb_put(skb, count), buf, count);
 
-	skb_queue_tail(&mp->outqueue, skb);
+	__skb_queue_tail(&mp->outqueue, skb);
 	mp->outbytes += skb->len;
-	(void)handle_minor_send(mp);
-	(void)handle_minor_recv(mp);
-	spin_unlock_irqrestore(&workaround_lock, flags);
+	spin_unlock_bh(&mp->outlock);
+
+	handle_minor_send(mp);
+
 	return count;
 }
 
 static int capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
 {
-	struct capiminor *mp = (struct capiminor *)tty->driver_data;
+	struct capiminor *mp = tty->driver_data;
+	bool invoke_send = false;
 	struct sk_buff *skb;
-	unsigned long flags;
 	int ret = 1;
 
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_put_char(%u)\n", ch);
 #endif
 
-	if (!mp || !mp->nccip) {
-#ifdef _DEBUG_TTYFUNCS
-		printk(KERN_DEBUG "capinc_tty_put_char: mp or mp->ncci NULL\n");
-#endif
-		return 0;
-	}
-
-	spin_lock_irqsave(&workaround_lock, flags);
-	skb = mp->ttyskb;
+	spin_lock_bh(&mp->outlock);
+	skb = mp->outskb;
 	if (skb) {
 		if (skb_tailroom(skb) > 0) {
 			*(skb_put(skb, 1)) = ch;
-			spin_unlock_irqrestore(&workaround_lock, flags);
-			return 1;
+			goto unlock_out;
 		}
-		mp->ttyskb = NULL;
-		skb_queue_tail(&mp->outqueue, skb);
+		mp->outskb = NULL;
+		__skb_queue_tail(&mp->outqueue, skb);
 		mp->outbytes += skb->len;
-		(void)handle_minor_send(mp);
+		invoke_send = true;
 	}
+
 	skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+CAPI_MAX_BLKSIZE, GFP_ATOMIC);
 	if (skb) {
 		skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
 		*(skb_put(skb, 1)) = ch;
-		mp->ttyskb = skb;
+		mp->outskb = skb;
 	} else {
 		printk(KERN_ERR "capinc_put_char: char %u lost\n", ch);
 		ret = 0;
 	}
-	spin_unlock_irqrestore(&workaround_lock, flags);
+
+unlock_out:
+	spin_unlock_bh(&mp->outlock);
+
+	if (invoke_send)
+		handle_minor_send(mp);
+
 	return ret;
 }
 
 static void capinc_tty_flush_chars(struct tty_struct *tty)
 {
-	struct capiminor *mp = (struct capiminor *)tty->driver_data;
+	struct capiminor *mp = tty->driver_data;
 	struct sk_buff *skb;
-	unsigned long flags;
 
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_tty_flush_chars\n");
 #endif
 
-	if (!mp || !mp->nccip) {
-#ifdef _DEBUG_TTYFUNCS
-		printk(KERN_DEBUG "capinc_tty_flush_chars: mp or mp->ncci NULL\n");
-#endif
-		return;
-	}
-
-	spin_lock_irqsave(&workaround_lock, flags);
-	skb = mp->ttyskb;
+	spin_lock_bh(&mp->outlock);
+	skb = mp->outskb;
 	if (skb) {
-		mp->ttyskb = NULL;
-		skb_queue_tail(&mp->outqueue, skb);
+		mp->outskb = NULL;
+		__skb_queue_tail(&mp->outqueue, skb);
 		mp->outbytes += skb->len;
-		(void)handle_minor_send(mp);
-	}
-	(void)handle_minor_recv(mp);
-	spin_unlock_irqrestore(&workaround_lock, flags);
+		spin_unlock_bh(&mp->outlock);
+
+		handle_minor_send(mp);
+	} else
+		spin_unlock_bh(&mp->outlock);
+
+	handle_minor_recv(mp);
 }
 
 static int capinc_tty_write_room(struct tty_struct *tty)
 {
-	struct capiminor *mp = (struct capiminor *)tty->driver_data;
+	struct capiminor *mp = tty->driver_data;
 	int room;
-	if (!mp || !mp->nccip) {
-#ifdef _DEBUG_TTYFUNCS
-		printk(KERN_DEBUG "capinc_tty_write_room: mp or mp->ncci NULL\n");
-#endif
-		return 0;
-	}
+
 	room = CAPINC_MAX_SENDQUEUE-skb_queue_len(&mp->outqueue);
 	room *= CAPI_MAX_BLKSIZE;
 #ifdef _DEBUG_TTYFUNCS
@@ -1209,13 +1197,8 @@ static int capinc_tty_write_room(struct
 
 static int capinc_tty_chars_in_buffer(struct tty_struct *tty)
 {
-	struct capiminor *mp = (struct capiminor *)tty->driver_data;
-	if (!mp || !mp->nccip) {
-#ifdef _DEBUG_TTYFUNCS
-		printk(KERN_DEBUG "capinc_tty_chars_in_buffer: mp or mp->ncci NULL\n");
-#endif
-		return 0;
-	}
+	struct capiminor *mp = tty->driver_data;
+
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%d\n",
 			mp->outbytes, mp->nack,
@@ -1244,62 +1227,55 @@ static void capinc_tty_set_termios(struc
 #endif
 }
 
-static void capinc_tty_throttle(struct tty_struct * tty)
+static void capinc_tty_throttle(struct tty_struct *tty)
 {
-	struct capiminor *mp = (struct capiminor *)tty->driver_data;
+	struct capiminor *mp = tty->driver_data;
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_tty_throttle\n");
 #endif
-	if (mp)
-		mp->ttyinstop = 1;
+	mp->ttyinstop = 1;
 }
 
-static void capinc_tty_unthrottle(struct tty_struct * tty)
+static void capinc_tty_unthrottle(struct tty_struct *tty)
 {
-	struct capiminor *mp = (struct capiminor *)tty->driver_data;
-	unsigned long flags;
+	struct capiminor *mp = tty->driver_data;
+
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_tty_unthrottle\n");
 #endif
-	if (mp) {
-		spin_lock_irqsave(&workaround_lock, flags);
-		mp->ttyinstop = 0;
-		handle_minor_recv(mp);
-		spin_unlock_irqrestore(&workaround_lock, flags);
-	}
+	mp->ttyinstop = 0;
+	handle_minor_recv(mp);
 }
 
 static void capinc_tty_stop(struct tty_struct *tty)
 {
-	struct capiminor *mp = (struct capiminor *)tty->driver_data;
+	struct capiminor *mp = tty->driver_data;
+
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_tty_stop\n");
 #endif
-	if (mp) {
-		mp->ttyoutstop = 1;
-	}
+	mp->ttyoutstop = 1;
 }
 
 static void capinc_tty_start(struct tty_struct *tty)
 {
-	struct capiminor *mp = (struct capiminor *)tty->driver_data;
-	unsigned long flags;
+	struct capiminor *mp = tty->driver_data;
+
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_tty_start\n");
 #endif
-	if (mp) {
-		spin_lock_irqsave(&workaround_lock, flags);
-		mp->ttyoutstop = 0;
-		(void)handle_minor_send(mp);
-		spin_unlock_irqrestore(&workaround_lock, flags);
-	}
+	mp->ttyoutstop = 0;
+	handle_minor_send(mp);
 }
 
 static void capinc_tty_hangup(struct tty_struct *tty)
 {
+	struct capiminor *mp = tty->driver_data;
+
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_tty_hangup\n");
 #endif
+	tty_port_hangup(&mp->port);
 }
 
 static int capinc_tty_break_ctl(struct tty_struct *tty, int state)
@@ -1331,8 +1307,6 @@ static void capinc_tty_send_xchar(struct
 #endif
 }
 
-static struct tty_driver *capinc_tty_driver;
-
 static const struct tty_operations capinc_ops = {
 	.open = capinc_tty_open,
 	.close = capinc_tty_close,
@@ -1352,25 +1326,34 @@ static const struct tty_operations capin
 	.flush_buffer = capinc_tty_flush_buffer,
 	.set_ldisc = capinc_tty_set_ldisc,
 	.send_xchar = capinc_tty_send_xchar,
+	.install = capinc_tty_install,
+	.cleanup = capinc_tty_cleanup,
 };
 
-static int capinc_tty_init(void)
+static int __init capinc_tty_init(void)
 {
 	struct tty_driver *drv;
-	
+	int err;
+
 	if (capi_ttyminors > CAPINC_MAX_PORTS)
 		capi_ttyminors = CAPINC_MAX_PORTS;
 	if (capi_ttyminors <= 0)
 		capi_ttyminors = CAPINC_NR_PORTS;
 
-	drv = alloc_tty_driver(capi_ttyminors);
-	if (!drv)
+	capiminors = kzalloc(sizeof(struct capi_minor *) * capi_ttyminors,
+			     GFP_KERNEL);
+	if (!capiminors)
 		return -ENOMEM;
 
+	drv = alloc_tty_driver(capi_ttyminors);
+	if (!drv) {
+		kfree(capiminors);
+		return -ENOMEM;
+	}
 	drv->owner = THIS_MODULE;
 	drv->driver_name = "capi_nc";
 	drv->name = "capi";
-	drv->major = capi_ttymajor;
+	drv->major = 0;
 	drv->minor_start = 0;
 	drv->type = TTY_DRIVER_TYPE_SERIAL;
 	drv->subtype = SERIAL_TYPE_NORMAL;
@@ -1379,27 +1362,39 @@ static int capinc_tty_init(void)
 	drv->init_termios.c_oflag = OPOST | ONLCR;
 	drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
 	drv->init_termios.c_lflag = 0;
-	drv->flags = TTY_DRIVER_REAL_RAW|TTY_DRIVER_RESET_TERMIOS;
+	drv->flags =
+		TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS |
+		TTY_DRIVER_DYNAMIC_DEV;
 	tty_set_operations(drv, &capinc_ops);
-	if (tty_register_driver(drv)) {
+
+	err = tty_register_driver(drv);
+	if (err) {
 		put_tty_driver(drv);
+		kfree(capiminors);
 		printk(KERN_ERR "Couldn't register capi_nc driver\n");
-		return -1;
+		return err;
 	}
 	capinc_tty_driver = drv;
 	return 0;
 }
 
-static void capinc_tty_exit(void)
+static void __exit capinc_tty_exit(void)
 {
-	struct tty_driver *drv = capinc_tty_driver;
-	int retval;
-	if ((retval = tty_unregister_driver(drv)))
-		printk(KERN_ERR "capi: failed to unregister capi_nc driver (%d)\n", retval);
-	put_tty_driver(drv);
+	tty_unregister_driver(capinc_tty_driver);
+	put_tty_driver(capinc_tty_driver);
+	kfree(capiminors);
 }
 
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
+#else /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
+
+static inline int capinc_tty_init(void)
+{
+	return 0;
+}
+
+static inline void capinc_tty_exit(void) { }
+
+#endif /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
 
 /* -------- /proc functions ----------------------------------------- */
 
@@ -1407,134 +1402,91 @@ static void capinc_tty_exit(void)
  * /proc/capi/capi20:
  *  minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
  */
-static int proc_capidev_read_proc(char *page, char **start, off_t off,
-                                       int count, int *eof, void *data)
+static int capi20_proc_show(struct seq_file *m, void *v)
 {
         struct capidev *cdev;
 	struct list_head *l;
-	int len = 0;
 
-	read_lock(&capidev_list_lock);
+	mutex_lock(&capidev_list_lock);
 	list_for_each(l, &capidev_list) {
 		cdev = list_entry(l, struct capidev, list);
-		len += sprintf(page+len, "0 %d %lu %lu %lu %lu\n",
+		seq_printf(m, "0 %d %lu %lu %lu %lu\n",
 			cdev->ap.applid,
 			cdev->ap.nrecvctlpkt,
 			cdev->ap.nrecvdatapkt,
 			cdev->ap.nsentctlpkt,
 			cdev->ap.nsentdatapkt);
-		if (len <= off) {
-			off -= len;
-			len = 0;
-		} else {
-			if (len-off > count)
-				goto endloop;
-		}
 	}
+	mutex_unlock(&capidev_list_lock);
+	return 0;
+}
 
-endloop:
-	read_unlock(&capidev_list_lock);
-	if (len < count)
-		*eof = 1;
-	if (len > count) len = count;
-	if (len < 0) len = 0;
-	return len;
+static int capi20_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, capi20_proc_show, NULL);
 }
 
+static const struct file_operations capi20_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= capi20_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*
  * /proc/capi/capi20ncci:
  *  applid ncci
  */
-static int proc_capincci_read_proc(char *page, char **start, off_t off,
-                                       int count, int *eof, void *data)
+static int capi20ncci_proc_show(struct seq_file *m, void *v)
 {
-        struct capidev *cdev;
-        struct capincci *np;
-	struct list_head *l;
-	int len = 0;
+	struct capidev *cdev;
+	struct capincci *np;
 
-	read_lock(&capidev_list_lock);
-	list_for_each(l, &capidev_list) {
-		cdev = list_entry(l, struct capidev, list);
-		for (np=cdev->nccis; np; np = np->next) {
-			len += sprintf(page+len, "%d 0x%x\n",
-				       cdev->ap.applid,
-				       np->ncci);
-			if (len <= off) {
-				off -= len;
-				len = 0;
-			} else {
-				if (len-off > count)
-					goto endloop;
-			}
-		}
+	mutex_lock(&capidev_list_lock);
+	list_for_each_entry(cdev, &capidev_list, list) {
+		mutex_lock(&cdev->lock);
+		list_for_each_entry(np, &cdev->nccis, list)
+			seq_printf(m, "%d 0x%x\n", cdev->ap.applid, np->ncci);
+		mutex_unlock(&cdev->lock);
 	}
-endloop:
-	read_unlock(&capidev_list_lock);
-	*start = page+off;
-	if (len < count)
-		*eof = 1;
-	if (len>count) len = count;
-	if (len<0) len = 0;
-	return len;
+	mutex_unlock(&capidev_list_lock);
+	return 0;
 }
 
-static struct procfsentries {
-  char *name;
-  mode_t mode;
-  int (*read_proc)(char *page, char **start, off_t off,
-                                       int count, int *eof, void *data);
-  struct proc_dir_entry *procent;
-} procfsentries[] = {
-   /* { "capi",		  S_IFDIR, 0 }, */
-   { "capi/capi20", 	  0	 , proc_capidev_read_proc },
-   { "capi/capi20ncci",   0	 , proc_capincci_read_proc },
+static int capi20ncci_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, capi20ncci_proc_show, NULL);
+}
+
+static const struct file_operations capi20ncci_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= capi20ncci_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
 };
 
 static void __init proc_init(void)
 {
-    int nelem = ARRAY_SIZE(procfsentries);
-    int i;
-
-    for (i=0; i < nelem; i++) {
-        struct procfsentries *p = procfsentries + i;
-	p->procent = create_proc_entry(p->name, p->mode, NULL);
-	if (p->procent) p->procent->read_proc = p->read_proc;
-    }
+	proc_create("capi/capi20", 0, NULL, &capi20_proc_fops);
+	proc_create("capi/capi20ncci", 0, NULL, &capi20ncci_proc_fops);
 }
 
 static void __exit proc_exit(void)
 {
-    int nelem = ARRAY_SIZE(procfsentries);
-    int i;
-
-    for (i=nelem-1; i >= 0; i--) {
-        struct procfsentries *p = procfsentries + i;
-	if (p->procent) {
-	   remove_proc_entry(p->name, NULL);
-	   p->procent = NULL;
-	}
-    }
+	remove_proc_entry("capi/capi20", NULL);
+	remove_proc_entry("capi/capi20ncci", NULL);
 }
 
 /* -------- init function and module interface ---------------------- */
 
 
-static char rev[32];
-
 static int __init capi_init(void)
 {
-	char *p;
-	char *compileinfo;
+	const char *compileinfo;
 	int major_ret;
 
-	if ((p = strchr(revision, ':')) != NULL && p[1]) {
-		strlcpy(rev, p + 2, sizeof(rev));
-		if ((p = strchr(rev, '$')) != NULL && p > rev)
-		   *(p-1) = 0;
-	} else
-		strcpy(rev, "1.0");
-
 	major_ret = register_chrdev(capi_major, "capi20", &capi_fops);
 	if (major_ret < 0) {
 		printk(KERN_ERR "capi20: unable to get major %d\n", capi_major);
@@ -1548,28 +1500,24 @@ static int __init capi_init(void)
 
 	device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi");
 
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 	if (capinc_tty_init() < 0) {
 		device_destroy(capi_class, MKDEV(capi_major, 0));
 		class_destroy(capi_class);
 		unregister_chrdev(capi_major, "capi20");
 		return -ENOMEM;
 	}
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 
 	proc_init();
 
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 #if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
         compileinfo = " (middleware+capifs)";
-#else
+#elif defined(CONFIG_ISDN_CAPI_MIDDLEWARE)
         compileinfo = " (no capifs)";
-#endif
 #else
         compileinfo = " (no middleware)";
 #endif
-	printk(KERN_NOTICE "capi20: Rev %s: started up with major %d%s\n",
-				rev, capi_major, compileinfo);
+	printk(KERN_NOTICE "CAPI 2.0 started up with major %d%s\n",
+	       capi_major, compileinfo);
 
 	return 0;
 }
@@ -1582,10 +1530,7 @@ static void __exit capi_exit(void)
 	class_destroy(capi_class);
 	unregister_chrdev(capi_major, "capi20");
 
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 	capinc_tty_exit();
-#endif
-	printk(KERN_NOTICE "capi: Rev %s: unloaded\n", rev);
 }
 
 module_init(capi_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/capi/capidrv.c linux-libre-2.6.34-gnu1/drivers/isdn/capi/capidrv.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/capi/capidrv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/capi/capidrv.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/isdn.h>
 #include <linux/isdnif.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
 #include <linux/ctype.h>
@@ -34,7 +35,6 @@
 #include <linux/isdn/capicmd.h>
 #include "capidrv.h"
 
-static char *revision = "$Revision: 1.1.2.2 $";
 static int debugmode = 0;
 
 MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux");
@@ -2210,96 +2210,73 @@ static int capidrv_delcontr(u16 contr)
 }
 
 
-static void lower_callback(unsigned int cmd, u32 contr, void *data)
+static int
+lower_callback(struct notifier_block *nb, unsigned long val, void *v)
 {
+	capi_profile profile;
+	u32 contr = (long)v;
 
-	switch (cmd) {
-	case KCI_CONTRUP:
+	switch (val) {
+	case CAPICTR_UP:
 		printk(KERN_INFO "capidrv: controller %hu up\n", contr);
-		(void) capidrv_addcontr(contr, (capi_profile *) data);
+		if (capi20_get_profile(contr, &profile) == CAPI_NOERROR)
+			(void) capidrv_addcontr(contr, &profile);
 		break;
-	case KCI_CONTRDOWN:
+	case CAPICTR_DOWN:
 		printk(KERN_INFO "capidrv: controller %hu down\n", contr);
 		(void) capidrv_delcontr(contr);
 		break;
 	}
+	return NOTIFY_OK;
 }
 
 /*
  * /proc/capi/capidrv:
  * nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
  */
-static int proc_capidrv_read_proc(char *page, char **start, off_t off,
-                                       int count, int *eof, void *data)
+static int capidrv_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
-
-	len += sprintf(page+len, "%lu %lu %lu %lu\n",
+	seq_printf(m, "%lu %lu %lu %lu\n",
 			global.ap.nrecvctlpkt,
 			global.ap.nrecvdatapkt,
 			global.ap.nsentctlpkt,
 			global.ap.nsentdatapkt);
-	if (off+count >= len)
-	   *eof = 1;
-	if (len < off)
-           return 0;
-	*start = page + off;
-	return ((count < len-off) ? count : len-off);
+	return 0;
 }
 
-static struct procfsentries {
-  char *name;
-  mode_t mode;
-  int (*read_proc)(char *page, char **start, off_t off,
-                                       int count, int *eof, void *data);
-  struct proc_dir_entry *procent;
-} procfsentries[] = {
-   /* { "capi",		  S_IFDIR, 0 }, */
-   { "capi/capidrv", 	  0	 , proc_capidrv_read_proc },
+static int capidrv_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, capidrv_proc_show, NULL);
+}
+
+static const struct file_operations capidrv_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= capidrv_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
 };
 
 static void __init proc_init(void)
 {
-    int nelem = ARRAY_SIZE(procfsentries);
-    int i;
-
-    for (i=0; i < nelem; i++) {
-        struct procfsentries *p = procfsentries + i;
-	p->procent = create_proc_entry(p->name, p->mode, NULL);
-	if (p->procent) p->procent->read_proc = p->read_proc;
-    }
+	proc_create("capi/capidrv", 0, NULL, &capidrv_proc_fops);
 }
 
 static void __exit proc_exit(void)
 {
-    int nelem = ARRAY_SIZE(procfsentries);
-    int i;
-
-    for (i=nelem-1; i >= 0; i--) {
-        struct procfsentries *p = procfsentries + i;
-	if (p->procent) {
-	   remove_proc_entry(p->name, NULL);
-	   p->procent = NULL;
-	}
-    }
+	remove_proc_entry("capi/capidrv", NULL);
 }
 
+static struct notifier_block capictr_nb = {
+	.notifier_call = lower_callback,
+};
+
 static int __init capidrv_init(void)
 {
 	capi_profile profile;
-	char rev[32];
-	char *p;
 	u32 ncontr, contr;
 	u16 errcode;
 
-	if ((p = strchr(revision, ':')) != NULL && p[1]) {
-		strncpy(rev, p + 2, sizeof(rev));
-		rev[sizeof(rev)-1] = 0;
-		if ((p = strchr(rev, '$')) != NULL && p > rev)
-		   *(p-1) = 0;
-	} else
-		strcpy(rev, "1.0");
-
 	global.ap.rparam.level3cnt = -2;  /* number of bchannels twice */
 	global.ap.rparam.datablkcnt = 16;
 	global.ap.rparam.datablklen = 2048;
@@ -2310,7 +2287,7 @@ static int __init capidrv_init(void)
 		return -EIO;
 	}
 
-	capi20_set_callback(&global.ap, lower_callback);
+	register_capictr_notifier(&capictr_nb);
 
 	errcode = capi20_get_profile(0, &profile);
 	if (errcode != CAPI_NOERROR) {
@@ -2327,29 +2304,15 @@ static int __init capidrv_init(void)
 	}
 	proc_init();
 
-	printk(KERN_NOTICE "capidrv: Rev %s: loaded\n", rev);
 	return 0;
 }
 
 static void __exit capidrv_exit(void)
 {
-	char rev[32];
-	char *p;
-
-	if ((p = strchr(revision, ':')) != NULL) {
-		strncpy(rev, p + 1, sizeof(rev));
-		rev[sizeof(rev)-1] = 0;
-		if ((p = strchr(rev, '$')) != NULL)
-			*p = 0;
-	} else {
-		strcpy(rev, " ??? ");
-	}
-
+	unregister_capictr_notifier(&capictr_nb);
 	capi20_release(&global.ap);
 
 	proc_exit();
-
-	printk(KERN_NOTICE "capidrv: Rev%s: unloaded\n", rev);
 }
 
 module_init(capidrv_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/capi/capifs.c linux-libre-2.6.34-gnu1/drivers/isdn/capi/capifs.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/capi/capifs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/capi/capifs.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <linux/fs.h>
 #include <linux/mount.h>
+#include <linux/slab.h>
 #include <linux/namei.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -25,14 +26,10 @@ MODULE_LICENSE("GPL");
 
 /* ------------------------------------------------------------------ */
 
-static char *revision = "$Revision: 1.1.2.3 $";
-
-/* ------------------------------------------------------------------ */
-
 #define CAPIFS_SUPER_MAGIC (('C'<<8)|'N')
 
 static struct vfsmount *capifs_mnt;
-static struct dentry *capifs_root;
+static int capifs_mnt_count;
 
 static struct {
 	int setuid;
@@ -118,7 +115,7 @@ capifs_fill_super(struct super_block *s,
 	inode->i_fop = &simple_dir_operations;
 	inode->i_nlink = 2;
 
-	capifs_root = s->s_root = d_alloc_root(inode);
+	s->s_root = d_alloc_root(inode);
 	if (s->s_root)
 		return 0;
 	
@@ -141,82 +138,98 @@ static struct file_system_type capifs_fs
 	.kill_sb	= kill_anon_super,
 };
 
-static struct dentry *get_node(int num)
+static struct dentry *new_ncci(unsigned int number, dev_t device)
 {
-	char s[10];
-	struct dentry *root = capifs_root;
+	struct super_block *s = capifs_mnt->mnt_sb;
+	struct dentry *root = s->s_root;
+	struct dentry *dentry;
+	struct inode *inode;
+	char name[10];
+	int namelen;
+
 	mutex_lock(&root->d_inode->i_mutex);
-	return lookup_one_len(s, root, sprintf(s, "%d", num));
-}
 
-void capifs_new_ncci(unsigned int number, dev_t device)
-{
-	struct dentry *dentry;
-	struct inode *inode = new_inode(capifs_mnt->mnt_sb);
-	if (!inode)
-		return;
-	inode->i_ino = number+2;
+	namelen = sprintf(name, "%d", number);
+	dentry = lookup_one_len(name, root, namelen);
+	if (IS_ERR(dentry)) {
+		dentry = NULL;
+		goto unlock_out;
+	}
 
-	dentry = get_node(number);
+	if (dentry->d_inode) {
+		dput(dentry);
+		dentry = NULL;
+		goto unlock_out;
+	}
+
+	inode = new_inode(s);
+	if (!inode) {
+		dput(dentry);
+		dentry = NULL;
+		goto unlock_out;
+	}
 
 	/* 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;
+	inode->i_ino = number + 2;
 	init_special_inode(inode, S_IFCHR|config.mode, device);
-	//inode->i_op = &capifs_file_inode_operations;
 
-	if (!IS_ERR(dentry) && !dentry->d_inode)
-		d_instantiate(dentry, inode);
-	mutex_unlock(&capifs_root->d_inode->i_mutex);
+	d_instantiate(dentry, inode);
+	dget(dentry);
+
+unlock_out:
+	mutex_unlock(&root->d_inode->i_mutex);
+
+	return dentry;
 }
 
-void capifs_free_ncci(unsigned int number)
+struct dentry *capifs_new_ncci(unsigned int number, dev_t device)
 {
-	struct dentry *dentry = get_node(number);
+	struct dentry *dentry;
 
-	if (!IS_ERR(dentry)) {
-		struct inode *inode = dentry->d_inode;
-		if (inode) {
-			inode->i_nlink--;
-			d_delete(dentry);
-			dput(dentry);
-		}
-		dput(dentry);
-	}
-	mutex_unlock(&capifs_root->d_inode->i_mutex);
+	if (simple_pin_fs(&capifs_fs_type, &capifs_mnt, &capifs_mnt_count) < 0)
+		return NULL;
+
+	dentry = new_ncci(number, device);
+	if (!dentry)
+		simple_release_fs(&capifs_mnt, &capifs_mnt_count);
+
+	return dentry;
 }
 
-static int __init capifs_init(void)
+void capifs_free_ncci(struct dentry *dentry)
 {
-	char rev[32];
-	char *p;
-	int err;
+	struct dentry *root = capifs_mnt->mnt_sb->s_root;
+	struct inode *inode;
 
-	if ((p = strchr(revision, ':')) != NULL && p[1]) {
-		strlcpy(rev, p + 2, sizeof(rev));
-		if ((p = strchr(rev, '$')) != NULL && p > rev)
-		   *(p-1) = 0;
-	} else
-		strcpy(rev, "1.0");
+	if (!dentry)
+		return;
 
-	err = register_filesystem(&capifs_fs_type);
-	if (!err) {
-		capifs_mnt = kern_mount(&capifs_fs_type);
-		if (IS_ERR(capifs_mnt)) {
-			err = PTR_ERR(capifs_mnt);
-			unregister_filesystem(&capifs_fs_type);
-		}
+	mutex_lock(&root->d_inode->i_mutex);
+
+	inode = dentry->d_inode;
+	if (inode) {
+		drop_nlink(inode);
+		d_delete(dentry);
+		dput(dentry);
 	}
-	if (!err)
-		printk(KERN_NOTICE "capifs: Rev %s\n", rev);
-	return err;
+	dput(dentry);
+
+	mutex_unlock(&root->d_inode->i_mutex);
+
+	simple_release_fs(&capifs_mnt, &capifs_mnt_count);
+}
+
+static int __init capifs_init(void)
+{
+	return register_filesystem(&capifs_fs_type);
 }
 
 static void __exit capifs_exit(void)
 {
 	unregister_filesystem(&capifs_fs_type);
-	mntput(capifs_mnt);
 }
 
 EXPORT_SYMBOL(capifs_new_ncci);
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/capi/capifs.h linux-libre-2.6.34-gnu1/drivers/isdn/capi/capifs.h
--- linux-libre-2.6.33-gnu1/drivers/isdn/capi/capifs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/capi/capifs.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,5 +7,22 @@
  *
  */
 
-void capifs_new_ncci(unsigned int num, dev_t device);
-void capifs_free_ncci(unsigned int num);
+#include <linux/dcache.h>
+
+#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
+
+struct dentry *capifs_new_ncci(unsigned int num, dev_t device);
+void capifs_free_ncci(struct dentry *dentry);
+
+#else
+
+static inline struct dentry *capifs_new_ncci(unsigned int num, dev_t device)
+{
+	return NULL;
+}
+
+static inline void capifs_free_ncci(struct dentry *dentry)
+{
+}
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/capi/capilib.c linux-libre-2.6.34-gnu1/drivers/isdn/capi/capilib.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/capi/capilib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/capi/capilib.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,5 @@
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/isdn/capilli.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/capi/capiutil.c linux-libre-2.6.34-gnu1/drivers/isdn/capi/capiutil.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/capi/capiutil.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/capi/capiutil.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/isdn/capiutil.h>
+#include <linux/slab.h>
 
 /* from CAPI2.0 DDK AVM Berlin GmbH */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/capi/kcapi.c linux-libre-2.6.34-gnu1/drivers/isdn/capi/kcapi.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/capi/kcapi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/capi/kcapi.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/moduleparam.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/isdn/capicmd.h>
 #include <linux/isdn/capiutil.h>
@@ -34,10 +35,7 @@
 #include <linux/b1lli.h>
 #endif
 #include <linux/mutex.h>
-
-static char *revision = "$Revision: 1.1.2.8 $";
-
-/* ------------------------------------------------------------- */
+#include <linux/rcupdate.h>
 
 static int showcapimsgs = 0;
 
@@ -48,12 +46,10 @@ module_param(showcapimsgs, uint, 0);
 
 /* ------------------------------------------------------------- */
 
-struct capi_notifier {
+struct capictr_event {
 	struct work_struct work;
-	unsigned int cmd;
+	unsigned int type;
 	u32 controller;
-	u16 applid;
-	u32 ncci;
 };
 
 /* ------------------------------------------------------------- */
@@ -65,30 +61,31 @@ static char capi_manufakturer[64] = "AVM
 #define NCCI2CTRL(ncci)    (((ncci) >> 24) & 0x7f)
 
 LIST_HEAD(capi_drivers);
-DEFINE_RWLOCK(capi_drivers_list_lock);
+DEFINE_MUTEX(capi_drivers_lock);
 
-static DEFINE_RWLOCK(application_lock);
-static DEFINE_MUTEX(controller_mutex);
+struct capi_ctr *capi_controller[CAPI_MAXCONTR];
+DEFINE_MUTEX(capi_controller_lock);
 
 struct capi20_appl *capi_applications[CAPI_MAXAPPL];
-struct capi_ctr *capi_cards[CAPI_MAXCONTR];
 
-static int ncards;
+static int ncontrollers;
+
+static BLOCKING_NOTIFIER_HEAD(ctr_notifier_list);
 
 /* -------- controller ref counting -------------------------------------- */
 
 static inline struct capi_ctr *
-capi_ctr_get(struct capi_ctr *card)
+capi_ctr_get(struct capi_ctr *ctr)
 {
-	if (!try_module_get(card->owner))
+	if (!try_module_get(ctr->owner))
 		return NULL;
-	return card;
+	return ctr;
 }
 
 static inline void
-capi_ctr_put(struct capi_ctr *card)
+capi_ctr_put(struct capi_ctr *ctr)
 {
-	module_put(card->owner);
+	module_put(ctr->owner);
 }
 
 /* ------------------------------------------------------------- */
@@ -98,7 +95,7 @@ static inline struct capi_ctr *get_capi_
 	if (contr - 1 >= CAPI_MAXCONTR)
 		return NULL;
 
-	return capi_cards[contr - 1];
+	return capi_controller[contr - 1];
 }
 
 static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
@@ -106,7 +103,7 @@ static inline struct capi20_appl *get_ca
 	if (applid - 1 >= CAPI_MAXAPPL)
 		return NULL;
 
-	return capi_applications[applid - 1];
+	return rcu_dereference(capi_applications[applid - 1]);
 }
 
 /* -------- util functions ------------------------------------ */
@@ -148,106 +145,159 @@ static inline int capi_subcmd_valid(u8 s
 
 /* ------------------------------------------------------------ */
 
-static void register_appl(struct capi_ctr *card, u16 applid, capi_register_params *rparam)
+static void
+register_appl(struct capi_ctr *ctr, u16 applid, capi_register_params *rparam)
 {
-	card = capi_ctr_get(card);
+	ctr = capi_ctr_get(ctr);
 
-	if (card)
-		card->register_appl(card, applid, rparam);
+	if (ctr)
+		ctr->register_appl(ctr, applid, rparam);
 	else
-		printk(KERN_WARNING "%s: cannot get card resources\n", __func__);
+		printk(KERN_WARNING "%s: cannot get controller resources\n",
+		       __func__);
 }
 
 
-static void release_appl(struct capi_ctr *card, u16 applid)
+static void release_appl(struct capi_ctr *ctr, u16 applid)
 {
 	DBG("applid %#x", applid);
 	
-	card->release_appl(card, applid);
-	capi_ctr_put(card);
+	ctr->release_appl(ctr, applid);
+	capi_ctr_put(ctr);
 }
 
-/* -------- KCI_CONTRUP --------------------------------------- */
-
 static void notify_up(u32 contr)
 {
-	struct capi_ctr *card = get_capi_ctr_by_nr(contr);
 	struct capi20_appl *ap;
+	struct capi_ctr *ctr;
 	u16 applid;
 
-	if (showcapimsgs & 1) {
+	mutex_lock(&capi_controller_lock);
+
+	if (showcapimsgs & 1)
 	        printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr);
-	}
-	if (!card) {
+
+	ctr = get_capi_ctr_by_nr(contr);
+	if (ctr) {
+		if (ctr->state == CAPI_CTR_RUNNING)
+			goto unlock_out;
+
+		ctr->state = CAPI_CTR_RUNNING;
+
+		for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
+			ap = get_capi_appl_by_nr(applid);
+			if (!ap)
+				continue;
+			register_appl(ctr, applid, &ap->rparam);
+		}
+
+		wake_up_interruptible_all(&ctr->state_wait_queue);
+	} else
 		printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
-		return;
-	}
-	for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
-		ap = get_capi_appl_by_nr(applid);
-		if (!ap || ap->release_in_progress) continue;
-		register_appl(card, applid, &ap->rparam);
-		if (ap->callback && !ap->release_in_progress)
-			ap->callback(KCI_CONTRUP, contr, &card->profile);
-	}
-}
 
-/* -------- KCI_CONTRDOWN ------------------------------------- */
+unlock_out:
+	mutex_unlock(&capi_controller_lock);
+}
 
-static void notify_down(u32 contr)
+static void ctr_down(struct capi_ctr *ctr, int new_state)
 {
 	struct capi20_appl *ap;
 	u16 applid;
 
-	if (showcapimsgs & 1) {
-        	printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr);
-	}
+	if (ctr->state == CAPI_CTR_DETECTED || ctr->state == CAPI_CTR_DETACHED)
+		return;
+
+	ctr->state = new_state;
+
+	memset(ctr->manu, 0, sizeof(ctr->manu));
+	memset(&ctr->version, 0, sizeof(ctr->version));
+	memset(&ctr->profile, 0, sizeof(ctr->profile));
+	memset(ctr->serial, 0, sizeof(ctr->serial));
 
 	for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
 		ap = get_capi_appl_by_nr(applid);
-		if (ap && ap->callback && !ap->release_in_progress)
-			ap->callback(KCI_CONTRDOWN, contr, NULL);
+		if (ap)
+			capi_ctr_put(ctr);
 	}
+
+	wake_up_interruptible_all(&ctr->state_wait_queue);
 }
 
-static void notify_handler(struct work_struct *work)
+static void notify_down(u32 contr)
 {
-	struct capi_notifier *np =
-		container_of(work, struct capi_notifier, work);
+	struct capi_ctr *ctr;
 
-	switch (np->cmd) {
-	case KCI_CONTRUP:
-		notify_up(np->controller);
+	mutex_lock(&capi_controller_lock);
+
+	if (showcapimsgs & 1)
+		printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr);
+
+	ctr = get_capi_ctr_by_nr(contr);
+	if (ctr)
+		ctr_down(ctr, CAPI_CTR_DETECTED);
+	else
+		printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
+
+	mutex_unlock(&capi_controller_lock);
+}
+
+static int
+notify_handler(struct notifier_block *nb, unsigned long val, void *v)
+{
+	u32 contr = (long)v;
+
+	switch (val) {
+	case CAPICTR_UP:
+		notify_up(contr);
 		break;
-	case KCI_CONTRDOWN:
-		notify_down(np->controller);
+	case CAPICTR_DOWN:
+		notify_down(contr);
 		break;
 	}
+	return NOTIFY_OK;
+}
 
-	kfree(np);
+static void do_notify_work(struct work_struct *work)
+{
+	struct capictr_event *event =
+		container_of(work, struct capictr_event, work);
+
+	blocking_notifier_call_chain(&ctr_notifier_list, event->type,
+				     (void *)(long)event->controller);
+	kfree(event);
 }
 
 /*
  * The notifier will result in adding/deleteing of devices. Devices can
  * only removed in user process, not in bh.
  */
-static int notify_push(unsigned int cmd, u32 controller, u16 applid, u32 ncci)
+static int notify_push(unsigned int event_type, u32 controller)
 {
-	struct capi_notifier *np = kmalloc(sizeof(*np), GFP_ATOMIC);
+	struct capictr_event *event = kmalloc(sizeof(*event), GFP_ATOMIC);
 
-	if (!np)
+	if (!event)
 		return -ENOMEM;
 
-	INIT_WORK(&np->work, notify_handler);
-	np->cmd = cmd;
-	np->controller = controller;
-	np->applid = applid;
-	np->ncci = ncci;
+	INIT_WORK(&event->work, do_notify_work);
+	event->type = event_type;
+	event->controller = controller;
 
-	schedule_work(&np->work);
+	schedule_work(&event->work);
 	return 0;
 }
 
-	
+int register_capictr_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&ctr_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(register_capictr_notifier);
+
+int unregister_capictr_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&ctr_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_capictr_notifier);
+
 /* -------- Receiver ------------------------------------------ */
 
 static void recv_handler(struct work_struct *work)
@@ -273,68 +323,70 @@ static void recv_handler(struct work_str
 
 /**
  * capi_ctr_handle_message() - handle incoming CAPI message
- * @card:	controller descriptor structure.
+ * @ctr:	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)
+void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl,
+			     struct sk_buff *skb)
 {
 	struct capi20_appl *ap;
 	int showctl = 0;
 	u8 cmd, subcmd;
-	unsigned long flags;
 	_cdebbuf *cdb;
 
-	if (card->cardstate != CARD_RUNNING) {
+	if (ctr->state != CAPI_CTR_RUNNING) {
 		cdb = capi_message2str(skb->data);
 		if (cdb) {
 			printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s",
-				card->cnr, cdb->buf);
+				ctr->cnr, cdb->buf);
 			cdebbuf_free(cdb);
 		} else
 			printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n",
-				card->cnr);
+				ctr->cnr);
 		goto error;
 	}
 
 	cmd = CAPIMSG_COMMAND(skb->data);
         subcmd = CAPIMSG_SUBCOMMAND(skb->data);
 	if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) {
-		card->nrecvdatapkt++;
-	        if (card->traceflag > 2) showctl |= 2;
+		ctr->nrecvdatapkt++;
+		if (ctr->traceflag > 2)
+			showctl |= 2;
 	} else {
-		card->nrecvctlpkt++;
-	        if (card->traceflag) showctl |= 2;
+		ctr->nrecvctlpkt++;
+		if (ctr->traceflag)
+			showctl |= 2;
 	}
-	showctl |= (card->traceflag & 1);
+	showctl |= (ctr->traceflag & 1);
 	if (showctl & 2) {
 		if (showctl & 1) {
 			printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n",
-			       card->cnr, CAPIMSG_APPID(skb->data),
+			       ctr->cnr, CAPIMSG_APPID(skb->data),
 			       capi_cmd2str(cmd, subcmd),
 			       CAPIMSG_LEN(skb->data));
 		} else {
 			cdb = capi_message2str(skb->data);
 			if (cdb) {
 				printk(KERN_DEBUG "kcapi: got [%03d] %s\n",
-					card->cnr, cdb->buf);
+					ctr->cnr, cdb->buf);
 				cdebbuf_free(cdb);
 			} else
 				printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n",
-					card->cnr, CAPIMSG_APPID(skb->data),
+					ctr->cnr, CAPIMSG_APPID(skb->data),
 					capi_cmd2str(cmd, subcmd),
 					CAPIMSG_LEN(skb->data));
 		}
 
 	}
 
-	read_lock_irqsave(&application_lock, flags);
+	rcu_read_lock();
 	ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data));
-	if ((!ap) || (ap->release_in_progress)) {
-		read_unlock_irqrestore(&application_lock, flags);
+	if (!ap) {
+		rcu_read_unlock();
 		cdb = capi_message2str(skb->data);
 		if (cdb) {
 			printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n",
@@ -348,7 +400,7 @@ void capi_ctr_handle_message(struct capi
 	}
 	skb_queue_tail(&ap->recv_queue, skb);
 	schedule_work(&ap->recv_work);
-	read_unlock_irqrestore(&application_lock, flags);
+	rcu_read_unlock();
 
 	return;
 
@@ -360,74 +412,54 @@ EXPORT_SYMBOL(capi_ctr_handle_message);
 
 /**
  * capi_ctr_ready() - signal CAPI controller ready
- * @card:	controller descriptor structure.
+ * @ctr:	controller descriptor structure.
  *
  * Called by hardware driver to signal that the controller is up and running.
  */
 
-void capi_ctr_ready(struct capi_ctr * card)
+void capi_ctr_ready(struct capi_ctr *ctr)
 {
-	card->cardstate = CARD_RUNNING;
-
-        printk(KERN_NOTICE "kcapi: card [%03d] \"%s\" ready.\n",
-	       card->cnr, card->name);
+	printk(KERN_NOTICE "kcapi: controller [%03d] \"%s\" ready.\n",
+	       ctr->cnr, ctr->name);
 
-	notify_push(KCI_CONTRUP, card->cnr, 0, 0);
+	notify_push(CAPICTR_UP, ctr->cnr);
 }
 
 EXPORT_SYMBOL(capi_ctr_ready);
 
 /**
  * capi_ctr_down() - signal CAPI controller not ready
- * @card:	controller descriptor structure.
+ * @ctr:	controller descriptor structure.
  *
  * Called by hardware driver to signal that the controller is down and
  * unavailable for use.
  */
 
-void capi_ctr_down(struct capi_ctr * card)
+void capi_ctr_down(struct capi_ctr *ctr)
 {
-	u16 appl;
-
-	DBG("");
-
-        if (card->cardstate == CARD_DETECTED)
-		return;
-
-        card->cardstate = CARD_DETECTED;
-
-	memset(card->manu, 0, sizeof(card->manu));
-	memset(&card->version, 0, sizeof(card->version));
-	memset(&card->profile, 0, sizeof(card->profile));
-	memset(card->serial, 0, sizeof(card->serial));
-
-	for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
-		struct capi20_appl *ap = get_capi_appl_by_nr(appl);
-		if (!ap || ap->release_in_progress)
-			continue;
-
-		capi_ctr_put(card);
-	}
-
-	printk(KERN_NOTICE "kcapi: card [%03d] down.\n", card->cnr);
+	printk(KERN_NOTICE "kcapi: controller [%03d] down.\n", ctr->cnr);
 
-	notify_push(KCI_CONTRDOWN, card->cnr, 0, 0);
+	notify_push(CAPICTR_DOWN, ctr->cnr);
 }
 
 EXPORT_SYMBOL(capi_ctr_down);
 
 /**
  * capi_ctr_suspend_output() - suspend controller
- * @card:	controller descriptor structure.
+ * @ctr:	controller descriptor structure.
  *
  * Called by hardware driver to stop data flow.
+ *
+ * Note: The caller is responsible for synchronizing concurrent state changes
+ * as well as invocations of capi_ctr_handle_message.
  */
 
-void capi_ctr_suspend_output(struct capi_ctr *card)
+void capi_ctr_suspend_output(struct capi_ctr *ctr)
 {
-	if (!card->blocked) {
-		printk(KERN_DEBUG "kcapi: card [%03d] suspend\n", card->cnr);
-		card->blocked = 1;
+	if (!ctr->blocked) {
+		printk(KERN_DEBUG "kcapi: controller [%03d] suspend\n",
+		       ctr->cnr);
+		ctr->blocked = 1;
 	}
 }
 
@@ -435,16 +467,20 @@ EXPORT_SYMBOL(capi_ctr_suspend_output);
 
 /**
  * capi_ctr_resume_output() - resume controller
- * @card:	controller descriptor structure.
+ * @ctr:	controller descriptor structure.
  *
  * Called by hardware driver to resume data flow.
+ *
+ * Note: The caller is responsible for synchronizing concurrent state changes
+ * as well as invocations of capi_ctr_handle_message.
  */
 
-void capi_ctr_resume_output(struct capi_ctr *card)
+void capi_ctr_resume_output(struct capi_ctr *ctr)
 {
-	if (card->blocked) {
-		printk(KERN_DEBUG "kcapi: card [%03d] resume\n", card->cnr);
-		card->blocked = 0;
+	if (ctr->blocked) {
+		printk(KERN_DEBUG "kcapi: controller [%03d] resumed\n",
+		       ctr->cnr);
+		ctr->blocked = 0;
 	}
 }
 
@@ -454,53 +490,48 @@ EXPORT_SYMBOL(capi_ctr_resume_output);
 
 /**
  * attach_capi_ctr() - register CAPI controller
- * @card:	controller descriptor structure.
+ * @ctr:	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)
+int attach_capi_ctr(struct capi_ctr *ctr)
 {
 	int i;
 
-	mutex_lock(&controller_mutex);
+	mutex_lock(&capi_controller_lock);
 
 	for (i = 0; i < CAPI_MAXCONTR; i++) {
-		if (capi_cards[i] == NULL)
+		if (!capi_controller[i])
 			break;
 	}
 	if (i == CAPI_MAXCONTR) {
-		mutex_unlock(&controller_mutex);
+		mutex_unlock(&capi_controller_lock);
 		printk(KERN_ERR "kcapi: out of controller slots\n");
 	   	return -EBUSY;
 	}
-	capi_cards[i] = card;
+	capi_controller[i] = ctr;
 
-	mutex_unlock(&controller_mutex);
+	ctr->nrecvctlpkt = 0;
+	ctr->nrecvdatapkt = 0;
+	ctr->nsentctlpkt = 0;
+	ctr->nsentdatapkt = 0;
+	ctr->cnr = i + 1;
+	ctr->state = CAPI_CTR_DETECTED;
+	ctr->blocked = 0;
+	ctr->traceflag = showcapimsgs;
+	init_waitqueue_head(&ctr->state_wait_queue);
 
-	card->nrecvctlpkt = 0;
-	card->nrecvdatapkt = 0;
-	card->nsentctlpkt = 0;
-	card->nsentdatapkt = 0;
-	card->cnr = i + 1;
-	card->cardstate = CARD_DETECTED;
-	card->blocked = 0;
-	card->traceflag = showcapimsgs;
+	sprintf(ctr->procfn, "capi/controllers/%d", ctr->cnr);
+	ctr->procent = proc_create_data(ctr->procfn, 0, NULL, ctr->proc_fops, ctr);
 
-	sprintf(card->procfn, "capi/controllers/%d", card->cnr);
-	card->procent = create_proc_entry(card->procfn, 0, NULL);
-	if (card->procent) {
-	   card->procent->read_proc = 
-		(int (*)(char *,char **,off_t,int,int *,void *))
-			card->ctr_read_proc;
-	   card->procent->data = card;
-	}
+	ncontrollers++;
 
-	ncards++;
-	printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n",
-			card->cnr, card->name);
+	mutex_unlock(&capi_controller_lock);
+
+	printk(KERN_NOTICE "kcapi: controller [%03d]: %s attached\n",
+			ctr->cnr, ctr->name);
 	return 0;
 }
 
@@ -508,29 +539,38 @@ EXPORT_SYMBOL(attach_capi_ctr);
 
 /**
  * detach_capi_ctr() - unregister CAPI controller
- * @card:	controller descriptor structure.
+ * @ctr:	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)
+int detach_capi_ctr(struct capi_ctr *ctr)
 {
-        if (card->cardstate != CARD_DETECTED)
-		capi_ctr_down(card);
+	int err = 0;
 
-	ncards--;
+	mutex_lock(&capi_controller_lock);
 
-	if (card->procent) {
-	   remove_proc_entry(card->procfn, NULL);
-	   card->procent = NULL;
+	ctr_down(ctr, CAPI_CTR_DETACHED);
+
+	if (capi_controller[ctr->cnr - 1] != ctr) {
+		err = -EINVAL;
+		goto unlock_out;
 	}
-	capi_cards[card->cnr - 1] = NULL;
-	printk(KERN_NOTICE "kcapi: Controller [%03d]: %s unregistered\n",
-			card->cnr, card->name);
+	capi_controller[ctr->cnr - 1] = NULL;
+	ncontrollers--;
 
-	return 0;
+	if (ctr->procent)
+		remove_proc_entry(ctr->procfn, NULL);
+
+	printk(KERN_NOTICE "kcapi: controller [%03d]: %s unregistered\n",
+	       ctr->cnr, ctr->name);
+
+unlock_out:
+	mutex_unlock(&capi_controller_lock);
+
+	return err;
 }
 
 EXPORT_SYMBOL(detach_capi_ctr);
@@ -544,11 +584,9 @@ EXPORT_SYMBOL(detach_capi_ctr);
 
 void register_capi_driver(struct capi_driver *driver)
 {
-	unsigned long flags;
-
-	write_lock_irqsave(&capi_drivers_list_lock, flags);
+	mutex_lock(&capi_drivers_lock);
 	list_add_tail(&driver->list, &capi_drivers);
-	write_unlock_irqrestore(&capi_drivers_list_lock, flags);
+	mutex_unlock(&capi_drivers_lock);
 }
 
 EXPORT_SYMBOL(register_capi_driver);
@@ -562,11 +600,9 @@ EXPORT_SYMBOL(register_capi_driver);
 
 void unregister_capi_driver(struct capi_driver *driver)
 {
-	unsigned long flags;
-
-	write_lock_irqsave(&capi_drivers_list_lock, flags);
+	mutex_lock(&capi_drivers_lock);
 	list_del(&driver->list);
-	write_unlock_irqrestore(&capi_drivers_list_lock, flags);
+	mutex_unlock(&capi_drivers_lock);
 }
 
 EXPORT_SYMBOL(unregister_capi_driver);
@@ -584,12 +620,21 @@ EXPORT_SYMBOL(unregister_capi_driver);
 
 u16 capi20_isinstalled(void)
 {
+	u16 ret = CAPI_REGNOTINSTALLED;
 	int i;
-	for (i = 0; i < CAPI_MAXCONTR; i++) {
-		if (capi_cards[i] && capi_cards[i]->cardstate == CARD_RUNNING)
-			return CAPI_NOERROR;
-	}
-	return CAPI_REGNOTINSTALLED;
+
+	mutex_lock(&capi_controller_lock);
+
+	for (i = 0; i < CAPI_MAXCONTR; i++)
+		if (capi_controller[i] &&
+		    capi_controller[i]->state == CAPI_CTR_RUNNING) {
+			ret = CAPI_NOERROR;
+			break;
+		}
+
+	mutex_unlock(&capi_controller_lock);
+
+	return ret;
 }
 
 EXPORT_SYMBOL(capi20_isinstalled);
@@ -610,46 +655,43 @@ u16 capi20_register(struct capi20_appl *
 {
 	int i;
 	u16 applid;
-	unsigned long flags;
 
 	DBG("");
 
 	if (ap->rparam.datablklen < 128)
 		return CAPI_LOGBLKSIZETOSMALL;
 
-	write_lock_irqsave(&application_lock, flags);
+	ap->nrecvctlpkt = 0;
+	ap->nrecvdatapkt = 0;
+	ap->nsentctlpkt = 0;
+	ap->nsentdatapkt = 0;
+	mutex_init(&ap->recv_mtx);
+	skb_queue_head_init(&ap->recv_queue);
+	INIT_WORK(&ap->recv_work, recv_handler);
+	ap->release_in_progress = 0;
+
+	mutex_lock(&capi_controller_lock);
 
 	for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
 		if (capi_applications[applid - 1] == NULL)
 			break;
 	}
 	if (applid > CAPI_MAXAPPL) {
-		write_unlock_irqrestore(&application_lock, flags);
+		mutex_unlock(&capi_controller_lock);
 		return CAPI_TOOMANYAPPLS;
 	}
 
 	ap->applid = applid;
 	capi_applications[applid - 1] = ap;
 
-	ap->nrecvctlpkt = 0;
-	ap->nrecvdatapkt = 0;
-	ap->nsentctlpkt = 0;
-	ap->nsentdatapkt = 0;
-	ap->callback = NULL;
-	mutex_init(&ap->recv_mtx);
-	skb_queue_head_init(&ap->recv_queue);
-	INIT_WORK(&ap->recv_work, recv_handler);
-	ap->release_in_progress = 0;
-
-	write_unlock_irqrestore(&application_lock, flags);
-	
-	mutex_lock(&controller_mutex);
 	for (i = 0; i < CAPI_MAXCONTR; i++) {
-		if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING)
+		if (!capi_controller[i] ||
+		    capi_controller[i]->state != CAPI_CTR_RUNNING)
 			continue;
-		register_appl(capi_cards[i], applid, &ap->rparam);
+		register_appl(capi_controller[i], applid, &ap->rparam);
 	}
-	mutex_unlock(&controller_mutex);
+
+	mutex_unlock(&capi_controller_lock);
 
 	if (showcapimsgs & 1) {
 		printk(KERN_DEBUG "kcapi: appl %d up\n", applid);
@@ -673,22 +715,24 @@ EXPORT_SYMBOL(capi20_register);
 u16 capi20_release(struct capi20_appl *ap)
 {
 	int i;
-	unsigned long flags;
 
 	DBG("applid %#x", ap->applid);
 
-	write_lock_irqsave(&application_lock, flags);
+	mutex_lock(&capi_controller_lock);
+
 	ap->release_in_progress = 1;
 	capi_applications[ap->applid - 1] = NULL;
-	write_unlock_irqrestore(&application_lock, flags);
 
-	mutex_lock(&controller_mutex);
+	synchronize_rcu();
+
 	for (i = 0; i < CAPI_MAXCONTR; i++) {
-		if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING)
+		if (!capi_controller[i] ||
+		    capi_controller[i]->state != CAPI_CTR_RUNNING)
 			continue;
-		release_appl(capi_cards[i], ap->applid);
+		release_appl(capi_controller[i], ap->applid);
 	}
-	mutex_unlock(&controller_mutex);
+
+	mutex_unlock(&capi_controller_lock);
 
 	flush_scheduled_work();
 	skb_queue_purge(&ap->recv_queue);
@@ -713,13 +757,13 @@ EXPORT_SYMBOL(capi20_release);
 
 u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
 {
-	struct capi_ctr *card;
+	struct capi_ctr *ctr;
 	int showctl = 0;
 	u8 cmd, subcmd;
 
 	DBG("applid %#x", ap->applid);
  
-	if (ncards == 0)
+	if (ncontrollers == 0)
 		return CAPI_REGNOTINSTALLED;
 	if ((ap->applid == 0) || ap->release_in_progress)
 		return CAPI_ILLAPPNR;
@@ -727,28 +771,33 @@ u16 capi20_put_message(struct capi20_app
 	    || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
 	    || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data)))
 		return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
-	card = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data));
-	if (!card || card->cardstate != CARD_RUNNING) {
-		card = get_capi_ctr_by_nr(1); // XXX why?
-	        if (!card || card->cardstate != CARD_RUNNING) 
-			return CAPI_REGNOTINSTALLED;
-	}
-	if (card->blocked)
+
+	/*
+	 * The controller reference is protected by the existence of the
+	 * application passed to us. We assume that the caller properly
+	 * synchronizes this service with capi20_release.
+	 */
+	ctr = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data));
+	if (!ctr || ctr->state != CAPI_CTR_RUNNING)
+		return CAPI_REGNOTINSTALLED;
+	if (ctr->blocked)
 		return CAPI_SENDQUEUEFULL;
 
 	cmd = CAPIMSG_COMMAND(skb->data);
         subcmd = CAPIMSG_SUBCOMMAND(skb->data);
 
 	if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) {
-		card->nsentdatapkt++;
+		ctr->nsentdatapkt++;
 		ap->nsentdatapkt++;
-	        if (card->traceflag > 2) showctl |= 2;
+		if (ctr->traceflag > 2)
+			showctl |= 2;
 	} else {
-		card->nsentctlpkt++;
+		ctr->nsentctlpkt++;
 		ap->nsentctlpkt++;
-	        if (card->traceflag) showctl |= 2;
+		if (ctr->traceflag)
+			showctl |= 2;
 	}
-	showctl |= (card->traceflag & 1);
+	showctl |= (ctr->traceflag & 1);
 	if (showctl & 2) {
 		if (showctl & 1) {
 			printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n",
@@ -771,7 +820,7 @@ u16 capi20_put_message(struct capi20_app
 					CAPIMSG_LEN(skb->data));
 		}
 	}
-	return card->send_message(card, skb);
+	return ctr->send_message(ctr, skb);
 }
 
 EXPORT_SYMBOL(capi20_put_message);
@@ -788,17 +837,25 @@ EXPORT_SYMBOL(capi20_put_message);
 
 u16 capi20_get_manufacturer(u32 contr, u8 *buf)
 {
-	struct capi_ctr *card;
+	struct capi_ctr *ctr;
+	u16 ret;
 
 	if (contr == 0) {
 		strlcpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
 		return CAPI_NOERROR;
 	}
-	card = get_capi_ctr_by_nr(contr);
-	if (!card || card->cardstate != CARD_RUNNING) 
-		return CAPI_REGNOTINSTALLED;
-	strlcpy(buf, card->manu, CAPI_MANUFACTURER_LEN);
-	return CAPI_NOERROR;
+
+	mutex_lock(&capi_controller_lock);
+
+	ctr = get_capi_ctr_by_nr(contr);
+	if (ctr && ctr->state == CAPI_CTR_RUNNING) {
+		strlcpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN);
+		ret = CAPI_NOERROR;
+	} else
+		ret = CAPI_REGNOTINSTALLED;
+
+	mutex_unlock(&capi_controller_lock);
+	return ret;
 }
 
 EXPORT_SYMBOL(capi20_get_manufacturer);
@@ -815,18 +872,25 @@ EXPORT_SYMBOL(capi20_get_manufacturer);
 
 u16 capi20_get_version(u32 contr, struct capi_version *verp)
 {
-	struct capi_ctr *card;
+	struct capi_ctr *ctr;
+	u16 ret;
 
 	if (contr == 0) {
 		*verp = driver_version;
 		return CAPI_NOERROR;
 	}
-	card = get_capi_ctr_by_nr(contr);
-	if (!card || card->cardstate != CARD_RUNNING) 
-		return CAPI_REGNOTINSTALLED;
 
-	memcpy((void *) verp, &card->version, sizeof(capi_version));
-	return CAPI_NOERROR;
+	mutex_lock(&capi_controller_lock);
+
+	ctr = get_capi_ctr_by_nr(contr);
+	if (ctr && ctr->state == CAPI_CTR_RUNNING) {
+		memcpy(verp, &ctr->version, sizeof(capi_version));
+		ret = CAPI_NOERROR;
+	} else
+		ret = CAPI_REGNOTINSTALLED;
+
+	mutex_unlock(&capi_controller_lock);
+	return ret;
 }
 
 EXPORT_SYMBOL(capi20_get_version);
@@ -843,18 +907,25 @@ EXPORT_SYMBOL(capi20_get_version);
 
 u16 capi20_get_serial(u32 contr, u8 *serial)
 {
-	struct capi_ctr *card;
+	struct capi_ctr *ctr;
+	u16 ret;
 
 	if (contr == 0) {
 		strlcpy(serial, driver_serial, CAPI_SERIAL_LEN);
 		return CAPI_NOERROR;
 	}
-	card = get_capi_ctr_by_nr(contr);
-	if (!card || card->cardstate != CARD_RUNNING) 
-		return CAPI_REGNOTINSTALLED;
 
-	strlcpy((void *) serial, card->serial, CAPI_SERIAL_LEN);
-	return CAPI_NOERROR;
+	mutex_lock(&capi_controller_lock);
+
+	ctr = get_capi_ctr_by_nr(contr);
+	if (ctr && ctr->state == CAPI_CTR_RUNNING) {
+		strlcpy(serial, ctr->serial, CAPI_SERIAL_LEN);
+		ret = CAPI_NOERROR;
+	} else
+		ret = CAPI_REGNOTINSTALLED;
+
+	mutex_unlock(&capi_controller_lock);
+	return ret;
 }
 
 EXPORT_SYMBOL(capi20_get_serial);
@@ -871,23 +942,65 @@ EXPORT_SYMBOL(capi20_get_serial);
 
 u16 capi20_get_profile(u32 contr, struct capi_profile *profp)
 {
-	struct capi_ctr *card;
+	struct capi_ctr *ctr;
+	u16 ret;
 
 	if (contr == 0) {
-		profp->ncontroller = ncards;
+		profp->ncontroller = ncontrollers;
 		return CAPI_NOERROR;
 	}
-	card = get_capi_ctr_by_nr(contr);
-	if (!card || card->cardstate != CARD_RUNNING) 
-		return CAPI_REGNOTINSTALLED;
 
-	memcpy((void *) profp, &card->profile,
-			sizeof(struct capi_profile));
-	return CAPI_NOERROR;
+	mutex_lock(&capi_controller_lock);
+
+	ctr = get_capi_ctr_by_nr(contr);
+	if (ctr && ctr->state == CAPI_CTR_RUNNING) {
+		memcpy(profp, &ctr->profile, sizeof(struct capi_profile));
+		ret = CAPI_NOERROR;
+	} else
+		ret = CAPI_REGNOTINSTALLED;
+
+	mutex_unlock(&capi_controller_lock);
+	return ret;
 }
 
 EXPORT_SYMBOL(capi20_get_profile);
 
+/* Must be called with capi_controller_lock held. */
+static int wait_on_ctr_state(struct capi_ctr *ctr, unsigned int state)
+{
+	DEFINE_WAIT(wait);
+	int retval = 0;
+
+	ctr = capi_ctr_get(ctr);
+	if (!ctr)
+		return -ESRCH;
+
+	for (;;) {
+		prepare_to_wait(&ctr->state_wait_queue, &wait,
+				TASK_INTERRUPTIBLE);
+
+		if (ctr->state == state)
+			break;
+		if (ctr->state == CAPI_CTR_DETACHED) {
+			retval = -ESRCH;
+			break;
+		}
+		if (signal_pending(current)) {
+			retval = -EINTR;
+			break;
+		}
+
+		mutex_unlock(&capi_controller_lock);
+		schedule();
+		mutex_lock(&capi_controller_lock);
+	}
+	finish_wait(&ctr->state_wait_queue, &wait);
+
+	capi_ctr_put(ctr);
+
+	return retval;
+}
+
 #ifdef AVMB1_COMPAT
 static int old_capi_manufacturer(unsigned int cmd, void __user *data)
 {
@@ -895,11 +1008,10 @@ static int old_capi_manufacturer(unsigne
 	avmb1_extcarddef cdef;
 	avmb1_resetdef rdef;
 	capicardparams cparams;
-	struct capi_ctr *card;
+	struct capi_ctr *ctr;
 	struct capi_driver *driver = NULL;
 	capiloaddata ldata;
 	struct list_head *l;
-	unsigned long flags;
 	int retval;
 
 	switch (cmd) {
@@ -919,7 +1031,8 @@ static int old_capi_manufacturer(unsigne
 		cparams.irq = cdef.irq;
 		cparams.cardnr = cdef.cardnr;
 
-		read_lock_irqsave(&capi_drivers_list_lock, flags);
+		mutex_lock(&capi_drivers_lock);
+
                 switch (cdef.cardtype) {
 			case AVM_CARDTYPE_B1:
 				list_for_each(l, &capi_drivers) {
@@ -940,18 +1053,15 @@ static int old_capi_manufacturer(unsigne
 				break;
 		}
 		if (!driver) {
-			read_unlock_irqrestore(&capi_drivers_list_lock, flags);
 			printk(KERN_ERR "kcapi: driver not loaded.\n");
-			return -EIO;
-		}
-		if (!driver->add_card) {
-			read_unlock_irqrestore(&capi_drivers_list_lock, flags);
+			retval = -EIO;
+		} else if (!driver->add_card) {
 			printk(KERN_ERR "kcapi: driver has no add card function.\n");
-			return -EIO;
-		}
+			retval = -EIO;
+		} else
+			retval = driver->add_card(driver, &cparams);
 
-		retval = driver->add_card(driver, &cparams);
-		read_unlock_irqrestore(&capi_drivers_list_lock, flags);
+		mutex_unlock(&capi_drivers_lock);
 		return retval;
 
 	case AVMB1_LOAD:
@@ -968,27 +1078,30 @@ static int old_capi_manufacturer(unsigne
 					   sizeof(avmb1_loadandconfigdef)))
 				return -EFAULT;
 		}
-		card = get_capi_ctr_by_nr(ldef.contr);
-		if (!card)
-			return -EINVAL;
-		card = capi_ctr_get(card);
-		if (!card)
-			return -ESRCH;
-		if (card->load_firmware == NULL) {
+
+		mutex_lock(&capi_controller_lock);
+
+		ctr = get_capi_ctr_by_nr(ldef.contr);
+		if (!ctr) {
+			retval = -EINVAL;
+			goto load_unlock_out;
+		}
+
+		if (ctr->load_firmware == NULL) {
 			printk(KERN_DEBUG "kcapi: load: no load function\n");
-			capi_ctr_put(card);
-			return -ESRCH;
+			retval = -ESRCH;
+			goto load_unlock_out;
 		}
 
 		if (ldef.t4file.len <= 0) {
 			printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len);
-			capi_ctr_put(card);
-			return -EINVAL;
+			retval = -EINVAL;
+			goto load_unlock_out;
 		}
 		if (ldef.t4file.data == NULL) {
 			printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n");
-			capi_ctr_put(card);
-			return -EINVAL;
+			retval = -EINVAL;
+			goto load_unlock_out;
 		}
 
 		ldata.firmware.user = 1;
@@ -998,54 +1111,49 @@ static int old_capi_manufacturer(unsigne
 		ldata.configuration.data = ldef.t4config.data;
 		ldata.configuration.len = ldef.t4config.len;
 
-		if (card->cardstate != CARD_DETECTED) {
+		if (ctr->state != CAPI_CTR_DETECTED) {
 			printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr);
-			capi_ctr_put(card);
-			return -EBUSY;
+			retval = -EBUSY;
+			goto load_unlock_out;
 		}
-		card->cardstate = CARD_LOADING;
-
-		retval = card->load_firmware(card, &ldata);
+		ctr->state = CAPI_CTR_LOADING;
 
+		retval = ctr->load_firmware(ctr, &ldata);
 		if (retval) {
-			card->cardstate = CARD_DETECTED;
-			capi_ctr_put(card);
-			return retval;
+			ctr->state = CAPI_CTR_DETECTED;
+			goto load_unlock_out;
 		}
 
-		while (card->cardstate != CARD_RUNNING) {
-
-			msleep_interruptible(100);	/* 0.1 sec */
+		retval = wait_on_ctr_state(ctr, CAPI_CTR_RUNNING);
 
-			if (signal_pending(current)) {
-				capi_ctr_put(card);
-				return -EINTR;
-			}
-		}
-		capi_ctr_put(card);
-		return 0;
+load_unlock_out:
+		mutex_unlock(&capi_controller_lock);
+		return retval;
 
 	case AVMB1_RESETCARD:
 		if (copy_from_user(&rdef, data, sizeof(avmb1_resetdef)))
 			return -EFAULT;
-		card = get_capi_ctr_by_nr(rdef.contr);
-		if (!card)
-			return -ESRCH;
 
-		if (card->cardstate == CARD_DETECTED)
-			return 0;
+		retval = 0;
 
-		card->reset_ctr(card);
+		mutex_lock(&capi_controller_lock);
 
-		while (card->cardstate > CARD_DETECTED) {
+		ctr = get_capi_ctr_by_nr(rdef.contr);
+		if (!ctr) {
+			retval = -ESRCH;
+			goto reset_unlock_out;
+		}
 
-			msleep_interruptible(100);	/* 0.1 sec */
+		if (ctr->state == CAPI_CTR_DETECTED)
+			goto reset_unlock_out;
 
-			if (signal_pending(current))
-				return -EINTR;
-		}
-		return 0;
+		ctr->reset_ctr(ctr);
 
+		retval = wait_on_ctr_state(ctr, CAPI_CTR_DETECTED);
+
+reset_unlock_out:
+		mutex_unlock(&capi_controller_lock);
+		return retval;
 	}
 	return -EINVAL;
 }
@@ -1062,7 +1170,8 @@ static int old_capi_manufacturer(unsigne
 
 int capi20_manufacturer(unsigned int cmd, void __user *data)
 {
-        struct capi_ctr *card;
+	struct capi_ctr *ctr;
+	int retval;
 
 	switch (cmd) {
 #ifdef AVMB1_COMPAT
@@ -1080,14 +1189,20 @@ int capi20_manufacturer(unsigned int cmd
 		if (copy_from_user(&fdef, data, sizeof(kcapi_flagdef)))
 			return -EFAULT;
 
-		card = get_capi_ctr_by_nr(fdef.contr);
-		if (!card)
-			return -ESRCH;
+		mutex_lock(&capi_controller_lock);
 
-		card->traceflag = fdef.flag;
-		printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n",
-			card->cnr, card->traceflag);
-		return 0;
+		ctr = get_capi_ctr_by_nr(fdef.contr);
+		if (ctr) {
+			ctr->traceflag = fdef.flag;
+			printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n",
+			       ctr->cnr, ctr->traceflag);
+			retval = 0;
+		} else
+			retval = -ESRCH;
+
+		mutex_unlock(&capi_controller_lock);
+
+		return retval;
 	}
 	case KCAPI_CMD_ADDCARD:
 	{
@@ -1095,7 +1210,6 @@ int capi20_manufacturer(unsigned int cmd
 		struct capi_driver *driver = NULL;
 		capicardparams cparams;
 		kcapi_carddef cdef;
-		int retval;
 
 		if ((retval = copy_from_user(&cdef, data, sizeof(cdef))))
 			return retval;
@@ -1107,6 +1221,8 @@ int capi20_manufacturer(unsigned int cmd
 		cparams.cardtype = 0;
 		cdef.driver[sizeof(cdef.driver)-1] = 0;
 
+		mutex_lock(&capi_drivers_lock);
+
 		list_for_each(l, &capi_drivers) {
 			driver = list_entry(l, struct capi_driver, list);
 			if (strcmp(driver->name, cdef.driver) == 0)
@@ -1115,15 +1231,15 @@ int capi20_manufacturer(unsigned int cmd
 		if (driver == NULL) {
 			printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n",
 					cdef.driver);
-			return -ESRCH;
-		}
-
-		if (!driver->add_card) {
+			retval = -ESRCH;
+		} else if (!driver->add_card) {
 			printk(KERN_ERR "kcapi: driver \"%s\" has no add card function.\n", cdef.driver);
-			return -EIO;
-		}
+			retval = -EIO;
+		} else
+			retval = driver->add_card(driver, &cparams);
 
-		return driver->add_card(driver, &cparams);
+		mutex_unlock(&capi_drivers_lock);
+		return retval;
 	}
 
 	default:
@@ -1137,30 +1253,6 @@ 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))
-{
-	ap->callback = callback;
-}
-
-EXPORT_SYMBOL(capi20_set_callback);
-
 /* ------------------------------------------------------------- */
 /* -------- Init & Cleanup ------------------------------------- */
 /* ------------------------------------------------------------- */
@@ -1169,27 +1261,21 @@ EXPORT_SYMBOL(capi20_set_callback);
  * init / exit functions
  */
 
+static struct notifier_block capictr_nb = {
+	.notifier_call = notify_handler,
+	.priority = INT_MAX,
+};
+
 static int __init kcapi_init(void)
 {
-	char *p;
-	char rev[32];
-	int ret;
-
-	ret = cdebug_init();
-	if (ret)
-		return ret;
-        kcapi_proc_init();
-
-	if ((p = strchr(revision, ':')) != NULL && p[1]) {
-		strlcpy(rev, p + 2, sizeof(rev));
-		if ((p = strchr(rev, '$')) != NULL && p > rev)
-		   *(p-1) = 0;
-	} else
-		strcpy(rev, "1.0");
+	int err;
 
-        printk(KERN_NOTICE "CAPI Subsystem Rev %s\n", rev);
+	register_capictr_notifier(&capictr_nb);
 
-	return 0;
+	err = cdebug_init();
+	if (!err)
+		kcapi_proc_init();
+	return err;
 }
 
 static void __exit kcapi_exit(void)
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/capi/kcapi.h linux-libre-2.6.34-gnu1/drivers/isdn/capi/kcapi.h
--- linux-libre-2.6.33-gnu1/drivers/isdn/capi/kcapi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/capi/kcapi.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,16 +24,19 @@ printk(KERN_DEBUG "%s: " format "\n" , _
 #endif
 
 enum {
-	CARD_DETECTED = 1,
-	CARD_LOADING  =	2,
-	CARD_RUNNING  = 3,
+	CAPI_CTR_DETACHED = 0,
+	CAPI_CTR_DETECTED = 1,
+	CAPI_CTR_LOADING  = 2,
+	CAPI_CTR_RUNNING  = 3,
 };
 
 extern struct list_head capi_drivers;
-extern rwlock_t capi_drivers_list_lock;
+extern struct mutex capi_drivers_lock;
+
+extern struct capi_ctr *capi_controller[CAPI_MAXCONTR];
+extern struct mutex capi_controller_lock;
 
 extern struct capi20_appl *capi_applications[CAPI_MAXAPPL];
-extern struct capi_ctr *capi_cards[CAPI_MAXCONTR];
 
 #ifdef CONFIG_PROC_FS
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/capi/kcapi_proc.c linux-libre-2.6.34-gnu1/drivers/isdn/capi/kcapi_proc.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/capi/kcapi_proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/capi/kcapi_proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,13 +15,12 @@
 #include <linux/seq_file.h>
 #include <linux/init.h>
 
-static char *
-cardstate2str(unsigned short cardstate)
+static char *state2str(unsigned short state)
 {
-	switch (cardstate) {
-	case CARD_DETECTED:	return "detected";
-	case CARD_LOADING:	return "loading";
-	case CARD_RUNNING:	return "running";
+	switch (state) {
+	case CAPI_CTR_DETECTED:	return "detected";
+	case CAPI_CTR_LOADING:	return "loading";
+	case CAPI_CTR_RUNNING:	return "running";
 	default:	        return "???";
 	}
 }
@@ -36,9 +35,12 @@ cardstate2str(unsigned short cardstate)
 // ---------------------------------------------------------------------------
 
 static void *controller_start(struct seq_file *seq, loff_t *pos)
+	__acquires(capi_controller_lock)
 {
+	mutex_lock(&capi_controller_lock);
+
 	if (*pos < CAPI_MAXCONTR)
-		return &capi_cards[*pos];
+		return &capi_controller[*pos];
 
 	return NULL;
 }
@@ -47,13 +49,15 @@ static void *controller_next(struct seq_
 {
 	++*pos;
 	if (*pos < CAPI_MAXCONTR)
-		return &capi_cards[*pos];
+		return &capi_controller[*pos];
 
 	return NULL;
 }
 
 static void controller_stop(struct seq_file *seq, void *v)
+	__releases(capi_controller_lock)
 {
+	mutex_unlock(&capi_controller_lock);
 }
 
 static int controller_show(struct seq_file *seq, void *v)
@@ -65,7 +69,7 @@ static int controller_show(struct seq_fi
 
 	seq_printf(seq, "%d %-10s %-8s %-16s %s\n",
 		   ctr->cnr, ctr->driver_name,
-		   cardstate2str(ctr->cardstate),
+		   state2str(ctr->state),
 		   ctr->name,
 		   ctr->procinfo ?  ctr->procinfo(ctr) : "");
 
@@ -135,9 +139,11 @@ static const struct file_operations proc
 //      applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
 // ---------------------------------------------------------------------------
 
-static void *
-applications_start(struct seq_file *seq, loff_t *pos)
+static void *applications_start(struct seq_file *seq, loff_t *pos)
+	__acquires(capi_controller_lock)
 {
+	mutex_lock(&capi_controller_lock);
+
 	if (*pos < CAPI_MAXAPPL)
 		return &capi_applications[*pos];
 
@@ -154,9 +160,10 @@ applications_next(struct seq_file *seq,
 	return NULL;
 }
 
-static void
-applications_stop(struct seq_file *seq, void *v)
+static void applications_stop(struct seq_file *seq, void *v)
+	__releases(capi_controller_lock)
 {
+	mutex_unlock(&capi_controller_lock);
 }
 
 static int
@@ -239,9 +246,9 @@ static const struct file_operations proc
 // ---------------------------------------------------------------------------
 
 static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
-	__acquires(&capi_drivers_list_lock)
+	__acquires(&capi_drivers_lock)
 {
-	read_lock(&capi_drivers_list_lock);
+	mutex_lock(&capi_drivers_lock);
 	return seq_list_start(&capi_drivers, *pos);
 }
 
@@ -251,9 +258,9 @@ static void *capi_driver_next(struct seq
 }
 
 static void capi_driver_stop(struct seq_file *seq, void *v)
-	__releases(&capi_drivers_list_lock)
+	__releases(&capi_drivers_lock)
 {
-	read_unlock(&capi_drivers_list_lock);
+	mutex_unlock(&capi_drivers_lock);
 }
 
 static int capi_driver_show(struct seq_file *seq, void *v)
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/capi/Kconfig linux-libre-2.6.34-gnu1/drivers/isdn/capi/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/isdn/capi/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/capi/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -17,8 +17,7 @@ config CAPI_TRACE
 	  If unsure, say Y.
 
 config ISDN_CAPI_MIDDLEWARE
-	bool "CAPI2.0 Middleware support (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
+	bool "CAPI2.0 Middleware support"
 	help
 	  This option will enhance the capabilities of the /dev/capi20
 	  interface.  It will provide a means of moving a data connection,
@@ -35,18 +34,19 @@ config ISDN_CAPI_CAPI20
 	  Y/M here.
 
 config ISDN_CAPI_CAPIFS_BOOL
-	bool "CAPI2.0 filesystem support"
+	bool "CAPI2.0 filesystem support (DEPRECATED)"
 	depends on ISDN_CAPI_MIDDLEWARE && ISDN_CAPI_CAPI20
+	help
+	  This option provides a special file system, similar to /dev/pts with
+	  device nodes for the special ttys established by using the
+	  middleware extension above.
+	  You no longer need this, udev fully replaces it. This feature is
+	  scheduled for removal.
 
 config ISDN_CAPI_CAPIFS
 	tristate
 	depends on ISDN_CAPI_CAPIFS_BOOL
 	default ISDN_CAPI_CAPI20
-	help
-	  This option provides a special file system, similar to /dev/pts with
-	  device nodes for the special ttys established by using the
-	  middleware extension above. If you want to use pppd with
-	  pppdcapiplugin to dial up to your ISP, say Y here.
 
 config ISDN_CAPI_CAPIDRV
 	tristate "CAPI2.0 capidrv interface support"
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/divert/divert_procfs.c linux-libre-2.6.34-gnu1/drivers/isdn/divert/divert_procfs.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/divert/divert_procfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/divert/divert_procfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #ifdef CONFIG_PROC_FS
 #include <linux/proc_fs.h>
 #else
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/divert/isdn_divert.c linux-libre-2.6.34-gnu1/drivers/isdn/divert/isdn_divert.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/divert/isdn_divert.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/divert/isdn_divert.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/jiffies.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/asyncdata.c linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/asyncdata.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/asyncdata.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/asyncdata.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,8 @@ static inline int muststuff(unsigned cha
  * Append received bytes to the command response buffer and forward them
  * line by line to the response handler. Exit whenever a mode/state change
  * might have occurred.
+ * Note: Received lines may be terminated by CR, LF, or CR LF, which will be
+ * removed before passing the line to the response handler.
  * Return value:
  *	number of processed bytes
  */
@@ -65,14 +67,14 @@ static unsigned cmd_loop(unsigned numbyt
 			/* --v-- fall through --v-- */
 		case '\r':
 			/* end of message line, pass to response handler */
-			gig_dbg(DEBUG_TRANSCMD, "%s: End of Message (%d Bytes)",
-				__func__, cbytes);
 			if (cbytes >= MAX_RESP_SIZE) {
 				dev_warn(cs->dev, "response too large (%d)\n",
 					 cbytes);
 				cbytes = MAX_RESP_SIZE;
 			}
 			cs->cbytes = cbytes;
+			gigaset_dbg_buffer(DEBUG_TRANSCMD, "received response",
+					   cbytes, cs->respdata);
 			gigaset_handle_modem_response(cs);
 			cbytes = 0;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/bas-gigaset.c linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/bas-gigaset.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/bas-gigaset.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/bas-gigaset.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,11 +14,6 @@
  */
 
 #include "gigaset.h"
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/timer.h>
 #include <linux/usb.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -347,12 +342,7 @@ static inline void error_hangup(struct b
 {
 	struct cardstate *cs = bcs->cs;
 
-	gig_dbg(DEBUG_ANY, "%s: scheduling HUP for channel %d",
-		__func__, bcs->channel);
-
-	if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL))
-		dev_err(cs->dev, "event queue full\n");
-
+	gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL);
 	gigaset_schedule_event(cs);
 }
 
@@ -1706,8 +1696,7 @@ static void complete_cb(struct cardstate
 
 	/* unqueue completed buffer */
 	cs->cmdbytes -= cs->curlen;
-	gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD,
-		"write_command: sent %u bytes, %u left",
+	gig_dbg(DEBUG_OUTPUT, "write_command: sent %u bytes, %u left",
 		cs->curlen, cs->cmdbytes);
 	if (cb->next != NULL) {
 		cs->cmdbuf = cb->next;
@@ -1881,13 +1870,13 @@ static int start_cbsend(struct cardstate
 
 	/* check if suspend requested */
 	if (ucs->basstate & BS_SUSPEND) {
-		gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "suspending");
+		gig_dbg(DEBUG_OUTPUT, "suspending");
 		return -EHOSTUNREACH;
 	}
 
 	/* check if AT channel is open */
 	if (!(ucs->basstate & BS_ATOPEN)) {
-		gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "AT channel not open");
+		gig_dbg(DEBUG_OUTPUT, "AT channel not open");
 		rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT);
 		if (rc < 0) {
 			/* flush command queue */
@@ -2251,7 +2240,7 @@ static int gigaset_probe(struct usb_inte
 	int i, j;
 	int rc;
 
-	gig_dbg(DEBUG_ANY,
+	gig_dbg(DEBUG_INIT,
 		"%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)",
 		__func__, le16_to_cpu(udev->descriptor.idVendor),
 		le16_to_cpu(udev->descriptor.idProduct));
@@ -2259,7 +2248,7 @@ static int gigaset_probe(struct usb_inte
 	/* set required alternate setting */
 	hostif = interface->cur_altsetting;
 	if (hostif->desc.bAlternateSetting != 3) {
-		gig_dbg(DEBUG_ANY,
+		gig_dbg(DEBUG_INIT,
 			"%s: wrong alternate setting %d - trying to switch",
 			__func__, hostif->desc.bAlternateSetting);
 		if (usb_set_interface(udev, hostif->desc.bInterfaceNumber, 3)
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/capi.c linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/capi.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/capi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/capi.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,8 @@
  */
 
 #include "gigaset.h"
-#include <linux/ctype.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/isdn/capilli.h>
 #include <linux/isdn/capicmd.h>
 #include <linux/isdn/capiutil.h>
@@ -169,20 +170,6 @@ static inline void ignore_cstruct_param(
 }
 
 /*
- * check for legal hex digit
- */
-static inline int ishexdigit(char c)
-{
-	if (c >= '0' && c <= '9')
-		return 1;
-	if (c >= 'A' && c <= 'F')
-		return 1;
-	if (c >= 'a' && c <= 'f')
-		return 1;
-	return 0;
-}
-
-/*
  * convert hex to binary
  */
 static inline u8 hex2bin(char c)
@@ -202,7 +189,7 @@ static int encode_ie(char *in, u8 *out,
 {
 	int l = 0;
 	while (*in) {
-		if (!ishexdigit(in[0]) || !ishexdigit(in[1]) || l >= maxlen)
+		if (!isxdigit(in[0]) || !isxdigit(in[1]) || l >= maxlen)
 			return -1;
 		out[++l] = (hex2bin(in[0]) << 4) + hex2bin(in[1]);
 		in += 2;
@@ -1313,7 +1300,7 @@ static void do_connect_req(struct gigase
 	}
 
 	/* check parameter: CIP Value */
-	if (cmsg->CIPValue > ARRAY_SIZE(cip2bchlc) ||
+	if (cmsg->CIPValue >= ARRAY_SIZE(cip2bchlc) ||
 	    (cmsg->CIPValue > 0 && cip2bchlc[cmsg->CIPValue].bc == NULL)) {
 		dev_notice(cs->dev, "%s: unknown CIP value %d\n",
 			   "CONNECT_REQ", cmsg->CIPValue);
@@ -1425,9 +1412,10 @@ static void do_connect_req(struct gigase
 
 	/* queue & schedule EV_DIAL event */
 	if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, commands,
-			       bcs->at_state.seq_index, NULL))
-		goto oom;
-	gig_dbg(DEBUG_CMD, "scheduling DIAL");
+			       bcs->at_state.seq_index, NULL)) {
+		info = CAPI_MSGOSRESOURCEERR;
+		goto error;
+	}
 	gigaset_schedule_event(cs);
 	ap->connected = APCONN_SETUP;
 	send_conf(iif, ap, skb, CapiSuccess);
@@ -1541,7 +1529,6 @@ static void do_connect_resp(struct gigas
 		if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
 				       EV_ACCEPT, NULL, 0, NULL))
 			return;
-		gig_dbg(DEBUG_CMD, "scheduling ACCEPT");
 		gigaset_schedule_event(cs);
 		return;
 
@@ -1582,7 +1569,6 @@ static void do_connect_resp(struct gigas
 		if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
 				       EV_HUP, NULL, 0, NULL))
 			return;
-		gig_dbg(DEBUG_CMD, "scheduling HUP");
 		gigaset_schedule_event(cs);
 		return;
 	}
@@ -1665,11 +1651,9 @@ static void do_connect_b3_resp(struct gi
 		/* trigger hangup, causing eventual DISCONNECT_IND */
 		if (!gigaset_add_event(cs, &bcs->at_state,
 				       EV_HUP, NULL, 0, NULL)) {
-			dev_err(cs->dev, "%s: out of memory\n", __func__);
 			dev_kfree_skb_any(skb);
 			return;
 		}
-		gig_dbg(DEBUG_CMD, "scheduling HUP");
 		gigaset_schedule_event(cs);
 
 		/* emit DISCONNECT_B3_IND */
@@ -1768,11 +1752,9 @@ static void do_disconnect_req(struct gig
 
 	/* trigger hangup, causing eventual DISCONNECT_IND */
 	if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) {
-		dev_err(cs->dev, "%s: out of memory\n", __func__);
 		send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
 		return;
 	}
-	gig_dbg(DEBUG_CMD, "scheduling HUP");
 	gigaset_schedule_event(cs);
 
 	/* emit reply */
@@ -1815,11 +1797,9 @@ static void do_disconnect_b3_req(struct
 	/* trigger hangup, causing eventual DISCONNECT_B3_IND */
 	if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
 			       EV_HUP, NULL, 0, NULL)) {
-		dev_err(cs->dev, "%s: out of memory\n", __func__);
 		send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
 		return;
 	}
-	gig_dbg(DEBUG_CMD, "scheduling HUP");
 	gigaset_schedule_event(cs);
 
 	/* NCPI parameter: not applicable for B3 Transparent */
@@ -2106,35 +2086,22 @@ static char *gigaset_procinfo(struct cap
 	return ctr->name;	/* ToDo: more? */
 }
 
-/**
- * gigaset_ctr_read_proc() - build controller proc file entry
- * @page:	buffer of PAGE_SIZE bytes for receiving the entry.
- * @start:	unused.
- * @off:	unused.
- * @count:	unused.
- * @eof:	unused.
- * @ctr:	controller descriptor structure.
- *
- * Return value: length of generated entry
- */
-static int gigaset_ctr_read_proc(char *page, char **start, off_t off,
-			  int count, int *eof, struct capi_ctr *ctr)
+static int gigaset_proc_show(struct seq_file *m, void *v)
 {
+	struct capi_ctr *ctr = m->private;
 	struct cardstate *cs = ctr->driverdata;
 	char *s;
 	int i;
-	int len = 0;
-	len += sprintf(page+len, "%-16s %s\n", "name", ctr->name);
-	len += sprintf(page+len, "%-16s %s %s\n", "dev",
+
+	seq_printf(m, "%-16s %s\n", "name", ctr->name);
+	seq_printf(m, "%-16s %s %s\n", "dev",
 			dev_driver_string(cs->dev), dev_name(cs->dev));
-	len += sprintf(page+len, "%-16s %d\n", "id", cs->myid);
+	seq_printf(m, "%-16s %d\n", "id", cs->myid);
 	if (cs->gotfwver)
-		len += sprintf(page+len, "%-16s %d.%d.%d.%d\n", "firmware",
+		seq_printf(m, "%-16s %d.%d.%d.%d\n", "firmware",
 			cs->fwver[0], cs->fwver[1], cs->fwver[2], cs->fwver[3]);
-	len += sprintf(page+len, "%-16s %d\n", "channels",
-			cs->channels);
-	len += sprintf(page+len, "%-16s %s\n", "onechannel",
-			cs->onechannel ? "yes" : "no");
+	seq_printf(m, "%-16s %d\n", "channels", cs->channels);
+	seq_printf(m, "%-16s %s\n", "onechannel", cs->onechannel ? "yes" : "no");
 
 	switch (cs->mode) {
 	case M_UNKNOWN:
@@ -2152,7 +2119,7 @@ static int gigaset_ctr_read_proc(char *p
 	default:
 		s = "??";
 	}
-	len += sprintf(page+len, "%-16s %s\n", "mode", s);
+	seq_printf(m, "%-16s %s\n", "mode", s);
 
 	switch (cs->mstate) {
 	case MS_UNINITIALIZED:
@@ -2176,25 +2143,21 @@ static int gigaset_ctr_read_proc(char *p
 	default:
 		s = "??";
 	}
-	len += sprintf(page+len, "%-16s %s\n", "mstate", s);
+	seq_printf(m, "%-16s %s\n", "mstate", s);
 
-	len += sprintf(page+len, "%-16s %s\n", "running",
-			cs->running ? "yes" : "no");
-	len += sprintf(page+len, "%-16s %s\n", "connected",
-			cs->connected ? "yes" : "no");
-	len += sprintf(page+len, "%-16s %s\n", "isdn_up",
-			cs->isdn_up ? "yes" : "no");
-	len += sprintf(page+len, "%-16s %s\n", "cidmode",
-			cs->cidmode ? "yes" : "no");
+	seq_printf(m, "%-16s %s\n", "running", cs->running ? "yes" : "no");
+	seq_printf(m, "%-16s %s\n", "connected", cs->connected ? "yes" : "no");
+	seq_printf(m, "%-16s %s\n", "isdn_up", cs->isdn_up ? "yes" : "no");
+	seq_printf(m, "%-16s %s\n", "cidmode", cs->cidmode ? "yes" : "no");
 
 	for (i = 0; i < cs->channels; i++) {
-		len += sprintf(page+len, "[%d]%-13s %d\n", i, "corrupted",
+		seq_printf(m, "[%d]%-13s %d\n", i, "corrupted",
 				cs->bcs[i].corrupted);
-		len += sprintf(page+len, "[%d]%-13s %d\n", i, "trans_down",
+		seq_printf(m, "[%d]%-13s %d\n", i, "trans_down",
 				cs->bcs[i].trans_down);
-		len += sprintf(page+len, "[%d]%-13s %d\n", i, "trans_up",
+		seq_printf(m, "[%d]%-13s %d\n", i, "trans_up",
 				cs->bcs[i].trans_up);
-		len += sprintf(page+len, "[%d]%-13s %d\n", i, "chstate",
+		seq_printf(m, "[%d]%-13s %d\n", i, "chstate",
 				cs->bcs[i].chstate);
 		switch (cs->bcs[i].proto2) {
 		case L2_BITSYNC:
@@ -2209,42 +2172,42 @@ static int gigaset_ctr_read_proc(char *p
 		default:
 			s = "??";
 		}
-		len += sprintf(page+len, "[%d]%-13s %s\n", i, "proto2", s);
+		seq_printf(m, "[%d]%-13s %s\n", i, "proto2", s);
 	}
-	return len;
+	return 0;
 }
 
+static int gigaset_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, gigaset_proc_show, PDE(inode)->data);
+}
 
-static struct capi_driver capi_driver_gigaset = {
-	.name		= "gigaset",
-	.revision	= "1.0",
+static const struct file_operations gigaset_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= gigaset_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
 };
 
 /**
- * gigaset_isdn_register() - register to LL
+ * gigaset_isdn_regdev() - register device to LL
  * @cs:		device descriptor structure.
  * @isdnid:	device name.
  *
- * Called by main module to register the device with the LL.
- *
  * Return value: 1 for success, 0 for failure
  */
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
 {
 	struct gigaset_capi_ctr *iif;
 	int rc;
 
-	pr_info("Kernel CAPI interface\n");
-
 	iif = kmalloc(sizeof(*iif), GFP_KERNEL);
 	if (!iif) {
 		pr_err("%s: out of memory\n", __func__);
 		return 0;
 	}
 
-	/* register driver with CAPI (ToDo: what for?) */
-	register_capi_driver(&capi_driver_gigaset);
-
 	/* prepare controller structure */
 	iif->ctr.owner         = THIS_MODULE;
 	iif->ctr.driverdata    = cs;
@@ -2256,7 +2219,7 @@ int gigaset_isdn_register(struct cardsta
 	iif->ctr.release_appl  = gigaset_release_appl;
 	iif->ctr.send_message  = gigaset_send_message;
 	iif->ctr.procinfo      = gigaset_procinfo;
-	iif->ctr.ctr_read_proc = gigaset_ctr_read_proc;
+	iif->ctr.proc_fops = &gigaset_proc_fops;
 	INIT_LIST_HEAD(&iif->appls);
 	skb_queue_head_init(&iif->sendqueue);
 	atomic_set(&iif->sendqlen, 0);
@@ -2265,7 +2228,6 @@ int gigaset_isdn_register(struct cardsta
 	rc = attach_capi_ctr(&iif->ctr);
 	if (rc) {
 		pr_err("attach_capi_ctr failed (%d)\n", rc);
-		unregister_capi_driver(&capi_driver_gigaset);
 		kfree(iif);
 		return 0;
 	}
@@ -2276,17 +2238,36 @@ int gigaset_isdn_register(struct cardsta
 }
 
 /**
- * gigaset_isdn_unregister() - unregister from LL
+ * gigaset_isdn_unregdev() - unregister device from LL
  * @cs:		device descriptor structure.
- *
- * Called by main module to unregister the device from the LL.
  */
-void gigaset_isdn_unregister(struct cardstate *cs)
+void gigaset_isdn_unregdev(struct cardstate *cs)
 {
 	struct gigaset_capi_ctr *iif = cs->iif;
 
 	detach_capi_ctr(&iif->ctr);
 	kfree(iif);
 	cs->iif = NULL;
+}
+
+static struct capi_driver capi_driver_gigaset = {
+	.name		= "gigaset",
+	.revision	= "1.0",
+};
+
+/**
+ * gigaset_isdn_regdrv() - register driver to LL
+ */
+void gigaset_isdn_regdrv(void)
+{
+	pr_info("Kernel CAPI interface\n");
+	register_capi_driver(&capi_driver_gigaset);
+}
+
+/**
+ * gigaset_isdn_unregdrv() - unregister driver from LL
+ */
+void gigaset_isdn_unregdrv(void)
+{
 	unregister_capi_driver(&capi_driver_gigaset);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/common.c linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/common.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/common.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
  */
 
 #include "gigaset.h"
-#include <linux/ctype.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 
@@ -149,10 +148,8 @@ static int test_timeout(struct at_state_
 		return 0;
 	}
 
-	if (!gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL,
-			       at_state->timer_index, NULL))
-			dev_err(at_state->cs->dev, "%s: out of memory\n",
-				__func__);
+	gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL,
+			  at_state->timer_index, NULL);
 	return 1;
 }
 
@@ -180,7 +177,7 @@ static void timer_tick(unsigned long dat
 	if (cs->running) {
 		mod_timer(&cs->timer, jiffies + msecs_to_jiffies(GIG_TICK));
 		if (timeout) {
-			gig_dbg(DEBUG_CMD, "scheduling timeout");
+			gig_dbg(DEBUG_EVENT, "scheduling timeout");
 			tasklet_schedule(&cs->event_tasklet);
 		}
 	}
@@ -194,14 +191,14 @@ int gigaset_get_channel(struct bc_state
 
 	spin_lock_irqsave(&bcs->cs->lock, flags);
 	if (bcs->use_count || !try_module_get(bcs->cs->driver->owner)) {
-		gig_dbg(DEBUG_ANY, "could not allocate channel %d",
+		gig_dbg(DEBUG_CHANNEL, "could not allocate channel %d",
 			bcs->channel);
 		spin_unlock_irqrestore(&bcs->cs->lock, flags);
 		return 0;
 	}
 	++bcs->use_count;
 	bcs->busy = 1;
-	gig_dbg(DEBUG_ANY, "allocated channel %d", bcs->channel);
+	gig_dbg(DEBUG_CHANNEL, "allocated channel %d", bcs->channel);
 	spin_unlock_irqrestore(&bcs->cs->lock, flags);
 	return 1;
 }
@@ -213,7 +210,7 @@ struct bc_state *gigaset_get_free_channe
 
 	spin_lock_irqsave(&cs->lock, flags);
 	if (!try_module_get(cs->driver->owner)) {
-		gig_dbg(DEBUG_ANY,
+		gig_dbg(DEBUG_CHANNEL,
 			"could not get module for allocating channel");
 		spin_unlock_irqrestore(&cs->lock, flags);
 		return NULL;
@@ -223,12 +220,12 @@ struct bc_state *gigaset_get_free_channe
 			++cs->bcs[i].use_count;
 			cs->bcs[i].busy = 1;
 			spin_unlock_irqrestore(&cs->lock, flags);
-			gig_dbg(DEBUG_ANY, "allocated channel %d", i);
+			gig_dbg(DEBUG_CHANNEL, "allocated channel %d", i);
 			return cs->bcs + i;
 		}
 	module_put(cs->driver->owner);
 	spin_unlock_irqrestore(&cs->lock, flags);
-	gig_dbg(DEBUG_ANY, "no free channel");
+	gig_dbg(DEBUG_CHANNEL, "no free channel");
 	return NULL;
 }
 
@@ -238,14 +235,15 @@ void gigaset_free_channel(struct bc_stat
 
 	spin_lock_irqsave(&bcs->cs->lock, flags);
 	if (!bcs->busy) {
-		gig_dbg(DEBUG_ANY, "could not free channel %d", bcs->channel);
+		gig_dbg(DEBUG_CHANNEL, "could not free channel %d",
+			bcs->channel);
 		spin_unlock_irqrestore(&bcs->cs->lock, flags);
 		return;
 	}
 	--bcs->use_count;
 	bcs->busy = 0;
 	module_put(bcs->cs->driver->owner);
-	gig_dbg(DEBUG_ANY, "freed channel %d", bcs->channel);
+	gig_dbg(DEBUG_CHANNEL, "freed channel %d", bcs->channel);
 	spin_unlock_irqrestore(&bcs->cs->lock, flags);
 }
 
@@ -258,14 +256,15 @@ int gigaset_get_channels(struct cardstat
 	for (i = 0; i < cs->channels; ++i)
 		if (cs->bcs[i].use_count) {
 			spin_unlock_irqrestore(&cs->lock, flags);
-			gig_dbg(DEBUG_ANY, "could not allocate all channels");
+			gig_dbg(DEBUG_CHANNEL,
+				"could not allocate all channels");
 			return 0;
 		}
 	for (i = 0; i < cs->channels; ++i)
 		++cs->bcs[i].use_count;
 	spin_unlock_irqrestore(&cs->lock, flags);
 
-	gig_dbg(DEBUG_ANY, "allocated all channels");
+	gig_dbg(DEBUG_CHANNEL, "allocated all channels");
 
 	return 1;
 }
@@ -275,7 +274,7 @@ void gigaset_free_channels(struct cardst
 	unsigned long flags;
 	int i;
 
-	gig_dbg(DEBUG_ANY, "unblocking all channels");
+	gig_dbg(DEBUG_CHANNEL, "unblocking all channels");
 	spin_lock_irqsave(&cs->lock, flags);
 	for (i = 0; i < cs->channels; ++i)
 		--cs->bcs[i].use_count;
@@ -287,7 +286,7 @@ void gigaset_block_channels(struct cards
 	unsigned long flags;
 	int i;
 
-	gig_dbg(DEBUG_ANY, "blocking all channels");
+	gig_dbg(DEBUG_CHANNEL, "blocking all channels");
 	spin_lock_irqsave(&cs->lock, flags);
 	for (i = 0; i < cs->channels; ++i)
 		++cs->bcs[i].use_count;
@@ -338,6 +337,8 @@ struct event_t *gigaset_add_event(struct
 	unsigned next, tail;
 	struct event_t *event = NULL;
 
+	gig_dbg(DEBUG_EVENT, "queueing event %d", type);
+
 	spin_lock_irqsave(&cs->ev_lock, flags);
 
 	tail = cs->ev_tail;
@@ -505,7 +506,7 @@ void gigaset_freecs(struct cardstate *cs
 	case 2: /* error in initcshw */
 		/* Deregister from LL */
 		make_invalid(cs, VALID_ID);
-		gigaset_isdn_unregister(cs);
+		gigaset_isdn_unregdev(cs);
 
 		/* fall through */
 	case 1: /* error when registering to LL */
@@ -767,7 +768,7 @@ struct cardstate *gigaset_initcs(struct
 	cs->cmdbytes = 0;
 
 	gig_dbg(DEBUG_INIT, "setting up iif");
-	if (!gigaset_isdn_register(cs, modulename)) {
+	if (!gigaset_isdn_regdev(cs, modulename)) {
 		pr_err("error registering ISDN device\n");
 		goto error;
 	}
@@ -934,11 +935,8 @@ int gigaset_start(struct cardstate *cs)
 
 	if (!gigaset_add_event(cs, &cs->at_state, EV_START, NULL, 0, NULL)) {
 		cs->waiting = 0;
-		dev_err(cs->dev, "%s: out of memory\n", __func__);
 		goto error;
 	}
-
-	gig_dbg(DEBUG_CMD, "scheduling START");
 	gigaset_schedule_event(cs);
 
 	wait_event(cs->waitqueue, !cs->waiting);
@@ -973,12 +971,8 @@ int gigaset_shutdown(struct cardstate *c
 
 	cs->waiting = 1;
 
-	if (!gigaset_add_event(cs, &cs->at_state, EV_SHUTDOWN, NULL, 0, NULL)) {
-		dev_err(cs->dev, "%s: out of memory\n", __func__);
+	if (!gigaset_add_event(cs, &cs->at_state, EV_SHUTDOWN, NULL, 0, NULL))
 		goto exit;
-	}
-
-	gig_dbg(DEBUG_CMD, "scheduling SHUTDOWN");
 	gigaset_schedule_event(cs);
 
 	wait_event(cs->waitqueue, !cs->waiting);
@@ -1004,12 +998,8 @@ void gigaset_stop(struct cardstate *cs)
 
 	cs->waiting = 1;
 
-	if (!gigaset_add_event(cs, &cs->at_state, EV_STOP, NULL, 0, NULL)) {
-		dev_err(cs->dev, "%s: out of memory\n", __func__);
+	if (!gigaset_add_event(cs, &cs->at_state, EV_STOP, NULL, 0, NULL))
 		goto exit;
-	}
-
-	gig_dbg(DEBUG_CMD, "scheduling STOP");
 	gigaset_schedule_event(cs);
 
 	wait_event(cs->waitqueue, !cs->waiting);
@@ -1214,11 +1204,13 @@ static int __init gigaset_init_module(vo
 		gigaset_debuglevel = DEBUG_DEFAULT;
 
 	pr_info(DRIVER_DESC DRIVER_DESC_DEBUG "\n");
+	gigaset_isdn_regdrv();
 	return 0;
 }
 
 static void __exit gigaset_exit_module(void)
 {
+	gigaset_isdn_unregdrv();
 }
 
 module_init(gigaset_init_module);
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/dummyll.c linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/dummyll.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/dummyll.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/dummyll.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,12 +57,20 @@ void gigaset_isdn_stop(struct cardstate
 {
 }
 
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
 {
-	pr_info("no ISDN subsystem interface\n");
 	return 1;
 }
 
-void gigaset_isdn_unregister(struct cardstate *cs)
+void gigaset_isdn_unregdev(struct cardstate *cs)
+{
+}
+
+void gigaset_isdn_regdrv(void)
+{
+	pr_info("no ISDN subsystem interface\n");
+}
+
+void gigaset_isdn_unregdrv(void)
 {
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/ev-layer.c linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/ev-layer.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/ev-layer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/ev-layer.c	2010-05-16 17:17:36.000000000 -0400
@@ -427,7 +427,7 @@ static int isdn_getnum(char *p)
 {
 	int v = -1;
 
-	gig_dbg(DEBUG_TRANSCMD, "string: %s", p);
+	gig_dbg(DEBUG_EVENT, "string: %s", p);
 
 	while (*p >= '0' && *p <= '9')
 		v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p++) - '0');
@@ -444,7 +444,7 @@ static int isdn_gethex(char *p)
 	int v = 0;
 	int c;
 
-	gig_dbg(DEBUG_TRANSCMD, "string: %s", p);
+	gig_dbg(DEBUG_EVENT, "string: %s", p);
 
 	if (!*p)
 		return -1;
@@ -517,7 +517,6 @@ void gigaset_handle_modem_response(struc
 		return;
 	}
 	cs->respdata[len] = 0;
-	gig_dbg(DEBUG_TRANSCMD, "raw string: '%s'", cs->respdata);
 	argv[0] = cs->respdata;
 	params = 1;
 	if (cs->at_state.getstring) {
@@ -552,14 +551,14 @@ void gigaset_handle_modem_response(struc
 		for (j = 1; j < params; ++j)
 			argv[j][-1] = 0;
 
-		gig_dbg(DEBUG_TRANSCMD, "CMD received: %s", argv[0]);
+		gig_dbg(DEBUG_EVENT, "CMD received: %s", argv[0]);
 		if (cid) {
 			--params;
-			gig_dbg(DEBUG_TRANSCMD, "CID: %s", argv[params]);
+			gig_dbg(DEBUG_EVENT, "CID: %s", argv[params]);
 		}
-		gig_dbg(DEBUG_TRANSCMD, "available params: %d", params - 1);
+		gig_dbg(DEBUG_EVENT, "available params: %d", params - 1);
 		for (j = 1; j < params; j++)
-			gig_dbg(DEBUG_TRANSCMD, "param %d: %s", j, argv[j]);
+			gig_dbg(DEBUG_EVENT, "param %d: %s", j, argv[j]);
 	}
 
 	spin_lock_irqsave(&cs->ev_lock, flags);
@@ -642,7 +641,7 @@ void gigaset_handle_modem_response(struc
 					dev_err(cs->dev, "out of memory\n");
 				++curarg;
 			}
-			gig_dbg(DEBUG_CMD, "string==%s",
+			gig_dbg(DEBUG_EVENT, "string==%s",
 				event->ptr ? (char *) event->ptr : "NULL");
 			break;
 		case RT_ZCAU:
@@ -669,7 +668,7 @@ void gigaset_handle_modem_response(struc
 				++curarg;
 			} else
 				event->parameter = -1;
-			gig_dbg(DEBUG_CMD, "parameter==%d", event->parameter);
+			gig_dbg(DEBUG_EVENT, "parameter==%d", event->parameter);
 			break;
 		}
 
@@ -684,7 +683,7 @@ void gigaset_handle_modem_response(struc
 	spin_unlock_irqrestore(&cs->ev_lock, flags);
 
 	if (curarg != params)
-		gig_dbg(DEBUG_ANY,
+		gig_dbg(DEBUG_EVENT,
 			"invalid number of processed parameters: %d/%d",
 			curarg, params);
 }
@@ -705,8 +704,8 @@ static void disconnect(struct at_state_t
 	/* revert to selected idle mode */
 	if (!cs->cidmode) {
 		cs->at_state.pending_commands |= PC_UMMODE;
+		gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE");
 		cs->commands_pending = 1;
-		gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE");
 	}
 	spin_unlock_irqrestore(&cs->lock, flags);
 
@@ -784,15 +783,15 @@ static void init_failed(struct cardstate
 static void schedule_init(struct cardstate *cs, int state)
 {
 	if (cs->at_state.pending_commands & PC_INIT) {
-		gig_dbg(DEBUG_CMD, "not scheduling PC_INIT again");
+		gig_dbg(DEBUG_EVENT, "not scheduling PC_INIT again");
 		return;
 	}
 	cs->mstate = state;
 	cs->mode = M_UNKNOWN;
 	gigaset_block_channels(cs);
 	cs->at_state.pending_commands |= PC_INIT;
+	gig_dbg(DEBUG_EVENT, "Scheduling PC_INIT");
 	cs->commands_pending = 1;
-	gig_dbg(DEBUG_CMD, "Scheduling PC_INIT");
 }
 
 /* Add "AT" to a command, add the cid, dle encode it, send the result to the
@@ -923,7 +922,7 @@ static void start_dial(struct at_state_t
 	}
 
 	at_state->pending_commands |= PC_CID;
-	gig_dbg(DEBUG_CMD, "Scheduling PC_CID");
+	gig_dbg(DEBUG_EVENT, "Scheduling PC_CID");
 	cs->commands_pending = 1;
 	return;
 
@@ -933,7 +932,7 @@ error:
 		commands[i] = NULL;
 	}
 	at_state->pending_commands |= PC_NOCID;
-	gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID");
+	gig_dbg(DEBUG_EVENT, "Scheduling PC_NOCID");
 	cs->commands_pending = 1;
 	return;
 }
@@ -955,7 +954,7 @@ static void start_accept(struct at_state
 		dev_err(at_state->cs->dev, "out of memory\n");
 		/* error reset */
 		at_state->pending_commands |= PC_HUP;
-		gig_dbg(DEBUG_CMD, "Scheduling PC_HUP");
+		gig_dbg(DEBUG_EVENT, "Scheduling PC_HUP");
 		cs->commands_pending = 1;
 		return;
 	}
@@ -964,7 +963,7 @@ static void start_accept(struct at_state
 	snprintf(bcs->commands[AT_ISO], 9, "^SISO=%u\r", bcs->channel + 1);
 
 	at_state->pending_commands |= PC_ACCEPT;
-	gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT");
+	gig_dbg(DEBUG_EVENT, "Scheduling PC_ACCEPT");
 	cs->commands_pending = 1;
 }
 
@@ -1009,8 +1008,8 @@ static void do_shutdown(struct cardstate
 	if (cs->mstate == MS_READY) {
 		cs->mstate = MS_SHUTDOWN;
 		cs->at_state.pending_commands |= PC_SHUTDOWN;
+		gig_dbg(DEBUG_EVENT, "Scheduling PC_SHUTDOWN");
 		cs->commands_pending = 1;
-		gig_dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN");
 	} else
 		finish_shutdown(cs);
 }
@@ -1191,8 +1190,8 @@ static void do_action(int action, struct
 		}
 		spin_unlock_irqrestore(&cs->lock, flags);
 		cs->at_state.pending_commands |= PC_CIDMODE;
+		gig_dbg(DEBUG_EVENT, "Scheduling PC_CIDMODE");
 		cs->commands_pending = 1;
-		gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE");
 		break;
 	case ACT_FAILINIT:
 		dev_warn(cs->dev, "Could not initialize the device.\n");
@@ -1259,14 +1258,10 @@ static void do_action(int action, struct
 		 * note that bcs may be NULL if no B channel is free
 		 */
 		at_state2->ConState = 700;
-		kfree(at_state2->str_var[STR_NMBR]);
-		at_state2->str_var[STR_NMBR] = NULL;
-		kfree(at_state2->str_var[STR_ZCPN]);
-		at_state2->str_var[STR_ZCPN] = NULL;
-		kfree(at_state2->str_var[STR_ZBC]);
-		at_state2->str_var[STR_ZBC] = NULL;
-		kfree(at_state2->str_var[STR_ZHLC]);
-		at_state2->str_var[STR_ZHLC] = NULL;
+		for (i = 0; i < STR_NUM; ++i) {
+			kfree(at_state2->str_var[i]);
+			at_state2->str_var[i] = NULL;
+		}
 		at_state2->int_var[VAR_ZCTP] = -1;
 
 		spin_lock_irqsave(&cs->lock, flags);
@@ -1443,7 +1438,7 @@ static void do_action(int action, struct
 	case ACT_GOTVER:
 		if (cs->gotfwver == 0) {
 			cs->gotfwver = 1;
-			gig_dbg(DEBUG_ANY,
+			gig_dbg(DEBUG_EVENT,
 				"firmware version %02d.%03d.%02d.%02d",
 				cs->fwver[0], cs->fwver[1],
 				cs->fwver[2], cs->fwver[3]);
@@ -1481,8 +1476,8 @@ static void do_action(int action, struct
 		break;
 	case ACT_HUP:
 		at_state->pending_commands |= PC_HUP;
+		gig_dbg(DEBUG_EVENT, "Scheduling PC_HUP");
 		cs->commands_pending = 1;
-		gig_dbg(DEBUG_CMD, "Scheduling PC_HUP");
 		break;
 
 	/* hotplug events */
@@ -1519,10 +1514,10 @@ static void do_action(int action, struct
 			cs->cidmode = ev->parameter;
 			if (ev->parameter) {
 				cs->at_state.pending_commands |= PC_CIDMODE;
-				gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE");
+				gig_dbg(DEBUG_EVENT, "Scheduling PC_CIDMODE");
 			} else {
 				cs->at_state.pending_commands |= PC_UMMODE;
-				gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE");
+				gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE");
 			}
 			cs->commands_pending = 1;
 		}
@@ -1573,6 +1568,8 @@ static void process_event(struct cardsta
 	if (ev->cid >= 0) {
 		at_state = at_state_from_cid(cs, ev->cid);
 		if (!at_state) {
+			gig_dbg(DEBUG_EVENT, "event %d for invalid cid %d",
+				ev->type, ev->cid);
 			gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID,
 					  NULL, 0, NULL);
 			return;
@@ -1580,13 +1577,13 @@ static void process_event(struct cardsta
 	} else {
 		at_state = ev->at_state;
 		if (at_state_invalid(cs, at_state)) {
-			gig_dbg(DEBUG_ANY, "event for invalid at_state %p",
+			gig_dbg(DEBUG_EVENT, "event for invalid at_state %p",
 				at_state);
 			return;
 		}
 	}
 
-	gig_dbg(DEBUG_CMD, "connection state %d, event %d",
+	gig_dbg(DEBUG_EVENT, "connection state %d, event %d",
 		at_state->ConState, ev->type);
 
 	bcs = at_state->bcs;
@@ -1600,11 +1597,11 @@ static void process_event(struct cardsta
 		if (ev->parameter != at_state->timer_index
 		    || !at_state->timer_active) {
 			ev->type = RSP_NONE; /* old timeout */
-			gig_dbg(DEBUG_ANY, "old timeout");
+			gig_dbg(DEBUG_EVENT, "old timeout");
 		} else if (!at_state->waiting)
-			gig_dbg(DEBUG_ANY, "timeout occurred");
+			gig_dbg(DEBUG_EVENT, "timeout occurred");
 		else
-			gig_dbg(DEBUG_ANY, "stopped waiting");
+			gig_dbg(DEBUG_EVENT, "stopped waiting");
 	}
 	spin_unlock_irqrestore(&cs->lock, flags);
 
@@ -1712,11 +1709,11 @@ static void process_command_flags(struct
 	cs->commands_pending = 0;
 
 	if (cs->cur_at_seq) {
-		gig_dbg(DEBUG_CMD, "not searching scheduled commands: busy");
+		gig_dbg(DEBUG_EVENT, "not searching scheduled commands: busy");
 		return;
 	}
 
-	gig_dbg(DEBUG_CMD, "searching scheduled commands");
+	gig_dbg(DEBUG_EVENT, "searching scheduled commands");
 
 	sequence = SEQ_NONE;
 
@@ -1857,7 +1854,7 @@ static void process_command_flags(struct
 			switch (cs->mode) {
 			case M_UNIMODEM:
 				cs->at_state.pending_commands |= PC_CIDMODE;
-				gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE");
+				gig_dbg(DEBUG_EVENT, "Scheduling PC_CIDMODE");
 				cs->commands_pending = 1;
 				return;
 #ifdef GIG_MAYINITONDIAL
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/gigaset.h linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/gigaset.h
--- linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/gigaset.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/gigaset.h	2010-05-16 17:17:36.000000000 -0400
@@ -20,10 +20,12 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
+#include <linux/sched.h>
 #include <linux/compiler.h>
 #include <linux/types.h>
+#include <linux/ctype.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <linux/usb.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/ppp_defs.h>
@@ -38,7 +40,7 @@
 #define GIG_COMPAT  {0, 4, 0, 0}
 
 #define MAX_REC_PARAMS 10	/* Max. number of params in response string */
-#define MAX_RESP_SIZE 512	/* Max. size of a response string */
+#define MAX_RESP_SIZE 511	/* Max. size of a response string */
 
 #define MAX_EVENTS 64		/* size of event queue */
 
@@ -78,9 +80,10 @@ enum debuglevel {
 	DEBUG_STREAM	  = 0x00040, /* application data stream I/O events */
 	DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */
 	DEBUG_LLDATA	  = 0x00100, /* sent/received LL data */
+	DEBUG_EVENT	  = 0x00200, /* event processing */
 	DEBUG_DRIVER	  = 0x00400, /* driver structure */
 	DEBUG_HDLC	  = 0x00800, /* M10x HDLC processing */
-	DEBUG_WRITE	  = 0x01000, /* M105 data write */
+	DEBUG_CHANNEL	  = 0x01000, /* channel allocation/deallocation */
 	DEBUG_TRANSCMD	  = 0x02000, /* AT-COMMANDS+RESPONSES */
 	DEBUG_MCMD	  = 0x04000, /* COMMANDS THAT ARE SENT VERY OFTEN */
 	DEBUG_INIT	  = 0x08000, /* (de)allocation+initialization of data
@@ -498,7 +501,7 @@ struct cardstate {
 	spinlock_t ev_lock;
 
 	/* current modem response */
-	unsigned char respdata[MAX_RESP_SIZE];
+	unsigned char respdata[MAX_RESP_SIZE+1];
 	unsigned cbytes;
 
 	/* private data of hardware drivers */
@@ -674,8 +677,10 @@ int gigaset_isowbuf_getbytes(struct isow
  */
 
 /* Called from common.c for setting up/shutting down with the ISDN subsystem */
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid);
-void gigaset_isdn_unregister(struct cardstate *cs);
+void gigaset_isdn_regdrv(void);
+void gigaset_isdn_unregdrv(void);
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid);
+void gigaset_isdn_unregdev(struct cardstate *cs);
 
 /* Called from hardware module to indicate completion of an skb */
 void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb);
@@ -785,8 +790,6 @@ static inline void gigaset_schedule_even
 static inline void gigaset_bchannel_down(struct bc_state *bcs)
 {
 	gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_CLOSED, NULL, 0, NULL);
-
-	gig_dbg(DEBUG_CMD, "scheduling BC_CLOSED");
 	gigaset_schedule_event(bcs->cs);
 }
 
@@ -795,8 +798,6 @@ static inline void gigaset_bchannel_down
 static inline void gigaset_bchannel_up(struct bc_state *bcs)
 {
 	gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_OPEN, NULL, 0, NULL);
-
-	gig_dbg(DEBUG_CMD, "scheduling BC_OPEN");
 	gigaset_schedule_event(bcs->cs);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/i4l.c linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/i4l.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/i4l.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/i4l.c	2010-05-16 17:17:36.000000000 -0400
@@ -216,7 +216,7 @@ static int command_from_LL(isdn_ctrl *cn
 		return -EINVAL;
 
 	case ISDN_CMD_DIAL:
-		gig_dbg(DEBUG_ANY,
+		gig_dbg(DEBUG_CMD,
 			"ISDN_CMD_DIAL (phone: %s, msn: %s, si1: %d, si2: %d)",
 			cntrl->parm.setup.phone, cntrl->parm.setup.eazmsn,
 			cntrl->parm.setup.si1, cntrl->parm.setup.si2);
@@ -304,11 +304,10 @@ static int command_from_LL(isdn_ctrl *cn
 			gigaset_free_channel(bcs);
 			return -ENOMEM;
 		}
-
-		gig_dbg(DEBUG_CMD, "scheduling DIAL");
 		gigaset_schedule_event(cs);
 		break;
 	case ISDN_CMD_ACCEPTD:
+		gig_dbg(DEBUG_CMD, "ISDN_CMD_ACCEPTD");
 		if (ch >= cs->channels) {
 			dev_err(cs->dev,
 				"ISDN_CMD_ACCEPTD: invalid channel (%d)\n", ch);
@@ -318,14 +317,11 @@ static int command_from_LL(isdn_ctrl *cn
 		if (!gigaset_add_event(cs, &bcs->at_state,
 				       EV_ACCEPT, NULL, 0, NULL))
 			return -ENOMEM;
-
-		gig_dbg(DEBUG_CMD, "scheduling ACCEPT");
 		gigaset_schedule_event(cs);
 
 		break;
-	case ISDN_CMD_ACCEPTB:
-		break;
 	case ISDN_CMD_HANGUP:
+		gig_dbg(DEBUG_CMD, "ISDN_CMD_HANGUP");
 		if (ch >= cs->channels) {
 			dev_err(cs->dev,
 				"ISDN_CMD_HANGUP: invalid channel (%d)\n", ch);
@@ -335,8 +331,6 @@ static int command_from_LL(isdn_ctrl *cn
 		if (!gigaset_add_event(cs, &bcs->at_state,
 				       EV_HUP, NULL, 0, NULL))
 			return -ENOMEM;
-
-		gig_dbg(DEBUG_CMD, "scheduling HUP");
 		gigaset_schedule_event(cs);
 
 		break;
@@ -376,6 +370,7 @@ static int command_from_LL(isdn_ctrl *cn
 		}
 		break;
 	case ISDN_CMD_SETL3: /* Set L3 to given protocol */
+		gig_dbg(DEBUG_CMD, "ISDN_CMD_SETL3");
 		if (ch >= cs->channels) {
 			dev_err(cs->dev,
 				"ISDN_CMD_SETL3: invalid channel (%d)\n", ch);
@@ -390,44 +385,9 @@ static int command_from_LL(isdn_ctrl *cn
 		}
 
 		break;
-	case ISDN_CMD_PROCEED:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_PROCEED");
-		break;
-	case ISDN_CMD_ALERT:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_ALERT");
-		if (cntrl->arg >= cs->channels) {
-			dev_err(cs->dev,
-				"ISDN_CMD_ALERT: invalid channel (%d)\n",
-				(int) cntrl->arg);
-			return -EINVAL;
-		}
-		break;
-	case ISDN_CMD_REDIR:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_REDIR");
-		break;
-	case ISDN_CMD_PROT_IO:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_PROT_IO");
-		break;
-	case ISDN_CMD_FAXCMD:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_FAXCMD");
-		break;
-	case ISDN_CMD_GETL2:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_GETL2");
-		break;
-	case ISDN_CMD_GETL3:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_GETL3");
-		break;
-	case ISDN_CMD_GETEAZ:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_GETEAZ");
-		break;
-	case ISDN_CMD_SETSIL:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_SETSIL");
-		break;
-	case ISDN_CMD_GETSIL:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_GETSIL");
-		break;
+
 	default:
-		dev_err(cs->dev, "unknown command %d from LL\n",
+		gig_dbg(DEBUG_CMD, "unknown command %d from LL",
 			cntrl->command);
 		return -EINVAL;
 	}
@@ -632,15 +592,13 @@ void gigaset_isdn_stop(struct cardstate
 }
 
 /**
- * gigaset_isdn_register() - register to LL
+ * gigaset_isdn_regdev() - register to LL
  * @cs:		device descriptor structure.
  * @isdnid:	device name.
  *
- * Called by main module to register the device with the LL.
- *
  * Return value: 1 for success, 0 for failure
  */
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
 {
 	isdn_if *iif;
 
@@ -690,15 +648,29 @@ int gigaset_isdn_register(struct cardsta
 }
 
 /**
- * gigaset_isdn_unregister() - unregister from LL
+ * gigaset_isdn_unregdev() - unregister device from LL
  * @cs:		device descriptor structure.
- *
- * Called by main module to unregister the device from the LL.
  */
-void gigaset_isdn_unregister(struct cardstate *cs)
+void gigaset_isdn_unregdev(struct cardstate *cs)
 {
 	gig_dbg(DEBUG_CMD, "sending UNLOAD");
 	gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD);
 	kfree(cs->iif);
 	cs->iif = NULL;
 }
+
+/**
+ * gigaset_isdn_regdrv() - register driver to LL
+ */
+void gigaset_isdn_regdrv(void)
+{
+	/* nothing to do */
+}
+
+/**
+ * gigaset_isdn_unregdrv() - unregister driver from LL
+ */
+void gigaset_isdn_unregdrv(void)
+{
+	/* nothing to do */
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/interface.c linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/interface.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/interface.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/interface.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 
 #include "gigaset.h"
 #include <linux/gigaset_dev.h>
-#include <linux/tty.h>
 #include <linux/tty_flip.h>
 
 /*** our ioctls ***/
@@ -45,8 +44,6 @@ static int if_lock(struct cardstate *cs,
 		cs->waiting = 0;
 		return -ENOMEM;
 	}
-
-	gig_dbg(DEBUG_CMD, "scheduling IF_LOCK");
 	gigaset_schedule_event(cs);
 
 	wait_event(cs->waitqueue, !cs->waiting);
@@ -81,8 +78,6 @@ static int if_version(struct cardstate *
 			cs->waiting = 0;
 			return -ENOMEM;
 		}
-
-		gig_dbg(DEBUG_CMD, "scheduling IF_VER");
 		gigaset_schedule_event(cs);
 
 		wait_event(cs->waitqueue, !cs->waiting);
@@ -274,7 +269,7 @@ static int if_ioctl(struct tty_struct *t
 					? -EFAULT : 0;
 			break;
 		default:
-			gig_dbg(DEBUG_ANY, "%s: arg not supported - 0x%04x",
+			gig_dbg(DEBUG_IF, "%s: arg not supported - 0x%04x",
 				__func__, cmd);
 			retval = -ENOIOCTLCMD;
 		}
@@ -455,7 +450,7 @@ static void if_throttle(struct tty_struc
 	else if (!cs->open_count)
 		dev_warn(cs->dev, "%s: device not opened\n", __func__);
 	else
-		gig_dbg(DEBUG_ANY, "%s: not implemented\n", __func__);
+		gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__);
 
 	mutex_unlock(&cs->mutex);
 }
@@ -479,7 +474,7 @@ static void if_unthrottle(struct tty_str
 	else if (!cs->open_count)
 		dev_warn(cs->dev, "%s: device not opened\n", __func__);
 	else
-		gig_dbg(DEBUG_ANY, "%s: not implemented\n", __func__);
+		gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__);
 
 	mutex_unlock(&cs->mutex);
 }
@@ -630,9 +625,8 @@ void gigaset_if_receive(struct cardstate
 	spin_lock_irqsave(&cs->lock, flags);
 	tty = cs->tty;
 	if (tty == NULL)
-		gig_dbg(DEBUG_ANY, "receive on closed device");
+		gig_dbg(DEBUG_IF, "receive on closed device");
 	else {
-		tty_buffer_request_room(tty, len);
 		tty_insert_flip_string(tty, buffer, len);
 		tty_flip_buffer_push(tty);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/isocdata.c linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/isocdata.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/isocdata.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/isocdata.c	2010-05-16 17:17:36.000000000 -0400
@@ -905,29 +905,49 @@ void gigaset_isoc_receive(unsigned char
 
 /* == data input =========================================================== */
 
+/* process a block of received bytes in command mode (mstate != MS_LOCKED)
+ * Append received bytes to the command response buffer and forward them
+ * line by line to the response handler.
+ * Note: Received lines may be terminated by CR, LF, or CR LF, which will be
+ * removed before passing the line to the response handler.
+ */
 static void cmd_loop(unsigned char *src, int numbytes, struct inbuf_t *inbuf)
 {
 	struct cardstate *cs = inbuf->cs;
 	unsigned cbytes      = cs->cbytes;
+	unsigned char c;
 
 	while (numbytes--) {
-		/* copy next character, check for end of line */
-		switch (cs->respdata[cbytes] = *src++) {
-		case '\r':
+		c = *src++;
+		switch (c) {
 		case '\n':
-			/* end of line */
-			gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)",
-				__func__, cbytes);
-			if (cbytes >= MAX_RESP_SIZE - 1)
-				dev_warn(cs->dev, "response too large\n");
+			if (cbytes == 0 && cs->respdata[0] == '\r') {
+				/* collapse LF with preceding CR */
+				cs->respdata[0] = 0;
+				break;
+			}
+			/* --v-- fall through --v-- */
+		case '\r':
+			/* end of message line, pass to response handler */
+			if (cbytes >= MAX_RESP_SIZE) {
+				dev_warn(cs->dev, "response too large (%d)\n",
+					 cbytes);
+				cbytes = MAX_RESP_SIZE;
+			}
 			cs->cbytes = cbytes;
+			gigaset_dbg_buffer(DEBUG_TRANSCMD, "received response",
+					   cbytes, cs->respdata);
 			gigaset_handle_modem_response(cs);
 			cbytes = 0;
+
+			/* store EOL byte for CRLF collapsing */
+			cs->respdata[0] = c;
 			break;
 		default:
-			/* advance in line buffer, checking for overflow */
-			if (cbytes < MAX_RESP_SIZE - 1)
-				cbytes++;
+			/* append to line buffer if possible */
+			if (cbytes < MAX_RESP_SIZE)
+				cs->respdata[cbytes] = c;
+			cbytes++;
 		}
 	}
 
@@ -958,8 +978,6 @@ void gigaset_isoc_input(struct inbuf_t *
 					   numbytes, src);
 			gigaset_if_receive(inbuf->cs, src, numbytes);
 		} else {
-			gigaset_dbg_buffer(DEBUG_CMD, "received response",
-					   numbytes, src);
 			cmd_loop(src, numbytes, inbuf);
 		}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/proc.c linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/proc.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
  */
 
 #include "gigaset.h"
-#include <linux/ctype.h>
 
 static ssize_t show_cidmode(struct device *dev,
 			    struct device_attribute *attr, char *buf)
@@ -48,8 +47,6 @@ static ssize_t set_cidmode(struct device
 		mutex_unlock(&cs->mutex);
 		return -ENOMEM;
 	}
-
-	gig_dbg(DEBUG_CMD, "scheduling PROC_CIDMODE");
 	gigaset_schedule_event(cs);
 
 	wait_event(cs->waitqueue, !cs->waiting);
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/ser-gigaset.c linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/ser-gigaset.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/ser-gigaset.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/ser-gigaset.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,11 +11,9 @@
  */
 
 #include "gigaset.h"
-
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
-#include <linux/tty.h>
 #include <linux/completion.h>
 
 /* Version Information */
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/usb-gigaset.c linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/usb-gigaset.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/usb-gigaset.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/gigaset/usb-gigaset.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,10 +16,6 @@
  */
 
 #include "gigaset.h"
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -628,7 +624,7 @@ static int write_modem(struct cardstate
 	struct usb_cardstate *ucs = cs->hw.usb;
 	unsigned long flags;
 
-	gig_dbg(DEBUG_WRITE, "len: %d...", bcs->tx_skb->len);
+	gig_dbg(DEBUG_OUTPUT, "len: %d...", bcs->tx_skb->len);
 
 	if (!bcs->tx_skb->len) {
 		dev_kfree_skb_any(bcs->tx_skb);
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/avmcard.h linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/avmcard.h
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/avmcard.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/avmcard.h	2010-05-16 17:17:36.000000000 -0400
@@ -556,8 +556,7 @@ u16  b1_send_message(struct capi_ctr *ct
 void b1_parse_version(avmctrl_info *card);
 irqreturn_t b1_interrupt(int interrupt, void *devptr);
 
-int b1ctl_read_proc(char *page, char **start, off_t off,
-        		int count, int *eof, struct capi_ctr *ctrl);
+extern const struct file_operations b1ctl_proc_fops;
 
 avmcard_dmainfo *avmcard_dma_alloc(char *name, struct pci_dev *,
 				   long rsize, long ssize);
@@ -577,7 +576,6 @@ void b1dma_register_appl(struct capi_ctr
 				capi_register_params *rp);
 void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl);
 u16  b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
-int b1dmactl_read_proc(char *page, char **start, off_t off,
-        		int count, int *eof, struct capi_ctr *ctrl);
+extern const struct file_operations b1dmactl_proc_fops;
 
 #endif /* _AVMCARD_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/b1.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/b1.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/b1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/b1.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,8 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/skbuff.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
@@ -19,6 +21,7 @@
 #include <linux/ioport.h>
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
@@ -634,18 +637,17 @@ irqreturn_t b1_interrupt(int interrupt,
 }
 
 /* ------------------------------------------------------------- */
-int b1ctl_read_proc(char *page, char **start, off_t off,
-        		int count, int *eof, struct capi_ctr *ctrl)
+static int b1ctl_proc_show(struct seq_file *m, void *v)
 {
+	struct capi_ctr *ctrl = m->private;
 	avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
 	avmcard *card = cinfo->card;
 	u8 flag;
-	int len = 0;
 	char *s;
 
-	len += sprintf(page+len, "%-16s %s\n", "name", card->name);
-	len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port);
-	len += sprintf(page+len, "%-16s %d\n", "irq", card->irq);
+	seq_printf(m, "%-16s %s\n", "name", card->name);
+	seq_printf(m, "%-16s 0x%x\n", "io", card->port);
+	seq_printf(m, "%-16s %d\n", "irq", card->irq);
 	switch (card->cardtype) {
 	case avm_b1isa: s = "B1 ISA"; break;
 	case avm_b1pci: s = "B1 PCI"; break;
@@ -658,20 +660,20 @@ int b1ctl_read_proc(char *page, char **s
 	case avm_c2: s = "C2"; break;
 	default: s = "???"; break;
 	}
-	len += sprintf(page+len, "%-16s %s\n", "type", s);
+	seq_printf(m, "%-16s %s\n", "type", s);
 	if (card->cardtype == avm_t1isa)
-	   len += sprintf(page+len, "%-16s %d\n", "cardnr", card->cardnr);
+		seq_printf(m, "%-16s %d\n", "cardnr", card->cardnr);
 	if ((s = cinfo->version[VER_DRIVER]) != NULL)
-	   len += sprintf(page+len, "%-16s %s\n", "ver_driver", s);
+		seq_printf(m, "%-16s %s\n", "ver_driver", s);
 	if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
-	   len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s);
+		seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
 	if ((s = cinfo->version[VER_SERIAL]) != NULL)
-	   len += sprintf(page+len, "%-16s %s\n", "ver_serial", s);
+		seq_printf(m, "%-16s %s\n", "ver_serial", s);
 
 	if (card->cardtype != avm_m1) {
         	flag = ((u8 *)(ctrl->profile.manu))[3];
         	if (flag)
-			len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n",
+			seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
 			"protocol",
 			(flag & 0x01) ? " DSS1" : "",
 			(flag & 0x02) ? " CT1" : "",
@@ -685,7 +687,7 @@ int b1ctl_read_proc(char *page, char **s
 	if (card->cardtype != avm_m1) {
         	flag = ((u8 *)(ctrl->profile.manu))[5];
 		if (flag)
-			len += sprintf(page+len, "%-16s%s%s%s%s\n",
+			seq_printf(m, "%-16s%s%s%s%s\n",
 			"linetype",
 			(flag & 0x01) ? " point to point" : "",
 			(flag & 0x02) ? " point to multipoint" : "",
@@ -693,16 +695,25 @@ int b1ctl_read_proc(char *page, char **s
 			(flag & 0x04) ? " leased line with D-channel" : ""
 			);
 	}
-	len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname);
+	seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
 
-	if (off+count >= len)
-	   *eof = 1;
-	if (len < off)
-           return 0;
-	*start = page + off;
-	return ((count < len-off) ? count : len-off);
+	return 0;
+}
+
+static int b1ctl_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, b1ctl_proc_show, PDE(inode)->data);
 }
 
+const struct file_operations b1ctl_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= b1ctl_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+EXPORT_SYMBOL(b1ctl_proc_fops);
+
 /* ------------------------------------------------------------- */
 
 #ifdef CONFIG_PCI
@@ -781,8 +792,6 @@ EXPORT_SYMBOL(b1_send_message);
 EXPORT_SYMBOL(b1_parse_version);
 EXPORT_SYMBOL(b1_interrupt);
 
-EXPORT_SYMBOL(b1ctl_read_proc);
-
 static int __init b1_init(void)
 {
 	char *p;
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/b1dma.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/b1dma.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/b1dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/b1dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,8 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/skbuff.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
@@ -18,6 +20,7 @@
 #include <linux/ioport.h>
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
@@ -855,21 +858,20 @@ u16 b1dma_send_message(struct capi_ctr *
 
 /* ------------------------------------------------------------- */
 
-int b1dmactl_read_proc(char *page, char **start, off_t off,
-        		int count, int *eof, struct capi_ctr *ctrl)
+static int b1dmactl_proc_show(struct seq_file *m, void *v)
 {
+	struct capi_ctr *ctrl = m->private;
 	avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
 	avmcard *card = cinfo->card;
 	u8 flag;
-	int len = 0;
 	char *s;
 	u32 txoff, txlen, rxoff, rxlen, csr;
 	unsigned long flags;
 
-	len += sprintf(page+len, "%-16s %s\n", "name", card->name);
-	len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port);
-	len += sprintf(page+len, "%-16s %d\n", "irq", card->irq);
-	len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase);
+	seq_printf(m, "%-16s %s\n", "name", card->name);
+	seq_printf(m, "%-16s 0x%x\n", "io", card->port);
+	seq_printf(m, "%-16s %d\n", "irq", card->irq);
+	seq_printf(m, "%-16s 0x%lx\n", "membase", card->membase);
 	switch (card->cardtype) {
 	case avm_b1isa: s = "B1 ISA"; break;
 	case avm_b1pci: s = "B1 PCI"; break;
@@ -882,18 +884,18 @@ int b1dmactl_read_proc(char *page, char
 	case avm_c2: s = "C2"; break;
 	default: s = "???"; break;
 	}
-	len += sprintf(page+len, "%-16s %s\n", "type", s);
+	seq_printf(m, "%-16s %s\n", "type", s);
 	if ((s = cinfo->version[VER_DRIVER]) != NULL)
-	   len += sprintf(page+len, "%-16s %s\n", "ver_driver", s);
+		seq_printf(m, "%-16s %s\n", "ver_driver", s);
 	if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
-	   len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s);
+		seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
 	if ((s = cinfo->version[VER_SERIAL]) != NULL)
-	   len += sprintf(page+len, "%-16s %s\n", "ver_serial", s);
+		seq_printf(m, "%-16s %s\n", "ver_serial", s);
 
 	if (card->cardtype != avm_m1) {
         	flag = ((u8 *)(ctrl->profile.manu))[3];
         	if (flag)
-			len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n",
+			seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
 			"protocol",
 			(flag & 0x01) ? " DSS1" : "",
 			(flag & 0x02) ? " CT1" : "",
@@ -907,7 +909,7 @@ int b1dmactl_read_proc(char *page, char
 	if (card->cardtype != avm_m1) {
         	flag = ((u8 *)(ctrl->profile.manu))[5];
 		if (flag)
-			len += sprintf(page+len, "%-16s%s%s%s%s\n",
+			seq_printf(m, "%-16s%s%s%s%s\n",
 			"linetype",
 			(flag & 0x01) ? " point to point" : "",
 			(flag & 0x02) ? " point to multipoint" : "",
@@ -915,7 +917,7 @@ int b1dmactl_read_proc(char *page, char
 			(flag & 0x04) ? " leased line with D-channel" : ""
 			);
 	}
-	len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname);
+	seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
 
 
 	spin_lock_irqsave(&card->lock, flags);
@@ -930,27 +932,30 @@ int b1dmactl_read_proc(char *page, char
 
 	spin_unlock_irqrestore(&card->lock, flags);
 
-        len += sprintf(page+len, "%-16s 0x%lx\n",
-				"csr (cached)", (unsigned long)card->csr);
-        len += sprintf(page+len, "%-16s 0x%lx\n",
-				"csr", (unsigned long)csr);
-        len += sprintf(page+len, "%-16s %lu\n",
-				"txoff", (unsigned long)txoff);
-        len += sprintf(page+len, "%-16s %lu\n",
-				"txlen", (unsigned long)txlen);
-        len += sprintf(page+len, "%-16s %lu\n",
-				"rxoff", (unsigned long)rxoff);
-        len += sprintf(page+len, "%-16s %lu\n",
-				"rxlen", (unsigned long)rxlen);
+	seq_printf(m, "%-16s 0x%lx\n", "csr (cached)", (unsigned long)card->csr);
+	seq_printf(m, "%-16s 0x%lx\n", "csr", (unsigned long)csr);
+	seq_printf(m, "%-16s %lu\n", "txoff", (unsigned long)txoff);
+	seq_printf(m, "%-16s %lu\n", "txlen", (unsigned long)txlen);
+	seq_printf(m, "%-16s %lu\n", "rxoff", (unsigned long)rxoff);
+	seq_printf(m, "%-16s %lu\n", "rxlen", (unsigned long)rxlen);
 
-	if (off+count >= len)
-	   *eof = 1;
-	if (len < off)
-           return 0;
-	*start = page + off;
-	return ((count < len-off) ? count : len-off);
+	return 0;
 }
 
+static int b1dmactl_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, b1dmactl_proc_show, PDE(inode)->data);
+}
+
+const struct file_operations b1dmactl_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= b1dmactl_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+EXPORT_SYMBOL(b1dmactl_proc_fops);
+
 /* ------------------------------------------------------------- */
 
 EXPORT_SYMBOL(b1dma_reset);
@@ -963,7 +968,6 @@ EXPORT_SYMBOL(b1dma_reset_ctr);
 EXPORT_SYMBOL(b1dma_register_appl);
 EXPORT_SYMBOL(b1dma_release_appl);
 EXPORT_SYMBOL(b1dma_send_message);
-EXPORT_SYMBOL(b1dmactl_read_proc);
 
 static int __init b1dma_init(void)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/b1isa.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/b1isa.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/b1isa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/b1isa.c	2010-05-16 17:17:36.000000000 -0400
@@ -121,7 +121,7 @@ static int b1isa_probe(struct pci_dev *p
 	cinfo->capi_ctrl.load_firmware = b1_load_firmware;
 	cinfo->capi_ctrl.reset_ctr     = b1_reset_ctr;
 	cinfo->capi_ctrl.procinfo      = b1isa_procinfo;
-	cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
+	cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops;
 	strcpy(cinfo->capi_ctrl.name, card->name);
 
 	retval = attach_capi_ctr(&cinfo->capi_ctrl);
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/b1pci.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/b1pci.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/b1pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/b1pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -112,7 +112,7 @@ static int b1pci_probe(struct capicardpa
 	cinfo->capi_ctrl.load_firmware = b1_load_firmware;
 	cinfo->capi_ctrl.reset_ctr     = b1_reset_ctr;
 	cinfo->capi_ctrl.procinfo      = b1pci_procinfo;
-	cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
+	cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops;
 	strcpy(cinfo->capi_ctrl.name, card->name);
 	cinfo->capi_ctrl.owner         = THIS_MODULE;
 
@@ -251,7 +251,7 @@ static int b1pciv4_probe(struct capicard
 	cinfo->capi_ctrl.load_firmware = b1dma_load_firmware;
 	cinfo->capi_ctrl.reset_ctr     = b1dma_reset_ctr;
 	cinfo->capi_ctrl.procinfo      = b1pciv4_procinfo;
-	cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc;
+	cinfo->capi_ctrl.proc_fops = &b1dmactl_proc_fops;
 	strcpy(cinfo->capi_ctrl.name, card->name);
 
 	retval = attach_capi_ctr(&cinfo->capi_ctrl);
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/b1pcmcia.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/b1pcmcia.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/b1pcmcia.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/b1pcmcia.c	2010-05-16 17:17:36.000000000 -0400
@@ -108,7 +108,7 @@ static int b1pcmcia_add_card(unsigned in
 	cinfo->capi_ctrl.load_firmware = b1_load_firmware;
 	cinfo->capi_ctrl.reset_ctr     = b1_reset_ctr;
 	cinfo->capi_ctrl.procinfo      = b1pcmcia_procinfo;
-	cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
+	cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops;
 	strcpy(cinfo->capi_ctrl.name, card->name);
 
 	retval = attach_capi_ctr(&cinfo->capi_ctrl);
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/c4.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/c4.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/c4.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/c4.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,8 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/skbuff.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
@@ -20,6 +22,7 @@
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <linux/netdevice.h>
@@ -1062,19 +1065,18 @@ static char *c4_procinfo(struct capi_ctr
 	return cinfo->infobuf;
 }
 
-static int c4_read_proc(char *page, char **start, off_t off,
-        		int count, int *eof, struct capi_ctr *ctrl)
+static int c4_proc_show(struct seq_file *m, void *v)
 {
+	struct capi_ctr *ctrl = m->private;
 	avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
 	avmcard *card = cinfo->card;
 	u8 flag;
-	int len = 0;
 	char *s;
 
-	len += sprintf(page+len, "%-16s %s\n", "name", card->name);
-	len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port);
-	len += sprintf(page+len, "%-16s %d\n", "irq", card->irq);
-	len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase);
+	seq_printf(m, "%-16s %s\n", "name", card->name);
+	seq_printf(m, "%-16s 0x%x\n", "io", card->port);
+	seq_printf(m, "%-16s %d\n", "irq", card->irq);
+	seq_printf(m, "%-16s 0x%lx\n", "membase", card->membase);
 	switch (card->cardtype) {
 	case avm_b1isa: s = "B1 ISA"; break;
 	case avm_b1pci: s = "B1 PCI"; break;
@@ -1087,18 +1089,18 @@ static int c4_read_proc(char *page, char
 	case avm_c2: s = "C2"; break;
 	default: s = "???"; break;
 	}
-	len += sprintf(page+len, "%-16s %s\n", "type", s);
+	seq_printf(m, "%-16s %s\n", "type", s);
 	if ((s = cinfo->version[VER_DRIVER]) != NULL)
-	   len += sprintf(page+len, "%-16s %s\n", "ver_driver", s);
+		seq_printf(m, "%-16s %s\n", "ver_driver", s);
 	if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
-	   len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s);
+		seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
 	if ((s = cinfo->version[VER_SERIAL]) != NULL)
-	   len += sprintf(page+len, "%-16s %s\n", "ver_serial", s);
+		seq_printf(m, "%-16s %s\n", "ver_serial", s);
 
 	if (card->cardtype != avm_m1) {
         	flag = ((u8 *)(ctrl->profile.manu))[3];
         	if (flag)
-			len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n",
+			seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
 			"protocol",
 			(flag & 0x01) ? " DSS1" : "",
 			(flag & 0x02) ? " CT1" : "",
@@ -1112,7 +1114,7 @@ static int c4_read_proc(char *page, char
 	if (card->cardtype != avm_m1) {
         	flag = ((u8 *)(ctrl->profile.manu))[5];
 		if (flag)
-			len += sprintf(page+len, "%-16s%s%s%s%s\n",
+			seq_printf(m, "%-16s%s%s%s%s\n",
 			"linetype",
 			(flag & 0x01) ? " point to point" : "",
 			(flag & 0x02) ? " point to multipoint" : "",
@@ -1120,16 +1122,24 @@ static int c4_read_proc(char *page, char
 			(flag & 0x04) ? " leased line with D-channel" : ""
 			);
 	}
-	len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname);
+	seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
 
-	if (off+count >= len)
-	   *eof = 1;
-	if (len < off)
-           return 0;
-	*start = page + off;
-	return ((count < len-off) ? count : len-off);
+	return 0;
+}
+
+static int c4_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, c4_proc_show, PDE(inode)->data);
 }
 
+static const struct file_operations c4_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= c4_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /* ------------------------------------------------------------- */
 
 static int c4_add_card(struct capicardparams *p, struct pci_dev *dev,
@@ -1201,7 +1211,7 @@ static int c4_add_card(struct capicardpa
 		cinfo->capi_ctrl.load_firmware = c4_load_firmware;
 		cinfo->capi_ctrl.reset_ctr     = c4_reset_ctr;
 		cinfo->capi_ctrl.procinfo      = c4_procinfo;
-		cinfo->capi_ctrl.ctr_read_proc = c4_read_proc;
+		cinfo->capi_ctrl.proc_fops = &c4_proc_fops;
 		strcpy(cinfo->capi_ctrl.name, card->name);
 
 		retval = attach_capi_ctr(&cinfo->capi_ctrl);
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/t1isa.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/t1isa.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/t1isa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/t1isa.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/kernelcapi.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 #include <linux/isdn/capicmd.h>
 #include <linux/isdn/capiutil.h>
@@ -429,7 +430,7 @@ static int t1isa_probe(struct pci_dev *p
 	cinfo->capi_ctrl.load_firmware = t1isa_load_firmware;
 	cinfo->capi_ctrl.reset_ctr     = t1isa_reset_ctr;
 	cinfo->capi_ctrl.procinfo      = t1isa_procinfo;
-	cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
+	cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops;
 	strcpy(cinfo->capi_ctrl.name, card->name);
 
 	retval = attach_capi_ctr(&cinfo->capi_ctrl);
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/t1pci.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/t1pci.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/t1pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/avm/t1pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -119,7 +119,7 @@ static int t1pci_add_card(struct capicar
 	cinfo->capi_ctrl.load_firmware = b1dma_load_firmware;
 	cinfo->capi_ctrl.reset_ctr     = b1dma_reset_ctr;
 	cinfo->capi_ctrl.procinfo      = t1pci_procinfo;
-	cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc;
+	cinfo->capi_ctrl.proc_fops = &b1dmactl_proc_fops;
 	strcpy(cinfo->capi_ctrl.name, card->name);
 
 	retval = attach_capi_ctr(&cinfo->capi_ctrl);
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/eicon/capimain.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/eicon/capimain.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/eicon/capimain.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/eicon/capimain.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,8 +11,10 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
+#include <linux/seq_file.h>
 #include <linux/skbuff.h>
 
 #include "os_capi.h"
@@ -75,25 +77,32 @@ void diva_os_free_message_buffer(diva_os
 /*
  * proc function for controller info
  */
-static int diva_ctl_read_proc(char *page, char **start, off_t off,
-			      int count, int *eof, struct capi_ctr *ctrl)
+static int diva_ctl_proc_show(struct seq_file *m, void *v)
 {
+	struct capi_ctr *ctrl = m->private;
 	diva_card *card = (diva_card *) ctrl->driverdata;
-	int len = 0;
 
-	len += sprintf(page + len, "%s\n", ctrl->name);
-	len += sprintf(page + len, "Serial No. : %s\n", ctrl->serial);
-	len += sprintf(page + len, "Id         : %d\n", card->Id);
-	len += sprintf(page + len, "Channels   : %d\n", card->d.channels);
+	seq_printf(m, "%s\n", ctrl->name);
+	seq_printf(m, "Serial No. : %s\n", ctrl->serial);
+	seq_printf(m, "Id         : %d\n", card->Id);
+	seq_printf(m, "Channels   : %d\n", card->d.channels);
 
-	if (off + count >= len)
-		*eof = 1;
-	if (len < off)
-		return 0;
-	*start = page + off;
-	return ((count < len - off) ? count : len - off);
+	return 0;
 }
 
+static int diva_ctl_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, diva_ctl_proc_show, NULL);
+}
+
+static const struct file_operations diva_ctl_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= diva_ctl_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*
  * set additional os settings in capi_ctr struct
  */
@@ -102,7 +111,7 @@ void diva_os_set_controller_struct(struc
 	ctrl->driver_name = DRIVERLNAME;
 	ctrl->load_firmware = NULL;
 	ctrl->reset_ctr = NULL;
-	ctrl->ctr_read_proc = diva_ctl_read_proc;
+	ctrl->proc_fops = &diva_ctl_proc_fops;
 	ctrl->owner = THIS_MODULE;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/eicon/diva_didd.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/eicon/diva_didd.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/eicon/diva_didd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/eicon/diva_didd.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <net/net_namespace.h>
 
 #include "platform.h"
@@ -62,39 +63,41 @@ static char *getrev(const char *revision
 	return rev;
 }
 
-static int
-proc_read(char *page, char **start, off_t off, int count, int *eof,
-	  void *data)
+static int divadidd_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
 	char tmprev[32];
 
 	strcpy(tmprev, main_revision);
-	len += sprintf(page + len, "%s\n", DRIVERNAME);
-	len += sprintf(page + len, "name     : %s\n", DRIVERLNAME);
-	len += sprintf(page + len, "release  : %s\n", DRIVERRELEASE_DIDD);
-	len += sprintf(page + len, "build    : %s(%s)\n",
+	seq_printf(m, "%s\n", DRIVERNAME);
+	seq_printf(m, "name     : %s\n", DRIVERLNAME);
+	seq_printf(m, "release  : %s\n", DRIVERRELEASE_DIDD);
+	seq_printf(m, "build    : %s(%s)\n",
 		       diva_didd_common_code_build, DIVA_BUILD);
-	len += sprintf(page + len, "revision : %s\n", getrev(tmprev));
+	seq_printf(m, "revision : %s\n", getrev(tmprev));
 
-	if (off + count >= len)
-		*eof = 1;
-	if (len < off)
-		return 0;
-	*start = page + off;
-	return ((count < len - off) ? count : len - off);
+	return 0;
+}
+
+static int divadidd_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, divadidd_proc_show, NULL);
 }
 
+static const struct file_operations divadidd_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= divadidd_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static int DIVA_INIT_FUNCTION create_proc(void)
 {
 	proc_net_eicon = proc_mkdir("eicon", init_net.proc_net);
 
 	if (proc_net_eicon) {
-		if ((proc_didd =
-		     create_proc_entry(DRIVERLNAME, S_IFREG | S_IRUGO,
-				       proc_net_eicon))) {
-			proc_didd->read_proc = proc_read;
-		}
+		proc_didd = proc_create(DRIVERLNAME, S_IRUGO, proc_net_eicon,
+					&divadidd_proc_fops);
 		return (1);
 	}
 	return (0);
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/eicon/divasi.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/eicon/divasi.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/eicon/divasi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/eicon/divasi.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
 #include <linux/skbuff.h>
+#include <linux/seq_file.h>
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 
@@ -86,39 +87,40 @@ static void diva_um_timer_function(unsig
 extern struct proc_dir_entry *proc_net_eicon;
 static struct proc_dir_entry *um_idi_proc_entry = NULL;
 
-static int
-um_idi_proc_read(char *page, char **start, off_t off, int count, int *eof,
-		 void *data)
+static int um_idi_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
 	char tmprev[32];
 
-	len += sprintf(page + len, "%s\n", DRIVERNAME);
-	len += sprintf(page + len, "name     : %s\n", DRIVERLNAME);
-	len += sprintf(page + len, "release  : %s\n", DRIVERRELEASE_IDI);
+	seq_printf(m, "%s\n", DRIVERNAME);
+	seq_printf(m, "name     : %s\n", DRIVERLNAME);
+	seq_printf(m, "release  : %s\n", DRIVERRELEASE_IDI);
 	strcpy(tmprev, main_revision);
-	len += sprintf(page + len, "revision : %s\n", getrev(tmprev));
-	len += sprintf(page + len, "build    : %s\n", DIVA_BUILD);
-	len += sprintf(page + len, "major    : %d\n", major);
+	seq_printf(m, "revision : %s\n", getrev(tmprev));
+	seq_printf(m, "build    : %s\n", DIVA_BUILD);
+	seq_printf(m, "major    : %d\n", major);
 
-	if (off + count >= len)
-		*eof = 1;
-	if (len < off)
-		return 0;
-	*start = page + off;
-	return ((count < len - off) ? count : len - off);
+	return 0;
+}
+
+static int um_idi_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, um_idi_proc_show, NULL);
 }
 
+static const struct file_operations um_idi_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= um_idi_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static int DIVA_INIT_FUNCTION create_um_idi_proc(void)
 {
-	um_idi_proc_entry = create_proc_entry(DRIVERLNAME,
-					      S_IFREG | S_IRUGO | S_IWUSR,
-					      proc_net_eicon);
+	um_idi_proc_entry = proc_create(DRIVERLNAME, S_IRUGO, proc_net_eicon,
+					&um_idi_proc_fops);
 	if (!um_idi_proc_entry)
 		return (0);
-
-	um_idi_proc_entry->read_proc = um_idi_proc_read;
-
 	return (1);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/eicon/divasproc.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/eicon/divasproc.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/eicon/divasproc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/eicon/divasproc.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/list.h>
 #include <asm/uaccess.h>
 
@@ -141,14 +142,10 @@ void remove_divas_proc(void)
 	}
 }
 
-/*
-** write group_optimization 
-*/
-static int
-write_grp_opt(struct file *file, const char __user *buffer, unsigned long count,
-	      void *data)
+static ssize_t grp_opt_proc_write(struct file *file, const char __user *buffer,
+				  size_t count, loff_t *pos)
 {
-	diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data;
+	diva_os_xdi_adapter_t *a = PDE(file->f_path.dentry->d_inode)->data;
 	PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
 
 	if ((count == 1) || (count == 2)) {
@@ -172,14 +169,10 @@ write_grp_opt(struct file *file, const c
 	return (-EINVAL);
 }
 
-/*
-** write dynamic_l1_down
-*/
-static int
-write_d_l1_down(struct file *file, const char __user *buffer, unsigned long count,
-		void *data)
+static ssize_t d_l1_down_proc_write(struct file *file, const char __user *buffer,
+				    size_t count, loff_t *pos)
 {
-	diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data;
+	diva_os_xdi_adapter_t *a = PDE(file->f_path.dentry->d_inode)->data;
 	PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
 
 	if ((count == 1) || (count == 2)) {
@@ -203,63 +196,62 @@ write_d_l1_down(struct file *file, const
 	return (-EINVAL);
 }
 
-
-/*
-** read dynamic_l1_down 
-*/
-static int
-read_d_l1_down(char *page, char **start, off_t off, int count, int *eof,
-	       void *data)
+static int d_l1_down_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
-	diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data;
+	diva_os_xdi_adapter_t *a = m->private;
 	PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
 
-	len += sprintf(page + len, "%s\n",
+	seq_printf(m, "%s\n",
 		       (IoAdapter->capi_cfg.
 			cfg_1 & DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? "1" :
 		       "0");
+	return 0;
+}
 
-	if (off + count >= len)
-		*eof = 1;
-	if (len < off)
-		return 0;
-	*start = page + off;
-	return ((count < len - off) ? count : len - off);
+static int d_l1_down_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, d_l1_down_proc_show, PDE(inode)->data);
 }
 
-/*
-** read group_optimization
-*/
-static int
-read_grp_opt(char *page, char **start, off_t off, int count, int *eof,
-	     void *data)
+static const struct file_operations d_l1_down_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= d_l1_down_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= d_l1_down_proc_write,
+};
+
+static int grp_opt_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
-	diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data;
+	diva_os_xdi_adapter_t *a = m->private;
 	PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
 
-	len += sprintf(page + len, "%s\n",
+	seq_printf(m, "%s\n",
 		       (IoAdapter->capi_cfg.
 			cfg_1 & DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON)
 		       ? "1" : "0");
+	return 0;
+}
 
-	if (off + count >= len)
-		*eof = 1;
-	if (len < off)
-		return 0;
-	*start = page + off;
-	return ((count < len - off) ? count : len - off);
+static int grp_opt_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, grp_opt_proc_show, PDE(inode)->data);
 }
 
-/*
-** info write
-*/
-static int
-info_write(struct file *file, const char __user *buffer, unsigned long count,
-	   void *data)
+static const struct file_operations grp_opt_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= grp_opt_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= grp_opt_proc_write,
+};
+
+static ssize_t info_proc_write(struct file *file, const char __user *buffer,
+			       size_t count, loff_t *pos)
 {
-	diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data;
+	diva_os_xdi_adapter_t *a = PDE(file->f_path.dentry->d_inode)->data;
 	PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
 	char c[4];
 
@@ -277,63 +269,46 @@ info_write(struct file *file, const char
 	return (-EINVAL);
 }
 
-/*
-** info read
-*/
-static int
-info_read(char *page, char **start, off_t off, int count, int *eof,
-	  void *data)
+static int info_proc_show(struct seq_file *m, void *v)
 {
 	int i = 0;
-	int len = 0;
 	char *p;
 	char tmpser[16];
-	diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data;
+	diva_os_xdi_adapter_t *a = m->private;
 	PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
 
-	len +=
-	    sprintf(page + len, "Name        : %s\n",
-		    IoAdapter->Properties.Name);
-	len += sprintf(page + len, "DSP state   : %08x\n", a->dsp_mask);
-	len += sprintf(page + len, "Channels    : %02d\n",
-		       IoAdapter->Properties.Channels);
-	len += sprintf(page + len, "E. max/used : %03d/%03d\n",
+	seq_printf(m, "Name        : %s\n", IoAdapter->Properties.Name);
+	seq_printf(m, "DSP state   : %08x\n", a->dsp_mask);
+	seq_printf(m, "Channels    : %02d\n", IoAdapter->Properties.Channels);
+	seq_printf(m, "E. max/used : %03d/%03d\n",
 		       IoAdapter->e_max, IoAdapter->e_count);
 	diva_get_vserial_number(IoAdapter, tmpser);
-	len += sprintf(page + len, "Serial      : %s\n", tmpser);
-	len +=
-	    sprintf(page + len, "IRQ         : %d\n",
-		    IoAdapter->irq_info.irq_nr);
-	len += sprintf(page + len, "CardIndex   : %d\n", a->CardIndex);
-	len += sprintf(page + len, "CardOrdinal : %d\n", a->CardOrdinal);
-	len += sprintf(page + len, "Controller  : %d\n", a->controller);
-	len += sprintf(page + len, "Bus-Type    : %s\n",
+	seq_printf(m, "Serial      : %s\n", tmpser);
+	seq_printf(m, "IRQ         : %d\n", IoAdapter->irq_info.irq_nr);
+	seq_printf(m, "CardIndex   : %d\n", a->CardIndex);
+	seq_printf(m, "CardOrdinal : %d\n", a->CardOrdinal);
+	seq_printf(m, "Controller  : %d\n", a->controller);
+	seq_printf(m, "Bus-Type    : %s\n",
 		       (a->Bus ==
 			DIVAS_XDI_ADAPTER_BUS_ISA) ? "ISA" : "PCI");
-	len += sprintf(page + len, "Port-Name   : %s\n", a->port_name);
+	seq_printf(m, "Port-Name   : %s\n", a->port_name);
 	if (a->Bus == DIVAS_XDI_ADAPTER_BUS_PCI) {
-		len +=
-		    sprintf(page + len, "PCI-bus     : %d\n",
-			    a->resources.pci.bus);
-		len +=
-		    sprintf(page + len, "PCI-func    : %d\n",
-			    a->resources.pci.func);
+		seq_printf(m, "PCI-bus     : %d\n", a->resources.pci.bus);
+		seq_printf(m, "PCI-func    : %d\n", a->resources.pci.func);
 		for (i = 0; i < 8; i++) {
 			if (a->resources.pci.bar[i]) {
-				len +=
-				    sprintf(page + len,
+				seq_printf(m,
 					    "Mem / I/O %d : 0x%x / mapped : 0x%lx",
 					    i, a->resources.pci.bar[i],
 					    (unsigned long) a->resources.
 					    pci.addr[i]);
 				if (a->resources.pci.length[i]) {
-					len +=
-					    sprintf(page + len,
+					seq_printf(m,
 						    " / length : %d",
 						    a->resources.pci.
 						    length[i]);
 				}
-				len += sprintf(page + len, "\n");
+				seq_putc(m, '\n');
 			}
 		}
 	}
@@ -353,16 +328,25 @@ info_read(char *page, char **start, off_
 	} else {
 		p = "ready";
 	}
-	len += sprintf(page + len, "State       : %s\n", p);
+	seq_printf(m, "State       : %s\n", p);
 
-	if (off + count >= len)
-		*eof = 1;
-	if (len < off)
-		return 0;
-	*start = page + off;
-	return ((count < len - off) ? count : len - off);
+	return 0;
 }
 
+static int info_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, info_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations info_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= info_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= info_proc_write,
+};
+
 /*
 ** adapter proc init/de-init
 */
@@ -380,28 +364,20 @@ int create_adapter_proc(diva_os_xdi_adap
 		return (0);
 	a->proc_adapter_dir = (void *) de;
 
-	if (!(pe =
-	     create_proc_entry(info_proc_name, S_IFREG | S_IRUGO | S_IWUSR, de)))
+	pe = proc_create_data(info_proc_name, S_IRUGO | S_IWUSR, de,
+			      &info_proc_fops, a);
+	if (!pe)
 		return (0);
 	a->proc_info = (void *) pe;
-	pe->write_proc = info_write;
-	pe->read_proc = info_read;
-	pe->data = a;
 
-	if ((pe = create_proc_entry(grp_opt_proc_name,
-			       S_IFREG | S_IRUGO | S_IWUSR, de))) {
+	pe = proc_create_data(grp_opt_proc_name, S_IRUGO | S_IWUSR, de,
+			      &grp_opt_proc_fops, a);
+	if (pe)
 		a->proc_grp_opt = (void *) pe;
-		pe->write_proc = write_grp_opt;
-		pe->read_proc = read_grp_opt;
-		pe->data = a;
-	}
-	if ((pe = create_proc_entry(d_l1_down_proc_name,
-			       S_IFREG | S_IRUGO | S_IWUSR, de))) {
+	pe = proc_create_data(d_l1_down_proc_name, S_IRUGO | S_IWUSR, de,
+			      &d_l1_down_proc_fops, a);
+	if (pe)
 		a->proc_d_l1_down = (void *) pe;
-		pe->write_proc = write_d_l1_down;
-		pe->read_proc = read_d_l1_down;
-		pe->data = a;
-	}
 
 	DBG_TRC(("proc entry %s created", tmp));
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/eicon/message.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/eicon/message.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/eicon/message.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/eicon/message.c	2010-05-16 17:17:36.000000000 -0400
@@ -2754,7 +2754,7 @@ static byte connect_b3_req(dword Id, wor
                     for (i = 0; i < w; i++)
                       ((T30_INFO   *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1+i];
                     ((T30_INFO   *)(plci->fax_connect_info_buffer))->head_line_len = 0;
-                    len = offsetof(T30_INFO, station_id) + 20;
+                    len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
                     w = fax_parms[5].length;
                     if (w > 20)
                       w = 20;
@@ -2892,7 +2892,7 @@ static byte connect_b3_res(dword Id, wor
     && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
     && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
    {
-            len = offsetof(T30_INFO, station_id) + 20;
+            len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
             if (plci->fax_connect_info_length < len)
             {
               ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
@@ -3802,7 +3802,7 @@ static byte manufacturer_res(dword Id, w
       break;
     }
     ncpi = &m_parms[1];
-    len = offsetof(T30_INFO, station_id) + 20;
+    len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
     if (plci->fax_connect_info_length < len)
     {
       ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
@@ -6830,7 +6830,7 @@ static void nl_ind(PLCI *plci)
         if(((T30_INFO   *)plci->NL.RBuffer->P)->station_id_len)
         {
           plci->ncpi_buffer[len] = 20;
-          for (i = 0; i < 20; i++)
+          for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++)
             plci->ncpi_buffer[++len] = ((T30_INFO   *)plci->NL.RBuffer->P)->station_id[i];
         }
         if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
@@ -6844,7 +6844,7 @@ static void nl_ind(PLCI *plci)
         if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1])
           & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
         {
-          i = offsetof(T30_INFO, station_id) + 20 + ((T30_INFO   *)plci->NL.RBuffer->P)->head_line_len;
+          i = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + ((T30_INFO   *)plci->NL.RBuffer->P)->head_line_len;
           while (i < plci->NL.RBuffer->length)
             plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++];
         }
@@ -8400,7 +8400,7 @@ static word add_b23(PLCI *plci, API_PARS
         }
       }
       /* copy station id to NLC */
-      for(i=0; i<20; i++)
+      for(i=0; i < T30_MAX_STATION_ID_LENGTH; i++)
       {
         if(i<b3_config_parms[2].length)
         {
@@ -8411,29 +8411,29 @@ static word add_b23(PLCI *plci, API_PARS
           ((T30_INFO *)&nlc[1])->station_id[i] = ' ';
         }
       }
-      ((T30_INFO *)&nlc[1])->station_id_len = 20;
+      ((T30_INFO *)&nlc[1])->station_id_len = T30_MAX_STATION_ID_LENGTH;
       /* copy head line to NLC */
       if(b3_config_parms[3].length)
       {
 
-        pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[20])));
+        pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[T30_MAX_STATION_ID_LENGTH])));
         if (pos != 0)
         {
           if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE)
             pos = 0;
           else
           {
-            ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
-            ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
+            nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
+            nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
             len = (byte)b3_config_parms[2].length;
             if (len > 20)
               len = 20;
             if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE)
             {
               for (i = 0; i < len; i++)
-                ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte   *)b3_config_parms[2].info)[1+i];
-              ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
-              ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
+                nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte   *)b3_config_parms[2].info)[1+i];
+              nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
+              nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
             }
           }
         }
@@ -8444,9 +8444,8 @@ static word add_b23(PLCI *plci, API_PARS
         ((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len);
         nlc[0] += (byte)(pos + len);
         for (i = 0; i < len; i++)
-          ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte   *)b3_config_parms[3].info)[1+i];
-        }
-      else
+          nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] =  ((byte   *)b3_config_parms[3].info)[1+i];
+      } else
         ((T30_INFO *)&nlc[1])->head_line_len = 0;
 
       plci->nsf_control_bits = 0;
@@ -8473,7 +8472,7 @@ static word add_b23(PLCI *plci, API_PARS
             fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
           }
             len = nlc[0];
-          pos = offsetof(T30_INFO, station_id) + 20;
+          pos = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
    if (pos < plci->fax_connect_info_length)
    {
      for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
@@ -8525,7 +8524,7 @@ static word add_b23(PLCI *plci, API_PARS
       }
 
       PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits);
-      len = offsetof(T30_INFO, station_id) + 20;
+      len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
       for (i = 0; i < len; i++)
         plci->fax_connect_info_buffer[i] = nlc[1+i];
       ((T30_INFO   *) plci->fax_connect_info_buffer)->head_line_len = 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/avmfritz.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/avmfritz.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/avmfritz.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/avmfritz.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mISDNhw.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include "ipac.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/hfcmulti.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/hfcmulti.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/hfcmulti.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/hfcmulti.c	2010-05-16 17:17:36.000000000 -0400
@@ -153,6 +153,7 @@
 #define HFC_MULTI_VERSION	"2.03"
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mISDNhw.h>
@@ -2846,7 +2847,7 @@ mode_hfcmulti(struct hfc_multi *hc, int
 	int conf;
 
 	if (ch < 0 || ch > 31)
-		return EINVAL;
+		return -EINVAL;
 	oslot_tx = hc->chan[ch].slot_tx;
 	oslot_rx = hc->chan[ch].slot_rx;
 	conf = hc->chan[ch].conf;
@@ -5265,6 +5266,8 @@ static const struct hm_map hfcm_map[] =
 /*31*/	{VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0,
 		HFC_IO_MODE_EMBSD, XHFC_IRQ},
 /*32*/	{VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0},
+/*33*/	{VENDOR_BN, "HFC-2S Beronet Card PCIe", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
+/*34*/	{VENDOR_BN, "HFC-4S Beronet Card PCIe", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
 };
 
 #undef H
@@ -5300,6 +5303,10 @@ static struct pci_device_id hfmultipci_i
 		PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
 		PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */
+	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
+		0xb761, 0, 0, H(33)}, /* BN2S PCIe */
+	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
+		0xb762, 0, 0, H(34)}, /* BN4S PCIe */
 
 	/* Cards with HFC-8S Chip */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/hfcpci.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/hfcpci.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/hfcpci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/hfcpci.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,6 +48,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mISDNhw.h>
+#include <linux/slab.h>
 
 #include "hfc_pci.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/delay.h>
 #include <linux/usb.h>
 #include <linux/mISDNhw.h>
+#include <linux/slab.h>
 #include "hfcsusb.h"
 
 static const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05";
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/mISDNinfineon.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/mISDNinfineon.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/mISDNinfineon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/mISDNinfineon.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mISDNhw.h>
+#include <linux/slab.h>
 #include "ipac.h"
 
 #define INFINEON_REV	"1.0"
@@ -1133,6 +1134,7 @@ inf_probe(struct pci_dev *pdev, const st
 			if (err) {
 				kfree(sc);
 				release_card(card);
+				break;
 			} else
 				card->sc[i - 1] = sc;
 		}
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/mISDNipac.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/mISDNipac.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/mISDNipac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/mISDNipac.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/mISDNhw.h>
 #include "ipac.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/mISDNisar.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/mISDNisar.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/mISDNisar.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/mISDNisar.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
  */
 /* #define DEBUG */
 
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
 #include <linux/mISDNhw.h>
@@ -1712,13 +1713,13 @@ mISDNisar_init(struct isar_hw *isar, voi
 }
 EXPORT_SYMBOL(mISDNisar_init);
 
-static int isar_mod_init(void)
+static int __init isar_mod_init(void)
 {
 	pr_notice("mISDN: ISAR driver Rev. %s\n", ISAR_REV);
 	return 0;
 }
 
-static void isar_mod_cleanup(void)
+static void __exit isar_mod_cleanup(void)
 {
 	pr_notice("mISDN: ISAR module unloaded\n");
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/netjet.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/netjet.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/netjet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/netjet.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mISDNhw.h>
+#include <linux/slab.h>
 #include "ipac.h"
 #include "iohelper.h"
 #include "netjet.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/speedfax.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/speedfax.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/speedfax.c	2013-05-03 12:12:14.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/speedfax.c	2013-05-03 09:51:46.000000000 -0400
@@ -23,6 +23,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mISDNhw.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/w6692.c linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/w6692.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/w6692.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hardware/mISDN/w6692.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mISDNhw.h>
+#include <linux/slab.h>
 #include "w6692.h"
 
 #define W6692_REV	"2.0"
@@ -529,6 +530,7 @@ W6692_fill_Bfifo(struct w6692_ch *wch)
 	}
 }
 
+#if 0
 static int
 setvolume(struct w6692_ch *wch, int mic, struct sk_buff *skb)
 {
@@ -571,6 +573,7 @@ enable_pots(struct w6692_ch *wch)
 	WriteW6692(card, W_PCTL, card->pctl);
 	return 0;
 }
+#endif
 
 static int
 disable_pots(struct w6692_ch *wch)
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/amd7930_fn.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/amd7930_fn.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/amd7930_fn.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/amd7930_fn.c	2010-05-16 17:17:36.000000000 -0400
@@ -59,6 +59,7 @@
 #include "amd7930_fn.h"
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 
 static void Amd7930_new_ph(struct IsdnCardState *cs);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/avma1_cs.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/avma1_cs.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/avma1_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/avma1_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,7 +50,7 @@ module_param(isdnprot, int, 0);
    handler.
 */
 
-static int avma1cs_config(struct pcmcia_device *link);
+static int avma1cs_config(struct pcmcia_device *link) __devinit ;
 static void avma1cs_release(struct pcmcia_device *link);
 
 /*
@@ -59,7 +59,7 @@ static void avma1cs_release(struct pcmci
    needed to manage one actual PCMCIA card.
 */
 
-static void avma1cs_detach(struct pcmcia_device *p_dev);
+static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ;
 
 
 /*
@@ -99,7 +99,7 @@ typedef struct local_info_t {
     
 ======================================================================*/
 
-static int avma1cs_probe(struct pcmcia_device *p_dev)
+static int __devinit avma1cs_probe(struct pcmcia_device *p_dev)
 {
     local_info_t *local;
 
@@ -140,7 +140,7 @@ static int avma1cs_probe(struct pcmcia_d
 
 ======================================================================*/
 
-static void avma1cs_detach(struct pcmcia_device *link)
+static void __devexit avma1cs_detach(struct pcmcia_device *link)
 {
 	dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link);
 	avma1cs_release(link);
@@ -174,7 +174,7 @@ static int avma1cs_configcheck(struct pc
 }
 
 
-static int avma1cs_config(struct pcmcia_device *link)
+static int __devinit avma1cs_config(struct pcmcia_device *link)
 {
     local_info_t *dev;
     int i;
@@ -282,7 +282,7 @@ static struct pcmcia_driver avma1cs_driv
 		.name	= "avma1_cs",
 	},
 	.probe		= avma1cs_probe,
-	.remove		= avma1cs_detach,
+	.remove		= __devexit_p(avma1cs_detach),
 	.id_table	= avma1cs_ids,
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/avm_pci.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/avm_pci.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/avm_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/avm_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include "isac.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/isapnp.h>
 #include <linux/interrupt.h>
 
@@ -822,7 +823,7 @@ static int __devinit avm_pnp_setup(struc
 
 #endif /* __ISAPNP__ */
 
-#ifndef CONFIG_PCI_LEGACY
+#ifndef CONFIG_PCI
 
 static int __devinit avm_pci_setup(struct IsdnCardState *cs)
 {
@@ -835,7 +836,7 @@ static struct pci_dev *dev_avm __devinit
 
 static int __devinit avm_pci_setup(struct IsdnCardState *cs)
 {
-	if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM,
+	if ((dev_avm = hisax_find_pci_device(PCI_VENDOR_ID_AVM,
 		PCI_DEVICE_ID_AVM_A1, dev_avm))) {
 
 		if (pci_enable_device(dev_avm))
@@ -864,7 +865,7 @@ static int __devinit avm_pci_setup(struc
 	return (1);
 }
 
-#endif /* CONFIG_PCI_LEGACY */
+#endif /* CONFIG_PCI */
 
 int __devinit
 setup_avm_pcipnp(struct IsdnCard *card)
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/bkm_a4t.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/bkm_a4t.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/bkm_a4t.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/bkm_a4t.c	2010-05-16 17:17:36.000000000 -0400
@@ -340,7 +340,7 @@ setup_bkm_a4t(struct IsdnCard *card)
 	} else
 		return (0);
 
-	while ((dev_a4t = pci_find_device(PCI_VENDOR_ID_ZORAN,
+	while ((dev_a4t = hisax_find_pci_device(PCI_VENDOR_ID_ZORAN,
 		PCI_DEVICE_ID_ZORAN_36120, dev_a4t))) {
 		ret = a4t_pci_probe(dev_a4t, cs, &found, &pci_memaddr);
 		if (!ret)
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/bkm_a8.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/bkm_a8.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/bkm_a8.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/bkm_a8.c	2010-05-16 17:17:36.000000000 -0400
@@ -301,7 +301,7 @@ setup_sct_quadro(struct IsdnCard *card)
 		(sub_vendor_id != PCI_VENDOR_ID_BERKOM)))
 		return (0);
 	if (cs->subtyp == SCT_1) {
-		while ((dev_a8 = pci_find_device(PCI_VENDOR_ID_PLX,
+		while ((dev_a8 = hisax_find_pci_device(PCI_VENDOR_ID_PLX,
 			PCI_DEVICE_ID_PLX_9050, dev_a8))) {
 			
 			sub_vendor_id = dev_a8->subsystem_vendor;
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/callc.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/callc.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/callc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/callc.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include "hisax.h"
 #include <linux/isdn/capicmd.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/config.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/config.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/config.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/config.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #define HISAX_STATUS_BUFSIZE 4096
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/diva.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/diva.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/diva.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/diva.c	2010-05-16 17:17:36.000000000 -0400
@@ -1148,7 +1148,7 @@ static int __devinit setup_diva_isapnp(s
 
 #endif	/* ISAPNP */
 
-#ifdef CONFIG_PCI_LEGACY
+#ifdef CONFIG_PCI
 static struct pci_dev *dev_diva __devinitdata = NULL;
 static struct pci_dev *dev_diva_u __devinitdata = NULL;
 static struct pci_dev *dev_diva201 __devinitdata = NULL;
@@ -1159,21 +1159,21 @@ static int __devinit setup_diva_pci(stru
 	struct IsdnCardState *cs = card->cs;
 
 	cs->subtyp = 0;
-	if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON,
+	if ((dev_diva = hisax_find_pci_device(PCI_VENDOR_ID_EICON,
 		PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) {
 		if (pci_enable_device(dev_diva))
 			return(0);
 		cs->subtyp = DIVA_PCI;
 		cs->irq = dev_diva->irq;
 		cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2);
-	} else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON,
+	} else if ((dev_diva_u = hisax_find_pci_device(PCI_VENDOR_ID_EICON,
 		PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) {
 		if (pci_enable_device(dev_diva_u))
 			return(0);
 		cs->subtyp = DIVA_PCI;
 		cs->irq = dev_diva_u->irq;
 		cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2);
-	} else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON,
+	} else if ((dev_diva201 = hisax_find_pci_device(PCI_VENDOR_ID_EICON,
 		PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) {
 		if (pci_enable_device(dev_diva201))
 			return(0);
@@ -1183,7 +1183,7 @@ static int __devinit setup_diva_pci(stru
 			(ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096);
 		cs->hw.diva.cfg_reg =
 			(ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096);
-	} else if ((dev_diva202 = pci_find_device(PCI_VENDOR_ID_EICON,
+	} else if ((dev_diva202 = hisax_find_pci_device(PCI_VENDOR_ID_EICON,
 		PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) {
 		if (pci_enable_device(dev_diva202))
 			return(0);
@@ -1229,14 +1229,14 @@ static int __devinit setup_diva_pci(stru
 	return (1);		/* card found */
 }
 
-#else	/* if !CONFIG_PCI_LEGACY */
+#else	/* if !CONFIG_PCI */
 
 static int __devinit setup_diva_pci(struct IsdnCard *card)
 {
 	return (-1);	/* card not found; continue search */
 }
 
-#endif	/* CONFIG_PCI_LEGACY */
+#endif	/* CONFIG_PCI */
 
 int __devinit
 setup_diva(struct IsdnCard *card)
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/elsa.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/elsa.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/elsa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/elsa.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include "hisax.h"
 #include "arcofi.h"
 #include "isac.h"
@@ -1025,7 +1026,7 @@ setup_elsa_pcmcia(struct IsdnCard *card)
 	       cs->irq);
 }
 
-#ifdef CONFIG_PCI_LEGACY
+#ifdef CONFIG_PCI
 static 	struct pci_dev *dev_qs1000 __devinitdata = NULL;
 static 	struct pci_dev *dev_qs3000 __devinitdata = NULL;
 
@@ -1035,7 +1036,7 @@ setup_elsa_pci(struct IsdnCard *card)
 	struct IsdnCardState *cs = card->cs;
 
 	cs->subtyp = 0;
-	if ((dev_qs1000 = pci_find_device(PCI_VENDOR_ID_ELSA,
+	if ((dev_qs1000 = hisax_find_pci_device(PCI_VENDOR_ID_ELSA,
 		PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) {
 		if (pci_enable_device(dev_qs1000))
 			return(0);
@@ -1043,7 +1044,7 @@ setup_elsa_pci(struct IsdnCard *card)
 		cs->irq = dev_qs1000->irq;
 		cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1);
 		cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3);
-	} else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ID_ELSA,
+	} else if ((dev_qs3000 = hisax_find_pci_device(PCI_VENDOR_ID_ELSA,
 		PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) {
 		if (pci_enable_device(dev_qs3000))
 			return(0);
@@ -1093,7 +1094,7 @@ setup_elsa_pci(struct IsdnCard *card)
 {
 	return (1);
 }
-#endif /* CONFIG_PCI_LEGACY */
+#endif /* CONFIG_PCI */
 
 static int __devinit
 setup_elsa_common(struct IsdnCard *card)
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/elsa_cs.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/elsa_cs.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/elsa_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/elsa_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -76,7 +76,7 @@ module_param(protocol, int, 0);
    handler.
 */
 
-static int elsa_cs_config(struct pcmcia_device *link);
+static int elsa_cs_config(struct pcmcia_device *link) __devinit ;
 static void elsa_cs_release(struct pcmcia_device *link);
 
 /*
@@ -85,7 +85,7 @@ static void elsa_cs_release(struct pcmci
    needed to manage one actual PCMCIA card.
 */
 
-static void elsa_cs_detach(struct pcmcia_device *p_dev);
+static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit;
 
 /*
    A driver needs to provide a dev_node_t structure for each device
@@ -121,7 +121,7 @@ typedef struct local_info_t {
 
 ======================================================================*/
 
-static int elsa_cs_probe(struct pcmcia_device *link)
+static int __devinit elsa_cs_probe(struct pcmcia_device *link)
 {
     local_info_t *local;
 
@@ -166,7 +166,7 @@ static int elsa_cs_probe(struct pcmcia_d
 
 ======================================================================*/
 
-static void elsa_cs_detach(struct pcmcia_device *link)
+static void __devexit elsa_cs_detach(struct pcmcia_device *link)
 {
 	local_info_t *info = link->priv;
 
@@ -210,7 +210,7 @@ static int elsa_cs_configcheck(struct pc
 	return -ENODEV;
 }
 
-static int elsa_cs_config(struct pcmcia_device *link)
+static int __devinit elsa_cs_config(struct pcmcia_device *link)
 {
     local_info_t *dev;
     int i;
@@ -327,7 +327,7 @@ static struct pcmcia_driver elsa_cs_driv
 		.name	= "elsa_cs",
 	},
 	.probe		= elsa_cs_probe,
-	.remove		= elsa_cs_detach,
+	.remove		= __devexit_p(elsa_cs_detach),
 	.id_table	= elsa_ids,
 	.suspend	= elsa_suspend,
 	.resume		= elsa_resume,
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/elsa_ser.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/elsa_ser.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/elsa_ser.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/elsa_ser.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 
 #include <linux/serial.h>
 #include <linux/serial_reg.h>
+#include <linux/slab.h>
 
 #define MAX_MODEM_BUF	256
 #define WAKEUP_CHARS	(MAX_MODEM_BUF/2)
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/enternow_pci.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/enternow_pci.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/enternow_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/enternow_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -406,7 +406,7 @@ setup_enternow_pci(struct IsdnCard *card
 
 	for ( ;; )
 	{
-		if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET,
+		if ((dev_netjet = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET,
 			PCI_DEVICE_ID_TIGERJET_300,  dev_netjet))) {
 			ret = en_pci_probe(dev_netjet, cs);
 			if (!ret)
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/fsm.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/fsm.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/fsm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/fsm.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include "hisax.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/gazel.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/gazel.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/gazel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/gazel.c	2010-05-16 17:17:36.000000000 -0400
@@ -531,7 +531,7 @@ setup_gazelisa(struct IsdnCard *card, st
 	return (0);
 }
 
-#ifdef CONFIG_PCI_LEGACY
+#ifdef CONFIG_PCI
 static struct pci_dev *dev_tel __devinitdata = NULL;
 
 static int __devinit
@@ -546,7 +546,7 @@ setup_gazelpci(struct IsdnCardState *cs)
 	found = 0;
 	seekcard = PCI_DEVICE_ID_PLX_R685;
 	for (nbseek = 0; nbseek < 4; nbseek++) {
-		if ((dev_tel = pci_find_device(PCI_VENDOR_ID_PLX,
+		if ((dev_tel = hisax_find_pci_device(PCI_VENDOR_ID_PLX,
 					seekcard, dev_tel))) {
 			if (pci_enable_device(dev_tel))
 				return 1;
@@ -620,7 +620,7 @@ setup_gazelpci(struct IsdnCardState *cs)
 
 	return (0);
 }
-#endif /* CONFIG_PCI_LEGACY */
+#endif /* CONFIG_PCI */
 
 int __devinit
 setup_gazel(struct IsdnCard *card)
@@ -640,7 +640,7 @@ setup_gazel(struct IsdnCard *card)
 			return (0);
 	} else {
 
-#ifdef CONFIG_PCI_LEGACY
+#ifdef CONFIG_PCI
 		if (setup_gazelpci(cs))
 			return (0);
 #else
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hfc_2bds0.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hfc_2bds0.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hfc_2bds0.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hfc_2bds0.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "hisax.h"
 #include "hfc_2bds0.h"
 #include "isdnl1.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hfc_2bs0.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hfc_2bs0.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hfc_2bs0.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hfc_2bs0.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include "isac.h"
 #include "isdnl1.h"
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 static inline int
 WaitForBusy(struct IsdnCardState *cs)
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hfc4s8s_l1.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hfc4s8s_l1.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hfc4s8s_l1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hfc4s8s_l1.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/skbuff.h>
 #include <linux/wait.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hfc_pci.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hfc_pci.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hfc_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hfc_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -1658,7 +1658,7 @@ setup_hfcpci(struct IsdnCard *card)
 
 	i = 0;
 	while (id_list[i].vendor_id) {
-		tmp_hfcpci = pci_find_device(id_list[i].vendor_id,
+		tmp_hfcpci = hisax_find_pci_device(id_list[i].vendor_id,
 					     id_list[i].device_id,
 					     dev_hfcpci);
 		i++;
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hfc_sx.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hfc_sx.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hfc_sx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hfc_sx.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include "isdnl1.h"
 #include <linux/interrupt.h>
 #include <linux/isapnp.h>
+#include <linux/slab.h>
 
 static const char *hfcsx_revision = "$Revision: 1.12.2.5 $";
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hfc_usb.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hfc_usb.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hfc_usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hfc_usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include "hisax.h"
 #include "hisax_if.h"
 #include "hfc_usb.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hisax.h linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hisax.h
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hisax.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hisax.h	2010-05-16 17:17:36.000000000 -0400
@@ -1323,3 +1323,26 @@ void release_tei(struct IsdnCardState *c
 char *HiSax_getrev(const char *revision);
 int TeiNew(void);
 void TeiFree(void);
+
+#ifdef CONFIG_PCI
+
+#include <linux/pci.h>
+
+/* adaptation wrapper for old usage
+ * WARNING! This is unfit for use in a PCI hotplug environment,
+ * as the returned PCI device can disappear at any moment in time.
+ * Callers should be converted to use pci_get_device() instead.
+ */
+static inline struct pci_dev *hisax_find_pci_device(unsigned int vendor,
+						    unsigned int device,
+						    struct pci_dev *from)
+{
+	struct pci_dev *pdev;
+
+	pci_dev_get(from);
+	pdev = pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
+	pci_dev_put(pdev);
+	return pdev;
+}
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hisax_isac.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hisax_isac.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hisax_isac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hisax_isac.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include "hisax_isac.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hscx.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hscx.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hscx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/hscx.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include "isac.h"
 #include "isdnl1.h"
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 static char *HSCXVer[] =
 {"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/icc.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/icc.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/icc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/icc.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 // #include "arcofi.h"
 #include "isdnl1.h"
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #define DBUSY_TIMER_VALUE 80
 #define ARCOFI_USE 0
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/ipacx.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/ipacx.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/ipacx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/ipacx.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  *
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include "hisax_if.h"
 #include "hisax.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/isac.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/isac.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/isac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/isac.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include "arcofi.h"
 #include "isdnl1.h"
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #define DBUSY_TIMER_VALUE 80
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/isar.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/isar.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/isar.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/isar.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include "isar.h"
 #include "isdnl1.h"
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #define DBG_LOADFIRM	0
 #define DUMP_MBOXFRAME	2
@@ -138,7 +139,7 @@ waitrecmsg(struct IsdnCardState *cs, u_c
 	while((!(cs->BC_Read_Reg(cs, 0, ISAR_IRQBIT) & ISAR_IRQSTA)) &&
 		(timeout++ < maxdelay))
 		udelay(1);
-	if (timeout >= maxdelay) {
+	if (timeout > maxdelay) {
 		printk(KERN_WARNING"isar recmsg IRQSTA timeout\n");
 		return(0);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/isdnl1.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/isdnl1.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/isdnl1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/isdnl1.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include "hisax.h"
 #include "isdnl1.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/isdnl2.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/isdnl2.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/isdnl2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/isdnl2.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include "hisax.h"
 #include "isdnl2.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/isdnl3.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/isdnl3.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/isdnl3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/isdnl3.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include "hisax.h"
 #include "isdnl3.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/jade.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/jade.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/jade.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/jade.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include "jade.h"
 #include "isdnl1.h"
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 
 int
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/Kconfig linux-libre-2.6.34-gnu1/drivers/isdn/hisax/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -109,7 +109,7 @@ config HISAX_16_3
 
 config HISAX_TELESPCI
 	bool "Teles PCI"
-	depends on PCI && PCI_LEGACY && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
 	help
 	  This enables HiSax support for the Teles PCI.
 	  See <file:Documentation/isdn/README.HiSax> on how to configure it.
@@ -237,7 +237,7 @@ config HISAX_MIC
 
 config HISAX_NETJET
 	bool "NETjet card"
-	depends on PCI && PCI_LEGACY && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
 	help
 	  This enables HiSax support for the NetJet from Traverse
 	  Technologies.
@@ -248,7 +248,7 @@ config HISAX_NETJET
 
 config HISAX_NETJET_U
 	bool "NETspider U card"
-	depends on PCI && PCI_LEGACY && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
 	help
 	  This enables HiSax support for the Netspider U interface ISDN card
 	  from Traverse Technologies.
@@ -287,7 +287,7 @@ config HISAX_HSTSAPHIR
 
 config HISAX_BKM_A4T
 	bool "Telekom A4T card"
-	depends on PCI && PCI_LEGACY
+	depends on PCI
 	help
 	  This enables HiSax support for the Telekom A4T card.
 
@@ -297,7 +297,7 @@ config HISAX_BKM_A4T
 
 config HISAX_SCT_QUADRO
 	bool "Scitel Quadro card"
-	depends on PCI && PCI_LEGACY
+	depends on PCI
 	help
 	  This enables HiSax support for the Scitel Quadro card.
 
@@ -316,7 +316,7 @@ config HISAX_GAZEL
 
 config HISAX_HFC_PCI
 	bool "HFC PCI-Bus cards"
-	depends on PCI && PCI_LEGACY && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
 	help
 	  This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
 
@@ -325,7 +325,7 @@ config HISAX_HFC_PCI
 
 config HISAX_W6692
 	bool "Winbond W6692 based cards"
-	depends on PCI && PCI_LEGACY
+	depends on PCI
 	help
 	  This enables HiSax support for Winbond W6692 based PCI ISDN cards.
 
@@ -341,7 +341,7 @@ config HISAX_HFC_SX
 
 config HISAX_ENTERNOW_PCI
 	bool "Formula-n enter:now PCI card"
-	depends on HISAX_NETJET && PCI && PCI_LEGACY && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+	depends on HISAX_NETJET && PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
 	help
 	  This enables HiSax support for the Formula-n enter:now PCI
 	  ISDN card.
@@ -412,7 +412,7 @@ config HISAX_HFC4S8S
 
 config HISAX_FRITZ_PCIPNP
 	tristate "AVM Fritz!Card PCI/PCIv2/PnP support (EXPERIMENTAL)"
-	depends on PCI && PCI_LEGACY && EXPERIMENTAL
+	depends on PCI && EXPERIMENTAL
 	help
 	  This enables the driver for the AVM Fritz!Card PCI,
 	  Fritz!Card PCI v2 and Fritz!Card PnP.
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/l3dss1.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/l3dss1.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/l3dss1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/l3dss1.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include "isdnl3.h"
 #include "l3dss1.h"
 #include <linux/ctype.h>
+#include <linux/slab.h>
 
 extern char *HiSax_getrev(const char *revision);
 static const char *dss1_revision = "$Revision: 2.32.2.3 $";
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/l3ni1.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/l3ni1.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/l3ni1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/l3ni1.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include "isdnl3.h"
 #include "l3ni1.h"
 #include <linux/ctype.h>
+#include <linux/slab.h>
 
 extern char *HiSax_getrev(const char *revision);
 static const char *ni1_revision = "$Revision: 2.8.2.3 $";
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/netjet.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/netjet.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/netjet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/netjet.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include "isdnl1.h"
 #include <linux/interrupt.h>
 #include <linux/ppp_defs.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include "netjet.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/niccy.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/niccy.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/niccy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/niccy.c	2010-05-16 17:17:36.000000000 -0400
@@ -297,12 +297,12 @@ int __devinit setup_niccy(struct IsdnCar
 			return 0;
 		}
 	} else {
-#ifdef CONFIG_PCI_LEGACY
+#ifdef CONFIG_PCI
 		static struct pci_dev *niccy_dev __devinitdata;
 
 		u_int pci_ioaddr;
 		cs->subtyp = 0;
-		if ((niccy_dev = pci_find_device(PCI_VENDOR_ID_SATSAGEM,
+		if ((niccy_dev = hisax_find_pci_device(PCI_VENDOR_ID_SATSAGEM,
 						 PCI_DEVICE_ID_SATSAGEM_NICCY,
 						 niccy_dev))) {
 			if (pci_enable_device(niccy_dev))
@@ -354,7 +354,7 @@ int __devinit setup_niccy(struct IsdnCar
 		printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n");
 		printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n");
 		return 0;
-#endif				/* CONFIG_PCI_LEGACY */
+#endif				/* CONFIG_PCI */
 	}
 	printk(KERN_INFO "HiSax: NICCY %s config irq:%d data:0x%X ale:0x%X\n",
 		(cs->subtyp == 1) ? "PnP" : "PCI",
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/nj_s.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/nj_s.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/nj_s.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/nj_s.c	2010-05-16 17:17:36.000000000 -0400
@@ -276,7 +276,7 @@ setup_netjet_s(struct IsdnCard *card)
 
 	for ( ;; )
 	{
-		if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET,
+		if ((dev_netjet = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET,
 			PCI_DEVICE_ID_TIGERJET_300,  dev_netjet))) {
 			ret = njs_pci_probe(dev_netjet, cs);
 			if (!ret)
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/nj_u.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/nj_u.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/nj_u.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/nj_u.c	2010-05-16 17:17:36.000000000 -0400
@@ -240,7 +240,7 @@ setup_netjet_u(struct IsdnCard *card)
 
 	for ( ;; )
 	{
-		if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET,
+		if ((dev_netjet = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET,
 			PCI_DEVICE_ID_TIGERJET_300,  dev_netjet))) {
 			ret = nju_pci_probe(dev_netjet, cs);
 			if (!ret)
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/sedlbauer.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/sedlbauer.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/sedlbauer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/sedlbauer.c	2010-05-16 17:17:36.000000000 -0400
@@ -598,7 +598,7 @@ setup_sedlbauer_isapnp(struct IsdnCard *
 }
 #endif /* __ISAPNP__ */
 
-#ifdef CONFIG_PCI_LEGACY
+#ifdef CONFIG_PCI
 static struct pci_dev *dev_sedl __devinitdata = NULL;
 
 static int __devinit
@@ -607,7 +607,7 @@ setup_sedlbauer_pci(struct IsdnCard *car
 	struct IsdnCardState *cs = card->cs;
 	u16 sub_vendor_id, sub_id;
 
-	if ((dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET,
+	if ((dev_sedl = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET,
 			PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) {
 		if (pci_enable_device(dev_sedl))
 			return(0);
@@ -673,7 +673,7 @@ setup_sedlbauer_pci(struct IsdnCard *car
 	return (1);
 }
 
-#endif /* CONFIG_PCI_LEGACY */
+#endif /* CONFIG_PCI */
 
 int __devinit
 setup_sedlbauer(struct IsdnCard *card)
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/sedlbauer_cs.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/sedlbauer_cs.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/sedlbauer_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/sedlbauer_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -76,7 +76,7 @@ module_param(protocol, int, 0);
    event handler. 
 */
 
-static int sedlbauer_config(struct pcmcia_device *link);
+static int sedlbauer_config(struct pcmcia_device *link) __devinit ;
 static void sedlbauer_release(struct pcmcia_device *link);
 
 /*
@@ -85,7 +85,7 @@ static void sedlbauer_release(struct pcm
    needed to manage one actual PCMCIA card.
 */
 
-static void sedlbauer_detach(struct pcmcia_device *p_dev);
+static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit;
 
 /*
    You'll also need to prototype all the functions that will actually
@@ -129,7 +129,7 @@ typedef struct local_info_t {
     
 ======================================================================*/
 
-static int sedlbauer_probe(struct pcmcia_device *link)
+static int __devinit sedlbauer_probe(struct pcmcia_device *link)
 {
     local_info_t *local;
 
@@ -177,7 +177,7 @@ static int sedlbauer_probe(struct pcmcia
 
 ======================================================================*/
 
-static void sedlbauer_detach(struct pcmcia_device *link)
+static void __devexit sedlbauer_detach(struct pcmcia_device *link)
 {
 	dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link);
 
@@ -283,7 +283,7 @@ static int sedlbauer_config_check(struct
 
 
 
-static int sedlbauer_config(struct pcmcia_device *link)
+static int __devinit sedlbauer_config(struct pcmcia_device *link)
 {
     local_info_t *dev = link->priv;
     win_req_t *req;
@@ -441,7 +441,7 @@ static struct pcmcia_driver sedlbauer_dr
 		.name	= "sedlbauer_cs",
 	},
 	.probe		= sedlbauer_probe,
-	.remove		= sedlbauer_detach,
+	.remove		= __devexit_p(sedlbauer_detach),
 	.id_table	= sedlbauer_ids,
 	.suspend	= sedlbauer_suspend,
 	.resume		= sedlbauer_resume,
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/st5481_b.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/st5481_b.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/st5481_b.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/st5481_b.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,8 +11,8 @@
  */
 
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/usb.h>
-#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/bitrev.h>
 #include "st5481.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/st5481_d.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/st5481_d.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/st5481_d.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/st5481_d.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,8 +11,8 @@
  */
 
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/usb.h>
-#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include "st5481.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/tei.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/tei.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/tei.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/tei.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 
 #include "hisax.h"
 #include "isdnl2.h"
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/random.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/teles_cs.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/teles_cs.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/teles_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/teles_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,7 +57,7 @@ module_param(protocol, int, 0);
    handler.
 */
 
-static int teles_cs_config(struct pcmcia_device *link);
+static int teles_cs_config(struct pcmcia_device *link) __devinit ;
 static void teles_cs_release(struct pcmcia_device *link);
 
 /*
@@ -66,7 +66,7 @@ static void teles_cs_release(struct pcmc
    needed to manage one actual PCMCIA card.
 */
 
-static void teles_detach(struct pcmcia_device *p_dev);
+static void teles_detach(struct pcmcia_device *p_dev) __devexit ;
 
 /*
    A linked list of "instances" of the teles_cs device.  Each actual
@@ -112,7 +112,7 @@ typedef struct local_info_t {
 
 ======================================================================*/
 
-static int teles_probe(struct pcmcia_device *link)
+static int __devinit teles_probe(struct pcmcia_device *link)
 {
     local_info_t *local;
 
@@ -156,7 +156,7 @@ static int teles_probe(struct pcmcia_dev
 
 ======================================================================*/
 
-static void teles_detach(struct pcmcia_device *link)
+static void __devexit teles_detach(struct pcmcia_device *link)
 {
 	local_info_t *info = link->priv;
 
@@ -200,7 +200,7 @@ static int teles_cs_configcheck(struct p
 	return -ENODEV;
 }
 
-static int teles_cs_config(struct pcmcia_device *link)
+static int __devinit teles_cs_config(struct pcmcia_device *link)
 {
     local_info_t *dev;
     int i;
@@ -319,7 +319,7 @@ static struct pcmcia_driver teles_cs_dri
 		.name	= "teles_cs",
 	},
 	.probe		= teles_probe,
-	.remove		= teles_detach,
+	.remove		= __devexit_p(teles_detach),
 	.id_table       = teles_ids,
 	.suspend	= teles_suspend,
 	.resume		= teles_resume,
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/telespci.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/telespci.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/telespci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/telespci.c	2010-05-16 17:17:36.000000000 -0400
@@ -300,7 +300,7 @@ setup_telespci(struct IsdnCard *card)
 	if (cs->typ != ISDN_CTYPE_TELESPCI)
 		return (0);
 
-	if ((dev_tel = pci_find_device (PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) {
+	if ((dev_tel = hisax_find_pci_device (PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) {
 		if (pci_enable_device(dev_tel))
 			return(0);
 		cs->irq = dev_tel->irq;
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hisax/w6692.c linux-libre-2.6.34-gnu1/drivers/isdn/hisax/w6692.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hisax/w6692.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hisax/w6692.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include "isdnl1.h"
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 /* table entry in the PCI devices list */
 typedef struct {
@@ -1007,7 +1008,7 @@ setup_w6692(struct IsdnCard *card)
 		return (0);
 
 	while (id_list[id_idx].vendor_id) {
-		dev_w6692 = pci_find_device(id_list[id_idx].vendor_id,
+		dev_w6692 = hisax_find_pci_device(id_list[id_idx].vendor_id,
 					    id_list[id_idx].device_id,
 					    dev_w6692);
 		if (dev_w6692) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hysdn/hycapi.c linux-libre-2.6.34-gnu1/drivers/isdn/hysdn/hycapi.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hysdn/hycapi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hysdn/hycapi.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,10 +11,13 @@
  */
 
 #include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/signal.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 
 #define	VER_DRIVER	0
 #define	VER_CARDTYPE	1
@@ -432,26 +435,16 @@ static u16 hycapi_send_message(struct ca
 	return retval;
 }
 
-/*********************************************************************
-hycapi_read_proc
-
-Informations provided in the /proc/capi-entries.
-
-*********************************************************************/
-
-static int hycapi_read_proc(char *page, char **start, off_t off,
-			    int count, int *eof, struct capi_ctr *ctrl)
+static int hycapi_proc_show(struct seq_file *m, void *v)
 {
+	struct capi_ctr *ctrl = m->private;
 	hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
 	hysdn_card *card = cinfo->card;
-	int len = 0;
 	char *s;
-#ifdef HYCAPI_PRINTFNAMES
-	printk(KERN_NOTICE "hycapi_read_proc\n");    
-#endif
-	len += sprintf(page+len, "%-16s %s\n", "name", cinfo->cardname);
-	len += sprintf(page+len, "%-16s 0x%x\n", "io", card->iobase);
-	len += sprintf(page+len, "%-16s %d\n", "irq", card->irq);
+
+	seq_printf(m, "%-16s %s\n", "name", cinfo->cardname);
+	seq_printf(m, "%-16s 0x%x\n", "io", card->iobase);
+	seq_printf(m, "%-16s %d\n", "irq", card->irq);
     
 	switch (card->brdtype) {
 		case BD_PCCARD:  s = "HYSDN Hycard"; break;
@@ -461,24 +454,32 @@ static int hycapi_read_proc(char *page,
 		case BD_PLEXUS: s = "HYSDN Plexus30"; break;
 		default: s = "???"; break;
 	}
-	len += sprintf(page+len, "%-16s %s\n", "type", s);
+	seq_printf(m, "%-16s %s\n", "type", s);
 	if ((s = cinfo->version[VER_DRIVER]) != NULL)
-		len += sprintf(page+len, "%-16s %s\n", "ver_driver", s);
+		seq_printf(m, "%-16s %s\n", "ver_driver", s);
 	if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
-		len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s);
+		seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
 	if ((s = cinfo->version[VER_SERIAL]) != NULL)
-		len += sprintf(page+len, "%-16s %s\n", "ver_serial", s);
+		seq_printf(m, "%-16s %s\n", "ver_serial", s);
     
-	len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname);
+	seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
     
-	if (off+count >= len)
-		*eof = 1;
-	if (len < off)
-		return 0;
-	*start = page + off;
-	return ((count < len-off) ? count : len-off);
+	return 0;
+}
+
+static int hycapi_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, hycapi_proc_show, PDE(inode)->data);
 }
 
+static const struct file_operations hycapi_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= hycapi_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /**************************************************************
 hycapi_load_firmware
 
@@ -774,7 +775,7 @@ hycapi_capi_create(hysdn_card *card)
 		ctrl->load_firmware = hycapi_load_firmware;
 		ctrl->reset_ctr     = hycapi_reset_ctr;
 		ctrl->procinfo      = hycapi_procinfo;
-		ctrl->ctr_read_proc = hycapi_read_proc;
+		ctrl->proc_fops = &hycapi_proc_fops;
 		strcpy(ctrl->name, cinfo->cardname);
 		ctrl->owner = THIS_MODULE;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hysdn/hysdn_boot.c linux-libre-2.6.34-gnu1/drivers/isdn/hysdn/hysdn_boot.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hysdn/hysdn_boot.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hysdn/hysdn_boot.c	2010-05-16 17:17:36.000000000 -0400
@@ -143,7 +143,7 @@ pof_handle_data(hysdn_card * card, int d
 					     (boot->pof_recid == TAG_CABSDATA) ? "CABSDATA" : "ABSDATA",
 					     datlen, boot->pof_recoffset);
 
-			if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen) < 0))
+			if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen)) < 0)
 				return (boot->last_error);	/* error writing data */
 
 			if (boot->pof_recoffset + datlen >= boot->pof_reclen)
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hysdn/hysdn_procconf.c linux-libre-2.6.34-gnu1/drivers/isdn/hysdn/hysdn_procconf.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hysdn/hysdn_procconf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hysdn/hysdn_procconf.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <net/net_namespace.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/hysdn/hysdn_proclog.c linux-libre-2.6.34-gnu1/drivers/isdn/hysdn/hysdn_proclog.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/hysdn/hysdn_proclog.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/hysdn/hysdn_proclog.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 
 #include "hysdn_defs.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_audio.c linux-libre-2.6.34-gnu1/drivers/isdn/i4l/isdn_audio.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_audio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/i4l/isdn_audio.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
  */
 
 #include <linux/isdn.h>
+#include <linux/slab.h>
 #include "isdn_audio.h"
 #include "isdn_common.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_common.c linux-libre-2.6.34-gnu1/drivers/isdn/i4l/isdn_common.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/i4l/isdn_common.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/isdn.h>
 #include <linux/smp_lock.h>
@@ -1347,7 +1348,7 @@ isdn_ioctl(struct inode *inode, struct f
 /*
  * isdn net devices manage lots of configuration variables as linked lists.
  * Those lists must only be manipulated from user space. Some of the ioctl's
- * service routines access user space and are not atomic. Therefor, ioctl's
+ * service routines access user space and are not atomic. Therefore, ioctl's
  * manipulating the lists and ioctl's sleeping while accessing the lists
  * are serialized by means of a semaphore.
  */
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_net.c linux-libre-2.6.34-gnu1/drivers/isdn/i4l/isdn_net.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_net.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/i4l/isdn_net.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
  */
 
 #include <linux/isdn.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 #include <net/dst.h>
 #include <net/pkt_sched.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_ppp.c linux-libre-2.6.34-gnu1/drivers/isdn/i4l/isdn_ppp.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_ppp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/i4l/isdn_ppp.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/isdn.h>
 #include <linux/poll.h>
 #include <linux/ppp-comp.h>
+#include <linux/slab.h>
 #ifdef CONFIG_IPPP_FILTER
 #include <linux/filter.h>
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_tty.c linux-libre-2.6.34-gnu1/drivers/isdn/i4l/isdn_tty.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_tty.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/i4l/isdn_tty.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #undef ISDN_TTY_STAT_DEBUG
 
 #include <linux/isdn.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/smp_lock.h>
 #include "isdn_common.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_x25iface.c linux-libre-2.6.34-gnu1/drivers/isdn/i4l/isdn_x25iface.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_x25iface.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/i4l/isdn_x25iface.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 /* #include <linux/isdn.h> */
 #include <linux/netdevice.h>
 #include <linux/concap.h>
+#include <linux/slab.h>
 #include <linux/wanrouter.h>
 #include <net/x25device.h>
 #include "isdn_x25iface.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/i4l/Kconfig linux-libre-2.6.34-gnu1/drivers/isdn/i4l/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/isdn/i4l/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/i4l/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -134,14 +134,7 @@ source "drivers/isdn/sc/Kconfig"
 
 source "drivers/isdn/act2000/Kconfig"
 
-source "drivers/isdn/hysdn/Kconfig"
-
 endmenu
 # end ISDN_I4L
 endif
 
-config ISDN_HDLC
-	tristate
-	select CRC_CCITT
-	select BITREVERSE
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/icn/icn.c linux-libre-2.6.34-gnu1/drivers/isdn/icn/icn.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/icn/icn.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/icn/icn.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include "icn.h"
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 static int portbase = ICN_BASEADDR;
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/isdnloop/isdnloop.c linux-libre-2.6.34-gnu1/drivers/isdn/isdnloop/isdnloop.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/isdnloop/isdnloop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/isdnloop/isdnloop.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include "isdnloop.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/Kconfig linux-libre-2.6.34-gnu1/drivers/isdn/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/isdn/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -7,15 +7,14 @@ menuconfig ISDN
 	depends on NET
 	depends on !S390
 	---help---
-	  ISDN ("Integrated Services Digital Networks", called RNIS in France)
-	  is a special type of fully digital telephone service; it's mostly
-	  used to connect to your Internet service provider (with SLIP or
-	  PPP).  The main advantage is that the speed is higher than ordinary
-	  modem/telephone connections, and that you can have voice
-	  conversations while downloading stuff.  It only works if your
-	  computer is equipped with an ISDN card and both you and your service
-	  provider purchased an ISDN line from the phone company.  For
-	  details, read <http://www.alumni.caltech.edu/~dank/isdn/> on the WWW.
+	  ISDN ("Integrated Services Digital Network", called RNIS in France)
+	  is a fully digital telephone service that can be used for voice and
+	  data connections.  If your computer is equipped with an ISDN
+	  adapter you can use it to connect to your Internet service provider
+	  (with SLIP or PPP) faster than via a conventional telephone modem
+	  (though still much slower than with DSL) or to make and accept
+	  voice calls (eg. turning your PC into a software answering machine
+	  or PABX).
 
 	  Select this option if you want your kernel to support ISDN.
 
@@ -39,17 +38,22 @@ menuconfig ISDN_I4L
 	  It is still available, though, for use with adapters that are not
 	  supported by the new CAPI subsystem yet.
 
-source "drivers/isdn/mISDN/Kconfig"
-
 source "drivers/isdn/i4l/Kconfig"
 
 menuconfig ISDN_CAPI
 	tristate "CAPI 2.0 subsystem"
 	help
-	  This provides the CAPI (Common ISDN Application Programming
-	  Interface, a standard making it easy for programs to access ISDN
-	  hardware, see <http://www.capi.org/>.  This is needed for AVM's set
-	  of active ISDN controllers like B1, T1, M1.
+	  This provides CAPI (the Common ISDN Application Programming
+	  Interface) Version 2.0, a standard making it easy for programs to
+	  access ISDN hardware in a device independent way. (For details see
+	  <http://www.capi.org/>.)  CAPI supports making and accepting voice
+	  and data connections, controlling call options and protocols,
+	  as well as ISDN supplementary services like call forwarding or
+	  three-party conferences (if supported by the specific hardware
+	  driver).
+
+	  Select this option and the appropriate hardware driver below if
+	  you have an ISDN adapter supported by the CAPI subsystem.
 
 if ISDN_CAPI
 
@@ -61,4 +65,13 @@ endif # ISDN_CAPI
 
 source "drivers/isdn/gigaset/Kconfig"
 
+source "drivers/isdn/hysdn/Kconfig"
+
+source "drivers/isdn/mISDN/Kconfig"
+
+config ISDN_HDLC
+	tristate
+	select CRC_CCITT
+	select BITREVERSE
+
 endif # ISDN
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/clock.c linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/clock.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/clock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/clock.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/stddef.h>
 #include <linux/spinlock.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/core.c linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/core.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/stddef.h>
 #include <linux/module.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/dsp_cmx.c linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/dsp_cmx.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/dsp_cmx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/dsp_cmx.c	2010-05-16 17:17:36.000000000 -0400
@@ -124,6 +124,7 @@
 
 /* delay.h is required for hw_lock.h */
 
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/mISDNif.h>
 #include <linux/mISDNdsp.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/dsp_core.c linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/dsp_core.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/dsp_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/dsp_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -154,6 +154,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/mISDNif.h>
 #include <linux/mISDNdsp.h>
 #include <linux/module.h>
@@ -1114,7 +1115,7 @@ static struct Bprotocol DSP = {
 	.create = dspcreate
 };
 
-static int dsp_init(void)
+static int __init dsp_init(void)
 {
 	int err;
 	int tics;
@@ -1212,7 +1213,7 @@ static int dsp_init(void)
 }
 
 
-static void dsp_cleanup(void)
+static void __exit dsp_cleanup(void)
 {
 	mISDN_unregister_Bprotocol(&DSP);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/dsp_pipeline.c linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/dsp_pipeline.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/dsp_pipeline.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/dsp_pipeline.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/string.h>
 #include <linux/mISDNif.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/dsp_tones.c linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/dsp_tones.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/dsp_tones.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/dsp_tones.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  *
  */
 
+#include <linux/gfp.h>
 #include <linux/mISDNif.h>
 #include <linux/mISDNdsp.h>
 #include "core.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/hwchannel.c linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/hwchannel.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/hwchannel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/hwchannel.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
  *
  */
 
+#include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/mISDNhw.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/l1oip_core.c linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/l1oip_core.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/l1oip_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/l1oip_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -233,6 +233,7 @@ socket process and create a new one.
 #include <linux/inet.h>
 #include <linux/workqueue.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include "core.h"
 #include "l1oip.h"
@@ -477,7 +478,7 @@ l1oip_socket_parse(struct l1oip *hc, str
 		printk(KERN_DEBUG "%s: received frame, parsing... (%d)\n",
 			__func__, len);
 
-	/* check lenght */
+	/* check length */
 	if (len < 1+1+2) {
 		printk(KERN_WARNING "%s: packet error - length %d below "
 			"4 bytes\n", __func__, len);
@@ -1509,7 +1510,7 @@ l1oip_init(void)
 			printk(KERN_DEBUG "%s: interface %d is %s with %s.\n",
 			    __func__, l1oip_cnt, pri ? "PRI" : "BRI",
 			    bundle ? "bundled IP packet for all B-channels" :
-			    "seperate IP packets for every B-channel");
+			    "separate IP packets for every B-channel");
 
 		hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC);
 		if (!hc) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/layer1.c linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/layer1.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/layer1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/layer1.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
  */
 
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/mISDNhw.h>
 #include "core.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/layer2.c linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/layer2.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/layer2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/layer2.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
  */
 
 #include <linux/mISDNif.h>
+#include <linux/slab.h>
 #include "core.h"
 #include "fsm.h"
 #include "layer2.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/socket.c linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/socket.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/socket.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/socket.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
  */
 
 #include <linux/mISDNif.h>
+#include <linux/slab.h>
 #include "core.h"
 
 static u_int	*debug;
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/stack.c linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/stack.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/stack.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/stack.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/mISDNif.h>
 #include <linux/kthread.h>
 #include <linux/smp_lock.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/tei.c linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/tei.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/tei.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/tei.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
  */
 #include "layer2.h"
 #include <linux/random.h>
+#include <linux/slab.h>
 #include "core.h"
 
 #define ID_REQUEST	1
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/timerdev.c linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/timerdev.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/timerdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/mISDN/timerdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 
 #include <linux/poll.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/pcbit/callbacks.c linux-libre-2.6.34-gnu1/drivers/isdn/pcbit/callbacks.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/pcbit/callbacks.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/pcbit/callbacks.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/kernel.h>
 
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/skbuff.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/pcbit/edss1.c linux-libre-2.6.34-gnu1/drivers/isdn/pcbit/edss1.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/pcbit/edss1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/pcbit/edss1.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/kernel.h>
 
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/skbuff.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/sc/hardware.h linux-libre-2.6.34-gnu1/drivers/isdn/sc/hardware.h
--- linux-libre-2.6.33-gnu1/drivers/isdn/sc/hardware.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/sc/hardware.h	2010-05-16 17:17:36.000000000 -0400
@@ -87,7 +87,7 @@
 #define BRI_CHANNELS	2		/* Number of B channels */
 #define BRI_BASEPG_VAL	0x98
 #define BRI_MAGIC	0x60000		/* Magic Number */
-#define BRI_MEMSIZE	0x10000		/* Ammount of RAM (64K) */
+#define BRI_MEMSIZE	0x10000		/* Amount of RAM (64K) */
 #define BRI_PARTNO	"72-029"
 #define BRI_FEATURES	ISDN_FEATURE_L2_HDLC | ISDN_FEATURE_L3_TRANS;
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/isdn/sc/init.c linux-libre-2.6.34-gnu1/drivers/isdn/sc/init.c
--- linux-libre-2.6.33-gnu1/drivers/isdn/sc/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/isdn/sc/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "includes.h"
 #include "hardware.h"
 #include "card.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/Kconfig linux-libre-2.6.34-gnu1/drivers/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -96,8 +96,6 @@ source "drivers/edac/Kconfig"
 
 source "drivers/rtc/Kconfig"
 
-source "drivers/clocksource/Kconfig"
-
 source "drivers/dma/Kconfig"
 
 source "drivers/dca/Kconfig"
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/dell-led.c linux-libre-2.6.34-gnu1/drivers/leds/dell-led.c
--- linux-libre-2.6.33-gnu1/drivers/leds/dell-led.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/dell-led.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,201 @@
+/*
+ * dell_led.c - Dell LED Driver
+ *
+ * Copyright (C) 2010 Dell Inc.
+ * Louis Davis <louis_davis@dell.com>
+ * Jim Dailey <jim_dailey@dell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/acpi.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+
+MODULE_AUTHOR("Louis Davis/Jim Dailey");
+MODULE_DESCRIPTION("Dell LED Control Driver");
+MODULE_LICENSE("GPL");
+
+#define DELL_LED_BIOS_GUID "F6E4FE6E-909D-47cb-8BAB-C9F6F2F8D396"
+MODULE_ALIAS("wmi:" DELL_LED_BIOS_GUID);
+
+/* Error Result Codes: */
+#define INVALID_DEVICE_ID	250
+#define INVALID_PARAMETER	251
+#define INVALID_BUFFER		252
+#define INTERFACE_ERROR		253
+#define UNSUPPORTED_COMMAND	254
+#define UNSPECIFIED_ERROR	255
+
+/* Device ID */
+#define DEVICE_ID_PANEL_BACK	1
+
+/* LED Commands */
+#define CMD_LED_ON	16
+#define CMD_LED_OFF	17
+#define CMD_LED_BLINK	18
+
+struct bios_args {
+	unsigned char length;
+	unsigned char result_code;
+	unsigned char device_id;
+	unsigned char command;
+	unsigned char on_time;
+	unsigned char off_time;
+};
+
+static int dell_led_perform_fn(u8 length,
+		u8 result_code,
+		u8 device_id,
+		u8 command,
+		u8 on_time,
+		u8 off_time)
+{
+	struct bios_args *bios_return;
+	u8 return_code;
+	union acpi_object *obj;
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_buffer input;
+	acpi_status status;
+
+	struct bios_args args;
+	args.length = length;
+	args.result_code = result_code;
+	args.device_id = device_id;
+	args.command = command;
+	args.on_time = on_time;
+	args.off_time = off_time;
+
+	input.length = sizeof(struct bios_args);
+	input.pointer = &args;
+
+	status = wmi_evaluate_method(DELL_LED_BIOS_GUID,
+		1,
+		1,
+		&input,
+		&output);
+
+	if (ACPI_FAILURE(status))
+		return status;
+
+	obj = output.pointer;
+
+	if (!obj)
+		return -EINVAL;
+	else if (obj->type != ACPI_TYPE_BUFFER) {
+		kfree(obj);
+		return -EINVAL;
+	}
+
+	bios_return = ((struct bios_args *)obj->buffer.pointer);
+	return_code = bios_return->result_code;
+
+	kfree(obj);
+
+	return return_code;
+}
+
+static int led_on(void)
+{
+	return dell_led_perform_fn(3,	/* Length of command */
+		INTERFACE_ERROR,	/* Init to  INTERFACE_ERROR */
+		DEVICE_ID_PANEL_BACK,	/* Device ID */
+		CMD_LED_ON,		/* Command */
+		0,			/* not used */
+		0);			/* not used */
+}
+
+static int led_off(void)
+{
+	return dell_led_perform_fn(3,	/* Length of command */
+		INTERFACE_ERROR,	/* Init to  INTERFACE_ERROR */
+		DEVICE_ID_PANEL_BACK,	/* Device ID */
+		CMD_LED_OFF,		/* Command */
+		0,			/* not used */
+		0);			/* not used */
+}
+
+static int led_blink(unsigned char on_eighths,
+		unsigned char off_eighths)
+{
+	return dell_led_perform_fn(5,	/* Length of command */
+		INTERFACE_ERROR,	/* Init to  INTERFACE_ERROR */
+		DEVICE_ID_PANEL_BACK,	/* Device ID */
+		CMD_LED_BLINK,		/* Command */
+		on_eighths,		/* blink on in eigths of a second */
+		off_eighths);		/* blink off in eights of a second */
+}
+
+static void dell_led_set(struct led_classdev *led_cdev,
+		enum led_brightness value)
+{
+	if (value == LED_OFF)
+		led_off();
+	else
+		led_on();
+}
+
+static int dell_led_blink(struct led_classdev *led_cdev,
+		unsigned long *delay_on,
+		unsigned long *delay_off)
+{
+	unsigned long on_eighths;
+	unsigned long off_eighths;
+
+	/* The Dell LED delay is based on 125ms intervals.
+	   Need to round up to next interval. */
+
+	on_eighths = (*delay_on + 124) / 125;
+	if (0 == on_eighths)
+		on_eighths = 1;
+	if (on_eighths > 255)
+		on_eighths = 255;
+	*delay_on = on_eighths * 125;
+
+	off_eighths = (*delay_off + 124) / 125;
+	if (0 == off_eighths)
+		off_eighths = 1;
+	if (off_eighths > 255)
+		off_eighths = 255;
+	*delay_off = off_eighths * 125;
+
+	led_blink(on_eighths, off_eighths);
+
+	return 0;
+}
+
+static struct led_classdev dell_led = {
+	.name		= "dell::lid",
+	.brightness	= LED_OFF,
+	.max_brightness = 1,
+	.brightness_set = dell_led_set,
+	.blink_set	= dell_led_blink,
+	.flags		= LED_CORE_SUSPENDRESUME,
+};
+
+static int __init dell_led_init(void)
+{
+	int error = 0;
+
+	if (!wmi_has_guid(DELL_LED_BIOS_GUID))
+		return -ENODEV;
+
+	error = led_off();
+	if (error != 0)
+		return -ENODEV;
+
+	return led_classdev_register(NULL, &dell_led);
+}
+
+static void __exit dell_led_exit(void)
+{
+	led_classdev_unregister(&dell_led);
+
+	led_off();
+}
+
+module_init(dell_led_init);
+module_exit(dell_led_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/Kconfig linux-libre-2.6.34-gnu1/drivers/leds/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/leds/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -15,77 +15,86 @@ config LEDS_CLASS
 	  This option enables the led sysfs class in /sys/class/leds.  You'll
 	  need this to do anything useful with LEDs.  If unsure, say N.
 
+if LEDS_CLASS
+
 comment "LED drivers"
 
+config LEDS_88PM860X
+	tristate "LED Support for Marvell 88PM860x PMIC"
+	depends on LEDS_CLASS && MFD_88PM860X
+	help
+	  This option enables support for on-chip LED drivers found on Marvell
+	  Semiconductor 88PM8606 PMIC.
+
 config LEDS_ATMEL_PWM
 	tristate "LED Support using Atmel PWM outputs"
-	depends on LEDS_CLASS && ATMEL_PWM
+	depends on ATMEL_PWM
 	help
 	  This option enables support for LEDs driven using outputs
 	  of the dedicated PWM controller found on newer Atmel SOCs.
 
 config LEDS_LOCOMO
 	tristate "LED Support for Locomo device"
-	depends on LEDS_CLASS && SHARP_LOCOMO
+	depends on SHARP_LOCOMO
 	help
 	  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
+	depends on 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
+	depends on ARCH_S3C2410
 	help
 	  This option enables support for LEDs connected to GPIO lines
 	  on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440.
 
 config LEDS_AMS_DELTA
 	tristate "LED Support for the Amstrad Delta (E3)"
-	depends on LEDS_CLASS && MACH_AMS_DELTA
+	depends on MACH_AMS_DELTA
 	help
 	  This option enables support for the LEDs on Amstrad Delta (E3).
 
 config LEDS_NET48XX
 	tristate "LED Support for Soekris net48xx series Error LED"
-	depends on LEDS_CLASS && SCx200_GPIO
+	depends on SCx200_GPIO
 	help
 	  This option enables support for the Soekris net4801 and net4826 error
 	  LED.
 
 config LEDS_FSG
 	tristate "LED Support for the Freecom FSG-3"
-	depends on LEDS_CLASS && MACH_FSG
+	depends on MACH_FSG
 	help
 	  This option enables support for the LEDs on the Freecom FSG-3.
 
 config LEDS_WRAP
 	tristate "LED Support for the WRAP series LEDs"
-	depends on LEDS_CLASS && SCx200_GPIO
+	depends on SCx200_GPIO
 	help
 	  This option enables support for the PCEngines WRAP programmable LEDs.
 
 config LEDS_ALIX2
 	tristate "LED Support for ALIX.2 and ALIX.3 series"
-	depends on LEDS_CLASS && X86 && EXPERIMENTAL
+	depends on X86 && !GPIO_CS5535 && !CS5535_GPIO
 	help
 	  This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs.
 	  You have to set leds-alix2.force=1 for boards with Award BIOS.
 
 config LEDS_H1940
 	tristate "LED Support for iPAQ H1940 device"
-	depends on LEDS_CLASS && ARCH_H1940
+	depends on ARCH_H1940
 	help
 	  This option enables support for the LEDs on the h1940.
 
 config LEDS_COBALT_QUBE
 	tristate "LED Support for the Cobalt Qube series front LED"
-	depends on LEDS_CLASS && MIPS_COBALT
+	depends on MIPS_COBALT
 	help
 	  This option enables support for the front LED on Cobalt Qube series
 
@@ -98,7 +107,7 @@ config LEDS_COBALT_RAQ
 
 config LEDS_SUNFIRE
 	tristate "LED support for SunFire servers."
-	depends on LEDS_CLASS && SPARC64
+	depends on SPARC64
 	select LEDS_TRIGGERS
 	help
 	  This option enables support for the Left, Middle, and Right
@@ -106,14 +115,14 @@ config LEDS_SUNFIRE
 
 config LEDS_HP6XX
 	tristate "LED Support for the HP Jornada 6xx"
-	depends on LEDS_CLASS && SH_HP6XX
+	depends on SH_HP6XX
 	help
 	  This option enables LED support for the handheld
 	  HP Jornada 620/660/680/690.
 
 config LEDS_PCA9532
 	tristate "LED driver for PCA9532 dimmer"
-	depends on LEDS_CLASS && I2C && INPUT && EXPERIMENTAL
+	depends on I2C && INPUT && EXPERIMENTAL
 	help
 	  This option enables support for NXP pca9532
 	  LED controller. It is generally only useful
@@ -121,7 +130,7 @@ config LEDS_PCA9532
 
 config LEDS_GPIO
 	tristate "LED Support for GPIO connected LEDs"
-	depends on LEDS_CLASS && GENERIC_GPIO
+	depends on GENERIC_GPIO
 	help
 	  This option enables support for the LEDs connected to GPIO
 	  outputs. To be useful the particular board must have LEDs
@@ -148,7 +157,7 @@ config LEDS_GPIO_OF
 
 config LEDS_LP3944
 	tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip"
-	depends on LEDS_CLASS && I2C
+	depends on I2C
 	help
 	  This option enables support for LEDs connected to the National
 	  Semiconductor LP3944 Lighting Management Unit (LMU) also known as
@@ -159,7 +168,7 @@ config LEDS_LP3944
 
 config LEDS_CLEVO_MAIL
 	tristate "Mail LED on Clevo notebook"
-	depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI
+	depends on X86 && SERIO_I8042 && DMI
 	help
 	  This driver makes the mail LED accessible from userspace
 	  programs through the leds subsystem. This LED have three
@@ -189,7 +198,7 @@ config LEDS_CLEVO_MAIL
 
 config LEDS_PCA955X
 	tristate "LED Support for PCA955x I2C chips"
-	depends on LEDS_CLASS && I2C
+	depends on I2C
 	help
 	  This option enables support for LEDs connected to PCA955x
 	  LED driver chips accessed via the I2C bus.  Supported
@@ -197,54 +206,54 @@ config LEDS_PCA955X
 
 config LEDS_WM831X_STATUS
 	tristate "LED support for status LEDs on WM831x PMICs"
-	depends on LEDS_CLASS && MFD_WM831X
+	depends on MFD_WM831X
 	help
 	  This option enables support for the status LEDs of the WM831x
           series of PMICs.
 
 config LEDS_WM8350
 	tristate "LED Support for WM8350 AudioPlus PMIC"
-	depends on LEDS_CLASS && MFD_WM8350
+	depends on MFD_WM8350
 	help
 	  This option enables support for LEDs driven by the Wolfson
 	  Microelectronics WM8350 AudioPlus PMIC.
 
 config LEDS_DA903X
 	tristate "LED Support for DA9030/DA9034 PMIC"
-	depends on LEDS_CLASS && PMIC_DA903X
+	depends on PMIC_DA903X
 	help
 	  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
+	depends on 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
+	depends on HAVE_PWM
 	help
 	  This option enables support for pwm driven LEDs
 
 config LEDS_REGULATOR
 	tristate "REGULATOR driven LED support"
-	depends on LEDS_CLASS && REGULATOR
+	depends on REGULATOR
 	help
 	  This option enables support for regulator driven LEDs.
 
 config LEDS_BD2802
 	tristate "LED driver for BD2802 RGB LED"
-	depends on LEDS_CLASS && I2C
+	depends on I2C
 	help
 	  This option enables support for BD2802GU RGB LED driver chips
 	  accessed via the I2C bus.
 
 config LEDS_INTEL_SS4200
 	tristate "LED driver for Intel NAS SS4200 series"
-	depends on LEDS_CLASS && PCI && DMI
+	depends on PCI && DMI
 	help
 	  This option enables support for the Intel SS4200 series of
 	  Network Attached Storage servers.  You may control the hard
@@ -253,7 +262,7 @@ config LEDS_INTEL_SS4200
 
 config LEDS_LT3593
 	tristate "LED driver for LT3593 controllers"
-	depends on LEDS_CLASS && GENERIC_GPIO
+	depends on GENERIC_GPIO
 	help
 	  This option enables support for LEDs driven by a Linear Technology
 	  LT3593 controller. This controller uses a special one-wire pulse
@@ -261,7 +270,7 @@ config LEDS_LT3593
 
 config LEDS_ADP5520
 	tristate "LED Support for ADP5520/ADP5501 PMIC"
-	depends on LEDS_CLASS && PMIC_ADP5520
+	depends on PMIC_ADP5520
 	help
 	  This option enables support for on-chip LED drivers found
 	  on Analog Devices ADP5520/ADP5501 PMICs.
@@ -269,7 +278,12 @@ config LEDS_ADP5520
 	  To compile this driver as a module, choose M here: the module will
 	  be called leds-adp5520.
 
-comment "LED Triggers"
+config LEDS_DELL_NETBOOKS
+	tristate "External LED on Dell Business Netbooks"
+	depends on X86 && ACPI_WMI
+	help
+	  This adds support for the Latitude 2100 and similar
+	  notebooks that have an external LED.
 
 config LEDS_TRIGGERS
 	bool "LED Trigger support"
@@ -278,9 +292,12 @@ config LEDS_TRIGGERS
 	  These triggers allow kernel events to drive the LEDs and can
 	  be configured via sysfs. If unsure, say Y.
 
+if LEDS_TRIGGERS
+
+comment "LED Triggers"
+
 config LEDS_TRIGGER_TIMER
 	tristate "LED Timer Trigger"
-	depends on LEDS_TRIGGERS
 	help
 	  This allows LEDs to be controlled by a programmable timer
 	  via sysfs. Some LED hardware can be programmed to start
@@ -291,14 +308,13 @@ config LEDS_TRIGGER_TIMER
 
 config LEDS_TRIGGER_IDE_DISK
 	bool "LED IDE Disk Trigger"
-	depends on LEDS_TRIGGERS && IDE_GD_ATA
+	depends on IDE_GD_ATA
 	help
 	  This allows LEDs to be controlled by IDE disk activity.
 	  If unsure, say Y.
 
 config LEDS_TRIGGER_HEARTBEAT
 	tristate "LED Heartbeat Trigger"
-	depends on LEDS_TRIGGERS
 	help
 	  This allows LEDs to be controlled by a CPU load average.
 	  The flash frequency is a hyperbolic function of the 1-minute
@@ -307,7 +323,6 @@ config LEDS_TRIGGER_HEARTBEAT
 
 config LEDS_TRIGGER_BACKLIGHT
 	tristate "LED backlight Trigger"
-	depends on LEDS_TRIGGERS
 	help
 	  This allows LEDs to be controlled as a backlight device: they
 	  turn off and on when the display is blanked and unblanked.
@@ -316,7 +331,6 @@ config LEDS_TRIGGER_BACKLIGHT
 
 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
@@ -329,7 +343,6 @@ config LEDS_TRIGGER_GPIO
 
 config LEDS_TRIGGER_DEFAULT_ON
 	tristate "LED Default ON Trigger"
-	depends on LEDS_TRIGGERS
 	help
 	  This allows LEDs to be initialised in the ON state.
 	  If unsure, say Y.
@@ -337,4 +350,8 @@ config LEDS_TRIGGER_DEFAULT_ON
 comment "iptables trigger is under Netfilter config (LED target)"
 	depends on LEDS_TRIGGERS
 
+endif # LEDS_TRIGGERS
+
+endif # LEDS_CLASS
+
 endif # NEW_LEDS
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/led-class.c linux-libre-2.6.34-gnu1/drivers/leds/led-class.c
--- linux-libre-2.6.33-gnu1/drivers/leds/led-class.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/led-class.c	2010-05-16 17:17:36.000000000 -0400
@@ -72,11 +72,14 @@ static ssize_t led_max_brightness_show(s
 	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);
+static struct device_attribute led_class_attrs[] = {
+	__ATTR(brightness, 0644, led_brightness_show, led_brightness_store),
+	__ATTR(max_brightness, 0644, led_max_brightness_show, NULL),
 #ifdef CONFIG_LEDS_TRIGGERS
-static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
+	__ATTR(trigger, 0644, led_trigger_show, led_trigger_store),
 #endif
+	__ATTR_NULL,
+};
 
 /**
  * led_classdev_suspend - suspend an led_classdev.
@@ -127,18 +130,11 @@ static int led_resume(struct device *dev
  */
 int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
 {
-	int rc;
-
 	led_cdev->dev = device_create(leds_class, parent, 0, led_cdev,
 				      "%s", led_cdev->name);
 	if (IS_ERR(led_cdev->dev))
 		return PTR_ERR(led_cdev->dev);
 
-	/* register the attributes */
-	rc = device_create_file(led_cdev->dev, &dev_attr_brightness);
-	if (rc)
-		goto err_out;
-
 #ifdef CONFIG_LEDS_TRIGGERS
 	init_rwsem(&led_cdev->trigger_lock);
 #endif
@@ -150,36 +146,18 @@ int led_classdev_register(struct device
 	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
-	rc = device_create_file(led_cdev->dev, &dev_attr_trigger);
-	if (rc)
-		goto err_out_led_list;
-
 	led_trigger_set_default(led_cdev);
 #endif
 
-	printk(KERN_INFO "Registered led device: %s\n",
+	printk(KERN_DEBUG "Registered led device: %s\n",
 			led_cdev->name);
 
 	return 0;
-
-#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);
-err_out:
-	device_unregister(led_cdev->dev);
-	return rc;
 }
+
 EXPORT_SYMBOL_GPL(led_classdev_register);
 
 /**
@@ -190,10 +168,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);
 	down_write(&led_cdev->trigger_lock);
 	if (led_cdev->trigger)
 		led_trigger_set(led_cdev, NULL);
@@ -215,6 +190,7 @@ static int __init leds_init(void)
 		return PTR_ERR(leds_class);
 	leds_class->suspend = led_suspend;
 	leds_class->resume = led_resume;
+	leds_class->dev_attrs = led_class_attrs;
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-88pm860x.c linux-libre-2.6.34-gnu1/drivers/leds/leds-88pm860x.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-88pm860x.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-88pm860x.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,326 @@
+/*
+ * LED driver for Marvell 88PM860x
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ *	Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/mfd/88pm860x.h>
+
+#define LED_PWM_SHIFT		(3)
+#define LED_PWM_MASK		(0x1F)
+#define LED_CURRENT_MASK	(0x07 << 5)
+
+#define LED_BLINK_ON_MASK	(0x07)
+#define LED_BLINK_PERIOD_MASK	(0x0F << 3)
+#define LED_BLINK_MASK		(0x7F)
+
+#define LED_BLINK_ON(x)		((x & 0x7) * 66 + 66)
+#define LED_BLINK_PERIOD(x)	((x & 0xF) * 530 + 930)
+#define LED_BLINK_ON_MIN	LED_BLINK_ON(0)
+#define LED_BLINK_ON_MAX	LED_BLINK_ON(0x7)
+#define LED_BLINK_PERIOD_MIN	LED_BLINK_PERIOD(0)
+#define LED_BLINK_PERIOD_MAX	LED_BLINK_PERIOD(0xE)
+#define LED_TO_ON(x)		((x - 66) / 66)
+#define LED_TO_PERIOD(x)	((x - 930) / 530)
+
+#define LED1_BLINK_EN		(1 << 1)
+#define LED2_BLINK_EN		(1 << 2)
+
+enum {
+	SET_BRIGHTNESS,
+	SET_BLINK,
+};
+
+struct pm860x_led {
+	struct led_classdev cdev;
+	struct i2c_client *i2c;
+	struct work_struct work;
+	struct pm860x_chip *chip;
+	struct mutex lock;
+	char name[MFD_NAME_SIZE];
+
+	int port;
+	int iset;
+	int command;
+	int offset;
+	unsigned char brightness;
+	unsigned char current_brightness;
+
+	int blink_data;
+	int blink_time;
+	int blink_on;
+	int blink_off;
+};
+
+/* return offset of color register */
+static inline int __led_off(int port)
+{
+	int ret = -EINVAL;
+
+	switch (port) {
+	case PM8606_LED1_RED:
+	case PM8606_LED1_GREEN:
+	case PM8606_LED1_BLUE:
+		ret = port - PM8606_LED1_RED + PM8606_RGB1B;
+		break;
+	case PM8606_LED2_RED:
+	case PM8606_LED2_GREEN:
+	case PM8606_LED2_BLUE:
+		ret = port - PM8606_LED2_RED + PM8606_RGB2B;
+		break;
+	}
+	return ret;
+}
+
+/* return offset of blink register */
+static inline int __blink_off(int port)
+{
+	int ret = -EINVAL;
+
+	switch (port) {
+	case PM8606_LED1_RED:
+	case PM8606_LED1_GREEN:
+	case PM8606_LED1_BLUE:
+		ret = PM8606_RGB1A;
+	case PM8606_LED2_RED:
+	case PM8606_LED2_GREEN:
+	case PM8606_LED2_BLUE:
+		ret = PM8606_RGB2A;
+	}
+	return ret;
+}
+
+static inline int __blink_ctl_mask(int port)
+{
+	int ret = -EINVAL;
+
+	switch (port) {
+	case PM8606_LED1_RED:
+	case PM8606_LED1_GREEN:
+	case PM8606_LED1_BLUE:
+		ret = LED1_BLINK_EN;
+		break;
+	case PM8606_LED2_RED:
+	case PM8606_LED2_GREEN:
+	case PM8606_LED2_BLUE:
+		ret = LED2_BLINK_EN;
+		break;
+	}
+	return ret;
+}
+
+static int __led_set(struct pm860x_led *led, int command)
+{
+	struct pm860x_chip *chip = led->chip;
+	int mask, ret;
+
+	mutex_lock(&led->lock);
+	switch (command) {
+	case SET_BRIGHTNESS:
+		if ((led->current_brightness == 0) && led->brightness) {
+			if (led->iset) {
+				ret = pm860x_set_bits(led->i2c, led->offset,
+						LED_CURRENT_MASK, led->iset);
+				if (ret < 0)
+					goto out;
+			}
+		} else if (led->brightness == 0) {
+			ret = pm860x_set_bits(led->i2c, led->offset,
+						LED_CURRENT_MASK, 0);
+			if (ret < 0)
+				goto out;
+		}
+		ret = pm860x_set_bits(led->i2c, led->offset, LED_PWM_MASK,
+					led->brightness);
+		if (ret < 0)
+			goto out;
+		led->current_brightness = led->brightness;
+		dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n",
+			led->offset, led->brightness);
+		break;
+	case SET_BLINK:
+		ret = pm860x_set_bits(led->i2c, led->offset,
+				LED_BLINK_MASK, led->blink_data);
+		if (ret < 0)
+			goto out;
+
+		mask = __blink_ctl_mask(led->port);
+		ret = pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, mask);
+		if (ret < 0)
+			goto out;
+		dev_dbg(chip->dev, "LED blink delay on:%dms, delay off:%dms\n",
+			led->blink_on, led->blink_off);
+		break;
+	}
+out:
+	mutex_unlock(&led->lock);
+	return 0;
+}
+
+static void pm860x_led_work(struct work_struct *work)
+{
+	struct pm860x_led *led;
+
+	led = container_of(work, struct pm860x_led, work);
+	__led_set(led, led->command);
+}
+
+static void pm860x_led_set(struct led_classdev *cdev,
+			   enum led_brightness value)
+{
+	struct pm860x_led *data = container_of(cdev, struct pm860x_led, cdev);
+
+	data->offset = __led_off(data->port);
+	data->brightness = value >> 3;
+	data->command = SET_BRIGHTNESS;
+	schedule_work(&data->work);
+}
+
+static int pm860x_led_blink(struct led_classdev *cdev,
+			    unsigned long *delay_on,
+			    unsigned long *delay_off)
+{
+	struct pm860x_led *data = container_of(cdev, struct pm860x_led, cdev);
+	int period, on;
+
+	on = *delay_on;
+	if ((on < LED_BLINK_ON_MIN) || (on > LED_BLINK_ON_MAX))
+		return -EINVAL;
+
+	on = LED_TO_ON(on);
+	on = LED_BLINK_ON(on);
+
+	period = on + *delay_off;
+	if ((period < LED_BLINK_PERIOD_MIN) || (period > LED_BLINK_PERIOD_MAX))
+		return -EINVAL;
+	period = LED_TO_PERIOD(period);
+	period = LED_BLINK_PERIOD(period);
+
+	data->offset = __blink_off(data->port);
+	data->blink_on = on;
+	data->blink_off = period - data->blink_on;
+	data->blink_data = (period << 3) | data->blink_on;
+	data->command = SET_BLINK;
+	schedule_work(&data->work);
+
+	return 0;
+}
+
+static int __check_device(struct pm860x_led_pdata *pdata, char *name)
+{
+	struct pm860x_led_pdata *p = pdata;
+	int ret = -EINVAL;
+
+	while (p && p->id) {
+		if ((p->id != PM8606_ID_LED) || (p->flags < 0))
+			break;
+
+		if (!strncmp(name, pm860x_led_name[p->flags],
+			MFD_NAME_SIZE)) {
+			ret = (int)p->flags;
+			break;
+		}
+		p++;
+	}
+	return ret;
+}
+
+static int pm860x_led_probe(struct platform_device *pdev)
+{
+	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct pm860x_platform_data *pm860x_pdata;
+	struct pm860x_led_pdata *pdata;
+	struct pm860x_led *data;
+	struct resource *res;
+	int ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "No I/O resource!\n");
+		return -EINVAL;
+	}
+
+	if (pdev->dev.parent->platform_data) {
+		pm860x_pdata = pdev->dev.parent->platform_data;
+		pdata = pm860x_pdata->led;
+	} else
+		pdata = NULL;
+
+	data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+	strncpy(data->name, res->name, MFD_NAME_SIZE);
+	dev_set_drvdata(&pdev->dev, data);
+	data->chip = chip;
+	data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
+	data->iset = pdata->iset;
+	data->port = __check_device(pdata, data->name);
+	if (data->port < 0)
+		return -EINVAL;
+
+	data->current_brightness = 0;
+	data->cdev.name = data->name;
+	data->cdev.brightness_set = pm860x_led_set;
+	data->cdev.blink_set = pm860x_led_blink;
+	mutex_init(&data->lock);
+	INIT_WORK(&data->work, pm860x_led_work);
+
+	ret = led_classdev_register(chip->dev, &data->cdev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to register LED: %d\n", ret);
+		goto out;
+	}
+	return 0;
+out:
+	kfree(data);
+	return ret;
+}
+
+static int pm860x_led_remove(struct platform_device *pdev)
+{
+	struct pm860x_led *data = platform_get_drvdata(pdev);
+
+	led_classdev_unregister(&data->cdev);
+	kfree(data);
+
+	return 0;
+}
+
+static struct platform_driver pm860x_led_driver = {
+	.driver	= {
+		.name	= "88pm860x-led",
+		.owner	= THIS_MODULE,
+	},
+	.probe	= pm860x_led_probe,
+	.remove	= pm860x_led_remove,
+};
+
+static int __devinit pm860x_led_init(void)
+{
+	return platform_driver_register(&pm860x_led_driver);
+}
+module_init(pm860x_led_init);
+
+static void __devexit pm860x_led_exit(void)
+{
+	platform_driver_unregister(&pm860x_led_driver);
+}
+module_exit(pm860x_led_exit);
+
+MODULE_DESCRIPTION("LED driver for Marvell PM860x");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:88pm860x-led");
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-adp5520.c linux-libre-2.6.34-gnu1/drivers/leds/leds-adp5520.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-adp5520.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-adp5520.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/leds.h>
 #include <linux/workqueue.h>
 #include <linux/mfd/adp5520.h>
+#include <linux/slab.h>
 
 struct adp5520_led {
 	struct led_classdev	cdev;
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-atmel-pwm.c linux-libre-2.6.34-gnu1/drivers/leds/leds-atmel-pwm.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-atmel-pwm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-atmel-pwm.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
 #include <linux/leds.h>
 #include <linux/io.h>
 #include <linux/atmel_pwm.h>
+#include <linux/slab.h>
 
 
 struct pwmled {
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-bd2802.c linux-libre-2.6.34-gnu1/drivers/leds/leds-bd2802.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-bd2802.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-bd2802.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/leds.h>
 #include <linux/leds-bd2802.h>
+#include <linux/slab.h>
 
 
 #define LED_CTL(rgb2en, rgb1en) ((rgb2en) << 4 | ((rgb1en) << 0))
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-da903x.c linux-libre-2.6.34-gnu1/drivers/leds/leds-da903x.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-da903x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-da903x.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/leds.h>
 #include <linux/workqueue.h>
 #include <linux/mfd/da903x.h>
+#include <linux/slab.h>
 
 #define DA9030_LED1_CONTROL	0x20
 #define DA9030_LED2_CONTROL	0x21
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-dac124s085.c linux-libre-2.6.34-gnu1/drivers/leds/leds-dac124s085.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-dac124s085.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-dac124s085.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,6 @@
  * LED driver for the DAC124S085 SPI DAC
  */
 
-#include <linux/gfp.h>
 #include <linux/leds.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-gpio.c linux-libre-2.6.34-gnu1/drivers/leds/leds-gpio.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/leds.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 
 #include <asm/gpio.h>
@@ -211,7 +212,6 @@ static int __devinit of_gpio_leds_probe(
 					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;
 
@@ -226,8 +226,8 @@ static int __devinit of_gpio_leds_probe(
 	if (!pdata)
 		return -ENOMEM;
 
-	memset(&led, 0, sizeof(led));
 	for_each_child_of_node(np, child) {
+		struct gpio_led led = {};
 		enum of_gpio_flags flags;
 		const char *state;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-lp3944.c linux-libre-2.6.34-gnu1/drivers/leds/leds-lp3944.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-lp3944.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-lp3944.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 
 #include <linux/module.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/leds.h>
 #include <linux/mutex.h>
 #include <linux/workqueue.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-lt3593.c linux-libre-2.6.34-gnu1/drivers/leds/leds-lt3593.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-lt3593.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-lt3593.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/workqueue.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 struct lt3593_led_data {
 	struct led_classdev cdev;
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-pca9532.c linux-libre-2.6.34-gnu1/drivers/leds/leds-pca9532.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-pca9532.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-pca9532.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 
 #include <linux/module.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/leds.h>
 #include <linux/input.h>
 #include <linux/mutex.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-pca955x.c linux-libre-2.6.34-gnu1/drivers/leds/leds-pca955x.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-pca955x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-pca955x.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,6 +48,7 @@
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 /* LED select registers determine the source that drives LED outputs */
 #define PCA955X_LS_LED_ON	0x0	/* Output LOW */
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-pwm.c linux-libre-2.6.34-gnu1/drivers/leds/leds-pwm.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-pwm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-pwm.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/err.h>
 #include <linux/pwm.h>
 #include <linux/leds_pwm.h>
+#include <linux/slab.h>
 
 struct led_pwm_data {
 	struct led_classdev	cdev;
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-regulator.c linux-libre-2.6.34-gnu1/drivers/leds/leds-regulator.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-regulator.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-regulator.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/leds.h>
 #include <linux/leds-regulator.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-s3c24xx.c linux-libre-2.6.34-gnu1/drivers/leds/leds-s3c24xx.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-s3c24xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-s3c24xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/leds.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <mach/regs-gpio.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-ss4200.c linux-libre-2.6.34-gnu1/drivers/leds/leds-ss4200.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-ss4200.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-ss4200.c	2010-05-16 17:17:36.000000000 -0400
@@ -63,7 +63,7 @@ MODULE_LICENSE("GPL");
 /*
  * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives.
  */
-static struct pci_device_id ich7_lpc_pci_id[] =
+static const struct pci_device_id ich7_lpc_pci_id[] =
 {
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) },
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-sunfire.c linux-libre-2.6.34-gnu1/drivers/leds/leds-sunfire.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-sunfire.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-sunfire.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/leds.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/fhc.h>
 #include <asm/upa.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-wm831x-status.c linux-libre-2.6.34-gnu1/drivers/leds/leds-wm831x-status.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-wm831x-status.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-wm831x-status.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/leds.h>
 #include <linux/err.h>
 #include <linux/mfd/wm831x/core.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/leds-wm8350.c linux-libre-2.6.34-gnu1/drivers/leds/leds-wm8350.c
--- linux-libre-2.6.33-gnu1/drivers/leds/leds-wm8350.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/leds-wm8350.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/mfd/wm8350/pmic.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 
 /* Microamps */
 static const int isink_cur[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/ledtrig-backlight.c linux-libre-2.6.34-gnu1/drivers/leds/ledtrig-backlight.c
--- linux-libre-2.6.33-gnu1/drivers/leds/ledtrig-backlight.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/ledtrig-backlight.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/leds.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/led-triggers.c linux-libre-2.6.34-gnu1/drivers/leds/led-triggers.c
--- linux-libre-2.6.33-gnu1/drivers/leds/led-triggers.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/led-triggers.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/timer.h>
 #include <linux/rwsem.h>
 #include <linux/leds.h>
+#include <linux/slab.h>
 #include "leds.h"
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/ledtrig-gpio.c linux-libre-2.6.34-gnu1/drivers/leds/ledtrig-gpio.c
--- linux-libre-2.6.33-gnu1/drivers/leds/ledtrig-gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/ledtrig-gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
 #include <linux/leds.h>
+#include <linux/slab.h>
 #include "leds.h"
 
 struct gpio_trig_data {
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/ledtrig-heartbeat.c linux-libre-2.6.34-gnu1/drivers/leds/ledtrig-heartbeat.c
--- linux-libre-2.6.33-gnu1/drivers/leds/ledtrig-heartbeat.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/ledtrig-heartbeat.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/sched.h>
 #include <linux/leds.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/ledtrig-timer.c linux-libre-2.6.34-gnu1/drivers/leds/ledtrig-timer.c
--- linux-libre-2.6.33-gnu1/drivers/leds/ledtrig-timer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/ledtrig-timer.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/timer.h>
 #include <linux/ctype.h>
 #include <linux/leds.h>
+#include <linux/slab.h>
 #include "leds.h"
 
 struct timer_trig_data {
diff -druNp linux-libre-2.6.33-gnu1/drivers/leds/Makefile linux-libre-2.6.34-gnu1/drivers/leds/Makefile
--- linux-libre-2.6.33-gnu1/drivers/leds/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/leds/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@ obj-$(CONFIG_LEDS_CLASS)		+= led-class.o
 obj-$(CONFIG_LEDS_TRIGGERS)		+= led-triggers.o
 
 # LED Platform Drivers
+obj-$(CONFIG_LEDS_88PM860X)		+= leds-88pm860x.o
 obj-$(CONFIG_LEDS_ATMEL_PWM)		+= leds-atmel-pwm.o
 obj-$(CONFIG_LEDS_BD2802)		+= leds-bd2802.o
 obj-$(CONFIG_LEDS_LOCOMO)		+= leds-locomo.o
@@ -33,6 +34,7 @@ obj-$(CONFIG_LEDS_REGULATOR)		+= leds-re
 obj-$(CONFIG_LEDS_INTEL_SS4200)		+= leds-ss4200.o
 obj-$(CONFIG_LEDS_LT3593)		+= leds-lt3593.o
 obj-$(CONFIG_LEDS_ADP5520)		+= leds-adp5520.o
+obj-$(CONFIG_LEDS_DELL_NETBOOKS)	+= dell-led.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/lguest/core.c linux-libre-2.6.34-gnu1/drivers/lguest/core.c
--- linux-libre-2.6.33-gnu1/drivers/lguest/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/lguest/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/cpu.h>
 #include <linux/freezer.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 #include <asm/paravirt.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/lguest/lg.h linux-libre-2.6.34-gnu1/drivers/lguest/lg.h
--- linux-libre-2.6.33-gnu1/drivers/lguest/lg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/lguest/lg.h	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/wait.h>
 #include <linux/hrtimer.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <asm/lguest.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/lguest/lguest_device.c linux-libre-2.6.34-gnu1/drivers/lguest/lguest_device.c
--- linux-libre-2.6.33-gnu1/drivers/lguest/lguest_device.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/lguest/lguest_device.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/interrupt.h>
 #include <linux/virtio_ring.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/paravirt.h>
 #include <asm/lguest_hcall.h>
@@ -177,7 +178,7 @@ static void set_status(struct virtio_dev
 
 	/* We set the status. */
 	to_lgdev(vdev)->desc->status = status;
-	kvm_hypercall1(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset);
+	hcall(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset, 0, 0, 0);
 }
 
 static void lg_set_status(struct virtio_device *vdev, u8 status)
@@ -228,7 +229,7 @@ static void lg_notify(struct virtqueue *
 	 */
 	struct lguest_vq_info *lvq = vq->priv;
 
-	kvm_hypercall1(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT);
+	hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0, 0);
 }
 
 /* An extern declaration inside a C file is bad form.  Don't do it. */
diff -druNp linux-libre-2.6.33-gnu1/drivers/lguest/lguest_user.c linux-libre-2.6.34-gnu1/drivers/lguest/lguest_user.c
--- linux-libre-2.6.33-gnu1/drivers/lguest/lguest_user.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/lguest/lguest_user.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/sched.h>
 #include <linux/eventfd.h>
 #include <linux/file.h>
+#include <linux/slab.h>
 #include "lg.h"
 
 /*L:056
diff -druNp linux-libre-2.6.33-gnu1/drivers/lguest/page_tables.c linux-libre-2.6.34-gnu1/drivers/lguest/page_tables.c
--- linux-libre-2.6.33-gnu1/drivers/lguest/page_tables.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/lguest/page_tables.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 /* Copyright (C) Rusty Russell IBM Corporation 2006.
  * GPL v2 and any later version */
 #include <linux/mm.h>
+#include <linux/gfp.h>
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/random.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/lguest/x86/core.c linux-libre-2.6.34-gnu1/drivers/lguest/x86/core.c
--- linux-libre-2.6.33-gnu1/drivers/lguest/x86/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/lguest/x86/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -288,6 +288,18 @@ static int emulate_insn(struct lg_cpu *c
 	insn = lgread(cpu, physaddr, u8);
 
 	/*
+	 * Around 2.6.33, the kernel started using an emulation for the
+	 * cmpxchg8b instruction in early boot on many configurations.  This
+	 * code isn't paravirtualized, and it tries to disable interrupts.
+	 * Ignore it, which will Mostly Work.
+	 */
+	if (insn == 0xfa) {
+		/* "cli", or Clear Interrupt Enable instruction.  Skip it. */
+		cpu->regs->eip++;
+		return 1;
+	}
+
+	/*
 	 * 0x66 is an "operand prefix".  It means it's using the upper 16 bits
 	 * of the eax register.
 	 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/adb.c linux-libre-2.6.34-gnu1/drivers/macintosh/adb.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/adb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/adb.c	2010-05-16 17:17:36.000000000 -0400
@@ -317,13 +317,15 @@ static int __init adb_init(void)
 			break;
 		}
 	}
-	if ((adb_controller == NULL) || adb_controller->init()) {
-		printk(KERN_WARNING "Warning: no ADB interface detected\n");
+	if (adb_controller != NULL && adb_controller->init &&
+	    adb_controller->init())
 		adb_controller = NULL;
+	if (adb_controller == NULL) {
+		printk(KERN_WARNING "Warning: no ADB interface detected\n");
 	} else {
 #ifdef CONFIG_PPC
-		if (machine_is_compatible("AAPL,PowerBook1998") ||
-			machine_is_compatible("PowerBook1,1"))
+		if (of_machine_is_compatible("AAPL,PowerBook1998") ||
+			of_machine_is_compatible("PowerBook1,1"))
 			sleepy_trackpad = 1;
 #endif /* CONFIG_PPC */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/Kconfig linux-libre-2.6.34-gnu1/drivers/macintosh/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/macintosh/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -171,8 +171,8 @@ config INPUT_ADBHID
 	  If unsure, say Y.
 
 config MAC_EMUMOUSEBTN
-	bool "Support for mouse button 2+3 emulation"
-	select INPUT
+	tristate "Support for mouse button 2+3 emulation"
+	depends on SYSCTL && INPUT
 	help
 	  This provides generic support for emulating the 2nd and 3rd mouse
 	  button with keypresses.  If you say Y here, the emulation is still
@@ -184,6 +184,9 @@ config MAC_EMUMOUSEBTN
 
 	  If you have an Apple machine with a 1-button mouse, say Y here.
 
+	  To compile this driver as a module, choose M here: the
+	  module will be called mac_hid.
+
 config THERM_WINDTUNNEL
 	tristate "Support for thermal management on Windtunnel G4s"
 	depends on I2C && I2C_POWERMAC && PPC_PMAC && !PPC_PMAC64
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/mac_hid.c linux-libre-2.6.34-gnu1/drivers/macintosh/mac_hid.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/mac_hid.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/mac_hid.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,17 +13,198 @@
 #include <linux/sysctl.h>
 #include <linux/input.h>
 #include <linux/module.h>
-#include <linux/kbd_kern.h>
+#include <linux/slab.h>
 
+MODULE_LICENSE("GPL");
 
-static struct input_dev *emumousebtn;
-static int emumousebtn_input_register(void);
 static int mouse_emulate_buttons;
 static int mouse_button2_keycode = KEY_RIGHTCTRL;	/* right control key */
 static int mouse_button3_keycode = KEY_RIGHTALT;	/* right option key */
-static int mouse_last_keycode;
 
-#if defined(CONFIG_SYSCTL)
+static struct input_dev *mac_hid_emumouse_dev;
+
+static int mac_hid_create_emumouse(void)
+{
+	static struct lock_class_key mac_hid_emumouse_dev_event_class;
+	static struct lock_class_key mac_hid_emumouse_dev_mutex_class;
+	int err;
+
+	mac_hid_emumouse_dev = input_allocate_device();
+	if (!mac_hid_emumouse_dev)
+		return -ENOMEM;
+
+	lockdep_set_class(&mac_hid_emumouse_dev->event_lock,
+			  &mac_hid_emumouse_dev_event_class);
+	lockdep_set_class(&mac_hid_emumouse_dev->mutex,
+			  &mac_hid_emumouse_dev_mutex_class);
+
+	mac_hid_emumouse_dev->name = "Macintosh mouse button emulation";
+	mac_hid_emumouse_dev->id.bustype = BUS_ADB;
+	mac_hid_emumouse_dev->id.vendor = 0x0001;
+	mac_hid_emumouse_dev->id.product = 0x0001;
+	mac_hid_emumouse_dev->id.version = 0x0100;
+
+	mac_hid_emumouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	mac_hid_emumouse_dev->keybit[BIT_WORD(BTN_MOUSE)] =
+		BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+	mac_hid_emumouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+
+	err = input_register_device(mac_hid_emumouse_dev);
+	if (err) {
+		input_free_device(mac_hid_emumouse_dev);
+		mac_hid_emumouse_dev = NULL;
+		return err;
+	}
+
+	return 0;
+}
+
+static void mac_hid_destroy_emumouse(void)
+{
+	input_unregister_device(mac_hid_emumouse_dev);
+	mac_hid_emumouse_dev = NULL;
+}
+
+static bool mac_hid_emumouse_filter(struct input_handle *handle,
+				    unsigned int type, unsigned int code,
+				    int value)
+{
+	unsigned int btn;
+
+	if (type != EV_KEY)
+		return false;
+
+	if (code == mouse_button2_keycode)
+		btn = BTN_MIDDLE;
+	else if (code == mouse_button3_keycode)
+		btn = BTN_RIGHT;
+	else
+		return false;
+
+	input_report_key(mac_hid_emumouse_dev, btn, value);
+	input_sync(mac_hid_emumouse_dev);
+
+	return true;
+}
+
+static int mac_hid_emumouse_connect(struct input_handler *handler,
+				    struct input_dev *dev,
+				    const struct input_device_id *id)
+{
+	struct input_handle *handle;
+	int error;
+
+	/* Don't bind to ourselves */
+	if (dev == mac_hid_emumouse_dev)
+		return -ENODEV;
+
+	handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
+	if (!handle)
+		return -ENOMEM;
+
+	handle->dev = dev;
+	handle->handler = handler;
+	handle->name = "mac-button-emul";
+
+	error = input_register_handle(handle);
+	if (error) {
+		printk(KERN_ERR
+			"mac_hid: Failed to register button emulation handle, "
+			"error %d\n", error);
+		goto err_free;
+	}
+
+	error = input_open_device(handle);
+	if (error) {
+		printk(KERN_ERR
+			"mac_hid: Failed to open input device, error %d\n",
+			error);
+		goto err_unregister;
+	}
+
+	return 0;
+
+ err_unregister:
+	input_unregister_handle(handle);
+ err_free:
+	kfree(handle);
+	return error;
+}
+
+static void mac_hid_emumouse_disconnect(struct input_handle *handle)
+{
+	input_close_device(handle);
+	input_unregister_handle(handle);
+	kfree(handle);
+}
+
+static const struct input_device_id mac_hid_emumouse_ids[] = {
+	{
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
+		.evbit = { BIT_MASK(EV_KEY) },
+	},
+	{ },
+};
+
+MODULE_DEVICE_TABLE(input, mac_hid_emumouse_ids);
+
+static struct input_handler mac_hid_emumouse_handler = {
+	.filter		= mac_hid_emumouse_filter,
+	.connect	= mac_hid_emumouse_connect,
+	.disconnect	= mac_hid_emumouse_disconnect,
+	.name		= "mac-button-emul",
+	.id_table	= mac_hid_emumouse_ids,
+};
+
+static int mac_hid_start_emulation(void)
+{
+	int err;
+
+	err = mac_hid_create_emumouse();
+	if (err)
+		return err;
+
+	err = input_register_handler(&mac_hid_emumouse_handler);
+	if (err) {
+		mac_hid_destroy_emumouse();
+		return err;
+	}
+
+	return 0;
+}
+
+static void mac_hid_stop_emulation(void)
+{
+	input_unregister_handler(&mac_hid_emumouse_handler);
+	mac_hid_destroy_emumouse();
+}
+
+static int mac_hid_toggle_emumouse(ctl_table *table, int write,
+				   void __user *buffer, size_t *lenp,
+				   loff_t *ppos)
+{
+	int *valp = table->data;
+	int old_val = *valp;
+	int rc;
+
+	rc = proc_dointvec(table, write, buffer, lenp, ppos);
+
+	if (rc == 0 && write && *valp != old_val) {
+		if (*valp == 1)
+			rc = mac_hid_start_emulation();
+		else if (*valp == 0)
+			mac_hid_stop_emulation();
+		else
+			rc = -EINVAL;
+	}
+
+	/* Restore the old value in case of error */
+	if (rc)
+		*valp = old_val;
+
+	return rc;
+}
+
 /* file(s) in /proc/sys/dev/mac_hid */
 static ctl_table mac_hid_files[] = {
 	{
@@ -31,7 +212,7 @@ static ctl_table mac_hid_files[] = {
 		.data		= &mouse_emulate_buttons,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= mac_hid_toggle_emumouse,
 	},
 	{
 		.procname	= "mouse_button2_keycode",
@@ -74,75 +255,21 @@ static ctl_table mac_hid_root_dir[] = {
 
 static struct ctl_table_header *mac_hid_sysctl_header;
 
-#endif /* endif CONFIG_SYSCTL */
-
-int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down)
-{
-	switch (caller) {
-	case 1:
-		/* Called from keyboard.c */
-		if (mouse_emulate_buttons
-		    && (keycode == mouse_button2_keycode
-			|| keycode == mouse_button3_keycode)) {
-			if (mouse_emulate_buttons == 1) {
-				input_report_key(emumousebtn,
-						 keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT,
-						 down);
-				input_sync(emumousebtn);
-				return 1;
-			}
-			mouse_last_keycode = down ? keycode : 0;
-		}
-		break;
-	}
-	return 0;
-}
-
-static struct lock_class_key emumousebtn_event_class;
-static struct lock_class_key emumousebtn_mutex_class;
-
-static int emumousebtn_input_register(void)
+static int __init mac_hid_init(void)
 {
-	int ret;
-
-	emumousebtn = input_allocate_device();
-	if (!emumousebtn)
+	mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir);
+	if (!mac_hid_sysctl_header)
 		return -ENOMEM;
 
-	lockdep_set_class(&emumousebtn->event_lock, &emumousebtn_event_class);
-	lockdep_set_class(&emumousebtn->mutex, &emumousebtn_mutex_class);
-
-	emumousebtn->name = "Macintosh mouse button emulation";
-	emumousebtn->id.bustype = BUS_ADB;
-	emumousebtn->id.vendor = 0x0001;
-	emumousebtn->id.product = 0x0001;
-	emumousebtn->id.version = 0x0100;
-
-	emumousebtn->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
-	emumousebtn->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
-		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
-	emumousebtn->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
-
-	ret = input_register_device(emumousebtn);
-	if (ret)
-		input_free_device(emumousebtn);
-
-	return ret;
+	return 0;
 }
+module_init(mac_hid_init);
 
-static int __init mac_hid_init(void)
+static void __exit mac_hid_exit(void)
 {
-	int err;
-
-	err = emumousebtn_input_register();
-	if (err)
-		return err;
-
-#if defined(CONFIG_SYSCTL)
-	mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir);
-#endif /* CONFIG_SYSCTL */
+	unregister_sysctl_table(mac_hid_sysctl_header);
 
-	return 0;
+	if (mouse_emulate_buttons)
+		mac_hid_stop_emulation();
 }
-
-device_initcall(mac_hid_init);
+module_exit(mac_hid_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/rack-meter.c linux-libre-2.6.34-gnu1/drivers/macintosh/rack-meter.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/rack-meter.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/rack-meter.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/smu.c linux-libre-2.6.34-gnu1/drivers/macintosh/smu.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/smu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/smu.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/mutex.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 
 #include <asm/byteorder.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/therm_adt746x.c linux-libre-2.6.34-gnu1/drivers/macintosh/therm_adt746x.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/therm_adt746x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/therm_adt746x.c	2010-05-16 17:17:36.000000000 -0400
@@ -90,6 +90,8 @@ static struct task_struct *thread_therm
 
 static void write_both_fan_speed(struct thermostat *th, int speed);
 static void write_fan_speed(struct thermostat *th, int speed, int fan);
+static void thermostat_create_files(void);
+static void thermostat_remove_files(void);
 
 static int
 write_reg(struct thermostat* th, int reg, u8 data)
@@ -161,6 +163,8 @@ remove_thermostat(struct i2c_client *cli
 	struct thermostat *th = i2c_get_clientdata(client);
 	int i;
 	
+	thermostat_remove_files();
+
 	if (thread_therm != NULL) {
 		kthread_stop(thread_therm);
 	}
@@ -312,7 +316,7 @@ static void update_fans_speed (struct th
 
 			if (verbose)
 				printk(KERN_DEBUG "adt746x: Setting fans speed to %d "
-						 "(limit exceeded by %d on %s) \n",
+						 "(limit exceeded by %d on %s)\n",
 						new_speed, var,
 						sensor_location[fan_number+1]);
 			write_both_fan_speed(th, new_speed);
@@ -449,6 +453,8 @@ static int probe_thermostat(struct i2c_c
 		return -ENOMEM;
 	}
 
+	thermostat_create_files();
+
 	return 0;
 }
 
@@ -566,7 +572,6 @@ thermostat_init(void)
 	struct device_node* np;
 	const u32 *prop;
 	int i = 0, offset = 0;
-	int err;
 
 	np = of_find_node_by_name(NULL, "fan");
 	if (!np)
@@ -633,6 +638,17 @@ thermostat_init(void)
 		return -ENODEV;
 	}
 
+#ifndef CONFIG_I2C_POWERMAC
+	request_module("i2c-powermac");
+#endif
+
+	return i2c_add_driver(&thermostat_driver);
+}
+
+static void thermostat_create_files(void)
+{
+	int err;
+
 	err = device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature);
 	err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature);
 	err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_limit);
@@ -647,16 +663,9 @@ thermostat_init(void)
 	if (err)
 		printk(KERN_WARNING
 			"Failed to create tempertaure attribute file(s).\n");
-
-#ifndef CONFIG_I2C_POWERMAC
-	request_module("i2c-powermac");
-#endif
-
-	return i2c_add_driver(&thermostat_driver);
 }
 
-static void __exit
-thermostat_exit(void)
+static void thermostat_remove_files(void)
 {
 	if (of_dev) {
 		device_remove_file(&of_dev->dev, &dev_attr_sensor1_temperature);
@@ -673,9 +682,14 @@ thermostat_exit(void)
 			device_remove_file(&of_dev->dev,
 					   &dev_attr_sensor2_fan_speed);
 
-		of_device_unregister(of_dev);
 	}
+}
+
+static void __exit
+thermostat_exit(void)
+{
 	i2c_del_driver(&thermostat_driver);
+	of_device_unregister(of_dev);
 }
 
 module_init(thermostat_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/therm_pm72.c linux-libre-2.6.34-gnu1/drivers/macintosh/therm_pm72.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/therm_pm72.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/therm_pm72.c	2010-05-16 17:17:36.000000000 -0400
@@ -114,7 +114,6 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/wait.h>
@@ -948,10 +947,16 @@ static void do_monitor_cpu_combined(void
 		printk(KERN_WARNING "Warning ! Temperature way above maximum (%d) !\n",
 		       temp_combi >> 16);
 		state0->overtemp += CPU_MAX_OVERTEMP / 4;
-	} else if (temp_combi > (state0->mpu.tmax << 16))
+	} else if (temp_combi > (state0->mpu.tmax << 16)) {
 		state0->overtemp++;
-	else
+		printk(KERN_WARNING "Temperature %d above max %d. overtemp %d\n",
+		       temp_combi >> 16, state0->mpu.tmax, state0->overtemp);
+	} else {
+		if (state0->overtemp)
+			printk(KERN_WARNING "Temperature back down to %d\n",
+			       temp_combi >> 16);
 		state0->overtemp = 0;
+	}
 	if (state0->overtemp >= CPU_MAX_OVERTEMP)
 		critical_state = 1;
 	if (state0->overtemp > 0) {
@@ -1023,10 +1028,16 @@ static void do_monitor_cpu_split(struct
 		       " (%d) !\n",
 		       state->index, temp >> 16);
 		state->overtemp += CPU_MAX_OVERTEMP / 4;
-	} else if (temp > (state->mpu.tmax << 16))
+	} else if (temp > (state->mpu.tmax << 16)) {
 		state->overtemp++;
-	else
+		printk(KERN_WARNING "CPU %d temperature %d above max %d. overtemp %d\n",
+		       state->index, temp >> 16, state->mpu.tmax, state->overtemp);
+	} else {
+		if (state->overtemp)
+			printk(KERN_WARNING "CPU %d temperature back down to %d\n",
+			       state->index, temp >> 16);
 		state->overtemp = 0;
+	}
 	if (state->overtemp >= CPU_MAX_OVERTEMP)
 		critical_state = 1;
 	if (state->overtemp > 0) {
@@ -1085,10 +1096,16 @@ static void do_monitor_cpu_rack(struct c
 		       " (%d) !\n",
 		       state->index, temp >> 16);
 		state->overtemp = CPU_MAX_OVERTEMP / 4;
-	} else if (temp > (state->mpu.tmax << 16))
+	} else if (temp > (state->mpu.tmax << 16)) {
 		state->overtemp++;
-	else
+		printk(KERN_WARNING "CPU %d temperature %d above max %d. overtemp %d\n",
+		       state->index, temp >> 16, state->mpu.tmax, state->overtemp);
+	} else {
+		if (state->overtemp)
+			printk(KERN_WARNING "CPU %d temperature back down to %d\n",
+			       state->index, temp >> 16);
 		state->overtemp = 0;
+	}
 	if (state->overtemp >= CPU_MAX_OVERTEMP)
 		critical_state = 1;
 	if (state->overtemp > 0) {
@@ -1899,7 +1916,7 @@ static int create_control_loops(void)
 	 */
 	if (rackmac)
 		cpu_pid_type = CPU_PID_TYPE_RACKMAC;
-	else if (machine_is_compatible("PowerMac7,3")
+	else if (of_machine_is_compatible("PowerMac7,3")
 	    && (cpu_count > 1)
 	    && fcu_fans[CPUA_PUMP_RPM_INDEX].id != FCU_FAN_ABSENT_ID
 	    && fcu_fans[CPUB_PUMP_RPM_INDEX].id != FCU_FAN_ABSENT_ID) {
@@ -2234,10 +2251,10 @@ static int __init therm_pm72_init(void)
 {
 	struct device_node *np;
 
-	rackmac = machine_is_compatible("RackMac3,1");
+	rackmac = of_machine_is_compatible("RackMac3,1");
 
-	if (!machine_is_compatible("PowerMac7,2") &&
-	    !machine_is_compatible("PowerMac7,3") &&
+	if (!of_machine_is_compatible("PowerMac7,2") &&
+	    !of_machine_is_compatible("PowerMac7,3") &&
 	    !rackmac)
 	    	return -ENODEV;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/therm_pm72.h linux-libre-2.6.34-gnu1/drivers/macintosh/therm_pm72.h
--- linux-libre-2.6.33-gnu1/drivers/macintosh/therm_pm72.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/therm_pm72.h	2010-05-16 17:17:36.000000000 -0400
@@ -269,7 +269,7 @@ struct slots_pid_state
 #define CPU_TEMP_HISTORY_SIZE		2
 #define CPU_POWER_HISTORY_SIZE		10
 #define CPU_PID_INTERVAL		1
-#define CPU_MAX_OVERTEMP		30
+#define CPU_MAX_OVERTEMP		90
 
 #define CPUA_PUMP_RPM_INDEX		7
 #define CPUB_PUMP_RPM_INDEX		8
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/therm_windtunnel.c linux-libre-2.6.34-gnu1/drivers/macintosh/therm_windtunnel.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/therm_windtunnel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/therm_windtunnel.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,6 @@
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/i2c.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/kthread.h>
 #include <linux/of_platform.h>
@@ -490,7 +489,7 @@ g4fan_init( void )
 	info = of_get_property(np, "thermal-info", NULL);
 	of_node_put(np);
 
-	if( !info || !machine_is_compatible("PowerMac3,6") )
+	if( !info || !of_machine_is_compatible("PowerMac3,6") )
 		return -ENODEV;
 
 	if( info->id != 3 ) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/via-cuda.c linux-libre-2.6.34-gnu1/drivers/macintosh/via-cuda.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/via-cuda.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/via-cuda.c	2010-05-16 17:17:36.000000000 -0400
@@ -89,7 +89,6 @@ static int cuda_fully_inited;
 
 #ifdef CONFIG_ADB
 static int cuda_probe(void);
-static int cuda_init(void);
 static int cuda_send_request(struct adb_request *req, int sync);
 static int cuda_adb_autopoll(int devs);
 static int cuda_reset_adb_bus(void);
@@ -107,17 +106,42 @@ int cuda_request(struct adb_request *req
 
 #ifdef CONFIG_ADB
 struct adb_driver via_cuda_driver = {
-	"CUDA",
-	cuda_probe,
-	cuda_init,
-	cuda_send_request,
-	cuda_adb_autopoll,
-	cuda_poll,
-	cuda_reset_adb_bus
+	.name         = "CUDA",
+	.probe        = cuda_probe,
+	.send_request = cuda_send_request,
+	.autopoll     = cuda_adb_autopoll,
+	.poll         = cuda_poll,
+	.reset_bus    = cuda_reset_adb_bus,
 };
 #endif /* CONFIG_ADB */
 
-#ifdef CONFIG_PPC
+#ifdef CONFIG_MAC
+int __init find_via_cuda(void)
+{
+    struct adb_request req;
+    int err;
+
+    if (macintosh_config->adb_type != MAC_ADB_CUDA)
+	return 0;
+
+    via = via1;
+    cuda_state = idle;
+
+    err = cuda_init_via();
+    if (err) {
+	printk(KERN_ERR "cuda_init_via() failed\n");
+	via = NULL;
+	return 0;
+    }
+
+    /* enable autopoll */
+    cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, 1);
+    while (!req.complete)
+	cuda_poll();
+
+    return 1;
+}
+#else
 int __init find_via_cuda(void)
 {
     struct adb_request req;
@@ -175,7 +199,7 @@ int __init find_via_cuda(void)
     vias = NULL;
     return 0;
 }
-#endif /* CONFIG_PPC */
+#endif /* !defined CONFIG_MAC */
 
 static int __init via_cuda_start(void)
 {
@@ -184,14 +208,14 @@ static int __init via_cuda_start(void)
 
 #ifdef CONFIG_MAC
     cuda_irq = IRQ_MAC_ADB;
-#else /* CONFIG_MAC */
+#else
     cuda_irq = irq_of_parse_and_map(vias, 0);
     if (cuda_irq == NO_IRQ) {
 	printk(KERN_ERR "via-cuda: can't map interrupts for %s\n",
 	       vias->full_name);
 	return -ENODEV;
     }
-#endif /* CONFIG_MAC */
+#endif
 
     if (request_irq(cuda_irq, cuda_interrupt, 0, "ADB", cuda_interrupt)) {
 	printk(KERN_ERR "via-cuda: can't request irq %d\n", cuda_irq);
@@ -216,28 +240,10 @@ cuda_probe(void)
 #else
     if (macintosh_config->adb_type != MAC_ADB_CUDA)
 	return -ENODEV;
-    via = via1;
 #endif
-    return 0;
-}
-
-static int __init
-cuda_init(void)
-{
-#ifdef CONFIG_PPC
     if (via == NULL)
 	return -ENODEV;
     return 0;
-#else 
-    int err = cuda_init_via();
-    if (err) {
-	printk(KERN_ERR "cuda_init_via() failed\n");
-	return -ENODEV;
-    }
-    out_8(&via[IER], IER_SET|SR_INT); /* enable interrupt from SR */
-
-    return via_cuda_start();
-#endif
 }
 #endif /* CONFIG_ADB */
 
@@ -430,9 +436,11 @@ cuda_poll(void)
     /* cuda_interrupt only takes a normal lock, we disable
      * interrupts here to avoid re-entering and thus deadlocking.
      */
-    disable_irq(cuda_irq);
+    if (cuda_irq)
+	disable_irq(cuda_irq);
     cuda_interrupt(0, NULL);
-    enable_irq(cuda_irq);
+    if (cuda_irq)
+	enable_irq(cuda_irq);
 }
 
 static irqreturn_t
@@ -446,7 +454,7 @@ cuda_interrupt(int irq, void *arg)
     
     spin_lock(&cuda_lock);
 
-    /* On powermacs, this handler is registered for the VIA IRQ. But it uses
+    /* On powermacs, this handler is registered for the VIA IRQ. But they use
      * just the shift register IRQ -- other VIA interrupt sources are disabled.
      * On m68k macs, the VIA IRQ sources are dispatched individually. Unless
      * we are polling, the shift register IRQ flag has already been cleared.
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/via-pmu68k.c linux-libre-2.6.34-gnu1/drivers/macintosh/via-pmu68k.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/via-pmu68k.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/via-pmu68k.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,6 @@
 #include <linux/miscdevice.h>
 #include <linux/blkdev.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/via-pmu-backlight.c linux-libre-2.6.34-gnu1/drivers/macintosh/via-pmu-backlight.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/via-pmu-backlight.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/via-pmu-backlight.c	2010-05-16 17:17:36.000000000 -0400
@@ -144,30 +144,33 @@ void pmu_backlight_set_sleep(int sleep)
 
 void __init pmu_backlight_init()
 {
+	struct backlight_properties props;
 	struct backlight_device *bd;
 	char name[10];
 	int level, autosave;
 
 	/* Special case for the old PowerBook since I can't test on it */
 	autosave =
-		machine_is_compatible("AAPL,3400/2400") ||
-		machine_is_compatible("AAPL,3500");
+		of_machine_is_compatible("AAPL,3400/2400") ||
+		of_machine_is_compatible("AAPL,3500");
 
 	if (!autosave &&
 	    !pmac_has_backlight_type("pmu") &&
-	    !machine_is_compatible("AAPL,PowerBook1998") &&
-	    !machine_is_compatible("PowerBook1,1"))
+	    !of_machine_is_compatible("AAPL,PowerBook1998") &&
+	    !of_machine_is_compatible("PowerBook1,1"))
 		return;
 
 	snprintf(name, sizeof(name), "pmubl");
 
-	bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+	bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data,
+				       &props);
 	if (IS_ERR(bd)) {
 		printk(KERN_ERR "PMU Backlight registration failed\n");
 		return;
 	}
 	uses_pmu_bl = 1;
-	bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
 	pmu_backlight_init_curve(0x7F, 0x46, 0x0E);
 
 	level = bd->props.max_brightness;
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/via-pmu.c linux-libre-2.6.34-gnu1/drivers/macintosh/via-pmu.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/via-pmu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/via-pmu.c	2010-05-16 17:17:36.000000000 -0400
@@ -463,8 +463,8 @@ static int __init via_pmu_dev_init(void)
 #endif
 
 #ifdef CONFIG_PPC32
-  	if (machine_is_compatible("AAPL,3400/2400") ||
-  		machine_is_compatible("AAPL,3500")) {
+  	if (of_machine_is_compatible("AAPL,3400/2400") ||
+  		of_machine_is_compatible("AAPL,3500")) {
 		int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
 			NULL, PMAC_MB_INFO_MODEL, 0);
 		pmu_battery_count = 1;
@@ -472,8 +472,8 @@ static int __init via_pmu_dev_init(void)
 			pmu_batteries[0].flags |= PMU_BATT_TYPE_COMET;
 		else
 			pmu_batteries[0].flags |= PMU_BATT_TYPE_HOOPER;
-	} else if (machine_is_compatible("AAPL,PowerBook1998") ||
-		machine_is_compatible("PowerBook1,1")) {
+	} else if (of_machine_is_compatible("AAPL,PowerBook1998") ||
+		of_machine_is_compatible("PowerBook1,1")) {
 		pmu_battery_count = 2;
 		pmu_batteries[0].flags |= PMU_BATT_TYPE_SMART;
 		pmu_batteries[1].flags |= PMU_BATT_TYPE_SMART;
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_core.c linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_core.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/kthread.h>
@@ -209,6 +210,7 @@ int wf_register_control(struct wf_contro
 	kref_init(&new_ct->ref);
 	list_add(&new_ct->link, &wf_controls);
 
+	sysfs_attr_init(&new_ct->attr.attr);
 	new_ct->attr.attr.name = new_ct->name;
 	new_ct->attr.attr.mode = 0644;
 	new_ct->attr.show = wf_show_control;
@@ -321,6 +323,7 @@ int wf_register_sensor(struct wf_sensor
 	kref_init(&new_sr->ref);
 	list_add(&new_sr->link, &wf_sensors);
 
+	sysfs_attr_init(&new_sr->attr.attr);
 	new_sr->attr.attr.name = new_sr->name;
 	new_sr->attr.attr.mode = 0444;
 	new_sr->attr.show = wf_show_sensor;
@@ -468,9 +471,9 @@ static int __init windfarm_core_init(voi
 	DBG("wf: core loaded\n");
 
 	/* Don't register on old machines that use therm_pm72 for now */
-	if (machine_is_compatible("PowerMac7,2") ||
-	    machine_is_compatible("PowerMac7,3") ||
-	    machine_is_compatible("RackMac3,1"))
+	if (of_machine_is_compatible("PowerMac7,2") ||
+	    of_machine_is_compatible("PowerMac7,3") ||
+	    of_machine_is_compatible("RackMac3,1"))
 		return -ENODEV;
 	platform_device_register(&wf_platform_device);
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_cpufreq_clamp.c linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_cpufreq_clamp.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_cpufreq_clamp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_cpufreq_clamp.c	2010-05-16 17:17:36.000000000 -0400
@@ -76,9 +76,9 @@ static int __init wf_cpufreq_clamp_init(
 	struct wf_control *clamp;
 
 	/* Don't register on old machines that use therm_pm72 for now */
-	if (machine_is_compatible("PowerMac7,2") ||
-	    machine_is_compatible("PowerMac7,3") ||
-	    machine_is_compatible("RackMac3,1"))
+	if (of_machine_is_compatible("PowerMac7,2") ||
+	    of_machine_is_compatible("PowerMac7,3") ||
+	    of_machine_is_compatible("RackMac3,1"))
 		return -ENODEV;
 
 	clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL);
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_lm75_sensor.c linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_lm75_sensor.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_lm75_sensor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_lm75_sensor.c	2010-05-16 17:17:36.000000000 -0400
@@ -239,9 +239,9 @@ static struct i2c_driver wf_lm75_driver
 static int __init wf_lm75_sensor_init(void)
 {
 	/* Don't register on old machines that use therm_pm72 for now */
-	if (machine_is_compatible("PowerMac7,2") ||
-	    machine_is_compatible("PowerMac7,3") ||
-	    machine_is_compatible("RackMac3,1"))
+	if (of_machine_is_compatible("PowerMac7,2") ||
+	    of_machine_is_compatible("PowerMac7,3") ||
+	    of_machine_is_compatible("RackMac3,1"))
 		return -ENODEV;
 	return i2c_add_driver(&wf_lm75_driver);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_max6690_sensor.c linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_max6690_sensor.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_max6690_sensor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_max6690_sensor.c	2010-05-16 17:17:36.000000000 -0400
@@ -188,9 +188,9 @@ static struct i2c_driver wf_max6690_driv
 static int __init wf_max6690_sensor_init(void)
 {
 	/* Don't register on old machines that use therm_pm72 for now */
-	if (machine_is_compatible("PowerMac7,2") ||
-	    machine_is_compatible("PowerMac7,3") ||
-	    machine_is_compatible("RackMac3,1"))
+	if (of_machine_is_compatible("PowerMac7,2") ||
+	    of_machine_is_compatible("PowerMac7,3") ||
+	    of_machine_is_compatible("RackMac3,1"))
 		return -ENODEV;
 	return i2c_add_driver(&wf_max6690_driver);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_pm112.c linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_pm112.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_pm112.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_pm112.c	2010-05-16 17:17:36.000000000 -0400
@@ -676,7 +676,7 @@ static int __init wf_pm112_init(void)
 {
 	struct device_node *cpu;
 
-	if (!machine_is_compatible("PowerMac11,2"))
+	if (!of_machine_is_compatible("PowerMac11,2"))
 		return -ENODEV;
 
 	/* Count the number of CPU cores */
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_pm121.c linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_pm121.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_pm121.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_pm121.c	2010-05-16 17:17:36.000000000 -0400
@@ -1008,7 +1008,7 @@ static int __init pm121_init(void)
 {
 	int rc = -ENODEV;
 
-	if (machine_is_compatible("PowerMac12,1"))
+	if (of_machine_is_compatible("PowerMac12,1"))
 		rc = pm121_init_pm();
 
 	if (rc == 0) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_pm81.c linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_pm81.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_pm81.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_pm81.c	2010-05-16 17:17:36.000000000 -0400
@@ -779,8 +779,8 @@ static int __init wf_smu_init(void)
 {
 	int rc = -ENODEV;
 
-	if (machine_is_compatible("PowerMac8,1") ||
-	    machine_is_compatible("PowerMac8,2"))
+	if (of_machine_is_compatible("PowerMac8,1") ||
+	    of_machine_is_compatible("PowerMac8,2"))
 		rc = wf_init_pm();
 
 	if (rc == 0) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_pm91.c linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_pm91.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_pm91.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_pm91.c	2010-05-16 17:17:36.000000000 -0400
@@ -711,7 +711,7 @@ static int __init wf_smu_init(void)
 {
 	int rc = -ENODEV;
 
-	if (machine_is_compatible("PowerMac9,1"))
+	if (of_machine_is_compatible("PowerMac9,1"))
 		rc = wf_init_pm();
 
 	if (rc == 0) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_smu_controls.c linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_smu_controls.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_smu_controls.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_smu_controls.c	2010-05-16 17:17:36.000000000 -0400
@@ -173,6 +173,7 @@ static struct smu_fan_control *smu_fan_c
 
 	fct->fan_type = pwm_fan;
 	fct->ctrl.type = pwm_fan ? WF_CONTROL_PWM_FAN : WF_CONTROL_RPM_FAN;
+	sysfs_attr_init(&fct->ctrl.attr.attr);
 
 	/* We use the name & location here the same way we do for SMU sensors,
 	 * see the comment in windfarm_smu_sensors.c. The locations are a bit
diff -druNp linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_smu_sensors.c linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_smu_sensors.c
--- linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_smu_sensors.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/macintosh/windfarm_smu_sensors.c	2010-05-16 17:17:36.000000000 -0400
@@ -363,9 +363,9 @@ smu_cpu_power_create(struct wf_sensor *v
 	 * I yet have to figure out what's up with 8,2 and will have to
 	 * adjust for later, unless we can 100% trust the SDB partition...
 	 */
-	if ((machine_is_compatible("PowerMac8,1") ||
-	     machine_is_compatible("PowerMac8,2") ||
-	     machine_is_compatible("PowerMac9,1")) &&
+	if ((of_machine_is_compatible("PowerMac8,1") ||
+	     of_machine_is_compatible("PowerMac8,2") ||
+	     of_machine_is_compatible("PowerMac9,1")) &&
 	    cpuvcp_version >= 2) {
 		pow->quadratic = 1;
 		DBG("windfarm: CPU Power using quadratic transform\n");
diff -druNp linux-libre-2.6.33-gnu1/drivers/Makefile linux-libre-2.6.34-gnu1/drivers/Makefile
--- linux-libre-2.6.33-gnu1/drivers/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@ obj-$(CONFIG_SFI)		+= sfi/
 obj-$(CONFIG_PNP)		+= pnp/
 obj-$(CONFIG_ARM_AMBA)		+= amba/
 
+obj-$(CONFIG_VIRTIO)		+= virtio/
 obj-$(CONFIG_XEN)		+= xen/
 
 # regulators early, since some subsystems rely on them to initialize
@@ -99,6 +100,7 @@ obj-$(CONFIG_SGI_SN)		+= sn/
 obj-y				+= firmware/
 obj-$(CONFIG_CRYPTO)		+= crypto/
 obj-$(CONFIG_SUPERH)		+= sh/
+obj-$(CONFIG_ARCH_SHMOBILE)	+= sh/
 obj-$(CONFIG_GENERIC_TIME)	+= clocksource/
 obj-$(CONFIG_DMA_ENGINE)	+= dma/
 obj-$(CONFIG_DCA)		+= dca/
@@ -106,7 +108,7 @@ obj-$(CONFIG_HID)		+= hid/
 obj-$(CONFIG_PPC_PS3)		+= ps3/
 obj-$(CONFIG_OF)		+= of/
 obj-$(CONFIG_SSB)		+= ssb/
-obj-$(CONFIG_VIRTIO)		+= virtio/
+obj-$(CONFIG_VHOST_NET)		+= vhost/
 obj-$(CONFIG_VLYNQ)		+= vlynq/
 obj-$(CONFIG_STAGING)		+= staging/
 obj-y				+= platform/
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm.c linux-libre-2.6.34-gnu1/drivers/md/dm.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm.c	2010-05-16 17:17:36.000000000 -0400
@@ -635,8 +635,10 @@ static void dec_pending(struct dm_io *io
 			if (!md->barrier_error && io_error != -EOPNOTSUPP)
 				md->barrier_error = io_error;
 			end_io_acct(io);
+			free_io(md, io);
 		} else {
 			end_io_acct(io);
+			free_io(md, io);
 
 			if (io_error != DM_ENDIO_REQUEUE) {
 				trace_block_bio_complete(md->queue, bio);
@@ -644,8 +646,6 @@ static void dec_pending(struct dm_io *io
 				bio_endio(bio, io_error);
 			}
 		}
-
-		free_io(md, io);
 	}
 }
 
@@ -2618,18 +2618,19 @@ out:
 /*-----------------------------------------------------------------
  * Event notification.
  *---------------------------------------------------------------*/
-void dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
+int dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
 		       unsigned cookie)
 {
 	char udev_cookie[DM_COOKIE_LENGTH];
 	char *envp[] = { udev_cookie, NULL };
 
 	if (!cookie)
-		kobject_uevent(&disk_to_dev(md->disk)->kobj, action);
+		return kobject_uevent(&disk_to_dev(md->disk)->kobj, action);
 	else {
 		snprintf(udev_cookie, DM_COOKIE_LENGTH, "%s=%u",
 			 DM_COOKIE_ENV_VAR_NAME, cookie);
-		kobject_uevent_env(&disk_to_dev(md->disk)->kobj, action, envp);
+		return kobject_uevent_env(&disk_to_dev(md->disk)->kobj,
+					  action, envp);
 	}
 }
 
@@ -2699,23 +2700,13 @@ int dm_suspended_md(struct mapped_device
 
 int dm_suspended(struct dm_target *ti)
 {
-	struct mapped_device *md = dm_table_get_md(ti->table);
-	int r = dm_suspended_md(md);
-
-	dm_put(md);
-
-	return r;
+	return dm_suspended_md(dm_table_get_md(ti->table));
 }
 EXPORT_SYMBOL_GPL(dm_suspended);
 
 int dm_noflush_suspending(struct dm_target *ti)
 {
-	struct mapped_device *md = dm_table_get_md(ti->table);
-	int r = __noflush_suspending(md);
-
-	dm_put(md);
-
-	return r;
+	return __noflush_suspending(dm_table_get_md(ti->table));
 }
 EXPORT_SYMBOL_GPL(dm_noflush_suspending);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-crypt.c linux-libre-2.6.34-gnu1/drivers/md/dm-crypt.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-crypt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-crypt.c	2010-05-16 17:17:36.000000000 -0400
@@ -1160,8 +1160,7 @@ static int crypt_ctr(struct dm_target *t
 	}
 	cc->start = tmpll;
 
-	if (dm_get_device(ti, argv[3], cc->start, ti->len,
-			  dm_table_get_mode(ti->table), &cc->dev)) {
+	if (dm_get_device(ti, argv[3], dm_table_get_mode(ti->table), &cc->dev)) {
 		ti->error = "Device lookup failed";
 		goto bad_device;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-delay.c linux-libre-2.6.34-gnu1/drivers/md/dm-delay.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-delay.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-delay.c	2010-05-16 17:17:36.000000000 -0400
@@ -156,8 +156,8 @@ static int delay_ctr(struct dm_target *t
 		goto bad;
 	}
 
-	if (dm_get_device(ti, argv[0], dc->start_read, ti->len,
-			  dm_table_get_mode(ti->table), &dc->dev_read)) {
+	if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
+			  &dc->dev_read)) {
 		ti->error = "Device lookup failed";
 		goto bad;
 	}
@@ -177,8 +177,8 @@ static int delay_ctr(struct dm_target *t
 		goto bad_dev_read;
 	}
 
-	if (dm_get_device(ti, argv[3], dc->start_write, ti->len,
-			  dm_table_get_mode(ti->table), &dc->dev_write)) {
+	if (dm_get_device(ti, argv[3], dm_table_get_mode(ti->table),
+			  &dc->dev_write)) {
 		ti->error = "Write device lookup failed";
 		goto bad_dev_read;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm.h linux-libre-2.6.34-gnu1/drivers/md/dm.h
--- linux-libre-2.6.33-gnu1/drivers/md/dm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm.h	2010-05-16 17:17:36.000000000 -0400
@@ -125,8 +125,8 @@ void dm_stripe_exit(void);
 int dm_open_count(struct mapped_device *md);
 int dm_lock_for_deletion(struct mapped_device *md);
 
-void dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
-		       unsigned cookie);
+int dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
+		      unsigned cookie);
 
 int dm_io_init(void);
 void dm_io_exit(void);
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-ioctl.c linux-libre-2.6.34-gnu1/drivers/md/dm-ioctl.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -285,7 +285,8 @@ retry:
 	up_write(&_hash_lock);
 }
 
-static int dm_hash_rename(uint32_t cookie, const char *old, const char *new)
+static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old,
+			  const char *new)
 {
 	char *new_name, *old_name;
 	struct hash_cell *hc;
@@ -344,7 +345,8 @@ static int dm_hash_rename(uint32_t cooki
 		dm_table_put(table);
 	}
 
-	dm_kobject_uevent(hc->md, KOBJ_CHANGE, cookie);
+	if (!dm_kobject_uevent(hc->md, KOBJ_CHANGE, cookie))
+		*flags |= DM_UEVENT_GENERATED_FLAG;
 
 	dm_put(hc->md);
 	up_write(&_hash_lock);
@@ -736,10 +738,10 @@ static int dev_remove(struct dm_ioctl *p
 	__hash_remove(hc);
 	up_write(&_hash_lock);
 
-	dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr);
+	if (!dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr))
+		param->flags |= DM_UEVENT_GENERATED_FLAG;
 
 	dm_put(md);
-	param->data_size = 0;
 	return 0;
 }
 
@@ -773,7 +775,9 @@ static int dev_rename(struct dm_ioctl *p
 		return r;
 
 	param->data_size = 0;
-	return dm_hash_rename(param->event_nr, param->name, new_name);
+
+	return dm_hash_rename(param->event_nr, &param->flags, param->name,
+			      new_name);
 }
 
 static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
@@ -897,16 +901,17 @@ static int do_resume(struct dm_ioctl *pa
 			set_disk_ro(dm_disk(md), 1);
 	}
 
-	if (dm_suspended_md(md))
+	if (dm_suspended_md(md)) {
 		r = dm_resume(md);
+		if (!r && !dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr))
+			param->flags |= DM_UEVENT_GENERATED_FLAG;
+	}
 
 	if (old_map)
 		dm_table_destroy(old_map);
 
-	if (!r) {
-		dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr);
+	if (!r)
 		r = __dev_status(md, param);
-	}
 
 	dm_put(md);
 	return r;
@@ -1476,6 +1481,7 @@ static int validate_params(uint cmd, str
 {
 	/* Always clear this flag */
 	param->flags &= ~DM_BUFFER_FULL_FLAG;
+	param->flags &= ~DM_UEVENT_GENERATED_FLAG;
 
 	/* Ignores parameters */
 	if (cmd == DM_REMOVE_ALL_CMD ||
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-linear.c linux-libre-2.6.34-gnu1/drivers/md/dm-linear.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-linear.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-linear.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,8 +47,7 @@ static int linear_ctr(struct dm_target *
 	}
 	lc->start = tmp;
 
-	if (dm_get_device(ti, argv[0], lc->start, ti->len,
-			  dm_table_get_mode(ti->table), &lc->dev)) {
+	if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &lc->dev)) {
 		ti->error = "dm-linear: Device lookup failed";
 		goto bad;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-log.c linux-libre-2.6.34-gnu1/drivers/md/dm-log.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-log.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-log.c	2010-05-16 17:17:36.000000000 -0400
@@ -543,8 +543,7 @@ static int disk_ctr(struct dm_dirty_log
 		return -EINVAL;
 	}
 
-	r = dm_get_device(ti, argv[0], 0, 0 /* FIXME */,
-			  FMODE_READ | FMODE_WRITE, &dev);
+	r = dm_get_device(ti, argv[0], FMODE_READ | FMODE_WRITE, &dev);
 	if (r)
 		return r;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-log-userspace-base.c linux-libre-2.6.34-gnu1/drivers/md/dm-log-userspace-base.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-log-userspace-base.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-log-userspace-base.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
  */
 
 #include <linux/bio.h>
+#include <linux/slab.h>
 #include <linux/dm-dirty-log.h>
 #include <linux/device-mapper.h>
 #include <linux/dm-log-userspace.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-log-userspace-transfer.c linux-libre-2.6.34-gnu1/drivers/md/dm-log-userspace-transfer.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-log-userspace-transfer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-log-userspace-transfer.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <linux/workqueue.h>
 #include <linux/connector.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-mpath.c linux-libre-2.6.34-gnu1/drivers/md/dm-mpath.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-mpath.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-mpath.c	2010-05-16 17:17:36.000000000 -0400
@@ -69,6 +69,7 @@ struct multipath {
 	struct list_head priority_groups;
 	unsigned pg_init_required;	/* pg_init needs calling? */
 	unsigned pg_init_in_progress;	/* Only one pg_init allowed at once */
+	wait_queue_head_t pg_init_wait;	/* Wait for pg_init completion */
 
 	unsigned nr_valid_paths;	/* Total number of usable paths */
 	struct pgpath *current_pgpath;
@@ -95,8 +96,6 @@ struct multipath {
 	mempool_t *mpio_pool;
 
 	struct mutex work_mutex;
-
-	unsigned suspended;	/* Don't create new I/O internally when set. */
 };
 
 /*
@@ -202,6 +201,7 @@ static struct multipath *alloc_multipath
 		m->queue_io = 1;
 		INIT_WORK(&m->process_queued_ios, process_queued_ios);
 		INIT_WORK(&m->trigger_event, trigger_event);
+		init_waitqueue_head(&m->pg_init_wait);
 		mutex_init(&m->work_mutex);
 		m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache);
 		if (!m->mpio_pool) {
@@ -235,6 +235,21 @@ static void free_multipath(struct multip
  * Path selection
  *-----------------------------------------------*/
 
+static void __pg_init_all_paths(struct multipath *m)
+{
+	struct pgpath *pgpath;
+
+	m->pg_init_count++;
+	m->pg_init_required = 0;
+	list_for_each_entry(pgpath, &m->current_pg->pgpaths, list) {
+		/* Skip failed paths */
+		if (!pgpath->is_active)
+			continue;
+		if (queue_work(kmpath_handlerd, &pgpath->activate_path))
+			m->pg_init_in_progress++;
+	}
+}
+
 static void __switch_pg(struct multipath *m, struct pgpath *pgpath)
 {
 	m->current_pg = pgpath->pg;
@@ -439,7 +454,7 @@ static void process_queued_ios(struct wo
 {
 	struct multipath *m =
 		container_of(work, struct multipath, process_queued_ios);
-	struct pgpath *pgpath = NULL, *tmp;
+	struct pgpath *pgpath = NULL;
 	unsigned must_queue = 1;
 	unsigned long flags;
 
@@ -457,14 +472,9 @@ static void process_queued_ios(struct wo
 	    (!pgpath && !m->queue_if_no_path))
 		must_queue = 0;
 
-	if (m->pg_init_required && !m->pg_init_in_progress && pgpath) {
-		m->pg_init_count++;
-		m->pg_init_required = 0;
-		list_for_each_entry(tmp, &pgpath->pg->pgpaths, list) {
-			if (queue_work(kmpath_handlerd, &tmp->activate_path))
-				m->pg_init_in_progress++;
-		}
-	}
+	if (m->pg_init_required && !m->pg_init_in_progress && pgpath)
+		__pg_init_all_paths(m);
+
 out:
 	spin_unlock_irqrestore(&m->lock, flags);
 	if (!must_queue)
@@ -597,8 +607,8 @@ static struct pgpath *parse_path(struct
 	if (!p)
 		return ERR_PTR(-ENOMEM);
 
-	r = dm_get_device(ti, shift(as), ti->begin, ti->len,
-			  dm_table_get_mode(ti->table), &p->path.dev);
+	r = dm_get_device(ti, shift(as), dm_table_get_mode(ti->table),
+			  &p->path.dev);
 	if (r) {
 		ti->error = "error getting device";
 		goto bad;
@@ -890,9 +900,34 @@ static int multipath_ctr(struct dm_targe
 	return r;
 }
 
-static void flush_multipath_work(void)
+static void multipath_wait_for_pg_init_completion(struct multipath *m)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	unsigned long flags;
+
+	add_wait_queue(&m->pg_init_wait, &wait);
+
+	while (1) {
+		set_current_state(TASK_UNINTERRUPTIBLE);
+
+		spin_lock_irqsave(&m->lock, flags);
+		if (!m->pg_init_in_progress) {
+			spin_unlock_irqrestore(&m->lock, flags);
+			break;
+		}
+		spin_unlock_irqrestore(&m->lock, flags);
+
+		io_schedule();
+	}
+	set_current_state(TASK_RUNNING);
+
+	remove_wait_queue(&m->pg_init_wait, &wait);
+}
+
+static void flush_multipath_work(struct multipath *m)
 {
 	flush_workqueue(kmpath_handlerd);
+	multipath_wait_for_pg_init_completion(m);
 	flush_workqueue(kmultipathd);
 	flush_scheduled_work();
 }
@@ -901,7 +936,7 @@ static void multipath_dtr(struct dm_targ
 {
 	struct multipath *m = ti->private;
 
-	flush_multipath_work();
+	flush_multipath_work(m);
 	free_multipath(m);
 }
 
@@ -1128,8 +1163,7 @@ static int pg_init_limit_reached(struct
 
 static void pg_init_done(void *data, int errors)
 {
-	struct dm_path *path = data;
-	struct pgpath *pgpath = path_to_pgpath(path);
+	struct pgpath *pgpath = data;
 	struct priority_group *pg = pgpath->pg;
 	struct multipath *m = pg->m;
 	unsigned long flags;
@@ -1143,8 +1177,8 @@ static void pg_init_done(void *data, int
 			errors = 0;
 			break;
 		}
-		DMERR("Cannot failover device because scsi_dh_%s was not "
-		      "loaded.", m->hw_handler_name);
+		DMERR("Could not failover the device: Handler scsi_dh_%s "
+		      "Error %d.", m->hw_handler_name, errors);
 		/*
 		 * Fail path for now, so we do not ping pong
 		 */
@@ -1181,14 +1215,24 @@ static void pg_init_done(void *data, int
 			m->current_pgpath = NULL;
 			m->current_pg = NULL;
 		}
-	} else if (!m->pg_init_required) {
-		m->queue_io = 0;
+	} else if (!m->pg_init_required)
 		pg->bypassed = 0;
-	}
 
-	m->pg_init_in_progress--;
-	if (!m->pg_init_in_progress)
-		queue_work(kmultipathd, &m->process_queued_ios);
+	if (--m->pg_init_in_progress)
+		/* Activations of other paths are still on going */
+		goto out;
+
+	if (!m->pg_init_required)
+		m->queue_io = 0;
+
+	queue_work(kmultipathd, &m->process_queued_ios);
+
+	/*
+	 * Wake up any thread waiting to suspend.
+	 */
+	wake_up(&m->pg_init_wait);
+
+out:
 	spin_unlock_irqrestore(&m->lock, flags);
 }
 
@@ -1198,7 +1242,7 @@ static void activate_path(struct work_st
 		container_of(work, struct pgpath, activate_path);
 
 	scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev),
-				pg_init_done, &pgpath->path);
+				pg_init_done, pgpath);
 }
 
 /*
@@ -1276,8 +1320,7 @@ static void multipath_postsuspend(struct
 	struct multipath *m = ti->private;
 
 	mutex_lock(&m->work_mutex);
-	m->suspended = 1;
-	flush_multipath_work();
+	flush_multipath_work(m);
 	mutex_unlock(&m->work_mutex);
 }
 
@@ -1289,10 +1332,6 @@ static void multipath_resume(struct dm_t
 	struct multipath *m = (struct multipath *) ti->private;
 	unsigned long flags;
 
-	mutex_lock(&m->work_mutex);
-	m->suspended = 0;
-	mutex_unlock(&m->work_mutex);
-
 	spin_lock_irqsave(&m->lock, flags);
 	m->queue_if_no_path = m->saved_queue_if_no_path;
 	spin_unlock_irqrestore(&m->lock, flags);
@@ -1428,11 +1467,6 @@ static int multipath_message(struct dm_t
 
 	mutex_lock(&m->work_mutex);
 
-	if (m->suspended) {
-		r = -EBUSY;
-		goto out;
-	}
-
 	if (dm_suspended(ti)) {
 		r = -EBUSY;
 		goto out;
@@ -1471,8 +1505,7 @@ static int multipath_message(struct dm_t
 		goto out;
 	}
 
-	r = dm_get_device(ti, argv[1], ti->begin, ti->len,
-			  dm_table_get_mode(ti->table), &dev);
+	r = dm_get_device(ti, argv[1], dm_table_get_mode(ti->table), &dev);
 	if (r) {
 		DMWARN("message: error getting device %s",
 		       argv[1]);
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-raid1.c linux-libre-2.6.34-gnu1/drivers/md/dm-raid1.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-raid1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-raid1.c	2010-05-16 17:17:36.000000000 -0400
@@ -465,9 +465,17 @@ static void map_region(struct dm_io_regi
 static void hold_bio(struct mirror_set *ms, struct bio *bio)
 {
 	/*
-	 * If device is suspended, complete the bio.
+	 * Lock is required to avoid race condition during suspend
+	 * process.
 	 */
+	spin_lock_irq(&ms->lock);
+
 	if (atomic_read(&ms->suspend)) {
+		spin_unlock_irq(&ms->lock);
+
+		/*
+		 * If device is suspended, complete the bio.
+		 */
 		if (dm_noflush_suspending(ms->ti))
 			bio_endio(bio, DM_ENDIO_REQUEUE);
 		else
@@ -478,7 +486,6 @@ static void hold_bio(struct mirror_set *
 	/*
 	 * Hold bio until the suspend is complete.
 	 */
-	spin_lock_irq(&ms->lock);
 	bio_list_add(&ms->holds, bio);
 	spin_unlock_irq(&ms->lock);
 }
@@ -737,9 +744,12 @@ static void do_writes(struct mirror_set
 		dm_rh_delay(ms->rh, bio);
 
 	while ((bio = bio_list_pop(&nosync))) {
-		if (unlikely(ms->leg_failure) && errors_handled(ms))
-			hold_bio(ms, bio);
-		else {
+		if (unlikely(ms->leg_failure) && errors_handled(ms)) {
+			spin_lock_irq(&ms->lock);
+			bio_list_add(&ms->failures, bio);
+			spin_unlock_irq(&ms->lock);
+			wakeup_mirrord(ms);
+		} else {
 			map_bio(get_default_mirror(ms), bio);
 			generic_make_request(bio);
 		}
@@ -917,8 +927,7 @@ static int get_mirror(struct mirror_set
 		return -EINVAL;
 	}
 
-	if (dm_get_device(ti, argv[0], offset, ti->len,
-			  dm_table_get_mode(ti->table),
+	if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
 			  &ms->mirror[mirror].dev)) {
 		ti->error = "Device lookup failure";
 		return -ENXIO;
@@ -1259,6 +1268,20 @@ static void mirror_presuspend(struct dm_
 	atomic_set(&ms->suspend, 1);
 
 	/*
+	 * Process bios in the hold list to start recovery waiting
+	 * for bios in the hold list. After the process, no bio has
+	 * a chance to be added in the hold list because ms->suspend
+	 * is set.
+	 */
+	spin_lock_irq(&ms->lock);
+	holds = ms->holds;
+	bio_list_init(&ms->holds);
+	spin_unlock_irq(&ms->lock);
+
+	while ((bio = bio_list_pop(&holds)))
+		hold_bio(ms, bio);
+
+	/*
 	 * We must finish up all the work that we've
 	 * generated (i.e. recovery work).
 	 */
@@ -1278,22 +1301,6 @@ static void mirror_presuspend(struct dm_
 	 * we know that all of our I/O has been pushed.
 	 */
 	flush_workqueue(ms->kmirrord_wq);
-
-	/*
-	 * Now set ms->suspend is set and the workqueue flushed, no more
-	 * entries can be added to ms->hold list, so process it.
-	 *
-	 * Bios can still arrive concurrently with or after this
-	 * presuspend function, but they cannot join the hold list
-	 * because ms->suspend is set.
-	 */
-	spin_lock_irq(&ms->lock);
-	holds = ms->holds;
-	bio_list_init(&ms->holds);
-	spin_unlock_irq(&ms->lock);
-
-	while ((bio = bio_list_pop(&holds)))
-		hold_bio(ms, bio);
 }
 
 static void mirror_postsuspend(struct dm_target *ti)
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-region-hash.c linux-libre-2.6.34-gnu1/drivers/md/dm-region-hash.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-region-hash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-region-hash.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "dm.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-service-time.c linux-libre-2.6.34-gnu1/drivers/md/dm-service-time.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-service-time.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-service-time.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,8 @@
 #include "dm.h"
 #include "dm-path-selector.h"
 
+#include <linux/slab.h>
+
 #define DM_MSG_PREFIX	"multipath service-time"
 #define ST_MIN_IO	1
 #define ST_MAX_RELATIVE_THROUGHPUT	100
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-snap.c linux-libre-2.6.34-gnu1/drivers/md/dm-snap.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-snap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-snap.c	2010-05-16 17:17:36.000000000 -0400
@@ -83,10 +83,10 @@ struct dm_snapshot {
 	/* Whether or not owning mapped_device is suspended */
 	int suspended;
 
-	mempool_t *pending_pool;
-
 	atomic_t pending_exceptions_count;
 
+	mempool_t *pending_pool;
+
 	struct dm_exception_table pending;
 	struct dm_exception_table complete;
 
@@ -96,6 +96,11 @@ struct dm_snapshot {
 	 */
 	spinlock_t pe_lock;
 
+	/* Chunks with outstanding reads */
+	spinlock_t tracked_chunk_lock;
+	mempool_t *tracked_chunk_pool;
+	struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
+
 	/* The on disk metadata handler */
 	struct dm_exception_store *store;
 
@@ -105,10 +110,12 @@ struct dm_snapshot {
 	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];
+	/* Wait for events based on state_bits */
+	unsigned long state_bits;
+
+	/* Range of chunks currently being merged. */
+	chunk_t first_merging_chunk;
+	int num_merging_chunks;
 
 	/*
 	 * The merge operation failed if this flag is set.
@@ -125,13 +132,6 @@ struct dm_snapshot {
 	 */
 	int merge_failed;
 
-	/* Wait for events based on state_bits */
-	unsigned long state_bits;
-
-	/* Range of chunks currently being merged. */
-	chunk_t first_merging_chunk;
-	int num_merging_chunks;
-
 	/*
 	 * Incoming bios that overlap with chunks being merged must wait
 	 * for them to be committed.
@@ -1081,8 +1081,7 @@ static int snapshot_ctr(struct dm_target
 	argv++;
 	argc--;
 
-	r = dm_get_device(ti, cow_path, 0, 0,
-			  FMODE_READ | FMODE_WRITE, &s->cow);
+	r = dm_get_device(ti, cow_path, FMODE_READ | FMODE_WRITE, &s->cow);
 	if (r) {
 		ti->error = "Cannot get COW device";
 		goto bad_cow;
@@ -1098,7 +1097,7 @@ static int snapshot_ctr(struct dm_target
 	argv += args_used;
 	argc -= args_used;
 
-	r = dm_get_device(ti, origin_path, 0, ti->len, origin_mode, &s->origin);
+	r = dm_get_device(ti, origin_path, origin_mode, &s->origin);
 	if (r) {
 		ti->error = "Cannot get origin device";
 		goto bad_origin;
@@ -2100,8 +2099,7 @@ static int origin_ctr(struct dm_target *
 		return -EINVAL;
 	}
 
-	r = dm_get_device(ti, argv[0], 0, ti->len,
-			  dm_table_get_mode(ti->table), &dev);
+	r = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &dev);
 	if (r) {
 		ti->error = "Cannot get target device";
 		return r;
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-stripe.c linux-libre-2.6.34-gnu1/drivers/md/dm-stripe.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-stripe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-stripe.c	2010-05-16 17:17:36.000000000 -0400
@@ -80,8 +80,7 @@ static int get_stripe(struct dm_target *
 	if (sscanf(argv[1], "%llu", &start) != 1)
 		return -EINVAL;
 
-	if (dm_get_device(ti, argv[0], start, sc->stripe_width,
-			  dm_table_get_mode(ti->table),
+	if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
 			  &sc->stripe[stripe].dev))
 		return -ENXIO;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-sysfs.c linux-libre-2.6.34-gnu1/drivers/md/dm-sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -75,7 +75,7 @@ static struct attribute *dm_attrs[] = {
 	NULL,
 };
 
-static struct sysfs_ops dm_sysfs_ops = {
+static const struct sysfs_ops dm_sysfs_ops = {
 	.show	= dm_attr_show,
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-table.c linux-libre-2.6.34-gnu1/drivers/md/dm-table.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-table.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-table.c	2010-05-16 17:17:36.000000000 -0400
@@ -429,8 +429,7 @@ static int upgrade_mode(struct dm_dev_in
  * it's already present.
  */
 static int __table_get_device(struct dm_table *t, struct dm_target *ti,
-			      const char *path, sector_t start, sector_t len,
-			      fmode_t mode, struct dm_dev **result)
+		      const char *path, fmode_t mode, struct dm_dev **result)
 {
 	int r;
 	dev_t uninitialized_var(dev);
@@ -527,11 +526,10 @@ int dm_set_device_limits(struct dm_targe
 }
 EXPORT_SYMBOL_GPL(dm_set_device_limits);
 
-int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
-		  sector_t len, fmode_t mode, struct dm_dev **result)
+int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode,
+		  struct dm_dev **result)
 {
-	return __table_get_device(ti->table, ti, path,
-				  start, len, mode, result);
+	return __table_get_device(ti->table, ti, path, mode, result);
 }
 
 
@@ -1231,8 +1229,6 @@ void dm_table_unplug_all(struct dm_table
 
 struct mapped_device *dm_table_get_md(struct dm_table *t)
 {
-	dm_get(t->md);
-
 	return t->md;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-target.c linux-libre-2.6.34-gnu1/drivers/md/dm-target.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-target.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-target.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/bio.h>
-#include <linux/slab.h>
 
 #define DM_MSG_PREFIX "target"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/dm-uevent.c linux-libre-2.6.34-gnu1/drivers/md/dm-uevent.c
--- linux-libre-2.6.33-gnu1/drivers/md/dm-uevent.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/dm-uevent.c	2010-05-16 17:17:36.000000000 -0400
@@ -187,7 +187,7 @@ void dm_path_uevent(enum dm_uevent_type
 
 	if (event_type >= ARRAY_SIZE(_dm_uevent_type_names)) {
 		DMERR("%s: Invalid event_type %d", __func__, event_type);
-		goto out;
+		return;
 	}
 
 	event = dm_build_path_uevent(md, ti,
@@ -195,12 +195,9 @@ void dm_path_uevent(enum dm_uevent_type
 				     _dm_uevent_type_names[event_type].name,
 				     path, nr_valid_paths);
 	if (IS_ERR(event))
-		goto out;
+		return;
 
 	dm_uevent_add(md, &event->elist);
-
-out:
-	dm_put(md);
 }
 EXPORT_SYMBOL_GPL(dm_path_uevent);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/faulty.c linux-libre-2.6.34-gnu1/drivers/md/faulty.c
--- linux-libre-2.6.33-gnu1/drivers/md/faulty.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/faulty.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,6 +64,7 @@
 #define MaxFault	50
 #include <linux/blkdev.h>
 #include <linux/raid/md_u.h>
+#include <linux/slab.h>
 #include "md.h"
 #include <linux/seq_file.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/linear.c linux-libre-2.6.34-gnu1/drivers/md/linear.c
--- linux-libre-2.6.33-gnu1/drivers/md/linear.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/linear.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/blkdev.h>
 #include <linux/raid/md_u.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "md.h"
 #include "linear.h"
 
@@ -172,12 +173,14 @@ static linear_conf_t *linear_conf(mddev_
 		disk_stack_limits(mddev->gendisk, rdev->bdev,
 				  rdev->data_offset << 9);
 		/* as we don't honour merge_bvec_fn, we must never risk
-		 * violating it, so limit ->max_sector to one PAGE, as
-		 * a one page request is never in violation.
+		 * violating it, so limit max_segments to 1 lying within
+		 * a single page.
 		 */
-		if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
-		    queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
-			blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
+		if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+			blk_queue_max_segments(mddev->queue, 1);
+			blk_queue_segment_boundary(mddev->queue,
+						   PAGE_CACHE_SIZE - 1);
+		}
 
 		conf->array_sectors += rdev->sectors;
 		cnt++;
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/md.c linux-libre-2.6.34-gnu1/drivers/md/md.c
--- linux-libre-2.6.33-gnu1/drivers/md/md.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/md.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,7 @@
 #include <linux/delay.h>
 #include <linux/raid/md_p.h>
 #include <linux/raid/md_u.h>
+#include <linux/slab.h>
 #include "md.h"
 #include "bitmap.h"
 
@@ -2108,12 +2109,18 @@ repeat:
 		if (!mddev->in_sync || mddev->recovery_cp != MaxSector) { /* not clean */
 			/* .. if the array isn't clean, an 'even' event must also go
 			 * to spares. */
-			if ((mddev->events&1)==0)
+			if ((mddev->events&1)==0) {
 				nospares = 0;
+				sync_req = 2; /* force a second update to get the
+					       * even/odd in sync */
+			}
 		} else {
 			/* otherwise an 'odd' event must go to spares */
-			if ((mddev->events&1))
+			if ((mddev->events&1)) {
 				nospares = 0;
+				sync_req = 2; /* force a second update to get the
+					       * even/odd in sync */
+			}
 		}
 	}
 
@@ -2642,7 +2649,7 @@ static void rdev_free(struct kobject *ko
 	mdk_rdev_t *rdev = container_of(ko, mdk_rdev_t, kobj);
 	kfree(rdev);
 }
-static struct sysfs_ops rdev_sysfs_ops = {
+static const struct sysfs_ops rdev_sysfs_ops = {
 	.show		= rdev_attr_show,
 	.store		= rdev_attr_store,
 };
@@ -4059,7 +4066,7 @@ static void md_free(struct kobject *ko)
 	kfree(mddev);
 }
 
-static struct sysfs_ops md_sysfs_ops = {
+static const struct sysfs_ops md_sysfs_ops = {
 	.show	= md_attr_show,
 	.store	= md_attr_store,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/multipath.c linux-libre-2.6.34-gnu1/drivers/md/multipath.c
--- linux-libre-2.6.33-gnu1/drivers/md/multipath.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/multipath.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/blkdev.h>
 #include <linux/raid/md_u.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "md.h"
 #include "multipath.h"
 
@@ -301,14 +302,16 @@ static int multipath_add_disk(mddev_t *m
 					  rdev->data_offset << 9);
 
 		/* as we don't honour merge_bvec_fn, we must never risk
-		 * violating it, so limit ->max_sector to one PAGE, as
-		 * a one page request is never in violation.
+		 * violating it, so limit ->max_segments to one, lying
+		 * within a single page.
 		 * (Note: it is very unlikely that a device with
 		 * merge_bvec_fn will be involved in multipath.)
 		 */
-			if (q->merge_bvec_fn &&
-			    queue_max_sectors(q) > (PAGE_SIZE>>9))
-				blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
+			if (q->merge_bvec_fn) {
+				blk_queue_max_segments(mddev->queue, 1);
+				blk_queue_segment_boundary(mddev->queue,
+							   PAGE_CACHE_SIZE - 1);
+			}
 
 			conf->working_disks++;
 			mddev->degraded--;
@@ -476,9 +479,11 @@ static int multipath_run (mddev_t *mddev
 		/* as we don't honour merge_bvec_fn, we must never risk
 		 * violating it, not that we ever expect a device with
 		 * a merge_bvec_fn to be involved in multipath */
-		if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
-		    queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
-			blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
+		if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+			blk_queue_max_segments(mddev->queue, 1);
+			blk_queue_segment_boundary(mddev->queue,
+						   PAGE_CACHE_SIZE - 1);
+		}
 
 		if (!test_bit(Faulty, &rdev->flags))
 			conf->working_disks++;
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/raid0.c linux-libre-2.6.34-gnu1/drivers/md/raid0.c
--- linux-libre-2.6.33-gnu1/drivers/md/raid0.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/raid0.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 
 #include <linux/blkdev.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "md.h"
 #include "raid0.h"
 
@@ -176,14 +177,15 @@ static int create_strip_zones(mddev_t *m
 		disk_stack_limits(mddev->gendisk, rdev1->bdev,
 				  rdev1->data_offset << 9);
 		/* as we don't honour merge_bvec_fn, we must never risk
-		 * violating it, so limit ->max_sector to one PAGE, as
-		 * a one page request is never in violation.
+		 * violating it, so limit ->max_segments to 1, lying within
+		 * a single page.
 		 */
 
-		if (rdev1->bdev->bd_disk->queue->merge_bvec_fn &&
-		    queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
-			blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
-
+		if (rdev1->bdev->bd_disk->queue->merge_bvec_fn) {
+			blk_queue_max_segments(mddev->queue, 1);
+			blk_queue_segment_boundary(mddev->queue,
+						   PAGE_CACHE_SIZE - 1);
+		}
 		if (!smallest || (rdev1->sectors < smallest->sectors))
 			smallest = rdev1;
 		cnt++;
@@ -325,7 +327,7 @@ static int raid0_run(mddev_t *mddev)
 	}
 	if (md_check_no_bitmap(mddev))
 		return -EINVAL;
-	blk_queue_max_sectors(mddev->queue, mddev->chunk_sectors);
+	blk_queue_max_hw_sectors(mddev->queue, mddev->chunk_sectors);
 	mddev->queue->queue_lock = &mddev->queue->__queue_lock;
 
 	ret = create_strip_zones(mddev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/raid10.c linux-libre-2.6.34-gnu1/drivers/md/raid10.c
--- linux-libre-2.6.33-gnu1/drivers/md/raid10.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/raid10.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/seq_file.h>
@@ -1155,13 +1156,17 @@ static int raid10_add_disk(mddev_t *mdde
 
 			disk_stack_limits(mddev->gendisk, rdev->bdev,
 					  rdev->data_offset << 9);
-			/* as we don't honour merge_bvec_fn, we must never risk
-			 * violating it, so limit ->max_sector to one PAGE, as
-			 * a one page request is never in violation.
+			/* as we don't honour merge_bvec_fn, we must
+			 * never risk violating it, so limit
+			 * ->max_segments to one lying with a single
+			 * page, as a one page request is never in
+			 * violation.
 			 */
-			if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
-			    queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
-				blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
+			if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+				blk_queue_max_segments(mddev->queue, 1);
+				blk_queue_segment_boundary(mddev->queue,
+							   PAGE_CACHE_SIZE - 1);
+			}
 
 			p->head_position = 0;
 			rdev->raid_disk = mirror;
@@ -2255,12 +2260,14 @@ static int run(mddev_t *mddev)
 		disk_stack_limits(mddev->gendisk, rdev->bdev,
 				  rdev->data_offset << 9);
 		/* as we don't honour merge_bvec_fn, we must never risk
-		 * violating it, so limit ->max_sector to one PAGE, as
-		 * a one page request is never in violation.
+		 * violating it, so limit max_segments to 1 lying
+		 * within a single page.
 		 */
-		if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
-		    queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
-			blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
+		if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+			blk_queue_max_segments(mddev->queue, 1);
+			blk_queue_segment_boundary(mddev->queue,
+						   PAGE_CACHE_SIZE - 1);
+		}
 
 		disk->head_position = 0;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/raid1.c linux-libre-2.6.34-gnu1/drivers/md/raid1.c
--- linux-libre-2.6.33-gnu1/drivers/md/raid1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/raid1.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/seq_file.h>
@@ -1152,13 +1153,17 @@ static int raid1_add_disk(mddev_t *mddev
 
 			disk_stack_limits(mddev->gendisk, rdev->bdev,
 					  rdev->data_offset << 9);
-			/* as we don't honour merge_bvec_fn, we must never risk
-			 * violating it, so limit ->max_sector to one PAGE, as
-			 * a one page request is never in violation.
+			/* as we don't honour merge_bvec_fn, we must
+			 * never risk violating it, so limit
+			 * ->max_segments to one lying with a single
+			 * page, as a one page request is never in
+			 * violation.
 			 */
-			if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
-			    queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
-				blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
+			if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+				blk_queue_max_segments(mddev->queue, 1);
+				blk_queue_segment_boundary(mddev->queue,
+							   PAGE_CACHE_SIZE - 1);
+			}
 
 			p->head_position = 0;
 			rdev->raid_disk = mirror;
@@ -2098,12 +2103,14 @@ static int run(mddev_t *mddev)
 		disk_stack_limits(mddev->gendisk, rdev->bdev,
 				  rdev->data_offset << 9);
 		/* as we don't honour merge_bvec_fn, we must never risk
-		 * violating it, so limit ->max_sector to one PAGE, as
-		 * a one page request is never in violation.
+		 * violating it, so limit ->max_segments to 1 lying within
+		 * a single page, as a one page request is never in violation.
 		 */
-		if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
-		    queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
-			blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
+		if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+			blk_queue_max_segments(mddev->queue, 1);
+			blk_queue_segment_boundary(mddev->queue,
+						   PAGE_CACHE_SIZE - 1);
+		}
 	}
 
 	mddev->degraded = 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/raid5.c linux-libre-2.6.34-gnu1/drivers/md/raid5.c
--- linux-libre-2.6.33-gnu1/drivers/md/raid5.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/raid5.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,6 +50,7 @@
 #include <linux/async.h>
 #include <linux/seq_file.h>
 #include <linux/cpu.h>
+#include <linux/slab.h>
 #include "md.h"
 #include "raid5.h"
 #include "bitmap.h"
@@ -1526,7 +1527,7 @@ static void raid5_end_read_request(struc
 
 		clear_bit(R5_UPTODATE, &sh->dev[i].flags);
 		atomic_inc(&rdev->read_errors);
-		if (conf->mddev->degraded)
+		if (conf->mddev->degraded >= conf->max_degraded)
 			printk_rl(KERN_WARNING
 				  "raid5:%s: read error not correctable "
 				  "(sector %llu on %s).\n",
@@ -1649,8 +1650,8 @@ static sector_t raid5_compute_sector(rai
 				     int previous, int *dd_idx,
 				     struct stripe_head *sh)
 {
-	long stripe;
-	unsigned long chunk_number;
+	sector_t stripe, stripe2;
+	sector_t chunk_number;
 	unsigned int chunk_offset;
 	int pd_idx, qd_idx;
 	int ddf_layout = 0;
@@ -1670,18 +1671,13 @@ static sector_t raid5_compute_sector(rai
 	 */
 	chunk_offset = sector_div(r_sector, sectors_per_chunk);
 	chunk_number = r_sector;
-	BUG_ON(r_sector != chunk_number);
 
 	/*
 	 * Compute the stripe number
 	 */
-	stripe = chunk_number / data_disks;
-
-	/*
-	 * Compute the data disk and parity disk indexes inside the stripe
-	 */
-	*dd_idx = chunk_number % data_disks;
-
+	stripe = chunk_number;
+	*dd_idx = sector_div(stripe, data_disks);
+	stripe2 = stripe;
 	/*
 	 * Select the parity disk based on the user selected algorithm.
 	 */
@@ -1693,21 +1689,21 @@ static sector_t raid5_compute_sector(rai
 	case 5:
 		switch (algorithm) {
 		case ALGORITHM_LEFT_ASYMMETRIC:
-			pd_idx = data_disks - stripe % raid_disks;
+			pd_idx = data_disks - sector_div(stripe2, raid_disks);
 			if (*dd_idx >= pd_idx)
 				(*dd_idx)++;
 			break;
 		case ALGORITHM_RIGHT_ASYMMETRIC:
-			pd_idx = stripe % raid_disks;
+			pd_idx = sector_div(stripe2, raid_disks);
 			if (*dd_idx >= pd_idx)
 				(*dd_idx)++;
 			break;
 		case ALGORITHM_LEFT_SYMMETRIC:
-			pd_idx = data_disks - stripe % raid_disks;
+			pd_idx = data_disks - sector_div(stripe2, raid_disks);
 			*dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
 			break;
 		case ALGORITHM_RIGHT_SYMMETRIC:
-			pd_idx = stripe % raid_disks;
+			pd_idx = sector_div(stripe2, raid_disks);
 			*dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
 			break;
 		case ALGORITHM_PARITY_0:
@@ -1727,7 +1723,7 @@ static sector_t raid5_compute_sector(rai
 
 		switch (algorithm) {
 		case ALGORITHM_LEFT_ASYMMETRIC:
-			pd_idx = raid_disks - 1 - (stripe % raid_disks);
+			pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks);
 			qd_idx = pd_idx + 1;
 			if (pd_idx == raid_disks-1) {
 				(*dd_idx)++;	/* Q D D D P */
@@ -1736,7 +1732,7 @@ static sector_t raid5_compute_sector(rai
 				(*dd_idx) += 2; /* D D P Q D */
 			break;
 		case ALGORITHM_RIGHT_ASYMMETRIC:
-			pd_idx = stripe % raid_disks;
+			pd_idx = sector_div(stripe2, raid_disks);
 			qd_idx = pd_idx + 1;
 			if (pd_idx == raid_disks-1) {
 				(*dd_idx)++;	/* Q D D D P */
@@ -1745,12 +1741,12 @@ static sector_t raid5_compute_sector(rai
 				(*dd_idx) += 2; /* D D P Q D */
 			break;
 		case ALGORITHM_LEFT_SYMMETRIC:
-			pd_idx = raid_disks - 1 - (stripe % raid_disks);
+			pd_idx = raid_disks - 1 - sector_div(stripe2, 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;
+			pd_idx = sector_div(stripe2, raid_disks);
 			qd_idx = (pd_idx + 1) % raid_disks;
 			*dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
 			break;
@@ -1769,7 +1765,7 @@ static sector_t raid5_compute_sector(rai
 			/* Exactly the same as RIGHT_ASYMMETRIC, but or
 			 * of blocks for computing Q is different.
 			 */
-			pd_idx = stripe % raid_disks;
+			pd_idx = sector_div(stripe2, raid_disks);
 			qd_idx = pd_idx + 1;
 			if (pd_idx == raid_disks-1) {
 				(*dd_idx)++;	/* Q D D D P */
@@ -1784,7 +1780,8 @@ static sector_t raid5_compute_sector(rai
 			 * D D D P Q  rather than
 			 * Q D D D P
 			 */
-			pd_idx = raid_disks - 1 - ((stripe + 1) % raid_disks);
+			stripe2 += 1;
+			pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks);
 			qd_idx = pd_idx + 1;
 			if (pd_idx == raid_disks-1) {
 				(*dd_idx)++;	/* Q D D D P */
@@ -1796,7 +1793,7 @@ static sector_t raid5_compute_sector(rai
 
 		case ALGORITHM_ROTATING_N_CONTINUE:
 			/* Same as left_symmetric but Q is before P */
-			pd_idx = raid_disks - 1 - (stripe % raid_disks);
+			pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks);
 			qd_idx = (pd_idx + raid_disks - 1) % raid_disks;
 			*dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
 			ddf_layout = 1;
@@ -1804,27 +1801,27 @@ static sector_t raid5_compute_sector(rai
 
 		case ALGORITHM_LEFT_ASYMMETRIC_6:
 			/* RAID5 left_asymmetric, with Q on last device */
-			pd_idx = data_disks - stripe % (raid_disks-1);
+			pd_idx = data_disks - sector_div(stripe2, 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);
+			pd_idx = sector_div(stripe2, 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);
+			pd_idx = data_disks - sector_div(stripe2, 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);
+			pd_idx = sector_div(stripe2, raid_disks-1);
 			*dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
 			qd_idx = raid_disks - 1;
 			break;
@@ -1869,14 +1866,14 @@ static sector_t compute_blocknr(struct s
 				 : conf->algorithm;
 	sector_t stripe;
 	int chunk_offset;
-	int chunk_number, dummy1, dd_idx = i;
+	sector_t chunk_number;
+	int dummy1, dd_idx = i;
 	sector_t r_sector;
 	struct stripe_head sh2;
 
 
 	chunk_offset = sector_div(new_sector, sectors_per_chunk);
 	stripe = new_sector;
-	BUG_ON(new_sector != stripe);
 
 	if (i == sh->pd_idx)
 		return 0;
@@ -1969,7 +1966,7 @@ static sector_t compute_blocknr(struct s
 	}
 
 	chunk_number = stripe * data_disks + i;
-	r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
+	r_sector = chunk_number * sectors_per_chunk + chunk_offset;
 
 	check = raid5_compute_sector(conf, r_sector,
 				     previous, &dummy1, &sh2);
@@ -3739,7 +3736,7 @@ static int bio_fits_rdev(struct bio *bi)
 	if ((bi->bi_size>>9) > queue_max_sectors(q))
 		return 0;
 	blk_recount_segments(q, bi);
-	if (bi->bi_phys_segments > queue_max_phys_segments(q))
+	if (bi->bi_phys_segments > queue_max_segments(q))
 		return 0;
 
 	if (q->merge_bvec_fn)
@@ -4680,7 +4677,7 @@ static int raid5_alloc_percpu(raid5_conf
 {
 	unsigned long cpu;
 	struct page *spare_page;
-	struct raid5_percpu *allcpus;
+	struct raid5_percpu __percpu *allcpus;
 	void *scribble;
 	int err;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/raid5.h linux-libre-2.6.34-gnu1/drivers/md/raid5.h
--- linux-libre-2.6.33-gnu1/drivers/md/raid5.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/raid5.h	2010-05-16 17:17:36.000000000 -0400
@@ -405,7 +405,7 @@ struct raid5_private_data {
 					      * lists and performing address
 					      * conversions
 					      */
-	} *percpu;
+	} __percpu *percpu;
 	size_t			scribble_len; /* size of scribble region must be
 					       * associated with conf to handle
 					       * cpu hotplug while reshaping
diff -druNp linux-libre-2.6.33-gnu1/drivers/md/raid6algos.c linux-libre-2.6.34-gnu1/drivers/md/raid6algos.c
--- linux-libre-2.6.33-gnu1/drivers/md/raid6algos.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/md/raid6algos.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 
 #include <linux/raid/pq.h>
+#include <linux/gfp.h>
 #ifndef __KERNEL__
 #include <sys/mman.h>
 #include <stdio.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/common/saa7146_video.c linux-libre-2.6.34-gnu1/drivers/media/common/saa7146_video.c
--- linux-libre-2.6.33-gnu1/drivers/media/common/saa7146_video.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/common/saa7146_video.c	2010-05-16 17:17:36.000000000 -0400
@@ -558,9 +558,11 @@ static int vidioc_s_fbuf(struct file *fi
 	/* 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;
+
+	if (vv->ov_fb.fmt.bytesperline < vv->ov_fb.fmt.width) {
+		vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width * fmt->depth / 8;
+		DEB_D(("setting bytesperline to %d\n", vv->ov_fb.fmt.bytesperline));
+	}
 
 	mutex_unlock(&dev->lock);
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/common/tuners/max2165.c linux-libre-2.6.34-gnu1/drivers/media/common/tuners/max2165.c
--- linux-libre-2.6.33-gnu1/drivers/media/common/tuners/max2165.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/common/tuners/max2165.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mc44s803.c linux-libre-2.6.34-gnu1/drivers/media/common/tuners/mc44s803.c
--- linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mc44s803.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/common/tuners/mc44s803.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mt2060.c linux-libre-2.6.34-gnu1/drivers/media/common/tuners/mt2060.c
--- linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mt2060.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/common/tuners/mt2060.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mt20xx.c linux-libre-2.6.34-gnu1/drivers/media/common/tuners/mt20xx.c
--- linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mt20xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/common/tuners/mt20xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
  */
 #include <linux/delay.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/videodev2.h>
 #include "tuner-i2c.h"
 #include "mt20xx.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mt2131.c linux-libre-2.6.34-gnu1/drivers/media/common/tuners/mt2131.c
--- linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mt2131.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/common/tuners/mt2131.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mt2266.c linux-libre-2.6.34-gnu1/drivers/media/common/tuners/mt2266.c
--- linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mt2266.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/common/tuners/mt2266.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "mt2266.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda827x.c linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tda827x.c
--- linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda827x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tda827x.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/types.h>
 #include <linux/dvb/frontend.h>
 #include <linux/videodev2.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda8290.c linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tda8290.c
--- linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda8290.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tda8290.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/videodev2.h>
 #include "tuner-i2c.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda9887.c linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tda9887.c
--- linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda9887.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tda9887.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,6 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tea5761.c linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tea5761.c
--- linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tea5761.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tea5761.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/videodev2.h>
 #include <media/tuner.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tea5767.c linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tea5767.c
--- linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tea5767.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tea5767.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/videodev2.h>
 #include "tuner-i2c.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tuner-i2c.h linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tuner-i2c.h
--- linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tuner-i2c.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tuner-i2c.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #define __TUNER_I2C_H__
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 struct tuner_i2c_props {
 	u8 addr;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tuner-types.c linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tuner-types.c
--- linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tuner-types.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tuner-types.c	2010-05-16 17:17:36.000000000 -0400
@@ -1337,6 +1337,22 @@ static struct tuner_params tuner_philips
 	},
 };
 
+/* ---------------------- TUNER_SONY_BTF_PXN01Z ------------------------ */
+
+static struct tuner_range tuner_sony_btf_pxn01z_ranges[] = {
+	{ 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
+	{ 16 * 367.25 /*MHz*/, 0x8e, 0x02, },
+	{ 16 * 999.99        , 0x8e, 0x04, },
+};
+
+static struct tuner_params tuner_sony_btf_pxn01z_params[] = {
+	{
+		.type   = TUNER_PARAM_TYPE_NTSC,
+		.ranges = tuner_sony_btf_pxn01z_ranges,
+		.count  = ARRAY_SIZE(tuner_sony_btf_pxn01z_ranges),
+	},
+};
+
 /* --------------------------------------------------------------------- */
 
 struct tunertype tuners[] = {
@@ -1805,6 +1821,11 @@ struct tunertype tuners[] = {
 		.name   = "NXP TDA18271",
 		/* see tda18271-fe.c for details */
 	},
+	[TUNER_SONY_BTF_PXN01Z] = {
+		.name   = "Sony BTF-Pxn01Z",
+		.params = tuner_sony_btf_pxn01z_params,
+		.count  = ARRAY_SIZE(tuner_sony_btf_pxn01z_params),
+	},
 };
 EXPORT_SYMBOL(tuners);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tuner-xc2028.c linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tuner-xc2028.c
--- linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tuner-xc2028.c	2013-05-03 12:03:50.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/common/tuners/tuner-xc2028.c	2013-05-03 09:44:45.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 #include <media/tuner.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include "tuner-i2c.h"
 #include "tuner-xc2028.h"
@@ -917,30 +918,68 @@ static int generic_set_freq(struct dvb_f
 	 * that xc2028 will be in a safe state.
 	 * Maybe this might also be needed for DTV.
 	 */
-	if (new_mode == T_ANALOG_TV)
+	if (new_mode == T_ANALOG_TV) {
 		rc = send_seq(priv, {0x00, 0x00});
 
-	/*
-	 * Digital modes require an offset to adjust to the
-	 * proper frequency.
-	 * Analog modes require offset = 0
-	 */
-	if (new_mode == T_DIGITAL_TV) {
-		/* Sets the offset according with firmware */
+		/* Analog modes require offset = 0 */
+	} else {
+		/*
+		 * Digital modes require an offset to adjust to the
+		 * proper frequency. The offset depends on what
+		 * firmware version is used.
+		 */
+
+		/*
+		 * Adjust to the center frequency. This is calculated by the
+		 * formula: offset = 1.25MHz - BW/2
+		 * For DTV 7/8, the firmware uses BW = 8000, so it needs a
+		 * further adjustment to get the frequency center on VHF
+		 */
 		if (priv->cur_fw.type & DTV6)
 			offset = 1750000;
 		else if (priv->cur_fw.type & DTV7)
 			offset = 2250000;
 		else	/* DTV8 or DTV78 */
 			offset = 2750000;
+		if ((priv->cur_fw.type & DTV78) && freq < 470000000)
+			offset -= 500000;
 
 		/*
-		 * We must adjust the offset by 500kHz  when
-		 * tuning a 7MHz VHF channel with DTV78 firmware
-		 * (used in Australia, Italy and Germany)
+		 * xc3028 additional "magic"
+		 * Depending on the firmware version, it needs some adjustments
+		 * to properly centralize the frequency. This seems to be
+		 * needed to compensate the SCODE table adjustments made by
+		 * newer firmwares
 		 */
-		if ((priv->cur_fw.type & DTV78) && freq < 470000000)
-			offset -= 500000;
+
+#if 1
+		/*
+		 * The proper adjustment would be to do it at s-code table.
+		 * However, this didn't work, as reported by
+		 * Robert Lowery <rglowery@exemail.com.au>
+		 */
+
+		if (priv->cur_fw.type & DTV7)
+			offset += 500000;
+
+#else
+		/*
+		 * Still need tests for XC3028L (firmware 3.2 or upper)
+		 * So, for now, let's just comment the per-firmware
+		 * version of this change. Reports with xc3028l working
+		 * with and without the lines bellow are welcome
+		 */
+
+		if (priv->firm_version < 0x0302) {
+			if (priv->cur_fw.type & DTV7)
+				offset += 500000;
+		} else {
+			if (priv->cur_fw.type & DTV7)
+				offset -= 300000;
+			else if (type != ATSC) /* DVB @6MHz, DTV 8 and DTV 7/8 */
+				offset += 200000;
+		}
+#endif
 	}
 
 	div = (freq - offset + DIV / 2) / DIV;
@@ -1097,17 +1136,24 @@ static int xc2028_set_params(struct dvb_
 
 	/* All S-code tables need a 200kHz shift */
 	if (priv->ctrl.demod) {
-		demod = priv->ctrl.demod + 200;
+		demod = priv->ctrl.demod;
+
+		/*
+		 * Newer firmwares require a 200 kHz offset only for ATSC
+		 */
+		if (type == ATSC || priv->firm_version < 0x0302)
+			demod += 200;
 		/*
 		 * The DTV7 S-code table needs a 700 kHz shift.
-		 * Thanks to Terry Wu <terrywu2009@gmail.com> for reporting this
 		 *
 		 * DTV7 is only used in Australia.  Germany or Italy may also
 		 * use this firmware after initialization, but a tune to a UHF
 		 * channel should then cause DTV78 to be used.
+		 *
+		 * Unfortunately, on real-field tests, the s-code offset
+		 * didn't work as expected, as reported by
+		 * Robert Lowery <rglowery@exemail.com.au>
 		 */
-		if (type & DTV7)
-			demod += 500;
 	}
 
 	return generic_set_freq(fe, p->frequency,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/bt8xx/bt878.c linux-libre-2.6.34-gnu1/drivers/media/dvb/bt8xx/bt878.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/bt8xx/bt878.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/bt8xx/bt878.c	2010-05-16 17:17:36.000000000 -0400
@@ -576,43 +576,30 @@ static struct pci_driver bt878_pci_drive
       .remove	= __devexit_p(bt878_remove),
 };
 
-static int bt878_pci_driver_registered;
-
 /*******************************/
 /* Module management functions */
 /*******************************/
 
-static int bt878_init_module(void)
+static int __init bt878_init_module(void)
 {
 	bt878_num = 0;
-	bt878_pci_driver_registered = 0;
 
 	printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n",
 	       (BT878_VERSION_CODE >> 16) & 0xff,
 	       (BT878_VERSION_CODE >> 8) & 0xff,
 	       BT878_VERSION_CODE & 0xff);
-/*
-	bt878_check_chipset();
-*/
-	/* later we register inside of bt878_find_audio_dma()
-	 * because we may want to ignore certain cards */
-	bt878_pci_driver_registered = 1;
+
 	return pci_register_driver(&bt878_pci_driver);
 }
 
-static void bt878_cleanup_module(void)
+static void __exit bt878_cleanup_module(void)
 {
-	if (bt878_pci_driver_registered) {
-		bt878_pci_driver_registered = 0;
-		pci_unregister_driver(&bt878_pci_driver);
-	}
-	return;
+	pci_unregister_driver(&bt878_pci_driver);
 }
 
 module_init(bt878_init_module);
 module_exit(bt878_cleanup_module);
 
-//MODULE_AUTHOR("XXX");
 MODULE_LICENSE("GPL");
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/bt8xx/dst.c linux-libre-2.6.34-gnu1/drivers/media/dvb/bt8xx/dst.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/bt8xx/dst.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/bt8xx/dst.c	2010-05-16 17:17:36.000000000 -0400
@@ -1352,8 +1352,7 @@ static int dst_get_tuna(struct dst_state
 		return retval;
 	}
 	if ((state->type_flags & DST_TYPE_HAS_VLF) &&
-		!(state->dst_type == DST_TYPE_IS_CABLE) &&
-		!(state->dst_type == DST_TYPE_IS_ATSC)) {
+	   !(state->dst_type == DST_TYPE_IS_ATSC)) {
 
 		if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
 			dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
@@ -1820,8 +1819,13 @@ static struct dvb_frontend_ops dst_dvbc_
 		.frequency_max = 858000000,
 		.symbol_rate_min = 1000000,
 		.symbol_rate_max = 45000000,
-	/*     . symbol_rate_tolerance	=	???,*/
-		.caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO
+		.caps = FE_CAN_FEC_AUTO |
+			FE_CAN_QAM_AUTO |
+			FE_CAN_QAM_16	|
+			FE_CAN_QAM_32	|
+			FE_CAN_QAM_64	|
+			FE_CAN_QAM_128	|
+			FE_CAN_QAM_256
 	},
 
 	.release = dst_release,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/bt8xx/dst_ca.c linux-libre-2.6.34-gnu1/drivers/media/dvb/bt8xx/dst_ca.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/bt8xx/dst_ca.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/bt8xx/dst_ca.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
 #include <linux/string.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dm1105/dm1105.c linux-libre-2.6.34-gnu1/drivers/media/dvb/dm1105/dm1105.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dm1105/dm1105.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dm1105/dm1105.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <media/ir-common.h>
 
 #include "demux.h"
@@ -43,6 +44,7 @@
 #include "si21xx.h"
 #include "cx24116.h"
 #include "z0194a.h"
+#include "ds3000.h"
 
 #define UNSET (-1U)
 
@@ -269,7 +271,7 @@ struct infrared {
 	u32			ir_command;
 };
 
-struct dm1105dvb {
+struct dm1105_dev {
 	/* pci */
 	struct pci_dev *pdev;
 	u8 __iomem *io_mem;
@@ -308,31 +310,47 @@ struct dm1105dvb {
 	spinlock_t lock;
 };
 
-#define dm_io_mem(reg)	((unsigned long)(&dm1105dvb->io_mem[reg]))
+#define dm_io_mem(reg)	((unsigned long)(&dev->io_mem[reg]))
+
+#define dm_readb(reg)		inb(dm_io_mem(reg))
+#define dm_writeb(reg, value)	outb((value), (dm_io_mem(reg)))
+
+#define dm_readw(reg)		inw(dm_io_mem(reg))
+#define dm_writew(reg, value)	outw((value), (dm_io_mem(reg)))
+
+#define dm_readl(reg)		inl(dm_io_mem(reg))
+#define dm_writel(reg, value)	outl((value), (dm_io_mem(reg)))
+
+#define dm_andorl(reg, mask, value) \
+	outl((inl(dm_io_mem(reg)) & ~(mask)) |\
+		((value) & (mask)), (dm_io_mem(reg)))
+
+#define dm_setl(reg, bit)	dm_andorl((reg), (bit), (bit))
+#define dm_clearl(reg, bit)	dm_andorl((reg), (bit), 0)
 
 static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap,
 			    struct i2c_msg *msgs, int num)
 {
-	struct dm1105dvb *dm1105dvb ;
+	struct dm1105_dev *dev ;
 
 	int addr, rc, i, j, k, len, byte, data;
 	u8 status;
 
-	dm1105dvb = i2c_adap->algo_data;
+	dev = i2c_adap->algo_data;
 	for (i = 0; i < num; i++) {
-		outb(0x00, dm_io_mem(DM1105_I2CCTR));
+		dm_writeb(DM1105_I2CCTR, 0x00);
 		if (msgs[i].flags & I2C_M_RD) {
 			/* read bytes */
 			addr  = msgs[i].addr << 1;
 			addr |= 1;
-			outb(addr, dm_io_mem(DM1105_I2CDAT));
+			dm_writeb(DM1105_I2CDAT, addr);
 			for (byte = 0; byte < msgs[i].len; byte++)
-				outb(0, dm_io_mem(DM1105_I2CDAT + byte + 1));
+				dm_writeb(DM1105_I2CDAT + byte + 1, 0);
 
-			outb(0x81 + msgs[i].len, dm_io_mem(DM1105_I2CCTR));
+			dm_writeb(DM1105_I2CCTR, 0x81 + msgs[i].len);
 			for (j = 0; j < 55; j++) {
 				mdelay(10);
-				status = inb(dm_io_mem(DM1105_I2CSTS));
+				status = dm_readb(DM1105_I2CSTS);
 				if ((status & 0xc0) == 0x40)
 					break;
 			}
@@ -340,56 +358,54 @@ static int dm1105_i2c_xfer(struct i2c_ad
 				return -1;
 
 			for (byte = 0; byte < msgs[i].len; byte++) {
-				rc = inb(dm_io_mem(DM1105_I2CDAT + byte + 1));
+				rc = dm_readb(DM1105_I2CDAT + byte + 1);
 				if (rc < 0)
 					goto err;
 				msgs[i].buf[byte] = rc;
 			}
-		} else {
-			if ((msgs[i].buf[0] == 0xf7) && (msgs[i].addr == 0x55)) {
-				/* prepaired for cx24116 firmware */
-				/* Write in small blocks */
-				len = msgs[i].len - 1;
-				k = 1;
-				do {
-					outb(msgs[i].addr << 1, dm_io_mem(DM1105_I2CDAT));
-					outb(0xf7, dm_io_mem(DM1105_I2CDAT + 1));
-					for (byte = 0; byte < (len > 48 ? 48 : len); byte++) {
-						data = msgs[i].buf[k+byte];
-						outb(data, dm_io_mem(DM1105_I2CDAT + byte + 2));
-					}
-					outb(0x82 + (len > 48 ? 48 : len), dm_io_mem(DM1105_I2CCTR));
-					for (j = 0; j < 25; j++) {
-						mdelay(10);
-						status = inb(dm_io_mem(DM1105_I2CSTS));
-						if ((status & 0xc0) == 0x40)
-							break;
-					}
-
-					if (j >= 25)
-						return -1;
-
-					k += 48;
-					len -= 48;
-				} while (len > 0);
-			} else {
-				/* write bytes */
-				outb(msgs[i].addr<<1, dm_io_mem(DM1105_I2CDAT));
-				for (byte = 0; byte < msgs[i].len; byte++) {
-					data = msgs[i].buf[byte];
-					outb(data, dm_io_mem(DM1105_I2CDAT + byte + 1));
+		} else if ((msgs[i].buf[0] == 0xf7) && (msgs[i].addr == 0x55)) {
+			/* prepaired for cx24116 firmware */
+			/* Write in small blocks */
+			len = msgs[i].len - 1;
+			k = 1;
+			do {
+				dm_writeb(DM1105_I2CDAT, msgs[i].addr << 1);
+				dm_writeb(DM1105_I2CDAT + 1, 0xf7);
+				for (byte = 0; byte < (len > 48 ? 48 : len); byte++) {
+					data = msgs[i].buf[k + byte];
+					dm_writeb(DM1105_I2CDAT + byte + 2, data);
 				}
-				outb(0x81 + msgs[i].len, dm_io_mem(DM1105_I2CCTR));
+				dm_writeb(DM1105_I2CCTR, 0x82 + (len > 48 ? 48 : len));
 				for (j = 0; j < 25; j++) {
 					mdelay(10);
-					status = inb(dm_io_mem(DM1105_I2CSTS));
+					status = dm_readb(DM1105_I2CSTS);
 					if ((status & 0xc0) == 0x40)
 						break;
 				}
 
 				if (j >= 25)
 					return -1;
+
+				k += 48;
+				len -= 48;
+			} while (len > 0);
+		} else {
+			/* write bytes */
+			dm_writeb(DM1105_I2CDAT, msgs[i].addr << 1);
+			for (byte = 0; byte < msgs[i].len; byte++) {
+				data = msgs[i].buf[byte];
+				dm_writeb(DM1105_I2CDAT + byte + 1, data);
 			}
+			dm_writeb(DM1105_I2CCTR, 0x81 + msgs[i].len);
+			for (j = 0; j < 25; j++) {
+				mdelay(10);
+				status = dm_readb(DM1105_I2CSTS);
+				if ((status & 0xc0) == 0x40)
+					break;
+			}
+
+			if (j >= 25)
+				return -1;
 		}
 	}
 	return num;
@@ -407,22 +423,22 @@ static struct i2c_algorithm dm1105_algo
 	.functionality = functionality,
 };
 
-static inline struct dm1105dvb *feed_to_dm1105dvb(struct dvb_demux_feed *feed)
+static inline struct dm1105_dev *feed_to_dm1105_dev(struct dvb_demux_feed *feed)
 {
-	return container_of(feed->demux, struct dm1105dvb, demux);
+	return container_of(feed->demux, struct dm1105_dev, demux);
 }
 
-static inline struct dm1105dvb *frontend_to_dm1105dvb(struct dvb_frontend *fe)
+static inline struct dm1105_dev *frontend_to_dm1105_dev(struct dvb_frontend *fe)
 {
-	return container_of(fe->dvb, struct dm1105dvb, dvb_adapter);
+	return container_of(fe->dvb, struct dm1105_dev, dvb_adapter);
 }
 
-static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+static int dm1105_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
 {
-	struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe);
+	struct dm1105_dev *dev = frontend_to_dm1105_dev(fe);
 	u32 lnb_mask, lnb_13v, lnb_18v, lnb_off;
 
-	switch (dm1105dvb->boardnr) {
+	switch (dev->boardnr) {
 	case DM1105_BOARD_AXESS_DM05:
 		lnb_mask = DM05_LNB_MASK;
 		lnb_off = DM05_LNB_OFF;
@@ -438,62 +454,67 @@ static int dm1105dvb_set_voltage(struct
 		lnb_18v = DM1105_LNB_18V;
 	}
 
-	outl(lnb_mask, dm_io_mem(DM1105_GPIOCTR));
+	dm_writel(DM1105_GPIOCTR, lnb_mask);
 	if (voltage == SEC_VOLTAGE_18)
-		outl(lnb_18v , dm_io_mem(DM1105_GPIOVAL));
+		dm_writel(DM1105_GPIOVAL, lnb_18v);
 	else if (voltage == SEC_VOLTAGE_13)
-		outl(lnb_13v, dm_io_mem(DM1105_GPIOVAL));
+		dm_writel(DM1105_GPIOVAL, lnb_13v);
 	else
-		outl(lnb_off, dm_io_mem(DM1105_GPIOVAL));
+		dm_writel(DM1105_GPIOVAL, lnb_off);
 
 	return 0;
 }
 
-static void dm1105dvb_set_dma_addr(struct dm1105dvb *dm1105dvb)
+static void dm1105_set_dma_addr(struct dm1105_dev *dev)
 {
-	outl(cpu_to_le32(dm1105dvb->dma_addr), dm_io_mem(DM1105_STADR));
+	dm_writel(DM1105_STADR, cpu_to_le32(dev->dma_addr));
 }
 
-static int __devinit dm1105dvb_dma_map(struct dm1105dvb *dm1105dvb)
+static int __devinit dm1105_dma_map(struct dm1105_dev *dev)
 {
-	dm1105dvb->ts_buf = pci_alloc_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, &dm1105dvb->dma_addr);
+	dev->ts_buf = pci_alloc_consistent(dev->pdev,
+					6 * DM1105_DMA_BYTES,
+					&dev->dma_addr);
 
-	return !dm1105dvb->ts_buf;
+	return !dev->ts_buf;
 }
 
-static void dm1105dvb_dma_unmap(struct dm1105dvb *dm1105dvb)
+static void dm1105_dma_unmap(struct dm1105_dev *dev)
 {
-	pci_free_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, dm1105dvb->ts_buf, dm1105dvb->dma_addr);
+	pci_free_consistent(dev->pdev,
+			6 * DM1105_DMA_BYTES,
+			dev->ts_buf,
+			dev->dma_addr);
 }
 
-static void dm1105dvb_enable_irqs(struct dm1105dvb *dm1105dvb)
+static void dm1105_enable_irqs(struct dm1105_dev *dev)
 {
-	outb(INTMAK_ALLMASK, dm_io_mem(DM1105_INTMAK));
-	outb(1, dm_io_mem(DM1105_CR));
+	dm_writeb(DM1105_INTMAK, INTMAK_ALLMASK);
+	dm_writeb(DM1105_CR, 1);
 }
 
-static void dm1105dvb_disable_irqs(struct dm1105dvb *dm1105dvb)
+static void dm1105_disable_irqs(struct dm1105_dev *dev)
 {
-	outb(INTMAK_IRM, dm_io_mem(DM1105_INTMAK));
-	outb(0, dm_io_mem(DM1105_CR));
+	dm_writeb(DM1105_INTMAK, INTMAK_IRM);
+	dm_writeb(DM1105_CR, 0);
 }
 
-static int dm1105dvb_start_feed(struct dvb_demux_feed *f)
+static int dm1105_start_feed(struct dvb_demux_feed *f)
 {
-	struct dm1105dvb *dm1105dvb = feed_to_dm1105dvb(f);
+	struct dm1105_dev *dev = feed_to_dm1105_dev(f);
 
-	if (dm1105dvb->full_ts_users++ == 0)
-		dm1105dvb_enable_irqs(dm1105dvb);
+	if (dev->full_ts_users++ == 0)
+		dm1105_enable_irqs(dev);
 
 	return 0;
 }
 
-static int dm1105dvb_stop_feed(struct dvb_demux_feed *f)
+static int dm1105_stop_feed(struct dvb_demux_feed *f)
 {
-	struct dm1105dvb *dm1105dvb = feed_to_dm1105dvb(f);
+	struct dm1105_dev *dev = feed_to_dm1105_dev(f);
 
-	if (--dm1105dvb->full_ts_users == 0)
-		dm1105dvb_disable_irqs(dm1105dvb);
+	if (--dev->full_ts_users == 0)
+		dm1105_disable_irqs(dev);
 
 	return 0;
 }
@@ -517,68 +538,64 @@ static void dm1105_emit_key(struct work_
 /* work handler */
 static void dm1105_dmx_buffer(struct work_struct *work)
 {
-	struct dm1105dvb *dm1105dvb =
-				container_of(work, struct dm1105dvb, work);
+	struct dm1105_dev *dev = container_of(work, struct dm1105_dev, work);
 	unsigned int nbpackets;
-	u32 oldwrp = dm1105dvb->wrp;
-	u32 nextwrp = dm1105dvb->nextwrp;
+	u32 oldwrp = dev->wrp;
+	u32 nextwrp = dev->nextwrp;
 
-	if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) &&
-			(dm1105dvb->ts_buf[oldwrp + 188] == 0x47) &&
-			(dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) {
-		dm1105dvb->PacketErrorCount++;
+	if (!((dev->ts_buf[oldwrp] == 0x47) &&
+			(dev->ts_buf[oldwrp + 188] == 0x47) &&
+			(dev->ts_buf[oldwrp + 188 * 2] == 0x47))) {
+		dev->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;
+		if ((dev->PacketErrorCount >= 2) &&
+				(dev->dmarst == 0)) {
+			dm_writeb(DM1105_RST, 1);
+			dev->wrp = 0;
+			dev->PacketErrorCount = 0;
+			dev->dmarst = 0;
 			return;
 		}
 	}
 
 	if (nextwrp < oldwrp) {
-		memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size,
-						dm1105dvb->ts_buf, nextwrp);
-		nbpackets = ((dm1105dvb->buffer_size - oldwrp) + nextwrp) / 188;
+		memcpy(dev->ts_buf + dev->buffer_size, dev->ts_buf, nextwrp);
+		nbpackets = ((dev->buffer_size - oldwrp) + nextwrp) / 188;
 	} else
 		nbpackets = (nextwrp - oldwrp) / 188;
 
-	dm1105dvb->wrp = nextwrp;
-	dvb_dmx_swfilter_packets(&dm1105dvb->demux,
-					&dm1105dvb->ts_buf[oldwrp], nbpackets);
+	dev->wrp = nextwrp;
+	dvb_dmx_swfilter_packets(&dev->demux, &dev->ts_buf[oldwrp], nbpackets);
 }
 
-static irqreturn_t dm1105dvb_irq(int irq, void *dev_id)
+static irqreturn_t dm1105_irq(int irq, void *dev_id)
 {
-	struct dm1105dvb *dm1105dvb = dev_id;
+	struct dm1105_dev *dev = dev_id;
 
 	/* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */
-	unsigned int intsts = inb(dm_io_mem(DM1105_INTSTS));
-	outb(intsts, dm_io_mem(DM1105_INTSTS));
+	unsigned int intsts = dm_readb(DM1105_INTSTS);
+	dm_writeb(DM1105_INTSTS, intsts);
 
 	switch (intsts) {
 	case INTSTS_TSIRQ:
 	case (INTSTS_TSIRQ | INTSTS_IR):
-		dm1105dvb->nextwrp = inl(dm_io_mem(DM1105_WRP)) -
-					inl(dm_io_mem(DM1105_STADR));
-		queue_work(dm1105dvb->wq, &dm1105dvb->work);
+		dev->nextwrp = dm_readl(DM1105_WRP) - dm_readl(DM1105_STADR);
+		queue_work(dev->wq, &dev->work);
 		break;
 	case INTSTS_IR:
-		dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE));
-		schedule_work(&dm1105dvb->ir.work);
+		dev->ir.ir_command = dm_readl(DM1105_IRCODE);
+		schedule_work(&dev->ir.work);
 		break;
 	}
 
 	return IRQ_HANDLED;
 }
 
-int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
+int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
 {
 	struct input_dev *input_dev;
 	struct ir_scancode_table *ir_codes = &ir_codes_dm1105_nec_table;
-	int ir_type = IR_TYPE_OTHER;
+	u64 ir_type = IR_TYPE_OTHER;
 	int err = -ENOMEM;
 
 	input_dev = input_allocate_device();
@@ -611,51 +628,51 @@ int __devinit dm1105_ir_init(struct dm11
 
 	INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
 
-	err = ir_input_register(input_dev, ir_codes);
+	err = ir_input_register(input_dev, ir_codes, NULL);
 
 	return err;
 }
 
-void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105)
+void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105)
 {
 	ir_input_unregister(dm1105->ir.input_dev);
 }
 
-static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb)
+static int __devinit dm1105_hw_init(struct dm1105_dev *dev)
 {
-	dm1105dvb_disable_irqs(dm1105dvb);
+	dm1105_disable_irqs(dev);
 
-	outb(0, dm_io_mem(DM1105_HOST_CTR));
+	dm_writeb(DM1105_HOST_CTR, 0);
 
 	/*DATALEN 188,*/
-	outb(188, dm_io_mem(DM1105_DTALENTH));
+	dm_writeb(DM1105_DTALENTH, 188);
 	/*TS_STRT TS_VALP MSBFIRST TS_MODE ALPAS TSPES*/
-	outw(0xc10a, dm_io_mem(DM1105_TSCTR));
+	dm_writew(DM1105_TSCTR, 0xc10a);
 
 	/* map DMA and set address */
-	dm1105dvb_dma_map(dm1105dvb);
-	dm1105dvb_set_dma_addr(dm1105dvb);
+	dm1105_dma_map(dev);
+	dm1105_set_dma_addr(dev);
 	/* big buffer */
-	outl(5*DM1105_DMA_BYTES, dm_io_mem(DM1105_RLEN));
-	outb(47, dm_io_mem(DM1105_INTCNT));
+	dm_writel(DM1105_RLEN, 5 * DM1105_DMA_BYTES);
+	dm_writeb(DM1105_INTCNT, 47);
 
 	/* IR NEC mode enable */
-	outb((DM1105_IR_EN | DM1105_SYS_CHK), dm_io_mem(DM1105_IRCTR));
-	outb(0, dm_io_mem(DM1105_IRMODE));
-	outw(0, dm_io_mem(DM1105_SYSTEMCODE));
+	dm_writeb(DM1105_IRCTR, (DM1105_IR_EN | DM1105_SYS_CHK));
+	dm_writeb(DM1105_IRMODE, 0);
+	dm_writew(DM1105_SYSTEMCODE, 0);
 
 	return 0;
 }
 
-static void dm1105dvb_hw_exit(struct dm1105dvb *dm1105dvb)
+static void dm1105_hw_exit(struct dm1105_dev *dev)
 {
-	dm1105dvb_disable_irqs(dm1105dvb);
+	dm1105_disable_irqs(dev);
 
 	/* IR disable */
-	outb(0, dm_io_mem(DM1105_IRCTR));
-	outb(INTMAK_NONEMASK, dm_io_mem(DM1105_INTMAK));
+	dm_writeb(DM1105_IRCTR, 0);
+	dm_writeb(DM1105_INTMAK, INTMAK_NONEMASK);
 
-	dm1105dvb_dma_unmap(dm1105dvb);
+	dm1105_dma_unmap(dev);
 }
 
 static struct stv0299_config sharp_z0194a_config = {
@@ -685,70 +702,79 @@ static struct cx24116_config serit_sp263
 	.demod_address = 0x55,
 };
 
-static int __devinit frontend_init(struct dm1105dvb *dm1105dvb)
+static struct ds3000_config dvbworld_ds3000_config = {
+	.demod_address = 0x68,
+};
+
+static int __devinit frontend_init(struct dm1105_dev *dev)
 {
 	int ret;
 
-	switch (dm1105dvb->boardnr) {
+	switch (dev->boardnr) {
 	case DM1105_BOARD_DVBWORLD_2004:
-		dm1105dvb->fe = dvb_attach(
+		dev->fe = dvb_attach(
 			cx24116_attach, &serit_sp2633_config,
-			&dm1105dvb->i2c_adap);
-		if (dm1105dvb->fe)
-			dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage;
+			&dev->i2c_adap);
+		if (dev->fe) {
+			dev->fe->ops.set_voltage = dm1105_set_voltage;
+			break;
+		}
+
+		dev->fe = dvb_attach(
+			ds3000_attach, &dvbworld_ds3000_config,
+			&dev->i2c_adap);
+		if (dev->fe)
+			dev->fe->ops.set_voltage = dm1105_set_voltage;
 
 		break;
 	case DM1105_BOARD_DVBWORLD_2002:
 	case DM1105_BOARD_AXESS_DM05:
 	default:
-		dm1105dvb->fe = dvb_attach(
+		dev->fe = dvb_attach(
 			stv0299_attach, &sharp_z0194a_config,
-			&dm1105dvb->i2c_adap);
-		if (dm1105dvb->fe) {
-			dm1105dvb->fe->ops.set_voltage =
-							dm1105dvb_set_voltage;
-			dvb_attach(dvb_pll_attach, dm1105dvb->fe, 0x60,
-					&dm1105dvb->i2c_adap, DVB_PLL_OPERA1);
+			&dev->i2c_adap);
+		if (dev->fe) {
+			dev->fe->ops.set_voltage = dm1105_set_voltage;
+			dvb_attach(dvb_pll_attach, dev->fe, 0x60,
+					&dev->i2c_adap, DVB_PLL_OPERA1);
 			break;
 		}
 
-		dm1105dvb->fe = dvb_attach(
+		dev->fe = dvb_attach(
 			stv0288_attach, &earda_config,
-			&dm1105dvb->i2c_adap);
-		if (dm1105dvb->fe) {
-			dm1105dvb->fe->ops.set_voltage =
-						dm1105dvb_set_voltage;
-			dvb_attach(stb6000_attach, dm1105dvb->fe, 0x61,
-					&dm1105dvb->i2c_adap);
+			&dev->i2c_adap);
+		if (dev->fe) {
+			dev->fe->ops.set_voltage = dm1105_set_voltage;
+			dvb_attach(stb6000_attach, dev->fe, 0x61,
+					&dev->i2c_adap);
 			break;
 		}
 
-		dm1105dvb->fe = dvb_attach(
+		dev->fe = dvb_attach(
 			si21xx_attach, &serit_config,
-			&dm1105dvb->i2c_adap);
-		if (dm1105dvb->fe)
-			dm1105dvb->fe->ops.set_voltage =
-						dm1105dvb_set_voltage;
+			&dev->i2c_adap);
+		if (dev->fe)
+			dev->fe->ops.set_voltage = dm1105_set_voltage;
 
 	}
 
-	if (!dm1105dvb->fe) {
-		dev_err(&dm1105dvb->pdev->dev, "could not attach frontend\n");
+	if (!dev->fe) {
+		dev_err(&dev->pdev->dev, "could not attach frontend\n");
 		return -ENODEV;
 	}
 
-	ret = dvb_register_frontend(&dm1105dvb->dvb_adapter, dm1105dvb->fe);
+	ret = dvb_register_frontend(&dev->dvb_adapter, dev->fe);
 	if (ret < 0) {
-		if (dm1105dvb->fe->ops.release)
-			dm1105dvb->fe->ops.release(dm1105dvb->fe);
-		dm1105dvb->fe = NULL;
+		if (dev->fe->ops.release)
+			dev->fe->ops.release(dev->fe);
+		dev->fe = NULL;
 		return ret;
 	}
 
 	return 0;
 }
 
-static void __devinit dm1105dvb_read_mac(struct dm1105dvb *dm1105dvb, u8 *mac)
+static void __devinit dm1105_read_mac(struct dm1105_dev *dev, u8 *mac)
 {
 	static u8 command[1] = { 0x28 };
 
@@ -766,47 +792,47 @@ static void __devinit dm1105dvb_read_mac
 		},
 	};
 
-	dm1105_i2c_xfer(&dm1105dvb->i2c_adap, msg , 2);
-	dev_info(&dm1105dvb->pdev->dev, "MAC %pM\n", mac);
+	dm1105_i2c_xfer(&dev->i2c_adap, msg , 2);
+	dev_info(&dev->pdev->dev, "MAC %pM\n", mac);
 }
 
 static int __devinit dm1105_probe(struct pci_dev *pdev,
 				  const struct pci_device_id *ent)
 {
-	struct dm1105dvb *dm1105dvb;
+	struct dm1105_dev *dev;
 	struct dvb_adapter *dvb_adapter;
 	struct dvb_demux *dvbdemux;
 	struct dmx_demux *dmx;
 	int ret = -ENOMEM;
 	int i;
 
-	dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL);
-	if (!dm1105dvb)
+	dev = kzalloc(sizeof(struct dm1105_dev), GFP_KERNEL);
+	if (!dev)
 		return -ENOMEM;
 
 	/* board config */
-	dm1105dvb->nr = dm1105_devcount;
-	dm1105dvb->boardnr = UNSET;
-	if (card[dm1105dvb->nr] < ARRAY_SIZE(dm1105_boards))
-		dm1105dvb->boardnr = card[dm1105dvb->nr];
-	for (i = 0; UNSET == dm1105dvb->boardnr &&
+	dev->nr = dm1105_devcount;
+	dev->boardnr = UNSET;
+	if (card[dev->nr] < ARRAY_SIZE(dm1105_boards))
+		dev->boardnr = card[dev->nr];
+	for (i = 0; UNSET == dev->boardnr &&
 				i < ARRAY_SIZE(dm1105_subids); i++)
 		if (pdev->subsystem_vendor ==
 			dm1105_subids[i].subvendor &&
 				pdev->subsystem_device ==
 					dm1105_subids[i].subdevice)
-			dm1105dvb->boardnr = dm1105_subids[i].card;
+			dev->boardnr = dm1105_subids[i].card;
 
-	if (UNSET == dm1105dvb->boardnr) {
-		dm1105dvb->boardnr = DM1105_BOARD_UNKNOWN;
+	if (UNSET == dev->boardnr) {
+		dev->boardnr = DM1105_BOARD_UNKNOWN;
 		dm1105_card_list(pdev);
 	}
 
 	dm1105_devcount++;
-	dm1105dvb->pdev = pdev;
-	dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES;
-	dm1105dvb->PacketErrorCount = 0;
-	dm1105dvb->dmarst = 0;
+	dev->pdev = pdev;
+	dev->buffer_size = 5 * DM1105_DMA_BYTES;
+	dev->PacketErrorCount = 0;
+	dev->dmarst = 0;
 
 	ret = pci_enable_device(pdev);
 	if (ret < 0)
@@ -822,47 +848,47 @@ static int __devinit dm1105_probe(struct
 	if (ret < 0)
 		goto err_pci_disable_device;
 
-	dm1105dvb->io_mem = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
-	if (!dm1105dvb->io_mem) {
+	dev->io_mem = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
+	if (!dev->io_mem) {
 		ret = -EIO;
 		goto err_pci_release_regions;
 	}
 
-	spin_lock_init(&dm1105dvb->lock);
-	pci_set_drvdata(pdev, dm1105dvb);
+	spin_lock_init(&dev->lock);
+	pci_set_drvdata(pdev, dev);
 
-	ret = dm1105dvb_hw_init(dm1105dvb);
+	ret = dm1105_hw_init(dev);
 	if (ret < 0)
 		goto err_pci_iounmap;
 
 	/* i2c */
-	i2c_set_adapdata(&dm1105dvb->i2c_adap, dm1105dvb);
-	strcpy(dm1105dvb->i2c_adap.name, DRIVER_NAME);
-	dm1105dvb->i2c_adap.owner = THIS_MODULE;
-	dm1105dvb->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
-	dm1105dvb->i2c_adap.dev.parent = &pdev->dev;
-	dm1105dvb->i2c_adap.algo = &dm1105_algo;
-	dm1105dvb->i2c_adap.algo_data = dm1105dvb;
-	ret = i2c_add_adapter(&dm1105dvb->i2c_adap);
+	i2c_set_adapdata(&dev->i2c_adap, dev);
+	strcpy(dev->i2c_adap.name, DRIVER_NAME);
+	dev->i2c_adap.owner = THIS_MODULE;
+	dev->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
+	dev->i2c_adap.dev.parent = &pdev->dev;
+	dev->i2c_adap.algo = &dm1105_algo;
+	dev->i2c_adap.algo_data = dev;
+	ret = i2c_add_adapter(&dev->i2c_adap);
 
 	if (ret < 0)
-		goto err_dm1105dvb_hw_exit;
+		goto err_dm1105_hw_exit;
 
 	/* dvb */
-	ret = dvb_register_adapter(&dm1105dvb->dvb_adapter, DRIVER_NAME,
+	ret = dvb_register_adapter(&dev->dvb_adapter, DRIVER_NAME,
 					THIS_MODULE, &pdev->dev, adapter_nr);
 	if (ret < 0)
 		goto err_i2c_del_adapter;
 
-	dvb_adapter = &dm1105dvb->dvb_adapter;
+	dvb_adapter = &dev->dvb_adapter;
 
-	dm1105dvb_read_mac(dm1105dvb, dvb_adapter->proposed_mac);
+	dm1105_read_mac(dev, dvb_adapter->proposed_mac);
 
-	dvbdemux = &dm1105dvb->demux;
+	dvbdemux = &dev->demux;
 	dvbdemux->filternum = 256;
 	dvbdemux->feednum = 256;
-	dvbdemux->start_feed = dm1105dvb_start_feed;
-	dvbdemux->stop_feed = dm1105dvb_stop_feed;
+	dvbdemux->start_feed = dm1105_start_feed;
+	dvbdemux->stop_feed = dm1105_stop_feed;
 	dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
 			DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
 	ret = dvb_dmx_init(dvbdemux);
@@ -870,113 +896,113 @@ static int __devinit dm1105_probe(struct
 		goto err_dvb_unregister_adapter;
 
 	dmx = &dvbdemux->dmx;
-	dm1105dvb->dmxdev.filternum = 256;
-	dm1105dvb->dmxdev.demux = dmx;
-	dm1105dvb->dmxdev.capabilities = 0;
+	dev->dmxdev.filternum = 256;
+	dev->dmxdev.demux = dmx;
+	dev->dmxdev.capabilities = 0;
 
-	ret = dvb_dmxdev_init(&dm1105dvb->dmxdev, dvb_adapter);
+	ret = dvb_dmxdev_init(&dev->dmxdev, dvb_adapter);
 	if (ret < 0)
 		goto err_dvb_dmx_release;
 
-	dm1105dvb->hw_frontend.source = DMX_FRONTEND_0;
+	dev->hw_frontend.source = DMX_FRONTEND_0;
 
-	ret = dmx->add_frontend(dmx, &dm1105dvb->hw_frontend);
+	ret = dmx->add_frontend(dmx, &dev->hw_frontend);
 	if (ret < 0)
 		goto err_dvb_dmxdev_release;
 
-	dm1105dvb->mem_frontend.source = DMX_MEMORY_FE;
+	dev->mem_frontend.source = DMX_MEMORY_FE;
 
-	ret = dmx->add_frontend(dmx, &dm1105dvb->mem_frontend);
+	ret = dmx->add_frontend(dmx, &dev->mem_frontend);
 	if (ret < 0)
 		goto err_remove_hw_frontend;
 
-	ret = dmx->connect_frontend(dmx, &dm1105dvb->hw_frontend);
+	ret = dmx->connect_frontend(dmx, &dev->hw_frontend);
 	if (ret < 0)
 		goto err_remove_mem_frontend;
 
-	ret = frontend_init(dm1105dvb);
+	ret = frontend_init(dev);
 	if (ret < 0)
 		goto err_disconnect_frontend;
 
-	dvb_net_init(dvb_adapter, &dm1105dvb->dvbnet, dmx);
-	dm1105_ir_init(dm1105dvb);
+	dvb_net_init(dvb_adapter, &dev->dvbnet, dmx);
+	dm1105_ir_init(dev);
 
-	INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer);
-	sprintf(dm1105dvb->wqn, "%s/%d", dvb_adapter->name, dvb_adapter->num);
-	dm1105dvb->wq = create_singlethread_workqueue(dm1105dvb->wqn);
-	if (!dm1105dvb->wq)
+	INIT_WORK(&dev->work, dm1105_dmx_buffer);
+	sprintf(dev->wqn, "%s/%d", dvb_adapter->name, dvb_adapter->num);
+	dev->wq = create_singlethread_workqueue(dev->wqn);
+	if (!dev->wq)
 		goto err_dvb_net;
 
-	ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED,
-						DRIVER_NAME, dm1105dvb);
+	ret = request_irq(pdev->irq, dm1105_irq, IRQF_SHARED,
+						DRIVER_NAME, dev);
 	if (ret < 0)
 		goto err_workqueue;
 
 	return 0;
 
 err_workqueue:
-	destroy_workqueue(dm1105dvb->wq);
+	destroy_workqueue(dev->wq);
 err_dvb_net:
-	dvb_net_release(&dm1105dvb->dvbnet);
+	dvb_net_release(&dev->dvbnet);
 err_disconnect_frontend:
 	dmx->disconnect_frontend(dmx);
 err_remove_mem_frontend:
-	dmx->remove_frontend(dmx, &dm1105dvb->mem_frontend);
+	dmx->remove_frontend(dmx, &dev->mem_frontend);
 err_remove_hw_frontend:
-	dmx->remove_frontend(dmx, &dm1105dvb->hw_frontend);
+	dmx->remove_frontend(dmx, &dev->hw_frontend);
 err_dvb_dmxdev_release:
-	dvb_dmxdev_release(&dm1105dvb->dmxdev);
+	dvb_dmxdev_release(&dev->dmxdev);
 err_dvb_dmx_release:
 	dvb_dmx_release(dvbdemux);
 err_dvb_unregister_adapter:
 	dvb_unregister_adapter(dvb_adapter);
 err_i2c_del_adapter:
-	i2c_del_adapter(&dm1105dvb->i2c_adap);
-err_dm1105dvb_hw_exit:
-	dm1105dvb_hw_exit(dm1105dvb);
+	i2c_del_adapter(&dev->i2c_adap);
+err_dm1105_hw_exit:
+	dm1105_hw_exit(dev);
 err_pci_iounmap:
-	pci_iounmap(pdev, dm1105dvb->io_mem);
+	pci_iounmap(pdev, dev->io_mem);
 err_pci_release_regions:
 	pci_release_regions(pdev);
 err_pci_disable_device:
 	pci_disable_device(pdev);
 err_kfree:
 	pci_set_drvdata(pdev, NULL);
-	kfree(dm1105dvb);
+	kfree(dev);
 	return ret;
 }
 
 static void __devexit dm1105_remove(struct pci_dev *pdev)
 {
-	struct dm1105dvb *dm1105dvb = pci_get_drvdata(pdev);
-	struct dvb_adapter *dvb_adapter = &dm1105dvb->dvb_adapter;
-	struct dvb_demux *dvbdemux = &dm1105dvb->demux;
+	struct dm1105_dev *dev = pci_get_drvdata(pdev);
+	struct dvb_adapter *dvb_adapter = &dev->dvb_adapter;
+	struct dvb_demux *dvbdemux = &dev->demux;
 	struct dmx_demux *dmx = &dvbdemux->dmx;
 
-	dm1105_ir_exit(dm1105dvb);
+	dm1105_ir_exit(dev);
 	dmx->close(dmx);
-	dvb_net_release(&dm1105dvb->dvbnet);
-	if (dm1105dvb->fe)
-		dvb_unregister_frontend(dm1105dvb->fe);
+	dvb_net_release(&dev->dvbnet);
+	if (dev->fe)
+		dvb_unregister_frontend(dev->fe);
 
 	dmx->disconnect_frontend(dmx);
-	dmx->remove_frontend(dmx, &dm1105dvb->mem_frontend);
-	dmx->remove_frontend(dmx, &dm1105dvb->hw_frontend);
-	dvb_dmxdev_release(&dm1105dvb->dmxdev);
+	dmx->remove_frontend(dmx, &dev->mem_frontend);
+	dmx->remove_frontend(dmx, &dev->hw_frontend);
+	dvb_dmxdev_release(&dev->dmxdev);
 	dvb_dmx_release(dvbdemux);
 	dvb_unregister_adapter(dvb_adapter);
-	if (&dm1105dvb->i2c_adap)
-		i2c_del_adapter(&dm1105dvb->i2c_adap);
+	if (&dev->i2c_adap)
+		i2c_del_adapter(&dev->i2c_adap);
 
-	dm1105dvb_hw_exit(dm1105dvb);
+	dm1105_hw_exit(dev);
 	synchronize_irq(pdev->irq);
-	free_irq(pdev->irq, dm1105dvb);
-	pci_iounmap(pdev, dm1105dvb->io_mem);
+	free_irq(pdev->irq, dev);
+	pci_iounmap(pdev, dev->io_mem);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
 	dm1105_devcount--;
-	kfree(dm1105dvb);
+	kfree(dev);
 }
 
 static struct pci_device_id dm1105_id_table[] __devinitdata = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dm1105/Kconfig linux-libre-2.6.34-gnu1/drivers/media/dvb/dm1105/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dm1105/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dm1105/Kconfig	2010-05-16 17:17:36.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 DVB_DS3000 if !DVB_FE_CUSTOMISE
 	select VIDEO_IR
 	help
 	  Support for cards based on the SDMC DM1105 PCI chip like
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dmxdev.h linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-core/dmxdev.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dmxdev.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-core/dmxdev.h	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <linux/dvb/dmx.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.c linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.c	2010-05-16 17:17:36.000000000 -0400
@@ -1199,8 +1199,6 @@ static int dtv_property_process_get(stru
 {
 	int r = 0;
 
-	dtv_property_dump(tvp);
-
 	/* Allow the frontend to validate incoming properties */
 	if (fe->ops.get_property)
 		r = fe->ops.get_property(fe, tvp);
@@ -1323,6 +1321,8 @@ static int dtv_property_process_get(stru
 		r = -1;
 	}
 
+	dtv_property_dump(tvp);
+
 	return r;
 }
 
@@ -1488,7 +1488,7 @@ static int dvb_frontend_ioctl(struct ino
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	int err = -EOPNOTSUPP;
 
-	dprintk ("%s\n", __func__);
+	dprintk("%s (%d)\n", __func__, _IOC_NR(cmd));
 
 	if (fepriv->exit)
 		return -ENODEV;
@@ -1536,8 +1536,7 @@ static int dvb_frontend_ioctl_properties
 		if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
 			return -EINVAL;
 
-		tvp = (struct dtv_property *) kmalloc(tvps->num *
-			sizeof(struct dtv_property), GFP_KERNEL);
+		tvp = kmalloc(tvps->num * sizeof(struct dtv_property), GFP_KERNEL);
 		if (!tvp) {
 			err = -ENOMEM;
 			goto out;
@@ -1569,8 +1568,7 @@ static int dvb_frontend_ioctl_properties
 		if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
 			return -EINVAL;
 
-		tvp = (struct dtv_property *) kmalloc(tvps->num *
-			sizeof(struct dtv_property), GFP_KERNEL);
+		tvp = kmalloc(tvps->num * sizeof(struct dtv_property), GFP_KERNEL);
 		if (!tvp) {
 			err = -ENOMEM;
 			goto out;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.h linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.h	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <linux/dvb/frontend.h>
 
@@ -214,14 +215,14 @@ struct dvb_tuner_ops {
 	int (*get_status)(struct dvb_frontend *fe, u32 *status);
 	int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength);
 
-	/** These are provided seperately from set_params in order to facilitate silicon
-	 * tuners which require sophisticated tuning loops, controlling each parameter seperately. */
+	/** These are provided separately from set_params in order to facilitate silicon
+	 * tuners which require sophisticated tuning loops, controlling each parameter separately. */
 	int (*set_frequency)(struct dvb_frontend *fe, u32 frequency);
 	int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
 
 	/*
-	 * These are provided seperately from set_params in order to facilitate silicon
-	 * tuners which require sophisticated tuning loops, controlling each parameter seperately.
+	 * These are provided separately from set_params in order to facilitate silicon
+	 * tuners which require sophisticated tuning loops, controlling each parameter separately.
 	 */
 	int (*set_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
 	int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_net.c linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-core/dvb_net.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_net.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-core/dvb_net.c	2010-05-16 17:17:36.000000000 -0400
@@ -504,6 +504,7 @@ static void dvb_net_ule( struct net_devi
 				       "bytes left in TS.  Resyncing.\n", ts_remain);
 				priv->ule_sndu_len = 0;
 				priv->need_pusi = 1;
+				ts += TS_SZ;
 				continue;
 			}
 
@@ -949,11 +950,8 @@ static int dvb_net_filter_sec_set(struct
 	(*secfilter)->filter_mask[10] = mac_mask[1];
 	(*secfilter)->filter_mask[11]=mac_mask[0];
 
-	dprintk("%s: filter mac=%02x %02x %02x %02x %02x %02x\n",
-	       dev->name, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-	dprintk("%s: filter mask=%02x %02x %02x %02x %02x %02x\n",
-	       dev->name, mac_mask[0], mac_mask[1], mac_mask[2],
-	       mac_mask[3], mac_mask[4], mac_mask[5]);
+	dprintk("%s: filter mac=%pM\n", dev->name, mac);
+	dprintk("%s: filter mask=%pM\n", dev->name, mac_mask);
 
 	return 0;
 }
@@ -1141,18 +1139,18 @@ static void wq_set_multicast_list (struc
 	} else if ((dev->flags & IFF_ALLMULTI)) {
 		dprintk("%s: allmulti mode\n", dev->name);
 		priv->rx_mode = RX_MODE_ALL_MULTI;
-	} else if (dev->mc_count) {
+	} else if (!netdev_mc_empty(dev)) {
 		int mci;
 		struct dev_mc_list *mc;
 
 		dprintk("%s: set_mc_list, %d entries\n",
-			dev->name, dev->mc_count);
+			dev->name, netdev_mc_count(dev));
 
 		priv->rx_mode = RX_MODE_MULTI;
 		priv->multi_num = 0;
 
 		for (mci = 0, mc=dev->mc_list;
-		     mci < dev->mc_count;
+		     mci < netdev_mc_count(dev);
 		     mc = mc->next, mci++) {
 			dvb_set_mc_filter(dev, mc);
 		}
@@ -1239,7 +1237,6 @@ static void dvb_net_setup(struct net_dev
 	dev->header_ops		= &dvb_header_ops;
 	dev->netdev_ops		= &dvb_netdev_ops;
 	dev->mtu		= 4096;
-	dev->mc_count           = 0;
 
 	dev->flags |= IFF_NOARP;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_ringbuffer.c linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_ringbuffer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-core/dvb_ringbuffer.c	2010-05-16 17:17:36.000000000 -0400
@@ -89,6 +89,7 @@ void dvb_ringbuffer_flush(struct dvb_rin
 	rbuf->pread = rbuf->pwrite;
 	rbuf->error = 0;
 }
+EXPORT_SYMBOL(dvb_ringbuffer_flush);
 
 void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/af9015.c linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/af9015.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/af9015.c	2013-05-03 12:03:58.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/af9015.c	2013-05-03 09:44:53.000000000 -0400
@@ -21,6 +21,9 @@
  *
  */
 
+#include <linux/hash.h>
+#include <linux/slab.h>
+
 #include "af9015.h"
 #include "af9013.h"
 #include "mt2060.h"
@@ -553,26 +556,45 @@ exit:
 	return ret;
 }
 
-/* dump eeprom */
-static int af9015_eeprom_dump(struct dvb_usb_device *d)
+/* hash (and dump) eeprom */
+static int af9015_eeprom_hash(struct usb_device *udev)
 {
-	u8 reg, val;
+	static const unsigned int eeprom_size = 256;
+	unsigned int reg;
+	int ret;
+	u8 val, *eeprom;
+	struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
 
-	for (reg = 0; ; reg++) {
-		if (reg % 16 == 0) {
-			if (reg)
-				deb_info(KERN_CONT "\n");
-			deb_info(KERN_DEBUG "%02x:", reg);
-		}
-		if (af9015_read_reg_i2c(d, AF9015_I2C_EEPROM, reg, &val) == 0)
-			deb_info(KERN_CONT " %02x", val);
-		else
-			deb_info(KERN_CONT " --");
-		if (reg == 0xff)
-			break;
+	eeprom = kmalloc(eeprom_size, GFP_KERNEL);
+	if (eeprom == NULL)
+		return -ENOMEM;
+
+	for (reg = 0; reg < eeprom_size; reg++) {
+		req.addr = reg;
+		ret = af9015_rw_udev(udev, &req);
+		if (ret)
+			goto free;
+		eeprom[reg] = val;
 	}
-	deb_info(KERN_CONT "\n");
-	return 0;
+
+	if (dvb_usb_af9015_debug & 0x01)
+		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, eeprom,
+				eeprom_size);
+
+	BUG_ON(eeprom_size % 4);
+
+	af9015_config.eeprom_sum = 0;
+	for (reg = 0; reg < eeprom_size / sizeof(u32); reg++) {
+		af9015_config.eeprom_sum *= GOLDEN_RATIO_PRIME_32;
+		af9015_config.eeprom_sum += le32_to_cpu(((u32 *)eeprom)[reg]);
+	}
+
+	deb_info("%s: eeprom sum=%.8x\n", __func__, af9015_config.eeprom_sum);
+
+	ret = 0;
+free:
+	kfree(eeprom);
+	return ret;
 }
 
 static int af9015_download_ir_table(struct dvb_usb_device *d)
@@ -711,12 +733,132 @@ error:
 	return ret;
 }
 
+struct af9015_setup {
+	unsigned int id;
+	struct dvb_usb_rc_key *rc_key_map;
+	unsigned int rc_key_map_size;
+	u8 *ir_table;
+	unsigned int ir_table_size;
+};
+
+static const struct af9015_setup *af9015_setup_match(unsigned int id,
+		const struct af9015_setup *table)
+{
+	for (; table->rc_key_map; table++)
+		if (table->id == id)
+			return table;
+	return NULL;
+}
+
+static const struct af9015_setup af9015_setup_modparam[] = {
+	{ AF9015_REMOTE_A_LINK_DTU_M,
+		af9015_rc_keys_a_link, ARRAY_SIZE(af9015_rc_keys_a_link),
+		af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) },
+	{ AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
+		af9015_rc_keys_msi, ARRAY_SIZE(af9015_rc_keys_msi),
+		af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) },
+	{ AF9015_REMOTE_MYGICTV_U718,
+		af9015_rc_keys_mygictv, ARRAY_SIZE(af9015_rc_keys_mygictv),
+		af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) },
+	{ AF9015_REMOTE_DIGITTRADE_DVB_T,
+		af9015_rc_keys_digittrade, ARRAY_SIZE(af9015_rc_keys_digittrade),
+		af9015_ir_table_digittrade, ARRAY_SIZE(af9015_ir_table_digittrade) },
+	{ AF9015_REMOTE_AVERMEDIA_KS,
+		af9015_rc_keys_avermedia, ARRAY_SIZE(af9015_rc_keys_avermedia),
+		af9015_ir_table_avermedia_ks, ARRAY_SIZE(af9015_ir_table_avermedia_ks) },
+	{ }
+};
+
+/* don't add new entries here anymore, use hashes instead */
+static const struct af9015_setup af9015_setup_usbids[] = {
+	{ USB_VID_LEADTEK,
+		af9015_rc_keys_leadtek, ARRAY_SIZE(af9015_rc_keys_leadtek),
+		af9015_ir_table_leadtek, ARRAY_SIZE(af9015_ir_table_leadtek) },
+	{ USB_VID_VISIONPLUS,
+		af9015_rc_keys_twinhan, ARRAY_SIZE(af9015_rc_keys_twinhan),
+		af9015_ir_table_twinhan, ARRAY_SIZE(af9015_ir_table_twinhan) },
+	{ USB_VID_KWORLD_2, /* TODO: use correct rc keys */
+		af9015_rc_keys_twinhan, ARRAY_SIZE(af9015_rc_keys_twinhan),
+		af9015_ir_table_kworld, ARRAY_SIZE(af9015_ir_table_kworld) },
+	{ USB_VID_AVERMEDIA,
+		af9015_rc_keys_avermedia, ARRAY_SIZE(af9015_rc_keys_avermedia),
+		af9015_ir_table_avermedia, ARRAY_SIZE(af9015_ir_table_avermedia) },
+	{ USB_VID_MSI_2,
+		af9015_rc_keys_msi_digivox_iii, ARRAY_SIZE(af9015_rc_keys_msi_digivox_iii),
+		af9015_ir_table_msi_digivox_iii, ARRAY_SIZE(af9015_ir_table_msi_digivox_iii) },
+	{ }
+};
+
+static const struct af9015_setup af9015_setup_hashes[] = {
+	{ 0xb8feb708,
+		af9015_rc_keys_msi, ARRAY_SIZE(af9015_rc_keys_msi),
+		af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) },
+	{ 0xa3703d00,
+		af9015_rc_keys_a_link, ARRAY_SIZE(af9015_rc_keys_a_link),
+		af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) },
+	{ 0x9b7dc64e,
+		af9015_rc_keys_mygictv, ARRAY_SIZE(af9015_rc_keys_mygictv),
+		af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) },
+	{ }
+};
+
+static void af9015_set_remote_config(struct usb_device *udev,
+		struct dvb_usb_device_properties *props)
+{
+	const struct af9015_setup *table = NULL;
+
+	if (dvb_usb_af9015_remote) {
+		/* load remote defined as module param */
+		table = af9015_setup_match(dvb_usb_af9015_remote,
+				af9015_setup_modparam);
+	} else {
+		u16 vendor = le16_to_cpu(udev->descriptor.idVendor);
+
+		table = af9015_setup_match(af9015_config.eeprom_sum,
+				af9015_setup_hashes);
+
+		if (!table && vendor == USB_VID_AFATECH) {
+			/* Check USB manufacturer and product strings and try
+			   to determine correct remote in case of chip vendor
+			   reference IDs are used.
+			   DO NOT ADD ANYTHING NEW HERE. Use hashes instead.
+			 */
+			char manufacturer[10];
+			memset(manufacturer, 0, sizeof(manufacturer));
+			usb_string(udev, udev->descriptor.iManufacturer,
+				manufacturer, sizeof(manufacturer));
+			if (!strcmp("MSI", manufacturer)) {
+				/* iManufacturer 1 MSI
+				   iProduct      2 MSI K-VOX */
+				table = af9015_setup_match(
+					AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
+					af9015_setup_modparam);
+			} else if (udev->descriptor.idProduct ==
+				cpu_to_le16(USB_PID_TREKSTOR_DVBT)) {
+				table = &(const struct af9015_setup){ 0,
+					af9015_rc_keys_trekstor,
+					ARRAY_SIZE(af9015_rc_keys_trekstor),
+					af9015_ir_table_trekstor,
+					ARRAY_SIZE(af9015_ir_table_trekstor)
+				};
+			}
+		} else if (!table)
+			table = af9015_setup_match(vendor, af9015_setup_usbids);
+	}
+
+	if (table) {
+		props->rc_key_map = table->rc_key_map;
+		props->rc_key_map_size = table->rc_key_map_size;
+		af9015_config.ir_table = table->ir_table;
+		af9015_config.ir_table_size = table->ir_table_size;
+	}
+}
+
 static int af9015_read_config(struct usb_device *udev)
 {
 	int ret;
 	u8 val, i, offset = 0;
 	struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
-	char manufacturer[10];
 
 	/* IR remote controller */
 	req.addr = AF9015_EEPROM_IR_MODE;
@@ -728,158 +870,18 @@ static int af9015_read_config(struct usb
 	}
 	if (ret)
 		goto error;
+
+	ret = af9015_eeprom_hash(udev);
+	if (ret)
+		goto error;
+
 	deb_info("%s: IR mode:%d\n", __func__, val);
 	for (i = 0; i < af9015_properties_count; i++) {
 		if (val == AF9015_IR_MODE_DISABLED) {
 			af9015_properties[i].rc_key_map = NULL;
 			af9015_properties[i].rc_key_map_size  = 0;
-		} else if (dvb_usb_af9015_remote) {
-			/* load remote defined as module param */
-			switch (dvb_usb_af9015_remote) {
-			case AF9015_REMOTE_A_LINK_DTU_M:
-				af9015_properties[i].rc_key_map =
-				  af9015_rc_keys_a_link;
-				af9015_properties[i].rc_key_map_size =
-				  ARRAY_SIZE(af9015_rc_keys_a_link);
-				af9015_config.ir_table = af9015_ir_table_a_link;
-				af9015_config.ir_table_size =
-				  ARRAY_SIZE(af9015_ir_table_a_link);
-				break;
-			case AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3:
-				af9015_properties[i].rc_key_map =
-				  af9015_rc_keys_msi;
-				af9015_properties[i].rc_key_map_size =
-				  ARRAY_SIZE(af9015_rc_keys_msi);
-				af9015_config.ir_table = af9015_ir_table_msi;
-				af9015_config.ir_table_size =
-				  ARRAY_SIZE(af9015_ir_table_msi);
-				break;
-			case AF9015_REMOTE_MYGICTV_U718:
-				af9015_properties[i].rc_key_map =
-				  af9015_rc_keys_mygictv;
-				af9015_properties[i].rc_key_map_size =
-				  ARRAY_SIZE(af9015_rc_keys_mygictv);
-				af9015_config.ir_table =
-				  af9015_ir_table_mygictv;
-				af9015_config.ir_table_size =
-				  ARRAY_SIZE(af9015_ir_table_mygictv);
-				break;
-			case AF9015_REMOTE_DIGITTRADE_DVB_T:
-				af9015_properties[i].rc_key_map =
-				  af9015_rc_keys_digittrade;
-				af9015_properties[i].rc_key_map_size =
-				  ARRAY_SIZE(af9015_rc_keys_digittrade);
-				af9015_config.ir_table =
-				  af9015_ir_table_digittrade;
-				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)) {
-			case USB_VID_LEADTEK:
-				af9015_properties[i].rc_key_map =
-				  af9015_rc_keys_leadtek;
-				af9015_properties[i].rc_key_map_size =
-				  ARRAY_SIZE(af9015_rc_keys_leadtek);
-				af9015_config.ir_table =
-				  af9015_ir_table_leadtek;
-				af9015_config.ir_table_size =
-				  ARRAY_SIZE(af9015_ir_table_leadtek);
-				break;
-			case USB_VID_VISIONPLUS:
-				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 */
-				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_kworld;
-				af9015_config.ir_table_size =
-				  ARRAY_SIZE(af9015_ir_table_kworld);
-				break;
-			/* Check USB manufacturer and product strings and try
-			   to determine correct remote in case of chip vendor
-			   reference IDs are used. */
-			case USB_VID_AFATECH:
-				memset(manufacturer, 0, sizeof(manufacturer));
-				usb_string(udev, udev->descriptor.iManufacturer,
-					manufacturer, sizeof(manufacturer));
-				if (!strcmp("Geniatech", manufacturer)) {
-					/* iManufacturer 1 Geniatech
-					   iProduct      2 AF9015 */
-					af9015_properties[i].rc_key_map =
-					  af9015_rc_keys_mygictv;
-					af9015_properties[i].rc_key_map_size =
-					  ARRAY_SIZE(af9015_rc_keys_mygictv);
-					af9015_config.ir_table =
-					  af9015_ir_table_mygictv;
-					af9015_config.ir_table_size =
-					  ARRAY_SIZE(af9015_ir_table_mygictv);
-				} else if (!strcmp("MSI", manufacturer)) {
-					/* iManufacturer 1 MSI
-					   iProduct      2 MSI K-VOX */
-					af9015_properties[i].rc_key_map =
-					  af9015_rc_keys_msi;
-					af9015_properties[i].rc_key_map_size =
-					  ARRAY_SIZE(af9015_rc_keys_msi);
-					af9015_config.ir_table =
-					  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:
-				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;
-				af9015_config.ir_table_size =
-				  ARRAY_SIZE(af9015_ir_table_avermedia);
-				break;
-			case USB_VID_MSI_2:
-				af9015_properties[i].rc_key_map =
-				  af9015_rc_keys_msi_digivox_iii;
-				af9015_properties[i].rc_key_map_size =
-				  ARRAY_SIZE(af9015_rc_keys_msi_digivox_iii);
-				af9015_config.ir_table =
-				  af9015_ir_table_msi_digivox_iii;
-				af9015_config.ir_table_size =
-				  ARRAY_SIZE(af9015_ir_table_msi_digivox_iii);
-				break;
-			}
-		}
+		} else
+			af9015_set_remote_config(udev, &af9015_properties[i]);
 	}
 
 	/* TS mode - one or two receivers */
@@ -1001,6 +1003,9 @@ static int af9015_read_config(struct usb
 			af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
 			af9015_af9013_config[i].rf_spec_inv = 1;
 			break;
+		case AF9013_TUNER_TDA18218:
+			warn("tuner NXP TDA18218 not supported yet");
+			return -ENODEV;
 		default:
 			warn("tuner id:%d not supported, please report!", val);
 			return -ENODEV;
@@ -1125,11 +1130,6 @@ static int af9015_af9013_frontend_attach
 
 		deb_info("%s: init I2C\n", __func__);
 		ret = af9015_i2c_init(adap->dev);
-
-		/* dump eeprom (debug) */
-		ret = af9015_eeprom_dump(adap->dev);
-		if (ret)
-			return ret;
 	} else {
 		/* select I2C adapter */
 		i2c_adap = &state->i2c_adap;
@@ -1295,6 +1295,8 @@ static struct usb_device_id af9015_usb_t
 /* 25 */{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_KWORLD_399U_2)},
 	{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_KWORLD_PC160_T)},
 	{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_SVEON_STV20)},
+	{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_TINYTWIN_2)},
+	{USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV2000DS)},
 	{0},
 };
 MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1381,7 +1383,8 @@ static struct dvb_usb_device_properties
 			},
 			{
 				.name = "DigitalNow TinyTwin DVB-T Receiver",
-				.cold_ids = {&af9015_usb_table[5], NULL},
+				.cold_ids = {&af9015_usb_table[5],
+					     &af9015_usb_table[28], NULL},
 				.warm_ids = {NULL},
 			},
 			{
@@ -1566,7 +1569,7 @@ static struct dvb_usb_device_properties
 
 		.i2c_algo = &af9015_i2c_algo,
 
-		.num_device_descs = 6, /* max 9 */
+		.num_device_descs = 7, /* max 9 */
 		.devices = {
 			{
 				.name = "AverMedia AVerTV Volar GPS 805 (A805)",
@@ -1600,6 +1603,11 @@ static struct dvb_usb_device_properties
 				.cold_ids = {&af9015_usb_table[27], NULL},
 				.warm_ids = {NULL},
 			},
+			{
+				.name = "Leadtek WinFast DTV2000DS",
+				.cold_ids = {&af9015_usb_table[29], NULL},
+				.warm_ids = {NULL},
+			},
 		}
 	},
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/af9015.h linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/af9015.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/af9015.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/af9015.h	2010-05-16 17:17:36.000000000 -0400
@@ -107,6 +107,7 @@ struct af9015_config {
 	u16 mt2060_if1[2];
 	u16 firmware_size;
 	u16 firmware_checksum;
+	u32 eeprom_sum;
 	u8  *ir_table;
 	u16 ir_table_size;
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/az6027.c linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/az6027.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/az6027.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/az6027.c	2013-05-03 09:44:56.000000000 -0400
@@ -0,0 +1,1151 @@
+/* DVB USB compliant Linux driver for the AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)
+ * receiver.
+ *
+ * Copyright (C) 2009 Adams.Xu <adams.xu@azwave.com.cn>
+ *
+ *	This program is free software; 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.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "az6027.h"
+
+#include "stb0899_drv.h"
+#include "stb0899_reg.h"
+#include "stb0899_cfg.h"
+
+#include "stb6100.h"
+#include "stb6100_cfg.h"
+#include "dvb_ca_en50221.h"
+
+int dvb_usb_az6027_debug;
+module_param_named(debug, dvb_usb_az6027_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct az6027_device_state {
+	struct dvb_ca_en50221 ca;
+	struct mutex ca_mutex;
+	u8 power_state;
+};
+
+static const struct stb0899_s1_reg az6027_stb0899_s1_init_1[] = {
+
+	/* 0x0000000b, SYSREG */
+	{ STB0899_DEV_ID		, 0x30 },
+	{ STB0899_DISCNTRL1		, 0x32 },
+	{ STB0899_DISCNTRL2     	, 0x80 },
+	{ STB0899_DISRX_ST0     	, 0x04 },
+	{ STB0899_DISRX_ST1     	, 0x00 },
+	{ STB0899_DISPARITY     	, 0x00 },
+	{ STB0899_DISFIFO       	, 0x00 },
+	{ STB0899_DISSTATUS		, 0x20 },
+	{ STB0899_DISF22        	, 0x99 },
+	{ STB0899_DISF22RX      	, 0xa8 },
+	/* SYSREG ? */
+	{ STB0899_ACRPRESC      	, 0x11 },
+	{ STB0899_ACRDIV1       	, 0x0a },
+	{ STB0899_ACRDIV2       	, 0x05 },
+	{ STB0899_DACR1         	, 0x00 },
+	{ STB0899_DACR2         	, 0x00 },
+	{ STB0899_OUTCFG        	, 0x00 },
+	{ STB0899_MODECFG       	, 0x00 },
+	{ STB0899_IRQSTATUS_3		, 0xfe },
+	{ STB0899_IRQSTATUS_2		, 0x03 },
+	{ STB0899_IRQSTATUS_1		, 0x7c },
+	{ STB0899_IRQSTATUS_0		, 0xf4 },
+	{ STB0899_IRQMSK_3      	, 0xf3 },
+	{ STB0899_IRQMSK_2      	, 0xfc },
+	{ STB0899_IRQMSK_1      	, 0xff },
+	{ STB0899_IRQMSK_0		, 0xff },
+	{ STB0899_IRQCFG		, 0x00 },
+	{ STB0899_I2CCFG        	, 0x88 },
+	{ STB0899_I2CRPT        	, 0x58 },
+	{ STB0899_IOPVALUE5		, 0x00 },
+	{ STB0899_IOPVALUE4		, 0x33 },
+	{ STB0899_IOPVALUE3		, 0x6d },
+	{ STB0899_IOPVALUE2		, 0x90 },
+	{ STB0899_IOPVALUE1		, 0x60 },
+	{ STB0899_IOPVALUE0		, 0x00 },
+	{ STB0899_GPIO00CFG     	, 0x82 },
+	{ STB0899_GPIO01CFG     	, 0x82 },
+	{ STB0899_GPIO02CFG     	, 0x82 },
+	{ STB0899_GPIO03CFG     	, 0x82 },
+	{ STB0899_GPIO04CFG     	, 0x82 },
+	{ STB0899_GPIO05CFG     	, 0x82 },
+	{ STB0899_GPIO06CFG     	, 0x82 },
+	{ STB0899_GPIO07CFG     	, 0x82 },
+	{ STB0899_GPIO08CFG     	, 0x82 },
+	{ STB0899_GPIO09CFG     	, 0x82 },
+	{ STB0899_GPIO10CFG     	, 0x82 },
+	{ STB0899_GPIO11CFG     	, 0x82 },
+	{ STB0899_GPIO12CFG     	, 0x82 },
+	{ STB0899_GPIO13CFG     	, 0x82 },
+	{ STB0899_GPIO14CFG     	, 0x82 },
+	{ STB0899_GPIO15CFG     	, 0x82 },
+	{ STB0899_GPIO16CFG     	, 0x82 },
+	{ STB0899_GPIO17CFG     	, 0x82 },
+	{ STB0899_GPIO18CFG     	, 0x82 },
+	{ STB0899_GPIO19CFG     	, 0x82 },
+	{ STB0899_GPIO20CFG     	, 0x82 },
+	{ STB0899_SDATCFG       	, 0xb8 },
+	{ STB0899_SCLTCFG       	, 0xba },
+	{ STB0899_AGCRFCFG      	, 0x1c }, /* 0x11 */
+	{ STB0899_GPIO22        	, 0x82 }, /* AGCBB2CFG */
+	{ STB0899_GPIO21        	, 0x91 }, /* AGCBB1CFG */
+	{ STB0899_DIRCLKCFG     	, 0x82 },
+	{ STB0899_CLKOUT27CFG   	, 0x7e },
+	{ STB0899_STDBYCFG      	, 0x82 },
+	{ STB0899_CS0CFG        	, 0x82 },
+	{ STB0899_CS1CFG        	, 0x82 },
+	{ STB0899_DISEQCOCFG    	, 0x20 },
+	{ STB0899_GPIO32CFG		, 0x82 },
+	{ STB0899_GPIO33CFG		, 0x82 },
+	{ STB0899_GPIO34CFG		, 0x82 },
+	{ STB0899_GPIO35CFG		, 0x82 },
+	{ STB0899_GPIO36CFG		, 0x82 },
+	{ STB0899_GPIO37CFG		, 0x82 },
+	{ STB0899_GPIO38CFG		, 0x82 },
+	{ STB0899_GPIO39CFG		, 0x82 },
+	{ STB0899_NCOARSE       	, 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
+	{ STB0899_SYNTCTRL      	, 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
+	{ STB0899_FILTCTRL      	, 0x00 },
+	{ STB0899_SYSCTRL       	, 0x01 },
+	{ STB0899_STOPCLK1      	, 0x20 },
+	{ STB0899_STOPCLK2      	, 0x00 },
+	{ STB0899_INTBUFSTATUS		, 0x00 },
+	{ STB0899_INTBUFCTRL    	, 0x0a },
+	{ 0xffff			, 0xff },
+};
+
+static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
+	{ STB0899_DEMOD         	, 0x00 },
+	{ STB0899_RCOMPC        	, 0xc9 },
+	{ STB0899_AGC1CN        	, 0x01 },
+	{ STB0899_AGC1REF       	, 0x10 },
+	{ STB0899_RTC	        	, 0x23 },
+	{ STB0899_TMGCFG        	, 0x4e },
+	{ STB0899_AGC2REF       	, 0x34 },
+	{ STB0899_TLSR          	, 0x84 },
+	{ STB0899_CFD           	, 0xf7 },
+	{ STB0899_ACLC	        	, 0x87 },
+	{ STB0899_BCLC          	, 0x94 },
+	{ STB0899_EQON          	, 0x41 },
+	{ STB0899_LDT           	, 0xf1 },
+	{ STB0899_LDT2          	, 0xe3 },
+	{ STB0899_EQUALREF      	, 0xb4 },
+	{ STB0899_TMGRAMP       	, 0x10 },
+	{ STB0899_TMGTHD        	, 0x30 },
+	{ STB0899_IDCCOMP		, 0xfd },
+	{ STB0899_QDCCOMP		, 0xff },
+	{ STB0899_POWERI		, 0x0c },
+	{ STB0899_POWERQ		, 0x0f },
+	{ STB0899_RCOMP			, 0x6c },
+	{ STB0899_AGCIQIN		, 0x80 },
+	{ STB0899_AGC2I1		, 0x06 },
+	{ STB0899_AGC2I2		, 0x00 },
+	{ STB0899_TLIR			, 0x30 },
+	{ STB0899_RTF			, 0x7f },
+	{ STB0899_DSTATUS		, 0x00 },
+	{ STB0899_LDI			, 0xbc },
+	{ STB0899_CFRM			, 0xea },
+	{ STB0899_CFRL			, 0x31 },
+	{ STB0899_NIRM			, 0x2b },
+	{ STB0899_NIRL			, 0x80 },
+	{ STB0899_ISYMB			, 0x1d },
+	{ STB0899_QSYMB			, 0xa6 },
+	{ STB0899_SFRH          	, 0x2f },
+	{ STB0899_SFRM          	, 0x68 },
+	{ STB0899_SFRL          	, 0x40 },
+	{ STB0899_SFRUPH        	, 0x2f },
+	{ STB0899_SFRUPM        	, 0x68 },
+	{ STB0899_SFRUPL        	, 0x40 },
+	{ STB0899_EQUAI1		, 0x02 },
+	{ STB0899_EQUAQ1		, 0xff },
+	{ STB0899_EQUAI2		, 0x04 },
+	{ STB0899_EQUAQ2		, 0x05 },
+	{ STB0899_EQUAI3		, 0x02 },
+	{ STB0899_EQUAQ3		, 0xfd },
+	{ STB0899_EQUAI4		, 0x03 },
+	{ STB0899_EQUAQ4		, 0x07 },
+	{ STB0899_EQUAI5		, 0x08 },
+	{ STB0899_EQUAQ5		, 0xf5 },
+	{ STB0899_DSTATUS2		, 0x00 },
+	{ STB0899_VSTATUS       	, 0x00 },
+	{ STB0899_VERROR		, 0x86 },
+	{ STB0899_IQSWAP		, 0x2a },
+	{ STB0899_ECNT1M		, 0x00 },
+	{ STB0899_ECNT1L		, 0x00 },
+	{ STB0899_ECNT2M		, 0x00 },
+	{ STB0899_ECNT2L		, 0x00 },
+	{ STB0899_ECNT3M		, 0x0a },
+	{ STB0899_ECNT3L		, 0xad },
+	{ STB0899_FECAUTO1      	, 0x06 },
+	{ STB0899_FECM	        	, 0x01 },
+	{ STB0899_VTH12         	, 0xb0 },
+	{ STB0899_VTH23         	, 0x7a },
+	{ STB0899_VTH34	        	, 0x58 },
+	{ STB0899_VTH56         	, 0x38 },
+	{ STB0899_VTH67         	, 0x34 },
+	{ STB0899_VTH78         	, 0x24 },
+	{ STB0899_PRVIT         	, 0xff },
+	{ STB0899_VITSYNC       	, 0x19 },
+	{ STB0899_RSULC         	, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
+	{ STB0899_TSULC         	, 0x42 },
+	{ STB0899_RSLLC         	, 0x41 },
+	{ STB0899_TSLPL	        	, 0x12 },
+	{ STB0899_TSCFGH        	, 0x0c },
+	{ STB0899_TSCFGM        	, 0x00 },
+	{ STB0899_TSCFGL        	, 0x00 },
+	{ STB0899_TSOUT			, 0x69 }, /* 0x0d for CAM */
+	{ STB0899_RSSYNCDEL     	, 0x00 },
+	{ STB0899_TSINHDELH     	, 0x02 },
+	{ STB0899_TSINHDELM		, 0x00 },
+	{ STB0899_TSINHDELL		, 0x00 },
+	{ STB0899_TSLLSTKM		, 0x1b },
+	{ STB0899_TSLLSTKL		, 0xb3 },
+	{ STB0899_TSULSTKM		, 0x00 },
+	{ STB0899_TSULSTKL		, 0x00 },
+	{ STB0899_PCKLENUL		, 0xbc },
+	{ STB0899_PCKLENLL		, 0xcc },
+	{ STB0899_RSPCKLEN		, 0xbd },
+	{ STB0899_TSSTATUS		, 0x90 },
+	{ STB0899_ERRCTRL1      	, 0xb6 },
+	{ STB0899_ERRCTRL2      	, 0x95 },
+	{ STB0899_ERRCTRL3      	, 0x8d },
+	{ STB0899_DMONMSK1		, 0x27 },
+	{ STB0899_DMONMSK0		, 0x03 },
+	{ STB0899_DEMAPVIT      	, 0x5c },
+	{ STB0899_PLPARM		, 0x19 },
+	{ STB0899_PDELCTRL      	, 0x48 },
+	{ STB0899_PDELCTRL2     	, 0x00 },
+	{ STB0899_BBHCTRL1      	, 0x00 },
+	{ STB0899_BBHCTRL2      	, 0x00 },
+	{ STB0899_HYSTTHRESH    	, 0x77 },
+	{ STB0899_MATCSTM		, 0x00 },
+	{ STB0899_MATCSTL		, 0x00 },
+	{ STB0899_UPLCSTM		, 0x00 },
+	{ STB0899_UPLCSTL		, 0x00 },
+	{ STB0899_DFLCSTM		, 0x00 },
+	{ STB0899_DFLCSTL		, 0x00 },
+	{ STB0899_SYNCCST		, 0x00 },
+	{ STB0899_SYNCDCSTM		, 0x00 },
+	{ STB0899_SYNCDCSTL		, 0x00 },
+	{ STB0899_ISI_ENTRY		, 0x00 },
+	{ STB0899_ISI_BIT_EN		, 0x00 },
+	{ STB0899_MATSTRM		, 0xf0 },
+	{ STB0899_MATSTRL		, 0x02 },
+	{ STB0899_UPLSTRM		, 0x45 },
+	{ STB0899_UPLSTRL		, 0x60 },
+	{ STB0899_DFLSTRM		, 0xe3 },
+	{ STB0899_DFLSTRL		, 0x00 },
+	{ STB0899_SYNCSTR		, 0x47 },
+	{ STB0899_SYNCDSTRM		, 0x05 },
+	{ STB0899_SYNCDSTRL		, 0x18 },
+	{ STB0899_CFGPDELSTATUS1	, 0x19 },
+	{ STB0899_CFGPDELSTATUS2	, 0x2b },
+	{ STB0899_BBFERRORM		, 0x00 },
+	{ STB0899_BBFERRORL		, 0x01 },
+	{ STB0899_UPKTERRORM		, 0x00 },
+	{ STB0899_UPKTERRORL		, 0x00 },
+	{ 0xffff			, 0xff },
+};
+
+
+
+struct stb0899_config az6027_stb0899_config = {
+	.init_dev		= az6027_stb0899_s1_init_1,
+	.init_s2_demod		= stb0899_s2_init_2,
+	.init_s1_demod		= az6027_stb0899_s1_init_3,
+	.init_s2_fec		= stb0899_s2_init_4,
+	.init_tst		= stb0899_s1_init_5,
+
+	.demod_address 		= 0xd0, /* 0x68, 0xd0 >> 1 */
+
+	.xtal_freq		= 27000000,
+	.inversion		= IQ_SWAP_ON, /* 1 */
+
+	.lo_clk			= 76500000,
+	.hi_clk			= 99000000,
+
+	.esno_ave		= STB0899_DVBS2_ESNO_AVE,
+	.esno_quant		= STB0899_DVBS2_ESNO_QUANT,
+	.avframes_coarse	= STB0899_DVBS2_AVFRAMES_COARSE,
+	.avframes_fine		= STB0899_DVBS2_AVFRAMES_FINE,
+	.miss_threshold		= STB0899_DVBS2_MISS_THRESHOLD,
+	.uwp_threshold_acq	= STB0899_DVBS2_UWP_THRESHOLD_ACQ,
+	.uwp_threshold_track	= STB0899_DVBS2_UWP_THRESHOLD_TRACK,
+	.uwp_threshold_sof	= STB0899_DVBS2_UWP_THRESHOLD_SOF,
+	.sof_search_timeout	= STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
+
+	.btr_nco_bits		= STB0899_DVBS2_BTR_NCO_BITS,
+	.btr_gain_shift_offset	= STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
+	.crl_nco_bits		= STB0899_DVBS2_CRL_NCO_BITS,
+	.ldpc_max_iter		= STB0899_DVBS2_LDPC_MAX_ITER,
+
+	.tuner_get_frequency	= stb6100_get_frequency,
+	.tuner_set_frequency	= stb6100_set_frequency,
+	.tuner_set_bandwidth	= stb6100_set_bandwidth,
+	.tuner_get_bandwidth	= stb6100_get_bandwidth,
+	.tuner_set_rfsiggain	= NULL,
+};
+
+struct stb6100_config az6027_stb6100_config = {
+	.tuner_address	= 0xc0,
+	.refclock	= 27000000,
+};
+
+
+/* check for mutex FIXME */
+int az6027_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+{
+	int ret = -1;
+	if (mutex_lock_interruptible(&d->usb_mutex))
+		return -EAGAIN;
+
+	ret = usb_control_msg(d->udev,
+			      usb_rcvctrlpipe(d->udev, 0),
+			      req,
+			      USB_TYPE_VENDOR | USB_DIR_IN,
+			      value,
+			      index,
+			      b,
+			      blen,
+			      2000);
+
+	if (ret < 0) {
+		warn("usb in operation failed. (%d)", ret);
+		ret = -EIO;
+	} else
+		ret = 0;
+
+	deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
+	debug_dump(b, blen, deb_xfer);
+
+	mutex_unlock(&d->usb_mutex);
+	return ret;
+}
+
+static int az6027_usb_out_op(struct dvb_usb_device *d,
+			     u8 req,
+			     u16 value,
+			     u16 index,
+			     u8 *b,
+			     int blen)
+{
+	int ret;
+
+	deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
+	debug_dump(b, blen, deb_xfer);
+
+	if (mutex_lock_interruptible(&d->usb_mutex))
+		return -EAGAIN;
+
+	ret = usb_control_msg(d->udev,
+			      usb_sndctrlpipe(d->udev, 0),
+			      req,
+			      USB_TYPE_VENDOR | USB_DIR_OUT,
+			      value,
+			      index,
+			      b,
+			      blen,
+			      2000);
+
+	if (ret != blen) {
+		warn("usb out operation failed. (%d)", ret);
+		mutex_unlock(&d->usb_mutex);
+		return -EIO;
+	} else{
+		mutex_unlock(&d->usb_mutex);
+		return 0;
+	}
+}
+
+static int az6027_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+	int ret;
+	u8 req;
+	u16 value;
+	u16 index;
+	int blen;
+
+	deb_info("%s %d", __func__, onoff);
+
+	req = 0xBC;
+	value = onoff;
+	index = 0;
+	blen = 0;
+
+	ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
+	if (ret != 0)
+		warn("usb out operation failed. (%d)", ret);
+
+	return ret;
+}
+
+/* keys for the enclosed remote control */
+static struct dvb_usb_rc_key az6027_rc_keys[] = {
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+};
+
+/* remote control stuff (does not work with my box) */
+static int az6027_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+	return 0;
+}
+
+/*
+int az6027_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	u8 v = onoff;
+	return az6027_usb_out_op(d,0xBC,v,3,NULL,1);
+}
+*/
+
+static int az6027_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
+					int slot,
+					int address)
+{
+	struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+	struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+
+	int ret;
+	u8 req;
+	u16 value;
+	u16 index;
+	int blen;
+	u8 b[12];
+
+	if (slot != 0)
+		return -EINVAL;
+
+	mutex_lock(&state->ca_mutex);
+
+	req = 0xC1;
+	value = address;
+	index = 0;
+	blen = 1;
+
+	ret = az6027_usb_in_op(d, req, value, index, b, blen);
+	if (ret < 0) {
+		warn("usb in operation failed. (%d)", ret);
+		ret = -EINVAL;
+	} else {
+		ret = b[0];
+	}
+
+	mutex_unlock(&state->ca_mutex);
+	return ret;
+}
+
+static int az6027_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
+					 int slot,
+					 int address,
+					 u8 value)
+{
+	struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+	struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+
+	int ret;
+	u8 req;
+	u16 value1;
+	u16 index;
+	int blen;
+
+	deb_info("%s %d", __func__, slot);
+	if (slot != 0)
+		return -EINVAL;
+
+	mutex_lock(&state->ca_mutex);
+	req = 0xC2;
+	value1 = address;
+	index = value;
+	blen = 0;
+
+	ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
+	if (ret != 0)
+		warn("usb out operation failed. (%d)", ret);
+
+	mutex_unlock(&state->ca_mutex);
+	return ret;
+}
+
+static int az6027_ci_read_cam_control(struct dvb_ca_en50221 *ca,
+				      int slot,
+				      u8 address)
+{
+	struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+	struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+
+	int ret;
+	u8 req;
+	u16 value;
+	u16 index;
+	int blen;
+	u8 b[12];
+
+	if (slot != 0)
+		return -EINVAL;
+
+	mutex_lock(&state->ca_mutex);
+
+	req = 0xC3;
+	value = address;
+	index = 0;
+	blen = 2;
+
+	ret = az6027_usb_in_op(d, req, value, index, b, blen);
+	if (ret < 0) {
+		warn("usb in operation failed. (%d)", ret);
+		ret = -EINVAL;
+	} else {
+		if (b[0] == 0)
+			warn("Read CI IO error");
+
+		ret = b[1];
+		deb_info("read cam data = %x from 0x%x", b[1], value);
+	}
+
+	mutex_unlock(&state->ca_mutex);
+	return ret;
+}
+
+static int az6027_ci_write_cam_control(struct dvb_ca_en50221 *ca,
+				       int slot,
+				       u8 address,
+				       u8 value)
+{
+	struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+	struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+
+	int ret;
+	u8 req;
+	u16 value1;
+	u16 index;
+	int blen;
+
+	if (slot != 0)
+		return -EINVAL;
+
+	mutex_lock(&state->ca_mutex);
+	req = 0xC4;
+	value1 = address;
+	index = value;
+	blen = 0;
+
+	ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
+	if (ret != 0) {
+		warn("usb out operation failed. (%d)", ret);
+		goto failed;
+	}
+
+failed:
+	mutex_unlock(&state->ca_mutex);
+	return ret;
+}
+
+static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
+{
+	struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+
+	int ret;
+	u8 req;
+	u16 value;
+	u16 index;
+	int blen;
+	u8 b[12];
+
+	req = 0xC8;
+	value = 0;
+	index = 0;
+	blen = 1;
+
+	ret = az6027_usb_in_op(d, req, value, index, b, blen);
+	if (ret < 0) {
+		warn("usb in operation failed. (%d)", ret);
+		ret = -EIO;
+	} else{
+		ret = b[0];
+	}
+	return ret;
+}
+
+static int az6027_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
+{
+	struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+	struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+
+	int ret, i;
+	u8 req;
+	u16 value;
+	u16 index;
+	int blen;
+
+	mutex_lock(&state->ca_mutex);
+
+	req = 0xC6;
+	value = 1;
+	index = 0;
+	blen = 0;
+
+	ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
+	if (ret != 0) {
+		warn("usb out operation failed. (%d)", ret);
+		goto failed;
+	}
+
+	msleep(500);
+	req = 0xC6;
+	value = 0;
+	index = 0;
+	blen = 0;
+
+	ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
+	if (ret != 0) {
+		warn("usb out operation failed. (%d)", ret);
+		goto failed;
+	}
+
+	for (i = 0; i < 15; i++) {
+		msleep(100);
+
+		if (CI_CamReady(ca, slot)) {
+			deb_info("CAM Ready");
+			break;
+		}
+	}
+	msleep(5000);
+
+failed:
+	mutex_unlock(&state->ca_mutex);
+	return ret;
+}
+
+static int az6027_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
+{
+	return 0;
+}
+
+static int az6027_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
+{
+	struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+	struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+
+	int ret;
+	u8 req;
+	u16 value;
+	u16 index;
+	int blen;
+
+	deb_info("%s", __func__);
+	mutex_lock(&state->ca_mutex);
+	req = 0xC7;
+	value = 1;
+	index = 0;
+	blen = 0;
+
+	ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
+	if (ret != 0) {
+		warn("usb out operation failed. (%d)", ret);
+		goto failed;
+	}
+
+failed:
+	mutex_unlock(&state->ca_mutex);
+	return ret;
+}
+
+static int az6027_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
+{
+	struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+	struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+	int ret;
+	u8 req;
+	u16 value;
+	u16 index;
+	int blen;
+	u8 b[12];
+
+	mutex_lock(&state->ca_mutex);
+
+	req = 0xC5;
+	value = 0;
+	index = 0;
+	blen = 1;
+
+	ret = az6027_usb_in_op(d, req, value, index, b, blen);
+	if (ret < 0) {
+		warn("usb in operation failed. (%d)", ret);
+		ret = -EIO;
+	} else
+		ret = 0;
+
+	if (b[0] == 0) {
+		ret = 0;
+
+	} else if (b[0] == 1) {
+		ret = DVB_CA_EN50221_POLL_CAM_PRESENT |
+		      DVB_CA_EN50221_POLL_CAM_READY;
+	}
+
+	mutex_unlock(&state->ca_mutex);
+	return ret;
+}
+
+
+static void az6027_ci_uninit(struct dvb_usb_device *d)
+{
+	struct az6027_device_state *state;
+
+	deb_info("%s", __func__);
+
+	if (NULL == d)
+		return;
+
+	state = (struct az6027_device_state *)d->priv;
+	if (NULL == state)
+		return;
+
+	if (NULL == state->ca.data)
+		return;
+
+	dvb_ca_en50221_release(&state->ca);
+
+	memset(&state->ca, 0, sizeof(state->ca));
+}
+
+
+static int az6027_ci_init(struct dvb_usb_adapter *a)
+{
+	struct dvb_usb_device *d = a->dev;
+	struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+	int ret;
+
+	deb_info("%s", __func__);
+
+	mutex_init(&state->ca_mutex);
+
+	state->ca.owner			= THIS_MODULE;
+	state->ca.read_attribute_mem	= az6027_ci_read_attribute_mem;
+	state->ca.write_attribute_mem	= az6027_ci_write_attribute_mem;
+	state->ca.read_cam_control	= az6027_ci_read_cam_control;
+	state->ca.write_cam_control	= az6027_ci_write_cam_control;
+	state->ca.slot_reset		= az6027_ci_slot_reset;
+	state->ca.slot_shutdown		= az6027_ci_slot_shutdown;
+	state->ca.slot_ts_enable	= az6027_ci_slot_ts_enable;
+	state->ca.poll_slot_status	= az6027_ci_poll_slot_status;
+	state->ca.data			= d;
+
+	ret = dvb_ca_en50221_init(&a->dvb_adap,
+				  &state->ca,
+				  0, /* flags */
+				  1);/* n_slots */
+	if (ret != 0) {
+		err("Cannot initialize CI: Error %d.", ret);
+		memset(&state->ca, 0, sizeof(state->ca));
+		return ret;
+	}
+
+	deb_info("CI initialized.");
+
+	return 0;
+}
+
+/*
+static int az6027_read_mac_addr(struct dvb_usb_device *d, u8 mac[6])
+{
+	az6027_usb_in_op(d, 0xb7, 6, 0, &mac[0], 6);
+	return 0;
+}
+*/
+
+static int az6027_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+
+	u8 buf;
+	int ret;
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
+
+	struct i2c_msg i2c_msg = {
+		.addr	= 0x99,
+		.flags	= 0,
+		.buf	= &buf,
+		.len	= 1
+	};
+
+	/*
+	 * 2   --18v
+	 * 1   --13v
+	 * 0   --off
+	 */
+	switch (voltage) {
+	case SEC_VOLTAGE_13:
+		buf = 1;
+		ret = i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
+		break;
+
+	case SEC_VOLTAGE_18:
+		buf = 2;
+		ret = i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
+		break;
+
+	case SEC_VOLTAGE_OFF:
+		buf = 0;
+		ret = i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+
+static int az6027_frontend_poweron(struct dvb_usb_adapter *adap)
+{
+	int ret;
+	u8 req;
+	u16 value;
+	u16 index;
+	int blen;
+
+	req = 0xBC;
+	value = 1; /* power on */
+	index = 3;
+	blen = 0;
+
+	ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
+	if (ret != 0)
+		return -EIO;
+
+	return 0;
+}
+static int az6027_frontend_reset(struct dvb_usb_adapter *adap)
+{
+	int ret;
+	u8 req;
+	u16 value;
+	u16 index;
+	int blen;
+
+	/* reset demodulator */
+	req = 0xC0;
+	value = 1; /* high */
+	index = 3;
+	blen = 0;
+
+	ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
+	if (ret != 0)
+		return -EIO;
+
+	req = 0xC0;
+	value = 0; /* low */
+	index = 3;
+	blen = 0;
+	msleep_interruptible(200);
+
+	ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
+	if (ret != 0)
+		return -EIO;
+
+	msleep_interruptible(200);
+
+	req = 0xC0;
+	value = 1; /*high */
+	index = 3;
+	blen = 0;
+
+	ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
+	if (ret != 0)
+		return -EIO;
+
+	msleep_interruptible(200);
+	return 0;
+}
+
+static int az6027_frontend_tsbypass(struct dvb_usb_adapter *adap, int onoff)
+{
+	int ret;
+	u8 req;
+	u16 value;
+	u16 index;
+	int blen;
+
+	/* TS passthrough */
+	req = 0xC7;
+	value = onoff;
+	index = 0;
+	blen = 0;
+
+	ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
+	if (ret != 0)
+		return -EIO;
+
+	return 0;
+}
+
+static int az6027_frontend_attach(struct dvb_usb_adapter *adap)
+{
+
+	az6027_frontend_poweron(adap);
+	az6027_frontend_reset(adap);
+
+	deb_info("adap = %p, dev = %p\n", adap, adap->dev);
+	adap->fe = stb0899_attach(&az6027_stb0899_config, &adap->dev->i2c_adap);
+
+	if (adap->fe) {
+		deb_info("found STB0899 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb0899_config.demod_address);
+		if (stb6100_attach(adap->fe, &az6027_stb6100_config, &adap->dev->i2c_adap)) {
+			deb_info("found STB6100 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb6100_config.tuner_address);
+			adap->fe->ops.set_voltage = az6027_set_voltage;
+			az6027_ci_init(adap);
+		} else {
+			adap->fe = NULL;
+		}
+	} else
+		warn("no front-end attached\n");
+
+	az6027_frontend_tsbypass(adap, 0);
+
+	return 0;
+}
+
+static struct dvb_usb_device_properties az6027_properties;
+
+static void az6027_usb_disconnect(struct usb_interface *intf)
+{
+	struct dvb_usb_device *d = usb_get_intfdata(intf);
+	az6027_ci_uninit(d);
+	dvb_usb_device_exit(intf);
+}
+
+
+static int az6027_usb_probe(struct usb_interface *intf,
+			    const struct usb_device_id *id)
+{
+	return dvb_usb_device_init(intf,
+				   &az6027_properties,
+				   THIS_MODULE,
+				   NULL,
+				   adapter_nr);
+}
+
+/* I2C */
+static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
+{
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	int i = 0, j = 0, len = 0;
+	int ret;
+	u16 index;
+	u16 value;
+	int length;
+	u8 req;
+	u8 data[256];
+
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
+
+	if (num > 2)
+		warn("more than 2 i2c messages at a time is not handled yet. TODO.");
+
+	for (i = 0; i < num; i++) {
+
+		if (msg[i].addr == 0x99) {
+			req = 0xBE;
+			index = 0;
+			value = msg[i].buf[0] & 0x00ff;
+			length = 1;
+			az6027_usb_out_op(d, req, value, index, data, length);
+		}
+
+		if (msg[i].addr == 0xd0) {
+			/* write/read request */
+			if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
+				req = 0xB9;
+				index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
+				value = msg[i].addr + (msg[i].len << 8);
+				length = msg[i + 1].len + 6;
+				ret = az6027_usb_in_op(d, req, value, index, data, length);
+				len = msg[i + 1].len;
+				for (j = 0; j < len; j++)
+					msg[i + 1].buf[j] = data[j + 5];
+
+				i++;
+			} else {
+
+				if (msg[i].addr == 0xd0) {
+					/* demod 16bit addr */
+					req = 0xBD;
+					index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
+					value = msg[i].addr + (2 << 8);
+					length = msg[i].len - 2;
+					len = msg[i].len - 2;
+					for (j = 0; j < len; j++)
+						data[j] = msg[i].buf[j + 2];
+
+				}
+				az6027_usb_out_op(d, req, value, index, data, length);
+			}
+		}
+
+		if (msg[i].addr == 0xc0) {
+			if (msg[i].flags & I2C_M_RD) {
+
+				req = 0xB9;
+				index = 0x0;
+				value = msg[i].addr;
+				length = msg[i].len + 6;
+				ret = az6027_usb_in_op(d, req, value, index, data, length);
+				len = msg[i].len;
+				for (j = 0; j < len; j++)
+					msg[i].buf[j] = data[j + 5];
+
+			} else {
+
+				req = 0xBD;
+				index = msg[i].buf[0] & 0x00FF;
+				value = msg[i].addr + (1 << 8);
+				length = msg[i].len - 1;
+				len = msg[i].len - 1;
+
+				for (j = 0; j < len; j++)
+					data[j] = msg[i].buf[j + 1];
+
+				az6027_usb_out_op(d, req, value, index, data, length);
+			}
+		}
+	}
+	mutex_unlock(&d->i2c_mutex);
+
+	return i;
+}
+
+
+static u32 az6027_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm az6027_i2c_algo = {
+	.master_xfer   = az6027_i2c_xfer,
+	.functionality = az6027_i2c_func,
+};
+
+int az6027_identify_state(struct usb_device *udev,
+			  struct dvb_usb_device_properties *props,
+			  struct dvb_usb_device_description **desc,
+			  int *cold)
+{
+	u8 b[16];
+	s16 ret = usb_control_msg(udev,
+				  usb_rcvctrlpipe(udev, 0),
+				  0xb7,
+				  USB_TYPE_VENDOR | USB_DIR_IN,
+				  6,
+				  0,
+				  b,
+				  6,
+				  USB_CTRL_GET_TIMEOUT);
+
+	*cold = ret <= 0;
+
+	deb_info("cold: %d\n", *cold);
+	return 0;
+}
+
+
+static struct usb_device_id az6027_usb_table[] = {
+	{ USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_AZ6027) },
+	{ USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_DVBS2CI) },
+	{ USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI) },
+	{ },
+};
+
+MODULE_DEVICE_TABLE(usb, az6027_usb_table);
+
+static struct dvb_usb_device_properties az6027_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+	.usb_ctrl = CYPRESS_FX2,
+	.firmware            = "/*(DEBLOBBED)*/",
+	.no_reconnect        = 1,
+
+	.size_of_priv     = sizeof(struct az6027_device_state),
+	.identify_state		= az6027_identify_state,
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.streaming_ctrl   = az6027_streaming_ctrl,
+			.frontend_attach  = az6027_frontend_attach,
+
+			/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+				.count = 10,
+				.endpoint = 0x02,
+				.u = {
+					.bulk = {
+						.buffersize = 4096,
+					}
+				}
+			},
+		}
+	},
+/*
+	.power_ctrl       = az6027_power_ctrl,
+	.read_mac_address = az6027_read_mac_addr,
+ */
+	.rc_key_map       = az6027_rc_keys,
+	.rc_key_map_size  = ARRAY_SIZE(az6027_rc_keys),
+	.rc_interval      = 400,
+	.rc_query         = az6027_rc_query,
+	.i2c_algo         = &az6027_i2c_algo,
+
+	.num_device_descs = 1,
+	.devices = {
+		{
+			.name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)",
+			.cold_ids = { &az6027_usb_table[0], NULL },
+			.warm_ids = { NULL },
+		},
+		{ NULL },
+	}
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver az6027_usb_driver = {
+	.name		= "dvb_usb_az6027",
+	.probe 		= az6027_usb_probe,
+	.disconnect 	= az6027_usb_disconnect,
+	.id_table 	= az6027_usb_table,
+};
+
+/* module stuff */
+static int __init az6027_usb_module_init(void)
+{
+	int result;
+
+	result = usb_register(&az6027_usb_driver);
+	if (result) {
+		err("usb_register failed. (%d)", result);
+		return result;
+	}
+
+	return 0;
+}
+
+static void __exit az6027_usb_module_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&az6027_usb_driver);
+}
+
+module_init(az6027_usb_module_init);
+module_exit(az6027_usb_module_exit);
+
+MODULE_AUTHOR("Adams Xu <Adams.xu@azwave.com.cn>");
+MODULE_DESCRIPTION("Driver for AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/az6027.h linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/az6027.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/az6027.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/az6027.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,14 @@
+#ifndef _DVB_USB_VP6027_H_
+#define _DVB_USB_VP6027_H_
+
+#define DVB_USB_LOG_PREFIX "az6027"
+#include "dvb-usb.h"
+
+
+extern int dvb_usb_az6027_debug;
+#define deb_info(args...) dprintk(dvb_usb_az6027_debug, 0x01, args)
+#define deb_xfer(args...) dprintk(dvb_usb_az6027_debug, 0x02, args)
+#define deb_rc(args...)   dprintk(dvb_usb_az6027_debug, 0x04, args)
+#define deb_fe(args...)   dprintk(dvb_usb_az6027_debug, 0x08, args)
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/cxusb.c linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/cxusb.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/cxusb.c	2013-05-03 12:04:01.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/cxusb.c	2013-05-03 09:44:58.000000000 -0400
@@ -25,6 +25,7 @@
  */
 #include <media/tuner.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include "cxusb.h"
 
@@ -1184,6 +1185,9 @@ static struct atbm8830_config mygica_d68
 	.osc_clk_freq = 30400, /* in kHz */
 	.if_freq = 0, /* zero IF */
 	.zif_swap_iq = 1,
+	.agc_min = 0x2E,
+	.agc_max = 0x90,
+	.agc_hold_loop = 0,
 };
 
 static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dib0700_core.c linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/dib0700_core.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dib0700_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/dib0700_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -471,14 +471,209 @@ int dib0700_streaming_ctrl(struct dvb_us
 	return dib0700_ctrl_wr(adap->dev, b, 4);
 }
 
+/* Number of keypresses to ignore before start repeating */
+#define RC_REPEAT_DELAY_V1_20 10
+
+/* This is the structure of the RC response packet starting in firmware 1.20 */
+struct dib0700_rc_response {
+	u8 report_id;
+	u8 data_state;
+	u16 system;
+	u8 data;
+	u8 not_data;
+};
+#define RC_MSG_SIZE_V1_20 6
+
+static void dib0700_rc_urb_completion(struct urb *purb)
+{
+	struct dvb_usb_device *d = purb->context;
+	struct dvb_usb_rc_key *keymap;
+	struct dib0700_state *st;
+	struct dib0700_rc_response poll_reply;
+	u8 *buf;
+	int found = 0;
+	u32 event;
+	int state;
+	int i;
+
+	deb_info("%s()\n", __func__);
+	if (d == NULL)
+		return;
+
+	if (d->rc_input_dev == NULL) {
+		/* This will occur if disable_rc_polling=1 */
+		usb_free_urb(purb);
+		return;
+	}
+
+	keymap = d->props.rc_key_map;
+	st = d->priv;
+	buf = (u8 *)purb->transfer_buffer;
+
+	if (purb->status < 0) {
+		deb_info("discontinuing polling\n");
+		usb_free_urb(purb);
+		return;
+	}
+
+	if (purb->actual_length != RC_MSG_SIZE_V1_20) {
+		deb_info("malformed rc msg size=%d\n", purb->actual_length);
+		goto resubmit;
+	}
+
+	/* Set initial results in case we exit the function early */
+	event = 0;
+	state = REMOTE_NO_KEY_PRESSED;
+
+	deb_data("IR raw %02X %02X %02X %02X %02X %02X (len %d)\n", buf[0],
+		 buf[1], buf[2], buf[3], buf[4], buf[5], purb->actual_length);
+
+	switch (dvb_usb_dib0700_ir_proto) {
+	case 0:
+		/* NEC Protocol */
+		poll_reply.report_id  = 0;
+		poll_reply.data_state = 1;
+		poll_reply.system     = buf[2];
+		poll_reply.data       = buf[4];
+		poll_reply.not_data   = buf[5];
+
+		/* NEC protocol sends repeat code as 0 0 0 FF */
+		if ((poll_reply.system == 0x00) && (poll_reply.data == 0x00)
+		    && (poll_reply.not_data == 0xff)) {
+			poll_reply.data_state = 2;
+			break;
+		}
+		break;
+	default:
+		/* RC5 Protocol */
+		poll_reply.report_id  = buf[0];
+		poll_reply.data_state = buf[1];
+		poll_reply.system     = (buf[2] << 8) | buf[3];
+		poll_reply.data       = buf[4];
+		poll_reply.not_data   = buf[5];
+		break;
+	}
+
+	if ((poll_reply.data + poll_reply.not_data) != 0xff) {
+		/* Key failed integrity check */
+		err("key failed integrity check: %04x %02x %02x",
+		    poll_reply.system,
+		    poll_reply.data, poll_reply.not_data);
+		goto resubmit;
+	}
+
+	deb_data("rid=%02x ds=%02x sm=%04x d=%02x nd=%02x\n",
+		 poll_reply.report_id, poll_reply.data_state,
+		 poll_reply.system, poll_reply.data, poll_reply.not_data);
+
+	/* Find the key in the map */
+	for (i = 0; i < d->props.rc_key_map_size; i++) {
+		if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) &&
+		    rc5_data(&keymap[i]) == poll_reply.data) {
+			event = keymap[i].event;
+			found = 1;
+			break;
+		}
+	}
+
+	if (found == 0) {
+		err("Unknown remote controller key: %04x %02x %02x",
+		    poll_reply.system, poll_reply.data, poll_reply.not_data);
+		d->last_event = 0;
+		goto resubmit;
+	}
+
+	if (poll_reply.data_state == 1) {
+		/* New key hit */
+		st->rc_counter = 0;
+		event = keymap[i].event;
+		state = REMOTE_KEY_PRESSED;
+		d->last_event = keymap[i].event;
+	} else if (poll_reply.data_state == 2) {
+		/* Key repeated */
+		st->rc_counter++;
+
+		/* prevents unwanted double hits */
+		if (st->rc_counter > RC_REPEAT_DELAY_V1_20) {
+			event = d->last_event;
+			state = REMOTE_KEY_PRESSED;
+			st->rc_counter = RC_REPEAT_DELAY_V1_20;
+		}
+	} else {
+		err("Unknown data state [%d]", poll_reply.data_state);
+	}
+
+	switch (state) {
+	case REMOTE_NO_KEY_PRESSED:
+		break;
+	case REMOTE_KEY_PRESSED:
+		deb_info("key pressed\n");
+		d->last_event = event;
+	case REMOTE_KEY_REPEAT:
+		deb_info("key repeated\n");
+		input_event(d->rc_input_dev, EV_KEY, event, 1);
+		input_sync(d->rc_input_dev);
+		input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
+		input_sync(d->rc_input_dev);
+		break;
+	default:
+		break;
+	}
+
+resubmit:
+	/* Clean the buffer before we requeue */
+	memset(purb->transfer_buffer, 0, RC_MSG_SIZE_V1_20);
+
+	/* Requeue URB */
+	usb_submit_urb(purb, GFP_ATOMIC);
+}
+
 int dib0700_rc_setup(struct dvb_usb_device *d)
 {
+	struct dib0700_state *st = d->priv;
 	u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0};
-	int i = dib0700_ctrl_wr(d, rc_setup, 3);
+	struct urb *purb;
+	int ret;
+	int i;
+
+	if (d->props.rc_key_map == NULL)
+		return 0;
+
+	/* Set the IR mode */
+	i = dib0700_ctrl_wr(d, rc_setup, 3);
 	if (i<0) {
 		err("ir protocol setup failed");
 		return -1;
 	}
+
+	if (st->fw_version < 0x10200)
+		return 0;
+
+	/* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
+	purb = usb_alloc_urb(0, GFP_KERNEL);
+	if (purb == NULL) {
+		err("rc usb alloc urb failed\n");
+		return -1;
+	}
+
+	purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL);
+	if (purb->transfer_buffer == NULL) {
+		err("rc kzalloc failed\n");
+		usb_free_urb(purb);
+		return -1;
+	}
+
+	purb->status = -EINPROGRESS;
+	usb_fill_bulk_urb(purb, d->udev, usb_rcvbulkpipe(d->udev, 1),
+			  purb->transfer_buffer, RC_MSG_SIZE_V1_20,
+			  dib0700_rc_urb_completion, d);
+
+	ret = usb_submit_urb(purb, GFP_ATOMIC);
+	if (ret != 0) {
+		err("rc submit urb failed\n");
+		return -1;
+	}
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dib0700_devices.c linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/dib0700_devices.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dib0700_devices.c	2013-05-03 12:04:04.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/dib0700_devices.c	2013-05-03 09:45:01.000000000 -0400
@@ -472,20 +472,25 @@ static u8 rc_request[] = { REQUEST_POLL_
 
 /* Number of keypresses to ignore before start repeating */
 #define RC_REPEAT_DELAY 6
-#define RC_REPEAT_DELAY_V1_20 10
-
-
 
-/* Used by firmware versions < 1.20 (deprecated) */
-static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
-				   int *state)
+static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 {
 	u8 key[4];
 	int i;
 	struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
 	struct dib0700_state *st = d->priv;
+
 	*event = 0;
 	*state = REMOTE_NO_KEY_PRESSED;
+
+	if (st->fw_version >= 0x10200) {
+		/* For 1.20 firmware , We need to keep the RC polling
+		   callback so we can reuse the input device setup in
+		   dvb-usb-remote.c.  However, the actual work is being done
+		   in the bulk URB completion handler. */
+		return 0;
+	}
+
 	i=dib0700_ctrl_rd(d,rc_request,2,key,4);
 	if (i<=0) {
 		err("RC Query Failed");
@@ -557,149 +562,6 @@ static int dib0700_rc_query_legacy(struc
 	return 0;
 }
 
-/* This is the structure of the RC response packet starting in firmware 1.20 */
-struct dib0700_rc_response {
-	u8 report_id;
-	u8 data_state;
-	u16 system;
-	u8 data;
-	u8 not_data;
-};
-
-/* This supports the new IR response format for firmware v1.20 */
-static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
-				  int *state)
-{
-	struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
-	struct dib0700_state *st = d->priv;
-	struct dib0700_rc_response poll_reply;
-	u8 buf[6];
-	int i;
-	int status;
-	int actlen;
-	int found = 0;
-
-	/* Set initial results in case we exit the function early */
-	*event = 0;
-	*state = REMOTE_NO_KEY_PRESSED;
-
-	/* Firmware v1.20 provides RC data via bulk endpoint 1 */
-	status = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 1), buf,
-			      sizeof(buf), &actlen, 50);
-	if (status < 0) {
-		/* No data available (meaning no key press) */
-		return 0;
-	}
-
-
-	switch (dvb_usb_dib0700_ir_proto) {
-	case 0:
-		poll_reply.report_id  = 0;
-		poll_reply.data_state = 1;
-		poll_reply.system     = buf[2];
-		poll_reply.data       = buf[4];
-		poll_reply.not_data   = buf[5];
-
-		/* NEC protocol sends repeat code as 0 0 0 FF */
-		if ((poll_reply.system == 0x00) && (poll_reply.data == 0x00)
-		    && (poll_reply.not_data == 0xff)) {
-			poll_reply.data_state = 2;
-			break;
-		}
-		break;
-	default:
-	if (actlen != sizeof(buf)) {
-		/* We didn't get back the 6 byte message we expected */
-		err("Unexpected RC response size [%d]", actlen);
-		return -1;
-	}
-
-	poll_reply.report_id  = buf[0];
-	poll_reply.data_state = buf[1];
-		poll_reply.system     = (buf[2] << 8) | buf[3];
-	poll_reply.data       = buf[4];
-	poll_reply.not_data   = buf[5];
-
-		break;
-	}
-
-	if ((poll_reply.data + poll_reply.not_data) != 0xff) {
-		/* Key failed integrity check */
-		err("key failed integrity check: %04x %02x %02x",
-		    poll_reply.system,
-		    poll_reply.data, poll_reply.not_data);
-		return -1;
-	}
-
-
-	/* Find the key in the map */
-	for (i = 0; i < d->props.rc_key_map_size; i++) {
-		if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) &&
-			rc5_data(&keymap[i]) == poll_reply.data) {
-			*event = keymap[i].event;
-			found = 1;
-			break;
-		}
-	}
-
-	if (found == 0) {
-		err("Unknown remote controller key: %04x %02x %02x",
-			poll_reply.system,
-			poll_reply.data, poll_reply.not_data);
-		d->last_event = 0;
-		return 0;
-	}
-
-	if (poll_reply.data_state == 1) {
-		/* New key hit */
-		st->rc_counter = 0;
-		*event = keymap[i].event;
-		*state = REMOTE_KEY_PRESSED;
-		d->last_event = keymap[i].event;
-	} else if (poll_reply.data_state == 2) {
-		/* Key repeated */
-		st->rc_counter++;
-
-		/* prevents unwanted double hits */
-		if (st->rc_counter > RC_REPEAT_DELAY_V1_20) {
-			*event = d->last_event;
-			*state = REMOTE_KEY_PRESSED;
-			st->rc_counter = RC_REPEAT_DELAY_V1_20;
-		}
-	} else {
-		err("Unknown data state [%d]", poll_reply.data_state);
-	}
-
-	return 0;
-}
-
-static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
-{
-	struct dib0700_state *st = d->priv;
-
-	/* Because some people may have improperly named firmware files,
-	   let's figure out whether to use the new firmware call or the legacy
-	   call based on the firmware version embedded in the file */
-	if (st->rc_func_version == 0) {
-		u32 hwver, romver, ramver, fwtype;
-		int ret = dib0700_get_version(d, &hwver, &romver, &ramver,
-					      &fwtype);
-		if (ret < 0) {
-			err("Could not determine version info");
-			return -1;
-		}
-		if (ramver < 0x10200)
-			st->rc_func_version = 1;
-		else
-			st->rc_func_version = 2;
-	}
-
-	if (st->rc_func_version == 2)
-		return dib0700_rc_query_v1_20(d, event, state);
-	else
-		return dib0700_rc_query_legacy(d, event, state);
-}
-
 static struct dvb_usb_rc_key dib0700_rc_keys[] = {
 	/* Key codes for the tiny Pinnacle remote*/
 	{ 0x0700, KEY_MUTE },
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dib0700.h linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/dib0700.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dib0700.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/dib0700.h	2010-05-16 17:17:36.000000000 -0400
@@ -42,7 +42,6 @@ struct dib0700_state {
 	u16 mt2060_if1[2];
 	u8 rc_toggle;
 	u8 rc_counter;
-	u8 rc_func_version;
 	u8 is_dib7000pc;
 	u8 fw_use_new_i2c_api;
 	u8 disable_streaming_master_mode;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-ids.h linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	2010-05-16 17:17:36.000000000 -0400
@@ -64,6 +64,8 @@
 #define USB_VID_HUMAX_COEX			0x10b9
 #define USB_VID_774				0x7a69
 #define USB_VID_EVOLUTEPC			0x1e59
+#define USB_VID_AZUREWAVE			0x13d3
+#define USB_VID_TECHNISAT			0x14f7
 
 /* Product IDs */
 #define USB_PID_ADSTECH_USB2_COLD			0xa333
@@ -138,6 +140,7 @@
 #define USB_PID_TWINHAN_VP7021_COLD			0x3207
 #define USB_PID_TWINHAN_VP7021_WARM			0x3208
 #define USB_PID_TINYTWIN				0x3226
+#define USB_PID_TINYTWIN_2				0xe402
 #define USB_PID_DNTV_TINYUSB2_COLD			0x3223
 #define USB_PID_DNTV_TINYUSB2_WARM			0x3224
 #define USB_PID_ULTIMA_TVBOX_COLD			0x8105
@@ -209,6 +212,7 @@
 #define USB_PID_PINNACLE_PCTV71E			0x022b
 #define USB_PID_PINNACLE_PCTV72E			0x0236
 #define USB_PID_PINNACLE_PCTV73E			0x0237
+#define USB_PID_PINNACLE_PCTV310E			0x3211
 #define USB_PID_PINNACLE_PCTV801E			0x023a
 #define USB_PID_PINNACLE_PCTV801E_SE			0x023b
 #define USB_PID_PINNACLE_PCTV73A			0x0243
@@ -248,6 +252,7 @@
 #define USB_PID_DIGIVOX_MINI_SL_WARM			0xe361
 #define USB_PID_GRANDTEC_DVBT_USB2_COLD			0x0bc6
 #define USB_PID_GRANDTEC_DVBT_USB2_WARM			0x0bc7
+#define USB_PID_WINFAST_DTV2000DS			0x6a04
 #define USB_PID_WINFAST_DTV_DONGLE_COLD			0x6025
 #define USB_PID_WINFAST_DTV_DONGLE_WARM			0x6026
 #define USB_PID_WINFAST_DTV_DONGLE_STK7700P		0x6f00
@@ -290,5 +295,7 @@
 #define USB_PID_FRIIO_WHITE				0x0001
 #define USB_PID_TVWAY_PLUS				0x0002
 #define USB_PID_SVEON_STV20				0xe39d
-
+#define USB_PID_AZUREWAVE_AZ6027			0x3275
+#define USB_PID_TERRATEC_DVBS2CI			0x3275
+#define USB_PID_TECHNISAT_USB2_HDCI			0x0002
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-init.c linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-init.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-init.c	2010-05-16 17:17:36.000000000 -0400
@@ -243,7 +243,7 @@ int dvb_usb_device_init(struct usb_inter
 		d = kzalloc(sizeof(struct dvb_usb_device),GFP_KERNEL);
 	if (d == NULL) {
 		err("no memory for 'struct dvb_usb_device'");
-		return ret;
+		return -ENOMEM;
 	}
 
 	d->udev = udev;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-remote.c linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-remote.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-remote.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,7 @@
 #include <linux/usb/input.h>
 
 static int dvb_usb_getkeycode(struct input_dev *dev,
-				    int scancode, int *keycode)
+				unsigned int scancode, unsigned int *keycode)
 {
 	struct dvb_usb_device *d = input_get_drvdata(dev);
 
@@ -39,7 +39,7 @@ static int dvb_usb_getkeycode(struct inp
 }
 
 static int dvb_usb_setkeycode(struct input_dev *dev,
-				    int scancode, int keycode)
+				unsigned int scancode, unsigned int keycode)
 {
 	struct dvb_usb_device *d = input_get_drvdata(dev);
 
@@ -107,6 +107,7 @@ static void dvb_usb_read_remote_control(
 		case REMOTE_KEY_REPEAT:
 			deb_rc("key repeated\n");
 			input_event(d->rc_input_dev, EV_KEY, event, 1);
+			input_sync(d->rc_input_dev);
 			input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
 			input_sync(d->rc_input_dev);
 			break;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dw2102.c linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/dw2102.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dw2102.c	2013-05-03 12:04:18.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/dw2102.c	2013-05-03 09:45:11.000000000 -0400
@@ -1,6 +1,7 @@
 /* DVB USB framework compliant Linux driver for the
 *	DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
-*	TeVii S600, S630, S650 Cards
+*	TeVii S600, S630, S650,
+*	Prof 1100, 7500 Cards
 * Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by)
 *
 *	This program is free software; you can redistribute it and/or modify it
@@ -469,11 +470,13 @@ static int s6x0_i2c_transfer(struct i2c_
 								int num)
 {
 	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	struct usb_device *udev;
 	int ret = 0;
 	int len, i, j;
 
 	if (!d)
 		return -ENODEV;
+	udev = d->udev;
 	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 		return -EAGAIN;
 
@@ -488,8 +491,13 @@ static int s6x0_i2c_transfer(struct i2c_
 		}
 		case (DW2102_VOLTAGE_CTRL): {
 			u8 obuf[2];
+
+			obuf[0] = 1;
+			obuf[1] = msg[j].buf[1];/* off-on */
+			ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
+					obuf, 2, DW210X_WRITE_MSG);
 			obuf[0] = 3;
-			obuf[1] = msg[j].buf[0];
+			obuf[1] = msg[j].buf[0];/* 13v-18v */
 			ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
 					obuf, 2, DW210X_WRITE_MSG);
 			break;
@@ -527,6 +535,17 @@ static int s6x0_i2c_transfer(struct i2c_
 					i += 16;
 					len -= 16;
 				} while (len > 0);
+			} else if ((udev->descriptor.idProduct == 0x7500)
+					&& (j < (num - 1))) {
+				/* write register addr before read */
+				u8 obuf[msg[j].len + 2];
+				obuf[0] = msg[j + 1].len;
+				obuf[1] = (msg[j].addr << 1);
+				memcpy(obuf + 2, msg[j].buf, msg[j].len);
+				ret = dw210x_op_rw(d->udev, 0x92, 0, 0,
+						obuf, msg[j].len + 2,
+						DW210X_WRITE_MSG);
+				break;
 			} else {
 				/* write registers */
 				u8 obuf[msg[j].len + 2];
@@ -651,18 +670,25 @@ static int s6x0_read_mac_address(struct
 
 static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
 {
-	static u8 command_13v[1] = {0x00};
-	static u8 command_18v[1] = {0x01};
-	struct i2c_msg msg[] = {
-		{.addr = DW2102_VOLTAGE_CTRL, .flags = 0,
-			.buf = command_13v, .len = 1},
+	static u8 command_13v[] = {0x00, 0x01};
+	static u8 command_18v[] = {0x01, 0x01};
+	static u8 command_off[] = {0x00, 0x00};
+	struct i2c_msg msg = {
+		.addr = DW2102_VOLTAGE_CTRL,
+		.flags = 0,
+		.buf = command_off,
+		.len = 2,
 	};
 
 	struct dvb_usb_adapter *udev_adap =
 		(struct dvb_usb_adapter *)(fe->dvb->priv);
 	if (voltage == SEC_VOLTAGE_18)
-		msg[0].buf = command_18v;
-	i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
+		msg.buf = command_18v;
+	else if (voltage == SEC_VOLTAGE_13)
+		msg.buf = command_13v;
+
+	i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
+
 	return 0;
 }
 
@@ -735,6 +761,18 @@ static struct stv6110_config dw2104_stv6
 	.clk_div = 1,
 };
 
+static struct stv0900_config prof_7500_stv0900_config = {
+	.demod_address = 0x6a,
+	.demod_mode = 0,
+	.xtal = 27000000,
+	.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
+	.diseqc_mode = 2,/* 2/3 PWM */
+	.tun1_maddress = 0,/* 0x60 */
+	.tun1_adc = 0,/* 2 Vpp */
+	.path1_mode = 3,
+	.tun1_type = 3,
+};
+
 static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
 {
 	struct dvb_tuner_ops *tuner_ops = NULL;
@@ -882,6 +920,19 @@ static int s6x0_frontend_attach(struct d
 	return -EIO;
 }
 
+static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
+{
+	d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
+					&d->dev->i2c_adap, 0);
+	if (d->fe == NULL)
+		return -EIO;
+	d->fe->ops.set_voltage = dw210x_set_voltage;
+
+	info("Attached STV0900+STB6100A!\n");
+
+	return 0;
+}
+
 static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
 {
 	dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -1073,6 +1124,7 @@ static struct usb_device_id dw2102_table
 	{USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
 	{USB_DEVICE(0x3011, USB_PID_PROF_1100)},
 	{USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
+	{USB_DEVICE(0x3034, 0x7500)},
 	{ }
 };
 
@@ -1387,9 +1439,30 @@ static struct dvb_usb_device_properties
 	}
 };
 
+struct dvb_usb_device_properties *p7500;
+static struct dvb_usb_device_description d7500 = {
+	"Prof 7500 USB DVB-S2",
+	{&dw2102_table[9], NULL},
+	{NULL},
+};
+
 static int dw2102_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
+
+	p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
+	if (!p7500)
+		return -ENOMEM;
+	/* copy default structure */
+	memcpy(p7500, &s6x0_properties,
+			sizeof(struct dvb_usb_device_properties));
+	/* fill only different fields */
+	p7500->firmware = "/*(DEBLOBBED)*/";
+	p7500->devices[0] = d7500;
+	p7500->rc_key_map = tbs_rc_keys;
+	p7500->rc_key_map_size = ARRAY_SIZE(tbs_rc_keys);
+	p7500->adapter->frontend_attach = prof_7500_frontend_attach;
+
 	if (0 == dvb_usb_device_init(intf, &dw2102_properties,
 			THIS_MODULE, NULL, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &dw2104_properties,
@@ -1397,6 +1470,8 @@ static int dw2102_probe(struct usb_inter
 	    0 == dvb_usb_device_init(intf, &dw3101_properties,
 			THIS_MODULE, NULL, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &s6x0_properties,
+			THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, p7500,
 			THIS_MODULE, NULL, adapter_nr))
 		return 0;
 
@@ -1431,6 +1506,6 @@ MODULE_AUTHOR("Igor M. Liplianin (c) lip
 MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
 				" DVB-C 3101 USB2.0,"
 				" TeVii S600, S630, S650, S660 USB2.0,"
-				" Prof 1100 USB2.0 devices");
+				" Prof 1100, 7500 USB2.0 devices");
 MODULE_VERSION("0.1");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/friio-fe.c linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/friio-fe.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/friio-fe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/friio-fe.c	2010-05-16 17:17:36.000000000 -0400
@@ -366,7 +366,7 @@ static u8 init_code[][2] = {
 	{0x76, 0x0C},
 };
 
-const static int init_code_len = sizeof(init_code) / sizeof(u8[2]);
+static const int init_code_len = sizeof(init_code) / sizeof(u8[2]);
 
 static int jdvbt90502_init(struct dvb_frontend *fe)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/Kconfig linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -336,3 +336,11 @@ config DVB_USB_EC168
 	select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
+
+config DVB_USB_AZ6027
+	tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support"
+	depends on DVB_USB
+	select DVB_STB0899 if !DVB_FE_CUSTOMISE
+	select DVB_STB6100 if !DVB_FE_CUSTOMISE
+	help
+	  Say Y here to support the AZ6027 device
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/m920x.c linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/m920x.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/m920x.c	2013-05-03 12:04:24.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/m920x.c	2013-05-03 09:45:17.000000000 -0400
@@ -16,6 +16,9 @@
 #include "qt1010.h"
 #include "tda1004x.h"
 #include "tda827x.h"
+
+#include <media/tuner.h>
+#include "tuner-simple.h"
 #include <asm/unaligned.h>
 
 /* debug */
@@ -158,11 +161,14 @@ static int m920x_rc_query(struct dvb_usb
 
 			case 0x93:
 			case 0x92:
+			case 0x83: /* pinnacle PCTV310e */
+			case 0x82:
 				m->rep_count = 0;
 				*state = REMOTE_KEY_PRESSED;
 				goto unlock;
 
 			case 0x91:
+			case 0x81: /* pinnacle PCTV310e */
 				/* prevent immediate auto-repeat */
 				if (++m->rep_count > 2)
 					*state = REMOTE_KEY_REPEAT;
@@ -546,6 +552,14 @@ static int m920x_tda8275_61_tuner_attach
 	return 0;
 }
 
+static int m920x_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	dvb_attach(simple_tuner_attach, adap->fe,
+		   &adap->dev->i2c_adap, 0x61,
+		   TUNER_PHILIPS_FMD1216ME_MK3);
+	return 0;
+}
+
 /* device-specific initialization */
 static struct m920x_inits megasky_rc_init [] = {
 	{ M9206_RC_INIT2, 0xa8 },
@@ -562,6 +576,18 @@ static struct m920x_inits tvwalkertwin_r
 	{ } /* terminating entry */
 };
 
+static struct m920x_inits pinnacle310e_init[] = {
+	/* without these the tuner don't work */
+	{ 0xff20,         0x9b },
+	{ 0xff22,         0x70 },
+
+	/* rc settings */
+	{ 0xff50,         0x80 },
+	{ M9206_RC_INIT1, 0x00 },
+	{ M9206_RC_INIT2, 0xff },
+	{ } /* terminating entry */
+};
+
 /* ir keymaps */
 static struct dvb_usb_rc_key megasky_rc_keys [] = {
 	{ 0x0012, KEY_POWER },
@@ -602,11 +628,68 @@ static struct dvb_usb_rc_key tvwalkertwi
 	{ 0x001e, KEY_VOLUMEUP },
 };
 
+static struct dvb_usb_rc_key pinnacle310e_rc_keys[] = {
+	{ 0x16, KEY_POWER },
+	{ 0x17, KEY_FAVORITES },
+	{ 0x0f, KEY_TEXT },
+	{ 0x48, KEY_MEDIA },		/* preview */
+	{ 0x1c, KEY_EPG },
+	{ 0x04, KEY_LIST },			/* record list */
+	{ 0x03, KEY_1 },
+	{ 0x01, KEY_2 },
+	{ 0x06, KEY_3 },
+	{ 0x09, KEY_4 },
+	{ 0x1d, KEY_5 },
+	{ 0x1f, KEY_6 },
+	{ 0x0d, KEY_7 },
+	{ 0x19, KEY_8 },
+	{ 0x1b, KEY_9 },
+	{ 0x15, KEY_0 },
+	{ 0x0c, KEY_CANCEL },
+	{ 0x4a, KEY_CLEAR },
+	{ 0x13, KEY_BACK },
+	{ 0x00, KEY_TAB },
+	{ 0x4b, KEY_UP },
+	{ 0x4e, KEY_LEFT },
+	{ 0x52, KEY_RIGHT },
+	{ 0x51, KEY_DOWN },
+	{ 0x4f, KEY_ENTER },		/* could also be KEY_OK */
+	{ 0x1e, KEY_VOLUMEUP },
+	{ 0x0a, KEY_VOLUMEDOWN },
+	{ 0x05, KEY_CHANNELUP },
+	{ 0x02, KEY_CHANNELDOWN },
+	{ 0x11, KEY_RECORD },
+	{ 0x14, KEY_PLAY },
+	{ 0x4c, KEY_PAUSE },
+	{ 0x1a, KEY_STOP },
+	{ 0x40, KEY_REWIND },
+	{ 0x12, KEY_FASTFORWARD },
+	{ 0x41, KEY_PREVIOUSSONG },	/* Replay */
+	{ 0x42, KEY_NEXTSONG },		/* Skip */
+	{ 0x54, KEY_CAMERA },		/* Capture */
+/*	{ 0x50, KEY_SAP },	*/		/* Sap */
+	{ 0x47, KEY_CYCLEWINDOWS },	/* Pip */
+	{ 0x4d, KEY_SCREEN },		/* FullScreen */
+	{ 0x08, KEY_SUBTITLE },
+	{ 0x0e, KEY_MUTE },
+/*	{ 0x49, KEY_LR },	*/		/* L/R */
+	{ 0x07, KEY_SLEEP },		/* Hibernate */
+	{ 0x08, KEY_MEDIA },		/* A/V */
+	{ 0x0e, KEY_MENU },			/* Recall */
+	{ 0x45, KEY_ZOOMIN },
+	{ 0x46, KEY_ZOOMOUT },
+	{ 0x18, KEY_TV },			/* Red */
+	{ 0x53, KEY_VCR },			/* Green */
+	{ 0x5e, KEY_SAT },			/* Yellow */
+	{ 0x5f, KEY_PLAYER },		/* Blue */
+};
+
 /* DVB USB Driver stuff */
 static struct dvb_usb_device_properties megasky_properties;
 static struct dvb_usb_device_properties digivox_mini_ii_properties;
 static struct dvb_usb_device_properties tvwalkertwin_properties;
 static struct dvb_usb_device_properties dposh_properties;
+static struct dvb_usb_device_properties pinnacle_pctv310e_properties;
 
 static int m920x_probe(struct usb_interface *intf,
 		       const struct usb_device_id *id)
@@ -652,6 +735,13 @@ static int m920x_probe(struct usb_interf
 			goto found;
 		}
 
+		ret = dvb_usb_device_init(intf, &pinnacle_pctv310e_properties,
+					  THIS_MODULE, &d, adapter_nr);
+		if (ret == 0) {
+			rc_init_seq = pinnacle310e_init;
+			goto found;
+		}
+
 		return ret;
 	} else {
 		/* Another interface on a multi-tuner device */
@@ -682,6 +772,7 @@ static struct usb_device_id m920x_table
 			     USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) },
 		{ USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) },
 		{ USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) },
+		{ USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_PINNACLE_PCTV310E) },
 		{ }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE (usb, m920x_table);
@@ -895,6 +986,56 @@ static struct dvb_usb_device_properties
 	 }
 };
 
+static struct dvb_usb_device_properties pinnacle_pctv310e_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+	.usb_ctrl = DEVICE_SPECIFIC,
+	.download_firmware = NULL,
+
+	.rc_interval      = 100,
+	.rc_key_map       = pinnacle310e_rc_keys,
+	.rc_key_map_size  = ARRAY_SIZE(pinnacle310e_rc_keys),
+	.rc_query         = m920x_rc_query,
+
+	.size_of_priv     = sizeof(struct m920x_state),
+
+	.identify_state   = m920x_identify_state,
+	.num_adapters = 1,
+	.adapter = {{
+		.caps = DVB_USB_ADAP_HAS_PID_FILTER |
+			DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+		.pid_filter_count = 8,
+		.pid_filter       = m920x_pid_filter,
+		.pid_filter_ctrl  = m920x_pid_filter_ctrl,
+
+		.frontend_attach  = m920x_mt352_frontend_attach,
+		.tuner_attach     = m920x_fmd1216me_tuner_attach,
+
+		.stream = {
+			.type = USB_ISOC,
+			.count = 5,
+			.endpoint = 0x84,
+			.u = {
+				.isoc = {
+					.framesperurb = 128,
+					.framesize = 564,
+					.interval = 1,
+				}
+			}
+		},
+	} },
+	.i2c_algo         = &m920x_i2c_algo,
+
+	.num_device_descs = 1,
+	.devices = {
+		{   "Pinnacle PCTV 310e",
+			{ &m920x_table[6], NULL },
+			{ NULL },
+		}
+	}
+};
+
 static struct usb_driver m920x_driver = {
 	.name		= "dvb_usb_m920x",
 	.probe		= m920x_probe,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/m920x.h linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/m920x.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/m920x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/m920x.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,7 @@
 #define M9206_FW	0x30
 
 #define M9206_MAX_FILTERS 8
-#define M9206_MAX_ADAPTERS 2
+#define M9206_MAX_ADAPTERS 4
 
 /*
 sequences found in logs:
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/Makefile linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/Makefile
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -85,6 +85,9 @@ obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-f
 dvb-usb-ec168-objs = ec168.o
 obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
 
+dvb-usb-az6027-objs = az6027.o
+obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
+
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
 # due to tuner-xc3028
 EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/opera1.c linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/opera1.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/opera1.c	2013-05-03 12:04:28.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/dvb-usb/opera1.c	2013-05-03 09:45:21.000000000 -0400
@@ -138,7 +138,7 @@ static int opera1_i2c_xfer(struct i2c_ad
 					(msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0),
 					msg[i].buf,
 					msg[i].len
-					)!= msg[i].len)) {
+					)) != msg[i].len) {
 			break;
 		}
 		if (dvb_usb_opera1_debug & 0x10)
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-1394.c linux-libre-2.6.34-gnu1/drivers/media/dvb/firewire/firedtv-1394.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-1394.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/firewire/firedtv-1394.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
 
@@ -90,13 +91,14 @@ static inline struct node_entry *node_of
 	return container_of(fdtv->device, struct unit_directory, device)->ne;
 }
 
-static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
+static int node_lock(struct firedtv *fdtv, u64 addr, void *data)
 {
+	quadlet_t *d = data;
 	int ret;
 
-	ret = hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP,
-		(__force quadlet_t *)&data[1], (__force quadlet_t)data[0]);
-	data[0] = data[1];
+	ret = hpsb_node_lock(node_of(fdtv), addr,
+			     EXTCODE_COMPARE_SWAP, &d[1], d[0]);
+	d[0] = d[1];
 
 	return ret;
 }
@@ -192,9 +194,13 @@ static int node_probe(struct device *dev
 	int kv_len, err;
 	void *kv_str;
 
-	kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t);
-	kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv);
-
+	if (ud->model_name_kv) {
+		kv_len = (ud->model_name_kv->value.leaf.len - 2) * 4;
+		kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv);
+	} else {
+		kv_len = 0;
+		kv_str = NULL;
+	}
 	fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len);
 	if (!fdtv)
 		return -ENOMEM;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-avc.c linux-libre-2.6.34-gnu1/drivers/media/dvb/firewire/firedtv-avc.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-avc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/firewire/firedtv-avc.c	2010-05-16 17:17:36.000000000 -0400
@@ -74,7 +74,6 @@
 #define EN50221_TAG_CA_INFO		0x9f8031
 
 struct avc_command_frame {
-	int length;
 	u8 ctype;
 	u8 subunit;
 	u8 opcode;
@@ -82,13 +81,27 @@ struct avc_command_frame {
 };
 
 struct avc_response_frame {
-	int length;
 	u8 response;
 	u8 subunit;
 	u8 opcode;
 	u8 operand[509];
 };
 
+#define LAST_OPERAND (509 - 1)
+
+static inline void clear_operands(struct avc_command_frame *c, int from, int to)
+{
+	memset(&c->operand[from], 0, to - from + 1);
+}
+
+static void pad_operands(struct avc_command_frame *c, int from)
+{
+	int to = ALIGN(from, 4);
+
+	if (from <= to && to <= LAST_OPERAND)
+		clear_operands(c, from, to);
+}
+
 #define AVC_DEBUG_READ_DESCRIPTOR              0x0001
 #define AVC_DEBUG_DSIT                         0x0002
 #define AVC_DEBUG_DSD                          0x0004
@@ -202,78 +215,65 @@ static void debug_pmt(char *msg, int len
 		       16, 1, msg, length, false);
 }
 
-static int __avc_write(struct firedtv *fdtv,
-		const struct avc_command_frame *c, struct avc_response_frame *r)
+static int avc_write(struct firedtv *fdtv)
 {
 	int err, retry;
 
-	if (r)
-		fdtv->avc_reply_received = false;
+	fdtv->avc_reply_received = false;
 
 	for (retry = 0; retry < 6; retry++) {
 		if (unlikely(avc_debug))
-			debug_fcp(&c->ctype, c->length);
+			debug_fcp(fdtv->avc_data, fdtv->avc_data_length);
 
 		err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER,
-					   (void *)&c->ctype, c->length);
+				fdtv->avc_data, fdtv->avc_data_length);
 		if (err) {
-			fdtv->avc_reply_received = true;
 			dev_err(fdtv->device, "FCP command write failed\n");
+
 			return err;
 		}
 
-		if (!r)
-			return 0;
-
 		/*
 		 * AV/C specs say that answers should be sent within 150 ms.
 		 * Time out after 200 ms.
 		 */
 		if (wait_event_timeout(fdtv->avc_wait,
 				       fdtv->avc_reply_received,
-				       msecs_to_jiffies(200)) != 0) {
-			r->length = fdtv->response_length;
-			memcpy(&r->response, fdtv->response, r->length);
-
+				       msecs_to_jiffies(200)) != 0)
 			return 0;
-		}
 	}
 	dev_err(fdtv->device, "FCP response timed out\n");
+
 	return -ETIMEDOUT;
 }
 
-static int avc_write(struct firedtv *fdtv,
-		const struct avc_command_frame *c, struct avc_response_frame *r)
+static bool is_register_rc(struct avc_response_frame *r)
 {
-	int ret;
-
-	if (mutex_lock_interruptible(&fdtv->avc_mutex))
-		return -EINTR;
-
-	ret = __avc_write(fdtv, c, r);
-
-	mutex_unlock(&fdtv->avc_mutex);
-	return ret;
+	return r->opcode     == AVC_OPCODE_VENDOR &&
+	       r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 &&
+	       r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 &&
+	       r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 &&
+	       r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;
 }
 
 int avc_recv(struct firedtv *fdtv, void *data, size_t length)
 {
-	struct avc_response_frame *r =
-			data - offsetof(struct avc_response_frame, response);
+	struct avc_response_frame *r = data;
 
 	if (unlikely(avc_debug))
 		debug_fcp(data, length);
 
-	if (length >= 8 &&
-	    r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 &&
-	    r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 &&
-	    r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 &&
-	    r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) {
-		if (r->response == AVC_RESPONSE_CHANGED) {
-			fdtv_handle_rc(fdtv,
-			    r->operand[4] << 8 | r->operand[5]);
+	if (length >= 8 && is_register_rc(r)) {
+		switch (r->response) {
+		case AVC_RESPONSE_CHANGED:
+			fdtv_handle_rc(fdtv, r->operand[4] << 8 | r->operand[5]);
 			schedule_work(&fdtv->remote_ctrl_work);
-		} else if (r->response != AVC_RESPONSE_INTERIM) {
+			break;
+		case AVC_RESPONSE_INTERIM:
+			if (is_register_rc((void *)fdtv->avc_data))
+				goto wake;
+			break;
+		default:
 			dev_info(fdtv->device,
 				 "remote control result = %d\n", r->response);
 		}
@@ -285,9 +285,9 @@ int avc_recv(struct firedtv *fdtv, void
 		return -EIO;
 	}
 
-	memcpy(fdtv->response, data, length);
-	fdtv->response_length = length;
-
+	memcpy(fdtv->avc_data, data, length);
+	fdtv->avc_data_length = length;
+wake:
 	fdtv->avc_reply_received = true;
 	wake_up(&fdtv->avc_wait);
 
@@ -318,10 +318,11 @@ static int add_pid_filter(struct firedtv
  * tuning command for setting the relative LNB frequency
  * (not supported by the AVC standard)
  */
-static void avc_tuner_tuneqpsk(struct firedtv *fdtv,
-			       struct dvb_frontend_parameters *params,
-			       struct avc_command_frame *c)
+static int avc_tuner_tuneqpsk(struct firedtv *fdtv,
+			      struct dvb_frontend_parameters *params)
 {
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+
 	c->opcode = AVC_OPCODE_VENDOR;
 
 	c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
@@ -370,16 +371,18 @@ static void avc_tuner_tuneqpsk(struct fi
 		c->operand[13] = 0x1;
 		c->operand[14] = 0xff;
 		c->operand[15] = 0xff;
-		c->length = 20;
+
+		return 16;
 	} else {
-		c->length = 16;
+		return 13;
 	}
 }
 
-static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv,
-				struct dvb_frontend_parameters *params,
-				struct avc_command_frame *c)
+static int avc_tuner_dsd_dvb_c(struct firedtv *fdtv,
+			       struct dvb_frontend_parameters *params)
 {
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+
 	c->opcode = AVC_OPCODE_DSD;
 
 	c->operand[0] = 0;    /* source plug */
@@ -440,15 +443,14 @@ static void avc_tuner_dsd_dvb_c(struct f
 	c->operand[20] = 0x00;
 	c->operand[21] = 0x00;
 
-	/* Add PIDs to filter */
-	c->length = ALIGN(22 + add_pid_filter(fdtv, &c->operand[22]) + 3, 4);
+	return 22 + add_pid_filter(fdtv, &c->operand[22]);
 }
 
-static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv,
-				struct dvb_frontend_parameters *params,
-				struct avc_command_frame *c)
+static int avc_tuner_dsd_dvb_t(struct firedtv *fdtv,
+			       struct dvb_frontend_parameters *params)
 {
 	struct dvb_ofdm_parameters *ofdm = &params->u.ofdm;
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
 
 	c->opcode = AVC_OPCODE_DSD;
 
@@ -543,55 +545,58 @@ static void avc_tuner_dsd_dvb_t(struct f
 	c->operand[15] = 0x00; /* network_ID[0] */
 	c->operand[16] = 0x00; /* network_ID[1] */
 
-	/* Add PIDs to filter */
-	c->length = ALIGN(17 + add_pid_filter(fdtv, &c->operand[17]) + 3, 4);
+	return 17 + add_pid_filter(fdtv, &c->operand[17]);
 }
 
 int avc_tuner_dsd(struct firedtv *fdtv,
 		  struct dvb_frontend_parameters *params)
 {
-	char buffer[sizeof(struct avc_command_frame)];
-	struct avc_command_frame *c = (void *)buffer;
-	struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+	int pos, ret;
 
-	memset(c, 0, sizeof(*c));
+	mutex_lock(&fdtv->avc_mutex);
 
 	c->ctype   = AVC_CTYPE_CONTROL;
 	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
 
 	switch (fdtv->type) {
 	case FIREDTV_DVB_S:
-	case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break;
-	case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(fdtv, params, c); break;
-	case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(fdtv, params, c); break;
+	case FIREDTV_DVB_S2: pos = avc_tuner_tuneqpsk(fdtv, params); break;
+	case FIREDTV_DVB_C: pos = avc_tuner_dsd_dvb_c(fdtv, params); break;
+	case FIREDTV_DVB_T: pos = avc_tuner_dsd_dvb_t(fdtv, params); break;
 	default:
 		BUG();
 	}
+	pad_operands(c, pos);
 
-	if (avc_write(fdtv, c, r) < 0)
-		return -EIO;
-
-	msleep(500);
+	fdtv->avc_data_length = ALIGN(3 + pos, 4);
+	ret = avc_write(fdtv);
 #if 0
-	/* FIXME: */
-	/* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */
+	/*
+	 * FIXME:
+	 * u8 *status was an out-parameter of avc_tuner_dsd, unused by caller.
+	 * Check for AVC_RESPONSE_ACCEPTED here instead?
+	 */
 	if (status)
 		*status = r->operand[2];
 #endif
-	return 0;
+	mutex_unlock(&fdtv->avc_mutex);
+
+	if (ret == 0)
+		msleep(500);
+
+	return ret;
 }
 
 int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[])
 {
-	char buffer[sizeof(struct avc_command_frame)];
-	struct avc_command_frame *c = (void *)buffer;
-	struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
-	int pos, k;
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+	int ret, pos, k;
 
 	if (pidc > 16 && pidc != 0xff)
 		return -EINVAL;
 
-	memset(c, 0, sizeof(*c));
+	mutex_lock(&fdtv->avc_mutex);
 
 	c->ctype   = AVC_CTYPE_CONTROL;
 	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -614,24 +619,27 @@ int avc_tuner_set_pids(struct firedtv *f
 			c->operand[pos++] = 0x00; /* tableID */
 			c->operand[pos++] = 0x00; /* filter_length */
 		}
+	pad_operands(c, pos);
 
-	c->length = ALIGN(3 + pos, 4);
+	fdtv->avc_data_length = ALIGN(3 + pos, 4);
+	ret = avc_write(fdtv);
 
-	if (avc_write(fdtv, c, r) < 0)
-		return -EIO;
+	/* FIXME: check response code? */
 
-	msleep(50);
-	return 0;
+	mutex_unlock(&fdtv->avc_mutex);
+
+	if (ret == 0)
+		msleep(50);
+
+	return ret;
 }
 
 int avc_tuner_get_ts(struct firedtv *fdtv)
 {
-	char buffer[sizeof(struct avc_command_frame)];
-	struct avc_command_frame *c = (void *)buffer;
-	struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
-	int sl;
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+	int ret, sl;
 
-	memset(c, 0, sizeof(*c));
+	mutex_lock(&fdtv->avc_mutex);
 
 	c->ctype   = AVC_CTYPE_CONTROL;
 	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -646,26 +654,33 @@ int avc_tuner_get_ts(struct firedtv *fdt
 	c->operand[4] = 0x00;	/* antenna number */
 	c->operand[5] = 0x0; 	/* system_specific_search_flags */
 	c->operand[6] = sl;	/* system_specific_multiplex selection_length */
-	c->operand[7] = 0x00;	/* valid_flags [0] */
-	c->operand[8] = 0x00;	/* valid_flags [1] */
-	c->operand[7 + sl] = 0x00; /* nr_of_dsit_sel_specs (always 0) */
+	/*
+	 * operand[7]: valid_flags[0]
+	 * operand[8]: valid_flags[1]
+	 * operand[7 + sl]: nr_of_dsit_sel_specs (always 0)
+	 */
+	clear_operands(c, 7, 24);
 
-	c->length = fdtv->type == FIREDTV_DVB_T ? 24 : 28;
+	fdtv->avc_data_length = fdtv->type == FIREDTV_DVB_T ? 24 : 28;
+	ret = avc_write(fdtv);
 
-	if (avc_write(fdtv, c, r) < 0)
-		return -EIO;
+	/* FIXME: check response code? */
 
-	msleep(250);
-	return 0;
+	mutex_unlock(&fdtv->avc_mutex);
+
+	if (ret == 0)
+		msleep(250);
+
+	return ret;
 }
 
 int avc_identify_subunit(struct firedtv *fdtv)
 {
-	char buffer[sizeof(struct avc_command_frame)];
-	struct avc_command_frame *c = (void *)buffer;
-	struct avc_response_frame *r = (void *)buffer;
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+	struct avc_response_frame *r = (void *)fdtv->avc_data;
+	int ret;
 
-	memset(c, 0, sizeof(*c));
+	mutex_lock(&fdtv->avc_mutex);
 
 	c->ctype   = AVC_CTYPE_CONTROL;
 	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -678,31 +693,34 @@ int avc_identify_subunit(struct firedtv
 	c->operand[4] = 0x08; /* length lowbyte  */
 	c->operand[5] = 0x00; /* offset highbyte */
 	c->operand[6] = 0x0d; /* offset lowbyte  */
+	clear_operands(c, 7, 8); /* padding */
 
-	c->length = 12;
-
-	if (avc_write(fdtv, c, r) < 0)
-		return -EIO;
+	fdtv->avc_data_length = 12;
+	ret = avc_write(fdtv);
+	if (ret < 0)
+		goto out;
 
 	if ((r->response != AVC_RESPONSE_STABLE &&
 	     r->response != AVC_RESPONSE_ACCEPTED) ||
 	    (r->operand[3] << 8) + r->operand[4] != 8) {
 		dev_err(fdtv->device, "cannot read subunit identifier\n");
-		return -EINVAL;
+		ret = -EINVAL;
 	}
-	return 0;
+out:
+	mutex_unlock(&fdtv->avc_mutex);
+
+	return ret;
 }
 
 #define SIZEOF_ANTENNA_INPUT_INFO 22
 
 int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat)
 {
-	char buffer[sizeof(struct avc_command_frame)];
-	struct avc_command_frame *c = (void *)buffer;
-	struct avc_response_frame *r = (void *)buffer;
-	int length;
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+	struct avc_response_frame *r = (void *)fdtv->avc_data;
+	int length, ret;
 
-	memset(c, 0, sizeof(*c));
+	mutex_lock(&fdtv->avc_mutex);
 
 	c->ctype   = AVC_CTYPE_CONTROL;
 	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -710,27 +728,30 @@ int avc_tuner_status(struct firedtv *fdt
 
 	c->operand[0] = DESCRIPTOR_TUNER_STATUS;
 	c->operand[1] = 0xff;	/* read_result_status */
-	c->operand[2] = 0x00;	/* reserved */
-	c->operand[3] = 0;	/* SIZEOF_ANTENNA_INPUT_INFO >> 8; */
-	c->operand[4] = 0;	/* SIZEOF_ANTENNA_INPUT_INFO & 0xff; */
-	c->operand[5] = 0x00;
-	c->operand[6] = 0x00;
-
-	c->length = 12;
+	/*
+	 * operand[2]: reserved
+	 * operand[3]: SIZEOF_ANTENNA_INPUT_INFO >> 8
+	 * operand[4]: SIZEOF_ANTENNA_INPUT_INFO & 0xff
+	 */
+	clear_operands(c, 2, 31);
 
-	if (avc_write(fdtv, c, r) < 0)
-		return -EIO;
+	fdtv->avc_data_length = 12;
+	ret = avc_write(fdtv);
+	if (ret < 0)
+		goto out;
 
 	if (r->response != AVC_RESPONSE_STABLE &&
 	    r->response != AVC_RESPONSE_ACCEPTED) {
 		dev_err(fdtv->device, "cannot read tuner status\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 
 	length = r->operand[9];
 	if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) {
 		dev_err(fdtv->device, "got invalid tuner status\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 
 	stat->active_system		= r->operand[10];
@@ -766,20 +787,21 @@ int avc_tuner_status(struct firedtv *fdt
 	stat->ca_dvb_flag		= r->operand[31] >> 3 & 1;
 	stat->ca_error_flag		= r->operand[31] >> 2 & 1;
 	stat->ca_initialization_status	= r->operand[31] >> 1 & 1;
+out:
+	mutex_unlock(&fdtv->avc_mutex);
 
-	return 0;
+	return ret;
 }
 
 int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst,
 		    char conttone, char nrdiseq,
 		    struct dvb_diseqc_master_cmd *diseqcmd)
 {
-	char buffer[sizeof(struct avc_command_frame)];
-	struct avc_command_frame *c = (void *)buffer;
-	struct avc_response_frame *r = (void *)buffer;
-	int i, j, k;
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+	struct avc_response_frame *r = (void *)fdtv->avc_data;
+	int pos, j, k, ret;
 
-	memset(c, 0, sizeof(*c));
+	mutex_lock(&fdtv->avc_mutex);
 
 	c->ctype   = AVC_CTYPE_CONTROL;
 	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -789,41 +811,41 @@ int avc_lnb_control(struct firedtv *fdtv
 	c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
 	c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
 	c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL;
-
 	c->operand[4] = voltage;
 	c->operand[5] = nrdiseq;
 
-	i = 6;
-
+	pos = 6;
 	for (j = 0; j < nrdiseq; j++) {
-		c->operand[i++] = diseqcmd[j].msg_len;
+		c->operand[pos++] = diseqcmd[j].msg_len;
 
 		for (k = 0; k < diseqcmd[j].msg_len; k++)
-			c->operand[i++] = diseqcmd[j].msg[k];
+			c->operand[pos++] = diseqcmd[j].msg[k];
 	}
+	c->operand[pos++] = burst;
+	c->operand[pos++] = conttone;
+	pad_operands(c, pos);
 
-	c->operand[i++] = burst;
-	c->operand[i++] = conttone;
-
-	c->length = ALIGN(3 + i, 4);
-
-	if (avc_write(fdtv, c, r) < 0)
-		return -EIO;
+	fdtv->avc_data_length = ALIGN(3 + pos, 4);
+	ret = avc_write(fdtv);
+	if (ret < 0)
+		goto out;
 
 	if (r->response != AVC_RESPONSE_ACCEPTED) {
 		dev_err(fdtv->device, "LNB control failed\n");
-		return -EINVAL;
+		ret = -EINVAL;
 	}
+out:
+	mutex_unlock(&fdtv->avc_mutex);
 
-	return 0;
+	return ret;
 }
 
 int avc_register_remote_control(struct firedtv *fdtv)
 {
-	char buffer[sizeof(struct avc_command_frame)];
-	struct avc_command_frame *c = (void *)buffer;
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+	int ret;
 
-	memset(c, 0, sizeof(*c));
+	mutex_lock(&fdtv->avc_mutex);
 
 	c->ctype   = AVC_CTYPE_NOTIFY;
 	c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7;
@@ -833,10 +855,16 @@ int avc_register_remote_control(struct f
 	c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
 	c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
 	c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;
+	c->operand[4] = 0; /* padding */
 
-	c->length = 8;
+	fdtv->avc_data_length = 8;
+	ret = avc_write(fdtv);
 
-	return avc_write(fdtv, c, NULL);
+	/* FIXME: check response code? */
+
+	mutex_unlock(&fdtv->avc_mutex);
+
+	return ret;
 }
 
 void avc_remote_ctrl_work(struct work_struct *work)
@@ -851,11 +879,10 @@ void avc_remote_ctrl_work(struct work_st
 #if 0 /* FIXME: unused */
 int avc_tuner_host2ca(struct firedtv *fdtv)
 {
-	char buffer[sizeof(struct avc_command_frame)];
-	struct avc_command_frame *c = (void *)buffer;
-	struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+	int ret;
 
-	memset(c, 0, sizeof(*c));
+	mutex_lock(&fdtv->avc_mutex);
 
 	c->ctype   = AVC_CTYPE_CONTROL;
 	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -867,15 +894,16 @@ int avc_tuner_host2ca(struct firedtv *fd
 	c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
 	c->operand[4] = 0; /* slot */
 	c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
-	c->operand[6] = 0; /* more/last */
-	c->operand[7] = 0; /* length */
+	clear_operands(c, 6, 8);
 
-	c->length = 12;
+	fdtv->avc_data_length = 12;
+	ret = avc_write(fdtv);
 
-	if (avc_write(fdtv, c, r) < 0)
-		return -EIO;
+	/* FIXME: check response code? */
 
-	return 0;
+	mutex_unlock(&fdtv->avc_mutex);
+
+	return ret;
 }
 #endif
 
@@ -906,12 +934,11 @@ static int get_ca_object_length(struct a
 
 int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
 {
-	char buffer[sizeof(struct avc_command_frame)];
-	struct avc_command_frame *c = (void *)buffer;
-	struct avc_response_frame *r = (void *)buffer;
-	int pos;
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+	struct avc_response_frame *r = (void *)fdtv->avc_data;
+	int pos, ret;
 
-	memset(c, 0, sizeof(*c));
+	mutex_lock(&fdtv->avc_mutex);
 
 	c->ctype   = AVC_CTYPE_STATUS;
 	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -923,11 +950,12 @@ int avc_ca_app_info(struct firedtv *fdtv
 	c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
 	c->operand[4] = 0; /* slot */
 	c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
+	clear_operands(c, 6, LAST_OPERAND);
 
-	c->length = 12;
-
-	if (avc_write(fdtv, c, r) < 0)
-		return -EIO;
+	fdtv->avc_data_length = 12;
+	ret = avc_write(fdtv);
+	if (ret < 0)
+		goto out;
 
 	/* FIXME: check response code and validate response data */
 
@@ -939,18 +967,19 @@ int avc_ca_app_info(struct firedtv *fdtv
 	app_info[4] = 0x01;
 	memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]);
 	*len = app_info[3] + 4;
+out:
+	mutex_unlock(&fdtv->avc_mutex);
 
-	return 0;
+	return ret;
 }
 
 int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
 {
-	char buffer[sizeof(struct avc_command_frame)];
-	struct avc_command_frame *c = (void *)buffer;
-	struct avc_response_frame *r = (void *)buffer;
-	int pos;
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+	struct avc_response_frame *r = (void *)fdtv->avc_data;
+	int pos, ret;
 
-	memset(c, 0, sizeof(*c));
+	mutex_lock(&fdtv->avc_mutex);
 
 	c->ctype   = AVC_CTYPE_STATUS;
 	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -962,11 +991,14 @@ int avc_ca_info(struct firedtv *fdtv, ch
 	c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
 	c->operand[4] = 0; /* slot */
 	c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
+	clear_operands(c, 6, LAST_OPERAND);
 
-	c->length = 12;
+	fdtv->avc_data_length = 12;
+	ret = avc_write(fdtv);
+	if (ret < 0)
+		goto out;
 
-	if (avc_write(fdtv, c, r) < 0)
-		return -EIO;
+	/* FIXME: check response code and validate response data */
 
 	pos = get_ca_object_pos(r);
 	app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff;
@@ -976,17 +1008,18 @@ int avc_ca_info(struct firedtv *fdtv, ch
 	app_info[4] = r->operand[pos + 0];
 	app_info[5] = r->operand[pos + 1];
 	*len = app_info[3] + 4;
+out:
+	mutex_unlock(&fdtv->avc_mutex);
 
-	return 0;
+	return ret;
 }
 
 int avc_ca_reset(struct firedtv *fdtv)
 {
-	char buffer[sizeof(struct avc_command_frame)];
-	struct avc_command_frame *c = (void *)buffer;
-	struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+	int ret;
 
-	memset(c, 0, sizeof(*c));
+	mutex_lock(&fdtv->avc_mutex);
 
 	c->ctype   = AVC_CTYPE_CONTROL;
 	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -1002,19 +1035,20 @@ int avc_ca_reset(struct firedtv *fdtv)
 	c->operand[7] = 1; /* length */
 	c->operand[8] = 0; /* force hardware reset */
 
-	c->length = 12;
+	fdtv->avc_data_length = 12;
+	ret = avc_write(fdtv);
 
-	if (avc_write(fdtv, c, r) < 0)
-		return -EIO;
+	/* FIXME: check response code? */
 
-	return 0;
+	mutex_unlock(&fdtv->avc_mutex);
+
+	return ret;
 }
 
 int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
 {
-	char buffer[sizeof(struct avc_command_frame)];
-	struct avc_command_frame *c = (void *)buffer;
-	struct avc_response_frame *r = (void *)buffer;
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+	struct avc_response_frame *r = (void *)fdtv->avc_data;
 	int list_management;
 	int program_info_length;
 	int pmt_cmd_id;
@@ -1022,11 +1056,12 @@ int avc_ca_pmt(struct firedtv *fdtv, cha
 	int write_pos;
 	int es_info_length;
 	int crc32_csum;
+	int ret;
 
 	if (unlikely(avc_debug & AVC_DEBUG_APPLICATION_PMT))
 		debug_pmt(msg, length);
 
-	memset(c, 0, sizeof(*c));
+	mutex_lock(&fdtv->avc_mutex);
 
 	c->ctype   = AVC_CTYPE_CONTROL;
 	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -1058,7 +1093,7 @@ int avc_ca_pmt(struct firedtv *fdtv, cha
 
 	c->operand[12] = 0x02; /* Table id=2 */
 	c->operand[13] = 0x80; /* Section syntax + length */
-	/* c->operand[14] = XXXprogram_info_length + 12; */
+
 	c->operand[15] = msg[1]; /* Program number */
 	c->operand[16] = msg[2];
 	c->operand[17] = 0x01; /* Version number=0 + current/next=1 */
@@ -1106,12 +1141,7 @@ int avc_ca_pmt(struct firedtv *fdtv, cha
 			write_pos += es_info_length;
 		}
 	}
-
-	/* CRC */
-	c->operand[write_pos++] = 0x00;
-	c->operand[write_pos++] = 0x00;
-	c->operand[write_pos++] = 0x00;
-	c->operand[write_pos++] = 0x00;
+	write_pos += 4; /* CRC */
 
 	c->operand[7] = 0x82;
 	c->operand[8] = (write_pos - 10) >> 8;
@@ -1123,28 +1153,31 @@ int avc_ca_pmt(struct firedtv *fdtv, cha
 	c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff;
 	c->operand[write_pos - 2] = (crc32_csum >>  8) & 0xff;
 	c->operand[write_pos - 1] = (crc32_csum >>  0) & 0xff;
+	pad_operands(c, write_pos);
 
-	c->length = ALIGN(3 + write_pos, 4);
-
-	if (avc_write(fdtv, c, r) < 0)
-		return -EIO;
+	fdtv->avc_data_length = ALIGN(3 + write_pos, 4);
+	ret = avc_write(fdtv);
+	if (ret < 0)
+		goto out;
 
 	if (r->response != AVC_RESPONSE_ACCEPTED) {
 		dev_err(fdtv->device,
 			"CA PMT failed with response 0x%x\n", r->response);
-		return -EFAULT;
+		ret = -EFAULT;
 	}
+out:
+	mutex_unlock(&fdtv->avc_mutex);
 
-	return 0;
+	return ret;
 }
 
 int avc_ca_get_time_date(struct firedtv *fdtv, int *interval)
 {
-	char buffer[sizeof(struct avc_command_frame)];
-	struct avc_command_frame *c = (void *)buffer;
-	struct avc_response_frame *r = (void *)buffer;
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+	struct avc_response_frame *r = (void *)fdtv->avc_data;
+	int ret;
 
-	memset(c, 0, sizeof(*c));
+	mutex_lock(&fdtv->avc_mutex);
 
 	c->ctype   = AVC_CTYPE_STATUS;
 	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -1156,28 +1189,28 @@ int avc_ca_get_time_date(struct firedtv
 	c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
 	c->operand[4] = 0; /* slot */
 	c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */
-	c->operand[6] = 0; /* more/last */
-	c->operand[7] = 0; /* length */
-
-	c->length = 12;
+	clear_operands(c, 6, LAST_OPERAND);
 
-	if (avc_write(fdtv, c, r) < 0)
-		return -EIO;
+	fdtv->avc_data_length = 12;
+	ret = avc_write(fdtv);
+	if (ret < 0)
+		goto out;
 
 	/* FIXME: check response code and validate response data */
 
 	*interval = r->operand[get_ca_object_pos(r)];
+out:
+	mutex_unlock(&fdtv->avc_mutex);
 
-	return 0;
+	return ret;
 }
 
 int avc_ca_enter_menu(struct firedtv *fdtv)
 {
-	char buffer[sizeof(struct avc_command_frame)];
-	struct avc_command_frame *c = (void *)buffer;
-	struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+	int ret;
 
-	memset(c, 0, sizeof(*c));
+	mutex_lock(&fdtv->avc_mutex);
 
 	c->ctype   = AVC_CTYPE_STATUS;
 	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -1189,24 +1222,25 @@ int avc_ca_enter_menu(struct firedtv *fd
 	c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
 	c->operand[4] = 0; /* slot */
 	c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU;
-	c->operand[6] = 0; /* more/last */
-	c->operand[7] = 0; /* length */
+	clear_operands(c, 6, 8);
 
-	c->length = 12;
+	fdtv->avc_data_length = 12;
+	ret = avc_write(fdtv);
 
-	if (avc_write(fdtv, c, r) < 0)
-		return -EIO;
+	/* FIXME: check response code? */
 
-	return 0;
+	mutex_unlock(&fdtv->avc_mutex);
+
+	return ret;
 }
 
 int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len)
 {
-	char buffer[sizeof(struct avc_command_frame)];
-	struct avc_command_frame *c = (void *)buffer;
-	struct avc_response_frame *r = (void *)buffer;
+	struct avc_command_frame *c = (void *)fdtv->avc_data;
+	struct avc_response_frame *r = (void *)fdtv->avc_data;
+	int ret;
 
-	memset(c, 0, sizeof(*c));
+	mutex_lock(&fdtv->avc_mutex);
 
 	c->ctype   = AVC_CTYPE_STATUS;
 	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -1218,20 +1252,21 @@ int avc_ca_get_mmi(struct firedtv *fdtv,
 	c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
 	c->operand[4] = 0; /* slot */
 	c->operand[5] = SFE_VENDOR_TAG_CA_MMI;
-	c->operand[6] = 0; /* more/last */
-	c->operand[7] = 0; /* length */
-
-	c->length = 12;
+	clear_operands(c, 6, LAST_OPERAND);
 
-	if (avc_write(fdtv, c, r) < 0)
-		return -EIO;
+	fdtv->avc_data_length = 12;
+	ret = avc_write(fdtv);
+	if (ret < 0)
+		goto out;
 
 	/* FIXME: check response code and validate response data */
 
 	*len = get_ca_object_length(r);
 	memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len);
+out:
+	mutex_unlock(&fdtv->avc_mutex);
 
-	return 0;
+	return ret;
 }
 
 #define CMP_OUTPUT_PLUG_CONTROL_REG_0	0xfffff0000904ULL
@@ -1240,14 +1275,14 @@ static int cmp_read(struct firedtv *fdtv
 {
 	int ret;
 
-	if (mutex_lock_interruptible(&fdtv->avc_mutex))
-		return -EINTR;
+	mutex_lock(&fdtv->avc_mutex);
 
 	ret = fdtv->backend->read(fdtv, addr, data);
 	if (ret < 0)
 		dev_err(fdtv->device, "CMP: read I/O error\n");
 
 	mutex_unlock(&fdtv->avc_mutex);
+
 	return ret;
 }
 
@@ -1255,14 +1290,19 @@ static int cmp_lock(struct firedtv *fdtv
 {
 	int ret;
 
-	if (mutex_lock_interruptible(&fdtv->avc_mutex))
-		return -EINTR;
+	mutex_lock(&fdtv->avc_mutex);
 
-	ret = fdtv->backend->lock(fdtv, addr, data);
+	/* data[] is stack-allocated and should not be DMA-mapped. */
+	memcpy(fdtv->avc_data, data, 8);
+
+	ret = fdtv->backend->lock(fdtv, addr, fdtv->avc_data);
 	if (ret < 0)
 		dev_err(fdtv->device, "CMP: lock I/O error\n");
+	else
+		memcpy(data, fdtv->avc_data, 8);
 
 	mutex_unlock(&fdtv->avc_mutex);
+
 	return ret;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-dvb.c linux-libre-2.6.34-gnu1/drivers/media/dvb/firewire/firedtv-dvb.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-dvb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/firewire/firedtv-dvb.c	2010-05-16 17:17:36.000000000 -0400
@@ -277,7 +277,6 @@ struct firedtv *fdtv_alloc(struct device
 
 	mutex_init(&fdtv->avc_mutex);
 	init_waitqueue_head(&fdtv->avc_wait);
-	fdtv->avc_reply_received = true;
 	mutex_init(&fdtv->demux_mutex);
 	INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-fw.c linux-libre-2.6.34-gnu1/drivers/media/dvb/firewire/firedtv-fw.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-fw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/firewire/firedtv-fw.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,7 @@ static int node_req(struct firedtv *fdtv
 	return rcode != RCODE_COMPLETE ? -EIO : 0;
 }
 
-static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
+static int node_lock(struct firedtv *fdtv, u64 addr, void *data)
 {
 	return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP);
 }
@@ -239,47 +239,18 @@ static const struct fw_address_region fc
 };
 
 /* Adjust the template string if models with longer names appear. */
-#define MAX_MODEL_NAME_LEN ((int)DIV_ROUND_UP(sizeof("FireDTV ????"), 4))
-
-static size_t model_name(u32 *directory, __be32 *buffer)
-{
-	struct fw_csr_iterator ci;
-	int i, length, key, value, last_key = 0;
-	u32 *block = NULL;
-
-	fw_csr_iterator_init(&ci, directory);
-	while (fw_csr_iterator_next(&ci, &key, &value)) {
-		if (last_key == CSR_MODEL &&
-		    key == (CSR_DESCRIPTOR | CSR_LEAF))
-			block = ci.p - 1 + value;
-		last_key = key;
-	}
-
-	if (block == NULL)
-		return 0;
-
-	length = min((int)(block[0] >> 16) - 2, MAX_MODEL_NAME_LEN);
-	if (length <= 0)
-		return 0;
-
-	/* fast-forward to text string */
-	block += 3;
-
-	for (i = 0; i < length; i++)
-		buffer[i] = cpu_to_be32(block[i]);
-
-	return length * 4;
-}
+#define MAX_MODEL_NAME_LEN sizeof("FireDTV ????")
 
 static int node_probe(struct device *dev)
 {
 	struct firedtv *fdtv;
-	__be32 name[MAX_MODEL_NAME_LEN];
+	char name[MAX_MODEL_NAME_LEN];
 	int name_len, err;
 
-	name_len = model_name(fw_unit(dev)->directory, name);
+	name_len = fw_csr_string(fw_unit(dev)->directory, CSR_MODEL,
+				 name, sizeof(name));
 
-	fdtv = fdtv_alloc(dev, &backend, (char *)name, name_len);
+	fdtv = fdtv_alloc(dev, &backend, name, name_len >= 0 ? name_len : 0);
 	if (!fdtv)
 		return -ENOMEM;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv.h linux-libre-2.6.34-gnu1/drivers/media/dvb/firewire/firedtv.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/firewire/firedtv.h	2010-05-16 17:17:36.000000000 -0400
@@ -73,7 +73,7 @@ struct input_dev;
 struct firedtv;
 
 struct firedtv_backend {
-	int (*lock)(struct firedtv *fdtv, u64 addr, __be32 data[]);
+	int (*lock)(struct firedtv *fdtv, u64 addr, void *data);
 	int (*read)(struct firedtv *fdtv, u64 addr, void *data);
 	int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
 	int (*start_iso)(struct firedtv *fdtv);
@@ -114,8 +114,8 @@ struct firedtv {
 	unsigned long		channel_active;
 	u16			channel_pid[16];
 
-	size_t			response_length;
-	u8			response[512];
+	int			avc_data_length;
+	u8			avc_data[512];
 };
 
 /* firedtv-1394.c */
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-rc.c linux-libre-2.6.34-gnu1/drivers/media/dvb/firewire/firedtv-rc.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-rc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/firewire/firedtv-rc.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/bitops.h>
 #include <linux/input.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/af9013.h linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/af9013.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/af9013.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/af9013.h	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,7 @@ enum af9013_tuner {
 	AF9013_TUNER_MT2060_2   = 147, /* Microtune */
 	AF9013_TUNER_TDA18271   = 156, /* NXP */
 	AF9013_TUNER_QT1010A    = 162, /* Quantek */
+	AF9013_TUNER_TDA18218   = 179, /* NXP */
 };
 
 /* AF9013/5 GPIOs (mostly guessed)
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/atbm8830.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/atbm8830.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/atbm8830.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/atbm8830.c	2010-05-16 17:17:36.000000000 -0400
@@ -170,6 +170,19 @@ static int is_locked(struct atbm_state *
 	return 0;
 }
 
+static int set_agc_config(struct atbm_state *priv,
+	u8 min, u8 max, u8 hold_loop)
+{
+	/* no effect if both min and max are zero */
+	if (!min && !max)
+	    return 0;
+
+	atbm8830_write_reg(priv, REG_AGC_MIN, min);
+	atbm8830_write_reg(priv, REG_AGC_MAX, max);
+	atbm8830_write_reg(priv, REG_AGC_HOLD_LOOP, hold_loop);
+
+	return 0;
+}
 
 static int set_static_channel_mode(struct atbm_state *priv)
 {
@@ -227,6 +240,9 @@ static int atbm8830_init(struct dvb_fron
 	/*Set IF frequency*/
 	set_if_freq(priv, cfg->if_freq);
 
+	/*Set AGC Config*/
+	set_agc_config(priv, cfg->agc_min, cfg->agc_max,
+		cfg->agc_hold_loop);
 
 	/*Set static channel mode*/
 	set_static_channel_mode(priv);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/au8522_dig.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/au8522_dig.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/au8522_dig.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/au8522_dig.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #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"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib0070.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dib0070.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib0070.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dib0070.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 
 #include "dvb_frontend.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib0090.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dib0090.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib0090.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dib0090.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 
 #include "dvb_frontend.h"
@@ -283,7 +284,7 @@ static int dib0090_sleep(struct dvb_fron
 	return 0;
 }
 
-extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
+void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
 {
 	struct dib0090_state *state = fe->tuner_priv;
 	if (fast)
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib3000mc.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dib3000mc.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib3000mc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dib3000mc.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 
 #include "dvb_frontend.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib7000m.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dib7000m.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib7000m.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dib7000m.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  *	published by the Free Software Foundation, version 2.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 
 #include "dvb_frontend.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib7000p.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dib7000p.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib7000p.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dib7000p.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  *	published by the Free Software Foundation, version 2.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 
 #include "dvb_math.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib8000.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dib8000.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib8000.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dib8000.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  *  published by the Free Software Foundation, version 2.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include "dvb_math.h"
 
@@ -1999,6 +2000,8 @@ static int dib8000_set_frontend(struct d
 	struct dib8000_state *state = fe->demodulator_priv;
 	int time, ret;
 
+	fe->dtv_property_cache.delivery_system = SYS_ISDBT;
+
 	dib8000_set_output_mode(state, OUTMODE_HIGH_Z);
 
 	if (fe->ops.tuner_ops.set_params)
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dibx000_common.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dibx000_common.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dibx000_common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dibx000_common.c	2010-05-16 17:17:36.000000000 -0400
@@ -174,7 +174,7 @@ void dibx000_exit_i2c_master(struct dibx
 EXPORT_SYMBOL(dibx000_exit_i2c_master);
 
 
-u32 systime()
+u32 systime(void)
 {
     struct timespec t;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/drx397xD.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/drx397xD.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/drx397xD.c	2013-05-03 12:04:57.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/drx397xD.c	2013-05-03 09:45:49.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <asm/div64.h>
 
 #include "dvb_frontend.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dvb-pll.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dvb-pll.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dvb-pll.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/dvb-pll.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/dvb/frontend.h>
 #include <asm/types.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/itd1000.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/itd1000.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/itd1000.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/itd1000.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/lgdt3304.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/lgdt3304.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/lgdt3304.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/lgdt3304.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include "dvb_frontend.h"
 #include "lgdt3304.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/lgdt3305.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/lgdt3305.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/lgdt3305.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/lgdt3305.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 
 #include <asm/div64.h>
 #include <linux/dvb/frontend.h>
+#include <linux/slab.h>
 #include "dvb_math.h"
 #include "lgdt3305.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/lnbp21.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/lnbp21.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/lnbp21.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/lnbp21.c	2010-05-16 17:17:36.000000000 -0400
@@ -158,7 +158,8 @@ static struct dvb_frontend *lnbx2x_attac
 	/* override frontend ops */
 	fe->ops.set_voltage = lnbp21_set_voltage;
 	fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
-	fe->ops.set_tone = lnbp21_set_tone;
+	if (!(override_clear & LNBH24_TEN)) /*22kHz logic controlled by demod*/
+		fe->ops.set_tone = lnbp21_set_tone;
 	printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr);
 
 	return fe;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/mb86a16.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/mb86a16.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/mb86a16.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/mb86a16.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "mb86a16.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/s921_module.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/s921_module.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/s921_module.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/s921_module.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include "dvb_frontend.h"
 #include "s921_module.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/si21xx.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/si21xx.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/si21xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/si21xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -97,8 +97,6 @@
 #define	LNB_SUPPLY_CTRL_REG_4		0xce
 #define	LNB_SUPPLY_STATUS_REG		0xcf
 
-#define FALSE	0
-#define TRUE	1
 #define FAIL	-1
 #define PASS	0
 
@@ -718,7 +716,7 @@ static int si21xx_set_frontend(struct dv
 	int fine_tune_freq;
 	unsigned char sample_rate = 0;
 	/* boolean */
-	unsigned int inband_interferer_ind;
+	bool inband_interferer_ind;
 
 	/* INTERMEDIATE VALUES */
 	int icoarse_tune_freq; /* MHz */
@@ -728,15 +726,8 @@ static int si21xx_set_frontend(struct dv
 	unsigned int x1;
 	unsigned int x2;
 	int i;
-	unsigned int inband_interferer_div2[ALLOWABLE_FS_COUNT] = {
-			FALSE, FALSE, FALSE, FALSE, FALSE,
-			FALSE, FALSE, FALSE, FALSE, FALSE
-	};
-	unsigned int inband_interferer_div4[ALLOWABLE_FS_COUNT] = {
-			FALSE, FALSE, FALSE, FALSE, FALSE,
-			FALSE, FALSE, FALSE, FALSE, FALSE
-	};
-
+	bool inband_interferer_div2[ALLOWABLE_FS_COUNT];
+	bool inband_interferer_div4[ALLOWABLE_FS_COUNT];
 	int status;
 
 	/* allowable sample rates for ADC in MHz */
@@ -762,7 +753,7 @@ static int si21xx_set_frontend(struct dv
 	}
 
 	for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
-		inband_interferer_div2[i] = inband_interferer_div4[i] = FALSE;
+		inband_interferer_div2[i] = inband_interferer_div4[i] = false;
 
 	if_limit_high = -700000;
 	if_limit_low = -100000;
@@ -798,7 +789,7 @@ static int si21xx_set_frontend(struct dv
 
 		if (((band_low < x1) && (x1 < band_high)) ||
 					((band_low < x2) && (x2 < band_high)))
-					inband_interferer_div4[i] = TRUE;
+					inband_interferer_div4[i] = true;
 
 	}
 
@@ -811,25 +802,28 @@ static int si21xx_set_frontend(struct dv
 
 		if (((band_low < x1) && (x1 < band_high)) ||
 					((band_low < x2) && (x2 < band_high)))
-					inband_interferer_div2[i] = TRUE;
+					inband_interferer_div2[i] = true;
 	}
 
-	inband_interferer_ind = TRUE;
-	for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
-		inband_interferer_ind &= inband_interferer_div2[i] |
-						inband_interferer_div4[i];
+	inband_interferer_ind = true;
+	for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
+		if (inband_interferer_div2[i] || inband_interferer_div4[i]) {
+			inband_interferer_ind = false;
+			break;
+		}
+	}
 
 	if (inband_interferer_ind) {
 		for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
-			if (inband_interferer_div2[i] == FALSE) {
+			if (!inband_interferer_div2[i]) {
 				sample_rate = (u8) afs[i];
 				break;
 			}
 		}
 	} else {
 		for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
-			if ((inband_interferer_div2[i] |
-					inband_interferer_div4[i]) == FALSE) {
+			if ((inband_interferer_div2[i] ||
+			     !inband_interferer_div4[i])) {
 				sample_rate = (u8) afs[i];
 				break;
 			}
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stb0899_drv.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stb0899_drv.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stb0899_drv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stb0899_drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
 #include <linux/dvb/frontend.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stb6000.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stb6000.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stb6000.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stb6000.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 
   */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/dvb/frontend.h>
 #include <asm/types.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stb6100.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stb6100.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stb6100.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stb6100.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
 #include "dvb_frontend.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_core.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv0900_core.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv0900_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -177,7 +177,7 @@ u8 stv0900_read_reg(struct stv0900_inter
 	return buf;
 }
 
-void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
+static void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
 {
 	u8 position = 0, i = 0;
 
@@ -218,7 +218,7 @@ u8 stv0900_get_bits(struct stv0900_inter
 	return val;
 }
 
-enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp)
+static enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp)
 {
 	s32 i;
 
@@ -282,7 +282,7 @@ enum fe_stv0900_error stv0900_initialize
 	return STV0900_NO_ERROR;
 }
 
-u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk)
+static u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk)
 {
 	u32 mclk = 90000000, div = 0, ad_div = 0;
 
@@ -296,7 +296,7 @@ u32 stv0900_get_mclk_freq(struct stv0900
 	return mclk;
 }
 
-enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk)
+static enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk)
 {
 	u32 m_div, clk_sel;
 
@@ -334,7 +334,7 @@ enum fe_stv0900_error stv0900_set_mclk(s
 	return STV0900_NO_ERROR;
 }
 
-u32 stv0900_get_err_count(struct stv0900_internal *intp, int cntr,
+static u32 stv0900_get_err_count(struct stv0900_internal *intp, int cntr,
 					enum fe_stv0900_demod_num demod)
 {
 	u32 lsb, msb, hsb, err_val;
@@ -567,6 +567,46 @@ void stv0900_set_bandwidth(struct dvb_fr
 	}
 }
 
+u32 stv0900_get_freq_auto(struct stv0900_internal *intp, int demod)
+{
+	u32 freq, round;
+	/*	Formulat :
+	Tuner_Frequency(MHz)	= Regs / 64
+	Tuner_granularity(MHz)	= Regs / 2048
+	real_Tuner_Frequency	= Tuner_Frequency(MHz) - Tuner_granularity(MHz)
+	*/
+	freq = (stv0900_get_bits(intp, TUN_RFFREQ2) << 10) +
+		(stv0900_get_bits(intp, TUN_RFFREQ1) << 2) +
+		stv0900_get_bits(intp, TUN_RFFREQ0);
+
+	freq = (freq * 1000) / 64;
+
+	round = (stv0900_get_bits(intp, TUN_RFRESTE1) >> 2) +
+		stv0900_get_bits(intp, TUN_RFRESTE0);
+
+	round = (round * 1000) / 2048;
+
+	return freq + round;
+}
+
+void stv0900_set_tuner_auto(struct stv0900_internal *intp, u32 Frequency,
+						u32 Bandwidth, int demod)
+{
+	u32 tunerFrequency;
+	/* Formulat:
+	Tuner_frequency_reg= Frequency(MHz)*64
+	*/
+	tunerFrequency = (Frequency * 64) / 1000;
+
+	stv0900_write_bits(intp, TUN_RFFREQ2, (tunerFrequency >> 10));
+	stv0900_write_bits(intp, TUN_RFFREQ1, (tunerFrequency >> 2) & 0xff);
+	stv0900_write_bits(intp, TUN_RFFREQ0, (tunerFrequency & 0x03));
+	/* Low Pass Filter = BW /2 (MHz)*/
+	stv0900_write_bits(intp, TUN_BW, Bandwidth / 2000000);
+	/* Tuner Write trig */
+	stv0900_write_reg(intp, TNRLD, 1);
+}
+
 static s32 stv0900_get_rf_level(struct stv0900_internal *intp,
 				const struct stv0900_table *lookup,
 				enum fe_stv0900_demod_num demod)
@@ -1329,7 +1369,6 @@ static enum fe_stv0900_error stv0900_ini
 	enum fe_stv0900_error error = STV0900_NO_ERROR;
 	enum fe_stv0900_error demodError = STV0900_NO_ERROR;
 	struct stv0900_internal *intp = NULL;
-
 	int selosci, i;
 
 	struct stv0900_inode *temp_int = find_inode(state->i2c_adap,
@@ -1345,7 +1384,14 @@ static enum fe_stv0900_error stv0900_ini
 	} else {
 		state->internal = kmalloc(sizeof(struct stv0900_internal),
 								GFP_KERNEL);
+		if (state->internal == NULL)
+			return STV0900_INVALID_HANDLE;
 		temp_int = append_internal(state->internal);
+		if (temp_int == NULL) {
+			kfree(state->internal);
+			state->internal = NULL;
+			return STV0900_INVALID_HANDLE;
+		}
 		state->internal->dmds_used = 1;
 		state->internal->i2c_adap = state->i2c_adap;
 		state->internal->i2c_addr = state->config->demod_address;
@@ -1371,11 +1417,6 @@ static enum fe_stv0900_error stv0900_ini
 		return error;
 	}
 
-	if (state->internal == NULL) {
-		error = STV0900_INVALID_HANDLE;
-		return error;
-	}
-
 	intp = state->internal;
 
 	intp->demod_mode = p_init->demod_mode;
@@ -1404,6 +1445,27 @@ static enum fe_stv0900_error stv0900_ini
 		stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0);
 	}
 
+	intp->tuner_type[0] = p_init->tuner1_type;
+	intp->tuner_type[1] = p_init->tuner2_type;
+	/* tuner init */
+	switch (p_init->tuner1_type) {
+	case 3: /*FE_AUTO_STB6100:*/
+		stv0900_write_reg(intp, R0900_P1_TNRCFG, 0x3c);
+		stv0900_write_reg(intp, R0900_P1_TNRCFG2, 0x86);
+		stv0900_write_reg(intp, R0900_P1_TNRCFG3, 0x18);
+		stv0900_write_reg(intp, R0900_P1_TNRXTAL, 27); /* 27MHz */
+		stv0900_write_reg(intp, R0900_P1_TNRSTEPS, 0x05);
+		stv0900_write_reg(intp, R0900_P1_TNRGAIN, 0x17);
+		stv0900_write_reg(intp, R0900_P1_TNRADJ, 0x1f);
+		stv0900_write_reg(intp, R0900_P1_TNRCTL2, 0x0);
+		stv0900_write_bits(intp, F0900_P1_TUN_TYPE, 3);
+		break;
+	/* case FE_SW_TUNER: */
+	default:
+		stv0900_write_bits(intp, F0900_P1_TUN_TYPE, 6);
+		break;
+	}
+
 	stv0900_write_bits(intp, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress);
 	switch (p_init->tuner1_adc) {
 	case 1:
@@ -1413,6 +1475,27 @@ static enum fe_stv0900_error stv0900_ini
 		break;
 	}
 
+	stv0900_write_reg(intp, R0900_P1_TNRLD, 1); /* hw tuner */
+
+	/* tuner init */
+	switch (p_init->tuner2_type) {
+	case 3: /*FE_AUTO_STB6100:*/
+		stv0900_write_reg(intp, R0900_P2_TNRCFG, 0x3c);
+		stv0900_write_reg(intp, R0900_P2_TNRCFG2, 0x86);
+		stv0900_write_reg(intp, R0900_P2_TNRCFG3, 0x18);
+		stv0900_write_reg(intp, R0900_P2_TNRXTAL, 27); /* 27MHz */
+		stv0900_write_reg(intp, R0900_P2_TNRSTEPS, 0x05);
+		stv0900_write_reg(intp, R0900_P2_TNRGAIN, 0x17);
+		stv0900_write_reg(intp, R0900_P2_TNRADJ, 0x1f);
+		stv0900_write_reg(intp, R0900_P2_TNRCTL2, 0x0);
+		stv0900_write_bits(intp, F0900_P2_TUN_TYPE, 3);
+		break;
+	/* case FE_SW_TUNER: */
+	default:
+		stv0900_write_bits(intp, F0900_P2_TUN_TYPE, 6);
+		break;
+	}
+
 	stv0900_write_bits(intp, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress);
 	switch (p_init->tuner2_adc) {
 	case 1:
@@ -1422,6 +1505,8 @@ static enum fe_stv0900_error stv0900_ini
 		break;
 	}
 
+	stv0900_write_reg(intp, R0900_P2_TNRLD, 1); /* hw tuner */
+
 	stv0900_write_bits(intp, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inv);
 	stv0900_write_bits(intp, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inv);
 	stv0900_set_mclk(intp, 135000000);
@@ -1824,10 +1909,12 @@ struct dvb_frontend *stv0900_attach(cons
 		init_params.tun1_maddress	= config->tun1_maddress;
 		init_params.tun1_iq_inv		= STV0900_IQ_NORMAL;
 		init_params.tuner1_adc		= config->tun1_adc;
+		init_params.tuner1_type		= config->tun1_type;
 		init_params.path2_ts_clock	= config->path2_mode;
 		init_params.ts_config		= config->ts_config_regs;
 		init_params.tun2_maddress	= config->tun2_maddress;
 		init_params.tuner2_adc		= config->tun2_adc;
+		init_params.tuner2_type		= config->tun2_type;
 		init_params.tun2_iq_inv		= STV0900_IQ_SWAPPED;
 
 		err_stv0900 = stv0900_init_internal(&state->frontend,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900.h linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv0900.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv0900.h	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,8 @@ struct stv0900_config {
 	u8 tun2_maddress;
 	u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */
 	u8 tun2_adc;
+	u8 tun1_type;/* for now 3 for stb6100 auto, else - software */
+	u8 tun2_type;
 	/* Set device param to start dma */
 	int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_priv.h linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv0900_priv.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_priv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv0900_priv.h	2010-05-16 17:17:36.000000000 -0400
@@ -247,6 +247,7 @@ struct stv0900_init_params{
 
 	u8	tun1_maddress;
 	int	tuner1_adc;
+	int 	tuner1_type;
 
 	/* IQ from the tuner1 to the demod */
 	enum stv0900_iq_inversion	tun1_iq_inv;
@@ -254,6 +255,7 @@ struct stv0900_init_params{
 
 	u8	tun2_maddress;
 	int	tuner2_adc;
+	int	tuner2_type;
 
 	/* IQ from the tuner2 to the demod */
 	enum stv0900_iq_inversion	tun2_iq_inv;
@@ -309,6 +311,8 @@ struct stv0900_internal{
 	s32	bw[2];
 	s32	symbol_rate[2];
 	s32	srch_range[2];
+	/* for software/auto tuner */
+	int	tuner_type[2];
 
 	/* algorithm for search Blind, Cold or Warm*/
 	enum fe_stv0900_search_algo	srch_algo[2];
@@ -394,4 +398,11 @@ extern enum
 fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
 				enum fe_stv0900_demod_num demod);
 
+extern u32
+stv0900_get_freq_auto(struct stv0900_internal *intp, int demod);
+
+extern void
+stv0900_set_tuner_auto(struct stv0900_internal *intp, u32 Frequency,
+						u32 Bandwidth, int demod);
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_reg.h linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv0900_reg.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_reg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv0900_reg.h	2010-05-16 17:17:36.000000000 -0400
@@ -3174,17 +3174,21 @@ extern s32 shiftx(s32 x, int demod, s32
 #define R0900_P1_TNRRF1 0xf4e9
 #define TNRRF1 REGx(R0900_P1_TNRRF1)
 #define F0900_P1_TUN_RFFREQ2 0xf4e900ff
+#define TUN_RFFREQ2 FLDx(F0900_P1_TUN_RFFREQ2)
 
 /*P1_TNRRF0*/
 #define R0900_P1_TNRRF0 0xf4ea
 #define TNRRF0 REGx(R0900_P1_TNRRF0)
 #define F0900_P1_TUN_RFFREQ1 0xf4ea00ff
+#define TUN_RFFREQ1 FLDx(F0900_P1_TUN_RFFREQ1)
 
 /*P1_TNRBW*/
 #define R0900_P1_TNRBW 0xf4eb
 #define TNRBW REGx(R0900_P1_TNRBW)
 #define F0900_P1_TUN_RFFREQ0 0xf4eb00c0
+#define TUN_RFFREQ0 FLDx(F0900_P1_TUN_RFFREQ0)
 #define F0900_P1_TUN_BW 0xf4eb003f
+#define TUN_BW FLDx(F0900_P1_TUN_BW)
 
 /*P1_TNRADJ*/
 #define R0900_P1_TNRADJ 0xf4ec
@@ -3234,11 +3238,13 @@ extern s32 shiftx(s32 x, int demod, s32
 #define F0900_P1_TUN_I2CLOCKED 0xf4f60010
 #define F0900_P1_TUN_PROGDONE 0xf4f6000c
 #define F0900_P1_TUN_RFRESTE1 0xf4f60003
+#define TUN_RFRESTE1 FLDx(F0900_P1_TUN_RFRESTE1)
 
 /*P1_TNRRESTE*/
 #define R0900_P1_TNRRESTE 0xf4f7
 #define TNRRESTE REGx(R0900_P1_TNRRESTE)
 #define F0900_P1_TUN_RFRESTE0 0xf4f700ff
+#define TUN_RFRESTE0 FLDx(F0900_P1_TUN_RFRESTE0)
 
 /*P1_SMAPCOEF7*/
 #define R0900_P1_SMAPCOEF7 0xf500
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_sw.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv0900_sw.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_sw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv0900_sw.c	2010-05-16 17:17:36.000000000 -0400
@@ -193,7 +193,7 @@ static int stv0900_search_carr_sw_loop(s
 	return lock;
 }
 
-int stv0900_sw_algo(struct stv0900_internal *intp,
+static int stv0900_sw_algo(struct stv0900_internal *intp,
 				enum fe_stv0900_demod_num demod)
 {
 	int	lock = FALSE,
@@ -606,7 +606,12 @@ static int stv0900_get_demod_cold_lock(s
 			tuner_freq -= (current_step * currier_step);
 
 		if (intp->chip_id <= 0x20) {
-			stv0900_set_tuner(fe, tuner_freq, intp->bw[d]);
+			if (intp->tuner_type[d] == 3)
+				stv0900_set_tuner_auto(intp, tuner_freq,
+						intp->bw[d], demod);
+			else
+				stv0900_set_tuner(fe, tuner_freq, intp->bw[d]);
+
 			stv0900_write_reg(intp, DMDISTATE, 0x1c);
 			stv0900_write_reg(intp, CFRINIT1, 0);
 			stv0900_write_reg(intp, CFRINIT0, 0);
@@ -790,7 +795,7 @@ static enum fe_stv0900_fec stv0900_get_v
 	return prate;
 }
 
-void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp,
+static void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod,
 					u32 srate)
 {
@@ -976,8 +981,16 @@ static void stv0900_track_optimization(s
 					intp->rolloff) + 10000000;
 
 		if ((intp->chip_id >= 0x20) || (blind_tun_sw == 1)) {
-			if (intp->srch_algo[demod] != STV0900_WARM_START)
-				stv0900_set_bandwidth(fe, intp->bw[demod]);
+			if (intp->srch_algo[demod] != STV0900_WARM_START) {
+				if (intp->tuner_type[demod] == 3)
+					stv0900_set_tuner_auto(intp,
+							intp->freq[demod],
+							intp->bw[demod],
+							demod);
+				else
+					stv0900_set_bandwidth(fe,
+							intp->bw[demod]);
+			}
 		}
 
 		if ((intp->srch_algo[demod] == STV0900_BLIND_SEARCH) ||
@@ -1202,7 +1215,11 @@ fe_stv0900_signal_type stv0900_get_signa
 	}
 
 	result->standard = stv0900_get_standard(fe, d);
-	result->frequency = stv0900_get_tuner_freq(fe);
+	if (intp->tuner_type[demod] == 3)
+		result->frequency = stv0900_get_freq_auto(intp, d);
+	else
+		result->frequency = stv0900_get_tuner_freq(fe);
+
 	offsetFreq = stv0900_get_carr_freq(intp, intp->mclk, d) / 1000;
 	result->frequency += offsetFreq;
 	result->symbol_rate = stv0900_get_symbol_rate(intp, intp->mclk, d);
@@ -1213,6 +1230,9 @@ fe_stv0900_signal_type stv0900_get_signa
 	result->pilot = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
 	result->frame_len = ((u32)stv0900_get_bits(intp, DEMOD_TYPE)) >> 1;
 	result->rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS);
+
+	dprintk("%s: modcode=0x%x \n", __func__, result->modcode);
+
 	switch (result->standard) {
 	case STV0900_DVBS2_STANDARD:
 		result->spectrum = stv0900_get_bits(intp, SPECINV_DEMOD);
@@ -1239,7 +1259,11 @@ fe_stv0900_signal_type stv0900_get_signa
 	if ((intp->srch_algo[d] == STV0900_BLIND_SEARCH) ||
 				(intp->symbol_rate[d] < 10000000)) {
 		offsetFreq = result->frequency - intp->freq[d];
-		intp->freq[d] = stv0900_get_tuner_freq(fe);
+		if (intp->tuner_type[demod] == 3)
+			intp->freq[d] = stv0900_get_freq_auto(intp, d);
+		else
+			intp->freq[d] = stv0900_get_tuner_freq(fe);
+
 		if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
 			range = STV0900_RANGEOK;
 		else if (ABS(offsetFreq) <=
@@ -1481,7 +1505,12 @@ static u32 stv0900_search_srate_coarse(s
 			else
 				tuner_freq -= (current_step * currier_step);
 
-			stv0900_set_tuner(fe, tuner_freq, intp->bw[demod]);
+			if (intp->tuner_type[demod] == 3)
+				stv0900_set_tuner_auto(intp, tuner_freq,
+						intp->bw[demod], demod);
+			else
+				stv0900_set_tuner(fe, tuner_freq,
+						intp->bw[demod]);
 		}
 	}
 
@@ -1608,7 +1637,8 @@ static int stv0900_blind_search_algo(str
 
 	agc2_int = stv0900_blind_check_agc2_min_level(intp, demod);
 
-	if (agc2_int > STV0900_BLIND_SEARCH_AGC2_TH)
+	dprintk("%s agc2_int=%d agc2_th=%d \n", __func__, agc2_int, agc2_th);
+	if (agc2_int > agc2_th)
 		return FALSE;
 
 	if (intp->chip_id == 0x10)
@@ -1875,7 +1905,11 @@ enum fe_stv0900_signal_type stv0900_algo
 
 	}
 
-	stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]);
+	if (intp->tuner_type[demod] == 3)
+		stv0900_set_tuner_auto(intp, intp->freq[demod],
+				intp->bw[demod], demod);
+	else
+		stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]);
 
 	agc1_power = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
 				stv0900_get_bits(intp, AGCIQ_VALUE0));
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv090x.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv090x.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv090x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv090x.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 
 #include <linux/dvb/frontend.h>
@@ -37,7 +38,82 @@
 static unsigned int verbose;
 module_param(verbose, int, 0644);
 
-struct mutex demod_lock;
+/* internal params node */
+struct stv090x_dev {
+	/* pointer for internal params, one for each pair of demods */
+	struct stv090x_internal		*internal;
+	struct stv090x_dev		*next_dev;
+};
+
+/* first internal params */
+static struct stv090x_dev *stv090x_first_dev;
+
+/* find chip by i2c adapter and i2c address */
+static struct stv090x_dev *find_dev(struct i2c_adapter *i2c_adap,
+					u8 i2c_addr)
+{
+	struct stv090x_dev *temp_dev = stv090x_first_dev;
+
+	/*
+	 Search of the last stv0900 chip or
+	 find it by i2c adapter and i2c address */
+	while ((temp_dev != NULL) &&
+		((temp_dev->internal->i2c_adap != i2c_adap) ||
+		(temp_dev->internal->i2c_addr != i2c_addr))) {
+
+		temp_dev = temp_dev->next_dev;
+	}
+
+	return temp_dev;
+}
+
+/* deallocating chip */
+static void remove_dev(struct stv090x_internal *internal)
+{
+	struct stv090x_dev *prev_dev = stv090x_first_dev;
+	struct stv090x_dev *del_dev = find_dev(internal->i2c_adap,
+						internal->i2c_addr);
+
+	if (del_dev != NULL) {
+		if (del_dev == stv090x_first_dev) {
+			stv090x_first_dev = del_dev->next_dev;
+		} else {
+			while (prev_dev->next_dev != del_dev)
+				prev_dev = prev_dev->next_dev;
+
+			prev_dev->next_dev = del_dev->next_dev;
+		}
+
+		kfree(del_dev);
+	}
+}
+
+/* allocating new chip */
+static struct stv090x_dev *append_internal(struct stv090x_internal *internal)
+{
+	struct stv090x_dev *new_dev;
+	struct stv090x_dev *temp_dev;
+
+	new_dev = kmalloc(sizeof(struct stv090x_dev), GFP_KERNEL);
+	if (new_dev != NULL) {
+		new_dev->internal = internal;
+		new_dev->next_dev = NULL;
+
+		/* append to list */
+		if (stv090x_first_dev == NULL) {
+			stv090x_first_dev = new_dev;
+		} else {
+			temp_dev = stv090x_first_dev;
+			while (temp_dev->next_dev != NULL)
+				temp_dev = temp_dev->next_dev;
+
+			temp_dev->next_dev = new_dev;
+		}
+	}
+
+	return new_dev;
+}
+
 
 /* DVBS1 and DSS C/N Lookup table */
 static const struct stv090x_tab stv090x_s1cn_tab[] = {
@@ -683,6 +759,9 @@ static int stv090x_i2c_gate_ctrl(struct
 	struct stv090x_state *state = fe->demodulator_priv;
 	u32 reg;
 
+	if (enable)
+		mutex_lock(&state->internal->tuner_lock);
+
 	reg = STV090x_READ_DEMOD(state, I2CRPT);
 	if (enable) {
 		dprintk(FE_DEBUG, 1, "Enable Gate");
@@ -696,9 +775,14 @@ static int stv090x_i2c_gate_ctrl(struct
 		if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0)
 			goto err;
 	}
+
+	if (!enable)
+		mutex_unlock(&state->internal->tuner_lock);
+
 	return 0;
 err:
 	dprintk(FE_ERROR, 1, "I/O error");
+	mutex_unlock(&state->internal->tuner_lock);
 	return -1;
 }
 
@@ -755,13 +839,13 @@ static int stv090x_set_srate(struct stv0
 
 	if (srate > 60000000) {
 		sym  = (srate << 4); /* SR * 2^16 / master_clk */
-		sym /= (state->mclk >> 12);
+		sym /= (state->internal->mclk >> 12);
 	} else if (srate > 6000000) {
 		sym  = (srate << 6);
-		sym /= (state->mclk >> 10);
+		sym /= (state->internal->mclk >> 10);
 	} else {
 		sym  = (srate << 9);
-		sym /= (state->mclk >> 7);
+		sym /= (state->internal->mclk >> 7);
 	}
 
 	if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */
@@ -782,13 +866,13 @@ static int stv090x_set_max_srate(struct
 	srate = 105 * (srate / 100);
 	if (srate > 60000000) {
 		sym  = (srate << 4); /* SR * 2^16 / master_clk */
-		sym /= (state->mclk >> 12);
+		sym /= (state->internal->mclk >> 12);
 	} else if (srate > 6000000) {
 		sym  = (srate << 6);
-		sym /= (state->mclk >> 10);
+		sym /= (state->internal->mclk >> 10);
 	} else {
 		sym  = (srate << 9);
-		sym /= (state->mclk >> 7);
+		sym /= (state->internal->mclk >> 7);
 	}
 
 	if (sym < 0x7fff) {
@@ -816,13 +900,13 @@ static int stv090x_set_min_srate(struct
 	srate = 95 * (srate / 100);
 	if (srate > 60000000) {
 		sym  = (srate << 4); /* SR * 2^16 / master_clk */
-		sym /= (state->mclk >> 12);
+		sym /= (state->internal->mclk >> 12);
 	} else if (srate > 6000000) {
 		sym  = (srate << 6);
-		sym /= (state->mclk >> 10);
+		sym /= (state->internal->mclk >> 10);
 	} else {
 		sym  = (srate << 9);
-		sym /= (state->mclk >> 7);
+		sym /= (state->internal->mclk >> 7);
 	}
 
 	if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */
@@ -1103,21 +1187,21 @@ static int stv090x_vitclk_ctl(struct stv
 
 	switch (state->demod) {
 	case STV090x_DEMODULATOR_0:
-		mutex_lock(&demod_lock);
+		mutex_lock(&state->internal->demod_lock);
 		reg = stv090x_read_reg(state, STV090x_STOPCLK2);
 		STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable);
 		if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
 			goto err;
-		mutex_unlock(&demod_lock);
+		mutex_unlock(&state->internal->demod_lock);
 		break;
 
 	case STV090x_DEMODULATOR_1:
-		mutex_lock(&demod_lock);
+		mutex_lock(&state->internal->demod_lock);
 		reg = stv090x_read_reg(state, STV090x_STOPCLK2);
 		STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable);
 		if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
 			goto err;
-		mutex_unlock(&demod_lock);
+		mutex_unlock(&state->internal->demod_lock);
 		break;
 
 	default:
@@ -1126,14 +1210,14 @@ static int stv090x_vitclk_ctl(struct stv
 	}
 	return 0;
 err:
-	mutex_unlock(&demod_lock);
+	mutex_unlock(&state->internal->demod_lock);
 	dprintk(FE_ERROR, 1, "I/O error");
 	return -1;
 }
 
 static int stv090x_dvbs_track_crl(struct stv090x_state *state)
 {
-	if (state->dev_ver >= 0x30) {
+	if (state->internal->dev_ver >= 0x30) {
 		/* Set ACLC BCLC optimised value vs SR */
 		if (state->srate >= 15000000) {
 			if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0)
@@ -1215,7 +1299,7 @@ static int stv090x_delivery_search(struc
 		if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0)
 			goto err;
 
-		if (state->dev_ver <= 0x20) {
+		if (state->internal->dev_ver <= 0x20) {
 			/* enable S2 carrier loop */
 			if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
 				goto err;
@@ -1246,6 +1330,10 @@ static int stv090x_delivery_search(struc
 	default:
 		/* enable DVB-S2 and DVB-S2 in Auto MODE */
 		reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+		STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
+		STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
+		if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+			goto err;
 		STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
 		STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
 		if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
@@ -1257,7 +1345,7 @@ static int stv090x_delivery_search(struc
 		if (stv090x_dvbs_track_crl(state) < 0)
 			goto err;
 
-		if (state->dev_ver <= 0x20) {
+		if (state->internal->dev_ver <= 0x20) {
 			/* enable S2 carrier loop */
 			if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
 				goto err;
@@ -1304,7 +1392,7 @@ static int stv090x_start_search(struct s
 	if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
 		goto err;
 
-	if (state->dev_ver <= 0x20) {
+	if (state->internal->dev_ver <= 0x20) {
 		if (state->srate <= 5000000) {
 			if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0)
 				goto err;
@@ -1348,7 +1436,7 @@ static int stv090x_start_search(struct s
 			 * CFR max = +1MHz
 			 */
 			freq_abs  = 1000 << 16;
-			freq_abs /= (state->mclk / 1000);
+			freq_abs /= (state->internal->mclk / 1000);
 			freq      = (s16) freq_abs;
 		} else {
 			/* COLD Start
@@ -1358,7 +1446,7 @@ static int stv090x_start_search(struct s
 			 */
 			freq_abs  = (state->search_range / 2000) + 600;
 			freq_abs  = freq_abs << 16;
-			freq_abs /= (state->mclk / 1000);
+			freq_abs /= (state->internal->mclk / 1000);
 			freq      = (s16) freq_abs;
 		}
 
@@ -1381,7 +1469,7 @@ static int stv090x_start_search(struct s
 	if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0)
 		goto err;
 
-	if (state->dev_ver >= 0x20) {
+	if (state->internal->dev_ver >= 0x20) {
 		if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
 			goto err;
 		if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
@@ -1418,10 +1506,10 @@ static int stv090x_start_search(struct s
 	if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0)
 		goto err;
 
-	if (state->dev_ver >= 0x20) {
+	if (state->internal->dev_ver >= 0x20) {
 		/*Frequency offset detector setting*/
 		if (state->srate < 2000000) {
-			if (state->dev_ver <= 0x20) {
+			if (state->internal->dev_ver <= 0x20) {
 				/* Cut 2 */
 				if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0)
 					goto err;
@@ -1512,7 +1600,7 @@ static int stv090x_get_agc2_min_level(st
 		steps = 1;
 
 	dir = 1;
-	freq_step = (1000000 * 256) / (state->mclk / 256);
+	freq_step = (1000000 * 256) / (state->internal->mclk / 256);
 	freq_init = 0;
 
 	for (i = 0; i < steps; i++) {
@@ -1583,7 +1671,7 @@ static u32 stv090x_srate_srch_coarse(str
 	u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg;
 	u32 agc2th;
 
-	if (state->dev_ver >= 0x30)
+	if (state->internal->dev_ver >= 0x30)
 		agc2th = 0x2e00;
 	else
 		agc2th = 0x1f00;
@@ -1619,13 +1707,13 @@ static u32 stv090x_srate_srch_coarse(str
 	if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0)
 		goto err;
 
-	if (state->dev_ver >= 0x30) {
+	if (state->internal->dev_ver >= 0x30) {
 		if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0)
 			goto err;
 		if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0)
 			goto err;
 
-	} else if (state->dev_ver >= 0x20) {
+	} else if (state->internal->dev_ver >= 0x20) {
 		if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0)
 			goto err;
 		if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0)
@@ -1677,7 +1765,7 @@ static u32 stv090x_srate_srch_coarse(str
 				STV090x_READ_DEMOD(state, AGC2I0);
 		}
 		agc2 /= 10;
-		srate_coarse = stv090x_get_srate(state, state->mclk);
+		srate_coarse = stv090x_get_srate(state, state->internal->mclk);
 		cur_step++;
 		dir *= -1;
 		if ((tmg_cpt >= 5) && (agc2 < agc2th) &&
@@ -1695,12 +1783,12 @@ static u32 stv090x_srate_srch_coarse(str
 
 			if (state->config->tuner_set_frequency) {
 				if (state->config->tuner_set_frequency(fe, freq) < 0)
-					goto err;
+					goto err_gateoff;
 			}
 
 			if (state->config->tuner_set_bandwidth) {
 				if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
-					goto err;
+					goto err_gateoff;
 			}
 
 			if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
@@ -1713,7 +1801,7 @@ static u32 stv090x_srate_srch_coarse(str
 
 			if (state->config->tuner_get_status) {
 				if (state->config->tuner_get_status(fe, &reg) < 0)
-					goto err;
+					goto err_gateoff;
 			}
 
 			if (reg)
@@ -1729,9 +1817,12 @@ static u32 stv090x_srate_srch_coarse(str
 	if (!tmg_lock)
 		srate_coarse = 0;
 	else
-		srate_coarse = stv090x_get_srate(state, state->mclk);
+		srate_coarse = stv090x_get_srate(state, state->internal->mclk);
 
 	return srate_coarse;
+
+err_gateoff:
+	stv090x_i2c_gate_ctrl(fe, 0);
 err:
 	dprintk(FE_ERROR, 1, "I/O error");
 	return -1;
@@ -1741,7 +1832,7 @@ static u32 stv090x_srate_srch_fine(struc
 {
 	u32 srate_coarse, freq_coarse, sym, reg;
 
-	srate_coarse = stv090x_get_srate(state, state->mclk);
+	srate_coarse = stv090x_get_srate(state, state->internal->mclk);
 	freq_coarse  = STV090x_READ_DEMOD(state, CFR2) << 8;
 	freq_coarse |= STV090x_READ_DEMOD(state, CFR1);
 	sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
@@ -1767,10 +1858,10 @@ static u32 stv090x_srate_srch_fine(struc
 		if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
 			goto err;
 
-		if (state->dev_ver >= 0x30) {
+		if (state->internal->dev_ver >= 0x30) {
 			if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0)
 				goto err;
-		} else if (state->dev_ver >= 0x20) {
+		} else if (state->internal->dev_ver >= 0x20) {
 			if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
 				goto err;
 		}
@@ -1778,20 +1869,20 @@ static u32 stv090x_srate_srch_fine(struc
 		if (srate_coarse > 3000000) {
 			sym  = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
 			sym  = (sym / 1000) * 65536;
-			sym /= (state->mclk / 1000);
+			sym /= (state->internal->mclk / 1000);
 			if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
 				goto err;
 			if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
 				goto err;
 			sym  = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */
 			sym  = (sym / 1000) * 65536;
-			sym /= (state->mclk / 1000);
+			sym /= (state->internal->mclk / 1000);
 			if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
 				goto err;
 			if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
 				goto err;
 			sym  = (srate_coarse / 1000) * 65536;
-			sym /= (state->mclk / 1000);
+			sym /= (state->internal->mclk / 1000);
 			if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
 				goto err;
 			if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
@@ -1799,20 +1890,20 @@ static u32 stv090x_srate_srch_fine(struc
 		} else {
 			sym  = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
 			sym  = (sym / 100) * 65536;
-			sym /= (state->mclk / 100);
+			sym /= (state->internal->mclk / 100);
 			if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
 				goto err;
 			if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
 				goto err;
 			sym  = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */
 			sym  = (sym / 100) * 65536;
-			sym /= (state->mclk / 100);
+			sym /= (state->internal->mclk / 100);
 			if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
 				goto err;
 			if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
 				goto err;
 			sym  = (srate_coarse / 100) * 65536;
-			sym /= (state->mclk / 100);
+			sym /= (state->internal->mclk / 100);
 			if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
 				goto err;
 			if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
@@ -1874,18 +1965,19 @@ static int stv090x_blind_search(struct s
 	u32 agc2, reg, srate_coarse;
 	s32 cpt_fail, agc2_ovflw, i;
 	u8 k_ref, k_max, k_min;
-	int coarse_fail, lock;
+	int coarse_fail = 0;
+	int lock;
 
 	k_max = 110;
 	k_min = 10;
 
 	agc2 = stv090x_get_agc2_min_level(state);
 
-	if (agc2 > STV090x_SEARCH_AGC2_TH(state->dev_ver)) {
+	if (agc2 > STV090x_SEARCH_AGC2_TH(state->internal->dev_ver)) {
 		lock = 0;
 	} else {
 
-		if (state->dev_ver <= 0x20) {
+		if (state->internal->dev_ver <= 0x20) {
 			if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0)
 				goto err;
 		} else {
@@ -1897,7 +1989,7 @@ static int stv090x_blind_search(struct s
 		if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0)
 			goto err;
 
-		if (state->dev_ver >= 0x20) {
+		if (state->internal->dev_ver >= 0x20) {
 			if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
 				goto err;
 			if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
@@ -1956,7 +2048,7 @@ static int stv090x_chk_tmg(struct stv090
 	u32 reg;
 	s32 tmg_cpt = 0, i;
 	u8 freq, tmg_thh, tmg_thl;
-	int tmg_lock;
+	int tmg_lock = 0;
 
 	freq = STV090x_READ_DEMOD(state, CARFREQ);
 	tmg_thh = STV090x_READ_DEMOD(state, TMGTHRISE);
@@ -2080,12 +2172,12 @@ static int stv090x_get_coldlock(struct s
 
 					if (state->config->tuner_set_frequency) {
 						if (state->config->tuner_set_frequency(fe, freq) < 0)
-							goto err;
+							goto err_gateoff;
 					}
 
 					if (state->config->tuner_set_bandwidth) {
 						if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
-							goto err;
+							goto err_gateoff;
 					}
 
 					if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
@@ -2098,7 +2190,7 @@ static int stv090x_get_coldlock(struct s
 
 					if (state->config->tuner_get_status) {
 						if (state->config->tuner_get_status(fe, &reg) < 0)
-							goto err;
+							goto err_gateoff;
 					}
 
 					if (reg)
@@ -2129,6 +2221,8 @@ static int stv090x_get_coldlock(struct s
 
 	return lock;
 
+err_gateoff:
+	stv090x_i2c_gate_ctrl(fe, 0);
 err:
 	dprintk(FE_ERROR, 1, "I/O error");
 	return -1;
@@ -2142,13 +2236,13 @@ static int stv090x_get_loop_params(struc
 	car_max = state->search_range / 1000;
 	car_max += car_max / 10;
 	car_max  = 65536 * (car_max / 2);
-	car_max /= (state->mclk / 1000);
+	car_max /= (state->internal->mclk / 1000);
 
 	if (car_max > 0x4000)
 		car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */
 
 	inc  = srate;
-	inc /= state->mclk / 1000;
+	inc /= state->internal->mclk / 1000;
 	inc *= 256;
 	inc *= 256;
 	inc /= 1000;
@@ -2209,7 +2303,7 @@ static int stv090x_chk_signal(struct stv
 
 	car_max += (car_max / 10); /* 10% margin */
 	car_max  = (65536 * car_max / 2);
-	car_max /= state->mclk / 1000;
+	car_max /= state->internal->mclk / 1000;
 
 	if (car_max > 0x4000)
 		car_max = 0x4000;
@@ -2234,7 +2328,7 @@ static int stv090x_search_car_loop(struc
 	car_max  = state->search_range / 1000;
 	car_max += (car_max / 10);
 	car_max  = (65536 * car_max / 2);
-	car_max /= (state->mclk / 1000);
+	car_max /= (state->internal->mclk / 1000);
 	if (car_max > 0x4000)
 		car_max = 0x4000;
 
@@ -2304,7 +2398,7 @@ static int stv090x_sw_algo(struct stv090
 	case STV090x_SEARCH_DVBS1:
 	case STV090x_SEARCH_DSS:
 		/* accelerate the frequency detector */
-		if (state->dev_ver >= 0x20) {
+		if (state->internal->dev_ver >= 0x20) {
 			if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0)
 				goto err;
 		}
@@ -2315,7 +2409,7 @@ static int stv090x_sw_algo(struct stv090
 		break;
 
 	case STV090x_SEARCH_DVBS2:
-		if (state->dev_ver >= 0x20) {
+		if (state->internal->dev_ver >= 0x20) {
 			if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
 				goto err;
 		}
@@ -2328,7 +2422,7 @@ static int stv090x_sw_algo(struct stv090
 	case STV090x_SEARCH_AUTO:
 	default:
 		/* accelerate the frequency detector */
-		if (state->dev_ver >= 0x20) {
+		if (state->internal->dev_ver >= 0x20) {
 			if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0)
 				goto err;
 			if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
@@ -2350,7 +2444,7 @@ static int stv090x_sw_algo(struct stv090
 		/*run the SW search 2 times maximum*/
 		if (lock || no_signal || (trials == 2)) {
 			/*Check if the demod is not losing lock in DVBS2*/
-			if (state->dev_ver >= 0x20) {
+			if (state->internal->dev_ver >= 0x20) {
 				if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
 					goto err;
 				if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
@@ -2372,7 +2466,7 @@ static int stv090x_sw_algo(struct stv090
 					/*FALSE lock, The demod is loosing lock */
 					lock = 0;
 					if (trials < 2) {
-						if (state->dev_ver >= 0x20) {
+						if (state->internal->dev_ver >= 0x20) {
 							if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
 								goto err;
 						}
@@ -2422,11 +2516,11 @@ static s32 stv090x_get_car_freq(struct s
 	derot |= STV090x_READ_DEMOD(state, CFR0);
 
 	derot = comp2(derot, 24);
-	int_1 = state->mclk >> 12;
+	int_1 = mclk >> 12;
 	int_2 = derot >> 12;
 
 	/* carrier_frequency = MasterClock * Reg / 2^24 */
-	tmp_1 = state->mclk % 0x1000;
+	tmp_1 = mclk % 0x1000;
 	tmp_2 = derot % 0x1000;
 
 	derot = (int_1 * int_2) +
@@ -2502,13 +2596,13 @@ static enum stv090x_signal_state stv090x
 
 	if (state->config->tuner_get_frequency) {
 		if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)
-			goto err;
+			goto err_gateoff;
 	}
 
 	if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
 		goto err;
 
-	offst_freq = stv090x_get_car_freq(state, state->mclk) / 1000;
+	offst_freq = stv090x_get_car_freq(state, state->internal->mclk) / 1000;
 	state->frequency += offst_freq;
 
 	if (stv090x_get_viterbi(state) < 0)
@@ -2530,7 +2624,7 @@ static enum stv090x_signal_state stv090x
 
 		if (state->config->tuner_get_frequency) {
 			if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)
-				goto err;
+				goto err_gateoff;
 		}
 
 		if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
@@ -2550,6 +2644,9 @@ static enum stv090x_signal_state stv090x
 	}
 
 	return STV090x_OUTOFRANGE;
+
+err_gateoff:
+	stv090x_i2c_gate_ctrl(fe, 0);
 err:
 	dprintk(FE_ERROR, 1, "I/O error");
 	return -1;
@@ -2579,7 +2676,7 @@ static u8 stv090x_optimize_carloop(struc
 	s32 i;
 	struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low;
 
-	if (state->dev_ver == 0x20) {
+	if (state->internal->dev_ver == 0x20) {
 		car_loop		= stv090x_s2_crl_cut20;
 		car_loop_qpsk_low	= stv090x_s2_lowqpsk_crl_cut20;
 		car_loop_apsk_low	= stv090x_s2_apsk_crl_cut20;
@@ -2700,7 +2797,7 @@ static u8 stv090x_optimize_carloop_short
 		break;
 	}
 
-	if (state->dev_ver >= 0x30) {
+	if (state->internal->dev_ver >= 0x30) {
 		/* Cut 3.0 and up */
 		short_crl = stv090x_s2_short_crl_cut30;
 	} else {
@@ -2732,7 +2829,7 @@ static int stv090x_optimize_track(struct
 	s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0;
 	u32 reg;
 
-	srate  = stv090x_get_srate(state, state->mclk);
+	srate  = stv090x_get_srate(state, state->internal->mclk);
 	srate += stv090x_get_tmgoffst(state, srate);
 
 	switch (state->delsys) {
@@ -2751,7 +2848,7 @@ static int stv090x_optimize_track(struct
 		if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
 			goto err;
 
-		if (state->dev_ver >= 0x30) {
+		if (state->internal->dev_ver >= 0x30) {
 			if (stv090x_get_viterbi(state) < 0)
 				goto err;
 
@@ -2868,7 +2965,7 @@ static int stv090x_optimize_track(struct
 			goto err;
 	}
 
-	if (state->dev_ver >= 0x20) {
+	if (state->internal->dev_ver >= 0x20) {
 		if ((state->search_mode == STV090x_SEARCH_DVBS1)	||
 		    (state->search_mode == STV090x_SEARCH_DSS)		||
 		    (state->search_mode == STV090x_SEARCH_AUTO)) {
@@ -2890,7 +2987,8 @@ static int stv090x_optimize_track(struct
 	if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0)
 		goto err;
 
-	if ((state->dev_ver >= 0x20) || (blind_tune == 1) || (state->srate < 10000000)) {
+	if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1) ||
+	    (state->srate < 10000000)) {
 		/* update initial carrier freq with the found freq offset */
 		if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
 			goto err;
@@ -2898,7 +2996,7 @@ static int stv090x_optimize_track(struct
 			goto err;
 		state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000;
 
-		if ((state->dev_ver >= 0x20) || (blind_tune == 1)) {
+		if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1)) {
 
 			if (state->algo != STV090x_WARM_SEARCH) {
 
@@ -2907,7 +3005,7 @@ static int stv090x_optimize_track(struct
 
 				if (state->config->tuner_set_bandwidth) {
 					if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
-						goto err;
+						goto err_gateoff;
 				}
 
 				if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
@@ -2950,7 +3048,7 @@ static int stv090x_optimize_track(struct
 
 	}
 
-	if (state->dev_ver >= 0x20) {
+	if (state->internal->dev_ver >= 0x20) {
 		if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
 			goto err;
 	}
@@ -2959,6 +3057,9 @@ static int stv090x_optimize_track(struct
 		stv090x_set_vit_thtracq(state);
 
 	return 0;
+
+err_gateoff:
+	stv090x_i2c_gate_ctrl(fe, 0);
 err:
 	dprintk(FE_ERROR, 1, "I/O error");
 	return -1;
@@ -3026,7 +3127,7 @@ static int stv090x_set_s2rolloff(struct
 {
 	u32 reg;
 
-	if (state->dev_ver <= 0x20) {
+	if (state->internal->dev_ver <= 0x20) {
 		/* rolloff to auto mode if DVBS2 */
 		reg = STV090x_READ_DEMOD(state, DEMOD);
 		STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00);
@@ -3062,7 +3163,7 @@ static enum stv090x_signal_state stv090x
 	if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */
 		goto err;
 
-	if (state->dev_ver >= 0x20) {
+	if (state->internal->dev_ver >= 0x20) {
 		if (state->srate > 5000000) {
 			if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
 				goto err;
@@ -3102,7 +3203,7 @@ static enum stv090x_signal_state stv090x
 		if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
 			goto err;
 
-		if (state->dev_ver >= 0x20) {
+		if (state->internal->dev_ver >= 0x20) {
 			if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0)
 				goto err;
 			if (state->algo == STV090x_COLD_SEARCH)
@@ -3120,9 +3221,11 @@ static enum stv090x_signal_state stv090x
 		if (stv090x_set_srate(state, state->srate) < 0)
 			goto err;
 
-		if (stv090x_set_max_srate(state, state->mclk, state->srate) < 0)
+		if (stv090x_set_max_srate(state, state->internal->mclk,
+					  state->srate) < 0)
 			goto err;
-		if (stv090x_set_min_srate(state, state->mclk, state->srate) < 0)
+		if (stv090x_set_min_srate(state, state->internal->mclk,
+					  state->srate) < 0)
 			goto err;
 
 		if (state->srate >= 10000000)
@@ -3136,18 +3239,21 @@ static enum stv090x_signal_state stv090x
 		goto err;
 
 	if (state->config->tuner_set_bbgain) {
-		if (state->config->tuner_set_bbgain(fe, 10) < 0) /* 10dB */
-			goto err;
+		reg = state->config->tuner_bbgain;
+		if (reg == 0)
+			reg = 10; /* default: 10dB */
+		if (state->config->tuner_set_bbgain(fe, reg) < 0)
+			goto err_gateoff;
 	}
 
 	if (state->config->tuner_set_frequency) {
 		if (state->config->tuner_set_frequency(fe, state->frequency) < 0)
-			goto err;
+			goto err_gateoff;
 	}
 
 	if (state->config->tuner_set_bandwidth) {
 		if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
-			goto err;
+			goto err_gateoff;
 	}
 
 	if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
@@ -3155,21 +3261,21 @@ static enum stv090x_signal_state stv090x
 
 	msleep(50);
 
-	if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
-		goto err;
-
 	if (state->config->tuner_get_status) {
+		if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
+			goto err;
 		if (state->config->tuner_get_status(fe, &reg) < 0)
+			goto err_gateoff;
+		if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
 			goto err;
-	}
-
-	if (reg)
-		dprintk(FE_DEBUG, 1, "Tuner phase locked");
-	else
-		dprintk(FE_DEBUG, 1, "Tuner unlocked");
 
-	if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
-		goto err;
+		if (reg)
+			dprintk(FE_DEBUG, 1, "Tuner phase locked");
+		else {
+			dprintk(FE_DEBUG, 1, "Tuner unlocked");
+			return STV090x_NOCARRIER;
+		}
+	}
 
 	msleep(10);
 	agc1_power = MAKEWORD16(STV090x_READ_DEMOD(state, AGCIQIN1),
@@ -3194,7 +3300,7 @@ static enum stv090x_signal_state stv090x
 		reg = STV090x_READ_DEMOD(state, DEMOD);
 		STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion);
 
-		if (state->dev_ver <= 0x20) {
+		if (state->internal->dev_ver <= 0x20) {
 			/* rolloff to auto mode if DVBS2 */
 			STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1);
 		} else {
@@ -3238,7 +3344,7 @@ static enum stv090x_signal_state stv090x
 	if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */
 		stv090x_optimize_track(state);
 
-		if (state->dev_ver >= 0x20) {
+		if (state->internal->dev_ver >= 0x20) {
 			/* >= Cut 2.0 :release TS reset after
 			 * demod lock and optimized Tracking
 			 */
@@ -3293,6 +3399,8 @@ static enum stv090x_signal_state stv090x
 	}
 	return signal_state;
 
+err_gateoff:
+	stv090x_i2c_gate_ctrl(fe, 0);
 err:
 	dprintk(FE_ERROR, 1, "I/O error");
 	return -1;
@@ -3303,6 +3411,9 @@ static enum dvbfe_search stv090x_search(
 	struct stv090x_state *state = fe->demodulator_priv;
 	struct dtv_frontend_properties *props = &fe->dtv_property_cache;
 
+	if (p->frequency == 0)
+		return DVBFE_ALGO_SEARCH_INVALID;
+
 	state->delsys = props->delivery_system;
 	state->frequency = p->frequency;
 	state->srate = p->u.qpsk.symbol_rate;
@@ -3353,7 +3464,8 @@ static int stv090x_read_status(struct dv
 			if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) {
 				reg = STV090x_READ_DEMOD(state, TSSTATUS);
 				if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) {
-					*status = FE_HAS_CARRIER |
+					*status = FE_HAS_SIGNAL |
+						  FE_HAS_CARRIER |
 						  FE_HAS_VITERBI |
 						  FE_HAS_SYNC |
 						  FE_HAS_LOCK;
@@ -3370,7 +3482,11 @@ static int stv090x_read_status(struct dv
 			if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) {
 				reg = STV090x_READ_DEMOD(state, TSSTATUS);
 				if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) {
-					*status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+					*status = FE_HAS_SIGNAL |
+						  FE_HAS_CARRIER |
+						  FE_HAS_VITERBI |
+						  FE_HAS_SYNC |
+						  FE_HAS_LOCK;
 				}
 			}
 		}
@@ -3770,6 +3886,15 @@ static void stv090x_release(struct dvb_f
 {
 	struct stv090x_state *state = fe->demodulator_priv;
 
+	state->internal->num_used--;
+	if (state->internal->num_used <= 0) {
+
+		dprintk(FE_ERROR, 1, "Actually removing");
+
+		remove_dev(state->internal);
+		kfree(state->internal);
+	}
+
 	kfree(state);
 }
 
@@ -3901,10 +4026,10 @@ static int stv090x_set_mclk(struct stv09
 	if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0)
 		goto err;
 
-	state->mclk = stv090x_get_mclk(state);
+	state->internal->mclk = stv090x_get_mclk(state);
 
 	/*Set the DiseqC frequency to 22KHz */
-	div = state->mclk / 704000;
+	div = state->internal->mclk / 704000;
 	if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0)
 		goto err;
 	if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0)
@@ -3920,7 +4045,7 @@ static int stv090x_set_tspath(struct stv
 {
 	u32 reg;
 
-	if (state->dev_ver >= 0x20) {
+	if (state->internal->dev_ver >= 0x20) {
 		switch (state->config->ts1_mode) {
 		case STV090x_TSMODE_PARALLEL_PUNCTURED:
 		case STV090x_TSMODE_DVBCI:
@@ -4092,6 +4217,71 @@ static int stv090x_set_tspath(struct stv
 	default:
 		break;
 	}
+
+	if (state->config->ts1_clk > 0) {
+		u32 speed;
+
+		switch (state->config->ts1_mode) {
+		case STV090x_TSMODE_PARALLEL_PUNCTURED:
+		case STV090x_TSMODE_DVBCI:
+		default:
+			speed = state->internal->mclk /
+				(state->config->ts1_clk / 4);
+			if (speed < 0x08)
+				speed = 0x08;
+			if (speed > 0xFF)
+				speed = 0xFF;
+			break;
+		case STV090x_TSMODE_SERIAL_PUNCTURED:
+		case STV090x_TSMODE_SERIAL_CONTINUOUS:
+			speed = state->internal->mclk /
+				(state->config->ts1_clk / 32);
+			if (speed < 0x20)
+				speed = 0x20;
+			if (speed > 0xFF)
+				speed = 0xFF;
+			break;
+		}
+		reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
+		STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
+		if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
+			goto err;
+		if (stv090x_write_reg(state, STV090x_P1_TSSPEED, speed) < 0)
+			goto err;
+	}
+
+	if (state->config->ts2_clk > 0) {
+		u32 speed;
+
+		switch (state->config->ts2_mode) {
+		case STV090x_TSMODE_PARALLEL_PUNCTURED:
+		case STV090x_TSMODE_DVBCI:
+		default:
+			speed = state->internal->mclk /
+				(state->config->ts2_clk / 4);
+			if (speed < 0x08)
+				speed = 0x08;
+			if (speed > 0xFF)
+				speed = 0xFF;
+			break;
+		case STV090x_TSMODE_SERIAL_PUNCTURED:
+		case STV090x_TSMODE_SERIAL_CONTINUOUS:
+			speed = state->internal->mclk /
+				(state->config->ts2_clk / 32);
+			if (speed < 0x20)
+				speed = 0x20;
+			if (speed > 0xFF)
+				speed = 0xFF;
+			break;
+		}
+		reg = stv090x_read_reg(state, STV090x_P2_TSCFGM);
+		STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
+		if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0)
+			goto err;
+		if (stv090x_write_reg(state, STV090x_P2_TSSPEED, speed) < 0)
+			goto err;
+	}
+
 	reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
 	STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
 	if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
@@ -4120,6 +4310,15 @@ static int stv090x_init(struct dvb_front
 	const struct stv090x_config *config = state->config;
 	u32 reg;
 
+	if (state->internal->mclk == 0) {
+		stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */
+		msleep(5);
+		if (stv090x_write_reg(state, STV090x_SYNTCTRL,
+				      0x20 | config->clk_mode) < 0)
+			goto err;
+		stv090x_get_mclk(state);
+	}
+
 	if (stv090x_wakeup(fe) < 0) {
 		dprintk(FE_ERROR, 1, "Error waking device");
 		goto err;
@@ -4142,12 +4341,12 @@ static int stv090x_init(struct dvb_front
 
 	if (config->tuner_set_mode) {
 		if (config->tuner_set_mode(fe, TUNER_WAKE) < 0)
-			goto err;
+			goto err_gateoff;
 	}
 
 	if (config->tuner_init) {
 		if (config->tuner_init(fe) < 0)
-			goto err;
+			goto err_gateoff;
 	}
 
 	if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
@@ -4157,6 +4356,9 @@ static int stv090x_init(struct dvb_front
 		goto err;
 
 	return 0;
+
+err_gateoff:
+	stv090x_i2c_gate_ctrl(fe, 0);
 err:
 	dprintk(FE_ERROR, 1, "I/O error");
 	return -1;
@@ -4188,16 +4390,26 @@ static int stv090x_setup(struct dvb_fron
 	}
 
 	/* STV090x init */
-	if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Stop Demod */
+
+	/* Stop Demod */
+	if (stv090x_write_reg(state, STV090x_P1_DMDISTATE, 0x5c) < 0)
+		goto err;
+	if (stv090x_write_reg(state, STV090x_P2_DMDISTATE, 0x5c) < 0)
 		goto err;
 
 	msleep(5);
 
-	if (STV090x_WRITE_DEMOD(state, TNRCFG, 0x6c) < 0) /* check register ! (No Tuner Mode) */
+	/* Set No Tuner Mode */
+	if (stv090x_write_reg(state, STV090x_P1_TNRCFG, 0x6c) < 0)
+		goto err;
+	if (stv090x_write_reg(state, STV090x_P2_TNRCFG, 0x6c) < 0)
 		goto err;
 
+	/* I2C repeater OFF */
 	STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level);
-	if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0) /* repeater OFF */
+	if (stv090x_write_reg(state, STV090x_P1_I2CRPT, reg) < 0)
+		goto err;
+	if (stv090x_write_reg(state, STV090x_P2_I2CRPT, reg) < 0)
 		goto err;
 
 	if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */
@@ -4216,8 +4428,8 @@ static int stv090x_setup(struct dvb_fron
 			goto err;
 	}
 
-	state->dev_ver = stv090x_read_reg(state, STV090x_MID);
-	if (state->dev_ver >= 0x20) {
+	state->internal->dev_ver = stv090x_read_reg(state, STV090x_MID);
+	if (state->internal->dev_ver >= 0x20) {
 		if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0)
 			goto err;
 
@@ -4228,27 +4440,39 @@ static int stv090x_setup(struct dvb_fron
 				goto err;
 		}
 
-	} else if (state->dev_ver < 0x20) {
+	} else if (state->internal->dev_ver < 0x20) {
 		dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!",
-			state->dev_ver);
+			state->internal->dev_ver);
 
 		goto err;
-	} else if (state->dev_ver > 0x30) {
+	} else if (state->internal->dev_ver > 0x30) {
 		/* we shouldn't bail out from here */
 		dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!",
-			state->dev_ver);
+			state->internal->dev_ver);
 	}
 
+	/* ADC1 range */
+	reg = stv090x_read_reg(state, STV090x_TSTTNR1);
+	STV090x_SETFIELD(reg, ADC1_INMODE_FIELD,
+		(config->adc1_range == STV090x_ADC_1Vpp) ? 0 : 1);
+	if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
+		goto err;
+
+	/* ADC2 range */
+	reg = stv090x_read_reg(state, STV090x_TSTTNR3);
+	STV090x_SETFIELD(reg, ADC2_INMODE_FIELD,
+		(config->adc2_range == STV090x_ADC_1Vpp) ? 0 : 1);
+	if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
+		goto err;
+
 	if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0)
 		goto err;
 	if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0)
 		goto err;
 
-	stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */
-	msleep(5);
-	if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0)
-		goto err;
-	stv090x_get_mclk(state);
+	/* workaround for stuck DiSEqC output */
+	if (config->diseqc_envelope_mode)
+		stv090x_send_diseqc_burst(fe, SEC_MINI_A);
 
 	return 0;
 err:
@@ -4299,6 +4523,7 @@ struct dvb_frontend *stv090x_attach(cons
 				    enum stv090x_demodulator demod)
 {
 	struct stv090x_state *state = NULL;
+	struct stv090x_dev *temp_int;
 
 	state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL);
 	if (state == NULL)
@@ -4314,8 +4539,32 @@ struct dvb_frontend *stv090x_attach(cons
 	state->device				= config->device;
 	state->rolloff				= STV090x_RO_35; /* default */
 
-	if (state->demod == STV090x_DEMODULATOR_0)
-		mutex_init(&demod_lock);
+	temp_int = find_dev(state->i2c,
+				state->config->address);
+
+	if ((temp_int != NULL) && (state->demod_mode == STV090x_DUAL)) {
+		state->internal = temp_int->internal;
+		state->internal->num_used++;
+		dprintk(FE_INFO, 1, "Found Internal Structure!");
+		dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
+			state->device == STV0900 ? "STV0900" : "STV0903",
+			demod,
+			state->internal->dev_ver);
+		return &state->frontend;
+	} else {
+		state->internal = kmalloc(sizeof(struct stv090x_internal),
+					  GFP_KERNEL);
+		temp_int = append_internal(state->internal);
+		state->internal->num_used = 1;
+		state->internal->mclk = 0;
+		state->internal->dev_ver = 0;
+		state->internal->i2c_adap = state->i2c;
+		state->internal->i2c_addr = state->config->address;
+		dprintk(FE_INFO, 1, "Create New Internal Structure!");
+	}
+
+	mutex_init(&state->internal->demod_lock);
+	mutex_init(&state->internal->tuner_lock);
 
 	if (stv090x_sleep(&state->frontend) < 0) {
 		dprintk(FE_ERROR, 1, "Error putting device to sleep");
@@ -4331,10 +4580,10 @@ struct dvb_frontend *stv090x_attach(cons
 		goto error;
 	}
 
-	dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x\n",
+	dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
 	       state->device == STV0900 ? "STV0900" : "STV0903",
 	       demod,
-	       state->dev_ver);
+	       state->internal->dev_ver);
 
 	return &state->frontend;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv090x.h linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv090x.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv090x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv090x.h	2010-05-16 17:17:36.000000000 -0400
@@ -60,6 +60,11 @@ enum stv090x_i2crpt {
 	STV090x_RPTLEVEL_2	= 7,
 };
 
+enum stv090x_adc_range {
+	STV090x_ADC_2Vpp	= 0,
+	STV090x_ADC_1Vpp	= 1
+};
+
 struct stv090x_config {
 	enum stv090x_device	device;
 	enum stv090x_mode	demod_mode;
@@ -68,13 +73,17 @@ struct stv090x_config {
 	u32 xtal; /* default: 8000000 */
 	u8 address; /* default: 0x68 */
 
-	u32 ref_clk; /* default: 16000000 FIXME to tuner config */
-
 	u8 ts1_mode;
 	u8 ts2_mode;
+	u32 ts1_clk;
+	u32 ts2_clk;
 
 	enum stv090x_i2crpt	repeater_level;
 
+	u8			tuner_bbgain; /* default: 10db */
+	enum stv090x_adc_range	adc1_range; /* default: 2Vpp */
+	enum stv090x_adc_range	adc2_range; /* default: 2Vpp */
+
 	bool diseqc_envelope_mode;
 
 	int (*tuner_init) (struct dvb_frontend *fe);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv090x_priv.h linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv090x_priv.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv090x_priv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv090x_priv.h	2010-05-16 17:17:36.000000000 -0400
@@ -230,11 +230,23 @@ struct stv090x_tab {
 	s32 read;
 };
 
+struct stv090x_internal {
+	struct i2c_adapter 	*i2c_adap;
+	u8			i2c_addr;
+
+	struct mutex		demod_lock; /* Lock access to shared register */
+	struct mutex		tuner_lock; /* Lock access to tuners */
+	s32			mclk; /* Masterclock Divider factor */
+	u32			dev_ver;
+
+	int			num_used;
+};
+
 struct stv090x_state {
 	enum stv090x_device		device;
 	enum stv090x_demodulator	demod;
 	enum stv090x_mode		demod_mode;
-	u32				dev_ver;
+	struct stv090x_internal		*internal;
 
 	struct i2c_adapter		*i2c;
 	const struct stv090x_config	*config;
@@ -256,11 +268,8 @@ struct stv090x_state {
 	u32				frequency;
 	u32				srate;
 
-	s32				mclk; /* Masterclock Divider factor */
 	s32				tuner_bw;
 
-	u32				tuner_refclk;
-
 	s32				search_range;
 
 	s32				DemodTimeout;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv6110.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv6110.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv6110.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv6110.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/dvb/frontend.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv6110x.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv6110x.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv6110x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv6110x.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
 #include "dvb_frontend.h"
@@ -35,8 +36,6 @@ static unsigned int verbose;
 module_param(verbose, int, 0644);
 MODULE_PARM_DESC(verbose, "Set Verbosity level");
 
-static u8 stv6110x_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e};
-
 static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data)
 {
 	int ret;
@@ -58,12 +57,23 @@ static int stv6110x_read_reg(struct stv6
 	return 0;
 }
 
-static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
+static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 data[], int len)
 {
 	int ret;
 	const struct stv6110x_config *config = stv6110x->config;
-	u8 buf[] = { reg, data };
-	struct i2c_msg msg = { .addr = config->addr, .flags = 0, . buf = buf, .len = 2 };
+	u8 buf[len + 1];
+	struct i2c_msg msg = {
+		.addr = config->addr,
+		.flags = 0,
+		.buf = buf,
+		.len = len + 1
+	};
+
+	if (start + len > 8)
+		return -EINVAL;
+
+	buf[0] = start;
+	memcpy(&buf[1], data, len);
 
 	ret = i2c_transfer(stv6110x->i2c, &msg, 1);
 	if (ret != 1) {
@@ -74,18 +84,21 @@ static int stv6110x_write_reg(struct stv
 	return 0;
 }
 
+static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
+{
+	return stv6110x_write_regs(stv6110x, reg, &data, 1);
+}
+
 static int stv6110x_init(struct dvb_frontend *fe)
 {
 	struct stv6110x_state *stv6110x = fe->tuner_priv;
 	int ret;
-	u8 i;
 
-	for (i = 0; i < ARRAY_SIZE(stv6110x_regs); i++) {
-		ret = stv6110x_write_reg(stv6110x, i, stv6110x_regs[i]);
-		if (ret < 0) {
-			dprintk(FE_ERROR, 1, "Initialization failed");
-			return -1;
-		}
+	ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs,
+				  ARRAY_SIZE(stv6110x->regs));
+	if (ret < 0) {
+		dprintk(FE_ERROR, 1, "Initialization failed");
+		return -1;
 	}
 
 	return 0;
@@ -98,23 +111,23 @@ static int stv6110x_set_frequency(struct
 	s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000;
 	u8 i;
 
-	STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16));
+	STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16));
 
 	if (frequency <= 1023000) {
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
 		pVal = 40;
 	} else if (frequency <= 1300000) {
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
 		pVal = 40;
 	} else if (frequency <= 2046000) {
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
 		pVal = 20;
 	} else {
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
 		pVal = 20;
 	}
 
@@ -130,21 +143,21 @@ static int stv6110x_set_frequency(struct
 	divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz;
 	divider = (divider + 5) / 10;
 
-	STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt);
-	STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider));
-	STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider));
+	STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt);
+	STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider));
+	STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider));
 
 	/* VCO Auto calibration */
-	STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1);
+	STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1);
 
-	stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]);
-	stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x_regs[STV6110x_TNG1]);
-	stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x_regs[STV6110x_TNG0]);
-	stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]);
+	stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]);
+	stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x->regs[STV6110x_TNG1]);
+	stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x->regs[STV6110x_TNG0]);
+	stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]);
 
 	for (i = 0; i < TRIALS; i++) {
-		stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]);
-		if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x_regs[STV6110x_STAT1]))
+		stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
+		if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x->regs[STV6110x_STAT1]))
 				break;
 		msleep(1);
 	}
@@ -156,14 +169,14 @@ static int stv6110x_get_frequency(struct
 {
 	struct stv6110x_state *stv6110x = fe->tuner_priv;
 
-	stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x_regs[STV6110x_TNG1]);
-	stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x_regs[STV6110x_TNG0]);
+	stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x->regs[STV6110x_TNG1]);
+	stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x->regs[STV6110x_TNG0]);
 
-	*frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x_regs[STV6110x_TNG1]),
-				 STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x_regs[STV6110x_TNG0]))) * REFCLOCK_kHz;
+	*frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x->regs[STV6110x_TNG1]),
+				 STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x->regs[STV6110x_TNG0]))) * REFCLOCK_kHz;
 
-	*frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x_regs[STV6110x_TNG1]) +
-			     STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x_regs[STV6110x_TNG1])));
+	*frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x->regs[STV6110x_TNG1]) +
+			     STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x->regs[STV6110x_TNG1])));
 
 	*frequency >>= 2;
 
@@ -179,27 +192,27 @@ static int stv6110x_set_bandwidth(struct
 	halfbw = bandwidth >> 1;
 
 	if (halfbw > 36000000)
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */
 	else if (halfbw < 5000000)
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */
 	else
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */
 
 
-	STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */
-	STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */
+	STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */
+	STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */
 
-	stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]);
-	stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]);
+	stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]);
+	stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]);
 
 	for (i = 0; i < TRIALS; i++) {
-		stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]);
-		if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x_regs[STV6110x_STAT1]))
+		stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
+		if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x->regs[STV6110x_STAT1]))
 			break;
 		msleep(1);
 	}
-	STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */
-	stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]);
+	STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */
+	stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]);
 
 	return 0;
 }
@@ -208,8 +221,8 @@ static int stv6110x_get_bandwidth(struct
 {
 	struct stv6110x_state *stv6110x = fe->tuner_priv;
 
-	stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x_regs[STV6110x_CTRL3]);
-	*bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x_regs[STV6110x_CTRL3]) + 5) * 2000000;
+	stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x->regs[STV6110x_CTRL3]);
+	*bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x->regs[STV6110x_CTRL3]) + 5) * 2000000;
 
 	return 0;
 }
@@ -222,20 +235,20 @@ static int stv6110x_set_refclock(struct
 	switch (refclock) {
 	default:
 	case 1:
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
 		break;
 	case 2:
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
 		break;
 	case 4:
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
 		break;
 	case 8:
 	case 0:
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
 		break;
 	}
-	stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]);
+	stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]);
 
 	return 0;
 }
@@ -244,8 +257,8 @@ static int stv6110x_get_bbgain(struct dv
 {
 	struct stv6110x_state *stv6110x = fe->tuner_priv;
 
-	stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x_regs[STV6110x_CTRL2]);
-	*gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x_regs[STV6110x_CTRL2]);
+	stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x->regs[STV6110x_CTRL2]);
+	*gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x->regs[STV6110x_CTRL2]);
 
 	return 0;
 }
@@ -254,8 +267,8 @@ static int stv6110x_set_bbgain(struct dv
 {
 	struct stv6110x_state *stv6110x = fe->tuner_priv;
 
-	STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2);
-	stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]);
+	STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2);
+	stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]);
 
 	return 0;
 }
@@ -267,19 +280,19 @@ static int stv6110x_set_mode(struct dvb_
 
 	switch (mode) {
 	case TUNER_SLEEP:
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 0);
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 0);
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 0);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 0);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 0);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 0);
 		break;
 
 	case TUNER_WAKE:
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 1);
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 1);
-		STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 1);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 1);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 1);
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 1);
 		break;
 	}
 
-	ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]);
+	ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]);
 	if (ret < 0) {
 		dprintk(FE_ERROR, 1, "I/O Error");
 		return -EIO;
@@ -297,9 +310,9 @@ static int stv6110x_get_status(struct dv
 {
 	struct stv6110x_state *stv6110x = fe->tuner_priv;
 
-	stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]);
+	stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
 
-	if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x_regs[STV6110x_STAT1]))
+	if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x->regs[STV6110x_STAT1]))
 		*status = TUNER_PHASELOCKED;
 	else
 		*status = 0;
@@ -349,6 +362,8 @@ struct stv6110x_devctl *stv6110x_attach(
 					struct i2c_adapter *i2c)
 {
 	struct stv6110x_state *stv6110x;
+	u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e};
+	int ret;
 
 	stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL);
 	if (stv6110x == NULL)
@@ -357,6 +372,44 @@ struct stv6110x_devctl *stv6110x_attach(
 	stv6110x->i2c		= i2c;
 	stv6110x->config	= config;
 	stv6110x->devctl	= &stv6110x_ctl;
+	memcpy(stv6110x->regs, default_regs, 8);
+
+	/* setup divider */
+	switch (stv6110x->config->clk_div) {
+	default:
+	case 1:
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
+		break;
+	case 2:
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
+		break;
+	case 4:
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
+		break;
+	case 8:
+	case 0:
+		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
+		break;
+	}
+
+	if (fe->ops.i2c_gate_ctrl) {
+		ret = fe->ops.i2c_gate_ctrl(fe, 1);
+		if (ret < 0)
+			goto error;
+	}
+
+	ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs,
+				  ARRAY_SIZE(stv6110x->regs));
+	if (ret < 0) {
+		dprintk(FE_ERROR, 1, "Initialization failed");
+		goto error;
+	}
+
+	if (fe->ops.i2c_gate_ctrl) {
+		ret = fe->ops.i2c_gate_ctrl(fe, 0);
+		if (ret < 0)
+			goto error;
+	}
 
 	fe->tuner_priv		= stv6110x;
 	fe->ops.tuner_ops	= stv6110x_ops;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv6110x.h linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv6110x.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv6110x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv6110x.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 struct stv6110x_config {
 	u8	addr;
 	u32	refclk;
+	u8	clk_div; /* divisor value for the output clock */
 };
 
 enum tuner_mode {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv6110x_priv.h linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv6110x_priv.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv6110x_priv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/stv6110x_priv.h	2010-05-16 17:17:36.000000000 -0400
@@ -68,6 +68,7 @@
 struct stv6110x_state {
 	struct i2c_adapter		*i2c;
 	const struct stv6110x_config	*config;
+	u8 				regs[8];
 
 	struct stv6110x_devctl		*devctl;
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/tda665x.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/tda665x.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/tda665x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/tda665x.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "tda665x.h"
@@ -133,7 +134,7 @@ static int tda665x_set_state(struct dvb_
 		frequency += config->ref_divider >> 1;
 		frequency /= config->ref_divider;
 
-		buf[0] = (u8) (frequency & 0x7f00) >> 8;
+		buf[0] = (u8) ((frequency & 0x7f00) >> 8);
 		buf[1] = (u8) (frequency & 0x00ff) >> 0;
 		buf[2] = 0x80 | 0x40 | 0x02;
 		buf[3] = 0x00;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/tda8261.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/tda8261.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/tda8261.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/tda8261.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "tda8261.h"
@@ -39,7 +40,7 @@ static int tda8261_read(struct tda8261_s
 {
 	const struct tda8261_config *config = state->config;
 	int err = 0;
-	struct i2c_msg msg = { .addr	= config->addr, .flags = I2C_M_RD,.buf = buf,  .len = 2 };
+	struct i2c_msg msg = { .addr	= config->addr, .flags = I2C_M_RD,.buf = buf,  .len = 1 };
 
 	if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
 		printk("%s: read error, err=%d\n", __func__, err);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/tda826x.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/tda826x.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/tda826x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/tda826x.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 
   */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/dvb/frontend.h>
 #include <asm/types.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/tua6100.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/tua6100.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/tua6100.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/tua6100.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/dvb/frontend.h>
 #include <asm/types.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/zl10036.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/zl10036.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/zl10036.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/zl10036.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 
 #include <linux/module.h>
 #include <linux/dvb/frontend.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include "zl10036.h"
@@ -411,7 +412,7 @@ static int zl10036_init_regs(struct zl10
 	state->bf = 0xff;
 
 	if (!state->config->rf_loop_enable)
-		zl10036_init_tab[1][2] |= 0x01;
+		zl10036_init_tab[1][0] |= 0x01;
 
 	deb_info("%s\n", __func__);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/zl10039.c linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/zl10039.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/zl10039.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/frontends/zl10039.c	2010-05-16 17:17:36.000000000 -0400
@@ -287,7 +287,6 @@ struct dvb_frontend *zl10039_attach(stru
 		break;
 	default:
 		dprintk("Chip ID=%x does not match a known type\n", state->id);
-		break;
 		goto error;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/Kconfig linux-libre-2.6.34-gnu1/drivers/media/dvb/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -76,6 +76,10 @@ comment "Supported Mantis Adapters"
 	depends on DVB_CORE && PCI && I2C
 	source "drivers/media/dvb/mantis/Kconfig"
 
+comment "Supported nGene Adapters"
+	depends on DVB_CORE && PCI && I2C
+	source "drivers/media/dvb/ngene/Kconfig"
+
 comment "Supported DVB Frontends"
 	depends on DVB_CORE
 source "drivers/media/dvb/frontends/Kconfig"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/Makefile linux-libre-2.6.34-gnu1/drivers/media/dvb/Makefile
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@ obj-y        := dvb-core/	\
 		siano/		\
 		dm1105/		\
 		pt1/		\
-		mantis/
+		mantis/		\
+		ngene/
 
 obj-$(CONFIG_DVB_FIREDTV)	+= firewire/
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/hopper_cards.c linux-libre-2.6.34-gnu1/drivers/media/dvb/mantis/hopper_cards.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/hopper_cards.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/mantis/hopper_cards.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <asm/irq.h>
 #include <linux/interrupt.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_ca.c linux-libre-2.6.34-gnu1/drivers/media/dvb/mantis/mantis_ca.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_ca.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/mantis/mantis_ca.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 */
 
 #include <linux/signal.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_cards.c linux-libre-2.6.34-gnu1/drivers/media/dvb/mantis/mantis_cards.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_cards.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/mantis/mantis_cards.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <asm/irq.h>
 #include <linux/interrupt.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_hif.c linux-libre-2.6.34-gnu1/drivers/media/dvb/mantis/mantis_hif.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_hif.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/mantis/mantis_hif.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,8 +22,6 @@
 #include <linux/signal.h>
 #include <linux/sched.h>
 
-#include <linux/signal.h>
-#include <linux/sched.h>
 #include <linux/interrupt.h>
 
 #include "dmxdev.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_input.c linux-libre-2.6.34-gnu1/drivers/media/dvb/mantis/mantis_input.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_input.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/mantis/mantis_input.c	2010-05-16 17:17:36.000000000 -0400
@@ -126,7 +126,7 @@ int mantis_input_init(struct mantis_pci
 	rc->id.version	= 1;
 	rc->dev		= mantis->pdev->dev;
 
-	err = ir_input_register(rc, &ir_mantis);
+	err = ir_input_register(rc, &ir_mantis, NULL);
 	if (err) {
 		dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err);
 		input_free_device(rc);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_pci.c linux-libre-2.6.34-gnu1/drivers/media/dvb/mantis/mantis_pci.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/mantis/mantis_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,11 +41,6 @@
 #include "dvb_frontend.h"
 #include "dvb_net.h"
 
-#include <asm/irq.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-
 #include "mantis_common.h"
 #include "mantis_reg.h"
 #include "mantis_pci.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/ngene/Kconfig linux-libre-2.6.34-gnu1/drivers/media/dvb/ngene/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/ngene/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/ngene/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,9 @@
+config DVB_NGENE
+	tristate "Micronas nGene support"
+	depends on DVB_CORE && PCI && I2C
+	select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+	select DVB_STV6110x if !DVB_FE_CUSTOMISE
+	select DVB_STV090x if !DVB_FE_CUSTOMISE
+	---help---
+	  Support for Micronas PCI express cards with nGene bridge.
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/ngene/Makefile linux-libre-2.6.34-gnu1/drivers/media/dvb/ngene/Makefile
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/ngene/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/ngene/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,11 @@
+#
+# Makefile for the nGene device driver
+#
+
+ngene-objs := ngene-core.o
+
+obj-$(CONFIG_DVB_NGENE) += ngene.o
+
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
+EXTRA_CFLAGS += -Idrivers/media/dvb/frontends/
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/ngene/ngene-core.c linux-libre-2.6.34-gnu1/drivers/media/dvb/ngene/ngene-core.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/ngene/ngene-core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/ngene/ngene-core.c	2013-05-03 09:45:53.000000000 -0400
@@ -0,0 +1,2023 @@
+/*
+ * ngene.c: nGene PCIe bridge driver
+ *
+ * Copyright (C) 2005-2007 Micronas
+ *
+ * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
+ *                         Modifications for new nGene firmware,
+ *                         support for EEPROM-copying,
+ *                         support for new dual DVB-S2 card prototype
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * You 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
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/poll.h>
+#include <linux/io.h>
+#include <asm/div64.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/smp_lock.h>
+#include <linux/timer.h>
+#include <linux/version.h>
+#include <linux/byteorder/generic.h>
+#include <linux/firmware.h>
+#include <linux/vmalloc.h>
+
+#include "ngene.h"
+
+#include "stv6110x.h"
+#include "stv090x.h"
+#include "lnbh24.h"
+
+static int one_adapter = 1;
+module_param(one_adapter, int, 0444);
+MODULE_PARM_DESC(one_adapter, "Use only one adapter.");
+
+
+static int debug;
+module_param(debug, int, 0444);
+MODULE_PARM_DESC(debug, "Print debugging information.");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define COMMAND_TIMEOUT_WORKAROUND
+
+#define dprintk	if (debug) printk
+
+#define DEVICE_NAME "ngene"
+
+#define ngwriteb(dat, adr)         writeb((dat), (char *)(dev->iomem + (adr)))
+#define ngwritel(dat, adr)         writel((dat), (char *)(dev->iomem + (adr)))
+#define ngwriteb(dat, adr)         writeb((dat), (char *)(dev->iomem + (adr)))
+#define ngreadl(adr)               readl(dev->iomem + (adr))
+#define ngreadb(adr)               readb(dev->iomem + (adr))
+#define ngcpyto(adr, src, count)   memcpy_toio((char *) \
+				   (dev->iomem + (adr)), (src), (count))
+#define ngcpyfrom(dst, adr, count) memcpy_fromio((dst), (char *) \
+				   (dev->iomem + (adr)), (count))
+
+/****************************************************************************/
+/* nGene interrupt handler **************************************************/
+/****************************************************************************/
+
+static void event_tasklet(unsigned long data)
+{
+	struct ngene *dev = (struct ngene *)data;
+
+	while (dev->EventQueueReadIndex != dev->EventQueueWriteIndex) {
+		struct EVENT_BUFFER Event =
+			dev->EventQueue[dev->EventQueueReadIndex];
+		dev->EventQueueReadIndex =
+			(dev->EventQueueReadIndex + 1) & (EVENT_QUEUE_SIZE - 1);
+
+		if ((Event.UARTStatus & 0x01) && (dev->TxEventNotify))
+			dev->TxEventNotify(dev, Event.TimeStamp);
+		if ((Event.UARTStatus & 0x02) && (dev->RxEventNotify))
+			dev->RxEventNotify(dev, Event.TimeStamp,
+					   Event.RXCharacter);
+	}
+}
+
+static void demux_tasklet(unsigned long data)
+{
+	struct ngene_channel *chan = (struct ngene_channel *)data;
+	struct SBufferHeader *Cur = chan->nextBuffer;
+
+	spin_lock_irq(&chan->state_lock);
+
+	while (Cur->ngeneBuffer.SR.Flags & 0x80) {
+		if (chan->mode & NGENE_IO_TSOUT) {
+			u32 Flags = chan->DataFormatFlags;
+			if (Cur->ngeneBuffer.SR.Flags & 0x20)
+				Flags |= BEF_OVERFLOW;
+			if (chan->pBufferExchange) {
+				if (!chan->pBufferExchange(chan,
+							   Cur->Buffer1,
+							   chan->Capture1Length,
+							   Cur->ngeneBuffer.SR.
+							   Clock, Flags)) {
+					/*
+					   We didn't get data
+					   Clear in service flag to make sure we
+					   get called on next interrupt again.
+					   leave fill/empty (0x80) flag alone
+					   to avoid hardware running out of
+					   buffers during startup, we hold only
+					   in run state ( the source may be late
+					   delivering data )
+					*/
+
+					if (chan->HWState == HWSTATE_RUN) {
+						Cur->ngeneBuffer.SR.Flags &=
+							~0x40;
+						break;
+						/* Stop proccessing stream */
+					}
+				} else {
+					/* We got a valid buffer,
+					   so switch to run state */
+					chan->HWState = HWSTATE_RUN;
+				}
+			} else {
+				printk(KERN_ERR DEVICE_NAME ": OOPS\n");
+				if (chan->HWState == HWSTATE_RUN) {
+					Cur->ngeneBuffer.SR.Flags &= ~0x40;
+					break;	/* Stop proccessing stream */
+				}
+			}
+			if (chan->AudioDTOUpdated) {
+				printk(KERN_INFO DEVICE_NAME
+				       ": Update AudioDTO = %d\n",
+				       chan->AudioDTOValue);
+				Cur->ngeneBuffer.SR.DTOUpdate =
+					chan->AudioDTOValue;
+				chan->AudioDTOUpdated = 0;
+			}
+		} else {
+			if (chan->HWState == HWSTATE_RUN) {
+				u32 Flags = 0;
+				if (Cur->ngeneBuffer.SR.Flags & 0x01)
+					Flags |= BEF_EVEN_FIELD;
+				if (Cur->ngeneBuffer.SR.Flags & 0x20)
+					Flags |= BEF_OVERFLOW;
+				if (chan->pBufferExchange)
+					chan->pBufferExchange(chan,
+							      Cur->Buffer1,
+							      chan->
+							      Capture1Length,
+							      Cur->ngeneBuffer.
+							      SR.Clock, Flags);
+				if (chan->pBufferExchange2)
+					chan->pBufferExchange2(chan,
+							       Cur->Buffer2,
+							       chan->
+							       Capture2Length,
+							       Cur->ngeneBuffer.
+							       SR.Clock, Flags);
+			} else if (chan->HWState != HWSTATE_STOP)
+				chan->HWState = HWSTATE_RUN;
+		}
+		Cur->ngeneBuffer.SR.Flags = 0x00;
+		Cur = Cur->Next;
+	}
+	chan->nextBuffer = Cur;
+
+	spin_unlock_irq(&chan->state_lock);
+}
+
+static irqreturn_t irq_handler(int irq, void *dev_id)
+{
+	struct ngene *dev = (struct ngene *)dev_id;
+	u32 icounts = 0;
+	irqreturn_t rc = IRQ_NONE;
+	u32 i = MAX_STREAM;
+	u8 *tmpCmdDoneByte;
+
+	if (dev->BootFirmware) {
+		icounts = ngreadl(NGENE_INT_COUNTS);
+		if (icounts != dev->icounts) {
+			ngwritel(0, FORCE_NMI);
+			dev->cmd_done = 1;
+			wake_up(&dev->cmd_wq);
+			dev->icounts = icounts;
+			rc = IRQ_HANDLED;
+		}
+		return rc;
+	}
+
+	ngwritel(0, FORCE_NMI);
+
+	spin_lock(&dev->cmd_lock);
+	tmpCmdDoneByte = dev->CmdDoneByte;
+	if (tmpCmdDoneByte &&
+	    (*tmpCmdDoneByte ||
+	    (dev->ngenetohost[0] == 1 && dev->ngenetohost[1] != 0))) {
+		dev->CmdDoneByte = NULL;
+		dev->cmd_done = 1;
+		wake_up(&dev->cmd_wq);
+		rc = IRQ_HANDLED;
+	}
+	spin_unlock(&dev->cmd_lock);
+
+	if (dev->EventBuffer->EventStatus & 0x80) {
+		u8 nextWriteIndex =
+			(dev->EventQueueWriteIndex + 1) &
+			(EVENT_QUEUE_SIZE - 1);
+		if (nextWriteIndex != dev->EventQueueReadIndex) {
+			dev->EventQueue[dev->EventQueueWriteIndex] =
+				*(dev->EventBuffer);
+			dev->EventQueueWriteIndex = nextWriteIndex;
+		} else {
+			printk(KERN_ERR DEVICE_NAME ": event overflow\n");
+			dev->EventQueueOverflowCount += 1;
+			dev->EventQueueOverflowFlag = 1;
+		}
+		dev->EventBuffer->EventStatus &= ~0x80;
+		tasklet_schedule(&dev->event_tasklet);
+		rc = IRQ_HANDLED;
+	}
+
+	while (i > 0) {
+		i--;
+		spin_lock(&dev->channel[i].state_lock);
+		/* if (dev->channel[i].State>=KSSTATE_RUN) { */
+		if (dev->channel[i].nextBuffer) {
+			if ((dev->channel[i].nextBuffer->
+			     ngeneBuffer.SR.Flags & 0xC0) == 0x80) {
+				dev->channel[i].nextBuffer->
+					ngeneBuffer.SR.Flags |= 0x40;
+				tasklet_schedule(
+					&dev->channel[i].demux_tasklet);
+				rc = IRQ_HANDLED;
+			}
+		}
+		spin_unlock(&dev->channel[i].state_lock);
+	}
+
+	/* Request might have been processed by a previous call. */
+	return IRQ_HANDLED;
+}
+
+/****************************************************************************/
+/* nGene command interface **************************************************/
+/****************************************************************************/
+
+static void dump_command_io(struct ngene *dev)
+{
+	u8 buf[8], *b;
+
+	ngcpyfrom(buf, HOST_TO_NGENE, 8);
+	printk(KERN_ERR "host_to_ngene (%04x): %02x %02x %02x %02x %02x %02x %02x %02x\n",
+		HOST_TO_NGENE, buf[0], buf[1], buf[2], buf[3],
+		buf[4], buf[5], buf[6], buf[7]);
+
+	ngcpyfrom(buf, NGENE_TO_HOST, 8);
+	printk(KERN_ERR "ngene_to_host (%04x): %02x %02x %02x %02x %02x %02x %02x %02x\n",
+		NGENE_TO_HOST, buf[0], buf[1], buf[2], buf[3],
+		buf[4], buf[5], buf[6], buf[7]);
+
+	b = dev->hosttongene;
+	printk(KERN_ERR "dev->hosttongene (%p): %02x %02x %02x %02x %02x %02x %02x %02x\n",
+		b, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
+
+	b = dev->ngenetohost;
+	printk(KERN_ERR "dev->ngenetohost (%p): %02x %02x %02x %02x %02x %02x %02x %02x\n",
+		b, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
+}
+
+static int ngene_command_mutex(struct ngene *dev, struct ngene_command *com)
+{
+	int ret;
+	u8 *tmpCmdDoneByte;
+
+	dev->cmd_done = 0;
+
+	if (com->cmd.hdr.Opcode == CMD_FWLOAD_PREPARE) {
+		dev->BootFirmware = 1;
+		dev->icounts = ngreadl(NGENE_INT_COUNTS);
+		ngwritel(0, NGENE_COMMAND);
+		ngwritel(0, NGENE_COMMAND_HI);
+		ngwritel(0, NGENE_STATUS);
+		ngwritel(0, NGENE_STATUS_HI);
+		ngwritel(0, NGENE_EVENT);
+		ngwritel(0, NGENE_EVENT_HI);
+	} else if (com->cmd.hdr.Opcode == CMD_FWLOAD_FINISH) {
+		u64 fwio = dev->PAFWInterfaceBuffer;
+
+		ngwritel(fwio & 0xffffffff, NGENE_COMMAND);
+		ngwritel(fwio >> 32, NGENE_COMMAND_HI);
+		ngwritel((fwio + 256) & 0xffffffff, NGENE_STATUS);
+		ngwritel((fwio + 256) >> 32, NGENE_STATUS_HI);
+		ngwritel((fwio + 512) & 0xffffffff, NGENE_EVENT);
+		ngwritel((fwio + 512) >> 32, NGENE_EVENT_HI);
+	}
+
+	memcpy(dev->FWInterfaceBuffer, com->cmd.raw8, com->in_len + 2);
+
+	if (dev->BootFirmware)
+		ngcpyto(HOST_TO_NGENE, com->cmd.raw8, com->in_len + 2);
+
+	spin_lock_irq(&dev->cmd_lock);
+	tmpCmdDoneByte = dev->ngenetohost + com->out_len;
+	if (!com->out_len)
+		tmpCmdDoneByte++;
+	*tmpCmdDoneByte = 0;
+	dev->ngenetohost[0] = 0;
+	dev->ngenetohost[1] = 0;
+	dev->CmdDoneByte = tmpCmdDoneByte;
+	spin_unlock_irq(&dev->cmd_lock);
+
+	/* Notify 8051. */
+	ngwritel(1, FORCE_INT);
+
+	ret = wait_event_timeout(dev->cmd_wq, dev->cmd_done == 1, 2 * HZ);
+	if (!ret) {
+		/*ngwritel(0, FORCE_NMI);*/
+
+		printk(KERN_ERR DEVICE_NAME
+		       ": Command timeout cmd=%02x prev=%02x\n",
+		       com->cmd.hdr.Opcode, dev->prev_cmd);
+		dump_command_io(dev);
+		return -1;
+	}
+	if (com->cmd.hdr.Opcode == CMD_FWLOAD_FINISH)
+		dev->BootFirmware = 0;
+
+	dev->prev_cmd = com->cmd.hdr.Opcode;
+
+	if (!com->out_len)
+		return 0;
+
+	memcpy(com->cmd.raw8, dev->ngenetohost, com->out_len);
+
+	return 0;
+}
+
+static int ngene_command(struct ngene *dev, struct ngene_command *com)
+{
+	int result;
+
+	down(&dev->cmd_mutex);
+	result = ngene_command_mutex(dev, com);
+	up(&dev->cmd_mutex);
+	return result;
+}
+
+
+static int ngene_command_i2c_read(struct ngene *dev, u8 adr,
+			   u8 *out, u8 outlen, u8 *in, u8 inlen, int flag)
+{
+	struct ngene_command com;
+
+	com.cmd.hdr.Opcode = CMD_I2C_READ;
+	com.cmd.hdr.Length = outlen + 3;
+	com.cmd.I2CRead.Device = adr << 1;
+	memcpy(com.cmd.I2CRead.Data, out, outlen);
+	com.cmd.I2CRead.Data[outlen] = inlen;
+	com.cmd.I2CRead.Data[outlen + 1] = 0;
+	com.in_len = outlen + 3;
+	com.out_len = inlen + 1;
+
+	if (ngene_command(dev, &com) < 0)
+		return -EIO;
+
+	if ((com.cmd.raw8[0] >> 1) != adr)
+		return -EIO;
+
+	if (flag)
+		memcpy(in, com.cmd.raw8, inlen + 1);
+	else
+		memcpy(in, com.cmd.raw8 + 1, inlen);
+	return 0;
+}
+
+static int ngene_command_i2c_write(struct ngene *dev, u8 adr,
+				   u8 *out, u8 outlen)
+{
+	struct ngene_command com;
+
+
+	com.cmd.hdr.Opcode = CMD_I2C_WRITE;
+	com.cmd.hdr.Length = outlen + 1;
+	com.cmd.I2CRead.Device = adr << 1;
+	memcpy(com.cmd.I2CRead.Data, out, outlen);
+	com.in_len = outlen + 1;
+	com.out_len = 1;
+
+	if (ngene_command(dev, &com) < 0)
+		return -EIO;
+
+	if (com.cmd.raw8[0] == 1)
+		return -EIO;
+
+	return 0;
+}
+
+static int ngene_command_load_firmware(struct ngene *dev,
+				       u8 *ngene_fw, u32 size)
+{
+#define FIRSTCHUNK (1024)
+	u32 cleft;
+	struct ngene_command com;
+
+	com.cmd.hdr.Opcode = CMD_FWLOAD_PREPARE;
+	com.cmd.hdr.Length = 0;
+	com.in_len = 0;
+	com.out_len = 0;
+
+	ngene_command(dev, &com);
+
+	cleft = (size + 3) & ~3;
+	if (cleft > FIRSTCHUNK) {
+		ngcpyto(PROGRAM_SRAM + FIRSTCHUNK, ngene_fw + FIRSTCHUNK,
+			cleft - FIRSTCHUNK);
+		cleft = FIRSTCHUNK;
+	}
+	ngcpyto(DATA_FIFO_AREA, ngene_fw, cleft);
+
+	memset(&com, 0, sizeof(struct ngene_command));
+	com.cmd.hdr.Opcode = CMD_FWLOAD_FINISH;
+	com.cmd.hdr.Length = 4;
+	com.cmd.FWLoadFinish.Address = DATA_FIFO_AREA;
+	com.cmd.FWLoadFinish.Length = (unsigned short)cleft;
+	com.in_len = 4;
+	com.out_len = 0;
+
+	return ngene_command(dev, &com);
+}
+
+
+static int ngene_command_config_buf(struct ngene *dev, u8 config)
+{
+	struct ngene_command com;
+
+	com.cmd.hdr.Opcode = CMD_CONFIGURE_BUFFER;
+	com.cmd.hdr.Length = 1;
+	com.cmd.ConfigureBuffers.config = config;
+	com.in_len = 1;
+	com.out_len = 0;
+
+	if (ngene_command(dev, &com) < 0)
+		return -EIO;
+	return 0;
+}
+
+static int ngene_command_config_free_buf(struct ngene *dev, u8 *config)
+{
+	struct ngene_command com;
+
+	com.cmd.hdr.Opcode = CMD_CONFIGURE_FREE_BUFFER;
+	com.cmd.hdr.Length = 6;
+	memcpy(&com.cmd.ConfigureBuffers.config, config, 6);
+	com.in_len = 6;
+	com.out_len = 0;
+
+	if (ngene_command(dev, &com) < 0)
+		return -EIO;
+
+	return 0;
+}
+
+static int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level)
+{
+	struct ngene_command com;
+
+	com.cmd.hdr.Opcode = CMD_SET_GPIO_PIN;
+	com.cmd.hdr.Length = 1;
+	com.cmd.SetGpioPin.select = select | (level << 7);
+	com.in_len = 1;
+	com.out_len = 0;
+
+	return ngene_command(dev, &com);
+}
+
+
+/*
+ 02000640 is sample on rising edge.
+ 02000740 is sample on falling edge.
+ 02000040 is ignore "valid" signal
+
+ 0: FD_CTL1 Bit 7,6 must be 0,1
+    7   disable(fw controlled)
+    6   0-AUX,1-TS
+    5   0-par,1-ser
+    4   0-lsb/1-msb
+    3,2 reserved
+    1,0 0-no sync, 1-use ext. start, 2-use 0x47, 3-both
+ 1: FD_CTL2 has 3-valid must be hi, 2-use valid, 1-edge
+ 2: FD_STA is read-only. 0-sync
+ 3: FD_INSYNC is number of 47s to trigger "in sync".
+ 4: FD_OUTSYNC is number of 47s to trigger "out of sync".
+ 5: FD_MAXBYTE1 is low-order of bytes per packet.
+ 6: FD_MAXBYTE2 is high-order of bytes per packet.
+ 7: Top byte is unused.
+*/
+
+/****************************************************************************/
+
+static u8 TSFeatureDecoderSetup[8 * 4] = {
+	0x42, 0x00, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00,
+	0x40, 0x06, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00,	/* DRXH */
+	0x71, 0x07, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00,	/* DRXHser */
+	0x72, 0x06, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00,	/* S2ser */
+};
+
+/* Set NGENE I2S Config to 16 bit packed */
+static u8 I2SConfiguration[] = {
+	0x00, 0x10, 0x00, 0x00,
+	0x80, 0x10, 0x00, 0x00,
+};
+
+static u8 SPDIFConfiguration[10] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* Set NGENE I2S Config to transport stream compatible mode */
+
+static u8 TS_I2SConfiguration[4] = { 0x3E, 0x1A, 0x00, 0x00 }; /*3e 18 00 00 ?*/
+
+static u8 TS_I2SOutConfiguration[4] = { 0x80, 0x20, 0x00, 0x00 };
+
+static u8 ITUDecoderSetup[4][16] = {
+	{0x1c, 0x13, 0x01, 0x68, 0x3d, 0x90, 0x14, 0x20,  /* SDTV */
+	 0x00, 0x00, 0x01, 0xb0, 0x9c, 0x00, 0x00, 0x00},
+	{0x9c, 0x03, 0x23, 0xC0, 0x60, 0x0E, 0x13, 0x00,
+	 0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00},
+	{0x9f, 0x00, 0x23, 0xC0, 0x60, 0x0F, 0x13, 0x00,  /* HDTV 1080i50 */
+	 0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00},
+	{0x9c, 0x01, 0x23, 0xC0, 0x60, 0x0E, 0x13, 0x00,  /* HDTV 1080i60 */
+	 0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00},
+};
+
+/*
+ * 50 48 60 gleich
+ * 27p50 9f 00 22 80 42 69 18 ...
+ * 27p60 93 00 22 80 82 69 1c ...
+ */
+
+/* Maxbyte to 1144 (for raw data) */
+static u8 ITUFeatureDecoderSetup[8] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x04, 0x00
+};
+
+static void FillTSBuffer(void *Buffer, int Length, u32 Flags)
+{
+	u32 *ptr = Buffer;
+
+	memset(Buffer, 0xff, Length);
+	while (Length > 0) {
+		if (Flags & DF_SWAP32)
+			*ptr = 0x471FFF10;
+		else
+			*ptr = 0x10FF1F47;
+		ptr += (188 / 4);
+		Length -= 188;
+	}
+}
+
+
+static void flush_buffers(struct ngene_channel *chan)
+{
+	u8 val;
+
+	do {
+		msleep(1);
+		spin_lock_irq(&chan->state_lock);
+		val = chan->nextBuffer->ngeneBuffer.SR.Flags & 0x80;
+		spin_unlock_irq(&chan->state_lock);
+	} while (val);
+}
+
+static void clear_buffers(struct ngene_channel *chan)
+{
+	struct SBufferHeader *Cur = chan->nextBuffer;
+
+	do {
+		memset(&Cur->ngeneBuffer.SR, 0, sizeof(Cur->ngeneBuffer.SR));
+		if (chan->mode & NGENE_IO_TSOUT)
+			FillTSBuffer(Cur->Buffer1,
+				     chan->Capture1Length,
+				     chan->DataFormatFlags);
+		Cur = Cur->Next;
+	} while (Cur != chan->nextBuffer);
+
+	if (chan->mode & NGENE_IO_TSOUT) {
+		chan->nextBuffer->ngeneBuffer.SR.DTOUpdate =
+			chan->AudioDTOValue;
+		chan->AudioDTOUpdated = 0;
+
+		Cur = chan->TSIdleBuffer.Head;
+
+		do {
+			memset(&Cur->ngeneBuffer.SR, 0,
+			       sizeof(Cur->ngeneBuffer.SR));
+			FillTSBuffer(Cur->Buffer1,
+				     chan->Capture1Length,
+				     chan->DataFormatFlags);
+			Cur = Cur->Next;
+		} while (Cur != chan->TSIdleBuffer.Head);
+	}
+}
+
+static int ngene_command_stream_control(struct ngene *dev, u8 stream,
+					u8 control, u8 mode, u8 flags)
+{
+	struct ngene_channel *chan = &dev->channel[stream];
+	struct ngene_command com;
+	u16 BsUVI = ((stream & 1) ? 0x9400 : 0x9300);
+	u16 BsSDI = ((stream & 1) ? 0x9600 : 0x9500);
+	u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700);
+	u16 BsSDO = 0x9B00;
+
+	/* down(&dev->stream_mutex); */
+	while (down_trylock(&dev->stream_mutex)) {
+		printk(KERN_INFO DEVICE_NAME ": SC locked\n");
+		msleep(1);
+	}
+	memset(&com, 0, sizeof(com));
+	com.cmd.hdr.Opcode = CMD_CONTROL;
+	com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2;
+	com.cmd.StreamControl.Stream = stream | (control ? 8 : 0);
+	if (chan->mode & NGENE_IO_TSOUT)
+		com.cmd.StreamControl.Stream |= 0x07;
+	com.cmd.StreamControl.Control = control |
+		(flags & SFLAG_ORDER_LUMA_CHROMA);
+	com.cmd.StreamControl.Mode = mode;
+	com.in_len = sizeof(struct FW_STREAM_CONTROL);
+	com.out_len = 0;
+
+	dprintk(KERN_INFO DEVICE_NAME
+		": Stream=%02x, Control=%02x, Mode=%02x\n",
+		com.cmd.StreamControl.Stream, com.cmd.StreamControl.Control,
+		com.cmd.StreamControl.Mode);
+
+	chan->Mode = mode;
+
+	if (!(control & 0x80)) {
+		spin_lock_irq(&chan->state_lock);
+		if (chan->State == KSSTATE_RUN) {
+			chan->State = KSSTATE_ACQUIRE;
+			chan->HWState = HWSTATE_STOP;
+			spin_unlock_irq(&chan->state_lock);
+			if (ngene_command(dev, &com) < 0) {
+				up(&dev->stream_mutex);
+				return -1;
+			}
+			/* clear_buffers(chan); */
+			flush_buffers(chan);
+			up(&dev->stream_mutex);
+			return 0;
+		}
+		spin_unlock_irq(&chan->state_lock);
+		up(&dev->stream_mutex);
+		return 0;
+	}
+
+	if (mode & SMODE_AUDIO_CAPTURE) {
+		com.cmd.StreamControl.CaptureBlockCount =
+			chan->Capture1Length / AUDIO_BLOCK_SIZE;
+		com.cmd.StreamControl.Buffer_Address = chan->RingBuffer.PAHead;
+	} else if (mode & SMODE_TRANSPORT_STREAM) {
+		com.cmd.StreamControl.CaptureBlockCount =
+			chan->Capture1Length / TS_BLOCK_SIZE;
+		com.cmd.StreamControl.MaxLinesPerField =
+			chan->Capture1Length / TS_BLOCK_SIZE;
+		com.cmd.StreamControl.Buffer_Address =
+			chan->TSRingBuffer.PAHead;
+		if (chan->mode & NGENE_IO_TSOUT) {
+			com.cmd.StreamControl.BytesPerVBILine =
+				chan->Capture1Length / TS_BLOCK_SIZE;
+			com.cmd.StreamControl.Stream |= 0x07;
+		}
+	} else {
+		com.cmd.StreamControl.BytesPerVideoLine = chan->nBytesPerLine;
+		com.cmd.StreamControl.MaxLinesPerField = chan->nLines;
+		com.cmd.StreamControl.MinLinesPerField = 100;
+		com.cmd.StreamControl.Buffer_Address = chan->RingBuffer.PAHead;
+
+		if (mode & SMODE_VBI_CAPTURE) {
+			com.cmd.StreamControl.MaxVBILinesPerField =
+				chan->nVBILines;
+			com.cmd.StreamControl.MinVBILinesPerField = 0;
+			com.cmd.StreamControl.BytesPerVBILine =
+				chan->nBytesPerVBILine;
+		}
+		if (flags & SFLAG_COLORBAR)
+			com.cmd.StreamControl.Stream |= 0x04;
+	}
+
+	spin_lock_irq(&chan->state_lock);
+	if (mode & SMODE_AUDIO_CAPTURE) {
+		chan->nextBuffer = chan->RingBuffer.Head;
+		if (mode & SMODE_AUDIO_SPDIF) {
+			com.cmd.StreamControl.SetupDataLen =
+				sizeof(SPDIFConfiguration);
+			com.cmd.StreamControl.SetupDataAddr = BsSPI;
+			memcpy(com.cmd.StreamControl.SetupData,
+			       SPDIFConfiguration, sizeof(SPDIFConfiguration));
+		} else {
+			com.cmd.StreamControl.SetupDataLen = 4;
+			com.cmd.StreamControl.SetupDataAddr = BsSDI;
+			memcpy(com.cmd.StreamControl.SetupData,
+			       I2SConfiguration +
+			       4 * dev->card_info->i2s[stream], 4);
+		}
+	} else if (mode & SMODE_TRANSPORT_STREAM) {
+		chan->nextBuffer = chan->TSRingBuffer.Head;
+		if (stream >= STREAM_AUDIOIN1) {
+			if (chan->mode & NGENE_IO_TSOUT) {
+				com.cmd.StreamControl.SetupDataLen =
+					sizeof(TS_I2SOutConfiguration);
+				com.cmd.StreamControl.SetupDataAddr = BsSDO;
+				memcpy(com.cmd.StreamControl.SetupData,
+				       TS_I2SOutConfiguration,
+				       sizeof(TS_I2SOutConfiguration));
+			} else {
+				com.cmd.StreamControl.SetupDataLen =
+					sizeof(TS_I2SConfiguration);
+				com.cmd.StreamControl.SetupDataAddr = BsSDI;
+				memcpy(com.cmd.StreamControl.SetupData,
+				       TS_I2SConfiguration,
+				       sizeof(TS_I2SConfiguration));
+			}
+		} else {
+			com.cmd.StreamControl.SetupDataLen = 8;
+			com.cmd.StreamControl.SetupDataAddr = BsUVI + 0x10;
+			memcpy(com.cmd.StreamControl.SetupData,
+			       TSFeatureDecoderSetup +
+			       8 * dev->card_info->tsf[stream], 8);
+		}
+	} else {
+		chan->nextBuffer = chan->RingBuffer.Head;
+		com.cmd.StreamControl.SetupDataLen =
+			16 + sizeof(ITUFeatureDecoderSetup);
+		com.cmd.StreamControl.SetupDataAddr = BsUVI;
+		memcpy(com.cmd.StreamControl.SetupData,
+		       ITUDecoderSetup[chan->itumode], 16);
+		memcpy(com.cmd.StreamControl.SetupData + 16,
+		       ITUFeatureDecoderSetup, sizeof(ITUFeatureDecoderSetup));
+	}
+	clear_buffers(chan);
+	chan->State = KSSTATE_RUN;
+	if (mode & SMODE_TRANSPORT_STREAM)
+		chan->HWState = HWSTATE_RUN;
+	else
+		chan->HWState = HWSTATE_STARTUP;
+	spin_unlock_irq(&chan->state_lock);
+
+	if (ngene_command(dev, &com) < 0) {
+		up(&dev->stream_mutex);
+		return -1;
+	}
+	up(&dev->stream_mutex);
+	return 0;
+}
+
+
+/****************************************************************************/
+/* I2C **********************************************************************/
+/****************************************************************************/
+
+static void ngene_i2c_set_bus(struct ngene *dev, int bus)
+{
+	if (!(dev->card_info->i2c_access & 2))
+		return;
+	if (dev->i2c_current_bus == bus)
+		return;
+
+	switch (bus) {
+	case 0:
+		ngene_command_gpio_set(dev, 3, 0);
+		ngene_command_gpio_set(dev, 2, 1);
+		break;
+
+	case 1:
+		ngene_command_gpio_set(dev, 2, 0);
+		ngene_command_gpio_set(dev, 3, 1);
+		break;
+	}
+	dev->i2c_current_bus = bus;
+}
+
+static int ngene_i2c_master_xfer(struct i2c_adapter *adapter,
+				 struct i2c_msg msg[], int num)
+{
+	struct ngene_channel *chan =
+		(struct ngene_channel *)i2c_get_adapdata(adapter);
+	struct ngene *dev = chan->dev;
+
+	down(&dev->i2c_switch_mutex);
+	ngene_i2c_set_bus(dev, chan->number);
+
+	if (num == 2 && msg[1].flags & I2C_M_RD && !(msg[0].flags & I2C_M_RD))
+		if (!ngene_command_i2c_read(dev, msg[0].addr,
+					    msg[0].buf, msg[0].len,
+					    msg[1].buf, msg[1].len, 0))
+			goto done;
+
+	if (num == 1 && !(msg[0].flags & I2C_M_RD))
+		if (!ngene_command_i2c_write(dev, msg[0].addr,
+					     msg[0].buf, msg[0].len))
+			goto done;
+	if (num == 1 && (msg[0].flags & I2C_M_RD))
+		if (!ngene_command_i2c_read(dev, msg[0].addr, 0, 0,
+					    msg[0].buf, msg[0].len, 0))
+			goto done;
+
+	up(&dev->i2c_switch_mutex);
+	return -EIO;
+
+done:
+	up(&dev->i2c_switch_mutex);
+	return num;
+}
+
+
+static u32 ngene_i2c_functionality(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm ngene_i2c_algo = {
+	.master_xfer = ngene_i2c_master_xfer,
+	.functionality = ngene_i2c_functionality,
+};
+
+static int ngene_i2c_init(struct ngene *dev, int dev_nr)
+{
+	struct i2c_adapter *adap = &(dev->channel[dev_nr].i2c_adapter);
+
+	i2c_set_adapdata(adap, &(dev->channel[dev_nr]));
+	adap->class = I2C_CLASS_TV_DIGITAL | I2C_CLASS_TV_ANALOG;
+
+	strcpy(adap->name, "nGene");
+
+	adap->algo = &ngene_i2c_algo;
+	adap->algo_data = (void *)&(dev->channel[dev_nr]);
+	adap->dev.parent = &dev->pci_dev->dev;
+
+	return i2c_add_adapter(adap);
+}
+
+
+/****************************************************************************/
+/* DVB functions and API interface ******************************************/
+/****************************************************************************/
+
+static void swap_buffer(u32 *p, u32 len)
+{
+	while (len) {
+		*p = swab32(*p);
+		p++;
+		len -= 4;
+	}
+}
+
+
+static void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
+{
+	struct ngene_channel *chan = priv;
+
+
+#ifdef COMMAND_TIMEOUT_WORKAROUND
+	if (chan->users > 0)
+#endif
+		dvb_dmx_swfilter(&chan->demux, buf, len);
+	return 0;
+}
+
+u8 fill_ts[188] = { 0x47, 0x1f, 0xff, 0x10 };
+
+static void *tsout_exchange(void *priv, void *buf, u32 len,
+			    u32 clock, u32 flags)
+{
+	struct ngene_channel *chan = priv;
+	struct ngene *dev = chan->dev;
+	u32 alen;
+
+	alen = dvb_ringbuffer_avail(&dev->tsout_rbuf);
+	alen -= alen % 188;
+
+	if (alen < len)
+		FillTSBuffer(buf + alen, len - alen, flags);
+	else
+		alen = len;
+	dvb_ringbuffer_read(&dev->tsout_rbuf, buf, alen);
+	if (flags & DF_SWAP32)
+		swap_buffer((u32 *)buf, alen);
+	wake_up_interruptible(&dev->tsout_rbuf.queue);
+	return buf;
+}
+
+
+static void set_transfer(struct ngene_channel *chan, int state)
+{
+	u8 control = 0, mode = 0, flags = 0;
+	struct ngene *dev = chan->dev;
+	int ret;
+
+	/*
+	printk(KERN_INFO DEVICE_NAME ": st %d\n", state);
+	msleep(100);
+	*/
+
+	if (state) {
+		if (chan->running) {
+			printk(KERN_INFO DEVICE_NAME ": already running\n");
+			return;
+		}
+	} else {
+		if (!chan->running) {
+			printk(KERN_INFO DEVICE_NAME ": already stopped\n");
+			return;
+		}
+	}
+
+	if (dev->card_info->switch_ctrl)
+		dev->card_info->switch_ctrl(chan, 1, state ^ 1);
+
+	if (state) {
+		spin_lock_irq(&chan->state_lock);
+
+		/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n",
+			  ngreadl(0x9310)); */
+		dvb_ringbuffer_flush(&dev->tsout_rbuf);
+		control = 0x80;
+		if (chan->mode & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
+			chan->Capture1Length = 512 * 188;
+			mode = SMODE_TRANSPORT_STREAM;
+		}
+		if (chan->mode & NGENE_IO_TSOUT) {
+			chan->pBufferExchange = tsout_exchange;
+			/* 0x66666666 = 50MHz *2^33 /250MHz */
+			chan->AudioDTOValue = 0x66666666;
+			/* set_dto(chan, 38810700+1000); */
+			/* set_dto(chan, 19392658); */
+		}
+		if (chan->mode & NGENE_IO_TSIN)
+			chan->pBufferExchange = tsin_exchange;
+		/* ngwritel(0, 0x9310); */
+		spin_unlock_irq(&chan->state_lock);
+	} else
+		;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n",
+			   ngreadl(0x9310)); */
+
+	ret = ngene_command_stream_control(dev, chan->number,
+					   control, mode, flags);
+	if (!ret)
+		chan->running = state;
+	else
+		printk(KERN_ERR DEVICE_NAME ": set_transfer %d failed\n",
+		       state);
+	if (!state) {
+		spin_lock_irq(&chan->state_lock);
+		chan->pBufferExchange = 0;
+		dvb_ringbuffer_flush(&dev->tsout_rbuf);
+		spin_unlock_irq(&chan->state_lock);
+	}
+}
+
+static int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+	struct ngene_channel *chan = dvbdmx->priv;
+
+	if (chan->users == 0) {
+#ifdef COMMAND_TIMEOUT_WORKAROUND
+		if (!chan->running)
+#endif
+			set_transfer(chan, 1);
+		/* msleep(10); */
+	}
+
+	return ++chan->users;
+}
+
+static int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+	struct ngene_channel *chan = dvbdmx->priv;
+
+	if (--chan->users)
+		return chan->users;
+
+#ifndef COMMAND_TIMEOUT_WORKAROUND
+	set_transfer(chan, 0);
+#endif
+
+	return 0;
+}
+
+
+
+static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id,
+				   int (*start_feed)(struct dvb_demux_feed *),
+				   int (*stop_feed)(struct dvb_demux_feed *),
+				   void *priv)
+{
+	dvbdemux->priv = priv;
+
+	dvbdemux->filternum = 256;
+	dvbdemux->feednum = 256;
+	dvbdemux->start_feed = start_feed;
+	dvbdemux->stop_feed = stop_feed;
+	dvbdemux->write_to_decoder = 0;
+	dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
+				      DMX_SECTION_FILTERING |
+				      DMX_MEMORY_BASED_FILTERING);
+	return dvb_dmx_init(dvbdemux);
+}
+
+static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev,
+				      struct dvb_demux *dvbdemux,
+				      struct dmx_frontend *hw_frontend,
+				      struct dmx_frontend *mem_frontend,
+				      struct dvb_adapter *dvb_adapter)
+{
+	int ret;
+
+	dmxdev->filternum = 256;
+	dmxdev->demux = &dvbdemux->dmx;
+	dmxdev->capabilities = 0;
+	ret = dvb_dmxdev_init(dmxdev, dvb_adapter);
+	if (ret < 0)
+		return ret;
+
+	hw_frontend->source = DMX_FRONTEND_0;
+	dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend);
+	mem_frontend->source = DMX_MEMORY_FE;
+	dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend);
+	return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend);
+}
+
+
+/****************************************************************************/
+/* nGene hardware init and release functions ********************************/
+/****************************************************************************/
+
+static void free_ringbuffer(struct ngene *dev, struct SRingBufferDescriptor *rb)
+{
+	struct SBufferHeader *Cur = rb->Head;
+	u32 j;
+
+	if (!Cur)
+		return;
+
+	for (j = 0; j < rb->NumBuffers; j++, Cur = Cur->Next) {
+		if (Cur->Buffer1)
+			pci_free_consistent(dev->pci_dev,
+					    rb->Buffer1Length,
+					    Cur->Buffer1,
+					    Cur->scList1->Address);
+
+		if (Cur->Buffer2)
+			pci_free_consistent(dev->pci_dev,
+					    rb->Buffer2Length,
+					    Cur->Buffer2,
+					    Cur->scList2->Address);
+	}
+
+	if (rb->SCListMem)
+		pci_free_consistent(dev->pci_dev, rb->SCListMemSize,
+				    rb->SCListMem, rb->PASCListMem);
+
+	pci_free_consistent(dev->pci_dev, rb->MemSize, rb->Head, rb->PAHead);
+}
+
+static void free_idlebuffer(struct ngene *dev,
+		     struct SRingBufferDescriptor *rb,
+		     struct SRingBufferDescriptor *tb)
+{
+	int j;
+	struct SBufferHeader *Cur = tb->Head;
+
+	if (!rb->Head)
+		return;
+	free_ringbuffer(dev, rb);
+	for (j = 0; j < tb->NumBuffers; j++, Cur = Cur->Next) {
+		Cur->Buffer2 = 0;
+		Cur->scList2 = 0;
+		Cur->ngeneBuffer.Address_of_first_entry_2 = 0;
+		Cur->ngeneBuffer.Number_of_entries_2 = 0;
+	}
+}
+
+static void free_common_buffers(struct ngene *dev)
+{
+	u32 i;
+	struct ngene_channel *chan;
+
+	for (i = STREAM_VIDEOIN1; i < MAX_STREAM; i++) {
+		chan = &dev->channel[i];
+		free_idlebuffer(dev, &chan->TSIdleBuffer, &chan->TSRingBuffer);
+		free_ringbuffer(dev, &chan->RingBuffer);
+		free_ringbuffer(dev, &chan->TSRingBuffer);
+	}
+
+	if (dev->OverflowBuffer)
+		pci_free_consistent(dev->pci_dev,
+				    OVERFLOW_BUFFER_SIZE,
+				    dev->OverflowBuffer, dev->PAOverflowBuffer);
+
+	if (dev->FWInterfaceBuffer)
+		pci_free_consistent(dev->pci_dev,
+				    4096,
+				    dev->FWInterfaceBuffer,
+				    dev->PAFWInterfaceBuffer);
+}
+
+/****************************************************************************/
+/* Ring buffer handling *****************************************************/
+/****************************************************************************/
+
+static int create_ring_buffer(struct pci_dev *pci_dev,
+		       struct SRingBufferDescriptor *descr, u32 NumBuffers)
+{
+	dma_addr_t tmp;
+	struct SBufferHeader *Head;
+	u32 i;
+	u32 MemSize = SIZEOF_SBufferHeader * NumBuffers;
+	u64 PARingBufferHead;
+	u64 PARingBufferCur;
+	u64 PARingBufferNext;
+	struct SBufferHeader *Cur, *Next;
+
+	descr->Head = 0;
+	descr->MemSize = 0;
+	descr->PAHead = 0;
+	descr->NumBuffers = 0;
+
+	if (MemSize < 4096)
+		MemSize = 4096;
+
+	Head = pci_alloc_consistent(pci_dev, MemSize, &tmp);
+	PARingBufferHead = tmp;
+
+	if (!Head)
+		return -ENOMEM;
+
+	memset(Head, 0, MemSize);
+
+	PARingBufferCur = PARingBufferHead;
+	Cur = Head;
+
+	for (i = 0; i < NumBuffers - 1; i++) {
+		Next = (struct SBufferHeader *)
+			(((u8 *) Cur) + SIZEOF_SBufferHeader);
+		PARingBufferNext = PARingBufferCur + SIZEOF_SBufferHeader;
+		Cur->Next = Next;
+		Cur->ngeneBuffer.Next = PARingBufferNext;
+		Cur = Next;
+		PARingBufferCur = PARingBufferNext;
+	}
+	/* Last Buffer points back to first one */
+	Cur->Next = Head;
+	Cur->ngeneBuffer.Next = PARingBufferHead;
+
+	descr->Head       = Head;
+	descr->MemSize    = MemSize;
+	descr->PAHead     = PARingBufferHead;
+	descr->NumBuffers = NumBuffers;
+
+	return 0;
+}
+
+static int AllocateRingBuffers(struct pci_dev *pci_dev,
+			       dma_addr_t of,
+			       struct SRingBufferDescriptor *pRingBuffer,
+			       u32 Buffer1Length, u32 Buffer2Length)
+{
+	dma_addr_t tmp;
+	u32 i, j;
+	int status = 0;
+	u32 SCListMemSize = pRingBuffer->NumBuffers
+		* ((Buffer2Length != 0) ? (NUM_SCATTER_GATHER_ENTRIES * 2) :
+		    NUM_SCATTER_GATHER_ENTRIES)
+		* sizeof(struct HW_SCATTER_GATHER_ELEMENT);
+
+	u64 PASCListMem;
+	struct HW_SCATTER_GATHER_ELEMENT *SCListEntry;
+	u64 PASCListEntry;
+	struct SBufferHeader *Cur;
+	void *SCListMem;
+
+	if (SCListMemSize < 4096)
+		SCListMemSize = 4096;
+
+	SCListMem = pci_alloc_consistent(pci_dev, SCListMemSize, &tmp);
+
+	PASCListMem = tmp;
+	if (SCListMem == NULL)
+		return -ENOMEM;
+
+	memset(SCListMem, 0, SCListMemSize);
+
+	pRingBuffer->SCListMem = SCListMem;
+	pRingBuffer->PASCListMem = PASCListMem;
+	pRingBuffer->SCListMemSize = SCListMemSize;
+	pRingBuffer->Buffer1Length = Buffer1Length;
+	pRingBuffer->Buffer2Length = Buffer2Length;
+
+	SCListEntry = SCListMem;
+	PASCListEntry = PASCListMem;
+	Cur = pRingBuffer->Head;
+
+	for (i = 0; i < pRingBuffer->NumBuffers; i += 1, Cur = Cur->Next) {
+		u64 PABuffer;
+
+		void *Buffer = pci_alloc_consistent(pci_dev, Buffer1Length,
+						    &tmp);
+		PABuffer = tmp;
+
+		if (Buffer == NULL)
+			return -ENOMEM;
+
+		Cur->Buffer1 = Buffer;
+
+		SCListEntry->Address = PABuffer;
+		SCListEntry->Length  = Buffer1Length;
+
+		Cur->scList1 = SCListEntry;
+		Cur->ngeneBuffer.Address_of_first_entry_1 = PASCListEntry;
+		Cur->ngeneBuffer.Number_of_entries_1 =
+			NUM_SCATTER_GATHER_ENTRIES;
+
+		SCListEntry += 1;
+		PASCListEntry += sizeof(struct HW_SCATTER_GATHER_ELEMENT);
+
+#if NUM_SCATTER_GATHER_ENTRIES > 1
+		for (j = 0; j < NUM_SCATTER_GATHER_ENTRIES - 1; j += 1) {
+			SCListEntry->Address = of;
+			SCListEntry->Length = OVERFLOW_BUFFER_SIZE;
+			SCListEntry += 1;
+			PASCListEntry +=
+				sizeof(struct HW_SCATTER_GATHER_ELEMENT);
+		}
+#endif
+
+		if (!Buffer2Length)
+			continue;
+
+		Buffer = pci_alloc_consistent(pci_dev, Buffer2Length, &tmp);
+		PABuffer = tmp;
+
+		if (Buffer == NULL)
+			return -ENOMEM;
+
+		Cur->Buffer2 = Buffer;
+
+		SCListEntry->Address = PABuffer;
+		SCListEntry->Length  = Buffer2Length;
+
+		Cur->scList2 = SCListEntry;
+		Cur->ngeneBuffer.Address_of_first_entry_2 = PASCListEntry;
+		Cur->ngeneBuffer.Number_of_entries_2 =
+			NUM_SCATTER_GATHER_ENTRIES;
+
+		SCListEntry   += 1;
+		PASCListEntry += sizeof(struct HW_SCATTER_GATHER_ELEMENT);
+
+#if NUM_SCATTER_GATHER_ENTRIES > 1
+		for (j = 0; j < NUM_SCATTER_GATHER_ENTRIES - 1; j++) {
+			SCListEntry->Address = of;
+			SCListEntry->Length = OVERFLOW_BUFFER_SIZE;
+			SCListEntry += 1;
+			PASCListEntry +=
+				sizeof(struct HW_SCATTER_GATHER_ELEMENT);
+		}
+#endif
+
+	}
+
+	return status;
+}
+
+static int FillTSIdleBuffer(struct SRingBufferDescriptor *pIdleBuffer,
+			    struct SRingBufferDescriptor *pRingBuffer)
+{
+	int status = 0;
+
+	/* Copy pointer to scatter gather list in TSRingbuffer
+	   structure for buffer 2
+	   Load number of buffer
+	*/
+	u32 n = pRingBuffer->NumBuffers;
+
+	/* Point to first buffer entry */
+	struct SBufferHeader *Cur = pRingBuffer->Head;
+	int i;
+	/* Loop thru all buffer and set Buffer 2 pointers to TSIdlebuffer */
+	for (i = 0; i < n; i++) {
+		Cur->Buffer2 = pIdleBuffer->Head->Buffer1;
+		Cur->scList2 = pIdleBuffer->Head->scList1;
+		Cur->ngeneBuffer.Address_of_first_entry_2 =
+			pIdleBuffer->Head->ngeneBuffer.
+			Address_of_first_entry_1;
+		Cur->ngeneBuffer.Number_of_entries_2 =
+			pIdleBuffer->Head->ngeneBuffer.Number_of_entries_1;
+		Cur = Cur->Next;
+	}
+	return status;
+}
+
+static u32 RingBufferSizes[MAX_STREAM] = {
+	RING_SIZE_VIDEO,
+	RING_SIZE_VIDEO,
+	RING_SIZE_AUDIO,
+	RING_SIZE_AUDIO,
+	RING_SIZE_AUDIO,
+};
+
+static u32 Buffer1Sizes[MAX_STREAM] = {
+	MAX_VIDEO_BUFFER_SIZE,
+	MAX_VIDEO_BUFFER_SIZE,
+	MAX_AUDIO_BUFFER_SIZE,
+	MAX_AUDIO_BUFFER_SIZE,
+	MAX_AUDIO_BUFFER_SIZE
+};
+
+static u32 Buffer2Sizes[MAX_STREAM] = {
+	MAX_VBI_BUFFER_SIZE,
+	MAX_VBI_BUFFER_SIZE,
+	0,
+	0,
+	0
+};
+
+
+static int AllocCommonBuffers(struct ngene *dev)
+{
+	int status = 0, i;
+
+	dev->FWInterfaceBuffer = pci_alloc_consistent(dev->pci_dev, 4096,
+						     &dev->PAFWInterfaceBuffer);
+	if (!dev->FWInterfaceBuffer)
+		return -ENOMEM;
+	dev->hosttongene = dev->FWInterfaceBuffer;
+	dev->ngenetohost = dev->FWInterfaceBuffer + 256;
+	dev->EventBuffer = dev->FWInterfaceBuffer + 512;
+
+	dev->OverflowBuffer = pci_alloc_consistent(dev->pci_dev,
+						   OVERFLOW_BUFFER_SIZE,
+						   &dev->PAOverflowBuffer);
+	if (!dev->OverflowBuffer)
+		return -ENOMEM;
+	memset(dev->OverflowBuffer, 0, OVERFLOW_BUFFER_SIZE);
+
+	for (i = STREAM_VIDEOIN1; i < MAX_STREAM; i++) {
+		int type = dev->card_info->io_type[i];
+
+		dev->channel[i].State = KSSTATE_STOP;
+
+		if (type & (NGENE_IO_TV | NGENE_IO_HDTV | NGENE_IO_AIN)) {
+			status = create_ring_buffer(dev->pci_dev,
+						    &dev->channel[i].RingBuffer,
+						    RingBufferSizes[i]);
+			if (status < 0)
+				break;
+
+			if (type & (NGENE_IO_TV | NGENE_IO_AIN)) {
+				status = AllocateRingBuffers(dev->pci_dev,
+							     dev->
+							     PAOverflowBuffer,
+							     &dev->channel[i].
+							     RingBuffer,
+							     Buffer1Sizes[i],
+							     Buffer2Sizes[i]);
+				if (status < 0)
+					break;
+			} else if (type & NGENE_IO_HDTV) {
+				status = AllocateRingBuffers(dev->pci_dev,
+							     dev->
+							     PAOverflowBuffer,
+							     &dev->channel[i].
+							     RingBuffer,
+							   MAX_HDTV_BUFFER_SIZE,
+							     0);
+				if (status < 0)
+					break;
+			}
+		}
+
+		if (type & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
+
+			status = create_ring_buffer(dev->pci_dev,
+						    &dev->channel[i].
+						    TSRingBuffer, RING_SIZE_TS);
+			if (status < 0)
+				break;
+
+			status = AllocateRingBuffers(dev->pci_dev,
+						     dev->PAOverflowBuffer,
+						     &dev->channel[i].
+						     TSRingBuffer,
+						     MAX_TS_BUFFER_SIZE, 0);
+			if (status)
+				break;
+		}
+
+		if (type & NGENE_IO_TSOUT) {
+			status = create_ring_buffer(dev->pci_dev,
+						    &dev->channel[i].
+						    TSIdleBuffer, 1);
+			if (status < 0)
+				break;
+			status = AllocateRingBuffers(dev->pci_dev,
+						     dev->PAOverflowBuffer,
+						     &dev->channel[i].
+						     TSIdleBuffer,
+						     MAX_TS_BUFFER_SIZE, 0);
+			if (status)
+				break;
+			FillTSIdleBuffer(&dev->channel[i].TSIdleBuffer,
+					 &dev->channel[i].TSRingBuffer);
+		}
+	}
+	return status;
+}
+
+static void ngene_release_buffers(struct ngene *dev)
+{
+	if (dev->iomem)
+		iounmap(dev->iomem);
+	free_common_buffers(dev);
+	vfree(dev->tsout_buf);
+	vfree(dev->ain_buf);
+	vfree(dev->vin_buf);
+	vfree(dev);
+}
+
+static int ngene_get_buffers(struct ngene *dev)
+{
+	if (AllocCommonBuffers(dev))
+		return -ENOMEM;
+	if (dev->card_info->io_type[4] & NGENE_IO_TSOUT) {
+		dev->tsout_buf = vmalloc(TSOUT_BUF_SIZE);
+		if (!dev->tsout_buf)
+			return -ENOMEM;
+		dvb_ringbuffer_init(&dev->tsout_rbuf,
+				    dev->tsout_buf, TSOUT_BUF_SIZE);
+	}
+	if (dev->card_info->io_type[2] & NGENE_IO_AIN) {
+		dev->ain_buf = vmalloc(AIN_BUF_SIZE);
+		if (!dev->ain_buf)
+			return -ENOMEM;
+		dvb_ringbuffer_init(&dev->ain_rbuf, dev->ain_buf, AIN_BUF_SIZE);
+	}
+	if (dev->card_info->io_type[0] & NGENE_IO_HDTV) {
+		dev->vin_buf = vmalloc(VIN_BUF_SIZE);
+		if (!dev->vin_buf)
+			return -ENOMEM;
+		dvb_ringbuffer_init(&dev->vin_rbuf, dev->vin_buf, VIN_BUF_SIZE);
+	}
+	dev->iomem = ioremap(pci_resource_start(dev->pci_dev, 0),
+			     pci_resource_len(dev->pci_dev, 0));
+	if (!dev->iomem)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void ngene_init(struct ngene *dev)
+{
+	int i;
+
+	tasklet_init(&dev->event_tasklet, event_tasklet, (unsigned long)dev);
+
+	memset_io(dev->iomem + 0xc000, 0x00, 0x220);
+	memset_io(dev->iomem + 0xc400, 0x00, 0x100);
+
+	for (i = 0; i < MAX_STREAM; i++) {
+		dev->channel[i].dev = dev;
+		dev->channel[i].number = i;
+	}
+
+	dev->fw_interface_version = 0;
+
+	ngwritel(0, NGENE_INT_ENABLE);
+
+	dev->icounts = ngreadl(NGENE_INT_COUNTS);
+
+	dev->device_version = ngreadl(DEV_VER) & 0x0f;
+	printk(KERN_INFO DEVICE_NAME ": Device version %d\n",
+	       dev->device_version);
+}
+
+static int ngene_load_firm(struct ngene *dev)
+{
+	u32 size;
+	const struct firmware *fw = NULL;
+	u8 *ngene_fw;
+	char *fw_name;
+	int err, version;
+
+	version = dev->card_info->fw_version;
+
+	switch (version) {
+	default:
+	case 15:
+		version = 15;
+		size = 23466;
+		fw_name = "/*(DEBLOBBED)*/";
+		break;
+	case 16:
+		size = 23498;
+		fw_name = "/*(DEBLOBBED)*/";
+		break;
+	case 17:
+		size = 24446;
+		fw_name = "/*(DEBLOBBED)*/";
+		break;
+	}
+
+	if (reject_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) {
+		printk(KERN_ERR DEVICE_NAME
+			": Could not load firmware file %s.\n", fw_name);
+		printk(KERN_INFO DEVICE_NAME
+			": Copy %s to your hotplug directory!\n", fw_name);
+		return -1;
+	}
+	if (size != fw->size) {
+		printk(KERN_ERR DEVICE_NAME
+			": Firmware %s has invalid size!", fw_name);
+		err = -1;
+	} else {
+		printk(KERN_INFO DEVICE_NAME
+			": Loading firmware file %s.\n", fw_name);
+		ngene_fw = (u8 *) fw->data;
+		err = ngene_command_load_firmware(dev, ngene_fw, size);
+	}
+
+	release_firmware(fw);
+
+	return err;
+}
+
+static void ngene_stop(struct ngene *dev)
+{
+	down(&dev->cmd_mutex);
+	i2c_del_adapter(&(dev->channel[0].i2c_adapter));
+	i2c_del_adapter(&(dev->channel[1].i2c_adapter));
+	ngwritel(0, NGENE_INT_ENABLE);
+	ngwritel(0, NGENE_COMMAND);
+	ngwritel(0, NGENE_COMMAND_HI);
+	ngwritel(0, NGENE_STATUS);
+	ngwritel(0, NGENE_STATUS_HI);
+	ngwritel(0, NGENE_EVENT);
+	ngwritel(0, NGENE_EVENT_HI);
+	free_irq(dev->pci_dev->irq, dev);
+}
+
+static int ngene_start(struct ngene *dev)
+{
+	int stat;
+	int i;
+
+	pci_set_master(dev->pci_dev);
+	ngene_init(dev);
+
+	stat = request_irq(dev->pci_dev->irq, irq_handler,
+			   IRQF_SHARED, "nGene",
+			   (void *)dev);
+	if (stat < 0)
+		return stat;
+
+	init_waitqueue_head(&dev->cmd_wq);
+	init_waitqueue_head(&dev->tx_wq);
+	init_waitqueue_head(&dev->rx_wq);
+	sema_init(&dev->cmd_mutex, 1);
+	sema_init(&dev->stream_mutex, 1);
+	sema_init(&dev->pll_mutex, 1);
+	sema_init(&dev->i2c_switch_mutex, 1);
+	spin_lock_init(&dev->cmd_lock);
+	for (i = 0; i < MAX_STREAM; i++)
+		spin_lock_init(&dev->channel[i].state_lock);
+	ngwritel(1, TIMESTAMPS);
+
+	ngwritel(1, NGENE_INT_ENABLE);
+
+	stat = ngene_load_firm(dev);
+	if (stat < 0)
+		goto fail;
+
+	stat = ngene_i2c_init(dev, 0);
+	if (stat < 0)
+		goto fail;
+
+	stat = ngene_i2c_init(dev, 1);
+	if (stat < 0)
+		goto fail;
+
+	if (dev->card_info->fw_version == 17) {
+		u8 tsin4_config[6] = {
+			3072 / 64, 3072 / 64, 0, 3072 / 64, 3072 / 64, 0};
+		u8 default_config[6] = {
+			4096 / 64, 4096 / 64, 0, 2048 / 64, 2048 / 64, 0};
+		u8 *bconf = default_config;
+
+		if (dev->card_info->io_type[3] == NGENE_IO_TSIN)
+			bconf = tsin4_config;
+		dprintk(KERN_DEBUG DEVICE_NAME ": FW 17 buffer config\n");
+		stat = ngene_command_config_free_buf(dev, bconf);
+	} else {
+		int bconf = BUFFER_CONFIG_4422;
+		if (dev->card_info->io_type[3] == NGENE_IO_TSIN)
+			bconf = BUFFER_CONFIG_3333;
+		stat = ngene_command_config_buf(dev, bconf);
+	}
+	return stat;
+fail:
+	ngwritel(0, NGENE_INT_ENABLE);
+	free_irq(dev->pci_dev->irq, dev);
+	return stat;
+}
+
+
+
+/****************************************************************************/
+/* Switch control (I2C gates, etc.) *****************************************/
+/****************************************************************************/
+
+
+/****************************************************************************/
+/* Demod/tuner attachment ***************************************************/
+/****************************************************************************/
+
+static int tuner_attach_stv6110(struct ngene_channel *chan)
+{
+	struct stv090x_config *feconf = (struct stv090x_config *)
+		chan->dev->card_info->fe_config[chan->number];
+	struct stv6110x_config *tunerconf = (struct stv6110x_config *)
+		chan->dev->card_info->tuner_config[chan->number];
+	struct stv6110x_devctl *ctl;
+
+	ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf,
+			 &chan->i2c_adapter);
+	if (ctl == NULL) {
+		printk(KERN_ERR	DEVICE_NAME ": No STV6110X found!\n");
+		return -ENODEV;
+	}
+
+	feconf->tuner_init          = ctl->tuner_init;
+	feconf->tuner_set_mode      = ctl->tuner_set_mode;
+	feconf->tuner_set_frequency = ctl->tuner_set_frequency;
+	feconf->tuner_get_frequency = ctl->tuner_get_frequency;
+	feconf->tuner_set_bandwidth = ctl->tuner_set_bandwidth;
+	feconf->tuner_get_bandwidth = ctl->tuner_get_bandwidth;
+	feconf->tuner_set_bbgain    = ctl->tuner_set_bbgain;
+	feconf->tuner_get_bbgain    = ctl->tuner_get_bbgain;
+	feconf->tuner_set_refclk    = ctl->tuner_set_refclk;
+	feconf->tuner_get_status    = ctl->tuner_get_status;
+
+	return 0;
+}
+
+
+static int demod_attach_stv0900(struct ngene_channel *chan)
+{
+	struct stv090x_config *feconf = (struct stv090x_config *)
+		chan->dev->card_info->fe_config[chan->number];
+
+	chan->fe = dvb_attach(stv090x_attach,
+			feconf,
+			&chan->i2c_adapter,
+			chan->number == 0 ? STV090x_DEMODULATOR_0 :
+					    STV090x_DEMODULATOR_1);
+	if (chan->fe == NULL) {
+		printk(KERN_ERR	DEVICE_NAME ": No STV0900 found!\n");
+		return -ENODEV;
+	}
+
+	if (!dvb_attach(lnbh24_attach, chan->fe, &chan->i2c_adapter, 0,
+			0, chan->dev->card_info->lnb[chan->number])) {
+		printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n");
+		dvb_frontend_detach(chan->fe);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+static void release_channel(struct ngene_channel *chan)
+{
+	struct dvb_demux *dvbdemux = &chan->demux;
+	struct ngene *dev = chan->dev;
+	struct ngene_info *ni = dev->card_info;
+	int io = ni->io_type[chan->number];
+
+#ifdef COMMAND_TIMEOUT_WORKAROUND
+	if (chan->running)
+		set_transfer(chan, 0);
+#endif
+
+	tasklet_kill(&chan->demux_tasklet);
+
+	if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
+		if (chan->fe) {
+			dvb_unregister_frontend(chan->fe);
+			dvb_frontend_detach(chan->fe);
+			chan->fe = 0;
+		}
+		dvbdemux->dmx.close(&dvbdemux->dmx);
+		dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
+					      &chan->hw_frontend);
+		dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
+					      &chan->mem_frontend);
+		dvb_dmxdev_release(&chan->dmxdev);
+		dvb_dmx_release(&chan->demux);
+
+		if (chan->number == 0 || !one_adapter)
+			dvb_unregister_adapter(&dev->adapter[chan->number]);
+	}
+}
+
+static int init_channel(struct ngene_channel *chan)
+{
+	int ret = 0, nr = chan->number;
+	struct dvb_adapter *adapter = NULL;
+	struct dvb_demux *dvbdemux = &chan->demux;
+	struct ngene *dev = chan->dev;
+	struct ngene_info *ni = dev->card_info;
+	int io = ni->io_type[nr];
+
+	tasklet_init(&chan->demux_tasklet, demux_tasklet, (unsigned long)chan);
+	chan->users = 0;
+	chan->type = io;
+	chan->mode = chan->type;	/* for now only one mode */
+
+	if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
+		if (nr >= STREAM_AUDIOIN1)
+			chan->DataFormatFlags = DF_SWAP32;
+		if (nr == 0 || !one_adapter) {
+			adapter = &dev->adapter[nr];
+			ret = dvb_register_adapter(adapter, "nGene",
+						   THIS_MODULE,
+						   &chan->dev->pci_dev->dev,
+						   adapter_nr);
+			if (ret < 0)
+				return ret;
+		} else {
+			adapter = &dev->adapter[0];
+		}
+
+		ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux",
+					      ngene_start_feed,
+					      ngene_stop_feed, chan);
+		ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux,
+						 &chan->hw_frontend,
+						 &chan->mem_frontend, adapter);
+	}
+
+	if (io & NGENE_IO_TSIN) {
+		chan->fe = NULL;
+		if (ni->demod_attach[nr])
+			ni->demod_attach[nr](chan);
+		if (chan->fe) {
+			if (dvb_register_frontend(adapter, chan->fe) < 0) {
+				if (chan->fe->ops.release)
+					chan->fe->ops.release(chan->fe);
+				chan->fe = NULL;
+			}
+		}
+		if (chan->fe && ni->tuner_attach[nr])
+			if (ni->tuner_attach[nr] (chan) < 0) {
+				printk(KERN_ERR DEVICE_NAME
+				       ": Tuner attach failed on channel %d!\n",
+				       nr);
+			}
+	}
+	return ret;
+}
+
+static int init_channels(struct ngene *dev)
+{
+	int i, j;
+
+	for (i = 0; i < MAX_STREAM; i++) {
+		if (init_channel(&dev->channel[i]) < 0) {
+			for (j = i - 1; j >= 0; j--)
+				release_channel(&dev->channel[j]);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+/****************************************************************************/
+/* device probe/remove calls ************************************************/
+/****************************************************************************/
+
+static void __devexit ngene_remove(struct pci_dev *pdev)
+{
+	struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev);
+	int i;
+
+	tasklet_kill(&dev->event_tasklet);
+	for (i = MAX_STREAM - 1; i >= 0; i--)
+		release_channel(&dev->channel[i]);
+	ngene_stop(dev);
+	ngene_release_buffers(dev);
+	pci_set_drvdata(pdev, 0);
+	pci_disable_device(pdev);
+}
+
+static int __devinit ngene_probe(struct pci_dev *pci_dev,
+				 const struct pci_device_id *id)
+{
+	struct ngene *dev;
+	int stat = 0;
+
+	if (pci_enable_device(pci_dev) < 0)
+		return -ENODEV;
+
+	dev = vmalloc(sizeof(struct ngene));
+	if (dev == NULL) {
+		stat = -ENOMEM;
+		goto fail0;
+	}
+	memset(dev, 0, sizeof(struct ngene));
+
+	dev->pci_dev = pci_dev;
+	dev->card_info = (struct ngene_info *)id->driver_data;
+	printk(KERN_INFO DEVICE_NAME ": Found %s\n", dev->card_info->name);
+
+	pci_set_drvdata(pci_dev, dev);
+
+	/* Alloc buffers and start nGene */
+	stat = ngene_get_buffers(dev);
+	if (stat < 0)
+		goto fail1;
+	stat = ngene_start(dev);
+	if (stat < 0)
+		goto fail1;
+
+	dev->i2c_current_bus = -1;
+
+	/* Register DVB adapters and devices for both channels */
+	if (init_channels(dev) < 0)
+		goto fail2;
+
+	return 0;
+
+fail2:
+	ngene_stop(dev);
+fail1:
+	ngene_release_buffers(dev);
+fail0:
+	pci_disable_device(pci_dev);
+	pci_set_drvdata(pci_dev, 0);
+	return stat;
+}
+
+/****************************************************************************/
+/* Card configs *************************************************************/
+/****************************************************************************/
+
+static struct stv090x_config fe_cineS2 = {
+	.device         = STV0900,
+	.demod_mode     = STV090x_DUAL,
+	.clk_mode       = STV090x_CLK_EXT,
+
+	.xtal           = 27000000,
+	.address        = 0x68,
+
+	.ts1_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
+	.ts2_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
+
+	.repeater_level = STV090x_RPTLEVEL_16,
+
+	.adc1_range	= STV090x_ADC_1Vpp,
+	.adc2_range	= STV090x_ADC_1Vpp,
+
+	.diseqc_envelope_mode = true,
+};
+
+static struct stv6110x_config tuner_cineS2_0 = {
+	.addr	= 0x60,
+	.refclk	= 27000000,
+	.clk_div = 1,
+};
+
+static struct stv6110x_config tuner_cineS2_1 = {
+	.addr	= 0x63,
+	.refclk	= 27000000,
+	.clk_div = 1,
+};
+
+static struct ngene_info ngene_info_cineS2 = {
+	.type		= NGENE_SIDEWINDER,
+	.name		= "Linux4Media cineS2 DVB-S2 Twin Tuner",
+	.io_type	= {NGENE_IO_TSIN, NGENE_IO_TSIN},
+	.demod_attach	= {demod_attach_stv0900, demod_attach_stv0900},
+	.tuner_attach	= {tuner_attach_stv6110, tuner_attach_stv6110},
+	.fe_config	= {&fe_cineS2, &fe_cineS2},
+	.tuner_config	= {&tuner_cineS2_0, &tuner_cineS2_1},
+	.lnb		= {0x0b, 0x08},
+	.tsf		= {3, 3},
+	.fw_version	= 15,
+};
+
+static struct ngene_info ngene_info_satixs2 = {
+	.type		= NGENE_SIDEWINDER,
+	.name		= "Mystique SaTiX-S2 Dual",
+	.io_type	= {NGENE_IO_TSIN, NGENE_IO_TSIN},
+	.demod_attach	= {demod_attach_stv0900, demod_attach_stv0900},
+	.tuner_attach	= {tuner_attach_stv6110, tuner_attach_stv6110},
+	.fe_config	= {&fe_cineS2, &fe_cineS2},
+	.tuner_config	= {&tuner_cineS2_0, &tuner_cineS2_1},
+	.lnb		= {0x0b, 0x08},
+	.tsf		= {3, 3},
+	.fw_version	= 15,
+};
+
+/****************************************************************************/
+
+
+
+/****************************************************************************/
+/* PCI Subsystem ID *********************************************************/
+/****************************************************************************/
+
+#define NGENE_ID(_subvend, _subdev, _driverdata) { \
+	.vendor = NGENE_VID, .device = NGENE_PID, \
+	.subvendor = _subvend, .subdevice = _subdev, \
+	.driver_data = (unsigned long) &_driverdata }
+
+/****************************************************************************/
+
+static const struct pci_device_id ngene_id_tbl[] __devinitdata = {
+	NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2),
+	NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2),
+	NGENE_ID(0x18c3, 0xdb01, ngene_info_satixs2),
+	{0}
+};
+MODULE_DEVICE_TABLE(pci, ngene_id_tbl);
+
+/****************************************************************************/
+/* Init/Exit ****************************************************************/
+/****************************************************************************/
+
+static pci_ers_result_t ngene_error_detected(struct pci_dev *dev,
+					     enum pci_channel_state state)
+{
+	printk(KERN_ERR DEVICE_NAME ": PCI error\n");
+	if (state == pci_channel_io_perm_failure)
+		return PCI_ERS_RESULT_DISCONNECT;
+	if (state == pci_channel_io_frozen)
+		return PCI_ERS_RESULT_NEED_RESET;
+	return PCI_ERS_RESULT_CAN_RECOVER;
+}
+
+static pci_ers_result_t ngene_link_reset(struct pci_dev *dev)
+{
+	printk(KERN_INFO DEVICE_NAME ": link reset\n");
+	return 0;
+}
+
+static pci_ers_result_t ngene_slot_reset(struct pci_dev *dev)
+{
+	printk(KERN_INFO DEVICE_NAME ": slot reset\n");
+	return 0;
+}
+
+static void ngene_resume(struct pci_dev *dev)
+{
+	printk(KERN_INFO DEVICE_NAME ": resume\n");
+}
+
+static struct pci_error_handlers ngene_errors = {
+	.error_detected = ngene_error_detected,
+	.link_reset = ngene_link_reset,
+	.slot_reset = ngene_slot_reset,
+	.resume = ngene_resume,
+};
+
+static struct pci_driver ngene_pci_driver = {
+	.name        = "ngene",
+	.id_table    = ngene_id_tbl,
+	.probe       = ngene_probe,
+	.remove      = __devexit_p(ngene_remove),
+	.err_handler = &ngene_errors,
+};
+
+static __init int module_init_ngene(void)
+{
+	printk(KERN_INFO
+	       "nGene PCIE bridge driver, Copyright (C) 2005-2007 Micronas\n");
+	return pci_register_driver(&ngene_pci_driver);
+}
+
+static __exit void module_exit_ngene(void)
+{
+	pci_unregister_driver(&ngene_pci_driver);
+}
+
+module_init(module_init_ngene);
+module_exit(module_exit_ngene);
+
+MODULE_DESCRIPTION("nGene");
+MODULE_AUTHOR("Micronas, Ralph Metzler, Manfred Voelkel");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/ngene/ngene.h linux-libre-2.6.34-gnu1/drivers/media/dvb/ngene/ngene.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/ngene/ngene.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/ngene/ngene.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,859 @@
+/*
+ * ngene.h: nGene PCIe bridge driver
+ *
+ * Copyright (C) 2005-2007 Micronas
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * You 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
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef _NGENE_H_
+#define _NGENE_H_
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <asm/dma.h>
+#include <linux/scatterlist.h>
+
+#include <linux/dvb/frontend.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_ringbuffer.h"
+
+#define NGENE_VID       0x18c3
+#define NGENE_PID       0x0720
+
+#ifndef VIDEO_CAP_VC1
+#define VIDEO_CAP_AVC   128
+#define VIDEO_CAP_H264  128
+#define VIDEO_CAP_VC1   256
+#define VIDEO_CAP_WMV9  256
+#define VIDEO_CAP_MPEG4 512
+#endif
+
+enum STREAM {
+	STREAM_VIDEOIN1 = 0,        /* ITU656 or TS Input */
+	STREAM_VIDEOIN2,
+	STREAM_AUDIOIN1,            /* I2S or SPI Input */
+	STREAM_AUDIOIN2,
+	STREAM_AUDIOOUT,
+	MAX_STREAM
+};
+
+enum SMODE_BITS {
+	SMODE_AUDIO_SPDIF = 0x20,
+	SMODE_AVSYNC = 0x10,
+	SMODE_TRANSPORT_STREAM = 0x08,
+	SMODE_AUDIO_CAPTURE = 0x04,
+	SMODE_VBI_CAPTURE = 0x02,
+	SMODE_VIDEO_CAPTURE = 0x01
+};
+
+enum STREAM_FLAG_BITS {
+	SFLAG_CHROMA_FORMAT_2COMP  = 0x01, /* Chroma Format : 2's complement */
+	SFLAG_CHROMA_FORMAT_OFFSET = 0x00, /* Chroma Format : Binary offset */
+	SFLAG_ORDER_LUMA_CHROMA    = 0x02, /* Byte order: Y,Cb,Y,Cr */
+	SFLAG_ORDER_CHROMA_LUMA    = 0x00, /* Byte order: Cb,Y,Cr,Y */
+	SFLAG_COLORBAR             = 0x04, /* Select colorbar */
+};
+
+#define PROGRAM_ROM     0x0000
+#define PROGRAM_SRAM    0x1000
+#define PERIPHERALS0    0x8000
+#define PERIPHERALS1    0x9000
+#define SHARED_BUFFER   0xC000
+
+#define HOST_TO_NGENE    (SHARED_BUFFER+0x0000)
+#define NGENE_TO_HOST    (SHARED_BUFFER+0x0100)
+#define NGENE_COMMAND    (SHARED_BUFFER+0x0200)
+#define NGENE_COMMAND_HI (SHARED_BUFFER+0x0204)
+#define NGENE_STATUS     (SHARED_BUFFER+0x0208)
+#define NGENE_STATUS_HI  (SHARED_BUFFER+0x020C)
+#define NGENE_EVENT      (SHARED_BUFFER+0x0210)
+#define NGENE_EVENT_HI   (SHARED_BUFFER+0x0214)
+#define VARIABLES        (SHARED_BUFFER+0x0210)
+
+#define NGENE_INT_COUNTS       (SHARED_BUFFER+0x0260)
+#define NGENE_INT_ENABLE       (SHARED_BUFFER+0x0264)
+#define NGENE_VBI_LINE_COUNT   (SHARED_BUFFER+0x0268)
+
+#define BUFFER_GP_XMIT  (SHARED_BUFFER+0x0800)
+#define BUFFER_GP_RECV  (SHARED_BUFFER+0x0900)
+#define EEPROM_AREA     (SHARED_BUFFER+0x0A00)
+
+#define SG_V_IN_1       (SHARED_BUFFER+0x0A80)
+#define SG_VBI_1        (SHARED_BUFFER+0x0B00)
+#define SG_A_IN_1       (SHARED_BUFFER+0x0B80)
+#define SG_V_IN_2       (SHARED_BUFFER+0x0C00)
+#define SG_VBI_2        (SHARED_BUFFER+0x0C80)
+#define SG_A_IN_2       (SHARED_BUFFER+0x0D00)
+#define SG_V_OUT        (SHARED_BUFFER+0x0D80)
+#define SG_A_OUT2       (SHARED_BUFFER+0x0E00)
+
+#define DATA_A_IN_1     (SHARED_BUFFER+0x0E80)
+#define DATA_A_IN_2     (SHARED_BUFFER+0x0F00)
+#define DATA_A_OUT      (SHARED_BUFFER+0x0F80)
+#define DATA_V_IN_1     (SHARED_BUFFER+0x1000)
+#define DATA_V_IN_2     (SHARED_BUFFER+0x2000)
+#define DATA_V_OUT      (SHARED_BUFFER+0x3000)
+
+#define DATA_FIFO_AREA  (SHARED_BUFFER+0x1000)
+
+#define TIMESTAMPS      0xA000
+#define SCRATCHPAD      0xA080
+#define FORCE_INT       0xA088
+#define FORCE_NMI       0xA090
+#define INT_STATUS      0xA0A0
+
+#define DEV_VER         0x9004
+
+#define FW_DEBUG_DEFAULT (PROGRAM_SRAM+0x00FF)
+
+struct SG_ADDR {
+	u64 start;
+	u64 curr;
+	u16 curr_ptr;
+	u16 elements;
+	u32 pad[3];
+} __attribute__ ((__packed__));
+
+struct SHARED_MEMORY {
+	/* C000 */
+	u32 HostToNgene[64];
+
+	/* C100 */
+	u32 NgeneToHost[64];
+
+	/* C200 */
+	u64 NgeneCommand;
+	u64 NgeneStatus;
+	u64 NgeneEvent;
+
+	/* C210 */
+	u8 pad1[0xc260 - 0xc218];
+
+	/* C260 */
+	u32 IntCounts;
+	u32 IntEnable;
+
+	/* C268 */
+	u8 pad2[0xd000 - 0xc268];
+
+} __attribute__ ((__packed__));
+
+struct BUFFER_STREAM_RESULTS {
+	u32 Clock;           /* Stream time in 100ns units */
+	u16 RemainingLines;  /* Remaining lines in this field.
+				0 for complete field */
+	u8  FieldCount;      /* Video field number */
+	u8  Flags;           /* Bit 7 = Done, Bit 6 = seen, Bit 5 = overflow,
+				Bit 0 = FieldID */
+	u16 BlockCount;      /* Audio block count (unused) */
+	u8  Reserved[2];
+	u32 DTOUpdate;
+} __attribute__ ((__packed__));
+
+struct HW_SCATTER_GATHER_ELEMENT {
+	u64 Address;
+	u32 Length;
+	u32 Reserved;
+} __attribute__ ((__packed__));
+
+struct BUFFER_HEADER {
+	u64    Next;
+	struct BUFFER_STREAM_RESULTS SR;
+
+	u32    Number_of_entries_1;
+	u32    Reserved5;
+	u64    Address_of_first_entry_1;
+
+	u32    Number_of_entries_2;
+	u32    Reserved7;
+	u64    Address_of_first_entry_2;
+} __attribute__ ((__packed__));
+
+struct EVENT_BUFFER {
+	u32    TimeStamp;
+	u8     GPIOStatus;
+	u8     UARTStatus;
+	u8     RXCharacter;
+	u8     EventStatus;
+	u32    Reserved[2];
+} __attribute__ ((__packed__));
+
+/* Firmware commands. */
+
+enum OPCODES {
+	CMD_NOP = 0,
+	CMD_FWLOAD_PREPARE  = 0x01,
+	CMD_FWLOAD_FINISH   = 0x02,
+	CMD_I2C_READ        = 0x03,
+	CMD_I2C_WRITE       = 0x04,
+
+	CMD_I2C_WRITE_NOSTOP = 0x05,
+	CMD_I2C_CONTINUE_WRITE = 0x06,
+	CMD_I2C_CONTINUE_WRITE_NOSTOP = 0x07,
+
+	CMD_DEBUG_OUTPUT    = 0x09,
+
+	CMD_CONTROL         = 0x10,
+	CMD_CONFIGURE_BUFFER = 0x11,
+	CMD_CONFIGURE_FREE_BUFFER = 0x12,
+
+	CMD_SPI_READ        = 0x13,
+	CMD_SPI_WRITE       = 0x14,
+
+	CMD_MEM_READ        = 0x20,
+	CMD_MEM_WRITE	    = 0x21,
+	CMD_SFR_READ	    = 0x22,
+	CMD_SFR_WRITE	    = 0x23,
+	CMD_IRAM_READ	    = 0x24,
+	CMD_IRAM_WRITE	    = 0x25,
+	CMD_SET_GPIO_PIN    = 0x26,
+	CMD_SET_GPIO_INT    = 0x27,
+	CMD_CONFIGURE_UART  = 0x28,
+	CMD_WRITE_UART      = 0x29,
+	MAX_CMD
+};
+
+enum RESPONSES {
+	OK = 0,
+	ERROR = 1
+};
+
+struct FW_HEADER {
+	u8 Opcode;
+	u8 Length;
+} __attribute__ ((__packed__));
+
+struct FW_I2C_WRITE {
+	struct FW_HEADER hdr;
+	u8 Device;
+	u8 Data[250];
+} __attribute__ ((__packed__));
+
+struct FW_I2C_CONTINUE_WRITE {
+	struct FW_HEADER hdr;
+	u8 Data[250];
+} __attribute__ ((__packed__));
+
+struct FW_I2C_READ {
+	struct FW_HEADER hdr;
+	u8 Device;
+	u8 Data[252];    /* followed by two bytes of read data count */
+} __attribute__ ((__packed__));
+
+struct FW_SPI_WRITE {
+	struct FW_HEADER hdr;
+	u8 ModeSelect;
+	u8 Data[250];
+} __attribute__ ((__packed__));
+
+struct FW_SPI_READ {
+	struct FW_HEADER hdr;
+	u8 ModeSelect;
+	u8 Data[252];    /* followed by two bytes of read data count */
+} __attribute__ ((__packed__));
+
+struct FW_FWLOAD_PREPARE {
+	struct FW_HEADER hdr;
+} __attribute__ ((__packed__));
+
+struct FW_FWLOAD_FINISH {
+	struct FW_HEADER hdr;
+	u16 Address;     /* address of final block */
+	u16 Length;
+} __attribute__ ((__packed__));
+
+/*
+ * Meaning of FW_STREAM_CONTROL::Mode bits:
+ *  Bit 7: Loopback PEXin to PEXout using TVOut channel
+ *  Bit 6: AVLOOP
+ *  Bit 5: Audio select; 0=I2S, 1=SPDIF
+ *  Bit 4: AVSYNC
+ *  Bit 3: Enable transport stream
+ *  Bit 2: Enable audio capture
+ *  Bit 1: Enable ITU-Video VBI capture
+ *  Bit 0: Enable ITU-Video capture
+ *
+ * Meaning of FW_STREAM_CONTROL::Control bits (see UVI1_CTL)
+ *  Bit 7: continuous capture
+ *  Bit 6: capture one field
+ *  Bit 5: capture one frame
+ *  Bit 4: unused
+ *  Bit 3: starting field; 0=odd, 1=even
+ *  Bit 2: sample size; 0=8-bit, 1=10-bit
+ *  Bit 1: data format; 0=UYVY, 1=YUY2
+ *  Bit 0: resets buffer pointers
+*/
+
+enum FSC_MODE_BITS {
+	SMODE_LOOPBACK          = 0x80,
+	SMODE_AVLOOP            = 0x40,
+	_SMODE_AUDIO_SPDIF      = 0x20,
+	_SMODE_AVSYNC           = 0x10,
+	_SMODE_TRANSPORT_STREAM = 0x08,
+	_SMODE_AUDIO_CAPTURE    = 0x04,
+	_SMODE_VBI_CAPTURE      = 0x02,
+	_SMODE_VIDEO_CAPTURE    = 0x01
+};
+
+
+/* Meaning of FW_STREAM_CONTROL::Stream bits:
+ * Bit 3: Audio sample count:  0 = relative, 1 = absolute
+ * Bit 2: color bar select; 1=color bars, 0=CV3 decoder
+ * Bits 1-0: stream select, UVI1, UVI2, TVOUT
+ */
+
+struct FW_STREAM_CONTROL {
+	struct FW_HEADER hdr;
+	u8     Stream;             /* Stream number (UVI1, UVI2, TVOUT) */
+	u8     Control;            /* Value written to UVI1_CTL */
+	u8     Mode;               /* Controls clock source */
+	u8     SetupDataLen;	   /* Length of setup data, MSB=1 write
+				      backwards */
+	u16    CaptureBlockCount;  /* Blocks (a 256 Bytes) to capture per buffer
+				      for TS and Audio */
+	u64    Buffer_Address;	   /* Address of first buffer header */
+	u16    BytesPerVideoLine;
+	u16    MaxLinesPerField;
+	u16    MinLinesPerField;
+	u16    Reserved_1;
+	u16    BytesPerVBILine;
+	u16    MaxVBILinesPerField;
+	u16    MinVBILinesPerField;
+	u16    SetupDataAddr;      /* ngene relative address of setup data */
+	u8     SetupData[32];      /* setup data */
+} __attribute__((__packed__));
+
+#define AUDIO_BLOCK_SIZE    256
+#define TS_BLOCK_SIZE       256
+
+struct FW_MEM_READ {
+	struct FW_HEADER hdr;
+	u16   address;
+} __attribute__ ((__packed__));
+
+struct FW_MEM_WRITE {
+	struct FW_HEADER hdr;
+	u16   address;
+	u8    data;
+} __attribute__ ((__packed__));
+
+struct FW_SFR_IRAM_READ {
+	struct FW_HEADER hdr;
+	u8    address;
+} __attribute__ ((__packed__));
+
+struct FW_SFR_IRAM_WRITE {
+	struct FW_HEADER hdr;
+	u8    address;
+	u8    data;
+} __attribute__ ((__packed__));
+
+struct FW_SET_GPIO_PIN {
+	struct FW_HEADER hdr;
+	u8    select;
+} __attribute__ ((__packed__));
+
+struct FW_SET_GPIO_INT {
+	struct FW_HEADER hdr;
+	u8    select;
+} __attribute__ ((__packed__));
+
+struct FW_SET_DEBUGMODE {
+	struct FW_HEADER hdr;
+	u8   debug_flags;
+} __attribute__ ((__packed__));
+
+struct FW_CONFIGURE_BUFFERS {
+	struct FW_HEADER hdr;
+	u8   config;
+} __attribute__ ((__packed__));
+
+enum _BUFFER_CONFIGS {
+	/* 4k UVI1, 4k UVI2, 2k AUD1, 2k AUD2  (standard usage) */
+	BUFFER_CONFIG_4422 = 0,
+	/* 3k UVI1, 3k UVI2, 3k AUD1, 3k AUD2  (4x TS input usage) */
+	BUFFER_CONFIG_3333 = 1,
+	/* 8k UVI1, 0k UVI2, 2k AUD1, 2k I2SOut  (HDTV decoder usage) */
+	BUFFER_CONFIG_8022 = 2,
+	BUFFER_CONFIG_FW17 = 255, /* Use new FW 17 command */
+};
+
+struct FW_CONFIGURE_FREE_BUFFERS {
+	struct FW_HEADER hdr;
+	u8   UVI1_BufferLength;
+	u8   UVI2_BufferLength;
+	u8   TVO_BufferLength;
+	u8   AUD1_BufferLength;
+	u8   AUD2_BufferLength;
+	u8   TVA_BufferLength;
+} __attribute__ ((__packed__));
+
+struct FW_CONFIGURE_UART {
+	struct FW_HEADER hdr;
+	u8 UartControl;
+} __attribute__ ((__packed__));
+
+enum _UART_CONFIG {
+	_UART_BAUDRATE_19200 = 0,
+	_UART_BAUDRATE_9600  = 1,
+	_UART_BAUDRATE_4800  = 2,
+	_UART_BAUDRATE_2400  = 3,
+	_UART_RX_ENABLE      = 0x40,
+	_UART_TX_ENABLE      = 0x80,
+};
+
+struct FW_WRITE_UART {
+	struct FW_HEADER hdr;
+	u8 Data[252];
+} __attribute__ ((__packed__));
+
+
+struct ngene_command {
+	u32 in_len;
+	u32 out_len;
+	union {
+		u32                              raw[64];
+		u8                               raw8[256];
+		struct FW_HEADER                 hdr;
+		struct FW_I2C_WRITE              I2CWrite;
+		struct FW_I2C_CONTINUE_WRITE     I2CContinueWrite;
+		struct FW_I2C_READ               I2CRead;
+		struct FW_STREAM_CONTROL         StreamControl;
+		struct FW_FWLOAD_PREPARE         FWLoadPrepare;
+		struct FW_FWLOAD_FINISH          FWLoadFinish;
+		struct FW_MEM_READ		 MemoryRead;
+		struct FW_MEM_WRITE		 MemoryWrite;
+		struct FW_SFR_IRAM_READ		 SfrIramRead;
+		struct FW_SFR_IRAM_WRITE         SfrIramWrite;
+		struct FW_SPI_WRITE              SPIWrite;
+		struct FW_SPI_READ               SPIRead;
+		struct FW_SET_GPIO_PIN           SetGpioPin;
+		struct FW_SET_GPIO_INT           SetGpioInt;
+		struct FW_SET_DEBUGMODE          SetDebugMode;
+		struct FW_CONFIGURE_BUFFERS      ConfigureBuffers;
+		struct FW_CONFIGURE_FREE_BUFFERS ConfigureFreeBuffers;
+		struct FW_CONFIGURE_UART         ConfigureUart;
+		struct FW_WRITE_UART             WriteUart;
+	} cmd;
+} __attribute__ ((__packed__));
+
+#define NGENE_INTERFACE_VERSION 0x103
+#define MAX_VIDEO_BUFFER_SIZE   (417792) /* 288*1440 rounded up to next page */
+#define MAX_AUDIO_BUFFER_SIZE     (8192) /* Gives room for about 23msec@48KHz */
+#define MAX_VBI_BUFFER_SIZE      (28672) /* 1144*18 rounded up to next page */
+#define MAX_TS_BUFFER_SIZE       (98304) /* 512*188 rounded up to next page */
+#define MAX_HDTV_BUFFER_SIZE   (2080768) /* 541*1920*2 rounded up to next page
+					    Max: (1920x1080i60) */
+
+#define OVERFLOW_BUFFER_SIZE    (8192)
+
+#define RING_SIZE_VIDEO     4
+#define RING_SIZE_AUDIO     8
+#define RING_SIZE_TS        8
+
+#define NUM_SCATTER_GATHER_ENTRIES  8
+
+#define MAX_DMA_LENGTH (((MAX_VIDEO_BUFFER_SIZE + MAX_VBI_BUFFER_SIZE) * \
+			RING_SIZE_VIDEO * 2) + \
+			(MAX_AUDIO_BUFFER_SIZE * RING_SIZE_AUDIO * 2) + \
+			(MAX_TS_BUFFER_SIZE * RING_SIZE_TS * 4) + \
+			(RING_SIZE_VIDEO * PAGE_SIZE * 2) + \
+			(RING_SIZE_AUDIO * PAGE_SIZE * 2) + \
+			(RING_SIZE_TS    * PAGE_SIZE * 4) + \
+			 8 * PAGE_SIZE + OVERFLOW_BUFFER_SIZE + PAGE_SIZE)
+
+#define EVENT_QUEUE_SIZE    16
+
+/* Gathers the current state of a single channel. */
+
+struct SBufferHeader {
+	struct BUFFER_HEADER   ngeneBuffer; /* Physical descriptor */
+	struct SBufferHeader  *Next;
+	void                  *Buffer1;
+	struct HW_SCATTER_GATHER_ELEMENT *scList1;
+	void                  *Buffer2;
+	struct HW_SCATTER_GATHER_ELEMENT *scList2;
+};
+
+/* Sizeof SBufferHeader aligned to next 64 Bit boundary (hw restriction) */
+#define SIZEOF_SBufferHeader ((sizeof(struct SBufferHeader) + 63) & ~63)
+
+enum HWSTATE {
+	HWSTATE_STOP,
+	HWSTATE_STARTUP,
+	HWSTATE_RUN,
+	HWSTATE_PAUSE,
+};
+
+enum KSSTATE {
+	KSSTATE_STOP,
+	KSSTATE_ACQUIRE,
+	KSSTATE_PAUSE,
+	KSSTATE_RUN,
+};
+
+struct SRingBufferDescriptor {
+	struct SBufferHeader *Head; /* Points to first buffer in ring buffer
+				       structure*/
+	u64   PAHead;         /* Physical address of first buffer */
+	u32   MemSize;        /* Memory size of allocated ring buffers
+				 (needed for freeing) */
+	u32   NumBuffers;     /* Number of buffers in the ring */
+	u32   Buffer1Length;  /* Allocated length of Buffer 1 */
+	u32   Buffer2Length;  /* Allocated length of Buffer 2 */
+	void *SCListMem;      /* Memory to hold scatter gather lists for this
+				 ring */
+	u64   PASCListMem;    /* Physical address  .. */
+	u32   SCListMemSize;  /* Size of this memory */
+};
+
+enum STREAMMODEFLAGS {
+	StreamMode_NONE   = 0, /* Stream not used */
+	StreamMode_ANALOG = 1, /* Analog: Stream 0,1 = Video, 2,3 = Audio */
+	StreamMode_TSIN   = 2, /* Transport stream input (all) */
+	StreamMode_HDTV   = 4, /* HDTV: Maximum 1920x1080p30,1920x1080i60
+				  (only stream 0) */
+	StreamMode_TSOUT  = 8, /* Transport stream output (only stream 3) */
+};
+
+
+enum BufferExchangeFlags {
+	BEF_EVEN_FIELD   = 0x00000001,
+	BEF_CONTINUATION = 0x00000002,
+	BEF_MORE_DATA    = 0x00000004,
+	BEF_OVERFLOW     = 0x00000008,
+	DF_SWAP32        = 0x00010000,
+};
+
+typedef void *(IBufferExchange)(void *, void *, u32, u32, u32);
+
+struct MICI_STREAMINFO {
+	IBufferExchange    *pExchange;
+	IBufferExchange    *pExchangeVBI;     /* Secondary (VBI, ancillary) */
+	u8  Stream;
+	u8  Flags;
+	u8  Mode;
+	u8  Reserved;
+	u16 nLinesVideo;
+	u16 nBytesPerLineVideo;
+	u16 nLinesVBI;
+	u16 nBytesPerLineVBI;
+	u32 CaptureLength;    /* Used for audio and transport stream */
+};
+
+/****************************************************************************/
+/* STRUCTS ******************************************************************/
+/****************************************************************************/
+
+/* sound hardware definition */
+#define MIXER_ADDR_TVTUNER      0
+#define MIXER_ADDR_LAST         0
+
+struct ngene_channel;
+
+/*struct sound chip*/
+
+struct mychip {
+	struct ngene_channel *chan;
+	struct snd_card *card;
+	struct pci_dev *pci;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm *pcm;
+	unsigned long port;
+	int irq;
+	spinlock_t mixer_lock;
+	spinlock_t lock;
+	int mixer_volume[MIXER_ADDR_LAST + 1][2];
+	int capture_source[MIXER_ADDR_LAST + 1][2];
+};
+
+#ifdef NGENE_V4L
+struct ngene_overlay {
+	int                    tvnorm;
+	struct v4l2_rect       w;
+	enum v4l2_field        field;
+	struct v4l2_clip       *clips;
+	int                    nclips;
+	int                    setup_ok;
+};
+
+struct ngene_tvnorm {
+	int   v4l2_id;
+	char  *name;
+	u16   swidth, sheight; /* scaled standard width, height */
+	int   tuner_norm;
+	int   soundstd;
+};
+
+struct ngene_vopen {
+	struct ngene_channel      *ch;
+	enum v4l2_priority         prio;
+	int                        width;
+	int                        height;
+	int                        depth;
+	struct videobuf_queue      vbuf_q;
+	struct videobuf_queue      vbi;
+	int                        fourcc;
+	int                        picxcount;
+	int                        resources;
+	enum v4l2_buf_type         type;
+	const struct ngene_format *fmt;
+
+	const struct ngene_format *ovfmt;
+	struct ngene_overlay       ov;
+};
+#endif
+
+struct ngene_channel {
+	struct device         device;
+	struct i2c_adapter    i2c_adapter;
+
+	struct ngene         *dev;
+	int                   number;
+	int                   type;
+	int                   mode;
+
+	struct dvb_frontend  *fe;
+	struct dmxdev         dmxdev;
+	struct dvb_demux      demux;
+	struct dmx_frontend   hw_frontend;
+	struct dmx_frontend   mem_frontend;
+	int                   users;
+	struct video_device  *v4l_dev;
+	struct tasklet_struct demux_tasklet;
+
+	struct SBufferHeader *nextBuffer;
+	enum KSSTATE          State;
+	enum HWSTATE          HWState;
+	u8                    Stream;
+	u8                    Flags;
+	u8                    Mode;
+	IBufferExchange      *pBufferExchange;
+	IBufferExchange      *pBufferExchange2;
+
+	spinlock_t            state_lock;
+	u16                   nLines;
+	u16                   nBytesPerLine;
+	u16                   nVBILines;
+	u16                   nBytesPerVBILine;
+	u16                   itumode;
+	u32                   Capture1Length;
+	u32                   Capture2Length;
+	struct SRingBufferDescriptor RingBuffer;
+	struct SRingBufferDescriptor TSRingBuffer;
+	struct SRingBufferDescriptor TSIdleBuffer;
+
+	u32                   DataFormatFlags;
+
+	int                   AudioDTOUpdated;
+	u32                   AudioDTOValue;
+
+	int (*set_tone)(struct dvb_frontend *, fe_sec_tone_mode_t);
+	u8 lnbh;
+
+	/* stuff from analog driver */
+
+	int minor;
+	struct mychip        *mychip;
+	struct snd_card      *soundcard;
+	u8                   *evenbuffer;
+	u8                    dma_on;
+	int                   soundstreamon;
+	int                   audiomute;
+	int                   soundbuffisallocated;
+	int                   sndbuffflag;
+	int                   tun_rdy;
+	int                   dec_rdy;
+	int                   tun_dec_rdy;
+	int                   lastbufferflag;
+
+	struct ngene_tvnorm  *tvnorms;
+	int                   tvnorm_num;
+	int                   tvnorm;
+
+#ifdef NGENE_V4L
+	int                   videousers;
+	struct v4l2_prio_state prio;
+	struct ngene_vopen    init;
+	int                   resources;
+	struct v4l2_framebuffer fbuf;
+	struct ngene_buffer  *screen;     /* overlay             */
+	struct list_head      capture;    /* video capture queue */
+	spinlock_t s_lock;
+	struct semaphore reslock;
+#endif
+
+	int running;
+};
+
+struct ngene;
+
+typedef void (rx_cb_t)(struct ngene *, u32, u8);
+typedef void (tx_cb_t)(struct ngene *, u32);
+
+struct ngene {
+	int                   nr;
+	struct pci_dev       *pci_dev;
+	unsigned char        *iomem;
+
+	/*struct i2c_adapter  i2c_adapter;*/
+
+	u32                   device_version;
+	u32                   fw_interface_version;
+	u32                   icounts;
+
+	u8                   *CmdDoneByte;
+	int                   BootFirmware;
+	void                 *OverflowBuffer;
+	dma_addr_t            PAOverflowBuffer;
+	void                 *FWInterfaceBuffer;
+	dma_addr_t            PAFWInterfaceBuffer;
+	u8                   *ngenetohost;
+	u8                   *hosttongene;
+
+	struct EVENT_BUFFER   EventQueue[EVENT_QUEUE_SIZE];
+	int                   EventQueueOverflowCount;
+	int                   EventQueueOverflowFlag;
+	struct tasklet_struct event_tasklet;
+	struct EVENT_BUFFER  *EventBuffer;
+	int                   EventQueueWriteIndex;
+	int                   EventQueueReadIndex;
+
+	wait_queue_head_t     cmd_wq;
+	int                   cmd_done;
+	struct semaphore      cmd_mutex;
+	struct semaphore      stream_mutex;
+	struct semaphore      pll_mutex;
+	struct semaphore      i2c_switch_mutex;
+	int                   i2c_current_channel;
+	int                   i2c_current_bus;
+	spinlock_t            cmd_lock;
+
+	struct dvb_adapter    adapter[MAX_STREAM];
+	struct ngene_channel  channel[MAX_STREAM];
+
+	struct ngene_info    *card_info;
+
+	tx_cb_t              *TxEventNotify;
+	rx_cb_t              *RxEventNotify;
+	int                   tx_busy;
+	wait_queue_head_t     tx_wq;
+	wait_queue_head_t     rx_wq;
+#define UART_RBUF_LEN 4096
+	u8                    uart_rbuf[UART_RBUF_LEN];
+	int                   uart_rp, uart_wp;
+
+	u8                   *tsout_buf;
+#define TSOUT_BUF_SIZE (512*188*8)
+	struct dvb_ringbuffer tsout_rbuf;
+
+	u8                   *ain_buf;
+#define AIN_BUF_SIZE (128*1024)
+	struct dvb_ringbuffer ain_rbuf;
+
+
+	u8                   *vin_buf;
+#define VIN_BUF_SIZE (4*1920*1080)
+	struct dvb_ringbuffer vin_rbuf;
+
+	unsigned long         exp_val;
+	int prev_cmd;
+};
+
+struct ngene_info {
+	int   type;
+#define NGENE_APP        0
+#define NGENE_TERRATEC   1
+#define NGENE_SIDEWINDER 2
+#define NGENE_RACER      3
+#define NGENE_VIPER      4
+#define NGENE_PYTHON     5
+#define NGENE_VBOX_V1	 6
+#define NGENE_VBOX_V2	 7
+
+	int   fw_version;
+	char *name;
+
+	int   io_type[MAX_STREAM];
+#define NGENE_IO_NONE    0
+#define NGENE_IO_TV      1
+#define NGENE_IO_HDTV    2
+#define NGENE_IO_TSIN    4
+#define NGENE_IO_TSOUT   8
+#define NGENE_IO_AIN     16
+
+	void *fe_config[4];
+	void *tuner_config[4];
+
+	int (*demod_attach[4])(struct ngene_channel *);
+	int (*tuner_attach[4])(struct ngene_channel *);
+
+	u8    avf[4];
+	u8    msp[4];
+	u8    demoda[4];
+	u8    lnb[4];
+	int   i2c_access;
+	u8    ntsc;
+	u8    tsf[4];
+	u8    i2s[4];
+
+	int (*gate_ctrl)(struct dvb_frontend *, int);
+	int (*switch_ctrl)(struct ngene_channel *, int, int);
+};
+
+#ifdef NGENE_V4L
+struct ngene_format{
+	char *name;
+	int   fourcc;          /* video4linux 2      */
+	int   btformat;        /* BT848_COLOR_FMT_*  */
+	int   format;
+	int   btswap;          /* BT848_COLOR_CTL_*  */
+	int   depth;           /* bit/pixel          */
+	int   flags;
+	int   hshift, vshift;  /* for planar modes   */
+	int   palette;
+};
+
+#define RESOURCE_OVERLAY       1
+#define RESOURCE_VIDEO         2
+#define RESOURCE_VBI           4
+
+struct ngene_buffer {
+	/* common v4l buffer stuff -- must be first */
+	struct videobuf_buffer     vb;
+
+	/* ngene specific */
+	const struct ngene_format *fmt;
+	int                        tvnorm;
+	int                        btformat;
+	int                        btswap;
+};
+#endif
+
+
+#endif
+
+/*  LocalWords:  Endif
+ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/pluto2/pluto2.c linux-libre-2.6.34-gnu1/drivers/media/dvb/pluto2/pluto2.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/pluto2/pluto2.c	2013-05-03 12:04:59.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/pluto2/pluto2.c	2013-05-03 09:45:53.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include "demux.h"
 #include "dmxdev.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/pt1/pt1.c linux-libre-2.6.34-gnu1/drivers/media/dvb/pt1/pt1.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/pt1/pt1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/pt1/pt1.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/pci.h>
 #include <linux/kthread.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/sms-cards.c linux-libre-2.6.34-gnu1/drivers/media/dvb/siano/sms-cards.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/sms-cards.c	2013-05-03 12:05:03.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/siano/sms-cards.c	2013-05-03 09:45:57.000000000 -0400
@@ -62,6 +62,7 @@ static struct sms_board sms_boards[] = {
 	[SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
 		.name	= "Hauppauge WinTV MiniStick",
 		.type	= SMS_NOVA_B0,
+		.fw[DEVICE_MODE_ISDBT_BDA] = "/*(DEBLOBBED)*/",
 		.fw[DEVICE_MODE_DVBT_BDA] = "/*(DEBLOBBED)*/",
 		.board_cfg.leds_power = 26,
 		.board_cfg.led0 = 27,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smscoreapi.c linux-libre-2.6.34-gnu1/drivers/media/dvb/siano/smscoreapi.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smscoreapi.c	2013-05-03 12:05:01.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/siano/smscoreapi.c	2013-05-03 09:45:56.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/firmware.h>
 #include <linux/wait.h>
@@ -1459,8 +1460,10 @@ int smscore_gpio_configure(struct smscor
 	if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
 		pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
 		if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
-				&groupCfg) != 0)
-			return -EINVAL;
+				&groupCfg) != 0) {
+			rc = -EINVAL;
+			goto free;
+		}
 
 		pMsg->msgData[1] = TranslatedPinNum;
 		pMsg->msgData[2] = GroupNum;
@@ -1490,6 +1493,7 @@ int smscore_gpio_configure(struct smscor
 		else
 			sms_err("smscore_gpio_configure error");
 	}
+free:
 	kfree(buffer);
 
 	return rc;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smscoreapi.h linux-libre-2.6.34-gnu1/drivers/media/dvb/siano/smscoreapi.h
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smscoreapi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/siano/smscoreapi.h	2010-05-16 17:17:36.000000000 -0400
@@ -212,6 +212,8 @@ struct smscore_device_t {
 #define MSG_SMS_DAB_CHANNEL				607
 #define MSG_SMS_GET_PID_FILTER_LIST_REQ			608
 #define MSG_SMS_GET_PID_FILTER_LIST_RES			609
+#define MSG_SMS_GET_STATISTICS_RES			616
+#define MSG_SMS_GET_STATISTICS_REQ			615
 #define MSG_SMS_HO_PER_SLICES_IND			630
 #define MSG_SMS_SET_ANTENNA_CONFIG_REQ			651
 #define MSG_SMS_SET_ANTENNA_CONFIG_RES			652
@@ -339,7 +341,7 @@ struct SmsFirmware_ST {
 
 /* Statistics information returned as response for
  * SmsHostApiGetStatistics_Req */
-struct SMSHOSTLIB_STATISTICS_S {
+struct SMSHOSTLIB_STATISTICS_ST {
 	u32 Reserved;		/* Reserved */
 
 	/* Common parameters */
@@ -424,6 +426,79 @@ struct SMSHOSTLIB_STATISTICS_S {
 	u32 ReservedFields[10];	/* Reserved */
 };
 
+struct SmsMsgStatisticsInfo_ST {
+	u32 RequestResult;
+
+	struct SMSHOSTLIB_STATISTICS_ST Stat;
+
+	/* Split the calc of the SNR in DAB */
+	u32 Signal; /* dB */
+	u32 Noise; /* dB */
+
+};
+
+struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST {
+	/* Per-layer information */
+	u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
+		       * 255 means layer does not exist */
+	u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET,
+			    * 255 means layer does not exist */
+	u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
+	u32 BERErrorCount; /* Post Viterbi Error Bits Count */
+	u32 BERBitCount; /* Post Viterbi Total Bits Count */
+	u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
+	u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */
+	u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */
+	u32 TotalTSPackets; /* Total number of transport-stream packets */
+	u32 TILdepthI; /* Time interleaver depth I parameter,
+			* 255 means layer does not exist */
+	u32 NumberOfSegments; /* Number of segments in layer A,
+			       * 255 means layer does not exist */
+	u32 TMCCErrors; /* TMCC errors */
+};
+
+struct SMSHOSTLIB_STATISTICS_ISDBT_ST {
+	u32 StatisticsType; /* Enumerator identifying the type of the
+				* structure.  Values are the same as
+				* SMSHOSTLIB_DEVICE_MODES_E
+				*
+				* This field MUST always be first in any
+				* statistics structure */
+
+	u32 FullSize; /* Total size of the structure returned by the modem.
+		       * If the size requested by the host is smaller than
+		       * FullSize, the struct will be truncated */
+
+	/* Common parameters */
+	u32 IsRfLocked; /* 0 - not locked, 1 - locked */
+	u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
+	u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
+
+	/* Reception quality */
+	s32  SNR; /* dB */
+	s32  RSSI; /* dBm */
+	s32  InBandPwr; /* In band power in dBM */
+	s32  CarrierOffset; /* Carrier Offset in Hz */
+
+	/* Transmission parameters */
+	u32 Frequency; /* Frequency in Hz */
+	u32 Bandwidth; /* Bandwidth in MHz */
+	u32 TransmissionMode; /* ISDB-T transmission mode */
+	u32 ModemState; /* 0 - Acquisition, 1 - Locked */
+	u32 GuardInterval; /* Guard Interval, 1 divided by value */
+	u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */
+	u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */
+	u32 NumOfLayers; /* Number of ISDB-T layers in the network */
+
+	/* Per-layer information */
+	/* Layers A, B and C */
+	struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST	LayerInfo[3];
+	/* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */
+
+	/* Interface information */
+	u32 SmsToHostTxErrors; /* Total number of transmission errors. */
+};
+
 struct PID_STATISTICS_DATA_S {
 	struct PID_BURST_S {
 		u32 size;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smsdvb.c linux-libre-2.6.34-gnu1/drivers/media/dvb/siano/smsdvb.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smsdvb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/siano/smsdvb.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@ along with this program.  If not, see <h
 ****************************************************************/
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #include "dmxdev.h"
@@ -116,6 +117,118 @@ static void sms_board_dvb3_event(struct
 	}
 }
 
+
+static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
+				   struct SMSHOSTLIB_STATISTICS_ST *p)
+{
+	if (sms_dbg & 2) {
+		printk(KERN_DEBUG "Reserved = %d", p->Reserved);
+		printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
+		printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
+		printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
+		printk(KERN_DEBUG "SNR = %d", p->SNR);
+		printk(KERN_DEBUG "BER = %d", p->BER);
+		printk(KERN_DEBUG "FIB_CRC = %d", p->FIB_CRC);
+		printk(KERN_DEBUG "TS_PER = %d", p->TS_PER);
+		printk(KERN_DEBUG "MFER = %d", p->MFER);
+		printk(KERN_DEBUG "RSSI = %d", p->RSSI);
+		printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
+		printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
+		printk(KERN_DEBUG "Frequency = %d", p->Frequency);
+		printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
+		printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
+		printk(KERN_DEBUG "ModemState = %d", p->ModemState);
+		printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
+		printk(KERN_DEBUG "CodeRate = %d", p->CodeRate);
+		printk(KERN_DEBUG "LPCodeRate = %d", p->LPCodeRate);
+		printk(KERN_DEBUG "Hierarchy = %d", p->Hierarchy);
+		printk(KERN_DEBUG "Constellation = %d", p->Constellation);
+		printk(KERN_DEBUG "BurstSize = %d", p->BurstSize);
+		printk(KERN_DEBUG "BurstDuration = %d", p->BurstDuration);
+		printk(KERN_DEBUG "BurstCycleTime = %d", p->BurstCycleTime);
+		printk(KERN_DEBUG "CalculatedBurstCycleTime = %d", p->CalculatedBurstCycleTime);
+		printk(KERN_DEBUG "NumOfRows = %d", p->NumOfRows);
+		printk(KERN_DEBUG "NumOfPaddCols = %d", p->NumOfPaddCols);
+		printk(KERN_DEBUG "NumOfPunctCols = %d", p->NumOfPunctCols);
+		printk(KERN_DEBUG "ErrorTSPackets = %d", p->ErrorTSPackets);
+		printk(KERN_DEBUG "TotalTSPackets = %d", p->TotalTSPackets);
+		printk(KERN_DEBUG "NumOfValidMpeTlbs = %d", p->NumOfValidMpeTlbs);
+		printk(KERN_DEBUG "NumOfInvalidMpeTlbs = %d", p->NumOfInvalidMpeTlbs);
+		printk(KERN_DEBUG "NumOfCorrectedMpeTlbs = %d", p->NumOfCorrectedMpeTlbs);
+		printk(KERN_DEBUG "BERErrorCount = %d", p->BERErrorCount);
+		printk(KERN_DEBUG "BERBitCount = %d", p->BERBitCount);
+		printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
+		printk(KERN_DEBUG "PreBER = %d", p->PreBER);
+		printk(KERN_DEBUG "CellId = %d", p->CellId);
+		printk(KERN_DEBUG "DvbhSrvIndHP = %d", p->DvbhSrvIndHP);
+		printk(KERN_DEBUG "DvbhSrvIndLP = %d", p->DvbhSrvIndLP);
+		printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived);
+	}
+
+	pReceptionData->IsDemodLocked = p->IsDemodLocked;
+
+	pReceptionData->SNR = p->SNR;
+	pReceptionData->BER = p->BER;
+	pReceptionData->BERErrorCount = p->BERErrorCount;
+	pReceptionData->InBandPwr = p->InBandPwr;
+	pReceptionData->ErrorTSPackets = p->ErrorTSPackets;
+};
+
+
+static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
+				    struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p)
+{
+	int i;
+
+	if (sms_dbg & 2) {
+		printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
+		printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
+		printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
+		printk(KERN_DEBUG "SNR = %d", p->SNR);
+		printk(KERN_DEBUG "RSSI = %d", p->RSSI);
+		printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
+		printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
+		printk(KERN_DEBUG "Frequency = %d", p->Frequency);
+		printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
+		printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
+		printk(KERN_DEBUG "ModemState = %d", p->ModemState);
+		printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
+		printk(KERN_DEBUG "SystemType = %d", p->SystemType);
+		printk(KERN_DEBUG "PartialReception = %d", p->PartialReception);
+		printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers);
+		printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
+
+		for (i = 0; i < 3; i++) {
+			printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate);
+			printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation);
+			printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER);
+			printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount);
+			printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount);
+			printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER);
+			printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER);
+			printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets);
+			printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets);
+			printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI);
+			printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments);
+			printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors);
+		}
+	}
+
+	pReceptionData->IsDemodLocked = p->IsDemodLocked;
+
+	pReceptionData->SNR = p->SNR;
+	pReceptionData->InBandPwr = p->InBandPwr;
+
+	pReceptionData->ErrorTSPackets = 0;
+	pReceptionData->BER = 0;
+	pReceptionData->BERErrorCount = 0;
+	for (i = 0; i < 3; i++) {
+		pReceptionData->BER += p->LayerInfo[i].BER;
+		pReceptionData->BERErrorCount += p->LayerInfo[i].BERErrorCount;
+		pReceptionData->ErrorTSPackets += p->LayerInfo[i].ErrorTSPackets;
+	}
+}
+
 static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
 {
 	struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
@@ -134,6 +247,7 @@ static int smsdvb_onresponse(void *conte
 		break;
 
 	case MSG_SMS_RF_TUNE_RES:
+	case MSG_SMS_ISDBT_TUNE_RES:
 		complete(&client->tune_done);
 		break;
 
@@ -217,6 +331,40 @@ static int smsdvb_onresponse(void *conte
 		is_status_update = true;
 		break;
 	}
+	case MSG_SMS_GET_STATISTICS_RES: {
+		union {
+			struct SMSHOSTLIB_STATISTICS_ISDBT_ST  isdbt;
+			struct SmsMsgStatisticsInfo_ST         dvb;
+		} *p = (void *) (phdr + 1);
+		struct RECEPTION_STATISTICS_S *pReceptionData =
+				&client->sms_stat_dvb.ReceptionData;
+
+		sms_info("MSG_SMS_GET_STATISTICS_RES");
+
+		is_status_update = true;
+
+		switch (smscore_get_device_mode(client->coredev)) {
+		case DEVICE_MODE_ISDBT:
+		case DEVICE_MODE_ISDBT_BDA:
+			smsdvb_update_isdbt_stats(pReceptionData, &p->isdbt);
+			break;
+		default:
+			smsdvb_update_dvb_stats(pReceptionData, &p->dvb.Stat);
+		}
+		if (!pReceptionData->IsDemodLocked) {
+			pReceptionData->SNR = 0;
+			pReceptionData->BER = 0;
+			pReceptionData->BERErrorCount = 0;
+			pReceptionData->InBandPwr = 0;
+			pReceptionData->ErrorTSPackets = 0;
+		}
+
+		complete(&client->tune_done);
+		break;
+	}
+	default:
+		sms_info("Unhandled message %d", phdr->msgType);
+
 	}
 	smscore_putbuffer(client->coredev, cb);
 
@@ -233,10 +381,10 @@ static int smsdvb_onresponse(void *conte
 						DVB3_EVENT_UNC_ERR);
 
 		} else {
-			/*client->fe_status =
-				(phdr->msgType == MSG_SMS_NO_SIGNAL_IND) ?
-				0 : FE_HAS_SIGNAL;*/
-			client->fe_status = 0;
+			if (client->sms_stat_dvb.ReceptionData.IsRfLocked)
+				client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
+			else
+				client->fe_status = 0;
 			sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK);
 		}
 	}
@@ -325,6 +473,20 @@ static int smsdvb_sendrequest_and_wait(s
 						0 : -ETIME;
 }
 
+static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
+{
+	int rc;
+	struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ,
+				    DVBT_BDA_CONTROL_MSG_ID,
+				    HIF_TASK,
+				    sizeof(struct SmsMsgHdr_ST), 0 };
+
+	rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+					  &client->tune_done);
+
+	return rc;
+}
+
 static inline int led_feedback(struct smsdvb_client_t *client)
 {
 	if (client->fe_status & FE_HAS_LOCK)
@@ -337,33 +499,43 @@ static inline int led_feedback(struct sm
 
 static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
 {
+	int rc;
 	struct smsdvb_client_t *client;
 	client = container_of(fe, struct smsdvb_client_t, frontend);
 
+	rc = smsdvb_send_statistics_request(client);
+
 	*stat = client->fe_status;
 
 	led_feedback(client);
 
-	return 0;
+	return rc;
 }
 
 static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
 {
+	int rc;
 	struct smsdvb_client_t *client;
 	client = container_of(fe, struct smsdvb_client_t, frontend);
 
+	rc = smsdvb_send_statistics_request(client);
+
 	*ber = client->sms_stat_dvb.ReceptionData.BER;
 
 	led_feedback(client);
 
-	return 0;
+	return rc;
 }
 
 static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 {
+	int rc;
+
 	struct smsdvb_client_t *client;
 	client = container_of(fe, struct smsdvb_client_t, frontend);
 
+	rc = smsdvb_send_statistics_request(client);
+
 	if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95)
 		*strength = 0;
 		else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29)
@@ -375,31 +547,37 @@ static int smsdvb_read_signal_strength(s
 
 	led_feedback(client);
 
-	return 0;
+	return rc;
 }
 
 static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
 {
+	int rc;
 	struct smsdvb_client_t *client;
 	client = container_of(fe, struct smsdvb_client_t, frontend);
 
+	rc = smsdvb_send_statistics_request(client);
+
 	*snr = client->sms_stat_dvb.ReceptionData.SNR;
 
 	led_feedback(client);
 
-	return 0;
+	return rc;
 }
 
 static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 {
+	int rc;
 	struct smsdvb_client_t *client;
 	client = container_of(fe, struct smsdvb_client_t, frontend);
 
+	rc = smsdvb_send_statistics_request(client);
+
 	*ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets;
 
 	led_feedback(client);
 
-	return 0;
+	return rc;
 }
 
 static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
@@ -413,9 +591,10 @@ static int smsdvb_get_tune_settings(stru
 	return 0;
 }
 
-static int smsdvb_set_frontend(struct dvb_frontend *fe,
-			       struct dvb_frontend_parameters *fep)
+static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe,
+				    struct dvb_frontend_parameters *p)
 {
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	struct smsdvb_client_t *client =
 		container_of(fe, struct smsdvb_client_t, frontend);
 
@@ -429,24 +608,33 @@ static int smsdvb_set_frontend(struct dv
 	client->fe_status = FE_HAS_SIGNAL;
 	client->event_fe_state = -1;
 	client->event_unc_state = -1;
+	fe->dtv_property_cache.delivery_system = SYS_DVBT;
 
 	Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
 	Msg.Msg.msgDstId = HIF_TASK;
 	Msg.Msg.msgFlags = 0;
 	Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ;
 	Msg.Msg.msgLength = sizeof(Msg);
-	Msg.Data[0] = fep->frequency;
+	Msg.Data[0] = c->frequency;
 	Msg.Data[2] = 12000000;
 
-	sms_debug("freq %d band %d",
-		  fep->frequency, fep->u.ofdm.bandwidth);
+	sms_info("%s: freq %d band %d", __func__, c->frequency,
+		 c->bandwidth_hz);
 
-	switch (fep->u.ofdm.bandwidth) {
-	case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break;
-	case BANDWIDTH_7_MHZ: Msg.Data[1] = BW_7_MHZ; break;
-	case BANDWIDTH_6_MHZ: Msg.Data[1] = BW_6_MHZ; break;
-	case BANDWIDTH_AUTO: return -EOPNOTSUPP;
-	default: return -EINVAL;
+	switch (c->bandwidth_hz / 1000000) {
+	case 8:
+		Msg.Data[1] = BW_8_MHZ;
+		break;
+	case 7:
+		Msg.Data[1] = BW_7_MHZ;
+		break;
+	case 6:
+		Msg.Data[1] = BW_6_MHZ;
+		break;
+	case 0:
+		return -EOPNOTSUPP;
+	default:
+		return -EINVAL;
 	}
 	/* Disable LNA, if any. An error is returned if no LNA is present */
 	ret = sms_board_lna_control(client->coredev, 0);
@@ -470,6 +658,90 @@ static int smsdvb_set_frontend(struct dv
 					   &client->tune_done);
 }
 
+static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe,
+				     struct dvb_frontend_parameters *p)
+{
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	struct smsdvb_client_t *client =
+		container_of(fe, struct smsdvb_client_t, frontend);
+
+	struct {
+		struct SmsMsgHdr_ST	Msg;
+		u32		Data[4];
+	} Msg;
+
+	fe->dtv_property_cache.delivery_system = SYS_ISDBT;
+
+	Msg.Msg.msgSrcId  = DVBT_BDA_CONTROL_MSG_ID;
+	Msg.Msg.msgDstId  = HIF_TASK;
+	Msg.Msg.msgFlags  = 0;
+	Msg.Msg.msgType   = MSG_SMS_ISDBT_TUNE_REQ;
+	Msg.Msg.msgLength = sizeof(Msg);
+
+	if (c->isdbt_sb_segment_idx == -1)
+		c->isdbt_sb_segment_idx = 0;
+
+	switch (c->isdbt_sb_segment_count) {
+	case 3:
+		Msg.Data[1] = BW_ISDBT_3SEG;
+		break;
+	case 1:
+		Msg.Data[1] = BW_ISDBT_1SEG;
+		break;
+	case 0:	/* AUTO */
+		switch (c->bandwidth_hz / 1000000) {
+		case 8:
+		case 7:
+			c->isdbt_sb_segment_count = 3;
+			Msg.Data[1] = BW_ISDBT_3SEG;
+			break;
+		case 6:
+			c->isdbt_sb_segment_count = 1;
+			Msg.Data[1] = BW_ISDBT_1SEG;
+			break;
+		default: /* Assumes 6 MHZ bw */
+			c->isdbt_sb_segment_count = 1;
+			c->bandwidth_hz = 6000;
+			Msg.Data[1] = BW_ISDBT_1SEG;
+			break;
+		}
+		break;
+	default:
+		sms_info("Segment count %d not supported", c->isdbt_sb_segment_count);
+		return -EINVAL;
+	}
+
+	Msg.Data[0] = c->frequency;
+	Msg.Data[2] = 12000000;
+	Msg.Data[3] = c->isdbt_sb_segment_idx;
+
+	sms_info("%s: freq %d segwidth %d segindex %d\n", __func__,
+		 c->frequency, c->isdbt_sb_segment_count,
+		 c->isdbt_sb_segment_idx);
+
+	return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+					   &client->tune_done);
+}
+
+static int smsdvb_set_frontend(struct dvb_frontend *fe,
+			       struct dvb_frontend_parameters *fep)
+{
+	struct smsdvb_client_t *client =
+		container_of(fe, struct smsdvb_client_t, frontend);
+	struct smscore_device_t *coredev = client->coredev;
+
+	switch (smscore_get_device_mode(coredev)) {
+	case DEVICE_MODE_DVBT:
+	case DEVICE_MODE_DVBT_BDA:
+		return smsdvb_dvbt_set_frontend(fe, fep);
+	case DEVICE_MODE_ISDBT:
+	case DEVICE_MODE_ISDBT_BDA:
+		return smsdvb_isdbt_set_frontend(fe, fep);
+	default:
+		return -EINVAL;
+	}
+}
+
 static int smsdvb_get_frontend(struct dvb_frontend *fe,
 			       struct dvb_frontend_parameters *fep)
 {
@@ -557,13 +829,6 @@ static int smsdvb_hotplug(struct smscore
 	/* device removal handled by onremove callback */
 	if (!arrival)
 		return 0;
-
-	if (smscore_get_device_mode(coredev) != DEVICE_MODE_DVBT_BDA) {
-		sms_err("SMS Device mode is not set for "
-			"DVB operation.");
-		return 0;
-	}
-
 	client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
 	if (!client) {
 		sms_err("kmalloc() failed");
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smsir.c linux-libre-2.6.34-gnu1/drivers/media/dvb/siano/smsir.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smsir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/siano/smsir.c	2010-05-16 17:17:36.000000000 -0400
@@ -85,9 +85,9 @@ static struct keyboard_layout_map_t keyb
 		{ } /* Terminating entry */
 };
 
-u32 ir_pos;
-u32	ir_word;
-u32 ir_toggle;
+static u32 ir_pos;
+static u32 ir_word;
+static u32 ir_toggle;
 
 #define RC5_PUSH_BIT(dst, bit, pos)	\
 	{ dst <<= 1; dst |= bit; pos++; }
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smssdio.c linux-libre-2.6.34-gnu1/drivers/media/dvb/siano/smssdio.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smssdio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/siano/smssdio.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
  */
 
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/delay.h>
 #include <linux/mmc/card.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smsusb.c linux-libre-2.6.34-gnu1/drivers/media/dvb/siano/smsusb.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smsusb.c	2013-05-03 12:05:05.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/siano/smsusb.c	2013-05-03 09:46:00.000000000 -0400
@@ -23,6 +23,7 @@ along with this program.  If not, see <h
 #include <linux/init.h>
 #include <linux/usb.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #include "smscoreapi.h"
 #include "sms-cards.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/av7110.c linux-libre-2.6.34-gnu1/drivers/media/dvb/ttpci/av7110.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/av7110.c	2013-05-03 12:04:57.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/ttpci/av7110.c	2013-05-03 09:45:49.000000000 -0400
@@ -49,6 +49,7 @@
 #include <linux/crc32.h>
 #include <linux/i2c.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include <asm/byteorder.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/av7110_ca.c linux-libre-2.6.34-gnu1/drivers/media/dvb/ttpci/av7110_ca.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/av7110_ca.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/ttpci/av7110_ca.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/fs.h>
 #include <linux/timer.h>
 #include <linux/poll.h>
+#include <linux/gfp.h>
 
 #include "av7110.h"
 #include "av7110_hw.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/av7110_ir.c linux-libre-2.6.34-gnu1/drivers/media/dvb/ttpci/av7110_ir.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/av7110_ir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/ttpci/av7110_ir.c	2010-05-16 17:17:36.000000000 -0400
@@ -268,8 +268,8 @@ int av7110_check_ir_config(struct av7110
 
 
 /* /proc/av7110_ir interface */
-static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
-				unsigned long count, void *data)
+static ssize_t av7110_ir_proc_write(struct file *file, const char __user *buffer,
+				    size_t count, loff_t *pos)
 {
 	char *page;
 	u32 ir_config;
@@ -309,6 +309,10 @@ static int av7110_ir_write_proc(struct f
 	return count;
 }
 
+static const struct file_operations av7110_ir_proc_fops = {
+	.owner		= THIS_MODULE,
+	.write		= av7110_ir_proc_write,
+};
 
 /* interrupt handler */
 static void ir_handler(struct av7110 *av7110, u32 ircom)
@@ -368,11 +372,9 @@ int __devinit av7110_ir_init(struct av71
 	input_dev->timer.data = (unsigned long) &av7110->ir;
 
 	if (av_cnt == 1) {
-		e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
-		if (e) {
-			e->write_proc = av7110_ir_write_proc;
+		e = proc_create("av7110_ir", S_IWUSR, NULL, &av7110_ir_proc_fops);
+		if (e)
 			e->size = 4 + 256 * sizeof(u16);
-		}
 	}
 
 	tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/budget.c linux-libre-2.6.34-gnu1/drivers/media/dvb/ttpci/budget.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/budget.c	2013-05-03 12:04:57.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/ttpci/budget.c	2013-05-03 09:45:49.000000000 -0400
@@ -433,9 +433,8 @@ static struct stv090x_config tt1600_stv0
 	.demod_mode		= STV090x_SINGLE,
 	.clk_mode		= STV090x_CLK_EXT,
 
-	.xtal			= 27000000,
+	.xtal			= 13500000,
 	.address		= 0x68,
-	.ref_clk		= 27000000,
 
 	.ts1_mode		= STV090x_TSMODE_DVBCI,
 	.ts2_mode		= STV090x_TSMODE_SERIAL_CONTINUOUS,
@@ -457,6 +456,7 @@ static struct stv090x_config tt1600_stv0
 static struct stv6110x_config tt1600_stv6110x_config = {
 	.addr			= 0x60,
 	.refclk			= 27000000,
+	.clk_div		= 2,
 };
 
 static struct isl6423_config tt1600_isl6423_config = {
@@ -643,9 +643,6 @@ static void frontend_init(struct budget
 					&budget->i2c_adap,
 					&tt1600_isl6423_config);
 
-			} else {
-				dvb_frontend_detach(budget->dvb_frontend);
-				budget->dvb_frontend = NULL;
 			}
 		}
 		break;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/budget-ci.c linux-libre-2.6.34-gnu1/drivers/media/dvb/ttpci/budget-ci.c
--- linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/budget-ci.c	2013-05-03 12:04:57.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/dvb/ttpci/budget-ci.c	2013-05-03 09:45:49.000000000 -0400
@@ -254,7 +254,7 @@ static int msp430_ir_init(struct budget_
 	budget_ci->ir.timer_keyup.function = msp430_ir_keyup;
 	budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir;
 	budget_ci->ir.last_raw = 0xffff; /* An impossible value */
-	error = ir_input_register(input_dev, ir_codes);
+	error = ir_input_register(input_dev, ir_codes, NULL);
 	if (error) {
 		printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
 		return error;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/IR/ir-functions.c linux-libre-2.6.34-gnu1/drivers/media/IR/ir-functions.c
--- linux-libre-2.6.33-gnu1/drivers/media/IR/ir-functions.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/IR/ir-functions.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,7 +52,7 @@ static void ir_input_key_event(struct in
 /* -------------------------------------------------------------------------- */
 
 int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
-		   int ir_type)
+		  const u64 ir_type)
 {
 	ir->ir_type = ir_type;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/IR/ir-keymaps.c linux-libre-2.6.34-gnu1/drivers/media/IR/ir-keymaps.c
--- linux-libre-2.6.33-gnu1/drivers/media/IR/ir-keymaps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/IR/ir-keymaps.c	2010-05-16 17:17:36.000000000 -0400
@@ -3393,3 +3393,102 @@ struct ir_scancode_table ir_codes_nec_te
 };
 EXPORT_SYMBOL_GPL(ir_codes_nec_terratec_cinergy_xs_table);
 
+
+/* Leadtek Winfast TV USB II Deluxe remote
+   Magnus Alm <magnus.alm@gmail.com>
+ */
+static struct ir_scancode ir_codes_winfast_usbii_deluxe[] = {
+	{ 0x62, KEY_0},
+	{ 0x75, KEY_1},
+	{ 0x76, KEY_2},
+	{ 0x77, KEY_3},
+	{ 0x79, KEY_4},
+	{ 0x7a, KEY_5},
+	{ 0x7b, KEY_6},
+	{ 0x7d, KEY_7},
+	{ 0x7e, KEY_8},
+	{ 0x7f, KEY_9},
+
+	{ 0x38, KEY_CAMERA},		/* SNAPSHOT */
+	{ 0x37, KEY_RECORD},		/* RECORD */
+	{ 0x35, KEY_TIME},		/* TIMESHIFT */
+
+	{ 0x74, KEY_VOLUMEUP},		/* VOLUMEUP */
+	{ 0x78, KEY_VOLUMEDOWN},	/* VOLUMEDOWN */
+	{ 0x64, KEY_MUTE},		/* MUTE */
+
+	{ 0x21, KEY_CHANNEL},		/* SURF */
+	{ 0x7c, KEY_CHANNELUP},		/* CHANNELUP */
+	{ 0x60, KEY_CHANNELDOWN},	/* CHANNELDOWN */
+	{ 0x61, KEY_LAST},		/* LAST CHANNEL (RECALL) */
+
+	{ 0x72, KEY_VIDEO}, 		/* INPUT MODES (TV/FM) */
+
+	{ 0x70, KEY_POWER2},		/* TV ON/OFF */
+
+	{ 0x39, KEY_CYCLEWINDOWS},	/* MINIMIZE (BOSS) */
+	{ 0x3a, KEY_NEW},		/* PIP */
+	{ 0x73, KEY_ZOOM},		/* FULLSECREEN */
+
+	{ 0x66, KEY_INFO},		/* OSD (DISPLAY) */
+
+	{ 0x31, KEY_DOT},		/* '.' */
+	{ 0x63, KEY_ENTER},		/* ENTER */
+
+};
+struct ir_scancode_table ir_codes_winfast_usbii_deluxe_table = {
+	.scan = ir_codes_winfast_usbii_deluxe,
+	.size = ARRAY_SIZE(ir_codes_winfast_usbii_deluxe),
+};
+EXPORT_SYMBOL_GPL(ir_codes_winfast_usbii_deluxe_table);
+
+/* Kworld 315U
+ */
+static struct ir_scancode ir_codes_kworld_315u[] = {
+	{ 0x6143, KEY_POWER },
+	{ 0x6101, KEY_TUNER },		/* source */
+	{ 0x610b, KEY_ZOOM },
+	{ 0x6103, KEY_POWER2 },		/* shutdown */
+
+	{ 0x6104, KEY_1 },
+	{ 0x6108, KEY_2 },
+	{ 0x6102, KEY_3 },
+	{ 0x6109, KEY_CHANNELUP },
+
+	{ 0x610f, KEY_4 },
+	{ 0x6105, KEY_5 },
+	{ 0x6106, KEY_6 },
+	{ 0x6107, KEY_CHANNELDOWN },
+
+	{ 0x610c, KEY_7 },
+	{ 0x610d, KEY_8 },
+	{ 0x610a, KEY_9 },
+	{ 0x610e, KEY_VOLUMEUP },
+
+	{ 0x6110, KEY_LAST },
+	{ 0x6111, KEY_0 },
+	{ 0x6112, KEY_ENTER },
+	{ 0x6113, KEY_VOLUMEDOWN },
+
+	{ 0x6114, KEY_RECORD },
+	{ 0x6115, KEY_STOP },
+	{ 0x6116, KEY_PLAY },
+	{ 0x6117, KEY_MUTE },
+
+	{ 0x6118, KEY_UP },
+	{ 0x6119, KEY_DOWN },
+	{ 0x611a, KEY_LEFT },
+	{ 0x611b, KEY_RIGHT },
+
+	{ 0x611c, KEY_RED },
+	{ 0x611d, KEY_GREEN },
+	{ 0x611e, KEY_YELLOW },
+	{ 0x611f, KEY_BLUE },
+};
+
+struct ir_scancode_table ir_codes_kworld_315u_table = {
+	.scan = ir_codes_kworld_315u,
+	.size = ARRAY_SIZE(ir_codes_kworld_315u),
+	.ir_type = IR_TYPE_NEC,
+};
+EXPORT_SYMBOL_GPL(ir_codes_kworld_315u_table);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/IR/ir-keytable.c linux-libre-2.6.34-gnu1/drivers/media/IR/ir-keytable.c
--- linux-libre-2.6.33-gnu1/drivers/media/IR/ir-keytable.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/IR/ir-keytable.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <media/ir-common.h>
 
 #define IR_TAB_MIN_SIZE	32
@@ -65,7 +66,7 @@ exit:
  * In order to reduce the quantity of table resizes, it has a minimum
  * table size of IR_TAB_MIN_SIZE.
  */
-int ir_roundup_tablesize(int n_elems)
+static int ir_roundup_tablesize(int n_elems)
 {
 	size_t size;
 
@@ -81,7 +82,6 @@ int ir_roundup_tablesize(int n_elems)
 
 	return n_elems;
 }
-EXPORT_SYMBOL_GPL(ir_roundup_tablesize);
 
 /**
  * ir_copy_table() - copies a keytable, discarding the unused entries
@@ -89,9 +89,11 @@ EXPORT_SYMBOL_GPL(ir_roundup_tablesize);
  * @origin:	origin table
  *
  * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED
+ * Also copies table size and table protocol.
+ * NOTE: It shouldn't copy the lock field
  */
 
-int ir_copy_table(struct ir_scancode_table *destin,
+static int ir_copy_table(struct ir_scancode_table *destin,
 		 const struct ir_scancode_table *origin)
 {
 	int i, j = 0;
@@ -105,12 +107,12 @@ int ir_copy_table(struct ir_scancode_tab
 		j++;
 	}
 	destin->size = j;
+	destin->ir_type = origin->ir_type;
 
 	IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size);
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(ir_copy_table);
 
 /**
  * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table
@@ -122,7 +124,7 @@ EXPORT_SYMBOL_GPL(ir_copy_table);
  * If the key is not found, returns -EINVAL, otherwise, returns 0.
  */
 static int ir_getkeycode(struct input_dev *dev,
-			 int scancode, int *keycode)
+			 unsigned int scancode, unsigned int *keycode)
 {
 	int elem;
 	struct ir_input_dev *ir_dev = input_get_drvdata(dev);
@@ -184,18 +186,14 @@ static void ir_delete_key(struct ir_scan
 	int newsize = rc_tab->size - 1;
 	int resize = ir_is_resize_needed(rc_tab, newsize);
 	struct ir_scancode *oldkeymap = rc_tab->scan;
-	struct ir_scancode *newkeymap;
+	struct ir_scancode *newkeymap = NULL;
 
-	if (resize) {
+	if (resize)
 		newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
 				    sizeof(*newkeymap), GFP_ATOMIC);
 
-		/* There's no memory for resize. Keep the old table */
-		if (!newkeymap)
-			resize = 0;
-	}
-
-	if (!resize) {
+	/* There's no memory for resize. Keep the old table */
+	if (!resize || !newkeymap) {
 		newkeymap = oldkeymap;
 
 		/* We'll modify the live table. Lock it */
@@ -294,7 +292,7 @@ static int ir_insert_key(struct ir_scanc
  * If the key is not found, returns -EINVAL, otherwise, returns 0.
  */
 static int ir_setkeycode(struct input_dev *dev,
-			 int scancode, int keycode)
+			 unsigned int scancode, unsigned int keycode)
 {
 	int rc = 0;
 	struct ir_input_dev *ir_dev = input_get_drvdata(dev);
@@ -399,12 +397,14 @@ EXPORT_SYMBOL_GPL(ir_g_keycode_from_tabl
  * @input_dev:	the struct input_dev descriptor of the device
  * @rc_tab:	the struct ir_scancode_table table of scancode/keymap
  *
- * This routine is used to initialize the input infrastructure to work with
- * an IR.
- * It should be called before registering the IR device.
+ * This routine is used to initialize the input infrastructure
+ * to work with an IR.
+ * It will register the input/evdev interface for the device and
+ * register the syfs code for IR class
  */
 int ir_input_register(struct input_dev *input_dev,
-		      struct ir_scancode_table *rc_tab)
+		      const struct ir_scancode_table *rc_tab,
+		      const struct ir_dev_props *props)
 {
 	struct ir_input_dev *ir_dev;
 	struct ir_scancode  *keymap    = rc_tab->scan;
@@ -417,19 +417,22 @@ int ir_input_register(struct input_dev *
 	if (!ir_dev)
 		return -ENOMEM;
 
-	spin_lock_init(&rc_tab->lock);
+	spin_lock_init(&ir_dev->rc_tab.lock);
 
 	ir_dev->rc_tab.size = ir_roundup_tablesize(rc_tab->size);
 	ir_dev->rc_tab.scan = kzalloc(ir_dev->rc_tab.size *
 				    sizeof(struct ir_scancode), GFP_KERNEL);
-	if (!ir_dev->rc_tab.scan)
+	if (!ir_dev->rc_tab.scan) {
+		kfree(ir_dev);
 		return -ENOMEM;
+	}
 
 	IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n",
 		ir_dev->rc_tab.size,
 		ir_dev->rc_tab.size * sizeof(ir_dev->rc_tab.scan));
 
 	ir_copy_table(&ir_dev->rc_tab, rc_tab);
+	ir_dev->props = props;
 
 	/* set the bits for the keys */
 	IR_dprintk(1, "key map size: %d\n", rc_tab->size);
@@ -447,16 +450,31 @@ int ir_input_register(struct input_dev *
 	input_set_drvdata(input_dev, ir_dev);
 
 	rc = input_register_device(input_dev);
+	if (rc < 0)
+		goto err;
+
+	rc = ir_register_class(input_dev);
 	if (rc < 0) {
-		kfree(rc_tab->scan);
-		kfree(ir_dev);
-		input_set_drvdata(input_dev, NULL);
+		input_unregister_device(input_dev);
+		goto err;
 	}
 
+	return 0;
+
+err:
+	kfree(rc_tab->scan);
+	kfree(ir_dev);
+	input_set_drvdata(input_dev, NULL);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(ir_input_register);
 
+/**
+ * ir_input_unregister() - unregisters IR and frees resources
+ * @input_dev:	the struct input_dev descriptor of the device
+
+ * This routine is used to free memory and de-register interfaces.
+ */
 void ir_input_unregister(struct input_dev *dev)
 {
 	struct ir_input_dev *ir_dev = input_get_drvdata(dev);
@@ -472,6 +490,8 @@ void ir_input_unregister(struct input_de
 	kfree(rc_tab->scan);
 	rc_tab->scan = NULL;
 
+	ir_unregister_class(dev);
+
 	kfree(ir_dev);
 	input_unregister_device(dev);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/IR/ir-sysfs.c linux-libre-2.6.34-gnu1/drivers/media/IR/ir-sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/media/IR/ir-sysfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/IR/ir-sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,212 @@
+/* ir-register.c - handle IR scancode->keycode tables
+ *
+ * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/device.h>
+#include <media/ir-core.h>
+
+#define IRRCV_NUM_DEVICES	256
+
+/* bit array to represent IR sysfs device number */
+static unsigned long ir_core_dev_number;
+
+/* class for /sys/class/irrcv */
+static struct class *ir_input_class;
+
+/**
+ * show_protocol() - shows the current IR protocol
+ * @d:		the device descriptor
+ * @mattr:	the device attribute struct (unused)
+ * @buf:	a pointer to the output buffer
+ *
+ * This routine is a callback routine for input read the IR protocol type.
+ * it is trigged by reading /sys/class/irrcv/irrcv?/current_protocol.
+ * It returns the protocol name, as understood by the driver.
+ */
+static ssize_t show_protocol(struct device *d,
+			     struct device_attribute *mattr, char *buf)
+{
+	char *s;
+	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
+	u64 ir_type = ir_dev->rc_tab.ir_type;
+
+	IR_dprintk(1, "Current protocol is %lld\n", (long long)ir_type);
+
+	/* FIXME: doesn't support multiple protocols at the same time */
+	if (ir_type == IR_TYPE_UNKNOWN)
+		s = "Unknown";
+	else if (ir_type == IR_TYPE_RC5)
+		s = "RC-5";
+	else if (ir_type == IR_TYPE_PD)
+		s = "Pulse/distance";
+	else if (ir_type == IR_TYPE_NEC)
+		s = "NEC";
+	else
+		s = "Other";
+
+	return sprintf(buf, "%s\n", s);
+}
+
+/**
+ * store_protocol() - shows the current IR protocol
+ * @d:		the device descriptor
+ * @mattr:	the device attribute struct (unused)
+ * @buf:	a pointer to the input buffer
+ * @len:	length of the input buffer
+ *
+ * This routine is a callback routine for changing the IR protocol type.
+ * it is trigged by reading /sys/class/irrcv/irrcv?/current_protocol.
+ * It changes the IR the protocol name, if the IR type is recognized
+ * by the driver.
+ * If an unknown protocol name is used, returns -EINVAL.
+ */
+static ssize_t store_protocol(struct device *d,
+			      struct device_attribute *mattr,
+			      const char *data,
+			      size_t len)
+{
+	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
+	u64 ir_type = IR_TYPE_UNKNOWN;
+	int rc = -EINVAL;
+	unsigned long flags;
+	char *buf;
+
+	buf = strsep((char **) &data, "\n");
+
+	if (!strcasecmp(buf, "rc-5"))
+		ir_type = IR_TYPE_RC5;
+	else if (!strcasecmp(buf, "pd"))
+		ir_type = IR_TYPE_PD;
+	else if (!strcasecmp(buf, "nec"))
+		ir_type = IR_TYPE_NEC;
+
+	if (ir_type == IR_TYPE_UNKNOWN) {
+		IR_dprintk(1, "Error setting protocol to %lld\n",
+			   (long long)ir_type);
+		return -EINVAL;
+	}
+
+	if (ir_dev->props && ir_dev->props->change_protocol)
+		rc = ir_dev->props->change_protocol(ir_dev->props->priv,
+						    ir_type);
+
+	if (rc < 0) {
+		IR_dprintk(1, "Error setting protocol to %lld\n",
+			   (long long)ir_type);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
+	ir_dev->rc_tab.ir_type = ir_type;
+	spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
+
+	IR_dprintk(1, "Current protocol is %lld\n",
+		   (long long)ir_type);
+
+	return len;
+}
+
+/*
+ * Static device attribute struct with the sysfs attributes for IR's
+ */
+static DEVICE_ATTR(current_protocol, S_IRUGO | S_IWUSR,
+		   show_protocol, store_protocol);
+
+static struct attribute *ir_dev_attrs[] = {
+	&dev_attr_current_protocol.attr,
+	NULL,
+};
+
+/**
+ * ir_register_class() - creates the sysfs for /sys/class/irrcv/irrcv?
+ * @input_dev:	the struct input_dev descriptor of the device
+ *
+ * This routine is used to register the syfs code for IR class
+ */
+int ir_register_class(struct input_dev *input_dev)
+{
+	int rc;
+	struct kobject *kobj;
+
+	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+	int devno = find_first_zero_bit(&ir_core_dev_number,
+					IRRCV_NUM_DEVICES);
+
+	if (unlikely(devno < 0))
+		return devno;
+
+	ir_dev->attr.attrs = ir_dev_attrs;
+	ir_dev->class_dev = device_create(ir_input_class, NULL,
+					  input_dev->dev.devt, ir_dev,
+					  "irrcv%d", devno);
+	kobj = &ir_dev->class_dev->kobj;
+
+	printk(KERN_WARNING "Creating IR device %s\n", kobject_name(kobj));
+	rc = sysfs_create_group(kobj, &ir_dev->attr);
+	if (unlikely(rc < 0)) {
+		device_destroy(ir_input_class, input_dev->dev.devt);
+		return -ENOMEM;
+	}
+
+	ir_dev->devno = devno;
+	set_bit(devno, &ir_core_dev_number);
+
+	return 0;
+};
+
+/**
+ * ir_unregister_class() - removes the sysfs for sysfs for
+ *			   /sys/class/irrcv/irrcv?
+ * @input_dev:	the struct input_dev descriptor of the device
+ *
+ * This routine is used to unregister the syfs code for IR class
+ */
+void ir_unregister_class(struct input_dev *input_dev)
+{
+	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+	struct kobject *kobj;
+
+	clear_bit(ir_dev->devno, &ir_core_dev_number);
+
+	kobj = &ir_dev->class_dev->kobj;
+
+	sysfs_remove_group(kobj, &ir_dev->attr);
+	device_destroy(ir_input_class, input_dev->dev.devt);
+
+	kfree(ir_dev->attr.name);
+}
+
+/*
+ * Init/exit code for the module. Basically, creates/removes /sys/class/irrcv
+ */
+
+static int __init ir_core_init(void)
+{
+	ir_input_class = class_create(THIS_MODULE, "irrcv");
+	if (IS_ERR(ir_input_class)) {
+		printk(KERN_ERR "ir_core: unable to register irrcv class\n");
+		return PTR_ERR(ir_input_class);
+	}
+
+	return 0;
+}
+
+static void __exit ir_core_exit(void)
+{
+	class_destroy(ir_input_class);
+}
+
+module_init(ir_core_init);
+module_exit(ir_core_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/IR/Makefile linux-libre-2.6.34-gnu1/drivers/media/IR/Makefile
--- linux-libre-2.6.33-gnu1/drivers/media/IR/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/IR/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 ir-common-objs  := ir-functions.o ir-keymaps.o
-ir-core-objs	:= ir-keytable.o
+ir-core-objs	:= ir-keytable.o ir-sysfs.o
 
 obj-$(CONFIG_IR_CORE) += ir-core.o
 obj-$(CONFIG_VIDEO_IR) += ir-common.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/radio/Kconfig linux-libre-2.6.34-gnu1/drivers/media/radio/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/media/radio/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/radio/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -417,6 +417,18 @@ config RADIO_TEA5764_XTAL
 	  Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N
 	  here if TEA5764 reference frequency is connected in FREQIN.
 
+config RADIO_SAA7706H
+	tristate "SAA7706H Car Radio DSP"
+	depends on I2C && VIDEO_V4L2
+	---help---
+	  Say Y here if you want to use the SAA7706H Car radio Digital
+	  Signal Processor, found for instance on the Russellville development
+	  board. On the russellville the device is connected to internal
+	  timberdale I2C bus.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called SAA7706H.
+
 config RADIO_TEF6862
 	tristate "TEF6862 Car Radio Enhanced Selectivity Tuner"
 	depends on I2C && VIDEO_V4L2
@@ -429,4 +441,15 @@ config RADIO_TEF6862
 	  To compile this driver as a module, choose M here: the
 	  module will be called TEF6862.
 
+config RADIO_TIMBERDALE
+	tristate "Enable the Timberdale radio driver"
+	depends on MFD_TIMBERDALE && VIDEO_V4L2
+	depends on I2C	# for RADIO_SAA7706H
+	select RADIO_TEF6862
+	select RADIO_SAA7706H
+	---help---
+	  This is a kind of umbrella driver for the Radio Tuner and DSP
+	  found behind the Timberdale FPGA on the Russellville board.
+	  Enabling this driver will automatically select the DSP and tuner.
+
 endif # RADIO_ADAPTERS
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/radio/Makefile linux-libre-2.6.34-gnu1/drivers/media/radio/Makefile
--- linux-libre-2.6.33-gnu1/drivers/media/radio/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/radio/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,8 @@ obj-$(CONFIG_USB_DSBR) += dsbr100.o
 obj-$(CONFIG_RADIO_SI470X) += si470x/
 obj-$(CONFIG_USB_MR800) += radio-mr800.o
 obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o
+obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o
 obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
+obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o
 
 EXTRA_CFLAGS += -Isound
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/radio/radio-gemtek-pci.c linux-libre-2.6.34-gnu1/drivers/media/radio/radio-gemtek-pci.c
--- linux-libre-2.6.33-gnu1/drivers/media/radio/radio-gemtek-pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/radio/radio-gemtek-pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,6 +48,7 @@
 #include <linux/errno.h>
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/radio/radio-maestro.c linux-libre-2.6.34-gnu1/drivers/media/radio/radio-maestro.c
--- linux-libre-2.6.33-gnu1/drivers/media/radio/radio-maestro.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/radio/radio-maestro.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/pci.h>
 #include <linux/videodev2.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/radio/radio-maxiradio.c linux-libre-2.6.34-gnu1/drivers/media/radio/radio-maxiradio.c
--- linux-libre-2.6.33-gnu1/drivers/media/radio/radio-maxiradio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/radio/radio-maxiradio.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/videodev2.h>
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/radio/radio-si4713.c linux-libre-2.6.34-gnu1/drivers/media/radio/radio-si4713.c
--- linux-libre-2.6.33-gnu1/drivers/media/radio/radio-si4713.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/radio/radio-si4713.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/radio/radio-tea5764.c linux-libre-2.6.34-gnu1/drivers/media/radio/radio-tea5764.c
--- linux-libre-2.6.33-gnu1/drivers/media/radio/radio-tea5764.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/radio/radio-tea5764.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
  *  add RDS support
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>			/* Initdata			*/
 #include <linux/videodev2.h>		/* kernel radio structs		*/
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/radio/radio-timb.c linux-libre-2.6.34-gnu1/drivers/media/radio/radio-timb.c
--- linux-libre-2.6.33-gnu1/drivers/media/radio/radio-timb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/radio/radio-timb.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,245 @@
+/*
+ * radio-timb.c Timberdale FPGA Radio driver
+ * Copyright (c) 2009 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/version.h>
+#include <linux/io.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <media/timb_radio.h>
+
+#define DRIVER_NAME "timb-radio"
+
+struct timbradio {
+	struct timb_radio_platform_data	pdata;
+	struct v4l2_subdev	*sd_tuner;
+	struct v4l2_subdev	*sd_dsp;
+	struct video_device	video_dev;
+	struct v4l2_device	v4l2_dev;
+};
+
+
+static int timbradio_vidioc_querycap(struct file *file, void  *priv,
+	struct v4l2_capability *v)
+{
+	strlcpy(v->driver, DRIVER_NAME, sizeof(v->driver));
+	strlcpy(v->card, "Timberdale Radio", sizeof(v->card));
+	snprintf(v->bus_info, sizeof(v->bus_info), "platform:"DRIVER_NAME);
+	v->version = KERNEL_VERSION(0, 0, 1);
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	return 0;
+}
+
+static int timbradio_vidioc_g_tuner(struct file *file, void *priv,
+	struct v4l2_tuner *v)
+{
+	struct timbradio *tr = video_drvdata(file);
+	return v4l2_subdev_call(tr->sd_tuner, tuner, g_tuner, v);
+}
+
+static int timbradio_vidioc_s_tuner(struct file *file, void *priv,
+	struct v4l2_tuner *v)
+{
+	struct timbradio *tr = video_drvdata(file);
+	return v4l2_subdev_call(tr->sd_tuner, tuner, s_tuner, v);
+}
+
+static int timbradio_vidioc_g_input(struct file *filp, void *priv,
+	unsigned int *i)
+{
+	*i = 0;
+	return 0;
+}
+
+static int timbradio_vidioc_s_input(struct file *filp, void *priv,
+	unsigned int i)
+{
+	return i ? -EINVAL : 0;
+}
+
+static int timbradio_vidioc_g_audio(struct file *file, void *priv,
+	struct v4l2_audio *a)
+{
+	a->index = 0;
+	strlcpy(a->name, "Radio", sizeof(a->name));
+	a->capability = V4L2_AUDCAP_STEREO;
+	return 0;
+}
+
+static int timbradio_vidioc_s_audio(struct file *file, void *priv,
+	struct v4l2_audio *a)
+{
+	return a->index ? -EINVAL : 0;
+}
+
+static int timbradio_vidioc_s_frequency(struct file *file, void *priv,
+	struct v4l2_frequency *f)
+{
+	struct timbradio *tr = video_drvdata(file);
+	return v4l2_subdev_call(tr->sd_tuner, tuner, s_frequency, f);
+}
+
+static int timbradio_vidioc_g_frequency(struct file *file, void *priv,
+	struct v4l2_frequency *f)
+{
+	struct timbradio *tr = video_drvdata(file);
+	return v4l2_subdev_call(tr->sd_tuner, tuner, g_frequency, f);
+}
+
+static int timbradio_vidioc_queryctrl(struct file *file, void *priv,
+	struct v4l2_queryctrl *qc)
+{
+	struct timbradio *tr = video_drvdata(file);
+	return v4l2_subdev_call(tr->sd_dsp, core, queryctrl, qc);
+}
+
+static int timbradio_vidioc_g_ctrl(struct file *file, void *priv,
+	struct v4l2_control *ctrl)
+{
+	struct timbradio *tr = video_drvdata(file);
+	return v4l2_subdev_call(tr->sd_dsp, core, g_ctrl, ctrl);
+}
+
+static int timbradio_vidioc_s_ctrl(struct file *file, void *priv,
+	struct v4l2_control *ctrl)
+{
+	struct timbradio *tr = video_drvdata(file);
+	return v4l2_subdev_call(tr->sd_dsp, core, s_ctrl, ctrl);
+}
+
+static const struct v4l2_ioctl_ops timbradio_ioctl_ops = {
+	.vidioc_querycap	= timbradio_vidioc_querycap,
+	.vidioc_g_tuner		= timbradio_vidioc_g_tuner,
+	.vidioc_s_tuner		= timbradio_vidioc_s_tuner,
+	.vidioc_g_frequency	= timbradio_vidioc_g_frequency,
+	.vidioc_s_frequency	= timbradio_vidioc_s_frequency,
+	.vidioc_g_input		= timbradio_vidioc_g_input,
+	.vidioc_s_input		= timbradio_vidioc_s_input,
+	.vidioc_g_audio		= timbradio_vidioc_g_audio,
+	.vidioc_s_audio		= timbradio_vidioc_s_audio,
+	.vidioc_queryctrl	= timbradio_vidioc_queryctrl,
+	.vidioc_g_ctrl		= timbradio_vidioc_g_ctrl,
+	.vidioc_s_ctrl		= timbradio_vidioc_s_ctrl
+};
+
+static const struct v4l2_file_operations timbradio_fops = {
+	.owner		= THIS_MODULE,
+	.ioctl		= video_ioctl2,
+};
+
+static int __devinit timbradio_probe(struct platform_device *pdev)
+{
+	struct timb_radio_platform_data *pdata = pdev->dev.platform_data;
+	struct timbradio *tr;
+	int err;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "Platform data missing\n");
+		err = -EINVAL;
+		goto err;
+	}
+
+	tr = kzalloc(sizeof(*tr), GFP_KERNEL);
+	if (!tr) {
+		err = -ENOMEM;
+		goto err;
+	}
+
+	tr->pdata = *pdata;
+
+	strlcpy(tr->video_dev.name, "Timberdale Radio",
+		sizeof(tr->video_dev.name));
+	tr->video_dev.fops = &timbradio_fops;
+	tr->video_dev.ioctl_ops = &timbradio_ioctl_ops;
+	tr->video_dev.release = video_device_release_empty;
+	tr->video_dev.minor = -1;
+
+	strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name));
+	err = v4l2_device_register(NULL, &tr->v4l2_dev);
+	if (err)
+		goto err_v4l2_dev;
+
+	tr->video_dev.v4l2_dev = &tr->v4l2_dev;
+
+	err = video_register_device(&tr->video_dev, VFL_TYPE_RADIO, -1);
+	if (err) {
+		dev_err(&pdev->dev, "Error reg video\n");
+		goto err_video_req;
+	}
+
+	video_set_drvdata(&tr->video_dev, tr);
+
+	platform_set_drvdata(pdev, tr);
+	return 0;
+
+err_video_req:
+	video_device_release_empty(&tr->video_dev);
+	v4l2_device_unregister(&tr->v4l2_dev);
+err_v4l2_dev:
+	kfree(tr);
+err:
+	dev_err(&pdev->dev, "Failed to register: %d\n", err);
+
+	return err;
+}
+
+static int __devexit timbradio_remove(struct platform_device *pdev)
+{
+	struct timbradio *tr = platform_get_drvdata(pdev);
+
+	video_unregister_device(&tr->video_dev);
+	video_device_release_empty(&tr->video_dev);
+
+	v4l2_device_unregister(&tr->v4l2_dev);
+
+	kfree(tr);
+
+	return 0;
+}
+
+static struct platform_driver timbradio_platform_driver = {
+	.driver = {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= timbradio_probe,
+	.remove		= timbradio_remove,
+};
+
+/*--------------------------------------------------------------------------*/
+
+static int __init timbradio_init(void)
+{
+	return platform_driver_register(&timbradio_platform_driver);
+}
+
+static void __exit timbradio_exit(void)
+{
+	platform_driver_unregister(&timbradio_platform_driver);
+}
+
+module_init(timbradio_init);
+module_exit(timbradio_exit);
+
+MODULE_DESCRIPTION("Timberdale Radio driver");
+MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:"DRIVER_NAME);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/radio/saa7706h.c linux-libre-2.6.34-gnu1/drivers/media/radio/saa7706h.c
--- linux-libre-2.6.33-gnu1/drivers/media/radio/saa7706h.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/radio/saa7706h.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,452 @@
+/*
+ * saa7706.c Philips SAA7706H Car Radio DSP driver
+ * Copyright (c) 2009 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+
+#define DRIVER_NAME "saa7706h"
+
+/* the I2C memory map looks like this
+
+	$1C00 - $FFFF Not Used
+	$2200 - $3FFF Reserved YRAM (DSP2) space
+	$2000 - $21FF YRAM (DSP2)
+	$1FF0 - $1FFF Hardware Registers
+	$1280 - $1FEF Reserved XRAM (DSP2) space
+	$1000 - $127F XRAM (DSP2)
+	$0FFF        DSP CONTROL
+	$0A00 - $0FFE Reserved
+	$0980 - $09FF Reserved YRAM (DSP1) space
+	$0800 - $097F YRAM (DSP1)
+	$0200 - $07FF Not Used
+	$0180 - $01FF Reserved XRAM (DSP1) space
+	$0000 - $017F XRAM (DSP1)
+*/
+
+#define SAA7706H_REG_CTRL		0x0fff
+#define SAA7706H_CTRL_BYP_PLL		0x0001
+#define SAA7706H_CTRL_PLL_DIV_MASK	0x003e
+#define SAA7706H_CTRL_PLL3_62975MHZ	0x003e
+#define SAA7706H_CTRL_DSP_TURBO		0x0040
+#define SAA7706H_CTRL_PC_RESET_DSP1	0x0080
+#define SAA7706H_CTRL_PC_RESET_DSP2	0x0100
+#define SAA7706H_CTRL_DSP1_ROM_EN_MASK	0x0600
+#define SAA7706H_CTRL_DSP1_FUNC_PROM	0x0000
+#define SAA7706H_CTRL_DSP2_ROM_EN_MASK	0x1800
+#define SAA7706H_CTRL_DSP2_FUNC_PROM	0x0000
+#define SAA7706H_CTRL_DIG_SIL_INTERPOL	0x8000
+
+#define SAA7706H_REG_EVALUATION			0x1ff0
+#define SAA7706H_EVAL_DISABLE_CHARGE_PUMP	0x000001
+#define SAA7706H_EVAL_DCS_CLOCK			0x000002
+#define SAA7706H_EVAL_GNDRC1_ENABLE		0x000004
+#define SAA7706H_EVAL_GNDRC2_ENABLE		0x000008
+
+#define SAA7706H_REG_CL_GEN1			0x1ff3
+#define SAA7706H_CL_GEN1_MIN_LOOPGAIN_MASK	0x00000f
+#define SAA7706H_CL_GEN1_LOOPGAIN_MASK		0x0000f0
+#define SAA7706H_CL_GEN1_COARSE_RATION		0xffff00
+
+#define SAA7706H_REG_CL_GEN2			0x1ff4
+#define SAA7706H_CL_GEN2_WSEDGE_FALLING		0x000001
+#define SAA7706H_CL_GEN2_STOP_VCO		0x000002
+#define SAA7706H_CL_GEN2_FRERUN			0x000004
+#define SAA7706H_CL_GEN2_ADAPTIVE		0x000008
+#define SAA7706H_CL_GEN2_FINE_RATIO_MASK	0x0ffff0
+
+#define SAA7706H_REG_CL_GEN4		0x1ff6
+#define SAA7706H_CL_GEN4_BYPASS_PLL1	0x001000
+#define SAA7706H_CL_GEN4_PLL1_DIV_MASK	0x03e000
+#define SAA7706H_CL_GEN4_DSP1_TURBO	0x040000
+
+#define SAA7706H_REG_SEL	0x1ff7
+#define SAA7706H_SEL_DSP2_SRCA_MASK	0x000007
+#define SAA7706H_SEL_DSP2_FMTA_MASK	0x000031
+#define SAA7706H_SEL_DSP2_SRCB_MASK	0x0001c0
+#define SAA7706H_SEL_DSP2_FMTB_MASK	0x000e00
+#define SAA7706H_SEL_DSP1_SRC_MASK	0x003000
+#define SAA7706H_SEL_DSP1_FMT_MASK	0x01c003
+#define SAA7706H_SEL_SPDIF2		0x020000
+#define SAA7706H_SEL_HOST_IO_FMT_MASK	0x1c0000
+#define SAA7706H_SEL_EN_HOST_IO		0x200000
+
+#define SAA7706H_REG_IAC		0x1ff8
+#define SAA7706H_REG_CLK_SET		0x1ff9
+#define SAA7706H_REG_CLK_COEFF		0x1ffa
+#define SAA7706H_REG_INPUT_SENS		0x1ffb
+#define SAA7706H_INPUT_SENS_RDS_VOL_MASK	0x0003f
+#define SAA7706H_INPUT_SENS_FM_VOL_MASK		0x00fc0
+#define SAA7706H_INPUT_SENS_FM_MPX		0x01000
+#define SAA7706H_INPUT_SENS_OFF_FILTER_A_EN	0x02000
+#define SAA7706H_INPUT_SENS_OFF_FILTER_B_EN	0x04000
+#define SAA7706H_REG_PHONE_NAV_AUDIO	0x1ffc
+#define SAA7706H_REG_IO_CONF_DSP2	0x1ffd
+#define SAA7706H_REG_STATUS_DSP2	0x1ffe
+#define SAA7706H_REG_PC_DSP2		0x1fff
+
+#define SAA7706H_DSP1_MOD0	0x0800
+#define SAA7706H_DSP1_ROM_VER	0x097f
+#define SAA7706H_DSP2_MPTR0	0x1000
+
+#define SAA7706H_DSP1_MODPNTR	0x0000
+
+#define SAA7706H_DSP2_XMEM_CONTLLCW	0x113e
+#define SAA7706H_DSP2_XMEM_BUSAMP	0x114a
+#define SAA7706H_DSP2_XMEM_FDACPNTR	0x11f9
+#define SAA7706H_DSP2_XMEM_IIS1PNTR	0x11fb
+
+#define SAA7706H_DSP2_YMEM_PVGA		0x212a
+#define SAA7706H_DSP2_YMEM_PVAT1	0x212b
+#define SAA7706H_DSP2_YMEM_PVAT		0x212c
+#define SAA7706H_DSP2_YMEM_ROM_VER	0x21ff
+
+#define SUPPORTED_DSP1_ROM_VER		0x667
+
+struct saa7706h_state {
+	struct v4l2_subdev sd;
+	unsigned muted;
+};
+
+static inline struct saa7706h_state *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct saa7706h_state, sd);
+}
+
+static int saa7706h_i2c_send(struct i2c_client *client, const u8 *data, int len)
+{
+	int err = i2c_master_send(client, data, len);
+	if (err == len)
+		return 0;
+	return err > 0 ? -EIO : err;
+}
+
+static int saa7706h_i2c_transfer(struct i2c_client *client,
+	struct i2c_msg *msgs, int num)
+{
+	int err = i2c_transfer(client->adapter, msgs, num);
+	if (err == num)
+		return 0;
+	return err > 0 ? -EIO : err;
+}
+
+static int saa7706h_set_reg24(struct v4l2_subdev *sd, u16 reg, u32 val)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	u8 buf[5];
+	int pos = 0;
+
+	buf[pos++] = reg >> 8;
+	buf[pos++] = reg;
+	buf[pos++] = val >> 16;
+	buf[pos++] = val >> 8;
+	buf[pos++] = val;
+
+	return saa7706h_i2c_send(client, buf, pos);
+}
+
+static int saa7706h_set_reg24_err(struct v4l2_subdev *sd, u16 reg, u32 val,
+	int *err)
+{
+	return *err ? *err : saa7706h_set_reg24(sd, reg, val);
+}
+
+static int saa7706h_set_reg16(struct v4l2_subdev *sd, u16 reg, u16 val)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	u8 buf[4];
+	int pos = 0;
+
+	buf[pos++] = reg >> 8;
+	buf[pos++] = reg;
+	buf[pos++] = val >> 8;
+	buf[pos++] = val;
+
+	return saa7706h_i2c_send(client, buf, pos);
+}
+
+static int saa7706h_set_reg16_err(struct v4l2_subdev *sd, u16 reg, u16 val,
+	int *err)
+{
+	return *err ? *err : saa7706h_set_reg16(sd, reg, val);
+}
+
+static int saa7706h_get_reg16(struct v4l2_subdev *sd, u16 reg)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	u8 buf[2];
+	int err;
+	u8 regaddr[] = {reg >> 8, reg};
+	struct i2c_msg msg[] = { {client->addr, 0, sizeof(regaddr), regaddr},
+				{client->addr, I2C_M_RD, sizeof(buf), buf} };
+
+	err = saa7706h_i2c_transfer(client, msg, ARRAY_SIZE(msg));
+	if (err)
+		return err;
+
+	return buf[0] << 8 | buf[1];
+}
+
+static int saa7706h_unmute(struct v4l2_subdev *sd)
+{
+	struct saa7706h_state *state = to_state(sd);
+	int err = 0;
+
+	err = saa7706h_set_reg16_err(sd, SAA7706H_REG_CTRL,
+		SAA7706H_CTRL_PLL3_62975MHZ | SAA7706H_CTRL_PC_RESET_DSP1 |
+		SAA7706H_CTRL_PC_RESET_DSP2, &err);
+
+	/* newer versions of the chip requires a small sleep after reset */
+	msleep(1);
+
+	err = saa7706h_set_reg16_err(sd, SAA7706H_REG_CTRL,
+		SAA7706H_CTRL_PLL3_62975MHZ, &err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_REG_EVALUATION, 0, &err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_REG_CL_GEN1, 0x040022, &err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_REG_CL_GEN2,
+		SAA7706H_CL_GEN2_WSEDGE_FALLING, &err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_REG_CL_GEN4, 0x024080, &err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_REG_SEL, 0x200080, &err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_REG_IAC, 0xf4caed, &err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_REG_CLK_SET, 0x124334, &err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_REG_CLK_COEFF, 0x004a1a,
+		&err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_REG_INPUT_SENS, 0x0071c7,
+		&err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_REG_PHONE_NAV_AUDIO,
+		0x0e22ff, &err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_REG_IO_CONF_DSP2, 0x001ff8,
+		&err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_REG_STATUS_DSP2, 0x080003,
+		&err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_REG_PC_DSP2, 0x000004, &err);
+
+	err = saa7706h_set_reg16_err(sd, SAA7706H_DSP1_MOD0, 0x0c6c, &err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_MPTR0, 0x000b4b, &err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_DSP1_MODPNTR, 0x000600, &err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_DSP1_MODPNTR, 0x0000c0, &err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_CONTLLCW, 0x000819,
+		&err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_CONTLLCW, 0x00085a,
+		&err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_BUSAMP, 0x7fffff,
+		&err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_FDACPNTR, 0x2000cb,
+		&err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_IIS1PNTR, 0x2000cb,
+		&err);
+
+	err = saa7706h_set_reg16_err(sd, SAA7706H_DSP2_YMEM_PVGA, 0x0f80, &err);
+
+	err = saa7706h_set_reg16_err(sd, SAA7706H_DSP2_YMEM_PVAT1, 0x0800,
+		&err);
+
+	err = saa7706h_set_reg16_err(sd, SAA7706H_DSP2_YMEM_PVAT, 0x0800, &err);
+
+	err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_CONTLLCW, 0x000905,
+		&err);
+	if (!err)
+		state->muted = 0;
+	return err;
+}
+
+static int saa7706h_mute(struct v4l2_subdev *sd)
+{
+	struct saa7706h_state *state = to_state(sd);
+	int err;
+
+	err = saa7706h_set_reg16(sd, SAA7706H_REG_CTRL,
+		SAA7706H_CTRL_PLL3_62975MHZ | SAA7706H_CTRL_PC_RESET_DSP1 |
+		SAA7706H_CTRL_PC_RESET_DSP2);
+	if (!err)
+		state->muted = 1;
+	return err;
+}
+
+static int saa7706h_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+	}
+	return -EINVAL;
+}
+
+static int saa7706h_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct saa7706h_state *state = to_state(sd);
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		ctrl->value = state->muted;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static int saa7706h_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		if (ctrl->value)
+			return saa7706h_mute(sd);
+		return saa7706h_unmute(sd);
+	}
+	return -EINVAL;
+}
+
+static int saa7706h_g_chip_ident(struct v4l2_subdev *sd,
+	struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7706H, 0);
+}
+
+static const struct v4l2_subdev_core_ops saa7706h_core_ops = {
+	.g_chip_ident = saa7706h_g_chip_ident,
+	.queryctrl = saa7706h_queryctrl,
+	.g_ctrl = saa7706h_g_ctrl,
+	.s_ctrl = saa7706h_s_ctrl,
+};
+
+static const struct v4l2_subdev_ops saa7706h_ops = {
+	.core = &saa7706h_core_ops,
+};
+
+/*
+ * Generic i2c probe
+ * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
+ */
+
+static int __devinit saa7706h_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct saa7706h_state *state;
+	struct v4l2_subdev *sd;
+	int err;
+
+	/* Check if the adapter supports the needed features */
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	v4l_info(client, "chip found @ 0x%02x (%s)\n",
+			client->addr << 1, client->adapter->name);
+
+	state = kmalloc(sizeof(struct saa7706h_state), GFP_KERNEL);
+	if (state == NULL)
+		return -ENOMEM;
+	sd = &state->sd;
+	v4l2_i2c_subdev_init(sd, client, &saa7706h_ops);
+
+	/* check the rom versions */
+	err = saa7706h_get_reg16(sd, SAA7706H_DSP1_ROM_VER);
+	if (err < 0)
+		goto err;
+	if (err != SUPPORTED_DSP1_ROM_VER)
+		v4l2_warn(sd, "Unknown DSP1 ROM code version: 0x%x\n", err);
+
+	state->muted = 1;
+
+	/* startup in a muted state */
+	err = saa7706h_mute(sd);
+	if (err)
+		goto err;
+
+	return 0;
+
+err:
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_state(sd));
+
+	printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", err);
+
+	return err;
+}
+
+static int __devexit saa7706h_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	saa7706h_mute(sd);
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_state(sd));
+	return 0;
+}
+
+static const struct i2c_device_id saa7706h_id[] = {
+	{DRIVER_NAME, 0},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, saa7706h_id);
+
+static struct i2c_driver saa7706h_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= DRIVER_NAME,
+	},
+	.probe		= saa7706h_probe,
+	.remove		= saa7706h_remove,
+	.id_table	= saa7706h_id,
+};
+
+static __init int saa7706h_init(void)
+{
+	return i2c_add_driver(&saa7706h_driver);
+}
+
+static __exit void saa7706h_exit(void)
+{
+	i2c_del_driver(&saa7706h_driver);
+}
+
+module_init(saa7706h_init);
+module_exit(saa7706h_exit);
+
+MODULE_DESCRIPTION("SAA7706H Car Radio DSP driver");
+MODULE_AUTHOR("Mocean Laboratories");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/radio/si470x/radio-si470x-common.c linux-libre-2.6.34-gnu1/drivers/media/radio/si470x/radio-si470x-common.c
--- linux-libre-2.6.33-gnu1/drivers/media/radio/si470x/radio-si470x-common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/radio/si470x/radio-si470x-common.c	2010-05-16 17:17:36.000000000 -0400
@@ -724,7 +724,7 @@ static int si470x_vidioc_g_tuner(struct
 		tuner->audmode = V4L2_TUNER_MODE_MONO;
 
 	/* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */
-	/* measured in units of dbì¨‰V in 1 db increments (max at ~75 dbì¨‰V) */
+	/* measured in units of dbÂµV in 1 db increments (max at ~75 dbÂµV) */
 	tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI);
 	/* the ideal factor is 0xffff/75 = 873,8 */
 	tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/radio/si470x/radio-si470x-i2c.c linux-libre-2.6.34-gnu1/drivers/media/radio/si470x/radio-si470x-i2c.c
--- linux-libre-2.6.33-gnu1/drivers/media/radio/si470x/radio-si470x-i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/radio/si470x/radio-si470x-i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 
 /* kernel includes */
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/radio/si470x/radio-si470x-usb.c linux-libre-2.6.34-gnu1/drivers/media/radio/si470x/radio-si470x-usb.c
--- linux-libre-2.6.33-gnu1/drivers/media/radio/si470x/radio-si470x-usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/radio/si470x/radio-si470x-usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 /* kernel includes */
 #include <linux/usb.h>
 #include <linux/hid.h>
+#include <linux/slab.h>
 
 #include "radio-si470x.h"
 
@@ -590,8 +591,9 @@ int si470x_fops_release(struct file *fil
 			video_unregister_device(radio->videodev);
 			kfree(radio->int_in_buffer);
 			kfree(radio->buffer);
+			mutex_unlock(&radio->disconnect_lock);
 			kfree(radio);
-			goto unlock;
+			goto done;
 		}
 
 		/* cancel read processes */
@@ -601,7 +603,6 @@ int si470x_fops_release(struct file *fil
 		retval = si470x_stop(radio);
 		usb_autopm_put_interface(radio->intf);
 	}
-unlock:
 	mutex_unlock(&radio->disconnect_lock);
 done:
 	return retval;
@@ -842,9 +843,11 @@ static void si470x_usb_driver_disconnect
 		kfree(radio->int_in_buffer);
 		video_unregister_device(radio->videodev);
 		kfree(radio->buffer);
+		mutex_unlock(&radio->disconnect_lock);
 		kfree(radio);
+	} else {
+		mutex_unlock(&radio->disconnect_lock);
 	}
-	mutex_unlock(&radio->disconnect_lock);
 }
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/radio/si4713-i2c.c linux-libre-2.6.34-gnu1/drivers/media/radio/si4713-i2c.c
--- linux-libre-2.6.33-gnu1/drivers/media/radio/si4713-i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/radio/si4713-i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-common.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/radio/tef6862.c linux-libre-2.6.34-gnu1/drivers/media/radio/tef6862.c
--- linux-libre-2.6.33-gnu1/drivers/media/radio/tef6862.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/radio/tef6862.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
+#include <linux/slab.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/adv7170.c linux-libre-2.6.34-gnu1/drivers/media/video/adv7170.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/adv7170.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/adv7170.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/adv7175.c linux-libre-2.6.34-gnu1/drivers/media/video/adv7175.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/adv7175.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/adv7175.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/adv7180.c linux-libre-2.6.34-gnu1/drivers/media/video/adv7180.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/adv7180.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/adv7180.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
+#include <linux/slab.h>
 #include <media/v4l2-ioctl.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/adv7343.c linux-libre-2.6.34-gnu1/drivers/media/video/adv7343.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/adv7343.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/adv7343.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/device.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/au0828/au0828-core.c linux-libre-2.6.34-gnu1/drivers/media/video/au0828/au0828-core.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/au0828/au0828-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/au0828/au0828-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <linux/mutex.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/au0828/au0828-dvb.c linux-libre-2.6.34-gnu1/drivers/media/video/au0828/au0828-dvb.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/au0828/au0828-dvb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/au0828/au0828-dvb.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/suspend.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/au0828/au0828-video.c linux-libre-2.6.34-gnu1/drivers/media/video/au0828/au0828-video.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/au0828/au0828-video.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/au0828/au0828-video.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/suspend.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/bt819.c linux-libre-2.6.34-gnu1/drivers/media/video/bt819.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/bt819.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/bt819.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv.h>
@@ -254,7 +255,7 @@ static int bt819_s_std(struct v4l2_subde
 		v4l2_err(sd, "no notify found!\n");
 
 	if (std & V4L2_STD_NTSC) {
-		v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0);
+		v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
 		bt819_setbit(decoder, 0x01, 0, 1);
 		bt819_setbit(decoder, 0x01, 1, 0);
 		bt819_setbit(decoder, 0x01, 5, 0);
@@ -263,7 +264,7 @@ static int bt819_s_std(struct v4l2_subde
 		/* 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);
+		v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
 		bt819_setbit(decoder, 0x01, 0, 1);
 		bt819_setbit(decoder, 0x01, 1, 1);
 		bt819_setbit(decoder, 0x01, 5, 1);
@@ -288,7 +289,7 @@ static int bt819_s_std(struct v4l2_subde
 	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);
+	v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
 	return 0;
 }
 
@@ -306,7 +307,7 @@ static int bt819_s_routing(struct v4l2_s
 		v4l2_err(sd, "no notify found!\n");
 
 	if (decoder->input != input) {
-		v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0);
+		v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
 		decoder->input = input;
 		/* select mode */
 		if (decoder->input == 0) {
@@ -316,7 +317,7 @@ static int bt819_s_routing(struct v4l2_s
 			bt819_setbit(decoder, 0x0b, 6, 1);
 			bt819_setbit(decoder, 0x1a, 1, 0);
 		}
-		v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, 0);
+		v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
 	}
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/bt856.c linux-libre-2.6.34-gnu1/drivers/media/video/bt856.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/bt856.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/bt856.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/bt866.c linux-libre-2.6.34-gnu1/drivers/media/video/bt866.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/bt866.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/bt866.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-cards.c linux-libre-2.6.34-gnu1/drivers/media/video/bt8xx/bttv-cards.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-cards.c	2013-05-03 12:06:48.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/bt8xx/bttv-cards.c	2013-05-03 09:46:10.000000000 -0400
@@ -4401,7 +4401,7 @@ static void rv605_muxsel(struct bttv *bt
 /* Tibet Systems 'Progress DVR' CS16 muxsel helper [Chris Fanning]
  *
  * The CS16 (available on eBay cheap) is a PCI board with four Fusion
- * 878A chips, a PCI bridge, an Atmel microcontroller, four sync seperator
+ * 878A chips, a PCI bridge, an Atmel microcontroller, four sync separator
  * chips, ten eight input analog multiplexors, a not chip and a few
  * other components.
  *
@@ -4423,7 +4423,7 @@ static void rv605_muxsel(struct bttv *bt
  *
  * There is an ATMEL microcontroller with an 8031 core on board.  I have not
  * determined what function (if any) it provides.  With the microcontroller
- * and sync seperator chips a guess is that it might have to do with video
+ * and sync separator chips a guess is that it might have to do with video
  * switching and maybe some digital I/O.
  */
 static void tibetCS16_muxsel(struct bttv *btv, unsigned int input)
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-driver.c linux-libre-2.6.34-gnu1/drivers/media/video/bt8xx/bttv-driver.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-driver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/bt8xx/bttv-driver.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
@@ -81,6 +82,7 @@ static int video_nr[BTTV_MAX] = { [0 ...
 static int radio_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };
 static int vbi_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };
 static int debug_latency;
+static int disable_ir;
 
 static unsigned int fdsr;
 
@@ -107,6 +109,7 @@ module_param(bttv_gpio,         int, 064
 module_param(bttv_debug,        int, 0644);
 module_param(irq_debug,         int, 0644);
 module_param(debug_latency,     int, 0644);
+module_param(disable_ir,        int, 0444);
 
 module_param(fdsr,              int, 0444);
 module_param(gbuffers,          int, 0444);
@@ -139,6 +142,7 @@ MODULE_PARM_DESC(bttv_verbose,"verbose s
 MODULE_PARM_DESC(bttv_gpio,"log gpio changes, default is 0 (no)");
 MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)");
 MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)");
+MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
 MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8");
 MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000");
 MODULE_PARM_DESC(reset_crop,"reset cropping parameters at open(), default "
@@ -4461,8 +4465,10 @@ static int __devinit bttv_probe(struct p
 		request_modules(btv);
 	}
 
-	init_bttv_i2c_ir(btv);
-	bttv_input_init(btv);
+	if (!disable_ir) {
+		init_bttv_i2c_ir(btv);
+		bttv_input_init(btv);
+	}
 
 	/* everything is fine */
 	bttv_num++;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-gpio.c linux-libre-2.6.34-gnu1/drivers/media/video/bt8xx/bttv-gpio.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/bt8xx/bttv-gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #include "bttvp.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-input.c linux-libre-2.6.34-gnu1/drivers/media/video/bt8xx/bttv-input.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-input.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/bt8xx/bttv-input.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 
 #include "bttv.h"
 #include "bttvp.h"
@@ -247,7 +248,7 @@ int bttv_input_init(struct bttv *btv)
 	struct card_ir *ir;
 	struct ir_scancode_table *ir_codes = NULL;
 	struct input_dev *input_dev;
-	int ir_type = IR_TYPE_OTHER;
+	u64 ir_type = IR_TYPE_OTHER;
 	int err = -ENOMEM;
 
 	if (!btv->has_remote)
@@ -389,7 +390,7 @@ int bttv_input_init(struct bttv *btv)
 	bttv_ir_start(btv, ir);
 
 	/* all done */
-	err = ir_input_register(btv->remote->dev, ir_codes);
+	err = ir_input_register(btv->remote->dev, ir_codes, NULL);
 	if (err)
 		goto err_out_stop;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-risc.c linux-libre-2.6.34-gnu1/drivers/media/video/bt8xx/bttv-risc.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-risc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/bt8xx/bttv-risc.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cafe_ccic.c linux-libre-2.6.34-gnu1/drivers/media/video/cafe_ccic.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cafe_ccic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cafe_ccic.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-chip-ident.h>
@@ -1907,7 +1908,6 @@ static int cafe_pci_probe(struct pci_dev
 		goto out_free;
 
 	mutex_init(&cam->s_mutex);
-	mutex_lock(&cam->s_mutex);
 	spin_lock_init(&cam->dev_lock);
 	cam->state = S_NOTREADY;
 	cafe_set_config_needed(cam, 1);
@@ -1947,7 +1947,6 @@ static int cafe_pci_probe(struct pci_dev
 	 * because the sensor could attach in this call chain, leading to
 	 * unsightly deadlocks.
 	 */
-	mutex_unlock(&cam->s_mutex);  /* attach can deadlock */
 	ret = cafe_smbus_setup(cam);
 	if (ret)
 		goto out_freeirq;
@@ -1973,7 +1972,7 @@ static int cafe_pci_probe(struct pci_dev
 	cam->vdev.v4l2_dev = &cam->v4l2_dev;
 	ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);
 	if (ret)
-		goto out_smbus;
+		goto out_unlock;
 	video_set_drvdata(&cam->vdev, cam);
 
 	/*
@@ -1988,6 +1987,8 @@ static int cafe_pci_probe(struct pci_dev
 	mutex_unlock(&cam->s_mutex);
 	return 0;
 
+out_unlock:
+	mutex_unlock(&cam->s_mutex);
 out_smbus:
 	cafe_smbus_shutdown(cam);
 out_freeirq:
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cpia.c linux-libre-2.6.34-gnu1/drivers/media/video/cpia.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cpia.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cpia.c	2010-05-16 17:17:36.000000000 -0400
@@ -3737,9 +3737,6 @@ static int cpia_mmap(struct file *file,
 	if (size > FRAME_NUM*CPIA_MAX_FRAME_SIZE)
 		return -EINVAL;
 
-	if (!cam || !cam->ops)
-		return -ENODEV;
-
 	/* make this _really_ smp-safe */
 	if (mutex_lock_interruptible(&cam->busy_lock))
 		return -EINTR;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cpia_pp.c linux-libre-2.6.34-gnu1/drivers/media/video/cpia_pp.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cpia_pp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cpia_pp.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/delay.h>
 #include <linux/workqueue.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <linux/kmod.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cs5345.c linux-libre-2.6.34-gnu1/drivers/media/video/cs5345.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cs5345.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cs5345.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cs53l32a.c linux-libre-2.6.34-gnu1/drivers/media/video/cs53l32a.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cs53l32a.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cs53l32a.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-alsa.h linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-alsa.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-alsa.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-alsa.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,75 @@
+/*
+ *  ALSA interface to cx18 PCM capture streams
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ *  02111-1307  USA
+ */
+
+struct snd_card;
+
+struct snd_cx18_card {
+	struct v4l2_device *v4l2_dev;
+	struct snd_card *sc;
+	unsigned int capture_transfer_done;
+	unsigned int hwptr_done_capture;
+	struct snd_pcm_substream *capture_pcm_substream;
+	spinlock_t slock;
+};
+
+extern int cx18_alsa_debug;
+
+/*
+ * File operations that manipulate the encoder or video or audio subdevices
+ * need to be serialized.  Use the same lock we use for v4l2 file ops.
+ */
+static inline void snd_cx18_lock(struct snd_cx18_card *cxsc)
+{
+	struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
+	mutex_lock(&cx->serialize_lock);
+}
+
+static inline void snd_cx18_unlock(struct snd_cx18_card *cxsc)
+{
+	struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
+	mutex_unlock(&cx->serialize_lock);
+}
+
+#define CX18_ALSA_DBGFLG_WARN  (1 << 0)
+#define CX18_ALSA_DBGFLG_WARN  (1 << 0)
+#define CX18_ALSA_DBGFLG_INFO  (1 << 1)
+
+#define CX18_ALSA_DEBUG(x, type, fmt, args...) \
+	do { \
+		if ((x) & cx18_alsa_debug) \
+			printk(KERN_INFO "%s-alsa: " type ": " fmt, \
+				v4l2_dev->name , ## args); \
+	} while (0)
+
+#define CX18_ALSA_DEBUG_WARN(fmt, args...) \
+	CX18_ALSA_DEBUG(CX18_ALSA_DBGFLG_WARN, "warning", fmt , ## args)
+
+#define CX18_ALSA_DEBUG_INFO(fmt, args...) \
+	CX18_ALSA_DEBUG(CX18_ALSA_DBGFLG_INFO, "info", fmt , ## args)
+
+#define CX18_ALSA_ERR(fmt, args...) \
+	printk(KERN_ERR "%s-alsa: " fmt, v4l2_dev->name , ## args)
+
+#define CX18_ALSA_WARN(fmt, args...) \
+	printk(KERN_WARNING "%s-alsa: " fmt, v4l2_dev->name , ## args)
+
+#define CX18_ALSA_INFO(fmt, args...) \
+	printk(KERN_INFO "%s-alsa: " fmt, v4l2_dev->name , ## args)
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-alsa-main.c linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-alsa-main.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-alsa-main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-alsa-main.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,294 @@
+/*
+ *  ALSA interface to cx18 PCM capture streams
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.net>
+ *  Copyright (C) 2009  Devin Heitmueller <dheitmueller@kernellabs.com>
+ *
+ *  Portions of this work were sponsored by ONELAN Limited.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ *  02111-1307  USA
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+
+#include <media/v4l2-device.h>
+
+#include <sound/core.h>
+#include <sound/initval.h>
+
+#include "cx18-driver.h"
+#include "cx18-version.h"
+#include "cx18-alsa.h"
+#include "cx18-alsa-mixer.h"
+#include "cx18-alsa-pcm.h"
+
+int cx18_alsa_debug;
+
+#define CX18_DEBUG_ALSA_INFO(fmt, arg...) \
+	do { \
+		if (cx18_alsa_debug & 2) \
+			printk(KERN_INFO "%s: " fmt, "cx18-alsa", ## arg); \
+	} while (0);
+
+module_param_named(debug, cx18_alsa_debug, int, 0644);
+MODULE_PARM_DESC(debug,
+		 "Debug level (bitmask). Default: 0\n"
+		 "\t\t\t  1/0x0001: warning\n"
+		 "\t\t\t  2/0x0002: info\n");
+
+MODULE_AUTHOR("Andy Walls");
+MODULE_DESCRIPTION("CX23418 ALSA Interface");
+MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder");
+MODULE_LICENSE("GPL");
+
+MODULE_VERSION(CX18_VERSION);
+
+static inline
+struct snd_cx18_card *to_snd_cx18_card(struct v4l2_device *v4l2_dev)
+{
+	return to_cx18(v4l2_dev)->alsa;
+}
+
+static inline
+struct snd_cx18_card *p_to_snd_cx18_card(struct v4l2_device **v4l2_dev)
+{
+	return container_of(v4l2_dev, struct snd_cx18_card, v4l2_dev);
+}
+
+static void snd_cx18_card_free(struct snd_cx18_card *cxsc)
+{
+	if (cxsc == NULL)
+		return;
+
+	if (cxsc->v4l2_dev != NULL)
+		to_cx18(cxsc->v4l2_dev)->alsa = NULL;
+
+	/* FIXME - take any other stopping actions needed */
+
+	kfree(cxsc);
+}
+
+static void snd_cx18_card_private_free(struct snd_card *sc)
+{
+	if (sc == NULL)
+		return;
+	snd_cx18_card_free(sc->private_data);
+	sc->private_data = NULL;
+	sc->private_free = NULL;
+}
+
+static int snd_cx18_card_create(struct v4l2_device *v4l2_dev,
+				       struct snd_card *sc,
+				       struct snd_cx18_card **cxsc)
+{
+	*cxsc = kzalloc(sizeof(struct snd_cx18_card), GFP_KERNEL);
+	if (*cxsc == NULL)
+		return -ENOMEM;
+
+	(*cxsc)->v4l2_dev = v4l2_dev;
+	(*cxsc)->sc = sc;
+
+	sc->private_data = *cxsc;
+	sc->private_free = snd_cx18_card_private_free;
+
+	return 0;
+}
+
+static int snd_cx18_card_set_names(struct snd_cx18_card *cxsc)
+{
+	struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
+	struct snd_card *sc = cxsc->sc;
+
+	/* sc->driver is used by alsa-lib's configurator: simple, unique */
+	strlcpy(sc->driver, "CX23418", sizeof(sc->driver));
+
+	/* sc->shortname is a symlink in /proc/asound: CX18-M -> cardN */
+	snprintf(sc->shortname,  sizeof(sc->shortname), "CX18-%d",
+		 cx->instance);
+
+	/* sc->longname is read from /proc/asound/cards */
+	snprintf(sc->longname, sizeof(sc->longname),
+		 "CX23418 #%d %s TV/FM Radio/Line-In Capture",
+		 cx->instance, cx->card_name);
+
+	return 0;
+}
+
+static int snd_cx18_init(struct v4l2_device *v4l2_dev)
+{
+	struct cx18 *cx = to_cx18(v4l2_dev);
+	struct snd_card *sc = NULL;
+	struct snd_cx18_card *cxsc;
+	int ret;
+
+	/* Numbrs steps from "Writing an ALSA Driver" by Takashi Iwai */
+
+	/* (1) Check and increment the device index */
+	/* This is a no-op for us.  We'll use the cx->instance */
+
+	/* (2) Create a card instance */
+	ret = snd_card_create(SNDRV_DEFAULT_IDX1, /* use first available id */
+			      SNDRV_DEFAULT_STR1, /* xid from end of shortname*/
+			      THIS_MODULE, 0, &sc);
+	if (ret) {
+		CX18_ALSA_ERR("%s: snd_card_create() failed with err %d\n",
+			      __func__, ret);
+		goto err_exit;
+	}
+
+	/* (3) Create a main component */
+	ret = snd_cx18_card_create(v4l2_dev, sc, &cxsc);
+	if (ret) {
+		CX18_ALSA_ERR("%s: snd_cx18_card_create() failed with err %d\n",
+			      __func__, ret);
+		goto err_exit_free;
+	}
+
+	/* (4) Set the driver ID and name strings */
+	snd_cx18_card_set_names(cxsc);
+
+
+	ret = snd_cx18_pcm_create(cxsc);
+	if (ret) {
+		CX18_ALSA_ERR("%s: snd_cx18_pcm_create() failed with err %d\n",
+			      __func__, ret);
+		goto err_exit_free;
+	}
+	/* FIXME - proc files */
+
+	/* (7) Set the driver data and return 0 */
+	/* We do this out of normal order for PCI drivers to avoid races */
+	cx->alsa = cxsc;
+
+	/* (6) Register the card instance */
+	ret = snd_card_register(sc);
+	if (ret) {
+		cx->alsa = NULL;
+		CX18_ALSA_ERR("%s: snd_card_register() failed with err %d\n",
+			      __func__, ret);
+		goto err_exit_free;
+	}
+
+	return 0;
+
+err_exit_free:
+	if (sc != NULL)
+		snd_card_free(sc);
+err_exit:
+	return ret;
+}
+
+int cx18_alsa_load(struct cx18 *cx)
+{
+	struct v4l2_device *v4l2_dev = &cx->v4l2_dev;
+	struct cx18_stream *s;
+
+	if (v4l2_dev == NULL) {
+		printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
+		       __func__);
+		return 0;
+	}
+
+	cx = to_cx18(v4l2_dev);
+	if (cx == NULL) {
+		printk(KERN_ERR "cx18-alsa cx is NULL\n");
+		return 0;
+	}
+
+	s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
+	if (s->video_dev == NULL) {
+		CX18_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - "
+				     "skipping\n", __func__);
+		return 0;
+	}
+
+	if (cx->alsa != NULL) {
+		CX18_ALSA_ERR("%s: struct snd_cx18_card * already exists\n",
+			      __func__);
+		return 0;
+	}
+
+	if (snd_cx18_init(v4l2_dev)) {
+		CX18_ALSA_ERR("%s: failed to create struct snd_cx18_card\n",
+			      __func__);
+	} else {
+		CX18_DEBUG_ALSA_INFO("%s: created cx18 ALSA interface instance "
+				     "\n", __func__);
+	}
+	return 0;
+}
+
+static int __init cx18_alsa_init(void)
+{
+	printk(KERN_INFO "cx18-alsa: module loading...\n");
+	cx18_ext_init = &cx18_alsa_load;
+	return 0;
+}
+
+static void __exit snd_cx18_exit(struct snd_cx18_card *cxsc)
+{
+	struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
+
+	/* FIXME - pointer checks & shutdown cxsc */
+
+	snd_card_free(cxsc->sc);
+	cx->alsa = NULL;
+}
+
+static int __exit cx18_alsa_exit_callback(struct device *dev, void *data)
+{
+	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
+	struct snd_cx18_card *cxsc;
+
+	if (v4l2_dev == NULL) {
+		printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
+		       __func__);
+		return 0;
+	}
+
+	cxsc = to_snd_cx18_card(v4l2_dev);
+	if (cxsc == NULL) {
+		CX18_ALSA_WARN("%s: struct snd_cx18_card * is NULL\n",
+			       __func__);
+		return 0;
+	}
+
+	snd_cx18_exit(cxsc);
+	return 0;
+}
+
+static void __exit cx18_alsa_exit(void)
+{
+	struct device_driver *drv;
+	int ret;
+
+	printk(KERN_INFO "cx18-alsa: module unloading...\n");
+
+	drv = driver_find("cx18", &pci_bus_type);
+	ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback);
+	put_driver(drv);
+
+	cx18_ext_init = NULL;
+	printk(KERN_INFO "cx18-alsa: module unload complete\n");
+}
+
+module_init(cx18_alsa_init);
+module_exit(cx18_alsa_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-alsa-mixer.c linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-alsa-mixer.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-alsa-mixer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-alsa-mixer.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,175 @@
+/*
+ *  ALSA mixer controls for the
+ *  ALSA interface to cx18 PCM capture streams
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ *  02111-1307  USA
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-device.h>
+
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/tlv.h>
+
+#include "cx18-alsa.h"
+#include "cx18-driver.h"
+
+/*
+ * Note the cx18-av-core volume scale is funny, due to the alignment of the
+ * scale with another chip's range:
+ *
+ * v4l2_control value	/512	indicated dB	actual dB	reg 0x8d4
+ * 0x0000 - 0x01ff	  0	-119		-96		228
+ * 0x0200 - 0x02ff	  1	-118		-96		228
+ * ...
+ * 0x2c00 - 0x2dff	 22	 -97		-96		228
+ * 0x2e00 - 0x2fff	 23	 -96		-96		228
+ * 0x3000 - 0x31ff	 24	 -95		-95		226
+ * ...
+ * 0xee00 - 0xefff	119	   0		  0		 36
+ * ...
+ * 0xfe00 - 0xffff	127	  +8		 +8		 20
+ */
+static inline int dB_to_cx18_av_vol(int dB)
+{
+	if (dB < -96)
+		dB = -96;
+	else if (dB > 8)
+		dB = 8;
+	return (dB + 119) << 9;
+}
+
+static inline int cx18_av_vol_to_dB(int v)
+{
+	if (v < (23 << 9))
+		v = (23 << 9);
+	else if (v > (127 << 9))
+		v = (127 << 9);
+	return (v >> 9) - 119;
+}
+
+static int snd_cx18_mixer_tv_vol_info(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	/* We're already translating values, just keep this control in dB */
+	uinfo->value.integer.min  = -96;
+	uinfo->value.integer.max  =   8;
+	uinfo->value.integer.step =   1;
+	return 0;
+}
+
+static int snd_cx18_mixer_tv_vol_get(struct snd_kcontrol *kctl,
+				     struct snd_ctl_elem_value *uctl)
+{
+	struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl);
+	struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
+	struct v4l2_control vctrl;
+	int ret;
+
+	vctrl.id = V4L2_CID_AUDIO_VOLUME;
+	vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
+
+	snd_cx18_lock(cxsc);
+	ret = v4l2_subdev_call(cx->sd_av, core, g_ctrl, &vctrl);
+	snd_cx18_unlock(cxsc);
+
+	if (!ret)
+		uctl->value.integer.value[0] = cx18_av_vol_to_dB(vctrl.value);
+	return ret;
+}
+
+static int snd_cx18_mixer_tv_vol_put(struct snd_kcontrol *kctl,
+				     struct snd_ctl_elem_value *uctl)
+{
+	struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl);
+	struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
+	struct v4l2_control vctrl;
+	int ret;
+
+	vctrl.id = V4L2_CID_AUDIO_VOLUME;
+	vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
+
+	snd_cx18_lock(cxsc);
+
+	/* Fetch current state */
+	ret = v4l2_subdev_call(cx->sd_av, core, g_ctrl, &vctrl);
+
+	if (ret ||
+	    (cx18_av_vol_to_dB(vctrl.value) != uctl->value.integer.value[0])) {
+
+		/* Set, if needed */
+		vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
+		ret = v4l2_subdev_call(cx->sd_av, core, s_ctrl, &vctrl);
+		if (!ret)
+			ret = 1; /* Indicate control was changed w/o error */
+	}
+	snd_cx18_unlock(cxsc);
+
+	return ret;
+}
+
+
+/* This is a bit of overkill, the slider is already in dB internally */
+static DECLARE_TLV_DB_SCALE(snd_cx18_mixer_tv_vol_db_scale, -9600, 100, 0);
+
+static struct snd_kcontrol_new snd_cx18_mixer_tv_vol __initdata = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Analog TV Capture Volume",
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+		  SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+	.info = snd_cx18_mixer_tv_volume_info,
+	.get = snd_cx18_mixer_tv_volume_get,
+	.put = snd_cx18_mixer_tv_volume_put,
+	.tlv.p = snd_cx18_mixer_tv_vol_db_scale
+};
+
+/* FIXME - add mute switch and balance, bass, treble sliders:
+	V4L2_CID_AUDIO_MUTE
+
+	V4L2_CID_AUDIO_BALANCE
+
+	V4L2_CID_AUDIO_BASS
+	V4L2_CID_AUDIO_TREBLE
+*/
+
+/* FIXME - add stereo, lang1, lang2, mono menu */
+/* FIXME - add CS5345 I2S volume for HVR-1600 */
+
+int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc)
+{
+	struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
+	struct snd_card *sc = cxsc->sc;
+	int ret;
+
+	strlcpy(sc->mixername, "CX23418 Mixer", sizeof(sc->mixername));
+
+	ret = snd_ctl_add(sc, snd_ctl_new1(snd_cx18_mixer_tv_vol, cxsc));
+	if (ret) {
+		CX18_ALSA_WARN("%s: failed to add %s control, err %d\n",
+				__func__, snd_cx18_mixer_tv_vol.name, ret);
+	}
+	return ret;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-alsa-mixer.h linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-alsa-mixer.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-alsa-mixer.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-alsa-mixer.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,23 @@
+/*
+ *  ALSA mixer controls for the
+ *  ALSA interface to cx18 PCM capture streams
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ *  02111-1307  USA
+ */
+
+int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-alsa-pcm.c linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-alsa-pcm.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-alsa-pcm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-alsa-pcm.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,354 @@
+/*
+ *  ALSA PCM device for the
+ *  ALSA interface to cx18 PCM capture streams
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.net>
+ *  Copyright (C) 2009  Devin Heitmueller <dheitmueller@kernellabs.com>
+ *
+ *  Portions of this work were sponsored by ONELAN Limited.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ *  02111-1307  USA
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+
+#include <media/v4l2-device.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+
+#include "cx18-driver.h"
+#include "cx18-queue.h"
+#include "cx18-streams.h"
+#include "cx18-fileops.h"
+#include "cx18-alsa.h"
+
+static unsigned int pcm_debug;
+module_param(pcm_debug, int, 0644);
+MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm");
+
+#define dprintk(fmt, arg...) do {					\
+	    if (pcm_debug)						\
+		printk(KERN_INFO "cx18-alsa-pcm %s: " fmt,		\
+				  __func__, ##arg); 			\
+	} while (0)
+
+static struct snd_pcm_hardware snd_cx18_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_48000,
+
+	.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, */
+};
+
+void cx18_alsa_announce_pcm_data(struct snd_cx18_card *cxsc, u8 *pcm_data,
+				 size_t num_bytes)
+{
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
+	unsigned int oldptr;
+	unsigned int stride;
+	int period_elapsed = 0;
+	int length;
+
+	dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%zd\n", cxsc,
+		pcm_data, num_bytes);
+
+	substream = cxsc->capture_pcm_substream;
+	if (substream == NULL) {
+		dprintk("substream was NULL\n");
+		return;
+	}
+
+	runtime = substream->runtime;
+	if (runtime == NULL) {
+		dprintk("runtime was NULL\n");
+		return;
+	}
+
+	stride = runtime->frame_bits >> 3;
+	if (stride == 0) {
+		dprintk("stride is zero\n");
+		return;
+	}
+
+	length = num_bytes / stride;
+	if (length == 0) {
+		dprintk("%s: length was zero\n", __func__);
+		return;
+	}
+
+	if (runtime->dma_area == NULL) {
+		dprintk("dma area was NULL - ignoring\n");
+		return;
+	}
+
+	oldptr = cxsc->hwptr_done_capture;
+	if (oldptr + length >= runtime->buffer_size) {
+		unsigned int cnt =
+			runtime->buffer_size - oldptr;
+		memcpy(runtime->dma_area + oldptr * stride, pcm_data,
+		       cnt * stride);
+		memcpy(runtime->dma_area, pcm_data + cnt * stride,
+		       length * stride - cnt * stride);
+	} else {
+		memcpy(runtime->dma_area + oldptr * stride, pcm_data,
+		       length * stride);
+	}
+	snd_pcm_stream_lock(substream);
+
+	cxsc->hwptr_done_capture += length;
+	if (cxsc->hwptr_done_capture >=
+	    runtime->buffer_size)
+		cxsc->hwptr_done_capture -=
+			runtime->buffer_size;
+
+	cxsc->capture_transfer_done += length;
+	if (cxsc->capture_transfer_done >=
+	    runtime->period_size) {
+		cxsc->capture_transfer_done -=
+			runtime->period_size;
+		period_elapsed = 1;
+	}
+
+	snd_pcm_stream_unlock(substream);
+
+	if (period_elapsed)
+		snd_pcm_period_elapsed(substream);
+}
+
+static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream)
+{
+	struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
+	struct cx18 *cx = to_cx18(v4l2_dev);
+	struct cx18_stream *s;
+	struct cx18_open_id item;
+	int ret;
+
+	/* Instruct the cx18 to start sending packets */
+	snd_cx18_lock(cxsc);
+	s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
+
+	item.cx = cx;
+	item.type = s->type;
+	item.open_id = cx->open_id++;
+
+	/* See if the stream is available */
+	if (cx18_claim_stream(&item, item.type)) {
+		/* No, it's already in use */
+		snd_cx18_unlock(cxsc);
+		return -EBUSY;
+	}
+
+	if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
+	    test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
+		/* We're already streaming.  No additional action required */
+		snd_cx18_unlock(cxsc);
+		return 0;
+	}
+
+
+	runtime->hw = snd_cx18_hw_capture;
+	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+	cxsc->capture_pcm_substream = substream;
+	runtime->private_data = cx;
+
+	cx->pcm_announce_callback = cx18_alsa_announce_pcm_data;
+
+	/* Not currently streaming, so start it up */
+	set_bit(CX18_F_S_STREAMING, &s->s_flags);
+	ret = cx18_start_v4l2_encode_stream(s);
+	snd_cx18_unlock(cxsc);
+
+	return 0;
+}
+
+static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
+{
+	struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
+	struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
+	struct cx18 *cx = to_cx18(v4l2_dev);
+	struct cx18_stream *s;
+	int ret;
+
+	/* Instruct the cx18 to stop sending packets */
+	snd_cx18_lock(cxsc);
+	s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
+	ret = cx18_stop_v4l2_encode_stream(s, 0);
+	clear_bit(CX18_F_S_STREAMING, &s->s_flags);
+
+	cx18_release_stream(s);
+
+	cx->pcm_announce_callback = NULL;
+	snd_cx18_unlock(cxsc);
+
+	return 0;
+}
+
+static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream,
+		     unsigned int cmd, void *arg)
+{
+	return snd_pcm_lib_ioctl(substream, cmd, arg);
+}
+
+
+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 int snd_cx18_pcm_hw_params(struct snd_pcm_substream *substream,
+			 struct snd_pcm_hw_params *params)
+{
+	int ret;
+
+	dprintk("%s called\n", __func__);
+
+	ret = snd_pcm_alloc_vmalloc_buffer(substream,
+					   params_buffer_bytes(params));
+	return 0;
+}
+
+static int snd_cx18_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+	struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
+	unsigned long flags;
+
+	spin_lock_irqsave(&cxsc->slock, flags);
+	if (substream->runtime->dma_area) {
+		dprintk("freeing pcm capture region\n");
+		vfree(substream->runtime->dma_area);
+		substream->runtime->dma_area = NULL;
+	}
+	spin_unlock_irqrestore(&cxsc->slock, flags);
+
+	return 0;
+}
+
+static int snd_cx18_pcm_prepare(struct snd_pcm_substream *substream)
+{
+	struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
+
+	cxsc->hwptr_done_capture = 0;
+	cxsc->capture_transfer_done = 0;
+
+	return 0;
+}
+
+static int snd_cx18_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	return 0;
+}
+
+static
+snd_pcm_uframes_t snd_cx18_pcm_pointer(struct snd_pcm_substream *substream)
+{
+	unsigned long flags;
+	snd_pcm_uframes_t hwptr_done;
+	struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
+
+	spin_lock_irqsave(&cxsc->slock, flags);
+	hwptr_done = cxsc->hwptr_done_capture;
+	spin_unlock_irqrestore(&cxsc->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_cx18_pcm_capture_ops = {
+	.open		= snd_cx18_pcm_capture_open,
+	.close		= snd_cx18_pcm_capture_close,
+	.ioctl		= snd_cx18_pcm_ioctl,
+	.hw_params	= snd_cx18_pcm_hw_params,
+	.hw_free	= snd_cx18_pcm_hw_free,
+	.prepare	= snd_cx18_pcm_prepare,
+	.trigger	= snd_cx18_pcm_trigger,
+	.pointer	= snd_cx18_pcm_pointer,
+	.page		= snd_pcm_get_vmalloc_page,
+};
+
+int snd_cx18_pcm_create(struct snd_cx18_card *cxsc)
+{
+	struct snd_pcm *sp;
+	struct snd_card *sc = cxsc->sc;
+	struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
+	struct cx18 *cx = to_cx18(v4l2_dev);
+	int ret;
+
+	ret = snd_pcm_new(sc, "CX23418 PCM",
+			  0, /* PCM device 0, the only one for this card */
+			  0, /* 0 playback substreams */
+			  1, /* 1 capture substream */
+			  &sp);
+	if (ret) {
+		CX18_ALSA_ERR("%s: snd_cx18_pcm_create() failed with err %d\n",
+			      __func__, ret);
+		goto err_exit;
+	}
+
+	spin_lock_init(&cxsc->slock);
+
+	snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
+			&snd_cx18_pcm_capture_ops);
+	sp->info_flags = 0;
+	sp->private_data = cxsc;
+	strlcpy(sp->name, cx->card_name, sizeof(sp->name));
+
+	return 0;
+
+err_exit:
+	return ret;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-alsa-pcm.h linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-alsa-pcm.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-alsa-pcm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-alsa-pcm.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,27 @@
+/*
+ *  ALSA PCM device for the
+ *  ALSA interface to cx18 PCM capture streams
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ *  02111-1307  USA
+ */
+
+int __init snd_cx18_pcm_create(struct snd_cx18_card *cxsc);
+
+/* Used by cx18-mailbox to announce the PCM data to the module */
+void cx18_alsa_announce_pcm_data(struct snd_cx18_card *card, u8 *pcm_data,
+				 size_t num_bytes);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-cards.c linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-cards.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-cards.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-cards.c	2010-05-16 17:17:36.000000000 -0400
@@ -393,7 +393,7 @@ static const struct cx18_card cx18_card_
 	.gpio_init.direction = 0x7,
 	.gpio_audio_input = { .mask   = 0x7,
 			      .tuner  = 0x6, .linein = 0x2, .radio  = 0x2 },
-	.xceive_pin = 15,
+	.xceive_pin = 1,
 	.pci_list = cx18_pci_leadtek_pvr2100,
 	.i2c = &cx18_i2c_std,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-controls.c linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-controls.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-controls.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-controls.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
  *  02111-1307  USA
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "cx18-driver.h"
 #include "cx18-cards.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-driver.c linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-driver.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-driver.c	2013-05-03 12:03:49.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-driver.c	2013-05-03 09:44:44.000000000 -0400
@@ -47,6 +47,10 @@
    setting this to 1 you ensure that radio0 is now also radio1. */
 int cx18_first_minor;
 
+/* Callback for registering extensions */
+int (*cx18_ext_init)(struct cx18 *);
+EXPORT_SYMBOL(cx18_ext_init);
+
 /* add your revision and whatnot here */
 static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
 	{PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
@@ -91,7 +95,7 @@ static int enc_pcm_bufsize = CX18_DEFAUL
 
 static int enc_ts_bufs = -1;
 static int enc_mpg_bufs = -1;
-static int enc_idx_bufs = -1;
+static int enc_idx_bufs = CX18_MAX_FW_MDLS_PER_STREAM;
 static int enc_yuv_bufs = -1;
 static int enc_vbi_bufs = -1;
 static int enc_pcm_bufs = -1;
@@ -196,14 +200,17 @@ MODULE_PARM_DESC(enc_mpg_bufs,
 		 "Number of encoder MPG buffers\n"
 		 "\t\t\tDefault is computed from other enc_mpg_* parameters");
 MODULE_PARM_DESC(enc_idx_buffers,
-		 "Encoder IDX buffer memory (MB). (enc_idx_bufs can override)\n"
-		 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFFERS));
+		 "(Deprecated) Encoder IDX buffer memory (MB)\n"
+		 "\t\t\tIgnored, except 0 disables IDX buffer allocations\n"
+		 "\t\t\tDefault: 1 [Enabled]");
 MODULE_PARM_DESC(enc_idx_bufsize,
 		 "Size of an encoder IDX buffer (kB)\n"
-		 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFSIZE));
+		 "\t\t\tAllowed values are multiples of 1.5 kB rounded up\n"
+		 "\t\t\t(multiples of size required for 64 index entries)\n"
+		 "\t\t\tDefault: 2");
 MODULE_PARM_DESC(enc_idx_bufs,
 		 "Number of encoder IDX buffers\n"
-		 "\t\t\tDefault is computed from other enc_idx_* parameters");
+		 "\t\t\tDefault: " __stringify(CX18_MAX_FW_MDLS_PER_STREAM));
 MODULE_PARM_DESC(enc_yuv_buffers,
 		 "Encoder YUV buffer memory (MB). (enc_yuv_bufs can override)\n"
 		 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
@@ -231,7 +238,8 @@ MODULE_PARM_DESC(enc_pcm_bufs,
 		 "Number of encoder PCM buffers\n"
 		 "\t\t\tDefault is computed from other enc_pcm_* parameters");
 
-MODULE_PARM_DESC(cx18_first_minor, "Set device node number assigned to first card");
+MODULE_PARM_DESC(cx18_first_minor,
+		 "Set device node number assigned to first card");
 
 MODULE_AUTHOR("Hans Verkuil");
 MODULE_DESCRIPTION("CX23418 driver");
@@ -240,6 +248,28 @@ MODULE_LICENSE("GPL");
 
 MODULE_VERSION(CX18_VERSION);
 
+#if defined(CONFIG_MODULES) && defined(MODULE)
+static void request_module_async(struct work_struct *work)
+{
+	struct cx18 *dev = container_of(work, struct cx18, request_module_wk);
+
+	/* Make sure cx18-alsa module is loaded */
+	request_module("cx18-alsa");
+
+	/* Initialize cx18-alsa for this instance of the cx18 device */
+	if (cx18_ext_init != NULL)
+		cx18_ext_init(dev);
+}
+
+static void request_modules(struct cx18 *dev)
+{
+	INIT_WORK(&dev->request_module_wk, request_module_async);
+	schedule_work(&dev->request_module_wk);
+}
+#else
+#define request_modules(dev)
+#endif /* CONFIG_MODULES */
+
 /* Generic utility functions */
 int cx18_msleep_timeout(unsigned int msecs, int intr)
 {
@@ -501,7 +531,12 @@ static void cx18_process_options(struct
 		/*
 		 * YUV is a special case where the stream_buf_size needs to be
 		 * an integral multiple of 33.75 kB (storage for 32 screens
-		 * lines to maintain alignment in case of lost buffers
+		 * lines to maintain alignment in case of lost buffers).
+		 *
+		 * IDX is a special case where the stream_buf_size should be
+		 * an integral multiple of 1.5 kB (storage for 64 index entries
+		 * to maintain alignment in case of lost buffers).
+		 *
 		 */
 		if (i == CX18_ENC_STREAM_TYPE_YUV) {
 			cx->stream_buf_size[i] *= 1024;
@@ -511,15 +546,24 @@ static void cx18_process_options(struct
 			if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE)
 				cx->stream_buf_size[i] =
 						CX18_UNIT_ENC_YUV_BUFSIZE;
+		} else if (i == CX18_ENC_STREAM_TYPE_IDX) {
+			cx->stream_buf_size[i] *= 1024;
+			cx->stream_buf_size[i] -=
+			   (cx->stream_buf_size[i] % CX18_UNIT_ENC_IDX_BUFSIZE);
+
+			if (cx->stream_buf_size[i] < CX18_UNIT_ENC_IDX_BUFSIZE)
+				cx->stream_buf_size[i] =
+						CX18_UNIT_ENC_IDX_BUFSIZE;
 		}
 		/*
-		 * YUV is a special case where the stream_buf_size is
+		 * YUV and IDX are special cases where the stream_buf_size is
 		 * now in bytes.
 		 * VBI is a special case where the stream_buf_size is fixed
 		 * and already in bytes
 		 */
 		if (i == CX18_ENC_STREAM_TYPE_VBI ||
-		    i == CX18_ENC_STREAM_TYPE_YUV) {
+		    i == CX18_ENC_STREAM_TYPE_YUV ||
+		    i == CX18_ENC_STREAM_TYPE_IDX) {
 			if (cx->stream_buffers[i] < 0) {
 				cx->stream_buffers[i] =
 					cx->options.megabytes[i] * 1024 * 1024
@@ -1032,6 +1076,10 @@ static int __devinit cx18_probe(struct p
 	}
 
 	CX18_INFO("Initialized card: %s\n", cx->card_name);
+
+	/* Load cx18 submodules (cx18-alsa) */
+	request_modules(cx);
+
 	return 0;
 
 free_streams:
@@ -1220,6 +1268,7 @@ static void cx18_remove(struct pci_dev *
 	kfree(cx);
 }
 
+
 /* define a pci_driver for card detection */
 static struct pci_driver cx18_pci_driver = {
       .name =     "cx18",
@@ -1230,7 +1279,8 @@ static struct pci_driver cx18_pci_driver
 
 static int __init module_start(void)
 {
-	printk(KERN_INFO "cx18:  Start initialization, version %s\n", CX18_VERSION);
+	printk(KERN_INFO "cx18:  Start initialization, version %s\n",
+	       CX18_VERSION);
 
 	/* Validate parameters */
 	if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-driver.h linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-driver.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-driver.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-driver.h	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/pagemap.h>
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 
 #include <linux/dvb/video.h>
@@ -126,10 +127,22 @@
 #define CX18_625_LINE_ENC_YUV_BUFSIZE	(CX18_UNIT_ENC_YUV_BUFSIZE * 576/32)
 #define CX18_525_LINE_ENC_YUV_BUFSIZE	(CX18_UNIT_ENC_YUV_BUFSIZE * 480/32)
 
+/* IDX buffer size should be a multiple of the index entry size from the chip */
+struct cx18_enc_idx_entry {
+	__le32 length;
+	__le32 offset_low;
+	__le32 offset_high;
+	__le32 flags;
+	__le32 pts_low;
+	__le32 pts_high;
+} __attribute__ ((packed));
+#define CX18_UNIT_ENC_IDX_BUFSIZE \
+	(sizeof(struct cx18_enc_idx_entry) * V4L2_ENC_IDX_ENTRIES)
+
 /* DMA buffer, default size in kB allocated */
 #define CX18_DEFAULT_ENC_TS_BUFSIZE   32
 #define CX18_DEFAULT_ENC_MPG_BUFSIZE  32
-#define CX18_DEFAULT_ENC_IDX_BUFSIZE  32
+#define CX18_DEFAULT_ENC_IDX_BUFSIZE  (CX18_UNIT_ENC_IDX_BUFSIZE * 1 / 1024 + 1)
 #define CX18_DEFAULT_ENC_YUV_BUFSIZE  (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1)
 #define CX18_DEFAULT_ENC_PCM_BUFSIZE   4
 
@@ -234,16 +247,8 @@
 #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
-#define MPEG_FRAME_TYPE_IFRAME_PFRAME 3
-#define MPEG_FRAME_TYPE_ALL 7
-
-#define CX18_MAX_PGM_INDEX (400)
-
 extern int cx18_debug;
 
-
 struct cx18_options {
 	int megabytes[CX18_MAX_STREAMS]; /* Size in megabytes of each stream */
 	int cardtype;		/* force card type on load */
@@ -276,6 +281,18 @@ struct cx18_options {
 #define CX18_SLICED_TYPE_WSS_625        (5)
 #define CX18_SLICED_TYPE_VPS            (7)
 
+/**
+ * list_entry_is_past_end - check if a previous loop cursor is off list end
+ * @pos:	the type * previously used as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Check if the entry's list_head is the head of the list, thus it's not a
+ * real entry but was the loop cursor that walked past the end
+ */
+#define list_entry_is_past_end(pos, head, member) \
+	(&pos->member == (head))
+
 struct cx18_buffer {
 	struct list_head list;
 	dma_addr_t dma_handle;
@@ -558,6 +575,10 @@ struct cx18 {
 	int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */
 	int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
 	struct cx18_stream streams[CX18_MAX_STREAMS]; 	/* Stream data */
+	struct snd_cx18_card *alsa; /* ALSA interface for PCM capture stream */
+	void (*pcm_announce_callback)(struct snd_cx18_card *card, u8 *pcm_data,
+				      size_t num_bytes);
+
 	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 */
@@ -575,12 +596,6 @@ struct cx18 {
 
 	struct vbi_info vbi;
 
-	u32 pgm_info_offset;
-	u32 pgm_info_num;
-	u32 pgm_info_write_idx;
-	u32 pgm_info_read_idx;
-	struct v4l2_enc_idx_entry pgm_info[CX18_MAX_PGM_INDEX];
-
 	u64 mpg_data_received;
 	u64 vbi_data_inserted;
 
@@ -623,6 +638,9 @@ struct cx18 {
 	u32 active_input;
 	v4l2_std_id std;
 	v4l2_std_id tuner_std;	/* The norm of the tuner (fixed) */
+
+	/* Used for cx18-alsa module loading */
+	struct work_struct request_module_wk;
 };
 
 static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev)
@@ -630,6 +648,9 @@ static inline struct cx18 *to_cx18(struc
 	return container_of(v4l2_dev, struct cx18, v4l2_dev);
 }
 
+/* cx18 extensions to be loaded */
+extern int (*cx18_ext_init)(struct cx18 *);
+
 /* Globals */
 extern int cx18_first_minor;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-dvb.c linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-dvb.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-dvb.c	2013-05-03 12:06:58.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-dvb.c	2013-05-03 09:46:21.000000000 -0400
@@ -213,10 +213,14 @@ static int cx18_dvb_start_feed(struct dv
 {
 	struct dvb_demux *demux = feed->demux;
 	struct cx18_stream *stream = (struct cx18_stream *) demux->priv;
-	struct cx18 *cx = stream->cx;
+	struct cx18 *cx;
 	int ret;
 	u32 v;
 
+	if (!stream)
+		return -EINVAL;
+
+	cx = stream->cx;
 	CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n",
 			feed->pid, feed->index);
 
@@ -253,12 +257,10 @@ static int cx18_dvb_start_feed(struct dv
 	if (!demux->dmx.frontend)
 		return -EINVAL;
 
-	if (!stream)
-		return -EINVAL;
-
 	mutex_lock(&stream->dvb.feedlock);
 	if (stream->dvb.feeding++ == 0) {
 		CX18_DEBUG_INFO("Starting Transport DMA\n");
+		mutex_lock(&cx->serialize_lock);
 		set_bit(CX18_F_S_STREAMING, &stream->s_flags);
 		ret = cx18_start_v4l2_encode_stream(stream);
 		if (ret < 0) {
@@ -267,6 +269,7 @@ static int cx18_dvb_start_feed(struct dv
 			if (stream->dvb.feeding == 0)
 				clear_bit(CX18_F_S_STREAMING, &stream->s_flags);
 		}
+		mutex_unlock(&cx->serialize_lock);
 	} else
 		ret = 0;
 	mutex_unlock(&stream->dvb.feedlock);
@@ -279,17 +282,20 @@ static int cx18_dvb_stop_feed(struct dvb
 {
 	struct dvb_demux *demux = feed->demux;
 	struct cx18_stream *stream = (struct cx18_stream *)demux->priv;
-	struct cx18 *cx = stream->cx;
+	struct cx18 *cx;
 	int ret = -EINVAL;
 
-	CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
-			feed->pid, feed->index);
-
 	if (stream) {
+		cx = stream->cx;
+		CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
+				feed->pid, feed->index);
+
 		mutex_lock(&stream->dvb.feedlock);
 		if (--stream->dvb.feeding == 0) {
 			CX18_DEBUG_INFO("Stopping Transport DMA\n");
+			mutex_lock(&cx->serialize_lock);
 			ret = cx18_stop_v4l2_encode_stream(stream, 0);
+			mutex_unlock(&cx->serialize_lock);
 		} else
 			ret = 0;
 		mutex_unlock(&stream->dvb.feedlock);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-fileops.c linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-fileops.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-fileops.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-fileops.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,15 +37,21 @@
 
 /* This function tries to claim the stream for a specific file descriptor.
    If no one else is using this stream then the stream is claimed and
-   associated VBI streams are also automatically claimed.
+   associated VBI and IDX streams are also automatically claimed.
    Possible error returns: -EBUSY if someone else has claimed
    the stream or 0 on success. */
-static int cx18_claim_stream(struct cx18_open_id *id, int type)
+int cx18_claim_stream(struct cx18_open_id *id, int type)
 {
 	struct cx18 *cx = id->cx;
 	struct cx18_stream *s = &cx->streams[type];
-	struct cx18_stream *s_vbi;
-	int vbi_type;
+	struct cx18_stream *s_assoc;
+
+	/* Nothing should ever try to directly claim the IDX stream */
+	if (type == CX18_ENC_STREAM_TYPE_IDX) {
+		CX18_WARN("MPEG Index stream cannot be claimed "
+			  "directly, but something tried.\n");
+		return -EINVAL;
+	}
 
 	if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
 		/* someone already claimed this stream */
@@ -67,32 +73,47 @@ static int cx18_claim_stream(struct cx18
 	}
 	s->id = id->open_id;
 
-	/* CX18_ENC_STREAM_TYPE_MPG needs to claim CX18_ENC_STREAM_TYPE_VBI
-	   (provided VBI insertion is on and sliced VBI is selected), for all
-	   other streams we're done */
-	if (type == CX18_ENC_STREAM_TYPE_MPG &&
-	    cx->vbi.insert_mpeg && !cx18_raw_vbi(cx)) {
-		vbi_type = CX18_ENC_STREAM_TYPE_VBI;
-	} else {
+	/*
+	 * CX18_ENC_STREAM_TYPE_MPG needs to claim:
+	 * CX18_ENC_STREAM_TYPE_VBI, if VBI insertion is on for sliced VBI, or
+	 * CX18_ENC_STREAM_TYPE_IDX, if VBI insertion is off for sliced VBI
+	 * (We don't yet fix up MPEG Index entries for our inserted packets).
+	 *
+	 * For all other streams we're done.
+	 */
+	if (type != CX18_ENC_STREAM_TYPE_MPG)
 		return 0;
-	}
-	s_vbi = &cx->streams[vbi_type];
 
-	set_bit(CX18_F_S_CLAIMED, &s_vbi->s_flags);
+	s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
+	if (cx->vbi.insert_mpeg && !cx18_raw_vbi(cx))
+		s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
+	else if (!cx18_stream_enabled(s_assoc))
+		return 0;
+
+	set_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
 
 	/* mark that it is used internally */
-	set_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags);
+	set_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags);
 	return 0;
 }
+EXPORT_SYMBOL(cx18_claim_stream);
 
 /* This function releases a previously claimed stream. It will take into
    account associated VBI streams. */
-static void cx18_release_stream(struct cx18_stream *s)
+void cx18_release_stream(struct cx18_stream *s)
 {
 	struct cx18 *cx = s->cx;
-	struct cx18_stream *s_vbi;
+	struct cx18_stream *s_assoc;
 
 	s->id = -1;
+	if (s->type == CX18_ENC_STREAM_TYPE_IDX) {
+		/*
+		 * The IDX stream is only used internally, and can
+		 * only be indirectly unclaimed by unclaiming the MPG stream.
+		 */
+		return;
+	}
+
 	if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
 		test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) {
 		/* this stream is still in use internally */
@@ -105,25 +126,36 @@ static void cx18_release_stream(struct c
 
 	cx18_flush_queues(s);
 
-	/* CX18_ENC_STREAM_TYPE_MPG needs to release CX18_ENC_STREAM_TYPE_VBI,
-	   for all other streams we're done */
-	if (s->type == CX18_ENC_STREAM_TYPE_MPG)
-		s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
-	else
+	/*
+	 * CX18_ENC_STREAM_TYPE_MPG needs to release the
+	 * CX18_ENC_STREAM_TYPE_VBI and/or CX18_ENC_STREAM_TYPE_IDX streams.
+	 *
+	 * For all other streams we're done.
+	 */
+	if (s->type != CX18_ENC_STREAM_TYPE_MPG)
 		return;
 
-	/* clear internal use flag */
-	if (!test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags)) {
-		/* was already cleared */
-		return;
+	/* Unclaim the associated MPEG Index stream */
+	s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
+	if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
+		clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
+		cx18_flush_queues(s_assoc);
 	}
-	if (s_vbi->id != -1) {
-		/* VBI stream still claimed by a file descriptor */
-		return;
+
+	/* Unclaim the associated VBI stream */
+	s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
+	if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
+		if (s_assoc->id == -1) {
+			/*
+			 * The VBI stream is not still claimed by a file
+			 * descriptor, so completely unclaim it.
+			 */
+			clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
+			cx18_flush_queues(s_assoc);
+		}
 	}
-	clear_bit(CX18_F_S_CLAIMED, &s_vbi->s_flags);
-	cx18_flush_queues(s_vbi);
 }
+EXPORT_SYMBOL(cx18_release_stream);
 
 static void cx18_dualwatch(struct cx18 *cx)
 {
@@ -177,9 +209,7 @@ static struct cx18_mdl *cx18_get_mdl(str
 	*err = 0;
 	while (1) {
 		if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
-			/* Process pending program info updates and pending
-			   VBI data */
-
+			/* Process pending program updates and VBI data */
 			if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
 				cx->dualwatch_jiffies = jiffies;
 				cx18_dualwatch(cx);
@@ -362,18 +392,6 @@ static size_t cx18_copy_buf_to_user(stru
 	return len;
 }
 
-/**
- * list_entry_is_past_end - check if a previous loop cursor is off list end
- * @pos:	the type * previously used as a loop cursor.
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- *
- * Check if the entry's list_head is the head of the list, thus it's not a
- * real entry but was the loop cursor that walked past the end
- */
-#define list_entry_is_past_end(pos, head, member) \
-	(&pos->member == (head))
-
 static size_t cx18_copy_mdl_to_user(struct cx18_stream *s,
 		struct cx18_mdl *mdl, char __user *ubuf, size_t ucount)
 {
@@ -498,6 +516,7 @@ int cx18_start_capture(struct cx18_open_
 	struct cx18 *cx = id->cx;
 	struct cx18_stream *s = &cx->streams[id->type];
 	struct cx18_stream *s_vbi;
+	struct cx18_stream *s_idx;
 
 	if (s->type == CX18_ENC_STREAM_TYPE_RAD) {
 		/* you cannot read from these stream types. */
@@ -516,25 +535,33 @@ int cx18_start_capture(struct cx18_open_
 		return 0;
 	}
 
-	/* Start VBI capture if required */
+	/* Start associated VBI or IDX stream capture if required */
 	s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
-	if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
-	    test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
-	    !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
-		/* Note: the CX18_ENC_STREAM_TYPE_VBI is claimed
-		   automatically when the MPG stream is claimed.
-		   We only need to start the VBI capturing. */
-		if (cx18_start_v4l2_encode_stream(s_vbi)) {
-			CX18_DEBUG_WARN("VBI capture start failed\n");
-
-			/* Failure, clean up and return an error */
-			clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
-			clear_bit(CX18_F_S_STREAMING, &s->s_flags);
-			/* also releases the associated VBI stream */
-			cx18_release_stream(s);
-			return -EIO;
+	s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
+	if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
+		/*
+		 * The VBI and IDX streams should have been claimed
+		 * automatically, if for internal use, when the MPG stream was
+		 * claimed.  We only need to start these streams capturing.
+		 */
+		if (test_bit(CX18_F_S_INTERNAL_USE, &s_idx->s_flags) &&
+		    !test_and_set_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
+			if (cx18_start_v4l2_encode_stream(s_idx)) {
+				CX18_DEBUG_WARN("IDX capture start failed\n");
+				clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
+				goto start_failed;
+			}
+			CX18_DEBUG_INFO("IDX capture started\n");
+		}
+		if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
+		    !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
+			if (cx18_start_v4l2_encode_stream(s_vbi)) {
+				CX18_DEBUG_WARN("VBI capture start failed\n");
+				clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
+				goto start_failed;
+			}
+			CX18_DEBUG_INFO("VBI insertion started\n");
 		}
-		CX18_DEBUG_INFO("VBI insertion started\n");
 	}
 
 	/* Tell the card to start capturing */
@@ -547,19 +574,29 @@ int cx18_start_capture(struct cx18_open_
 		return 0;
 	}
 
-	/* failure, clean up */
+start_failed:
 	CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
 
-	/* Note: the CX18_ENC_STREAM_TYPE_VBI is released
-	   automatically when the MPG stream is released.
-	   We only need to stop the VBI capturing. */
-	if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
-	    test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
-		cx18_stop_v4l2_encode_stream(s_vbi, 0);
-		clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
+	/*
+	 * The associated VBI and IDX streams for internal use are released
+	 * automatically when the MPG stream is released.  We only need to stop
+	 * the associated stream.
+	 */
+	if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
+		/* Stop the IDX stream which is always for internal use */
+		if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
+			cx18_stop_v4l2_encode_stream(s_idx, 0);
+			clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
+		}
+		/* Stop the VBI stream, if only running for internal use */
+		if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
+		    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
+			cx18_stop_v4l2_encode_stream(s_vbi, 0);
+			clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
+		}
 	}
 	clear_bit(CX18_F_S_STREAMING, &s->s_flags);
-	cx18_release_stream(s);
+	cx18_release_stream(s); /* Also releases associated streams */
 	return -EIO;
 }
 
@@ -618,6 +655,8 @@ void cx18_stop_capture(struct cx18_open_
 {
 	struct cx18 *cx = id->cx;
 	struct cx18_stream *s = &cx->streams[id->type];
+	struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
+	struct cx18_stream *s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
 
 	CX18_DEBUG_IOCTL("close() of %s\n", s->name);
 
@@ -625,17 +664,19 @@ void cx18_stop_capture(struct cx18_open_
 
 	/* Stop capturing */
 	if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
-		struct cx18_stream *s_vbi =
-			&cx->streams[CX18_ENC_STREAM_TYPE_VBI];
-
 		CX18_DEBUG_INFO("close stopping capture\n");
-		/* Special case: a running VBI capture for VBI insertion
-		   in the mpeg stream. Need to stop that too. */
-		if (id->type == CX18_ENC_STREAM_TYPE_MPG &&
-		    test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
-		    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
-			CX18_DEBUG_INFO("close stopping embedded VBI capture\n");
-			cx18_stop_v4l2_encode_stream(s_vbi, 0);
+		if (id->type == CX18_ENC_STREAM_TYPE_MPG) {
+			/* Stop internal use associated VBI and IDX streams */
+			if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
+			    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
+				CX18_DEBUG_INFO("close stopping embedded VBI "
+						"capture\n");
+				cx18_stop_v4l2_encode_stream(s_vbi, 0);
+			}
+			if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
+				CX18_DEBUG_INFO("close stopping IDX capture\n");
+				cx18_stop_v4l2_encode_stream(s_idx, 0);
+			}
 		}
 		if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
 		    test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-fileops.h linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-fileops.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-fileops.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-fileops.h	2010-05-16 17:17:36.000000000 -0400
@@ -34,3 +34,6 @@ void cx18_stop_capture(struct cx18_open_
 void cx18_mute(struct cx18 *cx);
 void cx18_unmute(struct cx18 *cx);
 
+/* Shared with cx18-alsa module */
+int cx18_claim_stream(struct cx18_open_id *id, int type);
+void cx18_release_stream(struct cx18_stream *s);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-ioctl.c linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-ioctl.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -775,10 +775,143 @@ static int cx18_g_sliced_vbi_cap(struct
 	return 0;
 }
 
+static int _cx18_process_idx_data(struct cx18_buffer *buf,
+				  struct v4l2_enc_idx *idx)
+{
+	int consumed, remaining;
+	struct v4l2_enc_idx_entry *e_idx;
+	struct cx18_enc_idx_entry *e_buf;
+
+	/* Frame type lookup: 1=I, 2=P, 4=B */
+	const int mapping[8] = {
+		-1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P,
+		-1, V4L2_ENC_IDX_FRAME_B, -1, -1, -1
+	};
+
+	/*
+	 * Assumption here is that a buf holds an integral number of
+	 * struct cx18_enc_idx_entry objects and is properly aligned.
+	 * This is enforced by the module options on IDX buffer sizes.
+	 */
+	remaining = buf->bytesused - buf->readpos;
+	consumed = 0;
+	e_idx = &idx->entry[idx->entries];
+	e_buf = (struct cx18_enc_idx_entry *) &buf->buf[buf->readpos];
+
+	while (remaining >= sizeof(struct cx18_enc_idx_entry) &&
+	       idx->entries < V4L2_ENC_IDX_ENTRIES) {
+
+		e_idx->offset = (((u64) le32_to_cpu(e_buf->offset_high)) << 32)
+				| le32_to_cpu(e_buf->offset_low);
+
+		e_idx->pts = (((u64) (le32_to_cpu(e_buf->pts_high) & 1)) << 32)
+			     | le32_to_cpu(e_buf->pts_low);
+
+		e_idx->length = le32_to_cpu(e_buf->length);
+
+		e_idx->flags = mapping[le32_to_cpu(e_buf->flags) & 0x7];
+
+		e_idx->reserved[0] = 0;
+		e_idx->reserved[1] = 0;
+
+		idx->entries++;
+		e_idx = &idx->entry[idx->entries];
+		e_buf++;
+
+		remaining -= sizeof(struct cx18_enc_idx_entry);
+		consumed += sizeof(struct cx18_enc_idx_entry);
+	}
+
+	/* Swallow any partial entries at the end, if there are any */
+	if (remaining > 0 && remaining < sizeof(struct cx18_enc_idx_entry))
+		consumed += remaining;
+
+	buf->readpos += consumed;
+	return consumed;
+}
+
+static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl,
+				 struct v4l2_enc_idx *idx)
+{
+	if (s->type != CX18_ENC_STREAM_TYPE_IDX)
+		return -EINVAL;
+
+	if (mdl->curr_buf == NULL)
+		mdl->curr_buf = list_first_entry(&mdl->buf_list,
+						 struct cx18_buffer, list);
+
+	if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
+		/*
+		 * For some reason we've exhausted the buffers, but the MDL
+		 * object still said some data was unread.
+		 * Fix that and bail out.
+		 */
+		mdl->readpos = mdl->bytesused;
+		return 0;
+	}
+
+	list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
+
+		/* Skip any empty buffers in the MDL */
+		if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
+			continue;
+
+		mdl->readpos += _cx18_process_idx_data(mdl->curr_buf, idx);
+
+		/* exit when MDL drained or request satisfied */
+		if (idx->entries >= V4L2_ENC_IDX_ENTRIES ||
+		    mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
+		    mdl->readpos >= mdl->bytesused)
+			break;
+	}
+	return 0;
+}
+
 static int cx18_g_enc_index(struct file *file, void *fh,
 				struct v4l2_enc_idx *idx)
 {
-	return -EINVAL;
+	struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+	struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
+	s32 tmp;
+	struct cx18_mdl *mdl;
+
+	if (!cx18_stream_enabled(s)) /* Module options inhibited IDX stream */
+		return -EINVAL;
+
+	/* Compute the best case number of entries we can buffer */
+	tmp = s->buffers -
+			  s->bufs_per_mdl * CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN;
+	if (tmp <= 0)
+		tmp = 1;
+	tmp = tmp * s->buf_size / sizeof(struct cx18_enc_idx_entry);
+
+	/* Fill out the header of the return structure */
+	idx->entries = 0;
+	idx->entries_cap = tmp;
+	memset(idx->reserved, 0, sizeof(idx->reserved));
+
+	/* Pull IDX MDLs and buffers from q_full and populate the entries */
+	do {
+		mdl = cx18_dequeue(s, &s->q_full);
+		if (mdl == NULL) /* No more IDX data right now */
+			break;
+
+		/* Extract the Index entry data from the MDL and buffers */
+		cx18_process_idx_data(s, mdl, idx);
+		if (mdl->readpos < mdl->bytesused) {
+			/* We finished with data remaining, push the MDL back */
+			cx18_push(s, mdl, &s->q_full);
+			break;
+		}
+
+		/* We drained this MDL, schedule it to go to the firmware */
+		cx18_enqueue(s, mdl, &s->q_free);
+
+	} while (idx->entries < V4L2_ENC_IDX_ENTRIES);
+
+	/* Tell the work handler to send free IDX MDLs to the firmware */
+	cx18_stream_load_fw_queue(s);
+	return 0;
 }
 
 static int cx18_encoder_cmd(struct file *file, void *fh,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-mailbox.c linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-mailbox.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-mailbox.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-mailbox.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include "cx18-mailbox.h"
 #include "cx18-queue.h"
 #include "cx18-streams.h"
+#include "cx18-alsa-pcm.h" /* FIXME make configurable */
 
 static const char *rpu_str[] = { "APU", "CPU", "EPU", "HPU" };
 
@@ -157,6 +158,34 @@ static void cx18_mdl_send_to_dvb(struct
 	}
 }
 
+
+static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s,
+				  struct cx18_mdl *mdl)
+{
+	struct cx18_buffer *buf;
+
+	if (mdl->bytesused == 0)
+		return;
+
+	/* We ignore mdl and buf readpos accounting here - it doesn't matter */
+
+	/* The likely case */
+	if (list_is_singular(&mdl->buf_list)) {
+		buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
+				       list);
+		if (buf->bytesused)
+			cx->pcm_announce_callback(cx->alsa, buf->buf,
+						  buf->bytesused);
+		return;
+	}
+
+	list_for_each_entry(buf, &mdl->buf_list, list) {
+		if (buf->bytesused == 0)
+			break;
+		cx->pcm_announce_callback(cx->alsa, buf->buf, buf->bytesused);
+	}
+}
+
 static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
 {
 	u32 handle, mdl_ack_count, id;
@@ -223,11 +252,21 @@ static void epu_dma_done(struct cx18 *cx
 		CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
 				  s->name, mdl->bytesused);
 
-		if (s->type != CX18_ENC_STREAM_TYPE_TS)
-			cx18_enqueue(s, mdl, &s->q_full);
-		else {
+		if (s->type == CX18_ENC_STREAM_TYPE_TS) {
 			cx18_mdl_send_to_dvb(s, mdl);
 			cx18_enqueue(s, mdl, &s->q_free);
+		} else if (s->type == CX18_ENC_STREAM_TYPE_PCM) {
+			/* Pass the data to cx18-alsa */
+			if (cx->pcm_announce_callback != NULL) {
+				cx18_mdl_send_to_alsa(cx, s, mdl);
+				cx18_enqueue(s, mdl, &s->q_free);
+			} else {
+				cx18_enqueue(s, mdl, &s->q_full);
+			}
+		} else {
+			cx18_enqueue(s, mdl, &s->q_full);
+			if (s->type == CX18_ENC_STREAM_TYPE_IDX)
+				cx18_stream_rotate_idx_mdls(cx);
 		}
 	}
 	/* Put as many MDLs as possible back into fw use */
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-queue.c linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-queue.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-queue.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-queue.c	2010-05-16 17:17:36.000000000 -0400
@@ -419,6 +419,9 @@ void cx18_stream_free(struct cx18_stream
 {
 	struct cx18_mdl *mdl;
 	struct cx18_buffer *buf;
+	struct cx18 *cx = s->cx;
+
+	CX18_DEBUG_INFO("Deallocating buffers for %s stream\n", s->name);
 
 	/* move all buffers to buf_pool and all MDLs to q_idle */
 	cx18_unload_queues(s);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-streams.c linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-streams.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-streams.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-streams.c	2010-05-16 17:17:36.000000000 -0400
@@ -319,11 +319,27 @@ void cx18_streams_cleanup(struct cx18 *c
 
 	/* Teardown all streams */
 	for (type = 0; type < CX18_MAX_STREAMS; type++) {
-		if (cx->streams[type].dvb.enabled) {
-			cx18_dvb_unregister(&cx->streams[type]);
-			cx->streams[type].dvb.enabled = false;
+
+		/* No struct video_device, but can have buffers allocated */
+		if (type == CX18_ENC_STREAM_TYPE_TS) {
+			if (cx->streams[type].dvb.enabled) {
+				cx18_dvb_unregister(&cx->streams[type]);
+				cx->streams[type].dvb.enabled = false;
+				cx18_stream_free(&cx->streams[type]);
+			}
+			continue;
+		}
+
+		/* No struct video_device, but can have buffers allocated */
+		if (type == CX18_ENC_STREAM_TYPE_IDX) {
+			if (cx->stream_buffers[type] != 0) {
+				cx->stream_buffers[type] = 0;
+				cx18_stream_free(&cx->streams[type]);
+			}
+			continue;
 		}
 
+		/* If struct video_device exists, can have buffers allocated */
 		vdev = cx->streams[type].video_dev;
 
 		cx->streams[type].video_dev = NULL;
@@ -447,6 +463,32 @@ static void cx18_vbi_setup(struct cx18_s
 	cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
 }
 
+void cx18_stream_rotate_idx_mdls(struct cx18 *cx)
+{
+	struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
+	struct cx18_mdl *mdl;
+
+	if (!cx18_stream_enabled(s))
+		return;
+
+	/* Return if the firmware is not running low on MDLs */
+	if ((atomic_read(&s->q_free.depth) + atomic_read(&s->q_busy.depth)) >=
+					    CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN)
+		return;
+
+	/* Return if there are no MDLs to rotate back to the firmware */
+	if (atomic_read(&s->q_full.depth) < 2)
+		return;
+
+	/*
+	 * Take the oldest IDX MDL still holding data, and discard its index
+	 * entries by scheduling the MDL to go back to the firmware
+	 */
+	mdl = cx18_dequeue(s, &s->q_full);
+	if (mdl != NULL)
+		cx18_enqueue(s, mdl, &s->q_free);
+}
+
 static
 struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,
 					   struct cx18_mdl *mdl)
@@ -546,8 +588,9 @@ int cx18_start_v4l2_encode_stream(struct
 	struct cx18 *cx = s->cx;
 	int captype = 0;
 	struct cx18_api_func_private priv;
+	struct cx18_stream *s_idx;
 
-	if (s->video_dev == NULL && s->dvb.enabled == 0)
+	if (!cx18_stream_enabled(s))
 		return -EINVAL;
 
 	CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);
@@ -561,6 +604,9 @@ int cx18_start_v4l2_encode_stream(struct
 		cx->search_pack_header = 0;
 		break;
 
+	case CX18_ENC_STREAM_TYPE_IDX:
+		captype = CAPTURE_CHANNEL_TYPE_INDEX;
+		break;
 	case CX18_ENC_STREAM_TYPE_TS:
 		captype = CAPTURE_CHANNEL_TYPE_TS;
 		break;
@@ -635,11 +681,13 @@ int cx18_start_v4l2_encode_stream(struct
 			cx18_vbi_setup(s);
 
 		/*
-		 * assign program index info.
-		 * Mask 7: select I/P/B, Num_req: 400 max
-		 * FIXME - currently we have this hardcoded as disabled
+		 * Select to receive I, P, and B frame index entries, if the
+		 * index stream is enabled.  Otherwise disable index entry
+		 * generation.
 		 */
-		cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0);
+		s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
+		cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 2,
+				 s->handle, cx18_stream_enabled(s_idx) ? 7 : 0);
 
 		/* Call out to the common CX2341x API setup for user controls */
 		priv.cx = cx;
@@ -697,6 +745,7 @@ int cx18_start_v4l2_encode_stream(struct
 	atomic_inc(&cx->tot_capturing);
 	return 0;
 }
+EXPORT_SYMBOL(cx18_start_v4l2_encode_stream);
 
 void cx18_stop_all_captures(struct cx18 *cx)
 {
@@ -705,7 +754,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->video_dev == NULL && s->dvb.enabled == 0)
+		if (!cx18_stream_enabled(s))
 			continue;
 		if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
 			cx18_stop_v4l2_encode_stream(s, 0);
@@ -717,7 +766,7 @@ int cx18_stop_v4l2_encode_stream(struct
 	struct cx18 *cx = s->cx;
 	unsigned long then;
 
-	if (s->video_dev == NULL && s->dvb.enabled == 0)
+	if (!cx18_stream_enabled(s))
 		return -EINVAL;
 
 	/* This function assumes that you are allowed to stop the capture
@@ -762,6 +811,7 @@ int cx18_stop_v4l2_encode_stream(struct
 
 	return 0;
 }
+EXPORT_SYMBOL(cx18_stop_v4l2_encode_stream);
 
 u32 cx18_find_handle(struct cx18 *cx)
 {
@@ -789,7 +839,7 @@ struct cx18_stream *cx18_handle_to_strea
 		s = &cx->streams[i];
 		if (s->handle != handle)
 			continue;
-		if (s->video_dev || s->dvb.enabled)
+		if (cx18_stream_enabled(s))
 			return s;
 	}
 	return NULL;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-streams.h linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-streams.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-streams.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-streams.h	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,16 @@ int cx18_streams_setup(struct cx18 *cx);
 int cx18_streams_register(struct cx18 *cx);
 void cx18_streams_cleanup(struct cx18 *cx, int unregister);
 
+#define CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN (3)
+void cx18_stream_rotate_idx_mdls(struct cx18 *cx);
+
+static inline bool cx18_stream_enabled(struct cx18_stream *s)
+{
+	return s->video_dev || s->dvb.enabled ||
+	       (s->type == CX18_ENC_STREAM_TYPE_IDX &&
+		s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0);
+}
+
 /* Related to submission of mdls to firmware */
 static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-version.h linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-version.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-version.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx18-version.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,7 @@
 
 #define CX18_DRIVER_NAME "cx18"
 #define CX18_DRIVER_VERSION_MAJOR 1
-#define CX18_DRIVER_VERSION_MINOR 3
+#define CX18_DRIVER_VERSION_MINOR 4
 #define CX18_DRIVER_VERSION_PATCHLEVEL 0
 
 #define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL)
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx23418.h linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx23418.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx23418.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/cx23418.h	2010-05-16 17:17:36.000000000 -0400
@@ -191,7 +191,8 @@
 #define CX18_CPU_SET_MEDIAN_CORING           	(CPU_CMD_MASK_CAPTURE | 0x000E)
 
 /* Description: This command set the picture type mask for index file
-   IN[0] - 	0 = disable index file output
+   IN[0] - Task handle (ignored by firmware)
+   IN[1] - 	0 = disable index file output
 			1 = output I picture
 			2 = P picture
 			4 = B picture
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/Kconfig linux-libre-2.6.34-gnu1/drivers/media/video/cx18/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -19,3 +19,14 @@ config VIDEO_CX18
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called cx18.
+
+config VIDEO_CX18_ALSA
+	tristate "Conexant 23418 DMA audio support"
+	depends on VIDEO_CX18 && SND && EXPERIMENTAL
+	select SND_PCM
+	---help---
+	  This is a video4linux driver for direct (DMA) audio on
+	  Conexant 23418 based TV cards using ALSA.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cx18-alsa.
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx18/Makefile linux-libre-2.6.34-gnu1/drivers/media/video/cx18/Makefile
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx18/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx18/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -3,8 +3,10 @@ cx18-objs    := cx18-driver.o cx18-cards
 	cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \
 	cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \
 	cx18-dvb.o cx18-io.o
+cx18-alsa-objs := cx18-alsa-main.o cx18-alsa-pcm.o
 
 obj-$(CONFIG_VIDEO_CX18) += cx18.o
+obj-$(CONFIG_VIDEO_CX18_ALSA) += cx18-alsa.o
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c linux-libre-2.6.34-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c	2013-05-03 12:03:50.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c	2013-05-03 09:44:45.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/usb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-core.c linux-libre-2.6.34-gnu1/drivers/media/video/cx231xx/cx231xx-core.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx231xx/cx231xx-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/vmalloc.h>
 #include <media/v4l2-common.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-dvb.c linux-libre-2.6.34-gnu1/drivers/media/video/cx231xx/cx231xx-dvb.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-dvb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx231xx/cx231xx-dvb.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "cx231xx.h"
@@ -464,9 +465,9 @@ static int dvb_init(struct cx231xx *dev)
 		/* define general-purpose callback pointer */
 		dvb->frontend->callback = cx231xx_tuner_callback;
 
-		if (dvb_attach(xc5000_attach, dev->dvb->frontend,
+		if (!dvb_attach(xc5000_attach, dev->dvb->frontend,
 			       &dev->i2c_bus[1].i2c_adap,
-			       &cnxt_rde250_tunerconfig) < 0) {
+			       &cnxt_rde250_tunerconfig)) {
 			result = -EINVAL;
 			goto out_free;
 		}
@@ -486,9 +487,9 @@ static int dvb_init(struct cx231xx *dev)
 		/* define general-purpose callback pointer */
 		dvb->frontend->callback = cx231xx_tuner_callback;
 
-		if (dvb_attach(xc5000_attach, dev->dvb->frontend,
+		if (!dvb_attach(xc5000_attach, dev->dvb->frontend,
 			       &dev->i2c_bus[1].i2c_adap,
-			       &cnxt_rde250_tunerconfig) < 0) {
+			       &cnxt_rde250_tunerconfig)) {
 			result = -EINVAL;
 			goto out_free;
 		}
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-input.c linux-libre-2.6.34-gnu1/drivers/media/video/cx231xx/cx231xx-input.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-input.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx231xx/cx231xx-input.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include "cx231xx.h"
 
@@ -216,7 +217,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
 	cx231xx_ir_start(ir);
 
 	/* all done */
-	err = ir_input_register(ir->input, dev->board.ir_codes);
+	err = ir_input_register(ir->input, dev->board.ir_codes, NULL);
 	if (err)
 		goto err_out_stop;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-vbi.c linux-libre-2.6.34-gnu1/drivers/media/video/cx231xx/cx231xx-vbi.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-vbi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx231xx/cx231xx-vbi.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/i2c.h>
 #include <linux/mm.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-video.c linux-libre-2.6.34-gnu1/drivers/media/video/cx231xx/cx231xx-video.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-video.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx231xx/cx231xx-video.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/version.h>
 #include <linux/mm.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-417.c linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23885-417.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-417.c	2013-05-03 12:07:03.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23885-417.c	2013-05-03 09:46:25.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/cx2341x.h>
@@ -681,7 +682,7 @@ static char *cmd_to_str(int cmd)
 	case CX2341X_ENC_SET_VIDEO_ID:
 		return  "SET_VIDEO_ID";
 	case CX2341X_ENC_SET_PCR_ID:
-		return  "SET_PCR_PID";
+		return  "SET_PCR_ID";
 	case CX2341X_ENC_SET_FRAME_RATE:
 		return  "SET_FRAME_RATE";
 	case CX2341X_ENC_SET_FRAME_SIZE:
@@ -693,7 +694,7 @@ static char *cmd_to_str(int cmd)
 	case CX2341X_ENC_SET_ASPECT_RATIO:
 		return  "SET_ASPECT_RATIO";
 	case CX2341X_ENC_SET_DNR_FILTER_MODE:
-		return  "SET_DNR_FILTER_PROPS";
+		return  "SET_DNR_FILTER_MODE";
 	case CX2341X_ENC_SET_DNR_FILTER_PROPS:
 		return  "SET_DNR_FILTER_PROPS";
 	case CX2341X_ENC_SET_CORING_LEVELS:
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-cards.c linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23885-cards.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-cards.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23885-cards.c	2010-05-16 17:17:36.000000000 -0400
@@ -274,6 +274,31 @@ struct cx23885_board cx23885_boards[] =
 		.portb		= CX23885_MPEG_DVB,
 		.portc		= CX23885_MPEG_DVB,
 	},
+	[CX23885_BOARD_LEADTEK_WINFAST_PXTV1200] = {
+		.name           = "LEADTEK WinFast PxTV1200",
+		.porta          = CX23885_ANALOG_VIDEO,
+		.tuner_type     = TUNER_XC2028,
+		.tuner_addr     = 0x61,
+		.input          = {{
+			.type   = CX23885_VMUX_TELEVISION,
+			.vmux   = CX25840_VIN2_CH1 |
+				  CX25840_VIN5_CH2 |
+				  CX25840_NONE0_CH3,
+		}, {
+			.type   = CX23885_VMUX_COMPOSITE1,
+			.vmux   = CX25840_COMPOSITE1,
+		}, {
+			.type   = CX23885_VMUX_SVIDEO,
+			.vmux   = CX25840_SVIDEO_LUMA3 |
+				  CX25840_SVIDEO_CHROMA4,
+		}, {
+			.type   = CX23885_VMUX_COMPONENT,
+			.vmux   = CX25840_VIN7_CH1 |
+				  CX25840_VIN6_CH2 |
+				  CX25840_VIN8_CH3 |
+				  CX25840_COMPONENT_ON,
+		} },
+	},
 };
 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
 
@@ -417,6 +442,10 @@ struct cx23885_subid cx23885_subids[] =
 		.subvendor = 0x14f1,
 		.subdevice = 0x8578,
 		.card      = CX23885_BOARD_MYGICA_X8558PRO,
+	}, {
+		.subvendor = 0x107d,
+		.subdevice = 0x6f22,
+		.card      = CX23885_BOARD_LEADTEK_WINFAST_PXTV1200,
 	},
 };
 const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -617,6 +646,7 @@ int cx23885_tuner_callback(void *priv, i
 	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
+	case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
 		/* Tuner Reset Command */
 		bitmask = 0x04;
 		break;
@@ -769,6 +799,7 @@ void cx23885_gpio_setup(struct cx23885_d
 	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
+	case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
 		/* GPIO-2  xc3028 tuner reset */
 
 		/* The following GPIO's are on the internal AVCore (cx25840) */
@@ -1076,6 +1107,7 @@ void cx23885_card_setup(struct cx23885_d
 	case CX23885_BOARD_MYGICA_X8506:
 	case CX23885_BOARD_MAGICPRO_PROHDTVE2:
 	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+	case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
 		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_bus[2].i2c_adap,
 				"cx25840", "cx25840", 0x88 >> 1, NULL);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-dvb.c linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23885-dvb.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-dvb.c	2013-05-03 12:03:50.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23885-dvb.c	2013-05-03 09:44:44.000000000 -0400
@@ -542,6 +542,9 @@ static struct atbm8830_config mygica_x85
 	.osc_clk_freq = 30400, /* in kHz */
 	.if_freq = 0, /* zero IF */
 	.zif_swap_iq = 1,
+	.agc_min = 0x2E,
+	.agc_max = 0xFF,
+	.agc_hold_loop = 0,
 };
 
 static struct max2165_config mygic_x8558pro_max2165_cfg1 = {
@@ -558,6 +561,9 @@ static struct atbm8830_config mygica_x85
 	.osc_clk_freq = 30400, /* in kHz */
 	.if_freq = 0, /* zero IF */
 	.zif_swap_iq = 1,
+	.agc_min = 0x2E,
+	.agc_max = 0xFF,
+	.agc_hold_loop = 0,
 };
 
 static struct max2165_config mygic_x8558pro_max2165_cfg2 = {
@@ -994,15 +1000,8 @@ static int dvb_register(struct cx23885_t
 		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]);
+		printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=%pM\n",
+			port->nr, port->frontends.adapter.proposed_mac);
 
 		netup_ci_init(port);
 		break;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885.h linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23885.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23885.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
 #include <linux/kdev_t.h>
+#include <linux/slab.h>
 
 #include <media/v4l2-device.h>
 #include <media/tuner.h>
@@ -81,6 +82,7 @@
 #define CX23885_BOARD_COMPRO_VIDEOMATE_E800    25
 #define CX23885_BOARD_HAUPPAUGE_HVR1290        26
 #define CX23885_BOARD_MYGICA_X8558PRO          27
+#define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28
 
 #define GPIO_0 0x00000001
 #define GPIO_1 0x00000002
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-input.c linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23885-input.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-input.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23885-input.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
  */
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <media/ir-common.h>
 #include <media/v4l2-subdev.h>
 
@@ -397,7 +398,7 @@ int cx23885_input_init(struct cx23885_de
 	dev->ir_input = ir;
 	cx23885_input_ir_start(dev);
 
-	ret = ir_input_register(ir->dev, ir_codes);
+	ret = ir_input_register(ir->dev, ir_codes, NULL);
 	if (ret)
 		goto err_out_stop;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-vbi.c linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23885-vbi.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-vbi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23885-vbi.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 
 #include "cx23885.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-video.c linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23885-video.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-video.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23885-video.c	2013-05-03 09:44:44.000000000 -0400
@@ -36,6 +36,7 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include "cx23885-ioctl.h"
+#include "tuner-xc2028.h"
 
 MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
 MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
@@ -1505,6 +1506,18 @@ int cx23885_video_register(struct cx2388
 			tun_setup.tuner_callback = cx23885_tuner_callback;
 
 			v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup);
+
+			if (dev->board == CX23885_BOARD_LEADTEK_WINFAST_PXTV1200) {
+				struct xc2028_ctrl ctrl = {
+					.fname = "/*(DEBLOBBED)*/",
+					.max_len = 64
+				};
+				struct v4l2_priv_tun_config cfg = {
+					.tuner = dev->tuner_type,
+					.priv = &ctrl
+				};
+				v4l2_subdev_call(sd, tuner, s_config, &cfg);
+			}
 		}
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23888-ir.c linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23888-ir.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23888-ir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx23885/cx23888-ir.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  */
 
 #include <linux/kfifo.h>
+#include <linux/slab.h>
 
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx25840/cx25840-core.c linux-libre-2.6.34-gnu1/drivers/media/video/cx25840/cx25840-core.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx25840/cx25840-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx25840/cx25840-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -734,10 +734,8 @@ static int set_input(struct i2c_client *
 		v4l_dbg(1, cx25840_debug, client, "vid_input 0x%x\n",
 			vid_input);
 		reg = vid_input & 0xff;
-		if ((vid_input & CX25840_SVIDEO_ON) == CX25840_SVIDEO_ON)
-			is_composite = 0;
-		else if ((vid_input & CX25840_COMPONENT_ON) == 0)
-			is_composite = 1;
+		is_composite = !is_component &&
+			((vid_input & CX25840_SVIDEO_ON) != CX25840_SVIDEO_ON);
 
 		v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n",
 			reg, is_composite);
@@ -1347,30 +1345,59 @@ static int cx25840_s_register(struct v4l
 }
 #endif
 
+static int cx25840_s_audio_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct cx25840_state *state = to_state(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	u8 v;
+
+	if (is_cx2583x(state) || is_cx2388x(state) || is_cx231xx(state))
+		return 0;
+
+	v4l_dbg(1, cx25840_debug, client, "%s audio output\n",
+			enable ? "enable" : "disable");
+
+	if (enable) {
+		v = cx25840_read(client, 0x115) | 0x80;
+		cx25840_write(client, 0x115, v);
+		v = cx25840_read(client, 0x116) | 0x03;
+		cx25840_write(client, 0x116, v);
+	} else {
+		v = cx25840_read(client, 0x115) & ~(0x80);
+		cx25840_write(client, 0x115, v);
+		v = cx25840_read(client, 0x116) & ~(0x03);
+		cx25840_write(client, 0x116, v);
+	}
+	return 0;
+}
+
 static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
 {
 	struct cx25840_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	u8 v;
 
-	v4l_dbg(1, cx25840_debug, client, "%s output\n",
+	v4l_dbg(1, cx25840_debug, client, "%s video output\n",
 			enable ? "enable" : "disable");
 	if (enable) {
 		if (is_cx2388x(state) || is_cx231xx(state)) {
-			u8 v = (cx25840_read(client, 0x421) | 0x0b);
+			v = cx25840_read(client, 0x421) | 0x0b;
 			cx25840_write(client, 0x421, v);
 		} else {
-			cx25840_write(client, 0x115,
-					is_cx2583x(state) ? 0x0c : 0x8c);
-			cx25840_write(client, 0x116,
-					is_cx2583x(state) ? 0x04 : 0x07);
+			v = cx25840_read(client, 0x115) | 0x0c;
+			cx25840_write(client, 0x115, v);
+			v = cx25840_read(client, 0x116) | 0x04;
+			cx25840_write(client, 0x116, v);
 		}
 	} else {
 		if (is_cx2388x(state) || is_cx231xx(state)) {
-			u8 v = cx25840_read(client, 0x421) & ~(0x0b);
+			v = cx25840_read(client, 0x421) & ~(0x0b);
 			cx25840_write(client, 0x421, v);
 		} else {
-			cx25840_write(client, 0x115, 0x00);
-			cx25840_write(client, 0x116, 0x00);
+			v = cx25840_read(client, 0x115) & ~(0x0c);
+			cx25840_write(client, 0x115, v);
+			v = cx25840_read(client, 0x116) & ~(0x04);
+			cx25840_write(client, 0x116, v);
 		}
 	}
 	return 0;
@@ -1601,6 +1628,7 @@ static const struct v4l2_subdev_tuner_op
 static const struct v4l2_subdev_audio_ops cx25840_audio_ops = {
 	.s_clock_freq = cx25840_s_clock_freq,
 	.s_routing = cx25840_s_audio_routing,
+	.s_stream = cx25840_s_audio_stream,
 };
 
 static const struct v4l2_subdev_video_ops cx25840_video_ops = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-alsa.c linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-alsa.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-alsa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-alsa.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/vmalloc.h>
 #include <linux/dma-mapping.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include <asm/delay.h>
 #include <sound/core.h>
@@ -583,16 +584,18 @@ static int snd_cx88_volume_put(struct sn
 {
 	snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
 	struct cx88_core *core=chip->core;
-	int v, b;
+	int left, right, v, b;
 	int changed = 0;
 	u32 old;
 
-	b = value->value.integer.value[1] - value->value.integer.value[0];
+	left = value->value.integer.value[0] & 0x3f;
+	right = value->value.integer.value[1] & 0x3f;
+	b = right - left;
 	if (b < 0) {
-	    v = 0x3f - value->value.integer.value[0];
+	    v = 0x3f - left;
 	    b = (-b) | 0x40;
 	} else {
-	    v = 0x3f - value->value.integer.value[1];
+	    v = 0x3f - right;
 	}
 	/* Do we really know this will always be called with IRQs on? */
 	spin_lock_irq(&chip->reg_lock);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-blackbird.c linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-blackbird.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-blackbird.c	2013-05-03 12:07:05.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-blackbird.c	2013-05-03 09:46:27.000000000 -0400
@@ -28,6 +28,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/delay.h>
 #include <linux/device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-cards.c linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-cards.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-cards.c	2013-05-03 12:03:50.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-cards.c	2013-05-03 09:44:45.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "cx88.h"
 #include "tea5767.h"
@@ -1466,6 +1467,18 @@ static const struct cx88_board cx88_boar
 			.audioroute = 8,
 		},
 	},
+	[CX88_BOARD_SAMSUNG_SMT_7020] = {
+		.name		= "Samsung SMT 7020 DVB-S",
+		.tuner_type	= TUNER_ABSENT,
+		.radio_type	= UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.input		= { {
+			.type	= CX88_VMUX_DVB,
+			.vmux	= 0,
+		} },
+		.mpeg           = CX88_MPEG_DVB,
+	},
 	[CX88_BOARD_ADSTECH_PTV_390] = {
 		.name           = "ADS Tech Instant Video PCI",
 		.tuner_type     = TUNER_ABSENT,
@@ -2355,6 +2368,14 @@ static const struct cx88_subid cx88_subi
 		.subvendor = 0x0070,
 		.subdevice = 0x1404,
 		.card      = CX88_BOARD_HAUPPAUGE_HVR3000,
+	}, {
+		.subvendor = 0x18ac,
+		.subdevice = 0xdc00,
+		.card      = CX88_BOARD_SAMSUNG_SMT_7020,
+	}, {
+		.subvendor = 0x18ac,
+		.subdevice = 0xdccd,
+		.card      = CX88_BOARD_SAMSUNG_SMT_7020,
 	},{
 		.subvendor = 0x1461,
 		.subdevice = 0xc111, /* AverMedia M150-D */
@@ -2633,6 +2654,9 @@ static void hauppauge_eeprom(struct cx88
 	case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
 		/* known */
 		break;
+	case CX88_BOARD_SAMSUNG_SMT_7020:
+		cx_set(MO_GP0_IO, 0x008989FF);
+		break;
 	default:
 		warn_printk(core, "warning: unknown hauppauge model #%d\n",
 			    tv.model);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-dsp.c linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-dsp.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-dsp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-dsp.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/jiffies.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-dvb.c linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-dvb.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-dvb.c	2013-05-03 12:03:50.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-dvb.c	2013-05-03 09:44:45.000000000 -0400
@@ -674,6 +674,194 @@ static int cx8802_alloc_frontends(struct
 	return 0;
 }
 
+
+
+static u8 samsung_smt_7020_inittab[] = {
+	     0x01, 0x15,
+	     0x02, 0x00,
+	     0x03, 0x00,
+	     0x04, 0x7D,
+	     0x05, 0x0F,
+	     0x06, 0x02,
+	     0x07, 0x00,
+	     0x08, 0x60,
+
+	     0x0A, 0xC2,
+	     0x0B, 0x00,
+	     0x0C, 0x01,
+	     0x0D, 0x81,
+	     0x0E, 0x44,
+	     0x0F, 0x09,
+	     0x10, 0x3C,
+	     0x11, 0x84,
+	     0x12, 0xDA,
+	     0x13, 0x99,
+	     0x14, 0x8D,
+	     0x15, 0xCE,
+	     0x16, 0xE8,
+	     0x17, 0x43,
+	     0x18, 0x1C,
+	     0x19, 0x1B,
+	     0x1A, 0x1D,
+
+	     0x1C, 0x12,
+	     0x1D, 0x00,
+	     0x1E, 0x00,
+	     0x1F, 0x00,
+	     0x20, 0x00,
+	     0x21, 0x00,
+	     0x22, 0x00,
+	     0x23, 0x00,
+
+	     0x28, 0x02,
+	     0x29, 0x28,
+	     0x2A, 0x14,
+	     0x2B, 0x0F,
+	     0x2C, 0x09,
+	     0x2D, 0x05,
+
+	     0x31, 0x1F,
+	     0x32, 0x19,
+	     0x33, 0xFC,
+	     0x34, 0x13,
+	     0xff, 0xff,
+};
+
+
+static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *params)
+{
+	struct cx8802_dev *dev = fe->dvb->priv;
+	u8 buf[4];
+	u32 div;
+	struct i2c_msg msg = {
+		.addr = 0x61,
+		.flags = 0,
+		.buf = buf,
+		.len = sizeof(buf) };
+
+	div = params->frequency / 125;
+
+	buf[0] = (div >> 8) & 0x7f;
+	buf[1] = div & 0xff;
+	buf[2] = 0x84;  /* 0xC4 */
+	buf[3] = 0x00;
+
+	if (params->frequency < 1500000)
+		buf[3] |= 0x10;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1)
+		return -EIO;
+
+	return 0;
+}
+
+static int samsung_smt_7020_set_tone(struct dvb_frontend *fe,
+	fe_sec_tone_mode_t tone)
+{
+	struct cx8802_dev *dev = fe->dvb->priv;
+	struct cx88_core *core = dev->core;
+
+	cx_set(MO_GP0_IO, 0x0800);
+
+	switch (tone) {
+	case SEC_TONE_ON:
+		cx_set(MO_GP0_IO, 0x08);
+		break;
+	case SEC_TONE_OFF:
+		cx_clear(MO_GP0_IO, 0x08);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe,
+	fe_sec_voltage_t voltage)
+{
+	struct cx8802_dev *dev = fe->dvb->priv;
+	struct cx88_core *core = dev->core;
+
+	u8 data;
+	struct i2c_msg msg = {
+		.addr = 8,
+		.flags = 0,
+		.buf = &data,
+		.len = sizeof(data) };
+
+	cx_set(MO_GP0_IO, 0x8000);
+
+	switch (voltage) {
+	case SEC_VOLTAGE_OFF:
+		break;
+	case SEC_VOLTAGE_13:
+		data = ISL6421_EN1 | ISL6421_LLC1;
+		cx_clear(MO_GP0_IO, 0x80);
+		break;
+	case SEC_VOLTAGE_18:
+		data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1;
+		cx_clear(MO_GP0_IO, 0x80);
+		break;
+	default:
+		return -EINVAL;
+	};
+
+	return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe,
+	u32 srate, u32 ratio)
+{
+	u8 aclk = 0;
+	u8 bclk = 0;
+
+	if (srate < 1500000) {
+		aclk = 0xb7;
+		bclk = 0x47;
+	} else if (srate < 3000000) {
+		aclk = 0xb7;
+		bclk = 0x4b;
+	} else if (srate < 7000000) {
+		aclk = 0xb7;
+		bclk = 0x4f;
+	} else if (srate < 14000000) {
+		aclk = 0xb7;
+		bclk = 0x53;
+	} else if (srate < 30000000) {
+		aclk = 0xb6;
+		bclk = 0x53;
+	} else if (srate < 45000000) {
+		aclk = 0xb4;
+		bclk = 0x51;
+	}
+
+	stv0299_writereg(fe, 0x13, aclk);
+	stv0299_writereg(fe, 0x14, bclk);
+	stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
+	stv0299_writereg(fe, 0x20, (ratio >>  8) & 0xff);
+	stv0299_writereg(fe, 0x21, ratio & 0xf0);
+
+	return 0;
+}
+
+
+static struct stv0299_config samsung_stv0299_config = {
+	.demod_address = 0x68,
+	.inittab = samsung_smt_7020_inittab,
+	.mclk = 88000000UL,
+	.invert = 0,
+	.skip_reinit = 0,
+	.lock_output = STV0299_LOCKOUTPUT_LK,
+	.volt13_op0_op1 = STV0299_VOLT13_OP1,
+	.min_delay_ms = 100,
+	.set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate,
+};
+
 static int dvb_register(struct cx8802_dev *dev)
 {
 	struct cx88_core *core = dev->core;
@@ -1203,6 +1391,32 @@ static int dvb_register(struct cx8802_de
 		}
 		break;
 		}
+	case CX88_BOARD_SAMSUNG_SMT_7020:
+		dev->ts_gen_cntrl = 0x08;
+
+		cx_set(MO_GP0_IO, 0x0101);
+
+		cx_clear(MO_GP0_IO, 0x01);
+		mdelay(100);
+		cx_set(MO_GP0_IO, 0x01);
+		mdelay(200);
+
+		fe0->dvb.frontend = dvb_attach(stv0299_attach,
+					&samsung_stv0299_config,
+					&dev->core->i2c_adap);
+		if (fe0->dvb.frontend) {
+			fe0->dvb.frontend->ops.tuner_ops.set_params =
+				samsung_smt_7020_tuner_set_params;
+			fe0->dvb.frontend->tuner_priv =
+				&dev->core->i2c_adap;
+			fe0->dvb.frontend->ops.set_voltage =
+				samsung_smt_7020_set_voltage;
+			fe0->dvb.frontend->ops.set_tone =
+				samsung_smt_7020_set_tone;
+		}
+
+		break;
+
 	default:
 		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
 		       core->name);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88.h linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88.h	2010-05-16 17:17:36.000000000 -0400
@@ -239,6 +239,7 @@ extern struct sram_channel cx88_sram_cha
 #define CX88_BOARD_WINFAST_DTV1800H        81
 #define CX88_BOARD_WINFAST_DTV2000H_J      82
 #define CX88_BOARD_PROF_7301               83
+#define CX88_BOARD_SAMSUNG_SMT_7020        84
 
 enum cx88_itype {
 	CX88_VMUX_COMPOSITE1 = 1,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-input.c linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-input.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-input.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-input.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/hrtimer.h>
 #include <linux/input.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 
 #include "cx88.h"
@@ -192,7 +193,7 @@ int cx88_ir_init(struct cx88_core *core,
 	struct cx88_IR *ir;
 	struct input_dev *input_dev;
 	struct ir_scancode_table *ir_codes = NULL;
-	int ir_type = IR_TYPE_OTHER;
+	u64 ir_type = IR_TYPE_OTHER;
 	int err = -ENOMEM;
 
 	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
@@ -383,7 +384,7 @@ int cx88_ir_init(struct cx88_core *core,
 	cx88_ir_start(core, ir);
 
 	/* all done */
-	err = ir_input_register(ir->input, ir_codes);
+	err = ir_input_register(ir->input, ir_codes, NULL);
 	if (err)
 		goto err_out_stop;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-mpeg.c linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-mpeg.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-mpeg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-mpeg.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
@@ -110,6 +111,9 @@ static int cx8802_start_dma(struct cx880
 		case CX88_BOARD_PCHDTV_HD5500:
 			cx_write(TS_SOP_STAT, 1<<13);
 			break;
+		case CX88_BOARD_SAMSUNG_SMT_7020:
+			cx_write(TS_SOP_STAT, 0x00);
+			break;
 		case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
 		case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
 			cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-tvaudio.c linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-tvaudio.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-tvaudio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-tvaudio.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,6 @@
 #include <linux/errno.h>
 #include <linux/freezer.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/poll.h>
 #include <linux/signal.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-vbi.c linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-vbi.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-vbi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-vbi.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 
 #include "cx88.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-vp3054-i2c.c linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-vp3054-i2c.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-vp3054-i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/cx88/cx88-vp3054-i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/dabusb.c linux-libre-2.6.34-gnu1/drivers/media/video/dabusb.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/dabusb.c	2013-05-03 12:07:28.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/dabusb.c	2013-05-03 09:46:51.000000000 -0400
@@ -616,10 +616,12 @@ static int dabusb_open (struct inode *in
 {
 	int devnum = iminor(inode);
 	pdabusb_t s;
+	int r;
 
 	if (devnum < DABUSB_MINOR || devnum >= (DABUSB_MINOR + NRDABUSB))
 		return -EIO;
 
+	lock_kernel();
 	s = &dabusb[devnum - DABUSB_MINOR];
 
 	dbg("dabusb_open");
@@ -634,6 +636,7 @@ static int dabusb_open (struct inode *in
 		msleep_interruptible(500);
 
 		if (signal_pending (current)) {
+			unlock_kernel();
 			return -EAGAIN;
 		}
 		mutex_lock(&s->mutex);
@@ -641,6 +644,7 @@ static int dabusb_open (struct inode *in
 	if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
 		mutex_unlock(&s->mutex);
 		dev_err(&s->usbdev->dev, "set_interface failed\n");
+		unlock_kernel();
 		return -EINVAL;
 	}
 	s->opened = 1;
@@ -649,7 +653,9 @@ static int dabusb_open (struct inode *in
 	file->f_pos = 0;
 	file->private_data = s;
 
-	return nonseekable_open(inode, file);
+	r = nonseekable_open(inode, file);
+	unlock_kernel();
+	return r;
 }
 
 static int dabusb_release (struct inode *inode, struct file *file)
@@ -913,6 +919,7 @@ static void __exit dabusb_cleanup (void)
 MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
 MODULE_LICENSE("GPL");
+/*(DEBLOBBED)*/
 
 module_param(buffers, int, 0);
 MODULE_PARM_DESC (buffers, "Number of buffers (default=256)");
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/davinci/dm355_ccdc.c linux-libre-2.6.34-gnu1/drivers/media/video/davinci/dm355_ccdc.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/davinci/dm355_ccdc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/davinci/dm355_ccdc.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,8 +37,12 @@
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
 #include <linux/videodev2.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
 #include <media/davinci/dm355_ccdc.h>
 #include <media/davinci/vpss.h>
+
 #include "dm355_ccdc_regs.h"
 #include "ccdc_hw_device.h"
 
@@ -46,67 +50,75 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("CCDC Driver for DM355");
 MODULE_AUTHOR("Texas Instruments");
 
-static struct device *dev;
-
-/* Object for CCDC raw mode */
-static struct ccdc_params_raw ccdc_hw_params_raw = {
-	.pix_fmt = CCDC_PIXFMT_RAW,
-	.frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
-	.win = CCDC_WIN_VGA,
-	.fid_pol = VPFE_PINPOL_POSITIVE,
-	.vd_pol = VPFE_PINPOL_POSITIVE,
-	.hd_pol = VPFE_PINPOL_POSITIVE,
-	.gain = {
-		.r_ye = 256,
-		.gb_g = 256,
-		.gr_cy = 256,
-		.b_mg = 256
-	},
-	.config_params = {
-		.datasft = 2,
-		.data_sz = CCDC_DATA_10BITS,
-		.mfilt1 = CCDC_NO_MEDIAN_FILTER1,
-		.mfilt2 = CCDC_NO_MEDIAN_FILTER2,
-		.alaw = {
-			.gama_wd = 2,
-		},
-		.blk_clamp = {
-			.sample_pixel = 1,
-			.dc_sub = 25
-		},
-		.col_pat_field0 = {
-			.olop = CCDC_GREEN_BLUE,
-			.olep = CCDC_BLUE,
-			.elop = CCDC_RED,
-			.elep = CCDC_GREEN_RED
+static struct ccdc_oper_config {
+	struct device *dev;
+	/* CCDC interface type */
+	enum vpfe_hw_if_type if_type;
+	/* Raw Bayer configuration */
+	struct ccdc_params_raw bayer;
+	/* YCbCr configuration */
+	struct ccdc_params_ycbcr ycbcr;
+	/* Master clock */
+	struct clk *mclk;
+	/* slave clock */
+	struct clk *sclk;
+	/* ccdc base address */
+	void __iomem *base_addr;
+} ccdc_cfg = {
+	/* Raw configurations */
+	.bayer = {
+		.pix_fmt = CCDC_PIXFMT_RAW,
+		.frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
+		.win = CCDC_WIN_VGA,
+		.fid_pol = VPFE_PINPOL_POSITIVE,
+		.vd_pol = VPFE_PINPOL_POSITIVE,
+		.hd_pol = VPFE_PINPOL_POSITIVE,
+		.gain = {
+			.r_ye = 256,
+			.gb_g = 256,
+			.gr_cy = 256,
+			.b_mg = 256
 		},
-		.col_pat_field1 = {
-			.olop = CCDC_GREEN_BLUE,
-			.olep = CCDC_BLUE,
-			.elop = CCDC_RED,
-			.elep = CCDC_GREEN_RED
+		.config_params = {
+			.datasft = 2,
+			.mfilt1 = CCDC_NO_MEDIAN_FILTER1,
+			.mfilt2 = CCDC_NO_MEDIAN_FILTER2,
+			.alaw = {
+				.gama_wd = 2,
+			},
+			.blk_clamp = {
+				.sample_pixel = 1,
+				.dc_sub = 25
+			},
+			.col_pat_field0 = {
+				.olop = CCDC_GREEN_BLUE,
+				.olep = CCDC_BLUE,
+				.elop = CCDC_RED,
+				.elep = CCDC_GREEN_RED
+			},
+			.col_pat_field1 = {
+				.olop = CCDC_GREEN_BLUE,
+				.olep = CCDC_BLUE,
+				.elop = CCDC_RED,
+				.elep = CCDC_GREEN_RED
+			},
 		},
 	},
+	/* YCbCr configuration */
+	.ycbcr = {
+		.win = CCDC_WIN_PAL,
+		.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
+		.frm_fmt = CCDC_FRMFMT_INTERLACED,
+		.fid_pol = VPFE_PINPOL_POSITIVE,
+		.vd_pol = VPFE_PINPOL_POSITIVE,
+		.hd_pol = VPFE_PINPOL_POSITIVE,
+		.bt656_enable = 1,
+		.pix_order = CCDC_PIXORDER_CBYCRY,
+		.buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
+	},
 };
 
 
-/* Object for CCDC ycbcr mode */
-static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = {
-	.win = CCDC_WIN_PAL,
-	.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
-	.frm_fmt = CCDC_FRMFMT_INTERLACED,
-	.fid_pol = VPFE_PINPOL_POSITIVE,
-	.vd_pol = VPFE_PINPOL_POSITIVE,
-	.hd_pol = VPFE_PINPOL_POSITIVE,
-	.bt656_enable = 1,
-	.pix_order = CCDC_PIXORDER_CBYCRY,
-	.buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
-};
-
-static enum vpfe_hw_if_type ccdc_if_type;
-static void *__iomem ccdc_base_addr;
-static int ccdc_addr_size;
-
 /* Raw Bayer formats */
 static u32 ccdc_raw_bayer_pix_formats[] =
 		{V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
@@ -118,18 +130,12 @@ static u32 ccdc_raw_yuv_pix_formats[] =
 /* register access routines */
 static inline u32 regr(u32 offset)
 {
-	return __raw_readl(ccdc_base_addr + offset);
+	return __raw_readl(ccdc_cfg.base_addr + offset);
 }
 
 static inline void regw(u32 val, u32 offset)
 {
-	__raw_writel(val, ccdc_base_addr + offset);
-}
-
-static void ccdc_set_ccdc_base(void *addr, int size)
-{
-	ccdc_base_addr = addr;
-	ccdc_addr_size = size;
+	__raw_writel(val, ccdc_cfg.base_addr + offset);
 }
 
 static void ccdc_enable(int en)
@@ -153,12 +159,12 @@ static void ccdc_enable_output_to_sdram(
 static void ccdc_config_gain_offset(void)
 {
 	/* configure gain */
-	regw(ccdc_hw_params_raw.gain.r_ye, RYEGAIN);
-	regw(ccdc_hw_params_raw.gain.gr_cy, GRCYGAIN);
-	regw(ccdc_hw_params_raw.gain.gb_g, GBGGAIN);
-	regw(ccdc_hw_params_raw.gain.b_mg, BMGGAIN);
+	regw(ccdc_cfg.bayer.gain.r_ye, RYEGAIN);
+	regw(ccdc_cfg.bayer.gain.gr_cy, GRCYGAIN);
+	regw(ccdc_cfg.bayer.gain.gb_g, GBGGAIN);
+	regw(ccdc_cfg.bayer.gain.b_mg, BMGGAIN);
 	/* configure offset */
-	regw(ccdc_hw_params_raw.ccdc_offset, OFFSET);
+	regw(ccdc_cfg.bayer.ccdc_offset, OFFSET);
 }
 
 /*
@@ -169,7 +175,7 @@ static int ccdc_restore_defaults(void)
 {
 	int i;
 
-	dev_dbg(dev, "\nstarting ccdc_restore_defaults...");
+	dev_dbg(ccdc_cfg.dev, "\nstarting ccdc_restore_defaults...");
 	/* set all registers to zero */
 	for (i = 0; i <= CCDC_REG_LAST; i += 4)
 		regw(0, i);
@@ -180,30 +186,29 @@ static int ccdc_restore_defaults(void)
 	regw(CULH_DEFAULT, CULH);
 	regw(CULV_DEFAULT, CULV);
 	/* Set default Gain and Offset */
-	ccdc_hw_params_raw.gain.r_ye = GAIN_DEFAULT;
-	ccdc_hw_params_raw.gain.gb_g = GAIN_DEFAULT;
-	ccdc_hw_params_raw.gain.gr_cy = GAIN_DEFAULT;
-	ccdc_hw_params_raw.gain.b_mg = GAIN_DEFAULT;
+	ccdc_cfg.bayer.gain.r_ye = GAIN_DEFAULT;
+	ccdc_cfg.bayer.gain.gb_g = GAIN_DEFAULT;
+	ccdc_cfg.bayer.gain.gr_cy = GAIN_DEFAULT;
+	ccdc_cfg.bayer.gain.b_mg = GAIN_DEFAULT;
 	ccdc_config_gain_offset();
 	regw(OUTCLIP_DEFAULT, OUTCLIP);
 	regw(LSCCFG2_DEFAULT, LSCCFG2);
 	/* select ccdc input */
 	if (vpss_select_ccdc_source(VPSS_CCDCIN)) {
-		dev_dbg(dev, "\ncouldn't select ccdc input source");
+		dev_dbg(ccdc_cfg.dev, "\ncouldn't select ccdc input source");
 		return -EFAULT;
 	}
 	/* select ccdc clock */
 	if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) {
-		dev_dbg(dev, "\ncouldn't enable ccdc clock");
+		dev_dbg(ccdc_cfg.dev, "\ncouldn't enable ccdc clock");
 		return -EFAULT;
 	}
-	dev_dbg(dev, "\nEnd of ccdc_restore_defaults...");
+	dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_restore_defaults...");
 	return 0;
 }
 
 static int ccdc_open(struct device *device)
 {
-	dev = device;
 	return ccdc_restore_defaults();
 }
 
@@ -226,7 +231,7 @@ static void ccdc_setwin(struct v4l2_rect
 	int vert_start, vert_nr_lines;
 	int mid_img = 0;
 
-	dev_dbg(dev, "\nStarting ccdc_setwin...");
+	dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_setwin...");
 
 	/*
 	 * ppc - per pixel count. indicates how many pixels per cell
@@ -260,45 +265,46 @@ static void ccdc_setwin(struct v4l2_rect
 	regw(vert_start & CCDC_START_VER_ONE_MASK, SLV0);
 	regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1);
 	regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV);
-	dev_dbg(dev, "\nEnd of ccdc_setwin...");
+	dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
 }
 
 static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
 {
 	if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT ||
 	    ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) {
-		dev_dbg(dev, "Invalid value of data shift\n");
+		dev_dbg(ccdc_cfg.dev, "Invalid value of data shift\n");
 		return -EINVAL;
 	}
 
 	if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 ||
 	    ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) {
-		dev_dbg(dev, "Invalid value of median filter1\n");
+		dev_dbg(ccdc_cfg.dev, "Invalid value of median filter1\n");
 		return -EINVAL;
 	}
 
 	if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 ||
 	    ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) {
-		dev_dbg(dev, "Invalid value of median filter2\n");
+		dev_dbg(ccdc_cfg.dev, "Invalid value of median filter2\n");
 		return -EINVAL;
 	}
 
 	if ((ccdcparam->med_filt_thres < 0) ||
 	   (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) {
-		dev_dbg(dev, "Invalid value of median filter threshold\n");
+		dev_dbg(ccdc_cfg.dev,
+			"Invalid value of median filter thresold\n");
 		return -EINVAL;
 	}
 
 	if (ccdcparam->data_sz < CCDC_DATA_16BITS ||
 	    ccdcparam->data_sz > CCDC_DATA_8BITS) {
-		dev_dbg(dev, "Invalid value of data size\n");
+		dev_dbg(ccdc_cfg.dev, "Invalid value of data size\n");
 		return -EINVAL;
 	}
 
 	if (ccdcparam->alaw.enable) {
 		if (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_13_4 ||
 		    ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) {
-			dev_dbg(dev, "Invalid value of ALAW\n");
+			dev_dbg(ccdc_cfg.dev, "Invalid value of ALAW\n");
 			return -EINVAL;
 		}
 	}
@@ -306,12 +312,14 @@ static int validate_ccdc_param(struct cc
 	if (ccdcparam->blk_clamp.b_clamp_enable) {
 		if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS ||
 		    ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) {
-			dev_dbg(dev, "Invalid value of sample pixel\n");
+			dev_dbg(ccdc_cfg.dev,
+				"Invalid value of sample pixel\n");
 			return -EINVAL;
 		}
 		if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES ||
 		    ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) {
-			dev_dbg(dev, "Invalid value of sample lines\n");
+			dev_dbg(ccdc_cfg.dev,
+				"Invalid value of sample lines\n");
 			return -EINVAL;
 		}
 	}
@@ -325,18 +333,18 @@ static int ccdc_set_params(void __user *
 	int x;
 
 	/* only raw module parameters can be set through the IOCTL */
-	if (ccdc_if_type != VPFE_RAW_BAYER)
+	if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
 		return -EINVAL;
 
 	x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
 	if (x) {
-		dev_dbg(dev, "ccdc_set_params: error in copying ccdc"
+		dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying ccdc"
 			"params, %d\n", x);
 		return -EFAULT;
 	}
 
 	if (!validate_ccdc_param(&ccdc_raw_params)) {
-		memcpy(&ccdc_hw_params_raw.config_params,
+		memcpy(&ccdc_cfg.bayer.config_params,
 			&ccdc_raw_params,
 			sizeof(ccdc_raw_params));
 		return 0;
@@ -347,11 +355,11 @@ static int ccdc_set_params(void __user *
 /* This function will configure CCDC for YCbCr video capture */
 static void ccdc_config_ycbcr(void)
 {
-	struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr;
+	struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
 	u32 temp;
 
 	/* first set the CCDC power on defaults values in all registers */
-	dev_dbg(dev, "\nStarting ccdc_config_ycbcr...");
+	dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
 	ccdc_restore_defaults();
 
 	/* configure pixel format & video frame format */
@@ -403,7 +411,7 @@ static void ccdc_config_ycbcr(void)
 		regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST);
 	}
 
-	dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n");
+	dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
 }
 
 /*
@@ -483,7 +491,7 @@ int ccdc_write_dfc_entry(int index, stru
 	 */
 
 	if (count) {
-		dev_err(dev, "defect table write timeout !!!\n");
+		dev_err(ccdc_cfg.dev, "defect table write timeout !!!\n");
 		return -1;
 	}
 	return 0;
@@ -605,12 +613,12 @@ static void ccdc_config_color_patterns(s
 /* This function will configure CCDC for Raw mode image capture */
 static int ccdc_config_raw(void)
 {
-	struct ccdc_params_raw *params = &ccdc_hw_params_raw;
+	struct ccdc_params_raw *params = &ccdc_cfg.bayer;
 	struct ccdc_config_params_raw *config_params =
-		&ccdc_hw_params_raw.config_params;
+					&ccdc_cfg.bayer.config_params;
 	unsigned int val;
 
-	dev_dbg(dev, "\nStarting ccdc_config_raw...");
+	dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");
 
 	/* restore power on defaults to register */
 	ccdc_restore_defaults();
@@ -659,7 +667,7 @@ static int ccdc_config_raw(void)
 	val |= (config_params->datasft & CCDC_DATASFT_MASK) <<
 		CCDC_DATASFT_SHIFT;
 	regw(val , MODESET);
-	dev_dbg(dev, "\nWriting 0x%x to MODESET...\n", val);
+	dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to MODESET...\n", val);
 
 	/* Configure the Median Filter threshold */
 	regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT);
@@ -681,7 +689,7 @@ static int ccdc_config_raw(void)
 		(config_params->mfilt2 << CCDC_MFILT2_SHIFT));
 
 	regw(val, GAMMAWD);
-	dev_dbg(dev, "\nWriting 0x%x to GAMMAWD...\n", val);
+	dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to GAMMAWD...\n", val);
 
 	/* configure video window */
 	ccdc_setwin(&params->win, params->frm_fmt, 1);
@@ -706,7 +714,7 @@ static int ccdc_config_raw(void)
 	/* Configure the Gain  & offset control */
 	ccdc_config_gain_offset();
 
-	dev_dbg(dev, "\nWriting %x to COLPTN...\n", val);
+	dev_dbg(ccdc_cfg.dev, "\nWriting %x to COLPTN...\n", val);
 
 	/* Configure DATAOFST  register */
 	val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) <<
@@ -726,7 +734,7 @@ static int ccdc_config_raw(void)
 			CCDC_HSIZE_VAL_MASK;
 
 		/* adjust to multiple of 32 */
-		dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n",
+		dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
 		       (((params->win.width) + 31) >> 5) &
 			CCDC_HSIZE_VAL_MASK);
 	} else {
@@ -734,7 +742,7 @@ static int ccdc_config_raw(void)
 		val |= (((params->win.width * 2) + 31) >> 5) &
 			CCDC_HSIZE_VAL_MASK;
 
-		dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n",
+		dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
 		       (((params->win.width * 2) + 31) >> 5) &
 			CCDC_HSIZE_VAL_MASK);
 	}
@@ -745,34 +753,34 @@ static int ccdc_config_raw(void)
 		if (params->image_invert_enable) {
 			/* For interlace inverse mode */
 			regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST);
-			dev_dbg(dev, "\nWriting %x to SDOFST...\n",
+			dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
 				CCDC_SDOFST_INTERLACE_INVERSE);
 		} else {
 			/* For interlace non inverse mode */
 			regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST);
-			dev_dbg(dev, "\nWriting %x to SDOFST...\n",
+			dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
 				CCDC_SDOFST_INTERLACE_NORMAL);
 		}
 	} else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
 		if (params->image_invert_enable) {
 			/* For progessive inverse mode */
 			regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST);
-			dev_dbg(dev, "\nWriting %x to SDOFST...\n",
+			dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
 				CCDC_SDOFST_PROGRESSIVE_INVERSE);
 		} else {
 			/* For progessive non inverse mode */
 			regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST);
-			dev_dbg(dev, "\nWriting %x to SDOFST...\n",
+			dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
 				CCDC_SDOFST_PROGRESSIVE_NORMAL);
 		}
 	}
-	dev_dbg(dev, "\nend of ccdc_config_raw...");
+	dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
 	return 0;
 }
 
 static int ccdc_configure(void)
 {
-	if (ccdc_if_type == VPFE_RAW_BAYER)
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
 		return ccdc_config_raw();
 	else
 		ccdc_config_ycbcr();
@@ -781,23 +789,23 @@ static int ccdc_configure(void)
 
 static int ccdc_set_buftype(enum ccdc_buftype buf_type)
 {
-	if (ccdc_if_type == VPFE_RAW_BAYER)
-		ccdc_hw_params_raw.buf_type = buf_type;
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+		ccdc_cfg.bayer.buf_type = buf_type;
 	else
-		ccdc_hw_params_ycbcr.buf_type = buf_type;
+		ccdc_cfg.ycbcr.buf_type = buf_type;
 	return 0;
 }
 static enum ccdc_buftype ccdc_get_buftype(void)
 {
-	if (ccdc_if_type == VPFE_RAW_BAYER)
-		return ccdc_hw_params_raw.buf_type;
-	return ccdc_hw_params_ycbcr.buf_type;
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+		return ccdc_cfg.bayer.buf_type;
+	return ccdc_cfg.ycbcr.buf_type;
 }
 
 static int ccdc_enum_pix(u32 *pix, int i)
 {
 	int ret = -EINVAL;
-	if (ccdc_if_type == VPFE_RAW_BAYER) {
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
 		if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
 			*pix = ccdc_raw_bayer_pix_formats[i];
 			ret = 0;
@@ -813,20 +821,19 @@ static int ccdc_enum_pix(u32 *pix, int i
 
 static int ccdc_set_pixel_format(u32 pixfmt)
 {
-	struct ccdc_a_law *alaw =
-		&ccdc_hw_params_raw.config_params.alaw;
+	struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
 
-	if (ccdc_if_type == VPFE_RAW_BAYER) {
-		ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW;
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
+		ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
 		if (pixfmt == V4L2_PIX_FMT_SBGGR8)
 			alaw->enable = 1;
 		else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
 			return -EINVAL;
 	} else {
 		if (pixfmt == V4L2_PIX_FMT_YUYV)
-			ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
+			ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
 		else if (pixfmt == V4L2_PIX_FMT_UYVY)
-			ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
+			ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
 		else
 			return -EINVAL;
 	}
@@ -834,17 +841,16 @@ static int ccdc_set_pixel_format(u32 pix
 }
 static u32 ccdc_get_pixel_format(void)
 {
-	struct ccdc_a_law *alaw =
-		&ccdc_hw_params_raw.config_params.alaw;
+	struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
 	u32 pixfmt;
 
-	if (ccdc_if_type == VPFE_RAW_BAYER)
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
 		if (alaw->enable)
 			pixfmt = V4L2_PIX_FMT_SBGGR8;
 		else
 			pixfmt = V4L2_PIX_FMT_SBGGR16;
 	else {
-		if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
+		if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
 			pixfmt = V4L2_PIX_FMT_YUYV;
 		else
 			pixfmt = V4L2_PIX_FMT_UYVY;
@@ -853,53 +859,53 @@ static u32 ccdc_get_pixel_format(void)
 }
 static int ccdc_set_image_window(struct v4l2_rect *win)
 {
-	if (ccdc_if_type == VPFE_RAW_BAYER)
-		ccdc_hw_params_raw.win = *win;
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+		ccdc_cfg.bayer.win = *win;
 	else
-		ccdc_hw_params_ycbcr.win = *win;
+		ccdc_cfg.ycbcr.win = *win;
 	return 0;
 }
 
 static void ccdc_get_image_window(struct v4l2_rect *win)
 {
-	if (ccdc_if_type == VPFE_RAW_BAYER)
-		*win = ccdc_hw_params_raw.win;
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+		*win = ccdc_cfg.bayer.win;
 	else
-		*win = ccdc_hw_params_ycbcr.win;
+		*win = ccdc_cfg.ycbcr.win;
 }
 
 static unsigned int ccdc_get_line_length(void)
 {
 	struct ccdc_config_params_raw *config_params =
-		&ccdc_hw_params_raw.config_params;
+				&ccdc_cfg.bayer.config_params;
 	unsigned int len;
 
-	if (ccdc_if_type == VPFE_RAW_BAYER) {
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
 		if ((config_params->alaw.enable) ||
 		    (config_params->data_sz == CCDC_DATA_8BITS))
-			len = ccdc_hw_params_raw.win.width;
+			len = ccdc_cfg.bayer.win.width;
 		else
-			len = ccdc_hw_params_raw.win.width * 2;
+			len = ccdc_cfg.bayer.win.width * 2;
 	} else
-		len = ccdc_hw_params_ycbcr.win.width * 2;
+		len = ccdc_cfg.ycbcr.win.width * 2;
 	return ALIGN(len, 32);
 }
 
 static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
 {
-	if (ccdc_if_type == VPFE_RAW_BAYER)
-		ccdc_hw_params_raw.frm_fmt = frm_fmt;
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+		ccdc_cfg.bayer.frm_fmt = frm_fmt;
 	else
-		ccdc_hw_params_ycbcr.frm_fmt = frm_fmt;
+		ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
 	return 0;
 }
 
 static enum ccdc_frmfmt ccdc_get_frame_format(void)
 {
-	if (ccdc_if_type == VPFE_RAW_BAYER)
-		return ccdc_hw_params_raw.frm_fmt;
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+		return ccdc_cfg.bayer.frm_fmt;
 	else
-		return ccdc_hw_params_ycbcr.frm_fmt;
+		return ccdc_cfg.ycbcr.frm_fmt;
 }
 
 static int ccdc_getfid(void)
@@ -916,14 +922,14 @@ static inline void ccdc_setfbaddr(unsign
 
 static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
 {
-	ccdc_if_type = params->if_type;
+	ccdc_cfg.if_type = params->if_type;
 
 	switch (params->if_type) {
 	case VPFE_BT656:
 	case VPFE_YCBCR_SYNC_16:
 	case VPFE_YCBCR_SYNC_8:
-		ccdc_hw_params_ycbcr.vd_pol = params->vdpol;
-		ccdc_hw_params_ycbcr.hd_pol = params->hdpol;
+		ccdc_cfg.ycbcr.vd_pol = params->vdpol;
+		ccdc_cfg.ycbcr.hd_pol = params->hdpol;
 		break;
 	default:
 		/* TODO add support for raw bayer here */
@@ -938,7 +944,6 @@ static struct ccdc_hw_device ccdc_hw_dev
 	.hw_ops = {
 		.open = ccdc_open,
 		.close = ccdc_close,
-		.set_ccdc_base = ccdc_set_ccdc_base,
 		.enable = ccdc_enable,
 		.enable_out_to_sdram = ccdc_enable_output_to_sdram,
 		.set_hw_if_params = ccdc_set_hw_if_params,
@@ -959,19 +964,118 @@ static struct ccdc_hw_device ccdc_hw_dev
 	},
 };
 
-static int __init dm355_ccdc_init(void)
+static int __init dm355_ccdc_probe(struct platform_device *pdev)
 {
-	printk(KERN_NOTICE "dm355_ccdc_init\n");
-	if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0)
-		return -1;
-	printk(KERN_NOTICE "%s is registered with vpfe.\n",
-		ccdc_hw_dev.name);
+	void (*setup_pinmux)(void);
+	struct resource	*res;
+	int status = 0;
+
+	/*
+	 * first try to register with vpfe. If not correct platform, then we
+	 * don't have to iomap
+	 */
+	status = vpfe_register_ccdc_device(&ccdc_hw_dev);
+	if (status < 0)
+		return status;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		status = -ENODEV;
+		goto fail_nores;
+	}
+
+	res = request_mem_region(res->start, resource_size(res), res->name);
+	if (!res) {
+		status = -EBUSY;
+		goto fail_nores;
+	}
+
+	ccdc_cfg.base_addr = ioremap_nocache(res->start, resource_size(res));
+	if (!ccdc_cfg.base_addr) {
+		status = -ENOMEM;
+		goto fail_nomem;
+	}
+
+	/* Get and enable Master clock */
+	ccdc_cfg.mclk = clk_get(&pdev->dev, "master");
+	if (IS_ERR(ccdc_cfg.mclk)) {
+		status = PTR_ERR(ccdc_cfg.mclk);
+		goto fail_nomap;
+	}
+	if (clk_enable(ccdc_cfg.mclk)) {
+		status = -ENODEV;
+		goto fail_mclk;
+	}
+
+	/* Get and enable Slave clock */
+	ccdc_cfg.sclk = clk_get(&pdev->dev, "slave");
+	if (IS_ERR(ccdc_cfg.sclk)) {
+		status = PTR_ERR(ccdc_cfg.sclk);
+		goto fail_mclk;
+	}
+	if (clk_enable(ccdc_cfg.sclk)) {
+		status = -ENODEV;
+		goto fail_sclk;
+	}
+
+	/* Platform data holds setup_pinmux function ptr */
+	if (NULL == pdev->dev.platform_data) {
+		status = -ENODEV;
+		goto fail_sclk;
+	}
+	setup_pinmux = pdev->dev.platform_data;
+	/*
+	 * setup Mux configuration for ccdc which may be different for
+	 * different SoCs using this CCDC
+	 */
+	setup_pinmux();
+	ccdc_cfg.dev = &pdev->dev;
+	printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
 	return 0;
+fail_sclk:
+	clk_put(ccdc_cfg.sclk);
+fail_mclk:
+	clk_put(ccdc_cfg.mclk);
+fail_nomap:
+	iounmap(ccdc_cfg.base_addr);
+fail_nomem:
+	release_mem_region(res->start, resource_size(res));
+fail_nores:
+	vpfe_unregister_ccdc_device(&ccdc_hw_dev);
+	return status;
 }
 
-static void __exit dm355_ccdc_exit(void)
+static int dm355_ccdc_remove(struct platform_device *pdev)
 {
+	struct resource	*res;
+
+	clk_put(ccdc_cfg.mclk);
+	clk_put(ccdc_cfg.sclk);
+	iounmap(ccdc_cfg.base_addr);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res)
+		release_mem_region(res->start, resource_size(res));
 	vpfe_unregister_ccdc_device(&ccdc_hw_dev);
+	return 0;
+}
+
+static struct platform_driver dm355_ccdc_driver = {
+	.driver = {
+		.name	= "dm355_ccdc",
+		.owner = THIS_MODULE,
+	},
+	.remove = __devexit_p(dm355_ccdc_remove),
+	.probe = dm355_ccdc_probe,
+};
+
+static int __init dm355_ccdc_init(void)
+{
+	return platform_driver_register(&dm355_ccdc_driver);
+}
+
+static void __exit dm355_ccdc_exit(void)
+{
+	platform_driver_unregister(&dm355_ccdc_driver);
 }
 
 module_init(dm355_ccdc_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/davinci/dm644x_ccdc.c linux-libre-2.6.34-gnu1/drivers/media/video/davinci/dm644x_ccdc.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/davinci/dm644x_ccdc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/davinci/dm644x_ccdc.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,8 +37,13 @@
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
 #include <linux/videodev2.h>
+#include <linux/gfp.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
 #include <media/davinci/dm644x_ccdc.h>
 #include <media/davinci/vpss.h>
+
 #include "dm644x_ccdc_regs.h"
 #include "ccdc_hw_device.h"
 
@@ -46,32 +51,44 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("CCDC Driver for DM6446");
 MODULE_AUTHOR("Texas Instruments");
 
-static struct device *dev;
-
-/* Object for CCDC raw mode */
-static struct ccdc_params_raw ccdc_hw_params_raw = {
-	.pix_fmt = CCDC_PIXFMT_RAW,
-	.frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
-	.win = CCDC_WIN_VGA,
-	.fid_pol = VPFE_PINPOL_POSITIVE,
-	.vd_pol = VPFE_PINPOL_POSITIVE,
-	.hd_pol = VPFE_PINPOL_POSITIVE,
-	.config_params = {
-		.data_sz = CCDC_DATA_10BITS,
+static struct ccdc_oper_config {
+	struct device *dev;
+	/* CCDC interface type */
+	enum vpfe_hw_if_type if_type;
+	/* Raw Bayer configuration */
+	struct ccdc_params_raw bayer;
+	/* YCbCr configuration */
+	struct ccdc_params_ycbcr ycbcr;
+	/* Master clock */
+	struct clk *mclk;
+	/* slave clock */
+	struct clk *sclk;
+	/* ccdc base address */
+	void __iomem *base_addr;
+} ccdc_cfg = {
+	/* Raw configurations */
+	.bayer = {
+		.pix_fmt = CCDC_PIXFMT_RAW,
+		.frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
+		.win = CCDC_WIN_VGA,
+		.fid_pol = VPFE_PINPOL_POSITIVE,
+		.vd_pol = VPFE_PINPOL_POSITIVE,
+		.hd_pol = VPFE_PINPOL_POSITIVE,
+		.config_params = {
+			.data_sz = CCDC_DATA_10BITS,
+		},
+	},
+	.ycbcr = {
+		.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
+		.frm_fmt = CCDC_FRMFMT_INTERLACED,
+		.win = CCDC_WIN_PAL,
+		.fid_pol = VPFE_PINPOL_POSITIVE,
+		.vd_pol = VPFE_PINPOL_POSITIVE,
+		.hd_pol = VPFE_PINPOL_POSITIVE,
+		.bt656_enable = 1,
+		.pix_order = CCDC_PIXORDER_CBYCRY,
+		.buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
 	},
-};
-
-/* Object for CCDC ycbcr mode */
-static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = {
-	.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
-	.frm_fmt = CCDC_FRMFMT_INTERLACED,
-	.win = CCDC_WIN_PAL,
-	.fid_pol = VPFE_PINPOL_POSITIVE,
-	.vd_pol = VPFE_PINPOL_POSITIVE,
-	.hd_pol = VPFE_PINPOL_POSITIVE,
-	.bt656_enable = 1,
-	.pix_order = CCDC_PIXORDER_CBYCRY,
-	.buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
 };
 
 #define CCDC_MAX_RAW_YUV_FORMATS	2
@@ -84,25 +101,15 @@ static u32 ccdc_raw_bayer_pix_formats[]
 static u32 ccdc_raw_yuv_pix_formats[] =
 	{V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
 
-static void *__iomem ccdc_base_addr;
-static int ccdc_addr_size;
-static enum vpfe_hw_if_type ccdc_if_type;
-
 /* register access routines */
 static inline u32 regr(u32 offset)
 {
-	return __raw_readl(ccdc_base_addr + offset);
+	return __raw_readl(ccdc_cfg.base_addr + offset);
 }
 
 static inline void regw(u32 val, u32 offset)
 {
-	__raw_writel(val, ccdc_base_addr + offset);
-}
-
-static void ccdc_set_ccdc_base(void *addr, int size)
-{
-	ccdc_base_addr = addr;
-	ccdc_addr_size = size;
+	__raw_writel(val, ccdc_cfg.base_addr + offset);
 }
 
 static void ccdc_enable(int flag)
@@ -132,7 +139,7 @@ void ccdc_setwin(struct v4l2_rect *image
 	int vert_start, vert_nr_lines;
 	int val = 0, mid_img = 0;
 
-	dev_dbg(dev, "\nStarting ccdc_setwin...");
+	dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_setwin...");
 	/*
 	 * ppc - per pixel count. indicates how many pixels per cell
 	 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
@@ -171,7 +178,7 @@ void ccdc_setwin(struct v4l2_rect *image
 	regw((vert_start << CCDC_VERT_START_SLV0_SHIFT) | vert_start,
 	     CCDC_VERT_START);
 	regw(vert_nr_lines, CCDC_VERT_LINES);
-	dev_dbg(dev, "\nEnd of ccdc_setwin...");
+	dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
 }
 
 static void ccdc_readregs(void)
@@ -179,39 +186,39 @@ static void ccdc_readregs(void)
 	unsigned int val = 0;
 
 	val = regr(CCDC_ALAW);
-	dev_notice(dev, "\nReading 0x%x to ALAW...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to ALAW...\n", val);
 	val = regr(CCDC_CLAMP);
-	dev_notice(dev, "\nReading 0x%x to CLAMP...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to CLAMP...\n", val);
 	val = regr(CCDC_DCSUB);
-	dev_notice(dev, "\nReading 0x%x to DCSUB...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to DCSUB...\n", val);
 	val = regr(CCDC_BLKCMP);
-	dev_notice(dev, "\nReading 0x%x to BLKCMP...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to BLKCMP...\n", val);
 	val = regr(CCDC_FPC_ADDR);
-	dev_notice(dev, "\nReading 0x%x to FPC_ADDR...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FPC_ADDR...\n", val);
 	val = regr(CCDC_FPC);
-	dev_notice(dev, "\nReading 0x%x to FPC...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FPC...\n", val);
 	val = regr(CCDC_FMTCFG);
-	dev_notice(dev, "\nReading 0x%x to FMTCFG...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMTCFG...\n", val);
 	val = regr(CCDC_COLPTN);
-	dev_notice(dev, "\nReading 0x%x to COLPTN...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to COLPTN...\n", val);
 	val = regr(CCDC_FMT_HORZ);
-	dev_notice(dev, "\nReading 0x%x to FMT_HORZ...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMT_HORZ...\n", val);
 	val = regr(CCDC_FMT_VERT);
-	dev_notice(dev, "\nReading 0x%x to FMT_VERT...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMT_VERT...\n", val);
 	val = regr(CCDC_HSIZE_OFF);
-	dev_notice(dev, "\nReading 0x%x to HSIZE_OFF...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to HSIZE_OFF...\n", val);
 	val = regr(CCDC_SDOFST);
-	dev_notice(dev, "\nReading 0x%x to SDOFST...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to SDOFST...\n", val);
 	val = regr(CCDC_VP_OUT);
-	dev_notice(dev, "\nReading 0x%x to VP_OUT...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VP_OUT...\n", val);
 	val = regr(CCDC_SYN_MODE);
-	dev_notice(dev, "\nReading 0x%x to SYN_MODE...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to SYN_MODE...\n", val);
 	val = regr(CCDC_HORZ_INFO);
-	dev_notice(dev, "\nReading 0x%x to HORZ_INFO...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to HORZ_INFO...\n", val);
 	val = regr(CCDC_VERT_START);
-	dev_notice(dev, "\nReading 0x%x to VERT_START...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_START...\n", val);
 	val = regr(CCDC_VERT_LINES);
-	dev_notice(dev, "\nReading 0x%x to VERT_LINES...\n", val);
+	dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_LINES...\n", val);
 }
 
 static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
@@ -220,7 +227,7 @@ static int validate_ccdc_param(struct cc
 		if ((ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) ||
 		    (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_15_6) ||
 		    (ccdcparam->alaw.gama_wd < ccdcparam->data_sz)) {
-			dev_dbg(dev, "\nInvalid data line select");
+			dev_dbg(ccdc_cfg.dev, "\nInvalid data line select");
 			return -1;
 		}
 	}
@@ -230,7 +237,7 @@ static int validate_ccdc_param(struct cc
 static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
 {
 	struct ccdc_config_params_raw *config_params =
-		&ccdc_hw_params_raw.config_params;
+				&ccdc_cfg.bayer.config_params;
 	unsigned int *fpc_virtaddr = NULL;
 	unsigned int *fpc_physaddr = NULL;
 
@@ -266,7 +273,7 @@ static int ccdc_update_raw_params(struct
 							 FP_NUM_BYTES));
 
 		if (fpc_virtaddr == NULL) {
-			dev_dbg(dev,
+			dev_dbg(ccdc_cfg.dev,
 				"\nUnable to allocate memory for FPC");
 			return -EFAULT;
 		}
@@ -279,7 +286,7 @@ static int ccdc_update_raw_params(struct
 	if (copy_from_user(fpc_virtaddr,
 			(void __user *)raw_params->fault_pxl.fpc_table_addr,
 			config_params->fault_pxl.fp_num * FP_NUM_BYTES)) {
-		dev_dbg(dev, "\n copy_from_user failed");
+		dev_dbg(ccdc_cfg.dev, "\n copy_from_user failed");
 		return -EFAULT;
 	}
 	config_params->fault_pxl.fpc_table_addr = (unsigned int)fpc_physaddr;
@@ -289,7 +296,7 @@ static int ccdc_update_raw_params(struct
 static int ccdc_close(struct device *dev)
 {
 	struct ccdc_config_params_raw *config_params =
-		&ccdc_hw_params_raw.config_params;
+				&ccdc_cfg.bayer.config_params;
 	unsigned int *fpc_physaddr = NULL, *fpc_virtaddr = NULL;
 
 	fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr;
@@ -323,9 +330,8 @@ static void ccdc_restore_defaults(void)
 
 static int ccdc_open(struct device *device)
 {
-	dev = device;
 	ccdc_restore_defaults();
-	if (ccdc_if_type == VPFE_RAW_BAYER)
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
 		ccdc_enable_vport(1);
 	return 0;
 }
@@ -341,12 +347,12 @@ static int ccdc_set_params(void __user *
 	struct ccdc_config_params_raw ccdc_raw_params;
 	int x;
 
-	if (ccdc_if_type != VPFE_RAW_BAYER)
+	if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
 		return -EINVAL;
 
 	x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
 	if (x) {
-		dev_dbg(dev, "ccdc_set_params: error in copying"
+		dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying"
 			   "ccdc params, %d\n", x);
 		return -EFAULT;
 	}
@@ -364,10 +370,10 @@ static int ccdc_set_params(void __user *
  */
 void ccdc_config_ycbcr(void)
 {
-	struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr;
+	struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
 	u32 syn_mode;
 
-	dev_dbg(dev, "\nStarting ccdc_config_ycbcr...");
+	dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
 	/*
 	 * first restore the CCDC registers to default values
 	 * This is important since we assume default values to be set in
@@ -428,7 +434,7 @@ void ccdc_config_ycbcr(void)
 		regw(CCDC_SDOFST_FIELD_INTERLEAVED, CCDC_SDOFST);
 
 	ccdc_sbl_reset();
-	dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n");
+	dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
 	ccdc_readregs();
 }
 
@@ -440,9 +446,9 @@ static void ccdc_config_black_clamp(stru
 		/* configure DCSub */
 		val = (bclamp->dc_sub) & CCDC_BLK_DC_SUB_MASK;
 		regw(val, CCDC_DCSUB);
-		dev_dbg(dev, "\nWriting 0x%x to DCSUB...\n", val);
+		dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to DCSUB...\n", val);
 		regw(CCDC_CLAMP_DEFAULT_VAL, CCDC_CLAMP);
-		dev_dbg(dev, "\nWriting 0x0000 to CLAMP...\n");
+		dev_dbg(ccdc_cfg.dev, "\nWriting 0x0000 to CLAMP...\n");
 		return;
 	}
 	/*
@@ -457,10 +463,10 @@ static void ccdc_config_black_clamp(stru
 	       ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
 		CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE);
 	regw(val, CCDC_CLAMP);
-	dev_dbg(dev, "\nWriting 0x%x to CLAMP...\n", val);
+	dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to CLAMP...\n", val);
 	/* If Black clamping is enable then make dcsub 0 */
 	regw(CCDC_DCSUB_DEFAULT_VAL, CCDC_DCSUB);
-	dev_dbg(dev, "\nWriting 0x00000000 to DCSUB...\n");
+	dev_dbg(ccdc_cfg.dev, "\nWriting 0x00000000 to DCSUB...\n");
 }
 
 static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
@@ -490,17 +496,17 @@ static void ccdc_config_fpc(struct ccdc_
 
 	/* Configure Fault pixel if needed */
 	regw(fpc->fpc_table_addr, CCDC_FPC_ADDR);
-	dev_dbg(dev, "\nWriting 0x%x to FPC_ADDR...\n",
+	dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC_ADDR...\n",
 		       (fpc->fpc_table_addr));
 	/* Write the FPC params with FPC disable */
 	val = fpc->fp_num & CCDC_FPC_FPC_NUM_MASK;
 	regw(val, CCDC_FPC);
 
-	dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val);
+	dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC...\n", val);
 	/* read the FPC register */
 	val = regr(CCDC_FPC) | CCDC_FPC_ENABLE;
 	regw(val, CCDC_FPC);
-	dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val);
+	dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC...\n", val);
 }
 
 /*
@@ -509,13 +515,13 @@ static void ccdc_config_fpc(struct ccdc_
  */
 void ccdc_config_raw(void)
 {
-	struct ccdc_params_raw *params = &ccdc_hw_params_raw;
+	struct ccdc_params_raw *params = &ccdc_cfg.bayer;
 	struct ccdc_config_params_raw *config_params =
-		&ccdc_hw_params_raw.config_params;
+				&ccdc_cfg.bayer.config_params;
 	unsigned int syn_mode = 0;
 	unsigned int val;
 
-	dev_dbg(dev, "\nStarting ccdc_config_raw...");
+	dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");
 
 	/*      Reset CCDC */
 	ccdc_restore_defaults();
@@ -545,7 +551,7 @@ void ccdc_config_raw(void)
 		val = ((config_params->alaw.gama_wd &
 		      CCDC_ALAW_GAMA_WD_MASK) | CCDC_ALAW_ENABLE);
 		regw(val, CCDC_ALAW);
-		dev_dbg(dev, "\nWriting 0x%x to ALAW...\n", val);
+		dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to ALAW...\n", val);
 	}
 
 	/* Configure video window */
@@ -582,11 +588,11 @@ void ccdc_config_raw(void)
 	/* Write value in FMTCFG */
 	regw(val, CCDC_FMTCFG);
 
-	dev_dbg(dev, "\nWriting 0x%x to FMTCFG...\n", val);
+	dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMTCFG...\n", val);
 	/* Configure the color pattern according to mt9t001 sensor */
 	regw(CCDC_COLPTN_VAL, CCDC_COLPTN);
 
-	dev_dbg(dev, "\nWriting 0xBB11BB11 to COLPTN...\n");
+	dev_dbg(ccdc_cfg.dev, "\nWriting 0xBB11BB11 to COLPTN...\n");
 	/*
 	 * Configure Data formatter(Video port) pixel selection
 	 * (FMT_HORZ, FMT_VERT)
@@ -596,7 +602,7 @@ void ccdc_config_raw(void)
 	      (params->win.width & CCDC_FMT_HORZ_FMTLNH_MASK);
 	regw(val, CCDC_FMT_HORZ);
 
-	dev_dbg(dev, "\nWriting 0x%x to FMT_HORZ...\n", val);
+	dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMT_HORZ...\n", val);
 	val = (params->win.top & CCDC_FMT_VERT_FMTSLV_MASK)
 	    << CCDC_FMT_VERT_FMTSLV_SHIFT;
 	if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
@@ -604,13 +610,13 @@ void ccdc_config_raw(void)
 	else
 		val |= (params->win.height >> 1) & CCDC_FMT_VERT_FMTLNV_MASK;
 
-	dev_dbg(dev, "\nparams->win.height  0x%x ...\n",
+	dev_dbg(ccdc_cfg.dev, "\nparams->win.height  0x%x ...\n",
 	       params->win.height);
 	regw(val, CCDC_FMT_VERT);
 
-	dev_dbg(dev, "\nWriting 0x%x to FMT_VERT...\n", val);
+	dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMT_VERT...\n", val);
 
-	dev_dbg(dev, "\nbelow regw(val, FMT_VERT)...");
+	dev_dbg(ccdc_cfg.dev, "\nbelow regw(val, FMT_VERT)...");
 
 	/*
 	 * Configure Horizontal offset register. If pack 8 is enabled then
@@ -631,17 +637,17 @@ void ccdc_config_raw(void)
 		if (params->image_invert_enable) {
 			/* For intelace inverse mode */
 			regw(CCDC_INTERLACED_IMAGE_INVERT, CCDC_SDOFST);
-			dev_dbg(dev, "\nWriting 0x4B6D to SDOFST...\n");
+			dev_dbg(ccdc_cfg.dev, "\nWriting 0x4B6D to SDOFST..\n");
 		}
 
 		else {
 			/* For intelace non inverse mode */
 			regw(CCDC_INTERLACED_NO_IMAGE_INVERT, CCDC_SDOFST);
-			dev_dbg(dev, "\nWriting 0x0249 to SDOFST...\n");
+			dev_dbg(ccdc_cfg.dev, "\nWriting 0x0249 to SDOFST..\n");
 		}
 	} else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
 		regw(CCDC_PROGRESSIVE_NO_IMAGE_INVERT, CCDC_SDOFST);
-		dev_dbg(dev, "\nWriting 0x0000 to SDOFST...\n");
+		dev_dbg(ccdc_cfg.dev, "\nWriting 0x0000 to SDOFST...\n");
 	}
 
 	/*
@@ -662,18 +668,18 @@ void ccdc_config_raw(void)
 	val |= (params->win.left) & CCDC_VP_OUT_HORZ_ST_MASK;
 	regw(val, CCDC_VP_OUT);
 
-	dev_dbg(dev, "\nWriting 0x%x to VP_OUT...\n", val);
+	dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to VP_OUT...\n", val);
 	regw(syn_mode, CCDC_SYN_MODE);
-	dev_dbg(dev, "\nWriting 0x%x to SYN_MODE...\n", syn_mode);
+	dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to SYN_MODE...\n", syn_mode);
 
 	ccdc_sbl_reset();
-	dev_dbg(dev, "\nend of ccdc_config_raw...");
+	dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
 	ccdc_readregs();
 }
 
 static int ccdc_configure(void)
 {
-	if (ccdc_if_type == VPFE_RAW_BAYER)
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
 		ccdc_config_raw();
 	else
 		ccdc_config_ycbcr();
@@ -682,24 +688,24 @@ static int ccdc_configure(void)
 
 static int ccdc_set_buftype(enum ccdc_buftype buf_type)
 {
-	if (ccdc_if_type == VPFE_RAW_BAYER)
-		ccdc_hw_params_raw.buf_type = buf_type;
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+		ccdc_cfg.bayer.buf_type = buf_type;
 	else
-		ccdc_hw_params_ycbcr.buf_type = buf_type;
+		ccdc_cfg.ycbcr.buf_type = buf_type;
 	return 0;
 }
 
 static enum ccdc_buftype ccdc_get_buftype(void)
 {
-	if (ccdc_if_type == VPFE_RAW_BAYER)
-		return ccdc_hw_params_raw.buf_type;
-	return ccdc_hw_params_ycbcr.buf_type;
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+		return ccdc_cfg.bayer.buf_type;
+	return ccdc_cfg.ycbcr.buf_type;
 }
 
 static int ccdc_enum_pix(u32 *pix, int i)
 {
 	int ret = -EINVAL;
-	if (ccdc_if_type == VPFE_RAW_BAYER) {
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
 		if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
 			*pix = ccdc_raw_bayer_pix_formats[i];
 			ret = 0;
@@ -715,17 +721,17 @@ static int ccdc_enum_pix(u32 *pix, int i
 
 static int ccdc_set_pixel_format(u32 pixfmt)
 {
-	if (ccdc_if_type == VPFE_RAW_BAYER) {
-		ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW;
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
+		ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
 		if (pixfmt == V4L2_PIX_FMT_SBGGR8)
-			ccdc_hw_params_raw.config_params.alaw.enable = 1;
+			ccdc_cfg.bayer.config_params.alaw.enable = 1;
 		else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
 			return -EINVAL;
 	} else {
 		if (pixfmt == V4L2_PIX_FMT_YUYV)
-			ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
+			ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
 		else if (pixfmt == V4L2_PIX_FMT_UYVY)
-			ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
+			ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
 		else
 			return -EINVAL;
 	}
@@ -734,17 +740,16 @@ static int ccdc_set_pixel_format(u32 pix
 
 static u32 ccdc_get_pixel_format(void)
 {
-	struct ccdc_a_law *alaw =
-		&ccdc_hw_params_raw.config_params.alaw;
+	struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
 	u32 pixfmt;
 
-	if (ccdc_if_type == VPFE_RAW_BAYER)
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
 		if (alaw->enable)
 			pixfmt = V4L2_PIX_FMT_SBGGR8;
 		else
 			pixfmt = V4L2_PIX_FMT_SBGGR16;
 	else {
-		if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
+		if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
 			pixfmt = V4L2_PIX_FMT_YUYV;
 		else
 			pixfmt = V4L2_PIX_FMT_UYVY;
@@ -754,53 +759,53 @@ static u32 ccdc_get_pixel_format(void)
 
 static int ccdc_set_image_window(struct v4l2_rect *win)
 {
-	if (ccdc_if_type == VPFE_RAW_BAYER)
-		ccdc_hw_params_raw.win = *win;
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+		ccdc_cfg.bayer.win = *win;
 	else
-		ccdc_hw_params_ycbcr.win = *win;
+		ccdc_cfg.ycbcr.win = *win;
 	return 0;
 }
 
 static void ccdc_get_image_window(struct v4l2_rect *win)
 {
-	if (ccdc_if_type == VPFE_RAW_BAYER)
-		*win = ccdc_hw_params_raw.win;
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+		*win = ccdc_cfg.bayer.win;
 	else
-		*win = ccdc_hw_params_ycbcr.win;
+		*win = ccdc_cfg.ycbcr.win;
 }
 
 static unsigned int ccdc_get_line_length(void)
 {
 	struct ccdc_config_params_raw *config_params =
-		&ccdc_hw_params_raw.config_params;
+				&ccdc_cfg.bayer.config_params;
 	unsigned int len;
 
-	if (ccdc_if_type == VPFE_RAW_BAYER) {
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
 		if ((config_params->alaw.enable) ||
 		    (config_params->data_sz == CCDC_DATA_8BITS))
-			len = ccdc_hw_params_raw.win.width;
+			len = ccdc_cfg.bayer.win.width;
 		else
-			len = ccdc_hw_params_raw.win.width * 2;
+			len = ccdc_cfg.bayer.win.width * 2;
 	} else
-		len = ccdc_hw_params_ycbcr.win.width * 2;
+		len = ccdc_cfg.ycbcr.win.width * 2;
 	return ALIGN(len, 32);
 }
 
 static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
 {
-	if (ccdc_if_type == VPFE_RAW_BAYER)
-		ccdc_hw_params_raw.frm_fmt = frm_fmt;
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+		ccdc_cfg.bayer.frm_fmt = frm_fmt;
 	else
-		ccdc_hw_params_ycbcr.frm_fmt = frm_fmt;
+		ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
 	return 0;
 }
 
 static enum ccdc_frmfmt ccdc_get_frame_format(void)
 {
-	if (ccdc_if_type == VPFE_RAW_BAYER)
-		return ccdc_hw_params_raw.frm_fmt;
+	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+		return ccdc_cfg.bayer.frm_fmt;
 	else
-		return ccdc_hw_params_ycbcr.frm_fmt;
+		return ccdc_cfg.ycbcr.frm_fmt;
 }
 
 static int ccdc_getfid(void)
@@ -816,14 +821,14 @@ static inline void ccdc_setfbaddr(unsign
 
 static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
 {
-	ccdc_if_type = params->if_type;
+	ccdc_cfg.if_type = params->if_type;
 
 	switch (params->if_type) {
 	case VPFE_BT656:
 	case VPFE_YCBCR_SYNC_16:
 	case VPFE_YCBCR_SYNC_8:
-		ccdc_hw_params_ycbcr.vd_pol = params->vdpol;
-		ccdc_hw_params_ycbcr.hd_pol = params->hdpol;
+		ccdc_cfg.ycbcr.vd_pol = params->vdpol;
+		ccdc_cfg.ycbcr.hd_pol = params->hdpol;
 		break;
 	default:
 		/* TODO add support for raw bayer here */
@@ -838,7 +843,6 @@ static struct ccdc_hw_device ccdc_hw_dev
 	.hw_ops = {
 		.open = ccdc_open,
 		.close = ccdc_close,
-		.set_ccdc_base = ccdc_set_ccdc_base,
 		.reset = ccdc_sbl_reset,
 		.enable = ccdc_enable,
 		.set_hw_if_params = ccdc_set_hw_if_params,
@@ -859,19 +863,105 @@ static struct ccdc_hw_device ccdc_hw_dev
 	},
 };
 
-static int __init dm644x_ccdc_init(void)
+static int __init dm644x_ccdc_probe(struct platform_device *pdev)
 {
-	printk(KERN_NOTICE "dm644x_ccdc_init\n");
-	if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0)
-		return -1;
-	printk(KERN_NOTICE "%s is registered with vpfe.\n",
-		ccdc_hw_dev.name);
+	struct resource	*res;
+	int status = 0;
+
+	/*
+	 * first try to register with vpfe. If not correct platform, then we
+	 * don't have to iomap
+	 */
+	status = vpfe_register_ccdc_device(&ccdc_hw_dev);
+	if (status < 0)
+		return status;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		status = -ENODEV;
+		goto fail_nores;
+	}
+
+	res = request_mem_region(res->start, resource_size(res), res->name);
+	if (!res) {
+		status = -EBUSY;
+		goto fail_nores;
+	}
+
+	ccdc_cfg.base_addr = ioremap_nocache(res->start, resource_size(res));
+	if (!ccdc_cfg.base_addr) {
+		status = -ENOMEM;
+		goto fail_nomem;
+	}
+
+	/* Get and enable Master clock */
+	ccdc_cfg.mclk = clk_get(&pdev->dev, "master");
+	if (IS_ERR(ccdc_cfg.mclk)) {
+		status = PTR_ERR(ccdc_cfg.mclk);
+		goto fail_nomap;
+	}
+	if (clk_enable(ccdc_cfg.mclk)) {
+		status = -ENODEV;
+		goto fail_mclk;
+	}
+
+	/* Get and enable Slave clock */
+	ccdc_cfg.sclk = clk_get(&pdev->dev, "slave");
+	if (IS_ERR(ccdc_cfg.sclk)) {
+		status = PTR_ERR(ccdc_cfg.sclk);
+		goto fail_mclk;
+	}
+	if (clk_enable(ccdc_cfg.sclk)) {
+		status = -ENODEV;
+		goto fail_sclk;
+	}
+	ccdc_cfg.dev = &pdev->dev;
+	printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
 	return 0;
+fail_sclk:
+	clk_put(ccdc_cfg.sclk);
+fail_mclk:
+	clk_put(ccdc_cfg.mclk);
+fail_nomap:
+	iounmap(ccdc_cfg.base_addr);
+fail_nomem:
+	release_mem_region(res->start, resource_size(res));
+fail_nores:
+	vpfe_unregister_ccdc_device(&ccdc_hw_dev);
+	return status;
 }
 
-static void __exit dm644x_ccdc_exit(void)
+static int dm644x_ccdc_remove(struct platform_device *pdev)
 {
+	struct resource	*res;
+
+	clk_put(ccdc_cfg.mclk);
+	clk_put(ccdc_cfg.sclk);
+	iounmap(ccdc_cfg.base_addr);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res)
+		release_mem_region(res->start, resource_size(res));
 	vpfe_unregister_ccdc_device(&ccdc_hw_dev);
+	return 0;
+}
+
+static struct platform_driver dm644x_ccdc_driver = {
+	.driver = {
+		.name	= "dm644x_ccdc",
+		.owner = THIS_MODULE,
+	},
+	.remove = __devexit_p(dm644x_ccdc_remove),
+	.probe = dm644x_ccdc_probe,
+};
+
+static int __init dm644x_ccdc_init(void)
+{
+	return platform_driver_register(&dm644x_ccdc_driver);
+}
+
+static void __exit dm644x_ccdc_exit(void)
+{
+	platform_driver_unregister(&dm644x_ccdc_driver);
 }
 
 module_init(dm644x_ccdc_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/davinci/isif.c linux-libre-2.6.34-gnu1/drivers/media/video/davinci/isif.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/davinci/isif.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/davinci/isif.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1172 @@
+/*
+ * Copyright (C) 2008-2009 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ *
+ * Image Sensor Interface (ISIF) driver
+ *
+ * This driver is for configuring the ISIF IP available on DM365 or any other
+ * TI SoCs. This is used for capturing yuv or bayer video or image data
+ * from a decoder or sensor. This IP is similar to the CCDC IP on DM355
+ * and DM6446, but with enhanced or additional ip blocks. The driver
+ * configures the ISIF upon commands from the vpfe bridge driver through
+ * ccdc_hw_device interface.
+ *
+ * TODO: 1) Raw bayer parameter settings and bayer capture
+ *	 2) Add support for control ioctl
+ */
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/videodev2.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <mach/mux.h>
+
+#include <media/davinci/isif.h>
+#include <media/davinci/vpss.h>
+
+#include "isif_regs.h"
+#include "ccdc_hw_device.h"
+
+/* Defaults for module configuration parameters */
+static struct isif_config_params_raw isif_config_defaults = {
+	.linearize = {
+		.en = 0,
+		.corr_shft = ISIF_NO_SHIFT,
+		.scale_fact = {1, 0},
+	},
+	.df_csc = {
+		.df_or_csc = 0,
+		.csc = {
+			.en = 0,
+		},
+	},
+	.dfc = {
+		.en = 0,
+	},
+	.bclamp = {
+		.en = 0,
+	},
+	.gain_offset = {
+		.gain = {
+			.r_ye = {1, 0},
+			.gr_cy = {1, 0},
+			.gb_g = {1, 0},
+			.b_mg = {1, 0},
+		},
+	},
+	.culling = {
+		.hcpat_odd = 0xff,
+		.hcpat_even = 0xff,
+		.vcpat = 0xff,
+	},
+	.compress = {
+		.alg = ISIF_ALAW,
+	},
+};
+
+/* ISIF operation configuration */
+static struct isif_oper_config {
+	struct device *dev;
+	enum vpfe_hw_if_type if_type;
+	struct isif_ycbcr_config ycbcr;
+	struct isif_params_raw bayer;
+	enum isif_data_pack data_pack;
+	/* Master clock */
+	struct clk *mclk;
+	/* ISIF base address */
+	void __iomem *base_addr;
+	/* ISIF Linear Table 0 */
+	void __iomem *linear_tbl0_addr;
+	/* ISIF Linear Table 1 */
+	void __iomem *linear_tbl1_addr;
+} isif_cfg = {
+	.ycbcr = {
+		.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
+		.frm_fmt = CCDC_FRMFMT_INTERLACED,
+		.win = ISIF_WIN_NTSC,
+		.fid_pol = VPFE_PINPOL_POSITIVE,
+		.vd_pol = VPFE_PINPOL_POSITIVE,
+		.hd_pol = VPFE_PINPOL_POSITIVE,
+		.pix_order = CCDC_PIXORDER_CBYCRY,
+		.buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED,
+	},
+	.bayer = {
+		.pix_fmt = CCDC_PIXFMT_RAW,
+		.frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
+		.win = ISIF_WIN_VGA,
+		.fid_pol = VPFE_PINPOL_POSITIVE,
+		.vd_pol = VPFE_PINPOL_POSITIVE,
+		.hd_pol = VPFE_PINPOL_POSITIVE,
+		.gain = {
+			.r_ye = {1, 0},
+			.gr_cy = {1, 0},
+			.gb_g = {1, 0},
+			.b_mg = {1, 0},
+		},
+		.cfa_pat = ISIF_CFA_PAT_MOSAIC,
+		.data_msb = ISIF_BIT_MSB_11,
+		.config_params = {
+			.data_shift = ISIF_NO_SHIFT,
+			.col_pat_field0 = {
+				.olop = ISIF_GREEN_BLUE,
+				.olep = ISIF_BLUE,
+				.elop = ISIF_RED,
+				.elep = ISIF_GREEN_RED,
+			},
+			.col_pat_field1 = {
+				.olop = ISIF_GREEN_BLUE,
+				.olep = ISIF_BLUE,
+				.elop = ISIF_RED,
+				.elep = ISIF_GREEN_RED,
+			},
+			.test_pat_gen = 0,
+		},
+	},
+	.data_pack = ISIF_DATA_PACK8,
+};
+
+/* Raw Bayer formats */
+static const u32 isif_raw_bayer_pix_formats[] = {
+	V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
+
+/* Raw YUV formats */
+static const u32 isif_raw_yuv_pix_formats[] = {
+	V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
+
+/* register access routines */
+static inline u32 regr(u32 offset)
+{
+	return __raw_readl(isif_cfg.base_addr + offset);
+}
+
+static inline void regw(u32 val, u32 offset)
+{
+	__raw_writel(val, isif_cfg.base_addr + offset);
+}
+
+/* reg_modify() - read, modify and write register */
+static inline u32 reg_modify(u32 mask, u32 val, u32 offset)
+{
+	u32 new_val = (regr(offset) & ~mask) | (val & mask);
+
+	regw(new_val, offset);
+	return new_val;
+}
+
+static inline void regw_lin_tbl(u32 val, u32 offset, int i)
+{
+	if (!i)
+		__raw_writel(val, isif_cfg.linear_tbl0_addr + offset);
+	else
+		__raw_writel(val, isif_cfg.linear_tbl1_addr + offset);
+}
+
+static void isif_disable_all_modules(void)
+{
+	/* disable BC */
+	regw(0, CLAMPCFG);
+	/* disable vdfc */
+	regw(0, DFCCTL);
+	/* disable CSC */
+	regw(0, CSCCTL);
+	/* disable linearization */
+	regw(0, LINCFG0);
+	/* disable other modules here as they are supported */
+}
+
+static void isif_enable(int en)
+{
+	if (!en) {
+		/* Before disable isif, disable all ISIF modules */
+		isif_disable_all_modules();
+		/*
+		 * wait for next VD. Assume lowest scan rate is 12 Hz. So
+		 * 100 msec delay is good enough
+		 */
+		msleep(100);
+	}
+	reg_modify(ISIF_SYNCEN_VDHDEN_MASK, en, SYNCEN);
+}
+
+static void isif_enable_output_to_sdram(int en)
+{
+	reg_modify(ISIF_SYNCEN_WEN_MASK, en << ISIF_SYNCEN_WEN_SHIFT, SYNCEN);
+}
+
+static void isif_config_culling(struct isif_cul *cul)
+{
+	u32 val;
+
+	/* Horizontal pattern */
+	val = (cul->hcpat_even << CULL_PAT_EVEN_LINE_SHIFT) | cul->hcpat_odd;
+	regw(val, CULH);
+
+	/* vertical pattern */
+	regw(cul->vcpat, CULV);
+
+	/* LPF */
+	reg_modify(ISIF_LPF_MASK << ISIF_LPF_SHIFT,
+		  cul->en_lpf << ISIF_LPF_SHIFT, MODESET);
+}
+
+static void isif_config_gain_offset(void)
+{
+	struct isif_gain_offsets_adj *gain_off_p =
+		&isif_cfg.bayer.config_params.gain_offset;
+	u32 val;
+
+	val = (!!gain_off_p->gain_sdram_en << GAIN_SDRAM_EN_SHIFT) |
+	      (!!gain_off_p->gain_ipipe_en << GAIN_IPIPE_EN_SHIFT) |
+	      (!!gain_off_p->gain_h3a_en << GAIN_H3A_EN_SHIFT) |
+	      (!!gain_off_p->offset_sdram_en << OFST_SDRAM_EN_SHIFT) |
+	      (!!gain_off_p->offset_ipipe_en << OFST_IPIPE_EN_SHIFT) |
+	      (!!gain_off_p->offset_h3a_en << OFST_H3A_EN_SHIFT);
+
+	reg_modify(GAIN_OFFSET_EN_MASK, val, CGAMMAWD);
+
+	val = (gain_off_p->gain.r_ye.integer << GAIN_INTEGER_SHIFT) |
+	       gain_off_p->gain.r_ye.decimal;
+	regw(val, CRGAIN);
+
+	val = (gain_off_p->gain.gr_cy.integer << GAIN_INTEGER_SHIFT) |
+	       gain_off_p->gain.gr_cy.decimal;
+	regw(val, CGRGAIN);
+
+	val = (gain_off_p->gain.gb_g.integer << GAIN_INTEGER_SHIFT) |
+	       gain_off_p->gain.gb_g.decimal;
+	regw(val, CGBGAIN);
+
+	val = (gain_off_p->gain.b_mg.integer << GAIN_INTEGER_SHIFT) |
+	       gain_off_p->gain.b_mg.decimal;
+	regw(val, CBGAIN);
+
+	regw(gain_off_p->offset, COFSTA);
+}
+
+static void isif_restore_defaults(void)
+{
+	enum vpss_ccdc_source_sel source = VPSS_CCDCIN;
+
+	dev_dbg(isif_cfg.dev, "\nstarting isif_restore_defaults...");
+	isif_cfg.bayer.config_params = isif_config_defaults;
+	/* Enable clock to ISIF, IPIPEIF and BL */
+	vpss_enable_clock(VPSS_CCDC_CLOCK, 1);
+	vpss_enable_clock(VPSS_IPIPEIF_CLOCK, 1);
+	vpss_enable_clock(VPSS_BL_CLOCK, 1);
+	/* Set default offset and gain */
+	isif_config_gain_offset();
+	vpss_select_ccdc_source(source);
+	dev_dbg(isif_cfg.dev, "\nEnd of isif_restore_defaults...");
+}
+
+static int isif_open(struct device *device)
+{
+	isif_restore_defaults();
+	return 0;
+}
+
+/* This function will configure the window size to be capture in ISIF reg */
+static void isif_setwin(struct v4l2_rect *image_win,
+			enum ccdc_frmfmt frm_fmt, int ppc)
+{
+	int horz_start, horz_nr_pixels;
+	int vert_start, vert_nr_lines;
+	int mid_img = 0;
+
+	dev_dbg(isif_cfg.dev, "\nStarting isif_setwin...");
+	/*
+	 * ppc - per pixel count. indicates how many pixels per cell
+	 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
+	 * raw capture this is 1
+	 */
+	horz_start = image_win->left << (ppc - 1);
+	horz_nr_pixels = ((image_win->width) << (ppc - 1)) - 1;
+
+	/* Writing the horizontal info into the registers */
+	regw(horz_start & START_PX_HOR_MASK, SPH);
+	regw(horz_nr_pixels & NUM_PX_HOR_MASK, LNH);
+	vert_start = image_win->top;
+
+	if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
+		vert_nr_lines = (image_win->height >> 1) - 1;
+		vert_start >>= 1;
+		/* To account for VD since line 0 doesn't have any data */
+		vert_start += 1;
+	} else {
+		/* To account for VD since line 0 doesn't have any data */
+		vert_start += 1;
+		vert_nr_lines = image_win->height - 1;
+		/* configure VDINT0 and VDINT1 */
+		mid_img = vert_start + (image_win->height / 2);
+		regw(mid_img, VDINT1);
+	}
+
+	regw(0, VDINT0);
+	regw(vert_start & START_VER_ONE_MASK, SLV0);
+	regw(vert_start & START_VER_TWO_MASK, SLV1);
+	regw(vert_nr_lines & NUM_LINES_VER, LNV);
+}
+
+static void isif_config_bclamp(struct isif_black_clamp *bc)
+{
+	u32 val;
+
+	/*
+	 * DC Offset is always added to image data irrespective of bc enable
+	 * status
+	 */
+	regw(bc->dc_offset, CLDCOFST);
+
+	if (bc->en) {
+		val = bc->bc_mode_color << ISIF_BC_MODE_COLOR_SHIFT;
+
+		/* Enable BC and horizontal clamp caculation paramaters */
+		val = val | 1 | (bc->horz.mode << ISIF_HORZ_BC_MODE_SHIFT);
+
+		regw(val, CLAMPCFG);
+
+		if (bc->horz.mode != ISIF_HORZ_BC_DISABLE) {
+			/*
+			 * Window count for calculation
+			 * Base window selection
+			 * pixel limit
+			 * Horizontal size of window
+			 * vertical size of the window
+			 * Horizontal start position of the window
+			 * Vertical start position of the window
+			 */
+			val = bc->horz.win_count_calc |
+			      ((!!bc->horz.base_win_sel_calc) <<
+				ISIF_HORZ_BC_WIN_SEL_SHIFT) |
+			      ((!!bc->horz.clamp_pix_limit) <<
+				ISIF_HORZ_BC_PIX_LIMIT_SHIFT) |
+			      (bc->horz.win_h_sz_calc <<
+				ISIF_HORZ_BC_WIN_H_SIZE_SHIFT) |
+			      (bc->horz.win_v_sz_calc <<
+				ISIF_HORZ_BC_WIN_V_SIZE_SHIFT);
+			regw(val, CLHWIN0);
+
+			regw(bc->horz.win_start_h_calc, CLHWIN1);
+			regw(bc->horz.win_start_v_calc, CLHWIN2);
+		}
+
+		/* vertical clamp caculation paramaters */
+
+		/* Reset clamp value sel for previous line */
+		val |=
+		(bc->vert.reset_val_sel << ISIF_VERT_BC_RST_VAL_SEL_SHIFT) |
+		(bc->vert.line_ave_coef << ISIF_VERT_BC_LINE_AVE_COEF_SHIFT);
+		regw(val, CLVWIN0);
+
+		/* Optical Black horizontal start position */
+		regw(bc->vert.ob_start_h, CLVWIN1);
+		/* Optical Black vertical start position */
+		regw(bc->vert.ob_start_v, CLVWIN2);
+		/* Optical Black vertical size for calculation */
+		regw(bc->vert.ob_v_sz_calc, CLVWIN3);
+		/* Vertical start position for BC subtraction */
+		regw(bc->vert_start_sub, CLSV);
+	}
+}
+
+static void isif_config_linearization(struct isif_linearize *linearize)
+{
+	u32 val, i;
+
+	if (!linearize->en) {
+		regw(0, LINCFG0);
+		return;
+	}
+
+	/* shift value for correction & enable linearization (set lsb) */
+	val = (linearize->corr_shft << ISIF_LIN_CORRSFT_SHIFT) | 1;
+	regw(val, LINCFG0);
+
+	/* Scale factor */
+	val = ((!!linearize->scale_fact.integer) <<
+	       ISIF_LIN_SCALE_FACT_INTEG_SHIFT) |
+	       linearize->scale_fact.decimal;
+	regw(val, LINCFG1);
+
+	for (i = 0; i < ISIF_LINEAR_TAB_SIZE; i++) {
+		if (i % 2)
+			regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 1);
+		else
+			regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 0);
+	}
+}
+
+static int isif_config_dfc(struct isif_dfc *vdfc)
+{
+	/* initialize retries to loop for max ~ 250 usec */
+	u32 val, count, retries = loops_per_jiffy / (4000/HZ);
+	int i;
+
+	if (!vdfc->en)
+		return 0;
+
+	/* Correction mode */
+	val = (vdfc->corr_mode << ISIF_VDFC_CORR_MOD_SHIFT);
+
+	/* Correct whole line or partial */
+	if (vdfc->corr_whole_line)
+		val |= 1 << ISIF_VDFC_CORR_WHOLE_LN_SHIFT;
+
+	/* level shift value */
+	val |= vdfc->def_level_shift << ISIF_VDFC_LEVEL_SHFT_SHIFT;
+
+	regw(val, DFCCTL);
+
+	/* Defect saturation level */
+	regw(vdfc->def_sat_level, VDFSATLV);
+
+	regw(vdfc->table[0].pos_vert, DFCMEM0);
+	regw(vdfc->table[0].pos_horz, DFCMEM1);
+	if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
+	    vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
+		regw(vdfc->table[0].level_at_pos, DFCMEM2);
+		regw(vdfc->table[0].level_up_pixels, DFCMEM3);
+		regw(vdfc->table[0].level_low_pixels, DFCMEM4);
+	}
+
+	/* set DFCMARST and set DFCMWR */
+	val = regr(DFCMEMCTL) | (1 << ISIF_DFCMEMCTL_DFCMARST_SHIFT) | 1;
+	regw(val, DFCMEMCTL);
+
+	count = retries;
+	while (count && (regr(DFCMEMCTL) & 0x1))
+		count--;
+
+	if (!count) {
+		dev_dbg(isif_cfg.dev, "defect table write timeout !!!\n");
+		return -1;
+	}
+
+	for (i = 1; i < vdfc->num_vdefects; i++) {
+		regw(vdfc->table[i].pos_vert, DFCMEM0);
+		regw(vdfc->table[i].pos_horz, DFCMEM1);
+		if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
+		    vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
+			regw(vdfc->table[i].level_at_pos, DFCMEM2);
+			regw(vdfc->table[i].level_up_pixels, DFCMEM3);
+			regw(vdfc->table[i].level_low_pixels, DFCMEM4);
+		}
+		val = regr(DFCMEMCTL);
+		/* clear DFCMARST and set DFCMWR */
+		val &= ~BIT(ISIF_DFCMEMCTL_DFCMARST_SHIFT);
+		val |= 1;
+		regw(val, DFCMEMCTL);
+
+		count = retries;
+		while (count && (regr(DFCMEMCTL) & 0x1))
+			count--;
+
+		if (!count) {
+			dev_err(isif_cfg.dev,
+				"defect table write timeout !!!\n");
+			return -1;
+		}
+	}
+	if (vdfc->num_vdefects < ISIF_VDFC_TABLE_SIZE) {
+		/* Extra cycle needed */
+		regw(0, DFCMEM0);
+		regw(0x1FFF, DFCMEM1);
+		regw(1, DFCMEMCTL);
+	}
+
+	/* enable VDFC */
+	reg_modify((1 << ISIF_VDFC_EN_SHIFT), (1 << ISIF_VDFC_EN_SHIFT),
+		   DFCCTL);
+	return 0;
+}
+
+static void isif_config_csc(struct isif_df_csc *df_csc)
+{
+	u32 val1 = 0, val2 = 0, i;
+
+	if (!df_csc->csc.en) {
+		regw(0, CSCCTL);
+		return;
+	}
+	for (i = 0; i < ISIF_CSC_NUM_COEFF; i++) {
+		if ((i % 2) == 0) {
+			/* CSCM - LSB */
+			val1 = (df_csc->csc.coeff[i].integer <<
+				ISIF_CSC_COEF_INTEG_SHIFT) |
+				df_csc->csc.coeff[i].decimal;
+		} else {
+
+			/* CSCM - MSB */
+			val2 = (df_csc->csc.coeff[i].integer <<
+				ISIF_CSC_COEF_INTEG_SHIFT) |
+				df_csc->csc.coeff[i].decimal;
+			val2 <<= ISIF_CSCM_MSB_SHIFT;
+			val2 |= val1;
+			regw(val2, (CSCM0 + ((i - 1) << 1)));
+		}
+	}
+
+	/* program the active area */
+	regw(df_csc->start_pix, FMTSPH);
+	/*
+	 * one extra pixel as required for CSC. Actually number of
+	 * pixel - 1 should be configured in this register. So we
+	 * need to subtract 1 before writing to FMTSPH, but we will
+	 * not do this since csc requires one extra pixel
+	 */
+	regw(df_csc->num_pixels, FMTLNH);
+	regw(df_csc->start_line, FMTSLV);
+	/*
+	 * one extra line as required for CSC. See reason documented for
+	 * num_pixels
+	 */
+	regw(df_csc->num_lines, FMTLNV);
+
+	/* Enable CSC */
+	regw(1, CSCCTL);
+}
+
+static int isif_config_raw(void)
+{
+	struct isif_params_raw *params = &isif_cfg.bayer;
+	struct isif_config_params_raw *module_params =
+		&isif_cfg.bayer.config_params;
+	struct vpss_pg_frame_size frame_size;
+	struct vpss_sync_pol sync;
+	u32 val;
+
+	dev_dbg(isif_cfg.dev, "\nStarting isif_config_raw..\n");
+
+	/*
+	 * Configure CCDCFG register:-
+	 * Set CCD Not to swap input since input is RAW data
+	 * Set FID detection function to Latch at V-Sync
+	 * Set WENLOG - isif valid area
+	 * Set TRGSEL
+	 * Set EXTRG
+	 * Packed to 8 or 16 bits
+	 */
+
+	val = ISIF_YCINSWP_RAW | ISIF_CCDCFG_FIDMD_LATCH_VSYNC |
+		ISIF_CCDCFG_WENLOG_AND | ISIF_CCDCFG_TRGSEL_WEN |
+		ISIF_CCDCFG_EXTRG_DISABLE | isif_cfg.data_pack;
+
+	dev_dbg(isif_cfg.dev, "Writing 0x%x to ...CCDCFG \n", val);
+	regw(val, CCDCFG);
+
+	/*
+	 * Configure the vertical sync polarity(MODESET.VDPOL)
+	 * Configure the horizontal sync polarity (MODESET.HDPOL)
+	 * Configure frame id polarity (MODESET.FLDPOL)
+	 * Configure data polarity
+	 * Configure External WEN Selection
+	 * Configure frame format(progressive or interlace)
+	 * Configure pixel format (Input mode)
+	 * Configure the data shift
+	 */
+
+	val = ISIF_VDHDOUT_INPUT | (params->vd_pol << ISIF_VD_POL_SHIFT) |
+		(params->hd_pol << ISIF_HD_POL_SHIFT) |
+		(params->fid_pol << ISIF_FID_POL_SHIFT) |
+		(ISIF_DATAPOL_NORMAL << ISIF_DATAPOL_SHIFT) |
+		(ISIF_EXWEN_DISABLE << ISIF_EXWEN_SHIFT) |
+		(params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
+		(params->pix_fmt << ISIF_INPUT_SHIFT) |
+		(params->config_params.data_shift << ISIF_DATASFT_SHIFT);
+
+	regw(val, MODESET);
+	dev_dbg(isif_cfg.dev, "Writing 0x%x to MODESET...\n", val);
+
+	/*
+	 * Configure GAMMAWD register
+	 * CFA pattern setting
+	 */
+	val = params->cfa_pat << ISIF_GAMMAWD_CFA_SHIFT;
+
+	/* Gamma msb */
+	if (module_params->compress.alg == ISIF_ALAW)
+		val |= ISIF_ALAW_ENABLE;
+
+	val |= (params->data_msb << ISIF_ALAW_GAMA_WD_SHIFT);
+	regw(val, CGAMMAWD);
+
+	/* Configure DPCM compression settings */
+	if (module_params->compress.alg == ISIF_DPCM) {
+		val =  BIT(ISIF_DPCM_EN_SHIFT) |
+		       (module_params->compress.pred <<
+		       ISIF_DPCM_PREDICTOR_SHIFT);
+	}
+
+	regw(val, MISC);
+
+	/* Configure Gain & Offset */
+	isif_config_gain_offset();
+
+	/* Configure Color pattern */
+	val = (params->config_params.col_pat_field0.olop) |
+	      (params->config_params.col_pat_field0.olep << 2) |
+	      (params->config_params.col_pat_field0.elop << 4) |
+	      (params->config_params.col_pat_field0.elep << 6) |
+	      (params->config_params.col_pat_field1.olop << 8) |
+	      (params->config_params.col_pat_field1.olep << 10) |
+	      (params->config_params.col_pat_field1.elop << 12) |
+	      (params->config_params.col_pat_field1.elep << 14);
+	regw(val, CCOLP);
+	dev_dbg(isif_cfg.dev, "Writing %x to CCOLP ...\n", val);
+
+	/* Configure HSIZE register  */
+	val = (!!params->horz_flip_en) << ISIF_HSIZE_FLIP_SHIFT;
+
+	/* calculate line offset in 32 bytes based on pack value */
+	if (isif_cfg.data_pack == ISIF_PACK_8BIT)
+		val |= ((params->win.width + 31) >> 5);
+	else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
+		val |= (((params->win.width +
+		       (params->win.width >> 2)) + 31) >> 5);
+	else
+		val |= (((params->win.width * 2) + 31) >> 5);
+	regw(val, HSIZE);
+
+	/* Configure SDOFST register  */
+	if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
+		if (params->image_invert_en) {
+			/* For interlace inverse mode */
+			regw(0x4B6D, SDOFST);
+			dev_dbg(isif_cfg.dev, "Writing 0x4B6D to SDOFST...\n");
+		} else {
+			/* For interlace non inverse mode */
+			regw(0x0B6D, SDOFST);
+			dev_dbg(isif_cfg.dev, "Writing 0x0B6D to SDOFST...\n");
+		}
+	} else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
+		if (params->image_invert_en) {
+			/* For progressive inverse mode */
+			regw(0x4000, SDOFST);
+			dev_dbg(isif_cfg.dev, "Writing 0x4000 to SDOFST...\n");
+		} else {
+			/* For progressive non inverse mode */
+			regw(0x0000, SDOFST);
+			dev_dbg(isif_cfg.dev, "Writing 0x0000 to SDOFST...\n");
+		}
+	}
+
+	/* Configure video window */
+	isif_setwin(&params->win, params->frm_fmt, 1);
+
+	/* Configure Black Clamp */
+	isif_config_bclamp(&module_params->bclamp);
+
+	/* Configure Vertical Defection Pixel Correction */
+	if (isif_config_dfc(&module_params->dfc) < 0)
+		return -EFAULT;
+
+	if (!module_params->df_csc.df_or_csc)
+		/* Configure Color Space Conversion */
+		isif_config_csc(&module_params->df_csc);
+
+	isif_config_linearization(&module_params->linearize);
+
+	/* Configure Culling */
+	isif_config_culling(&module_params->culling);
+
+	/* Configure horizontal and vertical offsets(DFC,LSC,Gain) */
+	regw(module_params->horz_offset, DATAHOFST);
+	regw(module_params->vert_offset, DATAVOFST);
+
+	/* Setup test pattern if enabled */
+	if (params->config_params.test_pat_gen) {
+		/* Use the HD/VD pol settings from user */
+		sync.ccdpg_hdpol = params->hd_pol;
+		sync.ccdpg_vdpol = params->vd_pol;
+		dm365_vpss_set_sync_pol(sync);
+		frame_size.hlpfr = isif_cfg.bayer.win.width;
+		frame_size.pplen = isif_cfg.bayer.win.height;
+		dm365_vpss_set_pg_frame_size(frame_size);
+		vpss_select_ccdc_source(VPSS_PGLPBK);
+	}
+
+	dev_dbg(isif_cfg.dev, "\nEnd of isif_config_ycbcr...\n");
+	return 0;
+}
+
+static int isif_set_buftype(enum ccdc_buftype buf_type)
+{
+	if (isif_cfg.if_type == VPFE_RAW_BAYER)
+		isif_cfg.bayer.buf_type = buf_type;
+	else
+		isif_cfg.ycbcr.buf_type = buf_type;
+
+	return 0;
+
+}
+static enum ccdc_buftype isif_get_buftype(void)
+{
+	if (isif_cfg.if_type == VPFE_RAW_BAYER)
+		return isif_cfg.bayer.buf_type;
+
+	return isif_cfg.ycbcr.buf_type;
+}
+
+static int isif_enum_pix(u32 *pix, int i)
+{
+	int ret = -EINVAL;
+
+	if (isif_cfg.if_type == VPFE_RAW_BAYER) {
+		if (i < ARRAY_SIZE(isif_raw_bayer_pix_formats)) {
+			*pix = isif_raw_bayer_pix_formats[i];
+			ret = 0;
+		}
+	} else {
+		if (i < ARRAY_SIZE(isif_raw_yuv_pix_formats)) {
+			*pix = isif_raw_yuv_pix_formats[i];
+			ret = 0;
+		}
+	}
+
+	return ret;
+}
+
+static int isif_set_pixel_format(unsigned int pixfmt)
+{
+	if (isif_cfg.if_type == VPFE_RAW_BAYER) {
+		if (pixfmt == V4L2_PIX_FMT_SBGGR8) {
+			if ((isif_cfg.bayer.config_params.compress.alg !=
+			     ISIF_ALAW) &&
+			    (isif_cfg.bayer.config_params.compress.alg !=
+			     ISIF_DPCM)) {
+				dev_dbg(isif_cfg.dev,
+					"Either configure A-Law or DPCM\n");
+				return -EINVAL;
+			}
+			isif_cfg.data_pack = ISIF_PACK_8BIT;
+		} else if (pixfmt == V4L2_PIX_FMT_SBGGR16) {
+			isif_cfg.bayer.config_params.compress.alg =
+					ISIF_NO_COMPRESSION;
+			isif_cfg.data_pack = ISIF_PACK_16BIT;
+		} else
+			return -EINVAL;
+		isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
+	} else {
+		if (pixfmt == V4L2_PIX_FMT_YUYV)
+			isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
+		else if (pixfmt == V4L2_PIX_FMT_UYVY)
+			isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
+		else
+			return -EINVAL;
+		isif_cfg.data_pack = ISIF_PACK_8BIT;
+	}
+	return 0;
+}
+
+static u32 isif_get_pixel_format(void)
+{
+	u32 pixfmt;
+
+	if (isif_cfg.if_type == VPFE_RAW_BAYER)
+		if (isif_cfg.bayer.config_params.compress.alg == ISIF_ALAW ||
+		    isif_cfg.bayer.config_params.compress.alg == ISIF_DPCM)
+			pixfmt = V4L2_PIX_FMT_SBGGR8;
+		else
+			pixfmt = V4L2_PIX_FMT_SBGGR16;
+	else {
+		if (isif_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
+			pixfmt = V4L2_PIX_FMT_YUYV;
+		else
+			pixfmt = V4L2_PIX_FMT_UYVY;
+	}
+	return pixfmt;
+}
+
+static int isif_set_image_window(struct v4l2_rect *win)
+{
+	if (isif_cfg.if_type == VPFE_RAW_BAYER) {
+		isif_cfg.bayer.win.top = win->top;
+		isif_cfg.bayer.win.left = win->left;
+		isif_cfg.bayer.win.width = win->width;
+		isif_cfg.bayer.win.height = win->height;
+	} else {
+		isif_cfg.ycbcr.win.top = win->top;
+		isif_cfg.ycbcr.win.left = win->left;
+		isif_cfg.ycbcr.win.width = win->width;
+		isif_cfg.ycbcr.win.height = win->height;
+	}
+	return 0;
+}
+
+static void isif_get_image_window(struct v4l2_rect *win)
+{
+	if (isif_cfg.if_type == VPFE_RAW_BAYER)
+		*win = isif_cfg.bayer.win;
+	else
+		*win = isif_cfg.ycbcr.win;
+}
+
+static unsigned int isif_get_line_length(void)
+{
+	unsigned int len;
+
+	if (isif_cfg.if_type == VPFE_RAW_BAYER) {
+		if (isif_cfg.data_pack == ISIF_PACK_8BIT)
+			len = ((isif_cfg.bayer.win.width));
+		else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
+			len = (((isif_cfg.bayer.win.width * 2) +
+				 (isif_cfg.bayer.win.width >> 2)));
+		else
+			len = (((isif_cfg.bayer.win.width * 2)));
+	} else
+		len = (((isif_cfg.ycbcr.win.width * 2)));
+	return ALIGN(len, 32);
+}
+
+static int isif_set_frame_format(enum ccdc_frmfmt frm_fmt)
+{
+	if (isif_cfg.if_type == VPFE_RAW_BAYER)
+		isif_cfg.bayer.frm_fmt = frm_fmt;
+	else
+		isif_cfg.ycbcr.frm_fmt = frm_fmt;
+	return 0;
+}
+static enum ccdc_frmfmt isif_get_frame_format(void)
+{
+	if (isif_cfg.if_type == VPFE_RAW_BAYER)
+		return isif_cfg.bayer.frm_fmt;
+	return isif_cfg.ycbcr.frm_fmt;
+}
+
+static int isif_getfid(void)
+{
+	return (regr(MODESET) >> 15) & 0x1;
+}
+
+/* misc operations */
+static void isif_setfbaddr(unsigned long addr)
+{
+	regw((addr >> 21) & 0x07ff, CADU);
+	regw((addr >> 5) & 0x0ffff, CADL);
+}
+
+static int isif_set_hw_if_params(struct vpfe_hw_if_param *params)
+{
+	isif_cfg.if_type = params->if_type;
+
+	switch (params->if_type) {
+	case VPFE_BT656:
+	case VPFE_BT656_10BIT:
+	case VPFE_YCBCR_SYNC_8:
+		isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
+		isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
+		break;
+	case VPFE_BT1120:
+	case VPFE_YCBCR_SYNC_16:
+		isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_16BIT;
+		isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
+		break;
+	case VPFE_RAW_BAYER:
+		isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
+		break;
+	default:
+		dev_dbg(isif_cfg.dev, "Invalid interface type\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* This function will configure ISIF for YCbCr parameters. */
+static int isif_config_ycbcr(void)
+{
+	struct isif_ycbcr_config *params = &isif_cfg.ycbcr;
+	struct vpss_pg_frame_size frame_size;
+	u32 modeset = 0, ccdcfg = 0;
+	struct vpss_sync_pol sync;
+
+	dev_dbg(isif_cfg.dev, "\nStarting isif_config_ycbcr...");
+
+	/* configure pixel format or input mode */
+	modeset = modeset | (params->pix_fmt << ISIF_INPUT_SHIFT) |
+		  (params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
+		  (params->fid_pol << ISIF_FID_POL_SHIFT) |
+		  (params->hd_pol << ISIF_HD_POL_SHIFT) |
+		  (params->vd_pol << ISIF_VD_POL_SHIFT);
+
+	/* pack the data to 8-bit ISIFCFG */
+	switch (isif_cfg.if_type) {
+	case VPFE_BT656:
+		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
+			dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
+			return -EINVAL;
+		}
+		modeset |= (VPFE_PINPOL_NEGATIVE << ISIF_VD_POL_SHIFT);
+		regw(3, REC656IF);
+		ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR;
+		break;
+	case VPFE_BT656_10BIT:
+		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
+			dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
+			return -EINVAL;
+		}
+		/* setup BT.656, embedded sync  */
+		regw(3, REC656IF);
+		/* enable 10 bit mode in ccdcfg */
+		ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR |
+			ISIF_BW656_ENABLE;
+		break;
+	case VPFE_BT1120:
+		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
+			dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
+			return -EINVAL;
+		}
+		regw(3, REC656IF);
+		break;
+
+	case VPFE_YCBCR_SYNC_8:
+		ccdcfg |= ISIF_DATA_PACK8;
+		ccdcfg |= ISIF_YCINSWP_YCBCR;
+		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
+			dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
+			return -EINVAL;
+		}
+		break;
+	case VPFE_YCBCR_SYNC_16:
+		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
+			dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
+			return -EINVAL;
+		}
+		break;
+	default:
+		/* should never come here */
+		dev_dbg(isif_cfg.dev, "Invalid interface type\n");
+		return -EINVAL;
+	}
+
+	regw(modeset, MODESET);
+
+	/* Set up pix order */
+	ccdcfg |= params->pix_order << ISIF_PIX_ORDER_SHIFT;
+
+	regw(ccdcfg, CCDCFG);
+
+	/* configure video window */
+	if ((isif_cfg.if_type == VPFE_BT1120) ||
+	    (isif_cfg.if_type == VPFE_YCBCR_SYNC_16))
+		isif_setwin(&params->win, params->frm_fmt, 1);
+	else
+		isif_setwin(&params->win, params->frm_fmt, 2);
+
+	/*
+	 * configure the horizontal line offset
+	 * this is done by rounding up width to a multiple of 16 pixels
+	 * and multiply by two to account for y:cb:cr 4:2:2 data
+	 */
+	regw(((((params->win.width * 2) + 31) & 0xffffffe0) >> 5), HSIZE);
+
+	/* configure the memory line offset */
+	if ((params->frm_fmt == CCDC_FRMFMT_INTERLACED) &&
+	    (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED))
+		/* two fields are interleaved in memory */
+		regw(0x00000249, SDOFST);
+
+	/* Setup test pattern if enabled */
+	if (isif_cfg.bayer.config_params.test_pat_gen) {
+		sync.ccdpg_hdpol = params->hd_pol;
+		sync.ccdpg_vdpol = params->vd_pol;
+		dm365_vpss_set_sync_pol(sync);
+		dm365_vpss_set_pg_frame_size(frame_size);
+	}
+	return 0;
+}
+
+static int isif_configure(void)
+{
+	if (isif_cfg.if_type == VPFE_RAW_BAYER)
+		return isif_config_raw();
+	return isif_config_ycbcr();
+}
+
+static int isif_close(struct device *device)
+{
+	/* copy defaults to module params */
+	isif_cfg.bayer.config_params = isif_config_defaults;
+	return 0;
+}
+
+static struct ccdc_hw_device isif_hw_dev = {
+	.name = "ISIF",
+	.owner = THIS_MODULE,
+	.hw_ops = {
+		.open = isif_open,
+		.close = isif_close,
+		.enable = isif_enable,
+		.enable_out_to_sdram = isif_enable_output_to_sdram,
+		.set_hw_if_params = isif_set_hw_if_params,
+		.configure = isif_configure,
+		.set_buftype = isif_set_buftype,
+		.get_buftype = isif_get_buftype,
+		.enum_pix = isif_enum_pix,
+		.set_pixel_format = isif_set_pixel_format,
+		.get_pixel_format = isif_get_pixel_format,
+		.set_frame_format = isif_set_frame_format,
+		.get_frame_format = isif_get_frame_format,
+		.set_image_window = isif_set_image_window,
+		.get_image_window = isif_get_image_window,
+		.get_line_length = isif_get_line_length,
+		.setfbaddr = isif_setfbaddr,
+		.getfid = isif_getfid,
+	},
+};
+
+static int __init isif_probe(struct platform_device *pdev)
+{
+	void (*setup_pinmux)(void);
+	struct resource	*res;
+	void *__iomem addr;
+	int status = 0, i;
+
+	/*
+	 * first try to register with vpfe. If not correct platform, then we
+	 * don't have to iomap
+	 */
+	status = vpfe_register_ccdc_device(&isif_hw_dev);
+	if (status < 0)
+		return status;
+
+	/* Get and enable Master clock */
+	isif_cfg.mclk = clk_get(&pdev->dev, "master");
+	if (IS_ERR(isif_cfg.mclk)) {
+		status = PTR_ERR(isif_cfg.mclk);
+		goto fail_mclk;
+	}
+	if (clk_enable(isif_cfg.mclk)) {
+		status = -ENODEV;
+		goto fail_mclk;
+	}
+
+	/* Platform data holds setup_pinmux function ptr */
+	if (NULL == pdev->dev.platform_data) {
+		status = -ENODEV;
+		goto fail_mclk;
+	}
+	setup_pinmux = pdev->dev.platform_data;
+	/*
+	 * setup Mux configuration for ccdc which may be different for
+	 * different SoCs using this CCDC
+	 */
+	setup_pinmux();
+
+	i = 0;
+	/* Get the ISIF base address, linearization table0 and table1 addr. */
+	while (i < 3) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		if (!res) {
+			status = -ENODEV;
+			goto fail_nobase_res;
+		}
+		res = request_mem_region(res->start, resource_size(res),
+					 res->name);
+		if (!res) {
+			status = -EBUSY;
+			goto fail_nobase_res;
+		}
+		addr = ioremap_nocache(res->start, resource_size(res));
+		if (!addr) {
+			status = -ENOMEM;
+			goto fail_base_iomap;
+		}
+		switch (i) {
+		case 0:
+			/* ISIF base address */
+			isif_cfg.base_addr = addr;
+			break;
+		case 1:
+			/* ISIF linear tbl0 address */
+			isif_cfg.linear_tbl0_addr = addr;
+			break;
+		default:
+			/* ISIF linear tbl0 address */
+			isif_cfg.linear_tbl1_addr = addr;
+			break;
+		}
+		i++;
+	}
+	isif_cfg.dev = &pdev->dev;
+
+	printk(KERN_NOTICE "%s is registered with vpfe.\n",
+		isif_hw_dev.name);
+	return 0;
+fail_base_iomap:
+	release_mem_region(res->start, resource_size(res));
+	i--;
+fail_nobase_res:
+	if (isif_cfg.base_addr)
+		iounmap(isif_cfg.base_addr);
+	if (isif_cfg.linear_tbl0_addr)
+		iounmap(isif_cfg.linear_tbl0_addr);
+
+	while (i >= 0) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		release_mem_region(res->start, resource_size(res));
+		i--;
+	}
+fail_mclk:
+	clk_put(isif_cfg.mclk);
+	vpfe_unregister_ccdc_device(&isif_hw_dev);
+	return status;
+}
+
+static int isif_remove(struct platform_device *pdev)
+{
+	struct resource	*res;
+	int i = 0;
+
+	iounmap(isif_cfg.base_addr);
+	iounmap(isif_cfg.linear_tbl0_addr);
+	iounmap(isif_cfg.linear_tbl1_addr);
+	while (i < 3) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		if (res)
+			release_mem_region(res->start, resource_size(res));
+		i++;
+	}
+	vpfe_unregister_ccdc_device(&isif_hw_dev);
+	return 0;
+}
+
+static struct platform_driver isif_driver = {
+	.driver = {
+		.name	= "isif",
+		.owner = THIS_MODULE,
+	},
+	.remove = __devexit_p(isif_remove),
+	.probe = isif_probe,
+};
+
+static int __init isif_init(void)
+{
+	return platform_driver_register(&isif_driver);
+}
+
+static void isif_exit(void)
+{
+	platform_driver_unregister(&isif_driver);
+}
+
+module_init(isif_init);
+module_exit(isif_exit);
+
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/davinci/isif_regs.h linux-libre-2.6.34-gnu1/drivers/media/video/davinci/isif_regs.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/davinci/isif_regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/davinci/isif_regs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2008-2009 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 _ISIF_REGS_H
+#define _ISIF_REGS_H
+
+/* ISIF registers relative offsets */
+#define SYNCEN					0x00
+#define MODESET					0x04
+#define HDW					0x08
+#define VDW					0x0c
+#define PPLN					0x10
+#define LPFR					0x14
+#define SPH					0x18
+#define LNH					0x1c
+#define SLV0					0x20
+#define SLV1					0x24
+#define LNV					0x28
+#define CULH					0x2c
+#define CULV					0x30
+#define HSIZE					0x34
+#define SDOFST					0x38
+#define CADU					0x3c
+#define CADL					0x40
+#define LINCFG0					0x44
+#define LINCFG1					0x48
+#define CCOLP					0x4c
+#define CRGAIN 					0x50
+#define CGRGAIN					0x54
+#define CGBGAIN					0x58
+#define CBGAIN					0x5c
+#define COFSTA					0x60
+#define FLSHCFG0				0x64
+#define FLSHCFG1				0x68
+#define FLSHCFG2				0x6c
+#define VDINT0					0x70
+#define VDINT1					0x74
+#define VDINT2					0x78
+#define MISC 					0x7c
+#define CGAMMAWD				0x80
+#define REC656IF				0x84
+#define CCDCFG					0x88
+/*****************************************************
+* Defect Correction registers
+*****************************************************/
+#define DFCCTL					0x8c
+#define VDFSATLV				0x90
+#define DFCMEMCTL				0x94
+#define DFCMEM0					0x98
+#define DFCMEM1					0x9c
+#define DFCMEM2					0xa0
+#define DFCMEM3					0xa4
+#define DFCMEM4					0xa8
+/****************************************************
+* Black Clamp registers
+****************************************************/
+#define CLAMPCFG				0xac
+#define CLDCOFST				0xb0
+#define CLSV					0xb4
+#define CLHWIN0					0xb8
+#define CLHWIN1					0xbc
+#define CLHWIN2					0xc0
+#define CLVRV					0xc4
+#define CLVWIN0					0xc8
+#define CLVWIN1					0xcc
+#define CLVWIN2					0xd0
+#define CLVWIN3					0xd4
+/****************************************************
+* Lense Shading Correction
+****************************************************/
+#define DATAHOFST				0xd8
+#define DATAVOFST				0xdc
+#define LSCHVAL					0xe0
+#define LSCVVAL					0xe4
+#define TWODLSCCFG				0xe8
+#define TWODLSCOFST				0xec
+#define TWODLSCINI				0xf0
+#define TWODLSCGRBU				0xf4
+#define TWODLSCGRBL				0xf8
+#define TWODLSCGROF				0xfc
+#define TWODLSCORBU				0x100
+#define TWODLSCORBL				0x104
+#define TWODLSCOROF				0x108
+#define TWODLSCIRQEN				0x10c
+#define TWODLSCIRQST				0x110
+/****************************************************
+* Data formatter
+****************************************************/
+#define FMTCFG					0x114
+#define FMTPLEN					0x118
+#define FMTSPH					0x11c
+#define FMTLNH					0x120
+#define FMTSLV					0x124
+#define FMTLNV					0x128
+#define FMTRLEN					0x12c
+#define FMTHCNT					0x130
+#define FMTAPTR_BASE				0x134
+/* Below macro for addresses FMTAPTR0 - FMTAPTR15 */
+#define FMTAPTR(i)			(FMTAPTR_BASE + (i * 4))
+#define FMTPGMVF0				0x174
+#define FMTPGMVF1				0x178
+#define FMTPGMAPU0				0x17c
+#define FMTPGMAPU1				0x180
+#define FMTPGMAPS0				0x184
+#define FMTPGMAPS1				0x188
+#define FMTPGMAPS2				0x18c
+#define FMTPGMAPS3				0x190
+#define FMTPGMAPS4				0x194
+#define FMTPGMAPS5				0x198
+#define FMTPGMAPS6				0x19c
+#define FMTPGMAPS7				0x1a0
+/************************************************
+* Color Space Converter
+************************************************/
+#define CSCCTL					0x1a4
+#define CSCM0					0x1a8
+#define CSCM1					0x1ac
+#define CSCM2					0x1b0
+#define CSCM3					0x1b4
+#define CSCM4					0x1b8
+#define CSCM5					0x1bc
+#define CSCM6					0x1c0
+#define CSCM7					0x1c4
+#define OBWIN0					0x1c8
+#define OBWIN1					0x1cc
+#define OBWIN2					0x1d0
+#define OBWIN3					0x1d4
+#define OBVAL0					0x1d8
+#define OBVAL1					0x1dc
+#define OBVAL2					0x1e0
+#define OBVAL3					0x1e4
+#define OBVAL4					0x1e8
+#define OBVAL5					0x1ec
+#define OBVAL6					0x1f0
+#define OBVAL7					0x1f4
+#define CLKCTL					0x1f8
+
+/* Masks & Shifts below */
+#define START_PX_HOR_MASK			0x7FFF
+#define NUM_PX_HOR_MASK				0x7FFF
+#define START_VER_ONE_MASK			0x7FFF
+#define START_VER_TWO_MASK			0x7FFF
+#define NUM_LINES_VER				0x7FFF
+
+/* gain - offset masks */
+#define GAIN_INTEGER_SHIFT			9
+#define OFFSET_MASK			  	0xFFF
+#define GAIN_SDRAM_EN_SHIFT			12
+#define GAIN_IPIPE_EN_SHIFT			13
+#define GAIN_H3A_EN_SHIFT			14
+#define OFST_SDRAM_EN_SHIFT			8
+#define OFST_IPIPE_EN_SHIFT			9
+#define OFST_H3A_EN_SHIFT			10
+#define GAIN_OFFSET_EN_MASK			0x7700
+
+/* Culling */
+#define CULL_PAT_EVEN_LINE_SHIFT		8
+
+/* CCDCFG register */
+#define ISIF_YCINSWP_RAW			(0x00 << 4)
+#define ISIF_YCINSWP_YCBCR			(0x01 << 4)
+#define ISIF_CCDCFG_FIDMD_LATCH_VSYNC		(0x00 << 6)
+#define ISIF_CCDCFG_WENLOG_AND			(0x00 << 8)
+#define ISIF_CCDCFG_TRGSEL_WEN			(0x00 << 9)
+#define ISIF_CCDCFG_EXTRG_DISABLE		(0x00 << 10)
+#define ISIF_LATCH_ON_VSYNC_DISABLE		(0x01 << 15)
+#define ISIF_LATCH_ON_VSYNC_ENABLE		(0x00 << 15)
+#define ISIF_DATA_PACK_MASK			3
+#define ISIF_DATA_PACK16			0
+#define ISIF_DATA_PACK12			1
+#define ISIF_DATA_PACK8				2
+#define ISIF_PIX_ORDER_SHIFT			11
+#define ISIF_BW656_ENABLE			(0x01 << 5)
+
+/* MODESET registers */
+#define ISIF_VDHDOUT_INPUT			(0x00 << 0)
+#define ISIF_INPUT_SHIFT			12
+#define ISIF_RAW_INPUT_MODE			0
+#define ISIF_FID_POL_SHIFT			4
+#define ISIF_HD_POL_SHIFT			3
+#define ISIF_VD_POL_SHIFT			2
+#define ISIF_DATAPOL_NORMAL			0
+#define ISIF_DATAPOL_SHIFT			6
+#define ISIF_EXWEN_DISABLE 			0
+#define ISIF_EXWEN_SHIFT			5
+#define ISIF_FRM_FMT_SHIFT			7
+#define ISIF_DATASFT_SHIFT			8
+#define ISIF_LPF_SHIFT				14
+#define ISIF_LPF_MASK				1
+
+/* GAMMAWD registers */
+#define ISIF_ALAW_GAMA_WD_MASK			0xF
+#define ISIF_ALAW_GAMA_WD_SHIFT			1
+#define ISIF_ALAW_ENABLE			1
+#define ISIF_GAMMAWD_CFA_SHIFT			5
+
+/* HSIZE registers */
+#define ISIF_HSIZE_FLIP_MASK			1
+#define ISIF_HSIZE_FLIP_SHIFT			12
+
+/* MISC registers */
+#define ISIF_DPCM_EN_SHIFT			12
+#define ISIF_DPCM_PREDICTOR_SHIFT		13
+
+/* Black clamp related */
+#define ISIF_BC_MODE_COLOR_SHIFT		4
+#define ISIF_HORZ_BC_MODE_SHIFT			1
+#define ISIF_HORZ_BC_WIN_SEL_SHIFT		5
+#define ISIF_HORZ_BC_PIX_LIMIT_SHIFT		6
+#define ISIF_HORZ_BC_WIN_H_SIZE_SHIFT		8
+#define ISIF_HORZ_BC_WIN_V_SIZE_SHIFT		12
+#define	ISIF_VERT_BC_RST_VAL_SEL_SHIFT		4
+#define ISIF_VERT_BC_LINE_AVE_COEF_SHIFT	8
+
+/* VDFC registers */
+#define ISIF_VDFC_EN_SHIFT			4
+#define ISIF_VDFC_CORR_MOD_SHIFT		5
+#define ISIF_VDFC_CORR_WHOLE_LN_SHIFT		7
+#define ISIF_VDFC_LEVEL_SHFT_SHIFT		8
+#define ISIF_VDFC_POS_MASK			0x1FFF
+#define ISIF_DFCMEMCTL_DFCMARST_SHIFT		2
+
+/* CSC registers */
+#define ISIF_CSC_COEF_INTEG_MASK		7
+#define ISIF_CSC_COEF_DECIMAL_MASK		0x1f
+#define ISIF_CSC_COEF_INTEG_SHIFT		5
+#define ISIF_CSCM_MSB_SHIFT			8
+#define ISIF_DF_CSC_SPH_MASK			0x1FFF
+#define ISIF_DF_CSC_LNH_MASK			0x1FFF
+#define ISIF_DF_CSC_SLV_MASK			0x1FFF
+#define ISIF_DF_CSC_LNV_MASK			0x1FFF
+#define ISIF_DF_NUMLINES			0x7FFF
+#define ISIF_DF_NUMPIX				0x1FFF
+
+/* Offsets for LSC/DFC/Gain */
+#define ISIF_DATA_H_OFFSET_MASK			0x1FFF
+#define ISIF_DATA_V_OFFSET_MASK			0x1FFF
+
+/* Linearization */
+#define ISIF_LIN_CORRSFT_SHIFT			4
+#define ISIF_LIN_SCALE_FACT_INTEG_SHIFT		10
+
+
+/* Pattern registers */
+#define ISIF_PG_EN				(1 << 3)
+#define ISIF_SEL_PG_SRC				(3 << 4)
+#define ISIF_PG_VD_POL_SHIFT			0
+#define ISIF_PG_HD_POL_SHIFT			1
+
+/*random other junk*/
+#define ISIF_SYNCEN_VDHDEN_MASK			(1 << 0)
+#define ISIF_SYNCEN_WEN_MASK			(1 << 1)
+#define ISIF_SYNCEN_WEN_SHIFT			1
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/davinci/Makefile linux-libre-2.6.34-gnu1/drivers/media/video/davinci/Makefile
--- linux-libre-2.6.33-gnu1/drivers/media/video/davinci/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/davinci/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -15,3 +15,4 @@ obj-$(CONFIG_VIDEO_VPSS_SYSTEM) += vpss.
 obj-$(CONFIG_VIDEO_VPFE_CAPTURE) += vpfe_capture.o
 obj-$(CONFIG_VIDEO_DM6446_CCDC) += dm644x_ccdc.o
 obj-$(CONFIG_VIDEO_DM355_CCDC) += dm355_ccdc.o
+obj-$(CONFIG_VIDEO_ISIF) += isif.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpfe_capture.c linux-libre-2.6.34-gnu1/drivers/media/video/davinci/vpfe_capture.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpfe_capture.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/davinci/vpfe_capture.c	2010-05-16 17:17:36.000000000 -0400
@@ -67,6 +67,7 @@
  *		- Support for control ioctls
  */
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
@@ -107,9 +108,6 @@ struct ccdc_config {
 	int vpfe_probed;
 	/* name of ccdc device */
 	char name[32];
-	/* for storing mem maps for CCDC */
-	int ccdc_addr_size;
-	void *__iomem ccdc_addr;
 };
 
 /* data structures */
@@ -225,11 +223,9 @@ int vpfe_register_ccdc_device(struct ccd
 	BUG_ON(!dev->hw_ops.get_frame_format);
 	BUG_ON(!dev->hw_ops.get_pixel_format);
 	BUG_ON(!dev->hw_ops.set_pixel_format);
-	BUG_ON(!dev->hw_ops.set_params);
 	BUG_ON(!dev->hw_ops.set_image_window);
 	BUG_ON(!dev->hw_ops.get_image_window);
 	BUG_ON(!dev->hw_ops.get_line_length);
-	BUG_ON(!dev->hw_ops.setfbaddr);
 	BUG_ON(!dev->hw_ops.getfid);
 
 	mutex_lock(&ccdc_lock);
@@ -240,25 +236,23 @@ int vpfe_register_ccdc_device(struct ccd
 		 * walk through it during vpfe probe
 		 */
 		printk(KERN_ERR "vpfe capture not initialized\n");
-		ret = -1;
+		ret = -EFAULT;
 		goto unlock;
 	}
 
 	if (strcmp(dev->name, ccdc_cfg->name)) {
 		/* ignore this ccdc */
-		ret = -1;
+		ret = -EINVAL;
 		goto unlock;
 	}
 
 	if (ccdc_dev) {
 		printk(KERN_ERR "ccdc already registered\n");
-		ret = -1;
+		ret = -EINVAL;
 		goto unlock;
 	}
 
 	ccdc_dev = dev;
-	dev->hw_ops.set_ccdc_base(ccdc_cfg->ccdc_addr,
-				  ccdc_cfg->ccdc_addr_size);
 unlock:
 	mutex_unlock(&ccdc_lock);
 	return ret;
@@ -1694,11 +1688,12 @@ static long vpfe_param_handler(struct fi
 	struct vpfe_device *vpfe_dev = video_drvdata(file);
 	int ret = 0;
 
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n");
+	v4l2_dbg(2, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n");
 
 	if (vpfe_dev->started) {
 		/* only allowed if streaming is not started */
-		v4l2_err(&vpfe_dev->v4l2_dev, "device already started\n");
+		v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+			"device already started\n");
 		return -EBUSY;
 	}
 
@@ -1710,16 +1705,23 @@ static long vpfe_param_handler(struct fi
 	case VPFE_CMD_S_CCDC_RAW_PARAMS:
 		v4l2_warn(&vpfe_dev->v4l2_dev,
 			  "VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n");
-		ret = ccdc_dev->hw_ops.set_params(param);
-		if (ret) {
-			v4l2_err(&vpfe_dev->v4l2_dev,
-				"Error in setting parameters in CCDC\n");
-			goto unlock_out;
-		}
-		if (vpfe_get_ccdc_image_format(vpfe_dev, &vpfe_dev->fmt) < 0) {
-			v4l2_err(&vpfe_dev->v4l2_dev,
-				"Invalid image format at CCDC\n");
-			goto unlock_out;
+		if (ccdc_dev->hw_ops.set_params) {
+			ret = ccdc_dev->hw_ops.set_params(param);
+			if (ret) {
+				v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+					"Error setting parameters in CCDC\n");
+				goto unlock_out;
+			}
+			if (vpfe_get_ccdc_image_format(vpfe_dev,
+						       &vpfe_dev->fmt) < 0) {
+				v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+					"Invalid image format at CCDC\n");
+				goto unlock_out;
+			}
+		} else {
+			ret = -EINVAL;
+			v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+				"VPFE_CMD_S_CCDC_RAW_PARAMS not supported\n");
 		}
 		break;
 	default:
@@ -1786,61 +1788,6 @@ static struct vpfe_device *vpfe_initiali
 	return vpfe_dev;
 }
 
-static void vpfe_disable_clock(struct vpfe_device *vpfe_dev)
-{
-	struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
-
-	clk_disable(vpfe_cfg->vpssclk);
-	clk_put(vpfe_cfg->vpssclk);
-	clk_disable(vpfe_cfg->slaveclk);
-	clk_put(vpfe_cfg->slaveclk);
-	v4l2_info(vpfe_dev->pdev->driver,
-		 "vpfe vpss master & slave clocks disabled\n");
-}
-
-static int vpfe_enable_clock(struct vpfe_device *vpfe_dev)
-{
-	struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
-	int ret = -ENOENT;
-
-	vpfe_cfg->vpssclk = clk_get(vpfe_dev->pdev, "vpss_master");
-	if (NULL == vpfe_cfg->vpssclk) {
-		v4l2_err(vpfe_dev->pdev->driver, "No clock defined for"
-			 "vpss_master\n");
-		return ret;
-	}
-
-	if (clk_enable(vpfe_cfg->vpssclk)) {
-		v4l2_err(vpfe_dev->pdev->driver,
-			"vpfe vpss master clock not enabled\n");
-		goto out;
-	}
-	v4l2_info(vpfe_dev->pdev->driver,
-		 "vpfe vpss master clock enabled\n");
-
-	vpfe_cfg->slaveclk = clk_get(vpfe_dev->pdev, "vpss_slave");
-	if (NULL == vpfe_cfg->slaveclk) {
-		v4l2_err(vpfe_dev->pdev->driver,
-			"No clock defined for vpss slave\n");
-		goto out;
-	}
-
-	if (clk_enable(vpfe_cfg->slaveclk)) {
-		v4l2_err(vpfe_dev->pdev->driver,
-			 "vpfe vpss slave clock not enabled\n");
-		goto out;
-	}
-	v4l2_info(vpfe_dev->pdev->driver, "vpfe vpss slave clock enabled\n");
-	return 0;
-out:
-	if (vpfe_cfg->vpssclk)
-		clk_put(vpfe_cfg->vpssclk);
-	if (vpfe_cfg->slaveclk)
-		clk_put(vpfe_cfg->slaveclk);
-
-	return -1;
-}
-
 /*
  * vpfe_probe : This function creates device entries by register
  * itself to the V4L2 driver and initializes fields of each
@@ -1870,7 +1817,7 @@ static __init int vpfe_probe(struct plat
 
 	if (NULL == pdev->dev.platform_data) {
 		v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
-		ret = -ENOENT;
+		ret = -ENODEV;
 		goto probe_free_dev_mem;
 	}
 
@@ -1884,18 +1831,13 @@ static __init int vpfe_probe(struct plat
 		goto probe_free_dev_mem;
 	}
 
-	/* enable vpss clocks */
-	ret = vpfe_enable_clock(vpfe_dev);
-	if (ret)
-		goto probe_free_dev_mem;
-
 	mutex_lock(&ccdc_lock);
 	/* Allocate memory for ccdc configuration */
 	ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL);
 	if (NULL == ccdc_cfg) {
 		v4l2_err(pdev->dev.driver,
 			 "Memory allocation failed for ccdc_cfg\n");
-		goto probe_disable_clock;
+		goto probe_free_lock;
 	}
 
 	strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32);
@@ -1904,61 +1846,34 @@ static __init int vpfe_probe(struct plat
 	if (!res1) {
 		v4l2_err(pdev->dev.driver,
 			 "Unable to get interrupt for VINT0\n");
-		ret = -ENOENT;
-		goto probe_disable_clock;
+		ret = -ENODEV;
+		goto probe_free_ccdc_cfg_mem;
 	}
 	vpfe_dev->ccdc_irq0 = res1->start;
 
 	/* Get VINT1 irq resource */
-	res1 = platform_get_resource(pdev,
-				IORESOURCE_IRQ, 1);
+	res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
 	if (!res1) {
 		v4l2_err(pdev->dev.driver,
 			 "Unable to get interrupt for VINT1\n");
-		ret = -ENOENT;
-		goto probe_disable_clock;
+		ret = -ENODEV;
+		goto probe_free_ccdc_cfg_mem;
 	}
 	vpfe_dev->ccdc_irq1 = res1->start;
 
-	/* Get address base of CCDC */
-	res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res1) {
-		v4l2_err(pdev->dev.driver,
-			"Unable to get register address map\n");
-		ret = -ENOENT;
-		goto probe_disable_clock;
-	}
-
-	ccdc_cfg->ccdc_addr_size = res1->end - res1->start + 1;
-	if (!request_mem_region(res1->start, ccdc_cfg->ccdc_addr_size,
-				pdev->dev.driver->name)) {
-		v4l2_err(pdev->dev.driver,
-			"Failed request_mem_region for ccdc base\n");
-		ret = -ENXIO;
-		goto probe_disable_clock;
-	}
-	ccdc_cfg->ccdc_addr = ioremap_nocache(res1->start,
-					     ccdc_cfg->ccdc_addr_size);
-	if (!ccdc_cfg->ccdc_addr) {
-		v4l2_err(pdev->dev.driver, "Unable to ioremap ccdc addr\n");
-		ret = -ENXIO;
-		goto probe_out_release_mem1;
-	}
-
 	ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED,
 			  "vpfe_capture0", vpfe_dev);
 
 	if (0 != ret) {
 		v4l2_err(pdev->dev.driver, "Unable to request interrupt\n");
-		goto probe_out_unmap1;
+		goto probe_free_ccdc_cfg_mem;
 	}
 
 	/* Allocate memory for video device */
 	vfd = video_device_alloc();
 	if (NULL == vfd) {
 		ret = -ENOMEM;
-		v4l2_err(pdev->dev.driver,
-			"Unable to alloc video device\n");
+		v4l2_err(pdev->dev.driver, "Unable to alloc video device\n");
 		goto probe_out_release_irq;
 	}
 
@@ -2073,14 +1988,10 @@ probe_out_video_release:
 		video_device_release(vpfe_dev->video_dev);
 probe_out_release_irq:
 	free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
-probe_out_unmap1:
-	iounmap(ccdc_cfg->ccdc_addr);
-probe_out_release_mem1:
-	release_mem_region(res1->start, res1->end - res1->start + 1);
-probe_disable_clock:
-	vpfe_disable_clock(vpfe_dev);
-	mutex_unlock(&ccdc_lock);
+probe_free_ccdc_cfg_mem:
 	kfree(ccdc_cfg);
+probe_free_lock:
+	mutex_unlock(&ccdc_lock);
 probe_free_dev_mem:
 	kfree(vpfe_dev);
 	return ret;
@@ -2092,7 +2003,6 @@ probe_free_dev_mem:
 static int __devexit vpfe_remove(struct platform_device *pdev)
 {
 	struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
-	struct resource *res;
 
 	v4l2_info(pdev->dev.driver, "vpfe_remove\n");
 
@@ -2100,12 +2010,6 @@ static int __devexit vpfe_remove(struct
 	kfree(vpfe_dev->sd);
 	v4l2_device_unregister(&vpfe_dev->v4l2_dev);
 	video_unregister_device(vpfe_dev->video_dev);
-	mutex_lock(&ccdc_lock);
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(res->start, res->end - res->start + 1);
-	iounmap(ccdc_cfg->ccdc_addr);
-	mutex_unlock(&ccdc_lock);
-	vpfe_disable_clock(vpfe_dev);
 	kfree(vpfe_dev);
 	kfree(ccdc_cfg);
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpif_capture.c linux-libre-2.6.34-gnu1/drivers/media/video/davinci/vpif_capture.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpif_capture.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/davinci/vpif_capture.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/version.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpif_display.c linux-libre-2.6.34-gnu1/drivers/media/video/davinci/vpif_display.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpif_display.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/davinci/vpif_display.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/version.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 #include <asm/page.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpss.c linux-libre-2.6.34-gnu1/drivers/media/video/davinci/vpss.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpss.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/davinci/vpss.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * common vpss driver for all video drivers.
+ * common vpss system module platform driver for all video drivers.
  */
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -35,12 +35,52 @@ MODULE_AUTHOR("Texas Instruments");
 /* DM644x defines */
 #define DM644X_SBL_PCR_VPSS		(4)
 
+#define DM355_VPSSBL_INTSEL		0x10
+#define DM355_VPSSBL_EVTSEL		0x14
 /* vpss BL register offsets */
 #define DM355_VPSSBL_CCDCMUX		0x1c
 /* vpss CLK register offsets */
 #define DM355_VPSSCLK_CLKCTRL		0x04
 /* masks and shifts */
 #define VPSS_HSSISEL_SHIFT		4
+/*
+ * VDINT0 - vpss_int0, VDINT1 - vpss_int1, H3A - vpss_int4,
+ * IPIPE_INT1_SDR - vpss_int5
+ */
+#define DM355_VPSSBL_INTSEL_DEFAULT	0xff83ff10
+/* VENCINT - vpss_int8 */
+#define DM355_VPSSBL_EVTSEL_DEFAULT	0x4
+
+#define DM365_ISP5_PCCR 		0x04
+#define DM365_ISP5_INTSEL1		0x10
+#define DM365_ISP5_INTSEL2		0x14
+#define DM365_ISP5_INTSEL3		0x18
+#define DM365_ISP5_CCDCMUX 		0x20
+#define DM365_ISP5_PG_FRAME_SIZE 	0x28
+#define DM365_VPBE_CLK_CTRL 		0x00
+/*
+ * vpss interrupts. VDINT0 - vpss_int0, VDINT1 - vpss_int1,
+ * AF - vpss_int3
+ */
+#define DM365_ISP5_INTSEL1_DEFAULT	0x0b1f0100
+/* AEW - vpss_int6, RSZ_INT_DMA - vpss_int5 */
+#define DM365_ISP5_INTSEL2_DEFAULT	0x1f0a0f1f
+/* VENC - vpss_int8 */
+#define DM365_ISP5_INTSEL3_DEFAULT	0x00000015
+
+/* masks and shifts for DM365*/
+#define DM365_CCDC_PG_VD_POL_SHIFT 	0
+#define DM365_CCDC_PG_HD_POL_SHIFT 	1
+
+#define CCD_SRC_SEL_MASK		(BIT_MASK(5) | BIT_MASK(4))
+#define CCD_SRC_SEL_SHIFT		4
+
+/* Different SoC platforms supported by this driver */
+enum vpss_platform_type {
+	DM644X,
+	DM355,
+	DM365,
+};
 
 /*
  * vpss operations. Depends on platform. Not all functions are available
@@ -59,13 +99,9 @@ struct vpss_hw_ops {
 
 /* vpss configuration */
 struct vpss_oper_config {
-	__iomem void *vpss_bl_regs_base;
-	__iomem void *vpss_regs_base;
-	struct resource		*r1;
-	resource_size_t		len1;
-	struct resource		*r2;
-	resource_size_t		len2;
-	char vpss_name[32];
+	__iomem void *vpss_regs_base0;
+	__iomem void *vpss_regs_base1;
+	enum vpss_platform_type platform;
 	spinlock_t vpss_lock;
 	struct vpss_hw_ops hw_ops;
 };
@@ -75,22 +111,46 @@ static struct vpss_oper_config oper_cfg;
 /* register access routines */
 static inline u32 bl_regr(u32 offset)
 {
-	return __raw_readl(oper_cfg.vpss_bl_regs_base + offset);
+	return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
 }
 
 static inline void bl_regw(u32 val, u32 offset)
 {
-	__raw_writel(val, oper_cfg.vpss_bl_regs_base + offset);
+	__raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
 }
 
 static inline u32 vpss_regr(u32 offset)
 {
-	return __raw_readl(oper_cfg.vpss_regs_base + offset);
+	return __raw_readl(oper_cfg.vpss_regs_base1 + offset);
 }
 
 static inline void vpss_regw(u32 val, u32 offset)
 {
-	__raw_writel(val, oper_cfg.vpss_regs_base + offset);
+	__raw_writel(val, oper_cfg.vpss_regs_base1 + offset);
+}
+
+/* For DM365 only */
+static inline u32 isp5_read(u32 offset)
+{
+	return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
+}
+
+/* For DM365 only */
+static inline void isp5_write(u32 val, u32 offset)
+{
+	__raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
+}
+
+static void dm365_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
+{
+	u32 temp = isp5_read(DM365_ISP5_CCDCMUX) & ~CCD_SRC_SEL_MASK;
+
+	/* if we are using pattern generator, enable it */
+	if (src_sel == VPSS_PGLPBK || src_sel == VPSS_CCDCPG)
+		temp |= 0x08;
+
+	temp |= (src_sel << CCD_SRC_SEL_SHIFT);
+	isp5_write(temp, DM365_ISP5_CCDCMUX);
 }
 
 static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
@@ -101,9 +161,9 @@ static void dm355_select_ccdc_source(enu
 int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
 {
 	if (!oper_cfg.hw_ops.select_ccdc_source)
-		return -1;
+		return -EINVAL;
 
-	dm355_select_ccdc_source(src_sel);
+	oper_cfg.hw_ops.select_ccdc_source(src_sel);
 	return 0;
 }
 EXPORT_SYMBOL(vpss_select_ccdc_source);
@@ -114,7 +174,7 @@ static int dm644x_clear_wbl_overflow(enu
 
 	if (wbl_sel < VPSS_PCR_AEW_WBL_0 ||
 	    wbl_sel > VPSS_PCR_CCDC_WBL_O)
-		return -1;
+		return -EINVAL;
 
 	/* writing a 0 clear the overflow */
 	mask = ~(mask << wbl_sel);
@@ -126,7 +186,7 @@ static int dm644x_clear_wbl_overflow(enu
 int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
 {
 	if (!oper_cfg.hw_ops.clear_wbl_overflow)
-		return -1;
+		return -EINVAL;
 
 	return oper_cfg.hw_ops.clear_wbl_overflow(wbl_sel);
 }
@@ -166,7 +226,7 @@ static int dm355_enable_clock(enum vpss_
 	default:
 		printk(KERN_ERR "dm355_enable_clock:"
 				" Invalid selector: %d\n", clock_sel);
-		return -1;
+		return -EINVAL;
 	}
 
 	spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
@@ -181,100 +241,221 @@ static int dm355_enable_clock(enum vpss_
 	return 0;
 }
 
+static int dm365_enable_clock(enum vpss_clock_sel clock_sel, int en)
+{
+	unsigned long flags;
+	u32 utemp, mask = 0x1, shift = 0, offset = DM365_ISP5_PCCR;
+	u32 (*read)(u32 offset) = isp5_read;
+	void(*write)(u32 val, u32 offset) = isp5_write;
+
+	switch (clock_sel) {
+	case VPSS_BL_CLOCK:
+		break;
+	case VPSS_CCDC_CLOCK:
+		shift = 1;
+		break;
+	case VPSS_H3A_CLOCK:
+		shift = 2;
+		break;
+	case VPSS_RSZ_CLOCK:
+		shift = 3;
+		break;
+	case VPSS_IPIPE_CLOCK:
+		shift = 4;
+		break;
+	case VPSS_IPIPEIF_CLOCK:
+		shift = 5;
+		break;
+	case VPSS_PCLK_INTERNAL:
+		shift = 6;
+		break;
+	case VPSS_PSYNC_CLOCK_SEL:
+		shift = 7;
+		break;
+	case VPSS_VPBE_CLOCK:
+		read = vpss_regr;
+		write = vpss_regw;
+		offset = DM365_VPBE_CLK_CTRL;
+		break;
+	case VPSS_VENC_CLOCK_SEL:
+		shift = 2;
+		read = vpss_regr;
+		write = vpss_regw;
+		offset = DM365_VPBE_CLK_CTRL;
+		break;
+	case VPSS_LDC_CLOCK:
+		shift = 3;
+		read = vpss_regr;
+		write = vpss_regw;
+		offset = DM365_VPBE_CLK_CTRL;
+		break;
+	case VPSS_FDIF_CLOCK:
+		shift = 4;
+		read = vpss_regr;
+		write = vpss_regw;
+		offset = DM365_VPBE_CLK_CTRL;
+		break;
+	case VPSS_OSD_CLOCK_SEL:
+		shift = 6;
+		read = vpss_regr;
+		write = vpss_regw;
+		offset = DM365_VPBE_CLK_CTRL;
+		break;
+	case VPSS_LDC_CLOCK_SEL:
+		shift = 7;
+		read = vpss_regr;
+		write = vpss_regw;
+		offset = DM365_VPBE_CLK_CTRL;
+		break;
+	default:
+		printk(KERN_ERR "dm365_enable_clock: Invalid selector: %d\n",
+		       clock_sel);
+		return -1;
+	}
+
+	spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
+	utemp = read(offset);
+	if (!en) {
+		mask = ~mask;
+		utemp &= (mask << shift);
+	} else
+		utemp |= (mask << shift);
+
+	write(utemp, offset);
+	spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
+
+	return 0;
+}
+
 int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en)
 {
 	if (!oper_cfg.hw_ops.enable_clock)
-		return -1;
+		return -EINVAL;
 
 	return oper_cfg.hw_ops.enable_clock(clock_sel, en);
 }
 EXPORT_SYMBOL(vpss_enable_clock);
 
+void dm365_vpss_set_sync_pol(struct vpss_sync_pol sync)
+{
+	int val = 0;
+	val = isp5_read(DM365_ISP5_CCDCMUX);
+
+	val |= (sync.ccdpg_hdpol << DM365_CCDC_PG_HD_POL_SHIFT);
+	val |= (sync.ccdpg_vdpol << DM365_CCDC_PG_VD_POL_SHIFT);
+
+	isp5_write(val, DM365_ISP5_CCDCMUX);
+}
+EXPORT_SYMBOL(dm365_vpss_set_sync_pol);
+
+void dm365_vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size)
+{
+	int current_reg = ((frame_size.hlpfr >> 1) - 1) << 16;
+
+	current_reg |= (frame_size.pplen - 1);
+	isp5_write(current_reg, DM365_ISP5_PG_FRAME_SIZE);
+}
+EXPORT_SYMBOL(dm365_vpss_set_pg_frame_size);
+
 static int __init vpss_probe(struct platform_device *pdev)
 {
-	int status, dm355 = 0;
+	struct resource		*r1, *r2;
+	char *platform_name;
+	int status;
 
 	if (!pdev->dev.platform_data) {
 		dev_err(&pdev->dev, "no platform data\n");
 		return -ENOENT;
 	}
-	strcpy(oper_cfg.vpss_name, pdev->dev.platform_data);
 
-	if (!strcmp(oper_cfg.vpss_name, "dm355_vpss"))
-		dm355 = 1;
-	else if (strcmp(oper_cfg.vpss_name, "dm644x_vpss")) {
+	platform_name = pdev->dev.platform_data;
+	if (!strcmp(platform_name, "dm355_vpss"))
+		oper_cfg.platform = DM355;
+	else if (!strcmp(platform_name, "dm365_vpss"))
+		oper_cfg.platform = DM365;
+	else if (!strcmp(platform_name, "dm644x_vpss"))
+		oper_cfg.platform = DM644X;
+	else {
 		dev_err(&pdev->dev, "vpss driver not supported on"
 			" this platform\n");
 		return -ENODEV;
 	}
 
-	dev_info(&pdev->dev, "%s vpss probed\n", oper_cfg.vpss_name);
-	oper_cfg.r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!oper_cfg.r1)
+	dev_info(&pdev->dev, "%s vpss probed\n", platform_name);
+	r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r1)
 		return -ENOENT;
 
-	oper_cfg.len1 = oper_cfg.r1->end - oper_cfg.r1->start + 1;
-
-	oper_cfg.r1 = request_mem_region(oper_cfg.r1->start, oper_cfg.len1,
-					 oper_cfg.r1->name);
-	if (!oper_cfg.r1)
+	r1 = request_mem_region(r1->start, resource_size(r1), r1->name);
+	if (!r1)
 		return -EBUSY;
 
-	oper_cfg.vpss_bl_regs_base = ioremap(oper_cfg.r1->start, oper_cfg.len1);
-	if (!oper_cfg.vpss_bl_regs_base) {
+	oper_cfg.vpss_regs_base0 = ioremap(r1->start, resource_size(r1));
+	if (!oper_cfg.vpss_regs_base0) {
 		status = -EBUSY;
 		goto fail1;
 	}
 
-	if (dm355) {
-		oper_cfg.r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-		if (!oper_cfg.r2) {
+	if (oper_cfg.platform == DM355 || oper_cfg.platform == DM365) {
+		r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+		if (!r2) {
 			status = -ENOENT;
 			goto fail2;
 		}
-		oper_cfg.len2 = oper_cfg.r2->end - oper_cfg.r2->start + 1;
-		oper_cfg.r2 = request_mem_region(oper_cfg.r2->start,
-						 oper_cfg.len2,
-						 oper_cfg.r2->name);
-		if (!oper_cfg.r2) {
+		r2 = request_mem_region(r2->start, resource_size(r2), r2->name);
+		if (!r2) {
 			status = -EBUSY;
 			goto fail2;
 		}
 
-		oper_cfg.vpss_regs_base = ioremap(oper_cfg.r2->start,
-						  oper_cfg.len2);
-		if (!oper_cfg.vpss_regs_base) {
+		oper_cfg.vpss_regs_base1 = ioremap(r2->start,
+						   resource_size(r2));
+		if (!oper_cfg.vpss_regs_base1) {
 			status = -EBUSY;
 			goto fail3;
 		}
 	}
 
-	if (dm355) {
+	if (oper_cfg.platform == DM355) {
 		oper_cfg.hw_ops.enable_clock = dm355_enable_clock;
 		oper_cfg.hw_ops.select_ccdc_source = dm355_select_ccdc_source;
+		/* Setup vpss interrupts */
+		bl_regw(DM355_VPSSBL_INTSEL_DEFAULT, DM355_VPSSBL_INTSEL);
+		bl_regw(DM355_VPSSBL_EVTSEL_DEFAULT, DM355_VPSSBL_EVTSEL);
+	} else if (oper_cfg.platform == DM365) {
+		oper_cfg.hw_ops.enable_clock = dm365_enable_clock;
+		oper_cfg.hw_ops.select_ccdc_source = dm365_select_ccdc_source;
+		/* Setup vpss interrupts */
+		isp5_write(DM365_ISP5_INTSEL1_DEFAULT, DM365_ISP5_INTSEL1);
+		isp5_write(DM365_ISP5_INTSEL2_DEFAULT, DM365_ISP5_INTSEL2);
+		isp5_write(DM365_ISP5_INTSEL3_DEFAULT, DM365_ISP5_INTSEL3);
 	} else
 		oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow;
 
 	spin_lock_init(&oper_cfg.vpss_lock);
-	dev_info(&pdev->dev, "%s vpss probe success\n", oper_cfg.vpss_name);
+	dev_info(&pdev->dev, "%s vpss probe success\n", platform_name);
 	return 0;
 
 fail3:
-	release_mem_region(oper_cfg.r2->start, oper_cfg.len2);
+	release_mem_region(r2->start, resource_size(r2));
 fail2:
-	iounmap(oper_cfg.vpss_bl_regs_base);
+	iounmap(oper_cfg.vpss_regs_base0);
 fail1:
-	release_mem_region(oper_cfg.r1->start, oper_cfg.len1);
+	release_mem_region(r1->start, resource_size(r1));
 	return status;
 }
 
 static int __devexit vpss_remove(struct platform_device *pdev)
 {
-	iounmap(oper_cfg.vpss_bl_regs_base);
-	release_mem_region(oper_cfg.r1->start, oper_cfg.len1);
-	if (!strcmp(oper_cfg.vpss_name, "dm355_vpss")) {
-		iounmap(oper_cfg.vpss_regs_base);
-		release_mem_region(oper_cfg.r2->start, oper_cfg.len2);
+	struct resource		*res;
+
+	iounmap(oper_cfg.vpss_regs_base0);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, resource_size(res));
+	if (oper_cfg.platform == DM355 || oper_cfg.platform == DM365) {
+		iounmap(oper_cfg.vpss_regs_base1);
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+		release_mem_region(res->start, resource_size(res));
 	}
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-cards.c linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx-cards.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-cards.c	2013-05-03 12:03:50.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx-cards.c	2013-05-03 09:44:45.000000000 -0400
@@ -24,6 +24,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/usb.h>
@@ -232,6 +233,12 @@ static struct em28xx_reg_seq vc211a_enab
 	{	-1,		-1,	-1,		-1},
 };
 
+static struct em28xx_reg_seq dikom_dk300_digital[] = {
+	{EM28XX_R08_GPIO,	0x6e,	~EM_GPIO_4,	10},
+	{EM2880_R04_GPO,	0x08,	0xff,		10},
+	{ -1,			-1,	-1,		-1},
+};
+
 
 /*
  *  Board definitions
@@ -461,21 +468,30 @@ struct em28xx_board em28xx_boards[] = {
 		.name         = "Leadtek Winfast USB II Deluxe",
 		.valid        = EM28XX_BOARD_NOT_VALIDATED,
 		.tuner_type   = TUNER_PHILIPS_FM1216ME_MK3,
-		.tda9887_conf = TDA9887_PRESENT,
+		.has_ir_i2c   = 1,
+		.tvaudio_addr = 0x58,
+		.tda9887_conf = TDA9887_PRESENT |
+				TDA9887_PORT2_ACTIVE |
+				TDA9887_QSS,
 		.decoder      = EM28XX_SAA711X,
+		.adecoder     = EM28XX_TVAUDIO,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
-			.vmux     = SAA7115_COMPOSITE2,
-			.amux     = EM28XX_AMUX_VIDEO,
+			.vmux     = SAA7115_COMPOSITE4,
+			.amux     = EM28XX_AMUX_AUX,
 		}, {
 			.type     = EM28XX_VMUX_COMPOSITE1,
-			.vmux     = SAA7115_COMPOSITE0,
+			.vmux     = SAA7115_COMPOSITE5,
 			.amux     = EM28XX_AMUX_LINE_IN,
 		}, {
 			.type     = EM28XX_VMUX_SVIDEO,
-			.vmux     = SAA7115_COMPOSITE0,
+			.vmux     = SAA7115_SVIDEO3,
 			.amux     = EM28XX_AMUX_LINE_IN,
 		} },
+			.radio	  = {
+			.type     = EM28XX_RADIO,
+			.amux     = EM28XX_AMUX_AUX,
+			}
 	},
 	[EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
 		.name         = "Videology 20K14XUSB USB2.0",
@@ -730,11 +746,12 @@ struct em28xx_board em28xx_boards[] = {
 
 	[EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = {
 		.name         = "Terratec Hybrid XS Secam",
-		.valid        = EM28XX_BOARD_NOT_VALIDATED,
 		.has_msp34xx  = 1,
 		.tuner_type   = TUNER_XC2028,
 		.tuner_gpio   = default_tuner_gpio,
 		.decoder      = EM28XX_TVP5150,
+		.has_dvb      = 1,
+		.dvb_gpio     = default_digital,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
 			.vmux     = TVP5150_COMPOSITE0,
@@ -1265,6 +1282,7 @@ struct em28xx_board em28xx_boards[] = {
 		.decoder	= EM28XX_SAA711X,
 		.has_dvb	= 1,
 		.dvb_gpio	= em2882_kworld_315u_digital,
+		.ir_codes	= &ir_codes_kworld_315u_table,
 		.xclk		= EM28XX_XCLK_FREQUENCY_12MHZ,
 		.i2c_speed	= EM28XX_I2C_CLK_WAIT_ENABLE,
 		/* Analog mode - still not ready */
@@ -1431,6 +1449,21 @@ struct em28xx_board em28xx_boards[] = {
 			.gpio     = hauppauge_wintv_hvr_900_analog,
 		} },
 	},
+	[EM2882_BOARD_DIKOM_DK300] = {
+		.name         = "Dikom DK300",
+		.tuner_type   = TUNER_XC2028,
+		.tuner_gpio   = default_tuner_gpio,
+		.decoder      = EM28XX_TVP5150,
+		.mts_firmware = 1,
+		.has_dvb      = 1,
+		.dvb_gpio     = dikom_dk300_digital,
+		.input        = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = EM28XX_AMUX_VIDEO,
+			.gpio     = default_analog,
+		} },
+	},
 	[EM2883_BOARD_KWORLD_HYBRID_330U] = {
 		.name         = "Kworld PlusTV HD Hybrid 330",
 		.tuner_type   = TUNER_XC2028,
@@ -1751,6 +1784,7 @@ static struct em28xx_hash_table em28xx_e
 	{0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028},
 	{0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028},
 	{0x63f653bd, EM2870_BOARD_REDDO_DVB_C_USB_BOX, TUNER_ABSENT},
+	{0x4e913442, EM2882_BOARD_DIKOM_DK300, TUNER_XC2028},
 };
 
 /* I2C devicelist hash table for devices with generic USB IDs */
@@ -2103,6 +2137,7 @@ static void em28xx_setup_xc3028(struct e
 		ctl->demod = XC3028_FE_DEFAULT;
 		break;
 	case EM2883_BOARD_KWORLD_HYBRID_330U:
+	case EM2882_BOARD_DIKOM_DK300:
 		ctl->demod = XC3028_FE_CHINA;
 		ctl->fname = "/*(DEBLOBBED)*/";
 		break;
@@ -2259,9 +2294,12 @@ static int em28xx_hint_board(struct em28
 /* ----------------------------------------------------------------------- */
 void em28xx_register_i2c_ir(struct em28xx *dev)
 {
+	/* Leadtek winfast tv USBII deluxe can find a non working IR-device */
+	/* at address 0x18, so if that address is needed for another board in */
+	/* the future, please put it after 0x1f. */
 	struct i2c_board_info info;
 	const unsigned short addr_list[] = {
-		 0x30, 0x47, I2C_CLIENT_END
+		 0x1f, 0x30, 0x47, I2C_CLIENT_END
 	};
 
 	if (disable_ir)
@@ -2288,6 +2326,10 @@ void em28xx_register_i2c_ir(struct em28x
 		dev->init_data.ir_codes = &ir_codes_rc5_hauppauge_new_table;
 		dev->init_data.get_key = em28xx_get_key_em_haup;
 		dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
+	case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
+		dev->init_data.ir_codes = &ir_codes_winfast_usbii_deluxe_table;;
+		dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe;
+		dev->init_data.name = "i2c IR (EM2820 Winfast TV USBII Deluxe)";
 		break;
 	}
 
@@ -2374,6 +2416,31 @@ void em28xx_card_setup(struct em28xx *de
 		if (!em28xx_hint_board(dev))
 			em28xx_set_model(dev);
 
+		/* In cases where we had to use a board hint, the call to
+		   em28xx_set_mode() in em28xx_pre_card_setup() was a no-op,
+		   so make the call now so the analog GPIOs are set properly
+		   before probing the i2c bus. */
+		em28xx_gpio_set(dev, dev->board.tuner_gpio);
+		em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
+		break;
+
+/*
+		 * The Dikom DK300 is detected as an Kworld VS-DVB-T 323UR.
+		 *
+		 * This occurs because they share identical USB vendor and
+		 * product IDs.
+		 *
+		 * What we do here is look up the EEPROM hash of the Dikom
+		 * and if it is found then we decide that we do not have
+		 * a Kworld and reset the device to the Dikom instead.
+		 *
+		 * This solution is only valid if they do not share eeprom
+		 * hash identities which has not been determined as yet.
+		 */
+	case EM2882_BOARD_KWORLD_VS_DVBT:
+		if (!em28xx_hint_board(dev))
+			em28xx_set_model(dev);
+
 		/* In cases where we had to use a board hint, the call to
 		   em28xx_set_mode() in em28xx_pre_card_setup() was a no-op,
 		   so make the call now so the analog GPIOs are set properly
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-core.c linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx-core.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/vmalloc.h>
 #include <media/v4l2-common.h>
@@ -691,9 +692,15 @@ int em28xx_set_outfmt(struct em28xx *dev
 	if (em28xx_vbi_supported(dev) == 1) {
 		vinctrl |= EM28XX_VINCTRL_VBI_RAW;
 		em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00);
-		em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09);
-		em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, 0xb4);
-		em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, 0x0c);
+		em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, dev->vbi_width/4);
+		em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, dev->vbi_height);
+		if (dev->norm & V4L2_STD_525_60) {
+			/* NTSC */
+			em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09);
+		} else if (dev->norm & V4L2_STD_625_50) {
+			/* PAL */
+			em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x07);
+		}
 	}
 
 	return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl);
@@ -760,6 +767,13 @@ int em28xx_resolution_set(struct em28xx
 	width = norm_maxw(dev);
 	height = norm_maxh(dev);
 
+	/* Properly setup VBI */
+	dev->vbi_width = 720;
+	if (dev->norm & V4L2_STD_525_60)
+		dev->vbi_height = 12;
+	else
+		dev->vbi_height = 18;
+
 	if (!dev->progressive)
 		height >>= norm_maxh(dev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-dvb.c linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx-dvb.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-dvb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx-dvb.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "em28xx.h"
@@ -502,7 +503,9 @@ static int dvb_init(struct em28xx *dev)
 		}
 		break;
 	case EM2880_BOARD_TERRATEC_HYBRID_XS:
+	case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
 	case EM2881_BOARD_PINNACLE_HYBRID_PRO:
+	case EM2882_BOARD_DIKOM_DK300:
 		dvb->frontend = dvb_attach(zl10353_attach,
 					   &em28xx_zl10353_xc3028_no_i2c_gate,
 					   &dev->i2c_adap);
@@ -606,6 +609,7 @@ static int dvb_fini(struct em28xx *dev)
 
 	if (dev->dvb) {
 		unregister_dvb(dev->dvb);
+		kfree(dev->dvb);
 		dev->dvb = NULL;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx.h linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -111,6 +111,7 @@
 #define EM2861_BOARD_GADMEI_UTV330PLUS           72
 #define EM2870_BOARD_REDDO_DVB_C_USB_BOX          73
 #define EM2800_BOARD_VC211A			  74
+#define EM2882_BOARD_DIKOM_DK300		  75
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
@@ -552,7 +553,8 @@ struct em28xx {
 	int capture_type;
 	int vbi_read;
 	unsigned char cur_field;
-
+	unsigned int vbi_width;
+	unsigned int vbi_height; /* lines per field */
 
 	struct work_struct         request_module_wk;
 
@@ -693,6 +695,8 @@ int em28xx_get_key_terratec(struct IR_i2
 int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
 int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
 				     u32 *ir_raw);
+int em28xx_get_key_winfast_usbii_deluxe(struct IR_i2c *ir, u32 *ir_key,
+				     u32 *ir_raw);
 void em28xx_register_snapshot_button(struct em28xx *dev);
 void em28xx_deregister_snapshot_button(struct em28xx *dev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-input.c linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx-input.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-input.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx-input.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include "em28xx.h"
 
@@ -75,6 +76,10 @@ struct em28xx_IR {
 	unsigned int repeat_interval;
 
 	int  (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
+
+	/* IR device properties */
+
+	struct ir_dev_props props;
 };
 
 /**********************************************************
@@ -180,6 +185,36 @@ int em28xx_get_key_pinnacle_usb_grey(str
 	return 1;
 }
 
+int em28xx_get_key_winfast_usbii_deluxe(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+	unsigned char subaddr, keydetect, key;
+
+	struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0, .buf = &subaddr, .len = 1},
+
+				{ .addr = ir->c->addr, .flags = I2C_M_RD, .buf = &keydetect, .len = 1} };
+
+	subaddr = 0x10;
+	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
+		i2cdprintk("read error\n");
+		return -EIO;
+	}
+	if (keydetect == 0x00)
+		return 0;
+
+	subaddr = 0x00;
+	msg[1].buf = &key;
+	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
+		i2cdprintk("read error\n");
+	return -EIO;
+	}
+	if (key == 0x00)
+		return 0;
+
+	*ir_key = key;
+	*ir_raw = key;
+	return 1;
+}
+
 /**********************************************************
  Poll based get keycode functions
  **********************************************************/
@@ -336,35 +371,28 @@ static void em28xx_ir_stop(struct em28xx
 	cancel_delayed_work_sync(&ir->work);
 }
 
-int em28xx_ir_init(struct em28xx *dev)
+int em28xx_ir_change_protocol(void *priv, u64 ir_type)
 {
-	struct em28xx_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;
-	ir_config = EM2874_IR_RC5;
+	int rc = 0;
+	struct em28xx_IR *ir = priv;
+	struct em28xx *dev = ir->dev;
+	u8 ir_config = EM2874_IR_RC5;
 
 	/* Adjust xclk based o IR table for RC5/NEC tables */
-	if (dev->board.ir_codes->ir_type == IR_TYPE_RC5) {
+
+	dev->board.ir_codes->ir_type = IR_TYPE_OTHER;
+	if (ir_type == IR_TYPE_RC5) {
 		dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
 		ir->full_code = 1;
-	} else  if (dev->board.ir_codes->ir_type == IR_TYPE_NEC) {
+	} else if (ir_type == IR_TYPE_NEC) {
 		dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
 		ir_config = EM2874_IR_NEC;
 		ir->full_code = 1;
-	}
+	} else
+		rc = -EINVAL;
+
+	dev->board.ir_codes->ir_type = ir_type;
+
 	em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
 			      EM28XX_XCLK_IR_RC5_MODE);
 
@@ -380,9 +408,42 @@ int em28xx_ir_init(struct em28xx *dev)
 		break;
 	default:
 		printk("Unrecognized em28xx chip id: IR not supported\n");
-		goto err_out_free;
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+int em28xx_ir_init(struct em28xx *dev)
+{
+	struct em28xx_IR *ir;
+	struct input_dev *input_dev;
+	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;
+
+	/* record handles to ourself */
+	ir->dev = dev;
+	dev->ir = ir;
+
+	ir->input = input_dev;
+
+	/*
+	 * em2874 supports more protocols. For now, let's just announce
+	 * the two protocols that were already tested
+	 */
+	ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
+	ir->props.priv = ir;
+	ir->props.change_protocol = em28xx_ir_change_protocol;
+
 	/* This is how often we ask the chip for IR information */
 	ir->polling = 100; /* ms */
 
@@ -393,6 +454,8 @@ int em28xx_ir_init(struct em28xx *dev)
 	usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
 	strlcat(ir->phys, "/input0", sizeof(ir->phys));
 
+	/* Set IR protocol */
+	em28xx_ir_change_protocol(ir, dev->board.ir_codes->ir_type);
 	err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
 	if (err < 0)
 		goto err_out_free;
@@ -405,14 +468,13 @@ int em28xx_ir_init(struct em28xx *dev)
 	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;
+
 
 	em28xx_ir_start(ir);
 
 	/* all done */
-	err = ir_input_register(ir->input, dev->board.ir_codes);
+	err = ir_input_register(ir->input, dev->board.ir_codes,
+				&ir->props);
 	if (err)
 		goto err_out_stop;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-reg.h linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx-reg.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-reg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx-reg.h	2010-05-16 17:17:36.000000000 -0400
@@ -173,8 +173,8 @@
 /* em2874 IR config register (0x50) */
 #define EM2874_IR_NEC           0x00
 #define EM2874_IR_RC5           0x04
-#define EM2874_IR_RC5_MODE_0    0x08
-#define EM2874_IR_RC5_MODE_6A   0x0b
+#define EM2874_IR_RC6_MODE_0    0x08
+#define EM2874_IR_RC6_MODE_6A   0x0b
 
 /* em2874 Transport Stream Enable Register (0x5f) */
 #define EM2874_TS1_CAPTURE_ENABLE (1 << 0)
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-vbi.c linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx-vbi.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-vbi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx-vbi.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 
 #include "em28xx.h"
 
@@ -71,7 +70,11 @@ free_buffer(struct videobuf_queue *vq, s
 static int
 vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
 {
-	*size = 720 * 12 * 2;
+	struct em28xx_fh     *fh  = q->priv_data;
+	struct em28xx        *dev = fh->dev;
+
+	*size = dev->vbi_width * dev->vbi_height * 2;
+
 	if (0 == *count)
 		*count = vbibufs;
 	if (*count < 2)
@@ -85,19 +88,18 @@ static int
 vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
 	    enum v4l2_field field)
 {
+	struct em28xx_fh     *fh  = q->priv_data;
+	struct em28xx        *dev = fh->dev;
 	struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
 	int                  rc = 0;
-	unsigned int size;
-
-	size = 720 * 12 * 2;
 
-	buf->vb.size = size;
+	buf->vb.size = dev->vbi_width * dev->vbi_height * 2;
 
 	if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
 		return -EINVAL;
 
-	buf->vb.width  = 720;
-	buf->vb.height = 12;
+	buf->vb.width  = dev->vbi_width;
+	buf->vb.height = dev->vbi_height;
 	buf->vb.field  = field;
 
 	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-video.c linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx-video.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-video.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/em28xx/em28xx-video.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/version.h>
 #include <linux/mm.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include "em28xx.h"
 #include <media/v4l2-common.h>
@@ -282,7 +283,7 @@ static void em28xx_copy_vbi(struct em28x
 {
 	void *startwrite, *startread;
 	int  offset;
-	int bytesperline = 720;
+	int bytesperline = dev->vbi_width;
 
 	if (dev == NULL) {
 		em28xx_isocdbg("dev is null\n");
@@ -323,8 +324,8 @@ static void em28xx_copy_vbi(struct em28x
 
 	/* Make sure the bottom field populates the second half of the frame */
 	if (buf->top_field == 0) {
-		startwrite += bytesperline * 0x0c;
-		offset += bytesperline * 0x0c;
+		startwrite += bytesperline * dev->vbi_height;
+		offset += bytesperline * dev->vbi_height;
 	}
 
 	memcpy(startwrite, startread, len);
@@ -578,8 +579,7 @@ static inline int em28xx_isoc_copy_vbi(s
 			dev->cur_field = p[2];
 		}
 
-		/* FIXME: get rid of hard-coded value */
-		vbi_size = 720 * 0x0c;
+		vbi_size = dev->vbi_width * dev->vbi_height;
 
 		if (dev->capture_type == 0) {
 			if (dev->vbi_read >= vbi_size) {
@@ -1850,18 +1850,27 @@ static int vidioc_try_set_sliced_vbi_cap
 static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
 				struct v4l2_format *format)
 {
-	format->fmt.vbi.samples_per_line = 720;
+	struct em28xx_fh      *fh  = priv;
+	struct em28xx         *dev = fh->dev;
+
+	format->fmt.vbi.samples_per_line = dev->vbi_width;
 	format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
 	format->fmt.vbi.offset = 0;
 	format->fmt.vbi.flags = 0;
+	format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
+	format->fmt.vbi.count[0] = dev->vbi_height;
+	format->fmt.vbi.count[1] = dev->vbi_height;
 
 	/* Varies by video standard (NTSC, PAL, etc.) */
-	/* FIXME: hard-coded for NTSC support */
-	format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */
-	format->fmt.vbi.count[0] = 12;
-	format->fmt.vbi.count[1] = 12;
-	format->fmt.vbi.start[0] = 10;
-	format->fmt.vbi.start[1] = 273;
+	if (dev->norm & V4L2_STD_525_60) {
+		/* NTSC */
+		format->fmt.vbi.start[0] = 10;
+		format->fmt.vbi.start[1] = 273;
+	} else if (dev->norm & V4L2_STD_625_50) {
+		/* PAL */
+		format->fmt.vbi.start[0] = 6;
+		format->fmt.vbi.start[1] = 318;
+	}
 
 	return 0;
 }
@@ -1869,18 +1878,27 @@ static int vidioc_g_fmt_vbi_cap(struct f
 static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv,
 				struct v4l2_format *format)
 {
-	format->fmt.vbi.samples_per_line = 720;
+	struct em28xx_fh      *fh  = priv;
+	struct em28xx         *dev = fh->dev;
+
+	format->fmt.vbi.samples_per_line = dev->vbi_width;
 	format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
 	format->fmt.vbi.offset = 0;
 	format->fmt.vbi.flags = 0;
+	format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
+	format->fmt.vbi.count[0] = dev->vbi_height;
+	format->fmt.vbi.count[1] = dev->vbi_height;
 
 	/* Varies by video standard (NTSC, PAL, etc.) */
-	/* FIXME: hard-coded for NTSC support */
-	format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */
-	format->fmt.vbi.count[0] = 12;
-	format->fmt.vbi.count[1] = 12;
-	format->fmt.vbi.start[0] = 10;
-	format->fmt.vbi.start[1] = 273;
+	if (dev->norm & V4L2_STD_525_60) {
+		/* NTSC */
+		format->fmt.vbi.start[0] = 10;
+		format->fmt.vbi.start[1] = 273;
+	} else if (dev->norm & V4L2_STD_625_50) {
+		/* PAL */
+		format->fmt.vbi.start[0] = 6;
+		format->fmt.vbi.start[1] = 318;
+	}
 
 	return 0;
 }
@@ -1922,7 +1940,8 @@ static int vidioc_querybuf(struct file *
 		   At a minimum, it causes a crash in zvbi since it does
 		   a memcpy based on the source buffer length */
 		int result = videobuf_querybuf(&fh->vb_vbiq, b);
-		b->length = 17280;
+		b->length = dev->vbi_width * dev->vbi_height * 2;
+
 		return result;
 	}
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/et61x251/Kconfig linux-libre-2.6.34-gnu1/drivers/media/video/et61x251/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/media/video/et61x251/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/et61x251/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,11 @@
 config USB_ET61X251
-	tristate "USB ET61X[12]51 PC Camera Controller support"
+	tristate "USB ET61X[12]51 PC Camera Controller support (DEPRECATED)"
 	depends on VIDEO_V4L2
+	default n
 	---help---
+	  This driver is DEPRECATED please use the gspca zc3xx module
+	  instead.
+
 	  Say Y here if you want support for cameras based on Etoms ET61X151
 	  or ET61X251 PC Camera Controllers.
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/benq.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/benq.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/benq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/benq.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,322 @@
+/*
+ * Benq DC E300 subdriver
+ *
+ * Copyright (C) 2009 Jean-Francois Moine (http://moinejf.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, 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 "benq"
+
+#include "gspca.h"
+
+MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
+MODULE_DESCRIPTION("Benq DC E300 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+	struct gspca_dev gspca_dev;	/* !! must be the first item */
+};
+
+/* V4L2 controls supported by the driver */
+static const struct ctrl sd_ctrls[] = {
+};
+
+static const struct v4l2_pix_format vga_mode[] = {
+	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240 * 3 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+};
+
+static void sd_isoc_irq(struct urb *urb);
+
+/* -- write a register -- */
+static void reg_w(struct gspca_dev *gspca_dev,
+			u16 value, u16 index)
+{
+	struct usb_device *dev = gspca_dev->dev;
+	int ret;
+
+	if (gspca_dev->usb_err < 0)
+		return;
+	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+			0x02,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			value,
+			index,
+			NULL,
+			0,
+			500);
+	if (ret < 0) {
+		PDEBUG(D_ERR, "reg_w err %d", ret);
+		gspca_dev->usb_err = ret;
+	}
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+			const struct usb_device_id *id)
+{
+	gspca_dev->cam.cam_mode = vga_mode;
+	gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
+	gspca_dev->cam.no_urb_create = 1;
+	gspca_dev->cam.reverse_alts = 1;
+	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_isoc_init(struct gspca_dev *gspca_dev)
+{
+	int ret;
+
+	ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface,
+		gspca_dev->nbalt - 1);
+	if (ret < 0) {
+		err("usb_set_interface failed");
+		return ret;
+	}
+/*	reg_w(gspca_dev, 0x0003, 0x0002); */
+	return 0;
+}
+
+/* -- start the camera -- */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	struct urb *urb;
+	int i, n;
+
+	/* create 4 URBs - 2 on endpoint 0x83 and 2 on 0x082 */
+#if MAX_NURBS < 4
+#error "Not enough URBs in the gspca table"
+#endif
+#define SD_PKT_SZ 64
+#define SD_NPKT 32
+	for (n = 0; n < 4; n++) {
+		urb = usb_alloc_urb(SD_NPKT, GFP_KERNEL);
+		if (!urb) {
+			err("usb_alloc_urb failed");
+			return -ENOMEM;
+		}
+		gspca_dev->urb[n] = urb;
+		urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev,
+						SD_PKT_SZ * SD_NPKT,
+						GFP_KERNEL,
+						&urb->transfer_dma);
+
+		if (urb->transfer_buffer == NULL) {
+			err("usb_buffer_alloc failed");
+			return -ENOMEM;
+		}
+		urb->dev = gspca_dev->dev;
+		urb->context = gspca_dev;
+		urb->transfer_buffer_length = SD_PKT_SZ * SD_NPKT;
+		urb->pipe = usb_rcvisocpipe(gspca_dev->dev,
+					n & 1 ? 0x82 : 0x83);
+		urb->transfer_flags = URB_ISO_ASAP
+					| URB_NO_TRANSFER_DMA_MAP;
+		urb->interval = 1;
+		urb->complete = sd_isoc_irq;
+		urb->number_of_packets = SD_NPKT;
+		for (i = 0; i < SD_NPKT; i++) {
+			urb->iso_frame_desc[i].length = SD_PKT_SZ;
+			urb->iso_frame_desc[i].offset = SD_PKT_SZ * i;
+		}
+	}
+
+	return gspca_dev->usb_err;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+	reg_w(gspca_dev, 0x003c, 0x0003);
+	reg_w(gspca_dev, 0x003c, 0x0004);
+	reg_w(gspca_dev, 0x003c, 0x0005);
+	reg_w(gspca_dev, 0x003c, 0x0006);
+	reg_w(gspca_dev, 0x003c, 0x0007);
+	usb_set_interface(gspca_dev->dev, gspca_dev->iface, gspca_dev->nbalt - 1);
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,		/* isoc packet */
+			int len)		/* iso packet length */
+{
+	/* unused */
+}
+
+/* reception of an URB */
+static void sd_isoc_irq(struct urb *urb)
+{
+	struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
+	struct urb *urb0;
+	u8 *data;
+	int i, st;
+
+	PDEBUG(D_PACK, "sd isoc irq");
+	if (!gspca_dev->streaming)
+		return;
+	if (urb->status != 0) {
+		if (urb->status == -ESHUTDOWN)
+			return;		/* disconnection */
+#ifdef CONFIG_PM
+		if (gspca_dev->frozen)
+			return;
+#endif
+		PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
+		return;
+	}
+
+	/* if this is a control URN (ep 0x83), wait */
+	if (urb == gspca_dev->urb[0] || urb == gspca_dev->urb[2])
+		return;
+
+	/* scan both received URBs */
+	if (urb == gspca_dev->urb[1])
+		urb0 = gspca_dev->urb[0];
+	else
+		urb0 = gspca_dev->urb[2];
+	for (i = 0; i < urb->number_of_packets; i++) {
+
+		/* check the packet status and length */
+		if (urb0->iso_frame_desc[i].actual_length != SD_PKT_SZ
+		    || urb->iso_frame_desc[i].actual_length != SD_PKT_SZ) {
+			PDEBUG(D_ERR, "ISOC bad lengths %d / %d",
+				urb0->iso_frame_desc[i].actual_length,
+				urb->iso_frame_desc[i].actual_length);
+			gspca_dev->last_packet_type = DISCARD_PACKET;
+			continue;
+		}
+		st = urb0->iso_frame_desc[i].status;
+		if (st == 0)
+			st = urb->iso_frame_desc[i].status;
+		if (st) {
+			PDEBUG(D_ERR,
+				"ISOC data error: [%d] status=%d",
+				i, st);
+			gspca_dev->last_packet_type = DISCARD_PACKET;
+			continue;
+		}
+
+		/*
+		 * The images are received in URBs of different endpoints
+		 * (0x83 and 0x82).
+		 * Image pieces in URBs of ep 0x83 are continuated in URBs of
+		 * ep 0x82 of the same index.
+		 * The packets in the URBs of endpoint 0x83 start with:
+		 *	- 80 ba/bb 00 00 = start of image followed by 'ff d8'
+		 *	- 04 ba/bb oo oo = image piece
+		 *		where 'oo oo' is the image offset
+						(not cheked)
+		 *	- (other -> bad frame)
+		 * The images are JPEG encoded with full header and
+		 * normal ff escape.
+		 * The end of image ('ff d9') may occur in any URB.
+		 * (not cheked)
+		 */
+		data = (u8 *) urb0->transfer_buffer
+					+ urb0->iso_frame_desc[i].offset;
+		if (data[0] == 0x80 && (data[1] & 0xfe) == 0xba) {
+
+			/* new image */
+			gspca_frame_add(gspca_dev, LAST_PACKET,
+					NULL, 0);
+			gspca_frame_add(gspca_dev, FIRST_PACKET,
+					data + 4, SD_PKT_SZ - 4);
+		} else if (data[0] == 0x04 && (data[1] & 0xfe) == 0xba) {
+			gspca_frame_add(gspca_dev, INTER_PACKET,
+					data + 4, SD_PKT_SZ - 4);
+		} else {
+			gspca_dev->last_packet_type = DISCARD_PACKET;
+			continue;
+		}
+		data = (u8 *) urb->transfer_buffer
+					+ urb->iso_frame_desc[i].offset;
+			gspca_frame_add(gspca_dev, INTER_PACKET,
+					data, SD_PKT_SZ);
+	}
+
+	/* resubmit the URBs */
+	st = usb_submit_urb(urb0, GFP_ATOMIC);
+	if (st < 0)
+		PDEBUG(D_ERR|D_PACK, "usb_submit_urb(0) ret %d", st);
+	st = usb_submit_urb(urb, GFP_ATOMIC);
+	if (st < 0)
+		PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st);
+}
+
+/* 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,
+	.isoc_init = sd_isoc_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(0x04a5, 0x3035)},
+	{}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+			const struct usb_device_id *id)
+{
+	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+				THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+	.name = MODULE_NAME,
+	.id_table = device_table,
+	.probe = sd_probe,
+	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+	int ret;
+
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
+	info("registered");
+	return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+	usb_deregister(&sd_driver);
+	info("deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/coarse_expo_autogain.h linux-libre-2.6.34-gnu1/drivers/media/video/gspca/coarse_expo_autogain.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/coarse_expo_autogain.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/coarse_expo_autogain.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,116 @@
+/*
+ * Auto gain algorithm for camera's with a coarse exposure control
+ *
+ * Copyright (C) 2010 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ */
+
+/* Autogain + exposure algorithm for cameras with a coarse exposure control
+   (usually this means we can only control the clockdiv to change exposure)
+   As changing the clockdiv so that the fps drops from 30 to 15 fps for
+   example, will lead to a huge exposure change (it effectively doubles),
+   this algorithm normally tries to only adjust the gain (between 40 and
+   80 %) and if that does not help, only then changes exposure. This leads
+   to a much more stable image then using the knee algorithm which at
+   certain points of the knee graph will only try to adjust exposure,
+   which leads to oscilating as one exposure step is huge.
+
+   Note this assumes that the sd struct for the cam in question has
+   exp_too_high_cnt and exp_too_high_cnt int members for use by this function.
+
+   Returns 0 if no changes were made, 1 if the gain and or exposure settings
+   where changed. */
+static int gspca_coarse_grained_expo_autogain(struct gspca_dev *gspca_dev,
+	int avg_lum, int desired_avg_lum, int deadzone)
+{
+	int i, steps, gain, orig_gain, exposure, orig_exposure;
+	int gain_low, gain_high;
+	const struct ctrl *gain_ctrl = NULL;
+	const struct ctrl *exposure_ctrl = NULL;
+	struct sd *sd = (struct sd *) gspca_dev;
+	int retval = 0;
+
+	for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
+		if (gspca_dev->ctrl_dis & (1 << i))
+			continue;
+		if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN)
+			gain_ctrl = &gspca_dev->sd_desc->ctrls[i];
+		if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE)
+			exposure_ctrl = &gspca_dev->sd_desc->ctrls[i];
+	}
+	if (!gain_ctrl || !exposure_ctrl) {
+		PDEBUG(D_ERR, "Error: gspca_coarse_grained_expo_autogain "
+			"called on cam without gain or exposure");
+		return 0;
+	}
+
+	if (gain_ctrl->get(gspca_dev, &gain) ||
+	    exposure_ctrl->get(gspca_dev, &exposure))
+		return 0;
+
+	orig_gain = gain;
+	orig_exposure = exposure;
+	gain_low =
+		(gain_ctrl->qctrl.maximum - gain_ctrl->qctrl.minimum) / 5 * 2;
+	gain_low += gain_ctrl->qctrl.minimum;
+	gain_high =
+		(gain_ctrl->qctrl.maximum - gain_ctrl->qctrl.minimum) / 5 * 4;
+	gain_high += gain_ctrl->qctrl.minimum;
+
+	/* If we are of a multiple of deadzone, do multiple steps to reach the
+	   desired lumination fast (with the risc of a slight overshoot) */
+	steps = (desired_avg_lum - avg_lum) / deadzone;
+
+	PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
+		avg_lum, desired_avg_lum, steps);
+
+	if ((gain + steps) > gain_high &&
+	    sd->exposure < exposure_ctrl->qctrl.maximum) {
+		gain = gain_high;
+		sd->exp_too_low_cnt++;
+	} else if ((gain + steps) < gain_low &&
+		   sd->exposure > exposure_ctrl->qctrl.minimum) {
+		gain = gain_low;
+		sd->exp_too_high_cnt++;
+	} else {
+		gain += steps;
+		if (gain > gain_ctrl->qctrl.maximum)
+			gain = gain_ctrl->qctrl.maximum;
+		else if (gain < gain_ctrl->qctrl.minimum)
+			gain = gain_ctrl->qctrl.minimum;
+		sd->exp_too_high_cnt = 0;
+		sd->exp_too_low_cnt = 0;
+	}
+
+	if (sd->exp_too_high_cnt > 3) {
+		exposure--;
+		sd->exp_too_high_cnt = 0;
+	} else if (sd->exp_too_low_cnt > 3) {
+		exposure++;
+		sd->exp_too_low_cnt = 0;
+	}
+
+	if (gain != orig_gain) {
+		gain_ctrl->set(gspca_dev, gain);
+		retval = 1;
+	}
+	if (exposure != orig_exposure) {
+		exposure_ctrl->set(gspca_dev, exposure);
+		retval = 1;
+	}
+
+	return retval;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/conex.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/conex.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/conex.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/conex.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,7 +52,7 @@ static int sd_getcontrast(struct gspca_d
 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 	{
 	    {
 		.id	 = V4L2_CID_BRIGHTNESS,
@@ -1032,7 +1032,7 @@ static int sd_get_jcomp(struct gspca_dev
 }
 
 /* sub-driver description */
-static struct sd_desc sd_desc = {
+static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/cpia1.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/cpia1.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/cpia1.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/cpia1.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,2022 @@
+/*
+ * cpia CPiA (1) gspca driver
+ *
+ * Copyright (C) 2010 Hans de Goede <hdgoede@redhat.com>
+ *
+ * This module is adapted from the in kernel v4l1 cpia driver which is :
+ *
+ * (C) Copyright 1999-2000 Peter Pregler
+ * (C) Copyright 1999-2000 Scott J. Bertin
+ * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
+ * (C) Copyright 2000 STMicroelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 "cpia1"
+
+#include "gspca.h"
+
+MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
+MODULE_DESCRIPTION("Vision CPiA");
+MODULE_LICENSE("GPL");
+
+/* constant value's */
+#define MAGIC_0		0x19
+#define MAGIC_1		0x68
+#define DATA_IN		0xC0
+#define DATA_OUT	0x40
+#define VIDEOSIZE_QCIF	0	/* 176x144 */
+#define VIDEOSIZE_CIF	1	/* 352x288 */
+#define SUBSAMPLE_420	0
+#define SUBSAMPLE_422	1
+#define YUVORDER_YUYV	0
+#define YUVORDER_UYVY	1
+#define NOT_COMPRESSED	0
+#define COMPRESSED	1
+#define NO_DECIMATION	0
+#define DECIMATION_ENAB	1
+#define EOI		0xff	/* End Of Image */
+#define EOL		0xfd	/* End Of Line */
+#define FRAME_HEADER_SIZE	64
+
+/* Image grab modes */
+#define CPIA_GRAB_SINGLE	0
+#define CPIA_GRAB_CONTINEOUS	1
+
+/* Compression parameters */
+#define CPIA_COMPRESSION_NONE	0
+#define CPIA_COMPRESSION_AUTO	1
+#define CPIA_COMPRESSION_MANUAL	2
+#define CPIA_COMPRESSION_TARGET_QUALITY         0
+#define CPIA_COMPRESSION_TARGET_FRAMERATE       1
+
+/* Return offsets for GetCameraState */
+#define SYSTEMSTATE	0
+#define GRABSTATE	1
+#define STREAMSTATE	2
+#define FATALERROR	3
+#define CMDERROR	4
+#define DEBUGFLAGS	5
+#define VPSTATUS	6
+#define ERRORCODE	7
+
+/* SystemState */
+#define UNINITIALISED_STATE	0
+#define PASS_THROUGH_STATE	1
+#define LO_POWER_STATE		2
+#define HI_POWER_STATE		3
+#define WARM_BOOT_STATE		4
+
+/* GrabState */
+#define GRAB_IDLE		0
+#define GRAB_ACTIVE		1
+#define GRAB_DONE		2
+
+/* StreamState */
+#define STREAM_NOT_READY	0
+#define STREAM_READY		1
+#define STREAM_OPEN		2
+#define STREAM_PAUSED		3
+#define STREAM_FINISHED		4
+
+/* Fatal Error, CmdError, and DebugFlags */
+#define CPIA_FLAG	  1
+#define SYSTEM_FLAG	  2
+#define INT_CTRL_FLAG	  4
+#define PROCESS_FLAG	  8
+#define COM_FLAG	 16
+#define VP_CTRL_FLAG	 32
+#define CAPTURE_FLAG	 64
+#define DEBUG_FLAG	128
+
+/* VPStatus */
+#define VP_STATE_OK			0x00
+
+#define VP_STATE_FAILED_VIDEOINIT	0x01
+#define VP_STATE_FAILED_AECACBINIT	0x02
+#define VP_STATE_AEC_MAX		0x04
+#define VP_STATE_ACB_BMAX		0x08
+
+#define VP_STATE_ACB_RMIN		0x10
+#define VP_STATE_ACB_GMIN		0x20
+#define VP_STATE_ACB_RMAX		0x40
+#define VP_STATE_ACB_GMAX		0x80
+
+/* default (minimum) compensation values */
+#define COMP_RED        220
+#define COMP_GREEN1     214
+#define COMP_GREEN2     COMP_GREEN1
+#define COMP_BLUE       230
+
+/* exposure status */
+#define EXPOSURE_VERY_LIGHT 0
+#define EXPOSURE_LIGHT      1
+#define EXPOSURE_NORMAL     2
+#define EXPOSURE_DARK       3
+#define EXPOSURE_VERY_DARK  4
+
+#define CPIA_MODULE_CPIA			(0 << 5)
+#define CPIA_MODULE_SYSTEM			(1 << 5)
+#define CPIA_MODULE_VP_CTRL			(5 << 5)
+#define CPIA_MODULE_CAPTURE			(6 << 5)
+#define CPIA_MODULE_DEBUG			(7 << 5)
+
+#define INPUT (DATA_IN << 8)
+#define OUTPUT (DATA_OUT << 8)
+
+#define CPIA_COMMAND_GetCPIAVersion	(INPUT | CPIA_MODULE_CPIA | 1)
+#define CPIA_COMMAND_GetPnPID		(INPUT | CPIA_MODULE_CPIA | 2)
+#define CPIA_COMMAND_GetCameraStatus	(INPUT | CPIA_MODULE_CPIA | 3)
+#define CPIA_COMMAND_GotoHiPower	(OUTPUT | CPIA_MODULE_CPIA | 4)
+#define CPIA_COMMAND_GotoLoPower	(OUTPUT | CPIA_MODULE_CPIA | 5)
+#define CPIA_COMMAND_GotoSuspend	(OUTPUT | CPIA_MODULE_CPIA | 7)
+#define CPIA_COMMAND_GotoPassThrough	(OUTPUT | CPIA_MODULE_CPIA | 8)
+#define CPIA_COMMAND_ModifyCameraStatus	(OUTPUT | CPIA_MODULE_CPIA | 10)
+
+#define CPIA_COMMAND_ReadVCRegs		(INPUT | CPIA_MODULE_SYSTEM | 1)
+#define CPIA_COMMAND_WriteVCReg		(OUTPUT | CPIA_MODULE_SYSTEM | 2)
+#define CPIA_COMMAND_ReadMCPorts	(INPUT | CPIA_MODULE_SYSTEM | 3)
+#define CPIA_COMMAND_WriteMCPort	(OUTPUT | CPIA_MODULE_SYSTEM | 4)
+#define CPIA_COMMAND_SetBaudRate	(OUTPUT | CPIA_MODULE_SYSTEM | 5)
+#define CPIA_COMMAND_SetECPTiming	(OUTPUT | CPIA_MODULE_SYSTEM | 6)
+#define CPIA_COMMAND_ReadIDATA		(INPUT | CPIA_MODULE_SYSTEM | 7)
+#define CPIA_COMMAND_WriteIDATA		(OUTPUT | CPIA_MODULE_SYSTEM | 8)
+#define CPIA_COMMAND_GenericCall	(OUTPUT | CPIA_MODULE_SYSTEM | 9)
+#define CPIA_COMMAND_I2CStart		(OUTPUT | CPIA_MODULE_SYSTEM | 10)
+#define CPIA_COMMAND_I2CStop		(OUTPUT | CPIA_MODULE_SYSTEM | 11)
+#define CPIA_COMMAND_I2CWrite		(OUTPUT | CPIA_MODULE_SYSTEM | 12)
+#define CPIA_COMMAND_I2CRead		(INPUT | CPIA_MODULE_SYSTEM | 13)
+
+#define CPIA_COMMAND_GetVPVersion	(INPUT | CPIA_MODULE_VP_CTRL | 1)
+#define CPIA_COMMAND_ResetFrameCounter	(INPUT | CPIA_MODULE_VP_CTRL | 2)
+#define CPIA_COMMAND_SetColourParams	(OUTPUT | CPIA_MODULE_VP_CTRL | 3)
+#define CPIA_COMMAND_SetExposure	(OUTPUT | CPIA_MODULE_VP_CTRL | 4)
+#define CPIA_COMMAND_SetColourBalance	(OUTPUT | CPIA_MODULE_VP_CTRL | 6)
+#define CPIA_COMMAND_SetSensorFPS	(OUTPUT | CPIA_MODULE_VP_CTRL | 7)
+#define CPIA_COMMAND_SetVPDefaults	(OUTPUT | CPIA_MODULE_VP_CTRL | 8)
+#define CPIA_COMMAND_SetApcor		(OUTPUT | CPIA_MODULE_VP_CTRL | 9)
+#define CPIA_COMMAND_SetFlickerCtrl	(OUTPUT | CPIA_MODULE_VP_CTRL | 10)
+#define CPIA_COMMAND_SetVLOffset	(OUTPUT | CPIA_MODULE_VP_CTRL | 11)
+#define CPIA_COMMAND_GetColourParams	(INPUT | CPIA_MODULE_VP_CTRL | 16)
+#define CPIA_COMMAND_GetColourBalance	(INPUT | CPIA_MODULE_VP_CTRL | 17)
+#define CPIA_COMMAND_GetExposure	(INPUT | CPIA_MODULE_VP_CTRL | 18)
+#define CPIA_COMMAND_SetSensorMatrix	(OUTPUT | CPIA_MODULE_VP_CTRL | 19)
+#define CPIA_COMMAND_ColourBars		(OUTPUT | CPIA_MODULE_VP_CTRL | 25)
+#define CPIA_COMMAND_ReadVPRegs		(INPUT | CPIA_MODULE_VP_CTRL | 30)
+#define CPIA_COMMAND_WriteVPReg		(OUTPUT | CPIA_MODULE_VP_CTRL | 31)
+
+#define CPIA_COMMAND_GrabFrame		(OUTPUT | CPIA_MODULE_CAPTURE | 1)
+#define CPIA_COMMAND_UploadFrame	(OUTPUT | CPIA_MODULE_CAPTURE | 2)
+#define CPIA_COMMAND_SetGrabMode	(OUTPUT | CPIA_MODULE_CAPTURE | 3)
+#define CPIA_COMMAND_InitStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 4)
+#define CPIA_COMMAND_FiniStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 5)
+#define CPIA_COMMAND_StartStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 6)
+#define CPIA_COMMAND_EndStreamCap	(OUTPUT | CPIA_MODULE_CAPTURE | 7)
+#define CPIA_COMMAND_SetFormat		(OUTPUT | CPIA_MODULE_CAPTURE | 8)
+#define CPIA_COMMAND_SetROI		(OUTPUT | CPIA_MODULE_CAPTURE | 9)
+#define CPIA_COMMAND_SetCompression	(OUTPUT | CPIA_MODULE_CAPTURE | 10)
+#define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
+#define CPIA_COMMAND_SetYUVThresh	(OUTPUT | CPIA_MODULE_CAPTURE | 12)
+#define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
+#define CPIA_COMMAND_DiscardFrame	(OUTPUT | CPIA_MODULE_CAPTURE | 14)
+#define CPIA_COMMAND_GrabReset		(OUTPUT | CPIA_MODULE_CAPTURE | 15)
+
+#define CPIA_COMMAND_OutputRS232	(OUTPUT | CPIA_MODULE_DEBUG | 1)
+#define CPIA_COMMAND_AbortProcess	(OUTPUT | CPIA_MODULE_DEBUG | 4)
+#define CPIA_COMMAND_SetDramPage	(OUTPUT | CPIA_MODULE_DEBUG | 5)
+#define CPIA_COMMAND_StartDramUpload	(OUTPUT | CPIA_MODULE_DEBUG | 6)
+#define CPIA_COMMAND_StartDummyDtream	(OUTPUT | CPIA_MODULE_DEBUG | 8)
+#define CPIA_COMMAND_AbortStream	(OUTPUT | CPIA_MODULE_DEBUG | 9)
+#define CPIA_COMMAND_DownloadDRAM	(OUTPUT | CPIA_MODULE_DEBUG | 10)
+#define CPIA_COMMAND_Null		(OUTPUT | CPIA_MODULE_DEBUG | 11)
+
+#define ROUND_UP_EXP_FOR_FLICKER 15
+
+/* Constants for automatic frame rate adjustment */
+#define MAX_EXP       302
+#define MAX_EXP_102   255
+#define LOW_EXP       140
+#define VERY_LOW_EXP   70
+#define TC             94
+#define	EXP_ACC_DARK   50
+#define	EXP_ACC_LIGHT  90
+#define HIGH_COMP_102 160
+#define MAX_COMP      239
+#define DARK_TIME       3
+#define LIGHT_TIME      3
+
+#define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
+				sd->params.version.firmwareRevision == (y))
+
+/* Developer's Guide Table 5 p 3-34
+ * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
+static u8 flicker_jumps[2][2][4] =
+{ { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
+  { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
+};
+
+struct cam_params {
+	struct {
+		u8 firmwareVersion;
+		u8 firmwareRevision;
+		u8 vcVersion;
+		u8 vcRevision;
+	} version;
+	struct {
+		u16 vendor;
+		u16 product;
+		u16 deviceRevision;
+	} pnpID;
+	struct {
+		u8 vpVersion;
+		u8 vpRevision;
+		u16 cameraHeadID;
+	} vpVersion;
+	struct {
+		u8 systemState;
+		u8 grabState;
+		u8 streamState;
+		u8 fatalError;
+		u8 cmdError;
+		u8 debugFlags;
+		u8 vpStatus;
+		u8 errorCode;
+	} status;
+	struct {
+		u8 brightness;
+		u8 contrast;
+		u8 saturation;
+	} colourParams;
+	struct {
+		u8 gainMode;
+		u8 expMode;
+		u8 compMode;
+		u8 centreWeight;
+		u8 gain;
+		u8 fineExp;
+		u8 coarseExpLo;
+		u8 coarseExpHi;
+		u8 redComp;
+		u8 green1Comp;
+		u8 green2Comp;
+		u8 blueComp;
+	} exposure;
+	struct {
+		u8 balanceMode;
+		u8 redGain;
+		u8 greenGain;
+		u8 blueGain;
+	} colourBalance;
+	struct {
+		u8 divisor;
+		u8 baserate;
+	} sensorFps;
+	struct {
+		u8 gain1;
+		u8 gain2;
+		u8 gain4;
+		u8 gain8;
+	} apcor;
+	struct {
+		u8 disabled;
+		u8 flickerMode;
+		u8 coarseJump;
+		u8 allowableOverExposure;
+	} flickerControl;
+	struct {
+		u8 gain1;
+		u8 gain2;
+		u8 gain4;
+		u8 gain8;
+	} vlOffset;
+	struct {
+		u8 mode;
+		u8 decimation;
+	} compression;
+	struct {
+		u8 frTargeting;
+		u8 targetFR;
+		u8 targetQ;
+	} compressionTarget;
+	struct {
+		u8 yThreshold;
+		u8 uvThreshold;
+	} yuvThreshold;
+	struct {
+		u8 hysteresis;
+		u8 threshMax;
+		u8 smallStep;
+		u8 largeStep;
+		u8 decimationHysteresis;
+		u8 frDiffStepThresh;
+		u8 qDiffStepThresh;
+		u8 decimationThreshMod;
+	} compressionParams;
+	struct {
+		u8 videoSize;		/* CIF/QCIF */
+		u8 subSample;
+		u8 yuvOrder;
+	} format;
+	struct {                        /* Intel QX3 specific data */
+		u8 qx3_detected;        /* a QX3 is present */
+		u8 toplight;            /* top light lit , R/W */
+		u8 bottomlight;         /* bottom light lit, R/W */
+		u8 button;              /* snapshot button pressed (R/O) */
+		u8 cradled;             /* microscope is in cradle (R/O) */
+	} qx3;
+	struct {
+		u8 colStart;		/* skip first 8*colStart pixels */
+		u8 colEnd;		/* finish at 8*colEnd pixels */
+		u8 rowStart;		/* skip first 4*rowStart lines */
+		u8 rowEnd;		/* finish at 4*rowEnd lines */
+	} roi;
+	u8 ecpTiming;
+	u8 streamStartLine;
+};
+
+/* specific webcam descriptor */
+struct sd {
+	struct gspca_dev gspca_dev;		/* !! must be the first item */
+	struct cam_params params;		/* camera settings */
+
+	atomic_t cam_exposure;
+	atomic_t fps;
+	int exposure_count;
+	u8 exposure_status;
+	u8 mainsFreq;				/* 0 = 50hz, 1 = 60hz */
+	u8 first_frame;
+	u8 freq;
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcomptarget(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 = 100,
+		.step = 1,
+#define BRIGHTNESS_DEF 50
+		.default_value = BRIGHTNESS_DEF,
+		.flags = 0,
+	    },
+	    .set = sd_setbrightness,
+	    .get = sd_getbrightness,
+	},
+	{
+	    {
+		.id      = V4L2_CID_CONTRAST,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Contrast",
+		.minimum = 0,
+		.maximum = 96,
+		.step    = 8,
+#define CONTRAST_DEF 48
+		.default_value = CONTRAST_DEF,
+	    },
+	    .set = sd_setcontrast,
+	    .get = sd_getcontrast,
+	},
+	{
+	    {
+		.id      = V4L2_CID_SATURATION,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Saturation",
+		.minimum = 0,
+		.maximum = 100,
+		.step    = 1,
+#define SATURATION_DEF 50
+		.default_value = SATURATION_DEF,
+	    },
+	    .set = sd_setsaturation,
+	    .get = sd_getsaturation,
+	},
+	{
+		{
+			.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
+			.type    = V4L2_CTRL_TYPE_MENU,
+			.name    = "Light frequency filter",
+			.minimum = 0,
+			.maximum = 2,	/* 0: 0, 1: 50Hz, 2:60Hz */
+			.step    = 1,
+#define FREQ_DEF 1
+			.default_value = FREQ_DEF,
+		},
+		.set = sd_setfreq,
+		.get = sd_getfreq,
+	},
+	{
+		{
+#define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE
+			.id	 = V4L2_CID_COMP_TARGET,
+			.type    = V4L2_CTRL_TYPE_MENU,
+			.name    = "Compression Target",
+			.minimum = 0,
+			.maximum = 1,
+			.step    = 1,
+#define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
+			.default_value = COMP_TARGET_DEF,
+		},
+		.set = sd_setcomptarget,
+		.get = sd_getcomptarget,
+	},
+};
+
+static const struct v4l2_pix_format mode[] = {
+	{160, 120, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
+		/* The sizeimage is trial and error, as with low framerates
+		   the camera will pad out usb frames, making the image
+		   data larger then strictly necessary */
+		.bytesperline = 160,
+		.sizeimage = 65536,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 3},
+	{176, 144, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
+		.bytesperline = 172,
+		.sizeimage = 65536,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 2},
+	{320, 240, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 262144,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1},
+	{352, 288, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
+		.bytesperline = 352,
+		.sizeimage = 262144,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+};
+
+/**********************************************************************
+ *
+ * General functions
+ *
+ **********************************************************************/
+
+static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command)
+{
+	u8 requesttype;
+	unsigned int pipe;
+	int ret, databytes = command[6] | (command[7] << 8);
+	/* Sometimes we see spurious EPIPE errors */
+	int retries = 3;
+
+	if (command[0] == DATA_IN) {
+		pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
+		requesttype = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+	} else if (command[0] == DATA_OUT) {
+		pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
+		requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+	} else {
+		PDEBUG(D_ERR, "Unexpected first byte of command: %x",
+		       command[0]);
+		return -EINVAL;
+	}
+
+retry:
+	ret = usb_control_msg(gspca_dev->dev, pipe,
+			      command[1],
+			      requesttype,
+			      command[2] | (command[3] << 8),
+			      command[4] | (command[5] << 8),
+			      gspca_dev->usb_buf, databytes, 1000);
+
+	if (ret < 0)
+		PDEBUG(D_ERR, "usb_control_msg %02x, error %d", command[1],
+		       ret);
+
+	if (ret == -EPIPE && retries > 0) {
+		retries--;
+		goto retry;
+	}
+
+	return (ret < 0) ? ret : 0;
+}
+
+/* send an arbitrary command to the camera */
+static int do_command(struct gspca_dev *gspca_dev, u16 command,
+		      u8 a, u8 b, u8 c, u8 d)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret, datasize;
+	u8 cmd[8];
+
+	switch (command) {
+	case CPIA_COMMAND_GetCPIAVersion:
+	case CPIA_COMMAND_GetPnPID:
+	case CPIA_COMMAND_GetCameraStatus:
+	case CPIA_COMMAND_GetVPVersion:
+	case CPIA_COMMAND_GetColourParams:
+	case CPIA_COMMAND_GetColourBalance:
+	case CPIA_COMMAND_GetExposure:
+		datasize = 8;
+		break;
+	case CPIA_COMMAND_ReadMCPorts:
+	case CPIA_COMMAND_ReadVCRegs:
+		datasize = 4;
+		break;
+	default:
+		datasize = 0;
+		break;
+	}
+
+	cmd[0] = command >> 8;
+	cmd[1] = command & 0xff;
+	cmd[2] = a;
+	cmd[3] = b;
+	cmd[4] = c;
+	cmd[5] = d;
+	cmd[6] = datasize;
+	cmd[7] = 0;
+
+	ret = cpia_usb_transferCmd(gspca_dev, cmd);
+	if (ret)
+		return ret;
+
+	switch (command) {
+	case CPIA_COMMAND_GetCPIAVersion:
+		sd->params.version.firmwareVersion = gspca_dev->usb_buf[0];
+		sd->params.version.firmwareRevision = gspca_dev->usb_buf[1];
+		sd->params.version.vcVersion = gspca_dev->usb_buf[2];
+		sd->params.version.vcRevision = gspca_dev->usb_buf[3];
+		break;
+	case CPIA_COMMAND_GetPnPID:
+		sd->params.pnpID.vendor =
+			gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8);
+		sd->params.pnpID.product =
+			gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
+		sd->params.pnpID.deviceRevision =
+			gspca_dev->usb_buf[4] | (gspca_dev->usb_buf[5] << 8);
+		break;
+	case CPIA_COMMAND_GetCameraStatus:
+		sd->params.status.systemState = gspca_dev->usb_buf[0];
+		sd->params.status.grabState = gspca_dev->usb_buf[1];
+		sd->params.status.streamState = gspca_dev->usb_buf[2];
+		sd->params.status.fatalError = gspca_dev->usb_buf[3];
+		sd->params.status.cmdError = gspca_dev->usb_buf[4];
+		sd->params.status.debugFlags = gspca_dev->usb_buf[5];
+		sd->params.status.vpStatus = gspca_dev->usb_buf[6];
+		sd->params.status.errorCode = gspca_dev->usb_buf[7];
+		break;
+	case CPIA_COMMAND_GetVPVersion:
+		sd->params.vpVersion.vpVersion = gspca_dev->usb_buf[0];
+		sd->params.vpVersion.vpRevision = gspca_dev->usb_buf[1];
+		sd->params.vpVersion.cameraHeadID =
+			gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
+		break;
+	case CPIA_COMMAND_GetColourParams:
+		sd->params.colourParams.brightness = gspca_dev->usb_buf[0];
+		sd->params.colourParams.contrast = gspca_dev->usb_buf[1];
+		sd->params.colourParams.saturation = gspca_dev->usb_buf[2];
+		break;
+	case CPIA_COMMAND_GetColourBalance:
+		sd->params.colourBalance.redGain = gspca_dev->usb_buf[0];
+		sd->params.colourBalance.greenGain = gspca_dev->usb_buf[1];
+		sd->params.colourBalance.blueGain = gspca_dev->usb_buf[2];
+		break;
+	case CPIA_COMMAND_GetExposure:
+		sd->params.exposure.gain = gspca_dev->usb_buf[0];
+		sd->params.exposure.fineExp = gspca_dev->usb_buf[1];
+		sd->params.exposure.coarseExpLo = gspca_dev->usb_buf[2];
+		sd->params.exposure.coarseExpHi = gspca_dev->usb_buf[3];
+		sd->params.exposure.redComp = gspca_dev->usb_buf[4];
+		sd->params.exposure.green1Comp = gspca_dev->usb_buf[5];
+		sd->params.exposure.green2Comp = gspca_dev->usb_buf[6];
+		sd->params.exposure.blueComp = gspca_dev->usb_buf[7];
+		break;
+
+	case CPIA_COMMAND_ReadMCPorts:
+		if (!sd->params.qx3.qx3_detected)
+			break;
+		/* test button press */
+		sd->params.qx3.button = ((gspca_dev->usb_buf[1] & 0x02) == 0);
+		if (sd->params.qx3.button) {
+			/* button pressed - unlock the latch */
+			do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
+				   3, 0xDF, 0xDF, 0);
+			do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
+				   3, 0xFF, 0xFF, 0);
+		}
+
+		/* test whether microscope is cradled */
+		sd->params.qx3.cradled = ((gspca_dev->usb_buf[2] & 0x40) == 0);
+		break;
+	}
+
+	return 0;
+}
+
+/* send a command to the camera with an additional data transaction */
+static int do_command_extended(struct gspca_dev *gspca_dev, u16 command,
+			       u8 a, u8 b, u8 c, u8 d,
+			       u8 e, u8 f, u8 g, u8 h,
+			       u8 i, u8 j, u8 k, u8 l)
+{
+	u8 cmd[8];
+
+	cmd[0] = command >> 8;
+	cmd[1] = command & 0xff;
+	cmd[2] = a;
+	cmd[3] = b;
+	cmd[4] = c;
+	cmd[5] = d;
+	cmd[6] = 8;
+	cmd[7] = 0;
+	gspca_dev->usb_buf[0] = e;
+	gspca_dev->usb_buf[1] = f;
+	gspca_dev->usb_buf[2] = g;
+	gspca_dev->usb_buf[3] = h;
+	gspca_dev->usb_buf[4] = i;
+	gspca_dev->usb_buf[5] = j;
+	gspca_dev->usb_buf[6] = k;
+	gspca_dev->usb_buf[7] = l;
+
+	return cpia_usb_transferCmd(gspca_dev, cmd);
+}
+
+/*  find_over_exposure
+ *  Finds a suitable value of OverExposure for use with SetFlickerCtrl
+ *  Some calculation is required because this value changes with the brightness
+ *  set with SetColourParameters
+ *
+ *  Parameters: Brightness - last brightness value set with SetColourParameters
+ *
+ *  Returns: OverExposure value to use with SetFlickerCtrl
+ */
+#define FLICKER_MAX_EXPOSURE                    250
+#define FLICKER_ALLOWABLE_OVER_EXPOSURE         146
+#define FLICKER_BRIGHTNESS_CONSTANT             59
+static int find_over_exposure(int brightness)
+{
+	int MaxAllowableOverExposure, OverExposure;
+
+	MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
+				   FLICKER_BRIGHTNESS_CONSTANT;
+
+	if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE)
+		OverExposure = MaxAllowableOverExposure;
+	else
+		OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
+
+	return OverExposure;
+}
+#undef FLICKER_MAX_EXPOSURE
+#undef FLICKER_ALLOWABLE_OVER_EXPOSURE
+#undef FLICKER_BRIGHTNESS_CONSTANT
+
+/* initialise cam_data structure  */
+static void reset_camera_params(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct cam_params *params = &sd->params;
+
+	/* The following parameter values are the defaults from
+	 * "Software Developer's Guide for CPiA Cameras".  Any changes
+	 * to the defaults are noted in comments. */
+	params->colourParams.brightness = BRIGHTNESS_DEF;
+	params->colourParams.contrast = CONTRAST_DEF;
+	params->colourParams.saturation = SATURATION_DEF;
+	params->exposure.gainMode = 4;
+	params->exposure.expMode = 2;		/* AEC */
+	params->exposure.compMode = 1;
+	params->exposure.centreWeight = 1;
+	params->exposure.gain = 0;
+	params->exposure.fineExp = 0;
+	params->exposure.coarseExpLo = 185;
+	params->exposure.coarseExpHi = 0;
+	params->exposure.redComp = COMP_RED;
+	params->exposure.green1Comp = COMP_GREEN1;
+	params->exposure.green2Comp = COMP_GREEN2;
+	params->exposure.blueComp = COMP_BLUE;
+	params->colourBalance.balanceMode = 2;	/* ACB */
+	params->colourBalance.redGain = 32;
+	params->colourBalance.greenGain = 6;
+	params->colourBalance.blueGain = 92;
+	params->apcor.gain1 = 0x18;
+	params->apcor.gain2 = 0x16;
+	params->apcor.gain4 = 0x24;
+	params->apcor.gain8 = 0x34;
+	params->flickerControl.flickerMode = 0;
+	params->flickerControl.disabled = 1;
+
+	params->flickerControl.coarseJump =
+		flicker_jumps[sd->mainsFreq]
+			     [params->sensorFps.baserate]
+			     [params->sensorFps.divisor];
+	params->flickerControl.allowableOverExposure =
+		find_over_exposure(params->colourParams.brightness);
+	params->vlOffset.gain1 = 20;
+	params->vlOffset.gain2 = 24;
+	params->vlOffset.gain4 = 26;
+	params->vlOffset.gain8 = 26;
+	params->compressionParams.hysteresis = 3;
+	params->compressionParams.threshMax = 11;
+	params->compressionParams.smallStep = 1;
+	params->compressionParams.largeStep = 3;
+	params->compressionParams.decimationHysteresis = 2;
+	params->compressionParams.frDiffStepThresh = 5;
+	params->compressionParams.qDiffStepThresh = 3;
+	params->compressionParams.decimationThreshMod = 2;
+	/* End of default values from Software Developer's Guide */
+
+	/* Set Sensor FPS to 15fps. This seems better than 30fps
+	 * for indoor lighting. */
+	params->sensorFps.divisor = 1;
+	params->sensorFps.baserate = 1;
+
+	params->yuvThreshold.yThreshold = 6; /* From windows driver */
+	params->yuvThreshold.uvThreshold = 6; /* From windows driver */
+
+	params->format.subSample = SUBSAMPLE_420;
+	params->format.yuvOrder = YUVORDER_YUYV;
+
+	params->compression.mode = CPIA_COMPRESSION_AUTO;
+	params->compression.decimation = NO_DECIMATION;
+
+	params->compressionTarget.frTargeting = COMP_TARGET_DEF;
+	params->compressionTarget.targetFR = 15; /* From windows driver */
+	params->compressionTarget.targetQ = 5; /* From windows driver */
+
+	params->qx3.qx3_detected = 0;
+	params->qx3.toplight = 0;
+	params->qx3.bottomlight = 0;
+	params->qx3.button = 0;
+	params->qx3.cradled = 0;
+}
+
+static void printstatus(struct cam_params *params)
+{
+	PDEBUG(D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
+	       params->status.systemState, params->status.grabState,
+	       params->status.streamState, params->status.fatalError,
+	       params->status.cmdError, params->status.debugFlags,
+	       params->status.vpStatus, params->status.errorCode);
+}
+
+static int goto_low_power(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+
+	ret = do_command(gspca_dev, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0);
+	if (ret)
+		return ret;
+
+	do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
+	if (ret)
+		return ret;
+
+	if (sd->params.status.systemState != LO_POWER_STATE) {
+		if (sd->params.status.systemState != WARM_BOOT_STATE) {
+			PDEBUG(D_ERR,
+			       "unexpected state after lo power cmd: %02x",
+			       sd->params.status.systemState);
+			printstatus(&sd->params);
+		}
+		return -EIO;
+	}
+
+	PDEBUG(D_CONF, "camera now in LOW power state");
+	return 0;
+}
+
+static int goto_high_power(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+
+	ret = do_command(gspca_dev, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0);
+	if (ret)
+		return ret;
+
+	msleep_interruptible(40);	/* windows driver does it too */
+
+	if (signal_pending(current))
+		return -EINTR;
+
+	do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
+	if (ret)
+		return ret;
+
+	if (sd->params.status.systemState != HI_POWER_STATE) {
+		PDEBUG(D_ERR, "unexpected state after hi power cmd: %02x",
+			       sd->params.status.systemState);
+		printstatus(&sd->params);
+		return -EIO;
+	}
+
+	PDEBUG(D_CONF, "camera now in HIGH power state");
+	return 0;
+}
+
+static int get_version_information(struct gspca_dev *gspca_dev)
+{
+	int ret;
+
+	/* GetCPIAVersion */
+	ret = do_command(gspca_dev, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
+	if (ret)
+		return ret;
+
+	/* GetPnPID */
+	return do_command(gspca_dev, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
+}
+
+static int save_camera_state(struct gspca_dev *gspca_dev)
+{
+	int ret;
+
+	ret = do_command(gspca_dev, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
+	if (ret)
+		return ret;
+
+	return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
+}
+
+int command_setformat(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+
+	ret = do_command(gspca_dev, CPIA_COMMAND_SetFormat,
+			 sd->params.format.videoSize,
+			 sd->params.format.subSample,
+			 sd->params.format.yuvOrder, 0);
+	if (ret)
+		return ret;
+
+	return do_command(gspca_dev, CPIA_COMMAND_SetROI,
+			  sd->params.roi.colStart, sd->params.roi.colEnd,
+			  sd->params.roi.rowStart, sd->params.roi.rowEnd);
+}
+
+int command_setcolourparams(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	return do_command(gspca_dev, CPIA_COMMAND_SetColourParams,
+			  sd->params.colourParams.brightness,
+			  sd->params.colourParams.contrast,
+			  sd->params.colourParams.saturation, 0);
+}
+
+int command_setapcor(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	return do_command(gspca_dev, CPIA_COMMAND_SetApcor,
+			  sd->params.apcor.gain1,
+			  sd->params.apcor.gain2,
+			  sd->params.apcor.gain4,
+			  sd->params.apcor.gain8);
+}
+
+int command_setvloffset(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset,
+			  sd->params.vlOffset.gain1,
+			  sd->params.vlOffset.gain2,
+			  sd->params.vlOffset.gain4,
+			  sd->params.vlOffset.gain8);
+}
+
+int command_setexposure(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+
+	ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
+				  sd->params.exposure.gainMode,
+				  1,
+				  sd->params.exposure.compMode,
+				  sd->params.exposure.centreWeight,
+				  sd->params.exposure.gain,
+				  sd->params.exposure.fineExp,
+				  sd->params.exposure.coarseExpLo,
+				  sd->params.exposure.coarseExpHi,
+				  sd->params.exposure.redComp,
+				  sd->params.exposure.green1Comp,
+				  sd->params.exposure.green2Comp,
+				  sd->params.exposure.blueComp);
+	if (ret)
+		return ret;
+
+	if (sd->params.exposure.expMode != 1) {
+		ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
+					  0,
+					  sd->params.exposure.expMode,
+					  0, 0,
+					  sd->params.exposure.gain,
+					  sd->params.exposure.fineExp,
+					  sd->params.exposure.coarseExpLo,
+					  sd->params.exposure.coarseExpHi,
+					  0, 0, 0, 0);
+	}
+
+	return ret;
+}
+
+int command_setcolourbalance(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->params.colourBalance.balanceMode == 1) {
+		int ret;
+
+		ret = do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
+				 1,
+				 sd->params.colourBalance.redGain,
+				 sd->params.colourBalance.greenGain,
+				 sd->params.colourBalance.blueGain);
+		if (ret)
+			return ret;
+
+		return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
+				  3, 0, 0, 0);
+	}
+	if (sd->params.colourBalance.balanceMode == 2) {
+		return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
+				  2, 0, 0, 0);
+	}
+	if (sd->params.colourBalance.balanceMode == 3) {
+		return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
+				  3, 0, 0, 0);
+	}
+
+	return -EINVAL;
+}
+
+int command_setcompressiontarget(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	return do_command(gspca_dev, CPIA_COMMAND_SetCompressionTarget,
+			  sd->params.compressionTarget.frTargeting,
+			  sd->params.compressionTarget.targetFR,
+			  sd->params.compressionTarget.targetQ, 0);
+}
+
+int command_setyuvtresh(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	return do_command(gspca_dev, CPIA_COMMAND_SetYUVThresh,
+			  sd->params.yuvThreshold.yThreshold,
+			  sd->params.yuvThreshold.uvThreshold, 0, 0);
+}
+
+int command_setcompressionparams(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	return do_command_extended(gspca_dev,
+			    CPIA_COMMAND_SetCompressionParams,
+			    0, 0, 0, 0,
+			    sd->params.compressionParams.hysteresis,
+			    sd->params.compressionParams.threshMax,
+			    sd->params.compressionParams.smallStep,
+			    sd->params.compressionParams.largeStep,
+			    sd->params.compressionParams.decimationHysteresis,
+			    sd->params.compressionParams.frDiffStepThresh,
+			    sd->params.compressionParams.qDiffStepThresh,
+			    sd->params.compressionParams.decimationThreshMod);
+}
+
+int command_setcompression(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	return do_command(gspca_dev, CPIA_COMMAND_SetCompression,
+			  sd->params.compression.mode,
+			  sd->params.compression.decimation, 0, 0);
+}
+
+int command_setsensorfps(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	return do_command(gspca_dev, CPIA_COMMAND_SetSensorFPS,
+			  sd->params.sensorFps.divisor,
+			  sd->params.sensorFps.baserate, 0, 0);
+}
+
+int command_setflickerctrl(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	return do_command(gspca_dev, CPIA_COMMAND_SetFlickerCtrl,
+			  sd->params.flickerControl.flickerMode,
+			  sd->params.flickerControl.coarseJump,
+			  sd->params.flickerControl.allowableOverExposure,
+			  0);
+}
+
+int command_setecptiming(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	return do_command(gspca_dev, CPIA_COMMAND_SetECPTiming,
+			  sd->params.ecpTiming, 0, 0, 0);
+}
+
+int command_pause(struct gspca_dev *gspca_dev)
+{
+	return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
+}
+
+int command_resume(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	return do_command(gspca_dev, CPIA_COMMAND_InitStreamCap,
+			  0, sd->params.streamStartLine, 0, 0);
+}
+
+int command_setlights(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret, p1, p2;
+
+	if (!sd->params.qx3.qx3_detected)
+		return 0;
+
+	p1 = (sd->params.qx3.bottomlight == 0) << 1;
+	p2 = (sd->params.qx3.toplight == 0) << 3;
+
+	ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg,
+			 0x90, 0x8F, 0x50, 0);
+	if (ret)
+		return ret;
+
+	return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
+			  p1 | p2 | 0xE0, 0);
+}
+
+static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
+{
+	/* Everything in here is from the Windows driver */
+/* define for compgain calculation */
+#if 0
+#define COMPGAIN(base, curexp, newexp) \
+    (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
+#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
+    (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
+    (float)(u8)(basecomp - 128))
+#else
+  /* equivalent functions without floating point math */
+#define COMPGAIN(base, curexp, newexp) \
+    (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
+#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
+    (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
+#endif
+
+	struct sd *sd = (struct sd *) gspca_dev;
+	int currentexp = sd->params.exposure.coarseExpLo +
+			 sd->params.exposure.coarseExpHi * 256;
+	int ret, startexp;
+
+	if (on) {
+		int cj = sd->params.flickerControl.coarseJump;
+		sd->params.flickerControl.flickerMode = 1;
+		sd->params.flickerControl.disabled = 0;
+		if (sd->params.exposure.expMode != 2) {
+			sd->params.exposure.expMode = 2;
+			sd->exposure_status = EXPOSURE_NORMAL;
+		}
+		currentexp = currentexp << sd->params.exposure.gain;
+		sd->params.exposure.gain = 0;
+		/* round down current exposure to nearest value */
+		startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
+		if (startexp < 1)
+			startexp = 1;
+		startexp = (startexp * cj) - 1;
+		if (FIRMWARE_VERSION(1, 2))
+			while (startexp > MAX_EXP_102)
+				startexp -= cj;
+		else
+			while (startexp > MAX_EXP)
+				startexp -= cj;
+		sd->params.exposure.coarseExpLo = startexp & 0xff;
+		sd->params.exposure.coarseExpHi = startexp >> 8;
+		if (currentexp > startexp) {
+			if (currentexp > (2 * startexp))
+				currentexp = 2 * startexp;
+			sd->params.exposure.redComp =
+				COMPGAIN(COMP_RED, currentexp, startexp);
+			sd->params.exposure.green1Comp =
+				COMPGAIN(COMP_GREEN1, currentexp, startexp);
+			sd->params.exposure.green2Comp =
+				COMPGAIN(COMP_GREEN2, currentexp, startexp);
+			sd->params.exposure.blueComp =
+				COMPGAIN(COMP_BLUE, currentexp, startexp);
+		} else {
+			sd->params.exposure.redComp = COMP_RED;
+			sd->params.exposure.green1Comp = COMP_GREEN1;
+			sd->params.exposure.green2Comp = COMP_GREEN2;
+			sd->params.exposure.blueComp = COMP_BLUE;
+		}
+		if (FIRMWARE_VERSION(1, 2))
+			sd->params.exposure.compMode = 0;
+		else
+			sd->params.exposure.compMode = 1;
+
+		sd->params.apcor.gain1 = 0x18;
+		sd->params.apcor.gain2 = 0x18;
+		sd->params.apcor.gain4 = 0x16;
+		sd->params.apcor.gain8 = 0x14;
+	} else {
+		sd->params.flickerControl.flickerMode = 0;
+		sd->params.flickerControl.disabled = 1;
+		/* Average equivalent coarse for each comp channel */
+		startexp = EXP_FROM_COMP(COMP_RED,
+				sd->params.exposure.redComp, currentexp);
+		startexp += EXP_FROM_COMP(COMP_GREEN1,
+				sd->params.exposure.green1Comp, currentexp);
+		startexp += EXP_FROM_COMP(COMP_GREEN2,
+				sd->params.exposure.green2Comp, currentexp);
+		startexp += EXP_FROM_COMP(COMP_BLUE,
+				sd->params.exposure.blueComp, currentexp);
+		startexp = startexp >> 2;
+		while (startexp > MAX_EXP && sd->params.exposure.gain <
+		       sd->params.exposure.gainMode - 1) {
+			startexp = startexp >> 1;
+			++sd->params.exposure.gain;
+		}
+		if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102)
+			startexp = MAX_EXP_102;
+		if (startexp > MAX_EXP)
+			startexp = MAX_EXP;
+		sd->params.exposure.coarseExpLo = startexp & 0xff;
+		sd->params.exposure.coarseExpHi = startexp >> 8;
+		sd->params.exposure.redComp = COMP_RED;
+		sd->params.exposure.green1Comp = COMP_GREEN1;
+		sd->params.exposure.green2Comp = COMP_GREEN2;
+		sd->params.exposure.blueComp = COMP_BLUE;
+		sd->params.exposure.compMode = 1;
+		sd->params.apcor.gain1 = 0x18;
+		sd->params.apcor.gain2 = 0x16;
+		sd->params.apcor.gain4 = 0x24;
+		sd->params.apcor.gain8 = 0x34;
+	}
+	sd->params.vlOffset.gain1 = 20;
+	sd->params.vlOffset.gain2 = 24;
+	sd->params.vlOffset.gain4 = 26;
+	sd->params.vlOffset.gain8 = 26;
+
+	if (apply) {
+		ret = command_setexposure(gspca_dev);
+		if (ret)
+			return ret;
+
+		ret = command_setapcor(gspca_dev);
+		if (ret)
+			return ret;
+
+		ret = command_setvloffset(gspca_dev);
+		if (ret)
+			return ret;
+
+		ret = command_setflickerctrl(gspca_dev);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+#undef EXP_FROM_COMP
+#undef COMPGAIN
+}
+
+/* monitor the exposure and adjust the sensor frame rate if needed */
+static void monitor_exposure(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 exp_acc, bcomp, gain, coarseL, cmd[8];
+	int ret, light_exp, dark_exp, very_dark_exp;
+	int old_exposure, new_exposure, framerate;
+	int setfps = 0, setexp = 0, setflicker = 0;
+
+	/* get necessary stats and register settings from camera */
+	/* do_command can't handle this, so do it ourselves */
+	cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8;
+	cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff;
+	cmd[2] = 30;
+	cmd[3] = 4;
+	cmd[4] = 9;
+	cmd[5] = 8;
+	cmd[6] = 8;
+	cmd[7] = 0;
+	ret = cpia_usb_transferCmd(gspca_dev, cmd);
+	if (ret) {
+		PDEBUG(D_ERR, "ReadVPRegs(30,4,9,8) - failed: %d", ret);
+		return;
+	}
+	exp_acc = gspca_dev->usb_buf[0];
+	bcomp = gspca_dev->usb_buf[1];
+	gain = gspca_dev->usb_buf[2];
+	coarseL = gspca_dev->usb_buf[3];
+
+	light_exp = sd->params.colourParams.brightness +
+		    TC - 50 + EXP_ACC_LIGHT;
+	if (light_exp > 255)
+		light_exp = 255;
+	dark_exp = sd->params.colourParams.brightness +
+		   TC - 50 - EXP_ACC_DARK;
+	if (dark_exp < 0)
+		dark_exp = 0;
+	very_dark_exp = dark_exp / 2;
+
+	old_exposure = sd->params.exposure.coarseExpHi * 256 +
+		       sd->params.exposure.coarseExpLo;
+
+	if (!sd->params.flickerControl.disabled) {
+		/* Flicker control on */
+		int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP :
+							HIGH_COMP_102;
+		bcomp += 128;	/* decode */
+		if (bcomp >= max_comp && exp_acc < dark_exp) {
+			/* dark */
+			if (exp_acc < very_dark_exp) {
+				/* very dark */
+				if (sd->exposure_status == EXPOSURE_VERY_DARK)
+					++sd->exposure_count;
+				else {
+					sd->exposure_status =
+						EXPOSURE_VERY_DARK;
+					sd->exposure_count = 1;
+				}
+			} else {
+				/* just dark */
+				if (sd->exposure_status == EXPOSURE_DARK)
+					++sd->exposure_count;
+				else {
+					sd->exposure_status = EXPOSURE_DARK;
+					sd->exposure_count = 1;
+				}
+			}
+		} else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
+			/* light */
+			if (old_exposure <= VERY_LOW_EXP) {
+				/* very light */
+				if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
+					++sd->exposure_count;
+				else {
+					sd->exposure_status =
+						EXPOSURE_VERY_LIGHT;
+					sd->exposure_count = 1;
+				}
+			} else {
+				/* just light */
+				if (sd->exposure_status == EXPOSURE_LIGHT)
+					++sd->exposure_count;
+				else {
+					sd->exposure_status = EXPOSURE_LIGHT;
+					sd->exposure_count = 1;
+				}
+			}
+		} else {
+			/* not dark or light */
+			sd->exposure_status = EXPOSURE_NORMAL;
+		}
+	} else {
+		/* Flicker control off */
+		if (old_exposure >= MAX_EXP && exp_acc < dark_exp) {
+			/* dark */
+			if (exp_acc < very_dark_exp) {
+				/* very dark */
+				if (sd->exposure_status == EXPOSURE_VERY_DARK)
+					++sd->exposure_count;
+				else {
+					sd->exposure_status =
+						EXPOSURE_VERY_DARK;
+					sd->exposure_count = 1;
+				}
+			} else {
+				/* just dark */
+				if (sd->exposure_status == EXPOSURE_DARK)
+					++sd->exposure_count;
+				else {
+					sd->exposure_status = EXPOSURE_DARK;
+					sd->exposure_count = 1;
+				}
+			}
+		} else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
+			/* light */
+			if (old_exposure <= VERY_LOW_EXP) {
+				/* very light */
+				if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
+					++sd->exposure_count;
+				else {
+					sd->exposure_status =
+						EXPOSURE_VERY_LIGHT;
+					sd->exposure_count = 1;
+				}
+			} else {
+				/* just light */
+				if (sd->exposure_status == EXPOSURE_LIGHT)
+					++sd->exposure_count;
+				else {
+					sd->exposure_status = EXPOSURE_LIGHT;
+					sd->exposure_count = 1;
+				}
+			}
+		} else {
+			/* not dark or light */
+			sd->exposure_status = EXPOSURE_NORMAL;
+		}
+	}
+
+	framerate = atomic_read(&sd->fps);
+	if (framerate > 30 || framerate < 1)
+		framerate = 1;
+
+	if (!sd->params.flickerControl.disabled) {
+		/* Flicker control on */
+		if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
+		     sd->exposure_status == EXPOSURE_DARK) &&
+		    sd->exposure_count >= DARK_TIME * framerate &&
+		    sd->params.sensorFps.divisor < 3) {
+
+			/* dark for too long */
+			++sd->params.sensorFps.divisor;
+			setfps = 1;
+
+			sd->params.flickerControl.coarseJump =
+				flicker_jumps[sd->mainsFreq]
+					     [sd->params.sensorFps.baserate]
+					     [sd->params.sensorFps.divisor];
+			setflicker = 1;
+
+			new_exposure = sd->params.flickerControl.coarseJump-1;
+			while (new_exposure < old_exposure / 2)
+				new_exposure +=
+					sd->params.flickerControl.coarseJump;
+			sd->params.exposure.coarseExpLo = new_exposure & 0xff;
+			sd->params.exposure.coarseExpHi = new_exposure >> 8;
+			setexp = 1;
+			sd->exposure_status = EXPOSURE_NORMAL;
+			PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
+
+		} else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
+			    sd->exposure_status == EXPOSURE_LIGHT) &&
+			   sd->exposure_count >= LIGHT_TIME * framerate &&
+			   sd->params.sensorFps.divisor > 0) {
+
+			/* light for too long */
+			int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 :
+							       MAX_EXP;
+			--sd->params.sensorFps.divisor;
+			setfps = 1;
+
+			sd->params.flickerControl.coarseJump =
+				flicker_jumps[sd->mainsFreq]
+					     [sd->params.sensorFps.baserate]
+					     [sd->params.sensorFps.divisor];
+			setflicker = 1;
+
+			new_exposure = sd->params.flickerControl.coarseJump-1;
+			while (new_exposure < 2 * old_exposure &&
+			       new_exposure +
+			       sd->params.flickerControl.coarseJump < max_exp)
+				new_exposure +=
+					sd->params.flickerControl.coarseJump;
+			sd->params.exposure.coarseExpLo = new_exposure & 0xff;
+			sd->params.exposure.coarseExpHi = new_exposure >> 8;
+			setexp = 1;
+			sd->exposure_status = EXPOSURE_NORMAL;
+			PDEBUG(D_CONF, "Automatically increasing sensor_fps");
+		}
+	} else {
+		/* Flicker control off */
+		if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
+		     sd->exposure_status == EXPOSURE_DARK) &&
+		    sd->exposure_count >= DARK_TIME * framerate &&
+		    sd->params.sensorFps.divisor < 3) {
+
+			/* dark for too long */
+			++sd->params.sensorFps.divisor;
+			setfps = 1;
+
+			if (sd->params.exposure.gain > 0) {
+				--sd->params.exposure.gain;
+				setexp = 1;
+			}
+			sd->exposure_status = EXPOSURE_NORMAL;
+			PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
+
+		} else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
+			    sd->exposure_status == EXPOSURE_LIGHT) &&
+			   sd->exposure_count >= LIGHT_TIME * framerate &&
+			   sd->params.sensorFps.divisor > 0) {
+
+			/* light for too long */
+			--sd->params.sensorFps.divisor;
+			setfps = 1;
+
+			if (sd->params.exposure.gain <
+			    sd->params.exposure.gainMode - 1) {
+				++sd->params.exposure.gain;
+				setexp = 1;
+			}
+			sd->exposure_status = EXPOSURE_NORMAL;
+			PDEBUG(D_CONF, "Automatically increasing sensor_fps");
+		}
+	}
+
+	if (setexp)
+		command_setexposure(gspca_dev);
+
+	if (setfps)
+		command_setsensorfps(gspca_dev);
+
+	if (setflicker)
+		command_setflickerctrl(gspca_dev);
+}
+
+/*-----------------------------------------------------------------*/
+/* if flicker is switched off, this function switches it back on.It checks,
+   however, that conditions are suitable before restarting it.
+   This should only be called for firmware version 1.2.
+
+   It also adjust the colour balance when an exposure step is detected - as
+   long as flicker is running
+*/
+static void restart_flicker(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int cam_exposure, old_exp;
+
+	if (!FIRMWARE_VERSION(1, 2))
+		return;
+
+	cam_exposure = atomic_read(&sd->cam_exposure);
+
+	if (sd->params.flickerControl.flickerMode == 0 ||
+	    cam_exposure == 0)
+		return;
+
+	old_exp = sd->params.exposure.coarseExpLo +
+		  sd->params.exposure.coarseExpHi*256;
+	/*
+	  see how far away camera exposure is from a valid
+	  flicker exposure value
+	*/
+	cam_exposure %= sd->params.flickerControl.coarseJump;
+	if (!sd->params.flickerControl.disabled &&
+	    cam_exposure <= sd->params.flickerControl.coarseJump - 3) {
+		/* Flicker control auto-disabled */
+		sd->params.flickerControl.disabled = 1;
+	}
+
+	if (sd->params.flickerControl.disabled &&
+	    old_exp > sd->params.flickerControl.coarseJump +
+		      ROUND_UP_EXP_FOR_FLICKER) {
+		/* exposure is now high enough to switch
+		   flicker control back on */
+		set_flicker(gspca_dev, 1, 1);
+	}
+}
+
+/* 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;
+
+	reset_camera_params(gspca_dev);
+
+	PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
+	       id->idVendor, id->idProduct);
+
+	cam = &gspca_dev->cam;
+	cam->cam_mode = mode;
+	cam->nmodes = ARRAY_SIZE(mode);
+
+	sd_setfreq(gspca_dev, FREQ_DEF);
+
+	return 0;
+}
+
+/* -- start the camera -- */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int priv, ret;
+
+	/* Start the camera in low power mode */
+	if (goto_low_power(gspca_dev)) {
+		if (sd->params.status.systemState != WARM_BOOT_STATE) {
+			PDEBUG(D_ERR, "unexpected systemstate: %02x",
+			       sd->params.status.systemState);
+			printstatus(&sd->params);
+			return -ENODEV;
+		}
+
+		/* FIXME: this is just dirty trial and error */
+		ret = goto_high_power(gspca_dev);
+		if (ret)
+			return ret;
+
+		ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame,
+				 0, 0, 0, 0);
+		if (ret)
+			return ret;
+
+		ret = goto_low_power(gspca_dev);
+		if (ret)
+			return ret;
+	}
+
+	/* procedure described in developer's guide p3-28 */
+
+	/* Check the firmware version. */
+	sd->params.version.firmwareVersion = 0;
+	get_version_information(gspca_dev);
+	if (sd->params.version.firmwareVersion != 1) {
+		PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)",
+		       sd->params.version.firmwareVersion);
+		return -ENODEV;
+	}
+
+	/* A bug in firmware 1-02 limits gainMode to 2 */
+	if (sd->params.version.firmwareRevision <= 2 &&
+	    sd->params.exposure.gainMode > 2) {
+		sd->params.exposure.gainMode = 2;
+	}
+
+	/* set QX3 detected flag */
+	sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 &&
+				       sd->params.pnpID.product == 0x0001);
+
+	/* The fatal error checking should be done after
+	 * the camera powers up (developer's guide p 3-38) */
+
+	/* Set streamState before transition to high power to avoid bug
+	 * in firmware 1-02 */
+	ret = do_command(gspca_dev, CPIA_COMMAND_ModifyCameraStatus,
+			 STREAMSTATE, 0, STREAM_NOT_READY, 0);
+	if (ret)
+		return ret;
+
+	/* GotoHiPower */
+	ret = goto_high_power(gspca_dev);
+	if (ret)
+		return ret;
+
+	/* Check the camera status */
+	ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
+	if (ret)
+		return ret;
+
+	if (sd->params.status.fatalError) {
+		PDEBUG(D_ERR, "fatal_error: %04x, vp_status: %04x",
+		       sd->params.status.fatalError,
+		       sd->params.status.vpStatus);
+		return -EIO;
+	}
+
+	/* VPVersion can't be retrieved before the camera is in HiPower,
+	 * so get it here instead of in get_version_information. */
+	ret = do_command(gspca_dev, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
+	if (ret)
+		return ret;
+
+	/* Determine video mode settings */
+	sd->params.streamStartLine = 120;
+
+	priv = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
+	if (priv & 0x01) { /* crop */
+		sd->params.roi.colStart = 2;
+		sd->params.roi.rowStart = 6;
+	} else {
+		sd->params.roi.colStart = 0;
+		sd->params.roi.rowStart = 0;
+	}
+
+	if (priv & 0x02) { /* quarter */
+		sd->params.format.videoSize = VIDEOSIZE_QCIF;
+		sd->params.roi.colStart /= 2;
+		sd->params.roi.rowStart /= 2;
+		sd->params.streamStartLine /= 2;
+	} else
+		sd->params.format.videoSize = VIDEOSIZE_CIF;
+
+	sd->params.roi.colEnd = sd->params.roi.colStart +
+				(gspca_dev->width >> 3);
+	sd->params.roi.rowEnd = sd->params.roi.rowStart +
+				(gspca_dev->height >> 2);
+
+	/* And now set the camera to a known state */
+	ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode,
+			 CPIA_GRAB_CONTINEOUS, 0, 0, 0);
+	if (ret)
+		return ret;
+	/* We start with compression disabled, as we need one uncompressed
+	   frame to handle later compressed frames */
+	ret = do_command(gspca_dev, CPIA_COMMAND_SetCompression,
+			 CPIA_COMPRESSION_NONE,
+			 NO_DECIMATION, 0, 0);
+	if (ret)
+		return ret;
+	ret = command_setcompressiontarget(gspca_dev);
+	if (ret)
+		return ret;
+	ret = command_setcolourparams(gspca_dev);
+	if (ret)
+		return ret;
+	ret = command_setformat(gspca_dev);
+	if (ret)
+		return ret;
+	ret = command_setyuvtresh(gspca_dev);
+	if (ret)
+		return ret;
+	ret = command_setecptiming(gspca_dev);
+	if (ret)
+		return ret;
+	ret = command_setcompressionparams(gspca_dev);
+	if (ret)
+		return ret;
+	ret = command_setexposure(gspca_dev);
+	if (ret)
+		return ret;
+	ret = command_setcolourbalance(gspca_dev);
+	if (ret)
+		return ret;
+	ret = command_setsensorfps(gspca_dev);
+	if (ret)
+		return ret;
+	ret = command_setapcor(gspca_dev);
+	if (ret)
+		return ret;
+	ret = command_setflickerctrl(gspca_dev);
+	if (ret)
+		return ret;
+	ret = command_setvloffset(gspca_dev);
+	if (ret)
+		return ret;
+
+	/* Start stream */
+	ret = command_resume(gspca_dev);
+	if (ret)
+		return ret;
+
+	/* Wait 6 frames before turning compression on for the sensor to get
+	   all settings and AEC/ACB to settle */
+	sd->first_frame = 6;
+	sd->exposure_status = EXPOSURE_NORMAL;
+	sd->exposure_count = 0;
+	atomic_set(&sd->cam_exposure, 0);
+	atomic_set(&sd->fps, 0);
+
+	return 0;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+	command_pause(gspca_dev);
+
+	/* save camera state for later open (developers guide ch 3.5.3) */
+	save_camera_state(gspca_dev);
+
+	/* GotoLoPower */
+	goto_low_power(gspca_dev);
+
+	/* Update the camera status */
+	do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+
+	/* Start / Stop the camera to make sure we are talking to
+	   a supported camera, and to get some information from it
+	   to print. */
+	ret = sd_start(gspca_dev);
+	if (ret)
+		return ret;
+
+	sd_stopN(gspca_dev);
+
+	PDEBUG(D_PROBE, "CPIA Version:             %d.%02d (%d.%d)",
+			sd->params.version.firmwareVersion,
+			sd->params.version.firmwareRevision,
+			sd->params.version.vcVersion,
+			sd->params.version.vcRevision);
+	PDEBUG(D_PROBE, "CPIA PnP-ID:              %04x:%04x:%04x",
+			sd->params.pnpID.vendor, sd->params.pnpID.product,
+			sd->params.pnpID.deviceRevision);
+	PDEBUG(D_PROBE, "VP-Version:               %d.%d %04x",
+			sd->params.vpVersion.vpVersion,
+			sd->params.vpVersion.vpRevision,
+			sd->params.vpVersion.cameraHeadID);
+
+	return 0;
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,
+			int len)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	/* Check for SOF */
+	if (len >= 64 &&
+	    data[0] == MAGIC_0 && data[1] == MAGIC_1 &&
+	    data[16] == sd->params.format.videoSize &&
+	    data[17] == sd->params.format.subSample &&
+	    data[18] == sd->params.format.yuvOrder &&
+	    data[24] == sd->params.roi.colStart &&
+	    data[25] == sd->params.roi.colEnd &&
+	    data[26] == sd->params.roi.rowStart &&
+	    data[27] == sd->params.roi.rowEnd) {
+		struct gspca_frame *frame = gspca_get_i_frame(gspca_dev);
+
+		atomic_set(&sd->cam_exposure, data[39] * 2);
+		atomic_set(&sd->fps, data[41]);
+
+		if (frame == NULL) {
+			gspca_dev->last_packet_type = DISCARD_PACKET;
+			return;
+		}
+
+		/* Check for proper EOF for last frame */
+		if ((frame->data_end - frame->data) > 4 &&
+		    frame->data_end[-4] == 0xff &&
+		    frame->data_end[-3] == 0xff &&
+		    frame->data_end[-2] == 0xff &&
+		    frame->data_end[-1] == 0xff)
+			gspca_frame_add(gspca_dev, LAST_PACKET,
+						NULL, 0);
+
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
+		return;
+	}
+
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
+}
+
+static void sd_dq_callback(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	/* Set the normal compression settings once we have captured a
+	   few uncompressed frames (and AEC has hopefully settled) */
+	if (sd->first_frame) {
+		sd->first_frame--;
+		if (sd->first_frame == 0)
+			command_setcompression(gspca_dev);
+	}
+
+	/* Switch flicker control back on if it got turned off */
+	restart_flicker(gspca_dev);
+
+	/* If AEC is enabled, monitor the exposure and
+	   adjust the sensor frame rate if needed */
+	if (sd->params.exposure.expMode == 2)
+		monitor_exposure(gspca_dev);
+
+	/* Update our knowledge of the camera state */
+	do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
+	if (sd->params.qx3.qx3_detected)
+		do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+
+	sd->params.colourParams.brightness = val;
+	sd->params.flickerControl.allowableOverExposure =
+		find_over_exposure(sd->params.colourParams.brightness);
+	if (gspca_dev->streaming) {
+		ret = command_setcolourparams(gspca_dev);
+		if (ret)
+			return ret;
+		return command_setflickerctrl(gspca_dev);
+	}
+	return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->params.colourParams.brightness;
+	return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->params.colourParams.contrast = val;
+	if (gspca_dev->streaming)
+		return command_setcolourparams(gspca_dev);
+
+	return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->params.colourParams.contrast;
+	return 0;
+}
+
+static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->params.colourParams.saturation = val;
+	if (gspca_dev->streaming)
+		return command_setcolourparams(gspca_dev);
+
+	return 0;
+}
+
+static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->params.colourParams.saturation;
+	return 0;
+}
+
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int on;
+
+	switch (val) {
+	case 0:		/* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
+		on = 0;
+		break;
+	case 1:		/* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
+		on = 1;
+		sd->mainsFreq = 0;
+		break;
+	case 2:		/* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+		on = 1;
+		sd->mainsFreq = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	sd->freq = val;
+	sd->params.flickerControl.coarseJump =
+		flicker_jumps[sd->mainsFreq]
+			     [sd->params.sensorFps.baserate]
+			     [sd->params.sensorFps.divisor];
+
+	return set_flicker(gspca_dev, on, gspca_dev->streaming);
+}
+
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->freq;
+	return 0;
+}
+
+static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->params.compressionTarget.frTargeting = val;
+	if (gspca_dev->streaming)
+		return command_setcompressiontarget(gspca_dev);
+
+	return 0;
+}
+
+static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->params.compressionTarget.frTargeting;
+	return 0;
+}
+
+static int sd_querymenu(struct gspca_dev *gspca_dev,
+			struct v4l2_querymenu *menu)
+{
+	switch (menu->id) {
+	case V4L2_CID_POWER_LINE_FREQUENCY:
+		switch (menu->index) {
+		case 0:		/* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
+			strcpy((char *) menu->name, "NoFliker");
+			return 0;
+		case 1:		/* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
+			strcpy((char *) menu->name, "50 Hz");
+			return 0;
+		case 2:		/* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+			strcpy((char *) menu->name, "60 Hz");
+			return 0;
+		}
+		break;
+	case V4L2_CID_COMP_TARGET:
+		switch (menu->index) {
+		case CPIA_COMPRESSION_TARGET_QUALITY:
+			strcpy((char *) menu->name, "Quality");
+			return 0;
+		case CPIA_COMPRESSION_TARGET_FRAMERATE:
+			strcpy((char *) menu->name, "Framerate");
+			return 0;
+		}
+		break;
+	}
+	return -EINVAL;
+}
+
+/* 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,
+	.dq_callback = sd_dq_callback,
+	.pkt_scan = sd_pkt_scan,
+	.querymenu = sd_querymenu,
+};
+
+/* -- module initialisation -- */
+static const __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x0553, 0x0002)},
+	{USB_DEVICE(0x0813, 0x0001)},
+	{}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+			const struct usb_device_id *id)
+{
+	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+				THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+	.name = MODULE_NAME,
+	.id_table = device_table,
+	.probe = sd_probe,
+	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
+	PDEBUG(D_PROBE, "registered");
+	return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+	usb_deregister(&sd_driver);
+	PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/etoms.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/etoms.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/etoms.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/etoms.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,7 +52,7 @@ static int sd_getcolors(struct gspca_dev
 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 	{
 	 {
 	  .id = V4L2_CID_BRIGHTNESS,
@@ -851,7 +851,7 @@ static int sd_getautogain(struct gspca_d
 }
 
 /* sub-driver description */
-static struct sd_desc sd_desc = {
+static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gl860/gl860.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/gl860/gl860.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gl860/gl860.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/gl860/gl860.c	2010-05-16 17:17:36.000000000 -0400
@@ -161,7 +161,7 @@ static int gl860_build_control_table(str
 
 /*==================== sud-driver structure initialisation =================*/
 
-static struct sd_desc sd_desc_mi1320 = {
+static const struct sd_desc sd_desc_mi1320 = {
 	.name        = MODULE_NAME,
 	.ctrls       = sd_ctrls_mi1320,
 	.nctrls      = GL860_NCTRLS,
@@ -174,7 +174,7 @@ static struct sd_desc sd_desc_mi1320 = {
 	.dq_callback = sd_callback,
 };
 
-static struct sd_desc sd_desc_mi2020 = {
+static const struct sd_desc sd_desc_mi2020 = {
 	.name        = MODULE_NAME,
 	.ctrls       = sd_ctrls_mi2020,
 	.nctrls      = GL860_NCTRLS,
@@ -187,7 +187,7 @@ static struct sd_desc sd_desc_mi2020 = {
 	.dq_callback = sd_callback,
 };
 
-static struct sd_desc sd_desc_mi2020b = {
+static const struct sd_desc sd_desc_mi2020b = {
 	.name        = MODULE_NAME,
 	.ctrls       = sd_ctrls_mi2020b,
 	.nctrls      = GL860_NCTRLS,
@@ -200,7 +200,7 @@ static struct sd_desc sd_desc_mi2020b =
 	.dq_callback = sd_callback,
 };
 
-static struct sd_desc sd_desc_ov2640 = {
+static const struct sd_desc sd_desc_ov2640 = {
 	.name        = MODULE_NAME,
 	.ctrls       = sd_ctrls_ov2640,
 	.nctrls      = GL860_NCTRLS,
@@ -213,7 +213,7 @@ static struct sd_desc sd_desc_ov2640 = {
 	.dq_callback = sd_callback,
 };
 
-static struct sd_desc sd_desc_ov9655 = {
+static const struct sd_desc sd_desc_ov9655 = {
 	.name        = MODULE_NAME,
 	.ctrls       = sd_ctrls_ov9655,
 	.nctrls      = GL860_NCTRLS,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gspca.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/gspca.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gspca.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/gspca.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,9 @@
  *
  * Copyright (C) 2008-2009 Jean-Francois Moine (http://moinejf.free.fr)
  *
+ * Camera button input handling by MÃ¡rton NÃ©meth
+ * Copyright (C) 2009-2010 MÃ¡rton NÃ©meth <nm127@freemail.hu>
+ *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
  * Free Software Foundation; either version 2 of the License, or (at your
@@ -37,6 +40,11 @@
 
 #include "gspca.h"
 
+#ifdef CONFIG_INPUT
+#include <linux/input.h>
+#include <linux/usb/input.h>
+#endif
+
 /* global values */
 #define DEF_NURBS 3		/* default number of URBs */
 #if DEF_NURBS > MAX_NURBS
@@ -47,7 +55,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http
 MODULE_DESCRIPTION("GSPCA USB Camera Driver");
 MODULE_LICENSE("GPL");
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 8, 0)
+#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 9, 0)
 
 #ifdef GSPCA_DEBUG
 int gspca_debug = D_ERR | D_PROBE;
@@ -104,15 +112,185 @@ static const struct vm_operations_struct
 	.close		= gspca_vm_close,
 };
 
+/*
+ * Input and interrupt endpoint handling functions
+ */
+#ifdef CONFIG_INPUT
+static void int_irq(struct urb *urb)
+{
+	struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
+	int ret;
+
+	ret = urb->status;
+	switch (ret) {
+	case 0:
+		if (gspca_dev->sd_desc->int_pkt_scan(gspca_dev,
+		    urb->transfer_buffer, urb->actual_length) < 0) {
+			PDEBUG(D_ERR, "Unknown packet received");
+		}
+		break;
+
+	case -ENOENT:
+	case -ECONNRESET:
+	case -ENODEV:
+	case -ESHUTDOWN:
+		/* Stop is requested either by software or hardware is gone,
+		 * keep the ret value non-zero and don't resubmit later.
+		 */
+		break;
+
+	default:
+		PDEBUG(D_ERR, "URB error %i, resubmitting", urb->status);
+		urb->status = 0;
+		ret = 0;
+	}
+
+	if (ret == 0) {
+		ret = usb_submit_urb(urb, GFP_ATOMIC);
+		if (ret < 0)
+			PDEBUG(D_ERR, "Resubmit URB failed with error %i", ret);
+	}
+}
+
+static int gspca_input_connect(struct gspca_dev *dev)
+{
+	struct input_dev *input_dev;
+	int err = 0;
+
+	dev->input_dev = NULL;
+	if (dev->sd_desc->int_pkt_scan || dev->sd_desc->other_input)  {
+		input_dev = input_allocate_device();
+		if (!input_dev)
+			return -ENOMEM;
+
+		usb_make_path(dev->dev, dev->phys, sizeof(dev->phys));
+		strlcat(dev->phys, "/input0", sizeof(dev->phys));
+
+		input_dev->name = dev->sd_desc->name;
+		input_dev->phys = dev->phys;
+
+		usb_to_input_id(dev->dev, &input_dev->id);
+
+		input_dev->evbit[0] = BIT_MASK(EV_KEY);
+		input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
+		input_dev->dev.parent = &dev->dev->dev;
+
+		err = input_register_device(input_dev);
+		if (err) {
+			PDEBUG(D_ERR, "Input device registration failed "
+				"with error %i", err);
+			input_dev->dev.parent = NULL;
+			input_free_device(input_dev);
+		} else {
+			dev->input_dev = input_dev;
+		}
+	}
+
+	return err;
+}
+
+static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
+			  struct usb_endpoint_descriptor *ep)
+{
+	unsigned int buffer_len;
+	int interval;
+	struct urb *urb;
+	struct usb_device *dev;
+	void *buffer = NULL;
+	int ret = -EINVAL;
+
+	buffer_len = ep->wMaxPacketSize;
+	interval = ep->bInterval;
+	PDEBUG(D_PROBE, "found int in endpoint: 0x%x, "
+		"buffer_len=%u, interval=%u",
+		ep->bEndpointAddress, buffer_len, interval);
+
+	dev = gspca_dev->dev;
+
+	urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!urb) {
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	buffer = usb_buffer_alloc(dev, ep->wMaxPacketSize,
+				GFP_KERNEL, &urb->transfer_dma);
+	if (!buffer) {
+		ret = -ENOMEM;
+		goto error_buffer;
+	}
+	usb_fill_int_urb(urb, dev,
+		usb_rcvintpipe(dev, ep->bEndpointAddress),
+		buffer, buffer_len,
+		int_irq, (void *)gspca_dev, interval);
+	gspca_dev->int_urb = urb;
+	ret = usb_submit_urb(urb, GFP_KERNEL);
+	if (ret < 0) {
+		PDEBUG(D_ERR, "submit URB failed with error %i", ret);
+		goto error_submit;
+	}
+	return ret;
+
+error_submit:
+	usb_buffer_free(dev,
+			urb->transfer_buffer_length,
+			urb->transfer_buffer,
+			urb->transfer_dma);
+error_buffer:
+	usb_free_urb(urb);
+error:
+	return ret;
+}
+
+static void gspca_input_create_urb(struct gspca_dev *gspca_dev)
+{
+	struct usb_interface *intf;
+	struct usb_host_interface *intf_desc;
+	struct usb_endpoint_descriptor *ep;
+	int i;
+
+	if (gspca_dev->sd_desc->int_pkt_scan)  {
+		intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
+		intf_desc = intf->cur_altsetting;
+		for (i = 0; i < intf_desc->desc.bNumEndpoints; i++) {
+			ep = &intf_desc->endpoint[i].desc;
+			if (usb_endpoint_dir_in(ep) &&
+			    usb_endpoint_xfer_int(ep)) {
+
+				alloc_and_submit_int_urb(gspca_dev, ep);
+				break;
+			}
+		}
+	}
+}
+
+static void gspca_input_destroy_urb(struct gspca_dev *gspca_dev)
+{
+	struct urb *urb;
+
+	urb = gspca_dev->int_urb;
+	if (urb) {
+		gspca_dev->int_urb = NULL;
+		usb_kill_urb(urb);
+		usb_buffer_free(gspca_dev->dev,
+				urb->transfer_buffer_length,
+				urb->transfer_buffer,
+				urb->transfer_dma);
+		usb_free_urb(urb);
+	}
+}
+#else
+#define gspca_input_connect(gspca_dev)		0
+#define gspca_input_create_urb(gspca_dev)
+#define gspca_input_destroy_urb(gspca_dev)
+#endif
+
 /* get the current input frame buffer */
 struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev)
 {
 	struct gspca_frame *frame;
-	int i;
 
-	i = gspca_dev->fr_i;
-	i = gspca_dev->fr_queue[i];
-	frame = &gspca_dev->frame[i];
+	frame = gspca_dev->cur_frame;
 	if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
 				!= V4L2_BUF_FLAG_QUEUED)
 		return NULL;
@@ -486,11 +664,13 @@ static struct usb_host_endpoint *get_ep(
 			i, ep->desc.bEndpointAddress);
 	gspca_dev->alt = i;		/* memorize the current alt setting */
 	if (gspca_dev->nbalt > 1) {
+		gspca_input_destroy_urb(gspca_dev);
 		ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
 		if (ret < 0) {
 			err("set alt %d err %d", i, ret);
-			return NULL;
+			ep = NULL;
 		}
+		gspca_input_create_urb(gspca_dev);
 	}
 	return ep;
 }
@@ -534,26 +714,22 @@ static int create_urbs(struct gspca_dev
 			nurbs = 1;
 	}
 
-	gspca_dev->nurbs = nurbs;
 	for (n = 0; n < nurbs; n++) {
 		urb = usb_alloc_urb(npkt, GFP_KERNEL);
 		if (!urb) {
 			err("usb_alloc_urb failed");
-			destroy_urbs(gspca_dev);
 			return -ENOMEM;
 		}
+		gspca_dev->urb[n] = urb;
 		urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev,
 						bsize,
 						GFP_KERNEL,
 						&urb->transfer_dma);
 
 		if (urb->transfer_buffer == NULL) {
-			usb_free_urb(urb);
-			err("usb_buffer_urb failed");
-			destroy_urbs(gspca_dev);
+			err("usb_buffer_alloc failed");
 			return -ENOMEM;
 		}
-		gspca_dev->urb[n] = urb;
 		urb->dev = gspca_dev->dev;
 		urb->context = gspca_dev;
 		urb->transfer_buffer_length = bsize;
@@ -585,6 +761,7 @@ static int create_urbs(struct gspca_dev
 static int gspca_init_transfer(struct gspca_dev *gspca_dev)
 {
 	struct usb_host_endpoint *ep;
+	struct urb *urb;
 	int n, ret;
 
 	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
@@ -595,6 +772,8 @@ static int gspca_init_transfer(struct gs
 		goto out;
 	}
 
+	gspca_dev->usb_err = 0;
+
 	/* set the higher alternate setting and
 	 * loop until urb submit succeeds */
 	if (gspca_dev->cam.reverse_alts)
@@ -613,10 +792,15 @@ static int gspca_init_transfer(struct gs
 		goto out;
 	}
 	for (;;) {
-		PDEBUG(D_STREAM, "init transfer alt %d", gspca_dev->alt);
-		ret = create_urbs(gspca_dev, ep);
-		if (ret < 0)
-			goto out;
+		if (!gspca_dev->cam.no_urb_create) {
+			PDEBUG(D_STREAM, "init transfer alt %d",
+				gspca_dev->alt);
+			ret = create_urbs(gspca_dev, ep);
+			if (ret < 0) {
+				destroy_urbs(gspca_dev);
+				goto out;
+			}
+		}
 
 		/* clear the bulk endpoint */
 		if (gspca_dev->cam.bulk)
@@ -636,8 +820,11 @@ static int gspca_init_transfer(struct gs
 			break;
 
 		/* submit the URBs */
-		for (n = 0; n < gspca_dev->nurbs; n++) {
-			ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL);
+		for (n = 0; n < MAX_NURBS; n++) {
+			urb = gspca_dev->urb[n];
+			if (urb == NULL)
+				break;
+			ret = usb_submit_urb(urb, GFP_KERNEL);
 			if (ret < 0)
 				break;
 		}
@@ -694,7 +881,9 @@ static void gspca_stream_off(struct gspc
 		if (gspca_dev->sd_desc->stopN)
 			gspca_dev->sd_desc->stopN(gspca_dev);
 		destroy_urbs(gspca_dev);
+		gspca_input_destroy_urb(gspca_dev);
 		gspca_set_alt0(gspca_dev);
+		gspca_input_create_urb(gspca_dev);
 	}
 
 	/* always call stop0 to free the subdriver's resources */
@@ -2060,11 +2249,12 @@ int gspca_dev_probe(struct usb_interface
 		PDEBUG(D_ERR, "Too many config");
 		return -ENODEV;
 	}
+
+	/* the USB video interface must be the first one */
 	interface = &intf->cur_altsetting->desc;
-	if (interface->bInterfaceNumber > 0) {
-		PDEBUG(D_ERR, "intf != 0");
+	if (dev->config->desc.bNumInterfaces != 1 &&
+	    interface->bInterfaceNumber != 0)
 		return -ENODEV;
-	}
 
 	/* create the device */
 	if (dev_size < sizeof *gspca_dev)
@@ -2096,6 +2286,10 @@ int gspca_dev_probe(struct usb_interface
 		goto out;
 	gspca_set_default_mode(gspca_dev);
 
+	ret = gspca_input_connect(gspca_dev);
+	if (ret)
+		goto out;
+
 	mutex_init(&gspca_dev->usb_lock);
 	mutex_init(&gspca_dev->read_lock);
 	mutex_init(&gspca_dev->queue_lock);
@@ -2116,8 +2310,15 @@ int gspca_dev_probe(struct usb_interface
 
 	usb_set_intfdata(intf, gspca_dev);
 	PDEBUG(D_PROBE, "%s created", video_device_node_name(&gspca_dev->vdev));
+
+	gspca_input_create_urb(gspca_dev);
+
 	return 0;
 out:
+#ifdef CONFIG_INPUT
+	if (gspca_dev->input_dev)
+		input_unregister_device(gspca_dev->input_dev);
+#endif
 	kfree(gspca_dev->usb_buf);
 	kfree(gspca_dev);
 	return ret;
@@ -2133,6 +2334,9 @@ EXPORT_SYMBOL(gspca_dev_probe);
 void gspca_disconnect(struct usb_interface *intf)
 {
 	struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
+#ifdef CONFIG_INPUT
+	struct input_dev *input_dev;
+#endif
 
 	PDEBUG(D_PROBE, "%s disconnect",
 		video_device_node_name(&gspca_dev->vdev));
@@ -2144,6 +2348,15 @@ void gspca_disconnect(struct usb_interfa
 		wake_up_interruptible(&gspca_dev->wq);
 	}
 
+#ifdef CONFIG_INPUT
+	gspca_input_destroy_urb(gspca_dev);
+	input_dev = gspca_dev->input_dev;
+	if (input_dev) {
+		gspca_dev->input_dev = NULL;
+		input_unregister_device(input_dev);
+	}
+#endif
+
 	/* the device is freed at exit of this function */
 	gspca_dev->dev = NULL;
 	mutex_unlock(&gspca_dev->usb_lock);
@@ -2169,6 +2382,7 @@ int gspca_suspend(struct usb_interface *
 	if (gspca_dev->sd_desc->stopN)
 		gspca_dev->sd_desc->stopN(gspca_dev);
 	destroy_urbs(gspca_dev);
+	gspca_input_destroy_urb(gspca_dev);
 	gspca_set_alt0(gspca_dev);
 	if (gspca_dev->sd_desc->stop0)
 		gspca_dev->sd_desc->stop0(gspca_dev);
@@ -2182,6 +2396,7 @@ int gspca_resume(struct usb_interface *i
 
 	gspca_dev->frozen = 0;
 	gspca_dev->sd_desc->init(gspca_dev);
+	gspca_input_create_urb(gspca_dev);
 	if (gspca_dev->streaming)
 		return gspca_init_transfer(gspca_dev);
 	return 0;
@@ -2205,6 +2420,8 @@ int gspca_auto_gain_n_exposure(struct gs
 	int retval = 0;
 
 	for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
+		if (gspca_dev->ctrl_dis & (1 << i))
+			continue;
 		if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN)
 			gain_ctrl = &gspca_dev->sd_desc->ctrls[i];
 		if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE)
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gspca.h linux-libre-2.6.34-gnu1/drivers/media/video/gspca/gspca.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gspca.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/gspca.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 /* compilation option */
 #define GSPCA_DEBUG 1
@@ -48,26 +49,27 @@ extern int gspca_debug;
 
 /* used to list framerates supported by a camera mode (resolution) */
 struct framerates {
-	int *rates;
+	const u8 *rates;
 	int nrates;
 };
 
 /* device information - set at probe time */
 struct cam {
-	int bulk_size;		/* buffer size when image transfer by bulk */
 	const struct v4l2_pix_format *cam_mode;	/* size nmodes */
-	char nmodes;
 	const struct framerates *mode_framerates; /* must have size nmode,
 						   * just like cam_mode */
-	__u8 bulk_nurbs;	/* number of URBs in bulk mode
+	u32 bulk_size;		/* buffer size when image transfer by bulk */
+	u32 input_flags;	/* value for ENUM_INPUT status flags */
+	u8 nmodes;		/* size of cam_mode */
+	u8 no_urb_create;	/* don't create transfer URBs */
+	u8 bulk_nurbs;		/* number of URBs in bulk mode
 				 * - cannot be > MAX_NURBS
 				 * - when 0 and bulk_size != 0 means
 				 *   1 URB and submit done by subdriver */
 	u8 bulk;		/* image transfer by 0:isoc / 1:bulk */
 	u8 npkt;		/* number of packets in an ISOC message
 				 * 0 is the default value: 32 packets */
-	u32 input_flags;	/* value for ENUM_INPUT status flags */
-	char reverse_alts;	/* Alt settings are in high to low order */
+	u8 reverse_alts;	/* Alt settings are in high to low order */
 };
 
 struct gspca_dev;
@@ -90,6 +92,9 @@ typedef int (*cam_qmnu_op) (struct gspca
 typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
 				u8 *data,
 				int len);
+typedef int (*cam_int_pkt_op) (struct gspca_dev *gspca_dev,
+				u8 *data,
+				int len);
 
 struct ctrl {
 	struct v4l2_queryctrl qctrl;
@@ -125,6 +130,12 @@ struct sd_desc {
 	cam_reg_op get_register;
 #endif
 	cam_ident_op get_chip_ident;
+#ifdef CONFIG_INPUT
+	cam_int_pkt_op int_pkt_scan;
+	/* other_input makes the gspca core create gspca_dev->input even when
+	   int_pkt_scan is NULL, for cams with non interrupt driven buttons */
+	u8 other_input;
+#endif
 };
 
 /* packet types when moving from iso buf to frame buf */
@@ -147,6 +158,10 @@ struct gspca_dev {
 	struct module *module;		/* subdriver handling the device */
 	struct usb_device *dev;
 	struct file *capt_file;		/* file doing video capture */
+#ifdef CONFIG_INPUT
+	struct input_dev *input_dev;
+	char phys[64];			/* physical device path */
+#endif
 
 	struct cam cam;				/* device information */
 	const struct sd_desc *sd_desc;		/* subdriver description */
@@ -156,6 +171,9 @@ struct gspca_dev {
 #define USB_BUF_SZ 64
 	__u8 *usb_buf;				/* buffer for USB exchanges */
 	struct urb *urb[MAX_NURBS];
+#ifdef CONFIG_INPUT
+	struct urb *int_urb;
+#endif
 
 	__u8 *frbuf;				/* buffer for nframes */
 	struct gspca_frame frame[GSPCA_MAX_FRAMES];
@@ -187,7 +205,6 @@ struct gspca_dev {
 	char users;			/* number of opens */
 	char present;			/* device connected */
 	char nbufread;			/* number of buffers for read() */
-	char nurbs;			/* number of allocated URBs */
 	char memory;			/* memory type (V4L2_MEMORY_xxx) */
 	__u8 iface;			/* USB interface number */
 	__u8 alt;			/* USB alternate setting */
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/jeilinj.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/jeilinj.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/jeilinj.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/jeilinj.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #define MODULE_NAME "jeilinj"
 
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 #include "gspca.h"
 #include "jpeg.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/Kconfig linux-libre-2.6.34-gnu1/drivers/media/video/gspca/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,15 @@ source "drivers/media/video/gspca/m5602/
 source "drivers/media/video/gspca/stv06xx/Kconfig"
 source "drivers/media/video/gspca/gl860/Kconfig"
 
+config USB_GSPCA_BENQ
+	tristate "Benq USB Camera Driver"
+	depends on VIDEO_V4L2 && USB_GSPCA
+	help
+	  Say Y here if you want support for the Benq DC E300 camera.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gspca_benq.
+
 config USB_GSPCA_CONEX
 	tristate "Conexant Camera Driver"
 	depends on VIDEO_V4L2 && USB_GSPCA
@@ -30,6 +39,17 @@ config USB_GSPCA_CONEX
 	  To compile this driver as a module, choose M here: the
 	  module will be called gspca_conex.
 
+config USB_GSPCA_CPIA1
+	tristate "cpia CPiA (version 1) Camera Driver"
+	depends on VIDEO_V4L2 && USB_GSPCA
+	help
+	  Say Y here if you want support for USB cameras based on the cpia
+	  CPiA chip. Note that you need atleast version 0.6.4 of libv4l for
+	  applications to understand the videoformat generated by this driver.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gspca_cpia1.
+
 config USB_GSPCA_ETOMS
 	tristate "Etoms USB Camera Driver"
 	depends on VIDEO_V4L2 && USB_GSPCA
@@ -86,15 +106,25 @@ config USB_GSPCA_OV519
 	  module will be called gspca_ov519.
 
 config USB_GSPCA_OV534
-	tristate "OV534 USB Camera Driver"
+	tristate "OV534 OV772x USB Camera Driver"
 	depends on VIDEO_V4L2 && USB_GSPCA
 	help
-	  Say Y here if you want support for cameras based on the OV534 chip.
-	  (e.g. Sony Playstation EYE)
+	  Say Y here if you want support for cameras based on the OV534 chip
+	  and sensor OV772x (e.g. Sony Playstation EYE)
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called gspca_ov534.
 
+config USB_GSPCA_OV534_9
+	tristate "OV534 OV965x USB Camera Driver"
+	depends on VIDEO_V4L2 && USB_GSPCA
+	help
+	  Say Y here if you want support for cameras based on the OV534 chip
+	  and sensor OV965x (e.g. Hercules Dualpix)
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gspca_ov534_9.
+
 config USB_GSPCA_PAC207
 	tristate "Pixart PAC207 USB Camera Driver"
 	depends on VIDEO_V4L2 && USB_GSPCA
@@ -122,6 +152,16 @@ config USB_GSPCA_PAC7311
 	  To compile this driver as a module, choose M here: the
 	  module will be called gspca_pac7311.
 
+config USB_GSPCA_SN9C2028
+	tristate "SONIX Dual-Mode USB Camera Driver"
+	depends on VIDEO_V4L2 && USB_GSPCA
+	help
+	  Say Y here if you want streaming support for Sonix SN9C2028 cameras.
+	  These are supported as stillcams in libgphoto2/camlibs/sonix.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gspca_sn9c2028.
+
 config USB_GSPCA_SN9C20X
 	tristate "SN9C20X USB Camera Driver"
 	depends on VIDEO_V4L2 && USB_GSPCA
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_mt9m111.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/m5602/m5602_mt9m111.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_mt9m111.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/m5602/m5602_mt9m111.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,7 +48,7 @@ static struct v4l2_pix_format mt9m111_mo
 	}
 };
 
-const static struct ctrl mt9m111_ctrls[] = {
+static const struct ctrl mt9m111_ctrls[] = {
 #define VFLIP_IDX 0
 	{
 		{
@@ -171,7 +171,7 @@ int mt9m111_probe(struct sd *sd)
 		return -ENODEV;
 	}
 
-	info("Probing for a mt9m111 sensor");
+	PDEBUG(D_PROBE, "Probing for a mt9m111 sensor");
 
 	/* Do the preinit */
 	for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_ov7660.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/m5602/m5602_ov7660.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_ov7660.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/m5602/m5602_ov7660.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,7 @@ static int ov7660_set_hflip(struct gspca
 static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
 static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
 
-const static struct ctrl ov7660_ctrls[] = {
+static const struct ctrl ov7660_ctrls[] = {
 #define GAIN_IDX 1
 	{
 		{
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_ov7660.h linux-libre-2.6.34-gnu1/drivers/media/video/gspca/m5602/m5602_ov7660.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_ov7660.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/m5602/m5602_ov7660.h	2010-05-16 17:17:36.000000000 -0400
@@ -94,7 +94,7 @@ int ov7660_start(struct sd *sd);
 int ov7660_stop(struct sd *sd);
 void ov7660_disconnect(struct sd *sd);
 
-const static struct m5602_sensor ov7660 = {
+static const struct m5602_sensor ov7660 = {
 	.name = "ov7660",
 	.i2c_slave_id = 0x42,
 	.i2c_regW = 1,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.c	2010-05-16 17:17:36.000000000 -0400
@@ -307,7 +307,7 @@ int ov9650_probe(struct sd *sd)
 		return -ENODEV;
 	}
 
-	info("Probing for an ov9650 sensor");
+	PDEBUG(D_PROBE, "Probing for an ov9650 sensor");
 
 	/* Run the pre-init before probing the sensor */
 	for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_po1030.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/m5602/m5602_po1030.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_po1030.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/m5602/m5602_po1030.c	2010-05-16 17:17:36.000000000 -0400
@@ -205,7 +205,7 @@ int po1030_probe(struct sd *sd)
 		return -ENODEV;
 	}
 
-	info("Probing for a po1030 sensor");
+	PDEBUG(D_PROBE, "Probing for a po1030 sensor");
 
 	/* Run the pre-init to actually probe the unit */
 	for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.c	2010-05-16 17:17:36.000000000 -0400
@@ -248,7 +248,7 @@ int s5k4aa_probe(struct sd *sd)
 		return -ENODEV;
 	}
 
-	info("Probing for a s5k4aa sensor");
+	PDEBUG(D_PROBE, "Probing for a s5k4aa sensor");
 
 	/* Preinit the sensor */
 	for (i = 0; i < ARRAY_SIZE(preinit_s5k4aa) && !err; i++) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_s5k83a.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/m5602/m5602_s5k83a.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_s5k83a.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/m5602/m5602_s5k83a.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include "m5602_s5k83a.h"
 
 static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
@@ -143,7 +144,7 @@ int s5k83a_probe(struct sd *sd)
 		return -ENODEV;
 	}
 
-	info("Probing for a s5k83a sensor");
+	PDEBUG(D_PROBE, "Probing for a s5k83a sensor");
 
 	/* Preinit the sensor */
 	for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/Makefile linux-libre-2.6.34-gnu1/drivers/media/video/gspca/Makefile
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,7 @@
 obj-$(CONFIG_USB_GSPCA)          += gspca_main.o
+obj-$(CONFIG_USB_GSPCA_BENQ)     += gspca_benq.o
 obj-$(CONFIG_USB_GSPCA_CONEX)    += gspca_conex.o
+obj-$(CONFIG_USB_GSPCA_CPIA1)    += gspca_cpia1.o
 obj-$(CONFIG_USB_GSPCA_ETOMS)    += gspca_etoms.o
 obj-$(CONFIG_USB_GSPCA_FINEPIX)  += gspca_finepix.o
 obj-$(CONFIG_USB_GSPCA_JEILINJ)  += gspca_jeilinj.o
@@ -7,9 +9,11 @@ obj-$(CONFIG_USB_GSPCA_MARS)     += gspc
 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_OV534_9)  += gspca_ov534_9.o
 obj-$(CONFIG_USB_GSPCA_PAC207)   += gspca_pac207.o
 obj-$(CONFIG_USB_GSPCA_PAC7302)  += gspca_pac7302.o
 obj-$(CONFIG_USB_GSPCA_PAC7311)  += gspca_pac7311.o
+obj-$(CONFIG_USB_GSPCA_SN9C2028) += gspca_sn9c2028.o
 obj-$(CONFIG_USB_GSPCA_SN9C20X)  += gspca_sn9c20x.o
 obj-$(CONFIG_USB_GSPCA_SONIXB)   += gspca_sonixb.o
 obj-$(CONFIG_USB_GSPCA_SONIXJ)   += gspca_sonixj.o
@@ -30,7 +34,9 @@ obj-$(CONFIG_USB_GSPCA_VC032X)   += gspc
 obj-$(CONFIG_USB_GSPCA_ZC3XX)    += gspca_zc3xx.o
 
 gspca_main-objs     := gspca.o
+gspca_benq-objs     := benq.o
 gspca_conex-objs    := conex.o
+gspca_cpia1-objs    := cpia1.o
 gspca_etoms-objs    := etoms.o
 gspca_finepix-objs  := finepix.o
 gspca_jeilinj-objs  := jeilinj.o
@@ -38,9 +44,11 @@ gspca_mars-objs     := mars.o
 gspca_mr97310a-objs := mr97310a.o
 gspca_ov519-objs    := ov519.o
 gspca_ov534-objs    := ov534.o
+gspca_ov534_9-objs  := ov534_9.o
 gspca_pac207-objs   := pac207.o
 gspca_pac7302-objs  := pac7302.o
 gspca_pac7311-objs  := pac7311.o
+gspca_sn9c2028-objs := sn9c2028.o
 gspca_sn9c20x-objs  := sn9c20x.o
 gspca_sonixb-objs   := sonixb.o
 gspca_sonixj-objs   := sonixj.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/mars.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/mars.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/mars.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/mars.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,7 +54,7 @@ static int sd_getgamma(struct gspca_dev
 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[] = {
+static const struct ctrl sd_ctrls[] = {
 	{
 	    {
 		.id      = V4L2_CID_BRIGHTNESS,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/mr97310a.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/mr97310a.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/mr97310a.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/mr97310a.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,6 +57,14 @@
 #define MR97310A_GAIN_MAX		31
 #define MR97310A_GAIN_DEFAULT		25
 
+#define MR97310A_CONTRAST_MIN		0
+#define MR97310A_CONTRAST_MAX		31
+#define MR97310A_CONTRAST_DEFAULT	23
+
+#define MR97310A_CS_GAIN_MIN		0
+#define MR97310A_CS_GAIN_MAX		0x7ff
+#define MR97310A_CS_GAIN_DEFAULT	0x110
+
 #define MR97310A_MIN_CLOCKDIV_MIN	3
 #define MR97310A_MIN_CLOCKDIV_MAX	8
 #define MR97310A_MIN_CLOCKDIV_DEFAULT	3
@@ -82,7 +90,8 @@ struct sd {
 
 	int brightness;
 	u16 exposure;
-	u8 gain;
+	u32 gain;
+	u8 contrast;
 	u8 min_clockdiv;
 };
 
@@ -98,6 +107,8 @@ static int sd_setbrightness(struct gspca
 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val);
@@ -105,11 +116,13 @@ static int sd_getmin_clockdiv(struct gsp
 static void setbrightness(struct gspca_dev *gspca_dev);
 static void setexposure(struct gspca_dev *gspca_dev);
 static void setgain(struct gspca_dev *gspca_dev);
+static void setcontrast(struct gspca_dev *gspca_dev);
 
 /* V4L2 controls supported by the driver */
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 /* Separate brightness control description for Argus QuickClix as it has
-   different limits from the other mr97310a cameras */
+ * different limits from the other mr97310a cameras, and separate gain
+ * control for Sakar CyberPix camera. */
 	{
 #define NORM_BRIGHTNESS_IDX 0
 		{
@@ -171,7 +184,37 @@ static struct ctrl sd_ctrls[] = {
 		.get = sd_getgain,
 	},
 	{
-#define MIN_CLOCKDIV_IDX 4
+#define SAKAR_CS_GAIN_IDX 4
+		{
+			.id = V4L2_CID_GAIN,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "Gain",
+			.minimum = MR97310A_CS_GAIN_MIN,
+			.maximum = MR97310A_CS_GAIN_MAX,
+			.step = 1,
+			.default_value = MR97310A_CS_GAIN_DEFAULT,
+			.flags = 0,
+		},
+		.set = sd_setgain,
+		.get = sd_getgain,
+	},
+	{
+#define CONTRAST_IDX 5
+		{
+			.id = V4L2_CID_CONTRAST,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "Contrast",
+			.minimum = MR97310A_CONTRAST_MIN,
+			.maximum = MR97310A_CONTRAST_MAX,
+			.step = 1,
+			.default_value = MR97310A_CONTRAST_DEFAULT,
+			.flags = 0,
+		},
+		.set = sd_setcontrast,
+		.get = sd_getcontrast,
+	},
+	{
+#define MIN_CLOCKDIV_IDX 6
 		{
 			.id = V4L2_CID_PRIVATE_BASE,
 			.type = V4L2_CTRL_TYPE_INTEGER,
@@ -327,7 +370,6 @@ static int zero_the_pointer(struct gspca
 	if (err_code < 0)
 		return err_code;
 
-	err_code = mr_write(gspca_dev, 1);
 	data[0] = 0x19;
 	data[1] = 0x51;
 	err_code = mr_write(gspca_dev, 2);
@@ -437,6 +479,7 @@ static int sd_config(struct gspca_dev *g
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
+	int gain_default = MR97310A_GAIN_DEFAULT;
 	int err_code;
 
 	cam = &gspca_dev->cam;
@@ -460,12 +503,14 @@ static int sd_config(struct gspca_dev *g
 	if (err_code < 0)
 		return err_code;
 
+	/* Now, the query for sensor type. */
+	err_code = cam_get_response16(gspca_dev, 0x07, 1);
+	if (err_code < 0)
+		return err_code;
+
 	if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {
 		sd->cam_type = CAM_TYPE_CIF;
 		cam->nmodes--;
-		err_code = cam_get_response16(gspca_dev, 0x06, 1);
-		if (err_code < 0)
-			return err_code;
 		/*
 		 * All but one of the known CIF cameras share the same USB ID,
 		 * but two different init routines are in use, and the control
@@ -473,12 +518,12 @@ static int sd_config(struct gspca_dev *g
 		 * of the two known varieties is connected!
 		 *
 		 * A list of known CIF cameras follows. They all report either
-		 * 0002 for type 0 or 0003 for type 1.
+		 * 0200 for type 0 or 0300 for type 1.
 		 * If you have another to report, please do
 		 *
 		 * Name		sd->sensor_type		reported by
 		 *
-		 * Sakar Spy-shot	0		T. Kilgore
+		 * Sakar 56379 Spy-shot	0		T. Kilgore
 		 * Innovage		0		T. Kilgore
 		 * Vivitar Mini		0		H. De Goede
 		 * Vivitar Mini		0		E. Rodriguez
@@ -487,7 +532,7 @@ static int sd_config(struct gspca_dev *g
 		 * Philips dig. keych.	1		T. Kilgore
 		 * Trust Spyc@m 100	1		A. Jacobs
 		 */
-		switch (gspca_dev->usb_buf[1]) {
+		switch (gspca_dev->usb_buf[0]) {
 		case 2:
 			sd->sensor_type = 0;
 			break;
@@ -504,20 +549,19 @@ static int sd_config(struct gspca_dev *g
 	} else {
 		sd->cam_type = CAM_TYPE_VGA;
 
-		err_code = cam_get_response16(gspca_dev, 0x07, 1);
-		if (err_code < 0)
-			return err_code;
-
 		/*
-		 * Here is a table of the responses to the previous command
-		 * from the known MR97310A VGA cameras.
+		 * Here is a table of the responses to the query for sensor
+		 * type, from the known MR97310A VGA cameras. Six different
+		 * cameras of which five share the same USB ID.
 		 *
 		 * Name			gspca_dev->usb_buf[]	sd->sensor_type
 		 *				sd->do_lcd_stop
 		 * Aiptek Pencam VGA+	0300		0		1
-		 * ION digital		0350		0		1
+		 * ION digital		0300		0		1
 		 * Argus DC-1620	0450		1		0
 		 * Argus QuickClix	0420		1		1
+		 * Sakar 77379 Digital	0350		0		1
+		 * Sakar 1638x CyberPix	0120		0		2
 		 *
 		 * Based upon these results, we assume default settings
 		 * and then correct as necessary, as follows.
@@ -527,10 +571,12 @@ static int sd_config(struct gspca_dev *g
 		sd->sensor_type = 1;
 		sd->do_lcd_stop = 0;
 		sd->adj_colors = 0;
-		if ((gspca_dev->usb_buf[0] != 0x03) &&
+		if (gspca_dev->usb_buf[0] == 0x01) {
+			sd->sensor_type = 2;
+		} else if ((gspca_dev->usb_buf[0] != 0x03) &&
 					(gspca_dev->usb_buf[0] != 0x04)) {
 			PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x",
-					gspca_dev->usb_buf[1]);
+					gspca_dev->usb_buf[0]);
 			PDEBUG(D_ERR, "Defaults assumed, may not work");
 			PDEBUG(D_ERR, "Please report this");
 		}
@@ -560,7 +606,7 @@ static int sd_config(struct gspca_dev *g
 		PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
 		       sd->sensor_type);
 	}
-	/* Stop streaming as we've started it to probe the sensor type. */
+	/* Stop streaming as we've started it only to probe the sensor type. */
 	sd_stopN(gspca_dev);
 
 	if (force_sensor_type != -1) {
@@ -574,9 +620,13 @@ static int sd_config(struct gspca_dev *g
 		/* No brightness for sensor_type 0 */
 		if (sd->sensor_type == 0)
 			gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
-					      (1 << ARGUS_QC_BRIGHTNESS_IDX);
+					      (1 << ARGUS_QC_BRIGHTNESS_IDX) |
+					      (1 << CONTRAST_IDX) |
+					      (1 << SAKAR_CS_GAIN_IDX);
 		else
 			gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
+					      (1 << CONTRAST_IDX) |
+					      (1 << SAKAR_CS_GAIN_IDX) |
 					      (1 << MIN_CLOCKDIV_IDX);
 	} else {
 		/* All controls need to be disabled if VGA sensor_type is 0 */
@@ -585,17 +635,30 @@ static int sd_config(struct gspca_dev *g
 					      (1 << ARGUS_QC_BRIGHTNESS_IDX) |
 					      (1 << EXPOSURE_IDX) |
 					      (1 << GAIN_IDX) |
+					      (1 << CONTRAST_IDX) |
+					      (1 << SAKAR_CS_GAIN_IDX) |
 					      (1 << MIN_CLOCKDIV_IDX);
-		else if (sd->do_lcd_stop)
+		else if (sd->sensor_type == 2) {
+			gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
+					      (1 << ARGUS_QC_BRIGHTNESS_IDX) |
+					      (1 << GAIN_IDX) |
+					      (1 << MIN_CLOCKDIV_IDX);
+			gain_default = MR97310A_CS_GAIN_DEFAULT;
+		} else if (sd->do_lcd_stop)
 			/* Argus QuickClix has different brightness limits */
-			gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX);
+			gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
+					      (1 << CONTRAST_IDX) |
+					      (1 << SAKAR_CS_GAIN_IDX);
 		else
-			gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX);
+			gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
+					      (1 << CONTRAST_IDX) |
+					      (1 << SAKAR_CS_GAIN_IDX);
 	}
 
 	sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
 	sd->exposure = MR97310A_EXPOSURE_DEFAULT;
-	sd->gain = MR97310A_GAIN_DEFAULT;
+	sd->gain = gain_default;
+	sd->contrast = MR97310A_CONTRAST_DEFAULT;
 	sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT;
 
 	return 0;
@@ -697,6 +760,12 @@ static int start_cif_cam(struct gspca_de
 			{0x13, 0x00, {0x01}, 1},
 			{0, 0, {0}, 0}
 		};
+		/* Without this command the cam won't work with USB-UHCI */
+		gspca_dev->usb_buf[0] = 0x0a;
+		gspca_dev->usb_buf[1] = 0x00;
+		err_code = mr_write(gspca_dev, 2);
+		if (err_code < 0)
+			return err_code;
 		err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
 					 ARRAY_SIZE(cif_sensor1_init_data));
 	}
@@ -717,6 +786,10 @@ static int start_vga_cam(struct gspca_de
 		data[5]  = 0x00;
 		data[10] = 0x91;
 	}
+	if (sd->sensor_type == 2) {
+		data[5]  = 0x00;
+		data[10] = 0x18;
+	}
 
 	switch (gspca_dev->width) {
 	case 160:
@@ -731,6 +804,10 @@ static int start_vga_cam(struct gspca_de
 		data[4] = 0x78;  /* reg 3, V size/4 */
 		data[6] = 0x04;  /* reg 5, H start */
 		data[8] = 0x03;  /* reg 7, V start */
+		if (sd->sensor_type == 2) {
+			data[6] = 2;
+			data[8] = 1;
+		}
 		if (sd->do_lcd_stop)
 			data[8] = 0x04;  /* Bayer tile shifted */
 		break;
@@ -753,7 +830,6 @@ static int start_vga_cam(struct gspca_de
 		return err_code;
 
 	if (!sd->sensor_type) {
-		/* The only known sensor_type 0 cam is the Argus DC-1620 */
 		const struct sensor_w_data vga_sensor0_init_data[] = {
 			{0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
 			{0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
@@ -764,7 +840,7 @@ static int start_vga_cam(struct gspca_de
 		};
 		err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
 					 ARRAY_SIZE(vga_sensor0_init_data));
-	} else {	/* sd->sensor_type = 1 */
+	} else if (sd->sensor_type == 1) {
 		const struct sensor_w_data color_adj[] = {
 			{0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
 				/* adjusted blue, green, red gain correct
@@ -802,6 +878,48 @@ static int start_vga_cam(struct gspca_de
 
 		err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
 					 ARRAY_SIZE(vga_sensor1_init_data));
+	} else {	/* sensor type == 2 */
+		const struct sensor_w_data vga_sensor2_init_data[] = {
+
+			{0x01, 0x00, {0x48}, 1},
+			{0x02, 0x00, {0x22}, 1},
+			/* Reg 3 msb and 4 is lsb of the exposure setting*/
+			{0x05, 0x00, {0x10}, 1},
+			{0x06, 0x00, {0x00}, 1},
+			{0x07, 0x00, {0x00}, 1},
+			{0x08, 0x00, {0x00}, 1},
+			{0x09, 0x00, {0x00}, 1},
+			/* The following are used in the gain control
+			 * which is BTW completely borked in the OEM driver
+			 * The values for each color go from 0 to 0x7ff
+			 *{0x0a, 0x00, {0x01}, 1},  green1 gain msb
+			 *{0x0b, 0x00, {0x10}, 1},  green1 gain lsb
+			 *{0x0c, 0x00, {0x01}, 1},  red gain msb
+			 *{0x0d, 0x00, {0x10}, 1},  red gain lsb
+			 *{0x0e, 0x00, {0x01}, 1},  blue gain msb
+			 *{0x0f, 0x00, {0x10}, 1},  blue gain lsb
+			 *{0x10, 0x00, {0x01}, 1}, green2 gain msb
+			 *{0x11, 0x00, {0x10}, 1}, green2 gain lsb
+			 */
+			{0x12, 0x00, {0x00}, 1},
+			{0x13, 0x00, {0x04}, 1}, /* weird effect on colors */
+			{0x14, 0x00, {0x00}, 1},
+			{0x15, 0x00, {0x06}, 1},
+			{0x16, 0x00, {0x01}, 1},
+			{0x17, 0x00, {0xe2}, 1}, /* vertical alignment */
+			{0x18, 0x00, {0x02}, 1},
+			{0x19, 0x00, {0x82}, 1}, /* don't mess with */
+			{0x1a, 0x00, {0x00}, 1},
+			{0x1b, 0x00, {0x20}, 1},
+			/* {0x1c, 0x00, {0x17}, 1}, contrast control */
+			{0x1d, 0x00, {0x80}, 1}, /* moving causes a mess */
+			{0x1e, 0x00, {0x08}, 1}, /* moving jams the camera */
+			{0x1f, 0x00, {0x0c}, 1},
+			{0x20, 0x00, {0x00}, 1},
+			{0, 0, {0}, 0}
+		};
+		err_code = sensor_write_regs(gspca_dev, vga_sensor2_init_data,
+					 ARRAY_SIZE(vga_sensor2_init_data));
 	}
 	return err_code;
 }
@@ -834,6 +952,7 @@ static int sd_start(struct gspca_dev *gs
 		return err_code;
 
 	setbrightness(gspca_dev);
+	setcontrast(gspca_dev);
 	setexposure(gspca_dev);
 	setgain(gspca_dev);
 
@@ -893,7 +1012,7 @@ static void setbrightness(struct gspca_d
 static void setexposure(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int exposure;
+	int exposure = MR97310A_EXPOSURE_DEFAULT;
 	u8 buf[2];
 
 	if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
@@ -905,6 +1024,11 @@ static void setexposure(struct gspca_dev
 		exposure = (sd->exposure * 9267) / 10000 + 300;
 		sensor_write1(gspca_dev, 3, exposure >> 4);
 		sensor_write1(gspca_dev, 4, exposure & 0x0f);
+	} else if (sd->sensor_type == 2) {
+		exposure = sd->exposure;
+		exposure >>= 3;
+		sensor_write1(gspca_dev, 3, exposure >> 8);
+		sensor_write1(gspca_dev, 4, exposure & 0xff);
 	} else {
 		/* We have both a clock divider and an exposure register.
 		   We first calculate the clock divider, as that determines
@@ -943,17 +1067,34 @@ static void setexposure(struct gspca_dev
 static void setgain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	u8 gainreg;
 
-	if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
+	if ((gspca_dev->ctrl_dis & (1 << GAIN_IDX)) &&
+	    (gspca_dev->ctrl_dis & (1 << SAKAR_CS_GAIN_IDX)))
 		return;
 
-	if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
+	if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1)
 		sensor_write1(gspca_dev, 0x0e, sd->gain);
-	} else {
+	else if (sd->cam_type == CAM_TYPE_VGA && sd->sensor_type == 2)
+		for (gainreg = 0x0a; gainreg < 0x11; gainreg += 2) {
+			sensor_write1(gspca_dev, gainreg, sd->gain >> 8);
+			sensor_write1(gspca_dev, gainreg + 1, sd->gain & 0xff);
+		}
+	else
 		sensor_write1(gspca_dev, 0x10, sd->gain);
-	}
 }
 
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (gspca_dev->ctrl_dis & (1 << CONTRAST_IDX))
+		return;
+
+	sensor_write1(gspca_dev, 0x1c, sd->contrast);
+}
+
+
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -1008,6 +1149,25 @@ static int sd_getgain(struct gspca_dev *
 	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;
+}
+
 static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/ov519.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/ov519.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/ov519.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/ov519.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
  */
 #define MODULE_NAME "ov519"
 
+#include <linux/input.h>
 #include "gspca.h"
 
 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
@@ -70,6 +71,9 @@ struct sd {
 	char invert_led;
 #define BRIDGE_INVERT_LED	8
 
+	char snapshot_pressed;
+	char snapshot_needs_reset;
+
 	/* Determined by sensor type */
 	__u8 sif;
 
@@ -99,10 +103,12 @@ struct sd {
 #define SEN_OV66308AF 5
 #define SEN_OV7610 6
 #define SEN_OV7620 7
-#define SEN_OV7640 8
-#define SEN_OV7670 9
-#define SEN_OV76BE 10
-#define SEN_OV8610 11
+#define SEN_OV7620AE 8
+#define SEN_OV7640 9
+#define SEN_OV7648 10
+#define SEN_OV7670 11
+#define SEN_OV76BE 12
+#define SEN_OV8610 13
 
 	u8 sensor_addr;
 	int sensor_width;
@@ -139,6 +145,7 @@ static void setautobrightness(struct sd
 static void setfreq(struct sd *sd);
 
 static const struct ctrl sd_ctrls[] = {
+#define BRIGHTNESS_IDX 0
 	{
 	    {
 		.id      = V4L2_CID_BRIGHTNESS,
@@ -153,6 +160,7 @@ static const struct ctrl sd_ctrls[] = {
 	    .set = sd_setbrightness,
 	    .get = sd_getbrightness,
 	},
+#define CONTRAST_IDX 1
 	{
 	    {
 		.id      = V4L2_CID_CONTRAST,
@@ -167,6 +175,7 @@ static const struct ctrl sd_ctrls[] = {
 	    .set = sd_setcontrast,
 	    .get = sd_getcontrast,
 	},
+#define COLOR_IDX 2
 	{
 	    {
 		.id      = V4L2_CID_SATURATION,
@@ -503,7 +512,7 @@ static const struct v4l2_pix_format ovfx
 /*
  * The FX2 chip does not give us a zero length read at end of frame.
  * It does, however, give a short read at the end of a frame, if
- * neccessary, rather than run two frames together.
+ * necessary, rather than run two frames together.
  *
  * By choosing the right bulk transfer size, we are guaranteed to always
  * get a short read for the last read of each frame.  Frame sizes are
@@ -2554,7 +2563,7 @@ static int ov7xx0_configure(struct sd *s
 		/* I don't know what's different about the 76BE yet. */
 		if (i2c_r(sd, 0x15) & 1) {
 			PDEBUG(D_PROBE, "Sensor is an OV7620AE");
-			sd->sensor = SEN_OV7620;
+			sd->sensor = SEN_OV7620AE;
 		} else {
 			PDEBUG(D_PROBE, "Sensor is an OV76BE");
 			sd->sensor = SEN_OV76BE;
@@ -2588,7 +2597,7 @@ static int ov7xx0_configure(struct sd *s
 				break;
 			case 0x48:
 				PDEBUG(D_PROBE, "Sensor is an OV7648");
-				sd->sensor = SEN_OV7640; /* FIXME */
+				sd->sensor = SEN_OV7648;
 				break;
 			default:
 				PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
@@ -2680,6 +2689,36 @@ static void ov51x_led_control(struct sd
 	}
 }
 
+static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (!sd->snapshot_needs_reset)
+		return;
+
+	/* Note it is important that we clear sd->snapshot_needs_reset,
+	   before actually clearing the snapshot state in the bridge
+	   otherwise we might race with the pkt_scan interrupt handler */
+	sd->snapshot_needs_reset = 0;
+
+	switch (sd->bridge) {
+	case BRIDGE_OV511:
+	case BRIDGE_OV511PLUS:
+		reg_w(sd, R51x_SYS_SNAP, 0x02);
+		reg_w(sd, R51x_SYS_SNAP, 0x00);
+		break;
+	case BRIDGE_OV518:
+	case BRIDGE_OV518PLUS:
+		reg_w(sd, R51x_SYS_SNAP, 0x02); /* Reset */
+		reg_w(sd, R51x_SYS_SNAP, 0x01); /* Enable */
+		break;
+	case BRIDGE_OV519:
+		reg_w(sd, R51x_SYS_RESET, 0x40);
+		reg_w(sd, R51x_SYS_RESET, 0x00);
+		break;
+	}
+}
+
 static int ov51x_upload_quan_tables(struct sd *sd)
 {
 	const unsigned char yQuanTable511[] = {
@@ -3115,7 +3154,11 @@ static int sd_config(struct gspca_dev *g
 				      (1 << OV7670_FREQ_IDX);
 	}
 	sd->quality = QUALITY_DEF;
-	if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670)
+	if (sd->sensor == SEN_OV7640 ||
+	    sd->sensor == SEN_OV7648)
+		gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT_IDX) |
+				       (1 << CONTRAST_IDX);
+	if (sd->sensor == SEN_OV7670)
 		gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX;
 	/* OV8610 Frequency filter control should work but needs testing */
 	if (sd->sensor == SEN_OV8610)
@@ -3169,10 +3212,12 @@ static int sd_init(struct gspca_dev *gsp
 			return -EIO;
 		break;
 	case SEN_OV7620:
+	case SEN_OV7620AE:
 		if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
 			return -EIO;
 		break;
 	case SEN_OV7640:
+	case SEN_OV7648:
 		if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
 			return -EIO;
 		break;
@@ -3246,7 +3291,9 @@ static int ov511_mode_init_regs(struct s
 	/* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed
 	   for more sensors we need to do this for them too */
 	case SEN_OV7620:
+	case SEN_OV7620AE:
 	case SEN_OV7640:
+	case SEN_OV7648:
 	case SEN_OV76BE:
 		if (sd->gspca_dev.width == 320)
 			interlaced = 1;
@@ -3377,7 +3424,7 @@ static int ov518_mode_init_regs(struct s
 
 	if (sd->bridge == BRIDGE_OV518PLUS) {
 		switch (sd->sensor) {
-		case SEN_OV7620:
+		case SEN_OV7620AE:
 			if (sd->gspca_dev.width == 320) {
 				reg_w(sd, 0x20, 0x00);
 				reg_w(sd, 0x21, 0x19);
@@ -3386,6 +3433,10 @@ static int ov518_mode_init_regs(struct s
 				reg_w(sd, 0x21, 0x1f);
 			}
 			break;
+		case SEN_OV7620:
+			reg_w(sd, 0x20, 0x00);
+			reg_w(sd, 0x21, 0x19);
+			break;
 		default:
 			reg_w(sd, 0x21, 0x19);
 		}
@@ -3488,7 +3539,8 @@ static int ov519_mode_init_regs(struct s
 		if (write_regvals(sd, mode_init_519,
 				  ARRAY_SIZE(mode_init_519)))
 			return -EIO;
-		if (sd->sensor == SEN_OV7640) {
+		if (sd->sensor == SEN_OV7640 ||
+		    sd->sensor == SEN_OV7648) {
 			/* Select 8-bit input mode */
 			reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
 		}
@@ -3503,6 +3555,9 @@ static int ov519_mode_init_regs(struct s
 	if (sd->sensor == SEN_OV7670 &&
 	    sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
 		reg_w(sd, OV519_R12_X_OFFSETL, 0x04);
+	else if (sd->sensor == SEN_OV7648 &&
+	    sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
+		reg_w(sd, OV519_R12_X_OFFSETL, 0x01);
 	else
 		reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
 	reg_w(sd, OV519_R13_X_OFFSETH,	0x00);
@@ -3520,6 +3575,7 @@ static int ov519_mode_init_regs(struct s
 	sd->clockdiv = 0;
 	switch (sd->sensor) {
 	case SEN_OV7640:
+	case SEN_OV7648:
 		switch (sd->frame_rate) {
 		default:
 /*		case 30: */
@@ -3649,6 +3705,7 @@ static int mode_init_ov_sensor_regs(stru
 		i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
 		break;
 	case SEN_OV7620:
+	case SEN_OV7620AE:
 	case SEN_OV76BE:
 		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
 		i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
@@ -3663,13 +3720,16 @@ static int mode_init_ov_sensor_regs(stru
 			i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
 		break;
 	case SEN_OV7640:
+	case SEN_OV7648:
 		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
 		i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
-/*		i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); */
-/*		i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); */
-/*		i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */
-/*		i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */
-/*		i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */
+		/* Setting this undocumented bit in qvga mode removes a very
+		   annoying vertical shaking of the image */
+		i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
+		/* Unknown */
+		i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
+		/* Allow higher automatic gain (to allow higher framerates) */
+		i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
 		i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
 		break;
 	case SEN_OV7670:
@@ -3795,11 +3855,13 @@ static int set_ov_sensor_window(struct s
 		}
 		break;
 	case SEN_OV7620:
+	case SEN_OV7620AE:
 		hwsbase = 0x2f;		/* From 7620.SET (spec is wrong) */
 		hwebase = 0x2f;
 		vwsbase = vwebase = 0x05;
 		break;
 	case SEN_OV7640:
+	case SEN_OV7648:
 		hwsbase = 0x1a;
 		hwebase = 0x1a;
 		vwsbase = vwebase = 0x03;
@@ -3893,6 +3955,12 @@ static int sd_start(struct gspca_dev *gs
 	setautobrightness(sd);
 	setfreq(sd);
 
+	/* Force clear snapshot state in case the snapshot button was
+	   pressed while we weren't streaming */
+	sd->snapshot_needs_reset = 1;
+	sd_reset_snapshot(gspca_dev);
+	sd->snapshot_pressed = 0;
+
 	ret = ov51x_restart(sd);
 	if (ret < 0)
 		goto out;
@@ -3919,6 +3987,34 @@ static void sd_stop0(struct gspca_dev *g
 		w9968cf_stop0(sd);
 }
 
+static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->snapshot_pressed != state) {
+#ifdef CONFIG_INPUT
+		input_report_key(gspca_dev->input_dev, KEY_CAMERA, state);
+		input_sync(gspca_dev->input_dev);
+#endif
+		if (state)
+			sd->snapshot_needs_reset = 1;
+
+		sd->snapshot_pressed = state;
+	} else {
+		/* On the ov511 / ov519 we need to reset the button state
+		   multiple times, as resetting does not work as long as the
+		   button stays pressed */
+		switch (sd->bridge) {
+		case BRIDGE_OV511:
+		case BRIDGE_OV511PLUS:
+		case BRIDGE_OV519:
+			if (state)
+				sd->snapshot_needs_reset = 1;
+			break;
+		}
+	}
+}
+
 static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
 			u8 *in,			/* isoc packet */
 			int len)		/* iso packet length */
@@ -3940,6 +4036,7 @@ static void ov511_pkt_scan(struct gspca_
 	 */
 	if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) &&
 	    (in[8] & 0x08)) {
+		ov51x_handle_button(gspca_dev, (in[8] >> 2) & 1);
 		if (in[8] & 0x80) {
 			/* Frame end */
 			if ((in[9] + 1) * 8 != gspca_dev->width ||
@@ -3977,6 +4074,7 @@ static void ov518_pkt_scan(struct gspca_
 	/* A false positive here is likely, until OVT gives me
 	 * the definitive SOF/EOF format */
 	if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
+		ov51x_handle_button(gspca_dev, (data[6] >> 1) & 1);
 		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
 		sd->packet_nr = 0;
@@ -4024,6 +4122,9 @@ static void ov519_pkt_scan(struct gspca_
 	if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) {
 		switch (data[3]) {
 		case 0x50:		/* start of frame */
+			/* Don't check the button state here, as the state
+			   usually (always ?) changes at EOF and checking it
+			   here leads to unnecessary snapshot state resets. */
 #define HDRSZ 16
 			data += HDRSZ;
 			len -= HDRSZ;
@@ -4035,6 +4136,7 @@ static void ov519_pkt_scan(struct gspca_
 				gspca_dev->last_packet_type = DISCARD_PACKET;
 			return;
 		case 0x51:		/* end of frame */
+			ov51x_handle_button(gspca_dev, data[11] & 1);
 			if (data[9] != 0)
 				gspca_dev->last_packet_type = DISCARD_PACKET;
 			gspca_frame_add(gspca_dev, LAST_PACKET,
@@ -4103,9 +4205,11 @@ static void setbrightness(struct gspca_d
 	case SEN_OV6630:
 	case SEN_OV66308AF:
 	case SEN_OV7640:
+	case SEN_OV7648:
 		i2c_w(sd, OV7610_REG_BRT, val);
 		break;
 	case SEN_OV7620:
+	case SEN_OV7620AE:
 		/* 7620 doesn't like manual changes when in auto mode */
 		if (!sd->autobrightness)
 			i2c_w(sd, OV7610_REG_BRT, val);
@@ -4142,7 +4246,8 @@ static void setcontrast(struct gspca_dev
 		i2c_w(sd, 0x64, ctab[val >> 5]);
 		break;
 	    }
-	case SEN_OV7620: {
+	case SEN_OV7620:
+	case SEN_OV7620AE: {
 		static const __u8 ctab[] = {
 			0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
 			0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
@@ -4152,10 +4257,6 @@ static void setcontrast(struct gspca_dev
 		i2c_w(sd, 0x64, ctab[val >> 4]);
 		break;
 	    }
-	case SEN_OV7640:
-		/* Use gain control instead. */
-		i2c_w(sd, OV7610_REG_GAIN, val >> 2);
-		break;
 	case SEN_OV7670:
 		/* check that this isn't just the same as ov7610 */
 		i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
@@ -4179,6 +4280,7 @@ static void setcolors(struct gspca_dev *
 		i2c_w(sd, OV7610_REG_SAT, val);
 		break;
 	case SEN_OV7620:
+	case SEN_OV7620AE:
 		/* Use UV gamma control instead. Bits 0 & 7 are reserved. */
 /*		rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e);
 		if (rc < 0)
@@ -4186,6 +4288,7 @@ static void setcolors(struct gspca_dev *
 		i2c_w(sd, OV7610_REG_SAT, val);
 		break;
 	case SEN_OV7640:
+	case SEN_OV7648:
 		i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
 		break;
 	case SEN_OV7670:
@@ -4198,7 +4301,8 @@ static void setcolors(struct gspca_dev *
 
 static void setautobrightness(struct sd *sd)
 {
-	if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670 ||
+	if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 ||
+	    sd->sensor == SEN_OV7670 ||
 	    sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
 		return;
 
@@ -4475,9 +4579,13 @@ static const struct sd_desc sd_desc = {
 	.stopN = sd_stopN,
 	.stop0 = sd_stop0,
 	.pkt_scan = sd_pkt_scan,
+	.dq_callback = sd_reset_snapshot,
 	.querymenu = sd_querymenu,
 	.get_jcomp = sd_get_jcomp,
 	.set_jcomp = sd_set_jcomp,
+#ifdef CONFIG_INPUT
+	.other_input = 1,
+#endif
 };
 
 /* -- module initialisation -- */
@@ -4494,7 +4602,8 @@ static const __devinitdata struct usb_de
 	 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
 	{USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
-	{USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x054c, 0x0155),
+	 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
 	{USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
 	{USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
 	{USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/ov534_9.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/ov534_9.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/ov534_9.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/ov534_9.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1477 @@
+/*
+ * ov534-ov965x gspca driver
+ *
+ * Copyright (C) 2009-2010 Jean-Francois Moine http://moinejf.free.fr
+ * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
+ * Copyright (C) 2008 Jim Paris <jim@jtan.com>
+ *
+ * Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
+ * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
+ * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * 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 "ov534_9"
+
+#include "gspca.h"
+
+#define OV534_REG_ADDRESS	0xf1	/* sensor address */
+#define OV534_REG_SUBADDR	0xf2
+#define OV534_REG_WRITE		0xf3
+#define OV534_REG_READ		0xf4
+#define OV534_REG_OPERATION	0xf5
+#define OV534_REG_STATUS	0xf6
+
+#define OV534_OP_WRITE_3	0x37
+#define OV534_OP_WRITE_2	0x33
+#define OV534_OP_READ_2		0xf9
+
+#define CTRL_TIMEOUT 500
+
+MODULE_AUTHOR("Jean-Francois Moine <moinejf@free.fr>");
+MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+	struct gspca_dev gspca_dev;	/* !! must be the first item */
+	__u32 last_pts;
+	u8 last_fid;
+
+	u8 brightness;
+	u8 contrast;
+	u8 autogain;
+	u8 exposure;
+	s8 sharpness;
+	u8 satur;
+	u8 freq;
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
+
+static const struct ctrl sd_ctrls[] = {
+    {							/* 0 */
+	{
+		.id      = V4L2_CID_BRIGHTNESS,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Brightness",
+		.minimum = 0,
+		.maximum = 15,
+		.step    = 1,
+#define BRIGHTNESS_DEF 7
+		.default_value = BRIGHTNESS_DEF,
+	},
+	.set = sd_setbrightness,
+	.get = sd_getbrightness,
+    },
+    {							/* 1 */
+	{
+		.id      = V4L2_CID_CONTRAST,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Contrast",
+		.minimum = 0,
+		.maximum = 15,
+		.step    = 1,
+#define CONTRAST_DEF 3
+		.default_value = CONTRAST_DEF,
+	},
+	.set = sd_setcontrast,
+	.get = sd_getcontrast,
+    },
+    {							/* 2 */
+	{
+		.id      = V4L2_CID_AUTOGAIN,
+		.type    = V4L2_CTRL_TYPE_BOOLEAN,
+		.name    = "Autogain",
+		.minimum = 0,
+		.maximum = 1,
+		.step    = 1,
+#define AUTOGAIN_DEF 1
+		.default_value = AUTOGAIN_DEF,
+	},
+	.set = sd_setautogain,
+	.get = sd_getautogain,
+    },
+#define EXPO_IDX 3
+    {							/* 3 */
+	{
+		.id      = V4L2_CID_EXPOSURE,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Exposure",
+		.minimum = 0,
+		.maximum = 3,
+		.step    = 1,
+#define EXPO_DEF 0
+		.default_value = EXPO_DEF,
+	},
+	.set = sd_setexposure,
+	.get = sd_getexposure,
+    },
+    {							/* 4 */
+	{
+		.id      = V4L2_CID_SHARPNESS,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Sharpness",
+		.minimum = -1,		/* -1 = auto */
+		.maximum = 4,
+		.step    = 1,
+#define SHARPNESS_DEF -1
+		.default_value = SHARPNESS_DEF,
+	},
+	.set = sd_setsharpness,
+	.get = sd_getsharpness,
+    },
+    {							/* 5 */
+	{
+		.id      = V4L2_CID_SATURATION,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Saturation",
+		.minimum = 0,
+		.maximum = 4,
+		.step    = 1,
+#define SATUR_DEF 2
+		.default_value = SATUR_DEF,
+	},
+	.set = sd_setsatur,
+	.get = sd_getsatur,
+    },
+    {
+	{
+		.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
+		.type    = V4L2_CTRL_TYPE_MENU,
+		.name    = "Light frequency filter",
+		.minimum = 0,
+		.maximum = 2,	/* 0: 0, 1: 50Hz, 2:60Hz */
+		.step    = 1,
+#define FREQ_DEF 0
+		.default_value = FREQ_DEF,
+	},
+	.set = sd_setfreq,
+	.get = sd_getfreq,
+    },
+};
+
+static const struct v4l2_pix_format ov965x_mode[] = {
+#define QVGA_MODE 0
+	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240 * 3 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+#define VGA_MODE 1
+	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480 * 3 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+#define SVGA_MODE 2
+	{800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 800,
+		.sizeimage = 800 * 600 * 3 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+#define XGA_MODE 3
+	{1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 1024,
+		.sizeimage = 1024 * 768 * 3 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+#define SXGA_MODE 4
+	{1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 1280,
+		.sizeimage = 1280 * 1024 * 3 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+};
+
+static const u8 bridge_init[][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[][2] = {
+	{0x12, 0x80},	/* com7 - SSCB 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 - 15fps VGA YUYV */
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+	{0x14, 0x28},	/* com9 */
+	{0x16, 0x24},	/* reg16 */
+	{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},	/* exhch */
+	{0x2b, 0x00},	/* exhcl */
+	{0x2c, 0x08},	/* rbias */
+	{0x32, 0xff},	/* href */
+	{0x33, 0x00},	/* chlf */
+	{0x34, 0x3f},	/* aref1 */
+	{0x35, 0x00},	/* aref2 */
+	{0x36, 0xf8},	/* aref3 */
+	{0x38, 0x72},	/* adc2 */
+	{0x39, 0x57},	/* aref4 */
+	{0x3a, 0x80},	/* tslb - yuyv */
+	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
+	{0x3d, 0x99},	/* com13 */
+	{0x3f, 0xc1},	/* edge */
+	{0x40, 0xc0},	/* com15 */
+	{0x41, 0x40},	/* com16 */
+	{0x42, 0xc0},	/* com17 */
+	{0x43, 0x0a},	/* rsvd */
+	{0x44, 0xf0},
+	{0x45, 0x46},
+	{0x46, 0x62},
+	{0x47, 0x2a},
+	{0x48, 0x3c},
+	{0x4a, 0xfc},
+	{0x4b, 0xfc},
+	{0x4c, 0x7f},
+	{0x4d, 0x7f},
+	{0x4e, 0x7f},
+	{0x4f, 0x98},	/* matrix */
+	{0x50, 0x98},
+	{0x51, 0x00},
+	{0x52, 0x28},
+	{0x53, 0x70},
+	{0x54, 0x98},
+	{0x58, 0x1a},	/* matrix coef sign */
+	{0x59, 0x85},	/* AWB control */
+	{0x5a, 0xa9},
+	{0x5b, 0x64},
+	{0x5c, 0x84},
+	{0x5d, 0x53},
+	{0x5e, 0x0e},
+	{0x5f, 0xf0},	/* AWB blue limit */
+	{0x60, 0xf0},	/* AWB red limit */
+	{0x61, 0xf0},	/* AWB green limit */
+	{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},	/* dnsth */
+	{0x71, 0x78},
+	{0x72, 0x00},	/* poidx */
+	{0x73, 0x01},	/* pckdv */
+	{0x74, 0x3a},	/* xindx */
+	{0x75, 0x35},	/* yindx */
+	{0x76, 0x01},
+	{0x77, 0x02},
+	{0x7a, 0x12},	/* gamma curve */
+	{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},	/* com19 */
+	{0x14, 0x28},	/* com9 */
+	{0x90, 0x7d},
+	{0x91, 0x7b},
+	{0x9d, 0x03},	/* lcc6 */
+	{0x9e, 0x04},	/* lcc7 */
+	{0x9f, 0x7a},
+	{0xa0, 0x79},
+	{0xa1, 0x40},	/* aechm */
+	{0xa4, 0x50},	/* com21 */
+	{0xa5, 0x68},	/* com26 */
+	{0xa6, 0x4a},	/* AWB green */
+	{0xa8, 0xc1},	/* refa8 */
+	{0xa9, 0xef},	/* refa9 */
+	{0xaa, 0x92},
+	{0xab, 0x04},
+	{0xac, 0x80},	/* black level control */
+	{0xad, 0x80},
+	{0xae, 0x80},
+	{0xaf, 0x80},
+	{0xb2, 0xf2},
+	{0xb3, 0x20},
+	{0xb4, 0x20},	/* ctrlb4 */
+	{0xb5, 0x00},
+	{0xb6, 0xaf},
+	{0xbb, 0xae},
+	{0xbc, 0x7f},	/* ADC channel offsets */
+	{0xdb, 0x7f},
+	{0xbe, 0x7f},
+	{0xbf, 0x7f},
+	{0xc0, 0xe2},
+	{0xc1, 0xc0},
+	{0xc2, 0x01},
+	{0xc3, 0x4e},
+	{0xc6, 0x85},
+	{0xc7, 0x80},	/* com24 */
+	{0xc9, 0xe0},
+	{0xca, 0xe8},
+	{0xcb, 0xf0},
+	{0xcc, 0xd8},
+	{0xcd, 0xf1},
+	{0x4f, 0x98},	/* matrix */
+	{0x50, 0x98},
+	{0x51, 0x00},
+	{0x52, 0x28},
+	{0x53, 0x70},
+	{0x54, 0x98},
+	{0x58, 0x1a},
+	{0xff, 0x41},	/* read 41, write ff 00 */
+	{0x41, 0x40},	/* com16 */
+
+	{0xc5, 0x03},	/* 60 Hz banding filter */
+	{0x6a, 0x02},	/* 50 Hz banding filter */
+
+	{0x12, 0x62},	/* com7 - 30fps VGA YUV */
+	{0x36, 0xfa},	/* aref3 */
+	{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_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_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},	/* com17 */
+	{0x2d, 0x00},
+	{0xff, 0x42},	/* read 42, write ff 00 */
+	{0x42, 0xc1},	/* com17 */
+/* sharpness */
+	{0x3f, 0x01},
+	{0xff, 0x42},	/* read 42, write ff 00 */
+	{0x42, 0xc1},	/* com17 */
+/* saturation */
+	{0x4f, 0x98},	/* matrix */
+	{0x50, 0x98},
+	{0x51, 0x00},
+	{0x52, 0x28},
+	{0x53, 0x70},
+	{0x54, 0x98},
+	{0x58, 0x1a},
+	{0xff, 0x41},	/* read 41, write ff 00 */
+	{0x41, 0x40},	/* com16 */
+/* contrast */
+	{0x56, 0x40},
+/* brightness */
+	{0x55, 0x8f},
+/* expo */
+	{0x10, 0x25},	/* aech - exposure high bits */
+	{0xff, 0x13},	/* read 13, write ff 00 */
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+};
+
+static const u8 sensor_start_1_vga[][2] = {	/* same for qvga */
+	{0x12, 0x62},	/* com7 - 30fps VGA YUV */
+	{0x36, 0xfa},	/* aref3 */
+	{0x69, 0x0a},	/* hv */
+	{0x8c, 0x89},	/* com22 */
+	{0x14, 0x28},	/* com9 */
+	{0x3e, 0x0c},	/* com14 */
+	{0x41, 0x40},	/* com16 */
+	{0x72, 0x00},
+	{0x73, 0x00},
+	{0x74, 0x3a},
+	{0x75, 0x35},
+	{0x76, 0x01},
+	{0xc7, 0x80},	/* com24 */
+	{0x03, 0x12},	/* vref */
+	{0x17, 0x16},	/* hstart */
+	{0x18, 0x02},	/* hstop */
+	{0x19, 0x01},	/* vstrt */
+	{0x1a, 0x3d},	/* vstop */
+	{0x32, 0xff},	/* href */
+	{0xc0, 0xaa},
+};
+
+static const u8 sensor_start_1_svga[][2] = {
+	{0x12, 0x02},	/* com7 - YUYV - VGA 15 full resolution */
+	{0x36, 0xf8},	/* aref3 */
+	{0x69, 0x02},	/* hv */
+	{0x8c, 0x0d},	/* com22 */
+	{0x3e, 0x0c},	/* com14 */
+	{0x41, 0x40},	/* com16 */
+	{0x72, 0x00},
+	{0x73, 0x01},
+	{0x74, 0x3a},
+	{0x75, 0x35},
+	{0x76, 0x01},
+	{0xc7, 0x80},	/* com24 */
+	{0x03, 0x1b},	/* vref */
+	{0x17, 0x1d},	/* hstart */
+	{0x18, 0xbd},	/* hstop */
+	{0x19, 0x01},	/* vstrt */
+	{0x1a, 0x81},	/* vstop */
+	{0x32, 0xff},	/* href */
+	{0xc0, 0xe2},
+};
+
+static const u8 sensor_start_1_xga[][2] = {
+	{0x12, 0x02},	/* com7 */
+	{0x36, 0xf8},	/* aref3 */
+	{0x69, 0x02},	/* hv */
+	{0x8c, 0x89},	/* com22 */
+	{0x14, 0x28},	/* com9 */
+	{0x3e, 0x0c},	/* com14 */
+	{0x41, 0x40},	/* com16 */
+	{0x72, 0x00},
+	{0x73, 0x01},
+	{0x74, 0x3a},
+	{0x75, 0x35},
+	{0x76, 0x01},
+	{0xc7, 0x80},	/* com24 */
+	{0x03, 0x1b},	/* vref */
+	{0x17, 0x1d},	/* hstart */
+	{0x18, 0xbd},	/* hstop */
+	{0x19, 0x01},	/* vstrt */
+	{0x1a, 0x81},	/* vstop */
+	{0x32, 0xff},	/* href */
+	{0xc0, 0xe2},
+};
+
+static const u8 sensor_start_1_sxga[][2] = {
+	{0x12, 0x02},	/* com7 */
+	{0x36, 0xf8},	/* aref3 */
+	{0x69, 0x02},	/* hv */
+	{0x8c, 0x89},	/* com22 */
+	{0x14, 0x28},	/* com9 */
+	{0x3e, 0x0c},	/* com14 */
+	{0x41, 0x40},	/* com16 */
+	{0x72, 0x00},
+	{0x73, 0x01},
+	{0x74, 0x3a},
+	{0x75, 0x35},
+	{0x76, 0x01},
+	{0xc7, 0x80},	/* com24 */
+	{0x03, 0x1b},	/* vref */
+	{0x17, 0x1d},	/* hstart */
+	{0x18, 0x02},	/* hstop */
+	{0x19, 0x01},	/* vstrt */
+	{0x1a, 0x81},	/* vstop */
+	{0x32, 0xff},	/* href */
+	{0xc0, 0xe2},
+};
+
+static const u8 bridge_start_qvga[][2] = {
+	{0x94, 0xaa},
+	{0xf1, 0x60},
+	{0xe5, 0x04},
+	{0xc0, 0x50},
+	{0xc1, 0x3c},
+	{0x8c, 0x00},
+	{0x8d, 0x1c},
+	{0x34, 0x05},
+
+	{0xc2, 0x4c},
+	{0xc3, 0xf9},
+	{0xda, 0x00},
+	{0x50, 0x00},
+	{0x51, 0xa0},
+	{0x52, 0x78},
+	{0x53, 0x00},
+	{0x54, 0x00},
+	{0x55, 0x00},
+	{0x57, 0x00},
+	{0x5c, 0x00},
+	{0x5a, 0x50},
+	{0x5b, 0x3c},
+	{0x35, 0x02},
+	{0xd9, 0x10},
+	{0x94, 0x11},
+};
+
+static const u8 bridge_start_vga[][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 bridge_start_svga[][2] = {
+	{0x94, 0xaa},
+	{0xf1, 0x60},
+	{0xe5, 0x04},
+	{0xc0, 0xa0},
+	{0xc1, 0x80},
+	{0x8c, 0x00},
+	{0x8d, 0x1c},
+	{0x34, 0x05},
+	{0xc2, 0x4c},
+	{0xc3, 0xf9},
+	{0x50, 0x00},
+	{0x51, 0x40},
+	{0x52, 0x00},
+	{0x53, 0x00},
+	{0x54, 0x00},
+	{0x55, 0x88},
+	{0x57, 0x00},
+	{0x5c, 0x00},
+	{0x5a, 0xc8},
+	{0x5b, 0x96},
+	{0x35, 0x02},
+	{0xd9, 0x10},
+	{0xda, 0x00},
+	{0x94, 0x11},
+};
+
+static const u8 bridge_start_xga[][2] = {
+	{0x94, 0xaa},
+	{0xf1, 0x60},
+	{0xe5, 0x04},
+	{0xc0, 0xa0},
+	{0xc1, 0x80},
+	{0x8c, 0x00},
+	{0x8d, 0x1c},
+	{0x34, 0x05},
+	{0xc2, 0x4c},
+	{0xc3, 0xf9},
+	{0x50, 0x00},
+	{0x51, 0x40},
+	{0x52, 0x00},
+	{0x53, 0x00},
+	{0x54, 0x00},
+	{0x55, 0x88},
+	{0x57, 0x00},
+	{0x5c, 0x01},
+	{0x5a, 0x00},
+	{0x5b, 0xc0},
+	{0x35, 0x02},
+	{0xd9, 0x10},
+	{0xda, 0x01},
+	{0x94, 0x11},
+};
+
+static const u8 bridge_start_sxga[][2] = {
+	{0x94, 0xaa},
+	{0xf1, 0x60},
+	{0xe5, 0x04},
+	{0xc0, 0xa0},
+	{0xc1, 0x80},
+	{0x8c, 0x00},
+	{0x8d, 0x1c},
+	{0x34, 0x05},
+	{0xc2, 0x0c},
+	{0xc3, 0xf9},
+	{0xda, 0x00},
+	{0x35, 0x02},
+	{0xd9, 0x10},
+	{0x94, 0x11},
+};
+
+static const u8 sensor_start_2_qvga[][2] = {
+	{0x3b, 0xe4},	/* com11 - night mode 1/4 frame rate */
+	{0x1e, 0x04},	/* mvfp */
+	{0x13, 0xe0},	/* com8 */
+	{0x00, 0x00},
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+	{0x11, 0x01},	/* clkrc */
+	{0x6b, 0x5a},	/* dblv */
+	{0x6a, 0x02},	/* 50 Hz banding filter */
+	{0xc5, 0x03},	/* 60 Hz banding filter */
+	{0xa2, 0x96},	/* bd50 */
+	{0xa3, 0x7d},	/* bd60 */
+
+	{0xff, 0x13},	/* read 13, write ff 00 */
+	{0x13, 0xe7},
+	{0x3a, 0x80},	/* tslb - yuyv */
+};
+
+static const u8 sensor_start_2_vga[][2] = {
+	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
+	{0x1e, 0x04},	/* mvfp */
+	{0x13, 0xe0},	/* com8 */
+	{0x00, 0x00},
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+	{0x11, 0x03},	/* clkrc */
+	{0x6b, 0x5a},	/* dblv */
+	{0x6a, 0x05},	/* 50 Hz banding filter */
+	{0xc5, 0x07},	/* 60 Hz banding filter */
+	{0xa2, 0x4b},	/* bd50 */
+	{0xa3, 0x3e},	/* bd60 */
+
+	{0x2d, 0x00},	/* advfl */
+};
+
+static const u8 sensor_start_2_svga[][2] = {	/* same for xga */
+	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
+	{0x1e, 0x04},	/* mvfp */
+	{0x13, 0xe0},	/* com8 */
+	{0x00, 0x00},
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+	{0x11, 0x01},	/* clkrc */
+	{0x6b, 0x5a},	/* dblv */
+	{0x6a, 0x0c},	/* 50 Hz banding filter */
+	{0xc5, 0x0f},	/* 60 Hz banding filter */
+	{0xa2, 0x4e},	/* bd50 */
+	{0xa3, 0x41},	/* bd60 */
+};
+
+static const u8 sensor_start_2_sxga[][2] = {
+	{0x13, 0xe0},	/* com8 */
+	{0x00, 0x00},
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
+	{0x1e, 0x04},	/* mvfp */
+	{0x11, 0x01},	/* clkrc */
+	{0x6b, 0x5a},	/* dblv */
+	{0x6a, 0x0c},	/* 50 Hz banding filter */
+	{0xc5, 0x0f},	/* 60 Hz banding filter */
+	{0xa2, 0x4e},	/* bd50 */
+	{0xa3, 0x41},	/* bd60 */
+};
+
+static void reg_w_i(struct gspca_dev *gspca_dev, u16 reg, u8 val)
+{
+	struct usb_device *udev = gspca_dev->dev;
+	int ret;
+
+	if (gspca_dev->usb_err < 0)
+		return;
+	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, "reg_w failed %d", ret);
+		gspca_dev->usb_err = ret;
+	}
+}
+
+static void reg_w(struct gspca_dev *gspca_dev, u16 reg, u8 val)
+{
+	PDEBUG(D_USBO, "reg_w [%04x] = %02x", reg, val);
+	reg_w_i(gspca_dev, reg, val);
+}
+
+static u8 reg_r(struct gspca_dev *gspca_dev, u16 reg)
+{
+	struct usb_device *udev = gspca_dev->dev;
+	int ret;
+
+	if (gspca_dev->usb_err < 0)
+		return 0;
+	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_r [%04x] -> %02x", reg, gspca_dev->usb_buf[0]);
+	if (ret < 0) {
+		PDEBUG(D_ERR, "reg_r err %d", ret);
+		gspca_dev->usb_err = ret;
+	}
+	return gspca_dev->usb_buf[0];
+}
+
+static int sccb_check_status(struct gspca_dev *gspca_dev)
+{
+	u8 data;
+	int i;
+
+	for (i = 0; i < 5; i++) {
+		data = reg_r(gspca_dev, OV534_REG_STATUS);
+
+		switch (data) {
+		case 0x00:
+			return 1;
+		case 0x04:
+			return 0;
+		case 0x03:
+			break;
+		default:
+			PDEBUG(D_USBI|D_USBO,
+				"sccb status 0x%02x, attempt %d/5",
+				data, i + 1);
+		}
+	}
+	return 0;
+}
+
+static void sccb_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
+{
+	PDEBUG(D_USBO, "sccb_write [%02x] = %02x", reg, val);
+	reg_w_i(gspca_dev, OV534_REG_SUBADDR, reg);
+	reg_w_i(gspca_dev, OV534_REG_WRITE, val);
+	reg_w_i(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
+
+	if (!sccb_check_status(gspca_dev))
+		PDEBUG(D_ERR, "sccb_write failed");
+}
+
+static u8 sccb_read(struct gspca_dev *gspca_dev, u16 reg)
+{
+	reg_w(gspca_dev, OV534_REG_SUBADDR, reg);
+	reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
+	if (!sccb_check_status(gspca_dev))
+		PDEBUG(D_ERR, "sccb_read failed 1");
+
+	reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
+	if (!sccb_check_status(gspca_dev))
+		PDEBUG(D_ERR, "sccb_read failed 2");
+
+	return reg_r(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) {
+		reg_w(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_write(gspca_dev, (*data)[0], (*data)[1]);
+		} else {
+			sccb_read(gspca_dev, (*data)[1]);
+			sccb_write(gspca_dev, 0xff, 0x00);
+		}
+		data++;
+	}
+}
+
+/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
+ * (direction and output)? */
+static void set_led(struct gspca_dev *gspca_dev, int status)
+{
+	u8 data;
+
+	PDEBUG(D_CONF, "led status: %d", status);
+
+	data = reg_r(gspca_dev, 0x21);
+	data |= 0x80;
+	reg_w(gspca_dev, 0x21, data);
+
+	data = reg_r(gspca_dev, 0x23);
+	if (status)
+		data |= 0x80;
+	else
+		data &= ~0x80;
+
+	reg_w(gspca_dev, 0x23, data);
+
+	if (!status) {
+		data = reg_r(gspca_dev, 0x21);
+		data &= ~0x80;
+		reg_w(gspca_dev, 0x21, data);
+	}
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+	val = sd->brightness;
+	if (val < 8)
+		val = 15 - val;		/* f .. 8 */
+	else
+		val = val - 8;		/* 0 .. 7 */
+	sccb_write(gspca_dev, 0x55,	/* brtn - brightness adjustment */
+			0x0f | (val << 4));
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sccb_write(gspca_dev, 0x56,	/* cnst1 - contrast 1 ctrl coeff */
+			sd->contrast << 4);
+}
+
+static void setautogain(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+/*fixme: should adjust agc/awb/aec by different controls */
+	val = sd->autogain;
+	val = sccb_read(gspca_dev, 0x13);		/* com8 */
+	sccb_write(gspca_dev, 0xff, 0x00);
+	if (sd->autogain)
+		val |= 0x05;		/* agc & aec */
+	else
+		val &= 0xfa;
+	sccb_write(gspca_dev, 0x13, val);
+}
+
+static void setexposure(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+	static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
+
+	sccb_write(gspca_dev, 0x10,			/* aec[9:2] */
+			expo[sd->exposure]);
+
+	val = sccb_read(gspca_dev, 0x13);		/* com8 */
+	sccb_write(gspca_dev, 0xff, 0x00);
+	sccb_write(gspca_dev, 0x13, val);
+
+	val = sccb_read(gspca_dev, 0xa1);		/* aech */
+	sccb_write(gspca_dev, 0xff, 0x00);
+	sccb_write(gspca_dev, 0xa1, val & 0xe0);	/* aec[15:10] = 0 */
+}
+
+static void setsharpness(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s8 val;
+
+	val = sd->sharpness;
+	if (val < 0) {				/* auto */
+		val = sccb_read(gspca_dev, 0x42);	/* com17 */
+		sccb_write(gspca_dev, 0xff, 0x00);
+		sccb_write(gspca_dev, 0x42, val | 0x40);
+				/* Edge enhancement strength auto adjust */
+		return;
+	}
+	if (val != 0)
+		val = 1 << (val - 1);
+	sccb_write(gspca_dev, 0x3f,	/* edge - edge enhance. factor */
+			val);
+	val = sccb_read(gspca_dev, 0x42);		/* com17 */
+	sccb_write(gspca_dev, 0xff, 0x00);
+	sccb_write(gspca_dev, 0x42, val & 0xbf);
+}
+
+static void setsatur(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val1, val2, val3;
+	static const u8 matrix[5][2] = {
+		{0x14, 0x38},
+		{0x1e, 0x54},
+		{0x28, 0x70},
+		{0x32, 0x8c},
+		{0x48, 0x90}
+	};
+
+	val1 = matrix[sd->satur][0];
+	val2 = matrix[sd->satur][1];
+	val3 = val1 + val2;
+	sccb_write(gspca_dev, 0x4f, val3);	/* matrix coeff */
+	sccb_write(gspca_dev, 0x50, val3);
+	sccb_write(gspca_dev, 0x51, 0x00);
+	sccb_write(gspca_dev, 0x52, val1);
+	sccb_write(gspca_dev, 0x53, val2);
+	sccb_write(gspca_dev, 0x54, val3);
+	sccb_write(gspca_dev, 0x58, 0x1a);	/* mtxs - coeff signs */
+
+	val1 = sccb_read(gspca_dev, 0x41);	/* com16 */
+	sccb_write(gspca_dev, 0xff, 0x00);
+	sccb_write(gspca_dev, 0x41, val1);
+}
+
+static void setfreq(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+	val = sccb_read(gspca_dev, 0x13);		/* com8 */
+	sccb_write(gspca_dev, 0xff, 0x00);
+	if (sd->freq == 0) {
+		sccb_write(gspca_dev, 0x13, val & 0xdf);
+		return;
+	}
+	sccb_write(gspca_dev, 0x13, val | 0x20);
+
+	val = sccb_read(gspca_dev, 0x42);		/* com17 */
+	sccb_write(gspca_dev, 0xff, 0x00);
+	if (sd->freq == 1)
+		val |= 0x01;
+	else
+		val &= 0xfe;
+	sccb_write(gspca_dev, 0x42, val);
+}
+
+/* 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;
+
+	cam = &gspca_dev->cam;
+
+	cam->cam_mode = ov965x_mode;
+	cam->nmodes = ARRAY_SIZE(ov965x_mode);
+
+	sd->brightness = BRIGHTNESS_DEF;
+	sd->contrast = CONTRAST_DEF;
+#if AUTOGAIN_DEF != 0
+	sd->autogain = AUTOGAIN_DEF;
+	gspca_dev->ctrl_inac |= (1 << EXPO_IDX);
+#endif
+#if EXPO_DEF != 0
+	sd->exposure = EXPO_DEF;
+#endif
+#if SHARPNESS_DEF != 0
+	sd->sharpness = SHARPNESS_DEF;
+#endif
+	sd->satur = SATUR_DEF;
+	sd->freq = FREQ_DEF;
+
+	return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+	u16 sensor_id;
+
+	/* reset bridge */
+	reg_w(gspca_dev, 0xe7, 0x3a);
+	reg_w(gspca_dev, 0xe0, 0x08);
+	msleep(100);
+
+	/* initialize the sensor address */
+	reg_w(gspca_dev, OV534_REG_ADDRESS, 0x60);
+
+	/* reset sensor */
+	sccb_write(gspca_dev, 0x12, 0x80);
+	msleep(10);
+
+	/* probe the sensor */
+	sccb_read(gspca_dev, 0x0a);
+	sensor_id = sccb_read(gspca_dev, 0x0a) << 8;
+	sccb_read(gspca_dev, 0x0b);
+	sensor_id |= sccb_read(gspca_dev, 0x0b);
+	PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
+
+	/* initialize */
+	reg_w_array(gspca_dev, bridge_init,
+			ARRAY_SIZE(bridge_init));
+	sccb_w_array(gspca_dev, sensor_init,
+			ARRAY_SIZE(sensor_init));
+	reg_w_array(gspca_dev, bridge_init_2,
+			ARRAY_SIZE(bridge_init_2));
+	sccb_w_array(gspca_dev, sensor_init_2,
+			ARRAY_SIZE(sensor_init_2));
+	reg_w(gspca_dev, 0xe0, 0x00);
+	reg_w(gspca_dev, 0xe0, 0x01);
+	set_led(gspca_dev, 0);
+	reg_w(gspca_dev, 0xe0, 0x00);
+
+	return gspca_dev->usb_err;
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	switch (gspca_dev->curr_mode) {
+	case QVGA_MODE:			/* 320x240 */
+		sccb_w_array(gspca_dev, sensor_start_1_vga,
+				ARRAY_SIZE(sensor_start_1_vga));
+		reg_w_array(gspca_dev, bridge_start_qvga,
+				ARRAY_SIZE(bridge_start_qvga));
+		sccb_w_array(gspca_dev, sensor_start_2_qvga,
+				ARRAY_SIZE(sensor_start_2_qvga));
+		break;
+	case VGA_MODE:			/* 640x480 */
+		sccb_w_array(gspca_dev, sensor_start_1_vga,
+				ARRAY_SIZE(sensor_start_1_vga));
+		reg_w_array(gspca_dev, bridge_start_vga,
+				ARRAY_SIZE(bridge_start_vga));
+		sccb_w_array(gspca_dev, sensor_start_2_vga,
+				ARRAY_SIZE(sensor_start_2_vga));
+		break;
+	case SVGA_MODE:			/* 800x600 */
+		sccb_w_array(gspca_dev, sensor_start_1_svga,
+				ARRAY_SIZE(sensor_start_1_svga));
+		reg_w_array(gspca_dev, bridge_start_svga,
+				ARRAY_SIZE(bridge_start_svga));
+		sccb_w_array(gspca_dev, sensor_start_2_svga,
+				ARRAY_SIZE(sensor_start_2_svga));
+		break;
+	case XGA_MODE:			/* 1024x768 */
+		sccb_w_array(gspca_dev, sensor_start_1_xga,
+				ARRAY_SIZE(sensor_start_1_xga));
+		reg_w_array(gspca_dev, bridge_start_xga,
+				ARRAY_SIZE(bridge_start_xga));
+		sccb_w_array(gspca_dev, sensor_start_2_svga,
+				ARRAY_SIZE(sensor_start_2_svga));
+		break;
+	default:
+/*	case SXGA_MODE:			 * 1280x1024 */
+		sccb_w_array(gspca_dev, sensor_start_1_sxga,
+				ARRAY_SIZE(sensor_start_1_sxga));
+		reg_w_array(gspca_dev, bridge_start_sxga,
+				ARRAY_SIZE(bridge_start_sxga));
+		sccb_w_array(gspca_dev, sensor_start_2_sxga,
+				ARRAY_SIZE(sensor_start_2_sxga));
+		break;
+	}
+	setfreq(gspca_dev);
+	setautogain(gspca_dev);
+	setbrightness(gspca_dev);
+	setcontrast(gspca_dev);
+	setexposure(gspca_dev);
+	setsharpness(gspca_dev);
+	setsatur(gspca_dev);
+
+	reg_w(gspca_dev, 0xe0, 0x00);
+	reg_w(gspca_dev, 0xe0, 0x00);
+	set_led(gspca_dev, 1);
+	return gspca_dev->usb_err;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+	reg_w(gspca_dev, 0xe0, 0x01);
+	set_led(gspca_dev, 0);
+	reg_w(gspca_dev, 0xe0, 0x00);
+}
+
+/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
+#define UVC_STREAM_EOH	(1 << 7)
+#define UVC_STREAM_ERR	(1 << 6)
+#define UVC_STREAM_STI	(1 << 5)
+#define UVC_STREAM_RES	(1 << 4)
+#define UVC_STREAM_SCR	(1 << 3)
+#define UVC_STREAM_PTS	(1 << 2)
+#define UVC_STREAM_EOF	(1 << 1)
+#define UVC_STREAM_FID	(1 << 0)
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data, int len)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	__u32 this_pts;
+	u8 this_fid;
+	int remaining_len = len;
+
+	do {
+		len = min(remaining_len, 2040);
+
+		/* 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;
+		}
+
+		/* 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;
+
+		/* If PTS or FID has changed, start a new frame. */
+		if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
+			if (gspca_dev->last_packet_type == INTER_PACKET)
+				gspca_frame_add(gspca_dev, LAST_PACKET,
+						NULL, 0);
+			sd->last_pts = this_pts;
+			sd->last_fid = this_fid;
+			gspca_frame_add(gspca_dev, FIRST_PACKET,
+					data + 12, len - 12);
+		/* If this packet is marked as EOF, end the frame */
+		} else if (data[1] & UVC_STREAM_EOF) {
+			sd->last_pts = 0;
+			gspca_frame_add(gspca_dev, LAST_PACKET,
+					data + 12, len - 12);
+		} else {
+
+			/* Add the data from this payload */
+			gspca_frame_add(gspca_dev, INTER_PACKET,
+					data + 12, len - 12);
+		}
+
+		/* Done this payload */
+		goto scan_next;
+
+discard:
+		/* Discard data until a new frame starts. */
+		gspca_dev->last_packet_type = DISCARD_PACKET;
+
+scan_next:
+		remaining_len -= len;
+		data += len;
+	} while (remaining_len > 0);
+}
+
+/* controls */
+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)
+		setbrightness(gspca_dev);
+	return gspca_dev->usb_err;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->brightness;
+	return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->contrast = val;
+	if (gspca_dev->streaming)
+		setcontrast(gspca_dev);
+	return gspca_dev->usb_err;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->contrast;
+	return 0;
+}
+
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->autogain = val;
+
+	if (gspca_dev->streaming) {
+		if (val)
+			gspca_dev->ctrl_inac |= (1 << EXPO_IDX);
+		else
+			gspca_dev->ctrl_inac &= ~(1 << EXPO_IDX);
+		setautogain(gspca_dev);
+	}
+	return gspca_dev->usb_err;
+}
+
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->autogain;
+	return 0;
+}
+
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->exposure = val;
+	if (gspca_dev->streaming)
+		setexposure(gspca_dev);
+	return gspca_dev->usb_err;
+}
+
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->exposure;
+	return 0;
+}
+
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->sharpness = val;
+	if (gspca_dev->streaming)
+		setsharpness(gspca_dev);
+	return gspca_dev->usb_err;
+}
+
+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_setsatur(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->satur = val;
+	if (gspca_dev->streaming)
+		setsatur(gspca_dev);
+	return gspca_dev->usb_err;
+}
+
+static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->satur;
+	return 0;
+}
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->freq = val;
+	if (gspca_dev->streaming)
+		setfreq(gspca_dev);
+	return gspca_dev->usb_err;
+}
+
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->freq;
+	return 0;
+}
+
+static int sd_querymenu(struct gspca_dev *gspca_dev,
+			struct v4l2_querymenu *menu)
+{
+	switch (menu->id) {
+	case V4L2_CID_POWER_LINE_FREQUENCY:
+		switch (menu->index) {
+		case 0:		/* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
+			strcpy((char *) menu->name, "NoFliker");
+			return 0;
+		case 1:		/* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
+			strcpy((char *) menu->name, "50 Hz");
+			return 0;
+		case 2:		/* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+			strcpy((char *) menu->name, "60 Hz");
+			return 0;
+		}
+		break;
+	}
+	return -EINVAL;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+	.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,
+	.querymenu = sd_querymenu,
+};
+
+/* -- module initialisation -- */
+static const __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x06f8, 0x3003)},
+	{}
+};
+
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+				THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+	.name       = MODULE_NAME,
+	.id_table   = device_table,
+	.probe      = sd_probe,
+	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend    = gspca_suspend,
+	.resume     = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+	int ret;
+
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
+	PDEBUG(D_PROBE, "registered");
+	return 0;
+}
+
+static void __exit sd_mod_exit(void)
+{
+	usb_deregister(&sd_driver);
+	PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/ov534.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/ov534.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/ov534.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/ov534.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * ov534 gspca driver
+ * ov534-ov772x gspca driver
  *
  * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
  * Copyright (C) 2008 Jim Paris <jim@jtan.com>
@@ -68,12 +68,7 @@ struct sd {
 	s8 sharpness;
 	u8 hflip;
 	u8 vflip;
-	u8 satur;
-	u8 lightfreq;
 
-	u8 sensor;
-#define SENSOR_OV772X 0
-#define SENSOR_OV965X 1
 };
 
 /* V4L2 controls supported by the driver */
@@ -101,12 +96,8 @@ static int sd_setbrightness(struct gspca
 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
 
-static struct ctrl sd_ctrls_ov772x[] = {
+static const struct ctrl sd_ctrls[] = {
     {							/* 0 */
 	{
 		.id      = V4L2_CID_BRIGHTNESS,
@@ -115,8 +106,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
 		.minimum = 0,
 		.maximum = 255,
 		.step    = 1,
-#define BRIGHTNESS_77_DEF 20
-		.default_value = BRIGHTNESS_77_DEF,
+#define BRIGHTNESS_DEF 20
+		.default_value = BRIGHTNESS_DEF,
 	},
 	.set = sd_setbrightness,
 	.get = sd_getbrightness,
@@ -129,8 +120,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
 		.minimum = 0,
 		.maximum = 255,
 		.step    = 1,
-#define CONTRAST_77_DEF 37
-		.default_value = CONTRAST_77_DEF,
+#define CONTRAST_DEF 37
+		.default_value = CONTRAST_DEF,
 	},
 	.set = sd_setcontrast,
 	.get = sd_getcontrast,
@@ -157,8 +148,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
 	    .minimum = 0,
 	    .maximum = 255,
 	    .step    = 1,
-#define EXPO_77_DEF 120
-	    .default_value = EXPO_77_DEF,
+#define EXPO_DEF 120
+	    .default_value = EXPO_DEF,
 	},
 	.set = sd_setexposure,
 	.get = sd_getexposure,
@@ -213,13 +204,13 @@ static struct ctrl sd_ctrls_ov772x[] = {
 	    .minimum = 0,
 	    .maximum = 1,
 	    .step    = 1,
-#define AUTOGAIN_77_DEF 0
-	    .default_value = AUTOGAIN_77_DEF,
+#define AUTOGAIN_DEF 0
+	    .default_value = AUTOGAIN_DEF,
 	},
 	.set = sd_setautogain,
 	.get = sd_getautogain,
     },
-#define AWB_77_IDX 8
+#define AWB_IDX 8
     {							/* 8 */
 	{
 		.id      = V4L2_CID_AUTO_WHITE_BALANCE,
@@ -242,8 +233,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
 	    .minimum = 0,
 	    .maximum = 63,
 	    .step    = 1,
-#define SHARPNESS_77_DEF 0
-	    .default_value = SHARPNESS_77_DEF,
+#define SHARPNESS_DEF 0
+	    .default_value = SHARPNESS_DEF,
 	},
 	.set = sd_setsharpness,
 	.get = sd_getsharpness,
@@ -277,107 +268,6 @@ static struct ctrl sd_ctrls_ov772x[] = {
 	.get = sd_getvflip,
     },
 };
-static struct ctrl sd_ctrls_ov965x[] = {
-    {							/* 0 */
-	{
-		.id      = V4L2_CID_BRIGHTNESS,
-		.type    = V4L2_CTRL_TYPE_INTEGER,
-		.name    = "Brightness",
-		.minimum = 0,
-		.maximum = 15,
-		.step    = 1,
-#define BRIGHTNESS_96_DEF 7
-		.default_value = BRIGHTNESS_96_DEF,
-	},
-	.set = sd_setbrightness,
-	.get = sd_getbrightness,
-    },
-    {							/* 1 */
-	{
-		.id      = V4L2_CID_CONTRAST,
-		.type    = V4L2_CTRL_TYPE_INTEGER,
-		.name    = "Contrast",
-		.minimum = 0,
-		.maximum = 15,
-		.step    = 1,
-#define CONTRAST_96_DEF 3
-		.default_value = CONTRAST_96_DEF,
-	},
-	.set = sd_setcontrast,
-	.get = sd_getcontrast,
-    },
-    {							/* 2 */
-	{
-	    .id      = V4L2_CID_AUTOGAIN,
-	    .type    = V4L2_CTRL_TYPE_BOOLEAN,
-	    .name    = "Autogain",
-	    .minimum = 0,
-	    .maximum = 1,
-	    .step    = 1,
-#define AUTOGAIN_96_DEF 1
-	    .default_value = AUTOGAIN_96_DEF,
-	},
-	.set = sd_setautogain,
-	.get = sd_getautogain,
-    },
-#define EXPO_96_IDX 3
-    {							/* 3 */
-	{
-	    .id      = V4L2_CID_EXPOSURE,
-	    .type    = V4L2_CTRL_TYPE_INTEGER,
-	    .name    = "Exposure",
-	    .minimum = 0,
-	    .maximum = 3,
-	    .step    = 1,
-#define EXPO_96_DEF 0
-	    .default_value = EXPO_96_DEF,
-	},
-	.set = sd_setexposure,
-	.get = sd_getexposure,
-    },
-    {							/* 4 */
-	{
-	    .id      = V4L2_CID_SHARPNESS,
-	    .type    = V4L2_CTRL_TYPE_INTEGER,
-	    .name    = "Sharpness",
-	    .minimum = -1,		/* -1 = auto */
-	    .maximum = 4,
-	    .step    = 1,
-#define SHARPNESS_96_DEF -1
-	    .default_value = SHARPNESS_96_DEF,
-	},
-	.set = sd_setsharpness,
-	.get = sd_getsharpness,
-    },
-    {							/* 5 */
-	{
-		.id      = V4L2_CID_SATURATION,
-		.type    = V4L2_CTRL_TYPE_INTEGER,
-		.name    = "Saturation",
-		.minimum = 0,
-		.maximum = 4,
-		.step    = 1,
-#define SATUR_DEF 2
-		.default_value = SATUR_DEF,
-	},
-	.set = sd_setsatur,
-	.get = sd_getsatur,
-    },
-    {
-	{
-		.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
-		.type    = V4L2_CTRL_TYPE_MENU,
-		.name    = "Light frequency filter",
-		.minimum = 0,
-		.maximum = 2,	/* 0: 0, 1: 50Hz, 2:60Hz */
-		.step    = 1,
-#define FREQ_DEF 0
-		.default_value = FREQ_DEF,
-	},
-	.set = sd_setfreq,
-	.get = sd_getfreq,
-    },
-};
 
 static const struct v4l2_pix_format ov772x_mode[] = {
 	{320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
@@ -392,35 +282,21 @@ static const struct v4l2_pix_format ov77
 	 .priv = 0},
 };
 
-static const struct v4l2_pix_format ov965x_mode[] = {
-	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
-	 .bytesperline = 320,
-	 .sizeimage = 320 * 240 * 3 / 8 + 590,
-	 .colorspace = V4L2_COLORSPACE_JPEG,
-	 .priv = 4},
-	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
-	 .bytesperline = 640,
-	 .sizeimage = 640 * 480 * 3 / 8 + 590,
-	 .colorspace = V4L2_COLORSPACE_JPEG,
-	 .priv = 3},
-	{800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
-	 .bytesperline = 800,
-	 .sizeimage = 800 * 600 * 3 / 8 + 590,
-	 .colorspace = V4L2_COLORSPACE_JPEG,
-	 .priv = 2},
-	{1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
-	 .bytesperline = 1024,
-	 .sizeimage = 1024 * 768 * 3 / 8 + 590,
-	 .colorspace = V4L2_COLORSPACE_JPEG,
-	 .priv = 1},
-	{1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
-	 .bytesperline = 1280,
-	 .sizeimage = 1280 * 1024 * 3 / 8 + 590,
-	 .colorspace = V4L2_COLORSPACE_JPEG,
-	 .priv = 0},
+static const u8 qvga_rates[] = {125, 100, 75, 60, 50, 40, 30};
+static const u8 vga_rates[] = {60, 50, 40, 30, 15};
+
+static const struct framerates ov772x_framerates[] = {
+	{ /* 320x240 */
+		.rates = qvga_rates,
+		.nrates = ARRAY_SIZE(qvga_rates),
+	},
+	{ /* 640x480 */
+		.rates = vga_rates,
+		.nrates = ARRAY_SIZE(vga_rates),
+	},
 };
 
-static const u8 bridge_init_ov772x[][2] = {
+static const u8 bridge_init[][2] = {
 	{ 0xc2, 0x0c },
 	{ 0x88, 0xf8 },
 	{ 0xc3, 0x69 },
@@ -478,7 +354,7 @@ static const u8 bridge_init_ov772x[][2]
 	{ 0xc1, 0x3c },
 	{ 0xc2, 0x0c },
 };
-static const u8 sensor_init_ov772x[][2] = {
+static const u8 sensor_init[][2] = {
 	{ 0x12, 0x80 },
 	{ 0x11, 0x01 },
 /*fixme: better have a delay?*/
@@ -571,7 +447,7 @@ static const u8 sensor_init_ov772x[][2]
 	{ 0x8e, 0x00 },		/* De-noise threshold */
 	{ 0x0c, 0xd0 }
 };
-static const u8 bridge_start_ov772x_vga[][2] = {
+static const u8 bridge_start_vga[][2] = {
 	{0x1c, 0x00},
 	{0x1d, 0x40},
 	{0x1d, 0x02},
@@ -582,7 +458,7 @@ static const u8 bridge_start_ov772x_vga[
 	{0xc0, 0x50},
 	{0xc1, 0x3c},
 };
-static const u8 sensor_start_ov772x_vga[][2] = {
+static const u8 sensor_start_vga[][2] = {
 	{0x12, 0x00},
 	{0x17, 0x26},
 	{0x18, 0xa0},
@@ -592,7 +468,7 @@ static const u8 sensor_start_ov772x_vga[
 	{0x2c, 0xf0},
 	{0x65, 0x20},
 };
-static const u8 bridge_start_ov772x_qvga[][2] = {
+static const u8 bridge_start_qvga[][2] = {
 	{0x1c, 0x00},
 	{0x1d, 0x40},
 	{0x1d, 0x02},
@@ -603,7 +479,7 @@ static const u8 bridge_start_ov772x_qvga
 	{0xc0, 0x28},
 	{0xc1, 0x1e},
 };
-static const u8 sensor_start_ov772x_qvga[][2] = {
+static const u8 sensor_start_qvga[][2] = {
 	{0x12, 0x40},
 	{0x17, 0x3f},
 	{0x18, 0x50},
@@ -614,571 +490,6 @@ static const u8 sensor_start_ov772x_qvga
 	{0x65, 0x2f},
 };
 
-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 - SSCB 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 - 15fps VGA YUYV */
-	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
-	{0x14, 0x28},	/* com9 */
-	{0x16, 0x24},	/* reg16 */
-	{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},	/* exhch */
-	{0x2b, 0x00},	/* exhcl */
-	{0x2c, 0x08},	/* rbias */
-	{0x32, 0xff},	/* href */
-	{0x33, 0x00},	/* chlf */
-	{0x34, 0x3f},	/* aref1 */
-	{0x35, 0x00},	/* aref2 */
-	{0x36, 0xf8},	/* aref3 */
-	{0x38, 0x72},	/* adc2 */
-	{0x39, 0x57},	/* aref4 */
-	{0x3a, 0x80},	/* tslb - yuyv */
-	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
-	{0x3d, 0x99},	/* com13 */
-	{0x3f, 0xc1},	/* edge */
-	{0x40, 0xc0},	/* com15 */
-	{0x41, 0x40},	/* com16 */
-	{0x42, 0xc0},	/* com17 */
-	{0x43, 0x0a},	/* rsvd */
-	{0x44, 0xf0},
-	{0x45, 0x46},
-	{0x46, 0x62},
-	{0x47, 0x2a},
-	{0x48, 0x3c},
-	{0x4a, 0xfc},
-	{0x4b, 0xfc},
-	{0x4c, 0x7f},
-	{0x4d, 0x7f},
-	{0x4e, 0x7f},
-	{0x4f, 0x98},	/* matrix */
-	{0x50, 0x98},
-	{0x51, 0x00},
-	{0x52, 0x28},
-	{0x53, 0x70},
-	{0x54, 0x98},
-	{0x58, 0x1a},	/* matrix coef sign */
-	{0x59, 0x85},	/* AWB control */
-	{0x5a, 0xa9},
-	{0x5b, 0x64},
-	{0x5c, 0x84},
-	{0x5d, 0x53},
-	{0x5e, 0x0e},
-	{0x5f, 0xf0},	/* AWB blue limit */
-	{0x60, 0xf0},	/* AWB red limit */
-	{0x61, 0xf0},	/* AWB green limit */
-	{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},	/* dnsth */
-	{0x71, 0x78},
-	{0x72, 0x00},	/* poidx */
-	{0x73, 0x01},	/* pckdv */
-	{0x74, 0x3a},	/* xindx */
-	{0x75, 0x35},	/* yindx */
-	{0x76, 0x01},
-	{0x77, 0x02},
-	{0x7a, 0x12},	/* gamma curve */
-	{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},	/* com19 */
-	{0x14, 0x28},	/* com9 */
-	{0x90, 0x7d},
-	{0x91, 0x7b},
-	{0x9d, 0x03},	/* lcc6 */
-	{0x9e, 0x04},	/* lcc7 */
-	{0x9f, 0x7a},
-	{0xa0, 0x79},
-	{0xa1, 0x40},	/* aechm */
-	{0xa4, 0x50},	/* com21 */
-	{0xa5, 0x68},	/* com26 */
-	{0xa6, 0x4a},	/* AWB green */
-	{0xa8, 0xc1},	/* refa8 */
-	{0xa9, 0xef},	/* refa9 */
-	{0xaa, 0x92},
-	{0xab, 0x04},
-	{0xac, 0x80},	/* black level control */
-	{0xad, 0x80},
-	{0xae, 0x80},
-	{0xaf, 0x80},
-	{0xb2, 0xf2},
-	{0xb3, 0x20},
-	{0xb4, 0x20},	/* ctrlb4 */
-	{0xb5, 0x00},
-	{0xb6, 0xaf},
-	{0xbb, 0xae},
-	{0xbc, 0x7f},	/* ADC channel offsets */
-	{0xdb, 0x7f},
-	{0xbe, 0x7f},
-	{0xbf, 0x7f},
-	{0xc0, 0xe2},
-	{0xc1, 0xc0},
-	{0xc2, 0x01},
-	{0xc3, 0x4e},
-	{0xc6, 0x85},
-	{0xc7, 0x80},	/* com24 */
-	{0xc9, 0xe0},
-	{0xca, 0xe8},
-	{0xcb, 0xf0},
-	{0xcc, 0xd8},
-	{0xcd, 0xf1},
-	{0x4f, 0x98},	/* matrix */
-	{0x50, 0x98},
-	{0x51, 0x00},
-	{0x52, 0x28},
-	{0x53, 0x70},
-	{0x54, 0x98},
-	{0x58, 0x1a},
-	{0xff, 0x41},	/* read 41, write ff 00 */
-	{0x41, 0x40},	/* com16 */
-
-	{0xc5, 0x03},	/* 60 Hz banding filter */
-	{0x6a, 0x02},	/* 50 Hz banding filter */
-
-	{0x12, 0x62},	/* com7 - 30fps VGA YUV */
-	{0x36, 0xfa},	/* aref3 */
-	{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},	/* com17 */
-	{0x2d, 0x00},
-	{0xff, 0x42},	/* read 42, write ff 00 */
-	{0x42, 0xc1},	/* com17 */
-/* sharpness */
-	{0x3f, 0x01},
-	{0xff, 0x42},	/* read 42, write ff 00 */
-	{0x42, 0xc1},	/* com17 */
-/* saturation */
-	{0x4f, 0x98},	/* matrix */
-	{0x50, 0x98},
-	{0x51, 0x00},
-	{0x52, 0x28},
-	{0x53, 0x70},
-	{0x54, 0x98},
-	{0x58, 0x1a},
-	{0xff, 0x41},	/* read 41, write ff 00 */
-	{0x41, 0x40},	/* com16 */
-/* contrast */
-	{0x56, 0x40},
-/* brightness */
-	{0x55, 0x8f},
-/* expo */
-	{0x10, 0x25},	/* aech - exposure high bits */
-	{0xff, 0x13},	/* read 13, write ff 00 */
-	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
-};
-
-static const u8 sensor_start_ov965x_1_vga[][2] = {	/* same for qvga */
-	{0x12, 0x62},	/* com7 - 30fps VGA YUV */
-	{0x36, 0xfa},	/* aref3 */
-	{0x69, 0x0a},	/* hv */
-	{0x8c, 0x89},	/* com22 */
-	{0x14, 0x28},	/* com9 */
-	{0x3e, 0x0c},	/* com14 */
-	{0x41, 0x40},	/* com16 */
-	{0x72, 0x00},
-	{0x73, 0x00},
-	{0x74, 0x3a},
-	{0x75, 0x35},
-	{0x76, 0x01},
-	{0xc7, 0x80},	/* com24 */
-	{0x03, 0x12},	/* vref */
-	{0x17, 0x16},	/* hstart */
-	{0x18, 0x02},	/* hstop */
-	{0x19, 0x01},	/* vstrt */
-	{0x1a, 0x3d},	/* vstop */
-	{0x32, 0xff},	/* href */
-	{0xc0, 0xaa},
-};
-
-static const u8 sensor_start_ov965x_1_svga[][2] = {
-	{0x12, 0x02},	/* com7 - YUYV - VGA 15 full resolution */
-	{0x36, 0xf8},	/* aref3 */
-	{0x69, 0x02},	/* hv */
-	{0x8c, 0x0d},	/* com22 */
-	{0x3e, 0x0c},	/* com14 */
-	{0x41, 0x40},	/* com16 */
-	{0x72, 0x00},
-	{0x73, 0x01},
-	{0x74, 0x3a},
-	{0x75, 0x35},
-	{0x76, 0x01},
-	{0xc7, 0x80},	/* com24 */
-	{0x03, 0x1b},	/* vref */
-	{0x17, 0x1d},	/* hstart */
-	{0x18, 0xbd},	/* hstop */
-	{0x19, 0x01},	/* vstrt */
-	{0x1a, 0x81},	/* vstop */
-	{0x32, 0xff},	/* href */
-	{0xc0, 0xe2},
-};
-
-static const u8 sensor_start_ov965x_1_xga[][2] = {
-	{0x12, 0x02},	/* com7 */
-	{0x36, 0xf8},	/* aref3 */
-	{0x69, 0x02},	/* hv */
-	{0x8c, 0x89},	/* com22 */
-	{0x14, 0x28},	/* com9 */
-	{0x3e, 0x0c},	/* com14 */
-	{0x41, 0x40},	/* com16 */
-	{0x72, 0x00},
-	{0x73, 0x01},
-	{0x74, 0x3a},
-	{0x75, 0x35},
-	{0x76, 0x01},
-	{0xc7, 0x80},	/* com24 */
-	{0x03, 0x1b},	/* vref */
-	{0x17, 0x1d},	/* hstart */
-	{0x18, 0xbd},	/* hstop */
-	{0x19, 0x01},	/* vstrt */
-	{0x1a, 0x81},	/* vstop */
-	{0x32, 0xff},	/* href */
-	{0xc0, 0xe2},
-};
-
-static const u8 sensor_start_ov965x_1_sxga[][2] = {
-	{0x12, 0x02},	/* com7 */
-	{0x36, 0xf8},	/* aref3 */
-	{0x69, 0x02},	/* hv */
-	{0x8c, 0x89},	/* com22 */
-	{0x14, 0x28},	/* com9 */
-	{0x3e, 0x0c},	/* com14 */
-	{0x41, 0x40},	/* com16 */
-	{0x72, 0x00},
-	{0x73, 0x01},
-	{0x74, 0x3a},
-	{0x75, 0x35},
-	{0x76, 0x01},
-	{0xc7, 0x80},	/* com24 */
-	{0x03, 0x1b},	/* vref */
-	{0x17, 0x1d},	/* hstart */
-	{0x18, 0x02},	/* hstop */
-	{0x19, 0x01},	/* vstrt */
-	{0x1a, 0x81},	/* vstop */
-	{0x32, 0xff},	/* href */
-	{0xc0, 0xe2},
-};
-
-static const u8 bridge_start_ov965x_qvga[][2] = {
-	{0x94, 0xaa},
-	{0xf1, 0x60},
-	{0xe5, 0x04},
-	{0xc0, 0x50},
-	{0xc1, 0x3c},
-	{0x8c, 0x00},
-	{0x8d, 0x1c},
-	{0x34, 0x05},
-
-	{0xc2, 0x4c},
-	{0xc3, 0xf9},
-	{0xda, 0x00},
-	{0x50, 0x00},
-	{0x51, 0xa0},
-	{0x52, 0x78},
-	{0x53, 0x00},
-	{0x54, 0x00},
-	{0x55, 0x00},
-	{0x57, 0x00},
-	{0x5c, 0x00},
-	{0x5a, 0x50},
-	{0x5b, 0x3c},
-	{0x35, 0x02},
-	{0xd9, 0x10},
-	{0x94, 0x11},
-};
-
-static const u8 bridge_start_ov965x_vga[][2] = {
-	{0x94, 0xaa},
-	{0xf1, 0x60},
-	{0xe5, 0x04},
-	{0xc0, 0x50},
-	{0xc1, 0x3c},
-	{0x8c, 0x00},
-	{0x8d, 0x1c},
-	{0x34, 0x05},
-	{0xc2, 0x0c},
-	{0xc3, 0xf9},
-	{0xda, 0x01},
-	{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 bridge_start_ov965x_svga[][2] = {
-	{0x94, 0xaa},
-	{0xf1, 0x60},
-	{0xe5, 0x04},
-	{0xc0, 0xa0},
-	{0xc1, 0x80},
-	{0x8c, 0x00},
-	{0x8d, 0x1c},
-	{0x34, 0x05},
-	{0xc2, 0x4c},
-	{0xc3, 0xf9},
-	{0x50, 0x00},
-	{0x51, 0x40},
-	{0x52, 0x00},
-	{0x53, 0x00},
-	{0x54, 0x00},
-	{0x55, 0x88},
-	{0x57, 0x00},
-	{0x5c, 0x00},
-	{0x5a, 0xc8},
-	{0x5b, 0x96},
-	{0x35, 0x02},
-	{0xd9, 0x10},
-	{0xda, 0x00},
-	{0x94, 0x11},
-};
-
-static const u8 bridge_start_ov965x_xga[][2] = {
-	{0x94, 0xaa},
-	{0xf1, 0x60},
-	{0xe5, 0x04},
-	{0xc0, 0xa0},
-	{0xc1, 0x80},
-	{0x8c, 0x00},
-	{0x8d, 0x1c},
-	{0x34, 0x05},
-	{0xc2, 0x4c},
-	{0xc3, 0xf9},
-	{0x50, 0x00},
-	{0x51, 0x40},
-	{0x52, 0x00},
-	{0x53, 0x00},
-	{0x54, 0x00},
-	{0x55, 0x88},
-	{0x57, 0x00},
-	{0x5c, 0x01},
-	{0x5a, 0x00},
-	{0x5b, 0xc0},
-	{0x35, 0x02},
-	{0xd9, 0x10},
-	{0xda, 0x01},
-	{0x94, 0x11},
-};
-
-static const u8 bridge_start_ov965x_sxga[][2] = {
-	{0x94, 0xaa},
-	{0xf1, 0x60},
-	{0xe5, 0x04},
-	{0xc0, 0xa0},
-	{0xc1, 0x80},
-	{0x8c, 0x00},
-	{0x8d, 0x1c},
-	{0x34, 0x05},
-	{0xc2, 0x0c},
-	{0xc3, 0xf9},
-	{0xda, 0x00},
-	{0x35, 0x02},
-	{0xd9, 0x10},
-	{0x94, 0x11},
-};
-
-static const u8 sensor_start_ov965x_2_qvga[][2] = {
-	{0x3b, 0xe4},	/* com11 - night mode 1/4 frame rate */
-	{0x1e, 0x04},	/* mvfp */
-	{0x13, 0xe0},	/* com8 */
-	{0x00, 0x00},
-	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
-	{0x11, 0x01},	/* clkrc */
-	{0x6b, 0x5a},	/* dblv */
-	{0x6a, 0x02},	/* 50 Hz banding filter */
-	{0xc5, 0x03},	/* 60 Hz banding filter */
-	{0xa2, 0x96},	/* bd50 */
-	{0xa3, 0x7d},	/* bd60 */
-
-	{0xff, 0x13},	/* read 13, write ff 00 */
-	{0x13, 0xe7},
-	{0x3a, 0x80},	/* tslb - yuyv */
-};
-
-static const u8 sensor_start_ov965x_2_vga[][2] = {
-	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
-	{0x1e, 0x04},	/* mvfp */
-	{0x13, 0xe0},	/* com8 */
-	{0x00, 0x00},
-	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
-	{0x11, 0x03},	/* clkrc */
-	{0x6b, 0x5a},	/* dblv */
-	{0x6a, 0x05},	/* 50 Hz banding filter */
-	{0xc5, 0x07},	/* 60 Hz banding filter */
-	{0xa2, 0x4b},	/* bd50 */
-	{0xa3, 0x3e},	/* bd60 */
-
-	{0x2d, 0x00},	/* advfl */
-};
-
-static const u8 sensor_start_ov965x_2_svga[][2] = {	/* same for xga */
-	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
-	{0x1e, 0x04},	/* mvfp */
-	{0x13, 0xe0},	/* com8 */
-	{0x00, 0x00},
-	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
-	{0x11, 0x01},	/* clkrc */
-	{0x6b, 0x5a},	/* dblv */
-	{0x6a, 0x0c},	/* 50 Hz banding filter */
-	{0xc5, 0x0f},	/* 60 Hz banding filter */
-	{0xa2, 0x4e},	/* bd50 */
-	{0xa3, 0x41},	/* bd60 */
-};
-
-static const u8 sensor_start_ov965x_2_sxga[][2] = {
-	{0x13, 0xe0},	/* com8 */
-	{0x00, 0x00},
-	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
-	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
-	{0x1e, 0x04},	/* mvfp */
-	{0x11, 0x01},	/* clkrc */
-	{0x6b, 0x5a},	/* dblv */
-	{0x6a, 0x0c},	/* 50 Hz banding filter */
-	{0xc5, 0x0f},	/* 60 Hz banding filter */
-	{0xa2, 0x4e},	/* bd50 */
-	{0xa3, 0x41},	/* bd60 */
-};
-
 static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
 {
 	struct usb_device *udev = gspca_dev->dev;
@@ -1360,14 +671,14 @@ static void set_frame_rate(struct gspca_
 	PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
 }
 
-static void setbrightness_77(struct gspca_dev *gspca_dev)
+static void setbrightness(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	sccb_reg_write(gspca_dev, 0x9B, sd->brightness);
 }
 
-static void setcontrast_77(struct gspca_dev *gspca_dev)
+static void setcontrast(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
@@ -1401,7 +712,7 @@ static void setgain(struct gspca_dev *gs
 	sccb_reg_write(gspca_dev, 0x00, val);
 }
 
-static void setexposure_77(struct gspca_dev *gspca_dev)
+static void setexposure(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 val;
@@ -1432,7 +743,7 @@ static void sethue(struct gspca_dev *gsp
 	sccb_reg_write(gspca_dev, 0x01, sd->hue);
 }
 
-static void setautogain_77(struct gspca_dev *gspca_dev)
+static void setautogain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
@@ -1457,7 +768,7 @@ static void setawb(struct gspca_dev *gsp
 		sccb_reg_write(gspca_dev, 0x63, 0xaa);	/* AWB off */
 }
 
-static void setsharpness_77(struct gspca_dev *gspca_dev)
+static void setsharpness(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 val;
@@ -1491,132 +802,6 @@ static void setvflip(struct gspca_dev *g
 				sccb_reg_read(gspca_dev, 0x0c) & 0x7f);
 }
 
-/* ov965x specific controls */
-static void setbrightness_96(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	u8 val;
-
-	val = sd->brightness;
-	if (val < 8)
-		val = 15 - val;		/* f .. 8 */
-	else
-		val = val - 8;		/* 0 .. 7 */
-	sccb_reg_write(gspca_dev, 0x55,	/* brtn - brightness adjustment */
-			0x0f | (val << 4));
-}
-
-static void setcontrast_96(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sccb_reg_write(gspca_dev, 0x56,	/* cnst1 - contrast 1 ctrl coeff */
-			sd->contrast << 4);
-}
-
-static void setexposure_96(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	u8 val;
-	static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
-
-	sccb_reg_write(gspca_dev, 0x10,			/* aec[9:2] */
-			expo[sd->exposure]);
-	val = sccb_reg_read(gspca_dev, 0x13);		/* com8 */
-	sccb_reg_write(gspca_dev, 0xff, 0x00);
-	sccb_reg_write(gspca_dev, 0x13, val);
-	val = sccb_reg_read(gspca_dev, 0xa1);		/* aech */
-	sccb_reg_write(gspca_dev, 0xff, 0x00);
-	sccb_reg_write(gspca_dev, 0xa1, val & 0xe0);	/* aec[15:10] = 0 */
-}
-
-static void setsharpness_96(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	s8 val;
-
-	val = sd->sharpness;
-	if (val < 0) {				/* auto */
-		val = sccb_reg_read(gspca_dev, 0x42);	/* com17 */
-		sccb_reg_write(gspca_dev, 0xff, 0x00);
-		sccb_reg_write(gspca_dev, 0x42, val | 0x40);
-				/* Edge enhancement strength auto adjust */
-		return;
-	}
-	if (val != 0)
-		val = 1 << (val - 1);
-	sccb_reg_write(gspca_dev, 0x3f,	/* edge - edge enhance. factor */
-			val);
-	val = sccb_reg_read(gspca_dev, 0x42);		/* com17 */
-	sccb_reg_write(gspca_dev, 0xff, 0x00);
-	sccb_reg_write(gspca_dev, 0x42, val & 0xbf);
-}
-
-static void setautogain_96(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	u8 val;
-
-/*fixme: should adjust agc/awb/aec by different controls */
-	val = sd->autogain;
-	val = sccb_reg_read(gspca_dev, 0x13);		/* com8 */
-	sccb_reg_write(gspca_dev, 0xff, 0x00);
-	if (sd->autogain)
-		val |= 0x05;		/* agc & aec */
-	else
-		val &= 0xfa;
-	sccb_reg_write(gspca_dev, 0x13, val);
-}
-
-static void setsatur(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	u8 val1, val2, val3;
-	static const u8 matrix[5][2] = {
-		{0x14, 0x38},
-		{0x1e, 0x54},
-		{0x28, 0x70},
-		{0x32, 0x8c},
-		{0x48, 0x90}
-	};
-
-	val1 = matrix[sd->satur][0];
-	val2 = matrix[sd->satur][1];
-	val3 = val1 + val2;
-	sccb_reg_write(gspca_dev, 0x4f, val3);	/* matrix coeff */
-	sccb_reg_write(gspca_dev, 0x50, val3);
-	sccb_reg_write(gspca_dev, 0x51, 0x00);
-	sccb_reg_write(gspca_dev, 0x52, val1);
-	sccb_reg_write(gspca_dev, 0x53, val2);
-	sccb_reg_write(gspca_dev, 0x54, val3);
-	sccb_reg_write(gspca_dev, 0x58, 0x1a);	/* mtxs - coeff signs */
-	val1 = sccb_reg_read(gspca_dev, 0x41);	/* com16 */
-	sccb_reg_write(gspca_dev, 0xff, 0x00);
-	sccb_reg_write(gspca_dev, 0x41, val1);
-}
-
-static void setfreq(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	u8 val;
-
-	val = sccb_reg_read(gspca_dev, 0x13);		/* com8 */
-	sccb_reg_write(gspca_dev, 0xff, 0x00);
-	if (sd->lightfreq == 0) {
-		sccb_reg_write(gspca_dev, 0x13, val & 0xdf);
-		return;
-	}
-	sccb_reg_write(gspca_dev, 0x13, val | 0x20);
-
-	val = sccb_reg_read(gspca_dev, 0x42);		/* com17 */
-	sccb_reg_write(gspca_dev, 0xff, 0x00);
-	if (sd->lightfreq == 1)
-		val |= 0x01;
-	else
-		val &= 0xfe;
-	sccb_reg_write(gspca_dev, 0x42, val);
-}
-
 /* this function is called at probe time */
 static int sd_config(struct gspca_dev *gspca_dev,
 		     const struct usb_device_id *id)
@@ -1624,77 +809,50 @@ static int sd_config(struct gspca_dev *g
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
 
-	sd->sensor = id->driver_info;
-
 	cam = &gspca_dev->cam;
 
-	if (sd->sensor == SENSOR_OV772X) {
-		cam->cam_mode = ov772x_mode;
-		cam->nmodes = ARRAY_SIZE(ov772x_mode);
+	cam->cam_mode = ov772x_mode;
+	cam->nmodes = ARRAY_SIZE(ov772x_mode);
+	cam->mode_framerates = ov772x_framerates;
 
-		cam->bulk = 1;
-		cam->bulk_size = 16384;
-		cam->bulk_nurbs = 2;
-	} else {		/* ov965x */
-		cam->cam_mode = ov965x_mode;
-		cam->nmodes = ARRAY_SIZE(ov965x_mode);
-	}
+	cam->bulk = 1;
+	cam->bulk_size = 16384;
+	cam->bulk_nurbs = 2;
 
 	sd->frame_rate = 30;
 
-	if (sd->sensor == SENSOR_OV772X) {
-		sd->brightness = BRIGHTNESS_77_DEF;
-		sd->contrast = CONTRAST_77_DEF;
-		sd->gain = GAIN_DEF;
-		sd->exposure = EXPO_77_DEF;
-		sd->redblc = RED_BALANCE_DEF;
-		sd->blueblc = BLUE_BALANCE_DEF;
-		sd->hue = HUE_DEF;
-#if AUTOGAIN_77_DEF != 0
-		sd->autogain = AUTOGAIN_77_DEF;
+	sd->brightness = BRIGHTNESS_DEF;
+	sd->contrast = CONTRAST_DEF;
+	sd->gain = GAIN_DEF;
+	sd->exposure = EXPO_DEF;
+	sd->redblc = RED_BALANCE_DEF;
+	sd->blueblc = BLUE_BALANCE_DEF;
+	sd->hue = HUE_DEF;
+#if AUTOGAIN_DEF != 0
+	sd->autogain = AUTOGAIN_DEF;
 #else
-		gspca_dev->ctrl_inac |= (1 << AWB_77_IDX);
+	gspca_dev->ctrl_inac |= (1 << AWB_IDX);
 #endif
 #if AWB_DEF != 0
-		sd->awb = AWB_DEF
+	sd->awb = AWB_DEF
 #endif
-#if SHARPNESS_77_DEF != 0
-		sd->sharpness = SHARPNESS_77_DEF;
+#if SHARPNESS_DEF != 0
+	sd->sharpness = SHARPNESS_DEF;
 #endif
 #if HFLIP_DEF != 0
-		sd->hflip = HFLIP_DEF;
+	sd->hflip = HFLIP_DEF;
 #endif
 #if VFLIP_DEF != 0
-		sd->vflip = VFLIP_DEF;
-#endif
-	} else {
-		sd->brightness = BRIGHTNESS_96_DEF;
-		sd->contrast = CONTRAST_96_DEF;
-#if AUTOGAIN_96_DEF != 0
-		sd->autogain = AUTOGAIN_96_DEF;
-		gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
-#endif
-#if EXPO_96_DEF != 0
-		sd->exposure = EXPO_96_DEF;
-#endif
-#if SHARPNESS_96_DEF != 0
-		sd->sharpness = SHARPNESS_96_DEF;
+	sd->vflip = VFLIP_DEF;
 #endif
-		sd->satur = SATUR_DEF;
-		sd->lightfreq = FREQ_DEF;
-	}
+
 	return 0;
 }
 
 /* this function is called at probe and resume time */
 static int sd_init(struct gspca_dev *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);
@@ -1702,8 +860,7 @@ static int sd_init(struct gspca_dev *gsp
 	msleep(100);
 
 	/* initialize the sensor address */
-	ov534_reg_write(gspca_dev, OV534_REG_ADDRESS,
-				sensor_addr[sd->sensor]);
+	ov534_reg_write(gspca_dev, OV534_REG_ADDRESS, 0x42);
 
 	/* reset sensor */
 	sccb_reg_write(gspca_dev, 0x12, 0x80);
@@ -1717,64 +874,46 @@ static int sd_init(struct gspca_dev *gsp
 	PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
 
 	/* initialize */
-	switch (sd->sensor) {
-	case SENSOR_OV772X:
-		reg_w_array(gspca_dev, bridge_init_ov772x,
-				ARRAY_SIZE(bridge_init_ov772x));
-		ov534_set_led(gspca_dev, 1);
-		sccb_w_array(gspca_dev, sensor_init_ov772x,
-				ARRAY_SIZE(sensor_init_ov772x));
-		ov534_reg_write(gspca_dev, 0xe0, 0x09);
-		ov534_set_led(gspca_dev, 0);
-		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);
-	}
+	reg_w_array(gspca_dev, bridge_init,
+			ARRAY_SIZE(bridge_init));
+	ov534_set_led(gspca_dev, 1);
+	sccb_w_array(gspca_dev, sensor_init,
+			ARRAY_SIZE(sensor_init));
+	ov534_reg_write(gspca_dev, 0xe0, 0x09);
+	ov534_set_led(gspca_dev, 0);
+	set_frame_rate(gspca_dev);
 
 	return 0;
 }
 
-static int sd_start_ov772x(struct gspca_dev *gspca_dev)
+static int sd_start(struct gspca_dev *gspca_dev)
 {
 	int mode;
 
 	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
 	if (mode != 0) {	/* 320x240 */
-		reg_w_array(gspca_dev, bridge_start_ov772x_qvga,
-				ARRAY_SIZE(bridge_start_ov772x_qvga));
-		sccb_w_array(gspca_dev, sensor_start_ov772x_qvga,
-				ARRAY_SIZE(sensor_start_ov772x_qvga));
+		reg_w_array(gspca_dev, bridge_start_qvga,
+				ARRAY_SIZE(bridge_start_qvga));
+		sccb_w_array(gspca_dev, sensor_start_qvga,
+				ARRAY_SIZE(sensor_start_qvga));
 	} else {		/* 640x480 */
-		reg_w_array(gspca_dev, bridge_start_ov772x_vga,
-				ARRAY_SIZE(bridge_start_ov772x_vga));
-		sccb_w_array(gspca_dev, sensor_start_ov772x_vga,
-				ARRAY_SIZE(sensor_start_ov772x_vga));
+		reg_w_array(gspca_dev, bridge_start_vga,
+				ARRAY_SIZE(bridge_start_vga));
+		sccb_w_array(gspca_dev, sensor_start_vga,
+				ARRAY_SIZE(sensor_start_vga));
 	}
 	set_frame_rate(gspca_dev);
 
-	setautogain_77(gspca_dev);
+	setautogain(gspca_dev);
 	setawb(gspca_dev);
 	setgain(gspca_dev);
 	setredblc(gspca_dev);
 	setblueblc(gspca_dev);
 	sethue(gspca_dev);
-	setexposure_77(gspca_dev);
-	setbrightness_77(gspca_dev);
-	setcontrast_77(gspca_dev);
-	setsharpness_77(gspca_dev);
+	setexposure(gspca_dev);
+	setbrightness(gspca_dev);
+	setcontrast(gspca_dev);
+	setsharpness(gspca_dev);
 	setvflip(gspca_dev);
 	sethflip(gspca_dev);
 
@@ -1783,81 +922,12 @@ static int sd_start_ov772x(struct gspca_
 	return 0;
 }
 
-static int sd_start_ov965x(struct gspca_dev *gspca_dev)
-{
-	int mode;
-
-	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
-	switch (mode) {
-	default:
-/*	case 4:			 * 320x240 */
-		sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
-				ARRAY_SIZE(sensor_start_ov965x_1_vga));
-		reg_w_array(gspca_dev, bridge_start_ov965x_qvga,
-				ARRAY_SIZE(bridge_start_ov965x_qvga));
-		sccb_w_array(gspca_dev, sensor_start_ov965x_2_qvga,
-				ARRAY_SIZE(sensor_start_ov965x_2_qvga));
-		break;
-	case 3:			/* 640x480 */
-		sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
-				ARRAY_SIZE(sensor_start_ov965x_1_vga));
-		reg_w_array(gspca_dev, bridge_start_ov965x_vga,
-				ARRAY_SIZE(bridge_start_ov965x_vga));
-		sccb_w_array(gspca_dev, sensor_start_ov965x_2_vga,
-				ARRAY_SIZE(sensor_start_ov965x_2_vga));
-		break;
-	case 2:			/* 800x600 */
-		sccb_w_array(gspca_dev, sensor_start_ov965x_1_svga,
-				ARRAY_SIZE(sensor_start_ov965x_1_svga));
-		reg_w_array(gspca_dev, bridge_start_ov965x_svga,
-				ARRAY_SIZE(bridge_start_ov965x_svga));
-		sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga,
-				ARRAY_SIZE(sensor_start_ov965x_2_svga));
-		break;
-	case 1:			/* 1024x768 */
-		sccb_w_array(gspca_dev, sensor_start_ov965x_1_xga,
-				ARRAY_SIZE(sensor_start_ov965x_1_xga));
-		reg_w_array(gspca_dev, bridge_start_ov965x_xga,
-				ARRAY_SIZE(bridge_start_ov965x_xga));
-		sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga,
-				ARRAY_SIZE(sensor_start_ov965x_2_svga));
-		break;
-	case 0:			/* 1280x1024 */
-		sccb_w_array(gspca_dev, sensor_start_ov965x_1_sxga,
-				ARRAY_SIZE(sensor_start_ov965x_1_sxga));
-		reg_w_array(gspca_dev, bridge_start_ov965x_sxga,
-				ARRAY_SIZE(bridge_start_ov965x_sxga));
-		sccb_w_array(gspca_dev, sensor_start_ov965x_2_sxga,
-				ARRAY_SIZE(sensor_start_ov965x_2_sxga));
-		break;
-	}
-	setfreq(gspca_dev);
-	setautogain_96(gspca_dev);
-	setbrightness_96(gspca_dev);
-	setcontrast_96(gspca_dev);
-	setexposure_96(gspca_dev);
-	setsharpness_96(gspca_dev);
-	setsatur(gspca_dev);
-
-	ov534_reg_write(gspca_dev, 0xe0, 0x00);
-	ov534_reg_write(gspca_dev, 0xe0, 0x00);
-	ov534_set_led(gspca_dev, 1);
-	return 0;
-}
-
-static void sd_stopN_ov772x(struct gspca_dev *gspca_dev)
+static void sd_stopN(struct gspca_dev *gspca_dev)
 {
 	ov534_reg_write(gspca_dev, 0xe0, 0x09);
 	ov534_set_led(gspca_dev, 0);
 }
 
-static void sd_stopN_ov965x(struct gspca_dev *gspca_dev)
-{
-	ov534_reg_write(gspca_dev, 0xe0, 0x01);
-	ov534_set_led(gspca_dev, 0);
-	ov534_reg_write(gspca_dev, 0xe0, 0x00);
-}
-
 /* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
 #define UVC_STREAM_EOH	(1 << 7)
 #define UVC_STREAM_ERR	(1 << 6)
@@ -1875,11 +945,9 @@ static void sd_pkt_scan(struct gspca_dev
 	__u32 this_pts;
 	u16 this_fid;
 	int remaining_len = len;
-	int payload_len;
 
-	payload_len = gspca_dev->cam.bulk ? 2048 : 2040;
 	do {
-		len = min(remaining_len, payload_len);
+		len = min(remaining_len, 2048);
 
 		/* Payloads are prefixed with a UVC-style header.  We
 		   consider a frame to start when the FID toggles, or the PTS
@@ -1918,7 +986,17 @@ static void sd_pkt_scan(struct gspca_dev
 					data + 12, len - 12);
 		/* If this packet is marked as EOF, end the frame */
 		} else if (data[1] & UVC_STREAM_EOF) {
+			struct gspca_frame *frame;
+
 			sd->last_pts = 0;
+			frame = gspca_get_i_frame(gspca_dev);
+			if (frame == NULL)
+				goto discard;
+			if (frame->data_end - frame->data + (len - 12) !=
+			    gspca_dev->width * gspca_dev->height * 2) {
+				PDEBUG(D_PACK, "wrong sized frame");
+				goto discard;
+			}
 			gspca_frame_add(gspca_dev, LAST_PACKET,
 					data + 12, len - 12);
 		} else {
@@ -1965,12 +1043,8 @@ static int sd_setexposure(struct gspca_d
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	sd->exposure = val;
-	if (gspca_dev->streaming) {
-		if (sd->sensor == SENSOR_OV772X)
-			setexposure_77(gspca_dev);
-		else
-			setexposure_96(gspca_dev);
-	}
+	if (gspca_dev->streaming)
+		setexposure(gspca_dev);
 	return 0;
 }
 
@@ -1987,12 +1061,8 @@ static int sd_setbrightness(struct gspca
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	sd->brightness = val;
-	if (gspca_dev->streaming) {
-		if (sd->sensor == SENSOR_OV772X)
-			setbrightness_77(gspca_dev);
-		else
-			setbrightness_96(gspca_dev);
-	}
+	if (gspca_dev->streaming)
+		setbrightness(gspca_dev);
 	return 0;
 }
 
@@ -2009,12 +1079,8 @@ static int sd_setcontrast(struct gspca_d
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	sd->contrast = val;
-	if (gspca_dev->streaming) {
-		if (sd->sensor == SENSOR_OV772X)
-			setcontrast_77(gspca_dev);
-		else
-			setcontrast_96(gspca_dev);
-	}
+	if (gspca_dev->streaming)
+		setcontrast(gspca_dev);
 	return 0;
 }
 
@@ -2026,41 +1092,6 @@ static int sd_getcontrast(struct gspca_d
 	return 0;
 }
 
-static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->satur = val;
-	if (gspca_dev->streaming)
-		setsatur(gspca_dev);
-	return 0;
-}
-
-static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	*val = sd->satur;
-	return 0;
-}
-static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->lightfreq = val;
-	if (gspca_dev->streaming)
-		setfreq(gspca_dev);
-	return 0;
-}
-
-static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	*val = sd->lightfreq;
-	return 0;
-}
-
 static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -2122,22 +1153,14 @@ static int sd_setautogain(struct gspca_d
 	sd->autogain = val;
 
 	if (gspca_dev->streaming) {
-		if (sd->sensor == SENSOR_OV772X) {
 
-			/* the auto white balance control works only
-			 * when auto gain is set */
-			if (val)
-				gspca_dev->ctrl_inac &= ~(1 << AWB_77_IDX);
-			else
-				gspca_dev->ctrl_inac |= (1 << AWB_77_IDX);
-			setautogain_77(gspca_dev);
-		} else {
-			if (val)
-				gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
-			else
-				gspca_dev->ctrl_inac &= ~(1 << EXPO_96_IDX);
-			setautogain_96(gspca_dev);
-		}
+		/* the auto white balance control works only
+		 * when auto gain is set */
+		if (val)
+			gspca_dev->ctrl_inac &= ~(1 << AWB_IDX);
+		else
+			gspca_dev->ctrl_inac |= (1 << AWB_IDX);
+		setautogain(gspca_dev);
 	}
 	return 0;
 }
@@ -2173,12 +1196,8 @@ static int sd_setsharpness(struct gspca_
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	sd->sharpness = val;
-	if (gspca_dev->streaming) {
-		if (sd->sensor == SENSOR_OV772X)
-			setsharpness_77(gspca_dev);
-		else
-			setsharpness_96(gspca_dev);
-	}
+	if (gspca_dev->streaming)
+		setsharpness(gspca_dev);
 	return 0;
 }
 
@@ -2257,7 +1276,7 @@ static int sd_set_streamparm(struct gspc
 
 	/* Set requested framerate */
 	sd->frame_rate = tpf->denominator / tpf->numerator;
-	if (gspca_dev->streaming && sd->sensor == SENSOR_OV772X)
+	if (gspca_dev->streaming)
 		set_frame_rate(gspca_dev);
 
 	/* Return the actual framerate */
@@ -2267,57 +1286,23 @@ static int sd_set_streamparm(struct gspc
 	return 0;
 }
 
-static int sd_querymenu(struct gspca_dev *gspca_dev,
-			struct v4l2_querymenu *menu)
-{
-	switch (menu->id) {
-	case V4L2_CID_POWER_LINE_FREQUENCY:
-		switch (menu->index) {
-		case 0:		/* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
-			strcpy((char *) menu->name, "NoFliker");
-			return 0;
-		case 1:		/* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
-			strcpy((char *) menu->name, "50 Hz");
-			return 0;
-		case 2:		/* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
-			strcpy((char *) menu->name, "60 Hz");
-			return 0;
-		}
-		break;
-	}
-	return -EINVAL;
-}
-
 /* sub-driver description */
-static const struct sd_desc sd_desc_ov772x = {
+static const struct sd_desc sd_desc = {
 	.name     = MODULE_NAME,
-	.ctrls    = sd_ctrls_ov772x,
-	.nctrls   = ARRAY_SIZE(sd_ctrls_ov772x),
+	.ctrls    = sd_ctrls,
+	.nctrls   = ARRAY_SIZE(sd_ctrls),
 	.config   = sd_config,
 	.init     = sd_init,
-	.start    = sd_start_ov772x,
-	.stopN    = sd_stopN_ov772x,
+	.start    = sd_start,
+	.stopN    = sd_stopN,
 	.pkt_scan = sd_pkt_scan,
 	.get_streamparm = sd_get_streamparm,
 	.set_streamparm = sd_set_streamparm,
 };
 
-static const struct sd_desc sd_desc_ov965x = {
-	.name     = MODULE_NAME,
-	.ctrls    = sd_ctrls_ov965x,
-	.nctrls   = ARRAY_SIZE(sd_ctrls_ov965x),
-	.config   = sd_config,
-	.init     = sd_init,
-	.start    = sd_start_ov965x,
-	.stopN    = sd_stopN_ov965x,
-	.pkt_scan = sd_pkt_scan,
-	.querymenu = sd_querymenu,
-};
-
 /* -- module initialisation -- */
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X},
-	{USB_DEVICE(0x1415, 0x2000), .driver_info = SENSOR_OV772X},
+	{USB_DEVICE(0x1415, 0x2000)},
 	{}
 };
 
@@ -2326,11 +1311,7 @@ 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,
-				id->driver_info == SENSOR_OV772X
-					? &sd_desc_ov772x
-					: &sd_desc_ov965x,
-				sizeof(struct sd),
+	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 				THIS_MODULE);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac207.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/pac207.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac207.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/pac207.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 
 #define MODULE_NAME "pac207"
 
+#include <linux/input.h>
 #include "gspca.h"
 
 MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
@@ -77,7 +78,7 @@ static int sd_getautogain(struct gspca_d
 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 #define SD_BRIGHTNESS 0
 	{
 	    {
@@ -495,6 +496,25 @@ static int sd_getautogain(struct gspca_d
 	return 0;
 }
 
+#ifdef CONFIG_INPUT
+static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,		/* interrupt packet data */
+			int len)		/* interrput packet length */
+{
+	int ret = -EINVAL;
+
+	if (len == 2 && data[0] == 0x5a && data[1] == 0x5a) {
+		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
+		input_sync(gspca_dev->input_dev);
+		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
+		input_sync(gspca_dev->input_dev);
+		ret = 0;
+	}
+
+	return ret;
+}
+#endif
+
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
@@ -506,6 +526,9 @@ static const struct sd_desc sd_desc = {
 	.stopN = sd_stopN,
 	.dq_callback = pac207_do_auto_gain,
 	.pkt_scan = sd_pkt_scan,
+#ifdef CONFIG_INPUT
+	.int_pkt_scan = sd_int_pkt_scan,
+#endif
 };
 
 /* -- module initialisation -- */
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac7302.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/pac7302.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac7302.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/pac7302.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,9 @@
  *
  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
  *
- * Separated from Pixart PAC7311 library by Márton Németh <nm127@freemail.hu>
+ * Separated from Pixart PAC7311 library by MÃ¡rton NÃ©meth
+ * Camera button input handling by MÃ¡rton NÃ©meth <nm127@freemail.hu>
+ * Copyright (C) 2009-2010 MÃ¡rton NÃ©meth <nm127@freemail.hu>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,33 +24,26 @@
  */
 
 /* Some documentation about various registers as determined by trial and error.
-   When the register addresses differ between the 7202 and the 7311 the 2
-   different addresses are written as 7302addr/7311addr, when one of the 2
-   addresses is a - sign that register description is not valid for the
-   matching IC.
 
    Register page 1:
 
    Address	Description
-   -/0x08	Unknown compressor related, must always be 8 except when not
-		in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
-   -/0x1b	Auto white balance related, bit 0 is AWB enable (inverted)
-		bits 345 seem to toggle per color gains on/off (inverted)
    0x78		Global control, bit 6 controls the LED (inverted)
-   -/0x80	JPEG compression ratio ? Best not touched
 
-   Register page 3/4:
+   Register page 3:
 
    Address	Description
-   0x02		Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
+   0x02		Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
 		the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
-   -/0x0f	Master gain 1-245, low value = high gain
-   0x10/-	Master gain 0-31
-   -/0x10	Another gain 0-15, limited influence (1-2x gain I guess)
+   0x03		Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
+   0x04		Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
+		63 -> ~27 fps, the 2 msb's must always be 1 !!
+   0x05		Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
+		1 -> ~30 fps, 2 -> ~20 fps
+   0x0e		Exposure bits 0-7, 0-448, 0 = use full frame time
+   0x0f		Exposure bit 8, 0-448, 448 = no exposure at all
+   0x10		Master gain 0-31
    0x21		Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
-   -/0x27	Seems to toggle various gains on / off, Setting bit 7 seems to
-		completely disable the analog amplification block. Set to 0x68
-		for max gain, 0x14 for minimal gain.
 
    The registers are accessed in the following functions:
 
@@ -68,6 +63,7 @@
 
 #define MODULE_NAME "pac7302"
 
+#include <linux/input.h>
 #include <media/v4l2-chip-ident.h>
 #include "gspca.h"
 
@@ -86,8 +82,8 @@ struct sd {
 	unsigned char red_balance;
 	unsigned char blue_balance;
 	unsigned char gain;
-	unsigned char exposure;
 	unsigned char autogain;
+	unsigned short exposure;
 	__u8 hflip;
 	__u8 vflip;
 	u8 flags;
@@ -124,8 +120,7 @@ static int sd_getgain(struct gspca_dev *
 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
 
-static struct ctrl sd_ctrls[] = {
-/* This control is pac7302 only */
+static const struct ctrl sd_ctrls[] = {
 	{
 	    {
 		.id      = V4L2_CID_BRIGHTNESS,
@@ -141,7 +136,6 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setbrightness,
 	    .get = sd_getbrightness,
 	},
-/* This control is for both the 7302 and the 7311 */
 	{
 	    {
 		.id      = V4L2_CID_CONTRAST,
@@ -157,7 +151,6 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setcontrast,
 	    .get = sd_getcontrast,
 	},
-/* This control is pac7302 only */
 	{
 	    {
 		.id      = V4L2_CID_SATURATION,
@@ -215,7 +208,6 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setbluebalance,
 	    .get = sd_getbluebalance,
 	},
-/* All controls below are for both the 7302 and the 7311 */
 	{
 	    {
 		.id      = V4L2_CID_GAIN,
@@ -238,11 +230,10 @@ static struct ctrl sd_ctrls[] = {
 		.type    = V4L2_CTRL_TYPE_INTEGER,
 		.name    = "Exposure",
 		.minimum = 0,
-#define EXPOSURE_MAX 255
-		.maximum = EXPOSURE_MAX,
+		.maximum = 1023,
 		.step    = 1,
-#define EXPOSURE_DEF  16 /*  32 ms / 30 fps */
-#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
+#define EXPOSURE_DEF  66  /*  33 ms / 30 fps */
+#define EXPOSURE_KNEE 133 /*  66 ms / 15 fps */
 		.default_value = EXPOSURE_DEF,
 	    },
 	    .set = sd_setexposure,
@@ -301,7 +292,6 @@ static const struct v4l2_pix_format vga_
 };
 
 #define LOAD_PAGE3		255
-#define LOAD_PAGE4		254
 #define END_OF_SEQUENCE		0
 
 /* pac 7302 */
@@ -379,7 +369,7 @@ static const __u8 start_7302[] = {
 #define SKIP		0xaa
 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
 static const __u8 page3_7302[] = {
-	0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
+	0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
 	0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
 	0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 	0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
@@ -388,7 +378,7 @@ static const __u8 page3_7302[] = {
 	0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
 	0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 	0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
+	SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
 	0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 	0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -401,12 +391,14 @@ static const __u8 page3_7302[] = {
 	0x00
 };
 
-static int reg_w_buf(struct gspca_dev *gspca_dev,
+static void reg_w_buf(struct gspca_dev *gspca_dev,
 		  __u8 index,
 		  const char *buffer, int len)
 {
 	int ret;
 
+	if (gspca_dev->usb_err < 0)
+		return;
 	memcpy(gspca_dev->usb_buf, buffer, len);
 	ret = usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -415,20 +407,23 @@ static int reg_w_buf(struct gspca_dev *g
 			0,		/* value */
 			index, gspca_dev->usb_buf, len,
 			500);
-	if (ret < 0)
+	if (ret < 0) {
 		PDEBUG(D_ERR, "reg_w_buf(): "
 		"Failed to write registers to index 0x%x, error %i",
 		index, ret);
-	return ret;
+		gspca_dev->usb_err = ret;
+	}
 }
 
 
-static int reg_w(struct gspca_dev *gspca_dev,
+static void reg_w(struct gspca_dev *gspca_dev,
 		  __u8 index,
 		  __u8 value)
 {
 	int ret;
 
+	if (gspca_dev->usb_err < 0)
+		return;
 	gspca_dev->usb_buf[0] = value;
 	ret = usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -436,32 +431,32 @@ static int reg_w(struct gspca_dev *gspca
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0, index, gspca_dev->usb_buf, 1,
 			500);
-	if (ret < 0)
+	if (ret < 0) {
 		PDEBUG(D_ERR, "reg_w(): "
 		"Failed to write register to index 0x%x, value 0x%x, error %i",
 		index, value, ret);
-	return ret;
+		gspca_dev->usb_err = ret;
+	}
 }
 
-static int reg_w_seq(struct gspca_dev *gspca_dev,
+static void reg_w_seq(struct gspca_dev *gspca_dev,
 		const __u8 *seq, int len)
 {
-	int ret = 0;
 	while (--len >= 0) {
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, seq[0], seq[1]);
+		reg_w(gspca_dev, seq[0], seq[1]);
 		seq += 2;
 	}
-	return ret;
 }
 
 /* load the beginning of a page */
-static int reg_w_page(struct gspca_dev *gspca_dev,
+static void reg_w_page(struct gspca_dev *gspca_dev,
 			const __u8 *page, int len)
 {
 	int index;
 	int ret = 0;
 
+	if (gspca_dev->usb_err < 0)
+		return;
 	for (index = 0; index < len; index++) {
 		if (page[index] == SKIP)		/* skip this index */
 			continue;
@@ -477,56 +472,47 @@ static int reg_w_page(struct gspca_dev *
 			"Failed to write register to index 0x%x, "
 			"value 0x%x, error %i",
 			index, page[index], ret);
+			gspca_dev->usb_err = ret;
 			break;
 		}
 	}
-	return ret;
 }
 
 /* output a variable sequence */
-static int reg_w_var(struct gspca_dev *gspca_dev,
+static void reg_w_var(struct gspca_dev *gspca_dev,
 			const __u8 *seq,
-			const __u8 *page3, unsigned int page3_len,
-			const __u8 *page4, unsigned int page4_len)
+			const __u8 *page3, unsigned int page3_len)
 {
 	int index, len;
-	int ret = 0;
 
 	for (;;) {
 		index = *seq++;
 		len = *seq++;
 		switch (len) {
 		case END_OF_SEQUENCE:
-			return ret;
-		case LOAD_PAGE4:
-			ret = reg_w_page(gspca_dev, page4, page4_len);
-			break;
+			return;
 		case LOAD_PAGE3:
-			ret = reg_w_page(gspca_dev, page3, page3_len);
+			reg_w_page(gspca_dev, page3, page3_len);
 			break;
 		default:
 			if (len > USB_BUF_SZ) {
 				PDEBUG(D_ERR|D_STREAM,
 					"Incorrect variable sequence");
-				return -EINVAL;
+				return;
 			}
 			while (len > 0) {
 				if (len < 8) {
-					ret = reg_w_buf(gspca_dev,
+					reg_w_buf(gspca_dev,
 						index, seq, len);
-					if (ret < 0)
-						return ret;
 					seq += len;
 					break;
 				}
-				ret = reg_w_buf(gspca_dev, index, seq, 8);
+				reg_w_buf(gspca_dev, index, seq, 8);
 				seq += 8;
 				index += 8;
 				len -= 8;
 			}
 		}
-		if (ret < 0)
-			return ret;
 	}
 	/* not reached */
 }
@@ -560,11 +546,10 @@ static int sd_config(struct gspca_dev *g
 }
 
 /* This function is used by pac7302 only */
-static int setbrightcont(struct gspca_dev *gspca_dev)
+static void setbrightcont(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i, v;
-	int ret;
 	static const __u8 max[10] =
 		{0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
 		 0xd4, 0xec};
@@ -572,7 +557,7 @@ static int setbrightcont(struct gspca_de
 		{0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
 		 0x11, 0x0b};
 
-	ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+	reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
 	for (i = 0; i < 10; i++) {
 		v = max[i];
 		v += (sd->brightness - BRIGHTNESS_MAX)
@@ -582,136 +567,121 @@ static int setbrightcont(struct gspca_de
 			v = 0;
 		else if (v > 0xff)
 			v = 0xff;
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, 0xa2 + i, v);
+		reg_w(gspca_dev, 0xa2 + i, v);
 	}
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0xdc, 0x01);
-	return ret;
+	reg_w(gspca_dev, 0xdc, 0x01);
 }
 
 /* This function is used by pac7302 only */
-static int setcolors(struct gspca_dev *gspca_dev)
+static void setcolors(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i, v;
-	int ret;
 	static const int a[9] =
 		{217, -212, 0, -101, 170, -67, -38, -315, 355};
 	static const int b[9] =
 		{19, 106, 0, 19, 106, 1, 19, 106, 1};
 
-	ret = reg_w(gspca_dev, 0xff, 0x03);	/* page 3 */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x11, 0x01);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
+	reg_w(gspca_dev, 0x11, 0x01);
+	reg_w(gspca_dev, 0xff, 0x00);			/* page 0 */
 	for (i = 0; i < 9; i++) {
 		v = a[i] * sd->colors / COLOR_MAX + b[i];
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
+		reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
+		reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
 	}
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0xdc, 0x01);
+	reg_w(gspca_dev, 0xdc, 0x01);
 	PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
-	return ret;
 }
 
-static int setwhitebalance(struct gspca_dev *gspca_dev)
+static void setwhitebalance(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret;
 
-	ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0xc6, sd->white_balance);
+	reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
+	reg_w(gspca_dev, 0xc6, sd->white_balance);
 
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0xdc, 0x01);
+	reg_w(gspca_dev, 0xdc, 0x01);
 	PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance);
-	return ret;
 }
 
-static int setredbalance(struct gspca_dev *gspca_dev)
+static void setredbalance(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret;
 
-	ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0xc5, sd->red_balance);
+	reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
+	reg_w(gspca_dev, 0xc5, sd->red_balance);
 
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0xdc, 0x01);
+	reg_w(gspca_dev, 0xdc, 0x01);
 	PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance);
-	return ret;
 }
 
-static int setbluebalance(struct gspca_dev *gspca_dev)
+static void setbluebalance(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret;
 
-	ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0xc7, sd->blue_balance);
+	reg_w(gspca_dev, 0xff, 0x00);			/* page 0 */
+	reg_w(gspca_dev, 0xc7, sd->blue_balance);
 
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0xdc, 0x01);
+	reg_w(gspca_dev, 0xdc, 0x01);
 	PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance);
-	return ret;
 }
 
-static int setgain(struct gspca_dev *gspca_dev)
+static void setgain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret;
 
-	ret = reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x10, sd->gain >> 3);
+	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
+	reg_w(gspca_dev, 0x10, sd->gain >> 3);
 
 	/* load registers to sensor (Bit 0, auto clear) */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x11, 0x01);
-	return ret;
+	reg_w(gspca_dev, 0x11, 0x01);
 }
 
-static int setexposure(struct gspca_dev *gspca_dev)
+static void setexposure(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret;
-	__u8 reg;
+	__u8 clockdiv;
+	__u16 exposure;
 
-	/* register 2 of frame 3/4 contains the clock divider configuring the
-	   no fps according to the formula: 60 / reg. sd->exposure is the
-	   desired exposure time in ms. */
-	reg = 120 * sd->exposure / 1000;
-	if (reg < 2)
-		reg = 2;
-	else if (reg > 63)
-		reg = 63;
+	/* register 2 of frame 3 contains the clock divider configuring the
+	   no fps according to the formula: 90 / reg. sd->exposure is the
+	   desired exposure time in 0.5 ms. */
+	clockdiv = (90 * sd->exposure + 1999) / 2000;
 
-	/* On the pac7302 reg2 MUST be a multiple of 3, so round it to
-	   the nearest multiple of 3, except when between 6 and 12? */
-	if (reg < 6 || reg > 12)
-		reg = ((reg + 1) / 3) * 3;
-	ret = reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x02, reg);
+	/* Note clockdiv = 3 also works, but when running at 30 fps, depending
+	   on the scene being recorded, the camera switches to another
+	   quantization table for certain JPEG blocks, and we don't know how
+	   to decompress these blocks. So we cap the framerate at 15 fps */
+	if (clockdiv < 6)
+		clockdiv = 6;
+	else if (clockdiv > 63)
+		clockdiv = 63;
+
+	/* reg2 MUST be a multiple of 3, except when between 6 and 12?
+	   Always round up, otherwise we cannot get the desired frametime
+	   using the partial frame time exposure control */
+	if (clockdiv < 6 || clockdiv > 12)
+		clockdiv = ((clockdiv + 2) / 3) * 3;
+
+	/* frame exposure time in ms = 1000 * clockdiv / 90    ->
+	exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) */
+	exposure = (sd->exposure * 45 * 448) / (1000 * clockdiv);
+	/* 0 = use full frametime, 448 = no exposure, reverse it */
+	exposure = 448 - exposure;
+
+	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
+	reg_w(gspca_dev, 0x02, clockdiv);
+	reg_w(gspca_dev, 0x0e, exposure & 0xff);
+	reg_w(gspca_dev, 0x0f, exposure >> 8);
 
 	/* load registers to sensor (Bit 0, auto clear) */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x11, 0x01);
-	return ret;
+	reg_w(gspca_dev, 0x11, 0x01);
 }
 
-static int sethvflip(struct gspca_dev *gspca_dev)
+static void sethvflip(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret;
 	u8 data, hflip, vflip;
 
 	hflip = sd->hflip;
@@ -721,48 +691,37 @@ static int sethvflip(struct gspca_dev *g
 	if (sd->flags & FL_VFLIP)
 		vflip = !vflip;
 
-	ret = reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
+	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
 	data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x21, data);
+	reg_w(gspca_dev, 0x21, data);
+
 	/* load registers to sensor (Bit 0, auto clear) */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x11, 0x01);
-	return ret;
+	reg_w(gspca_dev, 0x11, 0x01);
 }
 
 /* this function is called at probe and resume time for pac7302 */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
-	return reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
+	reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
+	return gspca_dev->usb_err;
 }
 
 static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret = 0;
 
 	sd->sof_read = 0;
 
-	ret = reg_w_var(gspca_dev, start_7302,
-		page3_7302, sizeof(page3_7302),
-		NULL, 0);
-	if (0 <= ret)
-		ret = setbrightcont(gspca_dev);
-	if (0 <= ret)
-		ret = setcolors(gspca_dev);
-	if (0 <= ret)
-		ret = setwhitebalance(gspca_dev);
-	if (0 <= ret)
-		ret = setredbalance(gspca_dev);
-	if (0 <= ret)
-		ret = setbluebalance(gspca_dev);
-	if (0 <= ret)
-		ret = setgain(gspca_dev);
-	if (0 <= ret)
-		ret = setexposure(gspca_dev);
-	if (0 <= ret)
-		ret = sethvflip(gspca_dev);
+	reg_w_var(gspca_dev, start_7302,
+		page3_7302, sizeof(page3_7302));
+	setbrightcont(gspca_dev);
+	setcolors(gspca_dev);
+	setwhitebalance(gspca_dev);
+	setredbalance(gspca_dev);
+	setbluebalance(gspca_dev);
+	setgain(gspca_dev);
+	setexposure(gspca_dev);
+	sethvflip(gspca_dev);
 
 	/* only resolution 640x480 is supported for pac7302 */
 
@@ -771,34 +730,27 @@ static int sd_start(struct gspca_dev *gs
 	atomic_set(&sd->avg_lum, -1);
 
 	/* start stream */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0xff, 0x01);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x78, 0x01);
+	reg_w(gspca_dev, 0xff, 0x01);
+	reg_w(gspca_dev, 0x78, 0x01);
 
-	return ret;
+	return gspca_dev->usb_err;
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
-	int ret;
 
 	/* stop stream */
-	ret = reg_w(gspca_dev, 0xff, 0x01);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x78, 0x00);
+	reg_w(gspca_dev, 0xff, 0x01);
+	reg_w(gspca_dev, 0x78, 0x00);
 }
 
 /* called on streamoff with alt 0 and on disconnect for pac7302 */
 static void sd_stop0(struct gspca_dev *gspca_dev)
 {
-	int ret;
-
 	if (!gspca_dev->present)
 		return;
-	ret = reg_w(gspca_dev, 0xff, 0x01);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x78, 0x40);
+	reg_w(gspca_dev, 0xff, 0x01);
+	reg_w(gspca_dev, 0x78, 0x40);
 }
 
 /* Include pac common sof detection functions */
@@ -808,22 +760,13 @@ static void do_autogain(struct gspca_dev
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int avg_lum = atomic_read(&sd->avg_lum);
-	int desired_lum, deadzone;
+	int desired_lum;
+	const int deadzone = 30;
 
 	if (avg_lum == -1)
 		return;
 
-	desired_lum = 270 + sd->brightness * 4;
-	/* Hack hack, with the 7202 the first exposure step is
-	   pretty large, so if we're about to make the first
-	   exposure increase make the deadzone large to avoid
-	   oscilating */
-	if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
-			sd->exposure > EXPOSURE_DEF &&
-			sd->exposure < 42)
-		deadzone = 90;
-	else
-		deadzone = 30;
+	desired_lum = 270 + sd->brightness;
 
 	if (sd->autogain_ignore_frames > 0)
 		sd->autogain_ignore_frames--;
@@ -947,7 +890,7 @@ static int sd_setbrightness(struct gspca
 	sd->brightness = val;
 	if (gspca_dev->streaming)
 		setbrightcont(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -966,7 +909,7 @@ static int sd_setcontrast(struct gspca_d
 	if (gspca_dev->streaming) {
 		setbrightcont(gspca_dev);
 	}
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@@ -984,7 +927,7 @@ static int sd_setcolors(struct gspca_dev
 	sd->colors = val;
 	if (gspca_dev->streaming)
 		setcolors(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
@@ -998,14 +941,11 @@ static int sd_getcolors(struct gspca_dev
 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret = 0;
 
 	sd->white_balance = val;
 	if (gspca_dev->streaming)
-		ret = setwhitebalance(gspca_dev);
-	if (0 <= ret)
-		ret = 0;
-	return ret;
+		setwhitebalance(gspca_dev);
+	return gspca_dev->usb_err;
 }
 
 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1019,14 +959,11 @@ static int sd_getwhitebalance(struct gsp
 static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret = 0;
 
 	sd->red_balance = val;
 	if (gspca_dev->streaming)
-		ret = setredbalance(gspca_dev);
-	if (0 <= ret)
-		ret = 0;
-	return ret;
+		setredbalance(gspca_dev);
+	return gspca_dev->usb_err;
 }
 
 static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1040,14 +977,11 @@ static int sd_getredbalance(struct gspca
 static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret = 0;
 
 	sd->blue_balance = val;
 	if (gspca_dev->streaming)
-		ret = setbluebalance(gspca_dev);
-	if (0 <= ret)
-		ret = 0;
-	return ret;
+		setbluebalance(gspca_dev);
+	return gspca_dev->usb_err;
 }
 
 static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1065,7 +999,7 @@ static int sd_setgain(struct gspca_dev *
 	sd->gain = val;
 	if (gspca_dev->streaming)
 		setgain(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1083,7 +1017,7 @@ static int sd_setexposure(struct gspca_d
 	sd->exposure = val;
 	if (gspca_dev->streaming)
 		setexposure(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1114,7 +1048,7 @@ static int sd_setautogain(struct gspca_d
 		}
 	}
 
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1132,7 +1066,7 @@ static int sd_sethflip(struct gspca_dev
 	sd->hflip = val;
 	if (gspca_dev->streaming)
 		sethvflip(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1150,7 +1084,7 @@ static int sd_setvflip(struct gspca_dev
 	sd->vflip = val;
 	if (gspca_dev->streaming)
 		sethvflip(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1165,7 +1099,6 @@ static int sd_getvflip(struct gspca_dev
 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
 			struct v4l2_dbg_register *reg)
 {
-	int ret = -EINVAL;
 	__u8 index;
 	__u8 value;
 
@@ -1185,14 +1118,12 @@ static int sd_dbg_s_register(struct gspc
 		/* Note that there shall be no access to other page
 		   by any other function between the page swith and
 		   the actual register write */
-		ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, index, value);
+		reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
+		reg_w(gspca_dev, index, value);
 
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, 0xdc, 0x01);
+		reg_w(gspca_dev, 0xdc, 0x01);
 	}
-	return ret;
+	return gspca_dev->usb_err;
 }
 
 static int sd_chip_ident(struct gspca_dev *gspca_dev,
@@ -1210,8 +1141,39 @@ static int sd_chip_ident(struct gspca_de
 }
 #endif
 
+#ifdef CONFIG_INPUT
+static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,		/* interrupt packet data */
+			int len)		/* interrput packet length */
+{
+	int ret = -EINVAL;
+	u8 data0, data1;
+
+	if (len == 2) {
+		data0 = data[0];
+		data1 = data[1];
+		if ((data0 == 0x00 && data1 == 0x11) ||
+		    (data0 == 0x22 && data1 == 0x33) ||
+		    (data0 == 0x44 && data1 == 0x55) ||
+		    (data0 == 0x66 && data1 == 0x77) ||
+		    (data0 == 0x88 && data1 == 0x99) ||
+		    (data0 == 0xaa && data1 == 0xbb) ||
+		    (data0 == 0xcc && data1 == 0xdd) ||
+		    (data0 == 0xee && data1 == 0xff)) {
+			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
+			input_sync(gspca_dev->input_dev);
+			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
+			input_sync(gspca_dev->input_dev);
+			ret = 0;
+		}
+	}
+
+	return ret;
+}
+#endif
+
 /* sub-driver description for pac7302 */
-static struct sd_desc sd_desc = {
+static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
@@ -1226,6 +1188,9 @@ static struct sd_desc sd_desc = {
 	.set_register = sd_dbg_s_register,
 	.get_chip_ident = sd_chip_ident,
 #endif
+#ifdef CONFIG_INPUT
+	.int_pkt_scan = sd_int_pkt_scan,
+#endif
 };
 
 /* -- module initialisation -- */
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac7311.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/pac7311.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac7311.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/pac7311.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,6 +51,7 @@
 
 #define MODULE_NAME "pac7311"
 
+#include <linux/input.h>
 #include "gspca.h"
 
 MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
@@ -88,7 +89,7 @@ static int sd_getgain(struct gspca_dev *
 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 /* This control is for both the 7302 and the 7311 */
 	{
 	    {
@@ -200,7 +201,6 @@ static const struct v4l2_pix_format vga_
 		.priv = 0},
 };
 
-#define LOAD_PAGE3		255
 #define LOAD_PAGE4		254
 #define END_OF_SEQUENCE		0
 
@@ -259,12 +259,14 @@ static const __u8 page4_7311[] = {
 	0x23, 0x28, 0x04, 0x11, 0x00, 0x00
 };
 
-static int reg_w_buf(struct gspca_dev *gspca_dev,
+static void reg_w_buf(struct gspca_dev *gspca_dev,
 		  __u8 index,
 		  const char *buffer, int len)
 {
 	int ret;
 
+	if (gspca_dev->usb_err < 0)
+		return;
 	memcpy(gspca_dev->usb_buf, buffer, len);
 	ret = usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -273,20 +275,23 @@ static int reg_w_buf(struct gspca_dev *g
 			0,		/* value */
 			index, gspca_dev->usb_buf, len,
 			500);
-	if (ret < 0)
+	if (ret < 0) {
 		PDEBUG(D_ERR, "reg_w_buf(): "
 		"Failed to write registers to index 0x%x, error %i",
 		index, ret);
-	return ret;
+		gspca_dev->usb_err = ret;
+	}
 }
 
 
-static int reg_w(struct gspca_dev *gspca_dev,
+static void reg_w(struct gspca_dev *gspca_dev,
 		  __u8 index,
 		  __u8 value)
 {
 	int ret;
 
+	if (gspca_dev->usb_err < 0)
+		return;
 	gspca_dev->usb_buf[0] = value;
 	ret = usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -294,32 +299,32 @@ static int reg_w(struct gspca_dev *gspca
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0, index, gspca_dev->usb_buf, 1,
 			500);
-	if (ret < 0)
+	if (ret < 0) {
 		PDEBUG(D_ERR, "reg_w(): "
 		"Failed to write register to index 0x%x, value 0x%x, error %i",
 		index, value, ret);
-	return ret;
+		gspca_dev->usb_err = ret;
+	}
 }
 
-static int reg_w_seq(struct gspca_dev *gspca_dev,
+static void reg_w_seq(struct gspca_dev *gspca_dev,
 		const __u8 *seq, int len)
 {
-	int ret = 0;
 	while (--len >= 0) {
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, seq[0], seq[1]);
+		reg_w(gspca_dev, seq[0], seq[1]);
 		seq += 2;
 	}
-	return ret;
 }
 
 /* load the beginning of a page */
-static int reg_w_page(struct gspca_dev *gspca_dev,
+static void reg_w_page(struct gspca_dev *gspca_dev,
 			const __u8 *page, int len)
 {
 	int index;
 	int ret = 0;
 
+	if (gspca_dev->usb_err < 0)
+		return;
 	for (index = 0; index < len; index++) {
 		if (page[index] == SKIP)		/* skip this index */
 			continue;
@@ -335,56 +340,47 @@ static int reg_w_page(struct gspca_dev *
 			"Failed to write register to index 0x%x, "
 			"value 0x%x, error %i",
 			index, page[index], ret);
+			gspca_dev->usb_err = ret;
 			break;
 		}
 	}
-	return ret;
 }
 
 /* output a variable sequence */
-static int reg_w_var(struct gspca_dev *gspca_dev,
+static void reg_w_var(struct gspca_dev *gspca_dev,
 			const __u8 *seq,
-			const __u8 *page3, unsigned int page3_len,
 			const __u8 *page4, unsigned int page4_len)
 {
 	int index, len;
-	int ret = 0;
 
 	for (;;) {
 		index = *seq++;
 		len = *seq++;
 		switch (len) {
 		case END_OF_SEQUENCE:
-			return ret;
+			return;
 		case LOAD_PAGE4:
-			ret = reg_w_page(gspca_dev, page4, page4_len);
-			break;
-		case LOAD_PAGE3:
-			ret = reg_w_page(gspca_dev, page3, page3_len);
+			reg_w_page(gspca_dev, page4, page4_len);
 			break;
 		default:
 			if (len > USB_BUF_SZ) {
 				PDEBUG(D_ERR|D_STREAM,
 					"Incorrect variable sequence");
-				return -EINVAL;
+				return;
 			}
 			while (len > 0) {
 				if (len < 8) {
-					ret = reg_w_buf(gspca_dev,
+					reg_w_buf(gspca_dev,
 						index, seq, len);
-					if (ret < 0)
-						return ret;
 					seq += len;
 					break;
 				}
-				ret = reg_w_buf(gspca_dev, index, seq, 8);
+				reg_w_buf(gspca_dev, index, seq, 8);
 				seq += 8;
 				index += 8;
 				len -= 8;
 			}
 		}
-		if (ret < 0)
-			return ret;
 	}
 	/* not reached */
 }
@@ -412,46 +408,36 @@ static int sd_config(struct gspca_dev *g
 }
 
 /* This function is used by pac7311 only */
-static int setcontrast(struct gspca_dev *gspca_dev)
+static void setcontrast(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret;
 
-	ret = reg_w(gspca_dev, 0xff, 0x04);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x10, sd->contrast >> 4);
+	reg_w(gspca_dev, 0xff, 0x04);
+	reg_w(gspca_dev, 0x10, sd->contrast >> 4);
 	/* load registers to sensor (Bit 0, auto clear) */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x11, 0x01);
-	return ret;
+	reg_w(gspca_dev, 0x11, 0x01);
 }
 
-static int setgain(struct gspca_dev *gspca_dev)
+static void setgain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int gain = GAIN_MAX - sd->gain;
-	int ret;
 
 	if (gain < 1)
 		gain = 1;
 	else if (gain > 245)
 		gain = 245;
-	ret = reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x0e, 0x00);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x0f, gain);
+	reg_w(gspca_dev, 0xff, 0x04);			/* page 4 */
+	reg_w(gspca_dev, 0x0e, 0x00);
+	reg_w(gspca_dev, 0x0f, gain);
 
 	/* load registers to sensor (Bit 0, auto clear) */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x11, 0x01);
-	return ret;
+	reg_w(gspca_dev, 0x11, 0x01);
 }
 
-static int setexposure(struct gspca_dev *gspca_dev)
+static void setexposure(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret;
 	__u8 reg;
 
 	/* register 2 of frame 3/4 contains the clock divider configuring the
@@ -463,94 +449,72 @@ static int setexposure(struct gspca_dev
 	else if (reg > 63)
 		reg = 63;
 
-	ret = reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x02, reg);
+	reg_w(gspca_dev, 0xff, 0x04);			/* page 4 */
+	reg_w(gspca_dev, 0x02, reg);
+
 	/* Page 1 register 8 must always be 0x08 except when not in
 	   640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0xff, 0x01);
+	reg_w(gspca_dev, 0xff, 0x01);
 	if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
 			reg <= 3) {
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, 0x08, 0x09);
+		reg_w(gspca_dev, 0x08, 0x09);
 	} else {
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, 0x08, 0x08);
+		reg_w(gspca_dev, 0x08, 0x08);
 	}
 
 	/* load registers to sensor (Bit 0, auto clear) */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x11, 0x01);
-	return ret;
+	reg_w(gspca_dev, 0x11, 0x01);
 }
 
-static int sethvflip(struct gspca_dev *gspca_dev)
+static void sethvflip(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret;
 	__u8 data;
 
-	ret = reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
+	reg_w(gspca_dev, 0xff, 0x04);			/* page 4 */
 	data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x21, data);
+	reg_w(gspca_dev, 0x21, data);
+
 	/* load registers to sensor (Bit 0, auto clear) */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x11, 0x01);
-	return ret;
+	reg_w(gspca_dev, 0x11, 0x01);
 }
 
 /* this function is called at probe and resume time for pac7311 */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
-	return reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
+	reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
+	return gspca_dev->usb_err;
 }
 
 static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret;
 
 	sd->sof_read = 0;
 
-	ret = reg_w_var(gspca_dev, start_7311,
-		NULL, 0,
+	reg_w_var(gspca_dev, start_7311,
 		page4_7311, sizeof(page4_7311));
-	if (0 <= ret)
-		ret = setcontrast(gspca_dev);
-	if (0 <= ret)
-		ret = setgain(gspca_dev);
-	if (0 <= ret)
-		ret = setexposure(gspca_dev);
-	if (0 <= ret)
-		ret = sethvflip(gspca_dev);
+	setcontrast(gspca_dev);
+	setgain(gspca_dev);
+	setexposure(gspca_dev);
+	sethvflip(gspca_dev);
 
 	/* set correct resolution */
 	switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
 	case 2:					/* 160x120 pac7311 */
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, 0xff, 0x01);
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, 0x17, 0x20);
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, 0x87, 0x10);
+		reg_w(gspca_dev, 0xff, 0x01);
+		reg_w(gspca_dev, 0x17, 0x20);
+		reg_w(gspca_dev, 0x87, 0x10);
 		break;
 	case 1:					/* 320x240 pac7311 */
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, 0xff, 0x01);
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, 0x17, 0x30);
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, 0x87, 0x11);
+		reg_w(gspca_dev, 0xff, 0x01);
+		reg_w(gspca_dev, 0x17, 0x30);
+		reg_w(gspca_dev, 0x87, 0x11);
 		break;
 	case 0:					/* 640x480 */
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, 0xff, 0x01);
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, 0x17, 0x00);
-		if (0 <= ret)
-			ret = reg_w(gspca_dev, 0x87, 0x12);
+		reg_w(gspca_dev, 0xff, 0x01);
+		reg_w(gspca_dev, 0x17, 0x00);
+		reg_w(gspca_dev, 0x87, 0x12);
 		break;
 	}
 
@@ -559,37 +523,24 @@ static int sd_start(struct gspca_dev *gs
 	atomic_set(&sd->avg_lum, -1);
 
 	/* start stream */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0xff, 0x01);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x78, 0x05);
+	reg_w(gspca_dev, 0xff, 0x01);
+	reg_w(gspca_dev, 0x78, 0x05);
 
-	return ret;
+	return gspca_dev->usb_err;
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
-	int ret;
-
-	ret = reg_w(gspca_dev, 0xff, 0x04);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x27, 0x80);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x28, 0xca);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x29, 0x53);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x2a, 0x0e);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0xff, 0x01);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x3e, 0x20);
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
-	if (0 <= ret)
-		ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
+	reg_w(gspca_dev, 0xff, 0x04);
+	reg_w(gspca_dev, 0x27, 0x80);
+	reg_w(gspca_dev, 0x28, 0xca);
+	reg_w(gspca_dev, 0x29, 0x53);
+	reg_w(gspca_dev, 0x2a, 0x0e);
+	reg_w(gspca_dev, 0xff, 0x01);
+	reg_w(gspca_dev, 0x3e, 0x20);
+	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
+	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
+	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
 }
 
 /* called on streamoff with alt 0 and on disconnect for 7311 */
@@ -734,7 +685,7 @@ static int sd_setcontrast(struct gspca_d
 	if (gspca_dev->streaming) {
 		setcontrast(gspca_dev);
 	}
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@@ -752,7 +703,7 @@ static int sd_setgain(struct gspca_dev *
 	sd->gain = val;
 	if (gspca_dev->streaming)
 		setgain(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -770,7 +721,7 @@ static int sd_setexposure(struct gspca_d
 	sd->exposure = val;
 	if (gspca_dev->streaming)
 		setexposure(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -801,7 +752,7 @@ static int sd_setautogain(struct gspca_d
 		}
 	}
 
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -819,7 +770,7 @@ static int sd_sethflip(struct gspca_dev
 	sd->hflip = val;
 	if (gspca_dev->streaming)
 		sethvflip(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -837,7 +788,7 @@ static int sd_setvflip(struct gspca_dev
 	sd->vflip = val;
 	if (gspca_dev->streaming)
 		sethvflip(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -848,8 +799,39 @@ static int sd_getvflip(struct gspca_dev
 	return 0;
 }
 
+#ifdef CONFIG_INPUT
+static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,		/* interrupt packet data */
+			int len)		/* interrupt packet length */
+{
+	int ret = -EINVAL;
+	u8 data0, data1;
+
+	if (len == 2) {
+		data0 = data[0];
+		data1 = data[1];
+		if ((data0 == 0x00 && data1 == 0x11) ||
+		    (data0 == 0x22 && data1 == 0x33) ||
+		    (data0 == 0x44 && data1 == 0x55) ||
+		    (data0 == 0x66 && data1 == 0x77) ||
+		    (data0 == 0x88 && data1 == 0x99) ||
+		    (data0 == 0xaa && data1 == 0xbb) ||
+		    (data0 == 0xcc && data1 == 0xdd) ||
+		    (data0 == 0xee && data1 == 0xff)) {
+			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
+			input_sync(gspca_dev->input_dev);
+			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
+			input_sync(gspca_dev->input_dev);
+			ret = 0;
+		}
+	}
+
+	return ret;
+}
+#endif
+
 /* sub-driver description for pac7311 */
-static struct sd_desc sd_desc = {
+static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
@@ -860,6 +842,9 @@ static struct sd_desc sd_desc = {
 	.stop0 = sd_stop0,
 	.pkt_scan = sd_pkt_scan,
 	.dq_callback = do_autogain,
+#ifdef CONFIG_INPUT
+	.int_pkt_scan = sd_int_pkt_scan,
+#endif
 };
 
 /* -- module initialisation -- */
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac_common.h linux-libre-2.6.34-gnu1/drivers/media/video/gspca/pac_common.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac_common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/pac_common.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,11 +24,10 @@
  */
 
 /* We calculate the autogain at the end of the transfer of a frame, at this
-   moment a frame with the old settings is being transmitted, and a frame is
-   being captured with the old settings. So if we adjust the autogain we must
-   ignore atleast the 2 next frames for the new settings to come into effect
-   before doing any other adjustments */
-#define PAC_AUTOGAIN_IGNORE_FRAMES	3
+   moment a frame with the old settings is being captured and transmitted. So
+   if we adjust the gain or exposure we must ignore atleast the next frame for
+   the new settings to come into effect before doing any other adjustments. */
+#define PAC_AUTOGAIN_IGNORE_FRAMES	2
 
 static const unsigned char pac_sof_marker[5] =
 		{ 0xff, 0xff, 0x00, 0xff, 0x96 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sn9c2028.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sn9c2028.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sn9c2028.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sn9c2028.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,757 @@
+/*
+ * SN9C2028 library
+ *
+ * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.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; 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 "sn9c2028"
+
+#include "gspca.h"
+
+MODULE_AUTHOR("Theodore Kilgore");
+MODULE_DESCRIPTION("Sonix SN9C2028 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+	struct gspca_dev gspca_dev;  /* !! must be the first item */
+	u8 sof_read;
+	u16 model;
+};
+
+struct init_command {
+	unsigned char instruction[6];
+	unsigned char to_read; /* length to read. 0 means no reply requested */
+};
+
+/* V4L2 controls supported by the driver */
+static struct ctrl sd_ctrls[] = {
+};
+
+/* How to change the resolution of any of the VGA cams is unknown */
+static const struct v4l2_pix_format vga_mode[] = {
+	{640, 480, V4L2_PIX_FMT_SN9C2028, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480 * 3 / 4,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+};
+
+/* No way to change the resolution of the CIF cams is known */
+static const struct v4l2_pix_format cif_mode[] = {
+	{352, 288, V4L2_PIX_FMT_SN9C2028, V4L2_FIELD_NONE,
+		.bytesperline = 352,
+		.sizeimage = 352 * 288 * 3 / 4,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+};
+
+/* the bytes to write are in gspca_dev->usb_buf */
+static int sn9c2028_command(struct gspca_dev *gspca_dev, u8 *command)
+{
+	int rc;
+
+	PDEBUG(D_USBO, "sending command %02x%02x%02x%02x%02x%02x", command[0],
+	       command[1], command[2], command[3], command[4], command[5]);
+
+	memcpy(gspca_dev->usb_buf, command, 6);
+	rc = usb_control_msg(gspca_dev->dev,
+			usb_sndctrlpipe(gspca_dev->dev, 0),
+			USB_REQ_GET_CONFIGURATION,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+			2, 0, gspca_dev->usb_buf, 6, 500);
+	if (rc < 0) {
+		PDEBUG(D_ERR, "command write [%02x] error %d",
+				gspca_dev->usb_buf[0], rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+static int sn9c2028_read1(struct gspca_dev *gspca_dev)
+{
+	int rc;
+
+	rc = usb_control_msg(gspca_dev->dev,
+			usb_rcvctrlpipe(gspca_dev->dev, 0),
+			USB_REQ_GET_STATUS,
+			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+			1, 0, gspca_dev->usb_buf, 1, 500);
+	if (rc != 1) {
+		PDEBUG(D_ERR, "read1 error %d", rc);
+		return (rc < 0) ? rc : -EIO;
+	}
+	PDEBUG(D_USBI, "read1 response %02x", gspca_dev->usb_buf[0]);
+	return gspca_dev->usb_buf[0];
+}
+
+static int sn9c2028_read4(struct gspca_dev *gspca_dev, u8 *reading)
+{
+	int rc;
+	rc = usb_control_msg(gspca_dev->dev,
+			usb_rcvctrlpipe(gspca_dev->dev, 0),
+			USB_REQ_GET_STATUS,
+			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+			4, 0, gspca_dev->usb_buf, 4, 500);
+	if (rc != 4) {
+		PDEBUG(D_ERR, "read4 error %d", rc);
+		return (rc < 0) ? rc : -EIO;
+	}
+	memcpy(reading, gspca_dev->usb_buf, 4);
+	PDEBUG(D_USBI, "read4 response %02x%02x%02x%02x", reading[0],
+	       reading[1], reading[2], reading[3]);
+	return rc;
+}
+
+static int sn9c2028_long_command(struct gspca_dev *gspca_dev, u8 *command)
+{
+	int i, status;
+	__u8 reading[4];
+
+	status = sn9c2028_command(gspca_dev, command);
+	if (status < 0)
+		return status;
+
+	status = -1;
+	for (i = 0; i < 256 && status < 2; i++)
+		status = sn9c2028_read1(gspca_dev);
+	if (status != 2) {
+		PDEBUG(D_ERR, "long command status read error %d", status);
+		return (status < 0) ? status : -EIO;
+	}
+
+	memset(reading, 0, 4);
+	status = sn9c2028_read4(gspca_dev, reading);
+	if (status < 0)
+		return status;
+
+	/* in general, the first byte of the response is the first byte of
+	 * the command, or'ed with 8 */
+	status = sn9c2028_read1(gspca_dev);
+	if (status < 0)
+		return status;
+
+	return 0;
+}
+
+static int sn9c2028_short_command(struct gspca_dev *gspca_dev, u8 *command)
+{
+	int err_code;
+
+	err_code = sn9c2028_command(gspca_dev, command);
+	if (err_code < 0)
+		return err_code;
+
+	err_code = sn9c2028_read1(gspca_dev);
+	if (err_code < 0)
+		return err_code;
+
+	return 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 = &gspca_dev->cam;
+
+	PDEBUG(D_PROBE, "SN9C2028 camera detected (vid/pid 0x%04X:0x%04X)",
+	       id->idVendor, id->idProduct);
+
+	sd->model = id->idProduct;
+
+	switch (sd->model) {
+	case 0x7005:
+		PDEBUG(D_PROBE, "Genius Smart 300 camera");
+		break;
+	case 0x8000:
+		PDEBUG(D_PROBE, "DC31VC");
+		break;
+	case 0x8001:
+		PDEBUG(D_PROBE, "Spy camera");
+		break;
+	case 0x8003:
+		PDEBUG(D_PROBE, "CIF camera");
+		break;
+	case 0x8008:
+		PDEBUG(D_PROBE, "Mini-Shotz ms-350 camera");
+		break;
+	case 0x800a:
+		PDEBUG(D_PROBE, "Vivitar 3350b type camera");
+		cam->input_flags = V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
+		break;
+	}
+
+	switch (sd->model) {
+	case 0x8000:
+	case 0x8001:
+	case 0x8003:
+		cam->cam_mode = cif_mode;
+		cam->nmodes = ARRAY_SIZE(cif_mode);
+		break;
+	default:
+		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)
+{
+	int status = -1;
+
+	sn9c2028_read1(gspca_dev);
+	sn9c2028_read1(gspca_dev);
+	status = sn9c2028_read1(gspca_dev);
+
+	return (status < 0) ? status : 0;
+}
+
+static int run_start_commands(struct gspca_dev *gspca_dev,
+			      struct init_command *cam_commands, int n)
+{
+	int i, err_code = -1;
+
+	for (i = 0; i < n; i++) {
+		switch (cam_commands[i].to_read) {
+		case 4:
+			err_code = sn9c2028_long_command(gspca_dev,
+					cam_commands[i].instruction);
+			break;
+		case 1:
+			err_code = sn9c2028_short_command(gspca_dev,
+					cam_commands[i].instruction);
+			break;
+		case 0:
+			err_code = sn9c2028_command(gspca_dev,
+					cam_commands[i].instruction);
+			break;
+		}
+		if (err_code < 0)
+			return err_code;
+	}
+	return 0;
+}
+
+static int start_spy_cam(struct gspca_dev *gspca_dev)
+{
+	struct init_command spy_start_commands[] = {
+		{{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x22, 0x01, 0x04, 0x00, 0x00}, 4},
+		{{0x13, 0x23, 0x01, 0x03, 0x00, 0x00}, 4},
+		{{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4}, /* width  352 */
+		{{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4}, /* height 288 */
+		/* {{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4}, */
+		{{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4},
+		{{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4}, /* red gain ?*/
+		/* {{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4}, */
+		{{0x13, 0x29, 0x01, 0x00, 0x00, 0x00}, 4},
+		/* {{0x13, 0x29, 0x01, 0x0c, 0x00, 0x00}, 4}, */
+		{{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
+		/* {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, */
+		{{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
+		{{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4},
+		/* {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4}, */
+		{{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4},
+		{{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4},
+		{{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
+		{{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x02, 0x06, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x03, 0x13, 0x00, 0x00, 0x00}, 4}, /*don't mess with*/
+		/*{{0x11, 0x04, 0x06, 0x00, 0x00, 0x00}, 4}, observed */
+		{{0x11, 0x04, 0x00, 0x00, 0x00, 0x00}, 4}, /* brighter */
+		/*{{0x11, 0x05, 0x65, 0x00, 0x00, 0x00}, 4}, observed */
+		{{0x11, 0x05, 0x00, 0x00, 0x00, 0x00}, 4}, /* brighter */
+		{{0x11, 0x06, 0xb1, 0x00, 0x00, 0x00}, 4}, /* observed */
+		{{0x11, 0x07, 0x00, 0x00, 0x00, 0x00}, 4},
+		/*{{0x11, 0x08, 0x06, 0x00, 0x00, 0x00}, 4}, observed */
+		{{0x11, 0x08, 0x0b, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x09, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x0a, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x0b, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x0c, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x0d, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x0e, 0x04, 0x00, 0x00, 0x00}, 4},
+		/* {{0x11, 0x0f, 0x00, 0x00, 0x00, 0x00}, 4}, */
+		/* brightness or gain. 0 is default. 4 is good
+		 * indoors at night with incandescent lighting */
+		{{0x11, 0x0f, 0x04, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x10, 0x06, 0x00, 0x00, 0x00}, 4}, /*hstart or hoffs*/
+		{{0x11, 0x11, 0x06, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x14, 0x02, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x13, 0x01, 0x00, 0x00, 0x00}, 4},
+		/* {{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1}, observed */
+		{{0x1b, 0x02, 0x11, 0x00, 0x00, 0x00}, 1}, /* brighter */
+		/* {{0x1b, 0x13, 0x01, 0x00, 0x00, 0x00}, 1}, observed */
+		{{0x1b, 0x13, 0x11, 0x00, 0x00, 0x00}, 1},
+		{{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1}, /* compresses */
+		/* Camera should start to capture now. */
+	};
+
+	return run_start_commands(gspca_dev, spy_start_commands,
+				  ARRAY_SIZE(spy_start_commands));
+}
+
+static int start_cif_cam(struct gspca_dev *gspca_dev)
+{
+	struct init_command cif_start_commands[] = {
+		{{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
+		/* The entire sequence below seems redundant */
+		/* {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x22, 0x01, 0x06, 0x00, 0x00}, 4},
+		{{0x13, 0x23, 0x01, 0x02, 0x00, 0x00}, 4},
+		{{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4}, width?
+		{{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4}, height?
+		{{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4}, subsample?
+		{{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x29, 0x01, 0x20, 0x00, 0x00}, 4},
+		{{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
+		{{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
+		{{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
+		{{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
+		{{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
+		{{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},*/
+		{{0x1b, 0x21, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x17, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x19, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x03, 0x5a, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x04, 0x27, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x05, 0x01, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x12, 0x14, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x13, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x14, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x15, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x16, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x77, 0xa2, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x06, 0x0f, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x07, 0x14, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x08, 0x0f, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x09, 0x10, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x0f, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x12, 0x07, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x10, 0x1f, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1},
+		{{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 1}, /* width/8 */
+		{{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 1}, /* height/8 */
+		/* {{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4}, subsample?
+		 * {{0x13, 0x28, 0x01, 0x1e, 0x00, 0x00}, 4}, does nothing
+		 * {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4}, */
+		/* {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4},
+		 * causes subsampling
+		 * but not a change in the resolution setting! */
+		{{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
+		{{0x13, 0x2d, 0x01, 0x01, 0x00, 0x00}, 4},
+		{{0x13, 0x2e, 0x01, 0x08, 0x00, 0x00}, 4},
+		{{0x13, 0x2f, 0x01, 0x06, 0x00, 0x00}, 4},
+		{{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x1b, 0x04, 0x6d, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x05, 0x03, 0x00, 0x00, 0x00}, 1},
+		{{0x20, 0x36, 0x06, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x0e, 0x01, 0x00, 0x00, 0x00}, 1},
+		{{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x1b, 0x0f, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x20, 0x36, 0x05, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x10, 0x0f, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1},
+		{{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1},/* use compression */
+		/* Camera should start to capture now. */
+	};
+
+	return run_start_commands(gspca_dev, cif_start_commands,
+				  ARRAY_SIZE(cif_start_commands));
+}
+
+static int start_ms350_cam(struct gspca_dev *gspca_dev)
+{
+	struct init_command ms350_start_commands[] = {
+		{{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x16, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x22, 0x01, 0x04, 0x00, 0x00}, 4},
+		{{0x13, 0x23, 0x01, 0x03, 0x00, 0x00}, 4},
+		{{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4},
+		{{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4},
+		{{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4},
+		{{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4},
+		{{0x13, 0x29, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
+		{{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
+		{{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
+		{{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
+		{{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
+		{{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x00, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x01, 0x70, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x02, 0x05, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x03, 0x5d, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x04, 0x07, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x05, 0x25, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x06, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x07, 0x09, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x08, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x09, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x0b, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x0c, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x0d, 0x0c, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x0e, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x0f, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x11, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x13, 0x63, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x15, 0x70, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x18, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x11, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4}, /* width  */
+		{{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4}, /* height */
+		{{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4}, /* vstart? */
+		{{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4},
+		{{0x13, 0x29, 0x01, 0x40, 0x00, 0x00}, 4}, /* hstart? */
+		{{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
+		{{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
+		{{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
+		{{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
+		{{0x1b, 0x02, 0x05, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1},
+		{{0x20, 0x18, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x02, 0x0a, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 0},
+		/* Camera should start to capture now. */
+	};
+
+	return run_start_commands(gspca_dev, ms350_start_commands,
+				  ARRAY_SIZE(ms350_start_commands));
+}
+
+static int start_genius_cam(struct gspca_dev *gspca_dev)
+{
+	struct init_command genius_start_commands[] = {
+		{{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x16, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x10, 0x00, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4},
+		{{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4},
+		/* "preliminary" width and height settings */
+		{{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
+		{{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
+		{{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4},
+		{{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
+		{{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4},
+		{{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4},
+		{{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4},
+		{{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x11, 0x64, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x13, 0x91, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x15, 0x20, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x16, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x17, 0x60, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x25, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x26, 0x02, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x27, 0x88, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x30, 0x38, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x31, 0x2a, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x32, 0x2a, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x33, 0x2a, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x34, 0x02, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x5b, 0x0a, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4}, /* real width */
+		{{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4}, /* real height */
+		{{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
+		{{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
+		{{0x13, 0x29, 0x01, 0x62, 0x00, 0x00}, 4},
+		{{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
+		{{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
+		{{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
+		{{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
+		{{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x21, 0x2a, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x23, 0x28, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x11, 0x04, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x13, 0x03, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x15, 0xe0, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x16, 0x02, 0x00, 0x00, 0x00}, 4},
+		{{0x11, 0x17, 0x80, 0x00, 0x00, 0x00}, 4},
+		{{0x1c, 0x20, 0x00, 0x2a, 0x00, 0x00}, 1},
+		{{0x1c, 0x20, 0x00, 0x2a, 0x00, 0x00}, 1},
+		{{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 0}
+		/* Camera should start to capture now. */
+	};
+
+	return run_start_commands(gspca_dev, genius_start_commands,
+				  ARRAY_SIZE(genius_start_commands));
+}
+
+static int start_vivitar_cam(struct gspca_dev *gspca_dev)
+{
+	struct init_command vivitar_start_commands[] = {
+		{{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x22, 0x01, 0x01, 0x00, 0x00}, 4},
+		{{0x13, 0x23, 0x01, 0x01, 0x00, 0x00}, 4},
+		{{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4},
+		{{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4},
+		{{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
+		{{0x13, 0x28, 0x01, 0x0a, 0x00, 0x00}, 4},
+		/*
+		 * Above is changed from OEM 0x0b. Fixes Bayer tiling.
+		 * Presumably gives a vertical shift of one row.
+		 */
+		{{0x13, 0x29, 0x01, 0x20, 0x00, 0x00}, 4},
+		/* Above seems to do horizontal shift. */
+		{{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
+		{{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
+		{{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
+		{{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
+		/* Above three commands seem to relate to brightness. */
+		{{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
+		{{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x1b, 0x12, 0x80, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x01, 0x77, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x02, 0x3a, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x12, 0x78, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x13, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x14, 0x80, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x15, 0x34, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x1b, 0x04, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x20, 0x44, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x23, 0xee, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x26, 0xa0, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x27, 0x9a, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x28, 0xa0, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x29, 0x30, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x2a, 0x80, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x2b, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x2f, 0x3d, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x30, 0x24, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x32, 0x86, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x60, 0xa9, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x61, 0x42, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x65, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x69, 0x38, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x6f, 0x88, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x70, 0x0b, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x71, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x74, 0x21, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x75, 0x86, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x76, 0x00, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x7d, 0xf3, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x17, 0x1c, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x18, 0xc0, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x19, 0x05, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x1a, 0xf6, 0x00, 0x00, 0x00}, 1},
+		/* {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4},
+		{{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4},
+		{{0x13, 0x28, 0x01, 0x0b, 0x00, 0x00}, 4}, */
+		{{0x20, 0x36, 0x06, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x10, 0x26, 0x00, 0x00, 0x00}, 1},
+		{{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x1b, 0x76, 0x03, 0x00, 0x00, 0x00}, 1},
+		{{0x20, 0x36, 0x05, 0x00, 0x00, 0x00}, 1},
+		{{0x1b, 0x00, 0x3f, 0x00, 0x00, 0x00}, 1},
+		/* Above is brightness; OEM driver setting is 0x10 */
+		{{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4},
+		{{0x20, 0x29, 0x30, 0x00, 0x00, 0x00}, 1},
+		{{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1}
+	};
+
+	return run_start_commands(gspca_dev, vivitar_start_commands,
+				  ARRAY_SIZE(vivitar_start_commands));
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int err_code;
+
+	sd->sof_read = 0;
+
+	switch (sd->model) {
+	case 0x7005:
+		err_code = start_genius_cam(gspca_dev);
+		break;
+	case 0x8001:
+		err_code = start_spy_cam(gspca_dev);
+		break;
+	case 0x8003:
+		err_code = start_cif_cam(gspca_dev);
+		break;
+	case 0x8008:
+		err_code = start_ms350_cam(gspca_dev);
+		break;
+	case 0x800a:
+		err_code = start_vivitar_cam(gspca_dev);
+		break;
+	default:
+		PDEBUG(D_ERR, "Starting unknown camera, please report this");
+		return -ENXIO;
+	}
+
+	return err_code;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+	int result;
+	__u8 data[6];
+
+	result = sn9c2028_read1(gspca_dev);
+	if (result < 0)
+		PDEBUG(D_ERR, "Camera Stop read failed");
+
+	memset(data, 0, 6);
+	data[0] = 0x14;
+	result = sn9c2028_command(gspca_dev, data);
+	if (result < 0)
+		PDEBUG(D_ERR, "Camera Stop command failed");
+}
+
+/* Include sn9c2028 sof detection functions */
+#include "sn9c2028.h"
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+			__u8 *data,			/* isoc packet */
+			int len)			/* iso packet length */
+{
+	unsigned char *sof;
+
+	sof = sn9c2028_find_sof(gspca_dev, data, len);
+	if (sof) {
+		int n;
+
+		/* finish decoding current frame */
+		n = sof - data;
+		if (n > sizeof sn9c2028_sof_marker)
+			n -= sizeof sn9c2028_sof_marker;
+		else
+			n = 0;
+		gspca_frame_add(gspca_dev, LAST_PACKET, data, n);
+		/* Start next frame. */
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
+			sn9c2028_sof_marker, sizeof sn9c2028_sof_marker);
+		len -= sof - data;
+		data = sof;
+	}
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+	.name = MODULE_NAME,
+	.ctrls = sd_ctrls,
+	.nctrls = ARRAY_SIZE(sd_ctrls),
+	.config = sd_config,
+	.init = sd_init,
+	.start = sd_start,
+	.stopN = sd_stopN,
+	.pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+static const __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x0458, 0x7005)}, /* Genius Smart 300, version 2 */
+	/* The Genius Smart is untested. I can't find an owner ! */
+	/* {USB_DEVICE(0x0c45, 0x8000)}, DC31VC, Don't know this camera */
+	{USB_DEVICE(0x0c45, 0x8001)}, /* Wild Planet digital spy cam */
+	{USB_DEVICE(0x0c45, 0x8003)}, /* Several small CIF cameras */
+	/* {USB_DEVICE(0x0c45, 0x8006)}, Unknown VGA camera */
+	{USB_DEVICE(0x0c45, 0x8008)}, /* Mini-Shotz ms-350 */
+	{USB_DEVICE(0x0c45, 0x800a)}, /* Vivicam 3350B */
+	{}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+			const struct usb_device_id *id)
+{
+	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+			       THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+	.name = MODULE_NAME,
+	.id_table = device_table,
+	.probe = sd_probe,
+	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+	int ret;
+
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
+	PDEBUG(D_PROBE, "registered");
+	return 0;
+}
+
+static void __exit sd_mod_exit(void)
+{
+	usb_deregister(&sd_driver);
+	PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sn9c2028.h linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sn9c2028.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sn9c2028.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sn9c2028.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,51 @@
+/*
+ * SN9C2028 common functions
+ *
+ * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn,edu>
+ *
+ * Based closely upon the file gspca/pac_common.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+static const unsigned char sn9c2028_sof_marker[5] =
+	{ 0xff, 0xff, 0x00, 0xc4, 0xc4 };
+
+static unsigned char *sn9c2028_find_sof(struct gspca_dev *gspca_dev,
+					unsigned char *m, int len)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int i;
+
+	/* Search for the SOF marker (fixed part) in the header */
+	for (i = 0; i < len; i++) {
+		if (m[i] == sn9c2028_sof_marker[sd->sof_read]) {
+			sd->sof_read++;
+			if (sd->sof_read == sizeof(sn9c2028_sof_marker)) {
+				PDEBUG(D_FRAM,
+					"SOF found, bytes to analyze: %u."
+					" Frame starts at byte #%u",
+					len, i + 1);
+				sd->sof_read = 0;
+				return m + i + 1;
+			}
+		} else {
+			sd->sof_read = 0;
+		}
+	}
+
+	return NULL;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sn9c20x.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sn9c20x.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sn9c20x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sn9c20x.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/freezer.h>
 #include <linux/usb/input.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 #endif
 
 #include "gspca.h"
@@ -129,7 +130,7 @@ static int sd_getexposure(struct gspca_d
 static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
 static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 	{
 #define BRIGHTNESS_IDX 0
 	    {
@@ -1426,7 +1427,7 @@ static int input_kthread(void *data)
 	struct gspca_dev *gspca_dev = (struct gspca_dev *)data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	DECLARE_WAIT_QUEUE_HEAD(wait);
+	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait);
 	set_freezable();
 	for (;;) {
 		if (kthread_should_stop())
@@ -1506,36 +1507,36 @@ static int set_cmatrix(struct gspca_dev
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 hue_coord, hue_index = 180 + sd->hue;
 	u8 cmatrix[21];
-	memset(cmatrix, 0, 21);
 
+	memset(cmatrix, 0, sizeof cmatrix);
 	cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26;
 	cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
 	cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
 	cmatrix[18] = sd->brightness - 0x80;
 
 	hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8;
-	cmatrix[6] = (unsigned char)(hue_coord & 0xff);
-	cmatrix[7] = (unsigned char)((hue_coord >> 8) & 0x0f);
+	cmatrix[6] = hue_coord;
+	cmatrix[7] = (hue_coord >> 8) & 0x0f;
 
 	hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8;
-	cmatrix[8] = (unsigned char)(hue_coord & 0xff);
-	cmatrix[9] = (unsigned char)((hue_coord >> 8) & 0x0f);
+	cmatrix[8] = hue_coord;
+	cmatrix[9] = (hue_coord >> 8) & 0x0f;
 
 	hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8;
-	cmatrix[10] = (unsigned char)(hue_coord & 0xff);
-	cmatrix[11] = (unsigned char)((hue_coord >> 8) & 0x0f);
+	cmatrix[10] = hue_coord;
+	cmatrix[11] = (hue_coord >> 8) & 0x0f;
 
 	hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8;
-	cmatrix[12] = (unsigned char)(hue_coord & 0xff);
-	cmatrix[13] = (unsigned char)((hue_coord >> 8) & 0x0f);
+	cmatrix[12] = hue_coord;
+	cmatrix[13] = (hue_coord >> 8) & 0x0f;
 
 	hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8;
-	cmatrix[14] = (unsigned char)(hue_coord & 0xff);
-	cmatrix[15] = (unsigned char)((hue_coord >> 8) & 0x0f);
+	cmatrix[14] = hue_coord;
+	cmatrix[15] = (hue_coord >> 8) & 0x0f;
 
 	hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8;
-	cmatrix[16] = (unsigned char)(hue_coord & 0xff);
-	cmatrix[17] = (unsigned char)((hue_coord >> 8) & 0x0f);
+	cmatrix[16] = hue_coord;
+	cmatrix[17] = (hue_coord >> 8) & 0x0f;
 
 	return reg_w(gspca_dev, 0x10e1, cmatrix, 21);
 }
@@ -2015,6 +2016,7 @@ static int sd_config(struct gspca_dev *g
 	default:
 		cam->cam_mode = vga_mode;
 		cam->nmodes = ARRAY_SIZE(vga_mode);
+		break;
 	}
 
 	sd->old_step = 0;
@@ -2319,7 +2321,7 @@ static void do_autogain(struct gspca_dev
 		}
 	}
 	if (avg_lum > MAX_AVG_LUM) {
-		if (sd->gain >= 1) {
+		if (sd->gain > 0) {
 			sd->gain--;
 			set_gain(gspca_dev);
 		}
@@ -2347,7 +2349,7 @@ static void sd_pkt_scan(struct gspca_dev
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int avg_lum;
-	static unsigned char frame_header[] =
+	static u8 frame_header[] =
 		{0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
 	if (len == 64 && memcmp(data, frame_header, 6) == 0) {
 		avg_lum = ((data[35] >> 2) & 3) |
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sonixb.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sonixb.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sonixb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sonixb.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@ Reg	Use
 
 #define MODULE_NAME "sonixb"
 
+#include <linux/input.h>
 #include "gspca.h"
 
 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
@@ -53,9 +54,11 @@ struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
 	atomic_t avg_lum;
 	int prev_avg_lum;
+	int exp_too_low_cnt;
+	int exp_too_high_cnt;
 
+	unsigned short exposure;
 	unsigned char gain;
-	unsigned char exposure;
 	unsigned char brightness;
 	unsigned char autogain;
 	unsigned char autogain_ignore_frames;
@@ -73,8 +76,9 @@ struct sd {
 #define SENSOR_OV7630 2
 #define SENSOR_PAS106 3
 #define SENSOR_PAS202 4
-#define SENSOR_TAS5110 5
-#define SENSOR_TAS5130CXX 6
+#define SENSOR_TAS5110C 5
+#define SENSOR_TAS5110D 6
+#define SENSOR_TAS5130CXX 7
 	__u8 reg11;
 };
 
@@ -95,13 +99,15 @@ struct sensor_data {
 /* sensor_data flags */
 #define F_GAIN 0x01		/* has gain */
 #define F_SIF  0x02		/* sif or vga */
+#define F_COARSE_EXPO 0x04	/* exposure control is coarse */
 
 /* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
 #define MODE_RAW 0x10		/* raw bayer mode */
 #define MODE_REDUCED_SIF 0x20	/* vga mode (320x240 / 160x120) on sif cam */
 
 /* ctrl_dis helper macros */
-#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX))
+#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << COARSE_EXPOSURE_IDX) | \
+		 (1 << AUTOGAIN_IDX))
 #define NO_FREQ (1 << FREQ_IDX)
 #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
 
@@ -127,11 +133,10 @@ struct sensor_data {
 }
 
 /* We calculate the autogain at the end of the transfer of a frame, at this
-   moment a frame with the old settings is being transmitted, and a frame is
-   being captured with the old settings. So if we adjust the autogain we must
-   ignore atleast the 2 next frames for the new settings to come into effect
-   before doing any other adjustments */
-#define AUTOGAIN_IGNORE_FRAMES 3
+   moment a frame with the old settings is being captured and transmitted. So
+   if we adjust the gain or exposure we must ignore atleast the next frame for
+   the new settings to come into effect before doing any other adjustments. */
+#define AUTOGAIN_IGNORE_FRAMES 1
 
 /* V4L2 controls supported by the driver */
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
@@ -145,7 +150,7 @@ static int sd_getautogain(struct gspca_d
 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 #define BRIGHTNESS_IDX 0
 	{
 	    {
@@ -171,7 +176,7 @@ static struct ctrl sd_ctrls[] = {
 		.maximum = 255,
 		.step    = 1,
 #define GAIN_DEF 127
-#define GAIN_KNEE 200
+#define GAIN_KNEE 230
 		.default_value = GAIN_DEF,
 	    },
 	    .set = sd_setgain,
@@ -183,10 +188,10 @@ static struct ctrl sd_ctrls[] = {
 			.id = V4L2_CID_EXPOSURE,
 			.type = V4L2_CTRL_TYPE_INTEGER,
 			.name = "Exposure",
-#define EXPOSURE_DEF  16 /*  32 ms / 30 fps */
-#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
+#define EXPOSURE_DEF  66 /*  33 ms / 30 fps (except on PASXXX) */
+#define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */
 			.minimum = 0,
-			.maximum = 255,
+			.maximum = 1023,
 			.step = 1,
 			.default_value = EXPOSURE_DEF,
 			.flags = 0,
@@ -194,7 +199,23 @@ static struct ctrl sd_ctrls[] = {
 		.set = sd_setexposure,
 		.get = sd_getexposure,
 	},
-#define AUTOGAIN_IDX 3
+#define COARSE_EXPOSURE_IDX 3
+	{
+		{
+			.id = V4L2_CID_EXPOSURE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "Exposure",
+#define COARSE_EXPOSURE_DEF  2 /* 30 fps */
+			.minimum = 2,
+			.maximum = 15,
+			.step = 1,
+			.default_value = COARSE_EXPOSURE_DEF,
+			.flags = 0,
+		},
+		.set = sd_setexposure,
+		.get = sd_getexposure,
+	},
+#define AUTOGAIN_IDX 4
 	{
 		{
 			.id = V4L2_CID_AUTOGAIN,
@@ -210,7 +231,7 @@ static struct ctrl sd_ctrls[] = {
 		.set = sd_setautogain,
 		.get = sd_getautogain,
 	},
-#define FREQ_IDX 4
+#define FREQ_IDX 5
 	{
 		{
 			.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -219,7 +240,7 @@ static struct ctrl sd_ctrls[] = {
 			.minimum = 0,
 			.maximum = 2,	/* 0: 0, 1: 50Hz, 2:60Hz */
 			.step    = 1,
-#define FREQ_DEF 1
+#define FREQ_DEF 0
 			.default_value = FREQ_DEF,
 		},
 		.set = sd_setfreq,
@@ -345,7 +366,7 @@ static const __u8 initOv7630[] = {
 };
 static const __u8 initOv7630_3[] = {
 	0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80,	/* r01 .. r08 */
-	0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,	/* r09 .. r10 */
+	0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* r09 .. r10 */
 	0x00, 0x02, 0x01, 0x0a,				/* r11 .. r14 */
 	0x28, 0x1e,			/* H & V sizes     r15 .. r16 */
 	0x68, 0x8f, MCK_INIT1,				/* r17 .. r19 */
@@ -387,6 +408,30 @@ static const __u8 initPas106[] = {
 	0x18, 0x10, 0x02, 0x02, 0x09, 0x07
 };
 /* compression 0x86 mckinit1 0x2b */
+
+/* "Known" PAS106B registers:
+  0x02 clock divider
+  0x03 Variable framerate bits 4-11
+  0x04 Var framerate bits 0-3, one must leave the 4 msb's at 0 !!
+       The variable framerate control must never be set lower then 300,
+       which sets the framerate at 90 / reg02, otherwise vsync is lost.
+  0x05 Shutter Time Line Offset, this can be used as an exposure control:
+       0 = use full frame time, 255 = no exposure at all
+       Note this may never be larger then "var-framerate control" / 2 - 2.
+       When var-framerate control is < 514, no exposure is reached at the max
+       allowed value for the framerate control value, rather then at 255.
+  0x06 Shutter Time Pixel Offset, like reg05 this influences exposure, but
+       only a very little bit, leave at 0xcd
+  0x07 offset sign bit (bit0 1 > negative offset)
+  0x08 offset
+  0x09 Blue Gain
+  0x0a Green1 Gain
+  0x0b Green2 Gain
+  0x0c Red Gain
+  0x0e Global gain
+  0x13 Write 1 to commit settings to sensor
+*/
+
 static const __u8 pas106_sensor_init[][8] = {
 	/* Pixel Clock Divider 6 */
 	{ 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
@@ -433,37 +478,55 @@ static const __u8 initPas202[] = {
 	0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
 	0x00, 0x00,
 	0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
-	0x28, 0x1e, 0x28, 0x89, 0x20,
+	0x28, 0x1e, 0x20, 0x89, 0x20,
 	0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
 };
+
+/* "Known" PAS202BCB registers:
+  0x02 clock divider
+  0x04 Variable framerate bits 6-11 (*)
+  0x05 Var framerate  bits 0-5, one must leave the 2 msb's at 0 !!
+  0x07 Blue Gain
+  0x08 Green Gain
+  0x09 Red Gain
+  0x0b offset sign bit (bit0 1 > negative offset)
+  0x0c offset
+  0x0e Unknown image is slightly brighter when bit 0 is 0, if reg0f is 0 too,
+       leave at 1 otherwise we get a jump in our exposure control
+  0x0f Exposure 0-255, 0 = use full frame time, 255 = no exposure at all
+  0x10 Master gain 0 - 31
+  0x11 write 1 to apply changes
+  (*) The variable framerate control must never be set lower then 500
+      which sets the framerate at 30 / reg02, otherwise vsync is lost.
+*/
 static const __u8 pas202_sensor_init[][8] = {
-	{0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10},
+	/* Set the clock divider to 4 -> 30 / 4 = 7.5 fps, we would like
+	   to set it lower, but for some reason the bridge starts missing
+	   vsync's then */
+	{0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10},
 	{0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
 	{0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
-	{0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10},
+	{0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x01, 0x32, 0x10},
 	{0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
 	{0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
 	{0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
 	{0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
 	{0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
 	{0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
-	{0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
-	{0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
-
-	{0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
-	{0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
-	{0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
-	{0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
-	{0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
-	{0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
-	{0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
-	{0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
 };
 
-static const __u8 initTas5110[] = {
+static const __u8 initTas5110c[] = {
 	0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
 	0x00, 0x00,
-	0x00, 0x01, 0x00, 0x45, 0x09, 0x0a,
+	0x00, 0x00, 0x00, 0x45, 0x09, 0x0a,
+	0x16, 0x12, 0x60, 0x86, 0x2b,
+	0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
+};
+/* Same as above, except a different hstart */
+static const __u8 initTas5110d[] = {
+	0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
+	0x00, 0x00,
+	0x00, 0x00, 0x00, 0x41, 0x09, 0x0a,
 	0x16, 0x12, 0x60, 0x86, 0x2b,
 	0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
 };
@@ -476,7 +539,7 @@ static const __u8 tas5110_sensor_init[][
 static const __u8 initTas5130[] = {
 	0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
 	0x00, 0x00,
-	0x00, 0x01, 0x00, 0x68, 0x0c, 0x0a,
+	0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a,
 	0x28, 0x1e, 0x60, COMP, MCK_INIT,
 	0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
 };
@@ -493,12 +556,14 @@ SENS(initHv7131, NULL, hv7131_sensor_ini
 SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
 SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
 	F_GAIN, 0, 0x21),
-SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ,
+SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_GAIN|F_SIF, NO_FREQ,
 	0),
-SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0,
-	NO_EXPO|NO_FREQ, 0),
-SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF,
-	NO_BRIGHTNESS|NO_FREQ, 0),
+SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_GAIN,
+	NO_FREQ, 0),
+SENS(initTas5110c, NULL, tas5110_sensor_init, NULL, NULL,
+	F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
+SENS(initTas5110d, NULL, tas5110_sensor_init, NULL, NULL,
+	F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
 SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
 	0),
 };
@@ -587,42 +652,28 @@ static void setbrightness(struct gspca_d
 			goto err;
 		break;
 	    }
-	case SENSOR_PAS106: {
-		__u8 i2c1[] =
-			{0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
-
-		i2c1[3] = sd->brightness >> 3;
-		i2c1[2] = 0x0e;
-		if (i2c_w(gspca_dev, i2c1) < 0)
-			goto err;
-		i2c1[3] = 0x01;
-		i2c1[2] = 0x13;
-		if (i2c_w(gspca_dev, i2c1) < 0)
-			goto err;
-		break;
-	    }
+	case SENSOR_PAS106:
 	case SENSOR_PAS202: {
-		/* __u8 i2cpexpo1[] =
-			{0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
-		__u8 i2cpexpo[] =
-			{0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
-		__u8 i2cp202[] =
-			{0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
-		static __u8 i2cpdoit[] =
-			{0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
+		__u8 i2cpbright[] =
+			{0xb0, 0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x16};
+		__u8 i2cpdoit[] =
+			{0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
 
-		/* change reg 0x10 */
-		i2cpexpo[4] = 0xff - sd->brightness;
-/*		if(i2c_w(gspca_dev,i2cpexpo1) < 0)
-			goto err; */
-/*		if(i2c_w(gspca_dev,i2cpdoit) < 0)
-			goto err; */
-		if (i2c_w(gspca_dev, i2cpexpo) < 0)
-			goto err;
-		if (i2c_w(gspca_dev, i2cpdoit) < 0)
-			goto err;
-		i2cp202[3] = sd->brightness >> 3;
-		if (i2c_w(gspca_dev, i2cp202) < 0)
+		/* PAS106 uses reg 7 and 8 instead of b and c */
+		if (sd->sensor == SENSOR_PAS106) {
+			i2cpbright[2] = 7;
+			i2cpdoit[2] = 0x13;
+		}
+
+		if (sd->brightness < 127) {
+			/* change reg 0x0b, signreg */
+			i2cpbright[3] = 0x01;
+			/* set reg 0x0c, offset */
+			i2cpbright[4] = 127 - sd->brightness;
+		} else
+			i2cpbright[4] = sd->brightness - 127;
+
+		if (i2c_w(gspca_dev, i2cpbright) < 0)
 			goto err;
 		if (i2c_w(gspca_dev, i2cpdoit) < 0)
 			goto err;
@@ -652,7 +703,8 @@ static void setsensorgain(struct gspca_d
 
 	switch (sd->sensor) {
 
-	case SENSOR_TAS5110: {
+	case SENSOR_TAS5110C:
+	case SENSOR_TAS5110D: {
 		__u8 i2c[] =
 			{0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
 
@@ -674,6 +726,37 @@ static void setsensorgain(struct gspca_d
 			goto err;
 		break;
 	    }
+	case SENSOR_PAS106:
+	case SENSOR_PAS202: {
+		__u8 i2cpgain[] =
+			{0xa0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15};
+		__u8 i2cpcolorgain[] =
+			{0xc0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x15};
+		__u8 i2cpdoit[] =
+			{0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
+
+		/* PAS106 uses different regs (and has split green gains) */
+		if (sd->sensor == SENSOR_PAS106) {
+			i2cpgain[2] = 0x0e;
+			i2cpcolorgain[0] = 0xd0;
+			i2cpcolorgain[2] = 0x09;
+			i2cpdoit[2] = 0x13;
+		}
+
+		i2cpgain[3] = sd->gain >> 3;
+		i2cpcolorgain[3] = sd->gain >> 4;
+		i2cpcolorgain[4] = sd->gain >> 4;
+		i2cpcolorgain[5] = sd->gain >> 4;
+		i2cpcolorgain[6] = sd->gain >> 4;
+
+		if (i2c_w(gspca_dev, i2cpgain) < 0)
+			goto err;
+		if (i2c_w(gspca_dev, i2cpcolorgain) < 0)
+			goto err;
+		if (i2c_w(gspca_dev, i2cpdoit) < 0)
+			goto err;
+		break;
+	    }
 	}
 	return;
 err:
@@ -684,19 +767,21 @@ static void setgain(struct gspca_dev *gs
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	__u8 gain;
-	__u8 rgb_value;
+	__u8 buf[2] = { 0, 0 };
+
+	if (sensor_data[sd->sensor].flags & F_GAIN) {
+		/* Use the sensor gain to do the actual gain */
+		setsensorgain(gspca_dev);
+		return;
+	}
 
 	gain = sd->gain >> 4;
 
 	/* red and blue gain */
-	rgb_value = gain << 4 | gain;
-	reg_w(gspca_dev, 0x10, &rgb_value, 1);
+	buf[0] = gain << 4 | gain;
 	/* green gain */
-	rgb_value = gain;
-	reg_w(gspca_dev, 0x11, &rgb_value, 1);
-
-	if (sensor_data[sd->sensor].flags & F_GAIN)
-		setsensorgain(gspca_dev);
+	buf[1] = gain;
+	reg_w(gspca_dev, 0x10, buf, 2);
 }
 
 static void setexposure(struct gspca_dev *gspca_dev)
@@ -704,17 +789,12 @@ static void setexposure(struct gspca_dev
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	switch (sd->sensor) {
-	case SENSOR_TAS5110: {
-		__u8 reg;
-
+	case SENSOR_TAS5110C:
+	case SENSOR_TAS5110D: {
 		/* register 19's high nibble contains the sn9c10x clock divider
 		   The high nibble configures the no fps according to the
 		   formula: 60 / high_nibble. With a maximum of 30 fps */
-		reg = 120 * sd->exposure / 1000;
-		if (reg < 2)
-			reg = 2;
-		else if (reg > 15)
-			reg = 15;
+		__u8 reg = sd->exposure;
 		reg = (reg << 4) | 0x0b;
 		reg_w(gspca_dev, 0x19, &reg, 1);
 		break;
@@ -750,20 +830,21 @@ static void setexposure(struct gspca_dev
 		} else
 			reg10_max = 0x41;
 
-		reg11 = (60 * sd->exposure + 999) / 1000;
+		reg11 = (15 * sd->exposure + 999) / 1000;
 		if (reg11 < 1)
 			reg11 = 1;
 		else if (reg11 > 16)
 			reg11 = 16;
 
-		/* In 640x480, if the reg11 has less than 3, the image is
-		   unstable (not enough bandwidth). */
-		if (gspca_dev->width == 640 && reg11 < 3)
-			reg11 = 3;
+		/* In 640x480, if the reg11 has less than 4, the image is
+		   unstable (the bridge goes into a higher compression mode
+		   which we have not reverse engineered yet). */
+		if (gspca_dev->width == 640 && reg11 < 4)
+			reg11 = 4;
 
 		/* frame exposure time in ms = 1000 * reg11 / 30    ->
-		reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
-		reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
+		reg10 = (sd->exposure / 2) * reg10_max / (1000 * reg11 / 30) */
+		reg10 = (sd->exposure * 15 * reg10_max) / (1000 * reg11);
 
 		/* Don't allow this to get below 10 when using autogain, the
 		   steps become very large (relatively) when below 10 causing
@@ -786,10 +867,85 @@ static void setexposure(struct gspca_dev
 		if (i2c_w(gspca_dev, i2c) == 0)
 			sd->reg11 = reg11;
 		else
-			PDEBUG(D_ERR, "i2c error exposure");
+			goto err;
+		break;
+	    }
+	case SENSOR_PAS202: {
+		__u8 i2cpframerate[] =
+			{0xb0, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x16};
+		__u8 i2cpexpo[] =
+			{0xa0, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x16};
+		const __u8 i2cpdoit[] =
+			{0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
+		int framerate_ctrl;
+
+		/* The exposure knee for the autogain algorithm is 200
+		   (100 ms / 10 fps on other sensors), for values below this
+		   use the control for setting the partial frame expose time,
+		   above that use variable framerate. This way we run at max
+		   framerate (640x480@7.5 fps, 320x240@10fps) until the knee
+		   is reached. Using the variable framerate control above 200
+		   is better then playing around with both clockdiv + partial
+		   frame exposure times (like we are doing with the ov chips),
+		   as that sometimes leads to jumps in the exposure control,
+		   which are bad for auto exposure. */
+		if (sd->exposure < 200) {
+			i2cpexpo[3] = 255 - (sd->exposure * 255) / 200;
+			framerate_ctrl = 500;
+		} else {
+			/* The PAS202's exposure control goes from 0 - 4095,
+			   but anything below 500 causes vsync issues, so scale
+			   our 200-1023 to 500-4095 */
+			framerate_ctrl = (sd->exposure - 200) * 1000 / 229 +
+					 500;
+		}
+
+		i2cpframerate[3] = framerate_ctrl >> 6;
+		i2cpframerate[4] = framerate_ctrl & 0x3f;
+		if (i2c_w(gspca_dev, i2cpframerate) < 0)
+			goto err;
+		if (i2c_w(gspca_dev, i2cpexpo) < 0)
+			goto err;
+		if (i2c_w(gspca_dev, i2cpdoit) < 0)
+			goto err;
+		break;
+	    }
+	case SENSOR_PAS106: {
+		__u8 i2cpframerate[] =
+			{0xb1, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x14};
+		__u8 i2cpexpo[] =
+			{0xa1, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x14};
+		const __u8 i2cpdoit[] =
+			{0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14};
+		int framerate_ctrl;
+
+		/* For values below 150 use partial frame exposure, above
+		   that use framerate ctrl */
+		if (sd->exposure < 150) {
+			i2cpexpo[3] = 150 - sd->exposure;
+			framerate_ctrl = 300;
+		} else {
+			/* The PAS106's exposure control goes from 0 - 4095,
+			   but anything below 300 causes vsync issues, so scale
+			   our 150-1023 to 300-4095 */
+			framerate_ctrl = (sd->exposure - 150) * 1000 / 230 +
+					 300;
+		}
+
+		i2cpframerate[3] = framerate_ctrl >> 4;
+		i2cpframerate[4] = framerate_ctrl & 0x0f;
+		if (i2c_w(gspca_dev, i2cpframerate) < 0)
+			goto err;
+		if (i2c_w(gspca_dev, i2cpexpo) < 0)
+			goto err;
+		if (i2c_w(gspca_dev, i2cpdoit) < 0)
+			goto err;
 		break;
 	    }
 	}
+	return;
+err:
+	PDEBUG(D_ERR, "i2c error exposure");
 }
 
 static void setfreq(struct gspca_dev *gspca_dev)
@@ -823,30 +979,43 @@ static void setfreq(struct gspca_dev *gs
 	}
 }
 
+#include "coarse_expo_autogain.h"
+
 static void do_autogain(struct gspca_dev *gspca_dev)
 {
-	int deadzone, desired_avg_lum;
+	int deadzone, desired_avg_lum, result;
 	struct sd *sd = (struct sd *) gspca_dev;
 	int avg_lum = atomic_read(&sd->avg_lum);
 
-	if (avg_lum == -1)
+	if (avg_lum == -1 || !sd->autogain)
 		return;
 
+	if (sd->autogain_ignore_frames > 0) {
+		sd->autogain_ignore_frames--;
+		return;
+	}
+
 	/* SIF / VGA sensors have a different autoexposure area and thus
 	   different avg_lum values for the same picture brightness */
 	if (sensor_data[sd->sensor].flags & F_SIF) {
-		deadzone = 1000;
-		desired_avg_lum = 7000;
+		deadzone = 500;
+		/* SIF sensors tend to overexpose, so keep this small */
+		desired_avg_lum = 5000;
 	} else {
-		deadzone = 3000;
-		desired_avg_lum = 23000;
+		deadzone = 1500;
+		desired_avg_lum = 18000;
 	}
 
-	if (sd->autogain_ignore_frames > 0)
-		sd->autogain_ignore_frames--;
-	else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
-			sd->brightness * desired_avg_lum / 127,
-			deadzone, GAIN_KNEE, EXPOSURE_KNEE)) {
+	if (sensor_data[sd->sensor].flags & F_COARSE_EXPO)
+		result = gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
+				sd->brightness * desired_avg_lum / 127,
+				deadzone);
+	else
+		result = gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
+				sd->brightness * desired_avg_lum / 127,
+				deadzone, GAIN_KNEE, EXPOSURE_KNEE);
+
+	if (result) {
 		PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
 			(int)sd->gain, (int)sd->exposure);
 		sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
@@ -881,7 +1050,13 @@ static int sd_config(struct gspca_dev *g
 
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->gain = GAIN_DEF;
-	sd->exposure = EXPOSURE_DEF;
+	if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) {
+		sd->exposure = COARSE_EXPOSURE_DEF;
+		gspca_dev->ctrl_dis |= (1 << EXPOSURE_IDX);
+	} else {
+		sd->exposure = EXPOSURE_DEF;
+		gspca_dev->ctrl_dis |= (1 << COARSE_EXPOSURE_IDX);
+	}
 	if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
 		sd->autogain = 0; /* Disable do_autogain callback */
 	else
@@ -917,9 +1092,6 @@ static int sd_start(struct gspca_dev *gs
 	reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
 	/* Special cases where reg 17 and or 19 value depends on mode */
 	switch (sd->sensor) {
-	case SENSOR_PAS202:
-		reg12_19[5] = mode ? 0x24 : 0x20;
-		break;
 	case SENSOR_TAS5130CXX:
 		/* probably not mode specific at all most likely the upper
 		   nibble of 0x19 is exposure (clock divider) just as with
@@ -955,6 +1127,16 @@ static int sd_start(struct gspca_dev *gs
 			sensor_data[sd->sensor].sensor_bridge_init_size[
 				sd->bridge]);
 
+	/* Mode specific sensor setup */
+	switch (sd->sensor) {
+	case SENSOR_PAS202: {
+		const __u8 i2cpclockdiv[] =
+			{0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10};
+		/* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */
+		if (mode)
+			i2c_w(gspca_dev, i2cpclockdiv);
+	    }
+	}
 	/* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
 	reg_w(gspca_dev, 0x15, &reg12_19[3], 2);
 	/* compression register */
@@ -985,6 +1167,8 @@ static int sd_start(struct gspca_dev *gs
 
 	sd->frames_to_drop = 0;
 	sd->autogain_ignore_frames = 0;
+	sd->exp_too_high_cnt = 0;
+	sd->exp_too_low_cnt = 0;
 	atomic_set(&sd->avg_lum, -1);
 	return 0;
 }
@@ -1143,11 +1327,14 @@ static int sd_setautogain(struct gspca_d
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	sd->autogain = val;
+	sd->exp_too_high_cnt = 0;
+	sd->exp_too_low_cnt = 0;
+
 	/* when switching to autogain set defaults to make sure
 	   we are on a valid point of the autogain gain /
 	   exposure knee graph, and give this change time to
 	   take effect before doing autogain. */
-	if (sd->autogain) {
+	if (sd->autogain && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) {
 		sd->exposure = EXPOSURE_DEF;
 		sd->gain = GAIN_DEF;
 		if (gspca_dev->streaming) {
@@ -1207,6 +1394,25 @@ static int sd_querymenu(struct gspca_dev
 	return -EINVAL;
 }
 
+#ifdef CONFIG_INPUT
+static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,		/* interrupt packet data */
+			int len)		/* interrupt packet length */
+{
+	int ret = -EINVAL;
+
+	if (len == 1 && data[0] == 1) {
+		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
+		input_sync(gspca_dev->input_dev);
+		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
+		input_sync(gspca_dev->input_dev);
+		ret = 0;
+	}
+
+	return ret;
+}
+#endif
+
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
@@ -1219,6 +1425,9 @@ static const struct sd_desc sd_desc = {
 	.pkt_scan = sd_pkt_scan,
 	.querymenu = sd_querymenu,
 	.dq_callback = do_autogain,
+#ifdef CONFIG_INPUT
+	.int_pkt_scan = sd_int_pkt_scan,
+#endif
 };
 
 /* -- module initialisation -- */
@@ -1227,21 +1436,21 @@ static const struct sd_desc sd_desc = {
 
 
 static const struct usb_device_id device_table[] __devinitconst = {
-	{USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */
-	{USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */
+	{USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */
+	{USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
-	{USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, /* TAS5110D */
+	{USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */
+#endif
 	{USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
 	{USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
-#endif
 	{USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
 	{USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
 	{USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
 	{USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
+#endif
 	{USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
 	{USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
-#endif
 	{USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
 	{USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sonixj.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sonixj.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sonixj.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sonixj.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,8 @@
 
 #define MODULE_NAME "sonixj"
 
+#include <linux/input.h>
+#include <linux/slab.h>
 #include "gspca.h"
 #include "jpeg.h"
 
@@ -45,6 +47,7 @@ struct sd {
 	u8 red;
 	u8 gamma;
 	u8 vflip;			/* ov7630/ov7648 only */
+	u8 sharpness;
 	u8 infrared;			/* mt9v111 only */
 	u8 freq;			/* ov76xx only */
 	u8 quality;			/* image quality */
@@ -64,16 +67,17 @@ struct sd {
 #define BRIDGE_SN9C110 2
 #define BRIDGE_SN9C120 3
 	u8 sensor;			/* Type of image sensor chip */
-#define SENSOR_HV7131R 0
-#define SENSOR_MI0360 1
-#define SENSOR_MO4000 2
-#define SENSOR_MT9V111 3
-#define SENSOR_OM6802 4
-#define SENSOR_OV7630 5
-#define SENSOR_OV7648 6
-#define SENSOR_OV7660 7
-#define SENSOR_PO1030 8
-#define SENSOR_SP80708 9
+#define SENSOR_ADCM1700 0
+#define SENSOR_HV7131R 1
+#define SENSOR_MI0360 2
+#define SENSOR_MO4000 3
+#define SENSOR_MT9V111 4
+#define SENSOR_OM6802 5
+#define SENSOR_OV7630 6
+#define SENSOR_OV7648 7
+#define SENSOR_OV7660 8
+#define SENSOR_PO1030 9
+#define SENSOR_SP80708 10
 	u8 i2c_addr;
 
 	u8 *jpeg_hdr;
@@ -96,12 +100,14 @@ static int sd_setautogain(struct gspca_d
 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 #define BRIGHTNESS_IDX 0
 	{
 	    {
@@ -225,8 +231,23 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setvflip,
 	    .get = sd_getvflip,
 	},
+#define SHARPNESS_IDX 8
+	{
+	    {
+		.id	 = V4L2_CID_SHARPNESS,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Sharpness",
+		.minimum = 0,
+		.maximum = 255,
+		.step    = 1,
+#define SHARPNESS_DEF 90
+		.default_value = SHARPNESS_DEF,
+	    },
+	    .set = sd_setsharpness,
+	    .get = sd_getsharpness,
+	},
 /* mt9v111 only */
-#define INFRARED_IDX 8
+#define INFRARED_IDX 9
 	{
 	    {
 		.id      = V4L2_CID_INFRARED,
@@ -242,7 +263,7 @@ static struct ctrl sd_ctrls[] = {
 	    .get = sd_getinfrared,
 	},
 /* ov7630/ov7648/ov7660 only */
-#define FREQ_IDX 9
+#define FREQ_IDX 10
 	{
 	    {
 		.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -261,28 +282,37 @@ static struct ctrl sd_ctrls[] = {
 
 /* table of the disabled controls */
 static __u32 ctrl_dis[] = {
+	(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX) |
+			(1 << AUTOGAIN_IDX),	/* SENSOR_ADCM1700 0 */
+	(1 << INFRARED_IDX) | (1 << FREQ_IDX),
+						/* SENSOR_HV7131R 1 */
 	(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
-						/* SENSOR_HV7131R 0 */
-	(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
-						/* SENSOR_MI0360 1 */
+						/* SENSOR_MI0360 2 */
 	(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
-						/* SENSOR_MO4000 2 */
+						/* SENSOR_MO4000 3 */
 	(1 << VFLIP_IDX) | (1 << FREQ_IDX),
-						/* SENSOR_MT9V111 3 */
+						/* SENSOR_MT9V111 4 */
 	(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
-						/* SENSOR_OM6802 4 */
+						/* SENSOR_OM6802 5 */
 	(1 << INFRARED_IDX),
-						/* SENSOR_OV7630 5 */
+						/* SENSOR_OV7630 6 */
 	(1 << INFRARED_IDX),
-						/* SENSOR_OV7648 6 */
+						/* SENSOR_OV7648 7 */
 	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
-						/* SENSOR_OV7660 7 */
+						/* SENSOR_OV7660 8 */
 	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
-			      (1 << FREQ_IDX),	/* SENSOR_PO1030 8 */
+			      (1 << FREQ_IDX),	/* SENSOR_PO1030 9 */
 	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
-			      (1 << FREQ_IDX),	/* SENSOR_SP80708 9 */
+			      (1 << FREQ_IDX),	/* SENSOR_SP80708 10 */
 };
 
+static const struct v4l2_pix_format cif_mode[] = {
+	{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 352,
+		.sizeimage = 352 * 288 * 4 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 0},
+};
 static const struct v4l2_pix_format vga_mode[] = {
 	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 		.bytesperline = 160,
@@ -302,6 +332,17 @@ static const struct v4l2_pix_format vga_
 		.priv = 0},
 };
 
+static const u8 sn_adcm1700[0x1c] = {
+/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
+	0x00,	0x43,	0x60,	0x00,	0x1a,	0x00,	0x00,	0x00,
+/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
+	0x80,	0x51,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
+/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
+	0x03,	0x00,	0x05,	0x01,	0x05,	0x16,	0x12,	0x42,
+/*	reg18	reg19	reg1a	reg1b */
+	0x06,	0x00,	0x00,	0x00
+};
+
 /*Data from sn9c102p+hv7131r */
 static const u8 sn_hv7131[0x1c] = {
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
@@ -415,6 +456,7 @@ static const u8 sn_sp80708[0x1c] = {
 
 /* sequence specific to the sensors - !! index = SENSOR_xxx */
 static const u8 *sn_tb[] = {
+	sn_adcm1700,
 	sn_hv7131,
 	sn_mi0360,
 	sn_mo4000,
@@ -432,6 +474,11 @@ 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 sensor ADCM1700 */
+static const u8 gamma_spec_0[17] = {
+	0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
+	0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
+};
 /* gamma for sensors HV7131R and MT9V111 */
 static const u8 gamma_spec_1[17] = {
 	0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
@@ -450,6 +497,42 @@ static const u8 reg84[] = {
 	0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f,	/* VR VG VB */
 	0x00, 0x00, 0x00			/* YUV offsets */
 };
+static const u8 adcm1700_sensor_init[][8] = {
+	{0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10},	/* reset */
+	{0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
+	{0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
+	{0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
+	{0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
+	{0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
+	{0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
+	{0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
+	{0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
+	{0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{}
+};
+static const u8 adcm1700_sensor_param1[][8] = {
+	{0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10},	/* exposure? */
+	{0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
+
+	{0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
+	{0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
+	{0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
+	{0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10},	/* exposure? */
+
+	{0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
+	{0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
+	{0xb0, 0x51, 0x32, 0x00, 0xa2, 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},
@@ -986,17 +1069,18 @@ static const u8 sp80708_sensor_param1[][
 	{}
 };
 
-static const u8 (*sensor_init[10])[8] = {
-	hv7131r_sensor_init,	/* HV7131R 0 */
-	mi0360_sensor_init,	/* MI0360 1 */
-	mo4000_sensor_init,	/* MO4000 2 */
-	mt9v111_sensor_init,	/* MT9V111 3 */
-	om6802_sensor_init,	/* OM6802 4 */
-	ov7630_sensor_init,	/* OV7630 5 */
-	ov7648_sensor_init,	/* OV7648 6 */
-	ov7660_sensor_init,	/* OV7660 7 */
-	po1030_sensor_init,	/* PO1030 8 */
-	sp80708_sensor_init,	/* SP80708 9 */
+static const u8 (*sensor_init[11])[8] = {
+	adcm1700_sensor_init,	/* ADCM1700 0 */
+	hv7131r_sensor_init,	/* HV7131R 1 */
+	mi0360_sensor_init,	/* MI0360 2 */
+	mo4000_sensor_init,	/* MO4000 3 */
+	mt9v111_sensor_init,	/* MT9V111 4 */
+	om6802_sensor_init,	/* OM6802 5 */
+	ov7630_sensor_init,	/* OV7630 6 */
+	ov7648_sensor_init,	/* OV7648 7 */
+	ov7660_sensor_init,	/* OV7660 8 */
+	po1030_sensor_init,	/* PO1030 9 */
+	sp80708_sensor_init,	/* SP80708 10 */
 };
 
 /* read <len> bytes to gspca_dev->usb_buf */
@@ -1064,6 +1148,7 @@ static void i2c_w1(struct gspca_dev *gsp
 
 	PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
 	switch (sd->sensor) {
+	case SENSOR_ADCM1700:
 	case SENSOR_OM6802:		/* i2c command = a0 (100 kHz) */
 		gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
 		break;
@@ -1110,6 +1195,7 @@ static void i2c_r(struct gspca_dev *gspc
 	u8 mode[8];
 
 	switch (sd->sensor) {
+	case SENSOR_ADCM1700:
 	case SENSOR_OM6802:		/* i2c command = 90 (100 kHz) */
 		mode[0] = 0x80 | 0x10;
 		break;
@@ -1260,7 +1346,8 @@ static void bridge_init(struct gspca_dev
 		{0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
 	static const u8 regd4[] = {0x60, 0x00, 0x00};
 
-	reg_w1(gspca_dev, 0xf1, 0x00);
+	/* sensor clock already enabled in sd_init */
+	/* reg_w1(gspca_dev, 0xf1, 0x00); */
 	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
 
 	/* configure gpio */
@@ -1284,6 +1371,12 @@ static void bridge_init(struct gspca_dev
 	reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
 
 	switch (sd->sensor) {
+	case SENSOR_ADCM1700:
+		reg_w1(gspca_dev, 0x01, 0x43);
+		reg_w1(gspca_dev, 0x17, 0x62);
+		reg_w1(gspca_dev, 0x01, 0x42);
+		reg_w1(gspca_dev, 0x01, 0x42);
+		break;
 	case SENSOR_MT9V111:
 		reg_w1(gspca_dev, 0x01, 0x61);
 		reg_w1(gspca_dev, 0x17, 0x61);
@@ -1357,14 +1450,19 @@ static int sd_config(struct gspca_dev *g
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
 
-	cam = &gspca_dev->cam;
-	cam->cam_mode = vga_mode;
-	cam->nmodes = ARRAY_SIZE(vga_mode);
-	cam->npkt = 24;			/* 24 packets per ISOC message */
-
 	sd->bridge = id->driver_info >> 16;
 	sd->sensor = id->driver_info;
 
+	cam = &gspca_dev->cam;
+	if (sd->sensor == SENSOR_ADCM1700) {
+		cam->cam_mode = cif_mode;
+		cam->nmodes = ARRAY_SIZE(cif_mode);
+	} else {
+		cam->cam_mode = vga_mode;
+		cam->nmodes = ARRAY_SIZE(vga_mode);
+	}
+	cam->npkt = 24;			/* 24 packets per ISOC message */
+
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->contrast = CONTRAST_DEF;
 	sd->colors = COLOR_DEF;
@@ -1374,6 +1472,14 @@ static int sd_config(struct gspca_dev *g
 	sd->autogain = AUTOGAIN_DEF;
 	sd->ag_cnt = -1;
 	sd->vflip = VFLIP_DEF;
+	switch (sd->sensor) {
+	case SENSOR_OM6802:
+		sd->sharpness = 0x10;
+		break;
+	default:
+		sd->sharpness = SHARPNESS_DEF;
+		break;
+	}
 	sd->infrared = INFRARED_DEF;
 	sd->freq = FREQ_DEF;
 	sd->quality = QUALITY_DEF;
@@ -1433,7 +1539,9 @@ static int sd_init(struct gspca_dev *gsp
 		break;
 	}
 
-	reg_w1(gspca_dev, 0xf1, 0x01);
+	/* Note we do not disable the sensor clock here (power saving mode),
+	   as that also disables the button on the cam. */
+	reg_w1(gspca_dev, 0xf1, 0x00);
 
 	/* set the i2c address */
 	sn9c1xx = sn_tb[sd->sensor];
@@ -1543,6 +1651,10 @@ static void setbrightness(struct gspca_d
 
 	k2 = ((int) sd->brightness - 0x8000) >> 10;
 	switch (sd->sensor) {
+	case SENSOR_ADCM1700:
+		if (k2 > 0x1f)
+			k2 = 0;		/* only positive Y offset */
+		break;
 	case SENSOR_HV7131R:
 		expo = sd->brightness << 4;
 		if (expo > 0x002dc6c0)
@@ -1625,6 +1737,9 @@ static void setgamma(struct gspca_dev *g
 	};
 
 	switch (sd->sensor) {
+	case SENSOR_ADCM1700:
+		gamma_base = gamma_spec_0;
+		break;
 	case SENSOR_HV7131R:
 	case SENSOR_MT9V111:
 		gamma_base = gamma_spec_1;
@@ -1670,23 +1785,39 @@ static void setautogain(struct gspca_dev
 		sd->ag_cnt = -1;
 }
 
-/* ov7630/ov7648 only */
+/* hv7131r/ov7630/ov7648 only */
 static void setvflip(struct sd *sd)
 {
 	u8 comn;
 
 	if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX))
 		return;
-	if (sd->sensor == SENSOR_OV7630) {
+	switch (sd->sensor) {
+	case SENSOR_HV7131R:
+		comn = 0x18;			/* clkdiv = 1, ablcen = 1 */
+		if (sd->vflip)
+			comn |= 0x01;
+		i2c_w1(&sd->gspca_dev, 0x01, comn);	/* sctra */
+		break;
+	case SENSOR_OV7630:
 		comn = 0x02;
 		if (!sd->vflip)
 			comn |= 0x80;
-	} else {
+		i2c_w1(&sd->gspca_dev, 0x75, comn);
+		break;
+	default:
+/*	case SENSOR_OV7648: */
 		comn = 0x06;
 		if (sd->vflip)
 			comn |= 0x80;
+		i2c_w1(&sd->gspca_dev, 0x75, comn);
+		break;
 	}
-	i2c_w1(&sd->gspca_dev, 0x75, comn);
+}
+
+static void setsharpness(struct sd *sd)
+{
+	reg_w1(&sd->gspca_dev, 0x99, sd->sharpness);
 }
 
 static void setinfrared(struct sd *sd)
@@ -1804,6 +1935,8 @@ static int sd_start(struct gspca_dev *gs
 	int mode;
 	static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
 	static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
+	static const u8 CA_adcm1700[] =
+				{ 0x14, 0xec, 0x0a, 0xf6 };
 	static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };	/* MI0360 */
 	static const u8 CE_ov76xx[] =
 				{ 0x32, 0xdd, 0x32, 0xdd };
@@ -1824,6 +1957,9 @@ static int sd_start(struct gspca_dev *gs
 	i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
 
 	switch (sd->sensor) {
+	case SENSOR_ADCM1700:
+		reg2 = 0x60;
+		break;
 	case SENSOR_OM6802:
 		reg2 = 0x71;
 		break;
@@ -1842,17 +1978,28 @@ static int sd_start(struct gspca_dev *gs
 	reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
 	reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
 	reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
-	reg_w1(gspca_dev, 0xd2, 0x6a);		/* DC29 */
-	reg_w1(gspca_dev, 0xd3, 0x50);
+	if (sd->sensor == SENSOR_ADCM1700) {
+		reg_w1(gspca_dev, 0xd2, 0x3a);	/* AE_H_SIZE = 116 */
+		reg_w1(gspca_dev, 0xd3, 0x30);	/* AE_V_SIZE = 96 */
+	} else {
+		reg_w1(gspca_dev, 0xd2, 0x6a);	/* AE_H_SIZE = 212 */
+		reg_w1(gspca_dev, 0xd3, 0x50);	/* AE_V_SIZE = 160 */
+	}
 	reg_w1(gspca_dev, 0xc6, 0x00);
 	reg_w1(gspca_dev, 0xc7, 0x00);
-	reg_w1(gspca_dev, 0xc8, 0x50);
-	reg_w1(gspca_dev, 0xc9, 0x3c);
+	if (sd->sensor == SENSOR_ADCM1700) {
+		reg_w1(gspca_dev, 0xc8, 0x2c);	/* AW_H_STOP = 352 */
+		reg_w1(gspca_dev, 0xc9, 0x24);	/* AW_V_STOP = 288 */
+	} else {
+		reg_w1(gspca_dev, 0xc8, 0x50);	/* AW_H_STOP = 640 */
+		reg_w1(gspca_dev, 0xc9, 0x3c);	/* AW_V_STOP = 480 */
+	}
 	reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
 	switch (sd->sensor) {
 	case SENSOR_MT9V111:
 		reg17 = 0xe0;
 		break;
+	case SENSOR_ADCM1700:
 	case SENSOR_OV7630:
 		reg17 = 0xe2;
 		break;
@@ -1870,44 +2017,39 @@ static int sd_start(struct gspca_dev *gs
 		break;
 	}
 	reg_w1(gspca_dev, 0x17, reg17);
-/* set reg1 was here */
-	reg_w1(gspca_dev, 0x05, sn9c1xx[5]);	/* red */
-	reg_w1(gspca_dev, 0x07, sn9c1xx[7]);	/* green */
-	reg_w1(gspca_dev, 0x06, sn9c1xx[6]);	/* blue */
+
+	reg_w1(gspca_dev, 0x05, 0x00);		/* red */
+	reg_w1(gspca_dev, 0x07, 0x00);		/* green */
+	reg_w1(gspca_dev, 0x06, 0x00);		/* blue */
 	reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
 
 	setgamma(gspca_dev);
 
+/*fixme: 8 times with all zeroes and 1 or 2 times with normal values */
 	for (i = 0; i < 8; i++)
 		reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
 	switch (sd->sensor) {
+	case SENSOR_ADCM1700:
+	case SENSOR_OV7660:
+	case SENSOR_SP80708:
+		reg_w1(gspca_dev, 0x9a, 0x05);
+		break;
 	case SENSOR_MT9V111:
 		reg_w1(gspca_dev, 0x9a, 0x07);
-		reg_w1(gspca_dev, 0x99, 0x59);
-		break;
-	case SENSOR_OM6802:
-		reg_w1(gspca_dev, 0x9a, 0x08);
-		reg_w1(gspca_dev, 0x99, 0x10);
 		break;
 	case SENSOR_OV7648:
 		reg_w1(gspca_dev, 0x9a, 0x0a);
-		reg_w1(gspca_dev, 0x99, 0x60);
-		break;
-	case SENSOR_OV7660:
-	case SENSOR_SP80708:
-		reg_w1(gspca_dev, 0x9a, 0x05);
-		reg_w1(gspca_dev, 0x99, 0x59);
 		break;
 	default:
 		reg_w1(gspca_dev, 0x9a, 0x08);
-		reg_w1(gspca_dev, 0x99, 0x59);
 		break;
 	}
+	setsharpness(sd);
 
 	reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
-	reg_w1(gspca_dev, 0x05, sn9c1xx[5]);	/* red */
-	reg_w1(gspca_dev, 0x07, sn9c1xx[7]);	/* green */
-	reg_w1(gspca_dev, 0x06, sn9c1xx[6]);	/* blue */
+	reg_w1(gspca_dev, 0x05, 0x20);		/* red */
+	reg_w1(gspca_dev, 0x07, 0x20);		/* green */
+	reg_w1(gspca_dev, 0x06, 0x20);		/* blue */
 
 	init = NULL;
 	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
@@ -1917,6 +2059,11 @@ static int sd_start(struct gspca_dev *gs
 		reg1 = 0x06;	/* 640x480: clk 24Mhz, video trf enable */
 	reg17 = 0x61;		/* 0x:20: enable sensor clock */
 	switch (sd->sensor) {
+	case SENSOR_ADCM1700:
+		init = adcm1700_sensor_param1;
+		reg1 = 0x46;
+		reg17 = 0xe2;
+		break;
 	case SENSOR_MO4000:
 		if (mode) {
 /*			reg1 = 0x46;	 * 320 clk 48Mhz 60fp/s */
@@ -1940,7 +2087,6 @@ static int sd_start(struct gspca_dev *gs
 		reg17 = 0x64;		/* 640 MCKSIZE */
 		break;
 	case SENSOR_OV7630:
-		setvflip(sd);
 		reg17 = 0xe2;
 		reg1 = 0x44;
 		break;
@@ -1986,8 +2132,12 @@ static int sd_start(struct gspca_dev *gs
 	}
 
 	reg_w(gspca_dev, 0xc0, C0, 6);
-	reg_w(gspca_dev, 0xca, CA, 4);
+	if (sd->sensor == SENSOR_ADCM1700)
+		reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
+	else
+		reg_w(gspca_dev, 0xca, CA, 4);
 	switch (sd->sensor) {
+	case SENSOR_ADCM1700:
 	case SENSOR_OV7630:
 	case SENSOR_OV7648:
 	case SENSOR_OV7660:
@@ -2008,11 +2158,7 @@ static int sd_start(struct gspca_dev *gs
 	reg_w1(gspca_dev, 0x17, reg17);
 	reg_w1(gspca_dev, 0x01, reg1);
 
-	switch (sd->sensor) {
-	case SENSOR_OV7630:
-		setvflip(sd);
-		break;
-	}
+	setvflip(sd);
 	setbrightness(gspca_dev);
 	setcontrast(gspca_dev);
 	setautogain(gspca_dev);
@@ -2056,7 +2202,8 @@ static void sd_stopN(struct gspca_dev *g
 	reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
 	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
 	reg_w1(gspca_dev, 0x01, data);
-	reg_w1(gspca_dev, 0xf1, 0x00);
+	/* Don't disable sensor clock as that disables the button on the cam */
+	/* reg_w1(gspca_dev, 0xf1, 0x01); */
 }
 
 static void sd_stop0(struct gspca_dev *gspca_dev)
@@ -2288,6 +2435,24 @@ static int sd_getautogain(struct gspca_d
 	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)
+		setsharpness(sd);
+	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_setvflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -2391,6 +2556,25 @@ static int sd_querymenu(struct gspca_dev
 	return -EINVAL;
 }
 
+#ifdef CONFIG_INPUT
+static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,		/* interrupt packet data */
+			int len)		/* interrupt packet length */
+{
+	int ret = -EINVAL;
+
+	if (len == 1 && data[0] == 1) {
+		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
+		input_sync(gspca_dev->input_dev);
+		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
+		input_sync(gspca_dev->input_dev);
+		ret = 0;
+	}
+
+	return ret;
+}
+#endif
+
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
@@ -2406,6 +2590,9 @@ static const struct sd_desc sd_desc = {
 	.get_jcomp = sd_get_jcomp,
 	.set_jcomp = sd_set_jcomp,
 	.querymenu = sd_querymenu,
+#ifdef CONFIG_INPUT
+	.int_pkt_scan = sd_int_pkt_scan,
+#endif
 };
 
 /* -- module initialisation -- */
@@ -2472,6 +2659,7 @@ static const __devinitdata struct usb_de
 /*	{USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)},	 *sn9c120b*/
 	{USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)},	/*sn9c120b*/
 	{USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)},	/*sn9c120b*/
+	{USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)},	/*sn9c120b*/
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca500.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/spca500.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca500.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/spca500.c	2010-05-16 17:17:36.000000000 -0400
@@ -68,7 +68,7 @@ static int sd_getcontrast(struct gspca_d
 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 	{
 	    {
 		.id      = V4L2_CID_BRIGHTNESS,
@@ -1047,7 +1047,7 @@ static int sd_get_jcomp(struct gspca_dev
 }
 
 /* sub-driver description */
-static struct sd_desc sd_desc = {
+static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca501.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/spca501.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca501.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/spca501.c	2010-05-16 17:17:36.000000000 -0400
@@ -59,7 +59,7 @@ static int sd_getblue_balance(struct gsp
 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 struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 #define MY_BRIGHTNESS 0
 	{
 	    {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca505.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/spca505.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca505.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/spca505.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,7 +42,7 @@ struct sd {
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 	{
 	    {
 		.id      = V4L2_CID_BRIGHTNESS,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca506.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/spca506.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca506.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/spca506.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,7 +51,7 @@ static int sd_getcolors(struct gspca_dev
 static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 #define SD_BRIGHTNESS 0
 	{
 	    {
@@ -673,7 +673,7 @@ static int sd_gethue(struct gspca_dev *g
 }
 
 /* sub-driver description */
-static struct sd_desc sd_desc = {
+static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca508.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/spca508.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca508.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/spca508.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,7 +45,7 @@ struct sd {
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 	{
 	    {
 		.id      = V4L2_CID_BRIGHTNESS,
@@ -1513,7 +1513,6 @@ static const struct sd_desc sd_desc = {
 static const __devinitdata struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x0130, 0x0130), .driver_info = HamaUSBSightcam},
 	{USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista},
-	{USB_DEVICE(0x0461, 0x0815), .driver_info = MicroInnovationIC200},
 	{USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110},
 	{USB_DEVICE(0x0af9, 0x0010), .driver_info = HamaUSBSightcam},
 	{USB_DEVICE(0x0af9, 0x0011), .driver_info = HamaUSBSightcam2},
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca561.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/spca561.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca561.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/spca561.c	2010-05-16 17:17:36.000000000 -0400
@@ -922,7 +922,7 @@ static int sd_getgain(struct gspca_dev *
 }
 
 /* control tables */
-static struct ctrl sd_ctrls_12a[] = {
+static const struct ctrl sd_ctrls_12a[] = {
 	{
 	    {
 		.id = V4L2_CID_HUE,
@@ -964,7 +964,7 @@ static struct ctrl sd_ctrls_12a[] = {
 	},
 };
 
-static struct ctrl sd_ctrls_72a[] = {
+static const struct ctrl sd_ctrls_72a[] = {
 	{
 	    {
 		.id = V4L2_CID_HUE,
@@ -1053,6 +1053,7 @@ static const __devinitdata struct usb_de
 	{USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
 	{USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
 	{USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
+	{USB_DEVICE(0x0461, 0x0815), .driver_info = Rev072A},
 	{USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
 	{USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
 	{USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sq905.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sq905.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sq905.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sq905.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #define MODULE_NAME "sq905"
 
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 #include "gspca.h"
 
 MODULE_AUTHOR("Adam Baker <linux@baker-net.org.uk>, "
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sq905c.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sq905c.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sq905c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sq905c.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #define MODULE_NAME "sq905c"
 
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 #include "gspca.h"
 
 MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
@@ -47,6 +48,7 @@ MODULE_LICENSE("GPL");
 
 /* Commands. These go in the "value" slot. */
 #define SQ905C_CLEAR   0xa0		/* clear everything */
+#define SQ905C_GET_ID  0x14f4		/* Read version number */
 #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 */
@@ -101,6 +103,26 @@ static int sq905c_command(struct gspca_d
 	return 0;
 }
 
+static int sq905c_read(struct gspca_dev *gspca_dev, u16 command, u16 index,
+		       int size)
+{
+	int ret;
+
+	ret = usb_control_msg(gspca_dev->dev,
+			      usb_rcvctrlpipe(gspca_dev->dev, 0),
+			      USB_REQ_SYNCH_FRAME,		/* request */
+			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      command, index, gspca_dev->usb_buf, size,
+			      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
@@ -183,13 +205,34 @@ static int sd_config(struct gspca_dev *g
 {
 	struct cam *cam = &gspca_dev->cam;
 	struct sd *dev = (struct sd *) gspca_dev;
+	int ret;
 
 	PDEBUG(D_PROBE,
 		"SQ9050 camera detected"
 		" (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+
+	ret = sq905c_command(gspca_dev, SQ905C_GET_ID, 0);
+	if (ret < 0) {
+		PDEBUG(D_ERR, "Get version command failed");
+		return ret;
+	}
+
+	ret = sq905c_read(gspca_dev, 0xf5, 0, 20);
+	if (ret < 0) {
+		PDEBUG(D_ERR, "Reading version command failed");
+		return ret;
+	}
+	/* Note we leave out the usb id and the manufacturing date */
+	PDEBUG(D_PROBE,
+	       "SQ9050 ID string: %02x - %02x %02x %02x %02x %02x %02x",
+		gspca_dev->usb_buf[3],
+		gspca_dev->usb_buf[14], gspca_dev->usb_buf[15],
+		gspca_dev->usb_buf[16], gspca_dev->usb_buf[17],
+		gspca_dev->usb_buf[18], gspca_dev->usb_buf[19]);
+
 	cam->cam_mode = sq905c_mode;
 	cam->nmodes = 2;
-	if (id->idProduct == 0x9050)
+	if (gspca_dev->usb_buf[15] == 0)
 		cam->nmodes = 1;
 	/* We don't use the buffer gspca allocates so make it small. */
 	cam->bulk_size = 32;
@@ -258,6 +301,7 @@ static int sd_start(struct gspca_dev *gs
 static const __devinitdata struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x2770, 0x905c)},
 	{USB_DEVICE(0x2770, 0x9050)},
+	{USB_DEVICE(0x2770, 0x9052)},
 	{USB_DEVICE(0x2770, 0x913d)},
 	{}
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/stk014.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/stk014.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/stk014.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/stk014.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,7 +53,7 @@ static int sd_getcolors(struct gspca_dev
 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 	{
 	    {
 		.id      = V4L2_CID_BRIGHTNESS,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/stv0680.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/stv0680.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/stv0680.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/stv0680.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,7 +45,7 @@ struct sd {
 };
 
 /* V4L2 controls supported by the driver */
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 };
 
 static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val,
@@ -53,24 +53,28 @@ static int stv_sndctrl(struct gspca_dev
 {
 	int ret = -1;
 	u8 req_type = 0;
+	unsigned int pipe = 0;
 
 	switch (set) {
 	case 0: /*  0xc1  */
 		req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
+		pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
 		break;
 	case 1: /*  0x41  */
 		req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
+		pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
 		break;
 	case 2:	/*  0x80  */
 		req_type = USB_DIR_IN | USB_RECIP_DEVICE;
+		pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
 		break;
 	case 3:	/*  0x40  */
 		req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+		pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
 		break;
 	}
 
-	ret = usb_control_msg(gspca_dev->dev,
-			      usb_rcvctrlpipe(gspca_dev->dev, 0),
+	ret = usb_control_msg(gspca_dev->dev, pipe,
 			      req, req_type,
 			      val, 0, gspca_dev->usb_buf, size, 500);
 
@@ -138,6 +142,10 @@ static int sd_config(struct gspca_dev *g
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam = &gspca_dev->cam;
 
+	/* Give the camera some time to settle, otherwise initalization will
+	   fail on hotplug, and yes it really needs a full second. */
+	msleep(1000);
+
 	/* ping camera to be sure STV0680 is present */
 	if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 ||
 	    gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) {
@@ -169,6 +177,8 @@ static int sd_config(struct gspca_dev *g
 		PDEBUG(D_PROBE, "Camera supports CIF mode");
 	if (gspca_dev->usb_buf[7] & 0x02)
 		PDEBUG(D_PROBE, "Camera supports VGA mode");
+	if (gspca_dev->usb_buf[7] & 0x04)
+		PDEBUG(D_PROBE, "Camera supports QCIF mode");
 	if (gspca_dev->usb_buf[7] & 0x08)
 		PDEBUG(D_PROBE, "Camera supports QVGA mode");
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/stv06xx/stv06xx.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/stv06xx/stv06xx.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/stv06xx/stv06xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/stv06xx/stv06xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
  * P/N 861040-0000: Sensor ST VV6410       ASIC STV0610   - QuickCam Web
  */
 
+#include <linux/input.h>
 #include "stv06xx_sensor.h"
 
 MODULE_AUTHOR("Erik AndrÃ©n");
@@ -219,6 +220,7 @@ static void stv06xx_dump_bridge(struct s
 		info("Read 0x%x from address 0x%x", data, i);
 	}
 
+	info("Testing stv06xx bridge registers for writability");
 	for (i = 0x1400; i < 0x160f; i++) {
 		stv06xx_read_bridge(sd, i, &data);
 		buf = data;
@@ -229,7 +231,7 @@ static void stv06xx_dump_bridge(struct s
 			info("Register 0x%x is read/write", i);
 		else if (data != buf)
 			info("Register 0x%x is read/write,"
-			     "but only partially", i);
+			     " but only partially", i);
 		else
 			info("Register 0x%x is read-only", i);
 
@@ -426,6 +428,29 @@ frame_data:
 	}
 }
 
+#ifdef CONFIG_INPUT
+static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,		/* interrupt packet data */
+			int len)		/* interrupt packet length */
+{
+	int ret = -EINVAL;
+
+	if (len == 1 && data[0] == 0x80) {
+		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
+		input_sync(gspca_dev->input_dev);
+		ret = 0;
+	}
+
+	if (len == 1 && data[0] == 0x88) {
+		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
+		input_sync(gspca_dev->input_dev);
+		ret = 0;
+	}
+
+	return ret;
+}
+#endif
+
 static int stv06xx_config(struct gspca_dev *gspca_dev,
 			  const struct usb_device_id *id);
 
@@ -436,7 +461,10 @@ static const struct sd_desc sd_desc = {
 	.init = stv06xx_init,
 	.start = stv06xx_start,
 	.stopN = stv06xx_stopN,
-	.pkt_scan = stv06xx_pkt_scan
+	.pkt_scan = stv06xx_pkt_scan,
+#ifdef CONFIG_INPUT
+	.int_pkt_scan = sd_int_pkt_scan,
+#endif
 };
 
 /* This function is called at probe time */
@@ -496,8 +524,6 @@ static const __devinitdata struct usb_de
 	{USB_DEVICE(0x046D, 0x08F5), .driver_info = BRIDGE_ST6422 },
 	/* QuickCam Messenger (new) */
 	{USB_DEVICE(0x046D, 0x08F6), .driver_info = BRIDGE_ST6422 },
-	/* QuickCam Messenger (new) */
-	{USB_DEVICE(0x046D, 0x08DA), .driver_info = BRIDGE_ST6422 },
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sunplus.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sunplus.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sunplus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/sunplus.c	2010-05-16 17:17:36.000000000 -0400
@@ -67,7 +67,7 @@ static int sd_getcolors(struct gspca_dev
 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 	{
 	    {
 		.id      = V4L2_CID_BRIGHTNESS,
@@ -267,142 +267,6 @@ static const struct cmd spca504A_clicksm
 	{0x06, 0x0000, 0x0000},
 	{0x00, 0x0004, 0x2880},
 	{0x00, 0x0001, 0x2881},
-/* look like setting a qTable */
-	{0x00, 0x0006, 0x2800},
-	{0x00, 0x0004, 0x2801},
-	{0x00, 0x0004, 0x2802},
-	{0x00, 0x0006, 0x2803},
-	{0x00, 0x000a, 0x2804},
-	{0x00, 0x0010, 0x2805},
-	{0x00, 0x0014, 0x2806},
-	{0x00, 0x0018, 0x2807},
-	{0x00, 0x0005, 0x2808},
-	{0x00, 0x0005, 0x2809},
-	{0x00, 0x0006, 0x280a},
-	{0x00, 0x0008, 0x280b},
-	{0x00, 0x000a, 0x280c},
-	{0x00, 0x0017, 0x280d},
-	{0x00, 0x0018, 0x280e},
-	{0x00, 0x0016, 0x280f},
-
-	{0x00, 0x0006, 0x2810},
-	{0x00, 0x0005, 0x2811},
-	{0x00, 0x0006, 0x2812},
-	{0x00, 0x000a, 0x2813},
-	{0x00, 0x0010, 0x2814},
-	{0x00, 0x0017, 0x2815},
-	{0x00, 0x001c, 0x2816},
-	{0x00, 0x0016, 0x2817},
-	{0x00, 0x0006, 0x2818},
-	{0x00, 0x0007, 0x2819},
-	{0x00, 0x0009, 0x281a},
-	{0x00, 0x000c, 0x281b},
-	{0x00, 0x0014, 0x281c},
-	{0x00, 0x0023, 0x281d},
-	{0x00, 0x0020, 0x281e},
-	{0x00, 0x0019, 0x281f},
-
-	{0x00, 0x0007, 0x2820},
-	{0x00, 0x0009, 0x2821},
-	{0x00, 0x000f, 0x2822},
-	{0x00, 0x0016, 0x2823},
-	{0x00, 0x001b, 0x2824},
-	{0x00, 0x002c, 0x2825},
-	{0x00, 0x0029, 0x2826},
-	{0x00, 0x001f, 0x2827},
-	{0x00, 0x000a, 0x2828},
-	{0x00, 0x000e, 0x2829},
-	{0x00, 0x0016, 0x282a},
-	{0x00, 0x001a, 0x282b},
-	{0x00, 0x0020, 0x282c},
-	{0x00, 0x002a, 0x282d},
-	{0x00, 0x002d, 0x282e},
-	{0x00, 0x0025, 0x282f},
-
-	{0x00, 0x0014, 0x2830},
-	{0x00, 0x001a, 0x2831},
-	{0x00, 0x001f, 0x2832},
-	{0x00, 0x0023, 0x2833},
-	{0x00, 0x0029, 0x2834},
-	{0x00, 0x0030, 0x2835},
-	{0x00, 0x0030, 0x2836},
-	{0x00, 0x0028, 0x2837},
-	{0x00, 0x001d, 0x2838},
-	{0x00, 0x0025, 0x2839},
-	{0x00, 0x0026, 0x283a},
-	{0x00, 0x0027, 0x283b},
-	{0x00, 0x002d, 0x283c},
-	{0x00, 0x0028, 0x283d},
-	{0x00, 0x0029, 0x283e},
-	{0x00, 0x0028, 0x283f},
-
-	{0x00, 0x0007, 0x2840},
-	{0x00, 0x0007, 0x2841},
-	{0x00, 0x000a, 0x2842},
-	{0x00, 0x0013, 0x2843},
-	{0x00, 0x0028, 0x2844},
-	{0x00, 0x0028, 0x2845},
-	{0x00, 0x0028, 0x2846},
-	{0x00, 0x0028, 0x2847},
-	{0x00, 0x0007, 0x2848},
-	{0x00, 0x0008, 0x2849},
-	{0x00, 0x000a, 0x284a},
-	{0x00, 0x001a, 0x284b},
-	{0x00, 0x0028, 0x284c},
-	{0x00, 0x0028, 0x284d},
-	{0x00, 0x0028, 0x284e},
-	{0x00, 0x0028, 0x284f},
-
-	{0x00, 0x000a, 0x2850},
-	{0x00, 0x000a, 0x2851},
-	{0x00, 0x0016, 0x2852},
-	{0x00, 0x0028, 0x2853},
-	{0x00, 0x0028, 0x2854},
-	{0x00, 0x0028, 0x2855},
-	{0x00, 0x0028, 0x2856},
-	{0x00, 0x0028, 0x2857},
-	{0x00, 0x0013, 0x2858},
-	{0x00, 0x001a, 0x2859},
-	{0x00, 0x0028, 0x285a},
-	{0x00, 0x0028, 0x285b},
-	{0x00, 0x0028, 0x285c},
-	{0x00, 0x0028, 0x285d},
-	{0x00, 0x0028, 0x285e},
-	{0x00, 0x0028, 0x285f},
-
-	{0x00, 0x0028, 0x2860},
-	{0x00, 0x0028, 0x2861},
-	{0x00, 0x0028, 0x2862},
-	{0x00, 0x0028, 0x2863},
-	{0x00, 0x0028, 0x2864},
-	{0x00, 0x0028, 0x2865},
-	{0x00, 0x0028, 0x2866},
-	{0x00, 0x0028, 0x2867},
-	{0x00, 0x0028, 0x2868},
-	{0x00, 0x0028, 0x2869},
-	{0x00, 0x0028, 0x286a},
-	{0x00, 0x0028, 0x286b},
-	{0x00, 0x0028, 0x286c},
-	{0x00, 0x0028, 0x286d},
-	{0x00, 0x0028, 0x286e},
-	{0x00, 0x0028, 0x286f},
-
-	{0x00, 0x0028, 0x2870},
-	{0x00, 0x0028, 0x2871},
-	{0x00, 0x0028, 0x2872},
-	{0x00, 0x0028, 0x2873},
-	{0x00, 0x0028, 0x2874},
-	{0x00, 0x0028, 0x2875},
-	{0x00, 0x0028, 0x2876},
-	{0x00, 0x0028, 0x2877},
-	{0x00, 0x0028, 0x2878},
-	{0x00, 0x0028, 0x2879},
-	{0x00, 0x0028, 0x287a},
-	{0x00, 0x0028, 0x287b},
-	{0x00, 0x0028, 0x287c},
-	{0x00, 0x0028, 0x287d},
-	{0x00, 0x0028, 0x287e},
-	{0x00, 0x0028, 0x287f},
 
 	{0xa0, 0x0000, 0x0503},
 };
@@ -622,6 +486,20 @@ static void spca504_acknowledged_command
 	PDEBUG(D_FRAM, "after wait 0x%04x", notdone);
 }
 
+static void spca504_read_info(struct gspca_dev *gspca_dev)
+{
+	int i;
+	u8 info[6];
+
+	for (i = 0; i < 6; i++)
+		info[i] = reg_r_1(gspca_dev, i);
+	PDEBUG(D_STREAM,
+		"Read info: %d %d %d %d %d %d."
+		" Should be 1,0,2,2,0,0",
+		info[0], info[1], info[2],
+		info[3], info[4], info[5]);
+}
+
 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
 			u8 req,
 			u16 idx, u16 val, u16 endcode, u8 count)
@@ -881,8 +759,6 @@ static int sd_config(struct gspca_dev *g
 static int sd_init(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int i;
-	u8 info[6];
 
 	switch (sd->bridge) {
 	case BRIDGE_SPCA504B:
@@ -924,15 +800,8 @@ static int sd_init(struct gspca_dev *gsp
 /*	case BRIDGE_SPCA504: */
 		PDEBUG(D_STREAM, "Opening SPCA504");
 		if (sd->subtype == AiptekMiniPenCam13) {
-			/*****************************/
-			for (i = 0; i < 6; i++)
-				info[i] = reg_r_1(gspca_dev, i);
-			PDEBUG(D_STREAM,
-				"Read info: %d %d %d %d %d %d."
-				" Should be 1,0,2,2,0,0",
-				info[0], info[1], info[2],
-				info[3], info[4], info[5]);
-			/* spca504a aiptek */
+			spca504_read_info(gspca_dev);
+
 			/* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
 			spca504A_acknowledged_command(gspca_dev, 0x24,
 							8, 3, 0x9e, 1);
@@ -971,8 +840,6 @@ static int sd_start(struct gspca_dev *gs
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int enable;
-	int i;
-	u8 info[6];
 
 	/* create the JPEG header */
 	sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
@@ -1008,14 +875,8 @@ static int sd_start(struct gspca_dev *gs
 		break;
 	case BRIDGE_SPCA504:
 		if (sd->subtype == AiptekMiniPenCam13) {
-			for (i = 0; i < 6; i++)
-				info[i] = reg_r_1(gspca_dev, i);
-			PDEBUG(D_STREAM,
-				"Read info: %d %d %d %d %d %d."
-				" Should be 1,0,2,2,0,0",
-				info[0], info[1], info[2],
-				info[3], info[4], info[5]);
-			/* spca504a aiptek */
+			spca504_read_info(gspca_dev);
+
 			/* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
 			spca504A_acknowledged_command(gspca_dev, 0x24,
 							8, 3, 0x9e, 1);
@@ -1026,13 +887,7 @@ static int sd_start(struct gspca_dev *gs
 							0, 0, 0x9d, 1);
 		} else {
 			spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
-			for (i = 0; i < 6; i++)
-				info[i] = reg_r_1(gspca_dev, i);
-			PDEBUG(D_STREAM,
-				"Read info: %d %d %d %d %d %d."
-				" Should be 1,0,2,2,0,0",
-				info[0], info[1], info[2],
-				info[3], info[4], info[5]);
+			spca504_read_info(gspca_dev);
 			spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
 			spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
 		}
@@ -1336,6 +1191,7 @@ static const __devinitdata struct usb_de
 	{USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)},
 	{USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
 	{USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
+	{USB_DEVICE(0x052b, 0x1507), BS(SPCA533, MegapixV4)},
 	{USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
 	{USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)},
 	{USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/t613.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/t613.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/t613.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/t613.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,6 +52,7 @@ struct sd {
 #define SENSOR_OM6802 0
 #define SENSOR_OTHER 1
 #define SENSOR_TAS5130A 2
+#define SENSOR_LT168G 3     /* must verify if this is the actual model */
 };
 
 /* V4L2 controls supported by the driver */
@@ -78,7 +79,7 @@ static int sd_geteffect(struct gspca_dev
 static int sd_querymenu(struct gspca_dev *gspca_dev,
 			struct v4l2_querymenu *menu);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 	{
 	 {
 	  .id = V4L2_CID_BRIGHTNESS,
@@ -306,6 +307,17 @@ static const u8 n4_tas5130a[] = {
 	0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8,
 	0xc6, 0xda
 };
+static const u8 n4_lt168g[] = {
+	0x66, 0x01, 0x7f, 0x00, 0x80, 0x7c, 0x81, 0x28,
+	0x83, 0x44, 0x84, 0x20, 0x86, 0x20, 0x8a, 0x70,
+	0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xa0, 0x8e, 0xb3,
+	0x8f, 0x24, 0xa1, 0xb0, 0xa2, 0x38, 0xa5, 0x20,
+	0xa6, 0x4a, 0xa8, 0xe8, 0xaf, 0x38, 0xb0, 0x68,
+	0xb1, 0x44, 0xb2, 0x88, 0xbb, 0x86, 0xbd, 0x40,
+	0xbe, 0x26, 0xc1, 0x05, 0xc2, 0x88, 0xc5, 0xc0,
+	0xda, 0x8e, 0xdb, 0xca, 0xdc, 0xa8, 0xdd, 0x8c,
+	0xde, 0x44, 0xdf, 0x0c, 0xe9, 0x80
+};
 
 static const struct additional_sensor_data sensor_data[] = {
     {				/* 0: OM6802 */
@@ -380,6 +392,23 @@ static const struct additional_sensor_da
 	.stream =
 		{0x0b, 0x04, 0x0a, 0x40},
     },
+    {				/* 3: LT168G */
+	.n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00},
+	.n4 = n4_lt168g,
+	.n4sz = sizeof n4_lt168g,
+	.reg80 = 0x7c,
+	.reg8e = 0xb3,
+	.nset8 = {0xa8, 0xf0, 0xc6, 0xba, 0xc0, 0x00},
+	.data1 = {0xc0, 0x38, 0x08, 0x10, 0xc0, 0x30, 0x10, 0x40,
+		 0xb0, 0xf4},
+	.data2 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
+		 0xff},
+	.data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
+		 0xff},
+	.data4 = {0x66, 0x41, 0xa8, 0xf0},
+	.data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b},
+	.stream = {0x0b, 0x04, 0x0a, 0x28},
+    },
 };
 
 #define MAX_EFFECTS 7
@@ -716,6 +745,10 @@ static int sd_init(struct gspca_dev *gsp
 		PDEBUG(D_PROBE, "sensor tas5130a");
 		sd->sensor = SENSOR_TAS5130A;
 		break;
+	case 0x0802:
+		PDEBUG(D_PROBE, "sensor lt168g");
+		sd->sensor = SENSOR_LT168G;
+		break;
 	case 0x0803:
 		PDEBUG(D_PROBE, "sensor 'other'");
 		sd->sensor = SENSOR_OTHER;
@@ -758,6 +791,13 @@ static int sd_init(struct gspca_dev *gsp
 	reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3);
 	reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz);
 
+	if (sd->sensor == SENSOR_LT168G) {
+		test_byte = reg_r(gspca_dev, 0x80);
+		PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
+		       test_byte);
+		reg_w(gspca_dev, 0x6c80);
+	}
+
 	reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
 	reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
 	reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
@@ -782,6 +822,13 @@ static int sd_init(struct gspca_dev *gsp
 	reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
 	reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
 
+	if (sd->sensor == SENSOR_LT168G) {
+		test_byte = reg_r(gspca_dev, 0x80);
+		PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
+		       test_byte);
+		reg_w(gspca_dev, 0x6c80);
+	}
+
 	reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
 	reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
 	reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
@@ -888,6 +935,8 @@ static int sd_start(struct gspca_dev *gs
 	case SENSOR_OM6802:
 		om6802_sensor_init(gspca_dev);
 		break;
+	case SENSOR_LT168G:
+		break;
 	case SENSOR_OTHER:
 		break;
 	default:
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/tv8532.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/tv8532.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/tv8532.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/tv8532.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,7 @@ struct sd {
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 	{
 	 {
 	  .id = V4L2_CID_BRIGHTNESS,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/vc032x.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/vc032x.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/vc032x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/vc032x.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,10 +32,13 @@ MODULE_LICENSE("GPL");
 struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
 
+	u8 brightness;
+	u8 contrast;
+	u8 colors;
 	u8 hflip;
 	u8 vflip;
 	u8 lightfreq;
-	u8 sharpness;
+	s8 sharpness;
 
 	u8 image_offset;
 
@@ -52,6 +55,7 @@ struct sd {
 #define SENSOR_OV7670 6
 #define SENSOR_PO1200 7
 #define SENSOR_PO3130NC 8
+#define SENSOR_POxxxx 9
 	u8 flags;
 #define FL_SAMSUNG 0x01		/* SamsungQ1 (2 sensors) */
 #define FL_HFLIP 0x02		/* mirrored by default */
@@ -59,6 +63,12 @@ struct sd {
 };
 
 /* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
@@ -68,9 +78,54 @@ static int sd_getfreq(struct gspca_dev *
 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[] = {
+static const struct ctrl sd_ctrls[] = {
+#define BRIGHTNESS_IDX 0
+	{
+	    {
+		.id      = V4L2_CID_BRIGHTNESS,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Brightness",
+		.minimum = 0,
+		.maximum = 255,
+		.step    = 1,
+#define BRIGHTNESS_DEF 128
+		.default_value = BRIGHTNESS_DEF,
+	    },
+	    .set = sd_setbrightness,
+	    .get = sd_getbrightness,
+	},
+#define CONTRAST_IDX 1
+	{
+	    {
+		.id      = V4L2_CID_CONTRAST,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Contrast",
+		.minimum = 0,
+		.maximum = 255,
+		.step    = 1,
+#define CONTRAST_DEF 127
+		.default_value = CONTRAST_DEF,
+	    },
+	    .set = sd_setcontrast,
+	    .get = sd_getcontrast,
+	},
+#define COLORS_IDX 2
+	{
+	    {
+		.id      = V4L2_CID_SATURATION,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Saturation",
+		.minimum = 1,
+		.maximum = 127,
+		.step    = 1,
+#define COLOR_DEF 63
+		.default_value = COLOR_DEF,
+	    },
+	    .set = sd_setcolors,
+	    .get = sd_getcolors,
+	},
 /* next 2 controls work with some sensors only */
-#define HFLIP_IDX 0
+#define HFLIP_IDX 3
 	{
 	    {
 		.id      = V4L2_CID_HFLIP,
@@ -85,7 +140,7 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_sethflip,
 	    .get = sd_gethflip,
 	},
-#define VFLIP_IDX 1
+#define VFLIP_IDX 4
 	{
 	    {
 		.id      = V4L2_CID_VFLIP,
@@ -100,7 +155,7 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setvflip,
 	    .get = sd_getvflip,
 	},
-#define LIGHTFREQ_IDX 2
+#define LIGHTFREQ_IDX 5
 	{
 	    {
 		.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -115,17 +170,16 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setfreq,
 	    .get = sd_getfreq,
 	},
-/* po1200 only */
-#define SHARPNESS_IDX 3
+#define SHARPNESS_IDX 6
 	{
 	 {
 	  .id = V4L2_CID_SHARPNESS,
 	  .type = V4L2_CTRL_TYPE_INTEGER,
 	  .name = "Sharpness",
-	  .minimum = 0,
+	  .minimum = -1,
 	  .maximum = 2,
 	  .step = 1,
-#define SHARPNESS_DEF 1
+#define SHARPNESS_DEF -1
 	  .default_value = SHARPNESS_DEF,
 	  },
 	 .set = sd_setsharpness,
@@ -133,6 +187,42 @@ static struct ctrl sd_ctrls[] = {
 	 },
 };
 
+/* table of the disabled controls */
+static u32 ctrl_dis[] = {
+/* SENSOR_HV7131R 0 */
+	(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
+		| (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX)
+		| (1 << SHARPNESS_IDX),
+/* SENSOR_MI0360 1 */
+	(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
+		| (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX)
+		| (1 << SHARPNESS_IDX),
+/* SENSOR_MI1310_SOC 2 */
+	(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
+		| (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
+/* SENSOR_MI1320 3 */
+	(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
+		| (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
+/* SENSOR_MI1320_SOC 4 */
+	(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
+		| (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
+/* SENSOR_OV7660 5 */
+	(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
+		| (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
+/* SENSOR_OV7670 6 */
+	(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
+		| (1 << SHARPNESS_IDX),
+/* SENSOR_PO1200 7 */
+	(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
+		| (1 << LIGHTFREQ_IDX),
+/* SENSOR_PO3130NC 8 */
+	(1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
+		| (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX)
+		| (1 << SHARPNESS_IDX),
+/* SENSOR_POxxxx 9 */
+	(1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX),
+};
+
 static const struct v4l2_pix_format vc0321_mode[] = {
 	{320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
 		.bytesperline = 320,
@@ -215,7 +305,7 @@ static const u8 mi0360_initVGA_JPG[][4]
 	{0xb3, 0x15, 0x00, 0xcc},
 	{0xb3, 0x16, 0x02, 0xcc},
 	{0xb3, 0x17, 0x7f, 0xcc},
-	{0xb3, 0x35, 0xdd, 0xcc},
+	{0xb3, 0x35, 0xdd, 0xcc},	/* i2c add: 5d */
 	{0xb3, 0x34, 0x02, 0xcc},
 	{0xb3, 0x00, 0x25, 0xcc},
 	{0xbc, 0x00, 0x71, 0xcc},
@@ -435,7 +525,7 @@ static const u8 mi1310_socinitVGA_JPG[][
 	{0xb3, 0x08, 0x01, 0xcc},
 	{0xb3, 0x09, 0x0c, 0xcc},
 	{0xb3, 0x34, 0x02, 0xcc},
-	{0xb3, 0x35, 0xdd, 0xcc},
+	{0xb3, 0x35, 0xdd, 0xcc},	/* i2c add: 5d */
 	{0xb3, 0x02, 0x00, 0xcc},
 	{0xb3, 0x03, 0x0a, 0xcc},
 	{0xb3, 0x04, 0x05, 0xcc},
@@ -860,7 +950,8 @@ static const u8 mi1320_initVGA_data[][4]
 	{0xb0, 0x16, 0x03, 0xcc},	{0xb3, 0x05, 0x00, 0xcc},
 	{0xb3, 0x06, 0x00, 0xcc},	{0xb3, 0x08, 0x01, 0xcc},
 	{0xb3, 0x09, 0x0c, 0xcc},	{0xb3, 0x34, 0x02, 0xcc},
-	{0xb3, 0x35, 0xc8, 0xcc},	{0xb3, 0x02, 0x00, 0xcc},
+	{0xb3, 0x35, 0xc8, 0xcc},	/* i2c add: 48 */
+	{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},
@@ -901,7 +992,8 @@ static const u8 mi1320_initVGA_data[][4]
 	{0xc3, 0x01, 0x03, 0xbb},	{0xc4, 0x00, 0x04, 0xbb},
 	{0xf0, 0x00, 0x00, 0xbb},	{0x05, 0x01, 0x13, 0xbb},
 	{0x06, 0x00, 0x11, 0xbb},	{0x07, 0x00, 0x85, 0xbb},
-	{0x08, 0x00, 0x27, 0xbb},	{0x20, 0x01, 0x03, 0xbb},
+	{0x08, 0x00, 0x27, 0xbb},
+	{0x20, 0x01, 0x00, 0xbb},	/* h/v flips - was 03 */
 	{0x21, 0x80, 0x00, 0xbb},	{0x22, 0x0d, 0x0f, 0xbb},
 	{0x24, 0x80, 0x00, 0xbb},	{0x59, 0x00, 0xff, 0xbb},
 	{0xf0, 0x00, 0x02, 0xbb},	{0x39, 0x03, 0x0d, 0xbb},
@@ -1012,7 +1104,7 @@ static const u8 mi1320_soc_InitVGA[][4]
 	{0xb3, 0x08, 0x01, 0xcc},
 	{0xb3, 0x09, 0x0c, 0xcc},
 	{0xb3, 0x34, 0x02, 0xcc},
-	{0xb3, 0x35, 0xc8, 0xcc},
+	{0xb3, 0x35, 0xc8, 0xcc},	/* i2c add: 48 */
 	{0xb3, 0x02, 0x00, 0xcc},
 	{0xb3, 0x03, 0x0a, 0xcc},
 	{0xb3, 0x04, 0x05, 0xcc},
@@ -1359,7 +1451,8 @@ static const u8 po3130_initVGA_data[][4]
 	{0xb3, 0x23, 0xe8, 0xcc},	{0xb8, 0x08, 0xe8, 0xcc},
 	{0xb3, 0x14, 0x00, 0xcc},	{0xb3, 0x15, 0x00, 0xcc},
 	{0xb3, 0x16, 0x02, 0xcc},	{0xb3, 0x17, 0x7f, 0xcc},
-	{0xb3, 0x34, 0x01, 0xcc},	{0xb3, 0x35, 0xf6, 0xcc},
+	{0xb3, 0x34, 0x01, 0xcc},
+	{0xb3, 0x35, 0xf6, 0xcc},	/* i2c add: 76 */
 	{0xb3, 0x00, 0x27, 0xcc},	{0xbc, 0x00, 0x71, 0xcc},
 	{0xb8, 0x00, 0x21, 0xcc},	{0xb8, 0x27, 0x20, 0xcc},
 	{0xb8, 0x01, 0x79, 0xcc},	{0xb8, 0x81, 0x09, 0xcc},
@@ -1561,7 +1654,7 @@ static const u8 hv7131r_initVGA_data[][4
 	{0xb3, 0x16, 0x02, 0xcc},
 	{0xb3, 0x17, 0x7f, 0xcc},
 	{0xb3, 0x34, 0x01, 0xcc},
-	{0xb3, 0x35, 0x91, 0xcc},
+	{0xb3, 0x35, 0x91, 0xcc},	/* i2c add: 11 */
 	{0xb3, 0x00, 0x27, 0xcc},
 	{0xbc, 0x00, 0x73, 0xcc},
 	{0xb8, 0x00, 0x23, 0xcc},
@@ -1747,7 +1840,8 @@ static const u8 ov7660_initVGA_data[][4]
 	{0xb3, 0x23, 0xe0, 0xcc},	{0xb3, 0x1d, 0x01, 0xcc},
 	{0xb3, 0x1f, 0x02, 0xcc},
 	{0xb3, 0x34, 0x01, 0xcc},
-	{0xb3, 0x35, 0xa1, 0xcc},	{0xb3, 0x00, 0x26, 0xcc},
+	{0xb3, 0x35, 0xa1, 0xcc},	/* i2c add: 21 */
+	{0xb3, 0x00, 0x26, 0xcc},
 	{0xb8, 0x00, 0x33, 0xcc}, /* 13 */
 	{0xb8, 0x01, 0x7d, 0xcc},
 	{0xbc, 0x00, 0x73, 0xcc},	{0xb8, 0x81, 0x09, 0xcc},
@@ -1883,7 +1977,8 @@ static const u8 ov7670_initVGA_JPG[][4]
 	{0x00, 0x00, 0x10, 0xdd},
 	{0xb0, 0x04, 0x02, 0xcc},	{0x00, 0x00, 0x10, 0xdd},
 	{0xb3, 0x00, 0x66, 0xcc},	{0xb3, 0x00, 0x67, 0xcc},
-	{0xb3, 0x35, 0xa1, 0xcc},	{0xb3, 0x34, 0x01, 0xcc},
+	{0xb3, 0x35, 0xa1, 0xcc},	/* i2c add: 21 */
+	{0xb3, 0x34, 0x01, 0xcc},
 	{0xb3, 0x05, 0x01, 0xcc},	{0xb3, 0x06, 0x01, 0xcc},
 	{0xb3, 0x08, 0x01, 0xcc},	{0xb3, 0x09, 0x0c, 0xcc},
 	{0xb3, 0x02, 0x02, 0xcc},	{0xb3, 0x03, 0x1f, 0xcc},
@@ -2181,7 +2276,7 @@ static const u8 po1200_initVGA_data[][4]
 	{0xb0, 0x54, 0x13, 0xcc},
 	{0xb3, 0x00, 0x67, 0xcc},
 	{0xb3, 0x34, 0x01, 0xcc},
-	{0xb3, 0x35, 0xdc, 0xcc},
+	{0xb3, 0x35, 0xdc, 0xcc},	/* i2c add: 5c */
 	{0x00, 0x03, 0x00, 0xaa},
 	{0x00, 0x12, 0x05, 0xaa},
 	{0x00, 0x13, 0x02, 0xaa},
@@ -2408,6 +2503,251 @@ static const u8 po1200_initVGA_data[][4]
 	{0x00, 0xb6, 0x39, 0xaa},
 	{0x00, 0xb7, 0x24, 0xaa},
 /*write 89 0400 1415*/
+	{}
+};
+
+static const u8 poxxxx_init_common[][4] = {
+	{0xb3, 0x00, 0x04, 0xcc},
+	{0x00, 0x00, 0x10, 0xdd},
+	{0xb3, 0x00, 0x64, 0xcc},
+	{0x00, 0x00, 0x10, 0xdd},
+	{0xb3, 0x00, 0x65, 0xcc},
+	{0x00, 0x00, 0x10, 0xdd},
+	{0xb3, 0x00, 0x67, 0xcc},
+	{0xb0, 0x03, 0x09, 0xcc},
+	{0xb3, 0x05, 0x00, 0xcc},
+	{0xb3, 0x06, 0x00, 0xcc},
+	{0xb3, 0x5c, 0x01, 0xcc},
+	{0xb3, 0x08, 0x01, 0xcc},
+	{0xb3, 0x09, 0x0c, 0xcc},
+	{0xb3, 0x34, 0x01, 0xcc},
+	{0xb3, 0x35, 0xf6, 0xcc},	/* i2c add: 76 */
+	{0xb3, 0x02, 0xb0, 0xcc},
+	{0xb3, 0x03, 0x18, 0xcc},
+	{0xb3, 0x04, 0x15, 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, 0x2c, 0x03, 0xcc},
+	{0xb3, 0x2d, 0x56, 0xcc},
+	{0xb3, 0x2e, 0x02, 0xcc},
+	{0xb3, 0x2f, 0x0a, 0xcc},
+	{0xb3, 0x40, 0x00, 0xcc},
+	{0xb3, 0x41, 0x34, 0xcc},
+	{0xb3, 0x42, 0x01, 0xcc},
+	{0xb3, 0x43, 0xe0, 0xcc},
+	{0xbc, 0x00, 0x71, 0xcc},
+	{0xbc, 0x01, 0x01, 0xcc},
+	{0xb3, 0x01, 0x41, 0xcc},
+	{0xb3, 0x4d, 0x00, 0xcc},
+	{0x00, 0x0b, 0x2a, 0xaa},
+	{0x00, 0x0e, 0x03, 0xaa},
+	{0x00, 0x0f, 0xea, 0xaa},
+	{0x00, 0x12, 0x08, 0xaa},
+	{0x00, 0x1e, 0x06, 0xaa},
+	{0x00, 0x21, 0x00, 0xaa},
+	{0x00, 0x31, 0x1f, 0xaa},
+	{0x00, 0x33, 0x38, 0xaa},
+	{0x00, 0x36, 0xc0, 0xaa},
+	{0x00, 0x37, 0xc8, 0xaa},
+	{0x00, 0x3b, 0x36, 0xaa},
+	{0x00, 0x4b, 0xfe, 0xaa},
+	{0x00, 0x4d, 0x2e, 0xaa},
+	{0x00, 0x51, 0x1c, 0xaa},
+	{0x00, 0x52, 0x01, 0xaa},
+	{0x00, 0x55, 0x0a, 0xaa},
+	{0x00, 0x56, 0x0a, 0xaa},
+	{0x00, 0x57, 0x07, 0xaa},
+	{0x00, 0x58, 0x07, 0xaa},
+	{0x00, 0x59, 0x04, 0xaa},
+	{0x00, 0x70, 0x68, 0xaa},
+	{0x00, 0x71, 0x04, 0xaa},
+	{0x00, 0x72, 0x10, 0xaa},
+	{0x00, 0x80, 0x71, 0xaa},
+	{0x00, 0x81, 0x08, 0xaa},
+	{0x00, 0x82, 0x00, 0xaa},
+	{0x00, 0x83, 0x55, 0xaa},
+	{0x00, 0x84, 0x06, 0xaa},
+	{0x00, 0x85, 0x06, 0xaa},
+	{0x00, 0x8b, 0x25, 0xaa},
+	{0x00, 0x8c, 0x00, 0xaa},
+	{0x00, 0x8d, 0x86, 0xaa},
+	{0x00, 0x8e, 0x82, 0xaa},
+	{0x00, 0x8f, 0x2d, 0xaa},
+	{0x00, 0x90, 0x8b, 0xaa},
+	{0x00, 0x91, 0x81, 0xaa},
+	{0x00, 0x92, 0x81, 0xaa},
+	{0x00, 0x93, 0x23, 0xaa},
+	{0x00, 0xa3, 0x2a, 0xaa},
+	{0x00, 0xa4, 0x03, 0xaa},
+	{0x00, 0xa5, 0xea, 0xaa},
+	{0x00, 0xb0, 0x68, 0xaa},
+	{0x00, 0xbc, 0x04, 0xaa},
+	{0x00, 0xbe, 0x3b, 0xaa},
+	{0x00, 0x4e, 0x40, 0xaa},
+	{0x00, 0x06, 0x04, 0xaa},
+	{0x00, 0x07, 0x03, 0xaa},
+	{0x00, 0xcd, 0x18, 0xaa},
+	{0x00, 0x28, 0x03, 0xaa},
+	{0x00, 0x29, 0xef, 0xaa},
+/* reinit on alt 2 (qvga) or alt7 (vga) */
+	{0xb3, 0x05, 0x00, 0xcc},
+	{0xb3, 0x06, 0x00, 0xcc},
+	{0xb8, 0x00, 0x01, 0xcc},
+
+	{0x00, 0x1d, 0x85, 0xaa},
+	{0x00, 0x1e, 0xc6, 0xaa},
+	{0x00, 0x00, 0x40, 0xdd},
+	{0x00, 0x1d, 0x05, 0xaa},
+
+	{0x00, 0xd6, 0x22, 0xaa},	/* gamma 0 */
+	{0x00, 0x73, 0x00, 0xaa},
+	{0x00, 0x74, 0x0a, 0xaa},
+	{0x00, 0x75, 0x16, 0xaa},
+	{0x00, 0x76, 0x25, 0xaa},
+	{0x00, 0x77, 0x34, 0xaa},
+	{0x00, 0x78, 0x49, 0xaa},
+	{0x00, 0x79, 0x5a, 0xaa},
+	{0x00, 0x7a, 0x7f, 0xaa},
+	{0x00, 0x7b, 0x9b, 0xaa},
+	{0x00, 0x7c, 0xba, 0xaa},
+	{0x00, 0x7d, 0xd4, 0xaa},
+	{0x00, 0x7e, 0xea, 0xaa},
+
+	{0x00, 0xd6, 0x62, 0xaa},	/* gamma 1 */
+	{0x00, 0x73, 0x00, 0xaa},
+	{0x00, 0x74, 0x0a, 0xaa},
+	{0x00, 0x75, 0x16, 0xaa},
+	{0x00, 0x76, 0x25, 0xaa},
+	{0x00, 0x77, 0x34, 0xaa},
+	{0x00, 0x78, 0x49, 0xaa},
+	{0x00, 0x79, 0x5a, 0xaa},
+	{0x00, 0x7a, 0x7f, 0xaa},
+	{0x00, 0x7b, 0x9b, 0xaa},
+	{0x00, 0x7c, 0xba, 0xaa},
+	{0x00, 0x7d, 0xd4, 0xaa},
+	{0x00, 0x7e, 0xea, 0xaa},
+
+	{0x00, 0xd6, 0xa2, 0xaa},	/* gamma 2 */
+	{0x00, 0x73, 0x00, 0xaa},
+	{0x00, 0x74, 0x0a, 0xaa},
+	{0x00, 0x75, 0x16, 0xaa},
+	{0x00, 0x76, 0x25, 0xaa},
+	{0x00, 0x77, 0x34, 0xaa},
+	{0x00, 0x78, 0x49, 0xaa},
+	{0x00, 0x79, 0x5a, 0xaa},
+	{0x00, 0x7a, 0x7f, 0xaa},
+	{0x00, 0x7b, 0x9b, 0xaa},
+	{0x00, 0x7c, 0xba, 0xaa},
+	{0x00, 0x7d, 0xd4, 0xaa},
+	{0x00, 0x7e, 0xea, 0xaa},
+
+	{0x00, 0xaa, 0xff, 0xaa},	/* back light comp */
+	{0x00, 0xc4, 0x03, 0xaa},
+	{0x00, 0xc5, 0x19, 0xaa},
+	{0x00, 0xc6, 0x03, 0xaa},
+	{0x00, 0xc7, 0x91, 0xaa},
+	{0x00, 0xc8, 0x01, 0xaa},
+	{0x00, 0xc9, 0xdd, 0xaa},
+	{0x00, 0xca, 0x02, 0xaa},
+	{0x00, 0xcb, 0x37, 0xaa},
+
+/* read d1 */
+	{0x00, 0xd1, 0x3c, 0xaa},
+	{0x00, 0xb8, 0x28, 0xaa},
+	{0x00, 0xb9, 0x1e, 0xaa},
+	{0x00, 0xb6, 0x14, 0xaa},
+	{0x00, 0xb7, 0x0f, 0xaa},
+	{0x00, 0x5c, 0x10, 0xaa},
+	{0x00, 0x5d, 0x18, 0xaa},
+	{0x00, 0x5e, 0x24, 0xaa},
+	{0x00, 0x5f, 0x24, 0xaa},
+	{0x00, 0x86, 0x1a, 0xaa},
+	{0x00, 0x60, 0x00, 0xaa},
+	{0x00, 0x61, 0x1b, 0xaa},
+	{0x00, 0x62, 0x30, 0xaa},
+	{0x00, 0x63, 0x40, 0xaa},
+	{0x00, 0x87, 0x1a, 0xaa},
+	{0x00, 0x64, 0x00, 0xaa},
+	{0x00, 0x65, 0x08, 0xaa},
+	{0x00, 0x66, 0x10, 0xaa},
+	{0x00, 0x67, 0x20, 0xaa},
+	{0x00, 0x88, 0x10, 0xaa},
+	{0x00, 0x68, 0x00, 0xaa},
+	{0x00, 0x69, 0x08, 0xaa},
+	{0x00, 0x6a, 0x0f, 0xaa},
+	{0x00, 0x6b, 0x0f, 0xaa},
+	{0x00, 0x89, 0x07, 0xaa},
+	{0x00, 0xd5, 0x4c, 0xaa},
+	{0x00, 0x0a, 0x00, 0xaa},
+	{0x00, 0x0b, 0x2a, 0xaa},
+	{0x00, 0x0e, 0x03, 0xaa},
+	{0x00, 0x0f, 0xea, 0xaa},
+	{0x00, 0xa2, 0x00, 0xaa},
+	{0x00, 0xa3, 0x2a, 0xaa},
+	{0x00, 0xa4, 0x03, 0xaa},
+	{0x00, 0xa5, 0xea, 0xaa},
+	{}
+};
+static const u8 poxxxx_initVGA[][4] = {
+	{0x00, 0x20, 0x11, 0xaa},
+	{0x00, 0x33, 0x38, 0xaa},
+	{0x00, 0xbb, 0x0d, 0xaa},
+	{0xb3, 0x22, 0x01, 0xcc},
+	{0xb3, 0x23, 0xe0, 0xcc},
+	{0xb3, 0x16, 0x02, 0xcc},
+	{0xb3, 0x17, 0x7f, 0xcc},
+	{0xb3, 0x02, 0xb0, 0xcc},
+	{0xb3, 0x06, 0x00, 0xcc},
+	{0xb3, 0x5c, 0x01, 0xcc},
+	{0x00, 0x04, 0x06, 0xaa},
+	{0x00, 0x05, 0x3f, 0xaa},
+	{0x00, 0x04, 0x00, 0xdd},	/* delay 1s */
+	{}
+};
+static const u8 poxxxx_initQVGA[][4] = {
+	{0x00, 0x20, 0x33, 0xaa},
+	{0x00, 0x33, 0x38, 0xaa},
+	{0x00, 0xbb, 0x0d, 0xaa},
+	{0xb3, 0x22, 0x00, 0xcc},
+	{0xb3, 0x23, 0xf0, 0xcc},
+	{0xb3, 0x16, 0x01, 0xcc},
+	{0xb3, 0x17, 0x3f, 0xcc},
+	{0xb3, 0x02, 0xb0, 0xcc},
+	{0xb3, 0x06, 0x01, 0xcc},
+	{0xb3, 0x5c, 0x00, 0xcc},
+	{0x00, 0x04, 0x06, 0xaa},
+	{0x00, 0x05, 0x3f, 0xaa},
+	{0x00, 0x04, 0x00, 0xdd},	/* delay 1s */
+	{}
+};
+static const u8 poxxxx_init_end_1[][4] = {
+	{0x00, 0x47, 0x25, 0xaa},
+	{0x00, 0x48, 0x80, 0xaa},
+	{0x00, 0x49, 0x1f, 0xaa},
+	{0x00, 0x4a, 0x40, 0xaa},
+	{0x00, 0x44, 0x40, 0xaa},
+	{0x00, 0xab, 0x4a, 0xaa},
+	{0x00, 0xb1, 0x00, 0xaa},
+	{0x00, 0xb2, 0x04, 0xaa},
+	{0x00, 0xb3, 0x08, 0xaa},
+	{0x00, 0xb4, 0x0b, 0xaa},
+	{0x00, 0xb5, 0x0d, 0xaa},
+	{0x00, 0x59, 0x7e, 0xaa},	/* sharpness */
+	{0x00, 0x16, 0x00, 0xaa},	/* white balance */
+	{0x00, 0x18, 0x00, 0xaa},
+	{}
+};
+static const u8 poxxxx_init_end_2[][4] = {
+	{0x00, 0x1d, 0x85, 0xaa},
+	{0x00, 0x1e, 0x06, 0xaa},
+	{0x00, 0x1d, 0x05, 0xaa},
+	{}
 };
 
 struct sensor_info {
@@ -2420,33 +2760,89 @@ struct sensor_info {
 	u8 op;
 };
 
-static const struct sensor_info sensor_info_data[] = {
-/*      sensorId,         I2cAdd,	IdAdd,  VpId,  m1,    m2,  op */
+/* probe values */
+static const struct sensor_info vc0321_probe_data[] = {
+/*      sensorId,	   I2cAdd,	IdAdd,  VpId,  m1,    m2,  op */
+/* 0 OV9640 */
 	{-1,		    0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
+/* 1 ICM108T (may respond on IdAdd == 0x83 - tested in vc032x_probe_sensor) */
 	{-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},
+/* 2 PO2130 (may detect PO3130NC - tested in vc032x_probe_sensor)*/
+	{-1,		    0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01},
+/* 3 MI1310 */
+	{-1,		    0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01},
+/* 4 MI360 - tested in vc032x_probe_sensor */
+/*	{SENSOR_MI0360,	    0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */
+/* 5 7131R */
+	{SENSOR_HV7131R,    0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
+/* 6 OV7649 */
+	{-1,		    0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05},
+/* 7 PAS302BCW */
+	{-1,		    0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05},
+/* 8 OV7660 */
+	{SENSOR_OV7660,     0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
+/* 9 PO3130NC - (tested in vc032x_probe_sensor) */
+/*	{SENSOR_PO3130NC,   0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, */
+/* 10 PO1030KC */
+	{-1,		    0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
+/* 11 MI1310_SOC */
 	{SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
-/* (tested in vc032x_probe_sensor) */
+/* 12 OV9650 */
+	{-1,		    0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
+/* 13 S5K532 */
+	{-1,		    0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01},
+/* 14 MI360_SOC - ??? */
+/* 15 PO1200N */
+	{SENSOR_PO1200,     0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01},
+/* 16 PO3030K */
+	{-1,		    0x80 | 0x18, 0x00, 0x0000, 0x24, 0x25, 0x01},
+/* 17 PO2030 */
+	{-1,		    0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
+/* ?? */
+	{-1,		    0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01},
+	{SENSOR_MI1320,     0x80 | 0x48, 0x00, 0x148c, 0x64, 0x65, 0x01},
+};
+static const struct sensor_info vc0323_probe_data[] = {
+/*      sensorId,	   I2cAdd,	IdAdd,  VpId,  m1,    m2,  op */
+/* 0 OV9640 */
+	{-1,		    0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
+/* 1 ICM108T (may respond on IdAdd == 0x83 - tested in vc032x_probe_sensor) */
+	{-1,		    0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01},
+/* 2 PO2130 (may detect PO3130NC - tested in vc032x_probe_sensor)*/
+	{-1,		    0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01},
+/* 3 MI1310 */
+	{-1,		    0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01},
+/* 4 MI360 - tested in vc032x_probe_sensor */
 /*	{SENSOR_MI0360,	    0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */
+/* 5 7131R */
 	{SENSOR_HV7131R,    0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
+/* 6 OV7649 */
 	{-1,		    0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05},
+/* 7 PAS302BCW */
 	{-1,		    0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05},
+/* 8 OV7660 */
 	{SENSOR_OV7660,     0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
-/*	{SENSOR_PO3130NC,   0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01}, */
+/* 9 PO3130NC - (tested in vc032x_probe_sensor) */
+/*	{SENSOR_PO3130NC,   0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, */
+/* 10 PO1030KC */
 	{-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}, */
+/* 11 MI1310_SOC */
+	{SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
+/* 12 OV9650 */
+	{-1,		    0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
+/* 13 S5K532 */
 	{-1,		    0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01},
+/* 14 MI360_SOC - ??? */
+/* 15 PO1200N */
 	{SENSOR_PO1200,     0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01},
+/* 16 ?? */
 	{-1,		    0x80 | 0x2d, 0x00, 0x0000, 0x65, 0x67, 0x01},
+/* 17 PO2030 */
 	{-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?*/
+/*fixme: not in the ms-win probe - may be found before? */
 	{SENSOR_OV7670,     0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05},
 };
 
@@ -2520,7 +2916,7 @@ static int vc032x_probe_sensor(struct gs
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct usb_device *dev = gspca_dev->dev;
-	int i;
+	int i, n;
 	u16 value;
 	const struct sensor_info *ptsensor_info;
 
@@ -2531,9 +2927,16 @@ static int vc032x_probe_sensor(struct gs
 	}
 
 	reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
-	PDEBUG(D_PROBE, "check sensor header %02x", gspca_dev->usb_buf[0]);
-	for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) {
-		ptsensor_info = &sensor_info_data[i];
+	PDEBUG(D_PROBE, "vc032%d check sensor header %02x",
+		sd->bridge == BRIDGE_VC0321 ? 1 : 3, gspca_dev->usb_buf[0]);
+	if (sd->bridge == BRIDGE_VC0321) {
+		ptsensor_info = vc0321_probe_data;
+		n = ARRAY_SIZE(vc0321_probe_data);
+	} else {
+		ptsensor_info = vc0323_probe_data;
+		n = ARRAY_SIZE(vc0323_probe_data);
+	}
+	for (i = 0; i < n; i++) {
 		reg_w(dev, 0xa0, 0x02, 0xb334);
 		reg_w(dev, 0xa0, ptsensor_info->m1, 0xb300);
 		reg_w(dev, 0xa0, ptsensor_info->m2, 0xb300);
@@ -2551,13 +2954,15 @@ static int vc032x_probe_sensor(struct gs
 				return ptsensor_info->sensorId;
 
 			switch (value) {
+			case 0x3130:
+				return SENSOR_PO3130NC;
 			case 0x7673:
 				return SENSOR_OV7670;
 			case 0x8243:
 				return SENSOR_MI0360;
 			}
-/*fixme: should return here*/
 		}
+		ptsensor_info++;
 	}
 	return -1;
 }
@@ -2619,7 +3024,7 @@ static void usb_exchange(struct gspca_de
 			i2c_write(gspca_dev, data[i][0], &data[i][1], 2);
 			break;
 		case 0xdd:
-			msleep(data[i][2] + 10);
+			msleep(data[i][1] * 256 + data[i][2] + 10);
 			break;
 		}
 		i++;
@@ -2646,12 +3051,17 @@ static int sd_config(struct gspca_dev *g
 		64,		/* OV7670 6 */
 		128,		/* PO1200 7 */
 		128,		/* PO3130NC 8 */
+		128,		/* POxxxx 9 */
 	};
 
 	cam = &gspca_dev->cam;
 	sd->bridge = id->driver_info >> 8;
 	sd->flags = id->driver_info & 0xff;
-	sensor = vc032x_probe_sensor(gspca_dev);
+	if (id->idVendor == 0x046d &&
+	    (id->idProduct == 0x0892 || id->idProduct == 0x0896))
+		sensor = SENSOR_POxxxx;
+	else
+		sensor = vc032x_probe_sensor(gspca_dev);
 	switch (sensor) {
 	case -1:
 		PDEBUG(D_PROBE, "Unknown sensor...");
@@ -2684,6 +3094,9 @@ static int sd_config(struct gspca_dev *g
 	case SENSOR_PO3130NC:
 		PDEBUG(D_PROBE, "Find Sensor PO3130NC");
 		break;
+	case SENSOR_POxxxx:
+		PDEBUG(D_PROBE, "Sensor POxxxx");
+		break;
 	}
 	sd->sensor = sensor;
 
@@ -2712,28 +3125,19 @@ static int sd_config(struct gspca_dev *g
 	}
 	cam->npkt = npkt[sd->sensor];
 
+	sd->brightness = BRIGHTNESS_DEF;
+	sd->contrast = CONTRAST_DEF;
+	sd->colors = COLOR_DEF;
 	sd->hflip = HFLIP_DEF;
 	sd->vflip = VFLIP_DEF;
-	if (sd->sensor == SENSOR_OV7670)
-		sd->flags |= FL_HFLIP | FL_VFLIP;
 	sd->lightfreq = FREQ_DEF;
-	if (sd->sensor != SENSOR_OV7670)
-		gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
-	switch (sd->sensor) {
-	case SENSOR_MI1310_SOC:
-	case SENSOR_MI1320_SOC:
-	case SENSOR_OV7660:
-	case SENSOR_OV7670:
-	case SENSOR_PO1200:
-		break;
-	default:
-		gspca_dev->ctrl_dis = (1 << HFLIP_IDX)
-					| (1 << VFLIP_IDX);
-		break;
-	}
-
 	sd->sharpness = SHARPNESS_DEF;
 
+	gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
+
+	if (sd->sensor == SENSOR_OV7670)
+		sd->flags |= FL_HFLIP | FL_VFLIP;
+
 	if (sd->bridge == BRIDGE_VC0321) {
 		reg_r(gspca_dev, 0x8a, 0, 3);
 		reg_w(dev, 0x87, 0x00, 0x0f0f);
@@ -2747,10 +3151,55 @@ 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)
 {
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->sensor == SENSOR_POxxxx) {
+		reg_r(gspca_dev, 0xa1, 0xb300, 1);
+		if (gspca_dev->usb_buf[0] != 0) {
+			reg_w(gspca_dev->dev, 0xa0, 0x26, 0xb300);
+			reg_w(gspca_dev->dev, 0xa0, 0x04, 0xb300);
+			reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb300);
+		}
+	}
 	return 0;
 }
 
-/* some sensors only */
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 data;
+
+	if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX))
+		return;
+	data = sd->brightness;
+	if (data >= 0x80)
+		data &= 0x7f;
+	else
+		data = 0xff ^ data;
+	i2c_write(gspca_dev, 0x98, &data, 1);
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (gspca_dev->ctrl_dis & (1 << CONTRAST_IDX))
+		return;
+	i2c_write(gspca_dev, 0x99, &sd->contrast, 1);
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 data;
+
+	if (gspca_dev->ctrl_dis & (1 << COLORS_IDX))
+		return;
+	data = sd->colors - (sd->colors >> 3) - 1;
+	i2c_write(gspca_dev, 0x94, &data, 1);
+	i2c_write(gspca_dev, 0x95, &sd->colors, 1);
+}
+
 static void sethvflip(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -2764,6 +3213,7 @@ static void sethvflip(struct gspca_dev *
 		vflip = !vflip;
 	switch (sd->sensor) {
 	case SENSOR_MI1310_SOC:
+	case SENSOR_MI1320:
 	case SENSOR_MI1320_SOC:
 		data[0] = data[1] = 0;		/* select page 0 */
 		i2c_write(gspca_dev, 0xf0, data, 2);
@@ -2801,18 +3251,29 @@ static void setlightfreq(struct gspca_de
 	usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]);
 }
 
-/* po1200 only */
 static void setsharpness(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 data;
 
-	if (sd->sensor != SENSOR_PO1200)
-		return;
-	data = 0;
-	i2c_write(gspca_dev, 0x03, &data, 1);
-	data = 0xb5 + sd->sharpness * 3;
-	i2c_write(gspca_dev, 0x61, &data, 1);
+	switch (sd->sensor) {
+	case SENSOR_PO1200:
+		data = 0;
+		i2c_write(gspca_dev, 0x03, &data, 1);
+		if (sd->sharpness < 0)
+			data = 0x6a;
+		else
+			data = 0xb5 + sd->sharpness * 3;
+		i2c_write(gspca_dev, 0x61, &data, 1);
+		break;
+	case SENSOR_POxxxx:
+		if (sd->sharpness < 0)
+			data = 0x7e;	/* def = max */
+		else
+			data = 0x60 + sd->sharpness * 0x0f;
+		i2c_write(gspca_dev, 0x59, &data, 1);
+		break;
+	}
 }
 
 static int sd_start(struct gspca_dev *gspca_dev)
@@ -2922,12 +3383,27 @@ static int sd_start(struct gspca_dev *gs
 		usb_exchange(gspca_dev, init);
 		init = po3130_rundata;
 		break;
-	default:
-/*	case SENSOR_PO1200: */
+	case SENSOR_PO1200:
 		GammaT = po1200_gamma;
 		MatrixT = po1200_matrix;
 		init = po1200_initVGA_data;
 		break;
+	default:
+/*	case SENSOR_POxxxx: */
+		usb_exchange(gspca_dev, poxxxx_init_common);
+		if (mode)
+			init = poxxxx_initQVGA;
+		else
+			init = poxxxx_initVGA;
+		usb_exchange(gspca_dev, init);
+		reg_r(gspca_dev, 0x8c, 0x0000, 3);
+		reg_w(gspca_dev->dev, 0xa0,
+				gspca_dev->usb_buf[2] & 1 ? 0 : 1,
+				0xb35c);
+		msleep(300);
+/*fixme: i2c read 04 and 05*/
+		init = poxxxx_init_end_1;
+		break;
 	}
 	usb_exchange(gspca_dev, init);
 	if (GammaT && MatrixT) {
@@ -2936,7 +3412,6 @@ static int sd_start(struct gspca_dev *gs
 		put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c);
 		put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c);
 
-		/* set the led on 0x0892 0x0896 */
 		switch (sd->sensor) {
 		case SENSOR_PO1200:
 		case SENSOR_HV7131R:
@@ -2945,16 +3420,22 @@ static int sd_start(struct gspca_dev *gs
 		case SENSOR_MI1310_SOC:
 			reg_w(gspca_dev->dev, 0x89, 0x058c, 0x0000);
 			break;
-		default:
-			if (!(sd->flags & FL_SAMSUNG))
-				reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
-			break;
 		}
 		msleep(100);
 		setsharpness(gspca_dev);
 		sethvflip(gspca_dev);
 		setlightfreq(gspca_dev);
 	}
+	if (sd->sensor == SENSOR_POxxxx) {
+		setcolors(gspca_dev);
+		setbrightness(gspca_dev);
+		setcontrast(gspca_dev);
+
+		/* led on */
+		msleep(80);
+		reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
+		usb_exchange(gspca_dev, poxxxx_init_end_2);
+	}
 	return 0;
 }
 
@@ -2963,10 +3444,17 @@ static void sd_stopN(struct gspca_dev *g
 	struct usb_device *dev = gspca_dev->dev;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	if (sd->sensor == SENSOR_MI1310_SOC)
+	switch (sd->sensor) {
+	case SENSOR_MI1310_SOC:
 		reg_w(dev, 0x89, 0x058c, 0x00ff);
-	else if (!(sd->flags & FL_SAMSUNG))
-		reg_w(dev, 0x89, 0xffff, 0xffff);
+		break;
+	case SENSOR_POxxxx:
+		return;
+	default:
+		if (!(sd->flags & FL_SAMSUNG))
+			reg_w(dev, 0x89, 0xffff, 0xffff);
+		break;
+	}
 	reg_w(dev, 0xa0, 0x01, 0xb301);
 	reg_w(dev, 0xa0, 0x09, 0xb003);
 }
@@ -2984,6 +3472,12 @@ static void sd_stop0(struct gspca_dev *g
 		reg_w(dev, 0x89, 0x058c, 0x00ff);
 	else if (!(sd->flags & FL_SAMSUNG))
 		reg_w(dev, 0x89, 0xffff, 0xffff);
+
+	if (sd->sensor == SENSOR_POxxxx) {
+		reg_w(dev, 0xa0, 0x26, 0xb300);
+		reg_w(dev, 0xa0, 0x04, 0xb300);
+		reg_w(dev, 0xa0, 0x00, 0xb300);
+	}
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -3020,6 +3514,60 @@ static void sd_pkt_scan(struct gspca_dev
 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->brightness = val;
+	if (gspca_dev->streaming)
+		setbrightness(gspca_dev);
+	return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->brightness;
+	return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->contrast = val;
+	if (gspca_dev->streaming)
+		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;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->colors = val;
+	if (gspca_dev->streaming)
+		setcolors(gspca_dev);
+	return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->colors;
+	return 0;
+}
+
 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/gspca/zc3xx.c linux-libre-2.6.34-gnu1/drivers/media/video/gspca/zc3xx.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/gspca/zc3xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/gspca/zc3xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,9 +1,8 @@
 /*
- *	Z-Star/Vimicro zc301/zc302p/vc30x library
- *	Copyright (C) 2004 2005 2006 Michel Xhaard
- *		mxhaard@magic.fr
+ * Z-Star/Vimicro zc301/zc302p/vc30x library
  *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ * Copyright (C) 2009-2010 Jean-Francois Moine <http://moinejf.free.fr>
+ * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,10 +21,12 @@
 
 #define MODULE_NAME "zc3xx"
 
+#include <linux/input.h>
+#include <linux/slab.h>
 #include "gspca.h"
 #include "jpeg.h"
 
-MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, "
+MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
 		"Serge A. Suchkov <Serge.A.S@tochka.ru>");
 MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -39,18 +40,18 @@ static int force_sensor = -1;
 struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
 
-	__u8 brightness;
-	__u8 contrast;
-	__u8 gamma;
-	__u8 autogain;
-	__u8 lightfreq;
-	__u8 sharpness;
+	u8 brightness;
+	u8 contrast;
+	u8 gamma;
+	u8 autogain;
+	u8 lightfreq;
+	u8 sharpness;
 	u8 quality;			/* image quality */
 #define QUALITY_MIN 40
 #define QUALITY_MAX 60
 #define QUALITY_DEF 50
 
-	signed char sensor;		/* Type of image sensor chip */
+	u8 sensor;		/* Type of image sensor chip */
 /* !! values used in different tables */
 #define SENSOR_ADCM2700 0
 #define SENSOR_CS2102 1
@@ -92,9 +93,8 @@ static int sd_getfreq(struct gspca_dev *
 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[] = {
+static const struct ctrl sd_ctrls[] = {
 #define BRIGHTNESS_IDX 0
-#define SD_BRIGHTNESS 0
 	{
 	    {
 		.id      = V4L2_CID_BRIGHTNESS,
@@ -103,26 +103,26 @@ static struct ctrl sd_ctrls[] = {
 		.minimum = 0,
 		.maximum = 255,
 		.step    = 1,
-		.default_value = 128,
+#define BRIGHTNESS_DEF 128
+		.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 = 256,
+		.maximum = 255,
 		.step    = 1,
-		.default_value = 128,
+#define CONTRAST_DEF 128
+		.default_value = CONTRAST_DEF,
 	    },
 	    .set = sd_setcontrast,
 	    .get = sd_getcontrast,
 	},
-#define SD_GAMMA 2
 	{
 	    {
 		.id      = V4L2_CID_GAMMA,
@@ -136,7 +136,6 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setgamma,
 	    .get = sd_getgamma,
 	},
-#define SD_AUTOGAIN 3
 	{
 	    {
 		.id      = V4L2_CID_AUTOGAIN,
@@ -145,13 +144,13 @@ static struct ctrl sd_ctrls[] = {
 		.minimum = 0,
 		.maximum = 1,
 		.step    = 1,
-		.default_value = 1,
+#define AUTOGAIN_DEF 1
+		.default_value = AUTOGAIN_DEF,
 	    },
 	    .set = sd_setautogain,
 	    .get = sd_getautogain,
 	},
 #define LIGHTFREQ_IDX 4
-#define SD_FREQ 4
 	{
 	    {
 		.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -160,12 +159,12 @@ static struct ctrl sd_ctrls[] = {
 		.minimum = 0,
 		.maximum = 2,	/* 0: 0, 1: 50Hz, 2:60Hz */
 		.step    = 1,
-		.default_value = 1,
+#define FREQ_DEF 0
+		.default_value = FREQ_DEF,
 	    },
 	    .set = sd_setfreq,
 	    .get = sd_getfreq,
 	},
-#define SD_SHARPNESS 5
 	{
 	    {
 		.id	 = V4L2_CID_SHARPNESS,
@@ -174,7 +173,8 @@ static struct ctrl sd_ctrls[] = {
 		.minimum = 0,
 		.maximum = 3,
 		.step    = 1,
-		.default_value = 2,
+#define SHARPNESS_DEF 2
+		.default_value = SHARPNESS_DEF,
 	    },
 	    .set = sd_setsharpness,
 	    .get = sd_getsharpness,
@@ -194,6 +194,19 @@ static const struct v4l2_pix_format vga_
 		.priv = 0},
 };
 
+static const struct v4l2_pix_format broken_vga_mode[] = {
+	{320, 232, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 232 * 4 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 1},
+	{640, 472, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 472 * 3 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 0},
+};
+
 static const struct v4l2_pix_format sif_mode[] = {
 	{176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 		.bytesperline = 176,
@@ -209,9 +222,9 @@ static const struct v4l2_pix_format sif_
 
 /* usb exchanges */
 struct usb_action {
-	__u8	req;
-	__u8	val;
-	__u16	idx;
+	u8	req;
+	u8	val;
+	u16	idx;
 };
 
 static const struct usb_action adcm2700_Initial[] = {
@@ -421,7 +434,7 @@ static const struct usb_action adcm2700_
 	{0xaa, 0xfe, 0x0010},				/* 00,fe,10,aa */
 	{}
 };
-static const struct usb_action cs2102_Initial[] = {	/* 320x240 */
+static const struct usb_action cs2102_InitialScale[] = {	/* 320x240 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -473,7 +486,7 @@ static const struct usb_action cs2102_In
 	{}
 };
 
-static const struct usb_action cs2102_InitialScale[] = {	/* 640x480 */
+static const struct usb_action cs2102_Initial[] = {	/* 640x480 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -524,7 +537,7 @@ static const struct usb_action cs2102_In
 	{0xa0, 0x00, 0x01ad},
 	{}
 };
-static const struct usb_action cs2102_50HZ[] = {
+static const struct usb_action cs2102_50HZScale[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
 	{0xaa, 0x23, 0x0001},
 	{0xaa, 0x24, 0x005f},
@@ -546,7 +559,7 @@ static const struct usb_action cs2102_50
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
 	{}
 };
-static const struct usb_action cs2102_50HZScale[] = {
+static const struct usb_action cs2102_50HZ[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
 	{0xaa, 0x23, 0x0000},
 	{0xaa, 0x24, 0x00af},
@@ -568,7 +581,7 @@ static const struct usb_action cs2102_50
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
 	{}
 };
-static const struct usb_action cs2102_60HZ[] = {
+static const struct usb_action cs2102_60HZScale[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
 	{0xaa, 0x23, 0x0001},
 	{0xaa, 0x24, 0x0055},
@@ -590,7 +603,7 @@ static const struct usb_action cs2102_60
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
 	{}
 };
-static const struct usb_action cs2102_60HZScale[] = {
+static const struct usb_action cs2102_60HZ[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
 	{0xaa, 0x23, 0x0000},
 	{0xaa, 0x24, 0x00aa},
@@ -612,7 +625,7 @@ static const struct usb_action cs2102_60
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
 	{}
 };
-static const struct usb_action cs2102_NoFliker[] = {
+static const struct usb_action cs2102_NoFlikerScale[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
 	{0xaa, 0x23, 0x0001},
 	{0xaa, 0x24, 0x005f},
@@ -634,7 +647,7 @@ static const struct usb_action cs2102_No
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
 	{}
 };
-static const struct usb_action cs2102_NoFlikerScale[] = {
+static const struct usb_action cs2102_NoFliker[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
 	{0xaa, 0x23, 0x0000},
 	{0xaa, 0x24, 0x00af},
@@ -658,7 +671,7 @@ static const struct usb_action cs2102_No
 };
 
 /* CS2102_KOCOM */
-static const struct usb_action cs2102K_Initial[] = {
+static const struct usb_action cs2102K_InitialScale[] = {
 	{0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
 	{0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
@@ -917,7 +930,7 @@ static const struct usb_action cs2102K_I
 	{}
 };
 
-static const struct usb_action cs2102K_InitialScale[] = {
+static const struct usb_action cs2102K_Initial[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -1495,7 +1508,7 @@ static const struct usb_action gc0305_No
 	{}
 };
 
-static const struct usb_action hdcs2020xb_Initial[] = {
+static const struct usb_action hdcs2020b_InitialScale[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* qtable 0x05 */
@@ -1627,7 +1640,7 @@ static const struct usb_action hdcs2020x
 	{0xa0, 0x40, ZC3XX_R118_BGAIN},
 	{}
 };
-static const struct usb_action hdcs2020xb_InitialScale[] = {
+static const struct usb_action hdcs2020b_Initial[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -1819,7 +1832,7 @@ static const struct usb_action hdcs2020b
 	{}
 };
 
-static const struct usb_action hv7131bxx_Initial[] = {		/* 320x240 */
+static const struct usb_action hv7131b_InitialScale[] = {	/* 320x240 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -1866,7 +1879,7 @@ static const struct usb_action hv7131bxx
 	{}
 };
 
-static const struct usb_action hv7131bxx_InitialScale[] = {	/* 640x480*/
+static const struct usb_action hv7131b_Initial[] = {	/* 640x480*/
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -2063,7 +2076,7 @@ static const struct usb_action hv7131b_N
 	{}
 };
 
-static const struct usb_action hv7131cxx_Initial[] = {
+static const struct usb_action hv7131r_InitialScale[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},
@@ -2157,7 +2170,7 @@ static const struct usb_action hv7131cxx
 	{}
 };
 
-static const struct usb_action hv7131cxx_InitialScale[] = {
+static const struct usb_action hv7131r_Initial[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 
 	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},	/* diff */
@@ -2259,7 +2272,7 @@ static const struct usb_action hv7131cxx
 	{}
 };
 
-static const struct usb_action icm105axx_Initial[] = {
+static const struct usb_action icm105a_InitialScale[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -2436,7 +2449,7 @@ static const struct usb_action icm105axx
 	{}
 };
 
-static const struct usb_action icm105axx_InitialScale[] = {
+static const struct usb_action icm105a_Initial[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -2615,7 +2628,7 @@ static const struct usb_action icm105axx
 	{0xa0, 0x40, ZC3XX_R118_BGAIN},
 	{}
 };
-static const struct usb_action icm105a_50HZ[] = {
+static const struct usb_action icm105a_50HZScale[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
 	{0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
 	{0xaa, 0x0c, 0x0020}, /* 00,0c,20,aa */
@@ -2646,7 +2659,7 @@ static const struct usb_action icm105a_5
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
 	{}
 };
-static const struct usb_action icm105a_50HZScale[] = {
+static const struct usb_action icm105a_50HZ[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
 	{0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
 	{0xaa, 0x0c, 0x008c}, /* 00,0c,8c,aa */
@@ -2679,7 +2692,7 @@ static const struct usb_action icm105a_5
 	{0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */
 	{}
 };
-static const struct usb_action icm105a_60HZ[] = {
+static const struct usb_action icm105a_60HZScale[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
 	{0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
 	{0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
@@ -2710,7 +2723,7 @@ static const struct usb_action icm105a_6
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
 	{}
 };
-static const struct usb_action icm105a_60HZScale[] = {
+static const struct usb_action icm105a_60HZ[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
 	{0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
 	{0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */
@@ -2743,7 +2756,7 @@ static const struct usb_action icm105a_6
 	{0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */
 	{}
 };
-static const struct usb_action icm105a_NoFliker[] = {
+static const struct usb_action icm105a_NoFlikerScale[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
 	{0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
 	{0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
@@ -2774,7 +2787,7 @@ static const struct usb_action icm105a_N
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
 	{}
 };
-static const struct usb_action icm105a_NoFlikerScale[] = {
+static const struct usb_action icm105a_NoFliker[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
 	{0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
 	{0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
@@ -2808,7 +2821,7 @@ static const struct usb_action icm105a_N
 	{}
 };
 
-static const struct usb_action MC501CB_InitialScale[] = {
+static const struct usb_action mc501cb_Initial[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
 	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */
 	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
@@ -2928,7 +2941,7 @@ static const struct usb_action MC501CB_I
 	{}
 };
 
-static const struct usb_action MC501CB_Initial[] = {	 /* 320x240 */
+static const struct usb_action mc501cb_InitialScale[] = {	 /* 320x240 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
 	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
 	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
@@ -3047,7 +3060,7 @@ static const struct usb_action MC501CB_I
 	{}
 };
 
-static const struct usb_action MC501CB_50HZ[] = {
+static const struct usb_action mc501cb_50HZScale[] = {
 	{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
 	{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
 	{0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */
@@ -3064,7 +3077,7 @@ static const struct usb_action MC501CB_5
 	{}
 };
 
-static const struct usb_action MC501CB_50HZScale[] = {
+static const struct usb_action mc501cb_50HZ[] = {
 	{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
 	{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
 	{0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */
@@ -3081,7 +3094,7 @@ static const struct usb_action MC501CB_5
 	{}
 };
 
-static const struct usb_action MC501CB_60HZ[] = {
+static const struct usb_action mc501cb_60HZScale[] = {
 	{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
 	{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
 	{0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
@@ -3098,7 +3111,7 @@ static const struct usb_action MC501CB_6
 	{}
 };
 
-static const struct usb_action MC501CB_60HZScale[] = {
+static const struct usb_action mc501cb_60HZ[] = {
 	{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
 	{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
 	{0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
@@ -3115,7 +3128,7 @@ static const struct usb_action MC501CB_6
 	{}
 };
 
-static const struct usb_action MC501CB_NoFliker[] = {
+static const struct usb_action mc501cb_NoFlikerScale[] = {
 	{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
 	{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
 	{0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
@@ -3132,7 +3145,7 @@ static const struct usb_action MC501CB_N
 	{}
 };
 
-static const struct usb_action MC501CB_NoFlikerScale[] = {
+static const struct usb_action mc501cb_NoFliker[] = {
 	{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
 	{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
 	{0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
@@ -3144,8 +3157,8 @@ static const struct usb_action MC501CB_N
 	{}
 };
 
-/* from zs211.inf - HKR,%OV7620%,Initial - 640x480 */
-static const struct usb_action OV7620_mode0[] = {
+/* from zs211.inf */
+static const struct usb_action ov7620_Initial[] = {	/* 640x480 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
 	{0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, /* 00,02,40,cc */
 	{0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */
@@ -3214,9 +3227,7 @@ static const struct usb_action OV7620_mo
 	{0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */
 	{}
 };
-
-/* from zs211.inf - HKR,%OV7620%,InitialScale - 320x240 */
-static const struct usb_action OV7620_mode1[] = {
+static const struct usb_action ov7620_InitialScale[] = {	/* 320x240 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
 	{0xa0, 0x50, ZC3XX_R002_CLOCKSELECT},	/* 00,02,50,cc */
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* 00,08,00,cc */
@@ -3287,9 +3298,7 @@ static const struct usb_action OV7620_mo
 	{0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},	/* 01,a8,50,cc */
 	{}
 };
-
-/* from zs211.inf - HKR,%OV7620%\AE,50HZ */
-static const struct usb_action OV7620_50HZ[] = {
+static const struct usb_action ov7620_50HZ[] = {
 	{0xaa, 0x13, 0x00a3},	/* 00,13,a3,aa */
 	{0xdd, 0x00, 0x0100},	/* 00,01,00,dd */
 	{0xaa, 0x2b, 0x0096},	/* 00,2b,96,aa */
@@ -3307,9 +3316,7 @@ static const struct usb_action OV7620_50
 							 if mode0 (640x480) */
 	{}
 };
-
-/* from zs211.inf - HKR,%OV7620%\AE,60HZ */
-static const struct usb_action OV7620_60HZ[] = {
+static const struct usb_action ov7620_60HZ[] = {
 	{0xaa, 0x13, 0x00a3},			/* 00,13,a3,aa */
 						/* (bug in zs211.inf) */
 	{0xdd, 0x00, 0x0100},			/* 00,01,00,dd */
@@ -3331,9 +3338,7 @@ static const struct usb_action OV7620_60
 	{0xa1, 0x01, 0x0037},		*/
 	{}
 };
-
-/* from zs211.inf - HKR,%OV7620%\AE,NoFliker */
-static const struct usb_action OV7620_NoFliker[] = {
+static const struct usb_action ov7620_NoFliker[] = {
 	{0xaa, 0x13, 0x00a3},			/* 00,13,a3,aa */
 						/* (bug in zs211.inf) */
 	{0xdd, 0x00, 0x0100},			/* 00,01,00,dd */
@@ -3354,7 +3359,7 @@ static const struct usb_action OV7620_No
 	{}
 };
 
-static const struct usb_action ov7630c_Initial[] = {
+static const struct usb_action ov7630c_InitialScale[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
@@ -3511,7 +3516,7 @@ static const struct usb_action ov7630c_I
 	{}
 };
 
-static const struct usb_action ov7630c_InitialScale[] = {
+static const struct usb_action ov7630c_Initial[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -3682,7 +3687,7 @@ static const struct usb_action pas106b_I
 	{}
 };
 
-static const struct usb_action pas106b_Initial[] = {	/* 176x144 */
+static const struct usb_action pas106b_InitialScale[] = {	/* 176x144 */
 /* JPEG control */
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
 /* Sream and Sensor specific */
@@ -3800,7 +3805,7 @@ static const struct usb_action pas106b_I
 	{}
 };
 
-static const struct usb_action pas106b_InitialScale[] = {	/* 352x288 */
+static const struct usb_action pas106b_Initial[] = {	/* 352x288 */
 /* JPEG control */
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
 /* Sream and Sensor specific */
@@ -3972,10 +3977,10 @@ static const struct usb_action pas106b_N
 	{}
 };
 
-/* from usbvm31b.inf */
+/* from lvWIMv.inf 046d:08a2/:08aa 2007/06/03 */
 static const struct usb_action pas202b_Initial[] = {	/* 640x480 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},		/* 00,00,01,cc */
-	{0xa0, 0x00, ZC3XX_R008_CLOCKSETTING},		/* 00,08,00,cc */
+	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
 	{0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0e,cc */
 	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},		/* 00,02,00,cc */
 	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},	/* 00,03,02,cc */
@@ -4000,7 +4005,7 @@ static const struct usb_action pas202b_I
 	{0xaa, 0x09, 0x0006},				/* 00,09,06,aa */
 	{0xaa, 0x0a, 0x0001},				/* 00,0a,01,aa */
 	{0xaa, 0x0b, 0x0001},				/* 00,0b,01,aa */
-	{0xaa, 0x0c, 0x0008},				/* 00,0c,08,aa */
+	{0xaa, 0x0c, 0x0006},
 	{0xaa, 0x0d, 0x0000},				/* 00,0d,00,aa */
 	{0xaa, 0x10, 0x0000},				/* 00,10,00,aa */
 	{0xaa, 0x12, 0x0005},				/* 00,12,05,aa */
@@ -4019,13 +4024,13 @@ static const struct usb_action pas202b_I
 };
 static const struct usb_action pas202b_InitialScale[] = {	/* 320x240 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},		/* 00,00,01,cc */
-	{0xa0, 0x00, ZC3XX_R008_CLOCKSETTING},		/* 00,08,00,cc */
+	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
 	{0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0e,cc */
 	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},		/* 00,02,10,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, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
 	{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 */
@@ -4035,7 +4040,7 @@ static const struct usb_action pas202b_I
 	{0xa0, 0x08, ZC3XX_R11A_FIRSTYLOW},		/* 01,1a,08,cc */
 	{0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW},		/* 01,1c,02,cc */
 	{0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},		/* 00,9b,01,cc */
-	{0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW},		/* 00,9c,d8,cc */
+	{0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
 	{0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},		/* 00,9d,02,cc */
 	{0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},		/* 00,9e,88,cc */
 	{0xaa, 0x02, 0x0002},				/* 00,02,02,aa */
@@ -4044,7 +4049,7 @@ static const struct usb_action pas202b_I
 	{0xaa, 0x09, 0x0006},				/* 00,09,06,aa */
 	{0xaa, 0x0a, 0x0001},				/* 00,0a,01,aa */
 	{0xaa, 0x0b, 0x0001},				/* 00,0b,01,aa */
-	{0xaa, 0x0c, 0x0008},				/* 00,0c,08,aa */
+	{0xaa, 0x0c, 0x0006},
 	{0xaa, 0x0d, 0x0000},				/* 00,0d,00,aa */
 	{0xaa, 0x10, 0x0000},				/* 00,10,00,aa */
 	{0xaa, 0x12, 0x0005},				/* 00,12,05,aa */
@@ -4059,6 +4064,8 @@ static const struct usb_action pas202b_I
 	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},	/* 02,50,08,cc */
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},		/* 03,01,08,cc */
 	{0xa0, 0x70, ZC3XX_R18D_YTARGET},		/* 01,8d,70,cc */
+	{0xa0, 0xff, ZC3XX_R097_WINYSTARTHIGH},
+	{0xa0, 0xfe, ZC3XX_R098_WINYSTARTLOW},
 	{}
 };
 static const struct usb_action pas202b_50HZ[] = {
@@ -4066,22 +4073,22 @@ static const struct usb_action pas202b_5
 	{0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},		/* 00,87,20,cc */
 	{0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},		/* 00,88,21,cc */
 	{0xaa, 0x20, 0x0002},				/* 00,20,02,aa */
-	{0xaa, 0x21, 0x0068},				/* 00,21,68,aa */
+	{0xaa, 0x21, 0x001b},
 	{0xaa, 0x03, 0x0044},				/* 00,03,44,aa */
-	{0xaa, 0x04, 0x0009},				/* 00,04,09,aa */
-	{0xaa, 0x05, 0x0028},				/* 00,05,28,aa */
+	{0xaa, 0x04, 0x0008},
+	{0xaa, 0x05, 0x001b},
 	{0xaa, 0x0e, 0x0001},				/* 00,0e,01,aa */
 	{0xaa, 0x0f, 0x0000},				/* 00,0f,00,aa */
-	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},	/* 01,a9,14,cc */
+	{0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
 	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},	/* 01,aa,24,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},	/* 01,90,00,cc */
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},	/* 01,91,07,cc */
-	{0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW},	/* 01,92,d2,cc */
+	{0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x1b, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},	/* 01,95,00,cc */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},	/* 01,96,00,cc */
 	{0xa0, 0x4d, ZC3XX_R197_ANTIFLICKERLOW},	/* 01,97,4d,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},		/* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},		/* 01,8f,20,cc */
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
 	{0xa0, 0x44, ZC3XX_R01D_HSYNC_0},		/* 00,1d,44,cc */
 	{0xa0, 0x6f, ZC3XX_R01E_HSYNC_1},		/* 00,1e,6f,cc */
 	{0xa0, 0xad, ZC3XX_R01F_HSYNC_2},		/* 00,1f,ad,cc */
@@ -4094,23 +4101,23 @@ static const struct usb_action pas202b_5
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},		/* 00,19,00,cc */
 	{0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},		/* 00,87,20,cc */
 	{0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},		/* 00,88,21,cc */
-	{0xaa, 0x20, 0x0002},				/* 00,20,02,aa */
-	{0xaa, 0x21, 0x006c},				/* 00,21,6c,aa */
+	{0xaa, 0x20, 0x0004},
+	{0xaa, 0x21, 0x003d},
 	{0xaa, 0x03, 0x0041},				/* 00,03,41,aa */
-	{0xaa, 0x04, 0x0009},				/* 00,04,09,aa */
-	{0xaa, 0x05, 0x002c},				/* 00,05,2c,aa */
+	{0xaa, 0x04, 0x0010},
+	{0xaa, 0x05, 0x003d},
 	{0xaa, 0x0e, 0x0001},				/* 00,0e,01,aa */
 	{0xaa, 0x0f, 0x0000},				/* 00,0f,00,aa */
-	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},	/* 01,a9,14,cc */
+	{0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
 	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},	/* 01,aa,24,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},	/* 01,90,00,cc */
-	{0xa0, 0x0f, ZC3XX_R191_EXPOSURELIMITMID},	/* 01,91,0f,cc */
-	{0xa0, 0xbe, ZC3XX_R192_EXPOSURELIMITLOW},	/* 01,92,be,cc */
+	{0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x3d, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},	/* 01,95,00,cc */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},	/* 01,96,00,cc */
 	{0xa0, 0x9b, ZC3XX_R197_ANTIFLICKERLOW},	/* 01,97,9b,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},		/* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},		/* 01,8f,20,cc */
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
 	{0xa0, 0x41, ZC3XX_R01D_HSYNC_0},		/* 00,1d,41,cc */
 	{0xa0, 0x6f, ZC3XX_R01E_HSYNC_1},		/* 00,1e,6f,cc */
 	{0xa0, 0xad, ZC3XX_R01F_HSYNC_2},		/* 00,1f,ad,cc */
@@ -4130,16 +4137,16 @@ static const struct usb_action pas202b_6
 	{0xaa, 0x05, 0x0000},				/* 00,05,00,aa */
 	{0xaa, 0x0e, 0x0001},				/* 00,0e,01,aa */
 	{0xaa, 0x0f, 0x0000},				/* 00,0f,00,aa */
-	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},	/* 01,a9,14,cc */
+	{0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
 	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},	/* 01,aa,24,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},	/* 01,90,00,cc */
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},	/* 01,91,07,cc */
-	{0xa0, 0xc0, ZC3XX_R192_EXPOSURELIMITLOW},	/* 01,92,c0,cc */
+	{0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},	/* 01,95,00,cc */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},	/* 01,96,00,cc */
 	{0xa0, 0x40, ZC3XX_R197_ANTIFLICKERLOW},	/* 01,97,40,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},		/* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},		/* 01,8f,20,cc */
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
 	{0xa0, 0x45, ZC3XX_R01D_HSYNC_0},		/* 00,1d,45,cc */
 	{0xa0, 0x8e, ZC3XX_R01E_HSYNC_1},		/* 00,1e,8e,cc */
 	{0xa0, 0xc1, ZC3XX_R01F_HSYNC_2},		/* 00,1f,c1,cc */
@@ -4152,23 +4159,23 @@ static const struct usb_action pas202b_6
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},		/* 00,19,00,cc */
 	{0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},		/* 00,87,20,cc */
 	{0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},		/* 00,88,21,cc */
-	{0xaa, 0x20, 0x0002},				/* 00,20,02,aa */
-	{0xaa, 0x21, 0x0004},				/* 00,21,04,aa */
+	{0xaa, 0x20, 0x0004},
+	{0xaa, 0x21, 0x0008},
 	{0xaa, 0x03, 0x0042},				/* 00,03,42,aa */
-	{0xaa, 0x04, 0x0008},				/* 00,04,08,aa */
-	{0xaa, 0x05, 0x0004},				/* 00,05,04,aa */
+	{0xaa, 0x04, 0x0010},
+	{0xaa, 0x05, 0x0008},
 	{0xaa, 0x0e, 0x0001},				/* 00,0e,01,aa */
 	{0xaa, 0x0f, 0x0000},				/* 00,0f,00,aa */
-	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},	/* 01,a9,14,cc */
+	{0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
 	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},	/* 01,aa,24,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},	/* 01,90,00,cc */
-	{0xa0, 0x0f, ZC3XX_R191_EXPOSURELIMITMID},	/* 01,91,0f,cc */
-	{0xa0, 0x9f, ZC3XX_R192_EXPOSURELIMITLOW},	/* 01,92,9f,cc */
+	{0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x08, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},	/* 01,95,00,cc */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},	/* 01,96,00,cc */
 	{0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW},	/* 01,97,81,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},		/* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},		/* 01,8f,20,cc */
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
 	{0xa0, 0x42, ZC3XX_R01D_HSYNC_0},		/* 00,1d,42,cc */
 	{0xa0, 0x6f, ZC3XX_R01E_HSYNC_1},		/* 00,1e,6f,cc */
 	{0xa0, 0xaf, ZC3XX_R01F_HSYNC_2},		/* 00,1f,af,cc */
@@ -4182,22 +4189,22 @@ static const struct usb_action pas202b_N
 	{0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},		/* 00,87,20,cc */
 	{0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},		/* 00,88,21,cc */
 	{0xaa, 0x20, 0x0002},				/* 00,20,02,aa */
-	{0xaa, 0x21, 0x0020},				/* 00,21,20,aa */
+	{0xaa, 0x21, 0x0006},
 	{0xaa, 0x03, 0x0040},				/* 00,03,40,aa */
 	{0xaa, 0x04, 0x0008},				/* 00,04,08,aa */
-	{0xaa, 0x05, 0x0020},				/* 00,05,20,aa */
+	{0xaa, 0x05, 0x0006},
 	{0xaa, 0x0e, 0x0001},				/* 00,0e,01,aa */
 	{0xaa, 0x0f, 0x0000},				/* 00,0f,00,aa */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},	/* 01,90,00,cc */
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},	/* 01,91,07,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},	/* 01,92,f0,cc */
+	{0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x06, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},	/* 01,95,00,cc */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},	/* 01,96,00,cc */
-	{0xa0, 0x02, ZC3XX_R197_ANTIFLICKERLOW},	/* 01,97,02,cc */
+	{0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW},
 	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},		/* 01,8c,10,cc */
 	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},		/* 01,8f,20,cc */
 	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},	/* 01,a9,00,cc */
-	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},	/* 01,aa,00,cc */
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
 	{0xa0, 0x40, ZC3XX_R01D_HSYNC_0},		/* 00,1d,40,cc */
 	{0xa0, 0x60, ZC3XX_R01E_HSYNC_1},		/* 00,1e,60,cc */
 	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},		/* 00,1f,90,cc */
@@ -4210,23 +4217,23 @@ static const struct usb_action pas202b_N
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},		/* 00,19,00,cc */
 	{0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},		/* 00,87,20,cc */
 	{0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},		/* 00,88,21,cc */
-	{0xaa, 0x20, 0x0002},				/* 00,20,02,aa */
-	{0xaa, 0x21, 0x0010},				/* 00,21,10,aa */
+	{0xaa, 0x20, 0x0004},
+	{0xaa, 0x21, 0x000c},
 	{0xaa, 0x03, 0x0040},				/* 00,03,40,aa */
-	{0xaa, 0x04, 0x0008},				/* 00,04,08,aa */
-	{0xaa, 0x05, 0x0010},				/* 00,05,10,aa */
+	{0xaa, 0x04, 0x0010},
+	{0xaa, 0x05, 0x000c},
 	{0xaa, 0x0e, 0x0001},				/* 00,0e,01,aa */
 	{0xaa, 0x0f, 0x0000},				/* 00,0f,00,aa */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},	/* 01,90,00,cc */
-	{0xa0, 0x0f, ZC3XX_R191_EXPOSURELIMITMID},	/* 01,91,0f,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},	/* 01,92,f0,cc */
+	{0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x0c, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},	/* 01,95,00,cc */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},	/* 01,96,00,cc */
 	{0xa0, 0x02, ZC3XX_R197_ANTIFLICKERLOW},	/* 01,97,02,cc */
 	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},		/* 01,8c,10,cc */
 	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},		/* 01,8f,20,cc */
 	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},	/* 01,a9,00,cc */
-	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},	/* 01,aa,00,cc */
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
 	{0xa0, 0x40, ZC3XX_R01D_HSYNC_0},		/* 00,1d,40,cc */
 	{0xa0, 0x60, ZC3XX_R01E_HSYNC_1},		/* 00,1e,60,cc */
 	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},		/* 00,1f,90,cc */
@@ -4713,8 +4720,8 @@ static const struct usb_action pb0330_No
 	{}
 };
 
-/* from oem9.inf - HKR,%PO2030%,Initial - 640x480 - (close to CS2102) */
-static const struct usb_action PO2030_mode0[] = {
+/* from oem9.inf */
+static const struct usb_action po2030_Initial[] = {	/* 640x480 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
 	{0xa0, 0x04, ZC3XX_R002_CLOCKSELECT},	/* 00,02,04,cc */
 	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
@@ -4790,8 +4797,8 @@ static const struct usb_action PO2030_mo
 	{}
 };
 
-/* from oem9.inf - HKR,%PO2030%,InitialScale - 320x240 */
-static const struct usb_action PO2030_mode1[] = {
+/* from oem9.inf */
+static const struct usb_action po2030_InitialScale[] = {	/* 320x240 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
 	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
 	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
@@ -4867,7 +4874,7 @@ static const struct usb_action PO2030_mo
 	{}
 };
 
-static const struct usb_action PO2030_50HZ[] = {
+static const struct usb_action po2030_50HZ[] = {
 	{0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */
 	{0xaa, 0x1a, 0x0001}, /* 00,1a,01,aa */
 	{0xaa, 0x1b, 0x000a}, /* 00,1b,0a,aa */
@@ -4889,7 +4896,7 @@ static const struct usb_action PO2030_50
 	{}
 };
 
-static const struct usb_action PO2030_60HZ[] = {
+static const struct usb_action po2030_60HZ[] = {
 	{0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */
 	{0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
 	{0xaa, 0x1b, 0x00de}, /* 00,1b,de,aa */
@@ -4912,7 +4919,7 @@ static const struct usb_action PO2030_60
 	{}
 };
 
-static const struct usb_action PO2030_NoFliker[] = {
+static const struct usb_action po2030_NoFliker[] = {
 	{0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
 	{0xaa, 0x8d, 0x000d}, /* 00,8d,0d,aa */
 	{0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
@@ -4924,7 +4931,7 @@ static const struct usb_action PO2030_No
 };
 
 /* TEST */
-static const struct usb_action tas5130CK_Initial[] = {
+static const struct usb_action tas5130cK_InitialScale[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x01, 0x003b},
 	{0xa0, 0x0e, 0x003a},
@@ -5127,7 +5134,7 @@ static const struct usb_action tas5130CK
 	{}
 };
 
-static const struct usb_action tas5130CK_InitialScale[] = {
+static const struct usb_action tas5130cK_Initial[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x01, 0x003b},
 	{0xa0, 0x0e, 0x003a},
@@ -5560,7 +5567,7 @@ static const struct usb_action tas5130cx
 	{}
 };
 
-static const struct usb_action tas5130c_vf0250_Initial[] = {
+static const struct usb_action tas5130c_vf0250_InitialScale[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},		/* 00,00,01,cc, */
 	{0xa0, 0x02, ZC3XX_R008_CLOCKSETTING},		/* 00,08,02,cc, */
 	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc, */
@@ -5627,7 +5634,7 @@ static const struct usb_action tas5130c_
 	{}
 };
 
-static const struct usb_action tas5130c_vf0250_InitialScale[] = {
+static const struct usb_action tas5130c_vf0250_Initial[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},		/* 00,00,01,cc, */
 	{0xa0, 0x02, ZC3XX_R008_CLOCKSETTING},		/* 00,08,02,cc, */
 	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc, */
@@ -5692,8 +5699,7 @@ static const struct usb_action tas5130c_
 	{0xa0, 0x65, ZC3XX_R118_BGAIN},		/* 01,18,65,cc */
 	{}
 };
-/* "50HZ" light frequency banding filter */
-static const struct usb_action tas5130c_vf0250_50HZ[] = {
+static const struct usb_action tas5130c_vf0250_50HZScale[] = {
 	{0xaa, 0x82, 0x0000},		/* 00,82,00,aa */
 	{0xaa, 0x83, 0x0001},		/* 00,83,01,aa */
 	{0xaa, 0x84, 0x00aa},		/* 00,84,aa,aa */
@@ -5717,8 +5723,7 @@ static const struct usb_action tas5130c_
 	{}
 };
 
-/* "50HZScale" light frequency banding filter */
-static const struct usb_action tas5130c_vf0250_50HZScale[] = {
+static const struct usb_action tas5130c_vf0250_50HZ[] = {
 	{0xaa, 0x82, 0x0000},		/* 00,82,00,aa */
 	{0xaa, 0x83, 0x0003},		/* 00,83,03,aa */
 	{0xaa, 0x84, 0x0054},		/* 00,84,54,aa */
@@ -5742,8 +5747,7 @@ static const struct usb_action tas5130c_
 	{}
 };
 
-/* "60HZ" light frequency banding filter */
-static const struct usb_action tas5130c_vf0250_60HZ[] = {
+static const struct usb_action tas5130c_vf0250_60HZScale[] = {
 	{0xaa, 0x82, 0x0000},		/* 00,82,00,aa */
 	{0xaa, 0x83, 0x0001},		/* 00,83,01,aa */
 	{0xaa, 0x84, 0x0062},		/* 00,84,62,aa */
@@ -5767,8 +5771,7 @@ static const struct usb_action tas5130c_
 	{}
 };
 
-/* "60HZScale" light frequency banding ilter */
-static const struct usb_action tas5130c_vf0250_60HZScale[] = {
+static const struct usb_action tas5130c_vf0250_60HZ[] = {
 	{0xaa, 0x82, 0x0000},		/* 00,82,00,aa */
 	{0xaa, 0x83, 0x0002},		/* 00,83,02,aa */
 	{0xaa, 0x84, 0x00c4},		/* 00,84,c4,aa */
@@ -5792,8 +5795,7 @@ static const struct usb_action tas5130c_
 	{}
 };
 
-/* "NoFliker" light frequency banding flter */
-static const struct usb_action tas5130c_vf0250_NoFliker[] = {
+static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
 	{0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE},		/* 01,00,0c,cc, */
 	{0xaa, 0x82, 0x0000},		/* 00,82,00,aa */
 	{0xaa, 0x83, 0x0000},		/* 00,83,00,aa */
@@ -5815,8 +5817,7 @@ static const struct usb_action tas5130c_
 	{}
 };
 
-/* "NoFlikerScale" light frequency banding filter */
-static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
+static const struct usb_action tas5130c_vf0250_NoFliker[] = {
 	{0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE},		/* 01,00,0c,cc, */
 	{0xaa, 0x82, 0x0000},		/* 00,82,00,aa */
 	{0xaa, 0x83, 0x0000},		/* 00,83,00,aa */
@@ -5839,7 +5840,7 @@ static const struct usb_action tas5130c_
 };
 
 static u8 reg_r_i(struct gspca_dev *gspca_dev,
-		__u16 index)
+		u16 index)
 {
 	usb_control_msg(gspca_dev->dev,
 			usb_rcvctrlpipe(gspca_dev->dev, 0),
@@ -5852,7 +5853,7 @@ static u8 reg_r_i(struct gspca_dev *gspc
 }
 
 static u8 reg_r(struct gspca_dev *gspca_dev,
-		__u16 index)
+		u16 index)
 {
 	u8 ret;
 
@@ -5862,8 +5863,8 @@ static u8 reg_r(struct gspca_dev *gspca_
 }
 
 static void reg_w_i(struct usb_device *dev,
-			__u8 value,
-			__u16 index)
+			u8 value,
+			u16 index)
 {
 	usb_control_msg(dev,
 			usb_sndctrlpipe(dev, 0),
@@ -5874,18 +5875,18 @@ static void reg_w_i(struct usb_device *d
 }
 
 static void reg_w(struct usb_device *dev,
-			__u8 value,
-			__u16 index)
+			u8 value,
+			u16 index)
 {
 	PDEBUG(D_USBO, "reg w [%04x] = %02x", index, value);
 	reg_w_i(dev, value, index);
 }
 
-static __u16 i2c_read(struct gspca_dev *gspca_dev,
-			__u8 reg)
+static u16 i2c_read(struct gspca_dev *gspca_dev,
+			u8 reg)
 {
-	__u8 retbyte;
-	__u16 retval;
+	u8 retbyte;
+	u16 retval;
 
 	reg_w_i(gspca_dev->dev, reg, 0x0092);
 	reg_w_i(gspca_dev->dev, 0x02, 0x0090);		/* <- read command */
@@ -5900,12 +5901,12 @@ static __u16 i2c_read(struct gspca_dev *
 	return retval;
 }
 
-static __u8 i2c_write(struct gspca_dev *gspca_dev,
-			__u8 reg,
-			__u8 valL,
-			__u8 valH)
+static u8 i2c_write(struct gspca_dev *gspca_dev,
+			u8 reg,
+			u8 valL,
+			u8 valH)
 {
-	__u8 retbyte;
+	u8 retbyte;
 
 	reg_w_i(gspca_dev->dev, reg, 0x92);
 	reg_w_i(gspca_dev->dev, valL, 0x93);
@@ -5957,24 +5958,24 @@ static void setmatrix(struct gspca_dev *
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i;
-	const __u8 *matrix;
+	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] =
+	static const u8 gc0305_matrix[9] =
 		{0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50};
-	static const __u8 ov7620_matrix[9] =
+	static const u8 ov7620_matrix[9] =
 		{0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58};
-	static const __u8 pas202b_matrix[9] =
+	static const u8 pas202b_matrix[9] =
 		{0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f};
-	static const __u8 po2030_matrix[9] =
+	static const u8 po2030_matrix[9] =
 		{0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60};
 	static const u8 tas5130c_matrix[9] =
 		{0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68};
-	static const __u8 vf0250_matrix[9] =
+	static const u8 vf0250_matrix[9] =
 		{0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
-	static const __u8 *matrix_tb[SENSOR_MAX] = {
+	static const u8 *matrix_tb[SENSOR_MAX] = {
 		adcm2700_matrix, /* SENSOR_ADCM2700 0 */
 		ov7620_matrix,	/* SENSOR_CS2102 1 */
 		NULL,		/* SENSOR_CS2102K 2 */
@@ -6006,11 +6007,12 @@ static void setmatrix(struct gspca_dev *
 static void setbrightness(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 brightness;
+	u8 brightness;
 
 	switch (sd->sensor) {
 	case SENSOR_GC0305:
 	case SENSOR_OV7620:
+	case SENSOR_PAS202B:
 	case SENSOR_PO2030:
 		return;
 	}
@@ -6034,7 +6036,7 @@ static void setsharpness(struct gspca_de
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct usb_device *dev = gspca_dev->dev;
 	int sharpness;
-	static const __u8 sharpness_tb[][2] = {
+	static const u8 sharpness_tb[][2] = {
 		{0x02, 0x03},
 		{0x04, 0x07},
 		{0x08, 0x0f},
@@ -6053,118 +6055,69 @@ static void setcontrast(struct gspca_dev
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct usb_device *dev = gspca_dev->dev;
-	const __u8 *Tgamma, *Tgradient;
-	int g, i, k;
-	static const __u8 kgamma_tb[16] =	/* delta for contrast */
+	const u8 *Tgamma;
+	int g, i, k, adj, gp;
+	u8 gr[16];
+	static const u8 delta_tb[16] =		/* delta for contrast */
 		{0x15, 0x0d, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08,
 		 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
-	static const __u8 kgrad_tb[16] =
-		{0x1b, 0x06, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00,
-		 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x04};
-	static const __u8 Tgamma_1[16] =
+	static const u8 gamma_tb[6][16] = {
 		{0x00, 0x00, 0x03, 0x0d, 0x1b, 0x2e, 0x45, 0x5f,
-		 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff};
-	static const __u8 Tgradient_1[16] =
-		{0x00, 0x01, 0x05, 0x0b, 0x10, 0x15, 0x18, 0x1a,
-		 0x1a, 0x18, 0x16, 0x14, 0x12, 0x0f, 0x0d, 0x06};
-	static const __u8 Tgamma_2[16] =
+		 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff},
 		{0x01, 0x0c, 0x1f, 0x3a, 0x53, 0x6d, 0x85, 0x9c,
-		 0xb0, 0xc2, 0xd1, 0xde, 0xe9, 0xf2, 0xf9, 0xff};
-	static const __u8 Tgradient_2[16] =
-		{0x05, 0x0f, 0x16, 0x1a, 0x19, 0x19, 0x17, 0x15,
-		 0x12, 0x10, 0x0e, 0x0b, 0x09, 0x08, 0x06, 0x03};
-	static const __u8 Tgamma_3[16] =
+		 0xb0, 0xc2, 0xd1, 0xde, 0xe9, 0xf2, 0xf9, 0xff},
 		{0x04, 0x16, 0x30, 0x4e, 0x68, 0x81, 0x98, 0xac,
-		 0xbe, 0xcd, 0xda, 0xe4, 0xed, 0xf5, 0xfb, 0xff};
-	static const __u8 Tgradient_3[16] =
-		{0x0c, 0x16, 0x1b, 0x1c, 0x19, 0x18, 0x15, 0x12,
-		 0x10, 0x0d, 0x0b, 0x09, 0x08, 0x06, 0x05, 0x03};
-	static const __u8 Tgamma_4[16] =
+		 0xbe, 0xcd, 0xda, 0xe4, 0xed, 0xf5, 0xfb, 0xff},
 		{0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
-		 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff};
-	static const __u8 Tgradient_4[16] =
-		{0x26, 0x22, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0d,
-		 0x0b, 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02};
-	static const __u8 Tgamma_5[16] =
+		 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff},
 		{0x20, 0x4b, 0x6e, 0x8d, 0xa3, 0xb5, 0xc5, 0xd2,
-		 0xdc, 0xe5, 0xec, 0xf2, 0xf6, 0xfa, 0xfd, 0xff};
-	static const __u8 Tgradient_5[16] =
-		{0x37, 0x26, 0x20, 0x1a, 0x14, 0x10, 0x0e, 0x0b,
-		 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02};
-	static const __u8 Tgamma_6[16] =		/* ?? was gamma 5 */
+		 0xdc, 0xe5, 0xec, 0xf2, 0xf6, 0xfa, 0xfd, 0xff},
 		{0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3,
-		 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff};
-	static const __u8 Tgradient_6[16] =
-		{0x18, 0x20, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0e,
-		 0x0b, 0x09, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01};
-	static const __u8 *gamma_tb[] = {
-		NULL, Tgamma_1, Tgamma_2,
-		Tgamma_3, Tgamma_4, Tgamma_5, Tgamma_6
-	};
-	static const __u8 *gradient_tb[] = {
-		NULL, Tgradient_1, Tgradient_2,
-		Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6
+		 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff},
 	};
-#ifdef GSPCA_DEBUG
-	__u8 v[16];
-#endif
 
-	Tgamma = gamma_tb[sd->gamma];
-	Tgradient = gradient_tb[sd->gamma];
+	Tgamma = gamma_tb[sd->gamma - 1];
 
-	k = (sd->contrast - 128)		/* -128 / 128 */
-			* Tgamma[0];
-	PDEBUG(D_CONF, "gamma:%d contrast:%d gamma coeff: %d/128",
-		sd->gamma, sd->contrast, k);
+	k = ((int) sd->contrast - 128);		/* -128 / 128 */
+	adj = 0;
+	gp = 0;
 	for (i = 0; i < 16; i++) {
-		g = Tgamma[i] + kgamma_tb[i] * k / 128;
+		g = Tgamma[i] - delta_tb[i] * k / 128 - adj / 2;
 		if (g > 0xff)
 			g = 0xff;
 		else if (g <= 0)
 			g = 1;
 		reg_w(dev, g, 0x0120 + i);	/* gamma */
-#ifdef GSPCA_DEBUG
-		if (gspca_debug & D_CONF)
-			v[i] = g;
-#endif
-	}
-	PDEBUG(D_CONF, "tb: %02x %02x %02x %02x %02x %02x %02x %02x",
-		v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
-	PDEBUG(D_CONF, "    %02x %02x %02x %02x %02x %02x %02x %02x",
-		v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15]);
-	for (i = 0; i < 16; i++) {
-		g = Tgradient[i] - kgrad_tb[i] * k / 128;
-		if (g > 0xff)
-			g = 0xff;
-		else if (g <= 0) {
-			if (i != 15)
-				g = 0;
+		if (k > 0)
+			adj--;
+		else
+			adj++;
+
+		if (i != 0) {
+			if (gp == 0)
+				gr[i - 1] = 0;
 			else
-				g = 1;
+				gr[i - 1] = g - gp;
 		}
-		reg_w(dev, g, 0x0130 + i);	/* gradient */
-#ifdef GSPCA_DEBUG
-		if (gspca_debug & D_CONF)
-			v[i] = g;
-#endif
+		gp = g;
 	}
-	PDEBUG(D_CONF, "    %02x %02x %02x %02x %02x %02x %02x %02x",
-		v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
-	PDEBUG(D_CONF, "    %02x %02x %02x %02x %02x %02x %02x %02x",
-		v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15]);
+	gr[15] = gr[14] / 2;
+	for (i = 0; i < 16; i++)
+		reg_w(dev, gr[i], 0x0130 + i);	/* gradient */
 }
 
 static void setquality(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct usb_device *dev = gspca_dev->dev;
-	__u8 frxt;
+	u8 frxt;
 
 	switch (sd->sensor) {
 	case SENSOR_ADCM2700:
 	case SENSOR_GC0305:
 	case SENSOR_HV7131B:
 	case SENSOR_OV7620:
+	case SENSOR_PAS202B:
 	case SENSOR_PO2030:
 		return;
 	}
@@ -6218,9 +6171,9 @@ static int setlightfreq(struct gspca_dev
 		 hdcs2020b_50HZ, hdcs2020b_50HZ,
 		 hdcs2020b_60HZ, hdcs2020b_60HZ},
 /* SENSOR_HV7131B 5 */
-		{hv7131b_NoFlikerScale, hv7131b_NoFliker,
-		 hv7131b_50HZScale, hv7131b_50HZ,
-		 hv7131b_60HZScale, hv7131b_60HZ},
+		{hv7131b_NoFliker, hv7131b_NoFlikerScale,
+		 hv7131b_50HZ, hv7131b_50HZScale,
+		 hv7131b_60HZ, hv7131b_60HZScale},
 /* SENSOR_HV7131C 6 */
 		{NULL, NULL,
 		 NULL, NULL,
@@ -6230,17 +6183,17 @@ static int setlightfreq(struct gspca_dev
 		 icm105a_50HZ, icm105a_50HZScale,
 		 icm105a_60HZ, icm105a_60HZScale},
 /* SENSOR_MC501CB 8 */
-		{MC501CB_NoFliker, MC501CB_NoFlikerScale,
-		 MC501CB_50HZ, MC501CB_50HZScale,
-		 MC501CB_60HZ, MC501CB_60HZScale},
+		{mc501cb_NoFliker, mc501cb_NoFlikerScale,
+		 mc501cb_50HZ, mc501cb_50HZScale,
+		 mc501cb_60HZ, mc501cb_60HZScale},
 /* SENSOR_MI0360SOC 9 */
-		{mi360soc_AENoFlikerScale, mi360soc_AENoFliker,
-		 mi360soc_AE50HZScale, mi360soc_AE50HZ,
-		 mi360soc_AE60HZScale, mi360soc_AE60HZ},
+		{mi360soc_AENoFliker, mi360soc_AENoFlikerScale,
+		 mi360soc_AE50HZ, mi360soc_AE50HZScale,
+		 mi360soc_AE60HZ, mi360soc_AE60HZScale},
 /* SENSOR_OV7620 10 */
-		{OV7620_NoFliker, OV7620_NoFliker,
-		 OV7620_50HZ, OV7620_50HZ,
-		 OV7620_60HZ, OV7620_60HZ},
+		{ov7620_NoFliker, ov7620_NoFliker,
+		 ov7620_50HZ, ov7620_50HZ,
+		 ov7620_60HZ, ov7620_60HZ},
 /* SENSOR_OV7630C 11 */
 		{NULL, NULL,
 		 NULL, NULL,
@@ -6258,17 +6211,17 @@ static int setlightfreq(struct gspca_dev
 		 pb0330_50HZScale, pb0330_50HZ,
 		 pb0330_60HZScale, pb0330_60HZ},
 /* SENSOR_PO2030 15 */
-		{PO2030_NoFliker, PO2030_NoFliker,
-		 PO2030_50HZ, PO2030_50HZ,
-		 PO2030_60HZ, PO2030_60HZ},
+		{po2030_NoFliker, po2030_NoFliker,
+		 po2030_50HZ, po2030_50HZ,
+		 po2030_60HZ, po2030_60HZ},
 /* SENSOR_TAS5130CK 16 */
-		{tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker,
-		 tas5130cxx_50HZScale, tas5130cxx_50HZ,
-		 tas5130cxx_60HZScale, tas5130cxx_60HZ},
+		{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
+		 tas5130cxx_50HZ, tas5130cxx_50HZScale,
+		 tas5130cxx_60HZ, tas5130cxx_60HZScale},
 /* SENSOR_TAS5130CXX 17 */
-		{tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker,
-		 tas5130cxx_50HZScale, tas5130cxx_50HZ,
-		 tas5130cxx_60HZScale, tas5130cxx_60HZ},
+		{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
+		 tas5130cxx_50HZ, tas5130cxx_50HZScale,
+		 tas5130cxx_60HZ, tas5130cxx_60HZScale},
 /* SENSOR_TAS5130C_VF0250 18 */
 		{tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale,
 		 tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale,
@@ -6277,9 +6230,9 @@ static int setlightfreq(struct gspca_dev
 
 	i = sd->lightfreq * 2;
 	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
-	if (!mode)
-		i++;			/* 640x480 */
-	zc3_freq = freq_tb[(int) sd->sensor][i];
+	if (mode)
+		i++;			/* 320x240 */
+	zc3_freq = freq_tb[sd->sensor][i];
 	if (zc3_freq != NULL) {
 		usb_exchange(gspca_dev, zc3_freq);
 		switch (sd->sensor) {
@@ -6297,6 +6250,9 @@ static int setlightfreq(struct gspca_dev
 					reg_w(gspca_dev->dev, 0x44, 0x0002);
 			}
 			break;
+		case SENSOR_PAS202B:
+			reg_w(gspca_dev->dev, 0x00, 0x01a7);
+			break;
 		}
 	}
 	return 0;
@@ -6305,7 +6261,7 @@ static int setlightfreq(struct gspca_dev
 static void setautogain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 autoval;
+	u8 autoval;
 
 	if (sd->autogain)
 		autoval = 0x42;
@@ -6333,6 +6289,12 @@ static void send_unknown(struct usb_devi
 		reg_w(dev, 0x02, 0x003b);
 		reg_w(dev, 0x00, 0x0038);
 		break;
+	case SENSOR_PAS202B:
+		reg_w(dev, 0x03, 0x003b);
+		reg_w(dev, 0x0c, 0x003a);
+		reg_w(dev, 0x0b, 0x0039);
+		reg_w(dev, 0x0b, 0x0038);
+		break;
 	}
 }
 
@@ -6349,7 +6311,7 @@ static void start_2wr_probe(struct usb_d
 
 static int sif_probe(struct gspca_dev *gspca_dev)
 {
-	__u16 checkword;
+	u16 checkword;
 
 	start_2wr_probe(gspca_dev->dev, 0x0f);		/* PAS106 */
 	reg_w(gspca_dev->dev, 0x08, 0x008d);
@@ -6392,6 +6354,7 @@ static int vga_2wr_probe(struct gspca_de
 	}
 
 	start_2wr_probe(dev, 0x08);		/* HDCS2020 */
+	i2c_write(gspca_dev, 0x1c, 0x00, 0x00);
 	i2c_write(gspca_dev, 0x15, 0xaa, 0x00);
 	retword = i2c_read(gspca_dev, 0x15);
 	if (retword != 0)
@@ -6420,8 +6383,10 @@ static int vga_2wr_probe(struct gspca_de
 	i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
 	msleep(50);
 	retword = i2c_read(gspca_dev, 0x03);
-	if (retword != 0)
+	if (retword != 0) {
+		send_unknown(dev, SENSOR_PAS202B);
 		return 0x0e;			/* PAS202BCB */
+	}
 
 	start_2wr_probe(dev, 0x02);		/* TAS5130C */
 	i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
@@ -6457,8 +6422,8 @@ ov_check:
 }
 
 struct sensor_by_chipset_revision {
-	__u16 revision;
-	__u8 internal_sensor_id;
+	u16 revision;
+	u8 internal_sensor_id;
 };
 static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
 	{0xc000, 0x12},		/* TAS5130C */
@@ -6467,6 +6432,7 @@ static const struct sensor_by_chipset_re
 	{0x8001, 0x13},
 	{0x8000, 0x14},		/* CS2102K */
 	{0x8400, 0x15},		/* TAS5130K */
+	{0xe400, 0x15},
 };
 
 static int vga_3wr_probe(struct gspca_dev *gspca_dev)
@@ -6474,7 +6440,7 @@ static int vga_3wr_probe(struct gspca_de
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct usb_device *dev = gspca_dev->dev;
 	int i;
-	__u8 retbyte;
+	u8 retbyte;
 	u16 retword;
 
 /*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
@@ -6622,8 +6588,7 @@ static int sd_config(struct gspca_dev *g
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
 	int sensor;
-	int vga = 1;		/* 1: vga, 0: sif */
-	static const __u8 gamma[SENSOR_MAX] = {
+	static const u8 gamma[SENSOR_MAX] = {
 		4,	/* SENSOR_ADCM2700 0 */
 		4,	/* SENSOR_CS2102 1 */
 		5,	/* SENSOR_CS2102K 2 */
@@ -6644,9 +6609,30 @@ static int sd_config(struct gspca_dev *g
 		3,	/* SENSOR_TAS5130CXX 17 */
 		3,	/* SENSOR_TAS5130C_VF0250 18 */
 	};
+	static const u8 mode_tb[SENSOR_MAX] = {
+		2,	/* SENSOR_ADCM2700 0 */
+		1,	/* SENSOR_CS2102 1 */
+		1,	/* SENSOR_CS2102K 2 */
+		1,	/* SENSOR_GC0305 3 */
+		1,	/* SENSOR_HDCS2020b 4 */
+		1,	/* SENSOR_HV7131B 5 */
+		1,	/* SENSOR_HV7131C 6 */
+		1,	/* SENSOR_ICM105A 7 */
+		2,	/* SENSOR_MC501CB 8 */
+		1,	/* SENSOR_MI0360SOC 9 */
+		2,	/* SENSOR_OV7620 10 */
+		1,	/* SENSOR_OV7630C 11 */
+		0,	/* SENSOR_PAS106 12 */
+		1,	/* SENSOR_PAS202B 13 */
+		1,	/* SENSOR_PB0330 14 */
+		1,	/* SENSOR_PO2030 15 */
+		1,	/* SENSOR_TAS5130CK 16 */
+		1,	/* SENSOR_TAS5130CXX 17 */
+		1,	/* SENSOR_TAS5130C_VF0250 18 */
+	};
 
 	/* define some sensors from the vendor/product */
-	sd->sharpness = 2;
+	sd->sharpness = SHARPNESS_DEF;
 	sd->sensor = id->driver_info;
 	sensor = zcxx_probeSensor(gspca_dev);
 	if (sensor >= 0)
@@ -6671,8 +6657,21 @@ static int sd_config(struct gspca_dev *g
 			}
 			break;
 		case 0:
-			PDEBUG(D_PROBE, "Find Sensor HV7131B");
-			sd->sensor = SENSOR_HV7131B;
+			/* check the sensor type */
+			sensor = i2c_read(gspca_dev, 0x00);
+			PDEBUG(D_PROBE, "Sensor hv7131 type %d", sensor);
+			switch (sensor) {
+			case 0:			/* hv7131b */
+			case 1:			/* hv7131e */
+				PDEBUG(D_PROBE, "Find Sensor HV7131B");
+				sd->sensor = SENSOR_HV7131B;
+				break;
+			default:
+/*			case 2:			 * hv7131r */
+				PDEBUG(D_PROBE, "Find Sensor HV7131R(c)");
+				sd->sensor = SENSOR_HV7131C;
+				break;
+			}
 			break;
 		case 0x02:
 			PDEBUG(D_PROBE, "Sensor TAS5130C");
@@ -6699,12 +6698,11 @@ static int sd_config(struct gspca_dev *g
 		case 0x0e:
 			PDEBUG(D_PROBE, "Find Sensor PAS202B");
 			sd->sensor = SENSOR_PAS202B;
-			sd->sharpness = 1;
+/*			sd->sharpness = 1; */
 			break;
 		case 0x0f:
 			PDEBUG(D_PROBE, "Find Sensor PAS106");
 			sd->sensor = SENSOR_PAS106;
-			vga = 0;		/* SIF */
 			break;
 		case 0x10:
 		case 0x12:
@@ -6770,31 +6768,38 @@ static int sd_config(struct gspca_dev *g
 	if (sensor < 0x20) {
 		if (sensor == -1 || sensor == 0x10 || sensor == 0x12)
 			reg_w(gspca_dev->dev, 0x02, 0x0010);
-		else
-			reg_w(gspca_dev->dev, sensor & 0x0f, 0x0010);
 		reg_r(gspca_dev, 0x0010);
 	}
 
 	cam = &gspca_dev->cam;
 /*fixme:test*/
 	gspca_dev->nbalt--;
-	if (vga) {
-		cam->cam_mode = vga_mode;
-		cam->nmodes = ARRAY_SIZE(vga_mode);
-	} else {
+	switch (mode_tb[sd->sensor]) {
+	case 0:
 		cam->cam_mode = sif_mode;
 		cam->nmodes = ARRAY_SIZE(sif_mode);
+		break;
+	case 1:
+		cam->cam_mode = vga_mode;
+		cam->nmodes = ARRAY_SIZE(vga_mode);
+		break;
+	default:
+/*	case 2: */
+		cam->cam_mode = broken_vga_mode;
+		cam->nmodes = ARRAY_SIZE(broken_vga_mode);
+		break;
 	}
-	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->brightness = BRIGHTNESS_DEF;
+	sd->contrast = CONTRAST_DEF;
+	sd->gamma = gamma[sd->sensor];
+	sd->autogain = AUTOGAIN_DEF;
+	sd->lightfreq = FREQ_DEF;
 	sd->quality = QUALITY_DEF;
 
 	switch (sd->sensor) {
 	case SENSOR_GC0305:
 	case SENSOR_OV7620:
+	case SENSOR_PAS202B:
 	case SENSOR_PO2030:
 		gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
 		break;
@@ -6805,14 +6810,13 @@ static int sd_config(struct gspca_dev *g
 		break;
 	}
 
-	/* switch the led off */
-	reg_w(gspca_dev->dev, 0x01, 0x0000);
 	return 0;
 }
 
 /* this function is called at probe and resume time */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
+	/* switch off the led */
 	reg_w(gspca_dev->dev, 0x01, 0x0000);
 	return 0;
 }
@@ -6821,28 +6825,27 @@ static int sd_start(struct gspca_dev *gs
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct usb_device *dev = gspca_dev->dev;
-	const struct usb_action *zc3_init;
 	int mode;
 	static const struct usb_action *init_tb[SENSOR_MAX][2] = {
 		{adcm2700_Initial, adcm2700_InitialScale},	/* 0 */
-		{cs2102_InitialScale, cs2102_Initial},		/* 1 */
-		{cs2102K_InitialScale, cs2102K_Initial},	/* 2 */
+		{cs2102_Initial, cs2102_InitialScale},		/* 1 */
+		{cs2102K_Initial, cs2102K_InitialScale},	/* 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 */
+		{hdcs2020b_Initial, hdcs2020b_InitialScale},	/* 4 */
+		{hv7131b_Initial, hv7131b_InitialScale},	/* 5 */
+		{hv7131r_Initial, hv7131r_InitialScale},	/* 6 */
+		{icm105a_Initial, icm105a_InitialScale},	/* 7 */
+		{mc501cb_Initial, mc501cb_InitialScale},	/* 8 */
 		{mi0360soc_Initial, mi0360soc_InitialScale},	/* 9 */
-		{OV7620_mode0, OV7620_mode1},			/* 10 */
-		{ov7630c_InitialScale, ov7630c_Initial},	/* 11 */
-		{pas106b_InitialScale, pas106b_Initial},	/* 12 */
+		{ov7620_Initial, ov7620_InitialScale},		/* 10 */
+		{ov7630c_Initial, ov7630c_InitialScale},	/* 11 */
+		{pas106b_Initial, pas106b_InitialScale},	/* 12 */
 		{pas202b_Initial, pas202b_InitialScale},	/* 13 */
 		{pb0330_Initial, pb0330_InitialScale},		/* 14 */
-		{PO2030_mode0, PO2030_mode1},			/* 15 */
-		{tas5130CK_InitialScale, tas5130CK_Initial},	/* 16 */
+		{po2030_Initial, po2030_InitialScale},		/* 15 */
+		{tas5130cK_Initial, tas5130cK_InitialScale},	/* 16 */
 		{tas5130cxx_Initial, tas5130cxx_InitialScale},	/* 17 */
-		{tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial},
+		{tas5130c_vf0250_Initial, tas5130c_vf0250_InitialScale},
 								/* 18 */
 	};
 
@@ -6854,8 +6857,7 @@ static int sd_start(struct gspca_dev *gs
 			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];
+	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
 	switch (sd->sensor) {
 	case SENSOR_HV7131C:
 		zcxx_probeSensor(gspca_dev);
@@ -6864,7 +6866,7 @@ static int sd_start(struct gspca_dev *gs
 		usb_exchange(gspca_dev, pas106b_Initial_com);
 		break;
 	}
-	usb_exchange(gspca_dev, zc3_init);
+	usb_exchange(gspca_dev, init_tb[sd->sensor][mode]);
 
 	switch (sd->sensor) {
 	case SENSOR_ADCM2700:
@@ -6883,6 +6885,11 @@ static int sd_start(struct gspca_dev *gs
 		reg_w(dev, 0x02, 0x003b);
 		reg_w(dev, 0x00, 0x0038);
 		break;
+	case SENSOR_PAS202B:
+		reg_w(dev, 0x03, 0x003b);
+		reg_w(dev, 0x0c, 0x003a);
+		reg_w(dev, 0x0b, 0x0039);
+		break;
 	}
 
 	setmatrix(gspca_dev);
@@ -6961,13 +6968,13 @@ static int sd_start(struct gspca_dev *gs
 	switch (sd->sensor) {
 	case SENSOR_PO2030:
 		msleep(50);
-		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, ZC3XX_R008_CLOCKSETTING);
 		break;
+	case SENSOR_PAS202B:
+		reg_w(dev, 0x32, 0x0007);	/* (from win traces) */
+		reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
+		break;
 	}
 	return 0;
 }
@@ -7165,6 +7172,22 @@ static int sd_get_jcomp(struct gspca_dev
 	return 0;
 }
 
+#ifdef CONFIG_INPUT
+static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,		/* interrupt packet data */
+			int len)		/* interrput packet length */
+{
+	if (len == 8 && data[4] == 1) {
+		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
+		input_sync(gspca_dev->input_dev);
+		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
+		input_sync(gspca_dev->input_dev);
+	}
+
+	return 0;
+}
+#endif
+
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
 	.ctrls = sd_ctrls,
@@ -7177,6 +7200,9 @@ static const struct sd_desc sd_desc = {
 	.querymenu = sd_querymenu,
 	.get_jcomp = sd_get_jcomp,
 	.set_jcomp = sd_set_jcomp,
+#ifdef CONFIG_INPUT
+	.int_pkt_scan = sd_int_pkt_scan,
+#endif
 };
 
 static const __devinitdata struct usb_device_id device_table[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/hdpvr/hdpvr-core.c linux-libre-2.6.34-gnu1/drivers/media/video/hdpvr/hdpvr-core.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/hdpvr/hdpvr-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/hdpvr/hdpvr-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,12 +39,12 @@ 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;
+static 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;
+static 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");
@@ -59,6 +59,7 @@ 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) },
+	{ USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID3) },
 	{ }					/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, hdpvr_table);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/hdpvr/hdpvr.h linux-libre-2.6.34-gnu1/drivers/media/video/hdpvr/hdpvr.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/hdpvr/hdpvr.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/hdpvr/hdpvr.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #define HD_PVR_PRODUCT_ID	0x4900
 #define HD_PVR_PRODUCT_ID1	0x4901
 #define HD_PVR_PRODUCT_ID2	0x4902
+#define HD_PVR_PRODUCT_ID3	0x4982
 
 #define UNSET    (-1U)
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/hdpvr/hdpvr-i2c.c linux-libre-2.6.34-gnu1/drivers/media/video/hdpvr/hdpvr-i2c.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/hdpvr/hdpvr-i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/hdpvr/hdpvr-i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include "hdpvr.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/hdpvr/hdpvr-video.c linux-libre-2.6.34-gnu1/drivers/media/video/hdpvr/hdpvr-video.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/hdpvr/hdpvr-video.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/hdpvr/hdpvr-video.c	2010-05-16 17:17:36.000000000 -0400
@@ -302,7 +302,8 @@ static int hdpvr_start_streaming(struct
 /* function expects dev->io_mutex to be hold by caller */
 static int hdpvr_stop_streaming(struct hdpvr_device *dev)
 {
-	uint actual_length, c = 0;
+	int actual_length;
+	uint c = 0;
 	u8 *buf;
 
 	if (dev->status == STATUS_IDLE)
@@ -572,7 +573,7 @@ static int vidioc_querycap(struct file *
 	struct hdpvr_device *dev = video_drvdata(file);
 
 	strcpy(cap->driver, "hdpvr");
-	strcpy(cap->card, "Haupauge HD PVR");
+	strcpy(cap->card, "Hauppauge HD PVR");
 	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
 	cap->version = HDPVR_VERSION;
 	cap->capabilities =     V4L2_CAP_VIDEO_CAPTURE |
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/hexium_gemini.c linux-libre-2.6.34-gnu1/drivers/media/video/hexium_gemini.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/hexium_gemini.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/hexium_gemini.c	2010-05-16 17:17:36.000000000 -0400
@@ -352,6 +352,7 @@ static struct saa7146_ext_vv vv_data;
 static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
 {
 	struct hexium *hexium = (struct hexium *) dev->ext_priv;
+	int ret;
 
 	DEB_EE((".\n"));
 
@@ -400,9 +401,10 @@ static int hexium_attach(struct saa7146_
 	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)) {
+	ret = saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER);
+	if (ret < 0) {
 		printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n");
-		return -1;
+		return ret;
 	}
 
 	printk("hexium_gemini: found 'hexium gemini' frame grabber-%d.\n", hexium_num);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ir-kbd-i2c.c linux-libre-2.6.34-gnu1/drivers/media/video/ir-kbd-i2c.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/ir-kbd-i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ir-kbd-i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -299,7 +299,7 @@ static int ir_probe(struct i2c_client *c
 {
 	struct ir_scancode_table *ir_codes = NULL;
 	const char *name = NULL;
-	int ir_type = 0;
+	u64 ir_type = 0;
 	struct IR_i2c *ir;
 	struct input_dev *input_dev;
 	struct i2c_adapter *adap = client->adapter;
@@ -331,6 +331,7 @@ static int ir_probe(struct i2c_client *c
 		ir_codes    = &ir_codes_pv951_table;
 		break;
 	case 0x18:
+	case 0x1f:
 	case 0x1a:
 		name        = "Hauppauge";
 		ir->get_key = get_key_haup;
@@ -446,7 +447,7 @@ static int ir_probe(struct i2c_client *c
 	input_dev->name       = ir->name;
 	input_dev->phys       = ir->phys;
 
-	err = ir_input_register(ir->input, ir->ir_codes);
+	err = ir_input_register(ir->input, ir->ir_codes, NULL);
 	if (err)
 		goto err_out_free;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-cards.c linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-cards.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-cards.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-cards.c	2010-05-16 17:17:36.000000000 -0400
@@ -1210,6 +1210,53 @@ static const struct ivtv_card ivtv_card_
 	.i2c = &ivtv_i2c_std,
 };
 
+/* ------------------------------------------------------------------------- */
+/* Sony Kikyou */
+
+static const struct ivtv_card_pci_info ivtv_pci_kikyou[] = {
+	{ PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_SONY, 0x813d },
+	{ 0, 0, 0 }
+};
+
+static const struct ivtv_card ivtv_card_kikyou = {
+	.type = IVTV_CARD_KIKYOU,
+	.name = "Sony VAIO Giga Pocket (ENX Kikyou)",
+	.v4l2_capabilities = IVTV_CAP_ENCODER,
+	.hw_video = IVTV_HW_SAA7115,
+	.hw_audio = IVTV_HW_GPIO,
+	.hw_audio_ctrl = IVTV_HW_GPIO,
+	.hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER,
+	.video_inputs = {
+	{ IVTV_CARD_INPUT_VID_TUNER,  0, IVTV_SAA71XX_COMPOSITE1 },
+	{ IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE1 },
+	{ IVTV_CARD_INPUT_SVIDEO1,    1, IVTV_SAA71XX_SVIDEO1 },
+	},
+	.audio_inputs = {
+	     { IVTV_CARD_INPUT_AUD_TUNER,  IVTV_GPIO_TUNER },
+	     { IVTV_CARD_INPUT_LINE_IN1,   IVTV_GPIO_LINE_IN },
+	     { IVTV_CARD_INPUT_LINE_IN2,   IVTV_GPIO_LINE_IN },
+	},
+	.gpio_init = { .direction = 0x03e1, .initial_value = 0x0320 },
+	.gpio_audio_input = { .mask   = 0x0060,
+			      .tuner  = 0x0020,
+			      .linein = 0x0000,
+			      .radio  = 0x0060 },
+	.gpio_audio_mute  = { .mask = 0x0000,
+			      .mute = 0x0000 }, /* 0x200? Disable for now. */
+	.gpio_audio_mode  = { .mask   = 0x0080,
+			      .mono   = 0x0000,
+			      .stereo = 0x0000, /* SAP */
+			      .lang1  = 0x0080,
+			      .lang2  = 0x0000,
+			      .both   = 0x0080 },
+	.tuners = {
+	     { .std = V4L2_STD_ALL, .tuner = TUNER_SONY_BTF_PXN01Z },
+	},
+	.pci_list = ivtv_pci_kikyou,
+	.i2c = &ivtv_i2c_std,
+};
+
+
 static const struct ivtv_card *ivtv_card_list[] = {
 	&ivtv_card_pvr250,
 	&ivtv_card_pvr350,
@@ -1238,6 +1285,7 @@ static const struct ivtv_card *ivtv_card
 	&ivtv_card_aver_m104,
 	&ivtv_card_buffalo,
 	&ivtv_card_aver_ultra1500mce,
+	&ivtv_card_kikyou,
 
 	/* Variations of standard cards but with the same PCI IDs.
 	   These cards must come last in this list. */
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-cards.h linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-cards.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-cards.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-cards.h	2010-05-16 17:17:36.000000000 -0400
@@ -51,7 +51,8 @@
 #define IVTV_CARD_AVER_M104          24 /* AverMedia M104 miniPCI card */
 #define IVTV_CARD_BUFFALO_MV5L       25 /* Buffalo PC-MV5L/PCI card */
 #define IVTV_CARD_AVER_ULTRA1500MCE  26 /* AVerMedia UltraTV 1500 MCE */
-#define IVTV_CARD_LAST 		     26
+#define IVTV_CARD_KIKYOU             27 /* Sony VAIO Giga Pocket (ENX Kikyou) */
+#define IVTV_CARD_LAST 		     27
 
 /* Variants of existing cards but with the same PCI IDs. The driver
    detects these based on other device information.
@@ -86,6 +87,7 @@
 #define IVTV_PCI_ID_MELCO 		0x1154
 #define IVTV_PCI_ID_GOTVIEW1		0xffac
 #define IVTV_PCI_ID_GOTVIEW2 		0xffad
+#define IVTV_PCI_ID_SONY 		0x104d
 
 /* hardware flags, no gaps allowed */
 #define IVTV_HW_CX25840			(1 << 0)
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-controls.c linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-controls.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-controls.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-controls.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "ivtv-driver.h"
 #include "ivtv-cards.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-driver.c linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-driver.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-driver.c	2013-05-03 12:03:49.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-driver.c	2013-05-03 09:44:44.000000000 -0400
@@ -193,6 +193,7 @@ MODULE_PARM_DESC(cardtype,
 		 "\t\t\t25 = AverMedia M104 (not yet working)\n"
 		 "\t\t\t26 = Buffalo PC-MV5L/PCI\n"
 		 "\t\t\t27 = AVerMedia UltraTV 1500 MCE\n"
+		 "\t\t\t28 = Sony VAIO Giga Pocket (ENX Kikyou)\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: BGH, DK, I, M, N, Nc, 60");
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-driver.h linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-driver.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-driver.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-driver.h	2010-05-16 17:17:36.000000000 -0400
@@ -53,6 +53,7 @@
 #include <linux/scatterlist.h>
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/byteorder.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtvfb.c linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtvfb.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtvfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtvfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/kernel.h>
 #include <linux/fb.h>
 #include <linux/ivtvfb.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_MTRR
 #include <asm/mtrr.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-firmware.c linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-firmware.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-firmware.c	2013-05-03 12:07:07.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-firmware.c	2013-05-03 09:46:29.000000000 -0400
@@ -258,7 +258,7 @@ void ivtv_init_mpeg_decoder(struct ivtv
 		IVTV_ERR("ivtv_init_mpeg_decoder failed to start playback\n");
 		return;
 	}
-	ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, data);
+	ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data);
 	mem_offset = itv->dec_mem + data[1];
 
 	if ((readbytes = load_fw_direct(IVTV_DECODE_INIT_MPEG_FILENAME,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-irq.c linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-irq.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -562,7 +562,7 @@ static void ivtv_irq_enc_dma_complete(st
 	u32 data[CX2341X_MBOX_MAX_DATA];
 	struct ivtv_stream *s;
 
-	ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data);
+	ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
 	IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream);
 
 	del_timer(&itv->dma_timer);
@@ -638,7 +638,7 @@ static void ivtv_irq_dma_err(struct ivtv
 	u32 data[CX2341X_MBOX_MAX_DATA];
 
 	del_timer(&itv->dma_timer);
-	ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data);
+	ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
 	IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1],
 				read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream);
 	write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
@@ -669,7 +669,7 @@ static void ivtv_irq_enc_start_cap(struc
 	struct ivtv_stream *s;
 
 	/* Get DMA destination and size arguments from card */
-	ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, data);
+	ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, 7, data);
 	IVTV_DEBUG_HI_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]);
 
 	if (data[0] > 2 || data[1] == 0 || data[2] == 0) {
@@ -713,9 +713,9 @@ static void ivtv_irq_dec_data_req(struct
 	struct ivtv_stream *s;
 
 	/* YUV or MPG */
-	ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, data);
 
 	if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) {
+		ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data);
 		itv->dma_data_req_size =
 				 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
 		itv->dma_data_req_offset = data[1];
@@ -724,6 +724,7 @@ static void ivtv_irq_dec_data_req(struct
 		s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
 	}
 	else {
+		ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 3, data);
 		itv->dma_data_req_size = min_t(u32, data[2], 0x10000);
 		itv->dma_data_req_offset = data[1];
 		s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
@@ -940,9 +941,10 @@ irqreturn_t ivtv_irq_handler(int irq, vo
 				ivtv_dma_enc_start(s);
 			break;
 		}
-		if (i == IVTV_MAX_STREAMS && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags)) {
+
+		if (i == IVTV_MAX_STREAMS &&
+		    test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
 			ivtv_udma_start(itv);
-		}
 	}
 
 	if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-mailbox.c linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-mailbox.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-mailbox.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-mailbox.c	2010-05-16 17:17:36.000000000 -0400
@@ -369,10 +369,11 @@ int ivtv_vapi(struct ivtv *itv, int cmd,
 }
 
 /* This one is for stuff that can't sleep.. irq handlers, etc.. */
-void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb, u32 data[])
+void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb,
+		       int argc, u32 data[])
 {
+	volatile u32 __iomem *p = mbdata->mbox[mb].data;
 	int i;
-
-	for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++)
-		data[i] = readl(&mbdata->mbox[mb].data[i]);
+	for (i = 0; i < argc; i++, p++)
+		data[i] = readl(p);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-mailbox.h linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-mailbox.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-mailbox.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-mailbox.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,8 @@
 #define IVTV_MBOX_DMA_END         8
 #define IVTV_MBOX_DMA             9
 
-void ivtv_api_get_data(struct ivtv_mailbox_data *mbox, int mb, u32 data[]);
+void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb,
+		       int argc, u32 data[]);
 int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]);
 int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...);
 int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-streams.c linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-streams.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-streams.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-streams.c	2010-05-16 17:17:36.000000000 -0400
@@ -577,10 +577,14 @@ int ivtv_start_v4l2_encode_stream(struct
 		clear_bit(IVTV_F_I_EOS, &itv->i_flags);
 
 		/* Initialize Digitizer for Capture */
+		/* Avoid tinny audio problem - ensure audio clocks are going */
+		v4l2_subdev_call(itv->sd_audio, audio, s_stream, 1);
+		/* Avoid unpredictable PCI bus hang - disable video clocks */
 		v4l2_subdev_call(itv->sd_video, video, s_stream, 0);
-		ivtv_msleep_timeout(300, 1);
+		ivtv_msleep_timeout(150, 1);
 		ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
 		v4l2_subdev_call(itv->sd_video, video, s_stream, 1);
+		ivtv_msleep_timeout(150, 1);
 	}
 
 	/* begin_capture */
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-udma.c linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-udma.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-udma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ivtv/ivtv-udma.c	2010-05-16 17:17:36.000000000 -0400
@@ -213,6 +213,7 @@ void ivtv_udma_start(struct ivtv *itv)
 	write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
 	set_bit(IVTV_F_I_DMA, &itv->i_flags);
 	set_bit(IVTV_F_I_UDMA, &itv->i_flags);
+	clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags);
 }
 
 void ivtv_udma_prepare(struct ivtv *itv)
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/Kconfig linux-libre-2.6.34-gnu1/drivers/media/video/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/media/video/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -361,7 +361,7 @@ config VIDEO_SAA717X
 
 config VIDEO_SAA7191
 	tristate "Philips SAA7191 video decoder"
-	depends on VIDEO_V4L1 && I2C
+	depends on VIDEO_V4L2 && I2C
 	---help---
 	  Support for the Philips SAA7191 video decoder.
 
@@ -388,6 +388,15 @@ config VIDEO_TVP5150
 	  To compile this driver as a module, choose M here: the
 	  module will be called tvp5150.
 
+config VIDEO_TVP7002
+	tristate "Texas Instruments TVP7002 video decoder"
+	depends on VIDEO_V4L2 && I2C
+	---help---
+	  Support for the Texas Instruments TVP7002 video decoder.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called tvp7002.
+
 config VIDEO_VPX3220
 	tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
 	depends on VIDEO_V4L2 && I2C
@@ -548,7 +557,6 @@ config VIDEO_VPSS_SYSTEM
 	depends on ARCH_DAVINCI
 	help
 	  Support for vpss system module for video driver
-	default y
 
 config VIDEO_VPFE_CAPTURE
 	tristate "VPFE Video Capture Driver"
@@ -592,6 +600,19 @@ config VIDEO_DM355_CCDC
 	   To compile this driver as a module, choose M here: the
 	   module will be called vpfe.
 
+config VIDEO_ISIF
+	tristate "ISIF HW module"
+	depends on ARCH_DAVINCI_DM365 && VIDEO_VPFE_CAPTURE
+	select VIDEO_VPSS_SYSTEM
+	default y
+	help
+	   Enables ISIF hw module. This is the hardware module for
+	   configuring ISIF in VPFE to capture Raw Bayer RGB data  from
+	   a image sensor or YUV data from a YUV source.
+
+	   To compile this driver as a module, choose M here: the
+	   module will be called vpfe.
+
 source "drivers/media/video/bt8xx/Kconfig"
 
 config VIDEO_PMS
@@ -638,9 +659,14 @@ config VIDEO_W9966
 	  information.
 
 config VIDEO_CPIA
-	tristate "CPiA Video For Linux"
+	tristate "CPiA Video For Linux (DEPRECATED)"
 	depends on VIDEO_V4L1
+	default n
 	---help---
+	  This driver is DEPRECATED please use the gspca cpia1 module
+	  instead. Note that you need atleast version 0.6.4 of libv4l for
+	  the cpia1 gspca module.
+
 	  This is the video4linux driver for cameras based on Vision's CPiA
 	  (Colour Processor Interface ASIC), such as the Creative Labs Video
 	  Blaster Webcam II. If you have one of these cameras, say Y here
@@ -730,7 +756,7 @@ source "drivers/media/video/saa7134/Kcon
 
 config VIDEO_MXB
 	tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
-	depends on PCI && VIDEO_V4L1 && I2C
+	depends on PCI && VIDEO_V4L2 && I2C
 	select VIDEO_SAA7146_VV
 	select VIDEO_TUNER
 	select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
@@ -944,6 +970,8 @@ source "drivers/media/video/hdpvr/Kconfi
 
 source "drivers/media/video/em28xx/Kconfig"
 
+source "drivers/media/video/tlg2300/Kconfig"
+
 source "drivers/media/video/cx231xx/Kconfig"
 
 source "drivers/media/video/usbvision/Kconfig"
@@ -955,6 +983,7 @@ source "drivers/media/video/et61x251/Kco
 config VIDEO_OVCAMCHIP
 	tristate "OmniVision Camera Chip support (DEPRECATED)"
 	depends on I2C && VIDEO_V4L1
+	default n
 	---help---
 	  This driver is DEPRECATED please use the gspca ov519 module
 	  instead. Note that for the ov511 / ov518 support of the gspca module
@@ -971,6 +1000,7 @@ config VIDEO_OVCAMCHIP
 config USB_W9968CF
 	tristate "USB W996[87]CF JPEG Dual Mode Camera support (DEPRECATED)"
 	depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP
+	default n
 	---help---
 	  This driver is DEPRECATED please use the gspca ov519 module
 	  instead. Note that for the w9968cf support of the gspca module
@@ -992,6 +1022,7 @@ config USB_W9968CF
 config USB_OV511
 	tristate "USB OV511 Camera support (DEPRECATED)"
 	depends on VIDEO_V4L1
+	default n
 	---help---
 	  This driver is DEPRECATED please use the gspca ov519 module
 	  instead. Note that for the ov511 / ov518 support of the gspca module
@@ -1020,6 +1051,7 @@ source "drivers/media/video/sn9c102/Kcon
 config USB_STV680
 	tristate "USB STV680 (Pencam) Camera support (DEPRECATED)"
 	depends on VIDEO_V4L1
+	default n
 	---help---
 	  This driver is DEPRECATED please use the gspca stv0680 module
 	  instead. Note that for the gspca stv0680 module you need
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ks0127.c linux-libre-2.6.34-gnu1/drivers/media/video/ks0127.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/ks0127.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ks0127.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/m52790.c linux-libre-2.6.34-gnu1/drivers/media/video/m52790.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/m52790.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/m52790.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/Makefile linux-libre-2.6.34-gnu1/drivers/media/video/Makefile
--- linux-libre-2.6.33-gnu1/drivers/media/video/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -56,6 +56,7 @@ obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
 obj-$(CONFIG_VIDEO_VINO) += indycam.o
 obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
 obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
+obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
 obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
 obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
 obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
@@ -99,6 +100,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_TLG2300) += tlg2300/
 obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
 obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
 obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
@@ -158,8 +160,6 @@ obj-$(CONFIG_VIDEO_MX3)			+= mx3_camera.
 obj-$(CONFIG_VIDEO_PXA27x)		+= pxa_camera.o
 obj-$(CONFIG_VIDEO_SH_MOBILE_CEU)	+= sh_mobile_ceu_camera.o
 
-obj-$(CONFIG_ARCH_DAVINCI)		+= davinci/
-
 obj-$(CONFIG_VIDEO_AU0828) += au0828/
 
 obj-$(CONFIG_USB_VIDEO_CLASS)	+= uvc/
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/meye.c linux-libre-2.6.34-gnu1/drivers/media/video/meye.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/meye.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/meye.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/videodev.h>
+#include <linux/gfp.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/msp3400-kthreads.c linux-libre-2.6.34-gnu1/drivers/media/video/msp3400-kthreads.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/msp3400-kthreads.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/msp3400-kthreads.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/freezer.h>
 #include <linux/videodev2.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/mt9v011.c linux-libre-2.6.34-gnu1/drivers/media/video/mt9v011.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/mt9v011.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/mt9v011.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/delay.h>
 #include <asm/div64.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/mt9v022.c linux-libre-2.6.34-gnu1/drivers/media/video/mt9v022.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/mt9v022.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/mt9v022.c	2010-05-16 17:17:36.000000000 -0400
@@ -257,19 +257,18 @@ static int mt9v022_set_bus_param(struct
 static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
 {
 	struct soc_camera_link *icl = to_soc_camera_link(icd);
-	unsigned int width_flag;
+	unsigned int flags = SOCAM_MASTER | SOCAM_SLAVE |
+		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_DATA_ACTIVE_HIGH;
 
 	if (icl->query_bus_param)
-		width_flag = icl->query_bus_param(icl) &
-			SOCAM_DATAWIDTH_MASK;
+		flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
 	else
-		width_flag = SOCAM_DATAWIDTH_10;
+		flags |= 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_DATA_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_SLAVE |
-		width_flag;
+	return soc_camera_apply_sensor_flags(icl, flags);
 }
 
 static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/mx1_camera.c linux-libre-2.6.34-gnu1/drivers/media/video/mx1_camera.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/mx1_camera.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/mx1_camera.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/version.h>
 #include <linux/videodev2.h>
@@ -48,8 +49,6 @@
 /*
  * 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 */
@@ -783,7 +782,7 @@ static int __init mx1_camera_probe(struc
 			       pcdev);
 
 	imx_dma_config_channel(pcdev->dma_chan, IMX_DMA_TYPE_FIFO,
-			       IMX_DMA_MEMSIZE_32, DMA_REQ_CSI_R, 0);
+			       IMX_DMA_MEMSIZE_32, MX1_DMA_REQ_CSI_R, 0);
 	/* burst length : 16 words = 64 bytes */
 	imx_dma_config_burstlen(pcdev->dma_chan, 0);
 
@@ -797,8 +796,8 @@ static int __init mx1_camera_probe(struc
 	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_r8 = (long)MX1_DMA_DIMR;
+	regs.ARM_r9 = (long)MX1_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;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/mxb.c linux-libre-2.6.34-gnu1/drivers/media/video/mxb.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/mxb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/mxb.c	2010-05-16 17:17:36.000000000 -0400
@@ -294,7 +294,7 @@ static int mxb_init_done(struct saa7146_
 	/* select tuner-output on saa7111a */
 	i = 0;
 	saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
-		SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS, 0);
+		SAA7111_FMT_CCIR, 0);
 
 	/* select a tuner type */
 	tun_setup.mode_mask = T_ANALOG_TV;
@@ -518,8 +518,8 @@ static int vidioc_s_input(struct file *f
 		return err;
 
 	/* 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 (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0))
+		printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a.\n");
 
 	/* switch the audio-source only if necessary */
 	if (0 == mxb->cur_mute)
@@ -695,14 +695,17 @@ 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)
 {
-	struct mxb *mxb = (struct mxb *)dev->ext_priv;
+	struct mxb *mxb;
 
 	DEB_EE(("dev:%p\n", dev));
 
-	/* checking for i2c-devices can be omitted here, because we
-	   already did this in "mxb_vl42_probe" */
-
 	saa7146_vv_init(dev, &vv_data);
+	if (mxb_probe(dev)) {
+		saa7146_vv_release(dev);
+		return -1;
+	}
+	mxb = (struct mxb *)dev->ext_priv;
+
 	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;
@@ -722,6 +725,7 @@ static int mxb_attach(struct saa7146_dev
 	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"));
+		saa7146_vv_release(dev);
 		return -1;
 	}
 
@@ -842,7 +846,6 @@ static struct saa7146_extension extensio
 	.pci_tbl	= &pci_tbl[0],
 	.module		= THIS_MODULE,
 
-	.probe		= mxb_probe,
 	.attach		= mxb_attach,
 	.detach		= mxb_detach,
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/omap24xxcam.c linux-libre-2.6.34-gnu1/drivers/media/video/omap24xxcam.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/omap24xxcam.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/omap24xxcam.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
@@ -1404,7 +1405,7 @@ static int omap24xxcam_mmap_buffers(stru
 	}
 
 	size = 0;
-	for (i = first; i <= last; i++) {
+	for (i = first; i <= last && i < VIDEO_MAX_FRAME; i++) {
 		struct videobuf_dmabuf *dma = videobuf_to_dma(vbq->bufs[i]);
 
 		for (j = 0; j < dma->sglen; j++) {
@@ -1735,7 +1736,7 @@ static struct v4l2_int_device omap24xxca
  *
  */
 
-static int __init omap24xxcam_probe(struct platform_device *pdev)
+static int __devinit omap24xxcam_probe(struct platform_device *pdev)
 {
 	struct omap24xxcam_device *cam;
 	struct resource *mem;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ov7670.c linux-libre-2.6.34-gnu1/drivers/media/video/ov7670.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/ov7670.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ov7670.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <linux/videodev2.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ov772x.c linux-libre-2.6.34-gnu1/drivers/media/video/ov772x.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/ov772x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ov772x.c	2010-05-16 17:17:36.000000000 -0400
@@ -547,7 +547,6 @@ static const struct v4l2_queryctrl ov772
 	},
 };
 
-
 /*
  * general function
  */
@@ -634,7 +633,12 @@ static unsigned long ov772x_query_bus_pa
 	struct soc_camera_link *icl = to_soc_camera_link(icd);
 	unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
 		SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
-		SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
+		SOCAM_DATA_ACTIVE_HIGH;
+
+	if (priv->info->flags & OV772X_FLAG_8BIT)
+		flags |= SOCAM_DATAWIDTH_8;
+	else
+		flags |= SOCAM_DATAWIDTH_10;
 
 	return soc_camera_apply_sensor_flags(icl, flags);
 }
@@ -1040,15 +1044,6 @@ static int ov772x_video_probe(struct soc
 		return -ENODEV;
 
 	/*
-	 * ov772x only use 8 or 10 bit bus width
-	 */
-	if (SOCAM_DATAWIDTH_10 != priv->info->buswidth &&
-	    SOCAM_DATAWIDTH_8  != priv->info->buswidth) {
-		dev_err(&client->dev, "bus width error\n");
-		return -ENODEV;
-	}
-
-	/*
 	 * check and show product ID and manufacturer ID
 	 */
 	pid = i2c_smbus_read_byte_data(client, PID);
@@ -1130,7 +1125,6 @@ static int ov772x_probe(struct i2c_clien
 			const struct i2c_device_id *did)
 {
 	struct ov772x_priv        *priv;
-	struct ov772x_camera_info *info;
 	struct soc_camera_device  *icd = client->dev.platform_data;
 	struct i2c_adapter        *adapter = to_i2c_adapter(client->dev.parent);
 	struct soc_camera_link    *icl;
@@ -1145,8 +1139,6 @@ static int ov772x_probe(struct i2c_clien
 	if (!icl || !icl->priv)
 		return -EINVAL;
 
-	info = icl->priv;
-
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		dev_err(&adapter->dev,
 			"I2C-Adapter doesn't support "
@@ -1158,7 +1150,7 @@ static int ov772x_probe(struct i2c_clien
 	if (!priv)
 		return -ENOMEM;
 
-	priv->info = info;
+	priv->info = icl->priv;
 
 	v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pms.c linux-libre-2.6.34-gnu1/drivers/media/video/pms.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/pms.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pms.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,6 @@
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,6 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 
 struct routing_scheme {
 	const int *def;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,7 +36,6 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 
 
 struct routing_scheme_item {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.c linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
  */
 
 #include <linux/string.h>
-#include <linux/slab.h>
 #include "pvrusb2-debugifc.h"
 #include "pvrusb2-hdw.h"
 #include "pvrusb2-debug.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-dvb.c linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-dvb.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-dvb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-dvb.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 
 #include <linux/kthread.h>
 #include <linux/freezer.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include "dvbdev.h"
 #include "pvrusb2-debug.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-eeprom.c linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-eeprom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-eeprom.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include "pvrusb2-eeprom.h"
 #include "pvrusb2-hdw-internal.h"
 #include "pvrusb2-debug.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c	2013-05-03 12:07:07.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c	2013-05-03 09:46:29.000000000 -0400
@@ -48,11 +48,13 @@
    before we are allowed to start it running. */
 #define TIME_MSEC_DECODER_WAIT 50
 
+/* This defines a minimum interval that the decoder must be allowed to run
+   before we can safely begin using its streaming output. */
+#define TIME_MSEC_DECODER_STABILIZATION_WAIT 300
+
 /* This defines a minimum interval that the encoder must remain quiet
-   before we are allowed to configure it.  I had this originally set to
-   50msec, but Martin Dauskardt <martin.dauskardt@gmx.de> reports that
-   things work better when it's set to 100msec. */
-#define TIME_MSEC_ENCODER_WAIT 100
+   before we are allowed to configure it. */
+#define TIME_MSEC_ENCODER_WAIT 50
 
 /* This defines the minimum interval that the encoder must successfully run
    before we consider that the encoder has run at least once since its
@@ -334,6 +336,7 @@ static int pvr2_hdw_get_eeprom_addr(stru
 static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
 static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
 static void pvr2_hdw_quiescent_timeout(unsigned long);
+static void pvr2_hdw_decoder_stabilization_timeout(unsigned long);
 static void pvr2_hdw_encoder_wait_timeout(unsigned long);
 static void pvr2_hdw_encoder_run_timeout(unsigned long);
 static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32);
@@ -1705,6 +1708,7 @@ static int pvr2_decoder_enable(struct pv
 	pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 stream=%s",
 		   (enablefl ? "on" : "off"));
 	v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_stream, enablefl);
+	v4l2_device_call_all(&hdw->v4l2_dev, 0, audio, 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
@@ -2461,6 +2465,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct
 	hdw->quiescent_timer.data = (unsigned long)hdw;
 	hdw->quiescent_timer.function = pvr2_hdw_quiescent_timeout;
 
+	init_timer(&hdw->decoder_stabilization_timer);
+	hdw->decoder_stabilization_timer.data = (unsigned long)hdw;
+	hdw->decoder_stabilization_timer.function =
+		pvr2_hdw_decoder_stabilization_timeout;
+
 	init_timer(&hdw->encoder_wait_timer);
 	hdw->encoder_wait_timer.data = (unsigned long)hdw;
 	hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout;
@@ -2674,6 +2683,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct
  fail:
 	if (hdw) {
 		del_timer_sync(&hdw->quiescent_timer);
+		del_timer_sync(&hdw->decoder_stabilization_timer);
 		del_timer_sync(&hdw->encoder_run_timer);
 		del_timer_sync(&hdw->encoder_wait_timer);
 		if (hdw->workqueue) {
@@ -2741,6 +2751,7 @@ void pvr2_hdw_destroy(struct pvr2_hdw *h
 		hdw->workqueue = NULL;
 	}
 	del_timer_sync(&hdw->quiescent_timer);
+	del_timer_sync(&hdw->decoder_stabilization_timer);
 	del_timer_sync(&hdw->encoder_run_timer);
 	del_timer_sync(&hdw->encoder_wait_timer);
 	if (hdw->fw_buffer) {
@@ -4452,7 +4463,7 @@ static int state_check_enable_encoder_ru
 
 	switch (hdw->pathway_state) {
 	case PVR2_PATHWAY_ANALOG:
-		if (hdw->state_decoder_run) {
+		if (hdw->state_decoder_run && hdw->state_decoder_ready) {
 			/* In analog mode, if the decoder is running, then
 			   run the encoder. */
 			return !0;
@@ -4519,6 +4530,17 @@ static void pvr2_hdw_quiescent_timeout(u
 }
 
 
+/* Timeout function for decoder stabilization timer. */
+static void pvr2_hdw_decoder_stabilization_timeout(unsigned long data)
+{
+	struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
+	hdw->state_decoder_ready = !0;
+	trace_stbit("state_decoder_ready", hdw->state_decoder_ready);
+	hdw->state_stale = !0;
+	queue_work(hdw->workqueue, &hdw->workpoll);
+}
+
+
 /* Timeout function for encoder wait timer. */
 static void pvr2_hdw_encoder_wait_timeout(unsigned long data)
 {
@@ -4557,8 +4579,13 @@ static int state_eval_decoder_run(struct
 		}
 		hdw->state_decoder_quiescent = 0;
 		hdw->state_decoder_run = 0;
-		/* paranoia - solve race if timer just completed */
+		/* paranoia - solve race if timer(s) just completed */
 		del_timer_sync(&hdw->quiescent_timer);
+		/* Kill the stabilization timer, in case we're killing the
+		   encoder before the previous stabilization interval has
+		   been properly timed. */
+		del_timer_sync(&hdw->decoder_stabilization_timer);
+		hdw->state_decoder_ready = 0;
 	} else {
 		if (!hdw->state_decoder_quiescent) {
 			if (!timer_pending(&hdw->quiescent_timer)) {
@@ -4596,10 +4623,21 @@ static int state_eval_decoder_run(struct
 		if (hdw->flag_decoder_missed) return 0;
 		if (pvr2_decoder_enable(hdw,!0) < 0) return 0;
 		hdw->state_decoder_quiescent = 0;
+		hdw->state_decoder_ready = 0;
 		hdw->state_decoder_run = !0;
+		if (hdw->decoder_client_id == PVR2_CLIENT_ID_SAA7115) {
+			hdw->decoder_stabilization_timer.expires =
+				jiffies +
+				(HZ * TIME_MSEC_DECODER_STABILIZATION_WAIT /
+				 1000);
+			add_timer(&hdw->decoder_stabilization_timer);
+		} else {
+			hdw->state_decoder_ready = !0;
+		}
 	}
 	trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent);
 	trace_stbit("state_decoder_run",hdw->state_decoder_run);
+	trace_stbit("state_decoder_ready", hdw->state_decoder_ready);
 	return !0;
 }
 
@@ -4797,7 +4835,8 @@ static unsigned int pvr2_hdw_report_unlo
 			buf,acnt,
 			"worker:%s%s%s%s%s%s%s",
 			(hdw->state_decoder_run ?
-			 " <decode:run>" :
+			 (hdw->state_decoder_ready ?
+			  "<decode:run>" : " <decode:start>") :
 			 (hdw->state_decoder_quiescent ?
 			  "" : " <decode:stop>")),
 			(hdw->state_decoder_quiescent ?
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.h linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.h	2010-05-16 17:17:36.000000000 -0400
@@ -306,6 +306,7 @@ struct pvr2_hdw_debug_info {
 	int state_encoder_ok;
 	int state_encoder_run;
 	int state_decoder_run;
+	int state_decoder_ready;
 	int state_usbstream_run;
 	int state_decoder_quiescent;
 	int state_pipeline_config;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h	2010-05-16 17:17:36.000000000 -0400
@@ -233,8 +233,9 @@ struct pvr2_hdw {
 	int state_encoder_waitok;     /* Encoder pre-wait done */
 	int state_encoder_runok;      /* Encoder has run for >= .25 sec */
 	int state_decoder_run;        /* Decoder is running */
+	int state_decoder_ready;      /* Decoder is stabilized & streamable */
 	int state_usbstream_run;      /* FX2 is streaming */
-	int state_decoder_quiescent;  /* Decoder idle for > 50msec */
+	int state_decoder_quiescent;  /* Decoder idle for minimal interval */
 	int state_pipeline_config;    /* Pipeline is configured */
 	int state_pipeline_req;       /* Somebody wants to stream */
 	int state_pipeline_pause;     /* Pipeline must be paused */
@@ -255,9 +256,16 @@ struct pvr2_hdw {
 	void (*state_func)(void *);
 	void *state_data;
 
-	/* Timer for measuring decoder settling time */
+	/* Timer for measuring required decoder settling time before we're
+	   allowed to fire it up again. */
 	struct timer_list quiescent_timer;
 
+	/* Timer for measuring decoder stabilization time, which is the
+	   amount of time we need to let the decoder run before we can
+	   trust its output (otherwise the encoder might see garbage and
+	   then fail to start correctly). */
+	struct timer_list decoder_stabilization_timer;
+
 	/* Timer for measuring encoder pre-wait time */
 	struct timer_list encoder_wait_timer;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-main.c linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-main.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-main.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/videodev2.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-sysfs.c linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -423,10 +423,12 @@ static void pvr2_sysfs_add_debugifc(stru
 
 	dip = kzalloc(sizeof(*dip),GFP_KERNEL);
 	if (!dip) return;
+	sysfs_attr_init(&dip->attr_debugcmd.attr);
 	dip->attr_debugcmd.attr.name = "debugcmd";
 	dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
 	dip->attr_debugcmd.show = debugcmd_show;
 	dip->attr_debugcmd.store = debugcmd_store;
+	sysfs_attr_init(&dip->attr_debuginfo.attr);
 	dip->attr_debuginfo.attr.name = "debuginfo";
 	dip->attr_debuginfo.attr.mode = S_IRUGO;
 	dip->attr_debuginfo.show = debuginfo_show;
@@ -644,6 +646,7 @@ static void class_dev_create(struct pvr2
 		return;
 	}
 
+	sysfs_attr_init(&sfp->attr_v4l_minor_number.attr);
 	sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
 	sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
 	sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
@@ -658,6 +661,7 @@ static void class_dev_create(struct pvr2
 		sfp->v4l_minor_number_created_ok = !0;
 	}
 
+	sysfs_attr_init(&sfp->attr_v4l_radio_minor_number.attr);
 	sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number";
 	sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO;
 	sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show;
@@ -672,6 +676,7 @@ static void class_dev_create(struct pvr2
 		sfp->v4l_radio_minor_number_created_ok = !0;
 	}
 
+	sysfs_attr_init(&sfp->attr_unit_number.attr);
 	sfp->attr_unit_number.attr.name = "unit_number";
 	sfp->attr_unit_number.attr.mode = S_IRUGO;
 	sfp->attr_unit_number.show = unit_number_show;
@@ -685,6 +690,7 @@ static void class_dev_create(struct pvr2
 		sfp->unit_number_created_ok = !0;
 	}
 
+	sysfs_attr_init(&sfp->attr_bus_info.attr);
 	sfp->attr_bus_info.attr.name = "bus_info_str";
 	sfp->attr_bus_info.attr.mode = S_IRUGO;
 	sfp->attr_bus_info.show = bus_info_show;
@@ -699,6 +705,7 @@ static void class_dev_create(struct pvr2
 		sfp->bus_info_created_ok = !0;
 	}
 
+	sysfs_attr_init(&sfp->attr_hdw_name.attr);
 	sfp->attr_hdw_name.attr.name = "device_hardware_type";
 	sfp->attr_hdw_name.attr.mode = S_IRUGO;
 	sfp->attr_hdw_name.show = hdw_name_show;
@@ -713,6 +720,7 @@ static void class_dev_create(struct pvr2
 		sfp->hdw_name_created_ok = !0;
 	}
 
+	sysfs_attr_init(&sfp->attr_hdw_desc.attr);
 	sfp->attr_hdw_desc.attr.name = "device_hardware_description";
 	sfp->attr_hdw_desc.attr.mode = S_IRUGO;
 	sfp->attr_hdw_desc.show = hdw_desc_show;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-v4l2.c linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-v4l2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-v4l2.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include "pvrusb2-context.h"
 #include "pvrusb2-hdw.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,7 +37,6 @@
 #include <media/v4l2-common.h>
 #include <media/saa7115.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 
 struct routing_scheme {
 	const int *def;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-wm8775.c linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-wm8775.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pvrusb2/pvrusb2-wm8775.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,6 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 
 void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pwc/philips.txt linux-libre-2.6.34-gnu1/drivers/media/video/pwc/philips.txt
--- linux-libre-2.6.33-gnu1/drivers/media/video/pwc/philips.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pwc/philips.txt	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,7 @@ a lot of extra information, a FAQ, and t
 contains decompression routines that allow you to use higher image sizes and
 framerates; in addition the webcam uses less bandwidth on the USB bus (handy
 if you want to run more than 1 camera simultaneously). These routines fall
-under a NDA, and may therefor not be distributed as source; however, its use
+under a NDA, and may therefore not be distributed as source; however, its use
 is completely optional.
 
 You can build this code either into your kernel, or as a module. I recommend
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pwc/pwc-dec23.c linux-libre-2.6.34-gnu1/drivers/media/video/pwc/pwc-dec23.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/pwc/pwc-dec23.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pwc/pwc-dec23.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <media/pwc-ioctl.h>
 
 #include <linux/string.h>
+#include <linux/slab.h>
 
 /*
  * USE_LOOKUP_TABLE_TO_CLAMP
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pwc/pwc.h linux-libre-2.6.34-gnu1/drivers/media/video/pwc/pwc.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/pwc/pwc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pwc/pwc.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/version.h>
 #include <linux/mutex.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <asm/errno.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pwc/pwc-v4l.c linux-libre-2.6.34-gnu1/drivers/media/video/pwc/pwc-v4l.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/pwc/pwc-v4l.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pwc/pwc-v4l.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,6 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/poll.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <asm/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/pxa_camera.c linux-libre-2.6.34-gnu1/drivers/media/video/pxa_camera.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/pxa_camera.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/pxa_camera.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
@@ -608,12 +609,9 @@ static void pxa_dma_add_tail_buf(struct
  */
 static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
 {
-	unsigned long cicr0, cifr;
+	unsigned long cicr0;
 
 	dev_dbg(pcdev->soc_host.v4l2_dev.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;
@@ -898,18 +896,8 @@ static void recalculate_fifo_timeout(str
 
 static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
 {
-	struct pxacamera_platform_data *pdata = pcdev->pdata;
-	struct device *dev = pcdev->soc_host.v4l2_dev.dev;
 	u32 cicr4 = 0;
 
-	dev_dbg(dev, "Registered platform device at %p data %p\n",
-		pcdev, pdata);
-
-	if (pdata && pdata->init) {
-		dev_dbg(dev, "%s: Init gpios\n", __func__);
-		pdata->init(dev);
-	}
-
 	/* disable all interrupts */
 	__raw_writel(0x3ff, pcdev->base + CICR0);
 
@@ -944,7 +932,7 @@ static void pxa_camera_deactivate(struct
 static irqreturn_t pxa_camera_irq(int irq, void *data)
 {
 	struct pxa_camera_dev *pcdev = data;
-	unsigned long status, cicr0;
+	unsigned long status, cifr, cicr0;
 	struct pxa_buffer *buf;
 	struct videobuf_buffer *vb;
 
@@ -958,6 +946,10 @@ static irqreturn_t pxa_camera_irq(int ir
 	__raw_writel(status, pcdev->base + CISR);
 
 	if (status & CISR_EOF) {
+		/* Reset the FIFOs */
+		cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
+		__raw_writel(cifr, pcdev->base + CIFR);
+
 		pcdev->active = list_first_entry(&pcdev->capture,
 					   struct pxa_buffer, vb.queue);
 		vb = &pcdev->active->vb;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/rj54n1cb0c.c linux-libre-2.6.34-gnu1/drivers/media/video/rj54n1cb0c.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/rj54n1cb0c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/rj54n1cb0c.c	2010-05-16 17:17:36.000000000 -0400
@@ -165,7 +165,7 @@ struct rj54n1_reg_val {
 	u8 val;
 };
 
-const static struct rj54n1_reg_val bank_4[] = {
+static const struct rj54n1_reg_val bank_4[] = {
 	{0x417, 0},
 	{0x42c, 0},
 	{0x42d, 0xf0},
@@ -186,7 +186,7 @@ const static struct rj54n1_reg_val bank_
 	{0x4fe, 2},
 };
 
-const static struct rj54n1_reg_val bank_5[] = {
+static const struct rj54n1_reg_val bank_5[] = {
 	{0x514, 0},
 	{0x516, 0},
 	{0x518, 0},
@@ -207,7 +207,7 @@ const static struct rj54n1_reg_val bank_
 	{0x5fe, 2},
 };
 
-const static struct rj54n1_reg_val bank_7[] = {
+static const struct rj54n1_reg_val bank_7[] = {
 	{0x70a, 0},
 	{0x714, 0xff},
 	{0x715, 0xff},
@@ -215,7 +215,7 @@ const static struct rj54n1_reg_val bank_
 	{0x7FE, 2},
 };
 
-const static struct rj54n1_reg_val bank_8[] = {
+static const struct rj54n1_reg_val bank_8[] = {
 	{0x800, 0x00},
 	{0x801, 0x01},
 	{0x802, 0x61},
@@ -403,12 +403,12 @@ const static struct rj54n1_reg_val bank_
 	{0x8FE, 2},
 };
 
-const static struct rj54n1_reg_val bank_10[] = {
+static const struct rj54n1_reg_val bank_10[] = {
 	{0x10bf, 0x69}
 };
 
 /* Clock dividers - these are default register values, divider = register + 1 */
-const static struct rj54n1_clock_div clk_div = {
+static const struct rj54n1_clock_div clk_div = {
 	.ratio_tg	= 3 /* default: 5 */,
 	.ratio_t	= 4 /* default: 1 */,
 	.ratio_r	= 4 /* default: 0 */,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/s2255drv.c linux-libre-2.6.34-gnu1/drivers/media/video/s2255drv.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/s2255drv.c	2013-05-03 12:07:31.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/s2255drv.c	2013-05-03 09:46:54.000000000 -0400
@@ -45,6 +45,7 @@
 #include <linux/firmware.h>
 #include <linux/kernel.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/version.h>
 #include <linux/mm.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa5246a.c linux-libre-2.6.34-gnu1/drivers/media/video/saa5246a.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa5246a.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa5246a.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/videotext.h>
 #include <linux/videodev2.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa5249.c linux-libre-2.6.34-gnu1/drivers/media/video/saa5249.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa5249.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa5249.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,6 +50,7 @@
 #include <linux/delay.h>
 #include <linux/videotext.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ioctl.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7115.c linux-libre-2.6.34-gnu1/drivers/media/video/saa7115.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7115.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7115.c	2010-05-16 17:17:36.000000000 -0400
@@ -104,6 +104,10 @@ static int saa711x_has_reg(const int id,
 	if (id == V4L2_IDENT_SAA7111)
 		return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
 		       (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
+	if (id == V4L2_IDENT_SAA7111A)
+		return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
+		       reg != 0x14 && reg != 0x18 && reg != 0x19 &&
+		       reg != 0x1d && reg != 0x1e;
 
 	/* common for saa7113/4/5/8 */
 	if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
@@ -954,8 +958,7 @@ static void saa711x_set_v4lstd(struct v4
 	011 NTSC N (3.58MHz)            PAL M (3.58MHz)
 	100 reserved                    NTSC-Japan (3.58MHz)
 	*/
-	if (state->ident == V4L2_IDENT_SAA7111 ||
-	    state->ident == V4L2_IDENT_SAA7113) {
+	if (state->ident <= V4L2_IDENT_SAA7113) {
 		u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
 
 		if (std == V4L2_STD_PAL_M) {
@@ -1232,22 +1235,19 @@ static int saa711x_s_routing(struct v4l2
 			     u32 input, u32 output, u32 config)
 {
 	struct saa711x_state *state = to_state(sd);
-	u8 mask = (state->ident == V4L2_IDENT_SAA7111) ? 0xf8 : 0xf0;
+	u8 mask = (state->ident <= V4L2_IDENT_SAA7111A) ? 0xf8 : 0xf0;
 
 	v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n",
 		input, output);
 
 	/* saa7111/3 does not have these inputs */
-	if ((state->ident == V4L2_IDENT_SAA7113 ||
-	     state->ident == V4L2_IDENT_SAA7111) &&
+	if (state->ident <= V4L2_IDENT_SAA7113 &&
 	    (input == SAA7115_COMPOSITE4 ||
 	     input == SAA7115_COMPOSITE5)) {
 		return -EINVAL;
 	}
 	if (input > SAA7115_SVIDEO3)
 		return -EINVAL;
-	if (output > SAA7115_IPORT_ON)
-		return -EINVAL;
 	if (state->input == input && state->output == output)
 		return 0;
 	v4l2_dbg(1, debug, sd, "now setting %s input %s output\n",
@@ -1256,7 +1256,7 @@ static int saa711x_s_routing(struct v4l2
 	state->input = input;
 
 	/* saa7111 has slightly different input numbering */
-	if (state->ident == V4L2_IDENT_SAA7111) {
+	if (state->ident <= V4L2_IDENT_SAA7111A) {
 		if (input >= SAA7115_COMPOSITE4)
 			input -= 2;
 		/* saa7111 specific */
@@ -1292,7 +1292,7 @@ static int saa711x_s_gpio(struct v4l2_su
 {
 	struct saa711x_state *state = to_state(sd);
 
-	if (state->ident != V4L2_IDENT_SAA7111)
+	if (state->ident > V4L2_IDENT_SAA7111A)
 		return -EINVAL;
 	saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) |
 		(val ? 0x80 : 0));
@@ -1596,6 +1596,10 @@ static int saa711x_probe(struct i2c_clie
 	switch (chip_id) {
 	case '1':
 		state->ident = V4L2_IDENT_SAA7111;
+		if (saa711x_read(sd, R_00_CHIP_VERSION) & 0xf0) {
+			v4l_info(client, "saa7111a variant found\n");
+			state->ident = V4L2_IDENT_SAA7111A;
+		}
 		break;
 	case '3':
 		state->ident = V4L2_IDENT_SAA7113;
@@ -1612,7 +1616,7 @@ static int saa711x_probe(struct i2c_clie
 	default:
 		state->ident = V4L2_IDENT_SAA7111;
 		v4l2_info(sd, "WARNING: Chip is not known - Falling back to saa7111\n");
-
+		break;
 	}
 
 	state->audclk_freq = 48000;
@@ -1623,6 +1627,7 @@ static int saa711x_probe(struct i2c_clie
 	state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
 	switch (state->ident) {
 	case V4L2_IDENT_SAA7111:
+	case V4L2_IDENT_SAA7111A:
 		saa711x_writeregs(sd, saa7111_init);
 		break;
 	case V4L2_IDENT_SAA7113:
@@ -1632,7 +1637,7 @@ static int saa711x_probe(struct i2c_clie
 		state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
 		saa711x_writeregs(sd, saa7115_init_auto_input);
 	}
-	if (state->ident != V4L2_IDENT_SAA7111)
+	if (state->ident > V4L2_IDENT_SAA7111A)
 		saa711x_writeregs(sd, saa7115_init_misc);
 	saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7127.c linux-libre-2.6.34-gnu1/drivers/media/video/saa7127.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7127.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7127.c	2010-05-16 17:17:36.000000000 -0400
@@ -181,7 +181,7 @@ static const struct i2c_reg_value saa712
 #define SAA7127_60HZ_DAC_CONTROL 0x15
 static const struct i2c_reg_value saa7127_init_config_60hz[] = {
 	{ SAA7127_REG_BURST_START, 			0x19 },
-	/* BURST_END is also used as a chip ID in saa7127_detect_client */
+	/* BURST_END is also used as a chip ID in saa7127_probe */
 	{ SAA7127_REG_BURST_END, 			0x1d },
 	{ SAA7127_REG_CHROMA_PHASE, 			0xa3 },
 	{ SAA7127_REG_GAINU, 				0x98 },
@@ -200,10 +200,10 @@ static const struct i2c_reg_value saa712
 	{ 0, 0 }
 };
 
-#define SAA7127_50HZ_DAC_CONTROL 0x02
-static struct i2c_reg_value saa7127_init_config_50hz[] = {
+#define SAA7127_50HZ_PAL_DAC_CONTROL 0x02
+static struct i2c_reg_value saa7127_init_config_50hz_pal[] = {
 	{ SAA7127_REG_BURST_START, 			0x21 },
-	/* BURST_END is also used as a chip ID in saa7127_detect_client */
+	/* BURST_END is also used as a chip ID in saa7127_probe */
 	{ SAA7127_REG_BURST_END, 			0x1d },
 	{ SAA7127_REG_CHROMA_PHASE, 			0x3f },
 	{ SAA7127_REG_GAINU, 				0x7d },
@@ -222,6 +222,28 @@ static struct i2c_reg_value saa7127_init
 	{ 0, 0 }
 };
 
+#define SAA7127_50HZ_SECAM_DAC_CONTROL 0x08
+static struct i2c_reg_value saa7127_init_config_50hz_secam[] = {
+	{ SAA7127_REG_BURST_START, 			0x21 },
+	/* BURST_END is also used as a chip ID in saa7127_probe */
+	{ SAA7127_REG_BURST_END, 			0x1d },
+	{ SAA7127_REG_CHROMA_PHASE, 			0x3f },
+	{ SAA7127_REG_GAINU, 				0x6a },
+	{ SAA7127_REG_GAINV, 				0x81 },
+	{ SAA7127_REG_BLACK_LEVEL, 			0x33 },
+	{ SAA7127_REG_BLANKING_LEVEL, 			0x35 },
+	{ SAA7127_REG_VBI_BLANKING, 			0x35 },
+	{ SAA7127_REG_DAC_CONTROL, 			0x08 },
+	{ SAA7127_REG_BURST_AMP, 			0x2f },
+	{ SAA7127_REG_SUBC3, 				0xb2 },
+	{ SAA7127_REG_SUBC2, 				0x3b },
+	{ SAA7127_REG_SUBC1, 				0xa3 },
+	{ SAA7127_REG_SUBC0, 				0x28 },
+	{ SAA7127_REG_MULTI, 				0x90 },
+	{ SAA7127_REG_CLOSED_CAPTION, 			0x00 },
+	{ 0, 0 }
+};
+
 /*
  **********************************************************************
  *
@@ -463,10 +485,21 @@ static int saa7127_set_std(struct v4l2_s
 		v4l2_dbg(1, debug, sd, "Selecting 60 Hz video Standard\n");
 		inittab = saa7127_init_config_60hz;
 		state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
+
+	} else if (state->ident == V4L2_IDENT_SAA7129 &&
+		   (std & V4L2_STD_SECAM) &&
+		   !(std & (V4L2_STD_625_50 & ~V4L2_STD_SECAM))) {
+
+		/* If and only if SECAM, with a SAA712[89] */
+		v4l2_dbg(1, debug, sd,
+			 "Selecting 50 Hz SECAM video Standard\n");
+		inittab = saa7127_init_config_50hz_secam;
+		state->reg_61 = SAA7127_50HZ_SECAM_DAC_CONTROL;
+
 	} else {
-		v4l2_dbg(1, debug, sd, "Selecting 50 Hz video Standard\n");
-		inittab = saa7127_init_config_50hz;
-		state->reg_61 = SAA7127_50HZ_DAC_CONTROL;
+		v4l2_dbg(1, debug, sd, "Selecting 50 Hz PAL video Standard\n");
+		inittab = saa7127_init_config_50hz_pal;
+		state->reg_61 = SAA7127_50HZ_PAL_DAC_CONTROL;
 	}
 
 	/* Write Table */
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-cards.c linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-cards.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-cards.c	2013-05-03 12:03:49.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-cards.c	2013-05-03 09:44:44.000000000 -0400
@@ -4160,7 +4160,7 @@ struct saa7134_board saa7134_boards[] =
 			.amux = LINE2,
 		},
 	},
-	[SAA7134_BOARD_BEHOLD_505RDS] = {
+	[SAA7134_BOARD_BEHOLD_505RDS_MK5] = {
 		/*       Beholder Intl. Ltd. 2008      */
 		/*Dmitry Belimov <d.belimov@gmail.com> */
 		.name           = "Beholder BeholdTV 505 RDS",
@@ -5320,6 +5320,41 @@ struct saa7134_board saa7134_boards[] =
 			.vmux = 8,
 		} },
 	},
+	[SAA7134_BOARD_BEHOLD_505RDS_MK3] = {
+		/*       Beholder Intl. Ltd. 2008      */
+		/*Dmitry Belimov <d.belimov@gmail.com> */
+		.name           = "Beholder BeholdTV 505 RDS",
+		.audio_clock    = 0x00200000,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.rds_addr 	= 0x10,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.gpiomask       = 0x00008000,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 3,
+			.amux = LINE2,
+			.tv   = 1,
+		}, {
+			.name = name_comp1,
+			.vmux = 1,
+			.amux = LINE1,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		} },
+		.mute = {
+			.name = name_mute,
+			.amux = LINE1,
+		},
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
+	},
 
 };
 
@@ -6235,7 +6270,13 @@ struct pci_device_id saa7134_pci_tbl[] =
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
 		.subvendor    = 0x0000,
 		.subdevice    = 0x505B,
-		.driver_data  = SAA7134_BOARD_BEHOLD_505RDS,
+		.driver_data  = SAA7134_BOARD_BEHOLD_505RDS_MK5,
+	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+		.subvendor    = 0x0000,
+		.subdevice    = 0x5051,
+		.driver_data  = SAA7134_BOARD_BEHOLD_505RDS_MK3,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
@@ -6792,7 +6833,8 @@ int saa7134_board_init1(struct saa7134_d
 	case SAA7134_BOARD_BEHOLD_407FM:
 	case SAA7134_BOARD_BEHOLD_409:
 	case SAA7134_BOARD_BEHOLD_505FM:
-	case SAA7134_BOARD_BEHOLD_505RDS:
+	case SAA7134_BOARD_BEHOLD_505RDS_MK5:
+	case SAA7134_BOARD_BEHOLD_505RDS_MK3:
 	case SAA7134_BOARD_BEHOLD_507_9FM:
 	case SAA7134_BOARD_BEHOLD_507RDS_MK3:
 	case SAA7134_BOARD_BEHOLD_507RDS_MK5:
@@ -6953,8 +6995,8 @@ int saa7134_board_init1(struct saa7134_d
 		break;
 	case SAA7134_BOARD_VIDEOMATE_S350:
 		dev->has_remote = SAA7134_REMOTE_GPIO;
-		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x00008000, 0x00008000);
-		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000);
+		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x0000C000, 0x0000C000);
+		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0000C000, 0x0000C000);
 		break;
 	}
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-dvb.c linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-dvb.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-dvb.c	2013-05-03 12:07:21.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-dvb.c	2013-05-03 09:46:41.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
 #include <linux/suspend.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-empress.c linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-empress.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-empress.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-empress.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/delay.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134.h linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134.h	2010-05-16 17:17:36.000000000 -0400
@@ -282,7 +282,7 @@ struct saa7134_format {
 #define SAA7134_BOARD_HAUPPAUGE_HVR1120   156
 #define SAA7134_BOARD_AVERMEDIA_STUDIO_507UA 157
 #define SAA7134_BOARD_AVERMEDIA_CARDBUS_501 158
-#define SAA7134_BOARD_BEHOLD_505RDS         159
+#define SAA7134_BOARD_BEHOLD_505RDS_MK5     159
 #define SAA7134_BOARD_BEHOLD_507RDS_MK3     160
 #define SAA7134_BOARD_BEHOLD_507RDS_MK5     161
 #define SAA7134_BOARD_BEHOLD_607FM_MK5      162
@@ -299,6 +299,7 @@ struct saa7134_format {
 #define SAA7134_BOARD_ZOLID_HYBRID_PCI		173
 #define SAA7134_BOARD_ASUS_EUROPA_HYBRID	174
 #define SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S 175
+#define SAA7134_BOARD_BEHOLD_505RDS_MK3     176
 
 #define SAA7134_MAXBOARDS 32
 #define SAA7134_INPUT_MAX 8
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-i2c.c linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-i2c.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include "saa7134-reg.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-input.c linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-input.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-input.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-input.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 
 #include "saa7134-reg.h"
 #include "saa7134.h"
@@ -460,7 +461,7 @@ int saa7134_input_init1(struct saa7134_d
 	int polling      = 0;
 	int rc5_gpio	 = 0;
 	int nec_gpio	 = 0;
-	int ir_type      = IR_TYPE_OTHER;
+	u64 ir_type = IR_TYPE_OTHER;
 	int err;
 
 	if (dev->has_remote != SAA7134_REMOTE_GPIO)
@@ -568,7 +569,8 @@ int saa7134_input_init1(struct saa7134_d
 	case SAA7134_BOARD_BEHOLD_407FM:
 	case SAA7134_BOARD_BEHOLD_409:
 	case SAA7134_BOARD_BEHOLD_505FM:
-	case SAA7134_BOARD_BEHOLD_505RDS:
+	case SAA7134_BOARD_BEHOLD_505RDS_MK5:
+	case SAA7134_BOARD_BEHOLD_505RDS_MK3:
 	case SAA7134_BOARD_BEHOLD_507_9FM:
 	case SAA7134_BOARD_BEHOLD_507RDS_MK3:
 	case SAA7134_BOARD_BEHOLD_507RDS_MK5:
@@ -728,7 +730,7 @@ int saa7134_input_init1(struct saa7134_d
 	dev->remote = ir;
 	saa7134_ir_start(dev, ir);
 
-	err = ir_input_register(ir->dev, ir_codes);
+	err = ir_input_register(ir->dev, ir_codes, NULL);
 	if (err)
 		goto err_out_stop;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-ts.c linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-ts.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-ts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-ts.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include "saa7134-reg.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-tvaudio.c linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-tvaudio.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-tvaudio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-tvaudio.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/kthread.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/freezer.h>
 #include <asm/div64.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-vbi.c linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-vbi.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-vbi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-vbi.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 
 #include "saa7134-reg.h"
 #include "saa7134.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-video.c linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-video.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-video.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7134/saa7134-video.c	2010-05-16 17:17:36.000000000 -0400
@@ -205,7 +205,7 @@ static struct saa7134_format formats[] =
 
 #define NORM_525_60			\
 		.h_start       = 0,	\
-		.h_stop        = 703,	\
+		.h_stop        = 719,	\
 		.video_v_start = 23,	\
 		.video_v_stop  = 262,	\
 		.vbi_v_start_0 = 10,	\
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7164/saa7164-api.c linux-libre-2.6.34-gnu1/drivers/media/video/saa7164/saa7164-api.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7164/saa7164-api.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7164/saa7164-api.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 
 #include <linux/wait.h>
+#include <linux/slab.h>
 
 #include "saa7164.h"
 
@@ -523,7 +524,7 @@ int saa7164_api_i2c_write(struct saa7164
 	}
 
 	reglen = saa7164_i2caddr_to_reglen(bus, addr);
-	if (unitid < 0) {
+	if (reglen < 0) {
 		printk(KERN_ERR
 			"%s() error, cannot translate regaddr to reglen\n",
 			__func__);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7164/saa7164-buffer.c linux-libre-2.6.34-gnu1/drivers/media/video/saa7164/saa7164-buffer.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7164/saa7164-buffer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7164/saa7164-buffer.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,8 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
+
 #include "saa7164.h"
 
 /* The PCI address space for buffer handling looks like this:
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7164/saa7164-fw.c linux-libre-2.6.34-gnu1/drivers/media/video/saa7164/saa7164-fw.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7164/saa7164-fw.c	2013-05-03 12:07:23.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7164/saa7164-fw.c	2013-05-03 09:46:43.000000000 -0400
@@ -20,6 +20,7 @@
  */
 
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #include "saa7164.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa717x.c linux-libre-2.6.34-gnu1/drivers/media/video/saa717x.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa717x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa717x.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #include <linux/videodev2.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/saa7185.c linux-libre-2.6.34-gnu1/drivers/media/video/saa7185.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/saa7185.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/saa7185.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/sh_mobile_ceu_camera.c linux-libre-2.6.34-gnu1/drivers/media/video/sh_mobile_ceu_camera.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/sh_mobile_ceu_camera.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/sh_mobile_ceu_camera.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/moduleparam.h>
 #include <linux/time.h>
 #include <linux/version.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/videodev2.h>
@@ -1632,7 +1633,7 @@ static int sh_mobile_ceu_try_fmt(struct
 	height = pix->height;
 
 	pix->bytesperline = soc_mbus_bytes_per_line(width, xlate->host_fmt);
-	if (pix->bytesperline < 0)
+	if ((int)pix->bytesperline < 0)
 		return pix->bytesperline;
 	pix->sizeimage = height * pix->bytesperline;
 
@@ -1748,6 +1749,22 @@ static void sh_mobile_ceu_init_videobuf(
 				       icd);
 }
 
+static int sh_mobile_ceu_get_parm(struct soc_camera_device *icd,
+				  struct v4l2_streamparm *parm)
+{
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+
+	return v4l2_subdev_call(sd, video, g_parm, parm);
+}
+
+static int sh_mobile_ceu_set_parm(struct soc_camera_device *icd,
+				  struct v4l2_streamparm *parm)
+{
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+
+	return v4l2_subdev_call(sd, video, s_parm, parm);
+}
+
 static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd,
 				  struct v4l2_control *ctrl)
 {
@@ -1808,6 +1825,8 @@ static struct soc_camera_host_ops sh_mob
 	.try_fmt	= sh_mobile_ceu_try_fmt,
 	.set_ctrl	= sh_mobile_ceu_set_ctrl,
 	.get_ctrl	= sh_mobile_ceu_get_ctrl,
+	.set_parm	= sh_mobile_ceu_set_parm,
+	.get_parm	= sh_mobile_ceu_get_parm,
 	.reqbufs	= sh_mobile_ceu_reqbufs,
 	.poll		= sh_mobile_ceu_poll,
 	.querycap	= sh_mobile_ceu_querycap,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/sn9c102/Kconfig linux-libre-2.6.34-gnu1/drivers/media/video/sn9c102/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/media/video/sn9c102/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/sn9c102/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,10 @@
 config USB_SN9C102
-	tristate "USB SN9C1xx PC Camera Controller support"
+	tristate "USB SN9C1xx PC Camera Controller support (DEPRECATED)"
 	depends on VIDEO_V4L2
 	---help---
+	  This driver is DEPRECATED please use the gspca sonixb and
+	  sonixj modules instead.
+
 	  Say Y here if you want support for cameras based on SONiX SN9C101,
 	  SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers.
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/sn9c102/sn9c102_devtable.h linux-libre-2.6.34-gnu1/drivers/media/video/sn9c102/sn9c102_devtable.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/sn9c102/sn9c102_devtable.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/sn9c102/sn9c102_devtable.h	2010-05-16 17:17:36.000000000 -0400
@@ -45,20 +45,24 @@ static const struct usb_device_id sn9c10
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), },
 #endif
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), },
+#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), },
 /*	{ SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */
+#endif
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), },
+#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6028, BRIDGE_SN9C102), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), },
+#endif
 	{ SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), },
 #if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
 	{ SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), },
-#endif
 /*	{ SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */
+#endif
 	{ SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), },
 	/* SN9C103 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/sn9c102/sn9c102_sensor.h linux-libre-2.6.34-gnu1/drivers/media/video/sn9c102/sn9c102_sensor.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/sn9c102/sn9c102_sensor.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/sn9c102/sn9c102_sensor.h	2010-05-16 17:17:36.000000000 -0400
@@ -120,7 +120,7 @@ extern int sn9c102_write_regs(struct sn9
 /*
    Write multiple registers with constant values. For example:
    sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
-   Register adresses must be < 256.
+   Register addresses must be < 256.
 */
 #define sn9c102_write_const_regs(sn9c102_device, data...)                     \
 	({ static const u8 _valreg[][2] = {data};                             \
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/soc_camera.c linux-libre-2.6.34-gnu1/drivers/media/video/soc_camera.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/soc_camera.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/soc_camera.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/mutex.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include <media/soc_camera.h>
@@ -781,6 +782,32 @@ static int soc_camera_s_crop(struct file
 	return ret;
 }
 
+static int soc_camera_g_parm(struct file *file, void *fh,
+			     struct v4l2_streamparm *a)
+{
+	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);
+
+	if (ici->ops->get_parm)
+		return ici->ops->get_parm(icd, a);
+
+	return -ENOIOCTLCMD;
+}
+
+static int soc_camera_s_parm(struct file *file, void *fh,
+			     struct v4l2_streamparm *a)
+{
+	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);
+
+	if (ici->ops->set_parm)
+		return ici->ops->set_parm(icd, a);
+
+	return -ENOIOCTLCMD;
+}
+
 static int soc_camera_g_chip_ident(struct file *file, void *fh,
 				   struct v4l2_dbg_chip_ident *id)
 {
@@ -846,10 +873,8 @@ static int soc_camera_init_i2c(struct so
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id);
 	struct v4l2_subdev *subdev;
-	int ret;
 
 	if (!adap) {
-		ret = -ENODEV;
 		dev_err(&icd->dev, "Cannot get I2C adapter #%d. No driver?\n",
 			icl->i2c_adapter_id);
 		goto ei2cga;
@@ -859,10 +884,8 @@ static int soc_camera_init_i2c(struct so
 
 	subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
 				icl->module_name, icl->board_info, NULL);
-	if (!subdev) {
-		ret = -ENOMEM;
+	if (!subdev)
 		goto ei2cnd;
-	}
 
 	client = subdev->priv;
 
@@ -873,7 +896,7 @@ static int soc_camera_init_i2c(struct so
 ei2cnd:
 	i2c_put_adapter(adap);
 ei2cga:
-	return ret;
+	return -ENODEV;
 }
 
 static void soc_camera_free_i2c(struct soc_camera_device *icd)
@@ -1260,6 +1283,8 @@ static const struct v4l2_ioctl_ops soc_c
 	.vidioc_cropcap		 = soc_camera_cropcap,
 	.vidioc_g_crop		 = soc_camera_g_crop,
 	.vidioc_s_crop		 = soc_camera_s_crop,
+	.vidioc_g_parm		 = soc_camera_g_parm,
+	.vidioc_s_parm		 = soc_camera_s_parm,
 	.vidioc_g_chip_ident     = soc_camera_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register	 = soc_camera_g_register,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/soc_mediabus.c linux-libre-2.6.34-gnu1/drivers/media/video/soc_mediabus.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/soc_mediabus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/soc_mediabus.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,91 +24,106 @@ static const struct soc_mbus_pixelfmt mb
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_LE,
-	}, [MBUS_IDX(YVYU8_2X8_LE)] = {
+	},
+	[MBUS_IDX(YVYU8_2X8_LE)] = {
 		.fourcc			= V4L2_PIX_FMT_YVYU,
 		.name			= "YVYU",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_LE,
-	}, [MBUS_IDX(YUYV8_2X8_BE)] = {
+	},
+	[MBUS_IDX(YUYV8_2X8_BE)] = {
 		.fourcc			= V4L2_PIX_FMT_UYVY,
 		.name			= "UYVY",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_LE,
-	}, [MBUS_IDX(YVYU8_2X8_BE)] = {
+	},
+	[MBUS_IDX(YVYU8_2X8_BE)] = {
 		.fourcc			= V4L2_PIX_FMT_VYUY,
 		.name			= "VYUY",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_LE,
-	}, [MBUS_IDX(RGB555_2X8_PADHI_LE)] = {
+	},
+	[MBUS_IDX(RGB555_2X8_PADHI_LE)] = {
 		.fourcc			= V4L2_PIX_FMT_RGB555,
 		.name			= "RGB555",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_LE,
-	}, [MBUS_IDX(RGB555_2X8_PADHI_BE)] = {
+	},
+	[MBUS_IDX(RGB555_2X8_PADHI_BE)] = {
 		.fourcc			= V4L2_PIX_FMT_RGB555X,
 		.name			= "RGB555X",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_LE,
-	}, [MBUS_IDX(RGB565_2X8_LE)] = {
+	},
+	[MBUS_IDX(RGB565_2X8_LE)] = {
 		.fourcc			= V4L2_PIX_FMT_RGB565,
 		.name			= "RGB565",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_LE,
-	}, [MBUS_IDX(RGB565_2X8_BE)] = {
+	},
+	[MBUS_IDX(RGB565_2X8_BE)] = {
 		.fourcc			= V4L2_PIX_FMT_RGB565X,
 		.name			= "RGB565X",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_LE,
-	}, [MBUS_IDX(SBGGR8_1X8)] = {
+	},
+	[MBUS_IDX(SBGGR8_1X8)] = {
 		.fourcc			= V4L2_PIX_FMT_SBGGR8,
 		.name			= "Bayer 8 BGGR",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_NONE,
 		.order			= SOC_MBUS_ORDER_LE,
-	}, [MBUS_IDX(SBGGR10_1X10)] = {
+	},
+	[MBUS_IDX(SBGGR10_1X10)] = {
 		.fourcc			= V4L2_PIX_FMT_SBGGR10,
 		.name			= "Bayer 10 BGGR",
 		.bits_per_sample	= 10,
 		.packing		= SOC_MBUS_PACKING_EXTEND16,
 		.order			= SOC_MBUS_ORDER_LE,
-	}, [MBUS_IDX(GREY8_1X8)] = {
+	},
+	[MBUS_IDX(GREY8_1X8)] = {
 		.fourcc			= V4L2_PIX_FMT_GREY,
 		.name			= "Grey",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_NONE,
 		.order			= SOC_MBUS_ORDER_LE,
-	}, [MBUS_IDX(Y10_1X10)] = {
+	},
+	[MBUS_IDX(Y10_1X10)] = {
 		.fourcc			= V4L2_PIX_FMT_Y10,
 		.name			= "Grey 10bit",
 		.bits_per_sample	= 10,
 		.packing		= SOC_MBUS_PACKING_EXTEND16,
 		.order			= SOC_MBUS_ORDER_LE,
-	}, [MBUS_IDX(SBGGR10_2X8_PADHI_LE)] = {
+	},
+	[MBUS_IDX(SBGGR10_2X8_PADHI_LE)] = {
 		.fourcc			= V4L2_PIX_FMT_SBGGR10,
 		.name			= "Bayer 10 BGGR",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_LE,
-	}, [MBUS_IDX(SBGGR10_2X8_PADLO_LE)] = {
+	},
+	[MBUS_IDX(SBGGR10_2X8_PADLO_LE)] = {
 		.fourcc			= V4L2_PIX_FMT_SBGGR10,
 		.name			= "Bayer 10 BGGR",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADLO,
 		.order			= SOC_MBUS_ORDER_LE,
-	}, [MBUS_IDX(SBGGR10_2X8_PADHI_BE)] = {
+	},
+	[MBUS_IDX(SBGGR10_2X8_PADHI_BE)] = {
 		.fourcc			= V4L2_PIX_FMT_SBGGR10,
 		.name			= "Bayer 10 BGGR",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_BE,
-	}, [MBUS_IDX(SBGGR10_2X8_PADLO_BE)] = {
+	},
+	[MBUS_IDX(SBGGR10_2X8_PADLO_BE)] = {
 		.fourcc			= V4L2_PIX_FMT_SBGGR10,
 		.name			= "Bayer 10 BGGR",
 		.bits_per_sample	= 8,
@@ -134,7 +149,8 @@ EXPORT_SYMBOL(soc_mbus_bytes_per_line);
 const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
 	enum v4l2_mbus_pixelcode code)
 {
-	if ((unsigned int)(code - V4L2_MBUS_FMT_FIXED) > ARRAY_SIZE(mbus_fmt))
+	if (code - V4L2_MBUS_FMT_FIXED > ARRAY_SIZE(mbus_fmt) ||
+	    code <= V4L2_MBUS_FMT_FIXED)
 		return NULL;
 	return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tda9840.c linux-libre-2.6.34-gnu1/drivers/media/video/tda9840.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/tda9840.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tda9840.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 
 #include <linux/module.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tea6415c.c linux-libre-2.6.34-gnu1/drivers/media/video/tea6415c.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/tea6415c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tea6415c.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 
 #include <linux/module.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tea6420.c linux-libre-2.6.34-gnu1/drivers/media/video/tea6420.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/tea6420.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tea6420.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
 
     The tea6420 is a bus controlled audio-matrix with 5 stereo inputs,
     4 stereo outputs and gain control for each output.
-    It is cascadable, i.e. it can be found at the adresses 0x98
+    It is cascadable, i.e. it can be found at the addresses 0x98
     and 0x9a on the i2c-bus.
 
     For detailed informations download the specifications directly
@@ -30,6 +30,7 @@
 
 #include <linux/module.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/ths7303.c linux-libre-2.6.34-gnu1/drivers/media/video/ths7303.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/ths7303.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/ths7303.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/device.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/Kconfig linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,16 @@
+config VIDEO_TLG2300
+	tristate "Telegent TLG2300 USB video capture support"
+	depends on VIDEO_DEV && I2C && INPUT && SND && DVB_CORE
+	select VIDEO_TUNER
+	select VIDEO_TVEEPROM
+	select VIDEO_IR
+	select VIDEOBUF_VMALLOC
+	select SND_PCM
+	select VIDEOBUF_DVB
+
+	---help---
+	  This is a video4linux driver for Telegent tlg2300 based TV cards.
+	  The driver supports V4L2, DVB-T and radio.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called poseidon
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/Makefile linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/Makefile
--- linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,9 @@
+poseidon-objs := pd-video.o pd-alsa.o pd-dvb.o pd-radio.o pd-main.o
+
+obj-$(CONFIG_VIDEO_TLG2300) += poseidon.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.33-gnu1/drivers/media/video/tlg2300/pd-alsa.c linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/pd-alsa.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/pd-alsa.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/pd-alsa.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,332 @@
+#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/vmalloc.h>
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <linux/gfp.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 "pd-common.h"
+#include "vendorcmds.h"
+
+static void complete_handler_audio(struct urb *urb);
+#define AUDIO_EP	(0x83)
+#define AUDIO_BUF_SIZE	(512)
+#define PERIOD_SIZE	(1024 * 8)
+#define PERIOD_MIN	(4)
+#define PERIOD_MAX 	PERIOD_MIN
+
+static struct snd_pcm_hardware snd_pd_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_48000,
+
+	.rate_min = 48000,
+	.rate_max = 48000,
+	.channels_min = 2,
+	.channels_max = 2,
+	.buffer_bytes_max = PERIOD_SIZE * PERIOD_MIN,
+	.period_bytes_min = PERIOD_SIZE,
+	.period_bytes_max = PERIOD_SIZE,
+	.periods_min = PERIOD_MIN,
+	.periods_max = PERIOD_MAX,
+	/*
+	.buffer_bytes_max = 62720 * 8,
+	.period_bytes_min = 64,
+	.period_bytes_max = 12544,
+	.periods_min = 2,
+	.periods_max = 98
+	*/
+};
+
+static int snd_pd_capture_open(struct snd_pcm_substream *substream)
+{
+	struct poseidon *p = snd_pcm_substream_chip(substream);
+	struct poseidon_audio *pa = &p->audio;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+
+	if (!p)
+		return -ENODEV;
+	pa->users++;
+	pa->card_close 		= 0;
+	pa->capture_pcm_substream	= substream;
+	runtime->private_data		= p;
+
+	runtime->hw = snd_pd_hw_capture;
+	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+	usb_autopm_get_interface(p->interface);
+	kref_get(&p->kref);
+	return 0;
+}
+
+static int snd_pd_pcm_close(struct snd_pcm_substream *substream)
+{
+	struct poseidon *p = snd_pcm_substream_chip(substream);
+	struct poseidon_audio *pa = &p->audio;
+
+	pa->users--;
+	pa->card_close 		= 1;
+	usb_autopm_put_interface(p->interface);
+	kref_put(&p->kref, poseidon_delete);
+	return 0;
+}
+
+static int snd_pd_hw_capture_params(struct snd_pcm_substream *substream,
+					struct snd_pcm_hw_params *hw_params)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	unsigned int size;
+
+	size = params_buffer_bytes(hw_params);
+	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;
+	else
+		runtime->dma_bytes = size;
+	return 0;
+}
+
+static int audio_buf_free(struct poseidon *p)
+{
+	struct poseidon_audio *pa = &p->audio;
+	int i;
+
+	for (i = 0; i < AUDIO_BUFS; i++)
+		if (pa->urb_array[i])
+			usb_kill_urb(pa->urb_array[i]);
+	free_all_urb_generic(pa->urb_array, AUDIO_BUFS);
+	logpm();
+	return 0;
+}
+
+static int snd_pd_hw_capture_free(struct snd_pcm_substream *substream)
+{
+	struct poseidon *p = snd_pcm_substream_chip(substream);
+
+	logpm();
+	audio_buf_free(p);
+	return 0;
+}
+
+static int snd_pd_prepare(struct snd_pcm_substream *substream)
+{
+	return 0;
+}
+
+#define AUDIO_TRAILER_SIZE	(16)
+static inline void handle_audio_data(struct urb *urb, int *period_elapsed)
+{
+	struct poseidon_audio *pa = urb->context;
+	struct snd_pcm_runtime *runtime = pa->capture_pcm_substream->runtime;
+
+	int stride	= runtime->frame_bits >> 3;
+	int len		= urb->actual_length / stride;
+	unsigned char *cp	= urb->transfer_buffer;
+	unsigned int oldptr	= pa->rcv_position;
+
+	if (urb->actual_length == AUDIO_BUF_SIZE - 4)
+		len -= (AUDIO_TRAILER_SIZE / stride);
+
+	/* do the copy */
+	if (oldptr + len >= runtime->buffer_size) {
+		unsigned int cnt = runtime->buffer_size - oldptr;
+
+		memcpy(runtime->dma_area + oldptr * stride, cp, cnt * stride);
+		memcpy(runtime->dma_area, (cp + cnt * stride),
+					(len * stride - cnt * stride));
+	} else
+		memcpy(runtime->dma_area + oldptr * stride, cp, len * stride);
+
+	/* update the statas */
+	snd_pcm_stream_lock(pa->capture_pcm_substream);
+	pa->rcv_position	+= len;
+	if (pa->rcv_position >= runtime->buffer_size)
+		pa->rcv_position -= runtime->buffer_size;
+
+	pa->copied_position += (len);
+	if (pa->copied_position >= runtime->period_size) {
+		pa->copied_position -= runtime->period_size;
+		*period_elapsed = 1;
+	}
+	snd_pcm_stream_unlock(pa->capture_pcm_substream);
+}
+
+static void complete_handler_audio(struct urb *urb)
+{
+	struct poseidon_audio *pa = urb->context;
+	struct snd_pcm_substream *substream = pa->capture_pcm_substream;
+	int    period_elapsed = 0;
+	int    ret;
+
+	if (1 == pa->card_close || pa->capture_stream != STREAM_ON)
+		return;
+
+	if (urb->status != 0) {
+		/*if (urb->status == -ESHUTDOWN)*/
+			return;
+	}
+
+	if (substream) {
+		if (urb->actual_length) {
+			handle_audio_data(urb, &period_elapsed);
+			if (period_elapsed)
+				snd_pcm_period_elapsed(substream);
+		}
+	}
+
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	if (ret < 0)
+		log("audio urb failed (errcod = %i)", ret);
+	return;
+}
+
+static int fire_audio_urb(struct poseidon *p)
+{
+	int i, ret = 0;
+	struct poseidon_audio *pa = &p->audio;
+
+	alloc_bulk_urbs_generic(pa->urb_array, AUDIO_BUFS,
+			p->udev, AUDIO_EP,
+			AUDIO_BUF_SIZE, GFP_ATOMIC,
+			complete_handler_audio, pa);
+
+	for (i = 0; i < AUDIO_BUFS; i++) {
+		ret = usb_submit_urb(pa->urb_array[i], GFP_KERNEL);
+		if (ret)
+			log("urb err : %d", ret);
+	}
+	log();
+	return ret;
+}
+
+static int snd_pd_capture_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct poseidon *p = snd_pcm_substream_chip(substream);
+	struct poseidon_audio *pa = &p->audio;
+
+	if (debug_mode)
+		log("cmd %d, audio stat : %d\n", cmd, pa->capture_stream);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_START:
+		if (pa->capture_stream == STREAM_ON)
+			return 0;
+
+		pa->rcv_position = pa->copied_position = 0;
+		pa->capture_stream = STREAM_ON;
+
+		if (in_hibernation(p))
+			return 0;
+		fire_audio_urb(p);
+		return 0;
+
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+		pa->capture_stream = STREAM_SUSPEND;
+		return 0;
+	case SNDRV_PCM_TRIGGER_STOP:
+		pa->capture_stream = STREAM_OFF;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static snd_pcm_uframes_t
+snd_pd_capture_pointer(struct snd_pcm_substream *substream)
+{
+	struct poseidon *p = snd_pcm_substream_chip(substream);
+	struct poseidon_audio *pa = &p->audio;
+	return pa->rcv_position;
+}
+
+static struct page *snd_pcm_pd_get_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 pcm_capture_ops = {
+	.open      = snd_pd_capture_open,
+	.close     = snd_pd_pcm_close,
+	.ioctl     = snd_pcm_lib_ioctl,
+	.hw_params = snd_pd_hw_capture_params,
+	.hw_free   = snd_pd_hw_capture_free,
+	.prepare   = snd_pd_prepare,
+	.trigger   = snd_pd_capture_trigger,
+	.pointer   = snd_pd_capture_pointer,
+	.page      = snd_pcm_pd_get_page,
+};
+
+#ifdef CONFIG_PM
+int pm_alsa_suspend(struct poseidon *p)
+{
+	logpm(p);
+	audio_buf_free(p);
+	return 0;
+}
+
+int pm_alsa_resume(struct poseidon *p)
+{
+	logpm(p);
+	fire_audio_urb(p);
+	return 0;
+}
+#endif
+
+int poseidon_audio_init(struct poseidon *p)
+{
+	struct poseidon_audio *pa = &p->audio;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	int ret;
+
+	ret = snd_card_create(-1, "Telegent", THIS_MODULE, 0, &card);
+	if (ret != 0)
+		return ret;
+
+	ret = snd_pcm_new(card, "poseidon audio", 0, 0, 1, &pcm);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);
+	pcm->info_flags   = 0;
+	pcm->private_data = p;
+	strcpy(pcm->name, "poseidon audio capture");
+
+	strcpy(card->driver, "ALSA driver");
+	strcpy(card->shortname, "poseidon Audio");
+	strcpy(card->longname, "poseidon ALSA Audio");
+
+	if (snd_card_register(card)) {
+		snd_card_free(card);
+		return -ENOMEM;
+	}
+	pa->card = card;
+	return 0;
+}
+
+int poseidon_audio_free(struct poseidon *p)
+{
+	struct poseidon_audio *pa = &p->audio;
+
+	if (pa->card)
+		snd_card_free(pa->card);
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/pd-common.h linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/pd-common.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/pd-common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/pd-common.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,282 @@
+#ifndef PD_COMMON_H
+#define PD_COMMON_H
+
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/videodev2.h>
+#include <linux/semaphore.h>
+#include <linux/usb.h>
+#include <linux/poll.h>
+#include <media/videobuf-vmalloc.h>
+#include <media/v4l2-device.h>
+
+#include "dvb_frontend.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dmxdev.h"
+
+#define SBUF_NUM	8
+#define MAX_BUFFER_NUM	6
+#define PK_PER_URB	32
+#define ISO_PKT_SIZE	3072
+
+#define POSEIDON_STATE_NONE		(0x0000)
+#define POSEIDON_STATE_ANALOG		(0x0001)
+#define POSEIDON_STATE_FM		(0x0002)
+#define POSEIDON_STATE_DVBT		(0x0004)
+#define POSEIDON_STATE_VBI		(0x0008)
+#define POSEIDON_STATE_DISCONNECT	(0x0080)
+
+#define PM_SUSPEND_DELAY	3
+
+#define V4L_PAL_VBI_LINES	18
+#define V4L_NTSC_VBI_LINES	12
+#define V4L_PAL_VBI_FRAMESIZE	(V4L_PAL_VBI_LINES * 1440 * 2)
+#define V4L_NTSC_VBI_FRAMESIZE	(V4L_NTSC_VBI_LINES * 1440 * 2)
+
+#define TUNER_FREQ_MIN		(45000000)
+#define TUNER_FREQ_MAX		(862000000)
+
+struct vbi_data {
+	struct video_device	*v_dev;
+	struct video_data	*video;
+	struct front_face	*front;
+
+	unsigned int		copied;
+	unsigned int		vbi_size; /* the whole size of two fields */
+	int 			users;
+};
+
+/*
+ * This is the running context of the video, it is useful for
+ * resume()
+ */
+struct running_context {
+	u32		freq;		/* VIDIOC_S_FREQUENCY */
+	int		audio_idx;	/* VIDIOC_S_TUNER    */
+	v4l2_std_id	tvnormid;	/* VIDIOC_S_STD     */
+	int		sig_index;	/* VIDIOC_S_INPUT  */
+	struct v4l2_pix_format pix;	/* VIDIOC_S_FMT   */
+};
+
+struct video_data {
+	/* v4l2 video device */
+	struct video_device	*v_dev;
+
+	/* the working context */
+	struct running_context	context;
+
+	/* for data copy */
+	int		field_count;
+
+	char		*dst;
+	int		lines_copied;
+	int		prev_left;
+
+	int		lines_per_field;
+	int		lines_size;
+
+	/* for communication */
+	u8			endpoint_addr;
+	struct urb 		*urb_array[SBUF_NUM];
+	struct vbi_data		*vbi;
+	struct poseidon 	*pd;
+	struct front_face	*front;
+
+	int			is_streaming;
+	int			users;
+
+	/* for bubble handler */
+	struct work_struct	bubble_work;
+};
+
+enum pcm_stream_state {
+	STREAM_OFF,
+	STREAM_ON,
+	STREAM_SUSPEND,
+};
+
+#define AUDIO_BUFS (3)
+#define CAPTURE_STREAM_EN 1
+struct poseidon_audio {
+	struct urb		*urb_array[AUDIO_BUFS];
+	unsigned int 		copied_position;
+	struct snd_pcm_substream   *capture_pcm_substream;
+
+	unsigned int 		rcv_position;
+	struct	snd_card	*card;
+	int 			card_close;
+
+	int 			users;
+	int			pm_state;
+	enum pcm_stream_state 	capture_stream;
+};
+
+struct radio_data {
+	__u32		fm_freq;
+	int		users;
+	unsigned int	is_radio_streaming;
+	int		pre_emphasis;
+	struct video_device *fm_dev;
+};
+
+#define DVB_SBUF_NUM		4
+#define DVB_URB_BUF_SIZE	0x2000
+struct pd_dvb_adapter {
+	struct dvb_adapter	dvb_adap;
+	struct dvb_frontend	dvb_fe;
+	struct dmxdev		dmxdev;
+	struct dvb_demux	demux;
+
+	atomic_t		users;
+	atomic_t		active_feed;
+
+	/* data transfer */
+	s32			is_streaming;
+	struct urb		*urb_array[DVB_SBUF_NUM];
+	struct poseidon		*pd_device;
+	u8			ep_addr;
+	u8			reserved[3];
+
+	/* data for power resume*/
+	struct dvb_frontend_parameters fe_param;
+
+	/* for channel scanning */
+	int		prev_freq;
+	int		bandwidth;
+	unsigned long	last_jiffies;
+};
+
+struct front_face {
+	/* use this field to distinguish VIDEO and VBI */
+	enum v4l2_buf_type	type;
+
+	/* for host */
+	struct videobuf_queue	q;
+
+	/* the bridge for host and device */
+	struct videobuf_buffer	*curr_frame;
+
+	/* for device */
+	spinlock_t		queue_lock;
+	struct list_head	active;
+	struct poseidon		*pd;
+};
+
+struct poseidon {
+	struct list_head	device_list;
+
+	struct mutex		lock;
+	struct kref		kref;
+
+	/* for V4L2 */
+	struct v4l2_device	v4l2_dev;
+
+	/* hardware info */
+	struct usb_device	*udev;
+	struct usb_interface	*interface;
+	int 			cur_transfer_mode;
+
+	struct video_data	video_data;	/* video */
+	struct vbi_data		vbi_data;	/* vbi	 */
+	struct poseidon_audio	audio;		/* audio (alsa) */
+	struct radio_data	radio_data;	/* FM	 */
+	struct pd_dvb_adapter	dvb_data;	/* DVB	 */
+
+	u32			state;
+	struct file		*file_for_stream; /* the active stream*/
+
+#ifdef CONFIG_PM
+	int (*pm_suspend)(struct poseidon *);
+	int (*pm_resume)(struct poseidon *);
+	pm_message_t		msg;
+
+	struct work_struct	pm_work;
+	u8			portnum;
+#endif
+};
+
+struct poseidon_format {
+	char 	*name;
+	int	fourcc;		 /* video4linux 2	  */
+	int	depth;		 /* bit/pixel		  */
+	int	flags;
+};
+
+struct poseidon_tvnorm {
+	v4l2_std_id	v4l2_id;
+	char		name[12];
+	u32		tlg_tvnorm;
+};
+
+/* video */
+int pd_video_init(struct poseidon *);
+void pd_video_exit(struct poseidon *);
+int stop_all_video_stream(struct poseidon *);
+
+/* alsa audio */
+int poseidon_audio_init(struct poseidon *);
+int poseidon_audio_free(struct poseidon *);
+#ifdef CONFIG_PM
+int pm_alsa_suspend(struct poseidon *);
+int pm_alsa_resume(struct poseidon *);
+#endif
+
+/* dvb */
+int pd_dvb_usb_device_init(struct poseidon *);
+void pd_dvb_usb_device_exit(struct poseidon *);
+void pd_dvb_usb_device_cleanup(struct poseidon *);
+int pd_dvb_get_adapter_num(struct pd_dvb_adapter *);
+void dvb_stop_streaming(struct pd_dvb_adapter *);
+
+/* FM */
+int poseidon_fm_init(struct poseidon *);
+int poseidon_fm_exit(struct poseidon *);
+struct video_device *vdev_init(struct poseidon *, struct video_device *);
+
+/* vendor command ops */
+int send_set_req(struct poseidon*, u8, s32, s32*);
+int send_get_req(struct poseidon*, u8, s32, void*, s32*, s32);
+s32 set_tuner_mode(struct poseidon*, unsigned char);
+
+/* bulk urb alloc/free */
+int alloc_bulk_urbs_generic(struct urb **urb_array, int num,
+			struct usb_device *udev, u8 ep_addr,
+			int buf_size, gfp_t gfp_flags,
+			usb_complete_t complete_fn, void *context);
+void free_all_urb_generic(struct urb **urb_array, int num);
+
+/* misc */
+void poseidon_delete(struct kref *kref);
+void destroy_video_device(struct video_device **v_dev);
+extern int debug_mode;
+void set_debug_mode(struct video_device *vfd, int debug_mode);
+
+#ifdef CONFIG_PM
+#define in_hibernation(pd) (pd->msg.event == PM_EVENT_FREEZE)
+#else
+#define in_hibernation(pd) (0)
+#endif
+#define get_pm_count(p) (atomic_read(&(p)->interface->pm_usage_cnt))
+
+#define log(a, ...) printk(KERN_DEBUG "\t[ %s : %.3d ] "a"\n", \
+				__func__, __LINE__,  ## __VA_ARGS__)
+
+/* for power management */
+#define logpm(pd) do {\
+			if (debug_mode & 0x10)\
+				log();\
+		} while (0)
+
+#define logs(f) do { \
+			if ((debug_mode & 0x4) && \
+				(f)->type == V4L2_BUF_TYPE_VBI_CAPTURE) \
+					log("type : VBI");\
+								\
+			if ((debug_mode & 0x8) && \
+				(f)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) \
+					log("type : VIDEO");\
+		} while (0)
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/pd-dvb.c linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/pd-dvb.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/pd-dvb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/pd-dvb.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,594 @@
+#include "pd-common.h"
+#include <linux/kernel.h>
+#include <linux/usb.h>
+#include <linux/dvb/dmx.h>
+#include <linux/delay.h>
+#include <linux/gfp.h>
+
+#include "vendorcmds.h"
+#include <linux/sched.h>
+#include <asm/atomic.h>
+
+static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb);
+
+static int dvb_bandwidth[][2] = {
+	{ TLG_BW_8, BANDWIDTH_8_MHZ },
+	{ TLG_BW_7, BANDWIDTH_7_MHZ },
+	{ TLG_BW_6, BANDWIDTH_6_MHZ }
+};
+static int dvb_bandwidth_length = ARRAY_SIZE(dvb_bandwidth);
+
+static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb);
+static int poseidon_check_mode_dvbt(struct poseidon *pd)
+{
+	s32 ret = 0, cmd_status = 0;
+
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(HZ/4);
+
+	ret = usb_set_interface(pd->udev, 0, BULK_ALTERNATE_IFACE);
+	if (ret != 0)
+		return ret;
+
+	ret = set_tuner_mode(pd, TLG_MODE_CAPS_DVB_T);
+	if (ret)
+		return ret;
+
+	/* signal source */
+	ret = send_set_req(pd, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &cmd_status);
+	if (ret|cmd_status)
+		return ret;
+
+	return 0;
+}
+
+/* acquire :
+ * 	1 == open
+ * 	0 == release
+ */
+static int poseidon_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
+{
+	struct poseidon *pd = fe->demodulator_priv;
+	struct pd_dvb_adapter *pd_dvb;
+	int ret = 0;
+
+	if (!pd)
+		return -ENODEV;
+
+	pd_dvb = container_of(fe, struct pd_dvb_adapter, dvb_fe);
+	if (acquire) {
+		mutex_lock(&pd->lock);
+		if (pd->state & POSEIDON_STATE_DISCONNECT) {
+			ret = -ENODEV;
+			goto open_out;
+		}
+
+		if (pd->state && !(pd->state & POSEIDON_STATE_DVBT)) {
+			ret = -EBUSY;
+			goto open_out;
+		}
+
+		usb_autopm_get_interface(pd->interface);
+		if (0 == pd->state) {
+			ret = poseidon_check_mode_dvbt(pd);
+			if (ret < 0) {
+				usb_autopm_put_interface(pd->interface);
+				goto open_out;
+			}
+			pd->state |= POSEIDON_STATE_DVBT;
+			pd_dvb->bandwidth = 0;
+			pd_dvb->prev_freq = 0;
+		}
+		atomic_inc(&pd_dvb->users);
+		kref_get(&pd->kref);
+open_out:
+		mutex_unlock(&pd->lock);
+	} else {
+		dvb_stop_streaming(pd_dvb);
+
+		if (atomic_dec_and_test(&pd_dvb->users)) {
+			mutex_lock(&pd->lock);
+			pd->state &= ~POSEIDON_STATE_DVBT;
+			mutex_unlock(&pd->lock);
+		}
+		kref_put(&pd->kref, poseidon_delete);
+		usb_autopm_put_interface(pd->interface);
+	}
+	return ret;
+}
+
+static void poseidon_fe_release(struct dvb_frontend *fe)
+{
+	struct poseidon *pd = fe->demodulator_priv;
+
+#ifdef CONFIG_PM
+	pd->pm_suspend = NULL;
+	pd->pm_resume  = NULL;
+#endif
+}
+
+static s32 poseidon_fe_sleep(struct dvb_frontend *fe)
+{
+	return 0;
+}
+
+/*
+ * return true if we can satisfy the conditions, else return false.
+ */
+static bool check_scan_ok(__u32 freq, int bandwidth,
+			struct pd_dvb_adapter *adapter)
+{
+	if (bandwidth < 0)
+		return false;
+
+	if (adapter->prev_freq == freq
+		&& adapter->bandwidth == bandwidth) {
+		long nl = jiffies - adapter->last_jiffies;
+		unsigned int msec ;
+
+		msec = jiffies_to_msecs(abs(nl));
+		return msec > 15000 ? true : false;
+	}
+	return true;
+}
+
+/*
+ * Check if the firmware delays too long for an invalid frequency.
+ */
+static int fw_delay_overflow(struct pd_dvb_adapter *adapter)
+{
+	long nl = jiffies - adapter->last_jiffies;
+	unsigned int msec ;
+
+	msec = jiffies_to_msecs(abs(nl));
+	return msec > 800 ? true : false;
+}
+
+static int poseidon_set_fe(struct dvb_frontend *fe,
+			struct dvb_frontend_parameters *fep)
+{
+	s32 ret = 0, cmd_status = 0;
+	s32 i, bandwidth = -1;
+	struct poseidon *pd = fe->demodulator_priv;
+	struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
+
+	if (in_hibernation(pd))
+		return -EBUSY;
+
+	mutex_lock(&pd->lock);
+	for (i = 0; i < dvb_bandwidth_length; i++)
+		if (fep->u.ofdm.bandwidth == dvb_bandwidth[i][1])
+			bandwidth = dvb_bandwidth[i][0];
+
+	if (check_scan_ok(fep->frequency, bandwidth, pd_dvb)) {
+		ret = send_set_req(pd, TUNE_FREQ_SELECT,
+					fep->frequency / 1000, &cmd_status);
+		if (ret | cmd_status) {
+			log("error line");
+			goto front_out;
+		}
+
+		ret = send_set_req(pd, DVBT_BANDW_SEL,
+						bandwidth, &cmd_status);
+		if (ret | cmd_status) {
+			log("error line");
+			goto front_out;
+		}
+
+		ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
+		if (ret | cmd_status) {
+			log("error line");
+			goto front_out;
+		}
+
+		/* save the context for future */
+		memcpy(&pd_dvb->fe_param, fep, sizeof(*fep));
+		pd_dvb->bandwidth = bandwidth;
+		pd_dvb->prev_freq = fep->frequency;
+		pd_dvb->last_jiffies = jiffies;
+	}
+front_out:
+	mutex_unlock(&pd->lock);
+	return ret;
+}
+
+#ifdef CONFIG_PM
+static int pm_dvb_suspend(struct poseidon *pd)
+{
+	struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
+	dvb_stop_streaming(pd_dvb);
+	dvb_urb_cleanup(pd_dvb);
+	msleep(500);
+	return 0;
+}
+
+static int pm_dvb_resume(struct poseidon *pd)
+{
+	struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
+
+	poseidon_check_mode_dvbt(pd);
+	msleep(300);
+	poseidon_set_fe(&pd_dvb->dvb_fe, &pd_dvb->fe_param);
+
+	dvb_start_streaming(pd_dvb);
+	return 0;
+}
+#endif
+
+static s32 poseidon_fe_init(struct dvb_frontend *fe)
+{
+	struct poseidon *pd = fe->demodulator_priv;
+	struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
+
+#ifdef CONFIG_PM
+	pd->pm_suspend = pm_dvb_suspend;
+	pd->pm_resume  = pm_dvb_resume;
+#endif
+	memset(&pd_dvb->fe_param, 0,
+			sizeof(struct dvb_frontend_parameters));
+	return 0;
+}
+
+static int poseidon_get_fe(struct dvb_frontend *fe,
+			struct dvb_frontend_parameters *fep)
+{
+	struct poseidon *pd = fe->demodulator_priv;
+	struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
+
+	memcpy(fep, &pd_dvb->fe_param, sizeof(*fep));
+	return 0;
+}
+
+static int poseidon_fe_get_tune_settings(struct dvb_frontend *fe,
+				struct dvb_frontend_tune_settings *tune)
+{
+	tune->min_delay_ms = 1000;
+	return 0;
+}
+
+static int poseidon_read_status(struct dvb_frontend *fe, fe_status_t *stat)
+{
+	struct poseidon *pd = fe->demodulator_priv;
+	s32 ret = -1, cmd_status;
+	struct tuner_dtv_sig_stat_s status = {};
+
+	if (in_hibernation(pd))
+		return -EBUSY;
+	mutex_lock(&pd->lock);
+
+	ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T,
+				&status, &cmd_status, sizeof(status));
+	if (ret | cmd_status) {
+		log("get tuner status error");
+		goto out;
+	}
+
+	if (debug_mode)
+		log("P : %d, L %d, LB :%d", status.sig_present,
+			status.sig_locked, status.sig_lock_busy);
+
+	if (status.sig_lock_busy) {
+		goto out;
+	} else if (status.sig_present || status.sig_locked) {
+		*stat |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER
+				| FE_HAS_SYNC | FE_HAS_VITERBI;
+	} else {
+		if (fw_delay_overflow(&pd->dvb_data))
+			*stat |= FE_TIMEDOUT;
+	}
+out:
+	mutex_unlock(&pd->lock);
+	return ret;
+}
+
+static int poseidon_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	struct poseidon *pd = fe->demodulator_priv;
+	struct tuner_ber_rate_s tlg_ber = {};
+	s32 ret = -1, cmd_status;
+
+	mutex_lock(&pd->lock);
+	ret = send_get_req(pd, TUNER_BER_RATE, 0,
+				&tlg_ber, &cmd_status, sizeof(tlg_ber));
+	if (ret | cmd_status)
+		goto out;
+	*ber = tlg_ber.ber_rate;
+out:
+	mutex_unlock(&pd->lock);
+	return ret;
+}
+
+static s32 poseidon_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+	struct poseidon *pd = fe->demodulator_priv;
+	struct tuner_dtv_sig_stat_s status = {};
+	s32 ret = 0, cmd_status;
+
+	mutex_lock(&pd->lock);
+	ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T,
+				&status, &cmd_status, sizeof(status));
+	if (ret | cmd_status)
+		goto out;
+	if ((status.sig_present || status.sig_locked) && !status.sig_strength)
+		*strength = 0xFFFF;
+	else
+		*strength = status.sig_strength;
+out:
+	mutex_unlock(&pd->lock);
+	return ret;
+}
+
+static int poseidon_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	return 0;
+}
+
+static int poseidon_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
+{
+	*unc = 0;
+	return 0;
+}
+
+static struct dvb_frontend_ops poseidon_frontend_ops = {
+	.info = {
+		.name		= "Poseidon DVB-T",
+		.type		= FE_OFDM,
+		.frequency_min	= 174000000,
+		.frequency_max  = 862000000,
+		.frequency_stepsize	  = 62500,/* FIXME */
+		.caps = FE_CAN_INVERSION_AUTO |
+			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+			FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+			FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+			FE_CAN_GUARD_INTERVAL_AUTO |
+			FE_CAN_RECOVER |
+			FE_CAN_HIERARCHY_AUTO,
+	},
+
+	.release = poseidon_fe_release,
+
+	.init = poseidon_fe_init,
+	.sleep = poseidon_fe_sleep,
+
+	.set_frontend = poseidon_set_fe,
+	.get_frontend = poseidon_get_fe,
+	.get_tune_settings = poseidon_fe_get_tune_settings,
+
+	.read_status	= poseidon_read_status,
+	.read_ber	= poseidon_read_ber,
+	.read_signal_strength = poseidon_read_signal_strength,
+	.read_snr	= poseidon_read_snr,
+	.read_ucblocks	= poseidon_read_unc_blocks,
+
+	.ts_bus_ctrl = poseidon_ts_bus_ctrl,
+};
+
+static void dvb_urb_irq(struct urb *urb)
+{
+	struct pd_dvb_adapter *pd_dvb = urb->context;
+	int len = urb->transfer_buffer_length;
+	struct dvb_demux *demux = &pd_dvb->demux;
+	s32 ret;
+
+	if (!pd_dvb->is_streaming || urb->status) {
+		if (urb->status == -EPROTO)
+			goto resend;
+		return;
+	}
+
+	if (urb->actual_length == len)
+		dvb_dmx_swfilter(demux, urb->transfer_buffer, len);
+	else if (urb->actual_length == len - 4) {
+		int offset;
+		u8 *buf = urb->transfer_buffer;
+
+		/*
+		 * The packet size is 512,
+		 * last packet contains 456 bytes tsp data
+		 */
+		for (offset = 456; offset < len; offset += 512) {
+			if (!strncmp(buf + offset, "DVHS", 4)) {
+				dvb_dmx_swfilter(demux, buf, offset);
+				if (len > offset + 52 + 4) {
+					/*16 bytes trailer + 36 bytes padding */
+					buf += offset + 52;
+					len -= offset + 52 + 4;
+					dvb_dmx_swfilter(demux, buf, len);
+				}
+				break;
+			}
+		}
+	}
+
+resend:
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	if (ret)
+		log(" usb_submit_urb failed: error %d", ret);
+}
+
+static int dvb_urb_init(struct pd_dvb_adapter *pd_dvb)
+{
+	if (pd_dvb->urb_array[0])
+		return 0;
+
+	alloc_bulk_urbs_generic(pd_dvb->urb_array, DVB_SBUF_NUM,
+			pd_dvb->pd_device->udev, pd_dvb->ep_addr,
+			DVB_URB_BUF_SIZE, GFP_KERNEL,
+			dvb_urb_irq, pd_dvb);
+	return 0;
+}
+
+static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb)
+{
+	free_all_urb_generic(pd_dvb->urb_array, DVB_SBUF_NUM);
+}
+
+static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb)
+{
+	struct poseidon *pd = pd_dvb->pd_device;
+	int ret = 0;
+
+	if (pd->state & POSEIDON_STATE_DISCONNECT)
+		return -ENODEV;
+
+	mutex_lock(&pd->lock);
+	if (!pd_dvb->is_streaming) {
+		s32 i, cmd_status = 0;
+		/*
+		 * Once upon a time, there was a difficult bug lying here.
+		 * ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
+		 */
+
+		ret = send_set_req(pd, PLAY_SERVICE, 1, &cmd_status);
+		if (ret | cmd_status)
+			goto out;
+
+		ret = dvb_urb_init(pd_dvb);
+		if (ret < 0)
+			goto out;
+
+		pd_dvb->is_streaming = 1;
+		for (i = 0; i < DVB_SBUF_NUM; i++) {
+			ret = usb_submit_urb(pd_dvb->urb_array[i],
+						       GFP_KERNEL);
+			if (ret) {
+				log(" submit urb error %d", ret);
+				goto out;
+			}
+		}
+	}
+out:
+	mutex_unlock(&pd->lock);
+	return ret;
+}
+
+void dvb_stop_streaming(struct pd_dvb_adapter *pd_dvb)
+{
+	struct poseidon *pd = pd_dvb->pd_device;
+
+	mutex_lock(&pd->lock);
+	if (pd_dvb->is_streaming) {
+		s32 i, ret, cmd_status = 0;
+
+		pd_dvb->is_streaming = 0;
+
+		for (i = 0; i < DVB_SBUF_NUM; i++)
+			if (pd_dvb->urb_array[i])
+				usb_kill_urb(pd_dvb->urb_array[i]);
+
+		ret = send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP,
+					&cmd_status);
+		if (ret | cmd_status)
+			log("error");
+	}
+	mutex_unlock(&pd->lock);
+}
+
+static int pd_start_feed(struct dvb_demux_feed *feed)
+{
+	struct pd_dvb_adapter *pd_dvb = feed->demux->priv;
+	int ret = 0;
+
+	if (!pd_dvb)
+		return -1;
+	if (atomic_inc_return(&pd_dvb->active_feed) == 1)
+		ret = dvb_start_streaming(pd_dvb);
+	return ret;
+}
+
+static int pd_stop_feed(struct dvb_demux_feed *feed)
+{
+	struct pd_dvb_adapter *pd_dvb = feed->demux->priv;
+
+	if (!pd_dvb)
+		return -1;
+	if (atomic_dec_and_test(&pd_dvb->active_feed))
+		dvb_stop_streaming(pd_dvb);
+	return 0;
+}
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+int pd_dvb_usb_device_init(struct poseidon *pd)
+{
+	struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
+	struct dvb_demux *dvbdemux;
+	int ret = 0;
+
+	pd_dvb->ep_addr = 0x82;
+	atomic_set(&pd_dvb->users, 0);
+	atomic_set(&pd_dvb->active_feed, 0);
+	pd_dvb->pd_device = pd;
+
+	ret = dvb_register_adapter(&pd_dvb->dvb_adap,
+				"Poseidon dvbt adapter",
+				THIS_MODULE,
+				NULL /* for hibernation correctly*/,
+				adapter_nr);
+	if (ret < 0)
+		goto error1;
+
+	/* register frontend */
+	pd_dvb->dvb_fe.demodulator_priv = pd;
+	memcpy(&pd_dvb->dvb_fe.ops, &poseidon_frontend_ops,
+			sizeof(struct dvb_frontend_ops));
+	ret = dvb_register_frontend(&pd_dvb->dvb_adap, &pd_dvb->dvb_fe);
+	if (ret < 0)
+		goto error2;
+
+	/* register demux device */
+	dvbdemux = &pd_dvb->demux;
+	dvbdemux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+	dvbdemux->priv = pd_dvb;
+	dvbdemux->feednum = dvbdemux->filternum = 64;
+	dvbdemux->start_feed = pd_start_feed;
+	dvbdemux->stop_feed = pd_stop_feed;
+	dvbdemux->write_to_decoder = NULL;
+
+	ret = dvb_dmx_init(dvbdemux);
+	if (ret < 0)
+		goto error3;
+
+	pd_dvb->dmxdev.filternum = pd_dvb->demux.filternum;
+	pd_dvb->dmxdev.demux = &pd_dvb->demux.dmx;
+	pd_dvb->dmxdev.capabilities = 0;
+
+	ret = dvb_dmxdev_init(&pd_dvb->dmxdev, &pd_dvb->dvb_adap);
+	if (ret < 0)
+		goto error3;
+	return 0;
+
+error3:
+	dvb_unregister_frontend(&pd_dvb->dvb_fe);
+error2:
+	dvb_unregister_adapter(&pd_dvb->dvb_adap);
+error1:
+	return ret;
+}
+
+void pd_dvb_usb_device_exit(struct poseidon *pd)
+{
+	struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
+
+	while (atomic_read(&pd_dvb->users) != 0
+		|| atomic_read(&pd_dvb->active_feed) != 0) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ);
+	}
+	dvb_dmxdev_release(&pd_dvb->dmxdev);
+	dvb_unregister_frontend(&pd_dvb->dvb_fe);
+	dvb_unregister_adapter(&pd_dvb->dvb_adap);
+	pd_dvb_usb_device_cleanup(pd);
+}
+
+void pd_dvb_usb_device_cleanup(struct poseidon *pd)
+{
+	struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
+
+	dvb_urb_cleanup(pd_dvb);
+}
+
+int pd_dvb_get_adapter_num(struct pd_dvb_adapter *pd_dvb)
+{
+	return pd_dvb->dvb_adap.num;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/pd-main.c linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/pd-main.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/pd-main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/pd-main.c	2013-05-03 09:46:45.000000000 -0400
@@ -0,0 +1,539 @@
+/*
+ * device driver for Telegent tlg2300 based TV cards
+ *
+ * Author :
+ * 	Kang Yong	<kangyong@telegent.com>
+ * 	Zhang Xiaobing	<xbzhang@telegent.com>
+ * 	Huang Shijie	<zyziii@telegent.com> or <shijie8@gmail.com>
+ *
+ *	(c) 2009 Telegent Systems
+ *	(c) 2010 Telegent Systems
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the 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/version.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kref.h>
+#include <linux/suspend.h>
+#include <linux/usb/quirks.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/firmware.h>
+#include <linux/smp_lock.h>
+
+#include "vendorcmds.h"
+#include "pd-common.h"
+
+#define VENDOR_ID	0x1B24
+#define PRODUCT_ID	0x4001
+static struct usb_device_id id_table[] = {
+	{ USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ID, PRODUCT_ID, 255, 1, 0) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ID, PRODUCT_ID, 255, 1, 1) },
+	{ },
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+int debug_mode;
+module_param(debug_mode, int, 0644);
+MODULE_PARM_DESC(debug_mode, "0 = disable, 1 = enable, 2 = verbose");
+
+const char *firmware_name = "/*(DEBLOBBED)*/";
+struct usb_driver poseidon_driver;
+static LIST_HEAD(pd_device_list);
+
+/*
+ * send set request to USB firmware.
+ */
+s32 send_set_req(struct poseidon *pd, u8 cmdid, s32 param, s32 *cmd_status)
+{
+	s32 ret;
+	s8  data[32] = {};
+	u16 lower_16, upper_16;
+
+	if (pd->state & POSEIDON_STATE_DISCONNECT)
+		return -ENODEV;
+
+	mdelay(30);
+
+	if (param == 0) {
+		upper_16 = lower_16 = 0;
+	} else {
+		/* send 32 bit param as  two 16 bit param,little endian */
+		lower_16 = (unsigned short)(param & 0xffff);
+		upper_16 = (unsigned short)((param >> 16) & 0xffff);
+	}
+	ret = usb_control_msg(pd->udev,
+			 usb_rcvctrlpipe(pd->udev, 0),
+			 REQ_SET_CMD | cmdid,
+			 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			 lower_16,
+			 upper_16,
+			 &data,
+			 sizeof(*cmd_status),
+			 USB_CTRL_GET_TIMEOUT);
+
+	if (!ret) {
+		return -ENXIO;
+	} else {
+		/*  1st 4 bytes into cmd_status   */
+		memcpy((char *)cmd_status, &(data[0]), sizeof(*cmd_status));
+	}
+	return 0;
+}
+
+/*
+ * send get request to Poseidon firmware.
+ */
+s32 send_get_req(struct poseidon *pd, u8 cmdid, s32 param,
+			void *buf, s32 *cmd_status, s32 datalen)
+{
+	s32 ret;
+	s8 data[128] = {};
+	u16 lower_16, upper_16;
+
+	if (pd->state & POSEIDON_STATE_DISCONNECT)
+		return -ENODEV;
+
+	mdelay(30);
+	if (param == 0) {
+		upper_16 = lower_16 = 0;
+	} else {
+		/*send 32 bit param as two 16 bit param, little endian */
+		lower_16 = (unsigned short)(param & 0xffff);
+		upper_16 = (unsigned short)((param >> 16) & 0xffff);
+	}
+	ret = usb_control_msg(pd->udev,
+			 usb_rcvctrlpipe(pd->udev, 0),
+			 REQ_GET_CMD | cmdid,
+			 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			 lower_16,
+			 upper_16,
+			 &data,
+			 (datalen + sizeof(*cmd_status)),
+			 USB_CTRL_GET_TIMEOUT);
+
+	if (ret < 0) {
+		return -ENXIO;
+	} else {
+		/* 1st 4 bytes into cmd_status, remaining data into cmd_data */
+		memcpy((char *)cmd_status, &data[0], sizeof(*cmd_status));
+		memcpy((char *)buf, &data[sizeof(*cmd_status)], datalen);
+	}
+	return 0;
+}
+
+static int pm_notifier_block(struct notifier_block *nb,
+				unsigned long event, void *dummy)
+{
+	struct poseidon *pd = NULL;
+	struct list_head *node, *next;
+
+	switch (event) {
+	case PM_POST_HIBERNATION:
+		list_for_each_safe(node, next, &pd_device_list) {
+			struct usb_device *udev;
+			struct usb_interface *iface;
+			int rc = 0;
+
+			pd = container_of(node, struct poseidon, device_list);
+			udev = pd->udev;
+			iface = pd->interface;
+
+			/* It will cause the system to reload the firmware */
+			rc = usb_lock_device_for_reset(udev, iface);
+			if (rc >= 0) {
+				usb_reset_device(udev);
+				usb_unlock_device(udev);
+			}
+		}
+		break;
+	default:
+		break;
+	}
+	log("event :%ld\n", event);
+	return 0;
+}
+
+static struct notifier_block pm_notifer = {
+	.notifier_call = pm_notifier_block,
+};
+
+int set_tuner_mode(struct poseidon *pd, unsigned char mode)
+{
+	s32 ret, cmd_status;
+
+	if (pd->state & POSEIDON_STATE_DISCONNECT)
+		return -ENODEV;
+
+	ret = send_set_req(pd, TUNE_MODE_SELECT, mode, &cmd_status);
+	if (ret || cmd_status)
+		return -ENXIO;
+	return 0;
+}
+
+void poseidon_delete(struct kref *kref)
+{
+	struct poseidon *pd = container_of(kref, struct poseidon, kref);
+
+	if (!pd)
+		return;
+	list_del_init(&pd->device_list);
+
+	pd_dvb_usb_device_cleanup(pd);
+	/* clean_audio_data(&pd->audio_data);*/
+
+	if (pd->udev) {
+		usb_put_dev(pd->udev);
+		pd->udev = NULL;
+	}
+	if (pd->interface) {
+		usb_put_intf(pd->interface);
+		pd->interface = NULL;
+	}
+	kfree(pd);
+	log();
+}
+
+static int firmware_download(struct usb_device *udev)
+{
+	int ret = 0, actual_length;
+	const struct firmware *fw = NULL;
+	void *fwbuf = NULL;
+	size_t fwlength = 0, offset;
+	size_t max_packet_size;
+
+	ret = reject_firmware(&fw, firmware_name, &udev->dev);
+	if (ret) {
+		log("download err : %d", ret);
+		return ret;
+	}
+
+	fwlength = fw->size;
+
+	fwbuf = kzalloc(fwlength, GFP_KERNEL);
+	if (!fwbuf) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	memcpy(fwbuf, fw->data, fwlength);
+
+	max_packet_size = udev->ep_out[0x1]->desc.wMaxPacketSize;
+	log("\t\t download size : %d", (int)max_packet_size);
+
+	for (offset = 0; offset < fwlength; offset += max_packet_size) {
+		actual_length = 0;
+		ret = usb_bulk_msg(udev,
+				usb_sndbulkpipe(udev, 0x01), /* ep 1 */
+				fwbuf + offset,
+				min(max_packet_size, fwlength - offset),
+				&actual_length,
+				HZ * 10);
+		if (ret)
+			break;
+	}
+	kfree(fwbuf);
+out:
+	release_firmware(fw);
+	return ret;
+}
+
+static inline struct poseidon *get_pd(struct usb_interface *intf)
+{
+	return usb_get_intfdata(intf);
+}
+
+#ifdef CONFIG_PM
+/* one-to-one map : poseidon{} <----> usb_device{}'s port */
+static inline void set_map_flags(struct poseidon *pd, struct usb_device *udev)
+{
+	pd->portnum = udev->portnum;
+}
+
+static inline int get_autopm_ref(struct poseidon *pd)
+{
+	return  pd->video_data.users + pd->vbi_data.users + pd->audio.users
+		+ atomic_read(&pd->dvb_data.users) + pd->radio_data.users;
+}
+
+/* fixup something for poseidon */
+static inline struct poseidon *fixup(struct poseidon *pd)
+{
+	int count;
+
+	/* old udev and interface have gone, so put back reference . */
+	count = get_autopm_ref(pd);
+	log("count : %d, ref count : %d", count, get_pm_count(pd));
+	while (count--)
+		usb_autopm_put_interface(pd->interface);
+	/*usb_autopm_set_interface(pd->interface); */
+
+	usb_put_dev(pd->udev);
+	usb_put_intf(pd->interface);
+	log("event : %d\n", pd->msg.event);
+	return pd;
+}
+
+static struct poseidon *find_old_poseidon(struct usb_device *udev)
+{
+	struct poseidon *pd;
+
+	list_for_each_entry(pd, &pd_device_list, device_list) {
+		if (pd->portnum == udev->portnum && in_hibernation(pd))
+			return fixup(pd);
+	}
+	return NULL;
+}
+
+/* Is the card working now ? */
+static inline int is_working(struct poseidon *pd)
+{
+	return get_pm_count(pd) > 0;
+}
+
+static int poseidon_suspend(struct usb_interface *intf, pm_message_t msg)
+{
+	struct poseidon *pd = get_pd(intf);
+
+	if (!pd)
+		return 0;
+	if (!is_working(pd)) {
+		if (get_pm_count(pd) <= 0 && !in_hibernation(pd)) {
+			pd->msg.event = PM_EVENT_AUTO_SUSPEND;
+			pd->pm_resume = NULL; /*  a good guard */
+			printk(KERN_DEBUG "\n\t+ TLG2300 auto suspend +\n\n");
+		}
+		return 0;
+	}
+	pd->msg = msg; /* save it here */
+	logpm(pd);
+	return pd->pm_suspend ? pd->pm_suspend(pd) : 0;
+}
+
+static int poseidon_resume(struct usb_interface *intf)
+{
+	struct poseidon *pd = get_pd(intf);
+
+	if (!pd)
+		return 0;
+	printk(KERN_DEBUG "\n\t ++ TLG2300 resume ++\n\n");
+
+	if (!is_working(pd)) {
+		if (PM_EVENT_AUTO_SUSPEND == pd->msg.event)
+			pd->msg = PMSG_ON;
+		return 0;
+	}
+	if (in_hibernation(pd)) {
+		logpm(pd);
+		return 0;
+	}
+	logpm(pd);
+	return pd->pm_resume ? pd->pm_resume(pd) : 0;
+}
+
+static void hibernation_resume(struct work_struct *w)
+{
+	struct poseidon *pd = container_of(w, struct poseidon, pm_work);
+	int count;
+
+	pd->msg.event = 0; /* clear it here */
+	pd->state &= ~POSEIDON_STATE_DISCONNECT;
+
+	/* set the new interface's reference */
+	count = get_autopm_ref(pd);
+	while (count--)
+		usb_autopm_get_interface(pd->interface);
+
+	/* resume the context */
+	logpm(pd);
+	if (pd->pm_resume)
+		pd->pm_resume(pd);
+}
+#else /* CONFIG_PM is not enabled: */
+static inline struct poseidon *find_old_poseidon(struct usb_device *udev)
+{
+	return NULL;
+}
+
+static inline void set_map_flags(struct poseidon *pd, struct usb_device *udev)
+{
+}
+#endif
+
+static bool check_firmware(struct usb_device *udev, int *down_firmware)
+{
+	void *buf;
+	int ret;
+	struct cmd_firmware_vers_s *cmd_firm;
+
+	buf = kzalloc(sizeof(*cmd_firm) + sizeof(u32), GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	ret = usb_control_msg(udev,
+			 usb_rcvctrlpipe(udev, 0),
+			 REQ_GET_CMD | GET_FW_ID,
+			 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			 0,
+			 0,
+			 buf,
+			 sizeof(*cmd_firm) + sizeof(u32),
+			 USB_CTRL_GET_TIMEOUT);
+	kfree(buf);
+
+	if (ret < 0) {
+		*down_firmware = 1;
+		return firmware_download(udev);
+	}
+	return ret;
+}
+
+static int poseidon_probe(struct usb_interface *interface,
+				const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(interface);
+	struct poseidon *pd = NULL;
+	int ret = 0;
+	int new_one = 0;
+
+	/* download firmware */
+	check_firmware(udev, &ret);
+	if (ret)
+		return 0;
+
+	/* Do I recovery from the hibernate ? */
+	pd = find_old_poseidon(udev);
+	if (!pd) {
+		pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+		if (!pd)
+			return -ENOMEM;
+		kref_init(&pd->kref);
+		set_map_flags(pd, udev);
+		new_one = 1;
+	}
+
+	pd->udev	= usb_get_dev(udev);
+	pd->interface	= usb_get_intf(interface);
+	usb_set_intfdata(interface, pd);
+
+	if (new_one) {
+		struct device *dev = &interface->dev;
+
+		logpm(pd);
+		mutex_init(&pd->lock);
+
+		/* register v4l2 device */
+		snprintf(pd->v4l2_dev.name, sizeof(pd->v4l2_dev.name), "%s %s",
+			dev->driver->name, dev_name(dev));
+		ret = v4l2_device_register(NULL, &pd->v4l2_dev);
+
+		/* register devices in directory /dev */
+		ret = pd_video_init(pd);
+		poseidon_audio_init(pd);
+		poseidon_fm_init(pd);
+		pd_dvb_usb_device_init(pd);
+
+		INIT_LIST_HEAD(&pd->device_list);
+		list_add_tail(&pd->device_list, &pd_device_list);
+	}
+
+	device_init_wakeup(&udev->dev, 1);
+#ifdef CONFIG_PM
+	pd->udev->autosuspend_disabled = 0;
+	pd->udev->autosuspend_delay = HZ * PM_SUSPEND_DELAY;
+
+	if (in_hibernation(pd)) {
+		INIT_WORK(&pd->pm_work, hibernation_resume);
+		schedule_work(&pd->pm_work);
+	}
+#endif
+	return 0;
+}
+
+static void poseidon_disconnect(struct usb_interface *interface)
+{
+	struct poseidon *pd = get_pd(interface);
+
+	if (!pd)
+		return;
+	logpm(pd);
+	if (in_hibernation(pd))
+		return;
+
+	mutex_lock(&pd->lock);
+	pd->state |= POSEIDON_STATE_DISCONNECT;
+	mutex_unlock(&pd->lock);
+
+	/* stop urb transferring */
+	stop_all_video_stream(pd);
+	dvb_stop_streaming(&pd->dvb_data);
+
+	/*unregister v4l2 device */
+	v4l2_device_unregister(&pd->v4l2_dev);
+
+	lock_kernel();
+	{
+		pd_dvb_usb_device_exit(pd);
+		poseidon_fm_exit(pd);
+
+		poseidon_audio_free(pd);
+		pd_video_exit(pd);
+	}
+	unlock_kernel();
+
+	usb_set_intfdata(interface, NULL);
+	kref_put(&pd->kref, poseidon_delete);
+}
+
+struct usb_driver poseidon_driver = {
+	.name		= "poseidon",
+	.probe		= poseidon_probe,
+	.disconnect	= poseidon_disconnect,
+	.id_table	= id_table,
+#ifdef CONFIG_PM
+	.suspend	= poseidon_suspend,
+	.resume		= poseidon_resume,
+#endif
+	.supports_autosuspend = 1,
+};
+
+static int __init poseidon_init(void)
+{
+	int ret;
+
+	ret = usb_register(&poseidon_driver);
+	if (ret)
+		return ret;
+	register_pm_notifier(&pm_notifer);
+	return ret;
+}
+
+static void __exit poseidon_exit(void)
+{
+	log();
+	unregister_pm_notifier(&pm_notifer);
+	usb_deregister(&poseidon_driver);
+}
+
+module_init(poseidon_init);
+module_exit(poseidon_exit);
+
+MODULE_AUTHOR("Telegent Systems");
+MODULE_DESCRIPTION("For tlg2300-based USB device ");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/pd-radio.c linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/pd-radio.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/pd-radio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/pd-radio.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,420 @@
+#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 <media/v4l2-dev.h>
+#include <linux/version.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <media/v4l2-ioctl.h>
+#include <linux/sched.h>
+
+#include "pd-common.h"
+#include "vendorcmds.h"
+
+static int set_frequency(struct poseidon *p, __u32 frequency);
+static int poseidon_fm_close(struct file *filp);
+static int poseidon_fm_open(struct file *filp);
+
+#define TUNER_FREQ_MIN_FM 76000000
+#define TUNER_FREQ_MAX_FM 108000000
+
+#define MAX_PREEMPHASIS (V4L2_PREEMPHASIS_75_uS + 1)
+static int preemphasis[MAX_PREEMPHASIS] = {
+	TLG_TUNE_ASTD_NONE,   /* V4L2_PREEMPHASIS_DISABLED */
+	TLG_TUNE_ASTD_FM_EUR, /* V4L2_PREEMPHASIS_50_uS    */
+	TLG_TUNE_ASTD_FM_US,  /* V4L2_PREEMPHASIS_75_uS    */
+};
+
+static int poseidon_check_mode_radio(struct poseidon *p)
+{
+	int ret;
+	u32 status;
+
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(HZ/2);
+	ret = usb_set_interface(p->udev, 0, BULK_ALTERNATE_IFACE);
+	if (ret < 0)
+		goto out;
+
+	ret = set_tuner_mode(p, TLG_MODE_FM_RADIO);
+	if (ret != 0)
+		goto out;
+
+	ret = send_set_req(p, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &status);
+	ret = send_set_req(p, TUNER_AUD_ANA_STD,
+				p->radio_data.pre_emphasis, &status);
+	ret |= send_set_req(p, TUNER_AUD_MODE,
+				TLG_TUNE_TVAUDIO_MODE_STEREO, &status);
+	ret |= send_set_req(p, AUDIO_SAMPLE_RATE_SEL,
+				ATV_AUDIO_RATE_48K, &status);
+	ret |= send_set_req(p, TUNE_FREQ_SELECT, TUNER_FREQ_MIN_FM, &status);
+out:
+	return ret;
+}
+
+#ifdef CONFIG_PM
+static int pm_fm_suspend(struct poseidon *p)
+{
+	logpm(p);
+	pm_alsa_suspend(p);
+	usb_set_interface(p->udev, 0, 0);
+	msleep(300);
+	return 0;
+}
+
+static int pm_fm_resume(struct poseidon *p)
+{
+	logpm(p);
+	poseidon_check_mode_radio(p);
+	set_frequency(p, p->radio_data.fm_freq);
+	pm_alsa_resume(p);
+	return 0;
+}
+#endif
+
+static int poseidon_fm_open(struct file *filp)
+{
+	struct video_device *vfd = video_devdata(filp);
+	struct poseidon *p = video_get_drvdata(vfd);
+	int ret = 0;
+
+	if (!p)
+		return -1;
+
+	mutex_lock(&p->lock);
+	if (p->state & POSEIDON_STATE_DISCONNECT) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (p->state && !(p->state & POSEIDON_STATE_FM)) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	usb_autopm_get_interface(p->interface);
+	if (0 == p->state) {
+		/* default pre-emphasis */
+		if (p->radio_data.pre_emphasis == 0)
+			p->radio_data.pre_emphasis = TLG_TUNE_ASTD_FM_EUR;
+		set_debug_mode(vfd, debug_mode);
+
+		ret = poseidon_check_mode_radio(p);
+		if (ret < 0) {
+			usb_autopm_put_interface(p->interface);
+			goto out;
+		}
+		p->state |= POSEIDON_STATE_FM;
+	}
+	p->radio_data.users++;
+	kref_get(&p->kref);
+	filp->private_data = p;
+out:
+	mutex_unlock(&p->lock);
+	return ret;
+}
+
+static int poseidon_fm_close(struct file *filp)
+{
+	struct poseidon *p = filp->private_data;
+	struct radio_data *fm = &p->radio_data;
+	uint32_t status;
+
+	mutex_lock(&p->lock);
+	fm->users--;
+	if (0 == fm->users)
+		p->state &= ~POSEIDON_STATE_FM;
+
+	if (fm->is_radio_streaming && filp == p->file_for_stream) {
+		fm->is_radio_streaming = 0;
+		send_set_req(p, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP, &status);
+	}
+	usb_autopm_put_interface(p->interface);
+	mutex_unlock(&p->lock);
+
+	kref_put(&p->kref, poseidon_delete);
+	filp->private_data = NULL;
+	return 0;
+}
+
+static int vidioc_querycap(struct file *file, void *priv,
+			struct v4l2_capability *v)
+{
+	struct poseidon *p = file->private_data;
+
+	strlcpy(v->driver, "tele-radio", sizeof(v->driver));
+	strlcpy(v->card, "Telegent Poseidon", sizeof(v->card));
+	usb_make_path(p->udev, v->bus_info, sizeof(v->bus_info));
+	v->version = KERNEL_VERSION(0, 0, 1);
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	return 0;
+}
+
+static const struct v4l2_file_operations poseidon_fm_fops = {
+	.owner         = THIS_MODULE,
+	.open          = poseidon_fm_open,
+	.release       = poseidon_fm_close,
+	.ioctl	       = video_ioctl2,
+};
+
+int tlg_fm_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
+{
+	struct tuner_fm_sig_stat_s fm_stat = {};
+	int ret, status, count = 5;
+	struct poseidon *p = file->private_data;
+
+	if (vt->index != 0)
+		return -EINVAL;
+
+	vt->type	= V4L2_TUNER_RADIO;
+	vt->capability	= V4L2_TUNER_CAP_STEREO;
+	vt->rangelow	= TUNER_FREQ_MIN_FM / 62500;
+	vt->rangehigh	= TUNER_FREQ_MAX_FM / 62500;
+	vt->rxsubchans	= V4L2_TUNER_SUB_STEREO;
+	vt->audmode	= V4L2_TUNER_MODE_STEREO;
+	vt->signal	= 0;
+	vt->afc 	= 0;
+
+	mutex_lock(&p->lock);
+	ret = send_get_req(p, TUNER_STATUS, TLG_MODE_FM_RADIO,
+			      &fm_stat, &status, sizeof(fm_stat));
+
+	while (fm_stat.sig_lock_busy && count-- && !ret) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ);
+
+		ret = send_get_req(p, TUNER_STATUS, TLG_MODE_FM_RADIO,
+				  &fm_stat, &status, sizeof(fm_stat));
+	}
+	mutex_unlock(&p->lock);
+
+	if (ret || status) {
+		vt->signal = 0;
+	} else if ((fm_stat.sig_present || fm_stat.sig_locked)
+			&& fm_stat.sig_strength == 0) {
+		vt->signal = 0xffff;
+	} else
+		vt->signal = (fm_stat.sig_strength * 255 / 10) << 8;
+
+	return 0;
+}
+
+int fm_get_freq(struct file *file, void *priv, struct v4l2_frequency *argp)
+{
+	struct poseidon *p = file->private_data;
+
+	argp->frequency = p->radio_data.fm_freq;
+	return 0;
+}
+
+static int set_frequency(struct poseidon *p, __u32 frequency)
+{
+	__u32 freq ;
+	int ret, status;
+
+	mutex_lock(&p->lock);
+
+	ret = send_set_req(p, TUNER_AUD_ANA_STD,
+				p->radio_data.pre_emphasis, &status);
+
+	freq =  (frequency * 125) * 500 / 1000;/* kHZ */
+	if (freq < TUNER_FREQ_MIN_FM/1000 || freq > TUNER_FREQ_MAX_FM/1000) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = send_set_req(p, TUNE_FREQ_SELECT, freq, &status);
+	if (ret < 0)
+		goto error ;
+	ret = send_set_req(p, TAKE_REQUEST, 0, &status);
+
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(HZ/4);
+	if (!p->radio_data.is_radio_streaming) {
+		ret = send_set_req(p, TAKE_REQUEST, 0, &status);
+		ret = send_set_req(p, PLAY_SERVICE,
+				TLG_TUNE_PLAY_SVC_START, &status);
+		p->radio_data.is_radio_streaming = 1;
+	}
+	p->radio_data.fm_freq = frequency;
+error:
+	mutex_unlock(&p->lock);
+	return ret;
+}
+
+int fm_set_freq(struct file *file, void *priv, struct v4l2_frequency *argp)
+{
+	struct poseidon *p = file->private_data;
+
+	p->file_for_stream  = file;
+#ifdef CONFIG_PM
+	p->pm_suspend = pm_fm_suspend;
+	p->pm_resume  = pm_fm_resume;
+#endif
+	return set_frequency(p, argp->frequency);
+}
+
+int tlg_fm_vidioc_g_ctrl(struct file *file, void *priv,
+		struct v4l2_control *arg)
+{
+	return 0;
+}
+
+int tlg_fm_vidioc_g_exts_ctrl(struct file *file, void *fh,
+				struct v4l2_ext_controls *ctrls)
+{
+	struct poseidon *p = file->private_data;
+	int i;
+
+	if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
+		return -EINVAL;
+
+	for (i = 0; i < ctrls->count; i++) {
+		struct v4l2_ext_control *ctrl = ctrls->controls + i;
+
+		if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS)
+			continue;
+
+		if (i < MAX_PREEMPHASIS)
+			ctrl->value = p->radio_data.pre_emphasis;
+	}
+	return 0;
+}
+
+int tlg_fm_vidioc_s_exts_ctrl(struct file *file, void *fh,
+			struct v4l2_ext_controls *ctrls)
+{
+	int i;
+
+	if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
+		return -EINVAL;
+
+	for (i = 0; i < ctrls->count; i++) {
+		struct v4l2_ext_control *ctrl = ctrls->controls + i;
+
+		if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS)
+			continue;
+
+		if (ctrl->value >= 0 && ctrl->value < MAX_PREEMPHASIS) {
+			struct poseidon *p = file->private_data;
+			int pre_emphasis = preemphasis[ctrl->value];
+			u32 status;
+
+			send_set_req(p, TUNER_AUD_ANA_STD,
+						pre_emphasis, &status);
+			p->radio_data.pre_emphasis = pre_emphasis;
+		}
+	}
+	return 0;
+}
+
+int tlg_fm_vidioc_s_ctrl(struct file *file, void *priv,
+		struct v4l2_control *ctrl)
+{
+	return 0;
+}
+
+int tlg_fm_vidioc_queryctrl(struct file *file, void *priv,
+		struct v4l2_queryctrl *ctrl)
+{
+	if (!(ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL))
+		return -EINVAL;
+
+	ctrl->id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
+	if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS) {
+		/* return the next supported control */
+		ctrl->id = V4L2_CID_TUNE_PREEMPHASIS;
+		v4l2_ctrl_query_fill(ctrl, V4L2_PREEMPHASIS_DISABLED,
+					V4L2_PREEMPHASIS_75_uS, 1,
+					V4L2_PREEMPHASIS_50_uS);
+		ctrl->flags = V4L2_CTRL_FLAG_UPDATE;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+int tlg_fm_vidioc_querymenu(struct file *file, void *fh,
+				struct v4l2_querymenu *qmenu)
+{
+	return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
+{
+	return vt->index > 0 ? -EINVAL : 0;
+}
+static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *va)
+{
+	return (va->index != 0) ? -EINVAL : 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+	a->index    = 0;
+	a->mode    = 0;
+	a->capability = V4L2_AUDCAP_STEREO;
+	strcpy(a->name, "Radio");
+	return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, u32 i)
+{
+	return (i != 0) ? -EINVAL : 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, u32 *i)
+{
+	return (*i != 0) ? -EINVAL : 0;
+}
+
+static const struct v4l2_ioctl_ops poseidon_fm_ioctl_ops = {
+	.vidioc_querycap    = vidioc_querycap,
+	.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_queryctrl   = tlg_fm_vidioc_queryctrl,
+	.vidioc_querymenu   = tlg_fm_vidioc_querymenu,
+	.vidioc_g_ctrl      = tlg_fm_vidioc_g_ctrl,
+	.vidioc_s_ctrl      = tlg_fm_vidioc_s_ctrl,
+	.vidioc_s_ext_ctrls = tlg_fm_vidioc_s_exts_ctrl,
+	.vidioc_g_ext_ctrls = tlg_fm_vidioc_g_exts_ctrl,
+	.vidioc_s_tuner     = vidioc_s_tuner,
+	.vidioc_g_tuner     = tlg_fm_vidioc_g_tuner,
+	.vidioc_g_frequency = fm_get_freq,
+	.vidioc_s_frequency = fm_set_freq,
+};
+
+static struct video_device poseidon_fm_template = {
+	.name       = "Telegent-Radio",
+	.fops       = &poseidon_fm_fops,
+	.minor      = -1,
+	.release    = video_device_release,
+	.ioctl_ops  = &poseidon_fm_ioctl_ops,
+};
+
+int poseidon_fm_init(struct poseidon *p)
+{
+	struct video_device *fm_dev;
+
+	fm_dev = vdev_init(p, &poseidon_fm_template);
+	if (fm_dev == NULL)
+		return -1;
+
+	if (video_register_device(fm_dev, VFL_TYPE_RADIO, -1) < 0) {
+		video_device_release(fm_dev);
+		return -1;
+	}
+	p->radio_data.fm_dev = fm_dev;
+	return 0;
+}
+
+int poseidon_fm_exit(struct poseidon *p)
+{
+	destroy_video_device(&p->radio_data.fm_dev);
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/pd-video.c linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/pd-video.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/pd-video.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/pd-video.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1668 @@
+#include <linux/fs.h>
+#include <linux/vmalloc.h>
+#include <linux/videodev2.h>
+#include <linux/usb.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-dev.h>
+
+#include "pd-common.h"
+#include "vendorcmds.h"
+
+static int pm_video_suspend(struct poseidon *pd);
+static int pm_video_resume(struct poseidon *pd);
+static void iso_bubble_handler(struct work_struct *w);
+
+int usb_transfer_mode;
+module_param(usb_transfer_mode, int, 0644);
+MODULE_PARM_DESC(usb_transfer_mode, "0 = Bulk, 1 = Isochronous");
+
+static const struct poseidon_format poseidon_formats[] = {
+	{ "YUV 422", V4L2_PIX_FMT_YUYV, 16, 0},
+	{ "RGB565", V4L2_PIX_FMT_RGB565, 16, 0},
+};
+
+static const struct poseidon_tvnorm poseidon_tvnorms[] = {
+	{ V4L2_STD_PAL_D, "PAL-D",  TLG_TUNE_VSTD_PAL_D },
+	{ V4L2_STD_PAL_B, "PAL-B",  TLG_TUNE_VSTD_PAL_B },
+	{ V4L2_STD_PAL_G, "PAL-G",  TLG_TUNE_VSTD_PAL_G },
+	{ V4L2_STD_PAL_H, "PAL-H",  TLG_TUNE_VSTD_PAL_H },
+	{ V4L2_STD_PAL_I, "PAL-I",  TLG_TUNE_VSTD_PAL_I },
+	{ V4L2_STD_PAL_M, "PAL-M",  TLG_TUNE_VSTD_PAL_M },
+	{ V4L2_STD_PAL_N, "PAL-N",  TLG_TUNE_VSTD_PAL_N_COMBO },
+	{ V4L2_STD_PAL_Nc, "PAL-Nc", TLG_TUNE_VSTD_PAL_N_COMBO },
+	{ V4L2_STD_NTSC_M, "NTSC-M", TLG_TUNE_VSTD_NTSC_M },
+	{ V4L2_STD_NTSC_M_JP, "NTSC-JP", TLG_TUNE_VSTD_NTSC_M_J },
+	{ V4L2_STD_SECAM_B, "SECAM-B", TLG_TUNE_VSTD_SECAM_B },
+	{ V4L2_STD_SECAM_D, "SECAM-D", TLG_TUNE_VSTD_SECAM_D },
+	{ V4L2_STD_SECAM_G, "SECAM-G", TLG_TUNE_VSTD_SECAM_G },
+	{ V4L2_STD_SECAM_H, "SECAM-H", TLG_TUNE_VSTD_SECAM_H },
+	{ V4L2_STD_SECAM_K, "SECAM-K", TLG_TUNE_VSTD_SECAM_K },
+	{ V4L2_STD_SECAM_K1, "SECAM-K1", TLG_TUNE_VSTD_SECAM_K1 },
+	{ V4L2_STD_SECAM_L, "SECAM-L", TLG_TUNE_VSTD_SECAM_L },
+	{ V4L2_STD_SECAM_LC, "SECAM-LC", TLG_TUNE_VSTD_SECAM_L1 },
+};
+static const unsigned int POSEIDON_TVNORMS = ARRAY_SIZE(poseidon_tvnorms);
+
+struct pd_audio_mode {
+	u32 tlg_audio_mode;
+	u32 v4l2_audio_sub;
+	u32 v4l2_audio_mode;
+};
+
+static const struct pd_audio_mode pd_audio_modes[] = {
+	{ TLG_TUNE_TVAUDIO_MODE_MONO, V4L2_TUNER_SUB_MONO,
+		V4L2_TUNER_MODE_MONO },
+	{ TLG_TUNE_TVAUDIO_MODE_STEREO, V4L2_TUNER_SUB_STEREO,
+		V4L2_TUNER_MODE_STEREO },
+	{ TLG_TUNE_TVAUDIO_MODE_LANG_A, V4L2_TUNER_SUB_LANG1,
+		V4L2_TUNER_MODE_LANG1 },
+	{ TLG_TUNE_TVAUDIO_MODE_LANG_B, V4L2_TUNER_SUB_LANG2,
+		V4L2_TUNER_MODE_LANG2 },
+	{ TLG_TUNE_TVAUDIO_MODE_LANG_C, V4L2_TUNER_SUB_LANG1,
+		V4L2_TUNER_MODE_LANG1_LANG2 }
+};
+static const unsigned int POSEIDON_AUDIOMODS = ARRAY_SIZE(pd_audio_modes);
+
+struct pd_input {
+	char *name;
+	uint32_t tlg_src;
+};
+
+static const struct pd_input pd_inputs[] = {
+	{ "TV Antenna", TLG_SIG_SRC_ANTENNA },
+	{ "TV Cable", TLG_SIG_SRC_CABLE },
+	{ "TV SVideo", TLG_SIG_SRC_SVIDEO },
+	{ "TV Composite", TLG_SIG_SRC_COMPOSITE }
+};
+static const unsigned int POSEIDON_INPUTS = ARRAY_SIZE(pd_inputs);
+
+struct poseidon_control {
+	struct v4l2_queryctrl v4l2_ctrl;
+	enum cmd_custom_param_id vc_id;
+};
+
+static struct poseidon_control controls[] = {
+	{
+		{ V4L2_CID_BRIGHTNESS, V4L2_CTRL_TYPE_INTEGER,
+			"brightness", 0, 10000, 1, 100, 0, },
+		CUST_PARM_ID_BRIGHTNESS_CTRL
+	}, {
+		{ V4L2_CID_CONTRAST, V4L2_CTRL_TYPE_INTEGER,
+			"contrast", 0, 10000, 1, 100, 0, },
+		CUST_PARM_ID_CONTRAST_CTRL,
+	}, {
+		{ V4L2_CID_HUE, V4L2_CTRL_TYPE_INTEGER,
+			"hue", 0, 10000, 1, 100, 0, },
+		CUST_PARM_ID_HUE_CTRL,
+	}, {
+		{ V4L2_CID_SATURATION, V4L2_CTRL_TYPE_INTEGER,
+			"saturation", 0, 10000, 1, 100, 0, },
+		CUST_PARM_ID_SATURATION_CTRL,
+	},
+};
+
+struct video_std_to_audio_std {
+	v4l2_std_id	video_std;
+	int 		audio_std;
+};
+
+static const struct video_std_to_audio_std video_to_audio_map[] = {
+	/* country : { 27, 32, 33, 34, 36, 44, 45, 46, 47, 48, 64,
+			65, 86, 351, 352, 353, 354, 358, 372, 852, 972 } */
+	{ (V4L2_STD_PAL_I | V4L2_STD_PAL_B | V4L2_STD_PAL_D |
+		V4L2_STD_SECAM_L | V4L2_STD_SECAM_D), TLG_TUNE_ASTD_NICAM },
+
+	/* country : { 1, 52, 54, 55, 886 } */
+	{V4L2_STD_NTSC_M | V4L2_STD_PAL_N | V4L2_STD_PAL_M, TLG_TUNE_ASTD_BTSC},
+
+	/* country : { 81 } */
+	{ V4L2_STD_NTSC_M_JP, TLG_TUNE_ASTD_EIAJ },
+
+	/* other country : TLG_TUNE_ASTD_A2 */
+};
+static const unsigned int map_size = ARRAY_SIZE(video_to_audio_map);
+
+static int get_audio_std(v4l2_std_id v4l2_std)
+{
+	int i = 0;
+
+	for (; i < map_size; i++) {
+		if (v4l2_std & video_to_audio_map[i].video_std)
+			return video_to_audio_map[i].audio_std;
+	}
+	return TLG_TUNE_ASTD_A2;
+}
+
+static int vidioc_querycap(struct file *file, void *fh,
+			struct v4l2_capability *cap)
+{
+	struct front_face *front = fh;
+	struct poseidon *p = front->pd;
+
+	logs(front);
+
+	strcpy(cap->driver, "tele-video");
+	strcpy(cap->card, "Telegent Poseidon");
+	usb_make_path(p->udev, cap->bus_info, sizeof(cap->bus_info));
+	cap->version = KERNEL_VERSION(0, 0, 1);
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
+				V4L2_CAP_AUDIO | V4L2_CAP_STREAMING |
+				V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE;
+	return 0;
+}
+
+/*====================================================================*/
+static void init_copy(struct video_data *video, bool index)
+{
+	struct front_face *front = video->front;
+
+	video->field_count	= index;
+	video->lines_copied	= 0;
+	video->prev_left	= 0 ;
+	video->dst 		= (char *)videobuf_to_vmalloc(front->curr_frame)
+					+ index * video->lines_size;
+	video->vbi->copied 	= 0; /* set it here */
+}
+
+static bool get_frame(struct front_face *front, int *need_init)
+{
+	struct videobuf_buffer *vb = front->curr_frame;
+
+	if (vb)
+		return true;
+
+	spin_lock(&front->queue_lock);
+	if (!list_empty(&front->active)) {
+		vb = list_entry(front->active.next,
+			       struct videobuf_buffer, queue);
+		if (need_init)
+			*need_init = 1;
+		front->curr_frame = vb;
+		list_del_init(&vb->queue);
+	}
+	spin_unlock(&front->queue_lock);
+
+	return !!vb;
+}
+
+/* check if the video's buffer is ready */
+static bool get_video_frame(struct front_face *front, struct video_data *video)
+{
+	int need_init = 0;
+	bool ret = true;
+
+	ret = get_frame(front, &need_init);
+	if (ret && need_init)
+		init_copy(video, 0);
+	return ret;
+}
+
+static void submit_frame(struct front_face *front)
+{
+	struct videobuf_buffer *vb = front->curr_frame;
+
+	if (vb == NULL)
+		return;
+
+	front->curr_frame	= NULL;
+	vb->state		= VIDEOBUF_DONE;
+	vb->field_count++;
+	do_gettimeofday(&vb->ts);
+
+	wake_up(&vb->done);
+}
+
+/*
+ * A frame is composed of two fields. If we receive all the two fields,
+ * call the  submit_frame() to submit the whole frame to applications.
+ */
+static void end_field(struct video_data *video)
+{
+	/* logs(video->front); */
+	if (1 == video->field_count)
+		submit_frame(video->front);
+	else
+		init_copy(video, 1);
+}
+
+static void copy_video_data(struct video_data *video, char *src,
+				unsigned int count)
+{
+#define copy_data(len)  \
+	do { \
+		if (++video->lines_copied > video->lines_per_field) \
+			goto overflow; \
+		memcpy(video->dst, src, len);\
+		video->dst += len + video->lines_size; \
+		src += len; \
+		count -= len; \
+	 } while (0)
+
+	while (count && count >= video->lines_size) {
+		if (video->prev_left) {
+			copy_data(video->prev_left);
+			video->prev_left = 0;
+			continue;
+		}
+		copy_data(video->lines_size);
+	}
+	if (count && count < video->lines_size) {
+		memcpy(video->dst, src, count);
+
+		video->prev_left = video->lines_size - count;
+		video->dst += count;
+	}
+	return;
+
+overflow:
+	end_field(video);
+}
+
+static void check_trailer(struct video_data *video, char *src, int count)
+{
+	struct vbi_data *vbi = video->vbi;
+	int offset; /* trailer's offset */
+	char *buf;
+
+	offset = (video->context.pix.sizeimage / 2 + vbi->vbi_size / 2)
+		- (vbi->copied + video->lines_size * video->lines_copied);
+	if (video->prev_left)
+		offset -= (video->lines_size - video->prev_left);
+
+	if (offset > count || offset <= 0)
+		goto short_package;
+
+	buf = src + offset;
+
+	/* trailer : (VFHS) + U32 + U32 + field_num */
+	if (!strncmp(buf, "VFHS", 4)) {
+		int field_num = *((u32 *)(buf + 12));
+
+		if ((field_num & 1) ^ video->field_count) {
+			init_copy(video, video->field_count);
+			return;
+		}
+		copy_video_data(video, src, offset);
+	}
+short_package:
+	end_field(video);
+}
+
+/* ==========  Check this more carefully! =========== */
+static inline void copy_vbi_data(struct vbi_data *vbi,
+				char *src, unsigned int count)
+{
+	struct front_face *front = vbi->front;
+
+	if (front && get_frame(front, NULL)) {
+		char *buf = videobuf_to_vmalloc(front->curr_frame);
+
+		if (vbi->video->field_count)
+			buf += (vbi->vbi_size / 2);
+		memcpy(buf + vbi->copied, src, count);
+	}
+	vbi->copied += count;
+}
+
+/*
+ * Copy the normal data (VBI or VIDEO) without the trailer.
+ * VBI is not interlaced, while VIDEO is interlaced.
+ */
+static inline void copy_vbi_video_data(struct video_data *video,
+				char *src, unsigned int count)
+{
+	struct vbi_data *vbi = video->vbi;
+	unsigned int vbi_delta = (vbi->vbi_size / 2) - vbi->copied;
+
+	if (vbi_delta >= count) {
+		copy_vbi_data(vbi, src, count);
+	} else {
+		if (vbi_delta) {
+			copy_vbi_data(vbi, src, vbi_delta);
+
+			/* we receive the two fields of the VBI*/
+			if (vbi->front && video->field_count)
+				submit_frame(vbi->front);
+		}
+		copy_video_data(video, src + vbi_delta, count - vbi_delta);
+	}
+}
+
+static void urb_complete_bulk(struct urb *urb)
+{
+	struct front_face *front = urb->context;
+	struct video_data *video = &front->pd->video_data;
+	char *src = (char *)urb->transfer_buffer;
+	int count = urb->actual_length;
+	int ret = 0;
+
+	if (!video->is_streaming || urb->status) {
+		if (urb->status == -EPROTO)
+			goto resend_it;
+		return;
+	}
+	if (!get_video_frame(front, video))
+		goto resend_it;
+
+	if (count == urb->transfer_buffer_length)
+		copy_vbi_video_data(video, src, count);
+	else
+		check_trailer(video, src, count);
+
+resend_it:
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	if (ret)
+		log(" submit failed: error %d", ret);
+}
+
+/************************* for ISO *********************/
+#define GET_SUCCESS		(0)
+#define GET_TRAILER		(1)
+#define GET_TOO_MUCH_BUBBLE	(2)
+#define GET_NONE		(3)
+static int get_chunk(int start, struct urb *urb,
+			int *head, int *tail, int *bubble_err)
+{
+	struct usb_iso_packet_descriptor *pkt = NULL;
+	int ret = GET_SUCCESS;
+
+	for (*head = *tail = -1; start < urb->number_of_packets; start++) {
+		pkt = &urb->iso_frame_desc[start];
+
+		/* handle the bubble of the Hub */
+		if (-EOVERFLOW == pkt->status) {
+			if (++*bubble_err > urb->number_of_packets / 3)
+				return GET_TOO_MUCH_BUBBLE;
+			continue;
+		}
+
+		/* This is the gap */
+		if (pkt->status || pkt->actual_length <= 0
+				|| pkt->actual_length > ISO_PKT_SIZE) {
+			if (*head != -1)
+				break;
+			continue;
+		}
+
+		/* a good isochronous packet */
+		if (pkt->actual_length == ISO_PKT_SIZE) {
+			if (*head == -1)
+				*head = start;
+			*tail = start;
+			continue;
+		}
+
+		/* trailer is here */
+		if (pkt->actual_length < ISO_PKT_SIZE) {
+			if (*head == -1) {
+				*head = start;
+				*tail = start;
+				return GET_TRAILER;
+			}
+			break;
+		}
+	}
+
+	if (*head == -1 && *tail == -1)
+		ret = GET_NONE;
+	return ret;
+}
+
+/*
+ * |__|------|___|-----|_______|
+ *       ^          ^
+ *       |          |
+ *      gap        gap
+ */
+static void urb_complete_iso(struct urb *urb)
+{
+	struct front_face *front = urb->context;
+	struct video_data *video = &front->pd->video_data;
+	int bubble_err = 0, head = 0, tail = 0;
+	char *src = (char *)urb->transfer_buffer;
+	int ret = 0;
+
+	if (!video->is_streaming)
+		return;
+
+	do {
+		if (!get_video_frame(front, video))
+			goto out;
+
+		switch (get_chunk(head, urb, &head, &tail, &bubble_err)) {
+		case GET_SUCCESS:
+			copy_vbi_video_data(video, src + (head * ISO_PKT_SIZE),
+					(tail - head + 1) * ISO_PKT_SIZE);
+			break;
+		case GET_TRAILER:
+			check_trailer(video, src + (head * ISO_PKT_SIZE),
+					ISO_PKT_SIZE);
+			break;
+		case GET_NONE:
+			goto out;
+		case GET_TOO_MUCH_BUBBLE:
+			log("\t We got too much bubble");
+			schedule_work(&video->bubble_work);
+			return;
+		}
+	} while (head = tail + 1, head < urb->number_of_packets);
+
+out:
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	if (ret)
+		log("usb_submit_urb err : %d", ret);
+}
+/*============================= [  end  ] =====================*/
+
+static int prepare_iso_urb(struct video_data *video)
+{
+	struct usb_device *udev = video->pd->udev;
+	int i;
+
+	if (video->urb_array[0])
+		return 0;
+
+	for (i = 0; i < SBUF_NUM; i++) {
+		struct urb *urb;
+		void *mem;
+		int j;
+
+		urb = usb_alloc_urb(PK_PER_URB, GFP_KERNEL);
+		if (urb == NULL)
+			goto out;
+
+		video->urb_array[i] = urb;
+		mem = usb_buffer_alloc(udev,
+					ISO_PKT_SIZE * PK_PER_URB,
+					GFP_KERNEL,
+					&urb->transfer_dma);
+
+		urb->complete	= urb_complete_iso;	/* handler */
+		urb->dev	= udev;
+		urb->context	= video->front;
+		urb->pipe	= usb_rcvisocpipe(udev,
+						video->endpoint_addr);
+		urb->interval	= 1;
+		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+		urb->number_of_packets	= PK_PER_URB;
+		urb->transfer_buffer	= mem;
+		urb->transfer_buffer_length = PK_PER_URB * ISO_PKT_SIZE;
+
+		for (j = 0; j < PK_PER_URB; j++) {
+			urb->iso_frame_desc[j].offset = ISO_PKT_SIZE * j;
+			urb->iso_frame_desc[j].length = ISO_PKT_SIZE;
+		}
+	}
+	return 0;
+out:
+	for (; i > 0; i--)
+		;
+	return -ENOMEM;
+}
+
+/* return the succeeded number of the allocation */
+int alloc_bulk_urbs_generic(struct urb **urb_array, int num,
+			struct usb_device *udev, u8 ep_addr,
+			int buf_size, gfp_t gfp_flags,
+			usb_complete_t complete_fn, void *context)
+{
+	struct urb *urb;
+	void *mem;
+	int i;
+
+	for (i = 0; i < num; i++) {
+		urb = usb_alloc_urb(0, gfp_flags);
+		if (urb == NULL)
+			return i;
+
+		mem = usb_buffer_alloc(udev, buf_size, gfp_flags,
+					&urb->transfer_dma);
+		if (mem == NULL)
+			return i;
+
+		usb_fill_bulk_urb(urb, udev, usb_rcvbulkpipe(udev, ep_addr),
+				mem, buf_size, complete_fn, context);
+		urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+		urb_array[i] = urb;
+	}
+	return i;
+}
+
+void free_all_urb_generic(struct urb **urb_array, int num)
+{
+	int i;
+	struct urb *urb;
+
+	for (i = 0; i < num; i++) {
+		urb = urb_array[i];
+		if (urb) {
+			usb_buffer_free(urb->dev,
+					urb->transfer_buffer_length,
+					urb->transfer_buffer,
+					urb->transfer_dma);
+			usb_free_urb(urb);
+			urb_array[i] = NULL;
+		}
+	}
+}
+
+static int prepare_bulk_urb(struct video_data *video)
+{
+	if (video->urb_array[0])
+		return 0;
+
+	alloc_bulk_urbs_generic(video->urb_array, SBUF_NUM,
+			video->pd->udev, video->endpoint_addr,
+			0x2000, GFP_KERNEL,
+			urb_complete_bulk, video->front);
+	return 0;
+}
+
+/* free the URBs */
+static void free_all_urb(struct video_data *video)
+{
+	free_all_urb_generic(video->urb_array, SBUF_NUM);
+}
+
+static void pd_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
+{
+	videobuf_vmalloc_free(vb);
+	vb->state = VIDEOBUF_NEEDS_INIT;
+}
+
+static void pd_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
+{
+	struct front_face *front = q->priv_data;
+	vb->state = VIDEOBUF_QUEUED;
+	list_add_tail(&vb->queue, &front->active);
+}
+
+static int pd_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
+			   enum v4l2_field field)
+{
+	struct front_face *front = q->priv_data;
+	int rc;
+
+	switch (front->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (VIDEOBUF_NEEDS_INIT == vb->state) {
+			struct v4l2_pix_format *pix;
+
+			pix = &front->pd->video_data.context.pix;
+			vb->size	= pix->sizeimage; /* real frame size */
+			vb->width	= pix->width;
+			vb->height	= pix->height;
+			rc = videobuf_iolock(q, vb, NULL);
+			if (rc < 0)
+				return rc;
+		}
+		break;
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		if (VIDEOBUF_NEEDS_INIT == vb->state) {
+			vb->size	= front->pd->vbi_data.vbi_size;
+			rc = videobuf_iolock(q, vb, NULL);
+			if (rc < 0)
+				return rc;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+	vb->field = field;
+	vb->state = VIDEOBUF_PREPARED;
+	return 0;
+}
+
+int fire_all_urb(struct video_data *video)
+{
+	int i, ret;
+
+	video->is_streaming = 1;
+
+	for (i = 0; i < SBUF_NUM; i++) {
+		ret = usb_submit_urb(video->urb_array[i], GFP_KERNEL);
+		if (ret)
+			log("(%d) failed: error %d", i, ret);
+	}
+	return ret;
+}
+
+static int start_video_stream(struct poseidon *pd)
+{
+	struct video_data *video = &pd->video_data;
+	s32 cmd_status;
+
+	send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
+	send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_START, &cmd_status);
+
+	if (pd->cur_transfer_mode) {
+		prepare_iso_urb(video);
+		INIT_WORK(&video->bubble_work, iso_bubble_handler);
+	} else {
+		/* The bulk mode does not need a bubble handler */
+		prepare_bulk_urb(video);
+	}
+	fire_all_urb(video);
+	return 0;
+}
+
+static int pd_buf_setup(struct videobuf_queue *q, unsigned int *count,
+		       unsigned int *size)
+{
+	struct front_face *front = q->priv_data;
+	struct poseidon *pd	= front->pd;
+
+	switch (front->type) {
+	default:
+		return -EINVAL;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
+		struct video_data *video = &pd->video_data;
+		struct v4l2_pix_format *pix = &video->context.pix;
+
+		*size = PAGE_ALIGN(pix->sizeimage);/* page aligned frame size */
+		if (*count < 4)
+			*count = 4;
+		if (1) {
+			/* same in different altersetting */
+			video->endpoint_addr	= 0x82;
+			video->vbi		= &pd->vbi_data;
+			video->vbi->video	= video;
+			video->pd		= pd;
+			video->lines_per_field	= pix->height / 2;
+			video->lines_size	= pix->width * 2;
+			video->front 		= front;
+		}
+		return start_video_stream(pd);
+	}
+
+	case V4L2_BUF_TYPE_VBI_CAPTURE: {
+		struct vbi_data *vbi = &pd->vbi_data;
+
+		*size = PAGE_ALIGN(vbi->vbi_size);
+		log("size : %d", *size);
+		if (*count == 0)
+			*count = 4;
+	}
+		break;
+	}
+	return 0;
+}
+
+static struct videobuf_queue_ops pd_video_qops = {
+	.buf_setup      = pd_buf_setup,
+	.buf_prepare    = pd_buf_prepare,
+	.buf_queue      = pd_buf_queue,
+	.buf_release    = pd_buf_release,
+};
+
+static int vidioc_enum_fmt(struct file *file, void *fh,
+				struct v4l2_fmtdesc *f)
+{
+	if (ARRAY_SIZE(poseidon_formats) <= f->index)
+		return -EINVAL;
+	f->type		= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	f->flags	= 0;
+	f->pixelformat	= poseidon_formats[f->index].fourcc;
+	strcpy(f->description, poseidon_formats[f->index].name);
+	return 0;
+}
+
+static int vidioc_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct front_face *front = fh;
+	struct poseidon *pd = front->pd;
+
+	logs(front);
+	f->fmt.pix = pd->video_data.context.pix;
+	return 0;
+}
+
+static int vidioc_try_fmt(struct file *file, void *fh,
+		struct v4l2_format *f)
+{
+	return 0;
+}
+
+/*
+ * VLC calls VIDIOC_S_STD before VIDIOC_S_FMT, while
+ * Mplayer calls them in the reverse order.
+ */
+static int pd_vidioc_s_fmt(struct poseidon *pd, struct v4l2_pix_format *pix)
+{
+	struct video_data *video	= &pd->video_data;
+	struct running_context *context = &video->context;
+	struct v4l2_pix_format *pix_def	= &context->pix;
+	s32 ret = 0, cmd_status = 0, vid_resol;
+
+	/* set the pixel format to firmware */
+	if (pix->pixelformat == V4L2_PIX_FMT_RGB565) {
+		vid_resol = TLG_TUNER_VID_FORMAT_RGB_565;
+	} else {
+		pix->pixelformat = V4L2_PIX_FMT_YUYV;
+		vid_resol = TLG_TUNER_VID_FORMAT_YUV;
+	}
+	ret = send_set_req(pd, VIDEO_STREAM_FMT_SEL,
+				vid_resol, &cmd_status);
+
+	/* set the resolution to firmware */
+	vid_resol = TLG_TUNE_VID_RES_720;
+	switch (pix->width) {
+	case 704:
+		vid_resol = TLG_TUNE_VID_RES_704;
+		break;
+	default:
+		pix->width = 720;
+	case 720:
+		break;
+	}
+	ret |= send_set_req(pd, VIDEO_ROSOLU_SEL,
+				vid_resol, &cmd_status);
+	if (ret || cmd_status) {
+		mutex_unlock(&pd->lock);
+		return -EBUSY;
+	}
+
+	pix_def->pixelformat = pix->pixelformat; /* save it */
+	pix->height = (context->tvnormid & V4L2_STD_525_60) ?  480 : 576;
+
+	/* Compare with the default setting */
+	if ((pix_def->width != pix->width)
+		|| (pix_def->height != pix->height)) {
+		pix_def->width		= pix->width;
+		pix_def->height		= pix->height;
+		pix_def->bytesperline	= pix->width * 2;
+		pix_def->sizeimage 	= pix->width * pix->height * 2;
+	}
+	*pix = *pix_def;
+
+	return 0;
+}
+
+static int vidioc_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct front_face *front	= fh;
+	struct poseidon *pd		= front->pd;
+
+	logs(front);
+	/* stop VBI here */
+	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != f->type)
+		return -EINVAL;
+
+	mutex_lock(&pd->lock);
+	if (pd->file_for_stream == NULL)
+		pd->file_for_stream = file;
+	else if (file != pd->file_for_stream) {
+		mutex_unlock(&pd->lock);
+		return -EINVAL;
+	}
+
+	pd_vidioc_s_fmt(pd, &f->fmt.pix);
+	mutex_unlock(&pd->lock);
+	return 0;
+}
+
+static int vidioc_g_fmt_vbi(struct file *file, void *fh,
+			       struct v4l2_format *v4l2_f)
+{
+	struct front_face *front	= fh;
+	struct poseidon *pd		= front->pd;
+	struct v4l2_vbi_format *vbi_fmt	= &v4l2_f->fmt.vbi;
+
+	vbi_fmt->samples_per_line	= 720 * 2;
+	vbi_fmt->sampling_rate		= 6750000 * 4;
+	vbi_fmt->sample_format		= V4L2_PIX_FMT_GREY;
+	vbi_fmt->offset			= 64 * 4;  /*FIXME: why offset */
+	if (pd->video_data.context.tvnormid & V4L2_STD_525_60) {
+		vbi_fmt->start[0] = 10;
+		vbi_fmt->start[1] = 264;
+		vbi_fmt->count[0] = V4L_NTSC_VBI_LINES;
+		vbi_fmt->count[1] = V4L_NTSC_VBI_LINES;
+	} else {
+		vbi_fmt->start[0] = 6;
+		vbi_fmt->start[1] = 314;
+		vbi_fmt->count[0] = V4L_PAL_VBI_LINES;
+		vbi_fmt->count[1] = V4L_PAL_VBI_LINES;
+	}
+	vbi_fmt->flags = V4L2_VBI_UNSYNC;
+	logs(front);
+	return 0;
+}
+
+static int set_std(struct poseidon *pd, v4l2_std_id *norm)
+{
+	struct video_data *video = &pd->video_data;
+	struct vbi_data *vbi	= &pd->vbi_data;
+	struct running_context *context;
+	struct v4l2_pix_format *pix;
+	s32 i, ret = 0, cmd_status, param;
+	int height;
+
+	for (i = 0; i < POSEIDON_TVNORMS; i++) {
+		if (*norm & poseidon_tvnorms[i].v4l2_id) {
+			param = poseidon_tvnorms[i].tlg_tvnorm;
+			log("name : %s", poseidon_tvnorms[i].name);
+			goto found;
+		}
+	}
+	return -EINVAL;
+found:
+	mutex_lock(&pd->lock);
+	ret = send_set_req(pd, VIDEO_STD_SEL, param, &cmd_status);
+	if (ret || cmd_status)
+		goto out;
+
+	/* Set vbi size and check the height of the frame */
+	context = &video->context;
+	context->tvnormid = poseidon_tvnorms[i].v4l2_id;
+	if (context->tvnormid & V4L2_STD_525_60) {
+		vbi->vbi_size = V4L_NTSC_VBI_FRAMESIZE;
+		height = 480;
+	} else {
+		vbi->vbi_size = V4L_PAL_VBI_FRAMESIZE;
+		height = 576;
+	}
+
+	pix = &context->pix;
+	if (pix->height != height) {
+		pix->height	= height;
+		pix->sizeimage 	= pix->width * pix->height * 2;
+	}
+
+out:
+	mutex_unlock(&pd->lock);
+	return ret;
+}
+
+int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *norm)
+{
+	struct front_face *front = fh;
+	logs(front);
+	return set_std(front->pd, norm);
+}
+
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *in)
+{
+	struct front_face *front = fh;
+
+	if (in->index < 0 || in->index >= POSEIDON_INPUTS)
+		return -EINVAL;
+	strcpy(in->name, pd_inputs[in->index].name);
+	in->type  = V4L2_INPUT_TYPE_TUNER;
+
+	/*
+	 * the audio input index mixed with this video input,
+	 * Poseidon only have one audio/video, set to "0"
+	 */
+	in->audioset	= 0;
+	in->tuner	= 0;
+	in->std		= V4L2_STD_ALL;
+	in->status	= 0;
+	logs(front);
+	return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
+{
+	struct front_face *front = fh;
+	struct poseidon *pd = front->pd;
+	struct running_context *context = &pd->video_data.context;
+
+	logs(front);
+	*i = context->sig_index;
+	return 0;
+}
+
+/* We can support several inputs */
+static int vidioc_s_input(struct file *file, void *fh, unsigned int i)
+{
+	struct front_face *front = fh;
+	struct poseidon *pd = front->pd;
+	s32 ret, cmd_status;
+
+	if (i < 0 || i >= POSEIDON_INPUTS)
+		return -EINVAL;
+	ret = send_set_req(pd, SGNL_SRC_SEL,
+			pd_inputs[i].tlg_src, &cmd_status);
+	if (ret)
+		return ret;
+
+	pd->video_data.context.sig_index = i;
+	return 0;
+}
+
+static struct poseidon_control *check_control_id(__u32 id)
+{
+	struct poseidon_control *control = &controls[0];
+	int array_size = ARRAY_SIZE(controls);
+
+	for (; control < &controls[array_size]; control++)
+		if (control->v4l2_ctrl.id  == id)
+			return control;
+	return NULL;
+}
+
+static int vidioc_queryctrl(struct file *file, void *fh,
+			struct v4l2_queryctrl *a)
+{
+	struct poseidon_control *control = NULL;
+
+	control = check_control_id(a->id);
+	if (!control)
+		return -EINVAL;
+
+	*a = control->v4l2_ctrl;
+	return 0;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *ctrl)
+{
+	struct front_face *front = fh;
+	struct poseidon *pd = front->pd;
+	struct poseidon_control *control = NULL;
+	struct tuner_custom_parameter_s tuner_param;
+	s32 ret = 0, cmd_status;
+
+	control = check_control_id(ctrl->id);
+	if (!control)
+		return -EINVAL;
+
+	mutex_lock(&pd->lock);
+	ret = send_get_req(pd, TUNER_CUSTOM_PARAMETER, control->vc_id,
+			&tuner_param, &cmd_status, sizeof(tuner_param));
+	mutex_unlock(&pd->lock);
+
+	if (ret || cmd_status)
+		return -1;
+
+	ctrl->value = tuner_param.param_value;
+	return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a)
+{
+	struct tuner_custom_parameter_s param = {0};
+	struct poseidon_control *control = NULL;
+	struct front_face *front	= fh;
+	struct poseidon *pd		= front->pd;
+	s32 ret = 0, cmd_status, params;
+
+	control = check_control_id(a->id);
+	if (!control)
+		return -EINVAL;
+
+	param.param_value = a->value;
+	param.param_id	= control->vc_id;
+	params = *(s32 *)&param; /* temp code */
+
+	mutex_lock(&pd->lock);
+	ret = send_set_req(pd, TUNER_CUSTOM_PARAMETER, params, &cmd_status);
+	ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
+	mutex_unlock(&pd->lock);
+
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(HZ/4);
+	return ret;
+}
+
+/* Audio ioctls */
+static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+	if (0 != a->index)
+		return -EINVAL;
+	a->capability = V4L2_AUDCAP_STEREO;
+	strcpy(a->name, "USB audio in");
+	/*Poseidon have no AVL function.*/
+	a->mode = 0;
+	return 0;
+}
+
+int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+	a->index = 0;
+	a->capability = V4L2_AUDCAP_STEREO;
+	strcpy(a->name, "USB audio in");
+	a->mode = 0;
+	return 0;
+}
+
+int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+	return (0 == a->index) ? 0 : -EINVAL;
+}
+
+/* Tuner ioctls */
+static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *tuner)
+{
+	struct front_face *front	= fh;
+	struct poseidon *pd		= front->pd;
+	struct tuner_atv_sig_stat_s atv_stat;
+	s32 count = 5, ret, cmd_status;
+	int index;
+
+	if (0 != tuner->index)
+		return -EINVAL;
+
+	mutex_lock(&pd->lock);
+	ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_ANALOG_TV,
+				&atv_stat, &cmd_status, sizeof(atv_stat));
+
+	while (atv_stat.sig_lock_busy && count-- && !ret) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ);
+
+		ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_ANALOG_TV,
+				&atv_stat, &cmd_status, sizeof(atv_stat));
+	}
+	mutex_unlock(&pd->lock);
+
+	if (debug_mode)
+		log("P:%d,S:%d", atv_stat.sig_present, atv_stat.sig_strength);
+
+	if (ret || cmd_status)
+		tuner->signal = 0;
+	else if (atv_stat.sig_present && !atv_stat.sig_strength)
+		tuner->signal = 0xFFFF;
+	else
+		tuner->signal = (atv_stat.sig_strength * 255 / 10) << 8;
+
+	strcpy(tuner->name, "Telegent Systems");
+	tuner->type = V4L2_TUNER_ANALOG_TV;
+	tuner->rangelow = TUNER_FREQ_MIN / 62500;
+	tuner->rangehigh = TUNER_FREQ_MAX / 62500;
+	tuner->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
+				V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
+	index = pd->video_data.context.audio_idx;
+	tuner->rxsubchans = pd_audio_modes[index].v4l2_audio_sub;
+	tuner->audmode = pd_audio_modes[index].v4l2_audio_mode;
+	tuner->afc = 0;
+	logs(front);
+	return 0;
+}
+
+static int pd_vidioc_s_tuner(struct poseidon *pd, int index)
+{
+	s32 ret = 0, cmd_status, param, audiomode;
+
+	mutex_lock(&pd->lock);
+	param = pd_audio_modes[index].tlg_audio_mode;
+	ret = send_set_req(pd, TUNER_AUD_MODE, param, &cmd_status);
+	audiomode = get_audio_std(pd->video_data.context.tvnormid);
+	ret |= send_set_req(pd, TUNER_AUD_ANA_STD, audiomode,
+				&cmd_status);
+	if (!ret)
+		pd->video_data.context.audio_idx = index;
+	mutex_unlock(&pd->lock);
+	return ret;
+}
+
+static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *a)
+{
+	struct front_face *front	= fh;
+	struct poseidon *pd		= front->pd;
+	int index;
+
+	if (0 != a->index)
+		return -EINVAL;
+	logs(front);
+	for (index = 0; index < POSEIDON_AUDIOMODS; index++)
+		if (a->audmode == pd_audio_modes[index].v4l2_audio_mode)
+			return pd_vidioc_s_tuner(pd, index);
+	return -EINVAL;
+}
+
+static int vidioc_g_frequency(struct file *file, void *fh,
+			struct v4l2_frequency *freq)
+{
+	struct front_face *front = fh;
+	struct poseidon *pd = front->pd;
+	struct running_context *context = &pd->video_data.context;
+
+	if (0 != freq->tuner)
+		return -EINVAL;
+	freq->frequency = context->freq;
+	freq->type = V4L2_TUNER_ANALOG_TV;
+	return 0;
+}
+
+static int set_frequency(struct poseidon *pd, __u32 frequency)
+{
+	s32 ret = 0, param, cmd_status;
+	struct running_context *context = &pd->video_data.context;
+
+	param = frequency * 62500 / 1000;
+	if (param < TUNER_FREQ_MIN/1000 || param > TUNER_FREQ_MAX / 1000)
+		return -EINVAL;
+
+	mutex_lock(&pd->lock);
+	ret = send_set_req(pd, TUNE_FREQ_SELECT, param, &cmd_status);
+	ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
+
+	msleep(250); /* wait for a while until the hardware is ready. */
+	context->freq = frequency;
+	mutex_unlock(&pd->lock);
+	return ret;
+}
+
+static int vidioc_s_frequency(struct file *file, void *fh,
+				struct v4l2_frequency *freq)
+{
+	struct front_face *front = fh;
+	struct poseidon *pd = front->pd;
+
+	logs(front);
+#ifdef CONFIG_PM
+	pd->pm_suspend = pm_video_suspend;
+	pd->pm_resume = pm_video_resume;
+#endif
+	return set_frequency(pd, freq->frequency);
+}
+
+static int vidioc_reqbufs(struct file *file, void *fh,
+				struct v4l2_requestbuffers *b)
+{
+	struct front_face *front = file->private_data;
+	logs(front);
+	return videobuf_reqbufs(&front->q, b);
+}
+
+static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
+{
+	struct front_face *front = file->private_data;
+	logs(front);
+	return videobuf_querybuf(&front->q, b);
+}
+
+static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
+{
+	struct front_face *front = file->private_data;
+	return videobuf_qbuf(&front->q, b);
+}
+
+static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
+{
+	struct front_face *front = file->private_data;
+	return videobuf_dqbuf(&front->q, b, file->f_flags & O_NONBLOCK);
+}
+
+/* Just stop the URBs, do not free the URBs */
+int usb_transfer_stop(struct video_data *video)
+{
+	if (video->is_streaming) {
+		int i;
+		s32 cmd_status;
+		struct poseidon *pd = video->pd;
+
+		video->is_streaming = 0;
+		for (i = 0; i < SBUF_NUM; ++i) {
+			if (video->urb_array[i])
+				usb_kill_urb(video->urb_array[i]);
+		}
+
+		send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP,
+			       &cmd_status);
+	}
+	return 0;
+}
+
+int stop_all_video_stream(struct poseidon *pd)
+{
+	struct video_data *video = &pd->video_data;
+	struct vbi_data *vbi	= &pd->vbi_data;
+
+	mutex_lock(&pd->lock);
+	if (video->is_streaming) {
+		struct front_face *front = video->front;
+
+		/* stop the URBs */
+		usb_transfer_stop(video);
+		free_all_urb(video);
+
+		/* stop the host side of VIDEO */
+		videobuf_stop(&front->q);
+		videobuf_mmap_free(&front->q);
+
+		/* stop the host side of VBI */
+		front = vbi->front;
+		if (front) {
+			videobuf_stop(&front->q);
+			videobuf_mmap_free(&front->q);
+		}
+	}
+	mutex_unlock(&pd->lock);
+	return 0;
+}
+
+/*
+ * The bubbles can seriously damage the video's quality,
+ * though it occurs in very rare situation.
+ */
+static void iso_bubble_handler(struct work_struct *w)
+{
+	struct video_data *video;
+	struct poseidon *pd;
+
+	video = container_of(w, struct video_data, bubble_work);
+	pd = video->pd;
+
+	mutex_lock(&pd->lock);
+	usb_transfer_stop(video);
+	msleep(500);
+	start_video_stream(pd);
+	mutex_unlock(&pd->lock);
+}
+
+
+static int vidioc_streamon(struct file *file, void *fh,
+				enum v4l2_buf_type type)
+{
+	struct front_face *front = fh;
+
+	logs(front);
+	if (unlikely(type != front->type))
+		return -EINVAL;
+	return videobuf_streamon(&front->q);
+}
+
+static int vidioc_streamoff(struct file *file, void *fh,
+				enum v4l2_buf_type type)
+{
+	struct front_face *front = file->private_data;
+
+	logs(front);
+	if (unlikely(type != front->type))
+		return -EINVAL;
+	return videobuf_streamoff(&front->q);
+}
+
+/* Set the firmware's default values : need altersetting */
+static int pd_video_checkmode(struct poseidon *pd)
+{
+	s32 ret = 0, cmd_status, audiomode;
+
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(HZ/2);
+
+	/* choose the altersetting */
+	ret = usb_set_interface(pd->udev, 0,
+					(pd->cur_transfer_mode ?
+					 ISO_3K_BULK_ALTERNATE_IFACE :
+					 BULK_ALTERNATE_IFACE));
+	if (ret < 0)
+		goto error;
+
+	/* set default parameters for PAL-D , with the VBI enabled*/
+	ret = set_tuner_mode(pd, TLG_MODE_ANALOG_TV);
+	ret |= send_set_req(pd, SGNL_SRC_SEL,
+				TLG_SIG_SRC_ANTENNA, &cmd_status);
+	ret |= send_set_req(pd, VIDEO_STD_SEL,
+				TLG_TUNE_VSTD_PAL_D, &cmd_status);
+	ret |= send_set_req(pd, VIDEO_STREAM_FMT_SEL,
+				TLG_TUNER_VID_FORMAT_YUV, &cmd_status);
+	ret |= send_set_req(pd, VIDEO_ROSOLU_SEL,
+				TLG_TUNE_VID_RES_720, &cmd_status);
+	ret |= send_set_req(pd, TUNE_FREQ_SELECT, TUNER_FREQ_MIN, &cmd_status);
+	ret |= send_set_req(pd, VBI_DATA_SEL, 1, &cmd_status);/* enable vbi */
+
+	/* set the audio */
+	audiomode = get_audio_std(pd->video_data.context.tvnormid);
+	ret |= send_set_req(pd, TUNER_AUD_ANA_STD, audiomode, &cmd_status);
+	ret |= send_set_req(pd, TUNER_AUD_MODE,
+				TLG_TUNE_TVAUDIO_MODE_STEREO, &cmd_status);
+	ret |= send_set_req(pd, AUDIO_SAMPLE_RATE_SEL,
+				ATV_AUDIO_RATE_48K, &cmd_status);
+error:
+	return ret;
+}
+
+#ifdef CONFIG_PM
+static int pm_video_suspend(struct poseidon *pd)
+{
+	/* stop audio */
+	pm_alsa_suspend(pd);
+
+	/* stop and free all the URBs */
+	usb_transfer_stop(&pd->video_data);
+	free_all_urb(&pd->video_data);
+
+	/* reset the interface */
+	usb_set_interface(pd->udev, 0, 0);
+	msleep(300);
+	return 0;
+}
+
+static int restore_v4l2_context(struct poseidon *pd,
+				struct running_context *context)
+{
+	struct front_face *front = pd->video_data.front;
+
+	pd_video_checkmode(pd);
+
+	set_std(pd, &context->tvnormid);
+	vidioc_s_input(NULL, front, context->sig_index);
+	pd_vidioc_s_tuner(pd, context->audio_idx);
+	pd_vidioc_s_fmt(pd, &context->pix);
+	set_frequency(pd, context->freq);
+	return 0;
+}
+
+static int pm_video_resume(struct poseidon *pd)
+{
+	struct video_data *video = &pd->video_data;
+
+	/* resume the video */
+	/* [1] restore the origin V4L2 parameters */
+	restore_v4l2_context(pd, &video->context);
+
+	/* [2] initiate video copy variables */
+	if (video->front->curr_frame)
+		init_copy(video, 0);
+
+	/* [3] fire urbs	*/
+	start_video_stream(pd);
+
+	/* resume the audio */
+	pm_alsa_resume(pd);
+	return 0;
+}
+#endif
+
+void set_debug_mode(struct video_device *vfd, int debug_mode)
+{
+	vfd->debug = 0;
+	if (debug_mode & 0x1)
+		vfd->debug = V4L2_DEBUG_IOCTL;
+	if (debug_mode & 0x2)
+		vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
+}
+
+static void init_video_context(struct running_context *context)
+{
+	context->sig_index	= 0;
+	context->audio_idx	= 1; /* stereo */
+	context->tvnormid  	= V4L2_STD_PAL_D;
+	context->pix = (struct v4l2_pix_format) {
+				.width		= 720,
+				.height		= 576,
+				.pixelformat	= V4L2_PIX_FMT_YUYV,
+				.field		= V4L2_FIELD_INTERLACED,
+				.bytesperline	= 720 * 2,
+				.sizeimage	= 720 * 576 * 2,
+				.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+				.priv		= 0
+			};
+}
+
+static int pd_video_open(struct file *file)
+{
+	struct video_device *vfd = video_devdata(file);
+	struct poseidon *pd = video_get_drvdata(vfd);
+	struct front_face *front = NULL;
+	int ret = -ENOMEM;
+
+	mutex_lock(&pd->lock);
+	usb_autopm_get_interface(pd->interface);
+
+	if (vfd->vfl_type == VFL_TYPE_GRABBER
+		&& !(pd->state & POSEIDON_STATE_ANALOG)) {
+		front = kzalloc(sizeof(struct front_face), GFP_KERNEL);
+		if (!front)
+			goto out;
+
+		pd->cur_transfer_mode	= usb_transfer_mode;/* bulk or iso */
+		init_video_context(&pd->video_data.context);
+
+		ret = pd_video_checkmode(pd);
+		if (ret < 0) {
+			kfree(front);
+			ret = -1;
+			goto out;
+		}
+
+		pd->state		|= POSEIDON_STATE_ANALOG;
+		front->type		= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		pd->video_data.users++;
+		set_debug_mode(vfd, debug_mode);
+
+		videobuf_queue_vmalloc_init(&front->q, &pd_video_qops,
+				NULL, &front->queue_lock,
+				V4L2_BUF_TYPE_VIDEO_CAPTURE,
+				V4L2_FIELD_INTERLACED,/* video is interlacd */
+				sizeof(struct videobuf_buffer),/*it's enough*/
+				front);
+	} else if (vfd->vfl_type == VFL_TYPE_VBI
+		&& !(pd->state & POSEIDON_STATE_VBI)) {
+		front = kzalloc(sizeof(struct front_face), GFP_KERNEL);
+		if (!front)
+			goto out;
+
+		pd->state	|= POSEIDON_STATE_VBI;
+		front->type	= V4L2_BUF_TYPE_VBI_CAPTURE;
+		pd->vbi_data.front = front;
+		pd->vbi_data.users++;
+
+		videobuf_queue_vmalloc_init(&front->q, &pd_video_qops,
+				NULL, &front->queue_lock,
+				V4L2_BUF_TYPE_VBI_CAPTURE,
+				V4L2_FIELD_NONE, /* vbi is NONE mode */
+				sizeof(struct videobuf_buffer),
+				front);
+	} else {
+		/* maybe add FM support here */
+		log("other ");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	front->pd		= pd;
+	front->curr_frame	= NULL;
+	INIT_LIST_HEAD(&front->active);
+	spin_lock_init(&front->queue_lock);
+
+	file->private_data	= front;
+	kref_get(&pd->kref);
+
+	mutex_unlock(&pd->lock);
+	return 0;
+out:
+	usb_autopm_put_interface(pd->interface);
+	mutex_unlock(&pd->lock);
+	return ret;
+}
+
+static int pd_video_release(struct file *file)
+{
+	struct front_face *front = file->private_data;
+	struct poseidon *pd = front->pd;
+	s32 cmd_status = 0;
+
+	logs(front);
+	mutex_lock(&pd->lock);
+
+	if (front->type	== V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		pd->state &= ~POSEIDON_STATE_ANALOG;
+
+		/* stop the device, and free the URBs */
+		usb_transfer_stop(&pd->video_data);
+		free_all_urb(&pd->video_data);
+
+		/* stop the firmware */
+		send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP,
+			       &cmd_status);
+
+		pd->file_for_stream = NULL;
+		pd->video_data.users--;
+	} else if (front->type	== V4L2_BUF_TYPE_VBI_CAPTURE) {
+		pd->state &= ~POSEIDON_STATE_VBI;
+		pd->vbi_data.front = NULL;
+		pd->vbi_data.users--;
+	}
+	videobuf_stop(&front->q);
+	videobuf_mmap_free(&front->q);
+
+	usb_autopm_put_interface(pd->interface);
+	mutex_unlock(&pd->lock);
+
+	kfree(front);
+	file->private_data = NULL;
+	kref_put(&pd->kref, poseidon_delete);
+	return 0;
+}
+
+static int pd_video_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct front_face *front = file->private_data;
+	return  videobuf_mmap_mapper(&front->q, vma);
+}
+
+unsigned int pd_video_poll(struct file *file, poll_table *table)
+{
+	struct front_face *front = file->private_data;
+	return videobuf_poll_stream(file, &front->q, table);
+}
+
+ssize_t pd_video_read(struct file *file, char __user *buffer,
+			size_t count, loff_t *ppos)
+{
+	struct front_face *front = file->private_data;
+	return videobuf_read_stream(&front->q, buffer, count, ppos,
+				0, file->f_flags & O_NONBLOCK);
+}
+
+/* This struct works for both VIDEO and VBI */
+static const struct v4l2_file_operations pd_video_fops = {
+	.owner		= THIS_MODULE,
+	.open		= pd_video_open,
+	.release	= pd_video_release,
+	.read		= pd_video_read,
+	.poll		= pd_video_poll,
+	.mmap		= pd_video_mmap,
+	.ioctl		= video_ioctl2, /* maybe changed in future */
+};
+
+static const struct v4l2_ioctl_ops pd_video_ioctl_ops = {
+	.vidioc_querycap	= vidioc_querycap,
+
+	/* Video format */
+	.vidioc_g_fmt_vid_cap	= vidioc_g_fmt,
+	.vidioc_enum_fmt_vid_cap	= vidioc_enum_fmt,
+	.vidioc_s_fmt_vid_cap	= vidioc_s_fmt,
+	.vidioc_g_fmt_vbi_cap	= vidioc_g_fmt_vbi, /* VBI */
+	.vidioc_try_fmt_vid_cap = vidioc_try_fmt,
+
+	/* Input */
+	.vidioc_g_input		= vidioc_g_input,
+	.vidioc_s_input		= vidioc_s_input,
+	.vidioc_enum_input	= vidioc_enum_input,
+
+	/* Audio ioctls */
+	.vidioc_enumaudio	= vidioc_enumaudio,
+	.vidioc_g_audio		= vidioc_g_audio,
+	.vidioc_s_audio		= vidioc_s_audio,
+
+	/* Tuner ioctls */
+	.vidioc_g_tuner		= vidioc_g_tuner,
+	.vidioc_s_tuner		= vidioc_s_tuner,
+	.vidioc_s_std		= vidioc_s_std,
+	.vidioc_g_frequency	= vidioc_g_frequency,
+	.vidioc_s_frequency	= vidioc_s_frequency,
+
+	/* Buffer handlers */
+	.vidioc_reqbufs		= vidioc_reqbufs,
+	.vidioc_querybuf	= vidioc_querybuf,
+	.vidioc_qbuf		= vidioc_qbuf,
+	.vidioc_dqbuf		= vidioc_dqbuf,
+
+	/* Stream on/off */
+	.vidioc_streamon	= vidioc_streamon,
+	.vidioc_streamoff	= vidioc_streamoff,
+
+	/* Control handling */
+	.vidioc_queryctrl	= vidioc_queryctrl,
+	.vidioc_g_ctrl		= vidioc_g_ctrl,
+	.vidioc_s_ctrl		= vidioc_s_ctrl,
+};
+
+static struct video_device pd_video_template = {
+	.name = "Telegent-Video",
+	.fops = &pd_video_fops,
+	.minor = -1,
+	.release = video_device_release,
+	.tvnorms = V4L2_STD_ALL,
+	.ioctl_ops = &pd_video_ioctl_ops,
+};
+
+struct video_device *vdev_init(struct poseidon *pd, struct video_device *tmp)
+{
+	struct video_device *vfd;
+
+	vfd = video_device_alloc();
+	if (vfd == NULL)
+		return NULL;
+	*vfd		= *tmp;
+	vfd->minor	= -1;
+	vfd->v4l2_dev	= &pd->v4l2_dev;
+	/*vfd->parent	= &(pd->udev->dev); */
+	vfd->release	= video_device_release;
+	video_set_drvdata(vfd, pd);
+	return vfd;
+}
+
+void destroy_video_device(struct video_device **v_dev)
+{
+	struct video_device *dev = *v_dev;
+
+	if (dev == NULL)
+		return;
+
+	if (video_is_registered(dev))
+		video_unregister_device(dev);
+	else
+		video_device_release(dev);
+	*v_dev = NULL;
+}
+
+void pd_video_exit(struct poseidon *pd)
+{
+	struct video_data *video = &pd->video_data;
+	struct vbi_data *vbi = &pd->vbi_data;
+
+	destroy_video_device(&video->v_dev);
+	destroy_video_device(&vbi->v_dev);
+	log();
+}
+
+int pd_video_init(struct poseidon *pd)
+{
+	struct video_data *video = &pd->video_data;
+	struct vbi_data *vbi	= &pd->vbi_data;
+	int ret = -ENOMEM;
+
+	video->v_dev = vdev_init(pd, &pd_video_template);
+	if (video->v_dev == NULL)
+		goto out;
+
+	ret = video_register_device(video->v_dev, VFL_TYPE_GRABBER, -1);
+	if (ret != 0)
+		goto out;
+
+	/* VBI uses the same template as video */
+	vbi->v_dev = vdev_init(pd, &pd_video_template);
+	if (vbi->v_dev == NULL) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	ret = video_register_device(vbi->v_dev, VFL_TYPE_VBI, -1);
+	if (ret != 0)
+		goto out;
+	log("register VIDEO/VBI devices");
+	return 0;
+out:
+	log("VIDEO/VBI devices register failed, : %d", ret);
+	pd_video_exit(pd);
+	return ret;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/vendorcmds.h linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/vendorcmds.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/tlg2300/vendorcmds.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tlg2300/vendorcmds.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,243 @@
+#ifndef VENDOR_CMD_H_
+#define VENDOR_CMD_H_
+
+#define BULK_ALTERNATE_IFACE		(2)
+#define ISO_3K_BULK_ALTERNATE_IFACE     (1)
+#define REQ_SET_CMD			(0X00)
+#define REQ_GET_CMD			(0X80)
+
+enum tlg__analog_audio_standard {
+	TLG_TUNE_ASTD_NONE	= 0x00000000,
+	TLG_TUNE_ASTD_A2	= 0x00000001,
+	TLG_TUNE_ASTD_NICAM	= 0x00000002,
+	TLG_TUNE_ASTD_EIAJ	= 0x00000004,
+	TLG_TUNE_ASTD_BTSC	= 0x00000008,
+	TLG_TUNE_ASTD_FM_US	= 0x00000010,
+	TLG_TUNE_ASTD_FM_EUR	= 0x00000020,
+	TLG_TUNE_ASTD_ALL	= 0x0000003f
+};
+
+/*
+ * identifiers for Custom Parameter messages.
+ * @typedef cmd_custom_param_id_t
+ */
+enum cmd_custom_param_id {
+	CUST_PARM_ID_NONE		= 0x00,
+	CUST_PARM_ID_BRIGHTNESS_CTRL	= 0x01,
+	CUST_PARM_ID_CONTRAST_CTRL	= 0x02,
+	CUST_PARM_ID_HUE_CTRL		= 0x03,
+	CUST_PARM_ID_SATURATION_CTRL	  = 0x04,
+	CUST_PARM_ID_AUDIO_SNR_THRESHOLD  = 0x10,
+	CUST_PARM_ID_AUDIO_AGC_THRESHOLD  = 0x11,
+	CUST_PARM_ID_MAX
+};
+
+struct  tuner_custom_parameter_s {
+	uint16_t	param_id;	 /*  Parameter identifier  */
+	uint16_t	param_value;	 /*  Parameter value	   */
+};
+
+struct  tuner_ber_rate_s {
+	uint32_t	ber_rate;  /*  BER sample rate in seconds   */
+};
+
+struct tuner_atv_sig_stat_s {
+	uint32_t	sig_present;
+	uint32_t	sig_locked;
+	uint32_t	sig_lock_busy;
+	uint32_t	sig_strength;	   /*  milliDb	  */
+	uint32_t	tv_audio_chan;	  /*  mono/stereo/sap*/
+	uint32_t 	mvision_stat;	   /*  macrovision status */
+};
+
+struct tuner_dtv_sig_stat_s {
+	uint32_t sig_present;   /*  Boolean*/
+	uint32_t sig_locked;	/*  Boolean */
+	uint32_t sig_lock_busy; /*  Boolean	(Can this time-out?) */
+	uint32_t sig_strength;  /*  milliDb*/
+};
+
+struct tuner_fm_sig_stat_s {
+	uint32_t sig_present;	/* Boolean*/
+	uint32_t sig_locked;	 /* Boolean */
+	uint32_t sig_lock_busy;  /* Boolean */
+	uint32_t sig_stereo_mono;/* TBD*/
+	uint32_t sig_strength;   /* milliDb*/
+};
+
+enum _tag_tlg_tune_srv_cmd {
+	TLG_TUNE_PLAY_SVC_START = 1,
+	TLG_TUNE_PLAY_SVC_STOP
+};
+
+enum  _tag_tune_atv_audio_mode_caps {
+	TLG_TUNE_TVAUDIO_MODE_MONO	= 0x00000001,
+	TLG_TUNE_TVAUDIO_MODE_STEREO	= 0x00000002,
+	TLG_TUNE_TVAUDIO_MODE_LANG_A	= 0x00000010,/* Primary language*/
+	TLG_TUNE_TVAUDIO_MODE_LANG_B	= 0x00000020,/* 2nd avail language*/
+	TLG_TUNE_TVAUDIO_MODE_LANG_C	= 0x00000040
+};
+
+
+enum   _tag_tuner_atv_audio_rates {
+	ATV_AUDIO_RATE_NONE	= 0x00,/* Audio not supported*/
+	ATV_AUDIO_RATE_32K	= 0x01,/* Audio rate = 32 KHz*/
+	ATV_AUDIO_RATE_48K	= 0x02, /* Audio rate = 48 KHz*/
+	ATV_AUDIO_RATE_31_25K	= 0x04 /* Audio rate = 31.25KHz */
+};
+
+enum  _tag_tune_atv_vid_res_caps {
+	TLG_TUNE_VID_RES_NONE	= 0x00000000,
+	TLG_TUNE_VID_RES_720	= 0x00000001,
+	TLG_TUNE_VID_RES_704	= 0x00000002,
+	TLG_TUNE_VID_RES_360	= 0x00000004
+};
+
+enum _tag_tuner_analog_video_format {
+	TLG_TUNER_VID_FORMAT_YUV	= 0x00000001,
+	TLG_TUNER_VID_FORMAT_YCRCB	= 0x00000002,
+	TLG_TUNER_VID_FORMAT_RGB_565	= 0x00000004,
+};
+
+enum  tlg_ext_audio_support {
+	TLG_EXT_AUDIO_NONE 	= 0x00,/*  No external audio input supported */
+	TLG_EXT_AUDIO_LR	= 0x01/*  LR external audio inputs supported*/
+};
+
+enum {
+	TLG_MODE_NONE			= 0x00, /* No Mode specified*/
+	TLG_MODE_ANALOG_TV		= 0x01, /* Analog Television mode*/
+	TLG_MODE_ANALOG_TV_UNCOMP	= 0x01, /* Analog Television mode*/
+	TLG_MODE_ANALOG_TV_COMP  	= 0x02, /* Analog TV mode (compressed)*/
+	TLG_MODE_FM_RADIO		= 0x04, /* FM Radio mode*/
+	TLG_MODE_DVB_T			= 0x08, /* Digital TV (DVB-T)*/
+};
+
+enum  tlg_signal_sources_t {
+	TLG_SIG_SRC_NONE	= 0x00,/* Signal source not specified */
+	TLG_SIG_SRC_ANTENNA	= 0x01,/* Signal src is: Antenna */
+	TLG_SIG_SRC_CABLE	= 0x02,/* Signal src is: Coax Cable*/
+	TLG_SIG_SRC_SVIDEO	= 0x04,/* Signal src is: S_VIDEO   */
+	TLG_SIG_SRC_COMPOSITE   = 0x08 /* Signal src is: Composite Video */
+};
+
+enum tuner_analog_video_standard {
+	TLG_TUNE_VSTD_NONE	= 0x00000000,
+	TLG_TUNE_VSTD_NTSC_M	= 0x00000001,
+	TLG_TUNE_VSTD_NTSC_M_J	= 0x00000002,/* Japan   */
+	TLG_TUNE_VSTD_PAL_B	= 0x00000010,
+	TLG_TUNE_VSTD_PAL_D	= 0x00000020,
+	TLG_TUNE_VSTD_PAL_G	= 0x00000040,
+	TLG_TUNE_VSTD_PAL_H	= 0x00000080,
+	TLG_TUNE_VSTD_PAL_I	= 0x00000100,
+	TLG_TUNE_VSTD_PAL_M	= 0x00000200,
+	TLG_TUNE_VSTD_PAL_N	= 0x00000400,
+	TLG_TUNE_VSTD_SECAM_B	= 0x00001000,
+	TLG_TUNE_VSTD_SECAM_D	= 0x00002000,
+	TLG_TUNE_VSTD_SECAM_G	= 0x00004000,
+	TLG_TUNE_VSTD_SECAM_H	= 0x00008000,
+	TLG_TUNE_VSTD_SECAM_K	= 0x00010000,
+	TLG_TUNE_VSTD_SECAM_K1	= 0x00020000,
+	TLG_TUNE_VSTD_SECAM_L	= 0x00040000,
+	TLG_TUNE_VSTD_SECAM_L1	= 0x00080000,
+	TLG_TUNE_VSTD_PAL_N_COMBO = 0x00100000
+};
+
+enum tlg_mode_caps {
+	TLG_MODE_CAPS_NONE		= 0x00,  /*  No Mode specified	*/
+	TLG_MODE_CAPS_ANALOG_TV_UNCOMP  = 0x01,  /*  Analog TV mode     */
+	TLG_MODE_CAPS_ANALOG_TV_COMP	= 0x02,  /*  Analog TV (compressed)*/
+	TLG_MODE_CAPS_FM_RADIO		= 0x04,  /*  FM Radio mode	*/
+	TLG_MODE_CAPS_DVB_T		= 0x08,  /*  Digital TV (DVB-T)	*/
+};
+
+enum poseidon_vendor_cmds {
+	LAST_CMD_STAT		= 0x00,
+	GET_CHIP_ID		= 0x01,
+	GET_FW_ID		= 0x02,
+	PRODUCT_CAPS		= 0x03,
+
+	TUNE_MODE_CAP_ATV	= 0x10,
+	TUNE_MODE_CAP_ATVCOMP	= 0X10,
+	TUNE_MODE_CAP_DVBT	= 0x10,
+	TUNE_MODE_CAP_FM	= 0x10,
+	TUNE_MODE_SELECT	= 0x11,
+	TUNE_FREQ_SELECT	= 0x12,
+	SGNL_SRC_SEL		= 0x13,
+
+	VIDEO_STD_SEL		= 0x14,
+	VIDEO_STREAM_FMT_SEL	= 0x15,
+	VIDEO_ROSOLU_AVAIL	= 0x16,
+	VIDEO_ROSOLU_SEL	= 0x17,
+	VIDEO_CONT_PROTECT	= 0x20,
+
+	VCR_TIMING_MODSEL	= 0x21,
+	EXT_AUDIO_CAP		= 0x22,
+	EXT_AUDIO_SEL		= 0x23,
+	TEST_PATTERN_SEL	= 0x24,
+	VBI_DATA_SEL		= 0x25,
+	AUDIO_SAMPLE_RATE_CAP   = 0x28,
+	AUDIO_SAMPLE_RATE_SEL   = 0x29,
+	TUNER_AUD_MODE		= 0x2a,
+	TUNER_AUD_MODE_AVAIL	= 0x2b,
+	TUNER_AUD_ANA_STD	= 0x2c,
+	TUNER_CUSTOM_PARAMETER	= 0x2f,
+
+	DVBT_TUNE_MODE_SEL	= 0x30,
+	DVBT_BANDW_CAP		= 0x31,
+	DVBT_BANDW_SEL		= 0x32,
+	DVBT_GUARD_INTERV_CAP   = 0x33,
+	DVBT_GUARD_INTERV_SEL   = 0x34,
+	DVBT_MODULATION_CAP	= 0x35,
+	DVBT_MODULATION_SEL	= 0x36,
+	DVBT_INNER_FEC_RATE_CAP = 0x37,
+	DVBT_INNER_FEC_RATE_SEL = 0x38,
+	DVBT_TRANS_MODE_CAP	= 0x39,
+	DVBT_TRANS_MODE_SEL	= 0x3a,
+	DVBT_SEARCH_RANG	= 0x3c,
+
+	TUNER_SETUP_ANALOG	= 0x40,
+	TUNER_SETUP_DIGITAL	= 0x41,
+	TUNER_SETUP_FM_RADIO	= 0x42,
+	TAKE_REQUEST		= 0x43, /* Take effect of the command */
+	PLAY_SERVICE		= 0x44, /* Play start or Play stop */
+	TUNER_STATUS		= 0x45,
+	TUNE_PROP_DVBT		= 0x46,
+	ERR_RATE_STATS		= 0x47,
+	TUNER_BER_RATE		= 0x48,
+
+	SCAN_CAPS		= 0x50,
+	SCAN_SETUP		= 0x51,
+	SCAN_SERVICE		= 0x52,
+	SCAN_STATS		= 0x53,
+
+	PID_SET			= 0x58,
+	PID_UNSET		= 0x59,
+	PID_LIST		= 0x5a,
+
+	IRD_CAP			= 0x60,
+	IRD_MODE_SEL		= 0x61,
+	IRD_SETUP		= 0x62,
+
+	PTM_MODE_CAP		= 0x70,
+	PTM_MODE_SEL		= 0x71,
+	PTM_SERVICE		= 0x72,
+	TUNER_REG_SCRIPT	= 0x73,
+	CMD_CHIP_RST		= 0x74,
+};
+
+enum tlg_bw {
+	TLG_BW_5 = 5,
+	TLG_BW_6 = 6,
+	TLG_BW_7 = 7,
+	TLG_BW_8 = 8,
+	TLG_BW_12 = 12,
+	TLG_BW_15 = 15
+};
+
+struct cmd_firmware_vers_s {
+	uint8_t	 fw_rev_major;
+	uint8_t	 fw_rev_minor;
+	uint16_t fw_patch;
+};
+#endif /* VENDOR_CMD_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tlv320aic23b.c linux-libre-2.6.34-gnu1/drivers/media/video/tlv320aic23b.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/tlv320aic23b.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tlv320aic23b.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tuner-core.c linux-libre-2.6.34-gnu1/drivers/media/video/tuner-core.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/tuner-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tuner-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -1078,6 +1078,7 @@ static int tuner_probe(struct i2c_client
 
 				goto register_client;
 			}
+			kfree(t);
 			return -ENODEV;
 		case 0x42:
 		case 0x43:
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tveeprom.c linux-libre-2.6.34-gnu1/drivers/media/video/tveeprom.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/tveeprom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tveeprom.c	2010-05-16 17:17:36.000000000 -0400
@@ -680,10 +680,7 @@ void tveeprom_hauppauge_analog(struct i2
 	tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
 		tvee->model, tvee->rev_str, tvee->serial_number);
 	if (tvee->has_MAC_address == 1)
-		tveeprom_info("MAC address is %02X-%02X-%02X-%02X-%02X-%02X\n",
-			tvee->MAC_address[0], tvee->MAC_address[1],
-			tvee->MAC_address[2], tvee->MAC_address[3],
-			tvee->MAC_address[4], tvee->MAC_address[5]);
+		tveeprom_info("MAC address is %pM\n", tvee->MAC_address);
 	tveeprom_info("tuner model is %s (idx %d, type %d)\n",
 		t_name1, tuner1, tvee->tuner_type);
 	tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tvp514x.c linux-libre-2.6.34-gnu1/drivers/media/video/tvp514x.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/tvp514x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tvp514x.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/videodev2.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tvp5150.c linux-libre-2.6.34-gnu1/drivers/media/video/tvp5150.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/tvp5150.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tvp5150.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/delay.h>
 #include <media/v4l2-device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tvp7002.c linux-libre-2.6.34-gnu1/drivers/media/video/tvp7002.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/tvp7002.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tvp7002.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1188 @@
+/* Texas Instruments Triple 8-/10-BIT 165-/110-MSPS Video and Graphics
+ * Digitizer with Horizontal PLL registers
+ *
+ * Copyright (C) 2009 Texas Instruments Inc
+ * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>
+ *
+ * This code is partially based upon the TVP5150 driver
+ * written by Mauro Carvalho Chehab (mchehab@infradead.org),
+ * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com>
+ * and the TVP7002 driver in the TI LSP 2.10.00.14. Revisions by
+ * Muralidharan Karicheri and Snehaprabha Narnakaje (TI).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the 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/delay.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <media/tvp7002.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-common.h>
+#include "tvp7002_reg.h"
+
+MODULE_DESCRIPTION("TI TVP7002 Video and Graphics Digitizer driver");
+MODULE_AUTHOR("Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>");
+MODULE_LICENSE("GPL");
+
+/* Module Name */
+#define TVP7002_MODULE_NAME	"tvp7002"
+
+/* I2C retry attempts */
+#define I2C_RETRY_COUNT		(5)
+
+/* End of registers */
+#define TVP7002_EOR		0x5c
+
+/* Read write definition for registers */
+#define TVP7002_READ		0
+#define TVP7002_WRITE		1
+#define TVP7002_RESERVED	2
+
+/* Interlaced vs progressive mask and shift */
+#define TVP7002_IP_SHIFT	5
+#define TVP7002_INPR_MASK	(0x01 << TVP7002_IP_SHIFT)
+
+/* Shift for CPL and LPF registers */
+#define TVP7002_CL_SHIFT	8
+#define TVP7002_CL_MASK		0x0f
+
+/* Debug functions */
+static int debug;
+module_param(debug, bool, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-2)");
+
+/* Structure for register values */
+struct i2c_reg_value {
+	u8 reg;
+	u8 value;
+	u8 type;
+};
+
+/*
+ * Register default values (according to tvp7002 datasheet)
+ * In the case of read-only registers, the value (0xff) is
+ * never written. R/W functionality is controlled by the
+ * writable bit in the register struct definition.
+ */
+static const struct i2c_reg_value tvp7002_init_default[] = {
+	{ TVP7002_CHIP_REV, 0xff, TVP7002_READ },
+	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0x67, TVP7002_WRITE },
+	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0x20, TVP7002_WRITE },
+	{ TVP7002_HPLL_CRTL, 0xa0, TVP7002_WRITE },
+	{ TVP7002_HPLL_PHASE_SEL, 0x80, TVP7002_WRITE },
+	{ TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
+	{ TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
+	{ TVP7002_HSYNC_OUT_W, 0x60, TVP7002_WRITE },
+	{ TVP7002_B_FINE_GAIN, 0x00, TVP7002_WRITE },
+	{ TVP7002_G_FINE_GAIN, 0x00, TVP7002_WRITE },
+	{ TVP7002_R_FINE_GAIN, 0x00, TVP7002_WRITE },
+	{ TVP7002_B_FINE_OFF_MSBS, 0x80, TVP7002_WRITE },
+	{ TVP7002_G_FINE_OFF_MSBS, 0x80, TVP7002_WRITE },
+	{ TVP7002_R_FINE_OFF_MSBS, 0x80, TVP7002_WRITE },
+	{ TVP7002_SYNC_CTL_1, 0x20, TVP7002_WRITE },
+	{ TVP7002_HPLL_AND_CLAMP_CTL, 0x2e, TVP7002_WRITE },
+	{ TVP7002_SYNC_ON_G_THRS, 0x5d, TVP7002_WRITE },
+	{ TVP7002_SYNC_SEPARATOR_THRS, 0x47, TVP7002_WRITE },
+	{ TVP7002_HPLL_PRE_COAST, 0x00, TVP7002_WRITE },
+	{ TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
+	{ TVP7002_SYNC_DETECT_STAT, 0xff, TVP7002_READ },
+	{ TVP7002_OUT_FORMATTER, 0x47, TVP7002_WRITE },
+	{ TVP7002_MISC_CTL_1, 0x01, TVP7002_WRITE },
+	{ TVP7002_MISC_CTL_2, 0x00, TVP7002_WRITE },
+	{ TVP7002_MISC_CTL_3, 0x01, TVP7002_WRITE },
+	{ TVP7002_IN_MUX_SEL_1, 0x00, TVP7002_WRITE },
+	{ TVP7002_IN_MUX_SEL_2, 0x67, TVP7002_WRITE },
+	{ TVP7002_B_AND_G_COARSE_GAIN, 0x77, TVP7002_WRITE },
+	{ TVP7002_R_COARSE_GAIN, 0x07, TVP7002_WRITE },
+	{ TVP7002_FINE_OFF_LSBS, 0x00, TVP7002_WRITE },
+	{ TVP7002_B_COARSE_OFF, 0x10, TVP7002_WRITE },
+	{ TVP7002_G_COARSE_OFF, 0x10, TVP7002_WRITE },
+	{ TVP7002_R_COARSE_OFF, 0x10, TVP7002_WRITE },
+	{ TVP7002_HSOUT_OUT_START, 0x08, TVP7002_WRITE },
+	{ TVP7002_MISC_CTL_4, 0x00, TVP7002_WRITE },
+	{ TVP7002_B_DGTL_ALC_OUT_LSBS, 0xff, TVP7002_READ },
+	{ TVP7002_G_DGTL_ALC_OUT_LSBS, 0xff, TVP7002_READ },
+	{ TVP7002_R_DGTL_ALC_OUT_LSBS, 0xff, TVP7002_READ },
+	{ TVP7002_AUTO_LVL_CTL_ENABLE, 0x80, TVP7002_WRITE },
+	{ TVP7002_DGTL_ALC_OUT_MSBS, 0xff, TVP7002_READ },
+	{ TVP7002_AUTO_LVL_CTL_FILTER, 0x53, TVP7002_WRITE },
+	{ 0x29, 0x08, TVP7002_RESERVED },
+	{ TVP7002_FINE_CLAMP_CTL, 0x07, TVP7002_WRITE },
+	/* PWR_CTL is controlled only by the probe and reset functions */
+	{ TVP7002_PWR_CTL, 0x00, TVP7002_RESERVED },
+	{ TVP7002_ADC_SETUP, 0x50, TVP7002_WRITE },
+	{ TVP7002_COARSE_CLAMP_CTL, 0x00, TVP7002_WRITE },
+	{ TVP7002_SOG_CLAMP, 0x80, TVP7002_WRITE },
+	{ TVP7002_RGB_COARSE_CLAMP_CTL, 0x00, TVP7002_WRITE },
+	{ TVP7002_SOG_COARSE_CLAMP_CTL, 0x04, TVP7002_WRITE },
+	{ TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
+	{ 0x32, 0x18, TVP7002_RESERVED },
+	{ 0x33, 0x60, TVP7002_RESERVED },
+	{ TVP7002_MVIS_STRIPPER_W, 0xff, TVP7002_RESERVED },
+	{ TVP7002_VSYNC_ALGN, 0x10, TVP7002_WRITE },
+	{ TVP7002_SYNC_BYPASS, 0x00, TVP7002_WRITE },
+	{ TVP7002_L_FRAME_STAT_LSBS, 0xff, TVP7002_READ },
+	{ TVP7002_L_FRAME_STAT_MSBS, 0xff, TVP7002_READ },
+	{ TVP7002_CLK_L_STAT_LSBS, 0xff, TVP7002_READ },
+	{ TVP7002_CLK_L_STAT_MSBS, 0xff, TVP7002_READ },
+	{ TVP7002_HSYNC_W, 0xff, TVP7002_READ },
+	{ TVP7002_VSYNC_W, 0xff, TVP7002_READ },
+	{ TVP7002_L_LENGTH_TOL, 0x03, TVP7002_WRITE },
+	{ 0x3e, 0x60, TVP7002_RESERVED },
+	{ TVP7002_VIDEO_BWTH_CTL, 0x01, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_LSBS, 0x01, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_MSBS, 0x2c, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x06, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x2c, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_START_L_OFF, 0x05, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_DURATION, 0x1e, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
+	{ TVP7002_FBIT_F_0_START_L_OFF, 0x00, TVP7002_WRITE },
+	{ TVP7002_FBIT_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
+	{ TVP7002_YUV_Y_G_COEF_LSBS, 0xe3, TVP7002_WRITE },
+	{ TVP7002_YUV_Y_G_COEF_MSBS, 0x16, TVP7002_WRITE },
+	{ TVP7002_YUV_Y_B_COEF_LSBS, 0x4f, TVP7002_WRITE },
+	{ TVP7002_YUV_Y_B_COEF_MSBS, 0x02, TVP7002_WRITE },
+	{ TVP7002_YUV_Y_R_COEF_LSBS, 0xce, TVP7002_WRITE },
+	{ TVP7002_YUV_Y_R_COEF_MSBS, 0x06, TVP7002_WRITE },
+	{ TVP7002_YUV_U_G_COEF_LSBS, 0xab, TVP7002_WRITE },
+	{ TVP7002_YUV_U_G_COEF_MSBS, 0xf3, TVP7002_WRITE },
+	{ TVP7002_YUV_U_B_COEF_LSBS, 0x00, TVP7002_WRITE },
+	{ TVP7002_YUV_U_B_COEF_MSBS, 0x10, TVP7002_WRITE },
+	{ TVP7002_YUV_U_R_COEF_LSBS, 0x55, TVP7002_WRITE },
+	{ TVP7002_YUV_U_R_COEF_MSBS, 0xfc, TVP7002_WRITE },
+	{ TVP7002_YUV_V_G_COEF_LSBS, 0x78, TVP7002_WRITE },
+	{ TVP7002_YUV_V_G_COEF_MSBS, 0xf1, TVP7002_WRITE },
+	{ TVP7002_YUV_V_B_COEF_LSBS, 0x88, TVP7002_WRITE },
+	{ TVP7002_YUV_V_B_COEF_MSBS, 0xfe, TVP7002_WRITE },
+	{ TVP7002_YUV_V_R_COEF_LSBS, 0x00, TVP7002_WRITE },
+	{ TVP7002_YUV_V_R_COEF_MSBS, 0x10, TVP7002_WRITE },
+	/* This signals end of register values */
+	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
+};
+
+/* Register parameters for 480P */
+static const struct i2c_reg_value tvp7002_parms_480P[] = {
+	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0x35, TVP7002_WRITE },
+	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0x0a, TVP7002_WRITE },
+	{ TVP7002_HPLL_CRTL, 0x02, TVP7002_WRITE },
+	{ TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_LSBS, 0x91, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_MSBS, 0x00, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x0B, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x00, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_START_L_OFF, 0x03, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_START_L_OFF, 0x01, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_DURATION, 0x13, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_DURATION, 0x13, TVP7002_WRITE },
+	{ TVP7002_ALC_PLACEMENT, 0x18, TVP7002_WRITE },
+	{ TVP7002_CLAMP_START, 0x06, TVP7002_WRITE },
+	{ TVP7002_CLAMP_W, 0x10, TVP7002_WRITE },
+	{ TVP7002_HPLL_PRE_COAST, 0x03, TVP7002_WRITE },
+	{ TVP7002_HPLL_POST_COAST, 0x03, TVP7002_WRITE },
+	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
+};
+
+/* Register parameters for 576P */
+static const struct i2c_reg_value tvp7002_parms_576P[] = {
+	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0x36, TVP7002_WRITE },
+	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0x00, TVP7002_WRITE },
+	{ TVP7002_HPLL_CRTL, 0x18, TVP7002_WRITE },
+	{ TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_LSBS, 0x9B, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_MSBS, 0x00, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x0F, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x00, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_START_L_OFF, 0x00, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_DURATION, 0x2D, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
+	{ TVP7002_ALC_PLACEMENT, 0x18, TVP7002_WRITE },
+	{ TVP7002_CLAMP_START, 0x06, TVP7002_WRITE },
+	{ TVP7002_CLAMP_W, 0x10, TVP7002_WRITE },
+	{ TVP7002_HPLL_PRE_COAST, 0x03, TVP7002_WRITE },
+	{ TVP7002_HPLL_POST_COAST, 0x03, TVP7002_WRITE },
+	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
+};
+
+/* Register parameters for 1080I60 */
+static const struct i2c_reg_value tvp7002_parms_1080I60[] = {
+	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0x89, TVP7002_WRITE },
+	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0x08, TVP7002_WRITE },
+	{ TVP7002_HPLL_CRTL, 0x98, TVP7002_WRITE },
+	{ TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_LSBS, 0x06, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x8a, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x08, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_START_L_OFF, 0x02, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_START_L_OFF, 0x02, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_DURATION, 0x16, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_DURATION, 0x17, TVP7002_WRITE },
+	{ TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
+	{ TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
+	{ TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
+	{ TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
+	{ TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
+	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
+};
+
+/* Register parameters for 1080P60 */
+static const struct i2c_reg_value tvp7002_parms_1080P60[] = {
+	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0x89, TVP7002_WRITE },
+	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0x08, TVP7002_WRITE },
+	{ TVP7002_HPLL_CRTL, 0xE0, TVP7002_WRITE },
+	{ TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_LSBS, 0x06, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x8a, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x08, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_START_L_OFF, 0x02, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_START_L_OFF, 0x02, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_DURATION, 0x16, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_DURATION, 0x17, TVP7002_WRITE },
+	{ TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
+	{ TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
+	{ TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
+	{ TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
+	{ TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
+	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
+};
+
+/* Register parameters for 1080I50 */
+static const struct i2c_reg_value tvp7002_parms_1080I50[] = {
+	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0xa5, TVP7002_WRITE },
+	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0x00, TVP7002_WRITE },
+	{ TVP7002_HPLL_CRTL, 0x98, TVP7002_WRITE },
+	{ TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_LSBS, 0x06, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x8a, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x08, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_START_L_OFF, 0x02, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_START_L_OFF, 0x02, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_DURATION, 0x16, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_DURATION, 0x17, TVP7002_WRITE },
+	{ TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
+	{ TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
+	{ TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
+	{ TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
+	{ TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
+	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
+};
+
+/* Register parameters for 720P60 */
+static const struct i2c_reg_value tvp7002_parms_720P60[] = {
+	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0x67, TVP7002_WRITE },
+	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0x02, TVP7002_WRITE },
+	{ TVP7002_HPLL_CRTL, 0xa0, TVP7002_WRITE },
+	{ TVP7002_HPLL_PHASE_SEL, 0x16, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_LSBS, 0x47, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x4B, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x06, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_START_L_OFF, 0x05, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_DURATION, 0x2D, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
+	{ TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
+	{ TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
+	{ TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
+	{ TVP7002_HPLL_PRE_COAST, 0x00, TVP7002_WRITE },
+	{ TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
+	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
+};
+
+/* Register parameters for 720P50 */
+static const struct i2c_reg_value tvp7002_parms_720P50[] = {
+	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0x7b, TVP7002_WRITE },
+	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0x0c, TVP7002_WRITE },
+	{ TVP7002_HPLL_CRTL, 0x98, TVP7002_WRITE },
+	{ TVP7002_HPLL_PHASE_SEL, 0x16, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_LSBS, 0x47, TVP7002_WRITE },
+	{ TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x4B, TVP7002_WRITE },
+	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x06, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_START_L_OFF, 0x05, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_0_DURATION, 0x2D, TVP7002_WRITE },
+	{ TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
+	{ TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
+	{ TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
+	{ TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
+	{ TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
+	{ TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
+	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
+};
+
+/* Struct list for available formats */
+static const struct v4l2_fmtdesc tvp7002_fmt_list[] = {
+	{
+	 .index = 0,
+	 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+	 .flags = 0,
+	 .description = "8-bit UYVY 4:2:2 Format",
+	 .pixelformat = V4L2_PIX_FMT_UYVY,
+	},
+};
+
+#define NUM_FORMATS		ARRAY_SIZE(tvp7002_fmt_list)
+
+/* Preset definition for handling device operation */
+struct tvp7002_preset_definition {
+	u32 preset;
+	const struct i2c_reg_value *p_settings;
+	enum v4l2_colorspace color_space;
+	enum v4l2_field scanmode;
+	u16 progressive;
+	u16 lines_per_frame;
+	u16 cpl_min;
+	u16 cpl_max;
+};
+
+/* Struct list for digital video presets */
+static const struct tvp7002_preset_definition tvp7002_presets[] = {
+	{
+		V4L2_DV_720P60,
+		tvp7002_parms_720P60,
+		V4L2_COLORSPACE_REC709,
+		V4L2_FIELD_NONE,
+		1,
+		0x2EE,
+		135,
+		153
+	},
+	{
+		V4L2_DV_1080I60,
+		tvp7002_parms_1080I60,
+		V4L2_COLORSPACE_REC709,
+		V4L2_FIELD_INTERLACED,
+		0,
+		0x465,
+		181,
+		205
+	},
+	{
+		V4L2_DV_1080I50,
+		tvp7002_parms_1080I50,
+		V4L2_COLORSPACE_REC709,
+		V4L2_FIELD_INTERLACED,
+		0,
+		0x465,
+		217,
+		245
+	},
+	{
+		V4L2_DV_720P50,
+		tvp7002_parms_720P50,
+		V4L2_COLORSPACE_REC709,
+		V4L2_FIELD_NONE,
+		1,
+		0x2EE,
+		163,
+		183
+	},
+	{
+		V4L2_DV_1080P60,
+		tvp7002_parms_1080P60,
+		V4L2_COLORSPACE_REC709,
+		V4L2_FIELD_NONE,
+		1,
+		0x465,
+		90,
+		102
+	},
+	{
+		V4L2_DV_480P59_94,
+		tvp7002_parms_480P,
+		V4L2_COLORSPACE_SMPTE170M,
+		V4L2_FIELD_NONE,
+		1,
+		0x20D,
+		0xffff,
+		0xffff
+	},
+	{
+		V4L2_DV_576P50,
+		tvp7002_parms_576P,
+		V4L2_COLORSPACE_SMPTE170M,
+		V4L2_FIELD_NONE,
+		1,
+		0x271,
+		0xffff,
+		0xffff
+	}
+};
+
+#define NUM_PRESETS	ARRAY_SIZE(tvp7002_presets)
+
+/* Device definition */
+struct tvp7002 {
+	struct v4l2_subdev sd;
+	const struct tvp7002_config *pdata;
+
+	int ver;
+	int streaming;
+
+	struct v4l2_pix_format pix;
+	const struct tvp7002_preset_definition *current_preset;
+	u8 gain;
+};
+
+/*
+ * to_tvp7002 - Obtain device handler TVP7002
+ * @sd: ptr to v4l2_subdev struct
+ *
+ * Returns device handler tvp7002.
+ */
+static inline struct tvp7002 *to_tvp7002(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct tvp7002, sd);
+}
+
+/*
+ * tvp7002_read - Read a value from a register in an TVP7002
+ * @sd: ptr to v4l2_subdev struct
+ * @reg: TVP7002 register address
+ * @dst: pointer to 8-bit destination
+ *
+ * Returns value read if successful, or non-zero (-1) otherwise.
+ */
+static int tvp7002_read(struct v4l2_subdev *sd, u8 addr, u8 *dst)
+{
+	struct i2c_client *c = v4l2_get_subdevdata(sd);
+	int retry;
+	int error;
+
+	for (retry = 0; retry < I2C_RETRY_COUNT; retry++) {
+		error = i2c_smbus_read_byte_data(c, addr);
+
+		if (error >= 0) {
+			*dst = (u8)error;
+			return 0;
+		}
+
+		msleep_interruptible(10);
+	}
+	v4l2_err(sd, "TVP7002 read error %d\n", error);
+	return error;
+}
+
+/*
+ * tvp7002_read_err() - Read a register value with error code
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @reg: destination register
+ * @val: value to be read
+ * @error: pointer to error value
+ *
+ * Read a value in a register and save error value in pointer.
+ * Also update the register table if successful
+ */
+static inline void tvp7002_read_err(struct v4l2_subdev *sd, u8 reg,
+							u8 *dst, int *err)
+{
+	if (!*err)
+		*err = tvp7002_read(sd, reg, dst);
+}
+
+/*
+ * tvp7002_write() - Write a value to a register in TVP7002
+ * @sd: ptr to v4l2_subdev struct
+ * @addr: TVP7002 register address
+ * @value: value to be written to the register
+ *
+ * Write a value to a register in an TVP7002 decoder device.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int tvp7002_write(struct v4l2_subdev *sd, u8 addr, u8 value)
+{
+	struct i2c_client *c;
+	int retry;
+	int error;
+
+	c = v4l2_get_subdevdata(sd);
+
+	for (retry = 0; retry < I2C_RETRY_COUNT; retry++) {
+		error = i2c_smbus_write_byte_data(c, addr, value);
+
+		if (error >= 0)
+			return 0;
+
+		v4l2_warn(sd, "Write: retry ... %d\n", retry);
+		msleep_interruptible(10);
+	}
+	v4l2_err(sd, "TVP7002 write error %d\n", error);
+	return error;
+}
+
+/*
+ * tvp7002_write_err() - Write a register value with error code
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @reg: destination register
+ * @val: value to be written
+ * @error: pointer to error value
+ *
+ * Write a value in a register and save error value in pointer.
+ * Also update the register table if successful
+ */
+static inline void tvp7002_write_err(struct v4l2_subdev *sd, u8 reg,
+							u8 val, int *err)
+{
+	if (!*err)
+		*err = tvp7002_write(sd, reg, val);
+}
+
+/*
+ * tvp7002_g_chip_ident() - Get chip identification number
+ * @sd: ptr to v4l2_subdev struct
+ * @chip: ptr to v4l2_dbg_chip_ident struct
+ *
+ * Obtains the chip's identification number.
+ * Returns zero or -EINVAL if read operation fails.
+ */
+static int tvp7002_g_chip_ident(struct v4l2_subdev *sd,
+					struct v4l2_dbg_chip_ident *chip)
+{
+	u8 rev;
+	int error;
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	error = tvp7002_read(sd, TVP7002_CHIP_REV, &rev);
+
+	if (error < 0)
+		return error;
+
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVP7002, rev);
+}
+
+/*
+ * tvp7002_write_inittab() - Write initialization values
+ * @sd: ptr to v4l2_subdev struct
+ * @regs: ptr to i2c_reg_value struct
+ *
+ * Write initialization values.
+ * Returns zero or -EINVAL if read operation fails.
+ */
+static int tvp7002_write_inittab(struct v4l2_subdev *sd,
+					const struct i2c_reg_value *regs)
+{
+	int error = 0;
+
+	/* Initialize the first (defined) registers */
+	while (TVP7002_EOR != regs->reg) {
+		if (TVP7002_WRITE == regs->type)
+			tvp7002_write_err(sd, regs->reg, regs->value, &error);
+		regs++;
+	}
+
+	return error;
+}
+
+/*
+ * tvp7002_s_dv_preset() - Set digital video preset
+ * @sd: ptr to v4l2_subdev struct
+ * @std: ptr to v4l2_dv_preset struct
+ *
+ * Set the digital video preset for a TVP7002 decoder device.
+ * Returns zero when successful or -EINVAL if register access fails.
+ */
+static int tvp7002_s_dv_preset(struct v4l2_subdev *sd,
+					struct v4l2_dv_preset *dv_preset)
+{
+	struct tvp7002 *device = to_tvp7002(sd);
+	u32 preset;
+	int i;
+
+	for (i = 0; i < NUM_PRESETS; i++) {
+		preset = tvp7002_presets[i].preset;
+		if (preset == dv_preset->preset) {
+			device->current_preset = &tvp7002_presets[i];
+			return tvp7002_write_inittab(sd, tvp7002_presets[i].p_settings);
+		}
+	}
+
+	return -EINVAL;
+}
+
+/*
+ * tvp7002_g_ctrl() - Get a control
+ * @sd: ptr to v4l2_subdev struct
+ * @ctrl: ptr to v4l2_control struct
+ *
+ * Get a control for a TVP7002 decoder device.
+ * Returns zero when successful or -EINVAL if register access fails.
+ */
+static int tvp7002_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct tvp7002 *device = to_tvp7002(sd);
+
+	switch (ctrl->id) {
+	case V4L2_CID_GAIN:
+		ctrl->value = device->gain;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+/*
+ * tvp7002_s_ctrl() - Set a control
+ * @sd: ptr to v4l2_subdev struct
+ * @ctrl: ptr to v4l2_control struct
+ *
+ * Set a control in TVP7002 decoder device.
+ * Returns zero when successful or -EINVAL if register access fails.
+ */
+static int tvp7002_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct tvp7002 *device = to_tvp7002(sd);
+	int error = 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_GAIN:
+		tvp7002_write_err(sd, TVP7002_R_FINE_GAIN,
+						ctrl->value & 0xff, &error);
+		tvp7002_write_err(sd, TVP7002_G_FINE_GAIN,
+						ctrl->value & 0xff, &error);
+		tvp7002_write_err(sd, TVP7002_B_FINE_GAIN,
+						ctrl->value & 0xff, &error);
+
+		if (error < 0)
+			return error;
+
+		/* Set only after knowing there is no error */
+		device->gain = ctrl->value & 0xff;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+/*
+ * tvp7002_queryctrl() - Query a control
+ * @sd: ptr to v4l2_subdev struct
+ * @ctrl: ptr to v4l2_queryctrl struct
+ *
+ * Query a control of a TVP7002 decoder device.
+ * Returns zero when successful or -EINVAL if register read fails.
+ */
+static int tvp7002_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+	switch (qc->id) {
+	case V4L2_CID_GAIN:
+		/*
+		 * Gain is supported [0-255, default=0, step=1]
+		 */
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0);
+	default:
+		return -EINVAL;
+	}
+}
+
+/*
+ * tvp7002_try_fmt_cap() - V4L2 decoder interface handler for try_fmt
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure
+ *
+ * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This
+ * ioctl is used to negotiate the image capture size and pixel format
+ * without actually making it take effect.
+ */
+static int tvp7002_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct tvp7002 *device = to_tvp7002(sd);
+	struct v4l2_dv_enum_preset e_preset;
+	struct v4l2_pix_format *pix;
+	int error = 0;
+
+	pix = &f->fmt.pix;
+
+	/* Calculate height and width based on current standard */
+	error = v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset);
+	if (error)
+		return -EINVAL;
+
+	pix->width = e_preset.width;
+	pix->height = e_preset.height;
+	pix->pixelformat = V4L2_PIX_FMT_UYVY;
+	pix->field = device->current_preset->scanmode;
+	pix->bytesperline = pix->width * 2;
+	pix->sizeimage = pix->bytesperline * pix->height;
+	pix->colorspace = device->current_preset->color_space;
+	pix->priv = 0;
+
+	v4l2_dbg(1, debug, sd, "Try FMT: pixelformat - %s, bytesperline - %d"
+			"Width - %d, Height - %d", "8-bit UYVY 4:2:2 Format",
+			pix->bytesperline, pix->width, pix->height);
+	return error;
+}
+
+/*
+ * tvp7002_s_fmt() - V4L2 decoder interface handler for s_fmt
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure
+ *
+ * If the requested format is supported, configures the HW to use that
+ * format, returns error code if format not supported or HW can't be
+ * correctly configured.
+ */
+static int tvp7002_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct tvp7002 *decoder = to_tvp7002(sd);
+	int rval;
+
+	rval = tvp7002_try_fmt_cap(sd, f);
+	if (!rval)
+		decoder->pix = f->fmt.pix;
+	return rval;
+}
+
+/*
+ * tvp7002_g_fmt() - V4L2 decoder interface handler for tvp7002_g_fmt
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @f: pointer to standard V4L2 v4l2_format structure
+ *
+ * Returns the decoder's current pixel format in the v4l2_format
+ * parameter.
+ */
+static int tvp7002_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct tvp7002 *decoder = to_tvp7002(sd);
+
+	f->fmt.pix = decoder->pix;
+
+	v4l2_dbg(1, debug, sd, "Current FMT: bytesperline - %d"
+			"Width - %d, Height - %d",
+			decoder->pix.bytesperline,
+			decoder->pix.width, decoder->pix.height);
+	return 0;
+}
+
+/*
+ * tvp7002_query_dv_preset() - query DV preset
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @std_id: standard V4L2 v4l2_dv_preset
+ *
+ * Returns the current DV preset by TVP7002. If no active input is
+ * detected, returns -EINVAL
+ */
+static int tvp7002_query_dv_preset(struct v4l2_subdev *sd,
+						struct v4l2_dv_preset *qpreset)
+{
+	const struct tvp7002_preset_definition *presets = tvp7002_presets;
+	struct v4l2_dv_enum_preset e_preset;
+	struct tvp7002 *device;
+	u8 progressive;
+	u32 lpfr;
+	u32 cpln;
+	int error = 0;
+	u8 lpf_lsb;
+	u8 lpf_msb;
+	u8 cpl_lsb;
+	u8 cpl_msb;
+	int index;
+
+	device = to_tvp7002(sd);
+
+	/* Read standards from device registers */
+	tvp7002_read_err(sd, TVP7002_L_FRAME_STAT_LSBS, &lpf_lsb, &error);
+	tvp7002_read_err(sd, TVP7002_L_FRAME_STAT_MSBS, &lpf_msb, &error);
+
+	if (error < 0)
+		return error;
+
+	tvp7002_read_err(sd, TVP7002_CLK_L_STAT_LSBS, &cpl_lsb, &error);
+	tvp7002_read_err(sd, TVP7002_CLK_L_STAT_MSBS, &cpl_msb, &error);
+
+	if (error < 0)
+		return error;
+
+	/* Get lines per frame, clocks per line and interlaced/progresive */
+	lpfr = lpf_lsb | ((TVP7002_CL_MASK & lpf_msb) << TVP7002_CL_SHIFT);
+	cpln = cpl_lsb | ((TVP7002_CL_MASK & cpl_msb) << TVP7002_CL_SHIFT);
+	progressive = (lpf_msb & TVP7002_INPR_MASK) >> TVP7002_IP_SHIFT;
+
+	/* Do checking of video modes */
+	for (index = 0; index < NUM_PRESETS; index++, presets++)
+		if (lpfr  == presets->lines_per_frame &&
+			progressive == presets->progressive) {
+			if (presets->cpl_min == 0xffff)
+				break;
+			if (cpln >= presets->cpl_min && cpln <= presets->cpl_max)
+				break;
+		}
+
+	if (index == NUM_PRESETS) {
+		v4l2_err(sd, "querystd error, lpf = %x, cpl = %x\n",
+								lpfr, cpln);
+		return -EINVAL;
+	}
+
+	if (v4l_fill_dv_preset_info(presets->preset, &e_preset))
+		return -EINVAL;
+
+	/* Set values in found preset */
+	qpreset->preset = presets->preset;
+
+	/* Update lines per frame and clocks per line info */
+	v4l2_dbg(1, debug, sd, "Current preset: %d %d",
+					e_preset.width, e_preset.height);
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+/*
+ * tvp7002_g_register() - Get the value of a register
+ * @sd: ptr to v4l2_subdev struct
+ * @vreg: ptr to v4l2_dbg_register struct
+ *
+ * Get the value of a TVP7002 decoder device register.
+ * Returns zero when successful, -EINVAL if register read fails or
+ * access to I2C client fails, -EPERM if the call is not allowed
+ * by diabled CAP_SYS_ADMIN.
+ */
+static int tvp7002_g_register(struct v4l2_subdev *sd,
+						struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	u8 val;
+	int ret;
+
+	if (!v4l2_chip_match_i2c_client(client, &reg->match))
+		return -EINVAL;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	ret = tvp7002_read(sd, reg->reg & 0xff, &val);
+	reg->val = val;
+	return ret;
+}
+
+/*
+ * tvp7002_s_register() - set a control
+ * @sd: ptr to v4l2_subdev struct
+ * @ctrl: ptr to v4l2_control struct
+ *
+ * Get the value of a TVP7002 decoder device register.
+ * Returns zero when successful, -EINVAL if register read fails or
+ * -EPERM if call not allowed.
+ */
+static int tvp7002_s_register(struct v4l2_subdev *sd,
+						struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	if (!v4l2_chip_match_i2c_client(client, &reg->match))
+		return -EINVAL;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	return tvp7002_write(sd, reg->reg & 0xff, reg->val & 0xff);
+}
+#endif
+
+/*
+ * tvp7002_enum_fmt() - Enum supported formats
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @enable: pointer to format struct
+ *
+ * Enumerate supported formats.
+ */
+
+static int tvp7002_enum_fmt(struct v4l2_subdev *sd,
+						struct v4l2_fmtdesc *fmtdesc)
+{
+	/* Check requested format index is within range */
+	if (fmtdesc->index < 0 || fmtdesc->index >= NUM_FORMATS)
+		return -EINVAL;
+	*fmtdesc = tvp7002_fmt_list[fmtdesc->index];
+
+	return 0;
+}
+
+/*
+ * tvp7002_s_stream() - V4L2 decoder i/f handler for s_stream
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @enable: streaming enable or disable
+ *
+ * Sets streaming to enable or disable, if possible.
+ */
+static int tvp7002_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct tvp7002 *device = to_tvp7002(sd);
+	int error = 0;
+
+	if (device->streaming == enable)
+		return 0;
+
+	if (enable) {
+		/* Set output state on (low impedance means stream on) */
+		error = tvp7002_write(sd, TVP7002_MISC_CTL_2, 0x00);
+		device->streaming = enable;
+	} else {
+		/* Set output state off (high impedance means stream off) */
+		error = tvp7002_write(sd, TVP7002_MISC_CTL_2, 0x03);
+		if (error)
+			v4l2_dbg(1, debug, sd, "Unable to stop streaming\n");
+
+		device->streaming = enable;
+	}
+
+	return error;
+}
+
+/*
+ * tvp7002_log_status() - Print information about register settings
+ * @sd: ptr to v4l2_subdev struct
+ *
+ * Log register values of a TVP7002 decoder device.
+ * Returns zero or -EINVAL if read operation fails.
+ */
+static int tvp7002_log_status(struct v4l2_subdev *sd)
+{
+	const struct tvp7002_preset_definition *presets = tvp7002_presets;
+	struct tvp7002 *device = to_tvp7002(sd);
+	struct v4l2_dv_enum_preset e_preset;
+	struct v4l2_dv_preset detected;
+	int i;
+
+	detected.preset = V4L2_DV_INVALID;
+	/* Find my current standard*/
+	tvp7002_query_dv_preset(sd, &detected);
+
+	/* Print standard related code values */
+	for (i = 0; i < NUM_PRESETS; i++, presets++)
+		if (presets->preset == detected.preset)
+			break;
+
+	if (v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset))
+		return -EINVAL;
+
+	v4l2_info(sd, "Selected DV Preset: %s\n", e_preset.name);
+	v4l2_info(sd, "   Pixels per line: %u\n", e_preset.width);
+	v4l2_info(sd, "   Lines per frame: %u\n\n", e_preset.height);
+	if (i == NUM_PRESETS) {
+		v4l2_info(sd, "Detected DV Preset: None\n");
+	} else {
+		if (v4l_fill_dv_preset_info(presets->preset, &e_preset))
+			return -EINVAL;
+		v4l2_info(sd, "Detected DV Preset: %s\n", e_preset.name);
+		v4l2_info(sd, "  Pixels per line: %u\n", e_preset.width);
+		v4l2_info(sd, "  Lines per frame: %u\n\n", e_preset.height);
+	}
+	v4l2_info(sd, "Streaming enabled: %s\n",
+					device->streaming ? "yes" : "no");
+
+	/* Print the current value of the gain control */
+	v4l2_info(sd, "Gain: %u\n", device->gain);
+
+	return 0;
+}
+
+/* V4L2 core operation handlers */
+static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
+	.g_chip_ident = tvp7002_g_chip_ident,
+	.log_status = tvp7002_log_status,
+	.g_ctrl = tvp7002_g_ctrl,
+	.s_ctrl = tvp7002_s_ctrl,
+	.queryctrl = tvp7002_queryctrl,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register = tvp7002_g_register,
+	.s_register = tvp7002_s_register,
+#endif
+};
+
+/* Specific video subsystem operation handlers */
+static const struct v4l2_subdev_video_ops tvp7002_video_ops = {
+	.s_dv_preset = tvp7002_s_dv_preset,
+	.query_dv_preset = tvp7002_query_dv_preset,
+	.s_stream = tvp7002_s_stream,
+	.g_fmt = tvp7002_g_fmt,
+	.s_fmt = tvp7002_s_fmt,
+	.enum_fmt = tvp7002_enum_fmt,
+};
+
+/* V4L2 top level operation handlers */
+static const struct v4l2_subdev_ops tvp7002_ops = {
+	.core = &tvp7002_core_ops,
+	.video = &tvp7002_video_ops,
+};
+
+static struct tvp7002 tvp7002_dev = {
+	.streaming = 0,
+
+	.pix = {
+		.width = 1280,
+		.height = 720,
+		.pixelformat = V4L2_PIX_FMT_UYVY,
+		.field = V4L2_FIELD_NONE,
+		.bytesperline = 1280 * 2,
+		.sizeimage = 1280 * 2 * 720,
+		.colorspace = V4L2_COLORSPACE_REC709,
+		},
+
+	.current_preset = tvp7002_presets,
+	.gain = 0,
+};
+
+/*
+ * tvp7002_probe - Probe a TVP7002 device
+ * @sd: ptr to v4l2_subdev struct
+ * @ctrl: ptr to i2c_device_id struct
+ *
+ * Initialize the TVP7002 device
+ * Returns zero when successful, -EINVAL if register read fails or
+ * -EIO if i2c access is not available.
+ */
+static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
+{
+	struct v4l2_subdev *sd;
+	struct tvp7002 *device;
+	struct v4l2_dv_preset preset;
+	int polarity_a;
+	int polarity_b;
+	u8 revision;
+
+	int error;
+
+	/* Check if the adapter supports the needed features */
+	if (!i2c_check_functionality(c->adapter,
+		I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
+		return -EIO;
+
+	if (!c->dev.platform_data) {
+		v4l_err(c, "No platform data!!\n");
+		return -ENODEV;
+	}
+
+	device = kmalloc(sizeof(struct tvp7002), GFP_KERNEL);
+
+	if (!device)
+		return -ENOMEM;
+
+	*device = tvp7002_dev;
+	sd = &device->sd;
+	device->pdata = c->dev.platform_data;
+
+	/* Tell v4l2 the device is ready */
+	v4l2_i2c_subdev_init(sd, c, &tvp7002_ops);
+	v4l_info(c, "tvp7002 found @ 0x%02x (%s)\n",
+					c->addr, c->adapter->name);
+
+	error = tvp7002_read(sd, TVP7002_CHIP_REV, &revision);
+	if (error < 0)
+		goto found_error;
+
+	/* Get revision number */
+	v4l2_info(sd, "Rev. %02x detected.\n", revision);
+	if (revision != 0x02)
+		v4l2_info(sd, "Unknown revision detected.\n");
+
+	/* Initializes TVP7002 to its default values */
+	error = tvp7002_write_inittab(sd, tvp7002_init_default);
+
+	if (error < 0)
+		goto found_error;
+
+	/* Set polarity information after registers have been set */
+	polarity_a = 0x20 | device->pdata->hs_polarity << 5
+			| device->pdata->vs_polarity << 2;
+	error = tvp7002_write(sd, TVP7002_SYNC_CTL_1, polarity_a);
+	if (error < 0)
+		goto found_error;
+
+	polarity_b = 0x01  | device->pdata->fid_polarity << 2
+			| device->pdata->sog_polarity << 1
+			| device->pdata->clk_polarity;
+	error = tvp7002_write(sd, TVP7002_MISC_CTL_3, polarity_b);
+	if (error < 0)
+		goto found_error;
+
+	/* Set registers according to default video mode */
+	preset.preset = device->current_preset->preset;
+	error = tvp7002_s_dv_preset(sd, &preset);
+
+found_error:
+	if (error < 0)
+		kfree(device);
+
+	return error;
+}
+
+/*
+ * tvp7002_remove - Remove TVP7002 device support
+ * @c: ptr to i2c_client struct
+ *
+ * Reset the TVP7002 device
+ * Returns zero.
+ */
+static int tvp7002_remove(struct i2c_client *c)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(c);
+	struct tvp7002 *device = to_tvp7002(sd);
+
+	v4l2_dbg(1, debug, sd, "Removing tvp7002 adapter"
+				"on address 0x%x\n", c->addr);
+
+	v4l2_device_unregister_subdev(sd);
+	kfree(device);
+	return 0;
+}
+
+/* I2C Device ID table */
+static const struct i2c_device_id tvp7002_id[] = {
+	{ "tvp7002", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, tvp7002_id);
+
+/* I2C driver data */
+static struct i2c_driver tvp7002_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = TVP7002_MODULE_NAME,
+	},
+	.probe = tvp7002_probe,
+	.remove = tvp7002_remove,
+	.id_table = tvp7002_id,
+};
+
+/*
+ * tvp7002_init - Initialize driver via I2C interface
+ *
+ * Register the TVP7002 driver.
+ * Return 0 on success or error code on failure.
+ */
+static int __init tvp7002_init(void)
+{
+	return i2c_add_driver(&tvp7002_driver);
+}
+
+/*
+ * tvp7002_exit - Remove driver via I2C interface
+ *
+ * Unregister the TVP7002 driver.
+ * Returns nothing.
+ */
+static void __exit tvp7002_exit(void)
+{
+	i2c_del_driver(&tvp7002_driver);
+}
+
+module_init(tvp7002_init);
+module_exit(tvp7002_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tvp7002_reg.h linux-libre-2.6.34-gnu1/drivers/media/video/tvp7002_reg.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/tvp7002_reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tvp7002_reg.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,150 @@
+/* Texas Instruments Triple 8-/10-BIT 165-/110-MSPS Video and Graphics
+ * Digitizer with Horizontal PLL registers
+ *
+ * Copyright (C) 2009 Texas Instruments Inc
+ * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>
+ *
+ * This code is partially based upon the TVP5150 driver
+ * written by Mauro Carvalho Chehab (mchehab@infradead.org),
+ * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com>
+ * and the TVP7002 driver in the TI LSP 2.10.00.14
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Naming conventions
+ * ------------------
+ *
+ * FDBK:  Feedback
+ * DIV:   Divider
+ * CTL:   Control
+ * SEL:   Select
+ * IN:    Input
+ * OUT:   Output
+ * R:     Red
+ * G:     Green
+ * B:     Blue
+ * OFF:   Offset
+ * THRS:  Threshold
+ * DGTL:  Digital
+ * LVL:   Level
+ * PWR:   Power
+ * MVIS:  Macrovision
+ * W:     Width
+ * H:     Height
+ * ALGN:  Alignment
+ * CLK:   Clocks
+ * TOL:   Tolerance
+ * BWTH:  Bandwidth
+ * COEF:  Coefficient
+ * STAT:  Status
+ * AUTO:  Automatic
+ * FLD:   Field
+ * L:	  Line
+ */
+
+#define TVP7002_CHIP_REV		0x00
+#define TVP7002_HPLL_FDBK_DIV_MSBS	0x01
+#define TVP7002_HPLL_FDBK_DIV_LSBS	0x02
+#define TVP7002_HPLL_CRTL		0x03
+#define TVP7002_HPLL_PHASE_SEL		0x04
+#define TVP7002_CLAMP_START		0x05
+#define TVP7002_CLAMP_W			0x06
+#define TVP7002_HSYNC_OUT_W		0x07
+#define TVP7002_B_FINE_GAIN		0x08
+#define TVP7002_G_FINE_GAIN		0x09
+#define TVP7002_R_FINE_GAIN		0x0a
+#define TVP7002_B_FINE_OFF_MSBS		0x0b
+#define TVP7002_G_FINE_OFF_MSBS         0x0c
+#define TVP7002_R_FINE_OFF_MSBS         0x0d
+#define TVP7002_SYNC_CTL_1		0x0e
+#define TVP7002_HPLL_AND_CLAMP_CTL	0x0f
+#define TVP7002_SYNC_ON_G_THRS		0x10
+#define TVP7002_SYNC_SEPARATOR_THRS	0x11
+#define TVP7002_HPLL_PRE_COAST		0x12
+#define TVP7002_HPLL_POST_COAST		0x13
+#define TVP7002_SYNC_DETECT_STAT	0x14
+#define TVP7002_OUT_FORMATTER		0x15
+#define TVP7002_MISC_CTL_1		0x16
+#define TVP7002_MISC_CTL_2              0x17
+#define TVP7002_MISC_CTL_3              0x18
+#define TVP7002_IN_MUX_SEL_1		0x19
+#define TVP7002_IN_MUX_SEL_2            0x1a
+#define TVP7002_B_AND_G_COARSE_GAIN	0x1b
+#define TVP7002_R_COARSE_GAIN		0x1c
+#define TVP7002_FINE_OFF_LSBS		0x1d
+#define TVP7002_B_COARSE_OFF		0x1e
+#define TVP7002_G_COARSE_OFF            0x1f
+#define TVP7002_R_COARSE_OFF            0x20
+#define TVP7002_HSOUT_OUT_START		0x21
+#define TVP7002_MISC_CTL_4		0x22
+#define TVP7002_B_DGTL_ALC_OUT_LSBS	0x23
+#define TVP7002_G_DGTL_ALC_OUT_LSBS     0x24
+#define TVP7002_R_DGTL_ALC_OUT_LSBS     0x25
+#define TVP7002_AUTO_LVL_CTL_ENABLE	0x26
+#define TVP7002_DGTL_ALC_OUT_MSBS	0x27
+#define TVP7002_AUTO_LVL_CTL_FILTER	0x28
+/* Reserved 0x29*/
+#define TVP7002_FINE_CLAMP_CTL		0x2a
+#define TVP7002_PWR_CTL			0x2b
+#define TVP7002_ADC_SETUP		0x2c
+#define TVP7002_COARSE_CLAMP_CTL	0x2d
+#define TVP7002_SOG_CLAMP		0x2e
+#define TVP7002_RGB_COARSE_CLAMP_CTL	0x2f
+#define TVP7002_SOG_COARSE_CLAMP_CTL	0x30
+#define TVP7002_ALC_PLACEMENT		0x31
+/* Reserved 0x32 */
+/* Reserved 0x33 */
+#define TVP7002_MVIS_STRIPPER_W		0x34
+#define TVP7002_VSYNC_ALGN		0x35
+#define TVP7002_SYNC_BYPASS		0x36
+#define TVP7002_L_FRAME_STAT_LSBS	0x37
+#define TVP7002_L_FRAME_STAT_MSBS	0x38
+#define TVP7002_CLK_L_STAT_LSBS		0x39
+#define TVP7002_CLK_L_STAT_MSBS      	0x3a
+#define TVP7002_HSYNC_W			0x3b
+#define TVP7002_VSYNC_W                 0x3c
+#define TVP7002_L_LENGTH_TOL 		0x3d
+/* Reserved 0x3e */
+#define TVP7002_VIDEO_BWTH_CTL		0x3f
+#define TVP7002_AVID_START_PIXEL_LSBS	0x40
+#define TVP7002_AVID_START_PIXEL_MSBS   0x41
+#define TVP7002_AVID_STOP_PIXEL_LSBS  	0x42
+#define TVP7002_AVID_STOP_PIXEL_MSBS    0x43
+#define TVP7002_VBLK_F_0_START_L_OFF	0x44
+#define TVP7002_VBLK_F_1_START_L_OFF    0x45
+#define TVP7002_VBLK_F_0_DURATION	0x46
+#define TVP7002_VBLK_F_1_DURATION       0x47
+#define TVP7002_FBIT_F_0_START_L_OFF	0x48
+#define TVP7002_FBIT_F_1_START_L_OFF    0x49
+#define TVP7002_YUV_Y_G_COEF_LSBS	0x4a
+#define TVP7002_YUV_Y_G_COEF_MSBS       0x4b
+#define TVP7002_YUV_Y_B_COEF_LSBS       0x4c
+#define TVP7002_YUV_Y_B_COEF_MSBS       0x4d
+#define TVP7002_YUV_Y_R_COEF_LSBS       0x4e
+#define TVP7002_YUV_Y_R_COEF_MSBS       0x4f
+#define TVP7002_YUV_U_G_COEF_LSBS       0x50
+#define TVP7002_YUV_U_G_COEF_MSBS       0x51
+#define TVP7002_YUV_U_B_COEF_LSBS       0x52
+#define TVP7002_YUV_U_B_COEF_MSBS       0x53
+#define TVP7002_YUV_U_R_COEF_LSBS       0x54
+#define TVP7002_YUV_U_R_COEF_MSBS       0x55
+#define TVP7002_YUV_V_G_COEF_LSBS       0x56
+#define TVP7002_YUV_V_G_COEF_MSBS       0x57
+#define TVP7002_YUV_V_B_COEF_LSBS       0x58
+#define TVP7002_YUV_V_B_COEF_MSBS       0x59
+#define TVP7002_YUV_V_R_COEF_LSBS       0x5a
+#define TVP7002_YUV_V_R_COEF_MSBS       0x5b
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/tw9910.c linux-libre-2.6.34-gnu1/drivers/media/video/tw9910.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/tw9910.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/tw9910.c	2010-05-16 17:17:36.000000000 -0400
@@ -233,10 +233,10 @@ struct tw9910_hsync_ctrl {
 };
 
 struct tw9910_priv {
-	struct v4l2_subdev                subdev;
-	struct tw9910_video_info       *info;
-	const struct tw9910_scale_ctrl *scale;
-	u32                             revision;
+	struct v4l2_subdev		subdev;
+	struct tw9910_video_info	*info;
+	const struct tw9910_scale_ctrl	*scale;
+	u32				revision;
 };
 
 static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/upd64031a.c linux-libre-2.6.34-gnu1/drivers/media/video/upd64031a.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/upd64031a.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/upd64031a.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/upd64083.c linux-libre-2.6.34-gnu1/drivers/media/video/upd64083.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/upd64083.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/upd64083.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/usbvideo/konicawc.c linux-libre-2.6.34-gnu1/drivers/media/video/usbvideo/konicawc.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/usbvideo/konicawc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/usbvideo/konicawc.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb/input.h>
+#include <linux/gfp.h>
 
 #include "usbvideo.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/usbvideo/quickcam_messenger.c linux-libre-2.6.34-gnu1/drivers/media/video/usbvideo/quickcam_messenger.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/usbvideo/quickcam_messenger.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/usbvideo/quickcam_messenger.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/usb/input.h>
+#include <linux/slab.h>
 
 #include "usbvideo.h"
 #include "quickcam_messenger.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/usbvision/usbvision-core.c linux-libre-2.6.34-gnu1/drivers/media/video/usbvision/usbvision-core.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/usbvision/usbvision-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/usbvision/usbvision-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/timer.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/vmalloc.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/usbvision/usbvision-i2c.c linux-libre-2.6.34-gnu1/drivers/media/video/usbvision/usbvision-i2c.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/usbvision/usbvision-i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/usbvision/usbvision-i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
 #include <linux/ioport.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/usbvision/usbvision-video.c linux-libre-2.6.34-gnu1/drivers/media/video/usbvision/usbvision-video.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/usbvision/usbvision-video.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/usbvision/usbvision-video.c	2010-05-16 17:17:36.000000000 -0400
@@ -1487,7 +1487,7 @@ static int __devinit usbvision_register_
 		usbvision->vbi = usbvision_vdev_init(usbvision,
 						     &usbvision_vbi_template,
 						     "USBVision VBI");
-		if (usbvision->vdev == NULL) {
+		if (usbvision->vbi == NULL) {
 			goto err_exit;
 		}
 		if (video_register_device(usbvision->vbi,
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_ctrl.c linux-libre-2.6.34-gnu1/drivers/media/video/uvc/uvc_ctrl.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_ctrl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/uvc/uvc_ctrl.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/videodev2.h>
@@ -23,9 +24,13 @@
 
 #include "uvcvideo.h"
 
-#define UVC_CTRL_NDATA		2
 #define UVC_CTRL_DATA_CURRENT	0
 #define UVC_CTRL_DATA_BACKUP	1
+#define UVC_CTRL_DATA_MIN	2
+#define UVC_CTRL_DATA_MAX	3
+#define UVC_CTRL_DATA_RES	4
+#define UVC_CTRL_DATA_DEF	5
+#define UVC_CTRL_DATA_LAST	6
 
 /* ------------------------------------------------------------------------
  * Controls
@@ -755,6 +760,49 @@ struct uvc_control *uvc_find_control(str
 	return ctrl;
 }
 
+static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
+	struct uvc_control *ctrl)
+{
+	int ret;
+
+	if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
+		ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id,
+				     chain->dev->intfnum, ctrl->info->selector,
+				     uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF),
+				     ctrl->info->size);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
+		ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id,
+				     chain->dev->intfnum, ctrl->info->selector,
+				     uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN),
+				     ctrl->info->size);
+		if (ret < 0)
+			return ret;
+	}
+	if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
+		ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,
+				     chain->dev->intfnum, ctrl->info->selector,
+				     uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX),
+				     ctrl->info->size);
+		if (ret < 0)
+			return ret;
+	}
+	if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
+		ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,
+				     chain->dev->intfnum, ctrl->info->selector,
+				     uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES),
+				     ctrl->info->size);
+		if (ret < 0)
+			return ret;
+	}
+
+	ctrl->cached = 1;
+	return 0;
+}
+
 int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
 	struct v4l2_queryctrl *v4l2_ctrl)
 {
@@ -762,17 +810,12 @@ int uvc_query_v4l2_ctrl(struct uvc_video
 	struct uvc_control_mapping *mapping;
 	struct uvc_menu_info *menu;
 	unsigned int i;
-	__u8 *data;
 	int ret;
 
 	ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
 	if (ctrl == NULL)
 		return -EINVAL;
 
-	data = kmalloc(ctrl->info->size, GFP_KERNEL);
-	if (data == NULL)
-		return -ENOMEM;
-
 	memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
 	v4l2_ctrl->id = mapping->id;
 	v4l2_ctrl->type = mapping->v4l2_type;
@@ -782,14 +825,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video
 	if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR))
 		v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 
-	if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
-		ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id,
-				     chain->dev->intfnum, ctrl->info->selector,
-				     data, ctrl->info->size);
+	if (!ctrl->cached) {
+		ret = uvc_ctrl_populate_cache(chain, ctrl);
 		if (ret < 0)
-			goto out;
-		v4l2_ctrl->default_value =
-			mapping->get(mapping, UVC_GET_DEF, data);
+			return ret;
+	}
+
+	if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
+		v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF,
+				uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF));
 	}
 
 	switch (mapping->v4l2_type) {
@@ -806,56 +850,37 @@ int uvc_query_v4l2_ctrl(struct uvc_video
 			}
 		}
 
-		ret = 0;
-		goto out;
+		return 0;
 
 	case V4L2_CTRL_TYPE_BOOLEAN:
 		v4l2_ctrl->minimum = 0;
 		v4l2_ctrl->maximum = 1;
 		v4l2_ctrl->step = 1;
-		ret = 0;
-		goto out;
+		return 0;
 
 	case V4L2_CTRL_TYPE_BUTTON:
 		v4l2_ctrl->minimum = 0;
 		v4l2_ctrl->maximum = 0;
 		v4l2_ctrl->step = 0;
-		ret = 0;
-		goto out;
+		return 0;
 
 	default:
 		break;
 	}
 
-	if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
-		ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id,
-				     chain->dev->intfnum, ctrl->info->selector,
-				     data, ctrl->info->size);
-		if (ret < 0)
-			goto out;
-		v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, data);
-	}
-	if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
-		ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,
-				     chain->dev->intfnum, ctrl->info->selector,
-				     data, ctrl->info->size);
-		if (ret < 0)
-			goto out;
-		v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, data);
-	}
-	if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
-		ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,
-				     chain->dev->intfnum, ctrl->info->selector,
-				     data, ctrl->info->size);
-		if (ret < 0)
-			goto out;
-		v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, data);
-	}
+	if (ctrl->info->flags & UVC_CONTROL_GET_MIN)
+		v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,
+				     uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
 
-	ret = 0;
-out:
-	kfree(data);
-	return ret;
+	if (ctrl->info->flags & UVC_CONTROL_GET_MAX)
+		v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX,
+				     uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
+
+	if (ctrl->info->flags & UVC_CONTROL_GET_RES)
+		v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES,
+				  uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
+
+	return 0;
 }
 
 
@@ -997,19 +1022,57 @@ int uvc_ctrl_set(struct uvc_video_chain
 {
 	struct uvc_control *ctrl;
 	struct uvc_control_mapping *mapping;
-	s32 value = xctrl->value;
+	s32 value;
+	u32 step;
+	s32 min;
+	s32 max;
 	int ret;
 
 	ctrl = uvc_find_control(chain, xctrl->id, &mapping);
 	if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0)
 		return -EINVAL;
 
-	if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
-		if (value < 0 || value >= mapping->menu_count)
-			return -EINVAL;
-		value = mapping->menu_info[value].value;
+	/* Clamp out of range values. */
+	switch (mapping->v4l2_type) {
+	case V4L2_CTRL_TYPE_INTEGER:
+		if (!ctrl->cached) {
+			ret = uvc_ctrl_populate_cache(chain, ctrl);
+			if (ret < 0)
+				return ret;
+		}
+
+		min = mapping->get(mapping, UVC_GET_MIN,
+				   uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
+		max = mapping->get(mapping, UVC_GET_MAX,
+				   uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
+		step = mapping->get(mapping, UVC_GET_RES,
+				    uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
+
+		xctrl->value = min + (xctrl->value - min + step/2) / step * step;
+		xctrl->value = clamp(xctrl->value, min, max);
+		value = xctrl->value;
+		break;
+
+	case V4L2_CTRL_TYPE_BOOLEAN:
+		xctrl->value = clamp(xctrl->value, 0, 1);
+		value = xctrl->value;
+		break;
+
+	case V4L2_CTRL_TYPE_MENU:
+		if (xctrl->value < 0 || xctrl->value >= mapping->menu_count)
+			return -ERANGE;
+		value = mapping->menu_info[xctrl->value].value;
+		break;
+
+	default:
+		value = xctrl->value;
+		break;
 	}
 
+	/* If the mapping doesn't span the whole UVC control, the current value
+	 * needs to be loaded from the device to perform the read-modify-write
+	 * operation.
+	 */
 	if (!ctrl->loaded && (ctrl->info->size * 8) != mapping->size) {
 		if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) {
 			memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
@@ -1027,6 +1090,7 @@ int uvc_ctrl_set(struct uvc_video_chain
 		ctrl->loaded = 1;
 	}
 
+	/* Backup the current value in case we need to rollback later. */
 	if (!ctrl->dirty) {
 		memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
 		       uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
@@ -1080,10 +1144,8 @@ int uvc_xu_ctrl_query(struct uvc_video_c
 	}
 
 	if (!found) {
-		uvc_trace(UVC_TRACE_CONTROL,
-			"Control " UVC_GUID_FORMAT "/%u not found.\n",
-			UVC_GUID_ARGS(entity->extension.guidExtensionCode),
-			xctrl->selector);
+		uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u not found.\n",
+			entity->extension.guidExtensionCode, xctrl->selector);
 		return -EINVAL;
 	}
 
@@ -1159,9 +1221,9 @@ int uvc_ctrl_resume_device(struct uvc_de
 			    (ctrl->info->flags & UVC_CONTROL_RESTORE) == 0)
 				continue;
 
-			printk(KERN_INFO "restoring control " UVC_GUID_FORMAT
-				"/%u/%u\n", UVC_GUID_ARGS(ctrl->info->entity),
-				ctrl->info->index, ctrl->info->selector);
+			printk(KERN_INFO "restoring control %pUl/%u/%u\n",
+				ctrl->info->entity, ctrl->info->index,
+				ctrl->info->selector);
 			ctrl->dirty = 1;
 		}
 
@@ -1215,47 +1277,43 @@ static void uvc_ctrl_add_ctrl(struct uvc
 		ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id,
 			dev->intfnum, info->selector, (__u8 *)&size, 2);
 		if (ret < 0) {
-			uvc_trace(UVC_TRACE_CONTROL, "GET_LEN failed on "
-				"control " UVC_GUID_FORMAT "/%u (%d).\n",
-				UVC_GUID_ARGS(info->entity), info->selector,
-				ret);
+			uvc_trace(UVC_TRACE_CONTROL,
+				"GET_LEN failed on control %pUl/%u (%d).\n",
+				info->entity, info->selector, ret);
 			return;
 		}
 
 		if (info->size != le16_to_cpu(size)) {
-			uvc_trace(UVC_TRACE_CONTROL, "Control " UVC_GUID_FORMAT
-				"/%u size doesn't match user supplied "
-				"value.\n", UVC_GUID_ARGS(info->entity),
-				info->selector);
+			uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u size "
+				"doesn't match user supplied value.\n",
+				info->entity, info->selector);
 			return;
 		}
 
 		ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id,
 			dev->intfnum, info->selector, &inf, 1);
 		if (ret < 0) {
-			uvc_trace(UVC_TRACE_CONTROL, "GET_INFO failed on "
-				"control " UVC_GUID_FORMAT "/%u (%d).\n",
-				UVC_GUID_ARGS(info->entity), info->selector,
-				ret);
+			uvc_trace(UVC_TRACE_CONTROL,
+				"GET_INFO failed on control %pUl/%u (%d).\n",
+				info->entity, info->selector, ret);
 			return;
 		}
 
 		flags = info->flags;
 		if (((flags & UVC_CONTROL_GET_CUR) && !(inf & (1 << 0))) ||
 		    ((flags & UVC_CONTROL_SET_CUR) && !(inf & (1 << 1)))) {
-			uvc_trace(UVC_TRACE_CONTROL, "Control "
-				UVC_GUID_FORMAT "/%u flags don't match "
-				"supported operations.\n",
-				UVC_GUID_ARGS(info->entity), info->selector);
+			uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u flags "
+				"don't match supported operations.\n",
+				info->entity, info->selector);
 			return;
 		}
 	}
 
 	ctrl->info = info;
-	ctrl->data = kmalloc(ctrl->info->size * UVC_CTRL_NDATA, GFP_KERNEL);
-	uvc_trace(UVC_TRACE_CONTROL, "Added control " UVC_GUID_FORMAT "/%u "
-		"to device %s entity %u\n", UVC_GUID_ARGS(ctrl->info->entity),
-		ctrl->info->selector, dev->udev->devpath, entity->id);
+	ctrl->data = kmalloc(ctrl->info->size * UVC_CTRL_DATA_LAST, GFP_KERNEL);
+	uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s "
+		"entity %u\n", ctrl->info->entity, ctrl->info->selector,
+		dev->udev->devpath, entity->id);
 }
 
 /*
@@ -1281,17 +1339,16 @@ int uvc_ctrl_add_info(struct uvc_control
 			continue;
 
 		if (ctrl->selector == info->selector) {
-			uvc_trace(UVC_TRACE_CONTROL, "Control "
-				UVC_GUID_FORMAT "/%u is already defined.\n",
-				UVC_GUID_ARGS(info->entity), info->selector);
+			uvc_trace(UVC_TRACE_CONTROL,
+				"Control %pUl/%u is already defined.\n",
+				info->entity, info->selector);
 			ret = -EEXIST;
 			goto end;
 		}
 		if (ctrl->index == info->index) {
-			uvc_trace(UVC_TRACE_CONTROL, "Control "
-				UVC_GUID_FORMAT "/%u would overwrite index "
-				"%d.\n", UVC_GUID_ARGS(info->entity),
-				info->selector, info->index);
+			uvc_trace(UVC_TRACE_CONTROL,
+				"Control %pUl/%u would overwrite index %d.\n",
+				info->entity, info->selector, info->index);
 			ret = -EEXIST;
 			goto end;
 		}
@@ -1332,10 +1389,9 @@ int uvc_ctrl_add_mapping(struct uvc_cont
 			continue;
 
 		if (info->size * 8 < mapping->size + mapping->offset) {
-			uvc_trace(UVC_TRACE_CONTROL, "Mapping '%s' would "
-				"overflow control " UVC_GUID_FORMAT "/%u\n",
-				mapping->name, UVC_GUID_ARGS(info->entity),
-				info->selector);
+			uvc_trace(UVC_TRACE_CONTROL,
+				"Mapping '%s' would overflow control %pUl/%u\n",
+				mapping->name, info->entity, info->selector);
 			ret = -EOVERFLOW;
 			goto end;
 		}
@@ -1354,9 +1410,9 @@ int uvc_ctrl_add_mapping(struct uvc_cont
 
 		mapping->ctrl = info;
 		list_add_tail(&mapping->list, &info->mappings);
-		uvc_trace(UVC_TRACE_CONTROL, "Adding mapping %s to control "
-			UVC_GUID_FORMAT "/%u.\n", mapping->name,
-			UVC_GUID_ARGS(info->entity), info->selector);
+		uvc_trace(UVC_TRACE_CONTROL,
+			"Adding mapping %s to control %pUl/%u.\n",
+			mapping->name, info->entity, info->selector);
 
 		ret = 0;
 		break;
@@ -1378,6 +1434,7 @@ uvc_ctrl_prune_entity(struct uvc_device
 		struct usb_device_id id;
 		u8 index;
 	} blacklist[] = {
+		{ { USB_DEVICE(0x13d3, 0x509b) }, 9 }, /* Gain */
 		{ { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */
 		{ { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */
 	};
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_driver.c linux-libre-2.6.34-gnu1/drivers/media/video/uvc/uvc_driver.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_driver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/uvc/uvc_driver.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/videodev2.h>
 #include <linux/vmalloc.h>
@@ -43,8 +44,9 @@
 #define DRIVER_VERSION		"v0.1.0"
 #endif
 
+unsigned int uvc_clock_param = CLOCK_MONOTONIC;
 unsigned int uvc_no_drop_param;
-static unsigned int uvc_quirks_param;
+static unsigned int uvc_quirks_param = -1;
 unsigned int uvc_trace_param;
 unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
 
@@ -59,6 +61,11 @@ static struct uvc_format_desc uvc_fmts[]
 		.fcc		= V4L2_PIX_FMT_YUYV,
 	},
 	{
+		.name		= "YUV 4:2:2 (YUYV)",
+		.guid		= UVC_GUID_FORMAT_YUY2_ISIGHT,
+		.fcc		= V4L2_PIX_FMT_YUYV,
+	},
+	{
 		.name		= "YUV 4:2:0 (NV12)",
 		.guid		= UVC_GUID_FORMAT_NV12,
 		.fcc		= V4L2_PIX_FMT_NV12,
@@ -309,11 +316,10 @@ static int uvc_parse_format(struct uvc_d
 				sizeof format->name);
 			format->fcc = fmtdesc->fcc;
 		} else {
-			uvc_printk(KERN_INFO, "Unknown video format "
-				UVC_GUID_FORMAT "\n",
-				UVC_GUID_ARGS(&buffer[5]));
-			snprintf(format->name, sizeof format->name,
-				UVC_GUID_FORMAT, UVC_GUID_ARGS(&buffer[5]));
+			uvc_printk(KERN_INFO, "Unknown video format %pUl\n",
+				&buffer[5]);
+			snprintf(format->name, sizeof(format->name), "%pUl\n",
+				&buffer[5]);
 			format->fcc = 0;
 		}
 
@@ -1750,7 +1756,8 @@ static int uvc_probe(struct usb_interfac
 	dev->udev = usb_get_dev(udev);
 	dev->intf = usb_get_intf(intf);
 	dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
-	dev->quirks = id->driver_info | uvc_quirks_param;
+	dev->quirks = (uvc_quirks_param == -1)
+		    ? id->driver_info : uvc_quirks_param;
 
 	if (udev->product != NULL)
 		strlcpy(dev->name, udev->product, sizeof dev->name);
@@ -1773,9 +1780,9 @@ static int uvc_probe(struct usb_interfac
 		le16_to_cpu(udev->descriptor.idVendor),
 		le16_to_cpu(udev->descriptor.idProduct));
 
-	if (uvc_quirks_param != 0) {
-		uvc_printk(KERN_INFO, "Forcing device quirks 0x%x by module "
-			"parameter for testing purpose.\n", uvc_quirks_param);
+	if (dev->quirks != id->driver_info) {
+		uvc_printk(KERN_INFO, "Forcing device quirks to 0x%x by module "
+			"parameter for testing purpose.\n", dev->quirks);
 		uvc_printk(KERN_INFO, "Please report required quirks to the "
 			"linux-uvc-devel mailing list.\n");
 	}
@@ -1892,6 +1899,45 @@ static int uvc_reset_resume(struct usb_i
 }
 
 /* ------------------------------------------------------------------------
+ * Module parameters
+ */
+
+static int uvc_clock_param_get(char *buffer, struct kernel_param *kp)
+{
+	if (uvc_clock_param == CLOCK_MONOTONIC)
+		return sprintf(buffer, "CLOCK_MONOTONIC");
+	else
+		return sprintf(buffer, "CLOCK_REALTIME");
+}
+
+static int uvc_clock_param_set(const char *val, struct kernel_param *kp)
+{
+	if (strncasecmp(val, "clock_", strlen("clock_")) == 0)
+		val += strlen("clock_");
+
+	if (strcasecmp(val, "monotonic") == 0)
+		uvc_clock_param = CLOCK_MONOTONIC;
+	else if (strcasecmp(val, "realtime") == 0)
+		uvc_clock_param = CLOCK_REALTIME;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
+module_param_call(clock, uvc_clock_param_set, uvc_clock_param_get,
+		  &uvc_clock_param, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(clock, "Video buffers timestamp clock");
+module_param_named(nodrop, uvc_no_drop_param, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(nodrop, "Don't drop incomplete frames");
+module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(quirks, "Forced device quirks");
+module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(trace, "Trace level bitmask");
+module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
+
+/* ------------------------------------------------------------------------
  * Driver initialization and cleanup
  */
 
@@ -2197,15 +2243,6 @@ static void __exit uvc_cleanup(void)
 module_init(uvc_init);
 module_exit(uvc_cleanup);
 
-module_param_named(nodrop, uvc_no_drop_param, uint, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(nodrop, "Don't drop incomplete frames");
-module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(quirks, "Forced device quirks");
-module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(trace, "Trace level bitmask");
-module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
-
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_queue.c linux-libre-2.6.34-gnu1/drivers/media/video/uvc/uvc_queue.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_queue.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/uvc/uvc_queue.c	2010-05-16 17:17:36.000000000 -0400
@@ -502,7 +502,6 @@ struct uvc_buffer *uvc_queue_next_buffer
 	spin_unlock_irqrestore(&queue->irqlock, flags);
 
 	buf->buf.sequence = queue->sequence++;
-	do_gettimeofday(&buf->buf.timestamp);
 
 	wake_up(&buf->wait);
 	return nextbuf;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_status.c linux-libre-2.6.34-gnu1/drivers/media/video/uvc/uvc_status.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_status.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/uvc/uvc_status.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 
 #include <linux/kernel.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/input.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_v4l2.c linux-libre-2.6.34-gnu1/drivers/media/video/uvc/uvc_v4l2.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_v4l2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/uvc/uvc_v4l2.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/version.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/videodev2.h>
 #include <linux/vmalloc.h>
@@ -539,7 +540,7 @@ static long uvc_v4l2_do_ioctl(struct fil
 		xctrl.id = ctrl->id;
 		xctrl.value = ctrl->value;
 
-		uvc_ctrl_begin(chain);
+		ret = uvc_ctrl_begin(chain);
 		if (ret < 0)
 			return ret;
 
@@ -549,6 +550,8 @@ static long uvc_v4l2_do_ioctl(struct fil
 			return ret;
 		}
 		ret = uvc_ctrl_commit(chain);
+		if (ret == 0)
+			ctrl->value = xctrl.value;
 		break;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_video.c linux-libre-2.6.34-gnu1/drivers/media/video/uvc/uvc_video.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_video.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/uvc/uvc_video.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/videodev2.h>
 #include <linux/vmalloc.h>
@@ -410,6 +411,8 @@ static int uvc_video_decode_start(struct
 	 * when the EOF bit is set to force synchronisation on the next packet.
 	 */
 	if (buf->state != UVC_BUF_STATE_ACTIVE) {
+		struct timespec ts;
+
 		if (fid == stream->last_fid) {
 			uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of "
 				"sync).\n");
@@ -419,6 +422,14 @@ static int uvc_video_decode_start(struct
 			return -ENODATA;
 		}
 
+		if (uvc_clock_param == CLOCK_MONOTONIC)
+			ktime_get_ts(&ts);
+		else
+			ktime_get_real_ts(&ts);
+
+		buf->buf.timestamp.tv_sec = ts.tv_sec;
+		buf->buf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+
 		/* TODO: Handle PTS and SCR. */
 		buf->state = UVC_BUF_STATE_ACTIVE;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvcvideo.h linux-libre-2.6.34-gnu1/drivers/media/video/uvc/uvcvideo.h
--- linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvcvideo.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/uvc/uvcvideo.h	2010-05-16 17:17:36.000000000 -0400
@@ -113,6 +113,9 @@ struct uvc_xu_control {
 #define UVC_GUID_FORMAT_YUY2 \
 	{ 'Y',  'U',  'Y',  '2', 0x00, 0x00, 0x10, 0x00, \
 	 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_YUY2_ISIGHT \
+	{ 'Y',  'U',  'Y',  '2', 0x00, 0x00, 0x10, 0x00, \
+	 0x80, 0x00, 0x00, 0x00, 0x00, 0x38, 0x9b, 0x71}
 #define UVC_GUID_FORMAT_NV12 \
 	{ 'N',  'V',  '1',  '2', 0x00, 0x00, 0x10, 0x00, \
 	 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
@@ -149,7 +152,7 @@ struct uvc_xu_control {
 #define UVC_MAX_STATUS_SIZE	16
 
 #define UVC_CTRL_CONTROL_TIMEOUT	300
-#define UVC_CTRL_STREAMING_TIMEOUT	3000
+#define UVC_CTRL_STREAMING_TIMEOUT	5000
 
 /* Devices quirks */
 #define UVC_QUIRK_STATUS_INTERVAL	0x00000001
@@ -242,7 +245,8 @@ struct uvc_control {
 			   uvc_control_info. */
 	__u8 dirty : 1,
 	     loaded : 1,
-	     modified : 1;
+	     modified : 1,
+	     cached : 1;
 
 	__u8 *data;
 };
@@ -533,6 +537,7 @@ struct uvc_driver {
 #define UVC_WARN_MINMAX		0
 #define UVC_WARN_PROBE_DEF	1
 
+extern unsigned int uvc_clock_param;
 extern unsigned int uvc_no_drop_param;
 extern unsigned int uvc_trace_param;
 extern unsigned int uvc_timeout_param;
@@ -552,16 +557,6 @@ extern unsigned int uvc_timeout_param;
 #define uvc_printk(level, msg...) \
 	printk(level "uvcvideo: " msg)
 
-#define UVC_GUID_FORMAT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" \
-			"%02x%02x%02x%02x%02x%02x"
-#define UVC_GUID_ARGS(guid) \
-	(guid)[3],  (guid)[2],  (guid)[1],  (guid)[0], \
-	(guid)[5],  (guid)[4], \
-	(guid)[7],  (guid)[6], \
-	(guid)[8],  (guid)[9], \
-	(guid)[10], (guid)[11], (guid)[12], \
-	(guid)[13], (guid)[14], (guid)[15]
-
 /* --------------------------------------------------------------------------
  * Internal functions.
  */
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/v4l2-compat-ioctl32.c linux-libre-2.6.34-gnu1/drivers/media/video/v4l2-compat-ioctl32.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/v4l2-compat-ioctl32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/v4l2-compat-ioctl32.c	2010-05-16 17:17:36.000000000 -0400
@@ -288,7 +288,7 @@ static int get_v4l2_window32(struct v4l2
 
 static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
 {
-	if (copy_to_user(&up->w, &kp->w, sizeof(up->w)) ||
+	if (copy_to_user(&up->w, &kp->w, sizeof(kp->w)) ||
 		put_user(kp->field, &up->field) ||
 		put_user(kp->chromakey, &up->chromakey) ||
 		put_user(kp->clipcount, &up->clipcount))
@@ -475,6 +475,9 @@ static int get_v4l2_buffer32(struct v4l2
 			return -EFAULT;
 	switch (kp->memory) {
 	case V4L2_MEMORY_MMAP:
+		if (get_user(kp->length, &up->length) ||
+			get_user(kp->m.offset, &up->m.offset))
+			return -EFAULT;
 		break;
 	case V4L2_MEMORY_USERPTR:
 		{
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/v4l2-ioctl.c linux-libre-2.6.34-gnu1/drivers/media/video/v4l2-ioctl.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/v4l2-ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/v4l2-ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-dma-contig.c linux-libre-2.6.34-gnu1/drivers/media/video/videobuf-dma-contig.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-dma-contig.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/videobuf-dma-contig.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/pagemap.h>
 #include <linux/dma-mapping.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <media/videobuf-dma-contig.h>
 
 struct videobuf_dma_contig_memory {
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-dma-sg.c linux-libre-2.6.34-gnu1/drivers/media/video/videobuf-dma-sg.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-dma-sg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/videobuf-dma-sg.c	2010-05-16 17:17:36.000000000 -0400
@@ -418,6 +418,8 @@ static void *__videobuf_alloc(size_t siz
 	struct videobuf_buffer *vb;
 
 	vb = kzalloc(size+sizeof(*mem),GFP_KERNEL);
+	if (!vb)
+		return vb;
 
 	mem = vb->priv = ((char *)vb)+size;
 	mem->magic=MAGIC_SG_MEM;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-dvb.c linux-libre-2.6.34-gnu1/drivers/media/video/videobuf-dvb.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-dvb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/videobuf-dvb.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/fs.h>
 #include <linux/kthread.h>
 #include <linux/file.h>
+#include <linux/slab.h>
 
 #include <linux/freezer.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-vmalloc.c linux-libre-2.6.34-gnu1/drivers/media/video/videobuf-vmalloc.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-vmalloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/videobuf-vmalloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -138,6 +138,8 @@ static void *__videobuf_alloc(size_t siz
 	struct videobuf_buffer *vb;
 
 	vb = kzalloc(size+sizeof(*mem),GFP_KERNEL);
+	if (!vb)
+		return vb;
 
 	mem = vb->priv = ((char *)vb)+size;
 	mem->magic=MAGIC_VMAL_MEM;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/vino.c linux-libre-2.6.34-gnu1/drivers/media/video/vino.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/vino.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/vino.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/fs.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/time.h>
 #include <linux/version.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/vivi.c linux-libre-2.6.34-gnu1/drivers/media/video/vivi.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/vivi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/vivi.c	2010-05-16 17:17:36.000000000 -0400
@@ -1371,7 +1371,7 @@ static int __init vivi_create_instance(i
 	/* Now that everything is fine, let's add it to device list */
 	list_add_tail(&dev->vivi_devlist, &vivi_devlist);
 
-	if (video_nr >= 0)
+	if (video_nr != -1)
 		video_nr++;
 
 	dev->vfd = vfd;
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/vp27smpx.c linux-libre-2.6.34-gnu1/drivers/media/video/vp27smpx.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/vp27smpx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/vp27smpx.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/vpx3220.c linux-libre-2.6.34-gnu1/drivers/media/video/vpx3220.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/vpx3220.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/vpx3220.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/w9966.c linux-libre-2.6.34-gnu1/drivers/media/video/w9966.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/w9966.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/w9966.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,6 +58,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/videodev.h>
+#include <linux/slab.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <linux/parport.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/wm8739.c linux-libre-2.6.34-gnu1/drivers/media/video/wm8739.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/wm8739.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/wm8739.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/wm8775.c linux-libre-2.6.34-gnu1/drivers/media/video/wm8775.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/wm8775.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/wm8775.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/zc0301/Kconfig linux-libre-2.6.34-gnu1/drivers/media/video/zc0301/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/media/video/zc0301/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/zc0301/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,11 @@
 config USB_ZC0301
-	tristate "USB ZC0301[P] Image Processor and Control Chip support"
+	tristate "USB ZC0301[P] webcam support (DEPRECATED)"
 	depends on VIDEO_V4L2
+	default n
 	---help---
+	  This driver is DEPRECATED please use the gspca zc3xx module
+	  instead.
+
 	  Say Y here if you want support for cameras based on the ZC0301 or
 	  ZC0301P Image Processors and Control Chips.
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/zoran/zoran_card.c linux-libre-2.6.34-gnu1/drivers/media/video/zoran/zoran_card.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/zoran/zoran_card.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/zoran/zoran_card.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include <linux/proc_fs.h>
 #include <linux/i2c.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/zoran/zoran_device.c linux-libre-2.6.34-gnu1/drivers/media/video/zoran/zoran_device.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/zoran/zoran_device.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/zoran/zoran_device.c	2010-05-16 17:17:36.000000000 -0400
@@ -1196,7 +1196,8 @@ 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;
+	unsigned int status = 0;
+	int mode;
 
 	if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
 		decoder_call(zr, video, g_input_status, &status);
@@ -1228,7 +1229,7 @@ error_handler (struct zoran *zr,
 	       u32           astat,
 	       u32           stat)
 {
-	int i, j;
+	int i;
 
 	/* This is JPEG error handling part */
 	if (zr->codec_mode != BUZ_MODE_MOTION_COMPRESS &&
@@ -1279,6 +1280,7 @@ error_handler (struct zoran *zr,
 	/* Report error */
 	if (zr36067_debug > 1 && zr->num_errors <= 8) {
 		long frame;
+		int j;
 
 		frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
 		printk(KERN_ERR
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/zoran/zoran_driver.c linux-libre-2.6.34-gnu1/drivers/media/video/zoran/zoran_driver.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/zoran/zoran_driver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/zoran/zoran_driver.c	2010-05-16 17:17:36.000000000 -0400
@@ -324,7 +324,7 @@ static int jpg_fbuffer_alloc(struct zora
 		/* Allocate fragment table for this buffer */
 
 		mem = (void *)get_zeroed_page(GFP_KERNEL);
-		if (mem == 0) {
+		if (!mem) {
 			dprintk(1,
 				KERN_ERR
 				"%s: %s - get_zeroed_page (frag_tab) failed for buffer %d\n",
@@ -1444,7 +1444,7 @@ zoran_set_norm (struct zoran *zr,
 	}
 
 	if (norm == V4L2_STD_ALL) {
-		int status = 0;
+		unsigned int status = 0;
 		v4l2_std_id std = 0;
 
 		decoder_call(zr, video, querystd, &std);
diff -druNp linux-libre-2.6.33-gnu1/drivers/media/video/zr364xx.c linux-libre-2.6.34-gnu1/drivers/media/video/zr364xx.c
--- linux-libre-2.6.33-gnu1/drivers/media/video/zr364xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/media/video/zr364xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -78,6 +78,7 @@
 #define METHOD0 0
 #define METHOD1 1
 #define METHOD2 2
+#define METHOD3 3
 
 
 /* Module parameters */
@@ -114,7 +115,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 },
+	{USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD3 },
 	{USB_DEVICE(0x06d6, 0x003d), .driver_info = METHOD0 },
 	{}			/* Terminating entry */
 };
@@ -302,7 +303,7 @@ static message m2[] = {
 };
 
 /* init table */
-static message *init[3] = { m0, m1, m2 };
+static message *init[4] = { m0, m1, m2, m2 };
 
 
 /* JPEG static data in header (Huffman table, etc) */
@@ -967,6 +968,22 @@ static int zr364xx_vidioc_s_fmt_vid_cap(
 	m0d1[0] = mode;
 	m1[2].value = 0xf000 + mode;
 	m2[1].value = 0xf000 + mode;
+
+	/* special case for METHOD3, the modes are different */
+	if (cam->method == METHOD3) {
+		switch (mode) {
+		case 1:
+			m2[1].value = 0xf000 + 4;
+			break;
+		case 2:
+			m2[1].value = 0xf000 + 0;
+			break;
+		default:
+			m2[1].value = 0xf000 + 1;
+			break;
+		}
+	}
+
 	header2[437] = cam->height / 256;
 	header2[438] = cam->height % 256;
 	header2[439] = cam->width / 256;
@@ -1582,6 +1599,22 @@ static int zr364xx_probe(struct usb_inte
 	m0d1[0] = mode;
 	m1[2].value = 0xf000 + mode;
 	m2[1].value = 0xf000 + mode;
+
+	/* special case for METHOD3, the modes are different */
+	if (cam->method == METHOD3) {
+		switch (mode) {
+		case 1:
+			m2[1].value = 0xf000 + 4;
+			break;
+		case 2:
+			m2[1].value = 0xf000 + 0;
+			break;
+		default:
+			m2[1].value = 0xf000 + 1;
+			break;
+		}
+	}
+
 	header2[437] = cam->height / 256;
 	header2[438] = cam->height % 256;
 	header2[439] = cam->width / 256;
diff -druNp linux-libre-2.6.33-gnu1/drivers/memstick/core/memstick.c linux-libre-2.6.34-gnu1/drivers/memstick/core/memstick.c
--- linux-libre-2.6.33-gnu1/drivers/memstick/core/memstick.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/memstick/core/memstick.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/idr.h>
 #include <linux/fs.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "memstick"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/memstick/core/mspro_block.c linux-libre-2.6.34-gnu1/drivers/memstick/core/mspro_block.c
--- linux-libre-2.6.33-gnu1/drivers/memstick/core/mspro_block.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/memstick/core/mspro_block.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/hdreg.h>
 #include <linux/kthread.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/memstick.h>
 
 #define DRIVER_NAME "mspro_block"
@@ -1226,9 +1227,8 @@ static int mspro_block_init_disk(struct
 	blk_queue_prep_rq(msb->queue, mspro_block_prepare_req);
 
 	blk_queue_bounce_limit(msb->queue, limit);
-	blk_queue_max_sectors(msb->queue, MSPRO_BLOCK_MAX_PAGES);
-	blk_queue_max_phys_segments(msb->queue, MSPRO_BLOCK_MAX_SEGS);
-	blk_queue_max_hw_segments(msb->queue, MSPRO_BLOCK_MAX_SEGS);
+	blk_queue_max_hw_sectors(msb->queue, MSPRO_BLOCK_MAX_PAGES);
+	blk_queue_max_segments(msb->queue, MSPRO_BLOCK_MAX_SEGS);
 	blk_queue_max_segment_size(msb->queue,
 				   MSPRO_BLOCK_MAX_PAGES * msb->page_size);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/memstick/host/jmb38x_ms.c linux-libre-2.6.34-gnu1/drivers/memstick/host/jmb38x_ms.c
--- linux-libre-2.6.33-gnu1/drivers/memstick/host/jmb38x_ms.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/memstick/host/jmb38x_ms.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/highmem.h>
 #include <linux/memstick.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "jmb38x_ms"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/message/fusion/mptbase.c linux-libre-2.6.34-gnu1/drivers/message/fusion/mptbase.c
--- linux-libre-2.6.33-gnu1/drivers/message/fusion/mptbase.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/message/fusion/mptbase.c	2010-05-16 17:17:36.000000000 -0400
@@ -126,8 +126,6 @@ static int mfcounter = 0;
  *  Public data...
  */
 
-static struct proc_dir_entry *mpt_proc_root_dir;
-
 #define WHOINIT_UNKNOWN		0xAA
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -146,6 +144,9 @@ static MPT_EVHANDLER		 MptEvHandlers[MPT
 static MPT_RESETHANDLER		 MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
 static struct mpt_pci_driver 	*MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
 
+#ifdef CONFIG_PROC_FS
+static struct proc_dir_entry 	*mpt_proc_root_dir;
+#endif
 
 /*
  *  Driver Callback Index's
diff -druNp linux-libre-2.6.33-gnu1/drivers/message/fusion/mptbase.h linux-libre-2.6.34-gnu1/drivers/message/fusion/mptbase.h
--- linux-libre-2.6.33-gnu1/drivers/message/fusion/mptbase.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/message/fusion/mptbase.h	2010-05-16 17:17:36.000000000 -0400
@@ -76,8 +76,8 @@
 #define COPYRIGHT	"Copyright (c) 1999-2008 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"3.04.13"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.04.13"
+#define MPT_LINUX_VERSION_COMMON	"3.04.14"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.04.14"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
diff -druNp linux-libre-2.6.33-gnu1/drivers/message/fusion/mptctl.c linux-libre-2.6.34-gnu1/drivers/message/fusion/mptctl.c
--- linux-libre-2.6.33-gnu1/drivers/message/fusion/mptctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/message/fusion/mptctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -360,8 +360,8 @@ static int mptctl_bus_reset(MPT_ADAPTER
 	u16		 iocstatus;
 
 	/* bus reset is only good for SCSI IO, RAID PASSTHRU */
-	if (!(function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) ||
-	    (function == MPI_FUNCTION_SCSI_IO_REQUEST)) {
+	if (!(function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH ||
+		function == MPI_FUNCTION_SCSI_IO_REQUEST)) {
 		dtmprintk(ioc, printk(MYIOC_s_WARN_FMT
 			"TaskMgmt, not SCSI_IO!!\n", ioc->name));
 		return -EPERM;
diff -druNp linux-libre-2.6.33-gnu1/drivers/message/fusion/mptfc.c linux-libre-2.6.34-gnu1/drivers/message/fusion/mptfc.c
--- linux-libre-2.6.33-gnu1/drivers/message/fusion/mptfc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/message/fusion/mptfc.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,6 +54,7 @@
 #include <linux/reboot.h>	/* notifier code */
 #include <linux/workqueue.h>
 #include <linux/sort.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -195,29 +196,34 @@ mptfc_block_error_handler(struct scsi_cm
 	unsigned long		flags;
 	int			ready;
 	MPT_ADAPTER 		*ioc;
+	int			loops = 40;	/* seconds */
 
 	hd = shost_priv(SCpnt->device->host);
 	ioc = hd->ioc;
 	spin_lock_irqsave(shost->host_lock, flags);
-	while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY) {
+	while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY
+	 || (loops > 0 && ioc->active == 0)) {
 		spin_unlock_irqrestore(shost->host_lock, flags);
 		dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
 			"mptfc_block_error_handler.%d: %d:%d, port status is "
-			"DID_IMM_RETRY, deferring %s recovery.\n",
+			"%x, active flag %d, deferring %s recovery.\n",
 			ioc->name, ioc->sh->host_no,
-			SCpnt->device->id, SCpnt->device->lun, caller));
+			SCpnt->device->id, SCpnt->device->lun,
+			ready, ioc->active, caller));
 		msleep(1000);
 		spin_lock_irqsave(shost->host_lock, flags);
+		loops --;
 	}
 	spin_unlock_irqrestore(shost->host_lock, flags);
 
-	if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata) {
+	if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata
+	 || ioc->active == 0) {
 		dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
 			"%s.%d: %d:%d, failing recovery, "
-			"port state %d, vdevice %p.\n", caller,
+			"port state %x, active %d, vdevice %p.\n", caller,
 			ioc->name, ioc->sh->host_no,
 			SCpnt->device->id, SCpnt->device->lun, ready,
-			SCpnt->device->hostdata));
+			ioc->active, SCpnt->device->hostdata));
 		return FAILED;
 	}
 	dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
diff -druNp linux-libre-2.6.33-gnu1/drivers/message/fusion/mptlan.c linux-libre-2.6.34-gnu1/drivers/message/fusion/mptlan.c
--- linux-libre-2.6.33-gnu1/drivers/message/fusion/mptlan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/message/fusion/mptlan.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,6 +57,7 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #define my_VERSION	MPT_LINUX_VERSION_COMMON
 #define MYNAM		"mptlan"
diff -druNp linux-libre-2.6.33-gnu1/drivers/message/fusion/mptsas.c linux-libre-2.6.34-gnu1/drivers/message/fusion/mptsas.c
--- linux-libre-2.6.33-gnu1/drivers/message/fusion/mptsas.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/message/fusion/mptsas.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,6 +45,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/jiffies.h>
@@ -1075,6 +1076,19 @@ mptsas_target_reset(MPT_ADAPTER *ioc, u8
 	return 0;
 }
 
+static void
+mptsas_block_io_sdev(struct scsi_device *sdev, void *data)
+{
+	scsi_device_set_state(sdev, SDEV_BLOCK);
+}
+
+static void
+mptsas_block_io_starget(struct scsi_target *starget)
+{
+	if (starget)
+		starget_for_each_device(starget, NULL, mptsas_block_io_sdev);
+}
+
 /**
  * mptsas_target_reset_queue
  *
@@ -1098,10 +1112,11 @@ mptsas_target_reset_queue(MPT_ADAPTER *i
 	id = sas_event_data->TargetID;
 	channel = sas_event_data->Bus;
 
-	if (!(vtarget = mptsas_find_vtarget(ioc, channel, id)))
-		return;
-
-	vtarget->deleted = 1; /* block IO */
+	vtarget = mptsas_find_vtarget(ioc, channel, id);
+	if (vtarget) {
+		mptsas_block_io_starget(vtarget->starget);
+		vtarget->deleted = 1; /* block IO */
+	}
 
 	target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event),
 	    GFP_ATOMIC);
@@ -1868,7 +1883,8 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, voi
 	if (ioc->sas_discovery_quiesce_io)
 		return SCSI_MLQUEUE_HOST_BUSY;
 
-//	scsi_print_command(SCpnt);
+	if (ioc->debug_level & MPT_DEBUG_SCSI)
+		scsi_print_command(SCpnt);
 
 	return mptscsih_qcmd(SCpnt,done);
 }
@@ -2686,6 +2702,187 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc
 	return error;
 }
 
+struct rep_manu_request{
+	u8 smp_frame_type;
+	u8 function;
+	u8 reserved;
+	u8 request_length;
+};
+
+struct rep_manu_reply{
+	u8 smp_frame_type; /* 0x41 */
+	u8 function; /* 0x01 */
+	u8 function_result;
+	u8 response_length;
+	u16 expander_change_count;
+	u8 reserved0[2];
+	u8 sas_format:1;
+	u8 reserved1:7;
+	u8 reserved2[3];
+	u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
+	u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
+	u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
+	u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
+	u16 component_id;
+	u8 component_revision_id;
+	u8 reserved3;
+	u8 vendor_specific[8];
+};
+
+/**
+  * mptsas_exp_repmanufacture_info -
+  * @ioc: per adapter object
+  * @sas_address: expander sas address
+  * @edev: the sas_expander_device object
+  *
+  * Fills in the sas_expander_device object when SMP port is created.
+  *
+  * Returns 0 for success, non-zero for failure.
+  */
+static int
+mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
+	u64 sas_address, struct sas_expander_device *edev)
+{
+	MPT_FRAME_HDR *mf;
+	SmpPassthroughRequest_t *smpreq;
+	SmpPassthroughReply_t *smprep;
+	struct rep_manu_reply *manufacture_reply;
+	struct rep_manu_request *manufacture_request;
+	int ret;
+	int flagsLength;
+	unsigned long timeleft;
+	char *psge;
+	unsigned long flags;
+	void *data_out = NULL;
+	dma_addr_t data_out_dma = 0;
+	u32 sz;
+
+	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
+	if (ioc->ioc_reset_in_progress) {
+		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
+		printk(MYIOC_s_INFO_FMT "%s: host reset in progress!\n",
+			__func__, ioc->name);
+		return -EFAULT;
+	}
+	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
+
+	ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
+	if (ret)
+		goto out;
+
+	mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
+	if (!mf) {
+		ret = -ENOMEM;
+		goto out_unlock;
+	}
+
+	smpreq = (SmpPassthroughRequest_t *)mf;
+	memset(smpreq, 0, sizeof(*smpreq));
+
+	sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
+
+	data_out = pci_alloc_consistent(ioc->pcidev, sz, &data_out_dma);
+	if (!data_out) {
+		printk(KERN_ERR "Memory allocation failure at %s:%d/%s()!\n",
+			__FILE__, __LINE__, __func__);
+		ret = -ENOMEM;
+		goto put_mf;
+	}
+
+	manufacture_request = data_out;
+	manufacture_request->smp_frame_type = 0x40;
+	manufacture_request->function = 1;
+	manufacture_request->reserved = 0;
+	manufacture_request->request_length = 0;
+
+	smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
+	smpreq->PhysicalPort = 0xFF;
+	*((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
+	smpreq->RequestDataLength = sizeof(struct rep_manu_request);
+
+	psge = (char *)
+		(((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
+
+	flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
+		MPI_SGE_FLAGS_SYSTEM_ADDRESS |
+		MPI_SGE_FLAGS_HOST_TO_IOC |
+		MPI_SGE_FLAGS_END_OF_BUFFER;
+	flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
+	flagsLength |= sizeof(struct rep_manu_request);
+
+	ioc->add_sge(psge, flagsLength, data_out_dma);
+	psge += ioc->SGE_size;
+
+	flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
+		MPI_SGE_FLAGS_SYSTEM_ADDRESS |
+		MPI_SGE_FLAGS_IOC_TO_HOST |
+		MPI_SGE_FLAGS_END_OF_BUFFER;
+	flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
+	flagsLength |= sizeof(struct rep_manu_reply);
+	ioc->add_sge(psge, flagsLength, data_out_dma +
+	sizeof(struct rep_manu_request));
+
+	INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
+	mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
+
+	timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
+	if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
+		ret = -ETIME;
+		mpt_free_msg_frame(ioc, mf);
+		mf = NULL;
+		if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
+			goto out_free;
+		if (!timeleft)
+			mpt_HardResetHandler(ioc, CAN_SLEEP);
+		goto out_free;
+	}
+
+	mf = NULL;
+
+	if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
+		u8 *tmp;
+
+	smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
+	if (le16_to_cpu(smprep->ResponseDataLength) !=
+		sizeof(struct rep_manu_reply))
+			goto out_free;
+
+	manufacture_reply = data_out + sizeof(struct rep_manu_request);
+	strncpy(edev->vendor_id, manufacture_reply->vendor_id,
+		SAS_EXPANDER_VENDOR_ID_LEN);
+	strncpy(edev->product_id, manufacture_reply->product_id,
+		SAS_EXPANDER_PRODUCT_ID_LEN);
+	strncpy(edev->product_rev, manufacture_reply->product_rev,
+		SAS_EXPANDER_PRODUCT_REV_LEN);
+	edev->level = manufacture_reply->sas_format;
+	if (manufacture_reply->sas_format) {
+		strncpy(edev->component_vendor_id,
+			manufacture_reply->component_vendor_id,
+				SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
+		tmp = (u8 *)&manufacture_reply->component_id;
+		edev->component_id = tmp[0] << 8 | tmp[1];
+		edev->component_revision_id =
+			manufacture_reply->component_revision_id;
+		}
+	} else {
+		printk(MYIOC_s_ERR_FMT
+			"%s: smp passthru reply failed to be returned\n",
+			ioc->name, __func__);
+		ret = -ENXIO;
+	}
+out_free:
+	if (data_out_dma)
+		pci_free_consistent(ioc->pcidev, sz, data_out, data_out_dma);
+put_mf:
+	if (mf)
+		mpt_free_msg_frame(ioc, mf);
+out_unlock:
+	CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
+	mutex_unlock(&ioc->sas_mgmt.mutex);
+out:
+	return ret;
+ }
+
 static void
 mptsas_parse_device_info(struct sas_identify *identify,
 		struct mptsas_devinfo *device_info)
@@ -2967,6 +3164,11 @@ static int mptsas_probe_one_phy(struct d
 			goto out;
 		}
 		mptsas_set_rphy(ioc, phy_info, rphy);
+		if (identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
+			identify.device_type == SAS_FANOUT_EXPANDER_DEVICE)
+				mptsas_exp_repmanufacture_info(ioc,
+					identify.sas_address,
+					rphy_to_expander_device(rphy));
 	}
 
  out:
diff -druNp linux-libre-2.6.33-gnu1/drivers/message/fusion/mptscsih.c linux-libre-2.6.34-gnu1/drivers/message/fusion/mptscsih.c
--- linux-libre-2.6.33-gnu1/drivers/message/fusion/mptscsih.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/message/fusion/mptscsih.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/kdev_t.h>
@@ -1438,9 +1439,14 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, v
 	    && (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
 	    && (SCpnt->device->tagged_supported)) {
 		scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
-	} else {
+		if (SCpnt->request && SCpnt->request->ioprio) {
+			if (((SCpnt->request->ioprio & 0x7) == 1) ||
+				!(SCpnt->request->ioprio & 0x7))
+				scsictl |= MPI_SCSIIO_CONTROL_HEADOFQ;
+		}
+	} else
 		scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
-	}
+
 
 	/* Use the above information to set up the message frame
 	 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/message/fusion/mptspi.c linux-libre-2.6.34-gnu1/drivers/message/fusion/mptspi.c
--- linux-libre-2.6.33-gnu1/drivers/message/fusion/mptspi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/message/fusion/mptspi.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/kdev_t.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/message/i2o/i2o_block.c linux-libre-2.6.34-gnu1/drivers/message/i2o/i2o_block.c
--- linux-libre-2.6.33-gnu1/drivers/message/i2o/i2o_block.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/message/i2o/i2o_block.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,6 +51,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/i2o.h>
 
 #include <linux/mempool.h>
@@ -1065,9 +1066,8 @@ static int i2o_block_probe(struct device
 	queue = gd->queue;
 	queue->queuedata = i2o_blk_dev;
 
-	blk_queue_max_phys_segments(queue, I2O_MAX_PHYS_SEGMENTS);
-	blk_queue_max_sectors(queue, max_sectors);
-	blk_queue_max_hw_segments(queue, i2o_sg_tablesize(c, body_size));
+	blk_queue_max_hw_sectors(queue, max_sectors);
+	blk_queue_max_segments(queue, i2o_sg_tablesize(c, body_size));
 
 	osm_debug("max sectors = %d\n", queue->max_sectors);
 	osm_debug("phys segments = %d\n", queue->max_phys_segments);
diff -druNp linux-libre-2.6.33-gnu1/drivers/message/i2o/i2o_config.c linux-libre-2.6.34-gnu1/drivers/message/i2o/i2o_config.c
--- linux-libre-2.6.33-gnu1/drivers/message/i2o/i2o_config.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/message/i2o/i2o_config.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/miscdevice.h>
 #include <linux/smp_lock.h>
 #include <linux/compat.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/message/i2o/i2o_proc.c linux-libre-2.6.34-gnu1/drivers/message/i2o/i2o_proc.c
--- linux-libre-2.6.33-gnu1/drivers/message/i2o/i2o_proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/message/i2o/i2o_proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/i2o.h>
+#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
@@ -111,10 +112,7 @@ static int print_serial_number(struct se
 		break;
 
 	case I2O_SNFORMAT_LAN48_MAC:	/* LAN-48 MAC Address */
-		seq_printf(seq,
-			   "LAN-48 MAC address @ %02X:%02X:%02X:%02X:%02X:%02X",
-			   serialno[2], serialno[3],
-			   serialno[4], serialno[5], serialno[6], serialno[7]);
+		seq_printf(seq, "LAN-48 MAC address @ %pM", &serialno[2]);
 		break;
 
 	case I2O_SNFORMAT_WAN:	/* WAN MAC Address */
@@ -126,10 +124,8 @@ static int print_serial_number(struct se
 	case I2O_SNFORMAT_LAN64_MAC:	/* LAN-64 MAC Address */
 		/* FIXME: Figure out what a LAN-64 address really looks like?? */
 		seq_printf(seq,
-			   "LAN-64 MAC address @ [?:%02X:%02X:?] %02X:%02X:%02X:%02X:%02X:%02X",
-			   serialno[8], serialno[9],
-			   serialno[2], serialno[3],
-			   serialno[4], serialno[5], serialno[6], serialno[7]);
+			   "LAN-64 MAC address @ [?:%02X:%02X:?] %pM",
+			   serialno[8], serialno[9], &serialno[2]);
 		break;
 
 	case I2O_SNFORMAT_DDM:	/* I2O DDM */
diff -druNp linux-libre-2.6.33-gnu1/drivers/message/i2o/iop.c linux-libre-2.6.34-gnu1/drivers/message/i2o/iop.c
--- linux-libre-2.6.33-gnu1/drivers/message/i2o/iop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/message/i2o/iop.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/i2o.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "core.h"
 
 #define OSM_NAME	"i2o"
@@ -539,7 +540,7 @@ static int i2o_iop_reset(struct i2o_cont
 		 * which is indeterminate. We need to wait until the IOP has
 		 * rebooted before we can let the system talk to it. We read
 		 * the inbound Free_List until a message is available. If we
-		 * can't read one in the given ammount of time, we assume the
+		 * can't read one in the given amount of time, we assume the
 		 * IOP could not reboot properly.
 		 */
 		osm_debug("%s: Reset in progress, waiting for reboot...\n",
diff -druNp linux-libre-2.6.33-gnu1/drivers/message/i2o/pci.c linux-libre-2.6.34-gnu1/drivers/message/i2o/pci.c
--- linux-libre-2.6.33-gnu1/drivers/message/i2o/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/message/i2o/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 
 #include <linux/pci.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/i2o.h>
 #include "core.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/88pm8607.c linux-libre-2.6.34-gnu1/drivers/mfd/88pm8607.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/88pm8607.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/88pm8607.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,302 +0,0 @@
-/*
- * Base driver for Marvell 88PM8607
- *
- * Copyright (C) 2009 Marvell International Ltd.
- * 	Haojian Zhuang <haojian.zhuang@marvell.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/88pm8607.h>
-
-
-#define PM8607_REG_RESOURCE(_start, _end)		\
-{							\
-	.start	= PM8607_##_start,			\
-	.end	= PM8607_##_end,			\
-	.flags	= IORESOURCE_IO,			\
-}
-
-static struct resource pm8607_regulator_resources[] = {
-	PM8607_REG_RESOURCE(BUCK1, BUCK1),
-	PM8607_REG_RESOURCE(BUCK2, BUCK2),
-	PM8607_REG_RESOURCE(BUCK3, BUCK3),
-	PM8607_REG_RESOURCE(LDO1,  LDO1),
-	PM8607_REG_RESOURCE(LDO2,  LDO2),
-	PM8607_REG_RESOURCE(LDO3,  LDO3),
-	PM8607_REG_RESOURCE(LDO4,  LDO4),
-	PM8607_REG_RESOURCE(LDO5,  LDO5),
-	PM8607_REG_RESOURCE(LDO6,  LDO6),
-	PM8607_REG_RESOURCE(LDO7,  LDO7),
-	PM8607_REG_RESOURCE(LDO8,  LDO8),
-	PM8607_REG_RESOURCE(LDO9,  LDO9),
-	PM8607_REG_RESOURCE(LDO10, LDO10),
-	PM8607_REG_RESOURCE(LDO12, LDO12),
-	PM8607_REG_RESOURCE(LDO14, LDO14),
-};
-
-#define PM8607_REG_DEVS(_name, _id)					\
-{									\
-	.name		= "88pm8607-" #_name,				\
-	.num_resources	= 1,						\
-	.resources	= &pm8607_regulator_resources[PM8607_ID_##_id],	\
-}
-
-static struct mfd_cell pm8607_devs[] = {
-	PM8607_REG_DEVS(buck1, BUCK1),
-	PM8607_REG_DEVS(buck2, BUCK2),
-	PM8607_REG_DEVS(buck3, BUCK3),
-	PM8607_REG_DEVS(ldo1,  LDO1),
-	PM8607_REG_DEVS(ldo2,  LDO2),
-	PM8607_REG_DEVS(ldo3,  LDO3),
-	PM8607_REG_DEVS(ldo4,  LDO4),
-	PM8607_REG_DEVS(ldo5,  LDO5),
-	PM8607_REG_DEVS(ldo6,  LDO6),
-	PM8607_REG_DEVS(ldo7,  LDO7),
-	PM8607_REG_DEVS(ldo8,  LDO8),
-	PM8607_REG_DEVS(ldo9,  LDO9),
-	PM8607_REG_DEVS(ldo10, LDO10),
-	PM8607_REG_DEVS(ldo12, LDO12),
-	PM8607_REG_DEVS(ldo14, LDO14),
-};
-
-static inline int pm8607_read_device(struct pm8607_chip *chip,
-				     int reg, int bytes, void *dest)
-{
-	struct i2c_client *i2c = chip->client;
-	unsigned char data;
-	int ret;
-
-	data = (unsigned char)reg;
-	ret = i2c_master_send(i2c, &data, 1);
-	if (ret < 0)
-		return ret;
-
-	ret = i2c_master_recv(i2c, dest, bytes);
-	if (ret < 0)
-		return ret;
-	return 0;
-}
-
-static inline int pm8607_write_device(struct pm8607_chip *chip,
-				      int reg, int bytes, void *src)
-{
-	struct i2c_client *i2c = chip->client;
-	unsigned char buf[bytes + 1];
-	int ret;
-
-	buf[0] = (unsigned char)reg;
-	memcpy(&buf[1], src, bytes);
-
-	ret = i2c_master_send(i2c, buf, bytes + 1);
-	if (ret < 0)
-		return ret;
-	return 0;
-}
-
-int pm8607_reg_read(struct pm8607_chip *chip, int reg)
-{
-	unsigned char data;
-	int ret;
-
-	mutex_lock(&chip->io_lock);
-	ret = chip->read(chip, reg, 1, &data);
-	mutex_unlock(&chip->io_lock);
-
-	if (ret < 0)
-		return ret;
-	else
-		return (int)data;
-}
-EXPORT_SYMBOL(pm8607_reg_read);
-
-int pm8607_reg_write(struct pm8607_chip *chip, int reg,
-		     unsigned char data)
-{
-	int ret;
-
-	mutex_lock(&chip->io_lock);
-	ret = chip->write(chip, reg, 1, &data);
-	mutex_unlock(&chip->io_lock);
-
-	return ret;
-}
-EXPORT_SYMBOL(pm8607_reg_write);
-
-int pm8607_bulk_read(struct pm8607_chip *chip, int reg,
-		     int count, unsigned char *buf)
-{
-	int ret;
-
-	mutex_lock(&chip->io_lock);
-	ret = chip->read(chip, reg, count, buf);
-	mutex_unlock(&chip->io_lock);
-
-	return ret;
-}
-EXPORT_SYMBOL(pm8607_bulk_read);
-
-int pm8607_bulk_write(struct pm8607_chip *chip, int reg,
-		      int count, unsigned char *buf)
-{
-	int ret;
-
-	mutex_lock(&chip->io_lock);
-	ret = chip->write(chip, reg, count, buf);
-	mutex_unlock(&chip->io_lock);
-
-	return ret;
-}
-EXPORT_SYMBOL(pm8607_bulk_write);
-
-int pm8607_set_bits(struct pm8607_chip *chip, int reg,
-		    unsigned char mask, unsigned char data)
-{
-	unsigned char value;
-	int ret;
-
-	mutex_lock(&chip->io_lock);
-	ret = chip->read(chip, reg, 1, &value);
-	if (ret < 0)
-		goto out;
-	value &= ~mask;
-	value |= data;
-	ret = chip->write(chip, reg, 1, &value);
-out:
-	mutex_unlock(&chip->io_lock);
-	return ret;
-}
-EXPORT_SYMBOL(pm8607_set_bits);
-
-
-static const struct i2c_device_id pm8607_id_table[] = {
-	{ "88PM8607", 0 },
-	{}
-};
-MODULE_DEVICE_TABLE(i2c, pm8607_id_table);
-
-
-static int __devinit pm8607_probe(struct i2c_client *client,
-				  const struct i2c_device_id *id)
-{
-	struct pm8607_platform_data *pdata = client->dev.platform_data;
-	struct pm8607_chip *chip;
-	int i, count;
-	int ret;
-
-	chip = kzalloc(sizeof(struct pm8607_chip), GFP_KERNEL);
-	if (chip == NULL)
-		return -ENOMEM;
-
-	chip->client = client;
-	chip->dev = &client->dev;
-	chip->read = pm8607_read_device;
-	chip->write = pm8607_write_device;
-	i2c_set_clientdata(client, chip);
-
-	mutex_init(&chip->io_lock);
-	dev_set_drvdata(chip->dev, chip);
-
-	ret = pm8607_reg_read(chip, PM8607_CHIP_ID);
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
-		goto out;
-	}
-	if ((ret & CHIP_ID_MASK) == CHIP_ID)
-		dev_info(chip->dev, "Marvell 88PM8607 (ID: %02x) detected\n",
-			 ret);
-	else {
-		dev_err(chip->dev, "Failed to detect Marvell 88PM8607. "
-			"Chip ID: %02x\n", ret);
-		goto out;
-	}
-	chip->chip_id = ret;
-
-	ret = pm8607_reg_read(chip, PM8607_BUCK3);
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to read BUCK3 register: %d\n", ret);
-		goto out;
-	}
-	if (ret & PM8607_BUCK3_DOUBLE)
-		chip->buck3_double = 1;
-
-	ret = pm8607_reg_read(chip, PM8607_MISC1);
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to read MISC1 register: %d\n", ret);
-		goto out;
-	}
-	if (pdata->i2c_port == PI2C_PORT)
-		ret |= PM8607_MISC1_PI2C;
-	else
-		ret &= ~PM8607_MISC1_PI2C;
-	ret = pm8607_reg_write(chip, PM8607_MISC1, ret);
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to write MISC1 register: %d\n", ret);
-		goto out;
-	}
-
-
-	count = ARRAY_SIZE(pm8607_devs);
-	for (i = 0; i < count; i++) {
-		ret = mfd_add_devices(chip->dev, i, &pm8607_devs[i],
-				      1, NULL, 0);
-		if (ret != 0) {
-			dev_err(chip->dev, "Failed to add subdevs\n");
-			goto out;
-		}
-	}
-
-	return 0;
-
-out:
-	i2c_set_clientdata(client, NULL);
-	kfree(chip);
-	return ret;
-}
-
-static int __devexit pm8607_remove(struct i2c_client *client)
-{
-	struct pm8607_chip *chip = i2c_get_clientdata(client);
-
-	mfd_remove_devices(chip->dev);
-	kfree(chip);
-	return 0;
-}
-
-static struct i2c_driver pm8607_driver = {
-	.driver	= {
-		.name	= "88PM8607",
-		.owner	= THIS_MODULE,
-	},
-	.probe		= pm8607_probe,
-	.remove		= __devexit_p(pm8607_remove),
-	.id_table	= pm8607_id_table,
-};
-
-static int __init pm8607_init(void)
-{
-	int ret;
-	ret = i2c_add_driver(&pm8607_driver);
-	if (ret != 0)
-		pr_err("Failed to register 88PM8607 I2C driver: %d\n", ret);
-	return ret;
-}
-subsys_initcall(pm8607_init);
-
-static void __exit pm8607_exit(void)
-{
-	i2c_del_driver(&pm8607_driver);
-}
-module_exit(pm8607_exit);
-
-MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM8607");
-MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/88pm860x-core.c linux-libre-2.6.34-gnu1/drivers/mfd/88pm860x-core.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/88pm860x-core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/88pm860x-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,740 @@
+/*
+ * Base driver for Marvell 88PM8607
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ * 	Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/88pm860x.h>
+
+#define INT_STATUS_NUM			3
+
+char pm860x_backlight_name[][MFD_NAME_SIZE] = {
+	"backlight-0",
+	"backlight-1",
+	"backlight-2",
+};
+EXPORT_SYMBOL(pm860x_backlight_name);
+
+char pm860x_led_name[][MFD_NAME_SIZE] = {
+	"led0-red",
+	"led0-green",
+	"led0-blue",
+	"led1-red",
+	"led1-green",
+	"led1-blue",
+};
+EXPORT_SYMBOL(pm860x_led_name);
+
+#define PM8606_BACKLIGHT_RESOURCE(_i, _x)		\
+{							\
+	.name	= pm860x_backlight_name[_i],		\
+	.start	= PM8606_##_x,				\
+	.end	= PM8606_##_x,				\
+	.flags	= IORESOURCE_IO,			\
+}
+
+static struct resource backlight_resources[] = {
+	PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT1, WLED1A),
+	PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT2, WLED2A),
+	PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT3, WLED3A),
+};
+
+#define PM8606_BACKLIGHT_DEVS(_i)			\
+{							\
+	.name		= "88pm860x-backlight",		\
+	.num_resources	= 1,				\
+	.resources	= &backlight_resources[_i],	\
+	.id		= _i,				\
+}
+
+static struct mfd_cell backlight_devs[] = {
+	PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT1),
+	PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT2),
+	PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT3),
+};
+
+#define PM8606_LED_RESOURCE(_i, _x)			\
+{							\
+	.name	= pm860x_led_name[_i],			\
+	.start	= PM8606_##_x,				\
+	.end	= PM8606_##_x,				\
+	.flags	= IORESOURCE_IO,			\
+}
+
+static struct resource led_resources[] = {
+	PM8606_LED_RESOURCE(PM8606_LED1_RED, RGB2B),
+	PM8606_LED_RESOURCE(PM8606_LED1_GREEN, RGB2C),
+	PM8606_LED_RESOURCE(PM8606_LED1_BLUE, RGB2D),
+	PM8606_LED_RESOURCE(PM8606_LED2_RED, RGB1B),
+	PM8606_LED_RESOURCE(PM8606_LED2_GREEN, RGB1C),
+	PM8606_LED_RESOURCE(PM8606_LED2_BLUE, RGB1D),
+};
+
+#define PM8606_LED_DEVS(_i)				\
+{							\
+	.name		= "88pm860x-led",		\
+	.num_resources	= 1,				\
+	.resources	= &led_resources[_i],		\
+	.id		= _i,				\
+}
+
+static struct mfd_cell led_devs[] = {
+	PM8606_LED_DEVS(PM8606_LED1_RED),
+	PM8606_LED_DEVS(PM8606_LED1_GREEN),
+	PM8606_LED_DEVS(PM8606_LED1_BLUE),
+	PM8606_LED_DEVS(PM8606_LED2_RED),
+	PM8606_LED_DEVS(PM8606_LED2_GREEN),
+	PM8606_LED_DEVS(PM8606_LED2_BLUE),
+};
+
+static struct resource touch_resources[] = {
+	{
+		.start	= PM8607_IRQ_PEN,
+		.end	= PM8607_IRQ_PEN,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mfd_cell touch_devs[] = {
+	{
+		.name		= "88pm860x-touch",
+		.num_resources	= 1,
+		.resources	= &touch_resources[0],
+	},
+};
+
+#define PM8607_REG_RESOURCE(_start, _end)		\
+{							\
+	.start	= PM8607_##_start,			\
+	.end	= PM8607_##_end,			\
+	.flags	= IORESOURCE_IO,			\
+}
+
+static struct resource power_supply_resources[] = {
+	{
+		.name		= "88pm860x-power",
+		.start		= PM8607_IRQ_CHG,
+		.end		= PM8607_IRQ_CHG,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct mfd_cell power_devs[] = {
+	{
+		.name		= "88pm860x-power",
+		.num_resources	= 1,
+		.resources	= &power_supply_resources[0],
+		.id		= -1,
+	},
+};
+
+static struct resource onkey_resources[] = {
+	{
+		.name		= "88pm860x-onkey",
+		.start		= PM8607_IRQ_ONKEY,
+		.end		= PM8607_IRQ_ONKEY,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct mfd_cell onkey_devs[] = {
+	{
+		.name		= "88pm860x-onkey",
+		.num_resources	= 1,
+		.resources	= &onkey_resources[0],
+		.id		= -1,
+	},
+};
+
+static struct resource regulator_resources[] = {
+	PM8607_REG_RESOURCE(BUCK1, BUCK1),
+	PM8607_REG_RESOURCE(BUCK2, BUCK2),
+	PM8607_REG_RESOURCE(BUCK3, BUCK3),
+	PM8607_REG_RESOURCE(LDO1,  LDO1),
+	PM8607_REG_RESOURCE(LDO2,  LDO2),
+	PM8607_REG_RESOURCE(LDO3,  LDO3),
+	PM8607_REG_RESOURCE(LDO4,  LDO4),
+	PM8607_REG_RESOURCE(LDO5,  LDO5),
+	PM8607_REG_RESOURCE(LDO6,  LDO6),
+	PM8607_REG_RESOURCE(LDO7,  LDO7),
+	PM8607_REG_RESOURCE(LDO8,  LDO8),
+	PM8607_REG_RESOURCE(LDO9,  LDO9),
+	PM8607_REG_RESOURCE(LDO10, LDO10),
+	PM8607_REG_RESOURCE(LDO12, LDO12),
+	PM8607_REG_RESOURCE(LDO14, LDO14),
+};
+
+#define PM8607_REG_DEVS(_name, _id)					\
+{									\
+	.name		= "88pm8607-" #_name,				\
+	.num_resources	= 1,						\
+	.resources	= &regulator_resources[PM8607_ID_##_id],	\
+	.id		= PM8607_ID_##_id,				\
+}
+
+static struct mfd_cell regulator_devs[] = {
+	PM8607_REG_DEVS(buck1, BUCK1),
+	PM8607_REG_DEVS(buck2, BUCK2),
+	PM8607_REG_DEVS(buck3, BUCK3),
+	PM8607_REG_DEVS(ldo1,  LDO1),
+	PM8607_REG_DEVS(ldo2,  LDO2),
+	PM8607_REG_DEVS(ldo3,  LDO3),
+	PM8607_REG_DEVS(ldo4,  LDO4),
+	PM8607_REG_DEVS(ldo5,  LDO5),
+	PM8607_REG_DEVS(ldo6,  LDO6),
+	PM8607_REG_DEVS(ldo7,  LDO7),
+	PM8607_REG_DEVS(ldo8,  LDO8),
+	PM8607_REG_DEVS(ldo9,  LDO9),
+	PM8607_REG_DEVS(ldo10, LDO10),
+	PM8607_REG_DEVS(ldo12, LDO12),
+	PM8607_REG_DEVS(ldo14, LDO14),
+};
+
+struct pm860x_irq_data {
+	int	reg;
+	int	mask_reg;
+	int	enable;		/* enable or not */
+	int	offs;		/* bit offset in mask register */
+};
+
+static struct pm860x_irq_data pm860x_irqs[] = {
+	[PM8607_IRQ_ONKEY] = {
+		.reg		= PM8607_INT_STATUS1,
+		.mask_reg	= PM8607_INT_MASK_1,
+		.offs		= 1 << 0,
+	},
+	[PM8607_IRQ_EXTON] = {
+		.reg		= PM8607_INT_STATUS1,
+		.mask_reg	= PM8607_INT_MASK_1,
+		.offs		= 1 << 1,
+	},
+	[PM8607_IRQ_CHG] = {
+		.reg		= PM8607_INT_STATUS1,
+		.mask_reg	= PM8607_INT_MASK_1,
+		.offs		= 1 << 2,
+	},
+	[PM8607_IRQ_BAT] = {
+		.reg		= PM8607_INT_STATUS1,
+		.mask_reg	= PM8607_INT_MASK_1,
+		.offs		= 1 << 3,
+	},
+	[PM8607_IRQ_RTC] = {
+		.reg		= PM8607_INT_STATUS1,
+		.mask_reg	= PM8607_INT_MASK_1,
+		.offs		= 1 << 4,
+	},
+	[PM8607_IRQ_CC] = {
+		.reg		= PM8607_INT_STATUS1,
+		.mask_reg	= PM8607_INT_MASK_1,
+		.offs		= 1 << 5,
+	},
+	[PM8607_IRQ_VBAT] = {
+		.reg		= PM8607_INT_STATUS2,
+		.mask_reg	= PM8607_INT_MASK_2,
+		.offs		= 1 << 0,
+	},
+	[PM8607_IRQ_VCHG] = {
+		.reg		= PM8607_INT_STATUS2,
+		.mask_reg	= PM8607_INT_MASK_2,
+		.offs		= 1 << 1,
+	},
+	[PM8607_IRQ_VSYS] = {
+		.reg		= PM8607_INT_STATUS2,
+		.mask_reg	= PM8607_INT_MASK_2,
+		.offs		= 1 << 2,
+	},
+	[PM8607_IRQ_TINT] = {
+		.reg		= PM8607_INT_STATUS2,
+		.mask_reg	= PM8607_INT_MASK_2,
+		.offs		= 1 << 3,
+	},
+	[PM8607_IRQ_GPADC0] = {
+		.reg		= PM8607_INT_STATUS2,
+		.mask_reg	= PM8607_INT_MASK_2,
+		.offs		= 1 << 4,
+	},
+	[PM8607_IRQ_GPADC1] = {
+		.reg		= PM8607_INT_STATUS2,
+		.mask_reg	= PM8607_INT_MASK_2,
+		.offs		= 1 << 5,
+	},
+	[PM8607_IRQ_GPADC2] = {
+		.reg		= PM8607_INT_STATUS2,
+		.mask_reg	= PM8607_INT_MASK_2,
+		.offs		= 1 << 6,
+	},
+	[PM8607_IRQ_GPADC3] = {
+		.reg		= PM8607_INT_STATUS2,
+		.mask_reg	= PM8607_INT_MASK_2,
+		.offs		= 1 << 7,
+	},
+	[PM8607_IRQ_AUDIO_SHORT] = {
+		.reg		= PM8607_INT_STATUS3,
+		.mask_reg	= PM8607_INT_MASK_3,
+		.offs		= 1 << 0,
+	},
+	[PM8607_IRQ_PEN] = {
+		.reg		= PM8607_INT_STATUS3,
+		.mask_reg	= PM8607_INT_MASK_3,
+		.offs		= 1 << 1,
+	},
+	[PM8607_IRQ_HEADSET] = {
+		.reg		= PM8607_INT_STATUS3,
+		.mask_reg	= PM8607_INT_MASK_3,
+		.offs		= 1 << 2,
+	},
+	[PM8607_IRQ_HOOK] = {
+		.reg		= PM8607_INT_STATUS3,
+		.mask_reg	= PM8607_INT_MASK_3,
+		.offs		= 1 << 3,
+	},
+	[PM8607_IRQ_MICIN] = {
+		.reg		= PM8607_INT_STATUS3,
+		.mask_reg	= PM8607_INT_MASK_3,
+		.offs		= 1 << 4,
+	},
+	[PM8607_IRQ_CHG_FAIL] = {
+		.reg		= PM8607_INT_STATUS3,
+		.mask_reg	= PM8607_INT_MASK_3,
+		.offs		= 1 << 5,
+	},
+	[PM8607_IRQ_CHG_DONE] = {
+		.reg		= PM8607_INT_STATUS3,
+		.mask_reg	= PM8607_INT_MASK_3,
+		.offs		= 1 << 6,
+	},
+	[PM8607_IRQ_CHG_FAULT] = {
+		.reg		= PM8607_INT_STATUS3,
+		.mask_reg	= PM8607_INT_MASK_3,
+		.offs		= 1 << 7,
+	},
+};
+
+static inline struct pm860x_irq_data *irq_to_pm860x(struct pm860x_chip *chip,
+						    int irq)
+{
+	return &pm860x_irqs[irq - chip->irq_base];
+}
+
+static irqreturn_t pm860x_irq(int irq, void *data)
+{
+	struct pm860x_chip *chip = data;
+	struct pm860x_irq_data *irq_data;
+	struct i2c_client *i2c;
+	int read_reg = -1, value = 0;
+	int i;
+
+	i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+	for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
+		irq_data = &pm860x_irqs[i];
+		if (read_reg != irq_data->reg) {
+			read_reg = irq_data->reg;
+			value = pm860x_reg_read(i2c, irq_data->reg);
+		}
+		if (value & irq_data->enable)
+			handle_nested_irq(chip->irq_base + i);
+	}
+	return IRQ_HANDLED;
+}
+
+static void pm860x_irq_lock(unsigned int irq)
+{
+	struct pm860x_chip *chip = get_irq_chip_data(irq);
+
+	mutex_lock(&chip->irq_lock);
+}
+
+static void pm860x_irq_sync_unlock(unsigned int irq)
+{
+	struct pm860x_chip *chip = get_irq_chip_data(irq);
+	struct pm860x_irq_data *irq_data;
+	struct i2c_client *i2c;
+	static unsigned char cached[3] = {0x0, 0x0, 0x0};
+	unsigned char mask[3];
+	int i;
+
+	i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+	/* Load cached value. In initial, all IRQs are masked */
+	for (i = 0; i < 3; i++)
+		mask[i] = cached[i];
+	for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
+		irq_data = &pm860x_irqs[i];
+		switch (irq_data->mask_reg) {
+		case PM8607_INT_MASK_1:
+			mask[0] &= ~irq_data->offs;
+			mask[0] |= irq_data->enable;
+			break;
+		case PM8607_INT_MASK_2:
+			mask[1] &= ~irq_data->offs;
+			mask[1] |= irq_data->enable;
+			break;
+		case PM8607_INT_MASK_3:
+			mask[2] &= ~irq_data->offs;
+			mask[2] |= irq_data->enable;
+			break;
+		default:
+			dev_err(chip->dev, "wrong IRQ\n");
+			break;
+		}
+	}
+	/* update mask into registers */
+	for (i = 0; i < 3; i++) {
+		if (mask[i] != cached[i]) {
+			cached[i] = mask[i];
+			pm860x_reg_write(i2c, PM8607_INT_MASK_1 + i, mask[i]);
+		}
+	}
+
+	mutex_unlock(&chip->irq_lock);
+}
+
+static void pm860x_irq_enable(unsigned int irq)
+{
+	struct pm860x_chip *chip = get_irq_chip_data(irq);
+	pm860x_irqs[irq - chip->irq_base].enable
+		= pm860x_irqs[irq - chip->irq_base].offs;
+}
+
+static void pm860x_irq_disable(unsigned int irq)
+{
+	struct pm860x_chip *chip = get_irq_chip_data(irq);
+	pm860x_irqs[irq - chip->irq_base].enable = 0;
+}
+
+static struct irq_chip pm860x_irq_chip = {
+	.name		= "88pm860x",
+	.bus_lock	= pm860x_irq_lock,
+	.bus_sync_unlock = pm860x_irq_sync_unlock,
+	.enable		= pm860x_irq_enable,
+	.disable	= pm860x_irq_disable,
+};
+
+static int __devinit device_gpadc_init(struct pm860x_chip *chip,
+				       struct pm860x_platform_data *pdata)
+{
+	struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
+				: chip->companion;
+	int use_gpadc = 0, data, ret;
+
+	/* initialize GPADC without activating it */
+
+	if (pdata && pdata->touch) {
+		/* set GPADC MISC1 register */
+		data = 0;
+		data |= (pdata->touch->gpadc_prebias << 1)
+			& PM8607_GPADC_PREBIAS_MASK;
+		data |= (pdata->touch->slot_cycle << 3)
+			& PM8607_GPADC_SLOT_CYCLE_MASK;
+		data |= (pdata->touch->off_scale << 5)
+			& PM8607_GPADC_OFF_SCALE_MASK;
+		data |= (pdata->touch->sw_cal << 7)
+			& PM8607_GPADC_SW_CAL_MASK;
+		if (data) {
+			ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
+			if (ret < 0)
+				goto out;
+		}
+		/* set tsi prebias time */
+		if (pdata->touch->tsi_prebias) {
+			data = pdata->touch->tsi_prebias;
+			ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
+			if (ret < 0)
+				goto out;
+		}
+		/* set prebias & prechg time of pen detect */
+		data = 0;
+		data |= pdata->touch->pen_prebias & PM8607_PD_PREBIAS_MASK;
+		data |= (pdata->touch->pen_prechg << 5)
+			& PM8607_PD_PRECHG_MASK;
+		if (data) {
+			ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
+			if (ret < 0)
+				goto out;
+		}
+
+		use_gpadc = 1;
+	}
+
+	/* turn on GPADC */
+	if (use_gpadc) {
+		ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1,
+				      PM8607_GPADC_EN, PM8607_GPADC_EN);
+	}
+out:
+	return ret;
+}
+
+static int __devinit device_irq_init(struct pm860x_chip *chip,
+				     struct pm860x_platform_data *pdata)
+{
+	struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
+				: chip->companion;
+	unsigned char status_buf[INT_STATUS_NUM];
+	unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
+	struct irq_desc *desc;
+	int i, data, mask, ret = -EINVAL;
+	int __irq;
+
+	if (!pdata || !pdata->irq_base) {
+		dev_warn(chip->dev, "No interrupt support on IRQ base\n");
+		return -EINVAL;
+	}
+
+	mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR
+		| PM8607_B0_MISC1_INT_MASK;
+	data = 0;
+	chip->irq_mode = 0;
+	if (pdata && pdata->irq_mode) {
+		/*
+		 * irq_mode defines the way of clearing interrupt. If it's 1,
+		 * clear IRQ by write. Otherwise, clear it by read.
+		 * This control bit is valid from 88PM8607 B0 steping.
+		 */
+		data |= PM8607_B0_MISC1_INT_CLEAR;
+		chip->irq_mode = 1;
+	}
+	ret = pm860x_set_bits(i2c, PM8607_B0_MISC1, mask, data);
+	if (ret < 0)
+		goto out;
+
+	/* mask all IRQs */
+	memset(status_buf, 0, INT_STATUS_NUM);
+	ret = pm860x_bulk_write(i2c, PM8607_INT_MASK_1,
+				INT_STATUS_NUM, status_buf);
+	if (ret < 0)
+		goto out;
+
+	if (chip->irq_mode) {
+		/* clear interrupt status by write */
+		memset(status_buf, 0xFF, INT_STATUS_NUM);
+		ret = pm860x_bulk_write(i2c, PM8607_INT_STATUS1,
+					INT_STATUS_NUM, status_buf);
+	} else {
+		/* clear interrupt status by read */
+		ret = pm860x_bulk_read(i2c, PM8607_INT_STATUS1,
+					INT_STATUS_NUM, status_buf);
+	}
+	if (ret < 0)
+		goto out;
+
+	mutex_init(&chip->irq_lock);
+	chip->irq_base = pdata->irq_base;
+	chip->core_irq = i2c->irq;
+	if (!chip->core_irq)
+		goto out;
+
+	desc = irq_to_desc(chip->core_irq);
+
+	/* register IRQ by genirq */
+	for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
+		__irq = i + chip->irq_base;
+		set_irq_chip_data(__irq, chip);
+		set_irq_chip_and_handler(__irq, &pm860x_irq_chip,
+					 handle_edge_irq);
+		set_irq_nested_thread(__irq, 1);
+#ifdef CONFIG_ARM
+		set_irq_flags(__irq, IRQF_VALID);
+#else
+		set_irq_noprobe(__irq);
+#endif
+	}
+
+	ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags,
+				   "88pm860x", chip);
+	if (ret) {
+		dev_err(chip->dev, "Failed to request IRQ: %d\n", ret);
+		chip->core_irq = 0;
+	}
+
+	return 0;
+out:
+	chip->core_irq = 0;
+	return ret;
+}
+
+static void __devexit device_irq_exit(struct pm860x_chip *chip)
+{
+	if (chip->core_irq)
+		free_irq(chip->core_irq, chip);
+}
+
+static void __devinit device_8606_init(struct pm860x_chip *chip,
+				       struct i2c_client *i2c,
+				       struct pm860x_platform_data *pdata)
+{
+	int ret;
+
+	if (pdata && pdata->backlight) {
+		ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],
+				      ARRAY_SIZE(backlight_devs),
+				      &backlight_resources[0], 0);
+		if (ret < 0) {
+			dev_err(chip->dev, "Failed to add backlight "
+				"subdev\n");
+			goto out_dev;
+		}
+	}
+
+	if (pdata && pdata->led) {
+		ret = mfd_add_devices(chip->dev, 0, &led_devs[0],
+				      ARRAY_SIZE(led_devs),
+				      &led_resources[0], 0);
+		if (ret < 0) {
+			dev_err(chip->dev, "Failed to add led "
+				"subdev\n");
+			goto out_dev;
+		}
+	}
+	return;
+out_dev:
+	mfd_remove_devices(chip->dev);
+	device_irq_exit(chip);
+}
+
+static void __devinit device_8607_init(struct pm860x_chip *chip,
+				       struct i2c_client *i2c,
+				       struct pm860x_platform_data *pdata)
+{
+	int data, ret;
+
+	ret = pm860x_reg_read(i2c, PM8607_CHIP_ID);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
+		goto out;
+	}
+	if ((ret & PM8607_VERSION_MASK) == PM8607_VERSION)
+		dev_info(chip->dev, "Marvell 88PM8607 (ID: %02x) detected\n",
+			 ret);
+	else {
+		dev_err(chip->dev, "Failed to detect Marvell 88PM8607. "
+			"Chip ID: %02x\n", ret);
+		goto out;
+	}
+
+	ret = pm860x_reg_read(i2c, PM8607_BUCK3);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to read BUCK3 register: %d\n", ret);
+		goto out;
+	}
+	if (ret & PM8607_BUCK3_DOUBLE)
+		chip->buck3_double = 1;
+
+	ret = pm860x_reg_read(i2c, PM8607_B0_MISC1);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to read MISC1 register: %d\n", ret);
+		goto out;
+	}
+
+	if (pdata && (pdata->i2c_port == PI2C_PORT))
+		data = PM8607_B0_MISC1_PI2C;
+	else
+		data = 0;
+	ret = pm860x_set_bits(i2c, PM8607_B0_MISC1, PM8607_B0_MISC1_PI2C, data);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to access MISC1:%d\n", ret);
+		goto out;
+	}
+
+	ret = device_gpadc_init(chip, pdata);
+	if (ret < 0)
+		goto out;
+
+	ret = device_irq_init(chip, pdata);
+	if (ret < 0)
+		goto out;
+
+	ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
+			      ARRAY_SIZE(regulator_devs),
+			      &regulator_resources[0], 0);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to add regulator subdev\n");
+		goto out_dev;
+	}
+
+	if (pdata && pdata->touch) {
+		ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
+				      ARRAY_SIZE(touch_devs),
+				      &touch_resources[0], 0);
+		if (ret < 0) {
+			dev_err(chip->dev, "Failed to add touch "
+				"subdev\n");
+			goto out_dev;
+		}
+	}
+
+	if (pdata && pdata->power) {
+		ret = mfd_add_devices(chip->dev, 0, &power_devs[0],
+				      ARRAY_SIZE(power_devs),
+				      &power_supply_resources[0], 0);
+		if (ret < 0) {
+			dev_err(chip->dev, "Failed to add power supply "
+				"subdev\n");
+			goto out_dev;
+		}
+	}
+
+	ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
+			      ARRAY_SIZE(onkey_devs),
+			      &onkey_resources[0], 0);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to add onkey subdev\n");
+		goto out_dev;
+	}
+
+	return;
+out_dev:
+	mfd_remove_devices(chip->dev);
+	device_irq_exit(chip);
+out:
+	return;
+}
+
+int pm860x_device_init(struct pm860x_chip *chip,
+		       struct pm860x_platform_data *pdata)
+{
+	chip->core_irq = 0;
+
+	switch (chip->id) {
+	case CHIP_PM8606:
+		device_8606_init(chip, chip->client, pdata);
+		break;
+	case CHIP_PM8607:
+		device_8607_init(chip, chip->client, pdata);
+		break;
+	}
+
+	if (chip->companion) {
+		switch (chip->id) {
+		case CHIP_PM8607:
+			device_8606_init(chip, chip->companion, pdata);
+			break;
+		case CHIP_PM8606:
+			device_8607_init(chip, chip->companion, pdata);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+void pm860x_device_exit(struct pm860x_chip *chip)
+{
+	device_irq_exit(chip);
+	mfd_remove_devices(chip->dev);
+}
+
+MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM860x");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/88pm860x-i2c.c linux-libre-2.6.34-gnu1/drivers/mfd/88pm860x-i2c.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/88pm860x-i2c.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/88pm860x-i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,237 @@
+/*
+ * I2C driver for Marvell 88PM860x
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ * 	Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/mfd/88pm860x.h>
+#include <linux/slab.h>
+
+static inline int pm860x_read_device(struct i2c_client *i2c,
+				     int reg, int bytes, void *dest)
+{
+	unsigned char data;
+	int ret;
+
+	data = (unsigned char)reg;
+	ret = i2c_master_send(i2c, &data, 1);
+	if (ret < 0)
+		return ret;
+
+	ret = i2c_master_recv(i2c, dest, bytes);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static inline int pm860x_write_device(struct i2c_client *i2c,
+				      int reg, int bytes, void *src)
+{
+	unsigned char buf[bytes + 1];
+	int ret;
+
+	buf[0] = (unsigned char)reg;
+	memcpy(&buf[1], src, bytes);
+
+	ret = i2c_master_send(i2c, buf, bytes + 1);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+int pm860x_reg_read(struct i2c_client *i2c, int reg)
+{
+	struct pm860x_chip *chip = i2c_get_clientdata(i2c);
+	unsigned char data;
+	int ret;
+
+	mutex_lock(&chip->io_lock);
+	ret = pm860x_read_device(i2c, reg, 1, &data);
+	mutex_unlock(&chip->io_lock);
+
+	if (ret < 0)
+		return ret;
+	else
+		return (int)data;
+}
+EXPORT_SYMBOL(pm860x_reg_read);
+
+int pm860x_reg_write(struct i2c_client *i2c, int reg,
+		     unsigned char data)
+{
+	struct pm860x_chip *chip = i2c_get_clientdata(i2c);
+	int ret;
+
+	mutex_lock(&chip->io_lock);
+	ret = pm860x_write_device(i2c, reg, 1, &data);
+	mutex_unlock(&chip->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(pm860x_reg_write);
+
+int pm860x_bulk_read(struct i2c_client *i2c, int reg,
+		     int count, unsigned char *buf)
+{
+	struct pm860x_chip *chip = i2c_get_clientdata(i2c);
+	int ret;
+
+	mutex_lock(&chip->io_lock);
+	ret = pm860x_read_device(i2c, reg, count, buf);
+	mutex_unlock(&chip->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(pm860x_bulk_read);
+
+int pm860x_bulk_write(struct i2c_client *i2c, int reg,
+		      int count, unsigned char *buf)
+{
+	struct pm860x_chip *chip = i2c_get_clientdata(i2c);
+	int ret;
+
+	mutex_lock(&chip->io_lock);
+	ret = pm860x_write_device(i2c, reg, count, buf);
+	mutex_unlock(&chip->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(pm860x_bulk_write);
+
+int pm860x_set_bits(struct i2c_client *i2c, int reg,
+		    unsigned char mask, unsigned char data)
+{
+	struct pm860x_chip *chip = i2c_get_clientdata(i2c);
+	unsigned char value;
+	int ret;
+
+	mutex_lock(&chip->io_lock);
+	ret = pm860x_read_device(i2c, reg, 1, &value);
+	if (ret < 0)
+		goto out;
+	value &= ~mask;
+	value |= data;
+	ret = pm860x_write_device(i2c, reg, 1, &value);
+out:
+	mutex_unlock(&chip->io_lock);
+	return ret;
+}
+EXPORT_SYMBOL(pm860x_set_bits);
+
+
+static const struct i2c_device_id pm860x_id_table[] = {
+	{ "88PM860x", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
+
+static int verify_addr(struct i2c_client *i2c)
+{
+	unsigned short addr_8607[] = {0x30, 0x34};
+	unsigned short addr_8606[] = {0x10, 0x11};
+	int size, i;
+
+	if (i2c == NULL)
+		return 0;
+	size = ARRAY_SIZE(addr_8606);
+	for (i = 0; i < size; i++) {
+		if (i2c->addr == *(addr_8606 + i))
+			return CHIP_PM8606;
+	}
+	size = ARRAY_SIZE(addr_8607);
+	for (i = 0; i < size; i++) {
+		if (i2c->addr == *(addr_8607 + i))
+			return CHIP_PM8607;
+	}
+	return 0;
+}
+
+static int __devinit pm860x_probe(struct i2c_client *client,
+				  const struct i2c_device_id *id)
+{
+	struct pm860x_platform_data *pdata = client->dev.platform_data;
+	struct pm860x_chip *chip;
+
+	if (!pdata) {
+		pr_info("No platform data in %s!\n", __func__);
+		return -EINVAL;
+	}
+
+	chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
+	if (chip == NULL)
+		return -ENOMEM;
+
+	chip->id = verify_addr(client);
+	chip->client = client;
+	i2c_set_clientdata(client, chip);
+	chip->dev = &client->dev;
+	mutex_init(&chip->io_lock);
+	dev_set_drvdata(chip->dev, chip);
+
+	/*
+	 * Both client and companion client shares same platform driver.
+	 * Driver distinguishes them by pdata->companion_addr.
+	 * pdata->companion_addr is only assigned if companion chip exists.
+	 * At the same time, the companion_addr shouldn't equal to client
+	 * address.
+	 */
+	if (pdata->companion_addr && (pdata->companion_addr != client->addr)) {
+		chip->companion_addr = pdata->companion_addr;
+		chip->companion = i2c_new_dummy(chip->client->adapter,
+						chip->companion_addr);
+		i2c_set_clientdata(chip->companion, chip);
+	}
+
+	pm860x_device_init(chip, pdata);
+	return 0;
+}
+
+static int __devexit pm860x_remove(struct i2c_client *client)
+{
+	struct pm860x_chip *chip = i2c_get_clientdata(client);
+
+	pm860x_device_exit(chip);
+	i2c_unregister_device(chip->companion);
+	i2c_set_clientdata(chip->companion, NULL);
+	i2c_set_clientdata(chip->client, NULL);
+	kfree(chip);
+	return 0;
+}
+
+static struct i2c_driver pm860x_driver = {
+	.driver	= {
+		.name	= "88PM860x",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= pm860x_probe,
+	.remove		= __devexit_p(pm860x_remove),
+	.id_table	= pm860x_id_table,
+};
+
+static int __init pm860x_i2c_init(void)
+{
+	int ret;
+	ret = i2c_add_driver(&pm860x_driver);
+	if (ret != 0)
+		pr_err("Failed to register 88PM860x I2C driver: %d\n", ret);
+	return ret;
+}
+subsys_initcall(pm860x_i2c_init);
+
+static void __exit pm860x_i2c_exit(void)
+{
+	i2c_del_driver(&pm860x_driver);
+}
+module_exit(pm860x_i2c_exit);
+
+MODULE_DESCRIPTION("I2C Driver for Marvell 88PM860x");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/ab3100-core.c linux-libre-2.6.34-gnu1/drivers/mfd/ab3100-core.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/ab3100-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/ab3100-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2009 ST-Ericsson
+ * Copyright (C) 2007-2010 ST-Ericsson
  * License terms: GNU General Public License (GPL) version 2
  * Low-level core for exclusive access to the AB3100 IC on the I2C bus
  * and some basic chip-configuration.
@@ -10,10 +10,12 @@
 #include <linux/mutex.h>
 #include <linux/list.h>
 #include <linux/notifier.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
+#include <linux/random.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
@@ -365,18 +367,23 @@ int ab3100_event_registers_startup_state
 }
 EXPORT_SYMBOL(ab3100_event_registers_startup_state_get);
 
-/* Interrupt handling worker */
-static void ab3100_work(struct work_struct *work)
+/*
+ * This is a threaded interrupt handler so we can make some
+ * I2C calls etc.
+ */
+static irqreturn_t ab3100_irq_handler(int irq, void *data)
 {
-	struct ab3100 *ab3100 = container_of(work, struct ab3100, work);
+	struct ab3100 *ab3100 = data;
 	u8 event_regs[3];
 	u32 fatevent;
 	int err;
 
+	add_interrupt_randomness(irq);
+
 	err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1,
 				       event_regs, 3);
 	if (err)
-		goto err_event_wq;
+		goto err_event;
 
 	fatevent = (event_regs[0] << 16) |
 		(event_regs[1] << 8) |
@@ -398,29 +405,11 @@ static void ab3100_work(struct work_stru
 	dev_dbg(ab3100->dev,
 		"IRQ Event: 0x%08x\n", fatevent);
 
-	/* By now the IRQ should be acked and deasserted so enable it again */
-	enable_irq(ab3100->i2c_client->irq);
-	return;
+	return IRQ_HANDLED;
 
- err_event_wq:
+ err_event:
 	dev_dbg(ab3100->dev,
-		"error in event workqueue\n");
-	/* Enable the IRQ anyway, what choice do we have? */
-	enable_irq(ab3100->i2c_client->irq);
-	return;
-}
-
-static irqreturn_t ab3100_irq_handler(int irq, void *data)
-{
-	struct ab3100 *ab3100 = data;
-	/*
-	 * Disable the IRQ and dispatch a worker to handle the
-	 * event. Since the chip resides on I2C this is slow
-	 * stuff and we will re-enable the interrupts once th
-	 * worker has finished.
-	 */
-	disable_irq_nosync(irq);
-	schedule_work(&ab3100->work);
+		"error reading event status\n");
 	return IRQ_HANDLED;
 }
 
@@ -735,10 +724,7 @@ static struct platform_device ab3100_##d
 	.id		= -1,					\
 }
 
-/*
- * This lists all the subdevices and corresponding register
- * ranges.
- */
+/* This lists all the subdevices */
 AB3100_DEVICE(dac, "ab3100-dac");
 AB3100_DEVICE(leds, "ab3100-leds");
 AB3100_DEVICE(power, "ab3100-power");
@@ -904,12 +890,11 @@ static int __init ab3100_probe(struct i2
 	if (err)
 		goto exit_no_setup;
 
-	INIT_WORK(&ab3100->work, ab3100_work);
-
+	err = request_threaded_irq(client->irq, NULL, ab3100_irq_handler,
+				IRQF_ONESHOT, "ab3100-core", ab3100);
 	/* This real unpredictable IRQ is of course sampled for entropy */
-	err = request_irq(client->irq, ab3100_irq_handler,
-			  IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
-			  "AB3100 IRQ", ab3100);
+	rand_initialize_irq(client->irq);
+
 	if (err)
 		goto exit_no_irq;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/ab3100-otp.c linux-libre-2.6.34-gnu1/drivers/mfd/ab3100-otp.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/ab3100-otp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/ab3100-otp.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,10 +9,12 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/ab3100.h>
 #include <linux/debugfs.h>
+#include <linux/seq_file.h>
 
 /* The OTP registers */
 #define AB3100_OTP0		0xb0
@@ -95,11 +97,10 @@ static int __init ab3100_otp_read(struct
  * This is a simple debugfs human-readable file that dumps out
  * the contents of the OTP.
  */
-#ifdef CONFIG_DEBUGFS
-static int show_otp(struct seq_file *s, void *v)
+#ifdef CONFIG_DEBUG_FS
+static int ab3100_show_otp(struct seq_file *s, void *v)
 {
 	struct ab3100_otp *otp = s->private;
-	int err;
 
 	seq_printf(s, "OTP is %s\n", otp->locked ? "LOCKED" : "UNLOCKED");
 	seq_printf(s, "OTP clock switch startup is %uHz\n", otp->freq);
@@ -113,7 +114,7 @@ static int show_otp(struct seq_file *s,
 
 static int ab3100_otp_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, ab3100_otp_show, inode->i_private);
+	return single_open(file, ab3100_show_otp, inode->i_private);
 }
 
 static const struct file_operations ab3100_otp_operations = {
@@ -131,13 +132,14 @@ static int __init ab3100_otp_init_debugf
 					   &ab3100_otp_operations);
 	if (!otp->debugfs) {
 		dev_err(dev, "AB3100 debugfs OTP file registration failed!\n");
-		return err;
+		return -ENOENT;
 	}
+	return 0;
 }
 
 static void __exit ab3100_otp_exit_debugfs(struct ab3100_otp *otp)
 {
-	debugfs_remove_file(otp->debugfs);
+	debugfs_remove(otp->debugfs);
 }
 #else
 /* Compile this out if debugfs not selected */
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/ab4500-core.c linux-libre-2.6.34-gnu1/drivers/mfd/ab4500-core.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/ab4500-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/ab4500-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
  * Interrupt management to be added - TODO.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/adp5520.c linux-libre-2.6.34-gnu1/drivers/mfd/adp5520.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/adp5520.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/adp5520.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/err.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/asic3.c linux-libre-2.6.34-gnu1/drivers/mfd/asic3.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/asic3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/asic3.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/platform_device.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/da903x.c linux-libre-2.6.34-gnu1/drivers/mfd/da903x.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/da903x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/da903x.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/mfd/da903x.h>
+#include <linux/slab.h>
 
 #define DA9030_CHIP_ID		0x00
 #define DA9030_EVENT_A		0x01
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/ezx-pcap.c linux-libre-2.6.34-gnu1/drivers/mfd/ezx-pcap.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/ezx-pcap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/ezx-pcap.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/mfd/ezx-pcap.h>
 #include <linux/spi/spi.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #define PCAP_ADC_MAXQ		8
 struct pcap_adc_request {
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/htc-egpio.c linux-libre-2.6.34-gnu1/drivers/mfd/htc-egpio.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/htc-egpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/htc-egpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/spinlock.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/mfd/htc-egpio.h>
 
@@ -108,7 +109,7 @@ static void egpio_handler(unsigned int i
 	ack_irqs(ei);
 	/* Process all set pins. */
 	readval &= ei->irqs_enabled;
-	for_each_bit(irqpin, &readval, ei->nirqs) {
+	for_each_set_bit(irqpin, &readval, ei->nirqs) {
 		/* Run irq handler */
 		pr_debug("got IRQ %d\n", irqpin);
 		irq = ei->irq_start + irqpin;
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/htc-i2cpld.c linux-libre-2.6.34-gnu1/drivers/mfd/htc-i2cpld.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/htc-i2cpld.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/htc-i2cpld.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,711 @@
+/*
+ *  htc-i2cpld.c
+ *  Chip driver for an unknown CPLD chip found on omap850 HTC devices like
+ *  the HTC Wizard and HTC Herald.
+ *  The cpld is located on the i2c bus and acts as an input/output GPIO
+ *  extender.
+ *
+ *  Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com>
+ *
+ *  Based on work done in the linwizard project
+ *  Copyright (C) 2008-2009 Angelo Arrifano <miknix@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/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <linux/htcpld.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+
+struct htcpld_chip {
+	spinlock_t              lock;
+
+	/* chip info */
+	u8                      reset;
+	u8                      addr;
+	struct device           *dev;
+	struct i2c_client	*client;
+
+	/* Output details */
+	u8                      cache_out;
+	struct gpio_chip        chip_out;
+
+	/* Input details */
+	u8                      cache_in;
+	struct gpio_chip        chip_in;
+
+	u16                     irqs_enabled;
+	uint                    irq_start;
+	int                     nirqs;
+
+	/*
+	 * Work structure to allow for setting values outside of any
+	 * possible interrupt context
+	 */
+	struct work_struct set_val_work;
+};
+
+struct htcpld_data {
+	/* irq info */
+	u16                irqs_enabled;
+	uint               irq_start;
+	int                nirqs;
+	uint               chained_irq;
+	unsigned int       int_reset_gpio_hi;
+	unsigned int       int_reset_gpio_lo;
+
+	/* htcpld info */
+	struct htcpld_chip *chip;
+	unsigned int       nchips;
+};
+
+/* There does not appear to be a way to proactively mask interrupts
+ * on the htcpld chip itself.  So, we simply ignore interrupts that
+ * aren't desired. */
+static void htcpld_mask(unsigned int irq)
+{
+	struct htcpld_chip *chip = get_irq_chip_data(irq);
+	chip->irqs_enabled &= ~(1 << (irq - chip->irq_start));
+	pr_debug("HTCPLD mask %d %04x\n", irq, chip->irqs_enabled);
+}
+static void htcpld_unmask(unsigned int irq)
+{
+	struct htcpld_chip *chip = get_irq_chip_data(irq);
+	chip->irqs_enabled |= 1 << (irq - chip->irq_start);
+	pr_debug("HTCPLD unmask %d %04x\n", irq, chip->irqs_enabled);
+}
+
+static int htcpld_set_type(unsigned int irq, unsigned int flags)
+{
+	struct irq_desc *d = irq_to_desc(irq);
+
+	if (!d) {
+		pr_err("HTCPLD invalid IRQ: %d\n", irq);
+		return -EINVAL;
+	}
+
+	if (flags & ~IRQ_TYPE_SENSE_MASK)
+		return -EINVAL;
+
+	/* We only allow edge triggering */
+	if (flags & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))
+		return -EINVAL;
+
+	d->status &= ~IRQ_TYPE_SENSE_MASK;
+	d->status |= flags;
+
+	return 0;
+}
+
+static struct irq_chip htcpld_muxed_chip = {
+	.name     = "htcpld",
+	.mask     = htcpld_mask,
+	.unmask   = htcpld_unmask,
+	.set_type = htcpld_set_type,
+};
+
+/* To properly dispatch IRQ events, we need to read from the
+ * chip.  This is an I2C action that could possibly sleep
+ * (which is bad in interrupt context) -- so we use a threaded
+ * interrupt handler to get around that.
+ */
+static irqreturn_t htcpld_handler(int irq, void *dev)
+{
+	struct htcpld_data *htcpld = dev;
+	unsigned int i;
+	unsigned long flags;
+	int irqpin;
+	struct irq_desc *desc;
+
+	if (!htcpld) {
+		pr_debug("htcpld is null in ISR\n");
+		return IRQ_HANDLED;
+	}
+
+	/*
+	 * For each chip, do a read of the chip and trigger any interrupts
+	 * desired.  The interrupts will be triggered from LSB to MSB (i.e.
+	 * bit 0 first, then bit 1, etc.)
+	 *
+	 * For chips that have no interrupt range specified, just skip 'em.
+	 */
+	for (i = 0; i < htcpld->nchips; i++) {
+		struct htcpld_chip *chip = &htcpld->chip[i];
+		struct i2c_client *client;
+		int val;
+		unsigned long uval, old_val;
+
+		if (!chip) {
+			pr_debug("chip %d is null in ISR\n", i);
+			continue;
+		}
+
+		if (chip->nirqs == 0)
+			continue;
+
+		client = chip->client;
+		if (!client) {
+			pr_debug("client %d is null in ISR\n", i);
+			continue;
+		}
+
+		/* Scan the chip */
+		val = i2c_smbus_read_byte_data(client, chip->cache_out);
+		if (val < 0) {
+			/* Throw a warning and skip this chip */
+			dev_warn(chip->dev, "Unable to read from chip: %d\n",
+				 val);
+			continue;
+		}
+
+		uval = (unsigned long)val;
+
+		spin_lock_irqsave(&chip->lock, flags);
+
+		/* Save away the old value so we can compare it */
+		old_val = chip->cache_in;
+
+		/* Write the new value */
+		chip->cache_in = uval;
+
+		spin_unlock_irqrestore(&chip->lock, flags);
+
+		/*
+		 * For each bit in the data (starting at bit 0), trigger
+		 * associated interrupts.
+		 */
+		for (irqpin = 0; irqpin < chip->nirqs; irqpin++) {
+			unsigned oldb, newb;
+			int flags;
+
+			irq = chip->irq_start + irqpin;
+			desc = irq_to_desc(irq);
+			flags = desc->status;
+
+			/* Run the IRQ handler, but only if the bit value
+			 * changed, and the proper flags are set */
+			oldb = (old_val >> irqpin) & 1;
+			newb = (uval >> irqpin) & 1;
+
+			if ((!oldb && newb && (flags & IRQ_TYPE_EDGE_RISING)) ||
+			    (oldb && !newb &&
+			     (flags & IRQ_TYPE_EDGE_FALLING))) {
+				pr_debug("fire IRQ %d\n", irqpin);
+				desc->handle_irq(irq, desc);
+			}
+		}
+	}
+
+	/*
+	 * In order to continue receiving interrupts, the int_reset_gpio must
+	 * be asserted.
+	 */
+	if (htcpld->int_reset_gpio_hi)
+		gpio_set_value(htcpld->int_reset_gpio_hi, 1);
+	if (htcpld->int_reset_gpio_lo)
+		gpio_set_value(htcpld->int_reset_gpio_lo, 0);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * The GPIO set routines can be called from interrupt context, especially if,
+ * for example they're attached to the led-gpio framework and a trigger is
+ * enabled.  As such, we declared work above in the htcpld_chip structure,
+ * and that work is scheduled in the set routine.  The kernel can then run
+ * the I2C functions, which will sleep, in process context.
+ */
+void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+	struct i2c_client *client;
+	struct htcpld_chip *chip_data;
+	unsigned long flags;
+
+	chip_data = container_of(chip, struct htcpld_chip, chip_out);
+	if (!chip_data)
+		return;
+
+	client = chip_data->client;
+	if (client == NULL)
+		return;
+
+	spin_lock_irqsave(&chip_data->lock, flags);
+	if (val)
+		chip_data->cache_out |= (1 << offset);
+	else
+		chip_data->cache_out &= ~(1 << offset);
+	spin_unlock_irqrestore(&chip_data->lock, flags);
+
+	schedule_work(&(chip_data->set_val_work));
+}
+
+void htcpld_chip_set_ni(struct work_struct *work)
+{
+	struct htcpld_chip *chip_data;
+	struct i2c_client *client;
+
+	chip_data = container_of(work, struct htcpld_chip, set_val_work);
+	client = chip_data->client;
+	i2c_smbus_read_byte_data(client, chip_data->cache_out);
+}
+
+int htcpld_chip_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct htcpld_chip *chip_data;
+	int val = 0;
+	int is_input = 0;
+
+	/* Try out first */
+	chip_data = container_of(chip, struct htcpld_chip, chip_out);
+	if (!chip_data) {
+		/* Try in */
+		is_input = 1;
+		chip_data = container_of(chip, struct htcpld_chip, chip_in);
+		if (!chip_data)
+			return -EINVAL;
+	}
+
+	/* Determine if this is an input or output GPIO */
+	if (!is_input)
+		/* Use the output cache */
+		val = (chip_data->cache_out >> offset) & 1;
+	else
+		/* Use the input cache */
+		val = (chip_data->cache_in >> offset) & 1;
+
+	if (val)
+		return 1;
+	else
+		return 0;
+}
+
+static int htcpld_direction_output(struct gpio_chip *chip,
+					unsigned offset, int value)
+{
+	htcpld_chip_set(chip, offset, value);
+	return 0;
+}
+
+static int htcpld_direction_input(struct gpio_chip *chip,
+					unsigned offset)
+{
+	/*
+	 * No-op: this function can only be called on the input chip.
+	 * We do however make sure the offset is within range.
+	 */
+	return (offset < chip->ngpio) ? 0 : -EINVAL;
+}
+
+int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	struct htcpld_chip *chip_data;
+
+	chip_data = container_of(chip, struct htcpld_chip, chip_in);
+
+	if (offset < chip_data->nirqs)
+		return chip_data->irq_start + offset;
+	else
+		return -EINVAL;
+}
+
+void htcpld_chip_reset(struct i2c_client *client)
+{
+	struct htcpld_chip *chip_data = i2c_get_clientdata(client);
+	if (!chip_data)
+		return;
+
+	i2c_smbus_read_byte_data(
+		client, (chip_data->cache_out = chip_data->reset));
+}
+
+static int __devinit htcpld_setup_chip_irq(
+		struct platform_device *pdev,
+		int chip_index)
+{
+	struct htcpld_data *htcpld;
+	struct device *dev = &pdev->dev;
+	struct htcpld_core_platform_data *pdata;
+	struct htcpld_chip *chip;
+	struct htcpld_chip_platform_data *plat_chip_data;
+	unsigned int irq, irq_end;
+	int ret = 0;
+
+	/* Get the platform and driver data */
+	pdata = dev->platform_data;
+	htcpld = platform_get_drvdata(pdev);
+	chip = &htcpld->chip[chip_index];
+	plat_chip_data = &pdata->chip[chip_index];
+
+	/* Setup irq handlers */
+	irq_end = chip->irq_start + chip->nirqs;
+	for (irq = chip->irq_start; irq < irq_end; irq++) {
+		set_irq_chip(irq, &htcpld_muxed_chip);
+		set_irq_chip_data(irq, chip);
+		set_irq_handler(irq, handle_simple_irq);
+#ifdef CONFIG_ARM
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+#else
+		set_irq_probe(irq);
+#endif
+	}
+
+	return ret;
+}
+
+static int __devinit htcpld_register_chip_i2c(
+		struct platform_device *pdev,
+		int chip_index)
+{
+	struct htcpld_data *htcpld;
+	struct device *dev = &pdev->dev;
+	struct htcpld_core_platform_data *pdata;
+	struct htcpld_chip *chip;
+	struct htcpld_chip_platform_data *plat_chip_data;
+	struct i2c_adapter *adapter;
+	struct i2c_client *client;
+	struct i2c_board_info info;
+
+	/* Get the platform and driver data */
+	pdata = dev->platform_data;
+	htcpld = platform_get_drvdata(pdev);
+	chip = &htcpld->chip[chip_index];
+	plat_chip_data = &pdata->chip[chip_index];
+
+	adapter = i2c_get_adapter(pdata->i2c_adapter_id);
+	if (adapter == NULL) {
+		/* Eek, no such I2C adapter!  Bail out. */
+		dev_warn(dev, "Chip at i2c address 0x%x: Invalid i2c adapter %d\n",
+			 plat_chip_data->addr, pdata->i2c_adapter_id);
+		return -ENODEV;
+	}
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
+		dev_warn(dev, "i2c adapter %d non-functional\n",
+			 pdata->i2c_adapter_id);
+		return -EINVAL;
+	}
+
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	info.addr = plat_chip_data->addr;
+	strlcpy(info.type, "htcpld-chip", I2C_NAME_SIZE);
+	info.platform_data = chip;
+
+	/* Add the I2C device.  This calls the probe() function. */
+	client = i2c_new_device(adapter, &info);
+	if (!client) {
+		/* I2C device registration failed, contineu with the next */
+		dev_warn(dev, "Unable to add I2C device for 0x%x\n",
+			 plat_chip_data->addr);
+		return -ENODEV;
+	}
+
+	i2c_set_clientdata(client, chip);
+	snprintf(client->name, I2C_NAME_SIZE, "Chip_0x%d", client->addr);
+	chip->client = client;
+
+	/* Reset the chip */
+	htcpld_chip_reset(client);
+	chip->cache_in = i2c_smbus_read_byte_data(client, chip->cache_out);
+
+	return 0;
+}
+
+static void __devinit htcpld_unregister_chip_i2c(
+		struct platform_device *pdev,
+		int chip_index)
+{
+	struct htcpld_data *htcpld;
+	struct htcpld_chip *chip;
+
+	/* Get the platform and driver data */
+	htcpld = platform_get_drvdata(pdev);
+	chip = &htcpld->chip[chip_index];
+
+	if (chip->client)
+		i2c_unregister_device(chip->client);
+}
+
+static int __devinit htcpld_register_chip_gpio(
+		struct platform_device *pdev,
+		int chip_index)
+{
+	struct htcpld_data *htcpld;
+	struct device *dev = &pdev->dev;
+	struct htcpld_core_platform_data *pdata;
+	struct htcpld_chip *chip;
+	struct htcpld_chip_platform_data *plat_chip_data;
+	struct gpio_chip *gpio_chip;
+	int ret = 0;
+
+	/* Get the platform and driver data */
+	pdata = dev->platform_data;
+	htcpld = platform_get_drvdata(pdev);
+	chip = &htcpld->chip[chip_index];
+	plat_chip_data = &pdata->chip[chip_index];
+
+	/* Setup the GPIO chips */
+	gpio_chip = &(chip->chip_out);
+	gpio_chip->label           = "htcpld-out";
+	gpio_chip->dev             = dev;
+	gpio_chip->owner           = THIS_MODULE;
+	gpio_chip->get             = htcpld_chip_get;
+	gpio_chip->set             = htcpld_chip_set;
+	gpio_chip->direction_input = NULL;
+	gpio_chip->direction_output = htcpld_direction_output;
+	gpio_chip->base            = plat_chip_data->gpio_out_base;
+	gpio_chip->ngpio           = plat_chip_data->num_gpios;
+
+	gpio_chip = &(chip->chip_in);
+	gpio_chip->label           = "htcpld-in";
+	gpio_chip->dev             = dev;
+	gpio_chip->owner           = THIS_MODULE;
+	gpio_chip->get             = htcpld_chip_get;
+	gpio_chip->set             = NULL;
+	gpio_chip->direction_input = htcpld_direction_input;
+	gpio_chip->direction_output = NULL;
+	gpio_chip->to_irq          = htcpld_chip_to_irq;
+	gpio_chip->base            = plat_chip_data->gpio_in_base;
+	gpio_chip->ngpio           = plat_chip_data->num_gpios;
+
+	/* Add the GPIO chips */
+	ret = gpiochip_add(&(chip->chip_out));
+	if (ret) {
+		dev_warn(dev, "Unable to register output GPIOs for 0x%x: %d\n",
+			 plat_chip_data->addr, ret);
+		return ret;
+	}
+
+	ret = gpiochip_add(&(chip->chip_in));
+	if (ret) {
+		int error;
+
+		dev_warn(dev, "Unable to register input GPIOs for 0x%x: %d\n",
+			 plat_chip_data->addr, ret);
+
+		error = gpiochip_remove(&(chip->chip_out));
+		if (error)
+			dev_warn(dev, "Error while trying to unregister gpio chip: %d\n", error);
+
+		return ret;
+	}
+
+	return 0;
+}
+
+static int __devinit htcpld_setup_chips(struct platform_device *pdev)
+{
+	struct htcpld_data *htcpld;
+	struct device *dev = &pdev->dev;
+	struct htcpld_core_platform_data *pdata;
+	int i;
+
+	/* Get the platform and driver data */
+	pdata = dev->platform_data;
+	htcpld = platform_get_drvdata(pdev);
+
+	/* Setup each chip's output GPIOs */
+	htcpld->nchips = pdata->num_chip;
+	htcpld->chip = kzalloc(sizeof(struct htcpld_chip) * htcpld->nchips,
+			       GFP_KERNEL);
+	if (!htcpld->chip) {
+		dev_warn(dev, "Unable to allocate memory for chips\n");
+		return -ENOMEM;
+	}
+
+	/* Add the chips as best we can */
+	for (i = 0; i < htcpld->nchips; i++) {
+		int ret;
+
+		/* Setup the HTCPLD chips */
+		htcpld->chip[i].reset = pdata->chip[i].reset;
+		htcpld->chip[i].cache_out = pdata->chip[i].reset;
+		htcpld->chip[i].cache_in = 0;
+		htcpld->chip[i].dev = dev;
+		htcpld->chip[i].irq_start = pdata->chip[i].irq_base;
+		htcpld->chip[i].nirqs = pdata->chip[i].num_irqs;
+
+		INIT_WORK(&(htcpld->chip[i].set_val_work), &htcpld_chip_set_ni);
+		spin_lock_init(&(htcpld->chip[i].lock));
+
+		/* Setup the interrupts for the chip */
+		if (htcpld->chained_irq) {
+			ret = htcpld_setup_chip_irq(pdev, i);
+			if (ret)
+				continue;
+		}
+
+		/* Register the chip with I2C */
+		ret = htcpld_register_chip_i2c(pdev, i);
+		if (ret)
+			continue;
+
+
+		/* Register the chips with the GPIO subsystem */
+		ret = htcpld_register_chip_gpio(pdev, i);
+		if (ret) {
+			/* Unregister the chip from i2c and continue */
+			htcpld_unregister_chip_i2c(pdev, i);
+			continue;
+		}
+
+		dev_info(dev, "Registered chip at 0x%x\n", pdata->chip[i].addr);
+	}
+
+	return 0;
+}
+
+static int __devinit htcpld_core_probe(struct platform_device *pdev)
+{
+	struct htcpld_data *htcpld;
+	struct device *dev = &pdev->dev;
+	struct htcpld_core_platform_data *pdata;
+	struct resource *res;
+	int ret = 0;
+
+	if (!dev)
+		return -ENODEV;
+
+	pdata = dev->platform_data;
+	if (!pdata) {
+		dev_warn(dev, "Platform data not found for htcpld core!\n");
+		return -ENXIO;
+	}
+
+	htcpld = kzalloc(sizeof(struct htcpld_data), GFP_KERNEL);
+	if (!htcpld)
+		return -ENOMEM;
+
+	/* Find chained irq */
+	ret = -EINVAL;
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (res) {
+		int flags;
+		htcpld->chained_irq = res->start;
+
+		/* Setup the chained interrupt handler */
+		flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING;
+		ret = request_threaded_irq(htcpld->chained_irq,
+					   NULL, htcpld_handler,
+					   flags, pdev->name, htcpld);
+		if (ret) {
+			dev_warn(dev, "Unable to setup chained irq handler: %d\n", ret);
+			goto fail;
+		} else
+			device_init_wakeup(dev, 0);
+	}
+
+	/* Set the driver data */
+	platform_set_drvdata(pdev, htcpld);
+
+	/* Setup the htcpld chips */
+	ret = htcpld_setup_chips(pdev);
+	if (ret)
+		goto fail;
+
+	/* Request the GPIO(s) for the int reset and set them up */
+	if (pdata->int_reset_gpio_hi) {
+		ret = gpio_request(pdata->int_reset_gpio_hi, "htcpld-core");
+		if (ret) {
+			/*
+			 * If it failed, that sucks, but we can probably
+			 * continue on without it.
+			 */
+			dev_warn(dev, "Unable to request int_reset_gpio_hi -- interrupts may not work\n");
+			htcpld->int_reset_gpio_hi = 0;
+		} else {
+			htcpld->int_reset_gpio_hi = pdata->int_reset_gpio_hi;
+			gpio_set_value(htcpld->int_reset_gpio_hi, 1);
+		}
+	}
+
+	if (pdata->int_reset_gpio_lo) {
+		ret = gpio_request(pdata->int_reset_gpio_lo, "htcpld-core");
+		if (ret) {
+			/*
+			 * If it failed, that sucks, but we can probably
+			 * continue on without it.
+			 */
+			dev_warn(dev, "Unable to request int_reset_gpio_lo -- interrupts may not work\n");
+			htcpld->int_reset_gpio_lo = 0;
+		} else {
+			htcpld->int_reset_gpio_lo = pdata->int_reset_gpio_lo;
+			gpio_set_value(htcpld->int_reset_gpio_lo, 0);
+		}
+	}
+
+	dev_info(dev, "Initialized successfully\n");
+	return 0;
+
+fail:
+	kfree(htcpld);
+	return ret;
+}
+
+/* The I2C Driver -- used internally */
+static const struct i2c_device_id htcpld_chip_id[] = {
+	{ "htcpld-chip", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, htcpld_chip_id);
+
+
+static struct i2c_driver htcpld_chip_driver = {
+	.driver = {
+		.name	= "htcpld-chip",
+	},
+	.id_table = htcpld_chip_id,
+};
+
+/* The Core Driver */
+static struct platform_driver htcpld_core_driver = {
+	.driver = {
+		.name = "i2c-htcpld",
+	},
+};
+
+static int __init htcpld_core_init(void)
+{
+	int ret;
+
+	/* Register the I2C Chip driver */
+	ret = i2c_add_driver(&htcpld_chip_driver);
+	if (ret)
+		return ret;
+
+	/* Probe for our chips */
+	return platform_driver_probe(&htcpld_core_driver, htcpld_core_probe);
+}
+
+static void __exit htcpld_core_exit(void)
+{
+	i2c_del_driver(&htcpld_chip_driver);
+	platform_driver_unregister(&htcpld_core_driver);
+}
+
+module_init(htcpld_core_init);
+module_exit(htcpld_core_exit);
+
+MODULE_AUTHOR("Cory Maccarrone <darkstar6262@gmail.com>");
+MODULE_DESCRIPTION("I2C HTC PLD Driver");
+MODULE_LICENSE("GPL");
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/htc-pasic3.c linux-libre-2.6.34-gnu1/drivers/mfd/htc-pasic3.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/htc-pasic3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/htc-pasic3.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/ds1wm.h>
 #include <linux/mfd/htc-pasic3.h>
+#include <linux/slab.h>
 
 struct pasic3_data {
 	void __iomem *mapping;
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/Kconfig linux-libre-2.6.34-gnu1/drivers/mfd/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/mfd/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,16 @@ config MFD_CORE
 	tristate
 	default n
 
+config MFD_88PM860X
+	bool "Support Marvell 88PM8606/88PM8607"
+	depends on I2C=y && GENERIC_HARDIRQS
+	select MFD_CORE
+	help
+	  This supports for Marvell 88PM8606/88PM8607 Power Management IC.
+	  This includes the I2C driver and the core APIs _only_, you have to
+	  select individual components like voltage regulators, RTC and
+	  battery-charger under the corresponding menus.
+
 config MFD_SM501
 	tristate "Support for Silicon Motion SM501"
 	 ---help---
@@ -37,7 +47,7 @@ config MFD_ASIC3
 
 config MFD_SH_MOBILE_SDHI
 	bool "Support for SuperH Mobile SDHI"
-	depends on SUPERH
+	depends on SUPERH || ARCH_SHMOBILE
 	select MFD_CORE
 	 ---help---
 	  This driver supports the SDHI hardware block found in many
@@ -68,6 +78,15 @@ config HTC_PASIC3
 	  HTC Magician devices, respectively. Actual functionality is
 	  handled by the leds-pasic3 and ds1wm drivers.
 
+config HTC_I2CPLD
+	bool "HTC I2C PLD chip support"
+	depends on I2C=y && GPIOLIB
+	help
+	  If you say yes here you get support for the supposed CPLD
+	  found on omap850 HTC devices like the HTC Wizard and HTC Herald.
+	  This device provides input and output GPIOs through an I2C
+	  interface to one or more sub-chips.
+
 config UCB1400_CORE
 	tristate "Philips UCB1400 Core driver"
 	depends on AC97_BUS
@@ -94,7 +113,7 @@ config TPS65010
 
 config MENELAUS
 	bool "Texas Instruments TWL92330/Menelaus PM chip"
-	depends on I2C=y && ARCH_OMAP24XX
+	depends on I2C=y && ARCH_OMAP2
 	help
 	  If you say yes here you get support for the Texas Instruments
 	  TWL92330/Menelaus Power Management chip. This include voltage
@@ -184,6 +203,16 @@ config PMIC_ADP5520
 	  individual components like LCD backlight, LEDs, GPIOs and Kepad
 	  under the corresponding menus.
 
+config MFD_MAX8925
+	bool "Maxim Semiconductor MAX8925 PMIC Support"
+	depends on I2C=y && GENERIC_HARDIRQS
+	select MFD_CORE
+	help
+	  Say yes here to support for Maxim Semiconductor MAX8925. This is
+	  a Power Management IC. This driver provies common support for
+	  accessing the device, additional drivers must be enabled in order
+	  to use the functionality of the device.
+
 config MFD_WM8400
 	tristate "Support Wolfson Microelectronics WM8400"
 	select MFD_CORE
@@ -197,7 +226,7 @@ config MFD_WM8400
 config MFD_WM831X
 	bool "Support Wolfson Microelectronics WM831x/2x PMICs"
 	select MFD_CORE
-	depends on I2C=y
+	depends on I2C=y && GENERIC_HARDIRQS
 	help
 	  Support for the Wolfson Microelecronics WM831x and WM832x PMICs.
 	  This driver provides common support for accessing the device,
@@ -205,7 +234,8 @@ config MFD_WM831X
 	  functionality of the device.
 
 config MFD_WM8350
-	tristate
+	bool
+	depends on GENERIC_HARDIRQS
 
 config MFD_WM8350_CONFIG_MODE_0
 	bool
@@ -256,9 +286,9 @@ config MFD_WM8352_CONFIG_MODE_3
 	depends on MFD_WM8350
 
 config MFD_WM8350_I2C
-	tristate "Support Wolfson Microelectronics WM8350 with I2C"
+	bool "Support Wolfson Microelectronics WM8350 with I2C"
 	select MFD_WM8350
-	depends on I2C
+	depends on I2C=y && GENERIC_HARDIRQS
 	help
 	  The WM8350 is an integrated audio and power management
 	  subsystem with watchdog and RTC functionality for embedded
@@ -266,6 +296,18 @@ config MFD_WM8350_I2C
 	  I2C as the control interface.  Additional options must be
 	  selected to enable support for the functionality of the chip.
 
+config MFD_WM8994
+	tristate "Support Wolfson Microelectronics WM8994"
+	select MFD_CORE
+	depends on I2C
+	help
+	  The WM8994 is a highly integrated hi-fi CODEC designed for
+	  smartphone applicatiosn.  As well as audio functionality it
+	  has on board GPIO and regulator functionality which is
+	  supported via the relevant subsystems.  This driver provides
+	  core support for the WM8994, in order to use the actual
+	  functionaltiy of the device other drivers must be enabled.
+
 config MFD_PCF50633
 	tristate "Support for NXP PCF50633"
 	depends on I2C
@@ -300,8 +342,8 @@ config PCF50633_GPIO
 	 the PCF50633 chip.
 
 config AB3100_CORE
-	tristate "ST-Ericsson AB3100 Mixed Signal Circuit core functions"
-	depends on I2C
+	bool "ST-Ericsson AB3100 Mixed Signal Circuit core functions"
+	depends on I2C=y
 	default y if ARCH_U300
 	help
 	  Select this to enable the AB3100 Mixed Signal IC core
@@ -329,16 +371,6 @@ config EZX_PCAP
 	  This enables the PCAP ASIC present on EZX Phones. This is
 	  needed for MMC, TouchScreen, Sound, USB, etc..
 
-config MFD_88PM8607
-	bool "Support Marvell 88PM8607"
-	depends on I2C=y
-	select MFD_CORE
-	help
-	  This supports for Marvell 88PM8607 Power Management IC. This includes
-	  the I2C driver and the core APIs _only_, you have to select
-	  individual components like voltage regulators, RTC and
-	  battery-charger under the corresponding menus.
-
 config AB4500_CORE
 	tristate "ST-Ericsson's AB4500 Mixed Signal Power management chip"
 	depends on SPI
@@ -348,6 +380,25 @@ config AB4500_CORE
 	  read/write functions for the devices to get access to this chip.
 	  This chip embeds various other multimedia funtionalities as well.
 
+config MFD_TIMBERDALE
+	tristate "Support for the Timberdale FPGA"
+	select MFD_CORE
+	depends on PCI && GPIOLIB
+	---help---
+	This is the core driver for the timberdale FPGA. This device is a
+	multifunction device which exposes numerous platform devices.
+
+	The timberdale FPGA can be found on the Intel Atom development board
+	for in-vehicle infontainment, called Russellville.
+
+config LPC_SCH
+	tristate "Intel SCH LPC"
+	depends on PCI
+	select MFD_CORE
+	help
+	  LPC bridge function of the Intel SCH provides support for
+	  System Management Bus and General Purpose I/O.
+
 endmenu
 
 menu "Multimedia Capabilities Port drivers"
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/lpc_sch.c linux-libre-2.6.34-gnu1/drivers/mfd/lpc_sch.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/lpc_sch.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/lpc_sch.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,133 @@
+/*
+ *  lpc_sch.c - LPC interface for Intel Poulsbo SCH
+ *
+ *  LPC bridge function of the Intel SCH contains many other
+ *  functional units, such as Interrupt controllers, Timers,
+ *  Power Management, System Management, GPIO, RTC, and LPC
+ *  Configuration Registers.
+ *
+ *  Copyright (c) 2010 CompuLab Ltd
+ *  Author: Denis Turischev <denis@compulab.co.il>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License 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; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/acpi.h>
+#include <linux/pci.h>
+#include <linux/mfd/core.h>
+
+#define SMBASE		0x40
+#define SMBUS_IO_SIZE	64
+
+#define GPIOBASE	0x44
+#define GPIO_IO_SIZE	64
+
+static struct resource smbus_sch_resource = {
+		.flags = IORESOURCE_IO,
+};
+
+
+static struct resource gpio_sch_resource = {
+		.flags = IORESOURCE_IO,
+};
+
+static struct mfd_cell lpc_sch_cells[] = {
+	{
+		.name = "isch_smbus",
+		.num_resources = 1,
+		.resources = &smbus_sch_resource,
+	},
+	{
+		.name = "sch_gpio",
+		.num_resources = 1,
+		.resources = &gpio_sch_resource,
+	},
+};
+
+static struct pci_device_id lpc_sch_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) },
+	{ 0, }
+};
+MODULE_DEVICE_TABLE(pci, lpc_sch_ids);
+
+static int __devinit lpc_sch_probe(struct pci_dev *dev,
+				const struct pci_device_id *id)
+{
+	unsigned int base_addr_cfg;
+	unsigned short base_addr;
+
+	pci_read_config_dword(dev, SMBASE, &base_addr_cfg);
+	if (!(base_addr_cfg & (1 << 31))) {
+		dev_err(&dev->dev, "Decode of the SMBus I/O range disabled\n");
+		return -ENODEV;
+	}
+	base_addr = (unsigned short)base_addr_cfg;
+	if (base_addr == 0) {
+		dev_err(&dev->dev, "I/O space for SMBus uninitialized\n");
+		return -ENODEV;
+	}
+
+	smbus_sch_resource.start = base_addr;
+	smbus_sch_resource.end = base_addr + SMBUS_IO_SIZE - 1;
+
+	pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg);
+	if (!(base_addr_cfg & (1 << 31))) {
+		dev_err(&dev->dev, "Decode of the GPIO I/O range disabled\n");
+		return -ENODEV;
+	}
+	base_addr = (unsigned short)base_addr_cfg;
+	if (base_addr == 0) {
+		dev_err(&dev->dev, "I/O space for GPIO uninitialized\n");
+		return -ENODEV;
+	}
+
+	gpio_sch_resource.start = base_addr;
+	gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1;
+
+	return mfd_add_devices(&dev->dev, -1,
+			lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0);
+}
+
+static void __devexit lpc_sch_remove(struct pci_dev *dev)
+{
+	mfd_remove_devices(&dev->dev);
+}
+
+static struct pci_driver lpc_sch_driver = {
+	.name		= "lpc_sch",
+	.id_table	= lpc_sch_ids,
+	.probe		= lpc_sch_probe,
+	.remove		= __devexit_p(lpc_sch_remove),
+};
+
+static int __init lpc_sch_init(void)
+{
+	return pci_register_driver(&lpc_sch_driver);
+}
+
+static void __exit lpc_sch_exit(void)
+{
+	pci_unregister_driver(&lpc_sch_driver);
+}
+
+module_init(lpc_sch_init);
+module_exit(lpc_sch_exit);
+
+MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
+MODULE_DESCRIPTION("LPC interface for Intel Poulsbo SCH");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/Makefile linux-libre-2.6.34-gnu1/drivers/mfd/Makefile
--- linux-libre-2.6.33-gnu1/drivers/mfd/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -2,12 +2,15 @@
 # Makefile for multifunction miscellaneous devices
 #
 
+88pm860x-objs			:= 88pm860x-core.o 88pm860x-i2c.o
+obj-$(CONFIG_MFD_88PM860X)	+= 88pm860x.o
 obj-$(CONFIG_MFD_SM501)		+= sm501.o
 obj-$(CONFIG_MFD_ASIC3)		+= asic3.o tmio_core.o
 obj-$(CONFIG_MFD_SH_MOBILE_SDHI)		+= sh_mobile_sdhi.o
 
 obj-$(CONFIG_HTC_EGPIO)		+= htc-egpio.o
 obj-$(CONFIG_HTC_PASIC3)	+= htc-pasic3.o
+obj-$(CONFIG_HTC_I2CPLD)	+= htc-i2cpld.o
 
 obj-$(CONFIG_MFD_DM355EVM_MSP)	+= dm355evm_msp.o
 
@@ -22,6 +25,7 @@ wm8350-objs			:= wm8350-core.o wm8350-re
 wm8350-objs			+= wm8350-irq.o
 obj-$(CONFIG_MFD_WM8350)	+= wm8350.o
 obj-$(CONFIG_MFD_WM8350_I2C)	+= wm8350-i2c.o
+obj-$(CONFIG_MFD_WM8994)	+= wm8994-core.o
 
 obj-$(CONFIG_TPS65010)		+= tps65010.o
 obj-$(CONFIG_MENELAUS)		+= menelaus.o
@@ -47,6 +51,8 @@ endif
 obj-$(CONFIG_UCB1400_CORE)	+= ucb1400_core.o
 
 obj-$(CONFIG_PMIC_DA903X)	+= da903x.o
+max8925-objs			:= max8925-core.o max8925-i2c.o
+obj-$(CONFIG_MFD_MAX8925)	+= max8925.o
 
 obj-$(CONFIG_MFD_PCF50633)	+= pcf50633-core.o
 obj-$(CONFIG_PCF50633_ADC)	+= pcf50633-adc.o
@@ -54,5 +60,6 @@ obj-$(CONFIG_PCF50633_GPIO)	+= pcf50633-
 obj-$(CONFIG_AB3100_CORE)	+= ab3100-core.o
 obj-$(CONFIG_AB3100_OTP)	+= ab3100-otp.o
 obj-$(CONFIG_AB4500_CORE)	+= ab4500-core.o
-obj-$(CONFIG_MFD_88PM8607)	+= 88pm8607.o
-obj-$(CONFIG_PMIC_ADP5520)	+= adp5520.o
\ No newline at end of file
+obj-$(CONFIG_MFD_TIMBERDALE)    += timberdale.o
+obj-$(CONFIG_PMIC_ADP5520)	+= adp5520.o
+obj-$(CONFIG_LPC_SCH)		+= lpc_sch.o
\ No newline at end of file
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/max8925-core.c linux-libre-2.6.34-gnu1/drivers/mfd/max8925-core.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/max8925-core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/max8925-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,656 @@
+/*
+ * Base driver for Maxim MAX8925
+ *
+ * Copyright (C) 2009-2010 Marvell International Ltd.
+ *	Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/max8925.h>
+
+static struct resource backlight_resources[] = {
+	{
+		.name	= "max8925-backlight",
+		.start	= MAX8925_WLED_MODE_CNTL,
+		.end	= MAX8925_WLED_CNTL,
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+static struct mfd_cell backlight_devs[] = {
+	{
+		.name		= "max8925-backlight",
+		.num_resources	= 1,
+		.resources	= &backlight_resources[0],
+		.id		= -1,
+	},
+};
+
+static struct resource touch_resources[] = {
+	{
+		.name	= "max8925-tsc",
+		.start	= MAX8925_TSC_IRQ,
+		.end	= MAX8925_ADC_RES_END,
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+static struct mfd_cell touch_devs[] = {
+	{
+		.name		= "max8925-touch",
+		.num_resources	= 1,
+		.resources	= &touch_resources[0],
+		.id		= -1,
+	},
+};
+
+static struct resource power_supply_resources[] = {
+	{
+		.name	= "max8925-power",
+		.start	= MAX8925_CHG_IRQ1,
+		.end	= MAX8925_CHG_IRQ1_MASK,
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+static struct mfd_cell power_devs[] = {
+	{
+		.name		= "max8925-power",
+		.num_resources	= 1,
+		.resources	= &power_supply_resources[0],
+		.id		= -1,
+	},
+};
+
+static struct resource rtc_resources[] = {
+	{
+		.name	= "max8925-rtc",
+		.start	= MAX8925_RTC_IRQ,
+		.end	= MAX8925_RTC_IRQ_MASK,
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+static struct mfd_cell rtc_devs[] = {
+	{
+		.name		= "max8925-rtc",
+		.num_resources	= 1,
+		.resources	= &rtc_resources[0],
+		.id		= -1,
+	},
+};
+
+#define MAX8925_REG_RESOURCE(_start, _end)	\
+{						\
+	.start	= MAX8925_##_start,		\
+	.end	= MAX8925_##_end,		\
+	.flags	= IORESOURCE_IO,		\
+}
+
+static struct resource regulator_resources[] = {
+	MAX8925_REG_RESOURCE(SDCTL1, SDCTL1),
+	MAX8925_REG_RESOURCE(SDCTL2, SDCTL2),
+	MAX8925_REG_RESOURCE(SDCTL3, SDCTL3),
+	MAX8925_REG_RESOURCE(LDOCTL1, LDOCTL1),
+	MAX8925_REG_RESOURCE(LDOCTL2, LDOCTL2),
+	MAX8925_REG_RESOURCE(LDOCTL3, LDOCTL3),
+	MAX8925_REG_RESOURCE(LDOCTL4, LDOCTL4),
+	MAX8925_REG_RESOURCE(LDOCTL5, LDOCTL5),
+	MAX8925_REG_RESOURCE(LDOCTL6, LDOCTL6),
+	MAX8925_REG_RESOURCE(LDOCTL7, LDOCTL7),
+	MAX8925_REG_RESOURCE(LDOCTL8, LDOCTL8),
+	MAX8925_REG_RESOURCE(LDOCTL9, LDOCTL9),
+	MAX8925_REG_RESOURCE(LDOCTL10, LDOCTL10),
+	MAX8925_REG_RESOURCE(LDOCTL11, LDOCTL11),
+	MAX8925_REG_RESOURCE(LDOCTL12, LDOCTL12),
+	MAX8925_REG_RESOURCE(LDOCTL13, LDOCTL13),
+	MAX8925_REG_RESOURCE(LDOCTL14, LDOCTL14),
+	MAX8925_REG_RESOURCE(LDOCTL15, LDOCTL15),
+	MAX8925_REG_RESOURCE(LDOCTL16, LDOCTL16),
+	MAX8925_REG_RESOURCE(LDOCTL17, LDOCTL17),
+	MAX8925_REG_RESOURCE(LDOCTL18, LDOCTL18),
+	MAX8925_REG_RESOURCE(LDOCTL19, LDOCTL19),
+	MAX8925_REG_RESOURCE(LDOCTL20, LDOCTL20),
+};
+
+#define MAX8925_REG_DEVS(_id)						\
+{									\
+	.name		= "max8925-regulator",				\
+	.num_resources	= 1,						\
+	.resources	= &regulator_resources[MAX8925_ID_##_id],	\
+	.id		= MAX8925_ID_##_id,				\
+}
+
+static struct mfd_cell regulator_devs[] = {
+	MAX8925_REG_DEVS(SD1),
+	MAX8925_REG_DEVS(SD2),
+	MAX8925_REG_DEVS(SD3),
+	MAX8925_REG_DEVS(LDO1),
+	MAX8925_REG_DEVS(LDO2),
+	MAX8925_REG_DEVS(LDO3),
+	MAX8925_REG_DEVS(LDO4),
+	MAX8925_REG_DEVS(LDO5),
+	MAX8925_REG_DEVS(LDO6),
+	MAX8925_REG_DEVS(LDO7),
+	MAX8925_REG_DEVS(LDO8),
+	MAX8925_REG_DEVS(LDO9),
+	MAX8925_REG_DEVS(LDO10),
+	MAX8925_REG_DEVS(LDO11),
+	MAX8925_REG_DEVS(LDO12),
+	MAX8925_REG_DEVS(LDO13),
+	MAX8925_REG_DEVS(LDO14),
+	MAX8925_REG_DEVS(LDO15),
+	MAX8925_REG_DEVS(LDO16),
+	MAX8925_REG_DEVS(LDO17),
+	MAX8925_REG_DEVS(LDO18),
+	MAX8925_REG_DEVS(LDO19),
+	MAX8925_REG_DEVS(LDO20),
+};
+
+enum {
+	FLAGS_ADC = 1,	/* register in ADC component */
+	FLAGS_RTC,	/* register in RTC component */
+};
+
+struct max8925_irq_data {
+	int	reg;
+	int	mask_reg;
+	int	enable;		/* enable or not */
+	int	offs;		/* bit offset in mask register */
+	int	flags;
+	int	tsc_irq;
+};
+
+static struct max8925_irq_data max8925_irqs[] = {
+	[MAX8925_IRQ_VCHG_DC_OVP] = {
+		.reg		= MAX8925_CHG_IRQ1,
+		.mask_reg	= MAX8925_CHG_IRQ1_MASK,
+		.offs		= 1 << 0,
+	},
+	[MAX8925_IRQ_VCHG_DC_F] = {
+		.reg		= MAX8925_CHG_IRQ1,
+		.mask_reg	= MAX8925_CHG_IRQ1_MASK,
+		.offs		= 1 << 1,
+	},
+	[MAX8925_IRQ_VCHG_DC_R] = {
+		.reg		= MAX8925_CHG_IRQ1,
+		.mask_reg	= MAX8925_CHG_IRQ1_MASK,
+		.offs		= 1 << 2,
+	},
+	[MAX8925_IRQ_VCHG_USB_OVP] = {
+		.reg		= MAX8925_CHG_IRQ1,
+		.mask_reg	= MAX8925_CHG_IRQ1_MASK,
+		.offs		= 1 << 3,
+	},
+	[MAX8925_IRQ_VCHG_USB_F] =  {
+		.reg		= MAX8925_CHG_IRQ1,
+		.mask_reg	= MAX8925_CHG_IRQ1_MASK,
+		.offs		= 1 << 4,
+	},
+	[MAX8925_IRQ_VCHG_USB_R] = {
+		.reg		= MAX8925_CHG_IRQ1,
+		.mask_reg	= MAX8925_CHG_IRQ1_MASK,
+		.offs		= 1 << 5,
+	},
+	[MAX8925_IRQ_VCHG_THM_OK_R] = {
+		.reg		= MAX8925_CHG_IRQ2,
+		.mask_reg	= MAX8925_CHG_IRQ2_MASK,
+		.offs		= 1 << 0,
+	},
+	[MAX8925_IRQ_VCHG_THM_OK_F] = {
+		.reg		= MAX8925_CHG_IRQ2,
+		.mask_reg	= MAX8925_CHG_IRQ2_MASK,
+		.offs		= 1 << 1,
+	},
+	[MAX8925_IRQ_VCHG_SYSLOW_F] = {
+		.reg		= MAX8925_CHG_IRQ2,
+		.mask_reg	= MAX8925_CHG_IRQ2_MASK,
+		.offs		= 1 << 2,
+	},
+	[MAX8925_IRQ_VCHG_SYSLOW_R] = {
+		.reg		= MAX8925_CHG_IRQ2,
+		.mask_reg	= MAX8925_CHG_IRQ2_MASK,
+		.offs		= 1 << 3,
+	},
+	[MAX8925_IRQ_VCHG_RST] = {
+		.reg		= MAX8925_CHG_IRQ2,
+		.mask_reg	= MAX8925_CHG_IRQ2_MASK,
+		.offs		= 1 << 4,
+	},
+	[MAX8925_IRQ_VCHG_DONE] = {
+		.reg		= MAX8925_CHG_IRQ2,
+		.mask_reg	= MAX8925_CHG_IRQ2_MASK,
+		.offs		= 1 << 5,
+	},
+	[MAX8925_IRQ_VCHG_TOPOFF] = {
+		.reg		= MAX8925_CHG_IRQ2,
+		.mask_reg	= MAX8925_CHG_IRQ2_MASK,
+		.offs		= 1 << 6,
+	},
+	[MAX8925_IRQ_VCHG_TMR_FAULT] = {
+		.reg		= MAX8925_CHG_IRQ2,
+		.mask_reg	= MAX8925_CHG_IRQ2_MASK,
+		.offs		= 1 << 7,
+	},
+	[MAX8925_IRQ_GPM_RSTIN] = {
+		.reg		= MAX8925_ON_OFF_IRQ1,
+		.mask_reg	= MAX8925_ON_OFF_IRQ1_MASK,
+		.offs		= 1 << 0,
+	},
+	[MAX8925_IRQ_GPM_MPL] = {
+		.reg		= MAX8925_ON_OFF_IRQ1,
+		.mask_reg	= MAX8925_ON_OFF_IRQ1_MASK,
+		.offs		= 1 << 1,
+	},
+	[MAX8925_IRQ_GPM_SW_3SEC] = {
+		.reg		= MAX8925_ON_OFF_IRQ1,
+		.mask_reg	= MAX8925_ON_OFF_IRQ1_MASK,
+		.offs		= 1 << 2,
+	},
+	[MAX8925_IRQ_GPM_EXTON_F] = {
+		.reg		= MAX8925_ON_OFF_IRQ1,
+		.mask_reg	= MAX8925_ON_OFF_IRQ1_MASK,
+		.offs		= 1 << 3,
+	},
+	[MAX8925_IRQ_GPM_EXTON_R] = {
+		.reg		= MAX8925_ON_OFF_IRQ1,
+		.mask_reg	= MAX8925_ON_OFF_IRQ1_MASK,
+		.offs		= 1 << 4,
+	},
+	[MAX8925_IRQ_GPM_SW_1SEC] = {
+		.reg		= MAX8925_ON_OFF_IRQ1,
+		.mask_reg	= MAX8925_ON_OFF_IRQ1_MASK,
+		.offs		= 1 << 5,
+	},
+	[MAX8925_IRQ_GPM_SW_F] = {
+		.reg		= MAX8925_ON_OFF_IRQ1,
+		.mask_reg	= MAX8925_ON_OFF_IRQ1_MASK,
+		.offs		= 1 << 6,
+	},
+	[MAX8925_IRQ_GPM_SW_R] = {
+		.reg		= MAX8925_ON_OFF_IRQ1,
+		.mask_reg	= MAX8925_ON_OFF_IRQ1_MASK,
+		.offs		= 1 << 7,
+	},
+	[MAX8925_IRQ_GPM_SYSCKEN_F] = {
+		.reg		= MAX8925_ON_OFF_IRQ2,
+		.mask_reg	= MAX8925_ON_OFF_IRQ2_MASK,
+		.offs		= 1 << 0,
+	},
+	[MAX8925_IRQ_GPM_SYSCKEN_R] = {
+		.reg		= MAX8925_ON_OFF_IRQ2,
+		.mask_reg	= MAX8925_ON_OFF_IRQ2_MASK,
+		.offs		= 1 << 1,
+	},
+	[MAX8925_IRQ_RTC_ALARM1] = {
+		.reg		= MAX8925_RTC_IRQ,
+		.mask_reg	= MAX8925_RTC_IRQ_MASK,
+		.offs		= 1 << 2,
+		.flags		= FLAGS_RTC,
+	},
+	[MAX8925_IRQ_RTC_ALARM0] = {
+		.reg		= MAX8925_RTC_IRQ,
+		.mask_reg	= MAX8925_RTC_IRQ_MASK,
+		.offs		= 1 << 3,
+		.flags		= FLAGS_RTC,
+	},
+	[MAX8925_IRQ_TSC_STICK] = {
+		.reg		= MAX8925_TSC_IRQ,
+		.mask_reg	= MAX8925_TSC_IRQ_MASK,
+		.offs		= 1 << 0,
+		.flags		= FLAGS_ADC,
+		.tsc_irq	= 1,
+	},
+	[MAX8925_IRQ_TSC_NSTICK] = {
+		.reg		= MAX8925_TSC_IRQ,
+		.mask_reg	= MAX8925_TSC_IRQ_MASK,
+		.offs		= 1 << 1,
+		.flags		= FLAGS_ADC,
+		.tsc_irq	= 1,
+	},
+};
+
+static inline struct max8925_irq_data *irq_to_max8925(struct max8925_chip *chip,
+						      int irq)
+{
+	return &max8925_irqs[irq - chip->irq_base];
+}
+
+static irqreturn_t max8925_irq(int irq, void *data)
+{
+	struct max8925_chip *chip = data;
+	struct max8925_irq_data *irq_data;
+	struct i2c_client *i2c;
+	int read_reg = -1, value = 0;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
+		irq_data = &max8925_irqs[i];
+		/* TSC IRQ should be serviced in max8925_tsc_irq() */
+		if (irq_data->tsc_irq)
+			continue;
+		if (irq_data->flags == FLAGS_RTC)
+			i2c = chip->rtc;
+		else if (irq_data->flags == FLAGS_ADC)
+			i2c = chip->adc;
+		else
+			i2c = chip->i2c;
+		if (read_reg != irq_data->reg) {
+			read_reg = irq_data->reg;
+			value = max8925_reg_read(i2c, irq_data->reg);
+		}
+		if (value & irq_data->enable)
+			handle_nested_irq(chip->irq_base + i);
+	}
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t max8925_tsc_irq(int irq, void *data)
+{
+	struct max8925_chip *chip = data;
+	struct max8925_irq_data *irq_data;
+	struct i2c_client *i2c;
+	int read_reg = -1, value = 0;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
+		irq_data = &max8925_irqs[i];
+		/* non TSC IRQ should be serviced in max8925_irq() */
+		if (!irq_data->tsc_irq)
+			continue;
+		if (irq_data->flags == FLAGS_RTC)
+			i2c = chip->rtc;
+		else if (irq_data->flags == FLAGS_ADC)
+			i2c = chip->adc;
+		else
+			i2c = chip->i2c;
+		if (read_reg != irq_data->reg) {
+			read_reg = irq_data->reg;
+			value = max8925_reg_read(i2c, irq_data->reg);
+		}
+		if (value & irq_data->enable)
+			handle_nested_irq(chip->irq_base + i);
+	}
+	return IRQ_HANDLED;
+}
+
+static void max8925_irq_lock(unsigned int irq)
+{
+	struct max8925_chip *chip = get_irq_chip_data(irq);
+
+	mutex_lock(&chip->irq_lock);
+}
+
+static void max8925_irq_sync_unlock(unsigned int irq)
+{
+	struct max8925_chip *chip = get_irq_chip_data(irq);
+	struct max8925_irq_data *irq_data;
+	static unsigned char cache_chg[2] = {0xff, 0xff};
+	static unsigned char cache_on[2] = {0xff, 0xff};
+	static unsigned char cache_rtc = 0xff, cache_tsc = 0xff;
+	unsigned char irq_chg[2], irq_on[2];
+	unsigned char irq_rtc, irq_tsc;
+	int i;
+
+	/* Load cached value. In initial, all IRQs are masked */
+	irq_chg[0] = cache_chg[0];
+	irq_chg[1] = cache_chg[1];
+	irq_on[0] = cache_on[0];
+	irq_on[1] = cache_on[1];
+	irq_rtc = cache_rtc;
+	irq_tsc = cache_tsc;
+	for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
+		irq_data = &max8925_irqs[i];
+		switch (irq_data->mask_reg) {
+		case MAX8925_CHG_IRQ1_MASK:
+			irq_chg[0] &= irq_data->enable;
+			break;
+		case MAX8925_CHG_IRQ2_MASK:
+			irq_chg[1] &= irq_data->enable;
+			break;
+		case MAX8925_ON_OFF_IRQ1_MASK:
+			irq_on[0] &= irq_data->enable;
+			break;
+		case MAX8925_ON_OFF_IRQ2_MASK:
+			irq_on[1] &= irq_data->enable;
+			break;
+		case MAX8925_RTC_IRQ_MASK:
+			irq_rtc &= irq_data->enable;
+			break;
+		case MAX8925_TSC_IRQ_MASK:
+			irq_tsc &= irq_data->enable;
+			break;
+		default:
+			dev_err(chip->dev, "wrong IRQ\n");
+			break;
+		}
+	}
+	/* update mask into registers */
+	if (cache_chg[0] != irq_chg[0]) {
+		cache_chg[0] = irq_chg[0];
+		max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK,
+			irq_chg[0]);
+	}
+	if (cache_chg[1] != irq_chg[1]) {
+		cache_chg[1] = irq_chg[1];
+		max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK,
+			irq_chg[1]);
+	}
+	if (cache_on[0] != irq_on[0]) {
+		cache_on[0] = irq_on[0];
+		max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK,
+				irq_on[0]);
+	}
+	if (cache_on[1] != irq_on[1]) {
+		cache_on[1] = irq_on[1];
+		max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK,
+				irq_on[1]);
+	}
+	if (cache_rtc != irq_rtc) {
+		cache_rtc = irq_rtc;
+		max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, irq_rtc);
+	}
+	if (cache_tsc != irq_tsc) {
+		cache_tsc = irq_tsc;
+		max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, irq_tsc);
+	}
+
+	mutex_unlock(&chip->irq_lock);
+}
+
+static void max8925_irq_enable(unsigned int irq)
+{
+	struct max8925_chip *chip = get_irq_chip_data(irq);
+	max8925_irqs[irq - chip->irq_base].enable
+		= max8925_irqs[irq - chip->irq_base].offs;
+}
+
+static void max8925_irq_disable(unsigned int irq)
+{
+	struct max8925_chip *chip = get_irq_chip_data(irq);
+	max8925_irqs[irq - chip->irq_base].enable = 0;
+}
+
+static struct irq_chip max8925_irq_chip = {
+	.name		= "max8925",
+	.bus_lock	= max8925_irq_lock,
+	.bus_sync_unlock = max8925_irq_sync_unlock,
+	.enable		= max8925_irq_enable,
+	.disable	= max8925_irq_disable,
+};
+
+static int max8925_irq_init(struct max8925_chip *chip, int irq,
+			    struct max8925_platform_data *pdata)
+{
+	unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
+	struct irq_desc *desc;
+	int i, ret;
+	int __irq;
+
+	if (!pdata || !pdata->irq_base) {
+		dev_warn(chip->dev, "No interrupt support on IRQ base\n");
+		return -EINVAL;
+	}
+	/* clear all interrupts */
+	max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ1);
+	max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ2);
+	max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ1);
+	max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ2);
+	max8925_reg_read(chip->rtc, MAX8925_RTC_IRQ);
+	max8925_reg_read(chip->adc, MAX8925_TSC_IRQ);
+	/* mask all interrupts */
+	max8925_reg_write(chip->rtc, MAX8925_ALARM0_CNTL, 0);
+	max8925_reg_write(chip->rtc, MAX8925_ALARM1_CNTL, 0);
+	max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK, 0xff);
+	max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK, 0xff);
+	max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK, 0xff);
+	max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK, 0xff);
+	max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff);
+	max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0xff);
+
+	mutex_init(&chip->irq_lock);
+	chip->core_irq = irq;
+	chip->irq_base = pdata->irq_base;
+	desc = irq_to_desc(chip->core_irq);
+
+	/* register with genirq */
+	for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
+		__irq = i + chip->irq_base;
+		set_irq_chip_data(__irq, chip);
+		set_irq_chip_and_handler(__irq, &max8925_irq_chip,
+					 handle_edge_irq);
+		set_irq_nested_thread(__irq, 1);
+#ifdef CONFIG_ARM
+		set_irq_flags(__irq, IRQF_VALID);
+#else
+		set_irq_noprobe(__irq);
+#endif
+	}
+	if (!irq) {
+		dev_warn(chip->dev, "No interrupt support on core IRQ\n");
+		goto tsc_irq;
+	}
+
+	ret = request_threaded_irq(irq, NULL, max8925_irq, flags,
+				   "max8925", chip);
+	if (ret) {
+		dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret);
+		chip->core_irq = 0;
+	}
+tsc_irq:
+	if (!pdata->tsc_irq) {
+		dev_warn(chip->dev, "No interrupt support on TSC IRQ\n");
+		return 0;
+	}
+	chip->tsc_irq = pdata->tsc_irq;
+
+	ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq,
+				   flags, "max8925-tsc", chip);
+	if (ret) {
+		dev_err(chip->dev, "Failed to request TSC IRQ: %d\n", ret);
+		chip->tsc_irq = 0;
+	}
+	return 0;
+}
+
+int __devinit max8925_device_init(struct max8925_chip *chip,
+				  struct max8925_platform_data *pdata)
+{
+	int ret;
+
+	max8925_irq_init(chip, chip->i2c->irq, pdata);
+
+	if (pdata && (pdata->power || pdata->touch)) {
+		/* enable ADC to control internal reference */
+		max8925_set_bits(chip->i2c, MAX8925_RESET_CNFG, 1, 1);
+		/* enable internal reference for ADC */
+		max8925_set_bits(chip->adc, MAX8925_TSC_CNFG1, 3, 2);
+		/* check for internal reference IRQ */
+		do {
+			ret = max8925_reg_read(chip->adc, MAX8925_TSC_IRQ);
+		} while (ret & MAX8925_NREF_OK);
+		/* enaable ADC scheduler, interval is 1 second */
+		max8925_set_bits(chip->adc, MAX8925_ADC_SCHED, 3, 2);
+	}
+
+	/* enable Momentary Power Loss */
+	max8925_set_bits(chip->rtc, MAX8925_MPL_CNTL, 1 << 4, 1 << 4);
+
+	ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
+			      ARRAY_SIZE(rtc_devs),
+			      &rtc_resources[0], 0);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to add rtc subdev\n");
+		goto out;
+	}
+	if (pdata && pdata->regulator[0]) {
+		ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
+				      ARRAY_SIZE(regulator_devs),
+				      &regulator_resources[0], 0);
+		if (ret < 0) {
+			dev_err(chip->dev, "Failed to add regulator subdev\n");
+			goto out_dev;
+		}
+	}
+
+	if (pdata && pdata->backlight) {
+		ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],
+				      ARRAY_SIZE(backlight_devs),
+				      &backlight_resources[0], 0);
+		if (ret < 0) {
+			dev_err(chip->dev, "Failed to add backlight subdev\n");
+			goto out_dev;
+		}
+	}
+
+	if (pdata && pdata->power) {
+		ret = mfd_add_devices(chip->dev, 0, &power_devs[0],
+					ARRAY_SIZE(power_devs),
+					&power_supply_resources[0], 0);
+		if (ret < 0) {
+			dev_err(chip->dev, "Failed to add power supply "
+				"subdev\n");
+			goto out_dev;
+		}
+	}
+
+	if (pdata && pdata->touch) {
+		ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
+				      ARRAY_SIZE(touch_devs),
+				      &touch_resources[0], 0);
+		if (ret < 0) {
+			dev_err(chip->dev, "Failed to add touch subdev\n");
+			goto out_dev;
+		}
+	}
+
+	return 0;
+out_dev:
+	mfd_remove_devices(chip->dev);
+out:
+	return ret;
+}
+
+void __devexit max8925_device_exit(struct max8925_chip *chip)
+{
+	if (chip->core_irq)
+		free_irq(chip->core_irq, chip);
+	if (chip->tsc_irq)
+		free_irq(chip->tsc_irq, chip);
+	mfd_remove_devices(chip->dev);
+}
+
+
+MODULE_DESCRIPTION("PMIC Driver for Maxim MAX8925");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/max8925-i2c.c linux-libre-2.6.34-gnu1/drivers/mfd/max8925-i2c.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/max8925-i2c.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/max8925-i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,212 @@
+/*
+ * I2C driver for Maxim MAX8925
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ *	Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/mfd/max8925.h>
+#include <linux/slab.h>
+
+#define RTC_I2C_ADDR		0x68
+#define ADC_I2C_ADDR		0x47
+
+static inline int max8925_read_device(struct i2c_client *i2c,
+				      int reg, int bytes, void *dest)
+{
+	int ret;
+
+	if (bytes > 1)
+		ret = i2c_smbus_read_i2c_block_data(i2c, reg, bytes, dest);
+	else {
+		ret = i2c_smbus_read_byte_data(i2c, reg);
+		if (ret < 0)
+			return ret;
+		*(unsigned char *)dest = (unsigned char)ret;
+	}
+	return ret;
+}
+
+static inline int max8925_write_device(struct i2c_client *i2c,
+				       int reg, int bytes, void *src)
+{
+	unsigned char buf[bytes + 1];
+	int ret;
+
+	buf[0] = (unsigned char)reg;
+	memcpy(&buf[1], src, bytes);
+
+	ret = i2c_master_send(i2c, buf, bytes + 1);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+int max8925_reg_read(struct i2c_client *i2c, int reg)
+{
+	struct max8925_chip *chip = i2c_get_clientdata(i2c);
+	unsigned char data = 0;
+	int ret;
+
+	mutex_lock(&chip->io_lock);
+	ret = max8925_read_device(i2c, reg, 1, &data);
+	mutex_unlock(&chip->io_lock);
+
+	if (ret < 0)
+		return ret;
+	else
+		return (int)data;
+}
+EXPORT_SYMBOL(max8925_reg_read);
+
+int max8925_reg_write(struct i2c_client *i2c, int reg,
+		unsigned char data)
+{
+	struct max8925_chip *chip = i2c_get_clientdata(i2c);
+	int ret;
+
+	mutex_lock(&chip->io_lock);
+	ret = max8925_write_device(i2c, reg, 1, &data);
+	mutex_unlock(&chip->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(max8925_reg_write);
+
+int max8925_bulk_read(struct i2c_client *i2c, int reg,
+		int count, unsigned char *buf)
+{
+	struct max8925_chip *chip = i2c_get_clientdata(i2c);
+	int ret;
+
+	mutex_lock(&chip->io_lock);
+	ret = max8925_read_device(i2c, reg, count, buf);
+	mutex_unlock(&chip->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(max8925_bulk_read);
+
+int max8925_bulk_write(struct i2c_client *i2c, int reg,
+		int count, unsigned char *buf)
+{
+	struct max8925_chip *chip = i2c_get_clientdata(i2c);
+	int ret;
+
+	mutex_lock(&chip->io_lock);
+	ret = max8925_write_device(i2c, reg, count, buf);
+	mutex_unlock(&chip->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(max8925_bulk_write);
+
+int max8925_set_bits(struct i2c_client *i2c, int reg,
+		unsigned char mask, unsigned char data)
+{
+	struct max8925_chip *chip = i2c_get_clientdata(i2c);
+	unsigned char value;
+	int ret;
+
+	mutex_lock(&chip->io_lock);
+	ret = max8925_read_device(i2c, reg, 1, &value);
+	if (ret < 0)
+		goto out;
+	value &= ~mask;
+	value |= data;
+	ret = max8925_write_device(i2c, reg, 1, &value);
+out:
+	mutex_unlock(&chip->io_lock);
+	return ret;
+}
+EXPORT_SYMBOL(max8925_set_bits);
+
+
+static const struct i2c_device_id max8925_id_table[] = {
+	{ "max8925", 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, max8925_id_table);
+
+static int __devinit max8925_probe(struct i2c_client *client,
+				   const struct i2c_device_id *id)
+{
+	struct max8925_platform_data *pdata = client->dev.platform_data;
+	static struct max8925_chip *chip;
+
+	if (!pdata) {
+		pr_info("%s: platform data is missing\n", __func__);
+		return -EINVAL;
+	}
+
+	chip = kzalloc(sizeof(struct max8925_chip), GFP_KERNEL);
+	if (chip == NULL)
+		return -ENOMEM;
+	chip->i2c = client;
+	chip->dev = &client->dev;
+	i2c_set_clientdata(client, chip);
+	dev_set_drvdata(chip->dev, chip);
+	mutex_init(&chip->io_lock);
+
+	chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR);
+	i2c_set_clientdata(chip->rtc, chip);
+
+	chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR);
+	i2c_set_clientdata(chip->adc, chip);
+
+	max8925_device_init(chip, pdata);
+
+	return 0;
+}
+
+static int __devexit max8925_remove(struct i2c_client *client)
+{
+	struct max8925_chip *chip = i2c_get_clientdata(client);
+
+	max8925_device_exit(chip);
+	i2c_unregister_device(chip->adc);
+	i2c_unregister_device(chip->rtc);
+	i2c_set_clientdata(chip->adc, NULL);
+	i2c_set_clientdata(chip->rtc, NULL);
+	i2c_set_clientdata(chip->i2c, NULL);
+	kfree(chip);
+	return 0;
+}
+
+static struct i2c_driver max8925_driver = {
+	.driver	= {
+		.name	= "max8925",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= max8925_probe,
+	.remove		= __devexit_p(max8925_remove),
+	.id_table	= max8925_id_table,
+};
+
+static int __init max8925_i2c_init(void)
+{
+	int ret;
+
+	ret = i2c_add_driver(&max8925_driver);
+	if (ret != 0)
+		pr_err("Failed to register MAX8925 I2C driver: %d\n", ret);
+	return ret;
+}
+subsys_initcall(max8925_i2c_init);
+
+static void __exit max8925_i2c_exit(void)
+{
+	i2c_del_driver(&max8925_driver);
+}
+module_exit(max8925_i2c_exit);
+
+MODULE_DESCRIPTION("I2C Driver for Maxim 8925");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/mc13783-core.c linux-libre-2.6.34-gnu1/drivers/mfd/mc13783-core.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/mc13783-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/mc13783-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  * 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/spi/spi.h>
 #include <linux/mfd/core.h>
@@ -225,7 +226,7 @@ int mc13783_reg_rmw(struct mc13783 *mc13
 }
 EXPORT_SYMBOL(mc13783_reg_rmw);
 
-int mc13783_mask(struct mc13783 *mc13783, int irq)
+int mc13783_irq_mask(struct mc13783 *mc13783, int irq)
 {
 	int ret;
 	unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
@@ -245,9 +246,9 @@ int mc13783_mask(struct mc13783 *mc13783
 
 	return mc13783_reg_write(mc13783, offmask, mask | irqbit);
 }
-EXPORT_SYMBOL(mc13783_mask);
+EXPORT_SYMBOL(mc13783_irq_mask);
 
-int mc13783_unmask(struct mc13783 *mc13783, int irq)
+int mc13783_irq_unmask(struct mc13783 *mc13783, int irq)
 {
 	int ret;
 	unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
@@ -267,7 +268,53 @@ int mc13783_unmask(struct mc13783 *mc137
 
 	return mc13783_reg_write(mc13783, offmask, mask & ~irqbit);
 }
-EXPORT_SYMBOL(mc13783_unmask);
+EXPORT_SYMBOL(mc13783_irq_unmask);
+
+int mc13783_irq_status(struct mc13783 *mc13783, int irq,
+		int *enabled, int *pending)
+{
+	int ret;
+	unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
+	unsigned int offstat = irq < 24 ? MC13783_IRQSTAT0 : MC13783_IRQSTAT1;
+	u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
+
+	if (irq < 0 || irq >= MC13783_NUM_IRQ)
+		return -EINVAL;
+
+	if (enabled) {
+		u32 mask;
+
+		ret = mc13783_reg_read(mc13783, offmask, &mask);
+		if (ret)
+			return ret;
+
+		*enabled = mask & irqbit;
+	}
+
+	if (pending) {
+		u32 stat;
+
+		ret = mc13783_reg_read(mc13783, offstat, &stat);
+		if (ret)
+			return ret;
+
+		*pending = stat & irqbit;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(mc13783_irq_status);
+
+int mc13783_irq_ack(struct mc13783 *mc13783, int irq)
+{
+	unsigned int offstat = irq < 24 ? MC13783_IRQSTAT0 : MC13783_IRQSTAT1;
+	unsigned int val = 1 << (irq < 24 ? irq : irq - 24);
+
+	BUG_ON(irq < 0 || irq >= MC13783_NUM_IRQ);
+
+	return mc13783_reg_write(mc13783, offstat, val);
+}
+EXPORT_SYMBOL(mc13783_irq_ack);
 
 int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq,
 		irq_handler_t handler, const char *name, void *dev)
@@ -297,7 +344,7 @@ int mc13783_irq_request(struct mc13783 *
 	if (ret)
 		return ret;
 
-	ret = mc13783_unmask(mc13783, irq);
+	ret = mc13783_irq_unmask(mc13783, irq);
 	if (ret) {
 		mc13783->irqhandler[irq] = NULL;
 		mc13783->irqdata[irq] = NULL;
@@ -317,7 +364,7 @@ int mc13783_irq_free(struct mc13783 *mc1
 			mc13783->irqdata[irq] != dev)
 		return -EINVAL;
 
-	ret = mc13783_mask(mc13783, irq);
+	ret = mc13783_irq_mask(mc13783, irq);
 	if (ret)
 		return ret;
 
@@ -333,17 +380,6 @@ static inline irqreturn_t mc13783_irqhan
 	return mc13783->irqhandler[irq](irq, mc13783->irqdata[irq]);
 }
 
-int mc13783_ackirq(struct mc13783 *mc13783, int irq)
-{
-	unsigned int offstat = irq < 24 ? MC13783_IRQSTAT0 : MC13783_IRQSTAT1;
-	unsigned int val = 1 << (irq < 24 ? irq : irq - 24);
-
-	BUG_ON(irq < 0 || irq >= MC13783_NUM_IRQ);
-
-	return mc13783_reg_write(mc13783, offstat, val);
-}
-EXPORT_SYMBOL(mc13783_ackirq);
-
 /*
  * returns: number of handled irqs or negative error
  * locking: holds mc13783->lock
@@ -422,7 +458,7 @@ static irqreturn_t mc13783_handler_adcdo
 {
 	struct mc13783_adcdone_data *adcdone_data = data;
 
-	mc13783_ackirq(adcdone_data->mc13783, irq);
+	mc13783_irq_ack(adcdone_data->mc13783, irq);
 
 	complete_all(&adcdone_data->done);
 
@@ -486,7 +522,7 @@ int mc13783_adc_do_conversion(struct mc1
 	dev_dbg(&mc13783->spidev->dev, "%s: request irq\n", __func__);
 	mc13783_irq_request(mc13783, MC13783_IRQ_ADCDONE,
 			mc13783_handler_adcdone, __func__, &adcdone_data);
-	mc13783_ackirq(mc13783, MC13783_IRQ_ADCDONE);
+	mc13783_irq_ack(mc13783, MC13783_IRQ_ADCDONE);
 
 	mc13783_reg_write(mc13783, MC13783_REG_ADC_0, adc0);
 	mc13783_reg_write(mc13783, MC13783_REG_ADC_1, adc1);
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/mcp-sa11x0.c linux-libre-2.6.34-gnu1/drivers/mfd/mcp-sa11x0.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/mcp-sa11x0.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/mcp-sa11x0.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
-#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/mcp.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/menelaus.c linux-libre-2.6.34-gnu1/drivers/mfd/menelaus.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/menelaus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/menelaus.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/delay.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 
 #include <asm/mach/irq.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/mfd-core.c linux-libre-2.6.34-gnu1/drivers/mfd/mfd-core.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/mfd-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/mfd-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,9 @@
 
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/acpi.h>
 #include <linux/mfd/core.h>
+#include <linux/slab.h>
 
 static int mfd_add_device(struct device *parent, int id,
 			  const struct mfd_cell *cell,
@@ -62,6 +64,10 @@ static int mfd_add_device(struct device
 			res[r].start = cell->resources[r].start;
 			res[r].end   = cell->resources[r].end;
 		}
+
+		ret = acpi_check_resource_conflict(res);
+		if (ret)
+			goto fail_res;
 	}
 
 	platform_device_add_resources(pdev, res, cell->num_resources);
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/pcf50633-adc.c linux-libre-2.6.34-gnu1/drivers/mfd/pcf50633-adc.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/pcf50633-adc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/pcf50633-adc.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/pcf50633-core.c linux-libre-2.6.34-gnu1/drivers/mfd/pcf50633-core.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/pcf50633-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/pcf50633-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/pcf50633/core.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/sh_mobile_sdhi.c linux-libre-2.6.34-gnu1/drivers/mfd/sh_mobile_sdhi.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/sh_mobile_sdhi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/sh_mobile_sdhi.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,8 +20,9 @@
 
 #include <linux/kernel.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
-
+#include <linux/mmc/host.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/tmio.h>
 #include <linux/mfd/sh_mobile_sdhi.h>
@@ -95,9 +96,9 @@ static int __init sh_mobile_sdhi_probe(s
 
 	clk_enable(priv->clk);
 
-	/* FIXME: silly const unsigned int hclk */
-	*(unsigned int *)&priv->mmc_data.hclk = clk_get_rate(priv->clk);
+	priv->mmc_data.hclk = clk_get_rate(priv->clk);
 	priv->mmc_data.set_pwr = sh_mobile_sdhi_set_pwr;
+	priv->mmc_data.capabilities = MMC_CAP_MMC_HIGHSPEED;
 
 	memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc));
 	priv->cell_mmc.driver_data = &priv->mmc_data;
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/sm501.c linux-libre-2.6.34-gnu1/drivers/mfd/sm501.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/sm501.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/sm501.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/platform_device.h>
 #include <linux/pci.h>
 #include <linux/i2c-gpio.h>
+#include <linux/slab.h>
 
 #include <linux/sm501.h>
 #include <linux/sm501-regs.h>
@@ -523,7 +524,7 @@ unsigned long sm501_set_clock(struct dev
 	unsigned long clock = readl(sm->regs + SM501_CURRENT_CLOCK);
 	unsigned char reg;
 	unsigned int pll_reg = 0;
-	unsigned long sm501_freq; /* the actual frequency acheived */
+	unsigned long sm501_freq; /* the actual frequency achieved */
 
 	struct sm501_clock to;
 
@@ -533,7 +534,7 @@ unsigned long sm501_set_clock(struct dev
 
 	switch (clksrc) {
 	case SM501_CLOCK_P2XCLK:
-		/* This clock is divided in half so to achive the
+		/* This clock is divided in half so to achieve the
 		 * requested frequency the value must be multiplied by
 		 * 2. This clock also has an additional pre divisor */
 
@@ -562,7 +563,7 @@ unsigned long sm501_set_clock(struct dev
 		break;
 
 	case SM501_CLOCK_V2XCLK:
-		/* This clock is divided in half so to achive the
+		/* This clock is divided in half so to achieve the
 		 * requested frequency the value must be multiplied by 2. */
 
 		sm501_freq = (sm501_select_clock(2 * req_freq, &to, 3) / 2);
@@ -648,7 +649,7 @@ unsigned long sm501_find_clock(struct de
 			       unsigned long req_freq)
 {
 	struct sm501_devdata *sm = dev_get_drvdata(dev);
-	unsigned long sm501_freq; /* the frequency achiveable by the 501 */
+	unsigned long sm501_freq; /* the frequency achieveable by the 501 */
 	struct sm501_clock to;
 
 	switch (clksrc) {
@@ -1440,8 +1441,7 @@ static int __devinit sm501_plat_probe(st
 
 	platform_set_drvdata(dev, sm);
 
-	sm->regs = ioremap(sm->io_res->start,
-			   (sm->io_res->end - sm->io_res->start) - 1);
+	sm->regs = ioremap(sm->io_res->start, resource_size(sm->io_res));
 
 	if (sm->regs == NULL) {
 		dev_err(&dev->dev, "cannot remap registers\n");
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/t7l66xb.c linux-libre-2.6.34-gnu1/drivers/mfd/t7l66xb.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/t7l66xb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/t7l66xb.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/irq.h>
 #include <linux/clk.h>
 #include <linux/platform_device.h>
@@ -360,7 +361,7 @@ static int t7l66xb_probe(struct platform
 	if (ret)
 		goto err_request_scr;
 
-	t7l66xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1);
+	t7l66xb->scr = ioremap(rscr->start, resource_size(rscr));
 	if (!t7l66xb->scr) {
 		ret = -ENOMEM;
 		goto err_ioremap;
@@ -403,12 +404,12 @@ static int t7l66xb_probe(struct platform
 err_ioremap:
 	release_resource(&t7l66xb->rscr);
 err_request_scr:
-	kfree(t7l66xb);
 	clk_put(t7l66xb->clk48m);
 err_clk48m_get:
 	clk_put(t7l66xb->clk32k);
 err_clk32k_get:
 err_noirq:
+	kfree(t7l66xb);
 	return ret;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/tc6387xb.c linux-libre-2.6.34-gnu1/drivers/mfd/tc6387xb.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/tc6387xb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/tc6387xb.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/tmio.h>
 #include <linux/mfd/tc6387xb.h>
+#include <linux/slab.h>
 
 enum {
 	TC6387XB_CELL_MMC,
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/tc6393xb.c linux-libre-2.6.34-gnu1/drivers/mfd/tc6393xb.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/tc6393xb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/tc6393xb.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/mfd/tmio.h>
 #include <linux/mfd/tc6393xb.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #define SCR_REVID	0x08		/* b Revision ID	*/
 #define SCR_ISR		0x50		/* b Interrupt Status	*/
@@ -647,7 +648,7 @@ static int __devinit tc6393xb_probe(stru
 	if (ret)
 		goto err_request_scr;
 
-	tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1);
+	tc6393xb->scr = ioremap(rscr->start, resource_size(rscr));
 	if (!tc6393xb->scr) {
 		ret = -ENOMEM;
 		goto err_ioremap;
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/timberdale.c linux-libre-2.6.34-gnu1/drivers/mfd/timberdale.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/timberdale.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/timberdale.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,728 @@
+/*
+ * timberdale.c timberdale FPGA MFD driver
+ * Copyright (c) 2009 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * Timberdale FPGA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/msi.h>
+#include <linux/mfd/core.h>
+#include <linux/slab.h>
+
+#include <linux/timb_gpio.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-ocores.h>
+#include <linux/i2c/tsc2007.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/xilinx_spi.h>
+#include <linux/spi/max7301.h>
+#include <linux/spi/mc33880.h>
+
+#include <media/timb_radio.h>
+
+#include "timberdale.h"
+
+#define DRIVER_NAME "timberdale"
+
+struct timberdale_device {
+	resource_size_t		ctl_mapbase;
+	unsigned char __iomem   *ctl_membase;
+	struct {
+		u32 major;
+		u32 minor;
+		u32 config;
+	} fw;
+};
+
+/*--------------------------------------------------------------------------*/
+
+static struct tsc2007_platform_data timberdale_tsc2007_platform_data = {
+	.model = 2003,
+	.x_plate_ohms = 100
+};
+
+static struct i2c_board_info timberdale_i2c_board_info[] = {
+	{
+		I2C_BOARD_INFO("tsc2007", 0x48),
+		.platform_data = &timberdale_tsc2007_platform_data,
+		.irq = IRQ_TIMBERDALE_TSC_INT
+	},
+};
+
+static __devinitdata struct ocores_i2c_platform_data
+timberdale_ocores_platform_data = {
+	.regstep = 4,
+	.clock_khz = 62500,
+	.devices = timberdale_i2c_board_info,
+	.num_devices = ARRAY_SIZE(timberdale_i2c_board_info)
+};
+
+const static __devinitconst struct resource timberdale_ocores_resources[] = {
+	{
+		.start	= OCORESOFFSET,
+		.end	= OCORESEND,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start 	= IRQ_TIMBERDALE_I2C,
+		.end	= IRQ_TIMBERDALE_I2C,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+const struct max7301_platform_data timberdale_max7301_platform_data = {
+	.base = 200
+};
+
+const struct mc33880_platform_data timberdale_mc33880_platform_data = {
+	.base = 100
+};
+
+static struct spi_board_info timberdale_spi_16bit_board_info[] = {
+	{
+		.modalias = "max7301",
+		.max_speed_hz = 26000,
+		.chip_select = 2,
+		.mode = SPI_MODE_0,
+		.platform_data = &timberdale_max7301_platform_data
+	},
+};
+
+static struct spi_board_info timberdale_spi_8bit_board_info[] = {
+	{
+		.modalias = "mc33880",
+		.max_speed_hz = 4000,
+		.chip_select = 1,
+		.mode = SPI_MODE_1,
+		.platform_data = &timberdale_mc33880_platform_data
+	},
+};
+
+static __devinitdata struct xspi_platform_data timberdale_xspi_platform_data = {
+	.num_chipselect = 3,
+	.little_endian = true,
+	/* bits per word and devices will be filled in runtime depending
+	 * on the HW config
+	 */
+};
+
+const static __devinitconst struct resource timberdale_spi_resources[] = {
+	{
+		.start 	= SPIOFFSET,
+		.end	= SPIEND,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_TIMBERDALE_SPI,
+		.end	= IRQ_TIMBERDALE_SPI,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+const static __devinitconst struct resource timberdale_eth_resources[] = {
+	{
+		.start	= ETHOFFSET,
+		.end	= ETHEND,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_TIMBERDALE_ETHSW_IF,
+		.end	= IRQ_TIMBERDALE_ETHSW_IF,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static __devinitdata struct timbgpio_platform_data
+	timberdale_gpio_platform_data = {
+	.gpio_base = 0,
+	.nr_pins = GPIO_NR_PINS,
+	.irq_base = 200,
+};
+
+const static __devinitconst struct resource timberdale_gpio_resources[] = {
+	{
+		.start	= GPIOOFFSET,
+		.end	= GPIOEND,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_TIMBERDALE_GPIO,
+		.end	= IRQ_TIMBERDALE_GPIO,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+const static __devinitconst struct resource timberdale_mlogicore_resources[] = {
+	{
+		.start	= MLCOREOFFSET,
+		.end	= MLCOREEND,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_TIMBERDALE_MLCORE,
+		.end	= IRQ_TIMBERDALE_MLCORE,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= IRQ_TIMBERDALE_MLCORE_BUF,
+		.end	= IRQ_TIMBERDALE_MLCORE_BUF,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+const static __devinitconst struct resource timberdale_uart_resources[] = {
+	{
+		.start	= UARTOFFSET,
+		.end	= UARTEND,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_TIMBERDALE_UART,
+		.end	= IRQ_TIMBERDALE_UART,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+const static __devinitconst struct resource timberdale_uartlite_resources[] = {
+	{
+		.start	= UARTLITEOFFSET,
+		.end	= UARTLITEEND,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_TIMBERDALE_UARTLITE,
+		.end	= IRQ_TIMBERDALE_UARTLITE,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+const static __devinitconst struct resource timberdale_radio_resources[] = {
+	{
+		.start	= RDSOFFSET,
+		.end	= RDSEND,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_TIMBERDALE_RDS,
+		.end	= IRQ_TIMBERDALE_RDS,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static __devinitdata struct i2c_board_info timberdale_tef6868_i2c_board_info = {
+	I2C_BOARD_INFO("tef6862", 0x60)
+};
+
+static __devinitdata struct i2c_board_info timberdale_saa7706_i2c_board_info = {
+	I2C_BOARD_INFO("saa7706h", 0x1C)
+};
+
+static __devinitdata struct timb_radio_platform_data
+	timberdale_radio_platform_data = {
+	.i2c_adapter = 0,
+	.tuner = {
+		.module_name = "tef6862",
+		.info = &timberdale_tef6868_i2c_board_info
+	},
+	.dsp = {
+		.module_name = "saa7706h",
+		.info = &timberdale_saa7706_i2c_board_info
+	}
+};
+
+const static __devinitconst struct resource timberdale_dma_resources[] = {
+	{
+		.start	= DMAOFFSET,
+		.end	= DMAEND,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_TIMBERDALE_DMA,
+		.end	= IRQ_TIMBERDALE_DMA,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = {
+	{
+		.name = "timb-uart",
+		.num_resources = ARRAY_SIZE(timberdale_uart_resources),
+		.resources = timberdale_uart_resources,
+	},
+	{
+		.name = "timb-gpio",
+		.num_resources = ARRAY_SIZE(timberdale_gpio_resources),
+		.resources = timberdale_gpio_resources,
+		.platform_data = &timberdale_gpio_platform_data,
+		.data_size = sizeof(timberdale_gpio_platform_data),
+	},
+	{
+		.name = "timb-radio",
+		.num_resources = ARRAY_SIZE(timberdale_radio_resources),
+		.resources = timberdale_radio_resources,
+		.platform_data = &timberdale_radio_platform_data,
+		.data_size = sizeof(timberdale_radio_platform_data),
+	},
+	{
+		.name = "xilinx_spi",
+		.num_resources = ARRAY_SIZE(timberdale_spi_resources),
+		.resources = timberdale_spi_resources,
+		.platform_data = &timberdale_xspi_platform_data,
+		.data_size = sizeof(timberdale_xspi_platform_data),
+	},
+	{
+		.name = "ks8842",
+		.num_resources = ARRAY_SIZE(timberdale_eth_resources),
+		.resources = timberdale_eth_resources,
+	},
+	{
+		.name = "timb-dma",
+		.num_resources = ARRAY_SIZE(timberdale_dma_resources),
+		.resources = timberdale_dma_resources,
+	},
+};
+
+static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
+	{
+		.name = "timb-uart",
+		.num_resources = ARRAY_SIZE(timberdale_uart_resources),
+		.resources = timberdale_uart_resources,
+	},
+	{
+		.name = "uartlite",
+		.num_resources = ARRAY_SIZE(timberdale_uartlite_resources),
+		.resources = timberdale_uartlite_resources,
+	},
+	{
+		.name = "timb-gpio",
+		.num_resources = ARRAY_SIZE(timberdale_gpio_resources),
+		.resources = timberdale_gpio_resources,
+		.platform_data = &timberdale_gpio_platform_data,
+		.data_size = sizeof(timberdale_gpio_platform_data),
+	},
+	{
+		.name = "timb-mlogicore",
+		.num_resources = ARRAY_SIZE(timberdale_mlogicore_resources),
+		.resources = timberdale_mlogicore_resources,
+	},
+	{
+		.name = "timb-radio",
+		.num_resources = ARRAY_SIZE(timberdale_radio_resources),
+		.resources = timberdale_radio_resources,
+		.platform_data = &timberdale_radio_platform_data,
+		.data_size = sizeof(timberdale_radio_platform_data),
+	},
+	{
+		.name = "xilinx_spi",
+		.num_resources = ARRAY_SIZE(timberdale_spi_resources),
+		.resources = timberdale_spi_resources,
+		.platform_data = &timberdale_xspi_platform_data,
+		.data_size = sizeof(timberdale_xspi_platform_data),
+	},
+	{
+		.name = "ks8842",
+		.num_resources = ARRAY_SIZE(timberdale_eth_resources),
+		.resources = timberdale_eth_resources,
+	},
+	{
+		.name = "timb-dma",
+		.num_resources = ARRAY_SIZE(timberdale_dma_resources),
+		.resources = timberdale_dma_resources,
+	},
+};
+
+static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = {
+	{
+		.name = "timb-uart",
+		.num_resources = ARRAY_SIZE(timberdale_uart_resources),
+		.resources = timberdale_uart_resources,
+	},
+	{
+		.name = "timb-gpio",
+		.num_resources = ARRAY_SIZE(timberdale_gpio_resources),
+		.resources = timberdale_gpio_resources,
+		.platform_data = &timberdale_gpio_platform_data,
+		.data_size = sizeof(timberdale_gpio_platform_data),
+	},
+	{
+		.name = "timb-radio",
+		.num_resources = ARRAY_SIZE(timberdale_radio_resources),
+		.resources = timberdale_radio_resources,
+		.platform_data = &timberdale_radio_platform_data,
+		.data_size = sizeof(timberdale_radio_platform_data),
+	},
+	{
+		.name = "xilinx_spi",
+		.num_resources = ARRAY_SIZE(timberdale_spi_resources),
+		.resources = timberdale_spi_resources,
+		.platform_data = &timberdale_xspi_platform_data,
+		.data_size = sizeof(timberdale_xspi_platform_data),
+	},
+	{
+		.name = "timb-dma",
+		.num_resources = ARRAY_SIZE(timberdale_dma_resources),
+		.resources = timberdale_dma_resources,
+	},
+};
+
+static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = {
+	{
+		.name = "timb-uart",
+		.num_resources = ARRAY_SIZE(timberdale_uart_resources),
+		.resources = timberdale_uart_resources,
+	},
+	{
+		.name = "ocores-i2c",
+		.num_resources = ARRAY_SIZE(timberdale_ocores_resources),
+		.resources = timberdale_ocores_resources,
+		.platform_data = &timberdale_ocores_platform_data,
+		.data_size = sizeof(timberdale_ocores_platform_data),
+	},
+	{
+		.name = "timb-gpio",
+		.num_resources = ARRAY_SIZE(timberdale_gpio_resources),
+		.resources = timberdale_gpio_resources,
+		.platform_data = &timberdale_gpio_platform_data,
+		.data_size = sizeof(timberdale_gpio_platform_data),
+	},
+	{
+		.name = "timb-radio",
+		.num_resources = ARRAY_SIZE(timberdale_radio_resources),
+		.resources = timberdale_radio_resources,
+		.platform_data = &timberdale_radio_platform_data,
+		.data_size = sizeof(timberdale_radio_platform_data),
+	},
+	{
+		.name = "xilinx_spi",
+		.num_resources = ARRAY_SIZE(timberdale_spi_resources),
+		.resources = timberdale_spi_resources,
+		.platform_data = &timberdale_xspi_platform_data,
+		.data_size = sizeof(timberdale_xspi_platform_data),
+	},
+	{
+		.name = "ks8842",
+		.num_resources = ARRAY_SIZE(timberdale_eth_resources),
+		.resources = timberdale_eth_resources,
+	},
+	{
+		.name = "timb-dma",
+		.num_resources = ARRAY_SIZE(timberdale_dma_resources),
+		.resources = timberdale_dma_resources,
+	},
+};
+
+static const __devinitconst struct resource timberdale_sdhc_resources[] = {
+	/* located in bar 1 and bar 2 */
+	{
+		.start	= SDHC0OFFSET,
+		.end	= SDHC0END,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_TIMBERDALE_SDHC,
+		.end	= IRQ_TIMBERDALE_SDHC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static __devinitdata struct mfd_cell timberdale_cells_bar1[] = {
+	{
+		.name = "sdhci",
+		.num_resources = ARRAY_SIZE(timberdale_sdhc_resources),
+		.resources = timberdale_sdhc_resources,
+	},
+};
+
+static __devinitdata struct mfd_cell timberdale_cells_bar2[] = {
+	{
+		.name = "sdhci",
+		.num_resources = ARRAY_SIZE(timberdale_sdhc_resources),
+		.resources = timberdale_sdhc_resources,
+	},
+};
+
+static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr,
+	char *buf)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct timberdale_device *priv = pci_get_drvdata(pdev);
+
+	return sprintf(buf, "%d.%d.%d\n", priv->fw.major, priv->fw.minor,
+		priv->fw.config);
+}
+
+static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
+
+/*--------------------------------------------------------------------------*/
+
+static int __devinit timb_probe(struct pci_dev *dev,
+	const struct pci_device_id *id)
+{
+	struct timberdale_device *priv;
+	int err, i;
+	resource_size_t mapbase;
+	struct msix_entry *msix_entries = NULL;
+	u8 ip_setup;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	pci_set_drvdata(dev, priv);
+
+	err = pci_enable_device(dev);
+	if (err)
+		goto err_enable;
+
+	mapbase = pci_resource_start(dev, 0);
+	if (!mapbase) {
+		dev_err(&dev->dev, "No resource\n");
+		goto err_start;
+	}
+
+	/* create a resource for the PCI master register */
+	priv->ctl_mapbase = mapbase + CHIPCTLOFFSET;
+	if (!request_mem_region(priv->ctl_mapbase, CHIPCTLSIZE, "timb-ctl")) {
+		dev_err(&dev->dev, "Failed to request ctl mem\n");
+		goto err_request;
+	}
+
+	priv->ctl_membase = ioremap(priv->ctl_mapbase, CHIPCTLSIZE);
+	if (!priv->ctl_membase) {
+		dev_err(&dev->dev, "ioremap failed for ctl mem\n");
+		goto err_ioremap;
+	}
+
+	/* read the HW config */
+	priv->fw.major = ioread32(priv->ctl_membase + TIMB_REV_MAJOR);
+	priv->fw.minor = ioread32(priv->ctl_membase + TIMB_REV_MINOR);
+	priv->fw.config = ioread32(priv->ctl_membase + TIMB_HW_CONFIG);
+
+	if (priv->fw.major > TIMB_SUPPORTED_MAJOR) {
+		dev_err(&dev->dev, "The driver supports an older "
+			"version of the FPGA, please update the driver to "
+			"support %d.%d\n", priv->fw.major, priv->fw.minor);
+		goto err_ioremap;
+	}
+	if (priv->fw.major < TIMB_SUPPORTED_MAJOR ||
+		priv->fw.minor < TIMB_REQUIRED_MINOR) {
+		dev_err(&dev->dev, "The FPGA image is too old (%d.%d), "
+			"please upgrade the FPGA to at least: %d.%d\n",
+			priv->fw.major, priv->fw.minor,
+			TIMB_SUPPORTED_MAJOR, TIMB_REQUIRED_MINOR);
+		goto err_ioremap;
+	}
+
+	msix_entries = kzalloc(TIMBERDALE_NR_IRQS * sizeof(*msix_entries),
+		GFP_KERNEL);
+	if (!msix_entries)
+		goto err_ioremap;
+
+	for (i = 0; i < TIMBERDALE_NR_IRQS; i++)
+		msix_entries[i].entry = i;
+
+	err = pci_enable_msix(dev, msix_entries, TIMBERDALE_NR_IRQS);
+	if (err) {
+		dev_err(&dev->dev,
+			"MSI-X init failed: %d, expected entries: %d\n",
+			err, TIMBERDALE_NR_IRQS);
+		goto err_msix;
+	}
+
+	err = device_create_file(&dev->dev, &dev_attr_fw_ver);
+	if (err)
+		goto err_create_file;
+
+	/* Reset all FPGA PLB peripherals */
+	iowrite32(0x1, priv->ctl_membase + TIMB_SW_RST);
+
+	/* update IRQ offsets in I2C board info */
+	for (i = 0; i < ARRAY_SIZE(timberdale_i2c_board_info); i++)
+		timberdale_i2c_board_info[i].irq =
+			msix_entries[timberdale_i2c_board_info[i].irq].vector;
+
+	/* Update the SPI configuration depending on the HW (8 or 16 bit) */
+	if (priv->fw.config & TIMB_HW_CONFIG_SPI_8BIT) {
+		timberdale_xspi_platform_data.bits_per_word = 8;
+		timberdale_xspi_platform_data.devices =
+			timberdale_spi_8bit_board_info;
+		timberdale_xspi_platform_data.num_devices =
+			ARRAY_SIZE(timberdale_spi_8bit_board_info);
+	} else {
+		timberdale_xspi_platform_data.bits_per_word = 16;
+		timberdale_xspi_platform_data.devices =
+			timberdale_spi_16bit_board_info;
+		timberdale_xspi_platform_data.num_devices =
+			ARRAY_SIZE(timberdale_spi_16bit_board_info);
+	}
+
+	ip_setup = priv->fw.config & TIMB_HW_VER_MASK;
+	switch (ip_setup) {
+	case TIMB_HW_VER0:
+		err = mfd_add_devices(&dev->dev, -1,
+			timberdale_cells_bar0_cfg0,
+			ARRAY_SIZE(timberdale_cells_bar0_cfg0),
+			&dev->resource[0], msix_entries[0].vector);
+		break;
+	case TIMB_HW_VER1:
+		err = mfd_add_devices(&dev->dev, -1,
+			timberdale_cells_bar0_cfg1,
+			ARRAY_SIZE(timberdale_cells_bar0_cfg1),
+			&dev->resource[0], msix_entries[0].vector);
+		break;
+	case TIMB_HW_VER2:
+		err = mfd_add_devices(&dev->dev, -1,
+			timberdale_cells_bar0_cfg2,
+			ARRAY_SIZE(timberdale_cells_bar0_cfg2),
+			&dev->resource[0], msix_entries[0].vector);
+		break;
+	case TIMB_HW_VER3:
+		err = mfd_add_devices(&dev->dev, -1,
+			timberdale_cells_bar0_cfg3,
+			ARRAY_SIZE(timberdale_cells_bar0_cfg3),
+			&dev->resource[0], msix_entries[0].vector);
+		break;
+	default:
+		dev_err(&dev->dev, "Uknown IP setup: %d.%d.%d\n",
+			priv->fw.major, priv->fw.minor, ip_setup);
+		err = -ENODEV;
+		goto err_mfd;
+		break;
+	}
+
+	if (err) {
+		dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err);
+		goto err_mfd;
+	}
+
+	err = mfd_add_devices(&dev->dev, 0,
+		timberdale_cells_bar1, ARRAY_SIZE(timberdale_cells_bar1),
+		&dev->resource[1], msix_entries[0].vector);
+	if (err) {
+		dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err);
+		goto err_mfd2;
+	}
+
+	/* only version 0 and 3 have the iNand routed to SDHCI */
+	if (((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER0) ||
+		((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER3)) {
+		err = mfd_add_devices(&dev->dev, 1, timberdale_cells_bar2,
+			ARRAY_SIZE(timberdale_cells_bar2),
+			&dev->resource[2], msix_entries[0].vector);
+		if (err) {
+			dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err);
+			goto err_mfd2;
+		}
+	}
+
+	kfree(msix_entries);
+
+	dev_info(&dev->dev,
+		"Found Timberdale Card. Rev: %d.%d, HW config: 0x%02x\n",
+		priv->fw.major, priv->fw.minor, priv->fw.config);
+
+	return 0;
+
+err_mfd2:
+	mfd_remove_devices(&dev->dev);
+err_mfd:
+	device_remove_file(&dev->dev, &dev_attr_fw_ver);
+err_create_file:
+	pci_disable_msix(dev);
+err_msix:
+	iounmap(priv->ctl_membase);
+err_ioremap:
+	release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE);
+err_request:
+	pci_set_drvdata(dev, NULL);
+err_start:
+	pci_disable_device(dev);
+err_enable:
+	kfree(msix_entries);
+	kfree(priv);
+	pci_set_drvdata(dev, NULL);
+	return -ENODEV;
+}
+
+static void __devexit timb_remove(struct pci_dev *dev)
+{
+	struct timberdale_device *priv = pci_get_drvdata(dev);
+
+	mfd_remove_devices(&dev->dev);
+
+	device_remove_file(&dev->dev, &dev_attr_fw_ver);
+
+	iounmap(priv->ctl_membase);
+	release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE);
+
+	pci_disable_msix(dev);
+	pci_disable_device(dev);
+	pci_set_drvdata(dev, NULL);
+	kfree(priv);
+}
+
+static struct pci_device_id timberdale_pci_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_TIMB, PCI_DEVICE_ID_TIMB) },
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(pci, timberdale_pci_tbl);
+
+static struct pci_driver timberdale_pci_driver = {
+	.name = DRIVER_NAME,
+	.id_table = timberdale_pci_tbl,
+	.probe = timb_probe,
+	.remove = __devexit_p(timb_remove),
+};
+
+static int __init timberdale_init(void)
+{
+	int err;
+
+	err = pci_register_driver(&timberdale_pci_driver);
+	if (err < 0) {
+		printk(KERN_ERR
+			"Failed to register PCI driver for %s device.\n",
+			timberdale_pci_driver.name);
+		return -ENODEV;
+	}
+
+	printk(KERN_INFO "Driver for %s has been successfully registered.\n",
+		timberdale_pci_driver.name);
+
+	return 0;
+}
+
+static void __exit timberdale_exit(void)
+{
+	pci_unregister_driver(&timberdale_pci_driver);
+
+	printk(KERN_INFO "Driver for %s has been successfully unregistered.\n",
+		timberdale_pci_driver.name);
+}
+
+module_init(timberdale_init);
+module_exit(timberdale_exit);
+
+MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
+MODULE_VERSION(DRV_VERSION);
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/timberdale.h linux-libre-2.6.34-gnu1/drivers/mfd/timberdale.h
--- linux-libre-2.6.33-gnu1/drivers/mfd/timberdale.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/timberdale.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,130 @@
+/*
+ * timberdale.h timberdale FPGA MFD driver defines
+ * Copyright (c) 2009 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * Timberdale FPGA
+ */
+
+#ifndef MFD_TIMBERDALE_H
+#define MFD_TIMBERDALE_H
+
+#define DRV_VERSION		"0.1"
+
+/* This driver only support versions >= 3.8 and < 4.0  */
+#define TIMB_SUPPORTED_MAJOR	3
+
+/* This driver only support minor >= 8 */
+#define TIMB_REQUIRED_MINOR	8
+
+/* Registers of the control area */
+#define TIMB_REV_MAJOR	0x00
+#define TIMB_REV_MINOR	0x04
+#define TIMB_HW_CONFIG	0x08
+#define TIMB_SW_RST	0x40
+
+/* bits in the TIMB_HW_CONFIG register */
+#define TIMB_HW_CONFIG_SPI_8BIT	0x80
+
+#define TIMB_HW_VER_MASK	0x0f
+#define TIMB_HW_VER0		0x00
+#define TIMB_HW_VER1		0x01
+#define TIMB_HW_VER2		0x02
+#define TIMB_HW_VER3		0x03
+
+#define OCORESOFFSET	0x0
+#define OCORESEND	0x1f
+
+#define SPIOFFSET	0x80
+#define SPIEND		0xff
+
+#define UARTLITEOFFSET	0x100
+#define UARTLITEEND	0x10f
+
+#define RDSOFFSET	0x180
+#define RDSEND		0x183
+
+#define ETHOFFSET	0x300
+#define ETHEND		0x3ff
+
+#define GPIOOFFSET	0x400
+#define GPIOEND		0x7ff
+
+#define CHIPCTLOFFSET	0x800
+#define CHIPCTLEND	0x8ff
+#define CHIPCTLSIZE	(CHIPCTLEND - CHIPCTLOFFSET)
+
+#define INTCOFFSET	0xc00
+#define INTCEND		0xfff
+#define INTCSIZE	(INTCEND - INTCOFFSET)
+
+#define MOSTOFFSET	0x1000
+#define MOSTEND		0x13ff
+
+#define UARTOFFSET	0x1400
+#define UARTEND		0x17ff
+
+#define XIICOFFSET	0x1800
+#define XIICEND		0x19ff
+
+#define I2SOFFSET	0x1C00
+#define I2SEND		0x1fff
+
+#define LOGIWOFFSET	0x30000
+#define LOGIWEND	0x37fff
+
+#define MLCOREOFFSET	0x40000
+#define MLCOREEND	0x43fff
+
+#define DMAOFFSET	0x01000000
+#define DMAEND		0x013fffff
+
+/* SDHC0 is placed in PCI bar 1 */
+#define SDHC0OFFSET	0x00
+#define SDHC0END	0xff
+
+/* SDHC1 is placed in PCI bar 2 */
+#define SDHC1OFFSET	0x00
+#define SDHC1END	0xff
+
+#define PCI_VENDOR_ID_TIMB	0x10ee
+#define PCI_DEVICE_ID_TIMB	0xa123
+
+#define IRQ_TIMBERDALE_INIC		0
+#define IRQ_TIMBERDALE_MLB		1
+#define IRQ_TIMBERDALE_GPIO		2
+#define IRQ_TIMBERDALE_I2C		3
+#define IRQ_TIMBERDALE_UART		4
+#define IRQ_TIMBERDALE_DMA		5
+#define IRQ_TIMBERDALE_I2S		6
+#define IRQ_TIMBERDALE_TSC_INT		7
+#define IRQ_TIMBERDALE_SDHC		8
+#define IRQ_TIMBERDALE_ADV7180		9
+#define IRQ_TIMBERDALE_ETHSW_IF		10
+#define IRQ_TIMBERDALE_SPI		11
+#define IRQ_TIMBERDALE_UARTLITE		12
+#define IRQ_TIMBERDALE_MLCORE		13
+#define IRQ_TIMBERDALE_MLCORE_BUF	14
+#define IRQ_TIMBERDALE_RDS		15
+#define TIMBERDALE_NR_IRQS		16
+
+#define GPIO_PIN_ASCB		8
+#define GPIO_PIN_INIC_RST	14
+#define GPIO_PIN_BT_RST		15
+#define GPIO_NR_PINS		16
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/twl4030-codec.c linux-libre-2.6.34-gnu1/drivers/mfd/twl4030-codec.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/twl4030-codec.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/twl4030-codec.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/platform_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/twl4030-irq.c linux-libre-2.6.34-gnu1/drivers/mfd/twl4030-irq.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/twl4030-irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/twl4030-irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 #include <linux/i2c/twl.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/twl4030-power.c linux-libre-2.6.34-gnu1/drivers/mfd/twl4030-power.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/twl4030-power.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/twl4030-power.c	2010-05-16 17:17:36.000000000 -0400
@@ -405,7 +405,7 @@ static int __init twl4030_configure_reso
 
 	if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) {
 		remap &= ~SLEEP_STATE_MASK;
-		remap |= rconfig->remap_off << SLEEP_STATE_SHIFT;
+		remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT;
 	}
 
 	err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
@@ -461,6 +461,56 @@ out:
 	return err;
 }
 
+int twl4030_remove_script(u8 flags)
+{
+	int err = 0;
+
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_1,
+			R_PROTECT_KEY);
+	if (err) {
+		pr_err("twl4030: unable to unlock PROTECT_KEY\n");
+		return err;
+	}
+
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_2,
+			R_PROTECT_KEY);
+	if (err) {
+		pr_err("twl4030: unable to unlock PROTECT_KEY\n");
+		return err;
+	}
+
+	if (flags & TWL4030_WRST_SCRIPT) {
+		err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
+				R_SEQ_ADD_WARM);
+		if (err)
+			return err;
+	}
+	if (flags & TWL4030_WAKEUP12_SCRIPT) {
+		if (err)
+		err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
+				R_SEQ_ADD_S2A12);
+			return err;
+	}
+	if (flags & TWL4030_WAKEUP3_SCRIPT) {
+		err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
+				R_SEQ_ADD_S2A3);
+		if (err)
+			return err;
+	}
+	if (flags & TWL4030_SLEEP_SCRIPT) {
+		err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
+				R_SEQ_ADD_A2S);
+		if (err)
+			return err;
+	}
+
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, R_PROTECT_KEY);
+	if (err)
+		pr_err("TWL4030 Unable to relock registers\n");
+
+	return err;
+}
+
 void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
 {
 	int err = 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/twl-core.c linux-libre-2.6.34-gnu1/drivers/mfd/twl-core.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/twl-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/twl-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,13 +58,6 @@
 
 #define DRIVER_NAME			"twl"
 
-#if defined(CONFIG_TWL4030_BCI_BATTERY) || \
-	defined(CONFIG_TWL4030_BCI_BATTERY_MODULE)
-#define twl_has_bci()		true
-#else
-#define twl_has_bci()		false
-#endif
-
 #if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE)
 #define twl_has_keypad()	true
 #else
@@ -115,7 +108,8 @@
 #define twl_has_watchdog()        false
 #endif
 
-#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE)
+#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE) ||\
+	defined(CONFIG_SND_SOC_TWL6030) || defined(CONFIG_SND_SOC_TWL6030_MODULE)
 #define twl_has_codec()	true
 #else
 #define twl_has_codec()	false
@@ -129,7 +123,7 @@
 #define TWL_NUM_SLAVES		4
 
 #if defined(CONFIG_INPUT_TWL4030_PWRBUTTON) \
-	|| defined(CONFIG_INPUT_TWL4030_PWBUTTON_MODULE)
+	|| defined(CONFIG_INPUT_TWL4030_PWRBUTTON_MODULE)
 #define twl_has_pwrbutton()	true
 #else
 #define twl_has_pwrbutton()	false
@@ -204,6 +198,7 @@
 /* subchip/slave 3 0x4B - AUDIO */
 #define TWL6030_BASEADD_AUDIO		0x0000
 #define TWL6030_BASEADD_RSV		0x0000
+#define TWL6030_BASEADD_ZERO		0x0000
 
 /* Few power values */
 #define R_CFG_BOOT			0x05
@@ -319,9 +314,11 @@ static struct twl_mapping twl6030_map[]
 	{ SUB_CHIP_ID1, TWL6030_BASEADD_CHARGER },
 	{ SUB_CHIP_ID1, TWL6030_BASEADD_GASGAUGE },
 	{ SUB_CHIP_ID1, TWL6030_BASEADD_PWM },
-	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
-	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
+	{ SUB_CHIP_ID0, TWL6030_BASEADD_ZERO },
+	{ SUB_CHIP_ID1, TWL6030_BASEADD_ZERO },
 
+	{ SUB_CHIP_ID2, TWL6030_BASEADD_ZERO },
+	{ SUB_CHIP_ID2, TWL6030_BASEADD_ZERO },
 	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
 	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
 	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
@@ -587,18 +584,6 @@ add_children(struct twl4030_platform_dat
 	struct device	*child;
 	unsigned sub_chip_id;
 
-	if (twl_has_bci() && pdata->bci &&
-	    !(features & (TPS_SUBSET | TWL5031))) {
-		child = add_child(3, "twl4030_bci",
-				pdata->bci, sizeof(*pdata->bci),
-				false,
-				/* irq0 = CHG_PRES, irq1 = BCI */
-				pdata->irq_base + BCI_PRES_INTR_OFFSET,
-				pdata->irq_base + BCI_INTR_OFFSET);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-	}
-
 	if (twl_has_gpio() && pdata->gpio) {
 		child = add_child(SUB_CHIP_ID1, "twl4030_gpio",
 				pdata->gpio, sizeof(*pdata->gpio),
@@ -711,8 +696,19 @@ add_children(struct twl4030_platform_dat
 			return PTR_ERR(child);
 	}
 
-	if (twl_has_codec() && pdata->codec) {
-		child = add_child(1, "twl4030_codec",
+	if (twl_has_codec() && pdata->codec && twl_class_is_4030()) {
+		sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
+		child = add_child(sub_chip_id, "twl4030_codec",
+				pdata->codec, sizeof(*pdata->codec),
+				false, 0, 0);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
+	/* Phoenix*/
+	if (twl_has_codec() && pdata->codec && twl_class_is_6030()) {
+		sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
+		child = add_child(sub_chip_id, "twl6030_codec",
 				pdata->codec, sizeof(*pdata->codec),
 				false, 0, 0);
 		if (IS_ERR(child))
@@ -965,6 +961,7 @@ twl_probe(struct i2c_client *client, con
 	int				status;
 	unsigned			i;
 	struct twl4030_platform_data	*pdata = client->dev.platform_data;
+	u8 temp;
 
 	if (!pdata) {
 		dev_dbg(&client->dev, "no platform data?\n");
@@ -1032,6 +1029,18 @@ twl_probe(struct i2c_client *client, con
 			goto fail;
 	}
 
+	/* Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface.
+	 * Program I2C_SCL_CTRL_PU(bit 0)=0, I2C_SDA_CTRL_PU (bit 2)=0,
+	 * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0.
+	 */
+
+	if (twl_class_is_4030()) {
+		twl_i2c_read_u8(TWL4030_MODULE_INTBR, &temp, REG_GPPUPDCTR1);
+		temp &= ~(SR_I2C_SDA_CTRL_PU | SR_I2C_SCL_CTRL_PU | \
+		I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU);
+		twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1);
+	}
+
 	status = add_children(pdata, id->driver_data);
 fail:
 	if (status < 0)
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/ucb1400_core.c linux-libre-2.6.34-gnu1/drivers/mfd/ucb1400_core.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/ucb1400_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/ucb1400_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/ucb1400.h>
 
 unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel,
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/ucb1x00-core.c linux-libre-2.6.34-gnu1/drivers/mfd/ucb1x00-core.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/ucb1x00-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/ucb1x00-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/mutex.h>
 #include <linux/mfd/ucb1x00.h>
 #include <linux/gpio.h>
+#include <linux/semaphore.h>
 
 #include <mach/dma.h>
 #include <mach/hardware.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/wm831x-core.c linux-libre-2.6.34-gnu1/drivers/mfd/wm831x-core.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/wm831x-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/wm831x-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/bcd.h>
 #include <linux/delay.h>
 #include <linux/mfd/core.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/pdata.h>
@@ -321,7 +322,6 @@ EXPORT_SYMBOL_GPL(wm831x_set_bits);
  */
 int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
 {
-	int tries = 10;
 	int ret, src;
 
 	mutex_lock(&wm831x->auxadc_lock);
@@ -349,13 +349,17 @@ int wm831x_auxadc_read(struct wm831x *wm
 		goto disable;
 	}
 
-	do {
-		msleep(1);
+	/* If an interrupt arrived late clean up after it */
+	try_wait_for_completion(&wm831x->auxadc_done);
 
-		ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL);
-		if (ret < 0)
-			ret = WM831X_AUX_CVT_ENA;
-	} while ((ret & WM831X_AUX_CVT_ENA) && --tries);
+	/* Ignore the result to allow us to soldier on without IRQ hookup */
+	wait_for_completion_timeout(&wm831x->auxadc_done, msecs_to_jiffies(5));
+
+	ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "AUXADC status read failed: %d\n", ret);
+		goto disable;
+	}
 
 	if (ret & WM831X_AUX_CVT_ENA) {
 		dev_err(wm831x->dev, "Timed out reading AUXADC\n");
@@ -390,6 +394,15 @@ out:
 }
 EXPORT_SYMBOL_GPL(wm831x_auxadc_read);
 
+static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data)
+{
+	struct wm831x *wm831x = irq_data;
+
+	complete(&wm831x->auxadc_done);
+
+	return IRQ_HANDLED;
+}
+
 /**
  * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC
  *
@@ -1411,6 +1424,7 @@ static int wm831x_device_init(struct wm8
 	mutex_init(&wm831x->io_lock);
 	mutex_init(&wm831x->key_lock);
 	mutex_init(&wm831x->auxadc_lock);
+	init_completion(&wm831x->auxadc_done);
 	dev_set_drvdata(wm831x->dev, wm831x);
 
 	ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
@@ -1449,18 +1463,33 @@ static int wm831x_device_init(struct wm8
 	case WM8310:
 		parent = WM8310;
 		wm831x->num_gpio = 16;
+		if (rev > 0) {
+			wm831x->has_gpio_ena = 1;
+			wm831x->has_cs_sts = 1;
+		}
+
 		dev_info(wm831x->dev, "WM8310 revision %c\n", 'A' + rev);
 		break;
 
 	case WM8311:
 		parent = WM8311;
 		wm831x->num_gpio = 16;
+		if (rev > 0) {
+			wm831x->has_gpio_ena = 1;
+			wm831x->has_cs_sts = 1;
+		}
+
 		dev_info(wm831x->dev, "WM8311 revision %c\n", 'A' + rev);
 		break;
 
 	case WM8312:
 		parent = WM8312;
 		wm831x->num_gpio = 16;
+		if (rev > 0) {
+			wm831x->has_gpio_ena = 1;
+			wm831x->has_cs_sts = 1;
+		}
+
 		dev_info(wm831x->dev, "WM8312 revision %c\n", 'A' + rev);
 		break;
 
@@ -1508,6 +1537,16 @@ static int wm831x_device_init(struct wm8
 	if (ret != 0)
 		goto err;
 
+	if (wm831x->irq_base) {
+		ret = request_threaded_irq(wm831x->irq_base +
+					   WM831X_IRQ_AUXADC_DATA,
+					   NULL, wm831x_auxadc_irq, 0,
+					   "auxadc", wm831x);
+		if (ret < 0)
+			dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n",
+				ret);
+	}
+
 	/* The core device is up, instantiate the subdevices. */
 	switch (parent) {
 	case WM8310:
@@ -1578,6 +1617,8 @@ static void wm831x_device_exit(struct wm
 {
 	wm831x_otp_exit(wm831x);
 	mfd_remove_devices(wm831x->dev);
+	if (wm831x->irq_base)
+		free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x);
 	wm831x_irq_exit(wm831x);
 	kfree(wm831x);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/wm8350-core.c linux-libre-2.6.34-gnu1/drivers/mfd/wm8350-core.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/wm8350-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/wm8350-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/bug.h>
 #include <linux/device.h>
 #include <linux/delay.h>
@@ -339,7 +340,6 @@ EXPORT_SYMBOL_GPL(wm8350_reg_unlock);
 int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
 {
 	u16 reg, result = 0;
-	int tries = 5;
 
 	if (channel < WM8350_AUXADC_AUX1 || channel > WM8350_AUXADC_TEMP)
 		return -EINVAL;
@@ -363,12 +363,17 @@ int wm8350_read_auxadc(struct wm8350 *wm
 	reg |= 1 << channel | WM8350_AUXADC_POLL;
 	wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg);
 
-	do {
-		schedule_timeout_interruptible(1);
-		reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
-	} while ((reg & WM8350_AUXADC_POLL) && --tries);
+	/* If a late IRQ left the completion signalled then consume
+	 * the completion. */
+	try_wait_for_completion(&wm8350->auxadc_done);
 
-	if (!tries)
+	/* We ignore the result of the completion and just check for a
+	 * conversion result, allowing us to soldier on if the IRQ
+	 * infrastructure is not set up for the chip. */
+	wait_for_completion_timeout(&wm8350->auxadc_done, msecs_to_jiffies(5));
+
+	reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
+	if (reg & WM8350_AUXADC_POLL)
 		dev_err(wm8350->dev, "adc chn %d read timeout\n", channel);
 	else
 		result = wm8350_reg_read(wm8350,
@@ -385,6 +390,15 @@ int wm8350_read_auxadc(struct wm8350 *wm
 }
 EXPORT_SYMBOL_GPL(wm8350_read_auxadc);
 
+static irqreturn_t wm8350_auxadc_irq(int irq, void *irq_data)
+{
+	struct wm8350 *wm8350 = irq_data;
+
+	complete(&wm8350->auxadc_done);
+
+	return IRQ_HANDLED;
+}
+
 /*
  * Cache is always host endian.
  */
@@ -682,11 +696,22 @@ int wm8350_device_init(struct wm8350 *wm
 	}
 
 	mutex_init(&wm8350->auxadc_mutex);
+	init_completion(&wm8350->auxadc_done);
 
 	ret = wm8350_irq_init(wm8350, irq, pdata);
 	if (ret < 0)
 		goto err;
 
+	if (wm8350->irq_base) {
+		ret = request_threaded_irq(wm8350->irq_base +
+					   WM8350_IRQ_AUXADC_DATARDY,
+					   NULL, wm8350_auxadc_irq, 0,
+					   "auxadc", wm8350);
+		if (ret < 0)
+			dev_warn(wm8350->dev,
+				 "Failed to request AUXADC IRQ: %d\n", ret);
+	}
+
 	if (pdata && pdata->init) {
 		ret = pdata->init(wm8350);
 		if (ret != 0) {
@@ -736,6 +761,9 @@ void wm8350_device_exit(struct wm8350 *w
 	platform_device_unregister(wm8350->gpio.pdev);
 	platform_device_unregister(wm8350->codec.pdev);
 
+	if (wm8350->irq_base)
+		free_irq(wm8350->irq_base + WM8350_IRQ_AUXADC_DATARDY, wm8350);
+
 	wm8350_irq_exit(wm8350);
 
 	kfree(wm8350->reg_cache);
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/wm8350-i2c.c linux-libre-2.6.34-gnu1/drivers/mfd/wm8350-i2c.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/wm8350-i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/wm8350-i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/wm8350/core.h>
+#include <linux/slab.h>
 
 static int wm8350_i2c_read_device(struct wm8350 *wm8350, char reg,
 				  int bytes, void *dest)
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/wm8350-irq.c linux-libre-2.6.34-gnu1/drivers/mfd/wm8350-irq.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/wm8350-irq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/wm8350-irq.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,7 @@
 #include <linux/bug.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
+#include <linux/irq.h>
 
 #include <linux/mfd/wm8350/core.h>
 #include <linux/mfd/wm8350/audio.h>
@@ -29,8 +29,6 @@
 #include <linux/mfd/wm8350/supply.h>
 #include <linux/mfd/wm8350/wdt.h>
 
-#define WM8350_NUM_IRQ_REGS 7
-
 #define WM8350_INT_OFFSET_1                     0
 #define WM8350_INT_OFFSET_2                     1
 #define WM8350_POWER_UP_INT_OFFSET              2
@@ -366,19 +364,10 @@ static struct wm8350_irq_data wm8350_irq
 	},
 };
 
-static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq)
+static inline struct wm8350_irq_data *irq_to_wm8350_irq(struct wm8350 *wm8350,
+							int irq)
 {
-	mutex_lock(&wm8350->irq_mutex);
-
-	if (wm8350->irq[irq].handler)
-		wm8350->irq[irq].handler(irq, wm8350->irq[irq].data);
-	else {
-		dev_err(wm8350->dev, "irq %d nobody cared. now masked.\n",
-			irq);
-		wm8350_mask_irq(wm8350, irq);
-	}
-
-	mutex_unlock(&wm8350->irq_mutex);
+	return &wm8350_irqs[irq - wm8350->irq_base];
 }
 
 /*
@@ -386,7 +375,9 @@ static void wm8350_irq_call_handler(stru
  * interrupts are clear on read the IRQ line will be reasserted and
  * the physical IRQ will be handled again if another interrupt is
  * asserted while we run - in the normal course of events this is a
- * rare occurrence so we save I2C/SPI reads.
+ * rare occurrence so we save I2C/SPI reads.  We're also assuming that
+ * it's rare to get lots of interrupts firing simultaneously so try to
+ * minimise I/O.
  */
 static irqreturn_t wm8350_irq(int irq, void *irq_data)
 {
@@ -397,7 +388,6 @@ static irqreturn_t wm8350_irq(int irq, v
 	struct wm8350_irq_data *data;
 	int i;
 
-	/* TODO: Use block reads to improve performance? */
 	level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS)
 		& ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK);
 
@@ -416,93 +406,101 @@ static irqreturn_t wm8350_irq(int irq, v
 			sub_reg[data->reg] =
 				wm8350_reg_read(wm8350, WM8350_INT_STATUS_1 +
 						data->reg);
-			sub_reg[data->reg] &=
-				~wm8350_reg_read(wm8350,
-						 WM8350_INT_STATUS_1_MASK +
-						 data->reg);
+			sub_reg[data->reg] &= ~wm8350->irq_masks[data->reg];
 			read_done[data->reg] = 1;
 		}
 
 		if (sub_reg[data->reg] & data->mask)
-			wm8350_irq_call_handler(wm8350, i);
+			handle_nested_irq(wm8350->irq_base + i);
 	}
 
 	return IRQ_HANDLED;
 }
 
-int wm8350_register_irq(struct wm8350 *wm8350, int irq,
-			irq_handler_t handler, unsigned long flags,
-			const char *name, void *data)
+static void wm8350_irq_lock(unsigned int irq)
 {
-	if (irq < 0 || irq >= WM8350_NUM_IRQ || !handler)
-		return -EINVAL;
-
-	if (wm8350->irq[irq].handler)
-		return -EBUSY;
-
-	mutex_lock(&wm8350->irq_mutex);
-	wm8350->irq[irq].handler = handler;
-	wm8350->irq[irq].data = data;
-	mutex_unlock(&wm8350->irq_mutex);
-
-	wm8350_unmask_irq(wm8350, irq);
+	struct wm8350 *wm8350 = get_irq_chip_data(irq);
 
-	return 0;
+	mutex_lock(&wm8350->irq_lock);
 }
-EXPORT_SYMBOL_GPL(wm8350_register_irq);
 
-int wm8350_free_irq(struct wm8350 *wm8350, int irq)
+static void wm8350_irq_sync_unlock(unsigned int irq)
 {
-	if (irq < 0 || irq >= WM8350_NUM_IRQ)
-		return -EINVAL;
+	struct wm8350 *wm8350 = get_irq_chip_data(irq);
+	int i;
 
-	wm8350_mask_irq(wm8350, irq);
+	for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) {
+		/* If there's been a change in the mask write it back
+		 * to the hardware. */
+		if (wm8350->irq_masks[i] !=
+		    wm8350->reg_cache[WM8350_INT_STATUS_1_MASK + i])
+			WARN_ON(wm8350_reg_write(wm8350,
+					 WM8350_INT_STATUS_1_MASK + i,
+						 wm8350->irq_masks[i]));
+	}
 
-	mutex_lock(&wm8350->irq_mutex);
-	wm8350->irq[irq].handler = NULL;
-	mutex_unlock(&wm8350->irq_mutex);
-	return 0;
+	mutex_unlock(&wm8350->irq_lock);
 }
-EXPORT_SYMBOL_GPL(wm8350_free_irq);
 
-int wm8350_mask_irq(struct wm8350 *wm8350, int irq)
+static void wm8350_irq_enable(unsigned int irq)
 {
-	return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK +
-			       wm8350_irqs[irq].reg,
-			       wm8350_irqs[irq].mask);
+	struct wm8350 *wm8350 = get_irq_chip_data(irq);
+	struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq);
+
+	wm8350->irq_masks[irq_data->reg] &= ~irq_data->mask;
 }
-EXPORT_SYMBOL_GPL(wm8350_mask_irq);
 
-int wm8350_unmask_irq(struct wm8350 *wm8350, int irq)
+static void wm8350_irq_disable(unsigned int irq)
 {
-	return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK +
-				 wm8350_irqs[irq].reg,
-				 wm8350_irqs[irq].mask);
+	struct wm8350 *wm8350 = get_irq_chip_data(irq);
+	struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq);
+
+	wm8350->irq_masks[irq_data->reg] |= irq_data->mask;
 }
-EXPORT_SYMBOL_GPL(wm8350_unmask_irq);
+
+static struct irq_chip wm8350_irq_chip = {
+	.name = "wm8350",
+	.bus_lock = wm8350_irq_lock,
+	.bus_sync_unlock = wm8350_irq_sync_unlock,
+	.disable = wm8350_irq_disable,
+	.enable = wm8350_irq_enable,
+};
 
 int wm8350_irq_init(struct wm8350 *wm8350, int irq,
 		    struct wm8350_platform_data *pdata)
 {
-	int ret;
+	int ret, cur_irq, i;
 	int flags = IRQF_ONESHOT;
 
 	if (!irq) {
-		dev_err(wm8350->dev, "No IRQ configured\n");
-		return -EINVAL;
+		dev_warn(wm8350->dev, "No interrupt support, no core IRQ\n");
+		return 0;
 	}
 
+	if (!pdata || !pdata->irq_base) {
+		dev_warn(wm8350->dev, "No interrupt support, no IRQ base\n");
+		return 0;
+	}
+
+	/* Mask top level interrupts */
 	wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF);
-	wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK, 0xFFFF);
-	wm8350_reg_write(wm8350, WM8350_INT_STATUS_2_MASK, 0xFFFF);
-	wm8350_reg_write(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, 0xFFFF);
-	wm8350_reg_write(wm8350, WM8350_GPIO_INT_STATUS_MASK, 0xFFFF);
-	wm8350_reg_write(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK, 0xFFFF);
 
-	mutex_init(&wm8350->irq_mutex);
+	/* Mask all individual interrupts by default and cache the
+	 * masks.  We read the masks back since there are unwritable
+	 * bits in the mask registers. */
+	for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) {
+		wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK + i,
+				 0xFFFF);
+		wm8350->irq_masks[i] =
+			wm8350_reg_read(wm8350,
+					WM8350_INT_STATUS_1_MASK + i);
+	}
+
+	mutex_init(&wm8350->irq_lock);
 	wm8350->chip_irq = irq;
+	wm8350->irq_base = pdata->irq_base;
 
-	if (pdata && pdata->irq_high) {
+	if (pdata->irq_high) {
 		flags |= IRQF_TRIGGER_HIGH;
 
 		wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
@@ -514,11 +512,32 @@ int wm8350_irq_init(struct wm8350 *wm835
 				  WM8350_IRQ_POL);
 	}
 
+	/* Register with genirq */
+	for (cur_irq = wm8350->irq_base;
+	     cur_irq < ARRAY_SIZE(wm8350_irqs) + wm8350->irq_base;
+	     cur_irq++) {
+		set_irq_chip_data(cur_irq, wm8350);
+		set_irq_chip_and_handler(cur_irq, &wm8350_irq_chip,
+					 handle_edge_irq);
+		set_irq_nested_thread(cur_irq, 1);
+
+		/* ARM needs us to explicitly flag the IRQ as valid
+		 * and will set them noprobe when we do so. */
+#ifdef CONFIG_ARM
+		set_irq_flags(cur_irq, IRQF_VALID);
+#else
+		set_irq_noprobe(cur_irq);
+#endif
+	}
+
 	ret = request_threaded_irq(irq, NULL, wm8350_irq, flags,
 				   "wm8350", wm8350);
 	if (ret != 0)
 		dev_err(wm8350->dev, "Failed to request IRQ: %d\n", ret);
 
+	/* Allow interrupts to fire */
+	wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0);
+
 	return ret;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/wm8400-core.c linux-libre-2.6.34-gnu1/drivers/mfd/wm8400-core.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/wm8400-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/wm8400-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/wm8400-private.h>
 #include <linux/mfd/wm8400-audio.h>
+#include <linux/slab.h>
 
 static struct {
 	u16  readable;    /* Mask of readable bits */
diff -druNp linux-libre-2.6.33-gnu1/drivers/mfd/wm8994-core.c linux-libre-2.6.34-gnu1/drivers/mfd/wm8994-core.c
--- linux-libre-2.6.33-gnu1/drivers/mfd/wm8994-core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mfd/wm8994-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,538 @@
+/*
+ * wm8994-core.c  --  Device access for Wolfson WM8994
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License 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/slab.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/mfd/core.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+
+#include <linux/mfd/wm8994/core.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/mfd/wm8994/registers.h>
+
+static int wm8994_read(struct wm8994 *wm8994, unsigned short reg,
+		       int bytes, void *dest)
+{
+	int ret, i;
+	u16 *buf = dest;
+
+	BUG_ON(bytes % 2);
+	BUG_ON(bytes <= 0);
+
+	ret = wm8994->read_dev(wm8994, reg, bytes, dest);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < bytes / 2; i++) {
+		buf[i] = be16_to_cpu(buf[i]);
+
+		dev_vdbg(wm8994->dev, "Read %04x from R%d(0x%x)\n",
+			 buf[i], reg + i, reg + i);
+	}
+
+	return 0;
+}
+
+/**
+ * wm8994_reg_read: Read a single WM8994 register.
+ *
+ * @wm8994: Device to read from.
+ * @reg: Register to read.
+ */
+int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg)
+{
+	unsigned short val;
+	int ret;
+
+	mutex_lock(&wm8994->io_lock);
+
+	ret = wm8994_read(wm8994, reg, 2, &val);
+
+	mutex_unlock(&wm8994->io_lock);
+
+	if (ret < 0)
+		return ret;
+	else
+		return val;
+}
+EXPORT_SYMBOL_GPL(wm8994_reg_read);
+
+/**
+ * wm8994_bulk_read: Read multiple WM8994 registers
+ *
+ * @wm8994: Device to read from
+ * @reg: First register
+ * @count: Number of registers
+ * @buf: Buffer to fill.
+ */
+int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
+		     int count, u16 *buf)
+{
+	int ret;
+
+	mutex_lock(&wm8994->io_lock);
+
+	ret = wm8994_read(wm8994, reg, count * 2, buf);
+
+	mutex_unlock(&wm8994->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wm8994_bulk_read);
+
+static int wm8994_write(struct wm8994 *wm8994, unsigned short reg,
+			int bytes, void *src)
+{
+	u16 *buf = src;
+	int i;
+
+	BUG_ON(bytes % 2);
+	BUG_ON(bytes <= 0);
+
+	for (i = 0; i < bytes / 2; i++) {
+		dev_vdbg(wm8994->dev, "Write %04x to R%d(0x%x)\n",
+			 buf[i], reg + i, reg + i);
+
+		buf[i] = cpu_to_be16(buf[i]);
+	}
+
+	return wm8994->write_dev(wm8994, reg, bytes, src);
+}
+
+/**
+ * wm8994_reg_write: Write a single WM8994 register.
+ *
+ * @wm8994: Device to write to.
+ * @reg: Register to write to.
+ * @val: Value to write.
+ */
+int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
+		     unsigned short val)
+{
+	int ret;
+
+	mutex_lock(&wm8994->io_lock);
+
+	ret = wm8994_write(wm8994, reg, 2, &val);
+
+	mutex_unlock(&wm8994->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wm8994_reg_write);
+
+/**
+ * wm8994_set_bits: Set the value of a bitfield in a WM8994 register
+ *
+ * @wm8994: Device to write to.
+ * @reg: Register to write to.
+ * @mask: Mask of bits to set.
+ * @val: Value to set (unshifted)
+ */
+int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
+		    unsigned short mask, unsigned short val)
+{
+	int ret;
+	u16 r;
+
+	mutex_lock(&wm8994->io_lock);
+
+	ret = wm8994_read(wm8994, reg, 2, &r);
+	if (ret < 0)
+		goto out;
+
+	r &= ~mask;
+	r |= val;
+
+	ret = wm8994_write(wm8994, reg, 2, &r);
+
+out:
+	mutex_unlock(&wm8994->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wm8994_set_bits);
+
+static struct mfd_cell wm8994_regulator_devs[] = {
+	{ .name = "wm8994-ldo", .id = 1 },
+	{ .name = "wm8994-ldo", .id = 2 },
+};
+
+static struct mfd_cell wm8994_devs[] = {
+	{ .name = "wm8994-codec" },
+	{ .name = "wm8994-gpio" },
+};
+
+/*
+ * Supplies for the main bulk of CODEC; the LDO supplies are ignored
+ * and should be handled via the standard regulator API supply
+ * management.
+ */
+static const char *wm8994_main_supplies[] = {
+	"DBVDD",
+	"DCVDD",
+	"AVDD1",
+	"AVDD2",
+	"CPVDD",
+	"SPKVDD1",
+	"SPKVDD2",
+};
+
+#ifdef CONFIG_PM
+static int wm8994_device_suspend(struct device *dev)
+{
+	struct wm8994 *wm8994 = dev_get_drvdata(dev);
+	int ret;
+
+	/* GPIO configuration state is saved here since we may be configuring
+	 * the GPIO alternate functions even if we're not using the gpiolib
+	 * driver for them.
+	 */
+	ret = wm8994_read(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2,
+			  &wm8994->gpio_regs);
+	if (ret < 0)
+		dev_err(dev, "Failed to save GPIO registers: %d\n", ret);
+
+	/* For similar reasons we also stash the regulator states */
+	ret = wm8994_read(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2,
+			  &wm8994->ldo_regs);
+	if (ret < 0)
+		dev_err(dev, "Failed to save LDO registers: %d\n", ret);
+
+	ret = regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
+				     wm8994->supplies);
+	if (ret != 0) {
+		dev_err(dev, "Failed to disable supplies: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int wm8994_device_resume(struct device *dev)
+{
+	struct wm8994 *wm8994 = dev_get_drvdata(dev);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies),
+				    wm8994->supplies);
+	if (ret != 0) {
+		dev_err(dev, "Failed to enable supplies: %d\n", ret);
+		return ret;
+	}
+
+	ret = wm8994_write(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2,
+			   &wm8994->ldo_regs);
+	if (ret < 0)
+		dev_err(dev, "Failed to restore LDO registers: %d\n", ret);
+
+	ret = wm8994_write(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2,
+			   &wm8994->gpio_regs);
+	if (ret < 0)
+		dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_REGULATOR
+static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
+{
+	struct wm8994_ldo_pdata *ldo_pdata;
+
+	if (!pdata)
+		return 0;
+
+	ldo_pdata = &pdata->ldo[ldo];
+
+	if (!ldo_pdata->init_data)
+		return 0;
+
+	return ldo_pdata->init_data->num_consumer_supplies != 0;
+}
+#else
+static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
+{
+	return 0;
+}
+#endif
+
+/*
+ * Instantiate the generic non-control parts of the device.
+ */
+static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
+{
+	struct wm8994_pdata *pdata = wm8994->dev->platform_data;
+	int ret, i;
+
+	mutex_init(&wm8994->io_lock);
+	dev_set_drvdata(wm8994->dev, wm8994);
+
+	/* Add the on-chip regulators first for bootstrapping */
+	ret = mfd_add_devices(wm8994->dev, -1,
+			      wm8994_regulator_devs,
+			      ARRAY_SIZE(wm8994_regulator_devs),
+			      NULL, 0);
+	if (ret != 0) {
+		dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
+		goto err;
+	}
+
+	wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
+				   ARRAY_SIZE(wm8994_main_supplies),
+				   GFP_KERNEL);
+	if (!wm8994->supplies)
+		goto err;
+
+	for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++)
+		wm8994->supplies[i].supply = wm8994_main_supplies[i];
+
+	ret = regulator_bulk_get(wm8994->dev, ARRAY_SIZE(wm8994_main_supplies),
+				 wm8994->supplies);
+	if (ret != 0) {
+		dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret);
+		goto err_supplies;
+	}
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies),
+				    wm8994->supplies);
+	if (ret != 0) {
+		dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret);
+		goto err_get;
+	}
+
+	ret = wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET);
+	if (ret < 0) {
+		dev_err(wm8994->dev, "Failed to read ID register\n");
+		goto err_enable;
+	}
+	if (ret != 0x8994) {
+		dev_err(wm8994->dev, "Device is not a WM8994, ID is %x\n",
+			ret);
+		ret = -EINVAL;
+		goto err_enable;
+	}
+
+	ret = wm8994_reg_read(wm8994, WM8994_CHIP_REVISION);
+	if (ret < 0) {
+		dev_err(wm8994->dev, "Failed to read revision register: %d\n",
+			ret);
+		goto err_enable;
+	}
+
+	switch (ret) {
+	case 0:
+	case 1:
+		dev_warn(wm8994->dev, "revision %c not fully supported\n",
+			'A' + ret);
+		break;
+	default:
+		dev_info(wm8994->dev, "revision %c\n", 'A' + ret);
+		break;
+	}
+
+
+	if (pdata) {
+		wm8994->gpio_base = pdata->gpio_base;
+
+		/* GPIO configuration is only applied if it's non-zero */
+		for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
+			if (pdata->gpio_defaults[i]) {
+				wm8994_set_bits(wm8994, WM8994_GPIO_1 + i,
+						0xffff,
+						pdata->gpio_defaults[i]);
+			}
+		}
+	}
+
+	/* In some system designs where the regulators are not in use,
+	 * we can achieve a small reduction in leakage currents by
+	 * floating LDO outputs.  This bit makes no difference if the
+	 * LDOs are enabled, it only affects cases where the LDOs were
+	 * in operation and are then disabled.
+	 */
+	for (i = 0; i < WM8994_NUM_LDO_REGS; i++) {
+		if (wm8994_ldo_in_use(pdata, i))
+			wm8994_set_bits(wm8994, WM8994_LDO_1 + i,
+					WM8994_LDO1_DISCH, WM8994_LDO1_DISCH);
+		else
+			wm8994_set_bits(wm8994, WM8994_LDO_1 + i,
+					WM8994_LDO1_DISCH, 0);
+	}
+
+	ret = mfd_add_devices(wm8994->dev, -1,
+			      wm8994_devs, ARRAY_SIZE(wm8994_devs),
+			      NULL, 0);
+	if (ret != 0) {
+		dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
+		goto err_enable;
+	}
+
+	return 0;
+
+err_enable:
+	regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
+			       wm8994->supplies);
+err_get:
+	regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies);
+err_supplies:
+	kfree(wm8994->supplies);
+err:
+	mfd_remove_devices(wm8994->dev);
+	kfree(wm8994);
+	return ret;
+}
+
+static void wm8994_device_exit(struct wm8994 *wm8994)
+{
+	mfd_remove_devices(wm8994->dev);
+	regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
+			       wm8994->supplies);
+	regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies);
+	kfree(wm8994->supplies);
+	kfree(wm8994);
+}
+
+static int wm8994_i2c_read_device(struct wm8994 *wm8994, unsigned short reg,
+				  int bytes, void *dest)
+{
+	struct i2c_client *i2c = wm8994->control_data;
+	int ret;
+	u16 r = cpu_to_be16(reg);
+
+	ret = i2c_master_send(i2c, (unsigned char *)&r, 2);
+	if (ret < 0)
+		return ret;
+	if (ret != 2)
+		return -EIO;
+
+	ret = i2c_master_recv(i2c, dest, bytes);
+	if (ret < 0)
+		return ret;
+	if (ret != bytes)
+		return -EIO;
+	return 0;
+}
+
+/* Currently we allocate the write buffer on the stack; this is OK for
+ * small writes - if we need to do large writes this will need to be
+ * revised.
+ */
+static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg,
+				   int bytes, void *src)
+{
+	struct i2c_client *i2c = wm8994->control_data;
+	unsigned char msg[bytes + 2];
+	int ret;
+
+	reg = cpu_to_be16(reg);
+	memcpy(&msg[0], &reg, 2);
+	memcpy(&msg[2], src, bytes);
+
+	ret = i2c_master_send(i2c, msg, bytes + 2);
+	if (ret < 0)
+		return ret;
+	if (ret < bytes + 2)
+		return -EIO;
+
+	return 0;
+}
+
+static int wm8994_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
+{
+	struct wm8994 *wm8994;
+
+	wm8994 = kzalloc(sizeof(struct wm8994), GFP_KERNEL);
+	if (wm8994 == NULL) {
+		kfree(i2c);
+		return -ENOMEM;
+	}
+
+	i2c_set_clientdata(i2c, wm8994);
+	wm8994->dev = &i2c->dev;
+	wm8994->control_data = i2c;
+	wm8994->read_dev = wm8994_i2c_read_device;
+	wm8994->write_dev = wm8994_i2c_write_device;
+
+	return wm8994_device_init(wm8994, id->driver_data, i2c->irq);
+}
+
+static int wm8994_i2c_remove(struct i2c_client *i2c)
+{
+	struct wm8994 *wm8994 = i2c_get_clientdata(i2c);
+
+	wm8994_device_exit(wm8994);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int wm8994_i2c_suspend(struct i2c_client *i2c, pm_message_t state)
+{
+	return wm8994_device_suspend(&i2c->dev);
+}
+
+static int wm8994_i2c_resume(struct i2c_client *i2c)
+{
+	return wm8994_device_resume(&i2c->dev);
+}
+#else
+#define wm8994_i2c_suspend NULL
+#define wm8994_i2c_resume NULL
+#endif
+
+static const struct i2c_device_id wm8994_i2c_id[] = {
+	{ "wm8994", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);
+
+static struct i2c_driver wm8994_i2c_driver = {
+	.driver = {
+		   .name = "wm8994",
+		   .owner = THIS_MODULE,
+	},
+	.probe = wm8994_i2c_probe,
+	.remove = wm8994_i2c_remove,
+	.suspend = wm8994_i2c_suspend,
+	.resume = wm8994_i2c_resume,
+	.id_table = wm8994_i2c_id,
+};
+
+static int __init wm8994_i2c_init(void)
+{
+	int ret;
+
+	ret = i2c_add_driver(&wm8994_i2c_driver);
+	if (ret != 0)
+		pr_err("Failed to register wm8994 I2C driver: %d\n", ret);
+
+	return ret;
+}
+module_init(wm8994_i2c_init);
+
+static void __exit wm8994_i2c_exit(void)
+{
+	i2c_del_driver(&wm8994_i2c_driver);
+}
+module_exit(wm8994_i2c_exit);
+
+MODULE_DESCRIPTION("Core support for the WM8994 audio CODEC");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/atmel_pwm.c linux-libre-2.6.34-gnu1/drivers/misc/atmel_pwm.c
--- linux-libre-2.6.33-gnu1/drivers/misc/atmel_pwm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/atmel_pwm.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 #include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/atmel-ssc.c linux-libre-2.6.34-gnu1/drivers/misc/atmel-ssc.c
--- linux-libre-2.6.33-gnu1/drivers/misc/atmel-ssc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/atmel-ssc.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/spinlock.h>
 #include <linux/atmel-ssc.h>
+#include <linux/slab.h>
 
 /* Serialize access to ssc_list and user count */
 static DEFINE_SPINLOCK(user_lock);
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/atmel_tclib.c linux-libre-2.6.34-gnu1/drivers/misc/atmel_tclib.c
--- linux-libre-2.6.33-gnu1/drivers/misc/atmel_tclib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/atmel_tclib.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 /* Number of bytes to reserve for the iomem resource */
 #define ATMEL_TC_IOMEM_SIZE	256
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/c2port/core.c linux-libre-2.6.34-gnu1/drivers/misc/c2port/core.c
--- linux-libre-2.6.33-gnu1/drivers/misc/c2port/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/c2port/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/idr.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <linux/c2port.h>
 
@@ -912,8 +913,8 @@ struct c2port_device *c2port_device_regi
 
 	c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
 					"c2port%d", id);
-	if (unlikely(!c2dev->dev)) {
-		ret = -ENOMEM;
+	if (unlikely(IS_ERR(c2dev->dev))) {
+		ret = PTR_ERR(c2dev->dev);
 		goto error_device_create;
 	}
 	dev_set_drvdata(c2dev->dev, c2dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/cb710/core.c linux-libre-2.6.34-gnu1/drivers/misc/cb710/core.c
--- linux-libre-2.6.33-gnu1/drivers/misc/cb710/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/cb710/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,11 +9,11 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/idr.h>
 #include <linux/cb710.h>
+#include <linux/gfp.h>
 
 static DEFINE_IDA(cb710_ida);
 static DEFINE_SPINLOCK(cb710_ida_lock);
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/cb710/debug.c linux-libre-2.6.34-gnu1/drivers/misc/cb710/debug.c
--- linux-libre-2.6.33-gnu1/drivers/misc/cb710/debug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/cb710/debug.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
 #include <linux/cb710.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 
 #define CB710_REG_COUNT		0x80
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/cs5535-mfgpt.c linux-libre-2.6.34-gnu1/drivers/misc/cs5535-mfgpt.c
--- linux-libre-2.6.33-gnu1/drivers/misc/cs5535-mfgpt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/cs5535-mfgpt.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/cs5535.h>
+#include <linux/slab.h>
 
 #define DRV_NAME "cs5535-mfgpt"
 #define MFGPT_BAR 2
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/ds1682.c linux-libre-2.6.34-gnu1/drivers/misc/ds1682.c
--- linux-libre-2.6.33-gnu1/drivers/misc/ds1682.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/ds1682.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/string.h>
 #include <linux/list.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/eeprom/at24.c linux-libre-2.6.34-gnu1/drivers/misc/eeprom/at24.c
--- linux-libre-2.6.33-gnu1/drivers/misc/eeprom/at24.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/eeprom/at24.c	2010-05-16 17:17:36.000000000 -0400
@@ -505,6 +505,7 @@ static int at24_probe(struct i2c_client
 	 * Export the EEPROM bytes through sysfs, since that's convenient.
 	 * By default, only root should see the data (maybe passwords etc)
 	 */
+	sysfs_bin_attr_init(&at24->bin);
 	at24->bin.attr.name = "eeprom";
 	at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR;
 	at24->bin.read = at24_bin_read;
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/eeprom/at25.c linux-libre-2.6.34-gnu1/drivers/misc/eeprom/at25.c
--- linux-libre-2.6.33-gnu1/drivers/misc/eeprom/at25.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/eeprom/at25.c	2010-05-16 17:17:36.000000000 -0400
@@ -347,6 +347,7 @@ static int at25_probe(struct spi_device
 	 * that's sensitive for read and/or write, like ethernet addresses,
 	 * security codes, board-specific manufacturing calibrations, etc.
 	 */
+	sysfs_bin_attr_init(&at25->bin);
 	at25->bin.attr.name = "eeprom";
 	at25->bin.attr.mode = S_IRUSR;
 	at25->bin.read = at25_bin_read;
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/enclosure.c linux-libre-2.6.34-gnu1/drivers/misc/enclosure.c
--- linux-libre-2.6.33-gnu1/drivers/misc/enclosure.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/enclosure.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 static LIST_HEAD(container_list);
 static DEFINE_MUTEX(container_list_lock);
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/ep93xx_pwm.c linux-libre-2.6.34-gnu1/drivers/misc/ep93xx_pwm.c
--- linux-libre-2.6.33-gnu1/drivers/misc/ep93xx_pwm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/ep93xx_pwm.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/hpilo.c linux-libre-2.6.34-gnu1/drivers/misc/hpilo.c
--- linux-libre-2.6.33-gnu1/drivers/misc/hpilo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/hpilo.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/io.h>
 #include <linux/wait.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include "hpilo.h"
 
 static struct class *ilo_class;
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/ibmasm/command.c linux-libre-2.6.34-gnu1/drivers/misc/ibmasm/command.c
--- linux-libre-2.6.33-gnu1/drivers/misc/ibmasm/command.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/ibmasm/command.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "ibmasm.h"
 #include "lowlevel.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/ibmasm/event.c linux-libre-2.6.34-gnu1/drivers/misc/ibmasm/event.c
--- linux-libre-2.6.33-gnu1/drivers/misc/ibmasm/event.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/ibmasm/event.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "ibmasm.h"
 #include "lowlevel.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/ibmasm/ibmasmfs.c linux-libre-2.6.34-gnu1/drivers/misc/ibmasm/ibmasmfs.c
--- linux-libre-2.6.33-gnu1/drivers/misc/ibmasm/ibmasmfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/ibmasm/ibmasmfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -75,6 +75,7 @@
 
 #include <linux/fs.h>
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include "ibmasm.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/ibmasm/module.c linux-libre-2.6.34-gnu1/drivers/misc/ibmasm/module.c
--- linux-libre-2.6.33-gnu1/drivers/misc/ibmasm/module.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/ibmasm/module.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,6 +52,7 @@
 
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include "ibmasm.h"
 #include "lowlevel.h"
 #include "remote.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/ics932s401.c linux-libre-2.6.34-gnu1/drivers/misc/ics932s401.c
--- linux-libre-2.6.33-gnu1/drivers/misc/ics932s401.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/ics932s401.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x69, I2C_CLIENT_END };
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/ioc4.c linux-libre-2.6.34-gnu1/drivers/misc/ioc4.c
--- linux-libre-2.6.33-gnu1/drivers/misc/ioc4.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/ioc4.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include <linux/ioc4.h>
 #include <linux/ktime.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/time.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/debugfs.c linux-libre-2.6.34-gnu1/drivers/misc/iwmc3200top/debugfs.c
--- linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/debugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/iwmc3200top/debugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <linux/mmc/sdio_func.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/fw-download.c linux-libre-2.6.34-gnu1/drivers/misc/iwmc3200top/fw-download.c
--- linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/fw-download.c	2013-05-03 12:10:04.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/misc/iwmc3200top/fw-download.c	2013-05-03 09:49:35.000000000 -0400
@@ -26,6 +26,7 @@
 
 #include <linux/firmware.h>
 #include <linux/mmc/sdio_func.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #include "iwmc3200top.h"
@@ -43,15 +44,14 @@ static int iwmct_fw_parser_init(struct i
 	struct iwmct_parser *parser = &priv->parser;
 	struct iwmct_fw_hdr *fw_hdr = &parser->versions;
 
-	LOG_INFOEX(priv, INIT, "-->\n");
+	LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");
 
 	LOG_INFO(priv, FW_DOWNLOAD, "file_size=%zd\n", file_size);
 
 	parser->file = file;
 	parser->file_size = file_size;
 	parser->cur_pos = 0;
-	parser->buf = NULL;
-
+	parser->entry_point = 0;
 	parser->buf = kzalloc(block_size, GFP_KERNEL);
 	if (!parser->buf) {
 		LOG_ERROR(priv, FW_DOWNLOAD, "kzalloc error\n");
@@ -70,7 +70,7 @@ static int iwmct_fw_parser_init(struct i
 
 	parser->cur_pos += sizeof(struct iwmct_fw_hdr);
 
-	LOG_INFOEX(priv, INIT, "<--\n");
+	LOG_TRACE(priv, FW_DOWNLOAD, "<--\n");
 	return 0;
 }
 
@@ -113,7 +113,7 @@ static int iwmct_parse_next_section(stru
 	struct iwmct_dbg *dbg = &priv->dbg;
 	struct iwmct_fw_sec_hdr *sec_hdr;
 
-	LOG_INFOEX(priv, INIT, "-->\n");
+	LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");
 
 	while (parser->cur_pos + sizeof(struct iwmct_fw_sec_hdr)
 		<= parser->file_size) {
@@ -152,7 +152,7 @@ static int iwmct_parse_next_section(stru
 			"finished with section cur_pos=%zd\n", parser->cur_pos);
 	}
 
-	LOG_INFOEX(priv, INIT, "<--\n");
+	LOG_TRACE(priv, INIT, "<--\n");
 	return 0;
 }
 
@@ -167,7 +167,7 @@ static int iwmct_download_section(struct
 	int ret = 0;
 	u32 cmd = 0;
 
-	LOG_INFOEX(priv, INIT, "-->\n");
+	LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");
 	LOG_INFO(priv, FW_DOWNLOAD, "Download address 0x%x size 0x%zx\n",
 				addr, sec_size);
 
@@ -229,7 +229,7 @@ static int iwmct_download_section(struct
 		hdr->cmd = cpu_to_le32(cmd);
 		/* send it down */
 		/* TODO: add more proper sending and error checking */
-		ret = iwmct_tx(priv, 0, parser->buf, trans_size);
+		ret = iwmct_tx(priv, parser->buf, trans_size);
 		if (ret != 0) {
 			LOG_INFO(priv, FW_DOWNLOAD,
 				"iwmct_tx returned %d\n", ret);
@@ -251,7 +251,7 @@ static int iwmct_download_section(struct
 	if (sent < sec_size)
 		ret = -EINVAL;
 exit:
-	LOG_INFOEX(priv, INIT, "<--\n");
+	LOG_TRACE(priv, FW_DOWNLOAD, "<--\n");
 	return ret;
 }
 
@@ -262,7 +262,7 @@ static int iwmct_kick_fw(struct iwmct_pr
 	int ret;
 	u32 cmd;
 
-	LOG_INFOEX(priv, INIT, "-->\n");
+	LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");
 
 	memset(parser->buf, 0, parser->buf_size);
 	cmd = IWMC_CMD_SIGNATURE << CMD_HDR_SIGNATURE_POS;
@@ -281,11 +281,11 @@ static int iwmct_kick_fw(struct iwmct_pr
 	LOG_HEXDUMP(FW_DOWNLOAD, parser->buf, sizeof(*hdr));
 	/* send it down */
 	/* TODO: add more proper sending and error checking */
-	ret = iwmct_tx(priv, 0, parser->buf, IWMC_SDIO_BLK_SIZE);
+	ret = iwmct_tx(priv, parser->buf, IWMC_SDIO_BLK_SIZE);
 	if (ret)
 		LOG_INFO(priv, FW_DOWNLOAD, "iwmct_tx returned %d", ret);
 
-	LOG_INFOEX(priv, INIT, "<--\n");
+	LOG_TRACE(priv, FW_DOWNLOAD, "<--\n");
 	return 0;
 }
 
@@ -298,8 +298,16 @@ int iwmct_fw_load(struct iwmct_priv *pri
 	__le32 addr;
 	int ret;
 
-	/* clear parser struct */
-	memset(&priv->parser, 0, sizeof(struct iwmct_parser));
+
+	LOG_INFO(priv, FW_DOWNLOAD, "barker download request 0x%x is:\n",
+			priv->barker);
+	LOG_INFO(priv, FW_DOWNLOAD, "*******  Top FW %s requested ********\n",
+			(priv->barker & BARKER_DNLOAD_TOP_MSK) ? "was" : "not");
+	LOG_INFO(priv, FW_DOWNLOAD, "*******  GPS FW %s requested ********\n",
+			(priv->barker & BARKER_DNLOAD_GPS_MSK) ? "was" : "not");
+	LOG_INFO(priv, FW_DOWNLOAD, "*******  BT FW %s requested ********\n",
+			(priv->barker & BARKER_DNLOAD_BT_MSK) ? "was" : "not");
+
 
 	/* get the firmware */
 	ret = reject_firmware(&raw, fw_name, &priv->func->dev);
@@ -317,6 +325,7 @@ int iwmct_fw_load(struct iwmct_priv *pri
 
 	LOG_INFO(priv, FW_DOWNLOAD, "Read firmware '%s'\n", fw_name);
 
+	/* clear parser struct */
 	ret = iwmct_fw_parser_init(priv, raw->data, raw->size, priv->trans_len);
 	if (ret < 0) {
 		LOG_ERROR(priv, FW_DOWNLOAD,
@@ -324,7 +333,6 @@ int iwmct_fw_load(struct iwmct_priv *pri
 		goto exit;
 	}
 
-	/* checksum  */
 	if (!iwmct_checksum(priv)) {
 		LOG_ERROR(priv, FW_DOWNLOAD, "checksum error\n");
 		ret = -EINVAL;
@@ -333,23 +341,18 @@ int iwmct_fw_load(struct iwmct_priv *pri
 
 	/* download firmware to device */
 	while (iwmct_parse_next_section(priv, &pdata, &len, &addr)) {
-		if (iwmct_download_section(priv, pdata, len, addr)) {
+		ret = iwmct_download_section(priv, pdata, len, addr);
+		if (ret) {
 			LOG_ERROR(priv, FW_DOWNLOAD,
 				  "%s download section failed\n", fw_name);
-			ret = -EIO;
 			goto exit;
 		}
 	}
 
-	iwmct_kick_fw(priv, !!(priv->barker & BARKER_DNLOAD_JUMP_MSK));
+	ret = iwmct_kick_fw(priv, !!(priv->barker & BARKER_DNLOAD_JUMP_MSK));
 
 exit:
 	kfree(priv->parser.buf);
-
-	if (raw)
-		release_firmware(raw);
-
-	raw = NULL;
-
+	release_firmware(raw);
 	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/iwmc3200top.h linux-libre-2.6.34-gnu1/drivers/misc/iwmc3200top/iwmc3200top.h
--- linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/iwmc3200top.h	2013-05-03 12:10:04.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/misc/iwmc3200top/iwmc3200top.h	2013-05-03 09:49:35.000000000 -0400
@@ -196,9 +196,7 @@ struct iwmct_priv {
 	struct list_head read_req_list;
 };
 
-extern int iwmct_tx(struct iwmct_priv *priv, unsigned int addr,
-		void *src, int count);
-
+extern int iwmct_tx(struct iwmct_priv *priv, void *src, int count);
 extern int iwmct_fw_load(struct iwmct_priv *priv);
 
 extern void iwmct_dbg_init_params(struct iwmct_priv *drv);
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/log.c linux-libre-2.6.34-gnu1/drivers/misc/iwmc3200top/log.c
--- linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/log.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/iwmc3200top/log.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 
 #include <linux/kernel.h>
 #include <linux/mmc/sdio_func.h>
+#include <linux/slab.h>
 #include <linux/ctype.h>
 #include "fw-msg.h"
 #include "iwmc3200top.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/log.h linux-libre-2.6.34-gnu1/drivers/misc/iwmc3200top/log.h
--- linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/log.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/iwmc3200top/log.h	2010-05-16 17:17:36.000000000 -0400
@@ -37,13 +37,26 @@
 #define LOG_SEV_INFO			3
 #define LOG_SEV_INFOEX			4
 
-#define LOG_SEV_FILTER_ALL		\
-	(BIT(LOG_SEV_CRITICAL) |	\
-	 BIT(LOG_SEV_ERROR)    |	\
-	 BIT(LOG_SEV_WARNING)  | 	\
-	 BIT(LOG_SEV_INFO)     |	\
+/* Log levels not defined for FW */
+#define LOG_SEV_TRACE			5
+#define LOG_SEV_DUMP			6
+
+#define LOG_SEV_FW_FILTER_ALL		\
+	(BIT(LOG_SEV_CRITICAL)	|	\
+	 BIT(LOG_SEV_ERROR)	|	\
+	 BIT(LOG_SEV_WARNING)	| 	\
+	 BIT(LOG_SEV_INFO)	|	\
 	 BIT(LOG_SEV_INFOEX))
 
+#define LOG_SEV_FILTER_ALL		\
+	(BIT(LOG_SEV_CRITICAL)	|	\
+	 BIT(LOG_SEV_ERROR)	|	\
+	 BIT(LOG_SEV_WARNING)	| 	\
+	 BIT(LOG_SEV_INFO)	|	\
+	 BIT(LOG_SEV_INFOEX)	|	\
+	 BIT(LOG_SEV_TRACE)	|	\
+	 BIT(LOG_SEV_DUMP))
+
 /* log source */
 #define LOG_SRC_INIT			0
 #define LOG_SRC_DEBUGFS			1
@@ -104,16 +117,16 @@ do {									\
 			 __func__, __LINE__, ##args);			\
 } while (0)
 
-#define LOG_INFOEX(priv, src, fmt, args...)				\
+#define LOG_TRACE(priv, src, fmt, args...)				\
 do {									\
-	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_INFOEX))	\
+	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_TRACE))	\
 		dev_dbg(priv2dev(priv), "%s %d: " fmt,			\
 			 __func__, __LINE__, ##args);			\
 } while (0)
 
 #define LOG_HEXDUMP(src, ptr, len)					\
 do {									\
-	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_INFOEX))	\
+	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_DUMP))	\
 		print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE,	\
 				16, 1, ptr, len, false);		\
 } while (0)
@@ -142,7 +155,7 @@ ssize_t store_iwmct_log_level_fw(struct
 #define LOG_ERROR(priv, src, fmt, args...)
 #define LOG_WARNING(priv, src, fmt, args...)
 #define LOG_INFO(priv, src, fmt, args...)
-#define LOG_INFOEX(priv, src, fmt, args...)
+#define LOG_TRACE(priv, src, fmt, args...)
 #define LOG_HEXDUMP(src, ptr, len)
 
 static inline void iwmct_log_top_message(struct iwmct_priv *priv,
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/main.c linux-libre-2.6.34-gnu1/drivers/misc/iwmc3200top/main.c
--- linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/main.c	2013-05-03 12:10:06.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/misc/iwmc3200top/main.c	2013-05-03 09:49:37.000000000 -0400
@@ -25,6 +25,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/debugfs.h>
@@ -49,6 +50,20 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR(DRIVER_COPYRIGHT);
 /*(DEBLOBBED)*/
 
+
+static inline int __iwmct_tx(struct iwmct_priv *priv, void *src, int count)
+{
+	return sdio_memcpy_toio(priv->func, IWMC_SDIO_DATA_ADDR, src, count);
+
+}
+int iwmct_tx(struct iwmct_priv *priv, void *src, int count)
+{
+	int ret;
+	sdio_claim_host(priv->func);
+	ret =  __iwmct_tx(priv, src, count);
+	sdio_release_host(priv->func);
+	return ret;
+}
 /*
  * This workers main task is to wait for OP_OPR_ALIVE
  * from TOP FW until ALIVE_MSG_TIMOUT timeout is elapsed.
@@ -66,7 +81,7 @@ static void iwmct_rescan_worker(struct w
 
 	ret = bus_rescan_devices(priv->func->dev.bus);
 	if (ret < 0)
-		LOG_INFO(priv, FW_DOWNLOAD, "bus_rescan_devices FAILED!!!\n");
+		LOG_INFO(priv, INIT, "bus_rescan_devices FAILED!!!\n");
 }
 
 static void op_top_message(struct iwmct_priv *priv, struct top_msg *msg)
@@ -137,7 +152,7 @@ int iwmct_send_hcmd(struct iwmct_priv *p
 	int ret;
 	u8 *buf;
 
-	LOG_INFOEX(priv, FW_MSG, "Sending hcmd:\n");
+	LOG_TRACE(priv, FW_MSG, "Sending hcmd:\n");
 
 	/* add padding to 256 for IWMC */
 	((struct top_msg *)cmd)->hdr.flags |= CMD_FLAG_PADDING_256;
@@ -158,27 +173,12 @@ int iwmct_send_hcmd(struct iwmct_priv *p
 	}
 
 	memcpy(buf, cmd, len);
-
-	sdio_claim_host(priv->func);
-	ret = sdio_memcpy_toio(priv->func, IWMC_SDIO_DATA_ADDR, buf,
-			       FW_HCMD_BLOCK_SIZE);
-	sdio_release_host(priv->func);
+	ret = iwmct_tx(priv, buf, FW_HCMD_BLOCK_SIZE);
 
 	kfree(buf);
 	return ret;
 }
 
-int iwmct_tx(struct iwmct_priv *priv, unsigned int addr,
-	void *src, int count)
-{
-	int ret;
-
-	sdio_claim_host(priv->func);
-	ret = sdio_memcpy_toio(priv->func, addr, src, count);
-	sdio_release_host(priv->func);
-
-	return ret;
-}
 
 static void iwmct_irq_read_worker(struct work_struct *ws)
 {
@@ -192,7 +192,7 @@ static void iwmct_irq_read_worker(struct
 
 	priv = container_of(ws, struct iwmct_priv, isr_worker);
 
-	LOG_INFO(priv, IRQ, "enter iwmct_irq_read_worker %p\n", ws);
+	LOG_TRACE(priv, IRQ, "enter iwmct_irq_read_worker %p\n", ws);
 
 	/* --------------------- Handshake with device -------------------- */
 	sdio_claim_host(priv->func);
@@ -273,8 +273,7 @@ static void iwmct_irq_read_worker(struct
 
 		if (barker & BARKER_DNLOAD_SYNC_MSK) {
 			/* Send the same barker back */
-			ret = sdio_memcpy_toio(priv->func, IWMC_SDIO_DATA_ADDR,
-					       buf, iosize);
+			ret = __iwmct_tx(priv, buf, iosize);
 			if (ret) {
 				LOG_ERROR(priv, IRQ,
 					 "error %d echoing barker\n", ret);
@@ -292,15 +291,6 @@ static void iwmct_irq_read_worker(struct
 
 	sdio_release_host(priv->func);
 
-
-	LOG_INFO(priv, IRQ, "barker download request 0x%x is:\n", priv->barker);
-	LOG_INFO(priv, IRQ, "*******  Top FW %s requested ********\n",
-			(priv->barker & BARKER_DNLOAD_TOP_MSK) ? "was" : "not");
-	LOG_INFO(priv, IRQ, "*******  GPS FW %s requested ********\n",
-			(priv->barker & BARKER_DNLOAD_GPS_MSK) ? "was" : "not");
-	LOG_INFO(priv, IRQ, "*******  BT FW %s requested ********\n",
-			(priv->barker & BARKER_DNLOAD_BT_MSK) ? "was" : "not");
-
 	if (priv->dbg.fw_download)
 		iwmct_fw_load(priv);
 	else
@@ -312,7 +302,7 @@ exit_release:
 	sdio_release_host(priv->func);
 exit:
 	kfree(buf);
-	LOG_INFO(priv, IRQ, "exit iwmct_irq_read_worker\n");
+	LOG_TRACE(priv, IRQ, "exit iwmct_irq_read_worker\n");
 }
 
 static void iwmct_irq(struct sdio_func *func)
@@ -325,12 +315,12 @@ static void iwmct_irq(struct sdio_func *
 
 	priv = sdio_get_drvdata(func);
 
-	LOG_INFO(priv, IRQ, "enter iwmct_irq\n");
+	LOG_TRACE(priv, IRQ, "enter iwmct_irq\n");
 
 	/* read the function's status register */
 	val = sdio_readb(func, IWMC_SDIO_INTR_STATUS_ADDR, &ret);
 
-	LOG_INFO(priv, IRQ, "iir value = %d, ret=%d\n", val, ret);
+	LOG_TRACE(priv, IRQ, "iir value = %d, ret=%d\n", val, ret);
 
 	if (!val) {
 		LOG_ERROR(priv, IRQ, "iir = 0, exiting ISR\n");
@@ -372,7 +362,7 @@ static void iwmct_irq(struct sdio_func *
 
 	queue_work(priv->wq, &priv->isr_worker);
 
-	LOG_INFO(priv, IRQ, "exit iwmct_irq\n");
+	LOG_TRACE(priv, IRQ, "exit iwmct_irq\n");
 
 	return;
 
@@ -608,8 +598,6 @@ static void iwmct_remove(struct sdio_fun
 	struct iwmct_work_struct *read_req;
 	struct iwmct_priv *priv = sdio_get_drvdata(func);
 
-	priv = sdio_get_drvdata(func);
-
 	LOG_INFO(priv, INIT, "enter\n");
 
 	sdio_claim_host(func);
@@ -660,7 +648,7 @@ static int __init iwmct_init(void)
 
 	/* Default log filter settings */
 	iwmct_log_set_filter(LOG_SRC_ALL, LOG_SEV_FILTER_RUNTIME);
-	iwmct_log_set_filter(LOG_SRC_FW_MSG, LOG_SEV_FILTER_ALL);
+	iwmct_log_set_filter(LOG_SRC_FW_MSG, LOG_SEV_FW_FILTER_ALL);
 	iwmct_log_set_fw_filter(LOG_SRC_ALL, FW_LOG_SEV_FILTER_RUNTIME);
 
 	rc = sdio_register_driver(&iwmct_driver);
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/Kconfig linux-libre-2.6.34-gnu1/drivers/misc/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/misc/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -212,6 +212,15 @@ config CS5535_MFGPT_DEFAULT_IRQ
 	  want to use a different IRQ by default.  This is here for
 	  architectures to set as necessary.
 
+config CS5535_CLOCK_EVENT_SRC
+	tristate "CS5535/CS5536 high-res timer (MFGPT) events"
+	depends on GENERIC_TIME && GENERIC_CLOCKEVENTS && CS5535_MFGPT
+	help
+	  This driver provides a clock event source based on the MFGPT
+	  timer(s) in the CS5535 and CS5536 companion chips.
+	  MFGPTs have a better resolution and max interval than the
+	  generic PIT, and are suitable for use as high-res timers.
+
 config HP_ILO
 	tristate "Channel interface driver for HP iLO/iLO2 processor"
 	depends on PCI
@@ -259,6 +268,16 @@ config ISL29003
 	  This driver can also be built as a module.  If so, the module
 	  will be called isl29003.
 
+config SENSORS_TSL2550
+	tristate "Taos TSL2550 ambient light sensor"
+	depends on I2C && SYSFS
+	help
+	  If you say yes here you get support for the Taos TSL2550
+	  ambient light sensor.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called tsl2550.
+
 config EP93XX_PWM
 	tristate "EP93xx PWM support"
 	depends on ARCH_EP93XX
@@ -292,6 +311,22 @@ config TI_DAC7512
 	  This driver can also be built as a module. If so, the module
 	  will be calles ti_dac7512.
 
+config VMWARE_BALLOON
+	tristate "VMware Balloon Driver"
+	depends on X86
+	help
+	  This is VMware physical memory management driver which acts
+	  like a "balloon" that can be inflated to reclaim physical pages
+	  by reserving them in the guest and invalidating them in the
+	  monitor, freeing up the underlying machine pages so they can
+	  be allocated to other guests. The balloon can also be deflated
+	  to allow the guest to use more physical memory.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called vmware_balloon.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/kgdbts.c linux-libre-2.6.34-gnu1/drivers/misc/kgdbts.c
--- linux-libre-2.6.33-gnu1/drivers/misc/kgdbts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/kgdbts.c	2010-05-16 17:17:36.000000000 -0400
@@ -295,6 +295,10 @@ static int check_and_rewind_pc(char *put
 	/* On x86 a breakpoint stop requires it to be decremented */
 	if (addr + 1 == kgdbts_regs.ip)
 		offset = -1;
+#elif defined(CONFIG_SUPERH)
+	/* On SUPERH a breakpoint stop requires it to be decremented */
+	if (addr + 2 == kgdbts_regs.pc)
+		offset = -2;
 #endif
 	if (strcmp(arg, "silent") &&
 		instruction_pointer(&kgdbts_regs) + offset != addr) {
@@ -305,6 +309,8 @@ static int check_and_rewind_pc(char *put
 #ifdef CONFIG_X86
 	/* On x86 adjust the instruction pointer if needed */
 	kgdbts_regs.ip += offset;
+#elif defined(CONFIG_SUPERH)
+	kgdbts_regs.pc += offset;
 #endif
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/lkdtm.c linux-libre-2.6.34-gnu1/drivers/misc/lkdtm.c
--- linux-libre-2.6.33-gnu1/drivers/misc/lkdtm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/lkdtm.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,21 +26,9 @@
  * It is adapted from the Linux Kernel Dump Test Tool by
  * Fernando Luis Vazquez Cao <http://lkdtt.sourceforge.net>
  *
- * Usage :  insmod lkdtm.ko [recur_count={>0}] cpoint_name=<> cpoint_type=<>
- *							[cpoint_count={>0}]
- *
- * recur_count : Recursion level for the stack overflow test. Default is 10.
- *
- * cpoint_name : Crash point where the kernel is to be crashed. It can be
- *		 one of INT_HARDWARE_ENTRY, INT_HW_IRQ_EN, INT_TASKLET_ENTRY,
- *		 FS_DEVRW, MEM_SWAPOUT, TIMERADD, SCSI_DISPATCH_CMD,
- *		 IDE_CORE_CP
- *
- * cpoint_type : Indicates the action to be taken on hitting the crash point.
- *		 It can be one of PANIC, BUG, EXCEPTION, LOOP, OVERFLOW
+ * Debugfs support added by Simon Kagstrom <simon.kagstrom@netinsight.net>
  *
- * cpoint_count : Indicates the number of times the crash point is to be hit
- *		  to trigger an action. The default is 10.
+ * See Documentation/fault-injection/provoke-crashes.txt for instructions
  */
 
 #include <linux/kernel.h>
@@ -52,14 +40,14 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/hrtimer.h>
+#include <linux/slab.h>
 #include <scsi/scsi_cmnd.h>
+#include <linux/debugfs.h>
 
 #ifdef CONFIG_IDE
 #include <linux/ide.h>
 #endif
 
-#define NUM_CPOINTS 8
-#define NUM_CPOINT_TYPES 5
 #define DEFAULT_COUNT 10
 #define REC_NUM_DEFAULT 10
 
@@ -72,7 +60,8 @@ enum cname {
 	MEM_SWAPOUT,
 	TIMERADD,
 	SCSI_DISPATCH_CMD,
-	IDE_CORE_CP
+	IDE_CORE_CP,
+	DIRECT,
 };
 
 enum ctype {
@@ -81,7 +70,11 @@ enum ctype {
 	BUG,
 	EXCEPTION,
 	LOOP,
-	OVERFLOW
+	OVERFLOW,
+	CORRUPT_STACK,
+	UNALIGNED_LOAD_STORE_WRITE,
+	OVERWRITE_ALLOCATION,
+	WRITE_AFTER_FREE,
 };
 
 static char* cp_name[] = {
@@ -92,7 +85,8 @@ static char* cp_name[] = {
 	"MEM_SWAPOUT",
 	"TIMERADD",
 	"SCSI_DISPATCH_CMD",
-	"IDE_CORE_CP"
+	"IDE_CORE_CP",
+	"DIRECT",
 };
 
 static char* cp_type[] = {
@@ -100,7 +94,11 @@ static char* cp_type[] = {
 	"BUG",
 	"EXCEPTION",
 	"LOOP",
-	"OVERFLOW"
+	"OVERFLOW",
+	"CORRUPT_STACK",
+	"UNALIGNED_LOAD_STORE_WRITE",
+	"OVERWRITE_ALLOCATION",
+	"WRITE_AFTER_FREE",
 };
 
 static struct jprobe lkdtm;
@@ -193,34 +191,66 @@ int jp_generic_ide_ioctl(ide_drive_t *dr
 }
 #endif
 
+/* Return the crashpoint number or NONE if the name is invalid */
+static enum ctype parse_cp_type(const char *what, size_t count)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(cp_type); i++) {
+		if (!strcmp(what, cp_type[i]))
+			return i + 1;
+	}
+
+	return NONE;
+}
+
+static const char *cp_type_to_str(enum ctype type)
+{
+	if (type == NONE || type < 0 || type > ARRAY_SIZE(cp_type))
+		return "None";
+
+	return cp_type[type - 1];
+}
+
+static const char *cp_name_to_str(enum cname name)
+{
+	if (name == INVALID || name < 0 || name > ARRAY_SIZE(cp_name))
+		return "INVALID";
+
+	return cp_name[name - 1];
+}
+
+
 static int lkdtm_parse_commandline(void)
 {
 	int i;
 
-	if (cpoint_name == NULL || cpoint_type == NULL ||
-					cpoint_count < 1 || recur_count < 1)
+	if (cpoint_count < 1 || recur_count < 1)
 		return -EINVAL;
 
-	for (i = 0; i < NUM_CPOINTS; ++i) {
+	count = cpoint_count;
+
+	/* No special parameters */
+	if (!cpoint_type && !cpoint_name)
+		return 0;
+
+	/* Neither or both of these need to be set */
+	if (!cpoint_type || !cpoint_name)
+		return -EINVAL;
+
+	cptype = parse_cp_type(cpoint_type, strlen(cpoint_type));
+	if (cptype == NONE)
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(cp_name); i++) {
 		if (!strcmp(cpoint_name, cp_name[i])) {
 			cpoint = i + 1;
-			break;
-		}
-	}
-
-	for (i = 0; i < NUM_CPOINT_TYPES; ++i) {
-		if (!strcmp(cpoint_type, cp_type[i])) {
-			cptype = i + 1;
-			break;
+			return 0;
 		}
 	}
 
-	if (cpoint == INVALID || cptype == NONE)
-                return -EINVAL;
-
-	count = cpoint_count;
-
-	return 0;
+	/* Could not find a valid crash point */
+	return -EINVAL;
 }
 
 static int recursive_loop(int a)
@@ -235,53 +265,92 @@ static int recursive_loop(int a)
         	return recursive_loop(a);
 }
 
-void lkdtm_handler(void)
+static void lkdtm_do_action(enum ctype which)
 {
-	printk(KERN_INFO "lkdtm : Crash point %s of type %s hit\n",
-					 cpoint_name, cpoint_type);
-	--count;
+	switch (which) {
+	case PANIC:
+		panic("dumptest");
+		break;
+	case BUG:
+		BUG();
+		break;
+	case EXCEPTION:
+		*((int *) 0) = 0;
+		break;
+	case LOOP:
+		for (;;)
+			;
+		break;
+	case OVERFLOW:
+		(void) recursive_loop(0);
+		break;
+	case CORRUPT_STACK: {
+		volatile u32 data[8];
+		volatile u32 *p = data;
+
+		p[12] = 0x12345678;
+		break;
+	}
+	case UNALIGNED_LOAD_STORE_WRITE: {
+		static u8 data[5] __attribute__((aligned(4))) = {1, 2,
+				3, 4, 5};
+		u32 *p;
+		u32 val = 0x12345678;
+
+		p = (u32 *)(data + 1);
+		if (*p == 0)
+			val = 0x87654321;
+		*p = val;
+		 break;
+	}
+	case OVERWRITE_ALLOCATION: {
+		size_t len = 1020;
+		u32 *data = kmalloc(len, GFP_KERNEL);
+
+		data[1024 / sizeof(u32)] = 0x12345678;
+		kfree(data);
+		break;
+	}
+	case WRITE_AFTER_FREE: {
+		size_t len = 1024;
+		u32 *data = kmalloc(len, GFP_KERNEL);
+
+		kfree(data);
+		schedule();
+		memset(data, 0x78, len);
+		break;
+	}
+	case NONE:
+	default:
+		break;
+	}
+
+}
+
+static void lkdtm_handler(void)
+{
+	count--;
+	printk(KERN_INFO "lkdtm: Crash point %s of type %s hit, trigger in %d rounds\n",
+			cp_name_to_str(cpoint), cp_type_to_str(cptype), count);
 
 	if (count == 0) {
-		switch (cptype) {
-		case NONE:
-			break;
-		case PANIC:
-			printk(KERN_INFO "lkdtm : PANIC\n");
-			panic("dumptest");
-			break;
-		case BUG:
-			printk(KERN_INFO "lkdtm : BUG\n");
-			BUG();
-			break;
-		case EXCEPTION:
-			printk(KERN_INFO "lkdtm : EXCEPTION\n");
-			*((int *) 0) = 0;
-			break;
-		case LOOP:
-			printk(KERN_INFO "lkdtm : LOOP\n");
-			for (;;);
-			break;
-		case OVERFLOW:
-			printk(KERN_INFO "lkdtm : OVERFLOW\n");
-			(void) recursive_loop(0);
-			break;
-		default:
-			break;
-		}
+		lkdtm_do_action(cptype);
 		count = cpoint_count;
 	}
 }
 
-static int __init lkdtm_module_init(void)
+static int lkdtm_register_cpoint(enum cname which)
 {
 	int ret;
 
-	if (lkdtm_parse_commandline() == -EINVAL) {
-		printk(KERN_INFO "lkdtm : Invalid command\n");
-		return -EINVAL;
-	}
+	cpoint = INVALID;
+	if (lkdtm.entry != NULL)
+		unregister_jprobe(&lkdtm);
 
-	switch (cpoint) {
+	switch (which) {
+	case DIRECT:
+		lkdtm_do_action(cptype);
+		return 0;
 	case INT_HARDWARE_ENTRY:
 		lkdtm.kp.symbol_name = "do_IRQ";
 		lkdtm.entry = (kprobe_opcode_t*) jp_do_irq;
@@ -315,28 +384,268 @@ static int __init lkdtm_module_init(void
 		lkdtm.kp.symbol_name = "generic_ide_ioctl";
 		lkdtm.entry = (kprobe_opcode_t*) jp_generic_ide_ioctl;
 #else
-		printk(KERN_INFO "lkdtm : Crash point not available\n");
+		printk(KERN_INFO "lkdtm: Crash point not available\n");
+		return -EINVAL;
 #endif
 		break;
 	default:
-		printk(KERN_INFO "lkdtm : Invalid Crash Point\n");
-		break;
+		printk(KERN_INFO "lkdtm: Invalid Crash Point\n");
+		return -EINVAL;
 	}
 
+	cpoint = which;
 	if ((ret = register_jprobe(&lkdtm)) < 0) {
-                printk(KERN_INFO "lkdtm : Couldn't register jprobe\n");
-                return ret;
+		printk(KERN_INFO "lkdtm: Couldn't register jprobe\n");
+		cpoint = INVALID;
+	}
+
+	return ret;
+}
+
+static ssize_t do_register_entry(enum cname which, struct file *f,
+		const char __user *user_buf, size_t count, loff_t *off)
+{
+	char *buf;
+	int err;
+
+	if (count >= PAGE_SIZE)
+		return -EINVAL;
+
+	buf = (char *)__get_free_page(GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	if (copy_from_user(buf, user_buf, count)) {
+		free_page((unsigned long) buf);
+		return -EFAULT;
+	}
+	/* NULL-terminate and remove enter */
+	buf[count] = '\0';
+	strim(buf);
+
+	cptype = parse_cp_type(buf, count);
+	free_page((unsigned long) buf);
+
+	if (cptype == NONE)
+		return -EINVAL;
+
+	err = lkdtm_register_cpoint(which);
+	if (err < 0)
+		return err;
+
+	*off += count;
+
+	return count;
+}
+
+/* Generic read callback that just prints out the available crash types */
+static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf,
+		size_t count, loff_t *off)
+{
+	char *buf;
+	int i, n, out;
+
+	buf = (char *)__get_free_page(GFP_KERNEL);
+
+	n = snprintf(buf, PAGE_SIZE, "Available crash types:\n");
+	for (i = 0; i < ARRAY_SIZE(cp_type); i++)
+		n += snprintf(buf + n, PAGE_SIZE - n, "%s\n", cp_type[i]);
+	buf[n] = '\0';
+
+	out = simple_read_from_buffer(user_buf, count, off,
+				      buf, n);
+	free_page((unsigned long) buf);
+
+	return out;
+}
+
+static int lkdtm_debugfs_open(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+
+static ssize_t int_hardware_entry(struct file *f, const char __user *buf,
+		size_t count, loff_t *off)
+{
+	return do_register_entry(INT_HARDWARE_ENTRY, f, buf, count, off);
+}
+
+static ssize_t int_hw_irq_en(struct file *f, const char __user *buf,
+		size_t count, loff_t *off)
+{
+	return do_register_entry(INT_HW_IRQ_EN, f, buf, count, off);
+}
+
+static ssize_t int_tasklet_entry(struct file *f, const char __user *buf,
+		size_t count, loff_t *off)
+{
+	return do_register_entry(INT_TASKLET_ENTRY, f, buf, count, off);
+}
+
+static ssize_t fs_devrw_entry(struct file *f, const char __user *buf,
+		size_t count, loff_t *off)
+{
+	return do_register_entry(FS_DEVRW, f, buf, count, off);
+}
+
+static ssize_t mem_swapout_entry(struct file *f, const char __user *buf,
+		size_t count, loff_t *off)
+{
+	return do_register_entry(MEM_SWAPOUT, f, buf, count, off);
+}
+
+static ssize_t timeradd_entry(struct file *f, const char __user *buf,
+		size_t count, loff_t *off)
+{
+	return do_register_entry(TIMERADD, f, buf, count, off);
+}
+
+static ssize_t scsi_dispatch_cmd_entry(struct file *f,
+		const char __user *buf, size_t count, loff_t *off)
+{
+	return do_register_entry(SCSI_DISPATCH_CMD, f, buf, count, off);
+}
+
+static ssize_t ide_core_cp_entry(struct file *f, const char __user *buf,
+		size_t count, loff_t *off)
+{
+	return do_register_entry(IDE_CORE_CP, f, buf, count, off);
+}
+
+/* Special entry to just crash directly. Available without KPROBEs */
+static ssize_t direct_entry(struct file *f, const char __user *user_buf,
+		size_t count, loff_t *off)
+{
+	enum ctype type;
+	char *buf;
+
+	if (count >= PAGE_SIZE)
+		return -EINVAL;
+	if (count < 1)
+		return -EINVAL;
+
+	buf = (char *)__get_free_page(GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	if (copy_from_user(buf, user_buf, count)) {
+		free_page((unsigned long) buf);
+		return -EFAULT;
+	}
+	/* NULL-terminate and remove enter */
+	buf[count] = '\0';
+	strim(buf);
+
+	type = parse_cp_type(buf, count);
+	free_page((unsigned long) buf);
+	if (type == NONE)
+		return -EINVAL;
+
+	printk(KERN_INFO "lkdtm: Performing direct entry %s\n",
+			cp_type_to_str(type));
+	lkdtm_do_action(type);
+	*off += count;
+
+	return count;
+}
+
+struct crash_entry {
+	const char *name;
+	const struct file_operations fops;
+};
+
+static const struct crash_entry crash_entries[] = {
+	{"DIRECT", {.read = lkdtm_debugfs_read,
+			.open = lkdtm_debugfs_open,
+			.write = direct_entry} },
+	{"INT_HARDWARE_ENTRY", {.read = lkdtm_debugfs_read,
+			.open = lkdtm_debugfs_open,
+			.write = int_hardware_entry} },
+	{"INT_HW_IRQ_EN", {.read = lkdtm_debugfs_read,
+			.open = lkdtm_debugfs_open,
+			.write = int_hw_irq_en} },
+	{"INT_TASKLET_ENTRY", {.read = lkdtm_debugfs_read,
+			.open = lkdtm_debugfs_open,
+			.write = int_tasklet_entry} },
+	{"FS_DEVRW", {.read = lkdtm_debugfs_read,
+			.open = lkdtm_debugfs_open,
+			.write = fs_devrw_entry} },
+	{"MEM_SWAPOUT", {.read = lkdtm_debugfs_read,
+			.open = lkdtm_debugfs_open,
+			.write = mem_swapout_entry} },
+	{"TIMERADD", {.read = lkdtm_debugfs_read,
+			.open = lkdtm_debugfs_open,
+			.write = timeradd_entry} },
+	{"SCSI_DISPATCH_CMD", {.read = lkdtm_debugfs_read,
+			.open = lkdtm_debugfs_open,
+			.write = scsi_dispatch_cmd_entry} },
+	{"IDE_CORE_CP",	{.read = lkdtm_debugfs_read,
+			.open = lkdtm_debugfs_open,
+			.write = ide_core_cp_entry} },
+};
+
+static struct dentry *lkdtm_debugfs_root;
+
+static int __init lkdtm_module_init(void)
+{
+	int ret = -EINVAL;
+	int n_debugfs_entries = 1; /* Assume only the direct entry */
+	int i;
+
+	/* Register debugfs interface */
+	lkdtm_debugfs_root = debugfs_create_dir("provoke-crash", NULL);
+	if (!lkdtm_debugfs_root) {
+		printk(KERN_ERR "lkdtm: creating root dir failed\n");
+		return -ENODEV;
+	}
+
+#ifdef CONFIG_KPROBES
+	n_debugfs_entries = ARRAY_SIZE(crash_entries);
+#endif
+
+	for (i = 0; i < n_debugfs_entries; i++) {
+		const struct crash_entry *cur = &crash_entries[i];
+		struct dentry *de;
+
+		de = debugfs_create_file(cur->name, 0644, lkdtm_debugfs_root,
+				NULL, &cur->fops);
+		if (de == NULL) {
+			printk(KERN_ERR "lkdtm: could not create %s\n",
+					cur->name);
+			goto out_err;
+		}
+	}
+
+	if (lkdtm_parse_commandline() == -EINVAL) {
+		printk(KERN_INFO "lkdtm: Invalid command\n");
+		goto out_err;
+	}
+
+	if (cpoint != INVALID && cptype != NONE) {
+		ret = lkdtm_register_cpoint(cpoint);
+		if (ret < 0) {
+			printk(KERN_INFO "lkdtm: Invalid crash point %d\n",
+					cpoint);
+			goto out_err;
+		}
+		printk(KERN_INFO "lkdtm: Crash point %s of type %s registered\n",
+				cpoint_name, cpoint_type);
+	} else {
+		printk(KERN_INFO "lkdtm: No crash points registered, enable through debugfs\n");
 	}
 
-	printk(KERN_INFO "lkdtm : Crash point %s of type %s registered\n",
-						cpoint_name, cpoint_type);
 	return 0;
+
+out_err:
+	debugfs_remove_recursive(lkdtm_debugfs_root);
+	return ret;
 }
 
 static void __exit lkdtm_module_exit(void)
 {
-        unregister_jprobe(&lkdtm);
-        printk(KERN_INFO "lkdtm : Crash point unregistered\n");
+	debugfs_remove_recursive(lkdtm_debugfs_root);
+
+	unregister_jprobe(&lkdtm);
+	printk(KERN_INFO "lkdtm: Crash point unregistered\n");
 }
 
 module_init(lkdtm_module_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/Makefile linux-libre-2.6.34-gnu1/drivers/misc/Makefile
--- linux-libre-2.6.33-gnu1/drivers/misc/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@ obj-$(CONFIG_SGI_GRU)		+= sgi-gru/
 obj-$(CONFIG_CS5535_MFGPT)	+= cs5535-mfgpt.o
 obj-$(CONFIG_HP_ILO)		+= hpilo.o
 obj-$(CONFIG_ISL29003)		+= isl29003.o
+obj-$(CONFIG_SENSORS_TSL2550)	+= tsl2550.o
 obj-$(CONFIG_EP93XX_PWM)	+= ep93xx_pwm.o
 obj-$(CONFIG_DS1682)		+= ds1682.o
 obj-$(CONFIG_TI_DAC7512)	+= ti_dac7512.o
@@ -28,3 +29,4 @@ obj-$(CONFIG_C2PORT)		+= c2port/
 obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
 obj-y				+= eeprom/
 obj-y				+= cb710/
+obj-$(CONFIG_VMWARE_BALLOON)	+= vmware_balloon.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/phantom.c linux-libre-2.6.34-gnu1/drivers/misc/phantom.c
--- linux-libre-2.6.33-gnu1/drivers/misc/phantom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/phantom.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/poll.h>
 #include <linux/interrupt.h>
 #include <linux/cdev.h>
+#include <linux/slab.h>
 #include <linux/phantom.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
@@ -497,12 +498,7 @@ static struct pci_driver phantom_pci_dri
 	.resume = phantom_resume
 };
 
-static ssize_t phantom_show_version(struct class *cls, char *buf)
-{
-	return sprintf(buf, PHANTOM_VERSION "\n");
-}
-
-static CLASS_ATTR(version, 0444, phantom_show_version, NULL);
+static CLASS_ATTR_STRING(version, 0444, PHANTOM_VERSION);
 
 static int __init phantom_init(void)
 {
@@ -515,7 +511,7 @@ static int __init phantom_init(void)
 		printk(KERN_ERR "phantom: can't register phantom class\n");
 		goto err;
 	}
-	retval = class_create_file(phantom_class, &class_attr_version);
+	retval = class_create_file(phantom_class, &class_attr_version.attr);
 	if (retval) {
 		printk(KERN_ERR "phantom: can't create sysfs version file\n");
 		goto err_class;
@@ -541,7 +537,7 @@ static int __init phantom_init(void)
 err_unchr:
 	unregister_chrdev_region(dev, PHANTOM_MAX_MINORS);
 err_attr:
-	class_remove_file(phantom_class, &class_attr_version);
+	class_remove_file(phantom_class, &class_attr_version.attr);
 err_class:
 	class_destroy(phantom_class);
 err:
@@ -554,7 +550,7 @@ static void __exit phantom_exit(void)
 
 	unregister_chrdev_region(MKDEV(phantom_major, 0), PHANTOM_MAX_MINORS);
 
-	class_remove_file(phantom_class, &class_attr_version);
+	class_remove_file(phantom_class, &class_attr_version.attr);
 	class_destroy(phantom_class);
 
 	pr_debug("phantom: module successfully removed\n");
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grutables.h linux-libre-2.6.34-gnu1/drivers/misc/sgi-gru/grutables.h
--- linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grutables.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/sgi-gru/grutables.h	2010-05-16 17:17:36.000000000 -0400
@@ -516,8 +516,7 @@ struct gru_blade_state {
 
 /* Scan all active GRUs in a GRU bitmap */
 #define for_each_gru_in_bitmap(gid, map)				\
-	for ((gid) = find_first_bit((map), GRU_MAX_GRUS); (gid) < GRU_MAX_GRUS;\
-		(gid)++, (gid) = find_next_bit((map), GRU_MAX_GRUS, (gid)))
+	for_each_set_bit((gid), (map), GRU_MAX_GRUS)
 
 /* Scan all active GRUs on a specific blade */
 #define for_each_gru_on_blade(gru, nid, i)				\
@@ -536,23 +535,17 @@ struct gru_blade_state {
 
 /* Scan each CBR whose bit is set in a TFM (or copy of) */
 #define for_each_cbr_in_tfm(i, map)					\
-	for ((i) = find_first_bit(map, GRU_NUM_CBE);			\
-			(i) < GRU_NUM_CBE;				\
-			(i)++, (i) = find_next_bit(map, GRU_NUM_CBE, i))
+	for_each_set_bit((i), (map), GRU_NUM_CBE)
 
 /* Scan each CBR in a CBR bitmap. Note: multiple CBRs in an allocation unit */
 #define for_each_cbr_in_allocation_map(i, map, k)			\
-	for ((k) = find_first_bit(map, GRU_CBR_AU); (k) < GRU_CBR_AU;	\
-			(k) = find_next_bit(map, GRU_CBR_AU, (k) + 1)) 	\
+	for_each_set_bit((k), (map), GRU_CBR_AU)			\
 		for ((i) = (k)*GRU_CBR_AU_SIZE;				\
 				(i) < ((k) + 1) * GRU_CBR_AU_SIZE; (i)++)
 
 /* Scan each DSR in a DSR bitmap. Note: multiple DSRs in an allocation unit */
 #define for_each_dsr_in_allocation_map(i, map, k)			\
-	for ((k) = find_first_bit((const unsigned long *)map, GRU_DSR_AU);\
-			(k) < GRU_DSR_AU;				\
-			(k) = find_next_bit((const unsigned long *)map,	\
-					  GRU_DSR_AU, (k) + 1))		\
+	for_each_set_bit((k), (const unsigned long *)(map), GRU_DSR_AU)	\
 		for ((i) = (k) * GRU_DSR_AU_CL;				\
 				(i) < ((k) + 1) * GRU_DSR_AU_CL; (i)++)
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpc_main.c linux-libre-2.6.34-gnu1/drivers/misc/sgi-xp/xpc_main.c
--- linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpc_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/sgi-xp/xpc_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/device.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpc_partition.c linux-libre-2.6.34-gnu1/drivers/misc/sgi-xp/xpc_partition.c
--- linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpc_partition.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/sgi-xp/xpc_partition.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 
 #include <linux/device.h>
 #include <linux/hardirq.h>
+#include <linux/slab.h>
 #include "xpc.h"
 #include <asm/uv/uv_hub.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpc_sn2.c linux-libre-2.6.34-gnu1/drivers/misc/sgi-xp/xpc_sn2.c
--- linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpc_sn2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/sgi-xp/xpc_sn2.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/uncached.h>
 #include <asm/sn/mspec.h>
 #include <asm/sn/sn_sal.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpc_uv.c linux-libre-2.6.34-gnu1/drivers/misc/sgi-xp/xpc_uv.c
--- linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpc_uv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/sgi-xp/xpc_uv.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <asm/uv/uv_hub.h>
 #if defined CONFIG_X86_64
 #include <asm/uv/bios.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpnet.c linux-libre-2.6.34-gnu1/drivers/misc/sgi-xp/xpnet.c
--- linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpnet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/sgi-xp/xpnet.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -475,7 +476,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff
 
 	if (skb->data[0] == 0xff) {
 		/* we are being asked to broadcast to all partitions */
-		for_each_bit(dest_partid, xpnet_broadcast_partitions,
+		for_each_set_bit(dest_partid, xpnet_broadcast_partitions,
 			     xp_max_npartitions) {
 
 			xpnet_send(skb, queued_msg, start_addr, end_addr,
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/tifm_core.c linux-libre-2.6.34-gnu1/drivers/misc/tifm_core.c
--- linux-libre-2.6.33-gnu1/drivers/misc/tifm_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/tifm_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/tifm.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/idr.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/tsl2550.c linux-libre-2.6.34-gnu1/drivers/misc/tsl2550.c
--- linux-libre-2.6.33-gnu1/drivers/misc/tsl2550.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/tsl2550.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,473 @@
+/*
+ *  tsl2550.c - Linux kernel modules for ambient light sensor
+ *
+ *  Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
+ *  Copyright (C) 2007 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>
+
+#define TSL2550_DRV_NAME	"tsl2550"
+#define DRIVER_VERSION		"1.2"
+
+/*
+ * Defines
+ */
+
+#define TSL2550_POWER_DOWN		0x00
+#define TSL2550_POWER_UP		0x03
+#define TSL2550_STANDARD_RANGE		0x18
+#define TSL2550_EXTENDED_RANGE		0x1d
+#define TSL2550_READ_ADC0		0x43
+#define TSL2550_READ_ADC1		0x83
+
+/*
+ * Structs
+ */
+
+struct tsl2550_data {
+	struct i2c_client *client;
+	struct mutex update_lock;
+
+	unsigned int power_state:1;
+	unsigned int operating_mode:1;
+};
+
+/*
+ * Global data
+ */
+
+static const u8 TSL2550_MODE_RANGE[2] = {
+	TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE,
+};
+
+/*
+ * Management functions
+ */
+
+static int tsl2550_set_operating_mode(struct i2c_client *client, int mode)
+{
+	struct tsl2550_data *data = i2c_get_clientdata(client);
+
+	int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]);
+
+	data->operating_mode = mode;
+
+	return ret;
+}
+
+static int tsl2550_set_power_state(struct i2c_client *client, int state)
+{
+	struct tsl2550_data *data = i2c_get_clientdata(client);
+	int ret;
+
+	if (state == 0)
+		ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN);
+	else {
+		ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
+
+		/* On power up we should reset operating mode also... */
+		tsl2550_set_operating_mode(client, data->operating_mode);
+	}
+
+	data->power_state = state;
+
+	return ret;
+}
+
+static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
+{
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(client, cmd);
+	if (ret < 0)
+		return ret;
+	if (!(ret & 0x80))
+		return -EAGAIN;
+	return ret & 0x7f;	/* remove the "valid" bit */
+}
+
+/*
+ * LUX calculation
+ */
+
+#define	TSL2550_MAX_LUX		1846
+
+static const u8 ratio_lut[] = {
+	100, 100, 100, 100, 100, 100, 100, 100,
+	100, 100, 100, 100, 100, 100, 99, 99,
+	99, 99, 99, 99, 99, 99, 99, 99,
+	99, 99, 99, 98, 98, 98, 98, 98,
+	98, 98, 97, 97, 97, 97, 97, 96,
+	96, 96, 96, 95, 95, 95, 94, 94,
+	93, 93, 93, 92, 92, 91, 91, 90,
+	89, 89, 88, 87, 87, 86, 85, 84,
+	83, 82, 81, 80, 79, 78, 77, 75,
+	74, 73, 71, 69, 68, 66, 64, 62,
+	60, 58, 56, 54, 52, 49, 47, 44,
+	42, 41, 40, 40, 39, 39, 38, 38,
+	37, 37, 37, 36, 36, 36, 35, 35,
+	35, 35, 34, 34, 34, 34, 33, 33,
+	33, 33, 32, 32, 32, 32, 32, 31,
+	31, 31, 31, 31, 30, 30, 30, 30,
+	30,
+};
+
+static const u16 count_lut[] = {
+	0, 1, 2, 3, 4, 5, 6, 7,
+	8, 9, 10, 11, 12, 13, 14, 15,
+	16, 18, 20, 22, 24, 26, 28, 30,
+	32, 34, 36, 38, 40, 42, 44, 46,
+	49, 53, 57, 61, 65, 69, 73, 77,
+	81, 85, 89, 93, 97, 101, 105, 109,
+	115, 123, 131, 139, 147, 155, 163, 171,
+	179, 187, 195, 203, 211, 219, 227, 235,
+	247, 263, 279, 295, 311, 327, 343, 359,
+	375, 391, 407, 423, 439, 455, 471, 487,
+	511, 543, 575, 607, 639, 671, 703, 735,
+	767, 799, 831, 863, 895, 927, 959, 991,
+	1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
+	1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
+	2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
+	3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
+};
+
+/*
+ * This function is described into Taos TSL2550 Designer's Notebook
+ * pages 2, 3.
+ */
+static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
+{
+	unsigned int lux;
+
+	/* Look up count from channel values */
+	u16 c0 = count_lut[ch0];
+	u16 c1 = count_lut[ch1];
+
+	/*
+	 * Calculate ratio.
+	 * Note: the "128" is a scaling factor
+	 */
+	u8 r = 128;
+
+	/* Avoid division by 0 and count 1 cannot be greater than count 0 */
+	if (c1 <= c0)
+		if (c0) {
+			r = c1 * 128 / c0;
+
+			/* Calculate LUX */
+			lux = ((c0 - c1) * ratio_lut[r]) / 256;
+		} else
+			lux = 0;
+	else
+		return -EAGAIN;
+
+	/* LUX range check */
+	return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
+}
+
+/*
+ * SysFS support
+ */
+
+static ssize_t tsl2550_show_power_state(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
+
+	return sprintf(buf, "%u\n", data->power_state);
+}
+
+static ssize_t tsl2550_store_power_state(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct tsl2550_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	int ret;
+
+	if (val < 0 || val > 1)
+		return -EINVAL;
+
+	mutex_lock(&data->update_lock);
+	ret = tsl2550_set_power_state(client, val);
+	mutex_unlock(&data->update_lock);
+
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
+		   tsl2550_show_power_state, tsl2550_store_power_state);
+
+static ssize_t tsl2550_show_operating_mode(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
+
+	return sprintf(buf, "%u\n", data->operating_mode);
+}
+
+static ssize_t tsl2550_store_operating_mode(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct tsl2550_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	int ret;
+
+	if (val < 0 || val > 1)
+		return -EINVAL;
+
+	if (data->power_state == 0)
+		return -EBUSY;
+
+	mutex_lock(&data->update_lock);
+	ret = tsl2550_set_operating_mode(client, val);
+	mutex_unlock(&data->update_lock);
+
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
+		   tsl2550_show_operating_mode, tsl2550_store_operating_mode);
+
+static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
+{
+	struct tsl2550_data *data = i2c_get_clientdata(client);
+	u8 ch0, ch1;
+	int ret;
+
+	ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
+	if (ret < 0)
+		return ret;
+	ch0 = ret;
+
+	ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
+	if (ret < 0)
+		return ret;
+	ch1 = ret;
+
+	/* Do the job */
+	ret = tsl2550_calculate_lux(ch0, ch1);
+	if (ret < 0)
+		return ret;
+	if (data->operating_mode == 1)
+		ret *= 5;
+
+	return sprintf(buf, "%d\n", ret);
+}
+
+static ssize_t tsl2550_show_lux1_input(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct tsl2550_data *data = i2c_get_clientdata(client);
+	int ret;
+
+	/* No LUX data if not operational */
+	if (!data->power_state)
+		return -EBUSY;
+
+	mutex_lock(&data->update_lock);
+	ret = __tsl2550_show_lux(client, buf);
+	mutex_unlock(&data->update_lock);
+
+	return ret;
+}
+
+static DEVICE_ATTR(lux1_input, S_IRUGO,
+		   tsl2550_show_lux1_input, NULL);
+
+static struct attribute *tsl2550_attributes[] = {
+	&dev_attr_power_state.attr,
+	&dev_attr_operating_mode.attr,
+	&dev_attr_lux1_input.attr,
+	NULL
+};
+
+static const struct attribute_group tsl2550_attr_group = {
+	.attrs = tsl2550_attributes,
+};
+
+/*
+ * Initialization function
+ */
+
+static int tsl2550_init_client(struct i2c_client *client)
+{
+	struct tsl2550_data *data = i2c_get_clientdata(client);
+	int err;
+
+	/*
+	 * Probe the chip. To do so we try to power up the device and then to
+	 * read back the 0x03 code
+	 */
+	err = i2c_smbus_read_byte_data(client, TSL2550_POWER_UP);
+	if (err < 0)
+		return err;
+	if (err != TSL2550_POWER_UP)
+		return -ENODEV;
+	data->power_state = 1;
+
+	/* Set the default operating mode */
+	err = i2c_smbus_write_byte(client,
+				   TSL2550_MODE_RANGE[data->operating_mode]);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+/*
+ * I2C init/probing/exit functions
+ */
+
+static struct i2c_driver tsl2550_driver;
+static int __devinit tsl2550_probe(struct i2c_client *client,
+				   const struct i2c_device_id *id)
+{
+	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+	struct tsl2550_data *data;
+	int *opmode, err = 0;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE
+					    | I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
+		err = -EIO;
+		goto exit;
+	}
+
+	data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	data->client = client;
+	i2c_set_clientdata(client, data);
+
+	/* Check platform data */
+	opmode = client->dev.platform_data;
+	if (opmode) {
+		if (*opmode < 0 || *opmode > 1) {
+			dev_err(&client->dev, "invalid operating_mode (%d)\n",
+					*opmode);
+			err = -EINVAL;
+			goto exit_kfree;
+		}
+		data->operating_mode = *opmode;
+	} else
+		data->operating_mode = 0;	/* default mode is standard */
+	dev_info(&client->dev, "%s operating mode\n",
+			data->operating_mode ? "extended" : "standard");
+
+	mutex_init(&data->update_lock);
+
+	/* Initialize the TSL2550 chip */
+	err = tsl2550_init_client(client);
+	if (err)
+		goto exit_kfree;
+
+	/* Register sysfs hooks */
+	err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
+	if (err)
+		goto exit_kfree;
+
+	dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
+
+	return 0;
+
+exit_kfree:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int __devexit tsl2550_remove(struct i2c_client *client)
+{
+	sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
+
+	/* Power down the device */
+	tsl2550_set_power_state(client, 0);
+
+	kfree(i2c_get_clientdata(client));
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int tsl2550_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+	return tsl2550_set_power_state(client, 0);
+}
+
+static int tsl2550_resume(struct i2c_client *client)
+{
+	return tsl2550_set_power_state(client, 1);
+}
+
+#else
+
+#define tsl2550_suspend		NULL
+#define tsl2550_resume		NULL
+
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id tsl2550_id[] = {
+	{ "tsl2550", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, tsl2550_id);
+
+static struct i2c_driver tsl2550_driver = {
+	.driver = {
+		.name	= TSL2550_DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+	.suspend = tsl2550_suspend,
+	.resume	= tsl2550_resume,
+	.probe	= tsl2550_probe,
+	.remove	= __devexit_p(tsl2550_remove),
+	.id_table = tsl2550_id,
+};
+
+static int __init tsl2550_init(void)
+{
+	return i2c_add_driver(&tsl2550_driver);
+}
+
+static void __exit tsl2550_exit(void)
+{
+	i2c_del_driver(&tsl2550_driver);
+}
+
+MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
+MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(tsl2550_init);
+module_exit(tsl2550_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/misc/vmware_balloon.c linux-libre-2.6.34-gnu1/drivers/misc/vmware_balloon.c
--- linux-libre-2.6.33-gnu1/drivers/misc/vmware_balloon.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/misc/vmware_balloon.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,832 @@
+/*
+ * VMware Balloon driver.
+ *
+ * Copyright (C) 2000-2010, VMware, 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; version 2 of the License and no later version.
+ *
+ * This program is distributed in 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Maintained by: Dmitry Torokhov <dtor@vmware.com>
+ */
+
+/*
+ * This is VMware physical memory management driver for Linux. The driver
+ * acts like a "balloon" that can be inflated to reclaim physical pages by
+ * reserving them in the guest and invalidating them in the monitor,
+ * freeing up the underlying machine pages so they can be allocated to
+ * other guests.  The balloon can also be deflated to allow the guest to
+ * use more physical memory. Higher level policies can control the sizes
+ * of balloons in VMs in order to manage physical memory resources.
+ */
+
+//#define DEBUG
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <asm/vmware.h>
+
+MODULE_AUTHOR("VMware, Inc.");
+MODULE_DESCRIPTION("VMware Memory Control (Balloon) Driver");
+MODULE_VERSION("1.2.1.0-K");
+MODULE_ALIAS("dmi:*:svnVMware*:*");
+MODULE_ALIAS("vmware_vmmemctl");
+MODULE_LICENSE("GPL");
+
+/*
+ * Various constants controlling rate of inflaint/deflating balloon,
+ * measured in pages.
+ */
+
+/*
+ * Rate of allocating memory when there is no memory pressure
+ * (driver performs non-sleeping allocations).
+ */
+#define VMW_BALLOON_NOSLEEP_ALLOC_MAX	16384U
+
+/*
+ * Rates of memory allocaton when guest experiences memory pressure
+ * (driver performs sleeping allocations).
+ */
+#define VMW_BALLOON_RATE_ALLOC_MIN	512U
+#define VMW_BALLOON_RATE_ALLOC_MAX	2048U
+#define VMW_BALLOON_RATE_ALLOC_INC	16U
+
+/*
+ * Rates for releasing pages while deflating balloon.
+ */
+#define VMW_BALLOON_RATE_FREE_MIN	512U
+#define VMW_BALLOON_RATE_FREE_MAX	16384U
+#define VMW_BALLOON_RATE_FREE_INC	16U
+
+/*
+ * When guest is under memory pressure, use a reduced page allocation
+ * rate for next several cycles.
+ */
+#define VMW_BALLOON_SLOW_CYCLES		4
+
+/*
+ * Use __GFP_HIGHMEM to allow pages from HIGHMEM zone. We don't
+ * allow wait (__GFP_WAIT) for NOSLEEP page allocations. Use
+ * __GFP_NOWARN, to suppress page allocation failure warnings.
+ */
+#define VMW_PAGE_ALLOC_NOSLEEP		(__GFP_HIGHMEM|__GFP_NOWARN)
+
+/*
+ * Use GFP_HIGHUSER when executing in a separate kernel thread
+ * context and allocation can sleep.  This is less stressful to
+ * the guest memory system, since it allows the thread to block
+ * while memory is reclaimed, and won't take pages from emergency
+ * low-memory pools.
+ */
+#define VMW_PAGE_ALLOC_CANSLEEP		(GFP_HIGHUSER)
+
+/* Maximum number of page allocations without yielding processor */
+#define VMW_BALLOON_YIELD_THRESHOLD	1024
+
+
+/*
+ * Hypervisor communication port definitions.
+ */
+#define VMW_BALLOON_HV_PORT		0x5670
+#define VMW_BALLOON_HV_MAGIC		0x456c6d6f
+#define VMW_BALLOON_PROTOCOL_VERSION	2
+#define VMW_BALLOON_GUEST_ID		1	/* Linux */
+
+#define VMW_BALLOON_CMD_START		0
+#define VMW_BALLOON_CMD_GET_TARGET	1
+#define VMW_BALLOON_CMD_LOCK		2
+#define VMW_BALLOON_CMD_UNLOCK		3
+#define VMW_BALLOON_CMD_GUEST_ID	4
+
+/* error codes */
+#define VMW_BALLOON_SUCCESS		0
+#define VMW_BALLOON_FAILURE		-1
+#define VMW_BALLOON_ERROR_CMD_INVALID	1
+#define VMW_BALLOON_ERROR_PPN_INVALID	2
+#define VMW_BALLOON_ERROR_PPN_LOCKED	3
+#define VMW_BALLOON_ERROR_PPN_UNLOCKED	4
+#define VMW_BALLOON_ERROR_PPN_PINNED	5
+#define VMW_BALLOON_ERROR_PPN_NOTNEEDED	6
+#define VMW_BALLOON_ERROR_RESET		7
+#define VMW_BALLOON_ERROR_BUSY		8
+
+#define VMWARE_BALLOON_CMD(cmd, data, result)		\
+({							\
+	unsigned long __stat, __dummy1, __dummy2;	\
+	__asm__ __volatile__ ("inl (%%dx)" :		\
+		"=a"(__stat),				\
+		"=c"(__dummy1),				\
+		"=d"(__dummy2),				\
+		"=b"(result) :				\
+		"0"(VMW_BALLOON_HV_MAGIC),		\
+		"1"(VMW_BALLOON_CMD_##cmd),		\
+		"2"(VMW_BALLOON_HV_PORT),		\
+		"3"(data) :				\
+		"memory");				\
+	result &= -1UL;					\
+	__stat & -1UL;					\
+})
+
+#ifdef CONFIG_DEBUG_FS
+struct vmballoon_stats {
+	unsigned int timer;
+
+	/* allocation statustics */
+	unsigned int alloc;
+	unsigned int alloc_fail;
+	unsigned int sleep_alloc;
+	unsigned int sleep_alloc_fail;
+	unsigned int refused_alloc;
+	unsigned int refused_free;
+	unsigned int free;
+
+	/* monitor operations */
+	unsigned int lock;
+	unsigned int lock_fail;
+	unsigned int unlock;
+	unsigned int unlock_fail;
+	unsigned int target;
+	unsigned int target_fail;
+	unsigned int start;
+	unsigned int start_fail;
+	unsigned int guest_type;
+	unsigned int guest_type_fail;
+};
+
+#define STATS_INC(stat) (stat)++
+#else
+#define STATS_INC(stat)
+#endif
+
+struct vmballoon {
+
+	/* list of reserved physical pages */
+	struct list_head pages;
+
+	/* transient list of non-balloonable pages */
+	struct list_head refused_pages;
+
+	/* balloon size in pages */
+	unsigned int size;
+	unsigned int target;
+
+	/* reset flag */
+	bool reset_required;
+
+	/* adjustment rates (pages per second) */
+	unsigned int rate_alloc;
+	unsigned int rate_free;
+
+	/* slowdown page allocations for next few cycles */
+	unsigned int slow_allocation_cycles;
+
+#ifdef CONFIG_DEBUG_FS
+	/* statistics */
+	struct vmballoon_stats stats;
+
+	/* debugfs file exporting statistics */
+	struct dentry *dbg_entry;
+#endif
+
+	struct sysinfo sysinfo;
+
+	struct delayed_work dwork;
+};
+
+static struct vmballoon balloon;
+static struct workqueue_struct *vmballoon_wq;
+
+/*
+ * Send "start" command to the host, communicating supported version
+ * of the protocol.
+ */
+static bool vmballoon_send_start(struct vmballoon *b)
+{
+	unsigned long status, dummy;
+
+	STATS_INC(b->stats.start);
+
+	status = VMWARE_BALLOON_CMD(START, VMW_BALLOON_PROTOCOL_VERSION, dummy);
+	if (status == VMW_BALLOON_SUCCESS)
+		return true;
+
+	pr_debug("%s - failed, hv returns %ld\n", __func__, status);
+	STATS_INC(b->stats.start_fail);
+	return false;
+}
+
+static bool vmballoon_check_status(struct vmballoon *b, unsigned long status)
+{
+	switch (status) {
+	case VMW_BALLOON_SUCCESS:
+		return true;
+
+	case VMW_BALLOON_ERROR_RESET:
+		b->reset_required = true;
+		/* fall through */
+
+	default:
+		return false;
+	}
+}
+
+/*
+ * Communicate guest type to the host so that it can adjust ballooning
+ * algorithm to the one most appropriate for the guest. This command
+ * is normally issued after sending "start" command and is part of
+ * standard reset sequence.
+ */
+static bool vmballoon_send_guest_id(struct vmballoon *b)
+{
+	unsigned long status, dummy;
+
+	status = VMWARE_BALLOON_CMD(GUEST_ID, VMW_BALLOON_GUEST_ID, dummy);
+
+	STATS_INC(b->stats.guest_type);
+
+	if (vmballoon_check_status(b, status))
+		return true;
+
+	pr_debug("%s - failed, hv returns %ld\n", __func__, status);
+	STATS_INC(b->stats.guest_type_fail);
+	return false;
+}
+
+/*
+ * Retrieve desired balloon size from the host.
+ */
+static bool vmballoon_send_get_target(struct vmballoon *b, u32 *new_target)
+{
+	unsigned long status;
+	unsigned long target;
+	unsigned long limit;
+	u32 limit32;
+
+	/*
+	 * si_meminfo() is cheap. Moreover, we want to provide dynamic
+	 * max balloon size later. So let us call si_meminfo() every
+	 * iteration.
+	 */
+	si_meminfo(&b->sysinfo);
+	limit = b->sysinfo.totalram;
+
+	/* Ensure limit fits in 32-bits */
+	limit32 = (u32)limit;
+	if (limit != limit32)
+		return false;
+
+	/* update stats */
+	STATS_INC(b->stats.target);
+
+	status = VMWARE_BALLOON_CMD(GET_TARGET, limit, target);
+	if (vmballoon_check_status(b, status)) {
+		*new_target = target;
+		return true;
+	}
+
+	pr_debug("%s - failed, hv returns %ld\n", __func__, status);
+	STATS_INC(b->stats.target_fail);
+	return false;
+}
+
+/*
+ * Notify the host about allocated page so that host can use it without
+ * fear that guest will need it. Host may reject some pages, we need to
+ * check the return value and maybe submit a different page.
+ */
+static bool vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn)
+{
+	unsigned long status, dummy;
+	u32 pfn32;
+
+	pfn32 = (u32)pfn;
+	if (pfn32 != pfn)
+		return false;
+
+	STATS_INC(b->stats.lock);
+
+	status = VMWARE_BALLOON_CMD(LOCK, pfn, dummy);
+	if (vmballoon_check_status(b, status))
+		return true;
+
+	pr_debug("%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
+	STATS_INC(b->stats.lock_fail);
+	return false;
+}
+
+/*
+ * Notify the host that guest intends to release given page back into
+ * the pool of available (to the guest) pages.
+ */
+static bool vmballoon_send_unlock_page(struct vmballoon *b, unsigned long pfn)
+{
+	unsigned long status, dummy;
+	u32 pfn32;
+
+	pfn32 = (u32)pfn;
+	if (pfn32 != pfn)
+		return false;
+
+	STATS_INC(b->stats.unlock);
+
+	status = VMWARE_BALLOON_CMD(UNLOCK, pfn, dummy);
+	if (vmballoon_check_status(b, status))
+		return true;
+
+	pr_debug("%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
+	STATS_INC(b->stats.unlock_fail);
+	return false;
+}
+
+/*
+ * Quickly release all pages allocated for the balloon. This function is
+ * called when host decides to "reset" balloon for one reason or another.
+ * Unlike normal "deflate" we do not (shall not) notify host of the pages
+ * being released.
+ */
+static void vmballoon_pop(struct vmballoon *b)
+{
+	struct page *page, *next;
+	unsigned int count = 0;
+
+	list_for_each_entry_safe(page, next, &b->pages, lru) {
+		list_del(&page->lru);
+		__free_page(page);
+		STATS_INC(b->stats.free);
+		b->size--;
+
+		if (++count >= b->rate_free) {
+			count = 0;
+			cond_resched();
+		}
+	}
+}
+
+/*
+ * Perform standard reset sequence by popping the balloon (in case it
+ * is not  empty) and then restarting protocol. This operation normally
+ * happens when host responds with VMW_BALLOON_ERROR_RESET to a command.
+ */
+static void vmballoon_reset(struct vmballoon *b)
+{
+	/* free all pages, skipping monitor unlock */
+	vmballoon_pop(b);
+
+	if (vmballoon_send_start(b)) {
+		b->reset_required = false;
+		if (!vmballoon_send_guest_id(b))
+			pr_err("failed to send guest ID to the host\n");
+	}
+}
+
+/*
+ * Allocate (or reserve) a page for the balloon and notify the host.  If host
+ * refuses the page put it on "refuse" list and allocate another one until host
+ * is satisfied. "Refused" pages are released at the end of inflation cycle
+ * (when we allocate b->rate_alloc pages).
+ */
+static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep)
+{
+	struct page *page;
+	gfp_t flags;
+	bool locked = false;
+
+	do {
+		if (!can_sleep)
+			STATS_INC(b->stats.alloc);
+		else
+			STATS_INC(b->stats.sleep_alloc);
+
+		flags = can_sleep ? VMW_PAGE_ALLOC_CANSLEEP : VMW_PAGE_ALLOC_NOSLEEP;
+		page = alloc_page(flags);
+		if (!page) {
+			if (!can_sleep)
+				STATS_INC(b->stats.alloc_fail);
+			else
+				STATS_INC(b->stats.sleep_alloc_fail);
+			return -ENOMEM;
+		}
+
+		/* inform monitor */
+		locked = vmballoon_send_lock_page(b, page_to_pfn(page));
+		if (!locked) {
+			if (b->reset_required) {
+				__free_page(page);
+				return -EIO;
+			}
+
+			/* place on list of non-balloonable pages, retry allocation */
+			list_add(&page->lru, &b->refused_pages);
+			STATS_INC(b->stats.refused_alloc);
+		}
+	} while (!locked);
+
+	/* track allocated page */
+	list_add(&page->lru, &b->pages);
+
+	/* update balloon size */
+	b->size++;
+
+	return 0;
+}
+
+/*
+ * Release the page allocated for the balloon. Note that we first notify
+ * the host so it can make sure the page will be available for the guest
+ * to use, if needed.
+ */
+static int vmballoon_release_page(struct vmballoon *b, struct page *page)
+{
+	if (!vmballoon_send_unlock_page(b, page_to_pfn(page)))
+		return -EIO;
+
+	list_del(&page->lru);
+
+	/* deallocate page */
+	__free_page(page);
+	STATS_INC(b->stats.free);
+
+	/* update balloon size */
+	b->size--;
+
+	return 0;
+}
+
+/*
+ * Release pages that were allocated while attempting to inflate the
+ * balloon but were refused by the host for one reason or another.
+ */
+static void vmballoon_release_refused_pages(struct vmballoon *b)
+{
+	struct page *page, *next;
+
+	list_for_each_entry_safe(page, next, &b->refused_pages, lru) {
+		list_del(&page->lru);
+		__free_page(page);
+		STATS_INC(b->stats.refused_free);
+	}
+}
+
+/*
+ * Inflate the balloon towards its target size. Note that we try to limit
+ * the rate of allocation to make sure we are not choking the rest of the
+ * system.
+ */
+static void vmballoon_inflate(struct vmballoon *b)
+{
+	unsigned int goal;
+	unsigned int rate;
+	unsigned int i;
+	unsigned int allocations = 0;
+	int error = 0;
+	bool alloc_can_sleep = false;
+
+	pr_debug("%s - size: %d, target %d\n", __func__, b->size, b->target);
+
+	/*
+	 * First try NOSLEEP page allocations to inflate balloon.
+	 *
+	 * If we do not throttle nosleep allocations, we can drain all
+	 * free pages in the guest quickly (if the balloon target is high).
+	 * As a side-effect, draining free pages helps to inform (force)
+	 * the guest to start swapping if balloon target is not met yet,
+	 * which is a desired behavior. However, balloon driver can consume
+	 * all available CPU cycles if too many pages are allocated in a
+	 * second. Therefore, we throttle nosleep allocations even when
+	 * the guest is not under memory pressure. OTOH, if we have already
+	 * predicted that the guest is under memory pressure, then we
+	 * slowdown page allocations considerably.
+	 */
+
+	goal = b->target - b->size;
+	/*
+	 * Start with no sleep allocation rate which may be higher
+	 * than sleeping allocation rate.
+	 */
+	rate = b->slow_allocation_cycles ?
+			b->rate_alloc : VMW_BALLOON_NOSLEEP_ALLOC_MAX;
+
+	pr_debug("%s - goal: %d, no-sleep rate: %d, sleep rate: %d\n",
+		 __func__, goal, rate, b->rate_alloc);
+
+	for (i = 0; i < goal; i++) {
+
+		error = vmballoon_reserve_page(b, alloc_can_sleep);
+		if (error) {
+			if (error != -ENOMEM) {
+				/*
+				 * Not a page allocation failure, stop this
+				 * cycle. Maybe we'll get new target from
+				 * the host soon.
+				 */
+				break;
+			}
+
+			if (alloc_can_sleep) {
+				/*
+				 * CANSLEEP page allocation failed, so guest
+				 * is under severe memory pressure. Quickly
+				 * decrease allocation rate.
+				 */
+				b->rate_alloc = max(b->rate_alloc / 2,
+						    VMW_BALLOON_RATE_ALLOC_MIN);
+				break;
+			}
+
+			/*
+			 * NOSLEEP page allocation failed, so the guest is
+			 * under memory pressure. Let us slow down page
+			 * allocations for next few cycles so that the guest
+			 * gets out of memory pressure. Also, if we already
+			 * allocated b->rate_alloc pages, let's pause,
+			 * otherwise switch to sleeping allocations.
+			 */
+			b->slow_allocation_cycles = VMW_BALLOON_SLOW_CYCLES;
+
+			if (i >= b->rate_alloc)
+				break;
+
+			alloc_can_sleep = true;
+			/* Lower rate for sleeping allocations. */
+			rate = b->rate_alloc;
+		}
+
+		if (++allocations > VMW_BALLOON_YIELD_THRESHOLD) {
+			cond_resched();
+			allocations = 0;
+		}
+
+		if (i >= rate) {
+			/* We allocated enough pages, let's take a break. */
+			break;
+		}
+	}
+
+	/*
+	 * We reached our goal without failures so try increasing
+	 * allocation rate.
+	 */
+	if (error == 0 && i >= b->rate_alloc) {
+		unsigned int mult = i / b->rate_alloc;
+
+		b->rate_alloc =
+			min(b->rate_alloc + mult * VMW_BALLOON_RATE_ALLOC_INC,
+			    VMW_BALLOON_RATE_ALLOC_MAX);
+	}
+
+	vmballoon_release_refused_pages(b);
+}
+
+/*
+ * Decrease the size of the balloon allowing guest to use more memory.
+ */
+static void vmballoon_deflate(struct vmballoon *b)
+{
+	struct page *page, *next;
+	unsigned int i = 0;
+	unsigned int goal;
+	int error;
+
+	pr_debug("%s - size: %d, target %d\n", __func__, b->size, b->target);
+
+	/* limit deallocation rate */
+	goal = min(b->size - b->target, b->rate_free);
+
+	pr_debug("%s - goal: %d, rate: %d\n", __func__, goal, b->rate_free);
+
+	/* free pages to reach target */
+	list_for_each_entry_safe(page, next, &b->pages, lru) {
+		error = vmballoon_release_page(b, page);
+		if (error) {
+			/* quickly decrease rate in case of error */
+			b->rate_free = max(b->rate_free / 2,
+					   VMW_BALLOON_RATE_FREE_MIN);
+			return;
+		}
+
+		if (++i >= goal)
+			break;
+	}
+
+	/* slowly increase rate if there were no errors */
+	b->rate_free = min(b->rate_free + VMW_BALLOON_RATE_FREE_INC,
+			   VMW_BALLOON_RATE_FREE_MAX);
+}
+
+/*
+ * Balloon work function: reset protocol, if needed, get the new size and
+ * adjust balloon as needed. Repeat in 1 sec.
+ */
+static void vmballoon_work(struct work_struct *work)
+{
+	struct delayed_work *dwork = to_delayed_work(work);
+	struct vmballoon *b = container_of(dwork, struct vmballoon, dwork);
+	unsigned int target;
+
+	STATS_INC(b->stats.timer);
+
+	if (b->reset_required)
+		vmballoon_reset(b);
+
+	if (b->slow_allocation_cycles > 0)
+		b->slow_allocation_cycles--;
+
+	if (vmballoon_send_get_target(b, &target)) {
+		/* update target, adjust size */
+		b->target = target;
+
+		if (b->size < target)
+			vmballoon_inflate(b);
+		else if (b->size > target)
+			vmballoon_deflate(b);
+	}
+
+	queue_delayed_work(vmballoon_wq, dwork, round_jiffies_relative(HZ));
+}
+
+/*
+ * DEBUGFS Interface
+ */
+#ifdef CONFIG_DEBUG_FS
+
+static int vmballoon_debug_show(struct seq_file *f, void *offset)
+{
+	struct vmballoon *b = f->private;
+	struct vmballoon_stats *stats = &b->stats;
+
+	/* format size info */
+	seq_printf(f,
+		   "target:             %8d pages\n"
+		   "current:            %8d pages\n",
+		   b->target, b->size);
+
+	/* format rate info */
+	seq_printf(f,
+		   "rateNoSleepAlloc:   %8d pages/sec\n"
+		   "rateSleepAlloc:     %8d pages/sec\n"
+		   "rateFree:           %8d pages/sec\n",
+		   VMW_BALLOON_NOSLEEP_ALLOC_MAX,
+		   b->rate_alloc, b->rate_free);
+
+	seq_printf(f,
+		   "\n"
+		   "timer:              %8u\n"
+		   "start:              %8u (%4u failed)\n"
+		   "guestType:          %8u (%4u failed)\n"
+		   "lock:               %8u (%4u failed)\n"
+		   "unlock:             %8u (%4u failed)\n"
+		   "target:             %8u (%4u failed)\n"
+		   "primNoSleepAlloc:   %8u (%4u failed)\n"
+		   "primCanSleepAlloc:  %8u (%4u failed)\n"
+		   "primFree:           %8u\n"
+		   "errAlloc:           %8u\n"
+		   "errFree:            %8u\n",
+		   stats->timer,
+		   stats->start, stats->start_fail,
+		   stats->guest_type, stats->guest_type_fail,
+		   stats->lock,  stats->lock_fail,
+		   stats->unlock, stats->unlock_fail,
+		   stats->target, stats->target_fail,
+		   stats->alloc, stats->alloc_fail,
+		   stats->sleep_alloc, stats->sleep_alloc_fail,
+		   stats->free,
+		   stats->refused_alloc, stats->refused_free);
+
+	return 0;
+}
+
+static int vmballoon_debug_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, vmballoon_debug_show, inode->i_private);
+}
+
+static const struct file_operations vmballoon_debug_fops = {
+	.owner		= THIS_MODULE,
+	.open		= vmballoon_debug_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init vmballoon_debugfs_init(struct vmballoon *b)
+{
+	int error;
+
+	b->dbg_entry = debugfs_create_file("vmmemctl", S_IRUGO, NULL, b,
+					   &vmballoon_debug_fops);
+	if (IS_ERR(b->dbg_entry)) {
+		error = PTR_ERR(b->dbg_entry);
+		pr_err("failed to create debugfs entry, error: %d\n", error);
+		return error;
+	}
+
+	return 0;
+}
+
+static void __exit vmballoon_debugfs_exit(struct vmballoon *b)
+{
+	debugfs_remove(b->dbg_entry);
+}
+
+#else
+
+static inline int vmballoon_debugfs_init(struct vmballoon *b)
+{
+	return 0;
+}
+
+static inline void vmballoon_debugfs_exit(struct vmballoon *b)
+{
+}
+
+#endif	/* CONFIG_DEBUG_FS */
+
+static int __init vmballoon_init(void)
+{
+	int error;
+
+	/*
+	 * Check if we are running on VMware's hypervisor and bail out
+	 * if we are not.
+	 */
+	if (!vmware_platform())
+		return -ENODEV;
+
+	vmballoon_wq = create_freezeable_workqueue("vmmemctl");
+	if (!vmballoon_wq) {
+		pr_err("failed to create workqueue\n");
+		return -ENOMEM;
+	}
+
+	INIT_LIST_HEAD(&balloon.pages);
+	INIT_LIST_HEAD(&balloon.refused_pages);
+
+	/* initialize rates */
+	balloon.rate_alloc = VMW_BALLOON_RATE_ALLOC_MAX;
+	balloon.rate_free = VMW_BALLOON_RATE_FREE_MAX;
+
+	INIT_DELAYED_WORK(&balloon.dwork, vmballoon_work);
+
+	/*
+	 * Start balloon.
+	 */
+	if (!vmballoon_send_start(&balloon)) {
+		pr_err("failed to send start command to the host\n");
+		error = -EIO;
+		goto fail;
+	}
+
+	if (!vmballoon_send_guest_id(&balloon)) {
+		pr_err("failed to send guest ID to the host\n");
+		error = -EIO;
+		goto fail;
+	}
+
+	error = vmballoon_debugfs_init(&balloon);
+	if (error)
+		goto fail;
+
+	queue_delayed_work(vmballoon_wq, &balloon.dwork, 0);
+
+	return 0;
+
+fail:
+	destroy_workqueue(vmballoon_wq);
+	return error;
+}
+module_init(vmballoon_init);
+
+static void __exit vmballoon_exit(void)
+{
+	cancel_delayed_work_sync(&balloon.dwork);
+	destroy_workqueue(vmballoon_wq);
+
+	vmballoon_debugfs_exit(&balloon);
+
+	/*
+	 * Deallocate all reserved memory, and reset connection with monitor.
+	 * Reset connection before deallocating memory to avoid potential for
+	 * additional spurious resets from guest touching deallocated pages.
+	 */
+	vmballoon_send_start(&balloon);
+	vmballoon_pop(&balloon);
+}
+module_exit(vmballoon_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/card/block.c linux-libre-2.6.34-gnu1/drivers/mmc/card/block.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/card/block.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/card/block.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 
 #include <linux/kernel.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/hdreg.h>
 #include <linux/kdev_t.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/card/mmc_test.c linux-libre-2.6.34-gnu1/drivers/mmc/card/mmc_test.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/card/mmc_test.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/card/mmc_test.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
+#include <linux/slab.h>
 
 #include <linux/scatterlist.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/card/queue.c linux-libre-2.6.34-gnu1/drivers/mmc/card/queue.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/card/queue.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/card/queue.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  *
  */
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/blkdev.h>
 #include <linux/freezer.h>
@@ -154,9 +155,8 @@ int mmc_init_queue(struct mmc_queue *mq,
 
 		if (mq->bounce_buf) {
 			blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY);
-			blk_queue_max_sectors(mq->queue, bouncesz / 512);
-			blk_queue_max_phys_segments(mq->queue, bouncesz / 512);
-			blk_queue_max_hw_segments(mq->queue, bouncesz / 512);
+			blk_queue_max_hw_sectors(mq->queue, bouncesz / 512);
+			blk_queue_max_segments(mq->queue, bouncesz / 512);
 			blk_queue_max_segment_size(mq->queue, bouncesz);
 
 			mq->sg = kmalloc(sizeof(struct scatterlist),
@@ -180,10 +180,9 @@ int mmc_init_queue(struct mmc_queue *mq,
 
 	if (!mq->bounce_buf) {
 		blk_queue_bounce_limit(mq->queue, limit);
-		blk_queue_max_sectors(mq->queue,
+		blk_queue_max_hw_sectors(mq->queue,
 			min(host->max_blk_count, host->max_req_size / 512));
-		blk_queue_max_phys_segments(mq->queue, host->max_phys_segs);
-		blk_queue_max_hw_segments(mq->queue, host->max_hw_segs);
+		blk_queue_max_segments(mq->queue, host->max_hw_segs);
 		blk_queue_max_segment_size(mq->queue, host->max_seg_size);
 
 		mq->sg = kmalloc(sizeof(struct scatterlist) *
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/card/sdio_uart.c linux-libre-2.6.34-gnu1/drivers/mmc/card/sdio_uart.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/card/sdio_uart.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/card/sdio_uart.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,9 +34,10 @@
 #include <linux/seq_file.h>
 #include <linux/serial_reg.h>
 #include <linux/circ_buf.h>
-#include <linux/gfp.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
+#include <linux/kfifo.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/core.h>
 #include <linux/mmc/card.h>
@@ -47,19 +48,9 @@
 #define UART_NR		8	/* Number of UARTs this driver can handle */
 
 
-#define UART_XMIT_SIZE	PAGE_SIZE
+#define FIFO_SIZE	PAGE_SIZE
 #define WAKEUP_CHARS	256
 
-#define circ_empty(circ)	((circ)->head == (circ)->tail)
-#define circ_clear(circ)	((circ)->head = (circ)->tail = 0)
-
-#define circ_chars_pending(circ) \
-		(CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
-
-#define circ_chars_free(circ) \
-		(CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
-
-
 struct uart_icount {
 	__u32	cts;
 	__u32	dsr;
@@ -82,7 +73,7 @@ struct sdio_uart_port {
 	struct mutex		func_lock;
 	struct task_struct	*in_sdio_uart_irq;
 	unsigned int		regs_offset;
-	struct circ_buf		xmit;
+	struct kfifo		xmit_fifo;
 	spinlock_t		write_lock;
 	struct uart_icount	icount;
 	unsigned int		uartclk;
@@ -105,6 +96,8 @@ static int sdio_uart_add_port(struct sdi
 	kref_init(&port->kref);
 	mutex_init(&port->func_lock);
 	spin_lock_init(&port->write_lock);
+	if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL))
+		return -ENOMEM;
 
 	spin_lock(&sdio_uart_table_lock);
 	for (index = 0; index < UART_NR; index++) {
@@ -140,6 +133,7 @@ static void sdio_uart_port_destroy(struc
 {
 	struct sdio_uart_port *port =
 		container_of(kref, struct sdio_uart_port, kref);
+	kfifo_free(&port->xmit_fifo);
 	kfree(port);
 }
 
@@ -456,9 +450,11 @@ static void sdio_uart_receive_chars(stru
 
 static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
 {
-	struct circ_buf *xmit = &port->xmit;
+	struct kfifo *xmit = &port->xmit_fifo;
 	int count;
 	struct tty_struct *tty;
+	u8 iobuf[16];
+	int len;
 
 	if (port->x_char) {
 		sdio_out(port, UART_TX, port->x_char);
@@ -469,27 +465,25 @@ static void sdio_uart_transmit_chars(str
 
 	tty = tty_port_tty_get(&port->port);
 
-	if (tty == NULL || circ_empty(xmit) ||
+	if (tty == NULL || !kfifo_len(xmit) ||
 				tty->stopped || tty->hw_stopped) {
 		sdio_uart_stop_tx(port);
 		tty_kref_put(tty);
 		return;
 	}
 
-	count = 16;
-	do {
-		sdio_out(port, UART_TX, xmit->buf[xmit->tail]);
-		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+	len = kfifo_out_locked(xmit, iobuf, 16, &port->write_lock);
+	for (count = 0; count < len; count++) {
+		sdio_out(port, UART_TX, iobuf[count]);
 		port->icount.tx++;
-		if (circ_empty(xmit))
-			break;
-	} while (--count > 0);
+	}
 
-	if (circ_chars_pending(xmit) < WAKEUP_CHARS)
+	len = kfifo_len(xmit);
+	if (len < WAKEUP_CHARS) {
 		tty_wakeup(tty);
-
-	if (circ_empty(xmit))
-		sdio_uart_stop_tx(port);
+		if (len == 0)
+			sdio_uart_stop_tx(port);
+	}
 	tty_kref_put(tty);
 }
 
@@ -581,7 +575,7 @@ static int uart_carrier_raised(struct tt
 	struct sdio_uart_port *port =
 			container_of(tport, struct sdio_uart_port, port);
 	unsigned int ret = sdio_uart_claim_func(port);
-	if (ret)	/* Missing hardware shoudn't block for carrier */
+	if (ret)	/* Missing hardware shouldn't block for carrier */
 		return 1;
 	ret = sdio_uart_get_mctrl(port);
 	sdio_uart_release_func(port);
@@ -632,7 +626,6 @@ static int sdio_uart_activate(struct tty
 {
 	struct sdio_uart_port *port =
 			container_of(tport, struct sdio_uart_port, port);
-	unsigned long page;
 	int ret;
 
 	/*
@@ -641,22 +634,17 @@ static int sdio_uart_activate(struct tty
 	 */
 	set_bit(TTY_IO_ERROR, &tty->flags);
 
-	/* Initialise and allocate the transmit buffer. */
-	page = __get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-	port->xmit.buf = (unsigned char *)page;
-	circ_clear(&port->xmit);
+	kfifo_reset(&port->xmit_fifo);
 
 	ret = sdio_uart_claim_func(port);
 	if (ret)
-		goto err1;
+		return ret;
 	ret = sdio_enable_func(port->func);
 	if (ret)
-		goto err2;
+		goto err1;
 	ret = sdio_claim_irq(port->func, sdio_uart_irq);
 	if (ret)
-		goto err3;
+		goto err2;
 
 	/*
 	 * Clear the FIFO buffers and disable them.
@@ -700,12 +688,10 @@ static int sdio_uart_activate(struct tty
 	sdio_uart_release_func(port);
 	return 0;
 
-err3:
-	sdio_disable_func(port->func);
 err2:
-	sdio_uart_release_func(port);
+	sdio_disable_func(port->func);
 err1:
-	free_page((unsigned long)port->xmit.buf);
+	sdio_uart_release_func(port);
 	return ret;
 }
 
@@ -727,7 +713,7 @@ static void sdio_uart_shutdown(struct tt
 
 	ret = sdio_uart_claim_func(port);
 	if (ret)
-		goto skip;
+		return;
 
 	sdio_uart_stop_rx(port);
 
@@ -749,10 +735,6 @@ static void sdio_uart_shutdown(struct tt
 	sdio_disable_func(port->func);
 
 	sdio_uart_release_func(port);
-
-skip:
-	/* Free the transmit buffer page. */
-	free_page((unsigned long)port->xmit.buf);
 }
 
 /**
@@ -822,27 +804,12 @@ static int sdio_uart_write(struct tty_st
 			   int count)
 {
 	struct sdio_uart_port *port = tty->driver_data;
-	struct circ_buf *circ = &port->xmit;
-	int c, ret = 0;
+	int ret;
 
 	if (!port->func)
 		return -ENODEV;
 
-	spin_lock(&port->write_lock);
-	while (1) {
-		c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
-		if (count < c)
-			c = count;
-		if (c <= 0)
-			break;
-		memcpy(circ->buf + circ->head, buf, c);
-		circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
-		buf += c;
-		count -= c;
-		ret += c;
-	}
-	spin_unlock(&port->write_lock);
-
+	ret = kfifo_in_locked(&port->xmit_fifo, buf, count, &port->write_lock);
 	if (!(port->ier & UART_IER_THRI)) {
 		int err = sdio_uart_claim_func(port);
 		if (!err) {
@@ -859,13 +826,13 @@ static int sdio_uart_write(struct tty_st
 static int sdio_uart_write_room(struct tty_struct *tty)
 {
 	struct sdio_uart_port *port = tty->driver_data;
-	return port ? circ_chars_free(&port->xmit) : 0;
+	return FIFO_SIZE - kfifo_len(&port->xmit_fifo);
 }
 
 static int sdio_uart_chars_in_buffer(struct tty_struct *tty)
 {
 	struct sdio_uart_port *port = tty->driver_data;
-	return port ? circ_chars_pending(&port->xmit) : 0;
+	return kfifo_len(&port->xmit_fifo);
 }
 
 static void sdio_uart_send_xchar(struct tty_struct *tty, char ch)
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/core/bus.c linux-libre-2.6.34-gnu1/drivers/mmc/core/bus.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/core/bus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/core/bus.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/core/core.c linux-libre-2.6.34-gnu1/drivers/mmc/core/core.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/core/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/core/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -1089,6 +1089,7 @@ void mmc_rescan(struct work_struct *work
 	mmc_claim_host(host);
 
 	mmc_power_up(host);
+	sdio_reset(host);
 	mmc_go_idle(host);
 
 	mmc_send_if_cond(host, host->ocr_avail);
@@ -1151,6 +1152,9 @@ void mmc_stop_host(struct mmc_host *host
 	cancel_delayed_work(&host->detect);
 	mmc_flush_scheduled_work();
 
+	/* clear pm flags now and let card drivers set them as needed */
+	host->pm_flags = 0;
+
 	mmc_bus_get(host);
 	if (host->bus_ops && !host->bus_dead) {
 		if (host->bus_ops->remove)
@@ -1273,12 +1277,13 @@ int mmc_suspend_host(struct mmc_host *ho
 			mmc_claim_host(host);
 			mmc_detach_bus(host);
 			mmc_release_host(host);
+			host->pm_flags = 0;
 			err = 0;
 		}
 	}
 	mmc_bus_put(host);
 
-	if (!err)
+	if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER))
 		mmc_power_off(host);
 
 	return err;
@@ -1296,8 +1301,10 @@ 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);
+		if (!(host->pm_flags & MMC_PM_KEEP_POWER)) {
+			mmc_power_up(host);
+			mmc_select_voltage(host, host->ocr);
+		}
 		BUG_ON(!host->bus_ops->resume);
 		err = host->bus_ops->resume(host);
 		if (err) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/core/debugfs.c linux-libre-2.6.34-gnu1/drivers/mmc/core/debugfs.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/core/debugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/core/debugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/debugfs.h>
 #include <linux/fs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/stat.h>
 
 #include <linux/mmc/card.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/core/host.c linux-libre-2.6.34-gnu1/drivers/mmc/core/host.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/core/host.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/core/host.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/idr.h>
 #include <linux/pagemap.h>
 #include <linux/leds.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/host.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/core/mmc.c linux-libre-2.6.34-gnu1/drivers/mmc/core/mmc.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/core/mmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/core/mmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
@@ -225,7 +226,7 @@ static int mmc_read_ext_csd(struct mmc_c
 			mmc_card_set_blockaddr(card);
 	}
 
-	switch (ext_csd[EXT_CSD_CARD_TYPE]) {
+	switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
 	case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
 		card->ext_csd.hs_max_dtr = 52000000;
 		break;
@@ -237,7 +238,6 @@ static int mmc_read_ext_csd(struct mmc_c
 		printk(KERN_WARNING "%s: card is mmc v4 but doesn't "
 			"support any high-speed modes.\n",
 			mmc_hostname(card->host));
-		goto out;
 	}
 
 	if (card->ext_csd.rev >= 3) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/core/mmc_ops.c linux-libre-2.6.34-gnu1/drivers/mmc/core/mmc_ops.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/core/mmc_ops.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/core/mmc_ops.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  * your option) any later version.
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/scatterlist.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/core/sd.c linux-libre-2.6.34-gnu1/drivers/mmc/core/sd.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/core/sd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/core/sd.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio_bus.c linux-libre-2.6.34-gnu1/drivers/mmc/core/sdio_bus.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio_bus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/core/sdio_bus.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/sdio_func.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio.c linux-libre-2.6.34-gnu1/drivers/mmc/core/sdio.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/core/sdio.c	2010-05-16 17:17:36.000000000 -0400
@@ -188,6 +188,40 @@ static int sdio_disable_cd(struct mmc_ca
 }
 
 /*
+ * Devices that remain active during a system suspend are
+ * put back into 1-bit mode.
+ */
+static int sdio_disable_wide(struct mmc_card *card)
+{
+	int ret;
+	u8 ctrl;
+
+	if (!(card->host->caps & MMC_CAP_4_BIT_DATA))
+		return 0;
+
+	if (card->cccr.low_speed && !card->cccr.wide_bus)
+		return 0;
+
+	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl);
+	if (ret)
+		return ret;
+
+	if (!(ctrl & SDIO_BUS_WIDTH_4BIT))
+		return 0;
+
+	ctrl &= ~SDIO_BUS_WIDTH_4BIT;
+	ctrl |= SDIO_BUS_ASYNC_INT;
+
+	ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL);
+	if (ret)
+		return ret;
+
+	mmc_set_bus_width(card->host, MMC_BUS_WIDTH_1);
+
+	return 0;
+}
+
+/*
  * Test if the card supports high-speed mode and, if so, switch to it.
  */
 static int sdio_enable_hs(struct mmc_card *card)
@@ -224,7 +258,7 @@ static int sdio_enable_hs(struct mmc_car
  * we're trying to reinitialise.
  */
 static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
-			      struct mmc_card *oldcard)
+			      struct mmc_card *oldcard, int powered_resume)
 {
 	struct mmc_card *card;
 	int err;
@@ -235,9 +269,11 @@ static int mmc_sdio_init_card(struct mmc
 	/*
 	 * Inform the card of the voltage
 	 */
-	err = mmc_send_io_op_cond(host, host->ocr, &ocr);
-	if (err)
-		goto err;
+	if (!powered_resume) {
+		err = mmc_send_io_op_cond(host, host->ocr, &ocr);
+		if (err)
+			goto err;
+	}
 
 	/*
 	 * For SPI, enable CRC as appropriate.
@@ -262,7 +298,7 @@ static int mmc_sdio_init_card(struct mmc
 	/*
 	 * For native busses:  set card RCA and quit open drain mode.
 	 */
-	if (!mmc_host_is_spi(host)) {
+	if (!powered_resume && !mmc_host_is_spi(host)) {
 		err = mmc_send_relative_addr(host, &card->rca);
 		if (err)
 			goto remove;
@@ -273,7 +309,7 @@ static int mmc_sdio_init_card(struct mmc
 	/*
 	 * Select card, as all following commands rely on that.
 	 */
-	if (!mmc_host_is_spi(host)) {
+	if (!powered_resume && !mmc_host_is_spi(host)) {
 		err = mmc_select_card(card);
 		if (err)
 			goto remove;
@@ -425,6 +461,12 @@ static int mmc_sdio_suspend(struct mmc_h
 		}
 	}
 
+	if (!err && host->pm_flags & MMC_PM_KEEP_POWER) {
+		mmc_claim_host(host);
+		sdio_disable_wide(host->card);
+		mmc_release_host(host);
+	}
+
 	return err;
 }
 
@@ -437,7 +479,13 @@ static int mmc_sdio_resume(struct mmc_ho
 
 	/* Basic card reinitialization. */
 	mmc_claim_host(host);
-	err = mmc_sdio_init_card(host, host->ocr, host->card);
+	err = mmc_sdio_init_card(host, host->ocr, host->card,
+				 (host->pm_flags & MMC_PM_KEEP_POWER));
+	if (!err)
+		/* We may have switched to 1-bit mode during suspend. */
+		err = sdio_enable_wide(host->card);
+	if (!err && host->sdio_irqs)
+		mmc_signal_sdio_irq(host);
 	mmc_release_host(host);
 
 	/*
@@ -507,7 +555,7 @@ int mmc_attach_sdio(struct mmc_host *hos
 	/*
 	 * Detect and init the card.
 	 */
-	err = mmc_sdio_init_card(host, host->ocr, NULL);
+	err = mmc_sdio_init_card(host, host->ocr, NULL, 0);
 	if (err)
 		goto err;
 	card = host->card;
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio_cis.c linux-libre-2.6.34-gnu1/drivers/mmc/core/sdio_cis.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio_cis.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/core/sdio_cis.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio_io.c linux-libre-2.6.34-gnu1/drivers/mmc/core/sdio_io.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio_io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/core/sdio_io.c	2010-05-16 17:17:36.000000000 -0400
@@ -189,7 +189,12 @@ static inline unsigned int sdio_max_byte
 {
 	unsigned mval =	min(func->card->host->max_seg_size,
 			    func->card->host->max_blk_size);
-	mval = min(mval, func->max_blksize);
+
+	if (mmc_blksz_for_byte_mode(func->card))
+		mval = min(mval, func->cur_blksize);
+	else
+		mval = min(mval, func->max_blksize);
+
 	return min(mval, 512u); /* maximum size for byte mode */
 }
 
@@ -635,3 +640,52 @@ void sdio_f0_writeb(struct sdio_func *fu
 		*err_ret = ret;
 }
 EXPORT_SYMBOL_GPL(sdio_f0_writeb);
+
+/**
+ *	sdio_get_host_pm_caps - get host power management capabilities
+ *	@func: SDIO function attached to host
+ *
+ *	Returns a capability bitmask corresponding to power management
+ *	features supported by the host controller that the card function
+ *	might rely upon during a system suspend.  The host doesn't need
+ *	to be claimed, nor the function active, for this information to be
+ *	obtained.
+ */
+mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func)
+{
+	BUG_ON(!func);
+	BUG_ON(!func->card);
+
+	return func->card->host->pm_caps;
+}
+EXPORT_SYMBOL_GPL(sdio_get_host_pm_caps);
+
+/**
+ *	sdio_set_host_pm_flags - set wanted host power management capabilities
+ *	@func: SDIO function attached to host
+ *
+ *	Set a capability bitmask corresponding to wanted host controller
+ *	power management features for the upcoming suspend state.
+ *	This must be called, if needed, each time the suspend method of
+ *	the function driver is called, and must contain only bits that
+ *	were returned by sdio_get_host_pm_caps().
+ *	The host doesn't need to be claimed, nor the function active,
+ *	for this information to be set.
+ */
+int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags)
+{
+	struct mmc_host *host;
+
+	BUG_ON(!func);
+	BUG_ON(!func->card);
+
+	host = func->card->host;
+
+	if (flags & ~host->pm_caps)
+		return -EINVAL;
+
+	/* function suspend methods are serialized, hence no lock needed */
+	host->pm_flags |= flags;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags);
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio_ops.c linux-libre-2.6.34-gnu1/drivers/mmc/core/sdio_ops.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio_ops.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/core/sdio_ops.c	2010-05-16 17:17:36.000000000 -0400
@@ -67,13 +67,13 @@ int mmc_send_io_op_cond(struct mmc_host
 	return err;
 }
 
-int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
-	unsigned addr, u8 in, u8* out)
+static int mmc_io_rw_direct_host(struct mmc_host *host, int write, unsigned fn,
+	unsigned addr, u8 in, u8 *out)
 {
 	struct mmc_command cmd;
 	int err;
 
-	BUG_ON(!card);
+	BUG_ON(!host);
 	BUG_ON(fn > 7);
 
 	/* sanity check */
@@ -90,11 +90,11 @@ int mmc_io_rw_direct(struct mmc_card *ca
 	cmd.arg |= in;
 	cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC;
 
-	err = mmc_wait_for_cmd(card->host, &cmd, 0);
+	err = mmc_wait_for_cmd(host, &cmd, 0);
 	if (err)
 		return err;
 
-	if (mmc_host_is_spi(card->host)) {
+	if (mmc_host_is_spi(host)) {
 		/* host driver already reported errors */
 	} else {
 		if (cmd.resp[0] & R5_ERROR)
@@ -106,7 +106,7 @@ int mmc_io_rw_direct(struct mmc_card *ca
 	}
 
 	if (out) {
-		if (mmc_host_is_spi(card->host))
+		if (mmc_host_is_spi(host))
 			*out = (cmd.resp[0] >> 8) & 0xFF;
 		else
 			*out = cmd.resp[0] & 0xFF;
@@ -115,6 +115,13 @@ int mmc_io_rw_direct(struct mmc_card *ca
 	return 0;
 }
 
+int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
+	unsigned addr, u8 in, u8 *out)
+{
+	BUG_ON(!card);
+	return mmc_io_rw_direct_host(card->host, write, fn, addr, in, out);
+}
+
 int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
 	unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz)
 {
@@ -182,3 +189,20 @@ int mmc_io_rw_extended(struct mmc_card *
 	return 0;
 }
 
+int sdio_reset(struct mmc_host *host)
+{
+	int ret;
+	u8 abort;
+
+	/* SDIO Simplified Specification V2.0, 4.4 Reset for SDIO */
+
+	ret = mmc_io_rw_direct_host(host, 0, 0, SDIO_CCCR_ABORT, 0, &abort);
+	if (ret)
+		abort = 0x08;
+	else
+		abort |= 0x08;
+
+	ret = mmc_io_rw_direct_host(host, 1, 0, SDIO_CCCR_ABORT, abort, NULL);
+	return ret;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio_ops.h linux-libre-2.6.34-gnu1/drivers/mmc/core/sdio_ops.h
--- linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio_ops.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/core/sdio_ops.h	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@ int mmc_io_rw_direct(struct mmc_card *ca
 	unsigned addr, u8 in, u8* out);
 int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
 	unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz);
+int sdio_reset(struct mmc_host *host);
 
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/at91_mci.c linux-libre-2.6.34-gnu1/drivers/mmc/host/at91_mci.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/at91_mci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/at91_mci.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,6 +65,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
 #include <linux/atmel_pdc.h>
+#include <linux/gfp.h>
 
 #include <linux/mmc/host.h>
 
@@ -78,6 +79,17 @@
 
 #define DRIVER_NAME "at91_mci"
 
+static inline int at91mci_is_mci1rev2xx(void)
+{
+	return (   cpu_is_at91sam9260()
+		|| cpu_is_at91sam9263()
+		|| cpu_is_at91cap9()
+		|| cpu_is_at91sam9rl()
+		|| cpu_is_at91sam9g10()
+		|| cpu_is_at91sam9g20()
+		);
+}
+
 #define FL_SENT_COMMAND	(1 << 0)
 #define FL_SENT_STOP	(1 << 1)
 
@@ -88,6 +100,10 @@
 #define at91_mci_read(host, reg)	__raw_readl((host)->baseaddr + (reg))
 #define at91_mci_write(host, reg, val)	__raw_writel((val), (host)->baseaddr + (reg))
 
+#define MCI_BLKSIZE 		512
+#define MCI_MAXBLKSIZE 		4095
+#define MCI_BLKATONCE 		256
+#define MCI_BUFSIZE 		(MCI_BLKSIZE * MCI_BLKATONCE)
 
 /*
  * Low level type for this driver
@@ -200,8 +216,8 @@ static inline void at91_mci_sg_to_dma(st
 	size = data->blksz * data->blocks;
 	len = data->sg_len;
 
-	/* AT91SAM926[0/3] Data Write Operation and number of bytes erratum */
-	if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
+	/* MCI1 rev2xx Data Write Operation and number of bytes erratum */
+	if (at91mci_is_mci1rev2xx())
 		if (host->total_length == 12)
 			memset(dmabuf, 0, 12);
 
@@ -227,8 +243,10 @@ static inline void at91_mci_sg_to_dma(st
 			for (index = 0; index < (amount / 4); index++)
 				*dmabuf++ = swab32(sgbuffer[index]);
 		} else {
-			memcpy(dmabuf, sgbuffer, amount);
-			dmabuf += amount;
+			char *tmpv = (char *)dmabuf;
+			memcpy(tmpv, sgbuffer, amount);
+			tmpv += amount;
+			dmabuf = (unsigned *)tmpv;
 		}
 
 		kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
@@ -245,80 +263,14 @@ static inline void at91_mci_sg_to_dma(st
 }
 
 /*
- * Prepare a dma read
- */
-static void at91_mci_pre_dma_read(struct at91mci_host *host)
-{
-	int i;
-	struct scatterlist *sg;
-	struct mmc_command *cmd;
-	struct mmc_data *data;
-
-	pr_debug("pre dma read\n");
-
-	cmd = host->cmd;
-	if (!cmd) {
-		pr_debug("no command\n");
-		return;
-	}
-
-	data = cmd->data;
-	if (!data) {
-		pr_debug("no data\n");
-		return;
-	}
-
-	for (i = 0; i < 2; i++) {
-		/* nothing left to transfer */
-		if (host->transfer_index >= data->sg_len) {
-			pr_debug("Nothing left to transfer (index = %d)\n", host->transfer_index);
-			break;
-		}
-
-		/* Check to see if this needs filling */
-		if (i == 0) {
-			if (at91_mci_read(host, ATMEL_PDC_RCR) != 0) {
-				pr_debug("Transfer active in current\n");
-				continue;
-			}
-		}
-		else {
-			if (at91_mci_read(host, ATMEL_PDC_RNCR) != 0) {
-				pr_debug("Transfer active in next\n");
-				continue;
-			}
-		}
-
-		/* Setup the next transfer */
-		pr_debug("Using transfer index %d\n", host->transfer_index);
-
-		sg = &data->sg[host->transfer_index++];
-		pr_debug("sg = %p\n", sg);
-
-		sg->dma_address = dma_map_page(NULL, sg_page(sg), sg->offset, sg->length, DMA_FROM_DEVICE);
-
-		pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length);
-
-		if (i == 0) {
-			at91_mci_write(host, ATMEL_PDC_RPR, sg->dma_address);
-			at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
-		}
-		else {
-			at91_mci_write(host, ATMEL_PDC_RNPR, sg->dma_address);
-			at91_mci_write(host, ATMEL_PDC_RNCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
-		}
-	}
-
-	pr_debug("pre dma read done\n");
-}
-
-/*
  * Handle after a dma read
  */
 static void at91_mci_post_dma_read(struct at91mci_host *host)
 {
 	struct mmc_command *cmd;
 	struct mmc_data *data;
+	unsigned int len, i, size;
+	unsigned *dmabuf = host->buffer;
 
 	pr_debug("post dma read\n");
 
@@ -334,42 +286,39 @@ static void at91_mci_post_dma_read(struc
 		return;
 	}
 
-	while (host->in_use_index < host->transfer_index) {
-		struct scatterlist *sg;
+	size = data->blksz * data->blocks;
+	len = data->sg_len;
 
-		pr_debug("finishing index %d\n", host->in_use_index);
+	at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX);
+	at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
 
-		sg = &data->sg[host->in_use_index++];
+	for (i = 0; i < len; i++) {
+		struct scatterlist *sg;
+		int amount;
+		unsigned int *sgbuffer;
 
-		pr_debug("Unmapping page %08X\n", sg->dma_address);
+		sg = &data->sg[i];
 
-		dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE);
+		sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
+		amount = min(size, sg->length);
+		size -= amount;
 
 		if (cpu_is_at91rm9200()) {	/* AT91RM9200 errata */
-			unsigned int *buffer;
 			int index;
-
-			/* Swap the contents of the buffer */
-			buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
-			pr_debug("buffer = %p, length = %d\n", buffer, sg->length);
-
-			for (index = 0; index < (sg->length / 4); index++)
-				buffer[index] = swab32(buffer[index]);
-
-			kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
+			for (index = 0; index < (amount / 4); index++)
+				sgbuffer[index] = swab32(*dmabuf++);
+		} else {
+			char *tmpv = (char *)dmabuf;
+			memcpy(sgbuffer, tmpv, amount);
+			tmpv += amount;
+			dmabuf = (unsigned *)tmpv;
 		}
 
-		flush_dcache_page(sg_page(sg));
-
-		data->bytes_xfered += sg->length;
-	}
-
-	/* Is there another transfer to trigger? */
-	if (host->transfer_index < data->sg_len)
-		at91_mci_pre_dma_read(host);
-	else {
-		at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX);
-		at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
+		flush_kernel_dcache_page(sg_page(sg));
+		kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
+		data->bytes_xfered += amount;
+		if (size == 0)
+			break;
 	}
 
 	pr_debug("post dma read done\n");
@@ -461,7 +410,7 @@ static void at91_mci_enable(struct at91m
 	at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
 	mr = AT91_MCI_PDCMODE | 0x34a;
 
-	if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
+	if (at91mci_is_mci1rev2xx())
 		mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF;
 
 	at91_mci_write(host, AT91_MCI_MR, mr);
@@ -602,10 +551,14 @@ static void at91_mci_send_command(struct
 				/*
 				 * Handle a read
 				 */
-				host->buffer = NULL;
 				host->total_length = 0;
 
-				at91_mci_pre_dma_read(host);
+				at91_mci_write(host, ATMEL_PDC_RPR, host->physical_address);
+				at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ?
+					(blocks * block_length) : (blocks * block_length) / 4);
+				at91_mci_write(host, ATMEL_PDC_RNPR, 0);
+				at91_mci_write(host, ATMEL_PDC_RNCR, 0);
+
 				ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
 			}
 			else {
@@ -614,27 +567,15 @@ static void at91_mci_send_command(struct
 				 */
 				host->total_length = block_length * blocks;
 				/*
-				 * AT91SAM926[0/3] Data Write Operation and
+				 * MCI1 rev2xx Data Write Operation and
 				 * number of bytes erratum
 				 */
-				if (cpu_is_at91sam9260 () || cpu_is_at91sam9263())
+				if (at91mci_is_mci1rev2xx())
 					if (host->total_length < 12)
 						host->total_length = 12;
 
-				host->buffer = kmalloc(host->total_length, GFP_KERNEL);
-				if (!host->buffer) {
-					pr_debug("Can't alloc tx buffer\n");
-					cmd->error = -ENOMEM;
-					mmc_request_done(host->mmc, host->request);
-					return;
-				}
-
 				at91_mci_sg_to_dma(host, data);
 
-				host->physical_address = dma_map_single(NULL,
-						host->buffer, host->total_length,
-						DMA_TO_DEVICE);
-
 				pr_debug("Transmitting %d bytes\n", host->total_length);
 
 				at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
@@ -701,14 +642,6 @@ static void at91_mci_completed_command(s
 	cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2));
 	cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3));
 
-	if (host->buffer) {
-		dma_unmap_single(NULL,
-				host->physical_address, host->total_length,
-				DMA_TO_DEVICE);
-		kfree(host->buffer);
-		host->buffer = NULL;
-	}
-
 	pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n",
 		 status, at91_mci_read(host, AT91_MCI_SR),
 		 cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
@@ -754,7 +687,8 @@ static void at91_mci_request(struct mmc_
 	host->request = mrq;
 	host->flags = 0;
 
-	mod_timer(&host->timer, jiffies +  HZ);
+	/* more than 1s timeout needed with slow SD cards */
+	mod_timer(&host->timer, jiffies +  msecs_to_jiffies(2000));
 
 	at91_mci_process_next(host);
 }
@@ -942,7 +876,8 @@ static irqreturn_t at91_mmc_det_irq(int
 			pr_debug("****** Resetting SD-card bus width ******\n");
 			at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS);
 		}
-		mmc_detect_change(host->mmc, msecs_to_jiffies(100));
+		/* 0.5s needed because of early card detect switch firing */
+		mmc_detect_change(host->mmc, msecs_to_jiffies(500));
 	}
 	return IRQ_HANDLED;
 }
@@ -1006,24 +941,42 @@ static int __init at91_mci_probe(struct
 	mmc->f_min = 375000;
 	mmc->f_max = 25000000;
 	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
-	mmc->caps = MMC_CAP_SDIO_IRQ;
+	mmc->caps = 0;
 
-	mmc->max_blk_size = 4095;
-	mmc->max_blk_count = mmc->max_req_size;
+	mmc->max_blk_size  = MCI_MAXBLKSIZE;
+	mmc->max_blk_count = MCI_BLKATONCE;
+	mmc->max_req_size  = MCI_BUFSIZE;
+	mmc->max_phys_segs = MCI_BLKATONCE;
+	mmc->max_hw_segs   = MCI_BLKATONCE;
+	mmc->max_seg_size  = MCI_BUFSIZE;
 
 	host = mmc_priv(mmc);
 	host->mmc = mmc;
-	host->buffer = NULL;
 	host->bus_mode = 0;
 	host->board = pdev->dev.platform_data;
 	if (host->board->wire4) {
-		if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
+		if (at91mci_is_mci1rev2xx())
 			mmc->caps |= MMC_CAP_4_BIT_DATA;
 		else
 			dev_warn(&pdev->dev, "4 wire bus mode not supported"
 				" - using 1 wire\n");
 	}
 
+	host->buffer = dma_alloc_coherent(&pdev->dev, MCI_BUFSIZE,
+					&host->physical_address, GFP_KERNEL);
+	if (!host->buffer) {
+		ret = -ENOMEM;
+		dev_err(&pdev->dev, "Can't allocate transmit buffer\n");
+		goto fail5;
+	}
+
+	/* Add SDIO capability when available */
+	if (at91mci_is_mci1rev2xx()) {
+		/* at91mci MCI1 rev2xx sdio interrupt erratum */
+		if (host->board->wire4 || !host->board->slot_b)
+			mmc->caps |= MMC_CAP_SDIO_IRQ;
+	}
+
 	/*
 	 * Reserve GPIOs ... board init code makes sure these pins are set
 	 * up as GPIOs with the right direction (input, except for vcc)
@@ -1032,7 +985,7 @@ static int __init at91_mci_probe(struct
 		ret = gpio_request(host->board->det_pin, "mmc_detect");
 		if (ret < 0) {
 			dev_dbg(&pdev->dev, "couldn't claim card detect pin\n");
-			goto fail5;
+			goto fail4b;
 		}
 	}
 	if (host->board->wp_pin) {
@@ -1132,6 +1085,10 @@ fail3:
 fail4:
 	if (host->board->det_pin)
 		gpio_free(host->board->det_pin);
+fail4b:
+	if (host->buffer)
+		dma_free_coherent(&pdev->dev, MCI_BUFSIZE,
+				host->buffer, host->physical_address);
 fail5:
 	mmc_free_host(mmc);
 fail6:
@@ -1154,6 +1111,10 @@ static int __exit at91_mci_remove(struct
 
 	host = mmc_priv(mmc);
 
+	if (host->buffer)
+		dma_free_coherent(&pdev->dev, MCI_BUFSIZE,
+				host->buffer, host->physical_address);
+
 	if (host->board->det_pin) {
 		if (device_can_wakeup(&pdev->dev))
 			free_irq(gpio_to_irq(host->board->det_pin), host);
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/atmel-mci.c linux-libre-2.6.34-gnu1/drivers/mmc/host/atmel-mci.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/atmel-mci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/atmel-mci.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/stat.h>
 
 #include <linux/mmc/host.h>
@@ -265,7 +266,7 @@ static int atmci_req_show(struct seq_fil
 				"CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
 				cmd->opcode, cmd->arg, cmd->flags,
 				cmd->resp[0], cmd->resp[1], cmd->resp[2],
-				cmd->resp[2], cmd->error);
+				cmd->resp[3], cmd->error);
 		if (data)
 			seq_printf(s, "DATA %u / %u * %u flg %x err %d\n",
 				data->bytes_xfered, data->blocks,
@@ -275,7 +276,7 @@ static int atmci_req_show(struct seq_fil
 				"CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
 				stop->opcode, stop->arg, stop->flags,
 				stop->resp[0], stop->resp[1], stop->resp[2],
-				stop->resp[2], stop->error);
+				stop->resp[3], stop->error);
 	}
 
 	spin_unlock_bh(&slot->host->lock);
@@ -568,9 +569,10 @@ static void atmci_dma_cleanup(struct atm
 {
 	struct mmc_data			*data = host->data;
 
-	dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len,
-		     ((data->flags & MMC_DATA_WRITE)
-		      ? DMA_TO_DEVICE : DMA_FROM_DEVICE));
+	if (data)
+		dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len,
+			     ((data->flags & MMC_DATA_WRITE)
+			      ? DMA_TO_DEVICE : DMA_FROM_DEVICE));
 }
 
 static void atmci_stop_dma(struct atmel_mci *host)
@@ -1098,8 +1100,8 @@ static void atmci_command_complete(struc
 			"command error: status=0x%08x\n", status);
 
 		if (cmd->data) {
-			host->data = NULL;
 			atmci_stop_dma(host);
+			host->data = NULL;
 			mci_writel(host, IDR, MCI_NOTBUSY
 					| MCI_TXRDY | MCI_RXRDY
 					| ATMCI_DATA_ERROR_FLAGS);
@@ -1292,6 +1294,7 @@ static void atmci_tasklet_func(unsigned
 			} else {
 				data->bytes_xfered = data->blocks * data->blksz;
 				data->error = 0;
+				mci_writel(host, IDR, ATMCI_DATA_ERROR_FLAGS);
 			}
 
 			if (!data->stop) {
@@ -1750,13 +1753,13 @@ static int __init atmci_probe(struct pla
 	ret = -ENODEV;
 	if (pdata->slot[0].bus_width) {
 		ret = atmci_init_slot(host, &pdata->slot[0],
-				MCI_SDCSEL_SLOT_A, 0);
+				0, MCI_SDCSEL_SLOT_A);
 		if (!ret)
 			nr_slots++;
 	}
 	if (pdata->slot[1].bus_width) {
 		ret = atmci_init_slot(host, &pdata->slot[1],
-				MCI_SDCSEL_SLOT_B, 1);
+				1, MCI_SDCSEL_SLOT_B);
 		if (!ret)
 			nr_slots++;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/au1xmmc.c linux-libre-2.6.34-gnu1/drivers/mmc/host/au1xmmc.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/au1xmmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/au1xmmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@
 #include <linux/scatterlist.h>
 #include <linux/leds.h>
 #include <linux/mmc/host.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/mach-au1x00/au1000.h>
@@ -650,11 +651,11 @@ static int au1xmmc_prepare_data(struct a
 				flags = DDMA_FLAGS_IE;
 
 			if (host->flags & HOST_F_XMIT) {
-				ret = au1xxx_dbdma_put_source_flags(channel,
-					(void *)sg_virt(sg), len, flags);
+				ret = au1xxx_dbdma_put_source(channel,
+					sg_phys(sg), len, flags);
 			} else {
-				ret = au1xxx_dbdma_put_dest_flags(channel,
-					(void *)sg_virt(sg), len, flags);
+				ret = au1xxx_dbdma_put_dest(channel,
+					sg_phys(sg), len, flags);
 			}
 
 			if (!ret)
@@ -1017,6 +1018,10 @@ static int __devinit au1xmmc_probe(struc
 	} else
 		mmc->caps |= MMC_CAP_NEEDS_POLL;
 
+	/* platform may not be able to use all advertised caps */
+	if (host->platdata)
+		mmc->caps &= ~(host->platdata->mask_host_caps);
+
 	tasklet_init(&host->data_task, au1xmmc_tasklet_data,
 			(unsigned long)host);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/bfin_sdh.c linux-libre-2.6.34-gnu1/drivers/mmc/host/bfin_sdh.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/bfin_sdh.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/bfin_sdh.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/mmc/host.h>
 #include <linux/proc_fs.h>
+#include <linux/gfp.h>
 
 #include <asm/cacheflush.h>
 #include <asm/dma.h>
@@ -115,7 +116,7 @@ static int sdh_setup_data(struct sdh_hos
 	unsigned int length;
 	unsigned int data_ctl;
 	unsigned int dma_cfg;
-	struct scatterlist *sg;
+	unsigned int cycle_ns, timeout;
 
 	dev_dbg(mmc_dev(host->mmc), "%s enter flags: 0x%x\n", __func__, data->flags);
 	host->data = data;
@@ -136,8 +137,11 @@ static int sdh_setup_data(struct sdh_hos
 	data_ctl |= ((ffs(data->blksz) - 1) << 4);
 
 	bfin_write_SDH_DATA_CTL(data_ctl);
-
-	bfin_write_SDH_DATA_TIMER(0xFFFF);
+	/* the time of a host clock period in ns */
+	cycle_ns = 1000000000 / (get_sclk() / (2 * (host->clk_div + 1)));
+	timeout = data->timeout_ns / cycle_ns;
+	timeout += data->timeout_clks;
+	bfin_write_SDH_DATA_TIMER(timeout);
 	SSYNC();
 
 	if (data->flags & MMC_DATA_READ) {
@@ -151,6 +155,7 @@ static int sdh_setup_data(struct sdh_hos
 #if defined(CONFIG_BF54x)
 	dma_cfg |= DMAFLOW_ARRAY | NDSIZE_5 | RESTART | WDSIZE_32 | DMAEN;
 	{
+		struct scatterlist *sg;
 		int i;
 		for_each_sg(data->sg, sg, host->dma_len, i) {
 			host->sg_cpu[i].start_addr = sg_dma_address(sg);
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/cb710-mmc.c linux-libre-2.6.34-gnu1/drivers/mmc/host/cb710-mmc.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/cb710-mmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/cb710-mmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,6 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include "cb710-mmc.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/davinci_mmc.c linux-libre-2.6.34-gnu1/drivers/mmc/host/davinci_mmc.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/davinci_mmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/davinci_mmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -73,6 +73,7 @@
 /* DAVINCI_MMCCTL definitions */
 #define MMCCTL_DATRST         (1 << 0)
 #define MMCCTL_CMDRST         (1 << 1)
+#define MMCCTL_WIDTH_8_BIT    (1 << 8)
 #define MMCCTL_WIDTH_4_BIT    (1 << 2)
 #define MMCCTL_DATEG_DISABLED (0 << 6)
 #define MMCCTL_DATEG_RISING   (1 << 6)
@@ -791,22 +792,42 @@ static void calculate_clk_divider(struct
 
 static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
-	unsigned int mmc_pclk = 0;
 	struct mmc_davinci_host *host = mmc_priv(mmc);
 
-	mmc_pclk = host->mmc_input_clk;
 	dev_dbg(mmc_dev(host->mmc),
 		"clock %dHz busmode %d powermode %d Vdd %04x\n",
 		ios->clock, ios->bus_mode, ios->power_mode,
 		ios->vdd);
-	if (ios->bus_width == MMC_BUS_WIDTH_4) {
-		dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n");
-		writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_WIDTH_4_BIT,
-			host->base + DAVINCI_MMCCTL);
-	} else {
-		dev_dbg(mmc_dev(host->mmc), "Disabling 4 bit mode\n");
-		writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_WIDTH_4_BIT,
+
+	switch (ios->bus_width) {
+	case MMC_BUS_WIDTH_8:
+		dev_dbg(mmc_dev(host->mmc), "Enabling 8 bit mode\n");
+		writel((readl(host->base + DAVINCI_MMCCTL) &
+			~MMCCTL_WIDTH_4_BIT) | MMCCTL_WIDTH_8_BIT,
 			host->base + DAVINCI_MMCCTL);
+		break;
+	case MMC_BUS_WIDTH_4:
+		dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n");
+		if (host->version == MMC_CTLR_VERSION_2)
+			writel((readl(host->base + DAVINCI_MMCCTL) &
+				~MMCCTL_WIDTH_8_BIT) | MMCCTL_WIDTH_4_BIT,
+				host->base + DAVINCI_MMCCTL);
+		else
+			writel(readl(host->base + DAVINCI_MMCCTL) |
+				MMCCTL_WIDTH_4_BIT,
+				host->base + DAVINCI_MMCCTL);
+		break;
+	case MMC_BUS_WIDTH_1:
+		dev_dbg(mmc_dev(host->mmc), "Enabling 1 bit mode\n");
+		if (host->version == MMC_CTLR_VERSION_2)
+			writel(readl(host->base + DAVINCI_MMCCTL) &
+				~(MMCCTL_WIDTH_8_BIT | MMCCTL_WIDTH_4_BIT),
+				host->base + DAVINCI_MMCCTL);
+		else
+			writel(readl(host->base + DAVINCI_MMCCTL) &
+				~MMCCTL_WIDTH_4_BIT,
+				host->base + DAVINCI_MMCCTL);
+		break;
 	}
 
 	calculate_clk_divider(mmc, ios);
@@ -1189,10 +1210,14 @@ static int __init davinci_mmcsd_probe(st
 
 	/* REVISIT:  someday, support IRQ-driven card detection.  */
 	mmc->caps |= MMC_CAP_NEEDS_POLL;
+	mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
 
-	if (!pdata || pdata->wires == 4 || pdata->wires == 0)
+	if (pdata && (pdata->wires == 4 || pdata->wires == 0))
 		mmc->caps |= MMC_CAP_4_BIT_DATA;
 
+	if (pdata && (pdata->wires == 8))
+		mmc->caps |= (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA);
+
 	host->version = pdata->version;
 
 	mmc->ops = &mmc_davinci_ops;
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/Kconfig linux-libre-2.6.34-gnu1/drivers/mmc/host/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -69,20 +69,16 @@ config MMC_SDHCI_PCI
 	  If unsure, say N.
 
 config MMC_RICOH_MMC
-	tristate "Ricoh MMC Controller Disabler  (EXPERIMENTAL)"
+	bool "Ricoh MMC Controller Disabler  (EXPERIMENTAL)"
 	depends on MMC_SDHCI_PCI
 	help
-	  This selects the disabler for the Ricoh MMC Controller. This
+	  This adds a pci quirk to disable Ricoh MMC Controller. This
 	  proprietary controller is unnecessary because the SDHCI driver
 	  supports MMC cards on the SD controller, but if it is not
 	  disabled, it will steal the MMC cards away - rendering them
-	  useless. It is safe to select this driver even if you don't
+	  useless. It is safe to select this even if you don't
 	  have a Ricoh based card reader.
 
-
-	  To compile this driver as a module, choose M here:
-	  the module will be called ricoh_mmc.
-
 	  If unsure, say Y.
 
 config MMC_SDHCI_OF
@@ -193,6 +189,7 @@ config MMC_AU1X
 
 choice
 	prompt "Atmel SD/MMC Driver"
+	depends on AVR32 || ARCH_AT91
 	default MMC_ATMELMCI if AVR32
 	help
 	  Choose which driver to use for the Atmel MCI Silicon
@@ -368,7 +365,7 @@ config MMC_SDRICOH_CS
 
 config MMC_TMIO
 	tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"
-	depends on MFD_TMIO || MFD_ASIC3 || SUPERH
+	depends on MFD_TMIO || MFD_ASIC3 || MFD_SH_MOBILE_SDHI
 	help
 	  This provides support for the SD/MMC cell found in TC6393XB,
 	  T7L66XB and also HTC ASIC3
@@ -399,7 +396,7 @@ config MMC_VIA_SDMMC
 
 config SDH_BFIN
 	tristate "Blackfin Secure Digital Host support"
-	depends on MMC && ((BF54x && !BF544) || (BF51x && !BF512))
+	depends on (BF54x && !BF544) || (BF51x && !BF512)
 	help
 	  If you say yes here you will get support for the Blackfin on-chip
 	  Secure Digital Host interface.  This includes support for MMC and
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/Makefile linux-libre-2.6.34-gnu1/drivers/mmc/host/Makefile
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@ obj-$(CONFIG_MMC_IMX)		+= imxmmc.o
 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_PLTFM)	+= sdhci-pltfm.o
 obj-$(CONFIG_MMC_SDHCI_S3C)	+= sdhci-s3c.o
 obj-$(CONFIG_MMC_WBSD)		+= wbsd.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/mmci.c linux-libre-2.6.34-gnu1/drivers/mmc/host/mmci.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/mmci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/mmci.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
  *  linux/drivers/mmc/host/mmci.c - ARM PrimeCell MMCI PL180/1 driver
  *
  *  Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
+ *  Copyright (C) 2010 ST-Ericsson 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
@@ -34,9 +35,6 @@
 
 #define DRIVER_NAME "mmci-pl18x"
 
-#define DBG(host,fmt,args...)	\
-	pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args)
-
 static unsigned int fmax = 515633;
 
 /*
@@ -105,8 +103,8 @@ static void mmci_start_data(struct mmci_
 	void __iomem *base;
 	int blksz_bits;
 
-	DBG(host, "blksz %04x blks %04x flags %08x\n",
-	    data->blksz, data->blocks, data->flags);
+	dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n",
+		data->blksz, data->blocks, data->flags);
 
 	host->data = data;
 	host->size = data->blksz;
@@ -155,7 +153,7 @@ mmci_start_command(struct mmci_host *hos
 {
 	void __iomem *base = host->base;
 
-	DBG(host, "op %02x arg %08x flags %08x\n",
+	dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n",
 	    cmd->opcode, cmd->arg, cmd->flags);
 
 	if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) {
@@ -184,8 +182,20 @@ mmci_data_irq(struct mmci_host *host, st
 {
 	if (status & MCI_DATABLOCKEND) {
 		host->data_xfered += data->blksz;
+#ifdef CONFIG_ARCH_U300
+		/*
+		 * On the U300 some signal or other is
+		 * badly routed so that a data write does
+		 * not properly terminate with a MCI_DATAEND
+		 * status flag. This quirk will make writes
+		 * work again.
+		 */
+		if (data->flags & MMC_DATA_WRITE)
+			status |= MCI_DATAEND;
+#endif
 	}
 	if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
+		dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status);
 		if (status & MCI_DATACRCFAIL)
 			data->error = -EILSEQ;
 		else if (status & MCI_DATATIMEOUT)
@@ -307,7 +317,7 @@ static irqreturn_t mmci_pio_irq(int irq,
 
 	status = readl(base + MMCISTATUS);
 
-	DBG(host, "irq1 %08x\n", status);
+	dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status);
 
 	do {
 		unsigned long flags;
@@ -401,7 +411,7 @@ static irqreturn_t mmci_irq(int irq, voi
 		status &= readl(host->base + MMCIMASK0);
 		writel(status, host->base + MMCICLEAR);
 
-		DBG(host, "irq0 %08x\n", status);
+		dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status);
 
 		data = host->data;
 		if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|
@@ -428,8 +438,8 @@ static void mmci_request(struct mmc_host
 	WARN_ON(host->mrq != NULL);
 
 	if (mrq->data && !is_power_of_2(mrq->data->blksz)) {
-		printk(KERN_ERR "%s: Unsupported block size (%d bytes)\n",
-			mmc_hostname(mmc), mrq->data->blksz);
+		dev_err(mmc_dev(mmc), "unsupported block size (%d bytes)\n",
+			mrq->data->blksz);
 		mrq->cmd->error = -EINVAL;
 		mmc_request_done(mmc, mrq);
 		return;
@@ -582,8 +592,8 @@ static int __devinit mmci_probe(struct a
 
 	host->hw_designer = amba_manf(dev);
 	host->hw_revision = amba_rev(dev);
-	DBG(host, "designer ID = 0x%02x\n", host->hw_designer);
-	DBG(host, "revision = 0x%01x\n", host->hw_revision);
+	dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer);
+	dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision);
 
 	host->clk = clk_get(&dev->dev, NULL);
 	if (IS_ERR(host->clk)) {
@@ -608,7 +618,8 @@ static int __devinit mmci_probe(struct a
 		if (ret < 0)
 			goto clk_disable;
 		host->mclk = clk_get_rate(host->clk);
-		DBG(host, "eventual mclk rate: %u Hz\n", host->mclk);
+		dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n",
+			host->mclk);
 	}
 	host->base = ioremap(dev->res.start, resource_size(&dev->res));
 	if (!host->base) {
@@ -619,6 +630,8 @@ static int __devinit mmci_probe(struct a
 	mmc->ops = &mmci_ops;
 	mmc->f_min = (host->mclk + 511) / 512;
 	mmc->f_max = min(host->mclk, fmax);
+	dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
+
 #ifdef CONFIG_REGULATOR
 	/* If we're using the regulator framework, try to fetch a regulator */
 	host->vcc = regulator_get(&dev->dev, "vmmc");
@@ -712,7 +725,7 @@ static int __devinit mmci_probe(struct a
 
 	mmc_add_host(mmc);
 
-	printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n",
+	dev_info(&dev->dev, "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n",
 		mmc_hostname(mmc), amba_rev(dev), amba_config(dev),
 		(unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/mmc_spi.c linux-libre-2.6.34-gnu1/drivers/mmc/host/mmc_spi.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/mmc_spi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/mmc_spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
  */
 #include <linux/sched.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/bio.h>
 #include <linux/dma-mapping.h>
 #include <linux/crc7.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/msm_sdcc.c linux-libre-2.6.34-gnu1/drivers/mmc/host/msm_sdcc.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/msm_sdcc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/msm_sdcc.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/debugfs.h>
 #include <linux/io.h>
 #include <linux/memory.h>
+#include <linux/gfp.h>
 
 #include <asm/cacheflush.h>
 #include <asm/div64.h>
@@ -1250,9 +1251,7 @@ msmsdcc_resume(struct platform_device *d
 
 		if (mmc->card && mmc->card->type != MMC_TYPE_SDIO)
 			mmc_resume_host(mmc);
-			if (host->stat_irq)
-				enable_irq(host->stat_irq);
-		else if (host->stat_irq)
+		if (host->stat_irq)
 			enable_irq(host->stat_irq);
 	}
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/mxcmmc.c linux-libre-2.6.34-gnu1/drivers/mmc/host/mxcmmc.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/mxcmmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/mxcmmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
  *  This is a driver for the SDHC controller found in Freescale MX2/MX3
  *  SoCs. It is basically the same hardware as found on MX1 (imxmmc.c).
  *  Unlike the hardware found on MX1, this hardware just works and does
- *  not need all the quirks found in imxmmc.c, hence the seperate driver.
+ *  not need all the quirks found in imxmmc.c, hence the separate driver.
  *
  *  Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
  *  Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
@@ -708,7 +708,7 @@ static int mxcmci_probe(struct platform_
 	mmc->max_blk_size = 2048;
 	mmc->max_blk_count = 65535;
 	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
-	mmc->max_seg_size = mmc->max_seg_size;
+	mmc->max_seg_size = mmc->max_req_size;
 
 	host = mmc_priv(mmc);
 	host->base = ioremap(r->start, resource_size(r));
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/of_mmc_spi.c linux-libre-2.6.34-gnu1/drivers/mmc/host/of_mmc_spi.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/of_mmc_spi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/of_mmc_spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/omap.c linux-libre-2.6.34-gnu1/drivers/mmc/host/omap.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/omap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/omap.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/clk.h>
 #include <linux/scatterlist.h>
 #include <linux/i2c/tps65010.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/omap_hsmmc.c linux-libre-2.6.34-gnu1/drivers/mmc/host/omap_hsmmc.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/omap_hsmmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/omap_hsmmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,8 @@
 #include <linux/mmc/core.h>
 #include <linux/io.h>
 #include <linux/semaphore.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
 #include <plat/dma.h>
 #include <mach/hardware.h>
 #include <plat/board.h>
@@ -146,6 +148,15 @@ struct omap_hsmmc_host {
 	struct	clk		*fclk;
 	struct	clk		*iclk;
 	struct	clk		*dbclk;
+	/*
+	 * vcc == configured supply
+	 * vcc_aux == optional
+	 *   -	MMC1, supply for DAT4..DAT7
+	 *   -	MMC2/MMC2, external level shifter voltage supply, for
+	 *	chip (SDIO, eMMC, etc) or transceiver (MMC2 only)
+	 */
+	struct	regulator	*vcc;
+	struct	regulator	*vcc_aux;
 	struct	semaphore	sem;
 	struct	work_struct	mmc_carddetect_work;
 	void	__iomem		*base;
@@ -171,10 +182,337 @@ struct omap_hsmmc_host {
 	int			vdd;
 	int			protect_card;
 	int			reqs_blocked;
+	int			use_reg;
 
 	struct	omap_mmc_platform_data	*pdata;
 };
 
+static int omap_hsmmc_card_detect(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);
+}
+
+static int omap_hsmmc_get_wp(struct device *dev, int slot)
+{
+	struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+	/* NOTE: assumes write protect signal is active-high */
+	return gpio_get_value_cansleep(mmc->slots[0].gpio_wp);
+}
+
+static int omap_hsmmc_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);
+}
+
+#ifdef CONFIG_PM
+
+static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot)
+{
+	struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+	disable_irq(mmc->slots[0].card_detect_irq);
+	return 0;
+}
+
+static int omap_hsmmc_resume_cdirq(struct device *dev, int slot)
+{
+	struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+	enable_irq(mmc->slots[0].card_detect_irq);
+	return 0;
+}
+
+#else
+
+#define omap_hsmmc_suspend_cdirq	NULL
+#define omap_hsmmc_resume_cdirq		NULL
+
+#endif
+
+#ifdef CONFIG_REGULATOR
+
+static int omap_hsmmc_1_set_power(struct device *dev, int slot, int power_on,
+				  int vdd)
+{
+	struct omap_hsmmc_host *host =
+		platform_get_drvdata(to_platform_device(dev));
+	int ret;
+
+	if (mmc_slot(host).before_set_reg)
+		mmc_slot(host).before_set_reg(dev, slot, power_on, vdd);
+
+	if (power_on)
+		ret = mmc_regulator_set_ocr(host->vcc, vdd);
+	else
+		ret = mmc_regulator_set_ocr(host->vcc, 0);
+
+	if (mmc_slot(host).after_set_reg)
+		mmc_slot(host).after_set_reg(dev, slot, power_on, vdd);
+
+	return ret;
+}
+
+static int omap_hsmmc_23_set_power(struct device *dev, int slot, int power_on,
+				   int vdd)
+{
+	struct omap_hsmmc_host *host =
+		platform_get_drvdata(to_platform_device(dev));
+	int ret = 0;
+
+	/*
+	 * If we don't see a Vcc regulator, assume it's a fixed
+	 * voltage always-on regulator.
+	 */
+	if (!host->vcc)
+		return 0;
+
+	if (mmc_slot(host).before_set_reg)
+		mmc_slot(host).before_set_reg(dev, slot, power_on, vdd);
+
+	/*
+	 * Assume Vcc regulator 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.
+	 *
+	 * In some cases this regulator won't support enable/disable;
+	 * e.g. it's a fixed rail for a WLAN chip.
+	 *
+	 * In other cases vcc_aux switches interface power.  Example, for
+	 * eMMC cards it represents VccQ.  Sometimes transceivers or SDIO
+	 * chips/cards need an interface voltage rail too.
+	 */
+	if (power_on) {
+		ret = mmc_regulator_set_ocr(host->vcc, vdd);
+		/* Enable interface voltage rail, if needed */
+		if (ret == 0 && host->vcc_aux) {
+			ret = regulator_enable(host->vcc_aux);
+			if (ret < 0)
+				ret = mmc_regulator_set_ocr(host->vcc, 0);
+		}
+	} else {
+		if (host->vcc_aux)
+			ret = regulator_disable(host->vcc_aux);
+		if (ret == 0)
+			ret = mmc_regulator_set_ocr(host->vcc, 0);
+	}
+
+	if (mmc_slot(host).after_set_reg)
+		mmc_slot(host).after_set_reg(dev, slot, power_on, vdd);
+
+	return ret;
+}
+
+static int omap_hsmmc_1_set_sleep(struct device *dev, int slot, int sleep,
+				  int vdd, int cardsleep)
+{
+	struct omap_hsmmc_host *host =
+		platform_get_drvdata(to_platform_device(dev));
+	int mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL;
+
+	return regulator_set_mode(host->vcc, mode);
+}
+
+static int omap_hsmmc_23_set_sleep(struct device *dev, int slot, int sleep,
+				   int vdd, int cardsleep)
+{
+	struct omap_hsmmc_host *host =
+		platform_get_drvdata(to_platform_device(dev));
+	int err, mode;
+
+	/*
+	 * If we don't see a Vcc regulator, assume it's a fixed
+	 * voltage always-on regulator.
+	 */
+	if (!host->vcc)
+		return 0;
+
+	mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL;
+
+	if (!host->vcc_aux)
+		return regulator_set_mode(host->vcc, mode);
+
+	if (cardsleep) {
+		/* VCC can be turned off if card is asleep */
+		if (sleep)
+			err = mmc_regulator_set_ocr(host->vcc, 0);
+		else
+			err = mmc_regulator_set_ocr(host->vcc, vdd);
+	} else
+		err = regulator_set_mode(host->vcc, mode);
+	if (err)
+		return err;
+
+	if (!mmc_slot(host).vcc_aux_disable_is_sleep)
+		return regulator_set_mode(host->vcc_aux, mode);
+
+	if (sleep)
+		return regulator_disable(host->vcc_aux);
+	else
+		return regulator_enable(host->vcc_aux);
+}
+
+static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
+{
+	struct regulator *reg;
+	int ret = 0;
+
+	switch (host->id) {
+	case OMAP_MMC1_DEVID:
+		/* On-chip level shifting via PBIAS0/PBIAS1 */
+		mmc_slot(host).set_power = omap_hsmmc_1_set_power;
+		mmc_slot(host).set_sleep = omap_hsmmc_1_set_sleep;
+		break;
+	case OMAP_MMC2_DEVID:
+	case OMAP_MMC3_DEVID:
+		/* Off-chip level shifting, or none */
+		mmc_slot(host).set_power = omap_hsmmc_23_set_power;
+		mmc_slot(host).set_sleep = omap_hsmmc_23_set_sleep;
+		break;
+	default:
+		pr_err("MMC%d configuration not supported!\n", host->id);
+		return -EINVAL;
+	}
+
+	reg = regulator_get(host->dev, "vmmc");
+	if (IS_ERR(reg)) {
+		dev_dbg(host->dev, "vmmc regulator missing\n");
+		/*
+		* HACK: until fixed.c regulator is usable,
+		* we don't require a main regulator
+		* for MMC2 or MMC3
+		*/
+		if (host->id == OMAP_MMC1_DEVID) {
+			ret = PTR_ERR(reg);
+			goto err;
+		}
+	} else {
+		host->vcc = reg;
+		mmc_slot(host).ocr_mask = mmc_regulator_get_ocrmask(reg);
+
+		/* Allow an aux regulator */
+		reg = regulator_get(host->dev, "vmmc_aux");
+		host->vcc_aux = IS_ERR(reg) ? NULL : reg;
+
+		/*
+		* UGLY HACK:  workaround regulator framework bugs.
+		* When the bootloader leaves a supply active, it's
+		* initialized with zero usecount ... and we can't
+		* disable it without first enabling it.  Until the
+		* framework is fixed, we need a workaround like this
+		* (which is safe for MMC, but not in general).
+		*/
+		if (regulator_is_enabled(host->vcc) > 0) {
+			regulator_enable(host->vcc);
+			regulator_disable(host->vcc);
+		}
+		if (host->vcc_aux) {
+			if (regulator_is_enabled(reg) > 0) {
+				regulator_enable(reg);
+				regulator_disable(reg);
+			}
+		}
+	}
+
+	return 0;
+
+err:
+	mmc_slot(host).set_power = NULL;
+	mmc_slot(host).set_sleep = NULL;
+	return ret;
+}
+
+static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host)
+{
+	regulator_put(host->vcc);
+	regulator_put(host->vcc_aux);
+	mmc_slot(host).set_power = NULL;
+	mmc_slot(host).set_sleep = NULL;
+}
+
+static inline int omap_hsmmc_have_reg(void)
+{
+	return 1;
+}
+
+#else
+
+static inline int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
+{
+	return -EINVAL;
+}
+
+static inline void omap_hsmmc_reg_put(struct omap_hsmmc_host *host)
+{
+}
+
+static inline int omap_hsmmc_have_reg(void)
+{
+	return 0;
+}
+
+#endif
+
+static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata)
+{
+	int ret;
+
+	if (gpio_is_valid(pdata->slots[0].switch_pin)) {
+		pdata->suspend = omap_hsmmc_suspend_cdirq;
+		pdata->resume = omap_hsmmc_resume_cdirq;
+		if (pdata->slots[0].cover)
+			pdata->slots[0].get_cover_state =
+					omap_hsmmc_get_cover_state;
+		else
+			pdata->slots[0].card_detect = omap_hsmmc_card_detect;
+		pdata->slots[0].card_detect_irq =
+				gpio_to_irq(pdata->slots[0].switch_pin);
+		ret = gpio_request(pdata->slots[0].switch_pin, "mmc_cd");
+		if (ret)
+			return ret;
+		ret = gpio_direction_input(pdata->slots[0].switch_pin);
+		if (ret)
+			goto err_free_sp;
+	} else
+		pdata->slots[0].switch_pin = -EINVAL;
+
+	if (gpio_is_valid(pdata->slots[0].gpio_wp)) {
+		pdata->slots[0].get_ro = omap_hsmmc_get_wp;
+		ret = gpio_request(pdata->slots[0].gpio_wp, "mmc_wp");
+		if (ret)
+			goto err_free_cd;
+		ret = gpio_direction_input(pdata->slots[0].gpio_wp);
+		if (ret)
+			goto err_free_wp;
+	} else
+		pdata->slots[0].gpio_wp = -EINVAL;
+
+	return 0;
+
+err_free_wp:
+	gpio_free(pdata->slots[0].gpio_wp);
+err_free_cd:
+	if (gpio_is_valid(pdata->slots[0].switch_pin))
+err_free_sp:
+		gpio_free(pdata->slots[0].switch_pin);
+	return ret;
+}
+
+static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata)
+{
+	if (gpio_is_valid(pdata->slots[0].gpio_wp))
+		gpio_free(pdata->slots[0].gpio_wp);
+	if (gpio_is_valid(pdata->slots[0].switch_pin))
+		gpio_free(pdata->slots[0].switch_pin);
+}
+
 /*
  * Stop clock to the card
  */
@@ -835,21 +1173,16 @@ static void omap_hsmmc_detect(struct wor
 	sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
 
 	if (slot->card_detect)
-		carddetect = slot->card_detect(slot->card_detect_irq);
+		carddetect = slot->card_detect(host->dev, host->slot_id);
 	else {
 		omap_hsmmc_protect_card(host);
 		carddetect = -ENOSYS;
 	}
 
-	if (carddetect) {
+	if (carddetect)
 		mmc_detect_change(host->mmc, (HZ * 200) / 1000);
-	} else {
-		mmc_host_enable(host->mmc);
-		omap_hsmmc_reset_controller_fsm(host, SRD);
-		mmc_host_lazy_disable(host->mmc);
-
+	else
 		mmc_detect_change(host->mmc, (HZ * 50) / 1000);
-	}
 }
 
 /*
@@ -1242,7 +1575,7 @@ static int omap_hsmmc_get_cd(struct mmc_
 
 	if (!mmc_slot(host).card_detect)
 		return -ENOSYS;
-	return mmc_slot(host).card_detect(mmc_slot(host).card_detect_irq);
+	return mmc_slot(host).card_detect(host->dev, host->slot_id);
 }
 
 static int omap_hsmmc_get_ro(struct mmc_host *mmc)
@@ -1311,7 +1644,7 @@ static int omap_hsmmc_enabled_to_disable
 	if (host->power_mode == MMC_POWER_OFF)
 		return 0;
 
-	return msecs_to_jiffies(OMAP_MMC_SLEEP_TIMEOUT);
+	return OMAP_MMC_SLEEP_TIMEOUT;
 }
 
 /* Handler for [DISABLED -> REGSLEEP / CARDSLEEP] transition */
@@ -1347,11 +1680,14 @@ static int omap_hsmmc_disabled_to_sleep(
 	dev_dbg(mmc_dev(host->mmc), "DISABLED -> %s\n",
 		host->dpm_state == CARDSLEEP ? "CARDSLEEP" : "REGSLEEP");
 
+	if (mmc_slot(host).no_off)
+		return 0;
+
 	if ((host->mmc->caps & MMC_CAP_NONREMOVABLE) ||
 	    mmc_slot(host).card_detect ||
 	    (mmc_slot(host).get_cover_state &&
 	     mmc_slot(host).get_cover_state(host->dev, host->slot_id)))
-		return msecs_to_jiffies(OMAP_MMC_OFF_TIMEOUT);
+		return OMAP_MMC_OFF_TIMEOUT;
 
 	return 0;
 }
@@ -1362,6 +1698,9 @@ static int omap_hsmmc_sleep_to_off(struc
 	if (!mmc_try_claim_host(host->mmc))
 		return 0;
 
+	if (mmc_slot(host).no_off)
+		return 0;
+
 	if (!((host->mmc->caps & MMC_CAP_NONREMOVABLE) ||
 	      mmc_slot(host).card_detect ||
 	      (mmc_slot(host).get_cover_state &&
@@ -1616,7 +1955,7 @@ static int __init omap_hsmmc_probe(struc
 	struct mmc_host *mmc;
 	struct omap_hsmmc_host *host = NULL;
 	struct resource *res;
-	int ret = 0, irq;
+	int ret, irq;
 
 	if (pdata == NULL) {
 		dev_err(&pdev->dev, "Platform Data is missing\n");
@@ -1638,10 +1977,14 @@ static int __init omap_hsmmc_probe(struc
 	if (res == NULL)
 		return -EBUSY;
 
+	ret = omap_hsmmc_gpio_init(pdata);
+	if (ret)
+		goto err;
+
 	mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), &pdev->dev);
 	if (!mmc) {
 		ret = -ENOMEM;
-		goto err;
+		goto err_alloc;
 	}
 
 	host		= mmc_priv(mmc);
@@ -1656,7 +1999,7 @@ static int __init omap_hsmmc_probe(struc
 	host->slot_id	= 0;
 	host->mapbase	= res->start;
 	host->base	= ioremap(host->mapbase, SZ_4K);
-	host->power_mode = -1;
+	host->power_mode = MMC_POWER_OFF;
 
 	platform_set_drvdata(pdev, host);
 	INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect);
@@ -1666,6 +2009,13 @@ static int __init omap_hsmmc_probe(struc
 	else
 		mmc->ops	= &omap_hsmmc_ops;
 
+	/*
+	 * If regulator_disable can only put vcc_aux to sleep then there is
+	 * no off state.
+	 */
+	if (mmc_slot(host).vcc_aux_disable_is_sleep)
+		mmc_slot(host).no_off = 1;
+
 	mmc->f_min	= 400000;
 	mmc->f_max	= 52000000;
 
@@ -1781,7 +2131,6 @@ static int __init omap_hsmmc_probe(struc
 		goto err_irq;
 	}
 
-	/* initialize power supplies, gpios, etc */
 	if (pdata->init != NULL) {
 		if (pdata->init(&pdev->dev) != 0) {
 			dev_dbg(mmc_dev(host->mmc),
@@ -1789,6 +2138,14 @@ static int __init omap_hsmmc_probe(struc
 			goto err_irq_cd_init;
 		}
 	}
+
+	if (omap_hsmmc_have_reg() && !mmc_slot(host).set_power) {
+		ret = omap_hsmmc_reg_get(host);
+		if (ret)
+			goto err_reg;
+		host->use_reg = 1;
+	}
+
 	mmc->ocr_avail = mmc_slot(host).ocr_mask;
 
 	/* Request IRQ for card detect */
@@ -1823,19 +2180,22 @@ static int __init omap_hsmmc_probe(struc
 		ret = device_create_file(&mmc->class_dev,
 					&dev_attr_cover_switch);
 		if (ret < 0)
-			goto err_cover_switch;
+			goto err_slot_name;
 	}
 
 	omap_hsmmc_debugfs(mmc);
 
 	return 0;
 
-err_cover_switch:
-	device_remove_file(&mmc->class_dev, &dev_attr_cover_switch);
 err_slot_name:
 	mmc_remove_host(mmc);
-err_irq_cd:
 	free_irq(mmc_slot(host).card_detect_irq, host);
+err_irq_cd:
+	if (host->use_reg)
+		omap_hsmmc_reg_put(host);
+err_reg:
+	if (host->pdata->cleanup)
+		host->pdata->cleanup(&pdev->dev);
 err_irq_cd_init:
 	free_irq(host->irq, host);
 err_irq:
@@ -1847,14 +2207,14 @@ err_irq:
 		clk_disable(host->dbclk);
 		clk_put(host->dbclk);
 	}
-
 err1:
 	iounmap(host->base);
+	platform_set_drvdata(pdev, NULL);
+	mmc_free_host(mmc);
+err_alloc:
+	omap_hsmmc_gpio_free(pdata);
 err:
-	dev_dbg(mmc_dev(host->mmc), "Probe Failed\n");
 	release_mem_region(res->start, res->end - res->start + 1);
-	if (host)
-		mmc_free_host(mmc);
 	return ret;
 }
 
@@ -1866,6 +2226,8 @@ static int omap_hsmmc_remove(struct plat
 	if (host) {
 		mmc_host_enable(host->mmc);
 		mmc_remove_host(host->mmc);
+		if (host->use_reg)
+			omap_hsmmc_reg_put(host);
 		if (host->pdata->cleanup)
 			host->pdata->cleanup(&pdev->dev);
 		free_irq(host->irq, host);
@@ -1884,6 +2246,7 @@ static int omap_hsmmc_remove(struct plat
 
 		mmc_free_host(host->mmc);
 		iounmap(host->base);
+		omap_hsmmc_gpio_free(pdev->dev.platform_data);
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/pxamci.c linux-libre-2.6.34-gnu1/drivers/mmc/host/pxamci.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/pxamci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/pxamci.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/io.h>
 #include <linux/regulator/consumer.h>
 #include <linux/gpio.h>
+#include <linux/gfp.h>
 
 #include <asm/sizes.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/ricoh_mmc.c linux-libre-2.6.34-gnu1/drivers/mmc/host/ricoh_mmc.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/ricoh_mmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/ricoh_mmc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,262 +0,0 @@
-/*
- *  ricoh_mmc.c - Dummy driver to disable the Rioch MMC controller.
- *
- *  Copyright (C) 2007 Philip Langdale, 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 is a conceptually ridiculous driver, but it is required by the way
- * the Ricoh multi-function chips (R5CXXX) work. These chips implement
- * the four main memory card controllers (SD, MMC, MS, xD) and one or both
- * of cardbus or firewire. It happens that they implement SD and MMC
- * support as separate controllers (and PCI functions). The linux SDHCI
- * driver supports MMC cards but the chip detects MMC cards in hardware
- * and directs them to the MMC controller - so the SDHCI driver never sees
- * them. To get around this, we must disable the useless MMC controller.
- * At that point, the SDHCI controller will start seeing them. As a bonus,
- * a detection event occurs immediately, even if the MMC card is already
- * in the reader.
- *
- * It seems to be the case that the relevant PCI registers to deactivate the
- * MMC controller live on PCI function 0, which might be the cardbus controller
- * or the firewire controller, depending on the particular chip in question. As
- * such, it makes what this driver has to do unavoidably ugly. Such is life.
- */
-
-#include <linux/pci.h>
-
-#define DRIVER_NAME "ricoh-mmc"
-
-static const struct pci_device_id pci_ids[] __devinitdata = {
-	{
-		.vendor		= PCI_VENDOR_ID_RICOH,
-		.device		= PCI_DEVICE_ID_RICOH_R5C843,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-	},
-	{ /* end: all zeroes */ },
-};
-
-MODULE_DEVICE_TABLE(pci, pci_ids);
-
-static int ricoh_mmc_disable(struct pci_dev *fw_dev)
-{
-	u8 write_enable;
-	u8 write_target;
-	u8 disable;
-
-	if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) {
-		/* via RL5C476 */
-
-		pci_read_config_byte(fw_dev, 0xB7, &disable);
-		if (disable & 0x02) {
-			printk(KERN_INFO DRIVER_NAME
-				": Controller already disabled. " \
-				"Nothing to do.\n");
-			return -ENODEV;
-		}
-
-		pci_read_config_byte(fw_dev, 0x8E, &write_enable);
-		pci_write_config_byte(fw_dev, 0x8E, 0xAA);
-		pci_read_config_byte(fw_dev, 0x8D, &write_target);
-		pci_write_config_byte(fw_dev, 0x8D, 0xB7);
-		pci_write_config_byte(fw_dev, 0xB7, disable | 0x02);
-		pci_write_config_byte(fw_dev, 0x8E, write_enable);
-		pci_write_config_byte(fw_dev, 0x8D, write_target);
-	} else {
-		/* via R5C832 */
-
-		pci_read_config_byte(fw_dev, 0xCB, &disable);
-		if (disable & 0x02) {
-			printk(KERN_INFO DRIVER_NAME
-			       ": Controller already disabled. " \
-				"Nothing to do.\n");
-			return -ENODEV;
-		}
-
-		pci_read_config_byte(fw_dev, 0xCA, &write_enable);
-		pci_write_config_byte(fw_dev, 0xCA, 0x57);
-		pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
-		pci_write_config_byte(fw_dev, 0xCA, write_enable);
-	}
-
-	printk(KERN_INFO DRIVER_NAME
-	       ": Controller is now disabled.\n");
-
-	return 0;
-}
-
-static int ricoh_mmc_enable(struct pci_dev *fw_dev)
-{
-	u8 write_enable;
-	u8 write_target;
-	u8 disable;
-
-	if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) {
-		/* via RL5C476 */
-
-		pci_read_config_byte(fw_dev, 0x8E, &write_enable);
-		pci_write_config_byte(fw_dev, 0x8E, 0xAA);
-		pci_read_config_byte(fw_dev, 0x8D, &write_target);
-		pci_write_config_byte(fw_dev, 0x8D, 0xB7);
-		pci_read_config_byte(fw_dev, 0xB7, &disable);
-		pci_write_config_byte(fw_dev, 0xB7, disable & ~0x02);
-		pci_write_config_byte(fw_dev, 0x8E, write_enable);
-		pci_write_config_byte(fw_dev, 0x8D, write_target);
-	} else {
-		/* via R5C832 */
-
-		pci_read_config_byte(fw_dev, 0xCA, &write_enable);
-		pci_read_config_byte(fw_dev, 0xCB, &disable);
-		pci_write_config_byte(fw_dev, 0xCA, 0x57);
-		pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
-		pci_write_config_byte(fw_dev, 0xCA, write_enable);
-	}
-
-	printk(KERN_INFO DRIVER_NAME
-	       ": Controller is now re-enabled.\n");
-
-	return 0;
-}
-
-static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
-				     const struct pci_device_id *ent)
-{
-	u8 rev;
-	u8 ctrlfound = 0;
-
-	struct pci_dev *fw_dev = NULL;
-
-	BUG_ON(pdev == NULL);
-	BUG_ON(ent == NULL);
-
-	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev);
-
-	printk(KERN_INFO DRIVER_NAME
-		": Ricoh MMC controller found at %s [%04x:%04x] (rev %x)\n",
-		pci_name(pdev), (int)pdev->vendor, (int)pdev->device,
-		(int)rev);
-
-	while ((fw_dev =
-		pci_get_device(PCI_VENDOR_ID_RICOH,
-			PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) {
-		if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) &&
-		    PCI_FUNC(fw_dev->devfn) == 0 &&
-		    pdev->bus == fw_dev->bus) {
-			if (ricoh_mmc_disable(fw_dev) != 0)
-				return -ENODEV;
-
-			pci_set_drvdata(pdev, fw_dev);
-
-			++ctrlfound;
-			break;
-		}
-	}
-
-	fw_dev = NULL;
-
-	while (!ctrlfound &&
-	    (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH,
-					PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) {
-		if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) &&
-		    PCI_FUNC(fw_dev->devfn) == 0 &&
-		    pdev->bus == fw_dev->bus) {
-			if (ricoh_mmc_disable(fw_dev) != 0)
-				return -ENODEV;
-
-			pci_set_drvdata(pdev, fw_dev);
-
-			++ctrlfound;
-		}
-	}
-
-	if (!ctrlfound) {
-		printk(KERN_WARNING DRIVER_NAME
-		       ": Main Ricoh function not found. Cannot disable controller.\n");
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-static void __devexit ricoh_mmc_remove(struct pci_dev *pdev)
-{
-	struct pci_dev *fw_dev = NULL;
-
-	fw_dev = pci_get_drvdata(pdev);
-	BUG_ON(fw_dev == NULL);
-
-	ricoh_mmc_enable(fw_dev);
-
-	pci_set_drvdata(pdev, NULL);
-}
-
-static int ricoh_mmc_suspend_late(struct pci_dev *pdev, pm_message_t state)
-{
-	struct pci_dev *fw_dev = NULL;
-
-	fw_dev = pci_get_drvdata(pdev);
-	BUG_ON(fw_dev == NULL);
-
-	printk(KERN_INFO DRIVER_NAME ": Suspending.\n");
-
-	ricoh_mmc_enable(fw_dev);
-
-	return 0;
-}
-
-static int ricoh_mmc_resume_early(struct pci_dev *pdev)
-{
-	struct pci_dev *fw_dev = NULL;
-
-	fw_dev = pci_get_drvdata(pdev);
-	BUG_ON(fw_dev == NULL);
-
-	printk(KERN_INFO DRIVER_NAME ": Resuming.\n");
-
-	ricoh_mmc_disable(fw_dev);
-
-	return 0;
-}
-
-static struct pci_driver ricoh_mmc_driver = {
-	.name = 	DRIVER_NAME,
-	.id_table =	pci_ids,
-	.probe = 	ricoh_mmc_probe,
-	.remove =	__devexit_p(ricoh_mmc_remove),
-	.suspend_late =	ricoh_mmc_suspend_late,
-	.resume_early =	ricoh_mmc_resume_early,
-};
-
-/*****************************************************************************\
- *                                                                           *
- * Driver init/exit                                                          *
- *                                                                           *
-\*****************************************************************************/
-
-static int __init ricoh_mmc_drv_init(void)
-{
-	printk(KERN_INFO DRIVER_NAME
-		": Ricoh MMC Controller disabling driver\n");
-	printk(KERN_INFO DRIVER_NAME ": Copyright(c) Philip Langdale\n");
-
-	return pci_register_driver(&ricoh_mmc_driver);
-}
-
-static void __exit ricoh_mmc_drv_exit(void)
-{
-	pci_unregister_driver(&ricoh_mmc_driver);
-}
-
-module_init(ricoh_mmc_drv_init);
-module_exit(ricoh_mmc_drv_exit);
-
-MODULE_AUTHOR("Philip Langdale <philipl@alumni.utexas.net>");
-MODULE_DESCRIPTION("Ricoh MMC Controller disabling driver");
-MODULE_LICENSE("GPL");
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/s3cmci.c linux-libre-2.6.34-gnu1/drivers/mmc/host/s3cmci.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/s3cmci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/s3cmci.c	2010-05-16 17:17:36.000000000 -0400
@@ -1179,7 +1179,7 @@ static int s3cmci_card_present(struct mm
 	struct s3c24xx_mci_pdata *pdata = host->pdata;
 	int ret;
 
-	if (pdata->gpio_detect == 0)
+	if (pdata->no_detect)
 		return -ENOSYS;
 
 	ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1;
@@ -1360,6 +1360,8 @@ static struct mmc_host_ops s3cmci_ops =
 static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
 	/* This is currently here to avoid a number of if (host->pdata)
 	 * checks. Any zero fields to ensure reasonable defaults are picked. */
+	 .no_wprotect = 1,
+	 .no_detect = 1,
 };
 
 #ifdef CONFIG_CPU_FREQ
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci.c linux-libre-2.6.34-gnu1/drivers/mmc/host/sdhci.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/sdhci.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/highmem.h>
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <linux/scatterlist.h>
 
 #include <linux/leds.h>
@@ -174,20 +175,31 @@ static void sdhci_reset(struct sdhci_hos
 		sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
 }
 
-static void sdhci_init(struct sdhci_host *host)
+static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios);
+
+static void sdhci_init(struct sdhci_host *host, int soft)
 {
-	sdhci_reset(host, SDHCI_RESET_ALL);
+	if (soft)
+		sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
+	else
+		sdhci_reset(host, SDHCI_RESET_ALL);
 
 	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_DATA_END | SDHCI_INT_RESPONSE);
+
+	if (soft) {
+		/* force clock reconfiguration */
+		host->clock = 0;
+		sdhci_set_ios(host->mmc, &host->mmc->ios);
+	}
 }
 
 static void sdhci_reinit(struct sdhci_host *host)
 {
-	sdhci_init(host);
+	sdhci_init(host, 0);
 	sdhci_enable_card_detection(host);
 }
 
@@ -376,6 +388,20 @@ static void sdhci_kunmap_atomic(void *bu
 	local_irq_restore(*flags);
 }
 
+static void sdhci_set_adma_desc(u8 *desc, u32 addr, int len, unsigned cmd)
+{
+	__le32 *dataddr = (__le32 __force *)(desc + 4);
+	__le16 *cmdlen = (__le16 __force *)desc;
+
+	/* SDHCI specification says ADMA descriptors should be 4 byte
+	 * aligned, so using 16 or 32bit operations should be safe. */
+
+	cmdlen[0] = cpu_to_le16(cmd);
+	cmdlen[1] = cpu_to_le16(len);
+
+	dataddr[0] = cpu_to_le32(addr);
+}
+
 static int sdhci_adma_table_pre(struct sdhci_host *host,
 	struct mmc_data *data)
 {
@@ -443,19 +469,11 @@ static int sdhci_adma_table_pre(struct s
 				sdhci_kunmap_atomic(buffer, &flags);
 			}
 
-			desc[7] = (align_addr >> 24) & 0xff;
-			desc[6] = (align_addr >> 16) & 0xff;
-			desc[5] = (align_addr >> 8) & 0xff;
-			desc[4] = (align_addr >> 0) & 0xff;
+			/* tran, valid */
+			sdhci_set_adma_desc(desc, align_addr, offset, 0x21);
 
 			BUG_ON(offset > 65536);
 
-			desc[3] = (offset >> 8) & 0xff;
-			desc[2] = (offset >> 0) & 0xff;
-
-			desc[1] = 0x00;
-			desc[0] = 0x21; /* tran, valid */
-
 			align += 4;
 			align_addr += 4;
 
@@ -465,19 +483,10 @@ static int sdhci_adma_table_pre(struct s
 			len -= offset;
 		}
 
-		desc[7] = (addr >> 24) & 0xff;
-		desc[6] = (addr >> 16) & 0xff;
-		desc[5] = (addr >> 8) & 0xff;
-		desc[4] = (addr >> 0) & 0xff;
-
 		BUG_ON(len > 65536);
 
-		desc[3] = (len >> 8) & 0xff;
-		desc[2] = (len >> 0) & 0xff;
-
-		desc[1] = 0x00;
-		desc[0] = 0x21; /* tran, valid */
-
+		/* tran, valid */
+		sdhci_set_adma_desc(desc, addr, len, 0x21);
 		desc += 8;
 
 		/*
@@ -490,16 +499,9 @@ static int sdhci_adma_table_pre(struct s
 	/*
 	 * Add a terminating entry.
 	 */
-	desc[7] = 0;
-	desc[6] = 0;
-	desc[5] = 0;
-	desc[4] = 0;
-
-	desc[3] = 0;
-	desc[2] = 0;
 
-	desc[1] = 0x00;
-	desc[0] = 0x03; /* nop, end, valid */
+	/* nop, end, valid */
+	sdhci_set_adma_desc(desc, 0, 0, 0x3);
 
 	/*
 	 * Resync align buffer as we might have changed it.
@@ -1610,16 +1612,13 @@ int sdhci_resume_host(struct sdhci_host
 	if (ret)
 		return ret;
 
-	sdhci_init(host);
+	sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER));
 	mmiowb();
 
 	ret = mmc_resume_host(host->mmc);
-	if (ret)
-		return ret;
-
 	sdhci_enable_card_detection(host);
 
-	return 0;
+	return ret;
 }
 
 EXPORT_SYMBOL_GPL(sdhci_resume_host);
@@ -1874,7 +1873,7 @@ int sdhci_add_host(struct sdhci_host *ho
 	if (ret)
 		goto untasklet;
 
-	sdhci_init(host);
+	sdhci_init(host, 0);
 
 #ifdef CONFIG_MMC_DEBUG
 	sdhci_dumpregs(host);
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-pci.c linux-libre-2.6.34-gnu1/drivers/mmc/host/sdhci-pci.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/sdhci-pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/highmem.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/host.h>
 
@@ -80,9 +81,6 @@ struct sdhci_pci_chip {
 
 static int ricoh_probe(struct sdhci_pci_chip *chip)
 {
-	if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM)
-		chip->quirks |= SDHCI_QUIRK_CLOCK_BEFORE_RESET;
-
 	if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG ||
 	    chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY)
 		chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET;
@@ -92,7 +90,9 @@ static int ricoh_probe(struct sdhci_pci_
 
 static const struct sdhci_pci_fixes sdhci_ricoh = {
 	.probe		= ricoh_probe,
-	.quirks		= SDHCI_QUIRK_32BIT_DMA_ADDR,
+	.quirks		= SDHCI_QUIRK_32BIT_DMA_ADDR |
+			  SDHCI_QUIRK_FORCE_DMA |
+			  SDHCI_QUIRK_CLOCK_BEFORE_RESET,
 };
 
 static const struct sdhci_pci_fixes sdhci_ene_712 = {
@@ -501,6 +501,7 @@ static int sdhci_pci_suspend (struct pci
 {
 	struct sdhci_pci_chip *chip;
 	struct sdhci_pci_slot *slot;
+	mmc_pm_flag_t pm_flags = 0;
 	int i, ret;
 
 	chip = pci_get_drvdata(pdev);
@@ -519,6 +520,8 @@ static int sdhci_pci_suspend (struct pci
 				sdhci_resume_host(chip->slots[i]->host);
 			return ret;
 		}
+
+		pm_flags |= slot->host->mmc->pm_flags;
 	}
 
 	if (chip->fixes && chip->fixes->suspend) {
@@ -531,9 +534,15 @@ static int sdhci_pci_suspend (struct pci
 	}
 
 	pci_save_state(pdev);
-	pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
-	pci_disable_device(pdev);
-	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	if (pm_flags & MMC_PM_KEEP_POWER) {
+		if (pm_flags & MMC_PM_WAKE_SDIO_IRQ)
+			pci_enable_wake(pdev, PCI_D3hot, 1);
+		pci_set_power_state(pdev, PCI_D3hot);
+	} else {
+		pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
+		pci_disable_device(pdev);
+		pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	}
 
 	return 0;
 }
@@ -653,6 +662,8 @@ static struct sdhci_pci_slot * __devinit
 			goto unmap;
 	}
 
+	host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ;
+
 	ret = sdhci_add_host(host);
 	if (ret)
 		goto remove;
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-s3c.c linux-libre-2.6.34-gnu1/drivers/mmc/host/sdhci-s3c.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-s3c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/sdhci-s3c.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/tmio_mmc.c linux-libre-2.6.34-gnu1/drivers/mmc/host/tmio_mmc.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/tmio_mmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/tmio_mmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -323,7 +323,7 @@ static irqreturn_t tmio_mmc_irq(int irq,
 		if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
 			ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT |
 				TMIO_STAT_CARD_REMOVE);
-			mmc_detect_change(host->mmc, 0);
+			mmc_detect_change(host->mmc, msecs_to_jiffies(100));
 		}
 
 		/* CRC and other errors */
@@ -550,6 +550,7 @@ static int __devinit tmio_mmc_probe(stru
 
 	mmc->ops = &tmio_mmc_ops;
 	mmc->caps = MMC_CAP_4_BIT_DATA;
+	mmc->caps |= pdata->capabilities;
 	mmc->f_max = pdata->hclk;
 	mmc->f_min = mmc->f_max / 512;
 	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
@@ -568,14 +569,14 @@ static int __devinit tmio_mmc_probe(stru
 	if (ret >= 0)
 		host->irq = ret;
 	else
-		goto unmap_ctl;
+		goto cell_disable;
 
 	disable_mmc_irqs(host, TMIO_MASK_ALL);
 
 	ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED |
 		IRQF_TRIGGER_FALLING, dev_name(&dev->dev), host);
 	if (ret)
-		goto unmap_ctl;
+		goto cell_disable;
 
 	mmc_add_host(mmc);
 
@@ -587,6 +588,9 @@ static int __devinit tmio_mmc_probe(stru
 
 	return 0;
 
+cell_disable:
+	if (cell->disable)
+		cell->disable(dev);
 unmap_ctl:
 	iounmap(host->ctl);
 host_free:
@@ -597,6 +601,7 @@ out:
 
 static int __devexit tmio_mmc_remove(struct platform_device *dev)
 {
+	struct mfd_cell	*cell = (struct mfd_cell *)dev->dev.platform_data;
 	struct mmc_host *mmc = platform_get_drvdata(dev);
 
 	platform_set_drvdata(dev, NULL);
@@ -605,6 +610,8 @@ static int __devexit tmio_mmc_remove(str
 		struct tmio_mmc_host *host = mmc_priv(mmc);
 		mmc_remove_host(mmc);
 		free_irq(host->irq, host);
+		if (cell->disable)
+			cell->disable(dev);
 		iounmap(host->ctl);
 		mmc_free_host(mmc);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/tmio_mmc.h linux-libre-2.6.34-gnu1/drivers/mmc/host/tmio_mmc.h
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/tmio_mmc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/tmio_mmc.h	2010-05-16 17:17:36.000000000 -0400
@@ -55,10 +55,8 @@
 /* Define some IRQ masks */
 /* This is the mask used at reset by the chip */
 #define TMIO_MASK_ALL           0x837f031d
-#define TMIO_MASK_READOP  (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND | \
-		TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
-#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND | \
-		TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
+#define TMIO_MASK_READOP  (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND)
+#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND)
 #define TMIO_MASK_CMD     (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \
 		TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
 #define TMIO_MASK_IRQ     (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD)
diff -druNp linux-libre-2.6.33-gnu1/drivers/mmc/host/wbsd.c linux-libre-2.6.34-gnu1/drivers/mmc/host/wbsd.c
--- linux-libre-2.6.33-gnu1/drivers/mmc/host/wbsd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mmc/host/wbsd.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/highmem.h>
 #include <linux/mmc/host.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/chips/jedec_probe.c linux-libre-2.6.34-gnu1/drivers/mtd/chips/jedec_probe.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/chips/jedec_probe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/chips/jedec_probe.c	2010-05-16 17:17:36.000000000 -0400
@@ -226,7 +226,7 @@ struct unlock_addr {
  * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore,
  * should not be used.  The  problem is that structures with
  * initializers have extra fields initialized to 0.  It is _very_
- * desireable to have the unlock address entries for unsupported
+ * desirable to have the unlock address entries for unsupported
  * data widths automatically initialized - that means that
  * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here
  * must go unused.
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/devices/block2mtd.c linux-libre-2.6.34-gnu1/drivers/mtd/devices/block2mtd.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/devices/block2mtd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/devices/block2mtd.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/buffer_head.h>
 #include <linux/mutex.h>
 #include <linux/mount.h>
+#include <linux/slab.h>
 
 #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
 #define INFO(fmt, args...) printk(KERN_INFO "block2mtd: " fmt "\n" , ## args)
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/devices/m25p80.c linux-libre-2.6.34-gnu1/drivers/mtd/devices/m25p80.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/devices/m25p80.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/devices/m25p80.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/math64.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/mod_devicetable.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/devices/sst25l.c linux-libre-2.6.34-gnu1/drivers/mtd/devices/sst25l.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/devices/sst25l.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/devices/sst25l.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/device.h>
 #include <linux/mutex.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #include <linux/mtd/mtd.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/internal.h linux-libre-2.6.34-gnu1/drivers/mtd/internal.h
--- linux-libre-2.6.33-gnu1/drivers/mtd/internal.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/internal.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-/* 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.33-gnu1/drivers/mtd/lpddr/lpddr_cmds.c linux-libre-2.6.34-gnu1/drivers/mtd/lpddr/lpddr_cmds.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/lpddr/lpddr_cmds.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/lpddr/lpddr_cmds.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
  */
 #include <linux/mtd/pfow.h>
 #include <linux/mtd/qinfo.h>
+#include <linux/slab.h>
 
 static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len,
 					size_t *retlen, u_char *buf);
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/Makefile linux-libre-2.6.34-gnu1/drivers/mtd/Makefile
--- linux-libre-2.6.33-gnu1/drivers/mtd/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
 
 # Core functionality.
 obj-$(CONFIG_MTD)		+= mtd.o
-mtd-y				:= mtdcore.o mtdsuper.o mtdbdi.o
+mtd-y				:= mtdcore.o mtdsuper.o
 mtd-$(CONFIG_MTD_PARTITIONS)	+= mtdpart.o
 
 obj-$(CONFIG_MTD_CONCAT)	+= mtdconcat.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/alchemy-flash.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/alchemy-flash.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/alchemy-flash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/alchemy-flash.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,166 +0,0 @@
-/*
- * Flash memory access on AMD Alchemy evaluation boards
- *
- * (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com>
- */
-
-#include <linux/init.h>
-#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>
-
-#ifdef CONFIG_MIPS_PB1000
-#define BOARD_MAP_NAME "Pb1000 Flash"
-#define BOARD_FLASH_SIZE 0x00800000 /* 8MB */
-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
-#endif
-
-#ifdef CONFIG_MIPS_PB1500
-#define BOARD_MAP_NAME "Pb1500 Flash"
-#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
-#endif
-
-#ifdef CONFIG_MIPS_PB1100
-#define BOARD_MAP_NAME "Pb1100 Flash"
-#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
-#endif
-
-#ifdef CONFIG_MIPS_PB1550
-#define BOARD_MAP_NAME "Pb1550 Flash"
-#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
-#endif
-
-#ifdef CONFIG_MIPS_PB1200
-#define BOARD_MAP_NAME "Pb1200 Flash"
-#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
-#define BOARD_FLASH_WIDTH 2 /* 16-bits */
-#endif
-
-#ifdef CONFIG_MIPS_DB1000
-#define BOARD_MAP_NAME "Db1000 Flash"
-#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
-#endif
-
-#ifdef CONFIG_MIPS_DB1500
-#define BOARD_MAP_NAME "Db1500 Flash"
-#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
-#endif
-
-#ifdef CONFIG_MIPS_DB1100
-#define BOARD_MAP_NAME "Db1100 Flash"
-#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
-#endif
-
-#ifdef CONFIG_MIPS_DB1550
-#define BOARD_MAP_NAME "Db1550 Flash"
-#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
-#endif
-
-#ifdef CONFIG_MIPS_DB1200
-#define BOARD_MAP_NAME "Db1200 Flash"
-#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
-#define BOARD_FLASH_WIDTH 2 /* 16-bits */
-#endif
-
-#ifdef CONFIG_MIPS_BOSPORUS
-#define BOARD_MAP_NAME "Bosporus Flash"
-#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */
-#define BOARD_FLASH_WIDTH 2 /* 16-bits */
-#endif
-
-#ifdef CONFIG_MIPS_MIRAGE
-#define BOARD_MAP_NAME "Mirage Flash"
-#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
-#define USE_LOCAL_ACCESSORS /* why? */
-#endif
-
-static struct map_info alchemy_map = {
-	.name =	BOARD_MAP_NAME,
-};
-
-static struct mtd_partition alchemy_partitions[] = {
-        {
-                .name = "User FS",
-                .size = BOARD_FLASH_SIZE - 0x00400000,
-                .offset = 0x0000000
-        },{
-                .name = "YAMON",
-                .size = 0x0100000,
-		.offset = MTDPART_OFS_APPEND,
-                .mask_flags = MTD_WRITEABLE
-        },{
-                .name = "raw kernel",
-		.size = (0x300000 - 0x40000), /* last 256KB is yamon env */
-		.offset = MTDPART_OFS_APPEND,
-        }
-};
-
-static struct mtd_info *mymtd;
-
-static int __init alchemy_mtd_init(void)
-{
-	struct mtd_partition *parts;
-	int nb_parts = 0;
-	unsigned long window_addr;
-	unsigned long window_size;
-
-	/* Default flash buswidth */
-	alchemy_map.bankwidth = BOARD_FLASH_WIDTH;
-
-	window_addr = 0x20000000 - BOARD_FLASH_SIZE;
-	window_size = BOARD_FLASH_SIZE;
-
-	/*
-	 * Static partition definition selection
-	 */
-	parts = alchemy_partitions;
-	nb_parts = ARRAY_SIZE(alchemy_partitions);
-	alchemy_map.size = window_size;
-
-	/*
-	 * Now let's probe for the actual flash.  Do it here since
-	 * specific machine settings might have been set above.
-	 */
-	printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n",
-			alchemy_map.bankwidth*8);
-	alchemy_map.virt = ioremap(window_addr, window_size);
-	mymtd = do_map_probe("cfi_probe", &alchemy_map);
-	if (!mymtd) {
-		iounmap(alchemy_map.virt);
-		return -ENXIO;
-	}
-	mymtd->owner = THIS_MODULE;
-
-	add_mtd_partitions(mymtd, parts, nb_parts);
-	return 0;
-}
-
-static void __exit alchemy_mtd_cleanup(void)
-{
-	if (mymtd) {
-		del_mtd_partitions(mymtd);
-		map_destroy(mymtd);
-		iounmap(alchemy_map.virt);
-	}
-}
-
-module_init(alchemy_mtd_init);
-module_exit(alchemy_mtd_cleanup);
-
-MODULE_AUTHOR("Embedded Alley Solutions, Inc");
-MODULE_DESCRIPTION(BOARD_MAP_NAME " MTD driver");
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/amd76xrom.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/amd76xrom.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/amd76xrom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/amd76xrom.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/bfin-async-flash.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/bfin-async-flash.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/bfin-async-flash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/bfin-async-flash.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include <asm/blackfin.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/ck804xrom.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/ck804xrom.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/ck804xrom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/ck804xrom.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/esb2rom.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/esb2rom.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/esb2rom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/esb2rom.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/gpio-addr-flash.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/gpio-addr-flash.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/gpio-addr-flash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/gpio-addr-flash.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); })
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/ichxrom.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/ichxrom.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/ichxrom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/ichxrom.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/intel_vr_nor.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/intel_vr_nor.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/intel_vr_nor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/intel_vr_nor.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/mtd/mtd.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/Kconfig linux-libre-2.6.34-gnu1/drivers/mtd/maps/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -251,12 +251,6 @@ config MTD_NETtel
 	help
 	  Support for flash chips on NETtel/SecureEdge/SnapGear boards.
 
-config MTD_ALCHEMY
-	tristate "AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support"
-	depends on SOC_AU1X00 && MTD_PARTITIONS && MTD_CFI
-	help
-	  Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards
-
 config MTD_DILNETPC
 	tristate "CFI Flash device mapped on DIL/Net PC"
 	depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN
@@ -428,15 +422,6 @@ config MTD_H720X
 	  This enables access to the flash chips on the Hynix evaluation boards.
 	  If you have such a board, say 'Y'.
 
-config MTD_OMAP_NOR
-	tristate "TI OMAP board mappings"
-	depends on MTD_CFI && ARCH_OMAP
-	help
-	  This enables access to the NOR flash chips on TI OMAP-based
-	  boards defining flash platform devices and flash platform data.
-	  These boards include the Innovator, H2, H3, OSK, Perseus2, and
-	  more.  If you have such a board, say 'Y'.
-
 # This needs CFI or JEDEC, depending on the cards found.
 config MTD_PCI
 	tristate "PCI MTD driver"
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/Makefile linux-libre-2.6.34-gnu1/drivers/mtd/maps/Makefile
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -40,7 +40,6 @@ obj-$(CONFIG_MTD_SCx200_DOCFLASH)+= scx2
 obj-$(CONFIG_MTD_DBOX2)		+= dbox2-flash.o
 obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
 obj-$(CONFIG_MTD_PCI)		+= pci.o
-obj-$(CONFIG_MTD_ALCHEMY)       += alchemy-flash.o
 obj-$(CONFIG_MTD_AUTCPU12)	+= autcpu12-nvram.o
 obj-$(CONFIG_MTD_EDB7312)	+= edb7312.o
 obj-$(CONFIG_MTD_IMPA7)		+= impa7.o
@@ -55,7 +54,6 @@ obj-$(CONFIG_MTD_IXP2000)	+= ixp2000.o
 obj-$(CONFIG_MTD_WRSBC8260)	+= wr_sbc82xx_flash.o
 obj-$(CONFIG_MTD_DMV182)	+= dmv182.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
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/octagon-5066.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/octagon-5066.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/octagon-5066.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/octagon-5066.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,6 @@
    ##################################################################### */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/omap_nor.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/omap_nor.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/omap_nor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/omap_nor.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,188 +0,0 @@
-/*
- * Flash memory support for various TI OMAP boards
- *
- * Copyright (C) 2001-2002 MontaVista Software Inc.
- * Copyright (C) 2003-2004 Texas Instruments
- * Copyright (C) 2004 Nokia Corporation
- *
- *	Assembled using driver code copyright the companies above
- *	and written by David Brownell, Jian Zhang <jzhang@ti.com>,
- * 	Tony Lindgren <tony@atomide.com> and others.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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.
- */
-
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-#include <mach/hardware.h>
-#include <asm/mach/flash.h>
-#include <plat/tc.h>
-
-#ifdef CONFIG_MTD_PARTITIONS
-static const char *part_probes[] = { /* "RedBoot", */ "cmdlinepart", NULL };
-#endif
-
-struct omapflash_info {
-	struct mtd_partition	*parts;
-	struct mtd_info		*mtd;
-	struct map_info		map;
-};
-
-static void omap_set_vpp(struct map_info *map, int enable)
-{
-	static int	count;
-	u32 l;
-
-	if (cpu_class_is_omap1()) {
-		if (enable) {
-			if (count++ == 0) {
-				l = omap_readl(EMIFS_CONFIG);
-				l |= OMAP_EMIFS_CONFIG_WP;
-				omap_writel(l, EMIFS_CONFIG);
-			}
-		} else {
-			if (count && (--count == 0)) {
-				l = omap_readl(EMIFS_CONFIG);
-				l &= ~OMAP_EMIFS_CONFIG_WP;
-				omap_writel(l, EMIFS_CONFIG);
-			}
-		}
-	}
-}
-
-static int __init omapflash_probe(struct platform_device *pdev)
-{
-	int err;
-	struct omapflash_info *info;
-	struct flash_platform_data *pdata = pdev->dev.platform_data;
-	struct resource *res = pdev->resource;
-	unsigned long size = res->end - res->start + 1;
-
-	info = kzalloc(sizeof(struct omapflash_info), GFP_KERNEL);
-	if (!info)
-		return -ENOMEM;
-
-	if (!request_mem_region(res->start, size, "flash")) {
-		err = -EBUSY;
-		goto out_free_info;
-	}
-
-	info->map.virt		= ioremap(res->start, size);
-	if (!info->map.virt) {
-		err = -ENOMEM;
-		goto out_release_mem_region;
-	}
-	info->map.name		= dev_name(&pdev->dev);
-	info->map.phys		= res->start;
-	info->map.size		= size;
-	info->map.bankwidth	= pdata->width;
-	info->map.set_vpp	= omap_set_vpp;
-
-	simple_map_init(&info->map);
-	info->mtd = do_map_probe(pdata->map_name, &info->map);
-	if (!info->mtd) {
-		err = -EIO;
-		goto out_iounmap;
-	}
-	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)
-		add_mtd_partitions(info->mtd, info->parts, err);
-	else if (err <= 0 && pdata->parts)
-		add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
-	else
-#endif
-		add_mtd_device(info->mtd);
-
-	platform_set_drvdata(pdev, info);
-
-	return 0;
-
-out_iounmap:
-	iounmap(info->map.virt);
-out_release_mem_region:
-	release_mem_region(res->start, size);
-out_free_info:
-	kfree(info);
-
-	return err;
-}
-
-static int __exit omapflash_remove(struct platform_device *pdev)
-{
-	struct omapflash_info *info = platform_get_drvdata(pdev);
-
-	platform_set_drvdata(pdev, NULL);
-
-	if (info) {
-		if (info->parts) {
-			del_mtd_partitions(info->mtd);
-			kfree(info->parts);
-		} else
-			del_mtd_device(info->mtd);
-		map_destroy(info->mtd);
-		release_mem_region(info->map.phys, info->map.size);
-		iounmap((void __iomem *) info->map.virt);
-		kfree(info);
-	}
-
-	return 0;
-}
-
-static struct platform_driver omapflash_driver = {
-	.remove	= __exit_p(omapflash_remove),
-	.driver = {
-		.name	= "omapflash",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init omapflash_init(void)
-{
-	return platform_driver_probe(&omapflash_driver, omapflash_probe);
-}
-
-static void __exit omapflash_exit(void)
-{
-	platform_driver_unregister(&omapflash_driver);
-}
-
-module_init(omapflash_init);
-module_exit(omapflash_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("MTD NOR map driver for TI OMAP boards");
-MODULE_ALIAS("platform:omapflash");
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/physmap_of.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/physmap_of.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/physmap_of.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/physmap_of.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/mtd/concat.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 
 struct of_flash_list {
 	struct mtd_info *mtd;
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/pismo.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/pismo.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/pismo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/pismo.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
@@ -118,7 +119,7 @@ static int __devinit pismo_add_device(st
 {
 	struct platform_device *dev;
 	struct resource res = { };
-	phys_addr_t base = region.base;
+	phys_addr_t base = region->base;
 	int ret;
 
 	if (base == ~0)
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/plat-ram.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/plat-ram.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/plat-ram.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/plat-ram.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
  *	http://www.simtec.co.uk/products/SWLINUX/
  *	Ben Dooks <ben@simtec.co.uk>
  *
- * Generic platfrom device based RAM map
+ * Generic platform device based RAM map
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/pmcmsp-flash.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/pmcmsp-flash.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/pmcmsp-flash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/pmcmsp-flash.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/pxa2xx-flash.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/pxa2xx-flash.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/pxa2xx-flash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/pxa2xx-flash.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/sbc_gxx.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/sbc_gxx.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/sbc_gxx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/sbc_gxx.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,7 +45,6 @@ separate MTD devices.
 // Includes
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/sun_uflash.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/sun_uflash.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/sun_uflash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/sun_uflash.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/ioport.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/slab.h>
 #include <asm/prom.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/vmax301.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/vmax301.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/vmax301.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/vmax301.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
    ##################################################################### */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/maps/vmu-flash.c linux-libre-2.6.34-gnu1/drivers/mtd/maps/vmu-flash.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/maps/vmu-flash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/maps/vmu-flash.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  * GNU General Public Licence
  */
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/maple.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/mtdbdi.c linux-libre-2.6.34-gnu1/drivers/mtd/mtdbdi.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/mtdbdi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/mtdbdi.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,43 +0,0 @@
-/* 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.33-gnu1/drivers/mtd/mtdcore.c linux-libre-2.6.34-gnu1/drivers/mtd/mtdcore.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/mtdcore.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/mtdcore.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,12 +2,14 @@
  * Core registration and callback routines for MTD
  * drivers and users.
  *
+ * bdi bits are:
+ * Copyright Â© 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
  */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/major.h>
@@ -17,11 +19,39 @@
 #include <linux/init.h>
 #include <linux/mtd/compatmac.h>
 #include <linux/proc_fs.h>
+#include <linux/backing-dev.h>
 
 #include <linux/mtd/mtd.h>
-#include "internal.h"
 
 #include "mtdcore.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),
+};
 
 static int mtd_cls_suspend(struct device *dev, pm_message_t state);
 static int mtd_cls_resume(struct device *dev);
@@ -629,20 +659,55 @@ done:
 /*====================================================================*/
 /* Init code */
 
+static int __init mtd_bdi_init(struct backing_dev_info *bdi, const char *name)
+{
+	int ret;
+
+	ret = bdi_init(bdi);
+	if (!ret)
+		ret = bdi_register(bdi, NULL, name);
+
+	if (ret)
+		bdi_destroy(bdi);
+
+	return ret;
+}
+
 static int __init init_mtd(void)
 {
 	int ret;
+
 	ret = class_register(&mtd_class);
+	if (ret)
+		goto err_reg;
+
+	ret = mtd_bdi_init(&mtd_bdi_unmappable, "mtd-unmap");
+	if (ret)
+		goto err_bdi1;
+
+	ret = mtd_bdi_init(&mtd_bdi_ro_mappable, "mtd-romap");
+	if (ret)
+		goto err_bdi2;
+
+	ret = mtd_bdi_init(&mtd_bdi_rw_mappable, "mtd-rwmap");
+	if (ret)
+		goto err_bdi3;
 
-	if (ret) {
-		pr_err("Error registering mtd class: %d\n", ret);
-		return ret;
-	}
 #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;
+
+err_bdi3:
+	bdi_destroy(&mtd_bdi_ro_mappable);
+err_bdi2:
+	bdi_destroy(&mtd_bdi_unmappable);
+err_bdi1:
+	class_unregister(&mtd_class);
+err_reg:
+	pr_err("Error registering mtd class or bdi: %d\n", ret);
+	return ret;
 }
 
 static void __exit cleanup_mtd(void)
@@ -652,6 +717,9 @@ static void __exit cleanup_mtd(void)
 		remove_proc_entry( "mtd", NULL);
 #endif /* CONFIG_PROC_FS */
 	class_unregister(&mtd_class);
+	bdi_destroy(&mtd_bdi_unmappable);
+	bdi_destroy(&mtd_bdi_ro_mappable);
+	bdi_destroy(&mtd_bdi_rw_mappable);
 }
 
 module_init(init_mtd);
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/mtdsuper.c linux-libre-2.6.34-gnu1/drivers/mtd/mtdsuper.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/mtdsuper.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/mtdsuper.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/mtd/super.h>
 #include <linux/namei.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 
 /*
  * compare superblocks to see if they're equivalent
@@ -44,6 +45,7 @@ static int get_sb_mtd_set(struct super_b
 
 	sb->s_mtd = mtd;
 	sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+	sb->s_bdi = mtd->backing_dev_info;
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/au1550nd.c linux-libre-2.6.34-gnu1/drivers/mtd/nand/au1550nd.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/au1550nd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/au1550nd.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <asm/io.h>
 
 #include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-db1x00/bcsr.h>
 
 /*
  * MTD structure for NAND controller
@@ -475,7 +476,8 @@ static int __init au1xxx_nand_init(void)
 	/* set gpio206 high */
 	au_writel(au_readl(GPIO2_DIR) & ~(1 << 6), GPIO2_DIR);
 
-	boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr->status >> 6) & 0x1);
+	boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr_read(BCSR_STATUS) >> 6) & 0x1);
+
 	switch (boot_swapboot) {
 	case 0:
 	case 2:
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/bcm_umi_nand.c linux-libre-2.6.34-gnu1/drivers/mtd/nand/bcm_umi_nand.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/bcm_umi_nand.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/bcm_umi_nand.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/device.h>
@@ -381,7 +382,7 @@ static int __devinit bcm_umi_nand_probe(
 	if (!r)
 		return -ENXIO;
 
-	/* map physical adress */
+	/* map physical address */
 	bcm_umi_io_base = ioremap(r->start, r->end - r->start + 1);
 
 	if (!bcm_umi_io_base) {
@@ -525,7 +526,7 @@ static int bcm_umi_nand_remove(struct pl
 	/* Release resources, unregister device */
 	nand_release(board_mtd);
 
-	/* unmap physical adress */
+	/* unmap physical address */
 	iounmap(bcm_umi_io_base);
 
 	/* Free the MTD device structure */
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/cafe_nand.c linux-libre-2.6.34-gnu1/drivers/mtd/nand/cafe_nand.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/cafe_nand.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/cafe_nand.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #define CAFE_NAND_CTRL1		0x00
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/cmx270_nand.c linux-libre-2.6.34-gnu1/drivers/mtd/nand/cmx270_nand.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/cmx270_nand.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/cmx270_nand.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/slab.h>
 #include <linux/gpio.h>
 
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/davinci_nand.c linux-libre-2.6.34-gnu1/drivers/mtd/nand/davinci_nand.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/davinci_nand.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/davinci_nand.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/io.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/slab.h>
 
 #include <mach/nand.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/diskonchip.c linux-libre-2.6.34-gnu1/drivers/mtd/nand/diskonchip.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/diskonchip.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/diskonchip.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/rslib.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #include <linux/mtd/mtd.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/fsl_upm.c linux-libre-2.6.34-gnu1/drivers/mtd/nand/fsl_upm.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/fsl_upm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/fsl_upm.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <asm/fsl_lbc.h>
 
 #define FSL_UPM_WAIT_RUN_PATTERN  0x1
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/Kconfig linux-libre-2.6.34-gnu1/drivers/mtd/nand/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -444,7 +444,7 @@ config MTD_NAND_FSL_UPM
 
 config MTD_NAND_MXC
 	tristate "MXC NAND support"
-	depends on ARCH_MX2 || ARCH_MX3
+	depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3
 	help
 	  This enables the driver for the NAND flash controller on the
 	  MXC processors.
@@ -457,10 +457,10 @@ config MTD_NAND_NOMADIK
 
 config MTD_NAND_SH_FLCTL
 	tristate "Support for NAND on Renesas SuperH FLCTL"
-	depends on MTD_NAND && SUPERH && CPU_SUBTYPE_SH7723
+	depends on MTD_NAND && (SUPERH || ARCH_SHMOBILE)
 	help
 	  Several Renesas SuperH CPU has FLCTL. This option enables support
-	  for NAND Flash using FLCTL. This driver support SH7723.
+	  for NAND Flash using FLCTL.
 
 config MTD_NAND_DAVINCI
         tristate "Support NAND on DaVinci SoC"
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/mxc_nand.c linux-libre-2.6.34-gnu1/drivers/mtd/nand/mxc_nand.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/mxc_nand.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/mxc_nand.c	2010-05-16 17:17:36.000000000 -0400
@@ -507,7 +507,7 @@ static void mxc_do_addr_cycle(struct mtd
 		 * MXC NANDFC can only perform full page+spare or
 		 * spare-only read/write.  When the upper layers
 		 * layers perform a read/write buf operation,
-		 * we will used the saved column adress to index into
+		 * we will used the saved column address to index into
 		 * the full page.
 		 */
 		send_addr(host, 0, page_addr == -1);
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/ndfc.c linux-libre-2.6.34-gnu1/drivers/mtd/nand/ndfc.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/ndfc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/ndfc.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/ndfc.h>
+#include <linux/slab.h>
 #include <linux/mtd/mtd.h>
 #include <linux/of_platform.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/nomadik_nand.c linux-libre-2.6.34-gnu1/drivers/mtd/nand/nomadik_nand.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/nomadik_nand.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/nomadik_nand.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/platform_device.h>
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <mach/nand.h>
 #include <mach/fsmc.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/omap2.c linux-libre-2.6.34-gnu1/drivers/mtd/nand/omap2.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/omap2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/omap2.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <plat/dma.h>
 #include <plat/gpmc.h>
@@ -30,12 +31,8 @@
 
 #define	DRIVER_NAME	"omap2-nand"
 
-/* size (4 KiB) for IO mapping */
-#define	NAND_IO_SIZE	SZ_4K
-
 #define	NAND_WP_OFF	0
 #define NAND_WP_BIT	0x00000010
-#define WR_RD_PIN_MONITORING	0x00600000
 
 #define	GPMC_BUF_FULL	0x00000001
 #define	GPMC_BUF_EMPTY	0x00000000
@@ -882,8 +879,6 @@ static int __devinit omap_nand_probe(str
 	struct omap_nand_info		*info;
 	struct omap_nand_platform_data	*pdata;
 	int				err;
-	unsigned long 			val;
-
 
 	pdata = pdev->dev.platform_data;
 	if (pdata == NULL) {
@@ -905,28 +900,14 @@ static int __devinit omap_nand_probe(str
 	info->gpmc_cs		= pdata->cs;
 	info->gpmc_baseaddr	= pdata->gpmc_baseaddr;
 	info->gpmc_cs_baseaddr	= pdata->gpmc_cs_baseaddr;
+	info->phys_base		= pdata->phys_base;
 
 	info->mtd.priv		= &info->nand;
 	info->mtd.name		= dev_name(&pdev->dev);
 	info->mtd.owner		= THIS_MODULE;
 
-	err = gpmc_cs_request(info->gpmc_cs, NAND_IO_SIZE, &info->phys_base);
-	if (err < 0) {
-		dev_err(&pdev->dev, "Cannot request GPMC CS\n");
-		goto out_free_info;
-	}
-
-	/* Enable RD PIN Monitoring Reg */
-	if (pdata->dev_ready) {
-		val  = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1);
-		val |= WR_RD_PIN_MONITORING;
-		gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG1, val);
-	}
-
-	val  = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG7);
-	val &= ~(0xf << 8);
-	val |=  (0xc & 0xf) << 8;
-	gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG7, val);
+	info->nand.options	|= pdata->devsize ? NAND_BUSWIDTH_16 : 0;
+	info->nand.options	|= NAND_SKIP_BBTSCAN;
 
 	/* NAND write protect off */
 	omap_nand_wp(&info->mtd, NAND_WP_OFF);
@@ -934,7 +915,7 @@ static int __devinit omap_nand_probe(str
 	if (!request_mem_region(info->phys_base, NAND_IO_SIZE,
 				pdev->dev.driver->name)) {
 		err = -EBUSY;
-		goto out_free_cs;
+		goto out_free_info;
 	}
 
 	info->nand.IO_ADDR_R = ioremap(info->phys_base, NAND_IO_SIZE);
@@ -963,11 +944,6 @@ static int __devinit omap_nand_probe(str
 		info->nand.chip_delay = 50;
 	}
 
-	info->nand.options  |= NAND_SKIP_BBTSCAN;
-	if ((gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1) & 0x3000)
-								== 0x1000)
-		info->nand.options  |= NAND_BUSWIDTH_16;
-
 	if (use_prefetch) {
 		/* copy the virtual address of nand base for fifo access */
 		info->nand_pref_fifo_add = info->nand.IO_ADDR_R;
@@ -1043,8 +1019,6 @@ static int __devinit omap_nand_probe(str
 
 out_release_mem_region:
 	release_mem_region(info->phys_base, NAND_IO_SIZE);
-out_free_cs:
-	gpmc_cs_free(info->gpmc_cs);
 out_free_info:
 	kfree(info);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/orion_nand.c linux-libre-2.6.34-gnu1/drivers/mtd/nand/orion_nand.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/orion_nand.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/orion_nand.c	2010-05-16 17:17:36.000000000 -0400
@@ -60,7 +60,13 @@ static void orion_nand_read_buf(struct m
 	}
 	buf64 = (uint64_t *)buf;
 	while (i < len/8) {
-		uint64_t x;
+		/*
+		 * Since GCC has no proper constraint (PR 43518)
+		 * force x variable to r2/r3 registers as ldrd instruction
+		 * requires first register to be even.
+		 */
+		register uint64_t x asm ("r2");
+
 		asm volatile ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base));
 		buf64[i++] = x;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/pxa3xx_nand.c linux-libre-2.6.34-gnu1/drivers/mtd/nand/pxa3xx_nand.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/pxa3xx_nand.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/pxa3xx_nand.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 
 #include <mach/dma.h>
 #include <plat/pxa3xx_nand.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/sh_flctl.c linux-libre-2.6.34-gnu1/drivers/mtd/nand/sh_flctl.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/sh_flctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/sh_flctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,10 +1,10 @@
 /*
  * SuperH FLCTL nand controller
  *
- * Copyright Â© 2008 Renesas Solutions Corp.
- * Copyright Â© 2008 Atom Create Engineering Co., Ltd.
+ * Copyright (c) 2008 Renesas Solutions Corp.
+ * Copyright (c) 2008 Atom Create Engineering Co., Ltd.
  *
- * Based on fsl_elbc_nand.c, Copyright Â© 2006-2007 Freescale Semiconductor
+ * Based on fsl_elbc_nand.c, Copyright (c) 2006-2007 Freescale Semiconductor
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
@@ -75,6 +76,11 @@ static void start_translation(struct sh_
 	writeb(TRSTRT, FLTRCR(flctl));
 }
 
+static void timeout_error(struct sh_flctl *flctl, const char *str)
+{
+	dev_err(&flctl->pdev->dev, "Timeout occured in %s\n", str);
+}
+
 static void wait_completion(struct sh_flctl *flctl)
 {
 	uint32_t timeout = LOOP_TIMEOUT_MAX;
@@ -87,7 +93,7 @@ static void wait_completion(struct sh_fl
 		udelay(1);
 	}
 
-	printk(KERN_ERR "wait_completion(): Timeout occured \n");
+	timeout_error(flctl, __func__);
 	writeb(0x0, FLTRCR(flctl));
 }
 
@@ -100,6 +106,8 @@ static void set_addr(struct mtd_info *mt
 		addr = page_addr;	/* ERASE1 */
 	} else if (page_addr != -1) {
 		/* SEQIN, READ0, etc.. */
+		if (flctl->chip.options & NAND_BUSWIDTH_16)
+			column >>= 1;
 		if (flctl->page_size) {
 			addr = column & 0x0FFF;
 			addr |= (page_addr & 0xff) << 16;
@@ -132,7 +140,7 @@ static void wait_rfifo_ready(struct sh_f
 			return;
 		udelay(1);
 	}
-	printk(KERN_ERR "wait_rfifo_ready(): Timeout occured \n");
+	timeout_error(flctl, __func__);
 }
 
 static void wait_wfifo_ready(struct sh_flctl *flctl)
@@ -146,7 +154,7 @@ static void wait_wfifo_ready(struct sh_f
 			return;
 		udelay(1);
 	}
-	printk(KERN_ERR "wait_wfifo_ready(): Timeout occured \n");
+	timeout_error(flctl, __func__);
 }
 
 static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
@@ -198,7 +206,7 @@ static int wait_recfifo_ready(struct sh_
 		writel(0, FL4ECCCR(flctl));
 	}
 
-	printk(KERN_ERR "wait_recfifo_ready(): Timeout occured \n");
+	timeout_error(flctl, __func__);
 	return 1;	/* timeout */
 }
 
@@ -214,7 +222,7 @@ static void wait_wecfifo_ready(struct sh
 			return;
 		udelay(1);
 	}
-	printk(KERN_ERR "wait_wecfifo_ready(): Timeout occured \n");
+	timeout_error(flctl, __func__);
 }
 
 static void read_datareg(struct sh_flctl *flctl, int offset)
@@ -275,7 +283,7 @@ static void write_fiforeg(struct sh_flct
 static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val)
 {
 	struct sh_flctl *flctl = mtd_to_flctl(mtd);
-	uint32_t flcmncr_val = readl(FLCMNCR(flctl));
+	uint32_t flcmncr_val = readl(FLCMNCR(flctl)) & ~SEL_16BIT;
 	uint32_t flcmdcr_val, addr_len_bytes = 0;
 
 	/* Set SNAND bit if page size is 2048byte */
@@ -297,6 +305,8 @@ static void set_cmd_regs(struct mtd_info
 	case NAND_CMD_READOOB:
 		addr_len_bytes = flctl->rw_ADRCNT;
 		flcmdcr_val |= CDSRC_E;
+		if (flctl->chip.options & NAND_BUSWIDTH_16)
+			flcmncr_val |= SEL_16BIT;
 		break;
 	case NAND_CMD_SEQIN:
 		/* This case is that cmd is READ0 or READ1 or READ00 */
@@ -305,6 +315,8 @@ static void set_cmd_regs(struct mtd_info
 	case NAND_CMD_PAGEPROG:
 		addr_len_bytes = flctl->rw_ADRCNT;
 		flcmdcr_val |= DOCMD2_E | CDSRC_E | SELRW;
+		if (flctl->chip.options & NAND_BUSWIDTH_16)
+			flcmncr_val |= SEL_16BIT;
 		break;
 	case NAND_CMD_READID:
 		flcmncr_val &= ~SNAND_E;
@@ -523,6 +535,8 @@ static void flctl_cmdfunc(struct mtd_inf
 		set_addr(mtd, 0, page_addr);
 
 		flctl->read_bytes = mtd->writesize + mtd->oobsize;
+		if (flctl->chip.options & NAND_BUSWIDTH_16)
+			column >>= 1;
 		flctl->index += column;
 		goto read_normal_exit;
 
@@ -686,6 +700,18 @@ static uint8_t flctl_read_byte(struct mt
 	return data;
 }
 
+static uint16_t flctl_read_word(struct mtd_info *mtd)
+{
+       struct sh_flctl *flctl = mtd_to_flctl(mtd);
+       int index = flctl->index;
+       uint16_t data;
+       uint16_t *buf = (uint16_t *)&flctl->done_buff[index];
+
+       data = *buf;
+       flctl->index += 2;
+       return data;
+}
+
 static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 {
 	int i;
@@ -769,38 +795,36 @@ static int flctl_chip_init_tail(struct m
 	return 0;
 }
 
-static int __init flctl_probe(struct platform_device *pdev)
+static int __devinit flctl_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	struct sh_flctl *flctl;
 	struct mtd_info *flctl_mtd;
 	struct nand_chip *nand;
 	struct sh_flctl_platform_data *pdata;
-	int ret;
+	int ret = -ENXIO;
 
 	pdata = pdev->dev.platform_data;
 	if (pdata == NULL) {
-		printk(KERN_ERR "sh_flctl platform_data not found.\n");
-		return -ENODEV;
+		dev_err(&pdev->dev, "no platform data defined\n");
+		return -EINVAL;
 	}
 
 	flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL);
 	if (!flctl) {
-		printk(KERN_ERR "Unable to allocate NAND MTD dev structure.\n");
+		dev_err(&pdev->dev, "failed to allocate driver data\n");
 		return -ENOMEM;
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
-		printk(KERN_ERR "%s: resource not found.\n", __func__);
-		ret = -ENODEV;
+		dev_err(&pdev->dev, "failed to get I/O memory\n");
 		goto err;
 	}
 
-	flctl->reg = ioremap(res->start, res->end - res->start + 1);
+	flctl->reg = ioremap(res->start, resource_size(res));
 	if (flctl->reg == NULL) {
-		printk(KERN_ERR "%s: ioremap error.\n", __func__);
-		ret = -ENOMEM;
+		dev_err(&pdev->dev, "failed to remap I/O memory\n");
 		goto err;
 	}
 
@@ -808,6 +832,7 @@ static int __init flctl_probe(struct pla
 	flctl_mtd = &flctl->mtd;
 	nand = &flctl->chip;
 	flctl_mtd->priv = nand;
+	flctl->pdev = pdev;
 	flctl->hwecc = pdata->has_hwecc;
 
 	flctl_register_init(flctl, pdata->flcmncr_val);
@@ -825,6 +850,11 @@ static int __init flctl_probe(struct pla
 	nand->select_chip = flctl_select_chip;
 	nand->cmdfunc = flctl_cmdfunc;
 
+	if (pdata->flcmncr_val & SEL_16BIT) {
+		nand->options |= NAND_BUSWIDTH_16;
+		nand->read_word = flctl_read_word;
+	}
+
 	ret = nand_scan_ident(flctl_mtd, 1);
 	if (ret)
 		goto err;
@@ -846,7 +876,7 @@ err:
 	return ret;
 }
 
-static int __exit flctl_remove(struct platform_device *pdev)
+static int __devexit flctl_remove(struct platform_device *pdev)
 {
 	struct sh_flctl *flctl = platform_get_drvdata(pdev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/nand/tmio_nand.c linux-libre-2.6.34-gnu1/drivers/mtd/nand/tmio_nand.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/nand/tmio_nand.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/nand/tmio_nand.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
+#include <linux/slab.h>
 
 /*--------------------------------------------------------------------------*/
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/ofpart.c linux-libre-2.6.34-gnu1/drivers/mtd/ofpart.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/ofpart.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/ofpart.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/of.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/mtd/partitions.h>
 
 int __devinit of_mtd_parse_partitions(struct device *dev,
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/onenand/omap2.c linux-libre-2.6.34-gnu1/drivers/mtd/onenand/omap2.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/onenand/omap2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/onenand/omap2.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/mach/flash.h>
 #include <plat/gpmc.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/onenand/onenand_base.c linux-libre-2.6.34-gnu1/drivers/mtd/onenand/onenand_base.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/onenand/onenand_base.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/onenand/onenand_base.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/onenand/onenand_sim.c linux-libre-2.6.34-gnu1/drivers/mtd/onenand/onenand_sim.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/onenand/onenand_sim.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/onenand/onenand_sim.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/vmalloc.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_nandecctest.c linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_nandecctest.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_nandecctest.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_nandecctest.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/list.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/string.h>
 #include <linux/bitops.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_oobtest.c linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_oobtest.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_oobtest.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_oobtest.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/moduleparam.h>
 #include <linux/err.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #define PRINT_PREF KERN_INFO "mtd_oobtest: "
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_pagetest.c linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_pagetest.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_pagetest.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_pagetest.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/moduleparam.h>
 #include <linux/err.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #define PRINT_PREF KERN_INFO "mtd_pagetest: "
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_readtest.c linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_readtest.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_readtest.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_readtest.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/moduleparam.h>
 #include <linux/err.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #define PRINT_PREF KERN_INFO "mtd_readtest: "
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_speedtest.c linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_speedtest.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_speedtest.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_speedtest.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/moduleparam.h>
 #include <linux/err.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #define PRINT_PREF KERN_INFO "mtd_speedtest: "
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_stresstest.c linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_stresstest.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_stresstest.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_stresstest.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/moduleparam.h>
 #include <linux/err.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/vmalloc.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_subpagetest.c linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_subpagetest.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_subpagetest.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_subpagetest.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/moduleparam.h>
 #include <linux/err.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #define PRINT_PREF KERN_INFO "mtd_subpagetest: "
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_torturetest.c linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_torturetest.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_torturetest.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/tests/mtd_torturetest.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/moduleparam.h>
 #include <linux/err.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #define PRINT_PREF KERN_INFO "mtd_torturetest: "
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/ubi/build.c linux-libre-2.6.34-gnu1/drivers/mtd/ubi/build.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/ubi/build.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/ubi/build.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,12 +37,14 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/stringify.h>
+#include <linux/namei.h>
 #include <linux/stat.h>
 #include <linux/miscdevice.h>
 #include <linux/log2.h>
 #include <linux/kthread.h>
 #include <linux/reboot.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include "ubi.h"
 
 /* Maximum length of the 'mtd=' parameter */
@@ -50,7 +52,8 @@
 
 /**
  * struct mtd_dev_param - MTD device parameter description data structure.
- * @name: MTD device name or number string
+ * @name: MTD character device node path, MTD device name, or MTD device number
+ *        string
  * @vid_hdr_offs: VID header offset
  */
 struct mtd_dev_param {
@@ -59,10 +62,10 @@ struct mtd_dev_param {
 };
 
 /* Numbers of elements set in the @mtd_dev_param array */
-static int mtd_devs;
+static int __initdata mtd_devs;
 
 /* MTD devices specification parameters */
-static struct mtd_dev_param mtd_dev_param[UBI_MAX_DEVICES];
+static struct mtd_dev_param __initdata mtd_dev_param[UBI_MAX_DEVICES];
 
 /* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */
 struct class *ubi_class;
@@ -87,7 +90,8 @@ DEFINE_MUTEX(ubi_devices_mutex);
 static DEFINE_SPINLOCK(ubi_devices_lock);
 
 /* "Show" method for files in '/<sysfs>/class/ubi/' */
-static ssize_t ubi_version_show(struct class *class, char *buf)
+static ssize_t ubi_version_show(struct class *class, struct class_attribute *attr,
+				char *buf)
 {
 	return sprintf(buf, "%d\n", UBI_VERSION);
 }
@@ -363,11 +367,13 @@ static void dev_release(struct device *d
 /**
  * ubi_sysfs_init - initialize sysfs for an UBI device.
  * @ubi: UBI device description object
+ * @ref: set to %1 on exit in case of failure if a reference to @ubi->dev was
+ *       taken
  *
  * This function returns zero in case of success and a negative error code in
  * case of failure.
  */
-static int ubi_sysfs_init(struct ubi_device *ubi)
+static int ubi_sysfs_init(struct ubi_device *ubi, int *ref)
 {
 	int err;
 
@@ -379,6 +385,7 @@ static int ubi_sysfs_init(struct ubi_dev
 	if (err)
 		return err;
 
+	*ref = 1;
 	err = device_create_file(&ubi->dev, &dev_eraseblock_size);
 	if (err)
 		return err;
@@ -434,7 +441,7 @@ static void ubi_sysfs_close(struct ubi_d
 }
 
 /**
- * kill_volumes - destroy all volumes.
+ * kill_volumes - destroy all user volumes.
  * @ubi: UBI device description object
  */
 static void kill_volumes(struct ubi_device *ubi)
@@ -447,36 +454,29 @@ static void kill_volumes(struct ubi_devi
 }
 
 /**
- * free_user_volumes - free all user volumes.
- * @ubi: UBI device description object
- *
- * Normally the volumes are freed at the release function of the volume device
- * objects. However, on error paths the volumes have to be freed before the
- * device objects have been initialized.
- */
-static void free_user_volumes(struct ubi_device *ubi)
-{
-	int i;
-
-	for (i = 0; i < ubi->vtbl_slots; i++)
-		if (ubi->volumes[i]) {
-			kfree(ubi->volumes[i]->eba_tbl);
-			kfree(ubi->volumes[i]);
-		}
-}
-
-/**
  * uif_init - initialize user interfaces for an UBI device.
  * @ubi: UBI device description object
+ * @ref: set to %1 on exit in case of failure if a reference to @ubi->dev was
+ *       taken, otherwise set to %0
+ *
+ * This function initializes various user interfaces for an UBI device. If the
+ * initialization fails at an early stage, this function frees all the
+ * resources it allocated, returns an error, and @ref is set to %0. However,
+ * if the initialization fails after the UBI device was registered in the
+ * driver core subsystem, this function takes a reference to @ubi->dev, because
+ * otherwise the release function ('dev_release()') would free whole @ubi
+ * object. The @ref argument is set to %1 in this case. The caller has to put
+ * this reference.
  *
  * This function returns zero in case of success and a negative error code in
- * case of failure. Note, this function destroys all volumes if it fails.
+ * case of failure.
  */
-static int uif_init(struct ubi_device *ubi)
+static int uif_init(struct ubi_device *ubi, int *ref)
 {
 	int i, err;
 	dev_t dev;
 
+	*ref = 0;
 	sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
 
 	/*
@@ -504,7 +504,7 @@ static int uif_init(struct ubi_device *u
 		goto out_unreg;
 	}
 
-	err = ubi_sysfs_init(ubi);
+	err = ubi_sysfs_init(ubi, ref);
 	if (err)
 		goto out_sysfs;
 
@@ -522,6 +522,8 @@ static int uif_init(struct ubi_device *u
 out_volumes:
 	kill_volumes(ubi);
 out_sysfs:
+	if (*ref)
+		get_device(&ubi->dev);
 	ubi_sysfs_close(ubi);
 	cdev_del(&ubi->cdev);
 out_unreg:
@@ -875,7 +877,7 @@ static int ubi_reboot_notifier(struct no
 int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
 {
 	struct ubi_device *ubi;
-	int i, err, do_free = 1;
+	int i, err, ref = 0;
 
 	/*
 	 * Check if we already have the same MTD device attached.
@@ -975,9 +977,9 @@ int ubi_attach_mtd_dev(struct mtd_info *
 			goto out_detach;
 	}
 
-	err = uif_init(ubi);
+	err = uif_init(ubi, &ref);
 	if (err)
-		goto out_nofree;
+		goto out_detach;
 
 	ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name);
 	if (IS_ERR(ubi->bgt_thread)) {
@@ -1025,12 +1027,8 @@ int ubi_attach_mtd_dev(struct mtd_info *
 
 out_uif:
 	uif_close(ubi);
-out_nofree:
-	do_free = 0;
 out_detach:
 	ubi_wl_close(ubi);
-	if (do_free)
-		free_user_volumes(ubi);
 	free_internal_volumes(ubi);
 	vfree(ubi->vtbl);
 out_free:
@@ -1039,7 +1037,10 @@ out_free:
 #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
 	vfree(ubi->dbg_peb_buf);
 #endif
-	kfree(ubi);
+	if (ref)
+		put_device(&ubi->dev);
+	else
+		kfree(ubi);
 	return err;
 }
 
@@ -1096,7 +1097,7 @@ int ubi_detach_mtd_dev(int ubi_num, int
 
 	/*
 	 * Get a reference to the device in order to prevent 'dev_release()'
-	 * from freeing @ubi object.
+	 * from freeing the @ubi object.
 	 */
 	get_device(&ubi->dev);
 
@@ -1116,13 +1117,50 @@ int ubi_detach_mtd_dev(int ubi_num, int
 }
 
 /**
- * find_mtd_device - open an MTD device by its name or number.
- * @mtd_dev: name or number of the device
+ * open_mtd_by_chdev - open an MTD device by its character device node path.
+ * @mtd_dev: MTD character device node path
+ *
+ * This helper function opens an MTD device by its character node device path.
+ * Returns MTD device description object in case of success and a negative
+ * error code in case of failure.
+ */
+static struct mtd_info * __init open_mtd_by_chdev(const char *mtd_dev)
+{
+	int err, major, minor, mode;
+	struct path path;
+
+	/* Probably this is an MTD character device node path */
+	err = kern_path(mtd_dev, LOOKUP_FOLLOW, &path);
+	if (err)
+		return ERR_PTR(err);
+
+	/* MTD device number is defined by the major / minor numbers */
+	major = imajor(path.dentry->d_inode);
+	minor = iminor(path.dentry->d_inode);
+	mode = path.dentry->d_inode->i_mode;
+	path_put(&path);
+	if (major != MTD_CHAR_MAJOR || !S_ISCHR(mode))
+		return ERR_PTR(-EINVAL);
+
+	if (minor & 1)
+		/*
+		 * Just do not think the "/dev/mtdrX" devices support is need,
+		 * so do not support them to avoid doing extra work.
+		 */
+		return ERR_PTR(-EINVAL);
+
+	return get_mtd_device(NULL, minor / 2);
+}
+
+/**
+ * open_mtd_device - open MTD device by name, character device path, or number.
+ * @mtd_dev: name, character device node path, or MTD device device number
  *
  * This function tries to open and MTD device described by @mtd_dev string,
- * which is first treated as an ASCII number, and if it is not true, it is
- * treated as MTD device name. Returns MTD device description object in case of
- * success and a negative error code in case of failure.
+ * which is first treated as ASCII MTD device number, and if it is not true, it
+ * is treated as MTD device name, and if that is also not true, it is treated
+ * as MTD character device node path. Returns MTD device description object in
+ * case of success and a negative error code in case of failure.
  */
 static struct mtd_info * __init open_mtd_device(const char *mtd_dev)
 {
@@ -1137,6 +1175,9 @@ static struct mtd_info * __init open_mtd
 		 * MTD device name.
 		 */
 		mtd = get_mtd_device_nm(mtd_dev);
+		if (IS_ERR(mtd) && PTR_ERR(mtd) == -ENODEV)
+			/* Probably this is an MTD character device node path */
+			mtd = open_mtd_by_chdev(mtd_dev);
 	} else
 		mtd = get_mtd_device(NULL, mtd_num);
 
@@ -1352,13 +1393,15 @@ static int __init ubi_mtd_param_parse(co
 
 module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 000);
 MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: "
-		      "mtd=<name|num>[,<vid_hdr_offs>].\n"
+		      "mtd=<name|num|path>[,<vid_hdr_offs>].\n"
 		      "Multiple \"mtd\" parameters may be specified.\n"
-		      "MTD devices may be specified by their number or name.\n"
+		      "MTD devices may be specified by their number, name, or "
+		      "path to the MTD character device node.\n"
 		      "Optional \"vid_hdr_offs\" parameter specifies UBI VID "
-		      "header position and data starting position to be used "
-		      "by UBI.\n"
-		      "Example: mtd=content,1984 mtd=4 - attach MTD device"
+		      "header position to be used by UBI.\n"
+		      "Example 1: mtd=/dev/mtd0 - attach MTD device "
+		      "/dev/mtd0.\n"
+		      "Example 2: mtd=content,1984 mtd=4 - attach MTD device "
 		      "with name \"content\" using VID header offset 1984, and "
 		      "MTD device number 4 with default VID header offset.");
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/ubi/cdev.c linux-libre-2.6.34-gnu1/drivers/mtd/ubi/cdev.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/ubi/cdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/ubi/cdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 
 #include <linux/module.h>
 #include <linux/stat.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <linux/capability.h>
 #include <linux/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/ubi/debug.h linux-libre-2.6.34-gnu1/drivers/mtd/ubi/debug.h
--- linux-libre-2.6.33-gnu1/drivers/mtd/ubi/debug.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/ubi/debug.h	2010-05-16 17:17:36.000000000 -0400
@@ -96,8 +96,11 @@ void ubi_dbg_dump_flash(struct ubi_devic
 
 #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
 int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len);
+int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
+			int offset, int len);
 #else
 #define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0
+#define ubi_dbg_check_write(ubi, buf, pnum, offset, len) 0
 #endif
 
 #ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT
@@ -176,6 +179,7 @@ static inline int ubi_dbg_is_erase_failu
 #define ubi_dbg_is_write_failure() 0
 #define ubi_dbg_is_erase_failure() 0
 #define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0
+#define ubi_dbg_check_write(ubi, buf, pnum, offset, len) 0
 
 #endif /* !CONFIG_MTD_UBI_DEBUG */
 #endif /* !__UBI_DEBUG_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/ubi/gluebi.c linux-libre-2.6.34-gnu1/drivers/mtd/ubi/gluebi.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/ubi/gluebi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/ubi/gluebi.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 
 #include <linux/err.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/math64.h>
 #include <linux/module.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/ubi/io.c linux-libre-2.6.34-gnu1/drivers/mtd/ubi/io.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/ubi/io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/ubi/io.c	2010-05-16 17:17:36.000000000 -0400
@@ -88,6 +88,7 @@
 
 #include <linux/crc32.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include "ubi.h"
 
 #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
@@ -143,7 +144,7 @@ int ubi_io_read(const struct ubi_device
 
 	err = paranoid_check_not_bad(ubi, pnum);
 	if (err)
-		return err > 0 ? -EINVAL : err;
+		return err;
 
 	addr = (loff_t)pnum * ubi->peb_size + offset;
 retry:
@@ -236,12 +237,12 @@ int ubi_io_write(struct ubi_device *ubi,
 
 	err = paranoid_check_not_bad(ubi, pnum);
 	if (err)
-		return err > 0 ? -EINVAL : err;
+		return err;
 
 	/* The area we are writing to has to contain all 0xFF bytes */
 	err = ubi_dbg_check_all_ff(ubi, pnum, offset, len);
 	if (err)
-		return err > 0 ? -EINVAL : err;
+		return err;
 
 	if (offset >= ubi->leb_start) {
 		/*
@@ -250,10 +251,10 @@ int ubi_io_write(struct ubi_device *ubi,
 		 */
 		err = paranoid_check_peb_ec_hdr(ubi, pnum);
 		if (err)
-			return err > 0 ? -EINVAL : err;
+			return err;
 		err = paranoid_check_peb_vid_hdr(ubi, pnum);
 		if (err)
-			return err > 0 ? -EINVAL : err;
+			return err;
 	}
 
 	if (ubi_dbg_is_write_failure()) {
@@ -273,6 +274,21 @@ int ubi_io_write(struct ubi_device *ubi,
 	} else
 		ubi_assert(written == len);
 
+	if (!err) {
+		err = ubi_dbg_check_write(ubi, buf, pnum, offset, len);
+		if (err)
+			return err;
+
+		/*
+		 * Since we always write sequentially, the rest of the PEB has
+		 * to contain only 0xFF bytes.
+		 */
+		offset += len;
+		len = ubi->peb_size - offset;
+		if (len)
+			err = ubi_dbg_check_all_ff(ubi, pnum, offset, len);
+	}
+
 	return err;
 }
 
@@ -348,7 +364,7 @@ retry:
 
 	err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size);
 	if (err)
-		return err > 0 ? -EINVAL : err;
+		return err;
 
 	if (ubi_dbg_is_erase_failure() && !err) {
 		dbg_err("cannot erase PEB %d (emulated)", pnum);
@@ -542,7 +558,7 @@ int ubi_io_sync_erase(struct ubi_device
 
 	err = paranoid_check_not_bad(ubi, pnum);
 	if (err != 0)
-		return err > 0 ? -EINVAL : err;
+		return err;
 
 	if (ubi->ro_mode) {
 		ubi_err("read-only mode");
@@ -819,7 +835,7 @@ int ubi_io_write_ec_hdr(struct ubi_devic
 
 	err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr);
 	if (err)
-		return -EINVAL;
+		return err;
 
 	err = ubi_io_write(ubi, ec_hdr, pnum, 0, ubi->ec_hdr_alsize);
 	return err;
@@ -1083,7 +1099,7 @@ int ubi_io_write_vid_hdr(struct ubi_devi
 
 	err = paranoid_check_peb_ec_hdr(ubi, pnum);
 	if (err)
-		return err > 0 ? -EINVAL : err;
+		return err;
 
 	vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC);
 	vid_hdr->version = UBI_VERSION;
@@ -1092,7 +1108,7 @@ int ubi_io_write_vid_hdr(struct ubi_devi
 
 	err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr);
 	if (err)
-		return -EINVAL;
+		return err;
 
 	p = (char *)vid_hdr - ubi->vid_hdr_shift;
 	err = ubi_io_write(ubi, p, pnum, ubi->vid_hdr_aloffset,
@@ -1107,8 +1123,8 @@ int ubi_io_write_vid_hdr(struct ubi_devi
  * @ubi: UBI device description object
  * @pnum: physical eraseblock number to check
  *
- * This function returns zero if the physical eraseblock is good, a positive
- * number if it is bad and a negative error code if an error occurred.
+ * This function returns zero if the physical eraseblock is good, %-EINVAL if
+ * it is bad and a negative error code if an error occurred.
  */
 static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum)
 {
@@ -1120,7 +1136,7 @@ static int paranoid_check_not_bad(const
 
 	ubi_err("paranoid check failed for PEB %d", pnum);
 	ubi_dbg_dump_stack();
-	return err;
+	return err > 0 ? -EINVAL : err;
 }
 
 /**
@@ -1130,7 +1146,7 @@ static int paranoid_check_not_bad(const
  * @ec_hdr: the erase counter header to check
  *
  * This function returns zero if the erase counter header contains valid
- * values, and %1 if not.
+ * values, and %-EINVAL if not.
  */
 static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
 				 const struct ubi_ec_hdr *ec_hdr)
@@ -1156,7 +1172,7 @@ static int paranoid_check_ec_hdr(const s
 fail:
 	ubi_dbg_dump_ec_hdr(ec_hdr);
 	ubi_dbg_dump_stack();
-	return 1;
+	return -EINVAL;
 }
 
 /**
@@ -1164,8 +1180,8 @@ fail:
  * @ubi: UBI device description object
  * @pnum: the physical eraseblock number to check
  *
- * This function returns zero if the erase counter header is all right, %1 if
- * not, and a negative error code if an error occurred.
+ * This function returns zero if the erase counter header is all right and and
+ * a negative error code if not or if an error occurred.
  */
 static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum)
 {
@@ -1188,7 +1204,7 @@ static int paranoid_check_peb_ec_hdr(con
 		ubi_err("paranoid check failed for PEB %d", pnum);
 		ubi_dbg_dump_ec_hdr(ec_hdr);
 		ubi_dbg_dump_stack();
-		err = 1;
+		err = -EINVAL;
 		goto exit;
 	}
 
@@ -1206,7 +1222,7 @@ exit:
  * @vid_hdr: the volume identifier header to check
  *
  * This function returns zero if the volume identifier header is all right, and
- * %1 if not.
+ * %-EINVAL if not.
  */
 static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum,
 				  const struct ubi_vid_hdr *vid_hdr)
@@ -1233,7 +1249,7 @@ fail:
 	ubi_err("paranoid check failed for PEB %d", pnum);
 	ubi_dbg_dump_vid_hdr(vid_hdr);
 	ubi_dbg_dump_stack();
-	return 1;
+	return -EINVAL;
 
 }
 
@@ -1243,7 +1259,7 @@ fail:
  * @pnum: the physical eraseblock number to check
  *
  * This function returns zero if the volume identifier header is all right,
- * %1 if not, and a negative error code if an error occurred.
+ * and a negative error code if not or if an error occurred.
  */
 static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
 {
@@ -1270,7 +1286,7 @@ static int paranoid_check_peb_vid_hdr(co
 		ubi_err("paranoid check failed for PEB %d", pnum);
 		ubi_dbg_dump_vid_hdr(vid_hdr);
 		ubi_dbg_dump_stack();
-		err = 1;
+		err = -EINVAL;
 		goto exit;
 	}
 
@@ -1282,6 +1298,61 @@ exit:
 }
 
 /**
+ * ubi_dbg_check_write - make sure write succeeded.
+ * @ubi: UBI device description object
+ * @buf: buffer with data which were written
+ * @pnum: physical eraseblock number the data were written to
+ * @offset: offset within the physical eraseblock the data were written to
+ * @len: how many bytes were written
+ *
+ * This functions reads data which were recently written and compares it with
+ * the original data buffer - the data have to match. Returns zero if the data
+ * match and a negative error code if not or in case of failure.
+ */
+int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
+			int offset, int len)
+{
+	int err, i;
+
+	mutex_lock(&ubi->dbg_buf_mutex);
+	err = ubi_io_read(ubi, ubi->dbg_peb_buf, pnum, offset, len);
+	if (err)
+		goto out_unlock;
+
+	for (i = 0; i < len; i++) {
+		uint8_t c = ((uint8_t *)buf)[i];
+		uint8_t c1 = ((uint8_t *)ubi->dbg_peb_buf)[i];
+		int dump_len;
+
+		if (c == c1)
+			continue;
+
+		ubi_err("paranoid check failed for PEB %d:%d, len %d",
+			pnum, offset, len);
+		ubi_msg("data differ at position %d", i);
+		dump_len = max_t(int, 128, len - i);
+		ubi_msg("hex dump of the original buffer from %d to %d",
+			i, i + dump_len);
+		print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
+			       buf + i, dump_len, 1);
+		ubi_msg("hex dump of the read buffer from %d to %d",
+			i, i + dump_len);
+		print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
+			       ubi->dbg_peb_buf + i, dump_len, 1);
+		ubi_dbg_dump_stack();
+		err = -EINVAL;
+		goto out_unlock;
+	}
+	mutex_unlock(&ubi->dbg_buf_mutex);
+
+	return 0;
+
+out_unlock:
+	mutex_unlock(&ubi->dbg_buf_mutex);
+	return err;
+}
+
+/**
  * ubi_dbg_check_all_ff - check that a region of flash is empty.
  * @ubi: UBI device description object
  * @pnum: the physical eraseblock number to check
@@ -1289,8 +1360,8 @@ exit:
  * @len: the length of the region to check
  *
  * This function returns zero if only 0xFF bytes are present at offset
- * @offset of the physical eraseblock @pnum, %1 if not, and a negative error
- * code if an error occurred.
+ * @offset of the physical eraseblock @pnum, and a negative error code if not
+ * or if an error occurred.
  */
 int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
 {
@@ -1321,7 +1392,7 @@ fail:
 	ubi_msg("hex dump of the %d-%d region", offset, offset + len);
 	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
 		       ubi->dbg_peb_buf, len, 1);
-	err = 1;
+	err = -EINVAL;
 error:
 	ubi_dbg_dump_stack();
 	mutex_unlock(&ubi->dbg_buf_mutex);
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/ubi/kapi.c linux-libre-2.6.34-gnu1/drivers/mtd/ubi/kapi.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/ubi/kapi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/ubi/kapi.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/namei.h>
 #include <linux/fs.h>
 #include <asm/div64.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/ubi/scan.c linux-libre-2.6.34-gnu1/drivers/mtd/ubi/scan.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/ubi/scan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/ubi/scan.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/crc32.h>
 #include <linux/math64.h>
 #include "ubi.h"
@@ -974,11 +975,8 @@ struct ubi_scan_info *ubi_scan(struct ub
 			seb->ec = si->mean_ec;
 
 	err = paranoid_check_si(ubi, si);
-	if (err) {
-		if (err > 0)
-			err = -EINVAL;
+	if (err)
 		goto out_vidh;
-	}
 
 	ubi_free_vid_hdr(ubi, vidh);
 	kfree(ech);
@@ -1086,8 +1084,8 @@ void ubi_scan_destroy_si(struct ubi_scan
  * @ubi: UBI device description object
  * @si: scanning information
  *
- * This function returns zero if the scanning information is all right, %1 if
- * not and a negative error code if an error occurred.
+ * This function returns zero if the scanning information is all right, and a
+ * negative error code if not or if an error occurred.
  */
 static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si)
 {
@@ -1346,7 +1344,7 @@ bad_vid_hdr:
 
 out:
 	ubi_dbg_dump_stack();
-	return 1;
+	return -EINVAL;
 }
 
 #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/ubi/ubi.h linux-libre-2.6.34-gnu1/drivers/mtd/ubi/ubi.h
--- linux-libre-2.6.33-gnu1/drivers/mtd/ubi/ubi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/ubi/ubi.h	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/fs.h>
 #include <linux/cdev.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
 #include <linux/notifier.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/ubi/vmt.c linux-libre-2.6.34-gnu1/drivers/mtd/ubi/vmt.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/ubi/vmt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/ubi/vmt.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 
 #include <linux/err.h>
 #include <linux/math64.h>
+#include <linux/slab.h>
 #include "ubi.h"
 
 #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/ubi/vtbl.c linux-libre-2.6.34-gnu1/drivers/mtd/ubi/vtbl.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/ubi/vtbl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/ubi/vtbl.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,6 +58,7 @@
 
 #include <linux/crc32.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <asm/div64.h>
 #include "ubi.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/mtd/ubi/wl.c linux-libre-2.6.34-gnu1/drivers/mtd/ubi/wl.c
--- linux-libre-2.6.33-gnu1/drivers/mtd/ubi/wl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/mtd/ubi/wl.c	2010-05-16 17:17:36.000000000 -0400
@@ -464,7 +464,7 @@ retry:
 				   ubi->peb_size - ubi->vid_hdr_aloffset);
 	if (err) {
 		ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum);
-		return err > 0 ? -EINVAL : err;
+		return err;
 	}
 
 	return e->pnum;
@@ -513,7 +513,7 @@ static int sync_erase(struct ubi_device
 	dbg_wl("erase PEB %d, old EC %llu", e->pnum, ec);
 
 	err = paranoid_check_ec(ubi, e->pnum, e->ec);
-	if (err > 0)
+	if (err)
 		return -EINVAL;
 
 	ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS);
@@ -1572,8 +1572,7 @@ void ubi_wl_close(struct ubi_device *ubi
  * @ec: the erase counter to check
  *
  * This function returns zero if the erase counter of physical eraseblock @pnum
- * is equivalent to @ec, %1 if not, and a negative error code if an error
- * occurred.
+ * is equivalent to @ec, and a negative error code if not or if an error occurred.
  */
 static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec)
 {
@@ -1611,8 +1610,8 @@ out_free:
  * @e: the wear-leveling entry to check
  * @root: the root of the tree
  *
- * This function returns zero if @e is in the @root RB-tree and %1 if it is
- * not.
+ * This function returns zero if @e is in the @root RB-tree and %-EINVAL if it
+ * is not.
  */
 static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e,
 				     struct rb_root *root)
@@ -1623,7 +1622,7 @@ static int paranoid_check_in_wl_tree(str
 	ubi_err("paranoid check failed for PEB %d, EC %d, RB-tree %p ",
 		e->pnum, e->ec, root);
 	ubi_dbg_dump_stack();
-	return 1;
+	return -EINVAL;
 }
 
 /**
@@ -1632,7 +1631,7 @@ static int paranoid_check_in_wl_tree(str
  * @ubi: UBI device description object
  * @e: the wear-leveling entry to check
  *
- * This function returns zero if @e is in @ubi->pq and %1 if it is not.
+ * This function returns zero if @e is in @ubi->pq and %-EINVAL if it is not.
  */
 static int paranoid_check_in_pq(struct ubi_device *ubi, struct ubi_wl_entry *e)
 {
@@ -1647,6 +1646,6 @@ static int paranoid_check_in_pq(struct u
 	ubi_err("paranoid check failed for PEB %d, EC %d, Protect queue",
 		e->pnum, e->ec);
 	ubi_dbg_dump_stack();
-	return 1;
+	return -EINVAL;
 }
 #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/3c501.c linux-libre-2.6.34-gnu1/drivers/net/3c501.c
--- linux-libre-2.6.33-gnu1/drivers/net/3c501.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/3c501.c	2010-05-16 17:17:36.000000000 -0400
@@ -117,7 +117,6 @@ static const char version[] =
 #include <linux/fcntl.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/spinlock.h>
@@ -812,7 +811,7 @@ static void set_multicast_list(struct ne
 	if (dev->flags & IFF_PROMISC) {
 		outb(RX_PROM, RX_CMD);
 		inb(RX_STATUS);
-	} else if (dev->mc_list || dev->flags & IFF_ALLMULTI) {
+	} else if (!netdev_mc_empty(dev) || dev->flags & IFF_ALLMULTI) {
 		/* Multicast or all multicast is the same */
 		outb(RX_MULT, RX_CMD);
 		inb(RX_STATUS);		/* Clear status. */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/3c505.c linux-libre-2.6.34-gnu1/drivers/net/3c505.c
--- linux-libre-2.6.33-gnu1/drivers/net/3c505.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/3c505.c	2010-05-16 17:17:36.000000000 -0400
@@ -102,12 +102,12 @@
 #include <linux/interrupt.h>
 #include <linux/errno.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
 #include <linux/delay.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -1216,7 +1216,7 @@ static int elp_close(struct net_device *
 static void elp_set_mc_list(struct net_device *dev)
 {
 	elp_device *adapter = netdev_priv(dev);
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	int i;
 	unsigned long flags;
 
@@ -1229,11 +1229,10 @@ static void elp_set_mc_list(struct net_d
 		/* send a "load multicast list" command to the board, max 10 addrs/cmd */
 		/* if num_addrs==0 the list will be cleared */
 		adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST;
-		adapter->tx_pcb.length = 6 * dev->mc_count;
-		for (i = 0; i < dev->mc_count; i++) {
-			memcpy(adapter->tx_pcb.data.multicast[i], dmi->dmi_addr, 6);
-			dmi = dmi->next;
-		}
+		adapter->tx_pcb.length = 6 * netdev_mc_count(dev);
+		i = 0;
+		netdev_for_each_mc_addr(dmi, dev)
+			memcpy(adapter->tx_pcb.data.multicast[i++], dmi->dmi_addr, 6);
 		adapter->got[CMD_LOAD_MULTICAST_LIST] = 0;
 		if (!send_pcb(dev, &adapter->tx_pcb))
 			pr_err("%s: couldn't send set_multicast command\n", dev->name);
@@ -1244,7 +1243,7 @@ static void elp_set_mc_list(struct net_d
 				TIMEOUT_MSG(__LINE__);
 			}
 		}
-		if (dev->mc_count)
+		if (!netdev_mc_empty(dev))
 			adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD | RECV_MULTI;
 		else		/* num_addrs == 0 */
 			adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/3c507.c linux-libre-2.6.34-gnu1/drivers/net/3c507.c
--- linux-libre-2.6.33-gnu1/drivers/net/3c507.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/3c507.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,7 +58,6 @@ static const char version[] =
 #include <linux/etherdevice.h>
 #include <linux/if_ether.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/3c509.c linux-libre-2.6.34-gnu1/drivers/net/3c509.c
--- linux-libre-2.6.33-gnu1/drivers/net/3c509.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/3c509.c	2010-05-16 17:17:36.000000000 -0400
@@ -76,7 +76,6 @@
 #include <linux/interrupt.h>
 #include <linux/errno.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
@@ -1111,12 +1110,14 @@ set_multicast_list(struct net_device *de
 	unsigned long flags;
 	struct el3_private *lp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
+	int mc_count = netdev_mc_count(dev);
 
 	if (el3_debug > 1) {
 		static int old;
-		if (old != dev->mc_count) {
-			old = dev->mc_count;
-			pr_debug("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);
+		if (old != mc_count) {
+			old = mc_count;
+			pr_debug("%s: Setting Rx mode to %d addresses.\n",
+				 dev->name, mc_count);
 		}
 	}
 	spin_lock_irqsave(&lp->lock, flags);
@@ -1124,7 +1125,7 @@ set_multicast_list(struct net_device *de
 		outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,
 			 ioaddr + EL3_CMD);
 	}
-	else if (dev->mc_count || (dev->flags&IFF_ALLMULTI)) {
+	else if (mc_count || (dev->flags&IFF_ALLMULTI)) {
 		outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast, ioaddr + EL3_CMD);
 	}
 	else
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/3c515.c linux-libre-2.6.34-gnu1/drivers/net/3c515.c
--- linux-libre-2.6.33-gnu1/drivers/net/3c515.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/3c515.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,7 +65,6 @@ static int max_interrupt_work = 20;
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/etherdevice.h>
 #include <linux/interrupt.h>
@@ -1536,7 +1535,7 @@ static void set_rx_mode(struct net_devic
 			pr_debug("%s: Setting promiscuous mode.\n",
 			       dev->name);
 		new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm;
-	} else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
+	} else if (!netdev_mc_empty(dev) || dev->flags & IFF_ALLMULTI) {
 		new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast;
 	} else
 		new_mode = SetRxFilter | RxStation | RxBroadcast;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/3c523.c linux-libre-2.6.34-gnu1/drivers/net/3c523.c
--- linux-libre-2.6.33-gnu1/drivers/net/3c523.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/3c523.c	2010-05-16 17:17:36.000000000 -0400
@@ -99,7 +99,6 @@
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/mca-legacy.h>
@@ -625,8 +624,8 @@ static int init586(struct net_device *de
 	volatile struct iasetup_cmd_struct *ias_cmd;
 	volatile struct tdr_cmd_struct *tdr_cmd;
 	volatile struct mcsetup_cmd_struct *mc_cmd;
-	struct dev_mc_list *dmi = dev->mc_list;
-	int num_addrs = dev->mc_count;
+	struct dev_mc_list *dmi;
+	int num_addrs = netdev_mc_count(dev);
 
 	ptr = (void *) ((char *) p->scb + sizeof(struct scb_struct));
 
@@ -771,7 +770,7 @@ static int init586(struct net_device *de
 	 * Multicast setup
 	 */
 
-	if (dev->mc_count) {
+	if (num_addrs) {
 		/* I don't understand this: do we really need memory after the init? */
 		int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
 		if (len <= 0) {
@@ -787,10 +786,9 @@ static int init586(struct net_device *de
 			mc_cmd->cmd_cmd = CMD_MCSETUP | CMD_LAST;
 			mc_cmd->cmd_link = 0xffff;
 			mc_cmd->mc_cnt = num_addrs * 6;
-			for (i = 0; i < num_addrs; i++) {
-				memcpy((char *) mc_cmd->mc_list[i], dmi->dmi_addr, 6);
-				dmi = dmi->next;
-			}
+			i = 0;
+			netdev_for_each_mc_addr(dmi, dev)
+				memcpy((char *) mc_cmd->mc_list[i++], dmi->dmi_addr, 6);
 			p->scb->cbl_offset = make16(mc_cmd);
 			p->scb->cmd = CUC_START;
 			elmc_id_attn586();
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/3c527.c linux-libre-2.6.34-gnu1/drivers/net/3c527.c
--- linux-libre-2.6.33-gnu1/drivers/net/3c527.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/3c527.c	2010-05-16 17:17:36.000000000 -0400
@@ -1526,32 +1526,29 @@ static void do_mc32_set_multicast_list(s
 
 	if ((dev->flags&IFF_PROMISC) ||
 	    (dev->flags&IFF_ALLMULTI) ||
-	    dev->mc_count > 10)
+	    netdev_mc_count(dev) > 10)
 		/* Enable promiscuous mode */
 		filt |= 1;
-	else if(dev->mc_count)
+	else if (!netdev_mc_empty(dev))
 	{
 		unsigned char block[62];
 		unsigned char *bp;
-		struct dev_mc_list *dmc=dev->mc_list;
-
-		int i;
+		struct dev_mc_list *dmc;
 
 		if(retry==0)
 			lp->mc_list_valid = 0;
 		if(!lp->mc_list_valid)
 		{
 			block[1]=0;
-			block[0]=dev->mc_count;
+			block[0]=netdev_mc_count(dev);
 			bp=block+2;
 
-			for(i=0;i<dev->mc_count;i++)
-			{
+			netdev_for_each_mc_addr(dmc, dev) {
 				memcpy(bp, dmc->dmi_addr, 6);
 				bp+=6;
-				dmc=dmc->next;
 			}
-			if(mc32_command_nowait(dev, 2, block, 2+6*dev->mc_count)==-1)
+			if(mc32_command_nowait(dev, 2, block,
+					       2+6*netdev_mc_count(dev))==-1)
 			{
 				lp->mc_reload_wait = 1;
 				return;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/3c59x.c linux-libre-2.6.34-gnu1/drivers/net/3c59x.c
--- linux-libre-2.6.33-gnu1/drivers/net/3c59x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/3c59x.c	2010-05-16 17:17:36.000000000 -0400
@@ -77,7 +77,6 @@ static int vortex_debug = 1;
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/mii.h>
@@ -90,6 +89,7 @@ static int vortex_debug = 1;
 #include <linux/eisa.h>
 #include <linux/bitops.h>
 #include <linux/jiffies.h>
+#include <linux/gfp.h>
 #include <asm/irq.h>			/* For nr_irqs only. */
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -375,7 +375,7 @@ static struct vortex_chip_info {
 };
 
 
-static struct pci_device_id vortex_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(vortex_pci_tbl) = {
 	{ 0x10B7, 0x5900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C590 },
 	{ 0x10B7, 0x5920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C592 },
 	{ 0x10B7, 0x5970, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C597 },
@@ -2970,7 +2970,7 @@ static void set_rx_mode(struct net_devic
 		if (vortex_debug > 3)
 			pr_notice("%s: Setting promiscuous mode.\n", dev->name);
 		new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast|RxProm;
-	} else	if ((dev->mc_list)  ||  (dev->flags & IFF_ALLMULTI)) {
+	} else	if (!netdev_mc_empty(dev) || dev->flags & IFF_ALLMULTI) {
 		new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast;
 	} else
 		new_mode = SetRxFilter | RxStation | RxBroadcast;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/7990.c linux-libre-2.6.34-gnu1/drivers/net/7990.c
--- linux-libre-2.6.33-gnu1/drivers/net/7990.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/7990.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 #include <linux/ioport.h>
 #include <linux/in.h>
 #include <linux/route.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/skbuff.h>
 #include <asm/irq.h>
@@ -595,9 +594,8 @@ static void lance_load_multicast (struct
         struct lance_private *lp = netdev_priv(dev);
         volatile struct lance_init_block *ib = lp->init_block;
         volatile u16 *mcast_table = (u16 *)&ib->filter;
-        struct dev_mc_list *dmi=dev->mc_list;
+	struct dev_mc_list *dmi;
         char *addrs;
-        int i;
         u32 crc;
 
         /* set all multicast bits */
@@ -611,9 +609,8 @@ static void lance_load_multicast (struct
         ib->filter [1] = 0;
 
         /* Add addresses */
-        for (i = 0; i < dev->mc_count; i++){
+	netdev_for_each_mc_addr(dmi, dev) {
                 addrs = dmi->dmi_addr;
-                dmi   = dmi->next;
 
                 /* multicast address? */
                 if (!(*addrs & 1))
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/8139cp.c linux-libre-2.6.34-gnu1/drivers/net/8139cp.c
--- linux-libre-2.6.33-gnu1/drivers/net/8139cp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/8139cp.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,8 @@
 
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #define DRV_NAME		"8139cp"
 #define DRV_VERSION		"1.3"
 #define DRV_RELDATE		"Mar 22, 2004"
@@ -62,6 +64,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/ethtool.h>
+#include <linux/gfp.h>
 #include <linux/mii.h>
 #include <linux/if_vlan.h>
 #include <linux/crc32.h>
@@ -104,8 +107,6 @@ static int multicast_filter_limit = 32;
 module_param(multicast_filter_limit, int, 0);
 MODULE_PARM_DESC (multicast_filter_limit, "8139cp: maximum number of filtered multicast addresses");
 
-#define PFX			DRV_NAME ": "
-
 #define CP_DEF_MSG_ENABLE	(NETIF_MSG_DRV		| \
 				 NETIF_MSG_PROBE 	| \
 				 NETIF_MSG_LINK)
@@ -394,7 +395,7 @@ static int cp_get_eeprom(struct net_devi
 static int cp_set_eeprom(struct net_device *dev,
 			 struct ethtool_eeprom *eeprom, u8 *data);
 
-static struct pci_device_id cp_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(cp_pci_tbl) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	PCI_DEVICE_ID_REALTEK_8139), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_TTTECH,	PCI_DEVICE_ID_TTTECH_MC322), },
 	{ },
@@ -470,9 +471,8 @@ static inline void cp_rx_skb (struct cp_
 static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail,
 			    u32 status, u32 len)
 {
-	if (netif_msg_rx_err (cp))
-		pr_debug("%s: rx err, slot %d status 0x%x len %d\n",
-			cp->dev->name, rx_tail, status, len);
+	netif_dbg(cp, rx_err, cp->dev, "rx err, slot %d status 0x%x len %d\n",
+		  rx_tail, status, len);
 	cp->dev->stats.rx_errors++;
 	if (status & RxErrFrame)
 		cp->dev->stats.rx_frame_errors++;
@@ -545,9 +545,8 @@ rx_status_loop:
 			goto rx_next;
 		}
 
-		if (netif_msg_rx_status(cp))
-			pr_debug("%s: rx slot %d status 0x%x len %d\n",
-			       dev->name, rx_tail, status, len);
+		netif_dbg(cp, rx_status, dev, "rx slot %d status 0x%x len %d\n",
+			  rx_tail, status, len);
 
 		new_skb = netdev_alloc_skb_ip_align(dev, buflen);
 		if (!new_skb) {
@@ -621,9 +620,8 @@ static irqreturn_t cp_interrupt (int irq
 	if (!status || (status == 0xFFFF))
 		return IRQ_NONE;
 
-	if (netif_msg_intr(cp))
-		pr_debug("%s: intr, status %04x cmd %02x cpcmd %04x\n",
-		        dev->name, status, cpr8(Cmd), cpr16(CpCmd));
+	netif_dbg(cp, intr, dev, "intr, status %04x cmd %02x cpcmd %04x\n",
+		  status, cpr8(Cmd), cpr16(CpCmd));
 
 	cpw16(IntrStatus, status & ~cp_rx_intr_mask);
 
@@ -654,8 +652,8 @@ static irqreturn_t cp_interrupt (int irq
 
 		pci_read_config_word(cp->pdev, PCI_STATUS, &pci_status);
 		pci_write_config_word(cp->pdev, PCI_STATUS, pci_status);
-		pr_err("%s: PCI bus error, status=%04x, PCI status=%04x\n",
-		       dev->name, status, pci_status);
+		netdev_err(dev, "PCI bus error, status=%04x, PCI status=%04x\n",
+			   status, pci_status);
 
 		/* TODO: reset hardware */
 	}
@@ -700,9 +698,8 @@ static void cp_tx (struct cp_private *cp
 
 		if (status & LastFrag) {
 			if (status & (TxError | TxFIFOUnder)) {
-				if (netif_msg_tx_err(cp))
-					pr_debug("%s: tx err, status 0x%x\n",
-					       cp->dev->name, status);
+				netif_dbg(cp, tx_err, cp->dev,
+					  "tx err, status 0x%x\n", status);
 				cp->dev->stats.tx_errors++;
 				if (status & TxOWC)
 					cp->dev->stats.tx_window_errors++;
@@ -717,8 +714,8 @@ static void cp_tx (struct cp_private *cp
 					((status >> TxColCntShift) & TxColCntMask);
 				cp->dev->stats.tx_packets++;
 				cp->dev->stats.tx_bytes += skb->len;
-				if (netif_msg_tx_done(cp))
-					pr_debug("%s: tx done, slot %d\n", cp->dev->name, tx_tail);
+				netif_dbg(cp, tx_done, cp->dev,
+					  "tx done, slot %d\n", tx_tail);
 			}
 			dev_kfree_skb_irq(skb);
 		}
@@ -752,8 +749,7 @@ static netdev_tx_t cp_start_xmit (struct
 	if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) {
 		netif_stop_queue(dev);
 		spin_unlock_irqrestore(&cp->lock, intr_flags);
-		pr_err(PFX "%s: BUG! Tx Ring full when queue awake!\n",
-		       dev->name);
+		netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
 		return NETDEV_TX_BUSY;
 	}
 
@@ -878,9 +874,8 @@ static netdev_tx_t cp_start_xmit (struct
 		wmb();
 	}
 	cp->tx_head = entry;
-	if (netif_msg_tx_queued(cp))
-		pr_debug("%s: tx queued, slot %d, skblen %d\n",
-		       dev->name, entry, skb->len);
+	netif_dbg(cp, tx_queued, cp->dev, "tx queued, slot %d, skblen %d\n",
+		  entry, skb->len);
 	if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1))
 		netif_stop_queue(dev);
 
@@ -899,7 +894,7 @@ static void __cp_set_rx_mode (struct net
 {
 	struct cp_private *cp = netdev_priv(dev);
 	u32 mc_filter[2];	/* Multicast hash filter */
-	int i, rx_mode;
+	int rx_mode;
 	u32 tmp;
 
 	/* Note: do not reorder, GCC is clever about common statements. */
@@ -909,7 +904,7 @@ static void __cp_set_rx_mode (struct net
 		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
 		    AcceptAllPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
-	} else if ((dev->mc_count > multicast_filter_limit) ||
+	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
 		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter perfectly -- accept all multicasts. */
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
@@ -918,8 +913,7 @@ static void __cp_set_rx_mode (struct net
 		struct dev_mc_list *mclist;
 		rx_mode = AcceptBroadcast | AcceptMyPhys;
 		mc_filter[1] = mc_filter[0] = 0;
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-		     i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
 
 			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
@@ -993,7 +987,7 @@ static void cp_reset_hw (struct cp_priva
 		schedule_timeout_uninterruptible(10);
 	}
 
-	pr_err("%s: hardware reset timeout\n", cp->dev->name);
+	netdev_err(cp->dev, "hardware reset timeout\n");
 }
 
 static inline void cp_start_hw (struct cp_private *cp)
@@ -1160,8 +1154,7 @@ static int cp_open (struct net_device *d
 	struct cp_private *cp = netdev_priv(dev);
 	int rc;
 
-	if (netif_msg_ifup(cp))
-		pr_debug("%s: enabling interface\n", dev->name);
+	netif_dbg(cp, ifup, dev, "enabling interface\n");
 
 	rc = cp_alloc_rings(cp);
 	if (rc)
@@ -1195,8 +1188,7 @@ static int cp_close (struct net_device *
 
 	napi_disable(&cp->napi);
 
-	if (netif_msg_ifdown(cp))
-		pr_debug("%s: disabling interface\n", dev->name);
+	netif_dbg(cp, ifdown, dev, "disabling interface\n");
 
 	spin_lock_irqsave(&cp->lock, flags);
 
@@ -1219,9 +1211,9 @@ static void cp_tx_timeout(struct net_dev
 	unsigned long flags;
 	int rc;
 
-	pr_warning("%s: Transmit timeout, status %2x %4x %4x %4x\n",
-	       dev->name, cpr8(Cmd), cpr16(CpCmd),
-	       cpr16(IntrStatus), cpr16(IntrMask));
+	netdev_warn(dev, "Transmit timeout, status %2x %4x %4x %4x\n",
+		    cpr8(Cmd), cpr16(CpCmd),
+		    cpr16(IntrStatus), cpr16(IntrMask));
 
 	spin_lock_irqsave(&cp->lock, flags);
 
@@ -1874,8 +1866,8 @@ static int cp_init_one (struct pci_dev *
 	if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
 	    pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pdev->revision < 0x20) {
 		dev_info(&pdev->dev,
-			   "This (id %04x:%04x rev %02x) is not an 8139C+ compatible chip, use 8139too\n",
-		           pdev->vendor, pdev->device, pdev->revision);
+			 "This (id %04x:%04x rev %02x) is not an 8139C+ compatible chip, use 8139too\n",
+			 pdev->vendor, pdev->device, pdev->revision);
 		return -ENODEV;
 	}
 
@@ -1933,14 +1925,13 @@ static int cp_init_one (struct pci_dev *
 		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc) {
 			dev_err(&pdev->dev,
-				   "No usable DMA configuration, aborting.\n");
+				"No usable DMA configuration, aborting\n");
 			goto err_out_res;
 		}
 		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc) {
 			dev_err(&pdev->dev,
-				   "No usable consistent DMA configuration, "
-			           "aborting.\n");
+				"No usable consistent DMA configuration, aborting\n");
 			goto err_out_res;
 		}
 	}
@@ -1952,7 +1943,7 @@ static int cp_init_one (struct pci_dev *
 	if (!regs) {
 		rc = -EIO;
 		dev_err(&pdev->dev, "Cannot map PCI MMIO (%Lx@%Lx)\n",
-		       (unsigned long long)pci_resource_len(pdev, 1),
+			(unsigned long long)pci_resource_len(pdev, 1),
 		       (unsigned long long)pciaddr);
 		goto err_out_res;
 	}
@@ -1990,11 +1981,8 @@ static int cp_init_one (struct pci_dev *
 	if (rc)
 		goto err_out_iomap;
 
-	pr_info("%s: RTL-8139C+ at 0x%lx, %pM, IRQ %d\n",
-		dev->name,
-		dev->base_addr,
-		dev->dev_addr,
-		dev->irq);
+	netdev_info(dev, "RTL-8139C+ at 0x%lx, %pM, IRQ %d\n",
+		    dev->base_addr, dev->dev_addr, dev->irq);
 
 	pci_set_drvdata(pdev, dev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/8139too.c linux-libre-2.6.34-gnu1/drivers/net/8139too.c
--- linux-libre-2.6.33-gnu1/drivers/net/8139too.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/8139too.c	2010-05-16 17:17:36.000000000 -0400
@@ -89,6 +89,8 @@
 
 */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #define DRV_NAME	"8139too"
 #define DRV_VERSION	"0.9.28"
 
@@ -108,10 +110,10 @@
 #include <linux/crc32.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
+#include <linux/gfp.h>
 #include <asm/irq.h>
 
 #define RTL8139_DRIVER_NAME   DRV_NAME " Fast Ethernet driver " DRV_VERSION
-#define PFX DRV_NAME ": "
 
 /* Default Message level */
 #define RTL8139_DEF_MSG_ENABLE   (NETIF_MSG_DRV   | \
@@ -130,9 +132,9 @@
 #  define assert(expr) do {} while (0)
 #else
 #  define assert(expr) \
-        if(unlikely(!(expr))) {				        \
-        pr_err("Assertion failed! %s,%s,%s,line=%d\n",	\
-	#expr, __FILE__, __func__, __LINE__);			\
+        if (unlikely(!(expr))) {				\
+		pr_err("Assertion failed! %s,%s,%s,line=%d\n",	\
+		       #expr, __FILE__, __func__, __LINE__);	\
         }
 #endif
 
@@ -231,7 +233,7 @@ static const struct {
 };
 
 
-static struct pci_device_id rtl8139_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(rtl8139_pci_tbl) = {
 	{0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 	{0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 	{0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
@@ -957,7 +959,7 @@ static int __devinit rtl8139_init_one (s
 	    pdev->device == PCI_DEVICE_ID_REALTEK_8139 &&
 	    pdev->subsystem_vendor == PCI_VENDOR_ID_ATHEROS &&
 	    pdev->subsystem_device == PCI_DEVICE_ID_REALTEK_8139) {
-		pr_info("8139too: OQO Model 2 detected. Forcing PIO\n");
+		pr_info("OQO Model 2 detected. Forcing PIO\n");
 		use_io = 1;
 	}
 
@@ -1010,21 +1012,19 @@ static int __devinit rtl8139_init_one (s
 	tp->mii.reg_num_mask = 0x1f;
 
 	/* dev is fully set up and ready to use now */
-	pr_debug("about to register device named %s (%p)...\n", dev->name, dev);
+	pr_debug("about to register device named %s (%p)...\n",
+		 dev->name, dev);
 	i = register_netdev (dev);
 	if (i) goto err_out;
 
 	pci_set_drvdata (pdev, dev);
 
-	pr_info("%s: %s at 0x%lx, %pM, IRQ %d\n",
-		dev->name,
-		board_info[ent->driver_data].name,
-		dev->base_addr,
-		dev->dev_addr,
-		dev->irq);
+	netdev_info(dev, "%s at 0x%lx, %pM, IRQ %d\n",
+		    board_info[ent->driver_data].name,
+		    dev->base_addr, dev->dev_addr, dev->irq);
 
-	pr_debug("%s:  Identified 8139 chip type '%s'\n",
-		dev->name, rtl_chip_info[tp->chipset].name);
+	netdev_dbg(dev, "Identified 8139 chip type '%s'\n",
+		   rtl_chip_info[tp->chipset].name);
 
 	/* Find the connected MII xcvrs.
 	   Doing this in open() would allow detecting external xcvrs later, but
@@ -1037,13 +1037,12 @@ static int __devinit rtl8139_init_one (s
 			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
 				u16 advertising = mdio_read(dev, phy, 4);
 				tp->phys[phy_idx++] = phy;
-				pr_info("%s: MII transceiver %d status 0x%4.4x advertising %4.4x.\n",
-					   dev->name, phy, mii_status, advertising);
+				netdev_info(dev, "MII transceiver %d status 0x%04x advertising %04x\n",
+					    phy, mii_status, advertising);
 			}
 		}
 		if (phy_idx == 0) {
-			pr_info("%s: No MII transceivers found! Assuming SYM transceiver.\n",
-				   dev->name);
+			netdev_info(dev, "No MII transceivers found! Assuming SYM transceiver\n");
 			tp->phys[0] = 32;
 		}
 	} else
@@ -1062,15 +1061,15 @@ static int __devinit rtl8139_init_one (s
 	if (board_idx < MAX_UNITS  &&  full_duplex[board_idx] > 0)
 		tp->mii.full_duplex = full_duplex[board_idx];
 	if (tp->mii.full_duplex) {
-		pr_info("%s: Media type forced to Full Duplex.\n", dev->name);
+		netdev_info(dev, "Media type forced to Full Duplex\n");
 		/* Changing the MII-advertised media because might prevent
 		   re-connection. */
 		tp->mii.force_media = 1;
 	}
 	if (tp->default_port) {
-		pr_info("  Forcing %dMbps %s-duplex operation.\n",
-			   (option & 0x20 ? 100 : 10),
-			   (option & 0x10 ? "full" : "half"));
+		netdev_info(dev, "  Forcing %dMbps %s-duplex operation\n",
+			    (option & 0x20 ? 100 : 10),
+			    (option & 0x10 ? "full" : "half"));
 		mdio_write(dev, tp->phys[0], 0,
 				   ((option & 0x20) ? 0x2000 : 0) | 	/* 100Mbps? */
 				   ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
@@ -1330,12 +1329,12 @@ static int rtl8139_open (struct net_devi
 	rtl8139_hw_start (dev);
 	netif_start_queue (dev);
 
-	if (netif_msg_ifup(tp))
-		pr_debug("%s: rtl8139_open() ioaddr %#llx IRQ %d"
-			" GP Pins %2.2x %s-duplex.\n", dev->name,
-			(unsigned long long)pci_resource_start (tp->pci_dev, 1),
-			dev->irq, RTL_R8 (MediaStatus),
-			tp->mii.full_duplex ? "full" : "half");
+	netif_dbg(tp, ifup, dev,
+		  "%s() ioaddr %#llx IRQ %d GP Pins %02x %s-duplex\n",
+		  __func__,
+		  (unsigned long long)pci_resource_start (tp->pci_dev, 1),
+		  dev->irq, RTL_R8 (MediaStatus),
+		  tp->mii.full_duplex ? "full" : "half");
 
 	rtl8139_start_thread(tp);
 
@@ -1393,7 +1392,7 @@ static void rtl8139_hw_start (struct net
 		RTL_W8 (Config3, RTL_R8 (Config3) & ~Cfg3_Magic);
 	}
 
-	pr_debug("init buffer addresses\n");
+	netdev_dbg(dev, "init buffer addresses\n");
 
 	/* Lock Config[01234] and BMCR register writes */
 	RTL_W8 (Cfg9346, Cfg9346_Lock);
@@ -1555,14 +1554,11 @@ static inline void rtl8139_thread_iter (
 			tp->mii.full_duplex = duplex;
 
 			if (mii_lpa) {
-				pr_info("%s: Setting %s-duplex based on MII #%d link"
-					" partner ability of %4.4x.\n",
-					dev->name,
-					tp->mii.full_duplex ? "full" : "half",
-					tp->phys[0], mii_lpa);
+				netdev_info(dev, "Setting %s-duplex based on MII #%d link partner ability of %04x\n",
+					    tp->mii.full_duplex ? "full" : "half",
+					    tp->phys[0], mii_lpa);
 			} else {
-				pr_info("%s: media is unconnected, link down, or incompatible connection\n",
-				       dev->name);
+				netdev_info(dev, "media is unconnected, link down, or incompatible connection\n");
 			}
 #if 0
 			RTL_W8 (Cfg9346, Cfg9346_Unlock);
@@ -1576,13 +1572,12 @@ static inline void rtl8139_thread_iter (
 
 	rtl8139_tune_twister (dev, tp);
 
-	pr_debug("%s: Media selection tick, Link partner %4.4x.\n",
-		 dev->name, RTL_R16 (NWayLPAR));
-	pr_debug("%s:  Other registers are IntMask %4.4x IntStatus %4.4x\n",
-		 dev->name, RTL_R16 (IntrMask), RTL_R16 (IntrStatus));
-	pr_debug("%s:  Chip config %2.2x %2.2x.\n",
-		 dev->name, RTL_R8 (Config0),
-		 RTL_R8 (Config1));
+	netdev_dbg(dev, "Media selection tick, Link partner %04x\n",
+		   RTL_R16(NWayLPAR));
+	netdev_dbg(dev, "Other registers are IntMask %04x IntStatus %04x\n",
+		   RTL_R16(IntrMask), RTL_R16(IntrStatus));
+	netdev_dbg(dev, "Chip config %02x %02x\n",
+		   RTL_R8(Config0), RTL_R8(Config1));
 }
 
 static void rtl8139_thread (struct work_struct *work)
@@ -1640,17 +1635,17 @@ static void rtl8139_tx_timeout_task (str
 	int i;
 	u8 tmp8;
 
-	pr_debug("%s: Transmit timeout, status %2.2x %4.4x %4.4x media %2.2x.\n",
-		dev->name, RTL_R8 (ChipCmd),
-		RTL_R16(IntrStatus), RTL_R16(IntrMask), RTL_R8(MediaStatus));
+	netdev_dbg(dev, "Transmit timeout, status %02x %04x %04x media %02x\n",
+		   RTL_R8(ChipCmd), RTL_R16(IntrStatus),
+		   RTL_R16(IntrMask), RTL_R8(MediaStatus));
 	/* Emit info to figure out what went wrong. */
-	pr_debug("%s: Tx queue start entry %ld  dirty entry %ld.\n",
-		dev->name, tp->cur_tx, tp->dirty_tx);
+	netdev_dbg(dev, "Tx queue start entry %ld  dirty entry %ld\n",
+		   tp->cur_tx, tp->dirty_tx);
 	for (i = 0; i < NUM_TX_DESC; i++)
-		pr_debug("%s:  Tx descriptor %d is %8.8lx.%s\n",
-			dev->name, i, RTL_R32 (TxStatus0 + (i * 4)),
-			i == tp->dirty_tx % NUM_TX_DESC ?
-				" (queue head)" : "");
+		netdev_dbg(dev, "Tx descriptor %d is %08lx%s\n",
+			   i, RTL_R32(TxStatus0 + (i * 4)),
+			   i == tp->dirty_tx % NUM_TX_DESC ?
+			   " (queue head)" : "");
 
 	tp->xstats.tx_timeouts++;
 
@@ -1729,9 +1724,8 @@ static netdev_tx_t rtl8139_start_xmit (s
 		netif_stop_queue (dev);
 	spin_unlock_irqrestore(&tp->lock, flags);
 
-	if (netif_msg_tx_queued(tp))
-		pr_debug("%s: Queued Tx packet size %u to slot %d.\n",
-			dev->name, len, entry);
+	netif_dbg(tp, tx_queued, dev, "Queued Tx packet size %u to slot %d\n",
+		  len, entry);
 
 	return NETDEV_TX_OK;
 }
@@ -1760,9 +1754,8 @@ static void rtl8139_tx_interrupt (struct
 		/* Note: TxCarrierLost is always asserted at 100mbps. */
 		if (txstatus & (TxOutOfWindow | TxAborted)) {
 			/* There was an major error, log it. */
-			if (netif_msg_tx_err(tp))
-				pr_debug("%s: Transmit error, Tx status %8.8x.\n",
-					dev->name, txstatus);
+			netif_dbg(tp, tx_err, dev, "Transmit error, Tx status %08x\n",
+				  txstatus);
 			dev->stats.tx_errors++;
 			if (txstatus & TxAborted) {
 				dev->stats.tx_aborted_errors++;
@@ -1792,8 +1785,8 @@ static void rtl8139_tx_interrupt (struct
 
 #ifndef RTL8139_NDEBUG
 	if (tp->cur_tx - dirty_tx > NUM_TX_DESC) {
-		pr_err("%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
-		        dev->name, dirty_tx, tp->cur_tx);
+		netdev_err(dev, "Out-of-sync dirty pointer, %ld vs. %ld\n",
+			   dirty_tx, tp->cur_tx);
 		dirty_tx += NUM_TX_DESC;
 	}
 #endif /* RTL8139_NDEBUG */
@@ -1816,14 +1809,13 @@ static void rtl8139_rx_err (u32 rx_statu
 	int tmp_work;
 #endif
 
-	if (netif_msg_rx_err (tp))
-		pr_debug("%s: Ethernet frame had errors, status %8.8x.\n",
-			dev->name, rx_status);
+	netif_dbg(tp, rx_err, dev, "Ethernet frame had errors, status %08x\n",
+		  rx_status);
 	dev->stats.rx_errors++;
 	if (!(rx_status & RxStatusOK)) {
 		if (rx_status & RxTooLong) {
-			pr_debug("%s: Oversized Ethernet frame, status %4.4x!\n",
-			 	dev->name, rx_status);
+			netdev_dbg(dev, "Oversized Ethernet frame, status %04x!\n",
+				   rx_status);
 			/* A.C.: The chip hangs here. */
 		}
 		if (rx_status & (RxBadSymbol | RxBadAlign))
@@ -1855,7 +1847,7 @@ static void rtl8139_rx_err (u32 rx_statu
 			break;
 	}
 	if (tmp_work <= 0)
-		pr_warning(PFX "rx stop wait too long\n");
+		netdev_warn(dev, "rx stop wait too long\n");
 	/* restart receive */
 	tmp_work = 200;
 	while (--tmp_work > 0) {
@@ -1866,7 +1858,7 @@ static void rtl8139_rx_err (u32 rx_statu
 			break;
 	}
 	if (tmp_work <= 0)
-		pr_warning(PFX "tx/rx enable wait too long\n");
+		netdev_warn(dev, "tx/rx enable wait too long\n");
 
 	/* and reinitialize all rx related registers */
 	RTL_W8_F (Cfg9346, Cfg9346_Unlock);
@@ -1877,7 +1869,7 @@ static void rtl8139_rx_err (u32 rx_statu
 	RTL_W32 (RxConfig, tp->rx_config);
 	tp->cur_rx = 0;
 
-	pr_debug("init buffer addresses\n");
+	netdev_dbg(dev, "init buffer addresses\n");
 
 	/* Lock Config[01234] and BMCR register writes */
 	RTL_W8 (Cfg9346, Cfg9346_Lock);
@@ -1931,10 +1923,9 @@ static int rtl8139_rx(struct net_device
 	unsigned int cur_rx = tp->cur_rx;
 	unsigned int rx_size = 0;
 
-	pr_debug("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
-		 " free to %4.4x, Cmd %2.2x.\n", dev->name, (u16)cur_rx,
-		 RTL_R16 (RxBufAddr),
-		 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
+	netdev_dbg(dev, "In %s(), current %04x BufAddr %04x, free to %04x, Cmd %02x\n",
+		   __func__, (u16)cur_rx,
+		   RTL_R16(RxBufAddr), RTL_R16(RxBufPtr), RTL_R8(ChipCmd));
 
 	while (netif_running(dev) && received < budget &&
 	       (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
@@ -1950,19 +1941,12 @@ static int rtl8139_rx(struct net_device
 		rx_size = rx_status >> 16;
 		pkt_size = rx_size - 4;
 
-		if (netif_msg_rx_status(tp))
-			pr_debug("%s:  rtl8139_rx() status %4.4x, size %4.4x,"
-				" cur %4.4x.\n", dev->name, rx_status,
-			 rx_size, cur_rx);
+		netif_dbg(tp, rx_status, dev, "%s() status %04x, size %04x, cur %04x\n",
+			  __func__, rx_status, rx_size, cur_rx);
 #if RTL8139_DEBUG > 2
-		{
-			int i;
-			pr_debug("%s: Frame contents ", dev->name);
-			for (i = 0; i < 70; i++)
-				pr_cont(" %2.2x",
-					rx_ring[ring_offset + i]);
-			pr_cont(".\n");
-		}
+		print_hex_dump(KERN_DEBUG, "Frame contents: ",
+			       DUMP_PREFIX_OFFSET, 16, 1,
+			       &rx_ring[ring_offset], 70, true);
 #endif
 
 		/* Packet copy from FIFO still in progress.
@@ -1973,14 +1957,11 @@ static int rtl8139_rx(struct net_device
 			if (!tp->fifo_copy_timeout)
 				tp->fifo_copy_timeout = jiffies + 2;
 			else if (time_after(jiffies, tp->fifo_copy_timeout)) {
-				pr_debug("%s: hung FIFO. Reset.", dev->name);
+				netdev_dbg(dev, "hung FIFO. Reset\n");
 				rx_size = 0;
 				goto no_early_rx;
 			}
-			if (netif_msg_intr(tp)) {
-				pr_debug("%s: fifo copy in progress.",
-				       dev->name);
-			}
+			netif_dbg(tp, intr, dev, "fifo copy in progress\n");
 			tp->xstats.early_rx++;
 			break;
 		}
@@ -2021,8 +2002,7 @@ no_early_rx:
 			netif_receive_skb (skb);
 		} else {
 			if (net_ratelimit())
-				pr_warning("%s: Memory squeeze, dropping packet.\n",
-					dev->name);
+				netdev_warn(dev, "Memory squeeze, dropping packet\n");
 			dev->stats.rx_dropped++;
 		}
 		received++;
@@ -2036,10 +2016,9 @@ no_early_rx:
 	if (unlikely(!received || rx_size == 0xfff0))
 		rtl8139_isr_ack(tp);
 
-	pr_debug("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
-		 " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
-		 RTL_R16 (RxBufAddr),
-		 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
+	netdev_dbg(dev, "Done %s(), current %04x BufAddr %04x, free to %04x, Cmd %02x\n",
+		   __func__, cur_rx,
+		   RTL_R16(RxBufAddr), RTL_R16(RxBufPtr), RTL_R8(ChipCmd));
 
 	tp->cur_rx = cur_rx;
 
@@ -2060,8 +2039,7 @@ static void rtl8139_weird_interrupt (str
 				     void __iomem *ioaddr,
 				     int status, int link_changed)
 {
-	pr_debug("%s: Abnormal interrupt, status %8.8x.\n",
-		 dev->name, status);
+	netdev_dbg(dev, "Abnormal interrupt, status %08x\n", status);
 
 	assert (dev != NULL);
 	assert (tp != NULL);
@@ -2089,8 +2067,7 @@ static void rtl8139_weird_interrupt (str
 		pci_read_config_word (tp->pci_dev, PCI_STATUS, &pci_cmd_status);
 		pci_write_config_word (tp->pci_dev, PCI_STATUS, pci_cmd_status);
 
-		pr_err("%s: PCI Bus error %4.4x.\n",
-			dev->name, pci_cmd_status);
+		netdev_err(dev, "PCI Bus error %04x\n", pci_cmd_status);
 	}
 }
 
@@ -2183,8 +2160,8 @@ static irqreturn_t rtl8139_interrupt (in
  out:
 	spin_unlock (&tp->lock);
 
-	pr_debug("%s: exiting interrupt, intr_status=%#4.4x.\n",
-		 dev->name, RTL_R16 (IntrStatus));
+	netdev_dbg(dev, "exiting interrupt, intr_status=%#4.4x\n",
+		   RTL_R16(IntrStatus));
 	return IRQ_RETVAL(handled);
 }
 
@@ -2233,9 +2210,8 @@ static int rtl8139_close (struct net_dev
 	netif_stop_queue(dev);
 	napi_disable(&tp->napi);
 
-	if (netif_msg_ifdown(tp))
-		pr_debug("%s: Shutting down ethercard, status was 0x%4.4x.\n",
-			dev->name, RTL_R16 (IntrStatus));
+	netif_dbg(tp, ifdown, dev, "Shutting down ethercard, status was 0x%04x\n",
+		  RTL_R16(IntrStatus));
 
 	spin_lock_irqsave (&tp->lock, flags);
 
@@ -2509,11 +2485,11 @@ static void __set_rx_mode (struct net_de
 	struct rtl8139_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
 	u32 mc_filter[2];	/* Multicast hash filter */
-	int i, rx_mode;
+	int rx_mode;
 	u32 tmp;
 
-	pr_debug("%s:   rtl8139_set_rx_mode(%4.4x) done -- Rx config %8.8lx.\n",
-			dev->name, dev->flags, RTL_R32 (RxConfig));
+	netdev_dbg(dev, "rtl8139_set_rx_mode(%04x) done -- Rx config %08lx\n",
+		   dev->flags, RTL_R32(RxConfig));
 
 	/* Note: do not reorder, GCC is clever about common statements. */
 	if (dev->flags & IFF_PROMISC) {
@@ -2521,7 +2497,7 @@ static void __set_rx_mode (struct net_de
 		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
 		    AcceptAllPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
-	} else if ((dev->mc_count > multicast_filter_limit) ||
+	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
 		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter perfectly -- accept all multicasts. */
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
@@ -2530,8 +2506,7 @@ static void __set_rx_mode (struct net_de
 		struct dev_mc_list *mclist;
 		rx_mode = AcceptBroadcast | AcceptMyPhys;
 		mc_filter[1] = mc_filter[0] = 0;
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-		     i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
 
 			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/82596.c linux-libre-2.6.34-gnu1/drivers/net/82596.c
--- linux-libre-2.6.33-gnu1/drivers/net/82596.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/82596.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,7 +45,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
@@ -53,6 +52,7 @@
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -1505,7 +1505,7 @@ static void set_multicast_list(struct ne
 	int config = 0, cnt;
 
 	DEB(DEB_MULTI,printk(KERN_DEBUG "%s: set multicast list, %d entries, promisc %s, allmulti %s\n",
-		dev->name, dev->mc_count,
+		dev->name, netdev_mc_count(dev),
 		dev->flags & IFF_PROMISC  ? "ON" : "OFF",
 		dev->flags & IFF_ALLMULTI ? "ON" : "OFF"));
 
@@ -1533,7 +1533,7 @@ static void set_multicast_list(struct ne
 		i596_add_cmd(dev, &lp->cf_cmd.cmd);
 	}
 
-	cnt = dev->mc_count;
+	cnt = netdev_mc_count(dev);
 	if (cnt > MAX_MC_CNT)
 	{
 		cnt = MAX_MC_CNT;
@@ -1541,7 +1541,7 @@ static void set_multicast_list(struct ne
 			dev->name, cnt);
 	}
 
-	if (dev->mc_count > 0) {
+	if (!netdev_mc_empty(dev)) {
 		struct dev_mc_list *dmi;
 		unsigned char *cp;
 		struct mc_cmd *cmd;
@@ -1550,13 +1550,16 @@ static void set_multicast_list(struct ne
 			return;
 		cmd = &lp->mc_cmd;
 		cmd->cmd.command = CmdMulticastList;
-		cmd->mc_cnt = dev->mc_count * 6;
+		cmd->mc_cnt = cnt * ETH_ALEN;
 		cp = cmd->mc_addrs;
-		for (dmi = dev->mc_list; cnt && dmi != NULL; dmi = dmi->next, cnt--, cp += 6) {
-			memcpy(cp, dmi->dmi_addr, 6);
+		netdev_for_each_mc_addr(dmi, dev) {
+			if (!cnt--)
+				break;
+			memcpy(cp, dmi->dmi_addr, ETH_ALEN);
 			if (i596_debug > 1)
 				DEB(DEB_MULTI,printk(KERN_INFO "%s: Adding address %pM\n",
 						dev->name, cp));
+			cp += ETH_ALEN;
 		}
 		i596_add_cmd(dev, &cmd->cmd);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/a2065.c linux-libre-2.6.34-gnu1/drivers/net/a2065.c
--- linux-libre-2.6.33-gnu1/drivers/net/a2065.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/a2065.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,7 +46,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
@@ -603,9 +602,8 @@ static void lance_load_multicast (struct
 	struct lance_private *lp = netdev_priv(dev);
 	volatile struct lance_init_block *ib = lp->init_block;
 	volatile u16 *mcast_table = (u16 *)&ib->filter;
-	struct dev_mc_list *dmi=dev->mc_list;
+	struct dev_mc_list *dmi;
 	char *addrs;
-	int i;
 	u32 crc;
 
 	/* set all multicast bits */
@@ -619,9 +617,8 @@ static void lance_load_multicast (struct
 	ib->filter [1] = 0;
 
 	/* Add addresses */
-	for (i = 0; i < dev->mc_count; i++){
+	netdev_for_each_mc_addr(dmi, dev) {
 		addrs = dmi->dmi_addr;
-		dmi   = dmi->next;
 
 		/* multicast address? */
 		if (!(*addrs & 1))
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/acenic.c linux-libre-2.6.34-gnu1/drivers/net/acenic.c
--- linux-libre-2.6.33-gnu1/drivers/net/acenic.c	2013-05-03 12:07:37.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/acenic.c	2013-05-03 09:46:59.000000000 -0400
@@ -67,6 +67,7 @@
 #include <linux/highmem.h>
 #include <linux/sockios.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 #include <linux/if_vlan.h>
@@ -134,7 +135,7 @@
 #define PCI_DEVICE_ID_SGI_ACENIC	0x0009
 #endif
 
-static struct pci_device_id acenic_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(acenic_pci_tbl) = {
 	{ PCI_VENDOR_ID_ALTEON, PCI_DEVICE_ID_ALTEON_ACENIC_FIBRE,
 	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
 	{ PCI_VENDOR_ID_ALTEON, PCI_DEVICE_ID_ALTEON_ACENIC_COPPER,
@@ -2845,7 +2846,7 @@ static void ace_set_multicast_list(struc
 	 * set the entire multicast list at a time and keeping track of
 	 * it here is going to be messy.
 	 */
-	if ((dev->mc_count) && !(ap->mcast_all)) {
+	if (!netdev_mc_empty(dev) && !ap->mcast_all) {
 		cmd.evt = C_SET_MULTICAST_MODE;
 		cmd.code = C_C_MCAST_ENABLE;
 		cmd.idx = 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/amd8111e.c linux-libre-2.6.34-gnu1/drivers/net/amd8111e.c
--- linux-libre-2.6.33-gnu1/drivers/net/amd8111e.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/amd8111e.c	2010-05-16 17:17:36.000000000 -0400
@@ -73,7 +73,6 @@ Revision History:
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/compiler.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
@@ -113,7 +112,7 @@ MODULE_PARM_DESC(coalesce, "Enable or Di
 module_param_array(dynamic_ipg, bool, NULL, 0);
 MODULE_PARM_DESC(dynamic_ipg, "Enable or Disable dynamic IPG, 1: Enable, 0: Disable");
 
-static struct pci_device_id amd8111e_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(amd8111e_pci_tbl) = {
 
 	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD8111E_7462,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
@@ -1176,8 +1175,7 @@ static irqreturn_t amd8111e_interrupt(in
 			/* Schedule a polling routine */
 			__napi_schedule(&lp->napi);
 		} else if (intren0 & RINTEN0) {
-			printk("************Driver bug! \
-				interrupt while in poll\n");
+			printk("************Driver bug! interrupt while in poll\n");
 			/* Fix by disable receive interrupts */
 			writel(RINTEN0, mmio + INTEN0);
 		}
@@ -1378,28 +1376,28 @@ list to the device.
 */
 static void amd8111e_set_multicast_list(struct net_device *dev)
 {
-	struct dev_mc_list* mc_ptr;
+	struct dev_mc_list *mc_ptr;
 	struct amd8111e_priv *lp = netdev_priv(dev);
 	u32 mc_filter[2] ;
-	int i,bit_num;
+	int bit_num;
+
 	if(dev->flags & IFF_PROMISC){
 		writel( VAL2 | PROM, lp->mmio + CMD2);
 		return;
 	}
 	else
 		writel( PROM, lp->mmio + CMD2);
-	if(dev->flags & IFF_ALLMULTI || dev->mc_count > MAX_FILTER_SIZE){
+	if (dev->flags & IFF_ALLMULTI ||
+	    netdev_mc_count(dev) > MAX_FILTER_SIZE) {
 		/* get all multicast packet */
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
-		lp->mc_list = dev->mc_list;
 		lp->options |= OPTION_MULTICAST_ENABLE;
 		amd8111e_writeq(*(u64*)mc_filter,lp->mmio + LADRF);
 		return;
 	}
-	if( dev->mc_count == 0 ){
+	if (netdev_mc_empty(dev)) {
 		/* get only own packets */
 		mc_filter[1] = mc_filter[0] = 0;
-		lp->mc_list = NULL;
 		lp->options &= ~OPTION_MULTICAST_ENABLE;
 		amd8111e_writeq(*(u64*)mc_filter,lp->mmio + LADRF);
 		/* disable promiscous mode */
@@ -1408,10 +1406,8 @@ static void amd8111e_set_multicast_list(
 	}
 	/* load all the multicast addresses in the logic filter */
 	lp->options |= OPTION_MULTICAST_ENABLE;
-	lp->mc_list = dev->mc_list;
 	mc_filter[1] = mc_filter[0] = 0;
-	for (i = 0, mc_ptr = dev->mc_list; mc_ptr && i < dev->mc_count;
-		     i++, mc_ptr = mc_ptr->next) {
+	netdev_for_each_mc_addr(mc_ptr, dev) {
 		bit_num = (ether_crc_le(ETH_ALEN, mc_ptr->dmi_addr) >> 26) & 0x3f;
 		mc_filter[bit_num >> 5] |= 1 << (bit_num & 31);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/amd8111e.h linux-libre-2.6.34-gnu1/drivers/net/amd8111e.h
--- linux-libre-2.6.33-gnu1/drivers/net/amd8111e.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/amd8111e.h	2010-05-16 17:17:36.000000000 -0400
@@ -789,7 +789,6 @@ struct amd8111e_priv{
 	char opened;
 	struct net_device_stats stats;
 	unsigned int drv_rx_errors;
-	struct dev_mc_list* mc_list;
 	struct amd8111e_coalesce_conf coal_conf;
 
 	struct ipg_info  ipg_data;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/appletalk/cops.c linux-libre-2.6.34-gnu1/drivers/net/appletalk/cops.c
--- linux-libre-2.6.33-gnu1/drivers/net/appletalk/cops.c	2013-05-03 12:08:47.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/appletalk/cops.c	2013-05-03 09:48:18.000000000 -0400
@@ -56,7 +56,6 @@ static const char *version =
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/appletalk/ipddp.c linux-libre-2.6.34-gnu1/drivers/net/appletalk/ipddp.c
--- linux-libre-2.6.33-gnu1/drivers/net/appletalk/ipddp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/appletalk/ipddp.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/ip.h>
 #include <linux/atalk.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <net/route.h>
 #include <asm/uaccess.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/appletalk/ltpc.c linux-libre-2.6.34-gnu1/drivers/net/appletalk/ltpc.c
--- linux-libre-2.6.33-gnu1/drivers/net/appletalk/ltpc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/appletalk/ltpc.c	2010-05-16 17:17:36.000000000 -0400
@@ -215,7 +215,6 @@ static int dma;
 #include <linux/ioport.h>
 #include <linux/spinlock.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -228,6 +227,7 @@ static int dma;
 #include <linux/timer.h>
 #include <linux/atalk.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/dma.h>
@@ -1125,7 +1125,6 @@ struct net_device * __init ltpc_probe(vo
 		printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, DMA%d.  Using polled mode.\n",io,dma);
 
 	dev->netdev_ops = &ltpc_netdev;
-	dev->mc_list = NULL;
 	dev->base_addr = io;
 	dev->irq = irq;
 	dev->dma = dma;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arcnet/arc-rawmode.c linux-libre-2.6.34-gnu1/drivers/net/arcnet/arc-rawmode.c
--- linux-libre-2.6.33-gnu1/drivers/net/arcnet/arc-rawmode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arcnet/arc-rawmode.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/if_arp.h>
 #include <net/arp.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arcnet/arc-rimi.c linux-libre-2.6.34-gnu1/drivers/net/arcnet/arc-rimi.c
--- linux-libre-2.6.33-gnu1/drivers/net/arcnet/arc-rimi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arcnet/arc-rimi.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/bootmem.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arcnet/capmode.c linux-libre-2.6.34-gnu1/drivers/net/arcnet/capmode.c
--- linux-libre-2.6.33-gnu1/drivers/net/arcnet/capmode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arcnet/capmode.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/if_arp.h>
 #include <net/arp.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arcnet/com20020.c linux-libre-2.6.34-gnu1/drivers/net/arcnet/com20020.c
--- linux-libre-2.6.33-gnu1/drivers/net/arcnet/com20020.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arcnet/com20020.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,7 +29,6 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arcnet/com20020-isa.c linux-libre-2.6.34-gnu1/drivers/net/arcnet/com20020-isa.c
--- linux-libre-2.6.33-gnu1/drivers/net/arcnet/com20020-isa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arcnet/com20020-isa.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,6 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arcnet/com20020-pci.c linux-libre-2.6.34-gnu1/drivers/net/arcnet/com20020-pci.c
--- linux-libre-2.6.33-gnu1/drivers/net/arcnet/com20020-pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arcnet/com20020-pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,6 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
 #include <linux/init.h>
@@ -144,7 +143,7 @@ static void __devexit com20020pci_remove
 	free_netdev(dev);
 }
 
-static struct pci_device_id com20020pci_id_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(com20020pci_id_table) = {
 	{ 0x1571, 0xa001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ 0x1571, 0xa002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ 0x1571, 0xa003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arcnet/com90io.c linux-libre-2.6.34-gnu1/drivers/net/arcnet/com90io.c
--- linux-libre-2.6.33-gnu1/drivers/net/arcnet/com90io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arcnet/com90io.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,7 +29,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/bootmem.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arcnet/com90xx.c linux-libre-2.6.34-gnu1/drivers/net/arcnet/com90xx.c
--- linux-libre-2.6.33-gnu1/drivers/net/arcnet/com90xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arcnet/com90xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/arcdevice.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arcnet/rfc1051.c linux-libre-2.6.34-gnu1/drivers/net/arcnet/rfc1051.c
--- linux-libre-2.6.33-gnu1/drivers/net/arcnet/rfc1051.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arcnet/rfc1051.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
  * **********************
  */
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/if_arp.h>
 #include <net/arp.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arcnet/rfc1201.c linux-libre-2.6.34-gnu1/drivers/net/arcnet/rfc1201.c
--- linux-libre-2.6.33-gnu1/drivers/net/arcnet/rfc1201.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arcnet/rfc1201.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
  *
  * **********************
  */
+#include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/if_arp.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ariadne.c linux-libre-2.6.34-gnu1/drivers/net/ariadne.c
--- linux-libre-2.6.33-gnu1/drivers/net/ariadne.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ariadne.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,7 +40,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/interrupt.h>
@@ -123,9 +122,7 @@ static void ariadne_reset(struct net_dev
 static irqreturn_t ariadne_interrupt(int irq, void *data);
 static int ariadne_close(struct net_device *dev);
 static struct net_device_stats *ariadne_get_stats(struct net_device *dev);
-#ifdef HAVE_MULTICAST
 static void set_multicast_list(struct net_device *dev);
-#endif
 
 
 static void memcpyw(volatile u_short *dest, u_short *src, int len)
@@ -821,7 +818,7 @@ static void set_multicast_list(struct ne
 	lance->RDP = PROM;		/* Set promiscuous mode */
     } else {
 	short multicast_table[4];
-	int num_addrs = dev->mc_count;
+	int num_addrs = netdev_mc_count(dev);
 	int i;
 	/* We don't use the multicast table, but rely on upper-layer filtering. */
 	memset(multicast_table, (num_addrs == 0) ? 0 : -1,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arm/am79c961a.c linux-libre-2.6.34-gnu1/drivers/net/arm/am79c961a.c
--- linux-libre-2.6.33-gnu1/drivers/net/arm/am79c961a.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arm/am79c961a.c	2010-05-16 17:17:36.000000000 -0400
@@ -351,13 +351,13 @@ static struct net_device_stats *am79c961
 	return &priv->stats;
 }
 
-static void am79c961_mc_hash(struct dev_mc_list *dmi, unsigned short *hash)
+static void am79c961_mc_hash(char *addr, unsigned short *hash)
 {
-	if (dmi->dmi_addrlen == ETH_ALEN && dmi->dmi_addr[0] & 0x01) {
+	if (addr[0] & 0x01) {
 		int idx, bit;
 		u32 crc;
 
-		crc = ether_crc_le(ETH_ALEN, dmi->dmi_addr);
+		crc = ether_crc_le(ETH_ALEN, addr);
 
 		idx = crc >> 30;
 		bit = (crc >> 26) & 15;
@@ -387,8 +387,8 @@ static void am79c961_setmulticastlist (s
 
 		memset(multi_hash, 0x00, sizeof(multi_hash));
 
-		for (dmi = dev->mc_list; dmi; dmi = dmi->next)
-			am79c961_mc_hash(dmi, multi_hash);
+		netdev_for_each_mc_addr(dmi, dev)
+			am79c961_mc_hash(dmi->dmi_addr, multi_hash);
 	}
 
 	spin_lock_irqsave(&priv->chip_lock, flags);
@@ -680,7 +680,7 @@ static const struct net_device_ops am79c
 #endif
 };
 
-static int __init am79c961_probe(struct platform_device *pdev)
+static int __devinit am79c961_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	struct net_device *dev;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arm/at91_ether.c linux-libre-2.6.34-gnu1/drivers/net/arm/at91_ether.c
--- linux-libre-2.6.33-gnu1/drivers/net/arm/at91_ether.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arm/at91_ether.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/ethtool.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -558,14 +559,11 @@ static void at91ether_sethashtable(struc
 {
 	struct dev_mc_list *curr;
 	unsigned long mc_filter[2];
-	unsigned int i, bitnr;
+	unsigned int bitnr;
 
 	mc_filter[0] = mc_filter[1] = 0;
 
-	curr = dev->mc_list;
-	for (i = 0; i < dev->mc_count; i++, curr = curr->next) {
-		if (!curr) break;	/* unexpected end of list */
-
+	netdev_for_each_mc_addr(curr, dev) {
 		bitnr = hash_get_index(curr->dmi_addr);
 		mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
 	}
@@ -592,7 +590,7 @@ static void at91ether_set_multicast_list
 		at91_emac_write(AT91_EMAC_HSH, -1);
 		at91_emac_write(AT91_EMAC_HSL, -1);
 		cfg |= AT91_EMAC_MTI;
-	} else if (dev->mc_count > 0) {			/* Enable specific multicasts */
+	} else if (!netdev_mc_empty(dev)) { /* Enable specific multicasts */
 		at91ether_sethashtable(dev);
 		cfg |= AT91_EMAC_MTI;
 	} else if (dev->flags & (~IFF_ALLMULTI)) {	/* Disable all multicast mode */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arm/ep93xx_eth.c linux-libre-2.6.34-gnu1/drivers/net/arm/ep93xx_eth.c
--- linux-libre-2.6.33-gnu1/drivers/net/arm/ep93xx_eth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arm/ep93xx_eth.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,8 @@
  * (at your option) any later version.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
+
 #include <linux/dma-mapping.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -20,9 +22,10 @@
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
-#include <mach/ep93xx-regs.h>
-#include <mach/platform.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <mach/hardware.h>
 
 #define DRV_MODULE_NAME		"ep93xx-eth"
 #define DRV_MODULE_VERSION	"0.1"
@@ -185,7 +188,47 @@ struct ep93xx_priv
 #define wrw(ep, off, val)	__raw_writew((val), (ep)->base_addr + (off))
 #define wrl(ep, off, val)	__raw_writel((val), (ep)->base_addr + (off))
 
-static int ep93xx_mdio_read(struct net_device *dev, int phy_id, int reg);
+static int ep93xx_mdio_read(struct net_device *dev, int phy_id, int reg)
+{
+	struct ep93xx_priv *ep = netdev_priv(dev);
+	int data;
+	int i;
+
+	wrl(ep, REG_MIICMD, REG_MIICMD_READ | (phy_id << 5) | reg);
+
+	for (i = 0; i < 10; i++) {
+		if ((rdl(ep, REG_MIISTS) & REG_MIISTS_BUSY) == 0)
+			break;
+		msleep(1);
+	}
+
+	if (i == 10) {
+		pr_info("mdio read timed out\n");
+		data = 0xffff;
+	} else {
+		data = rdl(ep, REG_MIIDATA);
+	}
+
+	return data;
+}
+
+static void ep93xx_mdio_write(struct net_device *dev, int phy_id, int reg, int data)
+{
+	struct ep93xx_priv *ep = netdev_priv(dev);
+	int i;
+
+	wrl(ep, REG_MIIDATA, data);
+	wrl(ep, REG_MIICMD, REG_MIICMD_WRITE | (phy_id << 5) | reg);
+
+	for (i = 0; i < 10; i++) {
+		if ((rdl(ep, REG_MIISTS) & REG_MIISTS_BUSY) == 0)
+			break;
+		msleep(1);
+	}
+
+	if (i == 10)
+		pr_info("mdio write timed out\n");
+}
 
 static struct net_device_stats *ep93xx_get_stats(struct net_device *dev)
 {
@@ -217,14 +260,11 @@ static int ep93xx_rx(struct net_device *
 		rstat->rstat1 = 0;
 
 		if (!(rstat0 & RSTAT0_EOF))
-			printk(KERN_CRIT "ep93xx_rx: not end-of-frame "
-					 " %.8x %.8x\n", rstat0, rstat1);
+			pr_crit("not end-of-frame %.8x %.8x\n", rstat0, rstat1);
 		if (!(rstat0 & RSTAT0_EOB))
-			printk(KERN_CRIT "ep93xx_rx: not end-of-buffer "
-					 " %.8x %.8x\n", rstat0, rstat1);
+			pr_crit("not end-of-buffer %.8x %.8x\n", rstat0, rstat1);
 		if ((rstat1 & RSTAT1_BUFFER_INDEX) >> 16 != entry)
-			printk(KERN_CRIT "ep93xx_rx: entry mismatch "
-					 " %.8x %.8x\n", rstat0, rstat1);
+			pr_crit("entry mismatch %.8x %.8x\n", rstat0, rstat1);
 
 		if (!(rstat0 & RSTAT0_RWE)) {
 			ep->stats.rx_errors++;
@@ -241,8 +281,7 @@ static int ep93xx_rx(struct net_device *
 
 		length = rstat1 & RSTAT1_FRAME_LENGTH;
 		if (length > MAX_PKT_SIZE) {
-			printk(KERN_NOTICE "ep93xx_rx: invalid length "
-					 " %.8x %.8x\n", rstat0, rstat1);
+			pr_notice("invalid length %.8x %.8x\n", rstat0, rstat1);
 			goto err;
 		}
 
@@ -272,11 +311,6 @@ err:
 		processed++;
 	}
 
-	if (processed) {
-		wrw(ep, REG_RXDENQ, processed);
-		wrw(ep, REG_RXSTSENQ, processed);
-	}
-
 	return processed;
 }
 
@@ -311,6 +345,11 @@ poll_some_more:
 			goto poll_some_more;
 	}
 
+	if (rx) {
+		wrw(ep, REG_RXDENQ, rx);
+		wrw(ep, REG_RXSTSENQ, rx);
+	}
+
 	return rx;
 }
 
@@ -371,11 +410,9 @@ static void ep93xx_tx_complete(struct ne
 		tstat->tstat0 = 0;
 
 		if (tstat0 & TSTAT0_FA)
-			printk(KERN_CRIT "ep93xx_tx_complete: frame aborted "
-					 " %.8x\n", tstat0);
+			pr_crit("frame aborted %.8x\n", tstat0);
 		if ((tstat0 & TSTAT0_BUFFER_INDEX) != entry)
-			printk(KERN_CRIT "ep93xx_tx_complete: entry mismatch "
-					 " %.8x\n", tstat0);
+			pr_crit("entry mismatch %.8x\n", tstat0);
 
 		if (tstat0 & TSTAT0_TXWE) {
 			int length = ep->descs->tdesc[entry].tdesc1 & 0xfff;
@@ -536,7 +573,7 @@ static int ep93xx_start_hw(struct net_de
 	}
 
 	if (i == 10) {
-		printk(KERN_CRIT DRV_MODULE_NAME ": hw failed to reset\n");
+		pr_crit("hw failed to reset\n");
 		return 1;
 	}
 
@@ -581,7 +618,7 @@ static int ep93xx_start_hw(struct net_de
 	}
 
 	if (i == 10) {
-		printk(KERN_CRIT DRV_MODULE_NAME ": hw failed to start\n");
+		pr_crit("hw failed to start\n");
 		return 1;
 	}
 
@@ -617,7 +654,7 @@ static void ep93xx_stop_hw(struct net_de
 	}
 
 	if (i == 10)
-		printk(KERN_CRIT DRV_MODULE_NAME ": hw failed to reset\n");
+		pr_crit("hw failed to reset\n");
 }
 
 static int ep93xx_open(struct net_device *dev)
@@ -681,48 +718,6 @@ static int ep93xx_ioctl(struct net_devic
 	return generic_mii_ioctl(&ep->mii, data, cmd, NULL);
 }
 
-static int ep93xx_mdio_read(struct net_device *dev, int phy_id, int reg)
-{
-	struct ep93xx_priv *ep = netdev_priv(dev);
-	int data;
-	int i;
-
-	wrl(ep, REG_MIICMD, REG_MIICMD_READ | (phy_id << 5) | reg);
-
-	for (i = 0; i < 10; i++) {
-		if ((rdl(ep, REG_MIISTS) & REG_MIISTS_BUSY) == 0)
-			break;
-		msleep(1);
-	}
-
-	if (i == 10) {
-		printk(KERN_INFO DRV_MODULE_NAME ": mdio read timed out\n");
-		data = 0xffff;
-	} else {
-		data = rdl(ep, REG_MIIDATA);
-	}
-
-	return data;
-}
-
-static void ep93xx_mdio_write(struct net_device *dev, int phy_id, int reg, int data)
-{
-	struct ep93xx_priv *ep = netdev_priv(dev);
-	int i;
-
-	wrl(ep, REG_MIIDATA, data);
-	wrl(ep, REG_MIICMD, REG_MIICMD_WRITE | (phy_id << 5) | reg);
-
-	for (i = 0; i < 10; i++) {
-		if ((rdl(ep, REG_MIISTS) & REG_MIISTS_BUSY) == 0)
-			break;
-		msleep(1);
-	}
-
-	if (i == 10)
-		printk(KERN_INFO DRV_MODULE_NAME ": mdio write timed out\n");
-}
-
 static void ep93xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
 	strcpy(info->driver, DRV_MODULE_NAME);
@@ -825,12 +820,19 @@ static int ep93xx_eth_probe(struct platf
 	struct ep93xx_eth_data *data;
 	struct net_device *dev;
 	struct ep93xx_priv *ep;
+	struct resource *mem;
+	int irq;
 	int err;
 
 	if (pdev == NULL)
 		return -ENODEV;
 	data = pdev->dev.platform_data;
 
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(pdev, 0);
+	if (!mem || irq < 0)
+		return -ENXIO;
+
 	dev = ep93xx_dev_alloc(data);
 	if (dev == NULL) {
 		err = -ENOMEM;
@@ -842,23 +844,21 @@ static int ep93xx_eth_probe(struct platf
 
 	platform_set_drvdata(pdev, dev);
 
-	ep->res = request_mem_region(pdev->resource[0].start,
-			pdev->resource[0].end - pdev->resource[0].start + 1,
-			dev_name(&pdev->dev));
+	ep->res = request_mem_region(mem->start, resource_size(mem),
+				     dev_name(&pdev->dev));
 	if (ep->res == NULL) {
 		dev_err(&pdev->dev, "Could not reserve memory region\n");
 		err = -ENOMEM;
 		goto err_out;
 	}
 
-	ep->base_addr = ioremap(pdev->resource[0].start,
-			pdev->resource[0].end - pdev->resource[0].start);
+	ep->base_addr = ioremap(mem->start, resource_size(mem));
 	if (ep->base_addr == NULL) {
 		dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n");
 		err = -EIO;
 		goto err_out;
 	}
-	ep->irq = pdev->resource[1].start;
+	ep->irq = irq;
 
 	ep->mii.phy_id = data->phy_id;
 	ep->mii.phy_id_mask = 0x1f;
@@ -877,11 +877,8 @@ static int ep93xx_eth_probe(struct platf
 		goto err_out;
 	}
 
-	printk(KERN_INFO "%s: ep93xx on-chip ethernet, IRQ %d, "
-			 "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x.\n", dev->name,
-			ep->irq, data->dev_addr[0], data->dev_addr[1],
-			data->dev_addr[2], data->dev_addr[3],
-			data->dev_addr[4], data->dev_addr[5]);
+	printk(KERN_INFO "%s: ep93xx on-chip ethernet, IRQ %d, %pM\n",
+			dev->name, ep->irq, dev->dev_addr);
 
 	return 0;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arm/ether3.c linux-libre-2.6.34-gnu1/drivers/net/arm/ether3.c
--- linux-libre-2.6.33-gnu1/drivers/net/arm/ether3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arm/ether3.c	2010-05-16 17:17:36.000000000 -0400
@@ -463,7 +463,7 @@ static void ether3_setmulticastlist(stru
 	if (dev->flags & IFF_PROMISC) {
 		/* promiscuous mode */
 		priv(dev)->regs.config1 |= CFG1_RECVPROMISC;
-	} else if (dev->flags & IFF_ALLMULTI || dev->mc_count) {
+	} else if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev)) {
 		priv(dev)->regs.config1 |= CFG1_RECVSPECBRMULTI;
 	} else
 		priv(dev)->regs.config1 |= CFG1_RECVSPECBROAD;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arm/etherh.c linux-libre-2.6.34-gnu1/drivers/net/arm/etherh.c
--- linux-libre-2.6.33-gnu1/drivers/net/arm/etherh.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arm/etherh.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arm/ixp4xx_eth.c linux-libre-2.6.34-gnu1/drivers/net/arm/ixp4xx_eth.c
--- linux-libre-2.6.33-gnu1/drivers/net/arm/ixp4xx_eth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arm/ixp4xx_eth.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/kernel.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <mach/npe.h>
 #include <mach/qmgr.h>
 
@@ -735,22 +736,25 @@ static int eth_xmit(struct sk_buff *skb,
 static void eth_set_mcast_list(struct net_device *dev)
 {
 	struct port *port = netdev_priv(dev);
-	struct dev_mc_list *mclist = dev->mc_list;
+	struct dev_mc_list *mclist;
 	u8 diffs[ETH_ALEN], *addr;
-	int cnt = dev->mc_count, i;
+	int i;
 
-	if ((dev->flags & IFF_PROMISC) || !mclist || !cnt) {
+	if ((dev->flags & IFF_PROMISC) || netdev_mc_empty(dev)) {
 		__raw_writel(DEFAULT_RX_CNTRL0 & ~RX_CNTRL0_ADDR_FLTR_EN,
 			     &port->regs->rx_control[0]);
 		return;
 	}
 
 	memset(diffs, 0, ETH_ALEN);
-	addr = mclist->dmi_addr; /* first MAC address */
 
-	while (--cnt && (mclist = mclist->next))
+	addr = NULL;
+	netdev_for_each_mc_addr(mclist, dev) {
+		if (!addr)
+			addr = mclist->dmi_addr; /* first MAC address */
 		for (i = 0; i < ETH_ALEN; i++)
 			diffs[i] |= addr[i] ^ mclist->dmi_addr[i];
+	}
 
 	for (i = 0; i < ETH_ALEN; i++) {
 		__raw_writel(addr[i], &port->regs->mcast_addr[i]);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arm/ks8695net.c linux-libre-2.6.34-gnu1/drivers/net/arm/ks8695net.c
--- linux-libre-2.6.33-gnu1/drivers/net/arm/ks8695net.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arm/ks8695net.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/platform_device.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 
@@ -327,25 +328,24 @@ ks8695_refill_rxbuffers(struct ks8695_pr
  */
 static void
 ks8695_init_partial_multicast(struct ks8695_priv *ksp,
-			      struct dev_mc_list *addr,
-			      int nr_addr)
+			      struct net_device *ndev)
 {
 	u32 low, high;
 	int i;
+	struct dev_mc_list *dmi;
 
-	for (i = 0; i < nr_addr; i++, addr = addr->next) {
-		/* Ran out of addresses? */
-		if (!addr)
-			break;
+	i = 0;
+	netdev_for_each_mc_addr(dmi, ndev) {
 		/* Ran out of space in chip? */
 		BUG_ON(i == KS8695_NR_ADDRESSES);
 
-		low = (addr->dmi_addr[2] << 24) | (addr->dmi_addr[3] << 16) |
-			(addr->dmi_addr[4] << 8) | (addr->dmi_addr[5]);
-		high = (addr->dmi_addr[0] << 8) | (addr->dmi_addr[1]);
+		low = (dmi->dmi_addr[2] << 24) | (dmi->dmi_addr[3] << 16) |
+		      (dmi->dmi_addr[4] << 8) | (dmi->dmi_addr[5]);
+		high = (dmi->dmi_addr[0] << 8) | (dmi->dmi_addr[1]);
 
 		ks8695_writereg(ksp, KS8695_AAL_(i), low);
 		ks8695_writereg(ksp, KS8695_AAH_(i), AAH_E | high);
+		i++;
 	}
 
 	/* Clear the remaining Additional Station Addresses */
@@ -450,11 +450,10 @@ ks8695_rx_irq(int irq, void *dev_id)
 }
 
 /**
- *	ks8695_rx - Receive packets  called by NAPI poll method
+ *	ks8695_rx - Receive packets called by NAPI poll method
  *	@ksp: Private data for the KS8695 Ethernet
- *	@budget: The max packets would be receive
+ *	@budget: Number of packets allowed to process
  */
-
 static int ks8695_rx(struct ks8695_priv *ksp, int budget)
 {
 	struct net_device *ndev = ksp->ndev;
@@ -462,7 +461,6 @@ static int ks8695_rx(struct ks8695_priv
 	int buff_n;
 	u32 flags;
 	int pktlen;
-	int last_rx_processed = -1;
 	int received = 0;
 
 	buff_n = ksp->next_rx_desc_read;
@@ -472,6 +470,7 @@ static int ks8695_rx(struct ks8695_priv
 					cpu_to_le32(RDES_OWN)))) {
 			rmb();
 			flags = le32_to_cpu(ksp->rx_ring[buff_n].status);
+
 			/* Found an SKB which we own, this means we
 			 * received a packet
 			 */
@@ -534,23 +533,18 @@ rx_failure:
 			ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN);
 rx_finished:
 			received++;
-			/* And note this as processed so we can start
-			 * from here next time
-			 */
-			last_rx_processed = buff_n;
 			buff_n = (buff_n + 1) & MAX_RX_DESC_MASK;
-			/*And note which RX descriptor we last did */
-			if (likely(last_rx_processed != -1))
-				ksp->next_rx_desc_read =
-					(last_rx_processed + 1) &
-					MAX_RX_DESC_MASK;
 	}
+
+	/* And note which RX descriptor we last did */
+	ksp->next_rx_desc_read = buff_n;
+
 	/* And refill the buffers */
 	ks8695_refill_rxbuffers(ksp);
 
-	/* Kick the RX DMA engine, in case it became
-	 *  suspended */
+	/* Kick the RX DMA engine, in case it became suspended */
 	ks8695_writereg(ksp, KS8695_DRSC, 0);
+
 	return received;
 }
 
@@ -576,9 +570,9 @@ static int ks8695_poll(struct napi_struc
 	if (work_done < budget) {
 		unsigned long flags;
 		spin_lock_irqsave(&ksp->rx_lock, flags);
+		__napi_complete(napi);
 		/*enable rx interrupt*/
 		writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN);
-		__napi_complete(napi);
 		spin_unlock_irqrestore(&ksp->rx_lock, flags);
 	}
 	return work_done;
@@ -1207,7 +1201,7 @@ ks8695_set_multicast(struct net_device *
 	if (ndev->flags & IFF_ALLMULTI) {
 		/* enable all multicast mode */
 		ctrl |= DRXC_RM;
-	} else if (ndev->mc_count > KS8695_NR_ADDRESSES) {
+	} else if (netdev_mc_count(ndev) > KS8695_NR_ADDRESSES) {
 		/* more specific multicast addresses than can be
 		 * handled in hardware
 		 */
@@ -1215,8 +1209,7 @@ ks8695_set_multicast(struct net_device *
 	} else {
 		/* enable specific multicasts */
 		ctrl &= ~DRXC_RM;
-		ks8695_init_partial_multicast(ksp, ndev->mc_list,
-					      ndev->mc_count);
+		ks8695_init_partial_multicast(ksp, ndev);
 	}
 
 	ks8695_writereg(ksp, KS8695_DRXC, ctrl);
@@ -1335,7 +1328,6 @@ ks8695_stop(struct net_device *ndev)
 
 	netif_stop_queue(ndev);
 	napi_disable(&ksp->napi);
-	netif_carrier_off(ndev);
 
 	ks8695_shutdown(ksp);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/arm/w90p910_ether.c linux-libre-2.6.34-gnu1/drivers/net/arm/w90p910_ether.c
--- linux-libre-2.6.33-gnu1/drivers/net/arm/w90p910_ether.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/arm/w90p910_ether.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/ethtool.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/gfp.h>
 
 #define DRV_MODULE_NAME		"w90p910-emc"
 #define DRV_MODULE_VERSION	"0.1"
@@ -858,10 +859,10 @@ static void w90p910_ether_set_multicast_
 
 	if (dev->flags & IFF_PROMISC)
 		rx_mode = CAMCMR_AUP | CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP;
-	else if ((dev->flags & IFF_ALLMULTI) || dev->mc_list)
-			rx_mode = CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP;
-		else
-				rx_mode = CAMCMR_ECMP | CAMCMR_ABP;
+	else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev))
+		rx_mode = CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP;
+	else
+		rx_mode = CAMCMR_ECMP | CAMCMR_ABP;
 	__raw_writel(rx_mode, ether->reg + REG_CAMCMR);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/at1700.c linux-libre-2.6.34-gnu1/drivers/net/at1700.c
--- linux-libre-2.6.33-gnu1/drivers/net/at1700.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/at1700.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,7 +47,6 @@
 #include <linux/ioport.h>
 #include <linux/in.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
@@ -839,21 +838,19 @@ set_rx_mode(struct net_device *dev)
 	if (dev->flags & IFF_PROMISC) {
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		outb(3, ioaddr + RX_MODE);	/* Enable promiscuous mode */
-	} else if (dev->mc_count > MC_FILTERBREAK ||
+	} else if (netdev_mc_count(dev) > MC_FILTERBREAK ||
 			   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter perfectly -- accept all multicasts. */
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		outb(2, ioaddr + RX_MODE);	/* Use normal mode. */
-	} else if (dev->mc_count == 0) {
+	} else if (netdev_mc_empty(dev)) {
 		memset(mc_filter, 0x00, sizeof(mc_filter));
 		outb(1, ioaddr + RX_MODE);	/* Ignore almost all multicasts. */
 	} else {
 		struct dev_mc_list *mclist;
-		int i;
 
 		memset(mc_filter, 0, sizeof(mc_filter));
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-			 i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			unsigned int bit =
 				ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26;
 			mc_filter[bit >> 3] |= (1 << bit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/atarilance.c linux-libre-2.6.34-gnu1/drivers/net/atarilance.c
--- linux-libre-2.6.33-gnu1/drivers/net/atarilance.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/atarilance.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,7 +53,6 @@ static char version[] = "atarilance.c: v
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
@@ -1097,7 +1096,7 @@ static void set_multicast_list( struct n
 		REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */
 	} else {
 		short multicast_table[4];
-		int num_addrs = dev->mc_count;
+		int num_addrs = netdev_mc_count(dev);
 		int i;
 		/* We don't use the multicast table, but rely on upper-layer
 		 * filtering. */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/atl1c/atl1c_ethtool.c linux-libre-2.6.34-gnu1/drivers/net/atl1c/atl1c_ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/atl1c/atl1c_ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/atl1c/atl1c_ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
+#include <linux/slab.h>
 
 #include "atl1c.h"
 
@@ -37,7 +38,7 @@ static int atl1c_get_settings(struct net
 			   SUPPORTED_100baseT_Full |
 			   SUPPORTED_Autoneg       |
 			   SUPPORTED_TP);
-	if (hw->ctrl_flags & ATL1C_LINK_CAP_1000M)
+	if (hw->link_cap_flags & ATL1C_LINK_CAP_1000M)
 		ecmd->supported |= SUPPORTED_1000baseT_Full;
 
 	ecmd->advertising = ADVERTISED_TP;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/atl1c/atl1c.h linux-libre-2.6.34-gnu1/drivers/net/atl1c/atl1c.h
--- linux-libre-2.6.33-gnu1/drivers/net/atl1c/atl1c.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/atl1c/atl1c.h	2010-05-16 17:17:36.000000000 -0400
@@ -313,6 +313,9 @@ enum atl1c_rss_type {
 enum atl1c_nic_type {
 	athr_l1c = 0,
 	athr_l2c = 1,
+	athr_l2c_b,
+	athr_l2c_b2,
+	athr_l1d,
 };
 
 enum atl1c_trans_queue {
@@ -426,8 +429,12 @@ struct atl1c_hw {
 #define ATL1C_ASPM_L1_SUPPORT		0x0100
 #define ATL1C_ASPM_CTRL_MON		0x0200
 #define ATL1C_HIB_DISABLE		0x0400
-#define ATL1C_LINK_CAP_1000M		0x0800
-#define ATL1C_FPGA_VERSION		0x8000
+#define ATL1C_APS_MODE_ENABLE           0x0800
+#define ATL1C_LINK_EXT_SYNC             0x1000
+#define ATL1C_CLK_GATING_EN             0x2000
+#define ATL1C_FPGA_VERSION              0x8000
+	u16 link_cap_flags;
+#define ATL1C_LINK_CAP_1000M		0x0001
 	u16 cmb_tpd;
 	u16 cmb_rrd;
 	u16 cmb_rx_timer; /* 2us resolution */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/atl1c/atl1c_hw.c linux-libre-2.6.34-gnu1/drivers/net/atl1c/atl1c_hw.c
--- linux-libre-2.6.33-gnu1/drivers/net/atl1c/atl1c_hw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/atl1c/atl1c_hw.c	2010-05-16 17:17:36.000000000 -0400
@@ -70,17 +70,39 @@ static int atl1c_get_permanent_address(s
 	u32 otp_ctrl_data;
 	u32 twsi_ctrl_data;
 	u8  eth_addr[ETH_ALEN];
+	u16 phy_data;
+	bool raise_vol = false;
 
 	/* init */
 	addr[0] = addr[1] = 0;
 	AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
 	if (atl1c_check_eeprom_exist(hw)) {
-		/* Enable OTP CLK */
-		if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) {
-			otp_ctrl_data |= OTP_CTRL_CLK_EN;
-			AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
-			AT_WRITE_FLUSH(hw);
-			msleep(1);
+		if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b) {
+			/* Enable OTP CLK */
+			if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) {
+				otp_ctrl_data |= OTP_CTRL_CLK_EN;
+				AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+				AT_WRITE_FLUSH(hw);
+				msleep(1);
+			}
+		}
+
+		if (hw->nic_type == athr_l2c_b ||
+		    hw->nic_type == athr_l2c_b2 ||
+		    hw->nic_type == athr_l1d) {
+			atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x00);
+			if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
+				goto out;
+			phy_data &= 0xFF7F;
+			atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
+
+			atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B);
+			if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
+				goto out;
+			phy_data |= 0x8;
+			atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
+			udelay(20);
+			raise_vol = true;
 		}
 
 		AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
@@ -96,11 +118,31 @@ static int atl1c_get_permanent_address(s
 			return -1;
 	}
 	/* Disable OTP_CLK */
-	if (otp_ctrl_data & OTP_CTRL_CLK_EN) {
-		otp_ctrl_data &= ~OTP_CTRL_CLK_EN;
-		AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
-		AT_WRITE_FLUSH(hw);
-		msleep(1);
+	if ((hw->nic_type == athr_l1c || hw->nic_type == athr_l2c)) {
+		if (otp_ctrl_data & OTP_CTRL_CLK_EN) {
+			otp_ctrl_data &= ~OTP_CTRL_CLK_EN;
+			AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+			AT_WRITE_FLUSH(hw);
+			msleep(1);
+		}
+	}
+	if (raise_vol) {
+		if (hw->nic_type == athr_l2c_b ||
+		    hw->nic_type == athr_l2c_b2 ||
+		    hw->nic_type == athr_l1d) {
+			atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x00);
+			if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
+				goto out;
+			phy_data |= 0x80;
+			atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
+
+			atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B);
+			if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
+				goto out;
+			phy_data &= 0xFFF7;
+			atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
+			udelay(20);
+		}
 	}
 
 	/* maybe MAC-address is from BIOS */
@@ -114,6 +156,7 @@ static int atl1c_get_permanent_address(s
 		return 0;
 	}
 
+out:
 	return -1;
 }
 
@@ -307,7 +350,7 @@ static int atl1c_phy_setup_adv(struct at
 		mii_adv_data |= ADVERTISE_10HALF  | ADVERTISE_10FULL |
 				ADVERTISE_100HALF | ADVERTISE_100FULL;
 
-	if (hw->ctrl_flags & ATL1C_LINK_CAP_1000M) {
+	if (hw->link_cap_flags & ATL1C_LINK_CAP_1000M) {
 		if (hw->autoneg_advertised & ADVERTISED_1000baseT_Half)
 			mii_giga_ctrl_data |= ADVERTISE_1000HALF;
 		if (hw->autoneg_advertised & ADVERTISED_1000baseT_Full)
@@ -389,6 +432,7 @@ int atl1c_phy_reset(struct atl1c_hw *hw)
 {
 	struct atl1c_adapter *adapter = hw->adapter;
 	struct pci_dev *pdev = adapter->pdev;
+	u16 phy_data;
 	u32 phy_ctrl_data = GPHY_CTRL_DEFAULT;
 	u32 mii_ier_data = IER_LINK_UP | IER_LINK_DOWN;
 	int err;
@@ -404,6 +448,21 @@ int atl1c_phy_reset(struct atl1c_hw *hw)
 	AT_WRITE_FLUSH(hw);
 	msleep(10);
 
+	if (hw->nic_type == athr_l2c_b) {
+		atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x0A);
+		atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data);
+		atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data & 0xDFFF);
+	}
+
+	if (hw->nic_type == athr_l2c_b ||
+	    hw->nic_type == athr_l2c_b2 ||
+	    hw->nic_type == athr_l1d) {
+		atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B);
+		atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data);
+		atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data & 0xFFF7);
+		msleep(20);
+	}
+
 	/*Enable PHY LinkChange Interrupt */
 	err = atl1c_write_phy_reg(hw, MII_IER, mii_ier_data);
 	if (err) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/atl1c/atl1c_hw.h linux-libre-2.6.34-gnu1/drivers/net/atl1c/atl1c_hw.h
--- linux-libre-2.6.33-gnu1/drivers/net/atl1c/atl1c_hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/atl1c/atl1c_hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -57,6 +57,7 @@ int atl1c_restart_autoneg(struct atl1c_h
 #define REG_LINK_CTRL			0x68
 #define LINK_CTRL_L0S_EN		0x01
 #define LINK_CTRL_L1_EN			0x02
+#define LINK_CTRL_EXT_SYNC		0x80
 
 #define REG_VPD_CAP			0x6C
 #define VPD_CAP_ID_MASK                 0xff
@@ -156,6 +157,8 @@ int atl1c_restart_autoneg(struct atl1c_h
 #define PM_CTRL_PM_REQ_TIMER_SHIFT	20
 #define PM_CTRL_LCKDET_TIMER_MASK	0x3F
 #define PM_CTRL_LCKDET_TIMER_SHIFT	24
+#define PM_CTRL_EN_BUFS_RX_L0S		0x10000000
+#define PM_CTRL_SA_DLY_EN		0x20000000
 #define PM_CTRL_MAC_ASPM_CHK		0x40000000
 #define PM_CTRL_HOTRST			0x80000000
 
@@ -314,6 +317,8 @@ int atl1c_restart_autoneg(struct atl1c_h
 #define MAC_CTRL_BC_EN              	0x4000000
 #define MAC_CTRL_DBG                	0x8000000
 #define MAC_CTRL_SINGLE_PAUSE_EN	0x10000000
+#define MAC_CTRL_HASH_ALG_CRC32		0x20000000
+#define MAC_CTRL_SPEED_MODE_SW		0x40000000
 
 /* MAC IPG/IFG Control Register  */
 #define REG_MAC_IPG_IFG             	0x1484
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/atl1c/atl1c_main.c linux-libre-2.6.34-gnu1/drivers/net/atl1c/atl1c_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/atl1c/atl1c_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/atl1c/atl1c_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,11 +21,18 @@
 
 #include "atl1c.h"
 
-#define ATL1C_DRV_VERSION "1.0.0.1-NAPI"
+#define ATL1C_DRV_VERSION "1.0.0.2-NAPI"
 char atl1c_driver_name[] = "atl1c";
 char atl1c_driver_version[] = ATL1C_DRV_VERSION;
 #define PCI_DEVICE_ID_ATTANSIC_L2C      0x1062
 #define PCI_DEVICE_ID_ATTANSIC_L1C      0x1063
+#define PCI_DEVICE_ID_ATHEROS_L2C_B	0x2060 /* AR8152 v1.1 Fast 10/100 */
+#define PCI_DEVICE_ID_ATHEROS_L2C_B2	0x2062 /* AR8152 v2.0 Fast 10/100 */
+#define PCI_DEVICE_ID_ATHEROS_L1D	0x1073 /* AR8151 v1.0 Gigabit 1000 */
+
+#define L2CB_V10			0xc0
+#define L2CB_V11			0xc1
+
 /*
  * atl1c_pci_tbl - PCI Device ID Table
  *
@@ -35,9 +42,12 @@ char atl1c_driver_version[] = ATL1C_DRV_
  * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
  *   Class, Class Mask, private data (not used) }
  */
-static struct pci_device_id atl1c_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(atl1c_pci_tbl) = {
 	{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1C)},
 	{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2C)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B2)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D)},
 	/* required last entry */
 	{ 0 }
 };
@@ -367,7 +377,7 @@ static void atl1c_set_multi(struct net_d
 	AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
 
 	/* comoute mc addresses' hash value ,and put it into hash table */
-	for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
+	netdev_for_each_mc_addr(mc_ptr, netdev) {
 		hash_value = atl1c_hash_mc_addr(hw, mc_ptr->dmi_addr);
 		atl1c_hash_set(hw, hash_value);
 	}
@@ -593,11 +603,18 @@ static void atl1c_set_mac_type(struct at
 	case PCI_DEVICE_ID_ATTANSIC_L2C:
 		hw->nic_type = athr_l2c;
 		break;
-
 	case PCI_DEVICE_ID_ATTANSIC_L1C:
 		hw->nic_type = athr_l1c;
 		break;
-
+	case PCI_DEVICE_ID_ATHEROS_L2C_B:
+		hw->nic_type = athr_l2c_b;
+		break;
+	case PCI_DEVICE_ID_ATHEROS_L2C_B2:
+		hw->nic_type = athr_l2c_b2;
+		break;
+	case PCI_DEVICE_ID_ATHEROS_L1D:
+		hw->nic_type = athr_l1d;
+		break;
 	default:
 		break;
 	}
@@ -620,10 +637,13 @@ static int atl1c_setup_mac_funcs(struct
 		hw->ctrl_flags |= ATL1C_ASPM_L0S_SUPPORT;
 	if (link_ctrl_data & LINK_CTRL_L1_EN)
 		hw->ctrl_flags |= ATL1C_ASPM_L1_SUPPORT;
+	if (link_ctrl_data & LINK_CTRL_EXT_SYNC)
+		hw->ctrl_flags |= ATL1C_LINK_EXT_SYNC;
 
-	if (hw->nic_type == athr_l1c) {
+	if (hw->nic_type == athr_l1c ||
+	    hw->nic_type == athr_l1d) {
 		hw->ctrl_flags |= ATL1C_ASPM_CTRL_MON;
-		hw->ctrl_flags |= ATL1C_LINK_CAP_1000M;
+		hw->link_cap_flags |= ATL1C_LINK_CAP_1000M;
 	}
 	return 0;
 }
@@ -1234,21 +1254,92 @@ static void atl1c_disable_l0s_l1(struct
 static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup)
 {
 	u32 pm_ctrl_data;
+	u32 link_ctrl_data;
 
 	AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data);
-
+	AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data);
 	pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1;
+
 	pm_ctrl_data &=  ~(PM_CTRL_L1_ENTRY_TIMER_MASK <<
 			PM_CTRL_L1_ENTRY_TIMER_SHIFT);
+	pm_ctrl_data &= ~(PM_CTRL_LCKDET_TIMER_MASK <<
+			  PM_CTRL_LCKDET_TIMER_SHIFT);
 
 	pm_ctrl_data |= PM_CTRL_MAC_ASPM_CHK;
+	pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
+	pm_ctrl_data |= PM_CTRL_RBER_EN;
+	pm_ctrl_data |= PM_CTRL_SDES_EN;
+
+	if (hw->nic_type == athr_l2c_b ||
+	    hw->nic_type == athr_l1d ||
+	    hw->nic_type == athr_l2c_b2) {
+		link_ctrl_data &= ~LINK_CTRL_EXT_SYNC;
+		if (!(hw->ctrl_flags & ATL1C_APS_MODE_ENABLE)) {
+			if (hw->nic_type == athr_l2c_b &&
+			    hw->revision_id == L2CB_V10)
+				link_ctrl_data |= LINK_CTRL_EXT_SYNC;
+		}
+
+		AT_WRITE_REG(hw, REG_LINK_CTRL, link_ctrl_data);
+
+		pm_ctrl_data |= PM_CTRL_PCIE_RECV;
+		pm_ctrl_data |= AT_ASPM_L1_TIMER << PM_CTRL_PM_REQ_TIMER_SHIFT;
+		pm_ctrl_data &= ~PM_CTRL_EN_BUFS_RX_L0S;
+		pm_ctrl_data &= ~PM_CTRL_SA_DLY_EN;
+		pm_ctrl_data &= ~PM_CTRL_HOTRST;
+		pm_ctrl_data |= 1 << PM_CTRL_L1_ENTRY_TIMER_SHIFT;
+		pm_ctrl_data |= PM_CTRL_SERDES_PD_EX_L1;
+	}
 
 	if (linkup) {
-		pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN;
-		pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1;
+		pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
+		pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
+		if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT)
+			pm_ctrl_data |= PM_CTRL_ASPM_L1_EN;
+		if (hw->ctrl_flags & ATL1C_ASPM_L0S_SUPPORT)
+			pm_ctrl_data |= PM_CTRL_ASPM_L0S_EN;
+
+		if (hw->nic_type == athr_l2c_b ||
+		    hw->nic_type == athr_l1d ||
+		    hw->nic_type == athr_l2c_b2) {
+			if (hw->nic_type == athr_l2c_b)
+				if (!(hw->ctrl_flags & ATL1C_APS_MODE_ENABLE))
+					pm_ctrl_data &= PM_CTRL_ASPM_L0S_EN;
+			pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN;
+			pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN;
+			pm_ctrl_data &= ~PM_CTRL_SERDES_BUDS_RX_L1_EN;
+			pm_ctrl_data |= PM_CTRL_CLK_SWH_L1;
+			if (hw->adapter->link_speed == SPEED_100 ||
+			    hw->adapter->link_speed == SPEED_1000) {
+				pm_ctrl_data &=
+					~(PM_CTRL_L1_ENTRY_TIMER_MASK <<
+					  PM_CTRL_L1_ENTRY_TIMER_SHIFT);
+				if (hw->nic_type == athr_l1d)
+					pm_ctrl_data |= 0xF <<
+						PM_CTRL_L1_ENTRY_TIMER_SHIFT;
+				else
+					pm_ctrl_data |= 7 <<
+						PM_CTRL_L1_ENTRY_TIMER_SHIFT;
+			}
+		} else {
+			pm_ctrl_data |= PM_CTRL_SERDES_L1_EN;
+			pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN;
+			pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN;
+			pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1;
+			pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
+			pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
+		}
+		atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x29);
+		if (hw->adapter->link_speed == SPEED_10)
+			if (hw->nic_type == athr_l1d)
+				atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0xB69D);
+			else
+				atl1c_write_phy_reg(hw, MII_DBG_DATA, 0xB6DD);
+		else if (hw->adapter->link_speed == SPEED_100)
+			atl1c_write_phy_reg(hw, MII_DBG_DATA, 0xB2DD);
+		else
+			atl1c_write_phy_reg(hw, MII_DBG_DATA, 0x96DD);
 
-		pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN;
-		pm_ctrl_data |= PM_CTRL_SERDES_L1_EN;
 	} else {
 		pm_ctrl_data &= ~PM_CTRL_SERDES_BUDS_RX_L1_EN;
 		pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN;
@@ -1302,6 +1393,10 @@ static void atl1c_setup_mac_ctrl(struct
 		mac_ctrl_data |= MAC_CTRL_MC_ALL_EN;
 
 	mac_ctrl_data |= MAC_CTRL_SINGLE_PAUSE_EN;
+	if (hw->nic_type == athr_l1d || hw->nic_type == athr_l2c_b2) {
+		mac_ctrl_data |= MAC_CTRL_SPEED_MODE_SW;
+		mac_ctrl_data |= MAC_CTRL_HASH_ALG_CRC32;
+	}
 	AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
 }
 
@@ -2596,11 +2691,8 @@ static int __devinit atl1c_probe(struct
 	memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
 	memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
 	if (netif_msg_probe(adapter))
-		dev_dbg(&pdev->dev,
-			"mac address : %02x-%02x-%02x-%02x-%02x-%02x\n",
-			adapter->hw.mac_addr[0], adapter->hw.mac_addr[1],
-			adapter->hw.mac_addr[2], adapter->hw.mac_addr[3],
-			adapter->hw.mac_addr[4], adapter->hw.mac_addr[5]);
+		dev_dbg(&pdev->dev, "mac address : %pM\n",
+			adapter->hw.mac_addr);
 
 	atl1c_hw_set_mac_addr(&adapter->hw);
 	INIT_WORK(&adapter->common_task, atl1c_common_task);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/atl1e/atl1e_ethtool.c linux-libre-2.6.34-gnu1/drivers/net/atl1e/atl1e_ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/atl1e/atl1e_ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/atl1e/atl1e_ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
+#include <linux/slab.h>
 
 #include "atl1e.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/atl1e/atl1e_hw.c linux-libre-2.6.34-gnu1/drivers/net/atl1e/atl1e_hw.c
--- linux-libre-2.6.33-gnu1/drivers/net/atl1e/atl1e_hw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/atl1e/atl1e_hw.c	2010-05-16 17:17:36.000000000 -0400
@@ -394,7 +394,6 @@ static int atl1e_phy_setup_autoneg_adv(s
 int atl1e_phy_commit(struct atl1e_hw *hw)
 {
 	struct atl1e_adapter *adapter = hw->adapter;
-	struct pci_dev *pdev = adapter->pdev;
 	int ret_val;
 	u16 phy_data;
 
@@ -415,12 +414,12 @@ int atl1e_phy_commit(struct atl1e_hw *hw
 		}
 
 		if (0 != (val & (MDIO_START | MDIO_BUSY))) {
-			dev_err(&pdev->dev,
-				"pcie linkdown at least for 25ms\n");
+			netdev_err(adapter->netdev,
+				   "pcie linkdown at least for 25ms\n");
 			return ret_val;
 		}
 
-		dev_err(&pdev->dev, "pcie linkup after %d ms\n", i);
+		netdev_err(adapter->netdev, "pcie linkup after %d ms\n", i);
 	}
 	return 0;
 }
@@ -428,7 +427,6 @@ int atl1e_phy_commit(struct atl1e_hw *hw
 int atl1e_phy_init(struct atl1e_hw *hw)
 {
 	struct atl1e_adapter *adapter = hw->adapter;
-	struct pci_dev *pdev = adapter->pdev;
 	s32 ret_val;
 	u16 phy_val;
 
@@ -492,20 +490,22 @@ int atl1e_phy_init(struct atl1e_hw *hw)
 	/*Enable PHY LinkChange Interrupt */
 	ret_val = atl1e_write_phy_reg(hw, MII_INT_CTRL, 0xC00);
 	if (ret_val) {
-		dev_err(&pdev->dev, "Error enable PHY linkChange Interrupt\n");
+		netdev_err(adapter->netdev,
+			   "Error enable PHY linkChange Interrupt\n");
 		return ret_val;
 	}
 	/* setup AutoNeg parameters */
 	ret_val = atl1e_phy_setup_autoneg_adv(hw);
 	if (ret_val) {
-		dev_err(&pdev->dev, "Error Setting up Auto-Negotiation\n");
+		netdev_err(adapter->netdev,
+			   "Error Setting up Auto-Negotiation\n");
 		return ret_val;
 	}
 	/* SW.Reset & En-Auto-Neg to restart Auto-Neg*/
-	dev_dbg(&pdev->dev, "Restarting Auto-Neg");
+	netdev_dbg(adapter->netdev, "Restarting Auto-Negotiation\n");
 	ret_val = atl1e_phy_commit(hw);
 	if (ret_val) {
-		dev_err(&pdev->dev, "Error Resetting the phy");
+		netdev_err(adapter->netdev, "Error resetting the phy\n");
 		return ret_val;
 	}
 
@@ -559,9 +559,8 @@ int atl1e_reset_hw(struct atl1e_hw *hw)
 	}
 
 	if (timeout >= AT_HW_MAX_IDLE_DELAY) {
-		dev_err(&pdev->dev,
-			"MAC state machine cann't be idle since"
-			" disabled for 10ms second\n");
+		netdev_err(adapter->netdev,
+			   "MAC state machine can't be idle since disabled for 10ms second\n");
 		return AT_ERR_TIMEOUT;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/atl1e/atl1e_main.c linux-libre-2.6.34-gnu1/drivers/net/atl1e/atl1e_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/atl1e/atl1e_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/atl1e/atl1e_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,7 +35,7 @@ char atl1e_driver_version[] = DRV_VERSIO
  * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
  *   Class, Class Mask, private data (not used) }
  */
-static struct pci_device_id atl1e_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(atl1e_pci_tbl) = {
 	{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1E)},
 	{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, 0x1066)},
 	/* required last entry */
@@ -164,11 +164,10 @@ static int atl1e_check_link(struct atl1e
 {
 	struct atl1e_hw *hw = &adapter->hw;
 	struct net_device *netdev = adapter->netdev;
-	struct pci_dev    *pdev   = adapter->pdev;
 	int err = 0;
 	u16 speed, duplex, phy_data;
 
-	/* MII_BMSR must read twise */
+	/* MII_BMSR must read twice */
 	atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
 	atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
 	if ((phy_data & BMSR_LSTATUS) == 0) {
@@ -195,12 +194,11 @@ static int atl1e_check_link(struct atl1e
 			adapter->link_speed  = speed;
 			adapter->link_duplex = duplex;
 			atl1e_setup_mac_ctrl(adapter);
-			dev_info(&pdev->dev,
-				"%s: %s NIC Link is Up<%d Mbps %s>\n",
-				atl1e_driver_name, netdev->name,
-				adapter->link_speed,
-				adapter->link_duplex == FULL_DUPLEX ?
-				"Full Duplex" : "Half Duplex");
+			netdev_info(netdev,
+				    "NIC Link is Up <%d Mbps %s Duplex>\n",
+				    adapter->link_speed,
+				    adapter->link_duplex == FULL_DUPLEX ?
+				    "Full" : "Half");
 		}
 
 		if (!netif_carrier_ok(netdev)) {
@@ -230,7 +228,6 @@ static void atl1e_link_chg_task(struct w
 static void atl1e_link_chg_event(struct atl1e_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
-	struct pci_dev    *pdev   = adapter->pdev;
 	u16 phy_data = 0;
 	u16 link_up = 0;
 
@@ -243,8 +240,7 @@ static void atl1e_link_chg_event(struct
 	if (!link_up) {
 		if (netif_carrier_ok(netdev)) {
 			/* old link state: Up */
-			dev_info(&pdev->dev, "%s: %s NIC Link is Down\n",
-					atl1e_driver_name, netdev->name);
+			netdev_info(netdev, "NIC Link is Down\n");
 			adapter->link_speed = SPEED_0;
 			netif_stop_queue(netdev);
 		}
@@ -311,7 +307,7 @@ static void atl1e_set_multi(struct net_d
 	AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
 
 	/* comoute mc addresses' hash value ,and put it into hash table */
-	for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
+	netdev_for_each_mc_addr(mc_ptr, netdev) {
 		hash_value = atl1e_hash_mc_addr(hw, mc_ptr->dmi_addr);
 		atl1e_hash_set(hw, hash_value);
 	}
@@ -321,10 +317,9 @@ static void atl1e_vlan_rx_register(struc
 				   struct vlan_group *grp)
 {
 	struct atl1e_adapter *adapter = netdev_priv(netdev);
-	struct pci_dev *pdev = adapter->pdev;
 	u32 mac_ctrl_data = 0;
 
-	dev_dbg(&pdev->dev, "atl1e_vlan_rx_register\n");
+	netdev_dbg(adapter->netdev, "%s\n", __func__);
 
 	atl1e_irq_disable(adapter);
 
@@ -345,9 +340,7 @@ static void atl1e_vlan_rx_register(struc
 
 static void atl1e_restore_vlan(struct atl1e_adapter *adapter)
 {
-	struct pci_dev *pdev = adapter->pdev;
-
-	dev_dbg(&pdev->dev, "atl1e_restore_vlan !");
+	netdev_dbg(adapter->netdev, "%s\n", __func__);
 	atl1e_vlan_rx_register(adapter->netdev, adapter->vlgrp);
 }
 /*
@@ -391,7 +384,7 @@ static int atl1e_change_mtu(struct net_d
 
 	if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
 			(max_frame > MAX_JUMBO_FRAME_SIZE)) {
-		dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
+		netdev_warn(adapter->netdev, "invalid MTU setting\n");
 		return -EINVAL;
 	}
 	/* set MTU */
@@ -438,7 +431,6 @@ static int atl1e_mii_ioctl(struct net_de
 			   struct ifreq *ifr, int cmd)
 {
 	struct atl1e_adapter *adapter = netdev_priv(netdev);
-	struct pci_dev *pdev = adapter->pdev;
 	struct mii_ioctl_data *data = if_mii(ifr);
 	unsigned long flags;
 	int retval = 0;
@@ -466,8 +458,8 @@ static int atl1e_mii_ioctl(struct net_de
 			goto out;
 		}
 
-		dev_dbg(&pdev->dev, "<atl1e_mii_ioctl> write %x %x",
-				data->reg_num, data->val_in);
+		netdev_dbg(adapter->netdev, "<atl1e_mii_ioctl> write %x %x\n",
+			   data->reg_num, data->val_in);
 		if (atl1e_write_phy_reg(&adapter->hw,
 				     data->reg_num, data->val_in)) {
 			retval = -EIO;
@@ -602,7 +594,7 @@ static int __devinit atl1e_sw_init(struc
 	hw->dmaw_dly_cnt = 4;
 
 	if (atl1e_alloc_queues(adapter)) {
-		dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
+		netdev_err(adapter->netdev, "Unable to allocate memory for queues\n");
 		return -ENOMEM;
 	}
 
@@ -800,8 +792,8 @@ static int atl1e_setup_ring_resources(st
 			adapter->ring_size, &adapter->ring_dma);
 
 	if (adapter->ring_vir_addr == NULL) {
-		dev_err(&pdev->dev, "pci_alloc_consistent failed, "
-				    "size = D%d", size);
+		netdev_err(adapter->netdev,
+			   "pci_alloc_consistent failed, size = D%d\n", size);
 		return -ENOMEM;
 	}
 
@@ -817,7 +809,8 @@ static int atl1e_setup_ring_resources(st
 	size = sizeof(struct atl1e_tx_buffer) * (tx_ring->count);
 	tx_ring->tx_buffer = kzalloc(size, GFP_KERNEL);
 	if (tx_ring->tx_buffer == NULL) {
-		dev_err(&pdev->dev, "kzalloc failed , size = D%d", size);
+		netdev_err(adapter->netdev, "kzalloc failed, size = D%d\n",
+			   size);
 		err = -ENOMEM;
 		goto failed;
 	}
@@ -852,8 +845,8 @@ static int atl1e_setup_ring_resources(st
 	}
 
 	if (unlikely(offset > adapter->ring_size)) {
-		dev_err(&pdev->dev, "offset(%d) > ring size(%d) !!\n",
-				offset, adapter->ring_size);
+		netdev_err(adapter->netdev, "offset(%d) > ring size(%d) !!\n",
+			   offset, adapter->ring_size);
 		err = -1;
 		goto failed;
 	}
@@ -1077,7 +1070,6 @@ static void atl1e_setup_mac_ctrl(struct
 static int atl1e_configure(struct atl1e_adapter *adapter)
 {
 	struct atl1e_hw *hw = &adapter->hw;
-	struct pci_dev *pdev = adapter->pdev;
 
 	u32 intr_status_data = 0;
 
@@ -1130,8 +1122,8 @@ static int atl1e_configure(struct atl1e_
 
 	intr_status_data = AT_READ_REG(hw, REG_ISR);
 	if (unlikely((intr_status_data & ISR_PHY_LINKDOWN) != 0)) {
-		dev_err(&pdev->dev, "atl1e_configure failed,"
-				"PCIE phy link down\n");
+		netdev_err(adapter->netdev,
+			   "atl1e_configure failed, PCIE phy link down\n");
 		return -1;
 	}
 
@@ -1262,7 +1254,6 @@ static irqreturn_t atl1e_intr(int irq, v
 {
 	struct net_device *netdev  = data;
 	struct atl1e_adapter *adapter = netdev_priv(netdev);
-	struct pci_dev *pdev = adapter->pdev;
 	struct atl1e_hw *hw = &adapter->hw;
 	int max_ints = AT_MAX_INT_WORK;
 	int handled = IRQ_NONE;
@@ -1285,8 +1276,8 @@ static irqreturn_t atl1e_intr(int irq, v
 		handled = IRQ_HANDLED;
 		/* check if PCIE PHY Link down */
 		if (status & ISR_PHY_LINKDOWN) {
-			dev_err(&pdev->dev,
-				"pcie phy linkdown %x\n", status);
+			netdev_err(adapter->netdev,
+				   "pcie phy linkdown %x\n", status);
 			if (netif_running(adapter->netdev)) {
 				/* reset MAC */
 				atl1e_irq_reset(adapter);
@@ -1297,9 +1288,9 @@ static irqreturn_t atl1e_intr(int irq, v
 
 		/* check if DMA read/write error */
 		if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
-			dev_err(&pdev->dev,
-				"PCIE DMA RW error (status = 0x%x)\n",
-				status);
+			netdev_err(adapter->netdev,
+				   "PCIE DMA RW error (status = 0x%x)\n",
+				   status);
 			atl1e_irq_reset(adapter);
 			schedule_work(&adapter->reset_task);
 			break;
@@ -1382,7 +1373,6 @@ static struct atl1e_rx_page *atl1e_get_r
 static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que,
 		   int *work_done, int work_to_do)
 {
-	struct pci_dev *pdev = adapter->pdev;
 	struct net_device *netdev  = adapter->netdev;
 	struct atl1e_rx_ring *rx_ring = (struct atl1e_rx_ring *)
 					 &adapter->rx_ring;
@@ -1404,11 +1394,10 @@ static void atl1e_clean_rx_irq(struct at
 						 rx_page->read_offset);
 			/* check sequence number */
 			if (prrs->seq_num != rx_page_desc[que].rx_nxseq) {
-				dev_err(&pdev->dev,
-					"rx sequence number"
-					" error (rx=%d) (expect=%d)\n",
-					prrs->seq_num,
-					rx_page_desc[que].rx_nxseq);
+				netdev_err(netdev,
+					   "rx sequence number error (rx=%d) (expect=%d)\n",
+					   prrs->seq_num,
+					   rx_page_desc[que].rx_nxseq);
 				rx_page_desc[que].rx_nxseq++;
 				/* just for debug use */
 				AT_WRITE_REG(&adapter->hw, REG_DEBUG_DATA0,
@@ -1424,9 +1413,9 @@ static void atl1e_clean_rx_irq(struct at
 					RRS_ERR_DRIBBLE | RRS_ERR_CODE |
 					RRS_ERR_TRUNC)) {
 				/* hardware error, discard this packet*/
-					dev_err(&pdev->dev,
-						"rx packet desc error %x\n",
-						*((u32 *)prrs + 1));
+					netdev_err(netdev,
+						   "rx packet desc error %x\n",
+						   *((u32 *)prrs + 1));
 					goto skip_pkt;
 				}
 			}
@@ -1435,8 +1424,8 @@ static void atl1e_clean_rx_irq(struct at
 					RRS_PKT_SIZE_MASK) - 4; /* CRC */
 			skb = netdev_alloc_skb_ip_align(netdev, packet_size);
 			if (skb == NULL) {
-				dev_warn(&pdev->dev, "%s: Memory squeeze,"
-					"deferring packet.\n", netdev->name);
+				netdev_warn(netdev,
+					    "Memory squeeze, deferring packet\n");
 				goto skip_pkt;
 			}
 			skb->dev = netdev;
@@ -1450,9 +1439,9 @@ static void atl1e_clean_rx_irq(struct at
 				u16 vlan_tag = (prrs->vtag >> 4) |
 					       ((prrs->vtag & 7) << 13) |
 					       ((prrs->vtag & 8) << 9);
-				dev_dbg(&pdev->dev,
-					"RXD VLAN TAG<RRD>=0x%04x\n",
-					prrs->vtag);
+				netdev_dbg(netdev,
+					   "RXD VLAN TAG<RRD>=0x%04x\n",
+					   prrs->vtag);
 				vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
 							 vlan_tag);
 			} else {
@@ -1500,7 +1489,6 @@ static int atl1e_clean(struct napi_struc
 {
 	struct atl1e_adapter *adapter =
 			container_of(napi, struct atl1e_adapter, napi);
-	struct pci_dev    *pdev    = adapter->pdev;
 	u32 imr_data;
 	int work_done = 0;
 
@@ -1519,8 +1507,8 @@ quit_polling:
 		/* test debug */
 		if (test_bit(__AT_DOWN, &adapter->flags)) {
 			atomic_dec(&adapter->irq_sem);
-			dev_err(&pdev->dev,
-				"atl1e_clean is called when AT_DOWN\n");
+			netdev_err(adapter->netdev,
+				   "atl1e_clean is called when AT_DOWN\n");
 		}
 		/* reenable RX intr */
 		/*atl1e_irq_enable(adapter); */
@@ -1618,7 +1606,6 @@ static u16 atl1e_cal_tdp_req(const struc
 static int atl1e_tso_csum(struct atl1e_adapter *adapter,
 		       struct sk_buff *skb, struct atl1e_tpd_desc *tpd)
 {
-	struct pci_dev *pdev = adapter->pdev;
 	u8 hdr_len;
 	u32 real_len;
 	unsigned short offload_type;
@@ -1642,8 +1629,8 @@ static int atl1e_tso_csum(struct atl1e_a
 			hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
 			if (unlikely(skb->len == hdr_len)) {
 				/* only xsum need */
-				dev_warn(&pdev->dev,
-				      "IPV4 tso with zero data??\n");
+				netdev_warn(adapter->netdev,
+					    "IPV4 tso with zero data??\n");
 				goto check_sum;
 			} else {
 				ip_hdr(skb)->check = 0;
@@ -1672,8 +1659,8 @@ check_sum:
 
 		cso = skb_transport_offset(skb);
 		if (unlikely(cso & 0x1)) {
-			dev_err(&adapter->pdev->dev,
-			   "pay load offset should not ant event number\n");
+			netdev_err(adapter->netdev,
+				   "payload offset should not ant event number\n");
 			return -1;
 		} else {
 			css = cso + skb->csum_offset;
@@ -1886,8 +1873,8 @@ static int atl1e_request_irq(struct atl1
 	adapter->have_msi = true;
 	err = pci_enable_msi(adapter->pdev);
 	if (err) {
-		dev_dbg(&pdev->dev,
-			"Unable to allocate MSI interrupt Error: %d\n", err);
+		netdev_dbg(adapter->netdev,
+			   "Unable to allocate MSI interrupt Error: %d\n", err);
 		adapter->have_msi = false;
 	} else
 		netdev->irq = pdev->irq;
@@ -1898,13 +1885,13 @@ static int atl1e_request_irq(struct atl1
 	err = request_irq(adapter->pdev->irq, atl1e_intr, flags,
 			netdev->name, netdev);
 	if (err) {
-		dev_dbg(&pdev->dev,
-			"Unable to allocate interrupt Error: %d\n", err);
+		netdev_dbg(adapter->netdev,
+			   "Unable to allocate interrupt Error: %d\n", err);
 		if (adapter->have_msi)
 			pci_disable_msi(adapter->pdev);
 		return err;
 	}
-	dev_dbg(&pdev->dev, "atl1e_request_irq OK\n");
+	netdev_dbg(adapter->netdev, "atl1e_request_irq OK\n");
 	return err;
 }
 
@@ -2078,7 +2065,7 @@ static int atl1e_suspend(struct pci_dev
 		    (atl1e_write_phy_reg(hw,
 			   MII_ADVERTISE, mii_advertise_data) != 0) ||
 		    (atl1e_phy_commit(hw)) != 0) {
-			dev_dbg(&pdev->dev, "set phy register failed\n");
+			netdev_dbg(adapter->netdev, "set phy register failed\n");
 			goto wol_dis;
 		}
 
@@ -2100,17 +2087,14 @@ static int atl1e_suspend(struct pci_dev
 				}
 
 				if ((mii_bmsr_data & BMSR_LSTATUS) == 0)
-					dev_dbg(&pdev->dev,
-						"%s: Link may change"
-						"when suspend\n",
-						atl1e_driver_name);
+					netdev_dbg(adapter->netdev,
+						   "Link may change when suspend\n");
 			}
 			wol_ctrl_data |=  WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
 			/* only link up can wake up */
 			if (atl1e_write_phy_reg(hw, MII_INT_CTRL, 0x400) != 0) {
-				dev_dbg(&pdev->dev, "%s: read write phy "
-						  "register failed.\n",
-						  atl1e_driver_name);
+				netdev_dbg(adapter->netdev,
+					   "read write phy register failed\n");
 				goto wol_dis;
 			}
 		}
@@ -2131,9 +2115,8 @@ static int atl1e_suspend(struct pci_dev
 		if (wufc & AT_WUFC_MAG)
 			mac_ctrl_data |= MAC_CTRL_BC_EN;
 
-		dev_dbg(&pdev->dev,
-			"%s: suspend MAC=0x%x\n",
-			atl1e_driver_name, mac_ctrl_data);
+		netdev_dbg(adapter->netdev, "suspend MAC=0x%x\n",
+			   mac_ctrl_data);
 
 		AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data);
 		AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
@@ -2183,8 +2166,8 @@ static int atl1e_resume(struct pci_dev *
 
 	err = pci_enable_device(pdev);
 	if (err) {
-		dev_err(&pdev->dev, "ATL1e: Cannot enable PCI"
-				" device from suspend\n");
+		netdev_err(adapter->netdev,
+			   "Cannot enable PCI device from suspend\n");
 		return err;
 	}
 
@@ -2315,7 +2298,7 @@ static int __devinit atl1e_probe(struct
 
 	err = atl1e_init_netdev(netdev, pdev);
 	if (err) {
-		dev_err(&pdev->dev, "init netdevice failed\n");
+		netdev_err(netdev, "init netdevice failed\n");
 		goto err_init_netdev;
 	}
 	adapter = netdev_priv(netdev);
@@ -2326,7 +2309,7 @@ static int __devinit atl1e_probe(struct
 	adapter->hw.hw_addr = pci_iomap(pdev, BAR_0, 0);
 	if (!adapter->hw.hw_addr) {
 		err = -EIO;
-		dev_err(&pdev->dev, "cannot map device registers\n");
+		netdev_err(netdev, "cannot map device registers\n");
 		goto err_ioremap;
 	}
 	netdev->base_addr = (unsigned long)adapter->hw.hw_addr;
@@ -2356,7 +2339,7 @@ static int __devinit atl1e_probe(struct
 	/* setup the private structure */
 	err = atl1e_sw_init(adapter);
 	if (err) {
-		dev_err(&pdev->dev, "net device private data init failed\n");
+		netdev_err(netdev, "net device private data init failed\n");
 		goto err_sw_init;
 	}
 
@@ -2372,22 +2355,19 @@ static int __devinit atl1e_probe(struct
 
 	if (atl1e_read_mac_addr(&adapter->hw) != 0) {
 		err = -EIO;
-		dev_err(&pdev->dev, "get mac address failed\n");
+		netdev_err(netdev, "get mac address failed\n");
 		goto err_eeprom;
 	}
 
 	memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
 	memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
-	dev_dbg(&pdev->dev, "mac address : %02x-%02x-%02x-%02x-%02x-%02x\n",
-			adapter->hw.mac_addr[0], adapter->hw.mac_addr[1],
-			adapter->hw.mac_addr[2], adapter->hw.mac_addr[3],
-			adapter->hw.mac_addr[4], adapter->hw.mac_addr[5]);
+	netdev_dbg(netdev, "mac address : %pM\n", adapter->hw.mac_addr);
 
 	INIT_WORK(&adapter->reset_task, atl1e_reset_task);
 	INIT_WORK(&adapter->link_chg_task, atl1e_link_chg_task);
 	err = register_netdev(netdev);
 	if (err) {
-		dev_err(&pdev->dev, "register netdevice failed\n");
+		netdev_err(netdev, "register netdevice failed\n");
 		goto err_register;
 	}
 
@@ -2488,8 +2468,8 @@ static pci_ers_result_t atl1e_io_slot_re
 	struct atl1e_adapter *adapter = netdev_priv(netdev);
 
 	if (pci_enable_device(pdev)) {
-		dev_err(&pdev->dev,
-		       "ATL1e: Cannot re-enable PCI device after reset.\n");
+		netdev_err(adapter->netdev,
+			   "Cannot re-enable PCI device after reset\n");
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 	pci_set_master(pdev);
@@ -2517,8 +2497,8 @@ static void atl1e_io_resume(struct pci_d
 
 	if (netif_running(netdev)) {
 		if (atl1e_up(adapter)) {
-			dev_err(&pdev->dev,
-			  "ATL1e: can't bring device back up after reset\n");
+			netdev_err(adapter->netdev,
+				   "can't bring device back up after reset\n");
 			return;
 		}
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/atl1e/atl1e_param.c linux-libre-2.6.34-gnu1/drivers/net/atl1e/atl1e_param.c
--- linux-libre-2.6.33-gnu1/drivers/net/atl1e/atl1e_param.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/atl1e/atl1e_param.c	2010-05-16 17:17:36.000000000 -0400
@@ -116,7 +116,7 @@ struct atl1e_option {
 	} arg;
 };
 
-static int __devinit atl1e_validate_option(int *value, struct atl1e_option *opt, struct pci_dev *pdev)
+static int __devinit atl1e_validate_option(int *value, struct atl1e_option *opt, struct atl1e_adapter *adapter)
 {
 	if (*value == OPTION_UNSET) {
 		*value = opt->def;
@@ -127,16 +127,19 @@ static int __devinit atl1e_validate_opti
 	case enable_option:
 		switch (*value) {
 		case OPTION_ENABLED:
-			dev_info(&pdev->dev, "%s Enabled\n", opt->name);
+			netdev_info(adapter->netdev,
+				    "%s Enabled\n", opt->name);
 			return 0;
 		case OPTION_DISABLED:
-			dev_info(&pdev->dev, "%s Disabled\n", opt->name);
+			netdev_info(adapter->netdev,
+				    "%s Disabled\n", opt->name);
 			return 0;
 		}
 		break;
 	case range_option:
 		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
-			dev_info(&pdev->dev, "%s set to %i\n", opt->name, *value);
+			netdev_info(adapter->netdev, "%s set to %i\n",
+				    opt->name, *value);
 			return 0;
 		}
 		break;
@@ -148,8 +151,8 @@ static int __devinit atl1e_validate_opti
 				ent = &opt->arg.l.p[i];
 				if (*value == ent->i) {
 					if (ent->str[0] != '\0')
-						dev_info(&pdev->dev, "%s\n",
-							ent->str);
+						netdev_info(adapter->netdev,
+							    "%s\n", ent->str);
 					return 0;
 				}
 			}
@@ -159,8 +162,8 @@ static int __devinit atl1e_validate_opti
 		BUG();
 	}
 
-	dev_info(&pdev->dev, "Invalid %s specified (%i) %s\n",
-			opt->name, *value, opt->err);
+	netdev_info(adapter->netdev, "Invalid %s specified (%i) %s\n",
+		    opt->name, *value, opt->err);
 	*value = opt->def;
 	return -1;
 }
@@ -176,11 +179,13 @@ static int __devinit atl1e_validate_opti
  */
 void __devinit atl1e_check_options(struct atl1e_adapter *adapter)
 {
-	struct pci_dev *pdev = adapter->pdev;
 	int bd = adapter->bd_number;
+
 	if (bd >= ATL1E_MAX_NIC) {
-		dev_notice(&pdev->dev, "no configuration for board #%i\n", bd);
-		dev_notice(&pdev->dev, "Using defaults for all values\n");
+		netdev_notice(adapter->netdev,
+			      "no configuration for board #%i\n", bd);
+		netdev_notice(adapter->netdev,
+			      "Using defaults for all values\n");
 	}
 
 	{ 		/* Transmit Ring Size */
@@ -196,7 +201,7 @@ void __devinit atl1e_check_options(struc
 		int val;
 		if (num_tx_desc_cnt > bd) {
 			val = tx_desc_cnt[bd];
-			atl1e_validate_option(&val, &opt, pdev);
+			atl1e_validate_option(&val, &opt, adapter);
 			adapter->tx_ring.count = (u16) val & 0xFFFC;
 		} else
 			adapter->tx_ring.count = (u16)opt.def;
@@ -215,7 +220,7 @@ void __devinit atl1e_check_options(struc
 		int val;
 		if (num_rx_mem_size > bd) {
 			val = rx_mem_size[bd];
-			atl1e_validate_option(&val, &opt, pdev);
+			atl1e_validate_option(&val, &opt, adapter);
 			adapter->rx_ring.page_size = (u32)val * 1024;
 		} else {
 			adapter->rx_ring.page_size = (u32)opt.def * 1024;
@@ -235,7 +240,7 @@ void __devinit atl1e_check_options(struc
 		int val;
 		if (num_int_mod_timer > bd) {
 			val = int_mod_timer[bd];
-			atl1e_validate_option(&val, &opt, pdev);
+			atl1e_validate_option(&val, &opt, adapter);
 			adapter->hw.imt = (u16) val;
 		} else
 			adapter->hw.imt = (u16)(opt.def);
@@ -254,7 +259,7 @@ void __devinit atl1e_check_options(struc
 		int val;
 		if (num_media_type > bd) {
 			val = media_type[bd];
-			atl1e_validate_option(&val, &opt, pdev);
+			atl1e_validate_option(&val, &opt, adapter);
 			adapter->hw.media_type = (u16) val;
 		} else
 			adapter->hw.media_type = (u16)(opt.def);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/atlx/atl1.c linux-libre-2.6.34-gnu1/drivers/net/atlx/atl1.c
--- linux-libre-2.6.33-gnu1/drivers/net/atlx/atl1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/atlx/atl1.c	2010-05-16 17:17:36.000000000 -0400
@@ -84,7 +84,7 @@
 
 #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>");
+Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(ATLX_DRIVER_VERSION);
 
@@ -232,7 +232,7 @@ static void __devinit atl1_check_options
 /*
  * atl1_pci_tbl - PCI Device ID Table
  */
-static const struct pci_device_id atl1_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(atl1_pci_tbl) = {
 	{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1)},
 	/* required last entry */
 	{0,}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/atlx/atl2.c linux-libre-2.6.34-gnu1/drivers/net/atlx/atl2.c
--- linux-libre-2.6.33-gnu1/drivers/net/atlx/atl2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/atlx/atl2.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/pci_ids.h>
 #include <linux/pm.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/tcp.h>
@@ -63,7 +64,7 @@ MODULE_VERSION(ATL2_DRV_VERSION);
 /*
  * atl2_pci_tbl - PCI Device ID Table
  */
-static struct pci_device_id atl2_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(atl2_pci_tbl) = {
 	{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2)},
 	/* required last entry */
 	{0,}
@@ -157,7 +158,7 @@ static void atl2_set_multi(struct net_de
 	ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
 
 	/* comoute mc addresses' hash value ,and put it into hash table */
-	for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
+	netdev_for_each_mc_addr(mc_ptr, netdev) {
 		hash_value = atl2_hash_mc_addr(hw, mc_ptr->dmi_addr);
 		atl2_hash_set(hw, hash_value);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/atlx/atl2.h linux-libre-2.6.34-gnu1/drivers/net/atlx/atl2.h
--- linux-libre-2.6.33-gnu1/drivers/net/atlx/atl2.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/atlx/atl2.h	2010-05-16 17:17:36.000000000 -0400
@@ -442,7 +442,7 @@ struct atl2_hw {
 struct atl2_ring_header {
     /* pointer to the descriptor ring memory */
     void *desc;
-    /* physical adress of the descriptor ring */
+    /* physical address of the descriptor ring */
     dma_addr_t dma;
     /* length of descriptor ring in bytes */
     unsigned int size;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/atlx/atlx.c linux-libre-2.6.34-gnu1/drivers/net/atlx/atlx.c
--- linux-libre-2.6.33-gnu1/drivers/net/atlx/atlx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/atlx/atlx.c	2010-05-16 17:17:36.000000000 -0400
@@ -144,7 +144,7 @@ static void atlx_set_multi(struct net_de
 	iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2));
 
 	/* compute mc addresses' hash value ,and put it into hash table */
-	for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
+	netdev_for_each_mc_addr(mc_ptr, netdev) {
 		hash_value = atlx_hash_mc_addr(hw, mc_ptr->dmi_addr);
 		atlx_hash_set(hw, hash_value);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/atp.c linux-libre-2.6.34-gnu1/drivers/net/atp.c
--- linux-libre-2.6.33-gnu1/drivers/net/atp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/atp.c	2010-05-16 17:17:36.000000000 -0400
@@ -129,7 +129,6 @@ static int xcvr[NUM_UNITS]; 			/* The da
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -861,7 +860,7 @@ static void set_rx_mode_8002(struct net_
 	struct net_local *lp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 
-	if (dev->mc_count > 0 || (dev->flags & (IFF_ALLMULTI|IFF_PROMISC)))
+	if (!netdev_mc_empty(dev) || (dev->flags & (IFF_ALLMULTI|IFF_PROMISC)))
 		lp->addr_mode = CMR2h_PROMISC;
 	else
 		lp->addr_mode = CMR2h_Normal;
@@ -877,7 +876,8 @@ static void set_rx_mode_8012(struct net_
 
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		new_mode = CMR2h_PROMISC;
-	} else if ((dev->mc_count > 1000)  ||  (dev->flags & IFF_ALLMULTI)) {
+	} else if ((netdev_mc_count(dev) > 1000) ||
+		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter perfectly -- accept all multicasts. */
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		new_mode = CMR2h_Normal;
@@ -885,9 +885,7 @@ static void set_rx_mode_8012(struct net_
 		struct dev_mc_list *mclist;
 
 		memset(mc_filter, 0, sizeof(mc_filter));
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-			 i++, mclist = mclist->next)
-		{
+		netdev_for_each_mc_addr(mclist, dev) {
 			int filterbit = ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f;
 			mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
 		}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/au1000_eth.c linux-libre-2.6.34-gnu1/drivers/net/au1000_eth.c
--- linux-libre-2.6.33-gnu1/drivers/net/au1000_eth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/au1000_eth.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,6 +55,7 @@
 #include <linux/delay.h>
 #include <linux/crc32.h>
 #include <linux/phy.h>
+#include <linux/platform_device.h>
 
 #include <asm/cpu.h>
 #include <asm/mipsregs.h>
@@ -63,6 +64,7 @@
 #include <asm/processor.h>
 
 #include <au1000.h>
+#include <au1xxx_eth.h>
 #include <prom.h>
 
 #include "au1000_eth.h"
@@ -112,15 +114,15 @@ struct au1000_private *au_macs[NUM_ETH_I
  *
  * PHY detection algorithm
  *
- * If AU1XXX_PHY_STATIC_CONFIG is undefined, the PHY setup is
+ * If phy_static_config is undefined, the PHY setup is
  * autodetected:
  *
  * mii_probe() first searches the current MAC's MII bus for a PHY,
- * selecting the first (or last, if AU1XXX_PHY_SEARCH_HIGHEST_ADDR is
+ * selecting the first (or last, if phy_search_highest_addr is
  * defined) PHY address not already claimed by another netdev.
  *
  * If nothing was found that way when searching for the 2nd ethernet
- * controller's PHY and AU1XXX_PHY1_SEARCH_ON_MAC0 is defined, then
+ * controller's PHY and phy1_search_mac0 is defined, then
  * the first MII bus is searched as well for an unclaimed PHY; this is
  * needed in case of a dual-PHY accessible only through the MAC0's MII
  * bus.
@@ -129,9 +131,7 @@ struct au1000_private *au_macs[NUM_ETH_I
  * controller is not registered to the network subsystem.
  */
 
-/* autodetection defaults */
-#undef  AU1XXX_PHY_SEARCH_HIGHEST_ADDR
-#define AU1XXX_PHY1_SEARCH_ON_MAC0
+/* autodetection defaults: phy1_search_mac0 */
 
 /* static PHY setup
  *
@@ -148,29 +148,6 @@ struct au1000_private *au_macs[NUM_ETH_I
  * specific irq-map
  */
 
-#if defined(CONFIG_MIPS_BOSPORUS)
-/*
- * Micrel/Kendin 5 port switch attached to MAC0,
- * MAC0 is associated with PHY address 5 (== WAN port)
- * MAC1 is not associated with any PHY, since it's connected directly
- * to the switch.
- * no interrupts are used
- */
-# define AU1XXX_PHY_STATIC_CONFIG
-
-# define AU1XXX_PHY0_ADDR  5
-# define AU1XXX_PHY0_BUSID 0
-#  undef AU1XXX_PHY0_IRQ
-
-#  undef AU1XXX_PHY1_ADDR
-#  undef AU1XXX_PHY1_BUSID
-#  undef AU1XXX_PHY1_IRQ
-#endif
-
-#if defined(AU1XXX_PHY0_BUSID) && (AU1XXX_PHY0_BUSID > 0)
-# 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;
@@ -390,67 +367,55 @@ static int mii_probe (struct net_device
 	struct au1000_private *const aup = netdev_priv(dev);
 	struct phy_device *phydev = NULL;
 
-#if defined(AU1XXX_PHY_STATIC_CONFIG)
-	BUG_ON(aup->mac_id < 0 || aup->mac_id > 1);
+	if (aup->phy_static_config) {
+		BUG_ON(aup->mac_id < 0 || aup->mac_id > 1);
 
-	if(aup->mac_id == 0) { /* get PHY0 */
-# if defined(AU1XXX_PHY0_ADDR)
-		phydev = au_macs[AU1XXX_PHY0_BUSID]->mii_bus->phy_map[AU1XXX_PHY0_ADDR];
-# else
-		printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
-			dev->name);
-		return 0;
-# endif /* defined(AU1XXX_PHY0_ADDR) */
-	} else if (aup->mac_id == 1) { /* get PHY1 */
-# if defined(AU1XXX_PHY1_ADDR)
-		phydev = au_macs[AU1XXX_PHY1_BUSID]->mii_bus->phy_map[AU1XXX_PHY1_ADDR];
-# else
-		printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
-			dev->name);
+		if (aup->phy_addr)
+			phydev = aup->mii_bus->phy_map[aup->phy_addr];
+		else
+			printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
+				dev->name);
 		return 0;
-# endif /* defined(AU1XXX_PHY1_ADDR) */
-	}
-
-#else /* defined(AU1XXX_PHY_STATIC_CONFIG) */
-	int phy_addr;
+	} else {
+		int phy_addr;
 
-	/* find the first (lowest address) PHY on the current MAC's MII bus */
-	for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
-		if (aup->mii_bus->phy_map[phy_addr]) {
-			phydev = aup->mii_bus->phy_map[phy_addr];
-# if !defined(AU1XXX_PHY_SEARCH_HIGHEST_ADDR)
-			break; /* break out with first one found */
-# endif
-		}
+		/* find the first (lowest address) PHY on the current MAC's MII bus */
+		for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
+			if (aup->mii_bus->phy_map[phy_addr]) {
+				phydev = aup->mii_bus->phy_map[phy_addr];
+				if (!aup->phy_search_highest_addr)
+					break; /* break out with first one found */
+			}
 
-# if defined(AU1XXX_PHY1_SEARCH_ON_MAC0)
-	/* try harder to find a PHY */
-	if (!phydev && (aup->mac_id == 1)) {
-		/* no PHY found, maybe we have a dual PHY? */
-		printk (KERN_INFO DRV_NAME ": no PHY found on MAC1, "
-			"let's see if it's attached to MAC0...\n");
+		if (aup->phy1_search_mac0) {
+			/* try harder to find a PHY */
+			if (!phydev && (aup->mac_id == 1)) {
+				/* no PHY found, maybe we have a dual PHY? */
+				printk (KERN_INFO DRV_NAME ": no PHY found on MAC1, "
+					"let's see if it's attached to MAC0...\n");
 
-		BUG_ON(!au_macs[0]);
+				/* find the first (lowest address) non-attached PHY on
+				 * the MAC0 MII bus */
+				for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+					struct phy_device *const tmp_phydev =
+							aup->mii_bus->phy_map[phy_addr];
 
-		/* find the first (lowest address) non-attached PHY on
-		 * the MAC0 MII bus */
-		for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
-			struct phy_device *const tmp_phydev =
-				au_macs[0]->mii_bus->phy_map[phy_addr];
+					if (aup->mac_id == 1)
+						break;
 
-			if (!tmp_phydev)
-				continue; /* no PHY here... */
+					if (!tmp_phydev)
+						continue; /* no PHY here... */
 
-			if (tmp_phydev->attached_dev)
-				continue; /* already claimed by MAC0 */
+					if (tmp_phydev->attached_dev)
+						continue; /* already claimed by MAC0 */
 
-			phydev = tmp_phydev;
-			break; /* found it */
+					phydev = tmp_phydev;
+					break; /* found it */
+				}
+			}
 		}
 	}
-# endif /* defined(AU1XXX_PHY1_SEARCH_OTHER_BUS) */
 
-#endif /* defined(AU1XXX_PHY_STATIC_CONFIG) */
 	if (!phydev) {
 		printk (KERN_ERR DRV_NAME ":%s: no PHY found\n", dev->name);
 		return -1;
@@ -578,31 +543,6 @@ setup_hw_rings(struct au1000_private *au
 	}
 }
 
-static struct {
-	u32 base_addr;
-	u32 macen_addr;
-	int irq;
-	struct net_device *dev;
-} iflist[2] = {
-#ifdef CONFIG_SOC_AU1000
-	{AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT},
-	{AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT}
-#endif
-#ifdef CONFIG_SOC_AU1100
-	{AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT}
-#endif
-#ifdef CONFIG_SOC_AU1500
-	{AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT},
-	{AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT}
-#endif
-#ifdef CONFIG_SOC_AU1550
-	{AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT},
-	{AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT}
-#endif
-};
-
-static int num_ifs;
-
 /*
  * ethtool operations
  */
@@ -711,7 +651,6 @@ static int au1000_init(struct net_device
 
 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++;
@@ -969,7 +908,7 @@ static netdev_tx_t au1000_tx(struct sk_b
 	}
 
 	pDB = aup->tx_db_inuse[aup->tx_head];
-	skb_copy_from_linear_data(skb, pDB->vaddr, skb->len);
+	skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len);
 	if (skb->len < ETH_ZLEN) {
 		for (i=skb->len; i<ETH_ZLEN; i++) {
 			((char *)pDB->vaddr)[i] = 0;
@@ -1013,21 +952,18 @@ static void au1000_multicast_list(struct
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		aup->mac->control |= MAC_PROMISCUOUS;
 	} else if ((dev->flags & IFF_ALLMULTI)  ||
-			   dev->mc_count > MULTICAST_FILTER_LIMIT) {
+			   netdev_mc_count(dev) > MULTICAST_FILTER_LIMIT) {
 		aup->mac->control |= MAC_PASS_ALL_MULTI;
 		aup->mac->control &= ~MAC_PROMISCUOUS;
 		printk(KERN_INFO "%s: Pass all multicast\n", dev->name);
 	} else {
-		int i;
 		struct dev_mc_list *mclist;
 		u32 mc_filter[2];	/* Multicast hash filter */
 
 		mc_filter[1] = mc_filter[0] = 0;
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-			 i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev)
 			set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26,
 					(long *)mc_filter);
-		}
 		aup->mac->multi_hash_high = mc_filter[1];
 		aup->mac->multi_hash_low = mc_filter[0];
 		aup->mac->control &= ~MAC_PROMISCUOUS;
@@ -1058,53 +994,59 @@ static const struct net_device_ops au100
 	.ndo_change_mtu		= eth_change_mtu,
 };
 
-static struct net_device * au1000_probe(int port_num)
+static int __devinit au1000_probe(struct platform_device *pdev)
 {
 	static unsigned version_printed = 0;
 	struct au1000_private *aup = NULL;
+	struct au1000_eth_platform_data *pd;
 	struct net_device *dev = NULL;
 	db_dest_t *pDB, *pDBfree;
+	int irq, i, err = 0;
+	struct resource *base, *macen;
 	char ethaddr[6];
-	int irq, i, err;
-	u32 base, macen;
 
-	if (port_num >= NUM_ETH_INTERFACES)
-		return NULL;
+	base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!base) {
+		printk(KERN_ERR DRV_NAME ": failed to retrieve base register\n");
+		err = -ENODEV;
+		goto out;
+	}
 
-	base  = CPHYSADDR(iflist[port_num].base_addr );
-	macen = CPHYSADDR(iflist[port_num].macen_addr);
-	irq = iflist[port_num].irq;
+	macen = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!macen) {
+		printk(KERN_ERR DRV_NAME ": failed to retrieve MAC Enable register\n");
+		err = -ENODEV;
+		goto out;
+	}
 
-	if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") ||
-	    !request_mem_region(macen, 4, "Au1x00 ENET"))
-		return NULL;
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		printk(KERN_ERR DRV_NAME ": failed to retrieve IRQ\n");
+		err = -ENODEV;
+		goto out;
+	}
 
-	if (version_printed++ == 0)
-		printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
+	if (!request_mem_region(base->start, resource_size(base), pdev->name)) {
+		printk(KERN_ERR DRV_NAME ": failed to request memory region for base registers\n");
+		err = -ENXIO;
+		goto out;
+	}
+
+	if (!request_mem_region(macen->start, resource_size(macen), pdev->name)) {
+		printk(KERN_ERR DRV_NAME ": failed to request memory region for MAC enable register\n");
+		err = -ENXIO;
+		goto err_request;
+	}
 
 	dev = alloc_etherdev(sizeof(struct au1000_private));
 	if (!dev) {
 		printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME);
-		return NULL;
-	}
-
-	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;
-
-	err = register_netdev(dev);
-	if (err != 0) {
-		printk(KERN_ERR "%s: Cannot register net device, error %d\n",
-				DRV_NAME, err);
-		free_netdev(dev);
-		return NULL;
+		err = -ENOMEM;
+		goto err_alloc;
 	}
 
-	printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
-		dev->name, base, irq);
-
+	SET_NETDEV_DEV(dev, &pdev->dev);
+	platform_set_drvdata(pdev, dev);
 	aup = netdev_priv(dev);
 
 	spin_lock_init(&aup->lock);
@@ -1115,21 +1057,29 @@ static struct net_device * au1000_probe(
 						(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;
+		printk(KERN_ERR DRV_NAME ": failed to allocate data buffers\n");
+		err = -ENOMEM;
+		goto err_vaddr;
 	}
 
 	/* aup->mac is the base address of the MAC's registers */
-	aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr;
+	aup->mac = (volatile mac_reg_t *)ioremap_nocache(base->start, resource_size(base));
+	if (!aup->mac) {
+		printk(KERN_ERR DRV_NAME ": failed to ioremap MAC registers\n");
+		err = -ENXIO;
+		goto err_remap1;
+	}
 
-	/* 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;
+        /* Setup some variables for quick register address access */
+	aup->enable = (volatile u32 *)ioremap_nocache(macen->start, resource_size(macen));
+	if (!aup->enable) {
+		printk(KERN_ERR DRV_NAME ": failed to ioremap MAC enable register\n");
+		err = -ENXIO;
+		goto err_remap2;
+	}
+	aup->mac_id = pdev->id;
 
-	if (port_num == 0) {
+	if (pdev->id == 0) {
 		if (prom_get_ethernet_addr(ethaddr) == 0)
 			memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
 		else {
@@ -1139,7 +1089,7 @@ static struct net_device * au1000_probe(
 		}
 
 		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
-	} else if (port_num == 1)
+	} else if (pdev->id == 1)
 		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
 
 	/*
@@ -1147,14 +1097,37 @@ static struct net_device * au1000_probe(
 	 * 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;
+	dev->dev_addr[5] += pdev->id;
 
 	*aup->enable = 0;
 	aup->mac_enabled = 0;
 
+	pd = pdev->dev.platform_data;
+	if (!pd) {
+		printk(KERN_INFO DRV_NAME ": no platform_data passed, PHY search on MAC0\n");
+		aup->phy1_search_mac0 = 1;
+	} else {
+		aup->phy_static_config = pd->phy_static_config;
+		aup->phy_search_highest_addr = pd->phy_search_highest_addr;
+		aup->phy1_search_mac0 = pd->phy1_search_mac0;
+		aup->phy_addr = pd->phy_addr;
+		aup->phy_busid = pd->phy_busid;
+		aup->phy_irq = pd->phy_irq;
+	}
+
+	if (aup->phy_busid && aup->phy_busid > 0) {
+		printk(KERN_ERR DRV_NAME ": MAC0-associated PHY attached 2nd MACs MII"
+				"bus not supported yet\n");
+		err = -ENODEV;
+		goto err_mdiobus_alloc;
+	}
+
 	aup->mii_bus = mdiobus_alloc();
-	if (aup->mii_bus == NULL)
-		goto err_out;
+	if (aup->mii_bus == NULL) {
+		printk(KERN_ERR DRV_NAME ": failed to allocate mdiobus structure\n");
+		err = -ENOMEM;
+		goto err_mdiobus_alloc;
+	}
 
 	aup->mii_bus->priv = dev;
 	aup->mii_bus->read = au1000_mdiobus_read;
@@ -1168,24 +1141,20 @@ static struct net_device * au1000_probe(
 
 	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 (aup->phy_static_config)
+		if (aup->phy_irq && aup->phy_busid == aup->mac_id)
+			aup->mii_bus->irq[aup->phy_addr] = aup->phy_irq;
 
-	if (mii_probe(dev) != 0) {
-		goto err_out;
+	err = mdiobus_register(aup->mii_bus);
+	if (err) {
+		printk(KERN_ERR DRV_NAME " failed to register MDIO bus\n");
+		goto err_mdiobus_reg;
 	}
 
+	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;
@@ -1216,19 +1185,35 @@ static struct net_device * au1000_probe(
 		aup->tx_db_inuse[i] = pDB;
 	}
 
+	dev->base_addr = base->start;
+	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 = register_netdev(dev);
+	if (err) {
+		printk(KERN_ERR DRV_NAME "%s: Cannot register net device, aborting.\n",
+					dev->name);
+		goto err_out;
+	}
+
+	printk("%s: Au1xx0 Ethernet found at 0x%lx, irq %d\n",
+			dev->name, (unsigned long)base->start, irq);
+	if (version_printed++ == 0)
+		printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
+
+	return 0;
 
 err_out:
-	if (aup->mii_bus != NULL) {
+	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.*/
@@ -1242,67 +1227,84 @@ err_out:
 		if (aup->tx_db_inuse[i])
 			ReleaseDB(aup, aup->tx_db_inuse[i]);
 	}
+err_mdiobus_reg:
+	mdiobus_free(aup->mii_bus);
+err_mdiobus_alloc:
+	iounmap(aup->enable);
+err_remap2:
+	iounmap(aup->mac);
+err_remap1:
 	dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
 			     (void *)aup->vaddr, aup->dma_addr);
-	unregister_netdev(dev);
+err_vaddr:
 	free_netdev(dev);
-	release_mem_region( base, MAC_IOSIZE);
-	release_mem_region(macen, 4);
-	return NULL;
+err_alloc:
+	release_mem_region(macen->start, resource_size(macen));
+err_request:
+	release_mem_region(base->start, resource_size(base));
+out:
+	return err;
 }
 
-/*
- * 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)
+static int __devexit au1000_remove(struct platform_device *pdev)
 {
-	int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
-	struct net_device *dev;
-	int i, found_one = 0;
+	struct net_device *dev = platform_get_drvdata(pdev);
+	struct au1000_private *aup = netdev_priv(dev);
+	int i;
+	struct resource *base, *macen;
 
-	num_ifs = NUM_ETH_INTERFACES - ni;
+	platform_set_drvdata(pdev, NULL);
+
+	unregister_netdev(dev);
+	mdiobus_unregister(aup->mii_bus);
+	mdiobus_free(aup->mii_bus);
+
+	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);
+
+	iounmap(aup->mac);
+	iounmap(aup->enable);
+
+	base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(base->start, resource_size(base));
+
+	macen = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	release_mem_region(macen->start, resource_size(macen));
+
+	free_netdev(dev);
 
-	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)
+static struct platform_driver au1000_eth_driver = {
+	.probe  = au1000_probe,
+	.remove = __devexit_p(au1000_remove),
+	.driver = {
+		.name   = "au1000-eth",
+		.owner  = THIS_MODULE,
+	},
+};
+MODULE_ALIAS("platform:au1000-eth");
+
+
+static int __init au1000_init_module(void)
 {
-	int i, j;
-	struct net_device *dev;
-	struct au1000_private *aup;
+	return platform_driver_register(&au1000_eth_driver);
+}
 
-	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 __exit au1000_exit_module(void)
+{
+	platform_driver_unregister(&au1000_eth_driver);
 }
 
 module_init(au1000_init_module);
-module_exit(au1000_cleanup_module);
+module_exit(au1000_exit_module);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/au1000_eth.h linux-libre-2.6.34-gnu1/drivers/net/au1000_eth.h
--- linux-libre-2.6.33-gnu1/drivers/net/au1000_eth.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/au1000_eth.h	2010-05-16 17:17:36.000000000 -0400
@@ -108,6 +108,15 @@ struct au1000_private {
 	struct phy_device *phy_dev;
 	struct mii_bus *mii_bus;
 
+	/* PHY configuration */
+	int phy_static_config;
+	int phy_search_highest_addr;
+	int phy1_search_mac0;
+
+	int phy_addr;
+	int phy_busid;
+	int phy_irq;
+
 	/* These variables are just for quick access to certain regs addresses. */
 	volatile mac_reg_t *mac;  /* mac registers                      */
 	volatile u32 *enable;     /* address of MAC Enable Register     */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ax88796.c linux-libre-2.6.34-gnu1/drivers/net/ax88796.c
--- linux-libre-2.6.33-gnu1/drivers/net/ax88796.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ax88796.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/eeprom_93cx6.h>
+#include <linux/slab.h>
 
 #include <net/ax88796.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/b44.c linux-libre-2.6.34-gnu1/drivers/net/b44.c
--- linux-libre-2.6.33-gnu1/drivers/net/b44.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/b44.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,8 @@
  * Distribute under GPL.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -25,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 #include <linux/ssb/ssb.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -34,7 +37,6 @@
 #include "b44.h"
 
 #define DRV_MODULE_NAME		"b44"
-#define PFX DRV_MODULE_NAME	": "
 #define DRV_MODULE_VERSION	"2.0"
 
 #define B44_DEF_MSG_ENABLE	  \
@@ -102,7 +104,7 @@ MODULE_PARM_DESC(b44_debug, "B44 bitmapp
 
 
 #ifdef CONFIG_B44_PCI
-static const struct pci_device_id b44_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(b44_pci_tbl) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B0) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B1) },
@@ -189,11 +191,10 @@ static int b44_wait_bit(struct b44 *bp,
 		udelay(10);
 	}
 	if (i == timeout) {
-		printk(KERN_ERR PFX "%s: BUG!  Timeout waiting for bit %08x of register "
-		       "%lx to %s.\n",
-		       bp->dev->name,
-		       bit, reg,
-		       (clear ? "clear" : "set"));
+		if (net_ratelimit())
+			netdev_err(bp->dev, "BUG!  Timeout waiting for bit %08x of register %lx to %s\n",
+				   bit, reg, clear ? "clear" : "set");
+
 		return -ENODEV;
 	}
 	return 0;
@@ -333,13 +334,12 @@ static int b44_phy_reset(struct b44 *bp)
 	err = b44_readphy(bp, MII_BMCR, &val);
 	if (!err) {
 		if (val & BMCR_RESET) {
-			printk(KERN_ERR PFX "%s: PHY Reset would not complete.\n",
-			       bp->dev->name);
+			netdev_err(bp->dev, "PHY Reset would not complete\n");
 			err = -ENODEV;
 		}
 	}
 
-	return 0;
+	return err;
 }
 
 static void __b44_set_flow_ctrl(struct b44 *bp, u32 pause_flags)
@@ -413,7 +413,7 @@ static void b44_wap54g10_workaround(stru
 	}
 	return;
 error:
-	printk(KERN_WARNING PFX "PHY: cannot reset MII transceiver isolate bit.\n");
+	pr_warning("PHY: cannot reset MII transceiver isolate bit\n");
 }
 #else
 static inline void b44_wap54g10_workaround(struct b44 *bp)
@@ -506,18 +506,15 @@ static void b44_stats_update(struct b44
 static void b44_link_report(struct b44 *bp)
 {
 	if (!netif_carrier_ok(bp->dev)) {
-		printk(KERN_INFO PFX "%s: Link is down.\n", bp->dev->name);
+		netdev_info(bp->dev, "Link is down\n");
 	} else {
-		printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n",
-		       bp->dev->name,
-		       (bp->flags & B44_FLAG_100_BASE_T) ? 100 : 10,
-		       (bp->flags & B44_FLAG_FULL_DUPLEX) ? "full" : "half");
+		netdev_info(bp->dev, "Link is up at %d Mbps, %s duplex\n",
+			    (bp->flags & B44_FLAG_100_BASE_T) ? 100 : 10,
+			    (bp->flags & B44_FLAG_FULL_DUPLEX) ? "full" : "half");
 
-		printk(KERN_INFO PFX "%s: Flow control is %s for TX and "
-		       "%s for RX.\n",
-		       bp->dev->name,
-		       (bp->flags & B44_FLAG_TX_PAUSE) ? "on" : "off",
-		       (bp->flags & B44_FLAG_RX_PAUSE) ? "on" : "off");
+		netdev_info(bp->dev, "Flow control is %s for TX and %s for RX\n",
+			    (bp->flags & B44_FLAG_TX_PAUSE) ? "on" : "off",
+			    (bp->flags & B44_FLAG_RX_PAUSE) ? "on" : "off");
 	}
 }
 
@@ -576,11 +573,9 @@ static void b44_check_phy(struct b44 *bp
 		}
 
 		if (bmsr & BMSR_RFAULT)
-			printk(KERN_WARNING PFX "%s: Remote fault detected in PHY\n",
-			       bp->dev->name);
+			netdev_warn(bp->dev, "Remote fault detected in PHY\n");
 		if (bmsr & BMSR_JCD)
-			printk(KERN_WARNING PFX "%s: Jabber detected in PHY\n",
-			       bp->dev->name);
+			netdev_warn(bp->dev, "Jabber detected in PHY\n");
 	}
 }
 
@@ -815,7 +810,7 @@ static int b44_rx(struct b44 *bp, int bu
 			struct sk_buff *copy_skb;
 
 			b44_recycle_rx(bp, cons, bp->rx_prod);
-			copy_skb = dev_alloc_skb(len + 2);
+			copy_skb = netdev_alloc_skb(bp->dev, len + 2);
 			if (copy_skb == NULL)
 				goto drop_it_no_recycle;
 
@@ -901,7 +896,7 @@ static irqreturn_t b44_interrupt(int irq
 		handled = 1;
 
 		if (unlikely(!netif_running(dev))) {
-			printk(KERN_INFO "%s: late interrupt.\n", dev->name);
+			netdev_info(dev, "late interrupt\n");
 			goto irq_ack;
 		}
 
@@ -926,8 +921,7 @@ static void b44_tx_timeout(struct net_de
 {
 	struct b44 *bp = netdev_priv(dev);
 
-	printk(KERN_ERR PFX "%s: transmit timed out, resetting\n",
-	       dev->name);
+	netdev_err(dev, "transmit timed out, resetting\n");
 
 	spin_lock_irq(&bp->lock);
 
@@ -956,8 +950,7 @@ static netdev_tx_t b44_start_xmit(struct
 	/* This is a hard error, log it. */
 	if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) {
 		netif_stop_queue(dev);
-		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
-		       dev->name);
+		netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
 		goto err_out;
 	}
 
@@ -1333,7 +1326,7 @@ static void b44_halt(struct b44 *bp)
 	/* reset PHY */
 	b44_phy_reset(bp);
 	/* power down PHY */
-	printk(KERN_INFO PFX "%s: powering down PHY\n", bp->dev->name);
+	netdev_info(bp->dev, "powering down PHY\n");
 	bw32(bp, B44_MAC_CTRL, MAC_CTRL_PHY_PDOWN);
 	/* now reset the chip, but without enabling the MAC&PHY
 	 * part of it. This has to be done _after_ we shut down the PHY */
@@ -1524,7 +1517,7 @@ static void b44_setup_pseudo_magicp(stru
 
 	pwol_pattern = kzalloc(B44_PATTERN_SIZE, GFP_KERNEL);
 	if (!pwol_pattern) {
-		printk(KERN_ERR PFX "Memory not available for WOL\n");
+		pr_err("Memory not available for WOL\n");
 		return;
 	}
 
@@ -1691,10 +1684,12 @@ static int __b44_load_mcast(struct b44 *
 	struct dev_mc_list *mclist;
 	int i, num_ents;
 
-	num_ents = min_t(int, dev->mc_count, B44_MCAST_TABLE_SIZE);
-	mclist = dev->mc_list;
-	for (i = 0; mclist && i < num_ents; i++, mclist = mclist->next) {
-		__b44_cam_write(bp, mclist->dmi_addr, i + 1);
+	num_ents = min_t(int, netdev_mc_count(dev), B44_MCAST_TABLE_SIZE);
+	i = 0;
+	netdev_for_each_mc_addr(mclist, dev) {
+		if (i == num_ents)
+			break;
+		__b44_cam_write(bp, mclist->dmi_addr, i++ + 1);
 	}
 	return i+1;
 }
@@ -1716,7 +1711,7 @@ static void __b44_set_rx_mode(struct net
 		__b44_set_mac_addr(bp);
 
 		if ((dev->flags & IFF_ALLMULTI) ||
-		    (dev->mc_count > B44_MCAST_TABLE_SIZE))
+		    (netdev_mc_count(dev) > B44_MCAST_TABLE_SIZE))
 			val |= RXCONFIG_ALLMULTI;
 		else
 			i = __b44_load_mcast(bp, dev);
@@ -2097,7 +2092,7 @@ static int __devinit b44_get_invariants(
 	memcpy(bp->dev->dev_addr, addr, 6);
 
 	if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){
-		printk(KERN_ERR PFX "Invalid MAC address found in EEPROM\n");
+		pr_err("Invalid MAC address found in EEPROM\n");
 		return -EINVAL;
 	}
 
@@ -2142,12 +2137,12 @@ static int __devinit b44_init_one(struct
 	instance++;
 
 	if (b44_version_printed++ == 0)
-		printk(KERN_INFO "%s", version);
+		pr_info("%s", version);
 
 
 	dev = alloc_etherdev(sizeof(*bp));
 	if (!dev) {
-		dev_err(sdev->dev, "Etherdev alloc failed, aborting.\n");
+		dev_err(sdev->dev, "Etherdev alloc failed, aborting\n");
 		err = -ENOMEM;
 		goto out;
 	}
@@ -2186,13 +2181,13 @@ static int __devinit b44_init_one(struct
 	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");
+			"Required 30BIT DMA mask unsupported by the system\n");
 		goto err_out_powerdown;
 	}
 	err = b44_get_invariants(bp);
 	if (err) {
 		dev_err(sdev->dev,
-			"Problem fetching invariants of chip, aborting.\n");
+			"Problem fetching invariants of chip, aborting\n");
 		goto err_out_powerdown;
 	}
 
@@ -2212,7 +2207,7 @@ static int __devinit b44_init_one(struct
 
 	err = register_netdev(dev);
 	if (err) {
-		dev_err(sdev->dev, "Cannot register net device, aborting.\n");
+		dev_err(sdev->dev, "Cannot register net device, aborting\n");
 		goto err_out_powerdown;
 	}
 
@@ -2223,8 +2218,12 @@ static int __devinit b44_init_one(struct
 	 */
 	b44_chip_reset(bp, B44_CHIP_RESET_FULL);
 
-	printk(KERN_INFO "%s: Broadcom 44xx/47xx 10/100BaseT Ethernet %pM\n",
-	       dev->name, dev->dev_addr);
+	/* do a phy reset to test if there is an active phy */
+	if (b44_phy_reset(bp) < 0)
+		bp->phy_addr = B44_PHY_ADDR_NO_PHY;
+
+	netdev_info(dev, "Broadcom 44xx/47xx 10/100BaseT Ethernet %pM\n",
+		    dev->dev_addr);
 
 	return 0;
 
@@ -2297,7 +2296,7 @@ static int b44_resume(struct ssb_device
 
 	rc = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev);
 	if (rc) {
-		printk(KERN_ERR PFX "%s: request_irq failed\n", dev->name);
+		netdev_err(dev, "request_irq failed\n");
 		return rc;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/bcm63xx_enet.c linux-libre-2.6.34-gnu1/drivers/net/bcm63xx_enet.c
--- linux-libre-2.6.33-gnu1/drivers/net/bcm63xx_enet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/bcm63xx_enet.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/ethtool.h>
 #include <linux/crc32.h>
@@ -619,7 +620,7 @@ static void bcm_enet_set_multicast_list(
 
 	/* only 3 perfect match registers left, first one is used for
 	 * own mac address */
-	if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 3)
+	if ((dev->flags & IFF_ALLMULTI) || netdev_mc_count(dev) > 3)
 		val |= ENET_RXCFG_ALLMCAST_MASK;
 	else
 		val &= ~ENET_RXCFG_ALLMCAST_MASK;
@@ -631,16 +632,13 @@ static void bcm_enet_set_multicast_list(
 		return;
 	}
 
-	for (i = 0, mc_list = dev->mc_list;
-	     (mc_list != NULL) && (i < dev->mc_count) && (i < 3);
-	     i++, mc_list = mc_list->next) {
+	i = 0;
+	netdev_for_each_mc_addr(mc_list, dev) {
 		u8 *dmi_addr;
 		u32 tmp;
 
-		/* filter non ethernet address */
-		if (mc_list->dmi_addrlen != 6)
-			continue;
-
+		if (i == 3)
+			break;
 		/* update perfect match registers */
 		dmi_addr = mc_list->dmi_addr;
 		tmp = (dmi_addr[2] << 24) | (dmi_addr[3] << 16) |
@@ -649,7 +647,7 @@ static void bcm_enet_set_multicast_list(
 
 		tmp = (dmi_addr[0] << 8 | dmi_addr[1]);
 		tmp |= ENET_PMH_DATAVALID_MASK;
-		enet_writel(priv, tmp, ENET_PMH_REG(i + 1));
+		enet_writel(priv, tmp, ENET_PMH_REG(i++ + 1));
 	}
 
 	for (; i < 3; i++) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/benet/be_cmds.c linux-libre-2.6.34-gnu1/drivers/net/benet/be_cmds.c
--- linux-libre-2.6.33-gnu1/drivers/net/benet/be_cmds.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/benet/be_cmds.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -104,10 +104,26 @@ static struct be_mcc_compl *be_mcc_compl
 	return NULL;
 }
 
-int be_process_mcc(struct be_adapter *adapter)
+void be_async_mcc_enable(struct be_adapter *adapter)
+{
+	spin_lock_bh(&adapter->mcc_cq_lock);
+
+	be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, 0);
+	adapter->mcc_obj.rearm_cq = true;
+
+	spin_unlock_bh(&adapter->mcc_cq_lock);
+}
+
+void be_async_mcc_disable(struct be_adapter *adapter)
+{
+	adapter->mcc_obj.rearm_cq = false;
+}
+
+int be_process_mcc(struct be_adapter *adapter, int *status)
 {
 	struct be_mcc_compl *compl;
-	int num = 0, status = 0;
+	int num = 0;
+	struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
 
 	spin_lock_bh(&adapter->mcc_cq_lock);
 	while ((compl = be_mcc_compl_get(adapter))) {
@@ -119,31 +135,31 @@ int be_process_mcc(struct be_adapter *ad
 			be_async_link_state_process(adapter,
 				(struct be_async_event_link_state *) compl);
 		} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
-				status = be_mcc_compl_process(adapter, compl);
-				atomic_dec(&adapter->mcc_obj.q.used);
+				*status = be_mcc_compl_process(adapter, compl);
+				atomic_dec(&mcc_obj->q.used);
 		}
 		be_mcc_compl_use(compl);
 		num++;
 	}
 
-	if (num)
-		be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, num);
-
 	spin_unlock_bh(&adapter->mcc_cq_lock);
-	return status;
+	return num;
 }
 
 /* Wait till no more pending mcc requests are present */
 static int be_mcc_wait_compl(struct be_adapter *adapter)
 {
 #define mcc_timeout		120000 /* 12s timeout */
-	int i, status;
+	int i, num, status = 0;
+	struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
+
 	for (i = 0; i < mcc_timeout; i++) {
-		status = be_process_mcc(adapter);
-		if (status)
-			return status;
+		num = be_process_mcc(adapter, &status);
+		if (num)
+			be_cq_notify(adapter, mcc_obj->cq.id,
+				mcc_obj->rearm_cq, num);
 
-		if (atomic_read(&adapter->mcc_obj.q.used) == 0)
+		if (atomic_read(&mcc_obj->q.used) == 0)
 			break;
 		udelay(100);
 	}
@@ -151,7 +167,7 @@ static int be_mcc_wait_compl(struct be_a
 		dev_err(&adapter->pdev->dev, "mccq poll timed out\n");
 		return -1;
 	}
-	return 0;
+	return status;
 }
 
 /* Notify MCC requests and wait for completion */
@@ -167,7 +183,14 @@ static int be_mbox_db_ready_wait(struct
 	u32 ready;
 
 	do {
-		ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
+		ready = ioread32(db);
+		if (ready == 0xffffffff) {
+			dev_err(&adapter->pdev->dev,
+				"pci slot disconnected\n");
+			return -1;
+		}
+
+		ready &= MPU_MAILBOX_DB_RDY_MASK;
 		if (ready)
 			break;
 
@@ -198,6 +221,11 @@ static int be_mbox_notify_wait(struct be
 	struct be_mcc_mailbox *mbox = mbox_mem->va;
 	struct be_mcc_compl *compl = &mbox->compl;
 
+	/* wait for ready to be set */
+	status = be_mbox_db_ready_wait(adapter, db);
+	if (status != 0)
+		return status;
+
 	val |= MPU_MAILBOX_DB_HI_MASK;
 	/* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
 	val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
@@ -397,6 +425,9 @@ int be_cmd_fw_clean(struct be_adapter *a
 	u8 *wrb;
 	int status;
 
+	if (adapter->eeh_err)
+		return -EIO;
+
 	spin_lock(&adapter->mbox_lock);
 
 	wrb = (u8 *)wrb_from_mbox(adapter);
@@ -434,8 +465,6 @@ int be_cmd_eq_create(struct be_adapter *
 
 	req->num_pages =  cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
 
-	AMAP_SET_BITS(struct amap_eq_context, func, req->context,
-			be_pci_func(adapter));
 	AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
 	/* 4byte eqe*/
 	AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
@@ -598,7 +627,6 @@ int be_cmd_cq_create(struct be_adapter *
 	AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
 	AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
 	AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1);
-	AMAP_SET_BITS(struct amap_cq_context, func, ctxt, be_pci_func(adapter));
 	be_dws_cpu_to_le(ctxt, sizeof(req->context));
 
 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
@@ -645,9 +673,8 @@ int be_cmd_mccq_create(struct be_adapter
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 			OPCODE_COMMON_MCC_CREATE, sizeof(*req));
 
-	req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
+	req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
 
-	AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt, be_pci_func(adapter));
 	AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
 	AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
 		be_encoded_q_len(mccq->len));
@@ -696,8 +723,6 @@ int be_cmd_txq_create(struct be_adapter
 
 	AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt,
 		be_encoded_q_len(txq->len));
-	AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt,
-			be_pci_func(adapter));
 	AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1);
 	AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id);
 
@@ -769,6 +794,9 @@ int be_cmd_q_destroy(struct be_adapter *
 	u8 subsys = 0, opcode = 0;
 	int status;
 
+	if (adapter->eeh_err)
+		return -EIO;
+
 	spin_lock(&adapter->mbox_lock);
 
 	wrb = wrb_from_mbox(adapter);
@@ -857,6 +885,9 @@ int be_cmd_if_destroy(struct be_adapter
 	struct be_cmd_req_if_destroy *req;
 	int status;
 
+	if (adapter->eeh_err)
+		return -EIO;
+
 	spin_lock(&adapter->mbox_lock);
 
 	wrb = wrb_from_mbox(adapter);
@@ -1097,8 +1128,7 @@ err:
  * (mc == NULL) => multicast promiscous
  */
 int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
-		struct dev_mc_list *mc_list, u32 mc_count,
-		struct be_dma_mem *mem)
+		struct net_device *netdev, struct be_dma_mem *mem)
 {
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_mcast_mac_config *req = mem->va;
@@ -1125,13 +1155,14 @@ int be_cmd_multicast_set(struct be_adapt
 		OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req));
 
 	req->interface_id = if_id;
-	if (mc_list) {
+	if (netdev) {
 		int i;
 		struct dev_mc_list *mc;
 
-		req->num_mac = cpu_to_le16(mc_count);
+		req->num_mac = cpu_to_le16(netdev_mc_count(netdev));
 
-		for (mc = mc_list, i = 0; mc; mc = mc->next, i++)
+		i = 0;
+		netdev_for_each_mc_addr(mc, netdev)
 			memcpy(req->mac[i].byte, mc->dmi_addr, ETH_ALEN);
 	} else {
 		req->promiscuous = 1;
@@ -1375,7 +1406,7 @@ int be_cmd_write_flashrom(struct be_adap
 			u32 flash_type, u32 flash_opcode, u32 buf_size)
 {
 	struct be_mcc_wrb *wrb;
-	struct be_cmd_write_flashrom *req = cmd->va;
+	struct be_cmd_write_flashrom *req;
 	struct be_sge *sge;
 	int status;
 
@@ -1409,7 +1440,8 @@ err:
 	return status;
 }
 
-int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc)
+int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
+			 int offset)
 {
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_write_flashrom *req;
@@ -1430,10 +1462,10 @@ int be_cmd_get_flash_crc(struct be_adapt
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_READ_FLASHROM, sizeof(*req)+4);
 
-	req->params.op_type = cpu_to_le32(FLASHROM_TYPE_REDBOOT);
+	req->params.op_type = cpu_to_le32(IMG_TYPE_REDBOOT);
 	req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT);
-	req->params.offset = 0x3FFFC;
-	req->params.data_buf_size = 0x4;
+	req->params.offset = cpu_to_le32(offset);
+	req->params.data_buf_size = cpu_to_le32(0x4);
 
 	status = be_mcc_notify_wait(adapter);
 	if (!status)
@@ -1608,3 +1640,33 @@ err:
 	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
+
+extern int be_cmd_get_seeprom_data(struct be_adapter *adapter,
+				struct be_dma_mem *nonemb_cmd)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_seeprom_read *req;
+	struct be_sge *sge;
+	int status;
+
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	req = nonemb_cmd->va;
+	sge = nonembedded_sgl(wrb);
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
+			OPCODE_COMMON_SEEPROM_READ);
+
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+			OPCODE_COMMON_SEEPROM_READ, sizeof(*req));
+
+	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
+	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
+	sge->len = cpu_to_le32(nonemb_cmd->size);
+
+	status = be_mcc_notify_wait(adapter);
+
+	spin_unlock_bh(&adapter->mcc_lock);
+	return status;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/benet/be_cmds.h linux-libre-2.6.34-gnu1/drivers/net/benet/be_cmds.h
--- linux-libre-2.6.33-gnu1/drivers/net/benet/be_cmds.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/benet/be_cmds.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -124,6 +124,7 @@ struct be_mcc_mailbox {
 #define OPCODE_COMMON_CQ_CREATE				12
 #define OPCODE_COMMON_EQ_CREATE				13
 #define OPCODE_COMMON_MCC_CREATE        		21
+#define OPCODE_COMMON_SEEPROM_READ			30
 #define OPCODE_COMMON_NTWK_RX_FILTER    		34
 #define OPCODE_COMMON_GET_FW_VERSION			35
 #define OPCODE_COMMON_SET_FLOW_CONTROL			36
@@ -855,6 +856,19 @@ struct be_cmd_resp_ddrdma_test {
 	u8  rcv_buff[4096];
 };
 
+/*********************** SEEPROM Read ***********************/
+
+#define BE_READ_SEEPROM_LEN 1024
+struct be_cmd_req_seeprom_read {
+	struct be_cmd_req_hdr hdr;
+	u8 rsvd0[BE_READ_SEEPROM_LEN];
+};
+
+struct be_cmd_resp_seeprom_read {
+	struct be_cmd_req_hdr hdr;
+	u8 seeprom_data[BE_READ_SEEPROM_LEN];
+};
+
 extern int be_pci_fnum_get(struct be_adapter *adapter);
 extern int be_cmd_POST(struct be_adapter *adapter);
 extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
@@ -898,8 +912,7 @@ extern int be_cmd_vlan_config(struct be_
 extern int be_cmd_promiscuous_config(struct be_adapter *adapter,
 			u8 port_num, bool en);
 extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
-			struct dev_mc_list *mc_list, u32 mc_count,
-			struct be_dma_mem *mem);
+			struct net_device *netdev, struct be_dma_mem *mem);
 extern int be_cmd_set_flow_control(struct be_adapter *adapter,
 			u32 tx_fc, u32 rx_fc);
 extern int be_cmd_get_flow_control(struct be_adapter *adapter,
@@ -907,7 +920,7 @@ extern int be_cmd_get_flow_control(struc
 extern int be_cmd_query_fw_cfg(struct be_adapter *adapter,
 			u32 *port_num, u32 *cap);
 extern int be_cmd_reset_function(struct be_adapter *adapter);
-extern int be_process_mcc(struct be_adapter *adapter);
+extern int be_process_mcc(struct be_adapter *adapter, int *status);
 extern int be_cmd_set_beacon_state(struct be_adapter *adapter,
 			u8 port_num, u8 beacon, u8 status, u8 state);
 extern int be_cmd_get_beacon_state(struct be_adapter *adapter,
@@ -917,15 +930,21 @@ extern int be_cmd_read_port_type(struct
 extern int be_cmd_write_flashrom(struct be_adapter *adapter,
 			struct be_dma_mem *cmd, u32 flash_oper,
 			u32 flash_opcode, u32 buf_size);
-extern int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc);
+int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
+				int offset);
 extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
 				struct be_dma_mem *nonemb_cmd);
 extern int be_cmd_fw_init(struct be_adapter *adapter);
 extern int be_cmd_fw_clean(struct be_adapter *adapter);
+extern void be_async_mcc_enable(struct be_adapter *adapter);
+extern void be_async_mcc_disable(struct be_adapter *adapter);
 extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
 				u32 loopback_type, u32 pkt_size,
 				u32 num_pkts, u64 pattern);
 extern int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
 			u32 byte_cnt, struct be_dma_mem *cmd);
+extern int be_cmd_get_seeprom_data(struct be_adapter *adapter,
+				struct be_dma_mem *nonemb_cmd);
 extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
 				u8 loopback_type, u8 enable);
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/benet/be_ethtool.c linux-libre-2.6.34-gnu1/drivers/net/benet/be_ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/benet/be_ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/benet/be_ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -112,6 +112,7 @@ static const char et_self_tests[][ETH_GS
 	"PHY Loopback test",
 	"External Loopback test",
 	"DDR DMA test"
+	"Link test"
 };
 
 #define ETHTOOL_TESTS_NUM ARRAY_SIZE(et_self_tests)
@@ -489,7 +490,7 @@ be_test_ddr_dma(struct be_adapter *adapt
 {
 	int ret, i;
 	struct be_dma_mem ddrdma_cmd;
-	u64 pattern[2] = {0x5a5a5a5a5a5a5a5a, 0xa5a5a5a5a5a5a5a5};
+	u64 pattern[2] = {0x5a5a5a5a5a5a5a5aULL, 0xa5a5a5a5a5a5a5a5ULL};
 
 	ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test);
 	ddrdma_cmd.va = pci_alloc_consistent(adapter->pdev, ddrdma_cmd.size,
@@ -529,6 +530,9 @@ static void
 be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
+	bool link_up;
+	u8 mac_speed = 0;
+	u16 qos_link_speed = 0;
 
 	memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM);
 
@@ -545,12 +549,20 @@ be_self_test(struct net_device *netdev,
 						&data[2]) != 0) {
 			test->flags |= ETH_TEST_FL_FAILED;
 		}
+	}
 
-		data[3] = be_test_ddr_dma(adapter);
-		if (data[3] != 0)
-			test->flags |= ETH_TEST_FL_FAILED;
+	if (be_test_ddr_dma(adapter) != 0) {
+		data[3] = 1;
+		test->flags |= ETH_TEST_FL_FAILED;
 	}
 
+	if (be_cmd_link_status_query(adapter, &link_up, &mac_speed,
+				&qos_link_speed) != 0) {
+		test->flags |= ETH_TEST_FL_FAILED;
+		data[4] = -1;
+	} else if (mac_speed) {
+		data[4] = 1;
+	}
 }
 
 static int
@@ -567,12 +579,57 @@ be_do_flash(struct net_device *netdev, s
 	return be_load_fw(adapter, file_name);
 }
 
+static int
+be_get_eeprom_len(struct net_device *netdev)
+{
+	return BE_READ_SEEPROM_LEN;
+}
+
+static int
+be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
+			uint8_t *data)
+{
+	struct be_adapter *adapter = netdev_priv(netdev);
+	struct be_dma_mem eeprom_cmd;
+	struct be_cmd_resp_seeprom_read *resp;
+	int status;
+
+	if (!eeprom->len)
+		return -EINVAL;
+
+	eeprom->magic = BE_VENDOR_ID | (adapter->pdev->device<<16);
+
+	memset(&eeprom_cmd, 0, sizeof(struct be_dma_mem));
+	eeprom_cmd.size = sizeof(struct be_cmd_req_seeprom_read);
+	eeprom_cmd.va = pci_alloc_consistent(adapter->pdev, eeprom_cmd.size,
+				&eeprom_cmd.dma);
+
+	if (!eeprom_cmd.va) {
+		dev_err(&adapter->pdev->dev,
+			"Memory allocation failure. Could not read eeprom\n");
+		return -ENOMEM;
+	}
+
+	status = be_cmd_get_seeprom_data(adapter, &eeprom_cmd);
+
+	if (!status) {
+		resp = (struct be_cmd_resp_seeprom_read *) eeprom_cmd.va;
+		memcpy(data, resp->seeprom_data + eeprom->offset, eeprom->len);
+	}
+	pci_free_consistent(adapter->pdev, eeprom_cmd.size, eeprom_cmd.va,
+			eeprom_cmd.dma);
+
+	return status;
+}
+
 const struct ethtool_ops be_ethtool_ops = {
 	.get_settings = be_get_settings,
 	.get_drvinfo = be_get_drvinfo,
 	.get_wol = be_get_wol,
 	.set_wol = be_set_wol,
 	.get_link = ethtool_op_get_link,
+	.get_eeprom_len = be_get_eeprom_len,
+	.get_eeprom = be_read_eeprom,
 	.get_coalesce = be_get_coalesce,
 	.set_coalesce = be_set_coalesce,
 	.get_ringparam = be_get_ringparam,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/benet/be.h linux-libre-2.6.34-gnu1/drivers/net/benet/be.h
--- linux-libre-2.6.33-gnu1/drivers/net/benet/be.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/benet/be.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -29,31 +29,30 @@
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #include "be_hw.h"
 
-#define DRV_VER			"2.101.346u"
+#define DRV_VER			"2.102.147u"
 #define DRV_NAME		"be2net"
 #define BE_NAME			"ServerEngines BladeEngine2 10Gbps NIC"
 #define BE3_NAME		"ServerEngines BladeEngine3 10Gbps NIC"
 #define OC_NAME			"Emulex OneConnect 10Gbps NIC"
 #define OC_NAME1		"Emulex OneConnect 10Gbps NIC (be3)"
-#define DRV_DESC		BE_NAME "Driver"
+#define DRV_DESC		"ServerEngines BladeEngine 10Gbps NIC Driver"
 
 #define BE_VENDOR_ID 		0x19a2
 #define BE_DEVICE_ID1		0x211
 #define BE_DEVICE_ID2		0x221
 #define OC_DEVICE_ID1		0x700
-#define OC_DEVICE_ID2		0x701
-#define OC_DEVICE_ID3		0x710
+#define OC_DEVICE_ID2		0x710
 
 static inline char *nic_name(struct pci_dev *pdev)
 {
 	switch (pdev->device) {
 	case OC_DEVICE_ID1:
-	case OC_DEVICE_ID2:
 		return OC_NAME;
-	case OC_DEVICE_ID3:
+	case OC_DEVICE_ID2:
 		return OC_NAME1;
 	case BE_DEVICE_ID2:
 		return BE3_NAME;
@@ -153,6 +152,7 @@ struct be_eq_obj {
 struct be_mcc_obj {
 	struct be_queue_info q;
 	struct be_queue_info cq;
+	bool rearm_cq;
 };
 
 struct be_drvr_stats {
@@ -165,6 +165,7 @@ struct be_drvr_stats {
 	ulong be_tx_jiffies;
 	u64 be_tx_bytes;
 	u64 be_tx_bytes_prev;
+	u64 be_tx_pkts;
 	u32 be_tx_rate;
 
 	u32 cache_barrier[16];
@@ -176,6 +177,7 @@ struct be_drvr_stats {
 	ulong be_rx_jiffies;
 	u64 be_rx_bytes;
 	u64 be_rx_bytes_prev;
+	u64 be_rx_pkts;
 	u32 be_rx_rate;
 	/* number of non ether type II frames dropped where
 	 * frame len > length field of Mac Hdr */
@@ -252,7 +254,8 @@ struct be_adapter {
 	bool rx_post_starved;	/* Zero rx frags have been posted to BE */
 
 	struct vlan_group *vlan_grp;
-	u16 num_vlans;
+	u16 vlans_added;
+	u16 max_vlans;	/* Number of vlans supported */
 	u8 vlan_tag[VLAN_GROUP_ARRAY_LEN];
 	struct be_dma_mem mc_cmd_mem;
 
@@ -266,6 +269,7 @@ struct be_adapter {
 	u32 if_handle;		/* Used to configure filtering */
 	u32 pmac_id;		/* MAC addr handle used by BE card */
 
+	bool eeh_err;
 	bool link_up;
 	u32 port_num;
 	bool promiscuous;
@@ -287,11 +291,6 @@ extern const struct ethtool_ops be_ethto
 
 #define drvr_stats(adapter)		(&adapter->stats.drvr_stats)
 
-static inline unsigned int be_pci_func(struct be_adapter *adapter)
-{
-	return PCI_FUNC(adapter->pdev->devfn);
-}
-
 #define BE_SET_NETDEV_OPS(netdev, ops)	(netdev->netdev_ops = ops)
 
 #define PAGE_SHIFT_4K		12
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/benet/be_hw.h linux-libre-2.6.34-gnu1/drivers/net/benet/be_hw.h
--- linux-libre-2.6.33-gnu1/drivers/net/benet/be_hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/benet/be_hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -99,6 +99,64 @@
 /* Number of entries posted */
 #define DB_MCCQ_NUM_POSTED_SHIFT	(16)	/* bits 16 - 29 */
 
+/* Flashrom related descriptors */
+#define IMAGE_TYPE_FIRMWARE		160
+#define IMAGE_TYPE_BOOTCODE		224
+#define IMAGE_TYPE_OPTIONROM		32
+
+#define NUM_FLASHDIR_ENTRIES		32
+
+#define IMG_TYPE_ISCSI_ACTIVE		0
+#define IMG_TYPE_REDBOOT		1
+#define IMG_TYPE_BIOS			2
+#define IMG_TYPE_PXE_BIOS		3
+#define IMG_TYPE_FCOE_BIOS		8
+#define IMG_TYPE_ISCSI_BACKUP		9
+#define IMG_TYPE_FCOE_FW_ACTIVE		10
+#define IMG_TYPE_FCOE_FW_BACKUP 	11
+#define IMG_TYPE_NCSI_FW		13
+
+#define FLASHROM_OPER_FLASH		1
+#define FLASHROM_OPER_SAVE		2
+#define FLASHROM_OPER_REPORT		4
+
+#define FLASH_IMAGE_MAX_SIZE_g2            (1310720) /* Max firmware image sz */
+#define FLASH_BIOS_IMAGE_MAX_SIZE_g2       (262144)  /* Max OPTION ROM img sz */
+#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g2	  (262144)  /* Max Redboot image sz */
+#define FLASH_IMAGE_MAX_SIZE_g3            (2097152) /* Max fw image size */
+#define FLASH_BIOS_IMAGE_MAX_SIZE_g3       (524288)  /* Max OPTION ROM img sz */
+#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3	  (1048576)  /* Max Redboot image sz */
+#define FLASH_NCSI_IMAGE_MAX_SIZE_g3       (262144)  /* Max NSCI image sz */
+
+#define FLASH_NCSI_MAGIC		(0x16032009)
+#define FLASH_NCSI_DISABLED		(0)
+#define FLASH_NCSI_ENABLED		(1)
+
+#define FLASH_NCSI_BITFILE_HDR_OFFSET	(0x600000)
+
+/* Offsets for components on Flash. */
+#define FLASH_iSCSI_PRIMARY_IMAGE_START_g2 (1048576)
+#define FLASH_iSCSI_BACKUP_IMAGE_START_g2  (2359296)
+#define FLASH_FCoE_PRIMARY_IMAGE_START_g2  (3670016)
+#define FLASH_FCoE_BACKUP_IMAGE_START_g2   (4980736)
+#define FLASH_iSCSI_BIOS_START_g2          (7340032)
+#define FLASH_PXE_BIOS_START_g2            (7864320)
+#define FLASH_FCoE_BIOS_START_g2           (524288)
+#define FLASH_REDBOOT_START_g2		  (0)
+
+#define FLASH_NCSI_START_g3		   (15990784)
+#define FLASH_iSCSI_PRIMARY_IMAGE_START_g3 (2097152)
+#define FLASH_iSCSI_BACKUP_IMAGE_START_g3  (4194304)
+#define FLASH_FCoE_PRIMARY_IMAGE_START_g3  (6291456)
+#define FLASH_FCoE_BACKUP_IMAGE_START_g3   (8388608)
+#define FLASH_iSCSI_BIOS_START_g3          (12582912)
+#define FLASH_PXE_BIOS_START_g3            (13107200)
+#define FLASH_FCoE_BIOS_START_g3           (13631488)
+#define FLASH_REDBOOT_START_g3             (262144)
+
+
+
+
 /*
  * BE descriptors: host memory data structures whose formats
  * are hardwired in BE silicon.
@@ -107,6 +165,7 @@
 #define EQ_ENTRY_VALID_MASK 		0x1	/* bit 0 */
 #define EQ_ENTRY_RES_ID_MASK 		0xFFFF	/* bits 16 - 31 */
 #define EQ_ENTRY_RES_ID_SHIFT 		16
+
 struct be_eq_entry {
 	u32 evt;
 };
@@ -221,41 +280,6 @@ struct be_eth_rx_compl {
 	u32 dw[4];
 };
 
-/* Flashrom related descriptors */
-#define IMAGE_TYPE_FIRMWARE		160
-#define IMAGE_TYPE_BOOTCODE		224
-#define IMAGE_TYPE_OPTIONROM		32
-
-#define NUM_FLASHDIR_ENTRIES		32
-
-#define FLASHROM_TYPE_ISCSI_ACTIVE	0
-#define FLASHROM_TYPE_REDBOOT		1
-#define FLASHROM_TYPE_BIOS		2
-#define FLASHROM_TYPE_PXE_BIOS		3
-#define FLASHROM_TYPE_FCOE_BIOS		8
-#define FLASHROM_TYPE_ISCSI_BACKUP	9
-#define FLASHROM_TYPE_FCOE_FW_ACTIVE	10
-#define FLASHROM_TYPE_FCOE_FW_BACKUP 	11
-
-#define FLASHROM_OPER_FLASH		1
-#define FLASHROM_OPER_SAVE		2
-#define FLASHROM_OPER_REPORT		4
-
-#define FLASH_IMAGE_MAX_SIZE            (1310720) /* Max firmware image size */
-#define FLASH_BIOS_IMAGE_MAX_SIZE       (262144)  /* Max OPTION ROM image sz */
-#define FLASH_REDBOOT_IMAGE_MAX_SIZE    (262144)  /* Max redboot image sz */
-
-/* Offsets for components on Flash. */
-#define FLASH_iSCSI_PRIMARY_IMAGE_START (1048576)
-#define FLASH_iSCSI_BACKUP_IMAGE_START  (2359296)
-#define FLASH_FCoE_PRIMARY_IMAGE_START  (3670016)
-#define FLASH_FCoE_BACKUP_IMAGE_START   (4980736)
-#define FLASH_iSCSI_BIOS_START          (7340032)
-#define FLASH_PXE_BIOS_START            (7864320)
-#define FLASH_FCoE_BIOS_START           (524288)
-#define FLASH_REDBOOT_START		(32768)
-#define FLASH_REDBOOT_ISM_START		(0)
-
 struct controller_id {
 	u32 vendor;
 	u32 device;
@@ -263,7 +287,20 @@ struct controller_id {
 	u32 subdevice;
 };
 
-struct flash_file_hdr {
+struct flash_comp {
+	unsigned long offset;
+	int optype;
+	int size;
+};
+
+struct image_hdr {
+	u32 imageid;
+	u32 imageoffset;
+	u32 imagelength;
+	u32 image_checksum;
+	u8 image_version[32];
+};
+struct flash_file_hdr_g2 {
 	u8 sign[32];
 	u32 cksum;
 	u32 antidote;
@@ -275,6 +312,17 @@ struct flash_file_hdr {
 	u8 build[24];
 };
 
+struct flash_file_hdr_g3 {
+	u8 sign[52];
+	u8 ufi_version[4];
+	u32 file_len;
+	u32 cksum;
+	u32 antidote;
+	u32 num_imgs;
+	u8 build[24];
+	u8 rsvd[32];
+};
+
 struct flash_section_hdr {
 	u32 format_rev;
 	u32 cksum;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/benet/be_main.c linux-libre-2.6.34-gnu1/drivers/net/benet/be_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/benet/be_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/benet/be_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -34,7 +34,6 @@ static DEFINE_PCI_DEVICE_TABLE(be_dev_id
 	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) },
 	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
 	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
-	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID3) },
 	{ 0 }
 };
 MODULE_DEVICE_TABLE(pci, be_dev_ids);
@@ -69,6 +68,9 @@ static void be_intr_set(struct be_adapte
 	u32 reg = ioread32(addr);
 	u32 enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
 
+	if (adapter->eeh_err)
+		return;
+
 	if (!enabled && enable)
 		reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
 	else if (enabled && !enable)
@@ -100,6 +102,10 @@ static void be_eq_notify(struct be_adapt
 {
 	u32 val = 0;
 	val |= qid & DB_EQ_RING_ID_MASK;
+
+	if (adapter->eeh_err)
+		return;
+
 	if (arm)
 		val |= 1 << DB_EQ_REARM_SHIFT;
 	if (clear_int)
@@ -113,6 +119,10 @@ void be_cq_notify(struct be_adapter *ada
 {
 	u32 val = 0;
 	val |= qid & DB_CQ_RING_ID_MASK;
+
+	if (adapter->eeh_err)
+		return;
+
 	if (arm)
 		val |= 1 << DB_CQ_REARM_SHIFT;
 	val |= num_popped << DB_CQ_NUM_POPPED_SHIFT;
@@ -149,13 +159,10 @@ void netdev_stats_update(struct be_adapt
 	struct net_device_stats *dev_stats = &adapter->netdev->stats;
 	struct be_erx_stats *erx_stats = &hw_stats->erx;
 
-	dev_stats->rx_packets = port_stats->rx_total_frames;
-	dev_stats->tx_packets = port_stats->tx_unicastframes +
-		port_stats->tx_multicastframes + port_stats->tx_broadcastframes;
-	dev_stats->rx_bytes = (u64) port_stats->rx_bytes_msd << 32 |
-				(u64) port_stats->rx_bytes_lsd;
-	dev_stats->tx_bytes = (u64) port_stats->tx_bytes_msd << 32 |
-				(u64) port_stats->tx_bytes_lsd;
+	dev_stats->rx_packets = drvr_stats(adapter)->be_rx_pkts;
+	dev_stats->tx_packets = drvr_stats(adapter)->be_tx_pkts;
+	dev_stats->rx_bytes = drvr_stats(adapter)->be_rx_bytes;
+	dev_stats->tx_bytes = drvr_stats(adapter)->be_tx_bytes;
 
 	/* bad pkts received */
 	dev_stats->rx_errors = port_stats->rx_crc_errors +
@@ -312,12 +319,13 @@ static void be_tx_rate_update(struct be_
 }
 
 static void be_tx_stats_update(struct be_adapter *adapter,
-			u32 wrb_cnt, u32 copied, bool stopped)
+			u32 wrb_cnt, u32 copied, u32 gso_segs, bool stopped)
 {
 	struct be_drvr_stats *stats = drvr_stats(adapter);
 	stats->be_tx_reqs++;
 	stats->be_tx_wrbs += wrb_cnt;
 	stats->be_tx_bytes += copied;
+	stats->be_tx_pkts += (gso_segs ? gso_segs : 1);
 	if (stopped)
 		stats->be_tx_stops++;
 }
@@ -462,7 +470,8 @@ static netdev_tx_t be_xmit(struct sk_buf
 
 		be_txq_notify(adapter, txq->id, wrb_cnt);
 
-		be_tx_stats_update(adapter, wrb_cnt, copied, stopped);
+		be_tx_stats_update(adapter, wrb_cnt, copied,
+				skb_shinfo(skb)->gso_segs, stopped);
 	} else {
 		txq->head = start;
 		dev_kfree_skb_any(skb);
@@ -474,10 +483,12 @@ static int be_change_mtu(struct net_devi
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
 	if (new_mtu < BE_MIN_MTU ||
-			new_mtu > BE_MAX_JUMBO_FRAME_SIZE) {
+			new_mtu > (BE_MAX_JUMBO_FRAME_SIZE -
+					(ETH_HLEN + ETH_FCS_LEN))) {
 		dev_info(&adapter->pdev->dev,
 			"MTU must be between %d and %d bytes\n",
-			BE_MIN_MTU, BE_MAX_JUMBO_FRAME_SIZE);
+			BE_MIN_MTU,
+			(BE_MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN)));
 		return -EINVAL;
 	}
 	dev_info(&adapter->pdev->dev, "MTU changed from %d to %d bytes\n",
@@ -487,17 +498,16 @@ static int be_change_mtu(struct net_devi
 }
 
 /*
- * if there are BE_NUM_VLANS_SUPPORTED or lesser number of VLANS configured,
- * program them in BE.  If more than BE_NUM_VLANS_SUPPORTED are configured,
- * set the BE in promiscuous VLAN mode.
+ * A max of 64 (BE_NUM_VLANS_SUPPORTED) vlans can be configured in BE.
+ * If the user configures more, place BE in vlan promiscuous mode.
  */
 static int be_vid_config(struct be_adapter *adapter)
 {
 	u16 vtag[BE_NUM_VLANS_SUPPORTED];
 	u16 ntags = 0, i;
-	int status;
+	int status = 0;
 
-	if (adapter->num_vlans <= BE_NUM_VLANS_SUPPORTED)  {
+	if (adapter->vlans_added <= adapter->max_vlans)  {
 		/* Construct VLAN Table to give to HW */
 		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
 			if (adapter->vlan_tag[i]) {
@@ -531,21 +541,21 @@ static void be_vlan_add_vid(struct net_d
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
 
-	adapter->num_vlans++;
 	adapter->vlan_tag[vid] = 1;
-
-	be_vid_config(adapter);
+	adapter->vlans_added++;
+	if (adapter->vlans_added <= (adapter->max_vlans + 1))
+		be_vid_config(adapter);
 }
 
 static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
 
-	adapter->num_vlans--;
 	adapter->vlan_tag[vid] = 0;
-
 	vlan_group_set_device(adapter->vlan_grp, vid, NULL);
-	be_vid_config(adapter);
+	adapter->vlans_added--;
+	if (adapter->vlans_added <= adapter->max_vlans)
+		be_vid_config(adapter);
 }
 
 static void be_set_multicast_list(struct net_device *netdev)
@@ -565,14 +575,15 @@ static void be_set_multicast_list(struct
 	}
 
 	/* Enable multicast promisc if num configured exceeds what we support */
-	if (netdev->flags & IFF_ALLMULTI || netdev->mc_count > BE_MAX_MC) {
-		be_cmd_multicast_set(adapter, adapter->if_handle, NULL, 0,
+	if (netdev->flags & IFF_ALLMULTI ||
+	    netdev_mc_count(netdev) > BE_MAX_MC) {
+		be_cmd_multicast_set(adapter, adapter->if_handle, NULL,
 				&adapter->mc_cmd_mem);
 		goto done;
 	}
 
-	be_cmd_multicast_set(adapter, adapter->if_handle, netdev->mc_list,
-		netdev->mc_count, &adapter->mc_cmd_mem);
+	be_cmd_multicast_set(adapter, adapter->if_handle, netdev,
+		&adapter->mc_cmd_mem);
 done:
 	return;
 }
@@ -607,6 +618,7 @@ static void be_rx_stats_update(struct be
 	stats->be_rx_compl++;
 	stats->be_rx_frags += numfrags;
 	stats->be_rx_bytes += pktsize;
+	stats->be_rx_pkts++;
 }
 
 static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso)
@@ -634,9 +646,11 @@ get_rx_page_info(struct be_adapter *adap
 	rx_page_info = &adapter->rx_obj.page_info_tbl[frag_idx];
 	BUG_ON(!rx_page_info->page);
 
-	if (rx_page_info->last_page_user)
+	if (rx_page_info->last_page_user) {
 		pci_unmap_page(adapter->pdev, pci_unmap_addr(rx_page_info, bus),
 			adapter->big_page_size, PCI_DMA_FROMDEVICE);
+		rx_page_info->last_page_user = false;
+	}
 
 	atomic_dec(&rxq->used);
 	return rx_page_info;
@@ -666,17 +680,17 @@ static void be_rx_compl_discard(struct b
  * indicated by rxcp.
  */
 static void skb_fill_rx_data(struct be_adapter *adapter,
-			struct sk_buff *skb, struct be_eth_rx_compl *rxcp)
+			struct sk_buff *skb, struct be_eth_rx_compl *rxcp,
+			u16 num_rcvd)
 {
 	struct be_queue_info *rxq = &adapter->rx_obj.q;
 	struct be_rx_page_info *page_info;
-	u16 rxq_idx, i, num_rcvd, j;
+	u16 rxq_idx, i, j;
 	u32 pktsize, hdr_len, curr_frag_len, size;
 	u8 *start;
 
 	rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
 	pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
-	num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
 
 	page_info = get_rx_page_info(adapter, rxq_idx);
 
@@ -704,7 +718,7 @@ static void skb_fill_rx_data(struct be_a
 		skb->data_len = curr_frag_len - hdr_len;
 		skb->tail += hdr_len;
 	}
-	memset(page_info, 0, sizeof(*page_info));
+	page_info->page = NULL;
 
 	if (pktsize <= rx_frag_size) {
 		BUG_ON(num_rcvd != 1);
@@ -737,7 +751,7 @@ static void skb_fill_rx_data(struct be_a
 		skb->len += curr_frag_len;
 		skb->data_len += curr_frag_len;
 
-		memset(page_info, 0, sizeof(*page_info));
+		page_info->page = NULL;
 	}
 	BUG_ON(j > MAX_SKB_FRAGS);
 
@@ -752,25 +766,23 @@ static void be_rx_compl_process(struct b
 {
 	struct sk_buff *skb;
 	u32 vlanf, vid;
+	u16 num_rcvd;
 	u8 vtm;
 
-	vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
-	vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
-
-	/* vlanf could be wrongly set in some cards.
-	 * ignore if vtm is not set */
-	if ((adapter->cap & 0x400) && !vtm)
-		vlanf = 0;
+	num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
+	/* Is it a flush compl that has no data */
+	if (unlikely(num_rcvd == 0))
+		return;
 
 	skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN);
-	if (!skb) {
+	if (unlikely(!skb)) {
 		if (net_ratelimit())
 			dev_warn(&adapter->pdev->dev, "skb alloc failed\n");
 		be_rx_compl_discard(adapter, rxcp);
 		return;
 	}
 
-	skb_fill_rx_data(adapter, skb, rxcp);
+	skb_fill_rx_data(adapter, skb, rxcp, num_rcvd);
 
 	if (do_pkt_csum(rxcp, adapter->rx_csum))
 		skb->ip_summed = CHECKSUM_NONE;
@@ -781,13 +793,21 @@ static void be_rx_compl_process(struct b
 	skb->protocol = eth_type_trans(skb, adapter->netdev);
 	skb->dev = adapter->netdev;
 
-	if (vlanf) {
-		if (!adapter->vlan_grp || adapter->num_vlans == 0) {
+	vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
+	vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
+
+	/* vlanf could be wrongly set in some cards.
+	 * ignore if vtm is not set */
+	if ((adapter->cap & 0x400) && !vtm)
+		vlanf = 0;
+
+	if (unlikely(vlanf)) {
+		if (!adapter->vlan_grp || adapter->vlans_added == 0) {
 			kfree_skb(skb);
 			return;
 		}
 		vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp);
-		vid = be16_to_cpu(vid);
+		vid = swab16(vid);
 		vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, vid);
 	} else {
 		netif_receive_skb(skb);
@@ -809,6 +829,10 @@ static void be_rx_compl_process_gro(stru
 	u8 vtm;
 
 	num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
+	/* Is it a flush compl that has no data */
+	if (unlikely(num_rcvd == 0))
+		return;
+
 	pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
 	vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
 	rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
@@ -860,9 +884,9 @@ static void be_rx_compl_process_gro(stru
 		napi_gro_frags(&eq_obj->napi);
 	} else {
 		vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp);
-		vid = be16_to_cpu(vid);
+		vid = swab16(vid);
 
-		if (!adapter->vlan_grp || adapter->num_vlans == 0)
+		if (!adapter->vlan_grp || adapter->vlans_added == 0)
 			return;
 
 		vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid);
@@ -1104,6 +1128,9 @@ static void be_tx_compl_clean(struct be_
 	struct be_queue_info *txq = &adapter->tx_obj.q;
 	struct be_eth_tx_compl *txcp;
 	u16 end_idx, cmpl = 0, timeo = 0;
+	struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list;
+	struct sk_buff *sent_skb;
+	bool dummy_wrb;
 
 	/* Wait for a max of 200ms for all the tx-completions to arrive. */
 	do {
@@ -1127,6 +1154,15 @@ static void be_tx_compl_clean(struct be_
 	if (atomic_read(&txq->used))
 		dev_err(&adapter->pdev->dev, "%d pending tx-completions\n",
 			atomic_read(&txq->used));
+
+	/* free posted tx for which compls will never arrive */
+	while (atomic_read(&txq->used)) {
+		sent_skb = sent_skbs[txq->tail];
+		end_idx = txq->tail;
+		index_adv(&end_idx,
+			wrb_cnt_for_skb(sent_skb, &dummy_wrb) - 1, txq->len);
+		be_tx_compl_process(adapter, end_idx);
+	}
 }
 
 static void be_mcc_queues_destroy(struct be_adapter *adapter)
@@ -1259,6 +1295,11 @@ static void be_rx_queues_destroy(struct
 	q = &adapter->rx_obj.q;
 	if (q->created) {
 		be_cmd_q_destroy(adapter, q, QTYPE_RXQ);
+
+		/* After the rxq is invalidated, wait for a grace time
+		 * of 1ms for all dma to end and the flush compl to arrive
+		 */
+		mdelay(1);
 		be_rx_q_clean(adapter);
 	}
 	be_queue_free(adapter, q);
@@ -1341,7 +1382,7 @@ rx_eq_free:
 /* There are 8 evt ids per func. Retruns the evt id's bit number */
 static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id)
 {
-	return eq_id - 8 * be_pci_func(adapter);
+	return eq_id % 8;
 }
 
 static irqreturn_t be_intx(int irq, void *dev)
@@ -1428,23 +1469,38 @@ int be_poll_rx(struct napi_struct *napi,
 	return work_done;
 }
 
-void be_process_tx(struct be_adapter *adapter)
+/* As TX and MCC share the same EQ check for both TX and MCC completions.
+ * For TX/MCC we don't honour budget; consume everything
+ */
+static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
 {
+	struct be_eq_obj *tx_eq = container_of(napi, struct be_eq_obj, napi);
+	struct be_adapter *adapter =
+		container_of(tx_eq, struct be_adapter, tx_eq);
 	struct be_queue_info *txq = &adapter->tx_obj.q;
 	struct be_queue_info *tx_cq = &adapter->tx_obj.cq;
 	struct be_eth_tx_compl *txcp;
-	u32 num_cmpl = 0;
+	int tx_compl = 0, mcc_compl, status = 0;
 	u16 end_idx;
 
 	while ((txcp = be_tx_compl_get(tx_cq))) {
 		end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl,
-					wrb_index, txcp);
+				wrb_index, txcp);
 		be_tx_compl_process(adapter, end_idx);
-		num_cmpl++;
+		tx_compl++;
 	}
 
-	if (num_cmpl) {
-		be_cq_notify(adapter, tx_cq->id, true, num_cmpl);
+	mcc_compl = be_process_mcc(adapter, &status);
+
+	napi_complete(napi);
+
+	if (mcc_compl) {
+		struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
+		be_cq_notify(adapter, mcc_obj->cq.id, true, mcc_compl);
+	}
+
+	if (tx_compl) {
+		be_cq_notify(adapter, adapter->tx_obj.cq.id, true, tx_compl);
 
 		/* As Tx wrbs have been freed up, wake up netdev queue if
 		 * it was stopped due to lack of tx wrbs.
@@ -1455,24 +1511,8 @@ void be_process_tx(struct be_adapter *ad
 		}
 
 		drvr_stats(adapter)->be_tx_events++;
-		drvr_stats(adapter)->be_tx_compl += num_cmpl;
+		drvr_stats(adapter)->be_tx_compl += tx_compl;
 	}
-}
-
-/* As TX and MCC share the same EQ check for both TX and MCC completions.
- * For TX/MCC we don't honour budget; consume everything
- */
-static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
-{
-	struct be_eq_obj *tx_eq = container_of(napi, struct be_eq_obj, napi);
-	struct be_adapter *adapter =
-		container_of(tx_eq, struct be_adapter, tx_eq);
-
-	napi_complete(napi);
-
-	be_process_tx(adapter);
-
-	be_process_mcc(adapter);
 
 	return 1;
 }
@@ -1641,6 +1681,9 @@ static int be_open(struct net_device *ne
 	/* Rx compl queue may be in unarmed state; rearm it */
 	be_cq_notify(adapter, adapter->rx_obj.cq.id, true, 0);
 
+	/* Now that interrupts are on we can process async mcc */
+	be_async_mcc_enable(adapter);
+
 	status = be_cmd_link_status_query(adapter, &link_up, &mac_speed,
 			&link_speed);
 	if (status)
@@ -1766,6 +1809,8 @@ static int be_close(struct net_device *n
 
 	cancel_delayed_work_sync(&adapter->work);
 
+	be_async_mcc_disable(adapter);
+
 	netif_stop_queue(netdev);
 	netif_carrier_off(netdev);
 	adapter->link_up = false;
@@ -1798,15 +1843,19 @@ char flash_cookie[2][16] =	{"*** SE FLAS
 				"H DIRECTORY *** "};
 
 static bool be_flash_redboot(struct be_adapter *adapter,
-			const u8 *p)
+			const u8 *p, u32 img_start, int image_size,
+			int hdr_size)
 {
 	u32 crc_offset;
 	u8 flashed_crc[4];
 	int status;
-	crc_offset = FLASH_REDBOOT_START + FLASH_REDBOOT_IMAGE_MAX_SIZE - 4
-			+ sizeof(struct flash_file_hdr) - 32*1024;
+
+	crc_offset = hdr_size + img_start + image_size - 4;
+
 	p += crc_offset;
-	status = be_cmd_get_flash_crc(adapter, flashed_crc);
+
+	status = be_cmd_get_flash_crc(adapter, flashed_crc,
+			(image_size - 4));
 	if (status) {
 		dev_err(&adapter->pdev->dev,
 		"could not get crc from flash, not flashing redboot\n");
@@ -1818,112 +1867,133 @@ static bool be_flash_redboot(struct be_a
 		return false;
 	else
 		return true;
-
 }
 
-static int be_flash_image(struct be_adapter *adapter,
+static int be_flash_data(struct be_adapter *adapter,
 			const struct firmware *fw,
-			struct be_dma_mem *flash_cmd, u32 flash_type)
+			struct be_dma_mem *flash_cmd, int num_of_images)
+
 {
-	int status;
-	u32 flash_op, image_offset = 0, total_bytes, image_size = 0;
+	int status = 0, i, filehdr_size = 0;
+	u32 total_bytes = 0, flash_op;
 	int num_bytes;
 	const u8 *p = fw->data;
 	struct be_cmd_write_flashrom *req = flash_cmd->va;
+	struct flash_comp *pflashcomp;
+	int num_comp;
 
-	switch (flash_type) {
-	case FLASHROM_TYPE_ISCSI_ACTIVE:
-		image_offset = FLASH_iSCSI_PRIMARY_IMAGE_START;
-		image_size = FLASH_IMAGE_MAX_SIZE;
-		break;
-	case FLASHROM_TYPE_ISCSI_BACKUP:
-		image_offset = FLASH_iSCSI_BACKUP_IMAGE_START;
-		image_size = FLASH_IMAGE_MAX_SIZE;
-		break;
-	case FLASHROM_TYPE_FCOE_FW_ACTIVE:
-		image_offset = FLASH_FCoE_PRIMARY_IMAGE_START;
-		image_size = FLASH_IMAGE_MAX_SIZE;
-		break;
-	case FLASHROM_TYPE_FCOE_FW_BACKUP:
-		image_offset = FLASH_FCoE_BACKUP_IMAGE_START;
-		image_size = FLASH_IMAGE_MAX_SIZE;
-		break;
-	case FLASHROM_TYPE_BIOS:
-		image_offset = FLASH_iSCSI_BIOS_START;
-		image_size = FLASH_BIOS_IMAGE_MAX_SIZE;
-		break;
-	case FLASHROM_TYPE_FCOE_BIOS:
-		image_offset = FLASH_FCoE_BIOS_START;
-		image_size = FLASH_BIOS_IMAGE_MAX_SIZE;
-		break;
-	case FLASHROM_TYPE_PXE_BIOS:
-		image_offset = FLASH_PXE_BIOS_START;
-		image_size = FLASH_BIOS_IMAGE_MAX_SIZE;
-		break;
-	case FLASHROM_TYPE_REDBOOT:
-		if (!be_flash_redboot(adapter, fw->data))
-			return 0;
-		image_offset = FLASH_REDBOOT_ISM_START;
-		image_size = FLASH_REDBOOT_IMAGE_MAX_SIZE;
-		break;
-	default:
-		return 0;
-	}
+	struct flash_comp gen3_flash_types[9] = {
+		{ FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE,
+			FLASH_IMAGE_MAX_SIZE_g3},
+		{ FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT,
+			FLASH_REDBOOT_IMAGE_MAX_SIZE_g3},
+		{ FLASH_iSCSI_BIOS_START_g3, IMG_TYPE_BIOS,
+			FLASH_BIOS_IMAGE_MAX_SIZE_g3},
+		{ FLASH_PXE_BIOS_START_g3, IMG_TYPE_PXE_BIOS,
+			FLASH_BIOS_IMAGE_MAX_SIZE_g3},
+		{ FLASH_FCoE_BIOS_START_g3, IMG_TYPE_FCOE_BIOS,
+			FLASH_BIOS_IMAGE_MAX_SIZE_g3},
+		{ FLASH_iSCSI_BACKUP_IMAGE_START_g3, IMG_TYPE_ISCSI_BACKUP,
+			FLASH_IMAGE_MAX_SIZE_g3},
+		{ FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE,
+			FLASH_IMAGE_MAX_SIZE_g3},
+		{ FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP,
+			FLASH_IMAGE_MAX_SIZE_g3},
+		{ FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW,
+			FLASH_NCSI_IMAGE_MAX_SIZE_g3}
+	};
+	struct flash_comp gen2_flash_types[8] = {
+		{ FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE,
+			FLASH_IMAGE_MAX_SIZE_g2},
+		{ FLASH_REDBOOT_START_g2, IMG_TYPE_REDBOOT,
+			FLASH_REDBOOT_IMAGE_MAX_SIZE_g2},
+		{ FLASH_iSCSI_BIOS_START_g2, IMG_TYPE_BIOS,
+			FLASH_BIOS_IMAGE_MAX_SIZE_g2},
+		{ FLASH_PXE_BIOS_START_g2, IMG_TYPE_PXE_BIOS,
+			FLASH_BIOS_IMAGE_MAX_SIZE_g2},
+		{ FLASH_FCoE_BIOS_START_g2, IMG_TYPE_FCOE_BIOS,
+			FLASH_BIOS_IMAGE_MAX_SIZE_g2},
+		{ FLASH_iSCSI_BACKUP_IMAGE_START_g2, IMG_TYPE_ISCSI_BACKUP,
+			FLASH_IMAGE_MAX_SIZE_g2},
+		{ FLASH_FCoE_PRIMARY_IMAGE_START_g2, IMG_TYPE_FCOE_FW_ACTIVE,
+			FLASH_IMAGE_MAX_SIZE_g2},
+		{ FLASH_FCoE_BACKUP_IMAGE_START_g2, IMG_TYPE_FCOE_FW_BACKUP,
+			 FLASH_IMAGE_MAX_SIZE_g2}
+	};
 
-	p += sizeof(struct flash_file_hdr) + image_offset;
-	if (p + image_size > fw->data + fw->size)
+	if (adapter->generation == BE_GEN3) {
+		pflashcomp = gen3_flash_types;
+		filehdr_size = sizeof(struct flash_file_hdr_g3);
+		num_comp = 9;
+	} else {
+		pflashcomp = gen2_flash_types;
+		filehdr_size = sizeof(struct flash_file_hdr_g2);
+		num_comp = 8;
+	}
+	for (i = 0; i < num_comp; i++) {
+		if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) &&
+				memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
+			continue;
+		if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) &&
+			(!be_flash_redboot(adapter, fw->data,
+			 pflashcomp[i].offset, pflashcomp[i].size,
+			 filehdr_size)))
+			continue;
+		p = fw->data;
+		p += filehdr_size + pflashcomp[i].offset
+			+ (num_of_images * sizeof(struct image_hdr));
+	if (p + pflashcomp[i].size > fw->data + fw->size)
 		return -1;
+	total_bytes = pflashcomp[i].size;
+		while (total_bytes) {
+			if (total_bytes > 32*1024)
+				num_bytes = 32*1024;
+			else
+				num_bytes = total_bytes;
+			total_bytes -= num_bytes;
 
-	total_bytes = image_size;
-
-	while (total_bytes) {
-		if (total_bytes > 32*1024)
-			num_bytes = 32*1024;
-		else
-			num_bytes = total_bytes;
-		total_bytes -= num_bytes;
-
-		if (!total_bytes)
-			flash_op = FLASHROM_OPER_FLASH;
-		else
-			flash_op = FLASHROM_OPER_SAVE;
-		memcpy(req->params.data_buf, p, num_bytes);
-		p += num_bytes;
-		status = be_cmd_write_flashrom(adapter, flash_cmd,
-				flash_type, flash_op, num_bytes);
-		if (status) {
-			dev_err(&adapter->pdev->dev,
-			"cmd to write to flash rom failed. type/op %d/%d\n",
-			flash_type, flash_op);
-			return -1;
+			if (!total_bytes)
+				flash_op = FLASHROM_OPER_FLASH;
+			else
+				flash_op = FLASHROM_OPER_SAVE;
+			memcpy(req->params.data_buf, p, num_bytes);
+			p += num_bytes;
+			status = be_cmd_write_flashrom(adapter, flash_cmd,
+				pflashcomp[i].optype, flash_op, num_bytes);
+			if (status) {
+				dev_err(&adapter->pdev->dev,
+					"cmd to write to flash rom failed.\n");
+				return -1;
+			}
+			yield();
 		}
-		yield();
 	}
-
 	return 0;
 }
 
+static int get_ufigen_type(struct flash_file_hdr_g2 *fhdr)
+{
+	if (fhdr == NULL)
+		return 0;
+	if (fhdr->build[0] == '3')
+		return BE_GEN3;
+	else if (fhdr->build[0] == '2')
+		return BE_GEN2;
+	else
+		return 0;
+}
+
 int be_load_fw(struct be_adapter *adapter, u8 *func)
 {
 	char fw_file[ETHTOOL_FLASH_MAX_FILENAME];
 	const struct firmware *fw;
-	struct flash_file_hdr *fhdr;
-	struct flash_section_info *fsec = NULL;
+	struct flash_file_hdr_g2 *fhdr;
+	struct flash_file_hdr_g3 *fhdr3;
+	struct image_hdr *img_hdr_ptr = NULL;
 	struct be_dma_mem flash_cmd;
-	int status;
+	int status, i = 0, num_imgs = 0;
 	const u8 *p;
-	bool entry_found = false;
-	int flash_type;
-	char fw_ver[FW_VER_LEN];
-	char fw_cfg;
-
-	status = be_cmd_get_fw_ver(adapter, fw_ver);
-	if (status)
-		return status;
 
-	fw_cfg = *(fw_ver + 2);
-	if (fw_cfg == '0')
-		fw_cfg = '1';
 	strcpy(fw_file, func);
 
 	status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
@@ -1931,34 +2001,9 @@ int be_load_fw(struct be_adapter *adapte
 		goto fw_exit;
 
 	p = fw->data;
-	fhdr = (struct flash_file_hdr *) p;
-	if (memcmp(fhdr->sign, FW_FILE_HDR_SIGN, strlen(FW_FILE_HDR_SIGN))) {
-		dev_err(&adapter->pdev->dev,
-			"Firmware(%s) load error (signature did not match)\n",
-				fw_file);
-		status = -1;
-		goto fw_exit;
-	}
-
+	fhdr = (struct flash_file_hdr_g2 *) p;
 	dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file);
 
-	p += sizeof(struct flash_file_hdr);
-	while (p < (fw->data + fw->size)) {
-		fsec = (struct flash_section_info *)p;
-		if (!memcmp(flash_cookie, fsec->cookie, sizeof(flash_cookie))) {
-			entry_found = true;
-			break;
-		}
-		p += 32;
-	}
-
-	if (!entry_found) {
-		status = -1;
-		dev_err(&adapter->pdev->dev,
-			"Flash cookie not found in firmware image\n");
-		goto fw_exit;
-	}
-
 	flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024;
 	flash_cmd.va = pci_alloc_consistent(adapter->pdev, flash_cmd.size,
 					&flash_cmd.dma);
@@ -1969,12 +2014,25 @@ int be_load_fw(struct be_adapter *adapte
 		goto fw_exit;
 	}
 
-	for (flash_type = FLASHROM_TYPE_ISCSI_ACTIVE;
-		flash_type <= FLASHROM_TYPE_FCOE_FW_BACKUP; flash_type++) {
-		status = be_flash_image(adapter, fw, &flash_cmd,
-				flash_type);
-		if (status)
-			break;
+	if ((adapter->generation == BE_GEN3) &&
+			(get_ufigen_type(fhdr) == BE_GEN3)) {
+		fhdr3 = (struct flash_file_hdr_g3 *) fw->data;
+		num_imgs = le32_to_cpu(fhdr3->num_imgs);
+		for (i = 0; i < num_imgs; i++) {
+			img_hdr_ptr = (struct image_hdr *) (fw->data +
+					(sizeof(struct flash_file_hdr_g3) +
+					 i * sizeof(struct image_hdr)));
+			if (le32_to_cpu(img_hdr_ptr->imageid) == 1)
+				status = be_flash_data(adapter, fw, &flash_cmd,
+							num_imgs);
+		}
+	} else if ((adapter->generation == BE_GEN2) &&
+			(get_ufigen_type(fhdr) == BE_GEN2)) {
+		status = be_flash_data(adapter, fw, &flash_cmd, 0);
+	} else {
+		dev_err(&adapter->pdev->dev,
+			"UFI and Interface are not compatible for flashing\n");
+		status = -1;
 	}
 
 	pci_free_consistent(adapter->pdev, flash_cmd.size, flash_cmd.va,
@@ -2136,6 +2194,7 @@ static int be_ctrl_init(struct be_adapte
 	spin_lock_init(&adapter->mcc_lock);
 	spin_lock_init(&adapter->mcc_cq_lock);
 
+	pci_save_state(adapter->pdev);
 	return 0;
 
 free_mbox:
@@ -2222,6 +2281,11 @@ static int be_get_config(struct be_adapt
 	memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
 	memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
 
+	if (adapter->cap & 0x400)
+		adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/4;
+	else
+		adapter->max_vlans = BE_NUM_VLANS_SUPPORTED;
+
 	return 0;
 }
 
@@ -2394,13 +2458,123 @@ static int be_resume(struct pci_dev *pde
 	return 0;
 }
 
+/*
+ * An FLR will stop BE from DMAing any data.
+ */
+static void be_shutdown(struct pci_dev *pdev)
+{
+	struct be_adapter *adapter = pci_get_drvdata(pdev);
+	struct net_device *netdev =  adapter->netdev;
+
+	netif_device_detach(netdev);
+
+	be_cmd_reset_function(adapter);
+
+	if (adapter->wol)
+		be_setup_wol(adapter, true);
+
+	pci_disable_device(pdev);
+
+	return;
+}
+
+static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev,
+				pci_channel_state_t state)
+{
+	struct be_adapter *adapter = pci_get_drvdata(pdev);
+	struct net_device *netdev =  adapter->netdev;
+
+	dev_err(&adapter->pdev->dev, "EEH error detected\n");
+
+	adapter->eeh_err = true;
+
+	netif_device_detach(netdev);
+
+	if (netif_running(netdev)) {
+		rtnl_lock();
+		be_close(netdev);
+		rtnl_unlock();
+	}
+	be_clear(adapter);
+
+	if (state == pci_channel_io_perm_failure)
+		return PCI_ERS_RESULT_DISCONNECT;
+
+	pci_disable_device(pdev);
+
+	return PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
+{
+	struct be_adapter *adapter = pci_get_drvdata(pdev);
+	int status;
+
+	dev_info(&adapter->pdev->dev, "EEH reset\n");
+	adapter->eeh_err = false;
+
+	status = pci_enable_device(pdev);
+	if (status)
+		return PCI_ERS_RESULT_DISCONNECT;
+
+	pci_set_master(pdev);
+	pci_set_power_state(pdev, 0);
+	pci_restore_state(pdev);
+
+	/* Check if card is ok and fw is ready */
+	status = be_cmd_POST(adapter);
+	if (status)
+		return PCI_ERS_RESULT_DISCONNECT;
+
+	return PCI_ERS_RESULT_RECOVERED;
+}
+
+static void be_eeh_resume(struct pci_dev *pdev)
+{
+	int status = 0;
+	struct be_adapter *adapter = pci_get_drvdata(pdev);
+	struct net_device *netdev =  adapter->netdev;
+
+	dev_info(&adapter->pdev->dev, "EEH resume\n");
+
+	pci_save_state(pdev);
+
+	/* tell fw we're ready to fire cmds */
+	status = be_cmd_fw_init(adapter);
+	if (status)
+		goto err;
+
+	status = be_setup(adapter);
+	if (status)
+		goto err;
+
+	if (netif_running(netdev)) {
+		status = be_open(netdev);
+		if (status)
+			goto err;
+	}
+	netif_device_attach(netdev);
+	return;
+err:
+	dev_err(&adapter->pdev->dev, "EEH resume failed\n");
+	return;
+}
+
+static struct pci_error_handlers be_eeh_handlers = {
+	.error_detected = be_eeh_err_detected,
+	.slot_reset = be_eeh_reset,
+	.resume = be_eeh_resume,
+};
+
 static struct pci_driver be_driver = {
 	.name = DRV_NAME,
 	.id_table = be_dev_ids,
 	.probe = be_probe,
 	.remove = be_remove,
 	.suspend = be_suspend,
-	.resume = be_resume
+	.resume = be_resume,
+	.shutdown = be_shutdown,
+	.err_handler = &be_eeh_handlers
 };
 
 static int __init be_init_module(void)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/benet/Kconfig linux-libre-2.6.34-gnu1/drivers/net/benet/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/net/benet/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/benet/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 config BE2NET
-	tristate "ServerEngines' 10Gbps NIC - BladeEngine 2"
+	tristate "ServerEngines' 10Gbps NIC - BladeEngine"
 	depends on PCI && INET
 	help
 	This driver implements the NIC functionality for ServerEngines'
-	10Gbps network adapter - BladeEngine 2.
+	10Gbps network adapter - BladeEngine.
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/bfin_mac.c linux-libre-2.6.34-gnu1/drivers/net/bfin_mac.c
--- linux-libre-2.6.33-gnu1/drivers/net/bfin_mac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/bfin_mac.c	2010-05-16 17:17:36.000000000 -0400
@@ -812,16 +812,14 @@ static void bfin_mac_timeout(struct net_
 static void bfin_mac_multicast_hash(struct net_device *dev)
 {
 	u32 emac_hashhi, emac_hashlo;
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	char *addrs;
-	int i;
 	u32 crc;
 
 	emac_hashhi = emac_hashlo = 0;
 
-	for (i = 0; i < dev->mc_count; i++) {
+	netdev_for_each_mc_addr(dmi, dev) {
 		addrs = dmi->dmi_addr;
-		dmi = dmi->next;
 
 		/* skip non-multicast addresses */
 		if (!(*addrs & 1))
@@ -862,7 +860,7 @@ static void bfin_mac_set_multicast_list(
 		sysctl = bfin_read_EMAC_OPMODE();
 		sysctl |= PAM;
 		bfin_write_EMAC_OPMODE(sysctl);
-	} else if (dev->mc_count) {
+	} else if (!netdev_mc_empty(dev)) {
 		/* set up multicast hash table */
 		sysctl = bfin_read_EMAC_OPMODE();
 		sysctl |= HM;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/bmac.c linux-libre-2.6.34-gnu1/drivers/net/bmac.c
--- linux-libre-2.6.33-gnu1/drivers/net/bmac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/bmac.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/crc32.h>
 #include <linux/bitrev.h>
 #include <linux/ethtool.h>
+#include <linux/slab.h>
 #include <asm/prom.h>
 #include <asm/dbdma.h>
 #include <asm/io.h>
@@ -973,7 +974,7 @@ static void bmac_set_multicast(struct ne
 {
 	struct dev_mc_list *dmi;
 	struct bmac_data *bp = netdev_priv(dev);
-	int num_addrs = dev->mc_count;
+	int num_addrs = netdev_mc_count(dev);
 	unsigned short rx_cfg;
 	int i;
 
@@ -982,7 +983,7 @@ static void bmac_set_multicast(struct ne
 
 	XXDEBUG(("bmac: enter bmac_set_multicast, n_addrs=%d\n", num_addrs));
 
-	if((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) {
+	if((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 64)) {
 		for (i=0; i<4; i++) bp->hash_table_mask[i] = 0xffff;
 		bmac_update_hash_table_mask(dev, bp);
 		rx_cfg = bmac_rx_on(dev, 1, 0);
@@ -1000,7 +1001,7 @@ static void bmac_set_multicast(struct ne
 			rx_cfg = bmac_rx_on(dev, 0, 0);
 			XXDEBUG(("bmac: multi disabled, rx_cfg=%#08x\n", rx_cfg));
 		} else {
-			for (dmi=dev->mc_list; dmi!=NULL; dmi=dmi->next)
+			netdev_for_each_mc_addr(dmi, dev)
 				bmac_addhash(bp, dmi->dmi_addr);
 			bmac_update_hash_table_mask(dev, bp);
 			rx_cfg = bmac_rx_on(dev, 1, 0);
@@ -1015,13 +1016,13 @@ static void bmac_set_multicast(struct ne
 
 static void bmac_set_multicast(struct net_device *dev)
 {
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	char *addrs;
 	int i;
 	unsigned short rx_cfg;
 	u32 crc;
 
-	if((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) {
+	if((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 64)) {
 		bmwrite(dev, BHASH0, 0xffff);
 		bmwrite(dev, BHASH1, 0xffff);
 		bmwrite(dev, BHASH2, 0xffff);
@@ -1039,9 +1040,8 @@ static void bmac_set_multicast(struct ne
 
 		for(i = 0; i < 4; i++) hash_table[i] = 0;
 
-		for(i = 0; i < dev->mc_count; i++) {
+		netdev_for_each_mc_addr(dmi, dev) {
 			addrs = dmi->dmi_addr;
-			dmi = dmi->next;
 
 			if(!(*addrs & 1))
 				continue;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/bnx2.c linux-libre-2.6.34-gnu1/drivers/net/bnx2.c
--- linux-libre-2.6.33-gnu1/drivers/net/bnx2.c	2013-05-03 12:07:48.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/bnx2.c	2013-05-03 09:47:10.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2.c: Broadcom NX2 network driver.
  *
- * Copyright (c) 2004-2009 Broadcom Corporation
+ * Copyright (c) 2004-2010 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
@@ -9,6 +9,7 @@
  * Written by: Michael Chan  (mchan@broadcom.com)
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -48,7 +49,6 @@
 #include <linux/cache.h>
 #include <linux/firmware.h>
 #include <linux/log2.h>
-#include <linux/list.h>
 
 #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
 #define BCM_CNIC 1
@@ -58,9 +58,8 @@
 #include "bnx2_fw.h"
 
 #define DRV_MODULE_NAME		"bnx2"
-#define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"2.0.3"
-#define DRV_MODULE_RELDATE	"Dec 03, 2009"
+#define DRV_MODULE_VERSION	"2.0.9"
+#define DRV_MODULE_RELDATE	"April 27, 2010"
 #define FW_MIPS_FILE_06		"/*(DEBLOBBED)*/"
 #define FW_RV2P_FILE_06		"/*(DEBLOBBED)*/"
 #define FW_MIPS_FILE_09		"/*(DEBLOBBED)*/"
@@ -243,6 +242,8 @@ static const struct flash_spec flash_570
 
 MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
 
+static void bnx2_init_napi(struct bnx2 *bp);
+
 static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr)
 {
 	u32 diff;
@@ -646,9 +647,10 @@ bnx2_napi_enable(struct bnx2 *bp)
 }
 
 static void
-bnx2_netif_stop(struct bnx2 *bp)
+bnx2_netif_stop(struct bnx2 *bp, bool stop_cnic)
 {
-	bnx2_cnic_stop(bp);
+	if (stop_cnic)
+		bnx2_cnic_stop(bp);
 	if (netif_running(bp->dev)) {
 		int i;
 
@@ -666,14 +668,15 @@ bnx2_netif_stop(struct bnx2 *bp)
 }
 
 static void
-bnx2_netif_start(struct bnx2 *bp)
+bnx2_netif_start(struct bnx2 *bp, bool start_cnic)
 {
 	if (atomic_dec_and_test(&bp->intr_sem)) {
 		if (netif_running(bp->dev)) {
 			netif_tx_wake_all_queues(bp->dev);
 			bnx2_napi_enable(bp);
 			bnx2_enable_int(bp);
-			bnx2_cnic_start(bp);
+			if (start_cnic)
+				bnx2_cnic_start(bp);
 		}
 	}
 }
@@ -976,33 +979,27 @@ bnx2_report_link(struct bnx2 *bp)
 {
 	if (bp->link_up) {
 		netif_carrier_on(bp->dev);
-		printk(KERN_INFO PFX "%s NIC %s Link is Up, ", bp->dev->name,
-		       bnx2_xceiver_str(bp));
-
-		printk("%d Mbps ", bp->line_speed);
-
-		if (bp->duplex == DUPLEX_FULL)
-			printk("full duplex");
-		else
-			printk("half duplex");
+		netdev_info(bp->dev, "NIC %s Link is Up, %d Mbps %s duplex",
+			    bnx2_xceiver_str(bp),
+			    bp->line_speed,
+			    bp->duplex == DUPLEX_FULL ? "full" : "half");
 
 		if (bp->flow_ctrl) {
 			if (bp->flow_ctrl & FLOW_CTRL_RX) {
-				printk(", receive ");
+				pr_cont(", receive ");
 				if (bp->flow_ctrl & FLOW_CTRL_TX)
-					printk("& transmit ");
+					pr_cont("& transmit ");
 			}
 			else {
-				printk(", transmit ");
+				pr_cont(", transmit ");
 			}
-			printk("flow control ON");
+			pr_cont("flow control ON");
 		}
-		printk("\n");
-	}
-	else {
+		pr_cont("\n");
+	} else {
 		netif_carrier_off(bp->dev);
-		printk(KERN_ERR PFX "%s NIC %s Link is Down\n", bp->dev->name,
-		       bnx2_xceiver_str(bp));
+		netdev_err(bp->dev, "NIC %s Link is Down\n",
+			   bnx2_xceiver_str(bp));
 	}
 
 	bnx2_report_fw_link(bp);
@@ -1274,7 +1271,7 @@ bnx2_init_rx_context(struct bnx2 *bp, u3
 		if (lo_water >= bp->rx_ring_size)
 			lo_water = 0;
 
-		hi_water = bp->rx_ring_size / 4;
+		hi_water = min_t(int, bp->rx_ring_size / 4, lo_water + 16);
 
 		if (hi_water <= lo_water)
 			lo_water = 0;
@@ -2479,8 +2476,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_da
 	/* If we timed out, inform the firmware that this is the case. */
 	if ((val & BNX2_FW_MSG_ACK) != (msg_data & BNX2_DRV_MSG_SEQ)) {
 		if (!silent)
-			printk(KERN_ERR PFX "fw sync timeout, reset code = "
-					    "%x\n", msg_data);
+			pr_err("fw sync timeout, reset code = %x\n", msg_data);
 
 		msg_data &= ~BNX2_DRV_MSG_CODE;
 		msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT;
@@ -2596,8 +2592,7 @@ bnx2_alloc_bad_rbuf(struct bnx2 *bp)
 
 	good_mbuf = kmalloc(512 * sizeof(u16), GFP_KERNEL);
 	if (good_mbuf == NULL) {
-		printk(KERN_ERR PFX "Failed to allocate memory in "
-				    "bnx2_alloc_bad_rbuf\n");
+		pr_err("Failed to allocate memory in %s\n", __func__);
 		return -ENOMEM;
 	}
 
@@ -3557,9 +3552,7 @@ bnx2_set_rx_mode(struct net_device *dev)
 
 		memset(mc_filter, 0, 4 * NUM_MC_HASH_REGISTERS);
 
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-		     i++, mclist = mclist->next) {
-
+		netdev_for_each_mc_addr(mclist, dev) {
 			crc = ether_crc_le(ETH_ALEN, mclist->dmi_addr);
 			bit = crc & 0xff;
 			regidx = (bit & 0xe0) >> 5;
@@ -3575,14 +3568,14 @@ bnx2_set_rx_mode(struct net_device *dev)
 		sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN;
 	}
 
-	if (dev->uc.count > BNX2_MAX_UNICAST_ADDRESSES) {
+	if (netdev_uc_count(dev) > BNX2_MAX_UNICAST_ADDRESSES) {
 		rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS;
 		sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN |
 			     BNX2_RPM_SORT_USER0_PROM_VLAN;
 	} else if (!(dev->flags & IFF_PROMISC)) {
 		/* Add all entries into to the match filter list */
 		i = 0;
-		list_for_each_entry(ha, &dev->uc.list, list) {
+		netdev_for_each_uc_addr(ha, dev) {
 			bnx2_set_mac_addr(bp, ha->addr,
 					  i + BNX2_START_UNICAST_ADDRESS_INDEX);
 			sort_mode |= (1 <<
@@ -3653,15 +3646,13 @@ bnx2_reject_firmware(struct bnx2 *bp)
 
 	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);
+		pr_err("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);
+		pr_err("Can't load firmware file \"%s\"\n", rv2p_fw_file);
 		return rc;
 	}
 	mips_fw = (const struct bnx2_mips_fw_file *) bp->mips_firmware->data;
@@ -3672,15 +3663,13 @@ bnx2_reject_firmware(struct bnx2 *bp)
 	    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);
+		pr_err("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);
+		pr_err("Firmware file \"%s\" is invalid\n", rv2p_fw_file);
 		return -EINVAL;
 	}
 
@@ -4314,7 +4303,7 @@ bnx2_init_nvram(struct bnx2 *bp)
 
 	if (j == entry_count) {
 		bp->flash_info = NULL;
-		printk(KERN_ALERT PFX "Unknown flash/EEPROM type.\n");
+		pr_alert("Unknown flash/EEPROM type\n");
 		return -ENODEV;
 	}
 
@@ -4734,7 +4723,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 res
 
 		if (val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
 			   BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
-			printk(KERN_ERR PFX "Chip reset did not complete\n");
+			pr_err("Chip reset did not complete\n");
 			return -EBUSY;
 		}
 	}
@@ -4742,7 +4731,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 res
 	/* Make sure byte swapping is properly configured. */
 	val = REG_RD(bp, BNX2_PCI_SWAP_DIAG0);
 	if (val != 0x01020304) {
-		printk(KERN_ERR PFX "Chip not in correct endian mode\n");
+		pr_err("Chip not in correct endian mode\n");
 		return -ENODEV;
 	}
 
@@ -4768,8 +4757,12 @@ bnx2_reset_chip(struct bnx2 *bp, u32 res
 		rc = bnx2_alloc_bad_rbuf(bp);
 	}
 
-	if (bp->flags & BNX2_FLAG_USING_MSIX)
+	if (bp->flags & BNX2_FLAG_USING_MSIX) {
 		bnx2_setup_msix_tbl(bp);
+		/* Prevent MSIX table reads and write from timing out */
+		REG_WR(bp, BNX2_MISC_ECO_HW_CTL,
+			BNX2_MISC_ECO_HW_CTL_LARGE_GRC_TMOUT_EN);
+	}
 
 	return rc;
 }
@@ -4937,7 +4930,7 @@ bnx2_init_chip(struct bnx2 *bp)
 		      BNX2_HC_CONFIG_COLLECT_STATS;
 	}
 
-	if (bp->irq_nvecs > 1) {
+	if (bp->flags & BNX2_FLAG_USING_MSIX) {
 		REG_WR(bp, BNX2_HC_MSIX_BIT_VECTOR,
 		       BNX2_HC_MSIX_BIT_VECTOR_VAL);
 
@@ -5163,9 +5156,8 @@ bnx2_init_rx_ring(struct bnx2 *bp, int r
 	ring_prod = prod = rxr->rx_pg_prod;
 	for (i = 0; i < bp->rx_pg_ring_size; i++) {
 		if (bnx2_alloc_rx_page(bp, rxr, ring_prod) < 0) {
-			printk(KERN_WARNING PFX "%s: init'ed rx page ring %d "
-						"with %d/%d pages only\n",
-			       bp->dev->name, ring_num, i, bp->rx_pg_ring_size);
+			netdev_warn(bp->dev, "init'ed rx page ring %d with %d/%d pages only\n",
+				    ring_num, i, bp->rx_pg_ring_size);
 			break;
 		}
 		prod = NEXT_RX_BD(prod);
@@ -5176,9 +5168,8 @@ bnx2_init_rx_ring(struct bnx2 *bp, int r
 	ring_prod = prod = rxr->rx_prod;
 	for (i = 0; i < bp->rx_ring_size; i++) {
 		if (bnx2_alloc_rx_skb(bp, rxr, ring_prod) < 0) {
-			printk(KERN_WARNING PFX "%s: init'ed rx ring %d with "
-						"%d/%d skbs only\n",
-			       bp->dev->name, ring_num, i, bp->rx_ring_size);
+			netdev_warn(bp->dev, "init'ed rx ring %d with %d/%d skbs only\n",
+				    ring_num, i, bp->rx_ring_size);
 			break;
 		}
 		prod = NEXT_RX_BD(prod);
@@ -6141,6 +6132,10 @@ bnx2_enable_msix(struct bnx2 *bp, int ms
 	REG_WR(bp, BNX2_PCI_MSIX_TBL_OFF_BIR, BNX2_PCI_GRC_WINDOW2_BASE);
 	REG_WR(bp, BNX2_PCI_MSIX_PBA_OFF_BIT, BNX2_PCI_GRC_WINDOW3_BASE);
 
+	/*  Need to flush the previous three writes to ensure MSI-X
+	 *  is setup properly */
+	REG_RD(bp, BNX2_PCI_MSIX_CONTROL);
+
 	for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
 		msix_ent[i].entry = i;
 		msix_ent[i].vector = 0;
@@ -6206,6 +6201,7 @@ bnx2_open(struct net_device *dev)
 	bnx2_disable_int(bp);
 
 	bnx2_setup_int_mode(bp, disable_msi);
+	bnx2_init_napi(bp);
 	bnx2_napi_enable(bp);
 	rc = bnx2_alloc_mem(bp);
 	if (rc)
@@ -6223,6 +6219,8 @@ bnx2_open(struct net_device *dev)
 
 	atomic_set(&bp->intr_sem, 0);
 
+	memset(bp->temp_stats_blk, 0, sizeof(struct statistics_block));
+
 	bnx2_enable_int(bp);
 
 	if (bp->flags & BNX2_FLAG_USING_MSI) {
@@ -6230,11 +6228,7 @@ bnx2_open(struct net_device *dev)
 		 * If MSI test fails, go back to INTx mode
 		 */
 		if (bnx2_test_intr(bp) != 0) {
-			printk(KERN_WARNING PFX "%s: No interrupt was generated"
-			       " using MSI, switching to INTx mode. Please"
-			       " report this failure to the PCI maintainer"
-			       " and include system chipset information.\n",
-			       bp->dev->name);
+			netdev_warn(bp->dev, "No interrupt was generated using MSI, switching to INTx mode. Please report this failure to the PCI maintainer and include system chipset information.\n");
 
 			bnx2_disable_int(bp);
 			bnx2_free_irq(bp);
@@ -6254,9 +6248,9 @@ bnx2_open(struct net_device *dev)
 		}
 	}
 	if (bp->flags & BNX2_FLAG_USING_MSI)
-		printk(KERN_INFO PFX "%s: using MSI\n", dev->name);
+		netdev_info(dev, "using MSI\n");
 	else if (bp->flags & BNX2_FLAG_USING_MSIX)
-		printk(KERN_INFO PFX "%s: using MSIX\n", dev->name);
+		netdev_info(dev, "using MSIX\n");
 
 	netif_tx_start_all_queues(dev);
 
@@ -6281,12 +6275,12 @@ bnx2_reset_task(struct work_struct *work
 		return;
 	}
 
-	bnx2_netif_stop(bp);
+	bnx2_netif_stop(bp, true);
 
 	bnx2_init_nic(bp, 1);
 
 	atomic_set(&bp->intr_sem, 1);
-	bnx2_netif_start(bp);
+	bnx2_netif_start(bp, true);
 	rtnl_unlock();
 }
 
@@ -6295,20 +6289,18 @@ bnx2_dump_state(struct bnx2 *bp)
 {
 	struct net_device *dev = bp->dev;
 
-	printk(KERN_ERR PFX "%s DEBUG: intr_sem[%x]\n", dev->name,
-		atomic_read(&bp->intr_sem));
-	printk(KERN_ERR PFX "%s DEBUG: EMAC_TX_STATUS[%08x] "
-			    "RPM_MGMT_PKT_CTRL[%08x]\n", dev->name,
-		REG_RD(bp, BNX2_EMAC_TX_STATUS),
-		REG_RD(bp, BNX2_RPM_MGMT_PKT_CTRL));
-	printk(KERN_ERR PFX "%s DEBUG: MCP_STATE_P0[%08x] MCP_STATE_P1[%08x]\n",
-		dev->name, bnx2_reg_rd_ind(bp, BNX2_MCP_STATE_P0),
-		bnx2_reg_rd_ind(bp, BNX2_MCP_STATE_P1));
-	printk(KERN_ERR PFX "%s DEBUG: HC_STATS_INTERRUPT_STATUS[%08x]\n",
-		dev->name, REG_RD(bp, BNX2_HC_STATS_INTERRUPT_STATUS));
+	netdev_err(dev, "DEBUG: intr_sem[%x]\n", atomic_read(&bp->intr_sem));
+	netdev_err(dev, "DEBUG: EMAC_TX_STATUS[%08x] RPM_MGMT_PKT_CTRL[%08x]\n",
+		   REG_RD(bp, BNX2_EMAC_TX_STATUS),
+		   REG_RD(bp, BNX2_RPM_MGMT_PKT_CTRL));
+	netdev_err(dev, "DEBUG: MCP_STATE_P0[%08x] MCP_STATE_P1[%08x]\n",
+		   bnx2_reg_rd_ind(bp, BNX2_MCP_STATE_P0),
+		   bnx2_reg_rd_ind(bp, BNX2_MCP_STATE_P1));
+	netdev_err(dev, "DEBUG: HC_STATS_INTERRUPT_STATUS[%08x]\n",
+		   REG_RD(bp, BNX2_HC_STATS_INTERRUPT_STATUS));
 	if (bp->flags & BNX2_FLAG_USING_MSIX)
-		printk(KERN_ERR PFX "%s DEBUG: PBA[%08x]\n", dev->name,
-			REG_RD(bp, BNX2_PCI_GRC_WINDOW3_BASE));
+		netdev_err(dev, "DEBUG: PBA[%08x]\n",
+			   REG_RD(bp, BNX2_PCI_GRC_WINDOW3_BASE));
 }
 
 static void
@@ -6330,7 +6322,7 @@ bnx2_vlan_rx_register(struct net_device
 	struct bnx2 *bp = netdev_priv(dev);
 
 	if (netif_running(dev))
-		bnx2_netif_stop(bp);
+		bnx2_netif_stop(bp, false);
 
 	bp->vlgrp = vlgrp;
 
@@ -6341,7 +6333,7 @@ bnx2_vlan_rx_register(struct net_device
 	if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
 		bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);
 
-	bnx2_netif_start(bp);
+	bnx2_netif_start(bp, false);
 }
 #endif
 
@@ -6372,8 +6364,7 @@ bnx2_start_xmit(struct sk_buff *skb, str
 	if (unlikely(bnx2_tx_avail(bp, txr) <
 	    (skb_shinfo(skb)->nr_frags + 1))) {
 		netif_tx_stop_queue(txq);
-		printk(KERN_ERR PFX "%s: BUG! Tx ring full when queue awake!\n",
-			dev->name);
+		netdev_err(dev, "BUG! Tx ring full when queue awake!\n");
 
 		return NETDEV_TX_BUSY;
 	}
@@ -6534,92 +6525,121 @@ bnx2_close(struct net_device *dev)
 	return 0;
 }
 
-#define GET_NET_STATS64(ctr)					\
+static void
+bnx2_save_stats(struct bnx2 *bp)
+{
+	u32 *hw_stats = (u32 *) bp->stats_blk;
+	u32 *temp_stats = (u32 *) bp->temp_stats_blk;
+	int i;
+
+	/* The 1st 10 counters are 64-bit counters */
+	for (i = 0; i < 20; i += 2) {
+		u32 hi;
+		u64 lo;
+
+		hi = temp_stats[i] + hw_stats[i];
+		lo = (u64) temp_stats[i + 1] + (u64) hw_stats[i + 1];
+		if (lo > 0xffffffff)
+			hi++;
+		temp_stats[i] = hi;
+		temp_stats[i + 1] = lo & 0xffffffff;
+	}
+
+	for ( ; i < sizeof(struct statistics_block) / 4; i++)
+		temp_stats[i] += hw_stats[i];
+}
+
+#define GET_64BIT_NET_STATS64(ctr)				\
 	(unsigned long) ((unsigned long) (ctr##_hi) << 32) +	\
 	(unsigned long) (ctr##_lo)
 
-#define GET_NET_STATS32(ctr)		\
+#define GET_64BIT_NET_STATS32(ctr)				\
 	(ctr##_lo)
 
 #if (BITS_PER_LONG == 64)
-#define GET_NET_STATS	GET_NET_STATS64
+#define GET_64BIT_NET_STATS(ctr)				\
+	GET_64BIT_NET_STATS64(bp->stats_blk->ctr) +		\
+	GET_64BIT_NET_STATS64(bp->temp_stats_blk->ctr)
 #else
-#define GET_NET_STATS	GET_NET_STATS32
+#define GET_64BIT_NET_STATS(ctr)				\
+	GET_64BIT_NET_STATS32(bp->stats_blk->ctr) +		\
+	GET_64BIT_NET_STATS32(bp->temp_stats_blk->ctr)
 #endif
 
+#define GET_32BIT_NET_STATS(ctr)				\
+	(unsigned long) (bp->stats_blk->ctr +			\
+			 bp->temp_stats_blk->ctr)
+
 static struct net_device_stats *
 bnx2_get_stats(struct net_device *dev)
 {
 	struct bnx2 *bp = netdev_priv(dev);
-	struct statistics_block *stats_blk = bp->stats_blk;
 	struct net_device_stats *net_stats = &dev->stats;
 
 	if (bp->stats_blk == NULL) {
 		return net_stats;
 	}
 	net_stats->rx_packets =
-		GET_NET_STATS(stats_blk->stat_IfHCInUcastPkts) +
-		GET_NET_STATS(stats_blk->stat_IfHCInMulticastPkts) +
-		GET_NET_STATS(stats_blk->stat_IfHCInBroadcastPkts);
+		GET_64BIT_NET_STATS(stat_IfHCInUcastPkts) +
+		GET_64BIT_NET_STATS(stat_IfHCInMulticastPkts) +
+		GET_64BIT_NET_STATS(stat_IfHCInBroadcastPkts);
 
 	net_stats->tx_packets =
-		GET_NET_STATS(stats_blk->stat_IfHCOutUcastPkts) +
-		GET_NET_STATS(stats_blk->stat_IfHCOutMulticastPkts) +
-		GET_NET_STATS(stats_blk->stat_IfHCOutBroadcastPkts);
+		GET_64BIT_NET_STATS(stat_IfHCOutUcastPkts) +
+		GET_64BIT_NET_STATS(stat_IfHCOutMulticastPkts) +
+		GET_64BIT_NET_STATS(stat_IfHCOutBroadcastPkts);
 
 	net_stats->rx_bytes =
-		GET_NET_STATS(stats_blk->stat_IfHCInOctets);
+		GET_64BIT_NET_STATS(stat_IfHCInOctets);
 
 	net_stats->tx_bytes =
-		GET_NET_STATS(stats_blk->stat_IfHCOutOctets);
+		GET_64BIT_NET_STATS(stat_IfHCOutOctets);
 
 	net_stats->multicast =
-		GET_NET_STATS(stats_blk->stat_IfHCOutMulticastPkts);
+		GET_64BIT_NET_STATS(stat_IfHCOutMulticastPkts);
 
 	net_stats->collisions =
-		(unsigned long) stats_blk->stat_EtherStatsCollisions;
+		GET_32BIT_NET_STATS(stat_EtherStatsCollisions);
 
 	net_stats->rx_length_errors =
-		(unsigned long) (stats_blk->stat_EtherStatsUndersizePkts +
-		stats_blk->stat_EtherStatsOverrsizePkts);
+		GET_32BIT_NET_STATS(stat_EtherStatsUndersizePkts) +
+		GET_32BIT_NET_STATS(stat_EtherStatsOverrsizePkts);
 
 	net_stats->rx_over_errors =
-		(unsigned long) (stats_blk->stat_IfInFTQDiscards +
-		stats_blk->stat_IfInMBUFDiscards);
+		GET_32BIT_NET_STATS(stat_IfInFTQDiscards) +
+		GET_32BIT_NET_STATS(stat_IfInMBUFDiscards);
 
 	net_stats->rx_frame_errors =
-		(unsigned long) stats_blk->stat_Dot3StatsAlignmentErrors;
+		GET_32BIT_NET_STATS(stat_Dot3StatsAlignmentErrors);
 
 	net_stats->rx_crc_errors =
-		(unsigned long) stats_blk->stat_Dot3StatsFCSErrors;
+		GET_32BIT_NET_STATS(stat_Dot3StatsFCSErrors);
 
 	net_stats->rx_errors = net_stats->rx_length_errors +
 		net_stats->rx_over_errors + net_stats->rx_frame_errors +
 		net_stats->rx_crc_errors;
 
 	net_stats->tx_aborted_errors =
-    		(unsigned long) (stats_blk->stat_Dot3StatsExcessiveCollisions +
-		stats_blk->stat_Dot3StatsLateCollisions);
+		GET_32BIT_NET_STATS(stat_Dot3StatsExcessiveCollisions) +
+		GET_32BIT_NET_STATS(stat_Dot3StatsLateCollisions);
 
 	if ((CHIP_NUM(bp) == CHIP_NUM_5706) ||
 	    (CHIP_ID(bp) == CHIP_ID_5708_A0))
 		net_stats->tx_carrier_errors = 0;
 	else {
 		net_stats->tx_carrier_errors =
-			(unsigned long)
-			stats_blk->stat_Dot3StatsCarrierSenseErrors;
+			GET_32BIT_NET_STATS(stat_Dot3StatsCarrierSenseErrors);
 	}
 
 	net_stats->tx_errors =
-    		(unsigned long)
-		stats_blk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors
-		+
+		GET_32BIT_NET_STATS(stat_emac_tx_stat_dot3statsinternalmactransmiterrors) +
 		net_stats->tx_aborted_errors +
 		net_stats->tx_carrier_errors;
 
 	net_stats->rx_missed_errors =
-		(unsigned long) (stats_blk->stat_IfInFTQDiscards +
-		stats_blk->stat_IfInMBUFDiscards + stats_blk->stat_FwRxDrop);
+		GET_32BIT_NET_STATS(stat_IfInFTQDiscards) +
+		GET_32BIT_NET_STATS(stat_IfInMBUFDiscards) +
+		GET_32BIT_NET_STATS(stat_FwRxDrop);
 
 	return net_stats;
 }
@@ -6713,32 +6733,15 @@ bnx2_set_settings(struct net_device *dev
 	if (cmd->autoneg == AUTONEG_ENABLE) {
 		autoneg |= AUTONEG_SPEED;
 
-		cmd->advertising &= ETHTOOL_ALL_COPPER_SPEED;
-
-		/* allow advertising 1 speed */
-		if ((cmd->advertising == ADVERTISED_10baseT_Half) ||
-			(cmd->advertising == ADVERTISED_10baseT_Full) ||
-			(cmd->advertising == ADVERTISED_100baseT_Half) ||
-			(cmd->advertising == ADVERTISED_100baseT_Full)) {
-
-			if (cmd->port == PORT_FIBRE)
-				goto err_out_unlock;
-
-			advertising = cmd->advertising;
-
-		} else if (cmd->advertising == ADVERTISED_2500baseX_Full) {
-			if (!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE) ||
-			    (cmd->port == PORT_TP))
-				goto err_out_unlock;
-		} else if (cmd->advertising == ADVERTISED_1000baseT_Full)
-			advertising = cmd->advertising;
-		else if (cmd->advertising == ADVERTISED_1000baseT_Half)
-			goto err_out_unlock;
-		else {
-			if (cmd->port == PORT_FIBRE)
-				advertising = ETHTOOL_ALL_FIBRE_SPEED;
-			else
+		advertising = cmd->advertising;
+		if (cmd->port == PORT_TP) {
+			advertising &= ETHTOOL_ALL_COPPER_SPEED;
+			if (!advertising)
 				advertising = ETHTOOL_ALL_COPPER_SPEED;
+		} else {
+			advertising &= ETHTOOL_ALL_FIBRE_SPEED;
+			if (!advertising)
+				advertising = ETHTOOL_ALL_FIBRE_SPEED;
 		}
 		advertising |= ADVERTISED_Autoneg;
 	}
@@ -7050,9 +7053,9 @@ bnx2_set_coalesce(struct net_device *dev
 	bp->stats_ticks &= BNX2_HC_STATS_TICKS_HC_STAT_TICKS;
 
 	if (netif_running(bp->dev)) {
-		bnx2_netif_stop(bp);
+		bnx2_netif_stop(bp, true);
 		bnx2_init_nic(bp, 0);
-		bnx2_netif_start(bp);
+		bnx2_netif_start(bp, true);
 	}
 
 	return 0;
@@ -7079,7 +7082,10 @@ static int
 bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
 {
 	if (netif_running(bp->dev)) {
-		bnx2_netif_stop(bp);
+		/* Reset will erase chipset stats; save them */
+		bnx2_save_stats(bp);
+
+		bnx2_netif_stop(bp, true);
 		bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
 		bnx2_free_skbs(bp);
 		bnx2_free_mem(bp);
@@ -7100,7 +7106,14 @@ bnx2_change_ring_size(struct bnx2 *bp, u
 			dev_close(bp->dev);
 			return rc;
 		}
-		bnx2_netif_start(bp);
+#ifdef BCM_CNIC
+		mutex_lock(&bp->cnic_lock);
+		/* Let cnic know about the new status block. */
+		if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD)
+			bnx2_setup_cnic_irq_info(bp);
+		mutex_unlock(&bp->cnic_lock);
+#endif
+		bnx2_netif_start(bp, true);
 	}
 	return 0;
 }
@@ -7353,7 +7366,7 @@ bnx2_self_test(struct net_device *dev, s
 	if (etest->flags & ETH_TEST_FL_OFFLINE) {
 		int i;
 
-		bnx2_netif_stop(bp);
+		bnx2_netif_stop(bp, true);
 		bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_DIAG);
 		bnx2_free_skbs(bp);
 
@@ -7372,7 +7385,7 @@ bnx2_self_test(struct net_device *dev, s
 			bnx2_shutdown_chip(bp);
 		else {
 			bnx2_init_nic(bp, 1);
-			bnx2_netif_start(bp);
+			bnx2_netif_start(bp, true);
 		}
 
 		/* wait for link up */
@@ -7423,6 +7436,7 @@ bnx2_get_ethtool_stats(struct net_device
 	struct bnx2 *bp = netdev_priv(dev);
 	int i;
 	u32 *hw_stats = (u32 *) bp->stats_blk;
+	u32 *temp_stats = (u32 *) bp->temp_stats_blk;
 	u8 *stats_len_arr = NULL;
 
 	if (hw_stats == NULL) {
@@ -7439,21 +7453,26 @@ bnx2_get_ethtool_stats(struct net_device
 		stats_len_arr = bnx2_5708_stats_len_arr;
 
 	for (i = 0; i < BNX2_NUM_STATS; i++) {
+		unsigned long offset;
+
 		if (stats_len_arr[i] == 0) {
 			/* skip this counter */
 			buf[i] = 0;
 			continue;
 		}
+
+		offset = bnx2_stats_offset_arr[i];
 		if (stats_len_arr[i] == 4) {
 			/* 4-byte counter */
-			buf[i] = (u64)
-				*(hw_stats + bnx2_stats_offset_arr[i]);
+			buf[i] = (u64) *(hw_stats + offset) +
+				 *(temp_stats + offset);
 			continue;
 		}
 		/* 8-byte counter */
-		buf[i] = (((u64) *(hw_stats +
-					bnx2_stats_offset_arr[i])) << 32) +
-				*(hw_stats + bnx2_stats_offset_arr[i] + 1);
+		buf[i] = (((u64) *(hw_stats + offset)) << 32) +
+			 *(hw_stats + offset + 1) +
+			 (((u64) *(temp_stats + offset)) << 32) +
+			 *(temp_stats + offset + 1);
 	}
 }
 
@@ -7621,7 +7640,7 @@ bnx2_change_mtu(struct net_device *dev,
 	return (bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size));
 }
 
-#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
+#ifdef CONFIG_NET_POLL_CONTROLLER
 static void
 poll_bnx2(struct net_device *dev)
 {
@@ -7629,9 +7648,11 @@ poll_bnx2(struct net_device *dev)
 	int i;
 
 	for (i = 0; i < bp->irq_nvecs; i++) {
-		disable_irq(bp->irq_tbl[i].vector);
-		bnx2_interrupt(bp->irq_tbl[i].vector, &bp->bnx2_napi[i]);
-		enable_irq(bp->irq_tbl[i].vector);
+		struct bnx2_irq *irq = &bp->irq_tbl[i];
+
+		disable_irq(irq->vector);
+		irq->handler(irq->vector, &bp->bnx2_napi[i]);
+		enable_irq(irq->vector);
 	}
 }
 #endif
@@ -7729,10 +7750,9 @@ bnx2_get_pci_speed(struct bnx2 *bp)
 static void __devinit
 bnx2_read_vpd_fw_ver(struct bnx2 *bp)
 {
-	int rc, i, v0_len = 0;
+	int rc, i, j;
 	u8 *data;
-	u8 *v0_str = NULL;
-	bool mn_match = false;
+	unsigned int block_end, rosize, len;
 
 #define BNX2_VPD_NVRAM_OFFSET	0x300
 #define BNX2_VPD_LEN		128
@@ -7754,53 +7774,42 @@ bnx2_read_vpd_fw_ver(struct bnx2 *bp)
 		data[i + 3] = data[i + BNX2_VPD_LEN];
 	}
 
-	for (i = 0; i <= BNX2_VPD_LEN - 3; ) {
-		unsigned char val = data[i];
-		unsigned int block_end;
-
-		if (val == 0x82 || val == 0x91) {
-			i = (i + 3 + (data[i + 1] + (data[i + 2] << 8)));
-			continue;
-		}
-
-		if (val != 0x90)
-			goto vpd_done;
+	i = pci_vpd_find_tag(data, 0, BNX2_VPD_LEN, PCI_VPD_LRDT_RO_DATA);
+	if (i < 0)
+		goto vpd_done;
 
-		block_end = (i + 3 + (data[i + 1] + (data[i + 2] << 8)));
-		i += 3;
+	rosize = pci_vpd_lrdt_size(&data[i]);
+	i += PCI_VPD_LRDT_TAG_SIZE;
+	block_end = i + rosize;
 
-		if (block_end > BNX2_VPD_LEN)
-			goto vpd_done;
+	if (block_end > BNX2_VPD_LEN)
+		goto vpd_done;
 
-		while (i < (block_end - 2)) {
-			int len = data[i + 2];
+	j = pci_vpd_find_info_keyword(data, i, rosize,
+				      PCI_VPD_RO_KEYWORD_MFR_ID);
+	if (j < 0)
+		goto vpd_done;
 
-			if (i + 3 + len > block_end)
-				goto vpd_done;
+	len = pci_vpd_info_field_size(&data[j]);
 
-			if (data[i] == 'M' && data[i + 1] == 'N') {
-				if (len != 4 ||
-				    memcmp(&data[i + 3], "1028", 4))
-					goto vpd_done;
-				mn_match = true;
+	j += PCI_VPD_INFO_FLD_HDR_SIZE;
+	if (j + len > block_end || len != 4 ||
+	    memcmp(&data[j], "1028", 4))
+		goto vpd_done;
 
-			} else if (data[i] == 'V' && data[i + 1] == '0') {
-				if (len > BNX2_MAX_VER_SLEN)
-					goto vpd_done;
+	j = pci_vpd_find_info_keyword(data, i, rosize,
+				      PCI_VPD_RO_KEYWORD_VENDOR0);
+	if (j < 0)
+		goto vpd_done;
 
-				v0_len = len;
-				v0_str = &data[i + 3];
-			}
-			i += 3 + len;
+	len = pci_vpd_info_field_size(&data[j]);
 
-			if (mn_match && v0_str) {
-				memcpy(bp->fw_version, v0_str, v0_len);
-				bp->fw_version[v0_len] = ' ';
-				goto vpd_done;
-			}
-		}
+	j += PCI_VPD_INFO_FLD_HDR_SIZE;
+	if (j + len > block_end || len > BNX2_MAX_VER_SLEN)
 		goto vpd_done;
-	}
+
+	memcpy(bp->fw_version, &data[j], len);
+	bp->fw_version[len] = ' ';
 
 vpd_done:
 	kfree(data);
@@ -7821,23 +7830,31 @@ bnx2_init_board(struct pci_dev *pdev, st
 	bp->flags = 0;
 	bp->phy_flags = 0;
 
+	bp->temp_stats_blk =
+		kzalloc(sizeof(struct statistics_block), GFP_KERNEL);
+
+	if (bp->temp_stats_blk == NULL) {
+		rc = -ENOMEM;
+		goto err_out;
+	}
+
 	/* enable device (incl. PCI PM wakeup), and bus-mastering */
 	rc = pci_enable_device(pdev);
 	if (rc) {
-		dev_err(&pdev->dev, "Cannot enable PCI device, aborting.\n");
+		dev_err(&pdev->dev, "Cannot enable PCI device, aborting\n");
 		goto err_out;
 	}
 
 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
 		dev_err(&pdev->dev,
-			"Cannot find PCI device base address, aborting.\n");
+			"Cannot find PCI device base address, aborting\n");
 		rc = -ENODEV;
 		goto err_out_disable;
 	}
 
 	rc = pci_request_regions(pdev, DRV_MODULE_NAME);
 	if (rc) {
-		dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting.\n");
+		dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting\n");
 		goto err_out_disable;
 	}
 
@@ -7847,7 +7864,7 @@ bnx2_init_board(struct pci_dev *pdev, st
 	bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
 	if (bp->pm_cap == 0) {
 		dev_err(&pdev->dev,
-			"Cannot find power management capability, aborting.\n");
+			"Cannot find power management capability, aborting\n");
 		rc = -EIO;
 		goto err_out_release;
 	}
@@ -7870,7 +7887,7 @@ bnx2_init_board(struct pci_dev *pdev, st
 	bp->regview = ioremap_nocache(dev->base_addr, mem_len);
 
 	if (!bp->regview) {
-		dev_err(&pdev->dev, "Cannot map register space, aborting.\n");
+		dev_err(&pdev->dev, "Cannot map register space, aborting\n");
 		rc = -ENOMEM;
 		goto err_out_release;
 	}
@@ -7890,7 +7907,7 @@ bnx2_init_board(struct pci_dev *pdev, st
 	if (CHIP_NUM(bp) == CHIP_NUM_5709) {
 		if (pci_find_capability(pdev, PCI_CAP_ID_EXP) == 0) {
 			dev_err(&pdev->dev,
-				"Cannot find PCIE capability, aborting.\n");
+				"Cannot find PCIE capability, aborting\n");
 			rc = -EIO;
 			goto err_out_unmap;
 		}
@@ -7901,7 +7918,7 @@ bnx2_init_board(struct pci_dev *pdev, st
 		bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
 		if (bp->pcix_cap == 0) {
 			dev_err(&pdev->dev,
-				"Cannot find PCIX capability, aborting.\n");
+				"Cannot find PCIX capability, aborting\n");
 			rc = -EIO;
 			goto err_out_unmap;
 		}
@@ -7930,11 +7947,11 @@ bnx2_init_board(struct pci_dev *pdev, st
 		rc = pci_set_consistent_dma_mask(pdev, persist_dma_mask);
 		if (rc) {
 			dev_err(&pdev->dev,
-				"pci_set_consistent_dma_mask failed, aborting.\n");
+				"pci_set_consistent_dma_mask failed, aborting\n");
 			goto err_out_unmap;
 		}
 	} else if ((rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) {
-		dev_err(&pdev->dev, "System does not support DMA, aborting.\n");
+		dev_err(&pdev->dev, "System does not support DMA, aborting\n");
 		goto err_out_unmap;
 	}
 
@@ -7951,7 +7968,7 @@ bnx2_init_board(struct pci_dev *pdev, st
 		!(bp->flags & BNX2_FLAG_PCIX)) {
 
 		dev_err(&pdev->dev,
-			"5706 A1 can only be used in a PCIX bus, aborting.\n");
+			"5706 A1 can only be used in a PCIX bus, aborting\n");
 		goto err_out_unmap;
 	}
 
@@ -7974,7 +7991,7 @@ bnx2_init_board(struct pci_dev *pdev, st
 
 	if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
 	    BNX2_DEV_INFO_SIGNATURE_MAGIC) {
-		dev_err(&pdev->dev, "Firmware not running, aborting.\n");
+		dev_err(&pdev->dev, "Firmware not running, aborting\n");
 		rc = -ENODEV;
 		goto err_out_unmap;
 	}
@@ -8197,7 +8214,7 @@ bnx2_init_napi(struct bnx2 *bp)
 {
 	int i;
 
-	for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
+	for (i = 0; i < bp->irq_nvecs; i++) {
 		struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
 		int (*poll)(struct napi_struct *, int);
 
@@ -8225,7 +8242,7 @@ static const struct net_device_ops bnx2_
 #ifdef BCM_VLAN
 	.ndo_vlan_rx_register	= bnx2_vlan_rx_register,
 #endif
-#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
+#ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= poll_bnx2,
 #endif
 };
@@ -8247,7 +8264,7 @@ bnx2_init_one(struct pci_dev *pdev, cons
 	char str[40];
 
 	if (version_printed++ == 0)
-		printk(KERN_INFO "%s", version);
+		pr_info("%s", version);
 
 	/* dev zeroed in init_etherdev */
 	dev = alloc_etherdev_mq(sizeof(*bp), TX_MAX_RINGS);
@@ -8266,7 +8283,6 @@ bnx2_init_one(struct pci_dev *pdev, cons
 	dev->ethtool_ops = &bnx2_ethtool_ops;
 
 	bp = netdev_priv(dev);
-	bnx2_init_napi(bp);
 
 	pci_set_drvdata(pdev, dev);
 
@@ -8297,15 +8313,13 @@ bnx2_init_one(struct pci_dev *pdev, cons
 		goto error;
 	}
 
-	printk(KERN_INFO "%s: %s (%c%d) %s found at mem %lx, "
-		"IRQ %d, node addr %pM\n",
-		dev->name,
-		board_info[ent->driver_data].name,
-		((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
-		((CHIP_ID(bp) & 0x0ff0) >> 4),
-		bnx2_bus_string(bp, str),
-		dev->base_addr,
-		bp->pdev->irq, dev->dev_addr);
+	netdev_info(dev, "%s (%c%d) %s found at mem %lx, IRQ %d, node addr %pM\n",
+		    board_info[ent->driver_data].name,
+		    ((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
+		    ((CHIP_ID(bp) & 0x0ff0) >> 4),
+		    bnx2_bus_string(bp, str),
+		    dev->base_addr,
+		    bp->pdev->irq, dev->dev_addr);
 
 	return 0;
 
@@ -8342,6 +8356,8 @@ bnx2_remove_one(struct pci_dev *pdev)
 	if (bp->regview)
 		iounmap(bp->regview);
 
+	kfree(bp->temp_stats_blk);
+
 	free_netdev(dev);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
@@ -8363,7 +8379,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_me
 		return 0;
 
 	flush_scheduled_work();
-	bnx2_netif_stop(bp);
+	bnx2_netif_stop(bp, true);
 	netif_device_detach(dev);
 	del_timer_sync(&bp->timer);
 	bnx2_shutdown_chip(bp);
@@ -8385,7 +8401,7 @@ bnx2_resume(struct pci_dev *pdev)
 	bnx2_set_power_state(bp, PCI_D0);
 	netif_device_attach(dev);
 	bnx2_init_nic(bp, 1);
-	bnx2_netif_start(bp);
+	bnx2_netif_start(bp, true);
 	return 0;
 }
 
@@ -8412,7 +8428,7 @@ static pci_ers_result_t bnx2_io_error_de
 	}
 
 	if (netif_running(dev)) {
-		bnx2_netif_stop(bp);
+		bnx2_netif_stop(bp, true);
 		del_timer_sync(&bp->timer);
 		bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET);
 	}
@@ -8438,7 +8454,7 @@ static pci_ers_result_t bnx2_io_slot_res
 	rtnl_lock();
 	if (pci_enable_device(pdev)) {
 		dev_err(&pdev->dev,
-			"Cannot re-enable PCI device after reset.\n");
+			"Cannot re-enable PCI device after reset\n");
 		rtnl_unlock();
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
@@ -8469,7 +8485,7 @@ static void bnx2_io_resume(struct pci_de
 
 	rtnl_lock();
 	if (netif_running(dev))
-		bnx2_netif_start(bp);
+		bnx2_netif_start(bp, true);
 
 	netif_device_attach(dev);
 	rtnl_unlock();
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/bnx2.h linux-libre-2.6.34-gnu1/drivers/net/bnx2.h
--- linux-libre-2.6.33-gnu1/drivers/net/bnx2.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/bnx2.h	2010-05-16 17:17:36.000000000 -0400
@@ -349,7 +349,7 @@ struct l2_fhdr {
 #define BNX2_L2CTX_BD_PRE_READ				0x00000000
 #define BNX2_L2CTX_CTX_SIZE				0x00000000
 #define BNX2_L2CTX_CTX_TYPE				0x00000000
-#define BNX2_L2CTX_LO_WATER_MARK_DEFAULT		 32
+#define BNX2_L2CTX_LO_WATER_MARK_DEFAULT		 4
 #define BNX2_L2CTX_LO_WATER_MARK_SCALE			 4
 #define BNX2_L2CTX_LO_WATER_MARK_DIS			 0
 #define BNX2_L2CTX_HI_WATER_MARK_SHIFT			 4
@@ -6851,6 +6851,7 @@ struct bnx2 {
 	dma_addr_t		status_blk_mapping;
 
 	struct statistics_block	*stats_blk;
+	struct statistics_block	*temp_stats_blk;
 	dma_addr_t		stats_blk_mapping;
 
 	int			ctx_pages;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/bnx2x_fw_defs.h linux-libre-2.6.34-gnu1/drivers/net/bnx2x_fw_defs.h
--- linux-libre-2.6.33-gnu1/drivers/net/bnx2x_fw_defs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/bnx2x_fw_defs.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_fw_defs.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2009 Broadcom Corporation
+ * Copyright (c) 2007-2010 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
@@ -471,6 +471,11 @@
 
 
 /* Host coalescing constants */
+#define HC_IGU_BC_MODE 0
+#define HC_IGU_NBC_MODE 1
+
+#define HC_REGULAR_SEGMENT 0
+#define HC_DEFAULT_SEGMENT 1
 
 /* index numbers */
 #define HC_USTORM_DEF_SB_NUM_INDICES 8
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/bnx2x.h linux-libre-2.6.34-gnu1/drivers/net/bnx2x.h
--- linux-libre-2.6.33-gnu1/drivers/net/bnx2x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/bnx2x.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2009 Broadcom Corporation
+ * Copyright (c) 2007-2010 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
@@ -44,7 +44,6 @@
 /* error/debug prints */
 
 #define DRV_MODULE_NAME		"bnx2x"
-#define PFX DRV_MODULE_NAME	": "
 
 /* for messages that are currently off */
 #define BNX2X_MSG_OFF			0
@@ -58,30 +57,40 @@
 #define DP_LEVEL			KERN_NOTICE	/* was: KERN_DEBUG */
 
 /* regular debug print */
-#define DP(__mask, __fmt, __args...) do { \
-	if (bp->msglevel & (__mask)) \
-		printk(DP_LEVEL "[%s:%d(%s)]" __fmt, __func__, __LINE__, \
-			bp->dev ? (bp->dev->name) : "?", ##__args); \
-	} while (0)
+#define DP(__mask, __fmt, __args...)				\
+do {								\
+	if (bp->msg_enable & (__mask))				\
+		printk(DP_LEVEL "[%s:%d(%s)]" __fmt,		\
+		       __func__, __LINE__,			\
+		       bp->dev ? (bp->dev->name) : "?",		\
+		       ##__args);				\
+} while (0)
 
 /* errors debug print */
-#define BNX2X_DBG_ERR(__fmt, __args...) do { \
-	if (bp->msglevel & NETIF_MSG_PROBE) \
-		printk(KERN_ERR "[%s:%d(%s)]" __fmt, __func__, __LINE__, \
-			bp->dev ? (bp->dev->name) : "?", ##__args); \
-	} while (0)
+#define BNX2X_DBG_ERR(__fmt, __args...)				\
+do {								\
+	if (netif_msg_probe(bp))				\
+		pr_err("[%s:%d(%s)]" __fmt,			\
+		       __func__, __LINE__,			\
+		       bp->dev ? (bp->dev->name) : "?",		\
+		       ##__args);				\
+} while (0)
 
 /* for errors (never masked) */
-#define BNX2X_ERR(__fmt, __args...) do { \
-	printk(KERN_ERR "[%s:%d(%s)]" __fmt, __func__, __LINE__, \
-		bp->dev ? (bp->dev->name) : "?", ##__args); \
-	} while (0)
+#define BNX2X_ERR(__fmt, __args...)				\
+do {								\
+	pr_err("[%s:%d(%s)]" __fmt,				\
+	       __func__, __LINE__,				\
+	       bp->dev ? (bp->dev->name) : "?",			\
+	       ##__args);					\
+} while (0)
 
 /* before we have a dev->name use dev_info() */
-#define BNX2X_DEV_INFO(__fmt, __args...) do { \
-	if (bp->msglevel & NETIF_MSG_PROBE) \
-		dev_info(&bp->pdev->dev, __fmt, ##__args); \
-	} while (0)
+#define BNX2X_DEV_INFO(__fmt, __args...)			 \
+do {								 \
+	if (netif_msg_probe(bp))				 \
+		dev_info(&bp->pdev->dev, __fmt, ##__args);	 \
+} while (0)
 
 
 #ifdef BNX2X_STOP_ON_ERROR
@@ -130,7 +139,7 @@
 				 offset, len32); \
 	} while (0)
 
-#define VIRT_WR_DMAE_LEN(bp, data, addr, len32) \
+#define VIRT_WR_DMAE_LEN(bp, data, addr, len32, le32_swap) \
 	do { \
 		memcpy(GUNZIP_BUF(bp), data, (len32) * 4); \
 		bnx2x_write_big_buf_wb(bp, addr, len32); \
@@ -882,7 +891,7 @@ struct bnx2x {
 	/* End of fields used in the performance code paths */
 
 	int			panic;
-	int			msglevel;
+	int			msg_enable;
 
 	u32			flags;
 #define PCIX_FLAG			1
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/bnx2x_hsi.h linux-libre-2.6.34-gnu1/drivers/net/bnx2x_hsi.h
--- linux-libre-2.6.33-gnu1/drivers/net/bnx2x_hsi.h	2013-05-03 12:07:57.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/bnx2x_hsi.h	2013-05-03 09:47:20.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_hsi.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2009 Broadcom Corporation
+ * Copyright (c) 2007-2010 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
@@ -2429,8 +2429,10 @@ struct common_ramrod_eth_rx_cqe {
 	u8 ramrod_type;
 #define COMMON_RAMROD_ETH_RX_CQE_TYPE (0x1<<0)
 #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
+#define COMMON_RAMROD_ETH_RX_CQE_ERROR (0x1<<1)
+#define COMMON_RAMROD_ETH_RX_CQE_ERROR_SHIFT 1
+#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0 (0x3F<<2)
+#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0_SHIFT 2
 	u8 conn_type;
 	__le16 reserved1;
 	__le32 conn_and_cmd_data;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/bnx2x_init_ops.h linux-libre-2.6.34-gnu1/drivers/net/bnx2x_init_ops.h
--- linux-libre-2.6.33-gnu1/drivers/net/bnx2x_init_ops.h	2013-05-03 12:07:59.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/bnx2x_init_ops.h	2013-05-03 09:47:22.000000000 -0400
@@ -2,7 +2,7 @@
  *               Static functions needed during the initialization.
  *               This file is "included" in bnx2x_main.c.
  *
- * Copyright (c) 2007-2009 Broadcom Corporation
+ * Copyright (c) 2007-2010 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
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/bnx2x_link.c linux-libre-2.6.34-gnu1/drivers/net/bnx2x_link.c
--- linux-libre-2.6.33-gnu1/drivers/net/bnx2x_link.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/bnx2x_link.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/pci.h>
@@ -2987,11 +2989,8 @@ static u8 bnx2x_verify_sfp_module(struct
 	else
 		vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
 
-	printk(KERN_INFO PFX  "Warning: "
-			 "Unqualified SFP+ module "
-			 "detected on %s, Port %d from %s part number %s\n"
-			, bp->dev->name, params->port,
-			vendor_name, vendor_pn);
+	netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected, Port %d from %s part number %s\n",
+		    params->port, vendor_name, vendor_pn);
 	return -EINVAL;
 }
 
@@ -4846,16 +4845,8 @@ static u8 bnx2x_ext_phy_is_link_up(struc
 						     " has been detected on "
 						     "port %d\n",
 						 params->port);
-					printk(KERN_ERR PFX  "Error:  Power"
-						 " fault on %s Port %d has"
-						 " been detected and the"
-						 " power to that SFP+ module"
-						 " has been removed to prevent"
-						 " failure of the card. Please"
-						 " remove the SFP+ module and"
-						 " restart the system to clear"
-						 " this error.\n"
-			, bp->dev->name, params->port);
+					netdev_err(bp->dev, "Error:  Power fault on Port %d has been detected and the power to that SFP+ module has been removed to prevent failure of the card. Please remove the SFP+ module and restart the system to clear this error.\n",
+						   params->port);
 					/*
 					 * Disable all RX_ALARMs except for
 					 * mod_abs
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/bnx2x_main.c linux-libre-2.6.34-gnu1/drivers/net/bnx2x_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/bnx2x_main.c	2013-05-03 12:07:54.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/bnx2x_main.c	2013-05-03 09:47:17.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_main.c: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2009 Broadcom Corporation
+ * Copyright (c) 2007-2010 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
@@ -57,11 +57,11 @@
 #include "bnx2x_init_ops.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),\
+  return (printk(KERN_ERR "%s: Missing Free firmware\n", bp->dev->name),\
 	  -EINVAL)
 
-#define DRV_MODULE_VERSION	"1.52.1-5"
-#define DRV_MODULE_RELDATE	"2009/11/09"
+#define DRV_MODULE_VERSION	"1.52.1-7"
+#define DRV_MODULE_RELDATE	"2010/02/28"
 #define BNX2X_BC_VER		0x040200
 
 #include <linux/firmware.h>
@@ -138,7 +138,7 @@ static struct {
 };
 
 
-static const struct pci_device_id bnx2x_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(bnx2x_pci_tbl) = {
 	{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57710), BCM57710 },
 	{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711), BCM57711 },
 	{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711E), BCM57711E },
@@ -512,24 +512,24 @@ static void bnx2x_fw_dump(struct bnx2x *
 
 	mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104);
 	mark = ((mark + 0x3) & ~0x3);
-	printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n", mark);
+	pr_err("begin fw dump (mark 0x%x)\n", mark);
 
-	printk(KERN_ERR PFX);
+	pr_err("");
 	for (offset = mark - 0x08000000; offset <= 0xF900; offset += 0x8*4) {
 		for (word = 0; word < 8; word++)
 			data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
 						  offset + 4*word));
 		data[8] = 0x0;
-		printk(KERN_CONT "%s", (char *)data);
+		pr_cont("%s", (char *)data);
 	}
 	for (offset = 0xF108; offset <= mark - 0x08000000; offset += 0x8*4) {
 		for (word = 0; word < 8; word++)
 			data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
 						  offset + 4*word));
 		data[8] = 0x0;
-		printk(KERN_CONT "%s", (char *)data);
+		pr_cont("%s", (char *)data);
 	}
-	printk(KERN_ERR PFX "end of fw dump\n");
+	pr_err("end of fw dump\n");
 }
 
 static void bnx2x_panic_dump(struct bnx2x *bp)
@@ -891,7 +891,6 @@ static inline u16 bnx2x_tx_avail(struct
 	u16 prod;
 	u16 cons;
 
-	barrier(); /* Tell compiler that prod and cons can change */
 	prod = fp->tx_bd_prod;
 	cons = fp->tx_bd_cons;
 
@@ -955,21 +954,34 @@ static int bnx2x_tx_int(struct bnx2x_fas
 	fp->tx_pkt_cons = sw_cons;
 	fp->tx_bd_cons = bd_cons;
 
+	/* 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();
+
 	/* TBD need a thresh? */
 	if (unlikely(netif_tx_queue_stopped(txq))) {
-
-		/* 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.
+		/* Taking tx_lock() is needed to prevent reenabling the queue
+		 * while it's empty. This could have happen if rx_action() gets
+		 * suspended in bnx2x_tx_int() after the condition before
+		 * netif_tx_wake_queue(), while tx_action (bnx2x_start_xmit()):
+		 *
+		 * stops the queue->sees fresh tx_bd_cons->releases the queue->
+		 * sends some packets consuming the whole queue again->
+		 * stops the queue
 		 */
-		smp_mb();
+
+		__netif_tx_lock(txq, smp_processor_id());
 
 		if ((netif_tx_queue_stopped(txq)) &&
 		    (bp->state == BNX2X_STATE_OPEN) &&
 		    (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3))
 			netif_tx_wake_queue(txq);
+
+		__netif_tx_unlock(txq);
 	}
 	return 0;
 }
@@ -2134,7 +2146,7 @@ static void bnx2x_link_report(struct bnx
 {
 	if (bp->flags & MF_FUNC_DIS) {
 		netif_carrier_off(bp->dev);
-		printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
+		netdev_err(bp->dev, "NIC Link is Down\n");
 		return;
 	}
 
@@ -2143,7 +2155,7 @@ static void bnx2x_link_report(struct bnx
 
 		if (bp->state == BNX2X_STATE_OPEN)
 			netif_carrier_on(bp->dev);
-		printk(KERN_INFO PFX "%s NIC Link is Up, ", bp->dev->name);
+		netdev_info(bp->dev, "NIC Link is Up, ");
 
 		line_speed = bp->link_vars.line_speed;
 		if (IS_E1HMF(bp)) {
@@ -2155,29 +2167,29 @@ static void bnx2x_link_report(struct bnx
 			if (vn_max_rate < line_speed)
 				line_speed = vn_max_rate;
 		}
-		printk("%d Mbps ", line_speed);
+		pr_cont("%d Mbps ", line_speed);
 
 		if (bp->link_vars.duplex == DUPLEX_FULL)
-			printk("full duplex");
+			pr_cont("full duplex");
 		else
-			printk("half duplex");
+			pr_cont("half duplex");
 
 		if (bp->link_vars.flow_ctrl != BNX2X_FLOW_CTRL_NONE) {
 			if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) {
-				printk(", receive ");
+				pr_cont(", receive ");
 				if (bp->link_vars.flow_ctrl &
 				    BNX2X_FLOW_CTRL_TX)
-					printk("& transmit ");
+					pr_cont("& transmit ");
 			} else {
-				printk(", transmit ");
+				pr_cont(", transmit ");
 			}
-			printk("flow control ON");
+			pr_cont("flow control ON");
 		}
-		printk("\n");
+		pr_cont("\n");
 
 	} else { /* link_down */
 		netif_carrier_off(bp->dev);
-		printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
+		netdev_err(bp->dev, "NIC Link is Down\n");
 	}
 }
 
@@ -2896,10 +2908,8 @@ static inline void bnx2x_fan_failure(str
 		 bp->link_params.ext_phy_config);
 
 	/* log the failure */
-	printk(KERN_ERR PFX "Fan Failure on Network Controller %s has caused"
-	       " the driver to shutdown the card to prevent permanent"
-	       " damage.  Please contact Dell Support for assistance\n",
-	       bp->dev->name);
+	netdev_err(bp->dev, "Fan Failure on Network Controller has caused the driver to shutdown the card to prevent permanent damage.\n"
+		   "Please contact Dell Support for assistance.\n");
 }
 
 static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
@@ -4294,7 +4304,7 @@ static void bnx2x_stats_update(struct bn
 	bnx2x_net_stats_update(bp);
 	bnx2x_drv_stats_update(bp);
 
-	if (bp->msglevel & NETIF_MSG_TIMER) {
+	if (netif_msg_timer(bp)) {
 		struct bnx2x_fastpath *fp0_rx = bp->fp;
 		struct bnx2x_fastpath *fp0_tx = bp->fp;
 		struct tstorm_per_client_stats *old_tclient =
@@ -4304,7 +4314,7 @@ static void bnx2x_stats_update(struct bn
 		struct net_device_stats *nstats = &bp->dev->stats;
 		int i;
 
-		printk(KERN_DEBUG "%s:\n", bp->dev->name);
+		netdev_printk(KERN_DEBUG, bp->dev, "\n");
 		printk(KERN_DEBUG "  tx avail (%4x)  tx hc idx (%x)"
 				  "  tx pkt (%lx)\n",
 		       bnx2x_tx_avail(fp0_tx),
@@ -4462,7 +4472,7 @@ static void bnx2x_stats_handle(struct bn
 	/* Make sure the state has been "changed" */
 	smp_wmb();
 
-	if ((event != STATS_EVENT_UPDATE) || (bp->msglevel & NETIF_MSG_TIMER))
+	if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp))
 		DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n",
 		   state, event, bp->stats_state);
 }
@@ -5672,8 +5682,7 @@ gunzip_nomem2:
 	bp->gunzip_buf = NULL;
 
 gunzip_nomem1:
-	printk(KERN_ERR PFX "%s: Cannot allocate firmware buffer for"
-	       " un-compression\n", bp->dev->name);
+	netdev_err(bp->dev, "Cannot allocate firmware buffer for un-compression\n");
 	return -ENOMEM;
 }
 
@@ -5719,14 +5728,13 @@ static int bnx2x_gunzip(struct bnx2x *bp
 
 	rc = zlib_inflate(bp->strm, Z_FINISH);
 	if ((rc != Z_OK) && (rc != Z_STREAM_END))
-		printk(KERN_ERR PFX "%s: Firmware decompression error: %s\n",
-		       bp->dev->name, bp->strm->msg);
+		netdev_err(bp->dev, "Firmware decompression error: %s\n",
+			   bp->strm->msg);
 
 	bp->gunzip_outlen = (FW_BUF_SIZE - bp->strm->avail_out);
 	if (bp->gunzip_outlen & 0x3)
-		printk(KERN_ERR PFX "%s: Firmware decompression error:"
-				    " gunzip_outlen (%d) not aligned\n",
-		       bp->dev->name, bp->gunzip_outlen);
+		netdev_err(bp->dev, "Firmware decompression error: gunzip_outlen (%d) not aligned\n",
+			   bp->gunzip_outlen);
 	bp->gunzip_outlen >>= 2;
 
 	zlib_inflateEnd(bp->strm);
@@ -6211,8 +6219,8 @@ static int bnx2x_init_common(struct bnx2
 
 	if (sizeof(union cdu_context) != 1024)
 		/* we currently assume that a context is 1024 bytes */
-		printk(KERN_ALERT PFX "please adjust the size of"
-		       " cdu_context(%ld)\n", (long)sizeof(union cdu_context));
+		pr_alert("please adjust the size of cdu_context(%ld)\n",
+			 (long)sizeof(union cdu_context));
 
 	bnx2x_init_block(bp, CDU_BLOCK, COMMON_STAGE);
 	val = (4 << 24) + (0 << 12) + 1024;
@@ -6936,19 +6944,21 @@ static void bnx2x_free_msix_irqs(struct
 	}
 }
 
-static void bnx2x_free_irq(struct bnx2x *bp)
+static void bnx2x_free_irq(struct bnx2x *bp, bool disable_only)
 {
 	if (bp->flags & USING_MSIX_FLAG) {
-		bnx2x_free_msix_irqs(bp);
+		if (!disable_only)
+			bnx2x_free_msix_irqs(bp);
 		pci_disable_msix(bp->pdev);
 		bp->flags &= ~USING_MSIX_FLAG;
 
 	} else if (bp->flags & USING_MSI_FLAG) {
-		free_irq(bp->pdev->irq, bp->dev);
+		if (!disable_only)
+			free_irq(bp->pdev->irq, bp->dev);
 		pci_disable_msi(bp->pdev);
 		bp->flags &= ~USING_MSI_FLAG;
 
-	} else
+	} else if (!disable_only)
 		free_irq(bp->pdev->irq, bp->dev);
 }
 
@@ -7016,11 +7026,10 @@ static int bnx2x_req_msix_irqs(struct bn
 	}
 
 	i = BNX2X_NUM_QUEUES(bp);
-	printk(KERN_INFO PFX "%s: using MSI-X  IRQs: sp %d  fp[%d] %d"
-	       " ... fp[%d] %d\n",
-	       bp->dev->name, bp->msix_table[0].vector,
-	       0, bp->msix_table[offset].vector,
-	       i - 1, bp->msix_table[offset + i - 1].vector);
+	netdev_info(bp->dev, "using MSI-X  IRQs: sp %d  fp[%d] %d ... fp[%d] %d\n",
+		    bp->msix_table[0].vector,
+		    0, bp->msix_table[offset].vector,
+		    i - 1, bp->msix_table[offset + i - 1].vector);
 
 	return 0;
 }
@@ -7441,8 +7450,10 @@ static int bnx2x_nic_load(struct bnx2x *
 
 	rc = bnx2x_set_num_queues(bp);
 
-	if (bnx2x_alloc_mem(bp))
+	if (bnx2x_alloc_mem(bp)) {
+		bnx2x_free_irq(bp, true);
 		return -ENOMEM;
+	}
 
 	for_each_queue(bp, i)
 		bnx2x_fp(bp, i, disable_tpa) =
@@ -7457,7 +7468,7 @@ static int bnx2x_nic_load(struct bnx2x *
 	if (bp->flags & USING_MSIX_FLAG) {
 		rc = bnx2x_req_msix_irqs(bp);
 		if (rc) {
-			pci_disable_msix(bp->pdev);
+			bnx2x_free_irq(bp, true);
 			goto load_error1;
 		}
 	} else {
@@ -7469,14 +7480,13 @@ static int bnx2x_nic_load(struct bnx2x *
 		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);
+			bnx2x_free_irq(bp, true);
 			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);
+			netdev_info(bp->dev, "using MSI  IRQ %d\n",
+				    bp->pdev->irq);
 		}
 	}
 
@@ -7525,6 +7535,9 @@ static int bnx2x_nic_load(struct bnx2x *
 	rc = bnx2x_init_hw(bp, load_code);
 	if (rc) {
 		BNX2X_ERR("HW init failed, aborting\n");
+		bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
+		bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP);
+		bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
 		goto load_error2;
 	}
 
@@ -7662,7 +7675,7 @@ load_error3:
 		bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
 load_error2:
 	/* Release IRQs */
-	bnx2x_free_irq(bp);
+	bnx2x_free_irq(bp, false);
 load_error1:
 	bnx2x_napi_disable(bp);
 	for_each_queue(bp, i)
@@ -7853,7 +7866,7 @@ static int bnx2x_nic_unload(struct bnx2x
 	bnx2x_stats_handle(bp, STATS_EVENT_STOP);
 
 	/* Release IRQs */
-	bnx2x_free_irq(bp);
+	bnx2x_free_irq(bp, false);
 
 	/* Wait until tx fastpath tasks complete */
 	for_each_queue(bp, i) {
@@ -8295,8 +8308,7 @@ static void __devinit bnx2x_get_common_h
 	val3 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[8]);
 	val4 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[12]);
 
-	printk(KERN_INFO PFX "part number %X-%X-%X-%X\n",
-	       val, val2, val3, val4);
+	pr_info("part number %X-%X-%X-%X\n", val, val2, val3, val4);
 }
 
 static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
@@ -8907,17 +8919,15 @@ static int __devinit bnx2x_init_bp(struc
 		bnx2x_undi_unload(bp);
 
 	if (CHIP_REV_IS_FPGA(bp))
-		printk(KERN_ERR PFX "FPGA detected\n");
+		pr_err("FPGA detected\n");
 
 	if (BP_NOMCP(bp) && (func == 0))
-		printk(KERN_ERR PFX
-		       "MCP disabled, must load devices in order!\n");
+		pr_err("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");
+		pr_err("Multi disabled since int_mode requested is not MSI-X\n");
 		multi_mode = ETH_RSS_MODE_DISABLED;
 	}
 	bp->multi_mode = multi_mode;
@@ -9343,7 +9353,7 @@ static u32 bnx2x_get_msglevel(struct net
 {
 	struct bnx2x *bp = netdev_priv(dev);
 
-	return bp->msglevel;
+	return bp->msg_enable;
 }
 
 static void bnx2x_set_msglevel(struct net_device *dev, u32 level)
@@ -9351,7 +9361,7 @@ static void bnx2x_set_msglevel(struct ne
 	struct bnx2x *bp = netdev_priv(dev);
 
 	if (capable(CAP_NET_ADMIN))
-		bp->msglevel = level;
+		bp->msg_enable = level;
 }
 
 static int bnx2x_nway_reset(struct net_device *dev)
@@ -9960,12 +9970,14 @@ static int bnx2x_set_flags(struct net_de
 
 	/* TPA requires Rx CSUM offloading */
 	if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
-		if (!(dev->features & NETIF_F_LRO)) {
-			dev->features |= NETIF_F_LRO;
-			bp->flags |= TPA_ENABLE_FLAG;
-			changed = 1;
-		}
-
+		if (!disable_tpa) {
+			if (!(dev->features & NETIF_F_LRO)) {
+				dev->features |= NETIF_F_LRO;
+				bp->flags |= TPA_ENABLE_FLAG;
+				changed = 1;
+			}
+		} else
+			rc = -EINVAL;
 	} else if (dev->features & NETIF_F_LRO) {
 		dev->features &= ~NETIF_F_LRO;
 		bp->flags &= ~TPA_ENABLE_FLAG;
@@ -10423,7 +10435,8 @@ static int bnx2x_test_intr(struct bnx2x
 
 	config->hdr.length = 0;
 	if (CHIP_IS_E1(bp))
-		config->hdr.offset = (BP_PORT(bp) ? 32 : 0);
+		/* use last unicast entries */
+		config->hdr.offset = (BP_PORT(bp) ? 63 : 31);
 	else
 		config->hdr.offset = BP_FUNC(bp);
 	config->hdr.client_id = bp->fp->cl_id;
@@ -10642,7 +10655,7 @@ static const struct {
 	((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))
+			(IS_E1HMF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS))
 
 static int bnx2x_get_sset_count(struct net_device *dev, int stringset)
 {
@@ -11413,9 +11426,12 @@ static netdev_tx_t bnx2x_start_xmit(stru
 
 	if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
 		netif_tx_stop_queue(txq);
-		/* We want bnx2x_tx_int to "see" the updated tx_bd_prod
-		   if we put Tx into XOFF state. */
+
+		/* paired memory barrier is in bnx2x_tx_int(), we have to keep
+		 * ordering of set_bit() in netif_tx_stop_queue() and read of
+		 * fp->bd_tx_cons */
 		smp_mb();
+
 		fp->eth_q_stats.driver_xoff++;
 		if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
 			netif_tx_wake_queue(txq);
@@ -11469,7 +11485,8 @@ static void bnx2x_set_rx_mode(struct net
 		rx_mode = BNX2X_RX_MODE_PROMISC;
 
 	else if ((dev->flags & IFF_ALLMULTI) ||
-		 ((dev->mc_count > BNX2X_MAX_MULTICAST) && CHIP_IS_E1(bp)))
+		 ((netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) &&
+		  CHIP_IS_E1(bp)))
 		rx_mode = BNX2X_RX_MODE_ALLMULTI;
 
 	else { /* some multicasts */
@@ -11479,10 +11496,8 @@ static void bnx2x_set_rx_mode(struct net
 			struct mac_configuration_cmd *config =
 						bnx2x_sp(bp, mcast_config);
 
-			for (i = 0, mclist = dev->mc_list;
-			     mclist && (i < dev->mc_count);
-			     i++, mclist = mclist->next) {
-
+			i = 0;
+			netdev_for_each_mc_addr(mclist, dev) {
 				config->config_table[i].
 					cam_entry.msb_mac_addr =
 					swab16(*(u16 *)&mclist->dmi_addr[0]);
@@ -11510,6 +11525,7 @@ static void bnx2x_set_rx_mode(struct net
 						cam_entry.middle_mac_addr,
 				   config->config_table[i].
 						cam_entry.lsb_mac_addr);
+				i++;
 			}
 			old = config->hdr.length;
 			if (old > i) {
@@ -11551,10 +11567,7 @@ static void bnx2x_set_rx_mode(struct net
 
 			memset(mc_filter, 0, 4 * MC_HASH_SIZE);
 
-			for (i = 0, mclist = dev->mc_list;
-			     mclist && (i < dev->mc_count);
-			     i++, mclist = mclist->next) {
-
+			netdev_for_each_mc_addr(mclist, dev) {
 				DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n",
 				   mclist->dmi_addr);
 
@@ -11729,7 +11742,7 @@ static void bnx2x_vlan_rx_register(struc
 
 #endif
 
-#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
+#ifdef CONFIG_NET_POLL_CONTROLLER
 static void poll_bnx2x(struct net_device *dev)
 {
 	struct bnx2x *bp = netdev_priv(dev);
@@ -11753,7 +11766,7 @@ static const struct net_device_ops bnx2x
 #ifdef BCM_VLAN
 	.ndo_vlan_rx_register	= bnx2x_vlan_rx_register,
 #endif
-#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
+#ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= poll_bnx2x,
 #endif
 };
@@ -11774,20 +11787,18 @@ static int __devinit bnx2x_init_dev(stru
 
 	rc = pci_enable_device(pdev);
 	if (rc) {
-		printk(KERN_ERR PFX "Cannot enable PCI device, aborting\n");
+		pr_err("Cannot enable PCI device, aborting\n");
 		goto err_out;
 	}
 
 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
-		printk(KERN_ERR PFX "Cannot find PCI device base address,"
-		       " aborting\n");
+		pr_err("Cannot find PCI device base address, aborting\n");
 		rc = -ENODEV;
 		goto err_out_disable;
 	}
 
 	if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
-		printk(KERN_ERR PFX "Cannot find second PCI device"
-		       " base address, aborting\n");
+		pr_err("Cannot find second PCI device base address, aborting\n");
 		rc = -ENODEV;
 		goto err_out_disable;
 	}
@@ -11795,8 +11806,7 @@ static int __devinit bnx2x_init_dev(stru
 	if (atomic_read(&pdev->enable_cnt) == 1) {
 		rc = pci_request_regions(pdev, DRV_MODULE_NAME);
 		if (rc) {
-			printk(KERN_ERR PFX "Cannot obtain PCI resources,"
-			       " aborting\n");
+			pr_err("Cannot obtain PCI resources, aborting\n");
 			goto err_out_disable;
 		}
 
@@ -11806,16 +11816,14 @@ static int __devinit bnx2x_init_dev(stru
 
 	bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
 	if (bp->pm_cap == 0) {
-		printk(KERN_ERR PFX "Cannot find power management"
-		       " capability, aborting\n");
+		pr_err("Cannot find power management capability, aborting\n");
 		rc = -EIO;
 		goto err_out_release;
 	}
 
 	bp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
 	if (bp->pcie_cap == 0) {
-		printk(KERN_ERR PFX "Cannot find PCI Express capability,"
-		       " aborting\n");
+		pr_err("Cannot find PCI Express capability, aborting\n");
 		rc = -EIO;
 		goto err_out_release;
 	}
@@ -11823,15 +11831,13 @@ static int __devinit bnx2x_init_dev(stru
 	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) == 0) {
 		bp->flags |= USING_DAC_FLAG;
 		if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
-			printk(KERN_ERR PFX "pci_set_consistent_dma_mask"
-			       " failed, aborting\n");
+			pr_err("pci_set_consistent_dma_mask failed, aborting\n");
 			rc = -EIO;
 			goto err_out_release;
 		}
 
 	} else if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
-		printk(KERN_ERR PFX "System does not support DMA,"
-		       " aborting\n");
+		pr_err("System does not support DMA, aborting\n");
 		rc = -EIO;
 		goto err_out_release;
 	}
@@ -11844,7 +11850,7 @@ static int __devinit bnx2x_init_dev(stru
 
 	bp->regview = pci_ioremap_bar(pdev, 0);
 	if (!bp->regview) {
-		printk(KERN_ERR PFX "Cannot map register space, aborting\n");
+		pr_err("Cannot map register space, aborting\n");
 		rc = -ENOMEM;
 		goto err_out_release;
 	}
@@ -11853,7 +11859,7 @@ static int __devinit bnx2x_init_dev(stru
 					min_t(u64, BNX2X_DB_SIZE,
 					      pci_resource_len(pdev, 2)));
 	if (!bp->doorbells) {
-		printk(KERN_ERR PFX "Cannot map doorbell space, aborting\n");
+		pr_err("Cannot map doorbell space, aborting\n");
 		rc = -ENOMEM;
 		goto err_out_unmap;
 	}
@@ -11973,18 +11979,17 @@ static inline void be16_to_cpu_n(const u
 		target[i] = be16_to_cpu(source[i]);
 }
 
-#define BNX2X_ALLOC_AND_SET(arr, lbl, func) \
-	do { \
-		u32 len = be32_to_cpu(fw_hdr->arr.len); \
-		bp->arr = kmalloc(len, GFP_KERNEL); \
-		if (!bp->arr) { \
-			printk(KERN_ERR PFX "Failed to allocate %d bytes " \
-					    "for "#arr"\n", len); \
-			goto lbl; \
-		} \
-		func(bp->firmware->data + be32_to_cpu(fw_hdr->arr.offset), \
-		     (u8 *)bp->arr, len); \
-	} while (0)
+#define BNX2X_ALLOC_AND_SET(arr, lbl, func)				\
+do {									\
+	u32 len = be32_to_cpu(fw_hdr->arr.len);				\
+	bp->arr = kmalloc(len, GFP_KERNEL);				\
+	if (!bp->arr) {							\
+		pr_err("Failed to allocate %d bytes for "#arr"\n", len); \
+		goto lbl;						\
+	}								\
+	func(bp->firmware->data + be32_to_cpu(fw_hdr->arr.offset),	\
+	     (u8 *)bp->arr, len);					\
+} while (0)
 
 static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
 {
@@ -11997,18 +12002,17 @@ static int __devinit bnx2x_init_firmware
 	else
 		fw_file_name = FW_FILE_NAME_E1H;
 
-	printk(KERN_INFO PFX "Loading %s\n", fw_file_name);
+	pr_info("Loading %s\n", fw_file_name);
 
 	rc = reject_firmware(&bp->firmware, fw_file_name, dev);
 	if (rc) {
-		printk(KERN_ERR PFX "Can't load firmware file %s\n",
-		       fw_file_name);
+		pr_err("Can't load firmware file %s\n", fw_file_name);
 		goto reject_firmware_exit;
 	}
 
 	/*(DEBLOBBED)*/
 	if (rc) {
-		printk(KERN_ERR PFX "Corrupt firmware file %s\n", fw_file_name);
+		pr_err("Corrupt firmware file %s\n", fw_file_name);
 		goto reject_firmware_exit;
 	}
 
@@ -12067,12 +12071,12 @@ static int __devinit bnx2x_init_one(stru
 	/* dev zeroed in init_etherdev */
 	dev = alloc_etherdev_mq(sizeof(*bp), MAX_CONTEXT);
 	if (!dev) {
-		printk(KERN_ERR PFX "Cannot allocate net device\n");
+		pr_err("Cannot allocate net device\n");
 		return -ENOMEM;
 	}
 
 	bp = netdev_priv(dev);
-	bp->msglevel = debug;
+	bp->msg_enable = debug;
 
 	pci_set_drvdata(pdev, dev);
 
@@ -12089,7 +12093,7 @@ static int __devinit bnx2x_init_one(stru
 	/* Set init arrays */
 	rc = bnx2x_init_firmware(bp, &pdev->dev);
 	if (rc) {
-		printk(KERN_ERR PFX "Error loading firmware\n");
+		pr_err("Error loading firmware\n");
 		goto init_one_exit;
 	}
 
@@ -12100,12 +12104,11 @@ static int __devinit bnx2x_init_one(stru
 	}
 
 	bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed);
-	printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
-	       " IRQ %d, ", dev->name, board_info[ent->driver_data].name,
-	       (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4),
-	       pcie_width, (pcie_speed == 2) ? "5GHz (Gen2)" : "2.5GHz",
-	       dev->base_addr, bp->pdev->irq);
-	printk(KERN_CONT "node addr %pM\n", dev->dev_addr);
+	netdev_info(dev, "%s (%c%d) PCI-E x%d %s found at mem %lx, IRQ %d, node addr %pM\n",
+		    board_info[ent->driver_data].name,
+		    (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4),
+		    pcie_width, (pcie_speed == 2) ? "5GHz (Gen2)" : "2.5GHz",
+		    dev->base_addr, bp->pdev->irq, dev->dev_addr);
 
 	return 0;
 
@@ -12133,7 +12136,7 @@ static void __devexit bnx2x_remove_one(s
 	struct bnx2x *bp;
 
 	if (!dev) {
-		printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n");
+		pr_err("BAD net device from bnx2x_init_one\n");
 		return;
 	}
 	bp = netdev_priv(dev);
@@ -12166,7 +12169,7 @@ static int bnx2x_suspend(struct pci_dev
 	struct bnx2x *bp;
 
 	if (!dev) {
-		printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n");
+		pr_err("BAD net device from bnx2x_init_one\n");
 		return -ENODEV;
 	}
 	bp = netdev_priv(dev);
@@ -12198,7 +12201,7 @@ static int bnx2x_resume(struct pci_dev *
 	int rc;
 
 	if (!dev) {
-		printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n");
+		pr_err("BAD net device from bnx2x_init_one\n");
 		return -ENODEV;
 	}
 	bp = netdev_priv(dev);
@@ -12237,7 +12240,7 @@ static int bnx2x_eeh_nic_unload(struct b
 	DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n");
 
 	/* Release IRQs */
-	bnx2x_free_irq(bp);
+	bnx2x_free_irq(bp, false);
 
 	if (CHIP_IS_E1(bp)) {
 		struct mac_configuration_cmd *config =
@@ -12401,17 +12404,17 @@ static int __init bnx2x_init(void)
 {
 	int ret;
 
-	printk(KERN_INFO "%s", version);
+	pr_info("%s", version);
 
 	bnx2x_wq = create_singlethread_workqueue("bnx2x");
 	if (bnx2x_wq == NULL) {
-		printk(KERN_ERR PFX "Cannot create workqueue\n");
+		pr_err("Cannot create workqueue\n");
 		return -ENOMEM;
 	}
 
 	ret = pci_register_driver(&bnx2x_pci_driver);
 	if (ret) {
-		printk(KERN_ERR PFX "Cannot register driver\n");
+		pr_err("Cannot register driver\n");
 		destroy_workqueue(bnx2x_wq);
 	}
 	return ret;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/bonding/bonding.h linux-libre-2.6.34-gnu1/drivers/net/bonding/bonding.h
--- linux-libre-2.6.33-gnu1/drivers/net/bonding/bonding.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/bonding/bonding.h	2010-05-16 17:17:36.000000000 -0400
@@ -197,7 +197,6 @@ struct bonding {
 	s8	 send_grat_arp;
 	s8	 send_unsol_na;
 	s8	 setup_by_slave;
-	struct   net_device_stats stats;
 #ifdef CONFIG_PROC_FS
 	struct   proc_dir_entry *proc_entry;
 	char     proc_file_name[IFNAMSIZ];
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/bonding/bond_main.c linux-libre-2.6.34-gnu1/drivers/net/bonding/bond_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/bonding/bond_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/bonding/bond_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -1235,6 +1235,11 @@ void bond_change_active_slave(struct bon
 			write_lock_bh(&bond->curr_slave_lock);
 		}
 	}
+
+	/* resend IGMP joins since all were sent on curr_active_slave */
+	if (bond->params.mode == BOND_MODE_ROUNDROBIN) {
+		bond_resend_igmp_join_requests(bond);
+	}
 }
 
 /**
@@ -2615,6 +2620,17 @@ static int bond_arp_rcv(struct sk_buff *
 	unsigned char *arp_ptr;
 	__be32 sip, tip;
 
+	if (dev->priv_flags & IFF_802_1Q_VLAN) {
+		/*
+		 * When using VLANS and bonding, dev and oriv_dev may be
+		 * incorrect if the physical interface supports VLAN
+		 * acceleration.  With this change ARP validation now
+		 * works for hosts only reachable on the VLAN interface.
+		 */
+		dev = vlan_dev_real_dev(dev);
+		orig_dev = dev_get_by_index_rcu(dev_net(skb->dev),skb->skb_iif);
+	}
+
 	if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER))
 		goto out;
 
@@ -3296,7 +3312,7 @@ static void bond_remove_proc_entry(struc
 /* Create the bonding directory under /proc/net, if doesn't exist yet.
  * Caller must hold rtnl_lock.
  */
-static void bond_create_proc_dir(struct bond_net *bn)
+static void __net_init bond_create_proc_dir(struct bond_net *bn)
 {
 	if (!bn->proc_dir) {
 		bn->proc_dir = proc_mkdir(DRV_NAME, bn->net->proc_net);
@@ -3309,7 +3325,7 @@ static void bond_create_proc_dir(struct
 /* Destroy the bonding directory under /proc/net, if empty.
  * Caller must hold rtnl_lock.
  */
-static void bond_destroy_proc_dir(struct bond_net *bn)
+static void __net_exit bond_destroy_proc_dir(struct bond_net *bn)
 {
 	if (bn->proc_dir) {
 		remove_proc_entry(DRV_NAME, bn->net->proc_net);
@@ -3327,11 +3343,11 @@ static void bond_remove_proc_entry(struc
 {
 }
 
-static void bond_create_proc_dir(struct bond_net *bn)
+static inline void bond_create_proc_dir(struct bond_net *bn)
 {
 }
 
-static void bond_destroy_proc_dir(struct bond_net *bn)
+static inline void bond_destroy_proc_dir(struct bond_net *bn)
 {
 }
 
@@ -3731,7 +3747,7 @@ static int bond_close(struct net_device
 static struct net_device_stats *bond_get_stats(struct net_device *bond_dev)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
-	struct net_device_stats *stats = &bond->stats;
+	struct net_device_stats *stats = &bond_dev->stats;
 	struct net_device_stats local_stats;
 	struct slave *slave;
 	int i;
@@ -4127,22 +4143,41 @@ static int bond_xmit_roundrobin(struct s
 	struct bonding *bond = netdev_priv(bond_dev);
 	struct slave *slave, *start_at;
 	int i, slave_no, res = 1;
+	struct iphdr *iph = ip_hdr(skb);
 
 	read_lock(&bond->lock);
 
 	if (!BOND_IS_OK(bond))
 		goto out;
-
 	/*
-	 * Concurrent TX may collide on rr_tx_counter; we accept that
-	 * as being rare enough not to justify using an atomic op here
+	 * Start with the curr_active_slave that joined the bond as the
+	 * default for sending IGMP traffic.  For failover purposes one
+	 * needs to maintain some consistency for the interface that will
+	 * send the join/membership reports.  The curr_active_slave found
+	 * will send all of this type of traffic.
 	 */
-	slave_no = bond->rr_tx_counter++ % bond->slave_cnt;
+	if ((iph->protocol == IPPROTO_IGMP) &&
+	    (skb->protocol == htons(ETH_P_IP))) {
 
-	bond_for_each_slave(bond, slave, i) {
-		slave_no--;
-		if (slave_no < 0)
-			break;
+		read_lock(&bond->curr_slave_lock);
+		slave = bond->curr_active_slave;
+		read_unlock(&bond->curr_slave_lock);
+
+		if (!slave)
+			goto out;
+	} else {
+		/*
+		 * Concurrent TX may collide on rr_tx_counter; we accept
+		 * that as being rare enough not to justify using an
+		 * atomic op here.
+		 */
+		slave_no = bond->rr_tx_counter++ % bond->slave_cnt;
+
+		bond_for_each_slave(bond, slave, i) {
+			slave_no--;
+			if (slave_no < 0)
+				break;
+		}
 	}
 
 	start_at = slave;
@@ -4415,6 +4450,14 @@ static const struct net_device_ops bond_
 	.ndo_vlan_rx_kill_vid	= bond_vlan_rx_kill_vid,
 };
 
+static void bond_destructor(struct net_device *bond_dev)
+{
+	struct bonding *bond = netdev_priv(bond_dev);
+	if (bond->wq)
+		destroy_workqueue(bond->wq);
+	free_netdev(bond_dev);
+}
+
 static void bond_setup(struct net_device *bond_dev)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
@@ -4435,7 +4478,7 @@ static void bond_setup(struct net_device
 	bond_dev->ethtool_ops = &bond_ethtool_ops;
 	bond_set_mode_ops(bond, bond->params.mode);
 
-	bond_dev->destructor = free_netdev;
+	bond_dev->destructor = bond_destructor;
 
 	/* Initialize the device options */
 	bond_dev->tx_queue_len = 0;
@@ -4507,9 +4550,6 @@ static void bond_uninit(struct net_devic
 
 	bond_remove_proc_entry(bond);
 
-	if (bond->wq)
-		destroy_workqueue(bond->wq);
-
 	netif_addr_lock_bh(bond_dev);
 	bond_mc_list_destroy(bond);
 	netif_addr_unlock_bh(bond_dev);
@@ -4921,8 +4961,8 @@ int bond_create(struct net *net, const c
 				bond_setup);
 	if (!bond_dev) {
 		pr_err("%s: eek! can't alloc netdev!\n", name);
-		res = -ENOMEM;
-		goto out;
+		rtnl_unlock();
+		return -ENOMEM;
 	}
 
 	dev_net_set(bond_dev, net);
@@ -4931,20 +4971,19 @@ int bond_create(struct net *net, const c
 	if (!name) {
 		res = dev_alloc_name(bond_dev, "bond%d");
 		if (res < 0)
-			goto out_netdev;
+			goto out;
 	}
 
 	res = register_netdevice(bond_dev);
 
 out:
 	rtnl_unlock();
+	if (res < 0)
+		bond_destructor(bond_dev);
 	return res;
-out_netdev:
-	free_netdev(bond_dev);
-	goto out;
 }
 
-static int bond_net_init(struct net *net)
+static int __net_init bond_net_init(struct net *net)
 {
 	struct bond_net *bn = net_generic(net, bond_net_id);
 
@@ -4956,7 +4995,7 @@ static int bond_net_init(struct net *net
 	return 0;
 }
 
-static void bond_net_exit(struct net *net)
+static void __net_exit bond_net_exit(struct net *net)
 {
 	struct bond_net *bn = net_generic(net, bond_net_id);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/bonding/bond_sysfs.c linux-libre-2.6.34-gnu1/drivers/net/bonding/bond_sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/net/bonding/bond_sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/bonding/bond_sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,7 +51,9 @@
  * "show" function for the bond_masters attribute.
  * The class parameter is ignored.
  */
-static ssize_t bonding_show_bonds(struct class *cls, char *buf)
+static ssize_t bonding_show_bonds(struct class *cls,
+				  struct class_attribute *attr,
+				  char *buf)
 {
 	struct net *net = current->nsproxy->net_ns;
 	struct bond_net *bn = net_generic(net, bond_net_id);
@@ -98,6 +100,7 @@ static struct net_device *bond_get_by_na
  */
 
 static ssize_t bonding_store_bonds(struct class *cls,
+				   struct class_attribute *attr,
 				   const char *buffer, size_t count)
 {
 	struct net *net = current->nsproxy->net_ns;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/at91_can.c linux-libre-2.6.34-gnu1/drivers/net/can/at91_can.c
--- linux-libre-2.6.33-gnu1/drivers/net/can/at91_can.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/at91_can.c	2010-05-16 17:17:36.000000000 -0400
@@ -342,6 +342,9 @@ static netdev_tx_t at91_start_xmit(struc
 	unsigned int mb, prio;
 	u32 reg_mid, reg_mcr;
 
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
+
 	mb = get_tx_next_mb(priv);
 	prio = get_tx_next_prio(priv);
 
@@ -1070,6 +1073,7 @@ static int __init at91_can_probe(struct
 	priv->can.bittiming_const = &at91_bittiming_const;
 	priv->can.do_set_bittiming = at91_set_bittiming;
 	priv->can.do_set_mode = at91_set_mode;
+	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 	priv->reg_base = addr;
 	priv->dev = dev;
 	priv->clk = clk;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/bfin_can.c linux-libre-2.6.34-gnu1/drivers/net/can/bfin_can.c
--- linux-libre-2.6.33-gnu1/drivers/net/can/bfin_can.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/bfin_can.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,94 +22,12 @@
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
 
+#include <asm/bfin_can.h>
 #include <asm/portmux.h>
 
 #define DRV_NAME "bfin_can"
 #define BFIN_CAN_TIMEOUT 100
-
-/*
- * transmit and receive channels
- */
-#define TRANSMIT_CHL            24
-#define RECEIVE_STD_CHL         0
-#define RECEIVE_EXT_CHL         4
-#define RECEIVE_RTR_CHL         8
-#define RECEIVE_EXT_RTR_CHL     12
-#define MAX_CHL_NUMBER          32
-
-/*
- * bfin can registers layout
- */
-struct bfin_can_mask_regs {
-	u16 aml;
-	u16 dummy1;
-	u16 amh;
-	u16 dummy2;
-};
-
-struct bfin_can_channel_regs {
-	u16 data[8];
-	u16 dlc;
-	u16 dummy1;
-	u16 tsv;
-	u16 dummy2;
-	u16 id0;
-	u16 dummy3;
-	u16 id1;
-	u16 dummy4;
-};
-
-struct bfin_can_regs {
-	/*
-	 * global control and status registers
-	 */
-	u16 mc1;           /* offset 0 */
-	u16 dummy1;
-	u16 md1;           /* offset 4 */
-	u16 rsv1[13];
-	u16 mbtif1;        /* offset 0x20 */
-	u16 dummy2;
-	u16 mbrif1;        /* offset 0x24 */
-	u16 dummy3;
-	u16 mbim1;         /* offset 0x28 */
-	u16 rsv2[11];
-	u16 mc2;           /* offset 0x40 */
-	u16 dummy4;
-	u16 md2;           /* offset 0x44 */
-	u16 dummy5;
-	u16 trs2;          /* offset 0x48 */
-	u16 rsv3[11];
-	u16 mbtif2;        /* offset 0x60 */
-	u16 dummy6;
-	u16 mbrif2;        /* offset 0x64 */
-	u16 dummy7;
-	u16 mbim2;         /* offset 0x68 */
-	u16 rsv4[11];
-	u16 clk;           /* offset 0x80 */
-	u16 dummy8;
-	u16 timing;        /* offset 0x84 */
-	u16 rsv5[3];
-	u16 status;        /* offset 0x8c */
-	u16 dummy9;
-	u16 cec;           /* offset 0x90 */
-	u16 dummy10;
-	u16 gis;           /* offset 0x94 */
-	u16 dummy11;
-	u16 gim;           /* offset 0x98 */
-	u16 rsv6[3];
-	u16 ctrl;          /* offset 0xa0 */
-	u16 dummy12;
-	u16 intr;          /* offset 0xa4 */
-	u16 rsv7[7];
-	u16 esr;           /* offset 0xb4 */
-	u16 rsv8[37];
-
-	/*
-	 * channel(mailbox) mask and message registers
-	 */
-	struct bfin_can_mask_regs msk[MAX_CHL_NUMBER];    /* offset 0x100 */
-	struct bfin_can_channel_regs chl[MAX_CHL_NUMBER]; /* offset 0x200 */
-};
+#define TX_ECHO_SKB_MAX  1
 
 /*
  * bfin can private data
@@ -162,7 +80,7 @@ static int bfin_can_set_bittiming(struct
 	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
 		timing |= SAM;
 
-	bfin_write16(&reg->clk, clk);
+	bfin_write16(&reg->clock, clk);
 	bfin_write16(&reg->timing, timing);
 
 	dev_info(dev->dev.parent, "setting CLOCK=0x%04x TIMING=0x%04x\n",
@@ -184,11 +102,11 @@ static void bfin_can_set_reset_mode(stru
 	bfin_write16(&reg->gim, 0);
 
 	/* reset can and enter configuration mode */
-	bfin_write16(&reg->ctrl, SRS | CCR);
+	bfin_write16(&reg->control, SRS | CCR);
 	SSYNC();
-	bfin_write16(&reg->ctrl, CCR);
+	bfin_write16(&reg->control, CCR);
 	SSYNC();
-	while (!(bfin_read16(&reg->ctrl) & CCA)) {
+	while (!(bfin_read16(&reg->control) & CCA)) {
 		udelay(10);
 		if (--timeout == 0) {
 			dev_err(dev->dev.parent,
@@ -243,7 +161,7 @@ static void bfin_can_set_normal_mode(str
 	/*
 	 * leave configuration mode
 	 */
-	bfin_write16(&reg->ctrl, bfin_read16(&reg->ctrl) & ~CCR);
+	bfin_write16(&reg->control, bfin_read16(&reg->control) & ~CCR);
 
 	while (bfin_read16(&reg->status) & CCA) {
 		udelay(10);
@@ -318,6 +236,9 @@ static int bfin_can_start_xmit(struct sk
 	u16 val;
 	int i;
 
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
+
 	netif_stop_queue(dev);
 
 	/* fill id */
@@ -590,7 +511,7 @@ struct net_device *alloc_bfin_candev(voi
 	struct net_device *dev;
 	struct bfin_can_priv *priv;
 
-	dev = alloc_candev(sizeof(*priv));
+	dev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX);
 	if (!dev)
 		return NULL;
 
@@ -600,6 +521,7 @@ struct net_device *alloc_bfin_candev(voi
 	priv->can.bittiming_const = &bfin_can_bittiming_const;
 	priv->can.do_set_bittiming = bfin_can_set_bittiming;
 	priv->can.do_set_mode = bfin_can_set_mode;
+	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
 	return dev;
 }
@@ -721,7 +643,7 @@ static int bfin_can_suspend(struct platf
 
 	if (netif_running(dev)) {
 		/* enter sleep mode */
-		bfin_write16(&reg->ctrl, bfin_read16(&reg->ctrl) | SMR);
+		bfin_write16(&reg->control, bfin_read16(&reg->control) | SMR);
 		SSYNC();
 		while (!(bfin_read16(&reg->intr) & SMACK)) {
 			udelay(10);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/dev.c linux-libre-2.6.34-gnu1/drivers/net/can/dev.c
--- linux-libre-2.6.33-gnu1/drivers/net/can/dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/can.h>
@@ -574,6 +575,7 @@ static const struct nla_policy can_polic
 	[IFLA_CAN_BITTIMING_CONST]
 				= { .len = sizeof(struct can_bittiming_const) },
 	[IFLA_CAN_CLOCK]	= { .len = sizeof(struct can_clock) },
+	[IFLA_CAN_BERR_COUNTER]	= { .len = sizeof(struct can_berr_counter) },
 };
 
 static int can_changelink(struct net_device *dev,
@@ -592,6 +594,8 @@ static int can_changelink(struct net_dev
 		if (dev->flags & IFF_UP)
 			return -EBUSY;
 		cm = nla_data(data[IFLA_CAN_CTRLMODE]);
+		if (cm->flags & ~priv->ctrlmode_supported)
+			return -EOPNOTSUPP;
 		priv->ctrlmode &= ~cm->mask;
 		priv->ctrlmode |= cm->flags;
 	}
@@ -647,6 +651,8 @@ static size_t can_get_size(const struct
 	size += nla_total_size(sizeof(u32));  /* IFLA_CAN_RESTART_MS */
 	size += sizeof(struct can_bittiming); /* IFLA_CAN_BITTIMING */
 	size += sizeof(struct can_clock);     /* IFLA_CAN_CLOCK */
+	if (priv->do_get_berr_counter)        /* IFLA_CAN_BERR_COUNTER */
+		size += sizeof(struct can_berr_counter);
 	if (priv->bittiming_const)	      /* IFLA_CAN_BITTIMING_CONST */
 		size += sizeof(struct can_bittiming_const);
 
@@ -657,6 +663,7 @@ static int can_fill_info(struct sk_buff
 {
 	struct can_priv *priv = netdev_priv(dev);
 	struct can_ctrlmode cm = {.flags = priv->ctrlmode};
+	struct can_berr_counter bec;
 	enum can_state state = priv->state;
 
 	if (priv->do_get_state)
@@ -667,6 +674,8 @@ static int can_fill_info(struct sk_buff
 	NLA_PUT(skb, IFLA_CAN_BITTIMING,
 		sizeof(priv->bittiming), &priv->bittiming);
 	NLA_PUT(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock);
+	if (priv->do_get_berr_counter && !priv->do_get_berr_counter(dev, &bec))
+		NLA_PUT(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec);
 	if (priv->bittiming_const)
 		NLA_PUT(skb, IFLA_CAN_BITTIMING_CONST,
 			sizeof(*priv->bittiming_const), priv->bittiming_const);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/mcp251x.c linux-libre-2.6.34-gnu1/drivers/net/can/mcp251x.c
--- linux-libre-2.6.33-gnu1/drivers/net/can/mcp251x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/mcp251x.c	2010-05-16 17:17:36.000000000 -0400
@@ -73,6 +73,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/spi/spi.h>
 #include <linux/uaccess.h>
 
@@ -180,6 +181,14 @@
 #define RXBEID0_OFF 4
 #define RXBDLC_OFF  5
 #define RXBDAT_OFF  6
+#define RXFSIDH(n) ((n) * 4)
+#define RXFSIDL(n) ((n) * 4 + 1)
+#define RXFEID8(n) ((n) * 4 + 2)
+#define RXFEID0(n) ((n) * 4 + 3)
+#define RXMSIDH(n) ((n) * 4 + 0x20)
+#define RXMSIDL(n) ((n) * 4 + 0x21)
+#define RXMEID8(n) ((n) * 4 + 0x22)
+#define RXMEID0(n) ((n) * 4 + 0x23)
 
 #define GET_BYTE(val, byte)			\
 	(((val) >> ((byte) * 8)) & 0xff)
@@ -219,7 +228,8 @@ struct mcp251x_priv {
 	struct net_device *net;
 	struct spi_device *spi;
 
-	struct mutex spi_lock; /* SPI buffer lock */
+	struct mutex mcp_lock; /* SPI device lock */
+
 	u8 *spi_tx_buf;
 	u8 *spi_rx_buf;
 	dma_addr_t spi_tx_dma;
@@ -227,11 +237,11 @@ struct mcp251x_priv {
 
 	struct sk_buff *tx_skb;
 	int tx_len;
+
 	struct workqueue_struct *wq;
 	struct work_struct tx_work;
-	struct work_struct irq_work;
-	struct completion awake;
-	int wake;
+	struct work_struct restart_work;
+
 	int force_quit;
 	int after_suspend;
 #define AFTER_SUSPEND_UP 1
@@ -245,7 +255,8 @@ static void mcp251x_clean(struct net_dev
 {
 	struct mcp251x_priv *priv = netdev_priv(net);
 
-	net->stats.tx_errors++;
+	if (priv->tx_skb || priv->tx_len)
+		net->stats.tx_errors++;
 	if (priv->tx_skb)
 		dev_kfree_skb(priv->tx_skb);
 	if (priv->tx_len)
@@ -300,16 +311,12 @@ static u8 mcp251x_read_reg(struct spi_de
 	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
 	u8 val = 0;
 
-	mutex_lock(&priv->spi_lock);
-
 	priv->spi_tx_buf[0] = INSTRUCTION_READ;
 	priv->spi_tx_buf[1] = reg;
 
 	mcp251x_spi_trans(spi, 3);
 	val = priv->spi_rx_buf[2];
 
-	mutex_unlock(&priv->spi_lock);
-
 	return val;
 }
 
@@ -317,15 +324,11 @@ static void mcp251x_write_reg(struct spi
 {
 	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
 
-	mutex_lock(&priv->spi_lock);
-
 	priv->spi_tx_buf[0] = INSTRUCTION_WRITE;
 	priv->spi_tx_buf[1] = reg;
 	priv->spi_tx_buf[2] = val;
 
 	mcp251x_spi_trans(spi, 3);
-
-	mutex_unlock(&priv->spi_lock);
 }
 
 static void mcp251x_write_bits(struct spi_device *spi, u8 reg,
@@ -333,16 +336,12 @@ static void mcp251x_write_bits(struct sp
 {
 	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
 
-	mutex_lock(&priv->spi_lock);
-
 	priv->spi_tx_buf[0] = INSTRUCTION_BIT_MODIFY;
 	priv->spi_tx_buf[1] = reg;
 	priv->spi_tx_buf[2] = mask;
 	priv->spi_tx_buf[3] = val;
 
 	mcp251x_spi_trans(spi, 4);
-
-	mutex_unlock(&priv->spi_lock);
 }
 
 static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf,
@@ -358,10 +357,8 @@ static void mcp251x_hw_tx_frame(struct s
 			mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx) + i,
 					  buf[i]);
 	} else {
-		mutex_lock(&priv->spi_lock);
 		memcpy(priv->spi_tx_buf, buf, TXBDAT_OFF + len);
 		mcp251x_spi_trans(spi, TXBDAT_OFF + len);
-		mutex_unlock(&priv->spi_lock);
 	}
 }
 
@@ -408,13 +405,9 @@ static void mcp251x_hw_rx_frame(struct s
 		for (; i < (RXBDAT_OFF + len); i++)
 			buf[i] = mcp251x_read_reg(spi, RXBCTRL(buf_idx) + i);
 	} else {
-		mutex_lock(&priv->spi_lock);
-
 		priv->spi_tx_buf[RXBCTRL_OFF] = INSTRUCTION_READ_RXB(buf_idx);
 		mcp251x_spi_trans(spi, SPI_TRANSFER_BUF_LEN);
 		memcpy(buf, priv->spi_rx_buf, SPI_TRANSFER_BUF_LEN);
-
-		mutex_unlock(&priv->spi_lock);
 	}
 }
 
@@ -467,21 +460,6 @@ static void mcp251x_hw_sleep(struct spi_
 	mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_SLEEP);
 }
 
-static void mcp251x_hw_wakeup(struct spi_device *spi)
-{
-	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
-
-	priv->wake = 1;
-
-	/* Can only wake up by generating a wake-up interrupt. */
-	mcp251x_write_bits(spi, CANINTE, CANINTE_WAKIE, CANINTE_WAKIE);
-	mcp251x_write_bits(spi, CANINTF, CANINTF_WAKIF, CANINTF_WAKIF);
-
-	/* Wait until the device is awake */
-	if (!wait_for_completion_timeout(&priv->awake, HZ))
-		dev_err(&spi->dev, "MCP251x didn't wake-up\n");
-}
-
 static netdev_tx_t mcp251x_hard_start_xmit(struct sk_buff *skb,
 					   struct net_device *net)
 {
@@ -490,16 +468,11 @@ static netdev_tx_t mcp251x_hard_start_xm
 
 	if (priv->tx_skb || priv->tx_len) {
 		dev_warn(&spi->dev, "hard_xmit called while tx busy\n");
-		netif_stop_queue(net);
 		return NETDEV_TX_BUSY;
 	}
 
-	if (skb->len != sizeof(struct can_frame)) {
-		dev_err(&spi->dev, "dropping packet - bad length\n");
-		dev_kfree_skb(skb);
-		net->stats.tx_dropped++;
+	if (can_dropped_invalid_skb(net, skb))
 		return NETDEV_TX_OK;
-	}
 
 	netif_stop_queue(net);
 	priv->tx_skb = skb;
@@ -515,12 +488,13 @@ static int mcp251x_do_set_mode(struct ne
 
 	switch (mode) {
 	case CAN_MODE_START:
+		mcp251x_clean(net);
 		/* We have to delay work since SPI I/O may sleep */
 		priv->can.state = CAN_STATE_ERROR_ACTIVE;
 		priv->restart_tx = 1;
 		if (priv->can.restart_ms == 0)
 			priv->after_suspend = AFTER_SUSPEND_RESTART;
-		queue_work(priv->wq, &priv->irq_work);
+		queue_work(priv->wq, &priv->restart_work);
 		break;
 	default:
 		return -EOPNOTSUPP;
@@ -529,7 +503,7 @@ static int mcp251x_do_set_mode(struct ne
 	return 0;
 }
 
-static void mcp251x_set_normal_mode(struct spi_device *spi)
+static int mcp251x_set_normal_mode(struct spi_device *spi)
 {
 	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
 	unsigned long timeout;
@@ -537,12 +511,14 @@ static void mcp251x_set_normal_mode(stru
 	/* Enable interrupts */
 	mcp251x_write_reg(spi, CANINTE,
 			  CANINTE_ERRIE | CANINTE_TX2IE | CANINTE_TX1IE |
-			  CANINTE_TX0IE | CANINTE_RX1IE | CANINTE_RX0IE |
-			  CANINTF_MERRF);
+			  CANINTE_TX0IE | CANINTE_RX1IE | CANINTE_RX0IE);
 
 	if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
 		/* Put device into loopback mode */
 		mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LOOPBACK);
+	} else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
+		/* Put device into listen-only mode */
+		mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LISTEN_ONLY);
 	} else {
 		/* Put device into normal mode */
 		mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL);
@@ -554,11 +530,12 @@ static void mcp251x_set_normal_mode(stru
 			if (time_after(jiffies, timeout)) {
 				dev_err(&spi->dev, "MCP251x didn't"
 					" enter in normal mode\n");
-				return;
+				return -EBUSY;
 			}
 		}
 	}
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+	return 0;
 }
 
 static int mcp251x_do_set_bittiming(struct net_device *net)
@@ -589,33 +566,39 @@ static int mcp251x_setup(struct net_devi
 {
 	mcp251x_do_set_bittiming(net);
 
-	/* Enable RX0->RX1 buffer roll over and disable filters */
-	mcp251x_write_bits(spi, RXBCTRL(0),
-			   RXBCTRL_BUKT | RXBCTRL_RXM0 | RXBCTRL_RXM1,
-			   RXBCTRL_BUKT | RXBCTRL_RXM0 | RXBCTRL_RXM1);
-	mcp251x_write_bits(spi, RXBCTRL(1),
-			   RXBCTRL_RXM0 | RXBCTRL_RXM1,
-			   RXBCTRL_RXM0 | RXBCTRL_RXM1);
+	mcp251x_write_reg(spi, RXBCTRL(0),
+			  RXBCTRL_BUKT | RXBCTRL_RXM0 | RXBCTRL_RXM1);
+	mcp251x_write_reg(spi, RXBCTRL(1),
+			  RXBCTRL_RXM0 | RXBCTRL_RXM1);
 	return 0;
 }
 
-static void mcp251x_hw_reset(struct spi_device *spi)
+static int mcp251x_hw_reset(struct spi_device *spi)
 {
 	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
 	int ret;
-
-	mutex_lock(&priv->spi_lock);
+	unsigned long timeout;
 
 	priv->spi_tx_buf[0] = INSTRUCTION_RESET;
-
 	ret = spi_write(spi, priv->spi_tx_buf, 1);
-
-	mutex_unlock(&priv->spi_lock);
-
-	if (ret)
+	if (ret) {
 		dev_err(&spi->dev, "reset failed: ret = %d\n", ret);
+		return -EIO;
+	}
+
 	/* Wait for reset to finish */
+	timeout = jiffies + HZ;
 	mdelay(10);
+	while ((mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK)
+	       != CANCTRL_REQOP_CONF) {
+		schedule();
+		if (time_after(jiffies, timeout)) {
+			dev_err(&spi->dev, "MCP251x didn't"
+				" enter in conf mode after reset\n");
+			return -EBUSY;
+		}
+	}
+	return 0;
 }
 
 static int mcp251x_hw_probe(struct spi_device *spi)
@@ -639,63 +622,17 @@ static int mcp251x_hw_probe(struct spi_d
 	return (st1 == 0x80 && st2 == 0x07) ? 1 : 0;
 }
 
-static irqreturn_t mcp251x_can_isr(int irq, void *dev_id)
-{
-	struct net_device *net = (struct net_device *)dev_id;
-	struct mcp251x_priv *priv = netdev_priv(net);
-
-	/* Schedule bottom half */
-	if (!work_pending(&priv->irq_work))
-		queue_work(priv->wq, &priv->irq_work);
-
-	return IRQ_HANDLED;
-}
-
-static int mcp251x_open(struct net_device *net)
+static void mcp251x_open_clean(struct net_device *net)
 {
 	struct mcp251x_priv *priv = netdev_priv(net);
 	struct spi_device *spi = priv->spi;
 	struct mcp251x_platform_data *pdata = spi->dev.platform_data;
-	int ret;
-
-	ret = open_candev(net);
-	if (ret) {
-		dev_err(&spi->dev, "unable to set initial baudrate!\n");
-		return ret;
-	}
 
+	free_irq(spi->irq, priv);
+	mcp251x_hw_sleep(spi);
 	if (pdata->transceiver_enable)
-		pdata->transceiver_enable(1);
-
-	priv->force_quit = 0;
-	priv->tx_skb = NULL;
-	priv->tx_len = 0;
-
-	ret = request_irq(spi->irq, mcp251x_can_isr,
-			  IRQF_TRIGGER_FALLING, DEVICE_NAME, net);
-	if (ret) {
-		dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
-		if (pdata->transceiver_enable)
-			pdata->transceiver_enable(0);
-		close_candev(net);
-		return ret;
-	}
-
-	mcp251x_hw_wakeup(spi);
-	mcp251x_hw_reset(spi);
-	ret = mcp251x_setup(net, priv, spi);
-	if (ret) {
-		free_irq(spi->irq, net);
-		mcp251x_hw_sleep(spi);
-		if (pdata->transceiver_enable)
-			pdata->transceiver_enable(0);
-		close_candev(net);
-		return ret;
-	}
-	mcp251x_set_normal_mode(spi);
-	netif_wake_queue(net);
-
-	return 0;
+		pdata->transceiver_enable(0);
+	close_candev(net);
 }
 
 static int mcp251x_stop(struct net_device *net)
@@ -706,17 +643,19 @@ static int mcp251x_stop(struct net_devic
 
 	close_candev(net);
 
+	priv->force_quit = 1;
+	free_irq(spi->irq, priv);
+	destroy_workqueue(priv->wq);
+	priv->wq = NULL;
+
+	mutex_lock(&priv->mcp_lock);
+
 	/* Disable and clear pending interrupts */
 	mcp251x_write_reg(spi, CANINTE, 0x00);
 	mcp251x_write_reg(spi, CANINTF, 0x00);
 
-	priv->force_quit = 1;
-	free_irq(spi->irq, net);
-	flush_workqueue(priv->wq);
-
 	mcp251x_write_reg(spi, TXBCTRL(0), 0);
-	if (priv->tx_skb || priv->tx_len)
-		mcp251x_clean(net);
+	mcp251x_clean(net);
 
 	mcp251x_hw_sleep(spi);
 
@@ -725,9 +664,27 @@ static int mcp251x_stop(struct net_devic
 
 	priv->can.state = CAN_STATE_STOPPED;
 
+	mutex_unlock(&priv->mcp_lock);
+
 	return 0;
 }
 
+static void mcp251x_error_skb(struct net_device *net, int can_id, int data1)
+{
+	struct sk_buff *skb;
+	struct can_frame *frame;
+
+	skb = alloc_can_err_skb(net, &frame);
+	if (skb) {
+		frame->can_id = can_id;
+		frame->data[1] = data1;
+		netif_rx(skb);
+	} else {
+		dev_err(&net->dev,
+			"cannot allocate error skb\n");
+	}
+}
+
 static void mcp251x_tx_work_handler(struct work_struct *ws)
 {
 	struct mcp251x_priv *priv = container_of(ws, struct mcp251x_priv,
@@ -736,33 +693,32 @@ static void mcp251x_tx_work_handler(stru
 	struct net_device *net = priv->net;
 	struct can_frame *frame;
 
+	mutex_lock(&priv->mcp_lock);
 	if (priv->tx_skb) {
-		frame = (struct can_frame *)priv->tx_skb->data;
-
 		if (priv->can.state == CAN_STATE_BUS_OFF) {
 			mcp251x_clean(net);
-			netif_wake_queue(net);
-			return;
+		} else {
+			frame = (struct can_frame *)priv->tx_skb->data;
+
+			if (frame->can_dlc > CAN_FRAME_MAX_DATA_LEN)
+				frame->can_dlc = CAN_FRAME_MAX_DATA_LEN;
+			mcp251x_hw_tx(spi, frame, 0);
+			priv->tx_len = 1 + frame->can_dlc;
+			can_put_echo_skb(priv->tx_skb, net, 0);
+			priv->tx_skb = NULL;
 		}
-		if (frame->can_dlc > CAN_FRAME_MAX_DATA_LEN)
-			frame->can_dlc = CAN_FRAME_MAX_DATA_LEN;
-		mcp251x_hw_tx(spi, frame, 0);
-		priv->tx_len = 1 + frame->can_dlc;
-		can_put_echo_skb(priv->tx_skb, net, 0);
-		priv->tx_skb = NULL;
 	}
+	mutex_unlock(&priv->mcp_lock);
 }
 
-static void mcp251x_irq_work_handler(struct work_struct *ws)
+static void mcp251x_restart_work_handler(struct work_struct *ws)
 {
 	struct mcp251x_priv *priv = container_of(ws, struct mcp251x_priv,
-						 irq_work);
+						 restart_work);
 	struct spi_device *spi = priv->spi;
 	struct net_device *net = priv->net;
-	u8 txbnctrl;
-	u8 intf;
-	enum can_state new_state;
 
+	mutex_lock(&priv->mcp_lock);
 	if (priv->after_suspend) {
 		mdelay(10);
 		mcp251x_hw_reset(spi);
@@ -771,45 +727,54 @@ static void mcp251x_irq_work_handler(str
 			mcp251x_set_normal_mode(spi);
 		} else if (priv->after_suspend & AFTER_SUSPEND_UP) {
 			netif_device_attach(net);
-			/* Clean since we lost tx buffer */
-			if (priv->tx_skb || priv->tx_len) {
-				mcp251x_clean(net);
-				netif_wake_queue(net);
-			}
+			mcp251x_clean(net);
 			mcp251x_set_normal_mode(spi);
+			netif_wake_queue(net);
 		} else {
 			mcp251x_hw_sleep(spi);
 		}
 		priv->after_suspend = 0;
+		priv->force_quit = 0;
 	}
 
-	if (priv->can.restart_ms == 0 && priv->can.state == CAN_STATE_BUS_OFF)
-		return;
+	if (priv->restart_tx) {
+		priv->restart_tx = 0;
+		mcp251x_write_reg(spi, TXBCTRL(0), 0);
+		mcp251x_clean(net);
+		netif_wake_queue(net);
+		mcp251x_error_skb(net, CAN_ERR_RESTARTED, 0);
+	}
+	mutex_unlock(&priv->mcp_lock);
+}
 
-	while (!priv->force_quit && !freezing(current)) {
-		u8 eflag = mcp251x_read_reg(spi, EFLG);
-		int can_id = 0, data1 = 0;
+static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
+{
+	struct mcp251x_priv *priv = dev_id;
+	struct spi_device *spi = priv->spi;
+	struct net_device *net = priv->net;
 
-		mcp251x_write_reg(spi, EFLG, 0x00);
+	mutex_lock(&priv->mcp_lock);
+	while (!priv->force_quit) {
+		enum can_state new_state;
+		u8 intf = mcp251x_read_reg(spi, CANINTF);
+		u8 eflag;
+		int can_id = 0, data1 = 0;
 
-		if (priv->restart_tx) {
-			priv->restart_tx = 0;
-			mcp251x_write_reg(spi, TXBCTRL(0), 0);
-			if (priv->tx_skb || priv->tx_len)
-				mcp251x_clean(net);
-			netif_wake_queue(net);
-			can_id |= CAN_ERR_RESTARTED;
+		if (intf & CANINTF_RX0IF) {
+			mcp251x_hw_rx(spi, 0);
+			/* Free one buffer ASAP */
+			mcp251x_write_bits(spi, CANINTF, intf & CANINTF_RX0IF,
+					   0x00);
 		}
 
-		if (priv->wake) {
-			/* Wait whilst the device wakes up */
-			mdelay(10);
-			priv->wake = 0;
-		}
+		if (intf & CANINTF_RX1IF)
+			mcp251x_hw_rx(spi, 1);
 
-		intf = mcp251x_read_reg(spi, CANINTF);
 		mcp251x_write_bits(spi, CANINTF, intf, 0x00);
 
+		eflag = mcp251x_read_reg(spi, EFLG);
+		mcp251x_write_reg(spi, EFLG, 0x00);
+
 		/* Update can state */
 		if (eflag & EFLG_TXBO) {
 			new_state = CAN_STATE_BUS_OFF;
@@ -850,59 +815,31 @@ static void mcp251x_irq_work_handler(str
 		}
 		priv->can.state = new_state;
 
-		if ((intf & CANINTF_ERRIF) || (can_id & CAN_ERR_RESTARTED)) {
-			struct sk_buff *skb;
-			struct can_frame *frame;
-
-			/* Create error frame */
-			skb = alloc_can_err_skb(net, &frame);
-			if (skb) {
-				/* Set error frame flags based on bus state */
-				frame->can_id = can_id;
-				frame->data[1] = data1;
-
-				/* Update net stats for overflows */
-				if (eflag & (EFLG_RX0OVR | EFLG_RX1OVR)) {
-					if (eflag & EFLG_RX0OVR)
-						net->stats.rx_over_errors++;
-					if (eflag & EFLG_RX1OVR)
-						net->stats.rx_over_errors++;
-					frame->can_id |= CAN_ERR_CRTL;
-					frame->data[1] |=
-						CAN_ERR_CRTL_RX_OVERFLOW;
-				}
-
-				netif_rx(skb);
-			} else {
-				dev_info(&spi->dev,
-					 "cannot allocate error skb\n");
+		if (intf & CANINTF_ERRIF) {
+			/* Handle overflow counters */
+			if (eflag & (EFLG_RX0OVR | EFLG_RX1OVR)) {
+				if (eflag & EFLG_RX0OVR)
+					net->stats.rx_over_errors++;
+				if (eflag & EFLG_RX1OVR)
+					net->stats.rx_over_errors++;
+				can_id |= CAN_ERR_CRTL;
+				data1 |= CAN_ERR_CRTL_RX_OVERFLOW;
 			}
+			mcp251x_error_skb(net, can_id, data1);
 		}
 
 		if (priv->can.state == CAN_STATE_BUS_OFF) {
 			if (priv->can.restart_ms == 0) {
+				priv->force_quit = 1;
 				can_bus_off(net);
 				mcp251x_hw_sleep(spi);
-				return;
+				break;
 			}
 		}
 
 		if (intf == 0)
 			break;
 
-		if (intf & CANINTF_WAKIF)
-			complete(&priv->awake);
-
-		if (intf & CANINTF_MERRF) {
-			/* If there are pending Tx buffers, restart queue */
-			txbnctrl = mcp251x_read_reg(spi, TXBCTRL(0));
-			if (!(txbnctrl & TXBCTRL_TXREQ)) {
-				if (priv->tx_skb || priv->tx_len)
-					mcp251x_clean(net);
-				netif_wake_queue(net);
-			}
-		}
-
 		if (intf & (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)) {
 			net->stats.tx_packets++;
 			net->stats.tx_bytes += priv->tx_len - 1;
@@ -913,12 +850,66 @@ static void mcp251x_irq_work_handler(str
 			netif_wake_queue(net);
 		}
 
-		if (intf & CANINTF_RX0IF)
-			mcp251x_hw_rx(spi, 0);
+	}
+	mutex_unlock(&priv->mcp_lock);
+	return IRQ_HANDLED;
+}
 
-		if (intf & CANINTF_RX1IF)
-			mcp251x_hw_rx(spi, 1);
+static int mcp251x_open(struct net_device *net)
+{
+	struct mcp251x_priv *priv = netdev_priv(net);
+	struct spi_device *spi = priv->spi;
+	struct mcp251x_platform_data *pdata = spi->dev.platform_data;
+	int ret;
+
+	ret = open_candev(net);
+	if (ret) {
+		dev_err(&spi->dev, "unable to set initial baudrate!\n");
+		return ret;
+	}
+
+	mutex_lock(&priv->mcp_lock);
+	if (pdata->transceiver_enable)
+		pdata->transceiver_enable(1);
+
+	priv->force_quit = 0;
+	priv->tx_skb = NULL;
+	priv->tx_len = 0;
+
+	ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
+			  IRQF_TRIGGER_FALLING, DEVICE_NAME, priv);
+	if (ret) {
+		dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
+		if (pdata->transceiver_enable)
+			pdata->transceiver_enable(0);
+		close_candev(net);
+		goto open_unlock;
 	}
+
+	priv->wq = create_freezeable_workqueue("mcp251x_wq");
+	INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler);
+	INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler);
+
+	ret = mcp251x_hw_reset(spi);
+	if (ret) {
+		mcp251x_open_clean(net);
+		goto open_unlock;
+	}
+	ret = mcp251x_setup(net, priv, spi);
+	if (ret) {
+		mcp251x_open_clean(net);
+		goto open_unlock;
+	}
+	ret = mcp251x_set_normal_mode(spi);
+	if (ret) {
+		mcp251x_open_clean(net);
+		goto open_unlock;
+	}
+	netif_wake_queue(net);
+
+open_unlock:
+	mutex_unlock(&priv->mcp_lock);
+	return ret;
 }
 
 static const struct net_device_ops mcp251x_netdev_ops = {
@@ -952,11 +943,13 @@ static int __devinit mcp251x_can_probe(s
 	priv->can.bittiming_const = &mcp251x_bittiming_const;
 	priv->can.do_set_mode = mcp251x_do_set_mode;
 	priv->can.clock.freq = pdata->oscillator_frequency / 2;
+	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
+		CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
 	priv->net = net;
 	dev_set_drvdata(&spi->dev, priv);
 
 	priv->spi = spi;
-	mutex_init(&priv->spi_lock);
+	mutex_init(&priv->mcp_lock);
 
 	/* If requested, allocate DMA buffers */
 	if (mcp251x_enable_dma) {
@@ -1005,18 +998,12 @@ static int __devinit mcp251x_can_probe(s
 
 	SET_NETDEV_DEV(net, &spi->dev);
 
-	priv->wq = create_freezeable_workqueue("mcp251x_wq");
-
-	INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler);
-	INIT_WORK(&priv->irq_work, mcp251x_irq_work_handler);
-
-	init_completion(&priv->awake);
-
 	/* Configure the SPI bus */
 	spi->mode = SPI_MODE_0;
 	spi->bits_per_word = 8;
 	spi_setup(spi);
 
+	/* Here is OK to not lock the MCP, no one knows about it yet */
 	if (!mcp251x_hw_probe(spi)) {
 		dev_info(&spi->dev, "Probe failed\n");
 		goto error_probe;
@@ -1059,10 +1046,6 @@ static int __devexit mcp251x_can_remove(
 	unregister_candev(net);
 	free_candev(net);
 
-	priv->force_quit = 1;
-	flush_workqueue(priv->wq);
-	destroy_workqueue(priv->wq);
-
 	if (mcp251x_enable_dma) {
 		dma_free_coherent(&spi->dev, PAGE_SIZE,
 				  priv->spi_tx_buf, priv->spi_tx_dma);
@@ -1084,6 +1067,12 @@ static int mcp251x_can_suspend(struct sp
 	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
 	struct net_device *net = priv->net;
 
+	priv->force_quit = 1;
+	disable_irq(spi->irq);
+	/*
+	 * Note: at this point neither IST nor workqueues are running.
+	 * open/stop cannot be called anyway so locking is not needed
+	 */
 	if (netif_running(net)) {
 		netif_device_detach(net);
 
@@ -1110,16 +1099,18 @@ static int mcp251x_can_resume(struct spi
 
 	if (priv->after_suspend & AFTER_SUSPEND_POWER) {
 		pdata->power_enable(1);
-		queue_work(priv->wq, &priv->irq_work);
+		queue_work(priv->wq, &priv->restart_work);
 	} else {
 		if (priv->after_suspend & AFTER_SUSPEND_UP) {
 			if (pdata->transceiver_enable)
 				pdata->transceiver_enable(1);
-			queue_work(priv->wq, &priv->irq_work);
+			queue_work(priv->wq, &priv->restart_work);
 		} else {
 			priv->after_suspend = 0;
 		}
 	}
+	priv->force_quit = 0;
+	enable_irq(spi->irq);
 	return 0;
 }
 #else
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/mscan/Kconfig linux-libre-2.6.34-gnu1/drivers/net/can/mscan/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/net/can/mscan/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/mscan/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -11,12 +11,13 @@ if CAN_MSCAN
 
 config CAN_MPC5XXX
 	tristate "Freescale MPC5xxx onboard CAN controller"
-	depends on PPC_MPC52xx
+	depends on (PPC_MPC52xx || PPC_MPC512x)
 	---help---
 	  If you say yes here you get support for Freescale's MPC5xxx
-	  onboard CAN controller.
+	  onboard CAN controller. Currently, the MPC5200, MPC5200B and
+	  MPC5121 (Rev. 2 and later) are supported.
 
-	  This driver can also be built as a module.  If so, the module
+	  This driver can also be built as a module. If so, the module
 	  will be called mscan-mpc5xxx.ko.
 
 endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/mscan/mpc5xxx_can.c linux-libre-2.6.34-gnu1/drivers/net/can/mscan/mpc5xxx_can.c
--- linux-libre-2.6.33-gnu1/drivers/net/can/mscan/mpc5xxx_can.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/mscan/mpc5xxx_can.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/can/dev.h>
 #include <linux/of_platform.h>
 #include <sysdev/fsl_soc.h>
+#include <linux/clk.h>
 #include <linux/io.h>
 #include <asm/mpc52xx.h>
 
@@ -36,22 +37,21 @@
 
 #define DRV_NAME "mpc5xxx_can"
 
-static struct of_device_id mpc52xx_cdm_ids[] __devinitdata = {
+struct mpc5xxx_can_data {
+	unsigned int type;
+	u32 (*get_clock)(struct of_device *ofdev, const char *clock_name,
+			 int *mscan_clksrc);
+};
+
+#ifdef CONFIG_PPC_MPC52xx
+static struct of_device_id __devinitdata mpc52xx_cdm_ids[] = {
 	{ .compatible = "fsl,mpc5200-cdm", },
 	{}
 };
 
-/*
- * Get frequency of the MSCAN clock source
- *
- * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock (IP_CLK)
- * can be selected. According to the MPC5200 user's manual, the oscillator
- * clock is the better choice as it has less jitter but due to a hardware
- * bug, it can not be selected for the old MPC5200 Rev. A chips.
- */
-
-static unsigned int  __devinit mpc52xx_can_clock_freq(struct of_device *of,
-						      int clock_src)
+static u32 __devinit mpc52xx_can_get_clock(struct of_device *ofdev,
+					   const char *clock_name,
+					   int *mscan_clksrc)
 {
 	unsigned int pvr;
 	struct mpc52xx_cdm  __iomem *cdm;
@@ -61,21 +61,33 @@ static unsigned int  __devinit mpc52xx_c
 
 	pvr = mfspr(SPRN_PVR);
 
-	freq = mpc5xxx_get_bus_frequency(of->node);
+	/*
+	 * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock
+	 * (IP_CLK) can be selected as MSCAN clock source. According to
+	 * the MPC5200 user's manual, the oscillator clock is the better
+	 * choice as it has less jitter. For this reason, it is selected
+	 * by default. Unfortunately, it can not be selected for the old
+	 * MPC5200 Rev. A chips due to a hardware bug (check errata).
+	 */
+	if (clock_name && strcmp(clock_name, "ip") == 0)
+		*mscan_clksrc = MSCAN_CLKSRC_BUS;
+	else
+		*mscan_clksrc = MSCAN_CLKSRC_XTAL;
+
+	freq = mpc5xxx_get_bus_frequency(ofdev->node);
 	if (!freq)
 		return 0;
 
-	if (clock_src == MSCAN_CLKSRC_BUS || pvr == 0x80822011)
+	if (*mscan_clksrc == MSCAN_CLKSRC_BUS || pvr == 0x80822011)
 		return freq;
 
 	/* Determine SYS_XTAL_IN frequency from the clock domain settings */
 	np_cdm = of_find_matching_node(NULL, mpc52xx_cdm_ids);
 	if (!np_cdm) {
-		dev_err(&of->dev, "can't get clock node!\n");
+		dev_err(&ofdev->dev, "can't get clock node!\n");
 		return 0;
 	}
 	cdm = of_iomap(np_cdm, 0);
-	of_node_put(np_cdm);
 
 	if (in_8(&cdm->ipb_clk_sel) & 0x1)
 		freq *= 2;
@@ -84,26 +96,174 @@ static unsigned int  __devinit mpc52xx_c
 	freq *= (val & (1 << 5)) ? 8 : 4;
 	freq /= (val & (1 << 6)) ? 12 : 16;
 
+	of_node_put(np_cdm);
 	iounmap(cdm);
 
 	return freq;
 }
+#else /* !CONFIG_PPC_MPC52xx */
+static u32 __devinit mpc52xx_can_get_clock(struct of_device *ofdev,
+					   const char *clock_name,
+					   int *mscan_clksrc)
+{
+	return 0;
+}
+#endif /* CONFIG_PPC_MPC52xx */
+
+#ifdef CONFIG_PPC_MPC512x
+struct mpc512x_clockctl {
+	u32 spmr;		/* System PLL Mode Reg */
+	u32 sccr[2];		/* System Clk Ctrl Reg 1 & 2 */
+	u32 scfr1;		/* System Clk Freq Reg 1 */
+	u32 scfr2;		/* System Clk Freq Reg 2 */
+	u32 reserved;
+	u32 bcr;		/* Bread Crumb Reg */
+	u32 pccr[12];		/* PSC Clk Ctrl Reg 0-11 */
+	u32 spccr;		/* SPDIF Clk Ctrl Reg */
+	u32 cccr;		/* CFM Clk Ctrl Reg */
+	u32 dccr;		/* DIU Clk Cnfg Reg */
+	u32 mccr[4];		/* MSCAN Clk Ctrl Reg 1-3 */
+};
+
+static struct of_device_id __devinitdata mpc512x_clock_ids[] = {
+	{ .compatible = "fsl,mpc5121-clock", },
+	{}
+};
+
+static u32 __devinit mpc512x_can_get_clock(struct of_device *ofdev,
+					   const char *clock_name,
+					   int *mscan_clksrc)
+{
+	struct mpc512x_clockctl __iomem *clockctl;
+	struct device_node *np_clock;
+	struct clk *sys_clk, *ref_clk;
+	int plen, clockidx, clocksrc = -1;
+	u32 sys_freq, val, clockdiv = 1, freq = 0;
+	const u32 *pval;
+
+	np_clock = of_find_matching_node(NULL, mpc512x_clock_ids);
+	if (!np_clock) {
+		dev_err(&ofdev->dev, "couldn't find clock node\n");
+		return -ENODEV;
+	}
+	clockctl = of_iomap(np_clock, 0);
+	if (!clockctl) {
+		dev_err(&ofdev->dev, "couldn't map clock registers\n");
+		return 0;
+	}
+
+	/* Determine the MSCAN device index from the physical address */
+	pval = of_get_property(ofdev->node, "reg", &plen);
+	BUG_ON(!pval || plen < sizeof(*pval));
+	clockidx = (*pval & 0x80) ? 1 : 0;
+	if (*pval & 0x2000)
+		clockidx += 2;
+
+	/*
+	 * Clock source and divider selection: 3 different clock sources
+	 * can be selected: "ip", "ref" or "sys". For the latter two, a
+	 * clock divider can be defined as well. If the clock source is
+	 * not specified by the device tree, we first try to find an
+	 * optimal CAN source clock based on the system clock. If that
+	 * is not posslible, the reference clock will be used.
+	 */
+	if (clock_name && !strcmp(clock_name, "ip")) {
+		*mscan_clksrc = MSCAN_CLKSRC_IPS;
+		freq = mpc5xxx_get_bus_frequency(ofdev->node);
+	} else {
+		*mscan_clksrc = MSCAN_CLKSRC_BUS;
+
+		pval = of_get_property(ofdev->node,
+				       "fsl,mscan-clock-divider", &plen);
+		if (pval && plen == sizeof(*pval))
+			clockdiv = *pval;
+		if (!clockdiv)
+			clockdiv = 1;
+
+		if (!clock_name || !strcmp(clock_name, "sys")) {
+			sys_clk = clk_get(&ofdev->dev, "sys_clk");
+			if (!sys_clk) {
+				dev_err(&ofdev->dev, "couldn't get sys_clk\n");
+				goto exit_unmap;
+			}
+			/* Get and round up/down sys clock rate */
+			sys_freq = 1000000 *
+				((clk_get_rate(sys_clk) + 499999) / 1000000);
+
+			if (!clock_name) {
+				/* A multiple of 16 MHz would be optimal */
+				if ((sys_freq % 16000000) == 0) {
+					clocksrc = 0;
+					clockdiv = sys_freq / 16000000;
+					freq = sys_freq / clockdiv;
+				}
+			} else {
+				clocksrc = 0;
+				freq = sys_freq / clockdiv;
+			}
+		}
+
+		if (clocksrc < 0) {
+			ref_clk = clk_get(&ofdev->dev, "ref_clk");
+			if (!ref_clk) {
+				dev_err(&ofdev->dev, "couldn't get ref_clk\n");
+				goto exit_unmap;
+			}
+			clocksrc = 1;
+			freq = clk_get_rate(ref_clk) / clockdiv;
+		}
+	}
+
+	/* Disable clock */
+	out_be32(&clockctl->mccr[clockidx], 0x0);
+	if (clocksrc >= 0) {
+		/* Set source and divider */
+		val = (clocksrc << 14) | ((clockdiv - 1) << 17);
+		out_be32(&clockctl->mccr[clockidx], val);
+		/* Enable clock */
+		out_be32(&clockctl->mccr[clockidx], val | 0x10000);
+	}
+
+	/* Enable MSCAN clock domain */
+	val = in_be32(&clockctl->sccr[1]);
+	if (!(val & (1 << 25)))
+		out_be32(&clockctl->sccr[1], val | (1 << 25));
+
+	dev_dbg(&ofdev->dev, "using '%s' with frequency divider %d\n",
+		*mscan_clksrc == MSCAN_CLKSRC_IPS ? "ips_clk" :
+		clocksrc == 1 ? "ref_clk" : "sys_clk", clockdiv);
+
+exit_unmap:
+	of_node_put(np_clock);
+	iounmap(clockctl);
+
+	return freq;
+}
+#else /* !CONFIG_PPC_MPC512x */
+static u32 __devinit mpc512x_can_get_clock(struct of_device *ofdev,
+					   const char *clock_name,
+					   int *mscan_clksrc)
+{
+	return 0;
+}
+#endif /* CONFIG_PPC_MPC512x */
 
 static int __devinit mpc5xxx_can_probe(struct of_device *ofdev,
 				       const struct of_device_id *id)
 {
+	struct mpc5xxx_can_data *data = (struct mpc5xxx_can_data *)id->data;
 	struct device_node *np = ofdev->node;
 	struct net_device *dev;
 	struct mscan_priv *priv;
 	void __iomem *base;
-	const char *clk_src;
-	int err, irq, clock_src;
+	const char *clock_name = NULL;
+	int irq, mscan_clksrc = 0;
+	int err = -ENOMEM;
 
-	base = of_iomap(ofdev->node, 0);
+	base = of_iomap(np, 0);
 	if (!base) {
 		dev_err(&ofdev->dev, "couldn't ioremap\n");
-		err = -ENOMEM;
-		goto exit_release_mem;
+		return err;
 	}
 
 	irq = irq_of_parse_and_map(np, 0);
@@ -114,37 +274,27 @@ static int __devinit mpc5xxx_can_probe(s
 	}
 
 	dev = alloc_mscandev();
-	if (!dev) {
-		err = -ENOMEM;
+	if (!dev)
 		goto exit_dispose_irq;
-	}
 
 	priv = netdev_priv(dev);
 	priv->reg_base = base;
 	dev->irq = irq;
 
-	/*
-	 * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock
-	 * (IP_CLK) can be selected as MSCAN clock source. According to
-	 * the MPC5200 user's manual, the oscillator clock is the better
-	 * choice as it has less jitter. For this reason, it is selected
-	 * by default.
-	 */
-	clk_src = of_get_property(np, "fsl,mscan-clock-source", NULL);
-	if (clk_src && strcmp(clk_src, "ip") == 0)
-		clock_src = MSCAN_CLKSRC_BUS;
-	else
-		clock_src = MSCAN_CLKSRC_XTAL;
-	priv->can.clock.freq = mpc52xx_can_clock_freq(ofdev, clock_src);
+	clock_name = of_get_property(np, "fsl,mscan-clock-source", NULL);
+
+	BUG_ON(!data);
+	priv->type = data->type;
+	priv->can.clock.freq = data->get_clock(ofdev, clock_name,
+					       &mscan_clksrc);
 	if (!priv->can.clock.freq) {
-		dev_err(&ofdev->dev, "couldn't get MSCAN clock frequency\n");
-		err = -ENODEV;
+		dev_err(&ofdev->dev, "couldn't get MSCAN clock properties\n");
 		goto exit_free_mscan;
 	}
 
 	SET_NETDEV_DEV(dev, &ofdev->dev);
 
-	err = register_mscandev(dev, clock_src);
+	err = register_mscandev(dev, mscan_clksrc);
 	if (err) {
 		dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
 			DRV_NAME, err);
@@ -164,7 +314,7 @@ exit_dispose_irq:
 	irq_dispose_mapping(irq);
 exit_unmap_mem:
 	iounmap(base);
-exit_release_mem:
+
 	return err;
 }
 
@@ -225,8 +375,20 @@ static int mpc5xxx_can_resume(struct of_
 }
 #endif
 
+static struct mpc5xxx_can_data __devinitdata mpc5200_can_data = {
+	.type = MSCAN_TYPE_MPC5200,
+	.get_clock = mpc52xx_can_get_clock,
+};
+
+static struct mpc5xxx_can_data __devinitdata mpc5121_can_data = {
+	.type = MSCAN_TYPE_MPC5121,
+	.get_clock = mpc512x_can_get_clock,
+};
+
 static struct of_device_id __devinitdata mpc5xxx_can_table[] = {
-	{.compatible = "fsl,mpc5200-mscan"},
+	{ .compatible = "fsl,mpc5200-mscan", .data = &mpc5200_can_data, },
+	/* Note that only MPC5121 Rev. 2 (and later) is supported */
+	{ .compatible = "fsl,mpc5121-mscan", .data = &mpc5121_can_data, },
 	{},
 };
 
@@ -255,5 +417,5 @@ static void __exit mpc5xxx_can_exit(void
 module_exit(mpc5xxx_can_exit);
 
 MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
-MODULE_DESCRIPTION("Freescale MPC5200 CAN driver");
+MODULE_DESCRIPTION("Freescale MPC5xxx CAN driver");
 MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/mscan/mscan.c linux-libre-2.6.34-gnu1/drivers/net/can/mscan/mscan.c
--- linux-libre-2.6.33-gnu1/drivers/net/can/mscan/mscan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/mscan/mscan.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
  * Copyright (C) 2005-2006 Andrey Volkov <avolkov@varma-el.com>,
  *                         Varma Electronics Oy
  * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
- * Copytight (C) 2008-2009 Pengutronix <kernel@pengutronix.de>
+ * Copyright (C) 2008-2009 Pengutronix <kernel@pengutronix.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the version 2 of the GNU General Public License
@@ -152,6 +152,12 @@ static int mscan_start(struct net_device
 	priv->shadow_canrier = 0;
 	priv->flags = 0;
 
+	if (priv->type == MSCAN_TYPE_MPC5121) {
+		/* Clear pending bus-off condition */
+		if (in_8(&regs->canmisc) & MSCAN_BOHOLD)
+			out_8(&regs->canmisc, MSCAN_BOHOLD);
+	}
+
 	err = mscan_set_mode(dev, MSCAN_NORMAL_MODE);
 	if (err)
 		return err;
@@ -163,8 +169,29 @@ static int mscan_start(struct net_device
 	out_8(&regs->cantier, 0);
 
 	/* Enable receive interrupts. */
-	out_8(&regs->canrier, MSCAN_OVRIE | MSCAN_RXFIE | MSCAN_CSCIE |
-	      MSCAN_RSTATE1 | MSCAN_RSTATE0 | MSCAN_TSTATE1 | MSCAN_TSTATE0);
+	out_8(&regs->canrier, MSCAN_RX_INTS_ENABLE);
+
+	return 0;
+}
+
+static int mscan_restart(struct net_device *dev)
+{
+	struct mscan_priv *priv = netdev_priv(dev);
+
+	if (priv->type == MSCAN_TYPE_MPC5121) {
+		struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
+		WARN(!(in_8(&regs->canmisc) & MSCAN_BOHOLD),
+		     "bus-off state expected");
+		out_8(&regs->canmisc, MSCAN_BOHOLD);
+		/* Re-enable receive interrupts. */
+		out_8(&regs->canrier, MSCAN_RX_INTS_ENABLE);
+	} else {
+		if (priv->can.state <= CAN_STATE_BUS_OFF)
+			mscan_set_mode(dev, MSCAN_INIT_MODE);
+		return mscan_start(dev);
+	}
 
 	return 0;
 }
@@ -177,8 +204,8 @@ static netdev_tx_t mscan_start_xmit(stru
 	int i, rtr, buf_id;
 	u32 can_id;
 
-	if (frame->can_dlc > 8)
-		return -EINVAL;
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
 
 	out_8(&regs->cantier, 0);
 
@@ -359,9 +386,12 @@ static void mscan_get_err_frame(struct n
 			 * automatically. To avoid that we stop the chip doing
 			 * a light-weight stop (we are in irq-context).
 			 */
-			out_8(&regs->cantier, 0);
-			out_8(&regs->canrier, 0);
-			setbits8(&regs->canctl0, MSCAN_SLPRQ | MSCAN_INITRQ);
+			if (priv->type != MSCAN_TYPE_MPC5121) {
+				out_8(&regs->cantier, 0);
+				out_8(&regs->canrier, 0);
+				setbits8(&regs->canctl0,
+					 MSCAN_SLPRQ | MSCAN_INITRQ);
+			}
 			can_bus_off(dev);
 			break;
 		default:
@@ -491,9 +521,7 @@ static int mscan_do_set_mode(struct net_
 
 	switch (mode) {
 	case CAN_MODE_START:
-		if (priv->can.state <= CAN_STATE_BUS_OFF)
-			mscan_set_mode(dev, MSCAN_INIT_MODE);
-		ret = mscan_start(dev);
+		ret = mscan_restart(dev);
 		if (ret)
 			break;
 		if (netif_queue_stopped(dev))
@@ -592,18 +620,21 @@ static const struct net_device_ops mscan
        .ndo_start_xmit         = mscan_start_xmit,
 };
 
-int register_mscandev(struct net_device *dev, int clock_src)
+int register_mscandev(struct net_device *dev, int mscan_clksrc)
 {
 	struct mscan_priv *priv = netdev_priv(dev);
 	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
 	u8 ctl1;
 
 	ctl1 = in_8(&regs->canctl1);
-	if (clock_src)
+	if (mscan_clksrc)
 		ctl1 |= MSCAN_CLKSRC;
 	else
 		ctl1 &= ~MSCAN_CLKSRC;
 
+	if (priv->type == MSCAN_TYPE_MPC5121)
+		ctl1 |= MSCAN_BORM; /* bus-off recovery upon request */
+
 	ctl1 |= MSCAN_CANE;
 	out_8(&regs->canctl1, ctl1);
 	udelay(100);
@@ -655,6 +686,7 @@ struct net_device *alloc_mscandev(void)
 	priv->can.bittiming_const = &mscan_bittiming_const;
 	priv->can.do_set_bittiming = mscan_do_set_bittiming;
 	priv->can.do_set_mode = mscan_do_set_mode;
+	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
 	for (i = 0; i < TX_QUEUE_SIZE; i++) {
 		priv->tx_queue[i].id = i;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/mscan/mscan.h linux-libre-2.6.34-gnu1/drivers/net/can/mscan/mscan.h
--- linux-libre-2.6.33-gnu1/drivers/net/can/mscan/mscan.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/mscan/mscan.h	2010-05-16 17:17:36.000000000 -0400
@@ -38,18 +38,20 @@
 #define MSCAN_CLKSRC		0x40
 #define MSCAN_LOOPB		0x20
 #define MSCAN_LISTEN		0x10
+#define MSCAN_BORM		0x08
 #define MSCAN_WUPM		0x04
 #define MSCAN_SLPAK		0x02
 #define MSCAN_INITAK		0x01
 
-/* Use the MPC5200 MSCAN variant? */
+/* Use the MPC5XXX MSCAN variant? */
 #ifdef CONFIG_PPC
-#define MSCAN_FOR_MPC5200
+#define MSCAN_FOR_MPC5XXX
 #endif
 
-#ifdef MSCAN_FOR_MPC5200
+#ifdef MSCAN_FOR_MPC5XXX
 #define MSCAN_CLKSRC_BUS	0
 #define MSCAN_CLKSRC_XTAL	MSCAN_CLKSRC
+#define MSCAN_CLKSRC_IPS	MSCAN_CLKSRC
 #else
 #define MSCAN_CLKSRC_BUS	MSCAN_CLKSRC
 #define MSCAN_CLKSRC_XTAL	0
@@ -136,7 +138,7 @@
 #define MSCAN_EFF_RTR_SHIFT	0
 #define MSCAN_EFF_FLAGS		0x18	/* IDE + SRR */
 
-#ifdef MSCAN_FOR_MPC5200
+#ifdef MSCAN_FOR_MPC5XXX
 #define _MSCAN_RESERVED_(n, num) u8 _res##n[num]
 #define _MSCAN_RESERVED_DSR_SIZE	2
 #else
@@ -165,67 +167,66 @@ struct mscan_regs {
 	u8 cantbsel;				/* + 0x14     0x0a */
 	u8 canidac;				/* + 0x15     0x0b */
 	u8 reserved;				/* + 0x16     0x0c */
-	_MSCAN_RESERVED_(6, 5);			/* + 0x17          */
-#ifndef MSCAN_FOR_MPC5200
-	u8 canmisc;				/*            0x0d */
-#endif
+	_MSCAN_RESERVED_(6, 2);			/* + 0x17          */
+	u8 canmisc;				/* + 0x19     0x0d */
+	_MSCAN_RESERVED_(7, 2);			/* + 0x1a          */
 	u8 canrxerr;				/* + 0x1c     0x0e */
 	u8 cantxerr;				/* + 0x1d     0x0f */
-	_MSCAN_RESERVED_(7, 2);			/* + 0x1e          */
+	_MSCAN_RESERVED_(8, 2);			/* + 0x1e          */
 	u16 canidar1_0;				/* + 0x20     0x10 */
-	_MSCAN_RESERVED_(8, 2);			/* + 0x22          */
+	_MSCAN_RESERVED_(9, 2);			/* + 0x22          */
 	u16 canidar3_2;				/* + 0x24     0x12 */
-	_MSCAN_RESERVED_(9, 2);			/* + 0x26          */
+	_MSCAN_RESERVED_(10, 2);		/* + 0x26          */
 	u16 canidmr1_0;				/* + 0x28     0x14 */
-	_MSCAN_RESERVED_(10, 2);		/* + 0x2a          */
+	_MSCAN_RESERVED_(11, 2);		/* + 0x2a          */
 	u16 canidmr3_2;				/* + 0x2c     0x16 */
-	_MSCAN_RESERVED_(11, 2);		/* + 0x2e          */
+	_MSCAN_RESERVED_(12, 2);		/* + 0x2e          */
 	u16 canidar5_4;				/* + 0x30     0x18 */
-	_MSCAN_RESERVED_(12, 2);		/* + 0x32          */
+	_MSCAN_RESERVED_(13, 2);		/* + 0x32          */
 	u16 canidar7_6;				/* + 0x34     0x1a */
-	_MSCAN_RESERVED_(13, 2);		/* + 0x36          */
+	_MSCAN_RESERVED_(14, 2);		/* + 0x36          */
 	u16 canidmr5_4;				/* + 0x38     0x1c */
-	_MSCAN_RESERVED_(14, 2);		/* + 0x3a          */
+	_MSCAN_RESERVED_(15, 2);		/* + 0x3a          */
 	u16 canidmr7_6;				/* + 0x3c     0x1e */
-	_MSCAN_RESERVED_(15, 2);		/* + 0x3e          */
+	_MSCAN_RESERVED_(16, 2);		/* + 0x3e          */
 	struct {
 		u16 idr1_0;			/* + 0x40     0x20 */
-		 _MSCAN_RESERVED_(16, 2);	/* + 0x42          */
+		_MSCAN_RESERVED_(17, 2);	/* + 0x42          */
 		u16 idr3_2;			/* + 0x44     0x22 */
-		 _MSCAN_RESERVED_(17, 2);	/* + 0x46          */
+		_MSCAN_RESERVED_(18, 2);	/* + 0x46          */
 		u16 dsr1_0;			/* + 0x48     0x24 */
-		 _MSCAN_RESERVED_(18, 2);	/* + 0x4a          */
+		_MSCAN_RESERVED_(19, 2);	/* + 0x4a          */
 		u16 dsr3_2;			/* + 0x4c     0x26 */
-		 _MSCAN_RESERVED_(19, 2);	/* + 0x4e          */
+		_MSCAN_RESERVED_(20, 2);	/* + 0x4e          */
 		u16 dsr5_4;			/* + 0x50     0x28 */
-		 _MSCAN_RESERVED_(20, 2);	/* + 0x52          */
+		_MSCAN_RESERVED_(21, 2);	/* + 0x52          */
 		u16 dsr7_6;			/* + 0x54     0x2a */
-		 _MSCAN_RESERVED_(21, 2);	/* + 0x56          */
+		_MSCAN_RESERVED_(22, 2);	/* + 0x56          */
 		u8 dlr;				/* + 0x58     0x2c */
-		 u8:8;				/* + 0x59     0x2d */
-		 _MSCAN_RESERVED_(22, 2);	/* + 0x5a          */
+		u8 reserved;			/* + 0x59     0x2d */
+		_MSCAN_RESERVED_(23, 2);	/* + 0x5a          */
 		u16 time;			/* + 0x5c     0x2e */
 	} rx;
-	 _MSCAN_RESERVED_(23, 2);		/* + 0x5e          */
+	_MSCAN_RESERVED_(24, 2);		/* + 0x5e          */
 	struct {
 		u16 idr1_0;			/* + 0x60     0x30 */
-		 _MSCAN_RESERVED_(24, 2);	/* + 0x62          */
+		_MSCAN_RESERVED_(25, 2);	/* + 0x62          */
 		u16 idr3_2;			/* + 0x64     0x32 */
-		 _MSCAN_RESERVED_(25, 2);	/* + 0x66          */
+		_MSCAN_RESERVED_(26, 2);	/* + 0x66          */
 		u16 dsr1_0;			/* + 0x68     0x34 */
-		 _MSCAN_RESERVED_(26, 2);	/* + 0x6a          */
+		_MSCAN_RESERVED_(27, 2);	/* + 0x6a          */
 		u16 dsr3_2;			/* + 0x6c     0x36 */
-		 _MSCAN_RESERVED_(27, 2);	/* + 0x6e          */
+		_MSCAN_RESERVED_(28, 2);	/* + 0x6e          */
 		u16 dsr5_4;			/* + 0x70     0x38 */
-		 _MSCAN_RESERVED_(28, 2);	/* + 0x72          */
+		_MSCAN_RESERVED_(29, 2);	/* + 0x72          */
 		u16 dsr7_6;			/* + 0x74     0x3a */
-		 _MSCAN_RESERVED_(29, 2);	/* + 0x76          */
+		_MSCAN_RESERVED_(30, 2);	/* + 0x76          */
 		u8 dlr;				/* + 0x78     0x3c */
 		u8 tbpr;			/* + 0x79     0x3d */
-		 _MSCAN_RESERVED_(30, 2);	/* + 0x7a          */
+		_MSCAN_RESERVED_(31, 2);	/* + 0x7a          */
 		u16 time;			/* + 0x7c     0x3e */
 	} tx;
-	 _MSCAN_RESERVED_(31, 2);		/* + 0x7e          */
+	_MSCAN_RESERVED_(32, 2);		/* + 0x7e          */
 } __attribute__ ((packed));
 
 #undef _MSCAN_RESERVED_
@@ -237,6 +238,15 @@ struct mscan_regs {
 #define MSCAN_POWEROFF_MODE	(MSCAN_CSWAI | MSCAN_SLPRQ)
 #define MSCAN_SET_MODE_RETRIES	255
 #define MSCAN_ECHO_SKB_MAX	3
+#define MSCAN_RX_INTS_ENABLE	(MSCAN_OVRIE | MSCAN_RXFIE | MSCAN_CSCIE | \
+				 MSCAN_RSTATE1 | MSCAN_RSTATE0 | \
+				 MSCAN_TSTATE1 | MSCAN_TSTATE0)
+
+/* MSCAN type variants */
+enum {
+	MSCAN_TYPE_MPC5200,
+	MSCAN_TYPE_MPC5121
+};
 
 #define BTR0_BRP_MASK		0x3f
 #define BTR0_SJW_SHIFT		6
@@ -270,6 +280,7 @@ struct tx_queue_entry {
 
 struct mscan_priv {
 	struct can_priv can;	/* must be the first member */
+	unsigned int type; 	/* MSCAN type variants */
 	long open_time;
 	unsigned long flags;
 	void __iomem *reg_base;	/* ioremap'ed address to registers */
@@ -285,12 +296,7 @@ struct mscan_priv {
 };
 
 extern struct net_device *alloc_mscandev(void);
-/*
- * clock_src:
- *	1 = The MSCAN clock source is the onchip Bus Clock.
- *	0 = The MSCAN clock source is the chip Oscillator Clock.
- */
-extern int register_mscandev(struct net_device *dev, int clock_src);
+extern int register_mscandev(struct net_device *dev, int mscan_clksrc);
 extern void unregister_mscandev(struct net_device *dev);
 
 #endif /* __MSCAN_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/ems_pci.c linux-libre-2.6.34-gnu1/drivers/net/can/sja1000/ems_pci.c
--- linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/ems_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/sja1000/ems_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/can.h>
 #include <linux/can/dev.h>
@@ -102,7 +103,7 @@ struct ems_pci_card {
 
 #define EMS_PCI_BASE_SIZE  4096 /* size of controller area */
 
-static struct pci_device_id ems_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(ems_pci_tbl) = {
 	/* CPC-PCI v1 */
 	{PCI_VENDOR_ID_SIEMENS, 0x2104, PCI_ANY_ID, PCI_ANY_ID,},
 	/* CPC-PCI v2 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/Kconfig linux-libre-2.6.34-gnu1/drivers/net/can/sja1000/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/sja1000/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -44,4 +44,16 @@ config CAN_KVASER_PCI
 	  This driver is for the the PCIcanx and PCIcan cards (1, 2 or
 	  4 channel) from Kvaser (http://www.kvaser.com).
 
+config CAN_PLX_PCI
+	tristate "PLX90xx PCI-bridge based Cards"
+	depends on PCI
+	---help---
+	  This driver is for CAN interface cards based on
+	  the PLX90xx PCI bridge.
+	  Driver supports now:
+	   - Adlink PCI-7841/cPCI-7841 card (http://www.adlinktech.com/)
+	   - Adlink PCI-7841/cPCI-7841 SE card
+	   - Marathon CAN-bus-PCI card (http://www.marathon.ru/)
+	   - TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/)
+
 endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/kvaser_pci.c linux-libre-2.6.34-gnu1/drivers/net/can/sja1000/kvaser_pci.c
--- linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/kvaser_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/sja1000/kvaser_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -109,7 +109,7 @@ struct kvaser_pci {
 #define KVASER_PCI_VENDOR_ID2     0x1a07    /* the PCI device and vendor IDs */
 #define KVASER_PCI_DEVICE_ID2     0x0008
 
-static struct pci_device_id kvaser_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(kvaser_pci_tbl) = {
 	{KVASER_PCI_VENDOR_ID1, KVASER_PCI_DEVICE_ID1, PCI_ANY_ID, PCI_ANY_ID,},
 	{KVASER_PCI_VENDOR_ID2, KVASER_PCI_DEVICE_ID2, PCI_ANY_ID, PCI_ANY_ID,},
 	{ 0,}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/Makefile linux-libre-2.6.34-gnu1/drivers/net/can/sja1000/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/sja1000/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -8,5 +8,6 @@ obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sj
 obj-$(CONFIG_CAN_SJA1000_OF_PLATFORM) += sja1000_of_platform.o
 obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o
 obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o
+obj-$(CONFIG_CAN_PLX_PCI) += plx_pci.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/plx_pci.c linux-libre-2.6.34-gnu1/drivers/net/can/sja1000/plx_pci.c
--- linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/plx_pci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/sja1000/plx_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,473 @@
+/*
+ * Copyright (C) 2008-2010 Pavel Cheblakov <P.B.Cheblakov@inp.nsk.su>
+ *
+ * Derived from the ems_pci.c driver:
+ *	Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
+ *	Copyright (C) 2008 Markus Plessing <plessing@ems-wuensche.com>
+ *	Copyright (C) 2008 Sebastian Haas <haas@ems-wuensche.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/io.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME  "sja1000_plx_pci"
+
+MODULE_AUTHOR("Pavel Cheblakov <P.B.Cheblakov@inp.nsk.su>");
+MODULE_DESCRIPTION("Socket-CAN driver for PLX90xx PCI-bridge cards with "
+		   "the SJA1000 chips");
+MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, "
+			"Adlink PCI-7841/cPCI-7841 SE, "
+			"Marathon CAN-bus-PCI, "
+			"TEWS TECHNOLOGIES TPMC810");
+MODULE_LICENSE("GPL v2");
+
+#define PLX_PCI_MAX_CHAN 2
+
+struct plx_pci_card {
+	int channels;			/* detected channels count */
+	struct net_device *net_dev[PLX_PCI_MAX_CHAN];
+	void __iomem *conf_addr;
+};
+
+#define PLX_PCI_CAN_CLOCK (16000000 / 2)
+
+/* PLX90xx registers */
+#define PLX_INTCSR	0x4c		/* Interrupt Control/Status */
+#define PLX_CNTRL	0x50		/* User I/O, Direct Slave Response,
+					 * Serial EEPROM, and Initialization
+					 * Control register
+					 */
+
+#define PLX_LINT1_EN	0x1		/* Local interrupt 1 enable */
+#define PLX_LINT2_EN	(1 << 3)	/* Local interrupt 2 enable */
+#define PLX_PCI_INT_EN	(1 << 6)	/* PCI Interrupt Enable */
+#define PLX_PCI_RESET	(1 << 30)	/* PCI Adapter Software Reset */
+
+/*
+ * The board configuration is probably following:
+ * RX1 is connected to ground.
+ * TX1 is not connected.
+ * CLKO is not connected.
+ * Setting the OCR register to 0xDA is a good idea.
+ * This means normal output mode, push-pull and the correct polarity.
+ */
+#define PLX_PCI_OCR	(OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
+
+/*
+ * In the CDR register, you should set CBP to 1.
+ * You will probably also want to set the clock divider value to 7
+ * (meaning direct oscillator output) because the second SJA1000 chip
+ * is driven by the first one CLKOUT output.
+ */
+#define PLX_PCI_CDR			(CDR_CBP | CDR_CLKOUT_MASK)
+
+/* SJA1000 Control Register in the BasicCAN Mode */
+#define REG_CR				0x00
+
+/* States of some SJA1000 registers after hardware reset in the BasicCAN mode*/
+#define REG_CR_BASICCAN_INITIAL		0x21
+#define REG_CR_BASICCAN_INITIAL_MASK	0xa1
+#define REG_SR_BASICCAN_INITIAL		0x0c
+#define REG_IR_BASICCAN_INITIAL		0xe0
+
+/* States of some SJA1000 registers after hardware reset in the PeliCAN mode*/
+#define REG_MOD_PELICAN_INITIAL		0x01
+#define REG_SR_PELICAN_INITIAL		0x3c
+#define REG_IR_PELICAN_INITIAL		0x00
+
+#define ADLINK_PCI_VENDOR_ID		0x144A
+#define ADLINK_PCI_DEVICE_ID		0x7841
+
+#define MARATHON_PCI_DEVICE_ID		0x2715
+
+#define TEWS_PCI_VENDOR_ID		0x1498
+#define TEWS_PCI_DEVICE_ID_TMPC810	0x032A
+
+static void plx_pci_reset_common(struct pci_dev *pdev);
+static void plx_pci_reset_marathon(struct pci_dev *pdev);
+
+struct plx_pci_channel_map {
+	u32 bar;
+	u32 offset;
+	u32 size;		/* 0x00 - auto, e.g. length of entire bar */
+};
+
+struct plx_pci_card_info {
+	const char *name;
+	int channel_count;
+	u32 can_clock;
+	u8 ocr;			/* output control register */
+	u8 cdr;			/* clock divider register */
+
+	/* Parameters for mapping local configuration space */
+	struct plx_pci_channel_map conf_map;
+
+	/* Parameters for mapping the SJA1000 chips */
+	struct plx_pci_channel_map chan_map_tbl[PLX_PCI_MAX_CHAN];
+
+	/* Pointer to device-dependent reset function */
+	void (*reset_func)(struct pci_dev *pdev);
+};
+
+static struct plx_pci_card_info plx_pci_card_info_adlink __devinitdata = {
+	"Adlink PCI-7841/cPCI-7841", 2,
+	PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
+	{1, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x80, 0x80} },
+	&plx_pci_reset_common
+	/* based on PLX9052 */
+};
+
+static struct plx_pci_card_info plx_pci_card_info_adlink_se __devinitdata = {
+	"Adlink PCI-7841/cPCI-7841 SE", 2,
+	PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
+	{0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x80, 0x80} },
+	&plx_pci_reset_common
+	/* based on PLX9052 */
+};
+
+static struct plx_pci_card_info plx_pci_card_info_marathon __devinitdata = {
+	"Marathon CAN-bus-PCI", 2,
+	PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
+	{0, 0x00, 0x00}, { {2, 0x00, 0x00}, {4, 0x00, 0x00} },
+	&plx_pci_reset_marathon
+	/* based on PLX9052 */
+};
+
+static struct plx_pci_card_info plx_pci_card_info_tews __devinitdata = {
+	"TEWS TECHNOLOGIES TPMC810", 2,
+	PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
+	{0, 0x00, 0x00}, { {2, 0x000, 0x80}, {2, 0x100, 0x80} },
+	&plx_pci_reset_common
+	/* based on PLX9030 */
+};
+
+static DEFINE_PCI_DEVICE_TABLE(plx_pci_tbl) = {
+	{
+		/* Adlink PCI-7841/cPCI-7841 */
+		ADLINK_PCI_VENDOR_ID, ADLINK_PCI_DEVICE_ID,
+		PCI_ANY_ID, PCI_ANY_ID,
+		PCI_CLASS_NETWORK_OTHER << 8, ~0,
+		(kernel_ulong_t)&plx_pci_card_info_adlink
+	},
+	{
+		/* Adlink PCI-7841/cPCI-7841 SE */
+		ADLINK_PCI_VENDOR_ID, ADLINK_PCI_DEVICE_ID,
+		PCI_ANY_ID, PCI_ANY_ID,
+		PCI_CLASS_COMMUNICATION_OTHER << 8, ~0,
+		(kernel_ulong_t)&plx_pci_card_info_adlink_se
+	},
+	{
+		/* Marathon CAN-bus-PCI card */
+		PCI_VENDOR_ID_PLX, MARATHON_PCI_DEVICE_ID,
+		PCI_ANY_ID, PCI_ANY_ID,
+		0, 0,
+		(kernel_ulong_t)&plx_pci_card_info_marathon
+	},
+	{
+		/* TEWS TECHNOLOGIES TPMC810 card */
+		TEWS_PCI_VENDOR_ID, TEWS_PCI_DEVICE_ID_TMPC810,
+		PCI_ANY_ID, PCI_ANY_ID,
+		0, 0,
+		(kernel_ulong_t)&plx_pci_card_info_tews
+	},
+	{ 0,}
+};
+MODULE_DEVICE_TABLE(pci, plx_pci_tbl);
+
+static u8 plx_pci_read_reg(const struct sja1000_priv *priv, int port)
+{
+	return ioread8(priv->reg_base + port);
+}
+
+static void plx_pci_write_reg(const struct sja1000_priv *priv, int port, u8 val)
+{
+	iowrite8(val, priv->reg_base + port);
+}
+
+/*
+ * Check if a CAN controller is present at the specified location
+ * by trying to switch 'em from the Basic mode into the PeliCAN mode.
+ * Also check states of some registers in reset mode.
+ */
+static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv)
+{
+	int flag = 0;
+
+	/*
+	 * Check registers after hardware reset (the Basic mode)
+	 * See states on p. 10 of the Datasheet.
+	 */
+	if ((priv->read_reg(priv, REG_CR) & REG_CR_BASICCAN_INITIAL_MASK) ==
+	    REG_CR_BASICCAN_INITIAL &&
+	    (priv->read_reg(priv, REG_SR) == REG_SR_BASICCAN_INITIAL) &&
+	    (priv->read_reg(priv, REG_IR) == REG_IR_BASICCAN_INITIAL))
+		flag = 1;
+
+	/* Bring the SJA1000 into the PeliCAN mode*/
+	priv->write_reg(priv, REG_CDR, CDR_PELICAN);
+
+	/*
+	 * Check registers after reset in the PeliCAN mode.
+	 * See states on p. 23 of the Datasheet.
+	 */
+	if (priv->read_reg(priv, REG_MOD) == REG_MOD_PELICAN_INITIAL &&
+	    priv->read_reg(priv, REG_SR) == REG_SR_PELICAN_INITIAL &&
+	    priv->read_reg(priv, REG_IR) == REG_IR_PELICAN_INITIAL)
+		return flag;
+
+	return 0;
+}
+
+/*
+ * PLX90xx software reset
+ * Also LRESET# asserts and brings to reset device on the Local Bus (if wired).
+ * For most cards it's enough for reset the SJA1000 chips.
+ */
+static void plx_pci_reset_common(struct pci_dev *pdev)
+{
+	struct plx_pci_card *card = pci_get_drvdata(pdev);
+	u32 cntrl;
+
+	cntrl = ioread32(card->conf_addr + PLX_CNTRL);
+	cntrl |= PLX_PCI_RESET;
+	iowrite32(cntrl, card->conf_addr + PLX_CNTRL);
+	udelay(100);
+	cntrl ^= PLX_PCI_RESET;
+	iowrite32(cntrl, card->conf_addr + PLX_CNTRL);
+};
+
+/* Special reset function for Marathon card */
+static void plx_pci_reset_marathon(struct pci_dev *pdev)
+{
+	void __iomem *reset_addr;
+	int i;
+	int reset_bar[2] = {3, 5};
+
+	plx_pci_reset_common(pdev);
+
+	for (i = 0; i < 2; i++) {
+		reset_addr = pci_iomap(pdev, reset_bar[i], 0);
+		if (!reset_addr) {
+			dev_err(&pdev->dev, "Failed to remap reset "
+				"space %d (BAR%d)\n", i, reset_bar[i]);
+		} else {
+			/* reset the SJA1000 chip */
+			iowrite8(0x1, reset_addr);
+			udelay(100);
+			pci_iounmap(pdev, reset_addr);
+		}
+	}
+}
+
+static void plx_pci_del_card(struct pci_dev *pdev)
+{
+	struct plx_pci_card *card = pci_get_drvdata(pdev);
+	struct net_device *dev;
+	struct sja1000_priv *priv;
+	int i = 0;
+
+	for (i = 0; i < card->channels; i++) {
+		dev = card->net_dev[i];
+		if (!dev)
+			continue;
+
+		dev_info(&pdev->dev, "Removing %s\n", dev->name);
+		unregister_sja1000dev(dev);
+		priv = netdev_priv(dev);
+		if (priv->reg_base)
+			pci_iounmap(pdev, priv->reg_base);
+		free_sja1000dev(dev);
+	}
+
+	plx_pci_reset_common(pdev);
+
+	/*
+	 * Disable interrupts from PCI-card (PLX90xx) and disable Local_1,
+	 * Local_2 interrupts
+	 */
+	iowrite32(0x0, card->conf_addr + PLX_INTCSR);
+
+	if (card->conf_addr)
+		pci_iounmap(pdev, card->conf_addr);
+
+	kfree(card);
+
+	pci_disable_device(pdev);
+	pci_set_drvdata(pdev, NULL);
+}
+
+/*
+ * Probe PLX90xx based device for the SJA1000 chips and register each
+ * available CAN channel to SJA1000 Socket-CAN subsystem.
+ */
+static int __devinit plx_pci_add_card(struct pci_dev *pdev,
+				      const struct pci_device_id *ent)
+{
+	struct sja1000_priv *priv;
+	struct net_device *dev;
+	struct plx_pci_card *card;
+	struct plx_pci_card_info *ci;
+	int err, i;
+	u32 val;
+	void __iomem *addr;
+
+	ci = (struct plx_pci_card_info *)ent->driver_data;
+
+	if (pci_enable_device(pdev) < 0) {
+		dev_err(&pdev->dev, "Failed to enable PCI device\n");
+		return -ENODEV;
+	}
+
+	dev_info(&pdev->dev, "Detected \"%s\" card at slot #%i\n",
+		 ci->name, PCI_SLOT(pdev->devfn));
+
+	/* Allocate card structures to hold addresses, ... */
+	card = kzalloc(sizeof(*card), GFP_KERNEL);
+	if (!card) {
+		dev_err(&pdev->dev, "Unable to allocate memory\n");
+		pci_disable_device(pdev);
+		return -ENOMEM;
+	}
+
+	pci_set_drvdata(pdev, card);
+
+	card->channels = 0;
+
+	/* Remap PLX90xx configuration space */
+	addr = pci_iomap(pdev, ci->conf_map.bar, ci->conf_map.size);
+	if (!addr) {
+		err = -ENOMEM;
+		dev_err(&pdev->dev, "Failed to remap configuration space "
+			"(BAR%d)\n", ci->conf_map.bar);
+		goto failure_cleanup;
+	}
+	card->conf_addr = addr + ci->conf_map.offset;
+
+	ci->reset_func(pdev);
+
+	/* Detect available channels */
+	for (i = 0; i < ci->channel_count; i++) {
+		struct plx_pci_channel_map *cm = &ci->chan_map_tbl[i];
+
+		dev = alloc_sja1000dev(0);
+		if (!dev) {
+			err = -ENOMEM;
+			goto failure_cleanup;
+		}
+
+		card->net_dev[i] = dev;
+		priv = netdev_priv(dev);
+		priv->priv = card;
+		priv->irq_flags = IRQF_SHARED;
+
+		dev->irq = pdev->irq;
+
+		/*
+		 * Remap IO space of the SJA1000 chips
+		 * This is device-dependent mapping
+		 */
+		addr = pci_iomap(pdev, cm->bar, cm->size);
+		if (!addr) {
+			err = -ENOMEM;
+			dev_err(&pdev->dev, "Failed to remap BAR%d\n", cm->bar);
+			goto failure_cleanup;
+		}
+
+		priv->reg_base = addr + cm->offset;
+		priv->read_reg = plx_pci_read_reg;
+		priv->write_reg = plx_pci_write_reg;
+
+		/* Check if channel is present */
+		if (plx_pci_check_sja1000(priv)) {
+			priv->can.clock.freq = ci->can_clock;
+			priv->ocr = ci->ocr;
+			priv->cdr = ci->cdr;
+
+			SET_NETDEV_DEV(dev, &pdev->dev);
+
+			/* Register SJA1000 device */
+			err = register_sja1000dev(dev);
+			if (err) {
+				dev_err(&pdev->dev, "Registering device failed "
+					"(err=%d)\n", err);
+				free_sja1000dev(dev);
+				goto failure_cleanup;
+			}
+
+			card->channels++;
+
+			dev_info(&pdev->dev, "Channel #%d at 0x%p, irq %d "
+				 "registered as %s\n", i + 1, priv->reg_base,
+				 dev->irq, dev->name);
+		} else {
+			dev_err(&pdev->dev, "Channel #%d not detected\n",
+				i + 1);
+			free_sja1000dev(dev);
+		}
+	}
+
+	if (!card->channels) {
+		err = -ENODEV;
+		goto failure_cleanup;
+	}
+
+	/*
+	 * Enable interrupts from PCI-card (PLX90xx) and enable Local_1,
+	 * Local_2 interrupts from the SJA1000 chips
+	 */
+	val = ioread32(card->conf_addr + PLX_INTCSR);
+	val |= PLX_LINT1_EN | PLX_LINT2_EN | PLX_PCI_INT_EN;
+	iowrite32(val, card->conf_addr + PLX_INTCSR);
+
+	return 0;
+
+failure_cleanup:
+	dev_err(&pdev->dev, "Error: %d. Cleaning Up.\n", err);
+
+	plx_pci_del_card(pdev);
+
+	return err;
+}
+
+static struct pci_driver plx_pci_driver = {
+	.name = DRV_NAME,
+	.id_table = plx_pci_tbl,
+	.probe = plx_pci_add_card,
+	.remove = plx_pci_del_card,
+};
+
+static int __init plx_pci_init(void)
+{
+	return pci_register_driver(&plx_pci_driver);
+}
+
+static void __exit plx_pci_exit(void)
+{
+	pci_unregister_driver(&plx_pci_driver);
+}
+
+module_init(plx_pci_init);
+module_exit(plx_pci_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/sja1000.c linux-libre-2.6.34-gnu1/drivers/net/can/sja1000/sja1000.c
--- linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/sja1000.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/sja1000/sja1000.c	2010-05-16 17:17:36.000000000 -0400
@@ -130,8 +130,12 @@ static void set_normal_mode(struct net_d
 		/* check reset bit */
 		if ((status & MOD_RM) == 0) {
 			priv->can.state = CAN_STATE_ERROR_ACTIVE;
-			/* enable all interrupts */
-			priv->write_reg(priv, REG_IER, IRQ_ALL);
+			/* enable interrupts */
+			if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
+				priv->write_reg(priv, REG_IER, IRQ_ALL);
+			else
+				priv->write_reg(priv, REG_IER,
+						IRQ_ALL & ~IRQ_BEI);
 			return;
 		}
 
@@ -203,6 +207,17 @@ static int sja1000_set_bittiming(struct
 	return 0;
 }
 
+static int sja1000_get_berr_counter(const struct net_device *dev,
+				    struct can_berr_counter *bec)
+{
+	struct sja1000_priv *priv = netdev_priv(dev);
+
+	bec->txerr = priv->read_reg(priv, REG_TXERR);
+	bec->rxerr = priv->read_reg(priv, REG_RXERR);
+
+	return 0;
+}
+
 /*
  * initialize SJA1000 chip:
  *   - reset chip
@@ -249,6 +264,9 @@ static netdev_tx_t sja1000_start_xmit(st
 	uint8_t dreg;
 	int i;
 
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
+
 	netif_stop_queue(dev);
 
 	fi = dlc = cf->can_dlc;
@@ -434,6 +452,8 @@ static int sja1000_err(struct net_device
 				CAN_ERR_CRTL_TX_PASSIVE :
 				CAN_ERR_CRTL_RX_PASSIVE;
 		}
+		cf->data[6] = txerr;
+		cf->data[7] = rxerr;
 	}
 
 	priv->can.state = state;
@@ -564,6 +584,9 @@ struct net_device *alloc_sja1000dev(int
 	priv->can.bittiming_const = &sja1000_bittiming_const;
 	priv->can.do_set_bittiming = sja1000_set_bittiming;
 	priv->can.do_set_mode = sja1000_set_mode;
+	priv->can.do_get_berr_counter = sja1000_get_berr_counter;
+	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
+		CAN_CTRLMODE_BERR_REPORTING;
 
 	if (sizeof_priv)
 		priv->priv = (void *)priv + sizeof(struct sja1000_priv);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/ti_hecc.c linux-libre-2.6.34-gnu1/drivers/net/can/ti_hecc.c
--- linux-libre-2.6.33-gnu1/drivers/net/can/ti_hecc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/ti_hecc.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,9 +28,11 @@
  *         .mbx_offset             = 0x2000,
  *         .int_line               = 0,
  *         .revision               = 1,
+ *         .transceiver_switch     = hecc_phy_control,
  * };
  *
- * Please see include/can/platform/ti_hecc.h for description of above fields
+ * Please see include/linux/can/platform/ti_hecc.h for description of
+ * above fields.
  *
  */
 
@@ -220,6 +222,7 @@ struct ti_hecc_priv {
 	u32 tx_head;
 	u32 tx_tail;
 	u32 rx_next;
+	void (*transceiver_switch)(int);
 };
 
 static inline int get_tx_head_mb(struct ti_hecc_priv *priv)
@@ -317,6 +320,13 @@ static int ti_hecc_set_btc(struct ti_hec
 	return 0;
 }
 
+static void ti_hecc_transceiver_switch(const struct ti_hecc_priv *priv,
+					int on)
+{
+	if (priv->transceiver_switch)
+		priv->transceiver_switch(on);
+}
+
 static void ti_hecc_reset(struct net_device *ndev)
 {
 	u32 cnt;
@@ -477,6 +487,9 @@ static netdev_tx_t ti_hecc_xmit(struct s
 	u32 mbxno, mbx_mask, data;
 	unsigned long flags;
 
+	if (can_dropped_invalid_skb(ndev, skb))
+		return NETDEV_TX_OK;
+
 	mbxno = get_tx_head_mb(priv);
 	mbx_mask = BIT(mbxno);
 	spin_lock_irqsave(&priv->mbx_lock, flags);
@@ -491,7 +504,6 @@ static netdev_tx_t ti_hecc_xmit(struct s
 	spin_unlock_irqrestore(&priv->mbx_lock, flags);
 
 	/* Prepare mailbox for transmission */
-	data = min_t(u8, cf->can_dlc, 8);
 	if (cf->can_id & CAN_RTR_FLAG) /* Remote transmission request */
 		data |= HECC_CANMCF_RTR;
 	data |= get_tx_head_prio(priv) << 8;
@@ -816,15 +828,17 @@ static int ti_hecc_open(struct net_devic
 		return err;
 	}
 
+	ti_hecc_transceiver_switch(priv, 1);
+
 	/* Open common can device */
 	err = open_candev(ndev);
 	if (err) {
 		dev_err(ndev->dev.parent, "open_candev() failed %d\n", err);
+		ti_hecc_transceiver_switch(priv, 0);
 		free_irq(ndev->irq, ndev);
 		return err;
 	}
 
-	clk_enable(priv->clk);
 	ti_hecc_start(ndev);
 	napi_enable(&priv->napi);
 	netif_start_queue(ndev);
@@ -840,8 +854,8 @@ static int ti_hecc_close(struct net_devi
 	napi_disable(&priv->napi);
 	ti_hecc_stop(ndev);
 	free_irq(ndev->irq, ndev);
-	clk_disable(priv->clk);
 	close_candev(ndev);
+	ti_hecc_transceiver_switch(priv, 0);
 
 	return 0;
 }
@@ -903,10 +917,12 @@ static int ti_hecc_probe(struct platform
 	priv->hecc_ram_offset = pdata->hecc_ram_offset;
 	priv->mbx_offset = pdata->mbx_offset;
 	priv->int_line = pdata->int_line;
+	priv->transceiver_switch = pdata->transceiver_switch;
 
 	priv->can.bittiming_const = &ti_hecc_bittiming_const;
 	priv->can.do_set_mode = ti_hecc_do_set_mode;
 	priv->can.do_get_state = ti_hecc_get_state;
+	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
 	ndev->irq = irq->start;
 	ndev->flags |= IFF_ECHO;
@@ -925,6 +941,7 @@ static int ti_hecc_probe(struct platform
 	netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll,
 		HECC_DEF_NAPI_WEIGHT);
 
+	clk_enable(priv->clk);
 	err = register_candev(ndev);
 	if (err) {
 		dev_err(&pdev->dev, "register_candev() failed\n");
@@ -953,6 +970,7 @@ static int __devexit ti_hecc_remove(stru
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct ti_hecc_priv *priv = netdev_priv(ndev);
 
+	clk_disable(priv->clk);
 	clk_put(priv->clk);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	iounmap(priv->base);
@@ -964,6 +982,48 @@ static int __devexit ti_hecc_remove(stru
 	return 0;
 }
 
+
+#ifdef CONFIG_PM
+static int ti_hecc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+	struct ti_hecc_priv *priv = netdev_priv(dev);
+
+	if (netif_running(dev)) {
+		netif_stop_queue(dev);
+		netif_device_detach(dev);
+	}
+
+	hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
+	priv->can.state = CAN_STATE_SLEEPING;
+
+	clk_disable(priv->clk);
+
+	return 0;
+}
+
+static int ti_hecc_resume(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+	struct ti_hecc_priv *priv = netdev_priv(dev);
+
+	clk_enable(priv->clk);
+
+	hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	if (netif_running(dev)) {
+		netif_device_attach(dev);
+		netif_start_queue(dev);
+	}
+
+	return 0;
+}
+#else
+#define ti_hecc_suspend NULL
+#define ti_hecc_resume NULL
+#endif
+
 /* TI HECC netdevice driver: platform driver structure */
 static struct platform_driver ti_hecc_driver = {
 	.driver = {
@@ -972,6 +1032,8 @@ static struct platform_driver ti_hecc_dr
 	},
 	.probe = ti_hecc_probe,
 	.remove = __devexit_p(ti_hecc_remove),
+	.suspend = ti_hecc_suspend,
+	.resume = ti_hecc_resume,
 };
 
 static int __init ti_hecc_init_driver(void)
@@ -979,14 +1041,15 @@ static int __init ti_hecc_init_driver(vo
 	printk(KERN_INFO DRV_DESC "\n");
 	return platform_driver_register(&ti_hecc_driver);
 }
-module_init(ti_hecc_init_driver);
 
 static void __exit ti_hecc_exit_driver(void)
 {
 	printk(KERN_INFO DRV_DESC " unloaded\n");
 	platform_driver_unregister(&ti_hecc_driver);
 }
+
 module_exit(ti_hecc_exit_driver);
+module_init(ti_hecc_init_driver);
 
 MODULE_AUTHOR("Anant Gole <anantgole@ti.com>");
 MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/usb/ems_usb.c linux-libre-2.6.34-gnu1/drivers/net/can/usb/ems_usb.c
--- linux-libre-2.6.33-gnu1/drivers/net/can/usb/ems_usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/usb/ems_usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -767,6 +767,9 @@ static netdev_tx_t ems_usb_start_xmit(st
 	size_t size = CPC_HEADER_SIZE + CPC_MSG_HEADER_LEN
 			+ sizeof(struct cpc_can_msg);
 
+	if (can_dropped_invalid_skb(netdev, skb))
+		return NETDEV_TX_OK;
+
 	/* create a URB, and a buffer for it, and copy the data to the URB */
 	urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!urb) {
@@ -873,9 +876,7 @@ static netdev_tx_t ems_usb_start_xmit(st
 	return NETDEV_TX_OK;
 
 nomem:
-	if (skb)
-		dev_kfree_skb(skb);
-
+	dev_kfree_skb(skb);
 	stats->tx_dropped++;
 
 	return NETDEV_TX_OK;
@@ -1005,7 +1006,7 @@ static int ems_usb_probe(struct usb_inte
 
 	netdev = alloc_candev(sizeof(struct ems_usb), MAX_TX_URBS);
 	if (!netdev) {
-		dev_err(netdev->dev.parent, "Couldn't alloc candev\n");
+		dev_err(&intf->dev, "ems_usb: Couldn't alloc candev\n");
 		return -ENOMEM;
 	}
 
@@ -1019,8 +1020,7 @@ static int ems_usb_probe(struct usb_inte
 	dev->can.bittiming_const = &ems_usb_bittiming_const;
 	dev->can.do_set_bittiming = ems_usb_set_bittiming;
 	dev->can.do_set_mode = ems_usb_set_mode;
-
-	netdev->flags |= IFF_ECHO; /* we support local echo */
+	dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
 	netdev->netdev_ops = &ems_usb_netdev_ops;
 
@@ -1036,20 +1036,20 @@ static int ems_usb_probe(struct usb_inte
 
 	dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!dev->intr_urb) {
-		dev_err(netdev->dev.parent, "Couldn't alloc intr URB\n");
+		dev_err(&intf->dev, "Couldn't alloc intr URB\n");
 		goto cleanup_candev;
 	}
 
 	dev->intr_in_buffer = kzalloc(INTR_IN_BUFFER_SIZE, GFP_KERNEL);
 	if (!dev->intr_in_buffer) {
-		dev_err(netdev->dev.parent, "Couldn't alloc Intr buffer\n");
+		dev_err(&intf->dev, "Couldn't alloc Intr buffer\n");
 		goto cleanup_intr_urb;
 	}
 
 	dev->tx_msg_buffer = kzalloc(CPC_HEADER_SIZE +
 				     sizeof(struct ems_cpc_msg), GFP_KERNEL);
 	if (!dev->tx_msg_buffer) {
-		dev_err(netdev->dev.parent, "Couldn't alloc Tx buffer\n");
+		dev_err(&intf->dev, "Couldn't alloc Tx buffer\n");
 		goto cleanup_intr_in_buffer;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/usb/Kconfig linux-libre-2.6.34-gnu1/drivers/net/can/usb/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/net/can/usb/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/usb/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,6 @@ config CAN_EMS_USB
 	tristate "EMS CPC-USB/ARM7 CAN/USB interface"
 	---help---
 	  This driver is for the one channel CPC-USB/ARM7 CAN/USB interface
-	  from from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
+	  from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
 
 endmenu
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/can/vcan.c linux-libre-2.6.34-gnu1/drivers/net/can/vcan.c
--- linux-libre-2.6.33-gnu1/drivers/net/can/vcan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/can/vcan.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,8 @@
 #include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/slab.h>
 #include <net/rtnetlink.h>
 
 static __initdata const char banner[] =
@@ -70,10 +72,11 @@ MODULE_PARM_DESC(echo, "Echo sent frames
 
 static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
 {
+	struct can_frame *cf = (struct can_frame *)skb->data;
 	struct net_device_stats *stats = &dev->stats;
 
 	stats->rx_packets++;
-	stats->rx_bytes += skb->len;
+	stats->rx_bytes += cf->can_dlc;
 
 	skb->protocol  = htons(ETH_P_CAN);
 	skb->pkt_type  = PACKET_BROADCAST;
@@ -85,11 +88,15 @@ static void vcan_rx(struct sk_buff *skb,
 
 static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
 {
+	struct can_frame *cf = (struct can_frame *)skb->data;
 	struct net_device_stats *stats = &dev->stats;
 	int loop;
 
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
+
 	stats->tx_packets++;
-	stats->tx_bytes += skb->len;
+	stats->tx_bytes += cf->can_dlc;
 
 	/* set flag whether this packet has to be looped back */
 	loop = skb->pkt_type == PACKET_LOOPBACK;
@@ -103,7 +110,7 @@ static netdev_tx_t vcan_tx(struct sk_buf
 			 * CAN core already did the echo for us
 			 */
 			stats->rx_packets++;
-			stats->rx_bytes += skb->len;
+			stats->rx_bytes += cf->can_dlc;
 		}
 		kfree_skb(skb);
 		return NETDEV_TX_OK;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cassini.c linux-libre-2.6.34-gnu1/drivers/net/cassini.c
--- linux-libre-2.6.33-gnu1/drivers/net/cassini.c	2013-05-03 12:08:03.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/cassini.c	2013-05-03 09:47:26.000000000 -0400
@@ -66,6 +66,7 @@
  * by default, the selective clear mask is set up to process rx packets.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -106,7 +107,7 @@
 #define cas_page_unmap(x)    kunmap_atomic((x), KM_SKB_DATA_SOFTIRQ)
 #define CAS_NCPUS            num_online_cpus()
 
-#if defined(CONFIG_CASSINI_NAPI) && defined(HAVE_NETDEV_POLL)
+#ifdef CONFIG_CASSINI_NAPI
 #define USE_NAPI
 #define cas_skb_release(x)  netif_receive_skb(x)
 #else
@@ -143,7 +144,6 @@
 #undef  RX_COUNT_BUFFERS    /* define to calculate RX buffer stats */
 
 #define DRV_MODULE_NAME		"cassini"
-#define PFX DRV_MODULE_NAME	": "
 #define DRV_MODULE_VERSION	"1.6"
 #define DRV_MODULE_RELDATE	"21 May 2008"
 
@@ -236,7 +236,7 @@ static u16 link_modes[] __devinitdata =
 	CAS_BMCR_SPEED1000|BMCR_FULLDPLX /* 5 : 1000bt full duplex */
 };
 
-static struct pci_device_id cas_pci_tbl[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(cas_pci_tbl) = {
 	{ PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_CASSINI,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SATURN,
@@ -649,9 +649,8 @@ static cas_page_t *cas_page_dequeue(stru
 		cas_spare_recover(cp, GFP_ATOMIC);
 		spin_lock(&cp->rx_spare_lock);
 		if (list_empty(&cp->rx_spare_list)) {
-			if (netif_msg_rx_err(cp))
-				printk(KERN_ERR "%s: no spare buffers "
-				       "available.\n", cp->dev->name);
+			netif_err(cp, rx_err, cp->dev,
+				  "no spare buffers available\n");
 			spin_unlock(&cp->rx_spare_lock);
 			return NULL;
 		}
@@ -728,12 +727,10 @@ static void cas_begin_auto_negotiation(s
 #endif
 start_aneg:
 	if (cp->lstate == link_up) {
-		printk(KERN_INFO "%s: PCS link down.\n",
-		       cp->dev->name);
+		netdev_info(cp->dev, "PCS link down\n");
 	} else {
 		if (changed) {
-			printk(KERN_INFO "%s: link configuration changed\n",
-			       cp->dev->name);
+			netdev_info(cp->dev, "link configuration changed\n");
 		}
 	}
 	cp->lstate = link_down;
@@ -826,12 +823,12 @@ static int cas_saturn_firmware_init(stru
 
 	err = reject_firmware(&fw, fw_name, &cp->pdev->dev);
 	if (err) {
-		printk(KERN_ERR "cassini: Failed to load firmware \"%s\"\n",
+		pr_err("Failed to load firmware \"%s\"\n",
 		       fw_name);
 		return err;
 	}
 	if (fw->size < 2) {
-		printk(KERN_ERR "cassini: bogus length %zu in \"%s\"\n",
+		pr_err("bogus length %zu in \"%s\"\n",
 		       fw->size, fw_name);
 		err = -EINVAL;
 		goto out;
@@ -841,7 +838,7 @@ static int cas_saturn_firmware_init(stru
 	cp->fw_data = vmalloc(cp->fw_size);
 	if (!cp->fw_data) {
 		err = -ENOMEM;
-		printk(KERN_ERR "cassini: \"%s\" Failed %d\n", fw_name, err);
+		pr_err("\"%s\" Failed %d\n", fw_name, err);
 		goto out;
 	}
 	memcpy(cp->fw_data, &fw->data[2], cp->fw_size);
@@ -986,9 +983,8 @@ static void cas_phy_init(struct cas *cp)
 				break;
 		}
 		if (limit <= 0)
-			printk(KERN_WARNING "%s: PCS reset bit would not "
-			       "clear [%08x].\n", cp->dev->name,
-			       readl(cp->regs + REG_PCS_STATE_MACHINE));
+			netdev_warn(cp->dev, "PCS reset bit would not clear [%08x]\n",
+				    readl(cp->regs + REG_PCS_STATE_MACHINE));
 
 		/* Make sure PCS is disabled while changing advertisement
 		 * configuration.
@@ -1030,11 +1026,8 @@ static int cas_pcs_link_check(struct cas
 	 */
 	if ((stat & (PCS_MII_STATUS_AUTONEG_COMP |
 		     PCS_MII_STATUS_REMOTE_FAULT)) ==
-	    (PCS_MII_STATUS_AUTONEG_COMP | PCS_MII_STATUS_REMOTE_FAULT)) {
-		if (netif_msg_link(cp))
-			printk(KERN_INFO "%s: PCS RemoteFault\n",
-			       cp->dev->name);
-	}
+	    (PCS_MII_STATUS_AUTONEG_COMP | PCS_MII_STATUS_REMOTE_FAULT))
+		netif_info(cp, link, cp->dev, "PCS RemoteFault\n");
 
 	/* work around link detection issue by querying the PCS state
 	 * machine directly.
@@ -1081,10 +1074,8 @@ static int cas_pcs_link_check(struct cas
 			cp->link_transition = LINK_TRANSITION_ON_FAILURE;
 		}
 		netif_carrier_off(cp->dev);
-		if (cp->opened && netif_msg_link(cp)) {
-			printk(KERN_INFO "%s: PCS link down.\n",
-			       cp->dev->name);
-		}
+		if (cp->opened)
+			netif_info(cp, link, cp->dev, "PCS link down\n");
 
 		/* Cassini only: if you force a mode, there can be
 		 * sync problems on link down. to fix that, the following
@@ -1139,9 +1130,8 @@ static int cas_txmac_interrupt(struct ne
 	if (!txmac_stat)
 		return 0;
 
-	if (netif_msg_intr(cp))
-		printk(KERN_DEBUG "%s: txmac interrupt, txmac_stat: 0x%x\n",
-			cp->dev->name, txmac_stat);
+	netif_printk(cp, intr, KERN_DEBUG, cp->dev,
+		     "txmac interrupt, txmac_stat: 0x%x\n", txmac_stat);
 
 	/* Defer timer expiration is quite normal,
 	 * don't even log the event.
@@ -1152,14 +1142,12 @@ static int cas_txmac_interrupt(struct ne
 
 	spin_lock(&cp->stat_lock[0]);
 	if (txmac_stat & MAC_TX_UNDERRUN) {
-		printk(KERN_ERR "%s: TX MAC xmit underrun.\n",
-		       dev->name);
+		netdev_err(dev, "TX MAC xmit underrun\n");
 		cp->net_stats[0].tx_fifo_errors++;
 	}
 
 	if (txmac_stat & MAC_TX_MAX_PACKET_ERR) {
-		printk(KERN_ERR "%s: TX MAC max packet size error.\n",
-		       dev->name);
+		netdev_err(dev, "TX MAC max packet size error\n");
 		cp->net_stats[0].tx_errors++;
 	}
 
@@ -1487,8 +1475,7 @@ static int cas_rxmac_reset(struct cas *c
 		udelay(10);
 	}
 	if (limit == STOP_TRIES) {
-		printk(KERN_ERR "%s: RX MAC will not disable, resetting whole "
-		       "chip.\n", dev->name);
+		netdev_err(dev, "RX MAC will not disable, resetting whole chip\n");
 		return 1;
 	}
 
@@ -1500,8 +1487,7 @@ static int cas_rxmac_reset(struct cas *c
 		udelay(10);
 	}
 	if (limit == STOP_TRIES) {
-		printk(KERN_ERR "%s: RX DMA will not disable, resetting whole "
-		       "chip.\n", dev->name);
+		netdev_err(dev, "RX DMA will not disable, resetting whole chip\n");
 		return 1;
 	}
 
@@ -1515,8 +1501,7 @@ static int cas_rxmac_reset(struct cas *c
 		udelay(10);
 	}
 	if (limit == STOP_TRIES) {
-		printk(KERN_ERR "%s: RX reset command will not execute, "
-		       "resetting whole chip.\n", dev->name);
+		netdev_err(dev, "RX reset command will not execute, resetting whole chip\n");
 		return 1;
 	}
 
@@ -1545,9 +1530,7 @@ static int cas_rxmac_interrupt(struct ne
 	if (!stat)
 		return 0;
 
-	if (netif_msg_intr(cp))
-		printk(KERN_DEBUG "%s: rxmac interrupt, stat: 0x%x\n",
-			cp->dev->name, stat);
+	netif_dbg(cp, intr, cp->dev, "rxmac interrupt, stat: 0x%x\n", stat);
 
 	/* these are all rollovers */
 	spin_lock(&cp->stat_lock[0]);
@@ -1580,9 +1563,8 @@ static int cas_mac_interrupt(struct net_
 	if (!stat)
 		return 0;
 
-	if (netif_msg_intr(cp))
-		printk(KERN_DEBUG "%s: mac interrupt, stat: 0x%x\n",
-			cp->dev->name, stat);
+	netif_printk(cp, intr, KERN_DEBUG, cp->dev,
+		     "mac interrupt, stat: 0x%x\n", stat);
 
 	/* This interrupt is just for pause frame and pause
 	 * tracking.  It is useful for diagnostics and debug
@@ -1605,9 +1587,7 @@ static inline int cas_mdio_link_not_up(s
 
 	switch (cp->lstate) {
 	case link_force_ret:
-		if (netif_msg_link(cp))
-			printk(KERN_INFO "%s: Autoneg failed again, keeping"
-				" forced mode\n", cp->dev->name);
+		netif_info(cp, link, cp->dev, "Autoneg failed again, keeping forced mode\n");
 		cas_phy_write(cp, MII_BMCR, cp->link_fcntl);
 		cp->timer_ticks = 5;
 		cp->lstate = link_force_ok;
@@ -1675,9 +1655,9 @@ static int cas_mii_link_check(struct cas
 			cas_mif_poll(cp, 0);
 			cp->link_fcntl = cas_phy_read(cp, MII_BMCR);
 			cp->timer_ticks = 5;
-			if (cp->opened && netif_msg_link(cp))
-				printk(KERN_INFO "%s: Got link after fallback, retrying"
-				       " autoneg once...\n", cp->dev->name);
+			if (cp->opened)
+				netif_info(cp, link, cp->dev,
+					   "Got link after fallback, retrying autoneg once...\n");
 			cas_phy_write(cp, MII_BMCR,
 				      cp->link_fcntl | BMCR_ANENABLE |
 				      BMCR_ANRESTART);
@@ -1704,9 +1684,8 @@ static int cas_mii_link_check(struct cas
 		cp->link_transition = LINK_TRANSITION_LINK_DOWN;
 
 		netif_carrier_off(cp->dev);
-		if (cp->opened && netif_msg_link(cp))
-			printk(KERN_INFO "%s: Link down\n",
-			       cp->dev->name);
+		if (cp->opened)
+			netif_info(cp, link, cp->dev, "Link down\n");
 		restart = 1;
 
 	} else if (++cp->timer_ticks > 10)
@@ -1737,23 +1716,23 @@ static int cas_pci_interrupt(struct net_
 	if (!stat)
 		return 0;
 
-	printk(KERN_ERR "%s: PCI error [%04x:%04x] ", dev->name, stat,
-	       readl(cp->regs + REG_BIM_DIAG));
+	netdev_err(dev, "PCI error [%04x:%04x]",
+		   stat, readl(cp->regs + REG_BIM_DIAG));
 
 	/* cassini+ has this reserved */
 	if ((stat & PCI_ERR_BADACK) &&
 	    ((cp->cas_flags & CAS_FLAG_REG_PLUS) == 0))
-		printk("<No ACK64# during ABS64 cycle> ");
+		pr_cont(" <No ACK64# during ABS64 cycle>");
 
 	if (stat & PCI_ERR_DTRTO)
-		printk("<Delayed transaction timeout> ");
+		pr_cont(" <Delayed transaction timeout>");
 	if (stat & PCI_ERR_OTHER)
-		printk("<other> ");
+		pr_cont(" <other>");
 	if (stat & PCI_ERR_BIM_DMA_WRITE)
-		printk("<BIM DMA 0 write req> ");
+		pr_cont(" <BIM DMA 0 write req>");
 	if (stat & PCI_ERR_BIM_DMA_READ)
-		printk("<BIM DMA 0 read req> ");
-	printk("\n");
+		pr_cont(" <BIM DMA 0 read req>");
+	pr_cont("\n");
 
 	if (stat & PCI_ERR_OTHER) {
 		u16 cfg;
@@ -1762,25 +1741,19 @@ static int cas_pci_interrupt(struct net_
 		 * true cause.
 		 */
 		pci_read_config_word(cp->pdev, PCI_STATUS, &cfg);
-		printk(KERN_ERR "%s: Read PCI cfg space status [%04x]\n",
-		       dev->name, cfg);
+		netdev_err(dev, "Read PCI cfg space status [%04x]\n", cfg);
 		if (cfg & PCI_STATUS_PARITY)
-			printk(KERN_ERR "%s: PCI parity error detected.\n",
-			       dev->name);
+			netdev_err(dev, "PCI parity error detected\n");
 		if (cfg & PCI_STATUS_SIG_TARGET_ABORT)
-			printk(KERN_ERR "%s: PCI target abort.\n",
-			       dev->name);
+			netdev_err(dev, "PCI target abort\n");
 		if (cfg & PCI_STATUS_REC_TARGET_ABORT)
-			printk(KERN_ERR "%s: PCI master acks target abort.\n",
-			       dev->name);
+			netdev_err(dev, "PCI master acks target abort\n");
 		if (cfg & PCI_STATUS_REC_MASTER_ABORT)
-			printk(KERN_ERR "%s: PCI master abort.\n", dev->name);
+			netdev_err(dev, "PCI master abort\n");
 		if (cfg & PCI_STATUS_SIG_SYSTEM_ERROR)
-			printk(KERN_ERR "%s: PCI system error SERR#.\n",
-			       dev->name);
+			netdev_err(dev, "PCI system error SERR#\n");
 		if (cfg & PCI_STATUS_DETECTED_PARITY)
-			printk(KERN_ERR "%s: PCI parity error.\n",
-			       dev->name);
+			netdev_err(dev, "PCI parity error\n");
 
 		/* Write the error bits back to clear them. */
 		cfg &= (PCI_STATUS_PARITY |
@@ -1806,9 +1779,8 @@ static int cas_abnormal_irq(struct net_d
 {
 	if (status & INTR_RX_TAG_ERROR) {
 		/* corrupt RX tag framing */
-		if (netif_msg_rx_err(cp))
-			printk(KERN_DEBUG "%s: corrupt rx tag framing\n",
-				cp->dev->name);
+		netif_printk(cp, rx_err, KERN_DEBUG, cp->dev,
+			     "corrupt rx tag framing\n");
 		spin_lock(&cp->stat_lock[0]);
 		cp->net_stats[0].rx_errors++;
 		spin_unlock(&cp->stat_lock[0]);
@@ -1817,9 +1789,8 @@ static int cas_abnormal_irq(struct net_d
 
 	if (status & INTR_RX_LEN_MISMATCH) {
 		/* length mismatch. */
-		if (netif_msg_rx_err(cp))
-			printk(KERN_DEBUG "%s: length mismatch for rx frame\n",
-				cp->dev->name);
+		netif_printk(cp, rx_err, KERN_DEBUG, cp->dev,
+			     "length mismatch for rx frame\n");
 		spin_lock(&cp->stat_lock[0]);
 		cp->net_stats[0].rx_errors++;
 		spin_unlock(&cp->stat_lock[0]);
@@ -1861,12 +1832,11 @@ do_reset:
 #if 1
 	atomic_inc(&cp->reset_task_pending);
 	atomic_inc(&cp->reset_task_pending_all);
-	printk(KERN_ERR "%s:reset called in cas_abnormal_irq [0x%x]\n",
-	       dev->name, status);
+	netdev_err(dev, "reset called in cas_abnormal_irq [0x%x]\n", status);
 	schedule_work(&cp->reset_task);
 #else
 	atomic_set(&cp->reset_task_pending, CAS_RESET_ALL);
-	printk(KERN_ERR "reset called in cas_abnormal_irq\n");
+	netdev_err(dev, "reset called in cas_abnormal_irq\n");
 	schedule_work(&cp->reset_task);
 #endif
 	return 1;
@@ -1920,9 +1890,8 @@ static inline void cas_tx_ringN(struct c
 		if (count < 0)
 			break;
 
-		if (netif_msg_tx_done(cp))
-			printk(KERN_DEBUG "%s: tx[%d] done, slot %d\n",
-			       cp->dev->name, ring, entry);
+		netif_printk(cp, tx_done, KERN_DEBUG, cp->dev,
+			     "tx[%d] done, slot %d\n", ring, entry);
 
 		skbs[entry] = NULL;
 		cp->tx_tiny_use[ring][entry].nbufs = 0;
@@ -1969,9 +1938,9 @@ static void cas_tx(struct net_device *de
 #ifdef USE_TX_COMPWB
 	u64 compwb = le64_to_cpu(cp->init_block->tx_compwb);
 #endif
-	if (netif_msg_intr(cp))
-		printk(KERN_DEBUG "%s: tx interrupt, status: 0x%x, %llx\n",
-			cp->dev->name, status, (unsigned long long)compwb);
+	netif_printk(cp, intr, KERN_DEBUG, cp->dev,
+		     "tx interrupt, status: 0x%x, %llx\n",
+		     status, (unsigned long long)compwb);
 	/* process all the rings */
 	for (ring = 0; ring < N_TX_RINGS; ring++) {
 #ifdef USE_TX_COMPWB
@@ -2050,10 +2019,8 @@ static int cas_rx_process_pkt(struct cas
 
 		hlen = min(cp->page_size - off, dlen);
 		if (hlen < 0) {
-			if (netif_msg_rx_err(cp)) {
-				printk(KERN_DEBUG "%s: rx page overflow: "
-				       "%d\n", cp->dev->name, hlen);
-			}
+			netif_printk(cp, rx_err, KERN_DEBUG, cp->dev,
+				     "rx page overflow: %d\n", hlen);
 			dev_kfree_skb_irq(skb);
 			return -1;
 		}
@@ -2130,10 +2097,8 @@ static int cas_rx_process_pkt(struct cas
 		off = CAS_VAL(RX_COMP1_DATA_OFF, words[0]) + swivel;
 		hlen = min(cp->page_size - off, dlen);
 		if (hlen < 0) {
-			if (netif_msg_rx_err(cp)) {
-				printk(KERN_DEBUG "%s: rx page overflow: "
-				       "%d\n", cp->dev->name, hlen);
-			}
+			netif_printk(cp, rx_err, KERN_DEBUG, cp->dev,
+				     "rx page overflow: %d\n", hlen);
 			dev_kfree_skb_irq(skb);
 			return -1;
 		}
@@ -2265,9 +2230,8 @@ static int cas_post_rxds_ringN(struct ca
 
 	entry = cp->rx_old[ring];
 
-	if (netif_msg_intr(cp))
-		printk(KERN_DEBUG "%s: rxd[%d] interrupt, done: %d\n",
-		       cp->dev->name, ring, entry);
+	netif_printk(cp, intr, KERN_DEBUG, cp->dev,
+		     "rxd[%d] interrupt, done: %d\n", ring, entry);
 
 	cluster = -1;
 	count = entry & 0x3;
@@ -2337,11 +2301,10 @@ static int cas_rx_ringN(struct cas *cp,
 	int entry, drops;
 	int npackets = 0;
 
-	if (netif_msg_intr(cp))
-		printk(KERN_DEBUG "%s: rx[%d] interrupt, done: %d/%d\n",
-		       cp->dev->name, ring,
-		       readl(cp->regs + REG_RX_COMP_HEAD),
-		       cp->rx_new[ring]);
+	netif_printk(cp, intr, KERN_DEBUG, cp->dev,
+		     "rx[%d] interrupt, done: %d/%d\n",
+		     ring,
+		     readl(cp->regs + REG_RX_COMP_HEAD), cp->rx_new[ring]);
 
 	entry = cp->rx_new[ring];
 	drops = 0;
@@ -2442,8 +2405,7 @@ static int cas_rx_ringN(struct cas *cp,
 	cp->rx_new[ring] = entry;
 
 	if (drops)
-		printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n",
-		       cp->dev->name);
+		netdev_info(cp->dev, "Memory squeeze, deferring packet\n");
 	return npackets;
 }
 
@@ -2457,10 +2419,9 @@ static void cas_post_rxcs_ringN(struct n
 
 	last = cp->rx_cur[ring];
 	entry = cp->rx_new[ring];
-	if (netif_msg_intr(cp))
-		printk(KERN_DEBUG "%s: rxc[%d] interrupt, done: %d/%d\n",
-		       dev->name, ring, readl(cp->regs + REG_RX_COMP_HEAD),
-		       entry);
+	netif_printk(cp, intr, KERN_DEBUG, dev,
+		     "rxc[%d] interrupt, done: %d/%d\n",
+		     ring, readl(cp->regs + REG_RX_COMP_HEAD), entry);
 
 	/* zero and re-mark descriptors */
 	while (last != entry) {
@@ -2729,42 +2690,38 @@ static void cas_tx_timeout(struct net_de
 {
 	struct cas *cp = netdev_priv(dev);
 
-	printk(KERN_ERR "%s: transmit timed out, resetting\n", dev->name);
+	netdev_err(dev, "transmit timed out, resetting\n");
 	if (!cp->hw_running) {
-		printk("%s: hrm.. hw not running!\n", dev->name);
+		netdev_err(dev, "hrm.. hw not running!\n");
 		return;
 	}
 
-	printk(KERN_ERR "%s: MIF_STATE[%08x]\n",
-	       dev->name, readl(cp->regs + REG_MIF_STATE_MACHINE));
+	netdev_err(dev, "MIF_STATE[%08x]\n",
+		   readl(cp->regs + REG_MIF_STATE_MACHINE));
 
-	printk(KERN_ERR "%s: MAC_STATE[%08x]\n",
-	       dev->name, readl(cp->regs + REG_MAC_STATE_MACHINE));
+	netdev_err(dev, "MAC_STATE[%08x]\n",
+		   readl(cp->regs + REG_MAC_STATE_MACHINE));
 
-	printk(KERN_ERR "%s: TX_STATE[%08x:%08x:%08x] "
-	       "FIFO[%08x:%08x:%08x] SM1[%08x] SM2[%08x]\n",
-	       dev->name,
-	       readl(cp->regs + REG_TX_CFG),
-	       readl(cp->regs + REG_MAC_TX_STATUS),
-	       readl(cp->regs + REG_MAC_TX_CFG),
-	       readl(cp->regs + REG_TX_FIFO_PKT_CNT),
-	       readl(cp->regs + REG_TX_FIFO_WRITE_PTR),
-	       readl(cp->regs + REG_TX_FIFO_READ_PTR),
-	       readl(cp->regs + REG_TX_SM_1),
-	       readl(cp->regs + REG_TX_SM_2));
+	netdev_err(dev, "TX_STATE[%08x:%08x:%08x] FIFO[%08x:%08x:%08x] SM1[%08x] SM2[%08x]\n",
+		   readl(cp->regs + REG_TX_CFG),
+		   readl(cp->regs + REG_MAC_TX_STATUS),
+		   readl(cp->regs + REG_MAC_TX_CFG),
+		   readl(cp->regs + REG_TX_FIFO_PKT_CNT),
+		   readl(cp->regs + REG_TX_FIFO_WRITE_PTR),
+		   readl(cp->regs + REG_TX_FIFO_READ_PTR),
+		   readl(cp->regs + REG_TX_SM_1),
+		   readl(cp->regs + REG_TX_SM_2));
 
-	printk(KERN_ERR "%s: RX_STATE[%08x:%08x:%08x]\n",
-	       dev->name,
-	       readl(cp->regs + REG_RX_CFG),
-	       readl(cp->regs + REG_MAC_RX_STATUS),
-	       readl(cp->regs + REG_MAC_RX_CFG));
+	netdev_err(dev, "RX_STATE[%08x:%08x:%08x]\n",
+		   readl(cp->regs + REG_RX_CFG),
+		   readl(cp->regs + REG_MAC_RX_STATUS),
+		   readl(cp->regs + REG_MAC_RX_CFG));
 
-	printk(KERN_ERR "%s: HP_STATE[%08x:%08x:%08x:%08x]\n",
-	       dev->name,
-	       readl(cp->regs + REG_HP_STATE_MACHINE),
-	       readl(cp->regs + REG_HP_STATUS0),
-	       readl(cp->regs + REG_HP_STATUS1),
-	       readl(cp->regs + REG_HP_STATUS2));
+	netdev_err(dev, "HP_STATE[%08x:%08x:%08x:%08x]\n",
+		   readl(cp->regs + REG_HP_STATE_MACHINE),
+		   readl(cp->regs + REG_HP_STATUS0),
+		   readl(cp->regs + REG_HP_STATUS1),
+		   readl(cp->regs + REG_HP_STATUS2));
 
 #if 1
 	atomic_inc(&cp->reset_task_pending);
@@ -2830,8 +2787,7 @@ static inline int cas_xmit_tx_ringN(stru
 	    CAS_TABORT(cp)*(skb_shinfo(skb)->nr_frags + 1)) {
 		netif_stop_queue(dev);
 		spin_unlock_irqrestore(&cp->tx_lock[ring], flags);
-		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when "
-		       "queue awake!\n", dev->name);
+		netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
 		return 1;
 	}
 
@@ -2908,11 +2864,9 @@ static inline int cas_xmit_tx_ringN(stru
 	if (TX_BUFFS_AVAIL(cp, ring) <= CAS_TABORT(cp)*(MAX_SKB_FRAGS + 1))
 		netif_stop_queue(dev);
 
-	if (netif_msg_tx_queued(cp))
-		printk(KERN_DEBUG "%s: tx[%d] queued, slot %d, skblen %d, "
-		       "avail %d\n",
-		       dev->name, ring, entry, skb->len,
-		       TX_BUFFS_AVAIL(cp, ring));
+	netif_printk(cp, tx_queued, KERN_DEBUG, dev,
+		     "tx[%d] queued, slot %d, skblen %d, avail %d\n",
+		     ring, entry, skb->len, TX_BUFFS_AVAIL(cp, ring));
 	writel(entry, cp->regs + REG_TX_KICKN(ring));
 	spin_unlock_irqrestore(&cp->tx_lock[ring], flags);
 	return 0;
@@ -2999,6 +2953,40 @@ static inline void cas_init_dma(struct c
 	cas_init_rx_dma(cp);
 }
 
+static void cas_process_mc_list(struct cas *cp)
+{
+	u16 hash_table[16];
+	u32 crc;
+	struct dev_mc_list *dmi;
+	int i = 1;
+
+	memset(hash_table, 0, sizeof(hash_table));
+	netdev_for_each_mc_addr(dmi, cp->dev) {
+		if (i <= CAS_MC_EXACT_MATCH_SIZE) {
+			/* use the alternate mac address registers for the
+			 * first 15 multicast addresses
+			 */
+			writel((dmi->dmi_addr[4] << 8) | dmi->dmi_addr[5],
+			       cp->regs + REG_MAC_ADDRN(i*3 + 0));
+			writel((dmi->dmi_addr[2] << 8) | dmi->dmi_addr[3],
+			       cp->regs + REG_MAC_ADDRN(i*3 + 1));
+			writel((dmi->dmi_addr[0] << 8) | dmi->dmi_addr[1],
+			       cp->regs + REG_MAC_ADDRN(i*3 + 2));
+			i++;
+		}
+		else {
+			/* use hw hash table for the next series of
+			 * multicast addresses
+			 */
+			crc = ether_crc_le(ETH_ALEN, dmi->dmi_addr);
+			crc >>= 24;
+			hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
+		}
+	}
+	for (i = 0; i < 16; i++)
+		writel(hash_table[i], cp->regs + REG_MAC_HASH_TABLEN(i));
+}
+
 /* Must be invoked under cp->lock. */
 static u32 cas_setup_multicast(struct cas *cp)
 {
@@ -3014,43 +3002,7 @@ static u32 cas_setup_multicast(struct ca
 		rxcfg |= MAC_RX_CFG_HASH_FILTER_EN;
 
 	} else {
-		u16 hash_table[16];
-		u32 crc;
-		struct dev_mc_list *dmi = cp->dev->mc_list;
-		int i;
-
-		/* use the alternate mac address registers for the
-		 * first 15 multicast addresses
-		 */
-		for (i = 1; i <= CAS_MC_EXACT_MATCH_SIZE; i++) {
-			if (!dmi) {
-				writel(0x0, cp->regs + REG_MAC_ADDRN(i*3 + 0));
-				writel(0x0, cp->regs + REG_MAC_ADDRN(i*3 + 1));
-				writel(0x0, cp->regs + REG_MAC_ADDRN(i*3 + 2));
-				continue;
-			}
-			writel((dmi->dmi_addr[4] << 8) | dmi->dmi_addr[5],
-			       cp->regs + REG_MAC_ADDRN(i*3 + 0));
-			writel((dmi->dmi_addr[2] << 8) | dmi->dmi_addr[3],
-			       cp->regs + REG_MAC_ADDRN(i*3 + 1));
-			writel((dmi->dmi_addr[0] << 8) | dmi->dmi_addr[1],
-			       cp->regs + REG_MAC_ADDRN(i*3 + 2));
-			dmi = dmi->next;
-		}
-
-		/* use hw hash table for the next series of
-		 * multicast addresses
-		 */
-		memset(hash_table, 0, sizeof(hash_table));
-		while (dmi) {
- 			crc = ether_crc_le(ETH_ALEN, dmi->dmi_addr);
-			crc >>= 24;
-			hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
-			dmi = dmi->next;
-		}
-	    	for (i=0; i < 16; i++)
-			writel(hash_table[i], cp->regs +
-			       REG_MAC_HASH_TABLEN(i));
+		cas_process_mc_list(cp);
 		rxcfg |= MAC_RX_CFG_HASH_FILTER_EN;
 	}
 
@@ -3100,10 +3052,10 @@ static void cas_mac_reset(struct cas *cp
 
 	if (readl(cp->regs + REG_MAC_TX_RESET) |
 	    readl(cp->regs + REG_MAC_RX_RESET))
-		printk(KERN_ERR "%s: mac tx[%d]/rx[%d] reset failed [%08x]\n",
-		       cp->dev->name, readl(cp->regs + REG_MAC_TX_RESET),
-		       readl(cp->regs + REG_MAC_RX_RESET),
-		       readl(cp->regs + REG_MAC_STATE_MACHINE));
+		netdev_err(cp->dev, "mac tx[%d]/rx[%d] reset failed [%08x]\n",
+			   readl(cp->regs + REG_MAC_TX_RESET),
+			   readl(cp->regs + REG_MAC_RX_RESET),
+			   readl(cp->regs + REG_MAC_STATE_MACHINE));
 }
 
 
@@ -3423,7 +3375,7 @@ use_random_mac_addr:
 		goto done;
 
 	/* Sun MAC prefix then 3 random bytes. */
-	printk(PFX "MAC address not found in ROM VPD\n");
+	pr_info("MAC address not found in ROM VPD\n");
 	dev_addr[0] = 0x08;
 	dev_addr[1] = 0x00;
 	dev_addr[2] = 0x20;
@@ -3484,7 +3436,7 @@ static int cas_check_invariants(struct c
 			__free_pages(page, CAS_JUMBO_PAGE_SHIFT - PAGE_SHIFT);
 			cp->page_order = CAS_JUMBO_PAGE_SHIFT - PAGE_SHIFT;
 		} else {
-			printk(PFX "MTU limited to %d bytes\n", CAS_MAX_MTU);
+			printk("MTU limited to %d bytes\n", CAS_MAX_MTU);
 		}
 	}
 #endif
@@ -3529,7 +3481,7 @@ static int cas_check_invariants(struct c
 			}
 		}
 	}
-	printk(KERN_ERR PFX "MII phy did not respond [%08x]\n",
+	pr_err("MII phy did not respond [%08x]\n",
 	       readl(cp->regs + REG_MIF_STATE_MACHINE));
 	return -1;
 
@@ -3574,21 +3526,19 @@ static inline void cas_start_dma(struct
 		val = readl(cp->regs + REG_MAC_RX_CFG);
 		if ((val & MAC_RX_CFG_EN)) {
 			if (txfailed) {
-			  printk(KERN_ERR
-				 "%s: enabling mac failed [tx:%08x:%08x].\n",
-				 cp->dev->name,
-				 readl(cp->regs + REG_MIF_STATE_MACHINE),
-				 readl(cp->regs + REG_MAC_STATE_MACHINE));
+				netdev_err(cp->dev,
+					   "enabling mac failed [tx:%08x:%08x]\n",
+					   readl(cp->regs + REG_MIF_STATE_MACHINE),
+					   readl(cp->regs + REG_MAC_STATE_MACHINE));
 			}
 			goto enable_rx_done;
 		}
 		udelay(10);
 	}
-	printk(KERN_ERR "%s: enabling mac failed [%s:%08x:%08x].\n",
-	       cp->dev->name,
-	       (txfailed? "tx,rx":"rx"),
-	       readl(cp->regs + REG_MIF_STATE_MACHINE),
-	       readl(cp->regs + REG_MAC_STATE_MACHINE));
+	netdev_err(cp->dev, "enabling mac failed [%s:%08x:%08x]\n",
+		   (txfailed ? "tx,rx" : "rx"),
+		   readl(cp->regs + REG_MIF_STATE_MACHINE),
+		   readl(cp->regs + REG_MAC_STATE_MACHINE));
 
 enable_rx_done:
 	cas_unmask_intr(cp); /* enable interrupts */
@@ -3690,9 +3640,8 @@ static void cas_set_link_modes(struct ca
 		}
 	}
 
-	if (netif_msg_link(cp))
-		printk(KERN_INFO "%s: Link up at %d Mbps, %s-duplex.\n",
-		       cp->dev->name, speed, (full_duplex ? "full" : "half"));
+	netif_info(cp, link, cp->dev, "Link up at %d Mbps, %s-duplex\n",
+		   speed, full_duplex ? "full" : "half");
 
 	val = MAC_XIF_TX_MII_OUTPUT_EN | MAC_XIF_LINK_LED;
 	if (CAS_PHY_MII(cp->phy_type)) {
@@ -3762,18 +3711,14 @@ static void cas_set_link_modes(struct ca
 
 	if (netif_msg_link(cp)) {
 		if (pause & 0x01) {
-			printk(KERN_INFO "%s: Pause is enabled "
-			       "(rxfifo: %d off: %d on: %d)\n",
-			       cp->dev->name,
-			       cp->rx_fifo_size,
-			       cp->rx_pause_off,
-			       cp->rx_pause_on);
+			netdev_info(cp->dev, "Pause is enabled (rxfifo: %d off: %d on: %d)\n",
+				    cp->rx_fifo_size,
+				    cp->rx_pause_off,
+				    cp->rx_pause_on);
 		} else if (pause & 0x10) {
-			printk(KERN_INFO "%s: TX pause enabled\n",
-			       cp->dev->name);
+			netdev_info(cp->dev, "TX pause enabled\n");
 		} else {
-			printk(KERN_INFO "%s: Pause is disabled\n",
-			       cp->dev->name);
+			netdev_info(cp->dev, "Pause is disabled\n");
 		}
 	}
 
@@ -3849,7 +3794,7 @@ static void cas_global_reset(struct cas
 			goto done;
 		udelay(10);
 	}
-	printk(KERN_ERR "%s: sw reset failed.\n", cp->dev->name);
+	netdev_err(cp->dev, "sw reset failed\n");
 
 done:
 	/* enable various BIM interrupts */
@@ -3955,7 +3900,7 @@ static int cas_change_mtu(struct net_dev
 #else
 	atomic_set(&cp->reset_task_pending, (cp->phy_type & CAS_PHY_SERDES) ?
 		   CAS_RESET_ALL : CAS_RESET_MTU);
-	printk(KERN_ERR "reset called in cas_change_mtu\n");
+	pr_err("reset called in cas_change_mtu\n");
 	schedule_work(&cp->reset_task);
 #endif
 
@@ -4237,10 +4182,8 @@ static void cas_link_timer(unsigned long
 
 		if (((tlm == 0x5) || (tlm == 0x3)) &&
 		    (CAS_VAL(MAC_SM_ENCAP_SM, val) == 0)) {
-			if (netif_msg_tx_err(cp))
-				printk(KERN_DEBUG "%s: tx err: "
-				       "MAC_STATE[%08x]\n",
-				       cp->dev->name, val);
+			netif_printk(cp, tx_err, KERN_DEBUG, cp->dev,
+				     "tx err: MAC_STATE[%08x]\n", val);
 			reset = 1;
 			goto done;
 		}
@@ -4249,10 +4192,9 @@ static void cas_link_timer(unsigned long
 		wptr = readl(cp->regs + REG_TX_FIFO_WRITE_PTR);
 		rptr = readl(cp->regs + REG_TX_FIFO_READ_PTR);
 		if ((val == 0) && (wptr != rptr)) {
-			if (netif_msg_tx_err(cp))
-				printk(KERN_DEBUG "%s: tx err: "
-				       "TX_FIFO[%08x:%08x:%08x]\n",
-				       cp->dev->name, val, wptr, rptr);
+			netif_printk(cp, tx_err, KERN_DEBUG, cp->dev,
+				     "tx err: TX_FIFO[%08x:%08x:%08x]\n",
+				     val, wptr, rptr);
 			reset = 1;
 		}
 
@@ -4268,7 +4210,7 @@ done:
 		schedule_work(&cp->reset_task);
 #else
 		atomic_set(&cp->reset_task_pending, CAS_RESET_ALL);
-		printk(KERN_ERR "reset called in cas_link_timer\n");
+		pr_err("reset called in cas_link_timer\n");
 		schedule_work(&cp->reset_task);
 #endif
 	}
@@ -4361,8 +4303,7 @@ static int cas_open(struct net_device *d
 	 */
 	if (request_irq(cp->pdev->irq, cas_interrupt,
 			IRQF_SHARED, dev->name, (void *) dev)) {
-		printk(KERN_ERR "%s: failed to request irq !\n",
-		       cp->dev->name);
+		netdev_err(cp->dev, "failed to request irq !\n");
 		err = -EAGAIN;
 		goto err_spare;
 	}
@@ -5002,24 +4943,24 @@ static int __devinit cas_init_one(struct
 	u8 orig_cacheline_size = 0, cas_cacheline_size = 0;
 
 	if (cas_version_printed++ == 0)
-		printk(KERN_INFO "%s", version);
+		pr_info("%s", version);
 
 	err = pci_enable_device(pdev);
 	if (err) {
-		dev_err(&pdev->dev, "Cannot enable PCI device, aborting.\n");
+		dev_err(&pdev->dev, "Cannot enable PCI device, aborting\n");
 		return err;
 	}
 
 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
 		dev_err(&pdev->dev, "Cannot find proper PCI device "
-		       "base address, aborting.\n");
+		       "base address, aborting\n");
 		err = -ENODEV;
 		goto err_out_disable_pdev;
 	}
 
 	dev = alloc_etherdev(sizeof(*cp));
 	if (!dev) {
-		dev_err(&pdev->dev, "Etherdev alloc failed, aborting.\n");
+		dev_err(&pdev->dev, "Etherdev alloc failed, aborting\n");
 		err = -ENOMEM;
 		goto err_out_disable_pdev;
 	}
@@ -5027,7 +4968,7 @@ static int __devinit cas_init_one(struct
 
 	err = pci_request_regions(pdev, dev->name);
 	if (err) {
-		dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting.\n");
+		dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting\n");
 		goto err_out_free_netdev;
 	}
 	pci_set_master(pdev);
@@ -5041,8 +4982,7 @@ static int __devinit cas_init_one(struct
 	pci_cmd |= PCI_COMMAND_PARITY;
 	pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
 	if (pci_try_set_mwi(pdev))
-		printk(KERN_WARNING PFX "Could not enable MWI for %s\n",
-		       pci_name(pdev));
+		pr_warning("Could not enable MWI for %s\n", pci_name(pdev));
 
 	cas_program_bridge(pdev);
 
@@ -5085,7 +5025,7 @@ static int __devinit cas_init_one(struct
 		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
 			dev_err(&pdev->dev, "No usable DMA configuration, "
-			       "aborting.\n");
+			       "aborting\n");
 			goto err_out_free_res;
 		}
 		pci_using_dac = 0;
@@ -5132,7 +5072,7 @@ static int __devinit cas_init_one(struct
 	INIT_WORK(&cp->reset_task, cas_reset_task);
 
 	/* Default link parameters */
-	if (link_mode >= 0 && link_mode <= 6)
+	if (link_mode >= 0 && link_mode < 6)
 		cp->link_cntl = link_modes[link_mode];
 	else
 		cp->link_cntl = BMCR_ANENABLE;
@@ -5144,7 +5084,7 @@ static int __devinit cas_init_one(struct
 	/* give us access to cassini registers */
 	cp->regs = pci_iomap(pdev, 0, casreg_len);
 	if (!cp->regs) {
-		dev_err(&pdev->dev, "Cannot map device registers, aborting.\n");
+		dev_err(&pdev->dev, "Cannot map device registers, aborting\n");
 		goto err_out_free_res;
 	}
 	cp->casreg_len = casreg_len;
@@ -5163,7 +5103,7 @@ static int __devinit cas_init_one(struct
 		pci_alloc_consistent(pdev, sizeof(struct cas_init_block),
 				     &cp->block_dvma);
 	if (!cp->init_block) {
-		dev_err(&pdev->dev, "Cannot allocate init block, aborting.\n");
+		dev_err(&pdev->dev, "Cannot allocate init block, aborting\n");
 		goto err_out_iounmap;
 	}
 
@@ -5197,18 +5137,17 @@ static int __devinit cas_init_one(struct
 		dev->features |= NETIF_F_HIGHDMA;
 
 	if (register_netdev(dev)) {
-		dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
+		dev_err(&pdev->dev, "Cannot register net device, aborting\n");
 		goto err_out_free_consistent;
 	}
 
 	i = readl(cp->regs + REG_BIM_CFG);
-	printk(KERN_INFO "%s: Sun Cassini%s (%sbit/%sMHz PCI/%s) "
-	       "Ethernet[%d] %pM\n",  dev->name,
-	       (cp->cas_flags & CAS_FLAG_REG_PLUS) ? "+" : "",
-	       (i & BIM_CFG_32BIT) ? "32" : "64",
-	       (i & BIM_CFG_66MHZ) ? "66" : "33",
-	       (cp->phy_type == CAS_PHY_SERDES) ? "Fi" : "Cu", pdev->irq,
-	       dev->dev_addr);
+	netdev_info(dev, "Sun Cassini%s (%sbit/%sMHz PCI/%s) Ethernet[%d] %pM\n",
+		    (cp->cas_flags & CAS_FLAG_REG_PLUS) ? "+" : "",
+		    (i & BIM_CFG_32BIT) ? "32" : "64",
+		    (i & BIM_CFG_66MHZ) ? "66" : "33",
+		    (cp->phy_type == CAS_PHY_SERDES) ? "Fi" : "Cu", pdev->irq,
+		    dev->dev_addr);
 
 	pci_set_drvdata(pdev, dev);
 	cp->hw_running = 1;
@@ -5322,7 +5261,7 @@ static int cas_resume(struct pci_dev *pd
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct cas *cp = netdev_priv(dev);
 
-	printk(KERN_INFO "%s: resuming\n", dev->name);
+	netdev_info(dev, "resuming\n");
 
 	mutex_lock(&cp->pm_mutex);
 	cas_hard_reset(cp);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/chelsio/common.h linux-libre-2.6.34-gnu1/drivers/net/chelsio/common.h
--- linux-libre-2.6.33-gnu1/drivers/net/chelsio/common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/chelsio/common.h	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,8 @@
  *                                                                           *
  ****************************************************************************/
 
+#define pr_fmt(fmt) "cxgb: " fmt
+
 #ifndef _CXGB_COMMON_H_
 #define _CXGB_COMMON_H_
 
@@ -49,34 +51,13 @@
 #include <linux/mdio.h>
 #include <linux/crc32.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/pci_ids.h>
 
 #define DRV_DESCRIPTION "Chelsio 10Gb Ethernet Driver"
 #define DRV_NAME "cxgb"
 #define DRV_VERSION "2.2"
-#define PFX      DRV_NAME ": "
-
-#define CH_ERR(fmt, ...)   printk(KERN_ERR PFX fmt, ## __VA_ARGS__)
-#define CH_WARN(fmt, ...)  printk(KERN_WARNING PFX fmt, ## __VA_ARGS__)
-#define CH_ALERT(fmt, ...) printk(KERN_ALERT PFX fmt, ## __VA_ARGS__)
-
-/*
- * More powerful macro that selectively prints messages based on msg_enable.
- * For info and debugging messages.
- */
-#define CH_MSG(adapter, level, category, fmt, ...) do { \
-	if ((adapter)->msg_enable & NETIF_MSG_##category) \
-		printk(KERN_##level PFX "%s: " fmt, (adapter)->name, \
-		       ## __VA_ARGS__); \
-} while (0)
-
-#ifdef DEBUG
-# define CH_DBG(adapter, category, fmt, ...) \
-	CH_MSG(adapter, DEBUG, category, fmt, ## __VA_ARGS__)
-#else
-# define CH_DBG(fmt, ...)
-#endif
 
 #define CH_DEVICE(devid, ssid, idx) \
 	{ PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, ssid, 0, 0, idx }
@@ -90,25 +71,13 @@
 typedef struct adapter adapter_t;
 
 struct t1_rx_mode {
-	struct net_device *dev;
-	u32 idx;
-	struct dev_mc_list *list;
+       struct net_device *dev;
 };
 
 #define t1_rx_mode_promisc(rm)	(rm->dev->flags & IFF_PROMISC)
 #define t1_rx_mode_allmulti(rm)	(rm->dev->flags & IFF_ALLMULTI)
-#define t1_rx_mode_mc_cnt(rm)	(rm->dev->mc_count)
-
-static inline u8 *t1_get_next_mcaddr(struct t1_rx_mode *rm)
-{
-	u8 *addr = NULL;
-
-	if (rm->idx++ < rm->dev->mc_count) {
-		addr = rm->list->dmi_addr;
-		rm->list = rm->list->next;
-	}
-	return addr;
-}
+#define t1_rx_mode_mc_cnt(rm)	(netdev_mc_count(rm->dev))
+#define t1_get_netdev(rm)	(rm->dev)
 
 #define	MAX_NPORTS 4
 #define PORT_MASK ((1 << MAX_NPORTS) - 1)
@@ -334,7 +303,7 @@ static inline int t1_is_asic(const adapt
 	return adapter->params.is_asic;
 }
 
-extern struct pci_device_id t1_pci_tbl[];
+extern const struct pci_device_id t1_pci_tbl[];
 
 static inline int adapter_matches_type(const adapter_t *adapter,
 				       int version, int revision)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/chelsio/cxgb2.c linux-libre-2.6.34-gnu1/drivers/net/chelsio/cxgb2.c
--- linux-libre-2.6.33-gnu1/drivers/net/chelsio/cxgb2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/chelsio/cxgb2.c	2010-05-16 17:17:36.000000000 -0400
@@ -125,8 +125,6 @@ static void t1_set_rxmode(struct net_dev
 	struct t1_rx_mode rm;
 
 	rm.dev = dev;
-	rm.idx = 0;
-	rm.list = dev->mc_list;
 	mac->ops->set_rx_mode(mac, &rm);
 }
 
@@ -976,7 +974,7 @@ void t1_fatal_err(struct adapter *adapte
 		t1_sge_stop(adapter->sge);
 		t1_interrupts_disable(adapter);
 	}
-	CH_ALERT("%s: encountered fatal error, operation suspended\n",
+	pr_alert("%s: encountered fatal error, operation suspended\n",
 		 adapter->name);
 }
 
@@ -1020,7 +1018,7 @@ static int __devinit init_one(struct pci
 		return err;
 
 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
-		CH_ERR("%s: cannot find PCI device memory base address\n",
+		pr_err("%s: cannot find PCI device memory base address\n",
 		       pci_name(pdev));
 		err = -ENODEV;
 		goto out_disable_pdev;
@@ -1030,20 +1028,20 @@ static int __devinit init_one(struct pci
 		pci_using_dac = 1;
 
 		if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
-			CH_ERR("%s: unable to obtain 64-bit DMA for "
+			pr_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_BIT_MASK(32))) != 0) {
-		CH_ERR("%s: no usable DMA configuration\n", pci_name(pdev));
+		pr_err("%s: no usable DMA configuration\n", pci_name(pdev));
 		goto out_disable_pdev;
 	}
 
 	err = pci_request_regions(pdev, DRV_NAME);
 	if (err) {
-		CH_ERR("%s: cannot obtain PCI resources\n", pci_name(pdev));
+		pr_err("%s: cannot obtain PCI resources\n", pci_name(pdev));
 		goto out_disable_pdev;
 	}
 
@@ -1071,7 +1069,7 @@ static int __devinit init_one(struct pci
 
 			adapter->regs = ioremap(mmio_start, mmio_len);
 			if (!adapter->regs) {
-				CH_ERR("%s: cannot map device registers\n",
+				pr_err("%s: cannot map device registers\n",
 				       pci_name(pdev));
 				err = -ENOMEM;
 				goto out_free_dev;
@@ -1150,8 +1148,8 @@ static int __devinit init_one(struct pci
 	for (i = 0; i < bi->port_number; ++i) {
 		err = register_netdev(adapter->port[i].dev);
 		if (err)
-			CH_WARN("%s: cannot register net device %s, skipping\n",
-				pci_name(pdev), adapter->port[i].dev->name);
+			pr_warning("%s: cannot register net device %s, skipping\n",
+				   pci_name(pdev), adapter->port[i].dev->name);
 		else {
 			/*
 			 * Change the name we use for messages to the name of
@@ -1164,7 +1162,7 @@ static int __devinit init_one(struct pci
 		}
 	}
 	if (!adapter->registered_device_map) {
-		CH_ERR("%s: could not register any net devices\n",
+		pr_err("%s: could not register any net devices\n",
 		       pci_name(pdev));
 		goto out_release_adapter_res;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/chelsio/espi.c linux-libre-2.6.34-gnu1/drivers/net/chelsio/espi.c
--- linux-libre-2.6.33-gnu1/drivers/net/chelsio/espi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/chelsio/espi.c	2010-05-16 17:17:36.000000000 -0400
@@ -76,7 +76,7 @@ static int tricn_write(adapter_t *adapte
 	} while (busy && --attempts);
 
 	if (busy)
-		CH_ERR("%s: TRICN write timed out\n", adapter->name);
+		pr_err("%s: TRICN write timed out\n", adapter->name);
 
 	return busy;
 }
@@ -86,7 +86,7 @@ static int tricn_init(adapter_t *adapter
 	int i, sme = 1;
 
 	if (!(readl(adapter->regs + A_ESPI_RX_RESET)  & F_RX_CLK_STATUS)) {
-		CH_ERR("%s: ESPI clock not ready\n", adapter->name);
+		pr_err("%s: ESPI clock not ready\n", adapter->name);
 		return -1;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/chelsio/pm3393.c linux-libre-2.6.34-gnu1/drivers/net/chelsio/pm3393.c
--- linux-libre-2.6.33-gnu1/drivers/net/chelsio/pm3393.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/chelsio/pm3393.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,7 @@
 #include "suni1x10gexp_regs.h"
 
 #include <linux/crc32.h>
+#include <linux/slab.h>
 
 #define OFFSET(REG_ADDR)    ((REG_ADDR) << 2)
 
@@ -251,8 +252,9 @@ static int pm3393_interrupt_handler(stru
 	/* Read the master interrupt status register. */
 	pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS,
 	       &master_intr_status);
-	CH_DBG(cmac->adapter, INTR, "PM3393 intr cause 0x%x\n",
-	       master_intr_status);
+	if (netif_msg_intr(cmac->adapter))
+		dev_dbg(&cmac->adapter->pdev->dev, "PM3393 intr cause 0x%x\n",
+			master_intr_status);
 
 	/* TBD XXX Lets just clear everything for now */
 	pm3393_interrupt_clear(cmac);
@@ -375,12 +377,12 @@ static int pm3393_set_rx_mode(struct cma
 		rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN;
 	} else if (t1_rx_mode_mc_cnt(rm)) {
 		/* Accept one or more multicast(s). */
-		u8 *addr;
+		struct dev_mc_list *dmi;
 		int bit;
 		u16 mc_filter[4] = { 0, };
 
-		while ((addr = t1_get_next_mcaddr(rm))) {
-			bit = (ether_crc(ETH_ALEN, addr) >> 23) & 0x3f;	/* bit[23:28] */
+		netdev_for_each_mc_addr(dmi, t1_get_netdev(rm)) {
+			bit = (ether_crc(ETH_ALEN, dmi->dmi_addr) >> 23) & 0x3f; /* bit[23:28] */
 			mc_filter[bit >> 4] |= 1 << (bit & 0xf);
 		}
 		pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_LOW, mc_filter[0]);
@@ -776,11 +778,12 @@ static int pm3393_mac_reset(adapter_t *
 		successful_reset = (is_pl4_reset_finished && !is_pl4_outof_lock
 				    && is_xaui_mabc_pll_locked);
 
-		CH_DBG(adapter, HW,
-		       "PM3393 HW reset %d: pl4_reset 0x%x, val 0x%x, "
-		       "is_pl4_outof_lock 0x%x, xaui_locked 0x%x\n",
-		       i, is_pl4_reset_finished, val, is_pl4_outof_lock,
-		       is_xaui_mabc_pll_locked);
+		if (netif_msg_hw(adapter))
+			dev_dbg(&adapter->pdev->dev,
+				"PM3393 HW reset %d: pl4_reset 0x%x, val 0x%x, "
+				"is_pl4_outof_lock 0x%x, xaui_locked 0x%x\n",
+				i, is_pl4_reset_finished, val,
+				is_pl4_outof_lock, is_xaui_mabc_pll_locked);
 	}
 	return successful_reset ? 0 : 1;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/chelsio/sge.c linux-libre-2.6.34-gnu1/drivers/net/chelsio/sge.c
--- linux-libre-2.6.33-gnu1/drivers/net/chelsio/sge.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/chelsio/sge.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,6 +53,7 @@
 #include <linux/ip.h>
 #include <linux/in.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 
 #include "cpl5_cmd.h"
 #include "sge.h"
@@ -248,7 +249,7 @@ static void restart_sched(unsigned long)
  *
  * Interrupts are handled by a single CPU and it is likely that on a MP system
  * the application is migrated to another CPU. In that scenario, we try to
- * seperate the RX(in irq context) and TX state in order to decrease memory
+ * separate the RX(in irq context) and TX state in order to decrease memory
  * contention.
  */
 struct sge {
@@ -267,7 +268,7 @@ struct sge {
 	struct sk_buff	*espibug_skb[MAX_NPORTS];
 	u32		sge_control;	/* shadow value of sge control reg */
 	struct sge_intr_counts stats;
-	struct sge_port_stats *port_stats[MAX_NPORTS];
+	struct sge_port_stats __percpu *port_stats[MAX_NPORTS];
 	struct sched	*tx_sched;
 	struct cmdQ cmdQ[SGE_CMDQ_N] ____cacheline_aligned_in_smp;
 };
@@ -953,7 +954,7 @@ int t1_sge_intr_error_handler(struct sge
 		sge->stats.respQ_empty++;
 	if (cause & F_RESPQ_OVERFLOW) {
 		sge->stats.respQ_overflow++;
-		CH_ALERT("%s: SGE response queue overflow\n",
+		pr_alert("%s: SGE response queue overflow\n",
 			 adapter->name);
 	}
 	if (cause & F_FL_EXHAUSTED) {
@@ -962,12 +963,12 @@ int t1_sge_intr_error_handler(struct sge
 	}
 	if (cause & F_PACKET_TOO_BIG) {
 		sge->stats.pkt_too_big++;
-		CH_ALERT("%s: SGE max packet size exceeded\n",
+		pr_alert("%s: SGE max packet size exceeded\n",
 			 adapter->name);
 	}
 	if (cause & F_PACKET_MISMATCH) {
 		sge->stats.pkt_mismatch++;
-		CH_ALERT("%s: SGE packet mismatch\n", adapter->name);
+		pr_alert("%s: SGE packet mismatch\n", adapter->name);
 	}
 	if (cause & SGE_INT_FATAL)
 		t1_fatal_err(adapter);
@@ -1101,7 +1102,7 @@ static void unexpected_offload(struct ad
 
 	pci_dma_sync_single_for_cpu(adapter->pdev, pci_unmap_addr(ce, dma_addr),
 			    pci_unmap_len(ce, dma_len), PCI_DMA_FROMDEVICE);
-	CH_ERR("%s: unexpected offload packet, cmd %u\n",
+	pr_err("%s: unexpected offload packet, cmd %u\n",
 	       adapter->name, *skb->data);
 	recycle_fl_buf(fl, fl->cidx);
 }
@@ -1687,7 +1688,7 @@ static int t1_sge_tx(struct sk_buff *skb
 			netif_stop_queue(dev);
 			set_bit(dev->if_port, &sge->stopped_tx_queues);
 			sge->stats.cmdQ_full[2]++;
-			CH_ERR("%s: Tx ring full while queue awake!\n",
+			pr_err("%s: Tx ring full while queue awake!\n",
 			       adapter->name);
 		}
 		spin_unlock(&q->lock);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/chelsio/subr.c linux-libre-2.6.34-gnu1/drivers/net/chelsio/subr.c
--- linux-libre-2.6.33-gnu1/drivers/net/chelsio/subr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/chelsio/subr.c	2010-05-16 17:17:36.000000000 -0400
@@ -90,7 +90,7 @@ int __t1_tpi_write(adapter_t *adapter, u
 	tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1,
 				   TPI_ATTEMPTS, 3);
 	if (tpi_busy)
-		CH_ALERT("%s: TPI write to 0x%x failed\n",
+		pr_alert("%s: TPI write to 0x%x failed\n",
 			 adapter->name, addr);
 	return tpi_busy;
 }
@@ -118,7 +118,7 @@ int __t1_tpi_read(adapter_t *adapter, u3
 	tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1,
 				   TPI_ATTEMPTS, 3);
 	if (tpi_busy)
-		CH_ALERT("%s: TPI read from 0x%x failed\n",
+		pr_alert("%s: TPI read from 0x%x failed\n",
 			 adapter->name, addr);
 	else
 		*valp = readl(adapter->regs + A_TPI_RD_DATA);
@@ -262,7 +262,7 @@ static int mi1_wait_until_ready(adapter_
 			udelay(10);
 	} while (busy && --attempts);
 	if (busy)
-		CH_ALERT("%s: MDIO operation timed out\n", adapter->name);
+		pr_alert("%s: MDIO operation timed out\n", adapter->name);
 	return busy;
 }
 
@@ -528,7 +528,7 @@ static const struct board_info t1_board[
 
 };
 
-struct pci_device_id t1_pci_tbl[] = {
+DEFINE_PCI_DEVICE_TABLE(t1_pci_tbl) = {
 	CH_DEVICE(8, 0, CH_BRD_T110_1CU),
 	CH_DEVICE(8, 1, CH_BRD_T110_1CU),
 	CH_DEVICE(7, 0, CH_BRD_N110_1F),
@@ -581,7 +581,7 @@ int t1_seeprom_read(adapter_t *adapter,
 	} while (!(val & F_VPD_OP_FLAG) && --i);
 
 	if (!(val & F_VPD_OP_FLAG)) {
-		CH_ERR("%s: reading EEPROM address 0x%x failed\n",
+		pr_err("%s: reading EEPROM address 0x%x failed\n",
 		       adapter->name, addr);
 		return -EIO;
 	}
@@ -734,8 +734,9 @@ int t1_elmer0_ext_intr_handler(adapter_t
 		break;
 	case CHBT_BOARD_8000:
 	case CHBT_BOARD_CHT110:
-		CH_DBG(adapter, INTR, "External interrupt cause 0x%x\n",
-		       cause);
+		if (netif_msg_intr(adapter))
+			dev_dbg(&adapter->pdev->dev,
+				"External interrupt cause 0x%x\n", cause);
 		if (cause & ELMER0_GP_BIT1) {        /* PMC3393 INTB */
 			struct cmac *mac = adapter->port[0].mac;
 
@@ -746,8 +747,9 @@ int t1_elmer0_ext_intr_handler(adapter_t
 
 			t1_tpi_read(adapter,
 					A_ELMER0_GPI_STAT, &mod_detect);
-			CH_MSG(adapter, INFO, LINK, "XPAK %s\n",
-			       mod_detect ? "removed" : "inserted");
+			if (netif_msg_link(adapter))
+				dev_info(&adapter->pdev->dev, "XPAK %s\n",
+					 mod_detect ? "removed" : "inserted");
 		}
 		break;
 #ifdef CONFIG_CHELSIO_T1_COUGAR
@@ -1084,7 +1086,7 @@ static void __devinit init_link_config(s
 
 #ifdef CONFIG_CHELSIO_T1_COUGAR
 	if (bi->clock_cspi && !(adapter->cspi = t1_cspi_create(adapter))) {
-		CH_ERR("%s: CSPI initialization failed\n",
+		pr_err("%s: CSPI initialization failed\n",
 		       adapter->name);
 		goto error;
 	}
@@ -1105,20 +1107,20 @@ int __devinit t1_init_sw_modules(adapter
 
 	adapter->sge = t1_sge_create(adapter, &adapter->params.sge);
 	if (!adapter->sge) {
-		CH_ERR("%s: SGE initialization failed\n",
+		pr_err("%s: SGE initialization failed\n",
 		       adapter->name);
 		goto error;
 	}
 
 	if (bi->espi_nports && !(adapter->espi = t1_espi_create(adapter))) {
-		CH_ERR("%s: ESPI initialization failed\n",
+		pr_err("%s: ESPI initialization failed\n",
 		       adapter->name);
 		goto error;
 	}
 
 	adapter->tp = t1_tp_create(adapter, &adapter->params.tp);
 	if (!adapter->tp) {
-		CH_ERR("%s: TP initialization failed\n",
+		pr_err("%s: TP initialization failed\n",
 		       adapter->name);
 		goto error;
 	}
@@ -1138,14 +1140,14 @@ int __devinit t1_init_sw_modules(adapter
 		adapter->port[i].phy = bi->gphy->create(adapter->port[i].dev,
 							phy_addr, bi->mdio_ops);
 		if (!adapter->port[i].phy) {
-			CH_ERR("%s: PHY %d initialization failed\n",
+			pr_err("%s: PHY %d initialization failed\n",
 			       adapter->name, i);
 			goto error;
 		}
 
 		adapter->port[i].mac = mac = bi->gmac->create(adapter, i);
 		if (!mac) {
-			CH_ERR("%s: MAC %d initialization failed\n",
+			pr_err("%s: MAC %d initialization failed\n",
 			       adapter->name, i);
 			goto error;
 		}
@@ -1157,7 +1159,7 @@ int __devinit t1_init_sw_modules(adapter
 		if (!t1_is_asic(adapter) || bi->chip_mac == CHBT_MAC_DUMMY)
 			mac->ops->macaddress_get(mac, hw_addr);
 		else if (vpd_macaddress_get(adapter, i, hw_addr)) {
-			CH_ERR("%s: could not read MAC address from VPD ROM\n",
+			pr_err("%s: could not read MAC address from VPD ROM\n",
 			       adapter->port[i].dev->name);
 			goto error;
 		}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/chelsio/vsc7326.c linux-libre-2.6.34-gnu1/drivers/net/chelsio/vsc7326.c
--- linux-libre-2.6.33-gnu1/drivers/net/chelsio/vsc7326.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/chelsio/vsc7326.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,14 +48,14 @@ static void vsc_read(adapter_t *adapter,
 		i++;
 	} while (((status & 1) == 0) && (i < 50));
 	if (i == 50)
-		CH_ERR("Invalid tpi read from MAC, breaking loop.\n");
+		pr_err("Invalid tpi read from MAC, breaking loop.\n");
 
 	t1_tpi_read(adapter, (REG_LOCAL_DATA << 2) + 4, &vlo);
 	t1_tpi_read(adapter, REG_LOCAL_DATA << 2, &vhi);
 
 	*val = (vhi << 16) | vlo;
 
-	/* CH_ERR("rd: block: 0x%x  sublock: 0x%x  reg: 0x%x  data: 0x%x\n",
+	/* pr_err("rd: block: 0x%x  sublock: 0x%x  reg: 0x%x  data: 0x%x\n",
 		((addr&0xe000)>>13), ((addr&0x1e00)>>9),
 		((addr&0x01fe)>>1), *val); */
 	spin_unlock_bh(&adapter->mac_lock);
@@ -66,7 +66,7 @@ static void vsc_write(adapter_t *adapter
 	spin_lock_bh(&adapter->mac_lock);
 	t1_tpi_write(adapter, (addr << 2) + 4, data & 0xFFFF);
 	t1_tpi_write(adapter, addr << 2, (data >> 16) & 0xFFFF);
-	/* CH_ERR("wr: block: 0x%x  sublock: 0x%x  reg: 0x%x  data: 0x%x\n",
+	/* pr_err("wr: block: 0x%x  sublock: 0x%x  reg: 0x%x  data: 0x%x\n",
 		((addr&0xe000)>>13), ((addr&0x1e00)>>9),
 		((addr&0x01fe)>>1), data); */
 	spin_unlock_bh(&adapter->mac_lock);
@@ -225,7 +225,7 @@ static void run_table(adapter_t *adapter
 	for (i = 0; i < len; i++) {
 		if (ib[i].addr == INITBLOCK_SLEEP) {
 			udelay( ib[i].data );
-			CH_ERR("sleep %d us\n",ib[i].data);
+			pr_err("sleep %d us\n",ib[i].data);
 		} else
 			vsc_write( adapter, ib[i].addr, ib[i].data );
 	}
@@ -241,7 +241,7 @@ static int bist_rd(adapter_t *adapter, i
 	    (address != 0x2) &&
 	    (address != 0xd) &&
 	    (address != 0xe))
-			CH_ERR("No bist address: 0x%x\n", address);
+			pr_err("No bist address: 0x%x\n", address);
 
 	data = ((0x00 << 24) | ((address & 0xff) << 16) | (0x00 << 8) |
 		((moduleid & 0xff) << 0));
@@ -251,9 +251,9 @@ static int bist_rd(adapter_t *adapter, i
 
 	vsc_read(adapter, REG_RAM_BIST_RESULT, &result);
 	if ((result & (1 << 9)) != 0x0)
-		CH_ERR("Still in bist read: 0x%x\n", result);
+		pr_err("Still in bist read: 0x%x\n", result);
 	else if ((result & (1 << 8)) != 0x0)
-		CH_ERR("bist read error: 0x%x\n", result);
+		pr_err("bist read error: 0x%x\n", result);
 
 	return (result & 0xff);
 }
@@ -268,10 +268,10 @@ static int bist_wr(adapter_t *adapter, i
 	    (address != 0x2) &&
 	    (address != 0xd) &&
 	    (address != 0xe))
-			CH_ERR("No bist address: 0x%x\n", address);
+			pr_err("No bist address: 0x%x\n", address);
 
 	if (value > 255)
-		CH_ERR("Suspicious write out of range value: 0x%x\n", value);
+		pr_err("Suspicious write out of range value: 0x%x\n", value);
 
 	data = ((0x01 << 24) | ((address & 0xff) << 16) | (value << 8) |
 		((moduleid & 0xff) << 0));
@@ -281,9 +281,9 @@ static int bist_wr(adapter_t *adapter, i
 
 	vsc_read(adapter, REG_RAM_BIST_CMD, &result);
 	if ((result & (1 << 27)) != 0x0)
-		CH_ERR("Still in bist write: 0x%x\n", result);
+		pr_err("Still in bist write: 0x%x\n", result);
 	else if ((result & (1 << 26)) != 0x0)
-		CH_ERR("bist write error: 0x%x\n", result);
+		pr_err("bist write error: 0x%x\n", result);
 
 	return 0;
 }
@@ -306,7 +306,7 @@ static int check_bist(adapter_t *adapter
 	column = ((bist_rd(adapter,moduleid, 0x0e)<<8) +
 			(bist_rd(adapter,moduleid, 0x0d)));
 	if ((result & 3) != 0x3)
-		CH_ERR("Result: 0x%x  BIST error in ram %d, column: 0x%04x\n",
+		pr_err("Result: 0x%x  BIST error in ram %d, column: 0x%04x\n",
 			result, moduleid, column);
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cnic.c linux-libre-2.6.34-gnu1/drivers/net/cnic.c
--- linux-libre-2.6.33-gnu1/drivers/net/cnic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cnic.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /* cnic.c: Broadcom CNIC core network driver.
  *
- * Copyright (c) 2006-2009 Broadcom Corporation
+ * Copyright (c) 2006-2010 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
@@ -10,6 +10,8 @@
  * Modified and maintained by: Michael Chan <mchan@broadcom.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 
 #include <linux/kernel.h>
@@ -47,7 +49,6 @@
 #include "cnic_defs.h"
 
 #define DRV_MODULE_NAME		"cnic"
-#define PFX DRV_MODULE_NAME	": "
 
 static char version[] __devinitdata =
 	"Broadcom NetXtreme II CNIC Driver " DRV_MODULE_NAME " v" CNIC_MODULE_VERSION " (" CNIC_MODULE_RELDATE ")\n";
@@ -326,6 +327,12 @@ static int cnic_iscsi_nl_msg_recv(struct
 		if (l5_cid >= MAX_CM_SK_TBL_SZ)
 			break;
 
+		rcu_read_lock();
+		if (!rcu_dereference(cp->ulp_ops[CNIC_ULP_L4])) {
+			rc = -ENODEV;
+			rcu_read_unlock();
+			break;
+		}
 		csk = &cp->csk_tbl[l5_cid];
 		csk_hold(csk);
 		if (cnic_in_use(csk)) {
@@ -340,6 +347,7 @@ static int cnic_iscsi_nl_msg_recv(struct
 				cnic_cm_set_pg(csk);
 		}
 		csk_put(csk);
+		rcu_read_unlock();
 		rc = 0;
 	}
 	}
@@ -409,14 +417,13 @@ int cnic_register_driver(int ulp_type, s
 	struct cnic_dev *dev;
 
 	if (ulp_type < 0 || ulp_type >= MAX_CNIC_ULP_TYPE) {
-		printk(KERN_ERR PFX "cnic_register_driver: Bad type %d\n",
-		       ulp_type);
+		pr_err("%s: Bad type %d\n", __func__, ulp_type);
 		return -EINVAL;
 	}
 	mutex_lock(&cnic_lock);
 	if (cnic_ulp_tbl[ulp_type]) {
-		printk(KERN_ERR PFX "cnic_register_driver: Type %d has already "
-				    "been registered\n", ulp_type);
+		pr_err("%s: Type %d has already been registered\n",
+		       __func__, ulp_type);
 		mutex_unlock(&cnic_lock);
 		return -EBUSY;
 	}
@@ -455,15 +462,14 @@ int cnic_unregister_driver(int ulp_type)
 	int i = 0;
 
 	if (ulp_type < 0 || ulp_type >= MAX_CNIC_ULP_TYPE) {
-		printk(KERN_ERR PFX "cnic_unregister_driver: Bad type %d\n",
-		       ulp_type);
+		pr_err("%s: Bad type %d\n", __func__, ulp_type);
 		return -EINVAL;
 	}
 	mutex_lock(&cnic_lock);
 	ulp_ops = cnic_ulp_tbl[ulp_type];
 	if (!ulp_ops) {
-		printk(KERN_ERR PFX "cnic_unregister_driver: Type %d has not "
-				    "been registered\n", ulp_type);
+		pr_err("%s: Type %d has not been registered\n",
+		       __func__, ulp_type);
 		goto out_unlock;
 	}
 	read_lock(&cnic_dev_lock);
@@ -471,8 +477,8 @@ int cnic_unregister_driver(int ulp_type)
 		struct cnic_local *cp = dev->cnic_priv;
 
 		if (rcu_dereference(cp->ulp_ops[ulp_type])) {
-			printk(KERN_ERR PFX "cnic_unregister_driver: Type %d "
-			       "still has devices registered\n", ulp_type);
+			pr_err("%s: Type %d still has devices registered\n",
+			       __func__, ulp_type);
 			read_unlock(&cnic_dev_lock);
 			goto out_unlock;
 		}
@@ -492,8 +498,7 @@ int cnic_unregister_driver(int ulp_type)
 	}
 
 	if (atomic_read(&ulp_ops->ref_count) != 0)
-		printk(KERN_WARNING PFX "%s: Failed waiting for ref count to go"
-					" to zero.\n", dev->netdev->name);
+		netdev_warn(dev->netdev, "Failed waiting for ref count to go to zero\n");
 	return 0;
 
 out_unlock:
@@ -511,20 +516,19 @@ static int cnic_register_device(struct c
 	struct cnic_ulp_ops *ulp_ops;
 
 	if (ulp_type < 0 || ulp_type >= MAX_CNIC_ULP_TYPE) {
-		printk(KERN_ERR PFX "cnic_register_device: Bad type %d\n",
-		       ulp_type);
+		pr_err("%s: Bad type %d\n", __func__, ulp_type);
 		return -EINVAL;
 	}
 	mutex_lock(&cnic_lock);
 	if (cnic_ulp_tbl[ulp_type] == NULL) {
-		printk(KERN_ERR PFX "cnic_register_device: Driver with type %d "
-				    "has not been registered\n", ulp_type);
+		pr_err("%s: Driver with type %d has not been registered\n",
+		       __func__, ulp_type);
 		mutex_unlock(&cnic_lock);
 		return -EAGAIN;
 	}
 	if (rcu_dereference(cp->ulp_ops[ulp_type])) {
-		printk(KERN_ERR PFX "cnic_register_device: Type %d has already "
-		       "been registered to this device\n", ulp_type);
+		pr_err("%s: Type %d has already been registered to this device\n",
+		       __func__, ulp_type);
 		mutex_unlock(&cnic_lock);
 		return -EBUSY;
 	}
@@ -552,8 +556,7 @@ static int cnic_unregister_device(struct
 	int i = 0;
 
 	if (ulp_type < 0 || ulp_type >= MAX_CNIC_ULP_TYPE) {
-		printk(KERN_ERR PFX "cnic_unregister_device: Bad type %d\n",
-		       ulp_type);
+		pr_err("%s: Bad type %d\n", __func__, ulp_type);
 		return -EINVAL;
 	}
 	mutex_lock(&cnic_lock);
@@ -561,8 +564,8 @@ static int cnic_unregister_device(struct
 		rcu_assign_pointer(cp->ulp_ops[ulp_type], NULL);
 		cnic_put(dev);
 	} else {
-		printk(KERN_ERR PFX "cnic_unregister_device: device not "
-		       "registered to this ulp type %d\n", ulp_type);
+		pr_err("%s: device not registered to this ulp type %d\n",
+		       __func__, ulp_type);
 		mutex_unlock(&cnic_lock);
 		return -EINVAL;
 	}
@@ -576,8 +579,7 @@ static int cnic_unregister_device(struct
 		i++;
 	}
 	if (test_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[ulp_type]))
-		printk(KERN_WARNING PFX "%s: Failed waiting for ULP up call"
-					" to complete.\n", dev->netdev->name);
+		netdev_warn(dev->netdev, "Failed waiting for ULP up call to complete\n");
 
 	return 0;
 }
@@ -898,7 +900,8 @@ static int cnic_alloc_uio(struct cnic_de
 	uinfo->mem[0].memtype = UIO_MEM_PHYS;
 
 	if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) {
-		uinfo->mem[1].addr = (unsigned long) cp->status_blk & PAGE_MASK;
+		uinfo->mem[1].addr = (unsigned long) cp->status_blk.gen &
+			PAGE_MASK;
 		if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX)
 			uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE * 9;
 		else
@@ -1101,10 +1104,9 @@ static int cnic_alloc_bnx2x_resc(struct
 	if (ret)
 		goto error;
 
-	cp->bnx2x_status_blk = cp->status_blk;
 	cp->bnx2x_def_status_blk = cp->ethdev->irq_arr[1].status_blk;
 
-	memset(cp->bnx2x_status_blk, 0, sizeof(struct host_status_block));
+	memset(cp->status_blk.bnx2x, 0, sizeof(*cp->status_blk.bnx2x));
 
 	cp->l2_rx_ring_size = 15;
 
@@ -1865,8 +1867,7 @@ static int cnic_bnx2x_connect(struct cni
 	}
 
 	if (sizeof(*conn_buf) > CNIC_KWQ16_DATA_SIZE) {
-		printk(KERN_ERR PFX "%s: conn_buf size too big\n",
-			       dev->netdev->name);
+		netdev_err(dev->netdev, "conn_buf size too big\n");
 		return -ENOMEM;
 	}
 	conn_buf = cnic_get_kwqe_16_data(cp, l5_cid, &l5_data);
@@ -2026,13 +2027,13 @@ static int cnic_submit_bnx2x_kwqes(struc
 			break;
 		default:
 			ret = 0;
-			printk(KERN_ERR PFX "%s: Unknown type of KWQE(0x%x)\n",
-			       dev->netdev->name, opcode);
+			netdev_err(dev->netdev, "Unknown type of KWQE(0x%x)\n",
+				   opcode);
 			break;
 		}
 		if (ret < 0)
-			printk(KERN_ERR PFX "%s: KWQE(0x%x) failed\n",
-			       dev->netdev->name, opcode);
+			netdev_err(dev->netdev, "KWQE(0x%x) failed\n",
+				   opcode);
 		i += work;
 	}
 	return 0;
@@ -2074,8 +2075,8 @@ static void service_kcqes(struct cnic_de
 		else if (kcqe_layer == KCQE_FLAGS_LAYER_MASK_L2)
 			goto end;
 		else {
-			printk(KERN_ERR PFX "%s: Unknown type of KCQE(0x%x)\n",
-			       dev->netdev->name, kcqe_op_flag);
+			netdev_err(dev->netdev, "Unknown type of KCQE(0x%x)\n",
+				   kcqe_op_flag);
 			goto end;
 		}
 
@@ -2204,7 +2205,7 @@ static void cnic_service_bnx2_msix(unsig
 {
 	struct cnic_dev *dev = (struct cnic_dev *) data;
 	struct cnic_local *cp = dev->cnic_priv;
-	struct status_block_msix *status_blk = cp->bnx2_status_blk;
+	struct status_block_msix *status_blk = cp->status_blk.bnx2;
 	u32 status_idx = status_blk->status_idx;
 	u16 hw_prod, sw_prod;
 	int kcqe_cnt;
@@ -2250,7 +2251,7 @@ static irqreturn_t cnic_irq(int irq, voi
 	if (cp->ack_int)
 		cp->ack_int(dev);
 
-	prefetch(cp->status_blk);
+	prefetch(cp->status_blk.gen);
 	prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
 
 	if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags)))
@@ -2291,7 +2292,7 @@ static void cnic_service_bnx2x_bh(unsign
 	struct cnic_local *cp = dev->cnic_priv;
 	u16 hw_prod, sw_prod;
 	struct cstorm_status_block_c *sblk =
-		&cp->bnx2x_status_blk->c_status_block;
+		&cp->status_blk.bnx2x->c_status_block;
 	u32 status_idx = sblk->status_block_index;
 	int kcqe_cnt;
 
@@ -2333,13 +2334,13 @@ static int cnic_service_bnx2x(void *data
 	struct cnic_local *cp = dev->cnic_priv;
 	u16 prod = cp->kcq_prod_idx & MAX_KCQ_IDX;
 
-	prefetch(cp->status_blk);
-	prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
+	if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags))) {
+		prefetch(cp->status_blk.bnx2x);
+		prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
 
-	if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags)))
 		tasklet_schedule(&cp->cnic_irq_task);
-
-	cnic_chk_pkt_rings(cp);
+		cnic_chk_pkt_rings(cp);
+	}
 
 	return 0;
 }
@@ -2513,7 +2514,7 @@ static int cnic_cm_offload_pg(struct cni
 	l4kwqe->sa5 = dev->mac_addr[5];
 
 	l4kwqe->etype = ETH_P_IP;
-	l4kwqe->ipid_count = DEF_IPID_COUNT;
+	l4kwqe->ipid_start = DEF_IPID_START;
 	l4kwqe->host_opaque = csk->l5_cid;
 
 	if (csk->vlan_id) {
@@ -2859,8 +2860,8 @@ static int cnic_get_route(struct cnic_so
 {
 	struct cnic_dev *dev = csk->dev;
 	struct cnic_local *cp = dev->cnic_priv;
-	int is_v6, err, rc = -ENETUNREACH;
-	struct dst_entry *dst;
+	int is_v6, rc = 0;
+	struct dst_entry *dst = NULL;
 	struct net_device *realdev;
 	u32 local_port;
 
@@ -2876,39 +2877,31 @@ static int cnic_get_route(struct cnic_so
 	clear_bit(SK_F_IPV6, &csk->flags);
 
 	if (is_v6) {
-#if defined(CONFIG_IPV6) || (defined(CONFIG_IPV6_MODULE) && defined(MODULE))
 		set_bit(SK_F_IPV6, &csk->flags);
-		err = cnic_get_v6_route(&saddr->remote.v6, &dst);
-		if (err)
-			return err;
-
-		if (!dst || dst->error || !dst->dev)
-			goto err_out;
+		cnic_get_v6_route(&saddr->remote.v6, &dst);
 
 		memcpy(&csk->dst_ip[0], &saddr->remote.v6.sin6_addr,
 		       sizeof(struct in6_addr));
 		csk->dst_port = saddr->remote.v6.sin6_port;
 		local_port = saddr->local.v6.sin6_port;
-#else
-		return rc;
-#endif
 
 	} else {
-		err = cnic_get_v4_route(&saddr->remote.v4, &dst);
-		if (err)
-			return err;
-
-		if (!dst || dst->error || !dst->dev)
-			goto err_out;
+		cnic_get_v4_route(&saddr->remote.v4, &dst);
 
 		csk->dst_ip[0] = saddr->remote.v4.sin_addr.s_addr;
 		csk->dst_port = saddr->remote.v4.sin_port;
 		local_port = saddr->local.v4.sin_port;
 	}
 
-	csk->vlan_id = cnic_get_vlan(dst->dev, &realdev);
-	if (realdev != dev->netdev)
-		goto err_out;
+	csk->vlan_id = 0;
+	csk->mtu = dev->netdev->mtu;
+	if (dst && dst->dev) {
+		u16 vlan = cnic_get_vlan(dst->dev, &realdev);
+		if (realdev == dev->netdev) {
+			csk->vlan_id = vlan;
+			csk->mtu = dst_mtu(dst);
+		}
+	}
 
 	if (local_port >= CNIC_LOCAL_PORT_MIN &&
 	    local_port < CNIC_LOCAL_PORT_MAX) {
@@ -2926,9 +2919,6 @@ static int cnic_get_route(struct cnic_so
 	}
 	csk->src_port = local_port;
 
-	csk->mtu = dst_mtu(dst);
-	rc = 0;
-
 err_out:
 	dst_release(dst);
 	return rc;
@@ -3052,6 +3042,14 @@ static void cnic_cm_process_offld_pg(str
 		clear_bit(SK_F_OFFLD_SCHED, &csk->flags);
 		goto done;
 	}
+	/* Possible PG kcqe status:  SUCCESS, OFFLOADED_PG, or CTX_ALLOC_FAIL */
+	if (kcqe->status == L4_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAIL) {
+		clear_bit(SK_F_OFFLD_SCHED, &csk->flags);
+		cnic_cm_upcall(cp, csk,
+			       L4_KCQE_OPCODE_VALUE_CONNECT_COMPLETE);
+		goto done;
+	}
+
 	csk->pg_cid = kcqe->pg_cid;
 	set_bit(SK_F_PG_OFFLD_COMPLETE, &csk->flags);
 	cnic_cm_conn_req(csk);
@@ -3089,6 +3087,13 @@ static void cnic_cm_process_kcqe(struct
 	}
 
 	switch (opcode) {
+	case L5CM_RAMROD_CMD_ID_TCP_CONNECT:
+		if (l4kcqe->status != 0) {
+			clear_bit(SK_F_OFFLD_SCHED, &csk->flags);
+			cnic_cm_upcall(cp, csk,
+				       L4_KCQE_OPCODE_VALUE_CONNECT_COMPLETE);
+		}
+		break;
 	case L4_KCQE_OPCODE_VALUE_CONNECT_COMPLETE:
 		if (l4kcqe->status == 0)
 			set_bit(SK_F_OFFLD_COMPLETE, &csk->flags);
@@ -3099,7 +3104,10 @@ static void cnic_cm_process_kcqe(struct
 		break;
 
 	case L4_KCQE_OPCODE_VALUE_RESET_RECEIVED:
-		if (test_and_clear_bit(SK_F_OFFLD_COMPLETE, &csk->flags))
+		if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) {
+			cnic_cm_upcall(cp, csk, opcode);
+			break;
+		} else if (test_and_clear_bit(SK_F_OFFLD_COMPLETE, &csk->flags))
 			csk->state = opcode;
 		/* fall through */
 	case L4_KCQE_OPCODE_VALUE_CLOSE_COMP:
@@ -3163,6 +3171,16 @@ static int cnic_ready_to_close(struct cn
 		if (!test_and_set_bit(SK_F_CLOSING, &csk->flags))
 			return 1;
 	}
+	/* 57710+ only  workaround to handle unsolicited RESET_COMP
+	 * which will be treated like a RESET RCVD notification
+	 * which triggers the clean up procedure
+	 */
+	else if (opcode == L4_KCQE_OPCODE_VALUE_RESET_COMP) {
+		if (!test_and_set_bit(SK_F_CLOSING, &csk->flags)) {
+			csk->state = L4_KCQE_OPCODE_VALUE_RESET_RECEIVED;
+			return 1;
+		}
+	}
 	return 0;
 }
 
@@ -3172,10 +3190,8 @@ static void cnic_close_bnx2_conn(struct
 	struct cnic_local *cp = dev->cnic_priv;
 
 	clear_bit(SK_F_CONNECT_START, &csk->flags);
-	if (cnic_ready_to_close(csk, opcode)) {
-		cnic_close_conn(csk);
-		cnic_cm_upcall(cp, csk, opcode);
-	}
+	cnic_close_conn(csk);
+	cnic_cm_upcall(cp, csk, opcode);
 }
 
 static void cnic_cm_stop_bnx2_hw(struct cnic_dev *dev)
@@ -3393,8 +3409,7 @@ static int cnic_init_bnx2_irq(struct cni
 		CNIC_WR(dev, base + BNX2_HC_COM_TICKS_OFF, (64 << 16) | 220);
 		CNIC_WR(dev, base + BNX2_HC_CMD_TICKS_OFF, (64 << 16) | 220);
 
-		cp->bnx2_status_blk = cp->status_blk;
-		cp->last_status_idx = cp->bnx2_status_blk->status_idx;
+		cp->last_status_idx = cp->status_blk.bnx2->status_idx;
 		tasklet_init(&cp->cnic_irq_task, cnic_service_bnx2_msix,
 			     (unsigned long) dev);
 		err = request_irq(ethdev->irq_arr[0].vector, cnic_irq, 0,
@@ -3403,7 +3418,7 @@ static int cnic_init_bnx2_irq(struct cni
 			tasklet_disable(&cp->cnic_irq_task);
 			return err;
 		}
-		while (cp->bnx2_status_blk->status_completion_producer_index &&
+		while (cp->status_blk.bnx2->status_completion_producer_index &&
 		       i < 10) {
 			CNIC_WR(dev, BNX2_HC_COALESCE_NOW,
 				1 << (11 + sblk_num));
@@ -3411,13 +3426,13 @@ static int cnic_init_bnx2_irq(struct cni
 			i++;
 			barrier();
 		}
-		if (cp->bnx2_status_blk->status_completion_producer_index) {
+		if (cp->status_blk.bnx2->status_completion_producer_index) {
 			cnic_free_irq(dev);
 			goto failed;
 		}
 
 	} else {
-		struct status_block *sblk = cp->status_blk;
+		struct status_block *sblk = cp->status_blk.gen;
 		u32 hc_cmd = CNIC_RD(dev, BNX2_HC_COMMAND);
 		int i = 0;
 
@@ -3435,8 +3450,7 @@ static int cnic_init_bnx2_irq(struct cni
 	return 0;
 
 failed:
-	printk(KERN_ERR PFX "%s: " "KCQ index not resetting to 0.\n",
-	       dev->netdev->name);
+	netdev_err(dev->netdev, "KCQ index not resetting to 0\n");
 	return -EBUSY;
 }
 
@@ -3475,7 +3489,7 @@ static void cnic_init_bnx2_tx_ring(struc
 	int i;
 	struct tx_bd *txbd;
 	dma_addr_t buf_map;
-	struct status_block *s_blk = cp->status_blk;
+	struct status_block *s_blk = cp->status_blk.gen;
 
 	sb_id = cp->status_blk_num;
 	tx_cid = 20;
@@ -3483,7 +3497,7 @@ static void cnic_init_bnx2_tx_ring(struc
 	cnic_init_context(dev, tx_cid + 1);
 	cp->tx_cons_ptr = &s_blk->status_tx_quick_consumer_index2;
 	if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) {
-		struct status_block_msix *sblk = cp->status_blk;
+		struct status_block_msix *sblk = cp->status_blk.bnx2;
 
 		tx_cid = TX_TSS_CID + sb_id - 1;
 		cnic_init_context(dev, tx_cid);
@@ -3539,7 +3553,7 @@ static void cnic_init_bnx2_rx_ring(struc
 	u32 cid_addr, sb_id, val, coal_reg, coal_val;
 	int i;
 	struct rx_bd *rxbd;
-	struct status_block *s_blk = cp->status_blk;
+	struct status_block *s_blk = cp->status_blk.gen;
 
 	sb_id = cp->status_blk_num;
 	cnic_init_context(dev, 2);
@@ -3547,7 +3561,7 @@ static void cnic_init_bnx2_rx_ring(struc
 	coal_reg = BNX2_HC_COMMAND;
 	coal_val = CNIC_RD(dev, coal_reg);
 	if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) {
-		struct status_block_msix *sblk = cp->status_blk;
+		struct status_block_msix *sblk = cp->status_blk.bnx2;
 
 		cp->rx_cons_ptr = &sblk->status_rx_quick_consumer_index;
 		coal_reg = BNX2_HC_COALESCE_NOW;
@@ -3646,7 +3660,7 @@ static int cnic_start_bnx2_hw(struct cni
 {
 	struct cnic_local *cp = dev->cnic_priv;
 	struct cnic_eth_dev *ethdev = cp->ethdev;
-	struct status_block *sblk = cp->status_blk;
+	struct status_block *sblk = cp->status_blk.gen;
 	u32 val;
 	int err;
 
@@ -3758,8 +3772,7 @@ static int cnic_start_bnx2_hw(struct cni
 
 	err = cnic_init_bnx2_irq(dev);
 	if (err) {
-		printk(KERN_ERR PFX "%s: cnic_init_irq failed\n",
-		       dev->netdev->name);
+		netdev_err(dev->netdev, "cnic_init_irq failed\n");
 		cnic_reg_wr_ind(dev, BNX2_CP_SCRATCH + 0x20, 0);
 		cnic_reg_wr_ind(dev, BNX2_COM_SCRATCH + 0x20, 0);
 		return err;
@@ -4122,8 +4135,7 @@ static int cnic_start_bnx2x_hw(struct cn
 			   offsetof(struct cstorm_status_block_c,
 				    index_values[HC_INDEX_C_ISCSI_EQ_CONS]));
 	if (eq_idx != 0) {
-		printk(KERN_ERR PFX "%s: EQ cons index %x != 0\n",
-		       dev->netdev->name, eq_idx);
+		netdev_err(dev->netdev, "EQ cons index %x != 0\n", eq_idx);
 		return -EBUSY;
 	}
 	ret = cnic_init_bnx2x_irq(dev);
@@ -4208,8 +4220,7 @@ static int cnic_register_netdev(struct c
 
 	err = ethdev->drv_register_cnic(dev->netdev, cp->cnic_ops, dev);
 	if (err)
-		printk(KERN_ERR PFX "%s: register_cnic failed\n",
-		       dev->netdev->name);
+		netdev_err(dev->netdev, "register_cnic failed\n");
 
 	return err;
 }
@@ -4238,13 +4249,12 @@ static int cnic_start_hw(struct cnic_dev
 	cp->chip_id = ethdev->chip_id;
 	pci_dev_get(dev->pcidev);
 	cp->func = PCI_FUNC(dev->pcidev->devfn);
-	cp->status_blk = ethdev->irq_arr[0].status_blk;
+	cp->status_blk.gen = ethdev->irq_arr[0].status_blk;
 	cp->status_blk_num = ethdev->irq_arr[0].status_blk_num;
 
 	err = cp->alloc_resc(dev);
 	if (err) {
-		printk(KERN_ERR PFX "%s: allocate resource failure\n",
-		       dev->netdev->name);
+		netdev_err(dev->netdev, "allocate resource failure\n");
 		goto err1;
 	}
 
@@ -4326,10 +4336,9 @@ static void cnic_free_dev(struct cnic_de
 		i++;
 	}
 	if (atomic_read(&dev->ref_count) != 0)
-		printk(KERN_ERR PFX "%s: Failed waiting for ref count to go"
-				    " to zero.\n", dev->netdev->name);
+		netdev_err(dev->netdev, "Failed waiting for ref count to go to zero\n");
 
-	printk(KERN_INFO PFX "Removed CNIC device: %s\n", dev->netdev->name);
+	netdev_info(dev->netdev, "Removed CNIC device\n");
 	dev_put(dev->netdev);
 	kfree(dev);
 }
@@ -4345,8 +4354,7 @@ static struct cnic_dev *cnic_alloc_dev(s
 
 	cdev = kzalloc(alloc_size , GFP_KERNEL);
 	if (cdev == NULL) {
-		printk(KERN_ERR PFX "%s: allocate dev struct failure\n",
-		       dev->name);
+		netdev_err(dev, "allocate dev struct failure\n");
 		return NULL;
 	}
 
@@ -4364,7 +4372,7 @@ static struct cnic_dev *cnic_alloc_dev(s
 
 	spin_lock_init(&cp->cnic_ulp_lock);
 
-	printk(KERN_INFO PFX "Added CNIC device: %s\n", dev->name);
+	netdev_info(dev, "Added CNIC device\n");
 
 	return cdev;
 }
@@ -4605,7 +4613,7 @@ static int __init cnic_init(void)
 {
 	int rc = 0;
 
-	printk(KERN_INFO "%s", version);
+	pr_info("%s", version);
 
 	rc = register_netdevice_notifier(&cnic_netdev_notifier);
 	if (rc) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cnic_defs.h linux-libre-2.6.34-gnu1/drivers/net/cnic_defs.h
--- linux-libre-2.6.33-gnu1/drivers/net/cnic_defs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cnic_defs.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 
 /* cnic.c: Broadcom CNIC core network driver.
  *
- * Copyright (c) 2006-2009 Broadcom Corporation
+ * Copyright (c) 2006-2010 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
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cnic.h linux-libre-2.6.34-gnu1/drivers/net/cnic.h
--- linux-libre-2.6.33-gnu1/drivers/net/cnic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cnic.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /* cnic.h: Broadcom CNIC core network driver.
  *
- * Copyright (c) 2006-2009 Broadcom Corporation
+ * Copyright (c) 2006-2010 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
@@ -101,7 +101,7 @@ struct cnic_redirect_entry {
 #define BNX2X_KWQ_DATA(cp, x)						\
 	&(cp)->kwq_16_data[BNX2X_KWQ_DATA_PG(cp, x)][BNX2X_KWQ_DATA_IDX(cp, x)]
 
-#define DEF_IPID_COUNT		0xc001
+#define DEF_IPID_START		0x8000
 
 #define DEF_KA_TIMEOUT		10000
 #define DEF_KA_INTERVAL		300000
@@ -224,9 +224,12 @@ struct cnic_local {
 	u16		kcq_prod_idx;
 	u32		kcq_io_addr;
 
-	void				*status_blk;
-	struct status_block_msix	*bnx2_status_blk;
-	struct host_status_block	*bnx2x_status_blk;
+	union {
+		void				*gen;
+		struct status_block_msix	*bnx2;
+		struct host_status_block	*bnx2x;
+	} status_blk;
+
 	struct host_def_status_block	*bnx2x_def_status_blk;
 
 	u32				status_blk_num;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cnic_if.h linux-libre-2.6.34-gnu1/drivers/net/cnic_if.h
--- linux-libre-2.6.33-gnu1/drivers/net/cnic_if.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cnic_if.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /* cnic_if.h: Broadcom CNIC core network driver.
  *
- * Copyright (c) 2006 Broadcom Corporation
+ * Copyright (c) 2006-2010 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
@@ -12,8 +12,8 @@
 #ifndef CNIC_IF_H
 #define CNIC_IF_H
 
-#define CNIC_MODULE_VERSION	"2.1.0"
-#define CNIC_MODULE_RELDATE	"Oct 10, 2009"
+#define CNIC_MODULE_VERSION	"2.1.1"
+#define CNIC_MODULE_RELDATE	"Feb 22, 2010"
 
 #define CNIC_ULP_RDMA		0
 #define CNIC_ULP_ISCSI		1
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cpmac.c linux-libre-2.6.34-gnu1/drivers/net/cpmac.c
--- linux-libre-2.6.33-gnu1/drivers/net/cpmac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cpmac.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/delay.h>
 
 #include <linux/netdevice.h>
+#include <linux/if_vlan.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/skbuff.h>
@@ -36,6 +37,7 @@
 #include <linux/phy_fixed.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/clk.h>
 #include <asm/gpio.h>
 #include <asm/atomic.h>
 
@@ -54,9 +56,9 @@ module_param(dumb_switch, int, 0444);
 MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable");
 MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
 
-#define CPMAC_VERSION "0.5.1"
-/* frame size + 802.1q tag */
-#define CPMAC_SKB_SIZE		(ETH_FRAME_LEN + 4)
+#define CPMAC_VERSION "0.5.2"
+/* frame size + 802.1q tag + FCS size */
+#define CPMAC_SKB_SIZE		(ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
 #define CPMAC_QUEUES	8
 
 /* Ethernet registers */
@@ -294,9 +296,16 @@ static int cpmac_mdio_write(struct mii_b
 
 static int cpmac_mdio_reset(struct mii_bus *bus)
 {
+	struct clk *cpmac_clk;
+
+	cpmac_clk = clk_get(&bus->dev, "cpmac");
+	if (IS_ERR(cpmac_clk)) {
+		printk(KERN_ERR "unable to get cpmac clock\n");
+		return -1;
+	}
 	ar7_device_reset(AR7_RESET_BIT_MDIO);
 	cpmac_write(bus->priv, CPMAC_MDIO_CONTROL, MDIOC_ENABLE |
-		    MDIOC_CLKDIV(ar7_cpmac_freq() / 2200000 - 1));
+		    MDIOC_CLKDIV(clk_get_rate(cpmac_clk) / 2200000 - 1));
 	return 0;
 }
 
@@ -320,7 +329,6 @@ static int cpmac_config(struct net_devic
 static void cpmac_set_multicast_list(struct net_device *dev)
 {
 	struct dev_mc_list *iter;
-	int i;
 	u8 tmp;
 	u32 mbp, bit, hash[2] = { 0, };
 	struct cpmac_priv *priv = netdev_priv(dev);
@@ -340,8 +348,7 @@ static void cpmac_set_multicast_list(str
 			 * cpmac uses some strange mac address hashing
 			 * (not crc32)
 			 */
-			for (i = 0, iter = dev->mc_list; i < dev->mc_count;
-			     i++, iter = iter->next) {
+			netdev_for_each_mc_addr(iter, dev) {
 				bit = 0;
 				tmp = iter->dmi_addr[0];
 				bit  ^= (tmp >> 2) ^ (tmp << 4);
@@ -1130,8 +1137,9 @@ static int __devinit cpmac_probe(struct
 	}
 
 	if (phy_id == PHY_MAX_ADDR) {
-		dev_err(&pdev->dev, "no PHY present\n");
-		return -ENODEV;
+		dev_err(&pdev->dev, "no PHY present, falling back to switch on MDIO bus 0\n");
+		strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */
+		phy_id = pdev->id;
 	}
 
 	dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES);
@@ -1284,8 +1292,8 @@ void __devexit cpmac_exit(void)
 {
 	platform_driver_unregister(&cpmac_driver);
 	mdiobus_unregister(cpmac_mii);
-	mdiobus_free(cpmac_mii);
 	iounmap(cpmac_mii->priv);
+	mdiobus_free(cpmac_mii);
 }
 
 module_init(cpmac_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cris/eth_v10.c linux-libre-2.6.34-gnu1/drivers/net/cris/eth_v10.c
--- linux-libre-2.6.33-gnu1/drivers/net/cris/eth_v10.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cris/eth_v10.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/spinlock.h>
 #include <linux/errno.h>
@@ -1564,7 +1563,7 @@ static void
 set_multicast_list(struct net_device *dev)
 {
 	struct net_local *lp = netdev_priv(dev);
-	int num_addr = dev->mc_count;
+	int num_addr = netdev_mc_count(dev);
 	unsigned long int lo_bits;
 	unsigned long int hi_bits;
 
@@ -1596,13 +1595,12 @@ set_multicast_list(struct net_device *de
 	} else {
 		/* MC mode, receive normal and MC packets */
 		char hash_ix;
-		struct dev_mc_list *dmi = dev->mc_list;
-		int i;
+		struct dev_mc_list *dmi;
 		char *baddr;
 
 		lo_bits = 0x00000000ul;
 		hi_bits = 0x00000000ul;
-		for (i = 0; i < num_addr; i++) {
+		netdev_for_each_mc_addr(dmi, dev) {
 			/* Calculate the hash index for the GA registers */
 
 			hash_ix = 0;
@@ -1632,7 +1630,6 @@ set_multicast_list(struct net_device *de
 			} else {
 				lo_bits |= (1 << hash_ix);
 			}
-			dmi = dmi->next;
 		}
 		/* Disable individual receive */
 		SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, individual, discard);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cs89x0.c linux-libre-2.6.34-gnu1/drivers/net/cs89x0.c
--- linux-libre-2.6.33-gnu1/drivers/net/cs89x0.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cs89x0.c	2010-05-16 17:17:36.000000000 -0400
@@ -138,12 +138,12 @@
 #include <linux/ioport.h>
 #include <linux/in.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -580,7 +580,7 @@ cs89x0_probe1(struct net_device *dev, in
 	}
 
 #ifdef CONFIG_SH_HICOSH4
-	/* truely reset the chip */
+	/* truly reset the chip */
 	writeword(ioaddr, ADD_PORT, 0x0114);
 	writeword(ioaddr, DATA_PORT, 0x0040);
 #endif
@@ -1785,7 +1785,7 @@ static void set_multicast_list(struct ne
 	{
 		lp->rx_mode = RX_ALL_ACCEPT;
 	}
-	else if((dev->flags&IFF_ALLMULTI)||dev->mc_list)
+	else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev))
 	{
 		/* The multicast-accept list is initialized to accept-all, and we
 		   rely on higher-level filtering for now. */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb3/adapter.h linux-libre-2.6.34-gnu1/drivers/net/cxgb3/adapter.h
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb3/adapter.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb3/adapter.h	2010-05-16 17:17:36.000000000 -0400
@@ -264,6 +264,10 @@ struct adapter {
 	struct work_struct fatal_error_handler_task;
 	struct work_struct link_fault_handler_task;
 
+	struct work_struct db_full_task;
+	struct work_struct db_empty_task;
+	struct work_struct db_drop_task;
+
 	struct dentry *debugfs_root;
 
 	struct mutex mdio_lock;
@@ -335,6 +339,7 @@ int t3_sge_alloc_qset(struct adapter *ad
 int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx,
 		unsigned char *data);
 irqreturn_t t3_sge_intr_msix(int irq, void *cookie);
+extern struct workqueue_struct *cxgb3_wq;
 
 int t3_get_edc_fw(struct cphy *phy, int edc_idx, int size);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb3/ael1002.c linux-libre-2.6.34-gnu1/drivers/net/cxgb3/ael1002.c
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb3/ael1002.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb3/ael1002.c	2010-05-16 17:17:36.000000000 -0400
@@ -934,7 +934,7 @@ static struct cphy_ops xaui_direct_ops =
 int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
 			    int phy_addr, const struct mdio_ops *mdio_ops)
 {
-	cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops,
+	cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops,
 		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
 		  "10GBASE-CX4");
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb3/common.h linux-libre-2.6.34-gnu1/drivers/net/cxgb3/common.h
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb3/common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb3/common.h	2010-05-16 17:17:36.000000000 -0400
@@ -67,32 +67,6 @@
 /* Additional NETIF_MSG_* categories */
 #define NETIF_MSG_MMIO 0x8000000
 
-struct t3_rx_mode {
-	struct net_device *dev;
-	struct dev_mc_list *mclist;
-	unsigned int idx;
-};
-
-static inline void init_rx_mode(struct t3_rx_mode *p, struct net_device *dev,
-				struct dev_mc_list *mclist)
-{
-	p->dev = dev;
-	p->mclist = mclist;
-	p->idx = 0;
-}
-
-static inline u8 *t3_get_next_mcaddr(struct t3_rx_mode *rm)
-{
-	u8 *addr = NULL;
-
-	if (rm->mclist && rm->idx < rm->dev->mc_count) {
-		addr = rm->mclist->dmi_addr;
-		rm->mclist = rm->mclist->next;
-		rm->idx++;
-	}
-	return addr;
-}
-
 enum {
 	MAX_NPORTS = 2,		/* max # of ports */
 	MAX_FRAME_SIZE = 10240,	/* max MAC frame size, including header + FCS */
@@ -746,7 +720,7 @@ void t3_mac_enable_exact_filters(struct
 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);
-int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm);
+int t3_mac_set_rx_mode(struct cmac *mac, struct net_device *dev);
 int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6]);
 int t3_mac_set_num_ucast(struct cmac *mac, int n);
 const struct mac_stats *t3_mac_update_stats(struct cmac *mac);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb3/cxgb3_main.c linux-libre-2.6.34-gnu1/drivers/net/cxgb3/cxgb3_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb3/cxgb3_main.c	2013-05-03 12:08:06.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb3/cxgb3_main.c	2013-05-03 09:47:29.000000000 -0400
@@ -45,6 +45,8 @@
 #include <linux/firmware.h>
 #include <linux/log2.h>
 #include <linux/stringify.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 #include "common.h"
@@ -80,7 +82,7 @@ enum {
 #define CH_DEVICE(devid, idx) \
 	{ PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, PCI_ANY_ID, 0, 0, idx }
 
-static const struct pci_device_id cxgb3_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(cxgb3_pci_tbl) = {
 	CH_DEVICE(0x20, 0),	/* PE9000 */
 	CH_DEVICE(0x21, 1),	/* T302E */
 	CH_DEVICE(0x22, 2),	/* T310E */
@@ -140,7 +142,7 @@ MODULE_PARM_DESC(ofld_disable, "whether
  * will block keventd as it needs the rtnl lock, and we'll deadlock waiting
  * for our work to complete.  Get our own work queue to solve this.
  */
-static struct workqueue_struct *cxgb3_wq;
+struct workqueue_struct *cxgb3_wq;
 
 /**
  *	link_report - show link status and link speed/duplex
@@ -324,11 +326,9 @@ void t3_os_phymod_changed(struct adapter
 
 static void cxgb_set_rxmode(struct net_device *dev)
 {
-	struct t3_rx_mode rm;
 	struct port_info *pi = netdev_priv(dev);
 
-	init_rx_mode(&rm, dev, dev->mc_list);
-	t3_mac_set_rx_mode(&pi->mac, &rm);
+	t3_mac_set_rx_mode(&pi->mac, dev);
 }
 
 /**
@@ -339,17 +339,15 @@ static void cxgb_set_rxmode(struct net_d
  */
 static void link_start(struct net_device *dev)
 {
-	struct t3_rx_mode rm;
 	struct port_info *pi = netdev_priv(dev);
 	struct cmac *mac = &pi->mac;
 
-	init_rx_mode(&rm, dev, dev->mc_list);
 	t3_mac_reset(mac);
 	t3_mac_set_num_ucast(mac, MAX_MAC_IDX);
 	t3_mac_set_mtu(mac, dev->mtu);
 	t3_mac_set_address(mac, LAN_MAC_IDX, dev->dev_addr);
 	t3_mac_set_address(mac, SAN_MAC_IDX, pi->iscsic.mac_addr);
-	t3_mac_set_rx_mode(mac, &rm);
+	t3_mac_set_rx_mode(mac, dev);
 	t3_link_start(&pi->phy, mac, &pi->link_config);
 	t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
 }
@@ -441,7 +439,7 @@ static void free_irq_resources(struct ad
 static int await_mgmt_replies(struct adapter *adap, unsigned long init_cnt,
 			      unsigned long n)
 {
-	int attempts = 5;
+	int attempts = 10;
 
 	while (adap->sge.qs[0].rspq.offload_pkts < init_cnt + n) {
 		if (!--attempts)
@@ -590,6 +588,19 @@ static void setup_rss(struct adapter *ad
 		      V_RRCPLCPUSIZE(6) | F_HASHTOEPLITZ, cpus, rspq_map);
 }
 
+static void ring_dbs(struct adapter *adap)
+{
+	int i, j;
+
+	for (i = 0; i < SGE_QSETS; i++) {
+		struct sge_qset *qs = &adap->sge.qs[i];
+
+		if (qs->adap)
+			for (j = 0; j < SGE_TXQ_PER_SET; j++)
+				t3_write_reg(adap, A_SG_KDOORBELL, F_SELEGRCNTX | V_EGRCNTX(qs->txq[j].cntxt_id));
+	}
+}
+
 static void init_napi(struct adapter *adap)
 {
 	int i;
@@ -1277,6 +1288,7 @@ static void cxgb_down(struct adapter *ad
 
 	free_irq_resources(adapter);
 	quiesce_rx(adapter);
+	t3_sge_stop(adapter);
 	flush_workqueue(cxgb3_wq);	/* wait for external IRQ handler */
 }
 
@@ -2747,6 +2759,42 @@ static void t3_adap_check_task(struct wo
 	spin_unlock_irq(&adapter->work_lock);
 }
 
+static void db_full_task(struct work_struct *work)
+{
+	struct adapter *adapter = container_of(work, struct adapter,
+					       db_full_task);
+
+	cxgb3_event_notify(&adapter->tdev, OFFLOAD_DB_FULL, 0);
+}
+
+static void db_empty_task(struct work_struct *work)
+{
+	struct adapter *adapter = container_of(work, struct adapter,
+					       db_empty_task);
+
+	cxgb3_event_notify(&adapter->tdev, OFFLOAD_DB_EMPTY, 0);
+}
+
+static void db_drop_task(struct work_struct *work)
+{
+	struct adapter *adapter = container_of(work, struct adapter,
+					       db_drop_task);
+	unsigned long delay = 1000;
+	unsigned short r;
+
+	cxgb3_event_notify(&adapter->tdev, OFFLOAD_DB_DROP, 0);
+
+	/*
+	 * Sleep a while before ringing the driver qset dbs.
+	 * The delay is between 1000-2023 usecs.
+	 */
+	get_random_bytes(&r, 2);
+	delay += r & 1023;
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(usecs_to_jiffies(delay));
+	ring_dbs(adapter);
+}
+
 /*
  * Processes external (PHY) interrupts in process context.
  */
@@ -3215,6 +3263,11 @@ static int __devinit init_one(struct pci
 	INIT_LIST_HEAD(&adapter->adapter_list);
 	INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task);
 	INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task);
+
+	INIT_WORK(&adapter->db_full_task, db_full_task);
+	INIT_WORK(&adapter->db_empty_task, db_empty_task);
+	INIT_WORK(&adapter->db_drop_task, db_drop_task);
+
 	INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task);
 
 	for (i = 0; i < ai->nports0 + ai->nports1; ++i) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb3/cxgb3_offload.c linux-libre-2.6.34-gnu1/drivers/net/cxgb3/cxgb3_offload.c
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb3/cxgb3_offload.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb3/cxgb3_offload.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
  */
 
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <net/neighbour.h>
 #include <linux/notifier.h>
 #include <asm/atomic.h>
@@ -1252,7 +1253,7 @@ int cxgb3_offload_activate(struct adapte
 	struct mtutab mtutab;
 	unsigned int l2t_capacity;
 
-	t = kcalloc(1, sizeof(*t), GFP_KERNEL);
+	t = kzalloc(sizeof(*t), GFP_KERNEL);
 	if (!t)
 		return -ENOMEM;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb3/cxgb3_offload.h linux-libre-2.6.34-gnu1/drivers/net/cxgb3/cxgb3_offload.h
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb3/cxgb3_offload.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb3/cxgb3_offload.h	2010-05-16 17:17:36.000000000 -0400
@@ -73,7 +73,10 @@ enum {
 	OFFLOAD_STATUS_UP,
 	OFFLOAD_STATUS_DOWN,
 	OFFLOAD_PORT_DOWN,
-	OFFLOAD_PORT_UP
+	OFFLOAD_PORT_UP,
+	OFFLOAD_DB_FULL,
+	OFFLOAD_DB_EMPTY,
+	OFFLOAD_DB_DROP
 };
 
 struct cxgb3_client {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb3/l2t.c linux-libre-2.6.34-gnu1/drivers/net/cxgb3/l2t.c
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb3/l2t.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb3/l2t.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <linux/jhash.h>
+#include <linux/slab.h>
 #include <net/neighbour.h>
 #include "common.h"
 #include "t3cdev.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb3/regs.h linux-libre-2.6.34-gnu1/drivers/net/cxgb3/regs.h
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb3/regs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb3/regs.h	2010-05-16 17:17:36.000000000 -0400
@@ -254,6 +254,22 @@
 #define V_LOPIODRBDROPERR(x) ((x) << S_LOPIODRBDROPERR)
 #define F_LOPIODRBDROPERR    V_LOPIODRBDROPERR(1U)
 
+#define S_HIPRIORITYDBFULL    7
+#define V_HIPRIORITYDBFULL(x) ((x) << S_HIPRIORITYDBFULL)
+#define F_HIPRIORITYDBFULL    V_HIPRIORITYDBFULL(1U)
+
+#define S_HIPRIORITYDBEMPTY   6
+#define V_HIPRIORITYDBEMPTY(x) ((x) << S_HIPRIORITYDBEMPTY)
+#define F_HIPRIORITYDBEMPTY    V_HIPRIORITYDBEMPTY(1U)
+
+#define S_LOPRIORITYDBFULL    5
+#define V_LOPRIORITYDBFULL(x) ((x) << S_LOPRIORITYDBFULL)
+#define F_LOPRIORITYDBFULL    V_LOPRIORITYDBFULL(1U)
+
+#define S_LOPRIORITYDBEMPTY   4
+#define V_LOPRIORITYDBEMPTY(x) ((x) << S_LOPRIORITYDBEMPTY)
+#define F_LOPRIORITYDBEMPTY    V_LOPRIORITYDBEMPTY(1U)
+
 #define S_RSPQDISABLED    3
 #define V_RSPQDISABLED(x) ((x) << S_RSPQDISABLED)
 #define F_RSPQDISABLED    V_RSPQDISABLED(1U)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb3/sge.c linux-libre-2.6.34-gnu1/drivers/net/cxgb3/sge.c
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb3/sge.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb3/sge.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,12 +36,14 @@
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 #include "common.h"
 #include "regs.h"
 #include "sge_defs.h"
 #include "t3_cpl.h"
 #include "firmware_exports.h"
+#include "cxgb3_offload.h"
 
 #define USE_GTS 0
 
@@ -196,13 +198,13 @@ static inline void refill_rspq(struct ad
 /**
  *	need_skb_unmap - does the platform need unmapping of sk_buffs?
  *
- *	Returns true if the platfrom needs sk_buff unmapping.  The compiler
+ *	Returns true if the platform needs sk_buff unmapping.  The compiler
  *	optimizes away unecessary code if this returns true.
  */
 static inline int need_skb_unmap(void)
 {
 	/*
-	 * This structure is used to tell if the platfrom needs buffer
+	 * This structure is used to tell if the platform needs buffer
 	 * unmapping by checking if DECLARE_PCI_UNMAP_ADDR defines anything.
 	 */
 	struct dummy {
@@ -480,6 +482,7 @@ static inline void ring_fl_db(struct ada
 {
 	if (q->pend_cred >= q->credits / 4) {
 		q->pend_cred = 0;
+		wmb();
 		t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
 	}
 }
@@ -2286,11 +2289,14 @@ static int process_responses(struct adap
 	while (likely(budget_left && is_new_response(r, q))) {
 		int packet_complete, eth, ethpad = 2, lro = qs->lro_enabled;
 		struct sk_buff *skb = NULL;
-		u32 len, flags = ntohl(r->flags);
-		__be32 rss_hi = *(const __be32 *)r,
-		       rss_lo = r->rss_hdr.rss_hash_val;
+		u32 len, flags;
+		__be32 rss_hi, rss_lo;
 
+		rmb();
 		eth = r->rss_hdr.opcode == CPL_RX_PKT;
+		rss_hi = *(const __be32 *)r;
+		rss_lo = r->rss_hdr.rss_hash_val;
+		flags = ntohl(r->flags);
 
 		if (unlikely(flags & F_RSPD_ASYNC_NOTIF)) {
 			skb = alloc_skb(AN_PKT_SIZE, GFP_ATOMIC);
@@ -2501,7 +2507,10 @@ static int process_pure_responses(struct
 			refill_rspq(adap, q, q->credits);
 			q->credits = 0;
 		}
-	} while (is_new_response(r, q) && is_pure_response(r));
+		if (!is_new_response(r, q))
+			break;
+		rmb();
+	} while (is_pure_response(r));
 
 	if (sleeping)
 		check_ring_db(adap, qs, sleeping);
@@ -2535,6 +2544,7 @@ static inline int handle_responses(struc
 
 	if (!is_new_response(r, q))
 		return -1;
+	rmb();
 	if (is_pure_response(r) && process_pure_responses(adap, qs, r) == 0) {
 		t3_write_reg(adap, A_SG_GTS, V_RSPQ(q->cntxt_id) |
 			     V_NEWTIMER(q->holdoff_tmr) | V_NEWINDEX(q->cidx));
@@ -2833,8 +2843,13 @@ void t3_sge_err_intr_handler(struct adap
 	}
 
 	if (status & (F_HIPIODRBDROPERR | F_LOPIODRBDROPERR))
-		CH_ALERT(adapter, "SGE dropped %s priority doorbell\n",
-			 status & F_HIPIODRBDROPERR ? "high" : "lo");
+		queue_work(cxgb3_wq, &adapter->db_drop_task);
+
+	if (status & (F_HIPRIORITYDBFULL | F_LOPRIORITYDBFULL))
+		queue_work(cxgb3_wq, &adapter->db_full_task);
+
+	if (status & (F_HIPRIORITYDBEMPTY | F_LOPRIORITYDBEMPTY))
+		queue_work(cxgb3_wq, &adapter->db_empty_task);
 
 	t3_write_reg(adapter, A_SG_INT_CAUSE, status);
 	if (status &  SGE_FATALERR)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb3/t3_hw.c linux-libre-2.6.34-gnu1/drivers/net/cxgb3/t3_hw.c
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb3/t3_hw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb3/t3_hw.c	2010-05-16 17:17:36.000000000 -0400
@@ -1262,7 +1262,8 @@ void t3_link_changed(struct adapter *ada
 		lc->fc = fc;
 	}
 
-	t3_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc);
+	t3_os_link_changed(adapter, port_id, link_ok && !pi->link_fault,
+			   speed, duplex, fc);
 }
 
 void t3_link_fault(struct adapter *adapter, int port_id)
@@ -1432,7 +1433,10 @@ static int t3_handle_intr_status(struct
 		       F_IRPARITYERROR | V_ITPARITYERROR(M_ITPARITYERROR) | \
 		       V_FLPARITYERROR(M_FLPARITYERROR) | F_LODRBPARITYERROR | \
 		       F_HIDRBPARITYERROR | F_LORCQPARITYERROR | \
-		       F_HIRCQPARITYERROR)
+		       F_HIRCQPARITYERROR | F_LOPRIORITYDBFULL | \
+		       F_HIPRIORITYDBFULL | F_LOPRIORITYDBEMPTY | \
+		       F_HIPRIORITYDBEMPTY | F_HIPIODRBDROPERR | \
+		       F_LOPIODRBDROPERR)
 #define MC5_INTR_MASK (F_PARITYERR | F_ACTRGNFULL | F_UNKNOWNCMD | \
 		       F_REQQPARERR | F_DISPQPARERR | F_DELACTEMPTY | \
 		       F_NFASRCHFAIL)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb3/xgmac.c linux-libre-2.6.34-gnu1/drivers/net/cxgb3/xgmac.c
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb3/xgmac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb3/xgmac.c	2010-05-16 17:17:36.000000000 -0400
@@ -297,29 +297,30 @@ static int hash_hw_addr(const u8 * addr)
 	return hash;
 }
 
-int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm)
+int t3_mac_set_rx_mode(struct cmac *mac, struct net_device *dev)
 {
 	u32 val, hash_lo, hash_hi;
 	struct adapter *adap = mac->adapter;
 	unsigned int oft = mac->offset;
 
 	val = t3_read_reg(adap, A_XGM_RX_CFG + oft) & ~F_COPYALLFRAMES;
-	if (rm->dev->flags & IFF_PROMISC)
+	if (dev->flags & IFF_PROMISC)
 		val |= F_COPYALLFRAMES;
 	t3_write_reg(adap, A_XGM_RX_CFG + oft, val);
 
-	if (rm->dev->flags & IFF_ALLMULTI)
+	if (dev->flags & IFF_ALLMULTI)
 		hash_lo = hash_hi = 0xffffffff;
 	else {
-		u8 *addr;
+		struct dev_mc_list *dmi;
 		int exact_addr_idx = mac->nucast;
 
 		hash_lo = hash_hi = 0;
-		while ((addr = t3_get_next_mcaddr(rm)))
+		netdev_for_each_mc_addr(dmi, dev)
 			if (exact_addr_idx < EXACT_ADDR_FILTERS)
-				set_addr_filter(mac, exact_addr_idx++, addr);
+				set_addr_filter(mac, exact_addr_idx++,
+						dmi->dmi_addr);
 			else {
-				int hash = hash_hw_addr(addr);
+				int hash = hash_hw_addr(dmi->dmi_addr);
 
 				if (hash < 32)
 					hash_lo |= (1 << hash);
@@ -353,6 +354,9 @@ int t3_mac_set_mtu(struct cmac *mac, uns
 	 * packet size register includes header, but not FCS.
 	 */
 	mtu += 14;
+	if (mtu > 1536)
+		mtu += 4;
+
 	if (mtu > MAX_FRAME_SIZE - 4)
 		return -EINVAL;
 	t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb4/cxgb4.h linux-libre-2.6.34-gnu1/drivers/net/cxgb4/cxgb4.h
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb4/cxgb4.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb4/cxgb4.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,741 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __CXGB4_H__
+#define __CXGB4_H__
+
+#include <linux/bitops.h>
+#include <linux/cache.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include "cxgb4_uld.h"
+#include "t4_hw.h"
+
+#define FW_VERSION_MAJOR 1
+#define FW_VERSION_MINOR 1
+#define FW_VERSION_MICRO 0
+
+enum {
+	MAX_NPORTS = 4,     /* max # of ports */
+	SERNUM_LEN = 16,    /* Serial # length */
+	EC_LEN     = 16,    /* E/C length */
+	ID_LEN     = 16,    /* ID length */
+};
+
+enum {
+	MEM_EDC0,
+	MEM_EDC1,
+	MEM_MC
+};
+
+enum dev_master {
+	MASTER_CANT,
+	MASTER_MAY,
+	MASTER_MUST
+};
+
+enum dev_state {
+	DEV_STATE_UNINIT,
+	DEV_STATE_INIT,
+	DEV_STATE_ERR
+};
+
+enum {
+	PAUSE_RX      = 1 << 0,
+	PAUSE_TX      = 1 << 1,
+	PAUSE_AUTONEG = 1 << 2
+};
+
+struct port_stats {
+	u64 tx_octets;            /* total # of octets in good frames */
+	u64 tx_frames;            /* all good frames */
+	u64 tx_bcast_frames;      /* all broadcast frames */
+	u64 tx_mcast_frames;      /* all multicast frames */
+	u64 tx_ucast_frames;      /* all unicast frames */
+	u64 tx_error_frames;      /* all error frames */
+
+	u64 tx_frames_64;         /* # of Tx frames in a particular range */
+	u64 tx_frames_65_127;
+	u64 tx_frames_128_255;
+	u64 tx_frames_256_511;
+	u64 tx_frames_512_1023;
+	u64 tx_frames_1024_1518;
+	u64 tx_frames_1519_max;
+
+	u64 tx_drop;              /* # of dropped Tx frames */
+	u64 tx_pause;             /* # of transmitted pause frames */
+	u64 tx_ppp0;              /* # of transmitted PPP prio 0 frames */
+	u64 tx_ppp1;              /* # of transmitted PPP prio 1 frames */
+	u64 tx_ppp2;              /* # of transmitted PPP prio 2 frames */
+	u64 tx_ppp3;              /* # of transmitted PPP prio 3 frames */
+	u64 tx_ppp4;              /* # of transmitted PPP prio 4 frames */
+	u64 tx_ppp5;              /* # of transmitted PPP prio 5 frames */
+	u64 tx_ppp6;              /* # of transmitted PPP prio 6 frames */
+	u64 tx_ppp7;              /* # of transmitted PPP prio 7 frames */
+
+	u64 rx_octets;            /* total # of octets in good frames */
+	u64 rx_frames;            /* all good frames */
+	u64 rx_bcast_frames;      /* all broadcast frames */
+	u64 rx_mcast_frames;      /* all multicast frames */
+	u64 rx_ucast_frames;      /* all unicast frames */
+	u64 rx_too_long;          /* # of frames exceeding MTU */
+	u64 rx_jabber;            /* # of jabber frames */
+	u64 rx_fcs_err;           /* # of received frames with bad FCS */
+	u64 rx_len_err;           /* # of received frames with length error */
+	u64 rx_symbol_err;        /* symbol errors */
+	u64 rx_runt;              /* # of short frames */
+
+	u64 rx_frames_64;         /* # of Rx frames in a particular range */
+	u64 rx_frames_65_127;
+	u64 rx_frames_128_255;
+	u64 rx_frames_256_511;
+	u64 rx_frames_512_1023;
+	u64 rx_frames_1024_1518;
+	u64 rx_frames_1519_max;
+
+	u64 rx_pause;             /* # of received pause frames */
+	u64 rx_ppp0;              /* # of received PPP prio 0 frames */
+	u64 rx_ppp1;              /* # of received PPP prio 1 frames */
+	u64 rx_ppp2;              /* # of received PPP prio 2 frames */
+	u64 rx_ppp3;              /* # of received PPP prio 3 frames */
+	u64 rx_ppp4;              /* # of received PPP prio 4 frames */
+	u64 rx_ppp5;              /* # of received PPP prio 5 frames */
+	u64 rx_ppp6;              /* # of received PPP prio 6 frames */
+	u64 rx_ppp7;              /* # of received PPP prio 7 frames */
+
+	u64 rx_ovflow0;           /* drops due to buffer-group 0 overflows */
+	u64 rx_ovflow1;           /* drops due to buffer-group 1 overflows */
+	u64 rx_ovflow2;           /* drops due to buffer-group 2 overflows */
+	u64 rx_ovflow3;           /* drops due to buffer-group 3 overflows */
+	u64 rx_trunc0;            /* buffer-group 0 truncated packets */
+	u64 rx_trunc1;            /* buffer-group 1 truncated packets */
+	u64 rx_trunc2;            /* buffer-group 2 truncated packets */
+	u64 rx_trunc3;            /* buffer-group 3 truncated packets */
+};
+
+struct lb_port_stats {
+	u64 octets;
+	u64 frames;
+	u64 bcast_frames;
+	u64 mcast_frames;
+	u64 ucast_frames;
+	u64 error_frames;
+
+	u64 frames_64;
+	u64 frames_65_127;
+	u64 frames_128_255;
+	u64 frames_256_511;
+	u64 frames_512_1023;
+	u64 frames_1024_1518;
+	u64 frames_1519_max;
+
+	u64 drop;
+
+	u64 ovflow0;
+	u64 ovflow1;
+	u64 ovflow2;
+	u64 ovflow3;
+	u64 trunc0;
+	u64 trunc1;
+	u64 trunc2;
+	u64 trunc3;
+};
+
+struct tp_tcp_stats {
+	u32 tcpOutRsts;
+	u64 tcpInSegs;
+	u64 tcpOutSegs;
+	u64 tcpRetransSegs;
+};
+
+struct tp_err_stats {
+	u32 macInErrs[4];
+	u32 hdrInErrs[4];
+	u32 tcpInErrs[4];
+	u32 tnlCongDrops[4];
+	u32 ofldChanDrops[4];
+	u32 tnlTxDrops[4];
+	u32 ofldVlanDrops[4];
+	u32 tcp6InErrs[4];
+	u32 ofldNoNeigh;
+	u32 ofldCongDefer;
+};
+
+struct tp_params {
+	unsigned int ntxchan;        /* # of Tx channels */
+	unsigned int tre;            /* log2 of core clocks per TP tick */
+};
+
+struct vpd_params {
+	unsigned int cclk;
+	u8 ec[EC_LEN + 1];
+	u8 sn[SERNUM_LEN + 1];
+	u8 id[ID_LEN + 1];
+};
+
+struct pci_params {
+	unsigned char speed;
+	unsigned char width;
+};
+
+struct adapter_params {
+	struct tp_params  tp;
+	struct vpd_params vpd;
+	struct pci_params pci;
+
+	unsigned int fw_vers;
+	unsigned int tp_vers;
+	u8 api_vers[7];
+
+	unsigned short mtus[NMTUS];
+	unsigned short a_wnd[NCCTRL_WIN];
+	unsigned short b_wnd[NCCTRL_WIN];
+
+	unsigned char nports;             /* # of ethernet ports */
+	unsigned char portvec;
+	unsigned char rev;                /* chip revision */
+	unsigned char offload;
+
+	unsigned int ofldq_wr_cred;
+};
+
+struct trace_params {
+	u32 data[TRACE_LEN / 4];
+	u32 mask[TRACE_LEN / 4];
+	unsigned short snap_len;
+	unsigned short min_len;
+	unsigned char skip_ofst;
+	unsigned char skip_len;
+	unsigned char invert;
+	unsigned char port;
+};
+
+struct link_config {
+	unsigned short supported;        /* link capabilities */
+	unsigned short advertising;      /* advertised capabilities */
+	unsigned short requested_speed;  /* speed user has requested */
+	unsigned short speed;            /* actual link speed */
+	unsigned char  requested_fc;     /* flow control user has requested */
+	unsigned char  fc;               /* actual link flow control */
+	unsigned char  autoneg;          /* autonegotiating? */
+	unsigned char  link_ok;          /* link up? */
+};
+
+#define FW_LEN16(fw_struct) FW_CMD_LEN16(sizeof(fw_struct) / 16)
+
+enum {
+	MAX_ETH_QSETS = 32,           /* # of Ethernet Tx/Rx queue sets */
+	MAX_OFLD_QSETS = 16,          /* # of offload Tx/Rx queue sets */
+	MAX_CTRL_QUEUES = NCHAN,      /* # of control Tx queues */
+	MAX_RDMA_QUEUES = NCHAN,      /* # of streaming RDMA Rx queues */
+};
+
+enum {
+	MAX_EGRQ = 128,         /* max # of egress queues, including FLs */
+	MAX_INGQ = 64           /* max # of interrupt-capable ingress queues */
+};
+
+struct adapter;
+struct vlan_group;
+struct sge_rspq;
+
+struct port_info {
+	struct adapter *adapter;
+	struct vlan_group *vlan_grp;
+	u16    viid;
+	s16    xact_addr_filt;        /* index of exact MAC address filter */
+	u16    rss_size;              /* size of VI's RSS table slice */
+	s8     mdio_addr;
+	u8     port_type;
+	u8     mod_type;
+	u8     port_id;
+	u8     tx_chan;
+	u8     lport;                 /* associated offload logical port */
+	u8     rx_offload;            /* CSO, etc */
+	u8     nqsets;                /* # of qsets */
+	u8     first_qset;            /* index of first qset */
+	struct link_config link_cfg;
+};
+
+/* port_info.rx_offload flags */
+enum {
+	RX_CSO = 1 << 0,
+};
+
+struct dentry;
+struct work_struct;
+
+enum {                                 /* adapter flags */
+	FULL_INIT_DONE     = (1 << 0),
+	USING_MSI          = (1 << 1),
+	USING_MSIX         = (1 << 2),
+	QUEUES_BOUND       = (1 << 3),
+	FW_OK              = (1 << 4),
+};
+
+struct rx_sw_desc;
+
+struct sge_fl {                     /* SGE free-buffer queue state */
+	unsigned int avail;         /* # of available Rx buffers */
+	unsigned int pend_cred;     /* new buffers since last FL DB ring */
+	unsigned int cidx;          /* consumer index */
+	unsigned int pidx;          /* producer index */
+	unsigned long alloc_failed; /* # of times buffer allocation failed */
+	unsigned long large_alloc_failed;
+	unsigned long starving;
+	/* RO fields */
+	unsigned int cntxt_id;      /* SGE context id for the free list */
+	unsigned int size;          /* capacity of free list */
+	struct rx_sw_desc *sdesc;   /* address of SW Rx descriptor ring */
+	__be64 *desc;               /* address of HW Rx descriptor ring */
+	dma_addr_t addr;            /* bus address of HW ring start */
+};
+
+/* A packet gather list */
+struct pkt_gl {
+	skb_frag_t frags[MAX_SKB_FRAGS];
+	void *va;                         /* virtual address of first byte */
+	unsigned int nfrags;              /* # of fragments */
+	unsigned int tot_len;             /* total length of fragments */
+};
+
+typedef int (*rspq_handler_t)(struct sge_rspq *q, const __be64 *rsp,
+			      const struct pkt_gl *gl);
+
+struct sge_rspq {                   /* state for an SGE response queue */
+	struct napi_struct napi;
+	const __be64 *cur_desc;     /* current descriptor in queue */
+	unsigned int cidx;          /* consumer index */
+	u8 gen;                     /* current generation bit */
+	u8 intr_params;             /* interrupt holdoff parameters */
+	u8 next_intr_params;        /* holdoff params for next interrupt */
+	u8 pktcnt_idx;              /* interrupt packet threshold */
+	u8 uld;                     /* ULD handling this queue */
+	u8 idx;                     /* queue index within its group */
+	int offset;                 /* offset into current Rx buffer */
+	u16 cntxt_id;               /* SGE context id for the response q */
+	u16 abs_id;                 /* absolute SGE id for the response q */
+	__be64 *desc;               /* address of HW response ring */
+	dma_addr_t phys_addr;       /* physical address of the ring */
+	unsigned int iqe_len;       /* entry size */
+	unsigned int size;          /* capacity of response queue */
+	struct adapter *adap;
+	struct net_device *netdev;  /* associated net device */
+	rspq_handler_t handler;
+};
+
+struct sge_eth_stats {              /* Ethernet queue statistics */
+	unsigned long pkts;         /* # of ethernet packets */
+	unsigned long lro_pkts;     /* # of LRO super packets */
+	unsigned long lro_merged;   /* # of wire packets merged by LRO */
+	unsigned long rx_cso;       /* # of Rx checksum offloads */
+	unsigned long vlan_ex;      /* # of Rx VLAN extractions */
+	unsigned long rx_drops;     /* # of packets dropped due to no mem */
+};
+
+struct sge_eth_rxq {                /* SW Ethernet Rx queue */
+	struct sge_rspq rspq;
+	struct sge_fl fl;
+	struct sge_eth_stats stats;
+} ____cacheline_aligned_in_smp;
+
+struct sge_ofld_stats {             /* offload queue statistics */
+	unsigned long pkts;         /* # of packets */
+	unsigned long imm;          /* # of immediate-data packets */
+	unsigned long an;           /* # of asynchronous notifications */
+	unsigned long nomem;        /* # of responses deferred due to no mem */
+};
+
+struct sge_ofld_rxq {               /* SW offload Rx queue */
+	struct sge_rspq rspq;
+	struct sge_fl fl;
+	struct sge_ofld_stats stats;
+} ____cacheline_aligned_in_smp;
+
+struct tx_desc {
+	__be64 flit[8];
+};
+
+struct tx_sw_desc;
+
+struct sge_txq {
+	unsigned int  in_use;       /* # of in-use Tx descriptors */
+	unsigned int  size;         /* # of descriptors */
+	unsigned int  cidx;         /* SW consumer index */
+	unsigned int  pidx;         /* producer index */
+	unsigned long stops;        /* # of times q has been stopped */
+	unsigned long restarts;     /* # of queue restarts */
+	unsigned int  cntxt_id;     /* SGE context id for the Tx q */
+	struct tx_desc *desc;       /* address of HW Tx descriptor ring */
+	struct tx_sw_desc *sdesc;   /* address of SW Tx descriptor ring */
+	struct sge_qstat *stat;     /* queue status entry */
+	dma_addr_t    phys_addr;    /* physical address of the ring */
+};
+
+struct sge_eth_txq {                /* state for an SGE Ethernet Tx queue */
+	struct sge_txq q;
+	struct netdev_queue *txq;   /* associated netdev TX queue */
+	unsigned long tso;          /* # of TSO requests */
+	unsigned long tx_cso;       /* # of Tx checksum offloads */
+	unsigned long vlan_ins;     /* # of Tx VLAN insertions */
+	unsigned long mapping_err;  /* # of I/O MMU packet mapping errors */
+} ____cacheline_aligned_in_smp;
+
+struct sge_ofld_txq {               /* state for an SGE offload Tx queue */
+	struct sge_txq q;
+	struct adapter *adap;
+	struct sk_buff_head sendq;  /* list of backpressured packets */
+	struct tasklet_struct qresume_tsk; /* restarts the queue */
+	u8 full;                    /* the Tx ring is full */
+	unsigned long mapping_err;  /* # of I/O MMU packet mapping errors */
+} ____cacheline_aligned_in_smp;
+
+struct sge_ctrl_txq {               /* state for an SGE control Tx queue */
+	struct sge_txq q;
+	struct adapter *adap;
+	struct sk_buff_head sendq;  /* list of backpressured packets */
+	struct tasklet_struct qresume_tsk; /* restarts the queue */
+	u8 full;                    /* the Tx ring is full */
+} ____cacheline_aligned_in_smp;
+
+struct sge {
+	struct sge_eth_txq ethtxq[MAX_ETH_QSETS];
+	struct sge_ofld_txq ofldtxq[MAX_OFLD_QSETS];
+	struct sge_ctrl_txq ctrlq[MAX_CTRL_QUEUES];
+
+	struct sge_eth_rxq ethrxq[MAX_ETH_QSETS];
+	struct sge_ofld_rxq ofldrxq[MAX_OFLD_QSETS];
+	struct sge_ofld_rxq rdmarxq[MAX_RDMA_QUEUES];
+	struct sge_rspq fw_evtq ____cacheline_aligned_in_smp;
+
+	struct sge_rspq intrq ____cacheline_aligned_in_smp;
+	spinlock_t intrq_lock;
+
+	u16 max_ethqsets;           /* # of available Ethernet queue sets */
+	u16 ethqsets;               /* # of active Ethernet queue sets */
+	u16 ethtxq_rover;           /* Tx queue to clean up next */
+	u16 ofldqsets;              /* # of active offload queue sets */
+	u16 rdmaqs;                 /* # of available RDMA Rx queues */
+	u16 ofld_rxq[MAX_OFLD_QSETS];
+	u16 rdma_rxq[NCHAN];
+	u16 timer_val[SGE_NTIMERS];
+	u8 counter_val[SGE_NCOUNTERS];
+	unsigned int starve_thres;
+	u8 idma_state[2];
+	void *egr_map[MAX_EGRQ];    /* qid->queue egress queue map */
+	struct sge_rspq *ingr_map[MAX_INGQ]; /* qid->queue ingress queue map */
+	DECLARE_BITMAP(starving_fl, MAX_EGRQ);
+	DECLARE_BITMAP(txq_maperr, MAX_EGRQ);
+	struct timer_list rx_timer; /* refills starving FLs */
+	struct timer_list tx_timer; /* checks Tx queues */
+};
+
+#define for_each_ethrxq(sge, i) for (i = 0; i < (sge)->ethqsets; i++)
+#define for_each_ofldrxq(sge, i) for (i = 0; i < (sge)->ofldqsets; i++)
+#define for_each_rdmarxq(sge, i) for (i = 0; i < (sge)->rdmaqs; i++)
+
+struct l2t_data;
+
+struct adapter {
+	void __iomem *regs;
+	struct pci_dev *pdev;
+	struct device *pdev_dev;
+	unsigned long registered_device_map;
+	unsigned long open_device_map;
+	unsigned long flags;
+
+	const char *name;
+	int msg_enable;
+
+	struct adapter_params params;
+	struct cxgb4_virt_res vres;
+	unsigned int swintr;
+
+	unsigned int wol;
+
+	struct {
+		unsigned short vec;
+		char desc[14];
+	} msix_info[MAX_INGQ + 1];
+
+	struct sge sge;
+
+	struct net_device *port[MAX_NPORTS];
+	u8 chan_map[NCHAN];                   /* channel -> port map */
+
+	struct l2t_data *l2t;
+	void *uld_handle[CXGB4_ULD_MAX];
+	struct list_head list_node;
+
+	struct tid_info tids;
+	void **tid_release_head;
+	spinlock_t tid_release_lock;
+	struct work_struct tid_release_task;
+	bool tid_release_task_busy;
+
+	struct dentry *debugfs_root;
+
+	spinlock_t stats_lock;
+};
+
+static inline u32 t4_read_reg(struct adapter *adap, u32 reg_addr)
+{
+	return readl(adap->regs + reg_addr);
+}
+
+static inline void t4_write_reg(struct adapter *adap, u32 reg_addr, u32 val)
+{
+	writel(val, adap->regs + reg_addr);
+}
+
+#ifndef readq
+static inline u64 readq(const volatile void __iomem *addr)
+{
+	return readl(addr) + ((u64)readl(addr + 4) << 32);
+}
+
+static inline void writeq(u64 val, volatile void __iomem *addr)
+{
+	writel(val, addr);
+	writel(val >> 32, addr + 4);
+}
+#endif
+
+static inline u64 t4_read_reg64(struct adapter *adap, u32 reg_addr)
+{
+	return readq(adap->regs + reg_addr);
+}
+
+static inline void t4_write_reg64(struct adapter *adap, u32 reg_addr, u64 val)
+{
+	writeq(val, adap->regs + reg_addr);
+}
+
+/**
+ * netdev2pinfo - return the port_info structure associated with a net_device
+ * @dev: the netdev
+ *
+ * Return the struct port_info associated with a net_device
+ */
+static inline struct port_info *netdev2pinfo(const struct net_device *dev)
+{
+	return netdev_priv(dev);
+}
+
+/**
+ * adap2pinfo - return the port_info of a port
+ * @adap: the adapter
+ * @idx: the port index
+ *
+ * Return the port_info structure for the port of the given index.
+ */
+static inline struct port_info *adap2pinfo(struct adapter *adap, int idx)
+{
+	return netdev_priv(adap->port[idx]);
+}
+
+/**
+ * netdev2adap - return the adapter structure associated with a net_device
+ * @dev: the netdev
+ *
+ * Return the struct adapter associated with a net_device
+ */
+static inline struct adapter *netdev2adap(const struct net_device *dev)
+{
+	return netdev2pinfo(dev)->adapter;
+}
+
+void t4_os_portmod_changed(const struct adapter *adap, int port_id);
+void t4_os_link_changed(struct adapter *adap, int port_id, int link_stat);
+
+void *t4_alloc_mem(size_t size);
+void t4_free_mem(void *addr);
+
+void t4_free_sge_resources(struct adapter *adap);
+irq_handler_t t4_intr_handler(struct adapter *adap);
+netdev_tx_t t4_eth_xmit(struct sk_buff *skb, struct net_device *dev);
+int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
+		     const struct pkt_gl *gl);
+int t4_mgmt_tx(struct adapter *adap, struct sk_buff *skb);
+int t4_ofld_send(struct adapter *adap, struct sk_buff *skb);
+int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
+		     struct net_device *dev, int intr_idx,
+		     struct sge_fl *fl, rspq_handler_t hnd);
+int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
+			 struct net_device *dev, struct netdev_queue *netdevq,
+			 unsigned int iqid);
+int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq,
+			  struct net_device *dev, unsigned int iqid,
+			  unsigned int cmplqid);
+int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq,
+			  struct net_device *dev, unsigned int iqid);
+irqreturn_t t4_sge_intr_msix(int irq, void *cookie);
+void t4_sge_init(struct adapter *adap);
+void t4_sge_start(struct adapter *adap);
+void t4_sge_stop(struct adapter *adap);
+
+#define for_each_port(adapter, iter) \
+	for (iter = 0; iter < (adapter)->params.nports; ++iter)
+
+static inline unsigned int core_ticks_per_usec(const struct adapter *adap)
+{
+	return adap->params.vpd.cclk / 1000;
+}
+
+static inline unsigned int us_to_core_ticks(const struct adapter *adap,
+					    unsigned int us)
+{
+	return (us * adap->params.vpd.cclk) / 1000;
+}
+
+void t4_set_reg_field(struct adapter *adap, unsigned int addr, u32 mask,
+		      u32 val);
+
+int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
+		    void *rpl, bool sleep_ok);
+
+static inline int t4_wr_mbox(struct adapter *adap, int mbox, const void *cmd,
+			     int size, void *rpl)
+{
+	return t4_wr_mbox_meat(adap, mbox, cmd, size, rpl, true);
+}
+
+static inline int t4_wr_mbox_ns(struct adapter *adap, int mbox, const void *cmd,
+				int size, void *rpl)
+{
+	return t4_wr_mbox_meat(adap, mbox, cmd, size, rpl, false);
+}
+
+void t4_intr_enable(struct adapter *adapter);
+void t4_intr_disable(struct adapter *adapter);
+void t4_intr_clear(struct adapter *adapter);
+int t4_slow_intr_handler(struct adapter *adapter);
+
+int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port,
+		  struct link_config *lc);
+int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port);
+int t4_seeprom_wp(struct adapter *adapter, bool enable);
+int t4_read_flash(struct adapter *adapter, unsigned int addr,
+		  unsigned int nwords, u32 *data, int byte_oriented);
+int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size);
+int t4_check_fw_version(struct adapter *adapter);
+int t4_prep_adapter(struct adapter *adapter);
+int t4_port_init(struct adapter *adap, int mbox, int pf, int vf);
+void t4_fatal_err(struct adapter *adapter);
+void t4_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on);
+int t4_set_trace_filter(struct adapter *adapter, const struct trace_params *tp,
+			int filter_index, int enable);
+void t4_get_trace_filter(struct adapter *adapter, struct trace_params *tp,
+			 int filter_index, int *enabled);
+int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
+			int start, int n, const u16 *rspq, unsigned int nrspq);
+int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode,
+		       unsigned int flags);
+int t4_read_rss(struct adapter *adapter, u16 *entries);
+int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *parity);
+int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data,
+		u64 *parity);
+
+void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p);
+void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p);
+
+void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log);
+void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st);
+void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4,
+			 struct tp_tcp_stats *v6);
+void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
+		  const unsigned short *alpha, const unsigned short *beta);
+
+void t4_wol_magic_enable(struct adapter *adap, unsigned int port,
+			 const u8 *addr);
+int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
+		      u64 mask0, u64 mask1, unsigned int crc, bool enable);
+
+int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox,
+		enum dev_master master, enum dev_state *state);
+int t4_fw_bye(struct adapter *adap, unsigned int mbox);
+int t4_early_init(struct adapter *adap, unsigned int mbox);
+int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset);
+int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
+		    unsigned int vf, unsigned int nparams, const u32 *params,
+		    u32 *val);
+int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
+		  unsigned int vf, unsigned int nparams, const u32 *params,
+		  const u32 *val);
+int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf,
+		unsigned int vf, unsigned int txq, unsigned int txq_eth_ctrl,
+		unsigned int rxqi, unsigned int rxq, unsigned int tc,
+		unsigned int vi, unsigned int cmask, unsigned int pmask,
+		unsigned int nexact, unsigned int rcaps, unsigned int wxcaps);
+int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
+		unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac,
+		unsigned int *rss_size);
+int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf,
+	       unsigned int vf, unsigned int viid);
+int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid,
+		int mtu, int promisc, int all_multi, int bcast, bool sleep_ok);
+int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox,
+		      unsigned int viid, bool free, unsigned int naddr,
+		      const u8 **addr, u16 *idx, u64 *hash, bool sleep_ok);
+int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid,
+		  int idx, const u8 *addr, bool persist, bool add_smt);
+int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid,
+		     bool ucast, u64 vec, bool sleep_ok);
+int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid,
+		 bool rx_en, bool tx_en);
+int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid,
+		     unsigned int nblinks);
+int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
+	       unsigned int mmd, unsigned int reg, u16 *valp);
+int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
+	       unsigned int mmd, unsigned int reg, u16 val);
+int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start,
+		     unsigned int pf, unsigned int vf, unsigned int iqid,
+		     unsigned int fl0id, unsigned int fl1id);
+int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+	       unsigned int vf, unsigned int iqtype, unsigned int iqid,
+	       unsigned int fl0id, unsigned int fl1id);
+int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+		   unsigned int vf, unsigned int eqid);
+int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+		    unsigned int vf, unsigned int eqid);
+int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+		    unsigned int vf, unsigned int eqid);
+int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl);
+#endif /* __CXGB4_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb4/cxgb4_main.c linux-libre-2.6.34-gnu1/drivers/net/cxgb4/cxgb4_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb4/cxgb4_main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb4/cxgb4_main.c	2013-05-03 09:47:32.000000000 -0400
@@ -0,0 +1,3388 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/bitmap.h>
+#include <linux/crc32.h>
+#include <linux/ctype.h>
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/etherdevice.h>
+#include <linux/firmware.h>
+#include <linux/if_vlan.h>
+#include <linux/init.h>
+#include <linux/log2.h>
+#include <linux/mdio.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mutex.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/aer.h>
+#include <linux/rtnetlink.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/sockios.h>
+#include <linux/vmalloc.h>
+#include <linux/workqueue.h>
+#include <net/neighbour.h>
+#include <net/netevent.h>
+#include <asm/uaccess.h>
+
+#include "cxgb4.h"
+#include "t4_regs.h"
+#include "t4_msg.h"
+#include "t4fw_api.h"
+#include "l2t.h"
+
+#define DRV_VERSION "1.0.0-ko"
+#define DRV_DESC "Chelsio T4 Network Driver"
+
+/*
+ * Max interrupt hold-off timer value in us.  Queues fall back to this value
+ * under extreme memory pressure so it's largish to give the system time to
+ * recover.
+ */
+#define MAX_SGE_TIMERVAL 200U
+
+enum {
+	MEMWIN0_APERTURE = 65536,
+	MEMWIN0_BASE     = 0x30000,
+	MEMWIN1_APERTURE = 32768,
+	MEMWIN1_BASE     = 0x28000,
+	MEMWIN2_APERTURE = 2048,
+	MEMWIN2_BASE     = 0x1b800,
+};
+
+enum {
+	MAX_TXQ_ENTRIES      = 16384,
+	MAX_CTRL_TXQ_ENTRIES = 1024,
+	MAX_RSPQ_ENTRIES     = 16384,
+	MAX_RX_BUFFERS       = 16384,
+	MIN_TXQ_ENTRIES      = 32,
+	MIN_CTRL_TXQ_ENTRIES = 32,
+	MIN_RSPQ_ENTRIES     = 128,
+	MIN_FL_ENTRIES       = 16
+};
+
+#define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \
+			 NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\
+			 NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
+
+#define CH_DEVICE(devid) { PCI_VDEVICE(CHELSIO, devid), 0 }
+
+static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = {
+	CH_DEVICE(0xa000),  /* PE10K */
+	{ 0, }
+};
+
+#define FW_FNAME "/*(DEBLOBBED)*/"
+
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_AUTHOR("Chelsio Communications");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(DRV_VERSION);
+MODULE_DEVICE_TABLE(pci, cxgb4_pci_tbl);
+/*(DEBLOBBED)*/
+
+static int dflt_msg_enable = DFLT_MSG_ENABLE;
+
+module_param(dflt_msg_enable, int, 0644);
+MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T4 default message enable bitmap");
+
+/*
+ * The driver uses the best interrupt scheme available on a platform in the
+ * order MSI-X, MSI, legacy INTx interrupts.  This parameter determines which
+ * of these schemes the driver may consider as follows:
+ *
+ * msi = 2: choose from among all three options
+ * msi = 1: only consider MSI and INTx interrupts
+ * msi = 0: force INTx interrupts
+ */
+static int msi = 2;
+
+module_param(msi, int, 0644);
+MODULE_PARM_DESC(msi, "whether to use INTx (0), MSI (1) or MSI-X (2)");
+
+/*
+ * Queue interrupt hold-off timer values.  Queues default to the first of these
+ * upon creation.
+ */
+static unsigned int intr_holdoff[SGE_NTIMERS - 1] = { 5, 10, 20, 50, 100 };
+
+module_param_array(intr_holdoff, uint, NULL, 0644);
+MODULE_PARM_DESC(intr_holdoff, "values for queue interrupt hold-off timers "
+		 "0..4 in microseconds");
+
+static unsigned int intr_cnt[SGE_NCOUNTERS - 1] = { 4, 8, 16 };
+
+module_param_array(intr_cnt, uint, NULL, 0644);
+MODULE_PARM_DESC(intr_cnt,
+		 "thresholds 1..3 for queue interrupt packet counters");
+
+static int vf_acls;
+
+#ifdef CONFIG_PCI_IOV
+module_param(vf_acls, bool, 0644);
+MODULE_PARM_DESC(vf_acls, "if set enable virtualization L2 ACL enforcement");
+
+static unsigned int num_vf[4];
+
+module_param_array(num_vf, uint, NULL, 0644);
+MODULE_PARM_DESC(num_vf, "number of VFs for each of PFs 0-3");
+#endif
+
+static struct dentry *cxgb4_debugfs_root;
+
+static LIST_HEAD(adapter_list);
+static DEFINE_MUTEX(uld_mutex);
+static struct cxgb4_uld_info ulds[CXGB4_ULD_MAX];
+static const char *uld_str[] = { "RDMA", "iSCSI" };
+
+static void link_report(struct net_device *dev)
+{
+	if (!netif_carrier_ok(dev))
+		netdev_info(dev, "link down\n");
+	else {
+		static const char *fc[] = { "no", "Rx", "Tx", "Tx/Rx" };
+
+		const char *s = "10Mbps";
+		const struct port_info *p = netdev_priv(dev);
+
+		switch (p->link_cfg.speed) {
+		case SPEED_10000:
+			s = "10Gbps";
+			break;
+		case SPEED_1000:
+			s = "1000Mbps";
+			break;
+		case SPEED_100:
+			s = "100Mbps";
+			break;
+		}
+
+		netdev_info(dev, "link up, %s, full-duplex, %s PAUSE\n", s,
+			    fc[p->link_cfg.fc]);
+	}
+}
+
+void t4_os_link_changed(struct adapter *adapter, int port_id, int link_stat)
+{
+	struct net_device *dev = adapter->port[port_id];
+
+	/* Skip changes from disabled ports. */
+	if (netif_running(dev) && link_stat != netif_carrier_ok(dev)) {
+		if (link_stat)
+			netif_carrier_on(dev);
+		else
+			netif_carrier_off(dev);
+
+		link_report(dev);
+	}
+}
+
+void t4_os_portmod_changed(const struct adapter *adap, int port_id)
+{
+	static const char *mod_str[] = {
+		NULL, "LR", "SR", "ER", "passive DA", "active DA"
+	};
+
+	const struct net_device *dev = adap->port[port_id];
+	const struct port_info *pi = netdev_priv(dev);
+
+	if (pi->mod_type == FW_PORT_MOD_TYPE_NONE)
+		netdev_info(dev, "port module unplugged\n");
+	else
+		netdev_info(dev, "%s module inserted\n", mod_str[pi->mod_type]);
+}
+
+/*
+ * Configure the exact and hash address filters to handle a port's multicast
+ * and secondary unicast MAC addresses.
+ */
+static int set_addr_filters(const struct net_device *dev, bool sleep)
+{
+	u64 mhash = 0;
+	u64 uhash = 0;
+	bool free = true;
+	u16 filt_idx[7];
+	const u8 *addr[7];
+	int ret, naddr = 0;
+	const struct dev_addr_list *d;
+	const struct netdev_hw_addr *ha;
+	int uc_cnt = netdev_uc_count(dev);
+	const struct port_info *pi = netdev_priv(dev);
+
+	/* first do the secondary unicast addresses */
+	netdev_for_each_uc_addr(ha, dev) {
+		addr[naddr++] = ha->addr;
+		if (--uc_cnt == 0 || naddr >= ARRAY_SIZE(addr)) {
+			ret = t4_alloc_mac_filt(pi->adapter, 0, pi->viid, free,
+					naddr, addr, filt_idx, &uhash, sleep);
+			if (ret < 0)
+				return ret;
+
+			free = false;
+			naddr = 0;
+		}
+	}
+
+	/* next set up the multicast addresses */
+	netdev_for_each_mc_addr(d, dev) {
+		addr[naddr++] = d->dmi_addr;
+		if (naddr >= ARRAY_SIZE(addr) || d->next == NULL) {
+			ret = t4_alloc_mac_filt(pi->adapter, 0, pi->viid, free,
+					naddr, addr, filt_idx, &mhash, sleep);
+			if (ret < 0)
+				return ret;
+
+			free = false;
+			naddr = 0;
+		}
+	}
+
+	return t4_set_addr_hash(pi->adapter, 0, pi->viid, uhash != 0,
+				uhash | mhash, sleep);
+}
+
+/*
+ * Set Rx properties of a port, such as promiscruity, address filters, and MTU.
+ * If @mtu is -1 it is left unchanged.
+ */
+static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok)
+{
+	int ret;
+	struct port_info *pi = netdev_priv(dev);
+
+	ret = set_addr_filters(dev, sleep_ok);
+	if (ret == 0)
+		ret = t4_set_rxmode(pi->adapter, 0, pi->viid, mtu,
+				    (dev->flags & IFF_PROMISC) ? 1 : 0,
+				    (dev->flags & IFF_ALLMULTI) ? 1 : 0, 1,
+				    sleep_ok);
+	return ret;
+}
+
+/**
+ *	link_start - enable a port
+ *	@dev: the port to enable
+ *
+ *	Performs the MAC and PHY actions needed to enable a port.
+ */
+static int link_start(struct net_device *dev)
+{
+	int ret;
+	struct port_info *pi = netdev_priv(dev);
+
+	/*
+	 * We do not set address filters and promiscuity here, the stack does
+	 * that step explicitly.
+	 */
+	ret = t4_set_rxmode(pi->adapter, 0, pi->viid, dev->mtu, -1, -1, -1,
+			    true);
+	if (ret == 0) {
+		ret = t4_change_mac(pi->adapter, 0, pi->viid,
+				    pi->xact_addr_filt, dev->dev_addr, true,
+				    false);
+		if (ret >= 0) {
+			pi->xact_addr_filt = ret;
+			ret = 0;
+		}
+	}
+	if (ret == 0)
+		ret = t4_link_start(pi->adapter, 0, pi->tx_chan, &pi->link_cfg);
+	if (ret == 0)
+		ret = t4_enable_vi(pi->adapter, 0, pi->viid, true, true);
+	return ret;
+}
+
+/*
+ * Response queue handler for the FW event queue.
+ */
+static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
+			  const struct pkt_gl *gl)
+{
+	u8 opcode = ((const struct rss_header *)rsp)->opcode;
+
+	rsp++;                                          /* skip RSS header */
+	if (likely(opcode == CPL_SGE_EGR_UPDATE)) {
+		const struct cpl_sge_egr_update *p = (void *)rsp;
+		unsigned int qid = EGR_QID(ntohl(p->opcode_qid));
+		struct sge_txq *txq = q->adap->sge.egr_map[qid];
+
+		txq->restarts++;
+		if ((u8 *)txq < (u8 *)q->adap->sge.ethrxq) {
+			struct sge_eth_txq *eq;
+
+			eq = container_of(txq, struct sge_eth_txq, q);
+			netif_tx_wake_queue(eq->txq);
+		} else {
+			struct sge_ofld_txq *oq;
+
+			oq = container_of(txq, struct sge_ofld_txq, q);
+			tasklet_schedule(&oq->qresume_tsk);
+		}
+	} else if (opcode == CPL_FW6_MSG || opcode == CPL_FW4_MSG) {
+		const struct cpl_fw6_msg *p = (void *)rsp;
+
+		if (p->type == 0)
+			t4_handle_fw_rpl(q->adap, p->data);
+	} else if (opcode == CPL_L2T_WRITE_RPL) {
+		const struct cpl_l2t_write_rpl *p = (void *)rsp;
+
+		do_l2t_write_rpl(q->adap, p);
+	} else
+		dev_err(q->adap->pdev_dev,
+			"unexpected CPL %#x on FW event queue\n", opcode);
+	return 0;
+}
+
+/**
+ *	uldrx_handler - response queue handler for ULD queues
+ *	@q: the response queue that received the packet
+ *	@rsp: the response queue descriptor holding the offload message
+ *	@gl: the gather list of packet fragments
+ *
+ *	Deliver an ingress offload packet to a ULD.  All processing is done by
+ *	the ULD, we just maintain statistics.
+ */
+static int uldrx_handler(struct sge_rspq *q, const __be64 *rsp,
+			 const struct pkt_gl *gl)
+{
+	struct sge_ofld_rxq *rxq = container_of(q, struct sge_ofld_rxq, rspq);
+
+	if (ulds[q->uld].rx_handler(q->adap->uld_handle[q->uld], rsp, gl)) {
+		rxq->stats.nomem++;
+		return -1;
+	}
+	if (gl == NULL)
+		rxq->stats.imm++;
+	else if (gl == CXGB4_MSG_AN)
+		rxq->stats.an++;
+	else
+		rxq->stats.pkts++;
+	return 0;
+}
+
+static void disable_msi(struct adapter *adapter)
+{
+	if (adapter->flags & USING_MSIX) {
+		pci_disable_msix(adapter->pdev);
+		adapter->flags &= ~USING_MSIX;
+	} else if (adapter->flags & USING_MSI) {
+		pci_disable_msi(adapter->pdev);
+		adapter->flags &= ~USING_MSI;
+	}
+}
+
+/*
+ * Interrupt handler for non-data events used with MSI-X.
+ */
+static irqreturn_t t4_nondata_intr(int irq, void *cookie)
+{
+	struct adapter *adap = cookie;
+
+	u32 v = t4_read_reg(adap, MYPF_REG(PL_PF_INT_CAUSE));
+	if (v & PFSW) {
+		adap->swintr = 1;
+		t4_write_reg(adap, MYPF_REG(PL_PF_INT_CAUSE), v);
+	}
+	t4_slow_intr_handler(adap);
+	return IRQ_HANDLED;
+}
+
+/*
+ * Name the MSI-X interrupts.
+ */
+static void name_msix_vecs(struct adapter *adap)
+{
+	int i, j, msi_idx = 2, n = sizeof(adap->msix_info[0].desc) - 1;
+
+	/* non-data interrupts */
+	snprintf(adap->msix_info[0].desc, n, "%s", adap->name);
+	adap->msix_info[0].desc[n] = 0;
+
+	/* FW events */
+	snprintf(adap->msix_info[1].desc, n, "%s-FWeventq", adap->name);
+	adap->msix_info[1].desc[n] = 0;
+
+	/* Ethernet queues */
+	for_each_port(adap, j) {
+		struct net_device *d = adap->port[j];
+		const struct port_info *pi = netdev_priv(d);
+
+		for (i = 0; i < pi->nqsets; i++, msi_idx++) {
+			snprintf(adap->msix_info[msi_idx].desc, n, "%s-Rx%d",
+				 d->name, i);
+			adap->msix_info[msi_idx].desc[n] = 0;
+		}
+	}
+
+	/* offload queues */
+	for_each_ofldrxq(&adap->sge, i) {
+		snprintf(adap->msix_info[msi_idx].desc, n, "%s-ofld%d",
+			 adap->name, i);
+		adap->msix_info[msi_idx++].desc[n] = 0;
+	}
+	for_each_rdmarxq(&adap->sge, i) {
+		snprintf(adap->msix_info[msi_idx].desc, n, "%s-rdma%d",
+			 adap->name, i);
+		adap->msix_info[msi_idx++].desc[n] = 0;
+	}
+}
+
+static int request_msix_queue_irqs(struct adapter *adap)
+{
+	struct sge *s = &adap->sge;
+	int err, ethqidx, ofldqidx = 0, rdmaqidx = 0, msi = 2;
+
+	err = request_irq(adap->msix_info[1].vec, t4_sge_intr_msix, 0,
+			  adap->msix_info[1].desc, &s->fw_evtq);
+	if (err)
+		return err;
+
+	for_each_ethrxq(s, ethqidx) {
+		err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0,
+				  adap->msix_info[msi].desc,
+				  &s->ethrxq[ethqidx].rspq);
+		if (err)
+			goto unwind;
+		msi++;
+	}
+	for_each_ofldrxq(s, ofldqidx) {
+		err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0,
+				  adap->msix_info[msi].desc,
+				  &s->ofldrxq[ofldqidx].rspq);
+		if (err)
+			goto unwind;
+		msi++;
+	}
+	for_each_rdmarxq(s, rdmaqidx) {
+		err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0,
+				  adap->msix_info[msi].desc,
+				  &s->rdmarxq[rdmaqidx].rspq);
+		if (err)
+			goto unwind;
+		msi++;
+	}
+	return 0;
+
+unwind:
+	while (--rdmaqidx >= 0)
+		free_irq(adap->msix_info[--msi].vec,
+			 &s->rdmarxq[rdmaqidx].rspq);
+	while (--ofldqidx >= 0)
+		free_irq(adap->msix_info[--msi].vec,
+			 &s->ofldrxq[ofldqidx].rspq);
+	while (--ethqidx >= 0)
+		free_irq(adap->msix_info[--msi].vec, &s->ethrxq[ethqidx].rspq);
+	free_irq(adap->msix_info[1].vec, &s->fw_evtq);
+	return err;
+}
+
+static void free_msix_queue_irqs(struct adapter *adap)
+{
+	int i, msi = 2;
+	struct sge *s = &adap->sge;
+
+	free_irq(adap->msix_info[1].vec, &s->fw_evtq);
+	for_each_ethrxq(s, i)
+		free_irq(adap->msix_info[msi++].vec, &s->ethrxq[i].rspq);
+	for_each_ofldrxq(s, i)
+		free_irq(adap->msix_info[msi++].vec, &s->ofldrxq[i].rspq);
+	for_each_rdmarxq(s, i)
+		free_irq(adap->msix_info[msi++].vec, &s->rdmarxq[i].rspq);
+}
+
+/**
+ *	setup_rss - configure RSS
+ *	@adap: the adapter
+ *
+ *	Sets up RSS to distribute packets to multiple receive queues.  We
+ *	configure the RSS CPU lookup table to distribute to the number of HW
+ *	receive queues, and the response queue lookup table to narrow that
+ *	down to the response queues actually configured for each port.
+ *	We always configure the RSS mapping for all ports since the mapping
+ *	table has plenty of entries.
+ */
+static int setup_rss(struct adapter *adap)
+{
+	int i, j, err;
+	u16 rss[MAX_ETH_QSETS];
+
+	for_each_port(adap, i) {
+		const struct port_info *pi = adap2pinfo(adap, i);
+		const struct sge_eth_rxq *q = &adap->sge.ethrxq[pi->first_qset];
+
+		for (j = 0; j < pi->nqsets; j++)
+			rss[j] = q[j].rspq.abs_id;
+
+		err = t4_config_rss_range(adap, 0, pi->viid, 0, pi->rss_size,
+					  rss, pi->nqsets);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
+/*
+ * Wait until all NAPI handlers are descheduled.
+ */
+static void quiesce_rx(struct adapter *adap)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(adap->sge.ingr_map); i++) {
+		struct sge_rspq *q = adap->sge.ingr_map[i];
+
+		if (q && q->handler)
+			napi_disable(&q->napi);
+	}
+}
+
+/*
+ * Enable NAPI scheduling and interrupt generation for all Rx queues.
+ */
+static void enable_rx(struct adapter *adap)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(adap->sge.ingr_map); i++) {
+		struct sge_rspq *q = adap->sge.ingr_map[i];
+
+		if (!q)
+			continue;
+		if (q->handler)
+			napi_enable(&q->napi);
+		/* 0-increment GTS to start the timer and enable interrupts */
+		t4_write_reg(adap, MYPF_REG(SGE_PF_GTS),
+			     SEINTARM(q->intr_params) |
+			     INGRESSQID(q->cntxt_id));
+	}
+}
+
+/**
+ *	setup_sge_queues - configure SGE Tx/Rx/response queues
+ *	@adap: the adapter
+ *
+ *	Determines how many sets of SGE queues to use and initializes them.
+ *	We support multiple queue sets per port if we have MSI-X, otherwise
+ *	just one queue set per port.
+ */
+static int setup_sge_queues(struct adapter *adap)
+{
+	int err, msi_idx, i, j;
+	struct sge *s = &adap->sge;
+
+	bitmap_zero(s->starving_fl, MAX_EGRQ);
+	bitmap_zero(s->txq_maperr, MAX_EGRQ);
+
+	if (adap->flags & USING_MSIX)
+		msi_idx = 1;         /* vector 0 is for non-queue interrupts */
+	else {
+		err = t4_sge_alloc_rxq(adap, &s->intrq, false, adap->port[0], 0,
+				       NULL, NULL);
+		if (err)
+			return err;
+		msi_idx = -((int)s->intrq.abs_id + 1);
+	}
+
+	err = t4_sge_alloc_rxq(adap, &s->fw_evtq, true, adap->port[0],
+			       msi_idx, NULL, fwevtq_handler);
+	if (err) {
+freeout:	t4_free_sge_resources(adap);
+		return err;
+	}
+
+	for_each_port(adap, i) {
+		struct net_device *dev = adap->port[i];
+		struct port_info *pi = netdev_priv(dev);
+		struct sge_eth_rxq *q = &s->ethrxq[pi->first_qset];
+		struct sge_eth_txq *t = &s->ethtxq[pi->first_qset];
+
+		for (j = 0; j < pi->nqsets; j++, q++) {
+			if (msi_idx > 0)
+				msi_idx++;
+			err = t4_sge_alloc_rxq(adap, &q->rspq, false, dev,
+					       msi_idx, &q->fl,
+					       t4_ethrx_handler);
+			if (err)
+				goto freeout;
+			q->rspq.idx = j;
+			memset(&q->stats, 0, sizeof(q->stats));
+		}
+		for (j = 0; j < pi->nqsets; j++, t++) {
+			err = t4_sge_alloc_eth_txq(adap, t, dev,
+					netdev_get_tx_queue(dev, j),
+					s->fw_evtq.cntxt_id);
+			if (err)
+				goto freeout;
+		}
+	}
+
+	j = s->ofldqsets / adap->params.nports; /* ofld queues per channel */
+	for_each_ofldrxq(s, i) {
+		struct sge_ofld_rxq *q = &s->ofldrxq[i];
+		struct net_device *dev = adap->port[i / j];
+
+		if (msi_idx > 0)
+			msi_idx++;
+		err = t4_sge_alloc_rxq(adap, &q->rspq, false, dev, msi_idx,
+				       &q->fl, uldrx_handler);
+		if (err)
+			goto freeout;
+		memset(&q->stats, 0, sizeof(q->stats));
+		s->ofld_rxq[i] = q->rspq.abs_id;
+		err = t4_sge_alloc_ofld_txq(adap, &s->ofldtxq[i], dev,
+					    s->fw_evtq.cntxt_id);
+		if (err)
+			goto freeout;
+	}
+
+	for_each_rdmarxq(s, i) {
+		struct sge_ofld_rxq *q = &s->rdmarxq[i];
+
+		if (msi_idx > 0)
+			msi_idx++;
+		err = t4_sge_alloc_rxq(adap, &q->rspq, false, adap->port[i],
+				       msi_idx, &q->fl, uldrx_handler);
+		if (err)
+			goto freeout;
+		memset(&q->stats, 0, sizeof(q->stats));
+		s->rdma_rxq[i] = q->rspq.abs_id;
+	}
+
+	for_each_port(adap, i) {
+		/*
+		 * Note that ->rdmarxq[i].rspq.cntxt_id below is 0 if we don't
+		 * have RDMA queues, and that's the right value.
+		 */
+		err = t4_sge_alloc_ctrl_txq(adap, &s->ctrlq[i], adap->port[i],
+					    s->fw_evtq.cntxt_id,
+					    s->rdmarxq[i].rspq.cntxt_id);
+		if (err)
+			goto freeout;
+	}
+
+	t4_write_reg(adap, MPS_TRC_RSS_CONTROL,
+		     RSSCONTROL(netdev2pinfo(adap->port[0])->tx_chan) |
+		     QUEUENUMBER(s->ethrxq[0].rspq.abs_id));
+	return 0;
+}
+
+/*
+ * Returns 0 if new FW was successfully loaded, a positive errno if a load was
+ * started but failed, and a negative errno if flash load couldn't start.
+ */
+static int upgrade_fw(struct adapter *adap)
+{
+	int ret;
+	u32 vers;
+	const struct fw_hdr *hdr;
+	const struct firmware *fw;
+	struct device *dev = adap->pdev_dev;
+
+	ret = reject_firmware(&fw, FW_FNAME, dev);
+	if (ret < 0) {
+		dev_err(dev, "unable to load firmware image " FW_FNAME
+			", error %d\n", ret);
+		return ret;
+	}
+
+	hdr = (const struct fw_hdr *)fw->data;
+	vers = ntohl(hdr->fw_ver);
+	if (FW_HDR_FW_VER_MAJOR_GET(vers) != FW_VERSION_MAJOR) {
+		ret = -EINVAL;              /* wrong major version, won't do */
+		goto out;
+	}
+
+	/*
+	 * If the flash FW is unusable or we found something newer, load it.
+	 */
+	if (FW_HDR_FW_VER_MAJOR_GET(adap->params.fw_vers) != FW_VERSION_MAJOR ||
+	    vers > adap->params.fw_vers) {
+		ret = -t4_load_fw(adap, fw->data, fw->size);
+		if (!ret)
+			dev_info(dev, "firmware upgraded to version %pI4 from "
+				 FW_FNAME "\n", &hdr->fw_ver);
+	}
+out:	release_firmware(fw);
+	return ret;
+}
+
+/*
+ * Allocate a chunk of memory using kmalloc or, if that fails, vmalloc.
+ * The allocated memory is cleared.
+ */
+void *t4_alloc_mem(size_t size)
+{
+	void *p = kmalloc(size, GFP_KERNEL);
+
+	if (!p)
+		p = vmalloc(size);
+	if (p)
+		memset(p, 0, size);
+	return p;
+}
+
+/*
+ * Free memory allocated through alloc_mem().
+ */
+void t4_free_mem(void *addr)
+{
+	if (is_vmalloc_addr(addr))
+		vfree(addr);
+	else
+		kfree(addr);
+}
+
+static inline int is_offload(const struct adapter *adap)
+{
+	return adap->params.offload;
+}
+
+/*
+ * Implementation of ethtool operations.
+ */
+
+static u32 get_msglevel(struct net_device *dev)
+{
+	return netdev2adap(dev)->msg_enable;
+}
+
+static void set_msglevel(struct net_device *dev, u32 val)
+{
+	netdev2adap(dev)->msg_enable = val;
+}
+
+static char stats_strings[][ETH_GSTRING_LEN] = {
+	"TxOctetsOK         ",
+	"TxFramesOK         ",
+	"TxBroadcastFrames  ",
+	"TxMulticastFrames  ",
+	"TxUnicastFrames    ",
+	"TxErrorFrames      ",
+
+	"TxFrames64         ",
+	"TxFrames65To127    ",
+	"TxFrames128To255   ",
+	"TxFrames256To511   ",
+	"TxFrames512To1023  ",
+	"TxFrames1024To1518 ",
+	"TxFrames1519ToMax  ",
+
+	"TxFramesDropped    ",
+	"TxPauseFrames      ",
+	"TxPPP0Frames       ",
+	"TxPPP1Frames       ",
+	"TxPPP2Frames       ",
+	"TxPPP3Frames       ",
+	"TxPPP4Frames       ",
+	"TxPPP5Frames       ",
+	"TxPPP6Frames       ",
+	"TxPPP7Frames       ",
+
+	"RxOctetsOK         ",
+	"RxFramesOK         ",
+	"RxBroadcastFrames  ",
+	"RxMulticastFrames  ",
+	"RxUnicastFrames    ",
+
+	"RxFramesTooLong    ",
+	"RxJabberErrors     ",
+	"RxFCSErrors        ",
+	"RxLengthErrors     ",
+	"RxSymbolErrors     ",
+	"RxRuntFrames       ",
+
+	"RxFrames64         ",
+	"RxFrames65To127    ",
+	"RxFrames128To255   ",
+	"RxFrames256To511   ",
+	"RxFrames512To1023  ",
+	"RxFrames1024To1518 ",
+	"RxFrames1519ToMax  ",
+
+	"RxPauseFrames      ",
+	"RxPPP0Frames       ",
+	"RxPPP1Frames       ",
+	"RxPPP2Frames       ",
+	"RxPPP3Frames       ",
+	"RxPPP4Frames       ",
+	"RxPPP5Frames       ",
+	"RxPPP6Frames       ",
+	"RxPPP7Frames       ",
+
+	"RxBG0FramesDropped ",
+	"RxBG1FramesDropped ",
+	"RxBG2FramesDropped ",
+	"RxBG3FramesDropped ",
+	"RxBG0FramesTrunc   ",
+	"RxBG1FramesTrunc   ",
+	"RxBG2FramesTrunc   ",
+	"RxBG3FramesTrunc   ",
+
+	"TSO                ",
+	"TxCsumOffload      ",
+	"RxCsumGood         ",
+	"VLANextractions    ",
+	"VLANinsertions     ",
+};
+
+static int get_sset_count(struct net_device *dev, int sset)
+{
+	switch (sset) {
+	case ETH_SS_STATS:
+		return ARRAY_SIZE(stats_strings);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+#define T4_REGMAP_SIZE (160 * 1024)
+
+static int get_regs_len(struct net_device *dev)
+{
+	return T4_REGMAP_SIZE;
+}
+
+static int get_eeprom_len(struct net_device *dev)
+{
+	return EEPROMSIZE;
+}
+
+static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	struct adapter *adapter = netdev2adap(dev);
+
+	strcpy(info->driver, KBUILD_MODNAME);
+	strcpy(info->version, DRV_VERSION);
+	strcpy(info->bus_info, pci_name(adapter->pdev));
+
+	if (!adapter->params.fw_vers)
+		strcpy(info->fw_version, "N/A");
+	else
+		snprintf(info->fw_version, sizeof(info->fw_version),
+			"%u.%u.%u.%u, TP %u.%u.%u.%u",
+			FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers),
+			FW_HDR_FW_VER_MINOR_GET(adapter->params.fw_vers),
+			FW_HDR_FW_VER_MICRO_GET(adapter->params.fw_vers),
+			FW_HDR_FW_VER_BUILD_GET(adapter->params.fw_vers),
+			FW_HDR_FW_VER_MAJOR_GET(adapter->params.tp_vers),
+			FW_HDR_FW_VER_MINOR_GET(adapter->params.tp_vers),
+			FW_HDR_FW_VER_MICRO_GET(adapter->params.tp_vers),
+			FW_HDR_FW_VER_BUILD_GET(adapter->params.tp_vers));
+}
+
+static void get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+	if (stringset == ETH_SS_STATS)
+		memcpy(data, stats_strings, sizeof(stats_strings));
+}
+
+/*
+ * port stats maintained per queue of the port.  They should be in the same
+ * order as in stats_strings above.
+ */
+struct queue_port_stats {
+	u64 tso;
+	u64 tx_csum;
+	u64 rx_csum;
+	u64 vlan_ex;
+	u64 vlan_ins;
+};
+
+static void collect_sge_port_stats(const struct adapter *adap,
+		const struct port_info *p, struct queue_port_stats *s)
+{
+	int i;
+	const struct sge_eth_txq *tx = &adap->sge.ethtxq[p->first_qset];
+	const struct sge_eth_rxq *rx = &adap->sge.ethrxq[p->first_qset];
+
+	memset(s, 0, sizeof(*s));
+	for (i = 0; i < p->nqsets; i++, rx++, tx++) {
+		s->tso += tx->tso;
+		s->tx_csum += tx->tx_cso;
+		s->rx_csum += rx->stats.rx_cso;
+		s->vlan_ex += rx->stats.vlan_ex;
+		s->vlan_ins += tx->vlan_ins;
+	}
+}
+
+static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
+		      u64 *data)
+{
+	struct port_info *pi = netdev_priv(dev);
+	struct adapter *adapter = pi->adapter;
+
+	t4_get_port_stats(adapter, pi->tx_chan, (struct port_stats *)data);
+
+	data += sizeof(struct port_stats) / sizeof(u64);
+	collect_sge_port_stats(adapter, pi, (struct queue_port_stats *)data);
+}
+
+/*
+ * Return a version number to identify the type of adapter.  The scheme is:
+ * - bits 0..9: chip version
+ * - bits 10..15: chip revision
+ */
+static inline unsigned int mk_adap_vers(const struct adapter *ap)
+{
+	return 4 | (ap->params.rev << 10);
+}
+
+static void reg_block_dump(struct adapter *ap, void *buf, unsigned int start,
+			   unsigned int end)
+{
+	u32 *p = buf + start;
+
+	for ( ; start <= end; start += sizeof(u32))
+		*p++ = t4_read_reg(ap, start);
+}
+
+static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
+		     void *buf)
+{
+	static const unsigned int reg_ranges[] = {
+		0x1008, 0x1108,
+		0x1180, 0x11b4,
+		0x11fc, 0x123c,
+		0x1300, 0x173c,
+		0x1800, 0x18fc,
+		0x3000, 0x30d8,
+		0x30e0, 0x5924,
+		0x5960, 0x59d4,
+		0x5a00, 0x5af8,
+		0x6000, 0x6098,
+		0x6100, 0x6150,
+		0x6200, 0x6208,
+		0x6240, 0x6248,
+		0x6280, 0x6338,
+		0x6370, 0x638c,
+		0x6400, 0x643c,
+		0x6500, 0x6524,
+		0x6a00, 0x6a38,
+		0x6a60, 0x6a78,
+		0x6b00, 0x6b84,
+		0x6bf0, 0x6c84,
+		0x6cf0, 0x6d84,
+		0x6df0, 0x6e84,
+		0x6ef0, 0x6f84,
+		0x6ff0, 0x7084,
+		0x70f0, 0x7184,
+		0x71f0, 0x7284,
+		0x72f0, 0x7384,
+		0x73f0, 0x7450,
+		0x7500, 0x7530,
+		0x7600, 0x761c,
+		0x7680, 0x76cc,
+		0x7700, 0x7798,
+		0x77c0, 0x77fc,
+		0x7900, 0x79fc,
+		0x7b00, 0x7c38,
+		0x7d00, 0x7efc,
+		0x8dc0, 0x8e1c,
+		0x8e30, 0x8e78,
+		0x8ea0, 0x8f6c,
+		0x8fc0, 0x9074,
+		0x90fc, 0x90fc,
+		0x9400, 0x9458,
+		0x9600, 0x96bc,
+		0x9800, 0x9808,
+		0x9820, 0x983c,
+		0x9850, 0x9864,
+		0x9c00, 0x9c6c,
+		0x9c80, 0x9cec,
+		0x9d00, 0x9d6c,
+		0x9d80, 0x9dec,
+		0x9e00, 0x9e6c,
+		0x9e80, 0x9eec,
+		0x9f00, 0x9f6c,
+		0x9f80, 0x9fec,
+		0xd004, 0xd03c,
+		0xdfc0, 0xdfe0,
+		0xe000, 0xea7c,
+		0xf000, 0x11190,
+		0x19040, 0x19124,
+		0x19150, 0x191b0,
+		0x191d0, 0x191e8,
+		0x19238, 0x1924c,
+		0x193f8, 0x19474,
+		0x19490, 0x194f8,
+		0x19800, 0x19f30,
+		0x1a000, 0x1a06c,
+		0x1a0b0, 0x1a120,
+		0x1a128, 0x1a138,
+		0x1a190, 0x1a1c4,
+		0x1a1fc, 0x1a1fc,
+		0x1e040, 0x1e04c,
+		0x1e240, 0x1e28c,
+		0x1e2c0, 0x1e2c0,
+		0x1e2e0, 0x1e2e0,
+		0x1e300, 0x1e384,
+		0x1e3c0, 0x1e3c8,
+		0x1e440, 0x1e44c,
+		0x1e640, 0x1e68c,
+		0x1e6c0, 0x1e6c0,
+		0x1e6e0, 0x1e6e0,
+		0x1e700, 0x1e784,
+		0x1e7c0, 0x1e7c8,
+		0x1e840, 0x1e84c,
+		0x1ea40, 0x1ea8c,
+		0x1eac0, 0x1eac0,
+		0x1eae0, 0x1eae0,
+		0x1eb00, 0x1eb84,
+		0x1ebc0, 0x1ebc8,
+		0x1ec40, 0x1ec4c,
+		0x1ee40, 0x1ee8c,
+		0x1eec0, 0x1eec0,
+		0x1eee0, 0x1eee0,
+		0x1ef00, 0x1ef84,
+		0x1efc0, 0x1efc8,
+		0x1f040, 0x1f04c,
+		0x1f240, 0x1f28c,
+		0x1f2c0, 0x1f2c0,
+		0x1f2e0, 0x1f2e0,
+		0x1f300, 0x1f384,
+		0x1f3c0, 0x1f3c8,
+		0x1f440, 0x1f44c,
+		0x1f640, 0x1f68c,
+		0x1f6c0, 0x1f6c0,
+		0x1f6e0, 0x1f6e0,
+		0x1f700, 0x1f784,
+		0x1f7c0, 0x1f7c8,
+		0x1f840, 0x1f84c,
+		0x1fa40, 0x1fa8c,
+		0x1fac0, 0x1fac0,
+		0x1fae0, 0x1fae0,
+		0x1fb00, 0x1fb84,
+		0x1fbc0, 0x1fbc8,
+		0x1fc40, 0x1fc4c,
+		0x1fe40, 0x1fe8c,
+		0x1fec0, 0x1fec0,
+		0x1fee0, 0x1fee0,
+		0x1ff00, 0x1ff84,
+		0x1ffc0, 0x1ffc8,
+		0x20000, 0x2002c,
+		0x20100, 0x2013c,
+		0x20190, 0x201c8,
+		0x20200, 0x20318,
+		0x20400, 0x20528,
+		0x20540, 0x20614,
+		0x21000, 0x21040,
+		0x2104c, 0x21060,
+		0x210c0, 0x210ec,
+		0x21200, 0x21268,
+		0x21270, 0x21284,
+		0x212fc, 0x21388,
+		0x21400, 0x21404,
+		0x21500, 0x21518,
+		0x2152c, 0x2153c,
+		0x21550, 0x21554,
+		0x21600, 0x21600,
+		0x21608, 0x21628,
+		0x21630, 0x2163c,
+		0x21700, 0x2171c,
+		0x21780, 0x2178c,
+		0x21800, 0x21c38,
+		0x21c80, 0x21d7c,
+		0x21e00, 0x21e04,
+		0x22000, 0x2202c,
+		0x22100, 0x2213c,
+		0x22190, 0x221c8,
+		0x22200, 0x22318,
+		0x22400, 0x22528,
+		0x22540, 0x22614,
+		0x23000, 0x23040,
+		0x2304c, 0x23060,
+		0x230c0, 0x230ec,
+		0x23200, 0x23268,
+		0x23270, 0x23284,
+		0x232fc, 0x23388,
+		0x23400, 0x23404,
+		0x23500, 0x23518,
+		0x2352c, 0x2353c,
+		0x23550, 0x23554,
+		0x23600, 0x23600,
+		0x23608, 0x23628,
+		0x23630, 0x2363c,
+		0x23700, 0x2371c,
+		0x23780, 0x2378c,
+		0x23800, 0x23c38,
+		0x23c80, 0x23d7c,
+		0x23e00, 0x23e04,
+		0x24000, 0x2402c,
+		0x24100, 0x2413c,
+		0x24190, 0x241c8,
+		0x24200, 0x24318,
+		0x24400, 0x24528,
+		0x24540, 0x24614,
+		0x25000, 0x25040,
+		0x2504c, 0x25060,
+		0x250c0, 0x250ec,
+		0x25200, 0x25268,
+		0x25270, 0x25284,
+		0x252fc, 0x25388,
+		0x25400, 0x25404,
+		0x25500, 0x25518,
+		0x2552c, 0x2553c,
+		0x25550, 0x25554,
+		0x25600, 0x25600,
+		0x25608, 0x25628,
+		0x25630, 0x2563c,
+		0x25700, 0x2571c,
+		0x25780, 0x2578c,
+		0x25800, 0x25c38,
+		0x25c80, 0x25d7c,
+		0x25e00, 0x25e04,
+		0x26000, 0x2602c,
+		0x26100, 0x2613c,
+		0x26190, 0x261c8,
+		0x26200, 0x26318,
+		0x26400, 0x26528,
+		0x26540, 0x26614,
+		0x27000, 0x27040,
+		0x2704c, 0x27060,
+		0x270c0, 0x270ec,
+		0x27200, 0x27268,
+		0x27270, 0x27284,
+		0x272fc, 0x27388,
+		0x27400, 0x27404,
+		0x27500, 0x27518,
+		0x2752c, 0x2753c,
+		0x27550, 0x27554,
+		0x27600, 0x27600,
+		0x27608, 0x27628,
+		0x27630, 0x2763c,
+		0x27700, 0x2771c,
+		0x27780, 0x2778c,
+		0x27800, 0x27c38,
+		0x27c80, 0x27d7c,
+		0x27e00, 0x27e04
+	};
+
+	int i;
+	struct adapter *ap = netdev2adap(dev);
+
+	regs->version = mk_adap_vers(ap);
+
+	memset(buf, 0, T4_REGMAP_SIZE);
+	for (i = 0; i < ARRAY_SIZE(reg_ranges); i += 2)
+		reg_block_dump(ap, buf, reg_ranges[i], reg_ranges[i + 1]);
+}
+
+static int restart_autoneg(struct net_device *dev)
+{
+	struct port_info *p = netdev_priv(dev);
+
+	if (!netif_running(dev))
+		return -EAGAIN;
+	if (p->link_cfg.autoneg != AUTONEG_ENABLE)
+		return -EINVAL;
+	t4_restart_aneg(p->adapter, 0, p->tx_chan);
+	return 0;
+}
+
+static int identify_port(struct net_device *dev, u32 data)
+{
+	if (data == 0)
+		data = 2;     /* default to 2 seconds */
+
+	return t4_identify_port(netdev2adap(dev), 0, netdev2pinfo(dev)->viid,
+				data * 5);
+}
+
+static unsigned int from_fw_linkcaps(unsigned int type, unsigned int caps)
+{
+	unsigned int v = 0;
+
+	if (type == FW_PORT_TYPE_BT_SGMII || type == FW_PORT_TYPE_BT_XAUI) {
+		v |= SUPPORTED_TP;
+		if (caps & FW_PORT_CAP_SPEED_100M)
+			v |= SUPPORTED_100baseT_Full;
+		if (caps & FW_PORT_CAP_SPEED_1G)
+			v |= SUPPORTED_1000baseT_Full;
+		if (caps & FW_PORT_CAP_SPEED_10G)
+			v |= SUPPORTED_10000baseT_Full;
+	} else if (type == FW_PORT_TYPE_KX4 || type == FW_PORT_TYPE_KX) {
+		v |= SUPPORTED_Backplane;
+		if (caps & FW_PORT_CAP_SPEED_1G)
+			v |= SUPPORTED_1000baseKX_Full;
+		if (caps & FW_PORT_CAP_SPEED_10G)
+			v |= SUPPORTED_10000baseKX4_Full;
+	} else if (type == FW_PORT_TYPE_KR)
+		v |= SUPPORTED_Backplane | SUPPORTED_10000baseKR_Full;
+	else if (type == FW_PORT_TYPE_FIBER)
+		v |= SUPPORTED_FIBRE;
+
+	if (caps & FW_PORT_CAP_ANEG)
+		v |= SUPPORTED_Autoneg;
+	return v;
+}
+
+static unsigned int to_fw_linkcaps(unsigned int caps)
+{
+	unsigned int v = 0;
+
+	if (caps & ADVERTISED_100baseT_Full)
+		v |= FW_PORT_CAP_SPEED_100M;
+	if (caps & ADVERTISED_1000baseT_Full)
+		v |= FW_PORT_CAP_SPEED_1G;
+	if (caps & ADVERTISED_10000baseT_Full)
+		v |= FW_PORT_CAP_SPEED_10G;
+	return v;
+}
+
+static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	const struct port_info *p = netdev_priv(dev);
+
+	if (p->port_type == FW_PORT_TYPE_BT_SGMII ||
+	    p->port_type == FW_PORT_TYPE_BT_XAUI)
+		cmd->port = PORT_TP;
+	else if (p->port_type == FW_PORT_TYPE_FIBER)
+		cmd->port = PORT_FIBRE;
+	else if (p->port_type == FW_PORT_TYPE_TWINAX)
+		cmd->port = PORT_DA;
+	else
+		cmd->port = PORT_OTHER;
+
+	if (p->mdio_addr >= 0) {
+		cmd->phy_address = p->mdio_addr;
+		cmd->transceiver = XCVR_EXTERNAL;
+		cmd->mdio_support = p->port_type == FW_PORT_TYPE_BT_SGMII ?
+			MDIO_SUPPORTS_C22 : MDIO_SUPPORTS_C45;
+	} else {
+		cmd->phy_address = 0;  /* not really, but no better option */
+		cmd->transceiver = XCVR_INTERNAL;
+		cmd->mdio_support = 0;
+	}
+
+	cmd->supported = from_fw_linkcaps(p->port_type, p->link_cfg.supported);
+	cmd->advertising = from_fw_linkcaps(p->port_type,
+					    p->link_cfg.advertising);
+	cmd->speed = netif_carrier_ok(dev) ? p->link_cfg.speed : 0;
+	cmd->duplex = DUPLEX_FULL;
+	cmd->autoneg = p->link_cfg.autoneg;
+	cmd->maxtxpkt = 0;
+	cmd->maxrxpkt = 0;
+	return 0;
+}
+
+static unsigned int speed_to_caps(int speed)
+{
+	if (speed == SPEED_100)
+		return FW_PORT_CAP_SPEED_100M;
+	if (speed == SPEED_1000)
+		return FW_PORT_CAP_SPEED_1G;
+	if (speed == SPEED_10000)
+		return FW_PORT_CAP_SPEED_10G;
+	return 0;
+}
+
+static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	unsigned int cap;
+	struct port_info *p = netdev_priv(dev);
+	struct link_config *lc = &p->link_cfg;
+
+	if (cmd->duplex != DUPLEX_FULL)     /* only full-duplex supported */
+		return -EINVAL;
+
+	if (!(lc->supported & FW_PORT_CAP_ANEG)) {
+		/*
+		 * PHY offers a single speed.  See if that's what's
+		 * being requested.
+		 */
+		if (cmd->autoneg == AUTONEG_DISABLE &&
+		    (lc->supported & speed_to_caps(cmd->speed)))
+				return 0;
+		return -EINVAL;
+	}
+
+	if (cmd->autoneg == AUTONEG_DISABLE) {
+		cap = speed_to_caps(cmd->speed);
+
+		if (!(lc->supported & cap) || cmd->speed == SPEED_1000 ||
+		    cmd->speed == SPEED_10000)
+			return -EINVAL;
+		lc->requested_speed = cap;
+		lc->advertising = 0;
+	} else {
+		cap = to_fw_linkcaps(cmd->advertising);
+		if (!(lc->supported & cap))
+			return -EINVAL;
+		lc->requested_speed = 0;
+		lc->advertising = cap | FW_PORT_CAP_ANEG;
+	}
+	lc->autoneg = cmd->autoneg;
+
+	if (netif_running(dev))
+		return t4_link_start(p->adapter, 0, p->tx_chan, lc);
+	return 0;
+}
+
+static void get_pauseparam(struct net_device *dev,
+			   struct ethtool_pauseparam *epause)
+{
+	struct port_info *p = netdev_priv(dev);
+
+	epause->autoneg = (p->link_cfg.requested_fc & PAUSE_AUTONEG) != 0;
+	epause->rx_pause = (p->link_cfg.fc & PAUSE_RX) != 0;
+	epause->tx_pause = (p->link_cfg.fc & PAUSE_TX) != 0;
+}
+
+static int set_pauseparam(struct net_device *dev,
+			  struct ethtool_pauseparam *epause)
+{
+	struct port_info *p = netdev_priv(dev);
+	struct link_config *lc = &p->link_cfg;
+
+	if (epause->autoneg == AUTONEG_DISABLE)
+		lc->requested_fc = 0;
+	else if (lc->supported & FW_PORT_CAP_ANEG)
+		lc->requested_fc = PAUSE_AUTONEG;
+	else
+		return -EINVAL;
+
+	if (epause->rx_pause)
+		lc->requested_fc |= PAUSE_RX;
+	if (epause->tx_pause)
+		lc->requested_fc |= PAUSE_TX;
+	if (netif_running(dev))
+		return t4_link_start(p->adapter, 0, p->tx_chan, lc);
+	return 0;
+}
+
+static u32 get_rx_csum(struct net_device *dev)
+{
+	struct port_info *p = netdev_priv(dev);
+
+	return p->rx_offload & RX_CSO;
+}
+
+static int set_rx_csum(struct net_device *dev, u32 data)
+{
+	struct port_info *p = netdev_priv(dev);
+
+	if (data)
+		p->rx_offload |= RX_CSO;
+	else
+		p->rx_offload &= ~RX_CSO;
+	return 0;
+}
+
+static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
+{
+	const struct port_info *pi = netdev_priv(dev);
+	const struct sge *s = &pi->adapter->sge;
+
+	e->rx_max_pending = MAX_RX_BUFFERS;
+	e->rx_mini_max_pending = MAX_RSPQ_ENTRIES;
+	e->rx_jumbo_max_pending = 0;
+	e->tx_max_pending = MAX_TXQ_ENTRIES;
+
+	e->rx_pending = s->ethrxq[pi->first_qset].fl.size - 8;
+	e->rx_mini_pending = s->ethrxq[pi->first_qset].rspq.size;
+	e->rx_jumbo_pending = 0;
+	e->tx_pending = s->ethtxq[pi->first_qset].q.size;
+}
+
+static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
+{
+	int i;
+	const struct port_info *pi = netdev_priv(dev);
+	struct adapter *adapter = pi->adapter;
+	struct sge *s = &adapter->sge;
+
+	if (e->rx_pending > MAX_RX_BUFFERS || e->rx_jumbo_pending ||
+	    e->tx_pending > MAX_TXQ_ENTRIES ||
+	    e->rx_mini_pending > MAX_RSPQ_ENTRIES ||
+	    e->rx_mini_pending < MIN_RSPQ_ENTRIES ||
+	    e->rx_pending < MIN_FL_ENTRIES || e->tx_pending < MIN_TXQ_ENTRIES)
+		return -EINVAL;
+
+	if (adapter->flags & FULL_INIT_DONE)
+		return -EBUSY;
+
+	for (i = 0; i < pi->nqsets; ++i) {
+		s->ethtxq[pi->first_qset + i].q.size = e->tx_pending;
+		s->ethrxq[pi->first_qset + i].fl.size = e->rx_pending + 8;
+		s->ethrxq[pi->first_qset + i].rspq.size = e->rx_mini_pending;
+	}
+	return 0;
+}
+
+static int closest_timer(const struct sge *s, int time)
+{
+	int i, delta, match = 0, min_delta = INT_MAX;
+
+	for (i = 0; i < ARRAY_SIZE(s->timer_val); i++) {
+		delta = time - s->timer_val[i];
+		if (delta < 0)
+			delta = -delta;
+		if (delta < min_delta) {
+			min_delta = delta;
+			match = i;
+		}
+	}
+	return match;
+}
+
+static int closest_thres(const struct sge *s, int thres)
+{
+	int i, delta, match = 0, min_delta = INT_MAX;
+
+	for (i = 0; i < ARRAY_SIZE(s->counter_val); i++) {
+		delta = thres - s->counter_val[i];
+		if (delta < 0)
+			delta = -delta;
+		if (delta < min_delta) {
+			min_delta = delta;
+			match = i;
+		}
+	}
+	return match;
+}
+
+/*
+ * Return a queue's interrupt hold-off time in us.  0 means no timer.
+ */
+static unsigned int qtimer_val(const struct adapter *adap,
+			       const struct sge_rspq *q)
+{
+	unsigned int idx = q->intr_params >> 1;
+
+	return idx < SGE_NTIMERS ? adap->sge.timer_val[idx] : 0;
+}
+
+/**
+ *	set_rxq_intr_params - set a queue's interrupt holdoff parameters
+ *	@adap: the adapter
+ *	@q: the Rx queue
+ *	@us: the hold-off time in us, or 0 to disable timer
+ *	@cnt: the hold-off packet count, or 0 to disable counter
+ *
+ *	Sets an Rx queue's interrupt hold-off time and packet count.  At least
+ *	one of the two needs to be enabled for the queue to generate interrupts.
+ */
+static int set_rxq_intr_params(struct adapter *adap, struct sge_rspq *q,
+			       unsigned int us, unsigned int cnt)
+{
+	if ((us | cnt) == 0)
+		cnt = 1;
+
+	if (cnt) {
+		int err;
+		u32 v, new_idx;
+
+		new_idx = closest_thres(&adap->sge, cnt);
+		if (q->desc && q->pktcnt_idx != new_idx) {
+			/* the queue has already been created, update it */
+			v = FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) |
+			    FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_IQ_INTCNTTHRESH) |
+			    FW_PARAMS_PARAM_YZ(q->cntxt_id);
+			err = t4_set_params(adap, 0, 0, 0, 1, &v, &new_idx);
+			if (err)
+				return err;
+		}
+		q->pktcnt_idx = new_idx;
+	}
+
+	us = us == 0 ? 6 : closest_timer(&adap->sge, us);
+	q->intr_params = QINTR_TIMER_IDX(us) | (cnt > 0 ? QINTR_CNT_EN : 0);
+	return 0;
+}
+
+static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
+{
+	const struct port_info *pi = netdev_priv(dev);
+	struct adapter *adap = pi->adapter;
+
+	return set_rxq_intr_params(adap, &adap->sge.ethrxq[pi->first_qset].rspq,
+			c->rx_coalesce_usecs, c->rx_max_coalesced_frames);
+}
+
+static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
+{
+	const struct port_info *pi = netdev_priv(dev);
+	const struct adapter *adap = pi->adapter;
+	const struct sge_rspq *rq = &adap->sge.ethrxq[pi->first_qset].rspq;
+
+	c->rx_coalesce_usecs = qtimer_val(adap, rq);
+	c->rx_max_coalesced_frames = (rq->intr_params & QINTR_CNT_EN) ?
+		adap->sge.counter_val[rq->pktcnt_idx] : 0;
+	return 0;
+}
+
+/*
+ * Translate a physical EEPROM address to virtual.  The first 1K is accessed
+ * through virtual addresses starting at 31K, the rest is accessed through
+ * virtual addresses starting at 0.  This mapping is correct only for PF0.
+ */
+static int eeprom_ptov(unsigned int phys_addr)
+{
+	if (phys_addr < 1024)
+		return phys_addr + (31 << 10);
+	if (phys_addr < EEPROMSIZE)
+		return phys_addr - 1024;
+	return -EINVAL;
+}
+
+/*
+ * The next two routines implement eeprom read/write from physical addresses.
+ * The physical->virtual translation is correct only for PF0.
+ */
+static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v)
+{
+	int vaddr = eeprom_ptov(phys_addr);
+
+	if (vaddr >= 0)
+		vaddr = pci_read_vpd(adap->pdev, vaddr, sizeof(u32), v);
+	return vaddr < 0 ? vaddr : 0;
+}
+
+static int eeprom_wr_phys(struct adapter *adap, unsigned int phys_addr, u32 v)
+{
+	int vaddr = eeprom_ptov(phys_addr);
+
+	if (vaddr >= 0)
+		vaddr = pci_write_vpd(adap->pdev, vaddr, sizeof(u32), &v);
+	return vaddr < 0 ? vaddr : 0;
+}
+
+#define EEPROM_MAGIC 0x38E2F10C
+
+static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
+		      u8 *data)
+{
+	int i, err = 0;
+	struct adapter *adapter = netdev2adap(dev);
+
+	u8 *buf = kmalloc(EEPROMSIZE, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	e->magic = EEPROM_MAGIC;
+	for (i = e->offset & ~3; !err && i < e->offset + e->len; i += 4)
+		err = eeprom_rd_phys(adapter, i, (u32 *)&buf[i]);
+
+	if (!err)
+		memcpy(data, buf + e->offset, e->len);
+	kfree(buf);
+	return err;
+}
+
+static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+		      u8 *data)
+{
+	u8 *buf;
+	int err = 0;
+	u32 aligned_offset, aligned_len, *p;
+	struct adapter *adapter = netdev2adap(dev);
+
+	if (eeprom->magic != EEPROM_MAGIC)
+		return -EINVAL;
+
+	aligned_offset = eeprom->offset & ~3;
+	aligned_len = (eeprom->len + (eeprom->offset & 3) + 3) & ~3;
+
+	if (aligned_offset != eeprom->offset || aligned_len != eeprom->len) {
+		/*
+		 * RMW possibly needed for first or last words.
+		 */
+		buf = kmalloc(aligned_len, GFP_KERNEL);
+		if (!buf)
+			return -ENOMEM;
+		err = eeprom_rd_phys(adapter, aligned_offset, (u32 *)buf);
+		if (!err && aligned_len > 4)
+			err = eeprom_rd_phys(adapter,
+					     aligned_offset + aligned_len - 4,
+					     (u32 *)&buf[aligned_len - 4]);
+		if (err)
+			goto out;
+		memcpy(buf + (eeprom->offset & 3), data, eeprom->len);
+	} else
+		buf = data;
+
+	err = t4_seeprom_wp(adapter, false);
+	if (err)
+		goto out;
+
+	for (p = (u32 *)buf; !err && aligned_len; aligned_len -= 4, p++) {
+		err = eeprom_wr_phys(adapter, aligned_offset, *p);
+		aligned_offset += 4;
+	}
+
+	if (!err)
+		err = t4_seeprom_wp(adapter, true);
+out:
+	if (buf != data)
+		kfree(buf);
+	return err;
+}
+
+static int set_flash(struct net_device *netdev, struct ethtool_flash *ef)
+{
+	int ret;
+	const struct firmware *fw;
+	struct adapter *adap = netdev2adap(netdev);
+
+	ef->data[sizeof(ef->data) - 1] = '\0';
+	ret = reject_firmware(&fw, ef->data, adap->pdev_dev);
+	if (ret < 0)
+		return ret;
+
+	ret = t4_load_fw(adap, fw->data, fw->size);
+	release_firmware(fw);
+	if (!ret)
+		dev_info(adap->pdev_dev, "loaded firmware %s\n", ef->data);
+	return ret;
+}
+
+#define WOL_SUPPORTED (WAKE_BCAST | WAKE_MAGIC)
+#define BCAST_CRC 0xa0ccc1a6
+
+static void get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	wol->supported = WAKE_BCAST | WAKE_MAGIC;
+	wol->wolopts = netdev2adap(dev)->wol;
+	memset(&wol->sopass, 0, sizeof(wol->sopass));
+}
+
+static int set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	int err = 0;
+	struct port_info *pi = netdev_priv(dev);
+
+	if (wol->wolopts & ~WOL_SUPPORTED)
+		return -EINVAL;
+	t4_wol_magic_enable(pi->adapter, pi->tx_chan,
+			    (wol->wolopts & WAKE_MAGIC) ? dev->dev_addr : NULL);
+	if (wol->wolopts & WAKE_BCAST) {
+		err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0xfe, ~0ULL,
+					~0ULL, 0, false);
+		if (!err)
+			err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 1,
+						~6ULL, ~0ULL, BCAST_CRC, true);
+	} else
+		t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0, 0, 0, 0, false);
+	return err;
+}
+
+static int set_tso(struct net_device *dev, u32 value)
+{
+	if (value)
+		dev->features |= NETIF_F_TSO | NETIF_F_TSO6;
+	else
+		dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+	return 0;
+}
+
+static struct ethtool_ops cxgb_ethtool_ops = {
+	.get_settings      = get_settings,
+	.set_settings      = set_settings,
+	.get_drvinfo       = get_drvinfo,
+	.get_msglevel      = get_msglevel,
+	.set_msglevel      = set_msglevel,
+	.get_ringparam     = get_sge_param,
+	.set_ringparam     = set_sge_param,
+	.get_coalesce      = get_coalesce,
+	.set_coalesce      = set_coalesce,
+	.get_eeprom_len    = get_eeprom_len,
+	.get_eeprom        = get_eeprom,
+	.set_eeprom        = set_eeprom,
+	.get_pauseparam    = get_pauseparam,
+	.set_pauseparam    = set_pauseparam,
+	.get_rx_csum       = get_rx_csum,
+	.set_rx_csum       = set_rx_csum,
+	.set_tx_csum       = ethtool_op_set_tx_ipv6_csum,
+	.set_sg            = ethtool_op_set_sg,
+	.get_link          = ethtool_op_get_link,
+	.get_strings       = get_strings,
+	.phys_id           = identify_port,
+	.nway_reset        = restart_autoneg,
+	.get_sset_count    = get_sset_count,
+	.get_ethtool_stats = get_stats,
+	.get_regs_len      = get_regs_len,
+	.get_regs          = get_regs,
+	.get_wol           = get_wol,
+	.set_wol           = set_wol,
+	.set_tso           = set_tso,
+	.flash_device      = set_flash,
+};
+
+/*
+ * debugfs support
+ */
+
+static int mem_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t mem_read(struct file *file, char __user *buf, size_t count,
+			loff_t *ppos)
+{
+	loff_t pos = *ppos;
+	loff_t avail = file->f_path.dentry->d_inode->i_size;
+	unsigned int mem = (uintptr_t)file->private_data & 3;
+	struct adapter *adap = file->private_data - mem;
+
+	if (pos < 0)
+		return -EINVAL;
+	if (pos >= avail)
+		return 0;
+	if (count > avail - pos)
+		count = avail - pos;
+
+	while (count) {
+		size_t len;
+		int ret, ofst;
+		__be32 data[16];
+
+		if (mem == MEM_MC)
+			ret = t4_mc_read(adap, pos, data, NULL);
+		else
+			ret = t4_edc_read(adap, mem, pos, data, NULL);
+		if (ret)
+			return ret;
+
+		ofst = pos % sizeof(data);
+		len = min(count, sizeof(data) - ofst);
+		if (copy_to_user(buf, (u8 *)data + ofst, len))
+			return -EFAULT;
+
+		buf += len;
+		pos += len;
+		count -= len;
+	}
+	count = pos - *ppos;
+	*ppos = pos;
+	return count;
+}
+
+static const struct file_operations mem_debugfs_fops = {
+	.owner   = THIS_MODULE,
+	.open    = mem_open,
+	.read    = mem_read,
+};
+
+static void __devinit add_debugfs_mem(struct adapter *adap, const char *name,
+				      unsigned int idx, unsigned int size_mb)
+{
+	struct dentry *de;
+
+	de = debugfs_create_file(name, S_IRUSR, adap->debugfs_root,
+				 (void *)adap + idx, &mem_debugfs_fops);
+	if (de && de->d_inode)
+		de->d_inode->i_size = size_mb << 20;
+}
+
+static int __devinit setup_debugfs(struct adapter *adap)
+{
+	int i;
+
+	if (IS_ERR_OR_NULL(adap->debugfs_root))
+		return -1;
+
+	i = t4_read_reg(adap, MA_TARGET_MEM_ENABLE);
+	if (i & EDRAM0_ENABLE)
+		add_debugfs_mem(adap, "edc0", MEM_EDC0, 5);
+	if (i & EDRAM1_ENABLE)
+		add_debugfs_mem(adap, "edc1", MEM_EDC1, 5);
+	if (i & EXT_MEM_ENABLE)
+		add_debugfs_mem(adap, "mc", MEM_MC,
+			EXT_MEM_SIZE_GET(t4_read_reg(adap, MA_EXT_MEMORY_BAR)));
+	if (adap->l2t)
+		debugfs_create_file("l2t", S_IRUSR, adap->debugfs_root, adap,
+				    &t4_l2t_fops);
+	return 0;
+}
+
+/*
+ * upper-layer driver support
+ */
+
+/*
+ * Allocate an active-open TID and set it to the supplied value.
+ */
+int cxgb4_alloc_atid(struct tid_info *t, void *data)
+{
+	int atid = -1;
+
+	spin_lock_bh(&t->atid_lock);
+	if (t->afree) {
+		union aopen_entry *p = t->afree;
+
+		atid = p - t->atid_tab;
+		t->afree = p->next;
+		p->data = data;
+		t->atids_in_use++;
+	}
+	spin_unlock_bh(&t->atid_lock);
+	return atid;
+}
+EXPORT_SYMBOL(cxgb4_alloc_atid);
+
+/*
+ * Release an active-open TID.
+ */
+void cxgb4_free_atid(struct tid_info *t, unsigned int atid)
+{
+	union aopen_entry *p = &t->atid_tab[atid];
+
+	spin_lock_bh(&t->atid_lock);
+	p->next = t->afree;
+	t->afree = p;
+	t->atids_in_use--;
+	spin_unlock_bh(&t->atid_lock);
+}
+EXPORT_SYMBOL(cxgb4_free_atid);
+
+/*
+ * Allocate a server TID and set it to the supplied value.
+ */
+int cxgb4_alloc_stid(struct tid_info *t, int family, void *data)
+{
+	int stid;
+
+	spin_lock_bh(&t->stid_lock);
+	if (family == PF_INET) {
+		stid = find_first_zero_bit(t->stid_bmap, t->nstids);
+		if (stid < t->nstids)
+			__set_bit(stid, t->stid_bmap);
+		else
+			stid = -1;
+	} else {
+		stid = bitmap_find_free_region(t->stid_bmap, t->nstids, 2);
+		if (stid < 0)
+			stid = -1;
+	}
+	if (stid >= 0) {
+		t->stid_tab[stid].data = data;
+		stid += t->stid_base;
+		t->stids_in_use++;
+	}
+	spin_unlock_bh(&t->stid_lock);
+	return stid;
+}
+EXPORT_SYMBOL(cxgb4_alloc_stid);
+
+/*
+ * Release a server TID.
+ */
+void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family)
+{
+	stid -= t->stid_base;
+	spin_lock_bh(&t->stid_lock);
+	if (family == PF_INET)
+		__clear_bit(stid, t->stid_bmap);
+	else
+		bitmap_release_region(t->stid_bmap, stid, 2);
+	t->stid_tab[stid].data = NULL;
+	t->stids_in_use--;
+	spin_unlock_bh(&t->stid_lock);
+}
+EXPORT_SYMBOL(cxgb4_free_stid);
+
+/*
+ * Populate a TID_RELEASE WR.  Caller must properly size the skb.
+ */
+static void mk_tid_release(struct sk_buff *skb, unsigned int chan,
+			   unsigned int tid)
+{
+	struct cpl_tid_release *req;
+
+	set_wr_txq(skb, CPL_PRIORITY_SETUP, chan);
+	req = (struct cpl_tid_release *)__skb_put(skb, sizeof(*req));
+	INIT_TP_WR(req, tid);
+	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, tid));
+}
+
+/*
+ * Queue a TID release request and if necessary schedule a work queue to
+ * process it.
+ */
+void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
+			     unsigned int tid)
+{
+	void **p = &t->tid_tab[tid];
+	struct adapter *adap = container_of(t, struct adapter, tids);
+
+	spin_lock_bh(&adap->tid_release_lock);
+	*p = adap->tid_release_head;
+	/* Low 2 bits encode the Tx channel number */
+	adap->tid_release_head = (void **)((uintptr_t)p | chan);
+	if (!adap->tid_release_task_busy) {
+		adap->tid_release_task_busy = true;
+		schedule_work(&adap->tid_release_task);
+	}
+	spin_unlock_bh(&adap->tid_release_lock);
+}
+EXPORT_SYMBOL(cxgb4_queue_tid_release);
+
+/*
+ * Process the list of pending TID release requests.
+ */
+static void process_tid_release_list(struct work_struct *work)
+{
+	struct sk_buff *skb;
+	struct adapter *adap;
+
+	adap = container_of(work, struct adapter, tid_release_task);
+
+	spin_lock_bh(&adap->tid_release_lock);
+	while (adap->tid_release_head) {
+		void **p = adap->tid_release_head;
+		unsigned int chan = (uintptr_t)p & 3;
+		p = (void *)p - chan;
+
+		adap->tid_release_head = *p;
+		*p = NULL;
+		spin_unlock_bh(&adap->tid_release_lock);
+
+		while (!(skb = alloc_skb(sizeof(struct cpl_tid_release),
+					 GFP_KERNEL)))
+			schedule_timeout_uninterruptible(1);
+
+		mk_tid_release(skb, chan, p - adap->tids.tid_tab);
+		t4_ofld_send(adap, skb);
+		spin_lock_bh(&adap->tid_release_lock);
+	}
+	adap->tid_release_task_busy = false;
+	spin_unlock_bh(&adap->tid_release_lock);
+}
+
+/*
+ * Release a TID and inform HW.  If we are unable to allocate the release
+ * message we defer to a work queue.
+ */
+void cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid)
+{
+	void *old;
+	struct sk_buff *skb;
+	struct adapter *adap = container_of(t, struct adapter, tids);
+
+	old = t->tid_tab[tid];
+	skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_ATOMIC);
+	if (likely(skb)) {
+		t->tid_tab[tid] = NULL;
+		mk_tid_release(skb, chan, tid);
+		t4_ofld_send(adap, skb);
+	} else
+		cxgb4_queue_tid_release(t, chan, tid);
+	if (old)
+		atomic_dec(&t->tids_in_use);
+}
+EXPORT_SYMBOL(cxgb4_remove_tid);
+
+/*
+ * Allocate and initialize the TID tables.  Returns 0 on success.
+ */
+static int tid_init(struct tid_info *t)
+{
+	size_t size;
+	unsigned int natids = t->natids;
+
+	size = t->ntids * sizeof(*t->tid_tab) + natids * sizeof(*t->atid_tab) +
+	       t->nstids * sizeof(*t->stid_tab) +
+	       BITS_TO_LONGS(t->nstids) * sizeof(long);
+	t->tid_tab = t4_alloc_mem(size);
+	if (!t->tid_tab)
+		return -ENOMEM;
+
+	t->atid_tab = (union aopen_entry *)&t->tid_tab[t->ntids];
+	t->stid_tab = (struct serv_entry *)&t->atid_tab[natids];
+	t->stid_bmap = (unsigned long *)&t->stid_tab[t->nstids];
+	spin_lock_init(&t->stid_lock);
+	spin_lock_init(&t->atid_lock);
+
+	t->stids_in_use = 0;
+	t->afree = NULL;
+	t->atids_in_use = 0;
+	atomic_set(&t->tids_in_use, 0);
+
+	/* Setup the free list for atid_tab and clear the stid bitmap. */
+	if (natids) {
+		while (--natids)
+			t->atid_tab[natids - 1].next = &t->atid_tab[natids];
+		t->afree = t->atid_tab;
+	}
+	bitmap_zero(t->stid_bmap, t->nstids);
+	return 0;
+}
+
+/**
+ *	cxgb4_create_server - create an IP server
+ *	@dev: the device
+ *	@stid: the server TID
+ *	@sip: local IP address to bind server to
+ *	@sport: the server's TCP port
+ *	@queue: queue to direct messages from this server to
+ *
+ *	Create an IP server for the given port and address.
+ *	Returns <0 on error and one of the %NET_XMIT_* values on success.
+ */
+int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
+			__be32 sip, __be16 sport, unsigned int queue)
+{
+	unsigned int chan;
+	struct sk_buff *skb;
+	struct adapter *adap;
+	struct cpl_pass_open_req *req;
+
+	skb = alloc_skb(sizeof(*req), GFP_KERNEL);
+	if (!skb)
+		return -ENOMEM;
+
+	adap = netdev2adap(dev);
+	req = (struct cpl_pass_open_req *)__skb_put(skb, sizeof(*req));
+	INIT_TP_WR(req, 0);
+	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ, stid));
+	req->local_port = sport;
+	req->peer_port = htons(0);
+	req->local_ip = sip;
+	req->peer_ip = htonl(0);
+	chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan;
+	req->opt0 = cpu_to_be64(TX_CHAN(chan));
+	req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
+				SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
+	return t4_mgmt_tx(adap, skb);
+}
+EXPORT_SYMBOL(cxgb4_create_server);
+
+/**
+ *	cxgb4_create_server6 - create an IPv6 server
+ *	@dev: the device
+ *	@stid: the server TID
+ *	@sip: local IPv6 address to bind server to
+ *	@sport: the server's TCP port
+ *	@queue: queue to direct messages from this server to
+ *
+ *	Create an IPv6 server for the given port and address.
+ *	Returns <0 on error and one of the %NET_XMIT_* values on success.
+ */
+int cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
+			 const struct in6_addr *sip, __be16 sport,
+			 unsigned int queue)
+{
+	unsigned int chan;
+	struct sk_buff *skb;
+	struct adapter *adap;
+	struct cpl_pass_open_req6 *req;
+
+	skb = alloc_skb(sizeof(*req), GFP_KERNEL);
+	if (!skb)
+		return -ENOMEM;
+
+	adap = netdev2adap(dev);
+	req = (struct cpl_pass_open_req6 *)__skb_put(skb, sizeof(*req));
+	INIT_TP_WR(req, 0);
+	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ6, stid));
+	req->local_port = sport;
+	req->peer_port = htons(0);
+	req->local_ip_hi = *(__be64 *)(sip->s6_addr);
+	req->local_ip_lo = *(__be64 *)(sip->s6_addr + 8);
+	req->peer_ip_hi = cpu_to_be64(0);
+	req->peer_ip_lo = cpu_to_be64(0);
+	chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan;
+	req->opt0 = cpu_to_be64(TX_CHAN(chan));
+	req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
+				SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
+	return t4_mgmt_tx(adap, skb);
+}
+EXPORT_SYMBOL(cxgb4_create_server6);
+
+/**
+ *	cxgb4_best_mtu - find the entry in the MTU table closest to an MTU
+ *	@mtus: the HW MTU table
+ *	@mtu: the target MTU
+ *	@idx: index of selected entry in the MTU table
+ *
+ *	Returns the index and the value in the HW MTU table that is closest to
+ *	but does not exceed @mtu, unless @mtu is smaller than any value in the
+ *	table, in which case that smallest available value is selected.
+ */
+unsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu,
+			    unsigned int *idx)
+{
+	unsigned int i = 0;
+
+	while (i < NMTUS - 1 && mtus[i + 1] <= mtu)
+		++i;
+	if (idx)
+		*idx = i;
+	return mtus[i];
+}
+EXPORT_SYMBOL(cxgb4_best_mtu);
+
+/**
+ *	cxgb4_port_chan - get the HW channel of a port
+ *	@dev: the net device for the port
+ *
+ *	Return the HW Tx channel of the given port.
+ */
+unsigned int cxgb4_port_chan(const struct net_device *dev)
+{
+	return netdev2pinfo(dev)->tx_chan;
+}
+EXPORT_SYMBOL(cxgb4_port_chan);
+
+/**
+ *	cxgb4_port_viid - get the VI id of a port
+ *	@dev: the net device for the port
+ *
+ *	Return the VI id of the given port.
+ */
+unsigned int cxgb4_port_viid(const struct net_device *dev)
+{
+	return netdev2pinfo(dev)->viid;
+}
+EXPORT_SYMBOL(cxgb4_port_viid);
+
+/**
+ *	cxgb4_port_idx - get the index of a port
+ *	@dev: the net device for the port
+ *
+ *	Return the index of the given port.
+ */
+unsigned int cxgb4_port_idx(const struct net_device *dev)
+{
+	return netdev2pinfo(dev)->port_id;
+}
+EXPORT_SYMBOL(cxgb4_port_idx);
+
+/**
+ *	cxgb4_netdev_by_hwid - return the net device of a HW port
+ *	@pdev: identifies the adapter
+ *	@id: the HW port id
+ *
+ *	Return the net device associated with the interface with the given HW
+ *	id.
+ */
+struct net_device *cxgb4_netdev_by_hwid(struct pci_dev *pdev, unsigned int id)
+{
+	const struct adapter *adap = pci_get_drvdata(pdev);
+
+	if (!adap || id >= NCHAN)
+		return NULL;
+	id = adap->chan_map[id];
+	return id < MAX_NPORTS ? adap->port[id] : NULL;
+}
+EXPORT_SYMBOL(cxgb4_netdev_by_hwid);
+
+void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4,
+			 struct tp_tcp_stats *v6)
+{
+	struct adapter *adap = pci_get_drvdata(pdev);
+
+	spin_lock(&adap->stats_lock);
+	t4_tp_get_tcp_stats(adap, v4, v6);
+	spin_unlock(&adap->stats_lock);
+}
+EXPORT_SYMBOL(cxgb4_get_tcp_stats);
+
+void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask,
+		      const unsigned int *pgsz_order)
+{
+	struct adapter *adap = netdev2adap(dev);
+
+	t4_write_reg(adap, ULP_RX_ISCSI_TAGMASK, tag_mask);
+	t4_write_reg(adap, ULP_RX_ISCSI_PSZ, HPZ0(pgsz_order[0]) |
+		     HPZ1(pgsz_order[1]) | HPZ2(pgsz_order[2]) |
+		     HPZ3(pgsz_order[3]));
+}
+EXPORT_SYMBOL(cxgb4_iscsi_init);
+
+static struct pci_driver cxgb4_driver;
+
+static void check_neigh_update(struct neighbour *neigh)
+{
+	const struct device *parent;
+	const struct net_device *netdev = neigh->dev;
+
+	if (netdev->priv_flags & IFF_802_1Q_VLAN)
+		netdev = vlan_dev_real_dev(netdev);
+	parent = netdev->dev.parent;
+	if (parent && parent->driver == &cxgb4_driver.driver)
+		t4_l2t_update(dev_get_drvdata(parent), neigh);
+}
+
+static int netevent_cb(struct notifier_block *nb, unsigned long event,
+		       void *data)
+{
+	switch (event) {
+	case NETEVENT_NEIGH_UPDATE:
+		check_neigh_update(data);
+		break;
+	case NETEVENT_PMTU_UPDATE:
+	case NETEVENT_REDIRECT:
+	default:
+		break;
+	}
+	return 0;
+}
+
+static bool netevent_registered;
+static struct notifier_block cxgb4_netevent_nb = {
+	.notifier_call = netevent_cb
+};
+
+static void uld_attach(struct adapter *adap, unsigned int uld)
+{
+	void *handle;
+	struct cxgb4_lld_info lli;
+
+	lli.pdev = adap->pdev;
+	lli.l2t = adap->l2t;
+	lli.tids = &adap->tids;
+	lli.ports = adap->port;
+	lli.vr = &adap->vres;
+	lli.mtus = adap->params.mtus;
+	if (uld == CXGB4_ULD_RDMA) {
+		lli.rxq_ids = adap->sge.rdma_rxq;
+		lli.nrxq = adap->sge.rdmaqs;
+	} else if (uld == CXGB4_ULD_ISCSI) {
+		lli.rxq_ids = adap->sge.ofld_rxq;
+		lli.nrxq = adap->sge.ofldqsets;
+	}
+	lli.ntxq = adap->sge.ofldqsets;
+	lli.nchan = adap->params.nports;
+	lli.nports = adap->params.nports;
+	lli.wr_cred = adap->params.ofldq_wr_cred;
+	lli.adapter_type = adap->params.rev;
+	lli.iscsi_iolen = MAXRXDATA_GET(t4_read_reg(adap, TP_PARA_REG2));
+	lli.udb_density = 1 << QUEUESPERPAGEPF0_GET(
+			t4_read_reg(adap, SGE_EGRESS_QUEUES_PER_PAGE_PF));
+	lli.ucq_density = 1 << QUEUESPERPAGEPF0_GET(
+			t4_read_reg(adap, SGE_INGRESS_QUEUES_PER_PAGE_PF));
+	lli.gts_reg = adap->regs + MYPF_REG(SGE_PF_GTS);
+	lli.db_reg = adap->regs + MYPF_REG(SGE_PF_KDOORBELL);
+	lli.fw_vers = adap->params.fw_vers;
+
+	handle = ulds[uld].add(&lli);
+	if (IS_ERR(handle)) {
+		dev_warn(adap->pdev_dev,
+			 "could not attach to the %s driver, error %ld\n",
+			 uld_str[uld], PTR_ERR(handle));
+		return;
+	}
+
+	adap->uld_handle[uld] = handle;
+
+	if (!netevent_registered) {
+		register_netevent_notifier(&cxgb4_netevent_nb);
+		netevent_registered = true;
+	}
+}
+
+static void attach_ulds(struct adapter *adap)
+{
+	unsigned int i;
+
+	mutex_lock(&uld_mutex);
+	list_add_tail(&adap->list_node, &adapter_list);
+	for (i = 0; i < CXGB4_ULD_MAX; i++)
+		if (ulds[i].add)
+			uld_attach(adap, i);
+	mutex_unlock(&uld_mutex);
+}
+
+static void detach_ulds(struct adapter *adap)
+{
+	unsigned int i;
+
+	mutex_lock(&uld_mutex);
+	list_del(&adap->list_node);
+	for (i = 0; i < CXGB4_ULD_MAX; i++)
+		if (adap->uld_handle[i]) {
+			ulds[i].state_change(adap->uld_handle[i],
+					     CXGB4_STATE_DETACH);
+			adap->uld_handle[i] = NULL;
+		}
+	if (netevent_registered && list_empty(&adapter_list)) {
+		unregister_netevent_notifier(&cxgb4_netevent_nb);
+		netevent_registered = false;
+	}
+	mutex_unlock(&uld_mutex);
+}
+
+static void notify_ulds(struct adapter *adap, enum cxgb4_state new_state)
+{
+	unsigned int i;
+
+	mutex_lock(&uld_mutex);
+	for (i = 0; i < CXGB4_ULD_MAX; i++)
+		if (adap->uld_handle[i])
+			ulds[i].state_change(adap->uld_handle[i], new_state);
+	mutex_unlock(&uld_mutex);
+}
+
+/**
+ *	cxgb4_register_uld - register an upper-layer driver
+ *	@type: the ULD type
+ *	@p: the ULD methods
+ *
+ *	Registers an upper-layer driver with this driver and notifies the ULD
+ *	about any presently available devices that support its type.  Returns
+ *	%-EBUSY if a ULD of the same type is already registered.
+ */
+int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p)
+{
+	int ret = 0;
+	struct adapter *adap;
+
+	if (type >= CXGB4_ULD_MAX)
+		return -EINVAL;
+	mutex_lock(&uld_mutex);
+	if (ulds[type].add) {
+		ret = -EBUSY;
+		goto out;
+	}
+	ulds[type] = *p;
+	list_for_each_entry(adap, &adapter_list, list_node)
+		uld_attach(adap, type);
+out:	mutex_unlock(&uld_mutex);
+	return ret;
+}
+EXPORT_SYMBOL(cxgb4_register_uld);
+
+/**
+ *	cxgb4_unregister_uld - unregister an upper-layer driver
+ *	@type: the ULD type
+ *
+ *	Unregisters an existing upper-layer driver.
+ */
+int cxgb4_unregister_uld(enum cxgb4_uld type)
+{
+	struct adapter *adap;
+
+	if (type >= CXGB4_ULD_MAX)
+		return -EINVAL;
+	mutex_lock(&uld_mutex);
+	list_for_each_entry(adap, &adapter_list, list_node)
+		adap->uld_handle[type] = NULL;
+	ulds[type].add = NULL;
+	mutex_unlock(&uld_mutex);
+	return 0;
+}
+EXPORT_SYMBOL(cxgb4_unregister_uld);
+
+/**
+ *	cxgb_up - enable the adapter
+ *	@adap: adapter being enabled
+ *
+ *	Called when the first port is enabled, this function performs the
+ *	actions necessary to make an adapter operational, such as completing
+ *	the initialization of HW modules, and enabling interrupts.
+ *
+ *	Must be called with the rtnl lock held.
+ */
+static int cxgb_up(struct adapter *adap)
+{
+	int err = 0;
+
+	if (!(adap->flags & FULL_INIT_DONE)) {
+		err = setup_sge_queues(adap);
+		if (err)
+			goto out;
+		err = setup_rss(adap);
+		if (err) {
+			t4_free_sge_resources(adap);
+			goto out;
+		}
+		if (adap->flags & USING_MSIX)
+			name_msix_vecs(adap);
+		adap->flags |= FULL_INIT_DONE;
+	}
+
+	if (adap->flags & USING_MSIX) {
+		err = request_irq(adap->msix_info[0].vec, t4_nondata_intr, 0,
+				  adap->msix_info[0].desc, adap);
+		if (err)
+			goto irq_err;
+
+		err = request_msix_queue_irqs(adap);
+		if (err) {
+			free_irq(adap->msix_info[0].vec, adap);
+			goto irq_err;
+		}
+	} else {
+		err = request_irq(adap->pdev->irq, t4_intr_handler(adap),
+				  (adap->flags & USING_MSI) ? 0 : IRQF_SHARED,
+				  adap->name, adap);
+		if (err)
+			goto irq_err;
+	}
+	enable_rx(adap);
+	t4_sge_start(adap);
+	t4_intr_enable(adap);
+	notify_ulds(adap, CXGB4_STATE_UP);
+ out:
+	return err;
+ irq_err:
+	dev_err(adap->pdev_dev, "request_irq failed, err %d\n", err);
+	goto out;
+}
+
+static void cxgb_down(struct adapter *adapter)
+{
+	t4_intr_disable(adapter);
+	cancel_work_sync(&adapter->tid_release_task);
+	adapter->tid_release_task_busy = false;
+
+	if (adapter->flags & USING_MSIX) {
+		free_msix_queue_irqs(adapter);
+		free_irq(adapter->msix_info[0].vec, adapter);
+	} else
+		free_irq(adapter->pdev->irq, adapter);
+	quiesce_rx(adapter);
+}
+
+/*
+ * net_device operations
+ */
+static int cxgb_open(struct net_device *dev)
+{
+	int err;
+	struct port_info *pi = netdev_priv(dev);
+	struct adapter *adapter = pi->adapter;
+
+	if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0)
+		return err;
+
+	dev->real_num_tx_queues = pi->nqsets;
+	set_bit(pi->tx_chan, &adapter->open_device_map);
+	link_start(dev);
+	netif_tx_start_all_queues(dev);
+	return 0;
+}
+
+static int cxgb_close(struct net_device *dev)
+{
+	int ret;
+	struct port_info *pi = netdev_priv(dev);
+	struct adapter *adapter = pi->adapter;
+
+	netif_tx_stop_all_queues(dev);
+	netif_carrier_off(dev);
+	ret = t4_enable_vi(adapter, 0, pi->viid, false, false);
+
+	clear_bit(pi->tx_chan, &adapter->open_device_map);
+
+	if (!adapter->open_device_map)
+		cxgb_down(adapter);
+	return 0;
+}
+
+static struct net_device_stats *cxgb_get_stats(struct net_device *dev)
+{
+	struct port_stats stats;
+	struct port_info *p = netdev_priv(dev);
+	struct adapter *adapter = p->adapter;
+	struct net_device_stats *ns = &dev->stats;
+
+	spin_lock(&adapter->stats_lock);
+	t4_get_port_stats(adapter, p->tx_chan, &stats);
+	spin_unlock(&adapter->stats_lock);
+
+	ns->tx_bytes   = stats.tx_octets;
+	ns->tx_packets = stats.tx_frames;
+	ns->rx_bytes   = stats.rx_octets;
+	ns->rx_packets = stats.rx_frames;
+	ns->multicast  = stats.rx_mcast_frames;
+
+	/* detailed rx_errors */
+	ns->rx_length_errors = stats.rx_jabber + stats.rx_too_long +
+			       stats.rx_runt;
+	ns->rx_over_errors   = 0;
+	ns->rx_crc_errors    = stats.rx_fcs_err;
+	ns->rx_frame_errors  = stats.rx_symbol_err;
+	ns->rx_fifo_errors   = stats.rx_ovflow0 + stats.rx_ovflow1 +
+			       stats.rx_ovflow2 + stats.rx_ovflow3 +
+			       stats.rx_trunc0 + stats.rx_trunc1 +
+			       stats.rx_trunc2 + stats.rx_trunc3;
+	ns->rx_missed_errors = 0;
+
+	/* detailed tx_errors */
+	ns->tx_aborted_errors   = 0;
+	ns->tx_carrier_errors   = 0;
+	ns->tx_fifo_errors      = 0;
+	ns->tx_heartbeat_errors = 0;
+	ns->tx_window_errors    = 0;
+
+	ns->tx_errors = stats.tx_error_frames;
+	ns->rx_errors = stats.rx_symbol_err + stats.rx_fcs_err +
+		ns->rx_length_errors + stats.rx_len_err + ns->rx_fifo_errors;
+	return ns;
+}
+
+static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+	int ret = 0, prtad, devad;
+	struct port_info *pi = netdev_priv(dev);
+	struct mii_ioctl_data *data = (struct mii_ioctl_data *)&req->ifr_data;
+
+	switch (cmd) {
+	case SIOCGMIIPHY:
+		if (pi->mdio_addr < 0)
+			return -EOPNOTSUPP;
+		data->phy_id = pi->mdio_addr;
+		break;
+	case SIOCGMIIREG:
+	case SIOCSMIIREG:
+		if (mdio_phy_id_is_c45(data->phy_id)) {
+			prtad = mdio_phy_id_prtad(data->phy_id);
+			devad = mdio_phy_id_devad(data->phy_id);
+		} else if (data->phy_id < 32) {
+			prtad = data->phy_id;
+			devad = 0;
+			data->reg_num &= 0x1f;
+		} else
+			return -EINVAL;
+
+		if (cmd == SIOCGMIIREG)
+			ret = t4_mdio_rd(pi->adapter, 0, prtad, devad,
+					 data->reg_num, &data->val_out);
+		else
+			ret = t4_mdio_wr(pi->adapter, 0, prtad, devad,
+					 data->reg_num, data->val_in);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+	return ret;
+}
+
+static void cxgb_set_rxmode(struct net_device *dev)
+{
+	/* unfortunately we can't return errors to the stack */
+	set_rxmode(dev, -1, false);
+}
+
+static int cxgb_change_mtu(struct net_device *dev, int new_mtu)
+{
+	int ret;
+	struct port_info *pi = netdev_priv(dev);
+
+	if (new_mtu < 81 || new_mtu > MAX_MTU)         /* accommodate SACK */
+		return -EINVAL;
+	ret = t4_set_rxmode(pi->adapter, 0, pi->viid, new_mtu, -1, -1, -1,
+			    true);
+	if (!ret)
+		dev->mtu = new_mtu;
+	return ret;
+}
+
+static int cxgb_set_mac_addr(struct net_device *dev, void *p)
+{
+	int ret;
+	struct sockaddr *addr = p;
+	struct port_info *pi = netdev_priv(dev);
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EINVAL;
+
+	ret = t4_change_mac(pi->adapter, 0, pi->viid, pi->xact_addr_filt,
+			    addr->sa_data, true, true);
+	if (ret < 0)
+		return ret;
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+	pi->xact_addr_filt = ret;
+	return 0;
+}
+
+static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+{
+	struct port_info *pi = netdev_priv(dev);
+
+	pi->vlan_grp = grp;
+	t4_set_vlan_accel(pi->adapter, 1 << pi->tx_chan, grp != NULL);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void cxgb_netpoll(struct net_device *dev)
+{
+	struct port_info *pi = netdev_priv(dev);
+	struct adapter *adap = pi->adapter;
+
+	if (adap->flags & USING_MSIX) {
+		int i;
+		struct sge_eth_rxq *rx = &adap->sge.ethrxq[pi->first_qset];
+
+		for (i = pi->nqsets; i; i--, rx++)
+			t4_sge_intr_msix(0, &rx->rspq);
+	} else
+		t4_intr_handler(adap)(0, adap);
+}
+#endif
+
+static const struct net_device_ops cxgb4_netdev_ops = {
+	.ndo_open             = cxgb_open,
+	.ndo_stop             = cxgb_close,
+	.ndo_start_xmit       = t4_eth_xmit,
+	.ndo_get_stats        = cxgb_get_stats,
+	.ndo_set_rx_mode      = cxgb_set_rxmode,
+	.ndo_set_mac_address  = cxgb_set_mac_addr,
+	.ndo_validate_addr    = eth_validate_addr,
+	.ndo_do_ioctl         = cxgb_ioctl,
+	.ndo_change_mtu       = cxgb_change_mtu,
+	.ndo_vlan_rx_register = vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller  = cxgb_netpoll,
+#endif
+};
+
+void t4_fatal_err(struct adapter *adap)
+{
+	t4_set_reg_field(adap, SGE_CONTROL, GLOBALENABLE, 0);
+	t4_intr_disable(adap);
+	dev_alert(adap->pdev_dev, "encountered fatal error, adapter stopped\n");
+}
+
+static void setup_memwin(struct adapter *adap)
+{
+	u32 bar0;
+
+	bar0 = pci_resource_start(adap->pdev, 0);  /* truncation intentional */
+	t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 0),
+		     (bar0 + MEMWIN0_BASE) | BIR(0) |
+		     WINDOW(ilog2(MEMWIN0_APERTURE) - 10));
+	t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 1),
+		     (bar0 + MEMWIN1_BASE) | BIR(0) |
+		     WINDOW(ilog2(MEMWIN1_APERTURE) - 10));
+	t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2),
+		     (bar0 + MEMWIN2_BASE) | BIR(0) |
+		     WINDOW(ilog2(MEMWIN2_APERTURE) - 10));
+}
+
+/*
+ * Max # of ATIDs.  The absolute HW max is 16K but we keep it lower.
+ */
+#define MAX_ATIDS 8192U
+
+/*
+ * Phase 0 of initialization: contact FW, obtain config, perform basic init.
+ */
+static int adap_init0(struct adapter *adap)
+{
+	int ret;
+	u32 v, port_vec;
+	enum dev_state state;
+	u32 params[7], val[7];
+	struct fw_caps_config_cmd c;
+
+	ret = t4_check_fw_version(adap);
+	if (ret == -EINVAL || ret > 0) {
+		if (upgrade_fw(adap) >= 0)             /* recache FW version */
+			ret = t4_check_fw_version(adap);
+	}
+	if (ret < 0)
+		return ret;
+
+	/* contact FW, request master */
+	ret = t4_fw_hello(adap, 0, 0, MASTER_MUST, &state);
+	if (ret < 0) {
+		dev_err(adap->pdev_dev, "could not connect to FW, error %d\n",
+			ret);
+		return ret;
+	}
+
+	/* reset device */
+	ret = t4_fw_reset(adap, 0, PIORSTMODE | PIORST);
+	if (ret < 0)
+		goto bye;
+
+	/* get device capabilities */
+	memset(&c, 0, sizeof(c));
+	c.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
+			      FW_CMD_REQUEST | FW_CMD_READ);
+	c.retval_len16 = htonl(FW_LEN16(c));
+	ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
+	if (ret < 0)
+		goto bye;
+
+	/* select capabilities we'll be using */
+	if (c.niccaps & htons(FW_CAPS_CONFIG_NIC_VM)) {
+		if (!vf_acls)
+			c.niccaps ^= htons(FW_CAPS_CONFIG_NIC_VM);
+		else
+			c.niccaps = htons(FW_CAPS_CONFIG_NIC_VM);
+	} else if (vf_acls) {
+		dev_err(adap->pdev_dev, "virtualization ACLs not supported");
+		goto bye;
+	}
+	c.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
+			      FW_CMD_REQUEST | FW_CMD_WRITE);
+	ret = t4_wr_mbox(adap, 0, &c, sizeof(c), NULL);
+	if (ret < 0)
+		goto bye;
+
+	ret = t4_config_glbl_rss(adap, 0,
+				 FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL,
+				 FW_RSS_GLB_CONFIG_CMD_TNLMAPEN |
+				 FW_RSS_GLB_CONFIG_CMD_TNLALLLKP);
+	if (ret < 0)
+		goto bye;
+
+	ret = t4_cfg_pfvf(adap, 0, 0, 0, 64, 64, 64, 0, 0, 4, 0xf, 0xf, 16,
+			  FW_CMD_CAP_PF, FW_CMD_CAP_PF);
+	if (ret < 0)
+		goto bye;
+
+	for (v = 0; v < SGE_NTIMERS - 1; v++)
+		adap->sge.timer_val[v] = min(intr_holdoff[v], MAX_SGE_TIMERVAL);
+	adap->sge.timer_val[SGE_NTIMERS - 1] = MAX_SGE_TIMERVAL;
+	adap->sge.counter_val[0] = 1;
+	for (v = 1; v < SGE_NCOUNTERS; v++)
+		adap->sge.counter_val[v] = min(intr_cnt[v - 1],
+					       THRESHOLD_3_MASK);
+	t4_sge_init(adap);
+
+	/* get basic stuff going */
+	ret = t4_early_init(adap, 0);
+	if (ret < 0)
+		goto bye;
+
+#define FW_PARAM_DEV(param) \
+	(FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | \
+	 FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param))
+
+#define FW_PARAM_PFVF(param) \
+	(FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \
+	 FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param))
+
+	params[0] = FW_PARAM_DEV(PORTVEC);
+	params[1] = FW_PARAM_PFVF(L2T_START);
+	params[2] = FW_PARAM_PFVF(L2T_END);
+	params[3] = FW_PARAM_PFVF(FILTER_START);
+	params[4] = FW_PARAM_PFVF(FILTER_END);
+	ret = t4_query_params(adap, 0, 0, 0, 5, params, val);
+	if (ret < 0)
+		goto bye;
+	port_vec = val[0];
+	adap->tids.ftid_base = val[3];
+	adap->tids.nftids = val[4] - val[3] + 1;
+
+	if (c.ofldcaps) {
+		/* query offload-related parameters */
+		params[0] = FW_PARAM_DEV(NTID);
+		params[1] = FW_PARAM_PFVF(SERVER_START);
+		params[2] = FW_PARAM_PFVF(SERVER_END);
+		params[3] = FW_PARAM_PFVF(TDDP_START);
+		params[4] = FW_PARAM_PFVF(TDDP_END);
+		params[5] = FW_PARAM_DEV(FLOWC_BUFFIFO_SZ);
+		ret = t4_query_params(adap, 0, 0, 0, 6, params, val);
+		if (ret < 0)
+			goto bye;
+		adap->tids.ntids = val[0];
+		adap->tids.natids = min(adap->tids.ntids / 2, MAX_ATIDS);
+		adap->tids.stid_base = val[1];
+		adap->tids.nstids = val[2] - val[1] + 1;
+		adap->vres.ddp.start = val[3];
+		adap->vres.ddp.size = val[4] - val[3] + 1;
+		adap->params.ofldq_wr_cred = val[5];
+		adap->params.offload = 1;
+	}
+	if (c.rdmacaps) {
+		params[0] = FW_PARAM_PFVF(STAG_START);
+		params[1] = FW_PARAM_PFVF(STAG_END);
+		params[2] = FW_PARAM_PFVF(RQ_START);
+		params[3] = FW_PARAM_PFVF(RQ_END);
+		params[4] = FW_PARAM_PFVF(PBL_START);
+		params[5] = FW_PARAM_PFVF(PBL_END);
+		ret = t4_query_params(adap, 0, 0, 0, 6, params, val);
+		if (ret < 0)
+			goto bye;
+		adap->vres.stag.start = val[0];
+		adap->vres.stag.size = val[1] - val[0] + 1;
+		adap->vres.rq.start = val[2];
+		adap->vres.rq.size = val[3] - val[2] + 1;
+		adap->vres.pbl.start = val[4];
+		adap->vres.pbl.size = val[5] - val[4] + 1;
+	}
+	if (c.iscsicaps) {
+		params[0] = FW_PARAM_PFVF(ISCSI_START);
+		params[1] = FW_PARAM_PFVF(ISCSI_END);
+		ret = t4_query_params(adap, 0, 0, 0, 2, params, val);
+		if (ret < 0)
+			goto bye;
+		adap->vres.iscsi.start = val[0];
+		adap->vres.iscsi.size = val[1] - val[0] + 1;
+	}
+#undef FW_PARAM_PFVF
+#undef FW_PARAM_DEV
+
+	adap->params.nports = hweight32(port_vec);
+	adap->params.portvec = port_vec;
+	adap->flags |= FW_OK;
+
+	/* These are finalized by FW initialization, load their values now */
+	v = t4_read_reg(adap, TP_TIMER_RESOLUTION);
+	adap->params.tp.tre = TIMERRESOLUTION_GET(v);
+	t4_read_mtu_tbl(adap, adap->params.mtus, NULL);
+	t4_load_mtus(adap, adap->params.mtus, adap->params.a_wnd,
+		     adap->params.b_wnd);
+
+	/* tweak some settings */
+	t4_write_reg(adap, TP_SHIFT_CNT, 0x64f8849);
+	t4_write_reg(adap, ULP_RX_TDDP_PSZ, HPZ0(PAGE_SHIFT - 12));
+	t4_write_reg(adap, TP_PIO_ADDR, TP_INGRESS_CONFIG);
+	v = t4_read_reg(adap, TP_PIO_DATA);
+	t4_write_reg(adap, TP_PIO_DATA, v & ~CSUM_HAS_PSEUDO_HDR);
+	setup_memwin(adap);
+	return 0;
+
+	/*
+	 * If a command timed out or failed with EIO FW does not operate within
+	 * its spec or something catastrophic happened to HW/FW, stop issuing
+	 * commands.
+	 */
+bye:	if (ret != -ETIMEDOUT && ret != -EIO)
+		t4_fw_bye(adap, 0);
+	return ret;
+}
+
+static inline bool is_10g_port(const struct link_config *lc)
+{
+	return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0;
+}
+
+static inline void init_rspq(struct sge_rspq *q, u8 timer_idx, u8 pkt_cnt_idx,
+			     unsigned int size, unsigned int iqe_size)
+{
+	q->intr_params = QINTR_TIMER_IDX(timer_idx) |
+			 (pkt_cnt_idx < SGE_NCOUNTERS ? QINTR_CNT_EN : 0);
+	q->pktcnt_idx = pkt_cnt_idx < SGE_NCOUNTERS ? pkt_cnt_idx : 0;
+	q->iqe_len = iqe_size;
+	q->size = size;
+}
+
+/*
+ * Perform default configuration of DMA queues depending on the number and type
+ * of ports we found and the number of available CPUs.  Most settings can be
+ * modified by the admin prior to actual use.
+ */
+static void __devinit cfg_queues(struct adapter *adap)
+{
+	struct sge *s = &adap->sge;
+	int i, q10g = 0, n10g = 0, qidx = 0;
+
+	for_each_port(adap, i)
+		n10g += is_10g_port(&adap2pinfo(adap, i)->link_cfg);
+
+	/*
+	 * We default to 1 queue per non-10G port and up to # of cores queues
+	 * per 10G port.
+	 */
+	if (n10g)
+		q10g = (MAX_ETH_QSETS - (adap->params.nports - n10g)) / n10g;
+	if (q10g > num_online_cpus())
+		q10g = num_online_cpus();
+
+	for_each_port(adap, i) {
+		struct port_info *pi = adap2pinfo(adap, i);
+
+		pi->first_qset = qidx;
+		pi->nqsets = is_10g_port(&pi->link_cfg) ? q10g : 1;
+		qidx += pi->nqsets;
+	}
+
+	s->ethqsets = qidx;
+	s->max_ethqsets = qidx;   /* MSI-X may lower it later */
+
+	if (is_offload(adap)) {
+		/*
+		 * For offload we use 1 queue/channel if all ports are up to 1G,
+		 * otherwise we divide all available queues amongst the channels
+		 * capped by the number of available cores.
+		 */
+		if (n10g) {
+			i = min_t(int, ARRAY_SIZE(s->ofldrxq),
+				  num_online_cpus());
+			s->ofldqsets = roundup(i, adap->params.nports);
+		} else
+			s->ofldqsets = adap->params.nports;
+		/* For RDMA one Rx queue per channel suffices */
+		s->rdmaqs = adap->params.nports;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(s->ethrxq); i++) {
+		struct sge_eth_rxq *r = &s->ethrxq[i];
+
+		init_rspq(&r->rspq, 0, 0, 1024, 64);
+		r->fl.size = 72;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(s->ethtxq); i++)
+		s->ethtxq[i].q.size = 1024;
+
+	for (i = 0; i < ARRAY_SIZE(s->ctrlq); i++)
+		s->ctrlq[i].q.size = 512;
+
+	for (i = 0; i < ARRAY_SIZE(s->ofldtxq); i++)
+		s->ofldtxq[i].q.size = 1024;
+
+	for (i = 0; i < ARRAY_SIZE(s->ofldrxq); i++) {
+		struct sge_ofld_rxq *r = &s->ofldrxq[i];
+
+		init_rspq(&r->rspq, 0, 0, 1024, 64);
+		r->rspq.uld = CXGB4_ULD_ISCSI;
+		r->fl.size = 72;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(s->rdmarxq); i++) {
+		struct sge_ofld_rxq *r = &s->rdmarxq[i];
+
+		init_rspq(&r->rspq, 0, 0, 511, 64);
+		r->rspq.uld = CXGB4_ULD_RDMA;
+		r->fl.size = 72;
+	}
+
+	init_rspq(&s->fw_evtq, 6, 0, 512, 64);
+	init_rspq(&s->intrq, 6, 0, 2 * MAX_INGQ, 64);
+}
+
+/*
+ * Reduce the number of Ethernet queues across all ports to at most n.
+ * n provides at least one queue per port.
+ */
+static void __devinit reduce_ethqs(struct adapter *adap, int n)
+{
+	int i;
+	struct port_info *pi;
+
+	while (n < adap->sge.ethqsets)
+		for_each_port(adap, i) {
+			pi = adap2pinfo(adap, i);
+			if (pi->nqsets > 1) {
+				pi->nqsets--;
+				adap->sge.ethqsets--;
+				if (adap->sge.ethqsets <= n)
+					break;
+			}
+		}
+
+	n = 0;
+	for_each_port(adap, i) {
+		pi = adap2pinfo(adap, i);
+		pi->first_qset = n;
+		n += pi->nqsets;
+	}
+}
+
+/* 2 MSI-X vectors needed for the FW queue and non-data interrupts */
+#define EXTRA_VECS 2
+
+static int __devinit enable_msix(struct adapter *adap)
+{
+	int ofld_need = 0;
+	int i, err, want, need;
+	struct sge *s = &adap->sge;
+	unsigned int nchan = adap->params.nports;
+	struct msix_entry entries[MAX_INGQ + 1];
+
+	for (i = 0; i < ARRAY_SIZE(entries); ++i)
+		entries[i].entry = i;
+
+	want = s->max_ethqsets + EXTRA_VECS;
+	if (is_offload(adap)) {
+		want += s->rdmaqs + s->ofldqsets;
+		/* need nchan for each possible ULD */
+		ofld_need = 2 * nchan;
+	}
+	need = adap->params.nports + EXTRA_VECS + ofld_need;
+
+	while ((err = pci_enable_msix(adap->pdev, entries, want)) >= need)
+		want = err;
+
+	if (!err) {
+		/*
+		 * Distribute available vectors to the various queue groups.
+		 * Every group gets its minimum requirement and NIC gets top
+		 * priority for leftovers.
+		 */
+		i = want - EXTRA_VECS - ofld_need;
+		if (i < s->max_ethqsets) {
+			s->max_ethqsets = i;
+			if (i < s->ethqsets)
+				reduce_ethqs(adap, i);
+		}
+		if (is_offload(adap)) {
+			i = want - EXTRA_VECS - s->max_ethqsets;
+			i -= ofld_need - nchan;
+			s->ofldqsets = (i / nchan) * nchan;  /* round down */
+		}
+		for (i = 0; i < want; ++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);
+	return err;
+}
+
+#undef EXTRA_VECS
+
+static void __devinit print_port_info(struct adapter *adap)
+{
+	static const char *base[] = {
+		"R", "KX4", "T", "KX", "T", "KR", "CX4"
+	};
+
+	int i;
+	char buf[80];
+
+	for_each_port(adap, i) {
+		struct net_device *dev = adap->port[i];
+		const struct port_info *pi = netdev_priv(dev);
+		char *bufp = buf;
+
+		if (!test_bit(i, &adap->registered_device_map))
+			continue;
+
+		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100M)
+			bufp += sprintf(bufp, "100/");
+		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G)
+			bufp += sprintf(bufp, "1000/");
+		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G)
+			bufp += sprintf(bufp, "10G/");
+		if (bufp != buf)
+			--bufp;
+		sprintf(bufp, "BASE-%s", base[pi->port_type]);
+
+		netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s\n",
+			    adap->params.vpd.id, adap->params.rev,
+			    buf, is_offload(adap) ? "R" : "",
+			    adap->params.pci.width,
+			    (adap->flags & USING_MSIX) ? " MSI-X" :
+			    (adap->flags & USING_MSI) ? " MSI" : "");
+		if (adap->name == dev->name)
+			netdev_info(dev, "S/N: %s, E/C: %s\n",
+				    adap->params.vpd.sn, adap->params.vpd.ec);
+	}
+}
+
+#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | NETIF_F_TSO6 |\
+		   NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA)
+
+static int __devinit init_one(struct pci_dev *pdev,
+			      const struct pci_device_id *ent)
+{
+	int func, i, err;
+	struct port_info *pi;
+	unsigned int highdma = 0;
+	struct adapter *adapter = NULL;
+
+	printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION);
+
+	err = pci_request_regions(pdev, KBUILD_MODNAME);
+	if (err) {
+		/* Just info, some other driver may have claimed the device. */
+		dev_info(&pdev->dev, "cannot obtain PCI resources\n");
+		return err;
+	}
+
+	/* We control everything through PF 0 */
+	func = PCI_FUNC(pdev->devfn);
+	if (func > 0)
+		goto sriov;
+
+	err = pci_enable_device(pdev);
+	if (err) {
+		dev_err(&pdev->dev, "cannot enable PCI device\n");
+		goto out_release_regions;
+	}
+
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+		highdma = NETIF_F_HIGHDMA;
+		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 {
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+		if (err) {
+			dev_err(&pdev->dev, "no usable DMA configuration\n");
+			goto out_disable_device;
+		}
+	}
+
+	pci_enable_pcie_error_reporting(pdev);
+	pci_set_master(pdev);
+	pci_save_state(pdev);
+
+	adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
+	if (!adapter) {
+		err = -ENOMEM;
+		goto out_disable_device;
+	}
+
+	adapter->regs = pci_ioremap_bar(pdev, 0);
+	if (!adapter->regs) {
+		dev_err(&pdev->dev, "cannot map device registers\n");
+		err = -ENOMEM;
+		goto out_free_adapter;
+	}
+
+	adapter->pdev = pdev;
+	adapter->pdev_dev = &pdev->dev;
+	adapter->name = pci_name(pdev);
+	adapter->msg_enable = dflt_msg_enable;
+	memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map));
+
+	spin_lock_init(&adapter->stats_lock);
+	spin_lock_init(&adapter->tid_release_lock);
+
+	INIT_WORK(&adapter->tid_release_task, process_tid_release_list);
+
+	err = t4_prep_adapter(adapter);
+	if (err)
+		goto out_unmap_bar;
+	err = adap_init0(adapter);
+	if (err)
+		goto out_unmap_bar;
+
+	for_each_port(adapter, i) {
+		struct net_device *netdev;
+
+		netdev = alloc_etherdev_mq(sizeof(struct port_info),
+					   MAX_ETH_QSETS);
+		if (!netdev) {
+			err = -ENOMEM;
+			goto out_free_dev;
+		}
+
+		SET_NETDEV_DEV(netdev, &pdev->dev);
+
+		adapter->port[i] = netdev;
+		pi = netdev_priv(netdev);
+		pi->adapter = adapter;
+		pi->xact_addr_filt = -1;
+		pi->rx_offload = RX_CSO;
+		pi->port_id = i;
+		netif_carrier_off(netdev);
+		netif_tx_stop_all_queues(netdev);
+		netdev->irq = pdev->irq;
+
+		netdev->features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6;
+		netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+		netdev->features |= NETIF_F_GRO | highdma;
+		netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+		netdev->vlan_features = netdev->features & VLAN_FEAT;
+
+		netdev->netdev_ops = &cxgb4_netdev_ops;
+		SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
+	}
+
+	pci_set_drvdata(pdev, adapter);
+
+	if (adapter->flags & FW_OK) {
+		err = t4_port_init(adapter, 0, 0, 0);
+		if (err)
+			goto out_free_dev;
+	}
+
+	/*
+	 * Configure queues and allocate tables now, they can be needed as
+	 * soon as the first register_netdev completes.
+	 */
+	cfg_queues(adapter);
+
+	adapter->l2t = t4_init_l2t();
+	if (!adapter->l2t) {
+		/* We tolerate a lack of L2T, giving up some functionality */
+		dev_warn(&pdev->dev, "could not allocate L2T, continuing\n");
+		adapter->params.offload = 0;
+	}
+
+	if (is_offload(adapter) && tid_init(&adapter->tids) < 0) {
+		dev_warn(&pdev->dev, "could not allocate TID table, "
+			 "continuing\n");
+		adapter->params.offload = 0;
+	}
+
+	/*
+	 * The card is now ready to go.  If any errors occur during device
+	 * registration we do not fail the whole card but rather proceed only
+	 * with the ports we manage to register successfully.  However we must
+	 * register at least one net device.
+	 */
+	for_each_port(adapter, i) {
+		err = register_netdev(adapter->port[i]);
+		if (err)
+			dev_warn(&pdev->dev,
+				 "cannot register net device %s, skipping\n",
+				 adapter->port[i]->name);
+		else {
+			/*
+			 * Change the name we use for messages to the name of
+			 * the first successfully registered interface.
+			 */
+			if (!adapter->registered_device_map)
+				adapter->name = adapter->port[i]->name;
+
+			__set_bit(i, &adapter->registered_device_map);
+			adapter->chan_map[adap2pinfo(adapter, i)->tx_chan] = i;
+		}
+	}
+	if (!adapter->registered_device_map) {
+		dev_err(&pdev->dev, "could not register any net devices\n");
+		goto out_free_dev;
+	}
+
+	if (cxgb4_debugfs_root) {
+		adapter->debugfs_root = debugfs_create_dir(pci_name(pdev),
+							   cxgb4_debugfs_root);
+		setup_debugfs(adapter);
+	}
+
+	/* See what interrupts we'll be using */
+	if (msi > 1 && enable_msix(adapter) == 0)
+		adapter->flags |= USING_MSIX;
+	else if (msi > 0 && pci_enable_msi(pdev) == 0)
+		adapter->flags |= USING_MSI;
+
+	if (is_offload(adapter))
+		attach_ulds(adapter);
+
+	print_port_info(adapter);
+
+sriov:
+#ifdef CONFIG_PCI_IOV
+	if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0)
+		if (pci_enable_sriov(pdev, num_vf[func]) == 0)
+			dev_info(&pdev->dev,
+				 "instantiated %u virtual functions\n",
+				 num_vf[func]);
+#endif
+	return 0;
+
+ out_free_dev:
+	t4_free_mem(adapter->tids.tid_tab);
+	t4_free_mem(adapter->l2t);
+	for_each_port(adapter, i)
+		if (adapter->port[i])
+			free_netdev(adapter->port[i]);
+	if (adapter->flags & FW_OK)
+		t4_fw_bye(adapter, 0);
+ out_unmap_bar:
+	iounmap(adapter->regs);
+ out_free_adapter:
+	kfree(adapter);
+ out_disable_device:
+	pci_disable_pcie_error_reporting(pdev);
+	pci_disable_device(pdev);
+ out_release_regions:
+	pci_release_regions(pdev);
+	pci_set_drvdata(pdev, NULL);
+	return err;
+}
+
+static void __devexit remove_one(struct pci_dev *pdev)
+{
+	struct adapter *adapter = pci_get_drvdata(pdev);
+
+	pci_disable_sriov(pdev);
+
+	if (adapter) {
+		int i;
+
+		if (is_offload(adapter))
+			detach_ulds(adapter);
+
+		for_each_port(adapter, i)
+			if (test_bit(i, &adapter->registered_device_map))
+				unregister_netdev(adapter->port[i]);
+
+		if (adapter->debugfs_root)
+			debugfs_remove_recursive(adapter->debugfs_root);
+
+		t4_sge_stop(adapter);
+		t4_free_sge_resources(adapter);
+		t4_free_mem(adapter->l2t);
+		t4_free_mem(adapter->tids.tid_tab);
+		disable_msi(adapter);
+
+		for_each_port(adapter, i)
+			if (adapter->port[i])
+				free_netdev(adapter->port[i]);
+
+		if (adapter->flags & FW_OK)
+			t4_fw_bye(adapter, 0);
+		iounmap(adapter->regs);
+		kfree(adapter);
+		pci_disable_pcie_error_reporting(pdev);
+		pci_disable_device(pdev);
+		pci_release_regions(pdev);
+		pci_set_drvdata(pdev, NULL);
+	} else if (PCI_FUNC(pdev->devfn) > 0)
+		pci_release_regions(pdev);
+}
+
+static struct pci_driver cxgb4_driver = {
+	.name     = KBUILD_MODNAME,
+	.id_table = cxgb4_pci_tbl,
+	.probe    = init_one,
+	.remove   = __devexit_p(remove_one),
+};
+
+static int __init cxgb4_init_module(void)
+{
+	int ret;
+
+	/* Debugfs support is optional, just warn if this fails */
+	cxgb4_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
+	if (!cxgb4_debugfs_root)
+		pr_warning("could not create debugfs entry, continuing\n");
+
+	ret = pci_register_driver(&cxgb4_driver);
+	if (ret < 0)
+		debugfs_remove(cxgb4_debugfs_root);
+	return ret;
+}
+
+static void __exit cxgb4_cleanup_module(void)
+{
+	pci_unregister_driver(&cxgb4_driver);
+	debugfs_remove(cxgb4_debugfs_root);  /* NULL ok */
+}
+
+module_init(cxgb4_init_module);
+module_exit(cxgb4_cleanup_module);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb4/cxgb4_uld.h linux-libre-2.6.34-gnu1/drivers/net/cxgb4/cxgb4_uld.h
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb4/cxgb4_uld.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb4/cxgb4_uld.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,239 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __CXGB4_OFLD_H
+#define __CXGB4_OFLD_H
+
+#include <linux/cache.h>
+#include <linux/spinlock.h>
+#include <linux/skbuff.h>
+#include <asm/atomic.h>
+
+/* CPL message priority levels */
+enum {
+	CPL_PRIORITY_DATA     = 0,  /* data messages */
+	CPL_PRIORITY_SETUP    = 1,  /* connection setup messages */
+	CPL_PRIORITY_TEARDOWN = 0,  /* connection teardown messages */
+	CPL_PRIORITY_LISTEN   = 1,  /* listen start/stop messages */
+	CPL_PRIORITY_ACK      = 1,  /* RX ACK messages */
+	CPL_PRIORITY_CONTROL  = 1   /* control messages */
+};
+
+#define INIT_TP_WR(w, tid) do { \
+	(w)->wr.wr_hi = htonl(FW_WR_OP(FW_TP_WR) | \
+			      FW_WR_IMMDLEN(sizeof(*w) - sizeof(w->wr))); \
+	(w)->wr.wr_mid = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*w), 16)) | \
+			       FW_WR_FLOWID(tid)); \
+	(w)->wr.wr_lo = cpu_to_be64(0); \
+} while (0)
+
+#define INIT_TP_WR_CPL(w, cpl, tid) do { \
+	INIT_TP_WR(w, tid); \
+	OPCODE_TID(w) = htonl(MK_OPCODE_TID(cpl, tid)); \
+} while (0)
+
+#define INIT_ULPTX_WR(w, wrlen, atomic, tid) do { \
+	(w)->wr.wr_hi = htonl(FW_WR_OP(FW_ULPTX_WR) | FW_WR_ATOMIC(atomic)); \
+	(w)->wr.wr_mid = htonl(FW_WR_LEN16(DIV_ROUND_UP(wrlen, 16)) | \
+			       FW_WR_FLOWID(tid)); \
+	(w)->wr.wr_lo = cpu_to_be64(0); \
+} while (0)
+
+/* Special asynchronous notification message */
+#define CXGB4_MSG_AN ((void *)1)
+
+struct serv_entry {
+	void *data;
+};
+
+union aopen_entry {
+	void *data;
+	union aopen_entry *next;
+};
+
+/*
+ * Holds the size, base address, free list start, etc of the TID, server TID,
+ * and active-open TID tables.  The tables themselves are allocated dynamically.
+ */
+struct tid_info {
+	void **tid_tab;
+	unsigned int ntids;
+
+	struct serv_entry *stid_tab;
+	unsigned long *stid_bmap;
+	unsigned int nstids;
+	unsigned int stid_base;
+
+	union aopen_entry *atid_tab;
+	unsigned int natids;
+
+	unsigned int nftids;
+	unsigned int ftid_base;
+
+	spinlock_t atid_lock ____cacheline_aligned_in_smp;
+	union aopen_entry *afree;
+	unsigned int atids_in_use;
+
+	spinlock_t stid_lock;
+	unsigned int stids_in_use;
+
+	atomic_t tids_in_use;
+};
+
+static inline void *lookup_tid(const struct tid_info *t, unsigned int tid)
+{
+	return tid < t->ntids ? t->tid_tab[tid] : NULL;
+}
+
+static inline void *lookup_atid(const struct tid_info *t, unsigned int atid)
+{
+	return atid < t->natids ? t->atid_tab[atid].data : NULL;
+}
+
+static inline void *lookup_stid(const struct tid_info *t, unsigned int stid)
+{
+	stid -= t->stid_base;
+	return stid < t->nstids ? t->stid_tab[stid].data : NULL;
+}
+
+static inline void cxgb4_insert_tid(struct tid_info *t, void *data,
+				    unsigned int tid)
+{
+	t->tid_tab[tid] = data;
+	atomic_inc(&t->tids_in_use);
+}
+
+int cxgb4_alloc_atid(struct tid_info *t, void *data);
+int cxgb4_alloc_stid(struct tid_info *t, int family, void *data);
+void cxgb4_free_atid(struct tid_info *t, unsigned int atid);
+void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family);
+void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid);
+void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
+			     unsigned int tid);
+
+struct in6_addr;
+
+int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
+			__be32 sip, __be16 sport, unsigned int queue);
+int cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
+			 const struct in6_addr *sip, __be16 sport,
+			 unsigned int queue);
+
+static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue)
+{
+	skb_set_queue_mapping(skb, (queue << 1) | prio);
+}
+
+enum cxgb4_uld {
+	CXGB4_ULD_RDMA,
+	CXGB4_ULD_ISCSI,
+	CXGB4_ULD_MAX
+};
+
+enum cxgb4_state {
+	CXGB4_STATE_UP,
+	CXGB4_STATE_START_RECOVERY,
+	CXGB4_STATE_DOWN,
+	CXGB4_STATE_DETACH
+};
+
+struct pci_dev;
+struct l2t_data;
+struct net_device;
+struct pkt_gl;
+struct tp_tcp_stats;
+
+struct cxgb4_range {
+	unsigned int start;
+	unsigned int size;
+};
+
+struct cxgb4_virt_res {                      /* virtualized HW resources */
+	struct cxgb4_range ddp;
+	struct cxgb4_range iscsi;
+	struct cxgb4_range stag;
+	struct cxgb4_range rq;
+	struct cxgb4_range pbl;
+};
+
+/*
+ * Block of information the LLD provides to ULDs attaching to a device.
+ */
+struct cxgb4_lld_info {
+	struct pci_dev *pdev;                /* associated PCI device */
+	struct l2t_data *l2t;                /* L2 table */
+	struct tid_info *tids;               /* TID table */
+	struct net_device **ports;           /* device ports */
+	const struct cxgb4_virt_res *vr;     /* assorted HW resources */
+	const unsigned short *mtus;          /* MTU table */
+	const unsigned short *rxq_ids;       /* the ULD's Rx queue ids */
+	unsigned short nrxq;                 /* # of Rx queues */
+	unsigned short ntxq;                 /* # of Tx queues */
+	unsigned char nchan:4;               /* # of channels */
+	unsigned char nports:4;              /* # of ports */
+	unsigned char wr_cred;               /* WR 16-byte credits */
+	unsigned char adapter_type;          /* type of adapter */
+	unsigned char fw_api_ver;            /* FW API version */
+	unsigned int fw_vers;                /* FW version */
+	unsigned int iscsi_iolen;            /* iSCSI max I/O length */
+	unsigned short udb_density;          /* # of user DB/page */
+	unsigned short ucq_density;          /* # of user CQs/page */
+	void __iomem *gts_reg;               /* address of GTS register */
+	void __iomem *db_reg;                /* address of kernel doorbell */
+};
+
+struct cxgb4_uld_info {
+	const char *name;
+	void *(*add)(const struct cxgb4_lld_info *p);
+	int (*rx_handler)(void *handle, const __be64 *rsp,
+			  const struct pkt_gl *gl);
+	int (*state_change)(void *handle, enum cxgb4_state new_state);
+};
+
+int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p);
+int cxgb4_unregister_uld(enum cxgb4_uld type);
+int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb);
+unsigned int cxgb4_port_chan(const struct net_device *dev);
+unsigned int cxgb4_port_viid(const struct net_device *dev);
+unsigned int cxgb4_port_idx(const struct net_device *dev);
+struct net_device *cxgb4_netdev_by_hwid(struct pci_dev *pdev, unsigned int id);
+unsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu,
+			    unsigned int *idx);
+void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4,
+			 struct tp_tcp_stats *v6);
+void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask,
+		      const unsigned int *pgsz_order);
+struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl,
+				   unsigned int skb_len, unsigned int pull_len);
+#endif  /* !__CXGB4_OFLD_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb4/l2t.c linux-libre-2.6.34-gnu1/drivers/net/cxgb4/l2t.c
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb4/l2t.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb4/l2t.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,624 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/if.h>
+#include <linux/if_vlan.h>
+#include <linux/jhash.h>
+#include <net/neighbour.h>
+#include "cxgb4.h"
+#include "l2t.h"
+#include "t4_msg.h"
+#include "t4fw_api.h"
+
+#define VLAN_NONE 0xfff
+
+/* identifies sync vs async L2T_WRITE_REQs */
+#define F_SYNC_WR    (1 << 12)
+
+enum {
+	L2T_STATE_VALID,      /* entry is up to date */
+	L2T_STATE_STALE,      /* entry may be used but needs revalidation */
+	L2T_STATE_RESOLVING,  /* entry needs address resolution */
+	L2T_STATE_SYNC_WRITE, /* synchronous write of entry underway */
+
+	/* when state is one of the below the entry is not hashed */
+	L2T_STATE_SWITCHING,  /* entry is being used by a switching filter */
+	L2T_STATE_UNUSED      /* entry not in use */
+};
+
+struct l2t_data {
+	rwlock_t lock;
+	atomic_t nfree;             /* number of free entries */
+	struct l2t_entry *rover;    /* starting point for next allocation */
+	struct l2t_entry l2tab[L2T_SIZE];
+};
+
+static inline unsigned int vlan_prio(const struct l2t_entry *e)
+{
+	return e->vlan >> 13;
+}
+
+static inline void l2t_hold(struct l2t_data *d, struct l2t_entry *e)
+{
+	if (atomic_add_return(1, &e->refcnt) == 1)  /* 0 -> 1 transition */
+		atomic_dec(&d->nfree);
+}
+
+/*
+ * To avoid having to check address families we do not allow v4 and v6
+ * neighbors to be on the same hash chain.  We keep v4 entries in the first
+ * half of available hash buckets and v6 in the second.
+ */
+enum {
+	L2T_SZ_HALF = L2T_SIZE / 2,
+	L2T_HASH_MASK = L2T_SZ_HALF - 1
+};
+
+static inline unsigned int arp_hash(const u32 *key, int ifindex)
+{
+	return jhash_2words(*key, ifindex, 0) & L2T_HASH_MASK;
+}
+
+static inline unsigned int ipv6_hash(const u32 *key, int ifindex)
+{
+	u32 xor = key[0] ^ key[1] ^ key[2] ^ key[3];
+
+	return L2T_SZ_HALF + (jhash_2words(xor, ifindex, 0) & L2T_HASH_MASK);
+}
+
+static unsigned int addr_hash(const u32 *addr, int addr_len, int ifindex)
+{
+	return addr_len == 4 ? arp_hash(addr, ifindex) :
+			       ipv6_hash(addr, ifindex);
+}
+
+/*
+ * Checks if an L2T entry is for the given IP/IPv6 address.  It does not check
+ * whether the L2T entry and the address are of the same address family.
+ * Callers ensure an address is only checked against L2T entries of the same
+ * family, something made trivial by the separation of IP and IPv6 hash chains
+ * mentioned above.  Returns 0 if there's a match,
+ */
+static int addreq(const struct l2t_entry *e, const u32 *addr)
+{
+	if (e->v6)
+		return (e->addr[0] ^ addr[0]) | (e->addr[1] ^ addr[1]) |
+		       (e->addr[2] ^ addr[2]) | (e->addr[3] ^ addr[3]);
+	return e->addr[0] ^ addr[0];
+}
+
+static void neigh_replace(struct l2t_entry *e, struct neighbour *n)
+{
+	neigh_hold(n);
+	if (e->neigh)
+		neigh_release(e->neigh);
+	e->neigh = n;
+}
+
+/*
+ * Write an L2T entry.  Must be called with the entry locked.
+ * The write may be synchronous or asynchronous.
+ */
+static int write_l2e(struct adapter *adap, struct l2t_entry *e, int sync)
+{
+	struct sk_buff *skb;
+	struct cpl_l2t_write_req *req;
+
+	skb = alloc_skb(sizeof(*req), GFP_ATOMIC);
+	if (!skb)
+		return -ENOMEM;
+
+	req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req));
+	INIT_TP_WR(req, 0);
+
+	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ,
+					e->idx | (sync ? F_SYNC_WR : 0) |
+					TID_QID(adap->sge.fw_evtq.abs_id)));
+	req->params = htons(L2T_W_PORT(e->lport) | L2T_W_NOREPLY(!sync));
+	req->l2t_idx = htons(e->idx);
+	req->vlan = htons(e->vlan);
+	if (e->neigh)
+		memcpy(e->dmac, e->neigh->ha, sizeof(e->dmac));
+	memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac));
+
+	set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0);
+	t4_ofld_send(adap, skb);
+
+	if (sync && e->state != L2T_STATE_SWITCHING)
+		e->state = L2T_STATE_SYNC_WRITE;
+	return 0;
+}
+
+/*
+ * Send packets waiting in an L2T entry's ARP queue.  Must be called with the
+ * entry locked.
+ */
+static void send_pending(struct adapter *adap, struct l2t_entry *e)
+{
+	while (e->arpq_head) {
+		struct sk_buff *skb = e->arpq_head;
+
+		e->arpq_head = skb->next;
+		skb->next = NULL;
+		t4_ofld_send(adap, skb);
+	}
+	e->arpq_tail = NULL;
+}
+
+/*
+ * Process a CPL_L2T_WRITE_RPL.  Wake up the ARP queue if it completes a
+ * synchronous L2T_WRITE.  Note that the TID in the reply is really the L2T
+ * index it refers to.
+ */
+void do_l2t_write_rpl(struct adapter *adap, const struct cpl_l2t_write_rpl *rpl)
+{
+	unsigned int tid = GET_TID(rpl);
+	unsigned int idx = tid & (L2T_SIZE - 1);
+
+	if (unlikely(rpl->status != CPL_ERR_NONE)) {
+		dev_err(adap->pdev_dev,
+			"Unexpected L2T_WRITE_RPL status %u for entry %u\n",
+			rpl->status, idx);
+		return;
+	}
+
+	if (tid & F_SYNC_WR) {
+		struct l2t_entry *e = &adap->l2t->l2tab[idx];
+
+		spin_lock(&e->lock);
+		if (e->state != L2T_STATE_SWITCHING) {
+			send_pending(adap, e);
+			e->state = (e->neigh->nud_state & NUD_STALE) ?
+					L2T_STATE_STALE : L2T_STATE_VALID;
+		}
+		spin_unlock(&e->lock);
+	}
+}
+
+/*
+ * Add a packet to an L2T entry's queue of packets awaiting resolution.
+ * Must be called with the entry's lock held.
+ */
+static inline void arpq_enqueue(struct l2t_entry *e, struct sk_buff *skb)
+{
+	skb->next = NULL;
+	if (e->arpq_head)
+		e->arpq_tail->next = skb;
+	else
+		e->arpq_head = skb;
+	e->arpq_tail = skb;
+}
+
+int cxgb4_l2t_send(struct net_device *dev, struct sk_buff *skb,
+		   struct l2t_entry *e)
+{
+	struct adapter *adap = netdev2adap(dev);
+
+again:
+	switch (e->state) {
+	case L2T_STATE_STALE:     /* entry is stale, kick off revalidation */
+		neigh_event_send(e->neigh, NULL);
+		spin_lock_bh(&e->lock);
+		if (e->state == L2T_STATE_STALE)
+			e->state = L2T_STATE_VALID;
+		spin_unlock_bh(&e->lock);
+	case L2T_STATE_VALID:     /* fast-path, send the packet on */
+		return t4_ofld_send(adap, skb);
+	case L2T_STATE_RESOLVING:
+	case L2T_STATE_SYNC_WRITE:
+		spin_lock_bh(&e->lock);
+		if (e->state != L2T_STATE_SYNC_WRITE &&
+		    e->state != L2T_STATE_RESOLVING) {
+			spin_unlock_bh(&e->lock);
+			goto again;
+		}
+		arpq_enqueue(e, skb);
+		spin_unlock_bh(&e->lock);
+
+		if (e->state == L2T_STATE_RESOLVING &&
+		    !neigh_event_send(e->neigh, NULL)) {
+			spin_lock_bh(&e->lock);
+			if (e->state == L2T_STATE_RESOLVING && e->arpq_head)
+				write_l2e(adap, e, 1);
+			spin_unlock_bh(&e->lock);
+		}
+	}
+	return 0;
+}
+EXPORT_SYMBOL(cxgb4_l2t_send);
+
+/*
+ * Allocate a free L2T entry.  Must be called with l2t_data.lock held.
+ */
+static struct l2t_entry *alloc_l2e(struct l2t_data *d)
+{
+	struct l2t_entry *end, *e, **p;
+
+	if (!atomic_read(&d->nfree))
+		return NULL;
+
+	/* there's definitely a free entry */
+	for (e = d->rover, end = &d->l2tab[L2T_SIZE]; e != end; ++e)
+		if (atomic_read(&e->refcnt) == 0)
+			goto found;
+
+	for (e = d->l2tab; atomic_read(&e->refcnt); ++e)
+		;
+found:
+	d->rover = e + 1;
+	atomic_dec(&d->nfree);
+
+	/*
+	 * The entry we found may be an inactive entry that is
+	 * presently in the hash table.  We need to remove it.
+	 */
+	if (e->state < L2T_STATE_SWITCHING)
+		for (p = &d->l2tab[e->hash].first; *p; p = &(*p)->next)
+			if (*p == e) {
+				*p = e->next;
+				e->next = NULL;
+				break;
+			}
+
+	e->state = L2T_STATE_UNUSED;
+	return e;
+}
+
+/*
+ * Called when an L2T entry has no more users.
+ */
+static void t4_l2e_free(struct l2t_entry *e)
+{
+	struct l2t_data *d;
+
+	spin_lock_bh(&e->lock);
+	if (atomic_read(&e->refcnt) == 0) {  /* hasn't been recycled */
+		if (e->neigh) {
+			neigh_release(e->neigh);
+			e->neigh = NULL;
+		}
+	}
+	spin_unlock_bh(&e->lock);
+
+	d = container_of(e, struct l2t_data, l2tab[e->idx]);
+	atomic_inc(&d->nfree);
+}
+
+void cxgb4_l2t_release(struct l2t_entry *e)
+{
+	if (atomic_dec_and_test(&e->refcnt))
+		t4_l2e_free(e);
+}
+EXPORT_SYMBOL(cxgb4_l2t_release);
+
+/*
+ * Update an L2T entry that was previously used for the same next hop as neigh.
+ * Must be called with softirqs disabled.
+ */
+static void reuse_entry(struct l2t_entry *e, struct neighbour *neigh)
+{
+	unsigned int nud_state;
+
+	spin_lock(&e->lock);                /* avoid race with t4_l2t_free */
+	if (neigh != e->neigh)
+		neigh_replace(e, neigh);
+	nud_state = neigh->nud_state;
+	if (memcmp(e->dmac, neigh->ha, sizeof(e->dmac)) ||
+	    !(nud_state & NUD_VALID))
+		e->state = L2T_STATE_RESOLVING;
+	else if (nud_state & NUD_CONNECTED)
+		e->state = L2T_STATE_VALID;
+	else
+		e->state = L2T_STATE_STALE;
+	spin_unlock(&e->lock);
+}
+
+struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh,
+				const struct net_device *physdev,
+				unsigned int priority)
+{
+	u8 lport;
+	u16 vlan;
+	struct l2t_entry *e;
+	int addr_len = neigh->tbl->key_len;
+	u32 *addr = (u32 *)neigh->primary_key;
+	int ifidx = neigh->dev->ifindex;
+	int hash = addr_hash(addr, addr_len, ifidx);
+
+	if (neigh->dev->flags & IFF_LOOPBACK)
+		lport = netdev2pinfo(physdev)->tx_chan + 4;
+	else
+		lport = netdev2pinfo(physdev)->lport;
+
+	if (neigh->dev->priv_flags & IFF_802_1Q_VLAN)
+		vlan = vlan_dev_vlan_id(neigh->dev);
+	else
+		vlan = VLAN_NONE;
+
+	write_lock_bh(&d->lock);
+	for (e = d->l2tab[hash].first; e; e = e->next)
+		if (!addreq(e, addr) && e->ifindex == ifidx &&
+		    e->vlan == vlan && e->lport == lport) {
+			l2t_hold(d, e);
+			if (atomic_read(&e->refcnt) == 1)
+				reuse_entry(e, neigh);
+			goto done;
+		}
+
+	/* Need to allocate a new entry */
+	e = alloc_l2e(d);
+	if (e) {
+		spin_lock(&e->lock);          /* avoid race with t4_l2t_free */
+		e->state = L2T_STATE_RESOLVING;
+		memcpy(e->addr, addr, addr_len);
+		e->ifindex = ifidx;
+		e->hash = hash;
+		e->lport = lport;
+		e->v6 = addr_len == 16;
+		atomic_set(&e->refcnt, 1);
+		neigh_replace(e, neigh);
+		e->vlan = vlan;
+		e->next = d->l2tab[hash].first;
+		d->l2tab[hash].first = e;
+		spin_unlock(&e->lock);
+	}
+done:
+	write_unlock_bh(&d->lock);
+	return e;
+}
+EXPORT_SYMBOL(cxgb4_l2t_get);
+
+/*
+ * Called when address resolution fails for an L2T entry to handle packets
+ * on the arpq head.  If a packet specifies a failure handler it is invoked,
+ * otherwise the packet is sent to the device.
+ */
+static void handle_failed_resolution(struct adapter *adap, struct sk_buff *arpq)
+{
+	while (arpq) {
+		struct sk_buff *skb = arpq;
+		const struct l2t_skb_cb *cb = L2T_SKB_CB(skb);
+
+		arpq = skb->next;
+		skb->next = NULL;
+		if (cb->arp_err_handler)
+			cb->arp_err_handler(cb->handle, skb);
+		else
+			t4_ofld_send(adap, skb);
+	}
+}
+
+/*
+ * Called when the host's neighbor layer makes a change to some entry that is
+ * loaded into the HW L2 table.
+ */
+void t4_l2t_update(struct adapter *adap, struct neighbour *neigh)
+{
+	struct l2t_entry *e;
+	struct sk_buff *arpq = NULL;
+	struct l2t_data *d = adap->l2t;
+	int addr_len = neigh->tbl->key_len;
+	u32 *addr = (u32 *) neigh->primary_key;
+	int ifidx = neigh->dev->ifindex;
+	int hash = addr_hash(addr, addr_len, ifidx);
+
+	read_lock_bh(&d->lock);
+	for (e = d->l2tab[hash].first; e; e = e->next)
+		if (!addreq(e, addr) && e->ifindex == ifidx) {
+			spin_lock(&e->lock);
+			if (atomic_read(&e->refcnt))
+				goto found;
+			spin_unlock(&e->lock);
+			break;
+		}
+	read_unlock_bh(&d->lock);
+	return;
+
+ found:
+	read_unlock(&d->lock);
+
+	if (neigh != e->neigh)
+		neigh_replace(e, neigh);
+
+	if (e->state == L2T_STATE_RESOLVING) {
+		if (neigh->nud_state & NUD_FAILED) {
+			arpq = e->arpq_head;
+			e->arpq_head = e->arpq_tail = NULL;
+		} else if ((neigh->nud_state & (NUD_CONNECTED | NUD_STALE)) &&
+			   e->arpq_head) {
+			write_l2e(adap, e, 1);
+		}
+	} else {
+		e->state = neigh->nud_state & NUD_CONNECTED ?
+			L2T_STATE_VALID : L2T_STATE_STALE;
+		if (memcmp(e->dmac, neigh->ha, sizeof(e->dmac)))
+			write_l2e(adap, e, 0);
+	}
+
+	spin_unlock_bh(&e->lock);
+
+	if (arpq)
+		handle_failed_resolution(adap, arpq);
+}
+
+/*
+ * Allocate an L2T entry for use by a switching rule.  Such entries need to be
+ * explicitly freed and while busy they are not on any hash chain, so normal
+ * address resolution updates do not see them.
+ */
+struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d)
+{
+	struct l2t_entry *e;
+
+	write_lock_bh(&d->lock);
+	e = alloc_l2e(d);
+	if (e) {
+		spin_lock(&e->lock);          /* avoid race with t4_l2t_free */
+		e->state = L2T_STATE_SWITCHING;
+		atomic_set(&e->refcnt, 1);
+		spin_unlock(&e->lock);
+	}
+	write_unlock_bh(&d->lock);
+	return e;
+}
+
+/*
+ * Sets/updates the contents of a switching L2T entry that has been allocated
+ * with an earlier call to @t4_l2t_alloc_switching.
+ */
+int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan,
+			 u8 port, u8 *eth_addr)
+{
+	e->vlan = vlan;
+	e->lport = port;
+	memcpy(e->dmac, eth_addr, ETH_ALEN);
+	return write_l2e(adap, e, 0);
+}
+
+struct l2t_data *t4_init_l2t(void)
+{
+	int i;
+	struct l2t_data *d;
+
+	d = t4_alloc_mem(sizeof(*d));
+	if (!d)
+		return NULL;
+
+	d->rover = d->l2tab;
+	atomic_set(&d->nfree, L2T_SIZE);
+	rwlock_init(&d->lock);
+
+	for (i = 0; i < L2T_SIZE; ++i) {
+		d->l2tab[i].idx = i;
+		d->l2tab[i].state = L2T_STATE_UNUSED;
+		spin_lock_init(&d->l2tab[i].lock);
+		atomic_set(&d->l2tab[i].refcnt, 0);
+	}
+	return d;
+}
+
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static inline void *l2t_get_idx(struct seq_file *seq, loff_t pos)
+{
+	struct l2t_entry *l2tab = seq->private;
+
+	return pos >= L2T_SIZE ? NULL : &l2tab[pos];
+}
+
+static void *l2t_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	return *pos ? l2t_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+}
+
+static void *l2t_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	v = l2t_get_idx(seq, *pos);
+	if (v)
+		++*pos;
+	return v;
+}
+
+static void l2t_seq_stop(struct seq_file *seq, void *v)
+{
+}
+
+static char l2e_state(const struct l2t_entry *e)
+{
+	switch (e->state) {
+	case L2T_STATE_VALID: return 'V';
+	case L2T_STATE_STALE: return 'S';
+	case L2T_STATE_SYNC_WRITE: return 'W';
+	case L2T_STATE_RESOLVING: return e->arpq_head ? 'A' : 'R';
+	case L2T_STATE_SWITCHING: return 'X';
+	default:
+		return 'U';
+	}
+}
+
+static int l2t_seq_show(struct seq_file *seq, void *v)
+{
+	if (v == SEQ_START_TOKEN)
+		seq_puts(seq, " Idx IP address                "
+			 "Ethernet address  VLAN/P LP State Users Port\n");
+	else {
+		char ip[60];
+		struct l2t_entry *e = v;
+
+		spin_lock_bh(&e->lock);
+		if (e->state == L2T_STATE_SWITCHING)
+			ip[0] = '\0';
+		else
+			sprintf(ip, e->v6 ? "%pI6c" : "%pI4", e->addr);
+		seq_printf(seq, "%4u %-25s %17pM %4d %u %2u   %c   %5u %s\n",
+			   e->idx, ip, e->dmac,
+			   e->vlan & VLAN_VID_MASK, vlan_prio(e), e->lport,
+			   l2e_state(e), atomic_read(&e->refcnt),
+			   e->neigh ? e->neigh->dev->name : "");
+		spin_unlock_bh(&e->lock);
+	}
+	return 0;
+}
+
+static const struct seq_operations l2t_seq_ops = {
+	.start = l2t_seq_start,
+	.next = l2t_seq_next,
+	.stop = l2t_seq_stop,
+	.show = l2t_seq_show
+};
+
+static int l2t_seq_open(struct inode *inode, struct file *file)
+{
+	int rc = seq_open(file, &l2t_seq_ops);
+
+	if (!rc) {
+		struct adapter *adap = inode->i_private;
+		struct seq_file *seq = file->private_data;
+
+		seq->private = adap->l2t->l2tab;
+	}
+	return rc;
+}
+
+const struct file_operations t4_l2t_fops = {
+	.owner = THIS_MODULE,
+	.open = l2t_seq_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = seq_release,
+};
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb4/l2t.h linux-libre-2.6.34-gnu1/drivers/net/cxgb4/l2t.h
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb4/l2t.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb4/l2t.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,110 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __CXGB4_L2T_H
+#define __CXGB4_L2T_H
+
+#include <linux/spinlock.h>
+#include <linux/if_ether.h>
+#include <asm/atomic.h>
+
+struct adapter;
+struct l2t_data;
+struct neighbour;
+struct net_device;
+struct file_operations;
+struct cpl_l2t_write_rpl;
+
+/*
+ * Each L2T entry plays multiple roles.  First of all, it keeps state for the
+ * corresponding entry of the HW L2 table and maintains a queue of offload
+ * packets awaiting address resolution.  Second, it is a node of a hash table
+ * chain, where the nodes of the chain are linked together through their next
+ * pointer.  Finally, each node is a bucket of a hash table, pointing to the
+ * first element in its chain through its first pointer.
+ */
+struct l2t_entry {
+	u16 state;                  /* entry state */
+	u16 idx;                    /* entry index */
+	u32 addr[4];                /* next hop IP or IPv6 address */
+	int ifindex;                /* neighbor's net_device's ifindex */
+	struct neighbour *neigh;    /* associated neighbour */
+	struct l2t_entry *first;    /* start of hash chain */
+	struct l2t_entry *next;     /* next l2t_entry on chain */
+	struct sk_buff *arpq_head;  /* queue of packets awaiting resolution */
+	struct sk_buff *arpq_tail;
+	spinlock_t lock;
+	atomic_t refcnt;            /* entry reference count */
+	u16 hash;                   /* hash bucket the entry is on */
+	u16 vlan;                   /* VLAN TCI (id: bits 0-11, prio: 13-15 */
+	u8 v6;                      /* whether entry is for IPv6 */
+	u8 lport;                   /* associated offload logical interface */
+	u8 dmac[ETH_ALEN];          /* neighbour's MAC address */
+};
+
+typedef void (*arp_err_handler_t)(void *handle, struct sk_buff *skb);
+
+/*
+ * Callback stored in an skb to handle address resolution failure.
+ */
+struct l2t_skb_cb {
+	void *handle;
+	arp_err_handler_t arp_err_handler;
+};
+
+#define L2T_SKB_CB(skb) ((struct l2t_skb_cb *)(skb)->cb)
+
+static inline void t4_set_arp_err_handler(struct sk_buff *skb, void *handle,
+					  arp_err_handler_t handler)
+{
+	L2T_SKB_CB(skb)->handle = handle;
+	L2T_SKB_CB(skb)->arp_err_handler = handler;
+}
+
+void cxgb4_l2t_release(struct l2t_entry *e);
+int cxgb4_l2t_send(struct net_device *dev, struct sk_buff *skb,
+		   struct l2t_entry *e);
+struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh,
+				const struct net_device *physdev,
+				unsigned int priority);
+
+void t4_l2t_update(struct adapter *adap, struct neighbour *neigh);
+struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d);
+int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan,
+			 u8 port, u8 *eth_addr);
+struct l2t_data *t4_init_l2t(void);
+void do_l2t_write_rpl(struct adapter *p, const struct cpl_l2t_write_rpl *rpl);
+
+extern const struct file_operations t4_l2t_fops;
+#endif  /* __CXGB4_L2T_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb4/Makefile linux-libre-2.6.34-gnu1/drivers/net/cxgb4/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb4/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb4/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,7 @@
+#
+# Chelsio T4 driver
+#
+
+obj-$(CONFIG_CHELSIO_T4) += cxgb4.o
+
+cxgb4-objs := cxgb4_main.o l2t.o t4_hw.o sge.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb4/sge.c linux-libre-2.6.34-gnu1/drivers/net/cxgb4/sge.c
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb4/sge.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb4/sge.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,2431 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
+#include <linux/ip.h>
+#include <linux/dma-mapping.h>
+#include <linux/jiffies.h>
+#include <net/ipv6.h>
+#include <net/tcp.h>
+#include "cxgb4.h"
+#include "t4_regs.h"
+#include "t4_msg.h"
+#include "t4fw_api.h"
+
+/*
+ * Rx buffer size.  We use largish buffers if possible but settle for single
+ * pages under memory shortage.
+ */
+#if PAGE_SHIFT >= 16
+# define FL_PG_ORDER 0
+#else
+# define FL_PG_ORDER (16 - PAGE_SHIFT)
+#endif
+
+/* RX_PULL_LEN should be <= RX_COPY_THRES */
+#define RX_COPY_THRES    256
+#define RX_PULL_LEN      128
+
+/*
+ * Main body length for sk_buffs used for Rx Ethernet packets with fragments.
+ * Should be >= RX_PULL_LEN but possibly bigger to give pskb_may_pull some room.
+ */
+#define RX_PKT_SKB_LEN   512
+
+/* Ethernet header padding prepended to RX_PKTs */
+#define RX_PKT_PAD 2
+
+/*
+ * Max number of Tx descriptors we clean up at a time.  Should be modest as
+ * freeing skbs isn't cheap and it happens while holding locks.  We just need
+ * to free packets faster than they arrive, we eventually catch up and keep
+ * the amortized cost reasonable.  Must be >= 2 * TXQ_STOP_THRES.
+ */
+#define MAX_TX_RECLAIM 16
+
+/*
+ * Max number of Rx buffers we replenish at a time.  Again keep this modest,
+ * allocating buffers isn't cheap either.
+ */
+#define MAX_RX_REFILL 16U
+
+/*
+ * Period of the Rx queue check timer.  This timer is infrequent as it has
+ * something to do only when the system experiences severe memory shortage.
+ */
+#define RX_QCHECK_PERIOD (HZ / 2)
+
+/*
+ * Period of the Tx queue check timer.
+ */
+#define TX_QCHECK_PERIOD (HZ / 2)
+
+/*
+ * Max number of Tx descriptors to be reclaimed by the Tx timer.
+ */
+#define MAX_TIMER_TX_RECLAIM 100
+
+/*
+ * Timer index used when backing off due to memory shortage.
+ */
+#define NOMEM_TMR_IDX (SGE_NTIMERS - 1)
+
+/*
+ * An FL with <= FL_STARVE_THRES buffers is starving and a periodic timer will
+ * attempt to refill it.
+ */
+#define FL_STARVE_THRES 4
+
+/*
+ * Suspend an Ethernet Tx queue with fewer available descriptors than this.
+ * This is the same as calc_tx_descs() for a TSO packet with
+ * nr_frags == MAX_SKB_FRAGS.
+ */
+#define ETHTXQ_STOP_THRES \
+	(1 + DIV_ROUND_UP((3 * MAX_SKB_FRAGS) / 2 + (MAX_SKB_FRAGS & 1), 8))
+
+/*
+ * Suspension threshold for non-Ethernet Tx queues.  We require enough room
+ * for a full sized WR.
+ */
+#define TXQ_STOP_THRES (SGE_MAX_WR_LEN / sizeof(struct tx_desc))
+
+/*
+ * Max Tx descriptor space we allow for an Ethernet packet to be inlined
+ * into a WR.
+ */
+#define MAX_IMM_TX_PKT_LEN 128
+
+/*
+ * Max size of a WR sent through a control Tx queue.
+ */
+#define MAX_CTRL_WR_LEN SGE_MAX_WR_LEN
+
+enum {
+	/* packet alignment in FL buffers */
+	FL_ALIGN = L1_CACHE_BYTES < 32 ? 32 : L1_CACHE_BYTES,
+	/* egress status entry size */
+	STAT_LEN = L1_CACHE_BYTES > 64 ? 128 : 64
+};
+
+struct tx_sw_desc {                /* SW state per Tx descriptor */
+	struct sk_buff *skb;
+	struct ulptx_sgl *sgl;
+};
+
+struct rx_sw_desc {                /* SW state per Rx descriptor */
+	struct page *page;
+	dma_addr_t dma_addr;
+};
+
+/*
+ * The low bits of rx_sw_desc.dma_addr have special meaning.
+ */
+enum {
+	RX_LARGE_BUF    = 1 << 0, /* buffer is larger than PAGE_SIZE */
+	RX_UNMAPPED_BUF = 1 << 1, /* buffer is not mapped */
+};
+
+static inline dma_addr_t get_buf_addr(const struct rx_sw_desc *d)
+{
+	return d->dma_addr & ~(dma_addr_t)(RX_LARGE_BUF | RX_UNMAPPED_BUF);
+}
+
+static inline bool is_buf_mapped(const struct rx_sw_desc *d)
+{
+	return !(d->dma_addr & RX_UNMAPPED_BUF);
+}
+
+/**
+ *	txq_avail - return the number of available slots in a Tx queue
+ *	@q: the Tx queue
+ *
+ *	Returns the number of descriptors in a Tx queue available to write new
+ *	packets.
+ */
+static inline unsigned int txq_avail(const struct sge_txq *q)
+{
+	return q->size - 1 - q->in_use;
+}
+
+/**
+ *	fl_cap - return the capacity of a free-buffer list
+ *	@fl: the FL
+ *
+ *	Returns the capacity of a free-buffer list.  The capacity is less than
+ *	the size because one descriptor needs to be left unpopulated, otherwise
+ *	HW will think the FL is empty.
+ */
+static inline unsigned int fl_cap(const struct sge_fl *fl)
+{
+	return fl->size - 8;   /* 1 descriptor = 8 buffers */
+}
+
+static inline bool fl_starving(const struct sge_fl *fl)
+{
+	return fl->avail - fl->pend_cred <= FL_STARVE_THRES;
+}
+
+static int map_skb(struct device *dev, const struct sk_buff *skb,
+		   dma_addr_t *addr)
+{
+	const skb_frag_t *fp, *end;
+	const struct skb_shared_info *si;
+
+	*addr = dma_map_single(dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
+	if (dma_mapping_error(dev, *addr))
+		goto out_err;
+
+	si = skb_shinfo(skb);
+	end = &si->frags[si->nr_frags];
+
+	for (fp = si->frags; fp < end; fp++) {
+		*++addr = dma_map_page(dev, fp->page, fp->page_offset, fp->size,
+				       DMA_TO_DEVICE);
+		if (dma_mapping_error(dev, *addr))
+			goto unwind;
+	}
+	return 0;
+
+unwind:
+	while (fp-- > si->frags)
+		dma_unmap_page(dev, *--addr, fp->size, DMA_TO_DEVICE);
+
+	dma_unmap_single(dev, addr[-1], skb_headlen(skb), DMA_TO_DEVICE);
+out_err:
+	return -ENOMEM;
+}
+
+#ifdef CONFIG_NEED_DMA_MAP_STATE
+static void unmap_skb(struct device *dev, const struct sk_buff *skb,
+		      const dma_addr_t *addr)
+{
+	const skb_frag_t *fp, *end;
+	const struct skb_shared_info *si;
+
+	dma_unmap_single(dev, *addr++, skb_headlen(skb), DMA_TO_DEVICE);
+
+	si = skb_shinfo(skb);
+	end = &si->frags[si->nr_frags];
+	for (fp = si->frags; fp < end; fp++)
+		dma_unmap_page(dev, *addr++, fp->size, DMA_TO_DEVICE);
+}
+
+/**
+ *	deferred_unmap_destructor - unmap a packet when it is freed
+ *	@skb: the packet
+ *
+ *	This is the packet destructor used for Tx packets that need to remain
+ *	mapped until they are freed rather than until their Tx descriptors are
+ *	freed.
+ */
+static void deferred_unmap_destructor(struct sk_buff *skb)
+{
+	unmap_skb(skb->dev->dev.parent, skb, (dma_addr_t *)skb->head);
+}
+#endif
+
+static void unmap_sgl(struct device *dev, const struct sk_buff *skb,
+		      const struct ulptx_sgl *sgl, const struct sge_txq *q)
+{
+	const struct ulptx_sge_pair *p;
+	unsigned int nfrags = skb_shinfo(skb)->nr_frags;
+
+	if (likely(skb_headlen(skb)))
+		dma_unmap_single(dev, be64_to_cpu(sgl->addr0), ntohl(sgl->len0),
+				 DMA_TO_DEVICE);
+	else {
+		dma_unmap_page(dev, be64_to_cpu(sgl->addr0), ntohl(sgl->len0),
+			       DMA_TO_DEVICE);
+		nfrags--;
+	}
+
+	/*
+	 * the complexity below is because of the possibility of a wrap-around
+	 * in the middle of an SGL
+	 */
+	for (p = sgl->sge; nfrags >= 2; nfrags -= 2) {
+		if (likely((u8 *)(p + 1) <= (u8 *)q->stat)) {
+unmap:			dma_unmap_page(dev, be64_to_cpu(p->addr[0]),
+				       ntohl(p->len[0]), DMA_TO_DEVICE);
+			dma_unmap_page(dev, be64_to_cpu(p->addr[1]),
+				       ntohl(p->len[1]), DMA_TO_DEVICE);
+			p++;
+		} else if ((u8 *)p == (u8 *)q->stat) {
+			p = (const struct ulptx_sge_pair *)q->desc;
+			goto unmap;
+		} else if ((u8 *)p + 8 == (u8 *)q->stat) {
+			const __be64 *addr = (const __be64 *)q->desc;
+
+			dma_unmap_page(dev, be64_to_cpu(addr[0]),
+				       ntohl(p->len[0]), DMA_TO_DEVICE);
+			dma_unmap_page(dev, be64_to_cpu(addr[1]),
+				       ntohl(p->len[1]), DMA_TO_DEVICE);
+			p = (const struct ulptx_sge_pair *)&addr[2];
+		} else {
+			const __be64 *addr = (const __be64 *)q->desc;
+
+			dma_unmap_page(dev, be64_to_cpu(p->addr[0]),
+				       ntohl(p->len[0]), DMA_TO_DEVICE);
+			dma_unmap_page(dev, be64_to_cpu(addr[0]),
+				       ntohl(p->len[1]), DMA_TO_DEVICE);
+			p = (const struct ulptx_sge_pair *)&addr[1];
+		}
+	}
+	if (nfrags) {
+		__be64 addr;
+
+		if ((u8 *)p == (u8 *)q->stat)
+			p = (const struct ulptx_sge_pair *)q->desc;
+		addr = (u8 *)p + 16 <= (u8 *)q->stat ? p->addr[0] :
+						       *(const __be64 *)q->desc;
+		dma_unmap_page(dev, be64_to_cpu(addr), ntohl(p->len[0]),
+			       DMA_TO_DEVICE);
+	}
+}
+
+/**
+ *	free_tx_desc - reclaims Tx descriptors and their buffers
+ *	@adapter: the adapter
+ *	@q: the Tx queue to reclaim descriptors from
+ *	@n: the number of descriptors to reclaim
+ *	@unmap: whether the buffers should be unmapped for DMA
+ *
+ *	Reclaims Tx descriptors from an SGE Tx queue and frees the associated
+ *	Tx buffers.  Called with the Tx queue lock held.
+ */
+static void free_tx_desc(struct adapter *adap, struct sge_txq *q,
+			 unsigned int n, bool unmap)
+{
+	struct tx_sw_desc *d;
+	unsigned int cidx = q->cidx;
+	struct device *dev = adap->pdev_dev;
+
+	d = &q->sdesc[cidx];
+	while (n--) {
+		if (d->skb) {                       /* an SGL is present */
+			if (unmap)
+				unmap_sgl(dev, d->skb, d->sgl, q);
+			kfree_skb(d->skb);
+			d->skb = NULL;
+		}
+		++d;
+		if (++cidx == q->size) {
+			cidx = 0;
+			d = q->sdesc;
+		}
+	}
+	q->cidx = cidx;
+}
+
+/*
+ * Return the number of reclaimable descriptors in a Tx queue.
+ */
+static inline int reclaimable(const struct sge_txq *q)
+{
+	int hw_cidx = ntohs(q->stat->cidx);
+	hw_cidx -= q->cidx;
+	return hw_cidx < 0 ? hw_cidx + q->size : hw_cidx;
+}
+
+/**
+ *	reclaim_completed_tx - reclaims completed Tx descriptors
+ *	@adap: the adapter
+ *	@q: the Tx queue to reclaim completed descriptors from
+ *	@unmap: whether the buffers should be unmapped for DMA
+ *
+ *	Reclaims Tx descriptors that the SGE has indicated it has processed,
+ *	and frees the associated buffers if possible.  Called with the Tx
+ *	queue locked.
+ */
+static inline void reclaim_completed_tx(struct adapter *adap, struct sge_txq *q,
+					bool unmap)
+{
+	int avail = reclaimable(q);
+
+	if (avail) {
+		/*
+		 * Limit the amount of clean up work we do at a time to keep
+		 * the Tx lock hold time O(1).
+		 */
+		if (avail > MAX_TX_RECLAIM)
+			avail = MAX_TX_RECLAIM;
+
+		free_tx_desc(adap, q, avail, unmap);
+		q->in_use -= avail;
+	}
+}
+
+static inline int get_buf_size(const struct rx_sw_desc *d)
+{
+#if FL_PG_ORDER > 0
+	return (d->dma_addr & RX_LARGE_BUF) ? (PAGE_SIZE << FL_PG_ORDER) :
+					      PAGE_SIZE;
+#else
+	return PAGE_SIZE;
+#endif
+}
+
+/**
+ *	free_rx_bufs - free the Rx buffers on an SGE free list
+ *	@adap: the adapter
+ *	@q: the SGE free list to free buffers from
+ *	@n: how many buffers to free
+ *
+ *	Release the next @n buffers on an SGE free-buffer Rx queue.   The
+ *	buffers must be made inaccessible to HW before calling this function.
+ */
+static void free_rx_bufs(struct adapter *adap, struct sge_fl *q, int n)
+{
+	while (n--) {
+		struct rx_sw_desc *d = &q->sdesc[q->cidx];
+
+		if (is_buf_mapped(d))
+			dma_unmap_page(adap->pdev_dev, get_buf_addr(d),
+				       get_buf_size(d), PCI_DMA_FROMDEVICE);
+		put_page(d->page);
+		d->page = NULL;
+		if (++q->cidx == q->size)
+			q->cidx = 0;
+		q->avail--;
+	}
+}
+
+/**
+ *	unmap_rx_buf - unmap the current Rx buffer on an SGE free list
+ *	@adap: the adapter
+ *	@q: the SGE free list
+ *
+ *	Unmap the current buffer on an SGE free-buffer Rx queue.   The
+ *	buffer must be made inaccessible to HW before calling this function.
+ *
+ *	This is similar to @free_rx_bufs above but does not free the buffer.
+ *	Do note that the FL still loses any further access to the buffer.
+ */
+static void unmap_rx_buf(struct adapter *adap, struct sge_fl *q)
+{
+	struct rx_sw_desc *d = &q->sdesc[q->cidx];
+
+	if (is_buf_mapped(d))
+		dma_unmap_page(adap->pdev_dev, get_buf_addr(d),
+			       get_buf_size(d), PCI_DMA_FROMDEVICE);
+	d->page = NULL;
+	if (++q->cidx == q->size)
+		q->cidx = 0;
+	q->avail--;
+}
+
+static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
+{
+	if (q->pend_cred >= 8) {
+		wmb();
+		t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), DBPRIO |
+			     QID(q->cntxt_id) | PIDX(q->pend_cred / 8));
+		q->pend_cred &= 7;
+	}
+}
+
+static inline void set_rx_sw_desc(struct rx_sw_desc *sd, struct page *pg,
+				  dma_addr_t mapping)
+{
+	sd->page = pg;
+	sd->dma_addr = mapping;      /* includes size low bits */
+}
+
+/**
+ *	refill_fl - refill an SGE Rx buffer ring
+ *	@adap: the adapter
+ *	@q: the ring to refill
+ *	@n: the number of new buffers to allocate
+ *	@gfp: the gfp flags for the allocations
+ *
+ *	(Re)populate an SGE free-buffer queue with up to @n new packet buffers,
+ *	allocated with the supplied gfp flags.  The caller must assure that
+ *	@n does not exceed the queue's capacity.  If afterwards the queue is
+ *	found critically low mark it as starving in the bitmap of starving FLs.
+ *
+ *	Returns the number of buffers allocated.
+ */
+static unsigned int refill_fl(struct adapter *adap, struct sge_fl *q, int n,
+			      gfp_t gfp)
+{
+	struct page *pg;
+	dma_addr_t mapping;
+	unsigned int cred = q->avail;
+	__be64 *d = &q->desc[q->pidx];
+	struct rx_sw_desc *sd = &q->sdesc[q->pidx];
+
+	gfp |= __GFP_NOWARN;         /* failures are expected */
+
+#if FL_PG_ORDER > 0
+	/*
+	 * Prefer large buffers
+	 */
+	while (n) {
+		pg = alloc_pages(gfp | __GFP_COMP, FL_PG_ORDER);
+		if (unlikely(!pg)) {
+			q->large_alloc_failed++;
+			break;       /* fall back to single pages */
+		}
+
+		mapping = dma_map_page(adap->pdev_dev, pg, 0,
+				       PAGE_SIZE << FL_PG_ORDER,
+				       PCI_DMA_FROMDEVICE);
+		if (unlikely(dma_mapping_error(adap->pdev_dev, mapping))) {
+			__free_pages(pg, FL_PG_ORDER);
+			goto out;   /* do not try small pages for this error */
+		}
+		mapping |= RX_LARGE_BUF;
+		*d++ = cpu_to_be64(mapping);
+
+		set_rx_sw_desc(sd, pg, mapping);
+		sd++;
+
+		q->avail++;
+		if (++q->pidx == q->size) {
+			q->pidx = 0;
+			sd = q->sdesc;
+			d = q->desc;
+		}
+		n--;
+	}
+#endif
+
+	while (n--) {
+		pg = __netdev_alloc_page(adap->port[0], gfp);
+		if (unlikely(!pg)) {
+			q->alloc_failed++;
+			break;
+		}
+
+		mapping = dma_map_page(adap->pdev_dev, pg, 0, PAGE_SIZE,
+				       PCI_DMA_FROMDEVICE);
+		if (unlikely(dma_mapping_error(adap->pdev_dev, mapping))) {
+			netdev_free_page(adap->port[0], pg);
+			goto out;
+		}
+		*d++ = cpu_to_be64(mapping);
+
+		set_rx_sw_desc(sd, pg, mapping);
+		sd++;
+
+		q->avail++;
+		if (++q->pidx == q->size) {
+			q->pidx = 0;
+			sd = q->sdesc;
+			d = q->desc;
+		}
+	}
+
+out:	cred = q->avail - cred;
+	q->pend_cred += cred;
+	ring_fl_db(adap, q);
+
+	if (unlikely(fl_starving(q))) {
+		smp_wmb();
+		set_bit(q->cntxt_id, adap->sge.starving_fl);
+	}
+
+	return cred;
+}
+
+static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl)
+{
+	refill_fl(adap, fl, min(MAX_RX_REFILL, fl_cap(fl) - fl->avail),
+		  GFP_ATOMIC);
+}
+
+/**
+ *	alloc_ring - allocate resources for an SGE descriptor ring
+ *	@dev: the PCI device's core device
+ *	@nelem: the number of descriptors
+ *	@elem_size: the size of each descriptor
+ *	@sw_size: the size of the SW state associated with each ring element
+ *	@phys: the physical address of the allocated ring
+ *	@metadata: address of the array holding the SW state for the ring
+ *	@stat_size: extra space in HW ring for status information
+ *
+ *	Allocates resources for an SGE descriptor ring, such as Tx queues,
+ *	free buffer lists, or response queues.  Each SGE ring requires
+ *	space for its HW descriptors plus, optionally, space for the SW state
+ *	associated with each HW entry (the metadata).  The function returns
+ *	three values: the virtual address for the HW ring (the return value
+ *	of the function), the bus address of the HW ring, and the address
+ *	of the SW ring.
+ */
+static void *alloc_ring(struct device *dev, size_t nelem, size_t elem_size,
+			size_t sw_size, dma_addr_t *phys, void *metadata,
+			size_t stat_size)
+{
+	size_t len = nelem * elem_size + stat_size;
+	void *s = NULL;
+	void *p = dma_alloc_coherent(dev, len, phys, GFP_KERNEL);
+
+	if (!p)
+		return NULL;
+	if (sw_size) {
+		s = kcalloc(nelem, sw_size, GFP_KERNEL);
+
+		if (!s) {
+			dma_free_coherent(dev, len, p, *phys);
+			return NULL;
+		}
+	}
+	if (metadata)
+		*(void **)metadata = s;
+	memset(p, 0, len);
+	return p;
+}
+
+/**
+ *	sgl_len - calculates the size of an SGL of the given capacity
+ *	@n: the number of SGL entries
+ *
+ *	Calculates the number of flits needed for a scatter/gather list that
+ *	can hold the given number of entries.
+ */
+static inline unsigned int sgl_len(unsigned int n)
+{
+	n--;
+	return (3 * n) / 2 + (n & 1) + 2;
+}
+
+/**
+ *	flits_to_desc - returns the num of Tx descriptors for the given flits
+ *	@n: the number of flits
+ *
+ *	Returns the number of Tx descriptors needed for the supplied number
+ *	of flits.
+ */
+static inline unsigned int flits_to_desc(unsigned int n)
+{
+	BUG_ON(n > SGE_MAX_WR_LEN / 8);
+	return DIV_ROUND_UP(n, 8);
+}
+
+/**
+ *	is_eth_imm - can an Ethernet packet be sent as immediate data?
+ *	@skb: the packet
+ *
+ *	Returns whether an Ethernet packet is small enough to fit as
+ *	immediate data.
+ */
+static inline int is_eth_imm(const struct sk_buff *skb)
+{
+	return skb->len <= MAX_IMM_TX_PKT_LEN - sizeof(struct cpl_tx_pkt);
+}
+
+/**
+ *	calc_tx_flits - calculate the number of flits for a packet Tx WR
+ *	@skb: the packet
+ *
+ *	Returns the number of flits needed for a Tx WR for the given Ethernet
+ *	packet, including the needed WR and CPL headers.
+ */
+static inline unsigned int calc_tx_flits(const struct sk_buff *skb)
+{
+	unsigned int flits;
+
+	if (is_eth_imm(skb))
+		return DIV_ROUND_UP(skb->len + sizeof(struct cpl_tx_pkt), 8);
+
+	flits = sgl_len(skb_shinfo(skb)->nr_frags + 1) + 4;
+	if (skb_shinfo(skb)->gso_size)
+		flits += 2;
+	return flits;
+}
+
+/**
+ *	calc_tx_descs - calculate the number of Tx descriptors for a packet
+ *	@skb: the packet
+ *
+ *	Returns the number of Tx descriptors needed for the given Ethernet
+ *	packet, including the needed WR and CPL headers.
+ */
+static inline unsigned int calc_tx_descs(const struct sk_buff *skb)
+{
+	return flits_to_desc(calc_tx_flits(skb));
+}
+
+/**
+ *	write_sgl - populate a scatter/gather list for a packet
+ *	@skb: the packet
+ *	@q: the Tx queue we are writing into
+ *	@sgl: starting location for writing the SGL
+ *	@end: points right after the end of the SGL
+ *	@start: start offset into skb main-body data to include in the SGL
+ *	@addr: the list of bus addresses for the SGL elements
+ *
+ *	Generates a gather list for the buffers that make up a packet.
+ *	The caller must provide adequate space for the SGL that will be written.
+ *	The SGL includes all of the packet's page fragments and the data in its
+ *	main body except for the first @start bytes.  @sgl must be 16-byte
+ *	aligned and within a Tx descriptor with available space.  @end points
+ *	right after the end of the SGL but does not account for any potential
+ *	wrap around, i.e., @end > @sgl.
+ */
+static void write_sgl(const struct sk_buff *skb, struct sge_txq *q,
+		      struct ulptx_sgl *sgl, u64 *end, unsigned int start,
+		      const dma_addr_t *addr)
+{
+	unsigned int i, len;
+	struct ulptx_sge_pair *to;
+	const struct skb_shared_info *si = skb_shinfo(skb);
+	unsigned int nfrags = si->nr_frags;
+	struct ulptx_sge_pair buf[MAX_SKB_FRAGS / 2 + 1];
+
+	len = skb_headlen(skb) - start;
+	if (likely(len)) {
+		sgl->len0 = htonl(len);
+		sgl->addr0 = cpu_to_be64(addr[0] + start);
+		nfrags++;
+	} else {
+		sgl->len0 = htonl(si->frags[0].size);
+		sgl->addr0 = cpu_to_be64(addr[1]);
+	}
+
+	sgl->cmd_nsge = htonl(ULPTX_CMD(ULP_TX_SC_DSGL) | ULPTX_NSGE(nfrags));
+	if (likely(--nfrags == 0))
+		return;
+	/*
+	 * Most of the complexity below deals with the possibility we hit the
+	 * end of the queue in the middle of writing the SGL.  For this case
+	 * only we create the SGL in a temporary buffer and then copy it.
+	 */
+	to = (u8 *)end > (u8 *)q->stat ? buf : sgl->sge;
+
+	for (i = (nfrags != si->nr_frags); nfrags >= 2; nfrags -= 2, to++) {
+		to->len[0] = cpu_to_be32(si->frags[i].size);
+		to->len[1] = cpu_to_be32(si->frags[++i].size);
+		to->addr[0] = cpu_to_be64(addr[i]);
+		to->addr[1] = cpu_to_be64(addr[++i]);
+	}
+	if (nfrags) {
+		to->len[0] = cpu_to_be32(si->frags[i].size);
+		to->len[1] = cpu_to_be32(0);
+		to->addr[0] = cpu_to_be64(addr[i + 1]);
+	}
+	if (unlikely((u8 *)end > (u8 *)q->stat)) {
+		unsigned int part0 = (u8 *)q->stat - (u8 *)sgl->sge, part1;
+
+		if (likely(part0))
+			memcpy(sgl->sge, buf, part0);
+		part1 = (u8 *)end - (u8 *)q->stat;
+		memcpy(q->desc, (u8 *)buf + part0, part1);
+		end = (void *)q->desc + part1;
+	}
+	if ((uintptr_t)end & 8)           /* 0-pad to multiple of 16 */
+		*(u64 *)end = 0;
+}
+
+/**
+ *	ring_tx_db - check and potentially ring a Tx queue's doorbell
+ *	@adap: the adapter
+ *	@q: the Tx queue
+ *	@n: number of new descriptors to give to HW
+ *
+ *	Ring the doorbel for a Tx queue.
+ */
+static inline void ring_tx_db(struct adapter *adap, struct sge_txq *q, int n)
+{
+	wmb();            /* write descriptors before telling HW */
+	t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL),
+		     QID(q->cntxt_id) | PIDX(n));
+}
+
+/**
+ *	inline_tx_skb - inline a packet's data into Tx descriptors
+ *	@skb: the packet
+ *	@q: the Tx queue where the packet will be inlined
+ *	@pos: starting position in the Tx queue where to inline the packet
+ *
+ *	Inline a packet's contents directly into Tx descriptors, starting at
+ *	the given position within the Tx DMA ring.
+ *	Most of the complexity of this operation is dealing with wrap arounds
+ *	in the middle of the packet we want to inline.
+ */
+static void inline_tx_skb(const struct sk_buff *skb, const struct sge_txq *q,
+			  void *pos)
+{
+	u64 *p;
+	int left = (void *)q->stat - pos;
+
+	if (likely(skb->len <= left)) {
+		if (likely(!skb->data_len))
+			skb_copy_from_linear_data(skb, pos, skb->len);
+		else
+			skb_copy_bits(skb, 0, pos, skb->len);
+		pos += skb->len;
+	} else {
+		skb_copy_bits(skb, 0, pos, left);
+		skb_copy_bits(skb, left, q->desc, skb->len - left);
+		pos = (void *)q->desc + (skb->len - left);
+	}
+
+	/* 0-pad to multiple of 16 */
+	p = PTR_ALIGN(pos, 8);
+	if ((uintptr_t)p & 8)
+		*p = 0;
+}
+
+/*
+ * Figure out what HW csum a packet wants and return the appropriate control
+ * bits.
+ */
+static u64 hwcsum(const struct sk_buff *skb)
+{
+	int csum_type;
+	const struct iphdr *iph = ip_hdr(skb);
+
+	if (iph->version == 4) {
+		if (iph->protocol == IPPROTO_TCP)
+			csum_type = TX_CSUM_TCPIP;
+		else if (iph->protocol == IPPROTO_UDP)
+			csum_type = TX_CSUM_UDPIP;
+		else {
+nocsum:			/*
+			 * unknown protocol, disable HW csum
+			 * and hope a bad packet is detected
+			 */
+			return TXPKT_L4CSUM_DIS;
+		}
+	} else {
+		/*
+		 * this doesn't work with extension headers
+		 */
+		const struct ipv6hdr *ip6h = (const struct ipv6hdr *)iph;
+
+		if (ip6h->nexthdr == IPPROTO_TCP)
+			csum_type = TX_CSUM_TCPIP6;
+		else if (ip6h->nexthdr == IPPROTO_UDP)
+			csum_type = TX_CSUM_UDPIP6;
+		else
+			goto nocsum;
+	}
+
+	if (likely(csum_type >= TX_CSUM_TCPIP))
+		return TXPKT_CSUM_TYPE(csum_type) |
+			TXPKT_IPHDR_LEN(skb_network_header_len(skb)) |
+			TXPKT_ETHHDR_LEN(skb_network_offset(skb) - ETH_HLEN);
+	else {
+		int start = skb_transport_offset(skb);
+
+		return TXPKT_CSUM_TYPE(csum_type) | TXPKT_CSUM_START(start) |
+			TXPKT_CSUM_LOC(start + skb->csum_offset);
+	}
+}
+
+static void eth_txq_stop(struct sge_eth_txq *q)
+{
+	netif_tx_stop_queue(q->txq);
+	q->q.stops++;
+}
+
+static inline void txq_advance(struct sge_txq *q, unsigned int n)
+{
+	q->in_use += n;
+	q->pidx += n;
+	if (q->pidx >= q->size)
+		q->pidx -= q->size;
+}
+
+/**
+ *	t4_eth_xmit - add a packet to an Ethernet Tx queue
+ *	@skb: the packet
+ *	@dev: the egress net device
+ *
+ *	Add a packet to an SGE Ethernet Tx queue.  Runs with softirqs disabled.
+ */
+netdev_tx_t t4_eth_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	u32 wr_mid;
+	u64 cntrl, *end;
+	int qidx, credits;
+	unsigned int flits, ndesc;
+	struct adapter *adap;
+	struct sge_eth_txq *q;
+	const struct port_info *pi;
+	struct fw_eth_tx_pkt_wr *wr;
+	struct cpl_tx_pkt_core *cpl;
+	const struct skb_shared_info *ssi;
+	dma_addr_t addr[MAX_SKB_FRAGS + 1];
+
+	/*
+	 * The chip min packet length is 10 octets but play safe and reject
+	 * anything shorter than an Ethernet header.
+	 */
+	if (unlikely(skb->len < ETH_HLEN)) {
+out_free:	dev_kfree_skb(skb);
+		return NETDEV_TX_OK;
+	}
+
+	pi = netdev_priv(dev);
+	adap = pi->adapter;
+	qidx = skb_get_queue_mapping(skb);
+	q = &adap->sge.ethtxq[qidx + pi->first_qset];
+
+	reclaim_completed_tx(adap, &q->q, true);
+
+	flits = calc_tx_flits(skb);
+	ndesc = flits_to_desc(flits);
+	credits = txq_avail(&q->q) - ndesc;
+
+	if (unlikely(credits < 0)) {
+		eth_txq_stop(q);
+		dev_err(adap->pdev_dev,
+			"%s: Tx ring %u full while queue awake!\n",
+			dev->name, qidx);
+		return NETDEV_TX_BUSY;
+	}
+
+	if (!is_eth_imm(skb) &&
+	    unlikely(map_skb(adap->pdev_dev, skb, addr) < 0)) {
+		q->mapping_err++;
+		goto out_free;
+	}
+
+	wr_mid = FW_WR_LEN16(DIV_ROUND_UP(flits, 2));
+	if (unlikely(credits < ETHTXQ_STOP_THRES)) {
+		eth_txq_stop(q);
+		wr_mid |= FW_WR_EQUEQ | FW_WR_EQUIQ;
+	}
+
+	wr = (void *)&q->q.desc[q->q.pidx];
+	wr->equiq_to_len16 = htonl(wr_mid);
+	wr->r3 = cpu_to_be64(0);
+	end = (u64 *)wr + flits;
+
+	ssi = skb_shinfo(skb);
+	if (ssi->gso_size) {
+		struct cpl_tx_pkt_lso *lso = (void *)wr;
+		bool v6 = (ssi->gso_type & SKB_GSO_TCPV6) != 0;
+		int l3hdr_len = skb_network_header_len(skb);
+		int eth_xtra_len = skb_network_offset(skb) - ETH_HLEN;
+
+		wr->op_immdlen = htonl(FW_WR_OP(FW_ETH_TX_PKT_WR) |
+				       FW_WR_IMMDLEN(sizeof(*lso)));
+		lso->lso_ctrl = htonl(LSO_OPCODE(CPL_TX_PKT_LSO) |
+				      LSO_FIRST_SLICE | LSO_LAST_SLICE |
+				      LSO_IPV6(v6) |
+				      LSO_ETHHDR_LEN(eth_xtra_len / 4) |
+				      LSO_IPHDR_LEN(l3hdr_len / 4) |
+				      LSO_TCPHDR_LEN(tcp_hdr(skb)->doff));
+		lso->ipid_ofst = htons(0);
+		lso->mss = htons(ssi->gso_size);
+		lso->seqno_offset = htonl(0);
+		lso->len = htonl(skb->len);
+		cpl = (void *)(lso + 1);
+		cntrl = TXPKT_CSUM_TYPE(v6 ? TX_CSUM_TCPIP6 : TX_CSUM_TCPIP) |
+			TXPKT_IPHDR_LEN(l3hdr_len) |
+			TXPKT_ETHHDR_LEN(eth_xtra_len);
+		q->tso++;
+		q->tx_cso += ssi->gso_segs;
+	} else {
+		int len;
+
+		len = is_eth_imm(skb) ? skb->len + sizeof(*cpl) : sizeof(*cpl);
+		wr->op_immdlen = htonl(FW_WR_OP(FW_ETH_TX_PKT_WR) |
+				       FW_WR_IMMDLEN(len));
+		cpl = (void *)(wr + 1);
+		if (skb->ip_summed == CHECKSUM_PARTIAL) {
+			cntrl = hwcsum(skb) | TXPKT_IPCSUM_DIS;
+			q->tx_cso++;
+		} else
+			cntrl = TXPKT_L4CSUM_DIS | TXPKT_IPCSUM_DIS;
+	}
+
+	if (vlan_tx_tag_present(skb)) {
+		q->vlan_ins++;
+		cntrl |= TXPKT_VLAN_VLD | TXPKT_VLAN(vlan_tx_tag_get(skb));
+	}
+
+	cpl->ctrl0 = htonl(TXPKT_OPCODE(CPL_TX_PKT_XT) |
+			   TXPKT_INTF(pi->tx_chan) | TXPKT_PF(0));
+	cpl->pack = htons(0);
+	cpl->len = htons(skb->len);
+	cpl->ctrl1 = cpu_to_be64(cntrl);
+
+	if (is_eth_imm(skb)) {
+		inline_tx_skb(skb, &q->q, cpl + 1);
+		dev_kfree_skb(skb);
+	} else {
+		int last_desc;
+
+		write_sgl(skb, &q->q, (struct ulptx_sgl *)(cpl + 1), end, 0,
+			  addr);
+		skb_orphan(skb);
+
+		last_desc = q->q.pidx + ndesc - 1;
+		if (last_desc >= q->q.size)
+			last_desc -= q->q.size;
+		q->q.sdesc[last_desc].skb = skb;
+		q->q.sdesc[last_desc].sgl = (struct ulptx_sgl *)(cpl + 1);
+	}
+
+	txq_advance(&q->q, ndesc);
+
+	ring_tx_db(adap, &q->q, ndesc);
+	return NETDEV_TX_OK;
+}
+
+/**
+ *	reclaim_completed_tx_imm - reclaim completed control-queue Tx descs
+ *	@q: the SGE control Tx queue
+ *
+ *	This is a variant of reclaim_completed_tx() that is used for Tx queues
+ *	that send only immediate data (presently just the control queues) and
+ *	thus do not have any sk_buffs to release.
+ */
+static inline void reclaim_completed_tx_imm(struct sge_txq *q)
+{
+	int hw_cidx = ntohs(q->stat->cidx);
+	int reclaim = hw_cidx - q->cidx;
+
+	if (reclaim < 0)
+		reclaim += q->size;
+
+	q->in_use -= reclaim;
+	q->cidx = hw_cidx;
+}
+
+/**
+ *	is_imm - check whether a packet can be sent as immediate data
+ *	@skb: the packet
+ *
+ *	Returns true if a packet can be sent as a WR with immediate data.
+ */
+static inline int is_imm(const struct sk_buff *skb)
+{
+	return skb->len <= MAX_CTRL_WR_LEN;
+}
+
+/**
+ *	ctrlq_check_stop - check if a control queue is full and should stop
+ *	@q: the queue
+ *	@wr: most recent WR written to the queue
+ *
+ *	Check if a control queue has become full and should be stopped.
+ *	We clean up control queue descriptors very lazily, only when we are out.
+ *	If the queue is still full after reclaiming any completed descriptors
+ *	we suspend it and have the last WR wake it up.
+ */
+static void ctrlq_check_stop(struct sge_ctrl_txq *q, struct fw_wr_hdr *wr)
+{
+	reclaim_completed_tx_imm(&q->q);
+	if (unlikely(txq_avail(&q->q) < TXQ_STOP_THRES)) {
+		wr->lo |= htonl(FW_WR_EQUEQ | FW_WR_EQUIQ);
+		q->q.stops++;
+		q->full = 1;
+	}
+}
+
+/**
+ *	ctrl_xmit - send a packet through an SGE control Tx queue
+ *	@q: the control queue
+ *	@skb: the packet
+ *
+ *	Send a packet through an SGE control Tx queue.  Packets sent through
+ *	a control queue must fit entirely as immediate data.
+ */
+static int ctrl_xmit(struct sge_ctrl_txq *q, struct sk_buff *skb)
+{
+	unsigned int ndesc;
+	struct fw_wr_hdr *wr;
+
+	if (unlikely(!is_imm(skb))) {
+		WARN_ON(1);
+		dev_kfree_skb(skb);
+		return NET_XMIT_DROP;
+	}
+
+	ndesc = DIV_ROUND_UP(skb->len, sizeof(struct tx_desc));
+	spin_lock(&q->sendq.lock);
+
+	if (unlikely(q->full)) {
+		skb->priority = ndesc;                  /* save for restart */
+		__skb_queue_tail(&q->sendq, skb);
+		spin_unlock(&q->sendq.lock);
+		return NET_XMIT_CN;
+	}
+
+	wr = (struct fw_wr_hdr *)&q->q.desc[q->q.pidx];
+	inline_tx_skb(skb, &q->q, wr);
+
+	txq_advance(&q->q, ndesc);
+	if (unlikely(txq_avail(&q->q) < TXQ_STOP_THRES))
+		ctrlq_check_stop(q, wr);
+
+	ring_tx_db(q->adap, &q->q, ndesc);
+	spin_unlock(&q->sendq.lock);
+
+	kfree_skb(skb);
+	return NET_XMIT_SUCCESS;
+}
+
+/**
+ *	restart_ctrlq - restart a suspended control queue
+ *	@data: the control queue to restart
+ *
+ *	Resumes transmission on a suspended Tx control queue.
+ */
+static void restart_ctrlq(unsigned long data)
+{
+	struct sk_buff *skb;
+	unsigned int written = 0;
+	struct sge_ctrl_txq *q = (struct sge_ctrl_txq *)data;
+
+	spin_lock(&q->sendq.lock);
+	reclaim_completed_tx_imm(&q->q);
+	BUG_ON(txq_avail(&q->q) < TXQ_STOP_THRES);  /* q should be empty */
+
+	while ((skb = __skb_dequeue(&q->sendq)) != NULL) {
+		struct fw_wr_hdr *wr;
+		unsigned int ndesc = skb->priority;     /* previously saved */
+
+		/*
+		 * Write descriptors and free skbs outside the lock to limit
+		 * wait times.  q->full is still set so new skbs will be queued.
+		 */
+		spin_unlock(&q->sendq.lock);
+
+		wr = (struct fw_wr_hdr *)&q->q.desc[q->q.pidx];
+		inline_tx_skb(skb, &q->q, wr);
+		kfree_skb(skb);
+
+		written += ndesc;
+		txq_advance(&q->q, ndesc);
+		if (unlikely(txq_avail(&q->q) < TXQ_STOP_THRES)) {
+			unsigned long old = q->q.stops;
+
+			ctrlq_check_stop(q, wr);
+			if (q->q.stops != old) {          /* suspended anew */
+				spin_lock(&q->sendq.lock);
+				goto ringdb;
+			}
+		}
+		if (written > 16) {
+			ring_tx_db(q->adap, &q->q, written);
+			written = 0;
+		}
+		spin_lock(&q->sendq.lock);
+	}
+	q->full = 0;
+ringdb: if (written)
+		ring_tx_db(q->adap, &q->q, written);
+	spin_unlock(&q->sendq.lock);
+}
+
+/**
+ *	t4_mgmt_tx - send a management message
+ *	@adap: the adapter
+ *	@skb: the packet containing the management message
+ *
+ *	Send a management message through control queue 0.
+ */
+int t4_mgmt_tx(struct adapter *adap, struct sk_buff *skb)
+{
+	int ret;
+
+	local_bh_disable();
+	ret = ctrl_xmit(&adap->sge.ctrlq[0], skb);
+	local_bh_enable();
+	return ret;
+}
+
+/**
+ *	is_ofld_imm - check whether a packet can be sent as immediate data
+ *	@skb: the packet
+ *
+ *	Returns true if a packet can be sent as an offload WR with immediate
+ *	data.  We currently use the same limit as for Ethernet packets.
+ */
+static inline int is_ofld_imm(const struct sk_buff *skb)
+{
+	return skb->len <= MAX_IMM_TX_PKT_LEN;
+}
+
+/**
+ *	calc_tx_flits_ofld - calculate # of flits for an offload packet
+ *	@skb: the packet
+ *
+ *	Returns the number of flits needed for the given offload packet.
+ *	These packets are already fully constructed and no additional headers
+ *	will be added.
+ */
+static inline unsigned int calc_tx_flits_ofld(const struct sk_buff *skb)
+{
+	unsigned int flits, cnt;
+
+	if (is_ofld_imm(skb))
+		return DIV_ROUND_UP(skb->len, 8);
+
+	flits = skb_transport_offset(skb) / 8U;   /* headers */
+	cnt = skb_shinfo(skb)->nr_frags;
+	if (skb->tail != skb->transport_header)
+		cnt++;
+	return flits + sgl_len(cnt);
+}
+
+/**
+ *	txq_stop_maperr - stop a Tx queue due to I/O MMU exhaustion
+ *	@adap: the adapter
+ *	@q: the queue to stop
+ *
+ *	Mark a Tx queue stopped due to I/O MMU exhaustion and resulting
+ *	inability to map packets.  A periodic timer attempts to restart
+ *	queues so marked.
+ */
+static void txq_stop_maperr(struct sge_ofld_txq *q)
+{
+	q->mapping_err++;
+	q->q.stops++;
+	set_bit(q->q.cntxt_id, q->adap->sge.txq_maperr);
+}
+
+/**
+ *	ofldtxq_stop - stop an offload Tx queue that has become full
+ *	@q: the queue to stop
+ *	@skb: the packet causing the queue to become full
+ *
+ *	Stops an offload Tx queue that has become full and modifies the packet
+ *	being written to request a wakeup.
+ */
+static void ofldtxq_stop(struct sge_ofld_txq *q, struct sk_buff *skb)
+{
+	struct fw_wr_hdr *wr = (struct fw_wr_hdr *)skb->data;
+
+	wr->lo |= htonl(FW_WR_EQUEQ | FW_WR_EQUIQ);
+	q->q.stops++;
+	q->full = 1;
+}
+
+/**
+ *	service_ofldq - restart a suspended offload queue
+ *	@q: the offload queue
+ *
+ *	Services an offload Tx queue by moving packets from its packet queue
+ *	to the HW Tx ring.  The function starts and ends with the queue locked.
+ */
+static void service_ofldq(struct sge_ofld_txq *q)
+{
+	u64 *pos;
+	int credits;
+	struct sk_buff *skb;
+	unsigned int written = 0;
+	unsigned int flits, ndesc;
+
+	while ((skb = skb_peek(&q->sendq)) != NULL && !q->full) {
+		/*
+		 * We drop the lock but leave skb on sendq, thus retaining
+		 * exclusive access to the state of the queue.
+		 */
+		spin_unlock(&q->sendq.lock);
+
+		reclaim_completed_tx(q->adap, &q->q, false);
+
+		flits = skb->priority;                /* previously saved */
+		ndesc = flits_to_desc(flits);
+		credits = txq_avail(&q->q) - ndesc;
+		BUG_ON(credits < 0);
+		if (unlikely(credits < TXQ_STOP_THRES))
+			ofldtxq_stop(q, skb);
+
+		pos = (u64 *)&q->q.desc[q->q.pidx];
+		if (is_ofld_imm(skb))
+			inline_tx_skb(skb, &q->q, pos);
+		else if (map_skb(q->adap->pdev_dev, skb,
+				 (dma_addr_t *)skb->head)) {
+			txq_stop_maperr(q);
+			spin_lock(&q->sendq.lock);
+			break;
+		} else {
+			int last_desc, hdr_len = skb_transport_offset(skb);
+
+			memcpy(pos, skb->data, hdr_len);
+			write_sgl(skb, &q->q, (void *)pos + hdr_len,
+				  pos + flits, hdr_len,
+				  (dma_addr_t *)skb->head);
+#ifdef CONFIG_NEED_DMA_MAP_STATE
+			skb->dev = q->adap->port[0];
+			skb->destructor = deferred_unmap_destructor;
+#endif
+			last_desc = q->q.pidx + ndesc - 1;
+			if (last_desc >= q->q.size)
+				last_desc -= q->q.size;
+			q->q.sdesc[last_desc].skb = skb;
+		}
+
+		txq_advance(&q->q, ndesc);
+		written += ndesc;
+		if (unlikely(written > 32)) {
+			ring_tx_db(q->adap, &q->q, written);
+			written = 0;
+		}
+
+		spin_lock(&q->sendq.lock);
+		__skb_unlink(skb, &q->sendq);
+		if (is_ofld_imm(skb))
+			kfree_skb(skb);
+	}
+	if (likely(written))
+		ring_tx_db(q->adap, &q->q, written);
+}
+
+/**
+ *	ofld_xmit - send a packet through an offload queue
+ *	@q: the Tx offload queue
+ *	@skb: the packet
+ *
+ *	Send an offload packet through an SGE offload queue.
+ */
+static int ofld_xmit(struct sge_ofld_txq *q, struct sk_buff *skb)
+{
+	skb->priority = calc_tx_flits_ofld(skb);       /* save for restart */
+	spin_lock(&q->sendq.lock);
+	__skb_queue_tail(&q->sendq, skb);
+	if (q->sendq.qlen == 1)
+		service_ofldq(q);
+	spin_unlock(&q->sendq.lock);
+	return NET_XMIT_SUCCESS;
+}
+
+/**
+ *	restart_ofldq - restart a suspended offload queue
+ *	@data: the offload queue to restart
+ *
+ *	Resumes transmission on a suspended Tx offload queue.
+ */
+static void restart_ofldq(unsigned long data)
+{
+	struct sge_ofld_txq *q = (struct sge_ofld_txq *)data;
+
+	spin_lock(&q->sendq.lock);
+	q->full = 0;            /* the queue actually is completely empty now */
+	service_ofldq(q);
+	spin_unlock(&q->sendq.lock);
+}
+
+/**
+ *	skb_txq - return the Tx queue an offload packet should use
+ *	@skb: the packet
+ *
+ *	Returns the Tx queue an offload packet should use as indicated by bits
+ *	1-15 in the packet's queue_mapping.
+ */
+static inline unsigned int skb_txq(const struct sk_buff *skb)
+{
+	return skb->queue_mapping >> 1;
+}
+
+/**
+ *	is_ctrl_pkt - return whether an offload packet is a control packet
+ *	@skb: the packet
+ *
+ *	Returns whether an offload packet should use an OFLD or a CTRL
+ *	Tx queue as indicated by bit 0 in the packet's queue_mapping.
+ */
+static inline unsigned int is_ctrl_pkt(const struct sk_buff *skb)
+{
+	return skb->queue_mapping & 1;
+}
+
+static inline int ofld_send(struct adapter *adap, struct sk_buff *skb)
+{
+	unsigned int idx = skb_txq(skb);
+
+	if (unlikely(is_ctrl_pkt(skb)))
+		return ctrl_xmit(&adap->sge.ctrlq[idx], skb);
+	return ofld_xmit(&adap->sge.ofldtxq[idx], skb);
+}
+
+/**
+ *	t4_ofld_send - send an offload packet
+ *	@adap: the adapter
+ *	@skb: the packet
+ *
+ *	Sends an offload packet.  We use the packet queue_mapping to select the
+ *	appropriate Tx queue as follows: bit 0 indicates whether the packet
+ *	should be sent as regular or control, bits 1-15 select the queue.
+ */
+int t4_ofld_send(struct adapter *adap, struct sk_buff *skb)
+{
+	int ret;
+
+	local_bh_disable();
+	ret = ofld_send(adap, skb);
+	local_bh_enable();
+	return ret;
+}
+
+/**
+ *	cxgb4_ofld_send - send an offload packet
+ *	@dev: the net device
+ *	@skb: the packet
+ *
+ *	Sends an offload packet.  This is an exported version of @t4_ofld_send,
+ *	intended for ULDs.
+ */
+int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb)
+{
+	return t4_ofld_send(netdev2adap(dev), skb);
+}
+EXPORT_SYMBOL(cxgb4_ofld_send);
+
+static inline void copy_frags(struct skb_shared_info *ssi,
+			      const struct pkt_gl *gl, unsigned int offset)
+{
+	unsigned int n;
+
+	/* usually there's just one frag */
+	ssi->frags[0].page = gl->frags[0].page;
+	ssi->frags[0].page_offset = gl->frags[0].page_offset + offset;
+	ssi->frags[0].size = gl->frags[0].size - offset;
+	ssi->nr_frags = gl->nfrags;
+	n = gl->nfrags - 1;
+	if (n)
+		memcpy(&ssi->frags[1], &gl->frags[1], n * sizeof(skb_frag_t));
+
+	/* get a reference to the last page, we don't own it */
+	get_page(gl->frags[n].page);
+}
+
+/**
+ *	cxgb4_pktgl_to_skb - build an sk_buff from a packet gather list
+ *	@gl: the gather list
+ *	@skb_len: size of sk_buff main body if it carries fragments
+ *	@pull_len: amount of data to move to the sk_buff's main body
+ *
+ *	Builds an sk_buff from the given packet gather list.  Returns the
+ *	sk_buff or %NULL if sk_buff allocation failed.
+ */
+struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl,
+				   unsigned int skb_len, unsigned int pull_len)
+{
+	struct sk_buff *skb;
+
+	/*
+	 * Below we rely on RX_COPY_THRES being less than the smallest Rx buffer
+	 * size, which is expected since buffers are at least PAGE_SIZEd.
+	 * In this case packets up to RX_COPY_THRES have only one fragment.
+	 */
+	if (gl->tot_len <= RX_COPY_THRES) {
+		skb = dev_alloc_skb(gl->tot_len);
+		if (unlikely(!skb))
+			goto out;
+		__skb_put(skb, gl->tot_len);
+		skb_copy_to_linear_data(skb, gl->va, gl->tot_len);
+	} else {
+		skb = dev_alloc_skb(skb_len);
+		if (unlikely(!skb))
+			goto out;
+		__skb_put(skb, pull_len);
+		skb_copy_to_linear_data(skb, gl->va, pull_len);
+
+		copy_frags(skb_shinfo(skb), gl, pull_len);
+		skb->len = gl->tot_len;
+		skb->data_len = skb->len - pull_len;
+		skb->truesize += skb->data_len;
+	}
+out:	return skb;
+}
+EXPORT_SYMBOL(cxgb4_pktgl_to_skb);
+
+/**
+ *	t4_pktgl_free - free a packet gather list
+ *	@gl: the gather list
+ *
+ *	Releases the pages of a packet gather list.  We do not own the last
+ *	page on the list and do not free it.
+ */
+void t4_pktgl_free(const struct pkt_gl *gl)
+{
+	int n;
+	const skb_frag_t *p;
+
+	for (p = gl->frags, n = gl->nfrags - 1; n--; p++)
+		put_page(p->page);
+}
+
+/*
+ * Process an MPS trace packet.  Give it an unused protocol number so it won't
+ * be delivered to anyone and send it to the stack for capture.
+ */
+static noinline int handle_trace_pkt(struct adapter *adap,
+				     const struct pkt_gl *gl)
+{
+	struct sk_buff *skb;
+	struct cpl_trace_pkt *p;
+
+	skb = cxgb4_pktgl_to_skb(gl, RX_PULL_LEN, RX_PULL_LEN);
+	if (unlikely(!skb)) {
+		t4_pktgl_free(gl);
+		return 0;
+	}
+
+	p = (struct cpl_trace_pkt *)skb->data;
+	__skb_pull(skb, sizeof(*p));
+	skb_reset_mac_header(skb);
+	skb->protocol = htons(0xffff);
+	skb->dev = adap->port[0];
+	netif_receive_skb(skb);
+	return 0;
+}
+
+static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl,
+		   const struct cpl_rx_pkt *pkt)
+{
+	int ret;
+	struct sk_buff *skb;
+
+	skb = napi_get_frags(&rxq->rspq.napi);
+	if (unlikely(!skb)) {
+		t4_pktgl_free(gl);
+		rxq->stats.rx_drops++;
+		return;
+	}
+
+	copy_frags(skb_shinfo(skb), gl, RX_PKT_PAD);
+	skb->len = gl->tot_len - RX_PKT_PAD;
+	skb->data_len = skb->len;
+	skb->truesize += skb->data_len;
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+	skb_record_rx_queue(skb, rxq->rspq.idx);
+
+	if (unlikely(pkt->vlan_ex)) {
+		struct port_info *pi = netdev_priv(rxq->rspq.netdev);
+		struct vlan_group *grp = pi->vlan_grp;
+
+		rxq->stats.vlan_ex++;
+		if (likely(grp)) {
+			ret = vlan_gro_frags(&rxq->rspq.napi, grp,
+					     ntohs(pkt->vlan));
+			goto stats;
+		}
+	}
+	ret = napi_gro_frags(&rxq->rspq.napi);
+stats:	if (ret == GRO_HELD)
+		rxq->stats.lro_pkts++;
+	else if (ret == GRO_MERGED || ret == GRO_MERGED_FREE)
+		rxq->stats.lro_merged++;
+	rxq->stats.pkts++;
+	rxq->stats.rx_cso++;
+}
+
+/**
+ *	t4_ethrx_handler - process an ingress ethernet packet
+ *	@q: the response queue that received the packet
+ *	@rsp: the response queue descriptor holding the RX_PKT message
+ *	@si: the gather list of packet fragments
+ *
+ *	Process an ingress ethernet packet and deliver it to the stack.
+ */
+int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
+		     const struct pkt_gl *si)
+{
+	bool csum_ok;
+	struct sk_buff *skb;
+	struct port_info *pi;
+	const struct cpl_rx_pkt *pkt;
+	struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq);
+
+	if (unlikely(*(u8 *)rsp == CPL_TRACE_PKT))
+		return handle_trace_pkt(q->adap, si);
+
+	pkt = (void *)&rsp[1];
+	csum_ok = pkt->csum_calc && !pkt->err_vec;
+	if ((pkt->l2info & htonl(RXF_TCP)) &&
+	    (q->netdev->features & NETIF_F_GRO) && csum_ok && !pkt->ip_frag) {
+		do_gro(rxq, si, pkt);
+		return 0;
+	}
+
+	skb = cxgb4_pktgl_to_skb(si, RX_PKT_SKB_LEN, RX_PULL_LEN);
+	if (unlikely(!skb)) {
+		t4_pktgl_free(si);
+		rxq->stats.rx_drops++;
+		return 0;
+	}
+
+	__skb_pull(skb, RX_PKT_PAD);      /* remove ethernet header padding */
+	skb->protocol = eth_type_trans(skb, q->netdev);
+	skb_record_rx_queue(skb, q->idx);
+	pi = netdev_priv(skb->dev);
+	rxq->stats.pkts++;
+
+	if (csum_ok && (pi->rx_offload & RX_CSO) &&
+	    (pkt->l2info & htonl(RXF_UDP | RXF_TCP))) {
+		if (!pkt->ip_frag)
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+		else {
+			__sum16 c = (__force __sum16)pkt->csum;
+			skb->csum = csum_unfold(c);
+			skb->ip_summed = CHECKSUM_COMPLETE;
+		}
+		rxq->stats.rx_cso++;
+	} else
+		skb->ip_summed = CHECKSUM_NONE;
+
+	if (unlikely(pkt->vlan_ex)) {
+		struct vlan_group *grp = pi->vlan_grp;
+
+		rxq->stats.vlan_ex++;
+		if (likely(grp))
+			vlan_hwaccel_receive_skb(skb, grp, ntohs(pkt->vlan));
+		else
+			dev_kfree_skb_any(skb);
+	} else
+		netif_receive_skb(skb);
+
+	return 0;
+}
+
+/**
+ *	restore_rx_bufs - put back a packet's Rx buffers
+ *	@si: the packet gather list
+ *	@q: the SGE free list
+ *	@frags: number of FL buffers to restore
+ *
+ *	Puts back on an FL the Rx buffers associated with @si.  The buffers
+ *	have already been unmapped and are left unmapped, we mark them so to
+ *	prevent further unmapping attempts.
+ *
+ *	This function undoes a series of @unmap_rx_buf calls when we find out
+ *	that the current packet can't be processed right away afterall and we
+ *	need to come back to it later.  This is a very rare event and there's
+ *	no effort to make this particularly efficient.
+ */
+static void restore_rx_bufs(const struct pkt_gl *si, struct sge_fl *q,
+			    int frags)
+{
+	struct rx_sw_desc *d;
+
+	while (frags--) {
+		if (q->cidx == 0)
+			q->cidx = q->size - 1;
+		else
+			q->cidx--;
+		d = &q->sdesc[q->cidx];
+		d->page = si->frags[frags].page;
+		d->dma_addr |= RX_UNMAPPED_BUF;
+		q->avail++;
+	}
+}
+
+/**
+ *	is_new_response - check if a response is newly written
+ *	@r: the response descriptor
+ *	@q: the response queue
+ *
+ *	Returns true if a response descriptor contains a yet unprocessed
+ *	response.
+ */
+static inline bool is_new_response(const struct rsp_ctrl *r,
+				   const struct sge_rspq *q)
+{
+	return RSPD_GEN(r->type_gen) == q->gen;
+}
+
+/**
+ *	rspq_next - advance to the next entry in a response queue
+ *	@q: the queue
+ *
+ *	Updates the state of a response queue to advance it to the next entry.
+ */
+static inline void rspq_next(struct sge_rspq *q)
+{
+	q->cur_desc = (void *)q->cur_desc + q->iqe_len;
+	if (unlikely(++q->cidx == q->size)) {
+		q->cidx = 0;
+		q->gen ^= 1;
+		q->cur_desc = q->desc;
+	}
+}
+
+/**
+ *	process_responses - process responses from an SGE response queue
+ *	@q: the ingress queue to process
+ *	@budget: how many responses can be processed in this round
+ *
+ *	Process responses from an SGE response queue up to the supplied budget.
+ *	Responses include received packets as well as control messages from FW
+ *	or HW.
+ *
+ *	Additionally choose the interrupt holdoff time for the next interrupt
+ *	on this queue.  If the system is under memory shortage use a fairly
+ *	long delay to help recovery.
+ */
+static int process_responses(struct sge_rspq *q, int budget)
+{
+	int ret, rsp_type;
+	int budget_left = budget;
+	const struct rsp_ctrl *rc;
+	struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq);
+
+	while (likely(budget_left)) {
+		rc = (void *)q->cur_desc + (q->iqe_len - sizeof(*rc));
+		if (!is_new_response(rc, q))
+			break;
+
+		rmb();
+		rsp_type = RSPD_TYPE(rc->type_gen);
+		if (likely(rsp_type == RSP_TYPE_FLBUF)) {
+			skb_frag_t *fp;
+			struct pkt_gl si;
+			const struct rx_sw_desc *rsd;
+			u32 len = ntohl(rc->pldbuflen_qid), bufsz, frags;
+
+			if (len & RSPD_NEWBUF) {
+				if (likely(q->offset > 0)) {
+					free_rx_bufs(q->adap, &rxq->fl, 1);
+					q->offset = 0;
+				}
+				len &= RSPD_LEN;
+			}
+			si.tot_len = len;
+
+			/* gather packet fragments */
+			for (frags = 0, fp = si.frags; ; frags++, fp++) {
+				rsd = &rxq->fl.sdesc[rxq->fl.cidx];
+				bufsz = get_buf_size(rsd);
+				fp->page = rsd->page;
+				fp->page_offset = q->offset;
+				fp->size = min(bufsz, len);
+				len -= fp->size;
+				if (!len)
+					break;
+				unmap_rx_buf(q->adap, &rxq->fl);
+			}
+
+			/*
+			 * Last buffer remains mapped so explicitly make it
+			 * coherent for CPU access.
+			 */
+			dma_sync_single_for_cpu(q->adap->pdev_dev,
+						get_buf_addr(rsd),
+						fp->size, DMA_FROM_DEVICE);
+
+			si.va = page_address(si.frags[0].page) +
+				si.frags[0].page_offset;
+			prefetch(si.va);
+
+			si.nfrags = frags + 1;
+			ret = q->handler(q, q->cur_desc, &si);
+			if (likely(ret == 0))
+				q->offset += ALIGN(fp->size, FL_ALIGN);
+			else
+				restore_rx_bufs(&si, &rxq->fl, frags);
+		} else if (likely(rsp_type == RSP_TYPE_CPL)) {
+			ret = q->handler(q, q->cur_desc, NULL);
+		} else {
+			ret = q->handler(q, (const __be64 *)rc, CXGB4_MSG_AN);
+		}
+
+		if (unlikely(ret)) {
+			/* couldn't process descriptor, back off for recovery */
+			q->next_intr_params = QINTR_TIMER_IDX(NOMEM_TMR_IDX);
+			break;
+		}
+
+		rspq_next(q);
+		budget_left--;
+	}
+
+	if (q->offset >= 0 && rxq->fl.size - rxq->fl.avail >= 16)
+		__refill_fl(q->adap, &rxq->fl);
+	return budget - budget_left;
+}
+
+/**
+ *	napi_rx_handler - the NAPI handler for Rx processing
+ *	@napi: the napi instance
+ *	@budget: how many packets we can process in this round
+ *
+ *	Handler for new data events when using NAPI.  This does not need any
+ *	locking or protection from interrupts as data interrupts are off at
+ *	this point and other adapter interrupts do not interfere (the latter
+ *	in not a concern at all with MSI-X as non-data interrupts then have
+ *	a separate handler).
+ */
+static int napi_rx_handler(struct napi_struct *napi, int budget)
+{
+	unsigned int params;
+	struct sge_rspq *q = container_of(napi, struct sge_rspq, napi);
+	int work_done = process_responses(q, budget);
+
+	if (likely(work_done < budget)) {
+		napi_complete(napi);
+		params = q->next_intr_params;
+		q->next_intr_params = q->intr_params;
+	} else
+		params = QINTR_TIMER_IDX(7);
+
+	t4_write_reg(q->adap, MYPF_REG(SGE_PF_GTS), CIDXINC(work_done) |
+		     INGRESSQID((u32)q->cntxt_id) | SEINTARM(params));
+	return work_done;
+}
+
+/*
+ * The MSI-X interrupt handler for an SGE response queue.
+ */
+irqreturn_t t4_sge_intr_msix(int irq, void *cookie)
+{
+	struct sge_rspq *q = cookie;
+
+	napi_schedule(&q->napi);
+	return IRQ_HANDLED;
+}
+
+/*
+ * Process the indirect interrupt entries in the interrupt queue and kick off
+ * NAPI for each queue that has generated an entry.
+ */
+static unsigned int process_intrq(struct adapter *adap)
+{
+	unsigned int credits;
+	const struct rsp_ctrl *rc;
+	struct sge_rspq *q = &adap->sge.intrq;
+
+	spin_lock(&adap->sge.intrq_lock);
+	for (credits = 0; ; credits++) {
+		rc = (void *)q->cur_desc + (q->iqe_len - sizeof(*rc));
+		if (!is_new_response(rc, q))
+			break;
+
+		rmb();
+		if (RSPD_TYPE(rc->type_gen) == RSP_TYPE_INTR) {
+			unsigned int qid = ntohl(rc->pldbuflen_qid);
+
+			napi_schedule(&adap->sge.ingr_map[qid]->napi);
+		}
+
+		rspq_next(q);
+	}
+
+	t4_write_reg(adap, MYPF_REG(SGE_PF_GTS), CIDXINC(credits) |
+		     INGRESSQID(q->cntxt_id) | SEINTARM(q->intr_params));
+	spin_unlock(&adap->sge.intrq_lock);
+	return credits;
+}
+
+/*
+ * The MSI interrupt handler, which handles data events from SGE response queues
+ * as well as error and other async events as they all use the same MSI vector.
+ */
+static irqreturn_t t4_intr_msi(int irq, void *cookie)
+{
+	struct adapter *adap = cookie;
+
+	t4_slow_intr_handler(adap);
+	process_intrq(adap);
+	return IRQ_HANDLED;
+}
+
+/*
+ * Interrupt handler for legacy INTx interrupts.
+ * Handles data events from SGE response queues as well as error and other
+ * async events as they all use the same interrupt line.
+ */
+static irqreturn_t t4_intr_intx(int irq, void *cookie)
+{
+	struct adapter *adap = cookie;
+
+	t4_write_reg(adap, MYPF_REG(PCIE_PF_CLI), 0);
+	if (t4_slow_intr_handler(adap) | process_intrq(adap))
+		return IRQ_HANDLED;
+	return IRQ_NONE;             /* probably shared interrupt */
+}
+
+/**
+ *	t4_intr_handler - select the top-level interrupt handler
+ *	@adap: the adapter
+ *
+ *	Selects the top-level interrupt handler based on the type of interrupts
+ *	(MSI-X, MSI, or INTx).
+ */
+irq_handler_t t4_intr_handler(struct adapter *adap)
+{
+	if (adap->flags & USING_MSIX)
+		return t4_sge_intr_msix;
+	if (adap->flags & USING_MSI)
+		return t4_intr_msi;
+	return t4_intr_intx;
+}
+
+static void sge_rx_timer_cb(unsigned long data)
+{
+	unsigned long m;
+	unsigned int i, cnt[2];
+	struct adapter *adap = (struct adapter *)data;
+	struct sge *s = &adap->sge;
+
+	for (i = 0; i < ARRAY_SIZE(s->starving_fl); i++)
+		for (m = s->starving_fl[i]; m; m &= m - 1) {
+			struct sge_eth_rxq *rxq;
+			unsigned int id = __ffs(m) + i * BITS_PER_LONG;
+			struct sge_fl *fl = s->egr_map[id];
+
+			clear_bit(id, s->starving_fl);
+			smp_mb__after_clear_bit();
+
+			if (fl_starving(fl)) {
+				rxq = container_of(fl, struct sge_eth_rxq, fl);
+				if (napi_reschedule(&rxq->rspq.napi))
+					fl->starving++;
+				else
+					set_bit(id, s->starving_fl);
+			}
+		}
+
+	t4_write_reg(adap, SGE_DEBUG_INDEX, 13);
+	cnt[0] = t4_read_reg(adap, SGE_DEBUG_DATA_HIGH);
+	cnt[1] = t4_read_reg(adap, SGE_DEBUG_DATA_LOW);
+
+	for (i = 0; i < 2; i++)
+		if (cnt[i] >= s->starve_thres) {
+			if (s->idma_state[i] || cnt[i] == 0xffffffff)
+				continue;
+			s->idma_state[i] = 1;
+			t4_write_reg(adap, SGE_DEBUG_INDEX, 11);
+			m = t4_read_reg(adap, SGE_DEBUG_DATA_LOW) >> (i * 16);
+			dev_warn(adap->pdev_dev,
+				 "SGE idma%u starvation detected for "
+				 "queue %lu\n", i, m & 0xffff);
+		} else if (s->idma_state[i])
+			s->idma_state[i] = 0;
+
+	mod_timer(&s->rx_timer, jiffies + RX_QCHECK_PERIOD);
+}
+
+static void sge_tx_timer_cb(unsigned long data)
+{
+	unsigned long m;
+	unsigned int i, budget;
+	struct adapter *adap = (struct adapter *)data;
+	struct sge *s = &adap->sge;
+
+	for (i = 0; i < ARRAY_SIZE(s->txq_maperr); i++)
+		for (m = s->txq_maperr[i]; m; m &= m - 1) {
+			unsigned long id = __ffs(m) + i * BITS_PER_LONG;
+			struct sge_ofld_txq *txq = s->egr_map[id];
+
+			clear_bit(id, s->txq_maperr);
+			tasklet_schedule(&txq->qresume_tsk);
+		}
+
+	budget = MAX_TIMER_TX_RECLAIM;
+	i = s->ethtxq_rover;
+	do {
+		struct sge_eth_txq *q = &s->ethtxq[i];
+
+		if (q->q.in_use &&
+		    time_after_eq(jiffies, q->txq->trans_start + HZ / 100) &&
+		    __netif_tx_trylock(q->txq)) {
+			int avail = reclaimable(&q->q);
+
+			if (avail) {
+				if (avail > budget)
+					avail = budget;
+
+				free_tx_desc(adap, &q->q, avail, true);
+				q->q.in_use -= avail;
+				budget -= avail;
+			}
+			__netif_tx_unlock(q->txq);
+		}
+
+		if (++i >= s->ethqsets)
+			i = 0;
+	} while (budget && i != s->ethtxq_rover);
+	s->ethtxq_rover = i;
+	mod_timer(&s->tx_timer, jiffies + (budget ? TX_QCHECK_PERIOD : 2));
+}
+
+int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
+		     struct net_device *dev, int intr_idx,
+		     struct sge_fl *fl, rspq_handler_t hnd)
+{
+	int ret, flsz = 0;
+	struct fw_iq_cmd c;
+	struct port_info *pi = netdev_priv(dev);
+
+	/* Size needs to be multiple of 16, including status entry. */
+	iq->size = roundup(iq->size, 16);
+
+	iq->desc = alloc_ring(adap->pdev_dev, iq->size, iq->iqe_len, 0,
+			      &iq->phys_addr, NULL, 0);
+	if (!iq->desc)
+		return -ENOMEM;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST |
+			    FW_CMD_WRITE | FW_CMD_EXEC |
+			    FW_IQ_CMD_PFN(0) | FW_IQ_CMD_VFN(0));
+	c.alloc_to_len16 = htonl(FW_IQ_CMD_ALLOC | FW_IQ_CMD_IQSTART(1) |
+				 FW_LEN16(c));
+	c.type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE(FW_IQ_TYPE_FL_INT_CAP) |
+		FW_IQ_CMD_IQASYNCH(fwevtq) | FW_IQ_CMD_VIID(pi->viid) |
+		FW_IQ_CMD_IQANDST(intr_idx < 0) | FW_IQ_CMD_IQANUD(1) |
+		FW_IQ_CMD_IQANDSTINDEX(intr_idx >= 0 ? intr_idx :
+							-intr_idx - 1));
+	c.iqdroprss_to_iqesize = htons(FW_IQ_CMD_IQPCIECH(pi->tx_chan) |
+		FW_IQ_CMD_IQGTSMODE |
+		FW_IQ_CMD_IQINTCNTTHRESH(iq->pktcnt_idx) |
+		FW_IQ_CMD_IQESIZE(ilog2(iq->iqe_len) - 4));
+	c.iqsize = htons(iq->size);
+	c.iqaddr = cpu_to_be64(iq->phys_addr);
+
+	if (fl) {
+		fl->size = roundup(fl->size, 8);
+		fl->desc = alloc_ring(adap->pdev_dev, fl->size, sizeof(__be64),
+				      sizeof(struct rx_sw_desc), &fl->addr,
+				      &fl->sdesc, STAT_LEN);
+		if (!fl->desc)
+			goto fl_nomem;
+
+		flsz = fl->size / 8 + STAT_LEN / sizeof(struct tx_desc);
+		c.iqns_to_fl0congen = htonl(FW_IQ_CMD_FL0PACKEN |
+					    FW_IQ_CMD_FL0PADEN);
+		c.fl0dcaen_to_fl0cidxfthresh = htons(FW_IQ_CMD_FL0FBMIN(2) |
+				FW_IQ_CMD_FL0FBMAX(3));
+		c.fl0size = htons(flsz);
+		c.fl0addr = cpu_to_be64(fl->addr);
+	}
+
+	ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
+	if (ret)
+		goto err;
+
+	netif_napi_add(dev, &iq->napi, napi_rx_handler, 64);
+	iq->cur_desc = iq->desc;
+	iq->cidx = 0;
+	iq->gen = 1;
+	iq->next_intr_params = iq->intr_params;
+	iq->cntxt_id = ntohs(c.iqid);
+	iq->abs_id = ntohs(c.physiqid);
+	iq->size--;                           /* subtract status entry */
+	iq->adap = adap;
+	iq->netdev = dev;
+	iq->handler = hnd;
+
+	/* set offset to -1 to distinguish ingress queues without FL */
+	iq->offset = fl ? 0 : -1;
+
+	adap->sge.ingr_map[iq->cntxt_id] = iq;
+
+	if (fl) {
+		fl->cntxt_id = htons(c.fl0id);
+		fl->avail = fl->pend_cred = 0;
+		fl->pidx = fl->cidx = 0;
+		fl->alloc_failed = fl->large_alloc_failed = fl->starving = 0;
+		adap->sge.egr_map[fl->cntxt_id] = fl;
+		refill_fl(adap, fl, fl_cap(fl), GFP_KERNEL);
+	}
+	return 0;
+
+fl_nomem:
+	ret = -ENOMEM;
+err:
+	if (iq->desc) {
+		dma_free_coherent(adap->pdev_dev, iq->size * iq->iqe_len,
+				  iq->desc, iq->phys_addr);
+		iq->desc = NULL;
+	}
+	if (fl && fl->desc) {
+		kfree(fl->sdesc);
+		fl->sdesc = NULL;
+		dma_free_coherent(adap->pdev_dev, flsz * sizeof(struct tx_desc),
+				  fl->desc, fl->addr);
+		fl->desc = NULL;
+	}
+	return ret;
+}
+
+static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id)
+{
+	q->in_use = 0;
+	q->cidx = q->pidx = 0;
+	q->stops = q->restarts = 0;
+	q->stat = (void *)&q->desc[q->size];
+	q->cntxt_id = id;
+	adap->sge.egr_map[id] = q;
+}
+
+int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
+			 struct net_device *dev, struct netdev_queue *netdevq,
+			 unsigned int iqid)
+{
+	int ret, nentries;
+	struct fw_eq_eth_cmd c;
+	struct port_info *pi = netdev_priv(dev);
+
+	/* Add status entries */
+	nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc);
+
+	txq->q.desc = alloc_ring(adap->pdev_dev, txq->q.size,
+			sizeof(struct tx_desc), sizeof(struct tx_sw_desc),
+			&txq->q.phys_addr, &txq->q.sdesc, STAT_LEN);
+	if (!txq->q.desc)
+		return -ENOMEM;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_ETH_CMD) | FW_CMD_REQUEST |
+			    FW_CMD_WRITE | FW_CMD_EXEC |
+			    FW_EQ_ETH_CMD_PFN(0) | FW_EQ_ETH_CMD_VFN(0));
+	c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_ALLOC |
+				 FW_EQ_ETH_CMD_EQSTART | FW_LEN16(c));
+	c.viid_pkd = htonl(FW_EQ_ETH_CMD_VIID(pi->viid));
+	c.fetchszm_to_iqid = htonl(FW_EQ_ETH_CMD_HOSTFCMODE(2) |
+				   FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) |
+				   FW_EQ_ETH_CMD_IQID(iqid));
+	c.dcaen_to_eqsize = htonl(FW_EQ_ETH_CMD_FBMIN(2) |
+				  FW_EQ_ETH_CMD_FBMAX(3) |
+				  FW_EQ_ETH_CMD_CIDXFTHRESH(5) |
+				  FW_EQ_ETH_CMD_EQSIZE(nentries));
+	c.eqaddr = cpu_to_be64(txq->q.phys_addr);
+
+	ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
+	if (ret) {
+		kfree(txq->q.sdesc);
+		txq->q.sdesc = NULL;
+		dma_free_coherent(adap->pdev_dev,
+				  nentries * sizeof(struct tx_desc),
+				  txq->q.desc, txq->q.phys_addr);
+		txq->q.desc = NULL;
+		return ret;
+	}
+
+	init_txq(adap, &txq->q, FW_EQ_ETH_CMD_EQID_GET(ntohl(c.eqid_pkd)));
+	txq->txq = netdevq;
+	txq->tso = txq->tx_cso = txq->vlan_ins = 0;
+	txq->mapping_err = 0;
+	return 0;
+}
+
+int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq,
+			  struct net_device *dev, unsigned int iqid,
+			  unsigned int cmplqid)
+{
+	int ret, nentries;
+	struct fw_eq_ctrl_cmd c;
+	struct port_info *pi = netdev_priv(dev);
+
+	/* Add status entries */
+	nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc);
+
+	txq->q.desc = alloc_ring(adap->pdev_dev, nentries,
+				 sizeof(struct tx_desc), 0, &txq->q.phys_addr,
+				 NULL, 0);
+	if (!txq->q.desc)
+		return -ENOMEM;
+
+	c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_CTRL_CMD) | FW_CMD_REQUEST |
+			    FW_CMD_WRITE | FW_CMD_EXEC |
+			    FW_EQ_CTRL_CMD_PFN(0) | FW_EQ_CTRL_CMD_VFN(0));
+	c.alloc_to_len16 = htonl(FW_EQ_CTRL_CMD_ALLOC |
+				 FW_EQ_CTRL_CMD_EQSTART | FW_LEN16(c));
+	c.cmpliqid_eqid = htonl(FW_EQ_CTRL_CMD_CMPLIQID(cmplqid));
+	c.physeqid_pkd = htonl(0);
+	c.fetchszm_to_iqid = htonl(FW_EQ_CTRL_CMD_HOSTFCMODE(2) |
+				   FW_EQ_CTRL_CMD_PCIECHN(pi->tx_chan) |
+				   FW_EQ_CTRL_CMD_IQID(iqid));
+	c.dcaen_to_eqsize = htonl(FW_EQ_CTRL_CMD_FBMIN(2) |
+				  FW_EQ_CTRL_CMD_FBMAX(3) |
+				  FW_EQ_CTRL_CMD_CIDXFTHRESH(5) |
+				  FW_EQ_CTRL_CMD_EQSIZE(nentries));
+	c.eqaddr = cpu_to_be64(txq->q.phys_addr);
+
+	ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
+	if (ret) {
+		dma_free_coherent(adap->pdev_dev,
+				  nentries * sizeof(struct tx_desc),
+				  txq->q.desc, txq->q.phys_addr);
+		txq->q.desc = NULL;
+		return ret;
+	}
+
+	init_txq(adap, &txq->q, FW_EQ_CTRL_CMD_EQID_GET(ntohl(c.cmpliqid_eqid)));
+	txq->adap = adap;
+	skb_queue_head_init(&txq->sendq);
+	tasklet_init(&txq->qresume_tsk, restart_ctrlq, (unsigned long)txq);
+	txq->full = 0;
+	return 0;
+}
+
+int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq,
+			  struct net_device *dev, unsigned int iqid)
+{
+	int ret, nentries;
+	struct fw_eq_ofld_cmd c;
+	struct port_info *pi = netdev_priv(dev);
+
+	/* Add status entries */
+	nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc);
+
+	txq->q.desc = alloc_ring(adap->pdev_dev, txq->q.size,
+			sizeof(struct tx_desc), sizeof(struct tx_sw_desc),
+			&txq->q.phys_addr, &txq->q.sdesc, STAT_LEN);
+	if (!txq->q.desc)
+		return -ENOMEM;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST |
+			    FW_CMD_WRITE | FW_CMD_EXEC |
+			    FW_EQ_OFLD_CMD_PFN(0) | FW_EQ_OFLD_CMD_VFN(0));
+	c.alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_ALLOC |
+				 FW_EQ_OFLD_CMD_EQSTART | FW_LEN16(c));
+	c.fetchszm_to_iqid = htonl(FW_EQ_OFLD_CMD_HOSTFCMODE(2) |
+				   FW_EQ_OFLD_CMD_PCIECHN(pi->tx_chan) |
+				   FW_EQ_OFLD_CMD_IQID(iqid));
+	c.dcaen_to_eqsize = htonl(FW_EQ_OFLD_CMD_FBMIN(2) |
+				  FW_EQ_OFLD_CMD_FBMAX(3) |
+				  FW_EQ_OFLD_CMD_CIDXFTHRESH(5) |
+				  FW_EQ_OFLD_CMD_EQSIZE(nentries));
+	c.eqaddr = cpu_to_be64(txq->q.phys_addr);
+
+	ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
+	if (ret) {
+		kfree(txq->q.sdesc);
+		txq->q.sdesc = NULL;
+		dma_free_coherent(adap->pdev_dev,
+				  nentries * sizeof(struct tx_desc),
+				  txq->q.desc, txq->q.phys_addr);
+		txq->q.desc = NULL;
+		return ret;
+	}
+
+	init_txq(adap, &txq->q, FW_EQ_OFLD_CMD_EQID_GET(ntohl(c.eqid_pkd)));
+	txq->adap = adap;
+	skb_queue_head_init(&txq->sendq);
+	tasklet_init(&txq->qresume_tsk, restart_ofldq, (unsigned long)txq);
+	txq->full = 0;
+	txq->mapping_err = 0;
+	return 0;
+}
+
+static void free_txq(struct adapter *adap, struct sge_txq *q)
+{
+	dma_free_coherent(adap->pdev_dev,
+			  q->size * sizeof(struct tx_desc) + STAT_LEN,
+			  q->desc, q->phys_addr);
+	q->cntxt_id = 0;
+	q->sdesc = NULL;
+	q->desc = NULL;
+}
+
+static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq,
+			 struct sge_fl *fl)
+{
+	unsigned int fl_id = fl ? fl->cntxt_id : 0xffff;
+
+	adap->sge.ingr_map[rq->cntxt_id] = NULL;
+	t4_iq_free(adap, 0, 0, 0, FW_IQ_TYPE_FL_INT_CAP, rq->cntxt_id, fl_id,
+		   0xffff);
+	dma_free_coherent(adap->pdev_dev, (rq->size + 1) * rq->iqe_len,
+			  rq->desc, rq->phys_addr);
+	netif_napi_del(&rq->napi);
+	rq->netdev = NULL;
+	rq->cntxt_id = rq->abs_id = 0;
+	rq->desc = NULL;
+
+	if (fl) {
+		free_rx_bufs(adap, fl, fl->avail);
+		dma_free_coherent(adap->pdev_dev, fl->size * 8 + STAT_LEN,
+				  fl->desc, fl->addr);
+		kfree(fl->sdesc);
+		fl->sdesc = NULL;
+		fl->cntxt_id = 0;
+		fl->desc = NULL;
+	}
+}
+
+/**
+ *	t4_free_sge_resources - free SGE resources
+ *	@adap: the adapter
+ *
+ *	Frees resources used by the SGE queue sets.
+ */
+void t4_free_sge_resources(struct adapter *adap)
+{
+	int i;
+	struct sge_eth_rxq *eq = adap->sge.ethrxq;
+	struct sge_eth_txq *etq = adap->sge.ethtxq;
+	struct sge_ofld_rxq *oq = adap->sge.ofldrxq;
+
+	/* clean up Ethernet Tx/Rx queues */
+	for (i = 0; i < adap->sge.ethqsets; i++, eq++, etq++) {
+		if (eq->rspq.desc)
+			free_rspq_fl(adap, &eq->rspq, &eq->fl);
+		if (etq->q.desc) {
+			t4_eth_eq_free(adap, 0, 0, 0, etq->q.cntxt_id);
+			free_tx_desc(adap, &etq->q, etq->q.in_use, true);
+			kfree(etq->q.sdesc);
+			free_txq(adap, &etq->q);
+		}
+	}
+
+	/* clean up RDMA and iSCSI Rx queues */
+	for (i = 0; i < adap->sge.ofldqsets; i++, oq++) {
+		if (oq->rspq.desc)
+			free_rspq_fl(adap, &oq->rspq, &oq->fl);
+	}
+	for (i = 0, oq = adap->sge.rdmarxq; i < adap->sge.rdmaqs; i++, oq++) {
+		if (oq->rspq.desc)
+			free_rspq_fl(adap, &oq->rspq, &oq->fl);
+	}
+
+	/* clean up offload Tx queues */
+	for (i = 0; i < ARRAY_SIZE(adap->sge.ofldtxq); i++) {
+		struct sge_ofld_txq *q = &adap->sge.ofldtxq[i];
+
+		if (q->q.desc) {
+			tasklet_kill(&q->qresume_tsk);
+			t4_ofld_eq_free(adap, 0, 0, 0, q->q.cntxt_id);
+			free_tx_desc(adap, &q->q, q->q.in_use, false);
+			kfree(q->q.sdesc);
+			__skb_queue_purge(&q->sendq);
+			free_txq(adap, &q->q);
+		}
+	}
+
+	/* clean up control Tx queues */
+	for (i = 0; i < ARRAY_SIZE(adap->sge.ctrlq); i++) {
+		struct sge_ctrl_txq *cq = &adap->sge.ctrlq[i];
+
+		if (cq->q.desc) {
+			tasklet_kill(&cq->qresume_tsk);
+			t4_ctrl_eq_free(adap, 0, 0, 0, cq->q.cntxt_id);
+			__skb_queue_purge(&cq->sendq);
+			free_txq(adap, &cq->q);
+		}
+	}
+
+	if (adap->sge.fw_evtq.desc)
+		free_rspq_fl(adap, &adap->sge.fw_evtq, NULL);
+
+	if (adap->sge.intrq.desc)
+		free_rspq_fl(adap, &adap->sge.intrq, NULL);
+
+	/* clear the reverse egress queue map */
+	memset(adap->sge.egr_map, 0, sizeof(adap->sge.egr_map));
+}
+
+void t4_sge_start(struct adapter *adap)
+{
+	adap->sge.ethtxq_rover = 0;
+	mod_timer(&adap->sge.rx_timer, jiffies + RX_QCHECK_PERIOD);
+	mod_timer(&adap->sge.tx_timer, jiffies + TX_QCHECK_PERIOD);
+}
+
+/**
+ *	t4_sge_stop - disable SGE operation
+ *	@adap: the adapter
+ *
+ *	Stop tasklets and timers associated with the DMA engine.  Note that
+ *	this is effective only if measures have been taken to disable any HW
+ *	events that may restart them.
+ */
+void t4_sge_stop(struct adapter *adap)
+{
+	int i;
+	struct sge *s = &adap->sge;
+
+	if (in_interrupt())  /* actions below require waiting */
+		return;
+
+	if (s->rx_timer.function)
+		del_timer_sync(&s->rx_timer);
+	if (s->tx_timer.function)
+		del_timer_sync(&s->tx_timer);
+
+	for (i = 0; i < ARRAY_SIZE(s->ofldtxq); i++) {
+		struct sge_ofld_txq *q = &s->ofldtxq[i];
+
+		if (q->q.desc)
+			tasklet_kill(&q->qresume_tsk);
+	}
+	for (i = 0; i < ARRAY_SIZE(s->ctrlq); i++) {
+		struct sge_ctrl_txq *cq = &s->ctrlq[i];
+
+		if (cq->q.desc)
+			tasklet_kill(&cq->qresume_tsk);
+	}
+}
+
+/**
+ *	t4_sge_init - initialize SGE
+ *	@adap: the adapter
+ *
+ *	Performs SGE initialization needed every time after a chip reset.
+ *	We do not initialize any of the queues here, instead the driver
+ *	top-level must request them individually.
+ */
+void t4_sge_init(struct adapter *adap)
+{
+	struct sge *s = &adap->sge;
+	unsigned int fl_align_log = ilog2(FL_ALIGN);
+
+	t4_set_reg_field(adap, SGE_CONTROL, PKTSHIFT_MASK |
+			 INGPADBOUNDARY_MASK | EGRSTATUSPAGESIZE,
+			 INGPADBOUNDARY(fl_align_log - 5) | PKTSHIFT(2) |
+			 RXPKTCPLMODE |
+			 (STAT_LEN == 128 ? EGRSTATUSPAGESIZE : 0));
+	t4_set_reg_field(adap, SGE_HOST_PAGE_SIZE, HOSTPAGESIZEPF0_MASK,
+			 HOSTPAGESIZEPF0(PAGE_SHIFT - 10));
+	t4_write_reg(adap, SGE_FL_BUFFER_SIZE0, PAGE_SIZE);
+#if FL_PG_ORDER > 0
+	t4_write_reg(adap, SGE_FL_BUFFER_SIZE1, PAGE_SIZE << FL_PG_ORDER);
+#endif
+	t4_write_reg(adap, SGE_INGRESS_RX_THRESHOLD,
+		     THRESHOLD_0(s->counter_val[0]) |
+		     THRESHOLD_1(s->counter_val[1]) |
+		     THRESHOLD_2(s->counter_val[2]) |
+		     THRESHOLD_3(s->counter_val[3]));
+	t4_write_reg(adap, SGE_TIMER_VALUE_0_AND_1,
+		     TIMERVALUE0(us_to_core_ticks(adap, s->timer_val[0])) |
+		     TIMERVALUE1(us_to_core_ticks(adap, s->timer_val[1])));
+	t4_write_reg(adap, SGE_TIMER_VALUE_2_AND_3,
+		     TIMERVALUE0(us_to_core_ticks(adap, s->timer_val[2])) |
+		     TIMERVALUE1(us_to_core_ticks(adap, s->timer_val[3])));
+	t4_write_reg(adap, SGE_TIMER_VALUE_4_AND_5,
+		     TIMERVALUE0(us_to_core_ticks(adap, s->timer_val[4])) |
+		     TIMERVALUE1(us_to_core_ticks(adap, s->timer_val[5])));
+	setup_timer(&s->rx_timer, sge_rx_timer_cb, (unsigned long)adap);
+	setup_timer(&s->tx_timer, sge_tx_timer_cb, (unsigned long)adap);
+	s->starve_thres = core_ticks_per_usec(adap) * 1000000;  /* 1 s */
+	s->idma_state[0] = s->idma_state[1] = 0;
+	spin_lock_init(&s->intrq_lock);
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb4/t4fw_api.h linux-libre-2.6.34-gnu1/drivers/net/cxgb4/t4fw_api.h
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb4/t4fw_api.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb4/t4fw_api.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1580 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2009-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _T4FW_INTERFACE_H_
+#define _T4FW_INTERFACE_H_
+
+#define FW_T4VF_SGE_BASE_ADDR      0x0000
+#define FW_T4VF_MPS_BASE_ADDR      0x0100
+#define FW_T4VF_PL_BASE_ADDR       0x0200
+#define FW_T4VF_MBDATA_BASE_ADDR   0x0240
+#define FW_T4VF_CIM_BASE_ADDR      0x0300
+
+enum fw_wr_opcodes {
+	FW_FILTER_WR                   = 0x02,
+	FW_ULPTX_WR                    = 0x04,
+	FW_TP_WR                       = 0x05,
+	FW_ETH_TX_PKT_WR               = 0x08,
+	FW_FLOWC_WR                    = 0x0a,
+	FW_OFLD_TX_DATA_WR             = 0x0b,
+	FW_CMD_WR                      = 0x10,
+	FW_ETH_TX_PKT_VM_WR            = 0x11,
+	FW_RI_RES_WR                   = 0x0c,
+	FW_RI_INIT_WR                  = 0x0d,
+	FW_RI_RDMA_WRITE_WR            = 0x14,
+	FW_RI_SEND_WR                  = 0x15,
+	FW_RI_RDMA_READ_WR             = 0x16,
+	FW_RI_RECV_WR                  = 0x17,
+	FW_RI_BIND_MW_WR               = 0x18,
+	FW_RI_FR_NSMR_WR               = 0x19,
+	FW_RI_INV_LSTAG_WR             = 0x1a,
+	FW_LASTC2E_WR                  = 0x40
+};
+
+struct fw_wr_hdr {
+	__be32 hi;
+	__be32 lo;
+};
+
+#define FW_WR_OP(x)	 ((x) << 24)
+#define FW_WR_ATOMIC(x)	 ((x) << 23)
+#define FW_WR_FLUSH(x)   ((x) << 22)
+#define FW_WR_COMPL(x)   ((x) << 21)
+#define FW_WR_IMMDLEN(x) ((x) << 0)
+
+#define FW_WR_EQUIQ	(1U << 31)
+#define FW_WR_EQUEQ	(1U << 30)
+#define FW_WR_FLOWID(x)	((x) << 8)
+#define FW_WR_LEN16(x)	((x) << 0)
+
+struct fw_ulptx_wr {
+	__be32 op_to_compl;
+	__be32 flowid_len16;
+	u64 cookie;
+};
+
+struct fw_tp_wr {
+	__be32 op_to_immdlen;
+	__be32 flowid_len16;
+	u64 cookie;
+};
+
+struct fw_eth_tx_pkt_wr {
+	__be32 op_immdlen;
+	__be32 equiq_to_len16;
+	__be64 r3;
+};
+
+enum fw_flowc_mnem {
+	FW_FLOWC_MNEM_PFNVFN,		/* PFN [15:8] VFN [7:0] */
+	FW_FLOWC_MNEM_CH,
+	FW_FLOWC_MNEM_PORT,
+	FW_FLOWC_MNEM_IQID,
+	FW_FLOWC_MNEM_SNDNXT,
+	FW_FLOWC_MNEM_RCVNXT,
+	FW_FLOWC_MNEM_SNDBUF,
+	FW_FLOWC_MNEM_MSS,
+};
+
+struct fw_flowc_mnemval {
+	u8 mnemonic;
+	u8 r4[3];
+	__be32 val;
+};
+
+struct fw_flowc_wr {
+	__be32 op_to_nparams;
+#define FW_FLOWC_WR_NPARAMS(x)	((x) << 0)
+	__be32 flowid_len16;
+	struct fw_flowc_mnemval mnemval[0];
+};
+
+struct fw_ofld_tx_data_wr {
+	__be32 op_to_immdlen;
+	__be32 flowid_len16;
+	__be32 plen;
+	__be32 tunnel_to_proxy;
+#define FW_OFLD_TX_DATA_WR_TUNNEL(x)	 ((x) << 19)
+#define FW_OFLD_TX_DATA_WR_SAVE(x)	 ((x) << 18)
+#define FW_OFLD_TX_DATA_WR_FLUSH(x)	 ((x) << 17)
+#define FW_OFLD_TX_DATA_WR_URGENT(x)	 ((x) << 16)
+#define FW_OFLD_TX_DATA_WR_MORE(x)	 ((x) << 15)
+#define FW_OFLD_TX_DATA_WR_SHOVE(x)	 ((x) << 14)
+#define FW_OFLD_TX_DATA_WR_ULPMODE(x)	 ((x) << 10)
+#define FW_OFLD_TX_DATA_WR_ULPSUBMODE(x) ((x) << 6)
+};
+
+struct fw_cmd_wr {
+	__be32 op_dma;
+#define FW_CMD_WR_DMA (1U << 17)
+	__be32 len16_pkd;
+	__be64 cookie_daddr;
+};
+
+struct fw_eth_tx_pkt_vm_wr {
+	__be32 op_immdlen;
+	__be32 equiq_to_len16;
+	__be32 r3[2];
+	u8 ethmacdst[6];
+	u8 ethmacsrc[6];
+	__be16 ethtype;
+	__be16 vlantci;
+};
+
+#define FW_CMD_MAX_TIMEOUT 3000
+
+enum fw_cmd_opcodes {
+	FW_LDST_CMD                    = 0x01,
+	FW_RESET_CMD                   = 0x03,
+	FW_HELLO_CMD                   = 0x04,
+	FW_BYE_CMD                     = 0x05,
+	FW_INITIALIZE_CMD              = 0x06,
+	FW_CAPS_CONFIG_CMD             = 0x07,
+	FW_PARAMS_CMD                  = 0x08,
+	FW_PFVF_CMD                    = 0x09,
+	FW_IQ_CMD                      = 0x10,
+	FW_EQ_MNGT_CMD                 = 0x11,
+	FW_EQ_ETH_CMD                  = 0x12,
+	FW_EQ_CTRL_CMD                 = 0x13,
+	FW_EQ_OFLD_CMD                 = 0x21,
+	FW_VI_CMD                      = 0x14,
+	FW_VI_MAC_CMD                  = 0x15,
+	FW_VI_RXMODE_CMD               = 0x16,
+	FW_VI_ENABLE_CMD               = 0x17,
+	FW_ACL_MAC_CMD                 = 0x18,
+	FW_ACL_VLAN_CMD                = 0x19,
+	FW_VI_STATS_CMD                = 0x1a,
+	FW_PORT_CMD                    = 0x1b,
+	FW_PORT_STATS_CMD              = 0x1c,
+	FW_PORT_LB_STATS_CMD           = 0x1d,
+	FW_PORT_TRACE_CMD              = 0x1e,
+	FW_PORT_TRACE_MMAP_CMD         = 0x1f,
+	FW_RSS_IND_TBL_CMD             = 0x20,
+	FW_RSS_GLB_CONFIG_CMD          = 0x22,
+	FW_RSS_VI_CONFIG_CMD           = 0x23,
+	FW_LASTC2E_CMD                 = 0x40,
+	FW_ERROR_CMD                   = 0x80,
+	FW_DEBUG_CMD                   = 0x81,
+};
+
+enum fw_cmd_cap {
+	FW_CMD_CAP_PF                  = 0x01,
+	FW_CMD_CAP_DMAQ                = 0x02,
+	FW_CMD_CAP_PORT                = 0x04,
+	FW_CMD_CAP_PORTPROMISC         = 0x08,
+	FW_CMD_CAP_PORTSTATS           = 0x10,
+	FW_CMD_CAP_VF                  = 0x80,
+};
+
+/*
+ * Generic command header flit0
+ */
+struct fw_cmd_hdr {
+	__be32 hi;
+	__be32 lo;
+};
+
+#define FW_CMD_OP(x)		((x) << 24)
+#define FW_CMD_OP_GET(x)        (((x) >> 24) & 0xff)
+#define FW_CMD_REQUEST          (1U << 23)
+#define FW_CMD_READ		(1U << 22)
+#define FW_CMD_WRITE		(1U << 21)
+#define FW_CMD_EXEC		(1U << 20)
+#define FW_CMD_RAMASK(x)	((x) << 20)
+#define FW_CMD_RETVAL(x)	((x) << 8)
+#define FW_CMD_RETVAL_GET(x)	(((x) >> 8) & 0xff)
+#define FW_CMD_LEN16(x)         ((x) << 0)
+
+enum fw_ldst_addrspc {
+	FW_LDST_ADDRSPC_FIRMWARE  = 0x0001,
+	FW_LDST_ADDRSPC_SGE_EGRC  = 0x0008,
+	FW_LDST_ADDRSPC_SGE_INGC  = 0x0009,
+	FW_LDST_ADDRSPC_SGE_FLMC  = 0x000a,
+	FW_LDST_ADDRSPC_SGE_CONMC = 0x000b,
+	FW_LDST_ADDRSPC_TP_PIO    = 0x0010,
+	FW_LDST_ADDRSPC_TP_TM_PIO = 0x0011,
+	FW_LDST_ADDRSPC_TP_MIB    = 0x0012,
+	FW_LDST_ADDRSPC_MDIO      = 0x0018,
+	FW_LDST_ADDRSPC_MPS       = 0x0020,
+	FW_LDST_ADDRSPC_FUNC      = 0x0028
+};
+
+enum fw_ldst_mps_fid {
+	FW_LDST_MPS_ATRB,
+	FW_LDST_MPS_RPLC
+};
+
+enum fw_ldst_func_access_ctl {
+	FW_LDST_FUNC_ACC_CTL_VIID,
+	FW_LDST_FUNC_ACC_CTL_FID
+};
+
+enum fw_ldst_func_mod_index {
+	FW_LDST_FUNC_MPS
+};
+
+struct fw_ldst_cmd {
+	__be32 op_to_addrspace;
+#define FW_LDST_CMD_ADDRSPACE(x) ((x) << 0)
+	__be32 cycles_to_len16;
+	union fw_ldst {
+		struct fw_ldst_addrval {
+			__be32 addr;
+			__be32 val;
+		} addrval;
+		struct fw_ldst_idctxt {
+			__be32 physid;
+			__be32 msg_pkd;
+			__be32 ctxt_data7;
+			__be32 ctxt_data6;
+			__be32 ctxt_data5;
+			__be32 ctxt_data4;
+			__be32 ctxt_data3;
+			__be32 ctxt_data2;
+			__be32 ctxt_data1;
+			__be32 ctxt_data0;
+		} idctxt;
+		struct fw_ldst_mdio {
+			__be16 paddr_mmd;
+			__be16 raddr;
+			__be16 vctl;
+			__be16 rval;
+		} mdio;
+		struct fw_ldst_mps {
+			__be16 fid_ctl;
+			__be16 rplcpf_pkd;
+			__be32 rplc127_96;
+			__be32 rplc95_64;
+			__be32 rplc63_32;
+			__be32 rplc31_0;
+			__be32 atrb;
+			__be16 vlan[16];
+		} mps;
+		struct fw_ldst_func {
+			u8 access_ctl;
+			u8 mod_index;
+			__be16 ctl_id;
+			__be32 offset;
+			__be64 data0;
+			__be64 data1;
+		} func;
+	} u;
+};
+
+#define FW_LDST_CMD_MSG(x)	((x) << 31)
+#define FW_LDST_CMD_PADDR(x)	((x) << 8)
+#define FW_LDST_CMD_MMD(x)	((x) << 0)
+#define FW_LDST_CMD_FID(x)	((x) << 15)
+#define FW_LDST_CMD_CTL(x)	((x) << 0)
+#define FW_LDST_CMD_RPLCPF(x)	((x) << 0)
+
+struct fw_reset_cmd {
+	__be32 op_to_write;
+	__be32 retval_len16;
+	__be32 val;
+	__be32 r3;
+};
+
+struct fw_hello_cmd {
+	__be32 op_to_write;
+	__be32 retval_len16;
+	__be32 err_to_mbasyncnot;
+#define FW_HELLO_CMD_ERR	    (1U << 31)
+#define FW_HELLO_CMD_INIT	    (1U << 30)
+#define FW_HELLO_CMD_MASTERDIS(x)   ((x) << 29)
+#define FW_HELLO_CMD_MASTERFORCE(x) ((x) << 28)
+#define FW_HELLO_CMD_MBMASTER(x)    ((x) << 24)
+#define FW_HELLO_CMD_MBASYNCNOT(x)  ((x) << 20)
+	__be32 fwrev;
+};
+
+struct fw_bye_cmd {
+	__be32 op_to_write;
+	__be32 retval_len16;
+	__be64 r3;
+};
+
+struct fw_initialize_cmd {
+	__be32 op_to_write;
+	__be32 retval_len16;
+	__be64 r3;
+};
+
+enum fw_caps_config_hm {
+	FW_CAPS_CONFIG_HM_PCIE		= 0x00000001,
+	FW_CAPS_CONFIG_HM_PL		= 0x00000002,
+	FW_CAPS_CONFIG_HM_SGE		= 0x00000004,
+	FW_CAPS_CONFIG_HM_CIM		= 0x00000008,
+	FW_CAPS_CONFIG_HM_ULPTX		= 0x00000010,
+	FW_CAPS_CONFIG_HM_TP		= 0x00000020,
+	FW_CAPS_CONFIG_HM_ULPRX		= 0x00000040,
+	FW_CAPS_CONFIG_HM_PMRX		= 0x00000080,
+	FW_CAPS_CONFIG_HM_PMTX		= 0x00000100,
+	FW_CAPS_CONFIG_HM_MC		= 0x00000200,
+	FW_CAPS_CONFIG_HM_LE		= 0x00000400,
+	FW_CAPS_CONFIG_HM_MPS		= 0x00000800,
+	FW_CAPS_CONFIG_HM_XGMAC		= 0x00001000,
+	FW_CAPS_CONFIG_HM_CPLSWITCH	= 0x00002000,
+	FW_CAPS_CONFIG_HM_T4DBG		= 0x00004000,
+	FW_CAPS_CONFIG_HM_MI		= 0x00008000,
+	FW_CAPS_CONFIG_HM_I2CM		= 0x00010000,
+	FW_CAPS_CONFIG_HM_NCSI		= 0x00020000,
+	FW_CAPS_CONFIG_HM_SMB		= 0x00040000,
+	FW_CAPS_CONFIG_HM_MA		= 0x00080000,
+	FW_CAPS_CONFIG_HM_EDRAM		= 0x00100000,
+	FW_CAPS_CONFIG_HM_PMU		= 0x00200000,
+	FW_CAPS_CONFIG_HM_UART		= 0x00400000,
+	FW_CAPS_CONFIG_HM_SF		= 0x00800000,
+};
+
+enum fw_caps_config_nbm {
+	FW_CAPS_CONFIG_NBM_IPMI		= 0x00000001,
+	FW_CAPS_CONFIG_NBM_NCSI		= 0x00000002,
+};
+
+enum fw_caps_config_link {
+	FW_CAPS_CONFIG_LINK_PPP		= 0x00000001,
+	FW_CAPS_CONFIG_LINK_QFC		= 0x00000002,
+	FW_CAPS_CONFIG_LINK_DCBX	= 0x00000004,
+};
+
+enum fw_caps_config_switch {
+	FW_CAPS_CONFIG_SWITCH_INGRESS	= 0x00000001,
+	FW_CAPS_CONFIG_SWITCH_EGRESS	= 0x00000002,
+};
+
+enum fw_caps_config_nic {
+	FW_CAPS_CONFIG_NIC		= 0x00000001,
+	FW_CAPS_CONFIG_NIC_VM		= 0x00000002,
+};
+
+enum fw_caps_config_ofld {
+	FW_CAPS_CONFIG_OFLD		= 0x00000001,
+};
+
+enum fw_caps_config_rdma {
+	FW_CAPS_CONFIG_RDMA_RDDP	= 0x00000001,
+	FW_CAPS_CONFIG_RDMA_RDMAC	= 0x00000002,
+};
+
+enum fw_caps_config_iscsi {
+	FW_CAPS_CONFIG_ISCSI_INITIATOR_PDU = 0x00000001,
+	FW_CAPS_CONFIG_ISCSI_TARGET_PDU = 0x00000002,
+	FW_CAPS_CONFIG_ISCSI_INITIATOR_CNXOFLD = 0x00000004,
+	FW_CAPS_CONFIG_ISCSI_TARGET_CNXOFLD = 0x00000008,
+};
+
+enum fw_caps_config_fcoe {
+	FW_CAPS_CONFIG_FCOE_INITIATOR	= 0x00000001,
+	FW_CAPS_CONFIG_FCOE_TARGET	= 0x00000002,
+};
+
+struct fw_caps_config_cmd {
+	__be32 op_to_write;
+	__be32 retval_len16;
+	__be32 r2;
+	__be32 hwmbitmap;
+	__be16 nbmcaps;
+	__be16 linkcaps;
+	__be16 switchcaps;
+	__be16 r3;
+	__be16 niccaps;
+	__be16 ofldcaps;
+	__be16 rdmacaps;
+	__be16 r4;
+	__be16 iscsicaps;
+	__be16 fcoecaps;
+	__be32 r5;
+	__be64 r6;
+};
+
+/*
+ * params command mnemonics
+ */
+enum fw_params_mnem {
+	FW_PARAMS_MNEM_DEV		= 1,	/* device params */
+	FW_PARAMS_MNEM_PFVF		= 2,	/* function params */
+	FW_PARAMS_MNEM_REG		= 3,	/* limited register access */
+	FW_PARAMS_MNEM_DMAQ		= 4,	/* dma queue params */
+	FW_PARAMS_MNEM_LAST
+};
+
+/*
+ * device parameters
+ */
+enum fw_params_param_dev {
+	FW_PARAMS_PARAM_DEV_CCLK	= 0x00, /* chip core clock in khz */
+	FW_PARAMS_PARAM_DEV_PORTVEC	= 0x01, /* the port vector */
+	FW_PARAMS_PARAM_DEV_NTID	= 0x02, /* reads the number of TIDs
+						 * allocated by the device's
+						 * Lookup Engine
+						 */
+	FW_PARAMS_PARAM_DEV_FLOWC_BUFFIFO_SZ = 0x03,
+	FW_PARAMS_PARAM_DEV_INTVER_NIC	= 0x04,
+	FW_PARAMS_PARAM_DEV_INTVER_VNIC = 0x05,
+	FW_PARAMS_PARAM_DEV_INTVER_OFLD = 0x06,
+	FW_PARAMS_PARAM_DEV_INTVER_RI	= 0x07,
+	FW_PARAMS_PARAM_DEV_INTVER_ISCSIPDU = 0x08,
+	FW_PARAMS_PARAM_DEV_INTVER_ISCSI = 0x09,
+	FW_PARAMS_PARAM_DEV_INTVER_FCOE = 0x0A
+};
+
+/*
+ * physical and virtual function parameters
+ */
+enum fw_params_param_pfvf {
+	FW_PARAMS_PARAM_PFVF_RWXCAPS	= 0x00,
+	FW_PARAMS_PARAM_PFVF_ROUTE_START = 0x01,
+	FW_PARAMS_PARAM_PFVF_ROUTE_END = 0x02,
+	FW_PARAMS_PARAM_PFVF_CLIP_START = 0x03,
+	FW_PARAMS_PARAM_PFVF_CLIP_END = 0x04,
+	FW_PARAMS_PARAM_PFVF_FILTER_START = 0x05,
+	FW_PARAMS_PARAM_PFVF_FILTER_END = 0x06,
+	FW_PARAMS_PARAM_PFVF_SERVER_START = 0x07,
+	FW_PARAMS_PARAM_PFVF_SERVER_END = 0x08,
+	FW_PARAMS_PARAM_PFVF_TDDP_START = 0x09,
+	FW_PARAMS_PARAM_PFVF_TDDP_END = 0x0A,
+	FW_PARAMS_PARAM_PFVF_ISCSI_START = 0x0B,
+	FW_PARAMS_PARAM_PFVF_ISCSI_END = 0x0C,
+	FW_PARAMS_PARAM_PFVF_STAG_START = 0x0D,
+	FW_PARAMS_PARAM_PFVF_STAG_END = 0x0E,
+	FW_PARAMS_PARAM_PFVF_RQ_START = 0x1F,
+	FW_PARAMS_PARAM_PFVF_RQ_END	= 0x10,
+	FW_PARAMS_PARAM_PFVF_PBL_START = 0x11,
+	FW_PARAMS_PARAM_PFVF_PBL_END	= 0x12,
+	FW_PARAMS_PARAM_PFVF_L2T_START = 0x13,
+	FW_PARAMS_PARAM_PFVF_L2T_END = 0x14,
+	FW_PARAMS_PARAM_PFVF_SCHEDCLASS_ETH = 0x20,
+};
+
+/*
+ * dma queue parameters
+ */
+enum fw_params_param_dmaq {
+	FW_PARAMS_PARAM_DMAQ_IQ_DCAEN_DCACPU = 0x00,
+	FW_PARAMS_PARAM_DMAQ_IQ_INTCNTTHRESH = 0x01,
+	FW_PARAMS_PARAM_DMAQ_EQ_CMPLIQID_MNGT = 0x10,
+	FW_PARAMS_PARAM_DMAQ_EQ_CMPLIQID_CTRL = 0x11,
+	FW_PARAMS_PARAM_DMAQ_EQ_SCHEDCLASS_ETH = 0x12,
+};
+
+#define FW_PARAMS_MNEM(x)      ((x) << 24)
+#define FW_PARAMS_PARAM_X(x)   ((x) << 16)
+#define FW_PARAMS_PARAM_Y(x)   ((x) << 8)
+#define FW_PARAMS_PARAM_Z(x)   ((x) << 0)
+#define FW_PARAMS_PARAM_XYZ(x) ((x) << 0)
+#define FW_PARAMS_PARAM_YZ(x)  ((x) << 0)
+
+struct fw_params_cmd {
+	__be32 op_to_vfn;
+	__be32 retval_len16;
+	struct fw_params_param {
+		__be32 mnem;
+		__be32 val;
+	} param[7];
+};
+
+#define FW_PARAMS_CMD_PFN(x) ((x) << 8)
+#define FW_PARAMS_CMD_VFN(x) ((x) << 0)
+
+struct fw_pfvf_cmd {
+	__be32 op_to_vfn;
+	__be32 retval_len16;
+	__be32 niqflint_niq;
+	__be32 cmask_to_neq;
+	__be32 tc_to_nexactf;
+	__be32 r_caps_to_nethctrl;
+	__be16 nricq;
+	__be16 nriqp;
+	__be32 r4;
+};
+
+#define FW_PFVF_CMD_PFN(x) ((x) << 8)
+#define FW_PFVF_CMD_VFN(x) ((x) << 0)
+
+#define FW_PFVF_CMD_NIQFLINT(x) ((x) << 20)
+#define FW_PFVF_CMD_NIQFLINT_GET(x) (((x) >> 20) & 0xfff)
+
+#define FW_PFVF_CMD_NIQ(x) ((x) << 0)
+#define FW_PFVF_CMD_NIQ_GET(x) (((x) >> 0) & 0xfffff)
+
+#define FW_PFVF_CMD_CMASK(x) ((x) << 24)
+#define FW_PFVF_CMD_CMASK_GET(x) (((x) >> 24) & 0xf)
+
+#define FW_PFVF_CMD_PMASK(x) ((x) << 20)
+#define FW_PFVF_CMD_PMASK_GET(x) (((x) >> 20) & 0xf)
+
+#define FW_PFVF_CMD_NEQ(x) ((x) << 0)
+#define FW_PFVF_CMD_NEQ_GET(x) (((x) >> 0) & 0xfffff)
+
+#define FW_PFVF_CMD_TC(x) ((x) << 24)
+#define FW_PFVF_CMD_TC_GET(x) (((x) >> 24) & 0xff)
+
+#define FW_PFVF_CMD_NVI(x) ((x) << 16)
+#define FW_PFVF_CMD_NVI_GET(x) (((x) >> 16) & 0xff)
+
+#define FW_PFVF_CMD_NEXACTF(x) ((x) << 0)
+#define FW_PFVF_CMD_NEXACTF_GET(x) (((x) >> 0) & 0xffff)
+
+#define FW_PFVF_CMD_R_CAPS(x) ((x) << 24)
+#define FW_PFVF_CMD_R_CAPS_GET(x) (((x) >> 24) & 0xff)
+
+#define FW_PFVF_CMD_WX_CAPS(x) ((x) << 16)
+#define FW_PFVF_CMD_WX_CAPS_GET(x) (((x) >> 16) & 0xff)
+
+#define FW_PFVF_CMD_NETHCTRL(x) ((x) << 0)
+#define FW_PFVF_CMD_NETHCTRL_GET(x) (((x) >> 0) & 0xffff)
+
+enum fw_iq_type {
+	FW_IQ_TYPE_FL_INT_CAP,
+	FW_IQ_TYPE_NO_FL_INT_CAP
+};
+
+struct fw_iq_cmd {
+	__be32 op_to_vfn;
+	__be32 alloc_to_len16;
+	__be16 physiqid;
+	__be16 iqid;
+	__be16 fl0id;
+	__be16 fl1id;
+	__be32 type_to_iqandstindex;
+	__be16 iqdroprss_to_iqesize;
+	__be16 iqsize;
+	__be64 iqaddr;
+	__be32 iqns_to_fl0congen;
+	__be16 fl0dcaen_to_fl0cidxfthresh;
+	__be16 fl0size;
+	__be64 fl0addr;
+	__be32 fl1cngchmap_to_fl1congen;
+	__be16 fl1dcaen_to_fl1cidxfthresh;
+	__be16 fl1size;
+	__be64 fl1addr;
+};
+
+#define FW_IQ_CMD_PFN(x) ((x) << 8)
+#define FW_IQ_CMD_VFN(x) ((x) << 0)
+
+#define FW_IQ_CMD_ALLOC (1U << 31)
+#define FW_IQ_CMD_FREE (1U << 30)
+#define FW_IQ_CMD_MODIFY (1U << 29)
+#define FW_IQ_CMD_IQSTART(x) ((x) << 28)
+#define FW_IQ_CMD_IQSTOP(x) ((x) << 27)
+
+#define FW_IQ_CMD_TYPE(x) ((x) << 29)
+#define FW_IQ_CMD_IQASYNCH(x) ((x) << 28)
+#define FW_IQ_CMD_VIID(x) ((x) << 16)
+#define FW_IQ_CMD_IQANDST(x) ((x) << 15)
+#define FW_IQ_CMD_IQANUS(x) ((x) << 14)
+#define FW_IQ_CMD_IQANUD(x) ((x) << 12)
+#define FW_IQ_CMD_IQANDSTINDEX(x) ((x) << 0)
+
+#define FW_IQ_CMD_IQDROPRSS (1U << 15)
+#define FW_IQ_CMD_IQGTSMODE (1U << 14)
+#define FW_IQ_CMD_IQPCIECH(x) ((x) << 12)
+#define FW_IQ_CMD_IQDCAEN(x) ((x) << 11)
+#define FW_IQ_CMD_IQDCACPU(x) ((x) << 6)
+#define FW_IQ_CMD_IQINTCNTTHRESH(x) ((x) << 4)
+#define FW_IQ_CMD_IQO (1U << 3)
+#define FW_IQ_CMD_IQCPRIO(x) ((x) << 2)
+#define FW_IQ_CMD_IQESIZE(x) ((x) << 0)
+
+#define FW_IQ_CMD_IQNS(x) ((x) << 31)
+#define FW_IQ_CMD_IQRO(x) ((x) << 30)
+#define FW_IQ_CMD_IQFLINTIQHSEN(x) ((x) << 28)
+#define FW_IQ_CMD_IQFLINTCONGEN(x) ((x) << 27)
+#define FW_IQ_CMD_IQFLINTISCSIC(x) ((x) << 26)
+#define FW_IQ_CMD_FL0CNGCHMAP(x) ((x) << 20)
+#define FW_IQ_CMD_FL0CACHELOCK(x) ((x) << 15)
+#define FW_IQ_CMD_FL0DBP(x) ((x) << 14)
+#define FW_IQ_CMD_FL0DATANS(x) ((x) << 13)
+#define FW_IQ_CMD_FL0DATARO(x) ((x) << 12)
+#define FW_IQ_CMD_FL0CONGCIF(x) ((x) << 11)
+#define FW_IQ_CMD_FL0ONCHIP(x) ((x) << 10)
+#define FW_IQ_CMD_FL0STATUSPGNS(x) ((x) << 9)
+#define FW_IQ_CMD_FL0STATUSPGRO(x) ((x) << 8)
+#define FW_IQ_CMD_FL0FETCHNS(x) ((x) << 7)
+#define FW_IQ_CMD_FL0FETCHRO(x) ((x) << 6)
+#define FW_IQ_CMD_FL0HOSTFCMODE(x) ((x) << 4)
+#define FW_IQ_CMD_FL0CPRIO(x) ((x) << 3)
+#define FW_IQ_CMD_FL0PADEN (1U << 2)
+#define FW_IQ_CMD_FL0PACKEN (1U << 1)
+#define FW_IQ_CMD_FL0CONGEN (1U << 0)
+
+#define FW_IQ_CMD_FL0DCAEN(x) ((x) << 15)
+#define FW_IQ_CMD_FL0DCACPU(x) ((x) << 10)
+#define FW_IQ_CMD_FL0FBMIN(x) ((x) << 7)
+#define FW_IQ_CMD_FL0FBMAX(x) ((x) << 4)
+#define FW_IQ_CMD_FL0CIDXFTHRESHO (1U << 3)
+#define FW_IQ_CMD_FL0CIDXFTHRESH(x) ((x) << 0)
+
+#define FW_IQ_CMD_FL1CNGCHMAP(x) ((x) << 20)
+#define FW_IQ_CMD_FL1CACHELOCK(x) ((x) << 15)
+#define FW_IQ_CMD_FL1DBP(x) ((x) << 14)
+#define FW_IQ_CMD_FL1DATANS(x) ((x) << 13)
+#define FW_IQ_CMD_FL1DATARO(x) ((x) << 12)
+#define FW_IQ_CMD_FL1CONGCIF(x) ((x) << 11)
+#define FW_IQ_CMD_FL1ONCHIP(x) ((x) << 10)
+#define FW_IQ_CMD_FL1STATUSPGNS(x) ((x) << 9)
+#define FW_IQ_CMD_FL1STATUSPGRO(x) ((x) << 8)
+#define FW_IQ_CMD_FL1FETCHNS(x) ((x) << 7)
+#define FW_IQ_CMD_FL1FETCHRO(x) ((x) << 6)
+#define FW_IQ_CMD_FL1HOSTFCMODE(x) ((x) << 4)
+#define FW_IQ_CMD_FL1CPRIO(x) ((x) << 3)
+#define FW_IQ_CMD_FL1PADEN (1U << 2)
+#define FW_IQ_CMD_FL1PACKEN (1U << 1)
+#define FW_IQ_CMD_FL1CONGEN (1U << 0)
+
+#define FW_IQ_CMD_FL1DCAEN(x) ((x) << 15)
+#define FW_IQ_CMD_FL1DCACPU(x) ((x) << 10)
+#define FW_IQ_CMD_FL1FBMIN(x) ((x) << 7)
+#define FW_IQ_CMD_FL1FBMAX(x) ((x) << 4)
+#define FW_IQ_CMD_FL1CIDXFTHRESHO (1U << 3)
+#define FW_IQ_CMD_FL1CIDXFTHRESH(x) ((x) << 0)
+
+struct fw_eq_eth_cmd {
+	__be32 op_to_vfn;
+	__be32 alloc_to_len16;
+	__be32 eqid_pkd;
+	__be32 physeqid_pkd;
+	__be32 fetchszm_to_iqid;
+	__be32 dcaen_to_eqsize;
+	__be64 eqaddr;
+	__be32 viid_pkd;
+	__be32 r8_lo;
+	__be64 r9;
+};
+
+#define FW_EQ_ETH_CMD_PFN(x) ((x) << 8)
+#define FW_EQ_ETH_CMD_VFN(x) ((x) << 0)
+#define FW_EQ_ETH_CMD_ALLOC (1U << 31)
+#define FW_EQ_ETH_CMD_FREE (1U << 30)
+#define FW_EQ_ETH_CMD_MODIFY (1U << 29)
+#define FW_EQ_ETH_CMD_EQSTART (1U << 28)
+#define FW_EQ_ETH_CMD_EQSTOP (1U << 27)
+
+#define FW_EQ_ETH_CMD_EQID(x) ((x) << 0)
+#define FW_EQ_ETH_CMD_EQID_GET(x) (((x) >> 0) & 0xfffff)
+#define FW_EQ_ETH_CMD_PHYSEQID(x) ((x) << 0)
+
+#define FW_EQ_ETH_CMD_FETCHSZM(x) ((x) << 26)
+#define FW_EQ_ETH_CMD_STATUSPGNS(x) ((x) << 25)
+#define FW_EQ_ETH_CMD_STATUSPGRO(x) ((x) << 24)
+#define FW_EQ_ETH_CMD_FETCHNS(x) ((x) << 23)
+#define FW_EQ_ETH_CMD_FETCHRO(x) ((x) << 22)
+#define FW_EQ_ETH_CMD_HOSTFCMODE(x) ((x) << 20)
+#define FW_EQ_ETH_CMD_CPRIO(x) ((x) << 19)
+#define FW_EQ_ETH_CMD_ONCHIP(x) ((x) << 18)
+#define FW_EQ_ETH_CMD_PCIECHN(x) ((x) << 16)
+#define FW_EQ_ETH_CMD_IQID(x) ((x) << 0)
+
+#define FW_EQ_ETH_CMD_DCAEN(x) ((x) << 31)
+#define FW_EQ_ETH_CMD_DCACPU(x) ((x) << 26)
+#define FW_EQ_ETH_CMD_FBMIN(x) ((x) << 23)
+#define FW_EQ_ETH_CMD_FBMAX(x) ((x) << 20)
+#define FW_EQ_ETH_CMD_CIDXFTHRESHO(x) ((x) << 19)
+#define FW_EQ_ETH_CMD_CIDXFTHRESH(x) ((x) << 16)
+#define FW_EQ_ETH_CMD_EQSIZE(x) ((x) << 0)
+
+#define FW_EQ_ETH_CMD_VIID(x) ((x) << 16)
+
+struct fw_eq_ctrl_cmd {
+	__be32 op_to_vfn;
+	__be32 alloc_to_len16;
+	__be32 cmpliqid_eqid;
+	__be32 physeqid_pkd;
+	__be32 fetchszm_to_iqid;
+	__be32 dcaen_to_eqsize;
+	__be64 eqaddr;
+};
+
+#define FW_EQ_CTRL_CMD_PFN(x) ((x) << 8)
+#define FW_EQ_CTRL_CMD_VFN(x) ((x) << 0)
+
+#define FW_EQ_CTRL_CMD_ALLOC (1U << 31)
+#define FW_EQ_CTRL_CMD_FREE (1U << 30)
+#define FW_EQ_CTRL_CMD_MODIFY (1U << 29)
+#define FW_EQ_CTRL_CMD_EQSTART (1U << 28)
+#define FW_EQ_CTRL_CMD_EQSTOP (1U << 27)
+
+#define FW_EQ_CTRL_CMD_CMPLIQID(x) ((x) << 20)
+#define FW_EQ_CTRL_CMD_EQID(x) ((x) << 0)
+#define FW_EQ_CTRL_CMD_EQID_GET(x) (((x) >> 0) & 0xfffff)
+#define FW_EQ_CTRL_CMD_PHYSEQID_GET(x) (((x) >> 0) & 0xfffff)
+
+#define FW_EQ_CTRL_CMD_FETCHSZM (1U << 26)
+#define FW_EQ_CTRL_CMD_STATUSPGNS (1U << 25)
+#define FW_EQ_CTRL_CMD_STATUSPGRO (1U << 24)
+#define FW_EQ_CTRL_CMD_FETCHNS (1U << 23)
+#define FW_EQ_CTRL_CMD_FETCHRO (1U << 22)
+#define FW_EQ_CTRL_CMD_HOSTFCMODE(x) ((x) << 20)
+#define FW_EQ_CTRL_CMD_CPRIO(x) ((x) << 19)
+#define FW_EQ_CTRL_CMD_ONCHIP(x) ((x) << 18)
+#define FW_EQ_CTRL_CMD_PCIECHN(x) ((x) << 16)
+#define FW_EQ_CTRL_CMD_IQID(x) ((x) << 0)
+
+#define FW_EQ_CTRL_CMD_DCAEN(x) ((x) << 31)
+#define FW_EQ_CTRL_CMD_DCACPU(x) ((x) << 26)
+#define FW_EQ_CTRL_CMD_FBMIN(x) ((x) << 23)
+#define FW_EQ_CTRL_CMD_FBMAX(x) ((x) << 20)
+#define FW_EQ_CTRL_CMD_CIDXFTHRESHO(x) ((x) << 19)
+#define FW_EQ_CTRL_CMD_CIDXFTHRESH(x) ((x) << 16)
+#define FW_EQ_CTRL_CMD_EQSIZE(x) ((x) << 0)
+
+struct fw_eq_ofld_cmd {
+	__be32 op_to_vfn;
+	__be32 alloc_to_len16;
+	__be32 eqid_pkd;
+	__be32 physeqid_pkd;
+	__be32 fetchszm_to_iqid;
+	__be32 dcaen_to_eqsize;
+	__be64 eqaddr;
+};
+
+#define FW_EQ_OFLD_CMD_PFN(x) ((x) << 8)
+#define FW_EQ_OFLD_CMD_VFN(x) ((x) << 0)
+
+#define FW_EQ_OFLD_CMD_ALLOC (1U << 31)
+#define FW_EQ_OFLD_CMD_FREE (1U << 30)
+#define FW_EQ_OFLD_CMD_MODIFY (1U << 29)
+#define FW_EQ_OFLD_CMD_EQSTART (1U << 28)
+#define FW_EQ_OFLD_CMD_EQSTOP (1U << 27)
+
+#define FW_EQ_OFLD_CMD_EQID(x) ((x) << 0)
+#define FW_EQ_OFLD_CMD_EQID_GET(x) (((x) >> 0) & 0xfffff)
+#define FW_EQ_OFLD_CMD_PHYSEQID_GET(x) (((x) >> 0) & 0xfffff)
+
+#define FW_EQ_OFLD_CMD_FETCHSZM(x) ((x) << 26)
+#define FW_EQ_OFLD_CMD_STATUSPGNS(x) ((x) << 25)
+#define FW_EQ_OFLD_CMD_STATUSPGRO(x) ((x) << 24)
+#define FW_EQ_OFLD_CMD_FETCHNS(x) ((x) << 23)
+#define FW_EQ_OFLD_CMD_FETCHRO(x) ((x) << 22)
+#define FW_EQ_OFLD_CMD_HOSTFCMODE(x) ((x) << 20)
+#define FW_EQ_OFLD_CMD_CPRIO(x) ((x) << 19)
+#define FW_EQ_OFLD_CMD_ONCHIP(x) ((x) << 18)
+#define FW_EQ_OFLD_CMD_PCIECHN(x) ((x) << 16)
+#define FW_EQ_OFLD_CMD_IQID(x) ((x) << 0)
+
+#define FW_EQ_OFLD_CMD_DCAEN(x) ((x) << 31)
+#define FW_EQ_OFLD_CMD_DCACPU(x) ((x) << 26)
+#define FW_EQ_OFLD_CMD_FBMIN(x) ((x) << 23)
+#define FW_EQ_OFLD_CMD_FBMAX(x) ((x) << 20)
+#define FW_EQ_OFLD_CMD_CIDXFTHRESHO(x) ((x) << 19)
+#define FW_EQ_OFLD_CMD_CIDXFTHRESH(x) ((x) << 16)
+#define FW_EQ_OFLD_CMD_EQSIZE(x) ((x) << 0)
+
+/*
+ * Macros for VIID parsing:
+ * VIID - [10:8] PFN, [7] VI Valid, [6:0] VI number
+ */
+#define FW_VIID_PFN_GET(x) (((x) >> 8) & 0x7)
+#define FW_VIID_VIVLD_GET(x) (((x) >> 7) & 0x1)
+#define FW_VIID_VIN_GET(x) (((x) >> 0) & 0x7F)
+
+struct fw_vi_cmd {
+	__be32 op_to_vfn;
+	__be32 alloc_to_len16;
+	__be16 viid_pkd;
+	u8 mac[6];
+	u8 portid_pkd;
+	u8 nmac;
+	u8 nmac0[6];
+	__be16 rsssize_pkd;
+	u8 nmac1[6];
+	__be16 r7;
+	u8 nmac2[6];
+	__be16 r8;
+	u8 nmac3[6];
+	__be64 r9;
+	__be64 r10;
+};
+
+#define FW_VI_CMD_PFN(x) ((x) << 8)
+#define FW_VI_CMD_VFN(x) ((x) << 0)
+#define FW_VI_CMD_ALLOC (1U << 31)
+#define FW_VI_CMD_FREE (1U << 30)
+#define FW_VI_CMD_VIID(x) ((x) << 0)
+#define FW_VI_CMD_PORTID(x) ((x) << 4)
+#define FW_VI_CMD_RSSSIZE_GET(x) (((x) >> 0) & 0x7ff)
+
+/* Special VI_MAC command index ids */
+#define FW_VI_MAC_ADD_MAC		0x3FF
+#define FW_VI_MAC_ADD_PERSIST_MAC	0x3FE
+#define FW_VI_MAC_MAC_BASED_FREE	0x3FD
+
+enum fw_vi_mac_smac {
+	FW_VI_MAC_MPS_TCAM_ENTRY,
+	FW_VI_MAC_MPS_TCAM_ONLY,
+	FW_VI_MAC_SMT_ONLY,
+	FW_VI_MAC_SMT_AND_MPSTCAM
+};
+
+enum fw_vi_mac_result {
+	FW_VI_MAC_R_SUCCESS,
+	FW_VI_MAC_R_F_NONEXISTENT_NOMEM,
+	FW_VI_MAC_R_SMAC_FAIL,
+	FW_VI_MAC_R_F_ACL_CHECK
+};
+
+struct fw_vi_mac_cmd {
+	__be32 op_to_viid;
+	__be32 freemacs_to_len16;
+	union fw_vi_mac {
+		struct fw_vi_mac_exact {
+			__be16 valid_to_idx;
+			u8 macaddr[6];
+		} exact[7];
+		struct fw_vi_mac_hash {
+			__be64 hashvec;
+		} hash;
+	} u;
+};
+
+#define FW_VI_MAC_CMD_VIID(x) ((x) << 0)
+#define FW_VI_MAC_CMD_FREEMACS(x) ((x) << 31)
+#define FW_VI_MAC_CMD_HASHVECEN (1U << 23)
+#define FW_VI_MAC_CMD_HASHUNIEN(x) ((x) << 22)
+#define FW_VI_MAC_CMD_VALID (1U << 15)
+#define FW_VI_MAC_CMD_PRIO(x) ((x) << 12)
+#define FW_VI_MAC_CMD_SMAC_RESULT(x) ((x) << 10)
+#define FW_VI_MAC_CMD_SMAC_RESULT_GET(x) (((x) >> 10) & 0x3)
+#define FW_VI_MAC_CMD_IDX(x) ((x) << 0)
+#define FW_VI_MAC_CMD_IDX_GET(x) (((x) >> 0) & 0x3ff)
+
+#define FW_RXMODE_MTU_NO_CHG	65535
+
+struct fw_vi_rxmode_cmd {
+	__be32 op_to_viid;
+	__be32 retval_len16;
+	__be32 mtu_to_broadcasten;
+	__be32 r4_lo;
+};
+
+#define FW_VI_RXMODE_CMD_VIID(x) ((x) << 0)
+#define FW_VI_RXMODE_CMD_MTU(x) ((x) << 16)
+#define FW_VI_RXMODE_CMD_PROMISCEN_MASK 0x3
+#define FW_VI_RXMODE_CMD_PROMISCEN(x) ((x) << 14)
+#define FW_VI_RXMODE_CMD_ALLMULTIEN_MASK 0x3
+#define FW_VI_RXMODE_CMD_ALLMULTIEN(x) ((x) << 12)
+#define FW_VI_RXMODE_CMD_BROADCASTEN_MASK 0x3
+#define FW_VI_RXMODE_CMD_BROADCASTEN(x) ((x) << 10)
+
+struct fw_vi_enable_cmd {
+	__be32 op_to_viid;
+	__be32 ien_to_len16;
+	__be16 blinkdur;
+	__be16 r3;
+	__be32 r4;
+};
+
+#define FW_VI_ENABLE_CMD_VIID(x) ((x) << 0)
+#define FW_VI_ENABLE_CMD_IEN(x) ((x) << 31)
+#define FW_VI_ENABLE_CMD_EEN(x) ((x) << 30)
+#define FW_VI_ENABLE_CMD_LED (1U << 29)
+
+/* VI VF stats offset definitions */
+#define VI_VF_NUM_STATS	16
+enum fw_vi_stats_vf_index {
+	FW_VI_VF_STAT_TX_BCAST_BYTES_IX,
+	FW_VI_VF_STAT_TX_BCAST_FRAMES_IX,
+	FW_VI_VF_STAT_TX_MCAST_BYTES_IX,
+	FW_VI_VF_STAT_TX_MCAST_FRAMES_IX,
+	FW_VI_VF_STAT_TX_UCAST_BYTES_IX,
+	FW_VI_VF_STAT_TX_UCAST_FRAMES_IX,
+	FW_VI_VF_STAT_TX_DROP_FRAMES_IX,
+	FW_VI_VF_STAT_TX_OFLD_BYTES_IX,
+	FW_VI_VF_STAT_TX_OFLD_FRAMES_IX,
+	FW_VI_VF_STAT_RX_BCAST_BYTES_IX,
+	FW_VI_VF_STAT_RX_BCAST_FRAMES_IX,
+	FW_VI_VF_STAT_RX_MCAST_BYTES_IX,
+	FW_VI_VF_STAT_RX_MCAST_FRAMES_IX,
+	FW_VI_VF_STAT_RX_UCAST_BYTES_IX,
+	FW_VI_VF_STAT_RX_UCAST_FRAMES_IX,
+	FW_VI_VF_STAT_RX_ERR_FRAMES_IX
+};
+
+/* VI PF stats offset definitions */
+#define VI_PF_NUM_STATS	17
+enum fw_vi_stats_pf_index {
+	FW_VI_PF_STAT_TX_BCAST_BYTES_IX,
+	FW_VI_PF_STAT_TX_BCAST_FRAMES_IX,
+	FW_VI_PF_STAT_TX_MCAST_BYTES_IX,
+	FW_VI_PF_STAT_TX_MCAST_FRAMES_IX,
+	FW_VI_PF_STAT_TX_UCAST_BYTES_IX,
+	FW_VI_PF_STAT_TX_UCAST_FRAMES_IX,
+	FW_VI_PF_STAT_TX_OFLD_BYTES_IX,
+	FW_VI_PF_STAT_TX_OFLD_FRAMES_IX,
+	FW_VI_PF_STAT_RX_BYTES_IX,
+	FW_VI_PF_STAT_RX_FRAMES_IX,
+	FW_VI_PF_STAT_RX_BCAST_BYTES_IX,
+	FW_VI_PF_STAT_RX_BCAST_FRAMES_IX,
+	FW_VI_PF_STAT_RX_MCAST_BYTES_IX,
+	FW_VI_PF_STAT_RX_MCAST_FRAMES_IX,
+	FW_VI_PF_STAT_RX_UCAST_BYTES_IX,
+	FW_VI_PF_STAT_RX_UCAST_FRAMES_IX,
+	FW_VI_PF_STAT_RX_ERR_FRAMES_IX
+};
+
+struct fw_vi_stats_cmd {
+	__be32 op_to_viid;
+	__be32 retval_len16;
+	union fw_vi_stats {
+		struct fw_vi_stats_ctl {
+			__be16 nstats_ix;
+			__be16 r6;
+			__be32 r7;
+			__be64 stat0;
+			__be64 stat1;
+			__be64 stat2;
+			__be64 stat3;
+			__be64 stat4;
+			__be64 stat5;
+		} ctl;
+		struct fw_vi_stats_pf {
+			__be64 tx_bcast_bytes;
+			__be64 tx_bcast_frames;
+			__be64 tx_mcast_bytes;
+			__be64 tx_mcast_frames;
+			__be64 tx_ucast_bytes;
+			__be64 tx_ucast_frames;
+			__be64 tx_offload_bytes;
+			__be64 tx_offload_frames;
+			__be64 rx_pf_bytes;
+			__be64 rx_pf_frames;
+			__be64 rx_bcast_bytes;
+			__be64 rx_bcast_frames;
+			__be64 rx_mcast_bytes;
+			__be64 rx_mcast_frames;
+			__be64 rx_ucast_bytes;
+			__be64 rx_ucast_frames;
+			__be64 rx_err_frames;
+		} pf;
+		struct fw_vi_stats_vf {
+			__be64 tx_bcast_bytes;
+			__be64 tx_bcast_frames;
+			__be64 tx_mcast_bytes;
+			__be64 tx_mcast_frames;
+			__be64 tx_ucast_bytes;
+			__be64 tx_ucast_frames;
+			__be64 tx_drop_frames;
+			__be64 tx_offload_bytes;
+			__be64 tx_offload_frames;
+			__be64 rx_bcast_bytes;
+			__be64 rx_bcast_frames;
+			__be64 rx_mcast_bytes;
+			__be64 rx_mcast_frames;
+			__be64 rx_ucast_bytes;
+			__be64 rx_ucast_frames;
+			__be64 rx_err_frames;
+		} vf;
+	} u;
+};
+
+#define FW_VI_STATS_CMD_VIID(x) ((x) << 0)
+#define FW_VI_STATS_CMD_NSTATS(x) ((x) << 12)
+#define FW_VI_STATS_CMD_IX(x) ((x) << 0)
+
+struct fw_acl_mac_cmd {
+	__be32 op_to_vfn;
+	__be32 en_to_len16;
+	u8 nmac;
+	u8 r3[7];
+	__be16 r4;
+	u8 macaddr0[6];
+	__be16 r5;
+	u8 macaddr1[6];
+	__be16 r6;
+	u8 macaddr2[6];
+	__be16 r7;
+	u8 macaddr3[6];
+};
+
+#define FW_ACL_MAC_CMD_PFN(x) ((x) << 8)
+#define FW_ACL_MAC_CMD_VFN(x) ((x) << 0)
+#define FW_ACL_MAC_CMD_EN(x) ((x) << 31)
+
+struct fw_acl_vlan_cmd {
+	__be32 op_to_vfn;
+	__be32 en_to_len16;
+	u8 nvlan;
+	u8 dropnovlan_fm;
+	u8 r3_lo[6];
+	__be16 vlanid[16];
+};
+
+#define FW_ACL_VLAN_CMD_PFN(x) ((x) << 8)
+#define FW_ACL_VLAN_CMD_VFN(x) ((x) << 0)
+#define FW_ACL_VLAN_CMD_EN(x) ((x) << 31)
+#define FW_ACL_VLAN_CMD_DROPNOVLAN(x) ((x) << 7)
+#define FW_ACL_VLAN_CMD_FM(x) ((x) << 6)
+
+enum fw_port_cap {
+	FW_PORT_CAP_SPEED_100M		= 0x0001,
+	FW_PORT_CAP_SPEED_1G		= 0x0002,
+	FW_PORT_CAP_SPEED_2_5G		= 0x0004,
+	FW_PORT_CAP_SPEED_10G		= 0x0008,
+	FW_PORT_CAP_SPEED_40G		= 0x0010,
+	FW_PORT_CAP_SPEED_100G		= 0x0020,
+	FW_PORT_CAP_FC_RX		= 0x0040,
+	FW_PORT_CAP_FC_TX		= 0x0080,
+	FW_PORT_CAP_ANEG		= 0x0100,
+	FW_PORT_CAP_MDI_0		= 0x0200,
+	FW_PORT_CAP_MDI_1		= 0x0400,
+	FW_PORT_CAP_BEAN		= 0x0800,
+	FW_PORT_CAP_PMA_LPBK		= 0x1000,
+	FW_PORT_CAP_PCS_LPBK		= 0x2000,
+	FW_PORT_CAP_PHYXS_LPBK		= 0x4000,
+	FW_PORT_CAP_FAR_END_LPBK	= 0x8000,
+};
+
+enum fw_port_mdi {
+	FW_PORT_MDI_UNCHANGED,
+	FW_PORT_MDI_AUTO,
+	FW_PORT_MDI_F_STRAIGHT,
+	FW_PORT_MDI_F_CROSSOVER
+};
+
+#define FW_PORT_MDI(x) ((x) << 9)
+
+enum fw_port_action {
+	FW_PORT_ACTION_L1_CFG		= 0x0001,
+	FW_PORT_ACTION_L2_CFG		= 0x0002,
+	FW_PORT_ACTION_GET_PORT_INFO	= 0x0003,
+	FW_PORT_ACTION_L2_PPP_CFG	= 0x0004,
+	FW_PORT_ACTION_L2_DCB_CFG	= 0x0005,
+	FW_PORT_ACTION_LOW_PWR_TO_NORMAL = 0x0010,
+	FW_PORT_ACTION_L1_LOW_PWR_EN	= 0x0011,
+	FW_PORT_ACTION_L2_WOL_MODE_EN	= 0x0012,
+	FW_PORT_ACTION_LPBK_TO_NORMAL	= 0x0020,
+	FW_PORT_ACTION_L1_LPBK		= 0x0021,
+	FW_PORT_ACTION_L1_PMA_LPBK	= 0x0022,
+	FW_PORT_ACTION_L1_PCS_LPBK	= 0x0023,
+	FW_PORT_ACTION_L1_PHYXS_CSIDE_LPBK = 0x0024,
+	FW_PORT_ACTION_L1_PHYXS_ESIDE_LPBK = 0x0025,
+	FW_PORT_ACTION_PHY_RESET	= 0x0040,
+	FW_PORT_ACTION_PMA_RESET	= 0x0041,
+	FW_PORT_ACTION_PCS_RESET	= 0x0042,
+	FW_PORT_ACTION_PHYXS_RESET	= 0x0043,
+	FW_PORT_ACTION_DTEXS_REEST	= 0x0044,
+	FW_PORT_ACTION_AN_RESET		= 0x0045
+};
+
+enum fw_port_l2cfg_ctlbf {
+	FW_PORT_L2_CTLBF_OVLAN0	= 0x01,
+	FW_PORT_L2_CTLBF_OVLAN1	= 0x02,
+	FW_PORT_L2_CTLBF_OVLAN2	= 0x04,
+	FW_PORT_L2_CTLBF_OVLAN3	= 0x08,
+	FW_PORT_L2_CTLBF_IVLAN	= 0x10,
+	FW_PORT_L2_CTLBF_TXIPG	= 0x20
+};
+
+enum fw_port_dcb_cfg {
+	FW_PORT_DCB_CFG_PG	= 0x01,
+	FW_PORT_DCB_CFG_PFC	= 0x02,
+	FW_PORT_DCB_CFG_APPL	= 0x04
+};
+
+enum fw_port_dcb_cfg_rc {
+	FW_PORT_DCB_CFG_SUCCESS	= 0x0,
+	FW_PORT_DCB_CFG_ERROR	= 0x1
+};
+
+struct fw_port_cmd {
+	__be32 op_to_portid;
+	__be32 action_to_len16;
+	union fw_port {
+		struct fw_port_l1cfg {
+			__be32 rcap;
+			__be32 r;
+		} l1cfg;
+		struct fw_port_l2cfg {
+			__be16 ctlbf_to_ivlan0;
+			__be16 ivlantype;
+			__be32 txipg_pkd;
+			__be16 ovlan0mask;
+			__be16 ovlan0type;
+			__be16 ovlan1mask;
+			__be16 ovlan1type;
+			__be16 ovlan2mask;
+			__be16 ovlan2type;
+			__be16 ovlan3mask;
+			__be16 ovlan3type;
+		} l2cfg;
+		struct fw_port_info {
+			__be32 lstatus_to_modtype;
+			__be16 pcap;
+			__be16 acap;
+		} info;
+		struct fw_port_ppp {
+			__be32 pppen_to_ncsich;
+			__be32 r11;
+		} ppp;
+		struct fw_port_dcb {
+			__be16 cfg;
+			u8 up_map;
+			u8 sf_cfgrc;
+			__be16 prot_ix;
+			u8 pe7_to_pe0;
+			u8 numTCPFCs;
+			__be32 pgid0_to_pgid7;
+			__be32 numTCs_oui;
+			u8 pgpc[8];
+		} dcb;
+	} u;
+};
+
+#define FW_PORT_CMD_READ (1U << 22)
+
+#define FW_PORT_CMD_PORTID(x) ((x) << 0)
+#define FW_PORT_CMD_PORTID_GET(x) (((x) >> 0) & 0xf)
+
+#define FW_PORT_CMD_ACTION(x) ((x) << 16)
+
+#define FW_PORT_CMD_CTLBF(x) ((x) << 10)
+#define FW_PORT_CMD_OVLAN3(x) ((x) << 7)
+#define FW_PORT_CMD_OVLAN2(x) ((x) << 6)
+#define FW_PORT_CMD_OVLAN1(x) ((x) << 5)
+#define FW_PORT_CMD_OVLAN0(x) ((x) << 4)
+#define FW_PORT_CMD_IVLAN0(x) ((x) << 3)
+
+#define FW_PORT_CMD_TXIPG(x) ((x) << 19)
+
+#define FW_PORT_CMD_LSTATUS (1U << 31)
+#define FW_PORT_CMD_LSPEED(x) ((x) << 24)
+#define FW_PORT_CMD_LSPEED_GET(x) (((x) >> 24) & 0x3f)
+#define FW_PORT_CMD_TXPAUSE (1U << 23)
+#define FW_PORT_CMD_RXPAUSE (1U << 22)
+#define FW_PORT_CMD_MDIOCAP (1U << 21)
+#define FW_PORT_CMD_MDIOADDR_GET(x) (((x) >> 16) & 0x1f)
+#define FW_PORT_CMD_LPTXPAUSE (1U << 15)
+#define FW_PORT_CMD_LPRXPAUSE (1U << 14)
+#define FW_PORT_CMD_PTYPE_MASK 0x1f
+#define FW_PORT_CMD_PTYPE_GET(x) (((x) >> 8) & FW_PORT_CMD_PTYPE_MASK)
+#define FW_PORT_CMD_MODTYPE_MASK 0x1f
+#define FW_PORT_CMD_MODTYPE_GET(x) (((x) >> 0) & FW_PORT_CMD_MODTYPE_MASK)
+
+#define FW_PORT_CMD_PPPEN(x) ((x) << 31)
+#define FW_PORT_CMD_TPSRC(x) ((x) << 28)
+#define FW_PORT_CMD_NCSISRC(x) ((x) << 24)
+
+#define FW_PORT_CMD_CH0(x) ((x) << 20)
+#define FW_PORT_CMD_CH1(x) ((x) << 16)
+#define FW_PORT_CMD_CH2(x) ((x) << 12)
+#define FW_PORT_CMD_CH3(x) ((x) << 8)
+#define FW_PORT_CMD_NCSICH(x) ((x) << 4)
+
+enum fw_port_type {
+	FW_PORT_TYPE_FIBER,
+	FW_PORT_TYPE_KX4,
+	FW_PORT_TYPE_BT_SGMII,
+	FW_PORT_TYPE_KX,
+	FW_PORT_TYPE_BT_XAUI,
+	FW_PORT_TYPE_KR,
+	FW_PORT_TYPE_CX4,
+	FW_PORT_TYPE_TWINAX,
+
+	FW_PORT_TYPE_NONE = FW_PORT_CMD_PTYPE_MASK
+};
+
+enum fw_port_module_type {
+	FW_PORT_MOD_TYPE_NA,
+	FW_PORT_MOD_TYPE_LR,
+	FW_PORT_MOD_TYPE_SR,
+	FW_PORT_MOD_TYPE_ER,
+
+	FW_PORT_MOD_TYPE_NONE = FW_PORT_CMD_MODTYPE_MASK
+};
+
+/* port stats */
+#define FW_NUM_PORT_STATS 50
+#define FW_NUM_PORT_TX_STATS 23
+#define FW_NUM_PORT_RX_STATS 27
+
+enum fw_port_stats_tx_index {
+	FW_STAT_TX_PORT_BYTES_IX,
+	FW_STAT_TX_PORT_FRAMES_IX,
+	FW_STAT_TX_PORT_BCAST_IX,
+	FW_STAT_TX_PORT_MCAST_IX,
+	FW_STAT_TX_PORT_UCAST_IX,
+	FW_STAT_TX_PORT_ERROR_IX,
+	FW_STAT_TX_PORT_64B_IX,
+	FW_STAT_TX_PORT_65B_127B_IX,
+	FW_STAT_TX_PORT_128B_255B_IX,
+	FW_STAT_TX_PORT_256B_511B_IX,
+	FW_STAT_TX_PORT_512B_1023B_IX,
+	FW_STAT_TX_PORT_1024B_1518B_IX,
+	FW_STAT_TX_PORT_1519B_MAX_IX,
+	FW_STAT_TX_PORT_DROP_IX,
+	FW_STAT_TX_PORT_PAUSE_IX,
+	FW_STAT_TX_PORT_PPP0_IX,
+	FW_STAT_TX_PORT_PPP1_IX,
+	FW_STAT_TX_PORT_PPP2_IX,
+	FW_STAT_TX_PORT_PPP3_IX,
+	FW_STAT_TX_PORT_PPP4_IX,
+	FW_STAT_TX_PORT_PPP5_IX,
+	FW_STAT_TX_PORT_PPP6_IX,
+	FW_STAT_TX_PORT_PPP7_IX
+};
+
+enum fw_port_stat_rx_index {
+	FW_STAT_RX_PORT_BYTES_IX,
+	FW_STAT_RX_PORT_FRAMES_IX,
+	FW_STAT_RX_PORT_BCAST_IX,
+	FW_STAT_RX_PORT_MCAST_IX,
+	FW_STAT_RX_PORT_UCAST_IX,
+	FW_STAT_RX_PORT_MTU_ERROR_IX,
+	FW_STAT_RX_PORT_MTU_CRC_ERROR_IX,
+	FW_STAT_RX_PORT_CRC_ERROR_IX,
+	FW_STAT_RX_PORT_LEN_ERROR_IX,
+	FW_STAT_RX_PORT_SYM_ERROR_IX,
+	FW_STAT_RX_PORT_64B_IX,
+	FW_STAT_RX_PORT_65B_127B_IX,
+	FW_STAT_RX_PORT_128B_255B_IX,
+	FW_STAT_RX_PORT_256B_511B_IX,
+	FW_STAT_RX_PORT_512B_1023B_IX,
+	FW_STAT_RX_PORT_1024B_1518B_IX,
+	FW_STAT_RX_PORT_1519B_MAX_IX,
+	FW_STAT_RX_PORT_PAUSE_IX,
+	FW_STAT_RX_PORT_PPP0_IX,
+	FW_STAT_RX_PORT_PPP1_IX,
+	FW_STAT_RX_PORT_PPP2_IX,
+	FW_STAT_RX_PORT_PPP3_IX,
+	FW_STAT_RX_PORT_PPP4_IX,
+	FW_STAT_RX_PORT_PPP5_IX,
+	FW_STAT_RX_PORT_PPP6_IX,
+	FW_STAT_RX_PORT_PPP7_IX,
+	FW_STAT_RX_PORT_LESS_64B_IX
+};
+
+struct fw_port_stats_cmd {
+	__be32 op_to_portid;
+	__be32 retval_len16;
+	union fw_port_stats {
+		struct fw_port_stats_ctl {
+			u8 nstats_bg_bm;
+			u8 tx_ix;
+			__be16 r6;
+			__be32 r7;
+			__be64 stat0;
+			__be64 stat1;
+			__be64 stat2;
+			__be64 stat3;
+			__be64 stat4;
+			__be64 stat5;
+		} ctl;
+		struct fw_port_stats_all {
+			__be64 tx_bytes;
+			__be64 tx_frames;
+			__be64 tx_bcast;
+			__be64 tx_mcast;
+			__be64 tx_ucast;
+			__be64 tx_error;
+			__be64 tx_64b;
+			__be64 tx_65b_127b;
+			__be64 tx_128b_255b;
+			__be64 tx_256b_511b;
+			__be64 tx_512b_1023b;
+			__be64 tx_1024b_1518b;
+			__be64 tx_1519b_max;
+			__be64 tx_drop;
+			__be64 tx_pause;
+			__be64 tx_ppp0;
+			__be64 tx_ppp1;
+			__be64 tx_ppp2;
+			__be64 tx_ppp3;
+			__be64 tx_ppp4;
+			__be64 tx_ppp5;
+			__be64 tx_ppp6;
+			__be64 tx_ppp7;
+			__be64 rx_bytes;
+			__be64 rx_frames;
+			__be64 rx_bcast;
+			__be64 rx_mcast;
+			__be64 rx_ucast;
+			__be64 rx_mtu_error;
+			__be64 rx_mtu_crc_error;
+			__be64 rx_crc_error;
+			__be64 rx_len_error;
+			__be64 rx_sym_error;
+			__be64 rx_64b;
+			__be64 rx_65b_127b;
+			__be64 rx_128b_255b;
+			__be64 rx_256b_511b;
+			__be64 rx_512b_1023b;
+			__be64 rx_1024b_1518b;
+			__be64 rx_1519b_max;
+			__be64 rx_pause;
+			__be64 rx_ppp0;
+			__be64 rx_ppp1;
+			__be64 rx_ppp2;
+			__be64 rx_ppp3;
+			__be64 rx_ppp4;
+			__be64 rx_ppp5;
+			__be64 rx_ppp6;
+			__be64 rx_ppp7;
+			__be64 rx_less_64b;
+			__be64 rx_bg_drop;
+			__be64 rx_bg_trunc;
+		} all;
+	} u;
+};
+
+#define FW_PORT_STATS_CMD_NSTATS(x) ((x) << 4)
+#define FW_PORT_STATS_CMD_BG_BM(x) ((x) << 0)
+#define FW_PORT_STATS_CMD_TX(x) ((x) << 7)
+#define FW_PORT_STATS_CMD_IX(x) ((x) << 0)
+
+/* port loopback stats */
+#define FW_NUM_LB_STATS 16
+enum fw_port_lb_stats_index {
+	FW_STAT_LB_PORT_BYTES_IX,
+	FW_STAT_LB_PORT_FRAMES_IX,
+	FW_STAT_LB_PORT_BCAST_IX,
+	FW_STAT_LB_PORT_MCAST_IX,
+	FW_STAT_LB_PORT_UCAST_IX,
+	FW_STAT_LB_PORT_ERROR_IX,
+	FW_STAT_LB_PORT_64B_IX,
+	FW_STAT_LB_PORT_65B_127B_IX,
+	FW_STAT_LB_PORT_128B_255B_IX,
+	FW_STAT_LB_PORT_256B_511B_IX,
+	FW_STAT_LB_PORT_512B_1023B_IX,
+	FW_STAT_LB_PORT_1024B_1518B_IX,
+	FW_STAT_LB_PORT_1519B_MAX_IX,
+	FW_STAT_LB_PORT_DROP_FRAMES_IX
+};
+
+struct fw_port_lb_stats_cmd {
+	__be32 op_to_lbport;
+	__be32 retval_len16;
+	union fw_port_lb_stats {
+		struct fw_port_lb_stats_ctl {
+			u8 nstats_bg_bm;
+			u8 ix_pkd;
+			__be16 r6;
+			__be32 r7;
+			__be64 stat0;
+			__be64 stat1;
+			__be64 stat2;
+			__be64 stat3;
+			__be64 stat4;
+			__be64 stat5;
+		} ctl;
+		struct fw_port_lb_stats_all {
+			__be64 tx_bytes;
+			__be64 tx_frames;
+			__be64 tx_bcast;
+			__be64 tx_mcast;
+			__be64 tx_ucast;
+			__be64 tx_error;
+			__be64 tx_64b;
+			__be64 tx_65b_127b;
+			__be64 tx_128b_255b;
+			__be64 tx_256b_511b;
+			__be64 tx_512b_1023b;
+			__be64 tx_1024b_1518b;
+			__be64 tx_1519b_max;
+			__be64 rx_lb_drop;
+			__be64 rx_lb_trunc;
+		} all;
+	} u;
+};
+
+#define FW_PORT_LB_STATS_CMD_LBPORT(x) ((x) << 0)
+#define FW_PORT_LB_STATS_CMD_NSTATS(x) ((x) << 4)
+#define FW_PORT_LB_STATS_CMD_BG_BM(x) ((x) << 0)
+#define FW_PORT_LB_STATS_CMD_IX(x) ((x) << 0)
+
+struct fw_rss_ind_tbl_cmd {
+	__be32 op_to_viid;
+#define FW_RSS_IND_TBL_CMD_VIID(x) ((x) << 0)
+	__be32 retval_len16;
+	__be16 niqid;
+	__be16 startidx;
+	__be32 r3;
+	__be32 iq0_to_iq2;
+#define FW_RSS_IND_TBL_CMD_IQ0(x) ((x) << 20)
+#define FW_RSS_IND_TBL_CMD_IQ1(x) ((x) << 10)
+#define FW_RSS_IND_TBL_CMD_IQ2(x) ((x) << 0)
+	__be32 iq3_to_iq5;
+	__be32 iq6_to_iq8;
+	__be32 iq9_to_iq11;
+	__be32 iq12_to_iq14;
+	__be32 iq15_to_iq17;
+	__be32 iq18_to_iq20;
+	__be32 iq21_to_iq23;
+	__be32 iq24_to_iq26;
+	__be32 iq27_to_iq29;
+	__be32 iq30_iq31;
+	__be32 r15_lo;
+};
+
+struct fw_rss_glb_config_cmd {
+	__be32 op_to_write;
+	__be32 retval_len16;
+	union fw_rss_glb_config {
+		struct fw_rss_glb_config_manual {
+			__be32 mode_pkd;
+			__be32 r3;
+			__be64 r4;
+			__be64 r5;
+		} manual;
+		struct fw_rss_glb_config_basicvirtual {
+			__be32 mode_pkd;
+			__be32 synmapen_to_hashtoeplitz;
+#define FW_RSS_GLB_CONFIG_CMD_SYNMAPEN      (1U << 8)
+#define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6 (1U << 7)
+#define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6 (1U << 6)
+#define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4 (1U << 5)
+#define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4 (1U << 4)
+#define FW_RSS_GLB_CONFIG_CMD_OFDMAPEN      (1U << 3)
+#define FW_RSS_GLB_CONFIG_CMD_TNLMAPEN      (1U << 2)
+#define FW_RSS_GLB_CONFIG_CMD_TNLALLLKP     (1U << 1)
+#define FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ  (1U << 0)
+			__be64 r8;
+			__be64 r9;
+		} basicvirtual;
+	} u;
+};
+
+#define FW_RSS_GLB_CONFIG_CMD_MODE(x)	((x) << 28)
+
+#define FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL	0
+#define FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL	1
+
+struct fw_rss_vi_config_cmd {
+	__be32 op_to_viid;
+#define FW_RSS_VI_CONFIG_CMD_VIID(x) ((x) << 0)
+	__be32 retval_len16;
+	union fw_rss_vi_config {
+		struct fw_rss_vi_config_manual {
+			__be64 r3;
+			__be64 r4;
+			__be64 r5;
+		} manual;
+		struct fw_rss_vi_config_basicvirtual {
+			__be32 r6;
+			__be32 defaultq_to_ip4udpen;
+#define FW_RSS_VI_CONFIG_CMD_DEFAULTQ(x)  ((x) << 16)
+#define FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN (1U << 4)
+#define FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN  (1U << 3)
+#define FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN (1U << 2)
+#define FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN  (1U << 1)
+#define FW_RSS_VI_CONFIG_CMD_IP4UDPEN     (1U << 0)
+			__be64 r9;
+			__be64 r10;
+		} basicvirtual;
+	} u;
+};
+
+enum fw_error_type {
+	FW_ERROR_TYPE_EXCEPTION		= 0x0,
+	FW_ERROR_TYPE_HWMODULE		= 0x1,
+	FW_ERROR_TYPE_WR		= 0x2,
+	FW_ERROR_TYPE_ACL		= 0x3,
+};
+
+struct fw_error_cmd {
+	__be32 op_to_type;
+	__be32 len16_pkd;
+	union fw_error {
+		struct fw_error_exception {
+			__be32 info[6];
+		} exception;
+		struct fw_error_hwmodule {
+			__be32 regaddr;
+			__be32 regval;
+		} hwmodule;
+		struct fw_error_wr {
+			__be16 cidx;
+			__be16 pfn_vfn;
+			__be32 eqid;
+			u8 wrhdr[16];
+		} wr;
+		struct fw_error_acl {
+			__be16 cidx;
+			__be16 pfn_vfn;
+			__be32 eqid;
+			__be16 mv_pkd;
+			u8 val[6];
+			__be64 r4;
+		} acl;
+	} u;
+};
+
+struct fw_debug_cmd {
+	__be32 op_type;
+#define FW_DEBUG_CMD_TYPE_GET(x) ((x) & 0xff)
+	__be32 len16_pkd;
+	union fw_debug {
+		struct fw_debug_assert {
+			__be32 fcid;
+			__be32 line;
+			__be32 x;
+			__be32 y;
+			u8 filename_0_7[8];
+			u8 filename_8_15[8];
+			__be64 r3;
+		} assert;
+		struct fw_debug_prt {
+			__be16 dprtstridx;
+			__be16 r3[3];
+			__be32 dprtstrparam0;
+			__be32 dprtstrparam1;
+			__be32 dprtstrparam2;
+			__be32 dprtstrparam3;
+		} prt;
+	} u;
+};
+
+struct fw_hdr {
+	u8 ver;
+	u8 reserved1;
+	__be16	len512;			/* bin length in units of 512-bytes */
+	__be32	fw_ver;			/* firmware version */
+	__be32	tp_microcode_ver;
+	u8 intfver_nic;
+	u8 intfver_vnic;
+	u8 intfver_ofld;
+	u8 intfver_ri;
+	u8 intfver_iscsipdu;
+	u8 intfver_iscsi;
+	u8 intfver_fcoe;
+	u8 reserved2;
+	__be32  reserved3[27];
+};
+
+#define FW_HDR_FW_VER_MAJOR_GET(x) (((x) >> 24) & 0xff)
+#define FW_HDR_FW_VER_MINOR_GET(x) (((x) >> 16) & 0xff)
+#define FW_HDR_FW_VER_MICRO_GET(x) (((x) >> 8) & 0xff)
+#define FW_HDR_FW_VER_BUILD_GET(x) (((x) >> 0) & 0xff)
+#endif /* _T4FW_INTERFACE_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb4/t4_hw.c linux-libre-2.6.34-gnu1/drivers/net/cxgb4/t4_hw.c
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb4/t4_hw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb4/t4_hw.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,3131 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include "cxgb4.h"
+#include "t4_regs.h"
+#include "t4fw_api.h"
+
+/**
+ *	t4_wait_op_done_val - wait until an operation is completed
+ *	@adapter: the adapter performing the operation
+ *	@reg: the register to check for completion
+ *	@mask: a single-bit field within @reg that indicates completion
+ *	@polarity: the value of the field when the operation is completed
+ *	@attempts: number of check iterations
+ *	@delay: delay in usecs between iterations
+ *	@valp: where to store the value of the register at completion time
+ *
+ *	Wait until an operation is completed by checking a bit in a register
+ *	up to @attempts times.  If @valp is not NULL the value of the register
+ *	at the time it indicated completion is stored there.  Returns 0 if the
+ *	operation completes and	-EAGAIN	otherwise.
+ */
+int t4_wait_op_done_val(struct adapter *adapter, int reg, u32 mask,
+			int polarity, int attempts, int delay, u32 *valp)
+{
+	while (1) {
+		u32 val = t4_read_reg(adapter, reg);
+
+		if (!!(val & mask) == polarity) {
+			if (valp)
+				*valp = val;
+			return 0;
+		}
+		if (--attempts == 0)
+			return -EAGAIN;
+		if (delay)
+			udelay(delay);
+	}
+}
+
+static inline int t4_wait_op_done(struct adapter *adapter, int reg, u32 mask,
+				  int polarity, int attempts, int delay)
+{
+	return t4_wait_op_done_val(adapter, reg, mask, polarity, attempts,
+				   delay, NULL);
+}
+
+/**
+ *	t4_set_reg_field - set a register field to a value
+ *	@adapter: the adapter to program
+ *	@addr: the register address
+ *	@mask: specifies the portion of the register to modify
+ *	@val: the new value for the register field
+ *
+ *	Sets a register field specified by the supplied mask to the
+ *	given value.
+ */
+void t4_set_reg_field(struct adapter *adapter, unsigned int addr, u32 mask,
+		      u32 val)
+{
+	u32 v = t4_read_reg(adapter, addr) & ~mask;
+
+	t4_write_reg(adapter, addr, v | val);
+	(void) t4_read_reg(adapter, addr);      /* flush */
+}
+
+/**
+ *	t4_read_indirect - read indirectly addressed registers
+ *	@adap: the adapter
+ *	@addr_reg: register holding the indirect address
+ *	@data_reg: register holding the value of the indirect register
+ *	@vals: where the read register values are stored
+ *	@nregs: how many indirect registers to read
+ *	@start_idx: index of first indirect register to read
+ *
+ *	Reads registers that are accessed indirectly through an address/data
+ *	register pair.
+ */
+void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
+		      unsigned int data_reg, u32 *vals, unsigned int nregs,
+		      unsigned int start_idx)
+{
+	while (nregs--) {
+		t4_write_reg(adap, addr_reg, start_idx);
+		*vals++ = t4_read_reg(adap, data_reg);
+		start_idx++;
+	}
+}
+
+/**
+ *	t4_write_indirect - write indirectly addressed registers
+ *	@adap: the adapter
+ *	@addr_reg: register holding the indirect addresses
+ *	@data_reg: register holding the value for the indirect registers
+ *	@vals: values to write
+ *	@nregs: how many indirect registers to write
+ *	@start_idx: address of first indirect register to write
+ *
+ *	Writes a sequential block of registers that are accessed indirectly
+ *	through an address/data register pair.
+ */
+void t4_write_indirect(struct adapter *adap, unsigned int addr_reg,
+		       unsigned int data_reg, const u32 *vals,
+		       unsigned int nregs, unsigned int start_idx)
+{
+	while (nregs--) {
+		t4_write_reg(adap, addr_reg, start_idx++);
+		t4_write_reg(adap, data_reg, *vals++);
+	}
+}
+
+/*
+ * Get the reply to a mailbox command and store it in @rpl in big-endian order.
+ */
+static void get_mbox_rpl(struct adapter *adap, __be64 *rpl, int nflit,
+			 u32 mbox_addr)
+{
+	for ( ; nflit; nflit--, mbox_addr += 8)
+		*rpl++ = cpu_to_be64(t4_read_reg64(adap, mbox_addr));
+}
+
+/*
+ * Handle a FW assertion reported in a mailbox.
+ */
+static void fw_asrt(struct adapter *adap, u32 mbox_addr)
+{
+	struct fw_debug_cmd asrt;
+
+	get_mbox_rpl(adap, (__be64 *)&asrt, sizeof(asrt) / 8, mbox_addr);
+	dev_alert(adap->pdev_dev,
+		  "FW assertion at %.16s:%u, val0 %#x, val1 %#x\n",
+		  asrt.u.assert.filename_0_7, ntohl(asrt.u.assert.line),
+		  ntohl(asrt.u.assert.x), ntohl(asrt.u.assert.y));
+}
+
+static void dump_mbox(struct adapter *adap, int mbox, u32 data_reg)
+{
+	dev_err(adap->pdev_dev,
+		"mbox %d: %llx %llx %llx %llx %llx %llx %llx %llx\n", mbox,
+		(unsigned long long)t4_read_reg64(adap, data_reg),
+		(unsigned long long)t4_read_reg64(adap, data_reg + 8),
+		(unsigned long long)t4_read_reg64(adap, data_reg + 16),
+		(unsigned long long)t4_read_reg64(adap, data_reg + 24),
+		(unsigned long long)t4_read_reg64(adap, data_reg + 32),
+		(unsigned long long)t4_read_reg64(adap, data_reg + 40),
+		(unsigned long long)t4_read_reg64(adap, data_reg + 48),
+		(unsigned long long)t4_read_reg64(adap, data_reg + 56));
+}
+
+/**
+ *	t4_wr_mbox_meat - send a command to FW through the given mailbox
+ *	@adap: the adapter
+ *	@mbox: index of the mailbox to use
+ *	@cmd: the command to write
+ *	@size: command length in bytes
+ *	@rpl: where to optionally store the reply
+ *	@sleep_ok: if true we may sleep while awaiting command completion
+ *
+ *	Sends the given command to FW through the selected mailbox and waits
+ *	for the FW to execute the command.  If @rpl is not %NULL it is used to
+ *	store the FW's reply to the command.  The command and its optional
+ *	reply are of the same length.  FW can take up to %FW_CMD_MAX_TIMEOUT ms
+ *	to respond.  @sleep_ok determines whether we may sleep while awaiting
+ *	the response.  If sleeping is allowed we use progressive backoff
+ *	otherwise we spin.
+ *
+ *	The return value is 0 on success or a negative errno on failure.  A
+ *	failure can happen either because we are not able to execute the
+ *	command or FW executes it but signals an error.  In the latter case
+ *	the return value is the error code indicated by FW (negated).
+ */
+int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
+		    void *rpl, bool sleep_ok)
+{
+	static int delay[] = {
+		1, 1, 3, 5, 10, 10, 20, 50, 100, 200
+	};
+
+	u32 v;
+	u64 res;
+	int i, ms, delay_idx;
+	const __be64 *p = cmd;
+	u32 data_reg = PF_REG(mbox, CIM_PF_MAILBOX_DATA);
+	u32 ctl_reg = PF_REG(mbox, CIM_PF_MAILBOX_CTRL);
+
+	if ((size & 15) || size > MBOX_LEN)
+		return -EINVAL;
+
+	v = MBOWNER_GET(t4_read_reg(adap, ctl_reg));
+	for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++)
+		v = MBOWNER_GET(t4_read_reg(adap, ctl_reg));
+
+	if (v != MBOX_OWNER_DRV)
+		return v ? -EBUSY : -ETIMEDOUT;
+
+	for (i = 0; i < size; i += 8)
+		t4_write_reg64(adap, data_reg + i, be64_to_cpu(*p++));
+
+	t4_write_reg(adap, ctl_reg, MBMSGVALID | MBOWNER(MBOX_OWNER_FW));
+	t4_read_reg(adap, ctl_reg);          /* flush write */
+
+	delay_idx = 0;
+	ms = delay[0];
+
+	for (i = 0; i < FW_CMD_MAX_TIMEOUT; i += ms) {
+		if (sleep_ok) {
+			ms = delay[delay_idx];  /* last element may repeat */
+			if (delay_idx < ARRAY_SIZE(delay) - 1)
+				delay_idx++;
+			msleep(ms);
+		} else
+			mdelay(ms);
+
+		v = t4_read_reg(adap, ctl_reg);
+		if (MBOWNER_GET(v) == MBOX_OWNER_DRV) {
+			if (!(v & MBMSGVALID)) {
+				t4_write_reg(adap, ctl_reg, 0);
+				continue;
+			}
+
+			res = t4_read_reg64(adap, data_reg);
+			if (FW_CMD_OP_GET(res >> 32) == FW_DEBUG_CMD) {
+				fw_asrt(adap, data_reg);
+				res = FW_CMD_RETVAL(EIO);
+			} else if (rpl)
+				get_mbox_rpl(adap, rpl, size / 8, data_reg);
+
+			if (FW_CMD_RETVAL_GET((int)res))
+				dump_mbox(adap, mbox, data_reg);
+			t4_write_reg(adap, ctl_reg, 0);
+			return -FW_CMD_RETVAL_GET((int)res);
+		}
+	}
+
+	dump_mbox(adap, mbox, data_reg);
+	dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n",
+		*(const u8 *)cmd, mbox);
+	return -ETIMEDOUT;
+}
+
+/**
+ *	t4_mc_read - read from MC through backdoor accesses
+ *	@adap: the adapter
+ *	@addr: address of first byte requested
+ *	@data: 64 bytes of data containing the requested address
+ *	@ecc: where to store the corresponding 64-bit ECC word
+ *
+ *	Read 64 bytes of data from MC starting at a 64-byte-aligned address
+ *	that covers the requested address @addr.  If @parity is not %NULL it
+ *	is assigned the 64-bit ECC word for the read data.
+ */
+int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *ecc)
+{
+	int i;
+
+	if (t4_read_reg(adap, MC_BIST_CMD) & START_BIST)
+		return -EBUSY;
+	t4_write_reg(adap, MC_BIST_CMD_ADDR, addr & ~0x3fU);
+	t4_write_reg(adap, MC_BIST_CMD_LEN, 64);
+	t4_write_reg(adap, MC_BIST_DATA_PATTERN, 0xc);
+	t4_write_reg(adap, MC_BIST_CMD, BIST_OPCODE(1) | START_BIST |
+		     BIST_CMD_GAP(1));
+	i = t4_wait_op_done(adap, MC_BIST_CMD, START_BIST, 0, 10, 1);
+	if (i)
+		return i;
+
+#define MC_DATA(i) MC_BIST_STATUS_REG(MC_BIST_STATUS_RDATA, i)
+
+	for (i = 15; i >= 0; i--)
+		*data++ = htonl(t4_read_reg(adap, MC_DATA(i)));
+	if (ecc)
+		*ecc = t4_read_reg64(adap, MC_DATA(16));
+#undef MC_DATA
+	return 0;
+}
+
+/**
+ *	t4_edc_read - read from EDC through backdoor accesses
+ *	@adap: the adapter
+ *	@idx: which EDC to access
+ *	@addr: address of first byte requested
+ *	@data: 64 bytes of data containing the requested address
+ *	@ecc: where to store the corresponding 64-bit ECC word
+ *
+ *	Read 64 bytes of data from EDC starting at a 64-byte-aligned address
+ *	that covers the requested address @addr.  If @parity is not %NULL it
+ *	is assigned the 64-bit ECC word for the read data.
+ */
+int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc)
+{
+	int i;
+
+	idx *= EDC_STRIDE;
+	if (t4_read_reg(adap, EDC_BIST_CMD + idx) & START_BIST)
+		return -EBUSY;
+	t4_write_reg(adap, EDC_BIST_CMD_ADDR + idx, addr & ~0x3fU);
+	t4_write_reg(adap, EDC_BIST_CMD_LEN + idx, 64);
+	t4_write_reg(adap, EDC_BIST_DATA_PATTERN + idx, 0xc);
+	t4_write_reg(adap, EDC_BIST_CMD + idx,
+		     BIST_OPCODE(1) | BIST_CMD_GAP(1) | START_BIST);
+	i = t4_wait_op_done(adap, EDC_BIST_CMD + idx, START_BIST, 0, 10, 1);
+	if (i)
+		return i;
+
+#define EDC_DATA(i) (EDC_BIST_STATUS_REG(EDC_BIST_STATUS_RDATA, i) + idx)
+
+	for (i = 15; i >= 0; i--)
+		*data++ = htonl(t4_read_reg(adap, EDC_DATA(i)));
+	if (ecc)
+		*ecc = t4_read_reg64(adap, EDC_DATA(16));
+#undef EDC_DATA
+	return 0;
+}
+
+#define VPD_ENTRY(name, len) \
+	u8 name##_kword[2]; u8 name##_len; u8 name##_data[len]
+
+/*
+ * Partial EEPROM Vital Product Data structure.  Includes only the ID and
+ * VPD-R sections.
+ */
+struct t4_vpd {
+	u8  id_tag;
+	u8  id_len[2];
+	u8  id_data[ID_LEN];
+	u8  vpdr_tag;
+	u8  vpdr_len[2];
+	VPD_ENTRY(pn, 16);                     /* part number */
+	VPD_ENTRY(ec, EC_LEN);                 /* EC level */
+	VPD_ENTRY(sn, SERNUM_LEN);             /* serial number */
+	VPD_ENTRY(na, 12);                     /* MAC address base */
+	VPD_ENTRY(port_type, 8);               /* port types */
+	VPD_ENTRY(gpio, 14);                   /* GPIO usage */
+	VPD_ENTRY(cclk, 6);                    /* core clock */
+	VPD_ENTRY(port_addr, 8);               /* port MDIO addresses */
+	VPD_ENTRY(rv, 1);                      /* csum */
+	u32 pad;                  /* for multiple-of-4 sizing and alignment */
+};
+
+#define EEPROM_STAT_ADDR   0x7bfc
+#define VPD_BASE           0
+
+/**
+ *	t4_seeprom_wp - enable/disable EEPROM write protection
+ *	@adapter: the adapter
+ *	@enable: whether to enable or disable write protection
+ *
+ *	Enables or disables write protection on the serial EEPROM.
+ */
+int t4_seeprom_wp(struct adapter *adapter, bool enable)
+{
+	unsigned int v = enable ? 0xc : 0;
+	int ret = pci_write_vpd(adapter->pdev, EEPROM_STAT_ADDR, 4, &v);
+	return ret < 0 ? ret : 0;
+}
+
+/**
+ *	get_vpd_params - read VPD parameters from VPD EEPROM
+ *	@adapter: adapter to read
+ *	@p: where to store the parameters
+ *
+ *	Reads card parameters stored in VPD EEPROM.
+ */
+static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
+{
+	int ret;
+	struct t4_vpd vpd;
+	u8 *q = (u8 *)&vpd, csum;
+
+	ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(vpd), &vpd);
+	if (ret < 0)
+		return ret;
+
+	for (csum = 0; q <= vpd.rv_data; q++)
+		csum += *q;
+
+	if (csum) {
+		dev_err(adapter->pdev_dev,
+			"corrupted VPD EEPROM, actual csum %u\n", csum);
+		return -EINVAL;
+	}
+
+	p->cclk = simple_strtoul(vpd.cclk_data, NULL, 10);
+	memcpy(p->id, vpd.id_data, sizeof(vpd.id_data));
+	strim(p->id);
+	memcpy(p->ec, vpd.ec_data, sizeof(vpd.ec_data));
+	strim(p->ec);
+	memcpy(p->sn, vpd.sn_data, sizeof(vpd.sn_data));
+	strim(p->sn);
+	return 0;
+}
+
+/* serial flash and firmware constants */
+enum {
+	SF_ATTEMPTS = 10,             /* max retries for SF operations */
+
+	/* flash command opcodes */
+	SF_PROG_PAGE    = 2,          /* program page */
+	SF_WR_DISABLE   = 4,          /* disable writes */
+	SF_RD_STATUS    = 5,          /* read status register */
+	SF_WR_ENABLE    = 6,          /* enable writes */
+	SF_RD_DATA_FAST = 0xb,        /* read flash */
+	SF_ERASE_SECTOR = 0xd8,       /* erase sector */
+
+	FW_START_SEC = 8,             /* first flash sector for FW */
+	FW_END_SEC = 15,              /* last flash sector for FW */
+	FW_IMG_START = FW_START_SEC * SF_SEC_SIZE,
+	FW_MAX_SIZE = (FW_END_SEC - FW_START_SEC + 1) * SF_SEC_SIZE,
+};
+
+/**
+ *	sf1_read - read data from the serial flash
+ *	@adapter: the adapter
+ *	@byte_cnt: number of bytes to read
+ *	@cont: whether another operation will be chained
+ *	@lock: whether to lock SF for PL access only
+ *	@valp: where to store the read data
+ *
+ *	Reads up to 4 bytes of data from the serial flash.  The location of
+ *	the read needs to be specified prior to calling this by issuing the
+ *	appropriate commands to the serial flash.
+ */
+static int sf1_read(struct adapter *adapter, unsigned int byte_cnt, int cont,
+		    int lock, u32 *valp)
+{
+	int ret;
+
+	if (!byte_cnt || byte_cnt > 4)
+		return -EINVAL;
+	if (t4_read_reg(adapter, SF_OP) & BUSY)
+		return -EBUSY;
+	cont = cont ? SF_CONT : 0;
+	lock = lock ? SF_LOCK : 0;
+	t4_write_reg(adapter, SF_OP, lock | cont | BYTECNT(byte_cnt - 1));
+	ret = t4_wait_op_done(adapter, SF_OP, BUSY, 0, SF_ATTEMPTS, 5);
+	if (!ret)
+		*valp = t4_read_reg(adapter, SF_DATA);
+	return ret;
+}
+
+/**
+ *	sf1_write - write data to the serial flash
+ *	@adapter: the adapter
+ *	@byte_cnt: number of bytes to write
+ *	@cont: whether another operation will be chained
+ *	@lock: whether to lock SF for PL access only
+ *	@val: value to write
+ *
+ *	Writes up to 4 bytes of data to the serial flash.  The location of
+ *	the write needs to be specified prior to calling this by issuing the
+ *	appropriate commands to the serial flash.
+ */
+static int sf1_write(struct adapter *adapter, unsigned int byte_cnt, int cont,
+		     int lock, u32 val)
+{
+	if (!byte_cnt || byte_cnt > 4)
+		return -EINVAL;
+	if (t4_read_reg(adapter, SF_OP) & BUSY)
+		return -EBUSY;
+	cont = cont ? SF_CONT : 0;
+	lock = lock ? SF_LOCK : 0;
+	t4_write_reg(adapter, SF_DATA, val);
+	t4_write_reg(adapter, SF_OP, lock |
+		     cont | BYTECNT(byte_cnt - 1) | OP_WR);
+	return t4_wait_op_done(adapter, SF_OP, BUSY, 0, SF_ATTEMPTS, 5);
+}
+
+/**
+ *	flash_wait_op - wait for a flash operation to complete
+ *	@adapter: the adapter
+ *	@attempts: max number of polls of the status register
+ *	@delay: delay between polls in ms
+ *
+ *	Wait for a flash operation to complete by polling the status register.
+ */
+static int flash_wait_op(struct adapter *adapter, int attempts, int delay)
+{
+	int ret;
+	u32 status;
+
+	while (1) {
+		if ((ret = sf1_write(adapter, 1, 1, 1, SF_RD_STATUS)) != 0 ||
+		    (ret = sf1_read(adapter, 1, 0, 1, &status)) != 0)
+			return ret;
+		if (!(status & 1))
+			return 0;
+		if (--attempts == 0)
+			return -EAGAIN;
+		if (delay)
+			msleep(delay);
+	}
+}
+
+/**
+ *	t4_read_flash - read words from serial flash
+ *	@adapter: the adapter
+ *	@addr: the start address for the read
+ *	@nwords: how many 32-bit words to read
+ *	@data: where to store the read data
+ *	@byte_oriented: whether to store data as bytes or as words
+ *
+ *	Read the specified number of 32-bit words from the serial flash.
+ *	If @byte_oriented is set the read data is stored as a byte array
+ *	(i.e., big-endian), otherwise as 32-bit words in the platform's
+ *	natural endianess.
+ */
+int t4_read_flash(struct adapter *adapter, unsigned int addr,
+		  unsigned int nwords, u32 *data, int byte_oriented)
+{
+	int ret;
+
+	if (addr + nwords * sizeof(u32) > SF_SIZE || (addr & 3))
+		return -EINVAL;
+
+	addr = swab32(addr) | SF_RD_DATA_FAST;
+
+	if ((ret = sf1_write(adapter, 4, 1, 0, addr)) != 0 ||
+	    (ret = sf1_read(adapter, 1, 1, 0, data)) != 0)
+		return ret;
+
+	for ( ; nwords; nwords--, data++) {
+		ret = sf1_read(adapter, 4, nwords > 1, nwords == 1, data);
+		if (nwords == 1)
+			t4_write_reg(adapter, SF_OP, 0);    /* unlock SF */
+		if (ret)
+			return ret;
+		if (byte_oriented)
+			*data = htonl(*data);
+	}
+	return 0;
+}
+
+/**
+ *	t4_write_flash - write up to a page of data to the serial flash
+ *	@adapter: the adapter
+ *	@addr: the start address to write
+ *	@n: length of data to write in bytes
+ *	@data: the data to write
+ *
+ *	Writes up to a page of data (256 bytes) to the serial flash starting
+ *	at the given address.  All the data must be written to the same page.
+ */
+static int t4_write_flash(struct adapter *adapter, unsigned int addr,
+			  unsigned int n, const u8 *data)
+{
+	int ret;
+	u32 buf[64];
+	unsigned int i, c, left, val, offset = addr & 0xff;
+
+	if (addr >= SF_SIZE || offset + n > SF_PAGE_SIZE)
+		return -EINVAL;
+
+	val = swab32(addr) | SF_PROG_PAGE;
+
+	if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 ||
+	    (ret = sf1_write(adapter, 4, 1, 1, val)) != 0)
+		goto unlock;
+
+	for (left = n; left; left -= c) {
+		c = min(left, 4U);
+		for (val = 0, i = 0; i < c; ++i)
+			val = (val << 8) + *data++;
+
+		ret = sf1_write(adapter, c, c != left, 1, val);
+		if (ret)
+			goto unlock;
+	}
+	ret = flash_wait_op(adapter, 5, 1);
+	if (ret)
+		goto unlock;
+
+	t4_write_reg(adapter, SF_OP, 0);    /* unlock SF */
+
+	/* Read the page to verify the write succeeded */
+	ret = t4_read_flash(adapter, addr & ~0xff, ARRAY_SIZE(buf), buf, 1);
+	if (ret)
+		return ret;
+
+	if (memcmp(data - n, (u8 *)buf + offset, n)) {
+		dev_err(adapter->pdev_dev,
+			"failed to correctly write the flash page at %#x\n",
+			addr);
+		return -EIO;
+	}
+	return 0;
+
+unlock:
+	t4_write_reg(adapter, SF_OP, 0);    /* unlock SF */
+	return ret;
+}
+
+/**
+ *	get_fw_version - read the firmware version
+ *	@adapter: the adapter
+ *	@vers: where to place the version
+ *
+ *	Reads the FW version from flash.
+ */
+static int get_fw_version(struct adapter *adapter, u32 *vers)
+{
+	return t4_read_flash(adapter,
+			     FW_IMG_START + offsetof(struct fw_hdr, fw_ver), 1,
+			     vers, 0);
+}
+
+/**
+ *	get_tp_version - read the TP microcode version
+ *	@adapter: the adapter
+ *	@vers: where to place the version
+ *
+ *	Reads the TP microcode version from flash.
+ */
+static int get_tp_version(struct adapter *adapter, u32 *vers)
+{
+	return t4_read_flash(adapter, FW_IMG_START + offsetof(struct fw_hdr,
+							      tp_microcode_ver),
+			     1, vers, 0);
+}
+
+/**
+ *	t4_check_fw_version - check if the FW is compatible with this driver
+ *	@adapter: the adapter
+ *
+ *	Checks if an adapter's FW is compatible with the driver.  Returns 0
+ *	if there's exact match, a negative error if the version could not be
+ *	read or there's a major version mismatch, and a positive value if the
+ *	expected major version is found but there's a minor version mismatch.
+ */
+int t4_check_fw_version(struct adapter *adapter)
+{
+	u32 api_vers[2];
+	int ret, major, minor, micro;
+
+	ret = get_fw_version(adapter, &adapter->params.fw_vers);
+	if (!ret)
+		ret = get_tp_version(adapter, &adapter->params.tp_vers);
+	if (!ret)
+		ret = t4_read_flash(adapter,
+			FW_IMG_START + offsetof(struct fw_hdr, intfver_nic),
+			2, api_vers, 1);
+	if (ret)
+		return ret;
+
+	major = FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers);
+	minor = FW_HDR_FW_VER_MINOR_GET(adapter->params.fw_vers);
+	micro = FW_HDR_FW_VER_MICRO_GET(adapter->params.fw_vers);
+	memcpy(adapter->params.api_vers, api_vers,
+	       sizeof(adapter->params.api_vers));
+
+	if (major != FW_VERSION_MAJOR) {            /* major mismatch - fail */
+		dev_err(adapter->pdev_dev,
+			"card FW has major version %u, driver wants %u\n",
+			major, FW_VERSION_MAJOR);
+		return -EINVAL;
+	}
+
+	if (minor == FW_VERSION_MINOR && micro == FW_VERSION_MICRO)
+		return 0;                                   /* perfect match */
+
+	/* Minor/micro version mismatch.  Report it but often it's OK. */
+	return 1;
+}
+
+/**
+ *	t4_flash_erase_sectors - erase a range of flash sectors
+ *	@adapter: the adapter
+ *	@start: the first sector to erase
+ *	@end: the last sector to erase
+ *
+ *	Erases the sectors in the given inclusive range.
+ */
+static int t4_flash_erase_sectors(struct adapter *adapter, int start, int end)
+{
+	int ret = 0;
+
+	while (start <= end) {
+		if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 ||
+		    (ret = sf1_write(adapter, 4, 0, 1,
+				     SF_ERASE_SECTOR | (start << 8))) != 0 ||
+		    (ret = flash_wait_op(adapter, 5, 500)) != 0) {
+			dev_err(adapter->pdev_dev,
+				"erase of flash sector %d failed, error %d\n",
+				start, ret);
+			break;
+		}
+		start++;
+	}
+	t4_write_reg(adapter, SF_OP, 0);    /* unlock SF */
+	return ret;
+}
+
+/**
+ *	t4_load_fw - download firmware
+ *	@adap: the adapter
+ *	@fw_data: the firmware image to write
+ *	@size: image size
+ *
+ *	Write the supplied firmware image to the card's serial flash.
+ */
+int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
+{
+	u32 csum;
+	int ret, addr;
+	unsigned int i;
+	u8 first_page[SF_PAGE_SIZE];
+	const u32 *p = (const u32 *)fw_data;
+	const struct fw_hdr *hdr = (const struct fw_hdr *)fw_data;
+
+	if (!size) {
+		dev_err(adap->pdev_dev, "FW image has no data\n");
+		return -EINVAL;
+	}
+	if (size & 511) {
+		dev_err(adap->pdev_dev,
+			"FW image size not multiple of 512 bytes\n");
+		return -EINVAL;
+	}
+	if (ntohs(hdr->len512) * 512 != size) {
+		dev_err(adap->pdev_dev,
+			"FW image size differs from size in FW header\n");
+		return -EINVAL;
+	}
+	if (size > FW_MAX_SIZE) {
+		dev_err(adap->pdev_dev, "FW image too large, max is %u bytes\n",
+			FW_MAX_SIZE);
+		return -EFBIG;
+	}
+
+	for (csum = 0, i = 0; i < size / sizeof(csum); i++)
+		csum += ntohl(p[i]);
+
+	if (csum != 0xffffffff) {
+		dev_err(adap->pdev_dev,
+			"corrupted firmware image, checksum %#x\n", csum);
+		return -EINVAL;
+	}
+
+	i = DIV_ROUND_UP(size, SF_SEC_SIZE);        /* # of sectors spanned */
+	ret = t4_flash_erase_sectors(adap, FW_START_SEC, FW_START_SEC + i - 1);
+	if (ret)
+		goto out;
+
+	/*
+	 * We write the correct version at the end so the driver can see a bad
+	 * version if the FW write fails.  Start by writing a copy of the
+	 * first page with a bad version.
+	 */
+	memcpy(first_page, fw_data, SF_PAGE_SIZE);
+	((struct fw_hdr *)first_page)->fw_ver = htonl(0xffffffff);
+	ret = t4_write_flash(adap, FW_IMG_START, SF_PAGE_SIZE, first_page);
+	if (ret)
+		goto out;
+
+	addr = FW_IMG_START;
+	for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) {
+		addr += SF_PAGE_SIZE;
+		fw_data += SF_PAGE_SIZE;
+		ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, fw_data);
+		if (ret)
+			goto out;
+	}
+
+	ret = t4_write_flash(adap,
+			     FW_IMG_START + offsetof(struct fw_hdr, fw_ver),
+			     sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver);
+out:
+	if (ret)
+		dev_err(adap->pdev_dev, "firmware download failed, error %d\n",
+			ret);
+	return ret;
+}
+
+#define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\
+		     FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_ANEG)
+
+/**
+ *	t4_link_start - apply link configuration to MAC/PHY
+ *	@phy: the PHY to setup
+ *	@mac: the MAC to setup
+ *	@lc: the requested link configuration
+ *
+ *	Set up a port's MAC and PHY according to a desired link configuration.
+ *	- If the PHY can auto-negotiate first decide what to advertise, then
+ *	  enable/disable auto-negotiation as desired, and reset.
+ *	- If the PHY does not auto-negotiate just reset it.
+ *	- If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
+ *	  otherwise do it later based on the outcome of auto-negotiation.
+ */
+int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port,
+		  struct link_config *lc)
+{
+	struct fw_port_cmd c;
+	unsigned int fc = 0, mdi = FW_PORT_MDI(FW_PORT_MDI_AUTO);
+
+	lc->link_ok = 0;
+	if (lc->requested_fc & PAUSE_RX)
+		fc |= FW_PORT_CAP_FC_RX;
+	if (lc->requested_fc & PAUSE_TX)
+		fc |= FW_PORT_CAP_FC_TX;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) | FW_CMD_REQUEST |
+			       FW_CMD_EXEC | FW_PORT_CMD_PORTID(port));
+	c.action_to_len16 = htonl(FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) |
+				  FW_LEN16(c));
+
+	if (!(lc->supported & FW_PORT_CAP_ANEG)) {
+		c.u.l1cfg.rcap = htonl((lc->supported & ADVERT_MASK) | fc);
+		lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
+	} else if (lc->autoneg == AUTONEG_DISABLE) {
+		c.u.l1cfg.rcap = htonl(lc->requested_speed | fc | mdi);
+		lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
+	} else
+		c.u.l1cfg.rcap = htonl(lc->advertising | fc | mdi);
+
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *	t4_restart_aneg - restart autonegotiation
+ *	@adap: the adapter
+ *	@mbox: mbox to use for the FW command
+ *	@port: the port id
+ *
+ *	Restarts autonegotiation for the selected port.
+ */
+int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port)
+{
+	struct fw_port_cmd c;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) | FW_CMD_REQUEST |
+			       FW_CMD_EXEC | FW_PORT_CMD_PORTID(port));
+	c.action_to_len16 = htonl(FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) |
+				  FW_LEN16(c));
+	c.u.l1cfg.rcap = htonl(FW_PORT_CAP_ANEG);
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *	t4_set_vlan_accel - configure HW VLAN extraction
+ *	@adap: the adapter
+ *	@ports: bitmap of adapter ports to operate on
+ *	@on: enable (1) or disable (0) HW VLAN extraction
+ *
+ *	Enables or disables HW extraction of VLAN tags for the ports specified
+ *	by @ports.  @ports is a bitmap with the ith bit designating the port
+ *	associated with the ith adapter channel.
+ */
+void t4_set_vlan_accel(struct adapter *adap, unsigned int ports, int on)
+{
+	ports <<= VLANEXTENABLE_SHIFT;
+	t4_set_reg_field(adap, TP_OUT_CONFIG, ports, on ? ports : 0);
+}
+
+struct intr_info {
+	unsigned int mask;       /* bits to check in interrupt status */
+	const char *msg;         /* message to print or NULL */
+	short stat_idx;          /* stat counter to increment or -1 */
+	unsigned short fatal;    /* whether the condition reported is fatal */
+};
+
+/**
+ *	t4_handle_intr_status - table driven interrupt handler
+ *	@adapter: the adapter that generated the interrupt
+ *	@reg: the interrupt status register to process
+ *	@acts: table of interrupt actions
+ *
+ *	A table driven interrupt handler that applies a set of masks to an
+ *	interrupt status word and performs the corresponding actions if the
+ *	interrupts described by the mask have occured.  The actions include
+ *	optionally emitting a warning or alert message.  The table is terminated
+ *	by an entry specifying mask 0.  Returns the number of fatal interrupt
+ *	conditions.
+ */
+static int t4_handle_intr_status(struct adapter *adapter, unsigned int reg,
+				 const struct intr_info *acts)
+{
+	int fatal = 0;
+	unsigned int mask = 0;
+	unsigned int status = t4_read_reg(adapter, reg);
+
+	for ( ; acts->mask; ++acts) {
+		if (!(status & acts->mask))
+			continue;
+		if (acts->fatal) {
+			fatal++;
+			dev_alert(adapter->pdev_dev, "%s (0x%x)\n", acts->msg,
+				  status & acts->mask);
+		} else if (acts->msg && printk_ratelimit())
+			dev_warn(adapter->pdev_dev, "%s (0x%x)\n", acts->msg,
+				 status & acts->mask);
+		mask |= acts->mask;
+	}
+	status &= mask;
+	if (status)                           /* clear processed interrupts */
+		t4_write_reg(adapter, reg, status);
+	return fatal;
+}
+
+/*
+ * Interrupt handler for the PCIE module.
+ */
+static void pcie_intr_handler(struct adapter *adapter)
+{
+	static struct intr_info sysbus_intr_info[] = {
+		{ RNPP, "RXNP array parity error", -1, 1 },
+		{ RPCP, "RXPC array parity error", -1, 1 },
+		{ RCIP, "RXCIF array parity error", -1, 1 },
+		{ RCCP, "Rx completions control array parity error", -1, 1 },
+		{ RFTP, "RXFT array parity error", -1, 1 },
+		{ 0 }
+	};
+	static struct intr_info pcie_port_intr_info[] = {
+		{ TPCP, "TXPC array parity error", -1, 1 },
+		{ TNPP, "TXNP array parity error", -1, 1 },
+		{ TFTP, "TXFT array parity error", -1, 1 },
+		{ TCAP, "TXCA array parity error", -1, 1 },
+		{ TCIP, "TXCIF array parity error", -1, 1 },
+		{ RCAP, "RXCA array parity error", -1, 1 },
+		{ OTDD, "outbound request TLP discarded", -1, 1 },
+		{ RDPE, "Rx data parity error", -1, 1 },
+		{ TDUE, "Tx uncorrectable data error", -1, 1 },
+		{ 0 }
+	};
+	static struct intr_info pcie_intr_info[] = {
+		{ MSIADDRLPERR, "MSI AddrL parity error", -1, 1 },
+		{ MSIADDRHPERR, "MSI AddrH parity error", -1, 1 },
+		{ MSIDATAPERR, "MSI data parity error", -1, 1 },
+		{ MSIXADDRLPERR, "MSI-X AddrL parity error", -1, 1 },
+		{ MSIXADDRHPERR, "MSI-X AddrH parity error", -1, 1 },
+		{ MSIXDATAPERR, "MSI-X data parity error", -1, 1 },
+		{ MSIXDIPERR, "MSI-X DI parity error", -1, 1 },
+		{ PIOCPLPERR, "PCI PIO completion FIFO parity error", -1, 1 },
+		{ PIOREQPERR, "PCI PIO request FIFO parity error", -1, 1 },
+		{ TARTAGPERR, "PCI PCI target tag FIFO parity error", -1, 1 },
+		{ CCNTPERR, "PCI CMD channel count parity error", -1, 1 },
+		{ CREQPERR, "PCI CMD channel request parity error", -1, 1 },
+		{ CRSPPERR, "PCI CMD channel response parity error", -1, 1 },
+		{ DCNTPERR, "PCI DMA channel count parity error", -1, 1 },
+		{ DREQPERR, "PCI DMA channel request parity error", -1, 1 },
+		{ DRSPPERR, "PCI DMA channel response parity error", -1, 1 },
+		{ HCNTPERR, "PCI HMA channel count parity error", -1, 1 },
+		{ HREQPERR, "PCI HMA channel request parity error", -1, 1 },
+		{ HRSPPERR, "PCI HMA channel response parity error", -1, 1 },
+		{ CFGSNPPERR, "PCI config snoop FIFO parity error", -1, 1 },
+		{ FIDPERR, "PCI FID parity error", -1, 1 },
+		{ INTXCLRPERR, "PCI INTx clear parity error", -1, 1 },
+		{ MATAGPERR, "PCI MA tag parity error", -1, 1 },
+		{ PIOTAGPERR, "PCI PIO tag parity error", -1, 1 },
+		{ RXCPLPERR, "PCI Rx completion parity error", -1, 1 },
+		{ RXWRPERR, "PCI Rx write parity error", -1, 1 },
+		{ RPLPERR, "PCI replay buffer parity error", -1, 1 },
+		{ PCIESINT, "PCI core secondary fault", -1, 1 },
+		{ PCIEPINT, "PCI core primary fault", -1, 1 },
+		{ UNXSPLCPLERR, "PCI unexpected split completion error", -1, 0 },
+		{ 0 }
+	};
+
+	int fat;
+
+	fat = t4_handle_intr_status(adapter,
+				    PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS,
+				    sysbus_intr_info) +
+	      t4_handle_intr_status(adapter,
+				    PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS,
+				    pcie_port_intr_info) +
+	      t4_handle_intr_status(adapter, PCIE_INT_CAUSE, pcie_intr_info);
+	if (fat)
+		t4_fatal_err(adapter);
+}
+
+/*
+ * TP interrupt handler.
+ */
+static void tp_intr_handler(struct adapter *adapter)
+{
+	static struct intr_info tp_intr_info[] = {
+		{ 0x3fffffff, "TP parity error", -1, 1 },
+		{ FLMTXFLSTEMPTY, "TP out of Tx pages", -1, 1 },
+		{ 0 }
+	};
+
+	if (t4_handle_intr_status(adapter, TP_INT_CAUSE, tp_intr_info))
+		t4_fatal_err(adapter);
+}
+
+/*
+ * SGE interrupt handler.
+ */
+static void sge_intr_handler(struct adapter *adapter)
+{
+	u64 v;
+
+	static struct intr_info sge_intr_info[] = {
+		{ ERR_CPL_EXCEED_IQE_SIZE,
+		  "SGE received CPL exceeding IQE size", -1, 1 },
+		{ ERR_INVALID_CIDX_INC,
+		  "SGE GTS CIDX increment too large", -1, 0 },
+		{ ERR_CPL_OPCODE_0, "SGE received 0-length CPL", -1, 0 },
+		{ ERR_DROPPED_DB, "SGE doorbell dropped", -1, 0 },
+		{ ERR_DATA_CPL_ON_HIGH_QID1 | ERR_DATA_CPL_ON_HIGH_QID0,
+		  "SGE IQID > 1023 received CPL for FL", -1, 0 },
+		{ ERR_BAD_DB_PIDX3, "SGE DBP 3 pidx increment too large", -1,
+		  0 },
+		{ ERR_BAD_DB_PIDX2, "SGE DBP 2 pidx increment too large", -1,
+		  0 },
+		{ ERR_BAD_DB_PIDX1, "SGE DBP 1 pidx increment too large", -1,
+		  0 },
+		{ ERR_BAD_DB_PIDX0, "SGE DBP 0 pidx increment too large", -1,
+		  0 },
+		{ ERR_ING_CTXT_PRIO,
+		  "SGE too many priority ingress contexts", -1, 0 },
+		{ ERR_EGR_CTXT_PRIO,
+		  "SGE too many priority egress contexts", -1, 0 },
+		{ INGRESS_SIZE_ERR, "SGE illegal ingress QID", -1, 0 },
+		{ EGRESS_SIZE_ERR, "SGE illegal egress QID", -1, 0 },
+		{ 0 }
+	};
+
+	v = (u64)t4_read_reg(adapter, SGE_INT_CAUSE1) |
+	    ((u64)t4_read_reg(adapter, SGE_INT_CAUSE2) << 32);
+	if (v) {
+		dev_alert(adapter->pdev_dev, "SGE parity error (%#llx)\n",
+			 (unsigned long long)v);
+		t4_write_reg(adapter, SGE_INT_CAUSE1, v);
+		t4_write_reg(adapter, SGE_INT_CAUSE2, v >> 32);
+	}
+
+	if (t4_handle_intr_status(adapter, SGE_INT_CAUSE3, sge_intr_info) ||
+	    v != 0)
+		t4_fatal_err(adapter);
+}
+
+/*
+ * CIM interrupt handler.
+ */
+static void cim_intr_handler(struct adapter *adapter)
+{
+	static struct intr_info cim_intr_info[] = {
+		{ PREFDROPINT, "CIM control register prefetch drop", -1, 1 },
+		{ OBQPARERR, "CIM OBQ parity error", -1, 1 },
+		{ IBQPARERR, "CIM IBQ parity error", -1, 1 },
+		{ MBUPPARERR, "CIM mailbox uP parity error", -1, 1 },
+		{ MBHOSTPARERR, "CIM mailbox host parity error", -1, 1 },
+		{ TIEQINPARERRINT, "CIM TIEQ outgoing parity error", -1, 1 },
+		{ TIEQOUTPARERRINT, "CIM TIEQ incoming parity error", -1, 1 },
+		{ 0 }
+	};
+	static struct intr_info cim_upintr_info[] = {
+		{ RSVDSPACEINT, "CIM reserved space access", -1, 1 },
+		{ ILLTRANSINT, "CIM illegal transaction", -1, 1 },
+		{ ILLWRINT, "CIM illegal write", -1, 1 },
+		{ ILLRDINT, "CIM illegal read", -1, 1 },
+		{ ILLRDBEINT, "CIM illegal read BE", -1, 1 },
+		{ ILLWRBEINT, "CIM illegal write BE", -1, 1 },
+		{ SGLRDBOOTINT, "CIM single read from boot space", -1, 1 },
+		{ SGLWRBOOTINT, "CIM single write to boot space", -1, 1 },
+		{ BLKWRBOOTINT, "CIM block write to boot space", -1, 1 },
+		{ SGLRDFLASHINT, "CIM single read from flash space", -1, 1 },
+		{ SGLWRFLASHINT, "CIM single write to flash space", -1, 1 },
+		{ BLKWRFLASHINT, "CIM block write to flash space", -1, 1 },
+		{ SGLRDEEPROMINT, "CIM single EEPROM read", -1, 1 },
+		{ SGLWREEPROMINT, "CIM single EEPROM write", -1, 1 },
+		{ BLKRDEEPROMINT, "CIM block EEPROM read", -1, 1 },
+		{ BLKWREEPROMINT, "CIM block EEPROM write", -1, 1 },
+		{ SGLRDCTLINT , "CIM single read from CTL space", -1, 1 },
+		{ SGLWRCTLINT , "CIM single write to CTL space", -1, 1 },
+		{ BLKRDCTLINT , "CIM block read from CTL space", -1, 1 },
+		{ BLKWRCTLINT , "CIM block write to CTL space", -1, 1 },
+		{ SGLRDPLINT , "CIM single read from PL space", -1, 1 },
+		{ SGLWRPLINT , "CIM single write to PL space", -1, 1 },
+		{ BLKRDPLINT , "CIM block read from PL space", -1, 1 },
+		{ BLKWRPLINT , "CIM block write to PL space", -1, 1 },
+		{ REQOVRLOOKUPINT , "CIM request FIFO overwrite", -1, 1 },
+		{ RSPOVRLOOKUPINT , "CIM response FIFO overwrite", -1, 1 },
+		{ TIMEOUTINT , "CIM PIF timeout", -1, 1 },
+		{ TIMEOUTMAINT , "CIM PIF MA timeout", -1, 1 },
+		{ 0 }
+	};
+
+	int fat;
+
+	fat = t4_handle_intr_status(adapter, CIM_HOST_INT_CAUSE,
+				    cim_intr_info) +
+	      t4_handle_intr_status(adapter, CIM_HOST_UPACC_INT_CAUSE,
+				    cim_upintr_info);
+	if (fat)
+		t4_fatal_err(adapter);
+}
+
+/*
+ * ULP RX interrupt handler.
+ */
+static void ulprx_intr_handler(struct adapter *adapter)
+{
+	static struct intr_info ulprx_intr_info[] = {
+		{ 0x7fffff, "ULPRX parity error", -1, 1 },
+		{ 0 }
+	};
+
+	if (t4_handle_intr_status(adapter, ULP_RX_INT_CAUSE, ulprx_intr_info))
+		t4_fatal_err(adapter);
+}
+
+/*
+ * ULP TX interrupt handler.
+ */
+static void ulptx_intr_handler(struct adapter *adapter)
+{
+	static struct intr_info ulptx_intr_info[] = {
+		{ PBL_BOUND_ERR_CH3, "ULPTX channel 3 PBL out of bounds", -1,
+		  0 },
+		{ PBL_BOUND_ERR_CH2, "ULPTX channel 2 PBL out of bounds", -1,
+		  0 },
+		{ PBL_BOUND_ERR_CH1, "ULPTX channel 1 PBL out of bounds", -1,
+		  0 },
+		{ PBL_BOUND_ERR_CH0, "ULPTX channel 0 PBL out of bounds", -1,
+		  0 },
+		{ 0xfffffff, "ULPTX parity error", -1, 1 },
+		{ 0 }
+	};
+
+	if (t4_handle_intr_status(adapter, ULP_TX_INT_CAUSE, ulptx_intr_info))
+		t4_fatal_err(adapter);
+}
+
+/*
+ * PM TX interrupt handler.
+ */
+static void pmtx_intr_handler(struct adapter *adapter)
+{
+	static struct intr_info pmtx_intr_info[] = {
+		{ PCMD_LEN_OVFL0, "PMTX channel 0 pcmd too large", -1, 1 },
+		{ PCMD_LEN_OVFL1, "PMTX channel 1 pcmd too large", -1, 1 },
+		{ PCMD_LEN_OVFL2, "PMTX channel 2 pcmd too large", -1, 1 },
+		{ ZERO_C_CMD_ERROR, "PMTX 0-length pcmd", -1, 1 },
+		{ PMTX_FRAMING_ERROR, "PMTX framing error", -1, 1 },
+		{ OESPI_PAR_ERROR, "PMTX oespi parity error", -1, 1 },
+		{ DB_OPTIONS_PAR_ERROR, "PMTX db_options parity error", -1, 1 },
+		{ ICSPI_PAR_ERROR, "PMTX icspi parity error", -1, 1 },
+		{ C_PCMD_PAR_ERROR, "PMTX c_pcmd parity error", -1, 1},
+		{ 0 }
+	};
+
+	if (t4_handle_intr_status(adapter, PM_TX_INT_CAUSE, pmtx_intr_info))
+		t4_fatal_err(adapter);
+}
+
+/*
+ * PM RX interrupt handler.
+ */
+static void pmrx_intr_handler(struct adapter *adapter)
+{
+	static struct intr_info pmrx_intr_info[] = {
+		{ ZERO_E_CMD_ERROR, "PMRX 0-length pcmd", -1, 1 },
+		{ PMRX_FRAMING_ERROR, "PMRX framing error", -1, 1 },
+		{ OCSPI_PAR_ERROR, "PMRX ocspi parity error", -1, 1 },
+		{ DB_OPTIONS_PAR_ERROR, "PMRX db_options parity error", -1, 1 },
+		{ IESPI_PAR_ERROR, "PMRX iespi parity error", -1, 1 },
+		{ E_PCMD_PAR_ERROR, "PMRX e_pcmd parity error", -1, 1},
+		{ 0 }
+	};
+
+	if (t4_handle_intr_status(adapter, PM_RX_INT_CAUSE, pmrx_intr_info))
+		t4_fatal_err(adapter);
+}
+
+/*
+ * CPL switch interrupt handler.
+ */
+static void cplsw_intr_handler(struct adapter *adapter)
+{
+	static struct intr_info cplsw_intr_info[] = {
+		{ CIM_OP_MAP_PERR, "CPLSW CIM op_map parity error", -1, 1 },
+		{ CIM_OVFL_ERROR, "CPLSW CIM overflow", -1, 1 },
+		{ TP_FRAMING_ERROR, "CPLSW TP framing error", -1, 1 },
+		{ SGE_FRAMING_ERROR, "CPLSW SGE framing error", -1, 1 },
+		{ CIM_FRAMING_ERROR, "CPLSW CIM framing error", -1, 1 },
+		{ ZERO_SWITCH_ERROR, "CPLSW no-switch error", -1, 1 },
+		{ 0 }
+	};
+
+	if (t4_handle_intr_status(adapter, CPL_INTR_CAUSE, cplsw_intr_info))
+		t4_fatal_err(adapter);
+}
+
+/*
+ * LE interrupt handler.
+ */
+static void le_intr_handler(struct adapter *adap)
+{
+	static struct intr_info le_intr_info[] = {
+		{ LIPMISS, "LE LIP miss", -1, 0 },
+		{ LIP0, "LE 0 LIP error", -1, 0 },
+		{ PARITYERR, "LE parity error", -1, 1 },
+		{ UNKNOWNCMD, "LE unknown command", -1, 1 },
+		{ REQQPARERR, "LE request queue parity error", -1, 1 },
+		{ 0 }
+	};
+
+	if (t4_handle_intr_status(adap, LE_DB_INT_CAUSE, le_intr_info))
+		t4_fatal_err(adap);
+}
+
+/*
+ * MPS interrupt handler.
+ */
+static void mps_intr_handler(struct adapter *adapter)
+{
+	static struct intr_info mps_rx_intr_info[] = {
+		{ 0xffffff, "MPS Rx parity error", -1, 1 },
+		{ 0 }
+	};
+	static struct intr_info mps_tx_intr_info[] = {
+		{ TPFIFO, "MPS Tx TP FIFO parity error", -1, 1 },
+		{ NCSIFIFO, "MPS Tx NC-SI FIFO parity error", -1, 1 },
+		{ TXDATAFIFO, "MPS Tx data FIFO parity error", -1, 1 },
+		{ TXDESCFIFO, "MPS Tx desc FIFO parity error", -1, 1 },
+		{ BUBBLE, "MPS Tx underflow", -1, 1 },
+		{ SECNTERR, "MPS Tx SOP/EOP error", -1, 1 },
+		{ FRMERR, "MPS Tx framing error", -1, 1 },
+		{ 0 }
+	};
+	static struct intr_info mps_trc_intr_info[] = {
+		{ FILTMEM, "MPS TRC filter parity error", -1, 1 },
+		{ PKTFIFO, "MPS TRC packet FIFO parity error", -1, 1 },
+		{ MISCPERR, "MPS TRC misc parity error", -1, 1 },
+		{ 0 }
+	};
+	static struct intr_info mps_stat_sram_intr_info[] = {
+		{ 0x1fffff, "MPS statistics SRAM parity error", -1, 1 },
+		{ 0 }
+	};
+	static struct intr_info mps_stat_tx_intr_info[] = {
+		{ 0xfffff, "MPS statistics Tx FIFO parity error", -1, 1 },
+		{ 0 }
+	};
+	static struct intr_info mps_stat_rx_intr_info[] = {
+		{ 0xffffff, "MPS statistics Rx FIFO parity error", -1, 1 },
+		{ 0 }
+	};
+	static struct intr_info mps_cls_intr_info[] = {
+		{ MATCHSRAM, "MPS match SRAM parity error", -1, 1 },
+		{ MATCHTCAM, "MPS match TCAM parity error", -1, 1 },
+		{ HASHSRAM, "MPS hash SRAM parity error", -1, 1 },
+		{ 0 }
+	};
+
+	int fat;
+
+	fat = t4_handle_intr_status(adapter, MPS_RX_PERR_INT_CAUSE,
+				    mps_rx_intr_info) +
+	      t4_handle_intr_status(adapter, MPS_TX_INT_CAUSE,
+				    mps_tx_intr_info) +
+	      t4_handle_intr_status(adapter, MPS_TRC_INT_CAUSE,
+				    mps_trc_intr_info) +
+	      t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_SRAM,
+				    mps_stat_sram_intr_info) +
+	      t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_TX_FIFO,
+				    mps_stat_tx_intr_info) +
+	      t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_RX_FIFO,
+				    mps_stat_rx_intr_info) +
+	      t4_handle_intr_status(adapter, MPS_CLS_INT_CAUSE,
+				    mps_cls_intr_info);
+
+	t4_write_reg(adapter, MPS_INT_CAUSE, CLSINT | TRCINT |
+		     RXINT | TXINT | STATINT);
+	t4_read_reg(adapter, MPS_INT_CAUSE);                    /* flush */
+	if (fat)
+		t4_fatal_err(adapter);
+}
+
+#define MEM_INT_MASK (PERR_INT_CAUSE | ECC_CE_INT_CAUSE | ECC_UE_INT_CAUSE)
+
+/*
+ * EDC/MC interrupt handler.
+ */
+static void mem_intr_handler(struct adapter *adapter, int idx)
+{
+	static const char name[3][5] = { "EDC0", "EDC1", "MC" };
+
+	unsigned int addr, cnt_addr, v;
+
+	if (idx <= MEM_EDC1) {
+		addr = EDC_REG(EDC_INT_CAUSE, idx);
+		cnt_addr = EDC_REG(EDC_ECC_STATUS, idx);
+	} else {
+		addr = MC_INT_CAUSE;
+		cnt_addr = MC_ECC_STATUS;
+	}
+
+	v = t4_read_reg(adapter, addr) & MEM_INT_MASK;
+	if (v & PERR_INT_CAUSE)
+		dev_alert(adapter->pdev_dev, "%s FIFO parity error\n",
+			  name[idx]);
+	if (v & ECC_CE_INT_CAUSE) {
+		u32 cnt = ECC_CECNT_GET(t4_read_reg(adapter, cnt_addr));
+
+		t4_write_reg(adapter, cnt_addr, ECC_CECNT_MASK);
+		if (printk_ratelimit())
+			dev_warn(adapter->pdev_dev,
+				 "%u %s correctable ECC data error%s\n",
+				 cnt, name[idx], cnt > 1 ? "s" : "");
+	}
+	if (v & ECC_UE_INT_CAUSE)
+		dev_alert(adapter->pdev_dev,
+			  "%s uncorrectable ECC data error\n", name[idx]);
+
+	t4_write_reg(adapter, addr, v);
+	if (v & (PERR_INT_CAUSE | ECC_UE_INT_CAUSE))
+		t4_fatal_err(adapter);
+}
+
+/*
+ * MA interrupt handler.
+ */
+static void ma_intr_handler(struct adapter *adap)
+{
+	u32 v, status = t4_read_reg(adap, MA_INT_CAUSE);
+
+	if (status & MEM_PERR_INT_CAUSE)
+		dev_alert(adap->pdev_dev,
+			  "MA parity error, parity status %#x\n",
+			  t4_read_reg(adap, MA_PARITY_ERROR_STATUS));
+	if (status & MEM_WRAP_INT_CAUSE) {
+		v = t4_read_reg(adap, MA_INT_WRAP_STATUS);
+		dev_alert(adap->pdev_dev, "MA address wrap-around error by "
+			  "client %u to address %#x\n",
+			  MEM_WRAP_CLIENT_NUM_GET(v),
+			  MEM_WRAP_ADDRESS_GET(v) << 4);
+	}
+	t4_write_reg(adap, MA_INT_CAUSE, status);
+	t4_fatal_err(adap);
+}
+
+/*
+ * SMB interrupt handler.
+ */
+static void smb_intr_handler(struct adapter *adap)
+{
+	static struct intr_info smb_intr_info[] = {
+		{ MSTTXFIFOPARINT, "SMB master Tx FIFO parity error", -1, 1 },
+		{ MSTRXFIFOPARINT, "SMB master Rx FIFO parity error", -1, 1 },
+		{ SLVFIFOPARINT, "SMB slave FIFO parity error", -1, 1 },
+		{ 0 }
+	};
+
+	if (t4_handle_intr_status(adap, SMB_INT_CAUSE, smb_intr_info))
+		t4_fatal_err(adap);
+}
+
+/*
+ * NC-SI interrupt handler.
+ */
+static void ncsi_intr_handler(struct adapter *adap)
+{
+	static struct intr_info ncsi_intr_info[] = {
+		{ CIM_DM_PRTY_ERR, "NC-SI CIM parity error", -1, 1 },
+		{ MPS_DM_PRTY_ERR, "NC-SI MPS parity error", -1, 1 },
+		{ TXFIFO_PRTY_ERR, "NC-SI Tx FIFO parity error", -1, 1 },
+		{ RXFIFO_PRTY_ERR, "NC-SI Rx FIFO parity error", -1, 1 },
+		{ 0 }
+	};
+
+	if (t4_handle_intr_status(adap, NCSI_INT_CAUSE, ncsi_intr_info))
+		t4_fatal_err(adap);
+}
+
+/*
+ * XGMAC interrupt handler.
+ */
+static void xgmac_intr_handler(struct adapter *adap, int port)
+{
+	u32 v = t4_read_reg(adap, PORT_REG(port, XGMAC_PORT_INT_CAUSE));
+
+	v &= TXFIFO_PRTY_ERR | RXFIFO_PRTY_ERR;
+	if (!v)
+		return;
+
+	if (v & TXFIFO_PRTY_ERR)
+		dev_alert(adap->pdev_dev, "XGMAC %d Tx FIFO parity error\n",
+			  port);
+	if (v & RXFIFO_PRTY_ERR)
+		dev_alert(adap->pdev_dev, "XGMAC %d Rx FIFO parity error\n",
+			  port);
+	t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_INT_CAUSE), v);
+	t4_fatal_err(adap);
+}
+
+/*
+ * PL interrupt handler.
+ */
+static void pl_intr_handler(struct adapter *adap)
+{
+	static struct intr_info pl_intr_info[] = {
+		{ FATALPERR, "T4 fatal parity error", -1, 1 },
+		{ PERRVFID, "PL VFID_MAP parity error", -1, 1 },
+		{ 0 }
+	};
+
+	if (t4_handle_intr_status(adap, PL_PL_INT_CAUSE, pl_intr_info))
+		t4_fatal_err(adap);
+}
+
+#define PF_INTR_MASK (PFSW | PFCIM)
+#define GLBL_INTR_MASK (CIM | MPS | PL | PCIE | MC | EDC0 | \
+		EDC1 | LE | TP | MA | PM_TX | PM_RX | ULP_RX | \
+		CPL_SWITCH | SGE | ULP_TX)
+
+/**
+ *	t4_slow_intr_handler - control path interrupt handler
+ *	@adapter: the adapter
+ *
+ *	T4 interrupt handler for non-data global interrupt events, e.g., errors.
+ *	The designation 'slow' is because it involves register reads, while
+ *	data interrupts typically don't involve any MMIOs.
+ */
+int t4_slow_intr_handler(struct adapter *adapter)
+{
+	u32 cause = t4_read_reg(adapter, PL_INT_CAUSE);
+
+	if (!(cause & GLBL_INTR_MASK))
+		return 0;
+	if (cause & CIM)
+		cim_intr_handler(adapter);
+	if (cause & MPS)
+		mps_intr_handler(adapter);
+	if (cause & NCSI)
+		ncsi_intr_handler(adapter);
+	if (cause & PL)
+		pl_intr_handler(adapter);
+	if (cause & SMB)
+		smb_intr_handler(adapter);
+	if (cause & XGMAC0)
+		xgmac_intr_handler(adapter, 0);
+	if (cause & XGMAC1)
+		xgmac_intr_handler(adapter, 1);
+	if (cause & XGMAC_KR0)
+		xgmac_intr_handler(adapter, 2);
+	if (cause & XGMAC_KR1)
+		xgmac_intr_handler(adapter, 3);
+	if (cause & PCIE)
+		pcie_intr_handler(adapter);
+	if (cause & MC)
+		mem_intr_handler(adapter, MEM_MC);
+	if (cause & EDC0)
+		mem_intr_handler(adapter, MEM_EDC0);
+	if (cause & EDC1)
+		mem_intr_handler(adapter, MEM_EDC1);
+	if (cause & LE)
+		le_intr_handler(adapter);
+	if (cause & TP)
+		tp_intr_handler(adapter);
+	if (cause & MA)
+		ma_intr_handler(adapter);
+	if (cause & PM_TX)
+		pmtx_intr_handler(adapter);
+	if (cause & PM_RX)
+		pmrx_intr_handler(adapter);
+	if (cause & ULP_RX)
+		ulprx_intr_handler(adapter);
+	if (cause & CPL_SWITCH)
+		cplsw_intr_handler(adapter);
+	if (cause & SGE)
+		sge_intr_handler(adapter);
+	if (cause & ULP_TX)
+		ulptx_intr_handler(adapter);
+
+	/* Clear the interrupts just processed for which we are the master. */
+	t4_write_reg(adapter, PL_INT_CAUSE, cause & GLBL_INTR_MASK);
+	(void) t4_read_reg(adapter, PL_INT_CAUSE); /* flush */
+	return 1;
+}
+
+/**
+ *	t4_intr_enable - enable interrupts
+ *	@adapter: the adapter whose interrupts should be enabled
+ *
+ *	Enable PF-specific interrupts for the calling function and the top-level
+ *	interrupt concentrator for global interrupts.  Interrupts are already
+ *	enabled at each module,	here we just enable the roots of the interrupt
+ *	hierarchies.
+ *
+ *	Note: this function should be called only when the driver manages
+ *	non PF-specific interrupts from the various HW modules.  Only one PCI
+ *	function at a time should be doing this.
+ */
+void t4_intr_enable(struct adapter *adapter)
+{
+	u32 pf = SOURCEPF_GET(t4_read_reg(adapter, PL_WHOAMI));
+
+	t4_write_reg(adapter, SGE_INT_ENABLE3, ERR_CPL_EXCEED_IQE_SIZE |
+		     ERR_INVALID_CIDX_INC | ERR_CPL_OPCODE_0 |
+		     ERR_DROPPED_DB | ERR_DATA_CPL_ON_HIGH_QID1 |
+		     ERR_DATA_CPL_ON_HIGH_QID0 | ERR_BAD_DB_PIDX3 |
+		     ERR_BAD_DB_PIDX2 | ERR_BAD_DB_PIDX1 |
+		     ERR_BAD_DB_PIDX0 | ERR_ING_CTXT_PRIO |
+		     ERR_EGR_CTXT_PRIO | INGRESS_SIZE_ERR |
+		     EGRESS_SIZE_ERR);
+	t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE), PF_INTR_MASK);
+	t4_set_reg_field(adapter, PL_INT_MAP0, 0, 1 << pf);
+}
+
+/**
+ *	t4_intr_disable - disable interrupts
+ *	@adapter: the adapter whose interrupts should be disabled
+ *
+ *	Disable interrupts.  We only disable the top-level interrupt
+ *	concentrators.  The caller must be a PCI function managing global
+ *	interrupts.
+ */
+void t4_intr_disable(struct adapter *adapter)
+{
+	u32 pf = SOURCEPF_GET(t4_read_reg(adapter, PL_WHOAMI));
+
+	t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE), 0);
+	t4_set_reg_field(adapter, PL_INT_MAP0, 1 << pf, 0);
+}
+
+/**
+ *	t4_intr_clear - clear all interrupts
+ *	@adapter: the adapter whose interrupts should be cleared
+ *
+ *	Clears all interrupts.  The caller must be a PCI function managing
+ *	global interrupts.
+ */
+void t4_intr_clear(struct adapter *adapter)
+{
+	static const unsigned int cause_reg[] = {
+		SGE_INT_CAUSE1, SGE_INT_CAUSE2, SGE_INT_CAUSE3,
+		PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS,
+		PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS,
+		PCIE_NONFAT_ERR, PCIE_INT_CAUSE,
+		MC_INT_CAUSE,
+		MA_INT_WRAP_STATUS, MA_PARITY_ERROR_STATUS, MA_INT_CAUSE,
+		EDC_INT_CAUSE, EDC_REG(EDC_INT_CAUSE, 1),
+		CIM_HOST_INT_CAUSE, CIM_HOST_UPACC_INT_CAUSE,
+		MYPF_REG(CIM_PF_HOST_INT_CAUSE),
+		TP_INT_CAUSE,
+		ULP_RX_INT_CAUSE, ULP_TX_INT_CAUSE,
+		PM_RX_INT_CAUSE, PM_TX_INT_CAUSE,
+		MPS_RX_PERR_INT_CAUSE,
+		CPL_INTR_CAUSE,
+		MYPF_REG(PL_PF_INT_CAUSE),
+		PL_PL_INT_CAUSE,
+		LE_DB_INT_CAUSE,
+	};
+
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(cause_reg); ++i)
+		t4_write_reg(adapter, cause_reg[i], 0xffffffff);
+
+	t4_write_reg(adapter, PL_INT_CAUSE, GLBL_INTR_MASK);
+	(void) t4_read_reg(adapter, PL_INT_CAUSE);          /* flush */
+}
+
+/**
+ *	hash_mac_addr - return the hash value of a MAC address
+ *	@addr: the 48-bit Ethernet MAC address
+ *
+ *	Hashes a MAC address according to the hash function used by HW inexact
+ *	(hash) address matching.
+ */
+static int hash_mac_addr(const u8 *addr)
+{
+	u32 a = ((u32)addr[0] << 16) | ((u32)addr[1] << 8) | addr[2];
+	u32 b = ((u32)addr[3] << 16) | ((u32)addr[4] << 8) | addr[5];
+	a ^= b;
+	a ^= (a >> 12);
+	a ^= (a >> 6);
+	return a & 0x3f;
+}
+
+/**
+ *	t4_config_rss_range - configure a portion of the RSS mapping table
+ *	@adapter: the adapter
+ *	@mbox: mbox to use for the FW command
+ *	@viid: virtual interface whose RSS subtable is to be written
+ *	@start: start entry in the table to write
+ *	@n: how many table entries to write
+ *	@rspq: values for the response queue lookup table
+ *	@nrspq: number of values in @rspq
+ *
+ *	Programs the selected part of the VI's RSS mapping table with the
+ *	provided values.  If @nrspq < @n the supplied values are used repeatedly
+ *	until the full table range is populated.
+ *
+ *	The caller must ensure the values in @rspq are in the range allowed for
+ *	@viid.
+ */
+int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
+			int start, int n, const u16 *rspq, unsigned int nrspq)
+{
+	int ret;
+	const u16 *rsp = rspq;
+	const u16 *rsp_end = rspq + nrspq;
+	struct fw_rss_ind_tbl_cmd cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.op_to_viid = htonl(FW_CMD_OP(FW_RSS_IND_TBL_CMD) |
+			       FW_CMD_REQUEST | FW_CMD_WRITE |
+			       FW_RSS_IND_TBL_CMD_VIID(viid));
+	cmd.retval_len16 = htonl(FW_LEN16(cmd));
+
+	/* each fw_rss_ind_tbl_cmd takes up to 32 entries */
+	while (n > 0) {
+		int nq = min(n, 32);
+		__be32 *qp = &cmd.iq0_to_iq2;
+
+		cmd.niqid = htons(nq);
+		cmd.startidx = htons(start);
+
+		start += nq;
+		n -= nq;
+
+		while (nq > 0) {
+			unsigned int v;
+
+			v = FW_RSS_IND_TBL_CMD_IQ0(*rsp);
+			if (++rsp >= rsp_end)
+				rsp = rspq;
+			v |= FW_RSS_IND_TBL_CMD_IQ1(*rsp);
+			if (++rsp >= rsp_end)
+				rsp = rspq;
+			v |= FW_RSS_IND_TBL_CMD_IQ2(*rsp);
+			if (++rsp >= rsp_end)
+				rsp = rspq;
+
+			*qp++ = htonl(v);
+			nq -= 3;
+		}
+
+		ret = t4_wr_mbox(adapter, mbox, &cmd, sizeof(cmd), NULL);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+
+/**
+ *	t4_config_glbl_rss - configure the global RSS mode
+ *	@adapter: the adapter
+ *	@mbox: mbox to use for the FW command
+ *	@mode: global RSS mode
+ *	@flags: mode-specific flags
+ *
+ *	Sets the global RSS mode.
+ */
+int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode,
+		       unsigned int flags)
+{
+	struct fw_rss_glb_config_cmd c;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_write = htonl(FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) |
+			      FW_CMD_REQUEST | FW_CMD_WRITE);
+	c.retval_len16 = htonl(FW_LEN16(c));
+	if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL) {
+		c.u.manual.mode_pkd = htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode));
+	} else if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL) {
+		c.u.basicvirtual.mode_pkd =
+			htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode));
+		c.u.basicvirtual.synmapen_to_hashtoeplitz = htonl(flags);
+	} else
+		return -EINVAL;
+	return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL);
+}
+
+/* Read an RSS table row */
+static int rd_rss_row(struct adapter *adap, int row, u32 *val)
+{
+	t4_write_reg(adap, TP_RSS_LKP_TABLE, 0xfff00000 | row);
+	return t4_wait_op_done_val(adap, TP_RSS_LKP_TABLE, LKPTBLROWVLD, 1,
+				   5, 0, val);
+}
+
+/**
+ *	t4_read_rss - read the contents of the RSS mapping table
+ *	@adapter: the adapter
+ *	@map: holds the contents of the RSS mapping table
+ *
+ *	Reads the contents of the RSS hash->queue mapping table.
+ */
+int t4_read_rss(struct adapter *adapter, u16 *map)
+{
+	u32 val;
+	int i, ret;
+
+	for (i = 0; i < RSS_NENTRIES / 2; ++i) {
+		ret = rd_rss_row(adapter, i, &val);
+		if (ret)
+			return ret;
+		*map++ = LKPTBLQUEUE0_GET(val);
+		*map++ = LKPTBLQUEUE1_GET(val);
+	}
+	return 0;
+}
+
+/**
+ *	t4_tp_get_tcp_stats - read TP's TCP MIB counters
+ *	@adap: the adapter
+ *	@v4: holds the TCP/IP counter values
+ *	@v6: holds the TCP/IPv6 counter values
+ *
+ *	Returns the values of TP's TCP/IP and TCP/IPv6 MIB counters.
+ *	Either @v4 or @v6 may be %NULL to skip the corresponding stats.
+ */
+void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4,
+			 struct tp_tcp_stats *v6)
+{
+	u32 val[TP_MIB_TCP_RXT_SEG_LO - TP_MIB_TCP_OUT_RST + 1];
+
+#define STAT_IDX(x) ((TP_MIB_TCP_##x) - TP_MIB_TCP_OUT_RST)
+#define STAT(x)     val[STAT_IDX(x)]
+#define STAT64(x)   (((u64)STAT(x##_HI) << 32) | STAT(x##_LO))
+
+	if (v4) {
+		t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, val,
+				 ARRAY_SIZE(val), TP_MIB_TCP_OUT_RST);
+		v4->tcpOutRsts = STAT(OUT_RST);
+		v4->tcpInSegs  = STAT64(IN_SEG);
+		v4->tcpOutSegs = STAT64(OUT_SEG);
+		v4->tcpRetransSegs = STAT64(RXT_SEG);
+	}
+	if (v6) {
+		t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, val,
+				 ARRAY_SIZE(val), TP_MIB_TCP_V6OUT_RST);
+		v6->tcpOutRsts = STAT(OUT_RST);
+		v6->tcpInSegs  = STAT64(IN_SEG);
+		v6->tcpOutSegs = STAT64(OUT_SEG);
+		v6->tcpRetransSegs = STAT64(RXT_SEG);
+	}
+#undef STAT64
+#undef STAT
+#undef STAT_IDX
+}
+
+/**
+ *	t4_tp_get_err_stats - read TP's error MIB counters
+ *	@adap: the adapter
+ *	@st: holds the counter values
+ *
+ *	Returns the values of TP's error counters.
+ */
+void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st)
+{
+	t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->macInErrs,
+			 12, TP_MIB_MAC_IN_ERR_0);
+	t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tnlCongDrops,
+			 8, TP_MIB_TNL_CNG_DROP_0);
+	t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tnlTxDrops,
+			 4, TP_MIB_TNL_DROP_0);
+	t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->ofldVlanDrops,
+			 4, TP_MIB_OFD_VLN_DROP_0);
+	t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tcp6InErrs,
+			 4, TP_MIB_TCP_V6IN_ERR_0);
+	t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, &st->ofldNoNeigh,
+			 2, TP_MIB_OFD_ARP_DROP);
+}
+
+/**
+ *	t4_read_mtu_tbl - returns the values in the HW path MTU table
+ *	@adap: the adapter
+ *	@mtus: where to store the MTU values
+ *	@mtu_log: where to store the MTU base-2 log (may be %NULL)
+ *
+ *	Reads the HW path MTU table.
+ */
+void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log)
+{
+	u32 v;
+	int i;
+
+	for (i = 0; i < NMTUS; ++i) {
+		t4_write_reg(adap, TP_MTU_TABLE,
+			     MTUINDEX(0xff) | MTUVALUE(i));
+		v = t4_read_reg(adap, TP_MTU_TABLE);
+		mtus[i] = MTUVALUE_GET(v);
+		if (mtu_log)
+			mtu_log[i] = MTUWIDTH_GET(v);
+	}
+}
+
+/**
+ *	init_cong_ctrl - initialize congestion control parameters
+ *	@a: the alpha values for congestion control
+ *	@b: the beta values for congestion control
+ *
+ *	Initialize the congestion control parameters.
+ */
+static void __devinit init_cong_ctrl(unsigned short *a, unsigned short *b)
+{
+	a[0] = a[1] = a[2] = a[3] = a[4] = a[5] = a[6] = a[7] = a[8] = 1;
+	a[9] = 2;
+	a[10] = 3;
+	a[11] = 4;
+	a[12] = 5;
+	a[13] = 6;
+	a[14] = 7;
+	a[15] = 8;
+	a[16] = 9;
+	a[17] = 10;
+	a[18] = 14;
+	a[19] = 17;
+	a[20] = 21;
+	a[21] = 25;
+	a[22] = 30;
+	a[23] = 35;
+	a[24] = 45;
+	a[25] = 60;
+	a[26] = 80;
+	a[27] = 100;
+	a[28] = 200;
+	a[29] = 300;
+	a[30] = 400;
+	a[31] = 500;
+
+	b[0] = b[1] = b[2] = b[3] = b[4] = b[5] = b[6] = b[7] = b[8] = 0;
+	b[9] = b[10] = 1;
+	b[11] = b[12] = 2;
+	b[13] = b[14] = b[15] = b[16] = 3;
+	b[17] = b[18] = b[19] = b[20] = b[21] = 4;
+	b[22] = b[23] = b[24] = b[25] = b[26] = b[27] = 5;
+	b[28] = b[29] = 6;
+	b[30] = b[31] = 7;
+}
+
+/* The minimum additive increment value for the congestion control table */
+#define CC_MIN_INCR 2U
+
+/**
+ *	t4_load_mtus - write the MTU and congestion control HW tables
+ *	@adap: the adapter
+ *	@mtus: the values for the MTU table
+ *	@alpha: the values for the congestion control alpha parameter
+ *	@beta: the values for the congestion control beta parameter
+ *
+ *	Write the HW MTU table with the supplied MTUs and the high-speed
+ *	congestion control table with the supplied alpha, beta, and MTUs.
+ *	We write the two tables together because the additive increments
+ *	depend on the MTUs.
+ */
+void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
+		  const unsigned short *alpha, const unsigned short *beta)
+{
+	static const unsigned int avg_pkts[NCCTRL_WIN] = {
+		2, 6, 10, 14, 20, 28, 40, 56, 80, 112, 160, 224, 320, 448, 640,
+		896, 1281, 1792, 2560, 3584, 5120, 7168, 10240, 14336, 20480,
+		28672, 40960, 57344, 81920, 114688, 163840, 229376
+	};
+
+	unsigned int i, w;
+
+	for (i = 0; i < NMTUS; ++i) {
+		unsigned int mtu = mtus[i];
+		unsigned int log2 = fls(mtu);
+
+		if (!(mtu & ((1 << log2) >> 2)))     /* round */
+			log2--;
+		t4_write_reg(adap, TP_MTU_TABLE, MTUINDEX(i) |
+			     MTUWIDTH(log2) | MTUVALUE(mtu));
+
+		for (w = 0; w < NCCTRL_WIN; ++w) {
+			unsigned int inc;
+
+			inc = max(((mtu - 40) * alpha[w]) / avg_pkts[w],
+				  CC_MIN_INCR);
+
+			t4_write_reg(adap, TP_CCTRL_TABLE, (i << 21) |
+				     (w << 16) | (beta[w] << 13) | inc);
+		}
+	}
+}
+
+/**
+ *	t4_set_trace_filter - configure one of the tracing filters
+ *	@adap: the adapter
+ *	@tp: the desired trace filter parameters
+ *	@idx: which filter to configure
+ *	@enable: whether to enable or disable the filter
+ *
+ *	Configures one of the tracing filters available in HW.  If @enable is
+ *	%0 @tp is not examined and may be %NULL.
+ */
+int t4_set_trace_filter(struct adapter *adap, const struct trace_params *tp,
+			int idx, int enable)
+{
+	int i, ofst = idx * 4;
+	u32 data_reg, mask_reg, cfg;
+	u32 multitrc = TRCMULTIFILTER;
+
+	if (!enable) {
+		t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, 0);
+		goto out;
+	}
+
+	if (tp->port > 11 || tp->invert > 1 || tp->skip_len > 0x1f ||
+	    tp->skip_ofst > 0x1f || tp->min_len > 0x1ff ||
+	    tp->snap_len > 9600 || (idx && tp->snap_len > 256))
+		return -EINVAL;
+
+	if (tp->snap_len > 256) {            /* must be tracer 0 */
+		if ((t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 4) |
+		     t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 8) |
+		     t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 12)) & TFEN)
+			return -EINVAL;  /* other tracers are enabled */
+		multitrc = 0;
+	} else if (idx) {
+		i = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B);
+		if (TFCAPTUREMAX_GET(i) > 256 &&
+		    (t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A) & TFEN))
+			return -EINVAL;
+	}
+
+	/* stop the tracer we'll be changing */
+	t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, 0);
+
+	/* disable tracing globally if running in the wrong single/multi mode */
+	cfg = t4_read_reg(adap, MPS_TRC_CFG);
+	if ((cfg & TRCEN) && multitrc != (cfg & TRCMULTIFILTER)) {
+		t4_write_reg(adap, MPS_TRC_CFG, cfg ^ TRCEN);
+		t4_read_reg(adap, MPS_TRC_CFG);                  /* flush */
+		msleep(1);
+		if (!(t4_read_reg(adap, MPS_TRC_CFG) & TRCFIFOEMPTY))
+			return -ETIMEDOUT;
+	}
+	/*
+	 * At this point either the tracing is enabled and in the right mode or
+	 * disabled.
+	 */
+
+	idx *= (MPS_TRC_FILTER1_MATCH - MPS_TRC_FILTER0_MATCH);
+	data_reg = MPS_TRC_FILTER0_MATCH + idx;
+	mask_reg = MPS_TRC_FILTER0_DONT_CARE + idx;
+
+	for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) {
+		t4_write_reg(adap, data_reg, tp->data[i]);
+		t4_write_reg(adap, mask_reg, ~tp->mask[i]);
+	}
+	t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B + ofst,
+		     TFCAPTUREMAX(tp->snap_len) |
+		     TFMINPKTSIZE(tp->min_len));
+	t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst,
+		     TFOFFSET(tp->skip_ofst) | TFLENGTH(tp->skip_len) |
+		     TFPORT(tp->port) | TFEN |
+		     (tp->invert ? TFINVERTMATCH : 0));
+
+	cfg &= ~TRCMULTIFILTER;
+	t4_write_reg(adap, MPS_TRC_CFG, cfg | TRCEN | multitrc);
+out:	t4_read_reg(adap, MPS_TRC_CFG);  /* flush */
+	return 0;
+}
+
+/**
+ *	t4_get_trace_filter - query one of the tracing filters
+ *	@adap: the adapter
+ *	@tp: the current trace filter parameters
+ *	@idx: which trace filter to query
+ *	@enabled: non-zero if the filter is enabled
+ *
+ *	Returns the current settings of one of the HW tracing filters.
+ */
+void t4_get_trace_filter(struct adapter *adap, struct trace_params *tp, int idx,
+			 int *enabled)
+{
+	u32 ctla, ctlb;
+	int i, ofst = idx * 4;
+	u32 data_reg, mask_reg;
+
+	ctla = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst);
+	ctlb = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B + ofst);
+
+	*enabled = !!(ctla & TFEN);
+	tp->snap_len = TFCAPTUREMAX_GET(ctlb);
+	tp->min_len = TFMINPKTSIZE_GET(ctlb);
+	tp->skip_ofst = TFOFFSET_GET(ctla);
+	tp->skip_len = TFLENGTH_GET(ctla);
+	tp->invert = !!(ctla & TFINVERTMATCH);
+	tp->port = TFPORT_GET(ctla);
+
+	ofst = (MPS_TRC_FILTER1_MATCH - MPS_TRC_FILTER0_MATCH) * idx;
+	data_reg = MPS_TRC_FILTER0_MATCH + ofst;
+	mask_reg = MPS_TRC_FILTER0_DONT_CARE + ofst;
+
+	for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) {
+		tp->mask[i] = ~t4_read_reg(adap, mask_reg);
+		tp->data[i] = t4_read_reg(adap, data_reg) & tp->mask[i];
+	}
+}
+
+/**
+ *	get_mps_bg_map - return the buffer groups associated with a port
+ *	@adap: the adapter
+ *	@idx: the port index
+ *
+ *	Returns a bitmap indicating which MPS buffer groups are associated
+ *	with the given port.  Bit i is set if buffer group i is used by the
+ *	port.
+ */
+static unsigned int get_mps_bg_map(struct adapter *adap, int idx)
+{
+	u32 n = NUMPORTS_GET(t4_read_reg(adap, MPS_CMN_CTL));
+
+	if (n == 0)
+		return idx == 0 ? 0xf : 0;
+	if (n == 1)
+		return idx < 2 ? (3 << (2 * idx)) : 0;
+	return 1 << idx;
+}
+
+/**
+ *	t4_get_port_stats - collect port statistics
+ *	@adap: the adapter
+ *	@idx: the port index
+ *	@p: the stats structure to fill
+ *
+ *	Collect statistics related to the given port from HW.
+ */
+void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p)
+{
+	u32 bgmap = get_mps_bg_map(adap, idx);
+
+#define GET_STAT(name) \
+	t4_read_reg64(adap, PORT_REG(idx, MPS_PORT_STAT_##name##_L))
+#define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L)
+
+	p->tx_octets           = GET_STAT(TX_PORT_BYTES);
+	p->tx_frames           = GET_STAT(TX_PORT_FRAMES);
+	p->tx_bcast_frames     = GET_STAT(TX_PORT_BCAST);
+	p->tx_mcast_frames     = GET_STAT(TX_PORT_MCAST);
+	p->tx_ucast_frames     = GET_STAT(TX_PORT_UCAST);
+	p->tx_error_frames     = GET_STAT(TX_PORT_ERROR);
+	p->tx_frames_64        = GET_STAT(TX_PORT_64B);
+	p->tx_frames_65_127    = GET_STAT(TX_PORT_65B_127B);
+	p->tx_frames_128_255   = GET_STAT(TX_PORT_128B_255B);
+	p->tx_frames_256_511   = GET_STAT(TX_PORT_256B_511B);
+	p->tx_frames_512_1023  = GET_STAT(TX_PORT_512B_1023B);
+	p->tx_frames_1024_1518 = GET_STAT(TX_PORT_1024B_1518B);
+	p->tx_frames_1519_max  = GET_STAT(TX_PORT_1519B_MAX);
+	p->tx_drop             = GET_STAT(TX_PORT_DROP);
+	p->tx_pause            = GET_STAT(TX_PORT_PAUSE);
+	p->tx_ppp0             = GET_STAT(TX_PORT_PPP0);
+	p->tx_ppp1             = GET_STAT(TX_PORT_PPP1);
+	p->tx_ppp2             = GET_STAT(TX_PORT_PPP2);
+	p->tx_ppp3             = GET_STAT(TX_PORT_PPP3);
+	p->tx_ppp4             = GET_STAT(TX_PORT_PPP4);
+	p->tx_ppp5             = GET_STAT(TX_PORT_PPP5);
+	p->tx_ppp6             = GET_STAT(TX_PORT_PPP6);
+	p->tx_ppp7             = GET_STAT(TX_PORT_PPP7);
+
+	p->rx_octets           = GET_STAT(RX_PORT_BYTES);
+	p->rx_frames           = GET_STAT(RX_PORT_FRAMES);
+	p->rx_bcast_frames     = GET_STAT(RX_PORT_BCAST);
+	p->rx_mcast_frames     = GET_STAT(RX_PORT_MCAST);
+	p->rx_ucast_frames     = GET_STAT(RX_PORT_UCAST);
+	p->rx_too_long         = GET_STAT(RX_PORT_MTU_ERROR);
+	p->rx_jabber           = GET_STAT(RX_PORT_MTU_CRC_ERROR);
+	p->rx_fcs_err          = GET_STAT(RX_PORT_CRC_ERROR);
+	p->rx_len_err          = GET_STAT(RX_PORT_LEN_ERROR);
+	p->rx_symbol_err       = GET_STAT(RX_PORT_SYM_ERROR);
+	p->rx_runt             = GET_STAT(RX_PORT_LESS_64B);
+	p->rx_frames_64        = GET_STAT(RX_PORT_64B);
+	p->rx_frames_65_127    = GET_STAT(RX_PORT_65B_127B);
+	p->rx_frames_128_255   = GET_STAT(RX_PORT_128B_255B);
+	p->rx_frames_256_511   = GET_STAT(RX_PORT_256B_511B);
+	p->rx_frames_512_1023  = GET_STAT(RX_PORT_512B_1023B);
+	p->rx_frames_1024_1518 = GET_STAT(RX_PORT_1024B_1518B);
+	p->rx_frames_1519_max  = GET_STAT(RX_PORT_1519B_MAX);
+	p->rx_pause            = GET_STAT(RX_PORT_PAUSE);
+	p->rx_ppp0             = GET_STAT(RX_PORT_PPP0);
+	p->rx_ppp1             = GET_STAT(RX_PORT_PPP1);
+	p->rx_ppp2             = GET_STAT(RX_PORT_PPP2);
+	p->rx_ppp3             = GET_STAT(RX_PORT_PPP3);
+	p->rx_ppp4             = GET_STAT(RX_PORT_PPP4);
+	p->rx_ppp5             = GET_STAT(RX_PORT_PPP5);
+	p->rx_ppp6             = GET_STAT(RX_PORT_PPP6);
+	p->rx_ppp7             = GET_STAT(RX_PORT_PPP7);
+
+	p->rx_ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_DROP_FRAME) : 0;
+	p->rx_ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_MAC_DROP_FRAME) : 0;
+	p->rx_ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_MAC_DROP_FRAME) : 0;
+	p->rx_ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_MAC_DROP_FRAME) : 0;
+	p->rx_trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_TRUNC_FRAME) : 0;
+	p->rx_trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_MAC_TRUNC_FRAME) : 0;
+	p->rx_trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_MAC_TRUNC_FRAME) : 0;
+	p->rx_trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_MAC_TRUNC_FRAME) : 0;
+
+#undef GET_STAT
+#undef GET_STAT_COM
+}
+
+/**
+ *	t4_get_lb_stats - collect loopback port statistics
+ *	@adap: the adapter
+ *	@idx: the loopback port index
+ *	@p: the stats structure to fill
+ *
+ *	Return HW statistics for the given loopback port.
+ */
+void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p)
+{
+	u32 bgmap = get_mps_bg_map(adap, idx);
+
+#define GET_STAT(name) \
+	t4_read_reg64(adap, PORT_REG(idx, MPS_PORT_STAT_LB_PORT_##name##_L))
+#define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L)
+
+	p->octets           = GET_STAT(BYTES);
+	p->frames           = GET_STAT(FRAMES);
+	p->bcast_frames     = GET_STAT(BCAST);
+	p->mcast_frames     = GET_STAT(MCAST);
+	p->ucast_frames     = GET_STAT(UCAST);
+	p->error_frames     = GET_STAT(ERROR);
+
+	p->frames_64        = GET_STAT(64B);
+	p->frames_65_127    = GET_STAT(65B_127B);
+	p->frames_128_255   = GET_STAT(128B_255B);
+	p->frames_256_511   = GET_STAT(256B_511B);
+	p->frames_512_1023  = GET_STAT(512B_1023B);
+	p->frames_1024_1518 = GET_STAT(1024B_1518B);
+	p->frames_1519_max  = GET_STAT(1519B_MAX);
+	p->drop             = t4_read_reg(adap, PORT_REG(idx,
+					  MPS_PORT_STAT_LB_PORT_DROP_FRAMES));
+
+	p->ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_DROP_FRAME) : 0;
+	p->ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_DROP_FRAME) : 0;
+	p->ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_DROP_FRAME) : 0;
+	p->ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_DROP_FRAME) : 0;
+	p->trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_TRUNC_FRAME) : 0;
+	p->trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_TRUNC_FRAME) : 0;
+	p->trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_TRUNC_FRAME) : 0;
+	p->trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_TRUNC_FRAME) : 0;
+
+#undef GET_STAT
+#undef GET_STAT_COM
+}
+
+/**
+ *	t4_wol_magic_enable - enable/disable magic packet WoL
+ *	@adap: the adapter
+ *	@port: the physical port index
+ *	@addr: MAC address expected in magic packets, %NULL to disable
+ *
+ *	Enables/disables magic packet wake-on-LAN for the selected port.
+ */
+void t4_wol_magic_enable(struct adapter *adap, unsigned int port,
+			 const u8 *addr)
+{
+	if (addr) {
+		t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_MAGIC_MACID_LO),
+			     (addr[2] << 24) | (addr[3] << 16) |
+			     (addr[4] << 8) | addr[5]);
+		t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_MAGIC_MACID_HI),
+			     (addr[0] << 8) | addr[1]);
+	}
+	t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2), MAGICEN,
+			 addr ? MAGICEN : 0);
+}
+
+/**
+ *	t4_wol_pat_enable - enable/disable pattern-based WoL
+ *	@adap: the adapter
+ *	@port: the physical port index
+ *	@map: bitmap of which HW pattern filters to set
+ *	@mask0: byte mask for bytes 0-63 of a packet
+ *	@mask1: byte mask for bytes 64-127 of a packet
+ *	@crc: Ethernet CRC for selected bytes
+ *	@enable: enable/disable switch
+ *
+ *	Sets the pattern filters indicated in @map to mask out the bytes
+ *	specified in @mask0/@mask1 in received packets and compare the CRC of
+ *	the resulting packet against @crc.  If @enable is %true pattern-based
+ *	WoL is enabled, otherwise disabled.
+ */
+int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
+		      u64 mask0, u64 mask1, unsigned int crc, bool enable)
+{
+	int i;
+
+	if (!enable) {
+		t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2),
+				 PATEN, 0);
+		return 0;
+	}
+	if (map > 0xff)
+		return -EINVAL;
+
+#define EPIO_REG(name) PORT_REG(port, XGMAC_PORT_EPIO_##name)
+
+	t4_write_reg(adap, EPIO_REG(DATA1), mask0 >> 32);
+	t4_write_reg(adap, EPIO_REG(DATA2), mask1);
+	t4_write_reg(adap, EPIO_REG(DATA3), mask1 >> 32);
+
+	for (i = 0; i < NWOL_PAT; i++, map >>= 1) {
+		if (!(map & 1))
+			continue;
+
+		/* write byte masks */
+		t4_write_reg(adap, EPIO_REG(DATA0), mask0);
+		t4_write_reg(adap, EPIO_REG(OP), ADDRESS(i) | EPIOWR);
+		t4_read_reg(adap, EPIO_REG(OP));                /* flush */
+		if (t4_read_reg(adap, EPIO_REG(OP)) & BUSY)
+			return -ETIMEDOUT;
+
+		/* write CRC */
+		t4_write_reg(adap, EPIO_REG(DATA0), crc);
+		t4_write_reg(adap, EPIO_REG(OP), ADDRESS(i + 32) | EPIOWR);
+		t4_read_reg(adap, EPIO_REG(OP));                /* flush */
+		if (t4_read_reg(adap, EPIO_REG(OP)) & BUSY)
+			return -ETIMEDOUT;
+	}
+#undef EPIO_REG
+
+	t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2), 0, PATEN);
+	return 0;
+}
+
+#define INIT_CMD(var, cmd, rd_wr) do { \
+	(var).op_to_write = htonl(FW_CMD_OP(FW_##cmd##_CMD) | \
+				  FW_CMD_REQUEST | FW_CMD_##rd_wr); \
+	(var).retval_len16 = htonl(FW_LEN16(var)); \
+} while (0)
+
+/**
+ *	t4_mdio_rd - read a PHY register through MDIO
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@phy_addr: the PHY address
+ *	@mmd: the PHY MMD to access (0 for clause 22 PHYs)
+ *	@reg: the register to read
+ *	@valp: where to store the value
+ *
+ *	Issues a FW command through the given mailbox to read a PHY register.
+ */
+int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
+	       unsigned int mmd, unsigned int reg, u16 *valp)
+{
+	int ret;
+	struct fw_ldst_cmd c;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_addrspace = htonl(FW_CMD_OP(FW_LDST_CMD) | FW_CMD_REQUEST |
+		FW_CMD_READ | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO));
+	c.cycles_to_len16 = htonl(FW_LEN16(c));
+	c.u.mdio.paddr_mmd = htons(FW_LDST_CMD_PADDR(phy_addr) |
+				   FW_LDST_CMD_MMD(mmd));
+	c.u.mdio.raddr = htons(reg);
+
+	ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+	if (ret == 0)
+		*valp = ntohs(c.u.mdio.rval);
+	return ret;
+}
+
+/**
+ *	t4_mdio_wr - write a PHY register through MDIO
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@phy_addr: the PHY address
+ *	@mmd: the PHY MMD to access (0 for clause 22 PHYs)
+ *	@reg: the register to write
+ *	@valp: value to write
+ *
+ *	Issues a FW command through the given mailbox to write a PHY register.
+ */
+int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
+	       unsigned int mmd, unsigned int reg, u16 val)
+{
+	struct fw_ldst_cmd c;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_addrspace = htonl(FW_CMD_OP(FW_LDST_CMD) | FW_CMD_REQUEST |
+		FW_CMD_WRITE | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO));
+	c.cycles_to_len16 = htonl(FW_LEN16(c));
+	c.u.mdio.paddr_mmd = htons(FW_LDST_CMD_PADDR(phy_addr) |
+				   FW_LDST_CMD_MMD(mmd));
+	c.u.mdio.raddr = htons(reg);
+	c.u.mdio.rval = htons(val);
+
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *	t4_fw_hello - establish communication with FW
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@evt_mbox: mailbox to receive async FW events
+ *	@master: specifies the caller's willingness to be the device master
+ *	@state: returns the current device state
+ *
+ *	Issues a command to establish communication with FW.
+ */
+int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox,
+		enum dev_master master, enum dev_state *state)
+{
+	int ret;
+	struct fw_hello_cmd c;
+
+	INIT_CMD(c, HELLO, WRITE);
+	c.err_to_mbasyncnot = htonl(
+		FW_HELLO_CMD_MASTERDIS(master == MASTER_CANT) |
+		FW_HELLO_CMD_MASTERFORCE(master == MASTER_MUST) |
+		FW_HELLO_CMD_MBMASTER(master == MASTER_MUST ? mbox : 0xff) |
+		FW_HELLO_CMD_MBASYNCNOT(evt_mbox));
+
+	ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+	if (ret == 0 && state) {
+		u32 v = ntohl(c.err_to_mbasyncnot);
+		if (v & FW_HELLO_CMD_INIT)
+			*state = DEV_STATE_INIT;
+		else if (v & FW_HELLO_CMD_ERR)
+			*state = DEV_STATE_ERR;
+		else
+			*state = DEV_STATE_UNINIT;
+	}
+	return ret;
+}
+
+/**
+ *	t4_fw_bye - end communication with FW
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *
+ *	Issues a command to terminate communication with FW.
+ */
+int t4_fw_bye(struct adapter *adap, unsigned int mbox)
+{
+	struct fw_bye_cmd c;
+
+	INIT_CMD(c, BYE, WRITE);
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *	t4_init_cmd - ask FW to initialize the device
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *
+ *	Issues a command to FW to partially initialize the device.  This
+ *	performs initialization that generally doesn't depend on user input.
+ */
+int t4_early_init(struct adapter *adap, unsigned int mbox)
+{
+	struct fw_initialize_cmd c;
+
+	INIT_CMD(c, INITIALIZE, WRITE);
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *	t4_fw_reset - issue a reset to FW
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@reset: specifies the type of reset to perform
+ *
+ *	Issues a reset command of the specified type to FW.
+ */
+int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset)
+{
+	struct fw_reset_cmd c;
+
+	INIT_CMD(c, RESET, WRITE);
+	c.val = htonl(reset);
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *	t4_query_params - query FW or device parameters
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@pf: the PF
+ *	@vf: the VF
+ *	@nparams: the number of parameters
+ *	@params: the parameter names
+ *	@val: the parameter values
+ *
+ *	Reads the value of FW or device parameters.  Up to 7 parameters can be
+ *	queried at once.
+ */
+int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
+		    unsigned int vf, unsigned int nparams, const u32 *params,
+		    u32 *val)
+{
+	int i, ret;
+	struct fw_params_cmd c;
+	__be32 *p = &c.param[0].mnem;
+
+	if (nparams > 7)
+		return -EINVAL;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_vfn = htonl(FW_CMD_OP(FW_PARAMS_CMD) | FW_CMD_REQUEST |
+			    FW_CMD_READ | FW_PARAMS_CMD_PFN(pf) |
+			    FW_PARAMS_CMD_VFN(vf));
+	c.retval_len16 = htonl(FW_LEN16(c));
+	for (i = 0; i < nparams; i++, p += 2)
+		*p = htonl(*params++);
+
+	ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+	if (ret == 0)
+		for (i = 0, p = &c.param[0].val; i < nparams; i++, p += 2)
+			*val++ = ntohl(*p);
+	return ret;
+}
+
+/**
+ *	t4_set_params - sets FW or device parameters
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@pf: the PF
+ *	@vf: the VF
+ *	@nparams: the number of parameters
+ *	@params: the parameter names
+ *	@val: the parameter values
+ *
+ *	Sets the value of FW or device parameters.  Up to 7 parameters can be
+ *	specified at once.
+ */
+int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
+		  unsigned int vf, unsigned int nparams, const u32 *params,
+		  const u32 *val)
+{
+	struct fw_params_cmd c;
+	__be32 *p = &c.param[0].mnem;
+
+	if (nparams > 7)
+		return -EINVAL;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_vfn = htonl(FW_CMD_OP(FW_PARAMS_CMD) | FW_CMD_REQUEST |
+			    FW_CMD_WRITE | FW_PARAMS_CMD_PFN(pf) |
+			    FW_PARAMS_CMD_VFN(vf));
+	c.retval_len16 = htonl(FW_LEN16(c));
+	while (nparams--) {
+		*p++ = htonl(*params++);
+		*p++ = htonl(*val++);
+	}
+
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *	t4_cfg_pfvf - configure PF/VF resource limits
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@pf: the PF being configured
+ *	@vf: the VF being configured
+ *	@txq: the max number of egress queues
+ *	@txq_eth_ctrl: the max number of egress Ethernet or control queues
+ *	@rxqi: the max number of interrupt-capable ingress queues
+ *	@rxq: the max number of interruptless ingress queues
+ *	@tc: the PCI traffic class
+ *	@vi: the max number of virtual interfaces
+ *	@cmask: the channel access rights mask for the PF/VF
+ *	@pmask: the port access rights mask for the PF/VF
+ *	@nexact: the maximum number of exact MPS filters
+ *	@rcaps: read capabilities
+ *	@wxcaps: write/execute capabilities
+ *
+ *	Configures resource limits and capabilities for a physical or virtual
+ *	function.
+ */
+int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf,
+		unsigned int vf, unsigned int txq, unsigned int txq_eth_ctrl,
+		unsigned int rxqi, unsigned int rxq, unsigned int tc,
+		unsigned int vi, unsigned int cmask, unsigned int pmask,
+		unsigned int nexact, unsigned int rcaps, unsigned int wxcaps)
+{
+	struct fw_pfvf_cmd c;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_vfn = htonl(FW_CMD_OP(FW_PFVF_CMD) | FW_CMD_REQUEST |
+			    FW_CMD_WRITE | FW_PFVF_CMD_PFN(pf) |
+			    FW_PFVF_CMD_VFN(vf));
+	c.retval_len16 = htonl(FW_LEN16(c));
+	c.niqflint_niq = htonl(FW_PFVF_CMD_NIQFLINT(rxqi) |
+			       FW_PFVF_CMD_NIQ(rxq));
+	c.cmask_to_neq = htonl(FW_PFVF_CMD_CMASK(cmask) |
+			       FW_PFVF_CMD_PMASK(pmask) |
+			       FW_PFVF_CMD_NEQ(txq));
+	c.tc_to_nexactf = htonl(FW_PFVF_CMD_TC(tc) | FW_PFVF_CMD_NVI(vi) |
+				FW_PFVF_CMD_NEXACTF(nexact));
+	c.r_caps_to_nethctrl = htonl(FW_PFVF_CMD_R_CAPS(rcaps) |
+				     FW_PFVF_CMD_WX_CAPS(wxcaps) |
+				     FW_PFVF_CMD_NETHCTRL(txq_eth_ctrl));
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *	t4_alloc_vi - allocate a virtual interface
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@port: physical port associated with the VI
+ *	@pf: the PF owning the VI
+ *	@vf: the VF owning the VI
+ *	@nmac: number of MAC addresses needed (1 to 5)
+ *	@mac: the MAC addresses of the VI
+ *	@rss_size: size of RSS table slice associated with this VI
+ *
+ *	Allocates a virtual interface for the given physical port.  If @mac is
+ *	not %NULL it contains the MAC addresses of the VI as assigned by FW.
+ *	@mac should be large enough to hold @nmac Ethernet addresses, they are
+ *	stored consecutively so the space needed is @nmac * 6 bytes.
+ *	Returns a negative error number or the non-negative VI id.
+ */
+int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
+		unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac,
+		unsigned int *rss_size)
+{
+	int ret;
+	struct fw_vi_cmd c;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_vfn = htonl(FW_CMD_OP(FW_VI_CMD) | FW_CMD_REQUEST |
+			    FW_CMD_WRITE | FW_CMD_EXEC |
+			    FW_VI_CMD_PFN(pf) | FW_VI_CMD_VFN(vf));
+	c.alloc_to_len16 = htonl(FW_VI_CMD_ALLOC | FW_LEN16(c));
+	c.portid_pkd = FW_VI_CMD_PORTID(port);
+	c.nmac = nmac - 1;
+
+	ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+	if (ret)
+		return ret;
+
+	if (mac) {
+		memcpy(mac, c.mac, sizeof(c.mac));
+		switch (nmac) {
+		case 5:
+			memcpy(mac + 24, c.nmac3, sizeof(c.nmac3));
+		case 4:
+			memcpy(mac + 18, c.nmac2, sizeof(c.nmac2));
+		case 3:
+			memcpy(mac + 12, c.nmac1, sizeof(c.nmac1));
+		case 2:
+			memcpy(mac + 6,  c.nmac0, sizeof(c.nmac0));
+		}
+	}
+	if (rss_size)
+		*rss_size = FW_VI_CMD_RSSSIZE_GET(ntohs(c.rsssize_pkd));
+	return ntohs(c.viid_pkd);
+}
+
+/**
+ *	t4_free_vi - free a virtual interface
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@pf: the PF owning the VI
+ *	@vf: the VF owning the VI
+ *	@viid: virtual interface identifiler
+ *
+ *	Free a previously allocated virtual interface.
+ */
+int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf,
+	       unsigned int vf, unsigned int viid)
+{
+	struct fw_vi_cmd c;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_vfn = htonl(FW_CMD_OP(FW_VI_CMD) | FW_CMD_REQUEST |
+			    FW_CMD_EXEC | FW_VI_CMD_PFN(pf) |
+			    FW_VI_CMD_VFN(vf));
+	c.alloc_to_len16 = htonl(FW_VI_CMD_FREE | FW_LEN16(c));
+	c.viid_pkd = htons(FW_VI_CMD_VIID(viid));
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+}
+
+/**
+ *	t4_set_rxmode - set Rx properties of a virtual interface
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@viid: the VI id
+ *	@mtu: the new MTU or -1
+ *	@promisc: 1 to enable promiscuous mode, 0 to disable it, -1 no change
+ *	@all_multi: 1 to enable all-multi mode, 0 to disable it, -1 no change
+ *	@bcast: 1 to enable broadcast Rx, 0 to disable it, -1 no change
+ *	@sleep_ok: if true we may sleep while awaiting command completion
+ *
+ *	Sets Rx properties of a virtual interface.
+ */
+int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid,
+		  int mtu, int promisc, int all_multi, int bcast, bool sleep_ok)
+{
+	struct fw_vi_rxmode_cmd c;
+
+	/* convert to FW values */
+	if (mtu < 0)
+		mtu = FW_RXMODE_MTU_NO_CHG;
+	if (promisc < 0)
+		promisc = FW_VI_RXMODE_CMD_PROMISCEN_MASK;
+	if (all_multi < 0)
+		all_multi = FW_VI_RXMODE_CMD_ALLMULTIEN_MASK;
+	if (bcast < 0)
+		bcast = FW_VI_RXMODE_CMD_BROADCASTEN_MASK;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_viid = htonl(FW_CMD_OP(FW_VI_RXMODE_CMD) | FW_CMD_REQUEST |
+			     FW_CMD_WRITE | FW_VI_RXMODE_CMD_VIID(viid));
+	c.retval_len16 = htonl(FW_LEN16(c));
+	c.mtu_to_broadcasten = htonl(FW_VI_RXMODE_CMD_MTU(mtu) |
+				     FW_VI_RXMODE_CMD_PROMISCEN(promisc) |
+				     FW_VI_RXMODE_CMD_ALLMULTIEN(all_multi) |
+				     FW_VI_RXMODE_CMD_BROADCASTEN(bcast));
+	return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok);
+}
+
+/**
+ *	t4_alloc_mac_filt - allocates exact-match filters for MAC addresses
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@viid: the VI id
+ *	@free: if true any existing filters for this VI id are first removed
+ *	@naddr: the number of MAC addresses to allocate filters for (up to 7)
+ *	@addr: the MAC address(es)
+ *	@idx: where to store the index of each allocated filter
+ *	@hash: pointer to hash address filter bitmap
+ *	@sleep_ok: call is allowed to sleep
+ *
+ *	Allocates an exact-match filter for each of the supplied addresses and
+ *	sets it to the corresponding address.  If @idx is not %NULL it should
+ *	have at least @naddr entries, each of which will be set to the index of
+ *	the filter allocated for the corresponding MAC address.  If a filter
+ *	could not be allocated for an address its index is set to 0xffff.
+ *	If @hash is not %NULL addresses that fail to allocate an exact filter
+ *	are hashed and update the hash filter bitmap pointed at by @hash.
+ *
+ *	Returns a negative error number or the number of filters allocated.
+ */
+int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox,
+		      unsigned int viid, bool free, unsigned int naddr,
+		      const u8 **addr, u16 *idx, u64 *hash, bool sleep_ok)
+{
+	int i, ret;
+	struct fw_vi_mac_cmd c;
+	struct fw_vi_mac_exact *p;
+
+	if (naddr > 7)
+		return -EINVAL;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_viid = htonl(FW_CMD_OP(FW_VI_MAC_CMD) | FW_CMD_REQUEST |
+			     FW_CMD_WRITE | (free ? FW_CMD_EXEC : 0) |
+			     FW_VI_MAC_CMD_VIID(viid));
+	c.freemacs_to_len16 = htonl(FW_VI_MAC_CMD_FREEMACS(free) |
+				    FW_CMD_LEN16((naddr + 2) / 2));
+
+	for (i = 0, p = c.u.exact; i < naddr; i++, p++) {
+		p->valid_to_idx = htons(FW_VI_MAC_CMD_VALID |
+				      FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
+		memcpy(p->macaddr, addr[i], sizeof(p->macaddr));
+	}
+
+	ret = t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), &c, sleep_ok);
+	if (ret)
+		return ret;
+
+	for (i = 0, p = c.u.exact; i < naddr; i++, p++) {
+		u16 index = FW_VI_MAC_CMD_IDX_GET(ntohs(p->valid_to_idx));
+
+		if (idx)
+			idx[i] = index >= NEXACT_MAC ? 0xffff : index;
+		if (index < NEXACT_MAC)
+			ret++;
+		else if (hash)
+			*hash |= (1 << hash_mac_addr(addr[i]));
+	}
+	return ret;
+}
+
+/**
+ *	t4_change_mac - modifies the exact-match filter for a MAC address
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@viid: the VI id
+ *	@idx: index of existing filter for old value of MAC address, or -1
+ *	@addr: the new MAC address value
+ *	@persist: whether a new MAC allocation should be persistent
+ *	@add_smt: if true also add the address to the HW SMT
+ *
+ *	Modifies an exact-match filter and sets it to the new MAC address.
+ *	Note that in general it is not possible to modify the value of a given
+ *	filter so the generic way to modify an address filter is to free the one
+ *	being used by the old address value and allocate a new filter for the
+ *	new address value.  @idx can be -1 if the address is a new addition.
+ *
+ *	Returns a negative error number or the index of the filter with the new
+ *	MAC value.
+ */
+int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid,
+		  int idx, const u8 *addr, bool persist, bool add_smt)
+{
+	int ret, mode;
+	struct fw_vi_mac_cmd c;
+	struct fw_vi_mac_exact *p = c.u.exact;
+
+	if (idx < 0)                             /* new allocation */
+		idx = persist ? FW_VI_MAC_ADD_PERSIST_MAC : FW_VI_MAC_ADD_MAC;
+	mode = add_smt ? FW_VI_MAC_SMT_AND_MPSTCAM : FW_VI_MAC_MPS_TCAM_ENTRY;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_viid = htonl(FW_CMD_OP(FW_VI_MAC_CMD) | FW_CMD_REQUEST |
+			     FW_CMD_WRITE | FW_VI_MAC_CMD_VIID(viid));
+	c.freemacs_to_len16 = htonl(FW_CMD_LEN16(1));
+	p->valid_to_idx = htons(FW_VI_MAC_CMD_VALID |
+				FW_VI_MAC_CMD_SMAC_RESULT(mode) |
+				FW_VI_MAC_CMD_IDX(idx));
+	memcpy(p->macaddr, addr, sizeof(p->macaddr));
+
+	ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+	if (ret == 0) {
+		ret = FW_VI_MAC_CMD_IDX_GET(ntohs(p->valid_to_idx));
+		if (ret >= NEXACT_MAC)
+			ret = -ENOMEM;
+	}
+	return ret;
+}
+
+/**
+ *	t4_set_addr_hash - program the MAC inexact-match hash filter
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@viid: the VI id
+ *	@ucast: whether the hash filter should also match unicast addresses
+ *	@vec: the value to be written to the hash filter
+ *	@sleep_ok: call is allowed to sleep
+ *
+ *	Sets the 64-bit inexact-match hash filter for a virtual interface.
+ */
+int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid,
+		     bool ucast, u64 vec, bool sleep_ok)
+{
+	struct fw_vi_mac_cmd c;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_viid = htonl(FW_CMD_OP(FW_VI_MAC_CMD) | FW_CMD_REQUEST |
+			     FW_CMD_WRITE | FW_VI_ENABLE_CMD_VIID(viid));
+	c.freemacs_to_len16 = htonl(FW_VI_MAC_CMD_HASHVECEN |
+				    FW_VI_MAC_CMD_HASHUNIEN(ucast) |
+				    FW_CMD_LEN16(1));
+	c.u.hash.hashvec = cpu_to_be64(vec);
+	return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok);
+}
+
+/**
+ *	t4_enable_vi - enable/disable a virtual interface
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@viid: the VI id
+ *	@rx_en: 1=enable Rx, 0=disable Rx
+ *	@tx_en: 1=enable Tx, 0=disable Tx
+ *
+ *	Enables/disables a virtual interface.
+ */
+int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid,
+		 bool rx_en, bool tx_en)
+{
+	struct fw_vi_enable_cmd c;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST |
+			     FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid));
+	c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_IEN(rx_en) |
+			       FW_VI_ENABLE_CMD_EEN(tx_en) | FW_LEN16(c));
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *	t4_identify_port - identify a VI's port by blinking its LED
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@viid: the VI id
+ *	@nblinks: how many times to blink LED at 2.5 Hz
+ *
+ *	Identifies a VI's port by blinking its LED.
+ */
+int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid,
+		     unsigned int nblinks)
+{
+	struct fw_vi_enable_cmd c;
+
+	c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST |
+			     FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid));
+	c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c));
+	c.blinkdur = htons(nblinks);
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *	t4_iq_start_stop - enable/disable an ingress queue and its FLs
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@start: %true to enable the queues, %false to disable them
+ *	@pf: the PF owning the queues
+ *	@vf: the VF owning the queues
+ *	@iqid: ingress queue id
+ *	@fl0id: FL0 queue id or 0xffff if no attached FL0
+ *	@fl1id: FL1 queue id or 0xffff if no attached FL1
+ *
+ *	Starts or stops an ingress queue and its associated FLs, if any.
+ */
+int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start,
+		     unsigned int pf, unsigned int vf, unsigned int iqid,
+		     unsigned int fl0id, unsigned int fl1id)
+{
+	struct fw_iq_cmd c;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST |
+			    FW_CMD_EXEC | FW_IQ_CMD_PFN(pf) |
+			    FW_IQ_CMD_VFN(vf));
+	c.alloc_to_len16 = htonl(FW_IQ_CMD_IQSTART(start) |
+				 FW_IQ_CMD_IQSTOP(!start) | FW_LEN16(c));
+	c.iqid = htons(iqid);
+	c.fl0id = htons(fl0id);
+	c.fl1id = htons(fl1id);
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *	t4_iq_free - free an ingress queue and its FLs
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@pf: the PF owning the queues
+ *	@vf: the VF owning the queues
+ *	@iqtype: the ingress queue type
+ *	@iqid: ingress queue id
+ *	@fl0id: FL0 queue id or 0xffff if no attached FL0
+ *	@fl1id: FL1 queue id or 0xffff if no attached FL1
+ *
+ *	Frees an ingress queue and its associated FLs, if any.
+ */
+int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+	       unsigned int vf, unsigned int iqtype, unsigned int iqid,
+	       unsigned int fl0id, unsigned int fl1id)
+{
+	struct fw_iq_cmd c;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST |
+			    FW_CMD_EXEC | FW_IQ_CMD_PFN(pf) |
+			    FW_IQ_CMD_VFN(vf));
+	c.alloc_to_len16 = htonl(FW_IQ_CMD_FREE | FW_LEN16(c));
+	c.type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE(iqtype));
+	c.iqid = htons(iqid);
+	c.fl0id = htons(fl0id);
+	c.fl1id = htons(fl1id);
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *	t4_eth_eq_free - free an Ethernet egress queue
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@pf: the PF owning the queue
+ *	@vf: the VF owning the queue
+ *	@eqid: egress queue id
+ *
+ *	Frees an Ethernet egress queue.
+ */
+int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+		   unsigned int vf, unsigned int eqid)
+{
+	struct fw_eq_eth_cmd c;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_ETH_CMD) | FW_CMD_REQUEST |
+			    FW_CMD_EXEC | FW_EQ_ETH_CMD_PFN(pf) |
+			    FW_EQ_ETH_CMD_VFN(vf));
+	c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_FREE | FW_LEN16(c));
+	c.eqid_pkd = htonl(FW_EQ_ETH_CMD_EQID(eqid));
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *	t4_ctrl_eq_free - free a control egress queue
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@pf: the PF owning the queue
+ *	@vf: the VF owning the queue
+ *	@eqid: egress queue id
+ *
+ *	Frees a control egress queue.
+ */
+int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+		    unsigned int vf, unsigned int eqid)
+{
+	struct fw_eq_ctrl_cmd c;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_CTRL_CMD) | FW_CMD_REQUEST |
+			    FW_CMD_EXEC | FW_EQ_CTRL_CMD_PFN(pf) |
+			    FW_EQ_CTRL_CMD_VFN(vf));
+	c.alloc_to_len16 = htonl(FW_EQ_CTRL_CMD_FREE | FW_LEN16(c));
+	c.cmpliqid_eqid = htonl(FW_EQ_CTRL_CMD_EQID(eqid));
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *	t4_ofld_eq_free - free an offload egress queue
+ *	@adap: the adapter
+ *	@mbox: mailbox to use for the FW command
+ *	@pf: the PF owning the queue
+ *	@vf: the VF owning the queue
+ *	@eqid: egress queue id
+ *
+ *	Frees a control egress queue.
+ */
+int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+		    unsigned int vf, unsigned int eqid)
+{
+	struct fw_eq_ofld_cmd c;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST |
+			    FW_CMD_EXEC | FW_EQ_OFLD_CMD_PFN(pf) |
+			    FW_EQ_OFLD_CMD_VFN(vf));
+	c.alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_FREE | FW_LEN16(c));
+	c.eqid_pkd = htonl(FW_EQ_OFLD_CMD_EQID(eqid));
+	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *	t4_handle_fw_rpl - process a FW reply message
+ *	@adap: the adapter
+ *	@rpl: start of the FW message
+ *
+ *	Processes a FW message, such as link state change messages.
+ */
+int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
+{
+	u8 opcode = *(const u8 *)rpl;
+
+	if (opcode == FW_PORT_CMD) {    /* link/module state change message */
+		int speed = 0, fc = 0;
+		const struct fw_port_cmd *p = (void *)rpl;
+		int chan = FW_PORT_CMD_PORTID_GET(ntohl(p->op_to_portid));
+		int port = adap->chan_map[chan];
+		struct port_info *pi = adap2pinfo(adap, port);
+		struct link_config *lc = &pi->link_cfg;
+		u32 stat = ntohl(p->u.info.lstatus_to_modtype);
+		int link_ok = (stat & FW_PORT_CMD_LSTATUS) != 0;
+		u32 mod = FW_PORT_CMD_MODTYPE_GET(stat);
+
+		if (stat & FW_PORT_CMD_RXPAUSE)
+			fc |= PAUSE_RX;
+		if (stat & FW_PORT_CMD_TXPAUSE)
+			fc |= PAUSE_TX;
+		if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
+			speed = SPEED_100;
+		else if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
+			speed = SPEED_1000;
+		else if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
+			speed = SPEED_10000;
+
+		if (link_ok != lc->link_ok || speed != lc->speed ||
+		    fc != lc->fc) {                    /* something changed */
+			lc->link_ok = link_ok;
+			lc->speed = speed;
+			lc->fc = fc;
+			t4_os_link_changed(adap, port, link_ok);
+		}
+		if (mod != pi->mod_type) {
+			pi->mod_type = mod;
+			t4_os_portmod_changed(adap, port);
+		}
+	}
+	return 0;
+}
+
+static void __devinit get_pci_mode(struct adapter *adapter,
+				   struct pci_params *p)
+{
+	u16 val;
+	u32 pcie_cap = pci_pcie_cap(adapter->pdev);
+
+	if (pcie_cap) {
+		pci_read_config_word(adapter->pdev, pcie_cap + PCI_EXP_LNKSTA,
+				     &val);
+		p->speed = val & PCI_EXP_LNKSTA_CLS;
+		p->width = (val & PCI_EXP_LNKSTA_NLW) >> 4;
+	}
+}
+
+/**
+ *	init_link_config - initialize a link's SW state
+ *	@lc: structure holding the link state
+ *	@caps: link capabilities
+ *
+ *	Initializes the SW state maintained for each link, including the link's
+ *	capabilities and default speed/flow-control/autonegotiation settings.
+ */
+static void __devinit init_link_config(struct link_config *lc,
+				       unsigned int caps)
+{
+	lc->supported = caps;
+	lc->requested_speed = 0;
+	lc->speed = 0;
+	lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
+	if (lc->supported & FW_PORT_CAP_ANEG) {
+		lc->advertising = lc->supported & ADVERT_MASK;
+		lc->autoneg = AUTONEG_ENABLE;
+		lc->requested_fc |= PAUSE_AUTONEG;
+	} else {
+		lc->advertising = 0;
+		lc->autoneg = AUTONEG_DISABLE;
+	}
+}
+
+static int __devinit wait_dev_ready(struct adapter *adap)
+{
+	if (t4_read_reg(adap, PL_WHOAMI) != 0xffffffff)
+		return 0;
+	msleep(500);
+	return t4_read_reg(adap, PL_WHOAMI) != 0xffffffff ? 0 : -EIO;
+}
+
+/**
+ *	t4_prep_adapter - prepare SW and HW for operation
+ *	@adapter: the adapter
+ *	@reset: if true perform a HW reset
+ *
+ *	Initialize adapter SW state for the various HW modules, set initial
+ *	values for some adapter tunables, take PHYs out of reset, and
+ *	initialize the MDIO interface.
+ */
+int __devinit t4_prep_adapter(struct adapter *adapter)
+{
+	int ret;
+
+	ret = wait_dev_ready(adapter);
+	if (ret < 0)
+		return ret;
+
+	get_pci_mode(adapter, &adapter->params.pci);
+	adapter->params.rev = t4_read_reg(adapter, PL_REV);
+
+	ret = get_vpd_params(adapter, &adapter->params.vpd);
+	if (ret < 0)
+		return ret;
+
+	init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd);
+
+	/*
+	 * Default port for debugging in case we can't reach FW.
+	 */
+	adapter->params.nports = 1;
+	adapter->params.portvec = 1;
+	return 0;
+}
+
+int __devinit t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
+{
+	u8 addr[6];
+	int ret, i, j = 0;
+	struct fw_port_cmd c;
+
+	memset(&c, 0, sizeof(c));
+
+	for_each_port(adap, i) {
+		unsigned int rss_size;
+		struct port_info *p = adap2pinfo(adap, i);
+
+		while ((adap->params.portvec & (1 << j)) == 0)
+			j++;
+
+		c.op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) |
+				       FW_CMD_REQUEST | FW_CMD_READ |
+				       FW_PORT_CMD_PORTID(j));
+		c.action_to_len16 = htonl(
+			FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) |
+			FW_LEN16(c));
+		ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+		if (ret)
+			return ret;
+
+		ret = t4_alloc_vi(adap, mbox, j, pf, vf, 1, addr, &rss_size);
+		if (ret < 0)
+			return ret;
+
+		p->viid = ret;
+		p->tx_chan = j;
+		p->lport = j;
+		p->rss_size = rss_size;
+		memcpy(adap->port[i]->dev_addr, addr, ETH_ALEN);
+		memcpy(adap->port[i]->perm_addr, addr, ETH_ALEN);
+
+		ret = ntohl(c.u.info.lstatus_to_modtype);
+		p->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP) ?
+			FW_PORT_CMD_MDIOADDR_GET(ret) : -1;
+		p->port_type = FW_PORT_CMD_PTYPE_GET(ret);
+		p->mod_type = FW_PORT_CMD_MODTYPE_GET(ret);
+
+		init_link_config(&p->link_cfg, ntohs(c.u.info.pcap));
+		j++;
+	}
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb4/t4_hw.h linux-libre-2.6.34-gnu1/drivers/net/cxgb4/t4_hw.h
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb4/t4_hw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb4/t4_hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,100 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __T4_HW_H
+#define __T4_HW_H
+
+#include <linux/types.h>
+
+enum {
+	NCHAN          = 4,     /* # of HW channels */
+	MAX_MTU        = 9600,  /* max MAC MTU, excluding header + FCS */
+	EEPROMSIZE     = 17408, /* Serial EEPROM physical size */
+	EEPROMVSIZE    = 32768, /* Serial EEPROM virtual address space size */
+	RSS_NENTRIES   = 2048,  /* # of entries in RSS mapping table */
+	TCB_SIZE       = 128,   /* TCB size */
+	NMTUS          = 16,    /* size of MTU table */
+	NCCTRL_WIN     = 32,    /* # of congestion control windows */
+	NEXACT_MAC     = 336,   /* # of exact MAC address filters */
+	L2T_SIZE       = 4096,  /* # of L2T entries */
+	MBOX_LEN       = 64,    /* mailbox size in bytes */
+	TRACE_LEN      = 112,   /* length of trace data and mask */
+	FILTER_OPT_LEN = 36,    /* filter tuple width for optional components */
+	NWOL_PAT       = 8,     /* # of WoL patterns */
+	WOL_PAT_LEN    = 128,   /* length of WoL patterns */
+};
+
+enum {
+	SF_PAGE_SIZE = 256,           /* serial flash page size */
+	SF_SEC_SIZE = 64 * 1024,      /* serial flash sector size */
+	SF_SIZE = SF_SEC_SIZE * 16,   /* serial flash size */
+};
+
+enum { RSP_TYPE_FLBUF, RSP_TYPE_CPL, RSP_TYPE_INTR }; /* response entry types */
+
+enum { MBOX_OWNER_NONE, MBOX_OWNER_FW, MBOX_OWNER_DRV };    /* mailbox owners */
+
+enum {
+	SGE_MAX_WR_LEN = 512,     /* max WR size in bytes */
+	SGE_NTIMERS = 6,          /* # of interrupt holdoff timer values */
+	SGE_NCOUNTERS = 4,        /* # of interrupt packet counter values */
+};
+
+struct sge_qstat {                /* data written to SGE queue status entries */
+	__be32 qid;
+	__be16 cidx;
+	__be16 pidx;
+};
+
+/*
+ * Structure for last 128 bits of response descriptors
+ */
+struct rsp_ctrl {
+	__be32 hdrbuflen_pidx;
+	__be32 pldbuflen_qid;
+	union {
+		u8 type_gen;
+		__be64 last_flit;
+	};
+};
+
+#define RSPD_NEWBUF 0x80000000U
+#define RSPD_LEN    0x7fffffffU
+
+#define RSPD_GEN(x)  ((x) >> 7)
+#define RSPD_TYPE(x) (((x) >> 4) & 3)
+
+#define QINTR_CNT_EN       0x1
+#define QINTR_TIMER_IDX(x) ((x) << 1)
+#endif /* __T4_HW_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb4/t4_msg.h linux-libre-2.6.34-gnu1/drivers/net/cxgb4/t4_msg.h
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb4/t4_msg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb4/t4_msg.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,664 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __T4_MSG_H
+#define __T4_MSG_H
+
+#include <linux/types.h>
+
+enum {
+	CPL_PASS_OPEN_REQ     = 0x1,
+	CPL_PASS_ACCEPT_RPL   = 0x2,
+	CPL_ACT_OPEN_REQ      = 0x3,
+	CPL_SET_TCB_FIELD     = 0x5,
+	CPL_GET_TCB           = 0x6,
+	CPL_CLOSE_CON_REQ     = 0x8,
+	CPL_CLOSE_LISTSRV_REQ = 0x9,
+	CPL_ABORT_REQ         = 0xA,
+	CPL_ABORT_RPL         = 0xB,
+	CPL_RX_DATA_ACK       = 0xD,
+	CPL_TX_PKT            = 0xE,
+	CPL_L2T_WRITE_REQ     = 0x12,
+	CPL_TID_RELEASE       = 0x1A,
+
+	CPL_CLOSE_LISTSRV_RPL = 0x20,
+	CPL_L2T_WRITE_RPL     = 0x23,
+	CPL_PASS_OPEN_RPL     = 0x24,
+	CPL_ACT_OPEN_RPL      = 0x25,
+	CPL_PEER_CLOSE        = 0x26,
+	CPL_ABORT_REQ_RSS     = 0x2B,
+	CPL_ABORT_RPL_RSS     = 0x2D,
+
+	CPL_CLOSE_CON_RPL     = 0x32,
+	CPL_ISCSI_HDR         = 0x33,
+	CPL_RDMA_CQE          = 0x35,
+	CPL_RDMA_CQE_READ_RSP = 0x36,
+	CPL_RDMA_CQE_ERR      = 0x37,
+	CPL_RX_DATA           = 0x39,
+	CPL_SET_TCB_RPL       = 0x3A,
+	CPL_RX_PKT            = 0x3B,
+	CPL_RX_DDP_COMPLETE   = 0x3F,
+
+	CPL_ACT_ESTABLISH     = 0x40,
+	CPL_PASS_ESTABLISH    = 0x41,
+	CPL_RX_DATA_DDP       = 0x42,
+	CPL_PASS_ACCEPT_REQ   = 0x44,
+
+	CPL_RDMA_READ_REQ     = 0x60,
+
+	CPL_PASS_OPEN_REQ6    = 0x81,
+	CPL_ACT_OPEN_REQ6     = 0x83,
+
+	CPL_RDMA_TERMINATE    = 0xA2,
+	CPL_RDMA_WRITE        = 0xA4,
+	CPL_SGE_EGR_UPDATE    = 0xA5,
+
+	CPL_TRACE_PKT         = 0xB0,
+
+	CPL_FW4_MSG           = 0xC0,
+	CPL_FW4_PLD           = 0xC1,
+	CPL_FW4_ACK           = 0xC3,
+
+	CPL_FW6_MSG           = 0xE0,
+	CPL_FW6_PLD           = 0xE1,
+	CPL_TX_PKT_LSO        = 0xED,
+	CPL_TX_PKT_XT         = 0xEE,
+
+	NUM_CPL_CMDS
+};
+
+enum CPL_error {
+	CPL_ERR_NONE               = 0,
+	CPL_ERR_TCAM_FULL          = 3,
+	CPL_ERR_BAD_LENGTH         = 15,
+	CPL_ERR_BAD_ROUTE          = 18,
+	CPL_ERR_CONN_RESET         = 20,
+	CPL_ERR_CONN_EXIST_SYNRECV = 21,
+	CPL_ERR_CONN_EXIST         = 22,
+	CPL_ERR_ARP_MISS           = 23,
+	CPL_ERR_BAD_SYN            = 24,
+	CPL_ERR_CONN_TIMEDOUT      = 30,
+	CPL_ERR_XMIT_TIMEDOUT      = 31,
+	CPL_ERR_PERSIST_TIMEDOUT   = 32,
+	CPL_ERR_FINWAIT2_TIMEDOUT  = 33,
+	CPL_ERR_KEEPALIVE_TIMEDOUT = 34,
+	CPL_ERR_RTX_NEG_ADVICE     = 35,
+	CPL_ERR_PERSIST_NEG_ADVICE = 36,
+	CPL_ERR_ABORT_FAILED       = 42,
+	CPL_ERR_IWARP_FLM          = 50,
+};
+
+enum {
+	ULP_MODE_NONE          = 0,
+	ULP_MODE_ISCSI         = 2,
+	ULP_MODE_RDMA          = 4,
+	ULP_MODE_FCOE          = 6,
+};
+
+enum {
+	ULP_CRC_HEADER = 1 << 0,
+	ULP_CRC_DATA   = 1 << 1
+};
+
+enum {
+	CPL_ABORT_SEND_RST = 0,
+	CPL_ABORT_NO_RST,
+};
+
+enum {                     /* TX_PKT_XT checksum types */
+	TX_CSUM_TCP    = 0,
+	TX_CSUM_UDP    = 1,
+	TX_CSUM_CRC16  = 4,
+	TX_CSUM_CRC32  = 5,
+	TX_CSUM_CRC32C = 6,
+	TX_CSUM_FCOE   = 7,
+	TX_CSUM_TCPIP  = 8,
+	TX_CSUM_UDPIP  = 9,
+	TX_CSUM_TCPIP6 = 10,
+	TX_CSUM_UDPIP6 = 11,
+	TX_CSUM_IP     = 12,
+};
+
+union opcode_tid {
+	__be32 opcode_tid;
+	u8 opcode;
+};
+
+#define CPL_OPCODE(x) ((x) << 24)
+#define MK_OPCODE_TID(opcode, tid) (CPL_OPCODE(opcode) | (tid))
+#define OPCODE_TID(cmd) ((cmd)->ot.opcode_tid)
+#define GET_TID(cmd) (ntohl(OPCODE_TID(cmd)) & 0xFFFFFF)
+
+/* partitioning of TID fields that also carry a queue id */
+#define GET_TID_TID(x) ((x) & 0x3fff)
+#define GET_TID_QID(x) (((x) >> 14) & 0x3ff)
+#define TID_QID(x)     ((x) << 14)
+
+struct rss_header {
+	u8 opcode;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+	u8 channel:2;
+	u8 filter_hit:1;
+	u8 filter_tid:1;
+	u8 hash_type:2;
+	u8 ipv6:1;
+	u8 send2fw:1;
+#else
+	u8 send2fw:1;
+	u8 ipv6:1;
+	u8 hash_type:2;
+	u8 filter_tid:1;
+	u8 filter_hit:1;
+	u8 channel:2;
+#endif
+	__be16 qid;
+	__be32 hash_val;
+};
+
+struct work_request_hdr {
+	__be32 wr_hi;
+	__be32 wr_mid;
+	__be64 wr_lo;
+};
+
+#define WR_HDR struct work_request_hdr wr
+
+struct cpl_pass_open_req {
+	WR_HDR;
+	union opcode_tid ot;
+	__be16 local_port;
+	__be16 peer_port;
+	__be32 local_ip;
+	__be32 peer_ip;
+	__be64 opt0;
+#define TX_CHAN(x)    ((x) << 2)
+#define DELACK(x)     ((x) << 5)
+#define ULP_MODE(x)   ((x) << 8)
+#define RCV_BUFSIZ(x) ((x) << 12)
+#define DSCP(x)       ((x) << 22)
+#define SMAC_SEL(x)   ((u64)(x) << 28)
+#define L2T_IDX(x)    ((u64)(x) << 36)
+#define NAGLE(x)      ((u64)(x) << 49)
+#define WND_SCALE(x)  ((u64)(x) << 50)
+#define KEEP_ALIVE(x) ((u64)(x) << 54)
+#define MSS_IDX(x)    ((u64)(x) << 60)
+	__be64 opt1;
+#define SYN_RSS_ENABLE   (1 << 0)
+#define SYN_RSS_QUEUE(x) ((x) << 2)
+#define CONN_POLICY_ASK  (1 << 22)
+};
+
+struct cpl_pass_open_req6 {
+	WR_HDR;
+	union opcode_tid ot;
+	__be16 local_port;
+	__be16 peer_port;
+	__be64 local_ip_hi;
+	__be64 local_ip_lo;
+	__be64 peer_ip_hi;
+	__be64 peer_ip_lo;
+	__be64 opt0;
+	__be64 opt1;
+};
+
+struct cpl_pass_open_rpl {
+	union opcode_tid ot;
+	u8 rsvd[3];
+	u8 status;
+};
+
+struct cpl_pass_accept_rpl {
+	WR_HDR;
+	union opcode_tid ot;
+	__be32 opt2;
+#define RSS_QUEUE(x)         ((x) << 0)
+#define RSS_QUEUE_VALID      (1 << 10)
+#define RX_COALESCE_VALID(x) ((x) << 11)
+#define RX_COALESCE(x)       ((x) << 12)
+#define TX_QUEUE(x)          ((x) << 23)
+#define RX_CHANNEL(x)        ((x) << 26)
+#define WND_SCALE_EN(x)      ((x) << 28)
+#define TSTAMPS_EN(x)        ((x) << 29)
+#define SACK_EN(x)           ((x) << 30)
+	__be64 opt0;
+};
+
+struct cpl_act_open_req {
+	WR_HDR;
+	union opcode_tid ot;
+	__be16 local_port;
+	__be16 peer_port;
+	__be32 local_ip;
+	__be32 peer_ip;
+	__be64 opt0;
+	__be32 params;
+	__be32 opt2;
+};
+
+struct cpl_act_open_req6 {
+	WR_HDR;
+	union opcode_tid ot;
+	__be16 local_port;
+	__be16 peer_port;
+	__be64 local_ip_hi;
+	__be64 local_ip_lo;
+	__be64 peer_ip_hi;
+	__be64 peer_ip_lo;
+	__be64 opt0;
+	__be32 params;
+	__be32 opt2;
+};
+
+struct cpl_act_open_rpl {
+	union opcode_tid ot;
+	__be32 atid_status;
+#define GET_AOPEN_STATUS(x) ((x) & 0xff)
+#define GET_AOPEN_ATID(x)   (((x) >> 8) & 0xffffff)
+};
+
+struct cpl_pass_establish {
+	union opcode_tid ot;
+	__be32 rsvd;
+	__be32 tos_stid;
+#define GET_POPEN_TID(x) ((x) & 0xffffff)
+#define GET_POPEN_TOS(x) (((x) >> 24) & 0xff)
+	__be16 mac_idx;
+	__be16 tcp_opt;
+#define GET_TCPOPT_WSCALE_OK(x)  (((x) >> 5) & 1)
+#define GET_TCPOPT_SACK(x)       (((x) >> 6) & 1)
+#define GET_TCPOPT_TSTAMP(x)     (((x) >> 7) & 1)
+#define GET_TCPOPT_SND_WSCALE(x) (((x) >> 8) & 0xf)
+#define GET_TCPOPT_MSS(x)        (((x) >> 12) & 0xf)
+	__be32 snd_isn;
+	__be32 rcv_isn;
+};
+
+struct cpl_act_establish {
+	union opcode_tid ot;
+	__be32 rsvd;
+	__be32 tos_atid;
+	__be16 mac_idx;
+	__be16 tcp_opt;
+	__be32 snd_isn;
+	__be32 rcv_isn;
+};
+
+struct cpl_get_tcb {
+	WR_HDR;
+	union opcode_tid ot;
+	__be16 reply_ctrl;
+#define QUEUENO(x)    ((x) << 0)
+#define REPLY_CHAN(x) ((x) << 14)
+#define NO_REPLY(x)   ((x) << 15)
+	__be16 cookie;
+};
+
+struct cpl_set_tcb_field {
+	WR_HDR;
+	union opcode_tid ot;
+	__be16 reply_ctrl;
+	__be16 word_cookie;
+#define TCB_WORD(x)   ((x) << 0)
+#define TCB_COOKIE(x) ((x) << 5)
+	__be64 mask;
+	__be64 val;
+};
+
+struct cpl_set_tcb_rpl {
+	union opcode_tid ot;
+	__be16 rsvd;
+	u8 cookie;
+	u8 status;
+	__be64 oldval;
+};
+
+struct cpl_close_con_req {
+	WR_HDR;
+	union opcode_tid ot;
+	__be32 rsvd;
+};
+
+struct cpl_close_con_rpl {
+	union opcode_tid ot;
+	u8 rsvd[3];
+	u8 status;
+	__be32 snd_nxt;
+	__be32 rcv_nxt;
+};
+
+struct cpl_close_listsvr_req {
+	WR_HDR;
+	union opcode_tid ot;
+	__be16 reply_ctrl;
+#define LISTSVR_IPV6 (1 << 14)
+	__be16 rsvd;
+};
+
+struct cpl_close_listsvr_rpl {
+	union opcode_tid ot;
+	u8 rsvd[3];
+	u8 status;
+};
+
+struct cpl_abort_req_rss {
+	union opcode_tid ot;
+	u8 rsvd[3];
+	u8 status;
+};
+
+struct cpl_abort_req {
+	WR_HDR;
+	union opcode_tid ot;
+	__be32 rsvd0;
+	u8 rsvd1;
+	u8 cmd;
+	u8 rsvd2[6];
+};
+
+struct cpl_abort_rpl_rss {
+	union opcode_tid ot;
+	u8 rsvd[3];
+	u8 status;
+};
+
+struct cpl_abort_rpl {
+	WR_HDR;
+	union opcode_tid ot;
+	__be32 rsvd0;
+	u8 rsvd1;
+	u8 cmd;
+	u8 rsvd2[6];
+};
+
+struct cpl_peer_close {
+	union opcode_tid ot;
+	__be32 rcv_nxt;
+};
+
+struct cpl_tid_release {
+	WR_HDR;
+	union opcode_tid ot;
+	__be32 rsvd;
+};
+
+struct cpl_tx_pkt_core {
+	__be32 ctrl0;
+#define TXPKT_VF(x)        ((x) << 0)
+#define TXPKT_PF(x)        ((x) << 8)
+#define TXPKT_VF_VLD       (1 << 11)
+#define TXPKT_OVLAN_IDX(x) ((x) << 12)
+#define TXPKT_INTF(x)      ((x) << 16)
+#define TXPKT_INS_OVLAN    (1 << 21)
+#define TXPKT_OPCODE(x)    ((x) << 24)
+	__be16 pack;
+	__be16 len;
+	__be64 ctrl1;
+#define TXPKT_CSUM_END(x)   ((x) << 12)
+#define TXPKT_CSUM_START(x) ((x) << 20)
+#define TXPKT_IPHDR_LEN(x)  ((u64)(x) << 20)
+#define TXPKT_CSUM_LOC(x)   ((u64)(x) << 30)
+#define TXPKT_ETHHDR_LEN(x) ((u64)(x) << 34)
+#define TXPKT_CSUM_TYPE(x)  ((u64)(x) << 40)
+#define TXPKT_VLAN(x)       ((u64)(x) << 44)
+#define TXPKT_VLAN_VLD      (1ULL << 60)
+#define TXPKT_IPCSUM_DIS    (1ULL << 62)
+#define TXPKT_L4CSUM_DIS    (1ULL << 63)
+};
+
+struct cpl_tx_pkt {
+	WR_HDR;
+	struct cpl_tx_pkt_core c;
+};
+
+#define cpl_tx_pkt_xt cpl_tx_pkt
+
+struct cpl_tx_pkt_lso {
+	WR_HDR;
+	__be32 lso_ctrl;
+#define LSO_TCPHDR_LEN(x) ((x) << 0)
+#define LSO_IPHDR_LEN(x)  ((x) << 4)
+#define LSO_ETHHDR_LEN(x) ((x) << 16)
+#define LSO_IPV6(x)       ((x) << 20)
+#define LSO_LAST_SLICE    (1 << 22)
+#define LSO_FIRST_SLICE   (1 << 23)
+#define LSO_OPCODE(x)     ((x) << 24)
+	__be16 ipid_ofst;
+	__be16 mss;
+	__be32 seqno_offset;
+	__be32 len;
+	/* encapsulated CPL (TX_PKT, TX_PKT_XT or TX_DATA) follows here */
+};
+
+struct cpl_iscsi_hdr {
+	union opcode_tid ot;
+	__be16 pdu_len_ddp;
+#define ISCSI_PDU_LEN(x) ((x) & 0x7FFF)
+#define ISCSI_DDP        (1 << 15)
+	__be16 len;
+	__be32 seq;
+	__be16 urg;
+	u8 rsvd;
+	u8 status;
+};
+
+struct cpl_rx_data {
+	union opcode_tid ot;
+	__be16 rsvd;
+	__be16 len;
+	__be32 seq;
+	__be16 urg;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+	u8 dack_mode:2;
+	u8 psh:1;
+	u8 heartbeat:1;
+	u8 ddp_off:1;
+	u8 :3;
+#else
+	u8 :3;
+	u8 ddp_off:1;
+	u8 heartbeat:1;
+	u8 psh:1;
+	u8 dack_mode:2;
+#endif
+	u8 status;
+};
+
+struct cpl_rx_data_ack {
+	WR_HDR;
+	union opcode_tid ot;
+	__be32 credit_dack;
+#define RX_CREDITS(x)   ((x) << 0)
+#define RX_FORCE_ACK(x) ((x) << 28)
+};
+
+struct cpl_rx_pkt {
+	u8 opcode;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+	u8 iff:4;
+	u8 csum_calc:1;
+	u8 ipmi_pkt:1;
+	u8 vlan_ex:1;
+	u8 ip_frag:1;
+#else
+	u8 ip_frag:1;
+	u8 vlan_ex:1;
+	u8 ipmi_pkt:1;
+	u8 csum_calc:1;
+	u8 iff:4;
+#endif
+	__be16 csum;
+	__be16 vlan;
+	__be16 len;
+	__be32 l2info;
+#define RXF_UDP (1 << 22)
+#define RXF_TCP (1 << 23)
+	__be16 hdr_len;
+	__be16 err_vec;
+};
+
+struct cpl_trace_pkt {
+	u8 opcode;
+	u8 intf;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+	u8 runt:4;
+	u8 filter_hit:4;
+	u8 :6;
+	u8 err:1;
+	u8 trunc:1;
+#else
+	u8 filter_hit:4;
+	u8 runt:4;
+	u8 trunc:1;
+	u8 err:1;
+	u8 :6;
+#endif
+	__be16 rsvd;
+	__be16 len;
+	__be64 tstamp;
+};
+
+struct cpl_l2t_write_req {
+	WR_HDR;
+	union opcode_tid ot;
+	__be16 params;
+#define L2T_W_INFO(x)    ((x) << 2)
+#define L2T_W_PORT(x)    ((x) << 8)
+#define L2T_W_NOREPLY(x) ((x) << 15)
+	__be16 l2t_idx;
+	__be16 vlan;
+	u8 dst_mac[6];
+};
+
+struct cpl_l2t_write_rpl {
+	union opcode_tid ot;
+	u8 status;
+	u8 rsvd[3];
+};
+
+struct cpl_rdma_terminate {
+	union opcode_tid ot;
+	__be16 rsvd;
+	__be16 len;
+};
+
+struct cpl_sge_egr_update {
+	__be32 opcode_qid;
+#define EGR_QID(x) ((x) & 0x1FFFF)
+	__be16 cidx;
+	__be16 pidx;
+};
+
+struct cpl_fw4_pld {
+	u8 opcode;
+	u8 rsvd0[3];
+	u8 type;
+	u8 rsvd1;
+	__be16 len;
+	__be64 data;
+	__be64 rsvd2;
+};
+
+struct cpl_fw6_pld {
+	u8 opcode;
+	u8 rsvd[5];
+	__be16 len;
+	__be64 data[4];
+};
+
+struct cpl_fw4_msg {
+	u8 opcode;
+	u8 type;
+	__be16 rsvd0;
+	__be32 rsvd1;
+	__be64 data[2];
+};
+
+struct cpl_fw4_ack {
+	union opcode_tid ot;
+	u8 credits;
+	u8 rsvd0[2];
+	u8 seq_vld;
+	__be32 snd_nxt;
+	__be32 snd_una;
+	__be64 rsvd1;
+};
+
+struct cpl_fw6_msg {
+	u8 opcode;
+	u8 type;
+	__be16 rsvd0;
+	__be32 rsvd1;
+	__be64 data[4];
+};
+
+enum {
+	ULP_TX_MEM_READ = 2,
+	ULP_TX_MEM_WRITE = 3,
+	ULP_TX_PKT = 4
+};
+
+enum {
+	ULP_TX_SC_NOOP = 0x80,
+	ULP_TX_SC_IMM  = 0x81,
+	ULP_TX_SC_DSGL = 0x82,
+	ULP_TX_SC_ISGL = 0x83
+};
+
+struct ulptx_sge_pair {
+	__be32 len[2];
+	__be64 addr[2];
+};
+
+struct ulptx_sgl {
+	__be32 cmd_nsge;
+#define ULPTX_CMD(x) ((x) << 24)
+#define ULPTX_NSGE(x) ((x) << 0)
+	__be32 len0;
+	__be64 addr0;
+	struct ulptx_sge_pair sge[0];
+};
+
+struct ulp_mem_io {
+	WR_HDR;
+	__be32 cmd;
+#define ULP_MEMIO_ORDER(x) ((x) << 23)
+	__be32 len16;             /* command length */
+	__be32 dlen;              /* data length in 32-byte units */
+#define ULP_MEMIO_DATA_LEN(x) ((x) << 0)
+	__be32 lock_addr;
+#define ULP_MEMIO_ADDR(x) ((x) << 0)
+#define ULP_MEMIO_LOCK(x) ((x) << 31)
+};
+
+#endif  /* __T4_MSG_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/cxgb4/t4_regs.h linux-libre-2.6.34-gnu1/drivers/net/cxgb4/t4_regs.h
--- linux-libre-2.6.33-gnu1/drivers/net/cxgb4/t4_regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/cxgb4/t4_regs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,878 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __T4_REGS_H
+#define __T4_REGS_H
+
+#define MYPF_BASE 0x1b000
+#define MYPF_REG(reg_addr) (MYPF_BASE + (reg_addr))
+
+#define PF0_BASE 0x1e000
+#define PF0_REG(reg_addr) (PF0_BASE + (reg_addr))
+
+#define PF_STRIDE 0x400
+#define PF_BASE(idx) (PF0_BASE + (idx) * PF_STRIDE)
+#define PF_REG(idx, reg) (PF_BASE(idx) + (reg))
+
+#define MYPORT_BASE 0x1c000
+#define MYPORT_REG(reg_addr) (MYPORT_BASE + (reg_addr))
+
+#define PORT0_BASE 0x20000
+#define PORT0_REG(reg_addr) (PORT0_BASE + (reg_addr))
+
+#define PORT_STRIDE 0x2000
+#define PORT_BASE(idx) (PORT0_BASE + (idx) * PORT_STRIDE)
+#define PORT_REG(idx, reg) (PORT_BASE(idx) + (reg))
+
+#define EDC_STRIDE (EDC_1_BASE_ADDR - EDC_0_BASE_ADDR)
+#define EDC_REG(reg, idx) (reg + EDC_STRIDE * idx)
+
+#define PCIE_MEM_ACCESS_REG(reg_addr, idx) ((reg_addr) + (idx) * 8)
+#define PCIE_MAILBOX_REG(reg_addr, idx) ((reg_addr) + (idx) * 8)
+#define MC_BIST_STATUS_REG(reg_addr, idx) ((reg_addr) + (idx) * 4)
+#define EDC_BIST_STATUS_REG(reg_addr, idx) ((reg_addr) + (idx) * 4)
+
+#define SGE_PF_KDOORBELL 0x0
+#define  QID_MASK    0xffff8000U
+#define  QID_SHIFT   15
+#define  QID(x)      ((x) << QID_SHIFT)
+#define  DBPRIO      0x00004000U
+#define  PIDX_MASK   0x00003fffU
+#define  PIDX_SHIFT  0
+#define  PIDX(x)     ((x) << PIDX_SHIFT)
+
+#define SGE_PF_GTS 0x4
+#define  INGRESSQID_MASK   0xffff0000U
+#define  INGRESSQID_SHIFT  16
+#define  INGRESSQID(x)     ((x) << INGRESSQID_SHIFT)
+#define  TIMERREG_MASK     0x0000e000U
+#define  TIMERREG_SHIFT    13
+#define  TIMERREG(x)       ((x) << TIMERREG_SHIFT)
+#define  SEINTARM_MASK     0x00001000U
+#define  SEINTARM_SHIFT    12
+#define  SEINTARM(x)       ((x) << SEINTARM_SHIFT)
+#define  CIDXINC_MASK      0x00000fffU
+#define  CIDXINC_SHIFT     0
+#define  CIDXINC(x)        ((x) << CIDXINC_SHIFT)
+
+#define SGE_CONTROL 0x1008
+#define  DCASYSTYPE             0x00080000U
+#define  RXPKTCPLMODE           0x00040000U
+#define  EGRSTATUSPAGESIZE      0x00020000U
+#define  PKTSHIFT_MASK          0x00001c00U
+#define  PKTSHIFT_SHIFT         10
+#define  PKTSHIFT(x)            ((x) << PKTSHIFT_SHIFT)
+#define  INGPCIEBOUNDARY_MASK   0x00000380U
+#define  INGPCIEBOUNDARY_SHIFT  7
+#define  INGPCIEBOUNDARY(x)     ((x) << INGPCIEBOUNDARY_SHIFT)
+#define  INGPADBOUNDARY_MASK    0x00000070U
+#define  INGPADBOUNDARY_SHIFT   4
+#define  INGPADBOUNDARY(x)      ((x) << INGPADBOUNDARY_SHIFT)
+#define  EGRPCIEBOUNDARY_MASK   0x0000000eU
+#define  EGRPCIEBOUNDARY_SHIFT  1
+#define  EGRPCIEBOUNDARY(x)     ((x) << EGRPCIEBOUNDARY_SHIFT)
+#define  GLOBALENABLE           0x00000001U
+
+#define SGE_HOST_PAGE_SIZE 0x100c
+#define  HOSTPAGESIZEPF0_MASK   0x0000000fU
+#define  HOSTPAGESIZEPF0_SHIFT  0
+#define  HOSTPAGESIZEPF0(x)     ((x) << HOSTPAGESIZEPF0_SHIFT)
+
+#define SGE_EGRESS_QUEUES_PER_PAGE_PF 0x1010
+#define  QUEUESPERPAGEPF0_MASK   0x0000000fU
+#define  QUEUESPERPAGEPF0_GET(x) ((x) & QUEUESPERPAGEPF0_MASK)
+
+#define SGE_INT_CAUSE1 0x1024
+#define SGE_INT_CAUSE2 0x1030
+#define SGE_INT_CAUSE3 0x103c
+#define  ERR_FLM_DBP               0x80000000U
+#define  ERR_FLM_IDMA1             0x40000000U
+#define  ERR_FLM_IDMA0             0x20000000U
+#define  ERR_FLM_HINT              0x10000000U
+#define  ERR_PCIE_ERROR3           0x08000000U
+#define  ERR_PCIE_ERROR2           0x04000000U
+#define  ERR_PCIE_ERROR1           0x02000000U
+#define  ERR_PCIE_ERROR0           0x01000000U
+#define  ERR_TIMER_ABOVE_MAX_QID   0x00800000U
+#define  ERR_CPL_EXCEED_IQE_SIZE   0x00400000U
+#define  ERR_INVALID_CIDX_INC      0x00200000U
+#define  ERR_ITP_TIME_PAUSED       0x00100000U
+#define  ERR_CPL_OPCODE_0          0x00080000U
+#define  ERR_DROPPED_DB            0x00040000U
+#define  ERR_DATA_CPL_ON_HIGH_QID1 0x00020000U
+#define  ERR_DATA_CPL_ON_HIGH_QID0 0x00010000U
+#define  ERR_BAD_DB_PIDX3          0x00008000U
+#define  ERR_BAD_DB_PIDX2          0x00004000U
+#define  ERR_BAD_DB_PIDX1          0x00002000U
+#define  ERR_BAD_DB_PIDX0          0x00001000U
+#define  ERR_ING_PCIE_CHAN         0x00000800U
+#define  ERR_ING_CTXT_PRIO         0x00000400U
+#define  ERR_EGR_CTXT_PRIO         0x00000200U
+#define  DBFIFO_HP_INT             0x00000100U
+#define  DBFIFO_LP_INT             0x00000080U
+#define  REG_ADDRESS_ERR           0x00000040U
+#define  INGRESS_SIZE_ERR          0x00000020U
+#define  EGRESS_SIZE_ERR           0x00000010U
+#define  ERR_INV_CTXT3             0x00000008U
+#define  ERR_INV_CTXT2             0x00000004U
+#define  ERR_INV_CTXT1             0x00000002U
+#define  ERR_INV_CTXT0             0x00000001U
+
+#define SGE_INT_ENABLE3 0x1040
+#define SGE_FL_BUFFER_SIZE0 0x1044
+#define SGE_FL_BUFFER_SIZE1 0x1048
+#define SGE_INGRESS_RX_THRESHOLD 0x10a0
+#define  THRESHOLD_0_MASK   0x3f000000U
+#define  THRESHOLD_0_SHIFT  24
+#define  THRESHOLD_0(x)     ((x) << THRESHOLD_0_SHIFT)
+#define  THRESHOLD_0_GET(x) (((x) & THRESHOLD_0_MASK) >> THRESHOLD_0_SHIFT)
+#define  THRESHOLD_1_MASK   0x003f0000U
+#define  THRESHOLD_1_SHIFT  16
+#define  THRESHOLD_1(x)     ((x) << THRESHOLD_1_SHIFT)
+#define  THRESHOLD_1_GET(x) (((x) & THRESHOLD_1_MASK) >> THRESHOLD_1_SHIFT)
+#define  THRESHOLD_2_MASK   0x00003f00U
+#define  THRESHOLD_2_SHIFT  8
+#define  THRESHOLD_2(x)     ((x) << THRESHOLD_2_SHIFT)
+#define  THRESHOLD_2_GET(x) (((x) & THRESHOLD_2_MASK) >> THRESHOLD_2_SHIFT)
+#define  THRESHOLD_3_MASK   0x0000003fU
+#define  THRESHOLD_3_SHIFT  0
+#define  THRESHOLD_3(x)     ((x) << THRESHOLD_3_SHIFT)
+#define  THRESHOLD_3_GET(x) (((x) & THRESHOLD_3_MASK) >> THRESHOLD_3_SHIFT)
+
+#define SGE_TIMER_VALUE_0_AND_1 0x10b8
+#define  TIMERVALUE0_MASK   0xffff0000U
+#define  TIMERVALUE0_SHIFT  16
+#define  TIMERVALUE0(x)     ((x) << TIMERVALUE0_SHIFT)
+#define  TIMERVALUE0_GET(x) (((x) & TIMERVALUE0_MASK) >> TIMERVALUE0_SHIFT)
+#define  TIMERVALUE1_MASK   0x0000ffffU
+#define  TIMERVALUE1_SHIFT  0
+#define  TIMERVALUE1(x)     ((x) << TIMERVALUE1_SHIFT)
+#define  TIMERVALUE1_GET(x) (((x) & TIMERVALUE1_MASK) >> TIMERVALUE1_SHIFT)
+
+#define SGE_TIMER_VALUE_2_AND_3 0x10bc
+#define SGE_TIMER_VALUE_4_AND_5 0x10c0
+#define SGE_DEBUG_INDEX 0x10cc
+#define SGE_DEBUG_DATA_HIGH 0x10d0
+#define SGE_DEBUG_DATA_LOW 0x10d4
+#define SGE_INGRESS_QUEUES_PER_PAGE_PF 0x10f4
+
+#define PCIE_PF_CLI 0x44
+#define PCIE_INT_CAUSE 0x3004
+#define  UNXSPLCPLERR  0x20000000U
+#define  PCIEPINT      0x10000000U
+#define  PCIESINT      0x08000000U
+#define  RPLPERR       0x04000000U
+#define  RXWRPERR      0x02000000U
+#define  RXCPLPERR     0x01000000U
+#define  PIOTAGPERR    0x00800000U
+#define  MATAGPERR     0x00400000U
+#define  INTXCLRPERR   0x00200000U
+#define  FIDPERR       0x00100000U
+#define  CFGSNPPERR    0x00080000U
+#define  HRSPPERR      0x00040000U
+#define  HREQPERR      0x00020000U
+#define  HCNTPERR      0x00010000U
+#define  DRSPPERR      0x00008000U
+#define  DREQPERR      0x00004000U
+#define  DCNTPERR      0x00002000U
+#define  CRSPPERR      0x00001000U
+#define  CREQPERR      0x00000800U
+#define  CCNTPERR      0x00000400U
+#define  TARTAGPERR    0x00000200U
+#define  PIOREQPERR    0x00000100U
+#define  PIOCPLPERR    0x00000080U
+#define  MSIXDIPERR    0x00000040U
+#define  MSIXDATAPERR  0x00000020U
+#define  MSIXADDRHPERR 0x00000010U
+#define  MSIXADDRLPERR 0x00000008U
+#define  MSIDATAPERR   0x00000004U
+#define  MSIADDRHPERR  0x00000002U
+#define  MSIADDRLPERR  0x00000001U
+
+#define PCIE_NONFAT_ERR 0x3010
+#define PCIE_MEM_ACCESS_BASE_WIN 0x3068
+#define  PCIEOFST_MASK   0xfffffc00U
+#define  BIR_MASK        0x00000300U
+#define  BIR_SHIFT       8
+#define  BIR(x)          ((x) << BIR_SHIFT)
+#define  WINDOW_MASK     0x000000ffU
+#define  WINDOW_SHIFT    0
+#define  WINDOW(x)       ((x) << WINDOW_SHIFT)
+
+#define PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS 0x5908
+#define  RNPP 0x80000000U
+#define  RPCP 0x20000000U
+#define  RCIP 0x08000000U
+#define  RCCP 0x04000000U
+#define  RFTP 0x00800000U
+#define  PTRP 0x00100000U
+
+#define PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS 0x59a4
+#define  TPCP 0x40000000U
+#define  TNPP 0x20000000U
+#define  TFTP 0x10000000U
+#define  TCAP 0x08000000U
+#define  TCIP 0x04000000U
+#define  RCAP 0x02000000U
+#define  PLUP 0x00800000U
+#define  PLDN 0x00400000U
+#define  OTDD 0x00200000U
+#define  GTRP 0x00100000U
+#define  RDPE 0x00040000U
+#define  TDCE 0x00020000U
+#define  TDUE 0x00010000U
+
+#define MC_INT_CAUSE 0x7518
+#define  ECC_UE_INT_CAUSE 0x00000004U
+#define  ECC_CE_INT_CAUSE 0x00000002U
+#define  PERR_INT_CAUSE   0x00000001U
+
+#define MC_ECC_STATUS 0x751c
+#define  ECC_CECNT_MASK   0xffff0000U
+#define  ECC_CECNT_SHIFT  16
+#define  ECC_CECNT(x)     ((x) << ECC_CECNT_SHIFT)
+#define  ECC_CECNT_GET(x) (((x) & ECC_CECNT_MASK) >> ECC_CECNT_SHIFT)
+#define  ECC_UECNT_MASK   0x0000ffffU
+#define  ECC_UECNT_SHIFT  0
+#define  ECC_UECNT(x)     ((x) << ECC_UECNT_SHIFT)
+#define  ECC_UECNT_GET(x) (((x) & ECC_UECNT_MASK) >> ECC_UECNT_SHIFT)
+
+#define MC_BIST_CMD 0x7600
+#define  START_BIST          0x80000000U
+#define  BIST_CMD_GAP_MASK   0x0000ff00U
+#define  BIST_CMD_GAP_SHIFT  8
+#define  BIST_CMD_GAP(x)     ((x) << BIST_CMD_GAP_SHIFT)
+#define  BIST_OPCODE_MASK    0x00000003U
+#define  BIST_OPCODE_SHIFT   0
+#define  BIST_OPCODE(x)      ((x) << BIST_OPCODE_SHIFT)
+
+#define MC_BIST_CMD_ADDR 0x7604
+#define MC_BIST_CMD_LEN 0x7608
+#define MC_BIST_DATA_PATTERN 0x760c
+#define  BIST_DATA_TYPE_MASK   0x0000000fU
+#define  BIST_DATA_TYPE_SHIFT  0
+#define  BIST_DATA_TYPE(x)     ((x) << BIST_DATA_TYPE_SHIFT)
+
+#define MC_BIST_STATUS_RDATA 0x7688
+
+#define MA_EXT_MEMORY_BAR 0x77c8
+#define  EXT_MEM_SIZE_MASK   0x00000fffU
+#define  EXT_MEM_SIZE_SHIFT  0
+#define  EXT_MEM_SIZE_GET(x) (((x) & EXT_MEM_SIZE_MASK) >> EXT_MEM_SIZE_SHIFT)
+
+#define MA_TARGET_MEM_ENABLE 0x77d8
+#define  EXT_MEM_ENABLE 0x00000004U
+#define  EDRAM1_ENABLE  0x00000002U
+#define  EDRAM0_ENABLE  0x00000001U
+
+#define MA_INT_CAUSE 0x77e0
+#define  MEM_PERR_INT_CAUSE 0x00000002U
+#define  MEM_WRAP_INT_CAUSE 0x00000001U
+
+#define MA_INT_WRAP_STATUS 0x77e4
+#define  MEM_WRAP_ADDRESS_MASK   0xfffffff0U
+#define  MEM_WRAP_ADDRESS_SHIFT  4
+#define  MEM_WRAP_ADDRESS_GET(x) (((x) & MEM_WRAP_ADDRESS_MASK) >> MEM_WRAP_ADDRESS_SHIFT)
+#define  MEM_WRAP_CLIENT_NUM_MASK   0x0000000fU
+#define  MEM_WRAP_CLIENT_NUM_SHIFT  0
+#define  MEM_WRAP_CLIENT_NUM_GET(x) (((x) & MEM_WRAP_CLIENT_NUM_MASK) >> MEM_WRAP_CLIENT_NUM_SHIFT)
+
+#define MA_PARITY_ERROR_STATUS 0x77f4
+
+#define EDC_0_BASE_ADDR 0x7900
+
+#define EDC_BIST_CMD 0x7904
+#define EDC_BIST_CMD_ADDR 0x7908
+#define EDC_BIST_CMD_LEN 0x790c
+#define EDC_BIST_DATA_PATTERN 0x7910
+#define EDC_BIST_STATUS_RDATA 0x7928
+#define EDC_INT_CAUSE 0x7978
+#define  ECC_UE_PAR     0x00000020U
+#define  ECC_CE_PAR     0x00000010U
+#define  PERR_PAR_CAUSE 0x00000008U
+
+#define EDC_ECC_STATUS 0x797c
+
+#define EDC_1_BASE_ADDR 0x7980
+
+#define CIM_PF_MAILBOX_DATA 0x240
+#define CIM_PF_MAILBOX_CTRL 0x280
+#define  MBMSGVALID     0x00000008U
+#define  MBINTREQ       0x00000004U
+#define  MBOWNER_MASK   0x00000003U
+#define  MBOWNER_SHIFT  0
+#define  MBOWNER(x)     ((x) << MBOWNER_SHIFT)
+#define  MBOWNER_GET(x) (((x) & MBOWNER_MASK) >> MBOWNER_SHIFT)
+
+#define CIM_PF_HOST_INT_CAUSE 0x28c
+#define  MBMSGRDYINT 0x00080000U
+
+#define CIM_HOST_INT_CAUSE 0x7b2c
+#define  TIEQOUTPARERRINT  0x00100000U
+#define  TIEQINPARERRINT   0x00080000U
+#define  MBHOSTPARERR      0x00040000U
+#define  MBUPPARERR        0x00020000U
+#define  IBQPARERR         0x0001f800U
+#define  IBQTP0PARERR      0x00010000U
+#define  IBQTP1PARERR      0x00008000U
+#define  IBQULPPARERR      0x00004000U
+#define  IBQSGELOPARERR    0x00002000U
+#define  IBQSGEHIPARERR    0x00001000U
+#define  IBQNCSIPARERR     0x00000800U
+#define  OBQPARERR         0x000007e0U
+#define  OBQULP0PARERR     0x00000400U
+#define  OBQULP1PARERR     0x00000200U
+#define  OBQULP2PARERR     0x00000100U
+#define  OBQULP3PARERR     0x00000080U
+#define  OBQSGEPARERR      0x00000040U
+#define  OBQNCSIPARERR     0x00000020U
+#define  PREFDROPINT       0x00000002U
+#define  UPACCNONZERO      0x00000001U
+
+#define CIM_HOST_UPACC_INT_CAUSE 0x7b34
+#define  EEPROMWRINT      0x40000000U
+#define  TIMEOUTMAINT     0x20000000U
+#define  TIMEOUTINT       0x10000000U
+#define  RSPOVRLOOKUPINT  0x08000000U
+#define  REQOVRLOOKUPINT  0x04000000U
+#define  BLKWRPLINT       0x02000000U
+#define  BLKRDPLINT       0x01000000U
+#define  SGLWRPLINT       0x00800000U
+#define  SGLRDPLINT       0x00400000U
+#define  BLKWRCTLINT      0x00200000U
+#define  BLKRDCTLINT      0x00100000U
+#define  SGLWRCTLINT      0x00080000U
+#define  SGLRDCTLINT      0x00040000U
+#define  BLKWREEPROMINT   0x00020000U
+#define  BLKRDEEPROMINT   0x00010000U
+#define  SGLWREEPROMINT   0x00008000U
+#define  SGLRDEEPROMINT   0x00004000U
+#define  BLKWRFLASHINT    0x00002000U
+#define  BLKRDFLASHINT    0x00001000U
+#define  SGLWRFLASHINT    0x00000800U
+#define  SGLRDFLASHINT    0x00000400U
+#define  BLKWRBOOTINT     0x00000200U
+#define  BLKRDBOOTINT     0x00000100U
+#define  SGLWRBOOTINT     0x00000080U
+#define  SGLRDBOOTINT     0x00000040U
+#define  ILLWRBEINT       0x00000020U
+#define  ILLRDBEINT       0x00000010U
+#define  ILLRDINT         0x00000008U
+#define  ILLWRINT         0x00000004U
+#define  ILLTRANSINT      0x00000002U
+#define  RSVDSPACEINT     0x00000001U
+
+#define TP_OUT_CONFIG 0x7d04
+#define  VLANEXTENABLE_MASK  0x0000f000U
+#define  VLANEXTENABLE_SHIFT 12
+
+#define TP_PARA_REG2 0x7d68
+#define  MAXRXDATA_MASK    0xffff0000U
+#define  MAXRXDATA_SHIFT   16
+#define  MAXRXDATA_GET(x) (((x) & MAXRXDATA_MASK) >> MAXRXDATA_SHIFT)
+
+#define TP_TIMER_RESOLUTION 0x7d90
+#define  TIMERRESOLUTION_MASK   0x00ff0000U
+#define  TIMERRESOLUTION_SHIFT  16
+#define  TIMERRESOLUTION_GET(x) (((x) & TIMERRESOLUTION_MASK) >> TIMERRESOLUTION_SHIFT)
+
+#define TP_SHIFT_CNT 0x7dc0
+
+#define TP_CCTRL_TABLE 0x7ddc
+#define TP_MTU_TABLE 0x7de4
+#define  MTUINDEX_MASK   0xff000000U
+#define  MTUINDEX_SHIFT  24
+#define  MTUINDEX(x)     ((x) << MTUINDEX_SHIFT)
+#define  MTUWIDTH_MASK   0x000f0000U
+#define  MTUWIDTH_SHIFT  16
+#define  MTUWIDTH(x)     ((x) << MTUWIDTH_SHIFT)
+#define  MTUWIDTH_GET(x) (((x) & MTUWIDTH_MASK) >> MTUWIDTH_SHIFT)
+#define  MTUVALUE_MASK   0x00003fffU
+#define  MTUVALUE_SHIFT  0
+#define  MTUVALUE(x)     ((x) << MTUVALUE_SHIFT)
+#define  MTUVALUE_GET(x) (((x) & MTUVALUE_MASK) >> MTUVALUE_SHIFT)
+
+#define TP_RSS_LKP_TABLE 0x7dec
+#define  LKPTBLROWVLD        0x80000000U
+#define  LKPTBLQUEUE1_MASK   0x000ffc00U
+#define  LKPTBLQUEUE1_SHIFT  10
+#define  LKPTBLQUEUE1(x)     ((x) << LKPTBLQUEUE1_SHIFT)
+#define  LKPTBLQUEUE1_GET(x) (((x) & LKPTBLQUEUE1_MASK) >> LKPTBLQUEUE1_SHIFT)
+#define  LKPTBLQUEUE0_MASK   0x000003ffU
+#define  LKPTBLQUEUE0_SHIFT  0
+#define  LKPTBLQUEUE0(x)     ((x) << LKPTBLQUEUE0_SHIFT)
+#define  LKPTBLQUEUE0_GET(x) (((x) & LKPTBLQUEUE0_MASK) >> LKPTBLQUEUE0_SHIFT)
+
+#define TP_PIO_ADDR 0x7e40
+#define TP_PIO_DATA 0x7e44
+#define TP_MIB_INDEX 0x7e50
+#define TP_MIB_DATA 0x7e54
+#define TP_INT_CAUSE 0x7e74
+#define  FLMTXFLSTEMPTY 0x40000000U
+
+#define TP_INGRESS_CONFIG 0x141
+#define  VNIC                0x00000800U
+#define  CSUM_HAS_PSEUDO_HDR 0x00000400U
+#define  RM_OVLAN            0x00000200U
+#define  LOOKUPEVERYPKT      0x00000100U
+
+#define TP_MIB_MAC_IN_ERR_0 0x0
+#define TP_MIB_TCP_OUT_RST 0xc
+#define TP_MIB_TCP_IN_SEG_HI 0x10
+#define TP_MIB_TCP_IN_SEG_LO 0x11
+#define TP_MIB_TCP_OUT_SEG_HI 0x12
+#define TP_MIB_TCP_OUT_SEG_LO 0x13
+#define TP_MIB_TCP_RXT_SEG_HI 0x14
+#define TP_MIB_TCP_RXT_SEG_LO 0x15
+#define TP_MIB_TNL_CNG_DROP_0 0x18
+#define TP_MIB_TCP_V6IN_ERR_0 0x28
+#define TP_MIB_TCP_V6OUT_RST 0x2c
+#define TP_MIB_OFD_ARP_DROP 0x36
+#define TP_MIB_TNL_DROP_0 0x44
+#define TP_MIB_OFD_VLN_DROP_0 0x58
+
+#define ULP_TX_INT_CAUSE 0x8dcc
+#define  PBL_BOUND_ERR_CH3 0x80000000U
+#define  PBL_BOUND_ERR_CH2 0x40000000U
+#define  PBL_BOUND_ERR_CH1 0x20000000U
+#define  PBL_BOUND_ERR_CH0 0x10000000U
+
+#define PM_RX_INT_CAUSE 0x8fdc
+#define  ZERO_E_CMD_ERROR     0x00400000U
+#define  PMRX_FRAMING_ERROR   0x003ffff0U
+#define  OCSPI_PAR_ERROR      0x00000008U
+#define  DB_OPTIONS_PAR_ERROR 0x00000004U
+#define  IESPI_PAR_ERROR      0x00000002U
+#define  E_PCMD_PAR_ERROR     0x00000001U
+
+#define PM_TX_INT_CAUSE 0x8ffc
+#define  PCMD_LEN_OVFL0     0x80000000U
+#define  PCMD_LEN_OVFL1     0x40000000U
+#define  PCMD_LEN_OVFL2     0x20000000U
+#define  ZERO_C_CMD_ERROR   0x10000000U
+#define  PMTX_FRAMING_ERROR 0x0ffffff0U
+#define  OESPI_PAR_ERROR    0x00000008U
+#define  ICSPI_PAR_ERROR    0x00000002U
+#define  C_PCMD_PAR_ERROR   0x00000001U
+
+#define MPS_PORT_STAT_TX_PORT_BYTES_L 0x400
+#define MPS_PORT_STAT_TX_PORT_BYTES_H 0x404
+#define MPS_PORT_STAT_TX_PORT_FRAMES_L 0x408
+#define MPS_PORT_STAT_TX_PORT_FRAMES_H 0x40c
+#define MPS_PORT_STAT_TX_PORT_BCAST_L 0x410
+#define MPS_PORT_STAT_TX_PORT_BCAST_H 0x414
+#define MPS_PORT_STAT_TX_PORT_MCAST_L 0x418
+#define MPS_PORT_STAT_TX_PORT_MCAST_H 0x41c
+#define MPS_PORT_STAT_TX_PORT_UCAST_L 0x420
+#define MPS_PORT_STAT_TX_PORT_UCAST_H 0x424
+#define MPS_PORT_STAT_TX_PORT_ERROR_L 0x428
+#define MPS_PORT_STAT_TX_PORT_ERROR_H 0x42c
+#define MPS_PORT_STAT_TX_PORT_64B_L 0x430
+#define MPS_PORT_STAT_TX_PORT_64B_H 0x434
+#define MPS_PORT_STAT_TX_PORT_65B_127B_L 0x438
+#define MPS_PORT_STAT_TX_PORT_65B_127B_H 0x43c
+#define MPS_PORT_STAT_TX_PORT_128B_255B_L 0x440
+#define MPS_PORT_STAT_TX_PORT_128B_255B_H 0x444
+#define MPS_PORT_STAT_TX_PORT_256B_511B_L 0x448
+#define MPS_PORT_STAT_TX_PORT_256B_511B_H 0x44c
+#define MPS_PORT_STAT_TX_PORT_512B_1023B_L 0x450
+#define MPS_PORT_STAT_TX_PORT_512B_1023B_H 0x454
+#define MPS_PORT_STAT_TX_PORT_1024B_1518B_L 0x458
+#define MPS_PORT_STAT_TX_PORT_1024B_1518B_H 0x45c
+#define MPS_PORT_STAT_TX_PORT_1519B_MAX_L 0x460
+#define MPS_PORT_STAT_TX_PORT_1519B_MAX_H 0x464
+#define MPS_PORT_STAT_TX_PORT_DROP_L 0x468
+#define MPS_PORT_STAT_TX_PORT_DROP_H 0x46c
+#define MPS_PORT_STAT_TX_PORT_PAUSE_L 0x470
+#define MPS_PORT_STAT_TX_PORT_PAUSE_H 0x474
+#define MPS_PORT_STAT_TX_PORT_PPP0_L 0x478
+#define MPS_PORT_STAT_TX_PORT_PPP0_H 0x47c
+#define MPS_PORT_STAT_TX_PORT_PPP1_L 0x480
+#define MPS_PORT_STAT_TX_PORT_PPP1_H 0x484
+#define MPS_PORT_STAT_TX_PORT_PPP2_L 0x488
+#define MPS_PORT_STAT_TX_PORT_PPP2_H 0x48c
+#define MPS_PORT_STAT_TX_PORT_PPP3_L 0x490
+#define MPS_PORT_STAT_TX_PORT_PPP3_H 0x494
+#define MPS_PORT_STAT_TX_PORT_PPP4_L 0x498
+#define MPS_PORT_STAT_TX_PORT_PPP4_H 0x49c
+#define MPS_PORT_STAT_TX_PORT_PPP5_L 0x4a0
+#define MPS_PORT_STAT_TX_PORT_PPP5_H 0x4a4
+#define MPS_PORT_STAT_TX_PORT_PPP6_L 0x4a8
+#define MPS_PORT_STAT_TX_PORT_PPP6_H 0x4ac
+#define MPS_PORT_STAT_TX_PORT_PPP7_L 0x4b0
+#define MPS_PORT_STAT_TX_PORT_PPP7_H 0x4b4
+#define MPS_PORT_STAT_LB_PORT_BYTES_L 0x4c0
+#define MPS_PORT_STAT_LB_PORT_BYTES_H 0x4c4
+#define MPS_PORT_STAT_LB_PORT_FRAMES_L 0x4c8
+#define MPS_PORT_STAT_LB_PORT_FRAMES_H 0x4cc
+#define MPS_PORT_STAT_LB_PORT_BCAST_L 0x4d0
+#define MPS_PORT_STAT_LB_PORT_BCAST_H 0x4d4
+#define MPS_PORT_STAT_LB_PORT_MCAST_L 0x4d8
+#define MPS_PORT_STAT_LB_PORT_MCAST_H 0x4dc
+#define MPS_PORT_STAT_LB_PORT_UCAST_L 0x4e0
+#define MPS_PORT_STAT_LB_PORT_UCAST_H 0x4e4
+#define MPS_PORT_STAT_LB_PORT_ERROR_L 0x4e8
+#define MPS_PORT_STAT_LB_PORT_ERROR_H 0x4ec
+#define MPS_PORT_STAT_LB_PORT_64B_L 0x4f0
+#define MPS_PORT_STAT_LB_PORT_64B_H 0x4f4
+#define MPS_PORT_STAT_LB_PORT_65B_127B_L 0x4f8
+#define MPS_PORT_STAT_LB_PORT_65B_127B_H 0x4fc
+#define MPS_PORT_STAT_LB_PORT_128B_255B_L 0x500
+#define MPS_PORT_STAT_LB_PORT_128B_255B_H 0x504
+#define MPS_PORT_STAT_LB_PORT_256B_511B_L 0x508
+#define MPS_PORT_STAT_LB_PORT_256B_511B_H 0x50c
+#define MPS_PORT_STAT_LB_PORT_512B_1023B_L 0x510
+#define MPS_PORT_STAT_LB_PORT_512B_1023B_H 0x514
+#define MPS_PORT_STAT_LB_PORT_1024B_1518B_L 0x518
+#define MPS_PORT_STAT_LB_PORT_1024B_1518B_H 0x51c
+#define MPS_PORT_STAT_LB_PORT_1519B_MAX_L 0x520
+#define MPS_PORT_STAT_LB_PORT_1519B_MAX_H 0x524
+#define MPS_PORT_STAT_LB_PORT_DROP_FRAMES 0x528
+#define MPS_PORT_STAT_RX_PORT_BYTES_L 0x540
+#define MPS_PORT_STAT_RX_PORT_BYTES_H 0x544
+#define MPS_PORT_STAT_RX_PORT_FRAMES_L 0x548
+#define MPS_PORT_STAT_RX_PORT_FRAMES_H 0x54c
+#define MPS_PORT_STAT_RX_PORT_BCAST_L 0x550
+#define MPS_PORT_STAT_RX_PORT_BCAST_H 0x554
+#define MPS_PORT_STAT_RX_PORT_MCAST_L 0x558
+#define MPS_PORT_STAT_RX_PORT_MCAST_H 0x55c
+#define MPS_PORT_STAT_RX_PORT_UCAST_L 0x560
+#define MPS_PORT_STAT_RX_PORT_UCAST_H 0x564
+#define MPS_PORT_STAT_RX_PORT_MTU_ERROR_L 0x568
+#define MPS_PORT_STAT_RX_PORT_MTU_ERROR_H 0x56c
+#define MPS_PORT_STAT_RX_PORT_MTU_CRC_ERROR_L 0x570
+#define MPS_PORT_STAT_RX_PORT_MTU_CRC_ERROR_H 0x574
+#define MPS_PORT_STAT_RX_PORT_CRC_ERROR_L 0x578
+#define MPS_PORT_STAT_RX_PORT_CRC_ERROR_H 0x57c
+#define MPS_PORT_STAT_RX_PORT_LEN_ERROR_L 0x580
+#define MPS_PORT_STAT_RX_PORT_LEN_ERROR_H 0x584
+#define MPS_PORT_STAT_RX_PORT_SYM_ERROR_L 0x588
+#define MPS_PORT_STAT_RX_PORT_SYM_ERROR_H 0x58c
+#define MPS_PORT_STAT_RX_PORT_64B_L 0x590
+#define MPS_PORT_STAT_RX_PORT_64B_H 0x594
+#define MPS_PORT_STAT_RX_PORT_65B_127B_L 0x598
+#define MPS_PORT_STAT_RX_PORT_65B_127B_H 0x59c
+#define MPS_PORT_STAT_RX_PORT_128B_255B_L 0x5a0
+#define MPS_PORT_STAT_RX_PORT_128B_255B_H 0x5a4
+#define MPS_PORT_STAT_RX_PORT_256B_511B_L 0x5a8
+#define MPS_PORT_STAT_RX_PORT_256B_511B_H 0x5ac
+#define MPS_PORT_STAT_RX_PORT_512B_1023B_L 0x5b0
+#define MPS_PORT_STAT_RX_PORT_512B_1023B_H 0x5b4
+#define MPS_PORT_STAT_RX_PORT_1024B_1518B_L 0x5b8
+#define MPS_PORT_STAT_RX_PORT_1024B_1518B_H 0x5bc
+#define MPS_PORT_STAT_RX_PORT_1519B_MAX_L 0x5c0
+#define MPS_PORT_STAT_RX_PORT_1519B_MAX_H 0x5c4
+#define MPS_PORT_STAT_RX_PORT_PAUSE_L 0x5c8
+#define MPS_PORT_STAT_RX_PORT_PAUSE_H 0x5cc
+#define MPS_PORT_STAT_RX_PORT_PPP0_L 0x5d0
+#define MPS_PORT_STAT_RX_PORT_PPP0_H 0x5d4
+#define MPS_PORT_STAT_RX_PORT_PPP1_L 0x5d8
+#define MPS_PORT_STAT_RX_PORT_PPP1_H 0x5dc
+#define MPS_PORT_STAT_RX_PORT_PPP2_L 0x5e0
+#define MPS_PORT_STAT_RX_PORT_PPP2_H 0x5e4
+#define MPS_PORT_STAT_RX_PORT_PPP3_L 0x5e8
+#define MPS_PORT_STAT_RX_PORT_PPP3_H 0x5ec
+#define MPS_PORT_STAT_RX_PORT_PPP4_L 0x5f0
+#define MPS_PORT_STAT_RX_PORT_PPP4_H 0x5f4
+#define MPS_PORT_STAT_RX_PORT_PPP5_L 0x5f8
+#define MPS_PORT_STAT_RX_PORT_PPP5_H 0x5fc
+#define MPS_PORT_STAT_RX_PORT_PPP6_L 0x600
+#define MPS_PORT_STAT_RX_PORT_PPP6_H 0x604
+#define MPS_PORT_STAT_RX_PORT_PPP7_L 0x608
+#define MPS_PORT_STAT_RX_PORT_PPP7_H 0x60c
+#define MPS_PORT_STAT_RX_PORT_LESS_64B_L 0x610
+#define MPS_PORT_STAT_RX_PORT_LESS_64B_H 0x614
+#define MPS_CMN_CTL 0x9000
+#define  NUMPORTS_MASK   0x00000003U
+#define  NUMPORTS_SHIFT  0
+#define  NUMPORTS_GET(x) (((x) & NUMPORTS_MASK) >> NUMPORTS_SHIFT)
+
+#define MPS_INT_CAUSE 0x9008
+#define  STATINT 0x00000020U
+#define  TXINT   0x00000010U
+#define  RXINT   0x00000008U
+#define  TRCINT  0x00000004U
+#define  CLSINT  0x00000002U
+#define  PLINT   0x00000001U
+
+#define MPS_TX_INT_CAUSE 0x9408
+#define  PORTERR    0x00010000U
+#define  FRMERR     0x00008000U
+#define  SECNTERR   0x00004000U
+#define  BUBBLE     0x00002000U
+#define  TXDESCFIFO 0x00001e00U
+#define  TXDATAFIFO 0x000001e0U
+#define  NCSIFIFO   0x00000010U
+#define  TPFIFO     0x0000000fU
+
+#define MPS_STAT_PERR_INT_CAUSE_SRAM 0x9614
+#define MPS_STAT_PERR_INT_CAUSE_TX_FIFO 0x9620
+#define MPS_STAT_PERR_INT_CAUSE_RX_FIFO 0x962c
+
+#define MPS_STAT_RX_BG_0_MAC_DROP_FRAME_L 0x9640
+#define MPS_STAT_RX_BG_0_MAC_DROP_FRAME_H 0x9644
+#define MPS_STAT_RX_BG_1_MAC_DROP_FRAME_L 0x9648
+#define MPS_STAT_RX_BG_1_MAC_DROP_FRAME_H 0x964c
+#define MPS_STAT_RX_BG_2_MAC_DROP_FRAME_L 0x9650
+#define MPS_STAT_RX_BG_2_MAC_DROP_FRAME_H 0x9654
+#define MPS_STAT_RX_BG_3_MAC_DROP_FRAME_L 0x9658
+#define MPS_STAT_RX_BG_3_MAC_DROP_FRAME_H 0x965c
+#define MPS_STAT_RX_BG_0_LB_DROP_FRAME_L 0x9660
+#define MPS_STAT_RX_BG_0_LB_DROP_FRAME_H 0x9664
+#define MPS_STAT_RX_BG_1_LB_DROP_FRAME_L 0x9668
+#define MPS_STAT_RX_BG_1_LB_DROP_FRAME_H 0x966c
+#define MPS_STAT_RX_BG_2_LB_DROP_FRAME_L 0x9670
+#define MPS_STAT_RX_BG_2_LB_DROP_FRAME_H 0x9674
+#define MPS_STAT_RX_BG_3_LB_DROP_FRAME_L 0x9678
+#define MPS_STAT_RX_BG_3_LB_DROP_FRAME_H 0x967c
+#define MPS_STAT_RX_BG_0_MAC_TRUNC_FRAME_L 0x9680
+#define MPS_STAT_RX_BG_0_MAC_TRUNC_FRAME_H 0x9684
+#define MPS_STAT_RX_BG_1_MAC_TRUNC_FRAME_L 0x9688
+#define MPS_STAT_RX_BG_1_MAC_TRUNC_FRAME_H 0x968c
+#define MPS_STAT_RX_BG_2_MAC_TRUNC_FRAME_L 0x9690
+#define MPS_STAT_RX_BG_2_MAC_TRUNC_FRAME_H 0x9694
+#define MPS_STAT_RX_BG_3_MAC_TRUNC_FRAME_L 0x9698
+#define MPS_STAT_RX_BG_3_MAC_TRUNC_FRAME_H 0x969c
+#define MPS_STAT_RX_BG_0_LB_TRUNC_FRAME_L 0x96a0
+#define MPS_STAT_RX_BG_0_LB_TRUNC_FRAME_H 0x96a4
+#define MPS_STAT_RX_BG_1_LB_TRUNC_FRAME_L 0x96a8
+#define MPS_STAT_RX_BG_1_LB_TRUNC_FRAME_H 0x96ac
+#define MPS_STAT_RX_BG_2_LB_TRUNC_FRAME_L 0x96b0
+#define MPS_STAT_RX_BG_2_LB_TRUNC_FRAME_H 0x96b4
+#define MPS_STAT_RX_BG_3_LB_TRUNC_FRAME_L 0x96b8
+#define MPS_STAT_RX_BG_3_LB_TRUNC_FRAME_H 0x96bc
+#define MPS_TRC_CFG 0x9800
+#define  TRCFIFOEMPTY       0x00000010U
+#define  TRCIGNOREDROPINPUT 0x00000008U
+#define  TRCKEEPDUPLICATES  0x00000004U
+#define  TRCEN              0x00000002U
+#define  TRCMULTIFILTER     0x00000001U
+
+#define MPS_TRC_RSS_CONTROL 0x9808
+#define  RSSCONTROL_MASK    0x00ff0000U
+#define  RSSCONTROL_SHIFT   16
+#define  RSSCONTROL(x)      ((x) << RSSCONTROL_SHIFT)
+#define  QUEUENUMBER_MASK   0x0000ffffU
+#define  QUEUENUMBER_SHIFT  0
+#define  QUEUENUMBER(x)     ((x) << QUEUENUMBER_SHIFT)
+
+#define MPS_TRC_FILTER_MATCH_CTL_A 0x9810
+#define  TFINVERTMATCH   0x01000000U
+#define  TFPKTTOOLARGE   0x00800000U
+#define  TFEN            0x00400000U
+#define  TFPORT_MASK     0x003c0000U
+#define  TFPORT_SHIFT    18
+#define  TFPORT(x)       ((x) << TFPORT_SHIFT)
+#define  TFPORT_GET(x)   (((x) & TFPORT_MASK) >> TFPORT_SHIFT)
+#define  TFDROP          0x00020000U
+#define  TFSOPEOPERR     0x00010000U
+#define  TFLENGTH_MASK   0x00001f00U
+#define  TFLENGTH_SHIFT  8
+#define  TFLENGTH(x)     ((x) << TFLENGTH_SHIFT)
+#define  TFLENGTH_GET(x) (((x) & TFLENGTH_MASK) >> TFLENGTH_SHIFT)
+#define  TFOFFSET_MASK   0x0000001fU
+#define  TFOFFSET_SHIFT  0
+#define  TFOFFSET(x)     ((x) << TFOFFSET_SHIFT)
+#define  TFOFFSET_GET(x) (((x) & TFOFFSET_MASK) >> TFOFFSET_SHIFT)
+
+#define MPS_TRC_FILTER_MATCH_CTL_B 0x9820
+#define  TFMINPKTSIZE_MASK   0x01ff0000U
+#define  TFMINPKTSIZE_SHIFT  16
+#define  TFMINPKTSIZE(x)     ((x) << TFMINPKTSIZE_SHIFT)
+#define  TFMINPKTSIZE_GET(x) (((x) & TFMINPKTSIZE_MASK) >> TFMINPKTSIZE_SHIFT)
+#define  TFCAPTUREMAX_MASK   0x00003fffU
+#define  TFCAPTUREMAX_SHIFT  0
+#define  TFCAPTUREMAX(x)     ((x) << TFCAPTUREMAX_SHIFT)
+#define  TFCAPTUREMAX_GET(x) (((x) & TFCAPTUREMAX_MASK) >> TFCAPTUREMAX_SHIFT)
+
+#define MPS_TRC_INT_CAUSE 0x985c
+#define  MISCPERR 0x00000100U
+#define  PKTFIFO  0x000000f0U
+#define  FILTMEM  0x0000000fU
+
+#define MPS_TRC_FILTER0_MATCH 0x9c00
+#define MPS_TRC_FILTER0_DONT_CARE 0x9c80
+#define MPS_TRC_FILTER1_MATCH 0x9d00
+#define MPS_CLS_INT_CAUSE 0xd028
+#define  PLERRENB  0x00000008U
+#define  HASHSRAM  0x00000004U
+#define  MATCHTCAM 0x00000002U
+#define  MATCHSRAM 0x00000001U
+
+#define MPS_RX_PERR_INT_CAUSE 0x11074
+
+#define CPL_INTR_CAUSE 0x19054
+#define  CIM_OP_MAP_PERR   0x00000020U
+#define  CIM_OVFL_ERROR    0x00000010U
+#define  TP_FRAMING_ERROR  0x00000008U
+#define  SGE_FRAMING_ERROR 0x00000004U
+#define  CIM_FRAMING_ERROR 0x00000002U
+#define  ZERO_SWITCH_ERROR 0x00000001U
+
+#define SMB_INT_CAUSE 0x19090
+#define  MSTTXFIFOPARINT 0x00200000U
+#define  MSTRXFIFOPARINT 0x00100000U
+#define  SLVFIFOPARINT   0x00080000U
+
+#define ULP_RX_INT_CAUSE 0x19158
+#define ULP_RX_ISCSI_TAGMASK 0x19164
+#define ULP_RX_ISCSI_PSZ 0x19168
+#define  HPZ3_MASK   0x0f000000U
+#define  HPZ3_SHIFT  24
+#define  HPZ3(x)     ((x) << HPZ3_SHIFT)
+#define  HPZ2_MASK   0x000f0000U
+#define  HPZ2_SHIFT  16
+#define  HPZ2(x)     ((x) << HPZ2_SHIFT)
+#define  HPZ1_MASK   0x00000f00U
+#define  HPZ1_SHIFT  8
+#define  HPZ1(x)     ((x) << HPZ1_SHIFT)
+#define  HPZ0_MASK   0x0000000fU
+#define  HPZ0_SHIFT  0
+#define  HPZ0(x)     ((x) << HPZ0_SHIFT)
+
+#define ULP_RX_TDDP_PSZ 0x19178
+
+#define SF_DATA 0x193f8
+#define SF_OP 0x193fc
+#define  BUSY          0x80000000U
+#define  SF_LOCK       0x00000010U
+#define  SF_CONT       0x00000008U
+#define  BYTECNT_MASK  0x00000006U
+#define  BYTECNT_SHIFT 1
+#define  BYTECNT(x)    ((x) << BYTECNT_SHIFT)
+#define  OP_WR         0x00000001U
+
+#define PL_PF_INT_CAUSE 0x3c0
+#define  PFSW  0x00000008U
+#define  PFSGE 0x00000004U
+#define  PFCIM 0x00000002U
+#define  PFMPS 0x00000001U
+
+#define PL_PF_INT_ENABLE 0x3c4
+#define PL_PF_CTL 0x3c8
+#define  SWINT 0x00000001U
+
+#define PL_WHOAMI 0x19400
+#define  SOURCEPF_MASK   0x00000700U
+#define  SOURCEPF_SHIFT  8
+#define  SOURCEPF(x)     ((x) << SOURCEPF_SHIFT)
+#define  SOURCEPF_GET(x) (((x) & SOURCEPF_MASK) >> SOURCEPF_SHIFT)
+#define  ISVF            0x00000080U
+#define  VFID_MASK       0x0000007fU
+#define  VFID_SHIFT      0
+#define  VFID(x)         ((x) << VFID_SHIFT)
+#define  VFID_GET(x)     (((x) & VFID_MASK) >> VFID_SHIFT)
+
+#define PL_INT_CAUSE 0x1940c
+#define  ULP_TX     0x08000000U
+#define  SGE        0x04000000U
+#define  HMA        0x02000000U
+#define  CPL_SWITCH 0x01000000U
+#define  ULP_RX     0x00800000U
+#define  PM_RX      0x00400000U
+#define  PM_TX      0x00200000U
+#define  MA         0x00100000U
+#define  TP         0x00080000U
+#define  LE         0x00040000U
+#define  EDC1       0x00020000U
+#define  EDC0       0x00010000U
+#define  MC         0x00008000U
+#define  PCIE       0x00004000U
+#define  PMU        0x00002000U
+#define  XGMAC_KR1  0x00001000U
+#define  XGMAC_KR0  0x00000800U
+#define  XGMAC1     0x00000400U
+#define  XGMAC0     0x00000200U
+#define  SMB        0x00000100U
+#define  SF         0x00000080U
+#define  PL         0x00000040U
+#define  NCSI       0x00000020U
+#define  MPS        0x00000010U
+#define  MI         0x00000008U
+#define  DBG        0x00000004U
+#define  I2CM       0x00000002U
+#define  CIM        0x00000001U
+
+#define PL_INT_MAP0 0x19414
+#define PL_RST 0x19428
+#define  PIORST     0x00000002U
+#define  PIORSTMODE 0x00000001U
+
+#define PL_PL_INT_CAUSE 0x19430
+#define  FATALPERR 0x00000010U
+#define  PERRVFID  0x00000001U
+
+#define PL_REV 0x1943c
+
+#define LE_DB_CONFIG 0x19c04
+#define  HASHEN 0x00100000U
+
+#define LE_DB_SERVER_INDEX 0x19c18
+#define LE_DB_ACT_CNT_IPV4 0x19c20
+#define LE_DB_ACT_CNT_IPV6 0x19c24
+
+#define LE_DB_INT_CAUSE 0x19c3c
+#define  REQQPARERR 0x00010000U
+#define  UNKNOWNCMD 0x00008000U
+#define  PARITYERR  0x00000040U
+#define  LIPMISS    0x00000020U
+#define  LIP0       0x00000010U
+
+#define LE_DB_TID_HASHBASE 0x19df8
+
+#define NCSI_INT_CAUSE 0x1a0d8
+#define  CIM_DM_PRTY_ERR 0x00000100U
+#define  MPS_DM_PRTY_ERR 0x00000080U
+#define  TXFIFO_PRTY_ERR 0x00000002U
+#define  RXFIFO_PRTY_ERR 0x00000001U
+
+#define XGMAC_PORT_CFG2 0x1018
+#define  PATEN   0x00040000U
+#define  MAGICEN 0x00020000U
+
+#define XGMAC_PORT_MAGIC_MACID_LO 0x1024
+#define XGMAC_PORT_MAGIC_MACID_HI 0x1028
+
+#define XGMAC_PORT_EPIO_DATA0 0x10c0
+#define XGMAC_PORT_EPIO_DATA1 0x10c4
+#define XGMAC_PORT_EPIO_DATA2 0x10c8
+#define XGMAC_PORT_EPIO_DATA3 0x10cc
+#define XGMAC_PORT_EPIO_OP 0x10d0
+#define  EPIOWR         0x00000100U
+#define  ADDRESS_MASK   0x000000ffU
+#define  ADDRESS_SHIFT  0
+#define  ADDRESS(x)     ((x) << ADDRESS_SHIFT)
+
+#define XGMAC_PORT_INT_CAUSE 0x10dc
+#endif /* __T4_REGS_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/davinci_emac.c linux-libre-2.6.34-gnu1/drivers/net/davinci_emac.c
--- linux-libre-2.6.33-gnu1/drivers/net/davinci_emac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/davinci_emac.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,10 +29,6 @@
  *     PHY layer usage
  */
 
-/** Pending Items in this driver:
- * 1. Use Linux cache infrastcture for DMA'ed memory (dma_xxx functions)
- */
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -62,12 +58,11 @@
 #include <linux/bitops.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
+#include <linux/davinci_emac.h>
 
 #include <asm/irq.h>
 #include <asm/page.h>
 
-#include <mach/emac.h>
-
 static int debug_level;
 module_param(debug_level, int, 0);
 MODULE_PARM_DESC(debug_level, "DaVinci EMAC debug level (NETIF_MSG bits)");
@@ -465,6 +460,7 @@ struct emac_priv {
 	void __iomem *ctrl_base;
 	void __iomem *emac_ctrl_ram;
 	u32 ctrl_ram_size;
+	u32 hw_ram_addr;
 	struct emac_txch *txch[EMAC_DEF_MAX_TX_CH];
 	struct emac_rxch *rxch[EMAC_DEF_MAX_RX_CH];
 	u32 link; /* 1=link on, 0=link off */
@@ -488,6 +484,9 @@ struct emac_priv {
 	struct mii_bus *mii_bus;
 	struct phy_device *phydev;
 	spinlock_t lock;
+	/*platform specific members*/
+	void (*int_enable) (void);
+	void (*int_disable) (void);
 };
 
 /* clock frequency for EMAC */
@@ -495,20 +494,12 @@ static struct clk *emac_clk;
 static unsigned long emac_bus_frequency;
 static unsigned long mdio_max_freq;
 
-/* EMAC internal utility function */
-static inline u32 emac_virt_to_phys(void __iomem *addr)
-{
-	return (u32 __force) io_v2p(addr);
-}
+#define emac_virt_to_phys(addr, priv) \
+	(((u32 __force)(addr) - (u32 __force)(priv->emac_ctrl_ram)) \
+	+ priv->hw_ram_addr)
 
 /* Cache macros - Packet buffers would be from skb pool which is cached */
 #define EMAC_VIRT_NOCACHE(addr) (addr)
-#define EMAC_CACHE_INVALIDATE(addr, size) \
-	dma_cache_maint((void *)addr, size, DMA_FROM_DEVICE)
-#define EMAC_CACHE_WRITEBACK(addr, size) \
-	dma_cache_maint((void *)addr, size, DMA_TO_DEVICE)
-#define EMAC_CACHE_WRITEBACK_INVALIDATE(addr, size) \
-	dma_cache_maint((void *)addr, size, DMA_BIDIRECTIONAL)
 
 /* DM644x does not have BD's in cached memory - so no cache functions */
 #define BD_CACHE_INVALIDATE(addr, size)
@@ -956,19 +947,18 @@ static void emac_dev_mcast_set(struct ne
 	} else {
 		mbp_enable = (mbp_enable & ~EMAC_MBP_RXPROMISC);
 		if ((ndev->flags & IFF_ALLMULTI) ||
-		    (ndev->mc_count > EMAC_DEF_MAX_MULTICAST_ADDRESSES)) {
+		    netdev_mc_count(ndev) > EMAC_DEF_MAX_MULTICAST_ADDRESSES) {
 			mbp_enable = (mbp_enable | EMAC_MBP_RXMCAST);
 			emac_add_mcast(priv, EMAC_ALL_MULTI_SET, NULL);
 		}
-		if (ndev->mc_count > 0) {
+		if (!netdev_mc_empty(ndev)) {
 			struct dev_mc_list *mc_ptr;
 			mbp_enable = (mbp_enable | EMAC_MBP_RXMCAST);
 			emac_add_mcast(priv, EMAC_ALL_MULTI_CLR, NULL);
 			/* program multicast address list into EMAC hardware */
-			for (mc_ptr = ndev->mc_list; mc_ptr;
-			     mc_ptr = mc_ptr->next) {
+			netdev_for_each_mc_addr(mc_ptr, ndev) {
 				emac_add_mcast(priv, EMAC_MULTICAST_ADD,
-					       (u8 *)mc_ptr->dmi_addr);
+					       (u8 *) mc_ptr->dmi_addr);
 			}
 		} else {
 			mbp_enable = (mbp_enable & ~EMAC_MBP_RXMCAST);
@@ -1002,6 +992,8 @@ static void emac_int_disable(struct emac
 		emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0x0);
 		emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0x0);
 		/* NOTE: Rx Threshold and Misc interrupts are not disabled */
+		if (priv->int_disable)
+			priv->int_disable();
 
 		local_irq_restore(flags);
 
@@ -1021,6 +1013,9 @@ static void emac_int_disable(struct emac
 static void emac_int_enable(struct emac_priv *priv)
 {
 	if (priv->version == EMAC_VERSION_2) {
+		if (priv->int_enable)
+			priv->int_enable();
+
 		emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0xff);
 		emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0xff);
 
@@ -1230,6 +1225,10 @@ static void emac_txch_teardown(struct em
 	if (1 == txch->queue_active) {
 		curr_bd = txch->active_queue_head;
 		while (curr_bd != NULL) {
+			dma_unmap_single(emac_dev, curr_bd->buff_ptr,
+				curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE,
+				DMA_TO_DEVICE);
+
 			emac_net_tx_complete(priv, (void __force *)
 					&curr_bd->buf_token, 1, ch);
 			if (curr_bd != txch->active_queue_tail)
@@ -1302,7 +1301,7 @@ static int emac_tx_bdproc(struct emac_pr
 	curr_bd = txch->active_queue_head;
 	if (NULL == curr_bd) {
 		emac_write(EMAC_TXCP(ch),
-			   emac_virt_to_phys(txch->last_hw_bdprocessed));
+			   emac_virt_to_phys(txch->last_hw_bdprocessed, priv));
 		txch->no_active_pkts++;
 		spin_unlock_irqrestore(&priv->tx_lock, flags);
 		return 0;
@@ -1312,7 +1311,7 @@ static int emac_tx_bdproc(struct emac_pr
 	while ((curr_bd) &&
 	      ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) &&
 	      (pkts_processed < budget)) {
-		emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd));
+		emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd, priv));
 		txch->active_queue_head = curr_bd->next;
 		if (frame_status & EMAC_CPPI_EOQ_BIT) {
 			if (curr_bd->next) {	/* misqueued packet */
@@ -1322,6 +1321,11 @@ static int emac_tx_bdproc(struct emac_pr
 				txch->queue_active = 0; /* end of queue */
 			}
 		}
+
+		dma_unmap_single(emac_dev, curr_bd->buff_ptr,
+				curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE,
+				DMA_TO_DEVICE);
+
 		*tx_complete_ptr = (u32) curr_bd->buf_token;
 		++tx_complete_ptr;
 		++tx_complete_cnt;
@@ -1382,8 +1386,8 @@ static int emac_send(struct emac_priv *p
 
 	txch->bd_pool_head = curr_bd->next;
 	curr_bd->buf_token = buf_list->buf_token;
-	/* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
-	curr_bd->buff_ptr = virt_to_phys(buf_list->data_ptr);
+	curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buf_list->data_ptr,
+			buf_list->length, DMA_TO_DEVICE);
 	curr_bd->off_b_len = buf_list->length;
 	curr_bd->h_next = 0;
 	curr_bd->next = NULL;
@@ -1399,7 +1403,7 @@ static int emac_send(struct emac_priv *p
 		txch->active_queue_tail = curr_bd;
 		if (1 != txch->queue_active) {
 			emac_write(EMAC_TXHDP(ch),
-					emac_virt_to_phys(curr_bd));
+					emac_virt_to_phys(curr_bd, priv));
 			txch->queue_active = 1;
 		}
 		++txch->queue_reinit;
@@ -1411,10 +1415,11 @@ static int emac_send(struct emac_priv *p
 		tail_bd->next = curr_bd;
 		txch->active_queue_tail = curr_bd;
 		tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
-		tail_bd->h_next = (int)emac_virt_to_phys(curr_bd);
+		tail_bd->h_next = (int)emac_virt_to_phys(curr_bd, priv);
 		frame_status = tail_bd->mode;
 		if (frame_status & EMAC_CPPI_EOQ_BIT) {
-			emac_write(EMAC_TXHDP(ch), emac_virt_to_phys(curr_bd));
+			emac_write(EMAC_TXHDP(ch),
+				emac_virt_to_phys(curr_bd, priv));
 			frame_status &= ~(EMAC_CPPI_EOQ_BIT);
 			tail_bd->mode = frame_status;
 			++txch->end_of_queue_add;
@@ -1462,7 +1467,6 @@ static int emac_dev_xmit(struct sk_buff
 	tx_buf.length = skb->len;
 	tx_buf.buf_token = (void *)skb;
 	tx_buf.data_ptr = skb->data;
-	EMAC_CACHE_WRITEBACK((unsigned long)skb->data, skb->len);
 	ndev->trans_start = jiffies;
 	ret_code = emac_send(priv, &tx_packet, EMAC_DEF_TX_CH);
 	if (unlikely(ret_code != 0)) {
@@ -1537,7 +1541,6 @@ static void *emac_net_alloc_rx_buf(struc
 	p_skb->dev = ndev;
 	skb_reserve(p_skb, NET_IP_ALIGN);
 	*data_token = (void *) p_skb;
-	EMAC_CACHE_WRITEBACK_INVALIDATE((unsigned long)p_skb->data, buf_size);
 	return p_skb->data;
 }
 
@@ -1604,9 +1607,10 @@ static int emac_init_rxch(struct emac_pr
 		}
 
 		/* populate the hardware descriptor */
-		curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head);
-		/* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
-		curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr);
+		curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head,
+				priv);
+		curr_bd->buff_ptr = dma_map_single(emac_dev, curr_bd->data_ptr,
+				rxch->buf_size, DMA_FROM_DEVICE);
 		curr_bd->off_b_len = rxch->buf_size;
 		curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
 
@@ -1690,6 +1694,12 @@ static void emac_cleanup_rxch(struct ema
 		curr_bd = rxch->active_queue_head;
 		while (curr_bd) {
 			if (curr_bd->buf_token) {
+				dma_unmap_single(&priv->ndev->dev,
+					curr_bd->buff_ptr,
+					curr_bd->off_b_len
+						& EMAC_RX_BD_BUF_SIZE,
+					DMA_FROM_DEVICE);
+
 				dev_kfree_skb_any((struct sk_buff *)\
 						  curr_bd->buf_token);
 			}
@@ -1864,8 +1874,8 @@ static void emac_addbd_to_rx_queue(struc
 
 	/* populate the hardware descriptor */
 	curr_bd->h_next = 0;
-	/* FIXME buff_ptr = dma_map_single(... buffer ...) */
-	curr_bd->buff_ptr = virt_to_phys(buffer);
+	curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buffer,
+				rxch->buf_size, DMA_FROM_DEVICE);
 	curr_bd->off_b_len = rxch->buf_size;
 	curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
 	curr_bd->next = NULL;
@@ -1879,7 +1889,7 @@ static void emac_addbd_to_rx_queue(struc
 		rxch->active_queue_tail = curr_bd;
 		if (0 != rxch->queue_active) {
 			emac_write(EMAC_RXHDP(ch),
-				   emac_virt_to_phys(rxch->active_queue_head));
+			   emac_virt_to_phys(rxch->active_queue_head, priv));
 			rxch->queue_active = 1;
 		}
 	} else {
@@ -1890,11 +1900,11 @@ static void emac_addbd_to_rx_queue(struc
 		rxch->active_queue_tail = curr_bd;
 		tail_bd->next = curr_bd;
 		tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
-		tail_bd->h_next = emac_virt_to_phys(curr_bd);
+		tail_bd->h_next = emac_virt_to_phys(curr_bd, priv);
 		frame_status = tail_bd->mode;
 		if (frame_status & EMAC_CPPI_EOQ_BIT) {
 			emac_write(EMAC_RXHDP(ch),
-					emac_virt_to_phys(curr_bd));
+					emac_virt_to_phys(curr_bd, priv));
 			frame_status &= ~(EMAC_CPPI_EOQ_BIT);
 			tail_bd->mode = frame_status;
 			++rxch->end_of_queue_add;
@@ -1920,7 +1930,6 @@ static int emac_net_rx_cb(struct emac_pr
 	p_skb = (struct sk_buff *)net_pkt_list->pkt_token;
 	/* set length of packet */
 	skb_put(p_skb, net_pkt_list->pkt_length);
-	EMAC_CACHE_INVALIDATE((unsigned long)p_skb->data, p_skb->len);
 	p_skb->protocol = eth_type_trans(p_skb, priv->ndev);
 	netif_receive_skb(p_skb);
 	priv->net_dev_stats.rx_bytes += net_pkt_list->pkt_length;
@@ -1983,11 +1992,16 @@ static int emac_rx_bdproc(struct emac_pr
 		rx_buf_obj->data_ptr = (char *)curr_bd->data_ptr;
 		rx_buf_obj->length = curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE;
 		rx_buf_obj->buf_token = curr_bd->buf_token;
+
+		dma_unmap_single(&priv->ndev->dev, curr_bd->buff_ptr,
+				curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE,
+				DMA_FROM_DEVICE);
+
 		curr_pkt->pkt_token = curr_pkt->buf_list->buf_token;
 		curr_pkt->num_bufs = 1;
 		curr_pkt->pkt_length =
 			(frame_status & EMAC_RX_BD_PKT_LENGTH_MASK);
-		emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd));
+		emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd, priv));
 		++rxch->processed_bd;
 		last_bd = curr_bd;
 		curr_bd = last_bd->next;
@@ -1998,7 +2012,7 @@ static int emac_rx_bdproc(struct emac_pr
 			if (curr_bd) {
 				++rxch->mis_queued_packets;
 				emac_write(EMAC_RXHDP(ch),
-					   emac_virt_to_phys(curr_bd));
+					   emac_virt_to_phys(curr_bd, priv));
 			} else {
 				++rxch->end_of_queue;
 				rxch->queue_active = 0;
@@ -2099,7 +2113,7 @@ static int emac_hw_enable(struct emac_pr
 		emac_write(EMAC_RXINTMASKSET, BIT(ch));
 		rxch->queue_active = 1;
 		emac_write(EMAC_RXHDP(ch),
-			   emac_virt_to_phys(rxch->active_queue_head));
+			   emac_virt_to_phys(rxch->active_queue_head, priv));
 	}
 
 	/* Enable MII */
@@ -2378,7 +2392,7 @@ static int emac_dev_open(struct net_devi
 	struct emac_priv *priv = netdev_priv(ndev);
 
 	netif_carrier_off(ndev);
-	for (cnt = 0; cnt <= ETH_ALEN; cnt++)
+	for (cnt = 0; cnt < ETH_ALEN; cnt++)
 		ndev->dev_addr[cnt] = priv->mac_addr[cnt];
 
 	/* Configuration items */
@@ -2651,7 +2665,7 @@ static int __devinit davinci_emac_probe(
 
 	pdata = pdev->dev.platform_data;
 	if (!pdata) {
-		printk(KERN_ERR "DaVinci EMAC: No platfrom data\n");
+		printk(KERN_ERR "DaVinci EMAC: No platform data\n");
 		return -ENODEV;
 	}
 
@@ -2660,6 +2674,9 @@ static int __devinit davinci_emac_probe(
 	priv->phy_mask = pdata->phy_mask;
 	priv->rmii_en = pdata->rmii_en;
 	priv->version = pdata->version;
+	priv->int_enable = pdata->interrupt_enable;
+	priv->int_disable = pdata->interrupt_disable;
+
 	emac_dev = &ndev->dev;
 	/* Get EMAC platform data */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -2672,8 +2689,7 @@ static int __devinit davinci_emac_probe(
 	priv->emac_base_phys = res->start + pdata->ctrl_reg_offset;
 	size = res->end - res->start + 1;
 	if (!request_mem_region(res->start, size, ndev->name)) {
-		dev_err(emac_dev, "DaVinci EMAC: failed request_mem_region() \
-					 for regs\n");
+		dev_err(emac_dev, "DaVinci EMAC: failed request_mem_region() for regs\n");
 		rc = -ENXIO;
 		goto probe_quit;
 	}
@@ -2692,6 +2708,12 @@ static int __devinit davinci_emac_probe(
 	priv->ctrl_ram_size = pdata->ctrl_ram_size;
 	priv->emac_ctrl_ram = priv->remap_addr + pdata->ctrl_ram_offset;
 
+	if (pdata->hw_ram_addr)
+		priv->hw_ram_addr = pdata->hw_ram_addr;
+	else
+		priv->hw_ram_addr = (u32 __force)res->start +
+					pdata->ctrl_ram_offset;
+
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!res) {
 		dev_err(emac_dev, "DaVinci EMAC: Error getting irq res\n");
@@ -2805,31 +2827,37 @@ static int __devexit davinci_emac_remove
 	return 0;
 }
 
-static
-int davinci_emac_suspend(struct platform_device *pdev, pm_message_t state)
+static int davinci_emac_suspend(struct device *dev)
 {
-	struct net_device *dev = platform_get_drvdata(pdev);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct net_device *ndev = platform_get_drvdata(pdev);
 
-	if (netif_running(dev))
-		emac_dev_stop(dev);
+	if (netif_running(ndev))
+		emac_dev_stop(ndev);
 
 	clk_disable(emac_clk);
 
 	return 0;
 }
 
-static int davinci_emac_resume(struct platform_device *pdev)
+static int davinci_emac_resume(struct device *dev)
 {
-	struct net_device *dev = platform_get_drvdata(pdev);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct net_device *ndev = platform_get_drvdata(pdev);
 
 	clk_enable(emac_clk);
 
-	if (netif_running(dev))
-		emac_dev_open(dev);
+	if (netif_running(ndev))
+		emac_dev_open(ndev);
 
 	return 0;
 }
 
+static const struct dev_pm_ops davinci_emac_pm_ops = {
+	.suspend	= davinci_emac_suspend,
+	.resume		= davinci_emac_resume,
+};
+
 /**
  * davinci_emac_driver: EMAC platform driver structure
  */
@@ -2837,11 +2865,10 @@ static struct platform_driver davinci_em
 	.driver = {
 		.name	 = "davinci_emac",
 		.owner	 = THIS_MODULE,
+		.pm	 = &davinci_emac_pm_ops,
 	},
 	.probe = davinci_emac_probe,
 	.remove = __devexit_p(davinci_emac_remove),
-	.suspend = davinci_emac_suspend,
-	.resume = davinci_emac_resume,
 };
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/de620.c linux-libre-2.6.34-gnu1/drivers/net/de620.c
--- linux-libre-2.6.33-gnu1/drivers/net/de620.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/de620.c	2010-05-16 17:17:36.000000000 -0400
@@ -464,7 +464,7 @@ static int de620_close(struct net_device
 
 static void de620_set_multicast_list(struct net_device *dev)
 {
-	if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
+	if (!netdev_mc_empty(dev) || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
 	{ /* Enable promiscuous mode */
 		de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/declance.c linux-libre-2.6.34-gnu1/drivers/net/declance.c
--- linux-libre-2.6.33-gnu1/drivers/net/declance.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/declance.c	2010-05-16 17:17:36.000000000 -0400
@@ -940,9 +940,8 @@ static void lance_load_multicast(struct
 {
 	struct lance_private *lp = netdev_priv(dev);
 	volatile u16 *ib = (volatile u16 *)dev->mem_start;
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	char *addrs;
-	int i;
 	u32 crc;
 
 	/* set all multicast bits */
@@ -960,9 +959,8 @@ static void lance_load_multicast(struct
 	*lib_ptr(ib, filter[3], lp->type) = 0;
 
 	/* Add addresses */
-	for (i = 0; i < dev->mc_count; i++) {
+	netdev_for_each_mc_addr(dmi, dev) {
 		addrs = dmi->dmi_addr;
-		dmi = dmi->next;
 
 		/* multicast address? */
 		if (!(*addrs & 1))
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/defxx.c linux-libre-2.6.34-gnu1/drivers/net/defxx.c
--- linux-libre-2.6.33-gnu1/drivers/net/defxx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/defxx.c	2010-05-16 17:17:36.000000000 -0400
@@ -1052,12 +1052,9 @@ static int __devinit dfx_driver_init(str
 		board_name = "DEFEA";
 	if (dfx_bus_pci)
 		board_name = "DEFPA";
-	pr_info("%s: %s at %saddr = 0x%llx, IRQ = %d, "
-		"Hardware addr = %02X-%02X-%02X-%02X-%02X-%02X\n",
+	pr_info("%s: %s at %saddr = 0x%llx, IRQ = %d, Hardware addr = %pMF\n",
 		print_name, board_name, dfx_use_mmio ? "" : "I/O ",
-		(long long)bar_start, dev->irq,
-		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+		(long long)bar_start, dev->irq, dev->dev_addr);
 
 	/*
 	 * Get memory for descriptor block, consumer block, and other buffers
@@ -2230,7 +2227,7 @@ static void dfx_ctl_set_multicast_list(s
 		 *		 perfect filtering will be used.
 		 */
 
-		if (dev->mc_count > (PI_CMD_ADDR_FILTER_K_SIZE - bp->uc_count))
+		if (netdev_mc_count(dev) > (PI_CMD_ADDR_FILTER_K_SIZE - bp->uc_count))
 			{
 			bp->group_prom	= PI_FSTATE_K_PASS;		/* Enable LLC group prom mode */
 			bp->mc_count	= 0;					/* Don't add mc addrs to CAM */
@@ -2238,17 +2235,16 @@ static void dfx_ctl_set_multicast_list(s
 		else
 			{
 			bp->group_prom	= PI_FSTATE_K_BLOCK;	/* Disable LLC group prom mode */
-			bp->mc_count	= dev->mc_count;		/* Add mc addrs to CAM */
+			bp->mc_count	= netdev_mc_count(dev);		/* Add mc addrs to CAM */
 			}
 
 		/* Copy addresses to multicast address table, then update adapter CAM */
 
-		dmi = dev->mc_list;				/* point to first multicast addr */
-		for (i=0; i < bp->mc_count; i++)
-			{
-			memcpy(&bp->mc_table[i*FDDI_K_ALEN], dmi->dmi_addr, FDDI_K_ALEN);
-			dmi = dmi->next;			/* point to next multicast addr */
-			}
+		i = 0;
+		netdev_for_each_mc_addr(dmi, dev)
+			memcpy(&bp->mc_table[i++ * FDDI_K_ALEN],
+			       dmi->dmi_addr, FDDI_K_ALEN);
+
 		if (dfx_ctl_update_cam(bp) != DFX_K_SUCCESS)
 			{
 			DBG_printk("%s: Could not update multicast address table!\n", dev->name);
@@ -3631,7 +3627,7 @@ static int __devinit dfx_pci_register(st
 				      const struct pci_device_id *);
 static void __devexit dfx_pci_unregister(struct pci_dev *);
 
-static struct pci_device_id dfx_pci_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(dfx_pci_table) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_FDDI) },
 	{ }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/depca.c linux-libre-2.6.34-gnu1/drivers/net/depca.c
--- linux-libre-2.6.33-gnu1/drivers/net/depca.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/depca.c	2010-05-16 17:17:36.000000000 -0400
@@ -1272,7 +1272,7 @@ static void set_multicast_list(struct ne
 static void SetMulticastFilter(struct net_device *dev)
 {
 	struct depca_private *lp = netdev_priv(dev);
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	char *addrs;
 	int i, j, bit, byte;
 	u16 hashcode;
@@ -1287,9 +1287,8 @@ static void SetMulticastFilter(struct ne
 			lp->init_block.mcast_table[i] = 0;
 		}
 		/* Add multicast addresses */
-		for (i = 0; i < dev->mc_count; i++) {	/* for each address in the list */
+		netdev_for_each_mc_addr(dmi, dev) {
 			addrs = dmi->dmi_addr;
-			dmi = dmi->next;
 			if ((*addrs & 0x01) == 1) {	/* multicast address? */
 				crc = ether_crc(ETH_ALEN, addrs);
 				hashcode = (crc & 1);	/* hashcode is 6 LSb of CRC ... */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/dl2k.c linux-libre-2.6.34-gnu1/drivers/net/dl2k.c
--- linux-libre-2.6.33-gnu1/drivers/net/dl2k.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/dl2k.c	2010-05-16 17:17:36.000000000 -0400
@@ -1128,19 +1128,16 @@ set_multicast (struct net_device *dev)
 		/* Receive all frames promiscuously. */
 		rx_mode = ReceiveAllFrames;
 	} else if ((dev->flags & IFF_ALLMULTI) ||
-			(dev->mc_count > multicast_filter_limit)) {
+			(netdev_mc_count(dev) > multicast_filter_limit)) {
 		/* Receive broadcast and multicast frames */
 		rx_mode = ReceiveBroadcast | ReceiveMulticast | ReceiveUnicast;
-	} else if (dev->mc_count > 0) {
-		int i;
+	} else if (!netdev_mc_empty(dev)) {
 		struct dev_mc_list *mclist;
 		/* Receive broadcast frames and multicast frames filtering
 		   by Hashtable */
 		rx_mode =
 		    ReceiveBroadcast | ReceiveMulticastHash | ReceiveUnicast;
-		for (i=0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-				i++, mclist=mclist->next)
-		{
+		netdev_for_each_mc_addr(mclist, dev) {
 			int bit, index = 0;
 			int crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr);
 			/* The inverted high significant 6 bits of CRC are
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/dl2k.h linux-libre-2.6.34-gnu1/drivers/net/dl2k.h
--- linux-libre-2.6.33-gnu1/drivers/net/dl2k.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/dl2k.h	2010-05-16 17:17:36.000000000 -0400
@@ -537,7 +537,7 @@ struct netdev_private {
         driver_data             Data private to the driver.
 */
 
-static const struct pci_device_id rio_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(rio_pci_tbl) = {
 	{0x1186, 0x4000, PCI_ANY_ID, PCI_ANY_ID, },
 	{0x13f0, 0x1021, PCI_ANY_ID, PCI_ANY_ID, },
 	{ }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/dm9000.c linux-libre-2.6.34-gnu1/drivers/net/dm9000.c
--- linux-libre-2.6.33-gnu1/drivers/net/dm9000.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/dm9000.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 
 #include <asm/delay.h>
 #include <asm/irq.h>
@@ -724,8 +725,7 @@ static void
 dm9000_hash_table(struct net_device *dev)
 {
 	board_info_t *db = netdev_priv(dev);
-	struct dev_mc_list *mcptr = dev->mc_list;
-	int mc_cnt = dev->mc_count;
+	struct dev_mc_list *mcptr;
 	int i, oft;
 	u32 hash_val;
 	u16 hash_table[4];
@@ -753,7 +753,7 @@ dm9000_hash_table(struct net_device *dev
 		rcr |= RCR_ALL;
 
 	/* the multicast address in Hash Table : 64 bits */
-	for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
+	netdev_for_each_mc_addr(mcptr, dev) {
 		hash_val = ether_crc_le(6, mcptr->dmi_addr) & 0x3f;
 		hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/e1000/e1000_ethtool.c linux-libre-2.6.34-gnu1/drivers/net/e1000/e1000_ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/e1000/e1000_ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/e1000/e1000_ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -215,6 +215,23 @@ static int e1000_set_settings(struct net
 	return 0;
 }
 
+static u32 e1000_get_link(struct net_device *netdev)
+{
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+
+	/*
+	 * If the link is not reported up to netdev, interrupts are disabled,
+	 * and so the physical link state may have changed since we last
+	 * looked. Set get_link_status to make sure that the true link
+	 * state is interrogated, rather than pulling a cached and possibly
+	 * stale link state from the driver.
+	 */
+	if (!netif_carrier_ok(netdev))
+		adapter->hw.get_link_status = 1;
+
+	return e1000_has_link(adapter);
+}
+
 static void e1000_get_pauseparam(struct net_device *netdev,
 				 struct ethtool_pauseparam *pause)
 {
@@ -1892,7 +1909,7 @@ static const struct ethtool_ops e1000_et
 	.get_msglevel           = e1000_get_msglevel,
 	.set_msglevel           = e1000_set_msglevel,
 	.nway_reset             = e1000_nway_reset,
-	.get_link               = ethtool_op_get_link,
+	.get_link               = e1000_get_link,
 	.get_eeprom_len         = e1000_get_eeprom_len,
 	.get_eeprom             = e1000_get_eeprom,
 	.set_eeprom             = e1000_set_eeprom,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/e1000/e1000.h linux-libre-2.6.34-gnu1/drivers/net/e1000/e1000.h
--- linux-libre-2.6.33-gnu1/drivers/net/e1000/e1000.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/e1000/e1000.h	2010-05-16 17:17:36.000000000 -0400
@@ -261,7 +261,6 @@ struct e1000_adapter {
 	/* TX */
 	struct e1000_tx_ring *tx_ring;      /* One per active queue */
 	unsigned int restart_queue;
-	unsigned long tx_queue_len;
 	u32 txd_cmd;
 	u32 tx_int_delay;
 	u32 tx_abs_int_delay;
@@ -349,6 +348,7 @@ extern int e1000_setup_all_tx_resources(
 extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
 extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
 extern void e1000_update_stats(struct e1000_adapter *adapter);
+extern bool e1000_has_link(struct e1000_adapter *adapter);
 extern void e1000_power_up_phy(struct e1000_adapter *);
 extern void e1000_set_ethtool_ops(struct net_device *netdev);
 extern void e1000_check_options(struct e1000_adapter *adapter);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/e1000/e1000_main.c linux-libre-2.6.34-gnu1/drivers/net/e1000/e1000_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/e1000/e1000_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/e1000/e1000_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,7 +42,7 @@ static const char e1000_copyright[] = "C
  * Macro expands to...
  *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
  */
-static struct pci_device_id e1000_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
 	INTEL_E1000_ETHERNET_DEVICE(0x1000),
 	INTEL_E1000_ETHERNET_DEVICE(0x1001),
 	INTEL_E1000_ETHERNET_DEVICE(0x1004),
@@ -383,8 +383,6 @@ static void e1000_configure(struct e1000
 		adapter->alloc_rx_buf(adapter, ring,
 		                      E1000_DESC_UNUSED(ring));
 	}
-
-	adapter->tx_queue_len = netdev->tx_queue_len;
 }
 
 int e1000_up(struct e1000_adapter *adapter)
@@ -503,7 +501,6 @@ void e1000_down(struct e1000_adapter *ad
 	del_timer_sync(&adapter->watchdog_timer);
 	del_timer_sync(&adapter->phy_info_timer);
 
-	netdev->tx_queue_len = adapter->tx_queue_len;
 	adapter->link_speed = 0;
 	adapter->link_duplex = 0;
 	netif_carrier_off(netdev);
@@ -847,6 +844,9 @@ static int __devinit e1000_probe(struct
 		goto err_pci_reg;
 
 	pci_set_master(pdev);
+	err = pci_save_state(pdev);
+	if (err)
+		goto err_alloc_etherdev;
 
 	err = -ENOMEM;
 	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
@@ -2127,7 +2127,7 @@ static void e1000_set_rx_mode(struct net
 			rctl |= E1000_RCTL_VFE;
 	}
 
-	if (netdev->uc.count > rar_entries - 1) {
+	if (netdev_uc_count(netdev) > rar_entries - 1) {
 		rctl |= E1000_RCTL_UPE;
 	} else if (!(netdev->flags & IFF_PROMISC)) {
 		rctl &= ~E1000_RCTL_UPE;
@@ -2150,7 +2150,7 @@ static void e1000_set_rx_mode(struct net
 	 */
 	i = 1;
 	if (use_uc)
-		list_for_each_entry(ha, &netdev->uc.list, list) {
+		netdev_for_each_uc_addr(ha, netdev) {
 			if (i == rar_entries)
 				break;
 			e1000_rar_set(hw, ha->addr, i++);
@@ -2158,29 +2158,25 @@ static void e1000_set_rx_mode(struct net
 
 	WARN_ON(i == rar_entries);
 
-	mc_ptr = netdev->mc_list;
-
-	for (; i < rar_entries; i++) {
-		if (mc_ptr) {
-			e1000_rar_set(hw, mc_ptr->da_addr, i);
-			mc_ptr = mc_ptr->next;
+	netdev_for_each_mc_addr(mc_ptr, netdev) {
+		if (i == rar_entries) {
+			/* load any remaining addresses into the hash table */
+			u32 hash_reg, hash_bit, mta;
+			hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
+			hash_reg = (hash_value >> 5) & 0x7F;
+			hash_bit = hash_value & 0x1F;
+			mta = (1 << hash_bit);
+			mcarray[hash_reg] |= mta;
 		} else {
-			E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
-			E1000_WRITE_FLUSH();
-			E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
-			E1000_WRITE_FLUSH();
+			e1000_rar_set(hw, mc_ptr->da_addr, i++);
 		}
 	}
 
-	/* 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);
-		hash_reg = (hash_value >> 5) & 0x7F;
-		hash_bit = hash_value & 0x1F;
-		mta = (1 << hash_bit);
-		mcarray[hash_reg] |= mta;
+	for (; i < rar_entries; i++) {
+		E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
+		E1000_WRITE_FLUSH();
+		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
+		E1000_WRITE_FLUSH();
 	}
 
 	/* write the hash table completely, write from bottom to avoid
@@ -2246,7 +2242,7 @@ static void e1000_82547_tx_fifo_stall(un
 	}
 }
 
-static bool e1000_has_link(struct e1000_adapter *adapter)
+bool e1000_has_link(struct e1000_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
 	bool link_active = false;
@@ -2317,19 +2313,15 @@ static void e1000_watchdog(unsigned long
 			        E1000_CTRL_RFCE) ? "RX" : ((ctrl &
 			        E1000_CTRL_TFCE) ? "TX" : "None" )));
 
-			/* tweak tx_queue_len according to speed/duplex
-			 * and adjust the timeout factor */
-			netdev->tx_queue_len = adapter->tx_queue_len;
+			/* adjust timeout factor according to speed/duplex */
 			adapter->tx_timeout_factor = 1;
 			switch (adapter->link_speed) {
 			case SPEED_10:
 				txb2b = false;
-				netdev->tx_queue_len = 10;
 				adapter->tx_timeout_factor = 16;
 				break;
 			case SPEED_100:
 				txb2b = false;
-				netdev->tx_queue_len = 100;
 				/* maybe add some timeout factor ? */
 				break;
 			}
@@ -4613,6 +4605,7 @@ static int e1000_resume(struct pci_dev *
 
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
+	pci_save_state(pdev);
 
 	if (adapter->need_ioport)
 		err = pci_enable_device(pdev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/e1000e/82571.c linux-libre-2.6.34-gnu1/drivers/net/e1000e/82571.c
--- linux-libre-2.6.33-gnu1/drivers/net/e1000e/82571.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/e1000e/82571.c	2010-05-16 17:17:36.000000000 -0400
@@ -267,8 +267,14 @@ static s32 e1000_init_mac_params_82571(s
 	}
 
 	switch (hw->mac.type) {
+	case e1000_82573:
+		func->set_lan_id = e1000_set_lan_id_single_port;
+		func->check_mng_mode = e1000e_check_mng_mode_generic;
+		func->led_on = e1000e_led_on_generic;
+		break;
 	case e1000_82574:
 	case e1000_82583:
+		func->set_lan_id = e1000_set_lan_id_single_port;
 		func->check_mng_mode = e1000_check_mng_mode_82574;
 		func->led_on = e1000_led_on_82574;
 		break;
@@ -330,7 +336,6 @@ static s32 e1000_get_variants_82571(stru
 	struct e1000_hw *hw = &adapter->hw;
 	static int global_quad_port_a; /* global port a indication */
 	struct pci_dev *pdev = adapter->pdev;
-	u16 eeprom_data = 0;
 	int is_port_b = er32(STATUS) & E1000_STATUS_FUNC_1;
 	s32 rc;
 
@@ -381,16 +386,15 @@ static s32 e1000_get_variants_82571(stru
 		if (pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD)
 			adapter->flags &= ~FLAG_HAS_WOL;
 		break;
-
 	case e1000_82573:
+	case e1000_82574:
+	case e1000_82583:
+		/* Disable ASPM L0s due to hardware errata */
+		e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L0S);
+
 		if (pdev->device == E1000_DEV_ID_82573L) {
-			if (e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1,
-				       &eeprom_data) < 0)
-				break;
-			if (!(eeprom_data & NVM_WORD1A_ASPM_MASK)) {
-				adapter->flags |= FLAG_HAS_JUMBO_FRAMES;
-				adapter->max_hw_frame_size = DEFAULT_JUMBO;
-			}
+			adapter->flags |= FLAG_HAS_JUMBO_FRAMES;
+			adapter->max_hw_frame_size = DEFAULT_JUMBO;
 		}
 		break;
 	default:
@@ -922,9 +926,12 @@ static s32 e1000_reset_hw_82571(struct e
 	ew32(IMC, 0xffffffff);
 	icr = er32(ICR);
 
-	if (hw->mac.type == e1000_82571 &&
-		hw->dev_spec.e82571.alt_mac_addr_is_present)
-			e1000e_set_laa_state_82571(hw, true);
+	/* Install any alternate MAC address into RAR0 */
+	ret_val = e1000_check_alt_mac_addr_generic(hw);
+	if (ret_val)
+		return ret_val;
+
+	e1000e_set_laa_state_82571(hw, true);
 
 	/* Reinitialize the 82571 serdes link state machine */
 	if (hw->phy.media_type == e1000_media_type_internal_serdes)
@@ -1225,32 +1232,6 @@ static s32 e1000_led_on_82574(struct e10
 }
 
 /**
- *  e1000_update_mc_addr_list_82571 - 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.
- **/
-static void e1000_update_mc_addr_list_82571(struct e1000_hw *hw,
-					    u8 *mc_addr_list,
-					    u32 mc_addr_count,
-					    u32 rar_used_count,
-					    u32 rar_count)
-{
-	if (e1000e_get_laa_state_82571(hw))
-		rar_count--;
-
-	e1000e_update_mc_addr_list_generic(hw, mc_addr_list, mc_addr_count,
-					   rar_used_count, rar_count);
-}
-
-/**
  *  e1000_setup_link_82571 - Setup flow control and link settings
  *  @hw: pointer to the HW structure
  *
@@ -1363,7 +1344,7 @@ static s32 e1000_setup_fiber_serdes_link
  *
  *  1) down
  *  2) autoneg_progress
- *  3) autoneg_complete (the link sucessfully autonegotiated)
+ *  3) autoneg_complete (the link successfully autonegotiated)
  *  4) forced_up (the link has been forced up, it did not autonegotiate)
  *
  **/
@@ -1621,6 +1602,29 @@ static s32 e1000_fix_nvm_checksum_82571(
 }
 
 /**
+ *  e1000_read_mac_addr_82571 - Read device MAC address
+ *  @hw: pointer to the HW structure
+ **/
+static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw)
+{
+	s32 ret_val = 0;
+
+	/*
+	 * If there's an alternate MAC address place it in RAR0
+	 * so that it will override the Si installed default perm
+	 * address.
+	 */
+	ret_val = e1000_check_alt_mac_addr_generic(hw);
+	if (ret_val)
+		goto out;
+
+	ret_val = e1000_read_mac_addr_generic(hw);
+
+out:
+	return ret_val;
+}
+
+/**
  * e1000_power_down_phy_copper_82571 - Remove link during PHY power down
  * @hw: pointer to the HW structure
  *
@@ -1695,10 +1699,11 @@ static struct e1000_mac_operations e8257
 	.cleanup_led		= e1000e_cleanup_led_generic,
 	.clear_hw_cntrs		= e1000_clear_hw_cntrs_82571,
 	.get_bus_info		= e1000e_get_bus_info_pcie,
+	.set_lan_id		= e1000_set_lan_id_multi_port_pcie,
 	/* .get_link_up_info: media type dependent */
 	/* .led_on: mac type dependent */
 	.led_off		= e1000e_led_off_generic,
-	.update_mc_addr_list	= e1000_update_mc_addr_list_82571,
+	.update_mc_addr_list	= e1000e_update_mc_addr_list_generic,
 	.write_vfta		= e1000_write_vfta_generic,
 	.clear_vfta		= e1000_clear_vfta_82571,
 	.reset_hw		= e1000_reset_hw_82571,
@@ -1706,6 +1711,7 @@ static struct e1000_mac_operations e8257
 	.setup_link		= e1000_setup_link_82571,
 	/* .setup_physical_interface: media type dependent */
 	.setup_led		= e1000e_setup_led_generic,
+	.read_mac_addr		= e1000_read_mac_addr_82571,
 };
 
 static struct e1000_phy_operations e82_phy_ops_igp = {
@@ -1784,6 +1790,7 @@ struct e1000_info e1000_82571_info = {
 				  | FLAG_RESET_OVERWRITES_LAA /* errata */
 				  | FLAG_TARC_SPEED_MODE_BIT /* errata */
 				  | FLAG_APME_CHECK_PORT_B,
+	.flags2			= FLAG2_DISABLE_ASPM_L1, /* errata 13 */
 	.pba			= 38,
 	.max_hw_frame_size	= DEFAULT_JUMBO,
 	.get_variants		= e1000_get_variants_82571,
@@ -1801,6 +1808,7 @@ struct e1000_info e1000_82572_info = {
 				  | FLAG_RX_CSUM_ENABLED
 				  | FLAG_HAS_CTRLEXT_ON_LOAD
 				  | FLAG_TARC_SPEED_MODE_BIT, /* errata */
+	.flags2			= FLAG2_DISABLE_ASPM_L1, /* errata 13 */
 	.pba			= 38,
 	.max_hw_frame_size	= DEFAULT_JUMBO,
 	.get_variants		= e1000_get_variants_82571,
@@ -1812,13 +1820,11 @@ struct e1000_info e1000_82572_info = {
 struct e1000_info e1000_82573_info = {
 	.mac			= e1000_82573,
 	.flags			= FLAG_HAS_HW_VLAN_FILTER
-				  | FLAG_HAS_JUMBO_FRAMES
 				  | FLAG_HAS_WOL
 				  | FLAG_APME_IN_CTRL3
 				  | FLAG_RX_CSUM_ENABLED
 				  | FLAG_HAS_SMART_POWER_DOWN
 				  | FLAG_HAS_AMT
-				  | FLAG_HAS_ERT
 				  | FLAG_HAS_SWSM_ON_LOAD,
 	.pba			= 20,
 	.max_hw_frame_size	= ETH_FRAME_LEN + ETH_FCS_LEN,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/e1000e/defines.h linux-libre-2.6.34-gnu1/drivers/net/e1000e/defines.h
--- linux-libre-2.6.33-gnu1/drivers/net/e1000e/defines.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/e1000e/defines.h	2010-05-16 17:17:36.000000000 -0400
@@ -320,6 +320,8 @@
 #define E1000_RXCSUM_IPPCSE    0x00001000   /* IP payload checksum enable */
 
 /* Header split receive */
+#define E1000_RFCTL_NFSW_DIS            0x00000040
+#define E1000_RFCTL_NFSR_DIS            0x00000080
 #define E1000_RFCTL_ACK_DIS             0x00001000
 #define E1000_RFCTL_EXTEN               0x00008000
 #define E1000_RFCTL_IPV6_EX_DIS         0x00010000
@@ -460,6 +462,8 @@
  */
 #define E1000_RAR_ENTRIES     15
 #define E1000_RAH_AV  0x80000000        /* Receive descriptor valid */
+#define E1000_RAL_MAC_ADDR_LEN 4
+#define E1000_RAH_MAC_ADDR_LEN 2
 
 /* Error Codes */
 #define E1000_ERR_NVM      1
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/e1000e/e1000.h linux-libre-2.6.34-gnu1/drivers/net/e1000e/e1000.h
--- linux-libre-2.6.33-gnu1/drivers/net/e1000e/e1000.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/e1000e/e1000.h	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/io.h>
 #include <linux/netdevice.h>
 #include <linux/pci.h>
+#include <linux/pci-aspm.h>
 
 #include "hw.h"
 
@@ -279,7 +280,6 @@ struct e1000_adapter {
 
 	struct napi_struct napi;
 
-	unsigned long tx_queue_len;
 	unsigned int restart_queue;
 	u32 txd_cmd;
 
@@ -375,7 +375,7 @@ struct e1000_adapter {
 struct e1000_info {
 	enum e1000_mac_type	mac;
 	unsigned int		flags;
-	unsigned int            flags2;
+	unsigned int		flags2;
 	u32			pba;
 	u32			max_hw_frame_size;
 	s32			(*get_variants)(struct e1000_adapter *);
@@ -422,6 +422,7 @@ struct e1000_info {
 #define FLAG2_CRC_STRIPPING               (1 << 0)
 #define FLAG2_HAS_PHY_WAKEUP              (1 << 1)
 #define FLAG2_IS_DISCARDING               (1 << 2)
+#define FLAG2_DISABLE_ASPM_L1             (1 << 3)
 
 #define E1000_RX_DESC_PS(R, i)	    \
 	(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
@@ -459,9 +460,10 @@ extern int e1000e_setup_tx_resources(str
 extern void e1000e_free_rx_resources(struct e1000_adapter *adapter);
 extern void e1000e_free_tx_resources(struct e1000_adapter *adapter);
 extern void e1000e_update_stats(struct e1000_adapter *adapter);
-extern bool e1000_has_link(struct e1000_adapter *adapter);
+extern bool e1000e_has_link(struct e1000_adapter *adapter);
 extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter);
 extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);
+extern void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
 
 extern unsigned int copybreak;
 
@@ -503,6 +505,8 @@ extern s32 e1000e_cleanup_led_generic(st
 extern s32 e1000e_led_on_generic(struct e1000_hw *hw);
 extern s32 e1000e_led_off_generic(struct e1000_hw *hw);
 extern s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw);
+extern void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw);
+extern void e1000_set_lan_id_single_port(struct e1000_hw *hw);
 extern s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, u16 *duplex);
 extern s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw *hw, u16 *speed, u16 *duplex);
 extern s32 e1000e_disable_pcie_master(struct e1000_hw *hw);
@@ -517,9 +521,7 @@ extern void e1000_clear_vfta_generic(str
 extern void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
 extern void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
 					       u8 *mc_addr_list,
-					       u32 mc_addr_count,
-					       u32 rar_used_count,
-					       u32 rar_count);
+					       u32 mc_addr_count);
 extern void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
 extern s32 e1000e_set_fc_watermarks(struct e1000_hw *hw);
 extern void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop);
@@ -530,6 +532,7 @@ extern s32 e1000e_config_fc_after_link_u
 extern s32 e1000e_force_mac_fc(struct e1000_hw *hw);
 extern s32 e1000e_blink_led(struct e1000_hw *hw);
 extern void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
+extern s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw);
 extern void e1000e_reset_adaptive(struct e1000_hw *hw);
 extern void e1000e_update_adaptive(struct e1000_hw *hw);
 
@@ -629,7 +632,15 @@ extern s32 e1000e_read_nvm_eerd(struct e
 extern s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw);
 extern void e1000e_release_nvm(struct e1000_hw *hw);
 extern void e1000e_reload_nvm(struct e1000_hw *hw);
-extern s32 e1000e_read_mac_addr(struct e1000_hw *hw);
+extern s32 e1000_read_mac_addr_generic(struct e1000_hw *hw);
+
+static inline s32 e1000e_read_mac_addr(struct e1000_hw *hw)
+{
+	if (hw->mac.ops.read_mac_addr)
+		return hw->mac.ops.read_mac_addr(hw);
+
+	return e1000_read_mac_addr_generic(hw);
+}
 
 static inline s32 e1000_validate_nvm_checksum(struct e1000_hw *hw)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/e1000e/es2lan.c linux-libre-2.6.34-gnu1/drivers/net/e1000e/es2lan.c
--- linux-libre-2.6.33-gnu1/drivers/net/e1000e/es2lan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/e1000e/es2lan.c	2010-05-16 17:17:36.000000000 -0400
@@ -246,6 +246,9 @@ static s32 e1000_init_mac_params_80003es
 		break;
 	}
 
+	/* set lan id for port to determine which phy lock to use */
+	hw->mac.ops.set_lan_id(hw);
+
 	return 0;
 }
 
@@ -814,7 +817,9 @@ static s32 e1000_reset_hw_80003es2lan(st
 	ew32(IMC, 0xffffffff);
 	icr = er32(ICR);
 
-	return 0;
+	ret_val = e1000_check_alt_mac_addr_generic(hw);
+
+	return ret_val;
 }
 
 /**
@@ -1340,6 +1345,29 @@ static s32 e1000_write_kmrn_reg_80003es2
 }
 
 /**
+ *  e1000_read_mac_addr_80003es2lan - Read device MAC address
+ *  @hw: pointer to the HW structure
+ **/
+static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw)
+{
+	s32 ret_val = 0;
+
+	/*
+	 * If there's an alternate MAC address place it in RAR0
+	 * so that it will override the Si installed default perm
+	 * address.
+	 */
+	ret_val = e1000_check_alt_mac_addr_generic(hw);
+	if (ret_val)
+		goto out;
+
+	ret_val = e1000_read_mac_addr_generic(hw);
+
+out:
+	return ret_val;
+}
+
+/**
  * e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down
  * @hw: pointer to the HW structure
  *
@@ -1403,12 +1431,14 @@ static void e1000_clear_hw_cntrs_80003es
 }
 
 static struct e1000_mac_operations es2_mac_ops = {
+	.read_mac_addr		= e1000_read_mac_addr_80003es2lan,
 	.id_led_init		= e1000e_id_led_init,
 	.check_mng_mode		= e1000e_check_mng_mode_generic,
 	/* check_for_link dependent on media type */
 	.cleanup_led		= e1000e_cleanup_led_generic,
 	.clear_hw_cntrs		= e1000_clear_hw_cntrs_80003es2lan,
 	.get_bus_info		= e1000e_get_bus_info_pcie,
+	.set_lan_id		= e1000_set_lan_id_multi_port_pcie,
 	.get_link_up_info	= e1000_get_link_up_info_80003es2lan,
 	.led_on			= e1000e_led_on_generic,
 	.led_off		= e1000e_led_off_generic,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/e1000e/ethtool.c linux-libre-2.6.34-gnu1/drivers/net/e1000e/ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/e1000e/ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/e1000e/ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include "e1000.h"
@@ -202,7 +203,7 @@ static u32 e1000_get_link(struct net_dev
 	if (!netif_carrier_ok(netdev))
 		mac->get_link_status = 1;
 
-	return e1000_has_link(adapter);
+	return e1000e_has_link(adapter);
 }
 
 static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/e1000e/hw.h linux-libre-2.6.34-gnu1/drivers/net/e1000e/hw.h
--- linux-libre-2.6.33-gnu1/drivers/net/e1000e/hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/e1000e/hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -389,6 +389,9 @@ enum e1e_registers {
 
 #define E1000_FUNC_1 1
 
+#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN0   0
+#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1   3
+
 enum e1000_mac_type {
 	e1000_82571,
 	e1000_82572,
@@ -746,16 +749,18 @@ struct e1000_mac_operations {
 	void (*clear_hw_cntrs)(struct e1000_hw *);
 	void (*clear_vfta)(struct e1000_hw *);
 	s32  (*get_bus_info)(struct e1000_hw *);
+	void (*set_lan_id)(struct e1000_hw *);
 	s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
 	s32  (*led_on)(struct e1000_hw *);
 	s32  (*led_off)(struct e1000_hw *);
-	void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32, u32, u32);
+	void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);
 	s32  (*reset_hw)(struct e1000_hw *);
 	s32  (*init_hw)(struct e1000_hw *);
 	s32  (*setup_link)(struct e1000_hw *);
 	s32  (*setup_physical_interface)(struct e1000_hw *);
 	s32  (*setup_led)(struct e1000_hw *);
 	void (*write_vfta)(struct e1000_hw *, u32, u32);
+	s32  (*read_mac_addr)(struct e1000_hw *);
 };
 
 /* Function pointers for the PHY. */
@@ -814,6 +819,10 @@ struct e1000_mac_info {
 	u16 ifs_ratio;
 	u16 ifs_step_size;
 	u16 mta_reg_count;
+
+	/* Maximum size of the MTA register table in all supported adapters */
+	#define MAX_MTA_REG 128
+	u32 mta_shadow[MAX_MTA_REG];
 	u16 rar_entry_count;
 
 	u8  forced_speed_duplex;
@@ -897,7 +906,6 @@ struct e1000_fc_info {
 
 struct e1000_dev_spec_82571 {
 	bool laa_is_present;
-	bool alt_mac_addr_is_present;
 	u32 smb_counter;
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/e1000e/ich8lan.c linux-libre-2.6.34-gnu1/drivers/net/e1000e/ich8lan.c
--- linux-libre-2.6.33-gnu1/drivers/net/e1000e/ich8lan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/e1000e/ich8lan.c	2010-05-16 17:17:36.000000000 -0400
@@ -2740,6 +2740,16 @@ static void e1000_initialize_hw_bits_ich
 		reg &= ~(1 << 31);
 		ew32(STATUS, reg);
 	}
+
+	/*
+	 * work-around descriptor data corruption issue during nfs v2 udp
+	 * traffic, just disable the nfs filtering capability
+	 */
+	reg = er32(RFCTL);
+	reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS);
+	ew32(RFCTL, reg);
+
+	return;
 }
 
 /**
@@ -3368,6 +3378,7 @@ static struct e1000_mac_operations ich8_
 	/* cleanup_led dependent on mac type */
 	.clear_hw_cntrs		= e1000_clear_hw_cntrs_ich8lan,
 	.get_bus_info		= e1000_get_bus_info_ich8lan,
+	.set_lan_id		= e1000_set_lan_id_single_port,
 	.get_link_up_info	= e1000_get_link_up_info_ich8lan,
 	/* led_on dependent on mac type */
 	/* led_off dependent on mac type */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/e1000e/lib.c linux-libre-2.6.34-gnu1/drivers/net/e1000e/lib.c
--- linux-libre-2.6.33-gnu1/drivers/net/e1000e/lib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/e1000e/lib.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,10 +51,10 @@ enum e1000_mng_mode {
  **/
 s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw)
 {
+	struct e1000_mac_info *mac = &hw->mac;
 	struct e1000_bus_info *bus = &hw->bus;
 	struct e1000_adapter *adapter = hw->adapter;
-	u32 status;
-	u16 pcie_link_status, pci_header_type, cap_offset;
+	u16 pcie_link_status, cap_offset;
 
 	cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
 	if (!cap_offset) {
@@ -68,20 +68,46 @@ s32 e1000e_get_bus_info_pcie(struct e100
 						    PCIE_LINK_WIDTH_SHIFT);
 	}
 
-	pci_read_config_word(adapter->pdev, PCI_HEADER_TYPE_REGISTER,
-			     &pci_header_type);
-	if (pci_header_type & PCI_HEADER_TYPE_MULTIFUNC) {
-		status = er32(STATUS);
-		bus->func = (status & E1000_STATUS_FUNC_MASK)
-			    >> E1000_STATUS_FUNC_SHIFT;
-	} else {
-		bus->func = 0;
-	}
+	mac->ops.set_lan_id(hw);
 
 	return 0;
 }
 
 /**
+ *  e1000_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 e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw)
+{
+	struct e1000_bus_info *bus = &hw->bus;
+	u32 reg;
+
+	/*
+	 * The status register reports the correct function number
+	 * for the device regardless of function swap state.
+	 */
+	reg = er32(STATUS);
+	bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT;
+}
+
+/**
+ *  e1000_set_lan_id_single_port - Set LAN id for a single port device
+ *  @hw: pointer to the HW structure
+ *
+ *  Sets the LAN function id to zero for a single port device.
+ **/
+void e1000_set_lan_id_single_port(struct e1000_hw *hw)
+{
+	struct e1000_bus_info *bus = &hw->bus;
+
+	bus->func = 0;
+}
+
+/**
  *  e1000_clear_vfta_generic - Clear VLAN filter table
  *  @hw: pointer to the HW structure
  *
@@ -139,6 +165,68 @@ void e1000e_init_rx_addrs(struct e1000_h
 }
 
 /**
+ *  e1000_check_alt_mac_addr_generic - Check for alternate MAC addr
+ *  @hw: pointer to the HW structure
+ *
+ *  Checks the nvm for an alternate MAC address.  An alternate MAC address
+ *  can be setup by pre-boot software and must be treated like a permanent
+ *  address and must override the actual permanent MAC address. If an
+ *  alternate MAC address is found it is programmed into RAR0, replacing
+ *  the permanent address that was installed into RAR0 by the Si on reset.
+ *  This function will return SUCCESS unless it encounters an error while
+ *  reading the EEPROM.
+ **/
+s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
+{
+	u32 i;
+	s32 ret_val = 0;
+	u16 offset, nvm_alt_mac_addr_offset, nvm_data;
+	u8 alt_mac_addr[ETH_ALEN];
+
+	ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
+	                         &nvm_alt_mac_addr_offset);
+	if (ret_val) {
+		e_dbg("NVM Read Error\n");
+		goto out;
+	}
+
+	if (nvm_alt_mac_addr_offset == 0xFFFF) {
+		/* There is no Alternate MAC Address */
+		goto out;
+	}
+
+	if (hw->bus.func == E1000_FUNC_1)
+		nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1;
+	for (i = 0; i < ETH_ALEN; i += 2) {
+		offset = nvm_alt_mac_addr_offset + (i >> 1);
+		ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
+		if (ret_val) {
+			e_dbg("NVM Read Error\n");
+			goto out;
+		}
+
+		alt_mac_addr[i] = (u8)(nvm_data & 0xFF);
+		alt_mac_addr[i + 1] = (u8)(nvm_data >> 8);
+	}
+
+	/* if multicast bit is set, the alternate address will not be used */
+	if (alt_mac_addr[0] & 0x01) {
+		e_dbg("Ignoring Alternate Mac Address with MC bit set\n");
+		goto out;
+	}
+
+	/*
+	 * We have a valid alternate MAC address, and we want to treat it the
+	 * same as the normal permanent MAC address stored by the HW into the
+	 * RAR. Do this by mapping this address into RAR0.
+	 */
+	e1000e_rar_set(hw, alt_mac_addr, 0);
+
+out:
+	return ret_val;
+}
+
+/**
  *  e1000e_rar_set - Set receive address register
  *  @hw: pointer to the HW structure
  *  @addr: pointer to the receive address
@@ -252,62 +340,34 @@ static u32 e1000_hash_mc_addr(struct e10
  *  @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.
+ *  Updates entire 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 e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
-					u8 *mc_addr_list, u32 mc_addr_count,
-					u32 rar_used_count, u32 rar_count)
+					u8 *mc_addr_list, u32 mc_addr_count)
 {
-	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;
-	}
+	u32 hash_value, hash_bit, hash_reg;
+	int i;
 
-	/*
-	 * Load the first set of multicast addresses into the exact
-	 * filters (RAR).  If there are not enough to fill the RAR
-	 * array, clear the filters.
-	 */
-	for (i = rar_used_count; i < rar_count; i++) {
-		if (mc_addr_count) {
-			e1000e_rar_set(hw, mc_addr_list, i);
-			mc_addr_count--;
-			mc_addr_list += ETH_ALEN;
-		} else {
-			E1000_WRITE_REG_ARRAY(hw, E1000_RA, i << 1, 0);
-			e1e_flush();
-			E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1) + 1, 0);
-			e1e_flush();
-		}
-	}
+	/* clear mta_shadow */
+	memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
 
-	/* 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;
+	/* update mta_shadow from mc_addr_list */
+	for (i = 0; (u32) i < mc_addr_count; i++) {
 		hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
-		e_dbg("Hash value = 0x%03X\n", hash_value);
+
 		hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
 		hash_bit = hash_value & 0x1F;
-		mta = (1 << hash_bit);
-		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]);
+		hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
+		mc_addr_list += (ETH_ALEN);
+	}
 
+	/* replace the entire MTA table */
+	for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
+		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
 	e1e_flush();
-	kfree(mcarray);
 }
 
 /**
@@ -587,7 +647,7 @@ s32 e1000e_check_for_serdes_link(struct
 				if (!(rxcw & E1000_RXCW_IV)) {
 					mac->serdes_has_link = true;
 					e_dbg("SERDES: Link up - autoneg "
-					   "completed sucessfully.\n");
+					   "completed successfully.\n");
 				} else {
 					mac->serdes_has_link = false;
 					e_dbg("SERDES: Link down - invalid"
@@ -2072,67 +2132,27 @@ s32 e1000e_write_nvm_spi(struct e1000_hw
 }
 
 /**
- *  e1000e_read_mac_addr - Read device MAC address
+ *  e1000_read_mac_addr_generic - Read device MAC address
  *  @hw: pointer to the HW structure
  *
  *  Reads the device MAC address from the EEPROM and stores the value.
  *  Since devices with two ports use the same EEPROM, we increment the
  *  last bit in the MAC address for the second port.
  **/
-s32 e1000e_read_mac_addr(struct e1000_hw *hw)
+s32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
 {
-	s32 ret_val;
-	u16 offset, nvm_data, i;
-	u16 mac_addr_offset = 0;
-
-	if (hw->mac.type == e1000_82571) {
-		/* Check for an alternate MAC address.  An alternate MAC
-		 * address can be setup by pre-boot software and must be
-		 * treated like a permanent address and must override the
-		 * actual permanent MAC address.*/
-		ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
-					 &mac_addr_offset);
-		if (ret_val) {
-			e_dbg("NVM Read Error\n");
-			return ret_val;
-		}
-		if (mac_addr_offset == 0xFFFF)
-			mac_addr_offset = 0;
-
-		if (mac_addr_offset) {
-			if (hw->bus.func == E1000_FUNC_1)
-				mac_addr_offset += ETH_ALEN/sizeof(u16);
-
-			/* make sure we have a valid mac address here
-			* before using it */
-			ret_val = e1000_read_nvm(hw, mac_addr_offset, 1,
-						 &nvm_data);
-			if (ret_val) {
-				e_dbg("NVM Read Error\n");
-				return ret_val;
-			}
-			if (nvm_data & 0x0001)
-				mac_addr_offset = 0;
-		}
+	u32 rar_high;
+	u32 rar_low;
+	u16 i;
 
-		if (mac_addr_offset)
-		hw->dev_spec.e82571.alt_mac_addr_is_present = 1;
-	}
+	rar_high = er32(RAH(0));
+	rar_low = er32(RAL(0));
 
-	for (i = 0; i < ETH_ALEN; i += 2) {
-		offset = mac_addr_offset + (i >> 1);
-		ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
-		if (ret_val) {
-			e_dbg("NVM Read Error\n");
-			return ret_val;
-		}
-		hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
-		hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
-	}
+	for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
+		hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
 
-	/* Flip last bit of mac address if we're on second port */
-	if (!mac_addr_offset && hw->bus.func == E1000_FUNC_1)
-		hw->mac.perm_addr[5] ^= 1;
+	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];
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/e1000e/netdev.c linux-libre-2.6.34-gnu1/drivers/net/e1000e/netdev.c
--- linux-libre-2.6.33-gnu1/drivers/net/e1000e/netdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/e1000e/netdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/netdevice.h>
 #include <linux/tcp.h>
 #include <linux/ipv6.h>
+#include <linux/slab.h>
 #include <net/checksum.h>
 #include <net/ip6_checksum.h>
 #include <linux/mii.h>
@@ -660,6 +661,8 @@ static bool e1000_clean_tx_irq(struct e1
 				i = 0;
 		}
 
+		if (i == tx_ring->next_to_use)
+			break;
 		eop = tx_ring->buffer_info[i].next_to_watch;
 		eop_desc = E1000_TX_DESC(*tx_ring, eop);
 	}
@@ -2289,8 +2292,6 @@ static void e1000_configure_tx(struct e1
 	ew32(TCTL, tctl);
 
 	e1000e_config_collision_dist(hw);
-
-	adapter->tx_queue_len = adapter->netdev->tx_queue_len;
 }
 
 /**
@@ -2541,22 +2542,14 @@ static void e1000_configure_rx(struct e1
  *  @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.
+ *  Updates the 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.  Currently no func pointer
- *  exists and all implementations are handled in the generic version of this
- *  function.
  **/
 static void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
-				      u32 mc_addr_count, u32 rar_used_count,
-				      u32 rar_count)
+				      u32 mc_addr_count)
 {
-	hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, mc_addr_count,
-				        rar_used_count, rar_count);
+	hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, mc_addr_count);
 }
 
 /**
@@ -2572,7 +2565,6 @@ static void e1000_set_multi(struct net_d
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
-	struct e1000_mac_info *mac = &hw->mac;
 	struct dev_mc_list *mc_ptr;
 	u8  *mta_list;
 	u32 rctl;
@@ -2598,31 +2590,25 @@ static void e1000_set_multi(struct net_d
 
 	ew32(RCTL, rctl);
 
-	if (netdev->mc_count) {
-		mta_list = kmalloc(netdev->mc_count * 6, GFP_ATOMIC);
+	if (!netdev_mc_empty(netdev)) {
+		mta_list = kmalloc(netdev_mc_count(netdev) * 6, GFP_ATOMIC);
 		if (!mta_list)
 			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;
-		}
+		i = 0;
+		netdev_for_each_mc_addr(mc_ptr, netdev)
+			memcpy(mta_list + (i++ * ETH_ALEN),
+			       mc_ptr->dmi_addr, ETH_ALEN);
 
-		e1000_update_mc_addr_list(hw, mta_list, i, 1,
-					  mac->rar_entry_count);
+		e1000_update_mc_addr_list(hw, mta_list, i);
 		kfree(mta_list);
 	} else {
 		/*
 		 * if we're called from probe, we might not have
 		 * anything to do here, so clear out the list
 		 */
-		e1000_update_mc_addr_list(hw, NULL, 0, 1, mac->rar_entry_count);
+		e1000_update_mc_addr_list(hw, NULL, 0);
 	}
 }
 
@@ -2892,7 +2878,6 @@ void e1000e_down(struct e1000_adapter *a
 	del_timer_sync(&adapter->watchdog_timer);
 	del_timer_sync(&adapter->phy_info_timer);
 
-	netdev->tx_queue_len = adapter->tx_queue_len;
 	netif_carrier_off(netdev);
 	adapter->link_speed = 0;
 	adapter->link_duplex = 0;
@@ -3482,7 +3467,7 @@ static void e1000_print_link_info(struct
 	       ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));
 }
 
-bool e1000_has_link(struct e1000_adapter *adapter)
+bool e1000e_has_link(struct e1000_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
 	bool link_active = 0;
@@ -3563,7 +3548,7 @@ static void e1000_watchdog_task(struct w
 	u32 link, tctl;
 	int tx_pending = 0;
 
-	link = e1000_has_link(adapter);
+	link = e1000e_has_link(adapter);
 	if ((netif_carrier_ok(netdev)) && link) {
 		e1000e_enable_receives(adapter);
 		goto link_up;
@@ -3603,21 +3588,15 @@ static void e1000_watchdog_task(struct w
 					       "link gets many collisions.\n");
 			}
 
-			/*
-			 * tweak tx_queue_len according to speed/duplex
-			 * and adjust the timeout factor
-			 */
-			netdev->tx_queue_len = adapter->tx_queue_len;
+			/* adjust timeout factor according to speed/duplex */
 			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;
 				adapter->tx_timeout_factor = 10;
 				break;
 			}
@@ -4304,6 +4283,14 @@ static int e1000_change_mtu(struct net_d
 		return -EINVAL;
 	}
 
+	/* 82573 Errata 17 */
+	if (((adapter->hw.mac.type == e1000_82573) ||
+	     (adapter->hw.mac.type == e1000_82574)) &&
+	    (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN)) {
+		adapter->flags2 |= FLAG2_DISABLE_ASPM_L1;
+		e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L1);
+	}
+
 	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
 		msleep(1);
 	/* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
@@ -4626,29 +4613,42 @@ static void e1000_complete_shutdown(stru
 	}
 }
 
-static void e1000e_disable_l1aspm(struct pci_dev *pdev)
+#ifdef CONFIG_PCIEASPM
+static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+{
+	pci_disable_link_state(pdev, state);
+}
+#else
+static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
 {
 	int pos;
-	u16 val;
+	u16 reg16;
 
 	/*
-	 * 82573 workaround - disable L1 ASPM on mobile chipsets
-	 *
-	 * L1 ASPM on various mobile (ich7) chipsets do not behave properly
-	 * resulting in lost data or garbage information on the pci-e link
-	 * level. This could result in (false) bad EEPROM checksum errors,
-	 * long ping times (up to 2s) or even a system freeze/hang.
-	 *
-	 * Unfortunately this feature saves about 1W power consumption when
-	 * active.
+	 * Both device and parent should have the same ASPM setting.
+	 * Disable ASPM in downstream component first and then upstream.
 	 */
-	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
-	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val);
-	if (val & 0x2) {
-		dev_warn(&pdev->dev, "Disabling L1 ASPM\n");
-		val &= ~0x2;
-		pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val);
-	}
+	pos = pci_pcie_cap(pdev);
+	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
+	reg16 &= ~state;
+	pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
+
+	if (!pdev->bus->self)
+		return;
+
+	pos = pci_pcie_cap(pdev->bus->self);
+	pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, &reg16);
+	reg16 &= ~state;
+	pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16);
+}
+#endif
+void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+{
+	dev_info(&pdev->dev, "Disabling ASPM %s %s\n",
+		 (state & PCIE_LINK_STATE_L0S) ? "L0s" : "",
+		 (state & PCIE_LINK_STATE_L1) ? "L1" : "");
+
+	__e1000e_disable_aspm(pdev, state);
 }
 
 #ifdef CONFIG_PM
@@ -4674,7 +4674,8 @@ static int e1000_resume(struct pci_dev *
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 	pci_save_state(pdev);
-	e1000e_disable_l1aspm(pdev);
+	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
+		e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
 
 	err = pci_enable_device_mem(pdev);
 	if (err) {
@@ -4816,7 +4817,8 @@ static pci_ers_result_t e1000_io_slot_re
 	int err;
 	pci_ers_result_t result;
 
-	e1000e_disable_l1aspm(pdev);
+	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
+		e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
 	err = pci_enable_device_mem(pdev);
 	if (err) {
 		dev_err(&pdev->dev,
@@ -4910,13 +4912,6 @@ static void e1000_eeprom_checks(struct e
 		dev_warn(&adapter->pdev->dev,
 			 "Warning: detected DSPD enabled in EEPROM\n");
 	}
-
-	ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf);
-	if (!ret_val && (le16_to_cpu(buf) & (3 << 2))) {
-		/* ASPM enable */
-		dev_warn(&adapter->pdev->dev,
-			 "Warning: detected ASPM enabled in EEPROM\n");
-	}
 }
 
 static const struct net_device_ops e1000e_netdev_ops = {
@@ -4965,7 +4960,8 @@ static int __devinit e1000_probe(struct
 	u16 eeprom_data = 0;
 	u16 eeprom_apme_mask = E1000_EEPROM_APME;
 
-	e1000e_disable_l1aspm(pdev);
+	if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
+		e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
 
 	err = pci_enable_device_mem(pdev);
 	if (err)
@@ -5134,7 +5130,7 @@ static int __devinit e1000_probe(struct
 
 	e1000_eeprom_checks(adapter);
 
-	/* copy the MAC address out of the NVM */
+	/* copy the MAC address */
 	if (e1000e_read_mac_addr(&adapter->hw))
 		e_err("NVM Read Error while reading MAC address\n");
 
@@ -5326,7 +5322,7 @@ static struct pci_error_handlers e1000_e
 	.resume = e1000_io_resume,
 };
 
-static struct pci_device_id e1000_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/e100.c linux-libre-2.6.34-gnu1/drivers/net/e100.c
--- linux-libre-2.6.33-gnu1/drivers/net/e100.c	2013-05-03 12:08:10.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/e100.c	2013-05-03 09:47:36.000000000 -0400
@@ -166,6 +166,7 @@
 #include <linux/ethtool.h>
 #include <linux/string.h>
 #include <linux/firmware.h>
+#include <linux/rtnetlink.h>
 #include <asm/unaligned.h>
 
 
@@ -206,7 +207,7 @@ MODULE_PARM_DESC(use_io, "Force use of i
 #define INTEL_8255X_ETHERNET_DEVICE(device_id, ich) {\
 	PCI_VENDOR_ID_INTEL, device_id, PCI_ANY_ID, PCI_ANY_ID, \
 	PCI_CLASS_NETWORK_ETHERNET << 8, 0xFFFF00, ich }
-static struct pci_device_id e100_id_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(e100_id_table) = {
 	INTEL_8255X_ETHERNET_DEVICE(0x1029, 0),
 	INTEL_8255X_ETHERNET_DEVICE(0x1030, 0),
 	INTEL_8255X_ETHERNET_DEVICE(0x1031, 3),
@@ -1536,14 +1537,18 @@ static int e100_hw_init(struct nic *nic)
 static void e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb)
 {
 	struct net_device *netdev = nic->netdev;
-	struct dev_mc_list *list = netdev->mc_list;
-	u16 i, count = min(netdev->mc_count, E100_MAX_MULTICAST_ADDRS);
+	struct dev_mc_list *list;
+	u16 i, count = min(netdev_mc_count(netdev), E100_MAX_MULTICAST_ADDRS);
 
 	cb->command = cpu_to_le16(cb_multi);
 	cb->u.multi.count = cpu_to_le16(count * ETH_ALEN);
-	for (i = 0; list && i < count; i++, list = list->next)
-		memcpy(&cb->u.multi.addr[i*ETH_ALEN], &list->dmi_addr,
+	i = 0;
+	netdev_for_each_mc_addr(list, netdev) {
+		if (i == count)
+			break;
+		memcpy(&cb->u.multi.addr[i++ * ETH_ALEN], &list->dmi_addr,
 			ETH_ALEN);
+	}
 }
 
 static void e100_set_multicast_list(struct net_device *netdev)
@@ -1551,7 +1556,7 @@ static void e100_set_multicast_list(stru
 	struct nic *nic = netdev_priv(netdev);
 
 	DPRINTK(HW, DEBUG, "mc_count=%d, flags=0x%04X\n",
-		netdev->mc_count, netdev->flags);
+		netdev_mc_count(netdev), netdev->flags);
 
 	if (netdev->flags & IFF_PROMISC)
 		nic->flags |= promiscuous;
@@ -1559,7 +1564,7 @@ static void e100_set_multicast_list(stru
 		nic->flags &= ~promiscuous;
 
 	if (netdev->flags & IFF_ALLMULTI ||
-		netdev->mc_count > E100_MAX_MULTICAST_ADDRS)
+		netdev_mc_count(netdev) > E100_MAX_MULTICAST_ADDRS)
 		nic->flags |= multicast_all;
 	else
 		nic->flags &= ~multicast_all;
@@ -2260,8 +2265,13 @@ static void e100_tx_timeout_task(struct
 
 	DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n",
 		ioread8(&nic->csr->scb.status));
-	e100_down(netdev_priv(netdev));
-	e100_up(netdev_priv(netdev));
+
+	rtnl_lock();
+	if (netif_running(netdev)) {
+		e100_down(netdev_priv(netdev));
+		e100_up(netdev_priv(netdev));
+	}
+	rtnl_unlock();
 }
 
 static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
@@ -2853,7 +2863,7 @@ static int __devinit e100_probe(struct p
 	}
 	nic->cbs_pool = pci_pool_create(netdev->name,
 			   nic->pdev,
-			   nic->params.cbs.count * sizeof(struct cb),
+			   nic->params.cbs.max * sizeof(struct cb),
 			   sizeof(u32),
 			   0);
 	DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n",
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/eepro.c linux-libre-2.6.34-gnu1/drivers/net/eepro.c
--- linux-libre-2.6.33-gnu1/drivers/net/eepro.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/eepro.c	2010-05-16 17:17:36.000000000 -0400
@@ -137,7 +137,6 @@ static const char version[] =
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
@@ -1287,9 +1286,10 @@ set_multicast_list(struct net_device *de
 	struct eepro_local *lp = netdev_priv(dev);
 	short ioaddr = dev->base_addr;
 	unsigned short mode;
-	struct dev_mc_list *dmi=dev->mc_list;
+	struct dev_mc_list *dmi;
+	int mc_count = netdev_mc_count(dev);
 
-	if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || dev->mc_count > 63)
+	if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || mc_count > 63)
 	{
 		eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
 		mode = inb(ioaddr + REG2);
@@ -1299,7 +1299,7 @@ set_multicast_list(struct net_device *de
 		eepro_sw2bank0(ioaddr); /* Return to BANK 0 now */
 	}
 
-	else if (dev->mc_count==0 )
+	else if (mc_count == 0)
 	{
 		eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
 		mode = inb(ioaddr + REG2);
@@ -1329,12 +1329,10 @@ set_multicast_list(struct net_device *de
 		outw(MC_SETUP, ioaddr + IO_PORT);
 		outw(0, ioaddr + IO_PORT);
 		outw(0, ioaddr + IO_PORT);
-		outw(6*(dev->mc_count + 1), ioaddr + IO_PORT);
+		outw(6 * (mc_count + 1), ioaddr + IO_PORT);
 
-		for (i = 0; i < dev->mc_count; i++)
-		{
-			eaddrs=(unsigned short *)dmi->dmi_addr;
-			dmi=dmi->next;
+		netdev_for_each_mc_addr(dmi, dev) {
+			eaddrs = (unsigned short *) dmi->dmi_addr;
 			outw(*eaddrs++, ioaddr + IO_PORT);
 			outw(*eaddrs++, ioaddr + IO_PORT);
 			outw(*eaddrs++, ioaddr + IO_PORT);
@@ -1348,7 +1346,7 @@ set_multicast_list(struct net_device *de
 		outb(MC_SETUP, ioaddr);
 
 		/* Update the transmit queue */
-		i = lp->tx_end + XMT_HEADER + 6*(dev->mc_count + 1);
+		i = lp->tx_end + XMT_HEADER + 6 * (mc_count + 1);
 
 		if (lp->tx_start != lp->tx_end)
 		{
@@ -1380,8 +1378,8 @@ set_multicast_list(struct net_device *de
 					break;
 				} else if ((i & 0x0f) == 0x03)	{ /* MC-Done */
 					printk(KERN_DEBUG "%s: set Rx mode to %d address%s.\n",
-						dev->name, dev->mc_count,
-						dev->mc_count > 1 ? "es":"");
+						dev->name, mc_count,
+						mc_count > 1 ? "es":"");
 					break;
 				}
 			}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/eexpress.c linux-libre-2.6.34-gnu1/drivers/net/eexpress.c
--- linux-libre-2.6.33-gnu1/drivers/net/eexpress.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/eexpress.c	2010-05-16 17:17:36.000000000 -0400
@@ -111,7 +111,6 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/mca-legacy.h>
 #include <linux/spinlock.h>
 #include <linux/bitops.h>
@@ -1578,7 +1577,7 @@ static void eexp_setup_filter(struct net
 {
 	struct dev_mc_list *dmi;
 	unsigned short ioaddr = dev->base_addr;
-	int count = dev->mc_count;
+	int count = netdev_mc_count(dev);
 	int i;
 	if (count > 8) {
 		printk(KERN_INFO "%s: too many multicast addresses (%d)\n",
@@ -1588,23 +1587,19 @@ static void eexp_setup_filter(struct net
 
 	outw(CONF_NR_MULTICAST & ~31, ioaddr+SM_PTR);
 	outw(6*count, ioaddr+SHADOW(CONF_NR_MULTICAST));
-	for (i = 0, dmi = dev->mc_list; i < count; i++, dmi = dmi->next) {
-		unsigned short *data;
-		if (!dmi) {
-			printk(KERN_INFO "%s: too few multicast addresses\n", dev->name);
+	i = 0;
+	netdev_for_each_mc_addr(dmi, dev) {
+		unsigned short *data = (unsigned short *) dmi->dmi_addr;
+
+		if (i == count)
 			break;
-		}
-		if (dmi->dmi_addrlen != ETH_ALEN) {
-			printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name);
-			continue;
-		}
-		data = (unsigned short *)dmi->dmi_addr;
 		outw((CONF_MULTICAST+(6*i)) & ~31, ioaddr+SM_PTR);
 		outw(data[0], ioaddr+SHADOW(CONF_MULTICAST+(6*i)));
 		outw((CONF_MULTICAST+(6*i)+2) & ~31, ioaddr+SM_PTR);
 		outw(data[1], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+2));
 		outw((CONF_MULTICAST+(6*i)+4) & ~31, ioaddr+SM_PTR);
 		outw(data[2], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+4));
+		i++;
 	}
 }
 
@@ -1627,9 +1622,9 @@ eexp_set_multicast(struct net_device *de
         }
         if (!(dev->flags & IFF_PROMISC)) {
                 eexp_setup_filter(dev);
-                if (lp->old_mc_count != dev->mc_count) {
+                if (lp->old_mc_count != netdev_mc_count(dev)) {
                         kick = 1;
-                        lp->old_mc_count = dev->mc_count;
+                        lp->old_mc_count = netdev_mc_count(dev);
                 }
         }
         if (kick) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ehea/ehea_main.c linux-libre-2.6.34-gnu1/drivers/net/ehea/ehea_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/ehea/ehea_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ehea/ehea_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/udp.h>
 #include <linux/if.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/if_ether.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
@@ -1967,7 +1968,7 @@ static void ehea_set_multicast_list(stru
 {
 	struct ehea_port *port = netdev_priv(dev);
 	struct dev_mc_list *k_mcl_entry;
-	int ret, i;
+	int ret;
 
 	if (dev->flags & IFF_PROMISC) {
 		ehea_promiscuous(dev, 1);
@@ -1981,7 +1982,7 @@ static void ehea_set_multicast_list(stru
 	}
 	ehea_allmulti(dev, 0);
 
-	if (dev->mc_count) {
+	if (!netdev_mc_empty(dev)) {
 		ret = ehea_drop_multicast_list(dev);
 		if (ret) {
 			/* Dropping the current multicast list failed.
@@ -1990,15 +1991,14 @@ static void ehea_set_multicast_list(stru
 			ehea_allmulti(dev, 1);
 		}
 
-		if (dev->mc_count > port->adapter->max_mc_mac) {
+		if (netdev_mc_count(dev) > port->adapter->max_mc_mac) {
 			ehea_info("Mcast registration limit reached (0x%llx). "
 				  "Use ALLMULTI!",
 				  port->adapter->max_mc_mac);
 			goto out;
 		}
 
-		for (i = 0, k_mcl_entry = dev->mc_list; i < dev->mc_count; i++,
-			     k_mcl_entry = k_mcl_entry->next)
+		netdev_for_each_mc_addr(k_mcl_entry, dev)
 			ehea_add_multicast_entry(port, k_mcl_entry->dmi_addr);
 
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ehea/ehea_qmr.c linux-libre-2.6.34-gnu1/drivers/net/ehea/ehea_qmr.c
--- linux-libre-2.6.33-gnu1/drivers/net/ehea/ehea_qmr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ehea/ehea_qmr.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
  */
 
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include "ehea.h"
 #include "ehea_phyp.h"
 #include "ehea_qmr.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/enc28j60.c linux-libre-2.6.34-gnu1/drivers/net/enc28j60.c
--- linux-libre-2.6.33-gnu1/drivers/net/enc28j60.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/enc28j60.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -1413,7 +1412,7 @@ static void enc28j60_set_multicast_list(
 		if (netif_msg_link(priv))
 			dev_info(&dev->dev, "promiscuous mode\n");
 		priv->rxfilter = RXFILTER_PROMISC;
-	} else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count) {
+	} else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev)) {
 		if (netif_msg_link(priv))
 			dev_info(&dev->dev, "%smulticast mode\n",
 				(dev->flags & IFF_ALLMULTI) ? "all-" : "");
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/enic/enic.h linux-libre-2.6.34-gnu1/drivers/net/enic/enic.h
--- linux-libre-2.6.33-gnu1/drivers/net/enic/enic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/enic/enic.h	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,7 @@
 
 #define DRV_NAME		"enic"
 #define DRV_DESCRIPTION		"Cisco 10G Ethernet Driver"
-#define DRV_VERSION		"1.1.0.100"
+#define DRV_VERSION		"1.1.0.241a"
 #define DRV_COPYRIGHT		"Copyright 2008-2009 Cisco Systems, Inc"
 #define PFX			DRV_NAME ": "
 
@@ -89,9 +89,12 @@ struct enic {
 	spinlock_t devcmd_lock;
 	u8 mac_addr[ETH_ALEN];
 	u8 mc_addr[ENIC_MULTICAST_PERFECT_FILTERS][ETH_ALEN];
+	unsigned int flags;
 	unsigned int mc_count;
 	int csum_rx_enabled;
 	u32 port_mtu;
+	u32 rx_coalesce_usecs;
+	u32 tx_coalesce_usecs;
 
 	/* work queue cache line section */
 	____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX];
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/enic/enic_main.c linux-libre-2.6.34-gnu1/drivers/net/enic/enic_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/enic/enic_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/enic/enic_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,7 +51,7 @@
 #define PCI_DEVICE_ID_CISCO_VIC_ENET         0x0043  /* ethernet vnic */
 
 /* Supported devices */
-static struct pci_device_id enic_id_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(enic_id_table) = {
 	{ PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET) },
 	{ 0, }	/* end of table */
 };
@@ -261,6 +261,62 @@ static void enic_set_msglevel(struct net
 	enic->msg_enable = value;
 }
 
+static int enic_get_coalesce(struct net_device *netdev,
+	struct ethtool_coalesce *ecmd)
+{
+	struct enic *enic = netdev_priv(netdev);
+
+	ecmd->tx_coalesce_usecs = enic->tx_coalesce_usecs;
+	ecmd->rx_coalesce_usecs = enic->rx_coalesce_usecs;
+
+	return 0;
+}
+
+static int enic_set_coalesce(struct net_device *netdev,
+	struct ethtool_coalesce *ecmd)
+{
+	struct enic *enic = netdev_priv(netdev);
+	u32 tx_coalesce_usecs;
+	u32 rx_coalesce_usecs;
+
+	tx_coalesce_usecs = min_t(u32,
+		INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX),
+		ecmd->tx_coalesce_usecs);
+	rx_coalesce_usecs = min_t(u32,
+		INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX),
+		ecmd->rx_coalesce_usecs);
+
+	switch (vnic_dev_get_intr_mode(enic->vdev)) {
+	case VNIC_DEV_INTR_MODE_INTX:
+		if (tx_coalesce_usecs != rx_coalesce_usecs)
+			return -EINVAL;
+
+		vnic_intr_coalescing_timer_set(&enic->intr[ENIC_INTX_WQ_RQ],
+			INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
+		break;
+	case VNIC_DEV_INTR_MODE_MSI:
+		if (tx_coalesce_usecs != rx_coalesce_usecs)
+			return -EINVAL;
+
+		vnic_intr_coalescing_timer_set(&enic->intr[0],
+			INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
+		break;
+	case VNIC_DEV_INTR_MODE_MSIX:
+		vnic_intr_coalescing_timer_set(&enic->intr[ENIC_MSIX_WQ],
+			INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
+		vnic_intr_coalescing_timer_set(&enic->intr[ENIC_MSIX_RQ],
+			INTR_COALESCE_USEC_TO_HW(rx_coalesce_usecs));
+		break;
+	default:
+		break;
+	}
+
+	enic->tx_coalesce_usecs = tx_coalesce_usecs;
+	enic->rx_coalesce_usecs = rx_coalesce_usecs;
+
+	return 0;
+}
+
 static const struct ethtool_ops enic_ethtool_ops = {
 	.get_settings = enic_get_settings,
 	.get_drvinfo = enic_get_drvinfo,
@@ -278,6 +334,8 @@ static const struct ethtool_ops enic_eth
 	.set_sg = ethtool_op_set_sg,
 	.get_tso = ethtool_op_get_tso,
 	.set_tso = enic_set_tso,
+	.get_coalesce = enic_get_coalesce,
+	.set_coalesce = enic_set_coalesce,
 	.get_flags = ethtool_op_get_flags,
 	.set_flags = ethtool_op_set_flags,
 };
@@ -363,12 +421,12 @@ static void enic_mtu_check(struct enic *
 	u32 mtu = vnic_dev_mtu(enic->vdev);
 
 	if (mtu && mtu != enic->port_mtu) {
+		enic->port_mtu = mtu;
 		if (mtu < enic->netdev->mtu)
 			printk(KERN_WARNING PFX
 				"%s: interface MTU (%d) set higher "
 				"than switch port MTU (%d)\n",
 				enic->netdev->name, enic->netdev->mtu, mtu);
-		enic->port_mtu = mtu;
 	}
 }
 
@@ -673,7 +731,7 @@ static inline void enic_queue_wq_skb(str
 
 /* netif_tx_lock held, process context with BHs disabled, or BH */
 static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb,
-					      struct net_device *netdev)
+	struct net_device *netdev)
 {
 	struct enic *enic = netdev_priv(netdev);
 	struct vnic_wq *wq = &enic->wq[0];
@@ -764,15 +822,16 @@ static int enic_set_mac_addr(struct net_
 static void enic_set_multicast_list(struct net_device *netdev)
 {
 	struct enic *enic = netdev_priv(netdev);
-	struct dev_mc_list *list = netdev->mc_list;
+	struct dev_mc_list *list;
 	int directed = 1;
 	int multicast = (netdev->flags & IFF_MULTICAST) ? 1 : 0;
 	int broadcast = (netdev->flags & IFF_BROADCAST) ? 1 : 0;
 	int promisc = (netdev->flags & IFF_PROMISC) ? 1 : 0;
+	unsigned int mc_count = netdev_mc_count(netdev);
 	int allmulti = (netdev->flags & IFF_ALLMULTI) ||
-	    (netdev->mc_count > ENIC_MULTICAST_PERFECT_FILTERS);
+		       mc_count > ENIC_MULTICAST_PERFECT_FILTERS;
+	unsigned int flags = netdev->flags | (allmulti ? IFF_ALLMULTI : 0);
 	u8 mc_addr[ENIC_MULTICAST_PERFECT_FILTERS][ETH_ALEN];
-	unsigned int mc_count = netdev->mc_count;
 	unsigned int i, j;
 
 	if (mc_count > ENIC_MULTICAST_PERFECT_FILTERS)
@@ -780,8 +839,11 @@ static void enic_set_multicast_list(stru
 
 	spin_lock(&enic->devcmd_lock);
 
-	vnic_dev_packet_filter(enic->vdev, directed,
-		multicast, broadcast, promisc, allmulti);
+	if (enic->flags != flags) {
+		enic->flags = flags;
+		vnic_dev_packet_filter(enic->vdev, directed,
+			multicast, broadcast, promisc, allmulti);
+	}
 
 	/* Is there an easier way?  Trying to minimize to
 	 * calls to add/del multicast addrs.  We keep the
@@ -789,9 +851,11 @@ static void enic_set_multicast_list(stru
 	 * look for changes to add/del.
 	 */
 
-	for (i = 0; list && i < mc_count; i++) {
-		memcpy(mc_addr[i], list->dmi_addr, ETH_ALEN);
-		list = list->next;
+	i = 0;
+	netdev_for_each_mc_addr(list, netdev) {
+		if (i == mc_count)
+			break;
+		memcpy(mc_addr[i++], list->dmi_addr, ETH_ALEN);
 	}
 
 	for (i = 0; i < enic->mc_count; i++) {
@@ -1084,34 +1148,6 @@ static int enic_rq_service(struct vnic_d
 	return 0;
 }
 
-static void enic_rq_drop_buf(struct vnic_rq *rq,
-	struct cq_desc *cq_desc, struct vnic_rq_buf *buf,
-	int skipped, void *opaque)
-{
-	struct enic *enic = vnic_dev_priv(rq->vdev);
-	struct sk_buff *skb = buf->os_buf;
-
-	if (skipped)
-		return;
-
-	pci_unmap_single(enic->pdev, buf->dma_addr,
-		buf->len, PCI_DMA_FROMDEVICE);
-
-	dev_kfree_skb_any(skb);
-}
-
-static int enic_rq_service_drop(struct vnic_dev *vdev, struct cq_desc *cq_desc,
-	u8 type, u16 q_number, u16 completed_index, void *opaque)
-{
-	struct enic *enic = vnic_dev_priv(vdev);
-
-	vnic_rq_service(&enic->rq[q_number], cq_desc,
-		completed_index, VNIC_RQ_RETURN_DESC,
-		enic_rq_drop_buf, opaque);
-
-	return 0;
-}
-
 static int enic_poll(struct napi_struct *napi, int budget)
 {
 	struct enic *enic = container_of(napi, struct enic, napi);
@@ -1119,6 +1155,7 @@ static int enic_poll(struct napi_struct
 	unsigned int rq_work_to_do = budget;
 	unsigned int wq_work_to_do = -1; /* no limit */
 	unsigned int  work_done, rq_work_done, wq_work_done;
+	int err;
 
 	/* Service RQ (first) and WQ
 	 */
@@ -1142,16 +1179,19 @@ static int enic_poll(struct napi_struct
 			0 /* don't unmask intr */,
 			0 /* don't reset intr timer */);
 
-	if (rq_work_done > 0) {
+	err = vnic_rq_fill(&enic->rq[0], enic->rq_alloc_buf);
 
-		/* Replenish RQ
-		 */
+	/* Buffer allocation failed. Stay in polling
+	 * mode so we can try to fill the ring again.
+	 */
 
-		vnic_rq_fill(&enic->rq[0], enic->rq_alloc_buf);
+	if (err)
+		rq_work_done = rq_work_to_do;
 
-	} else {
+	if (rq_work_done < rq_work_to_do) {
 
-		/* If no work done, flush all LROs and exit polling
+		/* Some work done, but not enough to stay in polling,
+		 * flush all LROs and exit polling
 		 */
 
 		if (netdev->features & NETIF_F_LRO)
@@ -1170,6 +1210,7 @@ static int enic_poll_msix(struct napi_st
 	struct net_device *netdev = enic->netdev;
 	unsigned int work_to_do = budget;
 	unsigned int work_done;
+	int err;
 
 	/* Service RQ
 	 */
@@ -1177,25 +1218,30 @@ static int enic_poll_msix(struct napi_st
 	work_done = vnic_cq_service(&enic->cq[ENIC_CQ_RQ],
 		work_to_do, enic_rq_service, NULL);
 
-	if (work_done > 0) {
-
-		/* Replenish RQ
-		 */
-
-		vnic_rq_fill(&enic->rq[0], enic->rq_alloc_buf);
-
-		/* Return intr event credits for this polling
-		 * cycle.  An intr event is the completion of a
-		 * RQ packet.
-		 */
+	/* Return intr event credits for this polling
+	 * cycle.  An intr event is the completion of a
+	 * RQ packet.
+	 */
 
+	if (work_done > 0)
 		vnic_intr_return_credits(&enic->intr[ENIC_MSIX_RQ],
 			work_done,
 			0 /* don't unmask intr */,
 			0 /* don't reset intr timer */);
-	} else {
 
-		/* If no work done, flush all LROs and exit polling
+	err = vnic_rq_fill(&enic->rq[0], enic->rq_alloc_buf);
+
+	/* Buffer allocation failed. Stay in polling mode
+	 * so we can try to fill the ring again.
+	 */
+
+	if (err)
+		work_done = work_to_do;
+
+	if (work_done < work_to_do) {
+
+		/* Some work done, but not enough to stay in polling,
+		 * flush all LROs and exit polling
 		 */
 
 		if (netdev->features & NETIF_F_LRO)
@@ -1304,6 +1350,24 @@ static int enic_request_intr(struct enic
 	return err;
 }
 
+static void enic_synchronize_irqs(struct enic *enic)
+{
+	unsigned int i;
+
+	switch (vnic_dev_get_intr_mode(enic->vdev)) {
+	case VNIC_DEV_INTR_MODE_INTX:
+	case VNIC_DEV_INTR_MODE_MSI:
+		synchronize_irq(enic->pdev->irq);
+		break;
+	case VNIC_DEV_INTR_MODE_MSIX:
+		for (i = 0; i < enic->intr_count; i++)
+			synchronize_irq(enic->msix_entry[i].vector);
+		break;
+	default:
+		break;
+	}
+}
+
 static int enic_notify_set(struct enic *enic)
 {
 	int err;
@@ -1360,11 +1424,13 @@ static int enic_open(struct net_device *
 	}
 
 	for (i = 0; i < enic->rq_count; i++) {
-		err = vnic_rq_fill(&enic->rq[i], enic->rq_alloc_buf);
-		if (err) {
+		vnic_rq_fill(&enic->rq[i], enic->rq_alloc_buf);
+		/* Need at least one buffer on ring to get going */
+		if (vnic_rq_desc_used(&enic->rq[i]) == 0) {
 			printk(KERN_ERR PFX
 				"%s: Unable to alloc receive buffers.\n",
 				netdev->name);
+			err = -ENOMEM;
 			goto err_out_notify_unset;
 		}
 	}
@@ -1409,16 +1475,19 @@ static int enic_stop(struct net_device *
 	unsigned int i;
 	int err;
 
+	for (i = 0; i < enic->intr_count; i++)
+		vnic_intr_mask(&enic->intr[i]);
+
+	enic_synchronize_irqs(enic);
+
 	del_timer_sync(&enic->notify_timer);
 
 	spin_lock(&enic->devcmd_lock);
 	vnic_dev_disable(enic->vdev);
 	spin_unlock(&enic->devcmd_lock);
 	napi_disable(&enic->napi);
-	netif_stop_queue(netdev);
-
-	for (i = 0; i < enic->intr_count; i++)
-		vnic_intr_mask(&enic->intr[i]);
+	netif_carrier_off(netdev);
+	netif_tx_disable(netdev);
 
 	for (i = 0; i < enic->wq_count; i++) {
 		err = vnic_wq_disable(&enic->wq[i]);
@@ -1436,11 +1505,6 @@ static int enic_stop(struct net_device *
 	spin_unlock(&enic->devcmd_lock);
 	enic_free_intr(enic);
 
-	(void)vnic_cq_service(&enic->cq[ENIC_CQ_RQ],
-		-1, enic_rq_service_drop, NULL);
-	(void)vnic_cq_service(&enic->cq[ENIC_CQ_WQ],
-		-1, enic_wq_service, NULL);
-
 	for (i = 0; i < enic->wq_count; i++)
 		vnic_wq_clean(&enic->wq[i], enic_free_wq_buf);
 	for (i = 0; i < enic->rq_count; i++)
@@ -1762,7 +1826,8 @@ int enic_dev_init(struct enic *enic)
 	err = enic_set_intr_mode(enic);
 	if (err) {
 		printk(KERN_ERR PFX
-			"Failed to set intr mode, aborting.\n");
+			"Failed to set intr mode based on resource "
+			"counts and system capabilities, aborting.\n");
 		return err;
 	}
 
@@ -1986,6 +2051,9 @@ static int __devinit enic_probe(struct p
 		goto err_out_dev_deinit;
 	}
 
+	enic->tx_coalesce_usecs = enic->config.intr_timer_usec;
+	enic->rx_coalesce_usecs = enic->tx_coalesce_usecs;
+
 	netdev->netdev_ops = &enic_netdev_ops;
 	netdev->watchdog_timeo = 2 * HZ;
 	netdev->ethtool_ops = &enic_ethtool_ops;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/enic/enic_res.c linux-libre-2.6.34-gnu1/drivers/net/enic/enic_res.c
--- linux-libre-2.6.33-gnu1/drivers/net/enic/enic_res.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/enic/enic_res.c	2010-05-16 17:17:36.000000000 -0400
@@ -66,21 +66,21 @@ int enic_get_vnic_config(struct enic *en
 	GET_CONFIG(wq_desc_count);
 	GET_CONFIG(rq_desc_count);
 	GET_CONFIG(mtu);
-	GET_CONFIG(intr_timer);
 	GET_CONFIG(intr_timer_type);
 	GET_CONFIG(intr_mode);
+	GET_CONFIG(intr_timer_usec);
 
 	c->wq_desc_count =
 		min_t(u32, ENIC_MAX_WQ_DESCS,
 		max_t(u32, ENIC_MIN_WQ_DESCS,
 		c->wq_desc_count));
-	c->wq_desc_count &= 0xfffffff0; /* must be aligned to groups of 16 */
+	c->wq_desc_count &= 0xffffffe0; /* must be aligned to groups of 32 */
 
 	c->rq_desc_count =
 		min_t(u32, ENIC_MAX_RQ_DESCS,
 		max_t(u32, ENIC_MIN_RQ_DESCS,
 		c->rq_desc_count));
-	c->rq_desc_count &= 0xfffffff0; /* must be aligned to groups of 16 */
+	c->rq_desc_count &= 0xffffffe0; /* must be aligned to groups of 32 */
 
 	if (c->mtu == 0)
 		c->mtu = 1500;
@@ -88,15 +88,17 @@ int enic_get_vnic_config(struct enic *en
 		max_t(u16, ENIC_MIN_MTU,
 		c->mtu));
 
-	c->intr_timer = min_t(u16, VNIC_INTR_TIMER_MAX, c->intr_timer);
+	c->intr_timer_usec = min_t(u32,
+		INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX),
+		c->intr_timer_usec);
 
 	printk(KERN_INFO PFX "vNIC MAC addr %pM wq/rq %d/%d\n",
 		enic->mac_addr, c->wq_desc_count, c->rq_desc_count);
 	printk(KERN_INFO PFX "vNIC mtu %d csum tx/rx %d/%d tso/lro %d/%d "
-		"intr timer %d\n",
+		"intr timer %d usec\n",
 		c->mtu, ENIC_SETTING(enic, TXCSUM),
 		ENIC_SETTING(enic, RXCSUM), ENIC_SETTING(enic, TSO),
-		ENIC_SETTING(enic, LRO), c->intr_timer);
+		ENIC_SETTING(enic, LRO), c->intr_timer_usec);
 
 	return 0;
 }
@@ -303,7 +305,7 @@ void enic_init_vnic_resources(struct eni
 
 	for (i = 0; i < enic->intr_count; i++) {
 		vnic_intr_init(&enic->intr[i],
-			enic->config.intr_timer,
+			INTR_COALESCE_USEC_TO_HW(enic->config.intr_timer_usec),
 			enic->config.intr_timer_type,
 			mask_on_assertion);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/enic/vnic_dev.c linux-libre-2.6.34-gnu1/drivers/net/enic/vnic_dev.c
--- linux-libre-2.6.33-gnu1/drivers/net/enic/vnic_dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/enic/vnic_dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/if_ether.h>
+#include <linux/slab.h>
 
 #include "vnic_resource.h"
 #include "vnic_devcmd.h"
@@ -36,7 +37,6 @@ struct vnic_res {
 };
 
 #define VNIC_DEV_CAP_INIT	0x0001
-#define VNIC_DEV_CAP_PERBI	0x0002
 
 struct vnic_dev {
 	void *priv;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/enic/vnic_enet.h linux-libre-2.6.34-gnu1/drivers/net/enic/vnic_enet.h
--- linux-libre-2.6.33-gnu1/drivers/net/enic/vnic_enet.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/enic/vnic_enet.h	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,10 @@
 #ifndef _VNIC_ENIC_H_
 #define _VNIC_ENIC_H_
 
+/* Hardware intr coalesce timer is in units of 1.5us */
+#define INTR_COALESCE_USEC_TO_HW(usec) ((usec) * 2/3)
+#define INTR_COALESCE_HW_TO_USEC(usec) ((usec) * 3/2)
+
 /* Device-specific region: enet configuration */
 struct vnic_enet_config {
 	u32 flags;
@@ -30,6 +34,7 @@ struct vnic_enet_config {
 	u8 intr_timer_type;
 	u8 intr_mode;
 	char devname[16];
+	u32 intr_timer_usec;
 };
 
 #define VENETF_TSO		0x1	/* TSO enabled */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/enic/vnic_intr.c linux-libre-2.6.34-gnu1/drivers/net/enic/vnic_intr.c
--- linux-libre-2.6.33-gnu1/drivers/net/enic/vnic_intr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/enic/vnic_intr.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,12 +50,18 @@ int vnic_intr_alloc(struct vnic_dev *vde
 void vnic_intr_init(struct vnic_intr *intr, unsigned int coalescing_timer,
 	unsigned int coalescing_type, unsigned int mask_on_assertion)
 {
-	iowrite32(coalescing_timer, &intr->ctrl->coalescing_timer);
+	vnic_intr_coalescing_timer_set(intr, coalescing_timer);
 	iowrite32(coalescing_type, &intr->ctrl->coalescing_type);
 	iowrite32(mask_on_assertion, &intr->ctrl->mask_on_assertion);
 	iowrite32(0, &intr->ctrl->int_credits);
 }
 
+void vnic_intr_coalescing_timer_set(struct vnic_intr *intr,
+	unsigned int coalescing_timer)
+{
+	iowrite32(coalescing_timer, &intr->ctrl->coalescing_timer);
+}
+
 void vnic_intr_clean(struct vnic_intr *intr)
 {
 	iowrite32(0, &intr->ctrl->int_credits);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/enic/vnic_intr.h linux-libre-2.6.34-gnu1/drivers/net/enic/vnic_intr.h
--- linux-libre-2.6.33-gnu1/drivers/net/enic/vnic_intr.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/enic/vnic_intr.h	2010-05-16 17:17:36.000000000 -0400
@@ -61,6 +61,7 @@ static inline void vnic_intr_unmask(stru
 static inline void vnic_intr_mask(struct vnic_intr *intr)
 {
 	iowrite32(1, &intr->ctrl->mask);
+	(void)ioread32(&intr->ctrl->mask);
 }
 
 static inline void vnic_intr_return_credits(struct vnic_intr *intr,
@@ -101,6 +102,8 @@ int vnic_intr_alloc(struct vnic_dev *vde
 	unsigned int index);
 void vnic_intr_init(struct vnic_intr *intr, unsigned int coalescing_timer,
 	unsigned int coalescing_type, unsigned int mask_on_assertion);
+void vnic_intr_coalescing_timer_set(struct vnic_intr *intr,
+	unsigned int coalescing_timer);
 void vnic_intr_clean(struct vnic_intr *intr);
 
 #endif /* _VNIC_INTR_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/enic/vnic_nic.h linux-libre-2.6.34-gnu1/drivers/net/enic/vnic_nic.h
--- linux-libre-2.6.33-gnu1/drivers/net/enic/vnic_nic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/enic/vnic_nic.h	2010-05-16 17:17:36.000000000 -0400
@@ -41,12 +41,12 @@
 #define NIC_CFG_IG_VLAN_STRIP_EN_MASK_FIELD	1UL
 #define NIC_CFG_IG_VLAN_STRIP_EN_SHIFT		24
 
-#define NIC_CFG_RSS_HASH_TYPE_IPV4		(1 << 0)
-#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV4		(1 << 1)
-#define NIC_CFG_RSS_HASH_TYPE_IPV6		(1 << 2)
-#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6		(1 << 3)
-#define NIC_CFG_RSS_HASH_TYPE_IPV6_EX		(1 << 4)
-#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6_EX	(1 << 5)
+#define NIC_CFG_RSS_HASH_TYPE_IPV4		(1 << 1)
+#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV4		(1 << 2)
+#define NIC_CFG_RSS_HASH_TYPE_IPV6		(1 << 3)
+#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6		(1 << 4)
+#define NIC_CFG_RSS_HASH_TYPE_IPV6_EX		(1 << 5)
+#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6_EX	(1 << 6)
 
 static inline void vnic_set_nic_cfg(u32 *nic_cfg,
 	u8 rss_default_cpu, u8 rss_hash_type,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/enic/vnic_rq.c linux-libre-2.6.34-gnu1/drivers/net/enic/vnic_rq.c
--- linux-libre-2.6.33-gnu1/drivers/net/enic/vnic_rq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/enic/vnic_rq.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "vnic_dev.h"
 #include "vnic_rq.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/enic/vnic_wq.c linux-libre-2.6.34-gnu1/drivers/net/enic/vnic_wq.c
--- linux-libre-2.6.33-gnu1/drivers/net/enic/vnic_wq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/enic/vnic_wq.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "vnic_dev.h"
 #include "vnic_wq.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/epic100.c linux-libre-2.6.34-gnu1/drivers/net/epic100.c
--- linux-libre-2.6.33-gnu1/drivers/net/epic100.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/epic100.c	2010-05-16 17:17:36.000000000 -0400
@@ -73,7 +73,6 @@ static int rx_copybreak;
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
@@ -167,7 +166,7 @@ static const struct epic_chip_info pci_i
 };
 
 
-static struct pci_device_id epic_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(epic_pci_tbl) = {
 	{ 0x10B8, 0x0005, 0x1092, 0x0AB4, 0, 0, SMSC_83C170_0 },
 	{ 0x10B8, 0x0005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SMSC_83C170 },
 	{ 0x10B8, 0x0006, PCI_ANY_ID, PCI_ANY_ID,
@@ -1390,21 +1389,20 @@ static void set_rx_mode(struct net_devic
 		outl(0x002C, ioaddr + RxCtrl);
 		/* Unconditionally log net taps. */
 		memset(mc_filter, 0xff, sizeof(mc_filter));
-	} else if ((dev->mc_count > 0)  ||  (dev->flags & IFF_ALLMULTI)) {
+	} else if ((!netdev_mc_empty(dev)) || (dev->flags & IFF_ALLMULTI)) {
 		/* There is apparently a chip bug, so the multicast filter
 		   is never enabled. */
 		/* Too many to filter perfectly -- accept all multicasts. */
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		outl(0x000C, ioaddr + RxCtrl);
-	} else if (dev->mc_count == 0) {
+	} else if (netdev_mc_empty(dev)) {
 		outl(0x0004, ioaddr + RxCtrl);
 		return;
 	} else {					/* Never executed, for now. */
 		struct dev_mc_list *mclist;
 
 		memset(mc_filter, 0, sizeof(mc_filter));
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-			 i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			unsigned int bit_nr =
 				ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f;
 			mc_filter[bit_nr >> 3] |= (1 << bit_nr);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/eql.c linux-libre-2.6.34-gnu1/drivers/net/eql.c
--- linux-libre-2.6.33-gnu1/drivers/net/eql.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/eql.c	2010-05-16 17:17:36.000000000 -0400
@@ -115,6 +115,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/netdevice.h>
 #include <net/net_namespace.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/eth16i.c linux-libre-2.6.34-gnu1/drivers/net/eth16i.c
--- linux-libre-2.6.33-gnu1/drivers/net/eth16i.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/eth16i.c	2010-05-16 17:17:36.000000000 -0400
@@ -152,7 +152,6 @@ static char *version =
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -1359,7 +1358,7 @@ static void eth16i_multicast(struct net_
 {
 	int ioaddr = dev->base_addr;
 
-	if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
+	if (!netdev_mc_empty(dev) || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
 	{
 		outb(3, ioaddr + RECEIVE_MODE_REG);
 	} else {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ethoc.c linux-libre-2.6.34-gnu1/drivers/net/ethoc.c
--- linux-libre-2.6.33-gnu1/drivers/net/ethoc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ethoc.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/phy.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <net/ethoc.h>
 
 static int buffer_size = 0x8000; /* 32 KBytes */
@@ -755,7 +756,7 @@ static void ethoc_set_multicast_list(str
 {
 	struct ethoc *priv = netdev_priv(dev);
 	u32 mode = ethoc_read(priv, MODER);
-	struct dev_mc_list *mc = NULL;
+	struct dev_mc_list *mc;
 	u32 hash[2] = { 0, 0 };
 
 	/* set loopback mode if requested */
@@ -783,8 +784,8 @@ static void ethoc_set_multicast_list(str
 		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);
+		netdev_for_each_mc_addr(mc, dev) {
+			u32 crc = ether_crc(ETH_ALEN, mc->dmi_addr);
 			int bit = (crc >> 26) & 0x3f;
 			hash[bit >> 5] |= 1 << (bit & 0x1f);
 		}
@@ -904,7 +905,7 @@ static int ethoc_probe(struct platform_d
 	}
 
 	mmio = devm_request_mem_region(&pdev->dev, res->start,
-			res->end - res->start + 1, res->name);
+			resource_size(res), res->name);
 	if (!mmio) {
 		dev_err(&pdev->dev, "cannot request I/O memory space\n");
 		ret = -ENXIO;
@@ -917,7 +918,7 @@ static int ethoc_probe(struct platform_d
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	if (res) {
 		mem = devm_request_mem_region(&pdev->dev, res->start,
-			res->end - res->start + 1, res->name);
+			resource_size(res), res->name);
 		if (!mem) {
 			dev_err(&pdev->dev, "cannot request memory space\n");
 			ret = -ENXIO;
@@ -945,7 +946,7 @@ static int ethoc_probe(struct platform_d
 	priv->dma_alloc = 0;
 
 	priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr,
-			mmio->end - mmio->start + 1);
+			resource_size(mmio));
 	if (!priv->iobase) {
 		dev_err(&pdev->dev, "cannot remap I/O memory space\n");
 		ret = -ENXIO;
@@ -954,7 +955,7 @@ static int ethoc_probe(struct platform_d
 
 	if (netdev->mem_end) {
 		priv->membase = devm_ioremap_nocache(&pdev->dev,
-			netdev->mem_start, mem->end - mem->start + 1);
+			netdev->mem_start, resource_size(mem));
 		if (!priv->membase) {
 			dev_err(&pdev->dev, "cannot remap memory space\n");
 			ret = -ENXIO;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ewrk3.c linux-libre-2.6.34-gnu1/drivers/net/ewrk3.c
--- linux-libre-2.6.33-gnu1/drivers/net/ewrk3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ewrk3.c	2010-05-16 17:17:36.000000000 -0400
@@ -1169,7 +1169,7 @@ static void set_multicast_list(struct ne
 static void SetMulticastFilter(struct net_device *dev)
 {
 	struct ewrk3_private *lp = netdev_priv(dev);
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	u_long iobase = dev->base_addr;
 	int i;
 	char *addrs, bit, byte;
@@ -1213,9 +1213,8 @@ static void SetMulticastFilter(struct ne
 		}
 
 		/* Update table */
-		for (i = 0; i < dev->mc_count; i++) {	/* for each address in the list */
+		netdev_for_each_mc_addr(dmi, dev) {
 			addrs = dmi->dmi_addr;
-			dmi = dmi->next;
 			if ((*addrs & 0x01) == 1) {	/* multicast address? */
 				crc = ether_crc_le(ETH_ALEN, addrs);
 				hashcode = crc & ((1 << 9) - 1);	/* hashcode is 9 LSb of CRC */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/fealnx.c linux-libre-2.6.34-gnu1/drivers/net/fealnx.c
--- linux-libre-2.6.33-gnu1/drivers/net/fealnx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/fealnx.c	2010-05-16 17:17:36.000000000 -0400
@@ -74,7 +74,6 @@ static int full_duplex[MAX_UNITS] = { -1
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
@@ -1786,18 +1785,16 @@ static void __set_rx_mode(struct net_dev
 	if (dev->flags & IFF_PROMISC) {	/* Set promiscuous. */
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		rx_mode = CR_W_PROM | CR_W_AB | CR_W_AM;
-	} else if ((dev->mc_count > multicast_filter_limit) ||
+	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
 		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		rx_mode = CR_W_AB | CR_W_AM;
 	} else {
 		struct dev_mc_list *mclist;
-		int i;
 
 		memset(mc_filter, 0, sizeof(mc_filter));
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-		     i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			unsigned int bit;
 			bit = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F;
 			mc_filter[bit >> 5] |= (1 << bit);
@@ -1941,7 +1938,7 @@ static int netdev_close(struct net_devic
 	return 0;
 }
 
-static struct pci_device_id fealnx_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(fealnx_pci_tbl) = {
 	{0x1516, 0x0800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x1516, 0x0803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
 	{0x1516, 0x0891, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/fec.c linux-libre-2.6.34-gnu1/drivers/net/fec.c
--- linux-libre-2.6.33-gnu1/drivers/net/fec.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/fec.c	2010-05-16 17:17:36.000000000 -0400
@@ -1128,6 +1128,26 @@ static phy_info_t phy_info_dp83848= {
 	},
 };
 
+static phy_info_t phy_info_lan8700 = {
+	0x0007C0C,
+	"LAN8700",
+	(const phy_cmd_t []) { /* config */
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* startup */
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* act_int */
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* shutdown */
+		{ mk_mii_end, }
+	},
+};
 /* ------------------------------------------------------------------------- */
 
 static phy_info_t const * const phy_info[] = {
@@ -1137,6 +1157,7 @@ static phy_info_t const * const phy_info
 	&phy_info_am79c874,
 	&phy_info_ks8721bl,
 	&phy_info_dp83848,
+	&phy_info_lan8700,
 	NULL
 };
 
@@ -1554,7 +1575,7 @@ static void set_multicast_list(struct ne
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
 	struct dev_mc_list *dmi;
-	unsigned int i, j, bit, data, crc, tmp;
+	unsigned int i, bit, data, crc, tmp;
 	unsigned char hash;
 
 	if (dev->flags & IFF_PROMISC) {
@@ -1583,9 +1604,7 @@ static void set_multicast_list(struct ne
 	writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
 	writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
 
-	dmi = dev->mc_list;
-
-	for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) {
+	netdev_for_each_mc_addr(dmi, dev) {
 		/* Only support group multicast for now */
 		if (!(dmi->dmi_addr[0] & 1))
 			continue;
@@ -1634,7 +1653,7 @@ fec_set_mac_address(struct net_device *d
 		(dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24),
 		fep->hwp + FEC_ADDR_LOW);
 	writel((dev->dev_addr[5] << 16) | (dev->dev_addr[4] << 24),
-		fep + FEC_ADDR_HIGH);
+		fep->hwp + FEC_ADDR_HIGH);
 	return 0;
 }
 
@@ -1658,6 +1677,7 @@ static int fec_enet_init(struct net_devi
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
 	struct bufdesc *cbd_base;
+	struct bufdesc *bdp;
 	int i;
 
 	/* Allocate memory for buffer descriptors. */
@@ -1710,6 +1730,34 @@ static int fec_enet_init(struct net_devi
 	/* Set MII speed to 2.5 MHz */
 	fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
 					/ 2500000) / 2) & 0x3F) << 1;
+
+	/* Initialize the receive buffer descriptors. */
+	bdp = fep->rx_bd_base;
+	for (i = 0; i < RX_RING_SIZE; i++) {
+
+		/* Initialize the BD for every fragment in the page. */
+		bdp->cbd_sc = 0;
+		bdp++;
+	}
+
+	/* Set the last buffer to wrap */
+	bdp--;
+	bdp->cbd_sc |= BD_SC_WRAP;
+
+	/* ...and the same for transmit */
+	bdp = fep->tx_bd_base;
+	for (i = 0; i < TX_RING_SIZE; i++) {
+
+		/* Initialize the BD for every fragment in the page. */
+		bdp->cbd_sc = 0;
+		bdp->cbd_bufaddr = 0;
+		bdp++;
+	}
+
+	/* Set the last buffer to wrap */
+	bdp--;
+	bdp->cbd_sc |= BD_SC_WRAP;
+
 	fec_restart(dev, 0);
 
 	/* Queue up command to detect the PHY and initialize the
@@ -1730,7 +1778,6 @@ static void
 fec_restart(struct net_device *dev, int duplex)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
-	struct bufdesc *bdp;
 	int i;
 
 	/* Whack a reset.  We should wait for this. */
@@ -1768,33 +1815,6 @@ fec_restart(struct net_device *dev, int
 		}
 	}
 
-	/* Initialize the receive buffer descriptors. */
-	bdp = fep->rx_bd_base;
-	for (i = 0; i < RX_RING_SIZE; i++) {
-
-		/* Initialize the BD for every fragment in the page. */
-		bdp->cbd_sc = BD_ENET_RX_EMPTY;
-		bdp++;
-	}
-
-	/* Set the last buffer to wrap */
-	bdp--;
-	bdp->cbd_sc |= BD_SC_WRAP;
-
-	/* ...and the same for transmit */
-	bdp = fep->tx_bd_base;
-	for (i = 0; i < TX_RING_SIZE; i++) {
-
-		/* Initialize the BD for every fragment in the page. */
-		bdp->cbd_sc = 0;
-		bdp->cbd_bufaddr = 0;
-		bdp++;
-	}
-
-	/* Set the last buffer to wrap */
-	bdp--;
-	bdp->cbd_sc |= BD_SC_WRAP;
-
 	/* Enable MII mode */
 	if (duplex) {
 		/* MII enable / FD enable */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/fec_mpc52xx.c linux-libre-2.6.34-gnu1/drivers/net/fec_mpc52xx.c
--- linux-libre-2.6.33-gnu1/drivers/net/fec_mpc52xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/fec_mpc52xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
@@ -575,19 +576,16 @@ static void mpc52xx_fec_set_multicast_li
 			out_be32(&fec->gaddr2, 0xffffffff);
 		} else {
 			u32 crc;
-			int i;
 			struct dev_mc_list *dmi;
 			u32 gaddr1 = 0x00000000;
 			u32 gaddr2 = 0x00000000;
 
-			dmi = dev->mc_list;
-			for (i=0; i<dev->mc_count; i++) {
+			netdev_for_each_mc_addr(dmi, dev) {
 				crc = ether_crc_le(6, dmi->dmi_addr) >> 26;
 				if (crc >= 32)
 					gaddr1 |= 1 << (crc-32);
 				else
 					gaddr2 |= 1 << crc;
-				dmi = dmi->next;
 			}
 			out_be32(&fec->gaddr1, gaddr1);
 			out_be32(&fec->gaddr2, gaddr2);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/fec_mpc52xx_phy.c linux-libre-2.6.34-gnu1/drivers/net/fec_mpc52xx_phy.c
--- linux-libre-2.6.33-gnu1/drivers/net/fec_mpc52xx_phy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/fec_mpc52xx_phy.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/netdevice.h>
 #include <linux/phy.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 #include <linux/of_mdio.h>
 #include <asm/io.h>
 #include <asm/mpc52xx.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/forcedeth.c linux-libre-2.6.34-gnu1/drivers/net/forcedeth.c
--- linux-libre-2.6.33-gnu1/drivers/net/forcedeth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/forcedeth.c	2010-05-16 17:17:36.000000000 -0400
@@ -59,6 +59,7 @@
 #include <linux/init.h>
 #include <linux/if_vlan.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
@@ -3095,7 +3096,7 @@ static void nv_set_multicast(struct net_
 	} else {
 		pff |= NVREG_PFF_MYADDR;
 
-		if (dev->flags & IFF_ALLMULTI || dev->mc_list) {
+		if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev)) {
 			u32 alwaysOff[2];
 			u32 alwaysOn[2];
 
@@ -3105,8 +3106,7 @@ static void nv_set_multicast(struct net_
 			} else {
 				struct dev_mc_list *walk;
 
-				walk = dev->mc_list;
-				while (walk != NULL) {
+				netdev_for_each_mc_addr(walk, dev) {
 					u32 a, b;
 					a = le32_to_cpu(*(__le32 *) walk->dmi_addr);
 					b = le16_to_cpu(*(__le16 *) (&walk->dmi_addr[4]));
@@ -3114,7 +3114,6 @@ static void nv_set_multicast(struct net_
 					alwaysOff[0] &= ~a;
 					alwaysOn[1] &= b;
 					alwaysOff[1] &= ~b;
-					walk = walk->next;
 				}
 			}
 			addr[0] = alwaysOn[0];
@@ -5900,7 +5899,7 @@ static int __devinit nv_probe(struct pci
 	/* Limit the number of tx's outstanding for hw bug */
 	if (id->driver_data & DEV_NEED_TX_LIMIT) {
 		np->tx_limit = 1;
-		if ((id->driver_data & DEV_NEED_TX_LIMIT2) &&
+		if (((id->driver_data & DEV_NEED_TX_LIMIT2) == DEV_NEED_TX_LIMIT2) &&
 		    pci_dev->revision >= 0xA2)
 			np->tx_limit = 0;
 	}
@@ -6198,7 +6197,7 @@ static void nv_shutdown(struct pci_dev *
 #define nv_resume NULL
 #endif /* CONFIG_PM */
 
-static struct pci_device_id pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(pci_tbl) = {
 	{	/* nForce Ethernet Controller */
 		PCI_DEVICE(0x10DE, 0x01C3),
 		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/fs_enet/fs_enet.h linux-libre-2.6.34-gnu1/drivers/net/fs_enet/fs_enet.h
--- linux-libre-2.6.33-gnu1/drivers/net/fs_enet/fs_enet.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/fs_enet/fs_enet.h	2010-05-16 17:17:36.000000000 -0400
@@ -13,9 +13,56 @@
 
 #ifdef CONFIG_CPM1
 #include <asm/cpm1.h>
+#endif
+
+#if defined(CONFIG_FS_ENET_HAS_FEC)
+#include <asm/cpm.h>
+
+#if defined(CONFIG_FS_ENET_MPC5121_FEC)
+/* MPC5121 FEC has different register layout */
+struct fec {
+	u32 fec_reserved0;
+	u32 fec_ievent;			/* Interrupt event reg */
+	u32 fec_imask;			/* Interrupt mask reg */
+	u32 fec_reserved1;
+	u32 fec_r_des_active;		/* Receive descriptor reg */
+	u32 fec_x_des_active;		/* Transmit descriptor reg */
+	u32 fec_reserved2[3];
+	u32 fec_ecntrl;			/* Ethernet control reg */
+	u32 fec_reserved3[6];
+	u32 fec_mii_data;		/* MII manage frame reg */
+	u32 fec_mii_speed;		/* MII speed control reg */
+	u32 fec_reserved4[7];
+	u32 fec_mib_ctrlstat;		/* MIB control/status reg */
+	u32 fec_reserved5[7];
+	u32 fec_r_cntrl;		/* Receive control reg */
+	u32 fec_reserved6[15];
+	u32 fec_x_cntrl;		/* Transmit Control reg */
+	u32 fec_reserved7[7];
+	u32 fec_addr_low;		/* Low 32bits MAC address */
+	u32 fec_addr_high;		/* High 16bits MAC address */
+	u32 fec_opd;			/* Opcode + Pause duration */
+	u32 fec_reserved8[10];
+	u32 fec_hash_table_high;	/* High 32bits hash table */
+	u32 fec_hash_table_low;		/* Low 32bits hash table */
+	u32 fec_grp_hash_table_high;	/* High 32bits hash table */
+	u32 fec_grp_hash_table_low;	/* Low 32bits hash table */
+	u32 fec_reserved9[7];
+	u32 fec_x_wmrk;			/* FIFO transmit water mark */
+	u32 fec_reserved10;
+	u32 fec_r_bound;		/* FIFO receive bound reg */
+	u32 fec_r_fstart;		/* FIFO receive start reg */
+	u32 fec_reserved11[11];
+	u32 fec_r_des_start;		/* Receive descriptor ring */
+	u32 fec_x_des_start;		/* Transmit descriptor ring */
+	u32 fec_r_buff_size;		/* Maximum receive buff size */
+	u32 fec_reserved12[26];
+	u32 fec_dma_control;		/* DMA Endian and other ctrl */
+};
+#endif
 
 struct fec_info {
-	fec_t __iomem *fecp;
+	struct fec __iomem *fecp;
 	u32 mii_speed;
 };
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/fs_enet/fs_enet-main.c linux-libre-2.6.34-gnu1/drivers/net/fs_enet/fs_enet-main.c
--- linux-libre-2.6.33-gnu1/drivers/net/fs_enet/fs_enet-main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/fs_enet/fs_enet-main.c	2010-05-16 17:17:36.000000000 -0400
@@ -108,9 +108,7 @@ static int fs_enet_rx_napi(struct napi_s
 		 * the last indicator should be set.
 		 */
 		if ((sc & BD_ENET_RX_LAST) == 0)
-			printk(KERN_WARNING DRV_MODULE_NAME
-			       ": %s rcv is not +last\n",
-			       dev->name);
+			dev_warn(fep->dev, "rcv is not +last\n");
 
 		/*
 		 * Check for errors.
@@ -178,9 +176,8 @@ static int fs_enet_rx_napi(struct napi_s
 				received++;
 				netif_receive_skb(skb);
 			} else {
-				printk(KERN_WARNING DRV_MODULE_NAME
-				       ": %s Memory squeeze, dropping packet.\n",
-				       dev->name);
+				dev_warn(fep->dev,
+					 "Memory squeeze, dropping packet.\n");
 				fep->stats.rx_dropped++;
 				skbn = skb;
 			}
@@ -242,9 +239,7 @@ static int fs_enet_rx_non_napi(struct ne
 		 * the last indicator should be set.
 		 */
 		if ((sc & BD_ENET_RX_LAST) == 0)
-			printk(KERN_WARNING DRV_MODULE_NAME
-			       ": %s rcv is not +last\n",
-			       dev->name);
+			dev_warn(fep->dev, "rcv is not +last\n");
 
 		/*
 		 * Check for errors.
@@ -313,9 +308,8 @@ static int fs_enet_rx_non_napi(struct ne
 				received++;
 				netif_rx(skb);
 			} else {
-				printk(KERN_WARNING DRV_MODULE_NAME
-				       ": %s Memory squeeze, dropping packet.\n",
-				       dev->name);
+				dev_warn(fep->dev,
+					 "Memory squeeze, dropping packet.\n");
 				fep->stats.rx_dropped++;
 				skbn = skb;
 			}
@@ -388,10 +382,10 @@ static void fs_enet_tx(struct net_device
 		} else
 			fep->stats.tx_packets++;
 
-		if (sc & BD_ENET_TX_READY)
-			printk(KERN_WARNING DRV_MODULE_NAME
-			       ": %s HEY! Enet xmit interrupt and TX_READY.\n",
-			       dev->name);
+		if (sc & BD_ENET_TX_READY) {
+			dev_warn(fep->dev,
+				 "HEY! Enet xmit interrupt and TX_READY.\n");
+		}
 
 		/*
 		 * Deferred means some collisions occurred during transmit,
@@ -511,9 +505,8 @@ void fs_init_bds(struct net_device *dev)
 	for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) {
 		skb = dev_alloc_skb(ENET_RX_FRSIZE);
 		if (skb == NULL) {
-			printk(KERN_WARNING DRV_MODULE_NAME
-			       ": %s Memory squeeze, unable to allocate skb\n",
-			       dev->name);
+			dev_warn(fep->dev,
+				 "Memory squeeze, unable to allocate skb\n");
 			break;
 		}
 		skb_align(skb, ENET_RX_ALIGN);
@@ -587,6 +580,40 @@ void fs_cleanup_bds(struct net_device *d
 
 /**********************************************************************************/
 
+#ifdef CONFIG_FS_ENET_MPC5121_FEC
+/*
+ * MPC5121 FEC requeries 4-byte alignment for TX data buffer!
+ */
+static struct sk_buff *tx_skb_align_workaround(struct net_device *dev,
+					       struct sk_buff *skb)
+{
+	struct sk_buff *new_skb;
+	struct fs_enet_private *fep = netdev_priv(dev);
+
+	/* Alloc new skb */
+	new_skb = dev_alloc_skb(skb->len + 4);
+	if (!new_skb) {
+		if (net_ratelimit()) {
+			dev_warn(fep->dev,
+				 "Memory squeeze, dropping tx packet.\n");
+		}
+		return NULL;
+	}
+
+	/* Make sure new skb is properly aligned */
+	skb_align(new_skb, 4);
+
+	/* Copy data to new skb ... */
+	skb_copy_from_linear_data(skb, new_skb->data, skb->len);
+	skb_put(new_skb, skb->len);
+
+	/* ... and free an old one */
+	dev_kfree_skb_any(skb);
+
+	return new_skb;
+}
+#endif
+
 static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
@@ -595,6 +622,19 @@ static int fs_enet_start_xmit(struct sk_
 	u16 sc;
 	unsigned long flags;
 
+#ifdef CONFIG_FS_ENET_MPC5121_FEC
+	if (((unsigned long)skb->data) & 0x3) {
+		skb = tx_skb_align_workaround(dev, skb);
+		if (!skb) {
+			/*
+			 * We have lost packet due to memory allocation error
+			 * in tx_skb_align_workaround(). Hopefully original
+			 * skb is still valid, so try transmit it later.
+			 */
+			return NETDEV_TX_BUSY;
+		}
+	}
+#endif
 	spin_lock_irqsave(&fep->tx_lock, flags);
 
 	/*
@@ -610,8 +650,7 @@ static int fs_enet_start_xmit(struct sk_
 		 * Ooops.  All transmit buffers are full.  Bail out.
 		 * This should not happen, since the tx queue should be stopped.
 		 */
-		printk(KERN_WARNING DRV_MODULE_NAME
-		       ": %s tx queue full!.\n", dev->name);
+		dev_warn(fep->dev, "tx queue full!.\n");
 		return NETDEV_TX_BUSY;
 	}
 
@@ -788,8 +827,7 @@ static int fs_enet_open(struct net_devic
 	r = request_irq(fep->interrupt, fs_enet_interrupt, IRQF_SHARED,
 			"fs_enet-mac", dev);
 	if (r != 0) {
-		printk(KERN_ERR DRV_MODULE_NAME
-		       ": %s Could not allocate FS_ENET IRQ!", dev->name);
+		dev_err(fep->dev, "Could not allocate FS_ENET IRQ!");
 		if (fep->fpi->use_napi)
 			napi_disable(&fep->napi);
 		return -EINVAL;
@@ -1053,7 +1091,7 @@ static int __devinit fs_enet_probe(struc
 	if (ret)
 		goto out_free_bd;
 
-	printk(KERN_INFO "%s: fs_enet: %pM\n", ndev->name, ndev->dev_addr);
+	pr_info("%s: fs_enet: %pM\n", ndev->name, ndev->dev_addr);
 
 	return 0;
 
@@ -1103,11 +1141,18 @@ static struct of_device_id fs_enet_match
 	},
 #endif
 #ifdef CONFIG_FS_ENET_HAS_FEC
+#ifdef CONFIG_FS_ENET_MPC5121_FEC
+	{
+		.compatible = "fsl,mpc5121-fec",
+		.data = (void *)&fs_fec_ops,
+	},
+#else
 	{
 		.compatible = "fsl,pq1-fec-enet",
 		.data = (void *)&fs_fec_ops,
 	},
 #endif
+#endif
 	{}
 };
 MODULE_DEVICE_TABLE(of, fs_enet_match);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/fs_enet/Kconfig linux-libre-2.6.34-gnu1/drivers/net/fs_enet/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/net/fs_enet/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/fs_enet/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,9 +1,13 @@
 config FS_ENET
        tristate "Freescale Ethernet Driver"
-       depends on CPM1 || CPM2
+       depends on CPM1 || CPM2 || PPC_MPC512x
        select MII
        select PHYLIB
 
+config FS_ENET_MPC5121_FEC
+	def_bool y if (FS_ENET && PPC_MPC512x)
+	select FS_ENET_HAS_FEC
+
 config FS_ENET_HAS_SCC
 	bool "Chip has an SCC usable for ethernet"
 	depends on FS_ENET && (CPM1 || CPM2)
@@ -16,13 +20,13 @@ config FS_ENET_HAS_FCC
 
 config FS_ENET_HAS_FEC
 	bool "Chip has an FEC usable for ethernet"
-	depends on FS_ENET && CPM1
+	depends on FS_ENET && (CPM1 || FS_ENET_MPC5121_FEC)
 	select FS_ENET_MDIO_FEC
 	default y
 
 config FS_ENET_MDIO_FEC
 	tristate "MDIO driver for FEC"
-	depends on FS_ENET && CPM1
+	depends on FS_ENET && (CPM1 || FS_ENET_MPC5121_FEC)
 
 config FS_ENET_MDIO_FCC
 	tristate "MDIO driver for FCC"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/fs_enet/mac-fcc.c linux-libre-2.6.34-gnu1/drivers/net/fs_enet/mac-fcc.c
--- linux-libre-2.6.33-gnu1/drivers/net/fs_enet/mac-fcc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/fs_enet/mac-fcc.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
@@ -34,6 +33,7 @@
 #include <linux/platform_device.h>
 #include <linux/phy.h>
 #include <linux/of_device.h>
+#include <linux/gfp.h>
 
 #include <asm/immap_cpm2.h>
 #include <asm/mpc8260.h>
@@ -218,7 +218,7 @@ static void set_multicast_finish(struct
 
 	/* if all multi or too many multicasts; just enable all */
 	if ((dev->flags & IFF_ALLMULTI) != 0 ||
-	    dev->mc_count > FCC_MAX_MULTICAST_ADDRS) {
+	    netdev_mc_count(dev) > FCC_MAX_MULTICAST_ADDRS) {
 
 		W32(ep, fen_gaddrh, 0xffffffff);
 		W32(ep, fen_gaddrl, 0xffffffff);
@@ -235,7 +235,7 @@ static void set_multicast_list(struct ne
 
 	if ((dev->flags & IFF_PROMISC) == 0) {
 		set_multicast_start(dev);
-		for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next)
+		netdev_for_each_mc_addr(pmc, dev)
 			set_multicast_one(dev, pmc->dmi_addr);
 		set_multicast_finish(dev);
 	} else
@@ -476,8 +476,9 @@ static void clear_int_events(struct net_
 
 static void ev_error(struct net_device *dev, u32 int_events)
 {
-	printk(KERN_WARNING DRV_MODULE_NAME
-	       ": %s FS_ENET ERROR(s) 0x%x\n", dev->name, int_events);
+	struct fs_enet_private *fep = netdev_priv(dev);
+
+	dev_warn(fep->dev, "FS_ENET ERROR(s) 0x%x\n", int_events);
 }
 
 static int get_regs(struct net_device *dev, void *p, int *sizep)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/fs_enet/mac-fec.c linux-libre-2.6.34-gnu1/drivers/net/fs_enet/mac-fec.c
--- linux-libre-2.6.33-gnu1/drivers/net/fs_enet/mac-fec.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/fs_enet/mac-fec.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
@@ -33,6 +32,7 @@
 #include <linux/fs.h>
 #include <linux/platform_device.h>
 #include <linux/of_device.h>
+#include <linux/gfp.h>
 
 #include <asm/irq.h>
 #include <asm/uaccess.h>
@@ -80,7 +80,7 @@
  */
 #define FEC_RESET_DELAY		50
 
-static int whack_reset(fec_t __iomem *fecp)
+static int whack_reset(struct fec __iomem *fecp)
 {
 	int i;
 
@@ -168,7 +168,7 @@ static void cleanup_data(struct net_devi
 static void set_promiscuous_mode(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct fec __iomem *fecp = fep->fec.fecp;
 
 	FS(fecp, r_cntrl, FEC_RCNTRL_PROM);
 }
@@ -216,11 +216,11 @@ static void set_multicast_one(struct net
 static void set_multicast_finish(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct fec __iomem *fecp = fep->fec.fecp;
 
 	/* if all multi or too many multicasts; just enable all */
 	if ((dev->flags & IFF_ALLMULTI) != 0 ||
-	    dev->mc_count > FEC_MAX_MULTICAST_ADDRS) {
+	    netdev_mc_count(dev) > FEC_MAX_MULTICAST_ADDRS) {
 		fep->fec.hthi = 0xffffffffU;
 		fep->fec.htlo = 0xffffffffU;
 	}
@@ -236,7 +236,7 @@ static void set_multicast_list(struct ne
 
 	if ((dev->flags & IFF_PROMISC) == 0) {
 		set_multicast_start(dev);
-		for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next)
+		netdev_for_each_mc_addr(pmc, dev)
 			set_multicast_one(dev, pmc->dmi_addr);
 		set_multicast_finish(dev);
 	} else
@@ -246,7 +246,7 @@ static void set_multicast_list(struct ne
 static void restart(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct fec __iomem *fecp = fep->fec.fecp;
 	const struct fs_platform_info *fpi = fep->fpi;
 	dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
 	int r;
@@ -257,8 +257,7 @@ static void restart(struct net_device *d
 
 	r = whack_reset(fep->fec.fecp);
 	if (r != 0)
-		printk(KERN_ERR DRV_MODULE_NAME
-				": %s FEC Reset FAILED!\n", dev->name);
+		dev_err(fep->dev, "FEC Reset FAILED!\n");
 	/*
 	 * Set station address.
 	 */
@@ -281,7 +280,11 @@ static void restart(struct net_device *d
 	 * Set maximum receive buffer size.
 	 */
 	FW(fecp, r_buff_size, PKT_MAXBLR_SIZE);
+#ifdef CONFIG_FS_ENET_MPC5121_FEC
+	FW(fecp, r_cntrl, PKT_MAXBUF_SIZE << 16);
+#else
 	FW(fecp, r_hash, PKT_MAXBUF_SIZE);
+#endif
 
 	/* get physical address */
 	rx_bd_base_phys = fep->ring_mem_addr;
@@ -298,7 +301,11 @@ static void restart(struct net_device *d
 	/*
 	 * Enable big endian and don't care about SDMA FC.
 	 */
+#ifdef CONFIG_FS_ENET_MPC5121_FEC
+	FS(fecp, dma_control, 0xC0000000);
+#else
 	FW(fecp, fun_code, 0x78000000);
+#endif
 
 	/*
 	 * Set MII speed.
@@ -309,9 +316,17 @@ static void restart(struct net_device *d
 	 * Clear any outstanding interrupt.
 	 */
 	FW(fecp, ievent, 0xffc0);
+#ifndef CONFIG_FS_ENET_MPC5121_FEC
 	FW(fecp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29);
 
 	FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE);	/* MII enable */
+#else
+	/*
+	 * Only set MII mode - do not touch maximum frame length
+	 * configured before.
+	 */
+	FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE);
+#endif
 	/*
 	 * adjust to duplex mode
 	 */
@@ -340,7 +355,7 @@ static void stop(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
 	const struct fs_platform_info *fpi = fep->fpi;
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct fec __iomem *fecp = fep->fec.fecp;
 
 	struct fec_info* feci= fep->phydev->bus->priv;
 
@@ -355,9 +370,7 @@ static void stop(struct net_device *dev)
 		udelay(1);
 
 	if (i == FEC_RESET_DELAY)
-		printk(KERN_WARNING DRV_MODULE_NAME
-		       ": %s FEC timeout on graceful transmit stop\n",
-		       dev->name);
+		dev_warn(fep->dev, "FEC timeout on graceful transmit stop\n");
 	/*
 	 * Disable FEC. Let only MII interrupts.
 	 */
@@ -378,7 +391,7 @@ static void stop(struct net_device *dev)
 static void napi_clear_rx_event(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct fec __iomem *fecp = fep->fec.fecp;
 
 	FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK);
 }
@@ -386,7 +399,7 @@ static void napi_clear_rx_event(struct n
 static void napi_enable_rx(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct fec __iomem *fecp = fep->fec.fecp;
 
 	FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
 }
@@ -394,7 +407,7 @@ static void napi_enable_rx(struct net_de
 static void napi_disable_rx(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct fec __iomem *fecp = fep->fec.fecp;
 
 	FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
 }
@@ -402,7 +415,7 @@ static void napi_disable_rx(struct net_d
 static void rx_bd_done(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct fec __iomem *fecp = fep->fec.fecp;
 
 	FW(fecp, r_des_active, 0x01000000);
 }
@@ -410,7 +423,7 @@ static void rx_bd_done(struct net_device
 static void tx_kickstart(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct fec __iomem *fecp = fep->fec.fecp;
 
 	FW(fecp, x_des_active, 0x01000000);
 }
@@ -418,7 +431,7 @@ static void tx_kickstart(struct net_devi
 static u32 get_int_events(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct fec __iomem *fecp = fep->fec.fecp;
 
 	return FR(fecp, ievent) & FR(fecp, imask);
 }
@@ -426,32 +439,33 @@ static u32 get_int_events(struct net_dev
 static void clear_int_events(struct net_device *dev, u32 int_events)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t __iomem *fecp = fep->fec.fecp;
+	struct fec __iomem *fecp = fep->fec.fecp;
 
 	FW(fecp, ievent, int_events);
 }
 
 static void ev_error(struct net_device *dev, u32 int_events)
 {
-	printk(KERN_WARNING DRV_MODULE_NAME
-	       ": %s FEC ERROR(s) 0x%x\n", dev->name, int_events);
+	struct fs_enet_private *fep = netdev_priv(dev);
+
+	dev_warn(fep->dev, "FEC ERROR(s) 0x%x\n", int_events);
 }
 
 static int get_regs(struct net_device *dev, void *p, int *sizep)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
 
-	if (*sizep < sizeof(fec_t))
+	if (*sizep < sizeof(struct fec))
 		return -EINVAL;
 
-	memcpy_fromio(p, fep->fec.fecp, sizeof(fec_t));
+	memcpy_fromio(p, fep->fec.fecp, sizeof(struct fec));
 
 	return 0;
 }
 
 static int get_regs_len(struct net_device *dev)
 {
-	return sizeof(fec_t);
+	return sizeof(struct fec);
 }
 
 static void tx_restart(struct net_device *dev)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/fs_enet/mac-scc.c linux-libre-2.6.34-gnu1/drivers/net/fs_enet/mac-scc.c
--- linux-libre-2.6.33-gnu1/drivers/net/fs_enet/mac-scc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/fs_enet/mac-scc.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
@@ -213,7 +212,7 @@ static void set_multicast_finish(struct
 
 	/* if all multi or too many multicasts; just enable all */
 	if ((dev->flags & IFF_ALLMULTI) != 0 ||
-	    dev->mc_count > SCC_MAX_MULTICAST_ADDRS) {
+	    netdev_mc_count(dev) > SCC_MAX_MULTICAST_ADDRS) {
 
 		W16(ep, sen_gaddr1, 0xffff);
 		W16(ep, sen_gaddr2, 0xffff);
@@ -228,7 +227,7 @@ static void set_multicast_list(struct ne
 
 	if ((dev->flags & IFF_PROMISC) == 0) {
 		set_multicast_start(dev);
-		for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next)
+		netdev_for_each_mc_addr(pmc, dev)
 			set_multicast_one(dev, pmc->dmi_addr);
 		set_multicast_finish(dev);
 	} else
@@ -367,9 +366,7 @@ static void stop(struct net_device *dev)
 		udelay(1);
 
 	if (i == SCC_RESET_DELAY)
-		printk(KERN_WARNING DRV_MODULE_NAME
-		       ": %s SCC timeout on graceful transmit stop\n",
-		       dev->name);
+		dev_warn(fep->dev, "SCC timeout on graceful transmit stop\n");
 
 	W16(sccp, scc_sccm, 0);
 	C32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
@@ -429,8 +426,9 @@ static void clear_int_events(struct net_
 
 static void ev_error(struct net_device *dev, u32 int_events)
 {
-	printk(KERN_WARNING DRV_MODULE_NAME
-	       ": %s SCC ERROR(s) 0x%x\n", dev->name, int_events);
+	struct fs_enet_private *fep = netdev_priv(dev);
+
+	dev_warn(fep->dev, "SCC ERROR(s) 0x%x\n", int_events);
 }
 
 static int get_regs(struct net_device *dev, void *p, int *sizep)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/fs_enet/mii-fec.c linux-libre-2.6.34-gnu1/drivers/net/fs_enet/mii-fec.c
--- linux-libre-2.6.33-gnu1/drivers/net/fs_enet/mii-fec.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/fs_enet/mii-fec.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,7 +52,7 @@
 static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
 {
 	struct fec_info* fec = bus->priv;
-	fec_t __iomem *fecp = fec->fecp;
+	struct fec __iomem *fecp = fec->fecp;
 	int i, ret = -1;
 
 	BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0);
@@ -75,7 +75,7 @@ static int fs_enet_fec_mii_read(struct m
 static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val)
 {
 	struct fec_info* fec = bus->priv;
-	fec_t __iomem *fecp = fec->fecp;
+	struct fec __iomem *fecp = fec->fecp;
 	int i;
 
 	/* this must never happen */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/fsl_pq_mdio.c linux-libre-2.6.34-gnu1/drivers/net/fsl_pq_mdio.c
--- linux-libre-2.6.33-gnu1/drivers/net/fsl_pq_mdio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/fsl_pq_mdio.c	2010-05-16 17:17:36.000000000 -0400
@@ -205,8 +205,6 @@ static int fsl_pq_mdio_find_free(struct
 static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct device_node *np)
 {
 	struct gfar __iomem *enet_regs;
-	u32 __iomem *ioremap_tbipa;
-	u64 addr, size;
 
 	/*
 	 * This is mildly evil, but so is our hardware for doing this.
@@ -220,9 +218,7 @@ static u32 __iomem *get_gfar_tbipa(struc
 		return &enet_regs->tbipa;
 	} else if (of_device_is_compatible(np, "fsl,etsec2-mdio") ||
 			of_device_is_compatible(np, "fsl,etsec2-tbi")) {
-		addr = of_translate_address(np, of_get_address(np, 1, &size, NULL));
-		ioremap_tbipa = ioremap(addr, size);
-		return ioremap_tbipa;
+		return of_iomap(np, 1);
 	} else
 		return NULL;
 }
@@ -279,6 +275,7 @@ static int fsl_pq_mdio_probe(struct of_d
 	u32 __iomem *tbipa;
 	struct mii_bus *new_bus;
 	int tbiaddr = -1;
+	const u32 *addrp;
 	u64 addr = 0, size = 0;
 	int err = 0;
 
@@ -297,8 +294,19 @@ static int fsl_pq_mdio_probe(struct of_d
 	new_bus->priv = priv;
 	fsl_pq_mdio_bus_name(new_bus->id, np);
 
+	addrp = of_get_address(np, 0, &size, NULL);
+	if (!addrp) {
+		err = -EINVAL;
+		goto err_free_bus;
+	}
+
 	/* Set the PHY base address */
-	addr = of_translate_address(np, of_get_address(np, 0, &size, NULL));
+	addr = of_translate_address(np, addrp);
+	if (addr == OF_BAD_ADDR) {
+		err = -EINVAL;
+		goto err_free_bus;
+	}
+
 	map = ioremap(addr, size);
 	if (!map) {
 		err = -ENOMEM;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/gianfar.c linux-libre-2.6.34-gnu1/drivers/net/gianfar.c
--- linux-libre-2.6.33-gnu1/drivers/net/gianfar.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/gianfar.c	2010-05-16 17:17:36.000000000 -0400
@@ -549,12 +549,8 @@ static int gfar_parse_group(struct devic
 		struct gfar_private *priv, const char *model)
 {
 	u32 *queue_mask;
-	u64 addr, size;
-
-	addr = of_translate_address(np,
-			of_get_address(np, 0, &size, NULL));
-	priv->gfargrp[priv->num_grps].regs = ioremap(addr, size);
 
+	priv->gfargrp[priv->num_grps].regs = of_iomap(np, 0);
 	if (!priv->gfargrp[priv->num_grps].regs)
 		return -ENOMEM;
 
@@ -676,7 +672,7 @@ static int gfar_of_init(struct of_device
 		priv->rx_queue[i] = NULL;
 
 	for (i = 0; i < priv->num_tx_queues; i++) {
-		priv->tx_queue[i] =  (struct gfar_priv_tx_q *)kmalloc(
+		priv->tx_queue[i] =  (struct gfar_priv_tx_q *)kzalloc(
 				sizeof (struct gfar_priv_tx_q), GFP_KERNEL);
 		if (!priv->tx_queue[i]) {
 			err = -ENOMEM;
@@ -689,7 +685,7 @@ static int gfar_of_init(struct of_device
 	}
 
 	for (i = 0; i < priv->num_rx_queues; i++) {
-		priv->rx_queue[i] = (struct gfar_priv_rx_q *)kmalloc(
+		priv->rx_queue[i] = (struct gfar_priv_rx_q *)kzalloc(
 					sizeof (struct gfar_priv_rx_q), GFP_KERNEL);
 		if (!priv->rx_queue[i]) {
 			err = -ENOMEM;
@@ -998,7 +994,7 @@ static int gfar_probe(struct of_device *
 	}
 
 	/* Need to reverse the bit maps as  bit_map's MSB is q0
-	 * but, for_each_bit parses from right to left, which
+	 * but, for_each_set_bit parses from right to left, which
 	 * basically reverses the queue numbers */
 	for (i = 0; i< priv->num_grps; i++) {
 		priv->gfargrp[i].tx_bit_map = reverse_bitmap(
@@ -1011,7 +1007,7 @@ static int gfar_probe(struct of_device *
 	 * also assign queues to groups */
 	for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) {
 		priv->gfargrp[grp_idx].num_rx_queues = 0x0;
-		for_each_bit(i, &priv->gfargrp[grp_idx].rx_bit_map,
+		for_each_set_bit(i, &priv->gfargrp[grp_idx].rx_bit_map,
 				priv->num_rx_queues) {
 			priv->gfargrp[grp_idx].num_rx_queues++;
 			priv->rx_queue[i]->grp = &priv->gfargrp[grp_idx];
@@ -1019,7 +1015,7 @@ static int gfar_probe(struct of_device *
 			rqueue = rqueue | ((RQUEUE_EN0 | RQUEUE_EX0) >> i);
 		}
 		priv->gfargrp[grp_idx].num_tx_queues = 0x0;
-		for_each_bit (i, &priv->gfargrp[grp_idx].tx_bit_map,
+		for_each_set_bit(i, &priv->gfargrp[grp_idx].tx_bit_map,
 				priv->num_tx_queues) {
 			priv->gfargrp[grp_idx].num_tx_queues++;
 			priv->tx_queue[i]->grp = &priv->gfargrp[grp_idx];
@@ -1120,10 +1116,10 @@ static int gfar_probe(struct of_device *
 	/* provided which set of benchmarks. */
 	printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name);
 	for (i = 0; i < priv->num_rx_queues; i++)
-		printk(KERN_INFO "%s: :RX BD ring size for Q[%d]: %d\n",
+		printk(KERN_INFO "%s: RX BD ring size for Q[%d]: %d\n",
 			dev->name, i, priv->rx_queue[i]->rx_ring_size);
 	for(i = 0; i < priv->num_tx_queues; i++)
-		 printk(KERN_INFO "%s:TX BD ring size for Q[%d]: %d\n",
+		 printk(KERN_INFO "%s: TX BD ring size for Q[%d]: %d\n",
 			dev->name, i, priv->tx_queue[i]->tx_ring_size);
 
 	return 0;
@@ -1515,9 +1511,9 @@ static void gfar_halt_nodisable(struct n
 		tempval |= (DMACTRL_GRS | DMACTRL_GTS);
 		gfar_write(&regs->dmactrl, tempval);
 
-		while (!(gfar_read(&regs->ievent) &
-			 (IEVENT_GRSC | IEVENT_GTSC)))
-			cpu_relax();
+		spin_event_timeout(((gfar_read(&regs->ievent) &
+			 (IEVENT_GRSC | IEVENT_GTSC)) ==
+			 (IEVENT_GRSC | IEVENT_GTSC)), -1, 0);
 	}
 }
 
@@ -1638,13 +1634,13 @@ static void free_skb_resources(struct gf
 	/* Go through all the buffer descriptors and free their data buffers */
 	for (i = 0; i < priv->num_tx_queues; i++) {
 		tx_queue = priv->tx_queue[i];
-		if(!tx_queue->tx_skbuff)
+		if(tx_queue->tx_skbuff)
 			free_skb_tx_queue(tx_queue);
 	}
 
 	for (i = 0; i < priv->num_rx_queues; i++) {
 		rx_queue = priv->rx_queue[i];
-		if(!rx_queue->rx_skbuff)
+		if(rx_queue->rx_skbuff)
 			free_skb_rx_queue(rx_queue);
 	}
 
@@ -1653,6 +1649,7 @@ static void free_skb_resources(struct gf
 			sizeof(struct rxbd8) * priv->total_rx_ring_size,
 			priv->tx_queue[0]->tx_bd_base,
 			priv->tx_queue[0]->tx_bd_dma_base);
+	skb_queue_purge(&priv->rx_recycle);
 }
 
 void gfar_start(struct net_device *dev)
@@ -1709,7 +1706,7 @@ void gfar_configure_coalescing(struct gf
 
 	if (priv->mode == MQ_MG_MODE) {
 		baddr = &regs->txic0;
-		for_each_bit (i, &tx_mask, priv->num_tx_queues) {
+		for_each_set_bit(i, &tx_mask, priv->num_tx_queues) {
 			if (likely(priv->tx_queue[i]->txcoalescing)) {
 				gfar_write(baddr + i, 0);
 				gfar_write(baddr + i, priv->tx_queue[i]->txic);
@@ -1717,7 +1714,7 @@ void gfar_configure_coalescing(struct gf
 		}
 
 		baddr = &regs->rxic0;
-		for_each_bit (i, &rx_mask, priv->num_rx_queues) {
+		for_each_set_bit(i, &rx_mask, priv->num_rx_queues) {
 			if (likely(priv->rx_queue[i]->rxcoalescing)) {
 				gfar_write(baddr + i, 0);
 				gfar_write(baddr + i, priv->rx_queue[i]->rxic);
@@ -2021,7 +2018,6 @@ static int gfar_start_xmit(struct sk_buf
 	}
 
 	/* setup the TxBD length and buffer pointer for the first BD */
-	tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
 	txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
 			skb_headlen(skb), DMA_TO_DEVICE);
 
@@ -2053,6 +2049,10 @@ static int gfar_start_xmit(struct sk_buf
 
 	txbdp_start->lstatus = lstatus;
 
+	eieio(); /* force lstatus write before tx_skbuff */
+
+	tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
+
 	/* Update the current skb pointer to the next entry we will use
 	 * (wrapping if necessary) */
 	tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) &
@@ -2089,7 +2089,6 @@ static int gfar_close(struct net_device
 
 	disable_napi(priv);
 
-	skb_queue_purge(&priv->rx_recycle);
 	cancel_work_sync(&priv->reset_task);
 	stop_gfar(dev);
 
@@ -2390,6 +2389,7 @@ struct sk_buff * gfar_new_skb(struct net
 	 * as many bytes as needed to align the data properly
 	 */
 	skb_reserve(skb, alignamount);
+	GFAR_CB(skb)->alignamount = alignamount;
 
 	return skb;
 }
@@ -2530,13 +2530,13 @@ int gfar_clean_rx_ring(struct gfar_priv_
 				newskb = skb;
 			else if (skb) {
 				/*
-				 * We need to reset ->data to what it
+				 * We need to un-reserve() the skb 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_reserve(skb, -GFAR_CB(skb)->alignamount);
 				__skb_queue_head(&priv->rx_recycle, skb);
 			}
 		} else {
@@ -2607,7 +2607,7 @@ static int gfar_poll(struct napi_struct
 		budget_per_queue = left_over_budget/num_queues;
 		left_over_budget = 0;
 
-		for_each_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) {
+		for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) {
 			if (test_bit(i, &serviced_queues))
 				continue;
 			rx_queue = priv->rx_queue[i];
@@ -2863,11 +2863,11 @@ static void gfar_set_multi(struct net_de
 			em_num = 0;
 		}
 
-		if (dev->mc_count == 0)
+		if (netdev_mc_empty(dev))
 			return;
 
 		/* Parse the list, and set the appropriate bits */
-		for(mc_ptr = dev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
+		netdev_for_each_mc_addr(mc_ptr, dev) {
 			if (idx < em_num) {
 				gfar_set_mac_for_addr(dev, idx,
 						mc_ptr->dmi_addr);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/gianfar_ethtool.c linux-libre-2.6.34-gnu1/drivers/net/gianfar_ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/gianfar_ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/gianfar_ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/gianfar.h linux-libre-2.6.34-gnu1/drivers/net/gianfar.h
--- linux-libre-2.6.33-gnu1/drivers/net/gianfar.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/gianfar.h	2010-05-16 17:17:36.000000000 -0400
@@ -566,6 +566,12 @@ struct rxfcb {
 	u16	vlctl;	/* VLAN control word */
 };
 
+struct gianfar_skb_cb {
+	int alignamount;
+};
+
+#define GFAR_CB(skb) ((struct gianfar_skb_cb *)((skb)->cb))
+
 struct rmon_mib
 {
 	u32	tr64;	/* 0x.680 - Transmit and Receive 64-byte Frame Counter */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/gianfar_sysfs.c linux-libre-2.6.34-gnu1/drivers/net/gianfar_sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/net/gianfar_sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/gianfar_sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/greth.c linux-libre-2.6.34-gnu1/drivers/net/greth.c
--- linux-libre-2.6.33-gnu1/drivers/net/greth.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/greth.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1635 @@
+/*
+ * Aeroflex Gaisler GRETH 10/100/1G Ethernet MAC.
+ *
+ * 2005-2009 (c) Aeroflex Gaisler AB
+ *
+ * This driver supports GRETH 10/100 and GRETH 10/100/1G Ethernet MACs
+ * available in the GRLIB VHDL IP core library.
+ *
+ * Full documentation of both cores can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * The Gigabit version supports scatter/gather DMA, any alignment of
+ * buffers and checksum offloading.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Kristoffer Glembo
+ *               Daniel Hellstrom
+ *               Marko Isomaki
+ */
+
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/skbuff.h>
+#include <linux/io.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <asm/cacheflush.h>
+#include <asm/byteorder.h>
+
+#ifdef CONFIG_SPARC
+#include <asm/idprom.h>
+#endif
+
+#include "greth.h"
+
+#define GRETH_DEF_MSG_ENABLE	  \
+	(NETIF_MSG_DRV		| \
+	 NETIF_MSG_PROBE	| \
+	 NETIF_MSG_LINK		| \
+	 NETIF_MSG_IFDOWN	| \
+	 NETIF_MSG_IFUP		| \
+	 NETIF_MSG_RX_ERR	| \
+	 NETIF_MSG_TX_ERR)
+
+static int greth_debug = -1;	/* -1 == use GRETH_DEF_MSG_ENABLE as value */
+module_param(greth_debug, int, 0);
+MODULE_PARM_DESC(greth_debug, "GRETH bitmapped debugging message enable value");
+
+/* Accept MAC address of the form macaddr=0x08,0x00,0x20,0x30,0x40,0x50 */
+static int macaddr[6];
+module_param_array(macaddr, int, NULL, 0);
+MODULE_PARM_DESC(macaddr, "GRETH Ethernet MAC address");
+
+static int greth_edcl = 1;
+module_param(greth_edcl, int, 0);
+MODULE_PARM_DESC(greth_edcl, "GRETH EDCL usage indicator. Set to 1 if EDCL is used.");
+
+static int greth_open(struct net_device *dev);
+static netdev_tx_t greth_start_xmit(struct sk_buff *skb,
+	   struct net_device *dev);
+static netdev_tx_t greth_start_xmit_gbit(struct sk_buff *skb,
+	   struct net_device *dev);
+static int greth_rx(struct net_device *dev, int limit);
+static int greth_rx_gbit(struct net_device *dev, int limit);
+static void greth_clean_tx(struct net_device *dev);
+static void greth_clean_tx_gbit(struct net_device *dev);
+static irqreturn_t greth_interrupt(int irq, void *dev_id);
+static int greth_close(struct net_device *dev);
+static int greth_set_mac_add(struct net_device *dev, void *p);
+static void greth_set_multicast_list(struct net_device *dev);
+
+#define GRETH_REGLOAD(a)	    (be32_to_cpu(__raw_readl(&(a))))
+#define GRETH_REGSAVE(a, v)         (__raw_writel(cpu_to_be32(v), &(a)))
+#define GRETH_REGORIN(a, v)         (GRETH_REGSAVE(a, (GRETH_REGLOAD(a) | (v))))
+#define GRETH_REGANDIN(a, v)        (GRETH_REGSAVE(a, (GRETH_REGLOAD(a) & (v))))
+
+#define NEXT_TX(N)      (((N) + 1) & GRETH_TXBD_NUM_MASK)
+#define SKIP_TX(N, C)   (((N) + C) & GRETH_TXBD_NUM_MASK)
+#define NEXT_RX(N)      (((N) + 1) & GRETH_RXBD_NUM_MASK)
+
+static void greth_print_rx_packet(void *addr, int len)
+{
+	print_hex_dump(KERN_DEBUG, "RX: ", DUMP_PREFIX_OFFSET, 16, 1,
+			addr, len, true);
+}
+
+static void greth_print_tx_packet(struct sk_buff *skb)
+{
+	int i;
+	int length;
+
+	if (skb_shinfo(skb)->nr_frags == 0)
+		length = skb->len;
+	else
+		length = skb_headlen(skb);
+
+	print_hex_dump(KERN_DEBUG, "TX: ", DUMP_PREFIX_OFFSET, 16, 1,
+			skb->data, length, true);
+
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+
+		print_hex_dump(KERN_DEBUG, "TX: ", DUMP_PREFIX_OFFSET, 16, 1,
+			       phys_to_virt(page_to_phys(skb_shinfo(skb)->frags[i].page)) +
+			       skb_shinfo(skb)->frags[i].page_offset,
+			       length, true);
+	}
+}
+
+static inline void greth_enable_tx(struct greth_private *greth)
+{
+	wmb();
+	GRETH_REGORIN(greth->regs->control, GRETH_TXEN);
+}
+
+static inline void greth_disable_tx(struct greth_private *greth)
+{
+	GRETH_REGANDIN(greth->regs->control, ~GRETH_TXEN);
+}
+
+static inline void greth_enable_rx(struct greth_private *greth)
+{
+	wmb();
+	GRETH_REGORIN(greth->regs->control, GRETH_RXEN);
+}
+
+static inline void greth_disable_rx(struct greth_private *greth)
+{
+	GRETH_REGANDIN(greth->regs->control, ~GRETH_RXEN);
+}
+
+static inline void greth_enable_irqs(struct greth_private *greth)
+{
+	GRETH_REGORIN(greth->regs->control, GRETH_RXI | GRETH_TXI);
+}
+
+static inline void greth_disable_irqs(struct greth_private *greth)
+{
+	GRETH_REGANDIN(greth->regs->control, ~(GRETH_RXI|GRETH_TXI));
+}
+
+static inline void greth_write_bd(u32 *bd, u32 val)
+{
+	__raw_writel(cpu_to_be32(val), bd);
+}
+
+static inline u32 greth_read_bd(u32 *bd)
+{
+	return be32_to_cpu(__raw_readl(bd));
+}
+
+static void greth_clean_rings(struct greth_private *greth)
+{
+	int i;
+	struct greth_bd *rx_bdp = greth->rx_bd_base;
+	struct greth_bd *tx_bdp = greth->tx_bd_base;
+
+	if (greth->gbit_mac) {
+
+		/* Free and unmap RX buffers */
+		for (i = 0; i < GRETH_RXBD_NUM; i++, rx_bdp++) {
+			if (greth->rx_skbuff[i] != NULL) {
+				dev_kfree_skb(greth->rx_skbuff[i]);
+				dma_unmap_single(greth->dev,
+						 greth_read_bd(&rx_bdp->addr),
+						 MAX_FRAME_SIZE+NET_IP_ALIGN,
+						 DMA_FROM_DEVICE);
+			}
+		}
+
+		/* TX buffers */
+		while (greth->tx_free < GRETH_TXBD_NUM) {
+
+			struct sk_buff *skb = greth->tx_skbuff[greth->tx_last];
+			int nr_frags = skb_shinfo(skb)->nr_frags;
+			tx_bdp = greth->tx_bd_base + greth->tx_last;
+			greth->tx_last = NEXT_TX(greth->tx_last);
+
+			dma_unmap_single(greth->dev,
+					 greth_read_bd(&tx_bdp->addr),
+					 skb_headlen(skb),
+					 DMA_TO_DEVICE);
+
+			for (i = 0; i < nr_frags; i++) {
+				skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+				tx_bdp = greth->tx_bd_base + greth->tx_last;
+
+				dma_unmap_page(greth->dev,
+					       greth_read_bd(&tx_bdp->addr),
+					       frag->size,
+					       DMA_TO_DEVICE);
+
+				greth->tx_last = NEXT_TX(greth->tx_last);
+			}
+			greth->tx_free += nr_frags+1;
+			dev_kfree_skb(skb);
+		}
+
+
+	} else { /* 10/100 Mbps MAC */
+
+		for (i = 0; i < GRETH_RXBD_NUM; i++, rx_bdp++) {
+			kfree(greth->rx_bufs[i]);
+			dma_unmap_single(greth->dev,
+					 greth_read_bd(&rx_bdp->addr),
+					 MAX_FRAME_SIZE,
+					 DMA_FROM_DEVICE);
+		}
+		for (i = 0; i < GRETH_TXBD_NUM; i++, tx_bdp++) {
+			kfree(greth->tx_bufs[i]);
+			dma_unmap_single(greth->dev,
+					 greth_read_bd(&tx_bdp->addr),
+					 MAX_FRAME_SIZE,
+					 DMA_TO_DEVICE);
+		}
+	}
+}
+
+static int greth_init_rings(struct greth_private *greth)
+{
+	struct sk_buff *skb;
+	struct greth_bd *rx_bd, *tx_bd;
+	u32 dma_addr;
+	int i;
+
+	rx_bd = greth->rx_bd_base;
+	tx_bd = greth->tx_bd_base;
+
+	/* Initialize descriptor rings and buffers */
+	if (greth->gbit_mac) {
+
+		for (i = 0; i < GRETH_RXBD_NUM; i++) {
+			skb = netdev_alloc_skb(greth->netdev, MAX_FRAME_SIZE+NET_IP_ALIGN);
+			if (skb == NULL) {
+				if (netif_msg_ifup(greth))
+					dev_err(greth->dev, "Error allocating DMA ring.\n");
+				goto cleanup;
+			}
+			skb_reserve(skb, NET_IP_ALIGN);
+			dma_addr = dma_map_single(greth->dev,
+						  skb->data,
+						  MAX_FRAME_SIZE+NET_IP_ALIGN,
+						  DMA_FROM_DEVICE);
+
+			if (dma_mapping_error(greth->dev, dma_addr)) {
+				if (netif_msg_ifup(greth))
+					dev_err(greth->dev, "Could not create initial DMA mapping\n");
+				goto cleanup;
+			}
+			greth->rx_skbuff[i] = skb;
+			greth_write_bd(&rx_bd[i].addr, dma_addr);
+			greth_write_bd(&rx_bd[i].stat, GRETH_BD_EN | GRETH_BD_IE);
+		}
+
+	} else {
+
+		/* 10/100 MAC uses a fixed set of buffers and copy to/from SKBs */
+		for (i = 0; i < GRETH_RXBD_NUM; i++) {
+
+			greth->rx_bufs[i] = kmalloc(MAX_FRAME_SIZE, GFP_KERNEL);
+
+			if (greth->rx_bufs[i] == NULL) {
+				if (netif_msg_ifup(greth))
+					dev_err(greth->dev, "Error allocating DMA ring.\n");
+				goto cleanup;
+			}
+
+			dma_addr = dma_map_single(greth->dev,
+						  greth->rx_bufs[i],
+						  MAX_FRAME_SIZE,
+						  DMA_FROM_DEVICE);
+
+			if (dma_mapping_error(greth->dev, dma_addr)) {
+				if (netif_msg_ifup(greth))
+					dev_err(greth->dev, "Could not create initial DMA mapping\n");
+				goto cleanup;
+			}
+			greth_write_bd(&rx_bd[i].addr, dma_addr);
+			greth_write_bd(&rx_bd[i].stat, GRETH_BD_EN | GRETH_BD_IE);
+		}
+		for (i = 0; i < GRETH_TXBD_NUM; i++) {
+
+			greth->tx_bufs[i] = kmalloc(MAX_FRAME_SIZE, GFP_KERNEL);
+
+			if (greth->tx_bufs[i] == NULL) {
+				if (netif_msg_ifup(greth))
+					dev_err(greth->dev, "Error allocating DMA ring.\n");
+				goto cleanup;
+			}
+
+			dma_addr = dma_map_single(greth->dev,
+						  greth->tx_bufs[i],
+						  MAX_FRAME_SIZE,
+						  DMA_TO_DEVICE);
+
+			if (dma_mapping_error(greth->dev, dma_addr)) {
+				if (netif_msg_ifup(greth))
+					dev_err(greth->dev, "Could not create initial DMA mapping\n");
+				goto cleanup;
+			}
+			greth_write_bd(&tx_bd[i].addr, dma_addr);
+			greth_write_bd(&tx_bd[i].stat, 0);
+		}
+	}
+	greth_write_bd(&rx_bd[GRETH_RXBD_NUM - 1].stat,
+		       greth_read_bd(&rx_bd[GRETH_RXBD_NUM - 1].stat) | GRETH_BD_WR);
+
+	/* Initialize pointers. */
+	greth->rx_cur = 0;
+	greth->tx_next = 0;
+	greth->tx_last = 0;
+	greth->tx_free = GRETH_TXBD_NUM;
+
+	/* Initialize descriptor base address */
+	GRETH_REGSAVE(greth->regs->tx_desc_p, greth->tx_bd_base_phys);
+	GRETH_REGSAVE(greth->regs->rx_desc_p, greth->rx_bd_base_phys);
+
+	return 0;
+
+cleanup:
+	greth_clean_rings(greth);
+	return -ENOMEM;
+}
+
+static int greth_open(struct net_device *dev)
+{
+	struct greth_private *greth = netdev_priv(dev);
+	int err;
+
+	err = greth_init_rings(greth);
+	if (err) {
+		if (netif_msg_ifup(greth))
+			dev_err(&dev->dev, "Could not allocate memory for DMA rings\n");
+		return err;
+	}
+
+	err = request_irq(greth->irq, greth_interrupt, 0, "eth", (void *) dev);
+	if (err) {
+		if (netif_msg_ifup(greth))
+			dev_err(&dev->dev, "Could not allocate interrupt %d\n", dev->irq);
+		greth_clean_rings(greth);
+		return err;
+	}
+
+	if (netif_msg_ifup(greth))
+		dev_dbg(&dev->dev, " starting queue\n");
+	netif_start_queue(dev);
+
+	napi_enable(&greth->napi);
+
+	greth_enable_irqs(greth);
+	greth_enable_tx(greth);
+	greth_enable_rx(greth);
+	return 0;
+
+}
+
+static int greth_close(struct net_device *dev)
+{
+	struct greth_private *greth = netdev_priv(dev);
+
+	napi_disable(&greth->napi);
+
+	greth_disable_tx(greth);
+
+	netif_stop_queue(dev);
+
+	free_irq(greth->irq, (void *) dev);
+
+	greth_clean_rings(greth);
+
+	return 0;
+}
+
+static netdev_tx_t
+greth_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct greth_private *greth = netdev_priv(dev);
+	struct greth_bd *bdp;
+	int err = NETDEV_TX_OK;
+	u32 status, dma_addr;
+
+	bdp = greth->tx_bd_base + greth->tx_next;
+
+	if (unlikely(greth->tx_free <= 0)) {
+		netif_stop_queue(dev);
+		return NETDEV_TX_BUSY;
+	}
+
+	if (netif_msg_pktdata(greth))
+		greth_print_tx_packet(skb);
+
+
+	if (unlikely(skb->len > MAX_FRAME_SIZE)) {
+		dev->stats.tx_errors++;
+		goto out;
+	}
+
+	dma_addr = greth_read_bd(&bdp->addr);
+
+	memcpy((unsigned char *) phys_to_virt(dma_addr), skb->data, skb->len);
+
+	dma_sync_single_for_device(greth->dev, dma_addr, skb->len, DMA_TO_DEVICE);
+
+	status = GRETH_BD_EN | (skb->len & GRETH_BD_LEN);
+
+	/* Wrap around descriptor ring */
+	if (greth->tx_next == GRETH_TXBD_NUM_MASK) {
+		status |= GRETH_BD_WR;
+	}
+
+	greth->tx_next = NEXT_TX(greth->tx_next);
+	greth->tx_free--;
+
+	/* No more descriptors */
+	if (unlikely(greth->tx_free == 0)) {
+
+		/* Free transmitted descriptors */
+		greth_clean_tx(dev);
+
+		/* If nothing was cleaned, stop queue & wait for irq */
+		if (unlikely(greth->tx_free == 0)) {
+			status |= GRETH_BD_IE;
+			netif_stop_queue(dev);
+		}
+	}
+
+	/* Write descriptor control word and enable transmission */
+	greth_write_bd(&bdp->stat, status);
+	greth_enable_tx(greth);
+
+out:
+	dev_kfree_skb(skb);
+	return err;
+}
+
+
+static netdev_tx_t
+greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct greth_private *greth = netdev_priv(dev);
+	struct greth_bd *bdp;
+	u32 status = 0, dma_addr;
+	int curr_tx, nr_frags, i, err = NETDEV_TX_OK;
+
+	nr_frags = skb_shinfo(skb)->nr_frags;
+
+	if (greth->tx_free < nr_frags + 1) {
+		netif_stop_queue(dev);
+		err = NETDEV_TX_BUSY;
+		goto out;
+	}
+
+	if (netif_msg_pktdata(greth))
+		greth_print_tx_packet(skb);
+
+	if (unlikely(skb->len > MAX_FRAME_SIZE)) {
+		dev->stats.tx_errors++;
+		goto out;
+	}
+
+	/* Save skb pointer. */
+	greth->tx_skbuff[greth->tx_next] = skb;
+
+	/* Linear buf */
+	if (nr_frags != 0)
+		status = GRETH_TXBD_MORE;
+
+	status |= GRETH_TXBD_CSALL;
+	status |= skb_headlen(skb) & GRETH_BD_LEN;
+	if (greth->tx_next == GRETH_TXBD_NUM_MASK)
+		status |= GRETH_BD_WR;
+
+
+	bdp = greth->tx_bd_base + greth->tx_next;
+	greth_write_bd(&bdp->stat, status);
+	dma_addr = dma_map_single(greth->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
+
+	if (unlikely(dma_mapping_error(greth->dev, dma_addr)))
+		goto map_error;
+
+	greth_write_bd(&bdp->addr, dma_addr);
+
+	curr_tx = NEXT_TX(greth->tx_next);
+
+	/* Frags */
+	for (i = 0; i < nr_frags; i++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+		greth->tx_skbuff[curr_tx] = NULL;
+		bdp = greth->tx_bd_base + curr_tx;
+
+		status = GRETH_TXBD_CSALL;
+		status |= frag->size & GRETH_BD_LEN;
+
+		/* Wrap around descriptor ring */
+		if (curr_tx == GRETH_TXBD_NUM_MASK)
+			status |= GRETH_BD_WR;
+
+		/* More fragments left */
+		if (i < nr_frags - 1)
+			status |= GRETH_TXBD_MORE;
+
+		/* ... last fragment, check if out of descriptors  */
+		else if (greth->tx_free - nr_frags - 1 < (MAX_SKB_FRAGS + 1)) {
+
+			/* Enable interrupts and stop queue */
+			status |= GRETH_BD_IE;
+			netif_stop_queue(dev);
+		}
+
+		greth_write_bd(&bdp->stat, status);
+
+		dma_addr = dma_map_page(greth->dev,
+					frag->page,
+					frag->page_offset,
+					frag->size,
+					DMA_TO_DEVICE);
+
+		if (unlikely(dma_mapping_error(greth->dev, dma_addr)))
+			goto frag_map_error;
+
+		greth_write_bd(&bdp->addr, dma_addr);
+
+		curr_tx = NEXT_TX(curr_tx);
+	}
+
+	wmb();
+
+	/* Enable the descriptors that we configured ...  */
+	for (i = 0; i < nr_frags + 1; i++) {
+		bdp = greth->tx_bd_base + greth->tx_next;
+		greth_write_bd(&bdp->stat, greth_read_bd(&bdp->stat) | GRETH_BD_EN);
+		greth->tx_next = NEXT_TX(greth->tx_next);
+		greth->tx_free--;
+	}
+
+	greth_enable_tx(greth);
+
+	return NETDEV_TX_OK;
+
+frag_map_error:
+	/* Unmap SKB mappings that succeeded */
+	for (i = 0; greth->tx_next + i != curr_tx; i++) {
+		bdp = greth->tx_bd_base + greth->tx_next + i;
+		dma_unmap_single(greth->dev,
+				 greth_read_bd(&bdp->addr),
+				 greth_read_bd(&bdp->stat) & GRETH_BD_LEN,
+				 DMA_TO_DEVICE);
+	}
+map_error:
+	if (net_ratelimit())
+		dev_warn(greth->dev, "Could not create TX DMA mapping\n");
+	dev_kfree_skb(skb);
+out:
+	return err;
+}
+
+
+static irqreturn_t greth_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct greth_private *greth;
+	u32 status;
+	irqreturn_t retval = IRQ_NONE;
+
+	greth = netdev_priv(dev);
+
+	spin_lock(&greth->devlock);
+
+	/* Get the interrupt events that caused us to be here. */
+	status = GRETH_REGLOAD(greth->regs->status);
+
+	/* Handle rx and tx interrupts through poll */
+	if (status & (GRETH_INT_RX | GRETH_INT_TX)) {
+
+		/* Clear interrupt status */
+		GRETH_REGORIN(greth->regs->status,
+			      status & (GRETH_INT_RX | GRETH_INT_TX));
+
+		retval = IRQ_HANDLED;
+
+		/* Disable interrupts and schedule poll() */
+		greth_disable_irqs(greth);
+		napi_schedule(&greth->napi);
+	}
+
+	mmiowb();
+	spin_unlock(&greth->devlock);
+
+	return retval;
+}
+
+static void greth_clean_tx(struct net_device *dev)
+{
+	struct greth_private *greth;
+	struct greth_bd *bdp;
+	u32 stat;
+
+	greth = netdev_priv(dev);
+
+	while (1) {
+		bdp = greth->tx_bd_base + greth->tx_last;
+		stat = greth_read_bd(&bdp->stat);
+
+		if (unlikely(stat & GRETH_BD_EN))
+			break;
+
+		if (greth->tx_free == GRETH_TXBD_NUM)
+			break;
+
+		/* Check status for errors */
+		if (unlikely(stat & GRETH_TXBD_STATUS)) {
+			dev->stats.tx_errors++;
+			if (stat & GRETH_TXBD_ERR_AL)
+				dev->stats.tx_aborted_errors++;
+			if (stat & GRETH_TXBD_ERR_UE)
+				dev->stats.tx_fifo_errors++;
+		}
+		dev->stats.tx_packets++;
+		greth->tx_last = NEXT_TX(greth->tx_last);
+		greth->tx_free++;
+	}
+
+	if (greth->tx_free > 0) {
+		netif_wake_queue(dev);
+	}
+
+}
+
+static inline void greth_update_tx_stats(struct net_device *dev, u32 stat)
+{
+	/* Check status for errors */
+	if (unlikely(stat & GRETH_TXBD_STATUS)) {
+		dev->stats.tx_errors++;
+		if (stat & GRETH_TXBD_ERR_AL)
+			dev->stats.tx_aborted_errors++;
+		if (stat & GRETH_TXBD_ERR_UE)
+			dev->stats.tx_fifo_errors++;
+		if (stat & GRETH_TXBD_ERR_LC)
+			dev->stats.tx_aborted_errors++;
+	}
+	dev->stats.tx_packets++;
+}
+
+static void greth_clean_tx_gbit(struct net_device *dev)
+{
+	struct greth_private *greth;
+	struct greth_bd *bdp, *bdp_last_frag;
+	struct sk_buff *skb;
+	u32 stat;
+	int nr_frags, i;
+
+	greth = netdev_priv(dev);
+
+	while (greth->tx_free < GRETH_TXBD_NUM) {
+
+		skb = greth->tx_skbuff[greth->tx_last];
+
+		nr_frags = skb_shinfo(skb)->nr_frags;
+
+		/* We only clean fully completed SKBs */
+		bdp_last_frag = greth->tx_bd_base + SKIP_TX(greth->tx_last, nr_frags);
+		stat = bdp_last_frag->stat;
+
+		if (stat & GRETH_BD_EN)
+			break;
+
+		greth->tx_skbuff[greth->tx_last] = NULL;
+
+		greth_update_tx_stats(dev, stat);
+
+		bdp = greth->tx_bd_base + greth->tx_last;
+
+		greth->tx_last = NEXT_TX(greth->tx_last);
+
+		dma_unmap_single(greth->dev,
+				 greth_read_bd(&bdp->addr),
+				 skb_headlen(skb),
+				 DMA_TO_DEVICE);
+
+		for (i = 0; i < nr_frags; i++) {
+			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+			bdp = greth->tx_bd_base + greth->tx_last;
+
+			dma_unmap_page(greth->dev,
+				       greth_read_bd(&bdp->addr),
+				       frag->size,
+				       DMA_TO_DEVICE);
+
+			greth->tx_last = NEXT_TX(greth->tx_last);
+		}
+		greth->tx_free += nr_frags+1;
+		dev_kfree_skb(skb);
+	}
+	if (greth->tx_free > (MAX_SKB_FRAGS + 1)) {
+		netif_wake_queue(dev);
+	}
+}
+
+static int greth_pending_packets(struct greth_private *greth)
+{
+	struct greth_bd *bdp;
+	u32 status;
+	bdp = greth->rx_bd_base + greth->rx_cur;
+	status = greth_read_bd(&bdp->stat);
+	if (status & GRETH_BD_EN)
+		return 0;
+	else
+		return 1;
+}
+
+static int greth_rx(struct net_device *dev, int limit)
+{
+	struct greth_private *greth;
+	struct greth_bd *bdp;
+	struct sk_buff *skb;
+	int pkt_len;
+	int bad, count;
+	u32 status, dma_addr;
+
+	greth = netdev_priv(dev);
+
+	for (count = 0; count < limit; ++count) {
+
+		bdp = greth->rx_bd_base + greth->rx_cur;
+		status = greth_read_bd(&bdp->stat);
+		dma_addr = greth_read_bd(&bdp->addr);
+		bad = 0;
+
+		if (unlikely(status & GRETH_BD_EN)) {
+			break;
+		}
+
+		/* Check status for errors. */
+		if (unlikely(status & GRETH_RXBD_STATUS)) {
+			if (status & GRETH_RXBD_ERR_FT) {
+				dev->stats.rx_length_errors++;
+				bad = 1;
+			}
+			if (status & (GRETH_RXBD_ERR_AE | GRETH_RXBD_ERR_OE)) {
+				dev->stats.rx_frame_errors++;
+				bad = 1;
+			}
+			if (status & GRETH_RXBD_ERR_CRC) {
+				dev->stats.rx_crc_errors++;
+				bad = 1;
+			}
+		}
+		if (unlikely(bad)) {
+			dev->stats.rx_errors++;
+
+		} else {
+
+			pkt_len = status & GRETH_BD_LEN;
+
+			skb = netdev_alloc_skb(dev, pkt_len + NET_IP_ALIGN);
+
+			if (unlikely(skb == NULL)) {
+
+				if (net_ratelimit())
+					dev_warn(&dev->dev, "low on memory - " "packet dropped\n");
+
+				dev->stats.rx_dropped++;
+
+			} else {
+				skb_reserve(skb, NET_IP_ALIGN);
+				skb->dev = dev;
+
+				dma_sync_single_for_cpu(greth->dev,
+							dma_addr,
+							pkt_len,
+							DMA_FROM_DEVICE);
+
+				if (netif_msg_pktdata(greth))
+					greth_print_rx_packet(phys_to_virt(dma_addr), pkt_len);
+
+				memcpy(skb_put(skb, pkt_len), phys_to_virt(dma_addr), pkt_len);
+
+				skb->protocol = eth_type_trans(skb, dev);
+				dev->stats.rx_packets++;
+				netif_receive_skb(skb);
+			}
+		}
+
+		status = GRETH_BD_EN | GRETH_BD_IE;
+		if (greth->rx_cur == GRETH_RXBD_NUM_MASK) {
+			status |= GRETH_BD_WR;
+		}
+
+		wmb();
+		greth_write_bd(&bdp->stat, status);
+
+		dma_sync_single_for_device(greth->dev, dma_addr, MAX_FRAME_SIZE, DMA_FROM_DEVICE);
+
+		greth_enable_rx(greth);
+
+		greth->rx_cur = NEXT_RX(greth->rx_cur);
+	}
+
+	return count;
+}
+
+static inline int hw_checksummed(u32 status)
+{
+
+	if (status & GRETH_RXBD_IP_FRAG)
+		return 0;
+
+	if (status & GRETH_RXBD_IP && status & GRETH_RXBD_IP_CSERR)
+		return 0;
+
+	if (status & GRETH_RXBD_UDP && status & GRETH_RXBD_UDP_CSERR)
+		return 0;
+
+	if (status & GRETH_RXBD_TCP && status & GRETH_RXBD_TCP_CSERR)
+		return 0;
+
+	return 1;
+}
+
+static int greth_rx_gbit(struct net_device *dev, int limit)
+{
+	struct greth_private *greth;
+	struct greth_bd *bdp;
+	struct sk_buff *skb, *newskb;
+	int pkt_len;
+	int bad, count = 0;
+	u32 status, dma_addr;
+
+	greth = netdev_priv(dev);
+
+	for (count = 0; count < limit; ++count) {
+
+		bdp = greth->rx_bd_base + greth->rx_cur;
+		skb = greth->rx_skbuff[greth->rx_cur];
+		status = greth_read_bd(&bdp->stat);
+		bad = 0;
+
+		if (status & GRETH_BD_EN)
+			break;
+
+		/* Check status for errors. */
+		if (unlikely(status & GRETH_RXBD_STATUS)) {
+
+			if (status & GRETH_RXBD_ERR_FT) {
+				dev->stats.rx_length_errors++;
+				bad = 1;
+			} else if (status &
+				   (GRETH_RXBD_ERR_AE | GRETH_RXBD_ERR_OE | GRETH_RXBD_ERR_LE)) {
+				dev->stats.rx_frame_errors++;
+				bad = 1;
+			} else if (status & GRETH_RXBD_ERR_CRC) {
+				dev->stats.rx_crc_errors++;
+				bad = 1;
+			}
+		}
+
+		/* Allocate new skb to replace current */
+		newskb = netdev_alloc_skb(dev, MAX_FRAME_SIZE + NET_IP_ALIGN);
+
+		if (!bad && newskb) {
+			skb_reserve(newskb, NET_IP_ALIGN);
+
+			dma_addr = dma_map_single(greth->dev,
+						      newskb->data,
+						      MAX_FRAME_SIZE + NET_IP_ALIGN,
+						      DMA_FROM_DEVICE);
+
+			if (!dma_mapping_error(greth->dev, dma_addr)) {
+				/* Process the incoming frame. */
+				pkt_len = status & GRETH_BD_LEN;
+
+				dma_unmap_single(greth->dev,
+						 greth_read_bd(&bdp->addr),
+						 MAX_FRAME_SIZE + NET_IP_ALIGN,
+						 DMA_FROM_DEVICE);
+
+				if (netif_msg_pktdata(greth))
+					greth_print_rx_packet(phys_to_virt(greth_read_bd(&bdp->addr)), pkt_len);
+
+				skb_put(skb, pkt_len);
+
+				if (greth->flags & GRETH_FLAG_RX_CSUM && hw_checksummed(status))
+					skb->ip_summed = CHECKSUM_UNNECESSARY;
+				else
+					skb->ip_summed = CHECKSUM_NONE;
+
+				skb->dev = dev;
+				skb->protocol = eth_type_trans(skb, dev);
+				dev->stats.rx_packets++;
+				netif_receive_skb(skb);
+
+				greth->rx_skbuff[greth->rx_cur] = newskb;
+				greth_write_bd(&bdp->addr, dma_addr);
+			} else {
+				if (net_ratelimit())
+					dev_warn(greth->dev, "Could not create DMA mapping, dropping packet\n");
+				dev_kfree_skb(newskb);
+				dev->stats.rx_dropped++;
+			}
+		} else {
+			if (net_ratelimit())
+				dev_warn(greth->dev, "Could not allocate SKB, dropping packet\n");
+			dev->stats.rx_dropped++;
+		}
+
+		status = GRETH_BD_EN | GRETH_BD_IE;
+		if (greth->rx_cur == GRETH_RXBD_NUM_MASK) {
+			status |= GRETH_BD_WR;
+		}
+
+		wmb();
+		greth_write_bd(&bdp->stat, status);
+		greth_enable_rx(greth);
+		greth->rx_cur = NEXT_RX(greth->rx_cur);
+	}
+
+	return count;
+
+}
+
+static int greth_poll(struct napi_struct *napi, int budget)
+{
+	struct greth_private *greth;
+	int work_done = 0;
+	greth = container_of(napi, struct greth_private, napi);
+
+	if (greth->gbit_mac) {
+		greth_clean_tx_gbit(greth->netdev);
+	} else {
+		greth_clean_tx(greth->netdev);
+	}
+
+restart_poll:
+	if (greth->gbit_mac) {
+		work_done += greth_rx_gbit(greth->netdev, budget - work_done);
+	} else {
+		work_done += greth_rx(greth->netdev, budget - work_done);
+	}
+
+	if (work_done < budget) {
+
+		napi_complete(napi);
+
+		if (greth_pending_packets(greth)) {
+			napi_reschedule(napi);
+			goto restart_poll;
+		}
+	}
+
+	greth_enable_irqs(greth);
+	return work_done;
+}
+
+static int greth_set_mac_add(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+	struct greth_private *greth;
+	struct greth_regs *regs;
+
+	greth = netdev_priv(dev);
+	regs = (struct greth_regs *) greth->regs;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EINVAL;
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	GRETH_REGSAVE(regs->esa_msb, addr->sa_data[0] << 8 | addr->sa_data[1]);
+	GRETH_REGSAVE(regs->esa_lsb,
+		      addr->sa_data[2] << 24 | addr->
+		      sa_data[3] << 16 | addr->sa_data[4] << 8 | addr->sa_data[5]);
+	return 0;
+}
+
+static u32 greth_hash_get_index(__u8 *addr)
+{
+	return (ether_crc(6, addr)) & 0x3F;
+}
+
+static void greth_set_hash_filter(struct net_device *dev)
+{
+	struct dev_mc_list *curr;
+	struct greth_private *greth = netdev_priv(dev);
+	struct greth_regs *regs = (struct greth_regs *) greth->regs;
+	u32 mc_filter[2];
+	unsigned int bitnr;
+
+	mc_filter[0] = mc_filter[1] = 0;
+
+	netdev_for_each_mc_addr(curr, dev) {
+		bitnr = greth_hash_get_index(curr->dmi_addr);
+		mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
+	}
+
+	GRETH_REGSAVE(regs->hash_msb, mc_filter[1]);
+	GRETH_REGSAVE(regs->hash_lsb, mc_filter[0]);
+}
+
+static void greth_set_multicast_list(struct net_device *dev)
+{
+	int cfg;
+	struct greth_private *greth = netdev_priv(dev);
+	struct greth_regs *regs = (struct greth_regs *) greth->regs;
+
+	cfg = GRETH_REGLOAD(regs->control);
+	if (dev->flags & IFF_PROMISC)
+		cfg |= GRETH_CTRL_PR;
+	else
+		cfg &= ~GRETH_CTRL_PR;
+
+	if (greth->multicast) {
+		if (dev->flags & IFF_ALLMULTI) {
+			GRETH_REGSAVE(regs->hash_msb, -1);
+			GRETH_REGSAVE(regs->hash_lsb, -1);
+			cfg |= GRETH_CTRL_MCEN;
+			GRETH_REGSAVE(regs->control, cfg);
+			return;
+		}
+
+		if (netdev_mc_empty(dev)) {
+			cfg &= ~GRETH_CTRL_MCEN;
+			GRETH_REGSAVE(regs->control, cfg);
+			return;
+		}
+
+		/* Setup multicast filter */
+		greth_set_hash_filter(dev);
+		cfg |= GRETH_CTRL_MCEN;
+	}
+	GRETH_REGSAVE(regs->control, cfg);
+}
+
+static u32 greth_get_msglevel(struct net_device *dev)
+{
+	struct greth_private *greth = netdev_priv(dev);
+	return greth->msg_enable;
+}
+
+static void greth_set_msglevel(struct net_device *dev, u32 value)
+{
+	struct greth_private *greth = netdev_priv(dev);
+	greth->msg_enable = value;
+}
+static int greth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct greth_private *greth = netdev_priv(dev);
+	struct phy_device *phy = greth->phy;
+
+	if (!phy)
+		return -ENODEV;
+
+	return phy_ethtool_gset(phy, cmd);
+}
+
+static int greth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct greth_private *greth = netdev_priv(dev);
+	struct phy_device *phy = greth->phy;
+
+	if (!phy)
+		return -ENODEV;
+
+	return phy_ethtool_sset(phy, cmd);
+}
+
+static int greth_get_regs_len(struct net_device *dev)
+{
+	return sizeof(struct greth_regs);
+}
+
+static void greth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	struct greth_private *greth = netdev_priv(dev);
+
+	strncpy(info->driver, dev_driver_string(greth->dev), 32);
+	strncpy(info->version, "revision: 1.0", 32);
+	strncpy(info->bus_info, greth->dev->bus->name, 32);
+	strncpy(info->fw_version, "N/A", 32);
+	info->eedump_len = 0;
+	info->regdump_len = sizeof(struct greth_regs);
+}
+
+static void greth_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
+{
+	int i;
+	struct greth_private *greth = netdev_priv(dev);
+	u32 __iomem *greth_regs = (u32 __iomem *) greth->regs;
+	u32 *buff = p;
+
+	for (i = 0; i < sizeof(struct greth_regs) / sizeof(u32); i++)
+		buff[i] = greth_read_bd(&greth_regs[i]);
+}
+
+static u32 greth_get_rx_csum(struct net_device *dev)
+{
+	struct greth_private *greth = netdev_priv(dev);
+	return (greth->flags & GRETH_FLAG_RX_CSUM) != 0;
+}
+
+static int greth_set_rx_csum(struct net_device *dev, u32 data)
+{
+	struct greth_private *greth = netdev_priv(dev);
+
+	spin_lock_bh(&greth->devlock);
+
+	if (data)
+		greth->flags |= GRETH_FLAG_RX_CSUM;
+	else
+		greth->flags &= ~GRETH_FLAG_RX_CSUM;
+
+	spin_unlock_bh(&greth->devlock);
+
+	return 0;
+}
+
+static u32 greth_get_tx_csum(struct net_device *dev)
+{
+	return (dev->features & NETIF_F_IP_CSUM) != 0;
+}
+
+static int greth_set_tx_csum(struct net_device *dev, u32 data)
+{
+	netif_tx_lock_bh(dev);
+	ethtool_op_set_tx_csum(dev, data);
+	netif_tx_unlock_bh(dev);
+	return 0;
+}
+
+static const struct ethtool_ops greth_ethtool_ops = {
+	.get_msglevel		= greth_get_msglevel,
+	.set_msglevel		= greth_set_msglevel,
+	.get_settings		= greth_get_settings,
+	.set_settings		= greth_set_settings,
+	.get_drvinfo		= greth_get_drvinfo,
+	.get_regs_len           = greth_get_regs_len,
+	.get_regs               = greth_get_regs,
+	.get_rx_csum		= greth_get_rx_csum,
+	.set_rx_csum		= greth_set_rx_csum,
+	.get_tx_csum		= greth_get_tx_csum,
+	.set_tx_csum		= greth_set_tx_csum,
+	.get_link		= ethtool_op_get_link,
+};
+
+static struct net_device_ops greth_netdev_ops = {
+	.ndo_open = greth_open,
+	.ndo_stop = greth_close,
+	.ndo_start_xmit = greth_start_xmit,
+	.ndo_set_mac_address = greth_set_mac_add,
+	.ndo_validate_addr 	= eth_validate_addr,
+};
+
+static inline int wait_for_mdio(struct greth_private *greth)
+{
+	unsigned long timeout = jiffies + 4*HZ/100;
+	while (GRETH_REGLOAD(greth->regs->mdio) & GRETH_MII_BUSY) {
+		if (time_after(jiffies, timeout))
+			return 0;
+	}
+	return 1;
+}
+
+static int greth_mdio_read(struct mii_bus *bus, int phy, int reg)
+{
+	struct greth_private *greth = bus->priv;
+	int data;
+
+	if (!wait_for_mdio(greth))
+		return -EBUSY;
+
+	GRETH_REGSAVE(greth->regs->mdio, ((phy & 0x1F) << 11) | ((reg & 0x1F) << 6) | 2);
+
+	if (!wait_for_mdio(greth))
+		return -EBUSY;
+
+	if (!(GRETH_REGLOAD(greth->regs->mdio) & GRETH_MII_NVALID)) {
+		data = (GRETH_REGLOAD(greth->regs->mdio) >> 16) & 0xFFFF;
+		return data;
+
+	} else {
+		return -1;
+	}
+}
+
+static int greth_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
+{
+	struct greth_private *greth = bus->priv;
+
+	if (!wait_for_mdio(greth))
+		return -EBUSY;
+
+	GRETH_REGSAVE(greth->regs->mdio,
+		      ((val & 0xFFFF) << 16) | ((phy & 0x1F) << 11) | ((reg & 0x1F) << 6) | 1);
+
+	if (!wait_for_mdio(greth))
+		return -EBUSY;
+
+	return 0;
+}
+
+static int greth_mdio_reset(struct mii_bus *bus)
+{
+	return 0;
+}
+
+static void greth_link_change(struct net_device *dev)
+{
+	struct greth_private *greth = netdev_priv(dev);
+	struct phy_device *phydev = greth->phy;
+	unsigned long flags;
+
+	int status_change = 0;
+
+	spin_lock_irqsave(&greth->devlock, flags);
+
+	if (phydev->link) {
+
+		if ((greth->speed != phydev->speed) || (greth->duplex != phydev->duplex)) {
+
+			GRETH_REGANDIN(greth->regs->control,
+				       ~(GRETH_CTRL_FD | GRETH_CTRL_SP | GRETH_CTRL_GB));
+
+			if (phydev->duplex)
+				GRETH_REGORIN(greth->regs->control, GRETH_CTRL_FD);
+
+			if (phydev->speed == SPEED_100) {
+
+				GRETH_REGORIN(greth->regs->control, GRETH_CTRL_SP);
+			}
+
+			else if (phydev->speed == SPEED_1000)
+				GRETH_REGORIN(greth->regs->control, GRETH_CTRL_GB);
+
+			greth->speed = phydev->speed;
+			greth->duplex = phydev->duplex;
+			status_change = 1;
+		}
+	}
+
+	if (phydev->link != greth->link) {
+		if (!phydev->link) {
+			greth->speed = 0;
+			greth->duplex = -1;
+		}
+		greth->link = phydev->link;
+
+		status_change = 1;
+	}
+
+	spin_unlock_irqrestore(&greth->devlock, flags);
+
+	if (status_change) {
+		if (phydev->link)
+			pr_debug("%s: link up (%d/%s)\n",
+				dev->name, phydev->speed,
+				DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
+		else
+			pr_debug("%s: link down\n", dev->name);
+	}
+}
+
+static int greth_mdio_probe(struct net_device *dev)
+{
+	struct greth_private *greth = netdev_priv(dev);
+	struct phy_device *phy = NULL;
+	int ret;
+
+	/* Find the first PHY */
+	phy = phy_find_first(greth->mdio);
+
+	if (!phy) {
+		if (netif_msg_probe(greth))
+			dev_err(&dev->dev, "no PHY found\n");
+		return -ENXIO;
+	}
+
+	ret = phy_connect_direct(dev, phy, &greth_link_change,
+			0, greth->gbit_mac ?
+			PHY_INTERFACE_MODE_GMII :
+			PHY_INTERFACE_MODE_MII);
+	if (ret) {
+		if (netif_msg_ifup(greth))
+			dev_err(&dev->dev, "could not attach to PHY\n");
+		return ret;
+	}
+
+	if (greth->gbit_mac)
+		phy->supported &= PHY_GBIT_FEATURES;
+	else
+		phy->supported &= PHY_BASIC_FEATURES;
+
+	phy->advertising = phy->supported;
+
+	greth->link = 0;
+	greth->speed = 0;
+	greth->duplex = -1;
+	greth->phy = phy;
+
+	return 0;
+}
+
+static inline int phy_aneg_done(struct phy_device *phydev)
+{
+	int retval;
+
+	retval = phy_read(phydev, MII_BMSR);
+
+	return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE);
+}
+
+static int greth_mdio_init(struct greth_private *greth)
+{
+	int ret, phy;
+	unsigned long timeout;
+
+	greth->mdio = mdiobus_alloc();
+	if (!greth->mdio) {
+		return -ENOMEM;
+	}
+
+	greth->mdio->name = "greth-mdio";
+	snprintf(greth->mdio->id, MII_BUS_ID_SIZE, "%s-%d", greth->mdio->name, greth->irq);
+	greth->mdio->read = greth_mdio_read;
+	greth->mdio->write = greth_mdio_write;
+	greth->mdio->reset = greth_mdio_reset;
+	greth->mdio->priv = greth;
+
+	greth->mdio->irq = greth->mdio_irqs;
+
+	for (phy = 0; phy < PHY_MAX_ADDR; phy++)
+		greth->mdio->irq[phy] = PHY_POLL;
+
+	ret = mdiobus_register(greth->mdio);
+	if (ret) {
+		goto error;
+	}
+
+	ret = greth_mdio_probe(greth->netdev);
+	if (ret) {
+		if (netif_msg_probe(greth))
+			dev_err(&greth->netdev->dev, "failed to probe MDIO bus\n");
+		goto unreg_mdio;
+	}
+
+	phy_start(greth->phy);
+
+	/* If Ethernet debug link is used make autoneg happen right away */
+	if (greth->edcl && greth_edcl == 1) {
+		phy_start_aneg(greth->phy);
+		timeout = jiffies + 6*HZ;
+		while (!phy_aneg_done(greth->phy) && time_before(jiffies, timeout)) {
+		}
+		genphy_read_status(greth->phy);
+		greth_link_change(greth->netdev);
+	}
+
+	return 0;
+
+unreg_mdio:
+	mdiobus_unregister(greth->mdio);
+error:
+	mdiobus_free(greth->mdio);
+	return ret;
+}
+
+/* Initialize the GRETH MAC */
+static int __devinit greth_of_probe(struct of_device *ofdev, const struct of_device_id *match)
+{
+	struct net_device *dev;
+	struct greth_private *greth;
+	struct greth_regs *regs;
+
+	int i;
+	int err;
+	int tmp;
+	unsigned long timeout;
+
+	dev = alloc_etherdev(sizeof(struct greth_private));
+
+	if (dev == NULL)
+		return -ENOMEM;
+
+	greth = netdev_priv(dev);
+	greth->netdev = dev;
+	greth->dev = &ofdev->dev;
+
+	if (greth_debug > 0)
+		greth->msg_enable = greth_debug;
+	else
+		greth->msg_enable = GRETH_DEF_MSG_ENABLE;
+
+	spin_lock_init(&greth->devlock);
+
+	greth->regs = of_ioremap(&ofdev->resource[0], 0,
+				 resource_size(&ofdev->resource[0]),
+				 "grlib-greth regs");
+
+	if (greth->regs == NULL) {
+		if (netif_msg_probe(greth))
+			dev_err(greth->dev, "ioremap failure.\n");
+		err = -EIO;
+		goto error1;
+	}
+
+	regs = (struct greth_regs *) greth->regs;
+	greth->irq = ofdev->irqs[0];
+
+	dev_set_drvdata(greth->dev, dev);
+	SET_NETDEV_DEV(dev, greth->dev);
+
+	if (netif_msg_probe(greth))
+		dev_dbg(greth->dev, "reseting controller.\n");
+
+	/* Reset the controller. */
+	GRETH_REGSAVE(regs->control, GRETH_RESET);
+
+	/* Wait for MAC to reset itself */
+	timeout = jiffies + HZ/100;
+	while (GRETH_REGLOAD(regs->control) & GRETH_RESET) {
+		if (time_after(jiffies, timeout)) {
+			err = -EIO;
+			if (netif_msg_probe(greth))
+				dev_err(greth->dev, "timeout when waiting for reset.\n");
+			goto error2;
+		}
+	}
+
+	/* Get default PHY address  */
+	greth->phyaddr = (GRETH_REGLOAD(regs->mdio) >> 11) & 0x1F;
+
+	/* Check if we have GBIT capable MAC */
+	tmp = GRETH_REGLOAD(regs->control);
+	greth->gbit_mac = (tmp >> 27) & 1;
+
+	/* Check for multicast capability */
+	greth->multicast = (tmp >> 25) & 1;
+
+	greth->edcl = (tmp >> 31) & 1;
+
+	/* If we have EDCL we disable the EDCL speed-duplex FSM so
+	 * it doesn't interfere with the software */
+	if (greth->edcl != 0)
+		GRETH_REGORIN(regs->control, GRETH_CTRL_DISDUPLEX);
+
+	/* Check if MAC can handle MDIO interrupts */
+	greth->mdio_int_en = (tmp >> 26) & 1;
+
+	err = greth_mdio_init(greth);
+	if (err) {
+		if (netif_msg_probe(greth))
+			dev_err(greth->dev, "failed to register MDIO bus\n");
+		goto error2;
+	}
+
+	/* Allocate TX descriptor ring in coherent memory */
+	greth->tx_bd_base = (struct greth_bd *) dma_alloc_coherent(greth->dev,
+								   1024,
+								   &greth->tx_bd_base_phys,
+								   GFP_KERNEL);
+
+	if (!greth->tx_bd_base) {
+		if (netif_msg_probe(greth))
+			dev_err(&dev->dev, "could not allocate descriptor memory.\n");
+		err = -ENOMEM;
+		goto error3;
+	}
+
+	memset(greth->tx_bd_base, 0, 1024);
+
+	/* Allocate RX descriptor ring in coherent memory */
+	greth->rx_bd_base = (struct greth_bd *) dma_alloc_coherent(greth->dev,
+								   1024,
+								   &greth->rx_bd_base_phys,
+								   GFP_KERNEL);
+
+	if (!greth->rx_bd_base) {
+		if (netif_msg_probe(greth))
+			dev_err(greth->dev, "could not allocate descriptor memory.\n");
+		err = -ENOMEM;
+		goto error4;
+	}
+
+	memset(greth->rx_bd_base, 0, 1024);
+
+	/* Get MAC address from: module param, OF property or ID prom */
+	for (i = 0; i < 6; i++) {
+		if (macaddr[i] != 0)
+			break;
+	}
+	if (i == 6) {
+		const unsigned char *addr;
+		int len;
+		addr = of_get_property(ofdev->node, "local-mac-address", &len);
+		if (addr != NULL && len == 6) {
+			for (i = 0; i < 6; i++)
+				macaddr[i] = (unsigned int) addr[i];
+		} else {
+#ifdef CONFIG_SPARC
+			for (i = 0; i < 6; i++)
+				macaddr[i] = (unsigned int) idprom->id_ethaddr[i];
+#endif
+		}
+	}
+
+	for (i = 0; i < 6; i++)
+		dev->dev_addr[i] = macaddr[i];
+
+	macaddr[5]++;
+
+	if (!is_valid_ether_addr(&dev->dev_addr[0])) {
+		if (netif_msg_probe(greth))
+			dev_err(greth->dev, "no valid ethernet address, aborting.\n");
+		err = -EINVAL;
+		goto error5;
+	}
+
+	GRETH_REGSAVE(regs->esa_msb, dev->dev_addr[0] << 8 | dev->dev_addr[1]);
+	GRETH_REGSAVE(regs->esa_lsb, dev->dev_addr[2] << 24 | dev->dev_addr[3] << 16 |
+		      dev->dev_addr[4] << 8 | dev->dev_addr[5]);
+
+	/* Clear all pending interrupts except PHY irq */
+	GRETH_REGSAVE(regs->status, 0xFF);
+
+	if (greth->gbit_mac) {
+		dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HIGHDMA;
+		greth_netdev_ops.ndo_start_xmit = greth_start_xmit_gbit;
+		greth->flags = GRETH_FLAG_RX_CSUM;
+	}
+
+	if (greth->multicast) {
+		greth_netdev_ops.ndo_set_multicast_list = greth_set_multicast_list;
+		dev->flags |= IFF_MULTICAST;
+	} else {
+		dev->flags &= ~IFF_MULTICAST;
+	}
+
+	dev->netdev_ops = &greth_netdev_ops;
+	dev->ethtool_ops = &greth_ethtool_ops;
+
+	if (register_netdev(dev)) {
+		if (netif_msg_probe(greth))
+			dev_err(greth->dev, "netdevice registration failed.\n");
+		err = -ENOMEM;
+		goto error5;
+	}
+
+	/* setup NAPI */
+	memset(&greth->napi, 0, sizeof(greth->napi));
+	netif_napi_add(dev, &greth->napi, greth_poll, 64);
+
+	return 0;
+
+error5:
+	dma_free_coherent(greth->dev, 1024, greth->rx_bd_base, greth->rx_bd_base_phys);
+error4:
+	dma_free_coherent(greth->dev, 1024, greth->tx_bd_base, greth->tx_bd_base_phys);
+error3:
+	mdiobus_unregister(greth->mdio);
+error2:
+	of_iounmap(&ofdev->resource[0], greth->regs, resource_size(&ofdev->resource[0]));
+error1:
+	free_netdev(dev);
+	return err;
+}
+
+static int __devexit greth_of_remove(struct of_device *of_dev)
+{
+	struct net_device *ndev = dev_get_drvdata(&of_dev->dev);
+	struct greth_private *greth = netdev_priv(ndev);
+
+	/* Free descriptor areas */
+	dma_free_coherent(&of_dev->dev, 1024, greth->rx_bd_base, greth->rx_bd_base_phys);
+
+	dma_free_coherent(&of_dev->dev, 1024, greth->tx_bd_base, greth->tx_bd_base_phys);
+
+	dev_set_drvdata(&of_dev->dev, NULL);
+
+	if (greth->phy)
+		phy_stop(greth->phy);
+	mdiobus_unregister(greth->mdio);
+
+	unregister_netdev(ndev);
+	free_netdev(ndev);
+
+	of_iounmap(&of_dev->resource[0], greth->regs, resource_size(&of_dev->resource[0]));
+
+	return 0;
+}
+
+static struct of_device_id greth_of_match[] = {
+	{
+	 .name = "GAISLER_ETHMAC",
+	 },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, greth_of_match);
+
+static struct of_platform_driver greth_of_driver = {
+	.name = "grlib-greth",
+	.match_table = greth_of_match,
+	.probe = greth_of_probe,
+	.remove = __devexit_p(greth_of_remove),
+	.driver = {
+		   .owner = THIS_MODULE,
+		   .name = "grlib-greth",
+		   },
+};
+
+static int __init greth_init(void)
+{
+	return of_register_platform_driver(&greth_of_driver);
+}
+
+static void __exit greth_cleanup(void)
+{
+	of_unregister_platform_driver(&greth_of_driver);
+}
+
+module_init(greth_init);
+module_exit(greth_cleanup);
+
+MODULE_AUTHOR("Aeroflex Gaisler AB.");
+MODULE_DESCRIPTION("Aeroflex Gaisler Ethernet MAC driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/greth.h linux-libre-2.6.34-gnu1/drivers/net/greth.h
--- linux-libre-2.6.33-gnu1/drivers/net/greth.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/greth.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,143 @@
+#ifndef GRETH_H
+#define GRETH_H
+
+#include <linux/phy.h>
+
+/* Register bits and masks */
+#define GRETH_RESET 0x40
+#define GRETH_MII_BUSY 0x8
+#define GRETH_MII_NVALID 0x10
+
+#define GRETH_CTRL_FD         0x10
+#define GRETH_CTRL_PR         0x20
+#define GRETH_CTRL_SP         0x80
+#define GRETH_CTRL_GB         0x100
+#define GRETH_CTRL_PSTATIEN   0x400
+#define GRETH_CTRL_MCEN       0x800
+#define GRETH_CTRL_DISDUPLEX  0x1000
+#define GRETH_STATUS_PHYSTAT  0x100
+
+#define GRETH_BD_EN 0x800
+#define GRETH_BD_WR 0x1000
+#define GRETH_BD_IE 0x2000
+#define GRETH_BD_LEN 0x7FF
+
+#define GRETH_TXEN 0x1
+#define GRETH_INT_TX 0x8
+#define GRETH_TXI 0x4
+#define GRETH_TXBD_STATUS 0x0001C000
+#define GRETH_TXBD_MORE 0x20000
+#define GRETH_TXBD_IPCS 0x40000
+#define GRETH_TXBD_TCPCS 0x80000
+#define GRETH_TXBD_UDPCS 0x100000
+#define GRETH_TXBD_CSALL (GRETH_TXBD_IPCS | GRETH_TXBD_TCPCS | GRETH_TXBD_UDPCS)
+#define GRETH_TXBD_ERR_LC 0x10000
+#define GRETH_TXBD_ERR_UE 0x4000
+#define GRETH_TXBD_ERR_AL 0x8000
+
+#define GRETH_INT_RX         0x4
+#define GRETH_RXEN           0x2
+#define GRETH_RXI            0x8
+#define GRETH_RXBD_STATUS    0xFFFFC000
+#define GRETH_RXBD_ERR_AE    0x4000
+#define GRETH_RXBD_ERR_FT    0x8000
+#define GRETH_RXBD_ERR_CRC   0x10000
+#define GRETH_RXBD_ERR_OE    0x20000
+#define GRETH_RXBD_ERR_LE    0x40000
+#define GRETH_RXBD_IP        0x80000
+#define GRETH_RXBD_IP_CSERR  0x100000
+#define GRETH_RXBD_UDP       0x200000
+#define GRETH_RXBD_UDP_CSERR 0x400000
+#define GRETH_RXBD_TCP       0x800000
+#define GRETH_RXBD_TCP_CSERR 0x1000000
+#define GRETH_RXBD_IP_FRAG   0x2000000
+#define GRETH_RXBD_MCAST     0x4000000
+
+/* Descriptor parameters */
+#define GRETH_TXBD_NUM 128
+#define GRETH_TXBD_NUM_MASK (GRETH_TXBD_NUM-1)
+#define GRETH_TX_BUF_SIZE 2048
+#define GRETH_RXBD_NUM 128
+#define GRETH_RXBD_NUM_MASK (GRETH_RXBD_NUM-1)
+#define GRETH_RX_BUF_SIZE 2048
+
+/* Buffers per page */
+#define GRETH_RX_BUF_PPGAE	(PAGE_SIZE/GRETH_RX_BUF_SIZE)
+#define GRETH_TX_BUF_PPGAE	(PAGE_SIZE/GRETH_TX_BUF_SIZE)
+
+/* How many pages are needed for buffers */
+#define GRETH_RX_BUF_PAGE_NUM	(GRETH_RXBD_NUM/GRETH_RX_BUF_PPGAE)
+#define GRETH_TX_BUF_PAGE_NUM	(GRETH_TXBD_NUM/GRETH_TX_BUF_PPGAE)
+
+/* Buffer size.
+ * Gbit MAC uses tagged maximum frame size which is 1518 excluding CRC.
+ * Set to 1520 to make all buffers word aligned for non-gbit MAC.
+ */
+#define MAX_FRAME_SIZE		1520
+
+/* Flags */
+#define GRETH_FLAG_RX_CSUM 0x1
+
+/* GRETH APB registers */
+struct greth_regs {
+	u32 control;
+	u32 status;
+	u32 esa_msb;
+	u32 esa_lsb;
+	u32 mdio;
+	u32 tx_desc_p;
+	u32 rx_desc_p;
+	u32 edclip;
+	u32 hash_msb;
+	u32 hash_lsb;
+};
+
+/* GRETH buffer descriptor */
+struct greth_bd {
+	u32 stat;
+	u32 addr;
+};
+
+struct greth_private {
+	struct sk_buff *rx_skbuff[GRETH_RXBD_NUM];
+	struct sk_buff *tx_skbuff[GRETH_TXBD_NUM];
+
+	unsigned char *tx_bufs[GRETH_TXBD_NUM];
+	unsigned char *rx_bufs[GRETH_RXBD_NUM];
+
+	u16 tx_next;
+	u16 tx_last;
+	u16 tx_free;
+	u16 rx_cur;
+
+	struct greth_regs *regs;	/* Address of controller registers. */
+	struct greth_bd *rx_bd_base;	/* Address of Rx BDs. */
+	struct greth_bd *tx_bd_base;	/* Address of Tx BDs. */
+	dma_addr_t rx_bd_base_phys;
+	dma_addr_t tx_bd_base_phys;
+
+	int irq;
+
+	struct device *dev;	        /* Pointer to of_device->dev */
+	struct net_device *netdev;
+	struct napi_struct napi;
+	spinlock_t devlock;
+
+	struct phy_device *phy;
+	struct mii_bus *mdio;
+	int mdio_irqs[PHY_MAX_ADDR];
+	unsigned int link;
+	unsigned int speed;
+	unsigned int duplex;
+
+	u32 msg_enable;
+	u32 flags;
+
+	u8 phyaddr;
+	u8 multicast;
+	u8 gbit_mac;
+	u8 mdio_int_en;
+	u8 edcl;
+};
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/hamachi.c linux-libre-2.6.34-gnu1/drivers/net/hamachi.c
--- linux-libre-2.6.33-gnu1/drivers/net/hamachi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/hamachi.c	2010-05-16 17:17:36.000000000 -0400
@@ -153,7 +153,6 @@ static int tx_params[MAX_UNITS] = {-1, -
 #include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -1854,17 +1853,18 @@ static void set_rx_mode(struct net_devic
 
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		writew(0x000F, ioaddr + AddrMode);
-	} else if ((dev->mc_count > 63)  ||  (dev->flags & IFF_ALLMULTI)) {
+	} else if ((netdev_mc_count(dev) > 63) || (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
 		writew(0x000B, ioaddr + AddrMode);
-	} else if (dev->mc_count > 0) { /* Must use the CAM filter. */
+	} else if (!netdev_mc_empty(dev)) { /* Must use the CAM filter. */
 		struct dev_mc_list *mclist;
-		int i;
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-			 i++, mclist = mclist->next) {
+		int i = 0;
+
+		netdev_for_each_mc_addr(mclist, dev) {
 			writel(*(u32*)(mclist->dmi_addr), ioaddr + 0x100 + i*8);
 			writel(0x20000 | (*(u16*)&mclist->dmi_addr[4]),
 				   ioaddr + 0x104 + i*8);
+			i++;
 		}
 		/* Clear remaining entries. */
 		for (; i < 64; i++)
@@ -1990,7 +1990,7 @@ static void __devexit hamachi_remove_one
 	}
 }
 
-static struct pci_device_id hamachi_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(hamachi_pci_tbl) = {
 	{ 0x1318, 0x0911, PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0, }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/hamradio/6pack.c linux-libre-2.6.34-gnu1/drivers/net/hamradio/6pack.c
--- linux-libre-2.6.33-gnu1/drivers/net/hamradio/6pack.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/hamradio/6pack.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/errno.h>
 #include <linux/netdevice.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/hamradio/bpqether.c linux-libre-2.6.34-gnu1/drivers/net/hamradio/bpqether.c
--- linux-libre-2.6.33-gnu1/drivers/net/hamradio/bpqether.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/hamradio/bpqether.c	2010-05-16 17:17:36.000000000 -0400
@@ -61,6 +61,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/hamradio/dmascc.c linux-libre-2.6.34-gnu1/drivers/net/hamradio/dmascc.c
--- linux-libre-2.6.33-gnu1/drivers/net/hamradio/dmascc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/hamradio/dmascc.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/rtnetlink.h>
 #include <linux/sockios.h>
 #include <linux/workqueue.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/hamradio/hdlcdrv.c linux-libre-2.6.34-gnu1/drivers/net/hamradio/hdlcdrv.c
--- linux-libre-2.6.33-gnu1/drivers/net/hamradio/hdlcdrv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/hamradio/hdlcdrv.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,7 +48,6 @@
 #include <linux/net.h>
 #include <linux/in.h>
 #include <linux/if.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/hamradio/mkiss.c linux-libre-2.6.34-gnu1/drivers/net/hamradio/mkiss.c
--- linux-libre-2.6.33-gnu1/drivers/net/hamradio/mkiss.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/hamradio/mkiss.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/hamradio/scc.c linux-libre-2.6.34-gnu1/drivers/net/hamradio/scc.c
--- linux-libre-2.6.33-gnu1/drivers/net/hamradio/scc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/hamradio/scc.c	2010-05-16 17:17:36.000000000 -0400
@@ -158,7 +158,6 @@
 #include <linux/in.h>
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/hp100.c linux-libre-2.6.34-gnu1/drivers/net/hp100.c
--- linux-libre-2.6.33-gnu1/drivers/net/hp100.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/hp100.c	2010-05-16 17:17:36.000000000 -0400
@@ -102,7 +102,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/eisa.h>
 #include <linux/pci.h>
@@ -210,7 +209,7 @@ MODULE_DEVICE_TABLE(eisa, hp100_eisa_tbl
 #endif
 
 #ifdef CONFIG_PCI
-static struct pci_device_id hp100_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(hp100_pci_tbl) = {
 	{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A, PCI_ANY_ID, PCI_ANY_ID,},
 	{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B, PCI_ANY_ID, PCI_ANY_ID,},
 	{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2970A, PCI_ANY_ID, PCI_ANY_ID,},
@@ -2090,7 +2089,7 @@ static void hp100_set_multicast_list(str
 		lp->mac2_mode = HP100_MAC2MODE6;	/* promiscuous mode = get all good */
 		lp->mac1_mode = HP100_MAC1MODE6;	/* packets on the net */
 		memset(&lp->hash_bytes, 0xff, 8);
-	} else if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) {
+	} else if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI)) {
 		lp->mac2_mode = HP100_MAC2MODE5;	/* multicast mode = get packets for */
 		lp->mac1_mode = HP100_MAC1MODE5;	/* me, broadcasts and all multicasts */
 #ifdef HP100_MULTICAST_FILTER	/* doesn't work!!! */
@@ -2098,22 +2097,23 @@ static void hp100_set_multicast_list(str
 			/* set hash filter to receive all multicast packets */
 			memset(&lp->hash_bytes, 0xff, 8);
 		} else {
-			int i, j, idx;
+			int i, idx;
 			u_char *addrs;
 			struct dev_mc_list *dmi;
 
 			memset(&lp->hash_bytes, 0x00, 8);
 #ifdef HP100_DEBUG
-			printk("hp100: %s: computing hash filter - mc_count = %i\n", dev->name, dev->mc_count);
+			printk("hp100: %s: computing hash filter - mc_count = %i\n",
+			       dev->name, netdev_mc_count(dev));
 #endif
-			for (i = 0, dmi = dev->mc_list; i < dev->mc_count; i++, dmi = dmi->next) {
+			netdev_for_each_mc_addr(dmi, dev) {
 				addrs = dmi->dmi_addr;
 				if ((*addrs & 0x01) == 0x01) {	/* multicast address? */
 #ifdef HP100_DEBUG
 					printk("hp100: %s: multicast = %pM, ",
 						     dev->name, addrs);
 #endif
-					for (j = idx = 0; j < 6; j++) {
+					for (i = idx = 0; i < 6; i++) {
 						idx ^= *addrs++ & 0x3f;
 						printk(":%02x:", idx);
 					}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/hplance.c linux-libre-2.6.34-gnu1/drivers/net/hplance.c
--- linux-libre-2.6.33-gnu1/drivers/net/hplance.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/hplance.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/hydra.c linux-libre-2.6.34-gnu1/drivers/net/hydra.c
--- linux-libre-2.6.33-gnu1/drivers/net/hydra.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/hydra.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ibmlana.c linux-libre-2.6.34-gnu1/drivers/net/ibmlana.c
--- linux-libre-2.6.33-gnu1/drivers/net/ibmlana.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ibmlana.c	2010-05-16 17:17:36.000000000 -0400
@@ -79,7 +79,6 @@ History:
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/time.h>
@@ -420,7 +419,7 @@ static void InitBoard(struct net_device
 	/* start putting the multicast addresses into the CAM list.  Stop if
 	   it is full. */
 
-	for (mcptr = dev->mc_list; mcptr != NULL; mcptr = mcptr->next) {
+	netdev_for_each_mc_addr(mcptr, dev) {
 		putcam(cams, &camcnt, mcptr->dmi_addr);
 		if (camcnt == 16)
 			break;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ibm_newemac/core.c linux-libre-2.6.34-gnu1/drivers/net/ibm_newemac/core.c
--- linux-libre-2.6.33-gnu1/drivers/net/ibm_newemac/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ibm_newemac/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/bitops.h>
 #include <linux/workqueue.h>
 #include <linux/of.h>
+#include <linux/slab.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
@@ -391,11 +392,11 @@ static void emac_hash_mc(struct emac_ins
 	struct dev_mc_list *dmi;
 	int i;
 
-	DBG(dev, "hash_mc %d" NL, dev->ndev->mc_count);
+	DBG(dev, "hash_mc %d" NL, netdev_mc_count(dev->ndev));
 
 	memset(gaht_temp, 0, sizeof (gaht_temp));
 
-	for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) {
+	netdev_for_each_mc_addr(dmi, dev->ndev) {
 		int slot, reg, mask;
 		DBG2(dev, "mc %pM" NL, dmi->dmi_addr);
 
@@ -425,9 +426,9 @@ static inline u32 emac_iff2rmr(struct ne
 	if (ndev->flags & IFF_PROMISC)
 		r |= EMAC_RMR_PME;
 	else if (ndev->flags & IFF_ALLMULTI ||
-			 (ndev->mc_count > EMAC_XAHT_SLOTS(dev)))
+			 (netdev_mc_count(ndev) > EMAC_XAHT_SLOTS(dev)))
 		r |= EMAC_RMR_PMME;
-	else if (ndev->mc_count > 0)
+	else if (!netdev_mc_empty(ndev))
 		r |= EMAC_RMR_MAE;
 
 	return r;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ibm_newemac/core.h linux-libre-2.6.34-gnu1/drivers/net/ibm_newemac/core.h
--- linux-libre-2.6.33-gnu1/drivers/net/ibm_newemac/core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ibm_newemac/core.h	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/dcr.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ibm_newemac/mal.c linux-libre-2.6.34-gnu1/drivers/net/ibm_newemac/mal.c
--- linux-libre-2.6.33-gnu1/drivers/net/ibm_newemac/mal.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ibm_newemac/mal.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "core.h"
 #include <asm/dcr-regs.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ibm_newemac/rgmii.c linux-libre-2.6.34-gnu1/drivers/net/ibm_newemac/rgmii.c
--- linux-libre-2.6.33-gnu1/drivers/net/ibm_newemac/rgmii.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ibm_newemac/rgmii.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
  * option) any later version.
  *
  */
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/ethtool.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ibm_newemac/zmii.c linux-libre-2.6.34-gnu1/drivers/net/ibm_newemac/zmii.c
--- linux-libre-2.6.33-gnu1/drivers/net/ibm_newemac/zmii.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ibm_newemac/zmii.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
  * option) any later version.
  *
  */
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/ethtool.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ibmveth.c linux-libre-2.6.34-gnu1/drivers/net/ibmveth.c
--- linux-libre-2.6.33-gnu1/drivers/net/ibmveth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ibmveth.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,7 @@
 #include <linux/proc_fs.h>
 #include <linux/in.h>
 #include <linux/ip.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <asm/hvcall.h>
 #include <asm/atomic.h>
@@ -1062,7 +1063,8 @@ static void ibmveth_set_multicast_list(s
 	struct ibmveth_adapter *adapter = netdev_priv(netdev);
 	unsigned long lpar_rc;
 
-	if((netdev->flags & IFF_PROMISC) || (netdev->mc_count > adapter->mcastFilterSize)) {
+	if ((netdev->flags & IFF_PROMISC) ||
+	    (netdev_mc_count(netdev) > adapter->mcastFilterSize)) {
 		lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address,
 					   IbmVethMcastEnableRecv |
 					   IbmVethMcastDisableFiltering,
@@ -1071,8 +1073,7 @@ static void ibmveth_set_multicast_list(s
 			ibmveth_error_printk("h_multicast_ctrl rc=%ld when entering promisc mode\n", lpar_rc);
 		}
 	} else {
-		struct dev_mc_list *mclist = netdev->mc_list;
-		int i;
+		struct dev_mc_list *mclist;
 		/* clear the filter table & disable filtering */
 		lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address,
 					   IbmVethMcastEnableRecv |
@@ -1083,7 +1084,7 @@ static void ibmveth_set_multicast_list(s
 			ibmveth_error_printk("h_multicast_ctrl rc=%ld when attempting to clear filter table\n", lpar_rc);
 		}
 		/* add the addresses to the filter table */
-		for(i = 0; i < netdev->mc_count; ++i, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, netdev) {
 			// add the multicast address to the filter table
 			unsigned long mcast_addr = 0;
 			memcpy(((char *)&mcast_addr)+2, mclist->dmi_addr, 6);
@@ -1577,7 +1578,7 @@ static struct attribute * veth_pool_attr
 	NULL,
 };
 
-static struct sysfs_ops veth_pool_ops = {
+static const struct sysfs_ops veth_pool_ops = {
 	.show   = veth_pool_show,
 	.store  = veth_pool_store,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_82575.c linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_82575.c
--- linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_82575.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_82575.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/if_ether.h>
 
 #include "e1000_mac.h"
@@ -94,6 +93,7 @@ static s32 igb_get_invariants_82575(stru
 	case E1000_DEV_ID_82576_FIBER:
 	case E1000_DEV_ID_82576_SERDES:
 	case E1000_DEV_ID_82576_QUAD_COPPER:
+	case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
 	case E1000_DEV_ID_82576_SERDES_QUAD:
 		mac->type = e1000_82576;
 		break;
@@ -727,6 +727,34 @@ static s32 igb_check_for_link_82575(stru
 }
 
 /**
+ *  igb_power_up_serdes_link_82575 - Power up the serdes link after shutdown
+ *  @hw: pointer to the HW structure
+ **/
+void igb_power_up_serdes_link_82575(struct e1000_hw *hw)
+{
+	u32 reg;
+
+
+	if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
+	    !igb_sgmii_active_82575(hw))
+		return;
+
+	/* Enable PCS to turn on link */
+	reg = rd32(E1000_PCS_CFG0);
+	reg |= E1000_PCS_CFG_PCS_EN;
+	wr32(E1000_PCS_CFG0, reg);
+
+	/* Power up the laser */
+	reg = rd32(E1000_CTRL_EXT);
+	reg &= ~E1000_CTRL_EXT_SDP3_DATA;
+	wr32(E1000_CTRL_EXT, reg);
+
+	/* flush the write to verify completion */
+	wrfl();
+	msleep(1);
+}
+
+/**
  *  igb_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
  *  @hw: pointer to the HW structure
  *  @speed: stores the current speed
@@ -791,27 +819,12 @@ static s32 igb_get_pcs_speed_and_duplex_
 void igb_shutdown_serdes_link_82575(struct e1000_hw *hw)
 {
 	u32 reg;
-	u16 eeprom_data = 0;
 
-	if (hw->phy.media_type != e1000_media_type_internal_serdes ||
+	if (hw->phy.media_type != e1000_media_type_internal_serdes &&
 	    igb_sgmii_active_82575(hw))
 		return;
 
-	if (hw->bus.func == E1000_FUNC_0)
-		hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
-	else if (hw->mac.type == e1000_82580)
-		hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A +
-		                 NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1,
-		                 &eeprom_data);
-	else if (hw->bus.func == E1000_FUNC_1)
-		hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
-
-	/*
-	 * If APM is not enabled in the EEPROM and management interface is
-	 * not enabled, then power down.
-	 */
-	if (!(eeprom_data & E1000_NVM_APME_82575) &&
-	    !igb_enable_mng_pass_thru(hw)) {
+	if (!igb_enable_mng_pass_thru(hw)) {
 		/* Disable PCS to turn off link */
 		reg = rd32(E1000_PCS_CFG0);
 		reg &= ~E1000_PCS_CFG_PCS_EN;
@@ -826,8 +839,6 @@ void igb_shutdown_serdes_link_82575(stru
 		wrfl();
 		msleep(1);
 	}
-
-	return;
 }
 
 /**
@@ -1183,6 +1194,22 @@ out:
 }
 
 /**
+ * igb_power_down_phy_copper_82575 - Remove link during PHY power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of a PHY power down to save power, or to turn off link during a
+ * driver unload, or wake on lan is not enabled, remove the link.
+ **/
+void igb_power_down_phy_copper_82575(struct e1000_hw *hw)
+{
+	/* If the management interface is not enabled, then power down */
+	if (!(igb_enable_mng_pass_thru(hw) || igb_check_reset_block(hw)))
+		igb_power_down_phy_copper(hw);
+
+	return;
+}
+
+/**
  *  igb_clear_hw_cntrs_82575 - Clear device specific hardware counters
  *  @hw: pointer to the HW structure
  *
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_82575.h linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_82575.h
--- linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_82575.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_82575.h	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,8 @@
 #define _E1000_82575_H_
 
 extern void igb_shutdown_serdes_link_82575(struct e1000_hw *hw);
+extern void igb_power_up_serdes_link_82575(struct e1000_hw *hw);
+extern void igb_power_down_phy_copper_82575(struct e1000_hw *hw);
 extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
 
 #define ID_LED_DEFAULT_82575_SERDES ((ID_LED_DEF1_DEF2 << 12) | \
@@ -219,6 +221,9 @@ struct e1000_adv_tx_context_desc {
 #define E1000_VLVF_LVLAN          0x00100000
 #define E1000_VLVF_VLANID_ENABLE  0x80000000
 
+#define E1000_VMVIR_VLANA_DEFAULT      0x40000000 /* Always use default VLAN */
+#define E1000_VMVIR_VLANA_NEVER        0x80000000 /* Never insert VLAN tag */
+
 #define E1000_IOVCTL 0x05BBC
 #define E1000_IOVCTL_REUSE_VFQ 0x00000001
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_defines.h linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_defines.h
--- linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_defines.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_defines.h	2010-05-16 17:17:36.000000000 -0400
@@ -313,12 +313,6 @@
 #define E1000_PBA_34K 0x0022
 #define E1000_PBA_64K 0x0040    /* 64KB */
 
-#define IFS_MAX       80
-#define IFS_MIN       40
-#define IFS_RATIO     4
-#define IFS_STEP      10
-#define MIN_NUM_XMITS 1000
-
 /* SW Semaphore Register */
 #define E1000_SWSM_SMBI         0x00000001 /* Driver Semaphore bit */
 #define E1000_SWSM_SWESMBI      0x00000002 /* FW Semaphore bit */
@@ -481,6 +475,7 @@
 /* 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 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_hw.h linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_hw.h
--- linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@ struct e1000_hw;
 #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_QUAD_COPPER_ET2    0x1526
 #define E1000_DEV_ID_82576_NS                 0x150A
 #define E1000_DEV_ID_82576_NS_SERDES          0x1518
 #define E1000_DEV_ID_82576_SERDES_QUAD        0x150D
@@ -339,19 +340,12 @@ struct e1000_mac_info {
 
 	enum e1000_mac_type type;
 
-	u32 collision_delta;
 	u32 ledctl_default;
 	u32 ledctl_mode1;
 	u32 ledctl_mode2;
 	u32 mc_filter_type;
-	u32 tx_packet_delta;
 	u32 txcw;
 
-	u16 current_ifs_val;
-	u16 ifs_max_val;
-	u16 ifs_min_val;
-	u16 ifs_ratio;
-	u16 ifs_step_size;
 	u16 mta_reg_count;
 	u16 uta_reg_count;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_mac.c linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_mac.c
--- linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_mac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_mac.c	2010-05-16 17:17:36.000000000 -0400
@@ -1304,76 +1304,6 @@ out:
 }
 
 /**
- *  igb_reset_adaptive - Reset Adaptive Interframe Spacing
- *  @hw: pointer to the HW structure
- *
- *  Reset the Adaptive Interframe Spacing throttle to default values.
- **/
-void igb_reset_adaptive(struct e1000_hw *hw)
-{
-	struct e1000_mac_info *mac = &hw->mac;
-
-	if (!mac->adaptive_ifs) {
-		hw_dbg("Not in Adaptive IFS mode!\n");
-		goto out;
-	}
-
-	if (!mac->ifs_params_forced) {
-		mac->current_ifs_val = 0;
-		mac->ifs_min_val = IFS_MIN;
-		mac->ifs_max_val = IFS_MAX;
-		mac->ifs_step_size = IFS_STEP;
-		mac->ifs_ratio = IFS_RATIO;
-	}
-
-	mac->in_ifs_mode = false;
-	wr32(E1000_AIT, 0);
-out:
-	return;
-}
-
-/**
- *  igb_update_adaptive - Update Adaptive Interframe Spacing
- *  @hw: pointer to the HW structure
- *
- *  Update the Adaptive Interframe Spacing Throttle value based on the
- *  time between transmitted packets and time between collisions.
- **/
-void igb_update_adaptive(struct e1000_hw *hw)
-{
-	struct e1000_mac_info *mac = &hw->mac;
-
-	if (!mac->adaptive_ifs) {
-		hw_dbg("Not in Adaptive IFS mode!\n");
-		goto out;
-	}
-
-	if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {
-		if (mac->tx_packet_delta > MIN_NUM_XMITS) {
-			mac->in_ifs_mode = true;
-			if (mac->current_ifs_val < mac->ifs_max_val) {
-				if (!mac->current_ifs_val)
-					mac->current_ifs_val = mac->ifs_min_val;
-				else
-					mac->current_ifs_val +=
-						mac->ifs_step_size;
-				wr32(E1000_AIT,
-						mac->current_ifs_val);
-			}
-		}
-	} else {
-		if (mac->in_ifs_mode &&
-		    (mac->tx_packet_delta <= MIN_NUM_XMITS)) {
-			mac->current_ifs_val = 0;
-			mac->in_ifs_mode = false;
-			wr32(E1000_AIT, 0);
-		}
-	}
-out:
-	return;
-}
-
-/**
  *  igb_validate_mdi_setting - Verify MDI/MDIx settings
  *  @hw: pointer to the HW structure
  *
@@ -1437,7 +1367,8 @@ out:
  *  igb_enable_mng_pass_thru - Enable processing of ARP's
  *  @hw: pointer to the HW structure
  *
- *  Verifies the hardware needs to allow ARPs to be processed by the host.
+ *  Verifies the hardware needs to leave interface enabled so that frames can
+ *  be directed to and from the management interface.
  **/
 bool igb_enable_mng_pass_thru(struct e1000_hw *hw)
 {
@@ -1450,8 +1381,7 @@ bool igb_enable_mng_pass_thru(struct e10
 
 	manc = rd32(E1000_MANC);
 
-	if (!(manc & E1000_MANC_RCV_TCO_EN) ||
-	    !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
+	if (!(manc & E1000_MANC_RCV_TCO_EN))
 		goto out;
 
 	if (hw->mac.arc_subsystem_valid) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_mac.h linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_mac.h
--- linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_mac.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_mac.h	2010-05-16 17:17:36.000000000 -0400
@@ -67,8 +67,6 @@ void igb_mta_set(struct e1000_hw *hw, u3
 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_reset_adaptive(struct e1000_hw *hw);
-void igb_update_adaptive(struct e1000_hw *hw);
 
 bool igb_enable_mng_pass_thru(struct e1000_hw *hw);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_phy.c linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_phy.c
--- linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_phy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_phy.c	2010-05-16 17:17:36.000000000 -0400
@@ -1931,6 +1931,41 @@ s32 igb_phy_init_script_igp3(struct e100
 }
 
 /**
+ * igb_power_up_phy_copper - Restore copper link in case of PHY power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of a PHY power down to save power, or to turn off link during a
+ * driver unload, restore the link to previous settings.
+ **/
+void igb_power_up_phy_copper(struct e1000_hw *hw)
+{
+	u16 mii_reg = 0;
+
+	/* The PHY will retain its settings across a power down/up cycle */
+	hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
+	mii_reg &= ~MII_CR_POWER_DOWN;
+	hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
+}
+
+/**
+ * igb_power_down_phy_copper - Power down copper PHY
+ * @hw: pointer to the HW structure
+ *
+ * Power down PHY to save power when interface is down and wake on lan
+ * is not enabled.
+ **/
+void igb_power_down_phy_copper(struct e1000_hw *hw)
+{
+	u16 mii_reg = 0;
+
+	/* The PHY will retain its settings across a power down/up cycle */
+	hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
+	mii_reg |= MII_CR_POWER_DOWN;
+	hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
+	msleep(1);
+}
+
+/**
  *  igb_check_polarity_82580 - Checks the polarity.
  *  @hw: pointer to the HW structure
  *
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_phy.h linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_phy.h
--- linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_phy.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_phy.h	2010-05-16 17:17:36.000000000 -0400
@@ -60,6 +60,8 @@ s32  igb_setup_copper_link(struct e1000_
 s32  igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
 s32  igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
 				u32 usec_interval, bool *success);
+void igb_power_up_phy_copper(struct e1000_hw *hw);
+void igb_power_down_phy_copper(struct e1000_hw *hw);
 s32  igb_phy_init_script_igp3(struct e1000_hw *hw);
 s32  igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
 s32  igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_regs.h linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_regs.h
--- linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_regs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/igb/e1000_regs.h	2010-05-16 17:17:36.000000000 -0400
@@ -310,6 +310,7 @@
 #define E1000_VMOLR(_n)        (0x05AD0 + (4 * (_n)))
 #define E1000_VLVF(_n)         (0x05D00 + (4 * (_n))) /* VLAN Virtual Machine
                                                        * Filter - RW */
+#define E1000_VMVIR(_n)        (0x03700 + (4 * (_n)))
 
 #define wr32(reg, value) (writel(value, hw->hw_addr + reg))
 #define rd32(reg) (readl(hw->hw_addr + reg))
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/igb/igb_ethtool.c linux-libre-2.6.34-gnu1/drivers/net/igb/igb_ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/igb/igb_ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/igb/igb_ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/if_ether.h>
 #include <linux/ethtool.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include "igb.h"
 
@@ -234,6 +235,24 @@ static int igb_set_settings(struct net_d
 	return 0;
 }
 
+static u32 igb_get_link(struct net_device *netdev)
+{
+	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct e1000_mac_info *mac = &adapter->hw.mac;
+
+	/*
+	 * If the link is not reported up to netdev, interrupts are disabled,
+	 * and so the physical link state may have changed since we last
+	 * looked. Set get_link_status to make sure that the true link
+	 * state is interrogated, rather than pulling a cached and possibly
+	 * stale link state from the driver.
+	 */
+	if (!netif_carrier_ok(netdev))
+		mac->get_link_status = 1;
+
+	return igb_has_link(adapter);
+}
+
 static void igb_get_pauseparam(struct net_device *netdev,
 			       struct ethtool_pauseparam *pause)
 {
@@ -296,7 +315,7 @@ static int igb_set_pauseparam(struct net
 static u32 igb_get_rx_csum(struct net_device *netdev)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
-	return !!(adapter->rx_ring[0].flags & IGB_RING_FLAG_RX_CSUM);
+	return !!(adapter->rx_ring[0]->flags & IGB_RING_FLAG_RX_CSUM);
 }
 
 static int igb_set_rx_csum(struct net_device *netdev, u32 data)
@@ -306,9 +325,9 @@ static int igb_set_rx_csum(struct net_de
 
 	for (i = 0; i < adapter->num_rx_queues; i++) {
 		if (data)
-			adapter->rx_ring[i].flags |= IGB_RING_FLAG_RX_CSUM;
+			adapter->rx_ring[i]->flags |= IGB_RING_FLAG_RX_CSUM;
 		else
-			adapter->rx_ring[i].flags &= ~IGB_RING_FLAG_RX_CSUM;
+			adapter->rx_ring[i]->flags &= ~IGB_RING_FLAG_RX_CSUM;
 	}
 
 	return 0;
@@ -771,9 +790,9 @@ static int igb_set_ringparam(struct net_
 
 	if (!netif_running(adapter->netdev)) {
 		for (i = 0; i < adapter->num_tx_queues; i++)
-			adapter->tx_ring[i].count = new_tx_count;
+			adapter->tx_ring[i]->count = new_tx_count;
 		for (i = 0; i < adapter->num_rx_queues; i++)
-			adapter->rx_ring[i].count = new_rx_count;
+			adapter->rx_ring[i]->count = new_rx_count;
 		adapter->tx_ring_count = new_tx_count;
 		adapter->rx_ring_count = new_rx_count;
 		goto clear_reset;
@@ -797,10 +816,10 @@ static int igb_set_ringparam(struct net_
 	 * to the tx and rx ring structs.
 	 */
 	if (new_tx_count != adapter->tx_ring_count) {
-		memcpy(temp_ring, adapter->tx_ring,
-		       adapter->num_tx_queues * sizeof(struct igb_ring));
-
 		for (i = 0; i < adapter->num_tx_queues; i++) {
+			memcpy(&temp_ring[i], adapter->tx_ring[i],
+			       sizeof(struct igb_ring));
+
 			temp_ring[i].count = new_tx_count;
 			err = igb_setup_tx_resources(&temp_ring[i]);
 			if (err) {
@@ -812,20 +831,21 @@ static int igb_set_ringparam(struct net_
 			}
 		}
 
-		for (i = 0; i < adapter->num_tx_queues; i++)
-			igb_free_tx_resources(&adapter->tx_ring[i]);
+		for (i = 0; i < adapter->num_tx_queues; i++) {
+			igb_free_tx_resources(adapter->tx_ring[i]);
 
-		memcpy(adapter->tx_ring, temp_ring,
-		       adapter->num_tx_queues * sizeof(struct igb_ring));
+			memcpy(adapter->tx_ring[i], &temp_ring[i],
+			       sizeof(struct igb_ring));
+		}
 
 		adapter->tx_ring_count = new_tx_count;
 	}
 
-	if (new_rx_count != adapter->rx_ring->count) {
-		memcpy(temp_ring, adapter->rx_ring,
-		       adapter->num_rx_queues * sizeof(struct igb_ring));
-
+	if (new_rx_count != adapter->rx_ring_count) {
 		for (i = 0; i < adapter->num_rx_queues; i++) {
+			memcpy(&temp_ring[i], adapter->rx_ring[i],
+			       sizeof(struct igb_ring));
+
 			temp_ring[i].count = new_rx_count;
 			err = igb_setup_rx_resources(&temp_ring[i]);
 			if (err) {
@@ -838,11 +858,12 @@ static int igb_set_ringparam(struct net_
 
 		}
 
-		for (i = 0; i < adapter->num_rx_queues; i++)
-			igb_free_rx_resources(&adapter->rx_ring[i]);
+		for (i = 0; i < adapter->num_rx_queues; i++) {
+			igb_free_rx_resources(adapter->rx_ring[i]);
 
-		memcpy(adapter->rx_ring, temp_ring,
-		       adapter->num_rx_queues * sizeof(struct igb_ring));
+			memcpy(adapter->rx_ring[i], &temp_ring[i],
+			       sizeof(struct igb_ring));
+		}
 
 		adapter->rx_ring_count = new_rx_count;
 	}
@@ -1704,6 +1725,9 @@ static void igb_diag_test(struct net_dev
 
 		dev_info(&adapter->pdev->dev, "offline testing starting\n");
 
+		/* power up link for link test */
+		igb_power_up_link(adapter);
+
 		/* Link test performed before hardware reset so autoneg doesn't
 		 * interfere with test result */
 		if (igb_link_test(adapter, &data[4]))
@@ -1727,6 +1751,8 @@ static void igb_diag_test(struct net_dev
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 		igb_reset(adapter);
+		/* power up link for loopback test */
+		igb_power_up_link(adapter);
 		if (igb_loopback_test(adapter, &data[3]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
@@ -1745,9 +1771,14 @@ static void igb_diag_test(struct net_dev
 			dev_open(netdev);
 	} else {
 		dev_info(&adapter->pdev->dev, "online testing starting\n");
-		/* Online tests */
-		if (igb_link_test(adapter, &data[4]))
-			eth_test->flags |= ETH_TEST_FL_FAILED;
+
+		/* PHY is powered down when interface is down */
+		if (!netif_carrier_ok(netdev)) {
+			data[4] = 0;
+		} else {
+			if (igb_link_test(adapter, &data[4]))
+				eth_test->flags |= ETH_TEST_FL_FAILED;
+		}
 
 		/* Online tests aren't run; pass by default */
 		data[0] = 0;
@@ -1783,6 +1814,7 @@ static int igb_wol_exclusion(struct igb_
 		retval = 0;
 		break;
 	case E1000_DEV_ID_82576_QUAD_COPPER:
+	case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
 		/* quad port adapters only support WoL on port A */
 		if (!(adapter->flags & IGB_FLAG_QUAD_PORT_A)) {
 			wol->supported = 0;
@@ -1812,7 +1844,8 @@ static void igb_get_wol(struct net_devic
 	struct igb_adapter *adapter = netdev_priv(netdev);
 
 	wol->supported = WAKE_UCAST | WAKE_MCAST |
-			 WAKE_BCAST | WAKE_MAGIC;
+	                 WAKE_BCAST | WAKE_MAGIC |
+	                 WAKE_PHY;
 	wol->wolopts = 0;
 
 	/* this function will set ->supported = 0 and return 1 if wol is not
@@ -1835,15 +1868,15 @@ static void igb_get_wol(struct net_devic
 		wol->wolopts |= WAKE_BCAST;
 	if (adapter->wol & E1000_WUFC_MAG)
 		wol->wolopts |= WAKE_MAGIC;
-
-	return;
+	if (adapter->wol & E1000_WUFC_LNKC)
+		wol->wolopts |= WAKE_PHY;
 }
 
 static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 
-	if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
+	if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE))
 		return -EOPNOTSUPP;
 
 	if (igb_wol_exclusion(adapter, wol) ||
@@ -1861,6 +1894,8 @@ static int igb_set_wol(struct net_device
 		adapter->wol |= E1000_WUFC_BC;
 	if (wol->wolopts & WAKE_MAGIC)
 		adapter->wol |= E1000_WUFC_MAG;
+	if (wol->wolopts & WAKE_PHY)
+		adapter->wol |= E1000_WUFC_LNKC;
 	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
 
 	return 0;
@@ -2005,12 +2040,12 @@ static void igb_get_ethtool_stats(struct
 			sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
 	}
 	for (j = 0; j < adapter->num_tx_queues; j++) {
-		queue_stat = (u64 *)&adapter->tx_ring[j].tx_stats;
+		queue_stat = (u64 *)&adapter->tx_ring[j]->tx_stats;
 		for (k = 0; k < IGB_TX_QUEUE_STATS_LEN; k++, i++)
 			data[i] = queue_stat[k];
 	}
 	for (j = 0; j < adapter->num_rx_queues; j++) {
-		queue_stat = (u64 *)&adapter->rx_ring[j].rx_stats;
+		queue_stat = (u64 *)&adapter->rx_ring[j]->rx_stats;
 		for (k = 0; k < IGB_RX_QUEUE_STATS_LEN; k++, i++)
 			data[i] = queue_stat[k];
 	}
@@ -2074,7 +2109,7 @@ static const struct ethtool_ops igb_etht
 	.get_msglevel           = igb_get_msglevel,
 	.set_msglevel           = igb_set_msglevel,
 	.nway_reset             = igb_nway_reset,
-	.get_link               = ethtool_op_get_link,
+	.get_link               = igb_get_link,
 	.get_eeprom_len         = igb_get_eeprom_len,
 	.get_eeprom             = igb_get_eeprom,
 	.set_eeprom             = igb_set_eeprom,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/igb/igb.h linux-libre-2.6.34-gnu1/drivers/net/igb/igb.h
--- linux-libre-2.6.33-gnu1/drivers/net/igb/igb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/igb/igb.h	2010-05-16 17:17:36.000000000 -0400
@@ -75,11 +75,14 @@ struct vf_data_storage {
 	u16 vlans_enabled;
 	u32 flags;
 	unsigned long last_nack;
+	u16 pf_vlan; /* When set, guest VLAN config not allowed. */
+	u16 pf_qos;
 };
 
 #define IGB_VF_FLAG_CTS            0x00000001 /* VF is clear to send data */
 #define IGB_VF_FLAG_UNI_PROMISC    0x00000002 /* VF has unicast promisc */
 #define IGB_VF_FLAG_MULTI_PROMISC  0x00000004 /* VF has multicast promisc */
+#define IGB_VF_FLAG_PF_SET_MAC     0x00000008 /* PF has set MAC address */
 
 /* RX descriptor control thresholds.
  * PTHRESH - MAC will consider prefetch if it has fewer than this number of
@@ -92,13 +95,13 @@ struct vf_data_storage {
  *           descriptors until either it has this many to write back, or the
  *           ITR timer expires.
  */
-#define IGB_RX_PTHRESH                    (hw->mac.type <= e1000_82576 ? 16 : 8)
+#define IGB_RX_PTHRESH                     8
 #define IGB_RX_HTHRESH                     8
 #define IGB_RX_WTHRESH                     1
 #define IGB_TX_PTHRESH                     8
 #define IGB_TX_HTHRESH                     1
 #define IGB_TX_WTHRESH                     ((hw->mac.type == e1000_82576 && \
-                                             adapter->msix_entries) ? 0 : 16)
+                                             adapter->msix_entries) ? 1 : 16)
 
 /* this is the size past which hardware will drop packets when setting LPE=0 */
 #define MAXIMUM_ETHERNET_VLAN_SIZE 1522
@@ -138,6 +141,7 @@ struct igb_buffer {
 			u16 length;
 			u16 next_to_watch;
 			u16 mapped_as_page;
+			u16 gso_segs;
 		};
 		/* RX */
 		struct {
@@ -173,7 +177,6 @@ struct igb_q_vector {
 
 	u16 itr_val;
 	u8 set_itr;
-	u8 itr_shift;
 	void __iomem *itr_register;
 
 	char name[IFNAMSIZ + 9];
@@ -238,7 +241,6 @@ static inline int igb_desc_unused(struct
 }
 
 /* board specific private data structure */
-
 struct igb_adapter {
 	struct timer_list watchdog_timer;
 	struct timer_list phy_info_timer;
@@ -264,12 +266,11 @@ struct igb_adapter {
 	unsigned long led_status;
 
 	/* TX */
-	struct igb_ring *tx_ring;      /* One per active queue */
-	unsigned long tx_queue_len;
+	struct igb_ring *tx_ring[16];
 	u32 tx_timeout_count;
 
 	/* RX */
-	struct igb_ring *rx_ring;      /* One per active queue */
+	struct igb_ring *rx_ring[16];
 	int num_tx_queues;
 	int num_rx_queues;
 
@@ -354,7 +355,9 @@ extern void igb_unmap_and_free_tx_resour
 					   struct igb_buffer *);
 extern void igb_alloc_rx_buffers_adv(struct igb_ring *, int);
 extern void igb_update_stats(struct igb_adapter *);
+extern bool igb_has_link(struct igb_adapter *adapter);
 extern void igb_set_ethtool_ops(struct net_device *);
+extern void igb_power_up_link(struct igb_adapter *);
 
 static inline s32 igb_reset_phy(struct e1000_hw *hw)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/igb/igb_main.c linux-libre-2.6.34-gnu1/drivers/net/igb/igb_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/igb/igb_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/igb/igb_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/pagemap.h>
 #include <linux/netdevice.h>
 #include <linux/ipv6.h>
+#include <linux/slab.h>
 #include <net/checksum.h>
 #include <net/ip6_checksum.h>
 #include <linux/net_tstamp.h>
@@ -60,7 +61,7 @@ static const struct e1000_info *igb_info
 	[board_82575] = &e1000_82575_info,
 };
 
-static struct pci_device_id igb_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = {
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_FIBER), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SERDES), board_82575 },
@@ -72,6 +73,7 @@ static struct pci_device_id igb_pci_tbl[
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES_QUAD), board_82575 },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER_ET2), 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 },
@@ -133,6 +135,12 @@ static void igb_msg_task(struct igb_adap
 static void igb_vmm_control(struct igb_adapter *);
 static int igb_set_vf_mac(struct igb_adapter *, int, unsigned char *);
 static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
+static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac);
+static int igb_ndo_set_vf_vlan(struct net_device *netdev,
+			       int vf, u16 vlan, u8 qos);
+static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate);
+static int igb_ndo_get_vf_config(struct net_device *netdev, int vf,
+				 struct ifla_vf_info *ivi);
 
 #ifdef CONFIG_PM
 static int igb_suspend(struct pci_dev *, pm_message_t);
@@ -312,31 +320,35 @@ static void igb_cache_ring_register(stru
 		 */
 		if (adapter->vfs_allocated_count) {
 			for (; i < adapter->rss_queues; i++)
-				adapter->rx_ring[i].reg_idx = rbase_offset +
-				                              Q_IDX_82576(i);
+				adapter->rx_ring[i]->reg_idx = rbase_offset +
+				                               Q_IDX_82576(i);
 			for (; j < adapter->rss_queues; j++)
-				adapter->tx_ring[j].reg_idx = rbase_offset +
-				                              Q_IDX_82576(j);
+				adapter->tx_ring[j]->reg_idx = rbase_offset +
+				                               Q_IDX_82576(j);
 		}
 	case e1000_82575:
 	case e1000_82580:
 	default:
 		for (; i < adapter->num_rx_queues; i++)
-			adapter->rx_ring[i].reg_idx = rbase_offset + i;
+			adapter->rx_ring[i]->reg_idx = rbase_offset + i;
 		for (; j < adapter->num_tx_queues; j++)
-			adapter->tx_ring[j].reg_idx = rbase_offset + j;
+			adapter->tx_ring[j]->reg_idx = rbase_offset + j;
 		break;
 	}
 }
 
 static void igb_free_queues(struct igb_adapter *adapter)
 {
-	kfree(adapter->tx_ring);
-	kfree(adapter->rx_ring);
-
-	adapter->tx_ring = NULL;
-	adapter->rx_ring = NULL;
+	int i;
 
+	for (i = 0; i < adapter->num_tx_queues; i++) {
+		kfree(adapter->tx_ring[i]);
+		adapter->tx_ring[i] = NULL;
+	}
+	for (i = 0; i < adapter->num_rx_queues; i++) {
+		kfree(adapter->rx_ring[i]);
+		adapter->rx_ring[i] = NULL;
+	}
 	adapter->num_rx_queues = 0;
 	adapter->num_tx_queues = 0;
 }
@@ -350,20 +362,13 @@ static void igb_free_queues(struct igb_a
  **/
 static int igb_alloc_queues(struct igb_adapter *adapter)
 {
+	struct igb_ring *ring;
 	int i;
 
-	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
-				   sizeof(struct igb_ring), GFP_KERNEL);
-	if (!adapter->tx_ring)
-		goto err;
-
-	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
-				   sizeof(struct igb_ring), GFP_KERNEL);
-	if (!adapter->rx_ring)
-		goto err;
-
 	for (i = 0; i < adapter->num_tx_queues; i++) {
-		struct igb_ring *ring = &(adapter->tx_ring[i]);
+		ring = kzalloc(sizeof(struct igb_ring), GFP_KERNEL);
+		if (!ring)
+			goto err;
 		ring->count = adapter->tx_ring_count;
 		ring->queue_index = i;
 		ring->pdev = adapter->pdev;
@@ -371,10 +376,13 @@ static int igb_alloc_queues(struct igb_a
 		/* For 82575, context index must be unique per ring. */
 		if (adapter->hw.mac.type == e1000_82575)
 			ring->flags = IGB_RING_FLAG_TX_CTX_IDX;
+		adapter->tx_ring[i] = ring;
 	}
 
 	for (i = 0; i < adapter->num_rx_queues; i++) {
-		struct igb_ring *ring = &(adapter->rx_ring[i]);
+		ring = kzalloc(sizeof(struct igb_ring), GFP_KERNEL);
+		if (!ring)
+			goto err;
 		ring->count = adapter->rx_ring_count;
 		ring->queue_index = i;
 		ring->pdev = adapter->pdev;
@@ -384,6 +392,7 @@ static int igb_alloc_queues(struct igb_a
 		/* set flag indicating ring supports SCTP checksum offload */
 		if (adapter->hw.mac.type >= e1000_82576)
 			ring->flags |= IGB_RING_FLAG_RX_SCTP_CSUM;
+		adapter->rx_ring[i] = ring;
 	}
 
 	igb_cache_ring_register(adapter);
@@ -498,6 +507,12 @@ static void igb_assign_vector(struct igb
 		BUG();
 		break;
 	}
+
+	/* add q_vector eims value to global eims_enable_mask */
+	adapter->eims_enable_mask |= q_vector->eims_value;
+
+	/* configure q_vector to set itr on first interrupt */
+	q_vector->set_itr = 1;
 }
 
 /**
@@ -555,11 +570,8 @@ static void igb_configure_msix(struct ig
 
 	adapter->eims_enable_mask |= adapter->eims_other;
 
-	for (i = 0; i < adapter->num_q_vectors; i++) {
-		struct igb_q_vector *q_vector = adapter->q_vector[i];
-		igb_assign_vector(q_vector, vector++);
-		adapter->eims_enable_mask |= q_vector->eims_value;
-	}
+	for (i = 0; i < adapter->num_q_vectors; i++)
+		igb_assign_vector(adapter->q_vector[i], vector++);
 
 	wrfl();
 }
@@ -639,6 +651,8 @@ static void igb_free_q_vectors(struct ig
 	for (v_idx = 0; v_idx < adapter->num_q_vectors; v_idx++) {
 		struct igb_q_vector *q_vector = adapter->q_vector[v_idx];
 		adapter->q_vector[v_idx] = NULL;
+		if (!q_vector)
+			continue;
 		netif_napi_del(&q_vector->napi);
 		kfree(q_vector);
 	}
@@ -676,7 +690,7 @@ static void igb_set_interrupt_capability
 	/* start with one vector for every rx queue */
 	numvecs = adapter->num_rx_queues;
 
-	/* if tx handler is seperate add 1 for every tx queue */
+	/* if tx handler is separate add 1 for every tx queue */
 	if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS))
 		numvecs += adapter->num_tx_queues;
 
@@ -750,33 +764,24 @@ static int igb_alloc_q_vectors(struct ig
 		if (!q_vector)
 			goto err_out;
 		q_vector->adapter = adapter;
-		q_vector->itr_shift = (hw->mac.type == e1000_82575) ? 16 : 0;
 		q_vector->itr_register = hw->hw_addr + E1000_EITR(0);
 		q_vector->itr_val = IGB_START_ITR;
-		q_vector->set_itr = 1;
 		netif_napi_add(adapter->netdev, &q_vector->napi, igb_poll, 64);
 		adapter->q_vector[v_idx] = q_vector;
 	}
 	return 0;
 
 err_out:
-	while (v_idx) {
-		v_idx--;
-		q_vector = adapter->q_vector[v_idx];
-		netif_napi_del(&q_vector->napi);
-		kfree(q_vector);
-		adapter->q_vector[v_idx] = NULL;
-	}
+	igb_free_q_vectors(adapter);
 	return -ENOMEM;
 }
 
 static void igb_map_rx_ring_to_vector(struct igb_adapter *adapter,
                                       int ring_idx, int v_idx)
 {
-	struct igb_q_vector *q_vector;
+	struct igb_q_vector *q_vector = adapter->q_vector[v_idx];
 
-	q_vector = adapter->q_vector[v_idx];
-	q_vector->rx_ring = &adapter->rx_ring[ring_idx];
+	q_vector->rx_ring = adapter->rx_ring[ring_idx];
 	q_vector->rx_ring->q_vector = q_vector;
 	q_vector->itr_val = adapter->rx_itr_setting;
 	if (q_vector->itr_val && q_vector->itr_val <= 3)
@@ -786,10 +791,9 @@ static void igb_map_rx_ring_to_vector(st
 static void igb_map_tx_ring_to_vector(struct igb_adapter *adapter,
                                       int ring_idx, int v_idx)
 {
-	struct igb_q_vector *q_vector;
+	struct igb_q_vector *q_vector = adapter->q_vector[v_idx];
 
-	q_vector = adapter->q_vector[v_idx];
-	q_vector->tx_ring = &adapter->tx_ring[ring_idx];
+	q_vector->tx_ring = adapter->tx_ring[ring_idx];
 	q_vector->tx_ring->q_vector = q_vector;
 	q_vector->itr_val = adapter->tx_itr_setting;
 	if (q_vector->itr_val && q_vector->itr_val <= 3)
@@ -1099,14 +1103,34 @@ static void igb_configure(struct igb_ada
 	 * 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];
+		struct igb_ring *ring = adapter->rx_ring[i];
 		igb_alloc_rx_buffers_adv(ring, igb_desc_unused(ring));
 	}
+}
 
-
-	adapter->tx_queue_len = netdev->tx_queue_len;
+/**
+ * igb_power_up_link - Power up the phy/serdes link
+ * @adapter: address of board private structure
+ **/
+void igb_power_up_link(struct igb_adapter *adapter)
+{
+	if (adapter->hw.phy.media_type == e1000_media_type_copper)
+		igb_power_up_phy_copper(&adapter->hw);
+	else
+		igb_power_up_serdes_link_82575(&adapter->hw);
 }
 
+/**
+ * igb_power_down_link - Power down the phy/serdes link
+ * @adapter: address of board private structure
+ */
+static void igb_power_down_link(struct igb_adapter *adapter)
+{
+	if (adapter->hw.phy.media_type == e1000_media_type_copper)
+		igb_power_down_phy_copper_82575(&adapter->hw);
+	else
+		igb_shutdown_serdes_link_82575(&adapter->hw);
+}
 
 /**
  * igb_up - Open the interface and prepare it to handle traffic
@@ -1187,7 +1211,6 @@ void igb_down(struct igb_adapter *adapte
 	del_timer_sync(&adapter->watchdog_timer);
 	del_timer_sync(&adapter->phy_info_timer);
 
-	netdev->tx_queue_len = adapter->tx_queue_len;
 	netif_carrier_off(netdev);
 
 	/* record the stats before reset*/
@@ -1328,12 +1351,14 @@ void igb_reset(struct igb_adapter *adapt
 		wr32(E1000_PCIEMISC,
 		                reg & ~E1000_PCIEMISC_LX_DECISION);
 	}
+	if (!netif_running(adapter->netdev))
+		igb_power_down_link(adapter);
+
 	igb_update_mng_vlan(adapter);
 
 	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
 	wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE);
 
-	igb_reset_adaptive(hw);
 	igb_get_phy_info(hw);
 }
 
@@ -1352,6 +1377,10 @@ static const struct net_device_ops igb_n
 	.ndo_vlan_rx_register	= igb_vlan_rx_register,
 	.ndo_vlan_rx_add_vid	= igb_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid	= igb_vlan_rx_kill_vid,
+	.ndo_set_vf_mac		= igb_ndo_set_vf_mac,
+	.ndo_set_vf_vlan	= igb_ndo_set_vf_vlan,
+	.ndo_set_vf_tx_rate	= igb_ndo_set_vf_bw,
+	.ndo_get_vf_config	= igb_ndo_get_vf_config,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= igb_netpoll,
 #endif
@@ -1472,7 +1501,6 @@ static int __devinit igb_probe(struct pc
 	igb_get_bus_info_pcie(hw);
 
 	hw->phy.autoneg_wait_to_complete = false;
-	hw->mac.adaptive_ifs = true;
 
 	/* Copper options */
 	if (hw->phy.media_type == e1000_media_type_copper) {
@@ -1584,6 +1612,7 @@ static int __devinit igb_probe(struct pc
 			adapter->eeprom_wol = 0;
 		break;
 	case E1000_DEV_ID_82576_QUAD_COPPER:
+	case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
 		/* if quad port adapter, disable WoL on all but port A */
 		if (global_quad_port_a != 0)
 			adapter->eeprom_wol = 0;
@@ -1706,9 +1735,6 @@ static void __devexit igb_remove(struct
 
 	unregister_netdev(netdev);
 
-	if (!igb_check_reset_block(hw))
-		igb_reset_phy(hw);
-
 	igb_clear_interrupt_scheme(adapter);
 
 #ifdef CONFIG_PCI_IOV
@@ -1984,7 +2010,7 @@ static int igb_open(struct net_device *n
 	if (err)
 		goto err_setup_rx;
 
-	/* e1000_power_up_phy(adapter); */
+	igb_power_up_link(adapter);
 
 	/* before we allocate an interrupt, we must be ready to handle it.
 	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
@@ -2026,7 +2052,7 @@ static int igb_open(struct net_device *n
 
 err_req_irq:
 	igb_release_hw_control(adapter);
-	/* e1000_power_down_phy(adapter); */
+	igb_power_down_link(adapter);
 	igb_free_all_rx_resources(adapter);
 err_setup_rx:
 	igb_free_all_tx_resources(adapter);
@@ -2114,19 +2140,19 @@ static int igb_setup_all_tx_resources(st
 	int i, err = 0;
 
 	for (i = 0; i < adapter->num_tx_queues; i++) {
-		err = igb_setup_tx_resources(&adapter->tx_ring[i]);
+		err = igb_setup_tx_resources(adapter->tx_ring[i]);
 		if (err) {
 			dev_err(&pdev->dev,
 				"Allocation for Tx Queue %u failed\n", i);
 			for (i--; i >= 0; i--)
-				igb_free_tx_resources(&adapter->tx_ring[i]);
+				igb_free_tx_resources(adapter->tx_ring[i]);
 			break;
 		}
 	}
 
 	for (i = 0; i < IGB_ABS_MAX_TX_QUEUES; i++) {
 		int r_idx = i % adapter->num_tx_queues;
-		adapter->multi_tx_table[i] = &adapter->tx_ring[r_idx];
+		adapter->multi_tx_table[i] = adapter->tx_ring[r_idx];
 	}
 	return err;
 }
@@ -2209,7 +2235,7 @@ static void igb_configure_tx(struct igb_
 	int i;
 
 	for (i = 0; i < adapter->num_tx_queues; i++)
-		igb_configure_tx_ring(adapter, &adapter->tx_ring[i]);
+		igb_configure_tx_ring(adapter, adapter->tx_ring[i]);
 }
 
 /**
@@ -2267,12 +2293,12 @@ static int igb_setup_all_rx_resources(st
 	int i, err = 0;
 
 	for (i = 0; i < adapter->num_rx_queues; i++) {
-		err = igb_setup_rx_resources(&adapter->rx_ring[i]);
+		err = igb_setup_rx_resources(adapter->rx_ring[i]);
 		if (err) {
 			dev_err(&pdev->dev,
 				"Allocation for Rx Queue %u failed\n", i);
 			for (i--; i >= 0; i--)
-				igb_free_rx_resources(&adapter->rx_ring[i]);
+				igb_free_rx_resources(adapter->rx_ring[i]);
 			break;
 		}
 	}
@@ -2479,7 +2505,8 @@ static void igb_rlpml_set(struct igb_ada
 	wr32(E1000_RLPML, max_frame_size);
 }
 
-static inline void igb_set_vmolr(struct igb_adapter *adapter, int vfn)
+static inline void igb_set_vmolr(struct igb_adapter *adapter,
+				 int vfn, bool aupe)
 {
 	struct e1000_hw *hw = &adapter->hw;
 	u32 vmolr;
@@ -2492,8 +2519,11 @@ static inline void igb_set_vmolr(struct
 		return;
 
 	vmolr = rd32(E1000_VMOLR(vfn));
-	vmolr |= E1000_VMOLR_AUPE |        /* Accept untagged packets */
-	         E1000_VMOLR_STRVLAN;      /* Strip vlan tags */
+	vmolr |= E1000_VMOLR_STRVLAN;      /* Strip vlan tags */
+	if (aupe)
+		vmolr |= E1000_VMOLR_AUPE;        /* Accept untagged packets */
+	else
+		vmolr &= ~(E1000_VMOLR_AUPE); /* Tagged packets ONLY */
 
 	/* clear all bits that might not be set */
 	vmolr &= ~(E1000_VMOLR_BAM | E1000_VMOLR_RSSE);
@@ -2560,11 +2590,14 @@ void igb_configure_rx_ring(struct igb_ad
 		         E1000_SRRCTL_BSIZEPKT_SHIFT;
 		srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
 	}
+	/* Only set Drop Enable if we are supporting multiple queues */
+	if (adapter->vfs_allocated_count || adapter->num_rx_queues > 1)
+		srrctl |= E1000_SRRCTL_DROP_EN;
 
 	wr32(E1000_SRRCTL(reg_idx), srrctl);
 
 	/* set filtering for VMDQ pools */
-	igb_set_vmolr(adapter, reg_idx & 0x7);
+	igb_set_vmolr(adapter, reg_idx & 0x7, true);
 
 	/* enable receive descriptor fetching */
 	rxdctl = rd32(E1000_RXDCTL(reg_idx));
@@ -2596,7 +2629,7 @@ 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++)
-		igb_configure_rx_ring(adapter, &adapter->rx_ring[i]);
+		igb_configure_rx_ring(adapter, adapter->rx_ring[i]);
 }
 
 /**
@@ -2633,7 +2666,7 @@ static void igb_free_all_tx_resources(st
 	int i;
 
 	for (i = 0; i < adapter->num_tx_queues; i++)
-		igb_free_tx_resources(&adapter->tx_ring[i]);
+		igb_free_tx_resources(adapter->tx_ring[i]);
 }
 
 void igb_unmap_and_free_tx_resource(struct igb_ring *tx_ring,
@@ -2700,7 +2733,7 @@ static void igb_clean_all_tx_rings(struc
 	int i;
 
 	for (i = 0; i < adapter->num_tx_queues; i++)
-		igb_clean_tx_ring(&adapter->tx_ring[i]);
+		igb_clean_tx_ring(adapter->tx_ring[i]);
 }
 
 /**
@@ -2737,7 +2770,7 @@ static void igb_free_all_rx_resources(st
 	int i;
 
 	for (i = 0; i < adapter->num_rx_queues; i++)
-		igb_free_rx_resources(&adapter->rx_ring[i]);
+		igb_free_rx_resources(adapter->rx_ring[i]);
 }
 
 /**
@@ -2801,7 +2834,7 @@ static void igb_clean_all_rx_rings(struc
 	int i;
 
 	for (i = 0; i < adapter->num_rx_queues; i++)
-		igb_clean_rx_ring(&adapter->rx_ring[i]);
+		igb_clean_rx_ring(adapter->rx_ring[i]);
 }
 
 /**
@@ -2843,38 +2876,30 @@ static int igb_write_mc_addr_list(struct
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
-	struct dev_mc_list *mc_ptr = netdev->mc_list;
+	struct dev_mc_list *mc_ptr;
 	u8  *mta_list;
-	u32 vmolr = 0;
 	int i;
 
-	if (!netdev->mc_count) {
+	if (netdev_mc_empty(netdev)) {
 		/* nothing to program, so clear mc list */
 		igb_update_mc_addr_list(hw, NULL, 0);
 		igb_restore_vf_multicasts(adapter);
 		return 0;
 	}
 
-	mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
+	mta_list = kzalloc(netdev_mc_count(netdev) * 6, GFP_ATOMIC);
 	if (!mta_list)
 		return -ENOMEM;
 
-	/* set vmolr receive overflow multicast bit */
-	vmolr |= E1000_VMOLR_ROMPE;
-
 	/* The shared function expects a packed array of only addresses. */
-	mc_ptr = netdev->mc_list;
+	i = 0;
+	netdev_for_each_mc_addr(mc_ptr, netdev)
+		memcpy(mta_list + (i++ * ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
 
-	for (i = 0; i < netdev->mc_count; i++) {
-		if (!mc_ptr)
-			break;
-		memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
-		mc_ptr = mc_ptr->next;
-	}
 	igb_update_mc_addr_list(hw, mta_list, i);
 	kfree(mta_list);
 
-	return netdev->mc_count;
+	return netdev_mc_count(netdev);
 }
 
 /**
@@ -2895,12 +2920,13 @@ static int igb_write_uc_addr_list(struct
 	int count = 0;
 
 	/* return ENOMEM indicating insufficient memory for addresses */
-	if (netdev->uc.count > rar_entries)
+	if (netdev_uc_count(netdev) > rar_entries)
 		return -ENOMEM;
 
-	if (netdev->uc.count && rar_entries) {
+	if (!netdev_uc_empty(netdev) && rar_entries) {
 		struct netdev_hw_addr *ha;
-		list_for_each_entry(ha, &netdev->uc.list, list) {
+
+		netdev_for_each_uc_addr(ha, netdev) {
 			if (!rar_entries)
 				break;
 			igb_rar_set_qsel(adapter, ha->addr,
@@ -3004,7 +3030,7 @@ 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)
+bool igb_has_link(struct igb_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
 	bool link_active = false;
@@ -3078,17 +3104,13 @@ static void igb_watchdog_task(struct wor
 			       ((ctrl & E1000_CTRL_RFCE) ?  "RX" :
 			       ((ctrl & E1000_CTRL_TFCE) ?  "TX" : "None")));
 
-			/* tweak tx_queue_len according to speed/duplex and
-			 * adjust the timeout factor */
-			netdev->tx_queue_len = adapter->tx_queue_len;
+			/* adjust timeout factor according to speed/duplex */
 			adapter->tx_timeout_factor = 1;
 			switch (adapter->link_speed) {
 			case SPEED_10:
-				netdev->tx_queue_len = 10;
 				adapter->tx_timeout_factor = 14;
 				break;
 			case SPEED_100:
-				netdev->tx_queue_len = 100;
 				/* maybe add some timeout factor ? */
 				break;
 			}
@@ -3121,10 +3143,9 @@ static void igb_watchdog_task(struct wor
 	}
 
 	igb_update_stats(adapter);
-	igb_update_adaptive(hw);
 
 	for (i = 0; i < adapter->num_tx_queues; i++) {
-		struct igb_ring *tx_ring = &adapter->tx_ring[i];
+		struct igb_ring *tx_ring = adapter->tx_ring[i];
 		if (!netif_carrier_ok(netdev)) {
 			/* We've lost link, so the controller stops DMA,
 			 * but we've got queued Tx work that's never going
@@ -3225,6 +3246,10 @@ static void igb_update_ring_itr(struct i
 	else
 		new_val = avg_wire_size / 2;
 
+	/* when in itr mode 3 do not exceed 20K ints/sec */
+	if (adapter->rx_itr_setting == 3 && new_val < 196)
+		new_val = 196;
+
 set_itr_val:
 	if (new_val != q_vector->itr_val) {
 		q_vector->itr_val = new_val;
@@ -3320,13 +3345,13 @@ static void igb_set_itr(struct igb_adapt
 
 	adapter->rx_itr = igb_update_itr(adapter,
 				    adapter->rx_itr,
-				    adapter->rx_ring->total_packets,
-				    adapter->rx_ring->total_bytes);
+				    q_vector->rx_ring->total_packets,
+				    q_vector->rx_ring->total_bytes);
 
 	adapter->tx_itr = igb_update_itr(adapter,
 				    adapter->tx_itr,
-				    adapter->tx_ring->total_packets,
-				    adapter->tx_ring->total_bytes);
+				    q_vector->tx_ring->total_packets,
+				    q_vector->tx_ring->total_bytes);
 	current_itr = max(adapter->rx_itr, adapter->tx_itr);
 
 	/* conservative mode (itr 3) eliminates the lowest_latency setting */
@@ -3349,10 +3374,10 @@ static void igb_set_itr(struct igb_adapt
 	}
 
 set_itr_now:
-	adapter->rx_ring->total_bytes = 0;
-	adapter->rx_ring->total_packets = 0;
-	adapter->tx_ring->total_bytes = 0;
-	adapter->tx_ring->total_packets = 0;
+	q_vector->rx_ring->total_bytes = 0;
+	q_vector->rx_ring->total_packets = 0;
+	q_vector->tx_ring->total_bytes = 0;
+	q_vector->tx_ring->total_packets = 0;
 
 	if (new_itr != q_vector->itr_val) {
 		/* this attempts to bias the interrupt rate towards Bulk
@@ -3392,8 +3417,8 @@ static inline int igb_tso_adv(struct igb
 	int err;
 	struct igb_buffer *buffer_info;
 	u32 info = 0, tu_cmd = 0;
-	u32 mss_l4len_idx, l4len;
-	*hdr_len = 0;
+	u32 mss_l4len_idx;
+	u8 l4len;
 
 	if (skb_header_cloned(skb)) {
 		err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
@@ -3599,6 +3624,7 @@ static inline int igb_tx_map_adv(struct
 	}
 
 	tx_ring->buffer_info[i].skb = skb;
+	tx_ring->buffer_info[i].gso_segs = skb_shinfo(skb)->gso_segs ?: 1;
 	tx_ring->buffer_info[first].next_to_watch = i;
 
 	return ++count;
@@ -3612,14 +3638,12 @@ dma_error:
 	buffer_info->length = 0;
 	buffer_info->next_to_watch = 0;
 	buffer_info->mapped_as_page = false;
-	count--;
 
 	/* clear timestamp and dma mappings for remaining portion of packet */
-	while (count >= 0) {
-		count--;
+	while (count--) {
+		if (i == 0)
+			i = tx_ring->count;
 		i--;
-		if (i < 0)
-			i += tx_ring->count;
 		buffer_info = &tx_ring->buffer_info[i];
 		igb_unmap_and_free_tx_resource(tx_ring, buffer_info);
 	}
@@ -3628,7 +3652,7 @@ dma_error:
 }
 
 static inline void igb_tx_queue_adv(struct igb_ring *tx_ring,
-				    int tx_flags, int count, u32 paylen,
+				    u32 tx_flags, int count, u32 paylen,
 				    u8 hdr_len)
 {
 	union e1000_adv_tx_desc *tx_desc;
@@ -3716,7 +3740,7 @@ static int __igb_maybe_stop_tx(struct ig
 	return 0;
 }
 
-static int igb_maybe_stop_tx(struct igb_ring *tx_ring, int size)
+static inline int igb_maybe_stop_tx(struct igb_ring *tx_ring, int size)
 {
 	if (igb_desc_unused(tx_ring) >= size)
 		return 0;
@@ -3727,10 +3751,10 @@ netdev_tx_t igb_xmit_frame_ring_adv(stru
 				    struct igb_ring *tx_ring)
 {
 	struct igb_adapter *adapter = netdev_priv(tx_ring->netdev);
-	unsigned int first;
-	unsigned int tx_flags = 0;
-	u8 hdr_len = 0;
 	int tso = 0, count;
+	u32 tx_flags = 0;
+	u16 first;
+	u8 hdr_len = 0;
 	union skb_shared_tx *shtx = skb_tx(skb);
 
 	/* need: 1 descriptor per page,
@@ -3911,7 +3935,7 @@ static int igb_change_mtu(struct net_dev
 	netdev->mtu = new_mtu;
 
 	for (i = 0; i < adapter->num_rx_queues; i++)
-		adapter->rx_ring[i].rx_buffer_len = rx_buffer_len;
+		adapter->rx_ring[i]->rx_buffer_len = rx_buffer_len;
 
 	if (netif_running(netdev))
 		igb_up(adapter);
@@ -3933,7 +3957,7 @@ void igb_update_stats(struct igb_adapter
 	struct net_device_stats *net_stats = igb_get_stats(adapter->netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	struct pci_dev *pdev = adapter->pdev;
-	u32 rnbc;
+	u32 reg, mpc;
 	u16 phy_tmp;
 	int i;
 	u64 bytes, packets;
@@ -3953,10 +3977,11 @@ void igb_update_stats(struct igb_adapter
 	packets = 0;
 	for (i = 0; i < adapter->num_rx_queues; i++) {
 		u32 rqdpc_tmp = rd32(E1000_RQDPC(i)) & 0x0FFF;
-		adapter->rx_ring[i].rx_stats.drops += rqdpc_tmp;
+		struct igb_ring *ring = adapter->rx_ring[i];
+		ring->rx_stats.drops += rqdpc_tmp;
 		net_stats->rx_fifo_errors += rqdpc_tmp;
-		bytes += adapter->rx_ring[i].rx_stats.bytes;
-		packets += adapter->rx_ring[i].rx_stats.packets;
+		bytes += ring->rx_stats.bytes;
+		packets += ring->rx_stats.packets;
 	}
 
 	net_stats->rx_bytes = bytes;
@@ -3965,8 +3990,9 @@ void igb_update_stats(struct igb_adapter
 	bytes = 0;
 	packets = 0;
 	for (i = 0; i < adapter->num_tx_queues; i++) {
-		bytes += adapter->tx_ring[i].tx_stats.bytes;
-		packets += adapter->tx_ring[i].tx_stats.packets;
+		struct igb_ring *ring = adapter->tx_ring[i];
+		bytes += ring->tx_stats.bytes;
+		packets += ring->tx_stats.packets;
 	}
 	net_stats->tx_bytes = bytes;
 	net_stats->tx_packets = packets;
@@ -3989,7 +4015,9 @@ void igb_update_stats(struct igb_adapter
 	adapter->stats.symerrs += rd32(E1000_SYMERRS);
 	adapter->stats.sec += rd32(E1000_SEC);
 
-	adapter->stats.mpc += rd32(E1000_MPC);
+	mpc = rd32(E1000_MPC);
+	adapter->stats.mpc += mpc;
+	net_stats->rx_fifo_errors += mpc;
 	adapter->stats.scc += rd32(E1000_SCC);
 	adapter->stats.ecol += rd32(E1000_ECOL);
 	adapter->stats.mcc += rd32(E1000_MCC);
@@ -4004,9 +4032,7 @@ void igb_update_stats(struct igb_adapter
 	adapter->stats.gptc += rd32(E1000_GPTC);
 	adapter->stats.gotc += rd32(E1000_GOTCL);
 	rd32(E1000_GOTCH); /* clear GOTCL */
-	rnbc = rd32(E1000_RNBC);
-	adapter->stats.rnbc += rnbc;
-	net_stats->rx_fifo_errors += rnbc;
+	adapter->stats.rnbc += rd32(E1000_RNBC);
 	adapter->stats.ruc += rd32(E1000_RUC);
 	adapter->stats.rfc += rd32(E1000_RFC);
 	adapter->stats.rjc += rd32(E1000_RJC);
@@ -4024,15 +4050,17 @@ void igb_update_stats(struct igb_adapter
 	adapter->stats.mptc += rd32(E1000_MPTC);
 	adapter->stats.bptc += rd32(E1000_BPTC);
 
-	/* used for adaptive IFS */
-	hw->mac.tx_packet_delta = rd32(E1000_TPT);
-	adapter->stats.tpt += hw->mac.tx_packet_delta;
-	hw->mac.collision_delta = rd32(E1000_COLC);
-	adapter->stats.colc += hw->mac.collision_delta;
+	adapter->stats.tpt += rd32(E1000_TPT);
+	adapter->stats.colc += rd32(E1000_COLC);
 
 	adapter->stats.algnerrc += rd32(E1000_ALGNERRC);
-	adapter->stats.rxerrc += rd32(E1000_RXERRC);
-	adapter->stats.tncrs += rd32(E1000_TNCRS);
+	/* read internal phy specific stats */
+	reg = rd32(E1000_CTRL_EXT);
+	if (!(reg & E1000_CTRL_EXT_LINK_MODE_MASK)) {
+		adapter->stats.rxerrc += rd32(E1000_RXERRC);
+		adapter->stats.tncrs += rd32(E1000_TNCRS);
+	}
+
 	adapter->stats.tsctc += rd32(E1000_TSCTC);
 	adapter->stats.tsctfc += rd32(E1000_TSCTFC);
 
@@ -4095,6 +4123,9 @@ 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_DRSTA)
+		schedule_work(&adapter->reset_task);
+
 	if (icr & E1000_ICR_DOUTSYNC) {
 		/* HW is reporting DMA is out of sync */
 		adapter->stats.doosync++;
@@ -4124,6 +4155,7 @@ static irqreturn_t igb_msix_other(int ir
 
 static void igb_write_itr(struct igb_q_vector *q_vector)
 {
+	struct igb_adapter *adapter = q_vector->adapter;
 	u32 itr_val = q_vector->itr_val & 0x7FFC;
 
 	if (!q_vector->set_itr)
@@ -4132,8 +4164,8 @@ static void igb_write_itr(struct igb_q_v
 	if (!itr_val)
 		itr_val = 0x4;
 
-	if (q_vector->itr_shift)
-		itr_val |= itr_val << q_vector->itr_shift;
+	if (adapter->hw.mac.type == e1000_82575)
+		itr_val |= itr_val << 16;
 	else
 		itr_val |= 0x8000000;
 
@@ -4210,9 +4242,8 @@ static void igb_setup_dca(struct igb_ada
 	wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_CB2);
 
 	for (i = 0; i < adapter->num_q_vectors; i++) {
-		struct igb_q_vector *q_vector = adapter->q_vector[i];
-		q_vector->cpu = -1;
-		igb_update_dca(q_vector);
+		adapter->q_vector[i]->cpu = -1;
+		igb_update_dca(adapter->q_vector[i]);
 	}
 }
 
@@ -4486,10 +4517,57 @@ static s32 igb_vlvf_set(struct igb_adapt
 				reg |= size;
 				wr32(E1000_VMOLR(vf), reg);
 			}
-			return 0;
 		}
 	}
-	return -1;
+	return 0;
+}
+
+static void igb_set_vmvir(struct igb_adapter *adapter, u32 vid, u32 vf)
+{
+	struct e1000_hw *hw = &adapter->hw;
+
+	if (vid)
+		wr32(E1000_VMVIR(vf), (vid | E1000_VMVIR_VLANA_DEFAULT));
+	else
+		wr32(E1000_VMVIR(vf), 0);
+}
+
+static int igb_ndo_set_vf_vlan(struct net_device *netdev,
+			       int vf, u16 vlan, u8 qos)
+{
+	int err = 0;
+	struct igb_adapter *adapter = netdev_priv(netdev);
+
+	if ((vf >= adapter->vfs_allocated_count) || (vlan > 4095) || (qos > 7))
+		return -EINVAL;
+	if (vlan || qos) {
+		err = igb_vlvf_set(adapter, vlan, !!vlan, vf);
+		if (err)
+			goto out;
+		igb_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf);
+		igb_set_vmolr(adapter, vf, !vlan);
+		adapter->vf_data[vf].pf_vlan = vlan;
+		adapter->vf_data[vf].pf_qos = qos;
+		dev_info(&adapter->pdev->dev,
+			 "Setting VLAN %d, QOS 0x%x on VF %d\n", vlan, qos, vf);
+		if (test_bit(__IGB_DOWN, &adapter->state)) {
+			dev_warn(&adapter->pdev->dev,
+				 "The VF VLAN has been set,"
+				 " but the PF device is not up.\n");
+			dev_warn(&adapter->pdev->dev,
+				 "Bring the PF device up before"
+				 " attempting to use the VF device.\n");
+		}
+	} else {
+		igb_vlvf_set(adapter, adapter->vf_data[vf].pf_vlan,
+				   false, vf);
+		igb_set_vmvir(adapter, vlan, vf);
+		igb_set_vmolr(adapter, vf, true);
+		adapter->vf_data[vf].pf_vlan = 0;
+		adapter->vf_data[vf].pf_qos = 0;
+       }
+out:
+       return err;
 }
 
 static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
@@ -4502,15 +4580,21 @@ static int igb_set_vf_vlan(struct igb_ad
 
 static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf)
 {
-	/* clear all flags */
-	adapter->vf_data[vf].flags = 0;
+	/* clear flags */
+	adapter->vf_data[vf].flags &= ~(IGB_VF_FLAG_PF_SET_MAC);
 	adapter->vf_data[vf].last_nack = jiffies;
 
 	/* reset offloads to defaults */
-	igb_set_vmolr(adapter, vf);
+	igb_set_vmolr(adapter, vf, true);
 
 	/* reset vlans for device */
 	igb_clear_vf_vfta(adapter, vf);
+	if (adapter->vf_data[vf].pf_vlan)
+		igb_ndo_set_vf_vlan(adapter->netdev, vf,
+				    adapter->vf_data[vf].pf_vlan,
+				    adapter->vf_data[vf].pf_qos);
+	else
+		igb_clear_vf_vfta(adapter, vf);
 
 	/* reset multicast table array for vf */
 	adapter->vf_data[vf].num_vf_mc_hashes = 0;
@@ -4524,7 +4608,8 @@ static void igb_vf_reset_event(struct ig
 	unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses;
 
 	/* generate a new mac address as we were hotplug removed/added */
-	random_ether_addr(vf_mac);
+	if (!(adapter->vf_data[vf].flags & IGB_VF_FLAG_PF_SET_MAC))
+		random_ether_addr(vf_mac);
 
 	/* process remaining reset events */
 	igb_vf_reset(adapter, vf);
@@ -4637,7 +4722,10 @@ static void igb_rcv_msg_from_vf(struct i
 		retval = igb_set_vf_rlpml(adapter, msgbuf[1], vf);
 		break;
 	case E1000_VF_SET_VLAN:
-		retval = igb_set_vf_vlan(adapter, msgbuf, vf);
+		if (adapter->vf_data[vf].pf_vlan)
+			retval = -1;
+		else
+			retval = igb_set_vf_vlan(adapter, msgbuf, vf);
 		break;
 	default:
 		dev_err(&pdev->dev, "Unhandled Msg %08x\n", msgbuf[0]);
@@ -4718,6 +4806,9 @@ static irqreturn_t igb_intr_msi(int irq,
 
 	igb_write_itr(q_vector);
 
+	if (icr & E1000_ICR_DRSTA)
+		schedule_work(&adapter->reset_task);
+
 	if (icr & E1000_ICR_DOUTSYNC) {
 		/* HW is reporting DMA is out of sync */
 		adapter->stats.doosync++;
@@ -4757,6 +4848,9 @@ static irqreturn_t igb_intr(int irq, voi
 	if (!(icr & E1000_ICR_INT_ASSERTED))
 		return IRQ_NONE;
 
+	if (icr & E1000_ICR_DRSTA)
+		schedule_work(&adapter->reset_task);
+
 	if (icr & E1000_ICR_DOUTSYNC) {
 		/* HW is reporting DMA is out of sync */
 		adapter->stats.doosync++;
@@ -4920,7 +5014,7 @@ static bool igb_clean_tx_irq(struct igb_
 			if (skb) {
 				unsigned int segs, bytecount;
 				/* gso_segs is currently only valid for tcp */
-				segs = skb_shinfo(skb)->gso_segs ?: 1;
+				segs = buffer_info->gso_segs;
 				/* multiply data chunks by size of headers */
 				bytecount = ((segs - 1) * skb_headlen(skb)) +
 					    skb->len;
@@ -5010,7 +5104,7 @@ static void igb_receive_skb(struct igb_q
 {
 	struct igb_adapter *adapter = q_vector->adapter;
 
-	if (vlan_tag)
+	if (vlan_tag && adapter->vlgrp)
 		vlan_gro_receive(&q_vector->napi, adapter->vlgrp,
 		                 vlan_tag, skb);
 	else
@@ -5738,7 +5832,9 @@ static int __igb_shutdown(struct pci_dev
 
 	*enable_wake = wufc || adapter->en_mng_pt;
 	if (!*enable_wake)
-		igb_shutdown_serdes_link_82575(hw);
+		igb_power_down_link(adapter);
+	else
+		igb_power_up_link(adapter);
 
 	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
 	 * would have already happened in close and is redundant. */
@@ -5778,6 +5874,7 @@ static int igb_resume(struct pci_dev *pd
 
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
+	pci_save_state(pdev);
 
 	err = pci_enable_device_mem(pdev);
 	if (err) {
@@ -5795,8 +5892,6 @@ static int igb_resume(struct pci_dev *pd
 		return -ENOMEM;
 	}
 
-	/* e1000_power_up_phy(adapter); */
-
 	igb_reset(adapter);
 
 	/* let the f/w know that the h/w is now under the control of the
@@ -5905,6 +6000,7 @@ static pci_ers_result_t igb_io_slot_rese
 	} else {
 		pci_set_master(pdev);
 		pci_restore_state(pdev);
+		pci_save_state(pdev);
 
 		pci_enable_wake(pdev, PCI_D3hot, 0);
 		pci_enable_wake(pdev, PCI_D3cold, 0);
@@ -5993,6 +6089,43 @@ static int igb_set_vf_mac(struct igb_ada
 	return 0;
 }
 
+static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
+{
+	struct igb_adapter *adapter = netdev_priv(netdev);
+	if (!is_valid_ether_addr(mac) || (vf >= adapter->vfs_allocated_count))
+		return -EINVAL;
+	adapter->vf_data[vf].flags |= IGB_VF_FLAG_PF_SET_MAC;
+	dev_info(&adapter->pdev->dev, "setting MAC %pM on VF %d\n", mac, vf);
+	dev_info(&adapter->pdev->dev, "Reload the VF driver to make this"
+				      " change effective.");
+	if (test_bit(__IGB_DOWN, &adapter->state)) {
+		dev_warn(&adapter->pdev->dev, "The VF MAC address has been set,"
+			 " but the PF device is not up.\n");
+		dev_warn(&adapter->pdev->dev, "Bring the PF device up before"
+			 " attempting to use the VF device.\n");
+	}
+	return igb_set_vf_mac(adapter, vf, mac);
+}
+
+static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate)
+{
+	return -EOPNOTSUPP;
+}
+
+static int igb_ndo_get_vf_config(struct net_device *netdev,
+				 int vf, struct ifla_vf_info *ivi)
+{
+	struct igb_adapter *adapter = netdev_priv(netdev);
+	if (vf >= adapter->vfs_allocated_count)
+		return -EINVAL;
+	ivi->vf = vf;
+	memcpy(&ivi->mac, adapter->vf_data[vf].vf_mac_addresses, ETH_ALEN);
+	ivi->tx_rate = 0;
+	ivi->vlan = adapter->vf_data[vf].pf_vlan;
+	ivi->qos = adapter->vf_data[vf].pf_qos;
+	return 0;
+}
+
 static void igb_vmm_control(struct igb_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/igbvf/igbvf.h linux-libre-2.6.34-gnu1/drivers/net/igbvf/igbvf.h
--- linux-libre-2.6.33-gnu1/drivers/net/igbvf/igbvf.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/igbvf/igbvf.h	2010-05-16 17:17:36.000000000 -0400
@@ -198,7 +198,6 @@ struct igbvf_adapter {
 	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;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/igbvf/netdev.c linux-libre-2.6.34-gnu1/drivers/net/igbvf/netdev.c
--- linux-libre-2.6.33-gnu1/drivers/net/igbvf/netdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/igbvf/netdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/netdevice.h>
 #include <linux/tcp.h>
 #include <linux/ipv6.h>
+#include <linux/slab.h>
 #include <net/checksum.h>
 #include <net/ip6_checksum.h>
 #include <linux/mii.h>
@@ -1304,8 +1305,6 @@ static void igbvf_configure_tx(struct ig
 
 	/* enable Report Status bit */
 	adapter->txd_cmd |= E1000_ADVTXD_DCMD_RS;
-
-	adapter->tx_queue_len = adapter->netdev->tx_queue_len;
 }
 
 /**
@@ -1403,8 +1402,8 @@ static void igbvf_set_multi(struct net_d
 	u8  *mta_list = NULL;
 	int i;
 
-	if (netdev->mc_count) {
-		mta_list = kmalloc(netdev->mc_count * 6, GFP_ATOMIC);
+	if (!netdev_mc_empty(netdev)) {
+		mta_list = kmalloc(netdev_mc_count(netdev) * 6, GFP_ATOMIC);
 		if (!mta_list) {
 			dev_err(&adapter->pdev->dev,
 			        "failed to allocate multicast filter list\n");
@@ -1413,15 +1412,9 @@ static void igbvf_set_multi(struct net_d
 	}
 
 	/* 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;
-	}
+	i = 0;
+	netdev_for_each_mc_addr(mc_ptr, netdev)
+		memcpy(mta_list + (i++ * ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
 
 	hw->mac.ops.update_mc_addr_list(hw, mta_list, i, 0, 0);
 	kfree(mta_list);
@@ -1530,7 +1523,6 @@ void igbvf_down(struct igbvf_adapter *ad
 
 	del_timer_sync(&adapter->watchdog_timer);
 
-	netdev->tx_queue_len = adapter->tx_queue_len;
 	netif_carrier_off(netdev);
 
 	/* record the stats before reset*/
@@ -1863,21 +1855,15 @@ static void igbvf_watchdog_task(struct w
 			                          &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;
+			/* adjust timeout factor according to speed/duplex */
 			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;
 			}
@@ -2609,11 +2595,7 @@ static void igbvf_print_device_info(stru
 	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, "Address: %pM\n", netdev->dev_addr);
 	dev_info(&pdev->dev, "MAC: %d\n", hw->mac.type);
 }
 
@@ -2779,11 +2761,8 @@ static int __devinit igbvf_probe(struct
 	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]);
+		dev_err(&pdev->dev, "Invalid MAC Address: %pM\n",
+		        netdev->dev_addr);
 		err = -EIO;
 		goto err_hw_init;
 	}
@@ -2885,7 +2864,7 @@ static struct pci_error_handlers igbvf_e
 	.resume = igbvf_io_resume,
 };
 
-static struct pci_device_id igbvf_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(igbvf_pci_tbl) = {
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_VF), board_vf },
 	{ } /* terminate list */
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ioc3-eth.c linux-libre-2.6.34-gnu1/drivers/net/ioc3-eth.c
--- linux-libre-2.6.33-gnu1/drivers/net/ioc3-eth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ioc3-eth.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,7 @@
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #ifdef CONFIG_SERIAL_8250
 #include <linux/serial_core.h>
@@ -1383,7 +1384,7 @@ static void __devexit ioc3_remove_one (s
 	 */
 }
 
-static struct pci_device_id ioc3_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(ioc3_pci_tbl) = {
 	{ PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, PCI_ANY_ID, PCI_ANY_ID },
 	{ 0 }
 };
@@ -1664,11 +1665,10 @@ static int ioc3_ioctl(struct net_device
 
 static void ioc3_set_multicast_list(struct net_device *dev)
 {
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	struct ioc3_private *ip = netdev_priv(dev);
 	struct ioc3 *ioc3 = ip->regs;
 	u64 ehar = 0;
-	int i;
 
 	netif_stop_queue(dev);				/* Lock out others. */
 
@@ -1681,16 +1681,16 @@ static void ioc3_set_multicast_list(stru
 		ioc3_w_emcr(ip->emcr);			/* Clear promiscuous. */
 		(void) ioc3_r_emcr();
 
-		if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) {
+		if ((dev->flags & IFF_ALLMULTI) ||
+		    (netdev_mc_count(dev) > 64)) {
 			/* Too many for hashing to make sense or we want all
 			   multicast packets anyway,  so skip computing all the
 			   hashes and just accept all packets.  */
 			ip->ehar_h = 0xffffffff;
 			ip->ehar_l = 0xffffffff;
 		} else {
-			for (i = 0; i < dev->mc_count; i++) {
+			netdev_for_each_mc_addr(dmi, dev) {
 				char *addr = dmi->dmi_addr;
-				dmi = dmi->next;
 
 				if (!(*addr & 1))
 					continue;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ipg.c linux-libre-2.6.34-gnu1/drivers/net/ipg.c
--- linux-libre-2.6.33-gnu1/drivers/net/ipg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ipg.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  */
 #include <linux/crc32.h>
 #include <linux/ethtool.h>
+#include <linux/gfp.h>
 #include <linux/mii.h>
 #include <linux/mutex.h>
 
@@ -88,17 +89,15 @@ static const char *ipg_brand_name[] = {
 	"Sundance Technology ST2021 based NIC",
 	"Tamarack Microelectronics TC9020/9021 based NIC",
 	"Tamarack Microelectronics TC9020/9021 based NIC",
-	"D-Link NIC",
 	"D-Link NIC IP1000A"
 };
 
-static struct pci_device_id ipg_pci_tbl[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(ipg_pci_tbl) = {
 	{ PCI_VDEVICE(SUNDANCE,	0x1023), 0 },
 	{ PCI_VDEVICE(SUNDANCE,	0x2021), 1 },
 	{ PCI_VDEVICE(SUNDANCE,	0x1021), 2 },
 	{ PCI_VDEVICE(DLINK,	0x9021), 3 },
-	{ PCI_VDEVICE(DLINK,	0x4000), 4 },
-	{ PCI_VDEVICE(DLINK,	0x4020), 5 },
+	{ PCI_VDEVICE(DLINK,	0x4020), 4 },
 	{ 0, }
 };
 
@@ -585,11 +584,11 @@ static void ipg_nic_set_multicast_list(s
 		receivemode = IPG_RM_RECEIVEALLFRAMES;
 	} else if ((dev->flags & IFF_ALLMULTI) ||
 		   ((dev->flags & IFF_MULTICAST) &&
-		    (dev->mc_count > IPG_MULTICAST_HASHTABLE_SIZE))) {
+		    (netdev_mc_count(dev) > IPG_MULTICAST_HASHTABLE_SIZE))) {
 		/* NIC to be configured to receive all multicast
 		 * frames. */
 		receivemode |= IPG_RM_RECEIVEMULTICAST;
-	} else if ((dev->flags & IFF_MULTICAST) && (dev->mc_count > 0)) {
+	} else if ((dev->flags & IFF_MULTICAST) && !netdev_mc_empty(dev)) {
 		/* NIC to be configured to receive selected
 		 * multicast addresses. */
 		receivemode |= IPG_RM_RECEIVEMULTICASTHASH;
@@ -610,8 +609,7 @@ static void ipg_nic_set_multicast_list(s
 	hashtable[1] = 0x00000000;
 
 	/* Cycle through all multicast addresses to filter. */
-	for (mc_list_ptr = dev->mc_list;
-	     mc_list_ptr != NULL; mc_list_ptr = mc_list_ptr->next) {
+	netdev_for_each_mc_addr(mc_list_ptr, dev) {
 		/* Calculate CRC result for each multicast address. */
 		hashindex = crc32_le(0xffffffff, mc_list_ptr->dmi_addr,
 				     ETH_ALEN);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/ali-ircc.c linux-libre-2.6.34-gnu1/drivers/net/irda/ali-ircc.c
--- linux-libre-2.6.33-gnu1/drivers/net/irda/ali-ircc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/ali-ircc.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  ********************************************************************/
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -29,7 +30,6 @@
 #include <linux/netdevice.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/serial_reg.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/au1k_ir.c linux-libre-2.6.34-gnu1/drivers/net/irda/au1k_ir.c
--- linux-libre-2.6.33-gnu1/drivers/net/irda/au1k_ir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/au1k_ir.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <asm/pb1000.h>
 #elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
 #include <asm/db1x00.h>
+#include <asm/mach-db1x00/bcsr.h>
 #else 
 #error au1k_ir: unsupported board
 #endif
@@ -66,10 +67,6 @@ static char version[] __devinitdata =
 
 #define RUN_AT(x) (jiffies + (x))
 
-#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
-static BCSR * const bcsr = (BCSR *)0xAE000000;
-#endif
-
 static DEFINE_SPINLOCK(ir_lock);
 
 /*
@@ -282,9 +279,8 @@ static int au1k_irda_net_init(struct net
 
 #if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
 	/* power on */
-	bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK;
-	bcsr->resets |= BCSR_RESETS_IRDA_MODE_FULL;
-	au_sync();
+	bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK,
+			      BCSR_RESETS_IRDA_MODE_FULL);
 #endif
 
 	return 0;
@@ -720,14 +716,14 @@ au1k_irda_set_speed(struct net_device *d
 
 	if (speed == 4000000) {
 #if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
-		bcsr->resets |= BCSR_RESETS_FIR_SEL;
+		bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_FIR_SEL);
 #else /* Pb1000 and Pb1100 */
 		writel(1<<13, CPLD_AUX1);
 #endif
 	}
 	else {
 #if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
-		bcsr->resets &= ~BCSR_RESETS_FIR_SEL;
+		bcsr_mod(BCSR_RESETS, BCSR_RESETS_FIR_SEL, 0);
 #else /* Pb1000 and Pb1100 */
 		writel(readl(CPLD_AUX1) & ~(1<<13), CPLD_AUX1);
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/bfin_sir.h linux-libre-2.6.34-gnu1/drivers/net/irda/bfin_sir.h
--- linux-libre-2.6.33-gnu1/drivers/net/irda/bfin_sir.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/bfin_sir.h	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/wrapper.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/donauboe.c linux-libre-2.6.34-gnu1/drivers/net/irda/donauboe.c
--- linux-libre-2.6.33-gnu1/drivers/net/irda/donauboe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/donauboe.c	2010-05-16 17:17:36.000000000 -0400
@@ -184,7 +184,7 @@
 #define CONFIG0H_DMA_ON_NORX CONFIG0H_DMA_OFF| OBOE_CONFIG0H_ENDMAC
 #define CONFIG0H_DMA_ON CONFIG0H_DMA_ON_NORX | OBOE_CONFIG0H_ENRX
 
-static struct pci_device_id toshoboe_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(toshoboe_pci_tbl) = {
 	{ PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIR701, PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIRD01, PCI_ANY_ID, PCI_ANY_ID, },
 	{ }			/* Terminating entry */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/irda-usb.c linux-libre-2.6.34-gnu1/drivers/net/irda/irda-usb.c
--- linux-libre-2.6.33-gnu1/drivers/net/irda/irda-usb.c	2013-05-03 12:08:52.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/irda-usb.c	2013-05-03 09:48:23.000000000 -0400
@@ -1648,6 +1648,8 @@ static int irda_usb_probe(struct usb_int
 
 	self->rx_urb = kcalloc(self->max_rx_urb, sizeof(struct urb *),
 				GFP_KERNEL);
+	if (!self->rx_urb)
+		goto err_free_net;
 
 	for (i = 0; i < self->max_rx_urb; i++) {
 		self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
@@ -1780,6 +1782,8 @@ err_out_2:
 err_out_1:
 	for (i = 0; i < self->max_rx_urb; i++)
 		usb_free_urb(self->rx_urb[i]);
+	kfree(self->rx_urb);
+err_free_net:
 	free_netdev(net);
 err_out:
 	return ret;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/irtty-sir.c linux-libre-2.6.34-gnu1/drivers/net/irda/irtty-sir.c
--- linux-libre-2.6.33-gnu1/drivers/net/irda/irtty-sir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/irtty-sir.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/Kconfig linux-libre-2.6.34-gnu1/drivers/net/irda/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/net/irda/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -64,6 +64,16 @@ endchoice
 
 comment "Dongle support"
 
+config SH_SIR
+	tristate "SuperH SIR on UART"
+	depends on IRDA && SUPERH && \
+		(CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7723 || \
+		 CPU_SUBTYPE_SH7724)
+	default n
+	help
+	  Say Y here if your want to enable SIR function on SuperH UART
+	  devices.
+
 config DONGLE
 	bool "Serial dongle support"
 	depends on IRTTY_SIR
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/Makefile linux-libre-2.6.34-gnu1/drivers/net/irda/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/irda/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@ obj-$(CONFIG_AU1000_FIR)	+= au1k_ir.o
 # SIR drivers
 obj-$(CONFIG_IRTTY_SIR)		+= irtty-sir.o	sir-dev.o
 obj-$(CONFIG_BFIN_SIR)		+= bfin_sir.o
+obj-$(CONFIG_SH_SIR)		+= sh_sir.o
 # dongle drivers for SIR drivers
 obj-$(CONFIG_ESI_DONGLE)	+= esi-sir.o
 obj-$(CONFIG_TEKRAM_DONGLE)	+= tekram-sir.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/nsc-ircc.c linux-libre-2.6.34-gnu1/drivers/net/irda/nsc-ircc.c
--- linux-libre-2.6.33-gnu1/drivers/net/irda/nsc-ircc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/nsc-ircc.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,7 @@
  ********************************************************************/
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -50,7 +51,6 @@
 #include <linux/netdevice.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/dma-mapping.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/pxaficp_ir.c linux-libre-2.6.34-gnu1/drivers/net/irda/pxaficp_ir.c
--- linux-libre-2.6.33-gnu1/drivers/net/irda/pxaficp_ir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/pxaficp_ir.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irmod.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/sa1100_ir.c linux-libre-2.6.34-gnu1/drivers/net/irda/sa1100_ir.c
--- linux-libre-2.6.33-gnu1/drivers/net/irda/sa1100_ir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/sa1100_ir.c	2010-05-16 17:17:36.000000000 -0400
@@ -331,7 +331,7 @@ static int sa1100_irda_resume(struct pla
 		 * If we missed a speed change, initialise at the new speed
 		 * directly.  It is debatable whether this is actually
 		 * required, but in the interests of continuing from where
-		 * we left off it is desireable.  The converse argument is
+		 * we left off it is desirable.  The converse argument is
 		 * that we should re-negotiate at 9600 baud again.
 		 */
 		if (si->newspeed) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/sh_sir.c linux-libre-2.6.34-gnu1/drivers/net/irda/sh_sir.c
--- linux-libre-2.6.33-gnu1/drivers/net/irda/sh_sir.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/sh_sir.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,824 @@
+/*
+ * SuperH IrDA Driver
+ *
+ * Copyright (C) 2009 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on bfin_sir.c
+ * Copyright 2006-2009 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <net/irda/wrapper.h>
+#include <net/irda/irda_device.h>
+#include <asm/clock.h>
+
+#define DRIVER_NAME "sh_sir"
+
+#define RX_PHASE	(1 << 0)
+#define TX_PHASE	(1 << 1)
+#define TX_COMP_PHASE	(1 << 2) /* tx complete */
+#define NONE_PHASE	(1 << 31)
+
+#define IRIF_RINTCLR	0x0016 /* DMA rx interrupt source clear */
+#define IRIF_TINTCLR	0x0018 /* DMA tx interrupt source clear */
+#define IRIF_SIR0	0x0020 /* IrDA-SIR10 control */
+#define IRIF_SIR1	0x0022 /* IrDA-SIR10 baudrate error correction */
+#define IRIF_SIR2	0x0024 /* IrDA-SIR10 baudrate count */
+#define IRIF_SIR3	0x0026 /* IrDA-SIR10 status */
+#define IRIF_SIR_FRM	0x0028 /* Hardware frame processing set */
+#define IRIF_SIR_EOF	0x002A /* EOF value */
+#define IRIF_SIR_FLG	0x002C /* Flag clear */
+#define IRIF_UART_STS2	0x002E /* UART status 2 */
+#define IRIF_UART0	0x0030 /* UART control */
+#define IRIF_UART1	0x0032 /* UART status */
+#define IRIF_UART2	0x0034 /* UART mode */
+#define IRIF_UART3	0x0036 /* UART transmit data */
+#define IRIF_UART4	0x0038 /* UART receive data */
+#define IRIF_UART5	0x003A /* UART interrupt mask */
+#define IRIF_UART6	0x003C /* UART baud rate error correction */
+#define IRIF_UART7	0x003E /* UART baud rate count set */
+#define IRIF_CRC0	0x0040 /* CRC engine control */
+#define IRIF_CRC1	0x0042 /* CRC engine input data */
+#define IRIF_CRC2	0x0044 /* CRC engine calculation */
+#define IRIF_CRC3	0x0046 /* CRC engine output data 1 */
+#define IRIF_CRC4	0x0048 /* CRC engine output data 2 */
+
+/* IRIF_SIR0 */
+#define IRTPW		(1 << 1) /* transmit pulse width select */
+#define IRERRC		(1 << 0) /* Clear receive pulse width error */
+
+/* IRIF_SIR3 */
+#define IRERR		(1 << 0) /* received pulse width Error */
+
+/* IRIF_SIR_FRM */
+#define EOFD		(1 << 9) /* EOF detection flag */
+#define FRER		(1 << 8) /* Frame Error bit */
+#define FRP		(1 << 0) /* Frame processing set */
+
+/* IRIF_UART_STS2 */
+#define IRSME		(1 << 6) /* Receive Sum     Error flag */
+#define IROVE		(1 << 5) /* Receive Overrun Error flag */
+#define IRFRE		(1 << 4) /* Receive Framing Error flag */
+#define IRPRE		(1 << 3) /* Receive Parity  Error flag */
+
+/* IRIF_UART0_*/
+#define TBEC		(1 << 2) /* Transmit Data Clear */
+#define RIE		(1 << 1) /* Receive Enable */
+#define TIE		(1 << 0) /* Transmit Enable */
+
+/* IRIF_UART1 */
+#define URSME		(1 << 6) /* Receive Sum Error Flag */
+#define UROVE		(1 << 5) /* Receive Overrun Error Flag */
+#define URFRE		(1 << 4) /* Receive Framing Error Flag */
+#define URPRE		(1 << 3) /* Receive Parity Error Flag */
+#define RBF		(1 << 2) /* Receive Buffer Full Flag */
+#define TSBE		(1 << 1) /* Transmit Shift Buffer Empty Flag */
+#define TBE		(1 << 0) /* Transmit Buffer Empty flag */
+#define TBCOMP		(TSBE | TBE)
+
+/* IRIF_UART5 */
+#define RSEIM		(1 << 6) /* Receive Sum Error Flag IRQ Mask */
+#define RBFIM		(1 << 2) /* Receive Buffer Full Flag IRQ Mask */
+#define TSBEIM		(1 << 1) /* Transmit Shift Buffer Empty Flag IRQ Mask */
+#define TBEIM		(1 << 0) /* Transmit Buffer Empty Flag IRQ Mask */
+#define RX_MASK		(RSEIM  | RBFIM)
+
+/* IRIF_CRC0 */
+#define CRC_RST		(1 << 15) /* CRC Engine Reset */
+#define CRC_CT_MASK	0x0FFF
+
+/************************************************************************
+
+
+			structure
+
+
+************************************************************************/
+struct sh_sir_self {
+	void __iomem		*membase;
+	unsigned int		 irq;
+	struct clk		*clk;
+
+	struct net_device	*ndev;
+
+	struct irlap_cb		*irlap;
+	struct qos_info		qos;
+
+	iobuff_t		tx_buff;
+	iobuff_t		rx_buff;
+};
+
+/************************************************************************
+
+
+			common function
+
+
+************************************************************************/
+static void sh_sir_write(struct sh_sir_self *self, u32 offset, u16 data)
+{
+	iowrite16(data, self->membase + offset);
+}
+
+static u16 sh_sir_read(struct sh_sir_self *self, u32 offset)
+{
+	return ioread16(self->membase + offset);
+}
+
+static void sh_sir_update_bits(struct sh_sir_self *self, u32 offset,
+			       u16 mask, u16 data)
+{
+	u16 old, new;
+
+	old = sh_sir_read(self, offset);
+	new = (old & ~mask) | data;
+	if (old != new)
+		sh_sir_write(self, offset, new);
+}
+
+/************************************************************************
+
+
+			CRC function
+
+
+************************************************************************/
+static void sh_sir_crc_reset(struct sh_sir_self *self)
+{
+	sh_sir_write(self, IRIF_CRC0, CRC_RST);
+}
+
+static void sh_sir_crc_add(struct sh_sir_self *self, u8 data)
+{
+	sh_sir_write(self, IRIF_CRC1, (u16)data);
+}
+
+static u16 sh_sir_crc_cnt(struct sh_sir_self *self)
+{
+	return CRC_CT_MASK & sh_sir_read(self, IRIF_CRC0);
+}
+
+static u16 sh_sir_crc_out(struct sh_sir_self *self)
+{
+	return sh_sir_read(self, IRIF_CRC4);
+}
+
+static int sh_sir_crc_init(struct sh_sir_self *self)
+{
+	struct device *dev = &self->ndev->dev;
+	int ret = -EIO;
+	u16 val;
+
+	sh_sir_crc_reset(self);
+
+	sh_sir_crc_add(self, 0xCC);
+	sh_sir_crc_add(self, 0xF5);
+	sh_sir_crc_add(self, 0xF1);
+	sh_sir_crc_add(self, 0xA7);
+
+	val = sh_sir_crc_cnt(self);
+	if (4 != val) {
+		dev_err(dev, "CRC count error %x\n", val);
+		goto crc_init_out;
+	}
+
+	val = sh_sir_crc_out(self);
+	if (0x51DF != val) {
+		dev_err(dev, "CRC result error%x\n", val);
+		goto crc_init_out;
+	}
+
+	ret = 0;
+
+crc_init_out:
+
+	sh_sir_crc_reset(self);
+	return ret;
+}
+
+/************************************************************************
+
+
+			baud rate functions
+
+
+************************************************************************/
+#define SCLK_BASE 1843200 /* 1.8432MHz */
+
+static u32 sh_sir_find_sclk(struct clk *irda_clk)
+{
+	struct cpufreq_frequency_table *freq_table = irda_clk->freq_table;
+	struct clk *pclk = clk_get(NULL, "peripheral_clk");
+	u32 limit, min = 0xffffffff, tmp;
+	int i, index = 0;
+
+	limit = clk_get_rate(pclk);
+	clk_put(pclk);
+
+	/* IrDA can not set over peripheral_clk */
+	for (i = 0;
+	     freq_table[i].frequency != CPUFREQ_TABLE_END;
+	     i++) {
+		u32 freq = freq_table[i].frequency;
+
+		if (freq == CPUFREQ_ENTRY_INVALID)
+			continue;
+
+		/* IrDA should not over peripheral_clk */
+		if (freq > limit)
+			continue;
+
+		tmp = freq % SCLK_BASE;
+		if (tmp < min) {
+			min = tmp;
+			index = i;
+		}
+	}
+
+	return freq_table[index].frequency;
+}
+
+#define ERR_ROUNDING(a) ((a + 5000) / 10000)
+static int sh_sir_set_baudrate(struct sh_sir_self *self, u32 baudrate)
+{
+	struct clk *clk;
+	struct device *dev = &self->ndev->dev;
+	u32 rate;
+	u16 uabca, uabc;
+	u16 irbca, irbc;
+	u32 min, rerr, tmp;
+	int i;
+
+	/* Baud Rate Error Correction x 10000 */
+	u32 rate_err_array[] = {
+		0000, 0625, 1250, 1875,
+		2500, 3125, 3750, 4375,
+		5000, 5625, 6250, 6875,
+		7500, 8125, 8750, 9375,
+	};
+
+	/*
+	 * FIXME
+	 *
+	 * it support 9600 only now
+	 */
+	switch (baudrate) {
+	case 9600:
+		break;
+	default:
+		dev_err(dev, "un-supported baudrate %d\n", baudrate);
+		return -EIO;
+	}
+
+	clk = clk_get(NULL, "irda_clk");
+	if (!clk) {
+		dev_err(dev, "can not get irda_clk\n");
+		return -EIO;
+	}
+
+	clk_set_rate(clk, sh_sir_find_sclk(clk));
+	rate = clk_get_rate(clk);
+	clk_put(clk);
+
+	dev_dbg(dev, "selected sclk = %d\n", rate);
+
+	/*
+	 * CALCULATION
+	 *
+	 * 1843200 = system rate / (irbca + (irbc + 1))
+	 */
+
+	irbc = rate / SCLK_BASE;
+
+	tmp = rate - (SCLK_BASE * irbc);
+	tmp *= 10000;
+
+	rerr = tmp / SCLK_BASE;
+
+	min = 0xffffffff;
+	irbca = 0;
+	for (i = 0; i < ARRAY_SIZE(rate_err_array); i++) {
+		tmp = abs(rate_err_array[i] - rerr);
+		if (min > tmp) {
+			min = tmp;
+			irbca = i;
+		}
+	}
+
+	tmp = rate / (irbc + ERR_ROUNDING(rate_err_array[irbca]));
+	if ((SCLK_BASE / 100) < abs(tmp - SCLK_BASE))
+		dev_warn(dev, "IrDA freq error margin over %d\n", tmp);
+
+	dev_dbg(dev, "target = %d, result = %d, infrared = %d.%d\n",
+	       SCLK_BASE, tmp, irbc, rate_err_array[irbca]);
+
+	irbca = (irbca & 0xF) << 4;
+	irbc  = (irbc - 1) & 0xF;
+
+	if (!irbc) {
+		dev_err(dev, "sh_sir can not set 0 in IRIF_SIR2\n");
+		return -EIO;
+	}
+
+	sh_sir_write(self, IRIF_SIR0, IRTPW | IRERRC);
+	sh_sir_write(self, IRIF_SIR1, irbca);
+	sh_sir_write(self, IRIF_SIR2, irbc);
+
+	/*
+	 * CALCULATION
+	 *
+	 * BaudRate[bps] = system rate / (uabca + (uabc + 1) x 16)
+	 */
+
+	uabc = rate / baudrate;
+	uabc = (uabc / 16) - 1;
+	uabc = (uabc + 1) * 16;
+
+	tmp = rate - (uabc * baudrate);
+	tmp *= 10000;
+
+	rerr = tmp / baudrate;
+
+	min = 0xffffffff;
+	uabca = 0;
+	for (i = 0; i < ARRAY_SIZE(rate_err_array); i++) {
+		tmp = abs(rate_err_array[i] - rerr);
+		if (min > tmp) {
+			min = tmp;
+			uabca = i;
+		}
+	}
+
+	tmp = rate / (uabc + ERR_ROUNDING(rate_err_array[uabca]));
+	if ((baudrate / 100) < abs(tmp - baudrate))
+		dev_warn(dev, "UART freq error margin over %d\n", tmp);
+
+	dev_dbg(dev, "target = %d, result = %d, uart = %d.%d\n",
+	       baudrate, tmp,
+	       uabc, rate_err_array[uabca]);
+
+	uabca = (uabca & 0xF) << 4;
+	uabc  = (uabc / 16) - 1;
+
+	sh_sir_write(self, IRIF_UART6, uabca);
+	sh_sir_write(self, IRIF_UART7, uabc);
+
+	return 0;
+}
+
+/************************************************************************
+
+
+			iobuf function
+
+
+************************************************************************/
+static int __sh_sir_init_iobuf(iobuff_t *io, int size)
+{
+	io->head = kmalloc(size, GFP_KERNEL);
+	if (!io->head)
+		return -ENOMEM;
+
+	io->truesize	= size;
+	io->in_frame	= FALSE;
+	io->state	= OUTSIDE_FRAME;
+	io->data	= io->head;
+
+	return 0;
+}
+
+static void sh_sir_remove_iobuf(struct sh_sir_self *self)
+{
+	kfree(self->rx_buff.head);
+	kfree(self->tx_buff.head);
+
+	self->rx_buff.head = NULL;
+	self->tx_buff.head = NULL;
+}
+
+static int sh_sir_init_iobuf(struct sh_sir_self *self, int rxsize, int txsize)
+{
+	int err = -ENOMEM;
+
+	if (self->rx_buff.head ||
+	    self->tx_buff.head) {
+		dev_err(&self->ndev->dev, "iobuff has already existed.");
+		return err;
+	}
+
+	err = __sh_sir_init_iobuf(&self->rx_buff, rxsize);
+	if (err)
+		goto iobuf_err;
+
+	err = __sh_sir_init_iobuf(&self->tx_buff, txsize);
+
+iobuf_err:
+	if (err)
+		sh_sir_remove_iobuf(self);
+
+	return err;
+}
+
+/************************************************************************
+
+
+			status function
+
+
+************************************************************************/
+static void sh_sir_clear_all_err(struct sh_sir_self *self)
+{
+	/* Clear error flag for receive pulse width */
+	sh_sir_update_bits(self, IRIF_SIR0, IRERRC, IRERRC);
+
+	/* Clear frame / EOF error flag */
+	sh_sir_write(self, IRIF_SIR_FLG, 0xffff);
+
+	/* Clear all status error */
+	sh_sir_write(self, IRIF_UART_STS2, 0);
+}
+
+static void sh_sir_set_phase(struct sh_sir_self *self, int phase)
+{
+	u16 uart5 = 0;
+	u16 uart0 = 0;
+
+	switch (phase) {
+	case TX_PHASE:
+		uart5 = TBEIM;
+		uart0 = TBEC | TIE;
+		break;
+	case TX_COMP_PHASE:
+		uart5 = TSBEIM;
+		uart0 = TIE;
+		break;
+	case RX_PHASE:
+		uart5 = RX_MASK;
+		uart0 = RIE;
+		break;
+	default:
+		break;
+	}
+
+	sh_sir_write(self, IRIF_UART5, uart5);
+	sh_sir_write(self, IRIF_UART0, uart0);
+}
+
+static int sh_sir_is_which_phase(struct sh_sir_self *self)
+{
+	u16 val = sh_sir_read(self, IRIF_UART5);
+
+	if (val & TBEIM)
+		return TX_PHASE;
+
+	if (val & TSBEIM)
+		return TX_COMP_PHASE;
+
+	if (val & RX_MASK)
+		return RX_PHASE;
+
+	return NONE_PHASE;
+}
+
+static void sh_sir_tx(struct sh_sir_self *self, int phase)
+{
+	switch (phase) {
+	case TX_PHASE:
+		if (0 >= self->tx_buff.len) {
+			sh_sir_set_phase(self, TX_COMP_PHASE);
+		} else {
+			sh_sir_write(self, IRIF_UART3, self->tx_buff.data[0]);
+			self->tx_buff.len--;
+			self->tx_buff.data++;
+		}
+		break;
+	case TX_COMP_PHASE:
+		sh_sir_set_phase(self, RX_PHASE);
+		netif_wake_queue(self->ndev);
+		break;
+	default:
+		dev_err(&self->ndev->dev, "should not happen\n");
+		break;
+	}
+}
+
+static int sh_sir_read_data(struct sh_sir_self *self)
+{
+	u16 val;
+	int timeout = 1024;
+
+	while (timeout--) {
+		val = sh_sir_read(self, IRIF_UART1);
+
+		/* data get */
+		if (val & RBF) {
+			if (val & (URSME | UROVE | URFRE | URPRE))
+				break;
+
+			return (int)sh_sir_read(self, IRIF_UART4);
+		}
+
+		udelay(1);
+	}
+
+	dev_err(&self->ndev->dev, "UART1 %04x : STATUS %04x\n",
+		val, sh_sir_read(self, IRIF_UART_STS2));
+
+	/* read data register for clear error */
+	sh_sir_read(self, IRIF_UART4);
+
+	return -1;
+}
+
+static void sh_sir_rx(struct sh_sir_self *self)
+{
+	int timeout = 1024;
+	int data;
+
+	while (timeout--) {
+		data = sh_sir_read_data(self);
+		if (data < 0)
+			break;
+
+		async_unwrap_char(self->ndev, &self->ndev->stats,
+				  &self->rx_buff, (u8)data);
+		self->ndev->last_rx = jiffies;
+
+		if (EOFD & sh_sir_read(self, IRIF_SIR_FRM))
+			continue;
+
+		break;
+	}
+}
+
+static irqreturn_t sh_sir_irq(int irq, void *dev_id)
+{
+	struct sh_sir_self *self = dev_id;
+	struct device *dev = &self->ndev->dev;
+	int phase = sh_sir_is_which_phase(self);
+
+	switch (phase) {
+	case TX_COMP_PHASE:
+	case TX_PHASE:
+		sh_sir_tx(self, phase);
+		break;
+	case RX_PHASE:
+		if (sh_sir_read(self, IRIF_SIR3))
+			dev_err(dev, "rcv pulse width error occurred\n");
+
+		sh_sir_rx(self);
+		sh_sir_clear_all_err(self);
+		break;
+	default:
+		dev_err(dev, "unknown interrupt\n");
+	}
+
+	 return IRQ_HANDLED;
+}
+
+/************************************************************************
+
+
+			net_device_ops function
+
+
+************************************************************************/
+static int sh_sir_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+	struct sh_sir_self *self = netdev_priv(ndev);
+	int speed = irda_get_next_speed(skb);
+
+	if ((0 < speed) &&
+	    (9600 != speed)) {
+		dev_err(&ndev->dev, "support 9600 only (%d)\n", speed);
+		return -EIO;
+	}
+
+	netif_stop_queue(ndev);
+
+	self->tx_buff.data = self->tx_buff.head;
+	self->tx_buff.len = 0;
+	if (skb->len)
+		self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data,
+						   self->tx_buff.truesize);
+
+	sh_sir_set_phase(self, TX_PHASE);
+	dev_kfree_skb(skb);
+
+	return 0;
+}
+
+static int sh_sir_ioctl(struct net_device *ndev, struct ifreq *ifreq, int cmd)
+{
+	/*
+	 * FIXME
+	 *
+	 * This function is needed for irda framework.
+	 * But nothing to do now
+	 */
+	return 0;
+}
+
+static struct net_device_stats *sh_sir_stats(struct net_device *ndev)
+{
+	struct sh_sir_self *self = netdev_priv(ndev);
+
+	return &self->ndev->stats;
+}
+
+static int sh_sir_open(struct net_device *ndev)
+{
+	struct sh_sir_self *self = netdev_priv(ndev);
+	int err;
+
+	clk_enable(self->clk);
+	err = sh_sir_crc_init(self);
+	if (err)
+		goto open_err;
+
+	sh_sir_set_baudrate(self, 9600);
+
+	self->irlap = irlap_open(ndev, &self->qos, DRIVER_NAME);
+	if (!self->irlap)
+		goto open_err;
+
+	/*
+	 * Now enable the interrupt then start the queue
+	 */
+	sh_sir_update_bits(self, IRIF_SIR_FRM, FRP, FRP);
+	sh_sir_read(self, IRIF_UART1); /* flag clear */
+	sh_sir_read(self, IRIF_UART4); /* flag clear */
+	sh_sir_set_phase(self, RX_PHASE);
+
+	netif_start_queue(ndev);
+
+	dev_info(&self->ndev->dev, "opened\n");
+
+	return 0;
+
+open_err:
+	clk_disable(self->clk);
+
+	return err;
+}
+
+static int sh_sir_stop(struct net_device *ndev)
+{
+	struct sh_sir_self *self = netdev_priv(ndev);
+
+	/* Stop IrLAP */
+	if (self->irlap) {
+		irlap_close(self->irlap);
+		self->irlap = NULL;
+	}
+
+	netif_stop_queue(ndev);
+
+	dev_info(&ndev->dev, "stoped\n");
+
+	return 0;
+}
+
+static const struct net_device_ops sh_sir_ndo = {
+	.ndo_open		= sh_sir_open,
+	.ndo_stop		= sh_sir_stop,
+	.ndo_start_xmit		= sh_sir_hard_xmit,
+	.ndo_do_ioctl		= sh_sir_ioctl,
+	.ndo_get_stats		= sh_sir_stats,
+};
+
+/************************************************************************
+
+
+			platform_driver function
+
+
+************************************************************************/
+static int __devinit sh_sir_probe(struct platform_device *pdev)
+{
+	struct net_device *ndev;
+	struct sh_sir_self *self;
+	struct resource *res;
+	char clk_name[8];
+	void __iomem *base;
+	unsigned int irq;
+	int err = -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(pdev, 0);
+	if (!res || irq < 0) {
+		dev_err(&pdev->dev, "Not enough platform resources.\n");
+		goto exit;
+	}
+
+	ndev = alloc_irdadev(sizeof(*self));
+	if (!ndev)
+		goto exit;
+
+	base = ioremap_nocache(res->start, resource_size(res));
+	if (!base) {
+		err = -ENXIO;
+		dev_err(&pdev->dev, "Unable to ioremap.\n");
+		goto err_mem_1;
+	}
+
+	self = netdev_priv(ndev);
+	err = sh_sir_init_iobuf(self, IRDA_SKB_MAX_MTU, IRDA_SIR_MAX_FRAME);
+	if (err)
+		goto err_mem_2;
+
+	snprintf(clk_name, sizeof(clk_name), "irda%d", pdev->id);
+	self->clk = clk_get(&pdev->dev, clk_name);
+	if (IS_ERR(self->clk)) {
+		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
+		goto err_mem_3;
+	}
+
+	irda_init_max_qos_capabilies(&self->qos);
+
+	ndev->netdev_ops	= &sh_sir_ndo;
+	ndev->irq		= irq;
+
+	self->membase			= base;
+	self->ndev			= ndev;
+	self->qos.baud_rate.bits	&= IR_9600; /* FIXME */
+	self->qos.min_turn_time.bits	= 1; /* 10 ms or more */
+
+	irda_qos_bits_to_value(&self->qos);
+
+	err = register_netdev(ndev);
+	if (err)
+		goto err_mem_4;
+
+	platform_set_drvdata(pdev, ndev);
+
+	if (request_irq(irq, sh_sir_irq, IRQF_DISABLED, "sh_sir", self)) {
+		dev_warn(&pdev->dev, "Unable to attach sh_sir interrupt\n");
+		goto err_mem_4;
+	}
+
+	dev_info(&pdev->dev, "SuperH IrDA probed\n");
+
+	goto exit;
+
+err_mem_4:
+	clk_put(self->clk);
+err_mem_3:
+	sh_sir_remove_iobuf(self);
+err_mem_2:
+	iounmap(self->membase);
+err_mem_1:
+	free_netdev(ndev);
+exit:
+	return err;
+}
+
+static int __devexit sh_sir_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct sh_sir_self *self = netdev_priv(ndev);
+
+	if (!self)
+		return 0;
+
+	unregister_netdev(ndev);
+	clk_put(self->clk);
+	sh_sir_remove_iobuf(self);
+	iounmap(self->membase);
+	free_netdev(ndev);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver sh_sir_driver = {
+	.probe   = sh_sir_probe,
+	.remove  = __devexit_p(sh_sir_remove),
+	.driver  = {
+		.name = DRIVER_NAME,
+	},
+};
+
+static int __init sh_sir_init(void)
+{
+	return platform_driver_register(&sh_sir_driver);
+}
+
+static void __exit sh_sir_exit(void)
+{
+	platform_driver_unregister(&sh_sir_driver);
+}
+
+module_init(sh_sir_init);
+module_exit(sh_sir_exit);
+
+MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
+MODULE_DESCRIPTION("SuperH IrDA driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/sir_dev.c linux-libre-2.6.34-gnu1/drivers/net/irda/sir_dev.c
--- linux-libre-2.6.33-gnu1/drivers/net/irda/sir_dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/sir_dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/smsc-ircc2.c linux-libre-2.6.34-gnu1/drivers/net/irda/smsc-ircc2.c
--- linux-libre-2.6.33-gnu1/drivers/net/irda/smsc-ircc2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/smsc-ircc2.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,13 +48,13 @@
 #include <linux/netdevice.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/serial_reg.h>
 #include <linux/dma-mapping.h>
 #include <linux/pnp.h>
 #include <linux/platform_device.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/via-ircc.c linux-libre-2.6.34-gnu1/drivers/net/irda/via-ircc.c
--- linux-libre-2.6.33-gnu1/drivers/net/irda/via-ircc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/via-ircc.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,11 +45,11 @@ F02 Oct/28/02: Add SB device ID for 3147
 #include <linux/netdevice.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -121,7 +121,7 @@ static void iodelay(int udelay)
 	}
 }
 
-static struct pci_device_id via_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(via_pci_tbl) = {
 	{ PCI_VENDOR_ID_VIA, 0x8231, PCI_ANY_ID, PCI_ANY_ID,0,0,0 },
 	{ PCI_VENDOR_ID_VIA, 0x3109, PCI_ANY_ID, PCI_ANY_ID,0,0,1 },
 	{ PCI_VENDOR_ID_VIA, 0x3074, PCI_ANY_ID, PCI_ANY_ID,0,0,2 },
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/vlsi_ir.c linux-libre-2.6.34-gnu1/drivers/net/irda/vlsi_ir.c
--- linux-libre-2.6.33-gnu1/drivers/net/irda/vlsi_ir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/vlsi_ir.c	2010-05-16 17:17:36.000000000 -0400
@@ -59,7 +59,7 @@ MODULE_LICENSE("GPL");
 
 static /* const */ char drivername[] = DRIVER_NAME;
 
-static struct pci_device_id vlsi_irda_table [] = {
+static DEFINE_PCI_DEVICE_TABLE(vlsi_irda_table) = {
 	{
 		.class =        PCI_CLASS_WIRELESS_IRDA << 8,
 		.class_mask =	PCI_CLASS_SUBCLASS_MASK << 8, 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/irda/w83977af_ir.c linux-libre-2.6.34-gnu1/drivers/net/irda/w83977af_ir.c
--- linux-libre-2.6.33-gnu1/drivers/net/irda/w83977af_ir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/irda/w83977af_ir.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,10 +46,10 @@
 #include <linux/netdevice.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -65,7 +65,6 @@
 #undef  CONFIG_NETWINDER_TX_DMA_PROBLEMS /* Not needed */
 #define CONFIG_NETWINDER_RX_DMA_PROBLEMS /* Must have this one! */
 #endif
-#undef  CONFIG_USE_INTERNAL_TIMER  /* Just cannot make that timer work */
 #define CONFIG_USE_W977_PNP        /* Currently needed */
 #define PIO_MAX_SPEED       115200 
 
@@ -533,25 +532,6 @@ static netdev_tx_t w83977af_hard_xmit(st
 		self->tx_buff.len = skb->len;
 		
 		mtt = irda_get_mtt(skb);
-#ifdef CONFIG_USE_INTERNAL_TIMER
-	        if (mtt > 50) {
-			/* Adjust for timer resolution */
-			mtt /= 1000+1;
-
-			/* Setup timer */
-			switch_bank(iobase, SET4);
-			outb(mtt & 0xff, iobase+TMRL);
-			outb((mtt >> 8) & 0x0f, iobase+TMRH);
-			
-			/* Start timer */
-			outb(IR_MSL_EN_TMR, iobase+IR_MSL);
-			self->io.direction = IO_XMIT;
-			
-			/* Enable timer interrupt */
-			switch_bank(iobase, SET0);
-			outb(ICR_ETMRI, iobase+ICR);
-		} else {
-#endif
 			IRDA_DEBUG(4, "%s(%ld), mtt=%d\n", __func__ , jiffies, mtt);
 			if (mtt)
 				udelay(mtt);
@@ -560,9 +540,6 @@ static netdev_tx_t w83977af_hard_xmit(st
 			switch_bank(iobase, SET0);
 	 		outb(ICR_EDMAI, iobase+ICR);
 	     		w83977af_dma_write(self, iobase);
-#ifdef CONFIG_USE_INTERNAL_TIMER
-		}
-#endif
 	} else {
 		self->tx_buff.data = self->tx_buff.head;
 		self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, 
@@ -876,20 +853,7 @@ static int w83977af_dma_receive_complete
 			/* Check if we have transferred all data to memory */
 			switch_bank(iobase, SET0);
 			if (inb(iobase+USR) & USR_RDR) {
-#ifdef CONFIG_USE_INTERNAL_TIMER
-				/* Put this entry back in fifo */
-				st_fifo->head--;
-				st_fifo->len++;
-				st_fifo->entries[st_fifo->head].status = status;
-				st_fifo->entries[st_fifo->head].len = len;
-				
-				/* Restore set register */
-				outb(set, iobase+SSR);
-			
-				return FALSE; 	/* I'll be back! */
-#else
 				udelay(80); /* Should be enough!? */
-#endif
 			}
 						
 			skb = dev_alloc_skb(len+1);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/isa-skeleton.c linux-libre-2.6.34-gnu1/drivers/net/isa-skeleton.c
--- linux-libre-2.6.33-gnu1/drivers/net/isa-skeleton.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/isa-skeleton.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,718 +0,0 @@
-/* isa-skeleton.c: A network driver outline for linux.
- *
- *	Written 1993-94 by Donald Becker.
- *
- *	Copyright 1993 United States Government as represented by the
- *	Director, National Security Agency.
- *
- *	This software may be used and distributed according to the terms
- *	of the GNU General Public License, incorporated herein by reference.
- *
- *	The author may be reached as becker@scyld.com, or C/O
- *	Scyld Computing Corporation
- *	410 Severn Ave., Suite 210
- *	Annapolis MD 21403
- *
- *	This file is an outline for writing a network device driver for the
- *	the Linux operating system.
- *
- *	To write (or understand) a driver, have a look at the "loopback.c" file to
- *	get a feel of what is going on, and then use the code below as a skeleton
- *	for the new driver.
- *
- */
-
-static const char *version =
-	"isa-skeleton.c:v1.51 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-/*
- *  Sources:
- *	List your sources of programming information to document that
- *	the driver is your own creation, and give due credit to others
- *	that contributed to the work. Remember that GNU project code
- *	cannot use proprietary or trade secret information. Interface
- *	definitions are generally considered non-copyrightable to the
- *	extent that the same names and structures must be used to be
- *	compatible.
- *
- *	Finally, keep in mind that the Linux kernel is has an API, not
- *	ABI. Proprietary object-code-only distributions are not permitted
- *	under the GPL.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-/*
- * The name of the card. Is used for messages and in the requests for
- * io regions, irqs and dma channels
- */
-static const char* cardname = "netcard";
-
-/* First, a few definitions that the brave might change. */
-
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int netcard_portlist[] __initdata =
-   { 0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0};
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 2
-#endif
-static unsigned int net_debug = NET_DEBUG;
-
-/* The number of low I/O ports used by the ethercard. */
-#define NETCARD_IO_EXTENT	32
-
-#define MY_TX_TIMEOUT  ((400*HZ)/1000)
-
-/* Information that need to be kept for each board. */
-struct net_local {
-	struct net_device_stats stats;
-	long open_time;			/* Useless example local info. */
-
-	/* Tx control lock.  This protects the transmit buffer ring
-	 * state along with the "tx full" state of the driver.  This
-	 * means all netif_queue flow control actions are protected
-	 * by this lock as well.
-	 */
-	spinlock_t lock;
-};
-
-/* The station (ethernet) address prefix, used for IDing the board. */
-#define SA_ADDR0 0x00
-#define SA_ADDR1 0x42
-#define SA_ADDR2 0x65
-
-/* Index to functions, as function prototypes. */
-
-static int	netcard_probe1(struct net_device *dev, int ioaddr);
-static int	net_open(struct net_device *dev);
-static int	net_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t net_interrupt(int irq, void *dev_id);
-static void	net_rx(struct net_device *dev);
-static int	net_close(struct net_device *dev);
-static struct	net_device_stats *net_get_stats(struct net_device *dev);
-static void	set_multicast_list(struct net_device *dev);
-static void     net_tx_timeout(struct net_device *dev);
-
-
-/* Example routines you must write ;->. */
-#define tx_done(dev) 1
-static void	hardware_send_packet(short ioaddr, char *buf, int length);
-static void 	chipset_init(struct net_device *dev, int startp);
-
-/*
- * Check for a network adaptor of this type, and return '0' iff one exists.
- * If dev->base_addr == 0, probe all likely locations.
- * If dev->base_addr == 1, always return failure.
- * If dev->base_addr == 2, allocate space for the device and return success
- * (detachable devices only).
- */
-static int __init do_netcard_probe(struct net_device *dev)
-{
-	int i;
-	int base_addr = dev->base_addr;
-	int irq = dev->irq;
-
-	if (base_addr > 0x1ff)    /* Check a single specified location. */
-		return netcard_probe1(dev, base_addr);
-	else if (base_addr != 0)  /* Don't probe at all. */
-		return -ENXIO;
-
-	for (i = 0; netcard_portlist[i]; i++) {
-		int ioaddr = netcard_portlist[i];
-		if (netcard_probe1(dev, ioaddr) == 0)
-			return 0;
-		dev->irq = irq;
-	}
-
-	return -ENODEV;
-}
-
-static void cleanup_card(struct net_device *dev)
-{
-#ifdef jumpered_dma
-	free_dma(dev->dma);
-#endif
-#ifdef jumpered_interrupts
-	free_irq(dev->irq, dev);
-#endif
-	release_region(dev->base_addr, NETCARD_IO_EXTENT);
-}
-
-#ifndef MODULE
-struct net_device * __init netcard_probe(int unit)
-{
-	struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
-	int err;
-
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	sprintf(dev->name, "eth%d", unit);
-	netdev_boot_setup_check(dev);
-
-	err = do_netcard_probe(dev);
-	if (err)
-		goto out;
-	return dev;
-out:
-	free_netdev(dev);
-	return ERR_PTR(err);
-}
-#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
- * verifies that the correct device exists and functions.
- */
-static int __init netcard_probe1(struct net_device *dev, int ioaddr)
-{
-	struct net_local *np;
-	static unsigned version_printed;
-	int i;
-	int err = -ENODEV;
-
-	/* Grab the region so that no one else tries to probe our ioports. */
-	if (!request_region(ioaddr, NETCARD_IO_EXTENT, cardname))
-		return -EBUSY;
-
-	/*
-	 * For ethernet adaptors the first three octets of the station address
-	 * contains the manufacturer's unique code. That might be a good probe
-	 * method. Ideally you would add additional checks.
-	 */
-	if (inb(ioaddr + 0) != SA_ADDR0 ||
-	    inb(ioaddr + 1) != SA_ADDR1 ||
-	    inb(ioaddr + 2) != SA_ADDR2)
-		goto out;
-
-	if (net_debug  &&  version_printed++ == 0)
-		printk(KERN_DEBUG "%s", version);
-
-	printk(KERN_INFO "%s: %s found at %#3x, ", dev->name, cardname, ioaddr);
-
-	/* Fill in the 'dev' fields. */
-	dev->base_addr = ioaddr;
-
-	/* Retrieve and print the ethernet address. */
-	for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = inb(ioaddr + i);
-
-	printk("%pM", dev->dev_addr);
-
-	err = -EAGAIN;
-#ifdef jumpered_interrupts
-	/*
-	 * If this board has jumpered interrupts, allocate the interrupt
-	 * vector now. There is no point in waiting since no other device
-	 * can use the interrupt, and this marks the irq as busy. Jumpered
-	 * interrupts are typically not reported by the boards, and we must
-	 * used autoIRQ to find them.
-	 */
-
-	if (dev->irq == -1)
-		;	/* Do nothing: a user-level program will set it. */
-	else if (dev->irq < 2) {	/* "Auto-IRQ" */
-		unsigned long irq_mask = probe_irq_on();
-		/* Trigger an interrupt here. */
-
-		dev->irq = probe_irq_off(irq_mask);
-		if (net_debug >= 2)
-			printk(" autoirq is %d", dev->irq);
-	} else if (dev->irq == 2)
-		/*
-		 * Fixup for users that don't know that IRQ 2 is really
-		 * IRQ9, or don't know which one to set.
-		 */
-		dev->irq = 9;
-
-	{
-		int irqval = request_irq(dev->irq, net_interrupt, 0, cardname, dev);
-		if (irqval) {
-			printk("%s: unable to get IRQ %d (irqval=%d).\n",
-				   dev->name, dev->irq, irqval);
-			goto out;
-		}
-	}
-#endif	/* jumpered interrupt */
-#ifdef jumpered_dma
-	/*
-	 * If we use a jumpered DMA channel, that should be probed for and
-	 * allocated here as well. See lance.c for an example.
-	 */
-	if (dev->dma == 0) {
-		if (request_dma(dev->dma, cardname)) {
-			printk("DMA %d allocation failed.\n", dev->dma);
-			goto out1;
-		} else
-			printk(", assigned DMA %d.\n", dev->dma);
-	} else {
-		short dma_status, new_dma_status;
-
-		/* Read the DMA channel status registers. */
-		dma_status = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
-			(inb(DMA2_STAT_REG) & 0xf0);
-		/* Trigger a DMA request, perhaps pause a bit. */
-		outw(0x1234, ioaddr + 8);
-		/* Re-read the DMA status registers. */
-		new_dma_status = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
-			(inb(DMA2_STAT_REG) & 0xf0);
-		/*
-		 * Eliminate the old and floating requests,
-		 * and DMA4 the cascade.
-		 */
-		new_dma_status ^= dma_status;
-		new_dma_status &= ~0x10;
-		for (i = 7; i > 0; i--)
-			if (test_bit(i, &new_dma_status)) {
-				dev->dma = i;
-				break;
-			}
-		if (i <= 0) {
-			printk("DMA probe failed.\n");
-			goto out1;
-		}
-		if (request_dma(dev->dma, cardname)) {
-			printk("probed DMA %d allocation failed.\n", dev->dma);
-			goto out1;
-		}
-	}
-#endif	/* jumpered DMA */
-
-	np = netdev_priv(dev);
-	spin_lock_init(&np->lock);
-
-        dev->netdev_ops		= &netcard_netdev_ops;
-        dev->watchdog_timeo	= MY_TX_TIMEOUT;
-
-	err = register_netdev(dev);
-	if (err)
-		goto out2;
-	return 0;
-out2:
-#ifdef jumpered_dma
-	free_dma(dev->dma);
-#endif
-out1:
-#ifdef jumpered_interrupts
-	free_irq(dev->irq, dev);
-#endif
-out:
-	release_region(base_addr, NETCARD_IO_EXTENT);
-	return err;
-}
-
-static void net_tx_timeout(struct net_device *dev)
-{
-	struct net_local *np = netdev_priv(dev);
-
-	printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
-	       tx_done(dev) ? "IRQ conflict" : "network cable problem");
-
-	/* Try to restart the adaptor. */
-	chipset_init(dev, 1);
-
-	np->stats.tx_errors++;
-
-	/* If we have space available to accept new transmit
-	 * requests, wake up the queueing layer.  This would
-	 * be the case if the chipset_init() call above just
-	 * flushes out the tx queue and empties it.
-	 *
-	 * If instead, the tx queue is retained then the
-	 * netif_wake_queue() call should be placed in the
-	 * TX completion interrupt handler of the driver instead
-	 * of here.
-	 */
-	if (!tx_full(dev))
-		netif_wake_queue(dev);
-}
-
-/*
- * Open/initialize the board. This is called (in the current kernel)
- * sometime after booting when the 'ifconfig' program is run.
- *
- * This routine should set everything up anew at each open, even
- * registers 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
-net_open(struct net_device *dev)
-{
-	struct net_local *np = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-	/*
-	 * This is used if the interrupt line can turned off (shared).
-	 * See 3c503.c for an example of selecting the IRQ at config-time.
-	 */
-	if (request_irq(dev->irq, net_interrupt, 0, cardname, dev)) {
-		return -EAGAIN;
-	}
-	/*
-	 * Always allocate the DMA channel after the IRQ,
-	 * and clean up on failure.
-	 */
-	if (request_dma(dev->dma, cardname)) {
-		free_irq(dev->irq, dev);
-		return -EAGAIN;
-	}
-
-	/* Reset the hardware here. Don't forget to set the station address. */
-	chipset_init(dev, 1);
-	outb(0x00, ioaddr);
-	np->open_time = jiffies;
-
-	/* We are now ready to accept transmit requeusts from
-	 * the queueing layer of the networking.
-	 */
-	netif_start_queue(dev);
-
-	return 0;
-}
-
-/* This will only be invoked if your driver is _not_ in XOFF state.
- * What this means is that you need not check it, and that this
- * invariant will hold if you make sure that the netif_*_queue()
- * calls are done at the proper times.
- */
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
-	struct net_local *np = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-	short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-	unsigned char *buf = skb->data;
-
-	/* If some error occurs while trying to transmit this
-	 * packet, you should return '1' from this function.
-	 * In such a case you _may not_ do anything to the
-	 * SKB, it is still owned by the network queueing
-	 * layer when an error is returned.  This means you
-	 * may not modify any SKB fields, you may not free
-	 * the SKB, etc.
-	 */
-
-#if TX_RING
-	/* This is the most common case for modern hardware.
-	 * The spinlock protects this code from the TX complete
-	 * hardware interrupt handler.  Queue flow control is
-	 * thus managed under this lock as well.
-	 */
-	unsigned long flags;
-	spin_lock_irqsave(&np->lock, flags);
-
-	add_to_tx_ring(np, skb, length);
-	dev->trans_start = jiffies;
-
-	/* If we just used up the very last entry in the
-	 * TX ring on this device, tell the queueing
-	 * layer to send no more.
-	 */
-	if (tx_full(dev))
-		netif_stop_queue(dev);
-
-	/* When the TX completion hw interrupt arrives, this
-	 * is when the transmit statistics are updated.
-	 */
-
-	spin_unlock_irqrestore(&np->lock, flags);
-#else
-	/* This is the case for older hardware which takes
-	 * a single transmit buffer at a time, and it is
-	 * just written to the device via PIO.
-	 *
-	 * No spin locking is needed since there is no TX complete
-	 * event.  If by chance your card does have a TX complete
-	 * hardware IRQ then you may need to utilize np->lock here.
-	 */
-	hardware_send_packet(ioaddr, buf, length);
-	np->stats.tx_bytes += skb->len;
-
-	dev->trans_start = jiffies;
-
-	/* You might need to clean up and record Tx statistics here. */
-	if (inw(ioaddr) == /*RU*/81)
-		np->stats.tx_aborted_errors++;
-	dev_kfree_skb (skb);
-#endif
-
-	return NETDEV_TX_OK;
-}
-
-#if TX_RING
-/* This handles TX complete events posted by the device
- * via interrupts.
- */
-void net_tx(struct net_device *dev)
-{
-	struct net_local *np = netdev_priv(dev);
-	int entry;
-
-	/* This protects us from concurrent execution of
-	 * our dev->hard_start_xmit function above.
-	 */
-	spin_lock(&np->lock);
-
-	entry = np->tx_old;
-	while (tx_entry_is_sent(np, entry)) {
-		struct sk_buff *skb = np->skbs[entry];
-
-		np->stats.tx_bytes += skb->len;
-		dev_kfree_skb_irq (skb);
-
-		entry = next_tx_entry(np, entry);
-	}
-	np->tx_old = entry;
-
-	/* If we had stopped the queue due to a "tx full"
-	 * condition, and space has now been made available,
-	 * wake up the queue.
-	 */
-	if (netif_queue_stopped(dev) && ! tx_full(dev))
-		netif_wake_queue(dev);
-
-	spin_unlock(&np->lock);
-}
-#endif
-
-/*
- * The typical workload of the driver:
- * Handle the network interface interrupts.
- */
-static irqreturn_t net_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev = dev_id;
-	struct net_local *np;
-	int ioaddr, status;
-	int handled = 0;
-
-	ioaddr = dev->base_addr;
-
-	np = netdev_priv(dev);
-	status = inw(ioaddr + 0);
-
-	if (status == 0)
-		goto out;
-	handled = 1;
-
-	if (status & RX_INTR) {
-		/* Got a packet(s). */
-		net_rx(dev);
-	}
-#if TX_RING
-	if (status & TX_INTR) {
-		/* Transmit complete. */
-		net_tx(dev);
-		np->stats.tx_packets++;
-		netif_wake_queue(dev);
-	}
-#endif
-	if (status & COUNTERS_INTR) {
-		/* Increment the appropriate 'localstats' field. */
-		np->stats.tx_window_errors++;
-	}
-out:
-	return IRQ_RETVAL(handled);
-}
-
-/* We have a good packet(s), get it/them out of the buffers. */
-static void
-net_rx(struct net_device *dev)
-{
-	struct net_local *lp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-	int boguscount = 10;
-
-	do {
-		int status = inw(ioaddr);
-		int pkt_len = inw(ioaddr);
-
-		if (pkt_len == 0)		/* Read all the frames? */
-			break;			/* Done for now */
-
-		if (status & 0x40) {	/* There was an error. */
-			lp->stats.rx_errors++;
-			if (status & 0x20) lp->stats.rx_frame_errors++;
-			if (status & 0x10) lp->stats.rx_over_errors++;
-			if (status & 0x08) lp->stats.rx_crc_errors++;
-			if (status & 0x04) lp->stats.rx_fifo_errors++;
-		} else {
-			/* Malloc up new buffer. */
-			struct sk_buff *skb;
-
-			lp->stats.rx_bytes+=pkt_len;
-
-			skb = dev_alloc_skb(pkt_len);
-			if (skb == NULL) {
-				printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
-					   dev->name);
-				lp->stats.rx_dropped++;
-				break;
-			}
-			skb->dev = dev;
-
-			/* 'skb->data' points to the start of sk_buff data area. */
-			memcpy(skb_put(skb,pkt_len), (void*)dev->rmem_start,
-				   pkt_len);
-			/* or */
-			insw(ioaddr, skb->data, (pkt_len + 1) >> 1);
-
-			netif_rx(skb);
-			lp->stats.rx_packets++;
-			lp->stats.rx_bytes += pkt_len;
-		}
-	} while (--boguscount);
-
-	return;
-}
-
-/* The inverse routine to net_open(). */
-static int
-net_close(struct net_device *dev)
-{
-	struct net_local *lp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-
-	lp->open_time = 0;
-
-	netif_stop_queue(dev);
-
-	/* Flush the Tx and disable Rx here. */
-
-	disable_dma(dev->dma);
-
-	/* If not IRQ or DMA jumpered, free up the line. */
-	outw(0x00, ioaddr+0);	/* Release the physical interrupt line. */
-
-	free_irq(dev->irq, dev);
-	free_dma(dev->dma);
-
-	/* Update the statistics here. */
-
-	return 0;
-
-}
-
-/*
- * Get the current statistics.
- * This may be called with the card open or closed.
- */
-static struct net_device_stats *net_get_stats(struct net_device *dev)
-{
-	struct net_local *lp = netdev_priv(dev);
-	short ioaddr = dev->base_addr;
-
-	/* Update the statistics from the device registers. */
-	lp->stats.rx_missed_errors = inw(ioaddr+1);
-	return &lp->stats;
-}
-
-/*
- * Set or clear the multicast filter for this adaptor.
- * num_addrs == -1	Promiscuous mode, receive all packets
- * num_addrs == 0	Normal mode, clear multicast list
- * num_addrs > 0	Multicast mode, receive normal and MC packets,
- *			and do best-effort filtering.
- */
-static void
-set_multicast_list(struct net_device *dev)
-{
-	short ioaddr = dev->base_addr;
-	if (dev->flags&IFF_PROMISC)
-	{
-		/* Enable promiscuous mode */
-		outw(MULTICAST|PROMISC, ioaddr);
-	}
-	else if((dev->flags&IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS)
-	{
-		/* Disable promiscuous mode, use normal mode. */
-		hardware_set_filter(NULL);
-
-		outw(MULTICAST, ioaddr);
-	}
-	else if(dev->mc_count)
-	{
-		/* Walk the address list, and load the filter */
-		hardware_set_filter(dev->mc_list);
-
-		outw(MULTICAST, ioaddr);
-	}
-	else
-		outw(0, ioaddr);
-}
-
-#ifdef MODULE
-
-static struct net_device *this_device;
-static int io = 0x300;
-static int irq;
-static int dma;
-static int mem;
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
-	struct net_device *dev;
-	int result;
-
-	if (io == 0)
-		printk(KERN_WARNING "%s: You shouldn't use auto-probing with insmod!\n",
-			   cardname);
-	dev = alloc_etherdev(sizeof(struct net_local));
-	if (!dev)
-		return -ENOMEM;
-
-	/* Copy the parameters from insmod into the device structure. */
-	dev->base_addr = io;
-	dev->irq       = irq;
-	dev->dma       = dma;
-	dev->mem_start = mem;
-	if (do_netcard_probe(dev) == 0) {
-		this_device = dev;
-		return 0;
-	}
-	free_netdev(dev);
-	return -ENXIO;
-}
-
-void
-cleanup_module(void)
-{
-	unregister_netdev(this_device);
-	cleanup_card(this_device);
-	free_netdev(this_device);
-}
-
-#endif /* MODULE */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/iseries_veth.c linux-libre-2.6.34-gnu1/drivers/net/iseries_veth.c
--- linux-libre-2.6.33-gnu1/drivers/net/iseries_veth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/iseries_veth.c	2010-05-16 17:17:36.000000000 -0400
@@ -69,6 +69,7 @@
 #include <linux/mm.h>
 #include <linux/ethtool.h>
 #include <linux/if_ether.h>
+#include <linux/slab.h>
 
 #include <asm/abs_addr.h>
 #include <asm/iseries/mf.h>
@@ -384,7 +385,7 @@ static struct attribute *veth_cnx_defaul
 	NULL
 };
 
-static struct sysfs_ops veth_cnx_sysfs_ops = {
+static const struct sysfs_ops veth_cnx_sysfs_ops = {
 		.show = veth_cnx_attribute_show
 };
 
@@ -441,7 +442,7 @@ static struct attribute *veth_port_defau
 	NULL
 };
 
-static struct sysfs_ops veth_port_sysfs_ops = {
+static const struct sysfs_ops veth_port_sysfs_ops = {
 	.show = veth_port_attribute_show
 };
 
@@ -958,18 +959,17 @@ static void veth_set_multicast_list(stru
 	write_lock_irqsave(&port->mcast_gate, flags);
 
 	if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
-			(dev->mc_count > VETH_MAX_MCAST)) {
+			(netdev_mc_count(dev) > VETH_MAX_MCAST)) {
 		port->promiscuous = 1;
 	} else {
-		struct dev_mc_list *dmi = dev->mc_list;
-		int i;
+		struct dev_mc_list *dmi;
 
 		port->promiscuous = 0;
 
 		/* Update table */
 		port->num_mcast = 0;
 
-		for (i = 0; i < dev->mc_count; i++) {
+		netdev_for_each_mc_addr(dmi, dev) {
 			u8 *addr = dmi->dmi_addr;
 			u64 xaddr = 0;
 
@@ -978,7 +978,6 @@ static void veth_set_multicast_list(stru
 				port->mcast_addr[port->num_mcast] = xaddr;
 				port->num_mcast++;
 			}
-			dmi = dmi->next;
 		}
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgb/ixgb.h linux-libre-2.6.34-gnu1/drivers/net/ixgb/ixgb.h
--- linux-libre-2.6.33-gnu1/drivers/net/ixgb/ixgb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgb/ixgb.h	2010-05-16 17:17:36.000000000 -0400
@@ -75,19 +75,14 @@ struct ixgb_adapter;
 #include "ixgb_ee.h"
 #include "ixgb_ids.h"
 
+#define PFX "ixgb: "
+
 #ifdef _DEBUG_DRIVER_
-#define IXGB_DBG(args...) printk(KERN_DEBUG "ixgb: " args)
+#define IXGB_DBG(args...) printk(KERN_DEBUG PFX args)
 #else
 #define IXGB_DBG(args...)
 #endif
 
-#define PFX "ixgb: "
-#define DPRINTK(nlevel, klevel, fmt, args...) \
-	(void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
-	printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
-		__func__ , ## args))
-
-
 /* TX/RX descriptor defines */
 #define DEFAULT_TXD      256
 #define MAX_TXD         4096
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgb/ixgb_main.c linux-libre-2.6.34-gnu1/drivers/net/ixgb/ixgb_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/ixgb/ixgb_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgb/ixgb_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,7 +50,7 @@ MODULE_PARM_DESC(copybreak,
  * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
  *   Class, Class Mask, private data (not used) }
  */
-static struct pci_device_id ixgb_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(ixgb_pci_tbl) = {
 	{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_CX4,
@@ -238,8 +238,8 @@ ixgb_up(struct ixgb_adapter *adapter)
 	if (err) {
 		if (adapter->have_msi)
 			pci_disable_msi(adapter->pdev);
-		DPRINTK(PROBE, ERR,
-		 "Unable to allocate interrupt Error: %d\n", err);
+		netif_err(adapter, probe, adapter->netdev,
+			  "Unable to allocate interrupt Error: %d\n", err);
 		return err;
 	}
 
@@ -310,7 +310,7 @@ ixgb_reset(struct ixgb_adapter *adapter)
 
 	ixgb_adapter_stop(hw);
 	if (!ixgb_init_hw(hw))
-		DPRINTK(PROBE, ERR, "ixgb_init_hw failed.\n");
+		netif_err(adapter, probe, adapter->netdev, "ixgb_init_hw failed\n");
 
 	/* restore frame size information */
 	IXGB_WRITE_REG(hw, MFS, hw->max_frame_size << IXGB_MFS_SHIFT);
@@ -447,7 +447,8 @@ ixgb_probe(struct pci_dev *pdev, const s
 	/* make sure the EEPROM is good */
 
 	if (!ixgb_validate_eeprom_checksum(&adapter->hw)) {
-		DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
+		netif_err(adapter, probe, adapter->netdev,
+			  "The EEPROM Checksum Is Not Valid\n");
 		err = -EIO;
 		goto err_eeprom;
 	}
@@ -456,7 +457,7 @@ ixgb_probe(struct pci_dev *pdev, const s
 	memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
 
 	if (!is_valid_ether_addr(netdev->perm_addr)) {
-		DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
+		netif_err(adapter, probe, adapter->netdev, "Invalid MAC Address\n");
 		err = -EIO;
 		goto err_eeprom;
 	}
@@ -477,7 +478,8 @@ ixgb_probe(struct pci_dev *pdev, const s
 	/* carrier off reporting is important to ethtool even BEFORE open */
 	netif_carrier_off(netdev);
 
-	DPRINTK(PROBE, INFO, "Intel(R) PRO/10GbE Network Connection\n");
+	netif_info(adapter, probe, adapter->netdev,
+		   "Intel(R) PRO/10GbE Network Connection\n");
 	ixgb_check_options(adapter);
 	/* reset the hardware with the new settings */
 
@@ -552,14 +554,14 @@ ixgb_sw_init(struct ixgb_adapter *adapte
 	hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
 	adapter->rx_buffer_len = hw->max_frame_size + 8; /* + 8 for errata */
 
-	if ((hw->device_id == IXGB_DEVICE_ID_82597EX)
-	   || (hw->device_id == IXGB_DEVICE_ID_82597EX_CX4)
-	   || (hw->device_id == IXGB_DEVICE_ID_82597EX_LR)
-	   || (hw->device_id == IXGB_DEVICE_ID_82597EX_SR))
+	if ((hw->device_id == IXGB_DEVICE_ID_82597EX) ||
+	    (hw->device_id == IXGB_DEVICE_ID_82597EX_CX4) ||
+	    (hw->device_id == IXGB_DEVICE_ID_82597EX_LR) ||
+	    (hw->device_id == IXGB_DEVICE_ID_82597EX_SR))
 		hw->mac_type = ixgb_82597;
 	else {
 		/* should never have loaded on this device */
-		DPRINTK(PROBE, ERR, "unsupported device id\n");
+		netif_err(adapter, probe, adapter->netdev, "unsupported device id\n");
 	}
 
 	/* enable flow control to be programmed */
@@ -661,8 +663,8 @@ ixgb_setup_tx_resources(struct ixgb_adap
 	size = sizeof(struct ixgb_buffer) * txdr->count;
 	txdr->buffer_info = vmalloc(size);
 	if (!txdr->buffer_info) {
-		DPRINTK(PROBE, ERR,
-		 "Unable to allocate transmit descriptor ring memory\n");
+		netif_err(adapter, probe, adapter->netdev,
+			  "Unable to allocate transmit descriptor ring memory\n");
 		return -ENOMEM;
 	}
 	memset(txdr->buffer_info, 0, size);
@@ -675,8 +677,8 @@ ixgb_setup_tx_resources(struct ixgb_adap
 	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
 	if (!txdr->desc) {
 		vfree(txdr->buffer_info);
-		DPRINTK(PROBE, ERR,
-		 "Unable to allocate transmit descriptor memory\n");
+		netif_err(adapter, probe, adapter->netdev,
+			  "Unable to allocate transmit descriptor memory\n");
 		return -ENOMEM;
 	}
 	memset(txdr->desc, 0, txdr->size);
@@ -750,8 +752,8 @@ ixgb_setup_rx_resources(struct ixgb_adap
 	size = sizeof(struct ixgb_buffer) * rxdr->count;
 	rxdr->buffer_info = vmalloc(size);
 	if (!rxdr->buffer_info) {
-		DPRINTK(PROBE, ERR,
-		 "Unable to allocate receive descriptor ring\n");
+		netif_err(adapter, probe, adapter->netdev,
+			  "Unable to allocate receive descriptor ring\n");
 		return -ENOMEM;
 	}
 	memset(rxdr->buffer_info, 0, size);
@@ -765,8 +767,8 @@ ixgb_setup_rx_resources(struct ixgb_adap
 
 	if (!rxdr->desc) {
 		vfree(rxdr->buffer_info);
-		DPRINTK(PROBE, ERR,
-		 "Unable to allocate receive descriptors\n");
+		netif_err(adapter, probe, adapter->netdev,
+			  "Unable to allocate receive descriptors\n");
 		return -ENOMEM;
 	}
 	memset(rxdr->desc, 0, rxdr->size);
@@ -1077,7 +1079,7 @@ ixgb_set_multi(struct net_device *netdev
 		rctl |= IXGB_RCTL_VFE;
 	}
 
-	if (netdev->mc_count > IXGB_MAX_NUM_MULTICAST_ADDRESSES) {
+	if (netdev_mc_count(netdev) > IXGB_MAX_NUM_MULTICAST_ADDRESSES) {
 		rctl |= IXGB_RCTL_MPE;
 		IXGB_WRITE_REG(hw, RCTL, rctl);
 	} else {
@@ -1086,13 +1088,12 @@ ixgb_set_multi(struct net_device *netdev
 
 		IXGB_WRITE_REG(hw, RCTL, rctl);
 
-		for (i = 0, mc_ptr = netdev->mc_list;
-		     mc_ptr;
-		     i++, mc_ptr = mc_ptr->next)
-			memcpy(&mta[i * IXGB_ETH_LENGTH_OF_ADDRESS],
+		i = 0;
+		netdev_for_each_mc_addr(mc_ptr, netdev)
+			memcpy(&mta[i++ * IXGB_ETH_LENGTH_OF_ADDRESS],
 			       mc_ptr->dmi_addr, IXGB_ETH_LENGTH_OF_ADDRESS);
 
-		ixgb_mc_addr_list_update(hw, mta, netdev->mc_count, 0);
+		ixgb_mc_addr_list_update(hw, mta, netdev_mc_count(netdev), 0);
 	}
 }
 
@@ -1580,7 +1581,8 @@ ixgb_change_mtu(struct net_device *netde
 	/* MTU < 68 is an error for IPv4 traffic, just don't allow it */
 	if ((new_mtu < 68) ||
 	    (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) {
-		DPRINTK(PROBE, ERR, "Invalid MTU setting %d\n", new_mtu);
+		netif_err(adapter, probe, adapter->netdev,
+			  "Invalid MTU setting %d\n", new_mtu);
 		return -EINVAL;
 	}
 
@@ -1616,7 +1618,7 @@ ixgb_update_stats(struct ixgb_adapter *a
 		return;
 
 	if ((netdev->flags & IFF_PROMISC) || (netdev->flags & IFF_ALLMULTI) ||
-	   (netdev->mc_count > IXGB_MAX_NUM_MULTICAST_ADDRESSES)) {
+	   (netdev_mc_count(netdev) > IXGB_MAX_NUM_MULTICAST_ADDRESSES)) {
 		u64 multi = IXGB_READ_REG(&adapter->hw, MPRCL);
 		u32 bcast_l = IXGB_READ_REG(&adapter->hw, BPRCL);
 		u32 bcast_h = IXGB_READ_REG(&adapter->hw, BPRCH);
@@ -1854,24 +1856,25 @@ ixgb_clean_tx_irq(struct ixgb_adapter *a
 		   && !(IXGB_READ_REG(&adapter->hw, STATUS) &
 		        IXGB_STATUS_TXOFF)) {
 			/* detected Tx unit hang */
-			DPRINTK(DRV, ERR, "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",
-				IXGB_READ_REG(&adapter->hw, TDH),
-				IXGB_READ_REG(&adapter->hw, TDT),
-				tx_ring->next_to_use,
-				tx_ring->next_to_clean,
-				tx_ring->buffer_info[eop].time_stamp,
-				eop,
-				jiffies,
-				eop_desc->status);
+			netif_err(adapter, drv, adapter->netdev,
+				  "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",
+				  IXGB_READ_REG(&adapter->hw, TDH),
+				  IXGB_READ_REG(&adapter->hw, TDT),
+				  tx_ring->next_to_use,
+				  tx_ring->next_to_clean,
+				  tx_ring->buffer_info[eop].time_stamp,
+				  eop,
+				  jiffies,
+				  eop_desc->status);
 			netif_stop_queue(netdev);
 		}
 	}
@@ -2269,7 +2272,8 @@ static pci_ers_result_t ixgb_io_slot_res
 	struct ixgb_adapter *adapter = netdev_priv(netdev);
 
 	if (pci_enable_device(pdev)) {
-		DPRINTK(PROBE, ERR, "Cannot re-enable PCI device after reset.\n");
+		netif_err(adapter, probe, adapter->netdev,
+			  "Cannot re-enable PCI device after reset\n");
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 
@@ -2285,14 +2289,16 @@ static pci_ers_result_t ixgb_io_slot_res
 
 	/* Make sure the EEPROM is good */
 	if (!ixgb_validate_eeprom_checksum(&adapter->hw)) {
-		DPRINTK(PROBE, ERR, "After reset, the EEPROM checksum is not valid.\n");
+		netif_err(adapter, probe, adapter->netdev,
+			  "After reset, the EEPROM checksum is not valid\n");
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 	ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);
 	memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
 
 	if (!is_valid_ether_addr(netdev->perm_addr)) {
-		DPRINTK(PROBE, ERR, "After reset, invalid MAC address.\n");
+		netif_err(adapter, probe, adapter->netdev,
+			  "After reset, invalid MAC address\n");
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_82599.c linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_82599.c
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_82599.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_82599.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 
 #include "ixgbe.h"
 #include "ixgbe_phy.h"
+#include "ixgbe_mbx.h"
 
 #define IXGBE_82599_MAX_TX_QUEUES 128
 #define IXGBE_82599_MAX_RX_QUEUES 128
@@ -38,6 +39,9 @@
 #define IXGBE_82599_MC_TBL_SIZE   128
 #define IXGBE_82599_VFT_TBL_SIZE  128
 
+void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
+void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
+void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
 s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                                           ixgbe_link_speed speed,
                                           bool autoneg,
@@ -67,7 +71,15 @@ static void ixgbe_init_mac_link_ops_8259
 	if (hw->phy.multispeed_fiber) {
 		/* Set up dual speed SFP+ support */
 		mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber;
+		mac->ops.disable_tx_laser =
+		                       &ixgbe_disable_tx_laser_multispeed_fiber;
+		mac->ops.enable_tx_laser =
+		                        &ixgbe_enable_tx_laser_multispeed_fiber;
+		mac->ops.flap_tx_laser = &ixgbe_flap_tx_laser_multispeed_fiber;
 	} else {
+		mac->ops.disable_tx_laser = NULL;
+		mac->ops.enable_tx_laser = NULL;
+		mac->ops.flap_tx_laser = NULL;
 		if ((mac->ops.get_media_type(hw) ==
 		     ixgbe_media_type_backplane) &&
 		    (hw->phy.smart_speed == ixgbe_smart_speed_auto ||
@@ -411,6 +423,67 @@ s32 ixgbe_start_mac_link_82599(struct ix
 	return status;
 }
 
+ /**
+  *  ixgbe_disable_tx_laser_multispeed_fiber - Disable Tx laser
+  *  @hw: pointer to hardware structure
+  *
+  *  The base drivers may require better control over SFP+ module
+  *  PHY states.  This includes selectively shutting down the Tx
+  *  laser on the PHY, effectively halting physical link.
+  **/
+void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
+{
+	u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
+
+	/* Disable tx laser; allow 100us to go dark per spec */
+	esdp_reg |= IXGBE_ESDP_SDP3;
+	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+	IXGBE_WRITE_FLUSH(hw);
+	udelay(100);
+}
+
+/**
+ *  ixgbe_enable_tx_laser_multispeed_fiber - Enable Tx laser
+ *  @hw: pointer to hardware structure
+ *
+ *  The base drivers may require better control over SFP+ module
+ *  PHY states.  This includes selectively turning on the Tx
+ *  laser on the PHY, effectively starting physical link.
+ **/
+void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
+{
+	u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
+
+	/* Enable tx laser; allow 100ms to light up */
+	esdp_reg &= ~IXGBE_ESDP_SDP3;
+	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+	IXGBE_WRITE_FLUSH(hw);
+	msleep(100);
+}
+
+/**
+ *  ixgbe_flap_tx_laser_multispeed_fiber - Flap Tx laser
+ *  @hw: pointer to hardware structure
+ *
+ *  When the driver changes the link speeds that it can support,
+ *  it sets autotry_restart to true to indicate that we need to
+ *  initiate a new autotry session with the link partner.  To do
+ *  so, we set the speed then disable and re-enable the tx laser, to
+ *  alert the link partner that it also needs to restart autotry on its
+ *  end.  This is consistent with true clause 37 autoneg, which also
+ *  involves a loss of signal.
+ **/
+void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
+{
+	hw_dbg(hw, "ixgbe_flap_tx_laser_multispeed_fiber\n");
+
+	if (hw->mac.autotry_restart) {
+		ixgbe_disable_tx_laser_multispeed_fiber(hw);
+		ixgbe_enable_tx_laser_multispeed_fiber(hw);
+		hw->mac.autotry_restart = false;
+	}
+}
+
 /**
  *  ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
  *  @hw: pointer to hardware structure
@@ -439,16 +512,6 @@ s32 ixgbe_setup_mac_link_multispeed_fibe
 	speed &= phy_link_speed;
 
 	/*
-	 * When the driver changes the link speeds that it can support,
-	 * it sets autotry_restart to true to indicate that we need to
-	 * initiate a new autotry session with the link partner.  To do
-	 * so, we set the speed then disable and re-enable the tx laser, to
-	 * alert the link partner that it also needs to restart autotry on its
-	 * end.  This is consistent with true clause 37 autoneg, which also
-	 * involves a loss of signal.
-	 */
-
-	/*
 	 * Try each speed one by one, highest priority first.  We do this in
 	 * software because 10gb fiber doesn't support speed autonegotiation.
 	 */
@@ -465,6 +528,7 @@ s32 ixgbe_setup_mac_link_multispeed_fibe
 		/* Set the module link speed */
 		esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
 		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+		IXGBE_WRITE_FLUSH(hw);
 
 		/* Allow module to change analog characteristics (1G->10G) */
 		msleep(40);
@@ -477,19 +541,7 @@ s32 ixgbe_setup_mac_link_multispeed_fibe
 			return status;
 
 		/* Flap the tx laser if it has not already been done */
-		if (hw->mac.autotry_restart) {
-			/* Disable tx laser; allow 100us to go dark per spec */
-			esdp_reg |= IXGBE_ESDP_SDP3;
-			IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-			udelay(100);
-
-			/* Enable tx laser; allow 2ms to light up per spec */
-			esdp_reg &= ~IXGBE_ESDP_SDP3;
-			IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-			msleep(2);
-
-			hw->mac.autotry_restart = false;
-		}
+		hw->mac.ops.flap_tx_laser(hw);
 
 		/*
 		 * Wait for the controller to acquire link.  Per IEEE 802.3ap,
@@ -524,6 +576,7 @@ s32 ixgbe_setup_mac_link_multispeed_fibe
 		esdp_reg &= ~IXGBE_ESDP_SDP5;
 		esdp_reg |= IXGBE_ESDP_SDP5_DIR;
 		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+		IXGBE_WRITE_FLUSH(hw);
 
 		/* Allow module to change analog characteristics (10G->1G) */
 		msleep(40);
@@ -536,19 +589,7 @@ s32 ixgbe_setup_mac_link_multispeed_fibe
 			return status;
 
 		/* Flap the tx laser if it has not already been done */
-		if (hw->mac.autotry_restart) {
-			/* Disable tx laser; allow 100us to go dark per spec */
-			esdp_reg |= IXGBE_ESDP_SDP3;
-			IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-			udelay(100);
-
-			/* Enable tx laser; allow 2ms to light up per spec */
-			esdp_reg &= ~IXGBE_ESDP_SDP3;
-			IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-			msleep(2);
-
-			hw->mac.autotry_restart = false;
-		}
+		hw->mac.ops.flap_tx_laser(hw);
 
 		/* Wait for the link partner to also set speed */
 		msleep(100);
@@ -889,7 +930,7 @@ static s32 ixgbe_setup_copper_link_82599
 static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
 {
 	s32 status = 0;
-	u32 ctrl, ctrl_ext;
+	u32 ctrl;
 	u32 i;
 	u32 autoc;
 	u32 autoc2;
@@ -944,15 +985,9 @@ static s32 ixgbe_reset_hw_82599(struct i
 		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
@@ -1095,9 +1130,11 @@ static s32 ixgbe_set_vfta_82599(struct i
                                 bool vlan_on)
 {
 	u32 regindex;
+	u32 vlvf_index;
 	u32 bitindex;
 	u32 bits;
 	u32 first_empty_slot;
+	u32 vt_ctl;
 
 	if (vlan > 4095)
 		return IXGBE_ERR_PARAM;
@@ -1124,76 +1161,84 @@ static s32 ixgbe_set_vfta_82599(struct i
 
 
 	/* Part 2
-	 * If the vind is set
+	 * If VT mode 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;
+	vt_ctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
+	if (!(vt_ctl & IXGBE_VT_CTL_VT_ENABLE))
+		goto out;
 
-		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;
-		}
+	/* find the vlanid or the first empty slot */
+	first_empty_slot = 0;
 
-		if (regindex >= IXGBE_VLVF_ENTRIES) {
-			if (first_empty_slot)
-				regindex = first_empty_slot;
-			else {
-				hw_dbg(hw, "No space in VLVF.\n");
-				goto out;
-			}
+	for (vlvf_index = 1; vlvf_index < IXGBE_VLVF_ENTRIES; vlvf_index++) {
+		bits = IXGBE_READ_REG(hw, IXGBE_VLVF(vlvf_index));
+		if (!bits && !first_empty_slot)
+			first_empty_slot = vlvf_index;
+		else if ((bits & 0x0FFF) == vlan)
+			break;
+	}
+
+	if (vlvf_index >= IXGBE_VLVF_ENTRIES) {
+		if (first_empty_slot)
+			vlvf_index = 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);
-			}
+	if (vlan_on) {
+		/* set the pool bit */
+		if (vind < 32) {
+			bits = IXGBE_READ_REG(hw,
+					      IXGBE_VLVFB(vlvf_index * 2));
+			bits |= (1 << vind);
+			IXGBE_WRITE_REG(hw,
+					IXGBE_VLVFB(vlvf_index * 2), bits);
 		} else {
-			/* clear the pool bit */
-			if (vind < 32) {
-				bits = IXGBE_READ_REG(hw,
-				     IXGBE_VLVFB(regindex * 2));
+			bits = IXGBE_READ_REG(hw,
+				IXGBE_VLVFB((vlvf_index * 2) + 1));
+			bits |= (1 << (vind - 32));
+			IXGBE_WRITE_REG(hw,
+				IXGBE_VLVFB((vlvf_index * 2) + 1), bits);
+		}
+	} else {
+		/* clear the pool bit */
+		if (vind < 32) {
+			bits = IXGBE_READ_REG(hw,
+					      IXGBE_VLVFB(vlvf_index * 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));
-			}
+			IXGBE_WRITE_REG(hw,
+					IXGBE_VLVFB(vlvf_index * 2), bits);
+			bits |= IXGBE_READ_REG(hw,
+					IXGBE_VLVFB((vlvf_index * 2) + 1));
+		} else {
+			bits = IXGBE_READ_REG(hw,
+				IXGBE_VLVFB((vlvf_index * 2) + 1));
+			bits &= ~(1 << (vind - 32));
+			IXGBE_WRITE_REG(hw,
+				IXGBE_VLVFB((vlvf_index * 2) + 1), bits);
+			bits |= IXGBE_READ_REG(hw,
+					       IXGBE_VLVFB(vlvf_index * 2));
 		}
+	}
 
-		if (bits)
-			IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex),
-			                (IXGBE_VLVF_VIEN | vlan));
-		else
-			IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex), 0);
+	if (bits) {
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
+				(IXGBE_VLVF_VIEN | vlan));
+		/* if bits is non-zero then some pools/VFs are still
+		 * using this VLAN ID.  Force the VFTA entry to on */
+		bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
+		bits |= (1 << bitindex);
+		IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
 	}
+	else
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
 
 out:
 	return 0;
@@ -1434,6 +1479,9 @@ s32 ixgbe_init_fdir_perfect_82599(struct
 	/* Send interrupt when 64 filters are left */
 	fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT;
 
+	/* Initialize the drop queue to Rx queue 127 */
+	fdirctrl |= (127 << IXGBE_FDIRCTRL_DROP_Q_SHIFT);
+
 	switch (pballoc) {
 	case IXGBE_FDIR_PBALLOC_64K:
 		/* 2k - 1 perfect filters */
@@ -1675,8 +1723,8 @@ s32 ixgbe_atr_set_dst_ipv4_82599(struct
  *  @src_addr_4: the fourth 4 bytes of the IP address to load
  **/
 s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input,
-                                        u32 src_addr_1, u32 src_addr_2,
-                                        u32 src_addr_3, u32 src_addr_4)
+                                 u32 src_addr_1, u32 src_addr_2,
+                                 u32 src_addr_3, u32 src_addr_4)
 {
 	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET] = src_addr_4 & 0xff;
 	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] =
@@ -1718,8 +1766,8 @@ s32 ixgbe_atr_set_src_ipv6_82599(struct
  *  @dst_addr_4: the fourth 4 bytes of the IP address to load
  **/
 s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input,
-                                        u32 dst_addr_1, u32 dst_addr_2,
-                                        u32 dst_addr_3, u32 dst_addr_4)
+                                 u32 dst_addr_1, u32 dst_addr_2,
+                                 u32 dst_addr_3, u32 dst_addr_4)
 {
 	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET] = dst_addr_4 & 0xff;
 	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] =
@@ -1797,7 +1845,7 @@ s32 ixgbe_atr_set_flex_byte_82599(struct
  *  @vm_pool: the Virtual Machine pool to load
  **/
 s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input,
-                                       u8 vm_pool)
+                                u8 vm_pool)
 {
 	input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET] = vm_pool;
 
@@ -1821,8 +1869,7 @@ s32 ixgbe_atr_set_l4type_82599(struct ix
  *  @input: input stream to search
  *  @vlan: the VLAN id to load
  **/
-static s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input,
-                                       u16 *vlan)
+static s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, u16 *vlan)
 {
 	*vlan = input->byte_stream[IXGBE_ATR_VLAN_OFFSET];
 	*vlan |= input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] << 8;
@@ -2078,23 +2125,26 @@ s32 ixgbe_fdir_add_signature_filter_8259
  *  ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter
  *  @hw: pointer to hardware structure
  *  @input: input bitstream
+ *  @input_masks: bitwise masks for relevant fields
+ *  @soft_id: software index into the silicon hash tables for filter storage
  *  @queue: queue index to direct traffic to
  *
  *  Note that the caller to this function must lock before calling, since the
  *  hardware writes must be protected from one another.
  **/
 s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
-                                               struct ixgbe_atr_input *input,
-                                               u16 soft_id,
-                                               u8 queue)
+                                      struct ixgbe_atr_input *input,
+                                      struct ixgbe_atr_input_masks *input_masks,
+                                      u16 soft_id, u8 queue)
 {
 	u32 fdircmd = 0;
 	u32 fdirhash;
-	u32 src_ipv4, dst_ipv4;
+	u32 src_ipv4 = 0, dst_ipv4 = 0;
 	u32 src_ipv6_1, src_ipv6_2, src_ipv6_3, src_ipv6_4;
 	u16 src_port, dst_port, vlan_id, flex_bytes;
 	u16 bucket_hash;
 	u8  l4type;
+	u8  fdirm = 0;
 
 	/* Get our input values */
 	ixgbe_atr_get_l4type_82599(input, &l4type);
@@ -2149,7 +2199,6 @@ s32 ixgbe_fdir_add_perfect_filter_82599(
 		/* IPv4 */
 		ixgbe_atr_get_src_ipv4_82599(input, &src_ipv4);
 		IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv4);
-
 	}
 
 	ixgbe_atr_get_dst_ipv4_82599(input, &dst_ipv4);
@@ -2158,7 +2207,78 @@ s32 ixgbe_fdir_add_perfect_filter_82599(
 	IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, (vlan_id |
 	                            (flex_bytes << IXGBE_FDIRVLAN_FLEX_SHIFT)));
 	IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, (src_port |
-	                       (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT)));
+	              (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT)));
+
+	/*
+	 * Program the relevant mask registers.  If src/dst_port or src/dst_addr
+	 * are zero, then assume a full mask for that field.  Also assume that
+	 * a VLAN of 0 is unspecified, so mask that out as well.  L4type
+	 * cannot be masked out in this implementation.
+	 *
+	 * This also assumes IPv4 only.  IPv6 masking isn't supported at this
+	 * point in time.
+	 */
+	if (src_ipv4 == 0)
+		IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, 0xffffffff);
+	else
+		IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, input_masks->src_ip_mask);
+
+	if (dst_ipv4 == 0)
+		IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, 0xffffffff);
+	else
+		IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, input_masks->dst_ip_mask);
+
+	switch (l4type & IXGBE_ATR_L4TYPE_MASK) {
+	case IXGBE_ATR_L4TYPE_TCP:
+		if (src_port == 0)
+			IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, 0xffff);
+		else
+			IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM,
+			                input_masks->src_port_mask);
+
+		if (dst_port == 0)
+			IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM,
+			               (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) |
+			                (0xffff << 16)));
+		else
+			IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM,
+			               (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) |
+			                (input_masks->dst_port_mask << 16)));
+		break;
+	case IXGBE_ATR_L4TYPE_UDP:
+		if (src_port == 0)
+			IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, 0xffff);
+		else
+			IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM,
+			                input_masks->src_port_mask);
+
+		if (dst_port == 0)
+			IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM,
+			               (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) |
+			                (0xffff << 16)));
+		else
+			IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM,
+			               (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) |
+			                (input_masks->src_port_mask << 16)));
+		break;
+	default:
+		/* this already would have failed above */
+		break;
+	}
+
+	/* Program the last mask register, FDIRM */
+	if (input_masks->vlan_id_mask || !vlan_id)
+		/* Mask both VLAN and VLANP - bits 0 and 1 */
+		fdirm |= 0x3;
+
+	if (input_masks->data_mask || !flex_bytes)
+		/* Flex bytes need masking, so mask the whole thing - bit 4 */
+		fdirm |= 0x10;
+
+	/* Now mask VM pool and destination IPv6 - bits 5 and 2 */
+	fdirm |= 0x24;
+
+	IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm);
 
 	fdircmd |= IXGBE_FDIRCMD_CMD_ADD_FLOW;
 	fdircmd |= IXGBE_FDIRCMD_FILTER_UPDATE;
@@ -2655,4 +2775,5 @@ struct ixgbe_info ixgbe_82599_info = {
 	.mac_ops                = &mac_ops_82599,
 	.eeprom_ops             = &eeprom_ops_82599,
 	.phy_ops                = &phy_ops_82599,
+	.mbx_ops                = &mbx_ops_82599,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_common.c linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_common.c
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_common.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,6 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
-#include <linux/list.h>
 #include <linux/netdevice.h>
 
 #include "ixgbe.h"
@@ -1278,19 +1277,11 @@ s32 ixgbe_init_rx_addrs_generic(struct i
 		/* Get the MAC address from the RAR0 for later reference */
 		hw->mac.ops.get_mac_addr(hw, hw->mac.addr);
 
-		hw_dbg(hw, " Keeping Current RAR0 Addr =%.2X %.2X %.2X ",
-		       hw->mac.addr[0], hw->mac.addr[1],
-		       hw->mac.addr[2]);
-		hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3],
-		       hw->mac.addr[4], hw->mac.addr[5]);
+		hw_dbg(hw, " Keeping Current RAR0 Addr =%pM\n", hw->mac.addr);
 	} else {
 		/* Setup the receive address. */
 		hw_dbg(hw, "Overriding MAC Address in RAR[0]\n");
-		hw_dbg(hw, " New MAC Addr =%.2X %.2X %.2X ",
-		       hw->mac.addr[0], hw->mac.addr[1],
-		       hw->mac.addr[2]);
-		hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3],
-		       hw->mac.addr[4], hw->mac.addr[5]);
+		hw_dbg(hw, " New MAC Addr =%pM\n", hw->mac.addr);
 
 		hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
 	}
@@ -1355,7 +1346,7 @@ static void ixgbe_add_uc_addr(struct ixg
 /**
  *  ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses
  *  @hw: pointer to hardware structure
- *  @uc_list: the list of new addresses
+ *  @netdev: pointer to net device structure
  *
  *  The given list replaces any existing list.  Clears the secondary addrs from
  *  receive address registers.  Uses unused receive address registers for the
@@ -1365,7 +1356,7 @@ static void ixgbe_add_uc_addr(struct ixg
  *  manually putting the device into promiscuous mode.
  **/
 s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw,
-				      struct list_head *uc_list)
+				      struct net_device *netdev)
 {
 	u32 i;
 	u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc;
@@ -1389,7 +1380,7 @@ s32 ixgbe_update_uc_addr_list_generic(st
 	}
 
 	/* Add the new addresses */
-	list_for_each_entry(ha, uc_list, list) {
+	netdev_for_each_uc_addr(ha, netdev) {
 		hw_dbg(hw, " Adding the secondary addresses:\n");
 		ixgbe_add_uc_addr(hw, ha->addr, 0);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_common.h linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_common.h
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_common.h	2010-05-16 17:17:36.000000000 -0400
@@ -60,7 +60,7 @@ s32 ixgbe_update_mc_addr_list_generic(st
                                       u32 mc_addr_count,
                                       ixgbe_mc_addr_itr func);
 s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw,
-				      struct list_head *uc_list);
+				      struct net_device *netdev);
 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);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_ethtool.c linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 
 #include <linux/types.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
@@ -441,10 +442,8 @@ static int ixgbe_set_tso(struct net_devi
 		netdev->features |= NETIF_F_TSO;
 		netdev->features |= NETIF_F_TSO6;
 	} else {
-		netif_tx_stop_all_queues(netdev);
 		netdev->features &= ~NETIF_F_TSO;
 		netdev->features &= ~NETIF_F_TSO6;
-		netif_tx_start_all_queues(netdev);
 	}
 	return 0;
 }
@@ -834,8 +833,8 @@ static void ixgbe_get_ringparam(struct n
                                 struct ethtool_ringparam *ring)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-	struct ixgbe_ring *tx_ring = adapter->tx_ring;
-	struct ixgbe_ring *rx_ring = adapter->rx_ring;
+	struct ixgbe_ring *tx_ring = adapter->tx_ring[0];
+	struct ixgbe_ring *rx_ring = adapter->rx_ring[0];
 
 	ring->rx_max_pending = IXGBE_MAX_RXD;
 	ring->tx_max_pending = IXGBE_MAX_TXD;
@@ -867,8 +866,8 @@ static int ixgbe_set_ringparam(struct ne
 	new_tx_count = min(new_tx_count, (u32)IXGBE_MAX_TXD);
 	new_tx_count = ALIGN(new_tx_count, IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE);
 
-	if ((new_tx_count == adapter->tx_ring->count) &&
-	    (new_rx_count == adapter->rx_ring->count)) {
+	if ((new_tx_count == adapter->tx_ring[0]->count) &&
+	    (new_rx_count == adapter->rx_ring[0]->count)) {
 		/* nothing to do */
 		return 0;
 	}
@@ -878,25 +877,24 @@ static int ixgbe_set_ringparam(struct ne
 
 	if (!netif_running(adapter->netdev)) {
 		for (i = 0; i < adapter->num_tx_queues; i++)
-			adapter->tx_ring[i].count = new_tx_count;
+			adapter->tx_ring[i]->count = new_tx_count;
 		for (i = 0; i < adapter->num_rx_queues; i++)
-			adapter->rx_ring[i].count = new_rx_count;
+			adapter->rx_ring[i]->count = new_rx_count;
 		adapter->tx_ring_count = new_tx_count;
 		adapter->rx_ring_count = new_rx_count;
-		goto err_setup;
+		goto clear_reset;
 	}
 
-	temp_tx_ring = kcalloc(adapter->num_tx_queues,
-	                       sizeof(struct ixgbe_ring), GFP_KERNEL);
+	temp_tx_ring = vmalloc(adapter->num_tx_queues * sizeof(struct ixgbe_ring));
 	if (!temp_tx_ring) {
 		err = -ENOMEM;
-		goto err_setup;
+		goto clear_reset;
 	}
 
 	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++) {
+			memcpy(&temp_tx_ring[i], adapter->tx_ring[i],
+			       sizeof(struct ixgbe_ring));
 			temp_tx_ring[i].count = new_tx_count;
 			err = ixgbe_setup_tx_resources(adapter,
 			                               &temp_tx_ring[i]);
@@ -904,28 +902,24 @@ static int ixgbe_set_ringparam(struct ne
 				while (i) {
 					i--;
 					ixgbe_free_tx_resources(adapter,
-					                        &temp_tx_ring[i]);
+					                      &temp_tx_ring[i]);
 				}
-				goto err_setup;
+				goto clear_reset;
 			}
 		}
 		need_update = true;
 	}
 
-	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);
+	temp_rx_ring = vmalloc(adapter->num_rx_queues * sizeof(struct ixgbe_ring));
+	if (!temp_rx_ring) {
 		err = -ENOMEM;
 		goto err_setup;
 	}
 
 	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++) {
+			memcpy(&temp_rx_ring[i], adapter->rx_ring[i],
+			       sizeof(struct ixgbe_ring));
 			temp_rx_ring[i].count = new_rx_count;
 			err = ixgbe_setup_rx_resources(adapter,
 			                               &temp_rx_ring[i]);
@@ -947,22 +941,32 @@ static int ixgbe_set_ringparam(struct ne
 
 		/* tx */
 		if (new_tx_count != adapter->tx_ring_count) {
-			kfree(adapter->tx_ring);
-			adapter->tx_ring = temp_tx_ring;
-			temp_tx_ring = NULL;
+			for (i = 0; i < adapter->num_tx_queues; i++) {
+				ixgbe_free_tx_resources(adapter,
+				                        adapter->tx_ring[i]);
+				memcpy(adapter->tx_ring[i], &temp_tx_ring[i],
+				       sizeof(struct ixgbe_ring));
+			}
 			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;
+			for (i = 0; i < adapter->num_rx_queues; i++) {
+				ixgbe_free_rx_resources(adapter,
+				                        adapter->rx_ring[i]);
+				memcpy(adapter->rx_ring[i], &temp_rx_ring[i],
+				       sizeof(struct ixgbe_ring));
+			}
 			adapter->rx_ring_count = new_rx_count;
 		}
 		ixgbe_up(adapter);
 	}
+
+	vfree(temp_rx_ring);
 err_setup:
+	vfree(temp_tx_ring);
+clear_reset:
 	clear_bit(__IXGBE_RESETTING, &adapter->state);
 	return err;
 }
@@ -974,6 +978,9 @@ static int ixgbe_get_sset_count(struct n
 		return IXGBE_TEST_LEN;
 	case ETH_SS_STATS:
 		return IXGBE_STATS_LEN;
+	case ETH_SS_NTUPLE_FILTERS:
+		return (ETHTOOL_MAX_NTUPLE_LIST_ENTRY *
+		        ETHTOOL_MAX_NTUPLE_STRING_PER_ENTRY);
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -1007,13 +1014,13 @@ static void ixgbe_get_ethtool_stats(stru
 		           sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
 	}
 	for (j = 0; j < adapter->num_tx_queues; j++) {
-		queue_stat = (u64 *)&adapter->tx_ring[j].stats;
+		queue_stat = (u64 *)&adapter->tx_ring[j]->stats;
 		for (k = 0; k < stat_count; k++)
 			data[i + k] = queue_stat[k];
 		i += k;
 	}
 	for (j = 0; j < adapter->num_rx_queues; j++) {
-		queue_stat = (u64 *)&adapter->rx_ring[j].stats;
+		queue_stat = (u64 *)&adapter->rx_ring[j]->stats;
 		for (k = 0; k < stat_count; k++)
 			data[i + k] = queue_stat[k];
 		i += k;
@@ -1627,7 +1634,7 @@ static int ixgbe_setup_desc_rings(struct
 	reg_data |= IXGBE_RXDCTL_ENABLE;
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(0), reg_data);
 	if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
-		int j = adapter->rx_ring[0].reg_idx;
+		int j = adapter->rx_ring[0]->reg_idx;
 		u32 k;
 		for (k = 0; k < 10; k++) {
 			if (IXGBE_READ_REG(&adapter->hw,
@@ -1847,6 +1854,26 @@ static void ixgbe_diag_test(struct net_d
 		if (ixgbe_link_test(adapter, &data[4]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
+		if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
+			int i;
+			for (i = 0; i < adapter->num_vfs; i++) {
+				if (adapter->vfinfo[i].clear_to_send) {
+					netdev_warn(netdev, "%s",
+						    "offline diagnostic is not "
+						    "supported when VFs are "
+						    "present\n");
+					data[0] = 1;
+					data[1] = 1;
+					data[2] = 1;
+					data[3] = 1;
+					eth_test->flags |= ETH_TEST_FL_FAILED;
+					clear_bit(__IXGBE_TESTING,
+						  &adapter->state);
+					goto skip_ol_tests;
+				}
+			}
+		}
+
 		if (if_running)
 			/* indicate we're in test mode */
 			dev_close(netdev);
@@ -1867,11 +1894,22 @@ static void ixgbe_diag_test(struct net_d
 		if (ixgbe_intr_test(adapter, &data[2]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
+		/* If SRIOV or VMDq is enabled then skip MAC
+		 * loopback diagnostic. */
+		if (adapter->flags & (IXGBE_FLAG_SRIOV_ENABLED |
+				      IXGBE_FLAG_VMDQ_ENABLED)) {
+			DPRINTK(HW, INFO, "Skip MAC loopback diagnostic in VT "
+				"mode\n");
+			data[3] = 0;
+			goto skip_loopback;
+		}
+
 		ixgbe_reset(adapter);
 		DPRINTK(HW, INFO, "loopback testing starting\n");
 		if (ixgbe_loopback_test(adapter, &data[3]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
+skip_loopback:
 		ixgbe_reset(adapter);
 
 		clear_bit(__IXGBE_TESTING, &adapter->state);
@@ -1891,6 +1929,7 @@ static void ixgbe_diag_test(struct net_d
 
 		clear_bit(__IXGBE_TESTING, &adapter->state);
 	}
+skip_ol_tests:
 	msleep_interruptible(4 * 1000);
 }
 
@@ -2000,7 +2039,7 @@ static int ixgbe_get_coalesce(struct net
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
-	ec->tx_max_coalesced_frames_irq = adapter->tx_ring[0].work_limit;
+	ec->tx_max_coalesced_frames_irq = adapter->tx_ring[0]->work_limit;
 
 	/* only valid if in constant ITR mode */
 	switch (adapter->rx_itr_setting) {
@@ -2053,7 +2092,7 @@ static int ixgbe_set_coalesce(struct net
 		return -EINVAL;
 
 	if (ec->tx_max_coalesced_frames_irq)
-		adapter->tx_ring[0].work_limit = 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 */
@@ -2134,23 +2173,124 @@ static int ixgbe_set_coalesce(struct net
 static int ixgbe_set_flags(struct net_device *netdev, u32 data)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+	bool need_reset = false;
 
 	ethtool_op_set_flags(netdev, data);
 
-	if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE))
-		return 0;
-
 	/* if state changes we need to update adapter->flags and reset */
 	if ((!!(data & ETH_FLAG_LRO)) != 
 	    (!!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) {
 		adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED;
+		need_reset = true;
+	}
+
+	/*
+	 * Check if Flow Director n-tuple support was enabled or disabled.  If
+	 * the state changed, we need to reset.
+	 */
+	if ((adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) &&
+	    (!(data & ETH_FLAG_NTUPLE))) {
+		/* turn off Flow Director perfect, set hash and reset */
+		adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
+		adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
+		need_reset = true;
+	} else if ((!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) &&
+	           (data & ETH_FLAG_NTUPLE)) {
+		/* turn off Flow Director hash, enable perfect and reset */
+		adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
+		adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
+		need_reset = true;
+	} else {
+		/* no state change */
+	}
+
+	if (need_reset) {
 		if (netif_running(netdev))
 			ixgbe_reinit_locked(adapter);
 		else
 			ixgbe_reset(adapter);
 	}
+
 	return 0;
+}
+
+static int ixgbe_set_rx_ntuple(struct net_device *dev,
+                               struct ethtool_rx_ntuple *cmd)
+{
+	struct ixgbe_adapter *adapter = netdev_priv(dev);
+	struct ethtool_rx_ntuple_flow_spec fs = cmd->fs;
+	struct ixgbe_atr_input input_struct;
+	struct ixgbe_atr_input_masks input_masks;
+	int target_queue;
+
+	if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+		return -EOPNOTSUPP;
+
+	/*
+	 * Don't allow programming if the action is a queue greater than
+	 * the number of online Tx queues.
+	 */
+	if ((fs.action >= adapter->num_tx_queues) ||
+	    (fs.action < ETHTOOL_RXNTUPLE_ACTION_DROP))
+		return -EINVAL;
+
+	memset(&input_struct, 0, sizeof(struct ixgbe_atr_input));
+	memset(&input_masks, 0, sizeof(struct ixgbe_atr_input_masks));
+
+	input_masks.src_ip_mask = fs.m_u.tcp_ip4_spec.ip4src;
+	input_masks.dst_ip_mask = fs.m_u.tcp_ip4_spec.ip4dst;
+	input_masks.src_port_mask = fs.m_u.tcp_ip4_spec.psrc;
+	input_masks.dst_port_mask = fs.m_u.tcp_ip4_spec.pdst;
+	input_masks.vlan_id_mask = fs.vlan_tag_mask;
+	/* only use the lowest 2 bytes for flex bytes */
+	input_masks.data_mask = (fs.data_mask & 0xffff);
+
+	switch (fs.flow_type) {
+	case TCP_V4_FLOW:
+		ixgbe_atr_set_l4type_82599(&input_struct, IXGBE_ATR_L4TYPE_TCP);
+		break;
+	case UDP_V4_FLOW:
+		ixgbe_atr_set_l4type_82599(&input_struct, IXGBE_ATR_L4TYPE_UDP);
+		break;
+	case SCTP_V4_FLOW:
+		ixgbe_atr_set_l4type_82599(&input_struct, IXGBE_ATR_L4TYPE_SCTP);
+		break;
+	default:
+		return -1;
+	}
+
+	/* Mask bits from the inputs based on user-supplied mask */
+	ixgbe_atr_set_src_ipv4_82599(&input_struct,
+	            (fs.h_u.tcp_ip4_spec.ip4src & ~fs.m_u.tcp_ip4_spec.ip4src));
+	ixgbe_atr_set_dst_ipv4_82599(&input_struct,
+	            (fs.h_u.tcp_ip4_spec.ip4dst & ~fs.m_u.tcp_ip4_spec.ip4dst));
+	/* 82599 expects these to be byte-swapped for perfect filtering */
+	ixgbe_atr_set_src_port_82599(&input_struct,
+	       ((ntohs(fs.h_u.tcp_ip4_spec.psrc)) & ~fs.m_u.tcp_ip4_spec.psrc));
+	ixgbe_atr_set_dst_port_82599(&input_struct,
+	       ((ntohs(fs.h_u.tcp_ip4_spec.pdst)) & ~fs.m_u.tcp_ip4_spec.pdst));
+
+	/* VLAN and Flex bytes are either completely masked or not */
+	if (!fs.vlan_tag_mask)
+		ixgbe_atr_set_vlan_id_82599(&input_struct, fs.vlan_tag);
+
+	if (!input_masks.data_mask)
+		/* make sure we only use the first 2 bytes of user data */
+		ixgbe_atr_set_flex_byte_82599(&input_struct,
+		                              (fs.data & 0xffff));
 
+	/* determine if we need to drop or route the packet */
+	if (fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP)
+		target_queue = MAX_RX_QUEUES - 1;
+	else
+		target_queue = fs.action;
+
+	spin_lock(&adapter->fdir_perfect_lock);
+	ixgbe_fdir_add_perfect_filter_82599(&adapter->hw, &input_struct,
+	                                    &input_masks, 0, target_queue);
+	spin_unlock(&adapter->fdir_perfect_lock);
+
+	return 0;
 }
 
 static const struct ethtool_ops ixgbe_ethtool_ops = {
@@ -2188,6 +2328,7 @@ static const struct ethtool_ops ixgbe_et
 	.set_coalesce           = ixgbe_set_coalesce,
 	.get_flags              = ethtool_op_get_flags,
 	.set_flags              = ixgbe_set_flags,
+	.set_rx_ntuple          = ixgbe_set_rx_ntuple,
 };
 
 void ixgbe_set_ethtool_ops(struct net_device *netdev)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_fcoe.c linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_fcoe.c
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_fcoe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_fcoe.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include "ixgbe_dcb_82599.h"
 #endif /* CONFIG_IXGBE_DCB */
 #include <linux/if_ether.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include <scsi/fc/fc_fs.h>
@@ -202,6 +203,15 @@ int ixgbe_fcoe_ddp_get(struct net_device
 		addr = sg_dma_address(sg);
 		len = sg_dma_len(sg);
 		while (len) {
+			/* max number of buffers allowed in one DDP context */
+			if (j >= IXGBE_BUFFCNT_MAX) {
+				netif_err(adapter, drv, adapter->netdev,
+					  "xid=%x:%d,%d,%d:addr=%llx "
+					  "not enough descriptors\n",
+					  xid, i, j, dmacount, (u64)addr);
+				goto out_noddp_free;
+			}
+
 			/* get the offset of length of current buffer */
 			thisoff = addr & ((dma_addr_t)bufflen - 1);
 			thislen = min((bufflen - thisoff), len);
@@ -227,20 +237,13 @@ int ixgbe_fcoe_ddp_get(struct net_device
 			len -= thislen;
 			addr += thislen;
 			j++;
-			/* max number of buffers allowed in one DDP context */
-			if (j > IXGBE_BUFFCNT_MAX) {
-				DPRINTK(DRV, ERR, "xid=%x:%d,%d,%d:addr=%llx "
-					"not enough descriptors\n",
-					xid, i, j, dmacount, (u64)addr);
-				goto out_noddp_free;
-			}
 		}
 	}
 	/* only the last buffer may have non-full bufflen */
 	lastsize = thisoff + thislen;
 
 	fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT);
-	fcbuff |= (j << IXGBE_FCBUFF_BUFFCNT_SHIFT);
+	fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT);
 	fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT);
 	fcbuff |= (IXGBE_FCBUFF_VALID);
 
@@ -520,25 +523,40 @@ void ixgbe_configure_fcoe(struct ixgbe_a
 	/* Enable L2 eth type filter for FCoE */
 	IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FCOE),
 			(ETH_P_FCOE | IXGBE_ETQF_FCOE | IXGBE_ETQF_FILTER_EN));
+	/* Enable L2 eth type filter for FIP */
+	IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FIP),
+			(ETH_P_FIP | IXGBE_ETQF_FILTER_EN));
 	if (adapter->ring_feature[RING_F_FCOE].indices) {
 		/* Use multiple rx queues for FCoE by redirection table */
 		for (i = 0; i < IXGBE_FCRETA_SIZE; i++) {
 			fcoe_i = f->mask + i % f->indices;
 			fcoe_i &= IXGBE_FCRETA_ENTRY_MASK;
-			fcoe_q = adapter->rx_ring[fcoe_i].reg_idx;
+			fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx;
 			IXGBE_WRITE_REG(hw, IXGBE_FCRETA(i), fcoe_q);
 		}
 		IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, IXGBE_FCRECTL_ENA);
 		IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE), 0);
+		fcoe_i = f->mask;
+		fcoe_i &= IXGBE_FCRETA_ENTRY_MASK;
+		fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx;
+		IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP),
+				IXGBE_ETQS_QUEUE_EN |
+				(fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
 	} else  {
 		/* Use single rx queue for FCoE */
 		fcoe_i = f->mask;
-		fcoe_q = adapter->rx_ring[fcoe_i].reg_idx;
+		fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx;
 		IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, 0);
 		IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE),
 				IXGBE_ETQS_QUEUE_EN |
 				(fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
 	}
+	/* send FIP frames to the first FCoE queue */
+	fcoe_i = f->mask;
+	fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx;
+	IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP),
+			IXGBE_ETQS_QUEUE_EN |
+			(fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
 
 	IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL,
 			IXGBE_FCRXCTRL_FCOELLI |
@@ -614,9 +632,9 @@ int ixgbe_fcoe_enable(struct net_device
 	netdev->vlan_features |= NETIF_F_FSO;
 	netdev->vlan_features |= NETIF_F_FCOE_MTU;
 	netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1;
-	netdev_features_change(netdev);
 
 	ixgbe_init_interrupt_scheme(adapter);
+	netdev_features_change(netdev);
 
 	if (netif_running(netdev))
 		netdev->netdev_ops->ndo_open(netdev);
@@ -660,11 +678,11 @@ int ixgbe_fcoe_disable(struct net_device
 	netdev->vlan_features &= ~NETIF_F_FSO;
 	netdev->vlan_features &= ~NETIF_F_FCOE_MTU;
 	netdev->fcoe_ddp_xid = 0;
-	netdev_features_change(netdev);
 
 	ixgbe_cleanup_fcoe(adapter);
-
 	ixgbe_init_interrupt_scheme(adapter);
+	netdev_features_change(netdev);
+
 	if (netif_running(netdev))
 		netdev->netdev_ops->ndo_open(netdev);
 	rc = 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe.h linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe.h
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe.h	2010-05-16 17:17:36.000000000 -0400
@@ -98,6 +98,22 @@
 
 #define IXGBE_MAX_RSC_INT_RATE          162760
 
+#define IXGBE_MAX_VF_MC_ENTRIES         30
+#define IXGBE_MAX_VF_FUNCTIONS          64
+#define IXGBE_MAX_VFTA_ENTRIES          128
+#define MAX_EMULATION_MAC_ADDRS         16
+#define VMDQ_P(p)   ((p) + adapter->num_vfs)
+
+struct vf_data_storage {
+	unsigned char vf_mac_addresses[ETH_ALEN];
+	u16 vf_mc_hashes[IXGBE_MAX_VF_MC_ENTRIES];
+	u16 num_vf_mc_hashes;
+	u16 default_vf_vlan_id;
+	u16 vlans_enabled;
+	bool clear_to_send;
+	int rar;
+};
+
 /* wrapper around a pointer to a socket buffer,
  * so a DMA handle can be stored along with the buffer */
 struct ixgbe_tx_buffer {
@@ -159,6 +175,7 @@ struct ixgbe_ring {
 
 	struct ixgbe_queue_stats stats;
 	unsigned long reinit_state;
+	int numa_node;
 	u64 rsc_count;			/* stat for coalesced packets */
 	u64 rsc_flush;			/* stats for flushed packets */
 	u32 restart_queue;		/* track tx queue restarts */
@@ -171,7 +188,7 @@ struct ixgbe_ring {
 enum ixgbe_ring_f_enum {
 	RING_F_NONE = 0,
 	RING_F_DCB,
-	RING_F_VMDQ,
+	RING_F_VMDQ,  /* SR-IOV uses the same ring feature */
 	RING_F_RSS,
 	RING_F_FDIR,
 #ifdef IXGBE_FCOE
@@ -183,18 +200,21 @@ enum ixgbe_ring_f_enum {
 
 #define IXGBE_MAX_DCB_INDICES   8
 #define IXGBE_MAX_RSS_INDICES  16
-#define IXGBE_MAX_VMDQ_INDICES 16
+#define IXGBE_MAX_VMDQ_INDICES 64
 #define IXGBE_MAX_FDIR_INDICES 64
 #ifdef IXGBE_FCOE
 #define IXGBE_MAX_FCOE_INDICES  8
+#define MAX_RX_QUEUES (IXGBE_MAX_FDIR_INDICES + IXGBE_MAX_FCOE_INDICES)
+#define MAX_TX_QUEUES (IXGBE_MAX_FDIR_INDICES + IXGBE_MAX_FCOE_INDICES)
+#else
+#define MAX_RX_QUEUES IXGBE_MAX_FDIR_INDICES
+#define MAX_TX_QUEUES IXGBE_MAX_FDIR_INDICES
 #endif /* IXGBE_FCOE */
 struct ixgbe_ring_feature {
 	int indices;
 	int mask;
 } ____cacheline_internodealigned_in_smp;
 
-#define MAX_RX_QUEUES 128
-#define MAX_TX_QUEUES 128
 
 #define MAX_RX_PACKET_BUFFERS ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) \
                               ? 8 : 1)
@@ -277,7 +297,7 @@ struct ixgbe_adapter {
 	u16 eitr_high;
 
 	/* TX */
-	struct ixgbe_ring *tx_ring ____cacheline_aligned_in_smp; /* One per active queue */
+	struct ixgbe_ring *tx_ring[MAX_TX_QUEUES] ____cacheline_aligned_in_smp;
 	int num_tx_queues;
 	u32 tx_timeout_count;
 	bool detect_tx_hung;
@@ -286,8 +306,10 @@ struct ixgbe_adapter {
 	u64 lsc_int;
 
 	/* RX */
-	struct ixgbe_ring *rx_ring ____cacheline_aligned_in_smp; /* One per active queue */
+	struct ixgbe_ring *rx_ring[MAX_RX_QUEUES] ____cacheline_aligned_in_smp;
 	int num_rx_queues;
+	int num_rx_pools;		/* == num_rx_queues in 82598 */
+	int num_rx_queues_per_pool;	/* 1 if 82598, can be many if 82599 */
 	u64 hw_csum_rx_error;
 	u64 hw_rx_no_dma_resources;
 	u64 non_eop_descs;
@@ -323,13 +345,14 @@ struct ixgbe_adapter {
 #define IXGBE_FLAG_VMDQ_ENABLED                 (u32)(1 << 19)
 #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_IN_SFP_LINK_TASK             (u32)(1 << 24)
-#define IXGBE_FLAG_IN_SFP_MOD_TASK              (u32)(1 << 25)
-#define IXGBE_FLAG_FDIR_HASH_CAPABLE            (u32)(1 << 26)
-#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE         (u32)(1 << 27)
-#define IXGBE_FLAG_FCOE_CAPABLE                 (u32)(1 << 28)
-#define IXGBE_FLAG_FCOE_ENABLED                 (u32)(1 << 29)
+#define IXGBE_FLAG_IN_SFP_LINK_TASK             (u32)(1 << 23)
+#define IXGBE_FLAG_IN_SFP_MOD_TASK              (u32)(1 << 24)
+#define IXGBE_FLAG_FDIR_HASH_CAPABLE            (u32)(1 << 25)
+#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE         (u32)(1 << 26)
+#define IXGBE_FLAG_FCOE_CAPABLE                 (u32)(1 << 27)
+#define IXGBE_FLAG_FCOE_ENABLED                 (u32)(1 << 28)
+#define IXGBE_FLAG_SRIOV_CAPABLE                (u32)(1 << 29)
+#define IXGBE_FLAG_SRIOV_ENABLED                (u32)(1 << 30)
 
 	u32 flags2;
 #define IXGBE_FLAG2_RSC_CAPABLE                 (u32)(1)
@@ -379,6 +402,13 @@ struct ixgbe_adapter {
 	u64 rsc_total_flush;
 	u32 wol;
 	u16 eeprom_version;
+
+	int node;
+
+	/* SR-IOV */
+	DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS);
+	unsigned int num_vfs;
+	struct vf_data_storage *vfinfo;
 };
 
 enum ixbge_state_t {
@@ -426,6 +456,10 @@ extern s32 ixgbe_init_fdir_perfect_82599
 extern s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
                                                  struct ixgbe_atr_input *input,
                                                  u8 queue);
+extern s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
+                                      struct ixgbe_atr_input *input,
+                                      struct ixgbe_atr_input_masks *input_masks,
+                                      u16 soft_id, u8 queue);
 extern s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input,
                                        u16 vlan_id);
 extern s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input,
@@ -440,6 +474,7 @@ extern s32 ixgbe_atr_set_flex_byte_82599
                                          u16 flex_byte);
 extern s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input,
                                       u8 l4type);
+extern void ixgbe_set_rx_mode(struct net_device *netdev);
 #ifdef IXGBE_FCOE
 extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter);
 extern int ixgbe_fso(struct ixgbe_adapter *adapter,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_main.c linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/tcp.h>
 #include <linux/pkt_sched.h>
 #include <linux/ipv6.h>
+#include <linux/slab.h>
 #include <net/checksum.h>
 #include <net/ip6_checksum.h>
 #include <linux/ethtool.h>
@@ -45,12 +46,13 @@
 #include "ixgbe.h"
 #include "ixgbe_common.h"
 #include "ixgbe_dcb_82599.h"
+#include "ixgbe_sriov.h"
 
 char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
                               "Intel(R) 10 Gigabit PCI Express Network Driver";
 
-#define DRV_VERSION "2.0.44-k2"
+#define DRV_VERSION "2.0.62-k2"
 const char ixgbe_driver_version[] = DRV_VERSION;
 static char ixgbe_copyright[] = "Copyright (c) 1999-2010 Intel Corporation.";
 
@@ -67,7 +69,7 @@ static const struct ixgbe_info *ixgbe_in
  * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
  *   Class, Class Mask, private data (not used) }
  */
-static struct pci_device_id ixgbe_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = {
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598),
 	 board_82598 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_DUAL_PORT),
@@ -124,6 +126,13 @@ static struct notifier_block dca_notifie
 };
 #endif
 
+#ifdef CONFIG_PCI_IOV
+static unsigned int max_vfs;
+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 */
+
 MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
 MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver");
 MODULE_LICENSE("GPL");
@@ -131,6 +140,41 @@ MODULE_VERSION(DRV_VERSION);
 
 #define DEFAULT_DEBUG_LEVEL_SHIFT 3
 
+static inline void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 gcr;
+	u32 gpie;
+	u32 vmdctl;
+
+#ifdef CONFIG_PCI_IOV
+	/* disable iov and allow time for transactions to clear */
+	pci_disable_sriov(adapter->pdev);
+#endif
+
+	/* turn off device IOV mode */
+	gcr = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
+	gcr &= ~(IXGBE_GCR_EXT_SRIOV);
+	IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr);
+	gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
+	gpie &= ~IXGBE_GPIE_VTMODE_MASK;
+	IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
+
+	/* set default pool back to 0 */
+	vmdctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
+	vmdctl &= ~IXGBE_VT_CTL_POOL_MASK;
+	IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl);
+
+	/* take a breather then clean up driver data */
+	msleep(100);
+	if (adapter->vfinfo)
+		kfree(adapter->vfinfo);
+	adapter->vfinfo = NULL;
+
+	adapter->num_vfs = 0;
+	adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
+}
+
 static void ixgbe_release_hw_control(struct ixgbe_adapter *adapter)
 {
 	u32 ctrl_ext;
@@ -451,7 +495,7 @@ static void ixgbe_update_rx_dca(struct i
 {
 	u32 rxctrl;
 	int cpu = get_cpu();
-	int q = rx_ring - adapter->rx_ring;
+	int q = rx_ring->reg_idx;
 
 	if (rx_ring->cpu != cpu) {
 		rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q));
@@ -479,7 +523,7 @@ static void ixgbe_update_tx_dca(struct i
 {
 	u32 txctrl;
 	int cpu = get_cpu();
-	int q = tx_ring - adapter->tx_ring;
+	int q = tx_ring->reg_idx;
 	struct ixgbe_hw *hw = &adapter->hw;
 
 	if (tx_ring->cpu != cpu) {
@@ -513,12 +557,12 @@ static void ixgbe_setup_dca(struct ixgbe
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2);
 
 	for (i = 0; i < adapter->num_tx_queues; i++) {
-		adapter->tx_ring[i].cpu = -1;
-		ixgbe_update_tx_dca(adapter, &adapter->tx_ring[i]);
+		adapter->tx_ring[i]->cpu = -1;
+		ixgbe_update_tx_dca(adapter, adapter->tx_ring[i]);
 	}
 	for (i = 0; i < adapter->num_rx_queues; i++) {
-		adapter->rx_ring[i].cpu = -1;
-		ixgbe_update_rx_dca(adapter, &adapter->rx_ring[i]);
+		adapter->rx_ring[i]->cpu = -1;
+		ixgbe_update_rx_dca(adapter, adapter->rx_ring[i]);
 	}
 }
 
@@ -775,6 +819,12 @@ static inline struct sk_buff *ixgbe_tran
 	return skb;
 }
 
+struct ixgbe_rsc_cb {
+	dma_addr_t dma;
+};
+
+#define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb)
+
 static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
                                struct ixgbe_ring *rx_ring,
                                int *work_done, int work_to_do)
@@ -806,6 +856,7 @@ static bool ixgbe_clean_rx_irq(struct ix
 			break;
 		(*work_done)++;
 
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 		if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
 			hdr_info = le16_to_cpu(ixgbe_get_hdr_info(rx_desc));
 			len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
@@ -823,9 +874,21 @@ static bool ixgbe_clean_rx_irq(struct ix
 		rx_buffer_info->skb = NULL;
 
 		if (rx_buffer_info->dma) {
-			pci_unmap_single(pdev, rx_buffer_info->dma,
-			                 rx_ring->rx_buf_len,
-			                 PCI_DMA_FROMDEVICE);
+			if ((adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) &&
+			    (!(staterr & IXGBE_RXD_STAT_EOP)) &&
+				 (!(skb->prev)))
+				/*
+				 * When HWRSC is enabled, delay unmapping
+				 * of the first packet. It carries the
+				 * header information, HW may still
+				 * access the header after the writeback.
+				 * Only unmap it when EOP is reached
+				 */
+				IXGBE_RSC_CB(skb)->dma = rx_buffer_info->dma;
+			else
+				pci_unmap_single(pdev, rx_buffer_info->dma,
+				                 rx_ring->rx_buf_len,
+				                 PCI_DMA_FROMDEVICE);
 			rx_buffer_info->dma = 0;
 			skb_put(skb, len);
 		}
@@ -873,6 +936,12 @@ static bool ixgbe_clean_rx_irq(struct ix
 			if (skb->prev)
 				skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rsc_count));
 			if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
+				if (IXGBE_RSC_CB(skb)->dma) {
+					pci_unmap_single(pdev, IXGBE_RSC_CB(skb)->dma,
+					                 rx_ring->rx_buf_len,
+					                 PCI_DMA_FROMDEVICE);
+					IXGBE_RSC_CB(skb)->dma = 0;
+				}
 				if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)
 					rx_ring->rsc_count += skb_shinfo(skb)->nr_frags;
 				else
@@ -984,12 +1053,12 @@ static void ixgbe_configure_msix(struct
 	 */
 	for (v_idx = 0; v_idx < q_vectors; v_idx++) {
 		q_vector = adapter->q_vector[v_idx];
-		/* XXX for_each_bit(...) */
+		/* XXX for_each_set_bit(...) */
 		r_idx = find_first_bit(q_vector->rxr_idx,
 		                       adapter->num_rx_queues);
 
 		for (i = 0; i < q_vector->rxr_count; i++) {
-			j = adapter->rx_ring[r_idx].reg_idx;
+			j = adapter->rx_ring[r_idx]->reg_idx;
 			ixgbe_set_ivar(adapter, 0, j, v_idx);
 			r_idx = find_next_bit(q_vector->rxr_idx,
 			                      adapter->num_rx_queues,
@@ -999,7 +1068,7 @@ static void ixgbe_configure_msix(struct
 		                       adapter->num_tx_queues);
 
 		for (i = 0; i < q_vector->txr_count; i++) {
-			j = adapter->tx_ring[r_idx].reg_idx;
+			j = adapter->tx_ring[r_idx]->reg_idx;
 			ixgbe_set_ivar(adapter, 1, j, v_idx);
 			r_idx = find_next_bit(q_vector->txr_idx,
 			                      adapter->num_tx_queues,
@@ -1025,7 +1094,12 @@ static void ixgbe_configure_msix(struct
 
 	/* set up to autoclear timer, and the vectors */
 	mask = IXGBE_EIMS_ENABLE_MASK;
-	mask &= ~(IXGBE_EIMS_OTHER | IXGBE_EIMS_LSC);
+	if (adapter->num_vfs)
+		mask &= ~(IXGBE_EIMS_OTHER |
+			  IXGBE_EIMS_MAILBOX |
+			  IXGBE_EIMS_LSC);
+	else
+		mask &= ~(IXGBE_EIMS_OTHER | IXGBE_EIMS_LSC);
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC, mask);
 }
 
@@ -1134,7 +1208,7 @@ static void ixgbe_set_itr_msix(struct ix
 
 	r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
 	for (i = 0; i < q_vector->txr_count; i++) {
-		tx_ring = &(adapter->tx_ring[r_idx]);
+		tx_ring = adapter->tx_ring[r_idx];
 		ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
 		                           q_vector->tx_itr,
 		                           tx_ring->total_packets,
@@ -1149,7 +1223,7 @@ static void ixgbe_set_itr_msix(struct ix
 
 	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
 	for (i = 0; i < q_vector->rxr_count; i++) {
-		rx_ring = &(adapter->rx_ring[r_idx]);
+		rx_ring = adapter->rx_ring[r_idx];
 		ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
 		                           q_vector->rx_itr,
 		                           rx_ring->total_packets,
@@ -1254,6 +1328,9 @@ static irqreturn_t ixgbe_msix_lsc(int ir
 	if (eicr & IXGBE_EICR_LSC)
 		ixgbe_check_lsc(adapter);
 
+	if (eicr & IXGBE_EICR_MAILBOX)
+		ixgbe_msg_task(adapter);
+
 	if (hw->mac.type == ixgbe_mac_82598EB)
 		ixgbe_check_fan_failure(adapter, eicr);
 
@@ -1268,7 +1345,7 @@ static irqreturn_t ixgbe_msix_lsc(int ir
 			netif_tx_stop_all_queues(netdev);
 			for (i = 0; i < adapter->num_tx_queues; i++) {
 				struct ixgbe_ring *tx_ring =
-				                           &adapter->tx_ring[i];
+				                            adapter->tx_ring[i];
 				if (test_and_clear_bit(__IXGBE_FDIR_INIT_DONE,
 				                       &tx_ring->reinit_state))
 					schedule_work(&adapter->fdir_reinit_task);
@@ -1327,7 +1404,7 @@ static irqreturn_t ixgbe_msix_clean_tx(i
 
 	r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
 	for (i = 0; i < q_vector->txr_count; i++) {
-		tx_ring = &(adapter->tx_ring[r_idx]);
+		tx_ring = adapter->tx_ring[r_idx];
 		tx_ring->total_bytes = 0;
 		tx_ring->total_packets = 0;
 		r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
@@ -1355,7 +1432,7 @@ static irqreturn_t ixgbe_msix_clean_rx(i
 
 	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
 	for (i = 0;  i < q_vector->rxr_count; i++) {
-		rx_ring = &(adapter->rx_ring[r_idx]);
+		rx_ring = adapter->rx_ring[r_idx];
 		rx_ring->total_bytes = 0;
 		rx_ring->total_packets = 0;
 		r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
@@ -1385,7 +1462,7 @@ static irqreturn_t ixgbe_msix_clean_many
 
 	r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
 	for (i = 0; i < q_vector->txr_count; i++) {
-		ring = &(adapter->tx_ring[r_idx]);
+		ring = adapter->tx_ring[r_idx];
 		ring->total_bytes = 0;
 		ring->total_packets = 0;
 		r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
@@ -1394,7 +1471,7 @@ static irqreturn_t ixgbe_msix_clean_many
 
 	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
 	for (i = 0; i < q_vector->rxr_count; i++) {
-		ring = &(adapter->rx_ring[r_idx]);
+		ring = adapter->rx_ring[r_idx];
 		ring->total_bytes = 0;
 		ring->total_packets = 0;
 		r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
@@ -1425,7 +1502,7 @@ static int ixgbe_clean_rxonly(struct nap
 	long r_idx;
 
 	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-	rx_ring = &(adapter->rx_ring[r_idx]);
+	rx_ring = adapter->rx_ring[r_idx];
 #ifdef CONFIG_IXGBE_DCA
 	if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
 		ixgbe_update_rx_dca(adapter, rx_ring);
@@ -1466,7 +1543,7 @@ static int ixgbe_clean_rxtx_many(struct
 
 	r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
 	for (i = 0; i < q_vector->txr_count; i++) {
-		ring = &(adapter->tx_ring[r_idx]);
+		ring = adapter->tx_ring[r_idx];
 #ifdef CONFIG_IXGBE_DCA
 		if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
 			ixgbe_update_tx_dca(adapter, ring);
@@ -1482,7 +1559,7 @@ static int ixgbe_clean_rxtx_many(struct
 	budget = max(budget, 1);
 	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
 	for (i = 0; i < q_vector->rxr_count; i++) {
-		ring = &(adapter->rx_ring[r_idx]);
+		ring = adapter->rx_ring[r_idx];
 #ifdef CONFIG_IXGBE_DCA
 		if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
 			ixgbe_update_rx_dca(adapter, ring);
@@ -1493,7 +1570,7 @@ static int ixgbe_clean_rxtx_many(struct
 	}
 
 	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-	ring = &(adapter->rx_ring[r_idx]);
+	ring = adapter->rx_ring[r_idx];
 	/* If all Rx work done, exit the polling mode */
 	if (work_done < budget) {
 		napi_complete(napi);
@@ -1526,7 +1603,7 @@ static int ixgbe_clean_txonly(struct nap
 	long r_idx;
 
 	r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
-	tx_ring = &(adapter->tx_ring[r_idx]);
+	tx_ring = adapter->tx_ring[r_idx];
 #ifdef CONFIG_IXGBE_DCA
 	if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
 		ixgbe_update_tx_dca(adapter, tx_ring);
@@ -1711,8 +1788,8 @@ static void ixgbe_set_itr(struct ixgbe_a
 	struct ixgbe_q_vector *q_vector = adapter->q_vector[0];
 	u8 current_itr;
 	u32 new_itr = q_vector->eitr;
-	struct ixgbe_ring *rx_ring = &adapter->rx_ring[0];
-	struct ixgbe_ring *tx_ring = &adapter->tx_ring[0];
+	struct ixgbe_ring *rx_ring = adapter->rx_ring[0];
+	struct ixgbe_ring *tx_ring = adapter->tx_ring[0];
 
 	q_vector->tx_itr = ixgbe_update_itr(adapter, new_itr,
 	                                    q_vector->tx_itr,
@@ -1768,6 +1845,8 @@ static inline void ixgbe_irq_enable(stru
 		mask |= IXGBE_EIMS_ECC;
 		mask |= IXGBE_EIMS_GPI_SDP1;
 		mask |= IXGBE_EIMS_GPI_SDP2;
+		if (adapter->num_vfs)
+			mask |= IXGBE_EIMS_MAILBOX;
 	}
 	if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
 	    adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
@@ -1776,6 +1855,11 @@ static inline void ixgbe_irq_enable(stru
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
 	ixgbe_irq_enable_queues(adapter, ~0);
 	IXGBE_WRITE_FLUSH(&adapter->hw);
+
+	if (adapter->num_vfs > 32) {
+		u32 eitrsel = (1 << (adapter->num_vfs - 32)) - 1;
+		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITRSEL, eitrsel);
+	}
 }
 
 /**
@@ -1817,10 +1901,10 @@ static irqreturn_t ixgbe_intr(int irq, v
 	ixgbe_check_fan_failure(adapter, eicr);
 
 	if (napi_schedule_prep(&(q_vector->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;
+		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 */
 		__napi_schedule(&(q_vector->napi));
 	}
@@ -1905,6 +1989,8 @@ static inline void ixgbe_irq_disable(str
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFF0000);
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), ~0);
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0);
+		if (adapter->num_vfs > 32)
+			IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITRSEL, 0);
 	}
 	IXGBE_WRITE_FLUSH(&adapter->hw);
 	if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
@@ -1950,7 +2036,7 @@ static void ixgbe_configure_tx(struct ix
 
 	/* Setup the HW Tx Head and Tail descriptor pointers */
 	for (i = 0; i < adapter->num_tx_queues; i++) {
-		struct ixgbe_ring *ring = &adapter->tx_ring[i];
+		struct ixgbe_ring *ring = adapter->tx_ring[i];
 		j = ring->reg_idx;
 		tdba = ring->dma;
 		tdlen = ring->count * sizeof(union ixgbe_adv_tx_desc);
@@ -1960,8 +2046,8 @@ static void ixgbe_configure_tx(struct ix
 		IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j), tdlen);
 		IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0);
 		IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0);
-		adapter->tx_ring[i].head = IXGBE_TDH(j);
-		adapter->tx_ring[i].tail = IXGBE_TDT(j);
+		adapter->tx_ring[i]->head = IXGBE_TDH(j);
+		adapter->tx_ring[i]->tail = IXGBE_TDT(j);
 		/*
 		 * Disable Tx Head Writeback RO bit, since this hoses
 		 * bookkeeping if things aren't delivered in order.
@@ -1989,18 +2075,32 @@ static void ixgbe_configure_tx(struct ix
 
 	if (hw->mac.type == ixgbe_mac_82599EB) {
 		u32 rttdcs;
+		u32 mask;
 
 		/* disable the arbiter while setting MTQC */
 		rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
 		rttdcs |= IXGBE_RTTDCS_ARBDIS;
 		IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
 
-		/* 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));
-		else
+		/* set transmit pool layout */
+		mask = (IXGBE_FLAG_SRIOV_ENABLED | IXGBE_FLAG_DCB_ENABLED);
+		switch (adapter->flags & mask) {
+
+		case (IXGBE_FLAG_SRIOV_ENABLED):
+			IXGBE_WRITE_REG(hw, IXGBE_MTQC,
+					(IXGBE_MTQC_VT_ENA | IXGBE_MTQC_64VF));
+			break;
+
+		case (IXGBE_FLAG_DCB_ENABLED):
+			/* We enable 8 traffic classes, DCB only */
+			IXGBE_WRITE_REG(hw, IXGBE_MTQC,
+				      (IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ));
+			break;
+
+		default:
 			IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB);
+			break;
+		}
 
 		/* re-eable the arbiter */
 		rttdcs &= ~IXGBE_RTTDCS_ARBDIS;
@@ -2059,12 +2159,16 @@ static u32 ixgbe_setup_mrqc(struct ixgbe
 #ifdef CONFIG_IXGBE_DCB
 				 | IXGBE_FLAG_DCB_ENABLED
 #endif
+				 | IXGBE_FLAG_SRIOV_ENABLED
 				);
 
 	switch (mask) {
 	case (IXGBE_FLAG_RSS_ENABLED):
 		mrqc = IXGBE_MRQC_RSSEN;
 		break;
+	case (IXGBE_FLAG_SRIOV_ENABLED):
+		mrqc = IXGBE_MRQC_VMDQEN;
+		break;
 #ifdef CONFIG_IXGBE_DCB
 	case (IXGBE_FLAG_DCB_ENABLED):
 		mrqc = IXGBE_MRQC_RT8TCEN;
@@ -2090,7 +2194,7 @@ static void ixgbe_configure_rscctl(struc
 	u32 rscctrl;
 	int rx_buf_len;
 
-	rx_ring = &adapter->rx_ring[index];
+	rx_ring = adapter->rx_ring[index];
 	j = rx_ring->reg_idx;
 	rx_buf_len = rx_ring->rx_buf_len;
 	rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(j));
@@ -2145,7 +2249,9 @@ static void ixgbe_configure_rx(struct ix
 	int rx_buf_len;
 
 	/* Decide whether to use packet split mode or not */
-	adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
+	/* Do not use packet split if we're in SR-IOV Mode */
+	if (!adapter->num_vfs)
+		adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
 
 	/* Set the RX buffer length according to the mode */
 	if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
@@ -2157,7 +2263,9 @@ static void ixgbe_configure_rx(struct ix
 			              IXGBE_PSRTYPE_IPV4HDR |
 			              IXGBE_PSRTYPE_IPV6HDR |
 			              IXGBE_PSRTYPE_L2HDR;
-			IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype);
+			IXGBE_WRITE_REG(hw,
+					IXGBE_PSRTYPE(adapter->num_vfs),
+					psrtype);
 		}
 	} else {
 		if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) &&
@@ -2184,7 +2292,7 @@ static void ixgbe_configure_rx(struct ix
 #endif
 	IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
 
-	rdlen = adapter->rx_ring[0].count * sizeof(union ixgbe_adv_rx_desc);
+	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);
 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
@@ -2194,7 +2302,7 @@ static void ixgbe_configure_rx(struct ix
 	 * the Base and Length of the Rx Descriptor Ring
 	 */
 	for (i = 0; i < adapter->num_rx_queues; i++) {
-		rx_ring = &adapter->rx_ring[i];
+		rx_ring = adapter->rx_ring[i];
 		rdba = rx_ring->dma;
 		j = rx_ring->reg_idx;
 		IXGBE_WRITE_REG(hw, IXGBE_RDBAL(j), (rdba & DMA_BIT_MASK(32)));
@@ -2243,6 +2351,30 @@ static void ixgbe_configure_rx(struct ix
 		IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
 	}
 
+	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
+		u32 vt_reg_bits;
+		u32 reg_offset, vf_shift;
+		u32 vmdctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
+		vt_reg_bits = IXGBE_VMD_CTL_VMDQ_EN
+			| IXGBE_VT_CTL_REPLEN;
+		vt_reg_bits |= (adapter->num_vfs <<
+				IXGBE_VT_CTL_POOL_SHIFT);
+		IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl | vt_reg_bits);
+		IXGBE_WRITE_REG(hw, IXGBE_MRQC, 0);
+
+		vf_shift = adapter->num_vfs % 32;
+		reg_offset = adapter->num_vfs / 32;
+		IXGBE_WRITE_REG(hw, IXGBE_VFRE(0), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VFRE(1), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VFTE(0), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VFTE(1), 0);
+		/* Enable only the PF's pool for Tx/Rx */
+		IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), (1 << vf_shift));
+		IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), (1 << vf_shift));
+		IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
+		ixgbe_set_vmolr(hw, adapter->num_vfs);
+	}
+
 	/* Program MRQC for the distribution of queues */
 	mrqc = ixgbe_setup_mrqc(adapter);
 
@@ -2274,6 +2406,20 @@ static void ixgbe_configure_rx(struct ix
 	}
 	IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
 
+	if (adapter->num_vfs) {
+		u32 reg;
+
+		/* Map PF MAC address in RAR Entry 0 to first pool
+		 * following VFs */
+		hw->mac.ops.set_vmdq(hw, 0, adapter->num_vfs);
+
+		/* Set up VF register offsets for selected VT Mode, i.e.
+		 * 64 VFs for SR-IOV */
+		reg = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
+		reg |= IXGBE_GCR_EXT_SRIOV;
+		IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, reg);
+	}
+
 	rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
 
 	if (adapter->flags & IXGBE_FLAG_RSS_ENABLED ||
@@ -2312,15 +2458,17 @@ static void ixgbe_vlan_rx_add_vid(struct
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
+	int pool_ndx = adapter->num_vfs;
 
 	/* add VID to filter table */
-	hw->mac.ops.set_vfta(&adapter->hw, vid, 0, true);
+	hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, true);
 }
 
 static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
+	int pool_ndx = adapter->num_vfs;
 
 	if (!test_bit(__IXGBE_DOWN, &adapter->state))
 		ixgbe_irq_disable(adapter);
@@ -2331,7 +2479,7 @@ static void ixgbe_vlan_rx_kill_vid(struc
 		ixgbe_irq_enable(adapter);
 
 	/* remove VID from filter table */
-	hw->mac.ops.set_vfta(&adapter->hw, vid, 0, false);
+	hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, false);
 }
 
 static void ixgbe_vlan_rx_register(struct net_device *netdev,
@@ -2361,7 +2509,7 @@ static void ixgbe_vlan_rx_register(struc
 	} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
 		for (i = 0; i < adapter->num_rx_queues; i++) {
 			u32 ctrl;
-			j = adapter->rx_ring[i].reg_idx;
+			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);
@@ -2414,7 +2562,7 @@ static u8 *ixgbe_addr_list_itr(struct ix
  * responsible for configuring the hardware for proper unicast, multicast and
  * promiscuous mode.
  **/
-static void ixgbe_set_rx_mode(struct net_device *netdev)
+void ixgbe_set_rx_mode(struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
@@ -2446,14 +2594,16 @@ static void ixgbe_set_rx_mode(struct net
 	IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
 
 	/* reprogram secondary unicast list */
-	hw->mac.ops.update_uc_addr_list(hw, &netdev->uc.list);
+	hw->mac.ops.update_uc_addr_list(hw, netdev);
 
 	/* reprogram multicast list */
-	addr_count = netdev->mc_count;
+	addr_count = netdev_mc_count(netdev);
 	if (addr_count)
 		addr_list = netdev->mc_list->dmi_addr;
 	hw->mac.ops.update_mc_addr_list(hw, addr_list, addr_count,
 	                                ixgbe_addr_list_itr);
+	if (adapter->num_vfs)
+		ixgbe_restore_vf_multicasts(adapter);
 }
 
 static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
@@ -2522,7 +2672,7 @@ static void ixgbe_configure_dcb(struct i
 	ixgbe_dcb_hw_config(&adapter->hw, &adapter->dcb_cfg);
 
 	for (i = 0; i < adapter->num_tx_queues; i++) {
-		j = adapter->tx_ring[i].reg_idx;
+		j = adapter->tx_ring[i]->reg_idx;
 		txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
 		/* PThresh workaround for Tx hang with DFP enabled. */
 		txdctl |= 32;
@@ -2539,7 +2689,7 @@ static void ixgbe_configure_dcb(struct i
 		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;
+			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);
@@ -2579,7 +2729,7 @@ static void ixgbe_configure(struct ixgbe
 #endif /* IXGBE_FCOE */
 	if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) {
 		for (i = 0; i < adapter->num_tx_queues; i++)
-			adapter->tx_ring[i].atr_sample_rate =
+			adapter->tx_ring[i]->atr_sample_rate =
 			                               adapter->atr_sample_rate;
 		ixgbe_init_fdir_signature_82599(hw, adapter->fdir_pballoc);
 	} else if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) {
@@ -2589,8 +2739,8 @@ static void ixgbe_configure(struct ixgbe
 	ixgbe_configure_tx(adapter);
 	ixgbe_configure_rx(adapter);
 	for (i = 0; i < adapter->num_rx_queues; i++)
-		ixgbe_alloc_rx_buffers(adapter, &adapter->rx_ring[i],
-		                       (adapter->rx_ring[i].count - 1));
+		ixgbe_alloc_rx_buffers(adapter, adapter->rx_ring[i],
+		                       (adapter->rx_ring[i]->count - 1));
 }
 
 static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw)
@@ -2673,7 +2823,7 @@ link_cfg_out:
 static inline void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
 	                                      int rxr)
 {
-	int j = adapter->rx_ring[rxr].reg_idx;
+	int j = adapter->rx_ring[rxr]->reg_idx;
 	int k;
 
 	for (k = 0; k < IXGBE_MAX_RX_DESC_POLL; k++) {
@@ -2687,8 +2837,8 @@ static inline void ixgbe_rx_desc_queue_e
 		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));
+	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)
@@ -2702,6 +2852,7 @@ static int ixgbe_up_complete(struct ixgb
 	u32 txdctl, rxdctl, mhadd;
 	u32 dmatxctl;
 	u32 gpie;
+	u32 ctrl_ext;
 
 	ixgbe_get_hw_control(adapter);
 
@@ -2714,6 +2865,10 @@ static int ixgbe_up_complete(struct ixgb
 			/* MSI only */
 			gpie = 0;
 		}
+		if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
+			gpie &= ~IXGBE_GPIE_VTMODE_MASK;
+			gpie |= IXGBE_GPIE_VTMODE_64;
+		}
 		/* XXX: to interrupt immediately for EICS writes, enable this */
 		/* gpie |= IXGBE_GPIE_EIMEN; */
 		IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
@@ -2770,7 +2925,7 @@ static int ixgbe_up_complete(struct ixgb
 	}
 
 	for (i = 0; i < adapter->num_tx_queues; i++) {
-		j = adapter->tx_ring[i].reg_idx;
+		j = adapter->tx_ring[i]->reg_idx;
 		txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
 		/* enable WTHRESH=8 descriptors, to encourage burst writeback */
 		txdctl |= (8 << 16);
@@ -2784,14 +2939,26 @@ static int ixgbe_up_complete(struct ixgb
 		IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl);
 	}
 	for (i = 0; i < adapter->num_tx_queues; i++) {
-		j = adapter->tx_ring[i].reg_idx;
+		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);
+		if (hw->mac.type == ixgbe_mac_82599EB) {
+			int wait_loop = 10;
+			/* poll for Tx Enable ready */
+			do {
+				msleep(1);
+				txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
+			} while (--wait_loop &&
+			         !(txdctl & IXGBE_TXDCTL_ENABLE));
+			if (!wait_loop)
+				DPRINTK(DRV, ERR, "Could not enable "
+				        "Tx Queue %d\n", j);
+		}
 	}
 
 	for (i = 0; i < num_rx_rings; i++) {
-		j = adapter->rx_ring[i].reg_idx;
+		j = adapter->rx_ring[i]->reg_idx;
 		rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
 		/* enable PTHRESH=32 descriptors (half the internal cache)
 		 * and HTHRESH=0 descriptors (to minimize latency on fetch),
@@ -2815,6 +2982,10 @@ static int ixgbe_up_complete(struct ixgb
 	else
 		ixgbe_configure_msi_and_legacy(adapter);
 
+	/* enable the optics */
+	if (hw->phy.multispeed_fiber)
+		hw->mac.ops.enable_tx_laser(hw);
+
 	clear_bit(__IXGBE_DOWN, &adapter->state);
 	ixgbe_napi_enable_all(adapter);
 
@@ -2865,7 +3036,7 @@ static int ixgbe_up_complete(struct ixgb
 
 	for (i = 0; i < adapter->num_tx_queues; i++)
 		set_bit(__IXGBE_FDIR_INIT_DONE,
-		        &(adapter->tx_ring[i].reinit_state));
+		        &(adapter->tx_ring[i]->reinit_state));
 
 	/* enable transmits */
 	netif_tx_start_all_queues(netdev);
@@ -2875,6 +3046,12 @@ static int ixgbe_up_complete(struct ixgb
 	adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
 	adapter->link_check_timeout = jiffies;
 	mod_timer(&adapter->watchdog_timer, jiffies);
+
+	/* Set 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);
+
 	return 0;
 }
 
@@ -2884,6 +3061,14 @@ void ixgbe_reinit_locked(struct ixgbe_ad
 	while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
 		msleep(1);
 	ixgbe_down(adapter);
+	/*
+	 * If SR-IOV enabled then wait a bit before bringing the adapter
+	 * back up to give the VFs time to respond to the reset.  The
+	 * two second wait is based upon the watchdog timer cycle in
+	 * the VF driver.
+	 */
+	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
+		msleep(2000);
 	ixgbe_up(adapter);
 	clear_bit(__IXGBE_RESETTING, &adapter->state);
 }
@@ -2923,7 +3108,8 @@ void ixgbe_reset(struct ixgbe_adapter *a
 	}
 
 	/* reprogram the RAR[0] in case user changed it. */
-	hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
+	hw->mac.ops.set_rar(hw, 0, hw->mac.addr, adapter->num_vfs,
+			    IXGBE_RAH_AV);
 }
 
 /**
@@ -2955,6 +3141,12 @@ static void ixgbe_clean_rx_ring(struct i
 			rx_buffer_info->skb = NULL;
 			do {
 				struct sk_buff *this = skb;
+				if (IXGBE_RSC_CB(this)->dma) {
+					pci_unmap_single(pdev, IXGBE_RSC_CB(this)->dma,
+					                 rx_ring->rx_buf_len,
+					                 PCI_DMA_FROMDEVICE);
+					IXGBE_RSC_CB(this)->dma = 0;
+				}
 				skb = skb->prev;
 				dev_kfree_skb(this);
 			} while (skb);
@@ -3029,7 +3221,7 @@ static void ixgbe_clean_all_rx_rings(str
 	int i;
 
 	for (i = 0; i < adapter->num_rx_queues; i++)
-		ixgbe_clean_rx_ring(adapter, &adapter->rx_ring[i]);
+		ixgbe_clean_rx_ring(adapter, adapter->rx_ring[i]);
 }
 
 /**
@@ -3041,7 +3233,7 @@ static void ixgbe_clean_all_tx_rings(str
 	int i;
 
 	for (i = 0; i < adapter->num_tx_queues; i++)
-		ixgbe_clean_tx_ring(adapter, &adapter->tx_ring[i]);
+		ixgbe_clean_tx_ring(adapter, adapter->tx_ring[i]);
 }
 
 void ixgbe_down(struct ixgbe_adapter *adapter)
@@ -3055,6 +3247,23 @@ void ixgbe_down(struct ixgbe_adapter *ad
 	/* signal that we are down to the interrupt handler */
 	set_bit(__IXGBE_DOWN, &adapter->state);
 
+	/* power down the optics */
+	if (hw->phy.multispeed_fiber)
+		hw->mac.ops.disable_tx_laser(hw);
+
+	/* disable receive for all VFs and wait one second */
+	if (adapter->num_vfs) {
+		/* ping all the active vfs to let them know we are going down */
+		ixgbe_ping_all_vfs(adapter);
+
+		/* Disable all VFTE/VFRE TX/RX */
+		ixgbe_disable_tx_rx(adapter);
+
+		/* Mark all the VFs as inactive */
+		for (i = 0 ; i < adapter->num_vfs; i++)
+			adapter->vfinfo[i].clear_to_send = 0;
+	}
+
 	/* disable receives */
 	rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
@@ -3081,7 +3290,7 @@ void ixgbe_down(struct ixgbe_adapter *ad
 
 	/* disable transmits in the hardware now that interrupts are off */
 	for (i = 0; i < adapter->num_tx_queues; i++) {
-		j = adapter->tx_ring[i].reg_idx;
+		j = adapter->tx_ring[i]->reg_idx;
 		txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
 		IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j),
 		                (txdctl & ~IXGBE_TXDCTL_ENABLE));
@@ -3094,6 +3303,9 @@ void ixgbe_down(struct ixgbe_adapter *ad
 
 	netif_carrier_off(netdev);
 
+	/* clear n-tuple filters that are cached */
+	ethtool_ntuple_flush(netdev);
+
 	if (!pci_channel_offline(adapter->pdev))
 		ixgbe_reset(adapter);
 	ixgbe_clean_all_tx_rings(adapter);
@@ -3121,13 +3333,13 @@ static int ixgbe_poll(struct napi_struct
 
 #ifdef CONFIG_IXGBE_DCA
 	if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
-		ixgbe_update_tx_dca(adapter, adapter->tx_ring);
-		ixgbe_update_rx_dca(adapter, adapter->rx_ring);
+		ixgbe_update_tx_dca(adapter, adapter->tx_ring[0]);
+		ixgbe_update_rx_dca(adapter, adapter->rx_ring[0]);
 	}
 #endif
 
-	tx_clean_complete = ixgbe_clean_tx_irq(q_vector, adapter->tx_ring);
-	ixgbe_clean_rx_irq(q_vector, adapter->rx_ring, &work_done, budget);
+	tx_clean_complete = ixgbe_clean_tx_irq(q_vector, adapter->tx_ring[0]);
+	ixgbe_clean_rx_irq(q_vector, adapter->rx_ring[0], &work_done, budget);
 
 	if (!tx_clean_complete)
 		work_done = budget;
@@ -3291,6 +3503,19 @@ static inline bool ixgbe_set_fcoe_queues
 }
 
 #endif /* IXGBE_FCOE */
+/**
+ * ixgbe_set_sriov_queues: Allocate queues for IOV use
+ * @adapter: board private structure to initialize
+ *
+ * IOV doesn't actually use anything, so just NAK the
+ * request for now and let the other queue routines
+ * figure out what to do.
+ */
+static inline bool ixgbe_set_sriov_queues(struct ixgbe_adapter *adapter)
+{
+	return false;
+}
+
 /*
  * ixgbe_set_num_queues: Allocate queues for device, feature dependant
  * @adapter: board private structure to initialize
@@ -3304,6 +3529,15 @@ static inline bool ixgbe_set_fcoe_queues
  **/
 static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
 {
+	/* Start with base case */
+	adapter->num_rx_queues = 1;
+	adapter->num_tx_queues = 1;
+	adapter->num_rx_pools = adapter->num_rx_queues;
+	adapter->num_rx_queues_per_pool = 1;
+
+	if (ixgbe_set_sriov_queues(adapter))
+		return;
+
 #ifdef IXGBE_FCOE
 	if (ixgbe_set_fcoe_queues(adapter))
 		goto done;
@@ -3393,9 +3627,9 @@ static inline bool ixgbe_cache_ring_rss(
 
 	if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
 		for (i = 0; i < adapter->num_rx_queues; i++)
-			adapter->rx_ring[i].reg_idx = i;
+			adapter->rx_ring[i]->reg_idx = i;
 		for (i = 0; i < adapter->num_tx_queues; i++)
-			adapter->tx_ring[i].reg_idx = i;
+			adapter->tx_ring[i]->reg_idx = i;
 		ret = true;
 	} else {
 		ret = false;
@@ -3422,8 +3656,8 @@ static inline bool ixgbe_cache_ring_dcb(
 		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;
+				adapter->rx_ring[i]->reg_idx = i << 3;
+				adapter->tx_ring[i]->reg_idx = i << 2;
 			}
 			ret = true;
 		} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
@@ -3441,18 +3675,18 @@ static inline bool ixgbe_cache_ring_dcb(
 				 * 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;
+					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 =
+					adapter->tx_ring[i]->reg_idx =
 					                         ((i + 2) << 4);
-					adapter->rx_ring[i].reg_idx = i << 4;
+					adapter->rx_ring[i]->reg_idx = i << 4;
 				}
 				for ( ; i < dcb_i; i++) {
-					adapter->tx_ring[i].reg_idx =
+					adapter->tx_ring[i]->reg_idx =
 					                         ((i + 8) << 3);
-					adapter->rx_ring[i].reg_idx = i << 4;
+					adapter->rx_ring[i]->reg_idx = i << 4;
 				}
 
 				ret = true;
@@ -3465,12 +3699,12 @@ static inline bool ixgbe_cache_ring_dcb(
 				 *
 				 * 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;
+				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;
+					adapter->rx_ring[i]->reg_idx = i << 5;
 
 				ret = true;
 			} else {
@@ -3503,9 +3737,9 @@ static bool inline ixgbe_cache_ring_fdir
 	    ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) ||
 	     (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE))) {
 		for (i = 0; i < adapter->num_rx_queues; i++)
-			adapter->rx_ring[i].reg_idx = i;
+			adapter->rx_ring[i]->reg_idx = i;
 		for (i = 0; i < adapter->num_tx_queues; i++)
-			adapter->tx_ring[i].reg_idx = i;
+			adapter->tx_ring[i]->reg_idx = i;
 		ret = true;
 	}
 
@@ -3533,8 +3767,8 @@ static inline bool ixgbe_cache_ring_fcoe
 
 			ixgbe_cache_ring_dcb(adapter);
 			/* find out queues in TC for FCoE */
-			fcoe_rx_i = adapter->rx_ring[fcoe->tc].reg_idx + 1;
-			fcoe_tx_i = adapter->tx_ring[fcoe->tc].reg_idx + 1;
+			fcoe_rx_i = adapter->rx_ring[fcoe->tc]->reg_idx + 1;
+			fcoe_tx_i = adapter->tx_ring[fcoe->tc]->reg_idx + 1;
 			/*
 			 * In 82599, the number of Tx queues for each traffic
 			 * class for both 8-TC and 4-TC modes are:
@@ -3565,8 +3799,8 @@ static inline bool ixgbe_cache_ring_fcoe
 			fcoe_tx_i = f->mask;
 		}
 		for (i = 0; i < f->indices; i++, fcoe_rx_i++, fcoe_tx_i++) {
-			adapter->rx_ring[f->mask + i].reg_idx = fcoe_rx_i;
-			adapter->tx_ring[f->mask + i].reg_idx = fcoe_tx_i;
+			adapter->rx_ring[f->mask + i]->reg_idx = fcoe_rx_i;
+			adapter->tx_ring[f->mask + i]->reg_idx = fcoe_tx_i;
 		}
 		ret = true;
 	}
@@ -3575,6 +3809,24 @@ static inline bool ixgbe_cache_ring_fcoe
 
 #endif /* IXGBE_FCOE */
 /**
+ * ixgbe_cache_ring_sriov - Descriptor ring to register mapping for sriov
+ * @adapter: board private structure to initialize
+ *
+ * SR-IOV doesn't use any descriptor rings but changes the default if
+ * no other mapping is used.
+ *
+ */
+static inline bool ixgbe_cache_ring_sriov(struct ixgbe_adapter *adapter)
+{
+	adapter->rx_ring[0]->reg_idx = adapter->num_vfs * 2;
+	adapter->tx_ring[0]->reg_idx = adapter->num_vfs * 2;
+	if (adapter->num_vfs)
+		return true;
+	else
+		return false;
+}
+
+/**
  * ixgbe_cache_ring_register - Descriptor ring to register mapping
  * @adapter: board private structure to initialize
  *
@@ -3588,8 +3840,11 @@ static inline bool ixgbe_cache_ring_fcoe
 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;
+	adapter->rx_ring[0]->reg_idx = 0;
+	adapter->tx_ring[0]->reg_idx = 0;
+
+	if (ixgbe_cache_ring_sriov(adapter))
+		return;
 
 #ifdef IXGBE_FCOE
 	if (ixgbe_cache_ring_fcoe(adapter))
@@ -3619,33 +3874,63 @@ static void ixgbe_cache_ring_register(st
 static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
 {
 	int i;
-
-	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
-	                           sizeof(struct ixgbe_ring), GFP_KERNEL);
-	if (!adapter->tx_ring)
-		goto err_tx_ring_allocation;
-
-	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
-	                           sizeof(struct ixgbe_ring), GFP_KERNEL);
-	if (!adapter->rx_ring)
-		goto err_rx_ring_allocation;
+	int orig_node = adapter->node;
 
 	for (i = 0; i < adapter->num_tx_queues; i++) {
-		adapter->tx_ring[i].count = adapter->tx_ring_count;
-		adapter->tx_ring[i].queue_index = i;
+		struct ixgbe_ring *ring = adapter->tx_ring[i];
+		if (orig_node == -1) {
+			int cur_node = next_online_node(adapter->node);
+			if (cur_node == MAX_NUMNODES)
+				cur_node = first_online_node;
+			adapter->node = cur_node;
+		}
+		ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL,
+		                    adapter->node);
+		if (!ring)
+			ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL);
+		if (!ring)
+			goto err_tx_ring_allocation;
+		ring->count = adapter->tx_ring_count;
+		ring->queue_index = i;
+		ring->numa_node = adapter->node;
+
+		adapter->tx_ring[i] = ring;
 	}
 
+	/* Restore the adapter's original node */
+	adapter->node = orig_node;
+
 	for (i = 0; i < adapter->num_rx_queues; i++) {
-		adapter->rx_ring[i].count = adapter->rx_ring_count;
-		adapter->rx_ring[i].queue_index = i;
+		struct ixgbe_ring *ring = adapter->rx_ring[i];
+		if (orig_node == -1) {
+			int cur_node = next_online_node(adapter->node);
+			if (cur_node == MAX_NUMNODES)
+				cur_node = first_online_node;
+			adapter->node = cur_node;
+		}
+		ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL,
+		                    adapter->node);
+		if (!ring)
+			ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL);
+		if (!ring)
+			goto err_rx_ring_allocation;
+		ring->count = adapter->rx_ring_count;
+		ring->queue_index = i;
+		ring->numa_node = adapter->node;
+
+		adapter->rx_ring[i] = ring;
 	}
 
+	/* Restore the adapter's original node */
+	adapter->node = orig_node;
+
 	ixgbe_cache_ring_register(adapter);
 
 	return 0;
 
 err_rx_ring_allocation:
-	kfree(adapter->tx_ring);
+	for (i = 0; i < adapter->num_tx_queues; i++)
+		kfree(adapter->tx_ring[i]);
 err_tx_ring_allocation:
 	return -ENOMEM;
 }
@@ -3700,6 +3985,9 @@ static int ixgbe_set_interrupt_capabilit
 	adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
 	adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
 	adapter->atr_sample_rate = 0;
+	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
+		ixgbe_disable_sriov(adapter);
+
 	ixgbe_set_num_queues(adapter);
 
 	err = pci_enable_msi(adapter->pdev);
@@ -3741,7 +4029,11 @@ static int ixgbe_alloc_q_vectors(struct
 	}
 
 	for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
-		q_vector = kzalloc(sizeof(struct ixgbe_q_vector), GFP_KERNEL);
+		q_vector = kzalloc_node(sizeof(struct ixgbe_q_vector),
+		                        GFP_KERNEL, adapter->node);
+		if (!q_vector)
+			q_vector = kzalloc(sizeof(struct ixgbe_q_vector),
+			                   GFP_KERNEL);
 		if (!q_vector)
 			goto err_out;
 		q_vector->adapter = adapter;
@@ -3868,10 +4160,16 @@ err_set_interrupt:
  **/
 void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
 {
-	kfree(adapter->tx_ring);
-	kfree(adapter->rx_ring);
-	adapter->tx_ring = NULL;
-	adapter->rx_ring = NULL;
+	int i;
+
+	for (i = 0; i < adapter->num_tx_queues; i++) {
+		kfree(adapter->tx_ring[i]);
+		adapter->tx_ring[i] = NULL;
+	}
+	for (i = 0; i < adapter->num_rx_queues; i++) {
+		kfree(adapter->rx_ring[i]);
+		adapter->rx_ring[i] = NULL;
+	}
 
 	ixgbe_free_q_vectors(adapter);
 	ixgbe_reset_interrupt_capability(adapter);
@@ -3942,6 +4240,7 @@ static int __devinit ixgbe_sw_init(struc
 {
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct pci_dev *pdev = adapter->pdev;
+	struct net_device *dev = adapter->netdev;
 	unsigned int rss;
 #ifdef CONFIG_IXGBE_DCB
 	int j;
@@ -3969,10 +4268,18 @@ static int __devinit ixgbe_sw_init(struc
 		adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599;
 		adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE;
 		adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED;
-		adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
+		if (dev->features & NETIF_F_NTUPLE) {
+			/* Flow Director perfect filter enabled */
+			adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
+			adapter->atr_sample_rate = 0;
+			spin_lock_init(&adapter->fdir_perfect_lock);
+		} else {
+			/* Flow Director hash filters enabled */
+			adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
+			adapter->atr_sample_rate = 20;
+		}
 		adapter->ring_feature[RING_F_FDIR].indices =
 		                                         IXGBE_MAX_FDIR_INDICES;
-		adapter->atr_sample_rate = 20;
 		adapter->fdir_pballoc = 0;
 #ifdef IXGBE_FCOE
 		adapter->flags |= IXGBE_FLAG_FCOE_CAPABLE;
@@ -4041,6 +4348,9 @@ static int __devinit ixgbe_sw_init(struc
 	/* enable rx csum by default */
 	adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
 
+	/* get assigned NUMA node */
+	adapter->node = dev_to_node(&pdev->dev);
+
 	set_bit(__IXGBE_DOWN, &adapter->state);
 
 	return 0;
@@ -4060,7 +4370,9 @@ int ixgbe_setup_tx_resources(struct ixgb
 	int size;
 
 	size = sizeof(struct ixgbe_tx_buffer) * tx_ring->count;
-	tx_ring->tx_buffer_info = vmalloc(size);
+	tx_ring->tx_buffer_info = vmalloc_node(size, tx_ring->numa_node);
+	if (!tx_ring->tx_buffer_info)
+		tx_ring->tx_buffer_info = vmalloc(size);
 	if (!tx_ring->tx_buffer_info)
 		goto err;
 	memset(tx_ring->tx_buffer_info, 0, size);
@@ -4102,7 +4414,7 @@ static int ixgbe_setup_all_tx_resources(
 	int i, err = 0;
 
 	for (i = 0; i < adapter->num_tx_queues; i++) {
-		err = ixgbe_setup_tx_resources(adapter, &adapter->tx_ring[i]);
+		err = ixgbe_setup_tx_resources(adapter, adapter->tx_ring[i]);
 		if (!err)
 			continue;
 		DPRINTK(PROBE, ERR, "Allocation for Tx Queue %u failed\n", i);
@@ -4126,7 +4438,9 @@ int ixgbe_setup_rx_resources(struct ixgb
 	int size;
 
 	size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count;
-	rx_ring->rx_buffer_info = vmalloc(size);
+	rx_ring->rx_buffer_info = vmalloc_node(size, adapter->node);
+	if (!rx_ring->rx_buffer_info)
+		rx_ring->rx_buffer_info = vmalloc(size);
 	if (!rx_ring->rx_buffer_info) {
 		DPRINTK(PROBE, ERR,
 		        "vmalloc allocation failed for the rx desc ring\n");
@@ -4172,7 +4486,7 @@ static int ixgbe_setup_all_rx_resources(
 	int i, err = 0;
 
 	for (i = 0; i < adapter->num_rx_queues; i++) {
-		err = ixgbe_setup_rx_resources(adapter, &adapter->rx_ring[i]);
+		err = ixgbe_setup_rx_resources(adapter, adapter->rx_ring[i]);
 		if (!err)
 			continue;
 		DPRINTK(PROBE, ERR, "Allocation for Rx Queue %u failed\n", i);
@@ -4215,8 +4529,8 @@ static void ixgbe_free_all_tx_resources(
 	int i;
 
 	for (i = 0; i < adapter->num_tx_queues; i++)
-		if (adapter->tx_ring[i].desc)
-			ixgbe_free_tx_resources(adapter, &adapter->tx_ring[i]);
+		if (adapter->tx_ring[i]->desc)
+			ixgbe_free_tx_resources(adapter, adapter->tx_ring[i]);
 }
 
 /**
@@ -4252,8 +4566,8 @@ static void ixgbe_free_all_rx_resources(
 	int i;
 
 	for (i = 0; i < adapter->num_rx_queues; i++)
-		if (adapter->rx_ring[i].desc)
-			ixgbe_free_rx_resources(adapter, &adapter->rx_ring[i]);
+		if (adapter->rx_ring[i]->desc)
+			ixgbe_free_rx_resources(adapter, adapter->rx_ring[i]);
 }
 
 /**
@@ -4530,8 +4844,8 @@ void ixgbe_update_stats(struct ixgbe_ada
 			adapter->hw_rx_no_dma_resources +=
 			                     IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
 		for (i = 0; i < adapter->num_rx_queues; i++) {
-			rsc_count += adapter->rx_ring[i].rsc_count;
-			rsc_flush += adapter->rx_ring[i].rsc_flush;
+			rsc_count += adapter->rx_ring[i]->rsc_count;
+			rsc_flush += adapter->rx_ring[i]->rsc_flush;
 		}
 		adapter->rsc_total_count = rsc_count;
 		adapter->rsc_total_flush = rsc_flush;
@@ -4539,11 +4853,11 @@ void ixgbe_update_stats(struct ixgbe_ada
 
 	/* gather some stats to the adapter struct that are per queue */
 	for (i = 0; i < adapter->num_tx_queues; i++)
-		restart_queue += adapter->tx_ring[i].restart_queue;
+		restart_queue += adapter->tx_ring[i]->restart_queue;
 	adapter->restart_queue = restart_queue;
 
 	for (i = 0; i < adapter->num_rx_queues; i++)
-		non_eop_descs += adapter->rx_ring[i].non_eop_descs;
+		non_eop_descs += adapter->rx_ring[i]->non_eop_descs;
 	adapter->non_eop_descs = non_eop_descs;
 
 	adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
@@ -4727,6 +5041,7 @@ static void ixgbe_multispeed_fiber_task(
 	autoneg = hw->phy.autoneg_advertised;
 	if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
 		hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation);
+	hw->mac.autotry_restart = false;
 	if (hw->mac.ops.setup_link)
 		hw->mac.ops.setup_link(hw, autoneg, negotiation, true);
 	adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -4782,7 +5097,7 @@ static void ixgbe_fdir_reinit_task(struc
 	if (ixgbe_reinit_fdir_tables_82599(hw) == 0) {
 		for (i = 0; i < adapter->num_tx_queues; i++)
 			set_bit(__IXGBE_FDIR_INIT_DONE,
-			        &(adapter->tx_ring[i].reinit_state));
+			        &(adapter->tx_ring[i]->reinit_state));
 	} else {
 		DPRINTK(PROBE, ERR, "failed to finish FDIR re-initialization, "
 		        "ignored adding FDIR ATR filters \n");
@@ -4791,6 +5106,8 @@ static void ixgbe_fdir_reinit_task(struc
 	netif_tx_start_all_queues(adapter->netdev);
 }
 
+static DEFINE_MUTEX(ixgbe_watchdog_lock);
+
 /**
  * ixgbe_watchdog_task - worker thread to bring link up
  * @work: pointer to work_struct containing our data
@@ -4802,13 +5119,16 @@ static void ixgbe_watchdog_task(struct w
 	                                             watchdog_task);
 	struct net_device *netdev = adapter->netdev;
 	struct ixgbe_hw *hw = &adapter->hw;
-	u32 link_speed = adapter->link_speed;
-	bool link_up = adapter->link_up;
+	u32 link_speed;
+	bool link_up;
 	int i;
 	struct ixgbe_ring *tx_ring;
 	int some_tx_pending = 0;
 
-	adapter->flags |= IXGBE_FLAG_IN_WATCHDOG_TASK;
+	mutex_lock(&ixgbe_watchdog_lock);
+
+	link_up = adapter->link_up;
+	link_speed = adapter->link_speed;
 
 	if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) {
 		hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
@@ -4879,7 +5199,7 @@ static void ixgbe_watchdog_task(struct w
 
 	if (!netif_carrier_ok(netdev)) {
 		for (i = 0; i < adapter->num_tx_queues; i++) {
-			tx_ring = &adapter->tx_ring[i];
+			tx_ring = adapter->tx_ring[i];
 			if (tx_ring->next_to_use != tx_ring->next_to_clean) {
 				some_tx_pending = 1;
 				break;
@@ -4897,7 +5217,7 @@ static void ixgbe_watchdog_task(struct w
 	}
 
 	ixgbe_update_stats(adapter);
-	adapter->flags &= ~IXGBE_FLAG_IN_WATCHDOG_TASK;
+	mutex_unlock(&ixgbe_watchdog_lock);
 }
 
 static int ixgbe_tso(struct ixgbe_adapter *adapter,
@@ -5337,14 +5657,21 @@ static u16 ixgbe_select_queue(struct net
 
 #ifdef IXGBE_FCOE
 	if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
-	    (skb->protocol == htons(ETH_P_FCOE))) {
+	    ((skb->protocol == htons(ETH_P_FCOE)) ||
+	     (skb->protocol == htons(ETH_P_FIP)))) {
 		txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1);
 		txq += adapter->ring_feature[RING_F_FCOE].mask;
 		return txq;
 	}
 #endif
-	if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
-		return (skb->vlan_tci & IXGBE_TX_FLAGS_VLAN_PRIO_MASK) >> 13;
+	if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+		if (skb->priority == TC_PRIO_CONTROL)
+			txq = adapter->ring_feature[RING_F_DCB].indices-1;
+		else
+			txq = (skb->vlan_tci & IXGBE_TX_FLAGS_VLAN_PRIO_MASK)
+			       >> 13;
+		return txq;
+	}
 
 	return skb_tx_hash(dev, skb);
 }
@@ -5371,30 +5698,32 @@ static netdev_tx_t ixgbe_xmit_frame(stru
 		tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
 		tx_flags |= IXGBE_TX_FLAGS_VLAN;
 	} else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
-		if (skb->priority != TC_PRIO_CONTROL) {
-			tx_flags |= ((skb->queue_mapping & 0x7) << 13);
-			tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
-			tx_flags |= IXGBE_TX_FLAGS_VLAN;
-		} else {
-			skb->queue_mapping =
-				adapter->ring_feature[RING_F_DCB].indices-1;
-		}
+		tx_flags |= ((skb->queue_mapping & 0x7) << 13);
+		tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
+		tx_flags |= IXGBE_TX_FLAGS_VLAN;
 	}
 
-	tx_ring = &adapter->tx_ring[skb->queue_mapping];
+	tx_ring = adapter->tx_ring[skb->queue_mapping];
 
-	if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
-	    (skb->protocol == htons(ETH_P_FCOE))) {
-		tx_flags |= IXGBE_TX_FLAGS_FCOE;
 #ifdef IXGBE_FCOE
+	if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
 #ifdef CONFIG_IXGBE_DCB
-		tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK
-			      << IXGBE_TX_FLAGS_VLAN_SHIFT);
-		tx_flags |= ((adapter->fcoe.up << 13)
-			      << IXGBE_TX_FLAGS_VLAN_SHIFT);
-#endif
+		/* for FCoE with DCB, we force the priority to what
+		 * was specified by the switch */
+		if ((skb->protocol == htons(ETH_P_FCOE)) ||
+		    (skb->protocol == htons(ETH_P_FIP))) {
+			tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK
+				      << IXGBE_TX_FLAGS_VLAN_SHIFT);
+			tx_flags |= ((adapter->fcoe.up << 13)
+				     << IXGBE_TX_FLAGS_VLAN_SHIFT);
+		}
 #endif
+		/* flag for FCoE offloads */
+		if (skb->protocol == htons(ETH_P_FCOE))
+			tx_flags |= IXGBE_TX_FLAGS_FCOE;
 	}
+#endif
+
 	/* four things can cause us to need a context descriptor */
 	if (skb_is_gso(skb) ||
 	    (skb->ip_summed == CHECKSUM_PARTIAL) ||
@@ -5487,7 +5816,8 @@ static int ixgbe_set_mac(struct net_devi
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 	memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
 
-	hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
+	hw->mac.ops.set_rar(hw, 0, hw->mac.addr, adapter->num_vfs,
+			    IXGBE_RAH_AV);
 
 	return 0;
 }
@@ -5624,6 +5954,61 @@ static const struct net_device_ops ixgbe
 #endif /* IXGBE_FCOE */
 };
 
+static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
+			   const struct ixgbe_info *ii)
+{
+#ifdef CONFIG_PCI_IOV
+	struct ixgbe_hw *hw = &adapter->hw;
+	int err;
+
+	if (hw->mac.type != ixgbe_mac_82599EB || !max_vfs)
+		return;
+
+	/* The 82599 supports up to 64 VFs per physical function
+	 * but this implementation limits allocation to 63 so that
+	 * basic networking resources are still available to the
+	 * physical function
+	 */
+	adapter->num_vfs = (max_vfs > 63) ? 63 : max_vfs;
+	adapter->flags |= IXGBE_FLAG_SRIOV_ENABLED;
+	err = pci_enable_sriov(adapter->pdev, adapter->num_vfs);
+	if (err) {
+		DPRINTK(PROBE, ERR,
+			"Failed to enable PCI sriov: %d\n", err);
+		goto err_novfs;
+	}
+	/* If call to enable VFs succeeded then allocate memory
+	 * for per VF control structures.
+	 */
+	adapter->vfinfo =
+		kcalloc(adapter->num_vfs,
+			sizeof(struct vf_data_storage), GFP_KERNEL);
+	if (adapter->vfinfo) {
+		/* Now that we're sure SR-IOV is enabled
+		 * and memory allocated set up the mailbox parameters
+		 */
+		ixgbe_init_mbx_params_pf(hw);
+		memcpy(&hw->mbx.ops, ii->mbx_ops,
+		       sizeof(hw->mbx.ops));
+
+		/* Disable RSC when in SR-IOV mode */
+		adapter->flags2 &= ~(IXGBE_FLAG2_RSC_CAPABLE |
+				     IXGBE_FLAG2_RSC_ENABLED);
+		return;
+	}
+
+	/* Oh oh */
+	DPRINTK(PROBE, ERR,
+		"Unable to allocate memory for VF "
+		"Data Storage - SRIOV disabled\n");
+	pci_disable_sriov(adapter->pdev);
+
+err_novfs:
+	adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
+	adapter->num_vfs = 0;
+#endif /* CONFIG_PCI_IOV */
+}
+
 /**
  * ixgbe_probe - Device Initialization Routine
  * @pdev: PCI device information struct
@@ -5644,6 +6029,7 @@ 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;
+	unsigned int indices = num_possible_cpus();
 #ifdef IXGBE_FCOE
 	u16 device_caps;
 #endif
@@ -5682,7 +6068,17 @@ static int __devinit ixgbe_probe(struct
 	pci_set_master(pdev);
 	pci_save_state(pdev);
 
-	netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), MAX_TX_QUEUES);
+	if (ii->mac == ixgbe_mac_82598EB)
+		indices = min_t(unsigned int, indices, IXGBE_MAX_RSS_INDICES);
+	else
+		indices = min_t(unsigned int, indices, IXGBE_MAX_FDIR_INDICES);
+
+	indices = max_t(unsigned int, indices, IXGBE_MAX_DCB_INDICES);
+#ifdef IXGBE_FCOE
+	indices += min_t(unsigned int, num_possible_cpus(),
+			 IXGBE_MAX_FCOE_INDICES);
+#endif
+	netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices);
 	if (!netdev) {
 		err = -ENOMEM;
 		goto err_alloc_etherdev;
@@ -5802,6 +6198,8 @@ static int __devinit ixgbe_probe(struct
 		goto err_sw_init;
 	}
 
+	ixgbe_probe_vf(adapter, ii);
+
 	netdev->features = NETIF_F_SG |
 	                   NETIF_F_IP_CSUM |
 	                   NETIF_F_HW_VLAN_TX |
@@ -5822,6 +6220,9 @@ static int __devinit ixgbe_probe(struct
 	netdev->vlan_features |= NETIF_F_IPV6_CSUM;
 	netdev->vlan_features |= NETIF_F_SG;
 
+	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
+		adapter->flags &= ~(IXGBE_FLAG_RSS_ENABLED |
+				    IXGBE_FLAG_DCB_ENABLED);
 	if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
 		adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
 
@@ -5860,6 +6261,10 @@ static int __devinit ixgbe_probe(struct
 		goto err_eeprom;
 	}
 
+	/* power down the optics */
+	if (hw->phy.multispeed_fiber)
+		hw->mac.ops.disable_tx_laser(hw);
+
 	init_timer(&adapter->watchdog_timer);
 	adapter->watchdog_timer.function = &ixgbe_watchdog;
 	adapter->watchdog_timer.data = (unsigned long)adapter;
@@ -5875,9 +6280,6 @@ static int __devinit ixgbe_probe(struct
 	case IXGBE_DEV_ID_82599_KX4:
 		adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX |
 		                IXGBE_WUFC_MC | IXGBE_WUFC_BC);
-		/* Enable ACPI wakeup in GRC */
-		IXGBE_WRITE_REG(hw, IXGBE_GRC,
-		             (IXGBE_READ_REG(hw, IXGBE_GRC) & ~IXGBE_GRC_APME));
 		break;
 	default:
 		adapter->wol = 0;
@@ -5948,6 +6350,13 @@ static int __devinit ixgbe_probe(struct
 		ixgbe_setup_dca(adapter);
 	}
 #endif
+	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
+		DPRINTK(PROBE, INFO, "IOV is enabled with %d VFs\n",
+			adapter->num_vfs);
+		for (i = 0; i < adapter->num_vfs; i++)
+			ixgbe_vf_configuration(pdev, (i | 0x10000000));
+	}
+
 	/* add san mac addr to netdev */
 	ixgbe_add_sanmac_netdev(netdev);
 
@@ -5960,6 +6369,8 @@ err_register:
 	ixgbe_clear_interrupt_scheme(adapter);
 err_sw_init:
 err_eeprom:
+	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
+		ixgbe_disable_sriov(adapter);
 	clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
 	del_timer_sync(&adapter->sfp_timer);
 	cancel_work_sync(&adapter->sfp_task);
@@ -6028,6 +6439,9 @@ static void __devexit ixgbe_remove(struc
 	if (netdev->reg_state == NETREG_REGISTERED)
 		unregister_netdev(netdev);
 
+	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
+		ixgbe_disable_sriov(adapter);
+
 	ixgbe_clear_interrupt_scheme(adapter);
 
 	ixgbe_release_hw_control(adapter);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_mbx.c linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_mbx.c
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_mbx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_mbx.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,479 @@
+/*******************************************************************************
+
+  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 "ixgbe_type.h"
+#include "ixgbe_common.h"
+#include "ixgbe_mbx.h"
+
+/**
+ *  ixgbe_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 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = IXGBE_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;
+}
+
+/**
+ *  ixgbe_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 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = 0;
+
+	if (size > mbx->size)
+		ret_val = IXGBE_ERR_MBX;
+
+	else if (mbx->ops.write)
+		ret_val = mbx->ops.write(hw, msg, size, mbx_id);
+
+	return ret_val;
+}
+
+/**
+ *  ixgbe_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 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = IXGBE_ERR_MBX;
+
+	if (mbx->ops.check_for_msg)
+		ret_val = mbx->ops.check_for_msg(hw, mbx_id);
+
+	return ret_val;
+}
+
+/**
+ *  ixgbe_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 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = IXGBE_ERR_MBX;
+
+	if (mbx->ops.check_for_ack)
+		ret_val = mbx->ops.check_for_ack(hw, mbx_id);
+
+	return ret_val;
+}
+
+/**
+ *  ixgbe_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 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = IXGBE_ERR_MBX;
+
+	if (mbx->ops.check_for_rst)
+		ret_val = mbx->ops.check_for_rst(hw, mbx_id);
+
+	return ret_val;
+}
+
+/**
+ *  ixgbe_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 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	int countdown = mbx->timeout;
+
+	if (!countdown || !mbx->ops.check_for_msg)
+		goto out;
+
+	while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
+		countdown--;
+		if (!countdown)
+			break;
+		udelay(mbx->usec_delay);
+	}
+
+	/* if we failed, all future posted messages fail until reset */
+	if (!countdown)
+		mbx->timeout = 0;
+out:
+	return countdown ? 0 : IXGBE_ERR_MBX;
+}
+
+/**
+ *  ixgbe_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 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	int countdown = mbx->timeout;
+
+	if (!countdown || !mbx->ops.check_for_ack)
+		goto out;
+
+	while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
+		countdown--;
+		if (!countdown)
+			break;
+		udelay(mbx->usec_delay);
+	}
+
+	/* if we failed, all future posted messages fail until reset */
+	if (!countdown)
+		mbx->timeout = 0;
+out:
+	return countdown ? 0 : IXGBE_ERR_MBX;
+}
+
+/**
+ *  ixgbe_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.
+ **/
+s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = IXGBE_ERR_MBX;
+
+	if (!mbx->ops.read)
+		goto out;
+
+	ret_val = ixgbe_poll_for_msg(hw, mbx_id);
+
+	/* if ack received read message, otherwise we timed out */
+	if (!ret_val)
+		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
+out:
+	return ret_val;
+}
+
+/**
+ *  ixgbe_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
+ **/
+s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
+                           u16 mbx_id)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = IXGBE_ERR_MBX;
+
+	/* exit if either we 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, mbx_id);
+
+	/* if msg sent wait until we receive an ack */
+	if (!ret_val)
+		ret_val = ixgbe_poll_for_ack(hw, mbx_id);
+out:
+	return ret_val;
+}
+
+/**
+ *  ixgbe_init_mbx_ops_generic - Initialize MB function pointers
+ *  @hw: pointer to the HW structure
+ *
+ *  Setup the mailbox read and write message function pointers
+ **/
+void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+
+	mbx->ops.read_posted = ixgbe_read_posted_mbx;
+	mbx->ops.write_posted = ixgbe_write_posted_mbx;
+}
+
+static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
+{
+	u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
+	s32 ret_val = IXGBE_ERR_MBX;
+
+	if (mbvficr & mask) {
+		ret_val = 0;
+		IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
+	}
+
+	return ret_val;
+}
+
+/**
+ *  ixgbe_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 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
+{
+	s32 ret_val = IXGBE_ERR_MBX;
+	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
+	u32 vf_bit = vf_number % 16;
+
+	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
+	                            index)) {
+		ret_val = 0;
+		hw->mbx.stats.reqs++;
+	}
+
+	return ret_val;
+}
+
+/**
+ *  ixgbe_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 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
+{
+	s32 ret_val = IXGBE_ERR_MBX;
+	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
+	u32 vf_bit = vf_number % 16;
+
+	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
+	                            index)) {
+		ret_val = 0;
+		hw->mbx.stats.acks++;
+	}
+
+	return ret_val;
+}
+
+/**
+ *  ixgbe_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 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
+{
+	u32 reg_offset = (vf_number < 32) ? 0 : 1;
+	u32 vf_shift = vf_number % 32;
+	u32 vflre = 0;
+	s32 ret_val = IXGBE_ERR_MBX;
+
+	if (hw->mac.type == ixgbe_mac_82599EB)
+		vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
+
+	if (vflre & (1 << vf_shift)) {
+		ret_val = 0;
+		IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
+		hw->mbx.stats.rsts++;
+	}
+
+	return ret_val;
+}
+
+/**
+ *  ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
+ *  @hw: pointer to the HW structure
+ *  @vf_number: the VF index
+ *
+ *  return SUCCESS if we obtained the mailbox lock
+ **/
+static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
+{
+	s32 ret_val = IXGBE_ERR_MBX;
+	u32 p2v_mailbox;
+
+	/* Take ownership of the buffer */
+	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
+
+	/* reserve mailbox for vf use */
+	p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
+	if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
+		ret_val = 0;
+
+	return ret_val;
+}
+
+/**
+ *  ixgbe_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 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
+                              u16 vf_number)
+{
+	s32 ret_val;
+	u16 i;
+
+	/* lock the mailbox to prevent pf/vf race condition */
+	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
+	if (ret_val)
+		goto out_no_write;
+
+	/* flush msg and acks as we are overwriting the message buffer */
+	ixgbe_check_for_msg_pf(hw, vf_number);
+	ixgbe_check_for_ack_pf(hw, vf_number);
+
+	/* copy the caller specified message to the mailbox memory buffer */
+	for (i = 0; i < size; i++)
+		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
+
+	/* Interrupt VF to tell it a message has been sent and release buffer*/
+	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
+
+	/* update stats */
+	hw->mbx.stats.msgs_tx++;
+
+out_no_write:
+	return ret_val;
+
+}
+
+/**
+ *  ixgbe_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 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
+                             u16 vf_number)
+{
+	s32 ret_val;
+	u16 i;
+
+	/* lock the mailbox to prevent pf/vf race condition */
+	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
+	if (ret_val)
+		goto out_no_read;
+
+	/* copy the message to the mailbox memory buffer */
+	for (i = 0; i < size; i++)
+		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
+
+	/* Acknowledge the message and release buffer */
+	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
+
+	/* update stats */
+	hw->mbx.stats.msgs_rx++;
+
+out_no_read:
+	return ret_val;
+}
+
+/**
+ *  ixgbe_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
+ */
+void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+
+	if (hw->mac.type != ixgbe_mac_82599EB)
+		return;
+
+	mbx->timeout = 0;
+	mbx->usec_delay = 0;
+
+	mbx->size = IXGBE_VFMAILBOX_SIZE;
+
+	mbx->stats.msgs_tx = 0;
+	mbx->stats.msgs_rx = 0;
+	mbx->stats.reqs = 0;
+	mbx->stats.acks = 0;
+	mbx->stats.rsts = 0;
+}
+
+struct ixgbe_mbx_operations mbx_ops_82599 = {
+	.read                   = ixgbe_read_mbx_pf,
+	.write                  = ixgbe_write_mbx_pf,
+	.read_posted            = ixgbe_read_posted_mbx,
+	.write_posted           = ixgbe_write_posted_mbx,
+	.check_for_msg          = ixgbe_check_for_msg_pf,
+	.check_for_ack          = ixgbe_check_for_ack_pf,
+	.check_for_rst          = ixgbe_check_for_rst_pf,
+};
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_mbx.h linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_mbx.h
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_mbx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_mbx.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,96 @@
+/*******************************************************************************
+
+  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 _IXGBE_MBX_H_
+#define _IXGBE_MBX_H_
+
+#include "ixgbe_type.h"
+
+#define IXGBE_VFMAILBOX_SIZE        16 /* 16 32 bit words - 64 bytes */
+#define IXGBE_ERR_MBX               -100
+
+#define IXGBE_VFMAILBOX             0x002FC
+#define IXGBE_VFMBMEM               0x00200
+
+#define IXGBE_PFMAILBOX(x)          (0x04B00 + (4 * x))
+#define IXGBE_PFMBMEM(vfn)          (0x13000 + (64 * vfn))
+
+#define IXGBE_PFMAILBOX_STS   0x00000001 /* Initiate message send to VF */
+#define IXGBE_PFMAILBOX_ACK   0x00000002 /* Ack message recv'd from VF */
+#define IXGBE_PFMAILBOX_VFU   0x00000004 /* VF owns the mailbox buffer */
+#define IXGBE_PFMAILBOX_PFU   0x00000008 /* PF owns the mailbox buffer */
+#define IXGBE_PFMAILBOX_RVFU  0x00000010 /* Reset VFU - used when VF stuck */
+
+#define IXGBE_MBVFICR_VFREQ_MASK 0x0000FFFF /* bits for VF messages */
+#define IXGBE_MBVFICR_VFREQ_VF1  0x00000001 /* bit for VF 1 message */
+#define IXGBE_MBVFICR_VFACK_MASK 0xFFFF0000 /* bits for VF acks */
+#define IXGBE_MBVFICR_VFACK_VF1  0x00010000 /* bit for VF 1 ack */
+
+
+/* If it's a IXGBE_VF_* msg then it originates in the VF and is sent to the
+ * PF.  The reverse is true if it is IXGBE_PF_*.
+ * Message ACK's are the value or'd with 0xF0000000
+ */
+#define IXGBE_VT_MSGTYPE_ACK      0x80000000  /* Messages below or'd with
+                                               * this are the ACK */
+#define IXGBE_VT_MSGTYPE_NACK     0x40000000  /* Messages below or'd with
+                                               * this are the NACK */
+#define IXGBE_VT_MSGTYPE_CTS      0x20000000  /* Indicates that VF is still
+                                                 clear to send requests */
+#define IXGBE_VT_MSGINFO_SHIFT    16
+/* bits 23:16 are used for exra info for certain messages */
+#define IXGBE_VT_MSGINFO_MASK     (0xFF << IXGBE_VT_MSGINFO_SHIFT)
+
+#define IXGBE_VF_RESET            0x01 /* VF requests reset */
+#define IXGBE_VF_SET_MAC_ADDR     0x02 /* VF requests PF to set MAC addr */
+#define IXGBE_VF_SET_MULTICAST    0x03 /* VF requests PF to set MC addr */
+#define IXGBE_VF_SET_VLAN         0x04 /* VF requests PF to set VLAN */
+#define IXGBE_VF_SET_LPE          0x05 /* VF requests PF to set VMOLR.LPE */
+
+/* length of permanent address message returned from PF */
+#define IXGBE_VF_PERMADDR_MSG_LEN 4
+/* word in permanent address message with the current multicast type */
+#define IXGBE_VF_MC_TYPE_WORD     3
+
+#define IXGBE_PF_CONTROL_MSG      0x0100 /* PF control message */
+
+#define IXGBE_VF_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */
+#define IXGBE_VF_MBX_INIT_DELAY   500  /* microseconds between retries */
+
+s32 ixgbe_read_mbx(struct ixgbe_hw *, u32 *, u16, u16);
+s32 ixgbe_write_mbx(struct ixgbe_hw *, u32 *, u16, u16);
+s32 ixgbe_read_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16);
+s32 ixgbe_write_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16);
+s32 ixgbe_check_for_msg(struct ixgbe_hw *, u16);
+s32 ixgbe_check_for_ack(struct ixgbe_hw *, u16);
+s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16);
+void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw);
+void ixgbe_init_mbx_params_pf(struct ixgbe_hw *);
+
+extern struct ixgbe_mbx_operations mbx_ops_82599;
+
+#endif /* _IXGBE_MBX_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_sriov.c linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_sriov.c
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_sriov.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_sriov.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,362 @@
+/*******************************************************************************
+
+  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/types.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/vmalloc.h>
+#include <linux/string.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/ipv6.h>
+#ifdef NETIF_F_HW_VLAN_TX
+#include <linux/if_vlan.h>
+#endif
+
+#include "ixgbe.h"
+
+#include "ixgbe_sriov.h"
+
+int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
+			    int entries, u16 *hash_list, u32 vf)
+{
+	struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
+	int i;
+
+	/* only so many hash values supported */
+	entries = min(entries, IXGBE_MAX_VF_MC_ENTRIES);
+
+	/*
+	 * salt away the number of multi cast addresses assigned
+	 * to this VF for later use to restore when the PF multi cast
+	 * list changes
+	 */
+	vfinfo->num_vf_mc_hashes = entries;
+
+	/*
+	 * VFs are limited to using the MTA hash table for their multicast
+	 * addresses
+	 */
+	for (i = 0; i < entries; i++) {
+		vfinfo->vf_mc_hashes[i] = hash_list[i];;
+	}
+
+	/* Flush and reset the mta with the new values */
+	ixgbe_set_rx_mode(adapter->netdev);
+
+	return 0;
+}
+
+void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	struct vf_data_storage *vfinfo;
+	int i, j;
+	u32 vector_bit;
+	u32 vector_reg;
+	u32 mta_reg;
+
+	for (i = 0; i < adapter->num_vfs; i++) {
+		vfinfo = &adapter->vfinfo[i];
+		for (j = 0; j < vfinfo->num_vf_mc_hashes; j++) {
+			hw->addr_ctrl.mta_in_use++;
+			vector_reg = (vfinfo->vf_mc_hashes[j] >> 5) & 0x7F;
+			vector_bit = vfinfo->vf_mc_hashes[j] & 0x1F;
+			mta_reg = IXGBE_READ_REG(hw, IXGBE_MTA(vector_reg));
+			mta_reg |= (1 << vector_bit);
+			IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
+		}
+	}
+}
+
+int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, u32 vf)
+{
+	u32 ctrl;
+
+	/* Check if global VLAN already set, if not set it */
+	ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_VLNCTRL);
+	if (!(ctrl & IXGBE_VLNCTRL_VFE)) {
+		/* enable VLAN tag insert/strip */
+		ctrl |= IXGBE_VLNCTRL_VFE;
+		ctrl &= ~IXGBE_VLNCTRL_CFIEN;
+		IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
+	}
+
+	return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add);
+}
+
+
+void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf)
+{
+	u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
+	vmolr |= (IXGBE_VMOLR_AUPE |
+		  IXGBE_VMOLR_ROMPE |
+		  IXGBE_VMOLR_ROPE |
+		  IXGBE_VMOLR_BAM);
+	IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);
+}
+
+inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	/* reset offloads to defaults */
+	ixgbe_set_vmolr(hw, vf);
+
+
+	/* reset multicast table array for vf */
+	adapter->vfinfo[vf].num_vf_mc_hashes = 0;
+
+	/* Flush and reset the mta with the new values */
+	ixgbe_set_rx_mode(adapter->netdev);
+
+	if (adapter->vfinfo[vf].rar > 0) {
+		adapter->hw.mac.ops.clear_rar(&adapter->hw,
+		                              adapter->vfinfo[vf].rar);
+		adapter->vfinfo[vf].rar = -1;
+	}
+}
+
+int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
+                          int vf, unsigned char *mac_addr)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	adapter->vfinfo[vf].rar = hw->mac.ops.set_rar(hw, vf + 1, mac_addr,
+	                                              vf, IXGBE_RAH_AV);
+	if (adapter->vfinfo[vf].rar < 0) {
+		DPRINTK(DRV, ERR, "Could not set MAC Filter for VF %d\n", vf);
+		return -1;
+	}
+
+	memcpy(adapter->vfinfo[vf].vf_mac_addresses, mac_addr, 6);
+
+	return 0;
+}
+
+int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
+{
+	unsigned char vf_mac_addr[6];
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+	unsigned int vfn = (event_mask & 0x3f);
+
+	bool enable = ((event_mask & 0x10000000U) != 0);
+
+	if (enable) {
+		random_ether_addr(vf_mac_addr);
+		DPRINTK(PROBE, INFO, "IOV: VF %d is enabled "
+		       "mac %02X:%02X:%02X:%02X:%02X:%02X\n",
+		       vfn,
+		       vf_mac_addr[0], vf_mac_addr[1], vf_mac_addr[2],
+		       vf_mac_addr[3], vf_mac_addr[4], vf_mac_addr[5]);
+		/*
+		 * Store away the VF "permananet" MAC address, it will ask
+		 * for it later.
+		 */
+		memcpy(adapter->vfinfo[vfn].vf_mac_addresses, vf_mac_addr, 6);
+	}
+
+	return 0;
+}
+
+inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 reg;
+	u32 reg_offset, vf_shift;
+
+	vf_shift = vf % 32;
+	reg_offset = vf / 32;
+
+	/* enable transmit and receive for vf */
+	reg = IXGBE_READ_REG(hw, IXGBE_VFTE(reg_offset));
+	reg |= (reg | (1 << vf_shift));
+	IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg);
+
+	reg = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset));
+	reg |= (reg | (1 << vf_shift));
+	IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg);
+
+	ixgbe_vf_reset_event(adapter, vf);
+}
+
+static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
+{
+	u32 mbx_size = IXGBE_VFMAILBOX_SIZE;
+	u32 msgbuf[mbx_size];
+	struct ixgbe_hw *hw = &adapter->hw;
+	s32 retval;
+	int entries;
+	u16 *hash_list;
+	int add, vid;
+
+	retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
+
+	if (retval)
+		printk(KERN_ERR "Error receiving message from VF\n");
+
+	/* this is a message we already processed, do nothing */
+	if (msgbuf[0] & (IXGBE_VT_MSGTYPE_ACK | IXGBE_VT_MSGTYPE_NACK))
+		return retval;
+
+	/*
+	 * until the vf completes a virtual function reset it should not be
+	 * allowed to start any configuration.
+	 */
+
+	if (msgbuf[0] == IXGBE_VF_RESET) {
+		unsigned char *vf_mac = adapter->vfinfo[vf].vf_mac_addresses;
+		u8 *addr = (u8 *)(&msgbuf[1]);
+		DPRINTK(PROBE, INFO, "VF Reset msg received from vf %d\n", vf);
+		adapter->vfinfo[vf].clear_to_send = false;
+		ixgbe_vf_reset_msg(adapter, vf);
+		adapter->vfinfo[vf].clear_to_send = true;
+
+		/* reply to reset with ack and vf mac address */
+		msgbuf[0] = IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK;
+		memcpy(addr, vf_mac, IXGBE_ETH_LENGTH_OF_ADDRESS);
+		/*
+		 * Piggyback the multicast filter type so VF can compute the
+		 * correct vectors
+		 */
+		msgbuf[3] = hw->mac.mc_filter_type;
+		ixgbe_write_mbx(hw, msgbuf, IXGBE_VF_PERMADDR_MSG_LEN, vf);
+
+		return retval;
+	}
+
+	if (!adapter->vfinfo[vf].clear_to_send) {
+		msgbuf[0] |= IXGBE_VT_MSGTYPE_NACK;
+		ixgbe_write_mbx(hw, msgbuf, 1, vf);
+		return retval;
+	}
+
+	switch ((msgbuf[0] & 0xFFFF)) {
+	case IXGBE_VF_SET_MAC_ADDR:
+		{
+			u8 *new_mac = ((u8 *)(&msgbuf[1]));
+			if (is_valid_ether_addr(new_mac))
+				ixgbe_set_vf_mac(adapter, vf, new_mac);
+			else
+				retval = -1;
+		}
+		break;
+	case IXGBE_VF_SET_MULTICAST:
+		entries = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK)
+		          >> IXGBE_VT_MSGINFO_SHIFT;
+		hash_list = (u16 *)&msgbuf[1];
+		retval = ixgbe_set_vf_multicasts(adapter, entries,
+		                                 hash_list, vf);
+		break;
+	case IXGBE_VF_SET_LPE:
+		WARN_ON((msgbuf[0] & 0xFFFF) == IXGBE_VF_SET_LPE);
+		break;
+	case IXGBE_VF_SET_VLAN:
+		add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK)
+		      >> IXGBE_VT_MSGINFO_SHIFT;
+		vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK);
+		retval = ixgbe_set_vf_vlan(adapter, add, vid, vf);
+		break;
+	default:
+		DPRINTK(DRV, ERR, "Unhandled Msg %8.8x\n", msgbuf[0]);
+		retval = IXGBE_ERR_MBX;
+		break;
+	}
+
+	/* notify the VF of the results of what it sent us */
+	if (retval)
+		msgbuf[0] |= IXGBE_VT_MSGTYPE_NACK;
+	else
+		msgbuf[0] |= IXGBE_VT_MSGTYPE_ACK;
+
+	msgbuf[0] |= IXGBE_VT_MSGTYPE_CTS;
+
+	ixgbe_write_mbx(hw, msgbuf, 1, vf);
+
+	return retval;
+}
+
+static void ixgbe_rcv_ack_from_vf(struct ixgbe_adapter *adapter, u32 vf)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 msg = IXGBE_VT_MSGTYPE_NACK;
+
+	/* if device isn't clear to send it shouldn't be reading either */
+	if (!adapter->vfinfo[vf].clear_to_send)
+		ixgbe_write_mbx(hw, &msg, 1, vf);
+}
+
+void ixgbe_msg_task(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 vf;
+
+	for (vf = 0; vf < adapter->num_vfs; vf++) {
+		/* process any reset requests */
+		if (!ixgbe_check_for_rst(hw, vf))
+			ixgbe_vf_reset_event(adapter, vf);
+
+		/* process any messages pending */
+		if (!ixgbe_check_for_msg(hw, vf))
+			ixgbe_rcv_msg_from_vf(adapter, vf);
+
+		/* process any acks */
+		if (!ixgbe_check_for_ack(hw, vf))
+			ixgbe_rcv_ack_from_vf(adapter, vf);
+	}
+}
+
+void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	/* disable transmit and receive for all vfs */
+	IXGBE_WRITE_REG(hw, IXGBE_VFTE(0), 0);
+	IXGBE_WRITE_REG(hw, IXGBE_VFTE(1), 0);
+
+	IXGBE_WRITE_REG(hw, IXGBE_VFRE(0), 0);
+	IXGBE_WRITE_REG(hw, IXGBE_VFRE(1), 0);
+}
+
+void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 ping;
+	int i;
+
+	for (i = 0 ; i < adapter->num_vfs; i++) {
+		ping = IXGBE_PF_CONTROL_MSG;
+		if (adapter->vfinfo[i].clear_to_send)
+			ping |= IXGBE_VT_MSGTYPE_CTS;
+		ixgbe_write_mbx(hw, &ping, 1, i);
+	}
+}
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_sriov.h linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_sriov.h
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_sriov.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_sriov.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,47 @@
+/*******************************************************************************
+
+  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 _IXGBE_SRIOV_H_
+#define _IXGBE_SRIOV_H_
+
+int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
+                            int entries, u16 *hash_list, u32 vf);
+void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter);
+int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, u32 vf);
+void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf);
+void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf);
+void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf);
+void ixgbe_msg_task(struct ixgbe_adapter *adapter);
+int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
+                     int vf, unsigned char *mac_addr);
+int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask);
+void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter);
+void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter);
+void ixgbe_dump_registers(struct ixgbe_adapter *adapter);
+
+#endif /* _IXGBE_SRIOV_H_ */
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_type.h linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_type.h
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_type.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbe/ixgbe_type.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,7 @@
 
 #include <linux/types.h>
 #include <linux/mdio.h>
-#include <linux/list.h>
+#include <linux/netdevice.h>
 
 /* Vendor ID */
 #define IXGBE_INTEL_VENDOR_ID   0x8086
@@ -277,6 +277,7 @@
 #define IXGBE_DTXCTL    0x07E00
 
 #define IXGBE_DMATXCTL  0x04A80
+#define IXGBE_PFDTXGSWC     0x08220
 #define IXGBE_DTXMXSZRQ     0x08100
 #define IXGBE_DTXTCPFLGL    0x04A88
 #define IXGBE_DTXTCPFLGH    0x04A8C
@@ -287,6 +288,8 @@
 #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_PFDTXGSWC_VT_LBEN 0x1 /* Local L2 VT switch enable */
 #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))
@@ -497,6 +500,7 @@
 /* DCB registers */
 #define IXGBE_RTRPCS      0x02430
 #define IXGBE_RTTDCS      0x04900
+#define IXGBE_RTTDCS_ARBDIS     0x00000040 /* DCB arbiter disable */
 #define IXGBE_RTTPCS      0x0CD00
 #define IXGBE_RTRUP2TC    0x03020
 #define IXGBE_RTTUP2TC    0x0C800
@@ -730,6 +734,13 @@
 #define IXGBE_GCR_CMPL_TMOUT_RESEND     0x00010000
 #define IXGBE_GCR_CAP_VER2              0x00040000
 
+#define IXGBE_GCR_EXT_MSIX_EN           0x80000000
+#define IXGBE_GCR_EXT_VT_MODE_16        0x00000001
+#define IXGBE_GCR_EXT_VT_MODE_32        0x00000002
+#define IXGBE_GCR_EXT_VT_MODE_64        0x00000003
+#define IXGBE_GCR_EXT_SRIOV             (IXGBE_GCR_EXT_MSIX_EN | \
+                                         IXGBE_GCR_EXT_VT_MODE_64)
+
 /* Time Sync Registers */
 #define IXGBE_TSYNCRXCTL 0x05188 /* Rx Time Sync Control register - RW */
 #define IXGBE_TSYNCTXCTL 0x08C00 /* Tx Time Sync Control register - RW */
@@ -1065,6 +1076,8 @@
 /* VFRE bitmask */
 #define IXGBE_VFRE_ENABLE_ALL   0xFFFFFFFF
 
+#define IXGBE_VF_INIT_TIMEOUT   200 /* Number of retries to clear RSTI */
+
 /* RDHMPN and TDHMPN bitmasks */
 #define IXGBE_RDHMPN_RDICADDR       0x007FF800
 #define IXGBE_RDHMPN_RDICRDREQ      0x00800000
@@ -1285,6 +1298,7 @@
 #define IXGBE_ETQF_FILTER_BCN            1
 #define IXGBE_ETQF_FILTER_FCOE           2
 #define IXGBE_ETQF_FILTER_1588           3
+#define IXGBE_ETQF_FILTER_FIP            4
 /* VLAN Control Bit Masks */
 #define IXGBE_VLNCTRL_VET       0x0000FFFF  /* bits 0-15 */
 #define IXGBE_VLNCTRL_CFI       0x10000000  /* bit 28 */
@@ -1295,6 +1309,7 @@
 /* VLAN pool filtering masks */
 #define IXGBE_VLVF_VIEN         0x80000000  /* filter is valid */
 #define IXGBE_VLVF_ENTRIES      64
+#define IXGBE_VLVF_VLANID_MASK  0x00000FFF
 
 #define IXGBE_ETHERNET_IEEE_VLAN_TYPE 0x8100  /* 802.1q protocol */
 
@@ -1843,6 +1858,12 @@
 #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
 
+/* SR-IOV specific macros */
+#define IXGBE_MBVFICR_INDEX(vf_number)   (vf_number >> 4)
+#define IXGBE_MBVFICR(_i)                (0x00710 + (_i * 4))
+#define IXGBE_VFLRE(_i)                  (((_i & 1) ? 0x001C0 : 0x00600))
+#define IXGBE_VFLREC(_i)                 (0x00700 + (_i * 4))
+
 /* Little Endian defines */
 #ifndef __le32
 #define __le32  u32
@@ -2109,6 +2130,15 @@ struct ixgbe_atr_input {
 	u8 byte_stream[42];
 };
 
+struct ixgbe_atr_input_masks {
+	u32 src_ip_mask;
+	u32 dst_ip_mask;
+	u16 src_port_mask;
+	u16 dst_port_mask;
+	u16 vlan_id_mask;
+	u16 data_mask;
+};
+
 enum ixgbe_eeprom_type {
 	ixgbe_eeprom_uninitialized = 0,
 	ixgbe_eeprom_spi,
@@ -2368,6 +2398,9 @@ struct ixgbe_mac_operations {
 	s32 (*enable_rx_dma)(struct ixgbe_hw *, u32);
 
 	/* Link */
+	void (*disable_tx_laser)(struct ixgbe_hw *);
+	void (*enable_tx_laser)(struct ixgbe_hw *);
+	void (*flap_tx_laser)(struct ixgbe_hw *);
 	s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool);
 	s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool);
 	s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *,
@@ -2385,7 +2418,7 @@ struct ixgbe_mac_operations {
 	s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32);
 	s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32);
 	s32 (*init_rx_addrs)(struct ixgbe_hw *);
-	s32 (*update_uc_addr_list)(struct ixgbe_hw *, struct list_head *);
+	s32 (*update_uc_addr_list)(struct ixgbe_hw *, struct net_device *);
 	s32 (*update_mc_addr_list)(struct ixgbe_hw *, u8 *, u32,
 	                           ixgbe_mc_addr_itr);
 	s32 (*enable_mc)(struct ixgbe_hw *);
@@ -2463,6 +2496,37 @@ struct ixgbe_phy_info {
 	bool                            multispeed_fiber;
 };
 
+#include "ixgbe_mbx.h"
+
+struct ixgbe_mbx_operations {
+	s32 (*init_params)(struct ixgbe_hw *hw);
+	s32 (*read)(struct ixgbe_hw *, u32 *, u16,  u16);
+	s32 (*write)(struct ixgbe_hw *, u32 *, u16, u16);
+	s32 (*read_posted)(struct ixgbe_hw *, u32 *, u16,  u16);
+	s32 (*write_posted)(struct ixgbe_hw *, u32 *, u16, u16);
+	s32 (*check_for_msg)(struct ixgbe_hw *, u16);
+	s32 (*check_for_ack)(struct ixgbe_hw *, u16);
+	s32 (*check_for_rst)(struct ixgbe_hw *, u16);
+};
+
+struct ixgbe_mbx_stats {
+	u32 msgs_tx;
+	u32 msgs_rx;
+
+	u32 acks;
+	u32 reqs;
+	u32 rsts;
+};
+
+struct ixgbe_mbx_info {
+	struct ixgbe_mbx_operations ops;
+	struct ixgbe_mbx_stats stats;
+	u32 timeout;
+	u32 usec_delay;
+	u32 v2p_mailbox;
+	u16 size;
+};
+
 struct ixgbe_hw {
 	u8 __iomem			*hw_addr;
 	void				*back;
@@ -2472,6 +2536,7 @@ struct ixgbe_hw {
 	struct ixgbe_phy_info		phy;
 	struct ixgbe_eeprom_info	eeprom;
 	struct ixgbe_bus_info		bus;
+	struct ixgbe_mbx_info		mbx;
 	u16				device_id;
 	u16				vendor_id;
 	u16				subsystem_device_id;
@@ -2486,6 +2551,7 @@ struct ixgbe_info {
 	struct ixgbe_mac_operations	*mac_ops;
 	struct ixgbe_eeprom_operations	*eeprom_ops;
 	struct ixgbe_phy_operations	*phy_ops;
+	struct ixgbe_mbx_operations	*mbx_ops;
 };
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbe/Makefile linux-libre-2.6.34-gnu1/drivers/net/ixgbe/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbe/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbe/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,8 @@
 obj-$(CONFIG_IXGBE) += ixgbe.o
 
 ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
-              ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o
+              ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \
+              ixgbe_mbx.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.33-gnu1/drivers/net/ixgbevf/defines.h linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/defines.h
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/defines.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/defines.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,292 @@
+/*******************************************************************************
+
+  Intel 82599 Virtual Function 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 _IXGBEVF_DEFINES_H_
+#define _IXGBEVF_DEFINES_H_
+
+/* Device IDs */
+#define IXGBE_DEV_ID_82599_VF           0x10ED
+
+#define IXGBE_VF_IRQ_CLEAR_MASK         7
+#define IXGBE_VF_MAX_TX_QUEUES          1
+#define IXGBE_VF_MAX_RX_QUEUES          1
+#define IXGBE_ETH_LENGTH_OF_ADDRESS     6
+
+/* Link speed */
+typedef u32 ixgbe_link_speed;
+#define IXGBE_LINK_SPEED_1GB_FULL       0x0020
+#define IXGBE_LINK_SPEED_10GB_FULL      0x0080
+
+#define IXGBE_CTRL_RST          0x04000000 /* Reset (SW) */
+#define IXGBE_RXDCTL_ENABLE     0x02000000 /* Enable specific Rx Queue */
+#define IXGBE_TXDCTL_ENABLE     0x02000000 /* Enable specific Tx Queue */
+#define IXGBE_LINKS_UP          0x40000000
+#define IXGBE_LINKS_SPEED       0x20000000
+
+/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
+#define IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE  8
+#define IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE  8
+#define IXGBE_REQ_TX_BUFFER_GRANULARITY   1024
+
+/* Interrupt Vector Allocation Registers */
+#define IXGBE_IVAR_ALLOC_VAL    0x80 /* Interrupt Allocation valid */
+
+#define IXGBE_VF_INIT_TIMEOUT   200 /* Number of retries to clear RSTI */
+
+/* Receive Config masks */
+#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 */
+
+/* DCA Control */
+#define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
+
+/* PSRTYPE bit definitions */
+#define IXGBE_PSRTYPE_TCPHDR    0x00000010
+#define IXGBE_PSRTYPE_UDPHDR    0x00000020
+#define IXGBE_PSRTYPE_IPV4HDR   0x00000100
+#define IXGBE_PSRTYPE_IPV6HDR   0x00000200
+#define IXGBE_PSRTYPE_L2HDR     0x00001000
+
+/* 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
+#define IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
+#define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT  0x04000000
+#define IXGBE_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000
+#define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
+#define IXGBE_SRRCTL_DESCTYPE_MASK      0x0E000000
+
+/* 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 */
+#define IXGBE_RXD_STAT_PIF        0x80    /* passed in-exact filter */
+#define IXGBE_RXD_STAT_CRCV       0x100   /* Speculative CRC Valid */
+#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_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 */
+#define IXGBE_RXD_ERR_PE          0x08    /* Packet Error */
+#define IXGBE_RXD_ERR_OSE         0x10    /* Oversize Error */
+#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 */
+#define IXGBE_RXDADV_ERR_PE       0x08000000 /* Packet Error */
+#define IXGBE_RXDADV_ERR_OSE      0x10000000 /* Oversize Error */
+#define IXGBE_RXDADV_ERR_USE      0x20000000 /* Undersize Error */
+#define IXGBE_RXDADV_ERR_TCPE     0x40000000 /* TCP/UDP Checksum Error */
+#define IXGBE_RXDADV_ERR_IPE      0x80000000 /* IP Checksum Error */
+#define IXGBE_RXD_VLAN_ID_MASK    0x0FFF  /* VLAN ID is in lower 12 bits */
+#define IXGBE_RXD_PRI_MASK        0xE000  /* Priority is in upper 3 bits */
+#define IXGBE_RXD_PRI_SHIFT       13
+#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 */
+#define IXGBE_RXDADV_STAT_FCEOFS        0x00000040 /* FCoE EOF/SOF Stat */
+#define IXGBE_RXDADV_STAT_FCSTAT        0x00000030 /* FCoE Pkt Stat */
+#define IXGBE_RXDADV_STAT_FCSTAT_NOMTCH 0x00000000 /* 00: No Ctxt Match */
+#define IXGBE_RXDADV_STAT_FCSTAT_NODDP  0x00000010 /* 01: Ctxt w/o DDP */
+#define IXGBE_RXDADV_STAT_FCSTAT_FCPRSP 0x00000020 /* 10: Recv. FCP_RSP */
+#define IXGBE_RXDADV_STAT_FCSTAT_DDP    0x00000030 /* 11: Ctxt w/ DDP */
+
+#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_RSCCNT_MASK        0x001E0000
+#define IXGBE_RXDADV_RSCCNT_SHIFT       17
+#define IXGBE_RXDADV_HDRBUFLEN_SHIFT    5
+#define IXGBE_RXDADV_SPLITHEADER_EN     0x00001000
+#define IXGBE_RXDADV_SPH                0x8000
+
+#define IXGBE_RXD_ERR_FRAME_ERR_MASK ( \
+				      IXGBE_RXD_ERR_CE |  \
+				      IXGBE_RXD_ERR_LE |  \
+				      IXGBE_RXD_ERR_PE |  \
+				      IXGBE_RXD_ERR_OSE | \
+				      IXGBE_RXD_ERR_USE)
+
+#define IXGBE_RXDADV_ERR_FRAME_ERR_MASK ( \
+					 IXGBE_RXDADV_ERR_CE |  \
+					 IXGBE_RXDADV_ERR_LE |  \
+					 IXGBE_RXDADV_ERR_PE |  \
+					 IXGBE_RXDADV_ERR_OSE | \
+					 IXGBE_RXDADV_ERR_USE)
+
+#define IXGBE_TXD_POPTS_IXSM 0x01       /* Insert IP checksum */
+#define IXGBE_TXD_POPTS_TXSM 0x02       /* Insert TCP/UDP checksum */
+#define IXGBE_TXD_CMD_EOP    0x01000000 /* End of Packet */
+#define IXGBE_TXD_CMD_IFCS   0x02000000 /* Insert FCS (Ethernet CRC) */
+#define IXGBE_TXD_CMD_IC     0x04000000 /* Insert Checksum */
+#define IXGBE_TXD_CMD_RS     0x08000000 /* Report Status */
+#define IXGBE_TXD_CMD_DEXT   0x20000000 /* Descriptor extension (0 = legacy) */
+#define IXGBE_TXD_CMD_VLE    0x40000000 /* Add VLAN tag */
+#define IXGBE_TXD_STAT_DD    0x00000001 /* Descriptor Done */
+
+/* Transmit Descriptor - Advanced */
+union ixgbe_adv_tx_desc {
+	struct {
+		__le64 buffer_addr;      /* Address of descriptor's data buf */
+		__le32 cmd_type_len;
+		__le32 olinfo_status;
+	} read;
+	struct {
+		__le64 rsvd;       /* Reserved */
+		__le32 nxtseq_seed;
+		__le32 status;
+	} wb;
+};
+
+/* Receive Descriptor - Advanced */
+union ixgbe_adv_rx_desc {
+	struct {
+		__le64 pkt_addr; /* Packet buffer address */
+		__le64 hdr_addr; /* Header buffer address */
+	} read;
+	struct {
+		struct {
+			union {
+				__le32 data;
+				struct {
+					__le16 pkt_info; /* RSS, Pkt type */
+					__le16 hdr_info; /* Splithdr, hdrlen */
+				} hs_rss;
+			} lo_dword;
+			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; /* Packet length */
+			__le16 vlan; /* VLAN tag */
+		} upper;
+	} wb;  /* writeback */
+};
+
+/* Context descriptors */
+struct ixgbe_adv_tx_context_desc {
+	__le32 vlan_macip_lens;
+	__le32 seqnum_seed;
+	__le32 type_tucmd_mlhl;
+	__le32 mss_l4len_idx;
+};
+
+/* Adv Transmit Descriptor Config Masks */
+#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 */
+#define IXGBE_ADVTXD_DCMD_EOP   IXGBE_TXD_CMD_EOP  /* End of Packet */
+#define IXGBE_ADVTXD_DCMD_IFCS  IXGBE_TXD_CMD_IFCS /* Insert FCS */
+#define IXGBE_ADVTXD_DCMD_RS    IXGBE_TXD_CMD_RS   /* Report Status */
+#define IXGBE_ADVTXD_DCMD_DEXT  IXGBE_TXD_CMD_DEXT /* Desc ext (1=Adv) */
+#define IXGBE_ADVTXD_DCMD_VLE   IXGBE_TXD_CMD_VLE  /* VLAN pkt enable */
+#define IXGBE_ADVTXD_DCMD_TSE   0x80000000 /* TCP Seg enable */
+#define IXGBE_ADVTXD_STAT_DD    IXGBE_TXD_STAT_DD  /* Descriptor Done */
+#define IXGBE_ADVTXD_TUCMD_IPV4      0x00000400  /* IP Packet Type: 1=IPv4 */
+#define IXGBE_ADVTXD_TUCMD_IPV6      0x00000000  /* IP Packet Type: 0=IPv6 */
+#define IXGBE_ADVTXD_TUCMD_L4T_UDP   0x00000000  /* L4 Packet TYPE of UDP */
+#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_IDX_SHIFT  4 /* Adv desc Index shift */
+#define IXGBE_ADVTXD_POPTS_SHIFT      8  /* Adv desc POPTS shift */
+#define IXGBE_ADVTXD_POPTS_IXSM (IXGBE_TXD_POPTS_IXSM << \
+				 IXGBE_ADVTXD_POPTS_SHIFT)
+#define IXGBE_ADVTXD_POPTS_TXSM (IXGBE_TXD_POPTS_TXSM << \
+				 IXGBE_ADVTXD_POPTS_SHIFT)
+#define IXGBE_ADVTXD_PAYLEN_SHIFT    14 /* Adv desc PAYLEN shift */
+#define IXGBE_ADVTXD_MACLEN_SHIFT    9  /* Adv ctxt desc mac len shift */
+#define IXGBE_ADVTXD_VLAN_SHIFT      16  /* Adv ctxt vlan tag shift */
+#define IXGBE_ADVTXD_L4LEN_SHIFT     8  /* Adv ctxt L4LEN shift */
+#define IXGBE_ADVTXD_MSS_SHIFT       16  /* Adv ctxt MSS shift */
+
+/* Interrupt register bitmasks */
+
+/* Extended Interrupt Cause Read */
+#define IXGBE_EICR_RTX_QUEUE    0x0000FFFF /* RTx Queue Interrupt */
+#define IXGBE_EICR_MAILBOX      0x00080000 /* VF to PF Mailbox Interrupt */
+#define IXGBE_EICR_OTHER        0x80000000 /* Interrupt Cause Active */
+
+/* Extended Interrupt Cause Set */
+#define IXGBE_EICS_RTX_QUEUE    IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
+#define IXGBE_EICS_MAILBOX      IXGBE_EICR_MAILBOX   /* VF to PF Mailbox Int */
+#define IXGBE_EICS_OTHER        IXGBE_EICR_OTHER     /* INT Cause Active */
+
+/* Extended Interrupt Mask Set */
+#define IXGBE_EIMS_RTX_QUEUE    IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
+#define IXGBE_EIMS_MAILBOX      IXGBE_EICR_MAILBOX   /* VF to PF Mailbox Int */
+#define IXGBE_EIMS_OTHER        IXGBE_EICR_OTHER     /* INT Cause Active */
+
+/* Extended Interrupt Mask Clear */
+#define IXGBE_EIMC_RTX_QUEUE    IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
+#define IXGBE_EIMC_MAILBOX      IXGBE_EICR_MAILBOX   /* VF to PF Mailbox Int */
+#define IXGBE_EIMC_OTHER        IXGBE_EICR_OTHER     /* INT Cause Active */
+
+#define IXGBE_EIMS_ENABLE_MASK ( \
+				IXGBE_EIMS_RTX_QUEUE       | \
+				IXGBE_EIMS_MAILBOX         | \
+				IXGBE_EIMS_OTHER)
+
+#define IXGBE_EITR_CNT_WDIS     0x80000000
+
+/* Error Codes */
+#define IXGBE_ERR_INVALID_MAC_ADDR              -1
+#define IXGBE_ERR_RESET_FAILED                  -2
+
+#endif /* _IXGBEVF_DEFINES_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/ethtool.c linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/ethtool.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,731 @@
+/*******************************************************************************
+
+  Intel 82599 Virtual Function 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
+
+*******************************************************************************/
+
+/* ethtool support for ixgbevf */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/vmalloc.h>
+#include <linux/if_vlan.h>
+#include <linux/uaccess.h>
+
+#include "ixgbevf.h"
+
+#define IXGBE_ALL_RAR_ENTRIES 16
+
+#ifdef ETHTOOL_GSTATS
+struct ixgbe_stats {
+	char stat_string[ETH_GSTRING_LEN];
+	int sizeof_stat;
+	int stat_offset;
+	int base_stat_offset;
+	int saved_reset_offset;
+};
+
+#define IXGBEVF_STAT(m, b, r)  sizeof(((struct ixgbevf_adapter *)0)->m), \
+			    offsetof(struct ixgbevf_adapter, m),         \
+			    offsetof(struct ixgbevf_adapter, b),         \
+			    offsetof(struct ixgbevf_adapter, r)
+static struct ixgbe_stats ixgbe_gstrings_stats[] = {
+	{"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc,
+				    stats.saved_reset_vfgprc)},
+	{"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc,
+				    stats.saved_reset_vfgptc)},
+	{"rx_bytes", IXGBEVF_STAT(stats.vfgorc, stats.base_vfgorc,
+				  stats.saved_reset_vfgorc)},
+	{"tx_bytes", IXGBEVF_STAT(stats.vfgotc, stats.base_vfgotc,
+				  stats.saved_reset_vfgotc)},
+	{"tx_busy", IXGBEVF_STAT(tx_busy, zero_base, zero_base)},
+	{"multicast", IXGBEVF_STAT(stats.vfmprc, stats.base_vfmprc,
+				   stats.saved_reset_vfmprc)},
+	{"rx_csum_offload_good", IXGBEVF_STAT(hw_csum_rx_good, zero_base,
+					      zero_base)},
+	{"rx_csum_offload_errors", IXGBEVF_STAT(hw_csum_rx_error, zero_base,
+						zero_base)},
+	{"tx_csum_offload_ctxt", IXGBEVF_STAT(hw_csum_tx_good, zero_base,
+					      zero_base)},
+	{"rx_header_split", IXGBEVF_STAT(rx_hdr_split, zero_base, zero_base)},
+};
+
+#define IXGBE_QUEUE_STATS_LEN 0
+#define IXGBE_GLOBAL_STATS_LEN	ARRAY_SIZE(ixgbe_gstrings_stats)
+
+#define IXGBEVF_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN)
+#endif /* ETHTOOL_GSTATS */
+#ifdef ETHTOOL_TEST
+static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = {
+	"Register test  (offline)",
+	"Link test   (on/offline)"
+};
+#define IXGBE_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN)
+#endif /* ETHTOOL_TEST */
+
+static int ixgbevf_get_settings(struct net_device *netdev,
+				struct ethtool_cmd *ecmd)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 link_speed = 0;
+	bool link_up;
+
+	ecmd->supported = SUPPORTED_10000baseT_Full;
+	ecmd->autoneg = AUTONEG_DISABLE;
+	ecmd->transceiver = XCVR_DUMMY1;
+	ecmd->port = -1;
+
+	hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
+
+	if (link_up) {
+		ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
+			       SPEED_10000 : SPEED_1000;
+		ecmd->duplex = DUPLEX_FULL;
+	} else {
+		ecmd->speed = -1;
+		ecmd->duplex = -1;
+	}
+
+	return 0;
+}
+
+static u32 ixgbevf_get_rx_csum(struct net_device *netdev)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	return adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED;
+}
+
+static int ixgbevf_set_rx_csum(struct net_device *netdev, u32 data)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	if (data)
+		adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
+	else
+		adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;
+
+	if (netif_running(netdev)) {
+		if (!adapter->dev_closed)
+			ixgbevf_reinit_locked(adapter);
+	} else {
+		ixgbevf_reset(adapter);
+	}
+
+	return 0;
+}
+
+static int ixgbevf_set_tso(struct net_device *netdev, u32 data)
+{
+	if (data) {
+		netdev->features |= NETIF_F_TSO;
+		netdev->features |= NETIF_F_TSO6;
+	} else {
+		netif_tx_stop_all_queues(netdev);
+		netdev->features &= ~NETIF_F_TSO;
+		netdev->features &= ~NETIF_F_TSO6;
+		netif_tx_start_all_queues(netdev);
+	}
+	return 0;
+}
+
+static u32 ixgbevf_get_msglevel(struct net_device *netdev)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	return adapter->msg_enable;
+}
+
+static void ixgbevf_set_msglevel(struct net_device *netdev, u32 data)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	adapter->msg_enable = data;
+}
+
+#define IXGBE_GET_STAT(_A_, _R_) (_A_->stats._R_)
+
+static char *ixgbevf_reg_names[] = {
+	"IXGBE_VFCTRL",
+	"IXGBE_VFSTATUS",
+	"IXGBE_VFLINKS",
+	"IXGBE_VFRXMEMWRAP",
+	"IXGBE_VFRTIMER",
+	"IXGBE_VTEICR",
+	"IXGBE_VTEICS",
+	"IXGBE_VTEIMS",
+	"IXGBE_VTEIMC",
+	"IXGBE_VTEIAC",
+	"IXGBE_VTEIAM",
+	"IXGBE_VTEITR",
+	"IXGBE_VTIVAR",
+	"IXGBE_VTIVAR_MISC",
+	"IXGBE_VFRDBAL0",
+	"IXGBE_VFRDBAL1",
+	"IXGBE_VFRDBAH0",
+	"IXGBE_VFRDBAH1",
+	"IXGBE_VFRDLEN0",
+	"IXGBE_VFRDLEN1",
+	"IXGBE_VFRDH0",
+	"IXGBE_VFRDH1",
+	"IXGBE_VFRDT0",
+	"IXGBE_VFRDT1",
+	"IXGBE_VFRXDCTL0",
+	"IXGBE_VFRXDCTL1",
+	"IXGBE_VFSRRCTL0",
+	"IXGBE_VFSRRCTL1",
+	"IXGBE_VFPSRTYPE",
+	"IXGBE_VFTDBAL0",
+	"IXGBE_VFTDBAL1",
+	"IXGBE_VFTDBAH0",
+	"IXGBE_VFTDBAH1",
+	"IXGBE_VFTDLEN0",
+	"IXGBE_VFTDLEN1",
+	"IXGBE_VFTDH0",
+	"IXGBE_VFTDH1",
+	"IXGBE_VFTDT0",
+	"IXGBE_VFTDT1",
+	"IXGBE_VFTXDCTL0",
+	"IXGBE_VFTXDCTL1",
+	"IXGBE_VFTDWBAL0",
+	"IXGBE_VFTDWBAL1",
+	"IXGBE_VFTDWBAH0",
+	"IXGBE_VFTDWBAH1"
+};
+
+
+static int ixgbevf_get_regs_len(struct net_device *netdev)
+{
+	return (ARRAY_SIZE(ixgbevf_reg_names)) * sizeof(u32);
+}
+
+static void ixgbevf_get_regs(struct net_device *netdev,
+			     struct ethtool_regs *regs,
+			     void *p)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 *regs_buff = p;
+	u32 regs_len = ixgbevf_get_regs_len(netdev);
+	u8 i;
+
+	memset(p, 0, regs_len);
+
+	regs->version = (1 << 24) | hw->revision_id << 16 | hw->device_id;
+
+	/* General Registers */
+	regs_buff[0] = IXGBE_READ_REG(hw, IXGBE_VFCTRL);
+	regs_buff[1] = IXGBE_READ_REG(hw, IXGBE_VFSTATUS);
+	regs_buff[2] = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
+	regs_buff[3] = IXGBE_READ_REG(hw, IXGBE_VFRXMEMWRAP);
+	regs_buff[4] = IXGBE_READ_REG(hw, IXGBE_VFRTIMER);
+
+	/* Interrupt */
+	/* don't read EICR because it can clear interrupt causes, instead
+	 * read EICS which is a shadow but doesn't clear EICR */
+	regs_buff[5] = IXGBE_READ_REG(hw, IXGBE_VTEICS);
+	regs_buff[6] = IXGBE_READ_REG(hw, IXGBE_VTEICS);
+	regs_buff[7] = IXGBE_READ_REG(hw, IXGBE_VTEIMS);
+	regs_buff[8] = IXGBE_READ_REG(hw, IXGBE_VTEIMC);
+	regs_buff[9] = IXGBE_READ_REG(hw, IXGBE_VTEIAC);
+	regs_buff[10] = IXGBE_READ_REG(hw, IXGBE_VTEIAM);
+	regs_buff[11] = IXGBE_READ_REG(hw, IXGBE_VTEITR(0));
+	regs_buff[12] = IXGBE_READ_REG(hw, IXGBE_VTIVAR(0));
+	regs_buff[13] = IXGBE_READ_REG(hw, IXGBE_VTIVAR_MISC);
+
+	/* Receive DMA */
+	for (i = 0; i < 2; i++)
+		regs_buff[14 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDBAL(i));
+	for (i = 0; i < 2; i++)
+		regs_buff[16 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDBAH(i));
+	for (i = 0; i < 2; i++)
+		regs_buff[18 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDLEN(i));
+	for (i = 0; i < 2; i++)
+		regs_buff[20 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDH(i));
+	for (i = 0; i < 2; i++)
+		regs_buff[22 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDT(i));
+	for (i = 0; i < 2; i++)
+		regs_buff[24 + i] = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i));
+	for (i = 0; i < 2; i++)
+		regs_buff[26 + i] = IXGBE_READ_REG(hw, IXGBE_VFSRRCTL(i));
+
+	/* Receive */
+	regs_buff[28] = IXGBE_READ_REG(hw, IXGBE_VFPSRTYPE);
+
+	/* Transmit */
+	for (i = 0; i < 2; i++)
+		regs_buff[29 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDBAL(i));
+	for (i = 0; i < 2; i++)
+		regs_buff[31 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDBAH(i));
+	for (i = 0; i < 2; i++)
+		regs_buff[33 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDLEN(i));
+	for (i = 0; i < 2; i++)
+		regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDH(i));
+	for (i = 0; i < 2; i++)
+		regs_buff[37 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDT(i));
+	for (i = 0; i < 2; i++)
+		regs_buff[39 + i] = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i));
+	for (i = 0; i < 2; i++)
+		regs_buff[41 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDWBAL(i));
+	for (i = 0; i < 2; i++)
+		regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDWBAH(i));
+
+	for (i = 0; i < ARRAY_SIZE(ixgbevf_reg_names); i++)
+		hw_dbg(hw, "%s\t%8.8x\n", ixgbevf_reg_names[i], regs_buff[i]);
+}
+
+static void ixgbevf_get_drvinfo(struct net_device *netdev,
+				struct ethtool_drvinfo *drvinfo)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+
+	strlcpy(drvinfo->driver, ixgbevf_driver_name, 32);
+	strlcpy(drvinfo->version, ixgbevf_driver_version, 32);
+
+	strlcpy(drvinfo->fw_version, "N/A", 4);
+	strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+}
+
+static void ixgbevf_get_ringparam(struct net_device *netdev,
+				  struct ethtool_ringparam *ring)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	struct ixgbevf_ring *tx_ring = adapter->tx_ring;
+	struct ixgbevf_ring *rx_ring = adapter->rx_ring;
+
+	ring->rx_max_pending = IXGBEVF_MAX_RXD;
+	ring->tx_max_pending = IXGBEVF_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 ixgbevf_set_ringparam(struct net_device *netdev,
+				 struct ethtool_ringparam *ring)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL;
+	int i, err;
+	u32 new_rx_count, new_tx_count;
+	bool need_tx_update = false;
+	bool need_rx_update = false;
+
+	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
+		return -EINVAL;
+
+	new_rx_count = max(ring->rx_pending, (u32)IXGBEVF_MIN_RXD);
+	new_rx_count = min(new_rx_count, (u32)IXGBEVF_MAX_RXD);
+	new_rx_count = ALIGN(new_rx_count, IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE);
+
+	new_tx_count = max(ring->tx_pending, (u32)IXGBEVF_MIN_TXD);
+	new_tx_count = min(new_tx_count, (u32)IXGBEVF_MAX_TXD);
+	new_tx_count = ALIGN(new_tx_count, IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE);
+
+	if ((new_tx_count == adapter->tx_ring->count) &&
+	    (new_rx_count == adapter->rx_ring->count)) {
+		/* nothing to do */
+		return 0;
+	}
+
+	while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state))
+		msleep(1);
+
+	if (new_tx_count != adapter->tx_ring_count) {
+		tx_ring = kcalloc(adapter->num_tx_queues,
+				  sizeof(struct ixgbevf_ring), GFP_KERNEL);
+		if (!tx_ring) {
+			err = -ENOMEM;
+			goto err_setup;
+		}
+		memcpy(tx_ring, adapter->tx_ring,
+		       adapter->num_tx_queues * sizeof(struct ixgbevf_ring));
+		for (i = 0; i < adapter->num_tx_queues; i++) {
+			tx_ring[i].count = new_tx_count;
+			err = ixgbevf_setup_tx_resources(adapter,
+							 &tx_ring[i]);
+			if (err) {
+				while (i) {
+					i--;
+					ixgbevf_free_tx_resources(adapter,
+								  &tx_ring[i]);
+				}
+				kfree(tx_ring);
+				goto err_setup;
+			}
+			tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;
+		}
+		need_tx_update = true;
+	}
+
+	if (new_rx_count != adapter->rx_ring_count) {
+		rx_ring = kcalloc(adapter->num_rx_queues,
+				  sizeof(struct ixgbevf_ring), GFP_KERNEL);
+		if ((!rx_ring) && (need_tx_update)) {
+			err = -ENOMEM;
+			goto err_rx_setup;
+		}
+		memcpy(rx_ring, adapter->rx_ring,
+		       adapter->num_rx_queues * sizeof(struct ixgbevf_ring));
+		for (i = 0; i < adapter->num_rx_queues; i++) {
+			rx_ring[i].count = new_rx_count;
+			err = ixgbevf_setup_rx_resources(adapter,
+							 &rx_ring[i]);
+			if (err) {
+				while (i) {
+					i--;
+					ixgbevf_free_rx_resources(adapter,
+								  &rx_ring[i]);
+				}
+				kfree(rx_ring);
+				goto err_rx_setup;
+			}
+			rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;
+		}
+		need_rx_update = true;
+	}
+
+err_rx_setup:
+	/* if rings need to be updated, here's the place to do it in one shot */
+	if (need_tx_update || need_rx_update) {
+		if (netif_running(netdev))
+			ixgbevf_down(adapter);
+	}
+
+	/* tx */
+	if (need_tx_update) {
+		kfree(adapter->tx_ring);
+		adapter->tx_ring = tx_ring;
+		tx_ring = NULL;
+		adapter->tx_ring_count = new_tx_count;
+	}
+
+	/* rx */
+	if (need_rx_update) {
+		kfree(adapter->rx_ring);
+		adapter->rx_ring = rx_ring;
+		rx_ring = NULL;
+		adapter->rx_ring_count = new_rx_count;
+	}
+
+	/* success! */
+	err = 0;
+	if (netif_running(netdev))
+		ixgbevf_up(adapter);
+
+err_setup:
+	clear_bit(__IXGBEVF_RESETTING, &adapter->state);
+	return err;
+}
+
+static int ixgbevf_get_sset_count(struct net_device *dev, int stringset)
+{
+       switch (stringset) {
+       case ETH_SS_TEST:
+	       return IXGBE_TEST_LEN;
+       case ETH_SS_STATS:
+	       return IXGBE_GLOBAL_STATS_LEN;
+       default:
+	       return -EINVAL;
+       }
+}
+
+static void ixgbevf_get_ethtool_stats(struct net_device *netdev,
+				      struct ethtool_stats *stats, u64 *data)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	int i;
+
+	ixgbevf_update_stats(adapter);
+	for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
+		char *p = (char *)adapter +
+			ixgbe_gstrings_stats[i].stat_offset;
+		char *b = (char *)adapter +
+			ixgbe_gstrings_stats[i].base_stat_offset;
+		char *r = (char *)adapter +
+			ixgbe_gstrings_stats[i].saved_reset_offset;
+		data[i] = ((ixgbe_gstrings_stats[i].sizeof_stat ==
+			    sizeof(u64)) ? *(u64 *)p : *(u32 *)p) -
+			  ((ixgbe_gstrings_stats[i].sizeof_stat ==
+			    sizeof(u64)) ? *(u64 *)b : *(u32 *)b) +
+			  ((ixgbe_gstrings_stats[i].sizeof_stat ==
+			    sizeof(u64)) ? *(u64 *)r : *(u32 *)r);
+	}
+}
+
+static void ixgbevf_get_strings(struct net_device *netdev, u32 stringset,
+				u8 *data)
+{
+	char *p = (char *)data;
+	int i;
+
+	switch (stringset) {
+	case ETH_SS_TEST:
+		memcpy(data, *ixgbe_gstrings_test,
+		       IXGBE_TEST_LEN * ETH_GSTRING_LEN);
+		break;
+	case ETH_SS_STATS:
+		for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
+			memcpy(p, ixgbe_gstrings_stats[i].stat_string,
+			       ETH_GSTRING_LEN);
+			p += ETH_GSTRING_LEN;
+		}
+		break;
+	}
+}
+
+static int ixgbevf_link_test(struct ixgbevf_adapter *adapter, u64 *data)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	bool link_up;
+	u32 link_speed = 0;
+	*data = 0;
+
+	hw->mac.ops.check_link(hw, &link_speed, &link_up, true);
+	if (!link_up)
+		*data = 1;
+
+	return *data;
+}
+
+/* ethtool register test data */
+struct ixgbevf_reg_test {
+	u16 reg;
+	u8  array_len;
+	u8  test_type;
+	u32 mask;
+	u32 write;
+};
+
+/* In the hardware, registers are laid out either singly, in arrays
+ * spaced 0x40 bytes apart, or in contiguous tables.  We assume
+ * most tests take place on arrays or single registers (handled
+ * as a single-element array) and special-case the tables.
+ * Table tests are always pattern tests.
+ *
+ * We also make provision for some required setup steps by specifying
+ * registers to be written without any read-back testing.
+ */
+
+#define PATTERN_TEST	1
+#define SET_READ_TEST	2
+#define WRITE_NO_TEST	3
+#define TABLE32_TEST	4
+#define TABLE64_TEST_LO	5
+#define TABLE64_TEST_HI	6
+
+/* default VF register test */
+static struct ixgbevf_reg_test reg_test_vf[] = {
+	{ IXGBE_VFRDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 },
+	{ IXGBE_VFRDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+	{ IXGBE_VFRDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
+	{ IXGBE_VFRXDCTL(0), 2, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE },
+	{ IXGBE_VFRDT(0), 2, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+	{ IXGBE_VFRXDCTL(0), 2, WRITE_NO_TEST, 0, 0 },
+	{ IXGBE_VFTDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+	{ IXGBE_VFTDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+	{ IXGBE_VFTDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFF80 },
+	{ 0, 0, 0, 0 }
+};
+
+#define REG_PATTERN_TEST(R, M, W)                                             \
+{                                                                             \
+	u32 pat, val, before;                                                 \
+	const u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \
+	for (pat = 0; pat < ARRAY_SIZE(_test); pat++) {                       \
+		before = readl(adapter->hw.hw_addr + R);                      \
+		writel((_test[pat] & W), (adapter->hw.hw_addr + R));          \
+		val = readl(adapter->hw.hw_addr + R);                         \
+		if (val != (_test[pat] & W & M)) {                            \
+			hw_dbg(&adapter->hw,                                  \
+			"pattern test reg %04X failed: got "                  \
+			"0x%08X expected 0x%08X\n",                           \
+			R, val, (_test[pat] & W & M));                        \
+			*data = R;                                            \
+			writel(before, adapter->hw.hw_addr + R);              \
+			return 1;                                             \
+		}                                                             \
+		writel(before, adapter->hw.hw_addr + R);                      \
+	}                                                                     \
+}
+
+#define REG_SET_AND_CHECK(R, M, W)                                            \
+{                                                                             \
+	u32 val, before;                                                      \
+	before = readl(adapter->hw.hw_addr + R);                              \
+	writel((W & M), (adapter->hw.hw_addr + R));                           \
+	val = readl(adapter->hw.hw_addr + R);                                 \
+	if ((W & M) != (val & M)) {                                           \
+		printk(KERN_ERR "set/check reg %04X test failed: got 0x%08X " \
+				 "expected 0x%08X\n", R, (val & M), (W & M)); \
+		*data = R;                                                    \
+		writel(before, (adapter->hw.hw_addr + R));                    \
+		return 1;                                                     \
+	}                                                                     \
+	writel(before, (adapter->hw.hw_addr + R));                            \
+}
+
+static int ixgbevf_reg_test(struct ixgbevf_adapter *adapter, u64 *data)
+{
+	struct ixgbevf_reg_test *test;
+	u32 i;
+
+	test = reg_test_vf;
+
+	/*
+	 * Perform the register test, looping through the test table
+	 * until we either fail or reach the null entry.
+	 */
+	while (test->reg) {
+		for (i = 0; i < test->array_len; i++) {
+			switch (test->test_type) {
+			case PATTERN_TEST:
+				REG_PATTERN_TEST(test->reg + (i * 0x40),
+						test->mask,
+						test->write);
+				break;
+			case SET_READ_TEST:
+				REG_SET_AND_CHECK(test->reg + (i * 0x40),
+						test->mask,
+						test->write);
+				break;
+			case WRITE_NO_TEST:
+				writel(test->write,
+				       (adapter->hw.hw_addr + test->reg)
+				       + (i * 0x40));
+				break;
+			case TABLE32_TEST:
+				REG_PATTERN_TEST(test->reg + (i * 4),
+						test->mask,
+						test->write);
+				break;
+			case TABLE64_TEST_LO:
+				REG_PATTERN_TEST(test->reg + (i * 8),
+						test->mask,
+						test->write);
+				break;
+			case TABLE64_TEST_HI:
+				REG_PATTERN_TEST((test->reg + 4) + (i * 8),
+						test->mask,
+						test->write);
+				break;
+			}
+		}
+		test++;
+	}
+
+	*data = 0;
+	return *data;
+}
+
+static void ixgbevf_diag_test(struct net_device *netdev,
+			      struct ethtool_test *eth_test, u64 *data)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	bool if_running = netif_running(netdev);
+
+	set_bit(__IXGBEVF_TESTING, &adapter->state);
+	if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
+		/* Offline tests */
+
+		hw_dbg(&adapter->hw, "offline testing starting\n");
+
+		/* Link test performed before hardware reset so autoneg doesn't
+		 * interfere with test result */
+		if (ixgbevf_link_test(adapter, &data[1]))
+			eth_test->flags |= ETH_TEST_FL_FAILED;
+
+		if (if_running)
+			/* indicate we're in test mode */
+			dev_close(netdev);
+		else
+			ixgbevf_reset(adapter);
+
+		hw_dbg(&adapter->hw, "register testing starting\n");
+		if (ixgbevf_reg_test(adapter, &data[0]))
+			eth_test->flags |= ETH_TEST_FL_FAILED;
+
+		ixgbevf_reset(adapter);
+
+		clear_bit(__IXGBEVF_TESTING, &adapter->state);
+		if (if_running)
+			dev_open(netdev);
+	} else {
+		hw_dbg(&adapter->hw, "online testing starting\n");
+		/* Online tests */
+		if (ixgbevf_link_test(adapter, &data[1]))
+			eth_test->flags |= ETH_TEST_FL_FAILED;
+
+		/* Online tests aren't run; pass by default */
+		data[0] = 0;
+
+		clear_bit(__IXGBEVF_TESTING, &adapter->state);
+	}
+	msleep_interruptible(4 * 1000);
+}
+
+static int ixgbevf_nway_reset(struct net_device *netdev)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+
+	if (netif_running(netdev)) {
+		if (!adapter->dev_closed)
+			ixgbevf_reinit_locked(adapter);
+	}
+
+	return 0;
+}
+
+static struct ethtool_ops ixgbevf_ethtool_ops = {
+	.get_settings           = ixgbevf_get_settings,
+	.get_drvinfo            = ixgbevf_get_drvinfo,
+	.get_regs_len           = ixgbevf_get_regs_len,
+	.get_regs               = ixgbevf_get_regs,
+	.nway_reset             = ixgbevf_nway_reset,
+	.get_link               = ethtool_op_get_link,
+	.get_ringparam          = ixgbevf_get_ringparam,
+	.set_ringparam          = ixgbevf_set_ringparam,
+	.get_rx_csum            = ixgbevf_get_rx_csum,
+	.set_rx_csum            = ixgbevf_set_rx_csum,
+	.get_tx_csum            = ethtool_op_get_tx_csum,
+	.set_tx_csum            = ethtool_op_set_tx_ipv6_csum,
+	.get_sg                 = ethtool_op_get_sg,
+	.set_sg                 = ethtool_op_set_sg,
+	.get_msglevel           = ixgbevf_get_msglevel,
+	.set_msglevel           = ixgbevf_set_msglevel,
+	.get_tso                = ethtool_op_get_tso,
+	.set_tso                = ixgbevf_set_tso,
+	.self_test              = ixgbevf_diag_test,
+	.get_sset_count         = ixgbevf_get_sset_count,
+	.get_strings            = ixgbevf_get_strings,
+	.get_ethtool_stats      = ixgbevf_get_ethtool_stats,
+};
+
+void ixgbevf_set_ethtool_ops(struct net_device *netdev)
+{
+	SET_ETHTOOL_OPS(netdev, &ixgbevf_ethtool_ops);
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/ixgbevf.h linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/ixgbevf.h
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/ixgbevf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/ixgbevf.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,318 @@
+/*******************************************************************************
+
+  Intel 82599 Virtual Function 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 _IXGBEVF_H_
+#define _IXGBEVF_H_
+
+#include <linux/types.h>
+#include <linux/timer.h>
+#include <linux/io.h>
+#include <linux/netdevice.h>
+
+#include "vf.h"
+
+/* wrapper around a pointer to a socket buffer,
+ * so a DMA handle can be stored along with the buffer */
+struct ixgbevf_tx_buffer {
+	struct sk_buff *skb;
+	dma_addr_t dma;
+	unsigned long time_stamp;
+	u16 length;
+	u16 next_to_watch;
+	u16 mapped_as_page;
+};
+
+struct ixgbevf_rx_buffer {
+	struct sk_buff *skb;
+	dma_addr_t dma;
+	struct page *page;
+	dma_addr_t page_dma;
+	unsigned int page_offset;
+};
+
+struct ixgbevf_ring {
+	struct ixgbevf_adapter *adapter;  /* backlink */
+	void *desc;			/* descriptor ring memory */
+	dma_addr_t dma;			/* phys. address of descriptor ring */
+	unsigned int size;		/* length in bytes */
+	unsigned int count;		/* amount of descriptors */
+	unsigned int next_to_use;
+	unsigned int next_to_clean;
+
+	int queue_index; /* needed for multiqueue queue management */
+	union {
+		struct ixgbevf_tx_buffer *tx_buffer_info;
+		struct ixgbevf_rx_buffer *rx_buffer_info;
+	};
+
+	u16 head;
+	u16 tail;
+
+	unsigned int total_bytes;
+	unsigned int total_packets;
+
+	u16 reg_idx; /* holds the special value that gets the hardware register
+		      * offset associated with this ring, which is different
+		      * for DCB and RSS modes */
+
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+	/* cpu for tx queue */
+	int cpu;
+#endif
+
+	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;
+};
+
+enum ixgbevf_ring_f_enum {
+	RING_F_NONE = 0,
+	RING_F_ARRAY_SIZE      /* must be last in enum set */
+};
+
+struct ixgbevf_ring_feature {
+	int indices;
+	int mask;
+};
+
+/* How many Rx Buffers do we bundle into one write to the hardware ? */
+#define IXGBEVF_RX_BUFFER_WRITE	16	/* Must be power of 2 */
+
+#define MAX_RX_QUEUES 1
+#define MAX_TX_QUEUES 1
+
+#define IXGBEVF_DEFAULT_TXD   1024
+#define IXGBEVF_DEFAULT_RXD   512
+#define IXGBEVF_MAX_TXD       4096
+#define IXGBEVF_MIN_TXD       64
+#define IXGBEVF_MAX_RXD       4096
+#define IXGBEVF_MIN_RXD       64
+
+/* Supported Rx Buffer Sizes */
+#define IXGBEVF_RXBUFFER_64    64     /* Used for packet split */
+#define IXGBEVF_RXBUFFER_128   128    /* Used for packet split */
+#define IXGBEVF_RXBUFFER_256   256    /* Used for packet split */
+#define IXGBEVF_RXBUFFER_2048  2048
+#define IXGBEVF_MAX_RXBUFFER   16384  /* largest size for single descriptor */
+
+#define IXGBEVF_RX_HDR_SIZE IXGBEVF_RXBUFFER_256
+
+#define MAXIMUM_ETHERNET_VLAN_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)
+
+#define IXGBE_TX_FLAGS_CSUM		(u32)(1)
+#define IXGBE_TX_FLAGS_VLAN		(u32)(1 << 1)
+#define IXGBE_TX_FLAGS_TSO		(u32)(1 << 2)
+#define IXGBE_TX_FLAGS_IPV4		(u32)(1 << 3)
+#define IXGBE_TX_FLAGS_FCOE		(u32)(1 << 4)
+#define IXGBE_TX_FLAGS_FSO		(u32)(1 << 5)
+#define IXGBE_TX_FLAGS_VLAN_MASK	0xffff0000
+#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK	0x0000e000
+#define IXGBE_TX_FLAGS_VLAN_SHIFT	16
+
+/* MAX_MSIX_Q_VECTORS of these are allocated,
+ * but we only use one per queue-specific vector.
+ */
+struct ixgbevf_q_vector {
+	struct ixgbevf_adapter *adapter;
+	struct napi_struct napi;
+	DECLARE_BITMAP(rxr_idx, MAX_RX_QUEUES); /* Rx ring indices */
+	DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */
+	u8 rxr_count;     /* Rx ring count assigned to this vector */
+	u8 txr_count;     /* Tx ring count assigned to this vector */
+	u8 tx_itr;
+	u8 rx_itr;
+	u32 eitr;
+	int v_idx;	  /* vector index in list */
+};
+
+/* Helper macros to switch between ints/sec and what the register uses.
+ * 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)) : 8)
+#define EITR_REG_TO_INTS_PER_SEC EITR_INTS_PER_SEC_TO_REG
+
+#define IXGBE_DESC_UNUSED(R) \
+	((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
+	(R)->next_to_clean - (R)->next_to_use - 1)
+
+#define IXGBE_RX_DESC_ADV(R, i)	    \
+	(&(((union ixgbe_adv_rx_desc *)((R).desc))[i]))
+#define IXGBE_TX_DESC_ADV(R, i)	    \
+	(&(((union ixgbe_adv_tx_desc *)((R).desc))[i]))
+#define IXGBE_TX_CTXTDESC_ADV(R, i)	    \
+	(&(((struct ixgbe_adv_tx_context_desc *)((R).desc))[i]))
+
+#define IXGBE_MAX_JUMBO_FRAME_SIZE        16128
+
+#define OTHER_VECTOR 1
+#define NON_Q_VECTORS (OTHER_VECTOR)
+
+#define MAX_MSIX_Q_VECTORS 2
+#define MAX_MSIX_COUNT 2
+
+#define MIN_MSIX_Q_VECTORS 2
+#define MIN_MSIX_COUNT (MIN_MSIX_Q_VECTORS + NON_Q_VECTORS)
+
+/* board specific private data structure */
+struct ixgbevf_adapter {
+	struct timer_list watchdog_timer;
+#ifdef NETIF_F_HW_VLAN_TX
+	struct vlan_group *vlgrp;
+#endif
+	u16 bd_number;
+	struct work_struct reset_task;
+	struct ixgbevf_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
+	char name[MAX_MSIX_COUNT][IFNAMSIZ + 9];
+
+	/* Interrupt Throttle Rate */
+	u32 itr_setting;
+	u16 eitr_low;
+	u16 eitr_high;
+
+	/* TX */
+	struct ixgbevf_ring *tx_ring;	/* One per active queue */
+	int num_tx_queues;
+	u64 restart_queue;
+	u64 hw_csum_tx_good;
+	u64 lsc_int;
+	u64 hw_tso_ctxt;
+	u64 hw_tso6_ctxt;
+	u32 tx_timeout_count;
+	bool detect_tx_hung;
+
+	/* RX */
+	struct ixgbevf_ring *rx_ring;	/* One per active queue */
+	int num_rx_queues;
+	int num_rx_pools;               /* == num_rx_queues in 82598 */
+	int num_rx_queues_per_pool;	/* 1 if 82598, can be many if 82599 */
+	u64 hw_csum_rx_error;
+	u64 hw_rx_no_dma_resources;
+	u64 hw_csum_rx_good;
+	u64 non_eop_descs;
+	int num_msix_vectors;
+	int max_msix_q_vectors;         /* true count of q_vectors for device */
+	struct ixgbevf_ring_feature ring_feature[RING_F_ARRAY_SIZE];
+	struct msix_entry *msix_entries;
+
+	u64 rx_hdr_split;
+	u32 alloc_rx_page_failed;
+	u32 alloc_rx_buff_failed;
+
+	/* Some features need tri-state capability,
+	 * thus the additional *_CAPABLE flags.
+	 */
+	u32 flags;
+#define IXGBE_FLAG_RX_CSUM_ENABLED              (u32)(1)
+#define IXGBE_FLAG_RX_1BUF_CAPABLE              (u32)(1 << 1)
+#define IXGBE_FLAG_RX_PS_CAPABLE                (u32)(1 << 2)
+#define IXGBE_FLAG_RX_PS_ENABLED                (u32)(1 << 3)
+#define IXGBE_FLAG_IN_NETPOLL                   (u32)(1 << 4)
+#define IXGBE_FLAG_IMIR_ENABLED                 (u32)(1 << 5)
+#define IXGBE_FLAG_MQ_CAPABLE                   (u32)(1 << 6)
+#define IXGBE_FLAG_NEED_LINK_UPDATE             (u32)(1 << 7)
+#define IXGBE_FLAG_IN_WATCHDOG_TASK             (u32)(1 << 8)
+	/* OS defined structs */
+	struct net_device *netdev;
+	struct pci_dev *pdev;
+	struct net_device_stats net_stats;
+
+	/* structs defined in ixgbe_vf.h */
+	struct ixgbe_hw hw;
+	u16 msg_enable;
+	struct ixgbevf_hw_stats stats;
+	u64 zero_base;
+	/* Interrupt Throttle Rate */
+	u32 eitr_param;
+
+	unsigned long state;
+	u32 *config_space;
+	u64 tx_busy;
+	unsigned int tx_ring_count;
+	unsigned int rx_ring_count;
+
+	u32 link_speed;
+	bool link_up;
+	unsigned long link_check_timeout;
+
+	struct work_struct watchdog_task;
+	bool netdev_registered;
+	bool dev_closed;
+};
+
+enum ixbgevf_state_t {
+	__IXGBEVF_TESTING,
+	__IXGBEVF_RESETTING,
+	__IXGBEVF_DOWN
+};
+
+enum ixgbevf_boards {
+	board_82599_vf,
+};
+
+extern struct ixgbevf_info ixgbevf_vf_info;
+extern struct ixgbe_mac_operations ixgbevf_mbx_ops;
+
+/* needed by ethtool.c */
+extern char ixgbevf_driver_name[];
+extern const char ixgbevf_driver_version[];
+
+extern int ixgbevf_up(struct ixgbevf_adapter *adapter);
+extern void ixgbevf_down(struct ixgbevf_adapter *adapter);
+extern void ixgbevf_reinit_locked(struct ixgbevf_adapter *adapter);
+extern void ixgbevf_reset(struct ixgbevf_adapter *adapter);
+extern void ixgbevf_set_ethtool_ops(struct net_device *netdev);
+extern int ixgbevf_setup_rx_resources(struct ixgbevf_adapter *,
+				      struct ixgbevf_ring *);
+extern int ixgbevf_setup_tx_resources(struct ixgbevf_adapter *,
+				      struct ixgbevf_ring *);
+extern void ixgbevf_free_rx_resources(struct ixgbevf_adapter *,
+				      struct ixgbevf_ring *);
+extern void ixgbevf_free_tx_resources(struct ixgbevf_adapter *,
+				      struct ixgbevf_ring *);
+extern void ixgbevf_update_stats(struct ixgbevf_adapter *adapter);
+
+#ifdef ETHTOOL_OPS_COMPAT
+extern int ethtool_ioctl(struct ifreq *ifr);
+
+#endif
+extern void ixgbe_napi_add_all(struct ixgbevf_adapter *adapter);
+extern void ixgbe_napi_del_all(struct ixgbevf_adapter *adapter);
+
+#ifdef DEBUG
+extern char *ixgbevf_get_hw_dev_name(struct ixgbe_hw *hw);
+#define hw_dbg(hw, format, arg...) \
+	printk(KERN_DEBUG "%s: " format, ixgbevf_get_hw_dev_name(hw), ##arg)
+#else
+#define hw_dbg(hw, format, arg...) do {} while (0)
+#endif
+
+#endif /* _IXGBEVF_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/ixgbevf_main.c linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/ixgbevf_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/ixgbevf_main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/ixgbevf_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,3600 @@
+/*******************************************************************************
+
+  Intel 82599 Virtual Function 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
+
+*******************************************************************************/
+
+
+/******************************************************************************
+ Copyright (c)2006 - 2007 Myricom, Inc. for some LRO specific code
+******************************************************************************/
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/vmalloc.h>
+#include <linux/string.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/ipv6.h>
+#include <linux/slab.h>
+#include <net/checksum.h>
+#include <net/ip6_checksum.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+
+#include "ixgbevf.h"
+
+char ixgbevf_driver_name[] = "ixgbevf";
+static const char ixgbevf_driver_string[] =
+	"Intel(R) 82599 Virtual Function";
+
+#define DRV_VERSION "1.0.0-k0"
+const char ixgbevf_driver_version[] = DRV_VERSION;
+static char ixgbevf_copyright[] = "Copyright (c) 2009 Intel Corporation.";
+
+static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
+	[board_82599_vf] = &ixgbevf_vf_info,
+};
+
+/* ixgbevf_pci_tbl - PCI Device ID Table
+ *
+ * Wildcard entries (PCI_ANY_ID) should come last
+ * Last entry must be all 0s
+ *
+ * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
+ *   Class, Class Mask, private data (not used) }
+ */
+static struct pci_device_id ixgbevf_pci_tbl[] = {
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF),
+	board_82599_vf},
+
+	/* required last entry */
+	{0, }
+};
+MODULE_DEVICE_TABLE(pci, ixgbevf_pci_tbl);
+
+MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
+MODULE_DESCRIPTION("Intel(R) 82599 Virtual Function Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+#define DEFAULT_DEBUG_LEVEL_SHIFT 3
+
+/* forward decls */
+static void ixgbevf_set_itr_msix(struct ixgbevf_q_vector *q_vector);
+static void ixgbevf_write_eitr(struct ixgbevf_adapter *adapter, int v_idx,
+			       u32 itr_reg);
+
+static inline void ixgbevf_release_rx_desc(struct ixgbe_hw *hw,
+					   struct ixgbevf_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_VFRDT(rx_ring->reg_idx), val);
+}
+
+/*
+ * 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 ixgbevf_set_ivar(struct ixgbevf_adapter *adapter, s8 direction,
+			     u8 queue, u8 msix_vector)
+{
+	u32 ivar, index;
+	struct ixgbe_hw *hw = &adapter->hw;
+	if (direction == -1) {
+		/* other causes */
+		msix_vector |= IXGBE_IVAR_ALLOC_VAL;
+		ivar = IXGBE_READ_REG(hw, IXGBE_VTIVAR_MISC);
+		ivar &= ~0xFF;
+		ivar |= msix_vector;
+		IXGBE_WRITE_REG(hw, IXGBE_VTIVAR_MISC, ivar);
+	} else {
+		/* tx or rx causes */
+		msix_vector |= IXGBE_IVAR_ALLOC_VAL;
+		index = ((16 * (queue & 1)) + (8 * direction));
+		ivar = IXGBE_READ_REG(hw, IXGBE_VTIVAR(queue >> 1));
+		ivar &= ~(0xFF << index);
+		ivar |= (msix_vector << index);
+		IXGBE_WRITE_REG(hw, IXGBE_VTIVAR(queue >> 1), ivar);
+	}
+}
+
+static void ixgbevf_unmap_and_free_tx_resource(struct ixgbevf_adapter *adapter,
+					       struct ixgbevf_tx_buffer
+					       *tx_buffer_info)
+{
+	if (tx_buffer_info->dma) {
+		if (tx_buffer_info->mapped_as_page)
+			pci_unmap_page(adapter->pdev,
+				       tx_buffer_info->dma,
+				       tx_buffer_info->length,
+				       PCI_DMA_TODEVICE);
+		else
+			pci_unmap_single(adapter->pdev,
+					 tx_buffer_info->dma,
+					 tx_buffer_info->length,
+					 PCI_DMA_TODEVICE);
+		tx_buffer_info->dma = 0;
+	}
+	if (tx_buffer_info->skb) {
+		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 */
+}
+
+static inline bool ixgbevf_check_tx_hang(struct ixgbevf_adapter *adapter,
+					 struct ixgbevf_ring *tx_ring,
+					 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 = readl(hw->hw_addr + tx_ring->head);
+	tail = readl(hw->hw_addr + tx_ring->tail);
+	adapter->detect_tx_hung = false;
+	if ((head != tail) &&
+	    tx_ring->tx_buffer_info[eop].time_stamp &&
+	    time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ)) {
+		/* detected Tx unit hang */
+		union ixgbe_adv_tx_desc *tx_desc;
+		tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
+		printk(KERN_ERR "Detected Tx Unit Hang\n"
+		       "  Tx Queue             <%d>\n"
+		       "  TDH, TDT             <%x>, <%x>\n"
+		       "  next_to_use          <%x>\n"
+		       "  next_to_clean        <%x>\n"
+		       "tx_buffer_info[next_to_clean]\n"
+		       "  time_stamp           <%lx>\n"
+		       "  jiffies              <%lx>\n",
+		       tx_ring->queue_index,
+		       head, tail,
+		       tx_ring->next_to_use, eop,
+		       tx_ring->tx_buffer_info[eop].time_stamp, jiffies);
+		return true;
+	}
+
+	return false;
+}
+
+#define IXGBE_MAX_TXD_PWR	14
+#define IXGBE_MAX_DATA_PER_TXD	(1 << IXGBE_MAX_TXD_PWR)
+
+/* Tx Descriptors needed, worst case */
+#define TXD_USE_COUNT(S) (((S) >> IXGBE_MAX_TXD_PWR) + \
+			 (((S) & (IXGBE_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
+#ifdef MAX_SKB_FRAGS
+#define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
+	MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1)      /* for context */
+#else
+#define DESC_NEEDED TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD)
+#endif
+
+static void ixgbevf_tx_timeout(struct net_device *netdev);
+
+/**
+ * ixgbevf_clean_tx_irq - Reclaim resources after transmit completes
+ * @adapter: board private structure
+ * @tx_ring: tx ring to clean
+ **/
+static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter,
+				 struct ixgbevf_ring *tx_ring)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct ixgbe_hw *hw = &adapter->hw;
+	union ixgbe_adv_tx_desc *tx_desc, *eop_desc;
+	struct ixgbevf_tx_buffer *tx_buffer_info;
+	unsigned int i, eop, count = 0;
+	unsigned int total_bytes = 0, total_packets = 0;
+
+	i = tx_ring->next_to_clean;
+	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 (cleaned && 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;
+			}
+
+			ixgbevf_unmap_and_free_tx_resource(adapter,
+							   tx_buffer_info);
+
+			tx_desc->wb.status = 0;
+
+			i++;
+			if (i == tx_ring->count)
+				i = 0;
+		}
+
+		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)
+	if (unlikely(count && netif_carrier_ok(netdev) &&
+		     (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) {
+		/* Make sure that anybody stopping the queue after this
+		 * sees the new next_to_clean.
+		 */
+		smp_mb();
+#ifdef HAVE_TX_MQ
+		if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
+		    !test_bit(__IXGBEVF_DOWN, &adapter->state)) {
+			netif_wake_subqueue(netdev, tx_ring->queue_index);
+			++adapter->restart_queue;
+		}
+#else
+		if (netif_queue_stopped(netdev) &&
+		    !test_bit(__IXGBEVF_DOWN, &adapter->state)) {
+			netif_wake_queue(netdev);
+			++adapter->restart_queue;
+		}
+#endif
+	}
+
+	if (adapter->detect_tx_hung) {
+		if (ixgbevf_check_tx_hang(adapter, tx_ring, i)) {
+			/* schedule immediate reset if we believe we hung */
+			printk(KERN_INFO
+			       "tx hang %d detected, resetting adapter\n",
+			       adapter->tx_timeout_count + 1);
+			ixgbevf_tx_timeout(adapter->netdev);
+		}
+	}
+
+	/* re-arm the interrupt */
+	if ((count >= tx_ring->work_limit) &&
+	    (!test_bit(__IXGBEVF_DOWN, &adapter->state))) {
+		IXGBE_WRITE_REG(hw, IXGBE_VTEICS, tx_ring->v_idx);
+	}
+
+	tx_ring->total_bytes += total_bytes;
+	tx_ring->total_packets += total_packets;
+
+	adapter->net_stats.tx_bytes += total_bytes;
+	adapter->net_stats.tx_packets += total_packets;
+
+	return (count < tx_ring->work_limit);
+}
+
+/**
+ * ixgbevf_receive_skb - Send a completed packet up the stack
+ * @q_vector: structure containing interrupt and ring information
+ * @skb: packet to send up
+ * @status: hardware indication of status of receive
+ * @rx_ring: rx descriptor ring (for a specific queue) to setup
+ * @rx_desc: rx descriptor
+ **/
+static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector,
+				struct sk_buff *skb, u8 status,
+				struct ixgbevf_ring *ring,
+				union ixgbe_adv_rx_desc *rx_desc)
+{
+	struct ixgbevf_adapter *adapter = q_vector->adapter;
+	bool is_vlan = (status & IXGBE_RXD_STAT_VP);
+	u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
+	int ret;
+
+	if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
+		if (adapter->vlgrp && is_vlan)
+			vlan_gro_receive(&q_vector->napi,
+					 adapter->vlgrp,
+					 tag, skb);
+		else
+			napi_gro_receive(&q_vector->napi, skb);
+	} else {
+		if (adapter->vlgrp && is_vlan)
+			ret = vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
+		else
+			ret = netif_rx(skb);
+	}
+}
+
+/**
+ * ixgbevf_rx_checksum - indicate in skb if hw indicated a good cksum
+ * @adapter: address of board private structure
+ * @status_err: hardware indication of status of receive
+ * @skb: skb currently being received and modified
+ **/
+static inline void ixgbevf_rx_checksum(struct ixgbevf_adapter *adapter,
+				       u32 status_err, struct sk_buff *skb)
+{
+	skb->ip_summed = CHECKSUM_NONE;
+
+	/* Rx csum disabled */
+	if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED))
+		return;
+
+	/* if IP and error */
+	if ((status_err & IXGBE_RXD_STAT_IPCS) &&
+	    (status_err & IXGBE_RXDADV_ERR_IPE)) {
+		adapter->hw_csum_rx_error++;
+		return;
+	}
+
+	if (!(status_err & IXGBE_RXD_STAT_L4CS))
+		return;
+
+	if (status_err & IXGBE_RXDADV_ERR_TCPE) {
+		adapter->hw_csum_rx_error++;
+		return;
+	}
+
+	/* It must be a TCP or UDP packet with a valid checksum */
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+	adapter->hw_csum_rx_good++;
+}
+
+/**
+ * ixgbevf_alloc_rx_buffers - Replace used receive buffers; packet split
+ * @adapter: address of board private structure
+ **/
+static void ixgbevf_alloc_rx_buffers(struct ixgbevf_adapter *adapter,
+				     struct ixgbevf_ring *rx_ring,
+				     int cleaned_count)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	union ixgbe_adv_rx_desc *rx_desc;
+	struct ixgbevf_rx_buffer *bi;
+	struct sk_buff *skb;
+	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];
+
+	while (cleaned_count--) {
+		rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
+
+		if (!bi->page_dma &&
+		    (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)) {
+			if (!bi->page) {
+				bi->page = netdev_alloc_page(adapter->netdev);
+				if (!bi->page) {
+					adapter->alloc_rx_page_failed++;
+					goto no_buffers;
+				}
+				bi->page_offset = 0;
+			} else {
+				/* use a half page if we're re-using */
+				bi->page_offset ^= (PAGE_SIZE / 2);
+			}
+
+			bi->page_dma = pci_map_page(pdev, bi->page,
+						    bi->page_offset,
+						    (PAGE_SIZE / 2),
+						    PCI_DMA_FROMDEVICE);
+		}
+
+		skb = bi->skb;
+		if (!skb) {
+			skb = netdev_alloc_skb(adapter->netdev,
+							       bufsz);
+
+			if (!skb) {
+				adapter->alloc_rx_buff_failed++;
+				goto no_buffers;
+			}
+
+			/*
+			 * Make buffer alignment 2 beyond a 16 byte boundary
+			 * this will result in a 16 byte aligned IP header after
+			 * the 14 byte MAC header is removed
+			 */
+			skb_reserve(skb, NET_IP_ALIGN);
+
+			bi->skb = skb;
+		}
+		if (!bi->dma) {
+			bi->dma = pci_map_single(pdev, skb->data,
+						 rx_ring->rx_buf_len,
+						 PCI_DMA_FROMDEVICE);
+		}
+		/* Refresh the desc even if buffer_addrs didn't change because
+		 * each write-back erases this info. */
+		if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+			rx_desc->read.pkt_addr = cpu_to_le64(bi->page_dma);
+			rx_desc->read.hdr_addr = cpu_to_le64(bi->dma);
+		} else {
+			rx_desc->read.pkt_addr = cpu_to_le64(bi->dma);
+		}
+
+		i++;
+		if (i == rx_ring->count)
+			i = 0;
+		bi = &rx_ring->rx_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);
+
+		ixgbevf_release_rx_desc(&adapter->hw, rx_ring, i);
+	}
+}
+
+static inline void ixgbevf_irq_enable_queues(struct ixgbevf_adapter *adapter,
+					     u64 qmask)
+{
+	u32 mask;
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	mask = (qmask & 0xFFFFFFFF);
+	IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
+}
+
+static inline u16 ixgbevf_get_hdr_info(union ixgbe_adv_rx_desc *rx_desc)
+{
+	return rx_desc->wb.lower.lo_dword.hs_rss.hdr_info;
+}
+
+static inline u16 ixgbevf_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc)
+{
+	return rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
+}
+
+static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
+				 struct ixgbevf_ring *rx_ring,
+				 int *work_done, int work_to_do)
+{
+	struct ixgbevf_adapter *adapter = q_vector->adapter;
+	struct pci_dev *pdev = adapter->pdev;
+	union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
+	struct ixgbevf_rx_buffer *rx_buffer_info, *next_buffer;
+	struct sk_buff *skb;
+	unsigned int i;
+	u32 len, staterr;
+	u16 hdr_info;
+	bool cleaned = false;
+	int cleaned_count = 0;
+	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
+
+	i = rx_ring->next_to_clean;
+	rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
+	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+	rx_buffer_info = &rx_ring->rx_buffer_info[i];
+
+	while (staterr & IXGBE_RXD_STAT_DD) {
+		u32 upper_len = 0;
+		if (*work_done >= work_to_do)
+			break;
+		(*work_done)++;
+
+		if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+			hdr_info = le16_to_cpu(ixgbevf_get_hdr_info(rx_desc));
+			len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
+			       IXGBE_RXDADV_HDRBUFLEN_SHIFT;
+			if (hdr_info & IXGBE_RXDADV_SPH)
+				adapter->rx_hdr_split++;
+			if (len > IXGBEVF_RX_HDR_SIZE)
+				len = IXGBEVF_RX_HDR_SIZE;
+			upper_len = le16_to_cpu(rx_desc->wb.upper.length);
+		} else {
+			len = le16_to_cpu(rx_desc->wb.upper.length);
+		}
+		cleaned = true;
+		skb = rx_buffer_info->skb;
+		prefetch(skb->data - NET_IP_ALIGN);
+		rx_buffer_info->skb = NULL;
+
+		if (rx_buffer_info->dma) {
+			pci_unmap_single(pdev, rx_buffer_info->dma,
+					 rx_ring->rx_buf_len,
+					 PCI_DMA_FROMDEVICE);
+			rx_buffer_info->dma = 0;
+			skb_put(skb, len);
+		}
+
+		if (upper_len) {
+			pci_unmap_page(pdev, rx_buffer_info->page_dma,
+				       PAGE_SIZE / 2, PCI_DMA_FROMDEVICE);
+			rx_buffer_info->page_dma = 0;
+			skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
+					   rx_buffer_info->page,
+					   rx_buffer_info->page_offset,
+					   upper_len);
+
+			if ((rx_ring->rx_buf_len > (PAGE_SIZE / 2)) ||
+			    (page_count(rx_buffer_info->page) != 1))
+				rx_buffer_info->page = NULL;
+			else
+				get_page(rx_buffer_info->page);
+
+			skb->len += upper_len;
+			skb->data_len += upper_len;
+			skb->truesize += upper_len;
+		}
+
+		i++;
+		if (i == rx_ring->count)
+			i = 0;
+
+		next_rxd = IXGBE_RX_DESC_ADV(*rx_ring, i);
+		prefetch(next_rxd);
+		cleaned_count++;
+
+		next_buffer = &rx_ring->rx_buffer_info[i];
+
+		if (!(staterr & IXGBE_RXD_STAT_EOP)) {
+			if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+				rx_buffer_info->skb = next_buffer->skb;
+				rx_buffer_info->dma = next_buffer->dma;
+				next_buffer->skb = skb;
+				next_buffer->dma = 0;
+			} else {
+				skb->next = next_buffer->skb;
+				skb->next->prev = skb;
+			}
+			adapter->non_eop_descs++;
+			goto next_desc;
+		}
+
+		/* ERR_MASK will only have valid bits if EOP set */
+		if (unlikely(staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK)) {
+			dev_kfree_skb_irq(skb);
+			goto next_desc;
+		}
+
+		ixgbevf_rx_checksum(adapter, staterr, skb);
+
+		/* probably a little skewed due to removing CRC */
+		total_rx_bytes += skb->len;
+		total_rx_packets++;
+
+		/*
+		 * Work around issue of some types of VM to VM loop back
+		 * packets not getting split correctly
+		 */
+		if (staterr & IXGBE_RXD_STAT_LB) {
+			u32 header_fixup_len = skb->len - skb->data_len;
+			if (header_fixup_len < 14)
+				skb_push(skb, header_fixup_len);
+		}
+		skb->protocol = eth_type_trans(skb, adapter->netdev);
+
+		ixgbevf_receive_skb(q_vector, skb, staterr, rx_ring, rx_desc);
+		adapter->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 >= IXGBEVF_RX_BUFFER_WRITE) {
+			ixgbevf_alloc_rx_buffers(adapter, rx_ring,
+						 cleaned_count);
+			cleaned_count = 0;
+		}
+
+		/* use prefetched values */
+		rx_desc = next_rxd;
+		rx_buffer_info = &rx_ring->rx_buffer_info[i];
+
+		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+	}
+
+	rx_ring->next_to_clean = i;
+	cleaned_count = IXGBE_DESC_UNUSED(rx_ring);
+
+	if (cleaned_count)
+		ixgbevf_alloc_rx_buffers(adapter, rx_ring, cleaned_count);
+
+	rx_ring->total_packets += total_rx_packets;
+	rx_ring->total_bytes += total_rx_bytes;
+	adapter->net_stats.rx_bytes += total_rx_bytes;
+	adapter->net_stats.rx_packets += total_rx_packets;
+
+	return cleaned;
+}
+
+/**
+ * ixgbevf_clean_rxonly - msix (aka one shot) rx clean routine
+ * @napi: napi struct with our devices info in it
+ * @budget: amount of work driver is allowed to do this pass, in packets
+ *
+ * This function is optimized for cleaning one queue only on a single
+ * q_vector!!!
+ **/
+static int ixgbevf_clean_rxonly(struct napi_struct *napi, int budget)
+{
+	struct ixgbevf_q_vector *q_vector =
+		container_of(napi, struct ixgbevf_q_vector, napi);
+	struct ixgbevf_adapter *adapter = q_vector->adapter;
+	struct ixgbevf_ring *rx_ring = NULL;
+	int work_done = 0;
+	long r_idx;
+
+	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+	rx_ring = &(adapter->rx_ring[r_idx]);
+
+	ixgbevf_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
+
+	/* If all Rx work done, exit the polling mode */
+	if (work_done < budget) {
+		napi_complete(napi);
+		if (adapter->itr_setting & 1)
+			ixgbevf_set_itr_msix(q_vector);
+		if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
+			ixgbevf_irq_enable_queues(adapter, rx_ring->v_idx);
+	}
+
+	return work_done;
+}
+
+/**
+ * ixgbevf_clean_rxonly_many - msix (aka one shot) rx clean routine
+ * @napi: napi struct with our devices info in it
+ * @budget: amount of work driver is allowed to do this pass, in packets
+ *
+ * This function will clean more than one rx queue associated with a
+ * q_vector.
+ **/
+static int ixgbevf_clean_rxonly_many(struct napi_struct *napi, int budget)
+{
+	struct ixgbevf_q_vector *q_vector =
+		container_of(napi, struct ixgbevf_q_vector, napi);
+	struct ixgbevf_adapter *adapter = q_vector->adapter;
+	struct ixgbevf_ring *rx_ring = NULL;
+	int work_done = 0, i;
+	long r_idx;
+	u64 enable_mask = 0;
+
+	/* attempt to distribute budget to each queue fairly, but don't allow
+	 * the budget to go below 1 because we'll exit polling */
+	budget /= (q_vector->rxr_count ?: 1);
+	budget = max(budget, 1);
+	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+	for (i = 0; i < q_vector->rxr_count; i++) {
+		rx_ring = &(adapter->rx_ring[r_idx]);
+		ixgbevf_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);
+	}
+
+#ifndef HAVE_NETDEV_NAPI_LIST
+	if (!netif_running(adapter->netdev))
+		work_done = 0;
+
+#endif
+	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+	rx_ring = &(adapter->rx_ring[r_idx]);
+
+	/* If all Rx work done, exit the polling mode */
+	if (work_done < budget) {
+		napi_complete(napi);
+		if (adapter->itr_setting & 1)
+			ixgbevf_set_itr_msix(q_vector);
+		if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
+			ixgbevf_irq_enable_queues(adapter, enable_mask);
+	}
+
+	return work_done;
+}
+
+
+/**
+ * ixgbevf_configure_msix - Configure MSI-X hardware
+ * @adapter: board private structure
+ *
+ * ixgbevf_configure_msix sets up the hardware to properly generate MSI-X
+ * interrupts.
+ **/
+static void ixgbevf_configure_msix(struct ixgbevf_adapter *adapter)
+{
+	struct ixgbevf_q_vector *q_vector;
+	struct ixgbe_hw *hw = &adapter->hw;
+	int i, j, q_vectors, v_idx, r_idx;
+	u32 mask;
+
+	q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+
+	/*
+	 * Populate the IVAR table and set the ITR values to the
+	 * corresponding register.
+	 */
+	for (v_idx = 0; v_idx < q_vectors; v_idx++) {
+		q_vector = adapter->q_vector[v_idx];
+		/* XXX for_each_set_bit(...) */
+		r_idx = find_first_bit(q_vector->rxr_idx,
+				       adapter->num_rx_queues);
+
+		for (i = 0; i < q_vector->rxr_count; i++) {
+			j = adapter->rx_ring[r_idx].reg_idx;
+			ixgbevf_set_ivar(adapter, 0, j, v_idx);
+			r_idx = find_next_bit(q_vector->rxr_idx,
+					      adapter->num_rx_queues,
+					      r_idx + 1);
+		}
+		r_idx = find_first_bit(q_vector->txr_idx,
+				       adapter->num_tx_queues);
+
+		for (i = 0; i < q_vector->txr_count; i++) {
+			j = adapter->tx_ring[r_idx].reg_idx;
+			ixgbevf_set_ivar(adapter, 1, j, v_idx);
+			r_idx = find_next_bit(q_vector->txr_idx,
+					      adapter->num_tx_queues,
+					      r_idx + 1);
+		}
+
+		/* 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 if (q_vector->rxr_count)
+			/* rx only */
+			q_vector->eitr = adapter->eitr_param;
+
+		ixgbevf_write_eitr(adapter, v_idx, q_vector->eitr);
+	}
+
+	ixgbevf_set_ivar(adapter, -1, 1, v_idx);
+
+	/* set up to autoclear timer, and the vectors */
+	mask = IXGBE_EIMS_ENABLE_MASK;
+	mask &= ~IXGBE_EIMS_OTHER;
+	IXGBE_WRITE_REG(hw, IXGBE_VTEIAC, mask);
+}
+
+enum latency_range {
+	lowest_latency = 0,
+	low_latency = 1,
+	bulk_latency = 2,
+	latency_invalid = 255
+};
+
+/**
+ * ixgbevf_update_itr - update the dynamic ITR value based on statistics
+ * @adapter: pointer to adapter
+ * @eitr: eitr setting (ints per sec) to give last timeslice
+ * @itr_setting: current throttle rate in ints/second
+ * @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.
+ **/
+static u8 ixgbevf_update_itr(struct ixgbevf_adapter *adapter,
+			     u32 eitr, u8 itr_setting,
+			     int packets, int bytes)
+{
+	unsigned int retval = itr_setting;
+	u32 timepassed_us;
+	u64 bytes_perint;
+
+	if (packets == 0)
+		goto update_itr_done;
+
+
+	/* simple throttlerate management
+	 *    0-20MB/s lowest (100000 ints/s)
+	 *   20-100MB/s low   (20000 ints/s)
+	 *  100-1249MB/s bulk (8000 ints/s)
+	 */
+	/* what was last interrupt timeslice? */
+	timepassed_us = 1000000/eitr;
+	bytes_perint = bytes / timepassed_us; /* bytes/usec */
+
+	switch (itr_setting) {
+	case lowest_latency:
+		if (bytes_perint > adapter->eitr_low)
+			retval = low_latency;
+		break;
+	case low_latency:
+		if (bytes_perint > adapter->eitr_high)
+			retval = bulk_latency;
+		else if (bytes_perint <= adapter->eitr_low)
+			retval = lowest_latency;
+		break;
+	case bulk_latency:
+		if (bytes_perint <= adapter->eitr_high)
+			retval = low_latency;
+		break;
+	}
+
+update_itr_done:
+	return retval;
+}
+
+/**
+ * ixgbevf_write_eitr - write VTEITR 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 VTEITR registers at runtime.  Hardware
+ * specific quirks/differences are taken care of here.
+ */
+static void ixgbevf_write_eitr(struct ixgbevf_adapter *adapter, int v_idx,
+			       u32 itr_reg)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	itr_reg = EITR_INTS_PER_SEC_TO_REG(itr_reg);
+
+	/*
+	 * 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_VTEITR(v_idx), itr_reg);
+}
+
+static void ixgbevf_set_itr_msix(struct ixgbevf_q_vector *q_vector)
+{
+	struct ixgbevf_adapter *adapter = q_vector->adapter;
+	u32 new_itr;
+	u8 current_itr, ret_itr;
+	int i, r_idx, v_idx = q_vector->v_idx;
+	struct ixgbevf_ring *rx_ring, *tx_ring;
+
+	r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
+	for (i = 0; i < q_vector->txr_count; i++) {
+		tx_ring = &(adapter->tx_ring[r_idx]);
+		ret_itr = ixgbevf_update_itr(adapter, q_vector->eitr,
+					     q_vector->tx_itr,
+					     tx_ring->total_packets,
+					     tx_ring->total_bytes);
+		/* if the result for this queue would decrease interrupt
+		 * rate for this vector then use that result */
+		q_vector->tx_itr = ((q_vector->tx_itr > ret_itr) ?
+				    q_vector->tx_itr - 1 : ret_itr);
+		r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
+				      r_idx + 1);
+	}
+
+	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+	for (i = 0; i < q_vector->rxr_count; i++) {
+		rx_ring = &(adapter->rx_ring[r_idx]);
+		ret_itr = ixgbevf_update_itr(adapter, q_vector->eitr,
+					     q_vector->rx_itr,
+					     rx_ring->total_packets,
+					     rx_ring->total_bytes);
+		/* if the result for this queue would decrease interrupt
+		 * rate for this vector then use that result */
+		q_vector->rx_itr = ((q_vector->rx_itr > ret_itr) ?
+				    q_vector->rx_itr - 1 : ret_itr);
+		r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
+				      r_idx + 1);
+	}
+
+	current_itr = max(q_vector->rx_itr, q_vector->tx_itr);
+
+	switch (current_itr) {
+	/* counts and packets in update_itr are dependent on these numbers */
+	case lowest_latency:
+		new_itr = 100000;
+		break;
+	case low_latency:
+		new_itr = 20000; /* aka hwitr = ~200 */
+		break;
+	case bulk_latency:
+	default:
+		new_itr = 8000;
+		break;
+	}
+
+	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);
+		itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
+		ixgbevf_write_eitr(adapter, v_idx, itr_reg);
+	}
+
+	return;
+}
+
+static irqreturn_t ixgbevf_msix_mbx(int irq, void *data)
+{
+	struct net_device *netdev = data;
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 eicr;
+	u32 msg;
+
+	eicr = IXGBE_READ_REG(hw, IXGBE_VTEICS);
+	IXGBE_WRITE_REG(hw, IXGBE_VTEICR, eicr);
+
+	hw->mbx.ops.read(hw, &msg, 1);
+
+	if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG)
+		mod_timer(&adapter->watchdog_timer,
+			  round_jiffies(jiffies + 1));
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t ixgbevf_msix_clean_tx(int irq, void *data)
+{
+	struct ixgbevf_q_vector *q_vector = data;
+	struct ixgbevf_adapter  *adapter = q_vector->adapter;
+	struct ixgbevf_ring     *tx_ring;
+	int i, r_idx;
+
+	if (!q_vector->txr_count)
+		return IRQ_HANDLED;
+
+	r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
+	for (i = 0; i < q_vector->txr_count; i++) {
+		tx_ring = &(adapter->tx_ring[r_idx]);
+		tx_ring->total_bytes = 0;
+		tx_ring->total_packets = 0;
+		ixgbevf_clean_tx_irq(adapter, tx_ring);
+		r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
+				      r_idx + 1);
+	}
+
+	if (adapter->itr_setting & 1)
+		ixgbevf_set_itr_msix(q_vector);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * ixgbe_msix_clean_rx - single unshared vector rx clean (all queues)
+ * @irq: unused
+ * @data: pointer to our q_vector struct for this interrupt vector
+ **/
+static irqreturn_t ixgbevf_msix_clean_rx(int irq, void *data)
+{
+	struct ixgbevf_q_vector *q_vector = data;
+	struct ixgbevf_adapter  *adapter = q_vector->adapter;
+	struct ixgbe_hw *hw = &adapter->hw;
+	struct ixgbevf_ring  *rx_ring;
+	int r_idx;
+	int i;
+
+	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+	for (i = 0; i < q_vector->rxr_count; i++) {
+		rx_ring = &(adapter->rx_ring[r_idx]);
+		rx_ring->total_bytes = 0;
+		rx_ring->total_packets = 0;
+		r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
+				      r_idx + 1);
+	}
+
+	if (!q_vector->rxr_count)
+		return IRQ_HANDLED;
+
+	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+	rx_ring = &(adapter->rx_ring[r_idx]);
+	/* disable interrupts on this vector only */
+	IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, rx_ring->v_idx);
+	napi_schedule(&q_vector->napi);
+
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t ixgbevf_msix_clean_many(int irq, void *data)
+{
+	ixgbevf_msix_clean_rx(irq, data);
+	ixgbevf_msix_clean_tx(irq, data);
+
+	return IRQ_HANDLED;
+}
+
+static inline void map_vector_to_rxq(struct ixgbevf_adapter *a, int v_idx,
+				     int r_idx)
+{
+	struct ixgbevf_q_vector *q_vector = a->q_vector[v_idx];
+
+	set_bit(r_idx, q_vector->rxr_idx);
+	q_vector->rxr_count++;
+	a->rx_ring[r_idx].v_idx = 1 << v_idx;
+}
+
+static inline void map_vector_to_txq(struct ixgbevf_adapter *a, int v_idx,
+				     int t_idx)
+{
+	struct ixgbevf_q_vector *q_vector = a->q_vector[v_idx];
+
+	set_bit(t_idx, q_vector->txr_idx);
+	q_vector->txr_count++;
+	a->tx_ring[t_idx].v_idx = 1 << v_idx;
+}
+
+/**
+ * ixgbevf_map_rings_to_vectors - Maps descriptor rings to vectors
+ * @adapter: board private structure to initialize
+ *
+ * This function maps descriptor rings to the queue-specific vectors
+ * we were allotted through the MSI-X enabling code.  Ideally, we'd have
+ * one vector per ring/queue, but on a constrained vector budget, we
+ * group the rings as "efficiently" as possible.  You would add new
+ * mapping configurations in here.
+ **/
+static int ixgbevf_map_rings_to_vectors(struct ixgbevf_adapter *adapter)
+{
+	int q_vectors;
+	int v_start = 0;
+	int rxr_idx = 0, txr_idx = 0;
+	int rxr_remaining = adapter->num_rx_queues;
+	int txr_remaining = adapter->num_tx_queues;
+	int i, j;
+	int rqpv, tqpv;
+	int err = 0;
+
+	q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+
+	/*
+	 * The ideal configuration...
+	 * We have enough vectors to map one per queue.
+	 */
+	if (q_vectors == adapter->num_rx_queues + adapter->num_tx_queues) {
+		for (; rxr_idx < rxr_remaining; v_start++, rxr_idx++)
+			map_vector_to_rxq(adapter, v_start, rxr_idx);
+
+		for (; txr_idx < txr_remaining; v_start++, txr_idx++)
+			map_vector_to_txq(adapter, v_start, txr_idx);
+		goto out;
+	}
+
+	/*
+	 * If we don't have enough vectors for a 1-to-1
+	 * mapping, we'll have to group them so there are
+	 * multiple queues per vector.
+	 */
+	/* Re-adjusting *qpv takes care of the remainder. */
+	for (i = v_start; i < q_vectors; i++) {
+		rqpv = DIV_ROUND_UP(rxr_remaining, q_vectors - i);
+		for (j = 0; j < rqpv; j++) {
+			map_vector_to_rxq(adapter, i, rxr_idx);
+			rxr_idx++;
+			rxr_remaining--;
+		}
+	}
+	for (i = v_start; i < q_vectors; i++) {
+		tqpv = DIV_ROUND_UP(txr_remaining, q_vectors - i);
+		for (j = 0; j < tqpv; j++) {
+			map_vector_to_txq(adapter, i, txr_idx);
+			txr_idx++;
+			txr_remaining--;
+		}
+	}
+
+out:
+	return err;
+}
+
+/**
+ * ixgbevf_request_msix_irqs - Initialize MSI-X interrupts
+ * @adapter: board private structure
+ *
+ * ixgbevf_request_msix_irqs allocates MSI-X vectors and requests
+ * interrupts from the kernel.
+ **/
+static int ixgbevf_request_msix_irqs(struct ixgbevf_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	irqreturn_t (*handler)(int, void *);
+	int i, vector, q_vectors, err;
+	int ri = 0, ti = 0;
+
+	/* Decrement for Other and TCP Timer vectors */
+	q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+
+#define SET_HANDLER(_v) (((_v)->rxr_count && (_v)->txr_count)          \
+					  ? &ixgbevf_msix_clean_many : \
+			  (_v)->rxr_count ? &ixgbevf_msix_clean_rx   : \
+			  (_v)->txr_count ? &ixgbevf_msix_clean_tx   : \
+			  NULL)
+	for (vector = 0; vector < q_vectors; vector++) {
+		handler = SET_HANDLER(adapter->q_vector[vector]);
+
+		if (handler == &ixgbevf_msix_clean_rx) {
+			sprintf(adapter->name[vector], "%s-%s-%d",
+				netdev->name, "rx", ri++);
+		} else if (handler == &ixgbevf_msix_clean_tx) {
+			sprintf(adapter->name[vector], "%s-%s-%d",
+				netdev->name, "tx", ti++);
+		} else if (handler == &ixgbevf_msix_clean_many) {
+			sprintf(adapter->name[vector], "%s-%s-%d",
+				netdev->name, "TxRx", vector);
+		} else {
+			/* skip this unused q_vector */
+			continue;
+		}
+		err = request_irq(adapter->msix_entries[vector].vector,
+				  handler, 0, adapter->name[vector],
+				  adapter->q_vector[vector]);
+		if (err) {
+			hw_dbg(&adapter->hw,
+			       "request_irq failed for MSIX interrupt "
+			       "Error: %d\n", err);
+			goto free_queue_irqs;
+		}
+	}
+
+	sprintf(adapter->name[vector], "%s:mbx", netdev->name);
+	err = request_irq(adapter->msix_entries[vector].vector,
+			  &ixgbevf_msix_mbx, 0, adapter->name[vector], netdev);
+	if (err) {
+		hw_dbg(&adapter->hw,
+		       "request_irq for msix_mbx failed: %d\n", err);
+		goto free_queue_irqs;
+	}
+
+	return 0;
+
+free_queue_irqs:
+	for (i = vector - 1; i >= 0; i--)
+		free_irq(adapter->msix_entries[--vector].vector,
+			 &(adapter->q_vector[i]));
+	pci_disable_msix(adapter->pdev);
+	kfree(adapter->msix_entries);
+	adapter->msix_entries = NULL;
+	return err;
+}
+
+static inline void ixgbevf_reset_q_vectors(struct ixgbevf_adapter *adapter)
+{
+	int i, q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+
+	for (i = 0; i < q_vectors; i++) {
+		struct ixgbevf_q_vector *q_vector = adapter->q_vector[i];
+		bitmap_zero(q_vector->rxr_idx, MAX_RX_QUEUES);
+		bitmap_zero(q_vector->txr_idx, MAX_TX_QUEUES);
+		q_vector->rxr_count = 0;
+		q_vector->txr_count = 0;
+		q_vector->eitr = adapter->eitr_param;
+	}
+}
+
+/**
+ * ixgbevf_request_irq - initialize interrupts
+ * @adapter: board private structure
+ *
+ * Attempts to configure interrupts using the best available
+ * capabilities of the hardware and kernel.
+ **/
+static int ixgbevf_request_irq(struct ixgbevf_adapter *adapter)
+{
+	int err = 0;
+
+	err = ixgbevf_request_msix_irqs(adapter);
+
+	if (err)
+		hw_dbg(&adapter->hw,
+		       "request_irq failed, Error %d\n", err);
+
+	return err;
+}
+
+static void ixgbevf_free_irq(struct ixgbevf_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	int i, q_vectors;
+
+	q_vectors = adapter->num_msix_vectors;
+
+	i = q_vectors - 1;
+
+	free_irq(adapter->msix_entries[i].vector, netdev);
+	i--;
+
+	for (; i >= 0; i--) {
+		free_irq(adapter->msix_entries[i].vector,
+			 adapter->q_vector[i]);
+	}
+
+	ixgbevf_reset_q_vectors(adapter);
+}
+
+/**
+ * ixgbevf_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ **/
+static inline void ixgbevf_irq_disable(struct ixgbevf_adapter *adapter)
+{
+	int i;
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, ~0);
+
+	IXGBE_WRITE_FLUSH(hw);
+
+	for (i = 0; i < adapter->num_msix_vectors; i++)
+		synchronize_irq(adapter->msix_entries[i].vector);
+}
+
+/**
+ * ixgbevf_irq_enable - Enable default interrupt generation settings
+ * @adapter: board private structure
+ **/
+static inline void ixgbevf_irq_enable(struct ixgbevf_adapter *adapter,
+				      bool queues, bool flush)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 mask;
+	u64 qmask;
+
+	mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
+	qmask = ~0;
+
+	IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
+
+	if (queues)
+		ixgbevf_irq_enable_queues(adapter, qmask);
+
+	if (flush)
+		IXGBE_WRITE_FLUSH(hw);
+}
+
+/**
+ * ixgbevf_configure_tx - Configure 82599 VF Transmit Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx unit of the MAC after a reset.
+ **/
+static void ixgbevf_configure_tx(struct ixgbevf_adapter *adapter)
+{
+	u64 tdba;
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 i, j, tdlen, txctrl;
+
+	/* Setup the HW Tx Head and Tail descriptor pointers */
+	for (i = 0; i < adapter->num_tx_queues; i++) {
+		struct ixgbevf_ring *ring = &adapter->tx_ring[i];
+		j = ring->reg_idx;
+		tdba = ring->dma;
+		tdlen = ring->count * sizeof(union ixgbe_adv_tx_desc);
+		IXGBE_WRITE_REG(hw, IXGBE_VFTDBAL(j),
+				(tdba & DMA_BIT_MASK(32)));
+		IXGBE_WRITE_REG(hw, IXGBE_VFTDBAH(j), (tdba >> 32));
+		IXGBE_WRITE_REG(hw, IXGBE_VFTDLEN(j), tdlen);
+		IXGBE_WRITE_REG(hw, IXGBE_VFTDH(j), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VFTDT(j), 0);
+		adapter->tx_ring[i].head = IXGBE_VFTDH(j);
+		adapter->tx_ring[i].tail = IXGBE_VFTDT(j);
+		/* Disable Tx Head Writeback RO bit, since this hoses
+		 * bookkeeping if things aren't delivered in order.
+		 */
+		txctrl = IXGBE_READ_REG(hw, IXGBE_VFDCA_TXCTRL(j));
+		txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+		IXGBE_WRITE_REG(hw, IXGBE_VFDCA_TXCTRL(j), txctrl);
+	}
+}
+
+#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT	2
+
+static void ixgbevf_configure_srrctl(struct ixgbevf_adapter *adapter, int index)
+{
+	struct ixgbevf_ring *rx_ring;
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 srrctl;
+
+	rx_ring = &adapter->rx_ring[index];
+
+	srrctl = IXGBE_SRRCTL_DROP_EN;
+
+	if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+		u16 bufsz = IXGBEVF_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)IXGBEVF_MAX_RXBUFFER, bufsz);
+
+		srrctl |= bufsz >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+		srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
+		srrctl |= ((IXGBEVF_RX_HDR_SIZE <<
+			   IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
+			   IXGBE_SRRCTL_BSIZEHDR_MASK);
+	} else {
+		srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
+
+		if (rx_ring->rx_buf_len == MAXIMUM_ETHERNET_VLAN_SIZE)
+			srrctl |= IXGBEVF_RXBUFFER_2048 >>
+				IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+		else
+			srrctl |= rx_ring->rx_buf_len >>
+				IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+	}
+	IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(index), srrctl);
+}
+
+/**
+ * ixgbevf_configure_rx - Configure 82599 VF Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Rx unit of the MAC after a reset.
+ **/
+static void ixgbevf_configure_rx(struct ixgbevf_adapter *adapter)
+{
+	u64 rdba;
+	struct ixgbe_hw *hw = &adapter->hw;
+	struct net_device *netdev = adapter->netdev;
+	int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
+	int i, j;
+	u32 rdlen;
+	int rx_buf_len;
+
+	/* Decide whether to use packet split mode or not */
+	if (netdev->mtu > ETH_DATA_LEN) {
+		if (adapter->flags & IXGBE_FLAG_RX_PS_CAPABLE)
+			adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
+		else
+			adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED;
+	} else {
+		if (adapter->flags & IXGBE_FLAG_RX_1BUF_CAPABLE)
+			adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED;
+		else
+			adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
+	}
+
+	/* Set the RX buffer length according to the mode */
+	if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+		/* PSRTYPE must be initialized in 82599 */
+		u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
+			IXGBE_PSRTYPE_UDPHDR |
+			IXGBE_PSRTYPE_IPV4HDR |
+			IXGBE_PSRTYPE_IPV6HDR |
+			IXGBE_PSRTYPE_L2HDR;
+		IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype);
+		rx_buf_len = IXGBEVF_RX_HDR_SIZE;
+	} else {
+		IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, 0);
+		if (netdev->mtu <= ETH_DATA_LEN)
+			rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
+		else
+			rx_buf_len = ALIGN(max_frame, 1024);
+	}
+
+	rdlen = adapter->rx_ring[0].count * sizeof(union ixgbe_adv_rx_desc);
+	/* 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++) {
+		rdba = adapter->rx_ring[i].dma;
+		j = adapter->rx_ring[i].reg_idx;
+		IXGBE_WRITE_REG(hw, IXGBE_VFRDBAL(j),
+				(rdba & DMA_BIT_MASK(32)));
+		IXGBE_WRITE_REG(hw, IXGBE_VFRDBAH(j), (rdba >> 32));
+		IXGBE_WRITE_REG(hw, IXGBE_VFRDLEN(j), rdlen);
+		IXGBE_WRITE_REG(hw, IXGBE_VFRDH(j), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VFRDT(j), 0);
+		adapter->rx_ring[i].head = IXGBE_VFRDH(j);
+		adapter->rx_ring[i].tail = IXGBE_VFRDT(j);
+		adapter->rx_ring[i].rx_buf_len = rx_buf_len;
+
+		ixgbevf_configure_srrctl(adapter, j);
+	}
+}
+
+static void ixgbevf_vlan_rx_register(struct net_device *netdev,
+				     struct vlan_group *grp)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_hw *hw = &adapter->hw;
+	int i, j;
+	u32 ctrl;
+
+	adapter->vlgrp = grp;
+
+	for (i = 0; i < adapter->num_rx_queues; i++) {
+		j = adapter->rx_ring[i].reg_idx;
+		ctrl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j));
+		ctrl |= IXGBE_RXDCTL_VME;
+		IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(j), ctrl);
+	}
+}
+
+static void ixgbevf_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_hw *hw = &adapter->hw;
+	struct net_device *v_netdev;
+
+	/* add VID to filter table */
+	if (hw->mac.ops.set_vfta)
+		hw->mac.ops.set_vfta(hw, vid, 0, true);
+	/*
+	 * Copy feature flags from netdev to the vlan netdev for this vid.
+	 * This allows things like TSO to bubble down to our vlan device.
+	 */
+	v_netdev = vlan_group_get_device(adapter->vlgrp, vid);
+	v_netdev->features |= adapter->netdev->features;
+	vlan_group_set_device(adapter->vlgrp, vid, v_netdev);
+}
+
+static void ixgbevf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
+		ixgbevf_irq_disable(adapter);
+
+	vlan_group_set_device(adapter->vlgrp, vid, NULL);
+
+	if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
+		ixgbevf_irq_enable(adapter, true, true);
+
+	/* remove VID from filter table */
+	if (hw->mac.ops.set_vfta)
+		hw->mac.ops.set_vfta(hw, vid, 0, false);
+}
+
+static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter)
+{
+	ixgbevf_vlan_rx_register(adapter->netdev, adapter->vlgrp);
+
+	if (adapter->vlgrp) {
+		u16 vid;
+		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+			if (!vlan_group_get_device(adapter->vlgrp, vid))
+				continue;
+			ixgbevf_vlan_rx_add_vid(adapter->netdev, vid);
+		}
+	}
+}
+
+static u8 *ixgbevf_addr_list_itr(struct ixgbe_hw *hw, u8 **mc_addr_ptr,
+				 u32 *vmdq)
+{
+	struct dev_mc_list *mc_ptr;
+	u8 *addr = *mc_addr_ptr;
+	*vmdq = 0;
+
+	mc_ptr = container_of(addr, struct dev_mc_list, dmi_addr[0]);
+	if (mc_ptr->next)
+		*mc_addr_ptr = mc_ptr->next->dmi_addr;
+	else
+		*mc_addr_ptr = NULL;
+
+	return addr;
+}
+
+/**
+ * ixgbevf_set_rx_mode - Multicast set
+ * @netdev: network interface device structure
+ *
+ * The set_rx_method 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 mode.
+ **/
+static void ixgbevf_set_rx_mode(struct net_device *netdev)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_hw *hw = &adapter->hw;
+	u8 *addr_list = NULL;
+	int addr_count = 0;
+
+	/* reprogram multicast list */
+	addr_count = netdev_mc_count(netdev);
+	if (addr_count)
+		addr_list = netdev->mc_list->dmi_addr;
+	if (hw->mac.ops.update_mc_addr_list)
+		hw->mac.ops.update_mc_addr_list(hw, addr_list, addr_count,
+						ixgbevf_addr_list_itr);
+}
+
+static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter)
+{
+	int q_idx;
+	struct ixgbevf_q_vector *q_vector;
+	int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+
+	for (q_idx = 0; q_idx < q_vectors; q_idx++) {
+		struct napi_struct *napi;
+		q_vector = adapter->q_vector[q_idx];
+		if (!q_vector->rxr_count)
+			continue;
+		napi = &q_vector->napi;
+		if (q_vector->rxr_count > 1)
+			napi->poll = &ixgbevf_clean_rxonly_many;
+
+		napi_enable(napi);
+	}
+}
+
+static void ixgbevf_napi_disable_all(struct ixgbevf_adapter *adapter)
+{
+	int q_idx;
+	struct ixgbevf_q_vector *q_vector;
+	int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+
+	for (q_idx = 0; q_idx < q_vectors; q_idx++) {
+		q_vector = adapter->q_vector[q_idx];
+		if (!q_vector->rxr_count)
+			continue;
+		napi_disable(&q_vector->napi);
+	}
+}
+
+static void ixgbevf_configure(struct ixgbevf_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	int i;
+
+	ixgbevf_set_rx_mode(netdev);
+
+	ixgbevf_restore_vlan(adapter);
+
+	ixgbevf_configure_tx(adapter);
+	ixgbevf_configure_rx(adapter);
+	for (i = 0; i < adapter->num_rx_queues; i++) {
+		struct ixgbevf_ring *ring = &adapter->rx_ring[i];
+		ixgbevf_alloc_rx_buffers(adapter, ring, ring->count);
+		ring->next_to_use = ring->count - 1;
+		writel(ring->next_to_use, adapter->hw.hw_addr + ring->tail);
+	}
+}
+
+#define IXGBE_MAX_RX_DESC_POLL 10
+static inline void ixgbevf_rx_desc_queue_enable(struct ixgbevf_adapter *adapter,
+						int rxr)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	int j = adapter->rx_ring[rxr].reg_idx;
+	int k;
+
+	for (k = 0; k < IXGBE_MAX_RX_DESC_POLL; k++) {
+		if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j)) & IXGBE_RXDCTL_ENABLE)
+			break;
+		else
+			msleep(1);
+	}
+	if (k >= IXGBE_MAX_RX_DESC_POLL) {
+		hw_dbg(hw, "RXDCTL.ENABLE on Rx queue %d "
+		       "not set within the polling period\n", rxr);
+	}
+
+	ixgbevf_release_rx_desc(&adapter->hw, &adapter->rx_ring[rxr],
+				(adapter->rx_ring[rxr].count - 1));
+}
+
+static void ixgbevf_save_reset_stats(struct ixgbevf_adapter *adapter)
+{
+	/* Only save pre-reset stats if there are some */
+	if (adapter->stats.vfgprc || adapter->stats.vfgptc) {
+		adapter->stats.saved_reset_vfgprc += adapter->stats.vfgprc -
+			adapter->stats.base_vfgprc;
+		adapter->stats.saved_reset_vfgptc += adapter->stats.vfgptc -
+			adapter->stats.base_vfgptc;
+		adapter->stats.saved_reset_vfgorc += adapter->stats.vfgorc -
+			adapter->stats.base_vfgorc;
+		adapter->stats.saved_reset_vfgotc += adapter->stats.vfgotc -
+			adapter->stats.base_vfgotc;
+		adapter->stats.saved_reset_vfmprc += adapter->stats.vfmprc -
+			adapter->stats.base_vfmprc;
+	}
+}
+
+static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	adapter->stats.last_vfgprc = IXGBE_READ_REG(hw, IXGBE_VFGPRC);
+	adapter->stats.last_vfgorc = IXGBE_READ_REG(hw, IXGBE_VFGORC_LSB);
+	adapter->stats.last_vfgorc |=
+		(((u64)(IXGBE_READ_REG(hw, IXGBE_VFGORC_MSB))) << 32);
+	adapter->stats.last_vfgptc = IXGBE_READ_REG(hw, IXGBE_VFGPTC);
+	adapter->stats.last_vfgotc = IXGBE_READ_REG(hw, IXGBE_VFGOTC_LSB);
+	adapter->stats.last_vfgotc |=
+		(((u64)(IXGBE_READ_REG(hw, IXGBE_VFGOTC_MSB))) << 32);
+	adapter->stats.last_vfmprc = IXGBE_READ_REG(hw, IXGBE_VFMPRC);
+
+	adapter->stats.base_vfgprc = adapter->stats.last_vfgprc;
+	adapter->stats.base_vfgorc = adapter->stats.last_vfgorc;
+	adapter->stats.base_vfgptc = adapter->stats.last_vfgptc;
+	adapter->stats.base_vfgotc = adapter->stats.last_vfgotc;
+	adapter->stats.base_vfmprc = adapter->stats.last_vfmprc;
+}
+
+static int ixgbevf_up_complete(struct ixgbevf_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;
+	u32 txdctl, rxdctl;
+
+	for (i = 0; i < adapter->num_tx_queues; i++) {
+		j = adapter->tx_ring[i].reg_idx;
+		txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(j));
+		/* enable WTHRESH=8 descriptors, to encourage burst writeback */
+		txdctl |= (8 << 16);
+		IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(j), txdctl);
+	}
+
+	for (i = 0; i < adapter->num_tx_queues; i++) {
+		j = adapter->tx_ring[i].reg_idx;
+		txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(j));
+		txdctl |= IXGBE_TXDCTL_ENABLE;
+		IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(j), txdctl);
+	}
+
+	for (i = 0; i < num_rx_rings; i++) {
+		j = adapter->rx_ring[i].reg_idx;
+		rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j));
+		rxdctl |= IXGBE_RXDCTL_ENABLE;
+		IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(j), rxdctl);
+		ixgbevf_rx_desc_queue_enable(adapter, i);
+	}
+
+	ixgbevf_configure_msix(adapter);
+
+	if (hw->mac.ops.set_rar) {
+		if (is_valid_ether_addr(hw->mac.addr))
+			hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0);
+		else
+			hw->mac.ops.set_rar(hw, 0, hw->mac.perm_addr, 0);
+	}
+
+	clear_bit(__IXGBEVF_DOWN, &adapter->state);
+	ixgbevf_napi_enable_all(adapter);
+
+	/* enable transmits */
+	netif_tx_start_all_queues(netdev);
+
+	ixgbevf_save_reset_stats(adapter);
+	ixgbevf_init_last_counter_stats(adapter);
+
+	/* bring the link up in the watchdog, this could race with our first
+	 * link up interrupt but shouldn't be a problem */
+	adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
+	adapter->link_check_timeout = jiffies;
+	mod_timer(&adapter->watchdog_timer, jiffies);
+	return 0;
+}
+
+int ixgbevf_up(struct ixgbevf_adapter *adapter)
+{
+	int err;
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	ixgbevf_configure(adapter);
+
+	err = ixgbevf_up_complete(adapter);
+
+	/* clear any pending interrupts, may auto mask */
+	IXGBE_READ_REG(hw, IXGBE_VTEICR);
+
+	ixgbevf_irq_enable(adapter, true, true);
+
+	return err;
+}
+
+/**
+ * ixgbevf_clean_rx_ring - Free Rx Buffers per Queue
+ * @adapter: board private structure
+ * @rx_ring: ring to free buffers from
+ **/
+static void ixgbevf_clean_rx_ring(struct ixgbevf_adapter *adapter,
+				  struct ixgbevf_ring *rx_ring)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	unsigned long size;
+	unsigned int i;
+
+	if (!rx_ring->rx_buffer_info)
+		return;
+
+	/* Free all the Rx ring sk_buffs */
+	for (i = 0; i < rx_ring->count; i++) {
+		struct ixgbevf_rx_buffer *rx_buffer_info;
+
+		rx_buffer_info = &rx_ring->rx_buffer_info[i];
+		if (rx_buffer_info->dma) {
+			pci_unmap_single(pdev, rx_buffer_info->dma,
+					 rx_ring->rx_buf_len,
+					 PCI_DMA_FROMDEVICE);
+			rx_buffer_info->dma = 0;
+		}
+		if (rx_buffer_info->skb) {
+			struct sk_buff *skb = rx_buffer_info->skb;
+			rx_buffer_info->skb = NULL;
+			do {
+				struct sk_buff *this = skb;
+				skb = skb->prev;
+				dev_kfree_skb(this);
+			} while (skb);
+		}
+		if (!rx_buffer_info->page)
+			continue;
+		pci_unmap_page(pdev, rx_buffer_info->page_dma, PAGE_SIZE / 2,
+			       PCI_DMA_FROMDEVICE);
+		rx_buffer_info->page_dma = 0;
+		put_page(rx_buffer_info->page);
+		rx_buffer_info->page = NULL;
+		rx_buffer_info->page_offset = 0;
+	}
+
+	size = sizeof(struct ixgbevf_rx_buffer) * rx_ring->count;
+	memset(rx_ring->rx_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;
+
+	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);
+}
+
+/**
+ * ixgbevf_clean_tx_ring - Free Tx Buffers
+ * @adapter: board private structure
+ * @tx_ring: ring to be cleaned
+ **/
+static void ixgbevf_clean_tx_ring(struct ixgbevf_adapter *adapter,
+				  struct ixgbevf_ring *tx_ring)
+{
+	struct ixgbevf_tx_buffer *tx_buffer_info;
+	unsigned long size;
+	unsigned int i;
+
+	if (!tx_ring->tx_buffer_info)
+		return;
+
+	/* Free all the Tx ring sk_buffs */
+
+	for (i = 0; i < tx_ring->count; i++) {
+		tx_buffer_info = &tx_ring->tx_buffer_info[i];
+		ixgbevf_unmap_and_free_tx_resource(adapter, tx_buffer_info);
+	}
+
+	size = sizeof(struct ixgbevf_tx_buffer) * tx_ring->count;
+	memset(tx_ring->tx_buffer_info, 0, size);
+
+	memset(tx_ring->desc, 0, tx_ring->size);
+
+	tx_ring->next_to_use = 0;
+	tx_ring->next_to_clean = 0;
+
+	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);
+}
+
+/**
+ * ixgbevf_clean_all_rx_rings - Free Rx Buffers for all queues
+ * @adapter: board private structure
+ **/
+static void ixgbevf_clean_all_rx_rings(struct ixgbevf_adapter *adapter)
+{
+	int i;
+
+	for (i = 0; i < adapter->num_rx_queues; i++)
+		ixgbevf_clean_rx_ring(adapter, &adapter->rx_ring[i]);
+}
+
+/**
+ * ixgbevf_clean_all_tx_rings - Free Tx Buffers for all queues
+ * @adapter: board private structure
+ **/
+static void ixgbevf_clean_all_tx_rings(struct ixgbevf_adapter *adapter)
+{
+	int i;
+
+	for (i = 0; i < adapter->num_tx_queues; i++)
+		ixgbevf_clean_tx_ring(adapter, &adapter->tx_ring[i]);
+}
+
+void ixgbevf_down(struct ixgbevf_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 txdctl;
+	int i, j;
+
+	/* signal that we are down to the interrupt handler */
+	set_bit(__IXGBEVF_DOWN, &adapter->state);
+	/* disable receives */
+
+	netif_tx_disable(netdev);
+
+	msleep(10);
+
+	netif_tx_stop_all_queues(netdev);
+
+	ixgbevf_irq_disable(adapter);
+
+	ixgbevf_napi_disable_all(adapter);
+
+	del_timer_sync(&adapter->watchdog_timer);
+	/* can't call flush scheduled work here because it can deadlock
+	 * if linkwatch_event tries to acquire the rtnl_lock which we are
+	 * holding */
+	while (adapter->flags & IXGBE_FLAG_IN_WATCHDOG_TASK)
+		msleep(1);
+
+	/* disable transmits in the hardware now that interrupts are off */
+	for (i = 0; i < adapter->num_tx_queues; i++) {
+		j = adapter->tx_ring[i].reg_idx;
+		txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(j));
+		IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(j),
+				(txdctl & ~IXGBE_TXDCTL_ENABLE));
+	}
+
+	netif_carrier_off(netdev);
+
+	if (!pci_channel_offline(adapter->pdev))
+		ixgbevf_reset(adapter);
+
+	ixgbevf_clean_all_tx_rings(adapter);
+	ixgbevf_clean_all_rx_rings(adapter);
+}
+
+void ixgbevf_reinit_locked(struct ixgbevf_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	WARN_ON(in_interrupt());
+
+	while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state))
+		msleep(1);
+
+	/*
+	 * Check if PF is up before re-init.  If not then skip until
+	 * later when the PF is up and ready to service requests from
+	 * the VF via mailbox.  If the VF is up and running then the
+	 * watchdog task will continue to schedule reset tasks until
+	 * the PF is up and running.
+	 */
+	if (!hw->mac.ops.reset_hw(hw)) {
+		ixgbevf_down(adapter);
+		ixgbevf_up(adapter);
+	}
+
+	clear_bit(__IXGBEVF_RESETTING, &adapter->state);
+}
+
+void ixgbevf_reset(struct ixgbevf_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	struct net_device *netdev = adapter->netdev;
+
+	if (hw->mac.ops.reset_hw(hw))
+		hw_dbg(hw, "PF still resetting\n");
+	else
+		hw->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);
+	}
+}
+
+static void ixgbevf_acquire_msix_vectors(struct ixgbevf_adapter *adapter,
+					 int vectors)
+{
+	int err, vector_threshold;
+
+	/* We'll want at least 3 (vector_threshold):
+	 * 1) TxQ[0] Cleanup
+	 * 2) RxQ[0] Cleanup
+	 * 3) Other (Link Status Change, etc.)
+	 */
+	vector_threshold = MIN_MSIX_COUNT;
+
+	/* The more we get, the more we will assign to Tx/Rx Cleanup
+	 * for the separate queues...where Rx Cleanup >= Tx Cleanup.
+	 * Right now, we simply care about how many we'll get; we'll
+	 * set them up later while requesting irq's.
+	 */
+	while (vectors >= vector_threshold) {
+		err = pci_enable_msix(adapter->pdev, adapter->msix_entries,
+				      vectors);
+		if (!err) /* Success in acquiring all requested vectors. */
+			break;
+		else if (err < 0)
+			vectors = 0; /* Nasty failure, quit now */
+		else /* err == number of vectors we should try again with */
+			vectors = err;
+	}
+
+	if (vectors < vector_threshold) {
+		/* Can't allocate enough MSI-X interrupts?  Oh well.
+		 * This just means we'll go with either a single MSI
+		 * vector or fall back to legacy interrupts.
+		 */
+		hw_dbg(&adapter->hw,
+		       "Unable to allocate MSI-X interrupts\n");
+		kfree(adapter->msix_entries);
+		adapter->msix_entries = NULL;
+	} else {
+		/*
+		 * 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 = vectors;
+	}
+}
+
+/*
+ * 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 ixgbevf_set_num_queues(struct ixgbevf_adapter *adapter)
+{
+	/* Start with base case */
+	adapter->num_rx_queues = 1;
+	adapter->num_tx_queues = 1;
+	adapter->num_rx_pools = adapter->num_rx_queues;
+	adapter->num_rx_queues_per_pool = 1;
+}
+
+/**
+ * ixgbevf_alloc_queues - Allocate memory for all rings
+ * @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.  The polling_netdev array is
+ * intended for Multiqueue, but should work fine with a single queue.
+ **/
+static int ixgbevf_alloc_queues(struct ixgbevf_adapter *adapter)
+{
+	int i;
+
+	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
+				   sizeof(struct ixgbevf_ring), GFP_KERNEL);
+	if (!adapter->tx_ring)
+		goto err_tx_ring_allocation;
+
+	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
+				   sizeof(struct ixgbevf_ring), GFP_KERNEL);
+	if (!adapter->rx_ring)
+		goto err_rx_ring_allocation;
+
+	for (i = 0; i < adapter->num_tx_queues; i++) {
+		adapter->tx_ring[i].count = adapter->tx_ring_count;
+		adapter->tx_ring[i].queue_index = i;
+		adapter->tx_ring[i].reg_idx = i;
+	}
+
+	for (i = 0; i < adapter->num_rx_queues; i++) {
+		adapter->rx_ring[i].count = adapter->rx_ring_count;
+		adapter->rx_ring[i].queue_index = i;
+		adapter->rx_ring[i].reg_idx = i;
+	}
+
+	return 0;
+
+err_rx_ring_allocation:
+	kfree(adapter->tx_ring);
+err_tx_ring_allocation:
+	return -ENOMEM;
+}
+
+/**
+ * ixgbevf_set_interrupt_capability - set MSI-X or FAIL if not supported
+ * @adapter: board private structure to initialize
+ *
+ * Attempt to configure the interrupts using the best available
+ * capabilities of the hardware and the kernel.
+ **/
+static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter)
+{
+	int err = 0;
+	int vector, v_budget;
+
+	/*
+	 * It's easy to be greedy for MSI-X vectors, but it really
+	 * doesn't do us much good if we have a lot more vectors
+	 * than CPU's.  So let's be conservative and only ask for
+	 * (roughly) twice the number of vectors as there are CPU's.
+	 */
+	v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues,
+		       (int)(num_online_cpus() * 2)) + NON_Q_VECTORS;
+
+	/* A failure in MSI-X entry allocation isn't fatal, but it does
+	 * mean we disable MSI-X capabilities of the adapter. */
+	adapter->msix_entries = kcalloc(v_budget,
+					sizeof(struct msix_entry), GFP_KERNEL);
+	if (!adapter->msix_entries) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	for (vector = 0; vector < v_budget; vector++)
+		adapter->msix_entries[vector].entry = vector;
+
+	ixgbevf_acquire_msix_vectors(adapter, v_budget);
+
+out:
+	return err;
+}
+
+/**
+ * ixgbevf_alloc_q_vectors - Allocate memory for interrupt vectors
+ * @adapter: board private structure to initialize
+ *
+ * We allocate one q_vector per queue interrupt.  If allocation fails we
+ * return -ENOMEM.
+ **/
+static int ixgbevf_alloc_q_vectors(struct ixgbevf_adapter *adapter)
+{
+	int q_idx, num_q_vectors;
+	struct ixgbevf_q_vector *q_vector;
+	int napi_vectors;
+	int (*poll)(struct napi_struct *, int);
+
+	num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+	napi_vectors = adapter->num_rx_queues;
+	poll = &ixgbevf_clean_rxonly;
+
+	for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
+		q_vector = kzalloc(sizeof(struct ixgbevf_q_vector), GFP_KERNEL);
+		if (!q_vector)
+			goto err_out;
+		q_vector->adapter = adapter;
+		q_vector->v_idx = q_idx;
+		q_vector->eitr = adapter->eitr_param;
+		if (q_idx < napi_vectors)
+			netif_napi_add(adapter->netdev, &q_vector->napi,
+				       (*poll), 64);
+		adapter->q_vector[q_idx] = q_vector;
+	}
+
+	return 0;
+
+err_out:
+	while (q_idx) {
+		q_idx--;
+		q_vector = adapter->q_vector[q_idx];
+		netif_napi_del(&q_vector->napi);
+		kfree(q_vector);
+		adapter->q_vector[q_idx] = NULL;
+	}
+	return -ENOMEM;
+}
+
+/**
+ * ixgbevf_free_q_vectors - Free memory allocated for interrupt vectors
+ * @adapter: board private structure to initialize
+ *
+ * This function frees the memory allocated to the q_vectors.  In addition if
+ * NAPI is enabled it will delete any references to the NAPI struct prior
+ * to freeing the q_vector.
+ **/
+static void ixgbevf_free_q_vectors(struct ixgbevf_adapter *adapter)
+{
+	int q_idx, num_q_vectors;
+	int napi_vectors;
+
+	num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+	napi_vectors = adapter->num_rx_queues;
+
+	for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
+		struct ixgbevf_q_vector *q_vector = adapter->q_vector[q_idx];
+
+		adapter->q_vector[q_idx] = NULL;
+		if (q_idx < napi_vectors)
+			netif_napi_del(&q_vector->napi);
+		kfree(q_vector);
+	}
+}
+
+/**
+ * ixgbevf_reset_interrupt_capability - Reset MSIX setup
+ * @adapter: board private structure
+ *
+ **/
+static void ixgbevf_reset_interrupt_capability(struct ixgbevf_adapter *adapter)
+{
+	pci_disable_msix(adapter->pdev);
+	kfree(adapter->msix_entries);
+	adapter->msix_entries = NULL;
+
+	return;
+}
+
+/**
+ * ixgbevf_init_interrupt_scheme - Determine if MSIX is supported and init
+ * @adapter: board private structure to initialize
+ *
+ **/
+static int ixgbevf_init_interrupt_scheme(struct ixgbevf_adapter *adapter)
+{
+	int err;
+
+	/* Number of supported queues */
+	ixgbevf_set_num_queues(adapter);
+
+	err = ixgbevf_set_interrupt_capability(adapter);
+	if (err) {
+		hw_dbg(&adapter->hw,
+		       "Unable to setup interrupt capabilities\n");
+		goto err_set_interrupt;
+	}
+
+	err = ixgbevf_alloc_q_vectors(adapter);
+	if (err) {
+		hw_dbg(&adapter->hw, "Unable to allocate memory for queue "
+		       "vectors\n");
+		goto err_alloc_q_vectors;
+	}
+
+	err = ixgbevf_alloc_queues(adapter);
+	if (err) {
+		printk(KERN_ERR "Unable to allocate memory for queues\n");
+		goto err_alloc_queues;
+	}
+
+	hw_dbg(&adapter->hw, "Multiqueue %s: Rx Queue count = %u, "
+	       "Tx Queue count = %u\n",
+	       (adapter->num_rx_queues > 1) ? "Enabled" :
+	       "Disabled", adapter->num_rx_queues, adapter->num_tx_queues);
+
+	set_bit(__IXGBEVF_DOWN, &adapter->state);
+
+	return 0;
+err_alloc_queues:
+	ixgbevf_free_q_vectors(adapter);
+err_alloc_q_vectors:
+	ixgbevf_reset_interrupt_capability(adapter);
+err_set_interrupt:
+	return err;
+}
+
+/**
+ * ixgbevf_sw_init - Initialize general software structures
+ * (struct ixgbevf_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * ixgbevf_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 ixgbevf_sw_init(struct ixgbevf_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	struct pci_dev *pdev = adapter->pdev;
+	int err;
+
+	/* PCI config space info */
+
+	hw->vendor_id = pdev->vendor;
+	hw->device_id = pdev->device;
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
+	hw->subsystem_vendor_id = pdev->subsystem_vendor;
+	hw->subsystem_device_id = pdev->subsystem_device;
+
+	hw->mbx.ops.init_params(hw);
+	hw->mac.max_tx_queues = MAX_TX_QUEUES;
+	hw->mac.max_rx_queues = MAX_RX_QUEUES;
+	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.init_hw(hw);
+		if (err) {
+			printk(KERN_ERR "init_shared_code failed: %d\n", err);
+			goto out;
+		}
+	}
+
+	/* Enable dynamic interrupt throttling rates */
+	adapter->eitr_param = 20000;
+	adapter->itr_setting = 1;
+
+	/* set defaults for eitr in MegaBytes */
+	adapter->eitr_low = 10;
+	adapter->eitr_high = 20;
+
+	/* set default ring sizes */
+	adapter->tx_ring_count = IXGBEVF_DEFAULT_TXD;
+	adapter->rx_ring_count = IXGBEVF_DEFAULT_RXD;
+
+	/* enable rx csum by default */
+	adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
+
+	set_bit(__IXGBEVF_DOWN, &adapter->state);
+
+out:
+	return err;
+}
+
+#define UPDATE_VF_COUNTER_32bit(reg, last_counter, counter)	\
+	{							\
+		u32 current_counter = IXGBE_READ_REG(hw, reg);	\
+		if (current_counter < last_counter)		\
+			counter += 0x100000000LL;		\
+		last_counter = current_counter;			\
+		counter &= 0xFFFFFFFF00000000LL;		\
+		counter |= current_counter;			\
+	}
+
+#define UPDATE_VF_COUNTER_36bit(reg_lsb, reg_msb, last_counter, counter) \
+	{								 \
+		u64 current_counter_lsb = IXGBE_READ_REG(hw, reg_lsb);	 \
+		u64 current_counter_msb = IXGBE_READ_REG(hw, reg_msb);	 \
+		u64 current_counter = (current_counter_msb << 32) |      \
+			current_counter_lsb;                             \
+		if (current_counter < last_counter)			 \
+			counter += 0x1000000000LL;			 \
+		last_counter = current_counter;				 \
+		counter &= 0xFFFFFFF000000000LL;			 \
+		counter |= current_counter;				 \
+	}
+/**
+ * ixgbevf_update_stats - Update the board statistics counters.
+ * @adapter: board private structure
+ **/
+void ixgbevf_update_stats(struct ixgbevf_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	UPDATE_VF_COUNTER_32bit(IXGBE_VFGPRC, adapter->stats.last_vfgprc,
+				adapter->stats.vfgprc);
+	UPDATE_VF_COUNTER_32bit(IXGBE_VFGPTC, adapter->stats.last_vfgptc,
+				adapter->stats.vfgptc);
+	UPDATE_VF_COUNTER_36bit(IXGBE_VFGORC_LSB, IXGBE_VFGORC_MSB,
+				adapter->stats.last_vfgorc,
+				adapter->stats.vfgorc);
+	UPDATE_VF_COUNTER_36bit(IXGBE_VFGOTC_LSB, IXGBE_VFGOTC_MSB,
+				adapter->stats.last_vfgotc,
+				adapter->stats.vfgotc);
+	UPDATE_VF_COUNTER_32bit(IXGBE_VFMPRC, adapter->stats.last_vfmprc,
+				adapter->stats.vfmprc);
+
+	/* Fill out the OS statistics structure */
+	adapter->net_stats.multicast = adapter->stats.vfmprc -
+		adapter->stats.base_vfmprc;
+}
+
+/**
+ * ixgbevf_watchdog - Timer Call-back
+ * @data: pointer to adapter cast into an unsigned long
+ **/
+static void ixgbevf_watchdog(unsigned long data)
+{
+	struct ixgbevf_adapter *adapter = (struct ixgbevf_adapter *)data;
+	struct ixgbe_hw *hw = &adapter->hw;
+	u64 eics = 0;
+	int i;
+
+	/*
+	 * Do the watchdog outside of interrupt context due to the lovely
+	 * delays that some of the newer hardware requires
+	 */
+
+	if (test_bit(__IXGBEVF_DOWN, &adapter->state))
+		goto watchdog_short_circuit;
+
+	/* get one bit for every active tx/rx interrupt vector */
+	for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
+		struct ixgbevf_q_vector *qv = adapter->q_vector[i];
+		if (qv->rxr_count || qv->txr_count)
+			eics |= (1 << i);
+	}
+
+	IXGBE_WRITE_REG(hw, IXGBE_VTEICS, (u32)eics);
+
+watchdog_short_circuit:
+	schedule_work(&adapter->watchdog_task);
+}
+
+/**
+ * ixgbevf_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ **/
+static void ixgbevf_tx_timeout(struct net_device *netdev)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+
+	/* Do the reset outside of interrupt context */
+	schedule_work(&adapter->reset_task);
+}
+
+static void ixgbevf_reset_task(struct work_struct *work)
+{
+	struct ixgbevf_adapter *adapter;
+	adapter = container_of(work, struct ixgbevf_adapter, reset_task);
+
+	/* If we're already down or resetting, just bail */
+	if (test_bit(__IXGBEVF_DOWN, &adapter->state) ||
+	    test_bit(__IXGBEVF_RESETTING, &adapter->state))
+		return;
+
+	adapter->tx_timeout_count++;
+
+	ixgbevf_reinit_locked(adapter);
+}
+
+/**
+ * ixgbevf_watchdog_task - worker thread to bring link up
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbevf_watchdog_task(struct work_struct *work)
+{
+	struct ixgbevf_adapter *adapter = container_of(work,
+						       struct ixgbevf_adapter,
+						       watchdog_task);
+	struct net_device *netdev = adapter->netdev;
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 link_speed = adapter->link_speed;
+	bool link_up = adapter->link_up;
+
+	adapter->flags |= IXGBE_FLAG_IN_WATCHDOG_TASK;
+
+	/*
+	 * Always check the link on the watchdog because we have
+	 * no LSC interrupt
+	 */
+	if (hw->mac.ops.check_link) {
+		if ((hw->mac.ops.check_link(hw, &link_speed,
+					    &link_up, false)) != 0) {
+			adapter->link_up = link_up;
+			adapter->link_speed = link_speed;
+			netif_carrier_off(netdev);
+			netif_tx_stop_all_queues(netdev);
+			schedule_work(&adapter->reset_task);
+			goto pf_has_reset;
+		}
+	} else {
+		/* always assume link is up, if no check link
+		 * function */
+		link_speed = IXGBE_LINK_SPEED_10GB_FULL;
+		link_up = true;
+	}
+	adapter->link_up = link_up;
+	adapter->link_speed = link_speed;
+
+	if (link_up) {
+		if (!netif_carrier_ok(netdev)) {
+			hw_dbg(&adapter->hw, "NIC Link is Up %s, ",
+			       ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
+				"10 Gbps\n" : "1 Gbps\n"));
+			netif_carrier_on(netdev);
+			netif_tx_wake_all_queues(netdev);
+		} else {
+			/* Force detection of hung controller */
+			adapter->detect_tx_hung = true;
+		}
+	} else {
+		adapter->link_up = false;
+		adapter->link_speed = 0;
+		if (netif_carrier_ok(netdev)) {
+			hw_dbg(&adapter->hw, "NIC Link is Down\n");
+			netif_carrier_off(netdev);
+			netif_tx_stop_all_queues(netdev);
+		}
+	}
+
+	ixgbevf_update_stats(adapter);
+
+pf_has_reset:
+	/* Force detection of hung controller every watchdog period */
+	adapter->detect_tx_hung = true;
+
+	/* Reset the timer */
+	if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
+		mod_timer(&adapter->watchdog_timer,
+			  round_jiffies(jiffies + (2 * HZ)));
+
+	adapter->flags &= ~IXGBE_FLAG_IN_WATCHDOG_TASK;
+}
+
+/**
+ * ixgbevf_free_tx_resources - Free Tx Resources per Queue
+ * @adapter: board private structure
+ * @tx_ring: Tx descriptor ring for a specific queue
+ *
+ * Free all transmit software resources
+ **/
+void ixgbevf_free_tx_resources(struct ixgbevf_adapter *adapter,
+			       struct ixgbevf_ring *tx_ring)
+{
+	struct pci_dev *pdev = adapter->pdev;
+
+	ixgbevf_clean_tx_ring(adapter, tx_ring);
+
+	vfree(tx_ring->tx_buffer_info);
+	tx_ring->tx_buffer_info = NULL;
+
+	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
+
+	tx_ring->desc = NULL;
+}
+
+/**
+ * ixgbevf_free_all_tx_resources - Free Tx Resources for All Queues
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ **/
+static void ixgbevf_free_all_tx_resources(struct ixgbevf_adapter *adapter)
+{
+	int i;
+
+	for (i = 0; i < adapter->num_tx_queues; i++)
+		if (adapter->tx_ring[i].desc)
+			ixgbevf_free_tx_resources(adapter,
+						  &adapter->tx_ring[i]);
+
+}
+
+/**
+ * ixgbevf_setup_tx_resources - allocate Tx resources (Descriptors)
+ * @adapter: board private structure
+ * @tx_ring:    tx descriptor ring (for a specific queue) to setup
+ *
+ * Return 0 on success, negative on failure
+ **/
+int ixgbevf_setup_tx_resources(struct ixgbevf_adapter *adapter,
+			       struct ixgbevf_ring *tx_ring)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	int size;
+
+	size = sizeof(struct ixgbevf_tx_buffer) * tx_ring->count;
+	tx_ring->tx_buffer_info = vmalloc(size);
+	if (!tx_ring->tx_buffer_info)
+		goto err;
+	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);
+	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->next_to_use = 0;
+	tx_ring->next_to_clean = 0;
+	tx_ring->work_limit = tx_ring->count;
+	return 0;
+
+err:
+	vfree(tx_ring->tx_buffer_info);
+	tx_ring->tx_buffer_info = NULL;
+	hw_dbg(&adapter->hw, "Unable to allocate memory for the transmit "
+	       "descriptor ring\n");
+	return -ENOMEM;
+}
+
+/**
+ * ixgbevf_setup_all_tx_resources - allocate all queues Tx resources
+ * @adapter: board private structure
+ *
+ * If this function returns with an error, then it's possible one or
+ * more of the rings is populated (while the rest are not).  It is the
+ * callers duty to clean those orphaned rings.
+ *
+ * Return 0 on success, negative on failure
+ **/
+static int ixgbevf_setup_all_tx_resources(struct ixgbevf_adapter *adapter)
+{
+	int i, err = 0;
+
+	for (i = 0; i < adapter->num_tx_queues; i++) {
+		err = ixgbevf_setup_tx_resources(adapter, &adapter->tx_ring[i]);
+		if (!err)
+			continue;
+		hw_dbg(&adapter->hw,
+		       "Allocation for Tx Queue %u failed\n", i);
+		break;
+	}
+
+	return err;
+}
+
+/**
+ * ixgbevf_setup_rx_resources - allocate Rx resources (Descriptors)
+ * @adapter: board private structure
+ * @rx_ring:    rx descriptor ring (for a specific queue) to setup
+ *
+ * Returns 0 on success, negative on failure
+ **/
+int ixgbevf_setup_rx_resources(struct ixgbevf_adapter *adapter,
+			       struct ixgbevf_ring *rx_ring)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	int size;
+
+	size = sizeof(struct ixgbevf_rx_buffer) * rx_ring->count;
+	rx_ring->rx_buffer_info = vmalloc(size);
+	if (!rx_ring->rx_buffer_info) {
+		hw_dbg(&adapter->hw,
+		       "Unable to vmalloc buffer memory for "
+		       "the receive descriptor ring\n");
+		goto alloc_failed;
+	}
+	memset(rx_ring->rx_buffer_info, 0, size);
+
+	/* Round up to nearest 4K */
+	rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc);
+	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) {
+		hw_dbg(&adapter->hw,
+		       "Unable to allocate memory for "
+		       "the receive descriptor ring\n");
+		vfree(rx_ring->rx_buffer_info);
+		rx_ring->rx_buffer_info = NULL;
+		goto alloc_failed;
+	}
+
+	rx_ring->next_to_clean = 0;
+	rx_ring->next_to_use = 0;
+
+	return 0;
+alloc_failed:
+	return -ENOMEM;
+}
+
+/**
+ * ixgbevf_setup_all_rx_resources - allocate all queues Rx resources
+ * @adapter: board private structure
+ *
+ * If this function returns with an error, then it's possible one or
+ * more of the rings is populated (while the rest are not).  It is the
+ * callers duty to clean those orphaned rings.
+ *
+ * Return 0 on success, negative on failure
+ **/
+static int ixgbevf_setup_all_rx_resources(struct ixgbevf_adapter *adapter)
+{
+	int i, err = 0;
+
+	for (i = 0; i < adapter->num_rx_queues; i++) {
+		err = ixgbevf_setup_rx_resources(adapter, &adapter->rx_ring[i]);
+		if (!err)
+			continue;
+		hw_dbg(&adapter->hw,
+		       "Allocation for Rx Queue %u failed\n", i);
+		break;
+	}
+	return err;
+}
+
+/**
+ * ixgbevf_free_rx_resources - Free Rx Resources
+ * @adapter: board private structure
+ * @rx_ring: ring to clean the resources from
+ *
+ * Free all receive software resources
+ **/
+void ixgbevf_free_rx_resources(struct ixgbevf_adapter *adapter,
+			       struct ixgbevf_ring *rx_ring)
+{
+	struct pci_dev *pdev = adapter->pdev;
+
+	ixgbevf_clean_rx_ring(adapter, rx_ring);
+
+	vfree(rx_ring->rx_buffer_info);
+	rx_ring->rx_buffer_info = NULL;
+
+	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
+
+	rx_ring->desc = NULL;
+}
+
+/**
+ * ixgbevf_free_all_rx_resources - Free Rx Resources for All Queues
+ * @adapter: board private structure
+ *
+ * Free all receive software resources
+ **/
+static void ixgbevf_free_all_rx_resources(struct ixgbevf_adapter *adapter)
+{
+	int i;
+
+	for (i = 0; i < adapter->num_rx_queues; i++)
+		if (adapter->rx_ring[i].desc)
+			ixgbevf_free_rx_resources(adapter,
+						  &adapter->rx_ring[i]);
+}
+
+/**
+ * ixgbevf_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 ixgbevf_open(struct net_device *netdev)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_hw *hw = &adapter->hw;
+	int err;
+
+	/* disallow open during test */
+	if (test_bit(__IXGBEVF_TESTING, &adapter->state))
+		return -EBUSY;
+
+	if (hw->adapter_stopped) {
+		ixgbevf_reset(adapter);
+		/* if adapter is still stopped then PF isn't up and
+		 * the vf can't start. */
+		if (hw->adapter_stopped) {
+			err = IXGBE_ERR_MBX;
+			printk(KERN_ERR "Unable to start - perhaps the PF"
+			       " Driver isn't up yet\n");
+			goto err_setup_reset;
+		}
+	}
+
+	/* allocate transmit descriptors */
+	err = ixgbevf_setup_all_tx_resources(adapter);
+	if (err)
+		goto err_setup_tx;
+
+	/* allocate receive descriptors */
+	err = ixgbevf_setup_all_rx_resources(adapter);
+	if (err)
+		goto err_setup_rx;
+
+	ixgbevf_configure(adapter);
+
+	/*
+	 * Map the Tx/Rx rings to the vectors we were allotted.
+	 * if request_irq will be called in this function map_rings
+	 * must be called *before* up_complete
+	 */
+	ixgbevf_map_rings_to_vectors(adapter);
+
+	err = ixgbevf_up_complete(adapter);
+	if (err)
+		goto err_up;
+
+	/* clear any pending interrupts, may auto mask */
+	IXGBE_READ_REG(hw, IXGBE_VTEICR);
+	err = ixgbevf_request_irq(adapter);
+	if (err)
+		goto err_req_irq;
+
+	ixgbevf_irq_enable(adapter, true, true);
+
+	return 0;
+
+err_req_irq:
+	ixgbevf_down(adapter);
+err_up:
+	ixgbevf_free_irq(adapter);
+err_setup_rx:
+	ixgbevf_free_all_rx_resources(adapter);
+err_setup_tx:
+	ixgbevf_free_all_tx_resources(adapter);
+	ixgbevf_reset(adapter);
+
+err_setup_reset:
+
+	return err;
+}
+
+/**
+ * ixgbevf_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 ixgbevf_close(struct net_device *netdev)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+
+	ixgbevf_down(adapter);
+	ixgbevf_free_irq(adapter);
+
+	ixgbevf_free_all_tx_resources(adapter);
+	ixgbevf_free_all_rx_resources(adapter);
+
+	return 0;
+}
+
+static int ixgbevf_tso(struct ixgbevf_adapter *adapter,
+		       struct ixgbevf_ring *tx_ring,
+		       struct sk_buff *skb, u32 tx_flags, u8 *hdr_len)
+{
+	struct ixgbe_adv_tx_context_desc *context_desc;
+	unsigned int i;
+	int err;
+	struct ixgbevf_tx_buffer *tx_buffer_info;
+	u32 vlan_macip_lens = 0, type_tucmd_mlhl;
+	u32 mss_l4len_idx, l4len;
+
+	if (skb_is_gso(skb)) {
+		if (skb_header_cloned(skb)) {
+			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+			if (err)
+				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);
+			adapter->hw_tso_ctxt++;
+		} else if (skb_is_gso_v6(skb)) {
+			ipv6_hdr(skb)->payload_len = 0;
+			tcp_hdr(skb)->check =
+			    ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+					     &ipv6_hdr(skb)->daddr,
+					     0, IPPROTO_TCP, 0);
+			adapter->hw_tso6_ctxt++;
+		}
+
+		i = tx_ring->next_to_use;
+
+		tx_buffer_info = &tx_ring->tx_buffer_info[i];
+		context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i);
+
+		/* VLAN MACLEN IPLEN */
+		if (tx_flags & IXGBE_TX_FLAGS_VLAN)
+			vlan_macip_lens |=
+				(tx_flags & IXGBE_TX_FLAGS_VLAN_MASK);
+		vlan_macip_lens |= ((skb_network_offset(skb)) <<
+				    IXGBE_ADVTXD_MACLEN_SHIFT);
+		*hdr_len += skb_network_offset(skb);
+		vlan_macip_lens |=
+			(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(vlan_macip_lens);
+		context_desc->seqnum_seed = 0;
+
+		/* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
+		type_tucmd_mlhl = (IXGBE_TXD_CMD_DEXT |
+				    IXGBE_ADVTXD_DTYP_CTXT);
+
+		if (skb->protocol == htons(ETH_P_IP))
+			type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
+		type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP;
+		context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl);
+
+		/* MSS L4LEN IDX */
+		mss_l4len_idx =
+			(skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT);
+		mss_l4len_idx |= (l4len << IXGBE_ADVTXD_L4LEN_SHIFT);
+		/* use index 1 for TSO */
+		mss_l4len_idx |= (1 << IXGBE_ADVTXD_IDX_SHIFT);
+		context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
+
+		tx_buffer_info->time_stamp = jiffies;
+		tx_buffer_info->next_to_watch = i;
+
+		i++;
+		if (i == tx_ring->count)
+			i = 0;
+		tx_ring->next_to_use = i;
+
+		return true;
+	}
+
+	return false;
+}
+
+static bool ixgbevf_tx_csum(struct ixgbevf_adapter *adapter,
+			    struct ixgbevf_ring *tx_ring,
+			    struct sk_buff *skb, u32 tx_flags)
+{
+	struct ixgbe_adv_tx_context_desc *context_desc;
+	unsigned int i;
+	struct ixgbevf_tx_buffer *tx_buffer_info;
+	u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0;
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL ||
+	    (tx_flags & IXGBE_TX_FLAGS_VLAN)) {
+		i = tx_ring->next_to_use;
+		tx_buffer_info = &tx_ring->tx_buffer_info[i];
+		context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i);
+
+		if (tx_flags & IXGBE_TX_FLAGS_VLAN)
+			vlan_macip_lens |= (tx_flags &
+					    IXGBE_TX_FLAGS_VLAN_MASK);
+		vlan_macip_lens |= (skb_network_offset(skb) <<
+				    IXGBE_ADVTXD_MACLEN_SHIFT);
+		if (skb->ip_summed == CHECKSUM_PARTIAL)
+			vlan_macip_lens |= (skb_transport_header(skb) -
+					    skb_network_header(skb));
+
+		context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
+		context_desc->seqnum_seed = 0;
+
+		type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT |
+				    IXGBE_ADVTXD_DTYP_CTXT);
+
+		if (skb->ip_summed == CHECKSUM_PARTIAL) {
+			switch (skb->protocol) {
+			case __constant_htons(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):
+				/* XXX what about other V6 headers?? */
+				if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
+					type_tucmd_mlhl |=
+						IXGBE_ADVTXD_TUCMD_L4T_TCP;
+				break;
+			default:
+				if (unlikely(net_ratelimit())) {
+					printk(KERN_WARNING
+					       "partial checksum but "
+					       "proto=%x!\n",
+					       skb->protocol);
+				}
+				break;
+			}
+		}
+
+		context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl);
+		/* use index zero for tx checksum offload */
+		context_desc->mss_l4len_idx = 0;
+
+		tx_buffer_info->time_stamp = jiffies;
+		tx_buffer_info->next_to_watch = i;
+
+		adapter->hw_csum_tx_good++;
+		i++;
+		if (i == tx_ring->count)
+			i = 0;
+		tx_ring->next_to_use = i;
+
+		return true;
+	}
+
+	return false;
+}
+
+static int ixgbevf_tx_map(struct ixgbevf_adapter *adapter,
+			  struct ixgbevf_ring *tx_ring,
+			  struct sk_buff *skb, u32 tx_flags,
+			  unsigned int first)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	struct ixgbevf_tx_buffer *tx_buffer_info;
+	unsigned int len;
+	unsigned int total = skb->len;
+	unsigned int offset = 0, size, count = 0;
+	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
+	unsigned int f;
+	int i;
+
+	i = tx_ring->next_to_use;
+
+	len = min(skb_headlen(skb), total);
+	while (len) {
+		tx_buffer_info = &tx_ring->tx_buffer_info[i];
+		size = min(len, (unsigned int)IXGBE_MAX_DATA_PER_TXD);
+
+		tx_buffer_info->length = size;
+		tx_buffer_info->mapped_as_page = false;
+		tx_buffer_info->dma = pci_map_single(adapter->pdev,
+						     skb->data + offset,
+						     size, PCI_DMA_TODEVICE);
+		if (pci_dma_mapping_error(pdev, tx_buffer_info->dma))
+			goto dma_error;
+		tx_buffer_info->time_stamp = jiffies;
+		tx_buffer_info->next_to_watch = i;
+
+		len -= size;
+		total -= size;
+		offset += size;
+		count++;
+		i++;
+		if (i == tx_ring->count)
+			i = 0;
+	}
+
+	for (f = 0; f < nr_frags; f++) {
+		struct skb_frag_struct *frag;
+
+		frag = &skb_shinfo(skb)->frags[f];
+		len = min((unsigned int)frag->size, total);
+		offset = frag->page_offset;
+
+		while (len) {
+			tx_buffer_info = &tx_ring->tx_buffer_info[i];
+			size = min(len, (unsigned int)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->mapped_as_page = true;
+			if (pci_dma_mapping_error(pdev, tx_buffer_info->dma))
+				goto dma_error;
+			tx_buffer_info->time_stamp = jiffies;
+			tx_buffer_info->next_to_watch = i;
+
+			len -= size;
+			total -= size;
+			offset += size;
+			count++;
+			i++;
+			if (i == tx_ring->count)
+				i = 0;
+		}
+		if (total == 0)
+			break;
+	}
+
+	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;
+
+	return count;
+
+dma_error:
+	dev_err(&pdev->dev, "TX DMA map failed\n");
+
+	/* clear timestamp and dma mappings for failed tx_buffer_info map */
+	tx_buffer_info->dma = 0;
+	tx_buffer_info->time_stamp = 0;
+	tx_buffer_info->next_to_watch = 0;
+	count--;
+
+	/* clear timestamp and dma mappings for remaining portion of packet */
+	while (count >= 0) {
+		count--;
+		i--;
+		if (i < 0)
+			i += tx_ring->count;
+		tx_buffer_info = &tx_ring->tx_buffer_info[i];
+		ixgbevf_unmap_and_free_tx_resource(adapter, tx_buffer_info);
+	}
+
+	return count;
+}
+
+static void ixgbevf_tx_queue(struct ixgbevf_adapter *adapter,
+			     struct ixgbevf_ring *tx_ring, int tx_flags,
+			     int count, u32 paylen, u8 hdr_len)
+{
+	union ixgbe_adv_tx_desc *tx_desc = NULL;
+	struct ixgbevf_tx_buffer *tx_buffer_info;
+	u32 olinfo_status = 0, cmd_type_len = 0;
+	unsigned int i;
+
+	u32 txd_cmd = IXGBE_TXD_CMD_EOP | IXGBE_TXD_CMD_RS | IXGBE_TXD_CMD_IFCS;
+
+	cmd_type_len |= IXGBE_ADVTXD_DTYP_DATA;
+
+	cmd_type_len |= IXGBE_ADVTXD_DCMD_IFCS | IXGBE_ADVTXD_DCMD_DEXT;
+
+	if (tx_flags & IXGBE_TX_FLAGS_VLAN)
+		cmd_type_len |= IXGBE_ADVTXD_DCMD_VLE;
+
+	if (tx_flags & IXGBE_TX_FLAGS_TSO) {
+		cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
+
+		olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
+			IXGBE_ADVTXD_POPTS_SHIFT;
+
+		/* use index 1 context for tso */
+		olinfo_status |= (1 << IXGBE_ADVTXD_IDX_SHIFT);
+		if (tx_flags & IXGBE_TX_FLAGS_IPV4)
+			olinfo_status |= IXGBE_TXD_POPTS_IXSM <<
+				IXGBE_ADVTXD_POPTS_SHIFT;
+
+	} else if (tx_flags & IXGBE_TX_FLAGS_CSUM)
+		olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
+			IXGBE_ADVTXD_POPTS_SHIFT;
+
+	olinfo_status |= ((paylen - hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT);
+
+	i = tx_ring->next_to_use;
+	while (count--) {
+		tx_buffer_info = &tx_ring->tx_buffer_info[i];
+		tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
+		tx_desc->read.buffer_addr = cpu_to_le64(tx_buffer_info->dma);
+		tx_desc->read.cmd_type_len =
+			cpu_to_le32(cmd_type_len | tx_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(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);
+}
+
+static int __ixgbevf_maybe_stop_tx(struct net_device *netdev,
+				   struct ixgbevf_ring *tx_ring, int size)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+
+	netif_stop_subqueue(netdev, tx_ring->queue_index);
+	/* Herbert's original patch had:
+	 *  smp_mb__after_netif_stop_queue();
+	 * but since that doesn't exist yet, just open code it. */
+	smp_mb();
+
+	/* We need to check again in a case another CPU has just
+	 * made room available. */
+	if (likely(IXGBE_DESC_UNUSED(tx_ring) < size))
+		return -EBUSY;
+
+	/* A reprieve! - use start_queue because it doesn't call schedule */
+	netif_start_subqueue(netdev, tx_ring->queue_index);
+	++adapter->restart_queue;
+	return 0;
+}
+
+static int ixgbevf_maybe_stop_tx(struct net_device *netdev,
+				 struct ixgbevf_ring *tx_ring, int size)
+{
+	if (likely(IXGBE_DESC_UNUSED(tx_ring) >= size))
+		return 0;
+	return __ixgbevf_maybe_stop_tx(netdev, tx_ring, size);
+}
+
+static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	struct ixgbevf_ring *tx_ring;
+	unsigned int first;
+	unsigned int tx_flags = 0;
+	u8 hdr_len = 0;
+	int r_idx = 0, tso;
+	int count = 0;
+
+	unsigned int f;
+
+	tx_ring = &adapter->tx_ring[r_idx];
+
+	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+		tx_flags |= vlan_tx_tag_get(skb);
+		tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
+		tx_flags |= IXGBE_TX_FLAGS_VLAN;
+	}
+
+	/* four things can cause us to need a context descriptor */
+	if (skb_is_gso(skb) ||
+	    (skb->ip_summed == CHECKSUM_PARTIAL) ||
+	    (tx_flags & IXGBE_TX_FLAGS_VLAN))
+		count++;
+
+	count += TXD_USE_COUNT(skb_headlen(skb));
+	for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
+		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
+
+	if (ixgbevf_maybe_stop_tx(netdev, tx_ring, count)) {
+		adapter->tx_busy++;
+		return NETDEV_TX_BUSY;
+	}
+
+	first = tx_ring->next_to_use;
+
+	if (skb->protocol == htons(ETH_P_IP))
+		tx_flags |= IXGBE_TX_FLAGS_IPV4;
+	tso = ixgbevf_tso(adapter, tx_ring, skb, tx_flags, &hdr_len);
+	if (tso < 0) {
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
+	}
+
+	if (tso)
+		tx_flags |= IXGBE_TX_FLAGS_TSO;
+	else if (ixgbevf_tx_csum(adapter, tx_ring, skb, tx_flags) &&
+		 (skb->ip_summed == CHECKSUM_PARTIAL))
+		tx_flags |= IXGBE_TX_FLAGS_CSUM;
+
+	ixgbevf_tx_queue(adapter, tx_ring, tx_flags,
+			 ixgbevf_tx_map(adapter, tx_ring, skb, tx_flags, first),
+			 skb->len, hdr_len);
+
+	netdev->trans_start = jiffies;
+
+	ixgbevf_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
+
+	return NETDEV_TX_OK;
+}
+
+/**
+ * ixgbevf_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 *ixgbevf_get_stats(struct net_device *netdev)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+
+	/* only return the current stats */
+	return &adapter->net_stats;
+}
+
+/**
+ * ixgbevf_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 ixgbevf_set_mac(struct net_device *netdev, void *p)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_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(hw->mac.addr, addr->sa_data, netdev->addr_len);
+
+	if (hw->mac.ops.set_rar)
+		hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0);
+
+	return 0;
+}
+
+/**
+ * ixgbevf_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 ixgbevf_change_mtu(struct net_device *netdev, int new_mtu)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
+
+	/* MTU < 68 is an error and causes problems on some kernels */
+	if ((new_mtu < 68) || (max_frame > MAXIMUM_ETHERNET_VLAN_SIZE))
+		return -EINVAL;
+
+	hw_dbg(&adapter->hw, "changing MTU from %d to %d\n",
+	       netdev->mtu, new_mtu);
+	/* must set new MTU before calling down or up */
+	netdev->mtu = new_mtu;
+
+	if (netif_running(netdev))
+		ixgbevf_reinit_locked(adapter);
+
+	return 0;
+}
+
+static void ixgbevf_shutdown(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+
+	netif_device_detach(netdev);
+
+	if (netif_running(netdev)) {
+		ixgbevf_down(adapter);
+		ixgbevf_free_irq(adapter);
+		ixgbevf_free_all_tx_resources(adapter);
+		ixgbevf_free_all_rx_resources(adapter);
+	}
+
+#ifdef CONFIG_PM
+	pci_save_state(pdev);
+#endif
+
+	pci_disable_device(pdev);
+}
+
+static const struct net_device_ops ixgbe_netdev_ops = {
+	.ndo_open		= &ixgbevf_open,
+	.ndo_stop		= &ixgbevf_close,
+	.ndo_start_xmit		= &ixgbevf_xmit_frame,
+	.ndo_get_stats		= &ixgbevf_get_stats,
+	.ndo_set_rx_mode	= &ixgbevf_set_rx_mode,
+	.ndo_set_multicast_list	= &ixgbevf_set_rx_mode,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= &ixgbevf_set_mac,
+	.ndo_change_mtu		= &ixgbevf_change_mtu,
+	.ndo_tx_timeout		= &ixgbevf_tx_timeout,
+	.ndo_vlan_rx_register	= &ixgbevf_vlan_rx_register,
+	.ndo_vlan_rx_add_vid	= &ixgbevf_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid	= &ixgbevf_vlan_rx_kill_vid,
+};
+
+static void ixgbevf_assign_netdev_ops(struct net_device *dev)
+{
+	struct ixgbevf_adapter *adapter;
+	adapter = netdev_priv(dev);
+	dev->netdev_ops = &ixgbe_netdev_ops;
+	ixgbevf_set_ethtool_ops(dev);
+	dev->watchdog_timeo = 5 * HZ;
+}
+
+/**
+ * ixgbevf_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in ixgbevf_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * ixgbevf_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 ixgbevf_probe(struct pci_dev *pdev,
+				   const struct pci_device_id *ent)
+{
+	struct net_device *netdev;
+	struct ixgbevf_adapter *adapter = NULL;
+	struct ixgbe_hw *hw = NULL;
+	const struct ixgbevf_info *ii = ixgbevf_info_tbl[ent->driver_data];
+	static int cards_found;
+	int err, pci_using_dac;
+
+	err = pci_enable_device(pdev);
+	if (err)
+		return err;
+
+	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_BIT_MASK(32));
+		if (err) {
+			err = pci_set_consistent_dma_mask(pdev,
+							  DMA_BIT_MASK(32));
+			if (err) {
+				dev_err(&pdev->dev, "No usable DMA "
+					"configuration, aborting\n");
+				goto err_dma;
+			}
+		}
+		pci_using_dac = 0;
+	}
+
+	err = pci_request_regions(pdev, ixgbevf_driver_name);
+	if (err) {
+		dev_err(&pdev->dev, "pci_request_regions failed 0x%x\n", err);
+		goto err_pci_reg;
+	}
+
+	pci_set_master(pdev);
+
+#ifdef HAVE_TX_MQ
+	netdev = alloc_etherdev_mq(sizeof(struct ixgbevf_adapter),
+				   MAX_TX_QUEUES);
+#else
+	netdev = alloc_etherdev(sizeof(struct ixgbevf_adapter));
+#endif
+	if (!netdev) {
+		err = -ENOMEM;
+		goto err_alloc_etherdev;
+	}
+
+	SET_NETDEV_DEV(netdev, &pdev->dev);
+
+	pci_set_drvdata(pdev, netdev);
+	adapter = netdev_priv(netdev);
+
+	adapter->netdev = netdev;
+	adapter->pdev = pdev;
+	hw = &adapter->hw;
+	hw->back = adapter;
+	adapter->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1;
+
+	/*
+	 * call save state here in standalone driver because it relies on
+	 * adapter struct to exist, and needs to call netdev_priv
+	 */
+	pci_save_state(pdev);
+
+	hw->hw_addr = ioremap(pci_resource_start(pdev, 0),
+			      pci_resource_len(pdev, 0));
+	if (!hw->hw_addr) {
+		err = -EIO;
+		goto err_ioremap;
+	}
+
+	ixgbevf_assign_netdev_ops(netdev);
+
+	adapter->bd_number = cards_found;
+
+	/* Setup hw api */
+	memcpy(&hw->mac.ops, ii->mac_ops, sizeof(hw->mac.ops));
+	hw->mac.type  = ii->mac;
+
+	memcpy(&hw->mbx.ops, &ixgbevf_mbx_ops,
+	       sizeof(struct ixgbe_mac_operations));
+
+	adapter->flags &= ~IXGBE_FLAG_RX_PS_CAPABLE;
+	adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED;
+	adapter->flags |= IXGBE_FLAG_RX_1BUF_CAPABLE;
+
+	/* setup the private structure */
+	err = ixgbevf_sw_init(adapter);
+
+#ifdef MAX_SKB_FRAGS
+	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;
+	netdev->vlan_features |= NETIF_F_TSO;
+	netdev->vlan_features |= NETIF_F_TSO6;
+	netdev->vlan_features |= NETIF_F_IP_CSUM;
+	netdev->vlan_features |= NETIF_F_SG;
+
+	if (pci_using_dac)
+		netdev->features |= NETIF_F_HIGHDMA;
+
+#endif /* MAX_SKB_FRAGS */
+
+	/* The HW MAC address was set and/or determined in sw_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->dev_addr)) {
+		printk(KERN_ERR "invalid MAC address\n");
+		err = -EIO;
+		goto err_sw_init;
+	}
+
+	init_timer(&adapter->watchdog_timer);
+	adapter->watchdog_timer.function = &ixgbevf_watchdog;
+	adapter->watchdog_timer.data = (unsigned long)adapter;
+
+	INIT_WORK(&adapter->reset_task, ixgbevf_reset_task);
+	INIT_WORK(&adapter->watchdog_task, ixgbevf_watchdog_task);
+
+	err = ixgbevf_init_interrupt_scheme(adapter);
+	if (err)
+		goto err_sw_init;
+
+	/* pick up the PCI bus settings for reporting later */
+	if (hw->mac.ops.get_bus_info)
+		hw->mac.ops.get_bus_info(hw);
+
+
+	netif_carrier_off(netdev);
+	netif_tx_stop_all_queues(netdev);
+
+	strcpy(netdev->name, "eth%d");
+
+	err = register_netdev(netdev);
+	if (err)
+		goto err_register;
+
+	adapter->netdev_registered = true;
+
+	ixgbevf_init_last_counter_stats(adapter);
+
+	/* print the MAC address */
+	hw_dbg(hw, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\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]);
+
+	hw_dbg(hw, "MAC: %d\n", hw->mac.type);
+
+	hw_dbg(hw, "LRO is disabled \n");
+
+	hw_dbg(hw, "Intel(R) 82599 Virtual Function\n");
+	cards_found++;
+	return 0;
+
+err_register:
+err_sw_init:
+	ixgbevf_reset_interrupt_capability(adapter);
+	iounmap(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;
+}
+
+/**
+ * ixgbevf_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * ixgbevf_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 ixgbevf_remove(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+
+	set_bit(__IXGBEVF_DOWN, &adapter->state);
+
+	del_timer_sync(&adapter->watchdog_timer);
+
+	cancel_work_sync(&adapter->watchdog_task);
+
+	flush_scheduled_work();
+
+	if (adapter->netdev_registered) {
+		unregister_netdev(netdev);
+		adapter->netdev_registered = false;
+	}
+
+	ixgbevf_reset_interrupt_capability(adapter);
+
+	iounmap(adapter->hw.hw_addr);
+	pci_release_regions(pdev);
+
+	hw_dbg(&adapter->hw, "Remove complete\n");
+
+	kfree(adapter->tx_ring);
+	kfree(adapter->rx_ring);
+
+	free_netdev(netdev);
+
+	pci_disable_device(pdev);
+}
+
+static struct pci_driver ixgbevf_driver = {
+	.name     = ixgbevf_driver_name,
+	.id_table = ixgbevf_pci_tbl,
+	.probe    = ixgbevf_probe,
+	.remove   = __devexit_p(ixgbevf_remove),
+	.shutdown = ixgbevf_shutdown,
+};
+
+/**
+ * ixgbe_init_module - Driver Registration Routine
+ *
+ * ixgbe_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ **/
+static int __init ixgbevf_init_module(void)
+{
+	int ret;
+	printk(KERN_INFO "ixgbevf: %s - version %s\n", ixgbevf_driver_string,
+	       ixgbevf_driver_version);
+
+	printk(KERN_INFO "%s\n", ixgbevf_copyright);
+
+	ret = pci_register_driver(&ixgbevf_driver);
+	return ret;
+}
+
+module_init(ixgbevf_init_module);
+
+/**
+ * ixgbe_exit_module - Driver Exit Cleanup Routine
+ *
+ * ixgbe_exit_module is called just before the driver is removed
+ * from memory.
+ **/
+static void __exit ixgbevf_exit_module(void)
+{
+	pci_unregister_driver(&ixgbevf_driver);
+}
+
+#ifdef DEBUG
+/**
+ * ixgbe_get_hw_dev_name - return device name string
+ * used by hardware layer to print debugging information
+ **/
+char *ixgbevf_get_hw_dev_name(struct ixgbe_hw *hw)
+{
+	struct ixgbevf_adapter *adapter = hw->back;
+	return adapter->netdev->name;
+}
+
+#endif
+module_exit(ixgbevf_exit_module);
+
+/* ixgbevf_main.c */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/Makefile linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,38 @@
+################################################################################
+#
+# Intel 82599 Virtual Function 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
+#
+################################################################################
+
+#
+# Makefile for the Intel(R) 82599 VF ethernet driver
+#
+
+obj-$(CONFIG_IXGBEVF) += ixgbevf.o
+
+ixgbevf-objs := vf.o \
+                mbx.o \
+                ethtool.o \
+                ixgbevf_main.o
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/mbx.c linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/mbx.c
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/mbx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/mbx.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,341 @@
+/*******************************************************************************
+
+  Intel 82599 Virtual Function 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 "mbx.h"
+
+/**
+ *  ixgbevf_poll_for_msg - Wait for message notification
+ *  @hw: pointer to the HW structure
+ *
+ *  returns 0 if it successfully received a message notification
+ **/
+static s32 ixgbevf_poll_for_msg(struct ixgbe_hw *hw)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	int countdown = mbx->timeout;
+
+	while (countdown && mbx->ops.check_for_msg(hw)) {
+		countdown--;
+		udelay(mbx->udelay);
+	}
+
+	/* if we failed, all future posted messages fail until reset */
+	if (!countdown)
+		mbx->timeout = 0;
+
+	return countdown ? 0 : IXGBE_ERR_MBX;
+}
+
+/**
+ *  ixgbevf_poll_for_ack - Wait for message acknowledgement
+ *  @hw: pointer to the HW structure
+ *
+ *  returns 0 if it successfully received a message acknowledgement
+ **/
+static s32 ixgbevf_poll_for_ack(struct ixgbe_hw *hw)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	int countdown = mbx->timeout;
+
+	while (countdown && mbx->ops.check_for_ack(hw)) {
+		countdown--;
+		udelay(mbx->udelay);
+	}
+
+	/* if we failed, all future posted messages fail until reset */
+	if (!countdown)
+		mbx->timeout = 0;
+
+	return countdown ? 0 : IXGBE_ERR_MBX;
+}
+
+/**
+ *  ixgbevf_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 0 if it successfully received a message notification and
+ *  copied it into the receive buffer.
+ **/
+static s32 ixgbevf_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = IXGBE_ERR_MBX;
+
+	ret_val = ixgbevf_poll_for_msg(hw);
+
+	/* if ack received read message, otherwise we timed out */
+	if (!ret_val)
+		ret_val = mbx->ops.read(hw, msg, size);
+
+	return ret_val;
+}
+
+/**
+ *  ixgbevf_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 0 if it successfully copied message into the buffer and
+ *  received an ack to that message within delay * timeout period
+ **/
+static s32 ixgbevf_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	s32 ret_val;
+
+	/* send msg */
+	ret_val = mbx->ops.write(hw, msg, size);
+
+	/* if msg sent wait until we receive an ack */
+	if (!ret_val)
+		ret_val = ixgbevf_poll_for_ack(hw);
+
+	return ret_val;
+}
+
+/**
+ *  ixgbevf_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 ixgbevf_read_v2p_mailbox(struct ixgbe_hw *hw)
+{
+	u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
+
+	v2p_mailbox |= hw->mbx.v2p_mailbox;
+	hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
+
+	return v2p_mailbox;
+}
+
+/**
+ *  ixgbevf_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 ixgbevf_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
+{
+	u32 v2p_mailbox = ixgbevf_read_v2p_mailbox(hw);
+	s32 ret_val = IXGBE_ERR_MBX;
+
+	if (v2p_mailbox & mask)
+		ret_val = 0;
+
+	hw->mbx.v2p_mailbox &= ~mask;
+
+	return ret_val;
+}
+
+/**
+ *  ixgbevf_check_for_msg_vf - checks to see if the PF has sent mail
+ *  @hw: pointer to the HW structure
+ *
+ *  returns 0 if the PF has set the Status bit or else ERR_MBX
+ **/
+static s32 ixgbevf_check_for_msg_vf(struct ixgbe_hw *hw)
+{
+	s32 ret_val = IXGBE_ERR_MBX;
+
+	if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
+		ret_val = 0;
+		hw->mbx.stats.reqs++;
+	}
+
+	return ret_val;
+}
+
+/**
+ *  ixgbevf_check_for_ack_vf - checks to see if the PF has ACK'd
+ *  @hw: pointer to the HW structure
+ *
+ *  returns 0 if the PF has set the ACK bit or else ERR_MBX
+ **/
+static s32 ixgbevf_check_for_ack_vf(struct ixgbe_hw *hw)
+{
+	s32 ret_val = IXGBE_ERR_MBX;
+
+	if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
+		ret_val = 0;
+		hw->mbx.stats.acks++;
+	}
+
+	return ret_val;
+}
+
+/**
+ *  ixgbevf_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 ixgbevf_check_for_rst_vf(struct ixgbe_hw *hw)
+{
+	s32 ret_val = IXGBE_ERR_MBX;
+
+	if (!ixgbevf_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
+					 IXGBE_VFMAILBOX_RSTI))) {
+		ret_val = 0;
+		hw->mbx.stats.rsts++;
+	}
+
+	return ret_val;
+}
+
+/**
+ *  ixgbevf_obtain_mbx_lock_vf - obtain mailbox lock
+ *  @hw: pointer to the HW structure
+ *
+ *  return 0 if we obtained the mailbox lock
+ **/
+static s32 ixgbevf_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
+{
+	s32 ret_val = IXGBE_ERR_MBX;
+
+	/* Take ownership of the buffer */
+	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
+
+	/* reserve mailbox for vf use */
+	if (ixgbevf_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
+		ret_val = 0;
+
+	return ret_val;
+}
+
+/**
+ *  ixgbevf_write_mbx_vf - Write a message to the mailbox
+ *  @hw: pointer to the HW structure
+ *  @msg: The message buffer
+ *  @size: Length of buffer
+ *
+ *  returns 0 if it successfully copied message into the buffer
+ **/
+static s32 ixgbevf_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)
+{
+	s32 ret_val;
+	u16 i;
+
+
+	/* lock the mailbox to prevent pf/vf race condition */
+	ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
+	if (ret_val)
+		goto out_no_write;
+
+	/* flush msg and acks as we are overwriting the message buffer */
+	ixgbevf_check_for_msg_vf(hw);
+	ixgbevf_check_for_ack_vf(hw);
+
+	/* copy the caller specified message to the mailbox memory buffer */
+	for (i = 0; i < size; i++)
+		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
+
+	/* update stats */
+	hw->mbx.stats.msgs_tx++;
+
+	/* Drop VFU and interrupt the PF to tell it a message has been sent */
+	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
+
+out_no_write:
+	return ret_val;
+}
+
+/**
+ *  ixgbevf_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 0 if it successfuly read message from buffer
+ **/
+static s32 ixgbevf_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)
+{
+	s32 ret_val = 0;
+	u16 i;
+
+	/* lock the mailbox to prevent pf/vf race condition */
+	ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
+	if (ret_val)
+		goto out_no_read;
+
+	/* copy the message from the mailbox memory buffer */
+	for (i = 0; i < size; i++)
+		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
+
+	/* Acknowledge receipt and release mailbox, then we're done */
+	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
+
+	/* update stats */
+	hw->mbx.stats.msgs_rx++;
+
+out_no_read:
+	return ret_val;
+}
+
+/**
+ *  ixgbevf_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 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+
+	/* start mailbox as timed out and let the reset_hw call set the timeout
+	 * value to begin communications */
+	mbx->timeout = 0;
+	mbx->udelay = IXGBE_VF_MBX_INIT_DELAY;
+
+	mbx->size = IXGBE_VFMAILBOX_SIZE;
+
+	mbx->stats.msgs_tx = 0;
+	mbx->stats.msgs_rx = 0;
+	mbx->stats.reqs = 0;
+	mbx->stats.acks = 0;
+	mbx->stats.rsts = 0;
+
+	return 0;
+}
+
+struct ixgbe_mbx_operations ixgbevf_mbx_ops = {
+	.init_params   = ixgbevf_init_mbx_params_vf,
+	.read          = ixgbevf_read_mbx_vf,
+	.write         = ixgbevf_write_mbx_vf,
+	.read_posted   = ixgbevf_read_posted_mbx,
+	.write_posted  = ixgbevf_write_posted_mbx,
+	.check_for_msg = ixgbevf_check_for_msg_vf,
+	.check_for_ack = ixgbevf_check_for_ack_vf,
+	.check_for_rst = ixgbevf_check_for_rst_vf,
+};
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/mbx.h linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/mbx.h
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/mbx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/mbx.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,100 @@
+/*******************************************************************************
+
+  Intel 82599 Virtual Function 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 _IXGBE_MBX_H_
+#define _IXGBE_MBX_H_
+
+#include "vf.h"
+
+#define IXGBE_VFMAILBOX_SIZE        16 /* 16 32 bit words - 64 bytes */
+#define IXGBE_ERR_MBX               -100
+
+#define IXGBE_VFMAILBOX             0x002FC
+#define IXGBE_VFMBMEM               0x00200
+
+/* Define mailbox register bits */
+#define IXGBE_VFMAILBOX_REQ      0x00000001 /* Request for PF Ready bit */
+#define IXGBE_VFMAILBOX_ACK      0x00000002 /* Ack PF message received */
+#define IXGBE_VFMAILBOX_VFU      0x00000004 /* VF owns the mailbox buffer */
+#define IXGBE_VFMAILBOX_PFU      0x00000008 /* PF owns the mailbox buffer */
+#define IXGBE_VFMAILBOX_PFSTS    0x00000010 /* PF wrote a message in the MB */
+#define IXGBE_VFMAILBOX_PFACK    0x00000020 /* PF ack the previous VF msg */
+#define IXGBE_VFMAILBOX_RSTI     0x00000040 /* PF has reset indication */
+#define IXGBE_VFMAILBOX_RSTD     0x00000080 /* PF has indicated reset done */
+#define IXGBE_VFMAILBOX_R2C_BITS 0x000000B0 /* All read to clear bits */
+
+#define IXGBE_PFMAILBOX(x)          (0x04B00 + (4 * x))
+#define IXGBE_PFMBMEM(vfn)          (0x13000 + (64 * vfn))
+
+#define IXGBE_PFMAILBOX_STS   0x00000001 /* Initiate message send to VF */
+#define IXGBE_PFMAILBOX_ACK   0x00000002 /* Ack message recv'd from VF */
+#define IXGBE_PFMAILBOX_VFU   0x00000004 /* VF owns the mailbox buffer */
+#define IXGBE_PFMAILBOX_PFU   0x00000008 /* PF owns the mailbox buffer */
+#define IXGBE_PFMAILBOX_RVFU  0x00000010 /* Reset VFU - used when VF stuck */
+
+#define IXGBE_MBVFICR_VFREQ_MASK 0x0000FFFF /* bits for VF messages */
+#define IXGBE_MBVFICR_VFREQ_VF1  0x00000001 /* bit for VF 1 message */
+#define IXGBE_MBVFICR_VFACK_MASK 0xFFFF0000 /* bits for VF acks */
+#define IXGBE_MBVFICR_VFACK_VF1  0x00010000 /* bit for VF 1 ack */
+
+
+/* If it's a IXGBE_VF_* msg then it originates in the VF and is sent to the
+ * PF.  The reverse is true if it is IXGBE_PF_*.
+ * Message ACK's are the value or'd with 0xF0000000
+ */
+#define IXGBE_VT_MSGTYPE_ACK      0x80000000  /* Messages below or'd with
+					       * this are the ACK */
+#define IXGBE_VT_MSGTYPE_NACK     0x40000000  /* Messages below or'd with
+					       * this are the NACK */
+#define IXGBE_VT_MSGTYPE_CTS      0x20000000  /* Indicates that VF is still
+					       *  clear to send requests */
+#define IXGBE_VT_MSGINFO_SHIFT    16
+/* bits 23:16 are used for exra info for certain messages */
+#define IXGBE_VT_MSGINFO_MASK     (0xFF << IXGBE_VT_MSGINFO_SHIFT)
+
+#define IXGBE_VF_RESET            0x01 /* VF requests reset */
+#define IXGBE_VF_SET_MAC_ADDR     0x02 /* VF requests PF to set MAC addr */
+#define IXGBE_VF_SET_MULTICAST    0x03 /* VF requests PF to set MC addr */
+#define IXGBE_VF_SET_VLAN         0x04 /* VF requests PF to set VLAN */
+#define IXGBE_VF_SET_LPE          0x05 /* VF requests PF to set VMOLR.LPE */
+
+/* length of permanent address message returned from PF */
+#define IXGBE_VF_PERMADDR_MSG_LEN 4
+/* word in permanent address message with the current multicast type */
+#define IXGBE_VF_MC_TYPE_WORD     3
+
+#define IXGBE_PF_CONTROL_MSG      0x0100 /* PF control message */
+
+#define IXGBE_VF_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */
+#define IXGBE_VF_MBX_INIT_DELAY   500  /* microseconds between retries */
+
+/* forward declaration of the HW struct */
+struct ixgbe_hw;
+
+s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *);
+
+#endif /* _IXGBE_MBX_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/regs.h linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/regs.h
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/regs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,85 @@
+/*******************************************************************************
+
+  Intel 82599 Virtual Function 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 _IXGBEVF_REGS_H_
+#define _IXGBEVF_REGS_H_
+
+#define IXGBE_VFCTRL           0x00000
+#define IXGBE_VFSTATUS         0x00008
+#define IXGBE_VFLINKS          0x00010
+#define IXGBE_VFRTIMER         0x00048
+#define IXGBE_VFRXMEMWRAP      0x03190
+#define IXGBE_VTEICR           0x00100
+#define IXGBE_VTEICS           0x00104
+#define IXGBE_VTEIMS           0x00108
+#define IXGBE_VTEIMC           0x0010C
+#define IXGBE_VTEIAC           0x00110
+#define IXGBE_VTEIAM           0x00114
+#define IXGBE_VTEITR(x)        (0x00820 + (4 * x))
+#define IXGBE_VTIVAR(x)        (0x00120 + (4 * x))
+#define IXGBE_VTIVAR_MISC      0x00140
+#define IXGBE_VTRSCINT(x)      (0x00180 + (4 * x))
+#define IXGBE_VFRDBAL(x)       (0x01000 + (0x40 * x))
+#define IXGBE_VFRDBAH(x)       (0x01004 + (0x40 * x))
+#define IXGBE_VFRDLEN(x)       (0x01008 + (0x40 * x))
+#define IXGBE_VFRDH(x)         (0x01010 + (0x40 * x))
+#define IXGBE_VFRDT(x)         (0x01018 + (0x40 * x))
+#define IXGBE_VFRXDCTL(x)      (0x01028 + (0x40 * x))
+#define IXGBE_VFSRRCTL(x)      (0x01014 + (0x40 * x))
+#define IXGBE_VFRSCCTL(x)      (0x0102C + (0x40 * x))
+#define IXGBE_VFPSRTYPE        0x00300
+#define IXGBE_VFTDBAL(x)       (0x02000 + (0x40 * x))
+#define IXGBE_VFTDBAH(x)       (0x02004 + (0x40 * x))
+#define IXGBE_VFTDLEN(x)       (0x02008 + (0x40 * x))
+#define IXGBE_VFTDH(x)         (0x02010 + (0x40 * x))
+#define IXGBE_VFTDT(x)         (0x02018 + (0x40 * x))
+#define IXGBE_VFTXDCTL(x)      (0x02028 + (0x40 * x))
+#define IXGBE_VFTDWBAL(x)      (0x02038 + (0x40 * x))
+#define IXGBE_VFTDWBAH(x)      (0x0203C + (0x40 * x))
+#define IXGBE_VFDCA_RXCTRL(x)  (0x0100C + (0x40 * x))
+#define IXGBE_VFDCA_TXCTRL(x)  (0x0200c + (0x40 * x))
+#define IXGBE_VFGPRC           0x0101C
+#define IXGBE_VFGPTC           0x0201C
+#define IXGBE_VFGORC_LSB       0x01020
+#define IXGBE_VFGORC_MSB       0x01024
+#define IXGBE_VFGOTC_LSB       0x02020
+#define IXGBE_VFGOTC_MSB       0x02024
+#define IXGBE_VFMPRC           0x01034
+
+#define IXGBE_WRITE_REG(a, reg, value) writel((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) ( \
+    writel((value), ((a)->hw_addr + (reg) + ((offset) << 2))))
+
+#define IXGBE_READ_REG_ARRAY(a, reg, offset) ( \
+    readl((a)->hw_addr + (reg) + ((offset) << 2)))
+
+#define IXGBE_WRITE_FLUSH(a) (IXGBE_READ_REG(a, IXGBE_VFSTATUS))
+
+#endif /* _IXGBEVF_REGS_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/vf.c linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/vf.c
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/vf.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/vf.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,387 @@
+/*******************************************************************************
+
+  Intel 82599 Virtual Function 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 "vf.h"
+
+/**
+ *  ixgbevf_start_hw_vf - Prepare hardware for Tx/Rx
+ *  @hw: pointer to hardware structure
+ *
+ *  Starts the hardware by filling the bus info structure and media type, clears
+ *  all on chip counters, initializes receive address registers, multicast
+ *  table, VLAN filter table, calls routine to set up link and flow control
+ *  settings, and leaves transmit and receive units disabled and uninitialized
+ **/
+static s32 ixgbevf_start_hw_vf(struct ixgbe_hw *hw)
+{
+	/* Clear adapter stopped flag */
+	hw->adapter_stopped = false;
+
+	return 0;
+}
+
+/**
+ *  ixgbevf_init_hw_vf - virtual function hardware initialization
+ *  @hw: pointer to hardware structure
+ *
+ *  Initialize the hardware by resetting the hardware and then starting
+ *  the hardware
+ **/
+static s32 ixgbevf_init_hw_vf(struct ixgbe_hw *hw)
+{
+	s32 status = hw->mac.ops.start_hw(hw);
+
+	hw->mac.ops.get_mac_addr(hw, hw->mac.addr);
+
+	return status;
+}
+
+/**
+ *  ixgbevf_reset_hw_vf - Performs hardware reset
+ *  @hw: pointer to hardware structure
+ *
+ *  Resets the hardware by reseting the transmit and receive units, masks and
+ *  clears all interrupts.
+ **/
+static s32 ixgbevf_reset_hw_vf(struct ixgbe_hw *hw)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	u32 timeout = IXGBE_VF_INIT_TIMEOUT;
+	s32 ret_val = IXGBE_ERR_INVALID_MAC_ADDR;
+	u32 msgbuf[IXGBE_VF_PERMADDR_MSG_LEN];
+	u8 *addr = (u8 *)(&msgbuf[1]);
+
+	/* Call adapter stop to disable tx/rx and clear interrupts */
+	hw->mac.ops.stop_adapter(hw);
+
+	IXGBE_WRITE_REG(hw, IXGBE_VFCTRL, IXGBE_CTRL_RST);
+	IXGBE_WRITE_FLUSH(hw);
+
+	/* we cannot reset while the RSTI / RSTD bits are asserted */
+	while (!mbx->ops.check_for_rst(hw) && timeout) {
+		timeout--;
+		udelay(5);
+	}
+
+	if (!timeout)
+		return IXGBE_ERR_RESET_FAILED;
+
+	/* mailbox timeout can now become active */
+	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
+
+	msgbuf[0] = IXGBE_VF_RESET;
+	mbx->ops.write_posted(hw, msgbuf, 1);
+
+	msleep(10);
+
+	/* set our "perm_addr" based on info provided by PF */
+	/* also set up the mc_filter_type which is piggy backed
+	 * on the mac address in word 3 */
+	ret_val = mbx->ops.read_posted(hw, msgbuf, IXGBE_VF_PERMADDR_MSG_LEN);
+	if (ret_val)
+		return ret_val;
+
+	if (msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK))
+		return IXGBE_ERR_INVALID_MAC_ADDR;
+
+	memcpy(hw->mac.perm_addr, addr, IXGBE_ETH_LENGTH_OF_ADDRESS);
+	hw->mac.mc_filter_type = msgbuf[IXGBE_VF_MC_TYPE_WORD];
+
+	return 0;
+}
+
+/**
+ *  ixgbevf_stop_hw_vf - Generic stop Tx/Rx units
+ *  @hw: pointer to hardware structure
+ *
+ *  Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts,
+ *  disables transmit and receive units. The adapter_stopped flag is used by
+ *  the shared code and drivers to determine if the adapter is in a stopped
+ *  state and should not touch the hardware.
+ **/
+static s32 ixgbevf_stop_hw_vf(struct ixgbe_hw *hw)
+{
+	u32 number_of_queues;
+	u32 reg_val;
+	u16 i;
+
+	/*
+	 * Set the adapter_stopped flag so other driver functions stop touching
+	 * the hardware
+	 */
+	hw->adapter_stopped = true;
+
+	/* Disable the receive unit by stopped each queue */
+	number_of_queues = hw->mac.max_rx_queues;
+	for (i = 0; i < number_of_queues; i++) {
+		reg_val = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i));
+		if (reg_val & IXGBE_RXDCTL_ENABLE) {
+			reg_val &= ~IXGBE_RXDCTL_ENABLE;
+			IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), reg_val);
+		}
+	}
+
+	IXGBE_WRITE_FLUSH(hw);
+
+	/* Clear interrupt mask to stop from interrupts being generated */
+	IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, IXGBE_VF_IRQ_CLEAR_MASK);
+
+	/* Clear any pending interrupts */
+	IXGBE_READ_REG(hw, IXGBE_VTEICR);
+
+	/* Disable the transmit unit.  Each queue must be disabled. */
+	number_of_queues = hw->mac.max_tx_queues;
+	for (i = 0; i < number_of_queues; i++) {
+		reg_val = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i));
+		if (reg_val & IXGBE_TXDCTL_ENABLE) {
+			reg_val &= ~IXGBE_TXDCTL_ENABLE;
+			IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(i), reg_val);
+		}
+	}
+
+	return 0;
+}
+
+/**
+ *  ixgbevf_mta_vector - Determines bit-vector in multicast table to set
+ *  @hw: pointer to hardware structure
+ *  @mc_addr: the multicast address
+ *
+ *  Extracts the 12 bits, from a multicast address, to determine which
+ *  bit-vector to set in the multicast table. The hardware uses 12 bits, from
+ *  incoming rx multicast addresses, to determine the bit-vector to check in
+ *  the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
+ *  by the MO field of the MCSTCTRL. The MO field is set during initialization
+ *  to mc_filter_type.
+ **/
+static s32 ixgbevf_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
+{
+	u32 vector = 0;
+
+	switch (hw->mac.mc_filter_type) {
+	case 0:   /* use bits [47:36] of the address */
+		vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
+		break;
+	case 1:   /* use bits [46:35] of the address */
+		vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
+		break;
+	case 2:   /* use bits [45:34] of the address */
+		vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
+		break;
+	case 3:   /* use bits [43:32] of the address */
+		vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
+		break;
+	default:  /* Invalid mc_filter_type */
+		break;
+	}
+
+	/* vector can only be 12-bits or boundary will be exceeded */
+	vector &= 0xFFF;
+	return vector;
+}
+
+/**
+ *  ixgbevf_get_mac_addr_vf - Read device MAC address
+ *  @hw: pointer to the HW structure
+ *  @mac_addr: pointer to storage for retrieved MAC address
+ **/
+static s32 ixgbevf_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr)
+{
+	memcpy(mac_addr, hw->mac.perm_addr, IXGBE_ETH_LENGTH_OF_ADDRESS);
+
+	return 0;
+}
+
+/**
+ *  ixgbevf_set_rar_vf - set device MAC address
+ *  @hw: pointer to hardware structure
+ *  @index: Receive address register to write
+ *  @addr: Address to put into receive address register
+ *  @vmdq: Unused in this implementation
+ **/
+static s32 ixgbevf_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr,
+			      u32 vmdq)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	u32 msgbuf[3];
+	u8 *msg_addr = (u8 *)(&msgbuf[1]);
+	s32 ret_val;
+
+	memset(msgbuf, 0, sizeof(msgbuf));
+	msgbuf[0] = IXGBE_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);
+
+	msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
+
+	/* if nacked the address was rejected, use "perm_addr" */
+	if (!ret_val &&
+	    (msgbuf[0] == (IXGBE_VF_SET_MAC_ADDR | IXGBE_VT_MSGTYPE_NACK)))
+		ixgbevf_get_mac_addr_vf(hw, hw->mac.addr);
+
+	return ret_val;
+}
+
+/**
+ *  ixgbevf_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
+ *  @next: caller supplied function to return next address in list
+ *
+ *  Updates the Multicast Table Array.
+ **/
+static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list,
+					u32 mc_addr_count,
+					ixgbe_mc_addr_itr next)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	u32 msgbuf[IXGBE_VFMAILBOX_SIZE];
+	u16 *vector_list = (u16 *)&msgbuf[1];
+	u32 vector;
+	u32 cnt, i;
+	u32 vmdq;
+
+	/* 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] = IXGBE_VF_SET_MULTICAST;
+	msgbuf[0] |= cnt << IXGBE_VT_MSGINFO_SHIFT;
+
+	for (i = 0; i < cnt; i++) {
+		vector = ixgbevf_mta_vector(hw, next(hw, &mc_addr_list, &vmdq));
+		vector_list[i] = vector;
+	}
+
+	mbx->ops.write_posted(hw, msgbuf, IXGBE_VFMAILBOX_SIZE);
+
+	return 0;
+}
+
+/**
+ *  ixgbevf_set_vfta_vf - Set/Unset vlan filter table address
+ *  @hw: pointer to the HW structure
+ *  @vlan: 12 bit VLAN ID
+ *  @vind: unused by VF drivers
+ *  @vlan_on: if true then set bit, else clear bit
+ **/
+static s32 ixgbevf_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind,
+			       bool vlan_on)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	u32 msgbuf[2];
+
+	msgbuf[0] = IXGBE_VF_SET_VLAN;
+	msgbuf[1] = vlan;
+	/* Setting the 8 bit field MSG INFO to TRUE indicates "add" */
+	msgbuf[0] |= vlan_on << IXGBE_VT_MSGINFO_SHIFT;
+
+	return mbx->ops.write_posted(hw, msgbuf, 2);
+}
+
+/**
+ *  ixgbevf_setup_mac_link_vf - Setup MAC link settings
+ *  @hw: pointer to hardware structure
+ *  @speed: Unused in this implementation
+ *  @autoneg: Unused in this implementation
+ *  @autoneg_wait_to_complete: Unused in this implementation
+ *
+ *  Do nothing and return success.  VF drivers are not allowed to change
+ *  global settings.  Maintained for driver compatibility.
+ **/
+static s32 ixgbevf_setup_mac_link_vf(struct ixgbe_hw *hw,
+				     ixgbe_link_speed speed, bool autoneg,
+				     bool autoneg_wait_to_complete)
+{
+	return 0;
+}
+
+/**
+ *  ixgbevf_check_mac_link_vf - Get link/speed status
+ *  @hw: pointer to hardware structure
+ *  @speed: pointer to link speed
+ *  @link_up: true is link is up, false otherwise
+ *  @autoneg_wait_to_complete: true when waiting for completion is needed
+ *
+ *  Reads the links register to determine if link is up and the current speed
+ **/
+static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw,
+				     ixgbe_link_speed *speed,
+				     bool *link_up,
+				     bool autoneg_wait_to_complete)
+{
+	u32 links_reg;
+
+	if (!(hw->mbx.ops.check_for_rst(hw))) {
+		*link_up = false;
+		*speed = 0;
+		return -1;
+	}
+
+	links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
+
+	if (links_reg & IXGBE_LINKS_UP)
+		*link_up = true;
+	else
+		*link_up = false;
+
+	if (links_reg & IXGBE_LINKS_SPEED)
+		*speed = IXGBE_LINK_SPEED_10GB_FULL;
+	else
+		*speed = IXGBE_LINK_SPEED_1GB_FULL;
+
+	return 0;
+}
+
+struct ixgbe_mac_operations ixgbevf_mac_ops = {
+	.init_hw             = ixgbevf_init_hw_vf,
+	.reset_hw            = ixgbevf_reset_hw_vf,
+	.start_hw            = ixgbevf_start_hw_vf,
+	.get_mac_addr        = ixgbevf_get_mac_addr_vf,
+	.stop_adapter        = ixgbevf_stop_hw_vf,
+	.setup_link          = ixgbevf_setup_mac_link_vf,
+	.check_link          = ixgbevf_check_mac_link_vf,
+	.set_rar             = ixgbevf_set_rar_vf,
+	.update_mc_addr_list = ixgbevf_update_mc_addr_list_vf,
+	.set_vfta            = ixgbevf_set_vfta_vf,
+};
+
+struct ixgbevf_info ixgbevf_vf_info = {
+	.mac = ixgbe_mac_82599_vf,
+	.mac_ops = &ixgbevf_mac_ops,
+};
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/vf.h linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/vf.h
--- linux-libre-2.6.33-gnu1/drivers/net/ixgbevf/vf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixgbevf/vf.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,174 @@
+/*******************************************************************************
+
+  Intel 82599 Virtual Function 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 __IXGBE_VF_H__
+#define __IXGBE_VF_H__
+
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+
+#include "defines.h"
+#include "regs.h"
+#include "mbx.h"
+
+struct ixgbe_hw;
+
+/* iterator type for walking multicast address lists */
+typedef u8* (*ixgbe_mc_addr_itr) (struct ixgbe_hw *hw, u8 **mc_addr_ptr,
+				  u32 *vmdq);
+struct ixgbe_mac_operations {
+	s32 (*init_hw)(struct ixgbe_hw *);
+	s32 (*reset_hw)(struct ixgbe_hw *);
+	s32 (*start_hw)(struct ixgbe_hw *);
+	s32 (*clear_hw_cntrs)(struct ixgbe_hw *);
+	enum ixgbe_media_type (*get_media_type)(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 *);
+
+	/* Link */
+	s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool);
+	s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool);
+	s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *,
+				     bool *);
+
+	/* RAR, Multicast, VLAN */
+	s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32);
+	s32 (*init_rx_addrs)(struct ixgbe_hw *);
+	s32 (*update_mc_addr_list)(struct ixgbe_hw *, u8 *, u32,
+				   ixgbe_mc_addr_itr);
+	s32 (*enable_mc)(struct ixgbe_hw *);
+	s32 (*disable_mc)(struct ixgbe_hw *);
+	s32 (*clear_vfta)(struct ixgbe_hw *);
+	s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool);
+};
+
+enum ixgbe_mac_type {
+	ixgbe_mac_unknown = 0,
+	ixgbe_mac_82599_vf,
+	ixgbe_num_macs
+};
+
+struct ixgbe_mac_info {
+	struct ixgbe_mac_operations ops;
+	u8 addr[6];
+	u8 perm_addr[6];
+
+	enum ixgbe_mac_type type;
+
+	s32  mc_filter_type;
+
+	bool get_link_status;
+	u32  max_tx_queues;
+	u32  max_rx_queues;
+	u32  max_msix_vectors;
+};
+
+struct ixgbe_mbx_operations {
+	s32 (*init_params)(struct ixgbe_hw *hw);
+	s32 (*read)(struct ixgbe_hw *, u32 *, u16);
+	s32 (*write)(struct ixgbe_hw *, u32 *, u16);
+	s32 (*read_posted)(struct ixgbe_hw *, u32 *, u16);
+	s32 (*write_posted)(struct ixgbe_hw *, u32 *, u16);
+	s32 (*check_for_msg)(struct ixgbe_hw *);
+	s32 (*check_for_ack)(struct ixgbe_hw *);
+	s32 (*check_for_rst)(struct ixgbe_hw *);
+};
+
+struct ixgbe_mbx_stats {
+	u32 msgs_tx;
+	u32 msgs_rx;
+
+	u32 acks;
+	u32 reqs;
+	u32 rsts;
+};
+
+struct ixgbe_mbx_info {
+	struct ixgbe_mbx_operations ops;
+	struct ixgbe_mbx_stats stats;
+	u32 timeout;
+	u32 udelay;
+	u32 v2p_mailbox;
+	u16 size;
+};
+
+struct ixgbe_hw {
+	void *back;
+
+	u8 __iomem *hw_addr;
+	u8 *flash_address;
+	unsigned long io_base;
+
+	struct ixgbe_mac_info mac;
+	struct ixgbe_mbx_info mbx;
+
+	u16 device_id;
+	u16 subsystem_vendor_id;
+	u16 subsystem_device_id;
+	u16 vendor_id;
+
+	u8  revision_id;
+	bool adapter_stopped;
+};
+
+struct ixgbevf_hw_stats {
+	u64 base_vfgprc;
+	u64 base_vfgptc;
+	u64 base_vfgorc;
+	u64 base_vfgotc;
+	u64 base_vfmprc;
+
+	u64 last_vfgprc;
+	u64 last_vfgptc;
+	u64 last_vfgorc;
+	u64 last_vfgotc;
+	u64 last_vfmprc;
+
+	u64 vfgprc;
+	u64 vfgptc;
+	u64 vfgorc;
+	u64 vfgotc;
+	u64 vfmprc;
+
+	u64 saved_reset_vfgprc;
+	u64 saved_reset_vfgptc;
+	u64 saved_reset_vfgorc;
+	u64 saved_reset_vfgotc;
+	u64 saved_reset_vfmprc;
+};
+
+struct ixgbevf_info {
+	enum ixgbe_mac_type		mac;
+	struct ixgbe_mac_operations	*mac_ops;
+};
+
+#endif /* __IXGBE_VF_H__ */
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ixp2000/ixpdev.c linux-libre-2.6.34-gnu1/drivers/net/ixp2000/ixpdev.c
--- linux-libre-2.6.33-gnu1/drivers/net/ixp2000/ixpdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ixp2000/ixpdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/etherdevice.h>
 #include <linux/init.h>
 #include <linux/moduleparam.h>
+#include <linux/gfp.h>
 #include <asm/hardware/uengine.h>
 #include <asm/io.h>
 #include "ixp2400_rx.ucode"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/jazzsonic.c linux-libre-2.6.34-gnu1/drivers/net/jazzsonic.c
--- linux-libre-2.6.33-gnu1/drivers/net/jazzsonic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/jazzsonic.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,11 +22,11 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
+#include <linux/gfp.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
@@ -35,6 +35,7 @@
 #include <linux/skbuff.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <asm/bootinfo.h>
 #include <asm/system.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/jme.c linux-libre-2.6.34-gnu1/drivers/net/jme.c
--- linux-libre-2.6.33-gnu1/drivers/net/jme.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/jme.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/if_vlan.h>
+#include <linux/slab.h>
 #include <net/ip6_checksum.h>
 #include "jme.h"
 
@@ -288,7 +289,7 @@ jme_set_rx_pcc(struct jme_adapter *jme,
 	wmb();
 
 	if (!(test_bit(JME_FLAG_POLL, &jme->flags)))
-		msg_rx_status(jme, "Switched to PCC_P%d\n", p);
+		netif_info(jme, rx_status, jme->dev, "Switched to PCC_P%d\n", p);
 }
 
 static void
@@ -483,13 +484,13 @@ jme_check_link(struct net_device *netdev
 		strcat(linkmsg, (phylink & PHY_LINK_MDI_STAT) ?
 					"MDI-X" :
 					"MDI");
-		msg_link(jme, "Link is up at %s.\n", linkmsg);
+		netif_info(jme, link, jme->dev, "Link is up at %s.\n", linkmsg);
 		netif_carrier_on(netdev);
 	} else {
 		if (testonly)
 			goto out;
 
-		msg_link(jme, "Link is down.\n");
+		netif_info(jme, link, jme->dev, "Link is down.\n");
 		jme->phylink = 0;
 		netif_carrier_off(netdev);
 	}
@@ -883,20 +884,20 @@ jme_rxsum_ok(struct jme_adapter *jme, u1
 	if (unlikely((flags & (RXWBFLAG_MF | RXWBFLAG_TCPON | RXWBFLAG_TCPCS))
 			== RXWBFLAG_TCPON)) {
 		if (flags & RXWBFLAG_IPV4)
-			msg_rx_err(jme, "TCP Checksum error\n");
+			netif_err(jme, rx_err, jme->dev, "TCP Checksum error\n");
 		return false;
 	}
 
 	if (unlikely((flags & (RXWBFLAG_MF | RXWBFLAG_UDPON | RXWBFLAG_UDPCS))
 			== RXWBFLAG_UDPON)) {
 		if (flags & RXWBFLAG_IPV4)
-			msg_rx_err(jme, "UDP Checksum error.\n");
+			netif_err(jme, rx_err, jme->dev, "UDP Checksum error.\n");
 		return false;
 	}
 
 	if (unlikely((flags & (RXWBFLAG_IPV4 | RXWBFLAG_IPCS))
 			== RXWBFLAG_IPV4)) {
-		msg_rx_err(jme, "IPv4 Checksum error.\n");
+		netif_err(jme, rx_err, jme->dev, "IPv4 Checksum error.\n");
 		return false;
 	}
 
@@ -946,6 +947,8 @@ jme_alloc_and_feed_skb(struct jme_adapte
 				jme->jme_vlan_rx(skb, jme->vlgrp,
 					le16_to_cpu(rxdesc->descwb.vlan));
 				NET_STAT(jme).rx_bytes += 4;
+			} else {
+				dev_kfree_skb(skb);
 			}
 		} else {
 			jme->jme_rx(skb);
@@ -1186,9 +1189,9 @@ jme_link_change_tasklet(unsigned long ar
 
 	while (!atomic_dec_and_test(&jme->link_changing)) {
 		atomic_inc(&jme->link_changing);
-		msg_intr(jme, "Get link change lock failed.\n");
+		netif_info(jme, intr, jme->dev, "Get link change lock failed.\n");
 		while (atomic_read(&jme->link_changing) != 1)
-			msg_intr(jme, "Waiting link change lock.\n");
+			netif_info(jme, intr, jme->dev, "Waiting link change lock.\n");
 	}
 
 	if (jme_check_link(netdev, 1) && jme->old_mtu == netdev->mtu)
@@ -1305,7 +1308,7 @@ jme_rx_empty_tasklet(unsigned long arg)
 	if (unlikely(!netif_carrier_ok(jme->dev)))
 		return;
 
-	msg_rx_status(jme, "RX Queue Full!\n");
+	netif_info(jme, rx_status, jme->dev, "RX Queue Full!\n");
 
 	jme_rx_clean_tasklet(arg);
 
@@ -1325,7 +1328,7 @@ jme_wake_queue_if_stopped(struct jme_ada
 	smp_wmb();
 	if (unlikely(netif_queue_stopped(jme->dev) &&
 	atomic_read(&txring->nr_free) >= (jme->tx_wake_threshold))) {
-		msg_tx_done(jme, "TX Queue Waked.\n");
+		netif_info(jme, tx_done, jme->dev, "TX Queue Waked.\n");
 		netif_wake_queue(jme->dev);
 	}
 
@@ -1835,7 +1838,7 @@ jme_tx_csum(struct jme_adapter *jme, str
 			*flags |= TXFLAG_UDPCS;
 			break;
 		default:
-			msg_tx_err(jme, "Error upper layer protocol.\n");
+			netif_err(jme, tx_err, jme->dev, "Error upper layer protocol.\n");
 			break;
 		}
 	}
@@ -1910,12 +1913,12 @@ jme_stop_queue_if_full(struct jme_adapte
 	smp_wmb();
 	if (unlikely(atomic_read(&txring->nr_free) < (MAX_SKB_FRAGS+2))) {
 		netif_stop_queue(jme->dev);
-		msg_tx_queued(jme, "TX Queue Paused.\n");
+		netif_info(jme, tx_queued, jme->dev, "TX Queue Paused.\n");
 		smp_wmb();
 		if (atomic_read(&txring->nr_free)
 			>= (jme->tx_wake_threshold)) {
 			netif_wake_queue(jme->dev);
-			msg_tx_queued(jme, "TX Queue Fast Waked.\n");
+			netif_info(jme, tx_queued, jme->dev, "TX Queue Fast Waked.\n");
 		}
 	}
 
@@ -1923,7 +1926,7 @@ jme_stop_queue_if_full(struct jme_adapte
 			(jiffies - txbi->start_xmit) >= TX_TIMEOUT &&
 			txbi->skb)) {
 		netif_stop_queue(jme->dev);
-		msg_tx_queued(jme, "TX Queue Stopped %d@%lu.\n", idx, jiffies);
+		netif_info(jme, tx_queued, jme->dev, "TX Queue Stopped %d@%lu.\n", idx, jiffies);
 	}
 }
 
@@ -1946,7 +1949,7 @@ jme_start_xmit(struct sk_buff *skb, stru
 
 	if (unlikely(idx < 0)) {
 		netif_stop_queue(netdev);
-		msg_tx_err(jme, "BUG! Tx ring full when queue awake!\n");
+		netif_err(jme, tx_err, jme->dev, "BUG! Tx ring full when queue awake!\n");
 
 		return NETDEV_TX_BUSY;
 	}
@@ -1997,7 +2000,6 @@ jme_set_multi(struct net_device *netdev)
 {
 	struct jme_adapter *jme = netdev_priv(netdev);
 	u32 mc_hash[2] = {};
-	int i;
 
 	spin_lock_bh(&jme->rxmcs_lock);
 
@@ -2012,10 +2014,7 @@ jme_set_multi(struct net_device *netdev)
 		int bit_nr;
 
 		jme->reg_rxmcs |= RXMCS_MULFRAME | RXMCS_MULFILTERED;
-		for (i = 0, mclist = netdev->mc_list;
-			mclist && i < netdev->mc_count;
-			++i, mclist = mclist->next) {
-
+		netdev_for_each_mc_addr(mclist, netdev) {
 			bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x3F;
 			mc_hash[bit_nr >> 5] |= 1 << (bit_nr & 0x1F);
 		}
@@ -2085,12 +2084,45 @@ jme_tx_timeout(struct net_device *netdev
 	jme_reset_link(jme);
 }
 
+static inline void jme_pause_rx(struct jme_adapter *jme)
+{
+	atomic_dec(&jme->link_changing);
+
+	jme_set_rx_pcc(jme, PCC_OFF);
+	if (test_bit(JME_FLAG_POLL, &jme->flags)) {
+		JME_NAPI_DISABLE(jme);
+	} else {
+		tasklet_disable(&jme->rxclean_task);
+		tasklet_disable(&jme->rxempty_task);
+	}
+}
+
+static inline void jme_resume_rx(struct jme_adapter *jme)
+{
+	struct dynpcc_info *dpi = &(jme->dpi);
+
+	if (test_bit(JME_FLAG_POLL, &jme->flags)) {
+		JME_NAPI_ENABLE(jme);
+	} else {
+		tasklet_hi_enable(&jme->rxclean_task);
+		tasklet_hi_enable(&jme->rxempty_task);
+	}
+	dpi->cur		= PCC_P1;
+	dpi->attempt		= PCC_P1;
+	dpi->cnt		= 0;
+	jme_set_rx_pcc(jme, PCC_P1);
+
+	atomic_inc(&jme->link_changing);
+}
+
 static void
 jme_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
 {
 	struct jme_adapter *jme = netdev_priv(netdev);
 
+	jme_pause_rx(jme);
 	jme->vlgrp = grp;
+	jme_resume_rx(jme);
 }
 
 static void
@@ -2473,7 +2505,7 @@ jme_smb_read(struct jme_adapter *jme, un
 		val = jread32(jme, JME_SMBCSR);
 	}
 	if (!to) {
-		msg_hw(jme, "SMB Bus Busy.\n");
+		netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n");
 		return 0xFF;
 	}
 
@@ -2489,7 +2521,7 @@ jme_smb_read(struct jme_adapter *jme, un
 		val = jread32(jme, JME_SMBINTF);
 	}
 	if (!to) {
-		msg_hw(jme, "SMB Bus Busy.\n");
+		netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n");
 		return 0xFF;
 	}
 
@@ -2509,7 +2541,7 @@ jme_smb_write(struct jme_adapter *jme, u
 		val = jread32(jme, JME_SMBCSR);
 	}
 	if (!to) {
-		msg_hw(jme, "SMB Bus Busy.\n");
+		netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n");
 		return;
 	}
 
@@ -2526,7 +2558,7 @@ jme_smb_write(struct jme_adapter *jme, u
 		val = jread32(jme, JME_SMBINTF);
 	}
 	if (!to) {
-		msg_hw(jme, "SMB Bus Busy.\n");
+		netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n");
 		return;
 	}
 
@@ -2876,14 +2908,14 @@ jme_init_one(struct pci_dev *pdev,
 		goto err_out_unmap;
 	}
 
-	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);
+	netif_info(jme, probe, jme->dev, "%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);
 
 	return 0;
 
@@ -2994,7 +3026,7 @@ jme_resume(struct pci_dev *pdev)
 }
 #endif
 
-static struct pci_device_id jme_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(jme_pci_tbl) = {
 	{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMC250) },
 	{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMC260) },
 	{ }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/jme.h linux-libre-2.6.34-gnu1/drivers/net/jme.h
--- linux-libre-2.6.33-gnu1/drivers/net/jme.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/jme.h	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,7 @@
 #define __JME_H_INCLUDED__
 
 #define DRV_NAME	"jme"
-#define DRV_VERSION	"1.0.5"
+#define DRV_VERSION	"1.0.6"
 #define PFX		DRV_NAME ": "
 
 #define PCI_DEVICE_ID_JMICRON_JMC250	0x0250
@@ -45,43 +45,16 @@
 	printk(KERN_ERR PFX fmt, ## args)
 
 #ifdef TX_DEBUG
-#define tx_dbg(priv, fmt, args...) \
-	printk(KERN_DEBUG "%s: " fmt, (priv)->dev->name, ## args)
+#define tx_dbg(priv, fmt, args...)					\
+	printk(KERN_DEBUG "%s: " fmt, (priv)->dev->name, ##args)
 #else
-#define tx_dbg(priv, fmt, args...)
+#define tx_dbg(priv, fmt, args...)					\
+do {									\
+	if (0)								\
+		printk(KERN_DEBUG "%s: " fmt, (priv)->dev->name, ##args); \
+} while (0)
 #endif
 
-#define jme_msg(msglvl, type, priv, fmt, args...) \
-	if (netif_msg_##type(priv)) \
-		printk(msglvl "%s: " fmt, (priv)->dev->name, ## args)
-
-#define msg_probe(priv, fmt, args...) \
-	jme_msg(KERN_INFO, probe, priv, fmt, ## args)
-
-#define msg_link(priv, fmt, args...) \
-	jme_msg(KERN_INFO, link, priv, fmt, ## args)
-
-#define msg_intr(priv, fmt, args...) \
-	jme_msg(KERN_INFO, intr, priv, fmt, ## args)
-
-#define msg_rx_err(priv, fmt, args...) \
-	jme_msg(KERN_ERR, rx_err, priv, fmt, ## args)
-
-#define msg_rx_status(priv, fmt, args...) \
-	jme_msg(KERN_INFO, rx_status, priv, fmt, ## args)
-
-#define msg_tx_err(priv, fmt, args...) \
-	jme_msg(KERN_ERR, tx_err, priv, fmt, ## args)
-
-#define msg_tx_done(priv, fmt, args...) \
-	jme_msg(KERN_INFO, tx_done, priv, fmt, ## args)
-
-#define msg_tx_queued(priv, fmt, args...) \
-	jme_msg(KERN_INFO, tx_queued, priv, fmt, ## args)
-
-#define msg_hw(priv, fmt, args...) \
-	jme_msg(KERN_ERR, hw, priv, fmt, ## args)
-
 /*
  * Extra PCI Configuration space interface
  */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/Kconfig linux-libre-2.6.34-gnu1/drivers/net/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/net/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -90,6 +90,18 @@ config MACVLAN
 	  To compile this driver as a module, choose M here: the module
 	  will be called macvlan.
 
+config MACVTAP
+	tristate "MAC-VLAN based tap driver (EXPERIMENTAL)"
+	depends on MACVLAN
+	help
+	  This adds a specialized tap character device driver that is based
+	  on the MAC-VLAN network interface, called macvtap. A macvtap device
+	  can be added in the same way as a macvlan device, using 'type
+	  macvlan', and then be accessed through the tap user space interface.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called macvtap.
+
 config EQUALIZER
 	tristate "EQL (serial line load balancing) support"
 	---help---
@@ -868,8 +880,8 @@ config BFIN_RX_DESC_NUM
 	  Set the number of buffer packets used in driver.
 
 config BFIN_MAC_RMII
-	bool "RMII PHY Interface (EXPERIMENTAL)"
-	depends on BFIN_MAC && EXPERIMENTAL
+	bool "RMII PHY Interface"
+	depends on BFIN_MAC
 	default y if BFIN527_EZKIT
 	default n if BFIN537_STAMP
 	help
@@ -895,7 +907,7 @@ config SMC91X
 	select CRC32
 	select MII
 	depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \
-		MIPS || BLACKFIN || MN10300
+		MIPS || BLACKFIN || MN10300 || COLDFIRE
 	help
 	  This is a driver for SMC's 91x series of Ethernet chipsets,
 	  including the SMC91C94 and the SMC91C111. Say Y if you want it
@@ -920,7 +932,7 @@ config NET_NETX
 
 config TI_DAVINCI_EMAC
 	tristate "TI DaVinci EMAC Support"
-	depends on ARM && ARCH_DAVINCI
+	depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
 	select PHYLIB
 	help
 	  This driver supports TI's DaVinci Ethernet .
@@ -983,6 +995,14 @@ config ETHOC
 	help
 	  Say Y here if you want to use the OpenCores 10/100 Mbps Ethernet MAC.
 
+config GRETH
+	tristate "Aeroflex Gaisler GRETH Ethernet MAC support"
+	depends on SPARC
+	select PHYLIB
+	select CRC32
+	help
+	  Say Y here if you want to use the Aeroflex Gaisler GRETH Ethernet MAC.
+
 config SMC911X
 	tristate "SMSC LAN911[5678] support"
 	select CRC32
@@ -1368,6 +1388,17 @@ config AC3200
 	  To compile this driver as a module, choose M here. The module
 	  will be called ac3200.
 
+config KSZ884X_PCI
+	tristate "Micrel KSZ8841/2 PCI"
+	depends on NET_PCI && PCI
+	select MII
+	select CRC32
+	help
+	  This PCI driver is for Micrel KSZ8841/KSZ8842 PCI Ethernet chip.
+
+	  To compile this driver as a module, choose M here. The module
+	  will be called ksz884x.
+
 config APRICOT
 	tristate "Apricot Xen-II on board Ethernet"
 	depends on NET_PCI && ISA
@@ -1883,7 +1914,8 @@ config 68360_ENET
 
 config FEC
 	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
-	depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 || ARCH_MX35 || ARCH_MX25
+	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
+		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
 	help
 	  Say Y here if you want to use the built-in 10/100 Fast ethernet
 	  controller on some Motorola ColdFire and Freescale i.MX processors.
@@ -1939,6 +1971,7 @@ config ATL2
 config XILINX_EMACLITE
 	tristate "Xilinx 10/100 Ethernet Lite support"
 	depends on PPC32 || MICROBLAZE
+	select PHYLIB
 	help
 	  This driver supports the 10/100 Ethernet Lite from Xilinx.
 
@@ -2356,20 +2389,6 @@ config GELIC_WIRELESS
 	  the driver automatically distinguishes the models, you can
 	  safely enable this option even if you have a wireless-less model.
 
-config GELIC_WIRELESS_OLD_PSK_INTERFACE
-       bool "PS3 Wireless private PSK interface (OBSOLETE)"
-       depends on GELIC_WIRELESS
-       select WEXT_PRIV
-       help
-          This option retains the obsolete private interface to pass
-          the PSK from user space programs to the driver.  The PSK
-          stands for 'Pre Shared Key' and is used for WPA[2]-PSK
-          (WPA-Personal) environment.
-          If WPA[2]-PSK is used and you need to use old programs that
-          support only this old interface, say Y.  Otherwise N.
-
-          If unsure, say N.
-
 config FSL_PQ_MDIO
 	tristate "Freescale PQ MDIO"
 	depends on FSL_SOC
@@ -2563,6 +2582,31 @@ config CHELSIO_T3
 	  To compile this driver as a module, choose M here: the module
 	  will be called cxgb3.
 
+config CHELSIO_T4_DEPENDS
+	tristate
+	depends on PCI && INET
+	default y
+
+config CHELSIO_T4
+	tristate "Chelsio Communications T4 Ethernet support"
+	depends on CHELSIO_T4_DEPENDS
+	select FW_LOADER
+	select MDIO
+	help
+	  This driver supports Chelsio T4-based gigabit and 10Gb Ethernet
+	  adapters.
+
+	  For general information about Chelsio and our products, visit
+	  our website at <http://www.chelsio.com>.
+
+	  For customer support, please visit our customer support page at
+	  <http://www.chelsio.com/support.htm>.
+
+	  Please send feedback to <linux-bugs@chelsio.com>.
+
+	  To compile this driver as a module choose M here; the module
+	  will be called cxgb4.
+
 config EHEA
 	tristate "eHEA Ethernet support"
 	depends on IBMEBUS && INET && SPARSEMEM
@@ -2618,6 +2662,28 @@ config IXGBE_DCB
 
 	  If unsure, say N.
 
+config IXGBEVF
+       tristate "Intel(R) 82599 Virtual Function Ethernet support"
+       depends on PCI_MSI
+       ---help---
+         This driver supports Intel(R) 82599 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/sb/CS-008441.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/ixgbevf.txt>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called ixgbevf.  MSI-X interrupt support is required
+         for this driver to work correctly.
+
 config IXGB
 	tristate "Intel(R) PRO/10GbE support"
 	depends on PCI
@@ -2756,6 +2822,13 @@ config BNX2X
 	  To compile this driver as a module, choose M here: the module
 	  will be called bnx2x.  This is recommended.
 
+config QLCNIC
+	tristate "QLOGIC QLCNIC 1/10Gb Converged Ethernet NIC Support"
+	depends on PCI
+	help
+	  This driver supports QLogic QLE8240 and QLE8242 Converged Ethernet
+	  devices.
+
 config QLGE
 	tristate "QLogic QLGE 10Gb Ethernet Driver Support"
 	depends on PCI
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/korina.c linux-libre-2.6.34-gnu1/drivers/net/korina.c
--- linux-libre-2.6.33-gnu1/drivers/net/korina.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/korina.c	2010-05-16 17:17:36.000000000 -0400
@@ -482,7 +482,7 @@ static void korina_multicast_list(struct
 {
 	struct korina_private *lp = netdev_priv(dev);
 	unsigned long flags;
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	u32 recognise = ETH_ARC_AB;	/* always accept broadcasts */
 	int i;
 
@@ -490,23 +490,21 @@ static void korina_multicast_list(struct
 	if (dev->flags & IFF_PROMISC)
 		recognise |= ETH_ARC_PRO;
 
-	else if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 4))
+	else if ((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 4))
 		/* All multicast and broadcast */
 		recognise |= ETH_ARC_AM;
 
 	/* Build the hash table */
-	if (dev->mc_count > 4) {
+	if (netdev_mc_count(dev) > 4) {
 		u16 hash_table[4];
 		u32 crc;
 
 		for (i = 0; i < 4; i++)
 			hash_table[i] = 0;
 
-		for (i = 0; i < dev->mc_count; i++) {
+		netdev_for_each_mc_addr(dmi, dev) {
 			char *addrs = dmi->dmi_addr;
 
-			dmi = dmi->next;
-
 			if (!(*addrs & 1))
 				continue;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ks8851.c linux-libre-2.6.34-gnu1/drivers/net/ks8851.c
--- linux-libre-2.6.33-gnu1/drivers/net/ks8851.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ks8851.c	2010-05-16 17:17:36.000000000 -0400
@@ -407,7 +407,7 @@ static irqreturn_t ks8851_irq(int irq, v
  * @buff: The buffer address
  * @len: The length of the data to read
  *
- * Issue an RXQ FIFO read command and read the @len ammount of data from
+ * Issue an RXQ FIFO read command and read the @len amount of data from
  * the FIFO into the buffer specified by @buff.
  */
 static void ks8851_rdfifo(struct ks8851_net *ks, u8 *buff, unsigned len)
@@ -722,12 +722,14 @@ static void ks8851_tx_work(struct work_s
 		txb = skb_dequeue(&ks->txq);
 		last = skb_queue_empty(&ks->txq);
 
-		ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA);
-		ks8851_wrpkt(ks, txb, last);
-		ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr);
-		ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE);
+		if (txb != NULL) {
+			ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA);
+			ks8851_wrpkt(ks, txb, last);
+			ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr);
+			ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE);
 
-		ks8851_done_tx(ks, txb);
+			ks8851_done_tx(ks, txb);
+		}
 	}
 
 	mutex_unlock(&ks->lock);
@@ -965,19 +967,17 @@ static void ks8851_set_rx_mode(struct ne
 
 		rxctrl.rxcr1 = (RXCR1_RXME | RXCR1_RXAE |
 				RXCR1_RXPAFMA | RXCR1_RXMAFMA);
-	} else if (dev->flags & IFF_MULTICAST && dev->mc_count > 0) {
-		struct dev_mc_list *mcptr = dev->mc_list;
+	} else if (dev->flags & IFF_MULTICAST && !netdev_mc_empty(dev)) {
+		struct dev_mc_list *mcptr;
 		u32 crc;
-		int i;
 
 		/* accept some multicast */
 
-		for (i = dev->mc_count; i > 0; i--) {
+		netdev_for_each_mc_addr(mcptr, dev) {
 			crc = ether_crc(ETH_ALEN, mcptr->dmi_addr);
 			crc >>= (32 - 6);  /* get top six bits */
 
 			rxctrl.mchash[crc >> 4] |= (1 << (crc & 0xf));
-			mcptr = mcptr->next;
 		}
 
 		rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXPAFMA;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ks8851_mll.c linux-libre-2.6.34-gnu1/drivers/net/ks8851_mll.c
--- linux-libre-2.6.33-gnu1/drivers/net/ks8851_mll.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ks8851_mll.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/mii.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #define	DRV_NAME	"ks8851_mll"
 
@@ -1193,10 +1194,11 @@ static void ks_set_rx_mode(struct net_de
 	else
 		ks_set_promis(ks, false);
 
-	if ((netdev->flags & IFF_MULTICAST) && netdev->mc_count) {
-		if (netdev->mc_count <= MAX_MCAST_LST) {
+	if ((netdev->flags & IFF_MULTICAST) && netdev_mc_count(netdev)) {
+		if (netdev_mc_count(netdev) <= MAX_MCAST_LST) {
 			int i = 0;
-			for (ptr = netdev->mc_list; ptr; ptr = ptr->next) {
+
+			netdev_for_each_mc_addr(ptr, netdev) {
 				if (!(*ptr->dmi_addr & 1))
 					continue;
 				if (i >= MAX_MCAST_LST)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ksz884x.c linux-libre-2.6.34-gnu1/drivers/net/ksz884x.c
--- linux-libre-2.6.33-gnu1/drivers/net/ksz884x.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ksz884x.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,7338 @@
+/**
+ * drivers/net/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver
+ *
+ * Copyright (c) 2009-2010 Micrel, Inc.
+ * 	Tristram Ha <Tristram.Ha@micrel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/mii.h>
+#include <linux/platform_device.h>
+#include <linux/ethtool.h>
+#include <linux/etherdevice.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/if_vlan.h>
+#include <linux/crc32.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+
+/* DMA Registers */
+
+#define KS_DMA_TX_CTRL			0x0000
+#define DMA_TX_ENABLE			0x00000001
+#define DMA_TX_CRC_ENABLE		0x00000002
+#define DMA_TX_PAD_ENABLE		0x00000004
+#define DMA_TX_LOOPBACK			0x00000100
+#define DMA_TX_FLOW_ENABLE		0x00000200
+#define DMA_TX_CSUM_IP			0x00010000
+#define DMA_TX_CSUM_TCP			0x00020000
+#define DMA_TX_CSUM_UDP			0x00040000
+#define DMA_TX_BURST_SIZE		0x3F000000
+
+#define KS_DMA_RX_CTRL			0x0004
+#define DMA_RX_ENABLE			0x00000001
+#define KS884X_DMA_RX_MULTICAST		0x00000002
+#define DMA_RX_PROMISCUOUS		0x00000004
+#define DMA_RX_ERROR			0x00000008
+#define DMA_RX_UNICAST			0x00000010
+#define DMA_RX_ALL_MULTICAST		0x00000020
+#define DMA_RX_BROADCAST		0x00000040
+#define DMA_RX_FLOW_ENABLE		0x00000200
+#define DMA_RX_CSUM_IP			0x00010000
+#define DMA_RX_CSUM_TCP			0x00020000
+#define DMA_RX_CSUM_UDP			0x00040000
+#define DMA_RX_BURST_SIZE		0x3F000000
+
+#define DMA_BURST_SHIFT			24
+#define DMA_BURST_DEFAULT		8
+
+#define KS_DMA_TX_START			0x0008
+#define KS_DMA_RX_START			0x000C
+#define DMA_START			0x00000001
+
+#define KS_DMA_TX_ADDR			0x0010
+#define KS_DMA_RX_ADDR			0x0014
+
+#define DMA_ADDR_LIST_MASK		0xFFFFFFFC
+#define DMA_ADDR_LIST_SHIFT		2
+
+/* MTR0 */
+#define KS884X_MULTICAST_0_OFFSET	0x0020
+#define KS884X_MULTICAST_1_OFFSET	0x0021
+#define KS884X_MULTICAST_2_OFFSET	0x0022
+#define KS884x_MULTICAST_3_OFFSET	0x0023
+/* MTR1 */
+#define KS884X_MULTICAST_4_OFFSET	0x0024
+#define KS884X_MULTICAST_5_OFFSET	0x0025
+#define KS884X_MULTICAST_6_OFFSET	0x0026
+#define KS884X_MULTICAST_7_OFFSET	0x0027
+
+/* Interrupt Registers */
+
+/* INTEN */
+#define KS884X_INTERRUPTS_ENABLE	0x0028
+/* INTST */
+#define KS884X_INTERRUPTS_STATUS	0x002C
+
+#define KS884X_INT_RX_STOPPED		0x02000000
+#define KS884X_INT_TX_STOPPED		0x04000000
+#define KS884X_INT_RX_OVERRUN		0x08000000
+#define KS884X_INT_TX_EMPTY		0x10000000
+#define KS884X_INT_RX			0x20000000
+#define KS884X_INT_TX			0x40000000
+#define KS884X_INT_PHY			0x80000000
+
+#define KS884X_INT_RX_MASK		\
+	(KS884X_INT_RX | KS884X_INT_RX_OVERRUN)
+#define KS884X_INT_TX_MASK		\
+	(KS884X_INT_TX | KS884X_INT_TX_EMPTY)
+#define KS884X_INT_MASK	(KS884X_INT_RX | KS884X_INT_TX | KS884X_INT_PHY)
+
+/* MAC Additional Station Address */
+
+/* MAAL0 */
+#define KS_ADD_ADDR_0_LO		0x0080
+/* MAAH0 */
+#define KS_ADD_ADDR_0_HI		0x0084
+/* MAAL1 */
+#define KS_ADD_ADDR_1_LO		0x0088
+/* MAAH1 */
+#define KS_ADD_ADDR_1_HI		0x008C
+/* MAAL2 */
+#define KS_ADD_ADDR_2_LO		0x0090
+/* MAAH2 */
+#define KS_ADD_ADDR_2_HI		0x0094
+/* MAAL3 */
+#define KS_ADD_ADDR_3_LO		0x0098
+/* MAAH3 */
+#define KS_ADD_ADDR_3_HI		0x009C
+/* MAAL4 */
+#define KS_ADD_ADDR_4_LO		0x00A0
+/* MAAH4 */
+#define KS_ADD_ADDR_4_HI		0x00A4
+/* MAAL5 */
+#define KS_ADD_ADDR_5_LO		0x00A8
+/* MAAH5 */
+#define KS_ADD_ADDR_5_HI		0x00AC
+/* MAAL6 */
+#define KS_ADD_ADDR_6_LO		0x00B0
+/* MAAH6 */
+#define KS_ADD_ADDR_6_HI		0x00B4
+/* MAAL7 */
+#define KS_ADD_ADDR_7_LO		0x00B8
+/* MAAH7 */
+#define KS_ADD_ADDR_7_HI		0x00BC
+/* MAAL8 */
+#define KS_ADD_ADDR_8_LO		0x00C0
+/* MAAH8 */
+#define KS_ADD_ADDR_8_HI		0x00C4
+/* MAAL9 */
+#define KS_ADD_ADDR_9_LO		0x00C8
+/* MAAH9 */
+#define KS_ADD_ADDR_9_HI		0x00CC
+/* MAAL10 */
+#define KS_ADD_ADDR_A_LO		0x00D0
+/* MAAH10 */
+#define KS_ADD_ADDR_A_HI		0x00D4
+/* MAAL11 */
+#define KS_ADD_ADDR_B_LO		0x00D8
+/* MAAH11 */
+#define KS_ADD_ADDR_B_HI		0x00DC
+/* MAAL12 */
+#define KS_ADD_ADDR_C_LO		0x00E0
+/* MAAH12 */
+#define KS_ADD_ADDR_C_HI		0x00E4
+/* MAAL13 */
+#define KS_ADD_ADDR_D_LO		0x00E8
+/* MAAH13 */
+#define KS_ADD_ADDR_D_HI		0x00EC
+/* MAAL14 */
+#define KS_ADD_ADDR_E_LO		0x00F0
+/* MAAH14 */
+#define KS_ADD_ADDR_E_HI		0x00F4
+/* MAAL15 */
+#define KS_ADD_ADDR_F_LO		0x00F8
+/* MAAH15 */
+#define KS_ADD_ADDR_F_HI		0x00FC
+
+#define ADD_ADDR_HI_MASK		0x0000FFFF
+#define ADD_ADDR_ENABLE			0x80000000
+#define ADD_ADDR_INCR			8
+
+/* Miscellaneous Registers */
+
+/* MARL */
+#define KS884X_ADDR_0_OFFSET		0x0200
+#define KS884X_ADDR_1_OFFSET		0x0201
+/* MARM */
+#define KS884X_ADDR_2_OFFSET		0x0202
+#define KS884X_ADDR_3_OFFSET		0x0203
+/* MARH */
+#define KS884X_ADDR_4_OFFSET		0x0204
+#define KS884X_ADDR_5_OFFSET		0x0205
+
+/* OBCR */
+#define KS884X_BUS_CTRL_OFFSET		0x0210
+
+#define BUS_SPEED_125_MHZ		0x0000
+#define BUS_SPEED_62_5_MHZ		0x0001
+#define BUS_SPEED_41_66_MHZ		0x0002
+#define BUS_SPEED_25_MHZ		0x0003
+
+/* EEPCR */
+#define KS884X_EEPROM_CTRL_OFFSET	0x0212
+
+#define EEPROM_CHIP_SELECT		0x0001
+#define EEPROM_SERIAL_CLOCK		0x0002
+#define EEPROM_DATA_OUT			0x0004
+#define EEPROM_DATA_IN			0x0008
+#define EEPROM_ACCESS_ENABLE		0x0010
+
+/* MBIR */
+#define KS884X_MEM_INFO_OFFSET		0x0214
+
+#define RX_MEM_TEST_FAILED		0x0008
+#define RX_MEM_TEST_FINISHED		0x0010
+#define TX_MEM_TEST_FAILED		0x0800
+#define TX_MEM_TEST_FINISHED		0x1000
+
+/* GCR */
+#define KS884X_GLOBAL_CTRL_OFFSET	0x0216
+#define GLOBAL_SOFTWARE_RESET		0x0001
+
+#define KS8841_POWER_MANAGE_OFFSET	0x0218
+
+/* WFCR */
+#define KS8841_WOL_CTRL_OFFSET		0x021A
+#define KS8841_WOL_MAGIC_ENABLE		0x0080
+#define KS8841_WOL_FRAME3_ENABLE	0x0008
+#define KS8841_WOL_FRAME2_ENABLE	0x0004
+#define KS8841_WOL_FRAME1_ENABLE	0x0002
+#define KS8841_WOL_FRAME0_ENABLE	0x0001
+
+/* WF0 */
+#define KS8841_WOL_FRAME_CRC_OFFSET	0x0220
+#define KS8841_WOL_FRAME_BYTE0_OFFSET	0x0224
+#define KS8841_WOL_FRAME_BYTE2_OFFSET	0x0228
+
+/* IACR */
+#define KS884X_IACR_P			0x04A0
+#define KS884X_IACR_OFFSET		KS884X_IACR_P
+
+/* IADR1 */
+#define KS884X_IADR1_P			0x04A2
+#define KS884X_IADR2_P			0x04A4
+#define KS884X_IADR3_P			0x04A6
+#define KS884X_IADR4_P			0x04A8
+#define KS884X_IADR5_P			0x04AA
+
+#define KS884X_ACC_CTRL_SEL_OFFSET	KS884X_IACR_P
+#define KS884X_ACC_CTRL_INDEX_OFFSET	(KS884X_ACC_CTRL_SEL_OFFSET + 1)
+
+#define KS884X_ACC_DATA_0_OFFSET	KS884X_IADR4_P
+#define KS884X_ACC_DATA_1_OFFSET	(KS884X_ACC_DATA_0_OFFSET + 1)
+#define KS884X_ACC_DATA_2_OFFSET	KS884X_IADR5_P
+#define KS884X_ACC_DATA_3_OFFSET	(KS884X_ACC_DATA_2_OFFSET + 1)
+#define KS884X_ACC_DATA_4_OFFSET	KS884X_IADR2_P
+#define KS884X_ACC_DATA_5_OFFSET	(KS884X_ACC_DATA_4_OFFSET + 1)
+#define KS884X_ACC_DATA_6_OFFSET	KS884X_IADR3_P
+#define KS884X_ACC_DATA_7_OFFSET	(KS884X_ACC_DATA_6_OFFSET + 1)
+#define KS884X_ACC_DATA_8_OFFSET	KS884X_IADR1_P
+
+/* P1MBCR */
+#define KS884X_P1MBCR_P			0x04D0
+#define KS884X_P1MBSR_P			0x04D2
+#define KS884X_PHY1ILR_P		0x04D4
+#define KS884X_PHY1IHR_P		0x04D6
+#define KS884X_P1ANAR_P			0x04D8
+#define KS884X_P1ANLPR_P		0x04DA
+
+/* P2MBCR */
+#define KS884X_P2MBCR_P			0x04E0
+#define KS884X_P2MBSR_P			0x04E2
+#define KS884X_PHY2ILR_P		0x04E4
+#define KS884X_PHY2IHR_P		0x04E6
+#define KS884X_P2ANAR_P			0x04E8
+#define KS884X_P2ANLPR_P		0x04EA
+
+#define KS884X_PHY_1_CTRL_OFFSET	KS884X_P1MBCR_P
+#define PHY_CTRL_INTERVAL		(KS884X_P2MBCR_P - KS884X_P1MBCR_P)
+
+#define KS884X_PHY_CTRL_OFFSET		0x00
+
+/* Mode Control Register */
+#define PHY_REG_CTRL			0
+
+#define PHY_RESET			0x8000
+#define PHY_LOOPBACK			0x4000
+#define PHY_SPEED_100MBIT		0x2000
+#define PHY_AUTO_NEG_ENABLE		0x1000
+#define PHY_POWER_DOWN			0x0800
+#define PHY_MII_DISABLE			0x0400
+#define PHY_AUTO_NEG_RESTART		0x0200
+#define PHY_FULL_DUPLEX			0x0100
+#define PHY_COLLISION_TEST		0x0080
+#define PHY_HP_MDIX			0x0020
+#define PHY_FORCE_MDIX			0x0010
+#define PHY_AUTO_MDIX_DISABLE		0x0008
+#define PHY_REMOTE_FAULT_DISABLE	0x0004
+#define PHY_TRANSMIT_DISABLE		0x0002
+#define PHY_LED_DISABLE			0x0001
+
+#define KS884X_PHY_STATUS_OFFSET	0x02
+
+/* Mode Status Register */
+#define PHY_REG_STATUS			1
+
+#define PHY_100BT4_CAPABLE		0x8000
+#define PHY_100BTX_FD_CAPABLE		0x4000
+#define PHY_100BTX_CAPABLE		0x2000
+#define PHY_10BT_FD_CAPABLE		0x1000
+#define PHY_10BT_CAPABLE		0x0800
+#define PHY_MII_SUPPRESS_CAPABLE	0x0040
+#define PHY_AUTO_NEG_ACKNOWLEDGE	0x0020
+#define PHY_REMOTE_FAULT		0x0010
+#define PHY_AUTO_NEG_CAPABLE		0x0008
+#define PHY_LINK_STATUS			0x0004
+#define PHY_JABBER_DETECT		0x0002
+#define PHY_EXTENDED_CAPABILITY		0x0001
+
+#define KS884X_PHY_ID_1_OFFSET		0x04
+#define KS884X_PHY_ID_2_OFFSET		0x06
+
+/* PHY Identifier Registers */
+#define PHY_REG_ID_1			2
+#define PHY_REG_ID_2			3
+
+#define KS884X_PHY_AUTO_NEG_OFFSET	0x08
+
+/* Auto-Negotiation Advertisement Register */
+#define PHY_REG_AUTO_NEGOTIATION	4
+
+#define PHY_AUTO_NEG_NEXT_PAGE		0x8000
+#define PHY_AUTO_NEG_REMOTE_FAULT	0x2000
+/* Not supported. */
+#define PHY_AUTO_NEG_ASYM_PAUSE		0x0800
+#define PHY_AUTO_NEG_SYM_PAUSE		0x0400
+#define PHY_AUTO_NEG_100BT4		0x0200
+#define PHY_AUTO_NEG_100BTX_FD		0x0100
+#define PHY_AUTO_NEG_100BTX		0x0080
+#define PHY_AUTO_NEG_10BT_FD		0x0040
+#define PHY_AUTO_NEG_10BT		0x0020
+#define PHY_AUTO_NEG_SELECTOR		0x001F
+#define PHY_AUTO_NEG_802_3		0x0001
+
+#define PHY_AUTO_NEG_PAUSE  (PHY_AUTO_NEG_SYM_PAUSE | PHY_AUTO_NEG_ASYM_PAUSE)
+
+#define KS884X_PHY_REMOTE_CAP_OFFSET	0x0A
+
+/* Auto-Negotiation Link Partner Ability Register */
+#define PHY_REG_REMOTE_CAPABILITY	5
+
+#define PHY_REMOTE_NEXT_PAGE		0x8000
+#define PHY_REMOTE_ACKNOWLEDGE		0x4000
+#define PHY_REMOTE_REMOTE_FAULT		0x2000
+#define PHY_REMOTE_SYM_PAUSE		0x0400
+#define PHY_REMOTE_100BTX_FD		0x0100
+#define PHY_REMOTE_100BTX		0x0080
+#define PHY_REMOTE_10BT_FD		0x0040
+#define PHY_REMOTE_10BT			0x0020
+
+/* P1VCT */
+#define KS884X_P1VCT_P			0x04F0
+#define KS884X_P1PHYCTRL_P		0x04F2
+
+/* P2VCT */
+#define KS884X_P2VCT_P			0x04F4
+#define KS884X_P2PHYCTRL_P		0x04F6
+
+#define KS884X_PHY_SPECIAL_OFFSET	KS884X_P1VCT_P
+#define PHY_SPECIAL_INTERVAL		(KS884X_P2VCT_P - KS884X_P1VCT_P)
+
+#define KS884X_PHY_LINK_MD_OFFSET	0x00
+
+#define PHY_START_CABLE_DIAG		0x8000
+#define PHY_CABLE_DIAG_RESULT		0x6000
+#define PHY_CABLE_STAT_NORMAL		0x0000
+#define PHY_CABLE_STAT_OPEN		0x2000
+#define PHY_CABLE_STAT_SHORT		0x4000
+#define PHY_CABLE_STAT_FAILED		0x6000
+#define PHY_CABLE_10M_SHORT		0x1000
+#define PHY_CABLE_FAULT_COUNTER		0x01FF
+
+#define KS884X_PHY_PHY_CTRL_OFFSET	0x02
+
+#define PHY_STAT_REVERSED_POLARITY	0x0020
+#define PHY_STAT_MDIX			0x0010
+#define PHY_FORCE_LINK			0x0008
+#define PHY_POWER_SAVING_DISABLE	0x0004
+#define PHY_REMOTE_LOOPBACK		0x0002
+
+/* SIDER */
+#define KS884X_SIDER_P			0x0400
+#define KS884X_CHIP_ID_OFFSET		KS884X_SIDER_P
+#define KS884X_FAMILY_ID_OFFSET		(KS884X_CHIP_ID_OFFSET + 1)
+
+#define REG_FAMILY_ID			0x88
+
+#define REG_CHIP_ID_41			0x8810
+#define REG_CHIP_ID_42			0x8800
+
+#define KS884X_CHIP_ID_MASK_41		0xFF10
+#define KS884X_CHIP_ID_MASK		0xFFF0
+#define KS884X_CHIP_ID_SHIFT		4
+#define KS884X_REVISION_MASK		0x000E
+#define KS884X_REVISION_SHIFT		1
+#define KS8842_START			0x0001
+
+#define CHIP_IP_41_M			0x8810
+#define CHIP_IP_42_M			0x8800
+#define CHIP_IP_61_M			0x8890
+#define CHIP_IP_62_M			0x8880
+
+#define CHIP_IP_41_P			0x8850
+#define CHIP_IP_42_P			0x8840
+#define CHIP_IP_61_P			0x88D0
+#define CHIP_IP_62_P			0x88C0
+
+/* SGCR1 */
+#define KS8842_SGCR1_P			0x0402
+#define KS8842_SWITCH_CTRL_1_OFFSET	KS8842_SGCR1_P
+
+#define SWITCH_PASS_ALL			0x8000
+#define SWITCH_TX_FLOW_CTRL		0x2000
+#define SWITCH_RX_FLOW_CTRL		0x1000
+#define SWITCH_CHECK_LENGTH		0x0800
+#define SWITCH_AGING_ENABLE		0x0400
+#define SWITCH_FAST_AGING		0x0200
+#define SWITCH_AGGR_BACKOFF		0x0100
+#define SWITCH_PASS_PAUSE		0x0008
+#define SWITCH_LINK_AUTO_AGING		0x0001
+
+/* SGCR2 */
+#define KS8842_SGCR2_P			0x0404
+#define KS8842_SWITCH_CTRL_2_OFFSET	KS8842_SGCR2_P
+
+#define SWITCH_VLAN_ENABLE		0x8000
+#define SWITCH_IGMP_SNOOP		0x4000
+#define IPV6_MLD_SNOOP_ENABLE		0x2000
+#define IPV6_MLD_SNOOP_OPTION		0x1000
+#define PRIORITY_SCHEME_SELECT		0x0800
+#define SWITCH_MIRROR_RX_TX		0x0100
+#define UNICAST_VLAN_BOUNDARY		0x0080
+#define MULTICAST_STORM_DISABLE		0x0040
+#define SWITCH_BACK_PRESSURE		0x0020
+#define FAIR_FLOW_CTRL			0x0010
+#define NO_EXC_COLLISION_DROP		0x0008
+#define SWITCH_HUGE_PACKET		0x0004
+#define SWITCH_LEGAL_PACKET		0x0002
+#define SWITCH_BUF_RESERVE		0x0001
+
+/* SGCR3 */
+#define KS8842_SGCR3_P			0x0406
+#define KS8842_SWITCH_CTRL_3_OFFSET	KS8842_SGCR3_P
+
+#define BROADCAST_STORM_RATE_LO		0xFF00
+#define SWITCH_REPEATER			0x0080
+#define SWITCH_HALF_DUPLEX		0x0040
+#define SWITCH_FLOW_CTRL		0x0020
+#define SWITCH_10_MBIT			0x0010
+#define SWITCH_REPLACE_NULL_VID		0x0008
+#define BROADCAST_STORM_RATE_HI		0x0007
+
+#define BROADCAST_STORM_RATE		0x07FF
+
+/* SGCR4 */
+#define KS8842_SGCR4_P			0x0408
+
+/* SGCR5 */
+#define KS8842_SGCR5_P			0x040A
+#define KS8842_SWITCH_CTRL_5_OFFSET	KS8842_SGCR5_P
+
+#define LED_MODE			0x8200
+#define LED_SPEED_DUPLEX_ACT		0x0000
+#define LED_SPEED_DUPLEX_LINK_ACT	0x8000
+#define LED_DUPLEX_10_100		0x0200
+
+/* SGCR6 */
+#define KS8842_SGCR6_P			0x0410
+#define KS8842_SWITCH_CTRL_6_OFFSET	KS8842_SGCR6_P
+
+#define KS8842_PRIORITY_MASK		3
+#define KS8842_PRIORITY_SHIFT		2
+
+/* SGCR7 */
+#define KS8842_SGCR7_P			0x0412
+#define KS8842_SWITCH_CTRL_7_OFFSET	KS8842_SGCR7_P
+
+#define SWITCH_UNK_DEF_PORT_ENABLE	0x0008
+#define SWITCH_UNK_DEF_PORT_3		0x0004
+#define SWITCH_UNK_DEF_PORT_2		0x0002
+#define SWITCH_UNK_DEF_PORT_1		0x0001
+
+/* MACAR1 */
+#define KS8842_MACAR1_P			0x0470
+#define KS8842_MACAR2_P			0x0472
+#define KS8842_MACAR3_P			0x0474
+#define KS8842_MAC_ADDR_1_OFFSET	KS8842_MACAR1_P
+#define KS8842_MAC_ADDR_0_OFFSET	(KS8842_MAC_ADDR_1_OFFSET + 1)
+#define KS8842_MAC_ADDR_3_OFFSET	KS8842_MACAR2_P
+#define KS8842_MAC_ADDR_2_OFFSET	(KS8842_MAC_ADDR_3_OFFSET + 1)
+#define KS8842_MAC_ADDR_5_OFFSET	KS8842_MACAR3_P
+#define KS8842_MAC_ADDR_4_OFFSET	(KS8842_MAC_ADDR_5_OFFSET + 1)
+
+/* TOSR1 */
+#define KS8842_TOSR1_P			0x0480
+#define KS8842_TOSR2_P			0x0482
+#define KS8842_TOSR3_P			0x0484
+#define KS8842_TOSR4_P			0x0486
+#define KS8842_TOSR5_P			0x0488
+#define KS8842_TOSR6_P			0x048A
+#define KS8842_TOSR7_P			0x0490
+#define KS8842_TOSR8_P			0x0492
+#define KS8842_TOS_1_OFFSET		KS8842_TOSR1_P
+#define KS8842_TOS_2_OFFSET		KS8842_TOSR2_P
+#define KS8842_TOS_3_OFFSET		KS8842_TOSR3_P
+#define KS8842_TOS_4_OFFSET		KS8842_TOSR4_P
+#define KS8842_TOS_5_OFFSET		KS8842_TOSR5_P
+#define KS8842_TOS_6_OFFSET		KS8842_TOSR6_P
+
+#define KS8842_TOS_7_OFFSET		KS8842_TOSR7_P
+#define KS8842_TOS_8_OFFSET		KS8842_TOSR8_P
+
+/* P1CR1 */
+#define KS8842_P1CR1_P			0x0500
+#define KS8842_P1CR2_P			0x0502
+#define KS8842_P1VIDR_P			0x0504
+#define KS8842_P1CR3_P			0x0506
+#define KS8842_P1IRCR_P			0x0508
+#define KS8842_P1ERCR_P			0x050A
+#define KS884X_P1SCSLMD_P		0x0510
+#define KS884X_P1CR4_P			0x0512
+#define KS884X_P1SR_P			0x0514
+
+/* P2CR1 */
+#define KS8842_P2CR1_P			0x0520
+#define KS8842_P2CR2_P			0x0522
+#define KS8842_P2VIDR_P			0x0524
+#define KS8842_P2CR3_P			0x0526
+#define KS8842_P2IRCR_P			0x0528
+#define KS8842_P2ERCR_P			0x052A
+#define KS884X_P2SCSLMD_P		0x0530
+#define KS884X_P2CR4_P			0x0532
+#define KS884X_P2SR_P			0x0534
+
+/* P3CR1 */
+#define KS8842_P3CR1_P			0x0540
+#define KS8842_P3CR2_P			0x0542
+#define KS8842_P3VIDR_P			0x0544
+#define KS8842_P3CR3_P			0x0546
+#define KS8842_P3IRCR_P			0x0548
+#define KS8842_P3ERCR_P			0x054A
+
+#define KS8842_PORT_1_CTRL_1		KS8842_P1CR1_P
+#define KS8842_PORT_2_CTRL_1		KS8842_P2CR1_P
+#define KS8842_PORT_3_CTRL_1		KS8842_P3CR1_P
+
+#define PORT_CTRL_ADDR(port, addr)		\
+	(addr = KS8842_PORT_1_CTRL_1 + (port) *	\
+		(KS8842_PORT_2_CTRL_1 - KS8842_PORT_1_CTRL_1))
+
+#define KS8842_PORT_CTRL_1_OFFSET	0x00
+
+#define PORT_BROADCAST_STORM		0x0080
+#define PORT_DIFFSERV_ENABLE		0x0040
+#define PORT_802_1P_ENABLE		0x0020
+#define PORT_BASED_PRIORITY_MASK	0x0018
+#define PORT_BASED_PRIORITY_BASE	0x0003
+#define PORT_BASED_PRIORITY_SHIFT	3
+#define PORT_BASED_PRIORITY_0		0x0000
+#define PORT_BASED_PRIORITY_1		0x0008
+#define PORT_BASED_PRIORITY_2		0x0010
+#define PORT_BASED_PRIORITY_3		0x0018
+#define PORT_INSERT_TAG			0x0004
+#define PORT_REMOVE_TAG			0x0002
+#define PORT_PRIO_QUEUE_ENABLE		0x0001
+
+#define KS8842_PORT_CTRL_2_OFFSET	0x02
+
+#define PORT_INGRESS_VLAN_FILTER	0x4000
+#define PORT_DISCARD_NON_VID		0x2000
+#define PORT_FORCE_FLOW_CTRL		0x1000
+#define PORT_BACK_PRESSURE		0x0800
+#define PORT_TX_ENABLE			0x0400
+#define PORT_RX_ENABLE			0x0200
+#define PORT_LEARN_DISABLE		0x0100
+#define PORT_MIRROR_SNIFFER		0x0080
+#define PORT_MIRROR_RX			0x0040
+#define PORT_MIRROR_TX			0x0020
+#define PORT_USER_PRIORITY_CEILING	0x0008
+#define PORT_VLAN_MEMBERSHIP		0x0007
+
+#define KS8842_PORT_CTRL_VID_OFFSET	0x04
+
+#define PORT_DEFAULT_VID		0x0001
+
+#define KS8842_PORT_CTRL_3_OFFSET	0x06
+
+#define PORT_INGRESS_LIMIT_MODE		0x000C
+#define PORT_INGRESS_ALL		0x0000
+#define PORT_INGRESS_UNICAST		0x0004
+#define PORT_INGRESS_MULTICAST		0x0008
+#define PORT_INGRESS_BROADCAST		0x000C
+#define PORT_COUNT_IFG			0x0002
+#define PORT_COUNT_PREAMBLE		0x0001
+
+#define KS8842_PORT_IN_RATE_OFFSET	0x08
+#define KS8842_PORT_OUT_RATE_OFFSET	0x0A
+
+#define PORT_PRIORITY_RATE		0x0F
+#define PORT_PRIORITY_RATE_SHIFT	4
+
+#define KS884X_PORT_LINK_MD		0x10
+
+#define PORT_CABLE_10M_SHORT		0x8000
+#define PORT_CABLE_DIAG_RESULT		0x6000
+#define PORT_CABLE_STAT_NORMAL		0x0000
+#define PORT_CABLE_STAT_OPEN		0x2000
+#define PORT_CABLE_STAT_SHORT		0x4000
+#define PORT_CABLE_STAT_FAILED		0x6000
+#define PORT_START_CABLE_DIAG		0x1000
+#define PORT_FORCE_LINK			0x0800
+#define PORT_POWER_SAVING_DISABLE	0x0400
+#define PORT_PHY_REMOTE_LOOPBACK	0x0200
+#define PORT_CABLE_FAULT_COUNTER	0x01FF
+
+#define KS884X_PORT_CTRL_4_OFFSET	0x12
+
+#define PORT_LED_OFF			0x8000
+#define PORT_TX_DISABLE			0x4000
+#define PORT_AUTO_NEG_RESTART		0x2000
+#define PORT_REMOTE_FAULT_DISABLE	0x1000
+#define PORT_POWER_DOWN			0x0800
+#define PORT_AUTO_MDIX_DISABLE		0x0400
+#define PORT_FORCE_MDIX			0x0200
+#define PORT_LOOPBACK			0x0100
+#define PORT_AUTO_NEG_ENABLE		0x0080
+#define PORT_FORCE_100_MBIT		0x0040
+#define PORT_FORCE_FULL_DUPLEX		0x0020
+#define PORT_AUTO_NEG_SYM_PAUSE		0x0010
+#define PORT_AUTO_NEG_100BTX_FD		0x0008
+#define PORT_AUTO_NEG_100BTX		0x0004
+#define PORT_AUTO_NEG_10BT_FD		0x0002
+#define PORT_AUTO_NEG_10BT		0x0001
+
+#define KS884X_PORT_STATUS_OFFSET	0x14
+
+#define PORT_HP_MDIX			0x8000
+#define PORT_REVERSED_POLARITY		0x2000
+#define PORT_RX_FLOW_CTRL		0x0800
+#define PORT_TX_FLOW_CTRL		0x1000
+#define PORT_STATUS_SPEED_100MBIT	0x0400
+#define PORT_STATUS_FULL_DUPLEX		0x0200
+#define PORT_REMOTE_FAULT		0x0100
+#define PORT_MDIX_STATUS		0x0080
+#define PORT_AUTO_NEG_COMPLETE		0x0040
+#define PORT_STATUS_LINK_GOOD		0x0020
+#define PORT_REMOTE_SYM_PAUSE		0x0010
+#define PORT_REMOTE_100BTX_FD		0x0008
+#define PORT_REMOTE_100BTX		0x0004
+#define PORT_REMOTE_10BT_FD		0x0002
+#define PORT_REMOTE_10BT		0x0001
+
+/*
+#define STATIC_MAC_TABLE_ADDR		00-0000FFFF-FFFFFFFF
+#define STATIC_MAC_TABLE_FWD_PORTS	00-00070000-00000000
+#define STATIC_MAC_TABLE_VALID		00-00080000-00000000
+#define STATIC_MAC_TABLE_OVERRIDE	00-00100000-00000000
+#define STATIC_MAC_TABLE_USE_FID	00-00200000-00000000
+#define STATIC_MAC_TABLE_FID		00-03C00000-00000000
+*/
+
+#define STATIC_MAC_TABLE_ADDR		0x0000FFFF
+#define STATIC_MAC_TABLE_FWD_PORTS	0x00070000
+#define STATIC_MAC_TABLE_VALID		0x00080000
+#define STATIC_MAC_TABLE_OVERRIDE	0x00100000
+#define STATIC_MAC_TABLE_USE_FID	0x00200000
+#define STATIC_MAC_TABLE_FID		0x03C00000
+
+#define STATIC_MAC_FWD_PORTS_SHIFT	16
+#define STATIC_MAC_FID_SHIFT		22
+
+/*
+#define VLAN_TABLE_VID			00-00000000-00000FFF
+#define VLAN_TABLE_FID			00-00000000-0000F000
+#define VLAN_TABLE_MEMBERSHIP		00-00000000-00070000
+#define VLAN_TABLE_VALID		00-00000000-00080000
+*/
+
+#define VLAN_TABLE_VID			0x00000FFF
+#define VLAN_TABLE_FID			0x0000F000
+#define VLAN_TABLE_MEMBERSHIP		0x00070000
+#define VLAN_TABLE_VALID		0x00080000
+
+#define VLAN_TABLE_FID_SHIFT		12
+#define VLAN_TABLE_MEMBERSHIP_SHIFT	16
+
+/*
+#define DYNAMIC_MAC_TABLE_ADDR		00-0000FFFF-FFFFFFFF
+#define DYNAMIC_MAC_TABLE_FID		00-000F0000-00000000
+#define DYNAMIC_MAC_TABLE_SRC_PORT	00-00300000-00000000
+#define DYNAMIC_MAC_TABLE_TIMESTAMP	00-00C00000-00000000
+#define DYNAMIC_MAC_TABLE_ENTRIES	03-FF000000-00000000
+#define DYNAMIC_MAC_TABLE_MAC_EMPTY	04-00000000-00000000
+#define DYNAMIC_MAC_TABLE_RESERVED	78-00000000-00000000
+#define DYNAMIC_MAC_TABLE_NOT_READY	80-00000000-00000000
+*/
+
+#define DYNAMIC_MAC_TABLE_ADDR		0x0000FFFF
+#define DYNAMIC_MAC_TABLE_FID		0x000F0000
+#define DYNAMIC_MAC_TABLE_SRC_PORT	0x00300000
+#define DYNAMIC_MAC_TABLE_TIMESTAMP	0x00C00000
+#define DYNAMIC_MAC_TABLE_ENTRIES	0xFF000000
+
+#define DYNAMIC_MAC_TABLE_ENTRIES_H	0x03
+#define DYNAMIC_MAC_TABLE_MAC_EMPTY	0x04
+#define DYNAMIC_MAC_TABLE_RESERVED	0x78
+#define DYNAMIC_MAC_TABLE_NOT_READY	0x80
+
+#define DYNAMIC_MAC_FID_SHIFT		16
+#define DYNAMIC_MAC_SRC_PORT_SHIFT	20
+#define DYNAMIC_MAC_TIMESTAMP_SHIFT	22
+#define DYNAMIC_MAC_ENTRIES_SHIFT	24
+#define DYNAMIC_MAC_ENTRIES_H_SHIFT	8
+
+/*
+#define MIB_COUNTER_VALUE		00-00000000-3FFFFFFF
+#define MIB_COUNTER_VALID		00-00000000-40000000
+#define MIB_COUNTER_OVERFLOW		00-00000000-80000000
+*/
+
+#define MIB_COUNTER_VALUE		0x3FFFFFFF
+#define MIB_COUNTER_VALID		0x40000000
+#define MIB_COUNTER_OVERFLOW		0x80000000
+
+#define MIB_PACKET_DROPPED		0x0000FFFF
+
+#define KS_MIB_PACKET_DROPPED_TX_0	0x100
+#define KS_MIB_PACKET_DROPPED_TX_1	0x101
+#define KS_MIB_PACKET_DROPPED_TX	0x102
+#define KS_MIB_PACKET_DROPPED_RX_0	0x103
+#define KS_MIB_PACKET_DROPPED_RX_1	0x104
+#define KS_MIB_PACKET_DROPPED_RX	0x105
+
+/* Change default LED mode. */
+#define SET_DEFAULT_LED			LED_SPEED_DUPLEX_ACT
+
+#define MAC_ADDR_LEN			6
+#define MAC_ADDR_ORDER(i)		(MAC_ADDR_LEN - 1 - (i))
+
+#define MAX_ETHERNET_BODY_SIZE		1500
+#define ETHERNET_HEADER_SIZE		14
+
+#define MAX_ETHERNET_PACKET_SIZE	\
+	(MAX_ETHERNET_BODY_SIZE + ETHERNET_HEADER_SIZE)
+
+#define REGULAR_RX_BUF_SIZE		(MAX_ETHERNET_PACKET_SIZE + 4)
+#define MAX_RX_BUF_SIZE			(1912 + 4)
+
+#define ADDITIONAL_ENTRIES		16
+#define MAX_MULTICAST_LIST		32
+
+#define HW_MULTICAST_SIZE		8
+
+#define HW_TO_DEV_PORT(port)		(port - 1)
+
+enum {
+	media_connected,
+	media_disconnected
+};
+
+enum {
+	OID_COUNTER_UNKOWN,
+
+	OID_COUNTER_FIRST,
+
+	/* total transmit errors */
+	OID_COUNTER_XMIT_ERROR,
+
+	/* total receive errors */
+	OID_COUNTER_RCV_ERROR,
+
+	OID_COUNTER_LAST
+};
+
+/*
+ * Hardware descriptor definitions
+ */
+
+#define DESC_ALIGNMENT			16
+#define BUFFER_ALIGNMENT		8
+
+#define NUM_OF_RX_DESC			64
+#define NUM_OF_TX_DESC			64
+
+#define KS_DESC_RX_FRAME_LEN		0x000007FF
+#define KS_DESC_RX_FRAME_TYPE		0x00008000
+#define KS_DESC_RX_ERROR_CRC		0x00010000
+#define KS_DESC_RX_ERROR_RUNT		0x00020000
+#define KS_DESC_RX_ERROR_TOO_LONG	0x00040000
+#define KS_DESC_RX_ERROR_PHY		0x00080000
+#define KS884X_DESC_RX_PORT_MASK	0x00300000
+#define KS_DESC_RX_MULTICAST		0x01000000
+#define KS_DESC_RX_ERROR		0x02000000
+#define KS_DESC_RX_ERROR_CSUM_UDP	0x04000000
+#define KS_DESC_RX_ERROR_CSUM_TCP	0x08000000
+#define KS_DESC_RX_ERROR_CSUM_IP	0x10000000
+#define KS_DESC_RX_LAST			0x20000000
+#define KS_DESC_RX_FIRST		0x40000000
+#define KS_DESC_RX_ERROR_COND		\
+	(KS_DESC_RX_ERROR_CRC |		\
+	KS_DESC_RX_ERROR_RUNT |		\
+	KS_DESC_RX_ERROR_PHY |		\
+	KS_DESC_RX_ERROR_TOO_LONG)
+
+#define KS_DESC_HW_OWNED		0x80000000
+
+#define KS_DESC_BUF_SIZE		0x000007FF
+#define KS884X_DESC_TX_PORT_MASK	0x00300000
+#define KS_DESC_END_OF_RING		0x02000000
+#define KS_DESC_TX_CSUM_GEN_UDP		0x04000000
+#define KS_DESC_TX_CSUM_GEN_TCP		0x08000000
+#define KS_DESC_TX_CSUM_GEN_IP		0x10000000
+#define KS_DESC_TX_LAST			0x20000000
+#define KS_DESC_TX_FIRST		0x40000000
+#define KS_DESC_TX_INTERRUPT		0x80000000
+
+#define KS_DESC_PORT_SHIFT		20
+
+#define KS_DESC_RX_MASK			(KS_DESC_BUF_SIZE)
+
+#define KS_DESC_TX_MASK			\
+	(KS_DESC_TX_INTERRUPT |		\
+	KS_DESC_TX_FIRST |		\
+	KS_DESC_TX_LAST |		\
+	KS_DESC_TX_CSUM_GEN_IP |	\
+	KS_DESC_TX_CSUM_GEN_TCP |	\
+	KS_DESC_TX_CSUM_GEN_UDP |	\
+	KS_DESC_BUF_SIZE)
+
+struct ksz_desc_rx_stat {
+#ifdef __BIG_ENDIAN_BITFIELD
+	u32 hw_owned:1;
+	u32 first_desc:1;
+	u32 last_desc:1;
+	u32 csum_err_ip:1;
+	u32 csum_err_tcp:1;
+	u32 csum_err_udp:1;
+	u32 error:1;
+	u32 multicast:1;
+	u32 src_port:4;
+	u32 err_phy:1;
+	u32 err_too_long:1;
+	u32 err_runt:1;
+	u32 err_crc:1;
+	u32 frame_type:1;
+	u32 reserved1:4;
+	u32 frame_len:11;
+#else
+	u32 frame_len:11;
+	u32 reserved1:4;
+	u32 frame_type:1;
+	u32 err_crc:1;
+	u32 err_runt:1;
+	u32 err_too_long:1;
+	u32 err_phy:1;
+	u32 src_port:4;
+	u32 multicast:1;
+	u32 error:1;
+	u32 csum_err_udp:1;
+	u32 csum_err_tcp:1;
+	u32 csum_err_ip:1;
+	u32 last_desc:1;
+	u32 first_desc:1;
+	u32 hw_owned:1;
+#endif
+};
+
+struct ksz_desc_tx_stat {
+#ifdef __BIG_ENDIAN_BITFIELD
+	u32 hw_owned:1;
+	u32 reserved1:31;
+#else
+	u32 reserved1:31;
+	u32 hw_owned:1;
+#endif
+};
+
+struct ksz_desc_rx_buf {
+#ifdef __BIG_ENDIAN_BITFIELD
+	u32 reserved4:6;
+	u32 end_of_ring:1;
+	u32 reserved3:14;
+	u32 buf_size:11;
+#else
+	u32 buf_size:11;
+	u32 reserved3:14;
+	u32 end_of_ring:1;
+	u32 reserved4:6;
+#endif
+};
+
+struct ksz_desc_tx_buf {
+#ifdef __BIG_ENDIAN_BITFIELD
+	u32 intr:1;
+	u32 first_seg:1;
+	u32 last_seg:1;
+	u32 csum_gen_ip:1;
+	u32 csum_gen_tcp:1;
+	u32 csum_gen_udp:1;
+	u32 end_of_ring:1;
+	u32 reserved4:1;
+	u32 dest_port:4;
+	u32 reserved3:9;
+	u32 buf_size:11;
+#else
+	u32 buf_size:11;
+	u32 reserved3:9;
+	u32 dest_port:4;
+	u32 reserved4:1;
+	u32 end_of_ring:1;
+	u32 csum_gen_udp:1;
+	u32 csum_gen_tcp:1;
+	u32 csum_gen_ip:1;
+	u32 last_seg:1;
+	u32 first_seg:1;
+	u32 intr:1;
+#endif
+};
+
+union desc_stat {
+	struct ksz_desc_rx_stat rx;
+	struct ksz_desc_tx_stat tx;
+	u32 data;
+};
+
+union desc_buf {
+	struct ksz_desc_rx_buf rx;
+	struct ksz_desc_tx_buf tx;
+	u32 data;
+};
+
+/**
+ * struct ksz_hw_desc - Hardware descriptor data structure
+ * @ctrl:	Descriptor control value.
+ * @buf:	Descriptor buffer value.
+ * @addr:	Physical address of memory buffer.
+ * @next:	Pointer to next hardware descriptor.
+ */
+struct ksz_hw_desc {
+	union desc_stat ctrl;
+	union desc_buf buf;
+	u32 addr;
+	u32 next;
+};
+
+/**
+ * struct ksz_sw_desc - Software descriptor data structure
+ * @ctrl:	Descriptor control value.
+ * @buf:	Descriptor buffer value.
+ * @buf_size:	Current buffers size value in hardware descriptor.
+ */
+struct ksz_sw_desc {
+	union desc_stat ctrl;
+	union desc_buf buf;
+	u32 buf_size;
+};
+
+/**
+ * struct ksz_dma_buf - OS dependent DMA buffer data structure
+ * @skb:	Associated socket buffer.
+ * @dma:	Associated physical DMA address.
+ * len:		Actual len used.
+ */
+struct ksz_dma_buf {
+	struct sk_buff *skb;
+	dma_addr_t dma;
+	int len;
+};
+
+/**
+ * struct ksz_desc - Descriptor structure
+ * @phw:	Hardware descriptor pointer to uncached physical memory.
+ * @sw:		Cached memory to hold hardware descriptor values for
+ * 		manipulation.
+ * @dma_buf:	Operating system dependent data structure to hold physical
+ * 		memory buffer allocation information.
+ */
+struct ksz_desc {
+	struct ksz_hw_desc *phw;
+	struct ksz_sw_desc sw;
+	struct ksz_dma_buf dma_buf;
+};
+
+#define DMA_BUFFER(desc)  ((struct ksz_dma_buf *)(&(desc)->dma_buf))
+
+/**
+ * struct ksz_desc_info - Descriptor information data structure
+ * @ring:	First descriptor in the ring.
+ * @cur:	Current descriptor being manipulated.
+ * @ring_virt:	First hardware descriptor in the ring.
+ * @ring_phys:	The physical address of the first descriptor of the ring.
+ * @size:	Size of hardware descriptor.
+ * @alloc:	Number of descriptors allocated.
+ * @avail:	Number of descriptors available for use.
+ * @last:	Index for last descriptor released to hardware.
+ * @next:	Index for next descriptor available for use.
+ * @mask:	Mask for index wrapping.
+ */
+struct ksz_desc_info {
+	struct ksz_desc *ring;
+	struct ksz_desc *cur;
+	struct ksz_hw_desc *ring_virt;
+	u32 ring_phys;
+	int size;
+	int alloc;
+	int avail;
+	int last;
+	int next;
+	int mask;
+};
+
+/*
+ * KSZ8842 switch definitions
+ */
+
+enum {
+	TABLE_STATIC_MAC = 0,
+	TABLE_VLAN,
+	TABLE_DYNAMIC_MAC,
+	TABLE_MIB
+};
+
+#define LEARNED_MAC_TABLE_ENTRIES	1024
+#define STATIC_MAC_TABLE_ENTRIES	8
+
+/**
+ * struct ksz_mac_table - Static MAC table data structure
+ * @mac_addr:	MAC address to filter.
+ * @vid:	VID value.
+ * @fid:	FID value.
+ * @ports:	Port membership.
+ * @override:	Override setting.
+ * @use_fid:	FID use setting.
+ * @valid:	Valid setting indicating the entry is being used.
+ */
+struct ksz_mac_table {
+	u8 mac_addr[MAC_ADDR_LEN];
+	u16 vid;
+	u8 fid;
+	u8 ports;
+	u8 override:1;
+	u8 use_fid:1;
+	u8 valid:1;
+};
+
+#define VLAN_TABLE_ENTRIES		16
+
+/**
+ * struct ksz_vlan_table - VLAN table data structure
+ * @vid:	VID value.
+ * @fid:	FID value.
+ * @member:	Port membership.
+ */
+struct ksz_vlan_table {
+	u16 vid;
+	u8 fid;
+	u8 member;
+};
+
+#define DIFFSERV_ENTRIES		64
+#define PRIO_802_1P_ENTRIES		8
+#define PRIO_QUEUES			4
+
+#define SWITCH_PORT_NUM			2
+#define TOTAL_PORT_NUM			(SWITCH_PORT_NUM + 1)
+#define HOST_MASK			(1 << SWITCH_PORT_NUM)
+#define PORT_MASK			7
+
+#define MAIN_PORT			0
+#define OTHER_PORT			1
+#define HOST_PORT			SWITCH_PORT_NUM
+
+#define PORT_COUNTER_NUM		0x20
+#define TOTAL_PORT_COUNTER_NUM		(PORT_COUNTER_NUM + 2)
+
+#define MIB_COUNTER_RX_LO_PRIORITY	0x00
+#define MIB_COUNTER_RX_HI_PRIORITY	0x01
+#define MIB_COUNTER_RX_UNDERSIZE	0x02
+#define MIB_COUNTER_RX_FRAGMENT		0x03
+#define MIB_COUNTER_RX_OVERSIZE		0x04
+#define MIB_COUNTER_RX_JABBER		0x05
+#define MIB_COUNTER_RX_SYMBOL_ERR	0x06
+#define MIB_COUNTER_RX_CRC_ERR		0x07
+#define MIB_COUNTER_RX_ALIGNMENT_ERR	0x08
+#define MIB_COUNTER_RX_CTRL_8808	0x09
+#define MIB_COUNTER_RX_PAUSE		0x0A
+#define MIB_COUNTER_RX_BROADCAST	0x0B
+#define MIB_COUNTER_RX_MULTICAST	0x0C
+#define MIB_COUNTER_RX_UNICAST		0x0D
+#define MIB_COUNTER_RX_OCTET_64		0x0E
+#define MIB_COUNTER_RX_OCTET_65_127	0x0F
+#define MIB_COUNTER_RX_OCTET_128_255	0x10
+#define MIB_COUNTER_RX_OCTET_256_511	0x11
+#define MIB_COUNTER_RX_OCTET_512_1023	0x12
+#define MIB_COUNTER_RX_OCTET_1024_1522	0x13
+#define MIB_COUNTER_TX_LO_PRIORITY	0x14
+#define MIB_COUNTER_TX_HI_PRIORITY	0x15
+#define MIB_COUNTER_TX_LATE_COLLISION	0x16
+#define MIB_COUNTER_TX_PAUSE		0x17
+#define MIB_COUNTER_TX_BROADCAST	0x18
+#define MIB_COUNTER_TX_MULTICAST	0x19
+#define MIB_COUNTER_TX_UNICAST		0x1A
+#define MIB_COUNTER_TX_DEFERRED		0x1B
+#define MIB_COUNTER_TX_TOTAL_COLLISION	0x1C
+#define MIB_COUNTER_TX_EXCESS_COLLISION	0x1D
+#define MIB_COUNTER_TX_SINGLE_COLLISION	0x1E
+#define MIB_COUNTER_TX_MULTI_COLLISION	0x1F
+
+#define MIB_COUNTER_RX_DROPPED_PACKET	0x20
+#define MIB_COUNTER_TX_DROPPED_PACKET	0x21
+
+/**
+ * struct ksz_port_mib - Port MIB data structure
+ * @cnt_ptr:	Current pointer to MIB counter index.
+ * @link_down:	Indication the link has just gone down.
+ * @state:	Connection status of the port.
+ * @mib_start:	The starting counter index.  Some ports do not start at 0.
+ * @counter:	64-bit MIB counter value.
+ * @dropped:	Temporary buffer to remember last read packet dropped values.
+ *
+ * MIB counters needs to be read periodically so that counters do not get
+ * overflowed and give incorrect values.  A right balance is needed to
+ * satisfy this condition and not waste too much CPU time.
+ *
+ * It is pointless to read MIB counters when the port is disconnected.  The
+ * @state provides the connection status so that MIB counters are read only
+ * when the port is connected.  The @link_down indicates the port is just
+ * disconnected so that all MIB counters are read one last time to update the
+ * information.
+ */
+struct ksz_port_mib {
+	u8 cnt_ptr;
+	u8 link_down;
+	u8 state;
+	u8 mib_start;
+
+	u64 counter[TOTAL_PORT_COUNTER_NUM];
+	u32 dropped[2];
+};
+
+/**
+ * struct ksz_port_cfg - Port configuration data structure
+ * @vid:	VID value.
+ * @member:	Port membership.
+ * @port_prio:	Port priority.
+ * @rx_rate:	Receive priority rate.
+ * @tx_rate:	Transmit priority rate.
+ * @stp_state:	Current Spanning Tree Protocol state.
+ */
+struct ksz_port_cfg {
+	u16 vid;
+	u8 member;
+	u8 port_prio;
+	u32 rx_rate[PRIO_QUEUES];
+	u32 tx_rate[PRIO_QUEUES];
+	int stp_state;
+};
+
+/**
+ * struct ksz_switch - KSZ8842 switch data structure
+ * @mac_table:	MAC table entries information.
+ * @vlan_table:	VLAN table entries information.
+ * @port_cfg:	Port configuration information.
+ * @diffserv:	DiffServ priority settings.  Possible values from 6-bit of ToS
+ * 		(bit7 ~ bit2) field.
+ * @p_802_1p:	802.1P priority settings.  Possible values from 3-bit of 802.1p
+ * 		Tag priority field.
+ * @br_addr:	Bridge address.  Used for STP.
+ * @other_addr:	Other MAC address.  Used for multiple network device mode.
+ * @broad_per:	Broadcast storm percentage.
+ * @member:	Current port membership.  Used for STP.
+ */
+struct ksz_switch {
+	struct ksz_mac_table mac_table[STATIC_MAC_TABLE_ENTRIES];
+	struct ksz_vlan_table vlan_table[VLAN_TABLE_ENTRIES];
+	struct ksz_port_cfg port_cfg[TOTAL_PORT_NUM];
+
+	u8 diffserv[DIFFSERV_ENTRIES];
+	u8 p_802_1p[PRIO_802_1P_ENTRIES];
+
+	u8 br_addr[MAC_ADDR_LEN];
+	u8 other_addr[MAC_ADDR_LEN];
+
+	u8 broad_per;
+	u8 member;
+};
+
+#define TX_RATE_UNIT			10000
+
+/**
+ * struct ksz_port_info - Port information data structure
+ * @state:	Connection status of the port.
+ * @tx_rate:	Transmit rate divided by 10000 to get Mbit.
+ * @duplex:	Duplex mode.
+ * @advertised:	Advertised auto-negotiation setting.  Used to determine link.
+ * @partner:	Auto-negotiation partner setting.  Used to determine link.
+ * @port_id:	Port index to access actual hardware register.
+ * @pdev:	Pointer to OS dependent network device.
+ */
+struct ksz_port_info {
+	uint state;
+	uint tx_rate;
+	u8 duplex;
+	u8 advertised;
+	u8 partner;
+	u8 port_id;
+	void *pdev;
+};
+
+#define MAX_TX_HELD_SIZE		52000
+
+/* Hardware features and bug fixes. */
+#define LINK_INT_WORKING		(1 << 0)
+#define SMALL_PACKET_TX_BUG		(1 << 1)
+#define HALF_DUPLEX_SIGNAL_BUG		(1 << 2)
+#define IPV6_CSUM_GEN_HACK		(1 << 3)
+#define RX_HUGE_FRAME			(1 << 4)
+#define STP_SUPPORT			(1 << 8)
+
+/* Software overrides. */
+#define PAUSE_FLOW_CTRL			(1 << 0)
+#define FAST_AGING			(1 << 1)
+
+/**
+ * struct ksz_hw - KSZ884X hardware data structure
+ * @io:			Virtual address assigned.
+ * @ksz_switch:		Pointer to KSZ8842 switch.
+ * @port_info:		Port information.
+ * @port_mib:		Port MIB information.
+ * @dev_count:		Number of network devices this hardware supports.
+ * @dst_ports:		Destination ports in switch for transmission.
+ * @id:			Hardware ID.  Used for display only.
+ * @mib_cnt:		Number of MIB counters this hardware has.
+ * @mib_port_cnt:	Number of ports with MIB counters.
+ * @tx_cfg:		Cached transmit control settings.
+ * @rx_cfg:		Cached receive control settings.
+ * @intr_mask:		Current interrupt mask.
+ * @intr_set:		Current interrup set.
+ * @intr_blocked:	Interrupt blocked.
+ * @rx_desc_info:	Receive descriptor information.
+ * @tx_desc_info:	Transmit descriptor information.
+ * @tx_int_cnt:		Transmit interrupt count.  Used for TX optimization.
+ * @tx_int_mask:	Transmit interrupt mask.  Used for TX optimization.
+ * @tx_size:		Transmit data size.  Used for TX optimization.
+ * 			The maximum is defined by MAX_TX_HELD_SIZE.
+ * @perm_addr:		Permanent MAC address.
+ * @override_addr:	Overrided MAC address.
+ * @address:		Additional MAC address entries.
+ * @addr_list_size:	Additional MAC address list size.
+ * @mac_override:	Indication of MAC address overrided.
+ * @promiscuous:	Counter to keep track of promiscuous mode set.
+ * @all_multi:		Counter to keep track of all multicast mode set.
+ * @multi_list:		Multicast address entries.
+ * @multi_bits:		Cached multicast hash table settings.
+ * @multi_list_size:	Multicast address list size.
+ * @enabled:		Indication of hardware enabled.
+ * @rx_stop:		Indication of receive process stop.
+ * @features:		Hardware features to enable.
+ * @overrides:		Hardware features to override.
+ * @parent:		Pointer to parent, network device private structure.
+ */
+struct ksz_hw {
+	void __iomem *io;
+
+	struct ksz_switch *ksz_switch;
+	struct ksz_port_info port_info[SWITCH_PORT_NUM];
+	struct ksz_port_mib port_mib[TOTAL_PORT_NUM];
+	int dev_count;
+	int dst_ports;
+	int id;
+	int mib_cnt;
+	int mib_port_cnt;
+
+	u32 tx_cfg;
+	u32 rx_cfg;
+	u32 intr_mask;
+	u32 intr_set;
+	uint intr_blocked;
+
+	struct ksz_desc_info rx_desc_info;
+	struct ksz_desc_info tx_desc_info;
+
+	int tx_int_cnt;
+	int tx_int_mask;
+	int tx_size;
+
+	u8 perm_addr[MAC_ADDR_LEN];
+	u8 override_addr[MAC_ADDR_LEN];
+	u8 address[ADDITIONAL_ENTRIES][MAC_ADDR_LEN];
+	u8 addr_list_size;
+	u8 mac_override;
+	u8 promiscuous;
+	u8 all_multi;
+	u8 multi_list[MAX_MULTICAST_LIST][MAC_ADDR_LEN];
+	u8 multi_bits[HW_MULTICAST_SIZE];
+	u8 multi_list_size;
+
+	u8 enabled;
+	u8 rx_stop;
+	u8 reserved2[1];
+
+	uint features;
+	uint overrides;
+
+	void *parent;
+};
+
+enum {
+	PHY_NO_FLOW_CTRL,
+	PHY_FLOW_CTRL,
+	PHY_TX_ONLY,
+	PHY_RX_ONLY
+};
+
+/**
+ * struct ksz_port - Virtual port data structure
+ * @duplex:		Duplex mode setting.  1 for half duplex, 2 for full
+ * 			duplex, and 0 for auto, which normally results in full
+ * 			duplex.
+ * @speed:		Speed setting.  10 for 10 Mbit, 100 for 100 Mbit, and
+ * 			0 for auto, which normally results in 100 Mbit.
+ * @force_link:		Force link setting.  0 for auto-negotiation, and 1 for
+ * 			force.
+ * @flow_ctrl:		Flow control setting.  PHY_NO_FLOW_CTRL for no flow
+ * 			control, and PHY_FLOW_CTRL for flow control.
+ * 			PHY_TX_ONLY and PHY_RX_ONLY are not supported for 100
+ * 			Mbit PHY.
+ * @first_port:		Index of first port this port supports.
+ * @mib_port_cnt:	Number of ports with MIB counters.
+ * @port_cnt:		Number of ports this port supports.
+ * @counter:		Port statistics counter.
+ * @hw:			Pointer to hardware structure.
+ * @linked:		Pointer to port information linked to this port.
+ */
+struct ksz_port {
+	u8 duplex;
+	u8 speed;
+	u8 force_link;
+	u8 flow_ctrl;
+
+	int first_port;
+	int mib_port_cnt;
+	int port_cnt;
+	u64 counter[OID_COUNTER_LAST];
+
+	struct ksz_hw *hw;
+	struct ksz_port_info *linked;
+};
+
+/**
+ * struct ksz_timer_info - Timer information data structure
+ * @timer:	Kernel timer.
+ * @cnt:	Running timer counter.
+ * @max:	Number of times to run timer; -1 for infinity.
+ * @period:	Timer period in jiffies.
+ */
+struct ksz_timer_info {
+	struct timer_list timer;
+	int cnt;
+	int max;
+	int period;
+};
+
+/**
+ * struct ksz_shared_mem - OS dependent shared memory data structure
+ * @dma_addr:	Physical DMA address allocated.
+ * @alloc_size:	Allocation size.
+ * @phys:	Actual physical address used.
+ * @alloc_virt:	Virtual address allocated.
+ * @virt:	Actual virtual address used.
+ */
+struct ksz_shared_mem {
+	dma_addr_t dma_addr;
+	uint alloc_size;
+	uint phys;
+	u8 *alloc_virt;
+	u8 *virt;
+};
+
+/**
+ * struct ksz_counter_info - OS dependent counter information data structure
+ * @counter:	Wait queue to wakeup after counters are read.
+ * @time:	Next time in jiffies to read counter.
+ * @read:	Indication of counters read in full or not.
+ */
+struct ksz_counter_info {
+	wait_queue_head_t counter;
+	unsigned long time;
+	int read;
+};
+
+/**
+ * struct dev_info - Network device information data structure
+ * @dev:		Pointer to network device.
+ * @pdev:		Pointer to PCI device.
+ * @hw:			Hardware structure.
+ * @desc_pool:		Physical memory used for descriptor pool.
+ * @hwlock:		Spinlock to prevent hardware from accessing.
+ * @lock:		Mutex lock to prevent device from accessing.
+ * @dev_rcv:		Receive process function used.
+ * @last_skb:		Socket buffer allocated for descriptor rx fragments.
+ * @skb_index:		Buffer index for receiving fragments.
+ * @skb_len:		Buffer length for receiving fragments.
+ * @mib_read:		Workqueue to read MIB counters.
+ * @mib_timer_info:	Timer to read MIB counters.
+ * @counter:		Used for MIB reading.
+ * @mtu:		Current MTU used.  The default is REGULAR_RX_BUF_SIZE;
+ * 			the maximum is MAX_RX_BUF_SIZE.
+ * @opened:		Counter to keep track of device open.
+ * @rx_tasklet:		Receive processing tasklet.
+ * @tx_tasklet:		Transmit processing tasklet.
+ * @wol_enable:		Wake-on-LAN enable set by ethtool.
+ * @wol_support:	Wake-on-LAN support used by ethtool.
+ * @pme_wait:		Used for KSZ8841 power management.
+ */
+struct dev_info {
+	struct net_device *dev;
+	struct pci_dev *pdev;
+
+	struct ksz_hw hw;
+	struct ksz_shared_mem desc_pool;
+
+	spinlock_t hwlock;
+	struct mutex lock;
+
+	int (*dev_rcv)(struct dev_info *);
+
+	struct sk_buff *last_skb;
+	int skb_index;
+	int skb_len;
+
+	struct work_struct mib_read;
+	struct ksz_timer_info mib_timer_info;
+	struct ksz_counter_info counter[TOTAL_PORT_NUM];
+
+	int mtu;
+	int opened;
+
+	struct tasklet_struct rx_tasklet;
+	struct tasklet_struct tx_tasklet;
+
+	int wol_enable;
+	int wol_support;
+	unsigned long pme_wait;
+};
+
+/**
+ * struct dev_priv - Network device private data structure
+ * @adapter:		Adapter device information.
+ * @port:		Port information.
+ * @monitor_time_info:	Timer to monitor ports.
+ * @stats:		Network statistics.
+ * @proc_sem:		Semaphore for proc accessing.
+ * @id:			Device ID.
+ * @mii_if:		MII interface information.
+ * @advertising:	Temporary variable to store advertised settings.
+ * @msg_enable:		The message flags controlling driver output.
+ * @media_state:	The connection status of the device.
+ * @multicast:		The all multicast state of the device.
+ * @promiscuous:	The promiscuous state of the device.
+ */
+struct dev_priv {
+	struct dev_info *adapter;
+	struct ksz_port port;
+	struct ksz_timer_info monitor_timer_info;
+	struct net_device_stats stats;
+
+	struct semaphore proc_sem;
+	int id;
+
+	struct mii_if_info mii_if;
+	u32 advertising;
+
+	u32 msg_enable;
+	int media_state;
+	int multicast;
+	int promiscuous;
+};
+
+#define ks_info(_ks, _msg...) dev_info(&(_ks)->pdev->dev, _msg)
+#define ks_warn(_ks, _msg...) dev_warn(&(_ks)->pdev->dev, _msg)
+#define ks_dbg(_ks, _msg...) dev_dbg(&(_ks)->pdev->dev, _msg)
+#define ks_err(_ks, _msg...) dev_err(&(_ks)->pdev->dev, _msg)
+
+#define DRV_NAME		"KSZ884X PCI"
+#define DEVICE_NAME		"KSZ884x PCI"
+#define DRV_VERSION		"1.0.0"
+#define DRV_RELDATE		"Feb 8, 2010"
+
+static char version[] __devinitdata =
+	"Micrel " DEVICE_NAME " " DRV_VERSION " (" DRV_RELDATE ")";
+
+static u8 DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x88, 0x42, 0x01 };
+
+/*
+ * Interrupt processing primary routines
+ */
+
+static inline void hw_ack_intr(struct ksz_hw *hw, uint interrupt)
+{
+	writel(interrupt, hw->io + KS884X_INTERRUPTS_STATUS);
+}
+
+static inline void hw_dis_intr(struct ksz_hw *hw)
+{
+	hw->intr_blocked = hw->intr_mask;
+	writel(0, hw->io + KS884X_INTERRUPTS_ENABLE);
+	hw->intr_set = readl(hw->io + KS884X_INTERRUPTS_ENABLE);
+}
+
+static inline void hw_set_intr(struct ksz_hw *hw, uint interrupt)
+{
+	hw->intr_set = interrupt;
+	writel(interrupt, hw->io + KS884X_INTERRUPTS_ENABLE);
+}
+
+static inline void hw_ena_intr(struct ksz_hw *hw)
+{
+	hw->intr_blocked = 0;
+	hw_set_intr(hw, hw->intr_mask);
+}
+
+static inline void hw_dis_intr_bit(struct ksz_hw *hw, uint bit)
+{
+	hw->intr_mask &= ~(bit);
+}
+
+static inline void hw_turn_off_intr(struct ksz_hw *hw, uint interrupt)
+{
+	u32 read_intr;
+
+	read_intr = readl(hw->io + KS884X_INTERRUPTS_ENABLE);
+	hw->intr_set = read_intr & ~interrupt;
+	writel(hw->intr_set, hw->io + KS884X_INTERRUPTS_ENABLE);
+	hw_dis_intr_bit(hw, interrupt);
+}
+
+/**
+ * hw_turn_on_intr - turn on specified interrupts
+ * @hw: 	The hardware instance.
+ * @bit:	The interrupt bits to be on.
+ *
+ * This routine turns on the specified interrupts in the interrupt mask so that
+ * those interrupts will be enabled.
+ */
+static void hw_turn_on_intr(struct ksz_hw *hw, u32 bit)
+{
+	hw->intr_mask |= bit;
+
+	if (!hw->intr_blocked)
+		hw_set_intr(hw, hw->intr_mask);
+}
+
+static inline void hw_ena_intr_bit(struct ksz_hw *hw, uint interrupt)
+{
+	u32 read_intr;
+
+	read_intr = readl(hw->io + KS884X_INTERRUPTS_ENABLE);
+	hw->intr_set = read_intr | interrupt;
+	writel(hw->intr_set, hw->io + KS884X_INTERRUPTS_ENABLE);
+}
+
+static inline void hw_read_intr(struct ksz_hw *hw, uint *status)
+{
+	*status = readl(hw->io + KS884X_INTERRUPTS_STATUS);
+	*status = *status & hw->intr_set;
+}
+
+static inline void hw_restore_intr(struct ksz_hw *hw, uint interrupt)
+{
+	if (interrupt)
+		hw_ena_intr(hw);
+}
+
+/**
+ * hw_block_intr - block hardware interrupts
+ *
+ * This function blocks all interrupts of the hardware and returns the current
+ * interrupt enable mask so that interrupts can be restored later.
+ *
+ * Return the current interrupt enable mask.
+ */
+static uint hw_block_intr(struct ksz_hw *hw)
+{
+	uint interrupt = 0;
+
+	if (!hw->intr_blocked) {
+		hw_dis_intr(hw);
+		interrupt = hw->intr_blocked;
+	}
+	return interrupt;
+}
+
+/*
+ * Hardware descriptor routines
+ */
+
+static inline void reset_desc(struct ksz_desc *desc, union desc_stat status)
+{
+	status.rx.hw_owned = 0;
+	desc->phw->ctrl.data = cpu_to_le32(status.data);
+}
+
+static inline void release_desc(struct ksz_desc *desc)
+{
+	desc->sw.ctrl.tx.hw_owned = 1;
+	if (desc->sw.buf_size != desc->sw.buf.data) {
+		desc->sw.buf_size = desc->sw.buf.data;
+		desc->phw->buf.data = cpu_to_le32(desc->sw.buf.data);
+	}
+	desc->phw->ctrl.data = cpu_to_le32(desc->sw.ctrl.data);
+}
+
+static void get_rx_pkt(struct ksz_desc_info *info, struct ksz_desc **desc)
+{
+	*desc = &info->ring[info->last];
+	info->last++;
+	info->last &= info->mask;
+	info->avail--;
+	(*desc)->sw.buf.data &= ~KS_DESC_RX_MASK;
+}
+
+static inline void set_rx_buf(struct ksz_desc *desc, u32 addr)
+{
+	desc->phw->addr = cpu_to_le32(addr);
+}
+
+static inline void set_rx_len(struct ksz_desc *desc, u32 len)
+{
+	desc->sw.buf.rx.buf_size = len;
+}
+
+static inline void get_tx_pkt(struct ksz_desc_info *info,
+	struct ksz_desc **desc)
+{
+	*desc = &info->ring[info->next];
+	info->next++;
+	info->next &= info->mask;
+	info->avail--;
+	(*desc)->sw.buf.data &= ~KS_DESC_TX_MASK;
+}
+
+static inline void set_tx_buf(struct ksz_desc *desc, u32 addr)
+{
+	desc->phw->addr = cpu_to_le32(addr);
+}
+
+static inline void set_tx_len(struct ksz_desc *desc, u32 len)
+{
+	desc->sw.buf.tx.buf_size = len;
+}
+
+/* Switch functions */
+
+#define TABLE_READ			0x10
+#define TABLE_SEL_SHIFT			2
+
+#define HW_DELAY(hw, reg)			\
+	do {					\
+		u16 dummy;			\
+		dummy = readw(hw->io + reg);	\
+	} while (0)
+
+/**
+ * sw_r_table - read 4 bytes of data from switch table
+ * @hw:		The hardware instance.
+ * @table:	The table selector.
+ * @addr:	The address of the table entry.
+ * @data:	Buffer to store the read data.
+ *
+ * This routine reads 4 bytes of data from the table of the switch.
+ * Hardware interrupts are disabled to minimize corruption of read data.
+ */
+static void sw_r_table(struct ksz_hw *hw, int table, u16 addr, u32 *data)
+{
+	u16 ctrl_addr;
+	uint interrupt;
+
+	ctrl_addr = (((table << TABLE_SEL_SHIFT) | TABLE_READ) << 8) | addr;
+
+	interrupt = hw_block_intr(hw);
+
+	writew(ctrl_addr, hw->io + KS884X_IACR_OFFSET);
+	HW_DELAY(hw, KS884X_IACR_OFFSET);
+	*data = readl(hw->io + KS884X_ACC_DATA_0_OFFSET);
+
+	hw_restore_intr(hw, interrupt);
+}
+
+/**
+ * sw_w_table_64 - write 8 bytes of data to the switch table
+ * @hw:		The hardware instance.
+ * @table:	The table selector.
+ * @addr:	The address of the table entry.
+ * @data_hi:	The high part of data to be written (bit63 ~ bit32).
+ * @data_lo:	The low part of data to be written (bit31 ~ bit0).
+ *
+ * This routine writes 8 bytes of data to the table of the switch.
+ * Hardware interrupts are disabled to minimize corruption of written data.
+ */
+static void sw_w_table_64(struct ksz_hw *hw, int table, u16 addr, u32 data_hi,
+	u32 data_lo)
+{
+	u16 ctrl_addr;
+	uint interrupt;
+
+	ctrl_addr = ((table << TABLE_SEL_SHIFT) << 8) | addr;
+
+	interrupt = hw_block_intr(hw);
+
+	writel(data_hi, hw->io + KS884X_ACC_DATA_4_OFFSET);
+	writel(data_lo, hw->io + KS884X_ACC_DATA_0_OFFSET);
+
+	writew(ctrl_addr, hw->io + KS884X_IACR_OFFSET);
+	HW_DELAY(hw, KS884X_IACR_OFFSET);
+
+	hw_restore_intr(hw, interrupt);
+}
+
+/**
+ * sw_w_sta_mac_table - write to the static MAC table
+ * @hw: 	The hardware instance.
+ * @addr:	The address of the table entry.
+ * @mac_addr:	The MAC address.
+ * @ports:	The port members.
+ * @override:	The flag to override the port receive/transmit settings.
+ * @valid:	The flag to indicate entry is valid.
+ * @use_fid:	The flag to indicate the FID is valid.
+ * @fid:	The FID value.
+ *
+ * This routine writes an entry of the static MAC table of the switch.  It
+ * calls sw_w_table_64() to write the data.
+ */
+static void sw_w_sta_mac_table(struct ksz_hw *hw, u16 addr, u8 *mac_addr,
+	u8 ports, int override, int valid, int use_fid, u8 fid)
+{
+	u32 data_hi;
+	u32 data_lo;
+
+	data_lo = ((u32) mac_addr[2] << 24) |
+		((u32) mac_addr[3] << 16) |
+		((u32) mac_addr[4] << 8) | mac_addr[5];
+	data_hi = ((u32) mac_addr[0] << 8) | mac_addr[1];
+	data_hi |= (u32) ports << STATIC_MAC_FWD_PORTS_SHIFT;
+
+	if (override)
+		data_hi |= STATIC_MAC_TABLE_OVERRIDE;
+	if (use_fid) {
+		data_hi |= STATIC_MAC_TABLE_USE_FID;
+		data_hi |= (u32) fid << STATIC_MAC_FID_SHIFT;
+	}
+	if (valid)
+		data_hi |= STATIC_MAC_TABLE_VALID;
+
+	sw_w_table_64(hw, TABLE_STATIC_MAC, addr, data_hi, data_lo);
+}
+
+/**
+ * sw_r_vlan_table - read from the VLAN table
+ * @hw: 	The hardware instance.
+ * @addr:	The address of the table entry.
+ * @vid:	Buffer to store the VID.
+ * @fid:	Buffer to store the VID.
+ * @member:	Buffer to store the port membership.
+ *
+ * This function reads an entry of the VLAN table of the switch.  It calls
+ * sw_r_table() to get the data.
+ *
+ * Return 0 if the entry is valid; otherwise -1.
+ */
+static int sw_r_vlan_table(struct ksz_hw *hw, u16 addr, u16 *vid, u8 *fid,
+	u8 *member)
+{
+	u32 data;
+
+	sw_r_table(hw, TABLE_VLAN, addr, &data);
+	if (data & VLAN_TABLE_VALID) {
+		*vid = (u16)(data & VLAN_TABLE_VID);
+		*fid = (u8)((data & VLAN_TABLE_FID) >> VLAN_TABLE_FID_SHIFT);
+		*member = (u8)((data & VLAN_TABLE_MEMBERSHIP) >>
+			VLAN_TABLE_MEMBERSHIP_SHIFT);
+		return 0;
+	}
+	return -1;
+}
+
+/**
+ * port_r_mib_cnt - read MIB counter
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ * @addr:	The address of the counter.
+ * @cnt:	Buffer to store the counter.
+ *
+ * This routine reads a MIB counter of the port.
+ * Hardware interrupts are disabled to minimize corruption of read data.
+ */
+static void port_r_mib_cnt(struct ksz_hw *hw, int port, u16 addr, u64 *cnt)
+{
+	u32 data;
+	u16 ctrl_addr;
+	uint interrupt;
+	int timeout;
+
+	ctrl_addr = addr + PORT_COUNTER_NUM * port;
+
+	interrupt = hw_block_intr(hw);
+
+	ctrl_addr |= (((TABLE_MIB << TABLE_SEL_SHIFT) | TABLE_READ) << 8);
+	writew(ctrl_addr, hw->io + KS884X_IACR_OFFSET);
+	HW_DELAY(hw, KS884X_IACR_OFFSET);
+
+	for (timeout = 100; timeout > 0; timeout--) {
+		data = readl(hw->io + KS884X_ACC_DATA_0_OFFSET);
+
+		if (data & MIB_COUNTER_VALID) {
+			if (data & MIB_COUNTER_OVERFLOW)
+				*cnt += MIB_COUNTER_VALUE + 1;
+			*cnt += data & MIB_COUNTER_VALUE;
+			break;
+		}
+	}
+
+	hw_restore_intr(hw, interrupt);
+}
+
+/**
+ * port_r_mib_pkt - read dropped packet counts
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ * @cnt:	Buffer to store the receive and transmit dropped packet counts.
+ *
+ * This routine reads the dropped packet counts of the port.
+ * Hardware interrupts are disabled to minimize corruption of read data.
+ */
+static void port_r_mib_pkt(struct ksz_hw *hw, int port, u32 *last, u64 *cnt)
+{
+	u32 cur;
+	u32 data;
+	u16 ctrl_addr;
+	uint interrupt;
+	int index;
+
+	index = KS_MIB_PACKET_DROPPED_RX_0 + port;
+	do {
+		interrupt = hw_block_intr(hw);
+
+		ctrl_addr = (u16) index;
+		ctrl_addr |= (((TABLE_MIB << TABLE_SEL_SHIFT) | TABLE_READ)
+			<< 8);
+		writew(ctrl_addr, hw->io + KS884X_IACR_OFFSET);
+		HW_DELAY(hw, KS884X_IACR_OFFSET);
+		data = readl(hw->io + KS884X_ACC_DATA_0_OFFSET);
+
+		hw_restore_intr(hw, interrupt);
+
+		data &= MIB_PACKET_DROPPED;
+		cur = *last;
+		if (data != cur) {
+			*last = data;
+			if (data < cur)
+				data += MIB_PACKET_DROPPED + 1;
+			data -= cur;
+			*cnt += data;
+		}
+		++last;
+		++cnt;
+		index -= KS_MIB_PACKET_DROPPED_TX -
+			KS_MIB_PACKET_DROPPED_TX_0 + 1;
+	} while (index >= KS_MIB_PACKET_DROPPED_TX_0 + port);
+}
+
+/**
+ * port_r_cnt - read MIB counters periodically
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ *
+ * This routine is used to read the counters of the port periodically to avoid
+ * counter overflow.  The hardware should be acquired first before calling this
+ * routine.
+ *
+ * Return non-zero when not all counters not read.
+ */
+static int port_r_cnt(struct ksz_hw *hw, int port)
+{
+	struct ksz_port_mib *mib = &hw->port_mib[port];
+
+	if (mib->mib_start < PORT_COUNTER_NUM)
+		while (mib->cnt_ptr < PORT_COUNTER_NUM) {
+			port_r_mib_cnt(hw, port, mib->cnt_ptr,
+				&mib->counter[mib->cnt_ptr]);
+			++mib->cnt_ptr;
+		}
+	if (hw->mib_cnt > PORT_COUNTER_NUM)
+		port_r_mib_pkt(hw, port, mib->dropped,
+			&mib->counter[PORT_COUNTER_NUM]);
+	mib->cnt_ptr = 0;
+	return 0;
+}
+
+/**
+ * port_init_cnt - initialize MIB counter values
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ *
+ * This routine is used to initialize all counters to zero if the hardware
+ * cannot do it after reset.
+ */
+static void port_init_cnt(struct ksz_hw *hw, int port)
+{
+	struct ksz_port_mib *mib = &hw->port_mib[port];
+
+	mib->cnt_ptr = 0;
+	if (mib->mib_start < PORT_COUNTER_NUM)
+		do {
+			port_r_mib_cnt(hw, port, mib->cnt_ptr,
+				&mib->counter[mib->cnt_ptr]);
+			++mib->cnt_ptr;
+		} while (mib->cnt_ptr < PORT_COUNTER_NUM);
+	if (hw->mib_cnt > PORT_COUNTER_NUM)
+		port_r_mib_pkt(hw, port, mib->dropped,
+			&mib->counter[PORT_COUNTER_NUM]);
+	memset((void *) mib->counter, 0, sizeof(u64) * TOTAL_PORT_COUNTER_NUM);
+	mib->cnt_ptr = 0;
+}
+
+/*
+ * Port functions
+ */
+
+/**
+ * port_chk - check port register bits
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ * @offset:	The offset of the port register.
+ * @bits:	The data bits to check.
+ *
+ * This function checks whether the specified bits of the port register are set
+ * or not.
+ *
+ * Return 0 if the bits are not set.
+ */
+static int port_chk(struct ksz_hw *hw, int port, int offset, u16 bits)
+{
+	u32 addr;
+	u16 data;
+
+	PORT_CTRL_ADDR(port, addr);
+	addr += offset;
+	data = readw(hw->io + addr);
+	return (data & bits) == bits;
+}
+
+/**
+ * port_cfg - set port register bits
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ * @offset:	The offset of the port register.
+ * @bits:	The data bits to set.
+ * @set:	The flag indicating whether the bits are to be set or not.
+ *
+ * This routine sets or resets the specified bits of the port register.
+ */
+static void port_cfg(struct ksz_hw *hw, int port, int offset, u16 bits,
+	int set)
+{
+	u32 addr;
+	u16 data;
+
+	PORT_CTRL_ADDR(port, addr);
+	addr += offset;
+	data = readw(hw->io + addr);
+	if (set)
+		data |= bits;
+	else
+		data &= ~bits;
+	writew(data, hw->io + addr);
+}
+
+/**
+ * port_chk_shift - check port bit
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ * @offset:	The offset of the register.
+ * @shift:	Number of bits to shift.
+ *
+ * This function checks whether the specified port is set in the register or
+ * not.
+ *
+ * Return 0 if the port is not set.
+ */
+static int port_chk_shift(struct ksz_hw *hw, int port, u32 addr, int shift)
+{
+	u16 data;
+	u16 bit = 1 << port;
+
+	data = readw(hw->io + addr);
+	data >>= shift;
+	return (data & bit) == bit;
+}
+
+/**
+ * port_cfg_shift - set port bit
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ * @offset:	The offset of the register.
+ * @shift:	Number of bits to shift.
+ * @set:	The flag indicating whether the port is to be set or not.
+ *
+ * This routine sets or resets the specified port in the register.
+ */
+static void port_cfg_shift(struct ksz_hw *hw, int port, u32 addr, int shift,
+	int set)
+{
+	u16 data;
+	u16 bits = 1 << port;
+
+	data = readw(hw->io + addr);
+	bits <<= shift;
+	if (set)
+		data |= bits;
+	else
+		data &= ~bits;
+	writew(data, hw->io + addr);
+}
+
+/**
+ * port_r8 - read byte from port register
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ * @offset:	The offset of the port register.
+ * @data:	Buffer to store the data.
+ *
+ * This routine reads a byte from the port register.
+ */
+static void port_r8(struct ksz_hw *hw, int port, int offset, u8 *data)
+{
+	u32 addr;
+
+	PORT_CTRL_ADDR(port, addr);
+	addr += offset;
+	*data = readb(hw->io + addr);
+}
+
+/**
+ * port_r16 - read word from port register.
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ * @offset:	The offset of the port register.
+ * @data:	Buffer to store the data.
+ *
+ * This routine reads a word from the port register.
+ */
+static void port_r16(struct ksz_hw *hw, int port, int offset, u16 *data)
+{
+	u32 addr;
+
+	PORT_CTRL_ADDR(port, addr);
+	addr += offset;
+	*data = readw(hw->io + addr);
+}
+
+/**
+ * port_w16 - write word to port register.
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ * @offset:	The offset of the port register.
+ * @data:	Data to write.
+ *
+ * This routine writes a word to the port register.
+ */
+static void port_w16(struct ksz_hw *hw, int port, int offset, u16 data)
+{
+	u32 addr;
+
+	PORT_CTRL_ADDR(port, addr);
+	addr += offset;
+	writew(data, hw->io + addr);
+}
+
+/**
+ * sw_chk - check switch register bits
+ * @hw: 	The hardware instance.
+ * @addr:	The address of the switch register.
+ * @bits:	The data bits to check.
+ *
+ * This function checks whether the specified bits of the switch register are
+ * set or not.
+ *
+ * Return 0 if the bits are not set.
+ */
+static int sw_chk(struct ksz_hw *hw, u32 addr, u16 bits)
+{
+	u16 data;
+
+	data = readw(hw->io + addr);
+	return (data & bits) == bits;
+}
+
+/**
+ * sw_cfg - set switch register bits
+ * @hw: 	The hardware instance.
+ * @addr:	The address of the switch register.
+ * @bits:	The data bits to set.
+ * @set:	The flag indicating whether the bits are to be set or not.
+ *
+ * This function sets or resets the specified bits of the switch register.
+ */
+static void sw_cfg(struct ksz_hw *hw, u32 addr, u16 bits, int set)
+{
+	u16 data;
+
+	data = readw(hw->io + addr);
+	if (set)
+		data |= bits;
+	else
+		data &= ~bits;
+	writew(data, hw->io + addr);
+}
+
+/* Bandwidth */
+
+static inline void port_cfg_broad_storm(struct ksz_hw *hw, int p, int set)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_1_OFFSET, PORT_BROADCAST_STORM, set);
+}
+
+static inline int port_chk_broad_storm(struct ksz_hw *hw, int p)
+{
+	return port_chk(hw, p,
+		KS8842_PORT_CTRL_1_OFFSET, PORT_BROADCAST_STORM);
+}
+
+/* Driver set switch broadcast storm protection at 10% rate. */
+#define BROADCAST_STORM_PROTECTION_RATE	10
+
+/* 148,800 frames * 67 ms / 100 */
+#define BROADCAST_STORM_VALUE		9969
+
+/**
+ * sw_cfg_broad_storm - configure broadcast storm threshold
+ * @hw: 	The hardware instance.
+ * @percent:	Broadcast storm threshold in percent of transmit rate.
+ *
+ * This routine configures the broadcast storm threshold of the switch.
+ */
+static void sw_cfg_broad_storm(struct ksz_hw *hw, u8 percent)
+{
+	u16 data;
+	u32 value = ((u32) BROADCAST_STORM_VALUE * (u32) percent / 100);
+
+	if (value > BROADCAST_STORM_RATE)
+		value = BROADCAST_STORM_RATE;
+
+	data = readw(hw->io + KS8842_SWITCH_CTRL_3_OFFSET);
+	data &= ~(BROADCAST_STORM_RATE_LO | BROADCAST_STORM_RATE_HI);
+	data |= ((value & 0x00FF) << 8) | ((value & 0xFF00) >> 8);
+	writew(data, hw->io + KS8842_SWITCH_CTRL_3_OFFSET);
+}
+
+/**
+ * sw_get_board_storm - get broadcast storm threshold
+ * @hw: 	The hardware instance.
+ * @percent:	Buffer to store the broadcast storm threshold percentage.
+ *
+ * This routine retrieves the broadcast storm threshold of the switch.
+ */
+static void sw_get_broad_storm(struct ksz_hw *hw, u8 *percent)
+{
+	int num;
+	u16 data;
+
+	data = readw(hw->io + KS8842_SWITCH_CTRL_3_OFFSET);
+	num = (data & BROADCAST_STORM_RATE_HI);
+	num <<= 8;
+	num |= (data & BROADCAST_STORM_RATE_LO) >> 8;
+	num = (num * 100 + BROADCAST_STORM_VALUE / 2) / BROADCAST_STORM_VALUE;
+	*percent = (u8) num;
+}
+
+/**
+ * sw_dis_broad_storm - disable broadstorm
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ *
+ * This routine disables the broadcast storm limit function of the switch.
+ */
+static void sw_dis_broad_storm(struct ksz_hw *hw, int port)
+{
+	port_cfg_broad_storm(hw, port, 0);
+}
+
+/**
+ * sw_ena_broad_storm - enable broadcast storm
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ *
+ * This routine enables the broadcast storm limit function of the switch.
+ */
+static void sw_ena_broad_storm(struct ksz_hw *hw, int port)
+{
+	sw_cfg_broad_storm(hw, hw->ksz_switch->broad_per);
+	port_cfg_broad_storm(hw, port, 1);
+}
+
+/**
+ * sw_init_broad_storm - initialize broadcast storm
+ * @hw: 	The hardware instance.
+ *
+ * This routine initializes the broadcast storm limit function of the switch.
+ */
+static void sw_init_broad_storm(struct ksz_hw *hw)
+{
+	int port;
+
+	hw->ksz_switch->broad_per = 1;
+	sw_cfg_broad_storm(hw, hw->ksz_switch->broad_per);
+	for (port = 0; port < TOTAL_PORT_NUM; port++)
+		sw_dis_broad_storm(hw, port);
+	sw_cfg(hw, KS8842_SWITCH_CTRL_2_OFFSET, MULTICAST_STORM_DISABLE, 1);
+}
+
+/**
+ * hw_cfg_broad_storm - configure broadcast storm
+ * @hw: 	The hardware instance.
+ * @percent:	Broadcast storm threshold in percent of transmit rate.
+ *
+ * This routine configures the broadcast storm threshold of the switch.
+ * It is called by user functions.  The hardware should be acquired first.
+ */
+static void hw_cfg_broad_storm(struct ksz_hw *hw, u8 percent)
+{
+	if (percent > 100)
+		percent = 100;
+
+	sw_cfg_broad_storm(hw, percent);
+	sw_get_broad_storm(hw, &percent);
+	hw->ksz_switch->broad_per = percent;
+}
+
+/**
+ * sw_dis_prio_rate - disable switch priority rate
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ *
+ * This routine disables the priority rate function of the switch.
+ */
+static void sw_dis_prio_rate(struct ksz_hw *hw, int port)
+{
+	u32 addr;
+
+	PORT_CTRL_ADDR(port, addr);
+	addr += KS8842_PORT_IN_RATE_OFFSET;
+	writel(0, hw->io + addr);
+}
+
+/**
+ * sw_init_prio_rate - initialize switch prioirty rate
+ * @hw: 	The hardware instance.
+ *
+ * This routine initializes the priority rate function of the switch.
+ */
+static void sw_init_prio_rate(struct ksz_hw *hw)
+{
+	int port;
+	int prio;
+	struct ksz_switch *sw = hw->ksz_switch;
+
+	for (port = 0; port < TOTAL_PORT_NUM; port++) {
+		for (prio = 0; prio < PRIO_QUEUES; prio++) {
+			sw->port_cfg[port].rx_rate[prio] =
+			sw->port_cfg[port].tx_rate[prio] = 0;
+		}
+		sw_dis_prio_rate(hw, port);
+	}
+}
+
+/* Communication */
+
+static inline void port_cfg_back_pressure(struct ksz_hw *hw, int p, int set)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_BACK_PRESSURE, set);
+}
+
+static inline void port_cfg_force_flow_ctrl(struct ksz_hw *hw, int p, int set)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_FORCE_FLOW_CTRL, set);
+}
+
+static inline int port_chk_back_pressure(struct ksz_hw *hw, int p)
+{
+	return port_chk(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_BACK_PRESSURE);
+}
+
+static inline int port_chk_force_flow_ctrl(struct ksz_hw *hw, int p)
+{
+	return port_chk(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_FORCE_FLOW_CTRL);
+}
+
+/* Spanning Tree */
+
+static inline void port_cfg_dis_learn(struct ksz_hw *hw, int p, int set)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_LEARN_DISABLE, set);
+}
+
+static inline void port_cfg_rx(struct ksz_hw *hw, int p, int set)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_RX_ENABLE, set);
+}
+
+static inline void port_cfg_tx(struct ksz_hw *hw, int p, int set)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_TX_ENABLE, set);
+}
+
+static inline void sw_cfg_fast_aging(struct ksz_hw *hw, int set)
+{
+	sw_cfg(hw, KS8842_SWITCH_CTRL_1_OFFSET, SWITCH_FAST_AGING, set);
+}
+
+static inline void sw_flush_dyn_mac_table(struct ksz_hw *hw)
+{
+	if (!(hw->overrides & FAST_AGING)) {
+		sw_cfg_fast_aging(hw, 1);
+		mdelay(1);
+		sw_cfg_fast_aging(hw, 0);
+	}
+}
+
+/* VLAN */
+
+static inline void port_cfg_ins_tag(struct ksz_hw *hw, int p, int insert)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_1_OFFSET, PORT_INSERT_TAG, insert);
+}
+
+static inline void port_cfg_rmv_tag(struct ksz_hw *hw, int p, int remove)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_1_OFFSET, PORT_REMOVE_TAG, remove);
+}
+
+static inline int port_chk_ins_tag(struct ksz_hw *hw, int p)
+{
+	return port_chk(hw, p,
+		KS8842_PORT_CTRL_1_OFFSET, PORT_INSERT_TAG);
+}
+
+static inline int port_chk_rmv_tag(struct ksz_hw *hw, int p)
+{
+	return port_chk(hw, p,
+		KS8842_PORT_CTRL_1_OFFSET, PORT_REMOVE_TAG);
+}
+
+static inline void port_cfg_dis_non_vid(struct ksz_hw *hw, int p, int set)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_DISCARD_NON_VID, set);
+}
+
+static inline void port_cfg_in_filter(struct ksz_hw *hw, int p, int set)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_INGRESS_VLAN_FILTER, set);
+}
+
+static inline int port_chk_dis_non_vid(struct ksz_hw *hw, int p)
+{
+	return port_chk(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_DISCARD_NON_VID);
+}
+
+static inline int port_chk_in_filter(struct ksz_hw *hw, int p)
+{
+	return port_chk(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_INGRESS_VLAN_FILTER);
+}
+
+/* Mirroring */
+
+static inline void port_cfg_mirror_sniffer(struct ksz_hw *hw, int p, int set)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_MIRROR_SNIFFER, set);
+}
+
+static inline void port_cfg_mirror_rx(struct ksz_hw *hw, int p, int set)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_MIRROR_RX, set);
+}
+
+static inline void port_cfg_mirror_tx(struct ksz_hw *hw, int p, int set)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_MIRROR_TX, set);
+}
+
+static inline void sw_cfg_mirror_rx_tx(struct ksz_hw *hw, int set)
+{
+	sw_cfg(hw, KS8842_SWITCH_CTRL_2_OFFSET, SWITCH_MIRROR_RX_TX, set);
+}
+
+static void sw_init_mirror(struct ksz_hw *hw)
+{
+	int port;
+
+	for (port = 0; port < TOTAL_PORT_NUM; port++) {
+		port_cfg_mirror_sniffer(hw, port, 0);
+		port_cfg_mirror_rx(hw, port, 0);
+		port_cfg_mirror_tx(hw, port, 0);
+	}
+	sw_cfg_mirror_rx_tx(hw, 0);
+}
+
+static inline void sw_cfg_unk_def_deliver(struct ksz_hw *hw, int set)
+{
+	sw_cfg(hw, KS8842_SWITCH_CTRL_7_OFFSET,
+		SWITCH_UNK_DEF_PORT_ENABLE, set);
+}
+
+static inline int sw_cfg_chk_unk_def_deliver(struct ksz_hw *hw)
+{
+	return sw_chk(hw, KS8842_SWITCH_CTRL_7_OFFSET,
+		SWITCH_UNK_DEF_PORT_ENABLE);
+}
+
+static inline void sw_cfg_unk_def_port(struct ksz_hw *hw, int port, int set)
+{
+	port_cfg_shift(hw, port, KS8842_SWITCH_CTRL_7_OFFSET, 0, set);
+}
+
+static inline int sw_chk_unk_def_port(struct ksz_hw *hw, int port)
+{
+	return port_chk_shift(hw, port, KS8842_SWITCH_CTRL_7_OFFSET, 0);
+}
+
+/* Priority */
+
+static inline void port_cfg_diffserv(struct ksz_hw *hw, int p, int set)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_1_OFFSET, PORT_DIFFSERV_ENABLE, set);
+}
+
+static inline void port_cfg_802_1p(struct ksz_hw *hw, int p, int set)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_1_OFFSET, PORT_802_1P_ENABLE, set);
+}
+
+static inline void port_cfg_replace_vid(struct ksz_hw *hw, int p, int set)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_USER_PRIORITY_CEILING, set);
+}
+
+static inline void port_cfg_prio(struct ksz_hw *hw, int p, int set)
+{
+	port_cfg(hw, p,
+		KS8842_PORT_CTRL_1_OFFSET, PORT_PRIO_QUEUE_ENABLE, set);
+}
+
+static inline int port_chk_diffserv(struct ksz_hw *hw, int p)
+{
+	return port_chk(hw, p,
+		KS8842_PORT_CTRL_1_OFFSET, PORT_DIFFSERV_ENABLE);
+}
+
+static inline int port_chk_802_1p(struct ksz_hw *hw, int p)
+{
+	return port_chk(hw, p,
+		KS8842_PORT_CTRL_1_OFFSET, PORT_802_1P_ENABLE);
+}
+
+static inline int port_chk_replace_vid(struct ksz_hw *hw, int p)
+{
+	return port_chk(hw, p,
+		KS8842_PORT_CTRL_2_OFFSET, PORT_USER_PRIORITY_CEILING);
+}
+
+static inline int port_chk_prio(struct ksz_hw *hw, int p)
+{
+	return port_chk(hw, p,
+		KS8842_PORT_CTRL_1_OFFSET, PORT_PRIO_QUEUE_ENABLE);
+}
+
+/**
+ * sw_dis_diffserv - disable switch DiffServ priority
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ *
+ * This routine disables the DiffServ priority function of the switch.
+ */
+static void sw_dis_diffserv(struct ksz_hw *hw, int port)
+{
+	port_cfg_diffserv(hw, port, 0);
+}
+
+/**
+ * sw_dis_802_1p - disable switch 802.1p priority
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ *
+ * This routine disables the 802.1p priority function of the switch.
+ */
+static void sw_dis_802_1p(struct ksz_hw *hw, int port)
+{
+	port_cfg_802_1p(hw, port, 0);
+}
+
+/**
+ * sw_cfg_replace_null_vid -
+ * @hw: 	The hardware instance.
+ * @set:	The flag to disable or enable.
+ *
+ */
+static void sw_cfg_replace_null_vid(struct ksz_hw *hw, int set)
+{
+	sw_cfg(hw, KS8842_SWITCH_CTRL_3_OFFSET, SWITCH_REPLACE_NULL_VID, set);
+}
+
+/**
+ * sw_cfg_replace_vid - enable switch 802.10 priority re-mapping
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ * @set:	The flag to disable or enable.
+ *
+ * This routine enables the 802.1p priority re-mapping function of the switch.
+ * That allows 802.1p priority field to be replaced with the port's default
+ * tag's priority value if the ingress packet's 802.1p priority has a higher
+ * priority than port's default tag's priority.
+ */
+static void sw_cfg_replace_vid(struct ksz_hw *hw, int port, int set)
+{
+	port_cfg_replace_vid(hw, port, set);
+}
+
+/**
+ * sw_cfg_port_based - configure switch port based priority
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ * @prio:	The priority to set.
+ *
+ * This routine configures the port based priority of the switch.
+ */
+static void sw_cfg_port_based(struct ksz_hw *hw, int port, u8 prio)
+{
+	u16 data;
+
+	if (prio > PORT_BASED_PRIORITY_BASE)
+		prio = PORT_BASED_PRIORITY_BASE;
+
+	hw->ksz_switch->port_cfg[port].port_prio = prio;
+
+	port_r16(hw, port, KS8842_PORT_CTRL_1_OFFSET, &data);
+	data &= ~PORT_BASED_PRIORITY_MASK;
+	data |= prio << PORT_BASED_PRIORITY_SHIFT;
+	port_w16(hw, port, KS8842_PORT_CTRL_1_OFFSET, data);
+}
+
+/**
+ * sw_dis_multi_queue - disable transmit multiple queues
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ *
+ * This routine disables the transmit multiple queues selection of the switch
+ * port.  Only single transmit queue on the port.
+ */
+static void sw_dis_multi_queue(struct ksz_hw *hw, int port)
+{
+	port_cfg_prio(hw, port, 0);
+}
+
+/**
+ * sw_init_prio - initialize switch priority
+ * @hw: 	The hardware instance.
+ *
+ * This routine initializes the switch QoS priority functions.
+ */
+static void sw_init_prio(struct ksz_hw *hw)
+{
+	int port;
+	int tos;
+	struct ksz_switch *sw = hw->ksz_switch;
+
+	/*
+	 * Init all the 802.1p tag priority value to be assigned to different
+	 * priority queue.
+	 */
+	sw->p_802_1p[0] = 0;
+	sw->p_802_1p[1] = 0;
+	sw->p_802_1p[2] = 1;
+	sw->p_802_1p[3] = 1;
+	sw->p_802_1p[4] = 2;
+	sw->p_802_1p[5] = 2;
+	sw->p_802_1p[6] = 3;
+	sw->p_802_1p[7] = 3;
+
+	/*
+	 * Init all the DiffServ priority value to be assigned to priority
+	 * queue 0.
+	 */
+	for (tos = 0; tos < DIFFSERV_ENTRIES; tos++)
+		sw->diffserv[tos] = 0;
+
+	/* All QoS functions disabled. */
+	for (port = 0; port < TOTAL_PORT_NUM; port++) {
+		sw_dis_multi_queue(hw, port);
+		sw_dis_diffserv(hw, port);
+		sw_dis_802_1p(hw, port);
+		sw_cfg_replace_vid(hw, port, 0);
+
+		sw->port_cfg[port].port_prio = 0;
+		sw_cfg_port_based(hw, port, sw->port_cfg[port].port_prio);
+	}
+	sw_cfg_replace_null_vid(hw, 0);
+}
+
+/**
+ * port_get_def_vid - get port default VID.
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ * @vid:	Buffer to store the VID.
+ *
+ * This routine retrieves the default VID of the port.
+ */
+static void port_get_def_vid(struct ksz_hw *hw, int port, u16 *vid)
+{
+	u32 addr;
+
+	PORT_CTRL_ADDR(port, addr);
+	addr += KS8842_PORT_CTRL_VID_OFFSET;
+	*vid = readw(hw->io + addr);
+}
+
+/**
+ * sw_init_vlan - initialize switch VLAN
+ * @hw: 	The hardware instance.
+ *
+ * This routine initializes the VLAN function of the switch.
+ */
+static void sw_init_vlan(struct ksz_hw *hw)
+{
+	int port;
+	int entry;
+	struct ksz_switch *sw = hw->ksz_switch;
+
+	/* Read 16 VLAN entries from device's VLAN table. */
+	for (entry = 0; entry < VLAN_TABLE_ENTRIES; entry++) {
+		sw_r_vlan_table(hw, entry,
+			&sw->vlan_table[entry].vid,
+			&sw->vlan_table[entry].fid,
+			&sw->vlan_table[entry].member);
+	}
+
+	for (port = 0; port < TOTAL_PORT_NUM; port++) {
+		port_get_def_vid(hw, port, &sw->port_cfg[port].vid);
+		sw->port_cfg[port].member = PORT_MASK;
+	}
+}
+
+/**
+ * sw_cfg_port_base_vlan - configure port-based VLAN membership
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ * @member:	The port-based VLAN membership.
+ *
+ * This routine configures the port-based VLAN membership of the port.
+ */
+static void sw_cfg_port_base_vlan(struct ksz_hw *hw, int port, u8 member)
+{
+	u32 addr;
+	u8 data;
+
+	PORT_CTRL_ADDR(port, addr);
+	addr += KS8842_PORT_CTRL_2_OFFSET;
+
+	data = readb(hw->io + addr);
+	data &= ~PORT_VLAN_MEMBERSHIP;
+	data |= (member & PORT_MASK);
+	writeb(data, hw->io + addr);
+
+	hw->ksz_switch->port_cfg[port].member = member;
+}
+
+/**
+ * sw_get_addr - get the switch MAC address.
+ * @hw: 	The hardware instance.
+ * @mac_addr:	Buffer to store the MAC address.
+ *
+ * This function retrieves the MAC address of the switch.
+ */
+static inline void sw_get_addr(struct ksz_hw *hw, u8 *mac_addr)
+{
+	int i;
+
+	for (i = 0; i < 6; i += 2) {
+		mac_addr[i] = readb(hw->io + KS8842_MAC_ADDR_0_OFFSET + i);
+		mac_addr[1 + i] = readb(hw->io + KS8842_MAC_ADDR_1_OFFSET + i);
+	}
+}
+
+/**
+ * sw_set_addr - configure switch MAC address
+ * @hw: 	The hardware instance.
+ * @mac_addr:	The MAC address.
+ *
+ * This function configures the MAC address of the switch.
+ */
+static void sw_set_addr(struct ksz_hw *hw, u8 *mac_addr)
+{
+	int i;
+
+	for (i = 0; i < 6; i += 2) {
+		writeb(mac_addr[i], hw->io + KS8842_MAC_ADDR_0_OFFSET + i);
+		writeb(mac_addr[1 + i], hw->io + KS8842_MAC_ADDR_1_OFFSET + i);
+	}
+}
+
+/**
+ * sw_set_global_ctrl - set switch global control
+ * @hw: 	The hardware instance.
+ *
+ * This routine sets the global control of the switch function.
+ */
+static void sw_set_global_ctrl(struct ksz_hw *hw)
+{
+	u16 data;
+
+	/* Enable switch MII flow control. */
+	data = readw(hw->io + KS8842_SWITCH_CTRL_3_OFFSET);
+	data |= SWITCH_FLOW_CTRL;
+	writew(data, hw->io + KS8842_SWITCH_CTRL_3_OFFSET);
+
+	data = readw(hw->io + KS8842_SWITCH_CTRL_1_OFFSET);
+
+	/* Enable aggressive back off algorithm in half duplex mode. */
+	data |= SWITCH_AGGR_BACKOFF;
+
+	/* Enable automatic fast aging when link changed detected. */
+	data |= SWITCH_AGING_ENABLE;
+	data |= SWITCH_LINK_AUTO_AGING;
+
+	if (hw->overrides & FAST_AGING)
+		data |= SWITCH_FAST_AGING;
+	else
+		data &= ~SWITCH_FAST_AGING;
+	writew(data, hw->io + KS8842_SWITCH_CTRL_1_OFFSET);
+
+	data = readw(hw->io + KS8842_SWITCH_CTRL_2_OFFSET);
+
+	/* Enable no excessive collision drop. */
+	data |= NO_EXC_COLLISION_DROP;
+	writew(data, hw->io + KS8842_SWITCH_CTRL_2_OFFSET);
+}
+
+enum {
+	STP_STATE_DISABLED = 0,
+	STP_STATE_LISTENING,
+	STP_STATE_LEARNING,
+	STP_STATE_FORWARDING,
+	STP_STATE_BLOCKED,
+	STP_STATE_SIMPLE
+};
+
+/**
+ * port_set_stp_state - configure port spanning tree state
+ * @hw: 	The hardware instance.
+ * @port:	The port index.
+ * @state:	The spanning tree state.
+ *
+ * This routine configures the spanning tree state of the port.
+ */
+static void port_set_stp_state(struct ksz_hw *hw, int port, int state)
+{
+	u16 data;
+
+	port_r16(hw, port, KS8842_PORT_CTRL_2_OFFSET, &data);
+	switch (state) {
+	case STP_STATE_DISABLED:
+		data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE);
+		data |= PORT_LEARN_DISABLE;
+		break;
+	case STP_STATE_LISTENING:
+/*
+ * No need to turn on transmit because of port direct mode.
+ * Turning on receive is required if static MAC table is not setup.
+ */
+		data &= ~PORT_TX_ENABLE;
+		data |= PORT_RX_ENABLE;
+		data |= PORT_LEARN_DISABLE;
+		break;
+	case STP_STATE_LEARNING:
+		data &= ~PORT_TX_ENABLE;
+		data |= PORT_RX_ENABLE;
+		data &= ~PORT_LEARN_DISABLE;
+		break;
+	case STP_STATE_FORWARDING:
+		data |= (PORT_TX_ENABLE | PORT_RX_ENABLE);
+		data &= ~PORT_LEARN_DISABLE;
+		break;
+	case STP_STATE_BLOCKED:
+/*
+ * Need to setup static MAC table with override to keep receiving BPDU
+ * messages.  See sw_init_stp routine.
+ */
+		data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE);
+		data |= PORT_LEARN_DISABLE;
+		break;
+	case STP_STATE_SIMPLE:
+		data |= (PORT_TX_ENABLE | PORT_RX_ENABLE);
+		data |= PORT_LEARN_DISABLE;
+		break;
+	}
+	port_w16(hw, port, KS8842_PORT_CTRL_2_OFFSET, data);
+	hw->ksz_switch->port_cfg[port].stp_state = state;
+}
+
+#define STP_ENTRY			0
+#define BROADCAST_ENTRY			1
+#define BRIDGE_ADDR_ENTRY		2
+#define IPV6_ADDR_ENTRY			3
+
+/**
+ * sw_clr_sta_mac_table - clear static MAC table
+ * @hw: 	The hardware instance.
+ *
+ * This routine clears the static MAC table.
+ */
+static void sw_clr_sta_mac_table(struct ksz_hw *hw)
+{
+	struct ksz_mac_table *entry;
+	int i;
+
+	for (i = 0; i < STATIC_MAC_TABLE_ENTRIES; i++) {
+		entry = &hw->ksz_switch->mac_table[i];
+		sw_w_sta_mac_table(hw, i,
+			entry->mac_addr, entry->ports,
+			entry->override, 0,
+			entry->use_fid, entry->fid);
+	}
+}
+
+/**
+ * sw_init_stp - initialize switch spanning tree support
+ * @hw: 	The hardware instance.
+ *
+ * This routine initializes the spanning tree support of the switch.
+ */
+static void sw_init_stp(struct ksz_hw *hw)
+{
+	struct ksz_mac_table *entry;
+
+	entry = &hw->ksz_switch->mac_table[STP_ENTRY];
+	entry->mac_addr[0] = 0x01;
+	entry->mac_addr[1] = 0x80;
+	entry->mac_addr[2] = 0xC2;
+	entry->mac_addr[3] = 0x00;
+	entry->mac_addr[4] = 0x00;
+	entry->mac_addr[5] = 0x00;
+	entry->ports = HOST_MASK;
+	entry->override = 1;
+	entry->valid = 1;
+	sw_w_sta_mac_table(hw, STP_ENTRY,
+		entry->mac_addr, entry->ports,
+		entry->override, entry->valid,
+		entry->use_fid, entry->fid);
+}
+
+/**
+ * sw_block_addr - block certain packets from the host port
+ * @hw: 	The hardware instance.
+ *
+ * This routine blocks certain packets from reaching to the host port.
+ */
+static void sw_block_addr(struct ksz_hw *hw)
+{
+	struct ksz_mac_table *entry;
+	int i;
+
+	for (i = BROADCAST_ENTRY; i <= IPV6_ADDR_ENTRY; i++) {
+		entry = &hw->ksz_switch->mac_table[i];
+		entry->valid = 0;
+		sw_w_sta_mac_table(hw, i,
+			entry->mac_addr, entry->ports,
+			entry->override, entry->valid,
+			entry->use_fid, entry->fid);
+	}
+}
+
+#define PHY_LINK_SUPPORT		\
+	(PHY_AUTO_NEG_ASYM_PAUSE |	\
+	PHY_AUTO_NEG_SYM_PAUSE |	\
+	PHY_AUTO_NEG_100BT4 |		\
+	PHY_AUTO_NEG_100BTX_FD |	\
+	PHY_AUTO_NEG_100BTX |		\
+	PHY_AUTO_NEG_10BT_FD |		\
+	PHY_AUTO_NEG_10BT)
+
+static inline void hw_r_phy_ctrl(struct ksz_hw *hw, int phy, u16 *data)
+{
+	*data = readw(hw->io + phy + KS884X_PHY_CTRL_OFFSET);
+}
+
+static inline void hw_w_phy_ctrl(struct ksz_hw *hw, int phy, u16 data)
+{
+	writew(data, hw->io + phy + KS884X_PHY_CTRL_OFFSET);
+}
+
+static inline void hw_r_phy_link_stat(struct ksz_hw *hw, int phy, u16 *data)
+{
+	*data = readw(hw->io + phy + KS884X_PHY_STATUS_OFFSET);
+}
+
+static inline void hw_r_phy_auto_neg(struct ksz_hw *hw, int phy, u16 *data)
+{
+	*data = readw(hw->io + phy + KS884X_PHY_AUTO_NEG_OFFSET);
+}
+
+static inline void hw_w_phy_auto_neg(struct ksz_hw *hw, int phy, u16 data)
+{
+	writew(data, hw->io + phy + KS884X_PHY_AUTO_NEG_OFFSET);
+}
+
+static inline void hw_r_phy_rem_cap(struct ksz_hw *hw, int phy, u16 *data)
+{
+	*data = readw(hw->io + phy + KS884X_PHY_REMOTE_CAP_OFFSET);
+}
+
+static inline void hw_r_phy_crossover(struct ksz_hw *hw, int phy, u16 *data)
+{
+	*data = readw(hw->io + phy + KS884X_PHY_CTRL_OFFSET);
+}
+
+static inline void hw_w_phy_crossover(struct ksz_hw *hw, int phy, u16 data)
+{
+	writew(data, hw->io + phy + KS884X_PHY_CTRL_OFFSET);
+}
+
+static inline void hw_r_phy_polarity(struct ksz_hw *hw, int phy, u16 *data)
+{
+	*data = readw(hw->io + phy + KS884X_PHY_PHY_CTRL_OFFSET);
+}
+
+static inline void hw_w_phy_polarity(struct ksz_hw *hw, int phy, u16 data)
+{
+	writew(data, hw->io + phy + KS884X_PHY_PHY_CTRL_OFFSET);
+}
+
+static inline void hw_r_phy_link_md(struct ksz_hw *hw, int phy, u16 *data)
+{
+	*data = readw(hw->io + phy + KS884X_PHY_LINK_MD_OFFSET);
+}
+
+static inline void hw_w_phy_link_md(struct ksz_hw *hw, int phy, u16 data)
+{
+	writew(data, hw->io + phy + KS884X_PHY_LINK_MD_OFFSET);
+}
+
+/**
+ * hw_r_phy - read data from PHY register
+ * @hw: 	The hardware instance.
+ * @port:	Port to read.
+ * @reg:	PHY register to read.
+ * @val:	Buffer to store the read data.
+ *
+ * This routine reads data from the PHY register.
+ */
+static void hw_r_phy(struct ksz_hw *hw, int port, u16 reg, u16 *val)
+{
+	int phy;
+
+	phy = KS884X_PHY_1_CTRL_OFFSET + port * PHY_CTRL_INTERVAL + reg;
+	*val = readw(hw->io + phy);
+}
+
+/**
+ * port_w_phy - write data to PHY register
+ * @hw: 	The hardware instance.
+ * @port:	Port to write.
+ * @reg:	PHY register to write.
+ * @val:	Word data to write.
+ *
+ * This routine writes data to the PHY register.
+ */
+static void hw_w_phy(struct ksz_hw *hw, int port, u16 reg, u16 val)
+{
+	int phy;
+
+	phy = KS884X_PHY_1_CTRL_OFFSET + port * PHY_CTRL_INTERVAL + reg;
+	writew(val, hw->io + phy);
+}
+
+/*
+ * EEPROM access functions
+ */
+
+#define AT93C_CODE			0
+#define AT93C_WR_OFF			0x00
+#define AT93C_WR_ALL			0x10
+#define AT93C_ER_ALL			0x20
+#define AT93C_WR_ON			0x30
+
+#define AT93C_WRITE			1
+#define AT93C_READ			2
+#define AT93C_ERASE			3
+
+#define EEPROM_DELAY			4
+
+static inline void drop_gpio(struct ksz_hw *hw, u8 gpio)
+{
+	u16 data;
+
+	data = readw(hw->io + KS884X_EEPROM_CTRL_OFFSET);
+	data &= ~gpio;
+	writew(data, hw->io + KS884X_EEPROM_CTRL_OFFSET);
+}
+
+static inline void raise_gpio(struct ksz_hw *hw, u8 gpio)
+{
+	u16 data;
+
+	data = readw(hw->io + KS884X_EEPROM_CTRL_OFFSET);
+	data |= gpio;
+	writew(data, hw->io + KS884X_EEPROM_CTRL_OFFSET);
+}
+
+static inline u8 state_gpio(struct ksz_hw *hw, u8 gpio)
+{
+	u16 data;
+
+	data = readw(hw->io + KS884X_EEPROM_CTRL_OFFSET);
+	return (u8)(data & gpio);
+}
+
+static void eeprom_clk(struct ksz_hw *hw)
+{
+	raise_gpio(hw, EEPROM_SERIAL_CLOCK);
+	udelay(EEPROM_DELAY);
+	drop_gpio(hw, EEPROM_SERIAL_CLOCK);
+	udelay(EEPROM_DELAY);
+}
+
+static u16 spi_r(struct ksz_hw *hw)
+{
+	int i;
+	u16 temp = 0;
+
+	for (i = 15; i >= 0; i--) {
+		raise_gpio(hw, EEPROM_SERIAL_CLOCK);
+		udelay(EEPROM_DELAY);
+
+		temp |= (state_gpio(hw, EEPROM_DATA_IN)) ? 1 << i : 0;
+
+		drop_gpio(hw, EEPROM_SERIAL_CLOCK);
+		udelay(EEPROM_DELAY);
+	}
+	return temp;
+}
+
+static void spi_w(struct ksz_hw *hw, u16 data)
+{
+	int i;
+
+	for (i = 15; i >= 0; i--) {
+		(data & (0x01 << i)) ? raise_gpio(hw, EEPROM_DATA_OUT) :
+			drop_gpio(hw, EEPROM_DATA_OUT);
+		eeprom_clk(hw);
+	}
+}
+
+static void spi_reg(struct ksz_hw *hw, u8 data, u8 reg)
+{
+	int i;
+
+	/* Initial start bit */
+	raise_gpio(hw, EEPROM_DATA_OUT);
+	eeprom_clk(hw);
+
+	/* AT93C operation */
+	for (i = 1; i >= 0; i--) {
+		(data & (0x01 << i)) ? raise_gpio(hw, EEPROM_DATA_OUT) :
+			drop_gpio(hw, EEPROM_DATA_OUT);
+		eeprom_clk(hw);
+	}
+
+	/* Address location */
+	for (i = 5; i >= 0; i--) {
+		(reg & (0x01 << i)) ? raise_gpio(hw, EEPROM_DATA_OUT) :
+			drop_gpio(hw, EEPROM_DATA_OUT);
+		eeprom_clk(hw);
+	}
+}
+
+#define EEPROM_DATA_RESERVED		0
+#define EEPROM_DATA_MAC_ADDR_0		1
+#define EEPROM_DATA_MAC_ADDR_1		2
+#define EEPROM_DATA_MAC_ADDR_2		3
+#define EEPROM_DATA_SUBSYS_ID		4
+#define EEPROM_DATA_SUBSYS_VEN_ID	5
+#define EEPROM_DATA_PM_CAP		6
+
+/* User defined EEPROM data */
+#define EEPROM_DATA_OTHER_MAC_ADDR	9
+
+/**
+ * eeprom_read - read from AT93C46 EEPROM
+ * @hw: 	The hardware instance.
+ * @reg:	The register offset.
+ *
+ * This function reads a word from the AT93C46 EEPROM.
+ *
+ * Return the data value.
+ */
+static u16 eeprom_read(struct ksz_hw *hw, u8 reg)
+{
+	u16 data;
+
+	raise_gpio(hw, EEPROM_ACCESS_ENABLE | EEPROM_CHIP_SELECT);
+
+	spi_reg(hw, AT93C_READ, reg);
+	data = spi_r(hw);
+
+	drop_gpio(hw, EEPROM_ACCESS_ENABLE | EEPROM_CHIP_SELECT);
+
+	return data;
+}
+
+/**
+ * eeprom_write - write to AT93C46 EEPROM
+ * @hw: 	The hardware instance.
+ * @reg:	The register offset.
+ * @data:	The data value.
+ *
+ * This procedure writes a word to the AT93C46 EEPROM.
+ */
+static void eeprom_write(struct ksz_hw *hw, u8 reg, u16 data)
+{
+	int timeout;
+
+	raise_gpio(hw, EEPROM_ACCESS_ENABLE | EEPROM_CHIP_SELECT);
+
+	/* Enable write. */
+	spi_reg(hw, AT93C_CODE, AT93C_WR_ON);
+	drop_gpio(hw, EEPROM_CHIP_SELECT);
+	udelay(1);
+
+	/* Erase the register. */
+	raise_gpio(hw, EEPROM_CHIP_SELECT);
+	spi_reg(hw, AT93C_ERASE, reg);
+	drop_gpio(hw, EEPROM_CHIP_SELECT);
+	udelay(1);
+
+	/* Check operation complete. */
+	raise_gpio(hw, EEPROM_CHIP_SELECT);
+	timeout = 8;
+	mdelay(2);
+	do {
+		mdelay(1);
+	} while (!state_gpio(hw, EEPROM_DATA_IN) && --timeout);
+	drop_gpio(hw, EEPROM_CHIP_SELECT);
+	udelay(1);
+
+	/* Write the register. */
+	raise_gpio(hw, EEPROM_CHIP_SELECT);
+	spi_reg(hw, AT93C_WRITE, reg);
+	spi_w(hw, data);
+	drop_gpio(hw, EEPROM_CHIP_SELECT);
+	udelay(1);
+
+	/* Check operation complete. */
+	raise_gpio(hw, EEPROM_CHIP_SELECT);
+	timeout = 8;
+	mdelay(2);
+	do {
+		mdelay(1);
+	} while (!state_gpio(hw, EEPROM_DATA_IN) && --timeout);
+	drop_gpio(hw, EEPROM_CHIP_SELECT);
+	udelay(1);
+
+	/* Disable write. */
+	raise_gpio(hw, EEPROM_CHIP_SELECT);
+	spi_reg(hw, AT93C_CODE, AT93C_WR_OFF);
+
+	drop_gpio(hw, EEPROM_ACCESS_ENABLE | EEPROM_CHIP_SELECT);
+}
+
+/*
+ * Link detection routines
+ */
+
+static u16 advertised_flow_ctrl(struct ksz_port *port, u16 ctrl)
+{
+	ctrl &= ~PORT_AUTO_NEG_SYM_PAUSE;
+	switch (port->flow_ctrl) {
+	case PHY_FLOW_CTRL:
+		ctrl |= PORT_AUTO_NEG_SYM_PAUSE;
+		break;
+	/* Not supported. */
+	case PHY_TX_ONLY:
+	case PHY_RX_ONLY:
+	default:
+		break;
+	}
+	return ctrl;
+}
+
+static void set_flow_ctrl(struct ksz_hw *hw, int rx, int tx)
+{
+	u32 rx_cfg;
+	u32 tx_cfg;
+
+	rx_cfg = hw->rx_cfg;
+	tx_cfg = hw->tx_cfg;
+	if (rx)
+		hw->rx_cfg |= DMA_RX_FLOW_ENABLE;
+	else
+		hw->rx_cfg &= ~DMA_RX_FLOW_ENABLE;
+	if (tx)
+		hw->tx_cfg |= DMA_TX_FLOW_ENABLE;
+	else
+		hw->tx_cfg &= ~DMA_TX_FLOW_ENABLE;
+	if (hw->enabled) {
+		if (rx_cfg != hw->rx_cfg)
+			writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL);
+		if (tx_cfg != hw->tx_cfg)
+			writel(hw->tx_cfg, hw->io + KS_DMA_TX_CTRL);
+	}
+}
+
+static void determine_flow_ctrl(struct ksz_hw *hw, struct ksz_port *port,
+	u16 local, u16 remote)
+{
+	int rx;
+	int tx;
+
+	if (hw->overrides & PAUSE_FLOW_CTRL)
+		return;
+
+	rx = tx = 0;
+	if (port->force_link)
+		rx = tx = 1;
+	if (remote & PHY_AUTO_NEG_SYM_PAUSE) {
+		if (local & PHY_AUTO_NEG_SYM_PAUSE) {
+			rx = tx = 1;
+		} else if ((remote & PHY_AUTO_NEG_ASYM_PAUSE) &&
+				(local & PHY_AUTO_NEG_PAUSE) ==
+				PHY_AUTO_NEG_ASYM_PAUSE) {
+			tx = 1;
+		}
+	} else if (remote & PHY_AUTO_NEG_ASYM_PAUSE) {
+		if ((local & PHY_AUTO_NEG_PAUSE) == PHY_AUTO_NEG_PAUSE)
+			rx = 1;
+	}
+	if (!hw->ksz_switch)
+		set_flow_ctrl(hw, rx, tx);
+}
+
+static inline void port_cfg_change(struct ksz_hw *hw, struct ksz_port *port,
+	struct ksz_port_info *info, u16 link_status)
+{
+	if ((hw->features & HALF_DUPLEX_SIGNAL_BUG) &&
+			!(hw->overrides & PAUSE_FLOW_CTRL)) {
+		u32 cfg = hw->tx_cfg;
+
+		/* Disable flow control in the half duplex mode. */
+		if (1 == info->duplex)
+			hw->tx_cfg &= ~DMA_TX_FLOW_ENABLE;
+		if (hw->enabled && cfg != hw->tx_cfg)
+			writel(hw->tx_cfg, hw->io + KS_DMA_TX_CTRL);
+	}
+}
+
+/**
+ * port_get_link_speed - get current link status
+ * @port: 	The port instance.
+ *
+ * This routine reads PHY registers to determine the current link status of the
+ * switch ports.
+ */
+static void port_get_link_speed(struct ksz_port *port)
+{
+	uint interrupt;
+	struct ksz_port_info *info;
+	struct ksz_port_info *linked = NULL;
+	struct ksz_hw *hw = port->hw;
+	u16 data;
+	u16 status;
+	u8 local;
+	u8 remote;
+	int i;
+	int p;
+	int change = 0;
+
+	interrupt = hw_block_intr(hw);
+
+	for (i = 0, p = port->first_port; i < port->port_cnt; i++, p++) {
+		info = &hw->port_info[p];
+		port_r16(hw, p, KS884X_PORT_CTRL_4_OFFSET, &data);
+		port_r16(hw, p, KS884X_PORT_STATUS_OFFSET, &status);
+
+		/*
+		 * Link status is changing all the time even when there is no
+		 * cable connection!
+		 */
+		remote = status & (PORT_AUTO_NEG_COMPLETE |
+			PORT_STATUS_LINK_GOOD);
+		local = (u8) data;
+
+		/* No change to status. */
+		if (local == info->advertised && remote == info->partner)
+			continue;
+
+		info->advertised = local;
+		info->partner = remote;
+		if (status & PORT_STATUS_LINK_GOOD) {
+
+			/* Remember the first linked port. */
+			if (!linked)
+				linked = info;
+
+			info->tx_rate = 10 * TX_RATE_UNIT;
+			if (status & PORT_STATUS_SPEED_100MBIT)
+				info->tx_rate = 100 * TX_RATE_UNIT;
+
+			info->duplex = 1;
+			if (status & PORT_STATUS_FULL_DUPLEX)
+				info->duplex = 2;
+
+			if (media_connected != info->state) {
+				hw_r_phy(hw, p, KS884X_PHY_AUTO_NEG_OFFSET,
+					&data);
+				hw_r_phy(hw, p, KS884X_PHY_REMOTE_CAP_OFFSET,
+					&status);
+				determine_flow_ctrl(hw, port, data, status);
+				if (hw->ksz_switch) {
+					port_cfg_back_pressure(hw, p,
+						(1 == info->duplex));
+				}
+				change |= 1 << i;
+				port_cfg_change(hw, port, info, status);
+			}
+			info->state = media_connected;
+		} else {
+			if (media_disconnected != info->state) {
+				change |= 1 << i;
+
+				/* Indicate the link just goes down. */
+				hw->port_mib[p].link_down = 1;
+			}
+			info->state = media_disconnected;
+		}
+		hw->port_mib[p].state = (u8) info->state;
+	}
+
+	if (linked && media_disconnected == port->linked->state)
+		port->linked = linked;
+
+	hw_restore_intr(hw, interrupt);
+}
+
+#define PHY_RESET_TIMEOUT		10
+
+/**
+ * port_set_link_speed - set port speed
+ * @port: 	The port instance.
+ *
+ * This routine sets the link speed of the switch ports.
+ */
+static void port_set_link_speed(struct ksz_port *port)
+{
+	struct ksz_port_info *info;
+	struct ksz_hw *hw = port->hw;
+	u16 data;
+	u16 cfg;
+	u8 status;
+	int i;
+	int p;
+
+	for (i = 0, p = port->first_port; i < port->port_cnt; i++, p++) {
+		info = &hw->port_info[p];
+
+		port_r16(hw, p, KS884X_PORT_CTRL_4_OFFSET, &data);
+		port_r8(hw, p, KS884X_PORT_STATUS_OFFSET, &status);
+
+		cfg = 0;
+		if (status & PORT_STATUS_LINK_GOOD)
+			cfg = data;
+
+		data |= PORT_AUTO_NEG_ENABLE;
+		data = advertised_flow_ctrl(port, data);
+
+		data |= PORT_AUTO_NEG_100BTX_FD | PORT_AUTO_NEG_100BTX |
+			PORT_AUTO_NEG_10BT_FD | PORT_AUTO_NEG_10BT;
+
+		/* Check if manual configuration is specified by the user. */
+		if (port->speed || port->duplex) {
+			if (10 == port->speed)
+				data &= ~(PORT_AUTO_NEG_100BTX_FD |
+					PORT_AUTO_NEG_100BTX);
+			else if (100 == port->speed)
+				data &= ~(PORT_AUTO_NEG_10BT_FD |
+					PORT_AUTO_NEG_10BT);
+			if (1 == port->duplex)
+				data &= ~(PORT_AUTO_NEG_100BTX_FD |
+					PORT_AUTO_NEG_10BT_FD);
+			else if (2 == port->duplex)
+				data &= ~(PORT_AUTO_NEG_100BTX |
+					PORT_AUTO_NEG_10BT);
+		}
+		if (data != cfg) {
+			data |= PORT_AUTO_NEG_RESTART;
+			port_w16(hw, p, KS884X_PORT_CTRL_4_OFFSET, data);
+		}
+	}
+}
+
+/**
+ * port_force_link_speed - force port speed
+ * @port: 	The port instance.
+ *
+ * This routine forces the link speed of the switch ports.
+ */
+static void port_force_link_speed(struct ksz_port *port)
+{
+	struct ksz_hw *hw = port->hw;
+	u16 data;
+	int i;
+	int phy;
+	int p;
+
+	for (i = 0, p = port->first_port; i < port->port_cnt; i++, p++) {
+		phy = KS884X_PHY_1_CTRL_OFFSET + p * PHY_CTRL_INTERVAL;
+		hw_r_phy_ctrl(hw, phy, &data);
+
+		data &= ~PHY_AUTO_NEG_ENABLE;
+
+		if (10 == port->speed)
+			data &= ~PHY_SPEED_100MBIT;
+		else if (100 == port->speed)
+			data |= PHY_SPEED_100MBIT;
+		if (1 == port->duplex)
+			data &= ~PHY_FULL_DUPLEX;
+		else if (2 == port->duplex)
+			data |= PHY_FULL_DUPLEX;
+		hw_w_phy_ctrl(hw, phy, data);
+	}
+}
+
+static void port_set_power_saving(struct ksz_port *port, int enable)
+{
+	struct ksz_hw *hw = port->hw;
+	int i;
+	int p;
+
+	for (i = 0, p = port->first_port; i < port->port_cnt; i++, p++)
+		port_cfg(hw, p,
+			KS884X_PORT_CTRL_4_OFFSET, PORT_POWER_DOWN, enable);
+}
+
+/*
+ * KSZ8841 power management functions
+ */
+
+/**
+ * hw_chk_wol_pme_status - check PMEN pin
+ * @hw: 	The hardware instance.
+ *
+ * This function is used to check PMEN pin is asserted.
+ *
+ * Return 1 if PMEN pin is asserted; otherwise, 0.
+ */
+static int hw_chk_wol_pme_status(struct ksz_hw *hw)
+{
+	struct dev_info *hw_priv = container_of(hw, struct dev_info, hw);
+	struct pci_dev *pdev = hw_priv->pdev;
+	u16 data;
+
+	if (!pdev->pm_cap)
+		return 0;
+	pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &data);
+	return (data & PCI_PM_CTRL_PME_STATUS) == PCI_PM_CTRL_PME_STATUS;
+}
+
+/**
+ * hw_clr_wol_pme_status - clear PMEN pin
+ * @hw: 	The hardware instance.
+ *
+ * This routine is used to clear PME_Status to deassert PMEN pin.
+ */
+static void hw_clr_wol_pme_status(struct ksz_hw *hw)
+{
+	struct dev_info *hw_priv = container_of(hw, struct dev_info, hw);
+	struct pci_dev *pdev = hw_priv->pdev;
+	u16 data;
+
+	if (!pdev->pm_cap)
+		return;
+
+	/* Clear PME_Status to deassert PMEN pin. */
+	pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &data);
+	data |= PCI_PM_CTRL_PME_STATUS;
+	pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, data);
+}
+
+/**
+ * hw_cfg_wol_pme - enable or disable Wake-on-LAN
+ * @hw: 	The hardware instance.
+ * @set:	The flag indicating whether to enable or disable.
+ *
+ * This routine is used to enable or disable Wake-on-LAN.
+ */
+static void hw_cfg_wol_pme(struct ksz_hw *hw, int set)
+{
+	struct dev_info *hw_priv = container_of(hw, struct dev_info, hw);
+	struct pci_dev *pdev = hw_priv->pdev;
+	u16 data;
+
+	if (!pdev->pm_cap)
+		return;
+	pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &data);
+	data &= ~PCI_PM_CTRL_STATE_MASK;
+	if (set)
+		data |= PCI_PM_CTRL_PME_ENABLE | PCI_D3hot;
+	else
+		data &= ~PCI_PM_CTRL_PME_ENABLE;
+	pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, data);
+}
+
+/**
+ * hw_cfg_wol - configure Wake-on-LAN features
+ * @hw: 	The hardware instance.
+ * @frame:	The pattern frame bit.
+ * @set:	The flag indicating whether to enable or disable.
+ *
+ * This routine is used to enable or disable certain Wake-on-LAN features.
+ */
+static void hw_cfg_wol(struct ksz_hw *hw, u16 frame, int set)
+{
+	u16 data;
+
+	data = readw(hw->io + KS8841_WOL_CTRL_OFFSET);
+	if (set)
+		data |= frame;
+	else
+		data &= ~frame;
+	writew(data, hw->io + KS8841_WOL_CTRL_OFFSET);
+}
+
+/**
+ * hw_set_wol_frame - program Wake-on-LAN pattern
+ * @hw: 	The hardware instance.
+ * @i:		The frame index.
+ * @mask_size:	The size of the mask.
+ * @mask:	Mask to ignore certain bytes in the pattern.
+ * @frame_size:	The size of the frame.
+ * @pattern:	The frame data.
+ *
+ * This routine is used to program Wake-on-LAN pattern.
+ */
+static void hw_set_wol_frame(struct ksz_hw *hw, int i, uint mask_size,
+	u8 *mask, uint frame_size, u8 *pattern)
+{
+	int bits;
+	int from;
+	int len;
+	int to;
+	u32 crc;
+	u8 data[64];
+	u8 val = 0;
+
+	if (frame_size > mask_size * 8)
+		frame_size = mask_size * 8;
+	if (frame_size > 64)
+		frame_size = 64;
+
+	i *= 0x10;
+	writel(0, hw->io + KS8841_WOL_FRAME_BYTE0_OFFSET + i);
+	writel(0, hw->io + KS8841_WOL_FRAME_BYTE2_OFFSET + i);
+
+	bits = len = from = to = 0;
+	do {
+		if (bits) {
+			if ((val & 1))
+				data[to++] = pattern[from];
+			val >>= 1;
+			++from;
+			--bits;
+		} else {
+			val = mask[len];
+			writeb(val, hw->io + KS8841_WOL_FRAME_BYTE0_OFFSET + i
+				+ len);
+			++len;
+			if (val)
+				bits = 8;
+			else
+				from += 8;
+		}
+	} while (from < (int) frame_size);
+	if (val) {
+		bits = mask[len - 1];
+		val <<= (from % 8);
+		bits &= ~val;
+		writeb(bits, hw->io + KS8841_WOL_FRAME_BYTE0_OFFSET + i + len -
+			1);
+	}
+	crc = ether_crc(to, data);
+	writel(crc, hw->io + KS8841_WOL_FRAME_CRC_OFFSET + i);
+}
+
+/**
+ * hw_add_wol_arp - add ARP pattern
+ * @hw: 	The hardware instance.
+ * @ip_addr:	The IPv4 address assigned to the device.
+ *
+ * This routine is used to add ARP pattern for waking up the host.
+ */
+static void hw_add_wol_arp(struct ksz_hw *hw, u8 *ip_addr)
+{
+	u8 mask[6] = { 0x3F, 0xF0, 0x3F, 0x00, 0xC0, 0x03 };
+	u8 pattern[42] = {
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x08, 0x06,
+		0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00 };
+
+	memcpy(&pattern[38], ip_addr, 4);
+	hw_set_wol_frame(hw, 3, 6, mask, 42, pattern);
+}
+
+/**
+ * hw_add_wol_bcast - add broadcast pattern
+ * @hw: 	The hardware instance.
+ *
+ * This routine is used to add broadcast pattern for waking up the host.
+ */
+static void hw_add_wol_bcast(struct ksz_hw *hw)
+{
+	u8 mask[] = { 0x3F };
+	u8 pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+	hw_set_wol_frame(hw, 2, 1, mask, MAC_ADDR_LEN, pattern);
+}
+
+/**
+ * hw_add_wol_mcast - add multicast pattern
+ * @hw: 	The hardware instance.
+ *
+ * This routine is used to add multicast pattern for waking up the host.
+ *
+ * It is assumed the multicast packet is the ICMPv6 neighbor solicitation used
+ * by IPv6 ping command.  Note that multicast packets are filtred through the
+ * multicast hash table, so not all multicast packets can wake up the host.
+ */
+static void hw_add_wol_mcast(struct ksz_hw *hw)
+{
+	u8 mask[] = { 0x3F };
+	u8 pattern[] = { 0x33, 0x33, 0xFF, 0x00, 0x00, 0x00 };
+
+	memcpy(&pattern[3], &hw->override_addr[3], 3);
+	hw_set_wol_frame(hw, 1, 1, mask, 6, pattern);
+}
+
+/**
+ * hw_add_wol_ucast - add unicast pattern
+ * @hw: 	The hardware instance.
+ *
+ * This routine is used to add unicast pattern to wakeup the host.
+ *
+ * It is assumed the unicast packet is directed to the device, as the hardware
+ * can only receive them in normal case.
+ */
+static void hw_add_wol_ucast(struct ksz_hw *hw)
+{
+	u8 mask[] = { 0x3F };
+
+	hw_set_wol_frame(hw, 0, 1, mask, MAC_ADDR_LEN, hw->override_addr);
+}
+
+/**
+ * hw_enable_wol - enable Wake-on-LAN
+ * @hw: 	The hardware instance.
+ * @wol_enable:	The Wake-on-LAN settings.
+ * @net_addr:	The IPv4 address assigned to the device.
+ *
+ * This routine is used to enable Wake-on-LAN depending on driver settings.
+ */
+static void hw_enable_wol(struct ksz_hw *hw, u32 wol_enable, u8 *net_addr)
+{
+	hw_cfg_wol(hw, KS8841_WOL_MAGIC_ENABLE, (wol_enable & WAKE_MAGIC));
+	hw_cfg_wol(hw, KS8841_WOL_FRAME0_ENABLE, (wol_enable & WAKE_UCAST));
+	hw_add_wol_ucast(hw);
+	hw_cfg_wol(hw, KS8841_WOL_FRAME1_ENABLE, (wol_enable & WAKE_MCAST));
+	hw_add_wol_mcast(hw);
+	hw_cfg_wol(hw, KS8841_WOL_FRAME2_ENABLE, (wol_enable & WAKE_BCAST));
+	hw_cfg_wol(hw, KS8841_WOL_FRAME3_ENABLE, (wol_enable & WAKE_ARP));
+	hw_add_wol_arp(hw, net_addr);
+}
+
+/**
+ * hw_init - check driver is correct for the hardware
+ * @hw: 	The hardware instance.
+ *
+ * This function checks the hardware is correct for this driver and sets the
+ * hardware up for proper initialization.
+ *
+ * Return number of ports or 0 if not right.
+ */
+static int hw_init(struct ksz_hw *hw)
+{
+	int rc = 0;
+	u16 data;
+	u16 revision;
+
+	/* Set bus speed to 125MHz. */
+	writew(BUS_SPEED_125_MHZ, hw->io + KS884X_BUS_CTRL_OFFSET);
+
+	/* Check KSZ884x chip ID. */
+	data = readw(hw->io + KS884X_CHIP_ID_OFFSET);
+
+	revision = (data & KS884X_REVISION_MASK) >> KS884X_REVISION_SHIFT;
+	data &= KS884X_CHIP_ID_MASK_41;
+	if (REG_CHIP_ID_41 == data)
+		rc = 1;
+	else if (REG_CHIP_ID_42 == data)
+		rc = 2;
+	else
+		return 0;
+
+	/* Setup hardware features or bug workarounds. */
+	if (revision <= 1) {
+		hw->features |= SMALL_PACKET_TX_BUG;
+		if (1 == rc)
+			hw->features |= HALF_DUPLEX_SIGNAL_BUG;
+	}
+	hw->features |= IPV6_CSUM_GEN_HACK;
+	return rc;
+}
+
+/**
+ * hw_reset - reset the hardware
+ * @hw: 	The hardware instance.
+ *
+ * This routine resets the hardware.
+ */
+static void hw_reset(struct ksz_hw *hw)
+{
+	writew(GLOBAL_SOFTWARE_RESET, hw->io + KS884X_GLOBAL_CTRL_OFFSET);
+
+	/* Wait for device to reset. */
+	mdelay(10);
+
+	/* Write 0 to clear device reset. */
+	writew(0, hw->io + KS884X_GLOBAL_CTRL_OFFSET);
+}
+
+/**
+ * hw_setup - setup the hardware
+ * @hw: 	The hardware instance.
+ *
+ * This routine setup the hardware for proper operation.
+ */
+static void hw_setup(struct ksz_hw *hw)
+{
+#if SET_DEFAULT_LED
+	u16 data;
+
+	/* Change default LED mode. */
+	data = readw(hw->io + KS8842_SWITCH_CTRL_5_OFFSET);
+	data &= ~LED_MODE;
+	data |= SET_DEFAULT_LED;
+	writew(data, hw->io + KS8842_SWITCH_CTRL_5_OFFSET);
+#endif
+
+	/* Setup transmit control. */
+	hw->tx_cfg = (DMA_TX_PAD_ENABLE | DMA_TX_CRC_ENABLE |
+		(DMA_BURST_DEFAULT << DMA_BURST_SHIFT) | DMA_TX_ENABLE);
+
+	/* Setup receive control. */
+	hw->rx_cfg = (DMA_RX_BROADCAST | DMA_RX_UNICAST |
+		(DMA_BURST_DEFAULT << DMA_BURST_SHIFT) | DMA_RX_ENABLE);
+	hw->rx_cfg |= KS884X_DMA_RX_MULTICAST;
+
+	/* Hardware cannot handle UDP packet in IP fragments. */
+	hw->rx_cfg |= (DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP);
+
+	if (hw->all_multi)
+		hw->rx_cfg |= DMA_RX_ALL_MULTICAST;
+	if (hw->promiscuous)
+		hw->rx_cfg |= DMA_RX_PROMISCUOUS;
+}
+
+/**
+ * hw_setup_intr - setup interrupt mask
+ * @hw: 	The hardware instance.
+ *
+ * This routine setup the interrupt mask for proper operation.
+ */
+static void hw_setup_intr(struct ksz_hw *hw)
+{
+	hw->intr_mask = KS884X_INT_MASK | KS884X_INT_RX_OVERRUN;
+}
+
+static void ksz_check_desc_num(struct ksz_desc_info *info)
+{
+#define MIN_DESC_SHIFT  2
+
+	int alloc = info->alloc;
+	int shift;
+
+	shift = 0;
+	while (!(alloc & 1)) {
+		shift++;
+		alloc >>= 1;
+	}
+	if (alloc != 1 || shift < MIN_DESC_SHIFT) {
+		printk(KERN_ALERT "Hardware descriptor numbers not right!\n");
+		while (alloc) {
+			shift++;
+			alloc >>= 1;
+		}
+		if (shift < MIN_DESC_SHIFT)
+			shift = MIN_DESC_SHIFT;
+		alloc = 1 << shift;
+		info->alloc = alloc;
+	}
+	info->mask = info->alloc - 1;
+}
+
+static void hw_init_desc(struct ksz_desc_info *desc_info, int transmit)
+{
+	int i;
+	u32 phys = desc_info->ring_phys;
+	struct ksz_hw_desc *desc = desc_info->ring_virt;
+	struct ksz_desc *cur = desc_info->ring;
+	struct ksz_desc *previous = NULL;
+
+	for (i = 0; i < desc_info->alloc; i++) {
+		cur->phw = desc++;
+		phys += desc_info->size;
+		previous = cur++;
+		previous->phw->next = cpu_to_le32(phys);
+	}
+	previous->phw->next = cpu_to_le32(desc_info->ring_phys);
+	previous->sw.buf.rx.end_of_ring = 1;
+	previous->phw->buf.data = cpu_to_le32(previous->sw.buf.data);
+
+	desc_info->avail = desc_info->alloc;
+	desc_info->last = desc_info->next = 0;
+
+	desc_info->cur = desc_info->ring;
+}
+
+/**
+ * hw_set_desc_base - set descriptor base addresses
+ * @hw: 	The hardware instance.
+ * @tx_addr:	The transmit descriptor base.
+ * @rx_addr:	The receive descriptor base.
+ *
+ * This routine programs the descriptor base addresses after reset.
+ */
+static void hw_set_desc_base(struct ksz_hw *hw, u32 tx_addr, u32 rx_addr)
+{
+	/* Set base address of Tx/Rx descriptors. */
+	writel(tx_addr, hw->io + KS_DMA_TX_ADDR);
+	writel(rx_addr, hw->io + KS_DMA_RX_ADDR);
+}
+
+static void hw_reset_pkts(struct ksz_desc_info *info)
+{
+	info->cur = info->ring;
+	info->avail = info->alloc;
+	info->last = info->next = 0;
+}
+
+static inline void hw_resume_rx(struct ksz_hw *hw)
+{
+	writel(DMA_START, hw->io + KS_DMA_RX_START);
+}
+
+/**
+ * hw_start_rx - start receiving
+ * @hw: 	The hardware instance.
+ *
+ * This routine starts the receive function of the hardware.
+ */
+static void hw_start_rx(struct ksz_hw *hw)
+{
+	writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL);
+
+	/* Notify when the receive stops. */
+	hw->intr_mask |= KS884X_INT_RX_STOPPED;
+
+	writel(DMA_START, hw->io + KS_DMA_RX_START);
+	hw_ack_intr(hw, KS884X_INT_RX_STOPPED);
+	hw->rx_stop++;
+
+	/* Variable overflows. */
+	if (0 == hw->rx_stop)
+		hw->rx_stop = 2;
+}
+
+/*
+ * hw_stop_rx - stop receiving
+ * @hw: 	The hardware instance.
+ *
+ * This routine stops the receive function of the hardware.
+ */
+static void hw_stop_rx(struct ksz_hw *hw)
+{
+	hw->rx_stop = 0;
+	hw_turn_off_intr(hw, KS884X_INT_RX_STOPPED);
+	writel((hw->rx_cfg & ~DMA_RX_ENABLE), hw->io + KS_DMA_RX_CTRL);
+}
+
+/**
+ * hw_start_tx - start transmitting
+ * @hw: 	The hardware instance.
+ *
+ * This routine starts the transmit function of the hardware.
+ */
+static void hw_start_tx(struct ksz_hw *hw)
+{
+	writel(hw->tx_cfg, hw->io + KS_DMA_TX_CTRL);
+}
+
+/**
+ * hw_stop_tx - stop transmitting
+ * @hw: 	The hardware instance.
+ *
+ * This routine stops the transmit function of the hardware.
+ */
+static void hw_stop_tx(struct ksz_hw *hw)
+{
+	writel((hw->tx_cfg & ~DMA_TX_ENABLE), hw->io + KS_DMA_TX_CTRL);
+}
+
+/**
+ * hw_disable - disable hardware
+ * @hw: 	The hardware instance.
+ *
+ * This routine disables the hardware.
+ */
+static void hw_disable(struct ksz_hw *hw)
+{
+	hw_stop_rx(hw);
+	hw_stop_tx(hw);
+	hw->enabled = 0;
+}
+
+/**
+ * hw_enable - enable hardware
+ * @hw: 	The hardware instance.
+ *
+ * This routine enables the hardware.
+ */
+static void hw_enable(struct ksz_hw *hw)
+{
+	hw_start_tx(hw);
+	hw_start_rx(hw);
+	hw->enabled = 1;
+}
+
+/**
+ * hw_alloc_pkt - allocate enough descriptors for transmission
+ * @hw: 	The hardware instance.
+ * @length:	The length of the packet.
+ * @physical:	Number of descriptors required.
+ *
+ * This function allocates descriptors for transmission.
+ *
+ * Return 0 if not successful; 1 for buffer copy; or number of descriptors.
+ */
+static int hw_alloc_pkt(struct ksz_hw *hw, int length, int physical)
+{
+	/* Always leave one descriptor free. */
+	if (hw->tx_desc_info.avail <= 1)
+		return 0;
+
+	/* Allocate a descriptor for transmission and mark it current. */
+	get_tx_pkt(&hw->tx_desc_info, &hw->tx_desc_info.cur);
+	hw->tx_desc_info.cur->sw.buf.tx.first_seg = 1;
+
+	/* Keep track of number of transmit descriptors used so far. */
+	++hw->tx_int_cnt;
+	hw->tx_size += length;
+
+	/* Cannot hold on too much data. */
+	if (hw->tx_size >= MAX_TX_HELD_SIZE)
+		hw->tx_int_cnt = hw->tx_int_mask + 1;
+
+	if (physical > hw->tx_desc_info.avail)
+		return 1;
+
+	return hw->tx_desc_info.avail;
+}
+
+/**
+ * hw_send_pkt - mark packet for transmission
+ * @hw: 	The hardware instance.
+ *
+ * This routine marks the packet for transmission in PCI version.
+ */
+static void hw_send_pkt(struct ksz_hw *hw)
+{
+	struct ksz_desc *cur = hw->tx_desc_info.cur;
+
+	cur->sw.buf.tx.last_seg = 1;
+
+	/* Interrupt only after specified number of descriptors used. */
+	if (hw->tx_int_cnt > hw->tx_int_mask) {
+		cur->sw.buf.tx.intr = 1;
+		hw->tx_int_cnt = 0;
+		hw->tx_size = 0;
+	}
+
+	/* KSZ8842 supports port directed transmission. */
+	cur->sw.buf.tx.dest_port = hw->dst_ports;
+
+	release_desc(cur);
+
+	writel(0, hw->io + KS_DMA_TX_START);
+}
+
+static int empty_addr(u8 *addr)
+{
+	u32 *addr1 = (u32 *) addr;
+	u16 *addr2 = (u16 *) &addr[4];
+
+	return 0 == *addr1 && 0 == *addr2;
+}
+
+/**
+ * hw_set_addr - set MAC address
+ * @hw: 	The hardware instance.
+ *
+ * This routine programs the MAC address of the hardware when the address is
+ * overrided.
+ */
+static void hw_set_addr(struct ksz_hw *hw)
+{
+	int i;
+
+	for (i = 0; i < MAC_ADDR_LEN; i++)
+		writeb(hw->override_addr[MAC_ADDR_ORDER(i)],
+			hw->io + KS884X_ADDR_0_OFFSET + i);
+
+	sw_set_addr(hw, hw->override_addr);
+}
+
+/**
+ * hw_read_addr - read MAC address
+ * @hw: 	The hardware instance.
+ *
+ * This routine retrieves the MAC address of the hardware.
+ */
+static void hw_read_addr(struct ksz_hw *hw)
+{
+	int i;
+
+	for (i = 0; i < MAC_ADDR_LEN; i++)
+		hw->perm_addr[MAC_ADDR_ORDER(i)] = readb(hw->io +
+			KS884X_ADDR_0_OFFSET + i);
+
+	if (!hw->mac_override) {
+		memcpy(hw->override_addr, hw->perm_addr, MAC_ADDR_LEN);
+		if (empty_addr(hw->override_addr)) {
+			memcpy(hw->perm_addr, DEFAULT_MAC_ADDRESS,
+				MAC_ADDR_LEN);
+			memcpy(hw->override_addr, DEFAULT_MAC_ADDRESS,
+				MAC_ADDR_LEN);
+			hw->override_addr[5] += hw->id;
+			hw_set_addr(hw);
+		}
+	}
+}
+
+static void hw_ena_add_addr(struct ksz_hw *hw, int index, u8 *mac_addr)
+{
+	int i;
+	u32 mac_addr_lo;
+	u32 mac_addr_hi;
+
+	mac_addr_hi = 0;
+	for (i = 0; i < 2; i++) {
+		mac_addr_hi <<= 8;
+		mac_addr_hi |= mac_addr[i];
+	}
+	mac_addr_hi |= ADD_ADDR_ENABLE;
+	mac_addr_lo = 0;
+	for (i = 2; i < 6; i++) {
+		mac_addr_lo <<= 8;
+		mac_addr_lo |= mac_addr[i];
+	}
+	index *= ADD_ADDR_INCR;
+
+	writel(mac_addr_lo, hw->io + index + KS_ADD_ADDR_0_LO);
+	writel(mac_addr_hi, hw->io + index + KS_ADD_ADDR_0_HI);
+}
+
+static void hw_set_add_addr(struct ksz_hw *hw)
+{
+	int i;
+
+	for (i = 0; i < ADDITIONAL_ENTRIES; i++) {
+		if (empty_addr(hw->address[i]))
+			writel(0, hw->io + ADD_ADDR_INCR * i +
+				KS_ADD_ADDR_0_HI);
+		else
+			hw_ena_add_addr(hw, i, hw->address[i]);
+	}
+}
+
+static int hw_add_addr(struct ksz_hw *hw, u8 *mac_addr)
+{
+	int i;
+	int j = ADDITIONAL_ENTRIES;
+
+	if (!memcmp(hw->override_addr, mac_addr, MAC_ADDR_LEN))
+		return 0;
+	for (i = 0; i < hw->addr_list_size; i++) {
+		if (!memcmp(hw->address[i], mac_addr, MAC_ADDR_LEN))
+			return 0;
+		if (ADDITIONAL_ENTRIES == j && empty_addr(hw->address[i]))
+			j = i;
+	}
+	if (j < ADDITIONAL_ENTRIES) {
+		memcpy(hw->address[j], mac_addr, MAC_ADDR_LEN);
+		hw_ena_add_addr(hw, j, hw->address[j]);
+		return 0;
+	}
+	return -1;
+}
+
+static int hw_del_addr(struct ksz_hw *hw, u8 *mac_addr)
+{
+	int i;
+
+	for (i = 0; i < hw->addr_list_size; i++) {
+		if (!memcmp(hw->address[i], mac_addr, MAC_ADDR_LEN)) {
+			memset(hw->address[i], 0, MAC_ADDR_LEN);
+			writel(0, hw->io + ADD_ADDR_INCR * i +
+				KS_ADD_ADDR_0_HI);
+			return 0;
+		}
+	}
+	return -1;
+}
+
+/**
+ * hw_clr_multicast - clear multicast addresses
+ * @hw: 	The hardware instance.
+ *
+ * This routine removes all multicast addresses set in the hardware.
+ */
+static void hw_clr_multicast(struct ksz_hw *hw)
+{
+	int i;
+
+	for (i = 0; i < HW_MULTICAST_SIZE; i++) {
+		hw->multi_bits[i] = 0;
+
+		writeb(0, hw->io + KS884X_MULTICAST_0_OFFSET + i);
+	}
+}
+
+/**
+ * hw_set_grp_addr - set multicast addresses
+ * @hw: 	The hardware instance.
+ *
+ * This routine programs multicast addresses for the hardware to accept those
+ * addresses.
+ */
+static void hw_set_grp_addr(struct ksz_hw *hw)
+{
+	int i;
+	int index;
+	int position;
+	int value;
+
+	memset(hw->multi_bits, 0, sizeof(u8) * HW_MULTICAST_SIZE);
+
+	for (i = 0; i < hw->multi_list_size; i++) {
+		position = (ether_crc(6, hw->multi_list[i]) >> 26) & 0x3f;
+		index = position >> 3;
+		value = 1 << (position & 7);
+		hw->multi_bits[index] |= (u8) value;
+	}
+
+	for (i = 0; i < HW_MULTICAST_SIZE; i++)
+		writeb(hw->multi_bits[i], hw->io + KS884X_MULTICAST_0_OFFSET +
+			i);
+}
+
+/**
+ * hw_set_multicast - enable or disable all multicast receiving
+ * @hw: 	The hardware instance.
+ * @multicast:	To turn on or off the all multicast feature.
+ *
+ * This routine enables/disables the hardware to accept all multicast packets.
+ */
+static void hw_set_multicast(struct ksz_hw *hw, u8 multicast)
+{
+	/* Stop receiving for reconfiguration. */
+	hw_stop_rx(hw);
+
+	if (multicast)
+		hw->rx_cfg |= DMA_RX_ALL_MULTICAST;
+	else
+		hw->rx_cfg &= ~DMA_RX_ALL_MULTICAST;
+
+	if (hw->enabled)
+		hw_start_rx(hw);
+}
+
+/**
+ * hw_set_promiscuous - enable or disable promiscuous receiving
+ * @hw: 	The hardware instance.
+ * @prom:	To turn on or off the promiscuous feature.
+ *
+ * This routine enables/disables the hardware to accept all packets.
+ */
+static void hw_set_promiscuous(struct ksz_hw *hw, u8 prom)
+{
+	/* Stop receiving for reconfiguration. */
+	hw_stop_rx(hw);
+
+	if (prom)
+		hw->rx_cfg |= DMA_RX_PROMISCUOUS;
+	else
+		hw->rx_cfg &= ~DMA_RX_PROMISCUOUS;
+
+	if (hw->enabled)
+		hw_start_rx(hw);
+}
+
+/**
+ * sw_enable - enable the switch
+ * @hw: 	The hardware instance.
+ * @enable:	The flag to enable or disable the switch
+ *
+ * This routine is used to enable/disable the switch in KSZ8842.
+ */
+static void sw_enable(struct ksz_hw *hw, int enable)
+{
+	int port;
+
+	for (port = 0; port < SWITCH_PORT_NUM; port++) {
+		if (hw->dev_count > 1) {
+			/* Set port-base vlan membership with host port. */
+			sw_cfg_port_base_vlan(hw, port,
+				HOST_MASK | (1 << port));
+			port_set_stp_state(hw, port, STP_STATE_DISABLED);
+		} else {
+			sw_cfg_port_base_vlan(hw, port, PORT_MASK);
+			port_set_stp_state(hw, port, STP_STATE_FORWARDING);
+		}
+	}
+	if (hw->dev_count > 1)
+		port_set_stp_state(hw, SWITCH_PORT_NUM, STP_STATE_SIMPLE);
+	else
+		port_set_stp_state(hw, SWITCH_PORT_NUM, STP_STATE_FORWARDING);
+
+	if (enable)
+		enable = KS8842_START;
+	writew(enable, hw->io + KS884X_CHIP_ID_OFFSET);
+}
+
+/**
+ * sw_setup - setup the switch
+ * @hw: 	The hardware instance.
+ *
+ * This routine setup the hardware switch engine for default operation.
+ */
+static void sw_setup(struct ksz_hw *hw)
+{
+	int port;
+
+	sw_set_global_ctrl(hw);
+
+	/* Enable switch broadcast storm protection at 10% percent rate. */
+	sw_init_broad_storm(hw);
+	hw_cfg_broad_storm(hw, BROADCAST_STORM_PROTECTION_RATE);
+	for (port = 0; port < SWITCH_PORT_NUM; port++)
+		sw_ena_broad_storm(hw, port);
+
+	sw_init_prio(hw);
+
+	sw_init_mirror(hw);
+
+	sw_init_prio_rate(hw);
+
+	sw_init_vlan(hw);
+
+	if (hw->features & STP_SUPPORT)
+		sw_init_stp(hw);
+	if (!sw_chk(hw, KS8842_SWITCH_CTRL_1_OFFSET,
+			SWITCH_TX_FLOW_CTRL | SWITCH_RX_FLOW_CTRL))
+		hw->overrides |= PAUSE_FLOW_CTRL;
+	sw_enable(hw, 1);
+}
+
+/**
+ * ksz_start_timer - start kernel timer
+ * @info:	Kernel timer information.
+ * @time:	The time tick.
+ *
+ * This routine starts the kernel timer after the specified time tick.
+ */
+static void ksz_start_timer(struct ksz_timer_info *info, int time)
+{
+	info->cnt = 0;
+	info->timer.expires = jiffies + time;
+	add_timer(&info->timer);
+
+	/* infinity */
+	info->max = -1;
+}
+
+/**
+ * ksz_stop_timer - stop kernel timer
+ * @info:	Kernel timer information.
+ *
+ * This routine stops the kernel timer.
+ */
+static void ksz_stop_timer(struct ksz_timer_info *info)
+{
+	if (info->max) {
+		info->max = 0;
+		del_timer_sync(&info->timer);
+	}
+}
+
+static void ksz_init_timer(struct ksz_timer_info *info, int period,
+	void (*function)(unsigned long), void *data)
+{
+	info->max = 0;
+	info->period = period;
+	init_timer(&info->timer);
+	info->timer.function = function;
+	info->timer.data = (unsigned long) data;
+}
+
+static void ksz_update_timer(struct ksz_timer_info *info)
+{
+	++info->cnt;
+	if (info->max > 0) {
+		if (info->cnt < info->max) {
+			info->timer.expires = jiffies + info->period;
+			add_timer(&info->timer);
+		} else
+			info->max = 0;
+	} else if (info->max < 0) {
+		info->timer.expires = jiffies + info->period;
+		add_timer(&info->timer);
+	}
+}
+
+/**
+ * ksz_alloc_soft_desc - allocate software descriptors
+ * @desc_info:	Descriptor information structure.
+ * @transmit:	Indication that descriptors are for transmit.
+ *
+ * This local function allocates software descriptors for manipulation in
+ * memory.
+ *
+ * Return 0 if successful.
+ */
+static int ksz_alloc_soft_desc(struct ksz_desc_info *desc_info, int transmit)
+{
+	desc_info->ring = kmalloc(sizeof(struct ksz_desc) * desc_info->alloc,
+		GFP_KERNEL);
+	if (!desc_info->ring)
+		return 1;
+	memset((void *) desc_info->ring, 0,
+		sizeof(struct ksz_desc) * desc_info->alloc);
+	hw_init_desc(desc_info, transmit);
+	return 0;
+}
+
+/**
+ * ksz_alloc_desc - allocate hardware descriptors
+ * @adapter:	Adapter information structure.
+ *
+ * This local function allocates hardware descriptors for receiving and
+ * transmitting.
+ *
+ * Return 0 if successful.
+ */
+static int ksz_alloc_desc(struct dev_info *adapter)
+{
+	struct ksz_hw *hw = &adapter->hw;
+	int offset;
+
+	/* Allocate memory for RX & TX descriptors. */
+	adapter->desc_pool.alloc_size =
+		hw->rx_desc_info.size * hw->rx_desc_info.alloc +
+		hw->tx_desc_info.size * hw->tx_desc_info.alloc +
+		DESC_ALIGNMENT;
+
+	adapter->desc_pool.alloc_virt =
+		pci_alloc_consistent(
+			adapter->pdev, adapter->desc_pool.alloc_size,
+			&adapter->desc_pool.dma_addr);
+	if (adapter->desc_pool.alloc_virt == NULL) {
+		adapter->desc_pool.alloc_size = 0;
+		return 1;
+	}
+	memset(adapter->desc_pool.alloc_virt, 0, adapter->desc_pool.alloc_size);
+
+	/* Align to the next cache line boundary. */
+	offset = (((ulong) adapter->desc_pool.alloc_virt % DESC_ALIGNMENT) ?
+		(DESC_ALIGNMENT -
+		((ulong) adapter->desc_pool.alloc_virt % DESC_ALIGNMENT)) : 0);
+	adapter->desc_pool.virt = adapter->desc_pool.alloc_virt + offset;
+	adapter->desc_pool.phys = adapter->desc_pool.dma_addr + offset;
+
+	/* Allocate receive/transmit descriptors. */
+	hw->rx_desc_info.ring_virt = (struct ksz_hw_desc *)
+		adapter->desc_pool.virt;
+	hw->rx_desc_info.ring_phys = adapter->desc_pool.phys;
+	offset = hw->rx_desc_info.alloc * hw->rx_desc_info.size;
+	hw->tx_desc_info.ring_virt = (struct ksz_hw_desc *)
+		(adapter->desc_pool.virt + offset);
+	hw->tx_desc_info.ring_phys = adapter->desc_pool.phys + offset;
+
+	if (ksz_alloc_soft_desc(&hw->rx_desc_info, 0))
+		return 1;
+	if (ksz_alloc_soft_desc(&hw->tx_desc_info, 1))
+		return 1;
+
+	return 0;
+}
+
+/**
+ * free_dma_buf - release DMA buffer resources
+ * @adapter:	Adapter information structure.
+ *
+ * This routine is just a helper function to release the DMA buffer resources.
+ */
+static void free_dma_buf(struct dev_info *adapter, struct ksz_dma_buf *dma_buf,
+	int direction)
+{
+	pci_unmap_single(adapter->pdev, dma_buf->dma, dma_buf->len, direction);
+	dev_kfree_skb(dma_buf->skb);
+	dma_buf->skb = NULL;
+	dma_buf->dma = 0;
+}
+
+/**
+ * ksz_init_rx_buffers - initialize receive descriptors
+ * @adapter:	Adapter information structure.
+ *
+ * This routine initializes DMA buffers for receiving.
+ */
+static void ksz_init_rx_buffers(struct dev_info *adapter)
+{
+	int i;
+	struct ksz_desc *desc;
+	struct ksz_dma_buf *dma_buf;
+	struct ksz_hw *hw = &adapter->hw;
+	struct ksz_desc_info *info = &hw->rx_desc_info;
+
+	for (i = 0; i < hw->rx_desc_info.alloc; i++) {
+		get_rx_pkt(info, &desc);
+
+		dma_buf = DMA_BUFFER(desc);
+		if (dma_buf->skb && dma_buf->len != adapter->mtu)
+			free_dma_buf(adapter, dma_buf, PCI_DMA_FROMDEVICE);
+		dma_buf->len = adapter->mtu;
+		if (!dma_buf->skb)
+			dma_buf->skb = alloc_skb(dma_buf->len, GFP_ATOMIC);
+		if (dma_buf->skb && !dma_buf->dma) {
+			dma_buf->skb->dev = adapter->dev;
+			dma_buf->dma = pci_map_single(
+				adapter->pdev,
+				skb_tail_pointer(dma_buf->skb),
+				dma_buf->len,
+				PCI_DMA_FROMDEVICE);
+		}
+
+		/* Set descriptor. */
+		set_rx_buf(desc, dma_buf->dma);
+		set_rx_len(desc, dma_buf->len);
+		release_desc(desc);
+	}
+}
+
+/**
+ * ksz_alloc_mem - allocate memory for hardware descriptors
+ * @adapter:	Adapter information structure.
+ *
+ * This function allocates memory for use by hardware descriptors for receiving
+ * and transmitting.
+ *
+ * Return 0 if successful.
+ */
+static int ksz_alloc_mem(struct dev_info *adapter)
+{
+	struct ksz_hw *hw = &adapter->hw;
+
+	/* Determine the number of receive and transmit descriptors. */
+	hw->rx_desc_info.alloc = NUM_OF_RX_DESC;
+	hw->tx_desc_info.alloc = NUM_OF_TX_DESC;
+
+	/* Determine how many descriptors to skip transmit interrupt. */
+	hw->tx_int_cnt = 0;
+	hw->tx_int_mask = NUM_OF_TX_DESC / 4;
+	if (hw->tx_int_mask > 8)
+		hw->tx_int_mask = 8;
+	while (hw->tx_int_mask) {
+		hw->tx_int_cnt++;
+		hw->tx_int_mask >>= 1;
+	}
+	if (hw->tx_int_cnt) {
+		hw->tx_int_mask = (1 << (hw->tx_int_cnt - 1)) - 1;
+		hw->tx_int_cnt = 0;
+	}
+
+	/* Determine the descriptor size. */
+	hw->rx_desc_info.size =
+		(((sizeof(struct ksz_hw_desc) + DESC_ALIGNMENT - 1) /
+		DESC_ALIGNMENT) * DESC_ALIGNMENT);
+	hw->tx_desc_info.size =
+		(((sizeof(struct ksz_hw_desc) + DESC_ALIGNMENT - 1) /
+		DESC_ALIGNMENT) * DESC_ALIGNMENT);
+	if (hw->rx_desc_info.size != sizeof(struct ksz_hw_desc))
+		printk(KERN_ALERT
+			"Hardware descriptor size not right!\n");
+	ksz_check_desc_num(&hw->rx_desc_info);
+	ksz_check_desc_num(&hw->tx_desc_info);
+
+	/* Allocate descriptors. */
+	if (ksz_alloc_desc(adapter))
+		return 1;
+
+	return 0;
+}
+
+/**
+ * ksz_free_desc - free software and hardware descriptors
+ * @adapter:	Adapter information structure.
+ *
+ * This local routine frees the software and hardware descriptors allocated by
+ * ksz_alloc_desc().
+ */
+static void ksz_free_desc(struct dev_info *adapter)
+{
+	struct ksz_hw *hw = &adapter->hw;
+
+	/* Reset descriptor. */
+	hw->rx_desc_info.ring_virt = NULL;
+	hw->tx_desc_info.ring_virt = NULL;
+	hw->rx_desc_info.ring_phys = 0;
+	hw->tx_desc_info.ring_phys = 0;
+
+	/* Free memory. */
+	if (adapter->desc_pool.alloc_virt)
+		pci_free_consistent(
+			adapter->pdev,
+			adapter->desc_pool.alloc_size,
+			adapter->desc_pool.alloc_virt,
+			adapter->desc_pool.dma_addr);
+
+	/* Reset resource pool. */
+	adapter->desc_pool.alloc_size = 0;
+	adapter->desc_pool.alloc_virt = NULL;
+
+	kfree(hw->rx_desc_info.ring);
+	hw->rx_desc_info.ring = NULL;
+	kfree(hw->tx_desc_info.ring);
+	hw->tx_desc_info.ring = NULL;
+}
+
+/**
+ * ksz_free_buffers - free buffers used in the descriptors
+ * @adapter:	Adapter information structure.
+ * @desc_info:	Descriptor information structure.
+ *
+ * This local routine frees buffers used in the DMA buffers.
+ */
+static void ksz_free_buffers(struct dev_info *adapter,
+	struct ksz_desc_info *desc_info, int direction)
+{
+	int i;
+	struct ksz_dma_buf *dma_buf;
+	struct ksz_desc *desc = desc_info->ring;
+
+	for (i = 0; i < desc_info->alloc; i++) {
+		dma_buf = DMA_BUFFER(desc);
+		if (dma_buf->skb)
+			free_dma_buf(adapter, dma_buf, direction);
+		desc++;
+	}
+}
+
+/**
+ * ksz_free_mem - free all resources used by descriptors
+ * @adapter:	Adapter information structure.
+ *
+ * This local routine frees all the resources allocated by ksz_alloc_mem().
+ */
+static void ksz_free_mem(struct dev_info *adapter)
+{
+	/* Free transmit buffers. */
+	ksz_free_buffers(adapter, &adapter->hw.tx_desc_info,
+		PCI_DMA_TODEVICE);
+
+	/* Free receive buffers. */
+	ksz_free_buffers(adapter, &adapter->hw.rx_desc_info,
+		PCI_DMA_FROMDEVICE);
+
+	/* Free descriptors. */
+	ksz_free_desc(adapter);
+}
+
+static void get_mib_counters(struct ksz_hw *hw, int first, int cnt,
+	u64 *counter)
+{
+	int i;
+	int mib;
+	int port;
+	struct ksz_port_mib *port_mib;
+
+	memset(counter, 0, sizeof(u64) * TOTAL_PORT_COUNTER_NUM);
+	for (i = 0, port = first; i < cnt; i++, port++) {
+		port_mib = &hw->port_mib[port];
+		for (mib = port_mib->mib_start; mib < hw->mib_cnt; mib++)
+			counter[mib] += port_mib->counter[mib];
+	}
+}
+
+/**
+ * send_packet - send packet
+ * @skb:	Socket buffer.
+ * @dev:	Network device.
+ *
+ * This routine is used to send a packet out to the network.
+ */
+static void send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ksz_desc *desc;
+	struct ksz_desc *first;
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+	struct ksz_desc_info *info = &hw->tx_desc_info;
+	struct ksz_dma_buf *dma_buf;
+	int len;
+	int last_frag = skb_shinfo(skb)->nr_frags;
+
+	/*
+	 * KSZ8842 with multiple device interfaces needs to be told which port
+	 * to send.
+	 */
+	if (hw->dev_count > 1)
+		hw->dst_ports = 1 << priv->port.first_port;
+
+	/* Hardware will pad the length to 60. */
+	len = skb->len;
+
+	/* Remember the very first descriptor. */
+	first = info->cur;
+	desc = first;
+
+	dma_buf = DMA_BUFFER(desc);
+	if (last_frag) {
+		int frag;
+		skb_frag_t *this_frag;
+
+		dma_buf->len = skb->len - skb->data_len;
+
+		dma_buf->dma = pci_map_single(
+			hw_priv->pdev, skb->data, dma_buf->len,
+			PCI_DMA_TODEVICE);
+		set_tx_buf(desc, dma_buf->dma);
+		set_tx_len(desc, dma_buf->len);
+
+		frag = 0;
+		do {
+			this_frag = &skb_shinfo(skb)->frags[frag];
+
+			/* Get a new descriptor. */
+			get_tx_pkt(info, &desc);
+
+			/* Keep track of descriptors used so far. */
+			++hw->tx_int_cnt;
+
+			dma_buf = DMA_BUFFER(desc);
+			dma_buf->len = this_frag->size;
+
+			dma_buf->dma = pci_map_single(
+				hw_priv->pdev,
+				page_address(this_frag->page) +
+				this_frag->page_offset,
+				dma_buf->len,
+				PCI_DMA_TODEVICE);
+			set_tx_buf(desc, dma_buf->dma);
+			set_tx_len(desc, dma_buf->len);
+
+			frag++;
+			if (frag == last_frag)
+				break;
+
+			/* Do not release the last descriptor here. */
+			release_desc(desc);
+		} while (1);
+
+		/* current points to the last descriptor. */
+		info->cur = desc;
+
+		/* Release the first descriptor. */
+		release_desc(first);
+	} else {
+		dma_buf->len = len;
+
+		dma_buf->dma = pci_map_single(
+			hw_priv->pdev, skb->data, dma_buf->len,
+			PCI_DMA_TODEVICE);
+		set_tx_buf(desc, dma_buf->dma);
+		set_tx_len(desc, dma_buf->len);
+	}
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		(desc)->sw.buf.tx.csum_gen_tcp = 1;
+		(desc)->sw.buf.tx.csum_gen_udp = 1;
+	}
+
+	/*
+	 * The last descriptor holds the packet so that it can be returned to
+	 * network subsystem after all descriptors are transmitted.
+	 */
+	dma_buf->skb = skb;
+
+	hw_send_pkt(hw);
+
+	/* Update transmit statistics. */
+	priv->stats.tx_packets++;
+	priv->stats.tx_bytes += len;
+}
+
+/**
+ * transmit_cleanup - clean up transmit descriptors
+ * @dev:	Network device.
+ *
+ * This routine is called to clean up the transmitted buffers.
+ */
+static void transmit_cleanup(struct dev_info *hw_priv, int normal)
+{
+	int last;
+	union desc_stat status;
+	struct ksz_hw *hw = &hw_priv->hw;
+	struct ksz_desc_info *info = &hw->tx_desc_info;
+	struct ksz_desc *desc;
+	struct ksz_dma_buf *dma_buf;
+	struct net_device *dev = NULL;
+
+	spin_lock(&hw_priv->hwlock);
+	last = info->last;
+
+	while (info->avail < info->alloc) {
+		/* Get next descriptor which is not hardware owned. */
+		desc = &info->ring[last];
+		status.data = le32_to_cpu(desc->phw->ctrl.data);
+		if (status.tx.hw_owned) {
+			if (normal)
+				break;
+			else
+				reset_desc(desc, status);
+		}
+
+		dma_buf = DMA_BUFFER(desc);
+		pci_unmap_single(
+			hw_priv->pdev, dma_buf->dma, dma_buf->len,
+			PCI_DMA_TODEVICE);
+
+		/* This descriptor contains the last buffer in the packet. */
+		if (dma_buf->skb) {
+			dev = dma_buf->skb->dev;
+
+			/* Release the packet back to network subsystem. */
+			dev_kfree_skb_irq(dma_buf->skb);
+			dma_buf->skb = NULL;
+		}
+
+		/* Free the transmitted descriptor. */
+		last++;
+		last &= info->mask;
+		info->avail++;
+	}
+	info->last = last;
+	spin_unlock(&hw_priv->hwlock);
+
+	/* Notify the network subsystem that the packet has been sent. */
+	if (dev)
+		dev->trans_start = jiffies;
+}
+
+/**
+ * transmit_done - transmit done processing
+ * @dev:	Network device.
+ *
+ * This routine is called when the transmit interrupt is triggered, indicating
+ * either a packet is sent successfully or there are transmit errors.
+ */
+static void tx_done(struct dev_info *hw_priv)
+{
+	struct ksz_hw *hw = &hw_priv->hw;
+	int port;
+
+	transmit_cleanup(hw_priv, 1);
+
+	for (port = 0; port < hw->dev_count; port++) {
+		struct net_device *dev = hw->port_info[port].pdev;
+
+		if (netif_running(dev) && netif_queue_stopped(dev))
+			netif_wake_queue(dev);
+	}
+}
+
+static inline void copy_old_skb(struct sk_buff *old, struct sk_buff *skb)
+{
+	skb->dev = old->dev;
+	skb->protocol = old->protocol;
+	skb->ip_summed = old->ip_summed;
+	skb->csum = old->csum;
+	skb_set_network_header(skb, ETH_HLEN);
+
+	dev_kfree_skb(old);
+}
+
+/**
+ * netdev_tx - send out packet
+ * @skb:	Socket buffer.
+ * @dev:	Network device.
+ *
+ * This function is used by the upper network layer to send out a packet.
+ *
+ * Return 0 if successful; otherwise an error code indicating failure.
+ */
+static int netdev_tx(struct sk_buff *skb, struct net_device *dev)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+	int left;
+	int num = 1;
+	int rc = 0;
+
+	if (hw->features & SMALL_PACKET_TX_BUG) {
+		struct sk_buff *org_skb = skb;
+
+		if (skb->len <= 48) {
+			if (skb_end_pointer(skb) - skb->data >= 50) {
+				memset(&skb->data[skb->len], 0, 50 - skb->len);
+				skb->len = 50;
+			} else {
+				skb = dev_alloc_skb(50);
+				if (!skb)
+					return NETDEV_TX_BUSY;
+				memcpy(skb->data, org_skb->data, org_skb->len);
+				memset(&skb->data[org_skb->len], 0,
+					50 - org_skb->len);
+				skb->len = 50;
+				copy_old_skb(org_skb, skb);
+			}
+		}
+	}
+
+	spin_lock_irq(&hw_priv->hwlock);
+
+	num = skb_shinfo(skb)->nr_frags + 1;
+	left = hw_alloc_pkt(hw, skb->len, num);
+	if (left) {
+		if (left < num ||
+				((hw->features & IPV6_CSUM_GEN_HACK) &&
+				(CHECKSUM_PARTIAL == skb->ip_summed) &&
+				(ETH_P_IPV6 == htons(skb->protocol)))) {
+			struct sk_buff *org_skb = skb;
+
+			skb = dev_alloc_skb(org_skb->len);
+			if (!skb) {
+				rc = NETDEV_TX_BUSY;
+				goto unlock;
+			}
+			skb_copy_and_csum_dev(org_skb, skb->data);
+			org_skb->ip_summed = 0;
+			skb->len = org_skb->len;
+			copy_old_skb(org_skb, skb);
+		}
+		send_packet(skb, dev);
+		if (left <= num)
+			netif_stop_queue(dev);
+	} else {
+		/* Stop the transmit queue until packet is allocated. */
+		netif_stop_queue(dev);
+		rc = NETDEV_TX_BUSY;
+	}
+unlock:
+	spin_unlock_irq(&hw_priv->hwlock);
+
+	return rc;
+}
+
+/**
+ * netdev_tx_timeout - transmit timeout processing
+ * @dev:	Network device.
+ *
+ * This routine is called when the transmit timer expires.  That indicates the
+ * hardware is not running correctly because transmit interrupts are not
+ * triggered to free up resources so that the transmit routine can continue
+ * sending out packets.  The hardware is reset to correct the problem.
+ */
+static void netdev_tx_timeout(struct net_device *dev)
+{
+	static unsigned long last_reset;
+
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+	int port;
+
+	if (hw->dev_count > 1) {
+		/*
+		 * Only reset the hardware if time between calls is long
+		 * enough.
+		 */
+		if (jiffies - last_reset <= dev->watchdog_timeo)
+			hw_priv = NULL;
+	}
+
+	last_reset = jiffies;
+	if (hw_priv) {
+		hw_dis_intr(hw);
+		hw_disable(hw);
+
+		transmit_cleanup(hw_priv, 0);
+		hw_reset_pkts(&hw->rx_desc_info);
+		hw_reset_pkts(&hw->tx_desc_info);
+		ksz_init_rx_buffers(hw_priv);
+
+		hw_reset(hw);
+
+		hw_set_desc_base(hw,
+			hw->tx_desc_info.ring_phys,
+			hw->rx_desc_info.ring_phys);
+		hw_set_addr(hw);
+		if (hw->all_multi)
+			hw_set_multicast(hw, hw->all_multi);
+		else if (hw->multi_list_size)
+			hw_set_grp_addr(hw);
+
+		if (hw->dev_count > 1) {
+			hw_set_add_addr(hw);
+			for (port = 0; port < SWITCH_PORT_NUM; port++) {
+				struct net_device *port_dev;
+
+				port_set_stp_state(hw, port,
+					STP_STATE_DISABLED);
+
+				port_dev = hw->port_info[port].pdev;
+				if (netif_running(port_dev))
+					port_set_stp_state(hw, port,
+						STP_STATE_SIMPLE);
+			}
+		}
+
+		hw_enable(hw);
+		hw_ena_intr(hw);
+	}
+
+	dev->trans_start = jiffies;
+	netif_wake_queue(dev);
+}
+
+static inline void csum_verified(struct sk_buff *skb)
+{
+	unsigned short protocol;
+	struct iphdr *iph;
+
+	protocol = skb->protocol;
+	skb_reset_network_header(skb);
+	iph = (struct iphdr *) skb_network_header(skb);
+	if (protocol == htons(ETH_P_8021Q)) {
+		protocol = iph->tot_len;
+		skb_set_network_header(skb, VLAN_HLEN);
+		iph = (struct iphdr *) skb_network_header(skb);
+	}
+	if (protocol == htons(ETH_P_IP)) {
+		if (iph->protocol == IPPROTO_TCP)
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+	}
+}
+
+static inline int rx_proc(struct net_device *dev, struct ksz_hw* hw,
+	struct ksz_desc *desc, union desc_stat status)
+{
+	int packet_len;
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_dma_buf *dma_buf;
+	struct sk_buff *skb;
+	int rx_status;
+
+	/* Received length includes 4-byte CRC. */
+	packet_len = status.rx.frame_len - 4;
+
+	dma_buf = DMA_BUFFER(desc);
+	pci_dma_sync_single_for_cpu(
+		hw_priv->pdev, dma_buf->dma, packet_len + 4,
+		PCI_DMA_FROMDEVICE);
+
+	do {
+		/* skb->data != skb->head */
+		skb = dev_alloc_skb(packet_len + 2);
+		if (!skb) {
+			priv->stats.rx_dropped++;
+			return -ENOMEM;
+		}
+
+		/*
+		 * Align socket buffer in 4-byte boundary for better
+		 * performance.
+		 */
+		skb_reserve(skb, 2);
+
+		memcpy(skb_put(skb, packet_len),
+			dma_buf->skb->data, packet_len);
+	} while (0);
+
+	skb->dev = dev;
+
+	skb->protocol = eth_type_trans(skb, dev);
+
+	if (hw->rx_cfg & (DMA_RX_CSUM_UDP | DMA_RX_CSUM_TCP))
+		csum_verified(skb);
+
+	/* Update receive statistics. */
+	priv->stats.rx_packets++;
+	priv->stats.rx_bytes += packet_len;
+
+	/* Notify upper layer for received packet. */
+	dev->last_rx = jiffies;
+
+	rx_status = netif_rx(skb);
+
+	return 0;
+}
+
+static int dev_rcv_packets(struct dev_info *hw_priv)
+{
+	int next;
+	union desc_stat status;
+	struct ksz_hw *hw = &hw_priv->hw;
+	struct net_device *dev = hw->port_info[0].pdev;
+	struct ksz_desc_info *info = &hw->rx_desc_info;
+	int left = info->alloc;
+	struct ksz_desc *desc;
+	int received = 0;
+
+	next = info->next;
+	while (left--) {
+		/* Get next descriptor which is not hardware owned. */
+		desc = &info->ring[next];
+		status.data = le32_to_cpu(desc->phw->ctrl.data);
+		if (status.rx.hw_owned)
+			break;
+
+		/* Status valid only when last descriptor bit is set. */
+		if (status.rx.last_desc && status.rx.first_desc) {
+			if (rx_proc(dev, hw, desc, status))
+				goto release_packet;
+			received++;
+		}
+
+release_packet:
+		release_desc(desc);
+		next++;
+		next &= info->mask;
+	}
+	info->next = next;
+
+	return received;
+}
+
+static int port_rcv_packets(struct dev_info *hw_priv)
+{
+	int next;
+	union desc_stat status;
+	struct ksz_hw *hw = &hw_priv->hw;
+	struct net_device *dev = hw->port_info[0].pdev;
+	struct ksz_desc_info *info = &hw->rx_desc_info;
+	int left = info->alloc;
+	struct ksz_desc *desc;
+	int received = 0;
+
+	next = info->next;
+	while (left--) {
+		/* Get next descriptor which is not hardware owned. */
+		desc = &info->ring[next];
+		status.data = le32_to_cpu(desc->phw->ctrl.data);
+		if (status.rx.hw_owned)
+			break;
+
+		if (hw->dev_count > 1) {
+			/* Get received port number. */
+			int p = HW_TO_DEV_PORT(status.rx.src_port);
+
+			dev = hw->port_info[p].pdev;
+			if (!netif_running(dev))
+				goto release_packet;
+		}
+
+		/* Status valid only when last descriptor bit is set. */
+		if (status.rx.last_desc && status.rx.first_desc) {
+			if (rx_proc(dev, hw, desc, status))
+				goto release_packet;
+			received++;
+		}
+
+release_packet:
+		release_desc(desc);
+		next++;
+		next &= info->mask;
+	}
+	info->next = next;
+
+	return received;
+}
+
+static int dev_rcv_special(struct dev_info *hw_priv)
+{
+	int next;
+	union desc_stat status;
+	struct ksz_hw *hw = &hw_priv->hw;
+	struct net_device *dev = hw->port_info[0].pdev;
+	struct ksz_desc_info *info = &hw->rx_desc_info;
+	int left = info->alloc;
+	struct ksz_desc *desc;
+	int received = 0;
+
+	next = info->next;
+	while (left--) {
+		/* Get next descriptor which is not hardware owned. */
+		desc = &info->ring[next];
+		status.data = le32_to_cpu(desc->phw->ctrl.data);
+		if (status.rx.hw_owned)
+			break;
+
+		if (hw->dev_count > 1) {
+			/* Get received port number. */
+			int p = HW_TO_DEV_PORT(status.rx.src_port);
+
+			dev = hw->port_info[p].pdev;
+			if (!netif_running(dev))
+				goto release_packet;
+		}
+
+		/* Status valid only when last descriptor bit is set. */
+		if (status.rx.last_desc && status.rx.first_desc) {
+			/*
+			 * Receive without error.  With receive errors
+			 * disabled, packets with receive errors will be
+			 * dropped, so no need to check the error bit.
+			 */
+			if (!status.rx.error || (status.data &
+					KS_DESC_RX_ERROR_COND) ==
+					KS_DESC_RX_ERROR_TOO_LONG) {
+				if (rx_proc(dev, hw, desc, status))
+					goto release_packet;
+				received++;
+			} else {
+				struct dev_priv *priv = netdev_priv(dev);
+
+				/* Update receive error statistics. */
+				priv->port.counter[OID_COUNTER_RCV_ERROR]++;
+			}
+		}
+
+release_packet:
+		release_desc(desc);
+		next++;
+		next &= info->mask;
+	}
+	info->next = next;
+
+	return received;
+}
+
+static void rx_proc_task(unsigned long data)
+{
+	struct dev_info *hw_priv = (struct dev_info *) data;
+	struct ksz_hw *hw = &hw_priv->hw;
+
+	if (!hw->enabled)
+		return;
+	if (unlikely(!hw_priv->dev_rcv(hw_priv))) {
+
+		/* In case receive process is suspended because of overrun. */
+		hw_resume_rx(hw);
+
+		/* tasklets are interruptible. */
+		spin_lock_irq(&hw_priv->hwlock);
+		hw_turn_on_intr(hw, KS884X_INT_RX_MASK);
+		spin_unlock_irq(&hw_priv->hwlock);
+	} else {
+		hw_ack_intr(hw, KS884X_INT_RX);
+		tasklet_schedule(&hw_priv->rx_tasklet);
+	}
+}
+
+static void tx_proc_task(unsigned long data)
+{
+	struct dev_info *hw_priv = (struct dev_info *) data;
+	struct ksz_hw *hw = &hw_priv->hw;
+
+	hw_ack_intr(hw, KS884X_INT_TX_MASK);
+
+	tx_done(hw_priv);
+
+	/* tasklets are interruptible. */
+	spin_lock_irq(&hw_priv->hwlock);
+	hw_turn_on_intr(hw, KS884X_INT_TX);
+	spin_unlock_irq(&hw_priv->hwlock);
+}
+
+static inline void handle_rx_stop(struct ksz_hw *hw)
+{
+	/* Receive just has been stopped. */
+	if (0 == hw->rx_stop)
+		hw->intr_mask &= ~KS884X_INT_RX_STOPPED;
+	else if (hw->rx_stop > 1) {
+		if (hw->enabled && (hw->rx_cfg & DMA_RX_ENABLE)) {
+			hw_start_rx(hw);
+		} else {
+			hw->intr_mask &= ~KS884X_INT_RX_STOPPED;
+			hw->rx_stop = 0;
+		}
+	} else
+		/* Receive just has been started. */
+		hw->rx_stop++;
+}
+
+/**
+ * netdev_intr - interrupt handling
+ * @irq:	Interrupt number.
+ * @dev_id:	Network device.
+ *
+ * This function is called by upper network layer to signal interrupt.
+ *
+ * Return IRQ_HANDLED if interrupt is handled.
+ */
+static irqreturn_t netdev_intr(int irq, void *dev_id)
+{
+	uint int_enable = 0;
+	struct net_device *dev = (struct net_device *) dev_id;
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+
+	hw_read_intr(hw, &int_enable);
+
+	/* Not our interrupt! */
+	if (!int_enable)
+		return IRQ_NONE;
+
+	do {
+		hw_ack_intr(hw, int_enable);
+		int_enable &= hw->intr_mask;
+
+		if (unlikely(int_enable & KS884X_INT_TX_MASK)) {
+			hw_dis_intr_bit(hw, KS884X_INT_TX_MASK);
+			tasklet_schedule(&hw_priv->tx_tasklet);
+		}
+
+		if (likely(int_enable & KS884X_INT_RX)) {
+			hw_dis_intr_bit(hw, KS884X_INT_RX);
+			tasklet_schedule(&hw_priv->rx_tasklet);
+		}
+
+		if (unlikely(int_enable & KS884X_INT_RX_OVERRUN)) {
+			priv->stats.rx_fifo_errors++;
+			hw_resume_rx(hw);
+		}
+
+		if (unlikely(int_enable & KS884X_INT_PHY)) {
+			struct ksz_port *port = &priv->port;
+
+			hw->features |= LINK_INT_WORKING;
+			port_get_link_speed(port);
+		}
+
+		if (unlikely(int_enable & KS884X_INT_RX_STOPPED)) {
+			handle_rx_stop(hw);
+			break;
+		}
+
+		if (unlikely(int_enable & KS884X_INT_TX_STOPPED)) {
+			u32 data;
+
+			hw->intr_mask &= ~KS884X_INT_TX_STOPPED;
+			printk(KERN_INFO "Tx stopped\n");
+			data = readl(hw->io + KS_DMA_TX_CTRL);
+			if (!(data & DMA_TX_ENABLE))
+				printk(KERN_INFO "Tx disabled\n");
+			break;
+		}
+	} while (0);
+
+	hw_ena_intr(hw);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * Linux network device functions
+ */
+
+static unsigned long next_jiffies;
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void netdev_netpoll(struct net_device *dev)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+
+	hw_dis_intr(&hw_priv->hw);
+	netdev_intr(dev->irq, dev);
+}
+#endif
+
+static void bridge_change(struct ksz_hw *hw)
+{
+	int port;
+	u8  member;
+	struct ksz_switch *sw = hw->ksz_switch;
+
+	/* No ports in forwarding state. */
+	if (!sw->member) {
+		port_set_stp_state(hw, SWITCH_PORT_NUM, STP_STATE_SIMPLE);
+		sw_block_addr(hw);
+	}
+	for (port = 0; port < SWITCH_PORT_NUM; port++) {
+		if (STP_STATE_FORWARDING == sw->port_cfg[port].stp_state)
+			member = HOST_MASK | sw->member;
+		else
+			member = HOST_MASK | (1 << port);
+		if (member != sw->port_cfg[port].member)
+			sw_cfg_port_base_vlan(hw, port, member);
+	}
+}
+
+/**
+ * netdev_close - close network device
+ * @dev:	Network device.
+ *
+ * This function process the close operation of network device.  This is caused
+ * by the user command "ifconfig ethX down."
+ *
+ * Return 0 if successful; otherwise an error code indicating failure.
+ */
+static int netdev_close(struct net_device *dev)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_port *port = &priv->port;
+	struct ksz_hw *hw = &hw_priv->hw;
+	int pi;
+
+	netif_stop_queue(dev);
+
+	ksz_stop_timer(&priv->monitor_timer_info);
+
+	/* Need to shut the port manually in multiple device interfaces mode. */
+	if (hw->dev_count > 1) {
+		port_set_stp_state(hw, port->first_port, STP_STATE_DISABLED);
+
+		/* Port is closed.  Need to change bridge setting. */
+		if (hw->features & STP_SUPPORT) {
+			pi = 1 << port->first_port;
+			if (hw->ksz_switch->member & pi) {
+				hw->ksz_switch->member &= ~pi;
+				bridge_change(hw);
+			}
+		}
+	}
+	if (port->first_port > 0)
+		hw_del_addr(hw, dev->dev_addr);
+	if (!hw_priv->wol_enable)
+		port_set_power_saving(port, true);
+
+	if (priv->multicast)
+		--hw->all_multi;
+	if (priv->promiscuous)
+		--hw->promiscuous;
+
+	hw_priv->opened--;
+	if (!(hw_priv->opened)) {
+		ksz_stop_timer(&hw_priv->mib_timer_info);
+		flush_work(&hw_priv->mib_read);
+
+		hw_dis_intr(hw);
+		hw_disable(hw);
+		hw_clr_multicast(hw);
+
+		/* Delay for receive task to stop scheduling itself. */
+		msleep(2000 / HZ);
+
+		tasklet_disable(&hw_priv->rx_tasklet);
+		tasklet_disable(&hw_priv->tx_tasklet);
+		free_irq(dev->irq, hw_priv->dev);
+
+		transmit_cleanup(hw_priv, 0);
+		hw_reset_pkts(&hw->rx_desc_info);
+		hw_reset_pkts(&hw->tx_desc_info);
+
+		/* Clean out static MAC table when the switch is shutdown. */
+		if (hw->features & STP_SUPPORT)
+			sw_clr_sta_mac_table(hw);
+	}
+
+	return 0;
+}
+
+static void hw_cfg_huge_frame(struct dev_info *hw_priv, struct ksz_hw *hw)
+{
+	if (hw->ksz_switch) {
+		u32 data;
+
+		data = readw(hw->io + KS8842_SWITCH_CTRL_2_OFFSET);
+		if (hw->features & RX_HUGE_FRAME)
+			data |= SWITCH_HUGE_PACKET;
+		else
+			data &= ~SWITCH_HUGE_PACKET;
+		writew(data, hw->io + KS8842_SWITCH_CTRL_2_OFFSET);
+	}
+	if (hw->features & RX_HUGE_FRAME) {
+		hw->rx_cfg |= DMA_RX_ERROR;
+		hw_priv->dev_rcv = dev_rcv_special;
+	} else {
+		hw->rx_cfg &= ~DMA_RX_ERROR;
+		if (hw->dev_count > 1)
+			hw_priv->dev_rcv = port_rcv_packets;
+		else
+			hw_priv->dev_rcv = dev_rcv_packets;
+	}
+}
+
+static int prepare_hardware(struct net_device *dev)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+	int rc = 0;
+
+	/* Remember the network device that requests interrupts. */
+	hw_priv->dev = dev;
+	rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev);
+	if (rc)
+		return rc;
+	tasklet_enable(&hw_priv->rx_tasklet);
+	tasklet_enable(&hw_priv->tx_tasklet);
+
+	hw->promiscuous = 0;
+	hw->all_multi = 0;
+	hw->multi_list_size = 0;
+
+	hw_reset(hw);
+
+	hw_set_desc_base(hw,
+		hw->tx_desc_info.ring_phys, hw->rx_desc_info.ring_phys);
+	hw_set_addr(hw);
+	hw_cfg_huge_frame(hw_priv, hw);
+	ksz_init_rx_buffers(hw_priv);
+	return 0;
+}
+
+/**
+ * netdev_open - open network device
+ * @dev:	Network device.
+ *
+ * This function process the open operation of network device.  This is caused
+ * by the user command "ifconfig ethX up."
+ *
+ * Return 0 if successful; otherwise an error code indicating failure.
+ */
+static int netdev_open(struct net_device *dev)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+	struct ksz_port *port = &priv->port;
+	int i;
+	int p;
+	int rc = 0;
+
+	priv->multicast = 0;
+	priv->promiscuous = 0;
+
+	/* Reset device statistics. */
+	memset(&priv->stats, 0, sizeof(struct net_device_stats));
+	memset((void *) port->counter, 0,
+		(sizeof(u64) * OID_COUNTER_LAST));
+
+	if (!(hw_priv->opened)) {
+		rc = prepare_hardware(dev);
+		if (rc)
+			return rc;
+		for (i = 0; i < hw->mib_port_cnt; i++) {
+			if (next_jiffies < jiffies)
+				next_jiffies = jiffies + HZ * 2;
+			else
+				next_jiffies += HZ * 1;
+			hw_priv->counter[i].time = next_jiffies;
+			hw->port_mib[i].state = media_disconnected;
+			port_init_cnt(hw, i);
+		}
+		if (hw->ksz_switch)
+			hw->port_mib[HOST_PORT].state = media_connected;
+		else {
+			hw_add_wol_bcast(hw);
+			hw_cfg_wol_pme(hw, 0);
+			hw_clr_wol_pme_status(&hw_priv->hw);
+		}
+	}
+	port_set_power_saving(port, false);
+
+	for (i = 0, p = port->first_port; i < port->port_cnt; i++, p++) {
+		/*
+		 * Initialize to invalid value so that link detection
+		 * is done.
+		 */
+		hw->port_info[p].partner = 0xFF;
+		hw->port_info[p].state = media_disconnected;
+	}
+
+	/* Need to open the port in multiple device interfaces mode. */
+	if (hw->dev_count > 1) {
+		port_set_stp_state(hw, port->first_port, STP_STATE_SIMPLE);
+		if (port->first_port > 0)
+			hw_add_addr(hw, dev->dev_addr);
+	}
+
+	port_get_link_speed(port);
+	if (port->force_link)
+		port_force_link_speed(port);
+	else
+		port_set_link_speed(port);
+
+	if (!(hw_priv->opened)) {
+		hw_setup_intr(hw);
+		hw_enable(hw);
+		hw_ena_intr(hw);
+
+		if (hw->mib_port_cnt)
+			ksz_start_timer(&hw_priv->mib_timer_info,
+				hw_priv->mib_timer_info.period);
+	}
+
+	hw_priv->opened++;
+
+	ksz_start_timer(&priv->monitor_timer_info,
+		priv->monitor_timer_info.period);
+
+	priv->media_state = port->linked->state;
+
+	if (media_connected == priv->media_state)
+		netif_carrier_on(dev);
+	else
+		netif_carrier_off(dev);
+	if (netif_msg_link(priv))
+		printk(KERN_INFO "%s link %s\n", dev->name,
+			(media_connected == priv->media_state ?
+			"on" : "off"));
+
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+/* RX errors = rx_errors */
+/* RX dropped = rx_dropped */
+/* RX overruns = rx_fifo_errors */
+/* RX frame = rx_crc_errors + rx_frame_errors + rx_length_errors */
+/* TX errors = tx_errors */
+/* TX dropped = tx_dropped */
+/* TX overruns = tx_fifo_errors */
+/* TX carrier = tx_aborted_errors + tx_carrier_errors + tx_window_errors */
+/* collisions = collisions */
+
+/**
+ * netdev_query_statistics - query network device statistics
+ * @dev:	Network device.
+ *
+ * This function returns the statistics of the network device.  The device
+ * needs not be opened.
+ *
+ * Return network device statistics.
+ */
+static struct net_device_stats *netdev_query_statistics(struct net_device *dev)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct ksz_port *port = &priv->port;
+	struct ksz_hw *hw = &priv->adapter->hw;
+	struct ksz_port_mib *mib;
+	int i;
+	int p;
+
+	priv->stats.rx_errors = port->counter[OID_COUNTER_RCV_ERROR];
+	priv->stats.tx_errors = port->counter[OID_COUNTER_XMIT_ERROR];
+
+	/* Reset to zero to add count later. */
+	priv->stats.multicast = 0;
+	priv->stats.collisions = 0;
+	priv->stats.rx_length_errors = 0;
+	priv->stats.rx_crc_errors = 0;
+	priv->stats.rx_frame_errors = 0;
+	priv->stats.tx_window_errors = 0;
+
+	for (i = 0, p = port->first_port; i < port->mib_port_cnt; i++, p++) {
+		mib = &hw->port_mib[p];
+
+		priv->stats.multicast += (unsigned long)
+			mib->counter[MIB_COUNTER_RX_MULTICAST];
+
+		priv->stats.collisions += (unsigned long)
+			mib->counter[MIB_COUNTER_TX_TOTAL_COLLISION];
+
+		priv->stats.rx_length_errors += (unsigned long)(
+			mib->counter[MIB_COUNTER_RX_UNDERSIZE] +
+			mib->counter[MIB_COUNTER_RX_FRAGMENT] +
+			mib->counter[MIB_COUNTER_RX_OVERSIZE] +
+			mib->counter[MIB_COUNTER_RX_JABBER]);
+		priv->stats.rx_crc_errors += (unsigned long)
+			mib->counter[MIB_COUNTER_RX_CRC_ERR];
+		priv->stats.rx_frame_errors += (unsigned long)(
+			mib->counter[MIB_COUNTER_RX_ALIGNMENT_ERR] +
+			mib->counter[MIB_COUNTER_RX_SYMBOL_ERR]);
+
+		priv->stats.tx_window_errors += (unsigned long)
+			mib->counter[MIB_COUNTER_TX_LATE_COLLISION];
+	}
+
+	return &priv->stats;
+}
+
+/**
+ * netdev_set_mac_address - set network device MAC address
+ * @dev:	Network device.
+ * @addr:	Buffer of MAC address.
+ *
+ * This function is used to set the MAC address of the network device.
+ *
+ * Return 0 to indicate success.
+ */
+static int netdev_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+	struct sockaddr *mac = addr;
+	uint interrupt;
+
+	if (priv->port.first_port > 0)
+		hw_del_addr(hw, dev->dev_addr);
+	else {
+		hw->mac_override = 1;
+		memcpy(hw->override_addr, mac->sa_data, MAC_ADDR_LEN);
+	}
+
+	memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN);
+
+	interrupt = hw_block_intr(hw);
+
+	if (priv->port.first_port > 0)
+		hw_add_addr(hw, dev->dev_addr);
+	else
+		hw_set_addr(hw);
+	hw_restore_intr(hw, interrupt);
+
+	return 0;
+}
+
+static void dev_set_promiscuous(struct net_device *dev, struct dev_priv *priv,
+	struct ksz_hw *hw, int promiscuous)
+{
+	if (promiscuous != priv->promiscuous) {
+		u8 prev_state = hw->promiscuous;
+
+		if (promiscuous)
+			++hw->promiscuous;
+		else
+			--hw->promiscuous;
+		priv->promiscuous = promiscuous;
+
+		/* Turn on/off promiscuous mode. */
+		if (hw->promiscuous <= 1 && prev_state <= 1)
+			hw_set_promiscuous(hw, hw->promiscuous);
+
+		/*
+		 * Port is not in promiscuous mode, meaning it is released
+		 * from the bridge.
+		 */
+		if ((hw->features & STP_SUPPORT) && !promiscuous &&
+				dev->br_port) {
+			struct ksz_switch *sw = hw->ksz_switch;
+			int port = priv->port.first_port;
+
+			port_set_stp_state(hw, port, STP_STATE_DISABLED);
+			port = 1 << port;
+			if (sw->member & port) {
+				sw->member &= ~port;
+				bridge_change(hw);
+			}
+		}
+	}
+}
+
+static void dev_set_multicast(struct dev_priv *priv, struct ksz_hw *hw,
+	int multicast)
+{
+	if (multicast != priv->multicast) {
+		u8 all_multi = hw->all_multi;
+
+		if (multicast)
+			++hw->all_multi;
+		else
+			--hw->all_multi;
+		priv->multicast = multicast;
+
+		/* Turn on/off all multicast mode. */
+		if (hw->all_multi <= 1 && all_multi <= 1)
+			hw_set_multicast(hw, hw->all_multi);
+	}
+}
+
+/**
+ * netdev_set_rx_mode
+ * @dev:	Network device.
+ *
+ * This routine is used to set multicast addresses or put the network device
+ * into promiscuous mode.
+ */
+static void netdev_set_rx_mode(struct net_device *dev)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+	struct dev_mc_list *mc_ptr;
+	int multicast = (dev->flags & IFF_ALLMULTI);
+
+	dev_set_promiscuous(dev, priv, hw, (dev->flags & IFF_PROMISC));
+
+	if (hw_priv->hw.dev_count > 1)
+		multicast |= (dev->flags & IFF_MULTICAST);
+	dev_set_multicast(priv, hw, multicast);
+
+	/* Cannot use different hashes in multiple device interfaces mode. */
+	if (hw_priv->hw.dev_count > 1)
+		return;
+
+	if ((dev->flags & IFF_MULTICAST) && !netdev_mc_empty(dev)) {
+		int i = 0;
+
+		/* List too big to support so turn on all multicast mode. */
+		if (dev->mc_count > MAX_MULTICAST_LIST) {
+			if (MAX_MULTICAST_LIST != hw->multi_list_size) {
+				hw->multi_list_size = MAX_MULTICAST_LIST;
+				++hw->all_multi;
+				hw_set_multicast(hw, hw->all_multi);
+			}
+			return;
+		}
+
+		netdev_for_each_mc_addr(mc_ptr, dev) {
+			if (!(*mc_ptr->dmi_addr & 1))
+				continue;
+			if (i >= MAX_MULTICAST_LIST)
+				break;
+			memcpy(hw->multi_list[i++], mc_ptr->dmi_addr,
+				MAC_ADDR_LEN);
+		}
+		hw->multi_list_size = (u8) i;
+		hw_set_grp_addr(hw);
+	} else {
+		if (MAX_MULTICAST_LIST == hw->multi_list_size) {
+			--hw->all_multi;
+			hw_set_multicast(hw, hw->all_multi);
+		}
+		hw->multi_list_size = 0;
+		hw_clr_multicast(hw);
+	}
+}
+
+static int netdev_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+	int hw_mtu;
+
+	if (netif_running(dev))
+		return -EBUSY;
+
+	/* Cannot use different MTU in multiple device interfaces mode. */
+	if (hw->dev_count > 1)
+		if (dev != hw_priv->dev)
+			return 0;
+	if (new_mtu < 60)
+		return -EINVAL;
+
+	if (dev->mtu != new_mtu) {
+		hw_mtu = new_mtu + ETHERNET_HEADER_SIZE + 4;
+		if (hw_mtu > MAX_RX_BUF_SIZE)
+			return -EINVAL;
+		if (hw_mtu > REGULAR_RX_BUF_SIZE) {
+			hw->features |= RX_HUGE_FRAME;
+			hw_mtu = MAX_RX_BUF_SIZE;
+		} else {
+			hw->features &= ~RX_HUGE_FRAME;
+			hw_mtu = REGULAR_RX_BUF_SIZE;
+		}
+		hw_mtu = (hw_mtu + 3) & ~3;
+		hw_priv->mtu = hw_mtu;
+		dev->mtu = new_mtu;
+	}
+	return 0;
+}
+
+/**
+ * netdev_ioctl - I/O control processing
+ * @dev:	Network device.
+ * @ifr:	Interface request structure.
+ * @cmd:	I/O control code.
+ *
+ * This function is used to process I/O control calls.
+ *
+ * Return 0 to indicate success.
+ */
+static int netdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+	struct ksz_port *port = &priv->port;
+	int rc;
+	int result = 0;
+	struct mii_ioctl_data *data = if_mii(ifr);
+
+	if (down_interruptible(&priv->proc_sem))
+		return -ERESTARTSYS;
+
+	/* assume success */
+	rc = 0;
+	switch (cmd) {
+	/* Get address of MII PHY in use. */
+	case SIOCGMIIPHY:
+		data->phy_id = priv->id;
+
+		/* Fallthrough... */
+
+	/* Read MII PHY register. */
+	case SIOCGMIIREG:
+		if (data->phy_id != priv->id || data->reg_num >= 6)
+			result = -EIO;
+		else
+			hw_r_phy(hw, port->linked->port_id, data->reg_num,
+				&data->val_out);
+		break;
+
+	/* Write MII PHY register. */
+	case SIOCSMIIREG:
+		if (!capable(CAP_NET_ADMIN))
+			result = -EPERM;
+		else if (data->phy_id != priv->id || data->reg_num >= 6)
+			result = -EIO;
+		else
+			hw_w_phy(hw, port->linked->port_id, data->reg_num,
+				data->val_in);
+		break;
+
+	default:
+		result = -EOPNOTSUPP;
+	}
+
+	up(&priv->proc_sem);
+
+	return result;
+}
+
+/*
+ * MII support
+ */
+
+/**
+ * mdio_read - read PHY register
+ * @dev:	Network device.
+ * @phy_id:	The PHY id.
+ * @reg_num:	The register number.
+ *
+ * This function returns the PHY register value.
+ *
+ * Return the register value.
+ */
+static int mdio_read(struct net_device *dev, int phy_id, int reg_num)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct ksz_port *port = &priv->port;
+	struct ksz_hw *hw = port->hw;
+	u16 val_out;
+
+	hw_r_phy(hw, port->linked->port_id, reg_num << 1, &val_out);
+	return val_out;
+}
+
+/**
+ * mdio_write - set PHY register
+ * @dev:	Network device.
+ * @phy_id:	The PHY id.
+ * @reg_num:	The register number.
+ * @val:	The register value.
+ *
+ * This procedure sets the PHY register value.
+ */
+static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct ksz_port *port = &priv->port;
+	struct ksz_hw *hw = port->hw;
+	int i;
+	int pi;
+
+	for (i = 0, pi = port->first_port; i < port->port_cnt; i++, pi++)
+		hw_w_phy(hw, pi, reg_num << 1, val);
+}
+
+/*
+ * ethtool support
+ */
+
+#define EEPROM_SIZE			0x40
+
+static u16 eeprom_data[EEPROM_SIZE] = { 0 };
+
+#define ADVERTISED_ALL			\
+	(ADVERTISED_10baseT_Half |	\
+	ADVERTISED_10baseT_Full |	\
+	ADVERTISED_100baseT_Half |	\
+	ADVERTISED_100baseT_Full)
+
+/* These functions use the MII functions in mii.c. */
+
+/**
+ * netdev_get_settings - get network device settings
+ * @dev:	Network device.
+ * @cmd:	Ethtool command.
+ *
+ * This function queries the PHY and returns its state in the ethtool command.
+ *
+ * Return 0 if successful; otherwise an error code.
+ */
+static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+
+	mutex_lock(&hw_priv->lock);
+	mii_ethtool_gset(&priv->mii_if, cmd);
+	cmd->advertising |= SUPPORTED_TP;
+	mutex_unlock(&hw_priv->lock);
+
+	/* Save advertised settings for workaround in next function. */
+	priv->advertising = cmd->advertising;
+	return 0;
+}
+
+/**
+ * netdev_set_settings - set network device settings
+ * @dev:	Network device.
+ * @cmd:	Ethtool command.
+ *
+ * This function sets the PHY according to the ethtool command.
+ *
+ * Return 0 if successful; otherwise an error code.
+ */
+static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_port *port = &priv->port;
+	int rc;
+
+	/*
+	 * ethtool utility does not change advertised setting if auto
+	 * negotiation is not specified explicitly.
+	 */
+	if (cmd->autoneg && priv->advertising == cmd->advertising) {
+		cmd->advertising |= ADVERTISED_ALL;
+		if (10 == cmd->speed)
+			cmd->advertising &=
+				~(ADVERTISED_100baseT_Full |
+				ADVERTISED_100baseT_Half);
+		else if (100 == cmd->speed)
+			cmd->advertising &=
+				~(ADVERTISED_10baseT_Full |
+				ADVERTISED_10baseT_Half);
+		if (0 == cmd->duplex)
+			cmd->advertising &=
+				~(ADVERTISED_100baseT_Full |
+				ADVERTISED_10baseT_Full);
+		else if (1 == cmd->duplex)
+			cmd->advertising &=
+				~(ADVERTISED_100baseT_Half |
+				ADVERTISED_10baseT_Half);
+	}
+	mutex_lock(&hw_priv->lock);
+	if (cmd->autoneg &&
+			(cmd->advertising & ADVERTISED_ALL) ==
+			ADVERTISED_ALL) {
+		port->duplex = 0;
+		port->speed = 0;
+		port->force_link = 0;
+	} else {
+		port->duplex = cmd->duplex + 1;
+		if (cmd->speed != 1000)
+			port->speed = cmd->speed;
+		if (cmd->autoneg)
+			port->force_link = 0;
+		else
+			port->force_link = 1;
+	}
+	rc = mii_ethtool_sset(&priv->mii_if, cmd);
+	mutex_unlock(&hw_priv->lock);
+	return rc;
+}
+
+/**
+ * netdev_nway_reset - restart auto-negotiation
+ * @dev:	Network device.
+ *
+ * This function restarts the PHY for auto-negotiation.
+ *
+ * Return 0 if successful; otherwise an error code.
+ */
+static int netdev_nway_reset(struct net_device *dev)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	int rc;
+
+	mutex_lock(&hw_priv->lock);
+	rc = mii_nway_restart(&priv->mii_if);
+	mutex_unlock(&hw_priv->lock);
+	return rc;
+}
+
+/**
+ * netdev_get_link - get network device link status
+ * @dev:	Network device.
+ *
+ * This function gets the link status from the PHY.
+ *
+ * Return true if PHY is linked and false otherwise.
+ */
+static u32 netdev_get_link(struct net_device *dev)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	int rc;
+
+	rc = mii_link_ok(&priv->mii_if);
+	return rc;
+}
+
+/**
+ * netdev_get_drvinfo - get network driver information
+ * @dev:	Network device.
+ * @info:	Ethtool driver info data structure.
+ *
+ * This procedure returns the driver information.
+ */
+static void netdev_get_drvinfo(struct net_device *dev,
+	struct ethtool_drvinfo *info)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+
+	strcpy(info->driver, DRV_NAME);
+	strcpy(info->version, DRV_VERSION);
+	strcpy(info->bus_info, pci_name(hw_priv->pdev));
+}
+
+/**
+ * netdev_get_regs_len - get length of register dump
+ * @dev:	Network device.
+ *
+ * This function returns the length of the register dump.
+ *
+ * Return length of the register dump.
+ */
+static struct hw_regs {
+	int start;
+	int end;
+} hw_regs_range[] = {
+	{ KS_DMA_TX_CTRL,	KS884X_INTERRUPTS_STATUS },
+	{ KS_ADD_ADDR_0_LO,	KS_ADD_ADDR_F_HI },
+	{ KS884X_ADDR_0_OFFSET,	KS8841_WOL_FRAME_BYTE2_OFFSET },
+	{ KS884X_SIDER_P,	KS8842_SGCR7_P },
+	{ KS8842_MACAR1_P,	KS8842_TOSR8_P },
+	{ KS884X_P1MBCR_P,	KS8842_P3ERCR_P },
+	{ 0, 0 }
+};
+
+static int netdev_get_regs_len(struct net_device *dev)
+{
+	struct hw_regs *range = hw_regs_range;
+	int regs_len = 0x10 * sizeof(u32);
+
+	while (range->end > range->start) {
+		regs_len += (range->end - range->start + 3) / 4 * 4;
+		range++;
+	}
+	return regs_len;
+}
+
+/**
+ * netdev_get_regs - get register dump
+ * @dev:	Network device.
+ * @regs:	Ethtool registers data structure.
+ * @ptr:	Buffer to store the register values.
+ *
+ * This procedure dumps the register values in the provided buffer.
+ */
+static void netdev_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+	void *ptr)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+	int *buf = (int *) ptr;
+	struct hw_regs *range = hw_regs_range;
+	int len;
+
+	mutex_lock(&hw_priv->lock);
+	regs->version = 0;
+	for (len = 0; len < 0x40; len += 4) {
+		pci_read_config_dword(hw_priv->pdev, len, buf);
+		buf++;
+	}
+	while (range->end > range->start) {
+		for (len = range->start; len < range->end; len += 4) {
+			*buf = readl(hw->io + len);
+			buf++;
+		}
+		range++;
+	}
+	mutex_unlock(&hw_priv->lock);
+}
+
+#define WOL_SUPPORT			\
+	(WAKE_PHY | WAKE_MAGIC |	\
+	WAKE_UCAST | WAKE_MCAST |	\
+	WAKE_BCAST | WAKE_ARP)
+
+/**
+ * netdev_get_wol - get Wake-on-LAN support
+ * @dev:	Network device.
+ * @wol:	Ethtool Wake-on-LAN data structure.
+ *
+ * This procedure returns Wake-on-LAN support.
+ */
+static void netdev_get_wol(struct net_device *dev,
+	struct ethtool_wolinfo *wol)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+
+	wol->supported = hw_priv->wol_support;
+	wol->wolopts = hw_priv->wol_enable;
+	memset(&wol->sopass, 0, sizeof(wol->sopass));
+}
+
+/**
+ * netdev_set_wol - set Wake-on-LAN support
+ * @dev:	Network device.
+ * @wol:	Ethtool Wake-on-LAN data structure.
+ *
+ * This function sets Wake-on-LAN support.
+ *
+ * Return 0 if successful; otherwise an error code.
+ */
+static int netdev_set_wol(struct net_device *dev,
+	struct ethtool_wolinfo *wol)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+
+	/* Need to find a way to retrieve the device IP address. */
+	u8 net_addr[] = { 192, 168, 1, 1 };
+
+	if (wol->wolopts & ~hw_priv->wol_support)
+		return -EINVAL;
+
+	hw_priv->wol_enable = wol->wolopts;
+
+	/* Link wakeup cannot really be disabled. */
+	if (wol->wolopts)
+		hw_priv->wol_enable |= WAKE_PHY;
+	hw_enable_wol(&hw_priv->hw, hw_priv->wol_enable, net_addr);
+	return 0;
+}
+
+/**
+ * netdev_get_msglevel - get debug message level
+ * @dev:	Network device.
+ *
+ * This function returns current debug message level.
+ *
+ * Return current debug message flags.
+ */
+static u32 netdev_get_msglevel(struct net_device *dev)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+
+	return priv->msg_enable;
+}
+
+/**
+ * netdev_set_msglevel - set debug message level
+ * @dev:	Network device.
+ * @value:	Debug message flags.
+ *
+ * This procedure sets debug message level.
+ */
+static void netdev_set_msglevel(struct net_device *dev, u32 value)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+
+	priv->msg_enable = value;
+}
+
+/**
+ * netdev_get_eeprom_len - get EEPROM length
+ * @dev:	Network device.
+ *
+ * This function returns the length of the EEPROM.
+ *
+ * Return length of the EEPROM.
+ */
+static int netdev_get_eeprom_len(struct net_device *dev)
+{
+	return EEPROM_SIZE * 2;
+}
+
+/**
+ * netdev_get_eeprom - get EEPROM data
+ * @dev:	Network device.
+ * @eeprom:	Ethtool EEPROM data structure.
+ * @data:	Buffer to store the EEPROM data.
+ *
+ * This function dumps the EEPROM data in the provided buffer.
+ *
+ * Return 0 if successful; otherwise an error code.
+ */
+#define EEPROM_MAGIC			0x10A18842
+
+static int netdev_get_eeprom(struct net_device *dev,
+	struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	u8 *eeprom_byte = (u8 *) eeprom_data;
+	int i;
+	int len;
+
+	len = (eeprom->offset + eeprom->len + 1) / 2;
+	for (i = eeprom->offset / 2; i < len; i++)
+		eeprom_data[i] = eeprom_read(&hw_priv->hw, i);
+	eeprom->magic = EEPROM_MAGIC;
+	memcpy(data, &eeprom_byte[eeprom->offset], eeprom->len);
+
+	return 0;
+}
+
+/**
+ * netdev_set_eeprom - write EEPROM data
+ * @dev:	Network device.
+ * @eeprom:	Ethtool EEPROM data structure.
+ * @data:	Data buffer.
+ *
+ * This function modifies the EEPROM data one byte at a time.
+ *
+ * Return 0 if successful; otherwise an error code.
+ */
+static int netdev_set_eeprom(struct net_device *dev,
+	struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	u16 eeprom_word[EEPROM_SIZE];
+	u8 *eeprom_byte = (u8 *) eeprom_word;
+	int i;
+	int len;
+
+	if (eeprom->magic != EEPROM_MAGIC)
+		return -EINVAL;
+
+	len = (eeprom->offset + eeprom->len + 1) / 2;
+	for (i = eeprom->offset / 2; i < len; i++)
+		eeprom_data[i] = eeprom_read(&hw_priv->hw, i);
+	memcpy(eeprom_word, eeprom_data, EEPROM_SIZE * 2);
+	memcpy(&eeprom_byte[eeprom->offset], data, eeprom->len);
+	for (i = 0; i < EEPROM_SIZE; i++)
+		if (eeprom_word[i] != eeprom_data[i]) {
+			eeprom_data[i] = eeprom_word[i];
+			eeprom_write(&hw_priv->hw, i, eeprom_data[i]);
+	}
+
+	return 0;
+}
+
+/**
+ * netdev_get_pauseparam - get flow control parameters
+ * @dev:	Network device.
+ * @pause:	Ethtool PAUSE settings data structure.
+ *
+ * This procedure returns the PAUSE control flow settings.
+ */
+static void netdev_get_pauseparam(struct net_device *dev,
+	struct ethtool_pauseparam *pause)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+
+	pause->autoneg = (hw->overrides & PAUSE_FLOW_CTRL) ? 0 : 1;
+	if (!hw->ksz_switch) {
+		pause->rx_pause =
+			(hw->rx_cfg & DMA_RX_FLOW_ENABLE) ? 1 : 0;
+		pause->tx_pause =
+			(hw->tx_cfg & DMA_TX_FLOW_ENABLE) ? 1 : 0;
+	} else {
+		pause->rx_pause =
+			(sw_chk(hw, KS8842_SWITCH_CTRL_1_OFFSET,
+				SWITCH_RX_FLOW_CTRL)) ? 1 : 0;
+		pause->tx_pause =
+			(sw_chk(hw, KS8842_SWITCH_CTRL_1_OFFSET,
+				SWITCH_TX_FLOW_CTRL)) ? 1 : 0;
+	}
+}
+
+/**
+ * netdev_set_pauseparam - set flow control parameters
+ * @dev:	Network device.
+ * @pause:	Ethtool PAUSE settings data structure.
+ *
+ * This function sets the PAUSE control flow settings.
+ * Not implemented yet.
+ *
+ * Return 0 if successful; otherwise an error code.
+ */
+static int netdev_set_pauseparam(struct net_device *dev,
+	struct ethtool_pauseparam *pause)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+	struct ksz_port *port = &priv->port;
+
+	mutex_lock(&hw_priv->lock);
+	if (pause->autoneg) {
+		if (!pause->rx_pause && !pause->tx_pause)
+			port->flow_ctrl = PHY_NO_FLOW_CTRL;
+		else
+			port->flow_ctrl = PHY_FLOW_CTRL;
+		hw->overrides &= ~PAUSE_FLOW_CTRL;
+		port->force_link = 0;
+		if (hw->ksz_switch) {
+			sw_cfg(hw, KS8842_SWITCH_CTRL_1_OFFSET,
+				SWITCH_RX_FLOW_CTRL, 1);
+			sw_cfg(hw, KS8842_SWITCH_CTRL_1_OFFSET,
+				SWITCH_TX_FLOW_CTRL, 1);
+		}
+		port_set_link_speed(port);
+	} else {
+		hw->overrides |= PAUSE_FLOW_CTRL;
+		if (hw->ksz_switch) {
+			sw_cfg(hw, KS8842_SWITCH_CTRL_1_OFFSET,
+				SWITCH_RX_FLOW_CTRL, pause->rx_pause);
+			sw_cfg(hw, KS8842_SWITCH_CTRL_1_OFFSET,
+				SWITCH_TX_FLOW_CTRL, pause->tx_pause);
+		} else
+			set_flow_ctrl(hw, pause->rx_pause, pause->tx_pause);
+	}
+	mutex_unlock(&hw_priv->lock);
+
+	return 0;
+}
+
+/**
+ * netdev_get_ringparam - get tx/rx ring parameters
+ * @dev:	Network device.
+ * @pause:	Ethtool RING settings data structure.
+ *
+ * This procedure returns the TX/RX ring settings.
+ */
+static void netdev_get_ringparam(struct net_device *dev,
+	struct ethtool_ringparam *ring)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+
+	ring->tx_max_pending = (1 << 9);
+	ring->tx_pending = hw->tx_desc_info.alloc;
+	ring->rx_max_pending = (1 << 9);
+	ring->rx_pending = hw->rx_desc_info.alloc;
+}
+
+#define STATS_LEN			(TOTAL_PORT_COUNTER_NUM)
+
+static struct {
+	char string[ETH_GSTRING_LEN];
+} ethtool_stats_keys[STATS_LEN] = {
+	{ "rx_lo_priority_octets" },
+	{ "rx_hi_priority_octets" },
+	{ "rx_undersize_packets" },
+	{ "rx_fragments" },
+	{ "rx_oversize_packets" },
+	{ "rx_jabbers" },
+	{ "rx_symbol_errors" },
+	{ "rx_crc_errors" },
+	{ "rx_align_errors" },
+	{ "rx_mac_ctrl_packets" },
+	{ "rx_pause_packets" },
+	{ "rx_bcast_packets" },
+	{ "rx_mcast_packets" },
+	{ "rx_ucast_packets" },
+	{ "rx_64_or_less_octet_packets" },
+	{ "rx_65_to_127_octet_packets" },
+	{ "rx_128_to_255_octet_packets" },
+	{ "rx_256_to_511_octet_packets" },
+	{ "rx_512_to_1023_octet_packets" },
+	{ "rx_1024_to_1522_octet_packets" },
+
+	{ "tx_lo_priority_octets" },
+	{ "tx_hi_priority_octets" },
+	{ "tx_late_collisions" },
+	{ "tx_pause_packets" },
+	{ "tx_bcast_packets" },
+	{ "tx_mcast_packets" },
+	{ "tx_ucast_packets" },
+	{ "tx_deferred" },
+	{ "tx_total_collisions" },
+	{ "tx_excessive_collisions" },
+	{ "tx_single_collisions" },
+	{ "tx_mult_collisions" },
+
+	{ "rx_discards" },
+	{ "tx_discards" },
+};
+
+/**
+ * netdev_get_strings - get statistics identity strings
+ * @dev:	Network device.
+ * @stringset:	String set identifier.
+ * @buf:	Buffer to store the strings.
+ *
+ * This procedure returns the strings used to identify the statistics.
+ */
+static void netdev_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+
+	if (ETH_SS_STATS == stringset)
+		memcpy(buf, &ethtool_stats_keys,
+			ETH_GSTRING_LEN * hw->mib_cnt);
+}
+
+/**
+ * netdev_get_sset_count - get statistics size
+ * @dev:	Network device.
+ * @sset:	The statistics set number.
+ *
+ * This function returns the size of the statistics to be reported.
+ *
+ * Return size of the statistics to be reported.
+ */
+static int netdev_get_sset_count(struct net_device *dev, int sset)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+
+	switch (sset) {
+	case ETH_SS_STATS:
+		return hw->mib_cnt;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+/**
+ * netdev_get_ethtool_stats - get network device statistics
+ * @dev:	Network device.
+ * @stats:	Ethtool statistics data structure.
+ * @data:	Buffer to store the statistics.
+ *
+ * This procedure returns the statistics.
+ */
+static void netdev_get_ethtool_stats(struct net_device *dev,
+	struct ethtool_stats *stats, u64 *data)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+	struct ksz_port *port = &priv->port;
+	int n_stats = stats->n_stats;
+	int i;
+	int n;
+	int p;
+	int rc;
+	u64 counter[TOTAL_PORT_COUNTER_NUM];
+
+	mutex_lock(&hw_priv->lock);
+	n = SWITCH_PORT_NUM;
+	for (i = 0, p = port->first_port; i < port->mib_port_cnt; i++, p++) {
+		if (media_connected == hw->port_mib[p].state) {
+			hw_priv->counter[p].read = 1;
+
+			/* Remember first port that requests read. */
+			if (n == SWITCH_PORT_NUM)
+				n = p;
+		}
+	}
+	mutex_unlock(&hw_priv->lock);
+
+	if (n < SWITCH_PORT_NUM)
+		schedule_work(&hw_priv->mib_read);
+
+	if (1 == port->mib_port_cnt && n < SWITCH_PORT_NUM) {
+		p = n;
+		rc = wait_event_interruptible_timeout(
+			hw_priv->counter[p].counter,
+			2 == hw_priv->counter[p].read,
+			HZ * 1);
+	} else
+		for (i = 0, p = n; i < port->mib_port_cnt - n; i++, p++) {
+			if (0 == i) {
+				rc = wait_event_interruptible_timeout(
+					hw_priv->counter[p].counter,
+					2 == hw_priv->counter[p].read,
+					HZ * 2);
+			} else if (hw->port_mib[p].cnt_ptr) {
+				rc = wait_event_interruptible_timeout(
+					hw_priv->counter[p].counter,
+					2 == hw_priv->counter[p].read,
+					HZ * 1);
+			}
+		}
+
+	get_mib_counters(hw, port->first_port, port->mib_port_cnt, counter);
+	n = hw->mib_cnt;
+	if (n > n_stats)
+		n = n_stats;
+	n_stats -= n;
+	for (i = 0; i < n; i++)
+		*data++ = counter[i];
+}
+
+/**
+ * netdev_get_rx_csum - get receive checksum support
+ * @dev:	Network device.
+ *
+ * This function gets receive checksum support setting.
+ *
+ * Return true if receive checksum is enabled; false otherwise.
+ */
+static u32 netdev_get_rx_csum(struct net_device *dev)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+
+	return hw->rx_cfg &
+		(DMA_RX_CSUM_UDP |
+		DMA_RX_CSUM_TCP |
+		DMA_RX_CSUM_IP);
+}
+
+/**
+ * netdev_set_rx_csum - set receive checksum support
+ * @dev:	Network device.
+ * @data:	Zero to disable receive checksum support.
+ *
+ * This function sets receive checksum support setting.
+ *
+ * Return 0 if successful; otherwise an error code.
+ */
+static int netdev_set_rx_csum(struct net_device *dev, u32 data)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+	u32 new_setting = hw->rx_cfg;
+
+	if (data)
+		new_setting |=
+			(DMA_RX_CSUM_UDP | DMA_RX_CSUM_TCP |
+			DMA_RX_CSUM_IP);
+	else
+		new_setting &=
+			~(DMA_RX_CSUM_UDP | DMA_RX_CSUM_TCP |
+			DMA_RX_CSUM_IP);
+	new_setting &= ~DMA_RX_CSUM_UDP;
+	mutex_lock(&hw_priv->lock);
+	if (new_setting != hw->rx_cfg) {
+		hw->rx_cfg = new_setting;
+		if (hw->enabled)
+			writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL);
+	}
+	mutex_unlock(&hw_priv->lock);
+	return 0;
+}
+
+static struct ethtool_ops netdev_ethtool_ops = {
+	.get_settings		= netdev_get_settings,
+	.set_settings		= netdev_set_settings,
+	.nway_reset		= netdev_nway_reset,
+	.get_link		= netdev_get_link,
+	.get_drvinfo		= netdev_get_drvinfo,
+	.get_regs_len		= netdev_get_regs_len,
+	.get_regs		= netdev_get_regs,
+	.get_wol		= netdev_get_wol,
+	.set_wol		= netdev_set_wol,
+	.get_msglevel		= netdev_get_msglevel,
+	.set_msglevel		= netdev_set_msglevel,
+	.get_eeprom_len		= netdev_get_eeprom_len,
+	.get_eeprom		= netdev_get_eeprom,
+	.set_eeprom		= netdev_set_eeprom,
+	.get_pauseparam		= netdev_get_pauseparam,
+	.set_pauseparam		= netdev_set_pauseparam,
+	.get_ringparam		= netdev_get_ringparam,
+	.get_strings		= netdev_get_strings,
+	.get_sset_count		= netdev_get_sset_count,
+	.get_ethtool_stats	= netdev_get_ethtool_stats,
+	.get_rx_csum		= netdev_get_rx_csum,
+	.set_rx_csum		= netdev_set_rx_csum,
+	.get_tx_csum		= ethtool_op_get_tx_csum,
+	.set_tx_csum		= ethtool_op_set_tx_csum,
+	.get_sg			= ethtool_op_get_sg,
+	.set_sg			= ethtool_op_set_sg,
+};
+
+/*
+ * Hardware monitoring
+ */
+
+static void update_link(struct net_device *dev, struct dev_priv *priv,
+	struct ksz_port *port)
+{
+	if (priv->media_state != port->linked->state) {
+		priv->media_state = port->linked->state;
+		if (netif_running(dev)) {
+			if (media_connected == priv->media_state)
+				netif_carrier_on(dev);
+			else
+				netif_carrier_off(dev);
+			if (netif_msg_link(priv))
+				printk(KERN_INFO "%s link %s\n", dev->name,
+					(media_connected == priv->media_state ?
+					"on" : "off"));
+		}
+	}
+}
+
+static void mib_read_work(struct work_struct *work)
+{
+	struct dev_info *hw_priv =
+		container_of(work, struct dev_info, mib_read);
+	struct ksz_hw *hw = &hw_priv->hw;
+	struct ksz_port_mib *mib;
+	int i;
+
+	next_jiffies = jiffies;
+	for (i = 0; i < hw->mib_port_cnt; i++) {
+		mib = &hw->port_mib[i];
+
+		/* Reading MIB counters or requested to read. */
+		if (mib->cnt_ptr || 1 == hw_priv->counter[i].read) {
+
+			/* Need to process receive interrupt. */
+			if (port_r_cnt(hw, i))
+				break;
+			hw_priv->counter[i].read = 0;
+
+			/* Finish reading counters. */
+			if (0 == mib->cnt_ptr) {
+				hw_priv->counter[i].read = 2;
+				wake_up_interruptible(
+					&hw_priv->counter[i].counter);
+			}
+		} else if (jiffies >= hw_priv->counter[i].time) {
+			/* Only read MIB counters when the port is connected. */
+			if (media_connected == mib->state)
+				hw_priv->counter[i].read = 1;
+			next_jiffies += HZ * 1 * hw->mib_port_cnt;
+			hw_priv->counter[i].time = next_jiffies;
+
+		/* Port is just disconnected. */
+		} else if (mib->link_down) {
+			mib->link_down = 0;
+
+			/* Read counters one last time after link is lost. */
+			hw_priv->counter[i].read = 1;
+		}
+	}
+}
+
+static void mib_monitor(unsigned long ptr)
+{
+	struct dev_info *hw_priv = (struct dev_info *) ptr;
+
+	mib_read_work(&hw_priv->mib_read);
+
+	/* This is used to verify Wake-on-LAN is working. */
+	if (hw_priv->pme_wait) {
+		if (hw_priv->pme_wait <= jiffies) {
+			hw_clr_wol_pme_status(&hw_priv->hw);
+			hw_priv->pme_wait = 0;
+		}
+	} else if (hw_chk_wol_pme_status(&hw_priv->hw)) {
+
+		/* PME is asserted.  Wait 2 seconds to clear it. */
+		hw_priv->pme_wait = jiffies + HZ * 2;
+	}
+
+	ksz_update_timer(&hw_priv->mib_timer_info);
+}
+
+/**
+ * dev_monitor - periodic monitoring
+ * @ptr:	Network device pointer.
+ *
+ * This routine is run in a kernel timer to monitor the network device.
+ */
+static void dev_monitor(unsigned long ptr)
+{
+	struct net_device *dev = (struct net_device *) ptr;
+	struct dev_priv *priv = netdev_priv(dev);
+	struct dev_info *hw_priv = priv->adapter;
+	struct ksz_hw *hw = &hw_priv->hw;
+	struct ksz_port *port = &priv->port;
+
+	if (!(hw->features & LINK_INT_WORKING))
+		port_get_link_speed(port);
+	update_link(dev, priv, port);
+
+	ksz_update_timer(&priv->monitor_timer_info);
+}
+
+/*
+ * Linux network device interface functions
+ */
+
+/* Driver exported variables */
+
+static int msg_enable;
+
+static char *macaddr = ":";
+static char *mac1addr = ":";
+
+/*
+ * This enables multiple network device mode for KSZ8842, which contains a
+ * switch with two physical ports.  Some users like to take control of the
+ * ports for running Spanning Tree Protocol.  The driver will create an
+ * additional eth? device for the other port.
+ *
+ * Some limitations are the network devices cannot have different MTU and
+ * multicast hash tables.
+ */
+static int multi_dev;
+
+/*
+ * As most users select multiple network device mode to use Spanning Tree
+ * Protocol, this enables a feature in which most unicast and multicast packets
+ * are forwarded inside the switch and not passed to the host.  Only packets
+ * that need the host's attention are passed to it.  This prevents the host
+ * wasting CPU time to examine each and every incoming packets and do the
+ * forwarding itself.
+ *
+ * As the hack requires the private bridge header, the driver cannot compile
+ * with just the kernel headers.
+ *
+ * Enabling STP support also turns on multiple network device mode.
+ */
+static int stp;
+
+/*
+ * This enables fast aging in the KSZ8842 switch.  Not sure what situation
+ * needs that.  However, fast aging is used to flush the dynamic MAC table when
+ * STP suport is enabled.
+ */
+static int fast_aging;
+
+/**
+ * netdev_init - initalize network device.
+ * @dev:	Network device.
+ *
+ * This function initializes the network device.
+ *
+ * Return 0 if successful; otherwise an error code indicating failure.
+ */
+static int __init netdev_init(struct net_device *dev)
+{
+	struct dev_priv *priv = netdev_priv(dev);
+
+	/* 500 ms timeout */
+	ksz_init_timer(&priv->monitor_timer_info, 500 * HZ / 1000,
+		dev_monitor, dev);
+
+	/* 500 ms timeout */
+	dev->watchdog_timeo = HZ / 2;
+
+	dev->features |= NETIF_F_IP_CSUM;
+
+	/*
+	 * Hardware does not really support IPv6 checksum generation, but
+	 * driver actually runs faster with this on.  Refer IPV6_CSUM_GEN_HACK.
+	 */
+	dev->features |= NETIF_F_IPV6_CSUM;
+	dev->features |= NETIF_F_SG;
+
+	sema_init(&priv->proc_sem, 1);
+
+	priv->mii_if.phy_id_mask = 0x1;
+	priv->mii_if.reg_num_mask = 0x7;
+	priv->mii_if.dev = dev;
+	priv->mii_if.mdio_read = mdio_read;
+	priv->mii_if.mdio_write = mdio_write;
+	priv->mii_if.phy_id = priv->port.first_port + 1;
+
+	priv->msg_enable = netif_msg_init(msg_enable,
+		(NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK));
+
+	return 0;
+}
+
+static const struct net_device_ops netdev_ops = {
+	.ndo_init		= netdev_init,
+	.ndo_open		= netdev_open,
+	.ndo_stop		= netdev_close,
+	.ndo_get_stats		= netdev_query_statistics,
+	.ndo_start_xmit		= netdev_tx,
+	.ndo_tx_timeout		= netdev_tx_timeout,
+	.ndo_change_mtu		= netdev_change_mtu,
+	.ndo_set_mac_address	= netdev_set_mac_address,
+	.ndo_do_ioctl		= netdev_ioctl,
+	.ndo_set_rx_mode	= netdev_set_rx_mode,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= netdev_netpoll,
+#endif
+};
+
+static void netdev_free(struct net_device *dev)
+{
+	if (dev->watchdog_timeo)
+		unregister_netdev(dev);
+
+	free_netdev(dev);
+}
+
+struct platform_info {
+	struct dev_info dev_info;
+	struct net_device *netdev[SWITCH_PORT_NUM];
+};
+
+static int net_device_present;
+
+static void get_mac_addr(struct dev_info *hw_priv, u8 *macaddr, int port)
+{
+	int i;
+	int j;
+	int got_num;
+	int num;
+
+	i = j = num = got_num = 0;
+	while (j < MAC_ADDR_LEN) {
+		if (macaddr[i]) {
+			got_num = 1;
+			if ('0' <= macaddr[i] && macaddr[i] <= '9')
+				num = num * 16 + macaddr[i] - '0';
+			else if ('A' <= macaddr[i] && macaddr[i] <= 'F')
+				num = num * 16 + 10 + macaddr[i] - 'A';
+			else if ('a' <= macaddr[i] && macaddr[i] <= 'f')
+				num = num * 16 + 10 + macaddr[i] - 'a';
+			else if (':' == macaddr[i])
+				got_num = 2;
+			else
+				break;
+		} else if (got_num)
+			got_num = 2;
+		else
+			break;
+		if (2 == got_num) {
+			if (MAIN_PORT == port) {
+				hw_priv->hw.override_addr[j++] = (u8) num;
+				hw_priv->hw.override_addr[5] +=
+					hw_priv->hw.id;
+			} else {
+				hw_priv->hw.ksz_switch->other_addr[j++] =
+					(u8) num;
+				hw_priv->hw.ksz_switch->other_addr[5] +=
+					hw_priv->hw.id;
+			}
+			num = got_num = 0;
+		}
+		i++;
+	}
+	if (MAC_ADDR_LEN == j) {
+		if (MAIN_PORT == port)
+			hw_priv->hw.mac_override = 1;
+	}
+}
+
+#define KS884X_DMA_MASK			(~0x0UL)
+
+static void read_other_addr(struct ksz_hw *hw)
+{
+	int i;
+	u16 data[3];
+	struct ksz_switch *sw = hw->ksz_switch;
+
+	for (i = 0; i < 3; i++)
+		data[i] = eeprom_read(hw, i + EEPROM_DATA_OTHER_MAC_ADDR);
+	if ((data[0] || data[1] || data[2]) && data[0] != 0xffff) {
+		sw->other_addr[5] = (u8) data[0];
+		sw->other_addr[4] = (u8)(data[0] >> 8);
+		sw->other_addr[3] = (u8) data[1];
+		sw->other_addr[2] = (u8)(data[1] >> 8);
+		sw->other_addr[1] = (u8) data[2];
+		sw->other_addr[0] = (u8)(data[2] >> 8);
+	}
+}
+
+#ifndef PCI_VENDOR_ID_MICREL_KS
+#define PCI_VENDOR_ID_MICREL_KS		0x16c6
+#endif
+
+static int __init pcidev_init(struct pci_dev *pdev,
+	const struct pci_device_id *id)
+{
+	struct net_device *dev;
+	struct dev_priv *priv;
+	struct dev_info *hw_priv;
+	struct ksz_hw *hw;
+	struct platform_info *info;
+	struct ksz_port *port;
+	unsigned long reg_base;
+	unsigned long reg_len;
+	int cnt;
+	int i;
+	int mib_port_count;
+	int pi;
+	int port_count;
+	int result;
+	char banner[80];
+	struct ksz_switch *sw = NULL;
+
+	result = pci_enable_device(pdev);
+	if (result)
+		return result;
+
+	result = -ENODEV;
+
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
+			pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
+		return result;
+
+	reg_base = pci_resource_start(pdev, 0);
+	reg_len = pci_resource_len(pdev, 0);
+	if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0)
+		return result;
+
+	if (!request_mem_region(reg_base, reg_len, DRV_NAME))
+		return result;
+	pci_set_master(pdev);
+
+	result = -ENOMEM;
+
+	info = kmalloc(sizeof(struct platform_info), GFP_KERNEL);
+	if (!info)
+		goto pcidev_init_dev_err;
+	memset(info, 0, sizeof(struct platform_info));
+
+	hw_priv = &info->dev_info;
+	hw_priv->pdev = pdev;
+
+	hw = &hw_priv->hw;
+
+	hw->io = ioremap(reg_base, reg_len);
+	if (!hw->io)
+		goto pcidev_init_io_err;
+
+	cnt = hw_init(hw);
+	if (!cnt) {
+		if (msg_enable & NETIF_MSG_PROBE)
+			printk(KERN_ALERT "chip not detected\n");
+		result = -ENODEV;
+		goto pcidev_init_alloc_err;
+	}
+
+	sprintf(banner,	"%s\n", version);
+	banner[13] = cnt + '0';
+	ks_info(hw_priv, "%s", banner);
+	ks_dbg(hw_priv, "Mem = %p; IRQ = %d\n", hw->io, pdev->irq);
+
+	/* Assume device is KSZ8841. */
+	hw->dev_count = 1;
+	port_count = 1;
+	mib_port_count = 1;
+	hw->addr_list_size = 0;
+	hw->mib_cnt = PORT_COUNTER_NUM;
+	hw->mib_port_cnt = 1;
+
+	/* KSZ8842 has a switch with multiple ports. */
+	if (2 == cnt) {
+		if (fast_aging)
+			hw->overrides |= FAST_AGING;
+
+		hw->mib_cnt = TOTAL_PORT_COUNTER_NUM;
+
+		/* Multiple network device interfaces are required. */
+		if (multi_dev) {
+			hw->dev_count = SWITCH_PORT_NUM;
+			hw->addr_list_size = SWITCH_PORT_NUM - 1;
+		}
+
+		/* Single network device has multiple ports. */
+		if (1 == hw->dev_count) {
+			port_count = SWITCH_PORT_NUM;
+			mib_port_count = SWITCH_PORT_NUM;
+		}
+		hw->mib_port_cnt = TOTAL_PORT_NUM;
+		hw->ksz_switch = kmalloc(sizeof(struct ksz_switch), GFP_KERNEL);
+		if (!hw->ksz_switch)
+			goto pcidev_init_alloc_err;
+		memset(hw->ksz_switch, 0, sizeof(struct ksz_switch));
+
+		sw = hw->ksz_switch;
+	}
+	for (i = 0; i < hw->mib_port_cnt; i++)
+		hw->port_mib[i].mib_start = 0;
+
+	hw->parent = hw_priv;
+
+	/* Default MTU is 1500. */
+	hw_priv->mtu = (REGULAR_RX_BUF_SIZE + 3) & ~3;
+
+	if (ksz_alloc_mem(hw_priv))
+		goto pcidev_init_mem_err;
+
+	hw_priv->hw.id = net_device_present;
+
+	spin_lock_init(&hw_priv->hwlock);
+	mutex_init(&hw_priv->lock);
+
+	/* tasklet is enabled. */
+	tasklet_init(&hw_priv->rx_tasklet, rx_proc_task,
+		(unsigned long) hw_priv);
+	tasklet_init(&hw_priv->tx_tasklet, tx_proc_task,
+		(unsigned long) hw_priv);
+
+	/* tasklet_enable will decrement the atomic counter. */
+	tasklet_disable(&hw_priv->rx_tasklet);
+	tasklet_disable(&hw_priv->tx_tasklet);
+
+	for (i = 0; i < TOTAL_PORT_NUM; i++)
+		init_waitqueue_head(&hw_priv->counter[i].counter);
+
+	if (macaddr[0] != ':')
+		get_mac_addr(hw_priv, macaddr, MAIN_PORT);
+
+	/* Read MAC address and initialize override address if not overrided. */
+	hw_read_addr(hw);
+
+	/* Multiple device interfaces mode requires a second MAC address. */
+	if (hw->dev_count > 1) {
+		memcpy(sw->other_addr, hw->override_addr, MAC_ADDR_LEN);
+		read_other_addr(hw);
+		if (mac1addr[0] != ':')
+			get_mac_addr(hw_priv, mac1addr, OTHER_PORT);
+	}
+
+	hw_setup(hw);
+	if (hw->ksz_switch)
+		sw_setup(hw);
+	else {
+		hw_priv->wol_support = WOL_SUPPORT;
+		hw_priv->wol_enable = 0;
+	}
+
+	INIT_WORK(&hw_priv->mib_read, mib_read_work);
+
+	/* 500 ms timeout */
+	ksz_init_timer(&hw_priv->mib_timer_info, 500 * HZ / 1000,
+		mib_monitor, hw_priv);
+
+	for (i = 0; i < hw->dev_count; i++) {
+		dev = alloc_etherdev(sizeof(struct dev_priv));
+		if (!dev)
+			goto pcidev_init_reg_err;
+		info->netdev[i] = dev;
+
+		priv = netdev_priv(dev);
+		priv->adapter = hw_priv;
+		priv->id = net_device_present++;
+
+		port = &priv->port;
+		port->port_cnt = port_count;
+		port->mib_port_cnt = mib_port_count;
+		port->first_port = i;
+		port->flow_ctrl = PHY_FLOW_CTRL;
+
+		port->hw = hw;
+		port->linked = &hw->port_info[port->first_port];
+
+		for (cnt = 0, pi = i; cnt < port_count; cnt++, pi++) {
+			hw->port_info[pi].port_id = pi;
+			hw->port_info[pi].pdev = dev;
+			hw->port_info[pi].state = media_disconnected;
+		}
+
+		dev->mem_start = (unsigned long) hw->io;
+		dev->mem_end = dev->mem_start + reg_len - 1;
+		dev->irq = pdev->irq;
+		if (MAIN_PORT == i)
+			memcpy(dev->dev_addr, hw_priv->hw.override_addr,
+				MAC_ADDR_LEN);
+		else {
+			memcpy(dev->dev_addr, sw->other_addr,
+				MAC_ADDR_LEN);
+			if (!memcmp(sw->other_addr, hw->override_addr,
+					MAC_ADDR_LEN))
+				dev->dev_addr[5] += port->first_port;
+		}
+
+		dev->netdev_ops = &netdev_ops;
+		SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+		if (register_netdev(dev))
+			goto pcidev_init_reg_err;
+		port_set_power_saving(port, true);
+	}
+
+	pci_dev_get(hw_priv->pdev);
+	pci_set_drvdata(pdev, info);
+	return 0;
+
+pcidev_init_reg_err:
+	for (i = 0; i < hw->dev_count; i++) {
+		if (info->netdev[i]) {
+			netdev_free(info->netdev[i]);
+			info->netdev[i] = NULL;
+		}
+	}
+
+pcidev_init_mem_err:
+	ksz_free_mem(hw_priv);
+	kfree(hw->ksz_switch);
+
+pcidev_init_alloc_err:
+	iounmap(hw->io);
+
+pcidev_init_io_err:
+	kfree(info);
+
+pcidev_init_dev_err:
+	release_mem_region(reg_base, reg_len);
+
+	return result;
+}
+
+static void pcidev_exit(struct pci_dev *pdev)
+{
+	int i;
+	struct platform_info *info = pci_get_drvdata(pdev);
+	struct dev_info *hw_priv = &info->dev_info;
+
+	pci_set_drvdata(pdev, NULL);
+
+	release_mem_region(pci_resource_start(pdev, 0),
+		pci_resource_len(pdev, 0));
+	for (i = 0; i < hw_priv->hw.dev_count; i++) {
+		if (info->netdev[i])
+			netdev_free(info->netdev[i]);
+	}
+	if (hw_priv->hw.io)
+		iounmap(hw_priv->hw.io);
+	ksz_free_mem(hw_priv);
+	kfree(hw_priv->hw.ksz_switch);
+	pci_dev_put(hw_priv->pdev);
+	kfree(info);
+}
+
+#ifdef CONFIG_PM
+static int pcidev_resume(struct pci_dev *pdev)
+{
+	int i;
+	struct platform_info *info = pci_get_drvdata(pdev);
+	struct dev_info *hw_priv = &info->dev_info;
+	struct ksz_hw *hw = &hw_priv->hw;
+
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+	pci_enable_wake(pdev, PCI_D0, 0);
+
+	if (hw_priv->wol_enable)
+		hw_cfg_wol_pme(hw, 0);
+	for (i = 0; i < hw->dev_count; i++) {
+		if (info->netdev[i]) {
+			struct net_device *dev = info->netdev[i];
+
+			if (netif_running(dev)) {
+				netdev_open(dev);
+				netif_device_attach(dev);
+			}
+		}
+	}
+	return 0;
+}
+
+static int pcidev_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int i;
+	struct platform_info *info = pci_get_drvdata(pdev);
+	struct dev_info *hw_priv = &info->dev_info;
+	struct ksz_hw *hw = &hw_priv->hw;
+
+	/* Need to find a way to retrieve the device IP address. */
+	u8 net_addr[] = { 192, 168, 1, 1 };
+
+	for (i = 0; i < hw->dev_count; i++) {
+		if (info->netdev[i]) {
+			struct net_device *dev = info->netdev[i];
+
+			if (netif_running(dev)) {
+				netif_device_detach(dev);
+				netdev_close(dev);
+			}
+		}
+	}
+	if (hw_priv->wol_enable) {
+		hw_enable_wol(hw, hw_priv->wol_enable, net_addr);
+		hw_cfg_wol_pme(hw, 1);
+	}
+
+	pci_save_state(pdev);
+	pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	return 0;
+}
+#endif
+
+static char pcidev_name[] = "ksz884xp";
+
+static struct pci_device_id pcidev_table[] = {
+	{ PCI_VENDOR_ID_MICREL_KS, 0x8841,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ PCI_VENDOR_ID_MICREL_KS, 0x8842,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, pcidev_table);
+
+static struct pci_driver pci_device_driver = {
+#ifdef CONFIG_PM
+	.suspend	= pcidev_suspend,
+	.resume		= pcidev_resume,
+#endif
+	.name		= pcidev_name,
+	.id_table	= pcidev_table,
+	.probe		= pcidev_init,
+	.remove		= pcidev_exit
+};
+
+static int __init ksz884x_init_module(void)
+{
+	return pci_register_driver(&pci_device_driver);
+}
+
+static void __exit ksz884x_cleanup_module(void)
+{
+	pci_unregister_driver(&pci_device_driver);
+}
+
+module_init(ksz884x_init_module);
+module_exit(ksz884x_cleanup_module);
+
+MODULE_DESCRIPTION("KSZ8841/2 PCI network driver");
+MODULE_AUTHOR("Tristram Ha <Tristram.Ha@micrel.com>");
+MODULE_LICENSE("GPL");
+
+module_param_named(message, msg_enable, int, 0);
+MODULE_PARM_DESC(message, "Message verbosity level (0=none, 31=all)");
+
+module_param(macaddr, charp, 0);
+module_param(mac1addr, charp, 0);
+module_param(fast_aging, int, 0);
+module_param(multi_dev, int, 0);
+module_param(stp, int, 0);
+MODULE_PARM_DESC(macaddr, "MAC address");
+MODULE_PARM_DESC(mac1addr, "Second MAC address");
+MODULE_PARM_DESC(fast_aging, "Fast aging");
+MODULE_PARM_DESC(multi_dev, "Multiple device interfaces");
+MODULE_PARM_DESC(stp, "STP support");
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/lance.c linux-libre-2.6.34-gnu1/drivers/net/lance.c
--- linux-libre-2.6.33-gnu1/drivers/net/lance.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/lance.c	2010-05-16 17:17:36.000000000 -0400
@@ -1288,7 +1288,7 @@ static void set_multicast_list(struct ne
 	} else {
 		short multicast_table[4];
 		int i;
-		int num_addrs=dev->mc_count;
+		int num_addrs=netdev_mc_count(dev);
 		if(dev->flags&IFF_ALLMULTI)
 			num_addrs=1;
 		/* FIXIT: We don't use the multicast table, but rely on upper-layer filtering. */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/lasi_82596.c linux-libre-2.6.34-gnu1/drivers/net/lasi_82596.c
--- linux-libre-2.6.33-gnu1/drivers/net/lasi_82596.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/lasi_82596.c	2010-05-16 17:17:36.000000000 -0400
@@ -74,7 +74,6 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/lib82596.c linux-libre-2.6.34-gnu1/drivers/net/lib82596.c
--- linux-libre-2.6.33-gnu1/drivers/net/lib82596.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/lib82596.c	2010-05-16 17:17:36.000000000 -0400
@@ -73,7 +73,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
@@ -85,6 +84,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/gfp.h>
 
 /* DEBUG flags
  */
@@ -1094,11 +1094,9 @@ static int __devinit i82596_probe(struct
 		return i;
 	};
 
-	DEB(DEB_PROBE, printk(KERN_INFO "%s: 82596 at %#3lx,",
-			      dev->name, dev->base_addr));
-	for (i = 0; i < 6; i++)
-		DEB(DEB_PROBE, printk(" %2.2X", dev->dev_addr[i]));
-	DEB(DEB_PROBE, printk(" IRQ %d.\n", dev->irq));
+	DEB(DEB_PROBE, printk(KERN_INFO "%s: 82596 at %#3lx, %pM IRQ %d.\n",
+			      dev->name, dev->base_addr, dev->dev_addr,
+			      dev->irq));
 	DEB(DEB_INIT, printk(KERN_INFO
 			     "%s: dma at 0x%p (%d bytes), lp->scb at 0x%p\n",
 			     dev->name, dma, (int)sizeof(struct i596_dma),
@@ -1382,31 +1380,32 @@ static void set_multicast_list(struct ne
 		}
 	}
 
-	cnt = dev->mc_count;
+	cnt = netdev_mc_count(dev);
 	if (cnt > MAX_MC_CNT) {
 		cnt = MAX_MC_CNT;
 		printk(KERN_NOTICE "%s: Only %d multicast addresses supported",
 			dev->name, cnt);
 	}
 
-	if (dev->mc_count > 0) {
+	if (!netdev_mc_empty(dev)) {
 		struct dev_mc_list *dmi;
 		unsigned char *cp;
 		struct mc_cmd *cmd;
 
 		cmd = &dma->mc_cmd;
 		cmd->cmd.command = SWAP16(CmdMulticastList);
-		cmd->mc_cnt = SWAP16(dev->mc_count * 6);
+		cmd->mc_cnt = SWAP16(netdev_mc_count(dev) * 6);
 		cp = cmd->mc_addrs;
-		for (dmi = dev->mc_list;
-		     cnt && dmi != NULL;
-		     dmi = dmi->next, cnt--, cp += 6) {
+		netdev_for_each_mc_addr(dmi, dev) {
+			if (!cnt--)
+				break;
 			memcpy(cp, dmi->dmi_addr, 6);
 			if (i596_debug > 1)
 				DEB(DEB_MULTI,
 				    printk(KERN_DEBUG
 					   "%s: Adding address %pM\n",
 					   dev->name, cp));
+			cp += 6;
 		}
 		DMA_WBACK_INV(dev, &dma->mc_cmd, sizeof(struct mc_cmd));
 		i596_add_cmd(dev, &cmd->cmd);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/lib8390.c linux-libre-2.6.34-gnu1/drivers/net/lib8390.c
--- linux-libre-2.6.33-gnu1/drivers/net/lib8390.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/lib8390.c	2010-05-16 17:17:36.000000000 -0400
@@ -907,15 +907,8 @@ static inline void make_mc_bits(u8 *bits
 {
 	struct dev_mc_list *dmi;
 
-	for (dmi=dev->mc_list; dmi; dmi=dmi->next)
-	{
-		u32 crc;
-		if (dmi->dmi_addrlen != ETH_ALEN)
-		{
-			printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name);
-			continue;
-		}
-		crc = ether_crc(ETH_ALEN, dmi->dmi_addr);
+	netdev_for_each_mc_addr(dmi, dev) {
+		u32 crc = ether_crc(ETH_ALEN, dmi->dmi_addr);
 		/*
 		 * The 8390 uses the 6 most significant bits of the
 		 * CRC to index the multicast table.
@@ -941,7 +934,7 @@ static void do_set_multicast_list(struct
 	if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)))
 	{
 		memset(ei_local->mcfilter, 0, 8);
-		if (dev->mc_list)
+		if (!netdev_mc_empty(dev))
 			make_mc_bits(ei_local->mcfilter, dev);
 	}
 	else
@@ -975,7 +968,7 @@ static void do_set_multicast_list(struct
 
   	if(dev->flags&IFF_PROMISC)
   		ei_outb_p(E8390_RXCONFIG | 0x18, e8390_base + EN0_RXCR);
-	else if(dev->flags&IFF_ALLMULTI || dev->mc_list)
+	else if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev))
   		ei_outb_p(E8390_RXCONFIG | 0x08, e8390_base + EN0_RXCR);
   	else
   		ei_outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ll_temac_main.c linux-libre-2.6.34-gnu1/drivers/net/ll_temac_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/ll_temac_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ll_temac_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,7 @@
 #include <linux/in.h>
 #include <linux/io.h>
 #include <linux/ip.h>
+#include <linux/slab.h>
 
 #include "ll_temac.h"
 
@@ -224,6 +225,13 @@ static int temac_set_mac_address(struct
 	return 0;
 }
 
+static int netdev_set_mac_address(struct net_device *ndev, void *p)
+{
+	struct sockaddr *addr = p;
+
+	return temac_set_mac_address(ndev, addr->sa_data);
+}
+
 static void temac_set_multicast_list(struct net_device *ndev)
 {
 	struct temac_local *lp = netdev_priv(ndev);
@@ -232,7 +240,7 @@ static void temac_set_multicast_list(str
 
 	mutex_lock(&lp->indirect_mutex);
 	if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC) ||
-	    ndev->mc_count > MULTICAST_CAM_TABLE_NUM) {
+	    netdev_mc_count(ndev) > MULTICAST_CAM_TABLE_NUM) {
 		/*
 		 *	We must make the kernel realise we had to move
 		 *	into promisc mode or we start all out war on
@@ -242,10 +250,11 @@ static void temac_set_multicast_list(str
 		ndev->flags |= IFF_PROMISC;
 		temac_indirect_out32(lp, XTE_AFM_OFFSET, XTE_AFM_EPPRM_MASK);
 		dev_info(&ndev->dev, "Promiscuous mode enabled.\n");
-	} else if (ndev->mc_count) {
-		struct dev_mc_list *mclist = ndev->mc_list;
-		for (i = 0; mclist && i < ndev->mc_count; i++) {
+	} else if (!netdev_mc_empty(ndev)) {
+		struct dev_mc_list *mclist;
 
+		i = 0;
+		netdev_for_each_mc_addr(mclist, ndev) {
 			if (i >= MULTICAST_CAM_TABLE_NUM)
 				break;
 			multi_addr_msw = ((mclist->dmi_addr[3] << 24) |
@@ -258,7 +267,7 @@ static void temac_set_multicast_list(str
 					  (mclist->dmi_addr[4]) | (i << 16));
 			temac_indirect_out32(lp, XTE_MAW1_OFFSET,
 					     multi_addr_lsw);
-			mclist = mclist->next;
+			i++;
 		}
 	} else {
 		val = temac_indirect_in32(lp, XTE_AFM_OFFSET);
@@ -615,7 +624,7 @@ static void ll_temac_recv(struct net_dev
 	while ((bdstat & STS_CTRL_APP0_CMPLT)) {
 
 		skb = lp->rx_skb[lp->rx_bd_ci];
-		length = cur_p->app4;
+		length = cur_p->app4 & 0x3FFF;
 
 		skb_vaddr = virt_to_bus(skb->data);
 		dma_unmap_single(ndev->dev.parent, skb_vaddr, length,
@@ -768,7 +777,7 @@ static const struct net_device_ops temac
 	.ndo_open = temac_open,
 	.ndo_stop = temac_stop,
 	.ndo_start_xmit = temac_start_xmit,
-	.ndo_set_mac_address = temac_set_mac_address,
+	.ndo_set_mac_address = netdev_set_mac_address,
 	//.ndo_set_multicast_list = temac_set_multicast_list,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller = temac_poll_controller,
@@ -938,6 +947,9 @@ static int __devexit temac_of_remove(str
 
 static struct of_device_id temac_of_match[] __devinitdata = {
 	{ .compatible = "xlnx,xps-ll-temac-1.01.b", },
+	{ .compatible = "xlnx,xps-ll-temac-2.00.a", },
+	{ .compatible = "xlnx,xps-ll-temac-2.02.a", },
+	{ .compatible = "xlnx,xps-ll-temac-2.03.a", },
 	{},
 };
 MODULE_DEVICE_TABLE(of, temac_of_match);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ll_temac_mdio.c linux-libre-2.6.34-gnu1/drivers/net/ll_temac_mdio.c
--- linux-libre-2.6.33-gnu1/drivers/net/ll_temac_mdio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ll_temac_mdio.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/phy.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/slab.h>
 #include <linux/of_mdio.h>
 
 #include "ll_temac.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/loopback.c linux-libre-2.6.34-gnu1/drivers/net/loopback.c
--- linux-libre-2.6.33-gnu1/drivers/net/loopback.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/loopback.c	2010-05-16 17:17:36.000000000 -0400
@@ -72,7 +72,8 @@ struct pcpu_lstats {
 static netdev_tx_t loopback_xmit(struct sk_buff *skb,
 				 struct net_device *dev)
 {
-	struct pcpu_lstats *pcpu_lstats, *lb_stats;
+	struct pcpu_lstats __percpu *pcpu_lstats;
+	struct pcpu_lstats *lb_stats;
 	int len;
 
 	skb_orphan(skb);
@@ -80,7 +81,7 @@ static netdev_tx_t loopback_xmit(struct
 	skb->protocol = eth_type_trans(skb, dev);
 
 	/* it's OK to use per_cpu_ptr() because BHs are off */
-	pcpu_lstats = dev->ml_priv;
+	pcpu_lstats = (void __percpu __force *)dev->ml_priv;
 	lb_stats = this_cpu_ptr(pcpu_lstats);
 
 	len = skb->len;
@@ -95,14 +96,14 @@ static netdev_tx_t loopback_xmit(struct
 
 static struct net_device_stats *loopback_get_stats(struct net_device *dev)
 {
-	const struct pcpu_lstats *pcpu_lstats;
+	const struct pcpu_lstats __percpu *pcpu_lstats;
 	struct net_device_stats *stats = &dev->stats;
 	unsigned long bytes = 0;
 	unsigned long packets = 0;
 	unsigned long drops = 0;
 	int i;
 
-	pcpu_lstats = dev->ml_priv;
+	pcpu_lstats = (void __percpu __force *)dev->ml_priv;
 	for_each_possible_cpu(i) {
 		const struct pcpu_lstats *lb_stats;
 
@@ -135,19 +136,20 @@ static const struct ethtool_ops loopback
 
 static int loopback_dev_init(struct net_device *dev)
 {
-	struct pcpu_lstats *lstats;
+	struct pcpu_lstats __percpu *lstats;
 
 	lstats = alloc_percpu(struct pcpu_lstats);
 	if (!lstats)
 		return -ENOMEM;
 
-	dev->ml_priv = lstats;
+	dev->ml_priv = (void __force *)lstats;
 	return 0;
 }
 
 static void loopback_dev_free(struct net_device *dev)
 {
-	struct pcpu_lstats *lstats = dev->ml_priv;
+	struct pcpu_lstats __percpu *lstats =
+		(void __percpu __force *)dev->ml_priv;
 
 	free_percpu(lstats);
 	free_netdev(dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/lp486e.c linux-libre-2.6.34-gnu1/drivers/net/lp486e.c
--- linux-libre-2.6.33-gnu1/drivers/net/lp486e.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/lp486e.c	2010-05-16 17:17:36.000000000 -0400
@@ -1253,21 +1253,22 @@ static void set_multicast_list(struct ne
 
 	if (i596_debug > 1)
 		printk ("%s: set multicast list %d\n",
-			dev->name, dev->mc_count);
+			dev->name, netdev_mc_count(dev));
 
-	if (dev->mc_count > 0) {
+	if (!netdev_mc_empty(dev)) {
 		struct dev_mc_list *dmi;
 		char *cp;
-		cmd = kmalloc(sizeof(struct i596_cmd)+2+dev->mc_count*6, GFP_ATOMIC);
+		cmd = kmalloc(sizeof(struct i596_cmd) + 2 +
+			      netdev_mc_count(dev) * 6, GFP_ATOMIC);
 		if (cmd == NULL) {
 			printk (KERN_ERR "%s: set_multicast Memory squeeze.\n", dev->name);
 			return;
 		}
 		cmd->command = CmdMulticastList;
-		*((unsigned short *) (cmd + 1)) = dev->mc_count * 6;
+		*((unsigned short *) (cmd + 1)) = netdev_mc_count(dev) * 6;
 		cp = ((char *)(cmd + 1))+2;
-		for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) {
-			memcpy(cp, dmi,6);
+		netdev_for_each_mc_addr(dmi, dev) {
+			memcpy(cp, dmi->dmi_addr, 6);
 			cp += 6;
 		}
 		if (i596_debug & LOG_SRCDST)
@@ -1277,7 +1278,8 @@ static void set_multicast_list(struct ne
 		if (lp->set_conf.pa_next != I596_NULL) {
 			return;
 		}
-		if (dev->mc_count == 0 && !(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
+		if (netdev_mc_empty(dev) &&
+		    !(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
 			lp->i596_config[8] &= ~0x01;
 		} else {
 			lp->i596_config[8] |= 0x01;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mac8390.c linux-libre-2.6.34-gnu1/drivers/net/mac8390.c
--- linux-libre-2.6.33-gnu1/drivers/net/mac8390.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mac8390.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,8 @@
 /* 2002-12-30: Try to support more cards, some clues from NetBSD driver */
 /* 2003-12-26: Make sure Asante cards always work. */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -26,7 +28,6 @@
 #include <linux/ioport.h>
 #include <linux/nubus.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -34,31 +35,36 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
+#include <linux/io.h>
 
 #include <asm/system.h>
-#include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/hwtest.h>
 #include <asm/macints.h>
 
 static char version[] =
-	"mac8390.c: v0.4 2001-05-15 David Huggins-Daines <dhd@debian.org> and others\n";
+	"v0.4 2001-05-15 David Huggins-Daines <dhd@debian.org> and others\n";
 
 #define EI_SHIFT(x)	(ei_local->reg_offset[x])
-#define ei_inb(port)   in_8(port)
-#define ei_outb(val,port)  out_8(port,val)
-#define ei_inb_p(port)   in_8(port)
-#define ei_outb_p(val,port)  out_8(port,val)
+#define ei_inb(port)	in_8(port)
+#define ei_outb(val, port)	out_8(port, val)
+#define ei_inb_p(port)	in_8(port)
+#define ei_outb_p(val, port)	out_8(port, val)
 
 #include "lib8390.c"
 
 #define WD_START_PG			0x00	/* First page of TX buffer */
 #define CABLETRON_RX_START_PG		0x00    /* First page of RX buffer */
 #define CABLETRON_RX_STOP_PG		0x30    /* Last page +1 of RX ring */
-#define CABLETRON_TX_START_PG		CABLETRON_RX_STOP_PG  /* First page of TX buffer */
+#define CABLETRON_TX_START_PG		CABLETRON_RX_STOP_PG
+						/* First page of TX buffer */
 
-/* Unfortunately it seems we have to hardcode these for the moment */
-/* Shouldn't the card know about this? Does anyone know where to read it off the card? Do we trust the data provided by the card? */
+/*
+ * Unfortunately it seems we have to hardcode these for the moment
+ * Shouldn't the card know about this?
+ * Does anyone know where to read it off the card?
+ * Do we trust the data provided by the card?
+ */
 
 #define DAYNA_8390_BASE		0x80000
 #define DAYNA_8390_MEM		0x00000
@@ -80,7 +86,7 @@ enum mac8390_type {
 	MAC8390_KINETICS,
 };
 
-static const char * cardname[] = {
+static const char *cardname[] = {
 	"apple",
 	"asante",
 	"farallon",
@@ -90,7 +96,7 @@ static const char * cardname[] = {
 	"kinetics",
 };
 
-static int word16[] = {
+static const int word16[] = {
 	1, /* apple */
 	1, /* asante */
 	1, /* farallon */
@@ -101,7 +107,7 @@ static int word16[] = {
 };
 
 /* on which cards do we use NuBus resources? */
-static int useresources[] = {
+static const int useresources[] = {
 	1, /* apple */
 	1, /* asante */
 	1, /* farallon */
@@ -117,22 +123,22 @@ enum mac8390_access {
 	ACCESS_16,
 };
 
-extern int mac8390_memtest(struct net_device * dev);
-static int mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,
+extern int mac8390_memtest(struct net_device *dev);
+static int mac8390_initdev(struct net_device *dev, struct nubus_dev *ndev,
 			   enum mac8390_type type);
 
-static int mac8390_open(struct net_device * dev);
-static int mac8390_close(struct net_device * dev);
+static int mac8390_open(struct net_device *dev);
+static int mac8390_close(struct net_device *dev);
 static void mac8390_no_reset(struct net_device *dev);
 static void interlan_reset(struct net_device *dev);
 
 /* Sane (32-bit chunk memory read/write) - Some Farallon and Apple do this*/
 static void sane_get_8390_hdr(struct net_device *dev,
 			      struct e8390_pkt_hdr *hdr, int ring_page);
-static void sane_block_input(struct net_device * dev, int count,
-			     struct sk_buff * skb, int ring_offset);
-static void sane_block_output(struct net_device * dev, int count,
-			      const unsigned char * buf, const int start_page);
+static void sane_block_input(struct net_device *dev, int count,
+			     struct sk_buff *skb, int ring_offset);
+static void sane_block_output(struct net_device *dev, int count,
+			      const unsigned char *buf, const int start_page);
 
 /* dayna_memcpy to and from card */
 static void dayna_memcpy_fromcard(struct net_device *dev, void *to,
@@ -148,8 +154,8 @@ static void dayna_block_input(struct net
 static void dayna_block_output(struct net_device *dev, int count,
 			       const unsigned char *buf, int start_page);
 
-#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
-#define memcpy_toio(a,b,c)	memcpy((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))
 
 /* Slow Sane (16-bit chunk memory read/write) Cabletron uses this */
 static void slow_sane_get_8390_hdr(struct net_device *dev,
@@ -164,70 +170,72 @@ static void word_memcpy_fromcard(void *t
 static enum mac8390_type __init mac8390_ident(struct nubus_dev *dev)
 {
 	switch (dev->dr_sw) {
-		case NUBUS_DRSW_3COM:
-			switch (dev->dr_hw) {
-				case NUBUS_DRHW_APPLE_SONIC_NB:
-				case NUBUS_DRHW_APPLE_SONIC_LC:
-				case NUBUS_DRHW_SONNET:
-					return MAC8390_NONE;
-					break;
-				default:
-					return MAC8390_APPLE;
-					break;
-			}
+	case NUBUS_DRSW_3COM:
+		switch (dev->dr_hw) {
+		case NUBUS_DRHW_APPLE_SONIC_NB:
+		case NUBUS_DRHW_APPLE_SONIC_LC:
+		case NUBUS_DRHW_SONNET:
+			return MAC8390_NONE;
 			break;
-
-		case NUBUS_DRSW_APPLE:
-			switch (dev->dr_hw) {
-				case NUBUS_DRHW_ASANTE_LC:
-					return MAC8390_NONE;
-					break;
-				case NUBUS_DRHW_CABLETRON:
-					return MAC8390_CABLETRON;
-					break;
-				default:
-					return MAC8390_APPLE;
-					break;
-			}
+		default:
+			return MAC8390_APPLE;
 			break;
+		}
+		break;
 
-		case NUBUS_DRSW_ASANTE:
-			return MAC8390_ASANTE;
+	case NUBUS_DRSW_APPLE:
+		switch (dev->dr_hw) {
+		case NUBUS_DRHW_ASANTE_LC:
+			return MAC8390_NONE;
 			break;
-
-		case NUBUS_DRSW_TECHWORKS:
-		case NUBUS_DRSW_DAYNA2:
-		case NUBUS_DRSW_DAYNA_LC:
-			if (dev->dr_hw == NUBUS_DRHW_CABLETRON)
-				return MAC8390_CABLETRON;
-			else
-				return MAC8390_APPLE;
+		case NUBUS_DRHW_CABLETRON:
+			return MAC8390_CABLETRON;
 			break;
-
-		case NUBUS_DRSW_FARALLON:
-			return MAC8390_FARALLON;
+		default:
+			return MAC8390_APPLE;
 			break;
+		}
+		break;
 
-		case NUBUS_DRSW_KINETICS:
-			switch (dev->dr_hw) {
-				case NUBUS_DRHW_INTERLAN:
-					return MAC8390_INTERLAN;
-					break;
-				default:
-					return MAC8390_KINETICS;
-					break;
-			}
-			break;
+	case NUBUS_DRSW_ASANTE:
+		return MAC8390_ASANTE;
+		break;
 
-		case NUBUS_DRSW_DAYNA:
-			// These correspond to Dayna Sonic cards
-			// which use the macsonic driver
-			if (dev->dr_hw == NUBUS_DRHW_SMC9194 ||
-				dev->dr_hw == NUBUS_DRHW_INTERLAN )
-				return MAC8390_NONE;
-			else
-				return MAC8390_DAYNA;
+	case NUBUS_DRSW_TECHWORKS:
+	case NUBUS_DRSW_DAYNA2:
+	case NUBUS_DRSW_DAYNA_LC:
+		if (dev->dr_hw == NUBUS_DRHW_CABLETRON)
+			return MAC8390_CABLETRON;
+		else
+			return MAC8390_APPLE;
+		break;
+
+	case NUBUS_DRSW_FARALLON:
+		return MAC8390_FARALLON;
+		break;
+
+	case NUBUS_DRSW_KINETICS:
+		switch (dev->dr_hw) {
+		case NUBUS_DRHW_INTERLAN:
+			return MAC8390_INTERLAN;
+			break;
+		default:
+			return MAC8390_KINETICS;
 			break;
+		}
+		break;
+
+	case NUBUS_DRSW_DAYNA:
+		/*
+		 * These correspond to Dayna Sonic cards
+		 * which use the macsonic driver
+		 */
+		if (dev->dr_hw == NUBUS_DRHW_SMC9194 ||
+		    dev->dr_hw == NUBUS_DRHW_INTERLAN)
+			return MAC8390_NONE;
+		else
+			return MAC8390_DAYNA;
+		break;
 	}
 	return MAC8390_NONE;
 }
@@ -237,14 +245,14 @@ static enum mac8390_access __init mac839
 	unsigned long outdata = 0xA5A0B5B0;
 	unsigned long indata =  0x00000000;
 	/* Try writing 32 bits */
-	memcpy((char *)membase, (char *)&outdata, 4);
+	memcpy(membase, &outdata, 4);
 	/* Now compare them */
 	if (memcmp((char *)&outdata, (char *)membase, 4) == 0)
 		return ACCESS_32;
 	/* Write 16 bit output */
-	word_memcpy_tocard((char *)membase, (char *)&outdata, 4);
+	word_memcpy_tocard(membase, &outdata, 4);
 	/* Now read it back */
-	word_memcpy_fromcard((char *)&indata, (char *)membase, 4);
+	word_memcpy_fromcard(&indata, membase, 4);
 	if (outdata == indata)
 		return ACCESS_16;
 	return ACCESS_UNKNOWN;
@@ -258,7 +266,7 @@ static int __init mac8390_memsize(unsign
 	local_irq_save(flags);
 	/* Check up to 32K in 4K increments */
 	for (i = 0; i < 8; i++) {
-		volatile unsigned short *m = (unsigned short *) (membase + (i * 0x1000));
+		volatile unsigned short *m = (unsigned short *)(membase + (i * 0x1000));
 
 		/* Unwriteable - we have a fully decoded card and the
 		   RAM end located */
@@ -273,28 +281,127 @@ static int __init mac8390_memsize(unsign
 
 		/* check for partial decode and wrap */
 		for (j = 0; j < i; j++) {
-			volatile unsigned short *p = (unsigned short *) (membase + (j * 0x1000));
+			volatile unsigned short *p = (unsigned short *)(membase + (j * 0x1000));
 			if (*p != (0xA5A0 | j))
 				break;
- 		}
- 	}
+		}
+	}
 	local_irq_restore(flags);
-	/* in any case, we stopped once we tried one block too many,
-           or once we reached 32K */
- 	return i * 0x1000;
+	/*
+	 * in any case, we stopped once we tried one block too many,
+	 * or once we reached 32K
+	 */
+	return i * 0x1000;
+}
+
+static bool __init mac8390_init(struct net_device *dev, struct nubus_dev *ndev,
+				enum mac8390_type cardtype)
+{
+	struct nubus_dir dir;
+	struct nubus_dirent ent;
+	int offset;
+	volatile unsigned short *i;
+
+	printk_once(KERN_INFO pr_fmt("%s"), version);
+
+	dev->irq = SLOT2IRQ(ndev->board->slot);
+	/* This is getting to be a habit */
+	dev->base_addr = (ndev->board->slot_addr |
+			  ((ndev->board->slot & 0xf) << 20));
+
+	/*
+	 * Get some Nubus info - we will trust the card's idea
+	 * of where its memory and registers are.
+	 */
+
+	if (nubus_get_func_dir(ndev, &dir) == -1) {
+		pr_err("%s: Unable to get Nubus functional directory for slot %X!\n",
+		       dev->name, ndev->board->slot);
+		return false;
+	}
+
+	/* Get the MAC address */
+	if (nubus_find_rsrc(&dir, NUBUS_RESID_MAC_ADDRESS, &ent) == -1) {
+		pr_info("%s: Couldn't get MAC address!\n", dev->name);
+		return false;
+	}
+
+	nubus_get_rsrc_mem(dev->dev_addr, &ent, 6);
+
+	if (useresources[cardtype] == 1) {
+		nubus_rewinddir(&dir);
+		if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_BASEOS,
+				    &ent) == -1) {
+			pr_err("%s: Memory offset resource for slot %X not found!\n",
+			       dev->name, ndev->board->slot);
+			return false;
+		}
+		nubus_get_rsrc_mem(&offset, &ent, 4);
+		dev->mem_start = dev->base_addr + offset;
+		/* yes, this is how the Apple driver does it */
+		dev->base_addr = dev->mem_start + 0x10000;
+		nubus_rewinddir(&dir);
+		if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_LENGTH,
+				    &ent) == -1) {
+			pr_info("%s: Memory length resource for slot %X not found, probing\n",
+				dev->name, ndev->board->slot);
+			offset = mac8390_memsize(dev->mem_start);
+		} else {
+			nubus_get_rsrc_mem(&offset, &ent, 4);
+		}
+		dev->mem_end = dev->mem_start + offset;
+	} else {
+		switch (cardtype) {
+		case MAC8390_KINETICS:
+		case MAC8390_DAYNA: /* it's the same */
+			dev->base_addr = (int)(ndev->board->slot_addr +
+					       DAYNA_8390_BASE);
+			dev->mem_start = (int)(ndev->board->slot_addr +
+					       DAYNA_8390_MEM);
+			dev->mem_end = dev->mem_start +
+				       mac8390_memsize(dev->mem_start);
+			break;
+		case MAC8390_INTERLAN:
+			dev->base_addr = (int)(ndev->board->slot_addr +
+					       INTERLAN_8390_BASE);
+			dev->mem_start = (int)(ndev->board->slot_addr +
+					       INTERLAN_8390_MEM);
+			dev->mem_end = dev->mem_start +
+				       mac8390_memsize(dev->mem_start);
+			break;
+		case MAC8390_CABLETRON:
+			dev->base_addr = (int)(ndev->board->slot_addr +
+					       CABLETRON_8390_BASE);
+			dev->mem_start = (int)(ndev->board->slot_addr +
+					       CABLETRON_8390_MEM);
+			/* The base address is unreadable if 0x00
+			 * has been written to the command register
+			 * Reset the chip by writing E8390_NODMA +
+			 *   E8390_PAGE0 + E8390_STOP just to be
+			 *   sure
+			 */
+			i = (void *)dev->base_addr;
+			*i = 0x21;
+			dev->mem_end = dev->mem_start +
+				       mac8390_memsize(dev->mem_start);
+			break;
+
+		default:
+			pr_err("Card type %s is unsupported, sorry\n",
+			       ndev->board->name);
+			return false;
+		}
+	}
+
+	return true;
 }
 
 struct net_device * __init mac8390_probe(int unit)
 {
 	struct net_device *dev;
-	volatile unsigned short *i;
-	int version_disp = 0;
-	struct nubus_dev * ndev = NULL;
+	struct nubus_dev *ndev = NULL;
 	int err = -ENODEV;
 
-	struct nubus_dir dir;
-	struct nubus_dirent ent;
-	int offset;
 	static unsigned int slots;
 
 	enum mac8390_type cardtype;
@@ -311,118 +418,19 @@ struct net_device * __init mac8390_probe
 	if (unit >= 0)
 		sprintf(dev->name, "eth%d", unit);
 
-	while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, NUBUS_TYPE_ETHERNET, ndev))) {
+	while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, NUBUS_TYPE_ETHERNET,
+				       ndev))) {
 		/* Have we seen it already? */
-		if (slots & (1<<ndev->board->slot))
-			continue;
-		slots |= 1<<ndev->board->slot;
-
-		if ((cardtype = mac8390_ident(ndev)) == MAC8390_NONE)
+		if (slots & (1 << ndev->board->slot))
 			continue;
+		slots |= 1 << ndev->board->slot;
 
-		if (version_disp == 0) {
-			version_disp = 1;
-			printk(version);
-		}
-
-		dev->irq = SLOT2IRQ(ndev->board->slot);
-		/* This is getting to be a habit */
-		dev->base_addr = ndev->board->slot_addr | ((ndev->board->slot&0xf) << 20);
-
-		/* Get some Nubus info - we will trust the card's idea
-		   of where its memory and registers are. */
-
-		if (nubus_get_func_dir(ndev, &dir) == -1) {
-			printk(KERN_ERR "%s: Unable to get Nubus functional"
-					" directory for slot %X!\n",
-			       dev->name, ndev->board->slot);
+		cardtype = mac8390_ident(ndev);
+		if (cardtype == MAC8390_NONE)
 			continue;
-		}
 
-		/* Get the MAC address */
-		if ((nubus_find_rsrc(&dir, NUBUS_RESID_MAC_ADDRESS, &ent)) == -1) {
-			printk(KERN_INFO "%s: Couldn't get MAC address!\n",
-					dev->name);
+		if (!mac8390_init(dev, ndev, cardtype))
 			continue;
-		} else {
-			nubus_get_rsrc_mem(dev->dev_addr, &ent, 6);
-		}
-
-		if (useresources[cardtype] == 1) {
-			nubus_rewinddir(&dir);
-			if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_BASEOS, &ent) == -1) {
-				printk(KERN_ERR "%s: Memory offset resource"
-						" for slot %X not found!\n",
-				       dev->name, ndev->board->slot);
-				continue;
-			}
-			nubus_get_rsrc_mem(&offset, &ent, 4);
-			dev->mem_start = dev->base_addr + offset;
-			/* yes, this is how the Apple driver does it */
-			dev->base_addr = dev->mem_start + 0x10000;
-			nubus_rewinddir(&dir);
-			if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_LENGTH, &ent) == -1) {
-				printk(KERN_INFO "%s: Memory length resource"
-						 " for slot %X not found"
-						 ", probing\n",
-				       dev->name, ndev->board->slot);
-				offset = mac8390_memsize(dev->mem_start);
-				} else {
-					nubus_get_rsrc_mem(&offset, &ent, 4);
-				}
-			dev->mem_end = dev->mem_start + offset;
-		} else {
-			switch (cardtype) {
-				case MAC8390_KINETICS:
-				case MAC8390_DAYNA: /* it's the same */
-					dev->base_addr =
-						(int)(ndev->board->slot_addr +
-						DAYNA_8390_BASE);
-					dev->mem_start =
-						(int)(ndev->board->slot_addr +
-						DAYNA_8390_MEM);
-					dev->mem_end =
-						dev->mem_start +
-						mac8390_memsize(dev->mem_start);
-					break;
-				case MAC8390_INTERLAN:
-					dev->base_addr =
-						(int)(ndev->board->slot_addr +
-						INTERLAN_8390_BASE);
-					dev->mem_start =
-						(int)(ndev->board->slot_addr +
-						INTERLAN_8390_MEM);
-					dev->mem_end =
-						dev->mem_start +
-						mac8390_memsize(dev->mem_start);
-					break;
-				case MAC8390_CABLETRON:
-					dev->base_addr =
-						(int)(ndev->board->slot_addr +
-						CABLETRON_8390_BASE);
-					dev->mem_start =
-						(int)(ndev->board->slot_addr +
-						CABLETRON_8390_MEM);
-					/* The base address is unreadable if 0x00
-					 * has been written to the command register
-					 * Reset the chip by writing E8390_NODMA +
-					 *   E8390_PAGE0 + E8390_STOP just to be
-					 *   sure
-					 */
-					i = (void *)dev->base_addr;
-					*i = 0x21;
-					dev->mem_end =
-						dev->mem_start +
-						mac8390_memsize(dev->mem_start);
-					break;
-
-				default:
-					printk(KERN_ERR "Card type %s is"
-					       " unsupported, sorry\n",
-					       ndev->board->name);
-					continue;
-			}
-		}
 
 		/* Do the nasty 8390 stuff */
 		if (!mac8390_initdev(dev, ndev, cardtype))
@@ -458,7 +466,7 @@ int init_module(void)
 		dev_mac890[i] = dev;
 	}
 	if (!i) {
-		printk(KERN_NOTICE "mac8390.c: No useable cards found, driver NOT installed.\n");
+		pr_notice("No useable cards found, driver NOT installed.\n");
 		return -ENODEV;
 	}
 	return 0;
@@ -493,22 +501,23 @@ static const struct net_device_ops mac83
 #endif
 };
 
-static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,
-			    enum mac8390_type type)
+static int __init mac8390_initdev(struct net_device *dev,
+				  struct nubus_dev *ndev,
+				  enum mac8390_type type)
 {
-	static u32 fwrd4_offsets[16]={
+	static u32 fwrd4_offsets[16] = {
 		0,      4,      8,      12,
 		16,     20,     24,     28,
 		32,     36,     40,     44,
 		48,     52,     56,     60
 	};
-	static u32 back4_offsets[16]={
+	static u32 back4_offsets[16] = {
 		60,     56,     52,     48,
 		44,     40,     36,     32,
 		28,     24,     20,     16,
 		12,     8,      4,      0
 	};
-	static u32 fwrd2_offsets[16]={
+	static u32 fwrd2_offsets[16] = {
 		0,      2,      4,      6,
 		8,     10,     12,     14,
 		16,    18,     20,     22,
@@ -526,47 +535,47 @@ static int __init mac8390_initdev(struct
 
 	/* Cabletron's TX/RX buffers are backwards */
 	if (type == MAC8390_CABLETRON) {
-               ei_status.tx_start_page = CABLETRON_TX_START_PG;
-               ei_status.rx_start_page = CABLETRON_RX_START_PG;
-               ei_status.stop_page = CABLETRON_RX_STOP_PG;
-               ei_status.rmem_start = dev->mem_start;
-               ei_status.rmem_end = dev->mem_start + CABLETRON_RX_STOP_PG*256;
+		ei_status.tx_start_page = CABLETRON_TX_START_PG;
+		ei_status.rx_start_page = CABLETRON_RX_START_PG;
+		ei_status.stop_page = CABLETRON_RX_STOP_PG;
+		ei_status.rmem_start = dev->mem_start;
+		ei_status.rmem_end = dev->mem_start + CABLETRON_RX_STOP_PG*256;
 	} else {
-               ei_status.tx_start_page = WD_START_PG;
-               ei_status.rx_start_page = WD_START_PG + TX_PAGES;
-               ei_status.stop_page = (dev->mem_end - dev->mem_start)/256;
-               ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
-               ei_status.rmem_end = dev->mem_end;
+		ei_status.tx_start_page = WD_START_PG;
+		ei_status.rx_start_page = WD_START_PG + TX_PAGES;
+		ei_status.stop_page = (dev->mem_end - dev->mem_start)/256;
+		ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
+		ei_status.rmem_end = dev->mem_end;
 	}
 
 	/* Fill in model-specific information and functions */
-	switch(type) {
+	switch (type) {
 	case MAC8390_FARALLON:
 	case MAC8390_APPLE:
-		switch(mac8390_testio(dev->mem_start)) {
-			case ACCESS_UNKNOWN:
-				printk("Don't know how to access card memory!\n");
-				return -ENODEV;
-				break;
+		switch (mac8390_testio(dev->mem_start)) {
+		case ACCESS_UNKNOWN:
+			pr_info("Don't know how to access card memory!\n");
+			return -ENODEV;
+			break;
 
-			case ACCESS_16:
-				/* 16 bit card, register map is reversed */
-				ei_status.reset_8390 = &mac8390_no_reset;
-				ei_status.block_input = &slow_sane_block_input;
-				ei_status.block_output = &slow_sane_block_output;
-				ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
-				ei_status.reg_offset = back4_offsets;
-				break;
+		case ACCESS_16:
+			/* 16 bit card, register map is reversed */
+			ei_status.reset_8390 = &mac8390_no_reset;
+			ei_status.block_input = &slow_sane_block_input;
+			ei_status.block_output = &slow_sane_block_output;
+			ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
+			ei_status.reg_offset = back4_offsets;
+			break;
 
-			case ACCESS_32:
-				/* 32 bit card, register map is reversed */
-				ei_status.reset_8390 = &mac8390_no_reset;
-				ei_status.block_input = &sane_block_input;
-				ei_status.block_output = &sane_block_output;
-				ei_status.get_8390_hdr = &sane_get_8390_hdr;
-				ei_status.reg_offset = back4_offsets;
-				access_bitmode = 1;
-				break;
+		case ACCESS_32:
+			/* 32 bit card, register map is reversed */
+			ei_status.reset_8390 = &mac8390_no_reset;
+			ei_status.block_input = &sane_block_input;
+			ei_status.block_output = &sane_block_output;
+			ei_status.get_8390_hdr = &sane_get_8390_hdr;
+			ei_status.reg_offset = back4_offsets;
+			access_bitmode = 1;
+			break;
 		}
 		break;
 
@@ -608,24 +617,25 @@ static int __init mac8390_initdev(struct
 		ei_status.block_input = &slow_sane_block_input;
 		ei_status.block_output = &slow_sane_block_output;
 		ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
-	        ei_status.reg_offset = fwrd4_offsets;
-	        break;
+		ei_status.reg_offset = fwrd4_offsets;
+		break;
 
 	default:
-		printk(KERN_ERR "Card type %s is unsupported, sorry\n", ndev->board->name);
+		pr_err("Card type %s is unsupported, sorry\n",
+		       ndev->board->name);
 		return -ENODEV;
 	}
 
 	__NS8390_init(dev, 0);
 
 	/* Good, done, now spit out some messages */
-	printk(KERN_INFO "%s: %s in slot %X (type %s)\n",
-	       dev->name, ndev->board->name, ndev->board->slot, cardname[type]);
-	printk(KERN_INFO
-	       "MAC %pM IRQ %d, %d KB shared memory at %#lx, %d-bit access.\n",
-	       dev->dev_addr, dev->irq,
-	       (unsigned int)(dev->mem_end - dev->mem_start) >> 10,
-	       dev->mem_start, access_bitmode ? 32 : 16);
+	pr_info("%s: %s in slot %X (type %s)\n",
+		dev->name, ndev->board->name, ndev->board->slot,
+		cardname[type]);
+	pr_info("MAC %pM IRQ %d, %d KB shared memory at %#lx, %d-bit access.\n",
+		dev->dev_addr, dev->irq,
+		(unsigned int)(dev->mem_end - dev->mem_start) >> 10,
+		dev->mem_start, access_bitmode ? 32 : 16);
 	return 0;
 }
 
@@ -633,7 +643,7 @@ static int mac8390_open(struct net_devic
 {
 	__ei_open(dev);
 	if (request_irq(dev->irq, __ei_interrupt, 0, "8390 Ethernet", dev)) {
-		printk ("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
+		pr_info("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
 		return -EAGAIN;
 	}
 	return 0;
@@ -650,72 +660,71 @@ static void mac8390_no_reset(struct net_
 {
 	ei_status.txing = 0;
 	if (ei_debug > 1)
-		printk("reset not supported\n");
+		pr_info("reset not supported\n");
 	return;
 }
 
 static void interlan_reset(struct net_device *dev)
 {
-	unsigned char *target=nubus_slot_addr(IRQ2SLOT(dev->irq));
+	unsigned char *target = nubus_slot_addr(IRQ2SLOT(dev->irq));
 	if (ei_debug > 1)
-		printk("Need to reset the NS8390 t=%lu...", jiffies);
+		pr_info("Need to reset the NS8390 t=%lu...", jiffies);
 	ei_status.txing = 0;
 	target[0xC0000] = 0;
 	if (ei_debug > 1)
-		printk("reset complete\n");
+		pr_cont("reset complete\n");
 	return;
 }
 
 /* dayna_memcpy_fromio/dayna_memcpy_toio */
 /* directly from daynaport.c by Alan Cox */
-static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, int count)
+static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from,
+				  int count)
 {
 	volatile unsigned char *ptr;
-	unsigned char *target=to;
-	from<<=1;	/* word, skip overhead */
-	ptr=(unsigned char *)(dev->mem_start+from);
+	unsigned char *target = to;
+	from <<= 1;	/* word, skip overhead */
+	ptr = (unsigned char *)(dev->mem_start+from);
 	/* Leading byte? */
-	if (from&2) {
+	if (from & 2) {
 		*target++ = ptr[-1];
 		ptr += 2;
 		count--;
 	}
-	while(count>=2)
-	{
+	while (count >= 2) {
 		*(unsigned short *)target = *(unsigned short volatile *)ptr;
 		ptr += 4;			/* skip cruft */
 		target += 2;
-		count-=2;
+		count -= 2;
 	}
 	/* Trailing byte? */
-	if(count)
+	if (count)
 		*target = *ptr;
 }
 
-static void dayna_memcpy_tocard(struct net_device *dev, int to, const void *from, int count)
+static void dayna_memcpy_tocard(struct net_device *dev, int to,
+				const void *from, int count)
 {
 	volatile unsigned short *ptr;
-	const unsigned char *src=from;
-	to<<=1;	/* word, skip overhead */
-	ptr=(unsigned short *)(dev->mem_start+to);
+	const unsigned char *src = from;
+	to <<= 1;	/* word, skip overhead */
+	ptr = (unsigned short *)(dev->mem_start+to);
 	/* Leading byte? */
-	if (to&2) { /* avoid a byte write (stomps on other data) */
+	if (to & 2) {		/* avoid a byte write (stomps on other data) */
 		ptr[-1] = (ptr[-1]&0xFF00)|*src++;
 		ptr++;
 		count--;
 	}
-	while(count>=2)
-	{
-		*ptr++=*(unsigned short *)src;		/* Copy and */
+	while (count >= 2) {
+		*ptr++ = *(unsigned short *)src;	/* Copy and */
 		ptr++;			/* skip cruft */
 		src += 2;
-		count-=2;
+		count -= 2;
 	}
 	/* Trailing byte? */
-	if(count)
-	{
+	if (count) {
 		/* card doesn't like byte writes */
-		*ptr=(*ptr&0x00FF)|(*src << 8);
+		*ptr = (*ptr & 0x00FF) | (*src << 8);
 	}
 }
 
@@ -738,11 +747,14 @@ static void sane_block_input(struct net_
 	if (xfer_start + count > ei_status.rmem_end) {
 		/* We must wrap the input move. */
 		int semi_count = ei_status.rmem_end - xfer_start;
-		memcpy_fromio(skb->data, (char *)dev->mem_start + xfer_base, semi_count);
+		memcpy_fromio(skb->data, (char *)dev->mem_start + xfer_base,
+			      semi_count);
 		count -= semi_count;
-		memcpy_toio(skb->data + semi_count, (char *)ei_status.rmem_start, count);
+		memcpy_toio(skb->data + semi_count,
+			    (char *)ei_status.rmem_start, count);
 	} else {
-		memcpy_fromio(skb->data, (char *)dev->mem_start + xfer_base, count);
+		memcpy_fromio(skb->data, (char *)dev->mem_start + xfer_base,
+			      count);
 	}
 }
 
@@ -755,16 +767,18 @@ static void sane_block_output(struct net
 }
 
 /* dayna block input/output */
-static void dayna_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
+static void dayna_get_8390_hdr(struct net_device *dev,
+			       struct e8390_pkt_hdr *hdr, int ring_page)
 {
 	unsigned long hdr_start = (ring_page - WD_START_PG)<<8;
 
-	dayna_memcpy_fromcard(dev, (void *)hdr, hdr_start, 4);
+	dayna_memcpy_fromcard(dev, hdr, hdr_start, 4);
 	/* Fix endianness */
-	hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8);
+	hdr->count = (hdr->count & 0xFF) << 8 | (hdr->count >> 8);
 }
 
-static void dayna_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
+static void dayna_block_input(struct net_device *dev, int count,
+			      struct sk_buff *skb, int ring_offset)
 {
 	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
 	unsigned long xfer_start = xfer_base+dev->mem_start;
@@ -772,8 +786,7 @@ static void dayna_block_input(struct net
 	/* Note the offset math is done in card memory space which is word
 	   per long onto our space. */
 
-	if (xfer_start + count > ei_status.rmem_end)
-	{
+	if (xfer_start + count > ei_status.rmem_end) {
 		/* We must wrap the input move. */
 		int semi_count = ei_status.rmem_end - xfer_start;
 		dayna_memcpy_fromcard(dev, skb->data, xfer_base, semi_count);
@@ -781,15 +794,14 @@ static void dayna_block_input(struct net
 		dayna_memcpy_fromcard(dev, skb->data + semi_count,
 				      ei_status.rmem_start - dev->mem_start,
 				      count);
-	}
-	else
-	{
+	} else {
 		dayna_memcpy_fromcard(dev, skb->data, xfer_base, count);
 	}
 }
 
-static void dayna_block_output(struct net_device *dev, int count, const unsigned char *buf,
-				int start_page)
+static void dayna_block_output(struct net_device *dev, int count,
+			       const unsigned char *buf,
+			       int start_page)
 {
 	long shmem = (start_page - WD_START_PG)<<8;
 
@@ -797,40 +809,39 @@ static void dayna_block_output(struct ne
 }
 
 /* Cabletron block I/O */
-static void slow_sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
-	int ring_page)
+static void slow_sane_get_8390_hdr(struct net_device *dev,
+				   struct e8390_pkt_hdr *hdr,
+				   int ring_page)
 {
 	unsigned long hdr_start = (ring_page - WD_START_PG)<<8;
-	word_memcpy_fromcard((void *)hdr, (char *)dev->mem_start+hdr_start, 4);
+	word_memcpy_fromcard(hdr, (char *)dev->mem_start + hdr_start, 4);
 	/* Register endianism - fix here rather than 8390.c */
 	hdr->count = (hdr->count&0xFF)<<8|(hdr->count>>8);
 }
 
-static void slow_sane_block_input(struct net_device *dev, int count, struct sk_buff *skb,
-	int ring_offset)
+static void slow_sane_block_input(struct net_device *dev, int count,
+				  struct sk_buff *skb, int ring_offset)
 {
 	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
 	unsigned long xfer_start = xfer_base+dev->mem_start;
 
-	if (xfer_start + count > ei_status.rmem_end)
-	{
+	if (xfer_start + count > ei_status.rmem_end) {
 		/* We must wrap the input move. */
 		int semi_count = ei_status.rmem_end - xfer_start;
-		word_memcpy_fromcard(skb->data, (char *)dev->mem_start +
-			xfer_base, semi_count);
+		word_memcpy_fromcard(skb->data,
+				     (char *)dev->mem_start + xfer_base,
+				     semi_count);
 		count -= semi_count;
 		word_memcpy_fromcard(skb->data + semi_count,
 				     (char *)ei_status.rmem_start, count);
-	}
-	else
-	{
-		word_memcpy_fromcard(skb->data, (char *)dev->mem_start +
-			xfer_base, count);
+	} else {
+		word_memcpy_fromcard(skb->data,
+				     (char *)dev->mem_start + xfer_base, count);
 	}
 }
 
-static void slow_sane_block_output(struct net_device *dev, int count, const unsigned char *buf,
-	int start_page)
+static void slow_sane_block_output(struct net_device *dev, int count,
+				   const unsigned char *buf, int start_page)
 {
 	long shmem = (start_page - WD_START_PG)<<8;
 
@@ -843,10 +854,10 @@ static void word_memcpy_tocard(void *tp,
 	const unsigned short *from = fp;
 
 	count++;
-	count/=2;
+	count /= 2;
 
-	while(count--)
-		*to++=*from++;
+	while (count--)
+		*to++ = *from++;
 }
 
 static void word_memcpy_fromcard(void *tp, const void *fp, int count)
@@ -855,10 +866,10 @@ static void word_memcpy_fromcard(void *t
 	const volatile unsigned short *from = fp;
 
 	count++;
-	count/=2;
+	count /= 2;
 
-	while(count--)
-		*to++=*from++;
+	while (count--)
+		*to++ = *from++;
 }
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mac89x0.c linux-libre-2.6.34-gnu1/drivers/net/mac89x0.c
--- linux-libre-2.6.33-gnu1/drivers/net/mac89x0.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mac89x0.c	2010-05-16 17:17:36.000000000 -0400
@@ -88,7 +88,6 @@ static char *version =
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/nubus.h>
 #include <linux/errno.h>
@@ -98,6 +97,7 @@ static char *version =
 #include <linux/skbuff.h>
 #include <linux/delay.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -568,9 +568,7 @@ static void set_multicast_list(struct ne
 	if(dev->flags&IFF_PROMISC)
 	{
 		lp->rx_mode = RX_ALL_ACCEPT;
-	}
-	else if((dev->flags&IFF_ALLMULTI)||dev->mc_list)
-	{
+	} else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev)) {
 		/* The multicast-accept list is initialized to accept-all, and we
 		   rely on higher-level filtering for now. */
 		lp->rx_mode = RX_MULTCAST_ACCEPT;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/macb.c linux-libre-2.6.34-gnu1/drivers/net/macb.c
--- linux-libre-2.6.33-gnu1/drivers/net/macb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/macb.c	2010-05-16 17:17:36.000000000 -0400
@@ -189,18 +189,11 @@ static void macb_handle_link_change(stru
 static int macb_mii_probe(struct net_device *dev)
 {
 	struct macb *bp = netdev_priv(dev);
-	struct phy_device *phydev = NULL;
+	struct phy_device *phydev;
 	struct eth_platform_data *pdata;
-	int phy_addr;
-
-	/* find the first phy */
-	for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
-		if (bp->mii_bus->phy_map[phy_addr]) {
-			phydev = bp->mii_bus->phy_map[phy_addr];
-			break;
-		}
-	}
+	int ret;
 
+	phydev = phy_find_first(bp->mii_bus);
 	if (!phydev) {
 		printk (KERN_ERR "%s: no PHY found\n", dev->name);
 		return -1;
@@ -210,17 +203,13 @@ static int macb_mii_probe(struct net_dev
 	/* TODO : add pin_irq */
 
 	/* attach the mac to the phy */
-	if (pdata && pdata->is_rmii) {
-		phydev = phy_connect(dev, dev_name(&phydev->dev),
-			&macb_handle_link_change, 0, PHY_INTERFACE_MODE_RMII);
-	} else {
-		phydev = phy_connect(dev, dev_name(&phydev->dev),
-			&macb_handle_link_change, 0, PHY_INTERFACE_MODE_MII);
-	}
-
-	if (IS_ERR(phydev)) {
+	ret = phy_connect_direct(dev, phydev, &macb_handle_link_change, 0,
+				 pdata && pdata->is_rmii ?
+				 PHY_INTERFACE_MODE_RMII :
+				 PHY_INTERFACE_MODE_MII);
+	if (ret) {
 		printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
-		return PTR_ERR(phydev);
+		return ret;
 	}
 
 	/* mask with MAC supported features */
@@ -895,15 +884,12 @@ static void macb_sethashtable(struct net
 {
 	struct dev_mc_list *curr;
 	unsigned long mc_filter[2];
-	unsigned int i, bitnr;
+	unsigned int bitnr;
 	struct macb *bp = netdev_priv(dev);
 
 	mc_filter[0] = mc_filter[1] = 0;
 
-	curr = dev->mc_list;
-	for (i = 0; i < dev->mc_count; i++, curr = curr->next) {
-		if (!curr) break;	/* unexpected end of list */
-
+	netdev_for_each_mc_addr(curr, dev) {
 		bitnr = hash_get_index(curr->dmi_addr);
 		mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
 	}
@@ -934,7 +920,7 @@ static void macb_set_rx_mode(struct net_
 		macb_writel(bp, HRB, -1);
 		macb_writel(bp, HRT, -1);
 		cfg |= MACB_BIT(NCFGR_MTI);
-	} else if (dev->mc_count > 0) {
+	} else if (!netdev_mc_empty(dev)) {
 		/* Enable specific multicasts */
 		macb_sethashtable(dev);
 		cfg |= MACB_BIT(NCFGR_MTI);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mace.c linux-libre-2.6.34-gnu1/drivers/net/mace.c
--- linux-libre-2.6.33-gnu1/drivers/net/mace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mace.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/crc32.h>
 #include <linux/spinlock.h>
 #include <linux/bitrev.h>
+#include <linux/slab.h>
 #include <asm/prom.h>
 #include <asm/dbdma.h>
 #include <asm/io.h>
@@ -206,7 +207,7 @@ static int __devinit mace_probe(struct m
 		mp->port_aaui = port_aaui;
 	else {
 		/* Apple Network Server uses the AAUI port */
-		if (machine_is_compatible("AAPL,ShinerESB"))
+		if (of_machine_is_compatible("AAPL,ShinerESB"))
 			mp->port_aaui = 1;
 		else {
 #ifdef CONFIG_MACE_AAUI_PORT
@@ -588,7 +589,7 @@ static void mace_set_multicast(struct ne
 {
     struct mace_data *mp = netdev_priv(dev);
     volatile struct mace __iomem *mb = mp->mace;
-    int i, j;
+    int i;
     u32 crc;
     unsigned long flags;
 
@@ -598,7 +599,7 @@ static void mace_set_multicast(struct ne
 	mp->maccc |= PROM;
     } else {
 	unsigned char multicast_filter[8];
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 
 	if (dev->flags & IFF_ALLMULTI) {
 	    for (i = 0; i < 8; i++)
@@ -606,11 +607,10 @@ static void mace_set_multicast(struct ne
 	} else {
 	    for (i = 0; i < 8; i++)
 		multicast_filter[i] = 0;
-	    for (i = 0; i < dev->mc_count; i++) {
+	    netdev_for_each_mc_addr(dmi, dev) {
 	        crc = ether_crc_le(6, dmi->dmi_addr);
-		j = crc >> 26;	/* bit number in multicast_filter */
-		multicast_filter[j >> 3] |= 1 << (j & 7);
-		dmi = dmi->next;
+		i = crc >> 26;	/* bit number in multicast_filter */
+		multicast_filter[i >> 3] |= 1 << (i & 7);
 	    }
 	}
 #if 0
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/macmace.c linux-libre-2.6.34-gnu1/drivers/net/macmace.c
--- linux-libre-2.6.33-gnu1/drivers/net/macmace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/macmace.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/bitrev.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/macintosh.h>
@@ -39,7 +40,6 @@
 #include "mace.h"
 
 static char mac_mace_string[] = "macmace";
-static struct platform_device *mac_mace_device;
 
 #define N_TX_BUFF_ORDER	0
 #define N_TX_RING	(1 << N_TX_BUFF_ORDER)
@@ -496,7 +496,7 @@ static void mace_set_multicast(struct ne
 {
 	struct mace_data *mp = netdev_priv(dev);
 	volatile struct mace *mb = mp->mace;
-	int i, j;
+	int i;
 	u32 crc;
 	u8 maccc;
 	unsigned long flags;
@@ -509,7 +509,7 @@ static void mace_set_multicast(struct ne
 		mb->maccc |= PROM;
 	} else {
 		unsigned char multicast_filter[8];
-		struct dev_mc_list *dmi = dev->mc_list;
+		struct dev_mc_list *dmi;
 
 		if (dev->flags & IFF_ALLMULTI) {
 			for (i = 0; i < 8; i++) {
@@ -518,11 +518,11 @@ static void mace_set_multicast(struct ne
 		} else {
 			for (i = 0; i < 8; i++)
 				multicast_filter[i] = 0;
-			for (i = 0; i < dev->mc_count; i++) {
+			netdev_for_each_mc_addr(dmi, dev) {
 				crc = ether_crc_le(6, dmi->dmi_addr);
-				j = crc >> 26;	/* bit number in multicast_filter */
-				multicast_filter[j >> 3] |= 1 << (j & 7);
-				dmi = dmi->next;
+				/* bit number in multicast_filter */
+				i = crc >> 26;
+				multicast_filter[i >> 3] |= 1 << (i & 7);
 			}
 		}
 
@@ -752,6 +752,7 @@ static irqreturn_t mace_dma_intr(int irq
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Macintosh MACE ethernet driver");
+MODULE_ALIAS("platform:macmace");
 
 static int __devexit mac_mace_device_remove (struct platform_device *pdev)
 {
@@ -777,47 +778,22 @@ static struct platform_driver mac_mace_d
 	.probe  = mace_probe,
 	.remove = __devexit_p(mac_mace_device_remove),
 	.driver	= {
-		.name = mac_mace_string,
+		.name	= mac_mace_string,
+		.owner	= THIS_MODULE,
 	},
 };
 
 static int __init mac_mace_init_module(void)
 {
-	int err;
-
 	if (!MACH_IS_MAC)
 		return -ENODEV;
 
-	if ((err = platform_driver_register(&mac_mace_driver))) {
-		printk(KERN_ERR "Driver registration failed\n");
-		return err;
-	}
-
-	mac_mace_device = platform_device_alloc(mac_mace_string, 0);
-	if (!mac_mace_device)
-		goto out_unregister;
-
-	if (platform_device_add(mac_mace_device)) {
-		platform_device_put(mac_mace_device);
-		mac_mace_device = NULL;
-	}
-
-	return 0;
-
-out_unregister:
-	platform_driver_unregister(&mac_mace_driver);
-
-	return -ENOMEM;
+	return platform_driver_register(&mac_mace_driver);
 }
 
 static void __exit mac_mace_cleanup_module(void)
 {
 	platform_driver_unregister(&mac_mace_driver);
-
-	if (mac_mace_device) {
-		platform_device_unregister(mac_mace_device);
-		mac_mace_device = NULL;
-	}
 }
 
 module_init(mac_mace_init_module);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/macsonic.c linux-libre-2.6.34-gnu1/drivers/net/macsonic.c
--- linux-libre-2.6.33-gnu1/drivers/net/macsonic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/macsonic.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,11 +35,11 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
+#include <linux/gfp.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/nubus.h>
@@ -50,6 +50,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/bitrev.h>
+#include <linux/slab.h>
 
 #include <asm/bootinfo.h>
 #include <asm/system.h>
@@ -62,7 +63,6 @@
 #include <asm/mac_via.h>
 
 static char mac_sonic_string[] = "macsonic";
-static struct platform_device *mac_sonic_device;
 
 #include "sonic.h"
 
@@ -607,6 +607,7 @@ out:
 MODULE_DESCRIPTION("Macintosh SONIC ethernet driver");
 module_param(sonic_debug, int, 0);
 MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)");
+MODULE_ALIAS("platform:macsonic");
 
 #include "sonic.c"
 
@@ -627,44 +628,19 @@ static struct platform_driver mac_sonic_
 	.probe  = mac_sonic_probe,
 	.remove = __devexit_p(mac_sonic_device_remove),
 	.driver	= {
-		.name = mac_sonic_string,
+		.name	= mac_sonic_string,
+		.owner	= THIS_MODULE,
 	},
 };
 
 static int __init mac_sonic_init_module(void)
 {
-	int err;
-
-	if ((err = platform_driver_register(&mac_sonic_driver))) {
-		printk(KERN_ERR "Driver registration failed\n");
-		return err;
-	}
-
-	mac_sonic_device = platform_device_alloc(mac_sonic_string, 0);
-	if (!mac_sonic_device)
-		goto out_unregister;
-
-	if (platform_device_add(mac_sonic_device)) {
-		platform_device_put(mac_sonic_device);
-		mac_sonic_device = NULL;
-	}
-
-	return 0;
-
-out_unregister:
-	platform_driver_unregister(&mac_sonic_driver);
-
-	return -ENOMEM;
+	return platform_driver_register(&mac_sonic_driver);
 }
 
 static void __exit mac_sonic_cleanup_module(void)
 {
 	platform_driver_unregister(&mac_sonic_driver);
-
-	if (mac_sonic_device) {
-		platform_device_unregister(mac_sonic_device);
-		mac_sonic_device = NULL;
-	}
 }
 
 module_init(mac_sonic_init_module);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/macvlan.c linux-libre-2.6.34-gnu1/drivers/net/macvlan.c
--- linux-libre-2.6.33-gnu1/drivers/net/macvlan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/macvlan.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,31 +39,6 @@ struct macvlan_port {
 	struct list_head	vlans;
 };
 
-/**
- *	struct macvlan_rx_stats - MACVLAN percpu rx stats
- *	@rx_packets: number of received packets
- *	@rx_bytes: number of received bytes
- *	@multicast: number of received multicast packets
- *	@rx_errors: number of errors
- */
-struct macvlan_rx_stats {
-	unsigned long rx_packets;
-	unsigned long rx_bytes;
-	unsigned long multicast;
-	unsigned long rx_errors;
-};
-
-struct macvlan_dev {
-	struct net_device	*dev;
-	struct list_head	list;
-	struct hlist_node	hlist;
-	struct macvlan_port	*port;
-	struct net_device	*lowerdev;
-	struct macvlan_rx_stats *rx_stats;
-	enum macvlan_mode	mode;
-};
-
-
 static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port,
 					       const unsigned char *addr)
 {
@@ -118,31 +93,17 @@ static int macvlan_addr_busy(const struc
 	return 0;
 }
 
-static inline void macvlan_count_rx(const struct macvlan_dev *vlan,
-				    unsigned int len, bool success,
-				    bool multicast)
-{
-	struct macvlan_rx_stats *rx_stats;
 
-	rx_stats = per_cpu_ptr(vlan->rx_stats, smp_processor_id());
-	if (likely(success)) {
-		rx_stats->rx_packets++;;
-		rx_stats->rx_bytes += len;
-		if (multicast)
-			rx_stats->multicast++;
-	} else {
-		rx_stats->rx_errors++;
-	}
-}
-
-static int macvlan_broadcast_one(struct sk_buff *skb, struct net_device *dev,
+static int macvlan_broadcast_one(struct sk_buff *skb,
+				 const struct macvlan_dev *vlan,
 				 const struct ethhdr *eth, bool local)
 {
+	struct net_device *dev = vlan->dev;
 	if (!skb)
 		return NET_RX_DROP;
 
 	if (local)
-		return dev_forward_skb(dev, skb);
+		return vlan->forward(dev, skb);
 
 	skb->dev = dev;
 	if (!compare_ether_addr_64bits(eth->h_dest,
@@ -151,7 +112,7 @@ static int macvlan_broadcast_one(struct
 	else
 		skb->pkt_type = PACKET_MULTICAST;
 
-	return netif_rx(skb);
+	return vlan->receive(skb);
 }
 
 static void macvlan_broadcast(struct sk_buff *skb,
@@ -175,7 +136,7 @@ static void macvlan_broadcast(struct sk_
 				continue;
 
 			nskb = skb_clone(skb, GFP_ATOMIC);
-			err = macvlan_broadcast_one(nskb, vlan->dev, eth,
+			err = macvlan_broadcast_one(nskb, vlan, eth,
 					 mode == MACVLAN_MODE_BRIDGE);
 			macvlan_count_rx(vlan, skb->len + ETH_HLEN,
 					 err == NET_RX_SUCCESS, 1);
@@ -238,7 +199,7 @@ static struct sk_buff *macvlan_handle_fr
 	skb->dev = dev;
 	skb->pkt_type = PACKET_HOST;
 
-	netif_rx(skb);
+	vlan->receive(skb);
 	return NULL;
 }
 
@@ -260,7 +221,7 @@ static int macvlan_queue_xmit(struct sk_
 		dest = macvlan_hash_lookup(port, eth->h_dest);
 		if (dest && dest->mode == MACVLAN_MODE_BRIDGE) {
 			unsigned int length = skb->len + ETH_HLEN;
-			int ret = dev_forward_skb(dest->dev, skb);
+			int ret = dest->forward(dest->dev, skb);
 			macvlan_count_rx(dest, length,
 					 ret == NET_RX_SUCCESS, 0);
 
@@ -269,12 +230,12 @@ static int macvlan_queue_xmit(struct sk_
 	}
 
 xmit_world:
-	skb->dev = vlan->lowerdev;
+	skb_set_dev(skb, vlan->lowerdev);
 	return dev_queue_xmit(skb);
 }
 
-static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
-				      struct net_device *dev)
+netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
+			       struct net_device *dev)
 {
 	int i = skb_get_queue_mapping(skb);
 	struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
@@ -290,6 +251,7 @@ static netdev_tx_t macvlan_start_xmit(st
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(macvlan_start_xmit);
 
 static int macvlan_hard_header(struct sk_buff *skb, struct net_device *dev,
 			       unsigned short type, const void *daddr,
@@ -418,7 +380,7 @@ static struct lock_class_key macvlan_net
 #define MACVLAN_FEATURES \
 	(NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
 	 NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO_ROBUST | \
-	 NETIF_F_TSO_ECN | NETIF_F_TSO6)
+	 NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO)
 
 #define MACVLAN_STATE_MASK \
 	((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT))
@@ -623,8 +585,11 @@ static int macvlan_get_tx_queues(struct
 	return 0;
 }
 
-static int macvlan_newlink(struct net *src_net, struct net_device *dev,
-			   struct nlattr *tb[], struct nlattr *data[])
+int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
+			   struct nlattr *tb[], struct nlattr *data[],
+			   int (*receive)(struct sk_buff *skb),
+			   int (*forward)(struct net_device *dev,
+					  struct sk_buff *skb))
 {
 	struct macvlan_dev *vlan = netdev_priv(dev);
 	struct macvlan_port *port;
@@ -664,6 +629,8 @@ static int macvlan_newlink(struct net *s
 	vlan->lowerdev = lowerdev;
 	vlan->dev      = dev;
 	vlan->port     = port;
+	vlan->receive  = receive;
+	vlan->forward  = forward;
 
 	vlan->mode     = MACVLAN_MODE_VEPA;
 	if (data && data[IFLA_MACVLAN_MODE])
@@ -677,8 +644,17 @@ static int macvlan_newlink(struct net *s
 	netif_stacked_transfer_operstate(lowerdev, dev);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(macvlan_common_newlink);
 
-static void macvlan_dellink(struct net_device *dev, struct list_head *head)
+static int macvlan_newlink(struct net *src_net, struct net_device *dev,
+			   struct nlattr *tb[], struct nlattr *data[])
+{
+	return macvlan_common_newlink(src_net, dev, tb, data,
+				      netif_rx,
+				      dev_forward_skb);
+}
+
+void macvlan_dellink(struct net_device *dev, struct list_head *head)
 {
 	struct macvlan_dev *vlan = netdev_priv(dev);
 	struct macvlan_port *port = vlan->port;
@@ -689,6 +665,7 @@ static void macvlan_dellink(struct net_d
 	if (list_empty(&port->vlans))
 		macvlan_port_destroy(port->dev);
 }
+EXPORT_SYMBOL_GPL(macvlan_dellink);
 
 static int macvlan_changelink(struct net_device *dev,
 		struct nlattr *tb[], struct nlattr *data[])
@@ -720,19 +697,27 @@ static const struct nla_policy macvlan_p
 	[IFLA_MACVLAN_MODE] = { .type = NLA_U32 },
 };
 
-static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
+int macvlan_link_register(struct rtnl_link_ops *ops)
+{
+	/* common fields */
+	ops->priv_size		= sizeof(struct macvlan_dev);
+	ops->get_tx_queues	= macvlan_get_tx_queues;
+	ops->setup		= macvlan_setup;
+	ops->validate		= macvlan_validate;
+	ops->maxtype		= IFLA_MACVLAN_MAX;
+	ops->policy		= macvlan_policy;
+	ops->changelink		= macvlan_changelink;
+	ops->get_size		= macvlan_get_size;
+	ops->fill_info		= macvlan_fill_info;
+
+	return rtnl_link_register(ops);
+};
+EXPORT_SYMBOL_GPL(macvlan_link_register);
+
+static struct rtnl_link_ops macvlan_link_ops = {
 	.kind		= "macvlan",
-	.priv_size	= sizeof(struct macvlan_dev),
-	.get_tx_queues  = macvlan_get_tx_queues,
-	.setup		= macvlan_setup,
-	.validate	= macvlan_validate,
 	.newlink	= macvlan_newlink,
 	.dellink	= macvlan_dellink,
-	.maxtype	= IFLA_MACVLAN_MAX,
-	.policy		= macvlan_policy,
-	.changelink	= macvlan_changelink,
-	.get_size	= macvlan_get_size,
-	.fill_info	= macvlan_fill_info,
 };
 
 static int macvlan_device_event(struct notifier_block *unused,
@@ -761,7 +746,7 @@ static int macvlan_device_event(struct n
 		break;
 	case NETDEV_UNREGISTER:
 		list_for_each_entry_safe(vlan, next, &port->vlans, list)
-			macvlan_dellink(vlan->dev, NULL);
+			vlan->dev->rtnl_link_ops->dellink(vlan->dev, NULL);
 		break;
 	}
 	return NOTIFY_DONE;
@@ -778,7 +763,7 @@ static int __init macvlan_init_module(vo
 	register_netdevice_notifier(&macvlan_notifier_block);
 	macvlan_handle_frame_hook = macvlan_handle_frame;
 
-	err = rtnl_link_register(&macvlan_link_ops);
+	err = macvlan_link_register(&macvlan_link_ops);
 	if (err < 0)
 		goto err1;
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/macvtap.c linux-libre-2.6.34-gnu1/drivers/net/macvtap.c
--- linux-libre-2.6.33-gnu1/drivers/net/macvtap.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/macvtap.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,804 @@
+#include <linux/etherdevice.h>
+#include <linux/if_macvlan.h>
+#include <linux/interrupt.h>
+#include <linux/nsproxy.h>
+#include <linux/compat.h>
+#include <linux/if_tun.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/cache.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/wait.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+
+#include <net/net_namespace.h>
+#include <net/rtnetlink.h>
+#include <net/sock.h>
+#include <linux/virtio_net.h>
+
+/*
+ * A macvtap queue is the central object of this driver, it connects
+ * an open character device to a macvlan interface. There can be
+ * multiple queues on one interface, which map back to queues
+ * implemented in hardware on the underlying device.
+ *
+ * macvtap_proto is used to allocate queues through the sock allocation
+ * mechanism.
+ *
+ * TODO: multiqueue support is currently not implemented, even though
+ * macvtap is basically prepared for that. We will need to add this
+ * here as well as in virtio-net and qemu to get line rate on 10gbit
+ * adapters from a guest.
+ */
+struct macvtap_queue {
+	struct sock sk;
+	struct socket sock;
+	struct macvlan_dev *vlan;
+	struct file *file;
+	unsigned int flags;
+};
+
+static struct proto macvtap_proto = {
+	.name = "macvtap",
+	.owner = THIS_MODULE,
+	.obj_size = sizeof (struct macvtap_queue),
+};
+
+/*
+ * Minor number matches netdev->ifindex, so need a potentially
+ * large value. This also makes it possible to split the
+ * tap functionality out again in the future by offering it
+ * from other drivers besides macvtap. As long as every device
+ * only has one tap, the interface numbers assure that the
+ * device nodes are unique.
+ */
+static unsigned int macvtap_major;
+#define MACVTAP_NUM_DEVS 65536
+static struct class *macvtap_class;
+static struct cdev macvtap_cdev;
+
+static const struct proto_ops macvtap_socket_ops;
+
+/*
+ * RCU usage:
+ * The macvtap_queue and the macvlan_dev are loosely coupled, the
+ * pointers from one to the other can only be read while rcu_read_lock
+ * or macvtap_lock is held.
+ *
+ * Both the file and the macvlan_dev hold a reference on the macvtap_queue
+ * through sock_hold(&q->sk). When the macvlan_dev goes away first,
+ * q->vlan becomes inaccessible. When the files gets closed,
+ * macvtap_get_queue() fails.
+ *
+ * There may still be references to the struct sock inside of the
+ * queue from outbound SKBs, but these never reference back to the
+ * file or the dev. The data structure is freed through __sk_free
+ * when both our references and any pending SKBs are gone.
+ */
+static DEFINE_SPINLOCK(macvtap_lock);
+
+/*
+ * Choose the next free queue, for now there is only one
+ */
+static int macvtap_set_queue(struct net_device *dev, struct file *file,
+				struct macvtap_queue *q)
+{
+	struct macvlan_dev *vlan = netdev_priv(dev);
+	int err = -EBUSY;
+
+	spin_lock(&macvtap_lock);
+	if (rcu_dereference(vlan->tap))
+		goto out;
+
+	err = 0;
+	rcu_assign_pointer(q->vlan, vlan);
+	rcu_assign_pointer(vlan->tap, q);
+	sock_hold(&q->sk);
+
+	q->file = file;
+	file->private_data = q;
+
+out:
+	spin_unlock(&macvtap_lock);
+	return err;
+}
+
+/*
+ * The file owning the queue got closed, give up both
+ * the reference that the files holds as well as the
+ * one from the macvlan_dev if that still exists.
+ *
+ * Using the spinlock makes sure that we don't get
+ * to the queue again after destroying it.
+ */
+static void macvtap_put_queue(struct macvtap_queue *q)
+{
+	struct macvlan_dev *vlan;
+
+	spin_lock(&macvtap_lock);
+	vlan = rcu_dereference(q->vlan);
+	if (vlan) {
+		rcu_assign_pointer(vlan->tap, NULL);
+		rcu_assign_pointer(q->vlan, NULL);
+		sock_put(&q->sk);
+	}
+
+	spin_unlock(&macvtap_lock);
+
+	synchronize_rcu();
+	sock_put(&q->sk);
+}
+
+/*
+ * Since we only support one queue, just dereference the pointer.
+ */
+static struct macvtap_queue *macvtap_get_queue(struct net_device *dev,
+					       struct sk_buff *skb)
+{
+	struct macvlan_dev *vlan = netdev_priv(dev);
+
+	return rcu_dereference(vlan->tap);
+}
+
+/*
+ * The net_device is going away, give up the reference
+ * that it holds on the queue (all the queues one day)
+ * and safely set the pointer from the queues to NULL.
+ */
+static void macvtap_del_queues(struct net_device *dev)
+{
+	struct macvlan_dev *vlan = netdev_priv(dev);
+	struct macvtap_queue *q;
+
+	spin_lock(&macvtap_lock);
+	q = rcu_dereference(vlan->tap);
+	if (!q) {
+		spin_unlock(&macvtap_lock);
+		return;
+	}
+
+	rcu_assign_pointer(vlan->tap, NULL);
+	rcu_assign_pointer(q->vlan, NULL);
+	spin_unlock(&macvtap_lock);
+
+	synchronize_rcu();
+	sock_put(&q->sk);
+}
+
+/*
+ * Forward happens for data that gets sent from one macvlan
+ * endpoint to another one in bridge mode. We just take
+ * the skb and put it into the receive queue.
+ */
+static int macvtap_forward(struct net_device *dev, struct sk_buff *skb)
+{
+	struct macvtap_queue *q = macvtap_get_queue(dev, skb);
+	if (!q)
+		return -ENOLINK;
+
+	skb_queue_tail(&q->sk.sk_receive_queue, skb);
+	wake_up_interruptible_poll(q->sk.sk_sleep, POLLIN | POLLRDNORM | POLLRDBAND);
+	return 0;
+}
+
+/*
+ * Receive is for data from the external interface (lowerdev),
+ * in case of macvtap, we can treat that the same way as
+ * forward, which macvlan cannot.
+ */
+static int macvtap_receive(struct sk_buff *skb)
+{
+	skb_push(skb, ETH_HLEN);
+	return macvtap_forward(skb->dev, skb);
+}
+
+static int macvtap_newlink(struct net *src_net,
+			   struct net_device *dev,
+			   struct nlattr *tb[],
+			   struct nlattr *data[])
+{
+	struct device *classdev;
+	dev_t devt;
+	int err;
+
+	err = macvlan_common_newlink(src_net, dev, tb, data,
+				     macvtap_receive, macvtap_forward);
+	if (err)
+		goto out;
+
+	devt = MKDEV(MAJOR(macvtap_major), dev->ifindex);
+
+	classdev = device_create(macvtap_class, &dev->dev, devt,
+				 dev, "tap%d", dev->ifindex);
+	if (IS_ERR(classdev)) {
+		err = PTR_ERR(classdev);
+		macvtap_del_queues(dev);
+	}
+
+out:
+	return err;
+}
+
+static void macvtap_dellink(struct net_device *dev,
+			    struct list_head *head)
+{
+	device_destroy(macvtap_class,
+		       MKDEV(MAJOR(macvtap_major), dev->ifindex));
+
+	macvtap_del_queues(dev);
+	macvlan_dellink(dev, head);
+}
+
+static struct rtnl_link_ops macvtap_link_ops __read_mostly = {
+	.kind		= "macvtap",
+	.newlink	= macvtap_newlink,
+	.dellink	= macvtap_dellink,
+};
+
+
+static void macvtap_sock_write_space(struct sock *sk)
+{
+	if (!sock_writeable(sk) ||
+	    !test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags))
+		return;
+
+	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+		wake_up_interruptible_poll(sk->sk_sleep, POLLOUT | POLLWRNORM | POLLWRBAND);
+}
+
+static int macvtap_open(struct inode *inode, struct file *file)
+{
+	struct net *net = current->nsproxy->net_ns;
+	struct net_device *dev = dev_get_by_index(net, iminor(inode));
+	struct macvtap_queue *q;
+	int err;
+
+	err = -ENODEV;
+	if (!dev)
+		goto out;
+
+	/* check if this is a macvtap device */
+	err = -EINVAL;
+	if (dev->rtnl_link_ops != &macvtap_link_ops)
+		goto out;
+
+	err = -ENOMEM;
+	q = (struct macvtap_queue *)sk_alloc(net, AF_UNSPEC, GFP_KERNEL,
+					     &macvtap_proto);
+	if (!q)
+		goto out;
+
+	init_waitqueue_head(&q->sock.wait);
+	q->sock.type = SOCK_RAW;
+	q->sock.state = SS_CONNECTED;
+	q->sock.file = file;
+	q->sock.ops = &macvtap_socket_ops;
+	sock_init_data(&q->sock, &q->sk);
+	q->sk.sk_write_space = macvtap_sock_write_space;
+	q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP;
+
+	err = macvtap_set_queue(dev, file, q);
+	if (err)
+		sock_put(&q->sk);
+
+out:
+	if (dev)
+		dev_put(dev);
+
+	return err;
+}
+
+static int macvtap_release(struct inode *inode, struct file *file)
+{
+	struct macvtap_queue *q = file->private_data;
+	macvtap_put_queue(q);
+	return 0;
+}
+
+static unsigned int macvtap_poll(struct file *file, poll_table * wait)
+{
+	struct macvtap_queue *q = file->private_data;
+	unsigned int mask = POLLERR;
+
+	if (!q)
+		goto out;
+
+	mask = 0;
+	poll_wait(file, &q->sock.wait, wait);
+
+	if (!skb_queue_empty(&q->sk.sk_receive_queue))
+		mask |= POLLIN | POLLRDNORM;
+
+	if (sock_writeable(&q->sk) ||
+	    (!test_and_set_bit(SOCK_ASYNC_NOSPACE, &q->sock.flags) &&
+	     sock_writeable(&q->sk)))
+		mask |= POLLOUT | POLLWRNORM;
+
+out:
+	return mask;
+}
+
+static inline struct sk_buff *macvtap_alloc_skb(struct sock *sk, size_t prepad,
+						size_t len, size_t linear,
+						int noblock, int *err)
+{
+	struct sk_buff *skb;
+
+	/* Under a page?  Don't bother with paged skb. */
+	if (prepad + len < PAGE_SIZE || !linear)
+		linear = len;
+
+	skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock,
+				   err);
+	if (!skb)
+		return NULL;
+
+	skb_reserve(skb, prepad);
+	skb_put(skb, linear);
+	skb->data_len = len - linear;
+	skb->len += len - linear;
+
+	return skb;
+}
+
+/*
+ * macvtap_skb_from_vnet_hdr and macvtap_skb_to_vnet_hdr should
+ * be shared with the tun/tap driver.
+ */
+static int macvtap_skb_from_vnet_hdr(struct sk_buff *skb,
+				     struct virtio_net_hdr *vnet_hdr)
+{
+	unsigned short gso_type = 0;
+	if (vnet_hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+		switch (vnet_hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+		case VIRTIO_NET_HDR_GSO_TCPV4:
+			gso_type = SKB_GSO_TCPV4;
+			break;
+		case VIRTIO_NET_HDR_GSO_TCPV6:
+			gso_type = SKB_GSO_TCPV6;
+			break;
+		case VIRTIO_NET_HDR_GSO_UDP:
+			gso_type = SKB_GSO_UDP;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		if (vnet_hdr->gso_type & VIRTIO_NET_HDR_GSO_ECN)
+			gso_type |= SKB_GSO_TCP_ECN;
+
+		if (vnet_hdr->gso_size == 0)
+			return -EINVAL;
+	}
+
+	if (vnet_hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+		if (!skb_partial_csum_set(skb, vnet_hdr->csum_start,
+					  vnet_hdr->csum_offset))
+			return -EINVAL;
+	}
+
+	if (vnet_hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+		skb_shinfo(skb)->gso_size = vnet_hdr->gso_size;
+		skb_shinfo(skb)->gso_type = gso_type;
+
+		/* Header must be checked, and gso_segs computed. */
+		skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+		skb_shinfo(skb)->gso_segs = 0;
+	}
+	return 0;
+}
+
+static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
+				   struct virtio_net_hdr *vnet_hdr)
+{
+	memset(vnet_hdr, 0, sizeof(*vnet_hdr));
+
+	if (skb_is_gso(skb)) {
+		struct skb_shared_info *sinfo = skb_shinfo(skb);
+
+		/* This is a hint as to how much should be linear. */
+		vnet_hdr->hdr_len = skb_headlen(skb);
+		vnet_hdr->gso_size = sinfo->gso_size;
+		if (sinfo->gso_type & SKB_GSO_TCPV4)
+			vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+		else if (sinfo->gso_type & SKB_GSO_TCPV6)
+			vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+		else if (sinfo->gso_type & SKB_GSO_UDP)
+			vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
+		else
+			BUG();
+		if (sinfo->gso_type & SKB_GSO_TCP_ECN)
+			vnet_hdr->gso_type |= VIRTIO_NET_HDR_GSO_ECN;
+	} else
+		vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		vnet_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+		vnet_hdr->csum_start = skb->csum_start -
+					skb_headroom(skb);
+		vnet_hdr->csum_offset = skb->csum_offset;
+	} /* else everything is zero */
+
+	return 0;
+}
+
+
+/* Get packet from user space buffer */
+static ssize_t macvtap_get_user(struct macvtap_queue *q,
+				const struct iovec *iv, size_t count,
+				int noblock)
+{
+	struct sk_buff *skb;
+	struct macvlan_dev *vlan;
+	size_t len = count;
+	int err;
+	struct virtio_net_hdr vnet_hdr = { 0 };
+	int vnet_hdr_len = 0;
+
+	if (q->flags & IFF_VNET_HDR) {
+		vnet_hdr_len = sizeof(vnet_hdr);
+
+		err = -EINVAL;
+		if ((len -= vnet_hdr_len) < 0)
+			goto err;
+
+		err = memcpy_fromiovecend((void *)&vnet_hdr, iv, 0,
+					   vnet_hdr_len);
+		if (err < 0)
+			goto err;
+		if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
+		     vnet_hdr.csum_start + vnet_hdr.csum_offset + 2 >
+							vnet_hdr.hdr_len)
+			vnet_hdr.hdr_len = vnet_hdr.csum_start +
+						vnet_hdr.csum_offset + 2;
+		err = -EINVAL;
+		if (vnet_hdr.hdr_len > len)
+			goto err;
+	}
+
+	err = -EINVAL;
+	if (unlikely(len < ETH_HLEN))
+		goto err;
+
+	skb = macvtap_alloc_skb(&q->sk, NET_IP_ALIGN, len, vnet_hdr.hdr_len,
+				noblock, &err);
+	if (!skb)
+		goto err;
+
+	err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len, len);
+	if (err)
+		goto err_kfree;
+
+	skb_set_network_header(skb, ETH_HLEN);
+	skb_reset_mac_header(skb);
+	skb->protocol = eth_hdr(skb)->h_proto;
+
+	if (vnet_hdr_len) {
+		err = macvtap_skb_from_vnet_hdr(skb, &vnet_hdr);
+		if (err)
+			goto err_kfree;
+	}
+
+	rcu_read_lock_bh();
+	vlan = rcu_dereference(q->vlan);
+	if (vlan)
+		macvlan_start_xmit(skb, vlan->dev);
+	else
+		kfree_skb(skb);
+	rcu_read_unlock_bh();
+
+	return count;
+
+err_kfree:
+	kfree_skb(skb);
+
+err:
+	rcu_read_lock_bh();
+	vlan = rcu_dereference(q->vlan);
+	if (vlan)
+		netdev_get_tx_queue(vlan->dev, 0)->tx_dropped++;
+	rcu_read_unlock_bh();
+
+	return err;
+}
+
+static ssize_t macvtap_aio_write(struct kiocb *iocb, const struct iovec *iv,
+				 unsigned long count, loff_t pos)
+{
+	struct file *file = iocb->ki_filp;
+	ssize_t result = -ENOLINK;
+	struct macvtap_queue *q = file->private_data;
+
+	result = macvtap_get_user(q, iv, iov_length(iv, count),
+			      file->f_flags & O_NONBLOCK);
+	return result;
+}
+
+/* Put packet to the user space buffer */
+static ssize_t macvtap_put_user(struct macvtap_queue *q,
+				const struct sk_buff *skb,
+				const struct iovec *iv, int len)
+{
+	struct macvlan_dev *vlan;
+	int ret;
+	int vnet_hdr_len = 0;
+
+	if (q->flags & IFF_VNET_HDR) {
+		struct virtio_net_hdr vnet_hdr;
+		vnet_hdr_len = sizeof (vnet_hdr);
+		if ((len -= vnet_hdr_len) < 0)
+			return -EINVAL;
+
+		ret = macvtap_skb_to_vnet_hdr(skb, &vnet_hdr);
+		if (ret)
+			return ret;
+
+		if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, vnet_hdr_len))
+			return -EFAULT;
+	}
+
+	len = min_t(int, skb->len, len);
+
+	ret = skb_copy_datagram_const_iovec(skb, 0, iv, vnet_hdr_len, len);
+
+	rcu_read_lock_bh();
+	vlan = rcu_dereference(q->vlan);
+	if (vlan)
+		macvlan_count_rx(vlan, len, ret == 0, 0);
+	rcu_read_unlock_bh();
+
+	return ret ? ret : (len + vnet_hdr_len);
+}
+
+static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb,
+			       const struct iovec *iv, unsigned long len,
+			       int noblock)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	struct sk_buff *skb;
+	ssize_t ret = 0;
+
+	add_wait_queue(q->sk.sk_sleep, &wait);
+	while (len) {
+		current->state = TASK_INTERRUPTIBLE;
+
+		/* Read frames from the queue */
+		skb = skb_dequeue(&q->sk.sk_receive_queue);
+		if (!skb) {
+			if (noblock) {
+				ret = -EAGAIN;
+				break;
+			}
+			if (signal_pending(current)) {
+				ret = -ERESTARTSYS;
+				break;
+			}
+			/* Nothing to read, let's sleep */
+			schedule();
+			continue;
+		}
+		ret = macvtap_put_user(q, skb, iv, len);
+		kfree_skb(skb);
+		break;
+	}
+
+	current->state = TASK_RUNNING;
+	remove_wait_queue(q->sk.sk_sleep, &wait);
+	return ret;
+}
+
+static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv,
+				unsigned long count, loff_t pos)
+{
+	struct file *file = iocb->ki_filp;
+	struct macvtap_queue *q = file->private_data;
+	ssize_t len, ret = 0;
+
+	len = iov_length(iv, count);
+	if (len < 0) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = macvtap_do_read(q, iocb, iv, len, file->f_flags & O_NONBLOCK);
+	ret = min_t(ssize_t, ret, len); /* XXX copied from tun.c. Why? */
+out:
+	return ret;
+}
+
+/*
+ * provide compatibility with generic tun/tap interface
+ */
+static long macvtap_ioctl(struct file *file, unsigned int cmd,
+			  unsigned long arg)
+{
+	struct macvtap_queue *q = file->private_data;
+	struct macvlan_dev *vlan;
+	void __user *argp = (void __user *)arg;
+	struct ifreq __user *ifr = argp;
+	unsigned int __user *up = argp;
+	unsigned int u;
+	int ret;
+
+	switch (cmd) {
+	case TUNSETIFF:
+		/* ignore the name, just look at flags */
+		if (get_user(u, &ifr->ifr_flags))
+			return -EFAULT;
+
+		ret = 0;
+		if ((u & ~IFF_VNET_HDR) != (IFF_NO_PI | IFF_TAP))
+			ret = -EINVAL;
+		else
+			q->flags = u;
+
+		return ret;
+
+	case TUNGETIFF:
+		rcu_read_lock_bh();
+		vlan = rcu_dereference(q->vlan);
+		if (vlan)
+			dev_hold(vlan->dev);
+		rcu_read_unlock_bh();
+
+		if (!vlan)
+			return -ENOLINK;
+
+		ret = 0;
+		if (copy_to_user(&ifr->ifr_name, q->vlan->dev->name, IFNAMSIZ) ||
+		    put_user(q->flags, &ifr->ifr_flags))
+			ret = -EFAULT;
+		dev_put(vlan->dev);
+		return ret;
+
+	case TUNGETFEATURES:
+		if (put_user(IFF_TAP | IFF_NO_PI | IFF_VNET_HDR, up))
+			return -EFAULT;
+		return 0;
+
+	case TUNSETSNDBUF:
+		if (get_user(u, up))
+			return -EFAULT;
+
+		q->sk.sk_sndbuf = u;
+		return 0;
+
+	case TUNSETOFFLOAD:
+		/* let the user check for future flags */
+		if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
+			    TUN_F_TSO_ECN | TUN_F_UFO))
+			return -EINVAL;
+
+		/* TODO: only accept frames with the features that
+			 got enabled for forwarded frames */
+		if (!(q->flags & IFF_VNET_HDR))
+			return  -EINVAL;
+		return 0;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+#ifdef CONFIG_COMPAT
+static long macvtap_compat_ioctl(struct file *file, unsigned int cmd,
+				 unsigned long arg)
+{
+	return macvtap_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
+}
+#endif
+
+static const struct file_operations macvtap_fops = {
+	.owner		= THIS_MODULE,
+	.open		= macvtap_open,
+	.release	= macvtap_release,
+	.aio_read	= macvtap_aio_read,
+	.aio_write	= macvtap_aio_write,
+	.poll		= macvtap_poll,
+	.llseek		= no_llseek,
+	.unlocked_ioctl	= macvtap_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= macvtap_compat_ioctl,
+#endif
+};
+
+static int macvtap_sendmsg(struct kiocb *iocb, struct socket *sock,
+			   struct msghdr *m, size_t total_len)
+{
+	struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock);
+	return macvtap_get_user(q, m->msg_iov, total_len,
+			    m->msg_flags & MSG_DONTWAIT);
+}
+
+static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock,
+			   struct msghdr *m, size_t total_len,
+			   int flags)
+{
+	struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock);
+	int ret;
+	if (flags & ~(MSG_DONTWAIT|MSG_TRUNC))
+		return -EINVAL;
+	ret = macvtap_do_read(q, iocb, m->msg_iov, total_len,
+			  flags & MSG_DONTWAIT);
+	if (ret > total_len) {
+		m->msg_flags |= MSG_TRUNC;
+		ret = flags & MSG_TRUNC ? ret : total_len;
+	}
+	return ret;
+}
+
+/* Ops structure to mimic raw sockets with tun */
+static const struct proto_ops macvtap_socket_ops = {
+	.sendmsg = macvtap_sendmsg,
+	.recvmsg = macvtap_recvmsg,
+};
+
+/* Get an underlying socket object from tun file.  Returns error unless file is
+ * attached to a device.  The returned object works like a packet socket, it
+ * can be used for sock_sendmsg/sock_recvmsg.  The caller is responsible for
+ * holding a reference to the file for as long as the socket is in use. */
+struct socket *macvtap_get_socket(struct file *file)
+{
+	struct macvtap_queue *q;
+	if (file->f_op != &macvtap_fops)
+		return ERR_PTR(-EINVAL);
+	q = file->private_data;
+	if (!q)
+		return ERR_PTR(-EBADFD);
+	return &q->sock;
+}
+EXPORT_SYMBOL_GPL(macvtap_get_socket);
+
+static int macvtap_init(void)
+{
+	int err;
+
+	err = alloc_chrdev_region(&macvtap_major, 0,
+				MACVTAP_NUM_DEVS, "macvtap");
+	if (err)
+		goto out1;
+
+	cdev_init(&macvtap_cdev, &macvtap_fops);
+	err = cdev_add(&macvtap_cdev, macvtap_major, MACVTAP_NUM_DEVS);
+	if (err)
+		goto out2;
+
+	macvtap_class = class_create(THIS_MODULE, "macvtap");
+	if (IS_ERR(macvtap_class)) {
+		err = PTR_ERR(macvtap_class);
+		goto out3;
+	}
+
+	err = macvlan_link_register(&macvtap_link_ops);
+	if (err)
+		goto out4;
+
+	return 0;
+
+out4:
+	class_unregister(macvtap_class);
+out3:
+	cdev_del(&macvtap_cdev);
+out2:
+	unregister_chrdev_region(macvtap_major, MACVTAP_NUM_DEVS);
+out1:
+	return err;
+}
+module_init(macvtap_init);
+
+static void macvtap_exit(void)
+{
+	rtnl_link_unregister(&macvtap_link_ops);
+	class_unregister(macvtap_class);
+	cdev_del(&macvtap_cdev);
+	unregister_chrdev_region(macvtap_major, MACVTAP_NUM_DEVS);
+}
+module_exit(macvtap_exit);
+
+MODULE_ALIAS_RTNL_LINK("macvtap");
+MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/Makefile linux-libre-2.6.34-gnu1/drivers/net/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -14,10 +14,12 @@ obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newema
 obj-$(CONFIG_IGB) += igb/
 obj-$(CONFIG_IGBVF) += igbvf/
 obj-$(CONFIG_IXGBE) += ixgbe/
+obj-$(CONFIG_IXGBEVF) += ixgbevf/
 obj-$(CONFIG_IXGB) += ixgb/
 obj-$(CONFIG_IP1000) += ipg.o
 obj-$(CONFIG_CHELSIO_T1) += chelsio/
 obj-$(CONFIG_CHELSIO_T3) += cxgb3/
+obj-$(CONFIG_CHELSIO_T4) += cxgb4/
 obj-$(CONFIG_EHEA) += ehea/
 obj-$(CONFIG_CAN) += can/
 obj-$(CONFIG_BONDING) += bonding/
@@ -95,6 +97,7 @@ obj-$(CONFIG_SKFP) += skfp/
 obj-$(CONFIG_KS8842)	+= ks8842.o
 obj-$(CONFIG_KS8851)	+= ks8851.o
 obj-$(CONFIG_KS8851_MLL)	+= ks8851_mll.o
+obj-$(CONFIG_KSZ884X_PCI)	+= ksz884x.o
 obj-$(CONFIG_VIA_RHINE) += via-rhine.o
 obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
 obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
@@ -148,6 +151,7 @@ ll_temac-objs := ll_temac_main.o ll_tema
 obj-$(CONFIG_XILINX_LL_TEMAC) += ll_temac.o
 obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
 obj-$(CONFIG_QLA3XXX) += qla3xxx.o
+obj-$(CONFIG_QLCNIC) += qlcnic/
 obj-$(CONFIG_QLGE) += qlge/
 
 obj-$(CONFIG_PPP) += ppp_generic.o
@@ -167,6 +171,7 @@ obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen
 obj-$(CONFIG_DUMMY) += dummy.o
 obj-$(CONFIG_IFB) += ifb.o
 obj-$(CONFIG_MACVLAN) += macvlan.o
+obj-$(CONFIG_MACVTAP) += macvtap.o
 obj-$(CONFIG_DE600) += de600.o
 obj-$(CONFIG_DE620) += de620.o
 obj-$(CONFIG_LANCE) += lance.o
@@ -246,6 +251,7 @@ pasemi_mac_driver-objs := pasemi_mac.o p
 obj-$(CONFIG_MLX4_CORE) += mlx4/
 obj-$(CONFIG_ENC28J60) += enc28j60.o
 obj-$(CONFIG_ETHOC) += ethoc.o
+obj-$(CONFIG_GRETH) += greth.o
 
 obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o
 
@@ -267,6 +273,7 @@ obj-$(CONFIG_USB_RTL8150)       += usb/
 obj-$(CONFIG_USB_HSO)		+= usb/
 obj-$(CONFIG_USB_USBNET)        += usb/
 obj-$(CONFIG_USB_ZD1201)        += usb/
+obj-$(CONFIG_USB_IPHETH)        += usb/
 
 obj-y += wireless/
 obj-$(CONFIG_NET_TULIP) += tulip/
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/meth.c linux-libre-2.6.34-gnu1/drivers/net/meth.c
--- linux-libre-2.6.33-gnu1/drivers/net/meth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/meth.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,14 +51,11 @@
 
 static const char *meth_str="SGI O2 Fast Ethernet";
 
-#define HAVE_TX_TIMEOUT
 /* The maximum time waited (in jiffies) before assuming a Tx failed. (400ms) */
 #define TX_TIMEOUT (400*HZ/1000)
 
-#ifdef HAVE_TX_TIMEOUT
 static int timeout = TX_TIMEOUT;
 module_param(timeout, int, 0);
-#endif
 
 /*
  * This structure is private to each device. It is used to pass
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/cmd.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/cmd.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/cmd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/cmd.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/errno.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/cq.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/cq.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/cq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/cq.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
  */
 
 #include <linux/hardirq.h>
+#include <linux/gfp.h>
 
 #include <linux/mlx4/cmd.h>
 #include <linux/mlx4/cq.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/en_main.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/en_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/en_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/en_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 
 #include <linux/mlx4/driver.h>
 #include <linux/mlx4/device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/en_netdev.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/en_netdev.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/en_netdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/en_netdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/tcp.h>
 #include <linux/if_vlan.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <linux/mlx4/driver.h>
 #include <linux/mlx4/device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/en_resources.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/en_resources.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/en_resources.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/en_resources.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/mlx4/qp.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/en_rx.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/en_rx.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/en_rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/en_rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
  */
 
 #include <linux/mlx4/cq.h>
+#include <linux/slab.h>
 #include <linux/mlx4/qp.h>
 #include <linux/skbuff.h>
 #include <linux/if_ether.h>
@@ -508,11 +509,11 @@ static struct sk_buff *mlx4_en_rx_skb(st
 		/* We are copying all relevant data to the skb - temporarily
 		 * synch buffers for the copy */
 		dma = be64_to_cpu(rx_desc->data[0].addr);
-		dma_sync_single_range_for_cpu(&mdev->pdev->dev, dma, 0,
-					      length, DMA_FROM_DEVICE);
+		dma_sync_single_for_cpu(&mdev->pdev->dev, dma, length,
+					DMA_FROM_DEVICE);
 		skb_copy_to_linear_data(skb, va, length);
-		dma_sync_single_range_for_device(&mdev->pdev->dev, dma, 0,
-						 length, DMA_FROM_DEVICE);
+		dma_sync_single_for_device(&mdev->pdev->dev, dma, length,
+					   DMA_FROM_DEVICE);
 		skb->tail += length;
 	} else {
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/en_tx.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/en_tx.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/en_tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/en_tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 
 #include <asm/page.h>
 #include <linux/mlx4/cq.h>
+#include <linux/slab.h>
 #include <linux/mlx4/qp.h>
 #include <linux/skbuff.h>
 #include <linux/if_vlan.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/eq.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/eq.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/eq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/eq.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
  */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/icm.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/icm.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/icm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/icm.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/errno.h>
 #include <linux/mm.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 #include <linux/mlx4/cmd.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/intf.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/intf.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/intf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/intf.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,8 @@
  * SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "mlx4.h"
 
 struct mlx4_device_context {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/main.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/main.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/main.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/errno.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <linux/mlx4/device.h>
 #include <linux/mlx4/doorbell.h>
@@ -1023,6 +1024,7 @@ static int mlx4_init_port_info(struct ml
 	info->port_attr.attr.mode = S_IRUGO | S_IWUSR;
 	info->port_attr.show      = show_port_type;
 	info->port_attr.store     = set_port_type;
+	sysfs_attr_init(&info->port_attr.attr);
 
 	err = device_create_file(&dev->pdev->dev, &info->port_attr);
 	if (err) {
@@ -1271,7 +1273,7 @@ int mlx4_restart_one(struct pci_dev *pde
 	return __mlx4_init_one(pdev, NULL);
 }
 
-static struct pci_device_id mlx4_pci_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(mlx4_pci_table) = {
 	{ PCI_VDEVICE(MELLANOX, 0x6340) }, /* MT25408 "Hermon" SDR */
 	{ PCI_VDEVICE(MELLANOX, 0x634a) }, /* MT25408 "Hermon" DDR */
 	{ PCI_VDEVICE(MELLANOX, 0x6354) }, /* MT25408 "Hermon" QDR */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/mcg.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/mcg.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/mcg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/mcg.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,6 @@
  */
 
 #include <linux/string.h>
-#include <linux/slab.h>
 
 #include <linux/mlx4/cmd.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/mr.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/mr.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/mr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/mr.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/slab.h>
 
 #include <linux/mlx4/cmd.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/profile.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/profile.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/profile.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/profile.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,8 @@
  * SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "mlx4.h"
 #include "fw.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/qp.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/qp.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/qp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/qp.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
  * SOFTWARE.
  */
 
+#include <linux/gfp.h>
 #include <linux/mlx4/cmd.h>
 #include <linux/mlx4/qp.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mlx4/srq.c linux-libre-2.6.34-gnu1/drivers/net/mlx4/srq.c
--- linux-libre-2.6.33-gnu1/drivers/net/mlx4/srq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mlx4/srq.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
  */
 
 #include <linux/mlx4/cmd.h>
+#include <linux/gfp.h>
 
 #include "mlx4.h"
 #include "icm.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mv643xx_eth.c linux-libre-2.6.34-gnu1/drivers/net/mv643xx_eth.c
--- linux-libre-2.6.33-gnu1/drivers/net/mv643xx_eth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mv643xx_eth.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,8 +54,8 @@
 #include <linux/io.h>
 #include <linux/types.h>
 #include <linux/inet_lro.h>
+#include <linux/slab.h>
 #include <asm/system.h>
-#include <linux/list.h>
 
 static char mv643xx_eth_driver_name[] = "mv643xx_eth";
 static char mv643xx_eth_driver_version[] = "1.4";
@@ -1697,7 +1697,7 @@ static u32 uc_addr_filter_mask(struct ne
 		return 0;
 
 	nibbles = 1 << (dev->dev_addr[5] & 0x0f);
-	list_for_each_entry(ha, &dev->uc.list, list) {
+	netdev_for_each_uc_addr(ha, dev) {
 		if (memcmp(dev->dev_addr, ha->addr, 5))
 			return 0;
 		if ((dev->dev_addr[5] ^ ha->addr[5]) & 0xf0)
@@ -1795,7 +1795,7 @@ oom:
 	memset(mc_spec, 0, 0x100);
 	memset(mc_other, 0, 0x100);
 
-	for (addr = dev->mc_list; addr != NULL; addr = addr->next) {
+	netdev_for_each_mc_addr(addr, dev) {
 		u8 *a = addr->da_addr;
 		u32 *table;
 		int entry;
@@ -2847,6 +2847,7 @@ static const struct net_device_ops mv643
 	.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_validate_addr	= eth_validate_addr,
 	.ndo_do_ioctl		= mv643xx_eth_ioctl,
 	.ndo_change_mtu		= mv643xx_eth_change_mtu,
 	.ndo_tx_timeout		= mv643xx_eth_tx_timeout,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/mvme147.c linux-libre-2.6.34-gnu1/drivers/net/mvme147.c
--- linux-libre-2.6.33-gnu1/drivers/net/mvme147.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/mvme147.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,11 +10,11 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 /* Used for the temporal inet entries and routing */
 #include <linux/socket.h>
 #include <linux/route.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/myri10ge/myri10ge.c linux-libre-2.6.34-gnu1/drivers/net/myri10ge/myri10ge.c
--- linux-libre-2.6.33-gnu1/drivers/net/myri10ge/myri10ge.c	2013-05-03 12:08:15.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/myri10ge/myri10ge.c	2013-05-03 09:47:41.000000000 -0400
@@ -38,6 +38,8 @@
  *   Myricom, Inc., 325N Santa Anita Avenue, Arcadia, CA 91006
  *************************************************************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/tcp.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
@@ -62,6 +64,7 @@
 #include <linux/moduleparam.h>
 #include <linux/io.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 #include <net/checksum.h>
 #include <net/ip.h>
 #include <net/tcp.h>
@@ -75,7 +78,7 @@
 #include "myri10ge_mcp.h"
 #include "myri10ge_mcp_gen_header.h"
 
-#define MYRI10GE_VERSION_STR "1.5.1-1.453"
+#define MYRI10GE_VERSION_STR "1.5.2-1.459"
 
 MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
 MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -816,9 +819,7 @@ static int myri10ge_change_pause(struct
 	status = myri10ge_send_cmd(mgp, ctl, &cmd, 0);
 
 	if (status) {
-		printk(KERN_ERR
-		       "myri10ge: %s: Failed to set flow control mode\n",
-		       mgp->dev->name);
+		netdev_err(mgp->dev, "Failed to set flow control mode\n");
 		return status;
 	}
 	mgp->pause = pause;
@@ -834,8 +835,7 @@ myri10ge_change_promisc(struct myri10ge_
 	ctl = promisc ? MXGEFW_ENABLE_PROMISC : MXGEFW_DISABLE_PROMISC;
 	status = myri10ge_send_cmd(mgp, ctl, &cmd, atomic);
 	if (status)
-		printk(KERN_ERR "myri10ge: %s: Failed to set promisc mode\n",
-		       mgp->dev->name);
+		netdev_err(mgp->dev, "Failed to set promisc mode\n");
 }
 
 static int myri10ge_dma_test(struct myri10ge_priv *mgp, int test_type)
@@ -1198,6 +1198,9 @@ myri10ge_alloc_rx_pages(struct myri10ge_
 {
 	struct page *page;
 	int idx;
+#if MYRI10GE_ALLOC_SIZE > 4096
+	int end_offset;
+#endif
 
 	if (unlikely(rx->watchdog_needed && !watchdog))
 		return;
@@ -1239,9 +1242,9 @@ myri10ge_alloc_rx_pages(struct myri10ge_
 
 #if MYRI10GE_ALLOC_SIZE > 4096
 		/* don't cross a 4KB boundary */
-		if ((rx->page_offset >> 12) !=
-		    ((rx->page_offset + bytes - 1) >> 12))
-			rx->page_offset = (rx->page_offset + 4096) & ~4095;
+		end_offset = rx->page_offset + bytes - 1;
+		if ((unsigned)(rx->page_offset ^ end_offset) > 4095)
+			rx->page_offset = end_offset & ~4095;
 #endif
 		rx->fill_cnt++;
 
@@ -1479,19 +1482,15 @@ static inline void myri10ge_check_statbl
 
 			if (mgp->link_state == MXGEFW_LINK_UP) {
 				if (netif_msg_link(mgp))
-					printk(KERN_INFO
-					       "myri10ge: %s: link up\n",
-					       mgp->dev->name);
+					netdev_info(mgp->dev, "link up\n");
 				netif_carrier_on(mgp->dev);
 				mgp->link_changes++;
 			} else {
 				if (netif_msg_link(mgp))
-					printk(KERN_INFO
-					       "myri10ge: %s: link %s\n",
-					       mgp->dev->name,
-					       (link_up == MXGEFW_LINK_MYRINET ?
-						"mismatch (Myrinet detected)" :
-						"down"));
+					netdev_info(mgp->dev, "link %s\n",
+					    link_up == MXGEFW_LINK_MYRINET ?
+					    "mismatch (Myrinet detected)" :
+					    "down");
 				netif_carrier_off(mgp->dev);
 				mgp->link_changes++;
 			}
@@ -1500,9 +1499,8 @@ static inline void myri10ge_check_statbl
 		    ntohl(stats->rdma_tags_available)) {
 			mgp->rdma_tags_available =
 			    ntohl(stats->rdma_tags_available);
-			printk(KERN_WARNING "myri10ge: %s: RDMA timed out! "
-			       "%d tags left\n", mgp->dev->name,
-			       mgp->rdma_tags_available);
+			netdev_warn(mgp->dev, "RDMA timed out! %d tags left\n",
+				    mgp->rdma_tags_available);
 		}
 		mgp->down_cnt += stats->link_down;
 		if (stats->link_down)
@@ -1573,8 +1571,7 @@ static irqreturn_t myri10ge_intr(int irq
 		if (send_done_count != tx->pkt_done)
 			myri10ge_tx_done(ss, (int)send_done_count);
 		if (unlikely(i > myri10ge_max_irq_loops)) {
-			printk(KERN_WARNING "myri10ge: %s: irq stuck?\n",
-			       mgp->dev->name);
+			netdev_err(mgp->dev, "irq stuck?\n");
 			stats->valid = 0;
 			schedule_work(&mgp->watchdog_work);
 		}
@@ -1611,16 +1608,14 @@ myri10ge_get_settings(struct net_device
 	 */
 	ptr = mgp->product_code_string;
 	if (ptr == NULL) {
-		printk(KERN_ERR "myri10ge: %s: Missing product code\n",
-		       netdev->name);
+		netdev_err(netdev, "Missing product code\n");
 		return 0;
 	}
 	for (i = 0; i < 3; i++, ptr++) {
 		ptr = strchr(ptr, '-');
 		if (ptr == NULL) {
-			printk(KERN_ERR "myri10ge: %s: Invalid product "
-			       "code %s\n", netdev->name,
-			       mgp->product_code_string);
+			netdev_err(netdev, "Invalid product code %s\n",
+				   mgp->product_code_string);
 			return 0;
 		}
 	}
@@ -1692,7 +1687,7 @@ myri10ge_set_pauseparam(struct net_devic
 	if (pause->tx_pause != mgp->pause)
 		return myri10ge_change_pause(mgp, pause->tx_pause);
 	if (pause->rx_pause != mgp->pause)
-		return myri10ge_change_pause(mgp, pause->tx_pause);
+		return myri10ge_change_pause(mgp, pause->rx_pause);
 	if (pause->autoneg != 0)
 		return -EINVAL;
 	return 0;
@@ -2006,17 +2001,15 @@ static int myri10ge_allocate_rings(struc
 				mgp->small_bytes + MXGEFW_PAD, 0);
 
 	if (ss->rx_small.fill_cnt < ss->rx_small.mask + 1) {
-		printk(KERN_ERR
-		       "myri10ge: %s:slice-%d: alloced only %d small bufs\n",
-		       dev->name, slice, ss->rx_small.fill_cnt);
+		netdev_err(dev, "slice-%d: alloced only %d small bufs\n",
+			   slice, ss->rx_small.fill_cnt);
 		goto abort_with_rx_small_ring;
 	}
 
 	myri10ge_alloc_rx_pages(mgp, &ss->rx_big, mgp->big_bytes, 0);
 	if (ss->rx_big.fill_cnt < ss->rx_big.mask + 1) {
-		printk(KERN_ERR
-		       "myri10ge: %s:slice-%d: alloced only %d big bufs\n",
-		       dev->name, slice, ss->rx_big.fill_cnt);
+		netdev_err(dev, "slice-%d: alloced only %d big bufs\n",
+			   slice, ss->rx_big.fill_cnt);
 		goto abort_with_rx_big_ring;
 	}
 
@@ -2355,7 +2348,7 @@ static int myri10ge_open(struct net_devi
 	mgp->running = MYRI10GE_ETH_STARTING;
 	status = myri10ge_reset(mgp);
 	if (status != 0) {
-		printk(KERN_ERR "myri10ge: %s: failed reset\n", dev->name);
+		netdev_err(dev, "failed reset\n");
 		goto abort_with_nothing;
 	}
 
@@ -2367,9 +2360,7 @@ static int myri10ge_open(struct net_devi
 		status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ENABLE_RSS_QUEUES,
 					   &cmd, 0);
 		if (status != 0) {
-			printk(KERN_ERR
-			       "myri10ge: %s: failed to set number of slices\n",
-			       dev->name);
+			netdev_err(dev, "failed to set number of slices\n");
 			goto abort_with_nothing;
 		}
 		/* setup the indirection table */
@@ -2381,9 +2372,7 @@ static int myri10ge_open(struct net_devi
 					    MXGEFW_CMD_GET_RSS_TABLE_OFFSET,
 					    &cmd, 0);
 		if (status != 0) {
-			printk(KERN_ERR
-			       "myri10ge: %s: failed to setup rss tables\n",
-			       dev->name);
+			netdev_err(dev, "failed to setup rss tables\n");
 			goto abort_with_nothing;
 		}
 
@@ -2397,9 +2386,7 @@ static int myri10ge_open(struct net_devi
 		status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_RSS_ENABLE,
 					   &cmd, 0);
 		if (status != 0) {
-			printk(KERN_ERR
-			       "myri10ge: %s: failed to enable slices\n",
-			       dev->name);
+			netdev_err(dev, "failed to enable slices\n");
 			goto abort_with_nothing;
 		}
 	}
@@ -2447,9 +2434,7 @@ static int myri10ge_open(struct net_devi
 
 		status = myri10ge_get_txrx(mgp, slice);
 		if (status != 0) {
-			printk(KERN_ERR
-			       "myri10ge: %s: failed to get ring sizes or locations\n",
-			       dev->name);
+			netdev_err(dev, "failed to get ring sizes or locations\n");
 			goto abort_with_rings;
 		}
 		status = myri10ge_allocate_rings(ss);
@@ -2462,9 +2447,7 @@ static int myri10ge_open(struct net_devi
 		if (slice == 0 || mgp->dev->real_num_tx_queues > 1)
 			status = myri10ge_set_stats(mgp, slice);
 		if (status) {
-			printk(KERN_ERR
-			       "myri10ge: %s: Couldn't set stats DMA\n",
-			       dev->name);
+			netdev_err(dev, "Couldn't set stats DMA\n");
 			goto abort_with_rings;
 		}
 
@@ -2495,8 +2478,7 @@ static int myri10ge_open(struct net_devi
 	status |=
 	    myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_BIG_BUFFER_SIZE, &cmd, 0);
 	if (status) {
-		printk(KERN_ERR "myri10ge: %s: Couldn't set buffer sizes\n",
-		       dev->name);
+		netdev_err(dev, "Couldn't set buffer sizes\n");
 		goto abort_with_rings;
 	}
 
@@ -2508,8 +2490,7 @@ static int myri10ge_open(struct net_devi
 	cmd.data0 = 0;
 	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_TSO_MODE, &cmd, 0);
 	if (status && status != -ENOSYS) {
-		printk(KERN_ERR "myri10ge: %s: Couldn't set TSO mode\n",
-		       dev->name);
+		netdev_err(dev, "Couldn't set TSO mode\n");
 		goto abort_with_rings;
 	}
 
@@ -2518,8 +2499,7 @@ static int myri10ge_open(struct net_devi
 
 	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_UP, &cmd, 0);
 	if (status) {
-		printk(KERN_ERR "myri10ge: %s: Couldn't bring up link\n",
-		       dev->name);
+		netdev_err(dev, "Couldn't bring up link\n");
 		goto abort_with_rings;
 	}
 
@@ -2572,15 +2552,12 @@ static int myri10ge_close(struct net_dev
 		status =
 		    myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_DOWN, &cmd, 0);
 		if (status)
-			printk(KERN_ERR
-			       "myri10ge: %s: Couldn't bring down link\n",
-			       dev->name);
+			netdev_err(dev, "Couldn't bring down link\n");
 
 		wait_event_timeout(mgp->down_wq, old_down_cnt != mgp->down_cnt,
 				   HZ);
 		if (old_down_cnt == mgp->down_cnt)
-			printk(KERN_ERR "myri10ge: %s never got down irq\n",
-			       dev->name);
+			netdev_err(dev, "never got down irq\n");
 	}
 	netif_tx_disable(dev);
 	myri10ge_free_irq(mgp);
@@ -2941,9 +2918,7 @@ abort_linearize:
 		idx = (idx + 1) & tx->mask;
 	} while (idx != last_idx);
 	if (skb_is_gso(skb)) {
-		printk(KERN_ERR
-		       "myri10ge: %s: TSO but wanted to linearize?!?!?\n",
-		       mgp->dev->name);
+		netdev_err(mgp->dev, "TSO but wanted to linearize?!?!?\n");
 		goto drop;
 	}
 
@@ -3040,8 +3015,8 @@ static void myri10ge_set_multicast_list(
 
 	err = myri10ge_send_cmd(mgp, MXGEFW_ENABLE_ALLMULTI, &cmd, 1);
 	if (err != 0) {
-		printk(KERN_ERR "myri10ge: %s: Failed MXGEFW_ENABLE_ALLMULTI,"
-		       " error status: %d\n", dev->name, err);
+		netdev_err(dev, "Failed MXGEFW_ENABLE_ALLMULTI, error status: %d\n",
+			   err);
 		goto abort;
 	}
 
@@ -3055,14 +3030,13 @@ static void myri10ge_set_multicast_list(
 	err = myri10ge_send_cmd(mgp, MXGEFW_LEAVE_ALL_MULTICAST_GROUPS,
 				&cmd, 1);
 	if (err != 0) {
-		printk(KERN_ERR
-		       "myri10ge: %s: Failed MXGEFW_LEAVE_ALL_MULTICAST_GROUPS"
-		       ", error status: %d\n", dev->name, err);
+		netdev_err(dev, "Failed MXGEFW_LEAVE_ALL_MULTICAST_GROUPS, error status: %d\n",
+			   err);
 		goto abort;
 	}
 
 	/* Walk the multicast list, and add each address */
-	for (mc_list = dev->mc_list; mc_list != NULL; mc_list = mc_list->next) {
+	netdev_for_each_mc_addr(mc_list, dev) {
 		memcpy(data, &mc_list->dmi_addr, 6);
 		cmd.data0 = ntohl(data[0]);
 		cmd.data1 = ntohl(data[1]);
@@ -3070,18 +3044,16 @@ static void myri10ge_set_multicast_list(
 					&cmd, 1);
 
 		if (err != 0) {
-			printk(KERN_ERR "myri10ge: %s: Failed "
-			       "MXGEFW_JOIN_MULTICAST_GROUP, error status:"
-			       "%d\t", dev->name, err);
-			printk(KERN_ERR "MAC %pM\n", mc_list->dmi_addr);
+			netdev_err(dev, "Failed MXGEFW_JOIN_MULTICAST_GROUP, error status:%d %pM\n",
+				   err, mc_list->dmi_addr);
 			goto abort;
 		}
 	}
 	/* Enable multicast filtering */
 	err = myri10ge_send_cmd(mgp, MXGEFW_DISABLE_ALLMULTI, &cmd, 1);
 	if (err != 0) {
-		printk(KERN_ERR "myri10ge: %s: Failed MXGEFW_DISABLE_ALLMULTI,"
-		       "error status: %d\n", dev->name, err);
+		netdev_err(dev, "Failed MXGEFW_DISABLE_ALLMULTI, error status: %d\n",
+			   err);
 		goto abort;
 	}
 
@@ -3102,9 +3074,8 @@ static int myri10ge_set_mac_address(stru
 
 	status = myri10ge_update_mac_address(mgp, sa->sa_data);
 	if (status != 0) {
-		printk(KERN_ERR
-		       "myri10ge: %s: changing mac address failed with %d\n",
-		       dev->name, status);
+		netdev_err(dev, "changing mac address failed with %d\n",
+			   status);
 		return status;
 	}
 
@@ -3119,12 +3090,10 @@ static int myri10ge_change_mtu(struct ne
 	int error = 0;
 
 	if ((new_mtu < 68) || (ETH_HLEN + new_mtu > MYRI10GE_MAX_ETHER_MTU)) {
-		printk(KERN_ERR "myri10ge: %s: new mtu (%d) is not valid\n",
-		       dev->name, new_mtu);
+		netdev_err(dev, "new mtu (%d) is not valid\n", new_mtu);
 		return -EINVAL;
 	}
-	printk(KERN_INFO "%s: changing mtu from %d to %d\n",
-	       dev->name, dev->mtu, new_mtu);
+	netdev_info(dev, "changing mtu from %d to %d\n", dev->mtu, new_mtu);
 	if (mgp->running) {
 		/* if we change the mtu on an active device, we must
 		 * reset the device so the firmware sees the change */
@@ -3346,7 +3315,7 @@ static int myri10ge_suspend(struct pci_d
 
 	netif_device_detach(netdev);
 	if (netif_running(netdev)) {
-		printk(KERN_INFO "myri10ge: closing %s\n", netdev->name);
+		netdev_info(netdev, "closing\n");
 		rtnl_lock();
 		myri10ge_close(netdev);
 		rtnl_unlock();
@@ -3373,8 +3342,7 @@ static int myri10ge_resume(struct pci_de
 	msleep(5);		/* give card time to respond */
 	pci_read_config_word(mgp->pdev, PCI_VENDOR_ID, &vendor);
 	if (vendor == 0xffff) {
-		printk(KERN_ERR "myri10ge: %s: device disappeared!\n",
-		       mgp->dev->name);
+		netdev_err(mgp->dev, "device disappeared!\n");
 		return -EIO;
 	}
 
@@ -3453,10 +3421,9 @@ static void myri10ge_watchdog(struct wor
 		 * if the card rebooted due to a parity error
 		 * For now, just report it */
 		reboot = myri10ge_read_reboot(mgp);
-		printk(KERN_ERR
-		       "myri10ge: %s: NIC rebooted (0x%x),%s resetting\n",
-		       mgp->dev->name, reboot,
-		       myri10ge_reset_recover ? " " : " not");
+		netdev_err(mgp->dev, "NIC rebooted (0x%x),%s resetting\n",
+			   reboot,
+			   myri10ge_reset_recover ? "" : " not");
 		if (myri10ge_reset_recover == 0)
 			return;
 		rtnl_lock();
@@ -3484,31 +3451,26 @@ static void myri10ge_watchdog(struct wor
 		if (cmd == 0xffff) {
 			pci_read_config_word(mgp->pdev, PCI_VENDOR_ID, &vendor);
 			if (vendor == 0xffff) {
-				printk(KERN_ERR
-				       "myri10ge: %s: device disappeared!\n",
-				       mgp->dev->name);
+				netdev_err(mgp->dev, "device disappeared!\n");
 				return;
 			}
 		}
 		/* Perhaps it is a software error.  Try to reset */
 
-		printk(KERN_ERR "myri10ge: %s: device timeout, resetting\n",
-		       mgp->dev->name);
+		netdev_err(mgp->dev, "device timeout, resetting\n");
 		for (i = 0; i < mgp->num_slices; i++) {
 			tx = &mgp->ss[i].tx;
-			printk(KERN_INFO
-			       "myri10ge: %s: (%d): %d %d %d %d %d %d\n",
-			       mgp->dev->name, i, tx->queue_active, tx->req,
-			       tx->done, tx->pkt_start, tx->pkt_done,
-			       (int)ntohl(mgp->ss[i].fw_stats->
-					  send_done_count));
+			netdev_err(mgp->dev, "(%d): %d %d %d %d %d %d\n",
+				   i, tx->queue_active, tx->req,
+				   tx->done, tx->pkt_start, tx->pkt_done,
+				   (int)ntohl(mgp->ss[i].fw_stats->
+					      send_done_count));
 			msleep(2000);
-			printk(KERN_INFO
-			       "myri10ge: %s: (%d): %d %d %d %d %d %d\n",
-			       mgp->dev->name, i, tx->queue_active, tx->req,
-			       tx->done, tx->pkt_start, tx->pkt_done,
-			       (int)ntohl(mgp->ss[i].fw_stats->
-					  send_done_count));
+			netdev_info(mgp->dev, "(%d): %d %d %d %d %d %d\n",
+				    i, tx->queue_active, tx->req,
+				    tx->done, tx->pkt_start, tx->pkt_done,
+				    (int)ntohl(mgp->ss[i].fw_stats->
+					       send_done_count));
 		}
 	}
 
@@ -3518,8 +3480,7 @@ static void myri10ge_watchdog(struct wor
 	}
 	status = myri10ge_load_firmware(mgp, 1);
 	if (status != 0)
-		printk(KERN_ERR "myri10ge: %s: failed to load firmware\n",
-		       mgp->dev->name);
+		netdev_err(mgp->dev, "failed to load firmware\n");
 	else
 		myri10ge_open(mgp->dev);
 	rtnl_unlock();
@@ -3570,14 +3531,10 @@ static void myri10ge_watchdog_timer(unsi
 			/* nic seems like it might be stuck.. */
 			if (rx_pause_cnt != mgp->watchdog_pause) {
 				if (net_ratelimit())
-					printk(KERN_WARNING
-					       "myri10ge %s slice %d:"
-					       "TX paused, check link partner\n",
-					       mgp->dev->name, i);
+					netdev_err(mgp->dev, "slice %d: TX paused, check link partner\n",
+						   i);
 			} else {
-				printk(KERN_WARNING
-				       "myri10ge %s slice %d stuck:",
-				       mgp->dev->name, i);
+				netdev_warn(mgp->dev, "slice %d stuck:", i);
 				reset_needed = 1;
 			}
 		}
@@ -3721,7 +3678,6 @@ static void myri10ge_probe_slices(struct
 	if (status != 0) {
 		dev_err(&mgp->pdev->dev, "failed reset\n");
 		goto abort_with_fw;
-		return;
 	}
 
 	mgp->max_intr_slots = cmd.data0 / sizeof(struct mcp_slot);
@@ -4075,7 +4031,7 @@ static void myri10ge_remove(struct pci_d
 #define PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E 	0x0008
 #define PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E_9	0x0009
 
-static struct pci_device_id myri10ge_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(myri10ge_pci_tbl) = {
 	{PCI_DEVICE(PCI_VENDOR_ID_MYRICOM, PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E)},
 	{PCI_DEVICE
 	 (PCI_VENDOR_ID_MYRICOM, PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E_9)},
@@ -4117,13 +4073,11 @@ static struct notifier_block myri10ge_dc
 
 static __init int myri10ge_init_module(void)
 {
-	printk(KERN_INFO "%s: Version %s\n", myri10ge_driver.name,
-	       MYRI10GE_VERSION_STR);
+	pr_info("Version %s\n", MYRI10GE_VERSION_STR);
 
 	if (myri10ge_rss_hash > MXGEFW_RSS_HASH_TYPE_MAX) {
-		printk(KERN_ERR
-		       "%s: Illegal rssh hash type %d, defaulting to source port\n",
-		       myri10ge_driver.name, myri10ge_rss_hash);
+		pr_err("Illegal rssh hash type %d, defaulting to source port\n",
+		       myri10ge_rss_hash);
 		myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
 	}
 #ifdef CONFIG_MYRI10GE_DCA
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/myri_sbus.c linux-libre-2.6.34-gnu1/drivers/net/myri_sbus.c
--- linux-libre-2.6.33-gnu1/drivers/net/myri_sbus.c	2013-05-03 12:08:12.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/myri_sbus.c	2013-05-03 09:47:38.000000000 -0400
@@ -14,7 +14,6 @@ static char version[] =
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -26,6 +25,7 @@ static char version[] =
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/firmware.h>
+#include <linux/gfp.h>
 
 #include <net/dst.h>
 #include <net/arp.h>
@@ -716,10 +716,10 @@ static int myri_header(struct sk_buff *s
 	pad[0] = MYRI_PAD_LEN;
 	pad[1] = 0xab;
 
-	/* Set the protocol type. For a packet of type ETH_P_802_3 we put the length
-	 * in here instead. It is up to the 802.2 layer to carry protocol information.
+	/* Set the protocol type. For a packet of type ETH_P_802_3/2 we put the
+	 * length in here instead.
 	 */
-	if (type != ETH_P_802_3)
+	if (type != ETH_P_802_3 && type != ETH_P_802_2)
 		eth->h_proto = htons(type);
 	else
 		eth->h_proto = htons(len);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/natsemi.c linux-libre-2.6.34-gnu1/drivers/net/natsemi.c
--- linux-libre-2.6.33-gnu1/drivers/net/natsemi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/natsemi.c	2010-05-16 17:17:36.000000000 -0400
@@ -247,7 +247,7 @@ static struct {
 	{ "NatSemi DP8381[56]", 0, 24 },
 };
 
-static struct pci_device_id natsemi_pci_tbl[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(natsemi_pci_tbl) = {
 	{ PCI_VENDOR_ID_NS, 0x0020, 0x12d9,     0x000c,     0, 0, 0 },
 	{ PCI_VENDOR_ID_NS, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
 	{ }	/* terminate list */
@@ -2488,16 +2488,16 @@ static void __set_rx_mode(struct net_dev
 	if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
 		rx_mode = RxFilterEnable | AcceptBroadcast
 			| AcceptAllMulticast | AcceptAllPhys | AcceptMyPhys;
-	} else if ((dev->mc_count > multicast_filter_limit) ||
+	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
 		   (dev->flags & IFF_ALLMULTI)) {
 		rx_mode = RxFilterEnable | AcceptBroadcast
 			| AcceptAllMulticast | AcceptMyPhys;
 	} else {
 		struct dev_mc_list *mclist;
 		int i;
+
 		memset(mc_filter, 0, sizeof(mc_filter));
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-			 i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			int b = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 23) & 0x1ff;
 			mc_filter[b/8] |= (1 << (b & 0x07));
 		}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ne2.c linux-libre-2.6.34-gnu1/drivers/net/ne2.c
--- linux-libre-2.6.33-gnu1/drivers/net/ne2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ne2.c	2010-05-16 17:17:36.000000000 -0400
@@ -66,7 +66,6 @@ static const char *version = "ne2.c:v0.9
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ne2k-pci.c linux-libre-2.6.34-gnu1/drivers/net/ne2k-pci.c
--- linux-libre-2.6.33-gnu1/drivers/net/ne2k-pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ne2k-pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -136,7 +136,7 @@ static struct {
 };
 
 
-static struct pci_device_id ne2k_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(ne2k_pci_tbl) = {
 	{ 0x10ec, 0x8029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RealTek_RTL_8029 },
 	{ 0x1050, 0x0940, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_89C940 },
 	{ 0x11f6, 0x1401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Compex_RL2000 },
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ne.c linux-libre-2.6.34-gnu1/drivers/net/ne.c
--- linux-libre-2.6.33-gnu1/drivers/net/ne.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ne.c	2010-05-16 17:17:36.000000000 -0400
@@ -142,7 +142,7 @@ bad_clone_list[] __initdata = {
     {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
     {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
 #ifdef CONFIG_MACH_TX49XX
-    {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}},  /* Toshiba built-in */
+    {"RBHMA4X00-RTL8019", "RBHMA4X00-RTL8019", {0x00, 0x60, 0x0a}},  /* Toshiba built-in */
 #endif
     {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
     {NULL,}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/netconsole.c linux-libre-2.6.34-gnu1/drivers/net/netconsole.c
--- linux-libre-2.6.33-gnu1/drivers/net/netconsole.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/netconsole.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/console.h>
 #include <linux/moduleparam.h>
 #include <linux/string.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/netxen/Makefile linux-libre-2.6.34-gnu1/drivers/net/netxen/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/netxen/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/netxen/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,7 @@
 # MA  02111-1307, USA.
 # 
 # The full GNU General Public License is included in this distribution
-# in the file called LICENSE.
+# in the file called "COPYING".
 # 
 #
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_ctx.c linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic_ctx.c
--- linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_ctx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic_ctx.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,7 @@
  * MA  02111-1307, USA.
  *
  * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.
+ * in the file called "COPYING".
  *
  */
 
@@ -669,13 +669,15 @@ int netxen_alloc_hw_resources(struct net
 		}
 		sds_ring->desc_head = (struct status_desc *)addr;
 
-		sds_ring->crb_sts_consumer =
-			netxen_get_ioaddr(adapter,
-			recv_crb_registers[port].crb_sts_consumer[ring]);
+		if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+			sds_ring->crb_sts_consumer =
+				netxen_get_ioaddr(adapter,
+				recv_crb_registers[port].crb_sts_consumer[ring]);
 
-		sds_ring->crb_intr_mask =
-			netxen_get_ioaddr(adapter,
-			recv_crb_registers[port].sw_int_mask[ring]);
+			sds_ring->crb_intr_mask =
+				netxen_get_ioaddr(adapter,
+				recv_crb_registers[port].sw_int_mask[ring]);
+		}
 	}
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_ethtool.c linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic_ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic_ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,7 @@
  * MA  02111-1307, USA.
  *
  * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.
+ * in the file called "COPYING".
  *
  */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic.h linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic.h
--- linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic.h	2013-05-03 12:08:18.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic.h	2013-05-03 09:47:44.000000000 -0400
@@ -19,7 +19,7 @@
  * MA  02111-1307, USA.
  *
  * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.
+ * in the file called "COPYING".
  *
  */
 
@@ -53,8 +53,8 @@
 
 #define _NETXEN_NIC_LINUX_MAJOR 4
 #define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 72
-#define NETXEN_NIC_LINUX_VERSIONID  "4.0.72"
+#define _NETXEN_NIC_LINUX_SUBVERSION 73
+#define NETXEN_NIC_LINUX_VERSIONID  "4.0.73"
 
 #define NETXEN_VERSION_CODE(a, b, c)	(((a) << 24) + ((b) << 16) + (c))
 #define _major(v)	(((v) >> 24) & 0xff)
@@ -420,7 +420,7 @@ struct status_desc {
 } __attribute__ ((aligned(16)));
 
 /* UNIFIED ROMIMAGE *************************/
-#define NX_UNI_FW_MIN_SIZE		0x3eb000
+#define NX_UNI_FW_MIN_SIZE		0xc8000
 #define NX_UNI_DIR_SECT_PRODUCT_TBL	0x0
 #define NX_UNI_DIR_SECT_BOOTLD		0x6
 #define NX_UNI_DIR_SECT_FW		0x7
@@ -1427,8 +1427,8 @@ static inline u32 netxen_tx_avail(struct
 
 }
 
-int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac);
-int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac);
+int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 *mac);
+int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, u64 *mac);
 extern void netxen_change_ringparam(struct netxen_adapter *adapter);
 extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
 				int *valp);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_hdr.h linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic_hdr.h
--- linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_hdr.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic_hdr.h	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,7 @@
  * MA  02111-1307, USA.
  *
  * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.
+ * in the file called "COPYING".
  *
  */
 
@@ -969,7 +969,8 @@ enum {
 #define NX_DEV_READY		3
 #define NX_DEV_NEED_RESET	4
 #define NX_DEV_NEED_QUISCENT	5
-#define NX_DEV_FAILED		6
+#define NX_DEV_NEED_AER 	6
+#define NX_DEV_FAILED		7
 
 #define NX_RCODE_DRIVER_INFO		0x20000000
 #define NX_RCODE_DRIVER_CAN_RELOAD	0x40000000
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_hw.c linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic_hw.c
--- linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_hw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic_hw.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,10 +19,11 @@
  * MA  02111-1307, USA.
  *
  * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.
+ * in the file called "COPYING".
  *
  */
 
+#include <linux/slab.h>
 #include "netxen_nic.h"
 #include "netxen_nic_hw.h"
 
@@ -539,7 +540,7 @@ void netxen_p2_nic_set_multi(struct net_
 	struct netxen_adapter *adapter = netdev_priv(netdev);
 	struct dev_mc_list *mc_ptr;
 	u8 null_addr[6];
-	int index = 0;
+	int i;
 
 	memset(null_addr, 0, 6);
 
@@ -554,7 +555,7 @@ void netxen_p2_nic_set_multi(struct net_
 		return;
 	}
 
-	if (netdev->mc_count == 0) {
+	if (netdev_mc_empty(netdev)) {
 		adapter->set_promisc(adapter,
 				NETXEN_NIU_NON_PROMISC_MODE);
 		netxen_nic_disable_mcast_filter(adapter);
@@ -563,23 +564,20 @@ void netxen_p2_nic_set_multi(struct net_
 
 	adapter->set_promisc(adapter, NETXEN_NIU_ALLMULTI_MODE);
 	if (netdev->flags & IFF_ALLMULTI ||
-			netdev->mc_count > adapter->max_mc_count) {
+			netdev_mc_count(netdev) > adapter->max_mc_count) {
 		netxen_nic_disable_mcast_filter(adapter);
 		return;
 	}
 
 	netxen_nic_enable_mcast_filter(adapter);
 
-	for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next, index++)
-		netxen_nic_set_mcast_addr(adapter, index, mc_ptr->dmi_addr);
-
-	if (index != netdev->mc_count)
-		printk(KERN_WARNING "%s: %s multicast address count mismatch\n",
-			netxen_nic_driver_name, netdev->name);
+	i = 0;
+	netdev_for_each_mc_addr(mc_ptr, netdev)
+		netxen_nic_set_mcast_addr(adapter, i++, mc_ptr->dmi_addr);
 
 	/* Clear out remaining addresses */
-	for (; index < adapter->max_mc_count; index++)
-		netxen_nic_set_mcast_addr(adapter, index, null_addr);
+	while (i < adapter->max_mc_count)
+		netxen_nic_set_mcast_addr(adapter, i++, null_addr);
 }
 
 static int
@@ -704,16 +702,14 @@ void netxen_p3_nic_set_multi(struct net_
 	}
 
 	if ((netdev->flags & IFF_ALLMULTI) ||
-			(netdev->mc_count > adapter->max_mc_count)) {
+			(netdev_mc_count(netdev) > adapter->max_mc_count)) {
 		mode = VPORT_MISS_MODE_ACCEPT_MULTI;
 		goto send_fw_cmd;
 	}
 
-	if (netdev->mc_count > 0) {
-		for (mc_ptr = netdev->mc_list; mc_ptr;
-		     mc_ptr = mc_ptr->next) {
+	if (!netdev_mc_empty(netdev)) {
+		netdev_for_each_mc_addr(mc_ptr, netdev)
 			nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, &del_list);
-		}
 	}
 
 send_fw_cmd:
@@ -777,17 +773,20 @@ int netxen_p3_nic_set_mac_addr(struct ne
 int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
 {
 	nx_nic_req_t req;
-	u64 word;
-	int rv;
+	u64 word[6];
+	int rv, i;
 
 	memset(&req, 0, sizeof(nx_nic_req_t));
+	memset(word, 0, sizeof(word));
 
 	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
 
-	word = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16);
-	req.req_hdr = cpu_to_le64(word);
+	word[0] = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word[0]);
 
-	memcpy(&req.words[0], &adapter->coal, sizeof(adapter->coal));
+	memcpy(&word[0], &adapter->coal, sizeof(adapter->coal));
+	for (i = 0; i < 6; i++)
+		req.words[i] = cpu_to_le64(word[i]);
 
 	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
 	if (rv != 0) {
@@ -1033,7 +1032,7 @@ static int netxen_get_flash_block(struct
 	return 0;
 }
 
-int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
+int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 *mac)
 {
 	__le32 *pmac = (__le32 *) mac;
 	u32 offset;
@@ -1058,7 +1057,7 @@ int netxen_get_flash_mac_addr(struct net
 	return 0;
 }
 
-int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
+int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, u64 *mac)
 {
 	uint32_t crbaddr, mac_hi, mac_lo;
 	int pci_func = adapter->ahw.pci_func;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_hw.h linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic_hw.h
--- linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic_hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,7 @@
  * MA  02111-1307, USA.
  *
  * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.
+ * in the file called "COPYING".
  *
  */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_init.c linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic_init.c
--- linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_init.c	2013-05-03 12:08:15.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic_init.c	2013-05-03 09:47:41.000000000 -0400
@@ -19,12 +19,13 @@
  * MA  02111-1307, USA.
  *
  * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.
+ * in the file called "COPYING".
  *
  */
 
 #include <linux/netdevice.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include "netxen_nic.h"
 #include "netxen_nic_hw.h"
 
@@ -761,7 +762,7 @@ nx_get_bios_version(struct netxen_adapte
 	if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) {
 		bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off])
 						+ NX_UNI_BIOS_VERSION_OFF));
-		return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) +
+		return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) +
 							(bios_ver >> 24);
 	} else
 		return cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
@@ -780,6 +781,9 @@ netxen_need_fw_reset(struct netxen_adapt
 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
 		return 1;
 
+	if (adapter->need_fw_reset)
+		return 1;
+
 	/* last attempt had failed */
 	if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED)
 		return 1;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_main.c linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_main.c	2013-05-03 12:08:20.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/netxen/netxen_nic_main.c	2013-05-03 09:47:47.000000000 -0400
@@ -19,10 +19,11 @@
  * MA  02111-1307, USA.
  *
  * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.
+ * in the file called "COPYING".
  *
  */
 
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/interrupt.h>
 #include "netxen_nic_hw.h"
@@ -35,6 +36,7 @@
 #include <linux/ipv6.h>
 #include <linux/inetdevice.h>
 #include <linux/sysfs.h>
+#include <linux/aer.h>
 
 MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver");
 MODULE_LICENSE("GPL");
@@ -81,6 +83,7 @@ static void netxen_remove_sysfs_entries(
 static void netxen_create_diag_entries(struct netxen_adapter *adapter);
 static void netxen_remove_diag_entries(struct netxen_adapter *adapter);
 
+static int nx_dev_request_aer(struct netxen_adapter *adapter);
 static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter);
 static int netxen_can_start_firmware(struct netxen_adapter *adapter);
 
@@ -95,7 +98,7 @@ static void netxen_config_indev_addr(str
 	{PCI_DEVICE(PCI_VENDOR_ID_NETXEN, (device)), \
 	.class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0}
 
-static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(netxen_pci_tbl) = {
 	ENTRY(PCI_DEVICE_ID_NX2031_10GXSR),
 	ENTRY(PCI_DEVICE_ID_NX2031_10GCX4),
 	ENTRY(PCI_DEVICE_ID_NX2031_4GCU),
@@ -427,7 +430,7 @@ netxen_read_mac_addr(struct netxen_adapt
 {
 	int i;
 	unsigned char *p;
-	__le64 mac_addr;
+	u64 mac_addr;
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
 
@@ -599,16 +602,14 @@ netxen_cleanup_pci_map(struct netxen_ada
 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;
 
 	resource_size_t mem_base, db_base;
-	unsigned long mem_len, db_len = 0, pci_len0 = 0;
+	unsigned long mem_len, db_len = 0;
 
 	struct pci_dev *pdev = adapter->pdev;
 	int pci_func = adapter->ahw.pci_func;
+	struct netxen_hardware_context *ahw = &adapter->ahw;
 
 	int err = 0;
 
@@ -625,24 +626,40 @@ netxen_setup_pci_map(struct netxen_adapt
 
 	/* 128 Meg of memory */
 	if (mem_len == NETXEN_PCI_128MB_SIZE) {
-		mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE);
-		mem_ptr1 = ioremap(mem_base + SECOND_PAGE_GROUP_START,
+
+		ahw->pci_base0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE);
+		ahw->pci_base1 = ioremap(mem_base + SECOND_PAGE_GROUP_START,
 				SECOND_PAGE_GROUP_SIZE);
-		mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
+		ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
 				THIRD_PAGE_GROUP_SIZE);
-		pci_len0 = FIRST_PAGE_GROUP_SIZE;
+		if (ahw->pci_base0 == NULL || ahw->pci_base1 == NULL ||
+						ahw->pci_base2 == NULL) {
+			dev_err(&pdev->dev, "failed to map PCI bar 0\n");
+			err = -EIO;
+			goto err_out;
+		}
+
+		ahw->pci_len0 = FIRST_PAGE_GROUP_SIZE;
+
 	} else if (mem_len == NETXEN_PCI_32MB_SIZE) {
-		mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE);
-		mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
+
+		ahw->pci_base1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE);
+		ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
 			SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
+		if (ahw->pci_base1 == NULL || ahw->pci_base2 == NULL) {
+			dev_err(&pdev->dev, "failed to map PCI bar 0\n");
+			err = -EIO;
+			goto err_out;
+		}
+
 	} else if (mem_len == NETXEN_PCI_2MB_SIZE) {
 
-		mem_ptr0 = pci_ioremap_bar(pdev, 0);
-		if (mem_ptr0 == NULL) {
+		ahw->pci_base0 = pci_ioremap_bar(pdev, 0);
+		if (ahw->pci_base0 == NULL) {
 			dev_err(&pdev->dev, "failed to map PCI bar 0\n");
 			return -EIO;
 		}
-		pci_len0 = mem_len;
+		ahw->pci_len0 = mem_len;
 	} else {
 		return -EIO;
 	}
@@ -651,11 +668,6 @@ netxen_setup_pci_map(struct netxen_adapt
 
 	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_P3P(adapter->ahw.revision_id)) {
 		adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter,
 			NETXEN_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func)));
@@ -1241,8 +1253,8 @@ netxen_nic_probe(struct pci_dev *pdev, c
 	int pci_func_id = PCI_FUNC(pdev->devfn);
 	uint8_t revision_id;
 
-	if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) {
-		pr_warning("%s: chip revisions between 0x%x-0x%x"
+	if (pdev->revision >= NX_P3_A0 && pdev->revision <= NX_P3_B1) {
+		pr_warning("%s: chip revisions between 0x%x-0x%x "
 				"will not be enabled.\n",
 				module_name(THIS_MODULE), NX_P3_A0, NX_P3_B1);
 		return -ENODEV;
@@ -1259,6 +1271,9 @@ netxen_nic_probe(struct pci_dev *pdev, c
 	if ((err = pci_request_regions(pdev, netxen_nic_driver_name)))
 		goto err_out_disable_pdev;
 
+	if (NX_IS_REVISION_P3(pdev->revision))
+		pci_enable_pcie_error_reporting(pdev);
+
 	pci_set_master(pdev);
 
 	netdev = alloc_etherdev(sizeof(struct netxen_adapter));
@@ -1406,17 +1421,19 @@ static void __devexit netxen_nic_remove(
 
 	netxen_release_firmware(adapter);
 
+	if (NX_IS_REVISION_P3(pdev->revision))
+		pci_disable_pcie_error_reporting(pdev);
+
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
 
 	free_netdev(netdev);
 }
-static int __netxen_nic_shutdown(struct pci_dev *pdev)
+
+static void netxen_nic_detach_func(struct netxen_adapter *adapter)
 {
-	struct netxen_adapter *adapter = pci_get_drvdata(pdev);
 	struct net_device *netdev = adapter->netdev;
-	int retval;
 
 	netif_device_detach(netdev);
 
@@ -1435,53 +1452,22 @@ static int __netxen_nic_shutdown(struct
 	nx_decr_dev_ref_cnt(adapter);
 
 	clear_bit(__NX_RESETTING, &adapter->state);
-
-	retval = pci_save_state(pdev);
-	if (retval)
-		return retval;
-
-	if (netxen_nic_wol_supported(adapter)) {
-		pci_enable_wake(pdev, PCI_D3cold, 1);
-		pci_enable_wake(pdev, PCI_D3hot, 1);
-	}
-
-	pci_disable_device(pdev);
-
-	return 0;
-}
-static void netxen_nic_shutdown(struct pci_dev *pdev)
-{
-	if (__netxen_nic_shutdown(pdev))
-		return;
-}
-#ifdef CONFIG_PM
-static int
-netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-	int retval;
-
-	retval = __netxen_nic_shutdown(pdev);
-	if (retval)
-		return retval;
-
-	pci_set_power_state(pdev, pci_choose_state(pdev, state));
-	return 0;
 }
 
-static int
-netxen_nic_resume(struct pci_dev *pdev)
+static int netxen_nic_attach_func(struct pci_dev *pdev)
 {
 	struct netxen_adapter *adapter = pci_get_drvdata(pdev);
 	struct net_device *netdev = adapter->netdev;
 	int err;
 
-	pci_set_power_state(pdev, PCI_D0);
-	pci_restore_state(pdev);
-
 	err = pci_enable_device(pdev);
 	if (err)
 		return err;
 
+	pci_set_power_state(pdev, PCI_D0);
+	pci_set_master(pdev);
+	pci_restore_state(pdev);
+
 	adapter->ahw.crb_win = -1;
 	adapter->ahw.ocm_win = -1;
 
@@ -1500,11 +1486,10 @@ netxen_nic_resume(struct pci_dev *pdev)
 		if (err)
 			goto err_out_detach;
 
-		netif_device_attach(netdev);
-
 		netxen_config_indev_addr(netdev, NETDEV_UP);
 	}
 
+	netif_device_attach(netdev);
 	netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
 	return 0;
 
@@ -1514,6 +1499,85 @@ err_out:
 	nx_decr_dev_ref_cnt(adapter);
 	return err;
 }
+
+static pci_ers_result_t netxen_io_error_detected(struct pci_dev *pdev,
+						pci_channel_state_t state)
+{
+	struct netxen_adapter *adapter = pci_get_drvdata(pdev);
+
+	if (state == pci_channel_io_perm_failure)
+		return PCI_ERS_RESULT_DISCONNECT;
+
+	if (nx_dev_request_aer(adapter))
+		return PCI_ERS_RESULT_RECOVERED;
+
+	netxen_nic_detach_func(adapter);
+
+	pci_disable_device(pdev);
+
+	return PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t netxen_io_slot_reset(struct pci_dev *pdev)
+{
+	int err = 0;
+
+	err = netxen_nic_attach_func(pdev);
+
+	return err ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
+}
+
+static void netxen_io_resume(struct pci_dev *pdev)
+{
+	pci_cleanup_aer_uncorrect_error_status(pdev);
+}
+
+static void netxen_nic_shutdown(struct pci_dev *pdev)
+{
+	struct netxen_adapter *adapter = pci_get_drvdata(pdev);
+
+	netxen_nic_detach_func(adapter);
+
+	if (pci_save_state(pdev))
+		return;
+
+	if (netxen_nic_wol_supported(adapter)) {
+		pci_enable_wake(pdev, PCI_D3cold, 1);
+		pci_enable_wake(pdev, PCI_D3hot, 1);
+	}
+
+	pci_disable_device(pdev);
+}
+
+#ifdef CONFIG_PM
+static int
+netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct netxen_adapter *adapter = pci_get_drvdata(pdev);
+	int retval;
+
+	netxen_nic_detach_func(adapter);
+
+	retval = pci_save_state(pdev);
+	if (retval)
+		return retval;
+
+	if (netxen_nic_wol_supported(adapter)) {
+		pci_enable_wake(pdev, PCI_D3cold, 1);
+		pci_enable_wake(pdev, PCI_D3hot, 1);
+	}
+
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+	return 0;
+}
+
+static int
+netxen_nic_resume(struct pci_dev *pdev)
+{
+	return netxen_nic_attach_func(pdev);
+}
 #endif
 
 static int netxen_nic_open(struct net_device *netdev)
@@ -2101,20 +2165,49 @@ nx_decr_dev_ref_cnt(struct netxen_adapte
 	return count;
 }
 
-static void
+static int
+nx_dev_request_aer(struct netxen_adapter *adapter)
+{
+	u32 state;
+	int ret = -EINVAL;
+
+	if (netxen_api_lock(adapter))
+		return ret;
+
+	state = NXRD32(adapter, NX_CRB_DEV_STATE);
+
+	if (state == NX_DEV_NEED_AER)
+		ret = 0;
+	else if (state == NX_DEV_READY) {
+		NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_AER);
+		ret = 0;
+	}
+
+	netxen_api_unlock(adapter);
+	return ret;
+}
+
+static int
 nx_dev_request_reset(struct netxen_adapter *adapter)
 {
 	u32 state;
+	int ret = -EINVAL;
 
 	if (netxen_api_lock(adapter))
-		return;
+		return ret;
 
 	state = NXRD32(adapter, NX_CRB_DEV_STATE);
 
-	if (state != NX_DEV_INITALIZING)
+	if (state == NX_DEV_NEED_RESET)
+		ret = 0;
+	else if (state != NX_DEV_INITALIZING && state != NX_DEV_NEED_AER) {
 		NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_RESET);
+		ret = 0;
+	}
 
 	netxen_api_unlock(adapter);
+
+	return ret;
 }
 
 static int
@@ -2268,17 +2361,29 @@ netxen_check_health(struct netxen_adapte
 	u32 state, heartbit;
 	struct net_device *netdev = adapter->netdev;
 
+	state = NXRD32(adapter, NX_CRB_DEV_STATE);
+	if (state == NX_DEV_NEED_AER)
+		return 0;
+
 	if (netxen_nic_check_temp(adapter))
 		goto detach;
 
 	if (adapter->need_fw_reset) {
-		nx_dev_request_reset(adapter);
+		if (nx_dev_request_reset(adapter))
+			return 0;
 		goto detach;
 	}
 
-	state = NXRD32(adapter, NX_CRB_DEV_STATE);
-	if (state == NX_DEV_NEED_RESET)
-		goto detach;
+	/* NX_DEV_NEED_RESET, this state can be marked in two cases
+	 * 1. Tx timeout 2. Fw hang
+	 * Send request to destroy context in case of tx timeout only
+	 * and doesn't required in case of Fw hang
+	 */
+	if (state == NX_DEV_NEED_RESET) {
+		adapter->need_fw_reset = 1;
+		if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+			goto detach;
+	}
 
 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
 		return 0;
@@ -2287,12 +2392,17 @@ netxen_check_health(struct netxen_adapte
 	if (heartbit != adapter->heartbit) {
 		adapter->heartbit = heartbit;
 		adapter->fw_fail_cnt = 0;
+		if (adapter->need_fw_reset)
+			goto detach;
 		return 0;
 	}
 
 	if (++adapter->fw_fail_cnt < FW_FAIL_THRESH)
 		return 0;
 
+	if (nx_dev_request_reset(adapter))
+		return 0;
+
 	clear_bit(__NX_FW_ATTACHED, &adapter->state);
 
 	dev_info(&netdev->dev, "firmware hang detected\n");
@@ -2495,7 +2605,7 @@ netxen_sysfs_read_mem(struct kobject *ko
 	return size;
 }
 
-ssize_t netxen_sysfs_write_mem(struct kobject *kobj,
+static ssize_t netxen_sysfs_write_mem(struct kobject *kobj,
 		struct bin_attribute *attr, char *buf,
 		loff_t offset, size_t size)
 {
@@ -2722,6 +2832,12 @@ netxen_config_indev_addr(struct net_devi
 { }
 #endif
 
+static struct pci_error_handlers netxen_err_handler = {
+	.error_detected = netxen_io_error_detected,
+	.slot_reset = netxen_io_slot_reset,
+	.resume = netxen_io_resume,
+};
+
 static struct pci_driver netxen_driver = {
 	.name = netxen_nic_driver_name,
 	.id_table = netxen_pci_tbl,
@@ -2731,7 +2847,8 @@ static struct pci_driver netxen_driver =
 	.suspend = netxen_nic_suspend,
 	.resume = netxen_nic_resume,
 #endif
-	.shutdown = netxen_nic_shutdown
+	.shutdown = netxen_nic_shutdown,
+	.err_handler = &netxen_err_handler
 };
 
 static int __init netxen_init_module(void)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ni5010.c linux-libre-2.6.34-gnu1/drivers/net/ni5010.c
--- linux-libre-2.6.33-gnu1/drivers/net/ni5010.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ni5010.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,7 +51,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -651,7 +650,8 @@ static void ni5010_set_multicast_list(st
 
 	PRINTK2((KERN_DEBUG "%s: entering set_multicast_list\n", dev->name));
 
-	if (dev->flags&IFF_PROMISC || dev->flags&IFF_ALLMULTI || dev->mc_list) {
+	if (dev->flags & IFF_PROMISC || dev->flags & IFF_ALLMULTI ||
+	    !netdev_mc_empty(dev)) {
 		outb(RMD_PROMISC, EDLC_RMODE); /* Enable promiscuous mode */
 		PRINTK((KERN_DEBUG "%s: Entering promiscuous mode\n", dev->name));
 	} else {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ni52.c linux-libre-2.6.34-gnu1/drivers/net/ni52.c
--- linux-libre-2.6.33-gnu1/drivers/net/ni52.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ni52.c	2010-05-16 17:17:36.000000000 -0400
@@ -109,7 +109,6 @@ static int fifo = 0x8;	/* don't change *
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -596,8 +595,8 @@ static int init586(struct net_device *de
 	struct iasetup_cmd_struct __iomem *ias_cmd;
 	struct tdr_cmd_struct __iomem *tdr_cmd;
 	struct mcsetup_cmd_struct __iomem *mc_cmd;
-	struct dev_mc_list *dmi = dev->mc_list;
-	int num_addrs = dev->mc_count;
+	struct dev_mc_list *dmi;
+	int num_addrs = netdev_mc_count(dev);
 
 	ptr = p->scb + 1;
 
@@ -724,9 +723,9 @@ static int init586(struct net_device *de
 		writew(0xffff, &mc_cmd->cmd_link);
 		writew(num_addrs * 6, &mc_cmd->mc_cnt);
 
-		for (i = 0; i < num_addrs; i++, dmi = dmi->next)
-			memcpy_toio(mc_cmd->mc_list[i],
-							dmi->dmi_addr, 6);
+		i = 0;
+		netdev_for_each_mc_addr(dmi, dev)
+			memcpy_toio(mc_cmd->mc_list[i++], dmi->dmi_addr, 6);
 
 		writew(make16(mc_cmd), &p->scb->cbl_offset);
 		writeb(CUC_START, &p->scb->cmd_cuc);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ni65.c linux-libre-2.6.34-gnu1/drivers/net/ni65.c
--- linux-libre-2.6.33-gnu1/drivers/net/ni65.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ni65.c	2010-05-16 17:17:36.000000000 -0400
@@ -849,7 +849,7 @@ static int ni65_lance_reinit(struct net_
 
 	 if(dev->flags & IFF_PROMISC)
 		 ni65_init_lance(p,dev->dev_addr,0x00,M_PROM);
-	 else if(dev->mc_count || dev->flags & IFF_ALLMULTI)
+	 else if (netdev_mc_count(dev) || dev->flags & IFF_ALLMULTI)
 		 ni65_init_lance(p,dev->dev_addr,0xff,0x0);
 	 else
 		 ni65_init_lance(p,dev->dev_addr,0x00,0x00);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/niu.c linux-libre-2.6.34-gnu1/drivers/net/niu.c
--- linux-libre-2.6.33-gnu1/drivers/net/niu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/niu.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,8 @@
  * Copyright (C) 2007, 2008 David S. Miller (davem@davemloft.net)
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>
@@ -23,6 +25,7 @@
 #include <linux/jiffies.h>
 #include <linux/crc32.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 
 #include <linux/io.h>
 
@@ -33,7 +36,6 @@
 #include "niu.h"
 
 #define DRV_MODULE_NAME		"niu"
-#define PFX DRV_MODULE_NAME	": "
 #define DRV_MODULE_VERSION	"1.0"
 #define DRV_MODULE_RELDATE	"Nov 14, 2008"
 
@@ -58,7 +60,7 @@ static void writeq(u64 val, void __iomem
 }
 #endif
 
-static struct pci_device_id niu_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(niu_pci_tbl) = {
 	{PCI_DEVICE(PCI_VENDOR_ID_SUN, 0xabcd)},
 	{}
 };
@@ -89,21 +91,6 @@ static int debug = -1;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "NIU debug level");
 
-#define niudbg(TYPE, f, a...) \
-do {	if ((np)->msg_enable & NETIF_MSG_##TYPE) \
-		printk(KERN_DEBUG PFX f, ## a); \
-} while (0)
-
-#define niuinfo(TYPE, f, a...) \
-do {	if ((np)->msg_enable & NETIF_MSG_##TYPE) \
-		printk(KERN_INFO PFX f, ## a); \
-} while (0)
-
-#define niuwarn(TYPE, f, a...) \
-do {	if ((np)->msg_enable & NETIF_MSG_##TYPE) \
-		printk(KERN_WARNING PFX f, ## a); \
-} while (0)
-
 #define niu_lock_parent(np, flags) \
 	spin_lock_irqsave(&np->parent->lock, flags)
 #define niu_unlock_parent(np, flags) \
@@ -135,10 +122,9 @@ static int __niu_set_and_wait_clear_mac(
 	nw64_mac(reg, bits);
 	err = __niu_wait_bits_clear_mac(np, reg, bits, limit, delay);
 	if (err)
-		dev_err(np->device, PFX "%s: bits (%llx) of register %s "
-			"would not clear, val[%llx]\n",
-			np->dev->name, (unsigned long long) bits, reg_name,
-			(unsigned long long) nr64_mac(reg));
+		netdev_err(np->dev, "bits (%llx) of register %s would not clear, val[%llx]\n",
+			   (unsigned long long)bits, reg_name,
+			   (unsigned long long)nr64_mac(reg));
 	return err;
 }
 
@@ -175,10 +161,9 @@ static int __niu_set_and_wait_clear_ipp(
 
 	err = __niu_wait_bits_clear_ipp(np, reg, bits, limit, delay);
 	if (err)
-		dev_err(np->device, PFX "%s: bits (%llx) of register %s "
-			"would not clear, val[%llx]\n",
-			np->dev->name, (unsigned long long) bits, reg_name,
-			(unsigned long long) nr64_ipp(reg));
+		netdev_err(np->dev, "bits (%llx) of register %s would not clear, val[%llx]\n",
+			   (unsigned long long)bits, reg_name,
+			   (unsigned long long)nr64_ipp(reg));
 	return err;
 }
 
@@ -216,10 +201,9 @@ static int __niu_set_and_wait_clear(stru
 	nw64(reg, bits);
 	err = __niu_wait_bits_clear(np, reg, bits, limit, delay);
 	if (err)
-		dev_err(np->device, PFX "%s: bits (%llx) of register %s "
-			"would not clear, val[%llx]\n",
-			np->dev->name, (unsigned long long) bits, reg_name,
-			(unsigned long long) nr64(reg));
+		netdev_err(np->dev, "bits (%llx) of register %s would not clear, val[%llx]\n",
+			   (unsigned long long)bits, reg_name,
+			   (unsigned long long)nr64(reg));
 	return err;
 }
 
@@ -475,9 +459,8 @@ static int serdes_init_niu_1g_serdes(str
 	err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR,
 			 ESR2_TI_PLL_CFG_L, pll_cfg);
 	if (err) {
-		dev_err(np->device, PFX "NIU Port %d "
-			"serdes_init_niu_1g_serdes: "
-			"mdio write to ESR2_TI_PLL_CFG_L failed", np->port);
+		netdev_err(np->dev, "NIU Port %d %s() mdio write to ESR2_TI_PLL_CFG_L failed\n",
+			   np->port, __func__);
 		return err;
 	}
 
@@ -486,9 +469,8 @@ static int serdes_init_niu_1g_serdes(str
 	err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR,
 			 ESR2_TI_PLL_STS_L, pll_sts);
 	if (err) {
-		dev_err(np->device, PFX "NIU Port %d "
-			"serdes_init_niu_1g_serdes: "
-			"mdio write to ESR2_TI_PLL_STS_L failed", np->port);
+		netdev_err(np->dev, "NIU Port %d %s() mdio write to ESR2_TI_PLL_STS_L failed\n",
+			   np->port, __func__);
 		return err;
 	}
 
@@ -531,8 +513,8 @@ static int serdes_init_niu_1g_serdes(str
 	}
 
 	if ((sig & mask) != val) {
-		dev_err(np->device, PFX "Port %u signal bits [%08x] are not "
-			"[%08x]\n", np->port, (int) (sig & mask), (int) val);
+		netdev_err(np->dev, "Port %u signal bits [%08x] are not [%08x]\n",
+			   np->port, (int)(sig & mask), (int)val);
 		return -ENODEV;
 	}
 
@@ -569,9 +551,8 @@ static int serdes_init_niu_10g_serdes(st
 	err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR,
 			 ESR2_TI_PLL_CFG_L, pll_cfg & 0xffff);
 	if (err) {
-		dev_err(np->device, PFX "NIU Port %d "
-			"serdes_init_niu_10g_serdes: "
-			"mdio write to ESR2_TI_PLL_CFG_L failed", np->port);
+		netdev_err(np->dev, "NIU Port %d %s() mdio write to ESR2_TI_PLL_CFG_L failed\n",
+			   np->port, __func__);
 		return err;
 	}
 
@@ -580,9 +561,8 @@ static int serdes_init_niu_10g_serdes(st
 	err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR,
 			 ESR2_TI_PLL_STS_L, pll_sts & 0xffff);
 	if (err) {
-		dev_err(np->device, PFX "NIU Port %d "
-			"serdes_init_niu_10g_serdes: "
-			"mdio write to ESR2_TI_PLL_STS_L failed", np->port);
+		netdev_err(np->dev, "NIU Port %d %s() mdio write to ESR2_TI_PLL_STS_L failed\n",
+			   np->port, __func__);
 		return err;
 	}
 
@@ -639,9 +619,8 @@ static int serdes_init_niu_10g_serdes(st
 	}
 
 	if ((sig & mask) != val) {
-		pr_info(PFX "NIU Port %u signal bits [%08x] are not "
-			"[%08x] for 10G...trying 1G\n",
-			np->port, (int) (sig & mask), (int) val);
+		pr_info("NIU Port %u signal bits [%08x] are not [%08x] for 10G...trying 1G\n",
+			np->port, (int)(sig & mask), (int)val);
 
 		/* 10G failed, try initializing at 1G */
 		err = serdes_init_niu_1g_serdes(np);
@@ -649,8 +628,8 @@ static int serdes_init_niu_10g_serdes(st
 			np->flags &= ~NIU_FLAGS_10G;
 			np->mac_xcvr = MAC_XCVR_PCS;
 		}  else {
-			dev_err(np->device, PFX "Port %u 10G/1G SERDES "
-				"Link Failed \n", np->port);
+			netdev_err(np->dev, "Port %u 10G/1G SERDES Link Failed\n",
+				   np->port);
 			return -ENODEV;
 		}
 	}
@@ -764,9 +743,8 @@ static int esr_reset(struct niu *np)
 	if (err)
 		return err;
 	if (reset != 0) {
-		dev_err(np->device, PFX "Port %u ESR_RESET "
-			"did not clear [%08x]\n",
-			np->port, reset);
+		netdev_err(np->dev, "Port %u ESR_RESET did not clear [%08x]\n",
+			   np->port, reset);
 		return -ENODEV;
 	}
 
@@ -890,8 +868,8 @@ static int serdes_init_10g(struct niu *n
 			np->flags &= ~NIU_FLAGS_HOTPLUG_PHY_PRESENT;
 			return 0;
 		}
-		dev_err(np->device, PFX "Port %u signal bits [%08x] are not "
-			"[%08x]\n", np->port, (int) (sig & mask), (int) val);
+		netdev_err(np->dev, "Port %u signal bits [%08x] are not [%08x]\n",
+			   np->port, (int)(sig & mask), (int)val);
 		return -ENODEV;
 	}
 	if (np->flags & NIU_FLAGS_HOTPLUG_PHY)
@@ -1039,8 +1017,8 @@ static int serdes_init_1g_serdes(struct
 	}
 
 	if ((sig & mask) != val) {
-		dev_err(np->device, PFX "Port %u signal bits [%08x] are not "
-			"[%08x]\n", np->port, (int) (sig & mask), (int) val);
+		netdev_err(np->dev, "Port %u signal bits [%08x] are not [%08x]\n",
+			   np->port, (int)(sig & mask), (int)val);
 		return -ENODEV;
 	}
 
@@ -1332,8 +1310,8 @@ static int bcm8704_reset(struct niu *np)
 			break;
 	}
 	if (limit < 0) {
-		dev_err(np->device, PFX "Port %u PHY will not reset "
-			"(bmcr=%04x)\n", np->port, (err & 0xffff));
+		netdev_err(np->dev, "Port %u PHY will not reset (bmcr=%04x)\n",
+			   np->port, (err & 0xffff));
 		return -ENODEV;
 	}
 	return 0;
@@ -1515,21 +1493,18 @@ static int xcvr_diag_bcm870x(struct niu
 			MII_STAT1000);
 	if (err < 0)
 		return err;
-	pr_info(PFX "Port %u PMA_PMD(MII_STAT1000) [%04x]\n",
-		np->port, err);
+	pr_info("Port %u PMA_PMD(MII_STAT1000) [%04x]\n", np->port, err);
 
 	err = mdio_read(np, np->phy_addr, BCM8704_USER_DEV3_ADDR, 0x20);
 	if (err < 0)
 		return err;
-	pr_info(PFX "Port %u USER_DEV3(0x20) [%04x]\n",
-		np->port, err);
+	pr_info("Port %u USER_DEV3(0x20) [%04x]\n", np->port, err);
 
 	err = mdio_read(np, np->phy_addr, BCM8704_PHYXS_DEV_ADDR,
 			MII_NWAYTEST);
 	if (err < 0)
 		return err;
-	pr_info(PFX "Port %u PHYXS(MII_NWAYTEST) [%04x]\n",
-		np->port, err);
+	pr_info("Port %u PHYXS(MII_NWAYTEST) [%04x]\n", np->port, err);
 #endif
 
 	/* XXX dig this out it might not be so useful XXX */
@@ -1555,11 +1530,11 @@ static int xcvr_diag_bcm870x(struct niu
 
 	if (analog_stat0 != 0x03fc) {
 		if ((analog_stat0 == 0x43bc) && (tx_alarm_status != 0)) {
-			pr_info(PFX "Port %u cable not connected "
-				"or bad cable.\n", np->port);
+			pr_info("Port %u cable not connected or bad cable\n",
+				np->port);
 		} else if (analog_stat0 == 0x639c) {
-			pr_info(PFX "Port %u optical module is bad "
-				"or missing.\n", np->port);
+			pr_info("Port %u optical module is bad or missing\n",
+				np->port);
 		}
 	}
 
@@ -1699,8 +1674,8 @@ static int mii_reset(struct niu *np)
 			break;
 	}
 	if (limit < 0) {
-		dev_err(np->device, PFX "Port %u MII would not reset, "
-			"bmcr[%04x]\n", np->port, err);
+		netdev_err(np->dev, "Port %u MII would not reset, bmcr[%04x]\n",
+			   np->port, err);
 		return -ENODEV;
 	}
 
@@ -1895,7 +1870,7 @@ static int mii_init_common(struct niu *n
 		return err;
 	bmsr = err;
 
-	pr_info(PFX "Port %u after MII init bmcr[%04x] bmsr[%04x]\n",
+	pr_info("Port %u after MII init bmcr[%04x] bmsr[%04x]\n",
 		np->port, bmcr, bmsr);
 #endif
 
@@ -1948,16 +1923,12 @@ static int niu_link_status_common(struct
 	unsigned long flags;
 
 	if (!netif_carrier_ok(dev) && link_up) {
-		niuinfo(LINK, "%s: Link is up at %s, %s duplex\n",
-		       dev->name,
-		       (lp->active_speed == SPEED_10000 ?
-			"10Gb/sec" :
-			(lp->active_speed == SPEED_1000 ?
-			 "1Gb/sec" :
-			 (lp->active_speed == SPEED_100 ?
-			  "100Mbit/sec" : "10Mbit/sec"))),
-		       (lp->active_duplex == DUPLEX_FULL ?
-			"full" : "half"));
+		netif_info(np, link, dev, "Link is up at %s, %s duplex\n",
+			   lp->active_speed == SPEED_10000 ? "10Gb/sec" :
+			   lp->active_speed == SPEED_1000 ? "1Gb/sec" :
+			   lp->active_speed == SPEED_100 ? "100Mbit/sec" :
+			   "10Mbit/sec",
+			   lp->active_duplex == DUPLEX_FULL ? "full" : "half");
 
 		spin_lock_irqsave(&np->lock, flags);
 		niu_init_xif(np);
@@ -1966,7 +1937,7 @@ static int niu_link_status_common(struct
 
 		netif_carrier_on(dev);
 	} else if (netif_carrier_ok(dev) && !link_up) {
-		niuwarn(LINK, "%s: Link is down\n", dev->name);
+		netif_warn(np, link, dev, "Link is down\n");
 		spin_lock_irqsave(&np->lock, flags);
 		niu_handle_led(np, 0);
 		spin_unlock_irqrestore(&np->lock, flags);
@@ -2232,8 +2203,8 @@ static int link_status_10g_hotplug(struc
 			} else {
 				np->flags &= ~NIU_FLAGS_HOTPLUG_PHY_PRESENT;
 				*link_up_p = 0;
-				niuwarn(LINK, "%s: Hotplug PHY Removed\n",
-					np->dev->name);
+				netif_warn(np, link, np->dev,
+					   "Hotplug PHY Removed\n");
 			}
 		}
 out:
@@ -2531,8 +2502,8 @@ static int serdes_init_10g_serdes(struct
 			np->flags &= ~NIU_FLAGS_10G;
 			np->mac_xcvr = MAC_XCVR_PCS;
 		}  else {
-			dev_err(np->device, PFX "Port %u 10G/1G SERDES Link Failed \n",
-			 np->port);
+			netdev_err(np->dev, "Port %u 10G/1G SERDES Link Failed\n",
+				   np->port);
 			return -ENODEV;
 		}
 	}
@@ -3234,23 +3205,22 @@ static int fflp_early_init(struct niu *n
 	parent = np->parent;
 	err = 0;
 	if (!(parent->flags & PARENT_FLGS_CLS_HWINIT)) {
-		niudbg(PROBE, "fflp_early_init: Initting hw on port %u\n",
-		       np->port);
 		if (np->parent->plat_type != PLAT_TYPE_NIU) {
 			fflp_reset(np);
 			fflp_set_timings(np);
 			err = fflp_disable_all_partitions(np);
 			if (err) {
-				niudbg(PROBE, "fflp_disable_all_partitions "
-				       "failed, err=%d\n", err);
+				netif_printk(np, probe, KERN_DEBUG, np->dev,
+					     "fflp_disable_all_partitions failed, err=%d\n",
+					     err);
 				goto out;
 			}
 		}
 
 		err = tcam_early_init(np);
 		if (err) {
-			niudbg(PROBE, "tcam_early_init failed, err=%d\n",
-			       err);
+			netif_printk(np, probe, KERN_DEBUG, np->dev,
+				     "tcam_early_init failed, err=%d\n", err);
 			goto out;
 		}
 		fflp_llcsnap_enable(np, 1);
@@ -3260,22 +3230,22 @@ static int fflp_early_init(struct niu *n
 
 		err = tcam_flush_all(np);
 		if (err) {
-			niudbg(PROBE, "tcam_flush_all failed, err=%d\n",
-			       err);
+			netif_printk(np, probe, KERN_DEBUG, np->dev,
+				     "tcam_flush_all failed, err=%d\n", err);
 			goto out;
 		}
 		if (np->parent->plat_type != PLAT_TYPE_NIU) {
 			err = fflp_hash_clear(np);
 			if (err) {
-				niudbg(PROBE, "fflp_hash_clear failed, "
-				       "err=%d\n", err);
+				netif_printk(np, probe, KERN_DEBUG, np->dev,
+					     "fflp_hash_clear failed, err=%d\n",
+					     err);
 				goto out;
 			}
 		}
 
 		vlan_tbl_clear(np);
 
-		niudbg(PROBE, "fflp_early_init: Success\n");
 		parent->flags |= PARENT_FLGS_CLS_HWINIT;
 	}
 out:
@@ -3665,8 +3635,8 @@ static void niu_tx_work(struct niu *np,
 
 	cons = rp->cons;
 
-	niudbg(TX_DONE, "%s: niu_tx_work() pkt_cnt[%u] cons[%d]\n",
-	       np->dev->name, pkt_cnt, cons);
+	netif_printk(np, tx_done, KERN_DEBUG, np->dev,
+		     "%s() pkt_cnt[%u] cons[%d]\n", __func__, pkt_cnt, cons);
 
 	while (pkt_cnt--)
 		cons = release_tx_packet(np, rp, cons);
@@ -3714,11 +3684,12 @@ static inline void niu_sync_rx_discard_s
 		rp->rx_errors += misc & RXMISC_COUNT;
 
 		if (unlikely(misc & RXMISC_OFLOW))
-			dev_err(np->device, "rx-%d: Counter overflow "
-				"RXMISC discard\n", rx_channel);
+			dev_err(np->device, "rx-%d: Counter overflow RXMISC discard\n",
+				rx_channel);
 
-		niudbg(RX_ERR, "%s-rx-%d: MISC drop=%u over=%u\n",
-		       np->dev->name, rx_channel, misc, misc-limit);
+		netif_printk(np, rx_err, KERN_DEBUG, np->dev,
+			     "rx-%d: MISC drop=%u over=%u\n",
+			     rx_channel, misc, misc-limit);
 	}
 
 	/* WRED (Weighted Random Early Discard) by hardware */
@@ -3728,11 +3699,11 @@ static inline void niu_sync_rx_discard_s
 		rp->rx_dropped += wred & RED_DIS_CNT_COUNT;
 
 		if (unlikely(wred & RED_DIS_CNT_OFLOW))
-			dev_err(np->device, "rx-%d: Counter overflow "
-				"WRED discard\n", rx_channel);
+			dev_err(np->device, "rx-%d: Counter overflow WRED discard\n", rx_channel);
 
-		niudbg(RX_ERR, "%s-rx-%d: WRED drop=%u over=%u\n",
-		       np->dev->name, rx_channel, wred, wred-limit);
+		netif_printk(np, rx_err, KERN_DEBUG, np->dev,
+			     "rx-%d: WRED drop=%u over=%u\n",
+			     rx_channel, wred, wred-limit);
 	}
 }
 
@@ -3753,8 +3724,9 @@ static int niu_rx_work(struct napi_struc
 	mbox->rx_dma_ctl_stat = 0;
 	mbox->rcrstat_a = 0;
 
-	niudbg(RX_STATUS, "%s: niu_rx_work(chan[%d]), stat[%llx] qlen=%d\n",
-	       np->dev->name, rp->rx_channel, (unsigned long long) stat, qlen);
+	netif_printk(np, rx_status, KERN_DEBUG, np->dev,
+		     "%s(chan[%d]), stat[%llx] qlen=%d\n",
+		     __func__, rp->rx_channel, (unsigned long long)stat, qlen);
 
 	rcr_done = work_done = 0;
 	qlen = min(qlen, budget);
@@ -3791,8 +3763,8 @@ static int niu_poll_core(struct niu *np,
 	u32 rx_vec = (v0 & 0xffffffff);
 	int i, work_done = 0;
 
-	niudbg(INTR, "%s: niu_poll_core() v0[%016llx]\n",
-	       np->dev->name, (unsigned long long) v0);
+	netif_printk(np, intr, KERN_DEBUG, np->dev,
+		     "%s() v0[%016llx]\n", __func__, (unsigned long long)v0);
 
 	for (i = 0; i < np->num_tx_rings; i++) {
 		struct tx_ring_info *rp = &np->tx_rings[i];
@@ -3837,39 +3809,38 @@ static int niu_poll(struct napi_struct *
 static void niu_log_rxchan_errors(struct niu *np, struct rx_ring_info *rp,
 				  u64 stat)
 {
-	dev_err(np->device, PFX "%s: RX channel %u errors ( ",
-		np->dev->name, rp->rx_channel);
+	netdev_err(np->dev, "RX channel %u errors ( ", rp->rx_channel);
 
 	if (stat & RX_DMA_CTL_STAT_RBR_TMOUT)
-		printk("RBR_TMOUT ");
+		pr_cont("RBR_TMOUT ");
 	if (stat & RX_DMA_CTL_STAT_RSP_CNT_ERR)
-		printk("RSP_CNT ");
+		pr_cont("RSP_CNT ");
 	if (stat & RX_DMA_CTL_STAT_BYTE_EN_BUS)
-		printk("BYTE_EN_BUS ");
+		pr_cont("BYTE_EN_BUS ");
 	if (stat & RX_DMA_CTL_STAT_RSP_DAT_ERR)
-		printk("RSP_DAT ");
+		pr_cont("RSP_DAT ");
 	if (stat & RX_DMA_CTL_STAT_RCR_ACK_ERR)
-		printk("RCR_ACK ");
+		pr_cont("RCR_ACK ");
 	if (stat & RX_DMA_CTL_STAT_RCR_SHA_PAR)
-		printk("RCR_SHA_PAR ");
+		pr_cont("RCR_SHA_PAR ");
 	if (stat & RX_DMA_CTL_STAT_RBR_PRE_PAR)
-		printk("RBR_PRE_PAR ");
+		pr_cont("RBR_PRE_PAR ");
 	if (stat & RX_DMA_CTL_STAT_CONFIG_ERR)
-		printk("CONFIG ");
+		pr_cont("CONFIG ");
 	if (stat & RX_DMA_CTL_STAT_RCRINCON)
-		printk("RCRINCON ");
+		pr_cont("RCRINCON ");
 	if (stat & RX_DMA_CTL_STAT_RCRFULL)
-		printk("RCRFULL ");
+		pr_cont("RCRFULL ");
 	if (stat & RX_DMA_CTL_STAT_RBRFULL)
-		printk("RBRFULL ");
+		pr_cont("RBRFULL ");
 	if (stat & RX_DMA_CTL_STAT_RBRLOGPAGE)
-		printk("RBRLOGPAGE ");
+		pr_cont("RBRLOGPAGE ");
 	if (stat & RX_DMA_CTL_STAT_CFIGLOGPAGE)
-		printk("CFIGLOGPAGE ");
+		pr_cont("CFIGLOGPAGE ");
 	if (stat & RX_DMA_CTL_STAT_DC_FIFO_ERR)
-		printk("DC_FIDO ");
+		pr_cont("DC_FIDO ");
 
-	printk(")\n");
+	pr_cont(")\n");
 }
 
 static int niu_rx_error(struct niu *np, struct rx_ring_info *rp)
@@ -3883,9 +3854,9 @@ static int niu_rx_error(struct niu *np,
 		err = -EINVAL;
 
 	if (err) {
-		dev_err(np->device, PFX "%s: RX channel %u error, stat[%llx]\n",
-			np->dev->name, rp->rx_channel,
-			(unsigned long long) stat);
+		netdev_err(np->dev, "RX channel %u error, stat[%llx]\n",
+			   rp->rx_channel,
+			   (unsigned long long) stat);
 
 		niu_log_rxchan_errors(np, rp, stat);
 	}
@@ -3899,27 +3870,26 @@ static int niu_rx_error(struct niu *np,
 static void niu_log_txchan_errors(struct niu *np, struct tx_ring_info *rp,
 				  u64 cs)
 {
-	dev_err(np->device, PFX "%s: TX channel %u errors ( ",
-		np->dev->name, rp->tx_channel);
+	netdev_err(np->dev, "TX channel %u errors ( ", rp->tx_channel);
 
 	if (cs & TX_CS_MBOX_ERR)
-		printk("MBOX ");
+		pr_cont("MBOX ");
 	if (cs & TX_CS_PKT_SIZE_ERR)
-		printk("PKT_SIZE ");
+		pr_cont("PKT_SIZE ");
 	if (cs & TX_CS_TX_RING_OFLOW)
-		printk("TX_RING_OFLOW ");
+		pr_cont("TX_RING_OFLOW ");
 	if (cs & TX_CS_PREF_BUF_PAR_ERR)
-		printk("PREF_BUF_PAR ");
+		pr_cont("PREF_BUF_PAR ");
 	if (cs & TX_CS_NACK_PREF)
-		printk("NACK_PREF ");
+		pr_cont("NACK_PREF ");
 	if (cs & TX_CS_NACK_PKT_RD)
-		printk("NACK_PKT_RD ");
+		pr_cont("NACK_PKT_RD ");
 	if (cs & TX_CS_CONF_PART_ERR)
-		printk("CONF_PART ");
+		pr_cont("CONF_PART ");
 	if (cs & TX_CS_PKT_PRT_ERR)
-		printk("PKT_PTR ");
+		pr_cont("PKT_PTR ");
 
-	printk(")\n");
+	pr_cont(")\n");
 }
 
 static int niu_tx_error(struct niu *np, struct tx_ring_info *rp)
@@ -3930,12 +3900,11 @@ static int niu_tx_error(struct niu *np,
 	logh = nr64(TX_RNG_ERR_LOGH(rp->tx_channel));
 	logl = nr64(TX_RNG_ERR_LOGL(rp->tx_channel));
 
-	dev_err(np->device, PFX "%s: TX channel %u error, "
-		"cs[%llx] logh[%llx] logl[%llx]\n",
-		np->dev->name, rp->tx_channel,
-		(unsigned long long) cs,
-		(unsigned long long) logh,
-		(unsigned long long) logl);
+	netdev_err(np->dev, "TX channel %u error, cs[%llx] logh[%llx] logl[%llx]\n",
+		   rp->tx_channel,
+		   (unsigned long long)cs,
+		   (unsigned long long)logh,
+		   (unsigned long long)logl);
 
 	niu_log_txchan_errors(np, rp, cs);
 
@@ -3954,9 +3923,8 @@ static int niu_mif_interrupt(struct niu
 			phy_mdint = 1;
 	}
 
-	dev_err(np->device, PFX "%s: MIF interrupt, "
-		"stat[%llx] phy_mdint(%d)\n",
-		np->dev->name, (unsigned long long) mif_status, phy_mdint);
+	netdev_err(np->dev, "MIF interrupt, stat[%llx] phy_mdint(%d)\n",
+		   (unsigned long long)mif_status, phy_mdint);
 
 	return -ENODEV;
 }
@@ -4081,41 +4049,40 @@ static int niu_mac_interrupt(struct niu
 
 static void niu_log_device_error(struct niu *np, u64 stat)
 {
-	dev_err(np->device, PFX "%s: Core device errors ( ",
-		np->dev->name);
+	netdev_err(np->dev, "Core device errors ( ");
 
 	if (stat & SYS_ERR_MASK_META2)
-		printk("META2 ");
+		pr_cont("META2 ");
 	if (stat & SYS_ERR_MASK_META1)
-		printk("META1 ");
+		pr_cont("META1 ");
 	if (stat & SYS_ERR_MASK_PEU)
-		printk("PEU ");
+		pr_cont("PEU ");
 	if (stat & SYS_ERR_MASK_TXC)
-		printk("TXC ");
+		pr_cont("TXC ");
 	if (stat & SYS_ERR_MASK_RDMC)
-		printk("RDMC ");
+		pr_cont("RDMC ");
 	if (stat & SYS_ERR_MASK_TDMC)
-		printk("TDMC ");
+		pr_cont("TDMC ");
 	if (stat & SYS_ERR_MASK_ZCP)
-		printk("ZCP ");
+		pr_cont("ZCP ");
 	if (stat & SYS_ERR_MASK_FFLP)
-		printk("FFLP ");
+		pr_cont("FFLP ");
 	if (stat & SYS_ERR_MASK_IPP)
-		printk("IPP ");
+		pr_cont("IPP ");
 	if (stat & SYS_ERR_MASK_MAC)
-		printk("MAC ");
+		pr_cont("MAC ");
 	if (stat & SYS_ERR_MASK_SMX)
-		printk("SMX ");
+		pr_cont("SMX ");
 
-	printk(")\n");
+	pr_cont(")\n");
 }
 
 static int niu_device_error(struct niu *np)
 {
 	u64 stat = nr64(SYS_ERR_STAT);
 
-	dev_err(np->device, PFX "%s: Core device error, stat[%llx]\n",
-		np->dev->name, (unsigned long long) stat);
+	netdev_err(np->dev, "Core device error, stat[%llx]\n",
+		   (unsigned long long)stat);
 
 	niu_log_device_error(np, stat);
 
@@ -4197,8 +4164,8 @@ static void niu_rxchan_intr(struct niu *
 		      RX_DMA_CTL_STAT_RCRTO);
 	nw64(RX_DMA_CTL_STAT(rp->rx_channel), stat_write);
 
-	niudbg(INTR, "%s: rxchan_intr stat[%llx]\n",
-	       np->dev->name, (unsigned long long) stat);
+	netif_printk(np, intr, KERN_DEBUG, np->dev,
+		     "%s() stat[%llx]\n", __func__, (unsigned long long)stat);
 }
 
 static void niu_txchan_intr(struct niu *np, struct tx_ring_info *rp,
@@ -4206,8 +4173,8 @@ static void niu_txchan_intr(struct niu *
 {
 	rp->tx_cs = nr64(TX_CS(rp->tx_channel));
 
-	niudbg(INTR, "%s: txchan_intr cs[%llx]\n",
-	       np->dev->name, (unsigned long long) rp->tx_cs);
+	netif_printk(np, intr, KERN_DEBUG, np->dev,
+		     "%s() cs[%llx]\n", __func__, (unsigned long long)rp->tx_cs);
 }
 
 static void __niu_fastpath_interrupt(struct niu *np, int ldg, u64 v0)
@@ -4265,8 +4232,8 @@ static irqreturn_t niu_interrupt(int irq
 	u64 v0, v1, v2;
 
 	if (netif_msg_intr(np))
-		printk(KERN_DEBUG PFX "niu_interrupt() ldg[%p](%d) ",
-		       lp, ldg);
+		printk(KERN_DEBUG KBUILD_MODNAME ": " "%s() ldg[%p](%d)",
+		       __func__, lp, ldg);
 
 	spin_lock_irqsave(&np->lock, flags);
 
@@ -4275,7 +4242,7 @@ static irqreturn_t niu_interrupt(int irq
 	v2 = nr64(LDSV2(ldg));
 
 	if (netif_msg_intr(np))
-		printk("v0[%llx] v1[%llx] v2[%llx]\n",
+		pr_cont(" v0[%llx] v1[%llx] v2[%llx]\n",
 		       (unsigned long long) v0,
 		       (unsigned long long) v1,
 		       (unsigned long long) v2);
@@ -4400,8 +4367,8 @@ static int niu_alloc_rx_ring_info(struct
 	if (!rp->mbox)
 		return -ENOMEM;
 	if ((unsigned long)rp->mbox & (64UL - 1)) {
-		dev_err(np->device, PFX "%s: Coherent alloc gives misaligned "
-			"RXDMA mailbox %p\n", np->dev->name, rp->mbox);
+		netdev_err(np->dev, "Coherent alloc gives misaligned RXDMA mailbox %p\n",
+			   rp->mbox);
 		return -EINVAL;
 	}
 
@@ -4411,8 +4378,8 @@ static int niu_alloc_rx_ring_info(struct
 	if (!rp->rcr)
 		return -ENOMEM;
 	if ((unsigned long)rp->rcr & (64UL - 1)) {
-		dev_err(np->device, PFX "%s: Coherent alloc gives misaligned "
-			"RXDMA RCR table %p\n", np->dev->name, rp->rcr);
+		netdev_err(np->dev, "Coherent alloc gives misaligned RXDMA RCR table %p\n",
+			   rp->rcr);
 		return -EINVAL;
 	}
 	rp->rcr_table_size = MAX_RCR_RING_SIZE;
@@ -4424,8 +4391,8 @@ static int niu_alloc_rx_ring_info(struct
 	if (!rp->rbr)
 		return -ENOMEM;
 	if ((unsigned long)rp->rbr & (64UL - 1)) {
-		dev_err(np->device, PFX "%s: Coherent alloc gives misaligned "
-			"RXDMA RBR table %p\n", np->dev->name, rp->rbr);
+		netdev_err(np->dev, "Coherent alloc gives misaligned RXDMA RBR table %p\n",
+			   rp->rbr);
 		return -EINVAL;
 	}
 	rp->rbr_table_size = MAX_RBR_RING_SIZE;
@@ -4458,8 +4425,8 @@ static int niu_alloc_tx_ring_info(struct
 	if (!rp->mbox)
 		return -ENOMEM;
 	if ((unsigned long)rp->mbox & (64UL - 1)) {
-		dev_err(np->device, PFX "%s: Coherent alloc gives misaligned "
-			"TXDMA mailbox %p\n", np->dev->name, rp->mbox);
+		netdev_err(np->dev, "Coherent alloc gives misaligned TXDMA mailbox %p\n",
+			   rp->mbox);
 		return -EINVAL;
 	}
 
@@ -4469,8 +4436,8 @@ static int niu_alloc_tx_ring_info(struct
 	if (!rp->descr)
 		return -ENOMEM;
 	if ((unsigned long)rp->descr & (64UL - 1)) {
-		dev_err(np->device, PFX "%s: Coherent alloc gives misaligned "
-			"TXDMA descr table %p\n", np->dev->name, rp->descr);
+		netdev_err(np->dev, "Coherent alloc gives misaligned TXDMA descr table %p\n",
+			   rp->descr);
 		return -EINVAL;
 	}
 
@@ -4726,10 +4693,8 @@ static int niu_init_one_tx_channel(struc
 
 	if (rp->descr_dma & ~(TX_RNG_CFIG_STADDR_BASE |
 			      TX_RNG_CFIG_STADDR)) {
-		dev_err(np->device, PFX "%s: TX ring channel %d "
-			"DMA addr (%llx) is not aligned.\n",
-			np->dev->name, channel,
-			(unsigned long long) rp->descr_dma);
+		netdev_err(np->dev, "TX ring channel %d DMA addr (%llx) is not aligned\n",
+			   channel, (unsigned long long)rp->descr_dma);
 		return -EINVAL;
 	}
 
@@ -4746,10 +4711,8 @@ static int niu_init_one_tx_channel(struc
 
 	if (((rp->mbox_dma >> 32) & ~TXDMA_MBH_MBADDR) ||
 	    ((u32)rp->mbox_dma & ~TXDMA_MBL_MBADDR)) {
-		dev_err(np->device, PFX "%s: TX ring channel %d "
-			"MBOX addr (%llx) is has illegal bits.\n",
-			np->dev->name, channel,
-			(unsigned long long) rp->mbox_dma);
+		netdev_err(np->dev, "TX ring channel %d MBOX addr (%llx) has invalid bits\n",
+			    channel, (unsigned long long)rp->mbox_dma);
 		return -EINVAL;
 	}
 	nw64(TXDMA_MBH(channel), rp->mbox_dma >> 32);
@@ -5146,9 +5109,8 @@ static int niu_zcp_read(struct niu *np,
 	err = niu_wait_bits_clear(np, ZCP_RAM_ACC, ZCP_RAM_ACC_BUSY,
 				  1000, 100);
 	if (err) {
-		dev_err(np->device, PFX "%s: ZCP read busy won't clear, "
-			"ZCP_RAM_ACC[%llx]\n", np->dev->name,
-			(unsigned long long) nr64(ZCP_RAM_ACC));
+		netdev_err(np->dev, "ZCP read busy won't clear, ZCP_RAM_ACC[%llx]\n",
+			   (unsigned long long)nr64(ZCP_RAM_ACC));
 		return err;
 	}
 
@@ -5160,9 +5122,8 @@ static int niu_zcp_read(struct niu *np,
 	err = niu_wait_bits_clear(np, ZCP_RAM_ACC, ZCP_RAM_ACC_BUSY,
 				  1000, 100);
 	if (err) {
-		dev_err(np->device, PFX "%s: ZCP read busy2 won't clear, "
-			"ZCP_RAM_ACC[%llx]\n", np->dev->name,
-			(unsigned long long) nr64(ZCP_RAM_ACC));
+		netdev_err(np->dev, "ZCP read busy2 won't clear, ZCP_RAM_ACC[%llx]\n",
+			   (unsigned long long)nr64(ZCP_RAM_ACC));
 		return err;
 	}
 
@@ -5527,8 +5488,7 @@ static int niu_reset_tx_bmac(struct niu
 		udelay(100);
 	}
 	if (limit < 0) {
-		dev_err(np->device, PFX "Port %u TX BMAC would not reset, "
-			"BTXMAC_SW_RST[%llx]\n",
+		dev_err(np->device, "Port %u TX BMAC would not reset, BTXMAC_SW_RST[%llx]\n",
 			np->port,
 			(unsigned long long) nr64_mac(BTXMAC_SW_RST));
 		return -ENODEV;
@@ -5629,12 +5589,11 @@ static int niu_reset_rx_xmac(struct niu
 	while (--limit >= 0) {
 		if (!(nr64_mac(XRXMAC_SW_RST) & (XRXMAC_SW_RST_REG_RS |
 						 XRXMAC_SW_RST_SOFT_RST)))
-		    break;
+			break;
 		udelay(100);
 	}
 	if (limit < 0) {
-		dev_err(np->device, PFX "Port %u RX XMAC would not reset, "
-			"XRXMAC_SW_RST[%llx]\n",
+		dev_err(np->device, "Port %u RX XMAC would not reset, XRXMAC_SW_RST[%llx]\n",
 			np->port,
 			(unsigned long long) nr64_mac(XRXMAC_SW_RST));
 		return -ENODEV;
@@ -5655,8 +5614,7 @@ static int niu_reset_rx_bmac(struct niu
 		udelay(100);
 	}
 	if (limit < 0) {
-		dev_err(np->device, PFX "Port %u RX BMAC would not reset, "
-			"BRXMAC_SW_RST[%llx]\n",
+		dev_err(np->device, "Port %u RX BMAC would not reset, BRXMAC_SW_RST[%llx]\n",
 			np->port,
 			(unsigned long long) nr64_mac(BRXMAC_SW_RST));
 		return -ENODEV;
@@ -5960,11 +5918,9 @@ static void niu_disable_ipp(struct niu *
 	}
 	if (limit < 0 &&
 	    (rd != 0 && wr != 1)) {
-		dev_err(np->device, PFX "%s: IPP would not quiesce, "
-			"rd_ptr[%llx] wr_ptr[%llx]\n",
-			np->dev->name,
-			(unsigned long long) nr64_ipp(IPP_DFIFO_RD_PTR),
-			(unsigned long long) nr64_ipp(IPP_DFIFO_WR_PTR));
+		netdev_err(np->dev, "IPP would not quiesce, rd_ptr[%llx] wr_ptr[%llx]\n",
+			   (unsigned long long)nr64_ipp(IPP_DFIFO_RD_PTR),
+			   (unsigned long long)nr64_ipp(IPP_DFIFO_WR_PTR));
 	}
 
 	val = nr64_ipp(IPP_CFIG);
@@ -5981,12 +5937,12 @@ static int niu_init_hw(struct niu *np)
 {
 	int i, err;
 
-	niudbg(IFUP, "%s: Initialize TXC\n", np->dev->name);
+	netif_printk(np, ifup, KERN_DEBUG, np->dev, "Initialize TXC\n");
 	niu_txc_enable_port(np, 1);
 	niu_txc_port_dma_enable(np, 1);
 	niu_txc_set_imask(np, 0);
 
-	niudbg(IFUP, "%s: Initialize TX channels\n", np->dev->name);
+	netif_printk(np, ifup, KERN_DEBUG, np->dev, "Initialize TX channels\n");
 	for (i = 0; i < np->num_tx_rings; i++) {
 		struct tx_ring_info *rp = &np->tx_rings[i];
 
@@ -5995,27 +5951,27 @@ static int niu_init_hw(struct niu *np)
 			return err;
 	}
 
-	niudbg(IFUP, "%s: Initialize RX channels\n", np->dev->name);
+	netif_printk(np, ifup, KERN_DEBUG, np->dev, "Initialize RX channels\n");
 	err = niu_init_rx_channels(np);
 	if (err)
 		goto out_uninit_tx_channels;
 
-	niudbg(IFUP, "%s: Initialize classifier\n", np->dev->name);
+	netif_printk(np, ifup, KERN_DEBUG, np->dev, "Initialize classifier\n");
 	err = niu_init_classifier_hw(np);
 	if (err)
 		goto out_uninit_rx_channels;
 
-	niudbg(IFUP, "%s: Initialize ZCP\n", np->dev->name);
+	netif_printk(np, ifup, KERN_DEBUG, np->dev, "Initialize ZCP\n");
 	err = niu_init_zcp(np);
 	if (err)
 		goto out_uninit_rx_channels;
 
-	niudbg(IFUP, "%s: Initialize IPP\n", np->dev->name);
+	netif_printk(np, ifup, KERN_DEBUG, np->dev, "Initialize IPP\n");
 	err = niu_init_ipp(np);
 	if (err)
 		goto out_uninit_rx_channels;
 
-	niudbg(IFUP, "%s: Initialize MAC\n", np->dev->name);
+	netif_printk(np, ifup, KERN_DEBUG, np->dev, "Initialize MAC\n");
 	err = niu_init_mac(np);
 	if (err)
 		goto out_uninit_ipp;
@@ -6023,16 +5979,16 @@ static int niu_init_hw(struct niu *np)
 	return 0;
 
 out_uninit_ipp:
-	niudbg(IFUP, "%s: Uninit IPP\n", np->dev->name);
+	netif_printk(np, ifup, KERN_DEBUG, np->dev, "Uninit IPP\n");
 	niu_disable_ipp(np);
 
 out_uninit_rx_channels:
-	niudbg(IFUP, "%s: Uninit RX channels\n", np->dev->name);
+	netif_printk(np, ifup, KERN_DEBUG, np->dev, "Uninit RX channels\n");
 	niu_stop_rx_channels(np);
 	niu_reset_rx_channels(np);
 
 out_uninit_tx_channels:
-	niudbg(IFUP, "%s: Uninit TX channels\n", np->dev->name);
+	netif_printk(np, ifup, KERN_DEBUG, np->dev, "Uninit TX channels\n");
 	niu_stop_tx_channels(np);
 	niu_reset_tx_channels(np);
 
@@ -6041,25 +5997,25 @@ out_uninit_tx_channels:
 
 static void niu_stop_hw(struct niu *np)
 {
-	niudbg(IFDOWN, "%s: Disable interrupts\n", np->dev->name);
+	netif_printk(np, ifdown, KERN_DEBUG, np->dev, "Disable interrupts\n");
 	niu_enable_interrupts(np, 0);
 
-	niudbg(IFDOWN, "%s: Disable RX MAC\n", np->dev->name);
+	netif_printk(np, ifdown, KERN_DEBUG, np->dev, "Disable RX MAC\n");
 	niu_enable_rx_mac(np, 0);
 
-	niudbg(IFDOWN, "%s: Disable IPP\n", np->dev->name);
+	netif_printk(np, ifdown, KERN_DEBUG, np->dev, "Disable IPP\n");
 	niu_disable_ipp(np);
 
-	niudbg(IFDOWN, "%s: Stop TX channels\n", np->dev->name);
+	netif_printk(np, ifdown, KERN_DEBUG, np->dev, "Stop TX channels\n");
 	niu_stop_tx_channels(np);
 
-	niudbg(IFDOWN, "%s: Stop RX channels\n", np->dev->name);
+	netif_printk(np, ifdown, KERN_DEBUG, np->dev, "Stop RX channels\n");
 	niu_stop_rx_channels(np);
 
-	niudbg(IFDOWN, "%s: Reset TX channels\n", np->dev->name);
+	netif_printk(np, ifdown, KERN_DEBUG, np->dev, "Reset TX channels\n");
 	niu_reset_tx_channels(np);
 
-	niudbg(IFDOWN, "%s: Reset RX channels\n", np->dev->name);
+	netif_printk(np, ifdown, KERN_DEBUG, np->dev, "Reset RX channels\n");
 	niu_reset_rx_channels(np);
 }
 
@@ -6369,10 +6325,10 @@ static void niu_set_rx_mode(struct net_d
 	np->flags &= ~(NIU_FLAGS_MCAST | NIU_FLAGS_PROMISC);
 	if (dev->flags & IFF_PROMISC)
 		np->flags |= NIU_FLAGS_PROMISC;
-	if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 0))
+	if ((dev->flags & IFF_ALLMULTI) || (!netdev_mc_empty(dev)))
 		np->flags |= NIU_FLAGS_MCAST;
 
-	alt_cnt = dev->uc.count;
+	alt_cnt = netdev_uc_count(dev);
 	if (alt_cnt > niu_num_alt_addr(np)) {
 		alt_cnt = 0;
 		np->flags |= NIU_FLAGS_PROMISC;
@@ -6381,17 +6337,15 @@ static void niu_set_rx_mode(struct net_d
 	if (alt_cnt) {
 		int index = 0;
 
-		list_for_each_entry(ha, &dev->uc.list, list) {
+		netdev_for_each_uc_addr(ha, dev) {
 			err = niu_set_alt_mac(np, index, ha->addr);
 			if (err)
-				printk(KERN_WARNING PFX "%s: Error %d "
-				       "adding alt mac %d\n",
-				       dev->name, err, index);
+				netdev_warn(dev, "Error %d adding alt mac %d\n",
+					    err, index);
 			err = niu_enable_alt_mac(np, index, 1);
 			if (err)
-				printk(KERN_WARNING PFX "%s: Error %d "
-				       "enabling alt mac %d\n",
-				       dev->name, err, index);
+				netdev_warn(dev, "Error %d enabling alt mac %d\n",
+					    err, index);
 
 			index++;
 		}
@@ -6404,16 +6358,15 @@ static void niu_set_rx_mode(struct net_d
 		for (i = alt_start; i < niu_num_alt_addr(np); i++) {
 			err = niu_enable_alt_mac(np, i, 0);
 			if (err)
-				printk(KERN_WARNING PFX "%s: Error %d "
-				       "disabling alt mac %d\n",
-				       dev->name, err, i);
+				netdev_warn(dev, "Error %d disabling alt mac %d\n",
+					    err, i);
 		}
 	}
 	if (dev->flags & IFF_ALLMULTI) {
 		for (i = 0; i < 16; i++)
 			hash[i] = 0xffff;
-	} else if (dev->mc_count > 0) {
-		for (addr = dev->mc_list; addr; addr = addr->next) {
+	} else if (!netdev_mc_empty(dev)) {
+		netdev_for_each_mc_addr(addr, dev) {
 			u32 crc = ether_crc_le(ETH_ALEN, addr->da_addr);
 
 			crc >>= 24;
@@ -6570,7 +6523,7 @@ static void niu_tx_timeout(struct net_de
 {
 	struct niu *np = netdev_priv(dev);
 
-	dev_err(np->device, PFX "%s: Transmit timed out, resetting\n",
+	dev_err(np->device, "%s: Transmit timed out, resetting\n",
 		dev->name);
 
 	schedule_work(&np->reset_task);
@@ -6672,8 +6625,7 @@ static netdev_tx_t niu_start_xmit(struct
 
 	if (niu_tx_avail(rp) <= (skb_shinfo(skb)->nr_frags + 1)) {
 		netif_tx_stop_queue(txq);
-		dev_err(np->device, PFX "%s: BUG! Tx ring full when "
-			"queue awake!\n", dev->name);
+		dev_err(np->device, "%s: BUG! Tx ring full when queue awake!\n", dev->name);
 		rp->tx_errors++;
 		return NETDEV_TX_BUSY;
 	}
@@ -7237,8 +7189,8 @@ static int niu_get_ethtool_tcam_entry(st
 
 	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);
+		netdev_info(np->dev, "niu%d: entry [%d] invalid for idx[%d]\n",
+			    parent->index, (u16)nfc->fs.location, idx);
 		return -EINVAL;
 	}
 
@@ -7248,8 +7200,8 @@ static int niu_get_ethtool_tcam_entry(st
 	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);
+		netdev_info(np->dev, "niu%d: niu_class_to_ethflow failed\n",
+			    parent->index);
 		ret = -EINVAL;
 		goto out;
 	}
@@ -7332,9 +7284,8 @@ static int niu_get_ethtool_tcam_all(stru
 
 	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);
+		netdev_info(np->dev, "niu%d: In %s(): n_entries[%d] != cnt[%d]!!!\n",
+			    np->parent->index, __func__, n_entries, cnt);
 	}
 
 	return 0;
@@ -7561,9 +7512,8 @@ static int niu_add_ethtool_tcam_entry(st
 			}
 		}
 		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);
+			netdev_info(np->dev, "niu%d: %s(): Could not find/insert class for pid %d\n",
+				    parent->index, __func__, uspec->proto);
 			ret = -EINVAL;
 			goto out;
 		}
@@ -7596,9 +7546,8 @@ static int niu_add_ethtool_tcam_entry(st
 	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);
+		netdev_info(np->dev, "niu%d: In %s(): flow %d for IPv6 not implemented\n",
+			    parent->index, __func__, fsp->flow_type);
 		ret = -EINVAL;
 		goto out;
 	case IP_USER_FLOW:
@@ -7607,17 +7556,15 @@ static int niu_add_ethtool_tcam_entry(st
 						   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);
+			netdev_info(np->dev, "niu%d: In %s(): usr flow for IPv6 not implemented\n",
+				    parent->index, __func__);
 			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);
+		netdev_info(np->dev, "niu%d: In %s(): Unknown flow type %d\n",
+			    parent->index, __func__, fsp->flow_type);
 		ret = -EINVAL;
 		goto out;
 	}
@@ -7627,10 +7574,9 @@ static int niu_add_ethtool_tcam_entry(st
 		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);
+			netdev_info(np->dev, "niu%d: In %s(): Invalid RX ring %lld\n",
+				    parent->index, __func__,
+				    (long long)fsp->ring_cookie);
 			ret = -EINVAL;
 			goto out;
 		}
@@ -7699,10 +7645,9 @@ static int niu_del_ethtool_tcam_entry(st
 			}
 		}
 		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);
+			netdev_info(np->dev, "niu%d: In %s(): Usr class 0x%llx not found\n",
+				    parent->index, __func__,
+				    (unsigned long long)class);
 			ret = -EINVAL;
 			goto out;
 		}
@@ -8001,9 +7946,7 @@ static int niu_ldg_assign_ldn(struct niu
 		 * won't get any interrupts and that's painful to debug.
 		 */
 		if (nr64(LDG_NUM(ldn)) != ldg) {
-			dev_err(np->device, PFX "Port %u, mis-matched "
-				"LDG assignment "
-				"for ldn %d, should be %d is %llu\n",
+			dev_err(np->device, "Port %u, mis-matched LDG assignment for ldn %d, should be %d is %llu\n",
 				np->port, ldn, ldg,
 				(unsigned long long) nr64(LDG_NUM(ldn)));
 			return -EINVAL;
@@ -8056,7 +7999,7 @@ static int __devinit niu_pci_eeprom_read
 			break;
 	} while (limit--);
 	if (!(frame & ESPC_PIO_STAT_READ_END)) {
-		dev_err(np->device, PFX "EEPROM read timeout frame[%llx]\n",
+		dev_err(np->device, "EEPROM read timeout frame[%llx]\n",
 			(unsigned long long) frame);
 		return -ENODEV;
 	}
@@ -8071,7 +8014,7 @@ static int __devinit niu_pci_eeprom_read
 			break;
 	} while (limit--);
 	if (!(frame & ESPC_PIO_STAT_READ_END)) {
-		dev_err(np->device, PFX "EEPROM read timeout frame[%llx]\n",
+		dev_err(np->device, "EEPROM read timeout frame[%llx]\n",
 			(unsigned long long) frame);
 		return -ENODEV;
 	}
@@ -8152,8 +8095,9 @@ static void __devinit niu_vpd_parse_vers
 	s += i + 5;
 	sscanf(s, "%d.%d", &vpd->fcode_major, &vpd->fcode_minor);
 
-	niudbg(PROBE, "VPD_SCAN: FCODE major(%d) minor(%d)\n",
-	       vpd->fcode_major, vpd->fcode_minor);
+	netif_printk(np, probe, KERN_DEBUG, np->dev,
+		     "VPD_SCAN: FCODE major(%d) minor(%d)\n",
+		     vpd->fcode_major, vpd->fcode_minor);
 	if (vpd->fcode_major > NIU_VPD_MIN_MAJOR ||
 	    (vpd->fcode_major == NIU_VPD_MIN_MAJOR &&
 	     vpd->fcode_minor >= NIU_VPD_MIN_MINOR))
@@ -8173,8 +8117,8 @@ static int __devinit niu_pci_vpd_scan_pr
 #define FOUND_MASK_PHY		0x00000020
 #define FOUND_MASK_ALL		0x0000003f
 
-	niudbg(PROBE, "VPD_SCAN: start[%x] end[%x]\n",
-	       start, end);
+	netif_printk(np, probe, KERN_DEBUG, np->dev,
+		     "VPD_SCAN: start[%x] end[%x]\n", start, end);
 	while (start < end) {
 		int len, err, instance, type, prop_len;
 		char namebuf[64];
@@ -8228,8 +8172,7 @@ static int __devinit niu_pci_vpd_scan_pr
 		}
 
 		if (max_len && prop_len > max_len) {
-			dev_err(np->device, PFX "Property '%s' length (%d) is "
-				"too long.\n", namebuf, prop_len);
+			dev_err(np->device, "Property '%s' length (%d) is too long\n", namebuf, prop_len);
 			return -EINVAL;
 		}
 
@@ -8237,8 +8180,9 @@ static int __devinit niu_pci_vpd_scan_pr
 			u32 off = start + 5 + err;
 			int i;
 
-			niudbg(PROBE, "VPD_SCAN: Reading in property [%s] "
-			       "len[%d]\n", namebuf, prop_len);
+			netif_printk(np, probe, KERN_DEBUG, np->dev,
+				     "VPD_SCAN: Reading in property [%s] len[%d]\n",
+				     namebuf, prop_len);
 			for (i = 0; i < prop_len; i++)
 				*prop_buf++ = niu_pci_eeprom_read(np, off + i);
 		}
@@ -8402,8 +8346,7 @@ static void __devinit niu_pci_vpd_valida
 	u8 val8;
 
 	if (!is_valid_ether_addr(&vpd->local_mac[0])) {
-		dev_err(np->device, PFX "VPD MAC invalid, "
-			"falling back to SPROM.\n");
+		dev_err(np->device, "VPD MAC invalid, falling back to SPROM\n");
 
 		np->flags &= ~NIU_FLAGS_VPD_VALID;
 		return;
@@ -8420,14 +8363,14 @@ static void __devinit niu_pci_vpd_valida
 			np->flags &= ~NIU_FLAGS_10G;
 		}
 		if (np->flags & NIU_FLAGS_10G)
-			 np->mac_xcvr = MAC_XCVR_XPCS;
+			np->mac_xcvr = MAC_XCVR_XPCS;
 	} else if (!strcmp(np->vpd.model, NIU_FOXXY_MDL_STR)) {
 		np->flags |= (NIU_FLAGS_10G | NIU_FLAGS_FIBER |
 			      NIU_FLAGS_HOTPLUG_PHY);
 	} else if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) {
-		dev_err(np->device, PFX "Illegal phy string [%s].\n",
+		dev_err(np->device, "Illegal phy string [%s]\n",
 			np->vpd.phy_type);
-		dev_err(np->device, PFX "Falling back to SPROM.\n");
+		dev_err(np->device, "Falling back to SPROM\n");
 		np->flags &= ~NIU_FLAGS_VPD_VALID;
 		return;
 	}
@@ -8455,7 +8398,8 @@ static int __devinit niu_pci_probe_sprom
 
 	np->eeprom_len = len;
 
-	niudbg(PROBE, "SPROM: Image size %llu\n", (unsigned long long) val);
+	netif_printk(np, probe, KERN_DEBUG, np->dev,
+		     "SPROM: Image size %llu\n", (unsigned long long)val);
 
 	sum = 0;
 	for (i = 0; i < len; i++) {
@@ -8465,10 +8409,10 @@ static int __devinit niu_pci_probe_sprom
 		sum += (val >> 16) & 0xff;
 		sum += (val >> 24) & 0xff;
 	}
-	niudbg(PROBE, "SPROM: Checksum %x\n", (int)(sum & 0xff));
+	netif_printk(np, probe, KERN_DEBUG, np->dev,
+		     "SPROM: Checksum %x\n", (int)(sum & 0xff));
 	if ((sum & 0xff) != 0xab) {
-		dev_err(np->device, PFX "Bad SPROM checksum "
-			"(%x, should be 0xab)\n", (int) (sum & 0xff));
+		dev_err(np->device, "Bad SPROM checksum (%x, should be 0xab)\n", (int)(sum & 0xff));
 		return -EINVAL;
 	}
 
@@ -8491,11 +8435,12 @@ static int __devinit niu_pci_probe_sprom
 			ESPC_PHY_TYPE_PORT3_SHIFT;
 		break;
 	default:
-		dev_err(np->device, PFX "Bogus port number %u\n",
+		dev_err(np->device, "Bogus port number %u\n",
 			np->port);
 		return -EINVAL;
 	}
-	niudbg(PROBE, "SPROM: PHY type %x\n", val8);
+	netif_printk(np, probe, KERN_DEBUG, np->dev,
+		     "SPROM: PHY type %x\n", val8);
 
 	switch (val8) {
 	case ESPC_PHY_TYPE_1G_COPPER:
@@ -8527,30 +8472,27 @@ static int __devinit niu_pci_probe_sprom
 		break;
 
 	default:
-		dev_err(np->device, PFX "Bogus SPROM phy type %u\n", val8);
+		dev_err(np->device, "Bogus SPROM phy type %u\n", val8);
 		return -EINVAL;
 	}
 
 	val = nr64(ESPC_MAC_ADDR0);
-	niudbg(PROBE, "SPROM: MAC_ADDR0[%08llx]\n",
-	       (unsigned long long) val);
+	netif_printk(np, probe, KERN_DEBUG, np->dev,
+		     "SPROM: MAC_ADDR0[%08llx]\n", (unsigned long long)val);
 	dev->perm_addr[0] = (val >>  0) & 0xff;
 	dev->perm_addr[1] = (val >>  8) & 0xff;
 	dev->perm_addr[2] = (val >> 16) & 0xff;
 	dev->perm_addr[3] = (val >> 24) & 0xff;
 
 	val = nr64(ESPC_MAC_ADDR1);
-	niudbg(PROBE, "SPROM: MAC_ADDR1[%08llx]\n",
-	       (unsigned long long) val);
+	netif_printk(np, probe, KERN_DEBUG, np->dev,
+		     "SPROM: MAC_ADDR1[%08llx]\n", (unsigned long long)val);
 	dev->perm_addr[4] = (val >>  0) & 0xff;
 	dev->perm_addr[5] = (val >>  8) & 0xff;
 
 	if (!is_valid_ether_addr(&dev->perm_addr[0])) {
-		dev_err(np->device, PFX "SPROM MAC address invalid\n");
-		dev_err(np->device, PFX "[ \n");
-		for (i = 0; i < 6; i++)
-			printk("%02x ", dev->perm_addr[i]);
-		printk("]\n");
+		dev_err(np->device, "SPROM MAC address invalid [ %pM ]\n",
+			dev->perm_addr);
 		return -EINVAL;
 	}
 
@@ -8562,8 +8504,8 @@ static int __devinit niu_pci_probe_sprom
 	memcpy(dev->dev_addr, dev->perm_addr, dev->addr_len);
 
 	val = nr64(ESPC_MOD_STR_LEN);
-	niudbg(PROBE, "SPROM: MOD_STR_LEN[%llu]\n",
-	       (unsigned long long) val);
+	netif_printk(np, probe, KERN_DEBUG, np->dev,
+		     "SPROM: MOD_STR_LEN[%llu]\n", (unsigned long long)val);
 	if (val >= 8 * 4)
 		return -EINVAL;
 
@@ -8578,8 +8520,8 @@ static int __devinit niu_pci_probe_sprom
 	np->vpd.model[val] = '\0';
 
 	val = nr64(ESPC_BD_MOD_STR_LEN);
-	niudbg(PROBE, "SPROM: BD_MOD_STR_LEN[%llu]\n",
-	       (unsigned long long) val);
+	netif_printk(np, probe, KERN_DEBUG, np->dev,
+		     "SPROM: BD_MOD_STR_LEN[%llu]\n", (unsigned long long)val);
 	if (val >= 4 * 4)
 		return -EINVAL;
 
@@ -8595,8 +8537,8 @@ static int __devinit niu_pci_probe_sprom
 
 	np->vpd.mac_num =
 		nr64(ESPC_NUM_PORTS_MACS) & ESPC_NUM_PORTS_MACS_VAL;
-	niudbg(PROBE, "SPROM: NUM_PORTS_MACS[%d]\n",
-	       np->vpd.mac_num);
+	netif_printk(np, probe, KERN_DEBUG, np->dev,
+		     "SPROM: NUM_PORTS_MACS[%d]\n", np->vpd.mac_num);
 
 	return 0;
 }
@@ -8629,8 +8571,6 @@ static int __devinit niu_get_and_validat
 		}
 	}
 
-	niudbg(PROBE, "niu_get_and_validate_port: port[%d] num_ports[%d]\n",
-	       np->port, parent->num_ports);
 	if (np->port >= parent->num_ports)
 		return -ENODEV;
 
@@ -8659,14 +8599,12 @@ static int __devinit phy_record(struct n
 
 	pr_info("niu%d: Found PHY %08x type %s at phy_port %u\n",
 		parent->index, id,
-		(type == PHY_TYPE_PMA_PMD ?
-		 "PMA/PMD" :
-		 (type == PHY_TYPE_PCS ?
-		  "PCS" : "MII")),
+		type == PHY_TYPE_PMA_PMD ? "PMA/PMD" :
+		type == PHY_TYPE_PCS ? "PCS" : "MII",
 		phy_port);
 
 	if (p->cur[type] >= NIU_MAX_PORTS) {
-		printk(KERN_ERR PFX "Too many PHY ports.\n");
+		pr_err("Too many PHY ports\n");
 		return -EINVAL;
 	}
 	idx = p->cur[type];
@@ -8727,8 +8665,7 @@ static void __devinit niu_n2_divide_chan
 		parent->rxchan_per_port[i] = (16 / num_ports);
 		parent->txchan_per_port[i] = (16 / num_ports);
 
-		pr_info(PFX "niu%d: Port %u [%u RX chans] "
-			"[%u TX chans]\n",
+		pr_info("niu%d: Port %u [%u RX chans] [%u TX chans]\n",
 			parent->index, i,
 			parent->rxchan_per_port[i],
 			parent->txchan_per_port[i]);
@@ -8771,8 +8708,7 @@ static void __devinit niu_divide_channel
 			parent->rxchan_per_port[i] = rx_chans_per_1g;
 			parent->txchan_per_port[i] = tx_chans_per_1g;
 		}
-		pr_info(PFX "niu%d: Port %u [%u RX chans] "
-			"[%u TX chans]\n",
+		pr_info("niu%d: Port %u [%u RX chans] [%u TX chans]\n",
 			parent->index, i,
 			parent->rxchan_per_port[i],
 			parent->txchan_per_port[i]);
@@ -8781,23 +8717,20 @@ static void __devinit niu_divide_channel
 	}
 
 	if (tot_rx > NIU_NUM_RXCHAN) {
-		printk(KERN_ERR PFX "niu%d: Too many RX channels (%d), "
-		       "resetting to one per port.\n",
+		pr_err("niu%d: Too many RX channels (%d), resetting to one per port\n",
 		       parent->index, tot_rx);
 		for (i = 0; i < num_ports; i++)
 			parent->rxchan_per_port[i] = 1;
 	}
 	if (tot_tx > NIU_NUM_TXCHAN) {
-		printk(KERN_ERR PFX "niu%d: Too many TX channels (%d), "
-		       "resetting to one per port.\n",
+		pr_err("niu%d: Too many TX channels (%d), resetting to one per port\n",
 		       parent->index, tot_tx);
 		for (i = 0; i < num_ports; i++)
 			parent->txchan_per_port[i] = 1;
 	}
 	if (tot_rx < NIU_NUM_RXCHAN || tot_tx < NIU_NUM_TXCHAN) {
-		printk(KERN_WARNING PFX "niu%d: Driver bug, wasted channels, "
-		       "RX[%d] TX[%d]\n",
-		       parent->index, tot_rx, tot_tx);
+		pr_warning("niu%d: Driver bug, wasted channels, RX[%d] TX[%d]\n",
+			   parent->index, tot_rx, tot_tx);
 	}
 }
 
@@ -8825,18 +8758,18 @@ static void __devinit niu_divide_rdc_gro
 			struct rdc_table *rt = &tp->tables[grp];
 			int slot;
 
-			pr_info(PFX "niu%d: Port %d RDC tbl(%d) [ ",
+			pr_info("niu%d: Port %d RDC tbl(%d) [ ",
 				parent->index, i, tp->first_table_num + grp);
 			for (slot = 0; slot < NIU_RDC_TABLE_SLOTS; slot++) {
 				rt->rxdma_channel[slot] =
 					rdc_channel_base + this_channel_offset;
 
-				printk("%d ", rt->rxdma_channel[slot]);
+				pr_cont("%d ", rt->rxdma_channel[slot]);
 
 				if (++this_channel_offset == num_channels)
 					this_channel_offset = 0;
 			}
-			printk("]\n");
+			pr_cont("]\n");
 		}
 
 		parent->rdc_default[i] = rdc_channel_base;
@@ -8996,8 +8929,7 @@ static int __devinit walk_phys(struct ni
 			break;
 
 		default:
-			printk(KERN_ERR PFX "Unsupported port config "
-			       "10G[%d] 1G[%d]\n",
+			pr_err("Unsupported port config 10G[%d] 1G[%d]\n",
 			       num_10g, num_1g);
 			return -EINVAL;
 		}
@@ -9015,8 +8947,7 @@ static int __devinit walk_phys(struct ni
 	return 0;
 
 unknown_vg_1g_port:
-	printk(KERN_ERR PFX "Cannot identify platform type, 1gport=%d\n",
-	       lowest_1g);
+	pr_err("Cannot identify platform type, 1gport=%d\n", lowest_1g);
 	return -EINVAL;
 }
 
@@ -9025,9 +8956,6 @@ static int __devinit niu_probe_ports(str
 	struct niu_parent *parent = np->parent;
 	int err, i;
 
-	niudbg(PROBE, "niu_probe_ports(): port_phy[%08x]\n",
-	       parent->port_phy);
-
 	if (parent->port_phy == PORT_PHY_UNKNOWN) {
 		err = walk_phys(np, parent);
 		if (err)
@@ -9048,9 +8976,6 @@ static int __devinit niu_classifier_swst
 {
 	struct niu_classifier *cp = &np->clas;
 
-	niudbg(PROBE, "niu_classifier_swstate_init: num_tcam(%d)\n",
-	       np->parent->tcam_num_entries);
-
 	cp->tcam_top = (u16) np->port;
 	cp->tcam_sz = np->parent->tcam_num_entries / np->parent->num_ports;
 	cp->h1_init = 0xffffffff;
@@ -9116,8 +9041,7 @@ static int __devinit niu_init_mac_ipp_pc
 		break;
 
 	default:
-		dev_err(np->device, PFX "Port %u is invalid, cannot "
-			"compute MAC block offset.\n", np->port);
+		dev_err(np->device, "Port %u is invalid, cannot compute MAC block offset\n", np->port);
 		return -EINVAL;
 	}
 
@@ -9327,9 +9251,8 @@ static int __devinit niu_get_of_props(st
 
 	phy_type = of_get_property(dp, "phy-type", &prop_len);
 	if (!phy_type) {
-		dev_err(np->device, PFX "%s: OF node lacks "
-			"phy-type property\n",
-			dp->full_name);
+		netdev_err(dev, "%s: OF node lacks phy-type property\n",
+			   dp->full_name);
 		return -EINVAL;
 	}
 
@@ -9339,34 +9262,26 @@ static int __devinit niu_get_of_props(st
 	strcpy(np->vpd.phy_type, phy_type);
 
 	if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) {
-		dev_err(np->device, PFX "%s: Illegal phy string [%s].\n",
-			dp->full_name, np->vpd.phy_type);
+		netdev_err(dev, "%s: Illegal phy string [%s]\n",
+			   dp->full_name, np->vpd.phy_type);
 		return -EINVAL;
 	}
 
 	mac_addr = of_get_property(dp, "local-mac-address", &prop_len);
 	if (!mac_addr) {
-		dev_err(np->device, PFX "%s: OF node lacks "
-			"local-mac-address property\n",
-			dp->full_name);
+		netdev_err(dev, "%s: OF node lacks local-mac-address property\n",
+			   dp->full_name);
 		return -EINVAL;
 	}
 	if (prop_len != dev->addr_len) {
-		dev_err(np->device, PFX "%s: OF MAC address prop len (%d) "
-			"is wrong.\n",
-			dp->full_name, prop_len);
+		netdev_err(dev, "%s: OF MAC address prop len (%d) is wrong\n",
+			   dp->full_name, prop_len);
 	}
 	memcpy(dev->perm_addr, mac_addr, dev->addr_len);
 	if (!is_valid_ether_addr(&dev->perm_addr[0])) {
-		int i;
-
-		dev_err(np->device, PFX "%s: OF MAC address is invalid\n",
-			dp->full_name);
-		dev_err(np->device, PFX "%s: [ \n",
-			dp->full_name);
-		for (i = 0; i < 6; i++)
-			printk("%02x ", dev->perm_addr[i]);
-		printk("]\n");
+		netdev_err(dev, "%s: OF MAC address is invalid\n",
+			   dp->full_name);
+		netdev_err(dev, "%s: [ %pM ]\n", dp->full_name, dev->perm_addr);
 		return -EINVAL;
 	}
 
@@ -9414,8 +9329,8 @@ static int __devinit niu_get_invariants(
 
 		nw64(ESPC_PIO_EN, ESPC_PIO_EN_ENABLE);
 		offset = niu_pci_vpd_offset(np);
-		niudbg(PROBE, "niu_get_invariants: VPD offset [%08x]\n",
-		       offset);
+		netif_printk(np, probe, KERN_DEBUG, np->dev,
+			     "%s() VPD offset [%08x]\n", __func__, offset);
 		if (offset)
 			niu_pci_vpd_fetch(np, offset);
 		nw64(ESPC_PIO_EN, 0);
@@ -9575,8 +9490,6 @@ static struct niu_parent * __devinit niu
 	struct niu_parent *p;
 	int i;
 
-	niudbg(PROBE, "niu_new_parent: Creating new parent.\n");
-
 	plat_dev = platform_device_register_simple("niu", niu_parent_index,
 						   NULL, 0);
 	if (IS_ERR(plat_dev))
@@ -9641,9 +9554,6 @@ static struct niu_parent * __devinit niu
 	struct niu_parent *p, *tmp;
 	int port = np->port;
 
-	niudbg(PROBE, "niu_get_parent: platform_type[%u] port[%u]\n",
-	       ptype, port);
-
 	mutex_lock(&niu_parent_lock);
 	p = NULL;
 	list_for_each_entry(tmp, &niu_parent_list, list) {
@@ -9681,7 +9591,8 @@ static void niu_put_parent(struct niu *n
 
 	BUG_ON(!p || p->ports[port] != np);
 
-	niudbg(PROBE, "niu_put_parent: port[%u]\n", port);
+	netif_printk(np, probe, KERN_DEBUG, np->dev,
+		     "%s() port[%u]\n", __func__, port);
 
 	sprintf(port_name, "port%d", port);
 
@@ -9772,7 +9683,7 @@ static struct net_device * __devinit niu
 
 	dev = alloc_etherdev_mq(sizeof(struct niu), NIU_NUM_TXCHAN);
 	if (!dev) {
-		dev_err(gen_dev, PFX "Etherdev alloc failed, aborting.\n");
+		dev_err(gen_dev, "Etherdev alloc failed, aborting\n");
 		return NULL;
 	}
 
@@ -9858,30 +9769,26 @@ static int __devinit niu_pci_init_one(st
 
 	err = pci_enable_device(pdev);
 	if (err) {
-		dev_err(&pdev->dev, PFX "Cannot enable PCI device, "
-			"aborting.\n");
+		dev_err(&pdev->dev, "Cannot enable PCI device, aborting\n");
 		return err;
 	}
 
 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) ||
 	    !(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
-		dev_err(&pdev->dev, PFX "Cannot find proper PCI device "
-			"base addresses, aborting.\n");
+		dev_err(&pdev->dev, "Cannot find proper PCI device base addresses, aborting\n");
 		err = -ENODEV;
 		goto err_out_disable_pdev;
 	}
 
 	err = pci_request_regions(pdev, DRV_MODULE_NAME);
 	if (err) {
-		dev_err(&pdev->dev, PFX "Cannot obtain PCI resources, "
-			"aborting.\n");
+		dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting\n");
 		goto err_out_disable_pdev;
 	}
 
 	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
 	if (pos <= 0) {
-		dev_err(&pdev->dev, PFX "Cannot find PCI Express capability, "
-			"aborting.\n");
+		dev_err(&pdev->dev, "Cannot find PCI Express capability, aborting\n");
 		goto err_out_free_res;
 	}
 
@@ -9920,17 +9827,14 @@ static int __devinit niu_pci_init_one(st
 		dev->features |= NETIF_F_HIGHDMA;
 		err = pci_set_consistent_dma_mask(pdev, dma_mask);
 		if (err) {
-			dev_err(&pdev->dev, PFX "Unable to obtain 44 bit "
-				"DMA for consistent allocations, "
-				"aborting.\n");
+			dev_err(&pdev->dev, "Unable to obtain 44 bit DMA for consistent allocations, aborting\n");
 			goto err_out_release_parent;
 		}
 	}
 	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");
+			dev_err(&pdev->dev, "No usable DMA configuration, aborting\n");
 			goto err_out_release_parent;
 		}
 	}
@@ -9939,8 +9843,7 @@ static int __devinit niu_pci_init_one(st
 
 	np->regs = pci_ioremap_bar(pdev, 0);
 	if (!np->regs) {
-		dev_err(&pdev->dev, PFX "Cannot map device registers, "
-			"aborting.\n");
+		dev_err(&pdev->dev, "Cannot map device registers, aborting\n");
 		err = -ENOMEM;
 		goto err_out_release_parent;
 	}
@@ -9955,15 +9858,13 @@ static int __devinit niu_pci_init_one(st
 	err = niu_get_invariants(np);
 	if (err) {
 		if (err != -ENODEV)
-			dev_err(&pdev->dev, PFX "Problem fetching invariants "
-				"of chip, aborting.\n");
+			dev_err(&pdev->dev, "Problem fetching invariants of chip, aborting\n");
 		goto err_out_iounmap;
 	}
 
 	err = register_netdev(dev);
 	if (err) {
-		dev_err(&pdev->dev, PFX "Cannot register net device, "
-			"aborting.\n");
+		dev_err(&pdev->dev, "Cannot register net device, aborting\n");
 		goto err_out_iounmap;
 	}
 
@@ -10157,7 +10058,7 @@ static int __devinit niu_of_probe(struct
 
 	reg = of_get_property(op->node, "reg", NULL);
 	if (!reg) {
-		dev_err(&op->dev, PFX "%s: No 'reg' property, aborting.\n",
+		dev_err(&op->dev, "%s: No 'reg' property, aborting\n",
 			op->node->full_name);
 		return -ENODEV;
 	}
@@ -10186,8 +10087,7 @@ static int __devinit niu_of_probe(struct
 			      resource_size(&op->resource[1]),
 			      "niu regs");
 	if (!np->regs) {
-		dev_err(&op->dev, PFX "Cannot map device registers, "
-			"aborting.\n");
+		dev_err(&op->dev, "Cannot map device registers, aborting\n");
 		err = -ENOMEM;
 		goto err_out_release_parent;
 	}
@@ -10196,8 +10096,7 @@ static int __devinit niu_of_probe(struct
 				    resource_size(&op->resource[2]),
 				    "niu vregs-1");
 	if (!np->vir_regs_1) {
-		dev_err(&op->dev, PFX "Cannot map device vir registers 1, "
-			"aborting.\n");
+		dev_err(&op->dev, "Cannot map device vir registers 1, aborting\n");
 		err = -ENOMEM;
 		goto err_out_iounmap;
 	}
@@ -10206,8 +10105,7 @@ static int __devinit niu_of_probe(struct
 				    resource_size(&op->resource[3]),
 				    "niu vregs-2");
 	if (!np->vir_regs_2) {
-		dev_err(&op->dev, PFX "Cannot map device vir registers 2, "
-			"aborting.\n");
+		dev_err(&op->dev, "Cannot map device vir registers 2, aborting\n");
 		err = -ENOMEM;
 		goto err_out_iounmap;
 	}
@@ -10217,15 +10115,13 @@ static int __devinit niu_of_probe(struct
 	err = niu_get_invariants(np);
 	if (err) {
 		if (err != -ENODEV)
-			dev_err(&op->dev, PFX "Problem fetching invariants "
-				"of chip, aborting.\n");
+			dev_err(&op->dev, "Problem fetching invariants of chip, aborting\n");
 		goto err_out_iounmap;
 	}
 
 	err = register_netdev(dev);
 	if (err) {
-		dev_err(&op->dev, PFX "Cannot register net device, "
-			"aborting.\n");
+		dev_err(&op->dev, "Cannot register net device, aborting\n");
 		goto err_out_iounmap;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ns83820.c linux-libre-2.6.34-gnu1/drivers/net/ns83820.c
--- linux-libre-2.6.33-gnu1/drivers/net/ns83820.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ns83820.c	2010-05-16 17:17:36.000000000 -0400
@@ -116,6 +116,7 @@
 #include <linux/if_vlan.h>
 #include <linux/rtnetlink.h>
 #include <linux/jiffies.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -1719,7 +1720,7 @@ static void ns83820_set_multicast(struct
 	else
 		and_mask &= ~(RFCR_AAU | RFCR_AAM);
 
-	if (ndev->flags & IFF_ALLMULTI || ndev->mc_count)
+	if (ndev->flags & IFF_ALLMULTI || netdev_mc_count(ndev))
 		or_mask |= RFCR_AAM;
 	else
 		and_mask &= ~RFCR_AAM;
@@ -2292,7 +2293,7 @@ static void __devexit ns83820_remove_one
 	pci_set_drvdata(pci_dev, NULL);
 }
 
-static struct pci_device_id ns83820_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(ns83820_pci_tbl) = {
 	{ 0x100b, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, .driver_data = 0, },
 	{ 0, },
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/octeon/octeon_mgmt.c linux-libre-2.6.34-gnu1/drivers/net/octeon/octeon_mgmt.c
--- linux-libre-2.6.33-gnu1/drivers/net/octeon/octeon_mgmt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/octeon/octeon_mgmt.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/if_vlan.h>
+#include <linux/slab.h>
 #include <linux/phy.h>
 #include <linux/spinlock.h>
 
@@ -467,7 +468,6 @@ static void octeon_mgmt_set_rx_filtering
 {
 	struct octeon_mgmt *p = netdev_priv(netdev);
 	int port = p->port;
-	int i;
 	union cvmx_agl_gmx_rxx_adr_ctl adr_ctl;
 	union cvmx_agl_gmx_prtx_cfg agl_gmx_prtx;
 	unsigned long flags;
@@ -493,8 +493,8 @@ static void octeon_mgmt_set_rx_filtering
 	}
 
 	if (netdev->flags & IFF_MULTICAST) {
-		if (cam_mode == 0 || (netdev->flags & IFF_ALLMULTI)
-		    || netdev->mc_count  > available_cam_entries)
+		if (cam_mode == 0 || (netdev->flags & IFF_ALLMULTI) ||
+		    netdev_mc_count(netdev) > available_cam_entries)
 			multicast_mode = 2; /* 1 - Accept all multicast.  */
 		else
 			multicast_mode = 0; /* 0 - Use CAM.  */
@@ -511,12 +511,8 @@ static void octeon_mgmt_set_rx_filtering
 		}
 	}
 	if (multicast_mode == 0) {
-		i = netdev->mc_count;
-		list = netdev->mc_list;
-		while (i--) {
+		netdev_for_each_mc_addr(list, netdev)
 			octeon_mgmt_cam_state_add(&cam_state, list->da_addr);
-			list = list->next;
-		}
 	}
 
 
@@ -1119,11 +1115,8 @@ static int __init octeon_mgmt_probe(stru
 
 	if (p->port >= octeon_bootinfo->mac_addr_count)
 		dev_err(&pdev->dev,
-			"Error %s: Using MAC outside of the assigned range: "
-			"%02x:%02x:%02x:%02x:%02x:%02x\n", netdev->name,
-			netdev->dev_addr[0], netdev->dev_addr[1],
-			netdev->dev_addr[2], netdev->dev_addr[3],
-			netdev->dev_addr[4], netdev->dev_addr[5]);
+			"Error %s: Using MAC outside of the assigned range: %pM\n",
+			netdev->name, netdev->dev_addr);
 
 	if (register_netdev(netdev))
 		goto err;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/pasemi_mac.c linux-libre-2.6.34-gnu1/drivers/net/pasemi_mac.c
--- linux-libre-2.6.33-gnu1/drivers/net/pasemi_mac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/pasemi_mac.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/dmaengine.h>
 #include <linux/delay.h>
@@ -1875,7 +1876,7 @@ static void __devexit pasemi_mac_remove(
 	free_netdev(netdev);
 }
 
-static struct pci_device_id pasemi_mac_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(pasemi_mac_pci_tbl) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa005) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa006) },
 	{ },
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/pci-skeleton.c linux-libre-2.6.34-gnu1/drivers/net/pci-skeleton.c
--- linux-libre-2.6.33-gnu1/drivers/net/pci-skeleton.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/pci-skeleton.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,7 @@
 
 	-----<snip>-----
 
-        	Written 1997-2000 by Donald Becker.
+		Written 1997-2000 by Donald Becker.
 		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
@@ -85,6 +85,8 @@ IVc. Errata
 
 */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -96,16 +98,15 @@ IVc. Errata
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/crc32.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #define NETDRV_VERSION		"1.0.1"
 #define MODNAME			"netdrv"
 #define NETDRV_DRIVER_LOAD_MSG	"MyVendor Fast Ethernet driver " NETDRV_VERSION " loaded"
-#define PFX			MODNAME ": "
 
 static char version[] __devinitdata =
-KERN_INFO NETDRV_DRIVER_LOAD_MSG "\n"
-"  Support available from http://foo.com/bar/baz.html\n";
+	KERN_INFO NETDRV_DRIVER_LOAD_MSG "\n"
+	"  Support available from http://foo.com/bar/baz.html\n";
 
 /* define to 1 to enable PIO instead of MMIO */
 #undef USE_IO_OPS
@@ -119,19 +120,24 @@ KERN_INFO NETDRV_DRIVER_LOAD_MSG "\n"
 
 #ifdef NETDRV_DEBUG
 /* note: prints function name for you */
-#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
+#define DPRINTK(fmt, args...)					\
+	printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
 #else
-#  define DPRINTK(fmt, args...)
+#define DPRINTK(fmt, args...)				\
+do {							\
+	if (0)						\
+		printk(KERN_DEBUG fmt, ##args);		\
+} while (0)
 #endif
 
 #ifdef NETDRV_NDEBUG
-#  define assert(expr) do {} while (0)
+#define assert(expr) do {} while (0)
 #else
-#  define assert(expr) \
-        if(!(expr)) {					\
-        printk( "Assertion failed! %s,%s,%s,line=%d\n",	\
-        #expr,__FILE__,__func__,__LINE__);		\
-        }
+#define assert(expr)						\
+	if (!(expr)) {						\
+		printk("Assertion failed! %s,%s,%s,line=%d\n",	\
+		       #expr, __FILE__, __func__, __LINE__);	\
+	}
 #endif
 
 
@@ -148,10 +154,10 @@ static int multicast_filter_limit = 32;
 
 /* Size of the in-memory receive ring. */
 #define RX_BUF_LEN_IDX	2	/* 0==8K, 1==16K, 2==32K, 3==64K */
-#define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX)
-#define RX_BUF_PAD 16
+#define RX_BUF_LEN	(8192 << RX_BUF_LEN_IDX)
+#define RX_BUF_PAD	16
 #define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */
-#define RX_BUF_TOT_LEN (RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
+#define RX_BUF_TOT_LEN	(RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
 
 /* Number of Tx descriptor registers. */
 #define NUM_TX_DESC	4
@@ -165,9 +171,11 @@ static int multicast_filter_limit = 32;
 
 /* PCI Tuning Parameters
    Threshold is bytes transferred to chip before transmission starts. */
-#define TX_FIFO_THRESH 256	/* In bytes, rounded down to 32 byte units. */
+#define TX_FIFO_THRESH	256	/* In bytes, rounded down to 32 byte units. */
 
-/* The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024, 7==end of packet. */
+/* The following settings are log_2(bytes)-4:
+   0==16 bytes 1==32 2==64 3==128 4==256 5==512 6==1024 7==end of packet.
+*/
 #define RX_FIFO_THRESH	6	/* Rx buffer level before first PCI xfer.  */
 #define RX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
 #define TX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
@@ -175,8 +183,7 @@ static int multicast_filter_limit = 32;
 
 /* Operational parameters that usually are not changed. */
 /* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT  (6*HZ)
-
+#define TX_TIMEOUT	(6 * HZ)
 
 enum {
 	HAS_CHIP_XCVR = 0x020000,
@@ -186,7 +193,7 @@ enum {
 #define NETDRV_MIN_IO_SIZE 0x80
 #define RTL8139B_IO_SIZE 256
 
-#define NETDRV_CAPS	HAS_CHIP_XCVR|HAS_LNK_CHNG
+#define NETDRV_CAPS	(HAS_CHIP_XCVR | HAS_LNK_CHNG)
 
 typedef enum {
 	RTL8139 = 0,
@@ -211,7 +218,7 @@ static struct {
 };
 
 
-static struct pci_device_id netdrv_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(netdrv_pci_tbl) = {
 	{0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 	{0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NETDRV_CB },
 	{0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SMC1211TX },
@@ -220,7 +227,7 @@ static struct pci_device_id netdrv_pci_t
 	{0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ADDTRON8139 },
 	{0,}
 };
-MODULE_DEVICE_TABLE (pci, netdrv_pci_tbl);
+MODULE_DEVICE_TABLE(pci, netdrv_pci_tbl);
 
 
 /* The rest of these values should never change. */
@@ -270,7 +277,7 @@ enum NETDRV_registers {
 enum ClearBitMasks {
 	MultiIntrClear = 0xF000,
 	ChipCmdClear = 0xE2,
-	Config1Clear = (1<<7)|(1<<6)|(1<<3)|(1<<2)|(1<<1),
+	Config1Clear = (1 << 7) | (1 << 6) | (1 << 3) | (1 << 2) | (1 << 1),
 };
 
 enum ChipCmdBits {
@@ -329,7 +336,7 @@ enum tx_config_bits {
 	TxLoopBack = (1 << 18) | (1 << 17), /* enable loopback test mode */
 	TxCRC = (1 << 16),	/* DISABLE appending CRC to end of Tx packets */
 	TxClearAbt = (1 << 0),	/* Clear abort (WO) */
-	TxDMAShift = 8,		/* DMA burst value (0-7) is shift this many bits */
+	TxDMAShift = 8,		/* DMA burst value(0-7) is shift this many bits */
 
 	TxVersionMask = 0x7C800000, /* mask out version bits 30-26, 23 */
 };
@@ -481,41 +488,44 @@ struct netdrv_private {
 	chip_t chipset;
 };
 
-MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>");
-MODULE_DESCRIPTION ("Skeleton for a PCI Fast Ethernet driver");
+MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
+MODULE_DESCRIPTION("Skeleton for a PCI Fast Ethernet driver");
 MODULE_LICENSE("GPL");
 module_param(multicast_filter_limit, int, 0);
 module_param(max_interrupt_work, int, 0);
 module_param_array(media, int, NULL, 0);
-MODULE_PARM_DESC (multicast_filter_limit, "pci-skeleton maximum number of filtered multicast addresses");
-MODULE_PARM_DESC (max_interrupt_work, "pci-skeleton maximum events handled per interrupt");
-MODULE_PARM_DESC (media, "pci-skeleton: Bits 0-3: media type, bit 17: full duplex");
+MODULE_PARM_DESC(multicast_filter_limit,
+		 MODNAME " maximum number of filtered multicast addresses");
+MODULE_PARM_DESC(max_interrupt_work,
+		 MODNAME " maximum events handled per interrupt");
+MODULE_PARM_DESC(media,
+		 MODNAME " Bits 0-3: media type, bit 17: full duplex");
 
-static int read_eeprom (void *ioaddr, int location, int addr_len);
-static int netdrv_open (struct net_device *dev);
-static int mdio_read (struct net_device *dev, int phy_id, int location);
-static void mdio_write (struct net_device *dev, int phy_id, int location,
-			int val);
-static void netdrv_timer (unsigned long data);
-static void netdrv_tx_timeout (struct net_device *dev);
-static void netdrv_init_ring (struct net_device *dev);
-static int netdrv_start_xmit (struct sk_buff *skb,
-			       struct net_device *dev);
-static irqreturn_t netdrv_interrupt (int irq, void *dev_instance);
-static int netdrv_close (struct net_device *dev);
-static int netdrv_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
-static void netdrv_set_rx_mode (struct net_device *dev);
-static void netdrv_hw_start (struct net_device *dev);
+static int read_eeprom(void *ioaddr, int location, int addr_len);
+static int netdrv_open(struct net_device *dev);
+static int mdio_read(struct net_device *dev, int phy_id, int location);
+static void mdio_write(struct net_device *dev, int phy_id, int location,
+		       int val);
+static void netdrv_timer(unsigned long data);
+static void netdrv_tx_timeout(struct net_device *dev);
+static void netdrv_init_ring(struct net_device *dev);
+static int netdrv_start_xmit(struct sk_buff *skb,
+			     struct net_device *dev);
+static irqreturn_t netdrv_interrupt(int irq, void *dev_instance);
+static int netdrv_close(struct net_device *dev);
+static int netdrv_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static void netdrv_set_rx_mode(struct net_device *dev);
+static void netdrv_hw_start(struct net_device *dev);
 
 
 #ifdef USE_IO_OPS
 
-#define NETDRV_R8(reg)		inb (((unsigned long)ioaddr) + (reg))
-#define NETDRV_R16(reg)		inw (((unsigned long)ioaddr) + (reg))
-#define NETDRV_R32(reg)		((unsigned long) inl (((unsigned long)ioaddr) + (reg)))
-#define NETDRV_W8(reg, val8)	outb ((val8), ((unsigned long)ioaddr) + (reg))
-#define NETDRV_W16(reg, val16)	outw ((val16), ((unsigned long)ioaddr) + (reg))
-#define NETDRV_W32(reg, val32)	outl ((val32), ((unsigned long)ioaddr) + (reg))
+#define NETDRV_R8(reg)		inb(((unsigned long)ioaddr) + (reg))
+#define NETDRV_R16(reg)		inw(((unsigned long)ioaddr) + (reg))
+#define NETDRV_R32(reg)		((unsigned long)inl(((unsigned long)ioaddr) + (reg)))
+#define NETDRV_W8(reg, val8)	outb((val8), ((unsigned long)ioaddr) + (reg))
+#define NETDRV_W16(reg, val16)	outw((val16), ((unsigned long)ioaddr) + (reg))
+#define NETDRV_W32(reg, val32)	outl((val32), ((unsigned long)ioaddr) + (reg))
 #define NETDRV_W8_F		NETDRV_W8
 #define NETDRV_W16_F		NETDRV_W16
 #define NETDRV_W32_F		NETDRV_W32
@@ -528,25 +538,37 @@ static void netdrv_hw_start (struct net_
 #define readb(addr) inb((unsigned long)(addr))
 #define readw(addr) inw((unsigned long)(addr))
 #define readl(addr) inl((unsigned long)(addr))
-#define writeb(val,addr) outb((val),(unsigned long)(addr))
-#define writew(val,addr) outw((val),(unsigned long)(addr))
-#define writel(val,addr) outl((val),(unsigned long)(addr))
+#define writeb(val, addr) outb((val), (unsigned long)(addr))
+#define writew(val, addr) outw((val), (unsigned long)(addr))
+#define writel(val, addr) outl((val), (unsigned long)(addr))
 
 #else
 
 /* write MMIO register, with flush */
 /* Flush avoids rtl8139 bug w/ posted MMIO writes */
-#define NETDRV_W8_F(reg, val8)	do { writeb ((val8), ioaddr + (reg)); readb (ioaddr + (reg)); } while (0)
-#define NETDRV_W16_F(reg, val16)	do { writew ((val16), ioaddr + (reg)); readw (ioaddr + (reg)); } while (0)
-#define NETDRV_W32_F(reg, val32)	do { writel ((val32), ioaddr + (reg)); readl (ioaddr + (reg)); } while (0)
+#define NETDRV_W8_F(reg, val8)			\
+do {						\
+	writeb((val8), ioaddr + (reg));		\
+	readb(ioaddr + (reg));			\
+} while (0)
+#define NETDRV_W16_F(reg, val16)		\
+do {						\
+	writew((val16), ioaddr + (reg));	\
+	readw(ioaddr + (reg));			\
+} while (0)
+#define NETDRV_W32_F(reg, val32)		\
+do {						\
+	writel((val32), ioaddr + (reg));	\
+	readl(ioaddr + (reg));			\
+} while (0)
 
 
 #ifdef MMIO_FLUSH_AUDIT_COMPLETE
 
 /* write MMIO register */
-#define NETDRV_W8(reg, val8)	writeb ((val8), ioaddr + (reg))
-#define NETDRV_W16(reg, val16)	writew ((val16), ioaddr + (reg))
-#define NETDRV_W32(reg, val32)	writel ((val32), ioaddr + (reg))
+#define NETDRV_W8(reg, val8)	writeb((val8), ioaddr + (reg))
+#define NETDRV_W16(reg, val16)	writew((val16), ioaddr + (reg))
+#define NETDRV_W32(reg, val32)	writel((val32), ioaddr + (reg))
 
 #else
 
@@ -558,9 +580,9 @@ static void netdrv_hw_start (struct net_
 #endif /* MMIO_FLUSH_AUDIT_COMPLETE */
 
 /* read MMIO register */
-#define NETDRV_R8(reg)		readb (ioaddr + (reg))
-#define NETDRV_R16(reg)		readw (ioaddr + (reg))
-#define NETDRV_R32(reg)		((unsigned long) readl (ioaddr + (reg)))
+#define NETDRV_R8(reg)		readb(ioaddr + (reg))
+#define NETDRV_R16(reg)		readw(ioaddr + (reg))
+#define NETDRV_R32(reg)		((unsigned long) readl(ioaddr + (reg)))
 
 #endif /* USE_IO_OPS */
 
@@ -570,14 +592,14 @@ static const u16 netdrv_intr_mask =
 	TxErr | TxOK | RxErr | RxOK;
 
 static const unsigned int netdrv_rx_config =
-	  RxCfgEarlyRxNone | RxCfgRcv32K | RxNoWrap |
-	  (RX_FIFO_THRESH << RxCfgFIFOShift) |
-	  (RX_DMA_BURST << RxCfgDMAShift);
+	RxCfgEarlyRxNone | RxCfgRcv32K | RxNoWrap |
+	(RX_FIFO_THRESH << RxCfgFIFOShift) |
+	(RX_DMA_BURST << RxCfgDMAShift);
 
 
-static int __devinit netdrv_init_board (struct pci_dev *pdev,
-					 struct net_device **dev_out,
-					 void **ioaddr_out)
+static int __devinit netdrv_init_board(struct pci_dev *pdev,
+				       struct net_device **dev_out,
+				       void **ioaddr_out)
 {
 	void *ioaddr = NULL;
 	struct net_device *dev;
@@ -587,43 +609,43 @@ static int __devinit netdrv_init_board (
 	unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
 	u32 tmp;
 
-	DPRINTK ("ENTER\n");
+	DPRINTK("ENTER\n");
 
-	assert (pdev != NULL);
-	assert (ioaddr_out != NULL);
+	assert(pdev != NULL);
+	assert(ioaddr_out != NULL);
 
 	*ioaddr_out = NULL;
 	*dev_out = NULL;
 
 	/* dev zeroed in alloc_etherdev */
-	dev = alloc_etherdev (sizeof (*tp));
+	dev = alloc_etherdev(sizeof(*tp));
 	if (dev == NULL) {
 		dev_err(&pdev->dev, "unable to alloc new ethernet\n");
-		DPRINTK ("EXIT, returning -ENOMEM\n");
+		DPRINTK("EXIT, returning -ENOMEM\n");
 		return -ENOMEM;
 	}
 	SET_NETDEV_DEV(dev, &pdev->dev);
 	tp = netdev_priv(dev);
 
-	/* enable device (incl. PCI PM wakeup), and bus-mastering */
-	rc = pci_enable_device (pdev);
+	/* enable device(incl. PCI PM wakeup), and bus-mastering */
+	rc = pci_enable_device(pdev);
 	if (rc)
 		goto err_out;
 
-	pio_start = pci_resource_start (pdev, 0);
-	pio_end = pci_resource_end (pdev, 0);
-	pio_flags = pci_resource_flags (pdev, 0);
-	pio_len = pci_resource_len (pdev, 0);
+	pio_start = pci_resource_start(pdev, 0);
+	pio_end = pci_resource_end(pdev, 0);
+	pio_flags = pci_resource_flags(pdev, 0);
+	pio_len = pci_resource_len(pdev, 0);
 
-	mmio_start = pci_resource_start (pdev, 1);
-	mmio_end = pci_resource_end (pdev, 1);
-	mmio_flags = pci_resource_flags (pdev, 1);
-	mmio_len = pci_resource_len (pdev, 1);
+	mmio_start = pci_resource_start(pdev, 1);
+	mmio_end = pci_resource_end(pdev, 1);
+	mmio_flags = pci_resource_flags(pdev, 1);
+	mmio_len = pci_resource_len(pdev, 1);
 
 	/* set this immediately, we need to know before
 	 * we talk to the chip directly */
-	DPRINTK("PIO region size == 0x%02X\n", pio_len);
-	DPRINTK("MMIO region size == 0x%02lX\n", mmio_len);
+	DPRINTK("PIO region size == %#02X\n", pio_len);
+	DPRINTK("MMIO region size == %#02lX\n", mmio_len);
 
 	/* make sure PCI base addr 0 is PIO */
 	if (!(pio_flags & IORESOURCE_IO)) {
@@ -647,17 +669,17 @@ static int __devinit netdrv_init_board (
 		goto err_out;
 	}
 
-	rc = pci_request_regions (pdev, MODNAME);
+	rc = pci_request_regions(pdev, MODNAME);
 	if (rc)
 		goto err_out;
 
-	pci_set_master (pdev);
+	pci_set_master(pdev);
 
 #ifdef USE_IO_OPS
-	ioaddr = (void *) pio_start;
+	ioaddr = (void *)pio_start;
 #else
 	/* ioremap MMIO region */
-	ioaddr = ioremap (mmio_start, mmio_len);
+	ioaddr = ioremap(mmio_start, mmio_len);
 	if (ioaddr == NULL) {
 		dev_err(&pdev->dev, "cannot remap MMIO, aborting\n");
 		rc = -EIO;
@@ -666,52 +688,50 @@ static int __devinit netdrv_init_board (
 #endif /* USE_IO_OPS */
 
 	/* Soft reset the chip. */
-	NETDRV_W8 (ChipCmd, (NETDRV_R8 (ChipCmd) & ChipCmdClear) | CmdReset);
+	NETDRV_W8(ChipCmd, (NETDRV_R8(ChipCmd) & ChipCmdClear) | CmdReset);
 
 	/* Check that the chip has finished the reset. */
 	for (i = 1000; i > 0; i--)
-		if ((NETDRV_R8 (ChipCmd) & CmdReset) == 0)
+		if ((NETDRV_R8(ChipCmd) & CmdReset) == 0)
 			break;
 		else
-			udelay (10);
+			udelay(10);
 
 	/* Bring the chip out of low-power mode. */
 	/* <insert device-specific code here> */
 
 #ifndef USE_IO_OPS
 	/* sanity checks -- ensure PIO and MMIO registers agree */
-	assert (inb (pio_start+Config0) == readb (ioaddr+Config0));
-	assert (inb (pio_start+Config1) == readb (ioaddr+Config1));
-	assert (inb (pio_start+TxConfig) == readb (ioaddr+TxConfig));
-	assert (inb (pio_start+RxConfig) == readb (ioaddr+RxConfig));
+	assert(inb(pio_start+Config0) == readb(ioaddr+Config0));
+	assert(inb(pio_start+Config1) == readb(ioaddr+Config1));
+	assert(inb(pio_start+TxConfig) == readb(ioaddr+TxConfig));
+	assert(inb(pio_start+RxConfig) == readb(ioaddr+RxConfig));
 #endif /* !USE_IO_OPS */
 
 	/* identify chip attached to board */
-	tmp = NETDRV_R8 (ChipVersion);
-	for (i = ARRAY_SIZE (rtl_chip_info) - 1; i >= 0; i--)
+	tmp = NETDRV_R8(ChipVersion);
+	for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--)
 		if (tmp == rtl_chip_info[i].version) {
 			tp->chipset = i;
 			goto match;
 		}
 
 	/* if unknown chip, assume array element #0, original RTL-8139 in this case */
-	dev_printk (KERN_DEBUG, &pdev->dev,
-		"unknown chip version, assuming RTL-8139\n");
-	dev_printk (KERN_DEBUG, &pdev->dev, "TxConfig = 0x%lx\n",
-		NETDRV_R32 (TxConfig));
+	dev_printk(KERN_DEBUG, &pdev->dev,
+		   "unknown chip version, assuming RTL-8139\n");
+	dev_printk(KERN_DEBUG, &pdev->dev, "TxConfig = %#lx\n",
+		   NETDRV_R32(TxConfig));
 	tp->chipset = 0;
 
 match:
-	DPRINTK ("chipset id (%d) == index %d, '%s'\n",
-		tmp,
-		tp->chipset,
-		rtl_chip_info[tp->chipset].name);
+	DPRINTK("chipset id(%d) == index %d, '%s'\n",
+		tmp, tp->chipset, rtl_chip_info[tp->chipset].name);
 
-	rc = register_netdev (dev);
+	rc = register_netdev(dev);
 	if (rc)
 		goto err_out_unmap;
 
-	DPRINTK ("EXIT, returning 0\n");
+	DPRINTK("EXIT, returning 0\n");
 	*ioaddr_out = ioaddr;
 	*dev_out = dev;
 	return 0;
@@ -721,10 +741,10 @@ err_out_unmap:
 	iounmap(ioaddr);
 err_out_free_res:
 #endif
-	pci_release_regions (pdev);
+	pci_release_regions(pdev);
 err_out:
-	free_netdev (dev);
-	DPRINTK ("EXIT, returning %d\n", rc);
+	free_netdev(dev);
+	DPRINTK("EXIT, returning %d\n", rc);
 	return rc;
 }
 
@@ -740,8 +760,8 @@ static const struct net_device_ops netdr
 	.ndo_set_mac_address	= eth_mac_addr,
 };
 
-static int __devinit netdrv_init_one (struct pci_dev *pdev,
-				       const struct pci_device_id *ent)
+static int __devinit netdrv_init_one(struct pci_dev *pdev,
+				     const struct pci_device_id *ent)
 {
 	struct net_device *dev = NULL;
 	struct netdrv_private *tp;
@@ -756,29 +776,29 @@ static int __devinit netdrv_init_one (st
 		printk(version);
 #endif
 
-	DPRINTK ("ENTER\n");
+	DPRINTK("ENTER\n");
 
-	assert (pdev != NULL);
-	assert (ent != NULL);
+	assert(pdev != NULL);
+	assert(ent != NULL);
 
 	board_idx++;
 
-	i = netdrv_init_board (pdev, &dev, &ioaddr);
+	i = netdrv_init_board(pdev, &dev, &ioaddr);
 	if (i < 0) {
-		DPRINTK ("EXIT, returning %d\n", i);
+		DPRINTK("EXIT, returning %d\n", i);
 		return i;
 	}
 
 	tp = netdev_priv(dev);
 
-	assert (ioaddr != NULL);
-	assert (dev != NULL);
-	assert (tp != NULL);
+	assert(ioaddr != NULL);
+	assert(dev != NULL);
+	assert(tp != NULL);
 
-	addr_len = read_eeprom (ioaddr, 0, 8) == 0x8129 ? 8 : 6;
+	addr_len = read_eeprom(ioaddr, 0, 8) == 0x8129 ? 8 : 6;
 	for (i = 0; i < 3; i++)
-		((u16 *) (dev->dev_addr))[i] =
-		    le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len));
+		((u16 *)(dev->dev_addr))[i] =
+			le16_to_cpu(read_eeprom(ioaddr, i + 7, addr_len));
 
 	dev->netdev_ops = &netdrv_netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
@@ -791,7 +811,7 @@ static int __devinit netdrv_init_one (st
 
 	/* note: tp->chipset set in netdrv_init_board */
 	tp->drv_flags = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
-			PCI_COMMAND_MASTER | NETDRV_CAPS;
+		PCI_COMMAND_MASTER | NETDRV_CAPS;
 	tp->pci_dev = pdev;
 	tp->board = ent->driver_data;
 	tp->mmio_addr = ioaddr;
@@ -801,18 +821,15 @@ static int __devinit netdrv_init_one (st
 
 	tp->phys[0] = 32;
 
-	printk (KERN_INFO "%s: %s at 0x%lx, %pM IRQ %d\n",
-		dev->name,
-		board_info[ent->driver_data].name,
-		dev->base_addr,
-		dev->dev_addr,
-		dev->irq);
+	netdev_info(dev, "%s at %#lx, %pM IRQ %d\n",
+		    board_info[ent->driver_data].name,
+		    dev->base_addr, dev->dev_addr, dev->irq);
 
-	printk (KERN_DEBUG "%s:  Identified 8139 chip type '%s'\n",
-		dev->name, rtl_chip_info[tp->chipset].name);
+	netdev_printk(KERN_DEBUG, dev, "Identified 8139 chip type '%s'\n",
+		      rtl_chip_info[tp->chipset].name);
 
 	/* Put the chip into low-power mode. */
-	NETDRV_W8_F (Cfg9346, Cfg9346_Unlock);
+	NETDRV_W8_F(Cfg9346, Cfg9346_Unlock);
 
 	/* The lower four bits are the media type. */
 	option = (board_idx > 7) ? 0 : media[board_idx];
@@ -824,45 +841,43 @@ static int __devinit netdrv_init_one (st
 	}
 
 	if (tp->full_duplex) {
-		printk (KERN_INFO
-			"%s: Media type forced to Full Duplex.\n",
-			dev->name);
-		mdio_write (dev, tp->phys[0], MII_ADVERTISE, ADVERTISE_FULL);
+		netdev_info(dev, "Media type forced to Full Duplex\n");
+		mdio_write(dev, tp->phys[0], MII_ADVERTISE, ADVERTISE_FULL);
 		tp->duplex_lock = 1;
 	}
 
-	DPRINTK ("EXIT - returning 0\n");
+	DPRINTK("EXIT - returning 0\n");
 	return 0;
 }
 
 
-static void __devexit netdrv_remove_one (struct pci_dev *pdev)
+static void __devexit netdrv_remove_one(struct pci_dev *pdev)
 {
-	struct net_device *dev = pci_get_drvdata (pdev);
+	struct net_device *dev = pci_get_drvdata(pdev);
 	struct netdrv_private *np;
 
-	DPRINTK ("ENTER\n");
+	DPRINTK("ENTER\n");
 
-	assert (dev != NULL);
+	assert(dev != NULL);
 
 	np = netdev_priv(dev);
-	assert (np != NULL);
+	assert(np != NULL);
 
-	unregister_netdev (dev);
+	unregister_netdev(dev);
 
 #ifndef USE_IO_OPS
-	iounmap (np->mmio_addr);
+	iounmap(np->mmio_addr);
 #endif /* !USE_IO_OPS */
 
-	pci_release_regions (pdev);
+	pci_release_regions(pdev);
 
-	free_netdev (dev);
+	free_netdev(dev);
 
-	pci_set_drvdata (pdev, NULL);
+	pci_set_drvdata(pdev, NULL);
 
-	pci_disable_device (pdev);
+	pci_disable_device(pdev);
 
-	DPRINTK ("EXIT\n");
+	DPRINTK("EXIT\n");
 }
 
 
@@ -870,63 +885,63 @@ static void __devexit netdrv_remove_one
 
 /*  EEPROM_Ctrl bits. */
 #define EE_SHIFT_CLK	0x04	/* EEPROM shift clock. */
-#define EE_CS			0x08	/* EEPROM chip select. */
+#define EE_CS		0x08	/* EEPROM chip select. */
 #define EE_DATA_WRITE	0x02	/* EEPROM chip data in. */
-#define EE_WRITE_0		0x00
-#define EE_WRITE_1		0x02
+#define EE_WRITE_0	0x00
+#define EE_WRITE_1	0x02
 #define EE_DATA_READ	0x01	/* EEPROM chip data out. */
-#define EE_ENB			(0x80 | EE_CS)
+#define EE_ENB		(0x80 | EE_CS)
 
 /* Delay between EEPROM clock transitions.
    No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
- */
+*/
 
 #define eeprom_delay()	readl(ee_addr)
 
 /* The EEPROM commands include the alway-set leading bit. */
 #define EE_WRITE_CMD	(5)
-#define EE_READ_CMD		(6)
+#define EE_READ_CMD	(6)
 #define EE_ERASE_CMD	(7)
 
-static int __devinit read_eeprom (void *ioaddr, int location, int addr_len)
+static int __devinit read_eeprom(void *ioaddr, int location, int addr_len)
 {
 	int i;
 	unsigned retval = 0;
 	void *ee_addr = ioaddr + Cfg9346;
 	int read_cmd = location | (EE_READ_CMD << addr_len);
 
-	DPRINTK ("ENTER\n");
+	DPRINTK("ENTER\n");
 
-	writeb (EE_ENB & ~EE_CS, ee_addr);
-	writeb (EE_ENB, ee_addr);
-	eeprom_delay ();
+	writeb(EE_ENB & ~EE_CS, ee_addr);
+	writeb(EE_ENB, ee_addr);
+	eeprom_delay();
 
 	/* Shift the read command bits out. */
 	for (i = 4 + addr_len; i >= 0; i--) {
 		int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
-		writeb (EE_ENB | dataval, ee_addr);
-		eeprom_delay ();
-		writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
-		eeprom_delay ();
+		writeb(EE_ENB | dataval, ee_addr);
+		eeprom_delay();
+		writeb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay();
 	}
-	writeb (EE_ENB, ee_addr);
-	eeprom_delay ();
+	writeb(EE_ENB, ee_addr);
+	eeprom_delay();
 
 	for (i = 16; i > 0; i--) {
-		writeb (EE_ENB | EE_SHIFT_CLK, ee_addr);
-		eeprom_delay ();
+		writeb(EE_ENB | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay();
 		retval =
-		    (retval << 1) | ((readb (ee_addr) & EE_DATA_READ) ? 1 :
-				     0);
-		writeb (EE_ENB, ee_addr);
-		eeprom_delay ();
+			(retval << 1) | ((readb(ee_addr) & EE_DATA_READ) ? 1 :
+					0);
+		writeb(EE_ENB, ee_addr);
+		eeprom_delay();
 	}
 
 	/* Terminate the EEPROM access. */
-	writeb (~EE_CS, ee_addr);
-	eeprom_delay ();
+	writeb(~EE_CS, ee_addr);
+	eeprom_delay();
 
-	DPRINTK ("EXIT - returning %d\n", retval);
+	DPRINTK("EXIT - returning %d\n", retval);
 	return retval;
 }
 
@@ -936,12 +951,12 @@ static int __devinit read_eeprom (void *
    The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
    met by back-to-back PCI I/O cycles, but we insert a delay to avoid
    "overclocking" issues. */
-#define MDIO_DIR		0x80
+#define MDIO_DIR	0x80
 #define MDIO_DATA_OUT	0x04
 #define MDIO_DATA_IN	0x02
-#define MDIO_CLK		0x01
-#define MDIO_WRITE0 (MDIO_DIR)
-#define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT)
+#define MDIO_CLK	0x01
+#define MDIO_WRITE0	(MDIO_DIR)
+#define MDIO_WRITE1	(MDIO_DIR | MDIO_DATA_OUT)
 
 #define mdio_delay()	readb(mdio_addr)
 
@@ -959,24 +974,24 @@ static char mii_2_8139_map[8] = {
 
 
 /* Syncronize the MII management interface by shifting 32 one bits out. */
-static void mdio_sync (void *mdio_addr)
+static void mdio_sync(void *mdio_addr)
 {
 	int i;
 
-	DPRINTK ("ENTER\n");
+	DPRINTK("ENTER\n");
 
 	for (i = 32; i >= 0; i--) {
-		writeb (MDIO_WRITE1, mdio_addr);
-		mdio_delay ();
-		writeb (MDIO_WRITE1 | MDIO_CLK, mdio_addr);
-		mdio_delay ();
+		writeb(MDIO_WRITE1, mdio_addr);
+		mdio_delay();
+		writeb(MDIO_WRITE1 | MDIO_CLK, mdio_addr);
+		mdio_delay();
 	}
 
-	DPRINTK ("EXIT\n");
+	DPRINTK("EXIT\n");
 }
 
 
-static int mdio_read (struct net_device *dev, int phy_id, int location)
+static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
 	struct netdrv_private *tp = netdev_priv(dev);
 	void *mdio_addr = tp->mmio_addr + Config4;
@@ -984,97 +999,94 @@ static int mdio_read (struct net_device
 	int retval = 0;
 	int i;
 
-	DPRINTK ("ENTER\n");
+	DPRINTK("ENTER\n");
 
 	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
-		DPRINTK ("EXIT after directly using 8139 internal regs\n");
+		DPRINTK("EXIT after directly using 8139 internal regs\n");
 		return location < 8 && mii_2_8139_map[location] ?
-		    readw (tp->mmio_addr + mii_2_8139_map[location]) : 0;
+			readw(tp->mmio_addr + mii_2_8139_map[location]) : 0;
 	}
-	mdio_sync (mdio_addr);
+	mdio_sync(mdio_addr);
 	/* Shift the read command bits out. */
 	for (i = 15; i >= 0; i--) {
 		int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;
 
-		writeb (MDIO_DIR | dataval, mdio_addr);
-		mdio_delay ();
-		writeb (MDIO_DIR | dataval | MDIO_CLK, mdio_addr);
-		mdio_delay ();
+		writeb(MDIO_DIR | dataval, mdio_addr);
+		mdio_delay();
+		writeb(MDIO_DIR | dataval | MDIO_CLK, mdio_addr);
+		mdio_delay();
 	}
 
 	/* Read the two transition, 16 data, and wire-idle bits. */
 	for (i = 19; i > 0; i--) {
-		writeb (0, mdio_addr);
-		mdio_delay ();
-		retval =
-		    (retval << 1) | ((readb (mdio_addr) & MDIO_DATA_IN) ? 1
-				     : 0);
-		writeb (MDIO_CLK, mdio_addr);
-		mdio_delay ();
+		writeb(0, mdio_addr);
+		mdio_delay();
+		retval = ((retval << 1) | ((readb(mdio_addr) & MDIO_DATA_IN))
+			  ? 1 : 0);
+		writeb(MDIO_CLK, mdio_addr);
+		mdio_delay();
 	}
 
-	DPRINTK ("EXIT, returning %d\n", (retval >> 1) & 0xffff);
+	DPRINTK("EXIT, returning %d\n", (retval >> 1) & 0xffff);
 	return (retval >> 1) & 0xffff;
 }
 
 
-static void mdio_write (struct net_device *dev, int phy_id, int location,
-			int value)
+static void mdio_write(struct net_device *dev, int phy_id, int location,
+		       int value)
 {
 	struct netdrv_private *tp = netdev_priv(dev);
 	void *mdio_addr = tp->mmio_addr + Config4;
 	int mii_cmd =
-	    (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
+		(0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
 	int i;
 
-	DPRINTK ("ENTER\n");
+	DPRINTK("ENTER\n");
 
 	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
 		if (location < 8 && mii_2_8139_map[location]) {
-			writew (value,
-				tp->mmio_addr + mii_2_8139_map[location]);
-			readw (tp->mmio_addr + mii_2_8139_map[location]);
+			writew(value,
+			       tp->mmio_addr + mii_2_8139_map[location]);
+			readw(tp->mmio_addr + mii_2_8139_map[location]);
 		}
-		DPRINTK ("EXIT after directly using 8139 internal regs\n");
+		DPRINTK("EXIT after directly using 8139 internal regs\n");
 		return;
 	}
-	mdio_sync (mdio_addr);
+	mdio_sync(mdio_addr);
 
 	/* Shift the command bits out. */
 	for (i = 31; i >= 0; i--) {
 		int dataval =
-		    (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
-		writeb (dataval, mdio_addr);
-		mdio_delay ();
-		writeb (dataval | MDIO_CLK, mdio_addr);
-		mdio_delay ();
+			(mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
+		writeb(dataval, mdio_addr);
+		mdio_delay();
+		writeb(dataval | MDIO_CLK, mdio_addr);
+		mdio_delay();
 	}
 
 	/* Clear out extra bits. */
 	for (i = 2; i > 0; i--) {
-		writeb (0, mdio_addr);
-		mdio_delay ();
-		writeb (MDIO_CLK, mdio_addr);
-		mdio_delay ();
+		writeb(0, mdio_addr);
+		mdio_delay();
+		writeb(MDIO_CLK, mdio_addr);
+		mdio_delay();
 	}
 
-	DPRINTK ("EXIT\n");
+	DPRINTK("EXIT\n");
 }
 
 
-static int netdrv_open (struct net_device *dev)
+static int netdrv_open(struct net_device *dev)
 {
 	struct netdrv_private *tp = netdev_priv(dev);
 	int retval;
-#ifdef NETDRV_DEBUG
 	void *ioaddr = tp->mmio_addr;
-#endif
 
-	DPRINTK ("ENTER\n");
+	DPRINTK("ENTER\n");
 
-	retval = request_irq (dev->irq, netdrv_interrupt, IRQF_SHARED, dev->name, dev);
+	retval = request_irq(dev->irq, netdrv_interrupt, IRQF_SHARED, dev->name, dev);
 	if (retval) {
-		DPRINTK ("EXIT, returning %d\n", retval);
+		DPRINTK("EXIT, returning %d\n", retval);
 		return retval;
 	}
 
@@ -1092,7 +1104,7 @@ static int netdrv_open (struct net_devic
 			pci_free_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
 					    tp->rx_ring, tp->rx_ring_dma);
 
-		DPRINTK ("EXIT, returning -ENOMEM\n");
+		DPRINTK("EXIT, returning -ENOMEM\n");
 		return -ENOMEM;
 
 	}
@@ -1100,109 +1112,108 @@ static int netdrv_open (struct net_devic
 	tp->full_duplex = tp->duplex_lock;
 	tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000;
 
-	netdrv_init_ring (dev);
-	netdrv_hw_start (dev);
+	netdrv_init_ring(dev);
+	netdrv_hw_start(dev);
 
-	DPRINTK ("%s: netdrv_open() ioaddr %#lx IRQ %d"
-			" GP Pins %2.2x %s-duplex.\n",
-			dev->name, pci_resource_start (tp->pci_dev, 1),
-			dev->irq, NETDRV_R8 (MediaStatus),
-			tp->full_duplex ? "full" : "half");
+	netdev_dbg(dev, "ioaddr %#llx IRQ %d GP Pins %02x %s-duplex\n",
+		   (unsigned long long)pci_resource_start(tp->pci_dev, 1),
+		   dev->irq, NETDRV_R8(MediaStatus),
+		   tp->full_duplex ? "full" : "half");
 
 	/* Set the timer to switch to check for link beat and perhaps switch
 	   to an alternate media type. */
-	init_timer (&tp->timer);
+	init_timer(&tp->timer);
 	tp->timer.expires = jiffies + 3 * HZ;
 	tp->timer.data = (unsigned long) dev;
 	tp->timer.function = &netdrv_timer;
-	add_timer (&tp->timer);
+	add_timer(&tp->timer);
 
-	DPRINTK ("EXIT, returning 0\n");
+	DPRINTK("EXIT, returning 0\n");
 	return 0;
 }
 
 
 /* Start the hardware at open or resume. */
-static void netdrv_hw_start (struct net_device *dev)
+static void netdrv_hw_start(struct net_device *dev)
 {
 	struct netdrv_private *tp = netdev_priv(dev);
 	void *ioaddr = tp->mmio_addr;
 	u32 i;
 
-	DPRINTK ("ENTER\n");
+	DPRINTK("ENTER\n");
 
 	/* Soft reset the chip. */
-	NETDRV_W8 (ChipCmd, (NETDRV_R8 (ChipCmd) & ChipCmdClear) | CmdReset);
-	udelay (100);
+	NETDRV_W8(ChipCmd, (NETDRV_R8(ChipCmd) & ChipCmdClear) | CmdReset);
+	udelay(100);
 
 	/* Check that the chip has finished the reset. */
 	for (i = 1000; i > 0; i--)
-		if ((NETDRV_R8 (ChipCmd) & CmdReset) == 0)
+		if ((NETDRV_R8(ChipCmd) & CmdReset) == 0)
 			break;
 
 	/* Restore our idea of the MAC address. */
-	NETDRV_W32_F (MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
-	NETDRV_W32_F (MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
+	NETDRV_W32_F(MAC0 + 0, cpu_to_le32(*(u32 *)(dev->dev_addr + 0)));
+	NETDRV_W32_F(MAC0 + 4, cpu_to_le32(*(u32 *)(dev->dev_addr + 4)));
 
 	/* Must enable Tx/Rx before setting transfer thresholds! */
-	NETDRV_W8_F (ChipCmd, (NETDRV_R8 (ChipCmd) & ChipCmdClear) |
-			   CmdRxEnb | CmdTxEnb);
+	NETDRV_W8_F(ChipCmd, (NETDRV_R8(ChipCmd) & ChipCmdClear) |
+		    CmdRxEnb | CmdTxEnb);
 
 	i = netdrv_rx_config |
-	    (NETDRV_R32 (RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
-	NETDRV_W32_F (RxConfig, i);
+		(NETDRV_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
+	NETDRV_W32_F(RxConfig, i);
 
 	/* Check this value: the documentation for IFG contradicts ifself. */
-	NETDRV_W32 (TxConfig, (TX_DMA_BURST << TxDMAShift));
+	NETDRV_W32(TxConfig, (TX_DMA_BURST << TxDMAShift));
 
 	/* unlock Config[01234] and BMCR register writes */
-	NETDRV_W8_F (Cfg9346, Cfg9346_Unlock);
-	udelay (10);
+	NETDRV_W8_F(Cfg9346, Cfg9346_Unlock);
+	udelay(10);
 
 	tp->cur_rx = 0;
 
 	/* Lock Config[01234] and BMCR register writes */
-	NETDRV_W8_F (Cfg9346, Cfg9346_Lock);
-	udelay (10);
+	NETDRV_W8_F(Cfg9346, Cfg9346_Lock);
+	udelay(10);
 
 	/* init Rx ring buffer DMA address */
-	NETDRV_W32_F (RxBuf, tp->rx_ring_dma);
+	NETDRV_W32_F(RxBuf, tp->rx_ring_dma);
 
 	/* init Tx buffer DMA addresses */
 	for (i = 0; i < NUM_TX_DESC; i++)
-		NETDRV_W32_F (TxAddr0 + (i * 4), tp->tx_bufs_dma + (tp->tx_buf[i] - tp->tx_bufs));
+		NETDRV_W32_F(TxAddr0 + (i * 4), tp->tx_bufs_dma + (tp->tx_buf[i] - tp->tx_bufs));
 
-	NETDRV_W32_F (RxMissed, 0);
+	NETDRV_W32_F(RxMissed, 0);
 
-	netdrv_set_rx_mode (dev);
+	netdrv_set_rx_mode(dev);
 
 	/* no early-rx interrupts */
-	NETDRV_W16 (MultiIntr, NETDRV_R16 (MultiIntr) & MultiIntrClear);
+	NETDRV_W16(MultiIntr, NETDRV_R16(MultiIntr) & MultiIntrClear);
 
 	/* make sure RxTx has started */
-	NETDRV_W8_F (ChipCmd, (NETDRV_R8 (ChipCmd) & ChipCmdClear) |
-			   CmdRxEnb | CmdTxEnb);
+	NETDRV_W8_F(ChipCmd, (NETDRV_R8(ChipCmd) & ChipCmdClear) |
+		    CmdRxEnb | CmdTxEnb);
 
 	/* Enable all known interrupts by setting the interrupt mask. */
-	NETDRV_W16_F (IntrMask, netdrv_intr_mask);
+	NETDRV_W16_F(IntrMask, netdrv_intr_mask);
 
-	netif_start_queue (dev);
+	netif_start_queue(dev);
 
-	DPRINTK ("EXIT\n");
+	DPRINTK("EXIT\n");
 }
 
 
 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
-static void netdrv_init_ring (struct net_device *dev)
+static void netdrv_init_ring(struct net_device *dev)
 {
 	struct netdrv_private *tp = netdev_priv(dev);
 	int i;
 
-	DPRINTK ("ENTER\n");
+	DPRINTK("ENTER\n");
 
 	tp->cur_rx = 0;
-	atomic_set (&tp->cur_tx, 0);
-	atomic_set (&tp->dirty_tx, 0);
+	atomic_set(&tp->cur_tx, 0);
+	atomic_set(&tp->dirty_tx, 0);
 
 	for (i = 0; i < NUM_TX_DESC; i++) {
 		tp->tx_info[i].skb = NULL;
@@ -1210,11 +1221,11 @@ static void netdrv_init_ring (struct net
 		tp->tx_buf[i] = &tp->tx_bufs[i * TX_BUF_SIZE];
 	}
 
-	DPRINTK ("EXIT\n");
+	DPRINTK("EXIT\n");
 }
 
 
-static void netdrv_timer (unsigned long data)
+static void netdrv_timer(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *) data;
 	struct netdrv_private *tp = netdev_priv(dev);
@@ -1222,58 +1233,54 @@ static void netdrv_timer (unsigned long
 	int next_tick = 60 * HZ;
 	int mii_lpa;
 
-	mii_lpa = mdio_read (dev, tp->phys[0], MII_LPA);
+	mii_lpa = mdio_read(dev, tp->phys[0], MII_LPA);
 
 	if (!tp->duplex_lock && mii_lpa != 0xffff) {
 		int duplex = ((mii_lpa & LPA_100FULL) ||
-			      (mii_lpa & 0x01C0) == 0x0040);
+			     (mii_lpa & 0x01C0) == 0x0040);
 		if (tp->full_duplex != duplex) {
 			tp->full_duplex = duplex;
-			printk (KERN_INFO
-				"%s: Setting %s-duplex based on MII #%d link"
-				" partner ability of %4.4x.\n", dev->name,
-				tp->full_duplex ? "full" : "half",
-				tp->phys[0], mii_lpa);
-			NETDRV_W8 (Cfg9346, Cfg9346_Unlock);
-			NETDRV_W8 (Config1, tp->full_duplex ? 0x60 : 0x20);
-			NETDRV_W8 (Cfg9346, Cfg9346_Lock);
+			netdev_info(dev, "Setting %s-duplex based on MII #%d link partner ability of %04x\n",
+				    tp->full_duplex ? "full" : "half",
+				    tp->phys[0], mii_lpa);
+			NETDRV_W8(Cfg9346, Cfg9346_Unlock);
+			NETDRV_W8(Config1, tp->full_duplex ? 0x60 : 0x20);
+			NETDRV_W8(Cfg9346, Cfg9346_Lock);
 		}
 	}
 
-	DPRINTK ("%s: Media selection tick, Link partner %4.4x.\n",
-		 dev->name, NETDRV_R16 (NWayLPAR));
-	DPRINTK ("%s:  Other registers are IntMask %4.4x IntStatus %4.4x"
-		 " RxStatus %4.4x.\n", dev->name,
-		 NETDRV_R16 (IntrMask),
-		 NETDRV_R16 (IntrStatus),
-		 NETDRV_R32 (RxEarlyStatus));
-	DPRINTK ("%s:  Chip config %2.2x %2.2x.\n",
-		 dev->name, NETDRV_R8 (Config0),
-		 NETDRV_R8 (Config1));
+	netdev_dbg(dev, "Media selection tick, Link partner %04x\n",
+		   NETDRV_R16(NWayLPAR));
+	netdev_dbg(dev, "Other registers are IntMask %04x IntStatus %04x RxStatus %04lx\n",
+		   NETDRV_R16(IntrMask),
+		   NETDRV_R16(IntrStatus),
+		   NETDRV_R32(RxEarlyStatus));
+	netdev_dbg(dev, "Chip config %02x %02x\n",
+		   NETDRV_R8(Config0), NETDRV_R8(Config1));
 
 	tp->timer.expires = jiffies + next_tick;
-	add_timer (&tp->timer);
+	add_timer(&tp->timer);
 }
 
 
-static void netdrv_tx_clear (struct net_device *dev)
+static void netdrv_tx_clear(struct net_device *dev)
 {
 	int i;
 	struct netdrv_private *tp = netdev_priv(dev);
 
-	atomic_set (&tp->cur_tx, 0);
-	atomic_set (&tp->dirty_tx, 0);
+	atomic_set(&tp->cur_tx, 0);
+	atomic_set(&tp->dirty_tx, 0);
 
 	/* Dump the unsent Tx packets. */
 	for (i = 0; i < NUM_TX_DESC; i++) {
 		struct ring_info *rp = &tp->tx_info[i];
 		if (rp->mapping != 0) {
-			pci_unmap_single (tp->pci_dev, rp->mapping,
-					  rp->skb->len, PCI_DMA_TODEVICE);
+			pci_unmap_single(tp->pci_dev, rp->mapping,
+					 rp->skb->len, PCI_DMA_TODEVICE);
 			rp->mapping = 0;
 		}
 		if (rp->skb) {
-			dev_kfree_skb (rp->skb);
+			dev_kfree_skb(rp->skb);
 			rp->skb = NULL;
 			dev->stats.tx_dropped++;
 		}
@@ -1281,7 +1288,7 @@ static void netdrv_tx_clear (struct net_
 }
 
 
-static void netdrv_tx_timeout (struct net_device *dev)
+static void netdrv_tx_timeout(struct net_device *dev)
 {
 	struct netdrv_private *tp = netdev_priv(dev);
 	void *ioaddr = tp->mmio_addr;
@@ -1289,96 +1296,95 @@ static void netdrv_tx_timeout (struct ne
 	u8 tmp8;
 	unsigned long flags;
 
-	DPRINTK ("%s: Transmit timeout, status %2.2x %4.4x "
-		 "media %2.2x.\n", dev->name,
-		 NETDRV_R8 (ChipCmd),
-		 NETDRV_R16 (IntrStatus),
-		 NETDRV_R8 (MediaStatus));
+	netdev_dbg(dev, "Transmit timeout, status %02x %04x media %02x\n",
+		   NETDRV_R8(ChipCmd),
+		   NETDRV_R16(IntrStatus),
+		   NETDRV_R8(MediaStatus));
 
 	/* disable Tx ASAP, if not already */
-	tmp8 = NETDRV_R8 (ChipCmd);
+	tmp8 = NETDRV_R8(ChipCmd);
 	if (tmp8 & CmdTxEnb)
-		NETDRV_W8 (ChipCmd, tmp8 & ~CmdTxEnb);
+		NETDRV_W8(ChipCmd, tmp8 & ~CmdTxEnb);
 
 	/* Disable interrupts by clearing the interrupt mask. */
-	NETDRV_W16 (IntrMask, 0x0000);
+	NETDRV_W16(IntrMask, 0x0000);
 
 	/* Emit info to figure out what went wrong. */
-	printk (KERN_DEBUG "%s: Tx queue start entry %d  dirty entry %d.\n",
-		dev->name, atomic_read (&tp->cur_tx),
-		atomic_read (&tp->dirty_tx));
+	netdev_dbg(dev, "Tx queue start entry %d dirty entry %d\n",
+		   atomic_read(&tp->cur_tx),
+		   atomic_read(&tp->dirty_tx));
 	for (i = 0; i < NUM_TX_DESC; i++)
-		printk (KERN_DEBUG "%s:  Tx descriptor %d is %8.8lx.%s\n",
-			dev->name, i, NETDRV_R32 (TxStatus0 + (i * 4)),
-			i == atomic_read (&tp->dirty_tx) % NUM_TX_DESC ?
-				" (queue head)" : "");
+		netdev_dbg(dev, "Tx descriptor %d is %08lx%s\n",
+			   i, NETDRV_R32(TxStatus0 + (i * 4)),
+			   i == atomic_read(&tp->dirty_tx) % NUM_TX_DESC ?
+			   "(queue head)" : "");
 
 	/* Stop a shared interrupt from scavenging while we are. */
-	spin_lock_irqsave (&tp->lock, flags);
+	spin_lock_irqsave(&tp->lock, flags);
 
-	netdrv_tx_clear (dev);
+	netdrv_tx_clear(dev);
 
-	spin_unlock_irqrestore (&tp->lock, flags);
+	spin_unlock_irqrestore(&tp->lock, flags);
 
 	/* ...and finally, reset everything */
-	netdrv_hw_start (dev);
+	netdrv_hw_start(dev);
 
-	netif_wake_queue (dev);
+	netif_wake_queue(dev);
 }
 
 
 
-static int netdrv_start_xmit (struct sk_buff *skb, struct net_device *dev)
+static int netdrv_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct netdrv_private *tp = netdev_priv(dev);
 	void *ioaddr = tp->mmio_addr;
 	int entry;
 
 	/* Calculate the next Tx descriptor entry. */
-	entry = atomic_read (&tp->cur_tx) % NUM_TX_DESC;
+	entry = atomic_read(&tp->cur_tx) % NUM_TX_DESC;
 
-	assert (tp->tx_info[entry].skb == NULL);
-	assert (tp->tx_info[entry].mapping == 0);
+	assert(tp->tx_info[entry].skb == NULL);
+	assert(tp->tx_info[entry].mapping == 0);
 
 	tp->tx_info[entry].skb = skb;
 	/* tp->tx_info[entry].mapping = 0; */
 	skb_copy_from_linear_data(skb, tp->tx_buf[entry], skb->len);
 
 	/* Note: the chip doesn't have auto-pad! */
-	NETDRV_W32 (TxStatus0 + (entry * sizeof(u32)),
-		 tp->tx_flag | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
+	NETDRV_W32(TxStatus0 + (entry * sizeof(u32)),
+		   tp->tx_flag | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
 
 	dev->trans_start = jiffies;
-	atomic_inc (&tp->cur_tx);
-	if ((atomic_read (&tp->cur_tx) - atomic_read (&tp->dirty_tx)) >= NUM_TX_DESC)
-		netif_stop_queue (dev);
+	atomic_inc(&tp->cur_tx);
+	if ((atomic_read(&tp->cur_tx) - atomic_read(&tp->dirty_tx)) >= NUM_TX_DESC)
+		netif_stop_queue(dev);
 
-	DPRINTK ("%s: Queued Tx packet at %p size %u to slot %d.\n",
-		 dev->name, skb->data, skb->len, entry);
+	netdev_dbg(dev, "Queued Tx packet at %p size %u to slot %d\n",
+		   skb->data, skb->len, entry);
 
 	return NETDEV_TX_OK;
 }
 
 
-static void netdrv_tx_interrupt (struct net_device *dev,
-				  struct netdrv_private *tp,
-				  void *ioaddr)
+static void netdrv_tx_interrupt(struct net_device *dev,
+				struct netdrv_private *tp,
+				void *ioaddr)
 {
 	int cur_tx, dirty_tx, tx_left;
 
-	assert (dev != NULL);
-	assert (tp != NULL);
-	assert (ioaddr != NULL);
+	assert(dev != NULL);
+	assert(tp != NULL);
+	assert(ioaddr != NULL);
 
-	dirty_tx = atomic_read (&tp->dirty_tx);
+	dirty_tx = atomic_read(&tp->dirty_tx);
 
-	cur_tx = atomic_read (&tp->cur_tx);
+	cur_tx = atomic_read(&tp->cur_tx);
 	tx_left = cur_tx - dirty_tx;
 	while (tx_left > 0) {
 		int entry = dirty_tx % NUM_TX_DESC;
 		int txstatus;
 
-		txstatus = NETDRV_R32 (TxStatus0 + (entry * sizeof (u32)));
+		txstatus = NETDRV_R32(TxStatus0 + (entry * sizeof(u32)));
 
 		if (!(txstatus & (TxStatOK | TxUnderrun | TxAborted)))
 			break;	/* It still hasn't been Txed */
@@ -1386,12 +1392,12 @@ static void netdrv_tx_interrupt (struct
 		/* Note: TxCarrierLost is always asserted at 100mbps. */
 		if (txstatus & (TxOutOfWindow | TxAborted)) {
 			/* There was an major error, log it. */
-			DPRINTK ("%s: Transmit error, Tx status %8.8x.\n",
-				 dev->name, txstatus);
+			netdev_dbg(dev, "Transmit error, Tx status %#08x\n",
+				   txstatus);
 			dev->stats.tx_errors++;
 			if (txstatus & TxAborted) {
 				dev->stats.tx_aborted_errors++;
-				NETDRV_W32 (TxConfig, TxClearAbt | (TX_DMA_BURST << TxDMAShift));
+				NETDRV_W32(TxConfig, TxClearAbt | (TX_DMA_BURST << TxDMAShift));
 			}
 			if (txstatus & TxCarrierLost)
 				dev->stats.tx_carrier_errors++;
@@ -1417,48 +1423,45 @@ static void netdrv_tx_interrupt (struct
 					 PCI_DMA_TODEVICE);
 			tp->tx_info[entry].mapping = 0;
 		}
-		dev_kfree_skb_irq (tp->tx_info[entry].skb);
+		dev_kfree_skb_irq(tp->tx_info[entry].skb);
 		tp->tx_info[entry].skb = NULL;
 		dirty_tx++;
 		if (dirty_tx < 0) { /* handle signed int overflow */
-			atomic_sub (cur_tx, &tp->cur_tx); /* XXX racy? */
+			atomic_sub(cur_tx, &tp->cur_tx); /* XXX racy? */
 			dirty_tx = cur_tx - tx_left + 1;
 		}
-		if (netif_queue_stopped (dev))
-			netif_wake_queue (dev);
+		if (netif_queue_stopped(dev))
+			netif_wake_queue(dev);
 
-		cur_tx = atomic_read (&tp->cur_tx);
+		cur_tx = atomic_read(&tp->cur_tx);
 		tx_left = cur_tx - dirty_tx;
 
 	}
 
 #ifndef NETDRV_NDEBUG
-	if (atomic_read (&tp->cur_tx) - dirty_tx > NUM_TX_DESC) {
-		printk (KERN_ERR
-		  "%s: Out-of-sync dirty pointer, %d vs. %d.\n",
-		     dev->name, dirty_tx, atomic_read (&tp->cur_tx));
+	if (atomic_read(&tp->cur_tx) - dirty_tx > NUM_TX_DESC) {
+		netdev_err(dev, "Out-of-sync dirty pointer, %d vs. %d\n",
+			   dirty_tx, atomic_read(&tp->cur_tx));
 		dirty_tx += NUM_TX_DESC;
 	}
 #endif /* NETDRV_NDEBUG */
 
-	atomic_set (&tp->dirty_tx, dirty_tx);
+	atomic_set(&tp->dirty_tx, dirty_tx);
 }
 
 
 /* TODO: clean this up!  Rx reset need not be this intensive */
-static void netdrv_rx_err (u32 rx_status, struct net_device *dev,
-			    struct netdrv_private *tp, void *ioaddr)
+static void netdrv_rx_err(u32 rx_status, struct net_device *dev,
+			  struct netdrv_private *tp, void *ioaddr)
 {
 	u8 tmp8;
 	int tmp_work = 1000;
 
-	DPRINTK ("%s: Ethernet frame had errors, status %8.8x.\n",
-	         dev->name, rx_status);
-	if (rx_status & RxTooLong) {
-		DPRINTK ("%s: Oversized Ethernet frame, status %4.4x!\n",
-			 dev->name, rx_status);
+	netdev_dbg(dev, "Ethernet frame had errors, status %08x\n", rx_status);
+	if (rx_status & RxTooLong)
+		netdev_dbg(dev, "Oversized Ethernet frame, status %04x!\n",
+			   rx_status);
 		/* A.C.: The chip hangs here. */
-	}
 	dev->stats.rx_errors++;
 	if (rx_status & (RxBadSymbol | RxBadAlign))
 		dev->stats.rx_frame_errors++;
@@ -1466,56 +1469,55 @@ static void netdrv_rx_err (u32 rx_status
 		dev->stats.rx_length_errors++;
 	if (rx_status & RxCRCErr)
 		dev->stats.rx_crc_errors++;
-	/* Reset the receiver, based on RealTek recommendation. (Bug?) */
+	/* Reset the receiver, based on RealTek recommendation.(Bug?) */
 	tp->cur_rx = 0;
 
 	/* disable receive */
-	tmp8 = NETDRV_R8 (ChipCmd) & ChipCmdClear;
-	NETDRV_W8_F (ChipCmd, tmp8 | CmdTxEnb);
+	tmp8 = NETDRV_R8(ChipCmd) & ChipCmdClear;
+	NETDRV_W8_F(ChipCmd, tmp8 | CmdTxEnb);
 
 	/* A.C.: Reset the multicast list. */
-	netdrv_set_rx_mode (dev);
+	netdrv_set_rx_mode(dev);
 
 	/* XXX potentially temporary hack to
 	 * restart hung receiver */
 	while (--tmp_work > 0) {
-		tmp8 = NETDRV_R8 (ChipCmd);
+		tmp8 = NETDRV_R8(ChipCmd);
 		if ((tmp8 & CmdRxEnb) && (tmp8 & CmdTxEnb))
 			break;
-		NETDRV_W8_F (ChipCmd,
-			  (tmp8 & ChipCmdClear) | CmdRxEnb | CmdTxEnb);
+		NETDRV_W8_F(ChipCmd,
+			    (tmp8 & ChipCmdClear) | CmdRxEnb | CmdTxEnb);
 	}
 
 	/* G.S.: Re-enable receiver */
 	/* XXX temporary hack to work around receiver hang */
-	netdrv_set_rx_mode (dev);
+	netdrv_set_rx_mode(dev);
 
 	if (tmp_work <= 0)
-		printk (KERN_WARNING PFX "tx/rx enable wait too long\n");
+		netdev_warn(dev, "tx/rx enable wait too long\n");
 }
 
 
 /* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the
    field alignments and semantics. */
-static void netdrv_rx_interrupt (struct net_device *dev,
-				  struct netdrv_private *tp, void *ioaddr)
+static void netdrv_rx_interrupt(struct net_device *dev,
+				struct netdrv_private *tp, void *ioaddr)
 {
 	unsigned char *rx_ring;
 	u16 cur_rx;
 
-	assert (dev != NULL);
-	assert (tp != NULL);
-	assert (ioaddr != NULL);
+	assert(dev != NULL);
+	assert(tp != NULL);
+	assert(ioaddr != NULL);
 
 	rx_ring = tp->rx_ring;
 	cur_rx = tp->cur_rx;
 
-	DPRINTK ("%s: In netdrv_rx(), current %4.4x BufAddr %4.4x,"
-		 " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
-		 NETDRV_R16 (RxBufAddr),
-		 NETDRV_R16 (RxBufPtr), NETDRV_R8 (ChipCmd));
+	netdev_dbg(dev, "In netdrv_rx(), current %04x BufAddr %04x, free to %04x, Cmd %02x\n",
+		   cur_rx, NETDRV_R16(RxBufAddr),
+		   NETDRV_R16(RxBufPtr), NETDRV_R8(ChipCmd));
 
-	while ((NETDRV_R8 (ChipCmd) & RxBufEmpty) == 0) {
+	while ((NETDRV_R8(ChipCmd) & RxBufEmpty) == 0) {
 		int ring_offset = cur_rx % RX_BUF_LEN;
 		u32 rx_status;
 		unsigned int rx_size;
@@ -1523,32 +1525,25 @@ static void netdrv_rx_interrupt (struct
 		struct sk_buff *skb;
 
 		/* read size+status of next frame from DMA ring buffer */
-		rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset));
+		rx_status = le32_to_cpu(*(u32 *)(rx_ring + ring_offset));
 		rx_size = rx_status >> 16;
 		pkt_size = rx_size - 4;
 
-		DPRINTK ("%s:  netdrv_rx() status %4.4x, size %4.4x,"
-			 " cur %4.4x.\n", dev->name, rx_status,
-			 rx_size, cur_rx);
+		netdev_dbg(dev, "netdrv_rx() status %04x, size %04x, cur %04x\n",
+			   rx_status, rx_size, cur_rx);
 #if defined(NETDRV_DEBUG) && (NETDRV_DEBUG > 2)
-		{
-			int i;
-			DPRINTK ("%s: Frame contents ", dev->name);
-			for (i = 0; i < 70; i++)
-				printk (" %2.2x",
-					rx_ring[ring_offset + i]);
-			printk (".\n");
-		}
+		print_hex_dump_bytes("Frame contents: ", HEX_DUMP_OFFSET,
+				     &rx_ring[ring_offset], 70);
 #endif
 
 		/* If Rx err or invalid rx_size/rx_status received
-		 * (which happens if we get lost in the ring),
+		 *(which happens if we get lost in the ring),
 		 * Rx process gets reset, so we abort any further
 		 * Rx processing.
 		 */
 		if ((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
 		    (!(rx_status & RxStatusOK))) {
-			netdrv_rx_err (rx_status, dev, tp, ioaddr);
+			netdrv_rx_err(rx_status, dev, tp, ioaddr);
 			return;
 		}
 
@@ -1561,71 +1556,67 @@ static void netdrv_rx_interrupt (struct
 		 * drop packets here under memory pressure.
 		 */
 
-		skb = dev_alloc_skb (pkt_size + 2);
+		skb = dev_alloc_skb(pkt_size + 2);
 		if (skb) {
-			skb_reserve (skb, 2);	/* 16 byte align the IP fields. */
+			skb_reserve(skb, 2);	/* 16 byte align the IP fields. */
 
-			skb_copy_to_linear_data (skb, &rx_ring[ring_offset + 4], pkt_size);
-			skb_put (skb, pkt_size);
+			skb_copy_to_linear_data(skb, &rx_ring[ring_offset + 4], pkt_size);
+			skb_put(skb, pkt_size);
 
-			skb->protocol = eth_type_trans (skb, dev);
-			netif_rx (skb);
+			skb->protocol = eth_type_trans(skb, dev);
+			netif_rx(skb);
 			dev->stats.rx_bytes += pkt_size;
 			dev->stats.rx_packets++;
 		} else {
-			printk (KERN_WARNING
-				"%s: Memory squeeze, dropping packet.\n",
-				dev->name);
+			netdev_warn(dev, "Memory squeeze, dropping packet\n");
 			dev->stats.rx_dropped++;
 		}
 
 		cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
-		NETDRV_W16_F (RxBufPtr, cur_rx - 16);
+		NETDRV_W16_F(RxBufPtr, cur_rx - 16);
 	}
 
-	DPRINTK ("%s: Done netdrv_rx(), current %4.4x BufAddr %4.4x,"
-		 " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
-		 NETDRV_R16 (RxBufAddr),
-		 NETDRV_R16 (RxBufPtr), NETDRV_R8 (ChipCmd));
+	netdev_dbg(dev, "Done netdrv_rx(), current %04x BufAddr %04x, free to %04x, Cmd %02x\n",
+		   cur_rx, NETDRV_R16(RxBufAddr),
+		   NETDRV_R16(RxBufPtr), NETDRV_R8(ChipCmd));
 
 	tp->cur_rx = cur_rx;
 }
 
 
-static void netdrv_weird_interrupt (struct net_device *dev,
-				     struct netdrv_private *tp,
-				     void *ioaddr,
-				     int status, int link_changed)
+static void netdrv_weird_interrupt(struct net_device *dev,
+				   struct netdrv_private *tp,
+				   void *ioaddr,
+				   int status, int link_changed)
 {
-	printk (KERN_DEBUG "%s: Abnormal interrupt, status %8.8x.\n",
-		dev->name, status);
+	netdev_printk(KERN_DEBUG, dev, "Abnormal interrupt, status %08x\n",
+		      status);
 
-	assert (dev != NULL);
-	assert (tp != NULL);
-	assert (ioaddr != NULL);
+	assert(dev != NULL);
+	assert(tp != NULL);
+	assert(ioaddr != NULL);
 
 	/* Update the error count. */
-	dev->stats.rx_missed_errors += NETDRV_R32 (RxMissed);
-	NETDRV_W32 (RxMissed, 0);
+	dev->stats.rx_missed_errors += NETDRV_R32(RxMissed);
+	NETDRV_W32(RxMissed, 0);
 
 	if ((status & RxUnderrun) && link_changed &&
 	    (tp->drv_flags & HAS_LNK_CHNG)) {
 		/* Really link-change on new chips. */
-		int lpar = NETDRV_R16 (NWayLPAR);
+		int lpar = NETDRV_R16(NWayLPAR);
 		int duplex = ((lpar & 0x0100) || (lpar & 0x01C0) == 0x0040 ||
-			      tp->duplex_lock);
+			     tp->duplex_lock);
 		if (tp->full_duplex != duplex) {
 			tp->full_duplex = duplex;
-			NETDRV_W8 (Cfg9346, Cfg9346_Unlock);
-			NETDRV_W8 (Config1, tp->full_duplex ? 0x60 : 0x20);
-			NETDRV_W8 (Cfg9346, Cfg9346_Lock);
+			NETDRV_W8(Cfg9346, Cfg9346_Unlock);
+			NETDRV_W8(Config1, tp->full_duplex ? 0x60 : 0x20);
+			NETDRV_W8(Cfg9346, Cfg9346_Lock);
 		}
 		status &= ~RxUnderrun;
 	}
 
 	/* XXX along with netdrv_rx_err, are we double-counting errors? */
-	if (status &
-	    (RxUnderrun | RxOverflow | RxErr | RxFIFOOver))
+	if (status & (RxUnderrun | RxOverflow | RxErr | RxFIFOOver))
 		dev->stats.rx_errors++;
 
 	if (status & (PCSTimeout))
@@ -1634,22 +1625,21 @@ static void netdrv_weird_interrupt (stru
 		dev->stats.rx_fifo_errors++;
 	if (status & RxOverflow) {
 		dev->stats.rx_over_errors++;
-		tp->cur_rx = NETDRV_R16 (RxBufAddr) % RX_BUF_LEN;
-		NETDRV_W16_F (RxBufPtr, tp->cur_rx - 16);
+		tp->cur_rx = NETDRV_R16(RxBufAddr) % RX_BUF_LEN;
+		NETDRV_W16_F(RxBufPtr, tp->cur_rx - 16);
 	}
 	if (status & PCIErr) {
 		u16 pci_cmd_status;
-		pci_read_config_word (tp->pci_dev, PCI_STATUS, &pci_cmd_status);
+		pci_read_config_word(tp->pci_dev, PCI_STATUS, &pci_cmd_status);
 
-		printk (KERN_ERR "%s: PCI Bus error %4.4x.\n",
-			dev->name, pci_cmd_status);
+		netdev_err(dev, "PCI Bus error %04x\n", pci_cmd_status);
 	}
 }
 
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static irqreturn_t netdrv_interrupt (int irq, void *dev_instance)
+static irqreturn_t netdrv_interrupt(int irq, void *dev_instance)
 {
 	struct net_device *dev = (struct net_device *) dev_instance;
 	struct netdrv_private *tp = netdev_priv(dev);
@@ -1658,22 +1648,21 @@ static irqreturn_t netdrv_interrupt (int
 	int status = 0, link_changed = 0; /* avoid bogus "uninit" warning */
 	int handled = 0;
 
-	spin_lock (&tp->lock);
+	spin_lock(&tp->lock);
 
 	do {
-		status = NETDRV_R16 (IntrStatus);
+		status = NETDRV_R16(IntrStatus);
 
-		/* h/w no longer present (hotplug?) or major error, bail */
+		/* h/w no longer present(hotplug?) or major error, bail */
 		if (status == 0xFFFF)
 			break;
 
 		handled = 1;
 		/* Acknowledge all of the current interrupt sources ASAP */
-		NETDRV_W16_F (IntrStatus, status);
+		NETDRV_W16_F(IntrStatus, status);
 
-		DPRINTK ("%s: interrupt  status=%#4.4x new intstat=%#4.4x.\n",
-				dev->name, status,
-				NETDRV_R16 (IntrStatus));
+		netdev_dbg(dev, "interrupt  status=%#04x new intstat=%#04x\n",
+			   status, NETDRV_R16(IntrStatus));
 
 		if ((status &
 		     (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
@@ -1682,69 +1671,67 @@ static irqreturn_t netdrv_interrupt (int
 
 		/* Check uncommon events with one test. */
 		if (status & (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
-		  	      RxFIFOOver | TxErr | RxErr))
-			netdrv_weird_interrupt (dev, tp, ioaddr,
-						 status, link_changed);
+			     RxFIFOOver | TxErr | RxErr))
+			netdrv_weird_interrupt(dev, tp, ioaddr,
+					       status, link_changed);
 
 		if (status & (RxOK | RxUnderrun | RxOverflow | RxFIFOOver))	/* Rx interrupt */
-			netdrv_rx_interrupt (dev, tp, ioaddr);
+			netdrv_rx_interrupt(dev, tp, ioaddr);
 
 		if (status & (TxOK | TxErr))
-			netdrv_tx_interrupt (dev, tp, ioaddr);
+			netdrv_tx_interrupt(dev, tp, ioaddr);
 
 		boguscnt--;
 	} while (boguscnt > 0);
 
 	if (boguscnt <= 0) {
-		printk (KERN_WARNING
-			"%s: Too much work at interrupt, "
-			"IntrStatus=0x%4.4x.\n", dev->name,
-			status);
+		netdev_warn(dev, "Too much work at interrupt, IntrStatus=%#04x\n",
+			    status);
 
 		/* Clear all interrupt sources. */
-		NETDRV_W16 (IntrStatus, 0xffff);
+		NETDRV_W16(IntrStatus, 0xffff);
 	}
 
-	spin_unlock (&tp->lock);
+	spin_unlock(&tp->lock);
 
-	DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
-		 dev->name, NETDRV_R16 (IntrStatus));
+	netdev_dbg(dev, "exiting interrupt, intr_status=%#04x\n",
+		   NETDRV_R16(IntrStatus));
 	return IRQ_RETVAL(handled);
 }
 
 
-static int netdrv_close (struct net_device *dev)
+static int netdrv_close(struct net_device *dev)
 {
 	struct netdrv_private *tp = netdev_priv(dev);
 	void *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
-	DPRINTK ("ENTER\n");
+	DPRINTK("ENTER\n");
 
-	netif_stop_queue (dev);
+	netif_stop_queue(dev);
 
-	DPRINTK ("%s: Shutting down ethercard, status was 0x%4.4x.\n",
-			dev->name, NETDRV_R16 (IntrStatus));
+	netdev_dbg(dev, "Shutting down ethercard, status was %#04x\n",
+		   NETDRV_R16(IntrStatus));
 
-	del_timer_sync (&tp->timer);
+	del_timer_sync(&tp->timer);
 
-	spin_lock_irqsave (&tp->lock, flags);
+	spin_lock_irqsave(&tp->lock, flags);
 
 	/* Stop the chip's Tx and Rx DMA processes. */
-	NETDRV_W8 (ChipCmd, (NETDRV_R8 (ChipCmd) & ChipCmdClear));
+	NETDRV_W8(ChipCmd, (NETDRV_R8(ChipCmd) & ChipCmdClear));
 
 	/* Disable interrupts by clearing the interrupt mask. */
-	NETDRV_W16 (IntrMask, 0x0000);
+	NETDRV_W16(IntrMask, 0x0000);
 
 	/* Update the error counts. */
-	dev->stats.rx_missed_errors += NETDRV_R32 (RxMissed);
-	NETDRV_W32 (RxMissed, 0);
+	dev->stats.rx_missed_errors += NETDRV_R32(RxMissed);
+	NETDRV_W32(RxMissed, 0);
 
-	spin_unlock_irqrestore (&tp->lock, flags);
+	spin_unlock_irqrestore(&tp->lock, flags);
 
-	free_irq (dev->irq, dev);
+	free_irq(dev->irq, dev);
 
-	netdrv_tx_clear (dev);
+	netdrv_tx_clear(dev);
 
 	pci_free_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
 			    tp->rx_ring, tp->rx_ring_dma);
@@ -1754,23 +1741,23 @@ static int netdrv_close (struct net_devi
 	tp->tx_bufs = NULL;
 
 	/* Green! Put the chip in low-power mode. */
-	NETDRV_W8 (Cfg9346, Cfg9346_Unlock);
-	NETDRV_W8 (Config1, 0x03);
-	NETDRV_W8 (Cfg9346, Cfg9346_Lock);
+	NETDRV_W8(Cfg9346, Cfg9346_Unlock);
+	NETDRV_W8(Config1, 0x03);
+	NETDRV_W8(Cfg9346, Cfg9346_Lock);
 
-	DPRINTK ("EXIT\n");
+	DPRINTK("EXIT\n");
 	return 0;
 }
 
 
-static int netdrv_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
+static int netdrv_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct netdrv_private *tp = netdev_priv(dev);
 	struct mii_ioctl_data *data = if_mii(rq);
 	unsigned long flags;
 	int rc = 0;
 
-	DPRINTK ("ENTER\n");
+	DPRINTK("ENTER\n");
 
 	switch (cmd) {
 	case SIOCGMIIPHY:		/* Get address of MII PHY in use. */
@@ -1778,15 +1765,15 @@ static int netdrv_ioctl (struct net_devi
 		/* Fall Through */
 
 	case SIOCGMIIREG:		/* Read MII PHY register. */
-		spin_lock_irqsave (&tp->lock, flags);
-		data->val_out = mdio_read (dev, data->phy_id & 0x1f, data->reg_num & 0x1f);
-		spin_unlock_irqrestore (&tp->lock, flags);
+		spin_lock_irqsave(&tp->lock, flags);
+		data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f);
+		spin_unlock_irqrestore(&tp->lock, flags);
 		break;
 
 	case SIOCSMIIREG:		/* Write MII PHY register. */
-		spin_lock_irqsave (&tp->lock, flags);
-		mdio_write (dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
-		spin_unlock_irqrestore (&tp->lock, flags);
+		spin_lock_irqsave(&tp->lock, flags);
+		mdio_write(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
+		spin_unlock_irqrestore(&tp->lock, flags);
 		break;
 
 	default:
@@ -1794,43 +1781,43 @@ static int netdrv_ioctl (struct net_devi
 		break;
 	}
 
-	DPRINTK ("EXIT, returning %d\n", rc);
+	DPRINTK("EXIT, returning %d\n", rc);
 	return rc;
 }
 
 /* Set or clear the multicast filter for this adaptor.
    This routine is not state sensitive and need not be SMP locked. */
 
-static void netdrv_set_rx_mode (struct net_device *dev)
+static void netdrv_set_rx_mode(struct net_device *dev)
 {
 	struct netdrv_private *tp = netdev_priv(dev);
 	void *ioaddr = tp->mmio_addr;
 	u32 mc_filter[2];	/* Multicast hash filter */
-	int i, rx_mode;
+	int rx_mode;
 	u32 tmp;
 
-	DPRINTK ("ENTER\n");
+	DPRINTK("ENTER\n");
 
-	DPRINTK ("%s:   netdrv_set_rx_mode(%4.4x) done -- Rx config %8.8x.\n",
-			dev->name, dev->flags, NETDRV_R32 (RxConfig));
+	netdev_dbg(dev, "%s(%04x) done -- Rx config %08lx\n",
+		   __func__, dev->flags, NETDRV_R32(RxConfig));
 
 	/* Note: do not reorder, GCC is clever about common statements. */
 	if (dev->flags & IFF_PROMISC) {
 		rx_mode =
-		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
-		    AcceptAllPhys;
+			AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
+			AcceptAllPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
-	} else if ((dev->mc_count > multicast_filter_limit) ||
+	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
 		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter perfectly -- accept all multicasts. */
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
 	} else {
 		struct dev_mc_list *mclist;
+
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 		mc_filter[1] = mc_filter[0] = 0;
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-		     i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
 
 			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
@@ -1838,66 +1825,66 @@ static void netdrv_set_rx_mode (struct n
 	}
 
 	/* if called from irq handler, lock already acquired */
-	if (!in_irq ())
-		spin_lock_irq (&tp->lock);
+	if (!in_irq())
+		spin_lock_irq(&tp->lock);
 
 	/* We can safely update without stopping the chip. */
 	tmp = netdrv_rx_config | rx_mode |
-		(NETDRV_R32 (RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
-	NETDRV_W32_F (RxConfig, tmp);
-	NETDRV_W32_F (MAR0 + 0, mc_filter[0]);
-	NETDRV_W32_F (MAR0 + 4, mc_filter[1]);
+		(NETDRV_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
+	NETDRV_W32_F(RxConfig, tmp);
+	NETDRV_W32_F(MAR0 + 0, mc_filter[0]);
+	NETDRV_W32_F(MAR0 + 4, mc_filter[1]);
 
-	if (!in_irq ())
-		spin_unlock_irq (&tp->lock);
+	if (!in_irq())
+		spin_unlock_irq(&tp->lock);
 
-	DPRINTK ("EXIT\n");
+	DPRINTK("EXIT\n");
 }
 
 
 #ifdef CONFIG_PM
 
-static int netdrv_suspend (struct pci_dev *pdev, pm_message_t state)
+static int netdrv_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-	struct net_device *dev = pci_get_drvdata (pdev);
+	struct net_device *dev = pci_get_drvdata(pdev);
 	struct netdrv_private *tp = netdev_priv(dev);
 	void *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
 	if (!netif_running(dev))
 		return 0;
-	netif_device_detach (dev);
+	netif_device_detach(dev);
 
-	spin_lock_irqsave (&tp->lock, flags);
+	spin_lock_irqsave(&tp->lock, flags);
 
 	/* Disable interrupts, stop Tx and Rx. */
-	NETDRV_W16 (IntrMask, 0x0000);
-	NETDRV_W8 (ChipCmd, (NETDRV_R8 (ChipCmd) & ChipCmdClear));
+	NETDRV_W16(IntrMask, 0x0000);
+	NETDRV_W8(ChipCmd, (NETDRV_R8(ChipCmd) & ChipCmdClear));
 
 	/* Update the error counts. */
-	dev->stats.rx_missed_errors += NETDRV_R32 (RxMissed);
-	NETDRV_W32 (RxMissed, 0);
+	dev->stats.rx_missed_errors += NETDRV_R32(RxMissed);
+	NETDRV_W32(RxMissed, 0);
 
-	spin_unlock_irqrestore (&tp->lock, flags);
+	spin_unlock_irqrestore(&tp->lock, flags);
 
-	pci_save_state (pdev);
-	pci_set_power_state (pdev, PCI_D3hot);
+	pci_save_state(pdev);
+	pci_set_power_state(pdev, PCI_D3hot);
 
 	return 0;
 }
 
 
-static int netdrv_resume (struct pci_dev *pdev)
+static int netdrv_resume(struct pci_dev *pdev)
 {
-	struct net_device *dev = pci_get_drvdata (pdev);
+	struct net_device *dev = pci_get_drvdata(pdev);
 	/*struct netdrv_private *tp = netdev_priv(dev);*/
 
 	if (!netif_running(dev))
 		return 0;
-	pci_set_power_state (pdev, PCI_D0);
-	pci_restore_state (pdev);
-	netif_device_attach (dev);
-	netdrv_hw_start (dev);
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+	netif_device_attach(dev);
+	netdrv_hw_start(dev);
 
 	return 0;
 }
@@ -1917,7 +1904,7 @@ static struct pci_driver netdrv_pci_driv
 };
 
 
-static int __init netdrv_init_module (void)
+static int __init netdrv_init_module(void)
 {
 /* when a module, this is printed whether or not devices are found in probe */
 #ifdef MODULE
@@ -1927,9 +1914,9 @@ static int __init netdrv_init_module (vo
 }
 
 
-static void __exit netdrv_cleanup_module (void)
+static void __exit netdrv_cleanup_module(void)
 {
-	pci_unregister_driver (&netdrv_pci_driver);
+	pci_unregister_driver(&netdrv_pci_driver);
 }
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/pcmcia/3c574_cs.c linux-libre-2.6.34-gnu1/drivers/net/pcmcia/3c574_cs.c
--- linux-libre-2.6.33-gnu1/drivers/net/pcmcia/3c574_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/pcmcia/3c574_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -781,8 +781,13 @@ static netdev_tx_t el3_start_xmit(struct
 		  inw(ioaddr + EL3_STATUS));
 
 	spin_lock_irqsave(&lp->window_lock, flags);
+
+	dev->stats.tx_bytes += skb->len;
+
+	/* Put out the doubleword header... */
 	outw(skb->len, ioaddr + TX_FIFO);
 	outw(0, ioaddr + TX_FIFO);
+	/* ... and the packet rounded to a doubleword. */
 	outsl(ioaddr + TX_FIFO, skb->data, (skb->len+3)>>2);
 
 	dev->trans_start = jiffies;
@@ -1021,8 +1026,6 @@ static void update_stats(struct net_devi
 	/* BadSSD */				   inb(ioaddr + 12);
 	up					 = inb(ioaddr + 13);
 
-	dev->stats.tx_bytes 			+= tx + ((up & 0xf0) << 12);
-
 	EL3WINDOW(1);
 }
 
@@ -1148,7 +1151,7 @@ static void set_rx_mode(struct net_devic
 	if (dev->flags & IFF_PROMISC)
 		outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,
 			 ioaddr + EL3_CMD);
-	else if (dev->mc_count || (dev->flags & IFF_ALLMULTI))
+	else if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI))
 		outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
 	else
 		outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/pcmcia/3c589_cs.c linux-libre-2.6.34-gnu1/drivers/net/pcmcia/3c589_cs.c
--- linux-libre-2.6.33-gnu1/drivers/net/pcmcia/3c589_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/pcmcia/3c589_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -886,7 +886,7 @@ static void set_rx_mode(struct net_devic
 
     if (dev->flags & IFF_PROMISC)
 	opts |= RxMulticast | RxProm;
-    else if (dev->mc_count || (dev->flags & IFF_ALLMULTI))
+    else if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI))
 	opts |= RxMulticast;
     outw(opts, ioaddr + EL3_CMD);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/pcmcia/axnet_cs.c linux-libre-2.6.34-gnu1/drivers/net/pcmcia/axnet_cs.c
--- linux-libre-2.6.33-gnu1/drivers/net/pcmcia/axnet_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/pcmcia/axnet_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/delay.h>
@@ -779,6 +778,7 @@ static struct pcmcia_device_id axnet_ids
 	PCMCIA_DEVICE_PROD_ID12("CNet", "CNF301", 0xbc477dde, 0x78c5f40b),
 	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEther PCC-TXD", 0x5261440f, 0x436768c5),
 	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEtherII PCC-TXD", 0x5261440f, 0x730df72e),
+	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEther PCC-TXM", 0x5261440f, 0x3abbd061),
 	PCMCIA_DEVICE_PROD_ID12("Dynalink", "L100C16", 0x55632fd5, 0x66bc2a90),
 	PCMCIA_DEVICE_PROD_ID12("IO DATA", "ETXPCM", 0x547e66dc, 0x233adac2),
 	PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V3)", 0x0733cc81, 0x232019a8),
@@ -1065,14 +1065,11 @@ static netdev_tx_t axnet_start_xmit(stru
 	   
 	spin_lock_irqsave(&ei_local->page_lock, flags);
 	outb_p(0x00, e8390_base + EN0_IMR);
-	spin_unlock_irqrestore(&ei_local->page_lock, flags);
 	
 	/*
 	 *	Slow phase with lock held.
 	 */
 	 
-	spin_lock_irqsave(&ei_local->page_lock, flags);
-	
 	ei_local->irqlock = 1;
 
 	send_length = max(length, ETH_ZLEN);
@@ -1628,8 +1625,7 @@ static inline void make_mc_bits(u8 *bits
 	struct dev_mc_list *dmi;
 	u32 crc;
 
-	for (dmi=dev->mc_list; dmi; dmi=dmi->next) {
-		
+	netdev_for_each_mc_addr(dmi, dev) {
 		crc = ether_crc(ETH_ALEN, dmi->dmi_addr);
 		/* 
 		 * The 8390 uses the 6 most significant bits of the
@@ -1655,7 +1651,7 @@ static void do_set_multicast_list(struct
 
 	if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) {
 		memset(ei_local->mcfilter, 0, 8);
-		if (dev->mc_list)
+		if (!netdev_mc_empty(dev))
 			make_mc_bits(ei_local->mcfilter, dev);
 	} else {
 		/* set to accept-all */
@@ -1671,7 +1667,7 @@ static void do_set_multicast_list(struct
 
   	if(dev->flags&IFF_PROMISC)
   		outb_p(E8390_RXCONFIG | 0x58, e8390_base + EN0_RXCR);
-	else if(dev->flags&IFF_ALLMULTI || dev->mc_list)
+	else if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev))
   		outb_p(E8390_RXCONFIG | 0x48, e8390_base + EN0_RXCR);
   	else
   		outb_p(E8390_RXCONFIG | 0x40, e8390_base + EN0_RXCR);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/pcmcia/fmvj18x_cs.c linux-libre-2.6.34-gnu1/drivers/net/pcmcia/fmvj18x_cs.c
--- linux-libre-2.6.33-gnu1/drivers/net/pcmcia/fmvj18x_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/pcmcia/fmvj18x_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -1187,22 +1187,20 @@ static void set_rx_mode(struct net_devic
     if (dev->flags & IFF_PROMISC) {
 	memset(mc_filter, 0xff, sizeof(mc_filter));
 	outb(3, ioaddr + RX_MODE);	/* Enable promiscuous mode */
-    } else if (dev->mc_count > MC_FILTERBREAK ||
+    } else if (netdev_mc_count(dev) > MC_FILTERBREAK ||
 	       (dev->flags & IFF_ALLMULTI)) {
 	/* Too many to filter perfectly -- accept all multicasts. */
 	memset(mc_filter, 0xff, sizeof(mc_filter));
 	outb(2, ioaddr + RX_MODE);	/* Use normal mode. */
-    } else if (dev->mc_count == 0) {
+    } else if (netdev_mc_empty(dev)) {
 	memset(mc_filter, 0x00, sizeof(mc_filter));
 	outb(1, ioaddr + RX_MODE);	/* Ignore almost all multicasts. */
     } else {
 	struct dev_mc_list *mclist;
 
 	memset(mc_filter, 0, sizeof(mc_filter));
-	for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-	     i++, mclist = mclist->next) {
-	    unsigned int bit =
-	    	ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26;
+	netdev_for_each_mc_addr(mclist, dev) {
+	    unsigned int bit = ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26;
 	    mc_filter[bit >> 3] |= (1 << (bit & 7));
 	}
 	outb(2, ioaddr + RX_MODE);	/* Use normal mode. */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/pcmcia/nmclan_cs.c linux-libre-2.6.34-gnu1/drivers/net/pcmcia/nmclan_cs.c
--- linux-libre-2.6.33-gnu1/drivers/net/pcmcia/nmclan_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/pcmcia/nmclan_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -1475,14 +1475,13 @@ static void set_multicast_list(struct ne
 {
   mace_private *lp = netdev_priv(dev);
   int adr[ETHER_ADDR_LEN] = {0}; /* Ethernet address */
-  int i;
-  struct dev_mc_list *dmi = dev->mc_list;
+  struct dev_mc_list *dmi;
 
 #ifdef PCMCIA_DEBUG
   {
     static int old;
-    if (dev->mc_count != old) {
-      old = dev->mc_count;
+    if (netdev_mc_count(dev) != old) {
+      old = netdev_mc_count(dev);
       pr_debug("%s: setting Rx mode to %d addresses.\n",
 	    dev->name, old);
     }
@@ -1490,15 +1489,14 @@ static void set_multicast_list(struct ne
 #endif
 
   /* Set multicast_num_addrs. */
-  lp->multicast_num_addrs = dev->mc_count;
+  lp->multicast_num_addrs = netdev_mc_count(dev);
 
   /* Set multicast_ladrf. */
   if (num_addrs > 0) {
     /* Calculate multicast logical address filter */
     memset(lp->multicast_ladrf, 0, MACE_LADRF_LEN);
-    for (i = 0; i < dev->mc_count; i++) {
+    netdev_for_each_mc_addr(dmi, dev) {
       memcpy(adr, dmi->dmi_addr, ETHER_ADDR_LEN);
-      dmi = dmi->next;
       BuildLAF(lp->multicast_ladrf, adr);
     }
   }
@@ -1537,15 +1535,15 @@ static void set_multicast_list(struct ne
 #ifdef PCMCIA_DEBUG
   {
     static int old;
-    if (dev->mc_count != old) {
-      old = dev->mc_count;
+    if (netdev_mc_count(dev) != old) {
+      old = netdev_mc_count(dev);
       pr_debug("%s: setting Rx mode to %d addresses.\n",
 	    dev->name, old);
     }
   }
 #endif
 
-  lp->multicast_num_addrs = dev->mc_count;
+  lp->multicast_num_addrs = netdev_mc_count(dev);
   restore_multicast_list(dev);
 
 } /* set_multicast_list */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/pcmcia/pcnet_cs.c linux-libre-2.6.34-gnu1/drivers/net/pcmcia/pcnet_cs.c
--- linux-libre-2.6.33-gnu1/drivers/net/pcmcia/pcnet_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/pcmcia/pcnet_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/delay.h>
@@ -1549,6 +1548,7 @@ static struct pcmcia_device_id pcnet_ids
 	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x021b, 0x0101),
 	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x08a1, 0xc0ab),
 	PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4),
+	PCMCIA_PFC_DEVICE_PROD_ID12(0, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e),
 	PCMCIA_PFC_DEVICE_PROD_ID12(0, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
 	PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
 	PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
@@ -1740,7 +1740,7 @@ static struct pcmcia_device_id pcnet_ids
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"),
-	PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"),
+	PCMCIA_DEVICE_CIS_PROD_ID12("Allied Telesis,K.K", "Ethernet LAN Card", 0x2ad62f3c, 0x9fd2f0a2, "cis/LA-PCM.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "cis/PE520.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("PMX   ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"),
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/pcmcia/smc91c92_cs.c linux-libre-2.6.34-gnu1/drivers/net/pcmcia/smc91c92_cs.c
--- linux-libre-2.6.33-gnu1/drivers/net/pcmcia/smc91c92_cs.c	2013-05-03 12:08:55.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/pcmcia/smc91c92_cs.c	2013-05-03 09:48:26.000000000 -0400
@@ -453,8 +453,7 @@ static int mhz_mfc_config(struct pcmcia_
 
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
-    link->irq.Attributes =
-	IRQ_TYPE_DYNAMIC_SHARING;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->io.IOAddrLines = 16;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts2 = 8;
@@ -494,13 +493,14 @@ static int pcmcia_get_versmac(struct pcm
 {
 	struct net_device *dev = priv;
 	cisparse_t parse;
+	u8 *buf;
 
 	if (pcmcia_parse_tuple(tuple, &parse))
 		return -EINVAL;
 
-	if ((parse.version_1.ns > 3) &&
-	    (cvt_ascii_address(dev,
-			       (parse.version_1.str + parse.version_1.ofs[3]))))
+	buf = parse.version_1.str + parse.version_1.ofs[3];
+
+	if ((parse.version_1.ns > 3) && (cvt_ascii_address(dev, buf) == 0))
 		return 0;
 
 	return -EINVAL;
@@ -529,7 +529,7 @@ static int mhz_setup(struct pcmcia_devic
     len = pcmcia_get_tuple(link, 0x81, &buf);
     if (buf && len >= 13) {
 	    buf[12] = '\0';
-	    if (cvt_ascii_address(dev, buf))
+	    if (cvt_ascii_address(dev, buf) == 0)
 		    rc = 0;
     }
     kfree(buf);
@@ -652,8 +652,7 @@ static int osi_config(struct pcmcia_devi
 
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
-    link->irq.Attributes =
-	IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->io.NumPorts1 = 64;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts2 = 8;
@@ -912,7 +911,7 @@ static int smc91c92_config(struct pcmcia
 
     if (i != 0) {
 	printk(KERN_NOTICE "smc91c92_cs: Unable to find hardware address.\n");
-	goto config_undo;
+	goto config_failed;
     }
 
     smc->duplex = 0;
@@ -1000,6 +999,7 @@ config_undo:
     unregister_netdev(dev);
 config_failed:
     smc91c92_release(link);
+    free_netdev(dev);
     return -ENODEV;
 } /* smc91c92_config */
 
@@ -1595,27 +1595,6 @@ static void smc_rx(struct net_device *de
 
 /*======================================================================
 
-    Calculate values for the hardware multicast filter hash table.
-
-======================================================================*/
-
-static void fill_multicast_tbl(int count, struct dev_mc_list *addrs,
-			       u_char *multicast_table)
-{
-    struct dev_mc_list	*mc_addr;
-
-    for (mc_addr = addrs;  mc_addr && count-- > 0;  mc_addr = mc_addr->next) {
-	u_int position = ether_crc(6, mc_addr->dmi_addr);
-#ifndef final_version		/* Verify multicast address. */
-	if ((mc_addr->dmi_addr[0] & 1) == 0)
-	    continue;
-#endif
-	multicast_table[position >> 29] |= 1 << ((position >> 26) & 7);
-    }
-}
-
-/*======================================================================
-
     Set the receive mode.
 
     This routine is used by both the protocol level to notify us of
@@ -1629,18 +1608,25 @@ static void set_rx_mode(struct net_devic
 {
     unsigned int ioaddr = dev->base_addr;
     struct smc_private *smc = netdev_priv(dev);
-    u_int multicast_table[ 2 ] = { 0, };
+    unsigned char multicast_table[8];
     unsigned long flags;
     u_short rx_cfg_setting;
+    int i;
+
+    memset(multicast_table, 0, sizeof(multicast_table));
 
     if (dev->flags & IFF_PROMISC) {
 	rx_cfg_setting = RxStripCRC | RxEnable | RxPromisc | RxAllMulti;
     } else if (dev->flags & IFF_ALLMULTI)
 	rx_cfg_setting = RxStripCRC | RxEnable | RxAllMulti;
     else {
-	if (dev->mc_count)  {
-	    fill_multicast_tbl(dev->mc_count, dev->mc_list,
-			       (u_char *)multicast_table);
+	if (!netdev_mc_empty(dev)) {
+	    struct dev_mc_list *mc_addr;
+
+	    netdev_for_each_mc_addr(mc_addr, dev) {
+		u_int position = ether_crc(6, mc_addr->dmi_addr);
+		multicast_table[position >> 29] |= 1 << ((position >> 26) & 7);
+	    }
 	}
 	rx_cfg_setting = RxStripCRC | RxEnable;
     }
@@ -1648,8 +1634,8 @@ static void set_rx_mode(struct net_devic
     /* Load MC table and Rx setting into the chip without interrupts. */
     spin_lock_irqsave(&smc->lock, flags);
     SMC_SELECT_BANK(3);
-    outl(multicast_table[0], ioaddr + MULTICAST0);
-    outl(multicast_table[1], ioaddr + MULTICAST4);
+    for (i = 0; i < 8; i++)
+	outb(multicast_table[i], ioaddr + MULTICAST0 + i);
     SMC_SELECT_BANK(0);
     outw(rx_cfg_setting, ioaddr + RCR);
     SMC_SELECT_BANK(2);
@@ -1818,23 +1804,30 @@ static void media_check(u_long arg)
     SMC_SELECT_BANK(1);
     media |= (inw(ioaddr + CONFIG) & CFG_AUI_SELECT) ? 2 : 1;
 
+    SMC_SELECT_BANK(saved_bank);
+    spin_unlock_irqrestore(&smc->lock, flags);
+
     /* Check for pending interrupt with watchdog flag set: with
        this, we can limp along even if the interrupt is blocked */
     if (smc->watchdog++ && ((i>>8) & i)) {
 	if (!smc->fast_poll)
 	    printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+	local_irq_save(flags);
 	smc_interrupt(dev->irq, dev);
+	local_irq_restore(flags);
 	smc->fast_poll = HZ;
     }
     if (smc->fast_poll) {
 	smc->fast_poll--;
 	smc->media.expires = jiffies + HZ/100;
 	add_timer(&smc->media);
-	SMC_SELECT_BANK(saved_bank);
-	spin_unlock_irqrestore(&smc->lock, flags);
 	return;
     }
 
+    spin_lock_irqsave(&smc->lock, flags);
+
+    saved_bank = inw(ioaddr + BANK_SELECT);
+
     if (smc->cfg & CFG_MII_SELECT) {
 	if (smc->mii_if.phy_id < 0)
 	    goto reschedule;
@@ -1992,15 +1985,16 @@ static int smc_get_settings(struct net_d
 	unsigned int ioaddr = dev->base_addr;
 	u16 saved_bank = inw(ioaddr + BANK_SELECT);
 	int ret;
+	unsigned long flags;
 
-	spin_lock_irq(&smc->lock);
+	spin_lock_irqsave(&smc->lock, flags);
 	SMC_SELECT_BANK(3);
 	if (smc->cfg & CFG_MII_SELECT)
 		ret = mii_ethtool_gset(&smc->mii_if, ecmd);
 	else
 		ret = smc_netdev_get_ecmd(dev, ecmd);
 	SMC_SELECT_BANK(saved_bank);
-	spin_unlock_irq(&smc->lock);
+	spin_unlock_irqrestore(&smc->lock, flags);
 	return ret;
 }
 
@@ -2010,15 +2004,16 @@ static int smc_set_settings(struct net_d
 	unsigned int ioaddr = dev->base_addr;
 	u16 saved_bank = inw(ioaddr + BANK_SELECT);
 	int ret;
+	unsigned long flags;
 
-	spin_lock_irq(&smc->lock);
+	spin_lock_irqsave(&smc->lock, flags);
 	SMC_SELECT_BANK(3);
 	if (smc->cfg & CFG_MII_SELECT)
 		ret = mii_ethtool_sset(&smc->mii_if, ecmd);
 	else
 		ret = smc_netdev_set_ecmd(dev, ecmd);
 	SMC_SELECT_BANK(saved_bank);
-	spin_unlock_irq(&smc->lock);
+	spin_unlock_irqrestore(&smc->lock, flags);
 	return ret;
 }
 
@@ -2028,12 +2023,13 @@ static u32 smc_get_link(struct net_devic
 	unsigned int ioaddr = dev->base_addr;
 	u16 saved_bank = inw(ioaddr + BANK_SELECT);
 	u32 ret;
+	unsigned long flags;
 
-	spin_lock_irq(&smc->lock);
+	spin_lock_irqsave(&smc->lock, flags);
 	SMC_SELECT_BANK(3);
 	ret = smc_link_ok(dev);
 	SMC_SELECT_BANK(saved_bank);
-	spin_unlock_irq(&smc->lock);
+	spin_unlock_irqrestore(&smc->lock, flags);
 	return ret;
 }
 
@@ -2070,16 +2066,17 @@ static int smc_ioctl (struct net_device
 	int rc = 0;
 	u16 saved_bank;
 	unsigned int ioaddr = dev->base_addr;
+	unsigned long flags;
 
 	if (!netif_running(dev))
 		return -EINVAL;
 
-	spin_lock_irq(&smc->lock);
+	spin_lock_irqsave(&smc->lock, flags);
 	saved_bank = inw(ioaddr + BANK_SELECT);
 	SMC_SELECT_BANK(3);
 	rc = generic_mii_ioctl(&smc->mii_if, mii, cmd, NULL);
 	SMC_SELECT_BANK(saved_bank);
-	spin_unlock_irq(&smc->lock);
+	spin_unlock_irqrestore(&smc->lock, flags);
 	return rc;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/pcmcia/xirc2ps_cs.c linux-libre-2.6.34-gnu1/drivers/net/pcmcia/xirc2ps_cs.c
--- linux-libre-2.6.33-gnu1/drivers/net/pcmcia/xirc2ps_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/pcmcia/xirc2ps_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -1364,47 +1364,63 @@ do_start_xmit(struct sk_buff *skb, struc
     return NETDEV_TX_OK;
 }
 
+struct set_address_info {
+	int reg_nr;
+	int page_nr;
+	int mohawk;
+	unsigned int ioaddr;
+};
+
+static void set_address(struct set_address_info *sa_info, char *addr)
+{
+	unsigned int ioaddr = sa_info->ioaddr;
+	int i;
+
+	for (i = 0; i < 6; i++) {
+		if (sa_info->reg_nr > 15) {
+			sa_info->reg_nr = 8;
+			sa_info->page_nr++;
+			SelectPage(sa_info->page_nr);
+		}
+		if (sa_info->mohawk)
+			PutByte(sa_info->reg_nr++, addr[5 - i]);
+		else
+			PutByte(sa_info->reg_nr++, addr[i]);
+	}
+}
+
 /****************
  * Set all addresses: This first one is the individual address,
  * the next 9 addresses are taken from the multicast list and
  * the rest is filled with the individual address.
  */
-static void
-set_addresses(struct net_device *dev)
+static void set_addresses(struct net_device *dev)
 {
-    unsigned int ioaddr = dev->base_addr;
-    local_info_t *lp = netdev_priv(dev);
-    struct dev_mc_list *dmi = dev->mc_list;
-    unsigned char *addr;
-    int i,j,k,n;
-
-    SelectPage(k=0x50);
-    for (i=0,j=8,n=0; ; i++, j++) {
-	if (i > 5) {
-	    if (++n > 9)
-		break;
-	    i = 0;
-	    if (n > 1 && n <= dev->mc_count && dmi) {
-	   	 dmi = dmi->next;
-	    }
-	}
-	if (j > 15) {
-	    j = 8;
-	    k++;
-	    SelectPage(k);
-	}
+	unsigned int ioaddr = dev->base_addr;
+	local_info_t *lp = netdev_priv(dev);
+	struct dev_mc_list *dmi;
+	struct set_address_info sa_info;
+	int i;
 
-	if (n && n <= dev->mc_count && dmi)
-	    addr = dmi->dmi_addr;
-	else
-	    addr = dev->dev_addr;
+	/*
+	 * Setup the info structure so that by first set_address call it will do
+	 * SelectPage with the right page number. Hence these ones here.
+	 */
+	sa_info.reg_nr = 15 + 1;
+	sa_info.page_nr = 0x50 - 1;
+	sa_info.mohawk = lp->mohawk;
+	sa_info.ioaddr = ioaddr;
 
-	if (lp->mohawk)
-	    PutByte(j, addr[5-i]);
-	else
-	    PutByte(j, addr[i]);
-    }
-    SelectPage(0);
+	set_address(&sa_info, dev->dev_addr);
+	i = 0;
+	netdev_for_each_mc_addr(dmi, dev) {
+		if (i++ == 9)
+			break;
+		set_address(&sa_info, dmi->dmi_addr);
+	}
+	while (i++ < 9)
+		set_address(&sa_info, dev->dev_addr);
+	SelectPage(0);
 }
 
 /****************
@@ -1424,9 +1440,9 @@ set_multicast_list(struct net_device *de
 
     if (dev->flags & IFF_PROMISC) { /* snoop */
 	PutByte(XIRCREG42_SWC1, value | 0x06); /* set MPE and PME */
-    } else if (dev->mc_count > 9 || (dev->flags & IFF_ALLMULTI)) {
+    } else if (netdev_mc_count(dev) > 9 || (dev->flags & IFF_ALLMULTI)) {
 	PutByte(XIRCREG42_SWC1, value | 0x02); /* set MPE */
-    } else if (dev->mc_count) {
+    } else if (!netdev_mc_empty(dev)) {
 	/* the chip can filter 9 addresses perfectly */
 	PutByte(XIRCREG42_SWC1, value | 0x01);
 	SelectPage(0x40);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/pcnet32.c linux-libre-2.6.34-gnu1/drivers/net/pcnet32.c
--- linux-libre-2.6.33-gnu1/drivers/net/pcnet32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/pcnet32.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,8 @@
  *
  *************************************************************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #define DRV_NAME	"pcnet32"
 #define DRV_VERSION	"1.35"
 #define DRV_RELDATE	"21.Apr.2008"
@@ -50,16 +52,16 @@ static const char *const version =
 #include <linux/spinlock.h>
 #include <linux/moduleparam.h>
 #include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
 
 #include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
 #include <asm/irq.h>
 
 /*
  * PCI device identifiers for "new style" Linux PCI Device Drivers
  */
-static struct pci_device_id pcnet32_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(pcnet32_pci_tbl) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE_HOME), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE), },
 
@@ -83,7 +85,7 @@ static int cards_found;
 static unsigned int pcnet32_portlist[] __initdata =
     { 0x300, 0x320, 0x340, 0x360, 0 };
 
-static int pcnet32_debug = 0;
+static int pcnet32_debug;
 static int tx_start = 1;	/* Mapping -- 0:20, 1:64, 2:128, 3:~220 (depends on chip vers) */
 static int pcnet32vlb;		/* check for VLB cards ? */
 
@@ -390,7 +392,7 @@ static struct pcnet32_access pcnet32_wio
 static u16 pcnet32_dwio_read_csr(unsigned long addr, int index)
 {
 	outl(index, addr + PCNET32_DWIO_RAP);
-	return (inl(addr + PCNET32_DWIO_RDP) & 0xffff);
+	return inl(addr + PCNET32_DWIO_RDP) & 0xffff;
 }
 
 static void pcnet32_dwio_write_csr(unsigned long addr, int index, u16 val)
@@ -402,7 +404,7 @@ static void pcnet32_dwio_write_csr(unsig
 static u16 pcnet32_dwio_read_bcr(unsigned long addr, int index)
 {
 	outl(index, addr + PCNET32_DWIO_RAP);
-	return (inl(addr + PCNET32_DWIO_BDP) & 0xffff);
+	return inl(addr + PCNET32_DWIO_BDP) & 0xffff;
 }
 
 static void pcnet32_dwio_write_bcr(unsigned long addr, int index, u16 val)
@@ -413,7 +415,7 @@ static void pcnet32_dwio_write_bcr(unsig
 
 static u16 pcnet32_dwio_read_rap(unsigned long addr)
 {
-	return (inl(addr + PCNET32_DWIO_RAP) & 0xffff);
+	return inl(addr + PCNET32_DWIO_RAP) & 0xffff;
 }
 
 static void pcnet32_dwio_write_rap(unsigned long addr, u16 val)
@@ -487,10 +489,7 @@ static void pcnet32_realloc_tx_ring(stru
 					   (1 << size),
 					   &new_ring_dma_addr);
 	if (new_tx_ring == NULL) {
-		if (netif_msg_drv(lp))
-			printk(KERN_ERR
-			       "%s: Consistent memory allocation failed.\n",
-			       dev->name);
+		netif_err(lp, drv, dev, "Consistent memory allocation failed\n");
 		return;
 	}
 	memset(new_tx_ring, 0, sizeof(struct pcnet32_tx_head) * (1 << size));
@@ -498,18 +497,14 @@ static void pcnet32_realloc_tx_ring(stru
 	new_dma_addr_list = kcalloc((1 << size), sizeof(dma_addr_t),
 				GFP_ATOMIC);
 	if (!new_dma_addr_list) {
-		if (netif_msg_drv(lp))
-			printk(KERN_ERR
-			       "%s: Memory allocation failed.\n", dev->name);
+		netif_err(lp, drv, dev, "Memory allocation failed\n");
 		goto free_new_tx_ring;
 	}
 
 	new_skb_list = kcalloc((1 << size), sizeof(struct sk_buff *),
 				GFP_ATOMIC);
 	if (!new_skb_list) {
-		if (netif_msg_drv(lp))
-			printk(KERN_ERR
-			       "%s: Memory allocation failed.\n", dev->name);
+		netif_err(lp, drv, dev, "Memory allocation failed\n");
 		goto free_new_lists;
 	}
 
@@ -529,15 +524,14 @@ static void pcnet32_realloc_tx_ring(stru
 	lp->tx_skbuff = new_skb_list;
 	return;
 
-    free_new_lists:
+free_new_lists:
 	kfree(new_dma_addr_list);
-    free_new_tx_ring:
+free_new_tx_ring:
 	pci_free_consistent(lp->pci_dev,
 			    sizeof(struct pcnet32_tx_head) *
 			    (1 << size),
 			    new_tx_ring,
 			    new_ring_dma_addr);
-	return;
 }
 
 /*
@@ -565,10 +559,7 @@ static void pcnet32_realloc_rx_ring(stru
 					   (1 << size),
 					   &new_ring_dma_addr);
 	if (new_rx_ring == NULL) {
-		if (netif_msg_drv(lp))
-			printk(KERN_ERR
-			       "%s: Consistent memory allocation failed.\n",
-			       dev->name);
+		netif_err(lp, drv, dev, "Consistent memory allocation failed\n");
 		return;
 	}
 	memset(new_rx_ring, 0, sizeof(struct pcnet32_rx_head) * (1 << size));
@@ -576,18 +567,14 @@ static void pcnet32_realloc_rx_ring(stru
 	new_dma_addr_list = kcalloc((1 << size), sizeof(dma_addr_t),
 				GFP_ATOMIC);
 	if (!new_dma_addr_list) {
-		if (netif_msg_drv(lp))
-			printk(KERN_ERR
-			       "%s: Memory allocation failed.\n", dev->name);
+		netif_err(lp, drv, dev, "Memory allocation failed\n");
 		goto free_new_rx_ring;
 	}
 
 	new_skb_list = kcalloc((1 << size), sizeof(struct sk_buff *),
 				GFP_ATOMIC);
 	if (!new_skb_list) {
-		if (netif_msg_drv(lp))
-			printk(KERN_ERR
-			       "%s: Memory allocation failed.\n", dev->name);
+		netif_err(lp, drv, dev, "Memory allocation failed\n");
 		goto free_new_lists;
 	}
 
@@ -599,15 +586,14 @@ static void pcnet32_realloc_rx_ring(stru
 		new_skb_list[new] = lp->rx_skbuff[new];
 	}
 	/* now allocate any new buffers needed */
-	for (; new < size; new++ ) {
+	for (; new < size; new++) {
 		struct sk_buff *rx_skbuff;
 		new_skb_list[new] = dev_alloc_skb(PKT_BUF_SKB);
-		if (!(rx_skbuff = new_skb_list[new])) {
+		rx_skbuff = new_skb_list[new];
+		if (!rx_skbuff) {
 			/* keep the original lists and buffers */
-			if (netif_msg_drv(lp))
-				printk(KERN_ERR
-				       "%s: pcnet32_realloc_rx_ring dev_alloc_skb failed.\n",
-				       dev->name);
+			netif_err(lp, drv, dev, "%s dev_alloc_skb failed\n",
+				  __func__);
 			goto free_all_new;
 		}
 		skb_reserve(rx_skbuff, NET_IP_ALIGN);
@@ -644,8 +630,8 @@ static void pcnet32_realloc_rx_ring(stru
 	lp->rx_skbuff = new_skb_list;
 	return;
 
-    free_all_new:
-	for (; --new >= lp->rx_ring_size; ) {
+free_all_new:
+	while (--new >= lp->rx_ring_size) {
 		if (new_skb_list[new]) {
 			pci_unmap_single(lp->pci_dev, new_dma_addr_list[new],
 					 PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
@@ -653,9 +639,9 @@ static void pcnet32_realloc_rx_ring(stru
 		}
 	}
 	kfree(new_skb_list);
-    free_new_lists:
+free_new_lists:
 	kfree(new_dma_addr_list);
-    free_new_rx_ring:
+free_new_rx_ring:
 	pci_free_consistent(lp->pci_dev,
 			    sizeof(struct pcnet32_rx_head) *
 			    (1 << size),
@@ -838,16 +824,14 @@ static int pcnet32_set_ringparam(struct
 
 	spin_unlock_irqrestore(&lp->lock, flags);
 
-	if (netif_msg_drv(lp))
-		printk(KERN_INFO
-		       "%s: Ring Param Settings: RX: %d, TX: %d\n", dev->name,
-		       lp->rx_ring_size, lp->tx_ring_size);
+	netif_info(lp, drv, dev, "Ring Param Settings: RX: %d, TX: %d\n",
+		   lp->rx_ring_size, lp->tx_ring_size);
 
 	return 0;
 }
 
 static void pcnet32_get_strings(struct net_device *dev, u32 stringset,
-				u8 * data)
+				u8 *data)
 {
 	memcpy(data, pcnet32_gstrings_test, sizeof(pcnet32_gstrings_test));
 }
@@ -871,17 +855,15 @@ static void pcnet32_ethtool_test(struct
 	if (test->flags == ETH_TEST_FL_OFFLINE) {
 		rc = pcnet32_loopback_test(dev, data);
 		if (rc) {
-			if (netif_msg_hw(lp))
-				printk(KERN_DEBUG "%s: Loopback test failed.\n",
-				       dev->name);
+			netif_printk(lp, hw, KERN_DEBUG, dev,
+				     "Loopback test failed\n");
 			test->flags |= ETH_TEST_FL_FAILED;
-		} else if (netif_msg_hw(lp))
-			printk(KERN_DEBUG "%s: Loopback test passed.\n",
-			       dev->name);
-	} else if (netif_msg_hw(lp))
-		printk(KERN_DEBUG
-		       "%s: No tests to run (specify 'Offline' on ethtool).",
-		       dev->name);
+		} else
+			netif_printk(lp, hw, KERN_DEBUG, dev,
+				     "Loopback test passed\n");
+	} else
+		netif_printk(lp, hw, KERN_DEBUG, dev,
+			     "No tests to run (specify 'Offline' on ethtool)\n");
 }				/* end pcnet32_ethtool_test */
 
 static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
@@ -926,40 +908,39 @@ static int pcnet32_loopback_test(struct
 	/* Initialize Transmit buffers. */
 	size = data_len + 15;
 	for (x = 0; x < numbuffs; x++) {
-		if (!(skb = dev_alloc_skb(size))) {
-			if (netif_msg_hw(lp))
-				printk(KERN_DEBUG
-				       "%s: Cannot allocate skb at line: %d!\n",
-				       dev->name, __LINE__);
+		skb = dev_alloc_skb(size);
+		if (!skb) {
+			netif_printk(lp, hw, KERN_DEBUG, dev,
+				     "Cannot allocate skb at line: %d!\n",
+				     __LINE__);
 			goto clean_up;
-		} else {
-			packet = skb->data;
-			skb_put(skb, size);	/* create space for data */
-			lp->tx_skbuff[x] = skb;
-			lp->tx_ring[x].length = cpu_to_le16(-skb->len);
-			lp->tx_ring[x].misc = 0;
+		}
+		packet = skb->data;
+		skb_put(skb, size);	/* create space for data */
+		lp->tx_skbuff[x] = skb;
+		lp->tx_ring[x].length = cpu_to_le16(-skb->len);
+		lp->tx_ring[x].misc = 0;
 
-			/* put DA and SA into the skb */
-			for (i = 0; i < 6; i++)
-				*packet++ = dev->dev_addr[i];
-			for (i = 0; i < 6; i++)
-				*packet++ = dev->dev_addr[i];
-			/* type */
-			*packet++ = 0x08;
-			*packet++ = 0x06;
-			/* packet number */
-			*packet++ = x;
-			/* fill packet with data */
-			for (i = 0; i < data_len; i++)
-				*packet++ = i;
+		/* put DA and SA into the skb */
+		for (i = 0; i < 6; i++)
+			*packet++ = dev->dev_addr[i];
+		for (i = 0; i < 6; i++)
+			*packet++ = dev->dev_addr[i];
+		/* type */
+		*packet++ = 0x08;
+		*packet++ = 0x06;
+		/* packet number */
+		*packet++ = x;
+		/* fill packet with data */
+		for (i = 0; i < data_len; i++)
+			*packet++ = i;
 
-			lp->tx_dma_addr[x] =
-			    pci_map_single(lp->pci_dev, skb->data, skb->len,
-					   PCI_DMA_TODEVICE);
-			lp->tx_ring[x].base = cpu_to_le32(lp->tx_dma_addr[x]);
-			wmb();	/* Make sure owner changes after all others are visible */
-			lp->tx_ring[x].status = cpu_to_le16(status);
-		}
+		lp->tx_dma_addr[x] =
+			pci_map_single(lp->pci_dev, skb->data, skb->len,
+				       PCI_DMA_TODEVICE);
+		lp->tx_ring[x].base = cpu_to_le32(lp->tx_dma_addr[x]);
+		wmb();	/* Make sure owner changes after all others are visible */
+		lp->tx_ring[x].status = cpu_to_le16(status);
 	}
 
 	x = a->read_bcr(ioaddr, 32);	/* set internal loopback in BCR32 */
@@ -984,9 +965,7 @@ static int pcnet32_loopback_test(struct
 			ticks++;
 		}
 		if (ticks == 200) {
-			if (netif_msg_hw(lp))
-				printk("%s: Desc %d failed to reset!\n",
-				       dev->name, x);
+			netif_err(lp, hw, dev, "Desc %d failed to reset!\n", x);
 			break;
 		}
 	}
@@ -994,15 +973,14 @@ static int pcnet32_loopback_test(struct
 	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);	/* Set STOP bit */
 	wmb();
 	if (netif_msg_hw(lp) && netif_msg_pktdata(lp)) {
-		printk(KERN_DEBUG "%s: RX loopback packets:\n", dev->name);
+		netdev_printk(KERN_DEBUG, dev, "RX loopback packets:\n");
 
 		for (x = 0; x < numbuffs; x++) {
-			printk(KERN_DEBUG "%s: Packet %d:\n", dev->name, x);
+			netdev_printk(KERN_DEBUG, dev, "Packet %d: ", x);
 			skb = lp->rx_skbuff[x];
-			for (i = 0; i < size; i++) {
-				printk("%02x ", *(skb->data + i));
-			}
-			printk("\n");
+			for (i = 0; i < size; i++)
+				pr_cont(" %02x", *(skb->data + i));
+			pr_cont("\n");
 		}
 	}
 
@@ -1013,11 +991,9 @@ static int pcnet32_loopback_test(struct
 		packet = lp->tx_skbuff[x]->data;
 		for (i = 0; i < size; i++) {
 			if (*(skb->data + i) != packet[i]) {
-				if (netif_msg_hw(lp))
-					printk(KERN_DEBUG
-					       "%s: Error in compare! %2x - %02x %02x\n",
-					       dev->name, i, *(skb->data + i),
-					       packet[i]);
+				netif_printk(lp, hw, KERN_DEBUG, dev,
+					     "Error in compare! %2x - %02x %02x\n",
+					     i, *(skb->data + i), packet[i]);
 				rc = 1;
 				break;
 			}
@@ -1025,7 +1001,7 @@ static int pcnet32_loopback_test(struct
 		x++;
 	}
 
-      clean_up:
+clean_up:
 	*data1 = rc;
 	pcnet32_purge_tx_ring(dev);
 
@@ -1044,7 +1020,7 @@ static int pcnet32_loopback_test(struct
 	}
 	spin_unlock_irqrestore(&lp->lock, flags);
 
-	return (rc);
+	return rc;
 }				/* end pcnet32_loopback_test  */
 
 static void pcnet32_led_blink_callback(struct net_device *dev)
@@ -1056,9 +1032,8 @@ static void pcnet32_led_blink_callback(s
 	int i;
 
 	spin_lock_irqsave(&lp->lock, flags);
-	for (i = 4; i < 8; i++) {
+	for (i = 4; i < 8; i++)
 		a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000);
-	}
 	spin_unlock_irqrestore(&lp->lock, flags);
 
 	mod_timer(&lp->blink_timer, PCNET32_BLINK_TIMEOUT);
@@ -1080,9 +1055,8 @@ static int pcnet32_phys_id(struct net_de
 
 	/* Save the current value of the bcrs */
 	spin_lock_irqsave(&lp->lock, flags);
-	for (i = 4; i < 8; i++) {
+	for (i = 4; i < 8; i++)
 		regs[i - 4] = a->read_bcr(ioaddr, i);
-	}
 	spin_unlock_irqrestore(&lp->lock, flags);
 
 	mod_timer(&lp->blink_timer, jiffies);
@@ -1097,9 +1071,8 @@ static int pcnet32_phys_id(struct net_de
 
 	/* Restore the original value of the bcrs */
 	spin_lock_irqsave(&lp->lock, flags);
-	for (i = 4; i < 8; i++) {
+	for (i = 4; i < 8; i++)
 		a->write_bcr(ioaddr, i, regs[i - 4]);
-	}
 	spin_unlock_irqrestore(&lp->lock, flags);
 
 	return 0;
@@ -1136,10 +1109,8 @@ static int pcnet32_suspend(struct net_de
 		spin_lock_irqsave(&lp->lock, *flags);
 		ticks++;
 		if (ticks > 200) {
-			if (netif_msg_hw(lp))
-				printk(KERN_DEBUG
-				       "%s: Error getting into suspend!\n",
-				       dev->name);
+			netif_printk(lp, hw, KERN_DEBUG, dev,
+				     "Error getting into suspend!\n");
 			return 0;
 		}
 	}
@@ -1184,15 +1155,13 @@ static void pcnet32_rx_entry(struct net_
 
 	/* Discard oversize frames. */
 	if (unlikely(pkt_len > PKT_BUF_SIZE)) {
-		if (netif_msg_drv(lp))
-			printk(KERN_ERR "%s: Impossible packet size %d!\n",
-			       dev->name, pkt_len);
+		netif_err(lp, drv, dev, "Impossible packet size %d!\n",
+			  pkt_len);
 		dev->stats.rx_errors++;
 		return;
 	}
 	if (pkt_len < 60) {
-		if (netif_msg_rx_err(lp))
-			printk(KERN_ERR "%s: Runt packet!\n", dev->name);
+		netif_err(lp, rx_err, dev, "Runt packet!\n");
 		dev->stats.rx_errors++;
 		return;
 	}
@@ -1200,7 +1169,8 @@ static void pcnet32_rx_entry(struct net_
 	if (pkt_len > rx_copybreak) {
 		struct sk_buff *newskb;
 
-		if ((newskb = dev_alloc_skb(PKT_BUF_SKB))) {
+		newskb = dev_alloc_skb(PKT_BUF_SKB);
+		if (newskb) {
 			skb_reserve(newskb, NET_IP_ALIGN);
 			skb = lp->rx_skbuff[entry];
 			pci_unmap_single(lp->pci_dev,
@@ -1218,15 +1188,11 @@ static void pcnet32_rx_entry(struct net_
 			rx_in_place = 1;
 		} else
 			skb = NULL;
-	} else {
+	} else
 		skb = dev_alloc_skb(pkt_len + NET_IP_ALIGN);
-	}
 
 	if (skb == NULL) {
-		if (netif_msg_drv(lp))
-			printk(KERN_ERR
-			       "%s: Memory squeeze, dropping packet.\n",
-			       dev->name);
+		netif_err(lp, drv, dev, "Memory squeeze, dropping packet\n");
 		dev->stats.rx_dropped++;
 		return;
 	}
@@ -1297,11 +1263,9 @@ static int pcnet32_tx(struct net_device
 			/* There was a major error, log it. */
 			int err_status = le32_to_cpu(lp->tx_ring[entry].misc);
 			dev->stats.tx_errors++;
-			if (netif_msg_tx_err(lp))
-				printk(KERN_ERR
-				       "%s: Tx error status=%04x err_status=%08x\n",
-				       dev->name, status,
-				       err_status);
+			netif_err(lp, tx_err, dev,
+				  "Tx error status=%04x err_status=%08x\n",
+				  status, err_status);
 			if (err_status & 0x04000000)
 				dev->stats.tx_aborted_errors++;
 			if (err_status & 0x08000000)
@@ -1313,10 +1277,7 @@ static int pcnet32_tx(struct net_device
 				dev->stats.tx_fifo_errors++;
 				/* Ackk!  On FIFO errors the Tx unit is turned off! */
 				/* Remove this verbosity later! */
-				if (netif_msg_tx_err(lp))
-					printk(KERN_ERR
-					       "%s: Tx FIFO error!\n",
-					       dev->name);
+				netif_err(lp, tx_err, dev, "Tx FIFO error!\n");
 				must_restart = 1;
 			}
 #else
@@ -1325,10 +1286,7 @@ static int pcnet32_tx(struct net_device
 				if (!lp->dxsuflo) {	/* If controller doesn't recover ... */
 					/* Ackk!  On FIFO errors the Tx unit is turned off! */
 					/* Remove this verbosity later! */
-					if (netif_msg_tx_err(lp))
-						printk(KERN_ERR
-						       "%s: Tx FIFO error!\n",
-						       dev->name);
+					netif_err(lp, tx_err, dev, "Tx FIFO error!\n");
 					must_restart = 1;
 				}
 			}
@@ -1354,11 +1312,8 @@ static int pcnet32_tx(struct net_device
 
 	delta = (lp->cur_tx - dirty_tx) & (lp->tx_mod_mask + lp->tx_ring_size);
 	if (delta > lp->tx_ring_size) {
-		if (netif_msg_drv(lp))
-			printk(KERN_ERR
-			       "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
-			       dev->name, dirty_tx, lp->cur_tx,
-			       lp->tx_full);
+		netif_err(lp, drv, dev, "out-of-sync dirty pointer, %d vs. %d, full=%d\n",
+			  dirty_tx, lp->cur_tx, lp->tx_full);
 		dirty_tx += lp->tx_ring_size;
 		delta -= lp->tx_ring_size;
 	}
@@ -1421,7 +1376,7 @@ static int pcnet32_get_regs_len(struct n
 	struct pcnet32_private *lp = netdev_priv(dev);
 	int j = lp->phycount * PCNET32_REGS_PER_PHY;
 
-	return ((PCNET32_NUM_REGS + j) * sizeof(u16));
+	return (PCNET32_NUM_REGS + j) * sizeof(u16);
 }
 
 static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
@@ -1445,21 +1400,20 @@ static void pcnet32_get_regs(struct net_
 		*buff++ = inw(ioaddr + i);
 
 	/* read control and status registers */
-	for (i = 0; i < 90; i++) {
+	for (i = 0; i < 90; i++)
 		*buff++ = a->read_csr(ioaddr, i);
-	}
 
 	*buff++ = a->read_csr(ioaddr, 112);
 	*buff++ = a->read_csr(ioaddr, 114);
 
 	/* read bus configuration registers */
-	for (i = 0; i < 30; i++) {
+	for (i = 0; i < 30; i++)
 		*buff++ = a->read_bcr(ioaddr, i);
-	}
+
 	*buff++ = 0;		/* skip bcr30 so as not to hang 79C976 */
-	for (i = 31; i < 36; i++) {
+
+	for (i = 31; i < 36; i++)
 		*buff++ = a->read_bcr(ioaddr, i);
-	}
 
 	/* read mii phy registers */
 	if (lp->mii) {
@@ -1535,8 +1489,7 @@ pcnet32_probe_pci(struct pci_dev *pdev,
 	err = pci_enable_device(pdev);
 	if (err < 0) {
 		if (pcnet32_debug & NETIF_MSG_PROBE)
-			printk(KERN_ERR PFX
-			       "failed to enable device -- err=%d\n", err);
+			pr_err("failed to enable device -- err=%d\n", err);
 		return err;
 	}
 	pci_set_master(pdev);
@@ -1544,29 +1497,25 @@ pcnet32_probe_pci(struct pci_dev *pdev,
 	ioaddr = pci_resource_start(pdev, 0);
 	if (!ioaddr) {
 		if (pcnet32_debug & NETIF_MSG_PROBE)
-			printk(KERN_ERR PFX
-			       "card has no PCI IO resources, aborting\n");
+			pr_err("card has no PCI IO resources, aborting\n");
 		return -ENODEV;
 	}
 
 	if (!pci_dma_supported(pdev, PCNET32_DMA_MASK)) {
 		if (pcnet32_debug & NETIF_MSG_PROBE)
-			printk(KERN_ERR PFX
-			       "architecture does not support 32bit PCI busmaster DMA\n");
+			pr_err("architecture does not support 32bit PCI busmaster DMA\n");
 		return -ENODEV;
 	}
-	if (request_region(ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_pci") ==
-	    NULL) {
+	if (!request_region(ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_pci")) {
 		if (pcnet32_debug & NETIF_MSG_PROBE)
-			printk(KERN_ERR PFX
-			       "io address range already allocated\n");
+			pr_err("io address range already allocated\n");
 		return -EBUSY;
 	}
 
 	err = pcnet32_probe1(ioaddr, 1, pdev);
-	if (err < 0) {
+	if (err < 0)
 		pci_disable_device(pdev);
-	}
+
 	return err;
 }
 
@@ -1616,7 +1565,7 @@ pcnet32_probe1(unsigned long ioaddr, int
 			a = &pcnet32_dwio;
 		} else {
 			if (pcnet32_debug & NETIF_MSG_PROBE)
-				printk(KERN_ERR PFX "No access methods\n");
+				pr_err("No access methods\n");
 			goto err_release_region;
 		}
 	}
@@ -1624,11 +1573,10 @@ pcnet32_probe1(unsigned long ioaddr, int
 	chip_version =
 	    a->read_csr(ioaddr, 88) | (a->read_csr(ioaddr, 89) << 16);
 	if ((pcnet32_debug & NETIF_MSG_PROBE) && (pcnet32_debug & NETIF_MSG_HW))
-		printk(KERN_INFO "  PCnet chip version is %#x.\n",
-		       chip_version);
+		pr_info("  PCnet chip version is %#x\n", chip_version);
 	if ((chip_version & 0xfff) != 0x003) {
 		if (pcnet32_debug & NETIF_MSG_PROBE)
-			printk(KERN_INFO PFX "Unsupported chip version.\n");
+			pr_info("Unsupported chip version\n");
 		goto err_release_region;
 	}
 
@@ -1681,7 +1629,7 @@ pcnet32_probe1(unsigned long ioaddr, int
 		if (cards_found < MAX_UNITS && homepna[cards_found])
 			media |= 1;	/* switch to home wiring mode */
 		if (pcnet32_debug & NETIF_MSG_PROBE)
-			printk(KERN_DEBUG PFX "media set to %sMbit mode.\n",
+			printk(KERN_DEBUG PFX "media set to %sMbit mode\n",
 			       (media & 1) ? "1" : "10");
 		a->write_bcr(ioaddr, 49, media);
 		break;
@@ -1697,9 +1645,8 @@ pcnet32_probe1(unsigned long ioaddr, int
 		break;
 	default:
 		if (pcnet32_debug & NETIF_MSG_PROBE)
-			printk(KERN_INFO PFX
-			       "PCnet version %#x, no PCnet32 chip.\n",
-			       chip_version);
+			pr_info("PCnet version %#x, no PCnet32 chip\n",
+				chip_version);
 		goto err_release_region;
 	}
 
@@ -1721,7 +1668,7 @@ pcnet32_probe1(unsigned long ioaddr, int
 	dev = alloc_etherdev(sizeof(*lp));
 	if (!dev) {
 		if (pcnet32_debug & NETIF_MSG_PROBE)
-			printk(KERN_ERR PFX "Memory allocation failed.\n");
+			pr_err("Memory allocation failed\n");
 		ret = -ENOMEM;
 		goto err_release_region;
 	}
@@ -1730,7 +1677,7 @@ pcnet32_probe1(unsigned long ioaddr, int
 		SET_NETDEV_DEV(dev, &pdev->dev);
 
 	if (pcnet32_debug & NETIF_MSG_PROBE)
-		printk(KERN_INFO PFX "%s at %#3lx,", chipname, ioaddr);
+		pr_info("%s at %#3lx,", chipname, ioaddr);
 
 	/* In most chips, after a chip reset, the ethernet address is read from the
 	 * station address PROM at the base address and programmed into the
@@ -1755,9 +1702,8 @@ pcnet32_probe1(unsigned long ioaddr, int
 	    !is_valid_ether_addr(dev->dev_addr)) {
 		if (is_valid_ether_addr(promaddr)) {
 			if (pcnet32_debug & NETIF_MSG_PROBE) {
-				printk(" warning: CSR address invalid,\n");
-				printk(KERN_INFO
-				       "    using instead PROM address of");
+				pr_cont(" warning: CSR address invalid,\n");
+				pr_info("    using instead PROM address of");
 			}
 			memcpy(dev->dev_addr, promaddr, 6);
 		}
@@ -1769,54 +1715,54 @@ pcnet32_probe1(unsigned long ioaddr, int
 		memset(dev->dev_addr, 0, ETH_ALEN);
 
 	if (pcnet32_debug & NETIF_MSG_PROBE) {
-		printk(" %pM", dev->dev_addr);
+		pr_cont(" %pM", dev->dev_addr);
 
 		/* Version 0x2623 and 0x2624 */
 		if (((chip_version + 1) & 0xfffe) == 0x2624) {
 			i = a->read_csr(ioaddr, 80) & 0x0C00;	/* Check tx_start_pt */
-			printk(KERN_INFO "    tx_start_pt(0x%04x):", i);
+			pr_info("    tx_start_pt(0x%04x):", i);
 			switch (i >> 10) {
 			case 0:
-				printk(KERN_CONT "  20 bytes,");
+				pr_cont("  20 bytes,");
 				break;
 			case 1:
-				printk(KERN_CONT "  64 bytes,");
+				pr_cont("  64 bytes,");
 				break;
 			case 2:
-				printk(KERN_CONT " 128 bytes,");
+				pr_cont(" 128 bytes,");
 				break;
 			case 3:
-				printk(KERN_CONT "~220 bytes,");
+				pr_cont("~220 bytes,");
 				break;
 			}
 			i = a->read_bcr(ioaddr, 18);	/* Check Burst/Bus control */
-			printk(KERN_CONT " BCR18(%x):", i & 0xffff);
+			pr_cont(" BCR18(%x):", i & 0xffff);
 			if (i & (1 << 5))
-				printk(KERN_CONT "BurstWrEn ");
+				pr_cont("BurstWrEn ");
 			if (i & (1 << 6))
-				printk(KERN_CONT "BurstRdEn ");
+				pr_cont("BurstRdEn ");
 			if (i & (1 << 7))
-				printk(KERN_CONT "DWordIO ");
+				pr_cont("DWordIO ");
 			if (i & (1 << 11))
-				printk(KERN_CONT "NoUFlow ");
+				pr_cont("NoUFlow ");
 			i = a->read_bcr(ioaddr, 25);
-			printk(KERN_INFO "    SRAMSIZE=0x%04x,", i << 8);
+			pr_info("    SRAMSIZE=0x%04x,", i << 8);
 			i = a->read_bcr(ioaddr, 26);
-			printk(KERN_CONT " SRAM_BND=0x%04x,", i << 8);
+			pr_cont(" SRAM_BND=0x%04x,", i << 8);
 			i = a->read_bcr(ioaddr, 27);
 			if (i & (1 << 14))
-				printk(KERN_CONT "LowLatRx");
+				pr_cont("LowLatRx");
 		}
 	}
 
 	dev->base_addr = ioaddr;
 	lp = netdev_priv(dev);
 	/* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */
-	if ((lp->init_block =
-	     pci_alloc_consistent(pdev, sizeof(*lp->init_block), &lp->init_dma_addr)) == NULL) {
+	lp->init_block = pci_alloc_consistent(pdev, sizeof(*lp->init_block),
+					      &lp->init_dma_addr);
+	if (!lp->init_block) {
 		if (pcnet32_debug & NETIF_MSG_PROBE)
-			printk(KERN_ERR PFX
-			       "Consistent memory allocation failed.\n");
+			pr_err("Consistent memory allocation failed\n");
 		ret = -ENOMEM;
 		goto err_free_netdev;
 	}
@@ -1890,7 +1836,7 @@ pcnet32_probe1(unsigned long ioaddr, int
 	if (pdev) {		/* use the IRQ provided by PCI */
 		dev->irq = pdev->irq;
 		if (pcnet32_debug & NETIF_MSG_PROBE)
-			printk(" assigned IRQ %d.\n", dev->irq);
+			pr_cont(" assigned IRQ %d\n", dev->irq);
 	} else {
 		unsigned long irq_mask = probe_irq_on();
 
@@ -1906,12 +1852,12 @@ pcnet32_probe1(unsigned long ioaddr, int
 		dev->irq = probe_irq_off(irq_mask);
 		if (!dev->irq) {
 			if (pcnet32_debug & NETIF_MSG_PROBE)
-				printk(", failed to detect IRQ line.\n");
+				pr_cont(", failed to detect IRQ line\n");
 			ret = -ENODEV;
 			goto err_free_ring;
 		}
 		if (pcnet32_debug & NETIF_MSG_PROBE)
-			printk(", probed IRQ %d.\n", dev->irq);
+			pr_cont(", probed IRQ %d\n", dev->irq);
 	}
 
 	/* Set the mii phy_id so that we can query the link state */
@@ -1935,14 +1881,12 @@ pcnet32_probe1(unsigned long ioaddr, int
 			lp->phymask |= (1 << i);
 			lp->mii_if.phy_id = i;
 			if (pcnet32_debug & NETIF_MSG_PROBE)
-				printk(KERN_INFO PFX
-				       "Found PHY %04x:%04x at address %d.\n",
-				       id1, id2, i);
+				pr_info("Found PHY %04x:%04x at address %d\n",
+					id1, id2, i);
 		}
 		lp->a.write_bcr(ioaddr, 33, (lp->mii_if.phy_id) << 5);
-		if (lp->phycount > 1) {
+		if (lp->phycount > 1)
 			lp->options |= PCNET32_PORT_MII;
-		}
 	}
 
 	init_timer(&lp->watchdog_timer);
@@ -1966,7 +1910,7 @@ pcnet32_probe1(unsigned long ioaddr, int
 	}
 
 	if (pcnet32_debug & NETIF_MSG_PROBE)
-		printk(KERN_INFO "%s: registered as %s\n", dev->name, lp->name);
+		pr_info("%s: registered as %s\n", dev->name, lp->name);
 	cards_found++;
 
 	/* enable LED writes */
@@ -1995,10 +1939,7 @@ static int pcnet32_alloc_ring(struct net
 					   lp->tx_ring_size,
 					   &lp->tx_ring_dma_addr);
 	if (lp->tx_ring == NULL) {
-		if (netif_msg_drv(lp))
-			printk(KERN_ERR PFX
-			       "%s: Consistent memory allocation failed.\n",
-			       name);
+		netif_err(lp, drv, dev, "Consistent memory allocation failed\n");
 		return -ENOMEM;
 	}
 
@@ -2007,46 +1948,35 @@ static int pcnet32_alloc_ring(struct net
 					   lp->rx_ring_size,
 					   &lp->rx_ring_dma_addr);
 	if (lp->rx_ring == NULL) {
-		if (netif_msg_drv(lp))
-			printk(KERN_ERR PFX
-			       "%s: Consistent memory allocation failed.\n",
-			       name);
+		netif_err(lp, drv, dev, "Consistent memory allocation failed\n");
 		return -ENOMEM;
 	}
 
 	lp->tx_dma_addr = kcalloc(lp->tx_ring_size, sizeof(dma_addr_t),
 				  GFP_ATOMIC);
 	if (!lp->tx_dma_addr) {
-		if (netif_msg_drv(lp))
-			printk(KERN_ERR PFX
-			       "%s: Memory allocation failed.\n", name);
+		netif_err(lp, drv, dev, "Memory allocation failed\n");
 		return -ENOMEM;
 	}
 
 	lp->rx_dma_addr = kcalloc(lp->rx_ring_size, sizeof(dma_addr_t),
 				  GFP_ATOMIC);
 	if (!lp->rx_dma_addr) {
-		if (netif_msg_drv(lp))
-			printk(KERN_ERR PFX
-			       "%s: Memory allocation failed.\n", name);
+		netif_err(lp, drv, dev, "Memory allocation failed\n");
 		return -ENOMEM;
 	}
 
 	lp->tx_skbuff = kcalloc(lp->tx_ring_size, sizeof(struct sk_buff *),
 				GFP_ATOMIC);
 	if (!lp->tx_skbuff) {
-		if (netif_msg_drv(lp))
-			printk(KERN_ERR PFX
-			       "%s: Memory allocation failed.\n", name);
+		netif_err(lp, drv, dev, "Memory allocation failed\n");
 		return -ENOMEM;
 	}
 
 	lp->rx_skbuff = kcalloc(lp->rx_ring_size, sizeof(struct sk_buff *),
 				GFP_ATOMIC);
 	if (!lp->rx_skbuff) {
-		if (netif_msg_drv(lp))
-			printk(KERN_ERR PFX
-			       "%s: Memory allocation failed.\n", name);
+		netif_err(lp, drv, dev, "Memory allocation failed\n");
 		return -ENOMEM;
 	}
 
@@ -2115,12 +2045,11 @@ static int pcnet32_open(struct net_devic
 	/* switch pcnet32 to 32bit mode */
 	lp->a.write_bcr(ioaddr, 20, 2);
 
-	if (netif_msg_ifup(lp))
-		printk(KERN_DEBUG
-		       "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n",
-		       dev->name, dev->irq, (u32) (lp->tx_ring_dma_addr),
-		       (u32) (lp->rx_ring_dma_addr),
-		       (u32) (lp->init_dma_addr));
+	netif_printk(lp, ifup, KERN_DEBUG, dev,
+		     "%s() irq %d tx/rx rings %#x/%#x init %#x\n",
+		     __func__, dev->irq, (u32) (lp->tx_ring_dma_addr),
+		     (u32) (lp->rx_ring_dma_addr),
+		     (u32) (lp->init_dma_addr));
 
 	/* set/reset autoselect bit */
 	val = lp->a.read_bcr(ioaddr, 2) & ~2;
@@ -2155,10 +2084,8 @@ static int pcnet32_open(struct net_devic
 	     pdev->subsystem_device == PCI_SUBDEVICE_ID_AT_2701FX)) {
 		if (lp->options & PCNET32_PORT_ASEL) {
 			lp->options = PCNET32_PORT_FD | PCNET32_PORT_100;
-			if (netif_msg_link(lp))
-				printk(KERN_DEBUG
-				       "%s: Setting 100Mb-Full Duplex.\n",
-				       dev->name);
+			netif_printk(lp, link, KERN_DEBUG, dev,
+				     "Setting 100Mb-Full Duplex\n");
 		}
 	}
 	if (lp->phycount < 2) {
@@ -2246,9 +2173,7 @@ static int pcnet32_open(struct net_devic
 			}
 		}
 		lp->mii_if.phy_id = first_phy;
-		if (netif_msg_link(lp))
-			printk(KERN_INFO "%s: Using PHY number %d.\n",
-			       dev->name, first_phy);
+		netif_info(lp, link, dev, "Using PHY number %d\n", first_phy);
 	}
 
 #ifdef DO_DXSUFLO
@@ -2295,18 +2220,17 @@ static int pcnet32_open(struct net_devic
 	 */
 	lp->a.write_csr(ioaddr, CSR0, CSR0_NORMAL);
 
-	if (netif_msg_ifup(lp))
-		printk(KERN_DEBUG
-		       "%s: pcnet32 open after %d ticks, init block %#x csr0 %4.4x.\n",
-		       dev->name, i,
-		       (u32) (lp->init_dma_addr),
-		       lp->a.read_csr(ioaddr, CSR0));
+	netif_printk(lp, ifup, KERN_DEBUG, dev,
+		     "pcnet32 open after %d ticks, init block %#x csr0 %4.4x\n",
+		     i,
+		     (u32) (lp->init_dma_addr),
+		     lp->a.read_csr(ioaddr, CSR0));
 
 	spin_unlock_irqrestore(&lp->lock, flags);
 
 	return 0;		/* Always succeed */
 
-      err_free_ring:
+err_free_ring:
 	/* free any allocated skbuffs */
 	pcnet32_purge_rx_ring(dev);
 
@@ -2316,7 +2240,7 @@ static int pcnet32_open(struct net_devic
 	 */
 	lp->a.write_bcr(ioaddr, 20, 4);
 
-      err_free_irq:
+err_free_irq:
 	spin_unlock_irqrestore(&lp->lock, flags);
 	free_irq(dev->irq, dev);
 	return rc;
@@ -2367,14 +2291,12 @@ static int pcnet32_init_ring(struct net_
 	for (i = 0; i < lp->rx_ring_size; i++) {
 		struct sk_buff *rx_skbuff = lp->rx_skbuff[i];
 		if (rx_skbuff == NULL) {
-			if (!
-			    (rx_skbuff = lp->rx_skbuff[i] =
-			     dev_alloc_skb(PKT_BUF_SKB))) {
-				/* there is not much, we can do at this point */
-				if (netif_msg_drv(lp))
-					printk(KERN_ERR
-					       "%s: pcnet32_init_ring dev_alloc_skb failed.\n",
-					       dev->name);
+			lp->rx_skbuff[i] = dev_alloc_skb(PKT_BUF_SKB);
+			rx_skbuff = lp->rx_skbuff[i];
+			if (!rx_skbuff) {
+				/* there is not much we can do at this point */
+				netif_err(lp, drv, dev, "%s dev_alloc_skb failed\n",
+					  __func__);
 				return -1;
 			}
 			skb_reserve(rx_skbuff, NET_IP_ALIGN);
@@ -2424,10 +2346,9 @@ static void pcnet32_restart(struct net_d
 		if (lp->a.read_csr(ioaddr, CSR0) & CSR0_STOP)
 			break;
 
-	if (i >= 100 && netif_msg_drv(lp))
-		printk(KERN_ERR
-		       "%s: pcnet32_restart timed out waiting for stop.\n",
-		       dev->name);
+	if (i >= 100)
+		netif_err(lp, drv, dev, "%s timed out waiting for stop\n",
+			  __func__);
 
 	pcnet32_purge_tx_ring(dev);
 	if (pcnet32_init_ring(dev))
@@ -2451,8 +2372,7 @@ static void pcnet32_tx_timeout(struct ne
 	spin_lock_irqsave(&lp->lock, flags);
 	/* Transmitter timeout, serious problems. */
 	if (pcnet32_debug & NETIF_MSG_DRV)
-		printk(KERN_ERR
-		       "%s: transmit timed out, status %4.4x, resetting.\n",
+		pr_err("%s: transmit timed out, status %4.4x, resetting\n",
 		       dev->name, lp->a.read_csr(ioaddr, CSR0));
 	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);
 	dev->stats.tx_errors++;
@@ -2495,11 +2415,9 @@ static netdev_tx_t pcnet32_start_xmit(st
 
 	spin_lock_irqsave(&lp->lock, flags);
 
-	if (netif_msg_tx_queued(lp)) {
-		printk(KERN_DEBUG
-		       "%s: pcnet32_start_xmit() called, csr0 %4.4x.\n",
-		       dev->name, lp->a.read_csr(ioaddr, CSR0));
-	}
+	netif_printk(lp, tx_queued, KERN_DEBUG, dev,
+		     "%s() called, csr0 %4.4x\n",
+		     __func__, lp->a.read_csr(ioaddr, CSR0));
 
 	/* Default status -- will not enable Successful-TxDone
 	 * interrupt when that option is available to us.
@@ -2558,16 +2476,14 @@ pcnet32_interrupt(int irq, void *dev_id)
 
 	csr0 = lp->a.read_csr(ioaddr, CSR0);
 	while ((csr0 & 0x8f00) && --boguscnt >= 0) {
-		if (csr0 == 0xffff) {
+		if (csr0 == 0xffff)
 			break;	/* PCMCIA remove happened */
-		}
 		/* Acknowledge all of the current interrupt sources ASAP. */
 		lp->a.write_csr(ioaddr, CSR0, csr0 & ~0x004f);
 
-		if (netif_msg_intr(lp))
-			printk(KERN_DEBUG
-			       "%s: interrupt  csr0=%#2.2x new csr=%#2.2x.\n",
-			       dev->name, csr0, lp->a.read_csr(ioaddr, CSR0));
+		netif_printk(lp, intr, KERN_DEBUG, dev,
+			     "interrupt  csr0=%#2.2x new csr=%#2.2x\n",
+			     csr0, lp->a.read_csr(ioaddr, CSR0));
 
 		/* Log misc errors. */
 		if (csr0 & 0x4000)
@@ -2587,10 +2503,8 @@ pcnet32_interrupt(int irq, void *dev_id)
 			dev->stats.rx_errors++;	/* Missed a Rx frame. */
 		}
 		if (csr0 & 0x0800) {
-			if (netif_msg_drv(lp))
-				printk(KERN_ERR
-				       "%s: Bus master arbitration failure, status %4.4x.\n",
-				       dev->name, csr0);
+			netif_err(lp, drv, dev, "Bus master arbitration failure, status %4.4x\n",
+				  csr0);
 			/* unlike for the lance, there is no restart needed */
 		}
 		if (napi_schedule_prep(&lp->napi)) {
@@ -2606,9 +2520,9 @@ pcnet32_interrupt(int irq, void *dev_id)
 		csr0 = lp->a.read_csr(ioaddr, CSR0);
 	}
 
-	if (netif_msg_intr(lp))
-		printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n",
-		       dev->name, lp->a.read_csr(ioaddr, CSR0));
+	netif_printk(lp, intr, KERN_DEBUG, dev,
+		     "exiting interrupt, csr0=%#4.4x\n",
+		     lp->a.read_csr(ioaddr, CSR0));
 
 	spin_unlock(&lp->lock);
 
@@ -2630,10 +2544,9 @@ static int pcnet32_close(struct net_devi
 
 	dev->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
 
-	if (netif_msg_ifdown(lp))
-		printk(KERN_DEBUG
-		       "%s: Shutting down ethercard, status was %2.2x.\n",
-		       dev->name, lp->a.read_csr(ioaddr, CSR0));
+	netif_printk(lp, ifdown, KERN_DEBUG, dev,
+		     "Shutting down ethercard, status was %2.2x\n",
+		     lp->a.read_csr(ioaddr, CSR0));
 
 	/* We stop the PCNET32 here -- it occasionally polls memory if we don't. */
 	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);
@@ -2677,7 +2590,7 @@ static void pcnet32_load_multicast(struc
 	struct pcnet32_private *lp = netdev_priv(dev);
 	volatile struct pcnet32_init_block *ib = lp->init_block;
 	volatile __le16 *mcast_table = (__le16 *)ib->filter;
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	unsigned long ioaddr = dev->base_addr;
 	char *addrs;
 	int i;
@@ -2698,9 +2611,8 @@ static void pcnet32_load_multicast(struc
 	ib->filter[1] = 0;
 
 	/* Add addresses */
-	for (i = 0; i < dev->mc_count; i++) {
+	netdev_for_each_mc_addr(dmi, dev) {
 		addrs = dmi->dmi_addr;
-		dmi = dmi->next;
 
 		/* multicast address? */
 		if (!(*addrs & 1))
@@ -2730,9 +2642,7 @@ static void pcnet32_set_multicast_list(s
 	csr15 = lp->a.read_csr(ioaddr, CSR15);
 	if (dev->flags & IFF_PROMISC) {
 		/* Log any net taps. */
-		if (netif_msg_hw(lp))
-			printk(KERN_INFO "%s: Promiscuous mode enabled.\n",
-			       dev->name);
+		netif_info(lp, hw, dev, "Promiscuous mode enabled\n");
 		lp->init_block->mode =
 		    cpu_to_le16(0x8000 | (lp->options & PCNET32_PORT_PORTSEL) <<
 				7);
@@ -2819,10 +2729,8 @@ static int pcnet32_check_otherphy(struct
 			mii.phy_id = i;
 			if (mii_link_ok(&mii)) {
 				/* found PHY with active link */
-				if (netif_msg_link(lp))
-					printk(KERN_INFO
-					       "%s: Using PHY number %d.\n",
-					       dev->name, i);
+				netif_info(lp, link, dev, "Using PHY number %d\n",
+					   i);
 
 				/* isolate inactive phy */
 				bmcr =
@@ -2868,8 +2776,7 @@ static void pcnet32_check_media(struct n
 	if (!curr_link) {
 		if (prev_link || verbose) {
 			netif_carrier_off(dev);
-			if (netif_msg_link(lp))
-				printk(KERN_INFO "%s: link down\n", dev->name);
+			netif_info(lp, link, dev, "link down\n");
 		}
 		if (lp->phycount > 1) {
 			curr_link = pcnet32_check_otherphy(dev);
@@ -2881,12 +2788,11 @@ static void pcnet32_check_media(struct n
 			if (netif_msg_link(lp)) {
 				struct ethtool_cmd ecmd;
 				mii_ethtool_gset(&lp->mii_if, &ecmd);
-				printk(KERN_INFO
-				       "%s: link up, %sMbps, %s-duplex\n",
-				       dev->name,
-				       (ecmd.speed == SPEED_100) ? "100" : "10",
-				       (ecmd.duplex ==
-					DUPLEX_FULL) ? "full" : "half");
+				netdev_info(dev, "link up, %sMbps, %s-duplex\n",
+					    (ecmd.speed == SPEED_100)
+					    ? "100" : "10",
+					    (ecmd.duplex == DUPLEX_FULL)
+					    ? "full" : "half");
 			}
 			bcr9 = lp->a.read_bcr(dev->base_addr, 9);
 			if ((bcr9 & (1 << 0)) != lp->mii_if.full_duplex) {
@@ -2897,8 +2803,7 @@ static void pcnet32_check_media(struct n
 				lp->a.write_bcr(dev->base_addr, 9, bcr9);
 			}
 		} else {
-			if (netif_msg_link(lp))
-				printk(KERN_INFO "%s: link up\n", dev->name);
+			netif_info(lp, link, dev, "link up\n");
 		}
 	}
 }
@@ -3010,7 +2915,7 @@ MODULE_LICENSE("GPL");
 
 static int __init pcnet32_init_module(void)
 {
-	printk(KERN_INFO "%s", version);
+	pr_info("%s", version);
 
 	pcnet32_debug = netif_msg_init(debug, PCNET32_MSG_DEFAULT);
 
@@ -3026,7 +2931,7 @@ static int __init pcnet32_init_module(vo
 		pcnet32_probe_vlbus(pcnet32_portlist);
 
 	if (cards_found && (pcnet32_debug & NETIF_MSG_PROBE))
-		printk(KERN_INFO PFX "%d cards_found.\n", cards_found);
+		pr_info("%d cards_found\n", cards_found);
 
 	return (pcnet32_have_pci + cards_found) ? 0 : -ENODEV;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/broadcom.c linux-libre-2.6.34-gnu1/drivers/net/phy/broadcom.c
--- linux-libre-2.6.33-gnu1/drivers/net/phy/broadcom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/broadcom.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,9 +18,6 @@
 #include <linux/phy.h>
 #include <linux/brcmphy.h>
 
-#define PHY_ID_BCM50610		0x0143bd60
-#define PHY_ID_BCM50610M	0x0143bd70
-#define PHY_ID_BCM57780		0x03625d90
 
 #define BRCM_PHY_MODEL(phydev) \
 	((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
@@ -823,7 +820,7 @@ static struct phy_driver bcm57780_driver
 };
 
 static struct phy_driver bcmac131_driver = {
-	.phy_id		= 0x0143bc70,
+	.phy_id		= PHY_ID_BCMAC131,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCMAC131",
 	.features	= PHY_BASIC_FEATURES |
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/cicada.c linux-libre-2.6.34-gnu1/drivers/net/phy/cicada.c
--- linux-libre-2.6.33-gnu1/drivers/net/phy/cicada.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/cicada.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #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>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/davicom.c linux-libre-2.6.34-gnu1/drivers/net/phy/davicom.c
--- linux-libre-2.6.33-gnu1/drivers/net/phy/davicom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/davicom.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #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>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/et1011c.c linux-libre-2.6.34-gnu1/drivers/net/phy/et1011c.c
--- linux-libre-2.6.33-gnu1/drivers/net/phy/et1011c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/et1011c.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #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>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/fixed.c linux-libre-2.6.34-gnu1/drivers/net/phy/fixed.c
--- linux-libre-2.6.33-gnu1/drivers/net/phy/fixed.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/fixed.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/phy.h>
 #include <linux/phy_fixed.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #define MII_REGS_NUM 29
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/icplus.c linux-libre-2.6.34-gnu1/drivers/net/phy/icplus.c
--- linux-libre-2.6.33-gnu1/drivers/net/phy/icplus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/icplus.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #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>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/Kconfig linux-libre-2.6.34-gnu1/drivers/net/phy/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/net/phy/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -88,6 +88,11 @@ config LSI_ET1011C_PHY
 	---help---
 	  Supports the LSI ET1011C PHY.
 
+config MICREL_PHY
+	tristate "Driver for Micrel PHYs"
+	---help---
+	  Supports the KSZ9021, VSC8201, KS8001 PHYs.
+
 config FIXED_PHY
 	bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
 	depends on PHYLIB=y
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/lxt.c linux-libre-2.6.34-gnu1/drivers/net/phy/lxt.c
--- linux-libre-2.6.33-gnu1/drivers/net/phy/lxt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/lxt.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #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>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/Makefile linux-libre-2.6.34-gnu1/drivers/net/phy/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/phy/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -20,4 +20,5 @@ obj-$(CONFIG_MDIO_BITBANG)	+= mdio-bitba
 obj-$(CONFIG_MDIO_GPIO)		+= mdio-gpio.o
 obj-$(CONFIG_NATIONAL_PHY)	+= national.o
 obj-$(CONFIG_STE10XP)		+= ste10Xp.o
+obj-$(CONFIG_MICREL_PHY)	+= micrel.o
 obj-$(CONFIG_MDIO_OCTEON)	+= mdio-octeon.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/marvell.c linux-libre-2.6.34-gnu1/drivers/net/phy/marvell.c
--- linux-libre-2.6.33-gnu1/drivers/net/phy/marvell.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/marvell.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #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>
@@ -63,6 +62,7 @@
 #define MII_M1111_HWCFG_MODE_COPPER_RGMII	0xb
 #define MII_M1111_HWCFG_MODE_FIBER_RGMII	0x3
 #define MII_M1111_HWCFG_MODE_SGMII_NO_CLK	0x4
+#define MII_M1111_HWCFG_MODE_COPPER_RTBI	0x9
 #define MII_M1111_HWCFG_FIBER_COPPER_AUTO	0x8000
 #define MII_M1111_HWCFG_FIBER_COPPER_RES	0x2000
 
@@ -269,6 +269,43 @@ static int m88e1111_config_init(struct p
 			return err;
 	}
 
+	if (phydev->interface == PHY_INTERFACE_MODE_RTBI) {
+		temp = phy_read(phydev, MII_M1111_PHY_EXT_CR);
+		if (temp < 0)
+			return temp;
+		temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY);
+		err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp);
+		if (err < 0)
+			return err;
+
+		temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
+		if (temp < 0)
+			return temp;
+		temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES);
+		temp |= 0x7 | MII_M1111_HWCFG_FIBER_COPPER_AUTO;
+		err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
+		if (err < 0)
+			return err;
+
+		/* soft reset */
+		err = phy_write(phydev, MII_BMCR, BMCR_RESET);
+		if (err < 0)
+			return err;
+		do
+			temp = phy_read(phydev, MII_BMCR);
+		while (temp & BMCR_RESET);
+
+		temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
+		if (temp < 0)
+			return temp;
+		temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES);
+		temp |= MII_M1111_HWCFG_MODE_COPPER_RTBI | MII_M1111_HWCFG_FIBER_COPPER_AUTO;
+		err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
+		if (err < 0)
+			return err;
+	}
+
+
 	err = phy_write(phydev, MII_BMCR, BMCR_RESET);
 	if (err < 0)
 		return err;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/mdio-bitbang.c linux-libre-2.6.34-gnu1/drivers/net/phy/mdio-bitbang.c
--- linux-libre-2.6.33-gnu1/drivers/net/phy/mdio-bitbang.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/mdio-bitbang.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 
 #include <linux/module.h>
 #include <linux/mdio-bitbang.h>
-#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/delay.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/mdio-octeon.c linux-libre-2.6.34-gnu1/drivers/net/phy/mdio-octeon.c
--- linux-libre-2.6.33-gnu1/drivers/net/phy/mdio-octeon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/mdio-octeon.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
  * Copyright (C) 2009 Cavium Networks
  */
 
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -87,6 +88,7 @@ static int octeon_mdiobus_write(struct m
 static int __init octeon_mdiobus_probe(struct platform_device *pdev)
 {
 	struct octeon_mdiobus *bus;
+	union cvmx_smix_en smi_en;
 	int i;
 	int err = -ENOENT;
 
@@ -102,6 +104,10 @@ static int __init octeon_mdiobus_probe(s
 	if (!bus->mii_bus)
 		goto err;
 
+	smi_en.u64 = 0;
+	smi_en.s.en = 1;
+	cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64);
+
 	/*
 	 * Standard Octeon evaluation boards don't support phy
 	 * interrupts, we need to poll.
@@ -132,17 +138,22 @@ err_register:
 
 err:
 	devm_kfree(&pdev->dev, bus);
+	smi_en.u64 = 0;
+	cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64);
 	return err;
 }
 
 static int __exit octeon_mdiobus_remove(struct platform_device *pdev)
 {
 	struct octeon_mdiobus *bus;
+	union cvmx_smix_en smi_en;
 
 	bus = dev_get_drvdata(&pdev->dev);
 
 	mdiobus_unregister(bus->mii_bus);
 	mdiobus_free(bus->mii_bus);
+	smi_en.u64 = 0;
+	cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/micrel.c linux-libre-2.6.34-gnu1/drivers/net/phy/micrel.c
--- linux-libre-2.6.33-gnu1/drivers/net/phy/micrel.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/micrel.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,105 @@
+/*
+ * drivers/net/phy/micrel.c
+ *
+ * Driver for Micrel PHYs
+ *
+ * Author: David J. Choi
+ *
+ * Copyright (c) 2010 Micrel, 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.
+ *
+ * Support : ksz9021 , vsc8201, ks8001
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+
+#define	PHY_ID_KSZ9021			0x00221611
+#define	PHY_ID_VSC8201			0x000FC413
+#define	PHY_ID_KS8001			0x0022161A
+
+
+static int kszphy_config_init(struct phy_device *phydev)
+{
+	return 0;
+}
+
+
+static struct phy_driver ks8001_driver = {
+	.phy_id		= PHY_ID_KS8001,
+	.name		= "Micrel KS8001",
+	.phy_id_mask	= 0x00fffff0,
+	.features	= PHY_BASIC_FEATURES,
+	.flags		= PHY_POLL,
+	.config_init	= kszphy_config_init,
+	.config_aneg	= genphy_config_aneg,
+	.read_status	= genphy_read_status,
+	.driver		= { .owner = THIS_MODULE,},
+};
+
+static struct phy_driver vsc8201_driver = {
+	.phy_id		= PHY_ID_VSC8201,
+	.name		= "Micrel VSC8201",
+	.phy_id_mask	= 0x00fffff0,
+	.features	= PHY_BASIC_FEATURES,
+	.flags		= PHY_POLL,
+	.config_init	= kszphy_config_init,
+	.config_aneg	= genphy_config_aneg,
+	.read_status	= genphy_read_status,
+	.driver		= { .owner = THIS_MODULE,},
+};
+
+static struct phy_driver ksz9021_driver = {
+	.phy_id		= PHY_ID_KSZ9021,
+	.phy_id_mask	= 0x000fff10,
+	.name		= "Micrel KSZ9021 Gigabit PHY",
+	.features	= PHY_GBIT_FEATURES | SUPPORTED_Pause,
+	.flags		= PHY_POLL,
+	.config_init	= kszphy_config_init,
+	.config_aneg	= genphy_config_aneg,
+	.read_status	= genphy_read_status,
+	.driver		= { .owner = THIS_MODULE, },
+};
+
+static int __init ksphy_init(void)
+{
+	int ret;
+
+	ret = phy_driver_register(&ks8001_driver);
+	if (ret)
+		goto err1;
+	ret = phy_driver_register(&vsc8201_driver);
+	if (ret)
+		goto err2;
+
+	ret = phy_driver_register(&ksz9021_driver);
+	if (ret)
+		goto err3;
+	return 0;
+
+err3:
+	phy_driver_unregister(&vsc8201_driver);
+err2:
+	phy_driver_unregister(&ks8001_driver);
+err1:
+	return ret;
+}
+
+static void __exit ksphy_exit(void)
+{
+	phy_driver_unregister(&ks8001_driver);
+	phy_driver_unregister(&vsc8201_driver);
+	phy_driver_unregister(&ksz9021_driver);
+}
+
+module_init(ksphy_init);
+module_exit(ksphy_exit);
+
+MODULE_DESCRIPTION("Micrel PHY driver");
+MODULE_AUTHOR("David J. Choi");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/phy.c linux-libre-2.6.34-gnu1/drivers/net/phy/phy.c
--- linux-libre-2.6.33-gnu1/drivers/net/phy/phy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/phy.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #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>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/phy_device.c linux-libre-2.6.34-gnu1/drivers/net/phy/phy_device.c
--- linux-libre-2.6.33-gnu1/drivers/net/phy/phy_device.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/phy_device.c	2010-05-16 17:17:36.000000000 -0400
@@ -277,6 +277,22 @@ int phy_device_register(struct phy_devic
 EXPORT_SYMBOL(phy_device_register);
 
 /**
+ * phy_find_first - finds the first PHY device on the bus
+ * @bus: the target MII bus
+ */
+struct phy_device *phy_find_first(struct mii_bus *bus)
+{
+	int addr;
+
+	for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
+		if (bus->phy_map[addr])
+			return bus->phy_map[addr];
+	}
+	return NULL;
+}
+EXPORT_SYMBOL(phy_find_first);
+
+/**
  * phy_prepare_link - prepares the PHY layer to monitor link status
  * @phydev: target phy_device struct
  * @handler: callback function for link status change notifications
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/qsemi.c linux-libre-2.6.34-gnu1/drivers/net/phy/qsemi.c
--- linux-libre-2.6.33-gnu1/drivers/net/phy/qsemi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/qsemi.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #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>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/phy/smsc.c linux-libre-2.6.34-gnu1/drivers/net/phy/smsc.c
--- linux-libre-2.6.33-gnu1/drivers/net/phy/smsc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/phy/smsc.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 
 #define MII_LAN83C185_ISF 29 /* Interrupt Source Flags */
 #define MII_LAN83C185_IM  30 /* Interrupt Mask */
+#define MII_LAN83C185_CTRL_STATUS 17 /* Mode/Status Register */
 
 #define MII_LAN83C185_ISF_INT1 (1<<1) /* Auto-Negotiation Page Received */
 #define MII_LAN83C185_ISF_INT2 (1<<2) /* Parallel Detection Fault */
@@ -37,8 +38,10 @@
 #define MII_LAN83C185_ISF_INT_ALL (0x0e)
 
 #define MII_LAN83C185_ISF_INT_PHYLIB_EVENTS \
-	(MII_LAN83C185_ISF_INT6 | MII_LAN83C185_ISF_INT4)
+	(MII_LAN83C185_ISF_INT6 | MII_LAN83C185_ISF_INT4 | \
+	 MII_LAN83C185_ISF_INT7)
 
+#define MII_LAN83C185_EDPWRDOWN	(1 << 13) /* EDPWRDOWN */
 
 static int smsc_phy_config_intr(struct phy_device *phydev)
 {
@@ -59,9 +62,23 @@ static int smsc_phy_ack_interrupt(struct
 
 static int smsc_phy_config_init(struct phy_device *phydev)
 {
+	int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
+	if (rc < 0)
+		return rc;
+
+	/* Enable energy detect mode for this SMSC Transceivers */
+	rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS,
+		       rc | MII_LAN83C185_EDPWRDOWN);
+	if (rc < 0)
+		return rc;
+
 	return smsc_phy_ack_interrupt (phydev);
 }
 
+static int lan911x_config_init(struct phy_device *phydev)
+{
+	return smsc_phy_ack_interrupt(phydev);
+}
 
 static struct phy_driver lan83c185_driver = {
 	.phy_id		= 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */
@@ -147,7 +164,7 @@ static struct phy_driver lan911x_int_dri
 	/* basic functions */
 	.config_aneg	= genphy_config_aneg,
 	.read_status	= genphy_read_status,
-	.config_init	= smsc_phy_config_init,
+	.config_init	= lan911x_config_init,
 
 	/* IRQ related */
 	.ack_interrupt	= smsc_phy_ack_interrupt,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/plip.c linux-libre-2.6.34-gnu1/drivers/net/plip.c
--- linux-libre-2.6.33-gnu1/drivers/net/plip.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/plip.c	2010-05-16 17:17:36.000000000 -0400
@@ -94,6 +94,7 @@ static const char version[] = "NET3 PLIP
 #include <linux/fcntl.h>
 #include <linux/interrupt.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/if_ether.h>
 #include <linux/in.h>
 #include <linux/errno.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ppp_async.c linux-libre-2.6.34-gnu1/drivers/net/ppp_async.c
--- linux-libre-2.6.33-gnu1/drivers/net/ppp_async.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ppp_async.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/spinlock.h>
 #include <linux/init.h>
 #include <linux/jiffies.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/string.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ppp_generic.c linux-libre-2.6.34-gnu1/drivers/net/ppp_generic.c
--- linux-libre-2.6.33-gnu1/drivers/net/ppp_generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ppp_generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,7 @@
 #include <linux/stddef.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <net/slhc_vj.h>
 #include <asm/atomic.h>
 
@@ -167,7 +168,7 @@ struct channel {
 	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*/
+	int		speed;		/* speed of the corresponding ppp channel*/
 #endif /* CONFIG_PPP_MULTILINK */
 };
 
@@ -404,6 +405,7 @@ static ssize_t ppp_read(struct file *fil
 	DECLARE_WAITQUEUE(wait, current);
 	ssize_t ret;
 	struct sk_buff *skb = NULL;
+	struct iovec iov;
 
 	ret = count;
 
@@ -447,7 +449,9 @@ static ssize_t ppp_read(struct file *fil
 	if (skb->len > count)
 		goto outf;
 	ret = -EFAULT;
-	if (copy_to_user(buf, skb->data, skb->len))
+	iov.iov_base = buf;
+	iov.iov_len = count;
+	if (skb_copy_datagram_iovec(skb, 0, &iov, skb->len))
 		goto outf;
 	ret = skb->len;
 
@@ -1293,13 +1297,13 @@ ppp_push(struct ppp *ppp)
  */
 static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
 {
-	int	len, totlen;
-	int	i, bits, hdrlen, mtu;
-	int	flen;
-	int	navail,	nfree, nzero;
-	int	nbigger;
-	int	totspeed;
-	int	totfree;
+	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;
@@ -1307,21 +1311,21 @@ static int ppp_mp_explode(struct ppp *pp
 	struct ppp_channel *chan;
 
 	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
+	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);
 		pch->speed = pch->chan->speed;
-		if (pch->avail)	{
+		if (pch->avail) {
 			if (skb_queue_empty(&pch->file.xq) ||
-				!pch->had_frag)	{
+				!pch->had_frag) {
 					if (pch->speed == 0)
 						nzero++;
 					else
@@ -1331,60 +1335,60 @@ static int ppp_mp_explode(struct ppp *pp
 					++nfree;
 					++totfree;
 				}
-			if (!pch->had_frag && i	< ppp->nxchan)
-				ppp->nxchan	= i;
+			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;
 	}
 
 	totlen = len;
-	nbigger	= len %	nfree;
+	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 (len	> 0) {
+	while (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 {
 			pch->avail = 1;
@@ -1393,32 +1397,32 @@ static int ppp_mp_explode(struct ppp *pp
 		/* 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;
+				totspeed -= pch->speed;
 
 			spin_unlock_bh(&pch->downl);
 			pch->avail = 0;
 			totlen = len;
 			totfree--;
 			nfree--;
-			if (--navail ==	0)
+			if (--navail == 0)
 				break;
 			continue;
 		}
 
 		/*
 		*if the channel speed is not set divide
-		*the packet	evenly among the free channels;
+		*the packet evenly among the free channels;
 		*otherwise divide it according to the speed
 		*of the channel we are going to transmit on
 		*/
 		flen = len;
 		if (nfree > 0) {
 			if (pch->speed == 0) {
-				flen = totlen/nfree	;
+				flen = totlen/nfree;
 				if (nbigger > 0) {
 					flen++;
 					nbigger--;
@@ -1436,8 +1440,8 @@ static int ppp_mp_explode(struct ppp *pp
 		}
 
 		/*
-		 *check	if we are on the last channel or
-		 *we exceded the lenght	of the data	to
+		 *check if we are on the last channel or
+		 *we exceded the lenght of the data to
 		 *fragment
 		 */
 		if ((nfree <= 0) || (flen > len))
@@ -1448,29 +1452,29 @@ static int ppp_mp_explode(struct ppp *pp
 		 *above formula will be equal or less than zero.
 		 *Skip the channel in this case
 		 */
-		if (flen <=	0) {
+		if (flen <= 0) {
 			pch->avail = 2;
 			spin_unlock_bh(&pch->downl);
 			continue;
 		}
 
-		mtu	= pch->chan->mtu - hdrlen;
-		if (mtu	< 4)
-			mtu	= 4;
+		mtu = pch->chan->mtu - hdrlen;
+		if (mtu < 4)
+			mtu = 4;
 		if (flen > mtu)
 			flen = mtu;
-		if (flen ==	len)
-			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;
@@ -1483,24 +1487,24 @@ static int ppp_mp_explode(struct ppp *pp
 
 		/* try to send it down the channel */
 		chan = pch->chan;
-		if (!skb_queue_empty(&pch->file.xq)	||
+		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);
 	}
-	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 */
@@ -1566,13 +1570,22 @@ ppp_input(struct ppp_channel *chan, stru
 	struct channel *pch = chan->ppp;
 	int proto;
 
-	if (!pch || skb->len == 0) {
+	if (!pch) {
 		kfree_skb(skb);
 		return;
 	}
 
-	proto = PPP_PROTO(skb);
 	read_lock_bh(&pch->upl);
+	if (!pskb_may_pull(skb, 2)) {
+		kfree_skb(skb);
+		if (pch->ppp) {
+			++pch->ppp->dev->stats.rx_length_errors;
+			ppp_receive_error(pch->ppp);
+		}
+		goto done;
+	}
+
+	proto = PPP_PROTO(skb);
 	if (!pch->ppp || proto >= 0xc000 || proto == PPP_CCPFRAG) {
 		/* put it on the channel queue */
 		skb_queue_tail(&pch->file.rq, skb);
@@ -1584,6 +1597,8 @@ ppp_input(struct ppp_channel *chan, stru
 	} else {
 		ppp_do_recv(pch->ppp, skb, pch);
 	}
+
+done:
 	read_unlock_bh(&pch->upl);
 }
 
@@ -1616,7 +1631,8 @@ ppp_input_error(struct ppp_channel *chan
 static void
 ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
 {
-	if (pskb_may_pull(skb, 2)) {
+	/* note: a 0-length skb is used as an error indication */
+	if (skb->len > 0) {
 #ifdef CONFIG_PPP_MULTILINK
 		/* XXX do channel-level decompression here */
 		if (PPP_PROTO(skb) == PPP_MP)
@@ -1624,15 +1640,10 @@ ppp_receive_frame(struct ppp *ppp, struc
 		else
 #endif /* CONFIG_PPP_MULTILINK */
 			ppp_receive_nonmp_frame(ppp, skb);
-		return;
+	} else {
+		kfree_skb(skb);
+		ppp_receive_error(ppp);
 	}
-
-	if (skb->len > 0)
-		/* note: a 0-length skb is used as an error indication */
-		++ppp->dev->stats.rx_length_errors;
-
-	kfree_skb(skb);
-	ppp_receive_error(ppp);
 }
 
 static void
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/pppol2tp.c linux-libre-2.6.34-gnu1/drivers/net/pppol2tp.c
--- linux-libre-2.6.33-gnu1/drivers/net/pppol2tp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/pppol2tp.c	2010-05-16 17:17:36.000000000 -0400
@@ -756,6 +756,7 @@ static int pppol2tp_recv_core(struct soc
 
 	/* Try to dequeue as many skbs from reorder_q as we can. */
 	pppol2tp_recv_dequeue(session);
+	sock_put(sock);
 
 	return 0;
 
@@ -772,6 +773,7 @@ discard_bad_csum:
 	UDP_INC_STATS_USER(&init_net, UDP_MIB_INERRORS, 0);
 	tunnel->stats.rx_errors++;
 	kfree_skb(skb);
+	sock_put(sock);
 
 	return 0;
 
@@ -1180,7 +1182,8 @@ static int pppol2tp_xmit(struct ppp_chan
 	/* Calculate UDP checksum if configured to do so */
 	if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT)
 		skb->ip_summed = CHECKSUM_NONE;
-	else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
+	else if ((skb_dst(skb) && skb_dst(skb)->dev) &&
+		 (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) {
 		skb->ip_summed = CHECKSUM_COMPLETE;
 		csum = skb_checksum(skb, 0, udp_len, 0);
 		uh->check = csum_tcpudp_magic(inet->inet_saddr,
@@ -1661,6 +1664,7 @@ static int pppol2tp_connect(struct socke
 		if (tunnel_sock == NULL)
 			goto end;
 
+		sock_hold(tunnel_sock);
 		tunnel = tunnel_sock->sk_user_data;
 	} else {
 		tunnel = pppol2tp_tunnel_find(sock_net(sk), sp->pppol2tp.s_tunnel);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/pppox.c linux-libre-2.6.34-gnu1/drivers/net/pppox.c
--- linux-libre-2.6.33-gnu1/drivers/net/pppox.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/pppox.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/string.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
 #include <linux/net.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ppp_synctty.c linux-libre-2.6.34-gnu1/drivers/net/ppp_synctty.c
--- linux-libre-2.6.33-gnu1/drivers/net/ppp_synctty.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ppp_synctty.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,7 @@
 #include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 #define PPP_VERSION	"2.4.2"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ps3_gelic_net.c linux-libre-2.6.34-gnu1/drivers/net/ps3_gelic_net.c
--- linux-libre-2.6.33-gnu1/drivers/net/ps3_gelic_net.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ps3_gelic_net.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
@@ -568,7 +569,7 @@ void gelic_net_set_multi(struct net_devi
 			status);
 
 	if ((netdev->flags & IFF_ALLMULTI) ||
-	    (netdev->mc_count > GELIC_NET_MC_COUNT_MAX)) {
+	    (netdev_mc_count(netdev) > GELIC_NET_MC_COUNT_MAX)) {
 		status = lv1_net_add_multicast_address(bus_id(card),
 						       dev_id(card),
 						       0, 1);
@@ -580,7 +581,7 @@ void gelic_net_set_multi(struct net_devi
 	}
 
 	/* set multicast addresses */
-	for (mc = netdev->mc_list; mc; mc = mc->next) {
+	netdev_for_each_mc_addr(mc, netdev) {
 		addr = 0;
 		p = mc->dmi_addr;
 		for (i = 0; i < ETH_ALEN; i++) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ps3_gelic_wireless.c linux-libre-2.6.34-gnu1/drivers/net/ps3_gelic_wireless.c
--- linux-libre-2.6.33-gnu1/drivers/net/ps3_gelic_wireless.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ps3_gelic_wireless.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
@@ -1389,113 +1390,6 @@ static int gelic_wl_get_mode(struct net_
 	return 0;
 }
 
-#ifdef CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE
-/* SIOCIWFIRSTPRIV */
-static int hex2bin(u8 *str, u8 *bin, unsigned int len)
-{
-	unsigned int i;
-	static unsigned char *hex = "0123456789ABCDEF";
-	unsigned char *p, *q;
-	u8 tmp;
-
-	if (len != WPA_PSK_LEN * 2)
-		return -EINVAL;
-
-	for (i = 0; i < WPA_PSK_LEN * 2; i += 2) {
-		p = strchr(hex, toupper(str[i]));
-		q = strchr(hex, toupper(str[i + 1]));
-		if (!p || !q) {
-			pr_info("%s: unconvertible PSK digit=%d\n",
-				__func__, i);
-			return -EINVAL;
-		}
-		tmp = ((p - hex) << 4) + (q - hex);
-		*bin++ = tmp;
-	}
-	return 0;
-};
-
-static int gelic_wl_priv_set_psk(struct net_device *net_dev,
-				 struct iw_request_info *info,
-				 union iwreq_data *data, char *extra)
-{
-	struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev));
-	unsigned int len;
-	unsigned long irqflag;
-	int ret = 0;
-
-	pr_debug("%s:<- len=%d\n", __func__, data->data.length);
-	len = data->data.length - 1;
-	if (len <= 2)
-		return -EINVAL;
-
-	spin_lock_irqsave(&wl->lock, irqflag);
-	if (extra[0] == '"' && extra[len - 1] == '"') {
-		pr_debug("%s: passphrase mode\n", __func__);
-		/* pass phrase */
-		if (GELIC_WL_EURUS_PSK_MAX_LEN < (len - 2)) {
-			pr_info("%s: passphrase too long\n", __func__);
-			ret = -E2BIG;
-			goto out;
-		}
-		memset(wl->psk, 0, sizeof(wl->psk));
-		wl->psk_len = len - 2;
-		memcpy(wl->psk, &(extra[1]), wl->psk_len);
-		wl->psk_type = GELIC_EURUS_WPA_PSK_PASSPHRASE;
-	} else {
-		ret = hex2bin(extra, wl->psk, len);
-		if (ret)
-			goto out;
-		wl->psk_len = WPA_PSK_LEN;
-		wl->psk_type = GELIC_EURUS_WPA_PSK_BIN;
-	}
-	set_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat);
-out:
-	spin_unlock_irqrestore(&wl->lock, irqflag);
-	pr_debug("%s:->\n", __func__);
-	return ret;
-}
-
-static int gelic_wl_priv_get_psk(struct net_device *net_dev,
-				 struct iw_request_info *info,
-				 union iwreq_data *data, char *extra)
-{
-	struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev));
-	char *p;
-	unsigned long irqflag;
-	unsigned int i;
-
-	pr_debug("%s:<-\n", __func__);
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
-	spin_lock_irqsave(&wl->lock, irqflag);
-	p = extra;
-	if (test_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat)) {
-		if (wl->psk_type == GELIC_EURUS_WPA_PSK_BIN) {
-			for (i = 0; i < wl->psk_len; i++) {
-				sprintf(p, "%02xu", wl->psk[i]);
-				p += 2;
-			}
-			*p = '\0';
-			data->data.length = wl->psk_len * 2;
-		} else {
-			*p++ = '"';
-			memcpy(p, wl->psk, wl->psk_len);
-			p += wl->psk_len;
-			*p++ = '"';
-			*p = '\0';
-			data->data.length = wl->psk_len + 2;
-		}
-	} else
-		/* no psk set */
-		data->data.length = 0;
-	spin_unlock_irqrestore(&wl->lock, irqflag);
-	pr_debug("%s:-> %d\n", __func__, data->data.length);
-	return 0;
-}
-#endif
-
 /* SIOCGIWNICKN */
 static int gelic_wl_get_nick(struct net_device *net_dev,
 				  struct iw_request_info *info,
@@ -1571,8 +1465,10 @@ static int gelic_wl_start_scan(struct ge
 	init_completion(&wl->scan_done);
 	/*
 	 * If we have already a bss list, don't try to get new
+	 * unless we are doing an ESSID scan
 	 */
-	if (!always_scan && wl->scan_stat == GELIC_WL_SCAN_STAT_GOT_LIST) {
+	if ((!essid_len && !always_scan)
+	    && wl->scan_stat == GELIC_WL_SCAN_STAT_GOT_LIST) {
 		pr_debug("%s: already has the list\n", __func__);
 		complete(&wl->scan_done);
 		goto out;
@@ -1673,7 +1569,7 @@ static void gelic_wl_scan_complete_event
 		}
 	}
 
-	/* put them in the newtork_list */
+	/* put them in the network_list */
 	for (i = 0, scan_info_size = 0, scan_info = buf;
 	     scan_info_size < data_len;
 	     i++, scan_info_size += be16_to_cpu(scan_info->size),
@@ -2009,7 +1905,7 @@ static int gelic_wl_do_wpa_setup(struct
 	/* PSK type */
 	wpa->psk_type = cpu_to_be16(wl->psk_type);
 #ifdef DEBUG
-	pr_debug("%s: sec=%s psktype=%s\nn", __func__,
+	pr_debug("%s: sec=%s psktype=%s\n", __func__,
 		 wpasecstr(wpa->security),
 		 (wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ?
 		 "BIN" : "passphrase");
@@ -2019,9 +1915,9 @@ static int gelic_wl_do_wpa_setup(struct
 	 * the debug log because this dumps your precious
 	 * passphrase/key.
 	 */
-	pr_debug("%s: psk=%s\n",
+	pr_debug("%s: psk=%s\n", __func__,
 		 (wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ?
-		 (char *)"N/A" : (char *)wpa->psk);
+		 "N/A" : wpa->psk);
 #endif
 #endif
 	/* issue wpa setup */
@@ -2406,40 +2302,10 @@ static const iw_handler gelic_wl_wext_ha
 	IW_IOCTL(SIOCGIWNICKN)		= gelic_wl_get_nick,
 };
 
-#ifdef CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE
-static struct iw_priv_args gelic_wl_private_args[] =
-{
-	{
-		.cmd = GELIC_WL_PRIV_SET_PSK,
-		.set_args = IW_PRIV_TYPE_CHAR |
-		(GELIC_WL_EURUS_PSK_MAX_LEN + 2),
-		.name = "set_psk"
-	},
-	{
-		.cmd = GELIC_WL_PRIV_GET_PSK,
-		.get_args = IW_PRIV_TYPE_CHAR |
-		(GELIC_WL_EURUS_PSK_MAX_LEN + 2),
-		.name = "get_psk"
-	}
-};
-
-static const iw_handler gelic_wl_private_handler[] =
-{
-	gelic_wl_priv_set_psk,
-	gelic_wl_priv_get_psk,
-};
-#endif
-
 static const struct iw_handler_def gelic_wl_wext_handler_def = {
 	.num_standard		= ARRAY_SIZE(gelic_wl_wext_handler),
 	.standard		= gelic_wl_wext_handler,
 	.get_wireless_stats	= gelic_wl_get_wireless_stats,
-#ifdef CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE
-	.num_private		= ARRAY_SIZE(gelic_wl_private_handler),
-	.num_private_args	= ARRAY_SIZE(gelic_wl_private_args),
-	.private		= gelic_wl_private_handler,
-	.private_args		= gelic_wl_private_args,
-#endif
 };
 
 static struct net_device * __devinit gelic_wl_alloc(struct gelic_card *card)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/qla3xxx.c linux-libre-2.6.34-gnu1/drivers/net/qla3xxx.c
--- linux-libre-2.6.33-gnu1/drivers/net/qla3xxx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/qla3xxx.c	2010-05-16 17:17:36.000000000 -0400
@@ -61,7 +61,7 @@ static int msi;
 module_param(msi, int, 0);
 MODULE_PARM_DESC(msi, "Turn on Message Signaled Interrupts.");
 
-static struct pci_device_id ql3xxx_pci_tbl[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(ql3xxx_pci_tbl) = {
 	{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QL3022_DEVICE_ID)},
 	{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QL3032_DEVICE_ID)},
 	/* required last entry */
@@ -4087,7 +4087,6 @@ static void __devexit ql3xxx_remove(stru
 	struct ql3_adapter *qdev = netdev_priv(ndev);
 
 	unregister_netdev(ndev);
-	qdev = netdev_priv(ndev);
 
 	ql_disable_interrupts(qdev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/qlcnic/Makefile linux-libre-2.6.34-gnu1/drivers/net/qlcnic/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/qlcnic/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/qlcnic/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,8 @@
+#
+# Makefile for Qlogic 1G/10G Ethernet Driver for CNA devices
+#
+
+obj-$(CONFIG_QLCNIC) := qlcnic.o
+
+qlcnic-y := qlcnic_hw.o qlcnic_main.o qlcnic_init.o \
+	qlcnic_ethtool.o qlcnic_ctx.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/qlcnic/qlcnic_ctx.c linux-libre-2.6.34-gnu1/drivers/net/qlcnic/qlcnic_ctx.c
--- linux-libre-2.6.33-gnu1/drivers/net/qlcnic/qlcnic_ctx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/qlcnic/qlcnic_ctx.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,534 @@
+/*
+ * Copyright (C) 2009 - QLogic Corporation.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called "COPYING".
+ *
+ */
+
+#include "qlcnic.h"
+
+static u32
+qlcnic_poll_rsp(struct qlcnic_adapter *adapter)
+{
+	u32 rsp;
+	int timeout = 0;
+
+	do {
+		/* give atleast 1ms for firmware to respond */
+		msleep(1);
+
+		if (++timeout > QLCNIC_OS_CRB_RETRY_COUNT)
+			return QLCNIC_CDRP_RSP_TIMEOUT;
+
+		rsp = QLCRD32(adapter, QLCNIC_CDRP_CRB_OFFSET);
+	} while (!QLCNIC_CDRP_IS_RSP(rsp));
+
+	return rsp;
+}
+
+u32
+qlcnic_issue_cmd(struct qlcnic_adapter *adapter,
+	u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd)
+{
+	u32 rsp;
+	u32 signature;
+	u32 rcode = QLCNIC_RCODE_SUCCESS;
+	struct pci_dev *pdev = adapter->pdev;
+
+	signature = QLCNIC_CDRP_SIGNATURE_MAKE(pci_fn, version);
+
+	/* Acquire semaphore before accessing CRB */
+	if (qlcnic_api_lock(adapter))
+		return QLCNIC_RCODE_TIMEOUT;
+
+	QLCWR32(adapter, QLCNIC_SIGN_CRB_OFFSET, signature);
+	QLCWR32(adapter, QLCNIC_ARG1_CRB_OFFSET, arg1);
+	QLCWR32(adapter, QLCNIC_ARG2_CRB_OFFSET, arg2);
+	QLCWR32(adapter, QLCNIC_ARG3_CRB_OFFSET, arg3);
+	QLCWR32(adapter, QLCNIC_CDRP_CRB_OFFSET, QLCNIC_CDRP_FORM_CMD(cmd));
+
+	rsp = qlcnic_poll_rsp(adapter);
+
+	if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) {
+		dev_err(&pdev->dev, "card response timeout.\n");
+		rcode = QLCNIC_RCODE_TIMEOUT;
+	} else if (rsp == QLCNIC_CDRP_RSP_FAIL) {
+		rcode = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
+		dev_err(&pdev->dev, "failed card response code:0x%x\n",
+				rcode);
+	}
+
+	/* Release semaphore */
+	qlcnic_api_unlock(adapter);
+
+	return rcode;
+}
+
+int
+qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu)
+{
+	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+
+	if (recv_ctx->state == QLCNIC_HOST_CTX_STATE_ACTIVE) {
+		if (qlcnic_issue_cmd(adapter,
+				adapter->ahw.pci_func,
+				QLCHAL_VERSION,
+				recv_ctx->context_id,
+				mtu,
+				0,
+				QLCNIC_CDRP_CMD_SET_MTU)) {
+
+			dev_err(&adapter->pdev->dev, "Failed to set mtu\n");
+			return -EIO;
+		}
+	}
+
+	return 0;
+}
+
+static int
+qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
+{
+	void *addr;
+	struct qlcnic_hostrq_rx_ctx *prq;
+	struct qlcnic_cardrsp_rx_ctx *prsp;
+	struct qlcnic_hostrq_rds_ring *prq_rds;
+	struct qlcnic_hostrq_sds_ring *prq_sds;
+	struct qlcnic_cardrsp_rds_ring *prsp_rds;
+	struct qlcnic_cardrsp_sds_ring *prsp_sds;
+	struct qlcnic_host_rds_ring *rds_ring;
+	struct qlcnic_host_sds_ring *sds_ring;
+
+	dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
+	u64 phys_addr;
+
+	int i, nrds_rings, nsds_rings;
+	size_t rq_size, rsp_size;
+	u32 cap, reg, val;
+	int err;
+
+	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+
+	nrds_rings = adapter->max_rds_rings;
+	nsds_rings = adapter->max_sds_rings;
+
+	rq_size =
+		SIZEOF_HOSTRQ_RX(struct qlcnic_hostrq_rx_ctx, nrds_rings,
+						nsds_rings);
+	rsp_size =
+		SIZEOF_CARDRSP_RX(struct qlcnic_cardrsp_rx_ctx, nrds_rings,
+						nsds_rings);
+
+	addr = pci_alloc_consistent(adapter->pdev,
+				rq_size, &hostrq_phys_addr);
+	if (addr == NULL)
+		return -ENOMEM;
+	prq = (struct qlcnic_hostrq_rx_ctx *)addr;
+
+	addr = pci_alloc_consistent(adapter->pdev,
+			rsp_size, &cardrsp_phys_addr);
+	if (addr == NULL) {
+		err = -ENOMEM;
+		goto out_free_rq;
+	}
+	prsp = (struct qlcnic_cardrsp_rx_ctx *)addr;
+
+	prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr);
+
+	cap = (QLCNIC_CAP0_LEGACY_CONTEXT | QLCNIC_CAP0_LEGACY_MN);
+	cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS);
+
+	prq->capabilities[0] = cpu_to_le32(cap);
+	prq->host_int_crb_mode =
+		cpu_to_le32(QLCNIC_HOST_INT_CRB_MODE_SHARED);
+	prq->host_rds_crb_mode =
+		cpu_to_le32(QLCNIC_HOST_RDS_CRB_MODE_UNIQUE);
+
+	prq->num_rds_rings = cpu_to_le16(nrds_rings);
+	prq->num_sds_rings = cpu_to_le16(nsds_rings);
+	prq->rds_ring_offset = cpu_to_le32(0);
+
+	val = le32_to_cpu(prq->rds_ring_offset) +
+		(sizeof(struct qlcnic_hostrq_rds_ring) * nrds_rings);
+	prq->sds_ring_offset = cpu_to_le32(val);
+
+	prq_rds = (struct qlcnic_hostrq_rds_ring *)(prq->data +
+			le32_to_cpu(prq->rds_ring_offset));
+
+	for (i = 0; i < nrds_rings; i++) {
+
+		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->num_desc);
+		prq_rds[i].ring_kind = cpu_to_le32(i);
+		prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size);
+	}
+
+	prq_sds = (struct qlcnic_hostrq_sds_ring *)(prq->data +
+			le32_to_cpu(prq->sds_ring_offset));
+
+	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 = qlcnic_issue_cmd(adapter,
+			adapter->ahw.pci_func,
+			QLCHAL_VERSION,
+			(u32)(phys_addr >> 32),
+			(u32)(phys_addr & 0xffffffff),
+			rq_size,
+			QLCNIC_CDRP_CMD_CREATE_RX_CTX);
+	if (err) {
+		dev_err(&adapter->pdev->dev,
+			"Failed to create rx ctx in firmware%d\n", err);
+		goto out_free_rsp;
+	}
+
+
+	prsp_rds = ((struct qlcnic_cardrsp_rds_ring *)
+			 &prsp->data[le32_to_cpu(prsp->rds_ring_offset)]);
+
+	for (i = 0; i < le16_to_cpu(prsp->num_rds_rings); i++) {
+		rds_ring = &recv_ctx->rds_rings[i];
+
+		reg = le32_to_cpu(prsp_rds[i].host_producer_crb);
+		rds_ring->crb_rcv_producer = qlcnic_get_ioaddr(adapter,
+				QLCNIC_REG(reg - 0x200));
+	}
+
+	prsp_sds = ((struct qlcnic_cardrsp_sds_ring *)
+			&prsp->data[le32_to_cpu(prsp->sds_ring_offset)]);
+
+	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 = qlcnic_get_ioaddr(adapter,
+				QLCNIC_REG(reg - 0x200));
+
+		reg = le32_to_cpu(prsp_sds[i].interrupt_crb);
+		sds_ring->crb_intr_mask = qlcnic_get_ioaddr(adapter,
+				QLCNIC_REG(reg - 0x200));
+	}
+
+	recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
+	recv_ctx->context_id = le16_to_cpu(prsp->context_id);
+	recv_ctx->virt_port = prsp->virt_port;
+
+out_free_rsp:
+	pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr);
+out_free_rq:
+	pci_free_consistent(adapter->pdev, rq_size, prq, hostrq_phys_addr);
+	return err;
+}
+
+static void
+qlcnic_fw_cmd_destroy_rx_ctx(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+
+	if (qlcnic_issue_cmd(adapter,
+			adapter->ahw.pci_func,
+			QLCHAL_VERSION,
+			recv_ctx->context_id,
+			QLCNIC_DESTROY_CTX_RESET,
+			0,
+			QLCNIC_CDRP_CMD_DESTROY_RX_CTX)) {
+
+		dev_err(&adapter->pdev->dev,
+			"Failed to destroy rx ctx in firmware\n");
+	}
+}
+
+static int
+qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_hostrq_tx_ctx	*prq;
+	struct qlcnic_hostrq_cds_ring	*prq_cds;
+	struct qlcnic_cardrsp_tx_ctx	*prsp;
+	void	*rq_addr, *rsp_addr;
+	size_t	rq_size, rsp_size;
+	u32	temp;
+	int	err;
+	u64	phys_addr;
+	dma_addr_t	rq_phys_addr, rsp_phys_addr;
+	struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring;
+
+	rq_size = SIZEOF_HOSTRQ_TX(struct qlcnic_hostrq_tx_ctx);
+	rq_addr = pci_alloc_consistent(adapter->pdev,
+		rq_size, &rq_phys_addr);
+	if (!rq_addr)
+		return -ENOMEM;
+
+	rsp_size = SIZEOF_CARDRSP_TX(struct qlcnic_cardrsp_tx_ctx);
+	rsp_addr = pci_alloc_consistent(adapter->pdev,
+		rsp_size, &rsp_phys_addr);
+	if (!rsp_addr) {
+		err = -ENOMEM;
+		goto out_free_rq;
+	}
+
+	memset(rq_addr, 0, rq_size);
+	prq = (struct qlcnic_hostrq_tx_ctx *)rq_addr;
+
+	memset(rsp_addr, 0, rsp_size);
+	prsp = (struct qlcnic_cardrsp_tx_ctx *)rsp_addr;
+
+	prq->host_rsp_dma_addr = cpu_to_le64(rsp_phys_addr);
+
+	temp = (QLCNIC_CAP0_LEGACY_CONTEXT | QLCNIC_CAP0_LEGACY_MN |
+					QLCNIC_CAP0_LSO);
+	prq->capabilities[0] = cpu_to_le32(temp);
+
+	prq->host_int_crb_mode =
+		cpu_to_le32(QLCNIC_HOST_INT_CRB_MODE_SHARED);
+
+	prq->interrupt_ctl = 0;
+	prq->msi_index = 0;
+	prq->cmd_cons_dma_addr = cpu_to_le64(tx_ring->hw_cons_phys_addr);
+
+	prq_cds = &prq->cds_ring;
+
+	prq_cds->host_phys_addr = cpu_to_le64(tx_ring->phys_addr);
+	prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc);
+
+	phys_addr = rq_phys_addr;
+	err = qlcnic_issue_cmd(adapter,
+			adapter->ahw.pci_func,
+			QLCHAL_VERSION,
+			(u32)(phys_addr >> 32),
+			((u32)phys_addr & 0xffffffff),
+			rq_size,
+			QLCNIC_CDRP_CMD_CREATE_TX_CTX);
+
+	if (err == QLCNIC_RCODE_SUCCESS) {
+		temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
+		tx_ring->crb_cmd_producer = qlcnic_get_ioaddr(adapter,
+				QLCNIC_REG(temp - 0x200));
+
+		adapter->tx_context_id =
+			le16_to_cpu(prsp->context_id);
+	} else {
+		dev_err(&adapter->pdev->dev,
+			"Failed to create tx ctx in firmware%d\n", err);
+		err = -EIO;
+	}
+
+	pci_free_consistent(adapter->pdev, rsp_size, rsp_addr, rsp_phys_addr);
+
+out_free_rq:
+	pci_free_consistent(adapter->pdev, rq_size, rq_addr, rq_phys_addr);
+
+	return err;
+}
+
+static void
+qlcnic_fw_cmd_destroy_tx_ctx(struct qlcnic_adapter *adapter)
+{
+	if (qlcnic_issue_cmd(adapter,
+			adapter->ahw.pci_func,
+			QLCHAL_VERSION,
+			adapter->tx_context_id,
+			QLCNIC_DESTROY_CTX_RESET,
+			0,
+			QLCNIC_CDRP_CMD_DESTROY_TX_CTX)) {
+
+		dev_err(&adapter->pdev->dev,
+			"Failed to destroy tx ctx in firmware\n");
+	}
+}
+
+int
+qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val)
+{
+
+	if (qlcnic_issue_cmd(adapter,
+			adapter->ahw.pci_func,
+			QLCHAL_VERSION,
+			reg,
+			0,
+			0,
+			QLCNIC_CDRP_CMD_READ_PHY)) {
+
+		return -EIO;
+	}
+
+	return QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
+}
+
+int
+qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val)
+{
+	return qlcnic_issue_cmd(adapter,
+			adapter->ahw.pci_func,
+			QLCHAL_VERSION,
+			reg,
+			val,
+			0,
+			QLCNIC_CDRP_CMD_WRITE_PHY);
+}
+
+int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
+{
+	void *addr;
+	int err;
+	int ring;
+	struct qlcnic_recv_context *recv_ctx;
+	struct qlcnic_host_rds_ring *rds_ring;
+	struct qlcnic_host_sds_ring *sds_ring;
+	struct qlcnic_host_tx_ring *tx_ring;
+
+	struct pci_dev *pdev = adapter->pdev;
+
+	recv_ctx = &adapter->recv_ctx;
+	tx_ring = adapter->tx_ring;
+
+	tx_ring->hw_consumer = (__le32 *)pci_alloc_consistent(pdev, sizeof(u32),
+						&tx_ring->hw_cons_phys_addr);
+	if (tx_ring->hw_consumer == NULL) {
+		dev_err(&pdev->dev, "failed to allocate tx consumer\n");
+		return -ENOMEM;
+	}
+	*(tx_ring->hw_consumer) = 0;
+
+	/* cmd desc ring */
+	addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring),
+			&tx_ring->phys_addr);
+
+	if (addr == NULL) {
+		dev_err(&pdev->dev, "failed to allocate tx desc ring\n");
+		return -ENOMEM;
+	}
+
+	tx_ring->desc_head = (struct cmd_desc_type0 *)addr;
+
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		rds_ring = &recv_ctx->rds_rings[ring];
+		addr = pci_alloc_consistent(adapter->pdev,
+				RCV_DESC_RINGSIZE(rds_ring),
+				&rds_ring->phys_addr);
+		if (addr == NULL) {
+			dev_err(&pdev->dev,
+				"failed to allocate rds ring [%d]\n", ring);
+			err = -ENOMEM;
+			goto err_out_free;
+		}
+		rds_ring->desc_head = (struct rcv_desc *)addr;
+
+	}
+
+	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,
+				"failed to allocate sds ring [%d]\n", ring);
+			err = -ENOMEM;
+			goto err_out_free;
+		}
+		sds_ring->desc_head = (struct status_desc *)addr;
+	}
+
+
+	err = qlcnic_fw_cmd_create_rx_ctx(adapter);
+	if (err)
+		goto err_out_free;
+	err = qlcnic_fw_cmd_create_tx_ctx(adapter);
+	if (err)
+		goto err_out_free;
+
+	set_bit(__QLCNIC_FW_ATTACHED, &adapter->state);
+	return 0;
+
+err_out_free:
+	qlcnic_free_hw_resources(adapter);
+	return err;
+}
+
+void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_recv_context *recv_ctx;
+	struct qlcnic_host_rds_ring *rds_ring;
+	struct qlcnic_host_sds_ring *sds_ring;
+	struct qlcnic_host_tx_ring *tx_ring;
+	int ring;
+
+
+	if (test_and_clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) {
+		qlcnic_fw_cmd_destroy_rx_ctx(adapter);
+		qlcnic_fw_cmd_destroy_tx_ctx(adapter);
+
+		/* Allow dma queues to drain after context reset */
+		msleep(20);
+	}
+
+	recv_ctx = &adapter->recv_ctx;
+
+	tx_ring = adapter->tx_ring;
+	if (tx_ring->hw_consumer != NULL) {
+		pci_free_consistent(adapter->pdev,
+				sizeof(u32),
+				tx_ring->hw_consumer,
+				tx_ring->hw_cons_phys_addr);
+		tx_ring->hw_consumer = NULL;
+	}
+
+	if (tx_ring->desc_head != NULL) {
+		pci_free_consistent(adapter->pdev,
+				TX_DESC_RINGSIZE(tx_ring),
+				tx_ring->desc_head, tx_ring->phys_addr);
+		tx_ring->desc_head = NULL;
+	}
+
+	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),
+					rds_ring->desc_head,
+					rds_ring->phys_addr);
+			rds_ring->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(sds_ring),
+				sds_ring->desc_head,
+				sds_ring->phys_addr);
+			sds_ring->desc_head = NULL;
+		}
+	}
+}
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/qlcnic/qlcnic_ethtool.c linux-libre-2.6.34-gnu1/drivers/net/qlcnic/qlcnic_ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/qlcnic/qlcnic_ethtool.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/qlcnic/qlcnic_ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1032 @@
+/*
+ * Copyright (C) 2009 - QLogic Corporation.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called "COPYING".
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+
+#include "qlcnic.h"
+
+struct qlcnic_stats {
+	char stat_string[ETH_GSTRING_LEN];
+	int sizeof_stat;
+	int stat_offset;
+};
+
+#define QLC_SIZEOF(m) FIELD_SIZEOF(struct qlcnic_adapter, m)
+#define QLC_OFF(m) offsetof(struct qlcnic_adapter, m)
+
+static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
+	{"xmit_called",
+		QLC_SIZEOF(stats.xmitcalled), QLC_OFF(stats.xmitcalled)},
+	{"xmit_finished",
+		QLC_SIZEOF(stats.xmitfinished), QLC_OFF(stats.xmitfinished)},
+	{"rx_dropped",
+		QLC_SIZEOF(stats.rxdropped), QLC_OFF(stats.rxdropped)},
+	{"tx_dropped",
+		QLC_SIZEOF(stats.txdropped), QLC_OFF(stats.txdropped)},
+	{"csummed",
+		QLC_SIZEOF(stats.csummed), QLC_OFF(stats.csummed)},
+	{"rx_pkts",
+		QLC_SIZEOF(stats.rx_pkts), QLC_OFF(stats.rx_pkts)},
+	{"lro_pkts",
+		QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)},
+	{"rx_bytes",
+		QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
+	{"tx_bytes",
+		QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
+	{"lrobytes",
+		QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
+	{"lso_frames",
+		QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
+	{"xmit_on",
+		QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)},
+	{"xmit_off",
+		QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
+	{"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
+		QLC_OFF(stats.skb_alloc_failure)},
+
+};
+
+#define QLCNIC_STATS_LEN	ARRAY_SIZE(qlcnic_gstrings_stats)
+
+static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
+	"Register_Test_on_offline",
+	"Link_Test_on_offline",
+	"Interrupt_Test_offline",
+	"Loopback_Test_offline"
+};
+
+#define QLCNIC_TEST_LEN	ARRAY_SIZE(qlcnic_gstrings_test)
+
+#define QLCNIC_RING_REGS_COUNT	20
+#define QLCNIC_RING_REGS_LEN	(QLCNIC_RING_REGS_COUNT * sizeof(u32))
+#define QLCNIC_MAX_EEPROM_LEN   1024
+
+static const u32 diag_registers[] = {
+	CRB_CMDPEG_STATE,
+	CRB_RCVPEG_STATE,
+	CRB_XG_STATE_P3,
+	CRB_FW_CAPABILITIES_1,
+	ISR_INT_STATE_REG,
+	QLCNIC_CRB_DEV_REF_COUNT,
+	QLCNIC_CRB_DEV_STATE,
+	QLCNIC_CRB_DRV_STATE,
+	QLCNIC_CRB_DRV_SCRATCH,
+	QLCNIC_CRB_DEV_PARTITION_INFO,
+	QLCNIC_CRB_DRV_IDC_VER,
+	QLCNIC_PEG_ALIVE_COUNTER,
+	QLCNIC_PEG_HALT_STATUS1,
+	QLCNIC_PEG_HALT_STATUS2,
+	QLCNIC_CRB_PEG_NET_0+0x3c,
+	QLCNIC_CRB_PEG_NET_1+0x3c,
+	QLCNIC_CRB_PEG_NET_2+0x3c,
+	QLCNIC_CRB_PEG_NET_4+0x3c,
+	-1
+};
+
+static int qlcnic_get_regs_len(struct net_device *dev)
+{
+	return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN;
+}
+
+static int qlcnic_get_eeprom_len(struct net_device *dev)
+{
+	return QLCNIC_FLASH_TOTAL_SIZE;
+}
+
+static void
+qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	u32 fw_major, fw_minor, fw_build;
+
+	fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR);
+	fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR);
+	fw_build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB);
+	sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
+
+	strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+	strlcpy(drvinfo->driver, qlcnic_driver_name, 32);
+	strlcpy(drvinfo->version, QLCNIC_LINUX_VERSIONID, 32);
+}
+
+static int
+qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	int check_sfp_module = 0;
+	u16 pcifn = adapter->ahw.pci_func;
+
+	/* read which mode */
+	if (adapter->ahw.port_type == QLCNIC_GBE) {
+		ecmd->supported = (SUPPORTED_10baseT_Half |
+				   SUPPORTED_10baseT_Full |
+				   SUPPORTED_100baseT_Half |
+				   SUPPORTED_100baseT_Full |
+				   SUPPORTED_1000baseT_Half |
+				   SUPPORTED_1000baseT_Full);
+
+		ecmd->advertising = (ADVERTISED_100baseT_Half |
+				     ADVERTISED_100baseT_Full |
+				     ADVERTISED_1000baseT_Half |
+				     ADVERTISED_1000baseT_Full);
+
+		ecmd->speed = adapter->link_speed;
+		ecmd->duplex = adapter->link_duplex;
+		ecmd->autoneg = adapter->link_autoneg;
+
+	} else if (adapter->ahw.port_type == QLCNIC_XGBE) {
+		u32 val;
+
+		val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
+		if (val == QLCNIC_PORT_MODE_802_3_AP) {
+			ecmd->supported = SUPPORTED_1000baseT_Full;
+			ecmd->advertising = ADVERTISED_1000baseT_Full;
+		} else {
+			ecmd->supported = SUPPORTED_10000baseT_Full;
+			ecmd->advertising = ADVERTISED_10000baseT_Full;
+		}
+
+		if (netif_running(dev) && adapter->has_link_events) {
+			ecmd->speed = adapter->link_speed;
+			ecmd->autoneg = adapter->link_autoneg;
+			ecmd->duplex = adapter->link_duplex;
+			goto skip;
+		}
+
+		val = QLCRD32(adapter, P3_LINK_SPEED_REG(pcifn));
+		ecmd->speed = P3_LINK_SPEED_MHZ *
+			P3_LINK_SPEED_VAL(pcifn, val);
+		ecmd->duplex = DUPLEX_FULL;
+		ecmd->autoneg = AUTONEG_DISABLE;
+	} else
+		return -EIO;
+
+skip:
+	ecmd->phy_address = adapter->physical_port;
+	ecmd->transceiver = XCVR_EXTERNAL;
+
+	switch (adapter->ahw.board_type) {
+	case QLCNIC_BRDTYPE_P3_REF_QG:
+	case QLCNIC_BRDTYPE_P3_4_GB:
+	case QLCNIC_BRDTYPE_P3_4_GB_MM:
+
+		ecmd->supported |= SUPPORTED_Autoneg;
+		ecmd->advertising |= ADVERTISED_Autoneg;
+	case QLCNIC_BRDTYPE_P3_10G_CX4:
+	case QLCNIC_BRDTYPE_P3_10G_CX4_LP:
+	case QLCNIC_BRDTYPE_P3_10000_BASE_T:
+		ecmd->supported |= SUPPORTED_TP;
+		ecmd->advertising |= ADVERTISED_TP;
+		ecmd->port = PORT_TP;
+		ecmd->autoneg =  adapter->link_autoneg;
+		break;
+	case QLCNIC_BRDTYPE_P3_IMEZ:
+	case QLCNIC_BRDTYPE_P3_XG_LOM:
+	case QLCNIC_BRDTYPE_P3_HMEZ:
+		ecmd->supported |= SUPPORTED_MII;
+		ecmd->advertising |= ADVERTISED_MII;
+		ecmd->port = PORT_MII;
+		ecmd->autoneg = AUTONEG_DISABLE;
+		break;
+	case QLCNIC_BRDTYPE_P3_10G_SFP_PLUS:
+	case QLCNIC_BRDTYPE_P3_10G_SFP_CT:
+	case QLCNIC_BRDTYPE_P3_10G_SFP_QT:
+		ecmd->advertising |= ADVERTISED_TP;
+		ecmd->supported |= SUPPORTED_TP;
+		check_sfp_module = netif_running(dev) &&
+			adapter->has_link_events;
+	case QLCNIC_BRDTYPE_P3_10G_XFP:
+		ecmd->supported |= SUPPORTED_FIBRE;
+		ecmd->advertising |= ADVERTISED_FIBRE;
+		ecmd->port = PORT_FIBRE;
+		ecmd->autoneg = AUTONEG_DISABLE;
+		break;
+	case QLCNIC_BRDTYPE_P3_10G_TP:
+		if (adapter->ahw.port_type == QLCNIC_XGBE) {
+			ecmd->autoneg = AUTONEG_DISABLE;
+			ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
+			ecmd->advertising |=
+				(ADVERTISED_FIBRE | ADVERTISED_TP);
+			ecmd->port = PORT_FIBRE;
+			check_sfp_module = netif_running(dev) &&
+				adapter->has_link_events;
+		} else {
+			ecmd->autoneg = AUTONEG_ENABLE;
+			ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
+			ecmd->advertising |=
+				(ADVERTISED_TP | ADVERTISED_Autoneg);
+			ecmd->port = PORT_TP;
+		}
+		break;
+	default:
+		dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
+			adapter->ahw.board_type);
+		return -EIO;
+	}
+
+	if (check_sfp_module) {
+		switch (adapter->module_type) {
+		case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
+		case LINKEVENT_MODULE_OPTICAL_SRLR:
+		case LINKEVENT_MODULE_OPTICAL_LRM:
+		case LINKEVENT_MODULE_OPTICAL_SFP_1G:
+			ecmd->port = PORT_FIBRE;
+			break;
+		case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
+		case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
+		case LINKEVENT_MODULE_TWINAX:
+			ecmd->port = PORT_TP;
+			break;
+		default:
+			ecmd->port = PORT_OTHER;
+		}
+	}
+
+	return 0;
+}
+
+static int
+qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	__u32 status;
+
+	/* read which mode */
+	if (adapter->ahw.port_type == QLCNIC_GBE) {
+		/* autonegotiation */
+		if (qlcnic_fw_cmd_set_phy(adapter,
+			       QLCNIC_NIU_GB_MII_MGMT_ADDR_AUTONEG,
+			       ecmd->autoneg) != 0)
+			return -EIO;
+		else
+			adapter->link_autoneg = ecmd->autoneg;
+
+		if (qlcnic_fw_cmd_query_phy(adapter,
+			      QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+			      &status) != 0)
+			return -EIO;
+
+		switch (ecmd->speed) {
+		case SPEED_10:
+			qlcnic_set_phy_speed(status, 0);
+			break;
+		case SPEED_100:
+			qlcnic_set_phy_speed(status, 1);
+			break;
+		case SPEED_1000:
+			qlcnic_set_phy_speed(status, 2);
+			break;
+		}
+
+		if (ecmd->duplex == DUPLEX_HALF)
+			qlcnic_clear_phy_duplex(status);
+		if (ecmd->duplex == DUPLEX_FULL)
+			qlcnic_set_phy_duplex(status);
+		if (qlcnic_fw_cmd_set_phy(adapter,
+			       QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+			       *((int *)&status)) != 0)
+			return -EIO;
+		else {
+			adapter->link_speed = ecmd->speed;
+			adapter->link_duplex = ecmd->duplex;
+		}
+	} else
+		return -EOPNOTSUPP;
+
+	if (!netif_running(dev))
+		return 0;
+
+	dev->netdev_ops->ndo_stop(dev);
+	return dev->netdev_ops->ndo_open(dev);
+}
+
+static void
+qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct qlcnic_host_sds_ring *sds_ring;
+	u32 *regs_buff = p;
+	int ring, i = 0;
+
+	memset(p, 0, qlcnic_get_regs_len(dev));
+	regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
+	    (adapter->pdev)->device;
+
+	for (i = 0; diag_registers[i] != -1; i++)
+		regs_buff[i] = QLCRD32(adapter, diag_registers[i]);
+
+	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+		return;
+
+	regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
+
+	regs_buff[i++] = 1; /* No. of tx ring */
+	regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
+	regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer);
+
+	regs_buff[i++] = 2; /* No. of rx ring */
+	regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer);
+	regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer);
+
+	regs_buff[i++] = adapter->max_sds_rings;
+
+	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+		sds_ring = &(recv_ctx->sds_rings[ring]);
+		regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
+	}
+}
+
+static u32 qlcnic_test_link(struct net_device *dev)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	u32 val;
+
+	val = QLCRD32(adapter, CRB_XG_STATE_P3);
+	val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
+	return (val == XG_LINK_UP_P3) ? 0 : 1;
+}
+
+static int
+qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+		      u8 *bytes)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	int offset;
+	int ret;
+
+	if (eeprom->len == 0)
+		return -EINVAL;
+
+	eeprom->magic = (adapter->pdev)->vendor |
+			((adapter->pdev)->device << 16);
+	offset = eeprom->offset;
+
+	ret = qlcnic_rom_fast_read_words(adapter, offset, bytes,
+						eeprom->len);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static void
+qlcnic_get_ringparam(struct net_device *dev,
+		struct ethtool_ringparam *ring)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+
+	ring->rx_pending = adapter->num_rxd;
+	ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
+	ring->rx_jumbo_pending += adapter->num_lro_rxd;
+	ring->tx_pending = adapter->num_txd;
+
+	if (adapter->ahw.port_type == QLCNIC_GBE) {
+		ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G;
+		ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_1G;
+	} else {
+		ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G;
+		ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_10G;
+	}
+
+	ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
+
+	ring->rx_mini_max_pending = 0;
+	ring->rx_mini_pending = 0;
+}
+
+static u32
+qlcnic_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
+{
+	u32 num_desc;
+	num_desc = max(val, min);
+	num_desc = min(num_desc, max);
+	num_desc = roundup_pow_of_two(num_desc);
+
+	if (val != num_desc) {
+		printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
+		       qlcnic_driver_name, r_name, num_desc, val);
+	}
+
+	return num_desc;
+}
+
+static int
+qlcnic_set_ringparam(struct net_device *dev,
+		struct ethtool_ringparam *ring)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	u16 max_rcv_desc = MAX_RCV_DESCRIPTORS_10G;
+	u16 max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
+	u16 num_rxd, num_jumbo_rxd, num_txd;
+
+
+	if (ring->rx_mini_pending)
+		return -EOPNOTSUPP;
+
+	if (adapter->ahw.port_type == QLCNIC_GBE) {
+		max_rcv_desc = MAX_RCV_DESCRIPTORS_1G;
+		max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
+	}
+
+	num_rxd = qlcnic_validate_ringparam(ring->rx_pending,
+			MIN_RCV_DESCRIPTORS, max_rcv_desc, "rx");
+
+	num_jumbo_rxd = qlcnic_validate_ringparam(ring->rx_jumbo_pending,
+			MIN_JUMBO_DESCRIPTORS, max_jumbo_desc, "rx jumbo");
+
+	num_txd = qlcnic_validate_ringparam(ring->tx_pending,
+			MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
+
+	if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
+			num_jumbo_rxd == adapter->num_jumbo_rxd)
+		return 0;
+
+	adapter->num_rxd = num_rxd;
+	adapter->num_jumbo_rxd = num_jumbo_rxd;
+	adapter->num_txd = num_txd;
+
+	return qlcnic_reset_context(adapter);
+}
+
+static void
+qlcnic_get_pauseparam(struct net_device *netdev,
+			  struct ethtool_pauseparam *pause)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	int port = adapter->physical_port;
+	__u32 val;
+
+	if (adapter->ahw.port_type == QLCNIC_GBE) {
+		if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
+			return;
+		/* get flow control settings */
+		val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
+		pause->rx_pause = qlcnic_gb_get_rx_flowctl(val);
+		val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
+		switch (port) {
+		case 0:
+			pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val));
+			break;
+		case 1:
+			pause->tx_pause = !(qlcnic_gb_get_gb1_mask(val));
+			break;
+		case 2:
+			pause->tx_pause = !(qlcnic_gb_get_gb2_mask(val));
+			break;
+		case 3:
+		default:
+			pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
+			break;
+		}
+	} else if (adapter->ahw.port_type == QLCNIC_XGBE) {
+		if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
+			return;
+		pause->rx_pause = 1;
+		val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
+		if (port == 0)
+			pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val));
+		else
+			pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val));
+	} else {
+		dev_err(&netdev->dev, "Unknown board type: %x\n",
+					adapter->ahw.port_type);
+	}
+}
+
+static int
+qlcnic_set_pauseparam(struct net_device *netdev,
+			  struct ethtool_pauseparam *pause)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	int port = adapter->physical_port;
+	__u32 val;
+
+	/* read mode */
+	if (adapter->ahw.port_type == QLCNIC_GBE) {
+		if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
+			return -EIO;
+		/* set flow control */
+		val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
+
+		if (pause->rx_pause)
+			qlcnic_gb_rx_flowctl(val);
+		else
+			qlcnic_gb_unset_rx_flowctl(val);
+
+		QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port),
+				val);
+		/* set autoneg */
+		val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
+		switch (port) {
+		case 0:
+			if (pause->tx_pause)
+				qlcnic_gb_unset_gb0_mask(val);
+			else
+				qlcnic_gb_set_gb0_mask(val);
+			break;
+		case 1:
+			if (pause->tx_pause)
+				qlcnic_gb_unset_gb1_mask(val);
+			else
+				qlcnic_gb_set_gb1_mask(val);
+			break;
+		case 2:
+			if (pause->tx_pause)
+				qlcnic_gb_unset_gb2_mask(val);
+			else
+				qlcnic_gb_set_gb2_mask(val);
+			break;
+		case 3:
+		default:
+			if (pause->tx_pause)
+				qlcnic_gb_unset_gb3_mask(val);
+			else
+				qlcnic_gb_set_gb3_mask(val);
+			break;
+		}
+		QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
+	} else if (adapter->ahw.port_type == QLCNIC_XGBE) {
+		if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
+			return -EIO;
+		val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
+		if (port == 0) {
+			if (pause->tx_pause)
+				qlcnic_xg_unset_xg0_mask(val);
+			else
+				qlcnic_xg_set_xg0_mask(val);
+		} else {
+			if (pause->tx_pause)
+				qlcnic_xg_unset_xg1_mask(val);
+			else
+				qlcnic_xg_set_xg1_mask(val);
+		}
+		QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val);
+	} else {
+		dev_err(&netdev->dev, "Unknown board type: %x\n",
+				adapter->ahw.port_type);
+	}
+	return 0;
+}
+
+static int qlcnic_reg_test(struct net_device *dev)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	u32 data_read, data_written;
+
+	data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0));
+	if ((data_read & 0xffff) != adapter->pdev->vendor)
+		return 1;
+
+	data_written = (u32)0xa5a5a5a5;
+
+	QLCWR32(adapter, CRB_SCRATCHPAD_TEST, data_written);
+	data_read = QLCRD32(adapter, CRB_SCRATCHPAD_TEST);
+	if (data_written != data_read)
+		return 1;
+
+	return 0;
+}
+
+static int qlcnic_get_sset_count(struct net_device *dev, int sset)
+{
+	switch (sset) {
+	case ETH_SS_TEST:
+		return QLCNIC_TEST_LEN;
+	case ETH_SS_STATS:
+		return QLCNIC_STATS_LEN;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+#define QLC_ILB_PKT_SIZE 64
+
+static void qlcnic_create_loopback_buff(unsigned char *data)
+{
+	unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00};
+	memset(data, 0x4e, QLC_ILB_PKT_SIZE);
+	memset(data, 0xff, 12);
+	memcpy(data + 12, random_data, sizeof(random_data));
+}
+
+int qlcnic_check_loopback_buff(unsigned char *data)
+{
+	unsigned char buff[QLC_ILB_PKT_SIZE];
+	qlcnic_create_loopback_buff(buff);
+	return memcmp(data, buff, QLC_ILB_PKT_SIZE);
+}
+
+static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
+	struct sk_buff *skb;
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		skb = dev_alloc_skb(QLC_ILB_PKT_SIZE);
+		qlcnic_create_loopback_buff(skb->data);
+		skb_put(skb, QLC_ILB_PKT_SIZE);
+
+		adapter->diag_cnt = 0;
+
+		qlcnic_xmit_frame(skb, adapter->netdev);
+
+		msleep(5);
+
+		qlcnic_process_rcv_ring_diag(sds_ring);
+
+		dev_kfree_skb_any(skb);
+		if (!adapter->diag_cnt)
+			return -1;
+	}
+	return 0;
+}
+
+static int qlcnic_loopback_test(struct net_device *netdev)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	int max_sds_rings = adapter->max_sds_rings;
+	int ret;
+
+	if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+		return -EIO;
+
+	ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
+	if (ret)
+		goto clear_it;
+
+	ret = qlcnic_set_ilb_mode(adapter);
+	if (ret)
+		goto done;
+
+	ret = qlcnic_do_ilb_test(adapter);
+
+	qlcnic_clear_ilb_mode(adapter);
+
+done:
+	qlcnic_diag_free_res(netdev, max_sds_rings);
+
+clear_it:
+	adapter->max_sds_rings = max_sds_rings;
+	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+	return ret;
+}
+
+static int qlcnic_irq_test(struct net_device *netdev)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	int max_sds_rings = adapter->max_sds_rings;
+	int ret;
+
+	if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+		return -EIO;
+
+	ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
+	if (ret)
+		goto clear_it;
+
+	adapter->diag_cnt = 0;
+	ret = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func,
+			QLCHAL_VERSION, adapter->portnum, 0, 0, 0x00000011);
+	if (ret)
+		goto done;
+
+	msleep(10);
+
+	ret = !adapter->diag_cnt;
+
+done:
+	qlcnic_diag_free_res(netdev, max_sds_rings);
+
+clear_it:
+	adapter->max_sds_rings = max_sds_rings;
+	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+	return ret;
+}
+
+static void
+qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
+		     u64 *data)
+{
+	memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
+
+	if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
+		data[2] = qlcnic_irq_test(dev);
+		if (data[2])
+			eth_test->flags |= ETH_TEST_FL_FAILED;
+
+		data[3] = qlcnic_loopback_test(dev);
+		if (data[3])
+			eth_test->flags |= ETH_TEST_FL_FAILED;
+
+	}
+
+	data[0] = qlcnic_reg_test(dev);
+	if (data[0])
+		eth_test->flags |= ETH_TEST_FL_FAILED;
+
+	/* link test */
+	data[1] = (u64) qlcnic_test_link(dev);
+	if (data[1])
+		eth_test->flags |= ETH_TEST_FL_FAILED;
+}
+
+static void
+qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
+{
+	int index;
+
+	switch (stringset) {
+	case ETH_SS_TEST:
+		memcpy(data, *qlcnic_gstrings_test,
+		       QLCNIC_TEST_LEN * ETH_GSTRING_LEN);
+		break;
+	case ETH_SS_STATS:
+		for (index = 0; index < QLCNIC_STATS_LEN; index++) {
+			memcpy(data + index * ETH_GSTRING_LEN,
+			       qlcnic_gstrings_stats[index].stat_string,
+			       ETH_GSTRING_LEN);
+		}
+		break;
+	}
+}
+
+static void
+qlcnic_get_ethtool_stats(struct net_device *dev,
+			     struct ethtool_stats *stats, u64 * data)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	int index;
+
+	for (index = 0; index < QLCNIC_STATS_LEN; index++) {
+		char *p =
+		    (char *)adapter +
+		    qlcnic_gstrings_stats[index].stat_offset;
+		data[index] =
+		    (qlcnic_gstrings_stats[index].sizeof_stat ==
+		     sizeof(u64)) ? *(u64 *)p:(*(u32 *)p);
+	}
+}
+
+static u32 qlcnic_get_tx_csum(struct net_device *dev)
+{
+	return dev->features & NETIF_F_IP_CSUM;
+}
+
+static u32 qlcnic_get_rx_csum(struct net_device *dev)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	return adapter->rx_csum;
+}
+
+static int qlcnic_set_rx_csum(struct net_device *dev, u32 data)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	adapter->rx_csum = !!data;
+	return 0;
+}
+
+static u32 qlcnic_get_tso(struct net_device *dev)
+{
+	return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0;
+}
+
+static int qlcnic_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 qlcnic_blink_led(struct net_device *dev, u32 val)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	int ret;
+
+	ret = qlcnic_config_led(adapter, 1, 0xf);
+	if (ret) {
+		dev_err(&adapter->pdev->dev,
+			"Failed to set LED blink state.\n");
+		return ret;
+	}
+
+	msleep_interruptible(val * 1000);
+
+	ret = qlcnic_config_led(adapter, 0, 0xf);
+	if (ret) {
+		dev_err(&adapter->pdev->dev,
+			"Failed to reset LED blink state.\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void
+qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	u32 wol_cfg;
+
+	wol->supported = 0;
+	wol->wolopts = 0;
+
+	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
+	if (wol_cfg & (1UL << adapter->portnum))
+		wol->supported |= WAKE_MAGIC;
+
+	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
+	if (wol_cfg & (1UL << adapter->portnum))
+		wol->wolopts |= WAKE_MAGIC;
+}
+
+static int
+qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	u32 wol_cfg;
+
+	if (wol->wolopts & ~WAKE_MAGIC)
+		return -EOPNOTSUPP;
+
+	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
+	if (!(wol_cfg & (1 << adapter->portnum)))
+		return -EOPNOTSUPP;
+
+	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
+	if (wol->wolopts & WAKE_MAGIC)
+		wol_cfg |= 1UL << adapter->portnum;
+	else
+		wol_cfg &= ~(1UL << adapter->portnum);
+
+	QLCWR32(adapter, QLCNIC_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
+ * firmware coalescing to default.
+ */
+static int qlcnic_set_intr_coalesce(struct net_device *netdev,
+			struct ethtool_coalesce *ethcoal)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+
+	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+		return -EINVAL;
+
+	/*
+	* Return Error if unsupported values or
+	* unsupported parameters are set.
+	*/
+	if (ethcoal->rx_coalesce_usecs > 0xffff ||
+		ethcoal->rx_max_coalesced_frames > 0xffff ||
+		ethcoal->tx_coalesce_usecs > 0xffff ||
+		ethcoal->tx_max_coalesced_frames > 0xffff ||
+		ethcoal->rx_coalesce_usecs_irq ||
+		ethcoal->rx_max_coalesced_frames_irq ||
+		ethcoal->tx_coalesce_usecs_irq ||
+		ethcoal->tx_max_coalesced_frames_irq ||
+		ethcoal->stats_block_coalesce_usecs ||
+		ethcoal->use_adaptive_rx_coalesce ||
+		ethcoal->use_adaptive_tx_coalesce ||
+		ethcoal->pkt_rate_low ||
+		ethcoal->rx_coalesce_usecs_low ||
+		ethcoal->rx_max_coalesced_frames_low ||
+		ethcoal->tx_coalesce_usecs_low ||
+		ethcoal->tx_max_coalesced_frames_low ||
+		ethcoal->pkt_rate_high ||
+		ethcoal->rx_coalesce_usecs_high ||
+		ethcoal->rx_max_coalesced_frames_high ||
+		ethcoal->tx_coalesce_usecs_high ||
+		ethcoal->tx_max_coalesced_frames_high)
+		return -EINVAL;
+
+	if (!ethcoal->rx_coalesce_usecs ||
+		!ethcoal->rx_max_coalesced_frames) {
+		adapter->coal.flags = QLCNIC_INTR_DEFAULT;
+		adapter->coal.normal.data.rx_time_us =
+			QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
+		adapter->coal.normal.data.rx_packets =
+			QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
+	} else {
+		adapter->coal.flags = 0;
+		adapter->coal.normal.data.rx_time_us =
+		ethcoal->rx_coalesce_usecs;
+		adapter->coal.normal.data.rx_packets =
+		ethcoal->rx_max_coalesced_frames;
+	}
+	adapter->coal.normal.data.tx_time_us = ethcoal->tx_coalesce_usecs;
+	adapter->coal.normal.data.tx_packets =
+	ethcoal->tx_max_coalesced_frames;
+
+	qlcnic_config_intr_coalesce(adapter);
+
+	return 0;
+}
+
+static int qlcnic_get_intr_coalesce(struct net_device *netdev,
+			struct ethtool_coalesce *ethcoal)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+
+	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+		return -EINVAL;
+
+	ethcoal->rx_coalesce_usecs = adapter->coal.normal.data.rx_time_us;
+	ethcoal->tx_coalesce_usecs = adapter->coal.normal.data.tx_time_us;
+	ethcoal->rx_max_coalesced_frames =
+		adapter->coal.normal.data.rx_packets;
+	ethcoal->tx_max_coalesced_frames =
+		adapter->coal.normal.data.tx_packets;
+
+	return 0;
+}
+
+static int qlcnic_set_flags(struct net_device *netdev, u32 data)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	int hw_lro;
+
+	if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO))
+		return -EINVAL;
+
+	ethtool_op_set_flags(netdev, data);
+
+	hw_lro = (data & ETH_FLAG_LRO) ? QLCNIC_LRO_ENABLED : 0;
+
+	if (qlcnic_config_hw_lro(adapter, hw_lro))
+		return -EIO;
+
+	if ((hw_lro == 0) && qlcnic_send_lro_cleanup(adapter))
+		return -EIO;
+
+
+	return 0;
+}
+
+const struct ethtool_ops qlcnic_ethtool_ops = {
+	.get_settings = qlcnic_get_settings,
+	.set_settings = qlcnic_set_settings,
+	.get_drvinfo = qlcnic_get_drvinfo,
+	.get_regs_len = qlcnic_get_regs_len,
+	.get_regs = qlcnic_get_regs,
+	.get_link = ethtool_op_get_link,
+	.get_eeprom_len = qlcnic_get_eeprom_len,
+	.get_eeprom = qlcnic_get_eeprom,
+	.get_ringparam = qlcnic_get_ringparam,
+	.set_ringparam = qlcnic_set_ringparam,
+	.get_pauseparam = qlcnic_get_pauseparam,
+	.set_pauseparam = qlcnic_set_pauseparam,
+	.get_tx_csum = qlcnic_get_tx_csum,
+	.set_tx_csum = ethtool_op_set_tx_csum,
+	.set_sg = ethtool_op_set_sg,
+	.get_tso = qlcnic_get_tso,
+	.set_tso = qlcnic_set_tso,
+	.get_wol = qlcnic_get_wol,
+	.set_wol = qlcnic_set_wol,
+	.self_test = qlcnic_diag_test,
+	.get_strings = qlcnic_get_strings,
+	.get_ethtool_stats = qlcnic_get_ethtool_stats,
+	.get_sset_count = qlcnic_get_sset_count,
+	.get_rx_csum = qlcnic_get_rx_csum,
+	.set_rx_csum = qlcnic_set_rx_csum,
+	.get_coalesce = qlcnic_get_intr_coalesce,
+	.set_coalesce = qlcnic_set_intr_coalesce,
+	.get_flags = ethtool_op_get_flags,
+	.set_flags = qlcnic_set_flags,
+	.phys_id = qlcnic_blink_led,
+};
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/qlcnic/qlcnic.h linux-libre-2.6.34-gnu1/drivers/net/qlcnic/qlcnic.h
--- linux-libre-2.6.33-gnu1/drivers/net/qlcnic/qlcnic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/qlcnic/qlcnic.h	2013-05-03 09:47:49.000000000 -0400
@@ -0,0 +1,1131 @@
+/*
+ * Copyright (C) 2009 - QLogic Corporation.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called "COPYING".
+ *
+ */
+
+#ifndef _QLCNIC_H_
+#define _QLCNIC_H_
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ip.h>
+#include <linux/in.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/firmware.h>
+
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/timer.h>
+
+#include <linux/vmalloc.h>
+
+#include <linux/io.h>
+#include <asm/byteorder.h>
+
+#include "qlcnic_hdr.h"
+
+#define _QLCNIC_LINUX_MAJOR 5
+#define _QLCNIC_LINUX_MINOR 0
+#define _QLCNIC_LINUX_SUBVERSION 0
+#define QLCNIC_LINUX_VERSIONID  "5.0.0"
+
+#define QLCNIC_VERSION_CODE(a, b, c)	(((a) << 24) + ((b) << 16) + (c))
+#define _major(v)	(((v) >> 24) & 0xff)
+#define _minor(v)	(((v) >> 16) & 0xff)
+#define _build(v)	((v) & 0xffff)
+
+/* version in image has weird encoding:
+ *  7:0  - major
+ * 15:8  - minor
+ * 31:16 - build (little endian)
+ */
+#define QLCNIC_DECODE_VERSION(v) \
+	QLCNIC_VERSION_CODE(((v) & 0xff), (((v) >> 8) & 0xff), ((v) >> 16))
+
+#define QLCNIC_NUM_FLASH_SECTORS (64)
+#define QLCNIC_FLASH_SECTOR_SIZE (64 * 1024)
+#define QLCNIC_FLASH_TOTAL_SIZE  (QLCNIC_NUM_FLASH_SECTORS \
+					* QLCNIC_FLASH_SECTOR_SIZE)
+
+#define RCV_DESC_RINGSIZE(rds_ring)	\
+	(sizeof(struct rcv_desc) * (rds_ring)->num_desc)
+#define RCV_BUFF_RINGSIZE(rds_ring)	\
+	(sizeof(struct qlcnic_rx_buffer) * rds_ring->num_desc)
+#define STATUS_DESC_RINGSIZE(sds_ring)	\
+	(sizeof(struct status_desc) * (sds_ring)->num_desc)
+#define TX_BUFF_RINGSIZE(tx_ring)	\
+	(sizeof(struct qlcnic_cmd_buffer) * tx_ring->num_desc)
+#define TX_DESC_RINGSIZE(tx_ring)	\
+	(sizeof(struct cmd_desc_type0) * tx_ring->num_desc)
+
+#define QLCNIC_P3P_A0		0x50
+
+#define QLCNIC_IS_REVISION_P3P(REVISION)     (REVISION >= QLCNIC_P3P_A0)
+
+#define FIRST_PAGE_GROUP_START	0
+#define FIRST_PAGE_GROUP_END	0x100000
+
+#define P3_MAX_MTU                     (9600)
+#define QLCNIC_MAX_ETHERHDR                32 /* This contains some padding */
+
+#define QLCNIC_P3_RX_BUF_MAX_LEN         (QLCNIC_MAX_ETHERHDR + ETH_DATA_LEN)
+#define QLCNIC_P3_RX_JUMBO_BUF_MAX_LEN   (QLCNIC_MAX_ETHERHDR + P3_MAX_MTU)
+#define QLCNIC_CT_DEFAULT_RX_BUF_LEN	2048
+#define QLCNIC_LRO_BUFFER_EXTRA		2048
+
+#define QLCNIC_RX_LRO_BUFFER_LENGTH		(8060)
+
+/* Opcodes to be used with the commands */
+#define TX_ETHER_PKT	0x01
+#define TX_TCP_PKT	0x02
+#define TX_UDP_PKT	0x03
+#define TX_IP_PKT	0x04
+#define TX_TCP_LSO	0x05
+#define TX_TCP_LSO6	0x06
+#define TX_IPSEC	0x07
+#define TX_IPSEC_CMD	0x0a
+#define TX_TCPV6_PKT	0x0b
+#define TX_UDPV6_PKT	0x0c
+
+/* Tx defines */
+#define MAX_BUFFERS_PER_CMD	32
+#define TX_STOP_THRESH		((MAX_SKB_FRAGS >> 2) + 4)
+#define QLCNIC_MAX_TX_TIMEOUTS	2
+
+/*
+ * Following are the states of the Phantom. Phantom will set them and
+ * Host will read to check if the fields are correct.
+ */
+#define PHAN_INITIALIZE_FAILED		0xffff
+#define PHAN_INITIALIZE_COMPLETE	0xff01
+
+/* Host writes the following to notify that it has done the init-handshake */
+#define PHAN_INITIALIZE_ACK		0xf00f
+#define PHAN_PEG_RCV_INITIALIZED	0xff01
+
+#define NUM_RCV_DESC_RINGS	3
+#define NUM_STS_DESC_RINGS	4
+
+#define RCV_RING_NORMAL 0
+#define RCV_RING_JUMBO	1
+#define RCV_RING_LRO	2
+
+#define MIN_CMD_DESCRIPTORS		64
+#define MIN_RCV_DESCRIPTORS		64
+#define MIN_JUMBO_DESCRIPTORS		32
+
+#define MAX_CMD_DESCRIPTORS		1024
+#define MAX_RCV_DESCRIPTORS_1G		4096
+#define MAX_RCV_DESCRIPTORS_10G 	8192
+#define MAX_JUMBO_RCV_DESCRIPTORS_1G	512
+#define MAX_JUMBO_RCV_DESCRIPTORS_10G	1024
+#define MAX_LRO_RCV_DESCRIPTORS		8
+
+#define DEFAULT_RCV_DESCRIPTORS_1G	2048
+#define DEFAULT_RCV_DESCRIPTORS_10G	4096
+
+#define get_next_index(index, length)	\
+	(((index) + 1) & ((length) - 1))
+
+#define MPORT_MULTI_FUNCTION_MODE 0x2222
+
+/*
+ * Following data structures describe the descriptors that will be used.
+ * Added fileds of tcpHdrSize and ipHdrSize, The driver needs to do it only when
+ * we are doing LSO (above the 1500 size packet) only.
+ */
+
+#define FLAGS_VLAN_TAGGED	0x10
+#define FLAGS_VLAN_OOB		0x40
+
+#define qlcnic_set_tx_vlan_tci(cmd_desc, v)	\
+	(cmd_desc)->vlan_TCI = cpu_to_le16(v);
+#define qlcnic_set_cmd_desc_port(cmd_desc, var)	\
+	((cmd_desc)->port_ctxid |= ((var) & 0x0F))
+#define qlcnic_set_cmd_desc_ctxid(cmd_desc, var)	\
+	((cmd_desc)->port_ctxid |= ((var) << 4 & 0xF0))
+
+#define qlcnic_set_tx_port(_desc, _port) \
+	((_desc)->port_ctxid = ((_port) & 0xf) | (((_port) << 4) & 0xf0))
+
+#define qlcnic_set_tx_flags_opcode(_desc, _flags, _opcode) \
+	((_desc)->flags_opcode = \
+	cpu_to_le16(((_flags) & 0x7f) | (((_opcode) & 0x3f) << 7)))
+
+#define qlcnic_set_tx_frags_len(_desc, _frags, _len) \
+	((_desc)->nfrags__length = \
+	cpu_to_le32(((_frags) & 0xff) | (((_len) & 0xffffff) << 8)))
+
+struct cmd_desc_type0 {
+	u8 tcp_hdr_offset;	/* For LSO only */
+	u8 ip_hdr_offset;	/* For LSO only */
+	__le16 flags_opcode;	/* 15:13 unused, 12:7 opcode, 6:0 flags */
+	__le32 nfrags__length;	/* 31:8 total len, 7:0 frag count */
+
+	__le64 addr_buffer2;
+
+	__le16 reference_handle;
+	__le16 mss;
+	u8 port_ctxid;		/* 7:4 ctxid 3:0 port */
+	u8 total_hdr_length;	/* LSO only : MAC+IP+TCP Hdr size */
+	__le16 conn_id;		/* IPSec offoad only */
+
+	__le64 addr_buffer3;
+	__le64 addr_buffer1;
+
+	__le16 buffer_length[4];
+
+	__le64 addr_buffer4;
+
+	__le32 reserved2;
+	__le16 reserved;
+	__le16 vlan_TCI;
+
+} __attribute__ ((aligned(64)));
+
+/* Note: sizeof(rcv_desc) should always be a mutliple of 2 */
+struct rcv_desc {
+	__le16 reference_handle;
+	__le16 reserved;
+	__le32 buffer_length;	/* allocated buffer length (usually 2K) */
+	__le64 addr_buffer;
+};
+
+/* opcode field in status_desc */
+#define QLCNIC_SYN_OFFLOAD	0x03
+#define QLCNIC_RXPKT_DESC  	0x04
+#define QLCNIC_OLD_RXPKT_DESC	0x3f
+#define QLCNIC_RESPONSE_DESC	0x05
+#define QLCNIC_LRO_DESC  	0x12
+
+/* for status field in status_desc */
+#define STATUS_CKSUM_OK		(2)
+
+/* owner bits of status_desc */
+#define STATUS_OWNER_HOST	(0x1ULL << 56)
+#define STATUS_OWNER_PHANTOM	(0x2ULL << 56)
+
+/* Status descriptor:
+   0-3 port, 4-7 status, 8-11 type, 12-27 total_length
+   28-43 reference_handle, 44-47 protocol, 48-52 pkt_offset
+   53-55 desc_cnt, 56-57 owner, 58-63 opcode
+ */
+#define qlcnic_get_sts_port(sts_data)	\
+	((sts_data) & 0x0F)
+#define qlcnic_get_sts_status(sts_data)	\
+	(((sts_data) >> 4) & 0x0F)
+#define qlcnic_get_sts_type(sts_data)	\
+	(((sts_data) >> 8) & 0x0F)
+#define qlcnic_get_sts_totallength(sts_data)	\
+	(((sts_data) >> 12) & 0xFFFF)
+#define qlcnic_get_sts_refhandle(sts_data)	\
+	(((sts_data) >> 28) & 0xFFFF)
+#define qlcnic_get_sts_prot(sts_data)	\
+	(((sts_data) >> 44) & 0x0F)
+#define qlcnic_get_sts_pkt_offset(sts_data)	\
+	(((sts_data) >> 48) & 0x1F)
+#define qlcnic_get_sts_desc_cnt(sts_data)	\
+	(((sts_data) >> 53) & 0x7)
+#define qlcnic_get_sts_opcode(sts_data)	\
+	(((sts_data) >> 58) & 0x03F)
+
+#define qlcnic_get_lro_sts_refhandle(sts_data) 	\
+	((sts_data) & 0x0FFFF)
+#define qlcnic_get_lro_sts_length(sts_data)	\
+	(((sts_data) >> 16) & 0x0FFFF)
+#define qlcnic_get_lro_sts_l2_hdr_offset(sts_data)	\
+	(((sts_data) >> 32) & 0x0FF)
+#define qlcnic_get_lro_sts_l4_hdr_offset(sts_data)	\
+	(((sts_data) >> 40) & 0x0FF)
+#define qlcnic_get_lro_sts_timestamp(sts_data)	\
+	(((sts_data) >> 48) & 0x1)
+#define qlcnic_get_lro_sts_type(sts_data)	\
+	(((sts_data) >> 49) & 0x7)
+#define qlcnic_get_lro_sts_push_flag(sts_data)		\
+	(((sts_data) >> 52) & 0x1)
+#define qlcnic_get_lro_sts_seq_number(sts_data)		\
+	((sts_data) & 0x0FFFFFFFF)
+
+
+struct status_desc {
+	__le64 status_desc_data[2];
+} __attribute__ ((aligned(16)));
+
+/* UNIFIED ROMIMAGE */
+#define QLCNIC_UNI_FW_MIN_SIZE		0xc8000
+#define QLCNIC_UNI_DIR_SECT_PRODUCT_TBL	0x0
+#define QLCNIC_UNI_DIR_SECT_BOOTLD	0x6
+#define QLCNIC_UNI_DIR_SECT_FW		0x7
+
+/*Offsets */
+#define QLCNIC_UNI_CHIP_REV_OFF		10
+#define QLCNIC_UNI_FLAGS_OFF		11
+#define QLCNIC_UNI_BIOS_VERSION_OFF 	12
+#define QLCNIC_UNI_BOOTLD_IDX_OFF	27
+#define QLCNIC_UNI_FIRMWARE_IDX_OFF 	29
+
+struct uni_table_desc{
+	u32	findex;
+	u32	num_entries;
+	u32	entry_size;
+	u32	reserved[5];
+};
+
+struct uni_data_desc{
+	u32	findex;
+	u32	size;
+	u32	reserved[5];
+};
+
+/* Magic number to let user know flash is programmed */
+#define	QLCNIC_BDINFO_MAGIC 0x12345678
+
+#define QLCNIC_BRDTYPE_P3_REF_QG	0x0021
+#define QLCNIC_BRDTYPE_P3_HMEZ		0x0022
+#define QLCNIC_BRDTYPE_P3_10G_CX4_LP	0x0023
+#define QLCNIC_BRDTYPE_P3_4_GB		0x0024
+#define QLCNIC_BRDTYPE_P3_IMEZ		0x0025
+#define QLCNIC_BRDTYPE_P3_10G_SFP_PLUS	0x0026
+#define QLCNIC_BRDTYPE_P3_10000_BASE_T	0x0027
+#define QLCNIC_BRDTYPE_P3_XG_LOM	0x0028
+#define QLCNIC_BRDTYPE_P3_4_GB_MM	0x0029
+#define QLCNIC_BRDTYPE_P3_10G_SFP_CT	0x002a
+#define QLCNIC_BRDTYPE_P3_10G_SFP_QT	0x002b
+#define QLCNIC_BRDTYPE_P3_10G_CX4	0x0031
+#define QLCNIC_BRDTYPE_P3_10G_XFP	0x0032
+#define QLCNIC_BRDTYPE_P3_10G_TP	0x0080
+
+/* Flash memory map */
+#define QLCNIC_BRDCFG_START	0x4000		/* board config */
+#define QLCNIC_BOOTLD_START	0x10000		/* bootld */
+#define QLCNIC_IMAGE_START	0x43000		/* compressed image */
+#define QLCNIC_USER_START	0x3E8000	/* Firmare info */
+
+#define QLCNIC_FW_VERSION_OFFSET	(QLCNIC_USER_START+0x408)
+#define QLCNIC_FW_SIZE_OFFSET		(QLCNIC_USER_START+0x40c)
+#define QLCNIC_FW_SERIAL_NUM_OFFSET	(QLCNIC_USER_START+0x81c)
+#define QLCNIC_BIOS_VERSION_OFFSET	(QLCNIC_USER_START+0x83c)
+
+#define QLCNIC_BRDTYPE_OFFSET		(QLCNIC_BRDCFG_START+0x8)
+#define QLCNIC_FW_MAGIC_OFFSET		(QLCNIC_BRDCFG_START+0x128)
+
+#define QLCNIC_FW_MIN_SIZE		(0x3fffff)
+#define QLCNIC_UNIFIED_ROMIMAGE  	0
+#define QLCNIC_FLASH_ROMIMAGE		1
+#define QLCNIC_UNKNOWN_ROMIMAGE		0xff
+
+#define QLCNIC_UNIFIED_ROMIMAGE_NAME	"/*(DEBLOBBED)*/"
+#define QLCNIC_FLASH_ROMIMAGE_NAME	"flash"
+
+extern char qlcnic_driver_name[];
+
+/* Number of status descriptors to handle per interrupt */
+#define MAX_STATUS_HANDLE	(64)
+
+/*
+ * qlcnic_skb_frag{} is to contain mapping info for each SG list. This
+ * has to be freed when DMA is complete. This is part of qlcnic_tx_buffer{}.
+ */
+struct qlcnic_skb_frag {
+	u64 dma;
+	u64 length;
+};
+
+struct qlcnic_recv_crb {
+	u32 crb_rcv_producer[NUM_RCV_DESC_RINGS];
+	u32 crb_sts_consumer[NUM_STS_DESC_RINGS];
+	u32 sw_int_mask[NUM_STS_DESC_RINGS];
+};
+
+/*    Following defines are for the state of the buffers    */
+#define	QLCNIC_BUFFER_FREE	0
+#define	QLCNIC_BUFFER_BUSY	1
+
+/*
+ * There will be one qlcnic_buffer per skb packet.    These will be
+ * used to save the dma info for pci_unmap_page()
+ */
+struct qlcnic_cmd_buffer {
+	struct sk_buff *skb;
+	struct qlcnic_skb_frag frag_array[MAX_BUFFERS_PER_CMD + 1];
+	u32 frag_count;
+};
+
+/* In rx_buffer, we do not need multiple fragments as is a single buffer */
+struct qlcnic_rx_buffer {
+	struct list_head list;
+	struct sk_buff *skb;
+	u64 dma;
+	u16 ref_handle;
+	u16 state;
+};
+
+/* Board types */
+#define	QLCNIC_GBE	0x01
+#define	QLCNIC_XGBE	0x02
+
+/*
+ * One hardware_context{} per adapter
+ * contains interrupt info as well shared hardware info.
+ */
+struct qlcnic_hardware_context {
+	void __iomem *pci_base0;
+	void __iomem *ocm_win_crb;
+
+	unsigned long pci_len0;
+
+	u32 ocm_win;
+	u32 crb_win;
+
+	rwlock_t crb_lock;
+	struct mutex mem_lock;
+
+	u8 cut_through;
+	u8 revision_id;
+	u8 pci_func;
+	u8 linkup;
+	u16 port_type;
+	u16 board_type;
+};
+
+struct qlcnic_adapter_stats {
+	u64  xmitcalled;
+	u64  xmitfinished;
+	u64  rxdropped;
+	u64  txdropped;
+	u64  csummed;
+	u64  rx_pkts;
+	u64  lro_pkts;
+	u64  rxbytes;
+	u64  txbytes;
+	u64  lrobytes;
+	u64  lso_frames;
+	u64  xmit_on;
+	u64  xmit_off;
+	u64  skb_alloc_failure;
+};
+
+/*
+ * Rcv Descriptor Context. One such per Rcv Descriptor. There may
+ * be one Rcv Descriptor for normal packets, one for jumbo and may be others.
+ */
+struct qlcnic_host_rds_ring {
+	u32 producer;
+	u32 num_desc;
+	u32 dma_size;
+	u32 skb_size;
+	u32 flags;
+	void __iomem *crb_rcv_producer;
+	struct rcv_desc *desc_head;
+	struct qlcnic_rx_buffer *rx_buf_arr;
+	struct list_head free_list;
+	spinlock_t lock;
+	dma_addr_t phys_addr;
+};
+
+struct qlcnic_host_sds_ring {
+	u32 consumer;
+	u32 num_desc;
+	void __iomem *crb_sts_consumer;
+	void __iomem *crb_intr_mask;
+
+	struct status_desc *desc_head;
+	struct qlcnic_adapter *adapter;
+	struct napi_struct napi;
+	struct list_head free_list[NUM_RCV_DESC_RINGS];
+
+	int irq;
+
+	dma_addr_t phys_addr;
+	char name[IFNAMSIZ+4];
+};
+
+struct qlcnic_host_tx_ring {
+	u32 producer;
+	__le32 *hw_consumer;
+	u32 sw_consumer;
+	void __iomem *crb_cmd_producer;
+	u32 num_desc;
+
+	struct netdev_queue *txq;
+
+	struct qlcnic_cmd_buffer *cmd_buf_arr;
+	struct cmd_desc_type0 *desc_head;
+	dma_addr_t phys_addr;
+	dma_addr_t hw_cons_phys_addr;
+};
+
+/*
+ * Receive context. There is one such structure per instance of the
+ * receive processing. Any state information that is relevant to
+ * the receive, and is must be in this structure. The global data may be
+ * present elsewhere.
+ */
+struct qlcnic_recv_context {
+	u32 state;
+	u16 context_id;
+	u16 virt_port;
+
+	struct qlcnic_host_rds_ring *rds_rings;
+	struct qlcnic_host_sds_ring *sds_rings;
+};
+
+/* HW context creation */
+
+#define QLCNIC_OS_CRB_RETRY_COUNT	4000
+#define QLCNIC_CDRP_SIGNATURE_MAKE(pcifn, version) \
+	(((pcifn) & 0xff) | (((version) & 0xff) << 8) | (0xcafe << 16))
+
+#define QLCNIC_CDRP_CMD_BIT		0x80000000
+
+/*
+ * All responses must have the QLCNIC_CDRP_CMD_BIT cleared
+ * in the crb QLCNIC_CDRP_CRB_OFFSET.
+ */
+#define QLCNIC_CDRP_FORM_RSP(rsp)	(rsp)
+#define QLCNIC_CDRP_IS_RSP(rsp)	(((rsp) & QLCNIC_CDRP_CMD_BIT) == 0)
+
+#define QLCNIC_CDRP_RSP_OK		0x00000001
+#define QLCNIC_CDRP_RSP_FAIL		0x00000002
+#define QLCNIC_CDRP_RSP_TIMEOUT 	0x00000003
+
+/*
+ * All commands must have the QLCNIC_CDRP_CMD_BIT set in
+ * the crb QLCNIC_CDRP_CRB_OFFSET.
+ */
+#define QLCNIC_CDRP_FORM_CMD(cmd)	(QLCNIC_CDRP_CMD_BIT | (cmd))
+#define QLCNIC_CDRP_IS_CMD(cmd)	(((cmd) & QLCNIC_CDRP_CMD_BIT) != 0)
+
+#define QLCNIC_CDRP_CMD_SUBMIT_CAPABILITIES     0x00000001
+#define QLCNIC_CDRP_CMD_READ_MAX_RDS_PER_CTX    0x00000002
+#define QLCNIC_CDRP_CMD_READ_MAX_SDS_PER_CTX    0x00000003
+#define QLCNIC_CDRP_CMD_READ_MAX_RULES_PER_CTX  0x00000004
+#define QLCNIC_CDRP_CMD_READ_MAX_RX_CTX         0x00000005
+#define QLCNIC_CDRP_CMD_READ_MAX_TX_CTX         0x00000006
+#define QLCNIC_CDRP_CMD_CREATE_RX_CTX           0x00000007
+#define QLCNIC_CDRP_CMD_DESTROY_RX_CTX          0x00000008
+#define QLCNIC_CDRP_CMD_CREATE_TX_CTX           0x00000009
+#define QLCNIC_CDRP_CMD_DESTROY_TX_CTX          0x0000000a
+#define QLCNIC_CDRP_CMD_SETUP_STATISTICS        0x0000000e
+#define QLCNIC_CDRP_CMD_GET_STATISTICS          0x0000000f
+#define QLCNIC_CDRP_CMD_DELETE_STATISTICS       0x00000010
+#define QLCNIC_CDRP_CMD_SET_MTU                 0x00000012
+#define QLCNIC_CDRP_CMD_READ_PHY		0x00000013
+#define QLCNIC_CDRP_CMD_WRITE_PHY		0x00000014
+#define QLCNIC_CDRP_CMD_READ_HW_REG		0x00000015
+#define QLCNIC_CDRP_CMD_GET_FLOW_CTL		0x00000016
+#define QLCNIC_CDRP_CMD_SET_FLOW_CTL		0x00000017
+#define QLCNIC_CDRP_CMD_READ_MAX_MTU		0x00000018
+#define QLCNIC_CDRP_CMD_READ_MAX_LRO		0x00000019
+#define QLCNIC_CDRP_CMD_CONFIGURE_TOE		0x0000001a
+#define QLCNIC_CDRP_CMD_FUNC_ATTRIB		0x0000001b
+#define QLCNIC_CDRP_CMD_READ_PEXQ_PARAMETERS	0x0000001c
+#define QLCNIC_CDRP_CMD_GET_LIC_CAPABILITIES	0x0000001d
+#define QLCNIC_CDRP_CMD_READ_MAX_LRO_PER_BOARD	0x0000001e
+#define QLCNIC_CDRP_CMD_MAX			0x0000001f
+
+#define QLCNIC_RCODE_SUCCESS		0
+#define QLCNIC_RCODE_TIMEOUT		17
+#define QLCNIC_DESTROY_CTX_RESET	0
+
+/*
+ * Capabilities Announced
+ */
+#define QLCNIC_CAP0_LEGACY_CONTEXT	(1)
+#define QLCNIC_CAP0_LEGACY_MN		(1 << 2)
+#define QLCNIC_CAP0_LSO 		(1 << 6)
+#define QLCNIC_CAP0_JUMBO_CONTIGUOUS	(1 << 7)
+#define QLCNIC_CAP0_LRO_CONTIGUOUS	(1 << 8)
+
+/*
+ * Context state
+ */
+#define QLCHAL_VERSION	1
+
+#define QLCNIC_HOST_CTX_STATE_ACTIVE	2
+
+/*
+ * Rx context
+ */
+
+struct qlcnic_hostrq_sds_ring {
+	__le64 host_phys_addr;	/* Ring base addr */
+	__le32 ring_size;		/* Ring entries */
+	__le16 msi_index;
+	__le16 rsvd;		/* Padding */
+};
+
+struct qlcnic_hostrq_rds_ring {
+	__le64 host_phys_addr;	/* Ring base addr */
+	__le64 buff_size;		/* Packet buffer size */
+	__le32 ring_size;		/* Ring entries */
+	__le32 ring_kind;		/* Class of ring */
+};
+
+struct qlcnic_hostrq_rx_ctx {
+	__le64 host_rsp_dma_addr;	/* Response dma'd here */
+	__le32 capabilities[4];	/* Flag bit vector */
+	__le32 host_int_crb_mode;	/* Interrupt crb usage */
+	__le32 host_rds_crb_mode;	/* RDS crb usage */
+	/* These ring offsets are relative to data[0] below */
+	__le32 rds_ring_offset;	/* Offset to RDS config */
+	__le32 sds_ring_offset;	/* Offset to SDS config */
+	__le16 num_rds_rings;	/* Count of RDS rings */
+	__le16 num_sds_rings;	/* Count of SDS rings */
+	__le16 rsvd1;		/* Padding */
+	__le16 rsvd2;		/* Padding */
+	u8  reserved[128]; 	/* reserve space for future expansion*/
+	/* MUST BE 64-bit aligned.
+	   The following is packed:
+	   - N hostrq_rds_rings
+	   - N hostrq_sds_rings */
+	char data[0];
+};
+
+struct qlcnic_cardrsp_rds_ring{
+	__le32 host_producer_crb;	/* Crb to use */
+	__le32 rsvd1;		/* Padding */
+};
+
+struct qlcnic_cardrsp_sds_ring {
+	__le32 host_consumer_crb;	/* Crb to use */
+	__le32 interrupt_crb;	/* Crb to use */
+};
+
+struct qlcnic_cardrsp_rx_ctx {
+	/* These ring offsets are relative to data[0] below */
+	__le32 rds_ring_offset;	/* Offset to RDS config */
+	__le32 sds_ring_offset;	/* Offset to SDS config */
+	__le32 host_ctx_state;	/* Starting State */
+	__le32 num_fn_per_port;	/* How many PCI fn share the port */
+	__le16 num_rds_rings;	/* Count of RDS rings */
+	__le16 num_sds_rings;	/* Count of SDS rings */
+	__le16 context_id;		/* Handle for context */
+	u8  phys_port;		/* Physical id of port */
+	u8  virt_port;		/* Virtual/Logical id of port */
+	u8  reserved[128];	/* save space for future expansion */
+	/*  MUST BE 64-bit aligned.
+	   The following is packed:
+	   - N cardrsp_rds_rings
+	   - N cardrs_sds_rings */
+	char data[0];
+};
+
+#define SIZEOF_HOSTRQ_RX(HOSTRQ_RX, rds_rings, sds_rings)	\
+	(sizeof(HOSTRQ_RX) + 					\
+	(rds_rings)*(sizeof(struct qlcnic_hostrq_rds_ring)) +		\
+	(sds_rings)*(sizeof(struct qlcnic_hostrq_sds_ring)))
+
+#define SIZEOF_CARDRSP_RX(CARDRSP_RX, rds_rings, sds_rings) 	\
+	(sizeof(CARDRSP_RX) + 					\
+	(rds_rings)*(sizeof(struct qlcnic_cardrsp_rds_ring)) + 		\
+	(sds_rings)*(sizeof(struct qlcnic_cardrsp_sds_ring)))
+
+/*
+ * Tx context
+ */
+
+struct qlcnic_hostrq_cds_ring {
+	__le64 host_phys_addr;	/* Ring base addr */
+	__le32 ring_size;		/* Ring entries */
+	__le32 rsvd;		/* Padding */
+};
+
+struct qlcnic_hostrq_tx_ctx {
+	__le64 host_rsp_dma_addr;	/* Response dma'd here */
+	__le64 cmd_cons_dma_addr;	/*  */
+	__le64 dummy_dma_addr;	/*  */
+	__le32 capabilities[4];	/* Flag bit vector */
+	__le32 host_int_crb_mode;	/* Interrupt crb usage */
+	__le32 rsvd1;		/* Padding */
+	__le16 rsvd2;		/* Padding */
+	__le16 interrupt_ctl;
+	__le16 msi_index;
+	__le16 rsvd3;		/* Padding */
+	struct qlcnic_hostrq_cds_ring cds_ring;	/* Desc of cds ring */
+	u8  reserved[128];	/* future expansion */
+};
+
+struct qlcnic_cardrsp_cds_ring {
+	__le32 host_producer_crb;	/* Crb to use */
+	__le32 interrupt_crb;	/* Crb to use */
+};
+
+struct qlcnic_cardrsp_tx_ctx {
+	__le32 host_ctx_state;	/* Starting state */
+	__le16 context_id;		/* Handle for context */
+	u8  phys_port;		/* Physical id of port */
+	u8  virt_port;		/* Virtual/Logical id of port */
+	struct qlcnic_cardrsp_cds_ring cds_ring;	/* Card cds settings */
+	u8  reserved[128];	/* future expansion */
+};
+
+#define SIZEOF_HOSTRQ_TX(HOSTRQ_TX)	(sizeof(HOSTRQ_TX))
+#define SIZEOF_CARDRSP_TX(CARDRSP_TX)	(sizeof(CARDRSP_TX))
+
+/* CRB */
+
+#define QLCNIC_HOST_RDS_CRB_MODE_UNIQUE	0
+#define QLCNIC_HOST_RDS_CRB_MODE_SHARED	1
+#define QLCNIC_HOST_RDS_CRB_MODE_CUSTOM	2
+#define QLCNIC_HOST_RDS_CRB_MODE_MAX	3
+
+#define QLCNIC_HOST_INT_CRB_MODE_UNIQUE	0
+#define QLCNIC_HOST_INT_CRB_MODE_SHARED	1
+#define QLCNIC_HOST_INT_CRB_MODE_NORX	2
+#define QLCNIC_HOST_INT_CRB_MODE_NOTX	3
+#define QLCNIC_HOST_INT_CRB_MODE_NORXTX	4
+
+
+/* MAC */
+
+#define MC_COUNT_P3	38
+
+#define QLCNIC_MAC_NOOP	0
+#define QLCNIC_MAC_ADD	1
+#define QLCNIC_MAC_DEL	2
+
+struct qlcnic_mac_list_s {
+	struct list_head list;
+	uint8_t mac_addr[ETH_ALEN+2];
+};
+
+/*
+ * Interrupt coalescing defaults. The defaults are for 1500 MTU. It is
+ * adjusted based on configured MTU.
+ */
+#define QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US	3
+#define QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS	256
+#define QLCNIC_DEFAULT_INTR_COALESCE_TX_PACKETS	64
+#define QLCNIC_DEFAULT_INTR_COALESCE_TX_TIME_US	4
+
+#define QLCNIC_INTR_DEFAULT			0x04
+
+union qlcnic_nic_intr_coalesce_data {
+	struct {
+		u16	rx_packets;
+		u16	rx_time_us;
+		u16	tx_packets;
+		u16	tx_time_us;
+	} data;
+	u64		word;
+};
+
+struct qlcnic_nic_intr_coalesce {
+	u16		stats_time_us;
+	u16		rate_sample_time;
+	u16		flags;
+	u16		rsvd_1;
+	u32		low_threshold;
+	u32		high_threshold;
+	union qlcnic_nic_intr_coalesce_data	normal;
+	union qlcnic_nic_intr_coalesce_data	low;
+	union qlcnic_nic_intr_coalesce_data	high;
+	union qlcnic_nic_intr_coalesce_data	irq;
+};
+
+#define QLCNIC_HOST_REQUEST	0x13
+#define QLCNIC_REQUEST		0x14
+
+#define QLCNIC_MAC_EVENT	0x1
+
+#define QLCNIC_IP_UP		2
+#define QLCNIC_IP_DOWN		3
+
+/*
+ * Driver --> Firmware
+ */
+#define QLCNIC_H2C_OPCODE_START 			0
+#define QLCNIC_H2C_OPCODE_CONFIG_RSS			1
+#define QLCNIC_H2C_OPCODE_CONFIG_RSS_TBL		2
+#define QLCNIC_H2C_OPCODE_CONFIG_INTR_COALESCE		3
+#define QLCNIC_H2C_OPCODE_CONFIG_LED			4
+#define QLCNIC_H2C_OPCODE_CONFIG_PROMISCUOUS		5
+#define QLCNIC_H2C_OPCODE_CONFIG_L2_MAC 		6
+#define QLCNIC_H2C_OPCODE_LRO_REQUEST			7
+#define QLCNIC_H2C_OPCODE_GET_SNMP_STATS		8
+#define QLCNIC_H2C_OPCODE_PROXY_START_REQUEST		9
+#define QLCNIC_H2C_OPCODE_PROXY_STOP_REQUEST		10
+#define QLCNIC_H2C_OPCODE_PROXY_SET_MTU 		11
+#define QLCNIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE	12
+#define QLCNIC_H2C_OPCODE_GET_FINGER_PRINT_REQUEST	13
+#define QLCNIC_H2C_OPCODE_INSTALL_LICENSE_REQUEST	14
+#define QLCNIC_H2C_OPCODE_GET_LICENSE_CAPABILITY_REQUEST	15
+#define QLCNIC_H2C_OPCODE_GET_NET_STATS 		16
+#define QLCNIC_H2C_OPCODE_PROXY_UPDATE_P2V		17
+#define QLCNIC_H2C_OPCODE_CONFIG_IPADDR 		18
+#define QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK		19
+#define QLCNIC_H2C_OPCODE_PROXY_STOP_DONE		20
+#define QLCNIC_H2C_OPCODE_GET_LINKEVENT 		21
+#define QLCNIC_C2C_OPCODE				22
+#define QLCNIC_H2C_OPCODE_CONFIG_BRIDGING		23
+#define QLCNIC_H2C_OPCODE_CONFIG_HW_LRO 		24
+#define QLCNIC_H2C_OPCODE_LAST				25
+/*
+ * Firmware --> Driver
+ */
+
+#define QLCNIC_C2H_OPCODE_START 			128
+#define QLCNIC_C2H_OPCODE_CONFIG_RSS_RESPONSE		129
+#define QLCNIC_C2H_OPCODE_CONFIG_RSS_TBL_RESPONSE	130
+#define QLCNIC_C2H_OPCODE_CONFIG_MAC_RESPONSE		131
+#define QLCNIC_C2H_OPCODE_CONFIG_PROMISCUOUS_RESPONSE	132
+#define QLCNIC_C2H_OPCODE_CONFIG_L2_MAC_RESPONSE	133
+#define QLCNIC_C2H_OPCODE_LRO_DELETE_RESPONSE		134
+#define QLCNIC_C2H_OPCODE_LRO_ADD_FAILURE_RESPONSE	135
+#define QLCNIC_C2H_OPCODE_GET_SNMP_STATS		136
+#define QLCNIC_C2H_OPCODE_GET_FINGER_PRINT_REPLY	137
+#define QLCNIC_C2H_OPCODE_INSTALL_LICENSE_REPLY 	138
+#define QLCNIC_C2H_OPCODE_GET_LICENSE_CAPABILITIES_REPLY 139
+#define QLCNIC_C2H_OPCODE_GET_NET_STATS_RESPONSE	140
+#define QLCNIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE	141
+#define QLCNIC_C2H_OPCODE_LAST				142
+
+#define VPORT_MISS_MODE_DROP		0 /* drop all unmatched */
+#define VPORT_MISS_MODE_ACCEPT_ALL	1 /* accept all packets */
+#define VPORT_MISS_MODE_ACCEPT_MULTI	2 /* accept unmatched multicast */
+
+#define QLCNIC_LRO_REQUEST_CLEANUP	4
+
+/* Capabilites received */
+#define QLCNIC_FW_CAPABILITY_BDG		(1 << 8)
+#define QLCNIC_FW_CAPABILITY_FVLANTX		(1 << 9)
+#define QLCNIC_FW_CAPABILITY_HW_LRO		(1 << 10)
+
+/* module types */
+#define LINKEVENT_MODULE_NOT_PRESENT			1
+#define LINKEVENT_MODULE_OPTICAL_UNKNOWN		2
+#define LINKEVENT_MODULE_OPTICAL_SRLR			3
+#define LINKEVENT_MODULE_OPTICAL_LRM			4
+#define LINKEVENT_MODULE_OPTICAL_SFP_1G 		5
+#define LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE	6
+#define LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN	7
+#define LINKEVENT_MODULE_TWINAX 			8
+
+#define LINKSPEED_10GBPS	10000
+#define LINKSPEED_1GBPS 	1000
+#define LINKSPEED_100MBPS	100
+#define LINKSPEED_10MBPS	10
+
+#define LINKSPEED_ENCODED_10MBPS	0
+#define LINKSPEED_ENCODED_100MBPS	1
+#define LINKSPEED_ENCODED_1GBPS 	2
+
+#define LINKEVENT_AUTONEG_DISABLED	0
+#define LINKEVENT_AUTONEG_ENABLED	1
+
+#define LINKEVENT_HALF_DUPLEX		0
+#define LINKEVENT_FULL_DUPLEX		1
+
+#define LINKEVENT_LINKSPEED_MBPS	0
+#define LINKEVENT_LINKSPEED_ENCODED	1
+
+#define AUTO_FW_RESET_ENABLED	0x01
+/* firmware response header:
+ *	63:58 - message type
+ *	57:56 - owner
+ *	55:53 - desc count
+ *	52:48 - reserved
+ *	47:40 - completion id
+ *	39:32 - opcode
+ *	31:16 - error code
+ *	15:00 - reserved
+ */
+#define qlcnic_get_nic_msg_opcode(msg_hdr)	\
+	((msg_hdr >> 32) & 0xFF)
+
+struct qlcnic_fw_msg {
+	union {
+		struct {
+			u64 hdr;
+			u64 body[7];
+		};
+		u64 words[8];
+	};
+};
+
+struct qlcnic_nic_req {
+	__le64 qhdr;
+	__le64 req_hdr;
+	__le64 words[6];
+};
+
+struct qlcnic_mac_req {
+	u8 op;
+	u8 tag;
+	u8 mac_addr[6];
+};
+
+#define QLCNIC_MSI_ENABLED		0x02
+#define QLCNIC_MSIX_ENABLED		0x04
+#define QLCNIC_LRO_ENABLED		0x08
+#define QLCNIC_BRIDGE_ENABLED       	0X10
+#define QLCNIC_DIAG_ENABLED		0x20
+#define QLCNIC_IS_MSI_FAMILY(adapter) \
+	((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
+
+#define MSIX_ENTRIES_PER_ADAPTER	NUM_STS_DESC_RINGS
+#define QLCNIC_MSIX_TBL_SPACE		8192
+#define QLCNIC_PCI_REG_MSIX_TBL 	0x44
+
+#define QLCNIC_NETDEV_WEIGHT	128
+#define QLCNIC_ADAPTER_UP_MAGIC 777
+
+#define __QLCNIC_FW_ATTACHED		0
+#define __QLCNIC_DEV_UP 		1
+#define __QLCNIC_RESETTING		2
+#define __QLCNIC_START_FW 		4
+
+#define QLCNIC_INTERRUPT_TEST		1
+#define QLCNIC_LOOPBACK_TEST		2
+
+struct qlcnic_adapter {
+	struct qlcnic_hardware_context ahw;
+
+	struct net_device *netdev;
+	struct pci_dev *pdev;
+	struct list_head mac_list;
+
+	spinlock_t tx_clean_lock;
+
+	u16 num_txd;
+	u16 num_rxd;
+	u16 num_jumbo_rxd;
+	u16 num_lro_rxd;
+
+	u8 max_rds_rings;
+	u8 max_sds_rings;
+	u8 driver_mismatch;
+	u8 msix_supported;
+	u8 rx_csum;
+	u8 pci_using_dac;
+	u8 portnum;
+	u8 physical_port;
+
+	u8 mc_enabled;
+	u8 max_mc_count;
+	u8 rss_supported;
+	u8 rsrvd1;
+	u8 fw_wait_cnt;
+	u8 fw_fail_cnt;
+	u8 tx_timeo_cnt;
+	u8 need_fw_reset;
+
+	u8 has_link_events;
+	u8 fw_type;
+	u16 tx_context_id;
+	u16 mtu;
+	u16 is_up;
+
+	u16 link_speed;
+	u16 link_duplex;
+	u16 link_autoneg;
+	u16 module_type;
+
+	u32 capabilities;
+	u32 flags;
+	u32 irq;
+	u32 temp;
+
+	u32 int_vec_bit;
+	u32 heartbit;
+
+	u8 dev_state;
+	u8 diag_test;
+	u8 diag_cnt;
+	u8 rsrd1;
+	u16 rsrd2;
+
+	u8 mac_addr[ETH_ALEN];
+
+	struct qlcnic_adapter_stats stats;
+
+	struct qlcnic_recv_context recv_ctx;
+	struct qlcnic_host_tx_ring *tx_ring;
+
+	void __iomem	*tgt_mask_reg;
+	void __iomem	*tgt_status_reg;
+	void __iomem	*crb_int_state_reg;
+	void __iomem	*isr_int_vec;
+
+	struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
+
+	struct delayed_work fw_work;
+
+	struct work_struct  tx_timeout_task;
+
+	struct qlcnic_nic_intr_coalesce coal;
+
+	unsigned long state;
+	__le32 file_prd_off;	/*File fw product offset*/
+	u32 fw_version;
+	const struct firmware *fw;
+};
+
+int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val);
+int qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val);
+
+u32 qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off);
+int qlcnic_hw_write_wx_2M(struct qlcnic_adapter *, ulong off, u32 data);
+int qlcnic_pci_mem_write_2M(struct qlcnic_adapter *, u64 off, u64 data);
+int qlcnic_pci_mem_read_2M(struct qlcnic_adapter *, u64 off, u64 *data);
+
+#define QLCRD32(adapter, off) \
+	(qlcnic_hw_read_wx_2M(adapter, off))
+#define QLCWR32(adapter, off, val) \
+	(qlcnic_hw_write_wx_2M(adapter, off, val))
+
+int qlcnic_pcie_sem_lock(struct qlcnic_adapter *, int, u32);
+void qlcnic_pcie_sem_unlock(struct qlcnic_adapter *, int);
+
+#define qlcnic_rom_lock(a)	\
+	qlcnic_pcie_sem_lock((a), 2, QLCNIC_ROM_LOCK_ID)
+#define qlcnic_rom_unlock(a)	\
+	qlcnic_pcie_sem_unlock((a), 2)
+#define qlcnic_phy_lock(a)	\
+	qlcnic_pcie_sem_lock((a), 3, QLCNIC_PHY_LOCK_ID)
+#define qlcnic_phy_unlock(a)	\
+	qlcnic_pcie_sem_unlock((a), 3)
+#define qlcnic_api_lock(a)	\
+	qlcnic_pcie_sem_lock((a), 5, 0)
+#define qlcnic_api_unlock(a)	\
+	qlcnic_pcie_sem_unlock((a), 5)
+#define qlcnic_sw_lock(a)	\
+	qlcnic_pcie_sem_lock((a), 6, 0)
+#define qlcnic_sw_unlock(a)	\
+	qlcnic_pcie_sem_unlock((a), 6)
+#define crb_win_lock(a)	\
+	qlcnic_pcie_sem_lock((a), 7, QLCNIC_CRB_WIN_LOCK_ID)
+#define crb_win_unlock(a)	\
+	qlcnic_pcie_sem_unlock((a), 7)
+
+int qlcnic_get_board_info(struct qlcnic_adapter *adapter);
+int qlcnic_wol_supported(struct qlcnic_adapter *adapter);
+int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate);
+
+/* Functions from qlcnic_init.c */
+int qlcnic_phantom_init(struct qlcnic_adapter *adapter);
+int qlcnic_load_firmware(struct qlcnic_adapter *adapter);
+int qlcnic_need_fw_reset(struct qlcnic_adapter *adapter);
+void qlcnic_reject_firmware(struct qlcnic_adapter *adapter);
+void qlcnic_release_firmware(struct qlcnic_adapter *adapter);
+int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter);
+
+int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, int addr, int *valp);
+int qlcnic_rom_fast_read_words(struct qlcnic_adapter *adapter, int addr,
+				u8 *bytes, size_t size);
+int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter);
+void qlcnic_free_sw_resources(struct qlcnic_adapter *adapter);
+
+void __iomem *qlcnic_get_ioaddr(struct qlcnic_adapter *, u32);
+
+int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter);
+void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter);
+
+void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter);
+void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter);
+
+int qlcnic_init_firmware(struct qlcnic_adapter *adapter);
+void qlcnic_watchdog_task(struct work_struct *work);
+void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid,
+		struct qlcnic_host_rds_ring *rds_ring);
+int qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max);
+void qlcnic_set_multi(struct net_device *netdev);
+void qlcnic_free_mac_list(struct qlcnic_adapter *adapter);
+int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32);
+int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter);
+int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable);
+int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, u32 ip, int cmd);
+int qlcnic_linkevent_request(struct qlcnic_adapter *adapter, int enable);
+void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup);
+
+int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu);
+int qlcnic_change_mtu(struct net_device *netdev, int new_mtu);
+int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable);
+int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, int enable);
+int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
+void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
+		struct qlcnic_host_tx_ring *tx_ring);
+int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u64 *mac);
+void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter);
+int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter);
+
+/* Functions from qlcnic_main.c */
+int qlcnic_reset_context(struct qlcnic_adapter *);
+u32 qlcnic_issue_cmd(struct qlcnic_adapter *adapter,
+	u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd);
+void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings);
+int qlcnic_diag_alloc_res(struct net_device *netdev, int test);
+int qlcnic_check_loopback_buff(unsigned char *data);
+netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
+void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring);
+
+/*
+ * QLOGIC Board information
+ */
+
+#define QLCNIC_MAX_BOARD_NAME_LEN 100
+struct qlcnic_brdinfo {
+	unsigned short  vendor;
+	unsigned short  device;
+	unsigned short  sub_vendor;
+	unsigned short  sub_device;
+	char short_name[QLCNIC_MAX_BOARD_NAME_LEN];
+};
+
+static const struct qlcnic_brdinfo qlcnic_boards[] = {
+	{0x1077, 0x8020, 0x1077, 0x203,
+		"8200 Series Single Port 10GbE Converged Network Adapter "
+		"(TCP/IP Networking)"},
+	{0x1077, 0x8020, 0x1077, 0x207,
+		"8200 Series Dual Port 10GbE Converged Network Adapter "
+		"(TCP/IP Networking)"},
+	{0x1077, 0x8020, 0x1077, 0x20b,
+		"3200 Series Dual Port 10Gb Intelligent Ethernet Adapter"},
+	{0x1077, 0x8020, 0x1077, 0x20c,
+		"3200 Series Quad Port 1Gb Intelligent Ethernet Adapter"},
+	{0x1077, 0x8020, 0x1077, 0x20f,
+		"3200 Series Single Port 10Gb Intelligent Ethernet Adapter"},
+	{0x1077, 0x8020, 0x0, 0x0, "cLOM8214 1/10GbE Controller"},
+};
+
+#define NUM_SUPPORTED_BOARDS ARRAY_SIZE(qlcnic_boards)
+
+static inline u32 qlcnic_tx_avail(struct qlcnic_host_tx_ring *tx_ring)
+{
+	smp_mb();
+	if (tx_ring->producer < tx_ring->sw_consumer)
+		return tx_ring->sw_consumer - tx_ring->producer;
+	else
+		return tx_ring->sw_consumer + tx_ring->num_desc -
+				tx_ring->producer;
+}
+
+extern const struct ethtool_ops qlcnic_ethtool_ops;
+
+#endif				/* __QLCNIC_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/qlcnic/qlcnic_hdr.h linux-libre-2.6.34-gnu1/drivers/net/qlcnic/qlcnic_hdr.h
--- linux-libre-2.6.33-gnu1/drivers/net/qlcnic/qlcnic_hdr.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/qlcnic/qlcnic_hdr.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,937 @@
+/*
+ * Copyright (C) 2009 - QLogic Corporation.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called "COPYING".
+ *
+ */
+
+#ifndef __QLCNIC_HDR_H_
+#define __QLCNIC_HDR_H_
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+/*
+ * The basic unit of access when reading/writing control registers.
+ */
+
+enum {
+	QLCNIC_HW_H0_CH_HUB_ADR = 0x05,
+	QLCNIC_HW_H1_CH_HUB_ADR = 0x0E,
+	QLCNIC_HW_H2_CH_HUB_ADR = 0x03,
+	QLCNIC_HW_H3_CH_HUB_ADR = 0x01,
+	QLCNIC_HW_H4_CH_HUB_ADR = 0x06,
+	QLCNIC_HW_H5_CH_HUB_ADR = 0x07,
+	QLCNIC_HW_H6_CH_HUB_ADR = 0x08
+};
+
+/*  Hub 0 */
+enum {
+	QLCNIC_HW_MN_CRB_AGT_ADR = 0x15,
+	QLCNIC_HW_MS_CRB_AGT_ADR = 0x25
+};
+
+/*  Hub 1 */
+enum {
+	QLCNIC_HW_PS_CRB_AGT_ADR = 0x73,
+	QLCNIC_HW_SS_CRB_AGT_ADR = 0x20,
+	QLCNIC_HW_RPMX3_CRB_AGT_ADR = 0x0b,
+	QLCNIC_HW_QMS_CRB_AGT_ADR = 0x00,
+	QLCNIC_HW_SQGS0_CRB_AGT_ADR = 0x01,
+	QLCNIC_HW_SQGS1_CRB_AGT_ADR = 0x02,
+	QLCNIC_HW_SQGS2_CRB_AGT_ADR = 0x03,
+	QLCNIC_HW_SQGS3_CRB_AGT_ADR = 0x04,
+	QLCNIC_HW_C2C0_CRB_AGT_ADR = 0x58,
+	QLCNIC_HW_C2C1_CRB_AGT_ADR = 0x59,
+	QLCNIC_HW_C2C2_CRB_AGT_ADR = 0x5a,
+	QLCNIC_HW_RPMX2_CRB_AGT_ADR = 0x0a,
+	QLCNIC_HW_RPMX4_CRB_AGT_ADR = 0x0c,
+	QLCNIC_HW_RPMX7_CRB_AGT_ADR = 0x0f,
+	QLCNIC_HW_RPMX9_CRB_AGT_ADR = 0x12,
+	QLCNIC_HW_SMB_CRB_AGT_ADR = 0x18
+};
+
+/*  Hub 2 */
+enum {
+	QLCNIC_HW_NIU_CRB_AGT_ADR = 0x31,
+	QLCNIC_HW_I2C0_CRB_AGT_ADR = 0x19,
+	QLCNIC_HW_I2C1_CRB_AGT_ADR = 0x29,
+
+	QLCNIC_HW_SN_CRB_AGT_ADR = 0x10,
+	QLCNIC_HW_I2Q_CRB_AGT_ADR = 0x20,
+	QLCNIC_HW_LPC_CRB_AGT_ADR = 0x22,
+	QLCNIC_HW_ROMUSB_CRB_AGT_ADR = 0x21,
+	QLCNIC_HW_QM_CRB_AGT_ADR = 0x66,
+	QLCNIC_HW_SQG0_CRB_AGT_ADR = 0x60,
+	QLCNIC_HW_SQG1_CRB_AGT_ADR = 0x61,
+	QLCNIC_HW_SQG2_CRB_AGT_ADR = 0x62,
+	QLCNIC_HW_SQG3_CRB_AGT_ADR = 0x63,
+	QLCNIC_HW_RPMX1_CRB_AGT_ADR = 0x09,
+	QLCNIC_HW_RPMX5_CRB_AGT_ADR = 0x0d,
+	QLCNIC_HW_RPMX6_CRB_AGT_ADR = 0x0e,
+	QLCNIC_HW_RPMX8_CRB_AGT_ADR = 0x11
+};
+
+/*  Hub 3 */
+enum {
+	QLCNIC_HW_PH_CRB_AGT_ADR = 0x1A,
+	QLCNIC_HW_SRE_CRB_AGT_ADR = 0x50,
+	QLCNIC_HW_EG_CRB_AGT_ADR = 0x51,
+	QLCNIC_HW_RPMX0_CRB_AGT_ADR = 0x08
+};
+
+/*  Hub 4 */
+enum {
+	QLCNIC_HW_PEGN0_CRB_AGT_ADR = 0x40,
+	QLCNIC_HW_PEGN1_CRB_AGT_ADR,
+	QLCNIC_HW_PEGN2_CRB_AGT_ADR,
+	QLCNIC_HW_PEGN3_CRB_AGT_ADR,
+	QLCNIC_HW_PEGNI_CRB_AGT_ADR,
+	QLCNIC_HW_PEGND_CRB_AGT_ADR,
+	QLCNIC_HW_PEGNC_CRB_AGT_ADR,
+	QLCNIC_HW_PEGR0_CRB_AGT_ADR,
+	QLCNIC_HW_PEGR1_CRB_AGT_ADR,
+	QLCNIC_HW_PEGR2_CRB_AGT_ADR,
+	QLCNIC_HW_PEGR3_CRB_AGT_ADR,
+	QLCNIC_HW_PEGN4_CRB_AGT_ADR
+};
+
+/*  Hub 5 */
+enum {
+	QLCNIC_HW_PEGS0_CRB_AGT_ADR = 0x40,
+	QLCNIC_HW_PEGS1_CRB_AGT_ADR,
+	QLCNIC_HW_PEGS2_CRB_AGT_ADR,
+	QLCNIC_HW_PEGS3_CRB_AGT_ADR,
+	QLCNIC_HW_PEGSI_CRB_AGT_ADR,
+	QLCNIC_HW_PEGSD_CRB_AGT_ADR,
+	QLCNIC_HW_PEGSC_CRB_AGT_ADR
+};
+
+/*  Hub 6 */
+enum {
+	QLCNIC_HW_CAS0_CRB_AGT_ADR = 0x46,
+	QLCNIC_HW_CAS1_CRB_AGT_ADR = 0x47,
+	QLCNIC_HW_CAS2_CRB_AGT_ADR = 0x48,
+	QLCNIC_HW_CAS3_CRB_AGT_ADR = 0x49,
+	QLCNIC_HW_NCM_CRB_AGT_ADR = 0x16,
+	QLCNIC_HW_TMR_CRB_AGT_ADR = 0x17,
+	QLCNIC_HW_XDMA_CRB_AGT_ADR = 0x05,
+	QLCNIC_HW_OCM0_CRB_AGT_ADR = 0x06,
+	QLCNIC_HW_OCM1_CRB_AGT_ADR = 0x07
+};
+
+/*  Floaters - non existent modules */
+#define QLCNIC_HW_EFC_RPMX0_CRB_AGT_ADR	0x67
+
+/*  This field defines PCI/X adr [25:20] of agents on the CRB */
+enum {
+	QLCNIC_HW_PX_MAP_CRB_PH = 0,
+	QLCNIC_HW_PX_MAP_CRB_PS,
+	QLCNIC_HW_PX_MAP_CRB_MN,
+	QLCNIC_HW_PX_MAP_CRB_MS,
+	QLCNIC_HW_PX_MAP_CRB_PGR1,
+	QLCNIC_HW_PX_MAP_CRB_SRE,
+	QLCNIC_HW_PX_MAP_CRB_NIU,
+	QLCNIC_HW_PX_MAP_CRB_QMN,
+	QLCNIC_HW_PX_MAP_CRB_SQN0,
+	QLCNIC_HW_PX_MAP_CRB_SQN1,
+	QLCNIC_HW_PX_MAP_CRB_SQN2,
+	QLCNIC_HW_PX_MAP_CRB_SQN3,
+	QLCNIC_HW_PX_MAP_CRB_QMS,
+	QLCNIC_HW_PX_MAP_CRB_SQS0,
+	QLCNIC_HW_PX_MAP_CRB_SQS1,
+	QLCNIC_HW_PX_MAP_CRB_SQS2,
+	QLCNIC_HW_PX_MAP_CRB_SQS3,
+	QLCNIC_HW_PX_MAP_CRB_PGN0,
+	QLCNIC_HW_PX_MAP_CRB_PGN1,
+	QLCNIC_HW_PX_MAP_CRB_PGN2,
+	QLCNIC_HW_PX_MAP_CRB_PGN3,
+	QLCNIC_HW_PX_MAP_CRB_PGND,
+	QLCNIC_HW_PX_MAP_CRB_PGNI,
+	QLCNIC_HW_PX_MAP_CRB_PGS0,
+	QLCNIC_HW_PX_MAP_CRB_PGS1,
+	QLCNIC_HW_PX_MAP_CRB_PGS2,
+	QLCNIC_HW_PX_MAP_CRB_PGS3,
+	QLCNIC_HW_PX_MAP_CRB_PGSD,
+	QLCNIC_HW_PX_MAP_CRB_PGSI,
+	QLCNIC_HW_PX_MAP_CRB_SN,
+	QLCNIC_HW_PX_MAP_CRB_PGR2,
+	QLCNIC_HW_PX_MAP_CRB_EG,
+	QLCNIC_HW_PX_MAP_CRB_PH2,
+	QLCNIC_HW_PX_MAP_CRB_PS2,
+	QLCNIC_HW_PX_MAP_CRB_CAM,
+	QLCNIC_HW_PX_MAP_CRB_CAS0,
+	QLCNIC_HW_PX_MAP_CRB_CAS1,
+	QLCNIC_HW_PX_MAP_CRB_CAS2,
+	QLCNIC_HW_PX_MAP_CRB_C2C0,
+	QLCNIC_HW_PX_MAP_CRB_C2C1,
+	QLCNIC_HW_PX_MAP_CRB_TIMR,
+	QLCNIC_HW_PX_MAP_CRB_PGR3,
+	QLCNIC_HW_PX_MAP_CRB_RPMX1,
+	QLCNIC_HW_PX_MAP_CRB_RPMX2,
+	QLCNIC_HW_PX_MAP_CRB_RPMX3,
+	QLCNIC_HW_PX_MAP_CRB_RPMX4,
+	QLCNIC_HW_PX_MAP_CRB_RPMX5,
+	QLCNIC_HW_PX_MAP_CRB_RPMX6,
+	QLCNIC_HW_PX_MAP_CRB_RPMX7,
+	QLCNIC_HW_PX_MAP_CRB_XDMA,
+	QLCNIC_HW_PX_MAP_CRB_I2Q,
+	QLCNIC_HW_PX_MAP_CRB_ROMUSB,
+	QLCNIC_HW_PX_MAP_CRB_CAS3,
+	QLCNIC_HW_PX_MAP_CRB_RPMX0,
+	QLCNIC_HW_PX_MAP_CRB_RPMX8,
+	QLCNIC_HW_PX_MAP_CRB_RPMX9,
+	QLCNIC_HW_PX_MAP_CRB_OCM0,
+	QLCNIC_HW_PX_MAP_CRB_OCM1,
+	QLCNIC_HW_PX_MAP_CRB_SMB,
+	QLCNIC_HW_PX_MAP_CRB_I2C0,
+	QLCNIC_HW_PX_MAP_CRB_I2C1,
+	QLCNIC_HW_PX_MAP_CRB_LPC,
+	QLCNIC_HW_PX_MAP_CRB_PGNC,
+	QLCNIC_HW_PX_MAP_CRB_PGR0
+};
+
+/*  This field defines CRB adr [31:20] of the agents */
+
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_MN	\
+	((QLCNIC_HW_H0_CH_HUB_ADR << 7) | QLCNIC_HW_MN_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PH	\
+	((QLCNIC_HW_H0_CH_HUB_ADR << 7) | QLCNIC_HW_PH_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_MS	\
+	((QLCNIC_HW_H0_CH_HUB_ADR << 7) | QLCNIC_HW_MS_CRB_AGT_ADR)
+
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PS	\
+	((QLCNIC_HW_H1_CH_HUB_ADR << 7) | QLCNIC_HW_PS_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_SS	\
+	((QLCNIC_HW_H1_CH_HUB_ADR << 7) | QLCNIC_HW_SS_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX3	\
+	((QLCNIC_HW_H1_CH_HUB_ADR << 7) | QLCNIC_HW_RPMX3_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_QMS	\
+	((QLCNIC_HW_H1_CH_HUB_ADR << 7) | QLCNIC_HW_QMS_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_SQS0	\
+	((QLCNIC_HW_H1_CH_HUB_ADR << 7) | QLCNIC_HW_SQGS0_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_SQS1	\
+	((QLCNIC_HW_H1_CH_HUB_ADR << 7) | QLCNIC_HW_SQGS1_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_SQS2	\
+	((QLCNIC_HW_H1_CH_HUB_ADR << 7) | QLCNIC_HW_SQGS2_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_SQS3	\
+	((QLCNIC_HW_H1_CH_HUB_ADR << 7) | QLCNIC_HW_SQGS3_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_C2C0	\
+	((QLCNIC_HW_H1_CH_HUB_ADR << 7) | QLCNIC_HW_C2C0_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_C2C1	\
+	((QLCNIC_HW_H1_CH_HUB_ADR << 7) | QLCNIC_HW_C2C1_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX2	\
+	((QLCNIC_HW_H1_CH_HUB_ADR << 7) | QLCNIC_HW_RPMX2_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX4	\
+	((QLCNIC_HW_H1_CH_HUB_ADR << 7) | QLCNIC_HW_RPMX4_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX7	\
+	((QLCNIC_HW_H1_CH_HUB_ADR << 7) | QLCNIC_HW_RPMX7_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX9	\
+	((QLCNIC_HW_H1_CH_HUB_ADR << 7) | QLCNIC_HW_RPMX9_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_SMB	\
+	((QLCNIC_HW_H1_CH_HUB_ADR << 7) | QLCNIC_HW_SMB_CRB_AGT_ADR)
+
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_NIU	\
+	((QLCNIC_HW_H2_CH_HUB_ADR << 7) | QLCNIC_HW_NIU_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_I2C0	\
+	((QLCNIC_HW_H2_CH_HUB_ADR << 7) | QLCNIC_HW_I2C0_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_I2C1	\
+	((QLCNIC_HW_H2_CH_HUB_ADR << 7) | QLCNIC_HW_I2C1_CRB_AGT_ADR)
+
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_SRE	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_SRE_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_EG	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_EG_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX0	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_RPMX0_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_QMN	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_QM_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_SQN0	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_SQG0_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_SQN1	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_SQG1_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_SQN2	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_SQG2_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_SQN3	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_SQG3_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX1	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_RPMX1_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX5	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_RPMX5_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX6	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_RPMX6_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX8	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_RPMX8_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_CAS0	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_CAS0_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_CAS1	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_CAS1_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_CAS2	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_CAS2_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_CAS3	\
+	((QLCNIC_HW_H3_CH_HUB_ADR << 7) | QLCNIC_HW_CAS3_CRB_AGT_ADR)
+
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGNI	\
+	((QLCNIC_HW_H4_CH_HUB_ADR << 7) | QLCNIC_HW_PEGNI_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGND	\
+	((QLCNIC_HW_H4_CH_HUB_ADR << 7) | QLCNIC_HW_PEGND_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGN0	\
+	((QLCNIC_HW_H4_CH_HUB_ADR << 7) | QLCNIC_HW_PEGN0_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGN1	\
+	((QLCNIC_HW_H4_CH_HUB_ADR << 7) | QLCNIC_HW_PEGN1_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGN2	\
+	((QLCNIC_HW_H4_CH_HUB_ADR << 7) | QLCNIC_HW_PEGN2_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGN3	\
+	((QLCNIC_HW_H4_CH_HUB_ADR << 7) | QLCNIC_HW_PEGN3_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGN4	\
+	((QLCNIC_HW_H4_CH_HUB_ADR << 7) | QLCNIC_HW_PEGN4_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGNC	\
+	((QLCNIC_HW_H4_CH_HUB_ADR << 7) | QLCNIC_HW_PEGNC_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGR0	\
+	((QLCNIC_HW_H4_CH_HUB_ADR << 7) | QLCNIC_HW_PEGR0_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGR1	\
+	((QLCNIC_HW_H4_CH_HUB_ADR << 7) | QLCNIC_HW_PEGR1_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGR2	\
+	((QLCNIC_HW_H4_CH_HUB_ADR << 7) | QLCNIC_HW_PEGR2_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGR3	\
+	((QLCNIC_HW_H4_CH_HUB_ADR << 7) | QLCNIC_HW_PEGR3_CRB_AGT_ADR)
+
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGSI	\
+	((QLCNIC_HW_H5_CH_HUB_ADR << 7) | QLCNIC_HW_PEGSI_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGSD	\
+	((QLCNIC_HW_H5_CH_HUB_ADR << 7) | QLCNIC_HW_PEGSD_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGS0	\
+	((QLCNIC_HW_H5_CH_HUB_ADR << 7) | QLCNIC_HW_PEGS0_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGS1	\
+	((QLCNIC_HW_H5_CH_HUB_ADR << 7) | QLCNIC_HW_PEGS1_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGS2	\
+	((QLCNIC_HW_H5_CH_HUB_ADR << 7) | QLCNIC_HW_PEGS2_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGS3	\
+	((QLCNIC_HW_H5_CH_HUB_ADR << 7) | QLCNIC_HW_PEGS3_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_PGSC	\
+	((QLCNIC_HW_H5_CH_HUB_ADR << 7) | QLCNIC_HW_PEGSC_CRB_AGT_ADR)
+
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_CAM	\
+	((QLCNIC_HW_H6_CH_HUB_ADR << 7) | QLCNIC_HW_NCM_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_TIMR	\
+	((QLCNIC_HW_H6_CH_HUB_ADR << 7) | QLCNIC_HW_TMR_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_XDMA	\
+	((QLCNIC_HW_H6_CH_HUB_ADR << 7) | QLCNIC_HW_XDMA_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_SN	\
+	((QLCNIC_HW_H6_CH_HUB_ADR << 7) | QLCNIC_HW_SN_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_I2Q	\
+	((QLCNIC_HW_H6_CH_HUB_ADR << 7) | QLCNIC_HW_I2Q_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_ROMUSB	\
+	((QLCNIC_HW_H6_CH_HUB_ADR << 7) | QLCNIC_HW_ROMUSB_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_OCM0	\
+	((QLCNIC_HW_H6_CH_HUB_ADR << 7) | QLCNIC_HW_OCM0_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_OCM1	\
+	((QLCNIC_HW_H6_CH_HUB_ADR << 7) | QLCNIC_HW_OCM1_CRB_AGT_ADR)
+#define QLCNIC_HW_CRB_HUB_AGT_ADR_LPC	\
+	((QLCNIC_HW_H6_CH_HUB_ADR << 7) | QLCNIC_HW_LPC_CRB_AGT_ADR)
+
+#define QLCNIC_SRE_MISC		(QLCNIC_CRB_SRE + 0x0002c)
+
+#define QLCNIC_I2Q_CLR_PCI_HI	(QLCNIC_CRB_I2Q + 0x00034)
+
+#define ROMUSB_GLB		(QLCNIC_CRB_ROMUSB + 0x00000)
+#define ROMUSB_ROM		(QLCNIC_CRB_ROMUSB + 0x10000)
+
+#define QLCNIC_ROMUSB_GLB_STATUS	(ROMUSB_GLB + 0x0004)
+#define QLCNIC_ROMUSB_GLB_SW_RESET	(ROMUSB_GLB + 0x0008)
+#define QLCNIC_ROMUSB_GLB_PAD_GPIO_I	(ROMUSB_GLB + 0x000c)
+#define QLCNIC_ROMUSB_GLB_CAS_RST	(ROMUSB_GLB + 0x0038)
+#define QLCNIC_ROMUSB_GLB_TEST_MUX_SEL	(ROMUSB_GLB + 0x0044)
+#define QLCNIC_ROMUSB_GLB_PEGTUNE_DONE	(ROMUSB_GLB + 0x005c)
+#define QLCNIC_ROMUSB_GLB_CHIP_CLK_CTRL	(ROMUSB_GLB + 0x00A8)
+
+#define QLCNIC_ROMUSB_GPIO(n)		(ROMUSB_GLB + 0x60 + (4 * (n)))
+
+#define QLCNIC_ROMUSB_ROM_INSTR_OPCODE	(ROMUSB_ROM + 0x0004)
+#define QLCNIC_ROMUSB_ROM_ADDRESS	(ROMUSB_ROM + 0x0008)
+#define QLCNIC_ROMUSB_ROM_WDATA		(ROMUSB_ROM + 0x000c)
+#define QLCNIC_ROMUSB_ROM_ABYTE_CNT	(ROMUSB_ROM + 0x0010)
+#define QLCNIC_ROMUSB_ROM_DUMMY_BYTE_CNT (ROMUSB_ROM + 0x0014)
+#define QLCNIC_ROMUSB_ROM_RDATA		(ROMUSB_ROM + 0x0018)
+
+/* Lock IDs for ROM lock */
+#define ROM_LOCK_DRIVER	0x0d417340
+
+/******************************************************************************
+*
+*    Definitions specific to M25P flash
+*
+*******************************************************************************
+*/
+
+/* all are 1MB windows */
+
+#define QLCNIC_PCI_CRB_WINDOWSIZE	0x00100000
+#define QLCNIC_PCI_CRB_WINDOW(A)	\
+	(QLCNIC_PCI_CRBSPACE + (A)*QLCNIC_PCI_CRB_WINDOWSIZE)
+
+#define QLCNIC_CRB_NIU		QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_NIU)
+#define QLCNIC_CRB_SRE		QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_SRE)
+#define QLCNIC_CRB_ROMUSB	\
+	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_ROMUSB)
+#define QLCNIC_CRB_I2Q		QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_I2Q)
+#define QLCNIC_CRB_I2C0 	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_I2C0)
+#define QLCNIC_CRB_SMB		QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_SMB)
+#define QLCNIC_CRB_MAX		QLCNIC_PCI_CRB_WINDOW(64)
+
+#define QLCNIC_CRB_PCIX_HOST	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_PH)
+#define QLCNIC_CRB_PCIX_HOST2	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_PH2)
+#define QLCNIC_CRB_PEG_NET_0	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_PGN0)
+#define QLCNIC_CRB_PEG_NET_1	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_PGN1)
+#define QLCNIC_CRB_PEG_NET_2	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_PGN2)
+#define QLCNIC_CRB_PEG_NET_3	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_PGN3)
+#define QLCNIC_CRB_PEG_NET_4	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_SQS2)
+#define QLCNIC_CRB_PEG_NET_D	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_PGND)
+#define QLCNIC_CRB_PEG_NET_I	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_PGNI)
+#define QLCNIC_CRB_DDR_NET	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_MN)
+#define QLCNIC_CRB_QDR_NET	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_SN)
+
+#define QLCNIC_CRB_PCIX_MD	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_PS)
+#define QLCNIC_CRB_PCIE 	QLCNIC_CRB_PCIX_MD
+
+#define ISR_INT_VECTOR		(QLCNIC_PCIX_PS_REG(PCIX_INT_VECTOR))
+#define ISR_INT_MASK		(QLCNIC_PCIX_PS_REG(PCIX_INT_MASK))
+#define ISR_INT_MASK_SLOW	(QLCNIC_PCIX_PS_REG(PCIX_INT_MASK))
+#define ISR_INT_TARGET_STATUS	(QLCNIC_PCIX_PS_REG(PCIX_TARGET_STATUS))
+#define ISR_INT_TARGET_MASK	(QLCNIC_PCIX_PS_REG(PCIX_TARGET_MASK))
+#define ISR_INT_TARGET_STATUS_F1   (QLCNIC_PCIX_PS_REG(PCIX_TARGET_STATUS_F1))
+#define ISR_INT_TARGET_MASK_F1     (QLCNIC_PCIX_PS_REG(PCIX_TARGET_MASK_F1))
+#define ISR_INT_TARGET_STATUS_F2   (QLCNIC_PCIX_PS_REG(PCIX_TARGET_STATUS_F2))
+#define ISR_INT_TARGET_MASK_F2     (QLCNIC_PCIX_PS_REG(PCIX_TARGET_MASK_F2))
+#define ISR_INT_TARGET_STATUS_F3   (QLCNIC_PCIX_PS_REG(PCIX_TARGET_STATUS_F3))
+#define ISR_INT_TARGET_MASK_F3     (QLCNIC_PCIX_PS_REG(PCIX_TARGET_MASK_F3))
+#define ISR_INT_TARGET_STATUS_F4   (QLCNIC_PCIX_PS_REG(PCIX_TARGET_STATUS_F4))
+#define ISR_INT_TARGET_MASK_F4     (QLCNIC_PCIX_PS_REG(PCIX_TARGET_MASK_F4))
+#define ISR_INT_TARGET_STATUS_F5   (QLCNIC_PCIX_PS_REG(PCIX_TARGET_STATUS_F5))
+#define ISR_INT_TARGET_MASK_F5     (QLCNIC_PCIX_PS_REG(PCIX_TARGET_MASK_F5))
+#define ISR_INT_TARGET_STATUS_F6   (QLCNIC_PCIX_PS_REG(PCIX_TARGET_STATUS_F6))
+#define ISR_INT_TARGET_MASK_F6     (QLCNIC_PCIX_PS_REG(PCIX_TARGET_MASK_F6))
+#define ISR_INT_TARGET_STATUS_F7   (QLCNIC_PCIX_PS_REG(PCIX_TARGET_STATUS_F7))
+#define ISR_INT_TARGET_MASK_F7     (QLCNIC_PCIX_PS_REG(PCIX_TARGET_MASK_F7))
+
+#define QLCNIC_PCI_MN_2M	(0)
+#define QLCNIC_PCI_MS_2M	(0x80000)
+#define QLCNIC_PCI_OCM0_2M	(0x000c0000UL)
+#define QLCNIC_PCI_CRBSPACE	(0x06000000UL)
+#define QLCNIC_PCI_2MB_SIZE	(0x00200000UL)
+#define QLCNIC_PCI_CAMQM_2M_BASE	(0x000ff800UL)
+#define QLCNIC_PCI_CAMQM_2M_END 	(0x04800800UL)
+
+#define QLCNIC_CRB_CAM	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_CAM)
+
+#define QLCNIC_ADDR_DDR_NET	(0x0000000000000000ULL)
+#define QLCNIC_ADDR_DDR_NET_MAX (0x000000000fffffffULL)
+#define QLCNIC_ADDR_OCM0	(0x0000000200000000ULL)
+#define QLCNIC_ADDR_OCM0_MAX	(0x00000002000fffffULL)
+#define QLCNIC_ADDR_OCM1	(0x0000000200400000ULL)
+#define QLCNIC_ADDR_OCM1_MAX	(0x00000002004fffffULL)
+#define QLCNIC_ADDR_QDR_NET	(0x0000000300000000ULL)
+#define QLCNIC_ADDR_QDR_NET_MAX_P3 (0x0000000303ffffffULL)
+
+/*
+ *   Register offsets for MN
+ */
+#define QLCNIC_MIU_CONTROL	(0x000)
+#define QLCNIC_MIU_MN_CONTROL	(QLCNIC_CRB_DDR_NET+QLCNIC_MIU_CONTROL)
+
+/* 200ms delay in each loop */
+#define QLCNIC_NIU_PHY_WAITLEN		200000
+/* 10 seconds before we give up */
+#define QLCNIC_NIU_PHY_WAITMAX		50
+#define QLCNIC_NIU_MAX_GBE_PORTS	4
+#define QLCNIC_NIU_MAX_XG_PORTS		2
+
+#define QLCNIC_NIU_MODE			(QLCNIC_CRB_NIU + 0x00000)
+#define QLCNIC_NIU_GB_PAUSE_CTL		(QLCNIC_CRB_NIU + 0x0030c)
+#define QLCNIC_NIU_XG_PAUSE_CTL		(QLCNIC_CRB_NIU + 0x00098)
+
+#define QLCNIC_NIU_GB_MAC_CONFIG_0(I)		\
+		(QLCNIC_CRB_NIU + 0x30000 + (I)*0x10000)
+#define QLCNIC_NIU_GB_MAC_CONFIG_1(I)		\
+		(QLCNIC_CRB_NIU + 0x30004 + (I)*0x10000)
+
+
+#define TEST_AGT_CTRL	(0x00)
+
+#define TA_CTL_START	1
+#define TA_CTL_ENABLE	2
+#define TA_CTL_WRITE	4
+#define TA_CTL_BUSY	8
+
+/*
+ *   Register offsets for MN
+ */
+#define MIU_TEST_AGT_BASE		(0x90)
+
+#define MIU_TEST_AGT_ADDR_LO		(0x04)
+#define MIU_TEST_AGT_ADDR_HI		(0x08)
+#define MIU_TEST_AGT_WRDATA_LO		(0x10)
+#define MIU_TEST_AGT_WRDATA_HI		(0x14)
+#define MIU_TEST_AGT_WRDATA_UPPER_LO	(0x20)
+#define MIU_TEST_AGT_WRDATA_UPPER_HI	(0x24)
+#define MIU_TEST_AGT_WRDATA(i)		(0x10+(0x10*((i)>>1))+(4*((i)&1)))
+#define MIU_TEST_AGT_RDDATA_LO		(0x18)
+#define MIU_TEST_AGT_RDDATA_HI		(0x1c)
+#define MIU_TEST_AGT_RDDATA_UPPER_LO	(0x28)
+#define MIU_TEST_AGT_RDDATA_UPPER_HI	(0x2c)
+#define MIU_TEST_AGT_RDDATA(i)		(0x18+(0x10*((i)>>1))+(4*((i)&1)))
+
+#define MIU_TEST_AGT_ADDR_MASK		0xfffffff8
+#define MIU_TEST_AGT_UPPER_ADDR(off)	(0)
+
+/*
+ *   Register offsets for MS
+ */
+#define SIU_TEST_AGT_BASE		(0x60)
+
+#define SIU_TEST_AGT_ADDR_LO		(0x04)
+#define SIU_TEST_AGT_ADDR_HI		(0x18)
+#define SIU_TEST_AGT_WRDATA_LO		(0x08)
+#define SIU_TEST_AGT_WRDATA_HI		(0x0c)
+#define SIU_TEST_AGT_WRDATA(i)		(0x08+(4*(i)))
+#define SIU_TEST_AGT_RDDATA_LO		(0x10)
+#define SIU_TEST_AGT_RDDATA_HI		(0x14)
+#define SIU_TEST_AGT_RDDATA(i)		(0x10+(4*(i)))
+
+#define SIU_TEST_AGT_ADDR_MASK		0x3ffff8
+#define SIU_TEST_AGT_UPPER_ADDR(off)	((off)>>22)
+
+/* XG Link status */
+#define XG_LINK_UP	0x10
+#define XG_LINK_DOWN	0x20
+
+#define XG_LINK_UP_P3	0x01
+#define XG_LINK_DOWN_P3	0x02
+#define XG_LINK_STATE_P3_MASK 0xf
+#define XG_LINK_STATE_P3(pcifn, val) \
+	(((val) >> ((pcifn) * 4)) & XG_LINK_STATE_P3_MASK)
+
+#define P3_LINK_SPEED_MHZ	100
+#define P3_LINK_SPEED_MASK	0xff
+#define P3_LINK_SPEED_REG(pcifn)	\
+	(CRB_PF_LINK_SPEED_1 + (((pcifn) / 4) * 4))
+#define P3_LINK_SPEED_VAL(pcifn, reg)	\
+	(((reg) >> (8 * ((pcifn) & 0x3))) & P3_LINK_SPEED_MASK)
+
+#define QLCNIC_CAM_RAM_BASE	(QLCNIC_CRB_CAM + 0x02000)
+#define QLCNIC_CAM_RAM(reg)	(QLCNIC_CAM_RAM_BASE + (reg))
+#define QLCNIC_FW_VERSION_MAJOR (QLCNIC_CAM_RAM(0x150))
+#define QLCNIC_FW_VERSION_MINOR (QLCNIC_CAM_RAM(0x154))
+#define QLCNIC_FW_VERSION_SUB	(QLCNIC_CAM_RAM(0x158))
+#define QLCNIC_ROM_LOCK_ID	(QLCNIC_CAM_RAM(0x100))
+#define QLCNIC_PHY_LOCK_ID	(QLCNIC_CAM_RAM(0x120))
+#define QLCNIC_CRB_WIN_LOCK_ID	(QLCNIC_CAM_RAM(0x124))
+
+#define NIC_CRB_BASE		(QLCNIC_CAM_RAM(0x200))
+#define NIC_CRB_BASE_2		(QLCNIC_CAM_RAM(0x700))
+#define QLCNIC_REG(X)		(NIC_CRB_BASE+(X))
+#define QLCNIC_REG_2(X) 	(NIC_CRB_BASE_2+(X))
+
+#define QLCNIC_CDRP_CRB_OFFSET		(QLCNIC_REG(0x18))
+#define QLCNIC_ARG1_CRB_OFFSET		(QLCNIC_REG(0x1c))
+#define QLCNIC_ARG2_CRB_OFFSET		(QLCNIC_REG(0x20))
+#define QLCNIC_ARG3_CRB_OFFSET		(QLCNIC_REG(0x24))
+#define QLCNIC_SIGN_CRB_OFFSET		(QLCNIC_REG(0x28))
+
+#define CRB_CMDPEG_STATE		(QLCNIC_REG(0x50))
+#define CRB_RCVPEG_STATE		(QLCNIC_REG(0x13c))
+
+#define CRB_XG_STATE_P3 		(QLCNIC_REG(0x98))
+#define CRB_PF_LINK_SPEED_1		(QLCNIC_REG(0xe8))
+#define CRB_PF_LINK_SPEED_2		(QLCNIC_REG(0xec))
+
+#define CRB_MPORT_MODE			(QLCNIC_REG(0xc4))
+#define CRB_DMA_SHIFT			(QLCNIC_REG(0xcc))
+
+#define CRB_TEMP_STATE			(QLCNIC_REG(0x1b4))
+
+#define CRB_V2P_0			(QLCNIC_REG(0x290))
+#define CRB_V2P(port)			(CRB_V2P_0+((port)*4))
+#define CRB_DRIVER_VERSION		(QLCNIC_REG(0x2a0))
+
+#define CRB_SW_INT_MASK_0		(QLCNIC_REG(0x1d8))
+#define CRB_SW_INT_MASK_1		(QLCNIC_REG(0x1e0))
+#define CRB_SW_INT_MASK_2		(QLCNIC_REG(0x1e4))
+#define CRB_SW_INT_MASK_3		(QLCNIC_REG(0x1e8))
+
+#define CRB_FW_CAPABILITIES_1		(QLCNIC_CAM_RAM(0x128))
+#define CRB_MAC_BLOCK_START		(QLCNIC_CAM_RAM(0x1c0))
+
+/*
+ * capabilities register, can be used to selectively enable/disable features
+ * for backward compability
+ */
+#define CRB_NIC_CAPABILITIES_HOST	QLCNIC_REG(0x1a8)
+#define CRB_NIC_CAPABILITIES_FW 	QLCNIC_REG(0x1dc)
+#define CRB_NIC_MSI_MODE_HOST		QLCNIC_REG(0x270)
+#define CRB_NIC_MSI_MODE_FW	  	QLCNIC_REG(0x274)
+
+#define INTR_SCHEME_PERPORT	      	0x1
+#define MSI_MODE_MULTIFUNC	      	0x1
+
+/* used for ethtool tests */
+#define CRB_SCRATCHPAD_TEST	    QLCNIC_REG(0x280)
+
+/*
+ * CrbPortPhanCntrHi/Lo is used to pass the address of HostPhantomIndex address
+ * which can be read by the Phantom host to get producer/consumer indexes from
+ * Phantom/Casper. If it is not HOST_SHARED_MEMORY, then the following
+ * registers will be used for the addresses of the ring's shared memory
+ * on the Phantom.
+ */
+
+#define qlcnic_get_temp_val(x)		((x) >> 16)
+#define qlcnic_get_temp_state(x)	((x) & 0xffff)
+#define qlcnic_encode_temp(val, state)	(((val) << 16) | (state))
+
+/*
+ * Temperature control.
+ */
+enum {
+	QLCNIC_TEMP_NORMAL = 0x1,	/* Normal operating range */
+	QLCNIC_TEMP_WARN,	/* Sound alert, temperature getting high */
+	QLCNIC_TEMP_PANIC	/* Fatal error, hardware has shut down. */
+};
+
+/* Lock IDs for PHY lock */
+#define PHY_LOCK_DRIVER		0x44524956
+
+/* Used for PS PCI Memory access */
+#define PCIX_PS_OP_ADDR_LO	(0x10000)
+/*   via CRB  (PS side only)     */
+#define PCIX_PS_OP_ADDR_HI	(0x10004)
+
+#define PCIX_INT_VECTOR 	(0x10100)
+#define PCIX_INT_MASK		(0x10104)
+
+#define PCIX_OCM_WINDOW		(0x10800)
+#define PCIX_OCM_WINDOW_REG(func)	(PCIX_OCM_WINDOW + 0x20 * (func))
+
+#define PCIX_TARGET_STATUS	(0x10118)
+#define PCIX_TARGET_STATUS_F1	(0x10160)
+#define PCIX_TARGET_STATUS_F2	(0x10164)
+#define PCIX_TARGET_STATUS_F3	(0x10168)
+#define PCIX_TARGET_STATUS_F4	(0x10360)
+#define PCIX_TARGET_STATUS_F5	(0x10364)
+#define PCIX_TARGET_STATUS_F6	(0x10368)
+#define PCIX_TARGET_STATUS_F7	(0x1036c)
+
+#define PCIX_TARGET_MASK	(0x10128)
+#define PCIX_TARGET_MASK_F1	(0x10170)
+#define PCIX_TARGET_MASK_F2	(0x10174)
+#define PCIX_TARGET_MASK_F3	(0x10178)
+#define PCIX_TARGET_MASK_F4	(0x10370)
+#define PCIX_TARGET_MASK_F5	(0x10374)
+#define PCIX_TARGET_MASK_F6	(0x10378)
+#define PCIX_TARGET_MASK_F7	(0x1037c)
+
+#define PCIX_MSI_F(i)		(0x13000+((i)*4))
+
+#define QLCNIC_PCIX_PH_REG(reg)	(QLCNIC_CRB_PCIE + (reg))
+#define QLCNIC_PCIX_PS_REG(reg)	(QLCNIC_CRB_PCIX_MD + (reg))
+#define QLCNIC_PCIE_REG(reg)	(QLCNIC_CRB_PCIE + (reg))
+
+#define PCIE_SEM0_LOCK		(0x1c000)
+#define PCIE_SEM0_UNLOCK	(0x1c004)
+#define PCIE_SEM_LOCK(N)	(PCIE_SEM0_LOCK + 8*(N))
+#define PCIE_SEM_UNLOCK(N)	(PCIE_SEM0_UNLOCK + 8*(N))
+
+#define PCIE_SETUP_FUNCTION	(0x12040)
+#define PCIE_SETUP_FUNCTION2	(0x12048)
+#define PCIE_MISCCFG_RC         (0x1206c)
+#define PCIE_TGT_SPLIT_CHICKEN	(0x12080)
+#define PCIE_CHICKEN3		(0x120c8)
+
+#define ISR_INT_STATE_REG       (QLCNIC_PCIX_PS_REG(PCIE_MISCCFG_RC))
+#define PCIE_MAX_MASTER_SPLIT	(0x14048)
+
+#define QLCNIC_PORT_MODE_NONE		0
+#define QLCNIC_PORT_MODE_XG		1
+#define QLCNIC_PORT_MODE_GB		2
+#define QLCNIC_PORT_MODE_802_3_AP	3
+#define QLCNIC_PORT_MODE_AUTO_NEG	4
+#define QLCNIC_PORT_MODE_AUTO_NEG_1G	5
+#define QLCNIC_PORT_MODE_AUTO_NEG_XG	6
+#define QLCNIC_PORT_MODE_ADDR		(QLCNIC_CAM_RAM(0x24))
+#define QLCNIC_WOL_PORT_MODE		(QLCNIC_CAM_RAM(0x198))
+
+#define QLCNIC_WOL_CONFIG_NV		(QLCNIC_CAM_RAM(0x184))
+#define QLCNIC_WOL_CONFIG		(QLCNIC_CAM_RAM(0x188))
+
+#define QLCNIC_PEG_TUNE_MN_PRESENT	0x1
+#define QLCNIC_PEG_TUNE_CAPABILITY	(QLCNIC_CAM_RAM(0x02c))
+
+#define QLCNIC_DMA_WATCHDOG_CTRL	(QLCNIC_CAM_RAM(0x14))
+#define QLCNIC_PEG_ALIVE_COUNTER	(QLCNIC_CAM_RAM(0xb0))
+#define QLCNIC_PEG_HALT_STATUS1 	(QLCNIC_CAM_RAM(0xa8))
+#define QLCNIC_PEG_HALT_STATUS2 	(QLCNIC_CAM_RAM(0xac))
+#define QLCNIC_CRB_DEV_REF_COUNT	(QLCNIC_CAM_RAM(0x138))
+#define QLCNIC_CRB_DEV_STATE		(QLCNIC_CAM_RAM(0x140))
+
+#define QLCNIC_CRB_DRV_STATE               (QLCNIC_CAM_RAM(0x144))
+#define QLCNIC_CRB_DRV_SCRATCH             (QLCNIC_CAM_RAM(0x148))
+#define QLCNIC_CRB_DEV_PARTITION_INFO      (QLCNIC_CAM_RAM(0x14c))
+#define QLCNIC_CRB_DRV_IDC_VER             (QLCNIC_CAM_RAM(0x14c))
+
+		 /* Device State */
+#define QLCNIC_DEV_COLD 		1
+#define QLCNIC_DEV_INITALIZING		2
+#define QLCNIC_DEV_READY		3
+#define QLCNIC_DEV_NEED_RESET		4
+#define QLCNIC_DEV_NEED_QUISCENT	5
+#define QLCNIC_DEV_FAILED		6
+
+#define QLCNIC_RCODE_DRIVER_INFO		0x20000000
+#define QLCNIC_RCODE_DRIVER_CAN_RELOAD		0x40000000
+#define QLCNIC_RCODE_FATAL_ERROR		0x80000000
+#define QLCNIC_FWERROR_PEGNUM(code)		((code) & 0xff)
+#define QLCNIC_FWERROR_CODE(code)		((code >> 8) & 0xfffff)
+
+#define FW_POLL_DELAY			(2 * HZ)
+#define FW_FAIL_THRESH			3
+#define FW_POLL_THRESH			10
+
+#define	ISR_MSI_INT_TRIGGER(FUNC) (QLCNIC_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
+#define ISR_LEGACY_INT_TRIGGERED(VAL)	(((VAL) & 0x300) == 0x200)
+
+/*
+ * PCI Interrupt Vector Values.
+ */
+#define	PCIX_INT_VECTOR_BIT_F0	0x0080
+#define	PCIX_INT_VECTOR_BIT_F1	0x0100
+#define	PCIX_INT_VECTOR_BIT_F2	0x0200
+#define	PCIX_INT_VECTOR_BIT_F3	0x0400
+#define	PCIX_INT_VECTOR_BIT_F4	0x0800
+#define	PCIX_INT_VECTOR_BIT_F5	0x1000
+#define	PCIX_INT_VECTOR_BIT_F6	0x2000
+#define	PCIX_INT_VECTOR_BIT_F7	0x4000
+
+struct qlcnic_legacy_intr_set {
+	u32	int_vec_bit;
+	u32	tgt_status_reg;
+	u32	tgt_mask_reg;
+	u32	pci_int_reg;
+};
+
+#define	QLCNIC_LEGACY_INTR_CONFIG					\
+{									\
+	{								\
+		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F0,		\
+		.tgt_status_reg	=	ISR_INT_TARGET_STATUS,		\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK,		\
+		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(0) },	\
+									\
+	{								\
+		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F1,		\
+		.tgt_status_reg	=	ISR_INT_TARGET_STATUS_F1,	\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F1,		\
+		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(1) },	\
+									\
+	{								\
+		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F2,		\
+		.tgt_status_reg	=	ISR_INT_TARGET_STATUS_F2,	\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F2,		\
+		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(2) },	\
+									\
+	{								\
+		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F3,		\
+		.tgt_status_reg	=	ISR_INT_TARGET_STATUS_F3,	\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F3,		\
+		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(3) },	\
+									\
+	{								\
+		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F4,		\
+		.tgt_status_reg	=	ISR_INT_TARGET_STATUS_F4,	\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F4,		\
+		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(4) },	\
+									\
+	{								\
+		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F5,		\
+		.tgt_status_reg	=	ISR_INT_TARGET_STATUS_F5,	\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F5,		\
+		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(5) },	\
+									\
+	{								\
+		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F6,		\
+		.tgt_status_reg	=	ISR_INT_TARGET_STATUS_F6,	\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F6,		\
+		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(6) },	\
+									\
+	{								\
+		.int_vec_bit	=	PCIX_INT_VECTOR_BIT_F7,		\
+		.tgt_status_reg	=	ISR_INT_TARGET_STATUS_F7,	\
+		.tgt_mask_reg	=	ISR_INT_TARGET_MASK_F7,		\
+		.pci_int_reg	=	ISR_MSI_INT_TRIGGER(7) },	\
+}
+
+/* NIU REGS */
+
+#define _qlcnic_crb_get_bit(var, bit)  ((var >> bit) & 0x1)
+
+/*
+ * NIU GB MAC Config Register 0 (applies to GB0, GB1, GB2, GB3)
+ *
+ *	Bit 0 : enable_tx => 1:enable frame xmit, 0:disable
+ *	Bit 1 : tx_synced => R/O: xmit enable synched to xmit stream
+ *	Bit 2 : enable_rx => 1:enable frame recv, 0:disable
+ *	Bit 3 : rx_synced => R/O: recv enable synched to recv stream
+ *	Bit 4 : tx_flowctl => 1:enable pause frame generation, 0:disable
+ *	Bit 5 : rx_flowctl => 1:act on recv'd pause frames, 0:ignore
+ *	Bit 8 : loopback => 1:loop MAC xmits to MAC recvs, 0:normal
+ *	Bit 16: tx_reset_pb => 1:reset frame xmit protocol blk, 0:no-op
+ *	Bit 17: rx_reset_pb => 1:reset frame recv protocol blk, 0:no-op
+ *	Bit 18: tx_reset_mac => 1:reset data/ctl multiplexer blk, 0:no-op
+ *	Bit 19: rx_reset_mac => 1:reset ctl frames & timers blk, 0:no-op
+ *	Bit 31: soft_reset => 1:reset the MAC and the SERDES, 0:no-op
+ */
+#define qlcnic_gb_rx_flowctl(config_word)	\
+	((config_word) |= 1 << 5)
+#define qlcnic_gb_get_rx_flowctl(config_word)	\
+	_qlcnic_crb_get_bit((config_word), 5)
+#define qlcnic_gb_unset_rx_flowctl(config_word)	\
+	((config_word) &= ~(1 << 5))
+
+/*
+ * NIU GB Pause Ctl Register
+ */
+
+#define qlcnic_gb_set_gb0_mask(config_word)    \
+	((config_word) |= 1 << 0)
+#define qlcnic_gb_set_gb1_mask(config_word)    \
+	((config_word) |= 1 << 2)
+#define qlcnic_gb_set_gb2_mask(config_word)    \
+	((config_word) |= 1 << 4)
+#define qlcnic_gb_set_gb3_mask(config_word)    \
+	((config_word) |= 1 << 6)
+
+#define qlcnic_gb_get_gb0_mask(config_word)    \
+	_qlcnic_crb_get_bit((config_word), 0)
+#define qlcnic_gb_get_gb1_mask(config_word)    \
+	_qlcnic_crb_get_bit((config_word), 2)
+#define qlcnic_gb_get_gb2_mask(config_word)    \
+	_qlcnic_crb_get_bit((config_word), 4)
+#define qlcnic_gb_get_gb3_mask(config_word)    \
+	_qlcnic_crb_get_bit((config_word), 6)
+
+#define qlcnic_gb_unset_gb0_mask(config_word)  \
+	((config_word) &= ~(1 << 0))
+#define qlcnic_gb_unset_gb1_mask(config_word)  \
+	((config_word) &= ~(1 << 2))
+#define qlcnic_gb_unset_gb2_mask(config_word)  \
+	((config_word) &= ~(1 << 4))
+#define qlcnic_gb_unset_gb3_mask(config_word)  \
+	((config_word) &= ~(1 << 6))
+
+/*
+ * NIU XG Pause Ctl Register
+ *
+ *      Bit 0       : xg0_mask => 1:disable tx pause frames
+ *      Bit 1       : xg0_request => 1:request single pause frame
+ *      Bit 2       : xg0_on_off => 1:request is pause on, 0:off
+ *      Bit 3       : xg1_mask => 1:disable tx pause frames
+ *      Bit 4       : xg1_request => 1:request single pause frame
+ *      Bit 5       : xg1_on_off => 1:request is pause on, 0:off
+ */
+
+#define qlcnic_xg_set_xg0_mask(config_word)    \
+	((config_word) |= 1 << 0)
+#define qlcnic_xg_set_xg1_mask(config_word)    \
+	((config_word) |= 1 << 3)
+
+#define qlcnic_xg_get_xg0_mask(config_word)    \
+	_qlcnic_crb_get_bit((config_word), 0)
+#define qlcnic_xg_get_xg1_mask(config_word)    \
+	_qlcnic_crb_get_bit((config_word), 3)
+
+#define qlcnic_xg_unset_xg0_mask(config_word)  \
+	((config_word) &= ~(1 << 0))
+#define qlcnic_xg_unset_xg1_mask(config_word)  \
+	((config_word) &= ~(1 << 3))
+
+/*
+ * NIU XG Pause Ctl Register
+ *
+ *      Bit 0       : xg0_mask => 1:disable tx pause frames
+ *      Bit 1       : xg0_request => 1:request single pause frame
+ *      Bit 2       : xg0_on_off => 1:request is pause on, 0:off
+ *      Bit 3       : xg1_mask => 1:disable tx pause frames
+ *      Bit 4       : xg1_request => 1:request single pause frame
+ *      Bit 5       : xg1_on_off => 1:request is pause on, 0:off
+ */
+
+/*
+ * PHY-Specific MII control/status registers.
+ */
+#define QLCNIC_NIU_GB_MII_MGMT_ADDR_AUTONEG		4
+#define QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS		17
+
+/*
+ * PHY-Specific Status Register (reg 17).
+ *
+ * Bit 0      : jabber => 1:jabber detected, 0:not
+ * Bit 1      : polarity => 1:polarity reversed, 0:normal
+ * Bit 2      : recvpause => 1:receive pause enabled, 0:disabled
+ * Bit 3      : xmitpause => 1:transmit pause enabled, 0:disabled
+ * Bit 4      : energydetect => 1:sleep, 0:active
+ * Bit 5      : downshift => 1:downshift, 0:no downshift
+ * Bit 6      : crossover => 1:MDIX (crossover), 0:MDI (no crossover)
+ * Bits 7-9   : cablelen => not valid in 10Mb/s mode
+ *			0:<50m, 1:50-80m, 2:80-110m, 3:110-140m, 4:>140m
+ * Bit 10     : link => 1:link up, 0:link down
+ * Bit 11     : resolved => 1:speed and duplex resolved, 0:not yet
+ * Bit 12     : pagercvd => 1:page received, 0:page not received
+ * Bit 13     : duplex => 1:full duplex, 0:half duplex
+ * Bits 14-15 : speed => 0:10Mb/s, 1:100Mb/s, 2:1000Mb/s, 3:rsvd
+ */
+
+#define qlcnic_get_phy_speed(config_word) (((config_word) >> 14) & 0x03)
+
+#define qlcnic_set_phy_speed(config_word, val)	\
+		((config_word) |= ((val & 0x03) << 14))
+#define qlcnic_set_phy_duplex(config_word)	\
+		((config_word) |= 1 << 13)
+#define qlcnic_clear_phy_duplex(config_word)	\
+		((config_word) &= ~(1 << 13))
+
+#define qlcnic_get_phy_link(config_word)	\
+		_qlcnic_crb_get_bit(config_word, 10)
+#define qlcnic_get_phy_duplex(config_word)	\
+		_qlcnic_crb_get_bit(config_word, 13)
+
+#define QLCNIC_NIU_NON_PROMISC_MODE	0
+#define QLCNIC_NIU_PROMISC_MODE		1
+#define QLCNIC_NIU_ALLMULTI_MODE	2
+
+struct crb_128M_2M_sub_block_map {
+	unsigned valid;
+	unsigned start_128M;
+	unsigned end_128M;
+	unsigned start_2M;
+};
+
+struct crb_128M_2M_block_map{
+	struct crb_128M_2M_sub_block_map sub_block[16];
+};
+#endif				/* __QLCNIC_HDR_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/qlcnic/qlcnic_hw.c linux-libre-2.6.34-gnu1/drivers/net/qlcnic/qlcnic_hw.c
--- linux-libre-2.6.33-gnu1/drivers/net/qlcnic/qlcnic_hw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/qlcnic/qlcnic_hw.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1260 @@
+/*
+ * Copyright (C) 2009 - QLogic Corporation.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called "COPYING".
+ *
+ */
+
+#include "qlcnic.h"
+
+#include <linux/slab.h>
+#include <net/ip.h>
+
+#define MASK(n) ((1ULL<<(n))-1)
+#define OCM_WIN_P3P(addr) (addr & 0xffc0000)
+
+#define GET_MEM_OFFS_2M(addr) (addr & MASK(18))
+
+#define CRB_BLK(off)	((off >> 20) & 0x3f)
+#define CRB_SUBBLK(off)	((off >> 16) & 0xf)
+#define CRB_WINDOW_2M	(0x130060)
+#define CRB_HI(off)	((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
+#define CRB_INDIRECT_2M	(0x1e0000UL)
+
+
+#ifndef readq
+static inline u64 readq(void __iomem *addr)
+{
+	return readl(addr) | (((u64) readl(addr + 4)) << 32LL);
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(u64 val, void __iomem *addr)
+{
+	writel(((u32) (val)), (addr));
+	writel(((u32) (val >> 32)), (addr + 4));
+}
+#endif
+
+#define ADDR_IN_RANGE(addr, low, high)	\
+	(((addr) < (high)) && ((addr) >= (low)))
+
+#define PCI_OFFSET_FIRST_RANGE(adapter, off)    \
+	((adapter)->ahw.pci_base0 + (off))
+
+static void __iomem *pci_base_offset(struct qlcnic_adapter *adapter,
+					    unsigned long off)
+{
+	if (ADDR_IN_RANGE(off, FIRST_PAGE_GROUP_START, FIRST_PAGE_GROUP_END))
+		return PCI_OFFSET_FIRST_RANGE(adapter, off);
+
+	return NULL;
+}
+
+static const struct crb_128M_2M_block_map
+crb_128M_2M_map[64] __cacheline_aligned_in_smp = {
+    {{{0, 0,         0,         0} } },		/* 0: PCI */
+    {{{1, 0x0100000, 0x0102000, 0x120000},	/* 1: PCIE */
+	  {1, 0x0110000, 0x0120000, 0x130000},
+	  {1, 0x0120000, 0x0122000, 0x124000},
+	  {1, 0x0130000, 0x0132000, 0x126000},
+	  {1, 0x0140000, 0x0142000, 0x128000},
+	  {1, 0x0150000, 0x0152000, 0x12a000},
+	  {1, 0x0160000, 0x0170000, 0x110000},
+	  {1, 0x0170000, 0x0172000, 0x12e000},
+	  {0, 0x0000000, 0x0000000, 0x000000},
+	  {0, 0x0000000, 0x0000000, 0x000000},
+	  {0, 0x0000000, 0x0000000, 0x000000},
+	  {0, 0x0000000, 0x0000000, 0x000000},
+	  {0, 0x0000000, 0x0000000, 0x000000},
+	  {0, 0x0000000, 0x0000000, 0x000000},
+	  {1, 0x01e0000, 0x01e0800, 0x122000},
+	  {0, 0x0000000, 0x0000000, 0x000000} } },
+	{{{1, 0x0200000, 0x0210000, 0x180000} } },/* 2: MN */
+    {{{0, 0,         0,         0} } },	    /* 3: */
+    {{{1, 0x0400000, 0x0401000, 0x169000} } },/* 4: P2NR1 */
+    {{{1, 0x0500000, 0x0510000, 0x140000} } },/* 5: SRE   */
+    {{{1, 0x0600000, 0x0610000, 0x1c0000} } },/* 6: NIU   */
+    {{{1, 0x0700000, 0x0704000, 0x1b8000} } },/* 7: QM    */
+    {{{1, 0x0800000, 0x0802000, 0x170000},  /* 8: SQM0  */
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {1, 0x08f0000, 0x08f2000, 0x172000} } },
+    {{{1, 0x0900000, 0x0902000, 0x174000},	/* 9: SQM1*/
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {1, 0x09f0000, 0x09f2000, 0x176000} } },
+    {{{0, 0x0a00000, 0x0a02000, 0x178000},	/* 10: SQM2*/
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {1, 0x0af0000, 0x0af2000, 0x17a000} } },
+    {{{0, 0x0b00000, 0x0b02000, 0x17c000},	/* 11: SQM3*/
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {1, 0x0bf0000, 0x0bf2000, 0x17e000} } },
+	{{{1, 0x0c00000, 0x0c04000, 0x1d4000} } },/* 12: I2Q */
+	{{{1, 0x0d00000, 0x0d04000, 0x1a4000} } },/* 13: TMR */
+	{{{1, 0x0e00000, 0x0e04000, 0x1a0000} } },/* 14: ROMUSB */
+	{{{1, 0x0f00000, 0x0f01000, 0x164000} } },/* 15: PEG4 */
+	{{{0, 0x1000000, 0x1004000, 0x1a8000} } },/* 16: XDMA */
+	{{{1, 0x1100000, 0x1101000, 0x160000} } },/* 17: PEG0 */
+	{{{1, 0x1200000, 0x1201000, 0x161000} } },/* 18: PEG1 */
+	{{{1, 0x1300000, 0x1301000, 0x162000} } },/* 19: PEG2 */
+	{{{1, 0x1400000, 0x1401000, 0x163000} } },/* 20: PEG3 */
+	{{{1, 0x1500000, 0x1501000, 0x165000} } },/* 21: P2ND */
+	{{{1, 0x1600000, 0x1601000, 0x166000} } },/* 22: P2NI */
+	{{{0, 0,         0,         0} } },	/* 23: */
+	{{{0, 0,         0,         0} } },	/* 24: */
+	{{{0, 0,         0,         0} } },	/* 25: */
+	{{{0, 0,         0,         0} } },	/* 26: */
+	{{{0, 0,         0,         0} } },	/* 27: */
+	{{{0, 0,         0,         0} } },	/* 28: */
+	{{{1, 0x1d00000, 0x1d10000, 0x190000} } },/* 29: MS */
+    {{{1, 0x1e00000, 0x1e01000, 0x16a000} } },/* 30: P2NR2 */
+    {{{1, 0x1f00000, 0x1f10000, 0x150000} } },/* 31: EPG */
+	{{{0} } },				/* 32: PCI */
+	{{{1, 0x2100000, 0x2102000, 0x120000},	/* 33: PCIE */
+	  {1, 0x2110000, 0x2120000, 0x130000},
+	  {1, 0x2120000, 0x2122000, 0x124000},
+	  {1, 0x2130000, 0x2132000, 0x126000},
+	  {1, 0x2140000, 0x2142000, 0x128000},
+	  {1, 0x2150000, 0x2152000, 0x12a000},
+	  {1, 0x2160000, 0x2170000, 0x110000},
+	  {1, 0x2170000, 0x2172000, 0x12e000},
+	  {0, 0x0000000, 0x0000000, 0x000000},
+	  {0, 0x0000000, 0x0000000, 0x000000},
+	  {0, 0x0000000, 0x0000000, 0x000000},
+	  {0, 0x0000000, 0x0000000, 0x000000},
+	  {0, 0x0000000, 0x0000000, 0x000000},
+	  {0, 0x0000000, 0x0000000, 0x000000},
+	  {0, 0x0000000, 0x0000000, 0x000000},
+	  {0, 0x0000000, 0x0000000, 0x000000} } },
+	{{{1, 0x2200000, 0x2204000, 0x1b0000} } },/* 34: CAM */
+	{{{0} } },				/* 35: */
+	{{{0} } },				/* 36: */
+	{{{0} } },				/* 37: */
+	{{{0} } },				/* 38: */
+	{{{0} } },				/* 39: */
+	{{{1, 0x2800000, 0x2804000, 0x1a4000} } },/* 40: TMR */
+	{{{1, 0x2900000, 0x2901000, 0x16b000} } },/* 41: P2NR3 */
+	{{{1, 0x2a00000, 0x2a00400, 0x1ac400} } },/* 42: RPMX1 */
+	{{{1, 0x2b00000, 0x2b00400, 0x1ac800} } },/* 43: RPMX2 */
+	{{{1, 0x2c00000, 0x2c00400, 0x1acc00} } },/* 44: RPMX3 */
+	{{{1, 0x2d00000, 0x2d00400, 0x1ad000} } },/* 45: RPMX4 */
+	{{{1, 0x2e00000, 0x2e00400, 0x1ad400} } },/* 46: RPMX5 */
+	{{{1, 0x2f00000, 0x2f00400, 0x1ad800} } },/* 47: RPMX6 */
+	{{{1, 0x3000000, 0x3000400, 0x1adc00} } },/* 48: RPMX7 */
+	{{{0, 0x3100000, 0x3104000, 0x1a8000} } },/* 49: XDMA */
+	{{{1, 0x3200000, 0x3204000, 0x1d4000} } },/* 50: I2Q */
+	{{{1, 0x3300000, 0x3304000, 0x1a0000} } },/* 51: ROMUSB */
+	{{{0} } },				/* 52: */
+	{{{1, 0x3500000, 0x3500400, 0x1ac000} } },/* 53: RPMX0 */
+	{{{1, 0x3600000, 0x3600400, 0x1ae000} } },/* 54: RPMX8 */
+	{{{1, 0x3700000, 0x3700400, 0x1ae400} } },/* 55: RPMX9 */
+	{{{1, 0x3800000, 0x3804000, 0x1d0000} } },/* 56: OCM0 */
+	{{{1, 0x3900000, 0x3904000, 0x1b4000} } },/* 57: CRYPTO */
+	{{{1, 0x3a00000, 0x3a04000, 0x1d8000} } },/* 58: SMB */
+	{{{0} } },				/* 59: I2C0 */
+	{{{0} } },				/* 60: I2C1 */
+	{{{1, 0x3d00000, 0x3d04000, 0x1d8000} } },/* 61: LPC */
+	{{{1, 0x3e00000, 0x3e01000, 0x167000} } },/* 62: P2NC */
+	{{{1, 0x3f00000, 0x3f01000, 0x168000} } }	/* 63: P2NR0 */
+};
+
+/*
+ * top 12 bits of crb internal address (hub, agent)
+ */
+static const unsigned crb_hub_agt[64] = {
+	0,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_PS,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_MN,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_MS,
+	0,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_SRE,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_NIU,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_QMN,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_SQN0,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_SQN1,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_SQN2,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_SQN3,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_I2Q,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_TIMR,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_ROMUSB,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_PGN4,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_XDMA,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_PGN0,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_PGN1,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_PGN2,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_PGN3,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_PGND,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_PGNI,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_PGS0,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_PGS1,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_PGS2,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_PGS3,
+	0,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_PGSI,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_SN,
+	0,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_EG,
+	0,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_PS,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_CAM,
+	0,
+	0,
+	0,
+	0,
+	0,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_TIMR,
+	0,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX1,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX2,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX3,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX4,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX5,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX6,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX7,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_XDMA,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_I2Q,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_ROMUSB,
+	0,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX0,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX8,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_RPMX9,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_OCM0,
+	0,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_SMB,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_I2C0,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_I2C1,
+	0,
+	QLCNIC_HW_CRB_HUB_AGT_ADR_PGNC,
+	0,
+};
+
+/*  PCI Windowing for DDR regions.  */
+
+#define QLCNIC_PCIE_SEM_TIMEOUT	10000
+
+int
+qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg)
+{
+	int done = 0, timeout = 0;
+
+	while (!done) {
+		done = QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_LOCK(sem)));
+		if (done == 1)
+			break;
+		if (++timeout >= QLCNIC_PCIE_SEM_TIMEOUT)
+			return -EIO;
+		msleep(1);
+	}
+
+	if (id_reg)
+		QLCWR32(adapter, id_reg, adapter->portnum);
+
+	return 0;
+}
+
+void
+qlcnic_pcie_sem_unlock(struct qlcnic_adapter *adapter, int sem)
+{
+	QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
+}
+
+static int
+qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,
+		struct cmd_desc_type0 *cmd_desc_arr, int nr_desc)
+{
+	u32 i, producer, consumer;
+	struct qlcnic_cmd_buffer *pbuf;
+	struct cmd_desc_type0 *cmd_desc;
+	struct qlcnic_host_tx_ring *tx_ring;
+
+	i = 0;
+
+	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+		return -EIO;
+
+	tx_ring = adapter->tx_ring;
+	__netif_tx_lock_bh(tx_ring->txq);
+
+	producer = tx_ring->producer;
+	consumer = tx_ring->sw_consumer;
+
+	if (nr_desc >= qlcnic_tx_avail(tx_ring)) {
+		netif_tx_stop_queue(tx_ring->txq);
+		__netif_tx_unlock_bh(tx_ring->txq);
+		adapter->stats.xmit_off++;
+		return -EBUSY;
+	}
+
+	do {
+		cmd_desc = &cmd_desc_arr[i];
+
+		pbuf = &tx_ring->cmd_buf_arr[producer];
+		pbuf->skb = NULL;
+		pbuf->frag_count = 0;
+
+		memcpy(&tx_ring->desc_head[producer],
+			&cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
+
+		producer = get_next_index(producer, tx_ring->num_desc);
+		i++;
+
+	} while (i != nr_desc);
+
+	tx_ring->producer = producer;
+
+	qlcnic_update_cmd_producer(adapter, tx_ring);
+
+	__netif_tx_unlock_bh(tx_ring->txq);
+
+	return 0;
+}
+
+static int
+qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
+				unsigned op)
+{
+	struct qlcnic_nic_req req;
+	struct qlcnic_mac_req *mac_req;
+	u64 word;
+
+	memset(&req, 0, sizeof(struct qlcnic_nic_req));
+	req.qhdr = cpu_to_le64(QLCNIC_REQUEST << 23);
+
+	word = QLCNIC_MAC_EVENT | ((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word);
+
+	mac_req = (struct qlcnic_mac_req *)&req.words[0];
+	mac_req->op = op;
+	memcpy(mac_req->mac_addr, addr, 6);
+
+	return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+}
+
+static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr)
+{
+	struct list_head *head;
+	struct qlcnic_mac_list_s *cur;
+
+	/* look up if already exists */
+	list_for_each(head, &adapter->mac_list) {
+		cur = list_entry(head, struct qlcnic_mac_list_s, list);
+		if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0)
+			return 0;
+	}
+
+	cur = kzalloc(sizeof(struct qlcnic_mac_list_s), GFP_ATOMIC);
+	if (cur == NULL) {
+		dev_err(&adapter->netdev->dev,
+			"failed to add mac address filter\n");
+		return -ENOMEM;
+	}
+	memcpy(cur->mac_addr, addr, ETH_ALEN);
+	list_add_tail(&cur->list, &adapter->mac_list);
+
+	return qlcnic_sre_macaddr_change(adapter,
+				cur->mac_addr, QLCNIC_MAC_ADD);
+}
+
+void qlcnic_set_multi(struct net_device *netdev)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct dev_mc_list *mc_ptr;
+	u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+	u32 mode = VPORT_MISS_MODE_DROP;
+
+	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+		return;
+
+	qlcnic_nic_add_mac(adapter, adapter->mac_addr);
+	qlcnic_nic_add_mac(adapter, bcast_addr);
+
+	if (netdev->flags & IFF_PROMISC) {
+		mode = VPORT_MISS_MODE_ACCEPT_ALL;
+		goto send_fw_cmd;
+	}
+
+	if ((netdev->flags & IFF_ALLMULTI) ||
+	    (netdev_mc_count(netdev) > adapter->max_mc_count)) {
+		mode = VPORT_MISS_MODE_ACCEPT_MULTI;
+		goto send_fw_cmd;
+	}
+
+	if (!netdev_mc_empty(netdev)) {
+		netdev_for_each_mc_addr(mc_ptr, netdev) {
+			qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr);
+		}
+	}
+
+send_fw_cmd:
+	qlcnic_nic_set_promisc(adapter, mode);
+}
+
+int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
+{
+	struct qlcnic_nic_req req;
+	u64 word;
+
+	memset(&req, 0, sizeof(struct qlcnic_nic_req));
+
+	req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
+
+	word = QLCNIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE |
+			((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word);
+
+	req.words[0] = cpu_to_le64(mode);
+
+	return qlcnic_send_cmd_descs(adapter,
+				(struct cmd_desc_type0 *)&req, 1);
+}
+
+void qlcnic_free_mac_list(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_mac_list_s *cur;
+	struct list_head *head = &adapter->mac_list;
+
+	while (!list_empty(head)) {
+		cur = list_entry(head->next, struct qlcnic_mac_list_s, list);
+		qlcnic_sre_macaddr_change(adapter,
+				cur->mac_addr, QLCNIC_MAC_DEL);
+		list_del(&cur->list);
+		kfree(cur);
+	}
+}
+
+#define	QLCNIC_CONFIG_INTR_COALESCE	3
+
+/*
+ * Send the interrupt coalescing parameter set by ethtool to the card.
+ */
+int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_nic_req req;
+	u64 word[6];
+	int rv, i;
+
+	memset(&req, 0, sizeof(struct qlcnic_nic_req));
+
+	req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
+
+	word[0] = QLCNIC_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word[0]);
+
+	memcpy(&word[0], &adapter->coal, sizeof(adapter->coal));
+	for (i = 0; i < 6; i++)
+		req.words[i] = cpu_to_le64(word[i]);
+
+	rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+	if (rv != 0)
+		dev_err(&adapter->netdev->dev,
+			"Could not send interrupt coalescing parameters\n");
+
+	return rv;
+}
+
+int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable)
+{
+	struct qlcnic_nic_req req;
+	u64 word;
+	int rv;
+
+	if ((adapter->flags & QLCNIC_LRO_ENABLED) == enable)
+		return 0;
+
+	memset(&req, 0, sizeof(struct qlcnic_nic_req));
+
+	req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
+
+	word = QLCNIC_H2C_OPCODE_CONFIG_HW_LRO | ((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word);
+
+	req.words[0] = cpu_to_le64(enable);
+
+	rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+	if (rv != 0)
+		dev_err(&adapter->netdev->dev,
+			"Could not send configure hw lro request\n");
+
+	adapter->flags ^= QLCNIC_LRO_ENABLED;
+
+	return rv;
+}
+
+int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, int enable)
+{
+	struct qlcnic_nic_req req;
+	u64 word;
+	int rv;
+
+	if (!!(adapter->flags & QLCNIC_BRIDGE_ENABLED) == enable)
+		return 0;
+
+	memset(&req, 0, sizeof(struct qlcnic_nic_req));
+
+	req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
+
+	word = QLCNIC_H2C_OPCODE_CONFIG_BRIDGING |
+		((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word);
+
+	req.words[0] = cpu_to_le64(enable);
+
+	rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+	if (rv != 0)
+		dev_err(&adapter->netdev->dev,
+			"Could not send configure bridge mode request\n");
+
+	adapter->flags ^= QLCNIC_BRIDGE_ENABLED;
+
+	return rv;
+}
+
+
+#define RSS_HASHTYPE_IP_TCP	0x3
+
+int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable)
+{
+	struct qlcnic_nic_req req;
+	u64 word;
+	int i, rv;
+
+	const u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
+			0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
+			0x255b0ec26d5a56daULL };
+
+
+	memset(&req, 0, sizeof(struct qlcnic_nic_req));
+	req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
+
+	word = QLCNIC_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 = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+	if (rv != 0)
+		dev_err(&adapter->netdev->dev, "could not configure RSS\n");
+
+	return rv;
+}
+
+int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, u32 ip, int cmd)
+{
+	struct qlcnic_nic_req req;
+	u64 word;
+	int rv;
+
+	memset(&req, 0, sizeof(struct qlcnic_nic_req));
+	req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
+
+	word = QLCNIC_H2C_OPCODE_CONFIG_IPADDR | ((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word);
+
+	req.words[0] = cpu_to_le64(cmd);
+	req.words[1] = cpu_to_le64(ip);
+
+	rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+	if (rv != 0)
+		dev_err(&adapter->netdev->dev,
+				"could not notify %s IP 0x%x reuqest\n",
+				(cmd == QLCNIC_IP_UP) ? "Add" : "Remove", ip);
+
+	return rv;
+}
+
+int qlcnic_linkevent_request(struct qlcnic_adapter *adapter, int enable)
+{
+	struct qlcnic_nic_req req;
+	u64 word;
+	int rv;
+
+	memset(&req, 0, sizeof(struct qlcnic_nic_req));
+	req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
+
+	word = QLCNIC_H2C_OPCODE_GET_LINKEVENT | ((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word);
+	req.words[0] = cpu_to_le64(enable | (enable << 8));
+
+	rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+	if (rv != 0)
+		dev_err(&adapter->netdev->dev,
+				"could not configure link notification\n");
+
+	return rv;
+}
+
+int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_nic_req req;
+	u64 word;
+	int rv;
+
+	memset(&req, 0, sizeof(struct qlcnic_nic_req));
+	req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
+
+	word = QLCNIC_H2C_OPCODE_LRO_REQUEST |
+		((u64)adapter->portnum << 16) |
+		((u64)QLCNIC_LRO_REQUEST_CLEANUP << 56) ;
+
+	req.req_hdr = cpu_to_le64(word);
+
+	rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+	if (rv != 0)
+		dev_err(&adapter->netdev->dev,
+				 "could not cleanup lro flows\n");
+
+	return rv;
+}
+
+/*
+ * qlcnic_change_mtu - Change the Maximum Transfer Unit
+ * @returns 0 on success, negative on failure
+ */
+
+int qlcnic_change_mtu(struct net_device *netdev, int mtu)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	int rc = 0;
+
+	if (mtu > P3_MAX_MTU) {
+		dev_err(&adapter->netdev->dev, "mtu > %d bytes unsupported\n",
+						P3_MAX_MTU);
+		return -EINVAL;
+	}
+
+	rc = qlcnic_fw_cmd_set_mtu(adapter, mtu);
+
+	if (!rc)
+		netdev->mtu = mtu;
+
+	return rc;
+}
+
+int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u64 *mac)
+{
+	u32 crbaddr, mac_hi, mac_lo;
+	int pci_func = adapter->ahw.pci_func;
+
+	crbaddr = CRB_MAC_BLOCK_START +
+		(4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));
+
+	mac_lo = QLCRD32(adapter, crbaddr);
+	mac_hi = QLCRD32(adapter, crbaddr+4);
+
+	if (pci_func & 1)
+		*mac = le64_to_cpu((mac_lo >> 16) | ((u64)mac_hi << 16));
+	else
+		*mac = le64_to_cpu((u64)mac_lo | ((u64)mac_hi << 32));
+
+	return 0;
+}
+
+/*
+ * Changes the CRB window to the specified window.
+ */
+ /* Returns < 0 if off is not valid,
+ *	 1 if window access is needed. 'off' is set to offset from
+ *	   CRB space in 128M pci map
+ *	 0 if no window access is needed. 'off' is set to 2M addr
+ * In: 'off' is offset from base in 128M pci map
+ */
+static int
+qlcnic_pci_get_crb_addr_2M(struct qlcnic_adapter *adapter,
+		ulong off, void __iomem **addr)
+{
+	const struct crb_128M_2M_sub_block_map *m;
+
+	if ((off >= QLCNIC_CRB_MAX) || (off < QLCNIC_PCI_CRBSPACE))
+		return -EINVAL;
+
+	off -= QLCNIC_PCI_CRBSPACE;
+
+	/*
+	 * Try direct map
+	 */
+	m = &crb_128M_2M_map[CRB_BLK(off)].sub_block[CRB_SUBBLK(off)];
+
+	if (m->valid && (m->start_128M <= off) && (m->end_128M > off)) {
+		*addr = adapter->ahw.pci_base0 + m->start_2M +
+			(off - m->start_128M);
+		return 0;
+	}
+
+	/*
+	 * Not in direct map, use crb window
+	 */
+	*addr = adapter->ahw.pci_base0 + CRB_INDIRECT_2M + (off & MASK(16));
+	return 1;
+}
+
+/*
+ * In: 'off' is offset from CRB space in 128M pci map
+ * Out: 'off' is 2M pci map addr
+ * side effect: lock crb window
+ */
+static void
+qlcnic_pci_set_crbwindow_2M(struct qlcnic_adapter *adapter, ulong off)
+{
+	u32 window;
+	void __iomem *addr = adapter->ahw.pci_base0 + CRB_WINDOW_2M;
+
+	off -= QLCNIC_PCI_CRBSPACE;
+
+	window = CRB_HI(off);
+
+	if (adapter->ahw.crb_win == window)
+		return;
+
+	writel(window, addr);
+	if (readl(addr) != window) {
+		if (printk_ratelimit())
+			dev_warn(&adapter->pdev->dev,
+				"failed to set CRB window to %d off 0x%lx\n",
+				window, off);
+	}
+	adapter->ahw.crb_win = window;
+}
+
+int
+qlcnic_hw_write_wx_2M(struct qlcnic_adapter *adapter, ulong off, u32 data)
+{
+	unsigned long flags;
+	int rv;
+	void __iomem *addr = NULL;
+
+	rv = qlcnic_pci_get_crb_addr_2M(adapter, off, &addr);
+
+	if (rv == 0) {
+		writel(data, addr);
+		return 0;
+	}
+
+	if (rv > 0) {
+		/* indirect access */
+		write_lock_irqsave(&adapter->ahw.crb_lock, flags);
+		crb_win_lock(adapter);
+		qlcnic_pci_set_crbwindow_2M(adapter, off);
+		writel(data, addr);
+		crb_win_unlock(adapter);
+		write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
+		return 0;
+	}
+
+	dev_err(&adapter->pdev->dev,
+			"%s: invalid offset: 0x%016lx\n", __func__, off);
+	dump_stack();
+	return -EIO;
+}
+
+u32
+qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off)
+{
+	unsigned long flags;
+	int rv;
+	u32 data;
+	void __iomem *addr = NULL;
+
+	rv = qlcnic_pci_get_crb_addr_2M(adapter, off, &addr);
+
+	if (rv == 0)
+		return readl(addr);
+
+	if (rv > 0) {
+		/* indirect access */
+		write_lock_irqsave(&adapter->ahw.crb_lock, flags);
+		crb_win_lock(adapter);
+		qlcnic_pci_set_crbwindow_2M(adapter, off);
+		data = readl(addr);
+		crb_win_unlock(adapter);
+		write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
+		return data;
+	}
+
+	dev_err(&adapter->pdev->dev,
+			"%s: invalid offset: 0x%016lx\n", __func__, off);
+	dump_stack();
+	return -1;
+}
+
+
+void __iomem *
+qlcnic_get_ioaddr(struct qlcnic_adapter *adapter, u32 offset)
+{
+	void __iomem *addr = NULL;
+
+	WARN_ON(qlcnic_pci_get_crb_addr_2M(adapter, offset, &addr));
+
+	return addr;
+}
+
+
+static int
+qlcnic_pci_set_window_2M(struct qlcnic_adapter *adapter,
+		u64 addr, u32 *start)
+{
+	u32 window;
+	struct pci_dev *pdev = adapter->pdev;
+
+	if ((addr & 0x00ff800) == 0xff800) {
+		if (printk_ratelimit())
+			dev_warn(&pdev->dev, "QM access not handled\n");
+		return -EIO;
+	}
+
+	window = OCM_WIN_P3P(addr);
+
+	writel(window, adapter->ahw.ocm_win_crb);
+	/* read back to flush */
+	readl(adapter->ahw.ocm_win_crb);
+
+	adapter->ahw.ocm_win = window;
+	*start = QLCNIC_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr);
+	return 0;
+}
+
+static int
+qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off,
+		u64 *data, int op)
+{
+	void __iomem *addr, *mem_ptr = NULL;
+	resource_size_t mem_base;
+	int ret;
+	u32 start;
+
+	mutex_lock(&adapter->ahw.mem_lock);
+
+	ret = qlcnic_pci_set_window_2M(adapter, off, &start);
+	if (ret != 0)
+		goto unlock;
+
+	addr = pci_base_offset(adapter, start);
+	if (addr)
+		goto noremap;
+
+	mem_base = pci_resource_start(adapter->pdev, 0) + (start & PAGE_MASK);
+
+	mem_ptr = ioremap(mem_base, PAGE_SIZE);
+	if (mem_ptr == NULL) {
+		ret = -EIO;
+		goto unlock;
+	}
+
+	addr = mem_ptr + (start & (PAGE_SIZE - 1));
+
+noremap:
+	if (op == 0)	/* read */
+		*data = readq(addr);
+	else		/* write */
+		writeq(*data, addr);
+
+unlock:
+	mutex_unlock(&adapter->ahw.mem_lock);
+
+	if (mem_ptr)
+		iounmap(mem_ptr);
+	return ret;
+}
+
+#define MAX_CTL_CHECK   1000
+
+int
+qlcnic_pci_mem_write_2M(struct qlcnic_adapter *adapter,
+		u64 off, u64 data)
+{
+	int i, j, ret;
+	u32 temp, off8;
+	u64 stride;
+	void __iomem *mem_crb;
+
+	/* Only 64-bit aligned access */
+	if (off & 7)
+		return -EIO;
+
+	/* P3 onward, test agent base for MIU and SIU is same */
+	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET,
+				QLCNIC_ADDR_QDR_NET_MAX_P3)) {
+		mem_crb = qlcnic_get_ioaddr(adapter,
+				QLCNIC_CRB_QDR_NET+MIU_TEST_AGT_BASE);
+		goto correct;
+	}
+
+	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET, QLCNIC_ADDR_DDR_NET_MAX)) {
+		mem_crb = qlcnic_get_ioaddr(adapter,
+				QLCNIC_CRB_DDR_NET+MIU_TEST_AGT_BASE);
+		goto correct;
+	}
+
+	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_OCM0, QLCNIC_ADDR_OCM0_MAX))
+		return qlcnic_pci_mem_access_direct(adapter, off, &data, 1);
+
+	return -EIO;
+
+correct:
+	stride = QLCNIC_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8;
+
+	off8 = off & ~(stride-1);
+
+	mutex_lock(&adapter->ahw.mem_lock);
+
+	writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
+	writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
+
+	i = 0;
+	if (stride == 16) {
+		writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
+		writel((TA_CTL_START | TA_CTL_ENABLE),
+				(mem_crb + TEST_AGT_CTRL));
+
+		for (j = 0; j < MAX_CTL_CHECK; j++) {
+			temp = readl(mem_crb + TEST_AGT_CTRL);
+			if ((temp & TA_CTL_BUSY) == 0)
+				break;
+		}
+
+		if (j >= MAX_CTL_CHECK) {
+			ret = -EIO;
+			goto done;
+		}
+
+		i = (off & 0xf) ? 0 : 2;
+		writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i)),
+				mem_crb + MIU_TEST_AGT_WRDATA(i));
+		writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i+1)),
+				mem_crb + MIU_TEST_AGT_WRDATA(i+1));
+		i = (off & 0xf) ? 2 : 0;
+	}
+
+	writel(data & 0xffffffff,
+			mem_crb + MIU_TEST_AGT_WRDATA(i));
+	writel((data >> 32) & 0xffffffff,
+			mem_crb + MIU_TEST_AGT_WRDATA(i+1));
+
+	writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL));
+	writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE),
+			(mem_crb + TEST_AGT_CTRL));
+
+	for (j = 0; j < MAX_CTL_CHECK; j++) {
+		temp = readl(mem_crb + TEST_AGT_CTRL);
+		if ((temp & TA_CTL_BUSY) == 0)
+			break;
+	}
+
+	if (j >= MAX_CTL_CHECK) {
+		if (printk_ratelimit())
+			dev_err(&adapter->pdev->dev,
+					"failed to write through agent\n");
+		ret = -EIO;
+	} else
+		ret = 0;
+
+done:
+	mutex_unlock(&adapter->ahw.mem_lock);
+
+	return ret;
+}
+
+int
+qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter,
+		u64 off, u64 *data)
+{
+	int j, ret;
+	u32 temp, off8;
+	u64 val, stride;
+	void __iomem *mem_crb;
+
+	/* Only 64-bit aligned access */
+	if (off & 7)
+		return -EIO;
+
+	/* P3 onward, test agent base for MIU and SIU is same */
+	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET,
+				QLCNIC_ADDR_QDR_NET_MAX_P3)) {
+		mem_crb = qlcnic_get_ioaddr(adapter,
+				QLCNIC_CRB_QDR_NET+MIU_TEST_AGT_BASE);
+		goto correct;
+	}
+
+	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET, QLCNIC_ADDR_DDR_NET_MAX)) {
+		mem_crb = qlcnic_get_ioaddr(adapter,
+				QLCNIC_CRB_DDR_NET+MIU_TEST_AGT_BASE);
+		goto correct;
+	}
+
+	if (ADDR_IN_RANGE(off, QLCNIC_ADDR_OCM0, QLCNIC_ADDR_OCM0_MAX)) {
+		return qlcnic_pci_mem_access_direct(adapter,
+				off, data, 0);
+	}
+
+	return -EIO;
+
+correct:
+	stride = QLCNIC_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8;
+
+	off8 = off & ~(stride-1);
+
+	mutex_lock(&adapter->ahw.mem_lock);
+
+	writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
+	writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
+	writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
+	writel((TA_CTL_START | TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL));
+
+	for (j = 0; j < MAX_CTL_CHECK; j++) {
+		temp = readl(mem_crb + TEST_AGT_CTRL);
+		if ((temp & TA_CTL_BUSY) == 0)
+			break;
+	}
+
+	if (j >= MAX_CTL_CHECK) {
+		if (printk_ratelimit())
+			dev_err(&adapter->pdev->dev,
+					"failed to read through agent\n");
+		ret = -EIO;
+	} else {
+		off8 = MIU_TEST_AGT_RDDATA_LO;
+		if ((stride == 16) && (off & 0xf))
+			off8 = MIU_TEST_AGT_RDDATA_UPPER_LO;
+
+		temp = readl(mem_crb + off8 + 4);
+		val = (u64)temp << 32;
+		val |= readl(mem_crb + off8);
+		*data = val;
+		ret = 0;
+	}
+
+	mutex_unlock(&adapter->ahw.mem_lock);
+
+	return ret;
+}
+
+int qlcnic_get_board_info(struct qlcnic_adapter *adapter)
+{
+	int offset, board_type, magic;
+	struct pci_dev *pdev = adapter->pdev;
+
+	offset = QLCNIC_FW_MAGIC_OFFSET;
+	if (qlcnic_rom_fast_read(adapter, offset, &magic))
+		return -EIO;
+
+	if (magic != QLCNIC_BDINFO_MAGIC) {
+		dev_err(&pdev->dev, "invalid board config, magic=%08x\n",
+			magic);
+		return -EIO;
+	}
+
+	offset = QLCNIC_BRDTYPE_OFFSET;
+	if (qlcnic_rom_fast_read(adapter, offset, &board_type))
+		return -EIO;
+
+	adapter->ahw.board_type = board_type;
+
+	if (board_type == QLCNIC_BRDTYPE_P3_4_GB_MM) {
+		u32 gpio = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_PAD_GPIO_I);
+		if ((gpio & 0x8000) == 0)
+			board_type = QLCNIC_BRDTYPE_P3_10G_TP;
+	}
+
+	switch (board_type) {
+	case QLCNIC_BRDTYPE_P3_HMEZ:
+	case QLCNIC_BRDTYPE_P3_XG_LOM:
+	case QLCNIC_BRDTYPE_P3_10G_CX4:
+	case QLCNIC_BRDTYPE_P3_10G_CX4_LP:
+	case QLCNIC_BRDTYPE_P3_IMEZ:
+	case QLCNIC_BRDTYPE_P3_10G_SFP_PLUS:
+	case QLCNIC_BRDTYPE_P3_10G_SFP_CT:
+	case QLCNIC_BRDTYPE_P3_10G_SFP_QT:
+	case QLCNIC_BRDTYPE_P3_10G_XFP:
+	case QLCNIC_BRDTYPE_P3_10000_BASE_T:
+		adapter->ahw.port_type = QLCNIC_XGBE;
+		break;
+	case QLCNIC_BRDTYPE_P3_REF_QG:
+	case QLCNIC_BRDTYPE_P3_4_GB:
+	case QLCNIC_BRDTYPE_P3_4_GB_MM:
+		adapter->ahw.port_type = QLCNIC_GBE;
+		break;
+	case QLCNIC_BRDTYPE_P3_10G_TP:
+		adapter->ahw.port_type = (adapter->portnum < 2) ?
+			QLCNIC_XGBE : QLCNIC_GBE;
+		break;
+	default:
+		dev_err(&pdev->dev, "unknown board type %x\n", board_type);
+		adapter->ahw.port_type = QLCNIC_XGBE;
+		break;
+	}
+
+	return 0;
+}
+
+int
+qlcnic_wol_supported(struct qlcnic_adapter *adapter)
+{
+	u32 wol_cfg;
+
+	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
+	if (wol_cfg & (1UL << adapter->portnum)) {
+		wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
+		if (wol_cfg & (1 << adapter->portnum))
+			return 1;
+	}
+
+	return 0;
+}
+
+int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
+{
+	struct qlcnic_nic_req   req;
+	int rv;
+	u64 word;
+
+	memset(&req, 0, sizeof(struct qlcnic_nic_req));
+	req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
+
+	word = QLCNIC_H2C_OPCODE_CONFIG_LED | ((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word);
+
+	req.words[0] = cpu_to_le64((u64)rate << 32);
+	req.words[1] = cpu_to_le64(state);
+
+	rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+	if (rv)
+		dev_err(&adapter->pdev->dev, "LED configuration failed.\n");
+
+	return rv;
+}
+
+static int qlcnic_set_fw_loopback(struct qlcnic_adapter *adapter, u32 flag)
+{
+	struct qlcnic_nic_req	req;
+	int			rv;
+	u64			word;
+
+	memset(&req, 0, sizeof(struct qlcnic_nic_req));
+	req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
+
+	word = QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK |
+			((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word);
+	req.words[0] = cpu_to_le64(flag);
+
+	rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+	if (rv)
+		dev_err(&adapter->pdev->dev,
+			"%sting loopback mode failed.\n",
+					flag ? "Set" : "Reset");
+	return rv;
+}
+
+int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter)
+{
+	if (qlcnic_set_fw_loopback(adapter, 1))
+		return -EIO;
+
+	if (qlcnic_nic_set_promisc(adapter,
+				VPORT_MISS_MODE_ACCEPT_ALL)) {
+		qlcnic_set_fw_loopback(adapter, 0);
+		return -EIO;
+	}
+
+	msleep(1000);
+	return 0;
+}
+
+void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter)
+{
+	int mode = VPORT_MISS_MODE_DROP;
+	struct net_device *netdev = adapter->netdev;
+
+	qlcnic_set_fw_loopback(adapter, 0);
+
+	if (netdev->flags & IFF_PROMISC)
+		mode = VPORT_MISS_MODE_ACCEPT_ALL;
+	else if (netdev->flags & IFF_ALLMULTI)
+		mode = VPORT_MISS_MODE_ACCEPT_MULTI;
+
+	qlcnic_nic_set_promisc(adapter, mode);
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/qlcnic/qlcnic_init.c linux-libre-2.6.34-gnu1/drivers/net/qlcnic/qlcnic_init.c
--- linux-libre-2.6.33-gnu1/drivers/net/qlcnic/qlcnic_init.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/qlcnic/qlcnic_init.c	2013-05-03 09:47:47.000000000 -0400
@@ -0,0 +1,1678 @@
+/*
+ * Copyright (C) 2009 - QLogic Corporation.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called "COPYING".
+ *
+ */
+
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include "qlcnic.h"
+
+struct crb_addr_pair {
+	u32 addr;
+	u32 data;
+};
+
+#define QLCNIC_MAX_CRB_XFORM 60
+static unsigned int crb_addr_xform[QLCNIC_MAX_CRB_XFORM];
+
+#define crb_addr_transform(name) \
+	(crb_addr_xform[QLCNIC_HW_PX_MAP_CRB_##name] = \
+	QLCNIC_HW_CRB_HUB_AGT_ADR_##name << 20)
+
+#define QLCNIC_ADDR_ERROR (0xffffffff)
+
+static void
+qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter,
+		struct qlcnic_host_rds_ring *rds_ring);
+
+static void crb_addr_transform_setup(void)
+{
+	crb_addr_transform(XDMA);
+	crb_addr_transform(TIMR);
+	crb_addr_transform(SRE);
+	crb_addr_transform(SQN3);
+	crb_addr_transform(SQN2);
+	crb_addr_transform(SQN1);
+	crb_addr_transform(SQN0);
+	crb_addr_transform(SQS3);
+	crb_addr_transform(SQS2);
+	crb_addr_transform(SQS1);
+	crb_addr_transform(SQS0);
+	crb_addr_transform(RPMX7);
+	crb_addr_transform(RPMX6);
+	crb_addr_transform(RPMX5);
+	crb_addr_transform(RPMX4);
+	crb_addr_transform(RPMX3);
+	crb_addr_transform(RPMX2);
+	crb_addr_transform(RPMX1);
+	crb_addr_transform(RPMX0);
+	crb_addr_transform(ROMUSB);
+	crb_addr_transform(SN);
+	crb_addr_transform(QMN);
+	crb_addr_transform(QMS);
+	crb_addr_transform(PGNI);
+	crb_addr_transform(PGND);
+	crb_addr_transform(PGN3);
+	crb_addr_transform(PGN2);
+	crb_addr_transform(PGN1);
+	crb_addr_transform(PGN0);
+	crb_addr_transform(PGSI);
+	crb_addr_transform(PGSD);
+	crb_addr_transform(PGS3);
+	crb_addr_transform(PGS2);
+	crb_addr_transform(PGS1);
+	crb_addr_transform(PGS0);
+	crb_addr_transform(PS);
+	crb_addr_transform(PH);
+	crb_addr_transform(NIU);
+	crb_addr_transform(I2Q);
+	crb_addr_transform(EG);
+	crb_addr_transform(MN);
+	crb_addr_transform(MS);
+	crb_addr_transform(CAS2);
+	crb_addr_transform(CAS1);
+	crb_addr_transform(CAS0);
+	crb_addr_transform(CAM);
+	crb_addr_transform(C2C1);
+	crb_addr_transform(C2C0);
+	crb_addr_transform(SMB);
+	crb_addr_transform(OCM0);
+	crb_addr_transform(I2C0);
+}
+
+void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_recv_context *recv_ctx;
+	struct qlcnic_host_rds_ring *rds_ring;
+	struct qlcnic_rx_buffer *rx_buf;
+	int i, ring;
+
+	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 == QLCNIC_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);
+		}
+	}
+}
+
+void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_cmd_buffer *cmd_buf;
+	struct qlcnic_skb_frag *buffrag;
+	int i, j;
+	struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring;
+
+	cmd_buf = tx_ring->cmd_buf_arr;
+	for (i = 0; i < tx_ring->num_desc; i++) {
+		buffrag = cmd_buf->frag_array;
+		if (buffrag->dma) {
+			pci_unmap_single(adapter->pdev, buffrag->dma,
+					 buffrag->length, PCI_DMA_TODEVICE);
+			buffrag->dma = 0ULL;
+		}
+		for (j = 0; j < cmd_buf->frag_count; j++) {
+			buffrag++;
+			if (buffrag->dma) {
+				pci_unmap_page(adapter->pdev, buffrag->dma,
+					       buffrag->length,
+					       PCI_DMA_TODEVICE);
+				buffrag->dma = 0ULL;
+			}
+		}
+		if (cmd_buf->skb) {
+			dev_kfree_skb_any(cmd_buf->skb);
+			cmd_buf->skb = NULL;
+		}
+		cmd_buf++;
+	}
+}
+
+void qlcnic_free_sw_resources(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_recv_context *recv_ctx;
+	struct qlcnic_host_rds_ring *rds_ring;
+	struct qlcnic_host_tx_ring *tx_ring;
+	int ring;
+
+	recv_ctx = &adapter->recv_ctx;
+
+	if (recv_ctx->rds_rings == NULL)
+		goto skip_rds;
+
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		rds_ring = &recv_ctx->rds_rings[ring];
+		vfree(rds_ring->rx_buf_arr);
+		rds_ring->rx_buf_arr = NULL;
+	}
+	kfree(recv_ctx->rds_rings);
+
+skip_rds:
+	if (adapter->tx_ring == NULL)
+		return;
+
+	tx_ring = adapter->tx_ring;
+	vfree(tx_ring->cmd_buf_arr);
+	kfree(adapter->tx_ring);
+}
+
+int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_recv_context *recv_ctx;
+	struct qlcnic_host_rds_ring *rds_ring;
+	struct qlcnic_host_sds_ring *sds_ring;
+	struct qlcnic_host_tx_ring *tx_ring;
+	struct qlcnic_rx_buffer *rx_buf;
+	int ring, i, size;
+
+	struct qlcnic_cmd_buffer *cmd_buf_arr;
+	struct net_device *netdev = adapter->netdev;
+
+	size = sizeof(struct qlcnic_host_tx_ring);
+	tx_ring = kzalloc(size, GFP_KERNEL);
+	if (tx_ring == NULL) {
+		dev_err(&netdev->dev, "failed to allocate tx ring struct\n");
+		return -ENOMEM;
+	}
+	adapter->tx_ring = tx_ring;
+
+	tx_ring->num_desc = adapter->num_txd;
+	tx_ring->txq = netdev_get_tx_queue(netdev, 0);
+
+	cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring));
+	if (cmd_buf_arr == NULL) {
+		dev_err(&netdev->dev, "failed to allocate cmd buffer ring\n");
+		return -ENOMEM;
+	}
+	memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring));
+	tx_ring->cmd_buf_arr = cmd_buf_arr;
+
+	recv_ctx = &adapter->recv_ctx;
+
+	size = adapter->max_rds_rings * sizeof(struct qlcnic_host_rds_ring);
+	rds_ring = kzalloc(size, GFP_KERNEL);
+	if (rds_ring == NULL) {
+		dev_err(&netdev->dev, "failed to allocate rds ring struct\n");
+		return -ENOMEM;
+	}
+	recv_ctx->rds_rings = rds_ring;
+
+	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 =
+					QLCNIC_CT_DEFAULT_RX_BUF_LEN;
+				rds_ring->skb_size =
+					QLCNIC_CT_DEFAULT_RX_BUF_LEN;
+			} else {
+				rds_ring->dma_size =
+					QLCNIC_P3_RX_BUF_MAX_LEN;
+				rds_ring->skb_size =
+					rds_ring->dma_size + NET_IP_ALIGN;
+			}
+			break;
+
+		case RCV_RING_JUMBO:
+			rds_ring->num_desc = adapter->num_jumbo_rxd;
+			rds_ring->dma_size =
+				QLCNIC_P3_RX_JUMBO_BUF_MAX_LEN;
+
+			if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
+				rds_ring->dma_size += QLCNIC_LRO_BUFFER_EXTRA;
+
+			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 = QLCNIC_RX_LRO_BUFFER_LENGTH;
+			rds_ring->skb_size = rds_ring->dma_size + NET_IP_ALIGN;
+			break;
+
+		}
+		rds_ring->rx_buf_arr = (struct qlcnic_rx_buffer *)
+			vmalloc(RCV_BUFF_RINGSIZE(rds_ring));
+		if (rds_ring->rx_buf_arr == NULL) {
+			dev_err(&netdev->dev, "Failed to allocate "
+				"rx buffer ring %d\n", ring);
+			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.
+		 */
+		rx_buf = rds_ring->rx_buf_arr;
+		for (i = 0; i < rds_ring->num_desc; i++) {
+			list_add_tail(&rx_buf->list,
+					&rds_ring->free_list);
+			rx_buf->ref_handle = i;
+			rx_buf->state = QLCNIC_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->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;
+
+err_out:
+	qlcnic_free_sw_resources(adapter);
+	return -ENOMEM;
+}
+
+/*
+ * Utility to translate from internal Phantom CRB address
+ * to external PCI CRB address.
+ */
+static u32 qlcnic_decode_crb_addr(u32 addr)
+{
+	int i;
+	u32 base_addr, offset, pci_base;
+
+	crb_addr_transform_setup();
+
+	pci_base = QLCNIC_ADDR_ERROR;
+	base_addr = addr & 0xfff00000;
+	offset = addr & 0x000fffff;
+
+	for (i = 0; i < QLCNIC_MAX_CRB_XFORM; i++) {
+		if (crb_addr_xform[i] == base_addr) {
+			pci_base = i << 20;
+			break;
+		}
+	}
+	if (pci_base == QLCNIC_ADDR_ERROR)
+		return pci_base;
+	else
+		return pci_base + offset;
+}
+
+#define QLCNIC_MAX_ROM_WAIT_USEC	100
+
+static int qlcnic_wait_rom_done(struct qlcnic_adapter *adapter)
+{
+	long timeout = 0;
+	long done = 0;
+
+	cond_resched();
+
+	while (done == 0) {
+		done = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_STATUS);
+		done &= 2;
+		if (++timeout >= QLCNIC_MAX_ROM_WAIT_USEC) {
+			dev_err(&adapter->pdev->dev,
+				"Timeout reached  waiting for rom done");
+			return -EIO;
+		}
+		udelay(1);
+	}
+	return 0;
+}
+
+static int do_rom_fast_read(struct qlcnic_adapter *adapter,
+			    int addr, int *valp)
+{
+	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_ADDRESS, addr);
+	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_ABYTE_CNT, 3);
+	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_INSTR_OPCODE, 0xb);
+	if (qlcnic_wait_rom_done(adapter)) {
+		dev_err(&adapter->pdev->dev, "Error waiting for rom done\n");
+		return -EIO;
+	}
+	/* reset abyte_cnt and dummy_byte_cnt */
+	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_ABYTE_CNT, 0);
+	udelay(10);
+	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+
+	*valp = QLCRD32(adapter, QLCNIC_ROMUSB_ROM_RDATA);
+	return 0;
+}
+
+static int do_rom_fast_read_words(struct qlcnic_adapter *adapter, int addr,
+				  u8 *bytes, size_t size)
+{
+	int addridx;
+	int ret = 0;
+
+	for (addridx = addr; addridx < (addr + size); addridx += 4) {
+		int v;
+		ret = do_rom_fast_read(adapter, addridx, &v);
+		if (ret != 0)
+			break;
+		*(__le32 *)bytes = cpu_to_le32(v);
+		bytes += 4;
+	}
+
+	return ret;
+}
+
+int
+qlcnic_rom_fast_read_words(struct qlcnic_adapter *adapter, int addr,
+				u8 *bytes, size_t size)
+{
+	int ret;
+
+	ret = qlcnic_rom_lock(adapter);
+	if (ret < 0)
+		return ret;
+
+	ret = do_rom_fast_read_words(adapter, addr, bytes, size);
+
+	qlcnic_rom_unlock(adapter);
+	return ret;
+}
+
+int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, int addr, int *valp)
+{
+	int ret;
+
+	if (qlcnic_rom_lock(adapter) != 0)
+		return -EIO;
+
+	ret = do_rom_fast_read(adapter, addr, valp);
+	qlcnic_rom_unlock(adapter);
+	return ret;
+}
+
+int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter)
+{
+	int addr, val;
+	int i, n, init_delay;
+	struct crb_addr_pair *buf;
+	unsigned offset;
+	u32 off;
+	struct pci_dev *pdev = adapter->pdev;
+
+	/* resetall */
+	qlcnic_rom_lock(adapter);
+	QLCWR32(adapter, QLCNIC_ROMUSB_GLB_SW_RESET, 0xffffffff);
+	qlcnic_rom_unlock(adapter);
+
+	if (qlcnic_rom_fast_read(adapter, 0, &n) != 0 || (n != 0xcafecafe) ||
+			qlcnic_rom_fast_read(adapter, 4, &n) != 0) {
+		dev_err(&pdev->dev, "ERROR Reading crb_init area: val:%x\n", n);
+		return -EIO;
+	}
+	offset = n & 0xffffU;
+	n = (n >> 16) & 0xffffU;
+
+	if (n >= 1024) {
+		dev_err(&pdev->dev, "QLOGIC card flash not initialized.\n");
+		return -EIO;
+	}
+
+	buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL);
+	if (buf == NULL) {
+		dev_err(&pdev->dev, "Unable to calloc memory for rom read.\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < n; i++) {
+		if (qlcnic_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 ||
+		qlcnic_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) {
+			kfree(buf);
+			return -EIO;
+		}
+
+		buf[i].addr = addr;
+		buf[i].data = val;
+	}
+
+	for (i = 0; i < n; i++) {
+
+		off = qlcnic_decode_crb_addr(buf[i].addr);
+		if (off == QLCNIC_ADDR_ERROR) {
+			dev_err(&pdev->dev, "CRB init value out of range %x\n",
+					buf[i].addr);
+			continue;
+		}
+		off += QLCNIC_PCI_CRBSPACE;
+
+		if (off & 1)
+			continue;
+
+		/* skipping cold reboot MAGIC */
+		if (off == QLCNIC_CAM_RAM(0x1fc))
+			continue;
+		if (off == (QLCNIC_CRB_I2C0 + 0x1c))
+			continue;
+		if (off == (ROMUSB_GLB + 0xbc)) /* do not reset PCI */
+			continue;
+		if (off == (ROMUSB_GLB + 0xa8))
+			continue;
+		if (off == (ROMUSB_GLB + 0xc8)) /* core clock */
+			continue;
+		if (off == (ROMUSB_GLB + 0x24)) /* MN clock */
+			continue;
+		if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */
+			continue;
+		if ((off & 0x0ff00000) == QLCNIC_CRB_DDR_NET)
+			continue;
+		/* skip the function enable register */
+		if (off == QLCNIC_PCIE_REG(PCIE_SETUP_FUNCTION))
+			continue;
+		if (off == QLCNIC_PCIE_REG(PCIE_SETUP_FUNCTION2))
+			continue;
+		if ((off & 0x0ff00000) == QLCNIC_CRB_SMB)
+			continue;
+
+		init_delay = 1;
+		/* After writing this register, HW needs time for CRB */
+		/* to quiet down (else crb_window returns 0xffffffff) */
+		if (off == QLCNIC_ROMUSB_GLB_SW_RESET)
+			init_delay = 1000;
+
+		QLCWR32(adapter, off, buf[i].data);
+
+		msleep(init_delay);
+	}
+	kfree(buf);
+
+	/* p2dn replyCount */
+	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_D + 0xec, 0x1e);
+	/* disable_peg_cache 0 & 1*/
+	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_D + 0x4c, 8);
+	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_I + 0x4c, 8);
+
+	/* peg_clr_all */
+	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x8, 0);
+	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0xc, 0);
+	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x8, 0);
+	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_1 + 0xc, 0);
+	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_2 + 0x8, 0);
+	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_2 + 0xc, 0);
+	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x8, 0);
+	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0xc, 0);
+	return 0;
+}
+
+static int
+qlcnic_has_mn(struct qlcnic_adapter *adapter)
+{
+	u32 capability, flashed_ver;
+	capability = 0;
+
+	qlcnic_rom_fast_read(adapter,
+			QLCNIC_FW_VERSION_OFFSET, (int *)&flashed_ver);
+	flashed_ver = QLCNIC_DECODE_VERSION(flashed_ver);
+
+	if (flashed_ver >= QLCNIC_VERSION_CODE(4, 0, 220)) {
+
+		capability = QLCRD32(adapter, QLCNIC_PEG_TUNE_CAPABILITY);
+		if (capability & QLCNIC_PEG_TUNE_MN_PRESENT)
+			return 1;
+	}
+	return 0;
+}
+
+static
+struct uni_table_desc *qlcnic_get_table_desc(const u8 *unirom, int section)
+{
+	u32 i;
+	struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0];
+	__le32 entries = cpu_to_le32(directory->num_entries);
+
+	for (i = 0; i < entries; i++) {
+
+		__le32 offs = cpu_to_le32(directory->findex) +
+				(i * cpu_to_le32(directory->entry_size));
+		__le32 tab_type = cpu_to_le32(*((u32 *)&unirom[offs] + 8));
+
+		if (tab_type == section)
+			return (struct uni_table_desc *) &unirom[offs];
+	}
+
+	return NULL;
+}
+
+#define FILEHEADER_SIZE (14 * 4)
+
+static int
+qlcnic_validate_header(struct qlcnic_adapter *adapter)
+{
+	const u8 *unirom = adapter->fw->data;
+	struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0];
+	__le32 fw_file_size = adapter->fw->size;
+	__le32 entries;
+	__le32 entry_size;
+	__le32 tab_size;
+
+	if (fw_file_size < FILEHEADER_SIZE)
+		return -EINVAL;
+
+	entries = cpu_to_le32(directory->num_entries);
+	entry_size = cpu_to_le32(directory->entry_size);
+	tab_size = cpu_to_le32(directory->findex) + (entries * entry_size);
+
+	if (fw_file_size < tab_size)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+qlcnic_validate_bootld(struct qlcnic_adapter *adapter)
+{
+	struct uni_table_desc *tab_desc;
+	struct uni_data_desc *descr;
+	const u8 *unirom = adapter->fw->data;
+	int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] +
+				QLCNIC_UNI_BOOTLD_IDX_OFF));
+	__le32 offs;
+	__le32 tab_size;
+	__le32 data_size;
+
+	tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_BOOTLD);
+
+	if (!tab_desc)
+		return -EINVAL;
+
+	tab_size = cpu_to_le32(tab_desc->findex) +
+			(cpu_to_le32(tab_desc->entry_size * (idx + 1)));
+
+	if (adapter->fw->size < tab_size)
+		return -EINVAL;
+
+	offs = cpu_to_le32(tab_desc->findex) +
+		(cpu_to_le32(tab_desc->entry_size) * (idx));
+	descr = (struct uni_data_desc *)&unirom[offs];
+
+	data_size = descr->findex + cpu_to_le32(descr->size);
+
+	if (adapter->fw->size < data_size)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+qlcnic_validate_fw(struct qlcnic_adapter *adapter)
+{
+	struct uni_table_desc *tab_desc;
+	struct uni_data_desc *descr;
+	const u8 *unirom = adapter->fw->data;
+	int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] +
+				QLCNIC_UNI_FIRMWARE_IDX_OFF));
+	__le32 offs;
+	__le32 tab_size;
+	__le32 data_size;
+
+	tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_FW);
+
+	if (!tab_desc)
+		return -EINVAL;
+
+	tab_size = cpu_to_le32(tab_desc->findex) +
+			(cpu_to_le32(tab_desc->entry_size * (idx + 1)));
+
+	if (adapter->fw->size < tab_size)
+		return -EINVAL;
+
+	offs = cpu_to_le32(tab_desc->findex) +
+		(cpu_to_le32(tab_desc->entry_size) * (idx));
+	descr = (struct uni_data_desc *)&unirom[offs];
+	data_size = descr->findex + cpu_to_le32(descr->size);
+
+	if (adapter->fw->size < data_size)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+qlcnic_validate_product_offs(struct qlcnic_adapter *adapter)
+{
+	struct uni_table_desc *ptab_descr;
+	const u8 *unirom = adapter->fw->data;
+	int mn_present = qlcnic_has_mn(adapter);
+	__le32 entries;
+	__le32 entry_size;
+	__le32 tab_size;
+	u32 i;
+
+	ptab_descr = qlcnic_get_table_desc(unirom,
+				QLCNIC_UNI_DIR_SECT_PRODUCT_TBL);
+	if (!ptab_descr)
+		return -EINVAL;
+
+	entries = cpu_to_le32(ptab_descr->num_entries);
+	entry_size = cpu_to_le32(ptab_descr->entry_size);
+	tab_size = cpu_to_le32(ptab_descr->findex) + (entries * entry_size);
+
+	if (adapter->fw->size < tab_size)
+		return -EINVAL;
+
+nomn:
+	for (i = 0; i < entries; i++) {
+
+		__le32 flags, file_chiprev, offs;
+		u8 chiprev = adapter->ahw.revision_id;
+		u32 flagbit;
+
+		offs = cpu_to_le32(ptab_descr->findex) +
+				(i * cpu_to_le32(ptab_descr->entry_size));
+		flags = cpu_to_le32(*((int *)&unirom[offs] +
+						QLCNIC_UNI_FLAGS_OFF));
+		file_chiprev = cpu_to_le32(*((int *)&unirom[offs] +
+						QLCNIC_UNI_CHIP_REV_OFF));
+
+		flagbit = mn_present ? 1 : 2;
+
+		if ((chiprev == file_chiprev) &&
+					((1ULL << flagbit) & flags)) {
+			adapter->file_prd_off = offs;
+			return 0;
+		}
+	}
+	if (mn_present) {
+		mn_present = 0;
+		goto nomn;
+	}
+	return -EINVAL;
+}
+
+static int
+qlcnic_validate_unified_romimage(struct qlcnic_adapter *adapter)
+{
+	if (qlcnic_validate_header(adapter)) {
+		dev_err(&adapter->pdev->dev,
+				"unified image: header validation failed\n");
+		return -EINVAL;
+	}
+
+	if (qlcnic_validate_product_offs(adapter)) {
+		dev_err(&adapter->pdev->dev,
+				"unified image: product validation failed\n");
+		return -EINVAL;
+	}
+
+	if (qlcnic_validate_bootld(adapter)) {
+		dev_err(&adapter->pdev->dev,
+				"unified image: bootld validation failed\n");
+		return -EINVAL;
+	}
+
+	if (qlcnic_validate_fw(adapter)) {
+		dev_err(&adapter->pdev->dev,
+				"unified image: firmware validation failed\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static
+struct uni_data_desc *qlcnic_get_data_desc(struct qlcnic_adapter *adapter,
+			u32 section, u32 idx_offset)
+{
+	const u8 *unirom = adapter->fw->data;
+	int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] +
+								idx_offset));
+	struct uni_table_desc *tab_desc;
+	__le32 offs;
+
+	tab_desc = qlcnic_get_table_desc(unirom, section);
+
+	if (tab_desc == NULL)
+		return NULL;
+
+	offs = cpu_to_le32(tab_desc->findex) +
+			(cpu_to_le32(tab_desc->entry_size) * idx);
+
+	return (struct uni_data_desc *)&unirom[offs];
+}
+
+static u8 *
+qlcnic_get_bootld_offs(struct qlcnic_adapter *adapter)
+{
+	u32 offs = QLCNIC_BOOTLD_START;
+
+	if (adapter->fw_type == QLCNIC_UNIFIED_ROMIMAGE)
+		offs = cpu_to_le32((qlcnic_get_data_desc(adapter,
+					QLCNIC_UNI_DIR_SECT_BOOTLD,
+					QLCNIC_UNI_BOOTLD_IDX_OFF))->findex);
+
+	return (u8 *)&adapter->fw->data[offs];
+}
+
+static u8 *
+qlcnic_get_fw_offs(struct qlcnic_adapter *adapter)
+{
+	u32 offs = QLCNIC_IMAGE_START;
+
+	if (adapter->fw_type == QLCNIC_UNIFIED_ROMIMAGE)
+		offs = cpu_to_le32((qlcnic_get_data_desc(adapter,
+					QLCNIC_UNI_DIR_SECT_FW,
+					QLCNIC_UNI_FIRMWARE_IDX_OFF))->findex);
+
+	return (u8 *)&adapter->fw->data[offs];
+}
+
+static __le32
+qlcnic_get_fw_size(struct qlcnic_adapter *adapter)
+{
+	if (adapter->fw_type == QLCNIC_UNIFIED_ROMIMAGE)
+		return cpu_to_le32((qlcnic_get_data_desc(adapter,
+					QLCNIC_UNI_DIR_SECT_FW,
+					QLCNIC_UNI_FIRMWARE_IDX_OFF))->size);
+	else
+		return cpu_to_le32(
+			*(u32 *)&adapter->fw->data[QLCNIC_FW_SIZE_OFFSET]);
+}
+
+static __le32
+qlcnic_get_fw_version(struct qlcnic_adapter *adapter)
+{
+	struct uni_data_desc *fw_data_desc;
+	const struct firmware *fw = adapter->fw;
+	__le32 major, minor, sub;
+	const u8 *ver_str;
+	int i, ret;
+
+	if (adapter->fw_type != QLCNIC_UNIFIED_ROMIMAGE)
+		return cpu_to_le32(*(u32 *)&fw->data[QLCNIC_FW_VERSION_OFFSET]);
+
+	fw_data_desc = qlcnic_get_data_desc(adapter, QLCNIC_UNI_DIR_SECT_FW,
+			QLCNIC_UNI_FIRMWARE_IDX_OFF);
+	ver_str = fw->data + cpu_to_le32(fw_data_desc->findex) +
+		cpu_to_le32(fw_data_desc->size) - 17;
+
+	for (i = 0; i < 12; i++) {
+		if (!strncmp(&ver_str[i], "REV=", 4)) {
+			ret = sscanf(&ver_str[i+4], "%u.%u.%u ",
+					&major, &minor, &sub);
+			if (ret != 3)
+				return 0;
+			else
+				return major + (minor << 8) + (sub << 16);
+		}
+	}
+
+	return 0;
+}
+
+static __le32
+qlcnic_get_bios_version(struct qlcnic_adapter *adapter)
+{
+	const struct firmware *fw = adapter->fw;
+	__le32 bios_ver, prd_off = adapter->file_prd_off;
+
+	if (adapter->fw_type != QLCNIC_UNIFIED_ROMIMAGE)
+		return cpu_to_le32(
+			*(u32 *)&fw->data[QLCNIC_BIOS_VERSION_OFFSET]);
+
+	bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off])
+				+ QLCNIC_UNI_BIOS_VERSION_OFF));
+
+	return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24);
+}
+
+int
+qlcnic_need_fw_reset(struct qlcnic_adapter *adapter)
+{
+	u32 count, old_count;
+	u32 val, version, major, minor, build;
+	int i, timeout;
+
+	if (adapter->need_fw_reset)
+		return 1;
+
+	/* last attempt had failed */
+	if (QLCRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED)
+		return 1;
+
+	old_count = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
+
+	for (i = 0; i < 10; i++) {
+
+		timeout = msleep_interruptible(200);
+		if (timeout) {
+			QLCWR32(adapter, CRB_CMDPEG_STATE,
+					PHAN_INITIALIZE_FAILED);
+			return -EINTR;
+		}
+
+		count = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
+		if (count != old_count)
+			break;
+	}
+
+	/* firmware is dead */
+	if (count == old_count)
+		return 1;
+
+	/* check if we have got newer or different file firmware */
+	if (adapter->fw) {
+
+		val = qlcnic_get_fw_version(adapter);
+
+		version = QLCNIC_DECODE_VERSION(val);
+
+		major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR);
+		minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR);
+		build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB);
+
+		if (version > QLCNIC_VERSION_CODE(major, minor, build))
+			return 1;
+	}
+
+	return 0;
+}
+
+static const char *fw_name[] = {
+	QLCNIC_UNIFIED_ROMIMAGE_NAME,
+	QLCNIC_FLASH_ROMIMAGE_NAME,
+};
+
+int
+qlcnic_load_firmware(struct qlcnic_adapter *adapter)
+{
+	u64 *ptr64;
+	u32 i, flashaddr, size;
+	const struct firmware *fw = adapter->fw;
+	struct pci_dev *pdev = adapter->pdev;
+
+	dev_info(&pdev->dev, "loading firmware from %s\n",
+			fw_name[adapter->fw_type]);
+
+	if (fw) {
+		__le64 data;
+
+		size = (QLCNIC_IMAGE_START - QLCNIC_BOOTLD_START) / 8;
+
+		ptr64 = (u64 *)qlcnic_get_bootld_offs(adapter);
+		flashaddr = QLCNIC_BOOTLD_START;
+
+		for (i = 0; i < size; i++) {
+			data = cpu_to_le64(ptr64[i]);
+
+			if (qlcnic_pci_mem_write_2M(adapter, flashaddr, data))
+				return -EIO;
+
+			flashaddr += 8;
+		}
+
+		size = (__force u32)qlcnic_get_fw_size(adapter) / 8;
+
+		ptr64 = (u64 *)qlcnic_get_fw_offs(adapter);
+		flashaddr = QLCNIC_IMAGE_START;
+
+		for (i = 0; i < size; i++) {
+			data = cpu_to_le64(ptr64[i]);
+
+			if (qlcnic_pci_mem_write_2M(adapter,
+						flashaddr, data))
+				return -EIO;
+
+			flashaddr += 8;
+		}
+	} else {
+		u64 data;
+		u32 hi, lo;
+
+		size = (QLCNIC_IMAGE_START - QLCNIC_BOOTLD_START) / 8;
+		flashaddr = QLCNIC_BOOTLD_START;
+
+		for (i = 0; i < size; i++) {
+			if (qlcnic_rom_fast_read(adapter,
+					flashaddr, (int *)&lo) != 0)
+				return -EIO;
+			if (qlcnic_rom_fast_read(adapter,
+					flashaddr + 4, (int *)&hi) != 0)
+				return -EIO;
+
+			data = (((u64)hi << 32) | lo);
+
+			if (qlcnic_pci_mem_write_2M(adapter,
+						flashaddr, data))
+				return -EIO;
+
+			flashaddr += 8;
+		}
+	}
+	msleep(1);
+
+	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x18, 0x1020);
+	QLCWR32(adapter, QLCNIC_ROMUSB_GLB_SW_RESET, 0x80001e);
+	return 0;
+}
+
+static int
+qlcnic_validate_firmware(struct qlcnic_adapter *adapter)
+{
+	__le32 val;
+	u32 ver, min_ver, bios, min_size;
+	struct pci_dev *pdev = adapter->pdev;
+	const struct firmware *fw = adapter->fw;
+	u8 fw_type = adapter->fw_type;
+
+	if (fw_type == QLCNIC_UNIFIED_ROMIMAGE) {
+		if (qlcnic_validate_unified_romimage(adapter))
+			return -EINVAL;
+
+		min_size = QLCNIC_UNI_FW_MIN_SIZE;
+	} else {
+		val = cpu_to_le32(*(u32 *)&fw->data[QLCNIC_FW_MAGIC_OFFSET]);
+		if ((__force u32)val != QLCNIC_BDINFO_MAGIC)
+			return -EINVAL;
+
+		min_size = QLCNIC_FW_MIN_SIZE;
+	}
+
+	if (fw->size < min_size)
+		return -EINVAL;
+
+	val = qlcnic_get_fw_version(adapter);
+
+	min_ver = QLCNIC_VERSION_CODE(4, 0, 216);
+
+	ver = QLCNIC_DECODE_VERSION(val);
+
+	if ((_major(ver) > _QLCNIC_LINUX_MAJOR) || (ver < min_ver)) {
+		dev_err(&pdev->dev,
+				"%s: firmware version %d.%d.%d unsupported\n",
+		fw_name[fw_type], _major(ver), _minor(ver), _build(ver));
+		return -EINVAL;
+	}
+
+	val = qlcnic_get_bios_version(adapter);
+	qlcnic_rom_fast_read(adapter, QLCNIC_BIOS_VERSION_OFFSET, (int *)&bios);
+	if ((__force u32)val != bios) {
+		dev_err(&pdev->dev, "%s: firmware bios is incompatible\n",
+				fw_name[fw_type]);
+		return -EINVAL;
+	}
+
+	/* check if flashed firmware is newer */
+	if (qlcnic_rom_fast_read(adapter,
+			QLCNIC_FW_VERSION_OFFSET, (int *)&val))
+		return -EIO;
+
+	val = QLCNIC_DECODE_VERSION(val);
+	if (val > ver) {
+		dev_info(&pdev->dev, "%s: firmware is older than flash\n",
+				fw_name[fw_type]);
+		return -EINVAL;
+	}
+
+	QLCWR32(adapter, QLCNIC_CAM_RAM(0x1fc), QLCNIC_BDINFO_MAGIC);
+	return 0;
+}
+
+static void
+qlcnic_get_next_fwtype(struct qlcnic_adapter *adapter)
+{
+	u8 fw_type;
+
+	switch (adapter->fw_type) {
+	case QLCNIC_UNKNOWN_ROMIMAGE:
+		fw_type = QLCNIC_UNIFIED_ROMIMAGE;
+		break;
+
+	case QLCNIC_UNIFIED_ROMIMAGE:
+	default:
+		fw_type = QLCNIC_FLASH_ROMIMAGE;
+		break;
+	}
+
+	adapter->fw_type = fw_type;
+}
+
+
+
+void qlcnic_reject_firmware(struct qlcnic_adapter *adapter)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	int rc;
+
+	adapter->fw_type = QLCNIC_UNKNOWN_ROMIMAGE;
+
+next:
+	qlcnic_get_next_fwtype(adapter);
+
+	if (adapter->fw_type == QLCNIC_FLASH_ROMIMAGE) {
+		adapter->fw = NULL;
+	} else {
+		rc = reject_firmware(&adapter->fw,
+				fw_name[adapter->fw_type], &pdev->dev);
+		if (rc != 0)
+			goto next;
+
+		rc = qlcnic_validate_firmware(adapter);
+		if (rc != 0) {
+			release_firmware(adapter->fw);
+			msleep(1);
+			goto next;
+		}
+	}
+}
+
+
+void
+qlcnic_release_firmware(struct qlcnic_adapter *adapter)
+{
+	if (adapter->fw)
+		release_firmware(adapter->fw);
+	adapter->fw = NULL;
+}
+
+int qlcnic_phantom_init(struct qlcnic_adapter *adapter)
+{
+	u32 val;
+	int retries = 60;
+
+	do {
+		val = QLCRD32(adapter, CRB_CMDPEG_STATE);
+
+		switch (val) {
+		case PHAN_INITIALIZE_COMPLETE:
+		case PHAN_INITIALIZE_ACK:
+			return 0;
+		case PHAN_INITIALIZE_FAILED:
+			goto out_err;
+		default:
+			break;
+		}
+
+		msleep(500);
+
+	} while (--retries);
+
+	QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED);
+
+out_err:
+	dev_err(&adapter->pdev->dev, "firmware init failed\n");
+	return -EIO;
+}
+
+static int
+qlcnic_receive_peg_ready(struct qlcnic_adapter *adapter)
+{
+	u32 val;
+	int retries = 2000;
+
+	do {
+		val = QLCRD32(adapter, CRB_RCVPEG_STATE);
+
+		if (val == PHAN_PEG_RCV_INITIALIZED)
+			return 0;
+
+		msleep(10);
+
+	} while (--retries);
+
+	if (!retries) {
+		dev_err(&adapter->pdev->dev, "Receive Peg initialization not "
+			      "complete, state: 0x%x.\n", val);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int qlcnic_init_firmware(struct qlcnic_adapter *adapter)
+{
+	int err;
+
+	err = qlcnic_receive_peg_ready(adapter);
+	if (err)
+		return err;
+
+	QLCWR32(adapter, CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT);
+	QLCWR32(adapter, CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC);
+	QLCWR32(adapter, CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
+	QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
+
+	return err;
+}
+
+static void
+qlcnic_handle_linkevent(struct qlcnic_adapter *adapter,
+				struct qlcnic_fw_msg *msg)
+{
+	u32 cable_OUI;
+	u16 cable_len;
+	u16 link_speed;
+	u8  link_status, module, duplex, autoneg;
+	struct net_device *netdev = adapter->netdev;
+
+	adapter->has_link_events = 1;
+
+	cable_OUI = msg->body[1] & 0xffffffff;
+	cable_len = (msg->body[1] >> 32) & 0xffff;
+	link_speed = (msg->body[1] >> 48) & 0xffff;
+
+	link_status = msg->body[2] & 0xff;
+	duplex = (msg->body[2] >> 16) & 0xff;
+	autoneg = (msg->body[2] >> 24) & 0xff;
+
+	module = (msg->body[2] >> 8) & 0xff;
+	if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE)
+		dev_info(&netdev->dev, "unsupported cable: OUI 0x%x, "
+				"length %d\n", cable_OUI, cable_len);
+	else if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN)
+		dev_info(&netdev->dev, "unsupported cable length %d\n",
+				cable_len);
+
+	qlcnic_advert_link_change(adapter, link_status);
+
+	if (duplex == LINKEVENT_FULL_DUPLEX)
+		adapter->link_duplex = DUPLEX_FULL;
+	else
+		adapter->link_duplex = DUPLEX_HALF;
+
+	adapter->module_type = module;
+	adapter->link_autoneg = autoneg;
+	adapter->link_speed = link_speed;
+}
+
+static void
+qlcnic_handle_fw_message(int desc_cnt, int index,
+		struct qlcnic_host_sds_ring *sds_ring)
+{
+	struct qlcnic_fw_msg msg;
+	struct status_desc *desc;
+	int i = 0, opcode;
+
+	while (desc_cnt > 0 && i < 8) {
+		desc = &sds_ring->desc_head[index];
+		msg.words[i++] = le64_to_cpu(desc->status_desc_data[0]);
+		msg.words[i++] = le64_to_cpu(desc->status_desc_data[1]);
+
+		index = get_next_index(index, sds_ring->num_desc);
+		desc_cnt--;
+	}
+
+	opcode = qlcnic_get_nic_msg_opcode(msg.body[0]);
+	switch (opcode) {
+	case QLCNIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE:
+		qlcnic_handle_linkevent(sds_ring->adapter, &msg);
+		break;
+	default:
+		break;
+	}
+}
+
+static int
+qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter,
+		struct qlcnic_host_rds_ring *rds_ring,
+		struct qlcnic_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) {
+		adapter->stats.skb_alloc_failure++;
+		return -ENOMEM;
+	}
+
+	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 -ENOMEM;
+	}
+
+	buffer->skb = skb;
+	buffer->dma = dma;
+	buffer->state = QLCNIC_BUFFER_BUSY;
+
+	return 0;
+}
+
+static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter,
+		struct qlcnic_host_rds_ring *rds_ring, u16 index, u16 cksum)
+{
+	struct qlcnic_rx_buffer *buffer;
+	struct sk_buff *skb;
+
+	buffer = &rds_ring->rx_buf_arr[index];
+
+	pci_unmap_single(adapter->pdev, buffer->dma, rds_ring->dma_size,
+			PCI_DMA_FROMDEVICE);
+
+	skb = buffer->skb;
+	if (!skb)
+		goto no_skb;
+
+	if (likely(adapter->rx_csum && cksum == STATUS_CKSUM_OK)) {
+		adapter->stats.csummed++;
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	} else {
+		skb->ip_summed = CHECKSUM_NONE;
+	}
+
+	skb->dev = adapter->netdev;
+
+	buffer->skb = NULL;
+no_skb:
+	buffer->state = QLCNIC_BUFFER_FREE;
+	return skb;
+}
+
+static struct qlcnic_rx_buffer *
+qlcnic_process_rcv(struct qlcnic_adapter *adapter,
+		struct qlcnic_host_sds_ring *sds_ring,
+		int ring, u64 sts_data0)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct qlcnic_rx_buffer *buffer;
+	struct sk_buff *skb;
+	struct qlcnic_host_rds_ring *rds_ring;
+	int index, length, cksum, pkt_offset;
+
+	if (unlikely(ring >= adapter->max_rds_rings))
+		return NULL;
+
+	rds_ring = &recv_ctx->rds_rings[ring];
+
+	index = qlcnic_get_sts_refhandle(sts_data0);
+	if (unlikely(index >= rds_ring->num_desc))
+		return NULL;
+
+	buffer = &rds_ring->rx_buf_arr[index];
+
+	length = qlcnic_get_sts_totallength(sts_data0);
+	cksum  = qlcnic_get_sts_status(sts_data0);
+	pkt_offset = qlcnic_get_sts_pkt_offset(sts_data0);
+
+	skb = qlcnic_process_rxbuf(adapter, rds_ring, index, cksum);
+	if (!skb)
+		return buffer;
+
+	if (length > rds_ring->skb_size)
+		skb_put(skb, rds_ring->skb_size);
+	else
+		skb_put(skb, length);
+
+	if (pkt_offset)
+		skb_pull(skb, pkt_offset);
+
+	skb->truesize = skb->len + sizeof(struct sk_buff);
+	skb->protocol = eth_type_trans(skb, netdev);
+
+	napi_gro_receive(&sds_ring->napi, skb);
+
+	adapter->stats.rx_pkts++;
+	adapter->stats.rxbytes += length;
+
+	return buffer;
+}
+
+#define QLC_TCP_HDR_SIZE            20
+#define QLC_TCP_TS_OPTION_SIZE      12
+#define QLC_TCP_TS_HDR_SIZE         (QLC_TCP_HDR_SIZE + QLC_TCP_TS_OPTION_SIZE)
+
+static struct qlcnic_rx_buffer *
+qlcnic_process_lro(struct qlcnic_adapter *adapter,
+		struct qlcnic_host_sds_ring *sds_ring,
+		int ring, u64 sts_data0, u64 sts_data1)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct qlcnic_rx_buffer *buffer;
+	struct sk_buff *skb;
+	struct qlcnic_host_rds_ring *rds_ring;
+	struct iphdr *iph;
+	struct tcphdr *th;
+	bool push, timestamp;
+	int l2_hdr_offset, l4_hdr_offset;
+	int index;
+	u16 lro_length, length, data_offset;
+	u32 seq_number;
+
+	if (unlikely(ring > adapter->max_rds_rings))
+		return NULL;
+
+	rds_ring = &recv_ctx->rds_rings[ring];
+
+	index = qlcnic_get_lro_sts_refhandle(sts_data0);
+	if (unlikely(index > rds_ring->num_desc))
+		return NULL;
+
+	buffer = &rds_ring->rx_buf_arr[index];
+
+	timestamp = qlcnic_get_lro_sts_timestamp(sts_data0);
+	lro_length = qlcnic_get_lro_sts_length(sts_data0);
+	l2_hdr_offset = qlcnic_get_lro_sts_l2_hdr_offset(sts_data0);
+	l4_hdr_offset = qlcnic_get_lro_sts_l4_hdr_offset(sts_data0);
+	push = qlcnic_get_lro_sts_push_flag(sts_data0);
+	seq_number = qlcnic_get_lro_sts_seq_number(sts_data1);
+
+	skb = qlcnic_process_rxbuf(adapter, rds_ring, index, STATUS_CKSUM_OK);
+	if (!skb)
+		return buffer;
+
+	if (timestamp)
+		data_offset = l4_hdr_offset + QLC_TCP_TS_HDR_SIZE;
+	else
+		data_offset = l4_hdr_offset + QLC_TCP_HDR_SIZE;
+
+	skb_put(skb, lro_length + data_offset);
+
+	skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb);
+
+	skb_pull(skb, l2_hdr_offset);
+	skb->protocol = eth_type_trans(skb, netdev);
+
+	iph = (struct iphdr *)skb->data;
+	th = (struct tcphdr *)(skb->data + (iph->ihl << 2));
+
+	length = (iph->ihl << 2) + (th->doff << 2) + lro_length;
+	iph->tot_len = htons(length);
+	iph->check = 0;
+	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
+	th->psh = push;
+	th->seq = htonl(seq_number);
+
+	length = skb->len;
+
+	netif_receive_skb(skb);
+
+	adapter->stats.lro_pkts++;
+	adapter->stats.lrobytes += length;
+
+	return buffer;
+}
+
+int
+qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max)
+{
+	struct qlcnic_adapter *adapter = sds_ring->adapter;
+	struct list_head *cur;
+	struct status_desc *desc;
+	struct qlcnic_rx_buffer *rxbuf;
+	u64 sts_data0, sts_data1;
+
+	int count = 0;
+	int opcode, ring, desc_cnt;
+	u32 consumer = sds_ring->consumer;
+
+	while (count < max) {
+		desc = &sds_ring->desc_head[consumer];
+		sts_data0 = le64_to_cpu(desc->status_desc_data[0]);
+
+		if (!(sts_data0 & STATUS_OWNER_HOST))
+			break;
+
+		desc_cnt = qlcnic_get_sts_desc_cnt(sts_data0);
+		opcode = qlcnic_get_sts_opcode(sts_data0);
+
+		switch (opcode) {
+		case QLCNIC_RXPKT_DESC:
+		case QLCNIC_OLD_RXPKT_DESC:
+		case QLCNIC_SYN_OFFLOAD:
+			ring = qlcnic_get_sts_type(sts_data0);
+			rxbuf = qlcnic_process_rcv(adapter, sds_ring,
+					ring, sts_data0);
+			break;
+		case QLCNIC_LRO_DESC:
+			ring = qlcnic_get_lro_sts_type(sts_data0);
+			sts_data1 = le64_to_cpu(desc->status_desc_data[1]);
+			rxbuf = qlcnic_process_lro(adapter, sds_ring,
+					ring, sts_data0, sts_data1);
+			break;
+		case QLCNIC_RESPONSE_DESC:
+			qlcnic_handle_fw_message(desc_cnt, consumer, sds_ring);
+		default:
+			goto skip;
+		}
+
+		WARN_ON(desc_cnt > 1);
+
+		if (rxbuf)
+			list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]);
+
+skip:
+		for (; desc_cnt > 0; desc_cnt--) {
+			desc = &sds_ring->desc_head[consumer];
+			desc->status_desc_data[0] =
+				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++) {
+		struct qlcnic_host_rds_ring *rds_ring =
+			&adapter->recv_ctx.rds_rings[ring];
+
+		if (!list_empty(&sds_ring->free_list[ring])) {
+			list_for_each(cur, &sds_ring->free_list[ring]) {
+				rxbuf = list_entry(cur,
+						struct qlcnic_rx_buffer, list);
+				qlcnic_alloc_rx_skb(adapter, rds_ring, rxbuf);
+			}
+			spin_lock(&rds_ring->lock);
+			list_splice_tail_init(&sds_ring->free_list[ring],
+						&rds_ring->free_list);
+			spin_unlock(&rds_ring->lock);
+		}
+
+		qlcnic_post_rx_buffers_nodb(adapter, rds_ring);
+	}
+
+	if (count) {
+		sds_ring->consumer = consumer;
+		writel(consumer, sds_ring->crb_sts_consumer);
+	}
+
+	return count;
+}
+
+void
+qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid,
+	struct qlcnic_host_rds_ring *rds_ring)
+{
+	struct rcv_desc *pdesc;
+	struct qlcnic_rx_buffer *buffer;
+	int producer, count = 0;
+	struct list_head *head;
+
+	producer = rds_ring->producer;
+
+	spin_lock(&rds_ring->lock);
+	head = &rds_ring->free_list;
+	while (!list_empty(head)) {
+
+		buffer = list_entry(head->next, struct qlcnic_rx_buffer, list);
+
+		if (!buffer->skb) {
+			if (qlcnic_alloc_rx_skb(adapter, rds_ring, buffer))
+				break;
+		}
+
+		count++;
+		list_del(&buffer->list);
+
+		/* make a rcv descriptor  */
+		pdesc = &rds_ring->desc_head[producer];
+		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->num_desc);
+	}
+	spin_unlock(&rds_ring->lock);
+
+	if (count) {
+		rds_ring->producer = producer;
+		writel((producer-1) & (rds_ring->num_desc-1),
+				rds_ring->crb_rcv_producer);
+	}
+}
+
+static void
+qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter,
+		struct qlcnic_host_rds_ring *rds_ring)
+{
+	struct rcv_desc *pdesc;
+	struct qlcnic_rx_buffer *buffer;
+	int producer, count = 0;
+	struct list_head *head;
+
+	producer = rds_ring->producer;
+	if (!spin_trylock(&rds_ring->lock))
+		return;
+
+	head = &rds_ring->free_list;
+	while (!list_empty(head)) {
+
+		buffer = list_entry(head->next, struct qlcnic_rx_buffer, list);
+
+		if (!buffer->skb) {
+			if (qlcnic_alloc_rx_skb(adapter, rds_ring, buffer))
+				break;
+		}
+
+		count++;
+		list_del(&buffer->list);
+
+		/* 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->num_desc);
+	}
+
+	if (count) {
+		rds_ring->producer = producer;
+		writel((producer - 1) & (rds_ring->num_desc - 1),
+				rds_ring->crb_rcv_producer);
+	}
+	spin_unlock(&rds_ring->lock);
+}
+
+static struct qlcnic_rx_buffer *
+qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter,
+		struct qlcnic_host_sds_ring *sds_ring,
+		int ring, u64 sts_data0)
+{
+	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct qlcnic_rx_buffer *buffer;
+	struct sk_buff *skb;
+	struct qlcnic_host_rds_ring *rds_ring;
+	int index, length, cksum, pkt_offset;
+
+	if (unlikely(ring >= adapter->max_rds_rings))
+		return NULL;
+
+	rds_ring = &recv_ctx->rds_rings[ring];
+
+	index = qlcnic_get_sts_refhandle(sts_data0);
+	if (unlikely(index >= rds_ring->num_desc))
+		return NULL;
+
+	buffer = &rds_ring->rx_buf_arr[index];
+
+	length = qlcnic_get_sts_totallength(sts_data0);
+	cksum  = qlcnic_get_sts_status(sts_data0);
+	pkt_offset = qlcnic_get_sts_pkt_offset(sts_data0);
+
+	skb = qlcnic_process_rxbuf(adapter, rds_ring, index, cksum);
+	if (!skb)
+		return buffer;
+
+	skb_put(skb, rds_ring->skb_size);
+
+	if (pkt_offset)
+		skb_pull(skb, pkt_offset);
+
+	skb->truesize = skb->len + sizeof(struct sk_buff);
+
+	if (!qlcnic_check_loopback_buff(skb->data))
+		adapter->diag_cnt++;
+
+	dev_kfree_skb_any(skb);
+	adapter->stats.rx_pkts++;
+	adapter->stats.rxbytes += length;
+
+	return buffer;
+}
+
+void
+qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring)
+{
+	struct qlcnic_adapter *adapter = sds_ring->adapter;
+	struct status_desc *desc;
+	struct qlcnic_rx_buffer *rxbuf;
+	u64 sts_data0;
+
+	int opcode, ring, desc_cnt;
+	u32 consumer = sds_ring->consumer;
+
+	desc = &sds_ring->desc_head[consumer];
+	sts_data0 = le64_to_cpu(desc->status_desc_data[0]);
+
+	if (!(sts_data0 & STATUS_OWNER_HOST))
+		return;
+
+	desc_cnt = qlcnic_get_sts_desc_cnt(sts_data0);
+	opcode = qlcnic_get_sts_opcode(sts_data0);
+
+	ring = qlcnic_get_sts_type(sts_data0);
+	rxbuf = qlcnic_process_rcv_diag(adapter, sds_ring,
+					ring, sts_data0);
+
+	desc->status_desc_data[0] = cpu_to_le64(STATUS_OWNER_PHANTOM);
+	consumer = get_next_index(consumer, sds_ring->num_desc);
+
+	sds_ring->consumer = consumer;
+	writel(consumer, sds_ring->crb_sts_consumer);
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/qlcnic/qlcnic_main.c linux-libre-2.6.34-gnu1/drivers/net/qlcnic/qlcnic_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/qlcnic/qlcnic_main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/qlcnic/qlcnic_main.c	2013-05-03 09:47:52.000000000 -0400
@@ -0,0 +1,2726 @@
+/*
+ * Copyright (C) 2009 - QLogic Corporation.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called "COPYING".
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+
+#include "qlcnic.h"
+
+#include <linux/dma-mapping.h>
+#include <linux/if_vlan.h>
+#include <net/ip.h>
+#include <linux/ipv6.h>
+#include <linux/inetdevice.h>
+#include <linux/sysfs.h>
+
+MODULE_DESCRIPTION("QLogic 10 GbE Converged Ethernet Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(QLCNIC_LINUX_VERSIONID);
+/*(DEBLOBBED)*/
+
+char qlcnic_driver_name[] = "qlcnic";
+static const char qlcnic_driver_string[] = "QLogic Converged Ethernet Driver v"
+    QLCNIC_LINUX_VERSIONID;
+
+static int port_mode = QLCNIC_PORT_MODE_AUTO_NEG;
+
+/* Default to restricted 1G auto-neg mode */
+static int wol_port_mode = 5;
+
+static int use_msi = 1;
+module_param(use_msi, int, 0644);
+MODULE_PARM_DESC(use_msi, "MSI interrupt (0=disabled, 1=enabled");
+
+static int use_msi_x = 1;
+module_param(use_msi_x, int, 0644);
+MODULE_PARM_DESC(use_msi_x, "MSI-X interrupt (0=disabled, 1=enabled");
+
+static int auto_fw_reset = AUTO_FW_RESET_ENABLED;
+module_param(auto_fw_reset, int, 0644);
+MODULE_PARM_DESC(auto_fw_reset, "Auto firmware reset (0=disabled, 1=enabled");
+
+static int __devinit qlcnic_probe(struct pci_dev *pdev,
+		const struct pci_device_id *ent);
+static void __devexit qlcnic_remove(struct pci_dev *pdev);
+static int qlcnic_open(struct net_device *netdev);
+static int qlcnic_close(struct net_device *netdev);
+static void qlcnic_tx_timeout(struct net_device *netdev);
+static void qlcnic_tx_timeout_task(struct work_struct *work);
+static void qlcnic_attach_work(struct work_struct *work);
+static void qlcnic_fwinit_work(struct work_struct *work);
+static void qlcnic_fw_poll_work(struct work_struct *work);
+static void qlcnic_schedule_work(struct qlcnic_adapter *adapter,
+		work_func_t func, int delay);
+static void qlcnic_cancel_fw_work(struct qlcnic_adapter *adapter);
+static int qlcnic_poll(struct napi_struct *napi, int budget);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void qlcnic_poll_controller(struct net_device *netdev);
+#endif
+
+static void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter);
+static void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter);
+static void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter);
+static void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter);
+
+static void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter);
+static int qlcnic_can_start_firmware(struct qlcnic_adapter *adapter);
+
+static irqreturn_t qlcnic_tmp_intr(int irq, void *data);
+static irqreturn_t qlcnic_intr(int irq, void *data);
+static irqreturn_t qlcnic_msi_intr(int irq, void *data);
+static irqreturn_t qlcnic_msix_intr(int irq, void *data);
+
+static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev);
+static void qlcnic_config_indev_addr(struct net_device *dev, unsigned long);
+
+/*  PCI Device ID Table  */
+#define ENTRY(device) \
+	{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \
+	.class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0}
+
+#define PCI_DEVICE_ID_QLOGIC_QLE824X  0x8020
+
+static DEFINE_PCI_DEVICE_TABLE(qlcnic_pci_tbl) = {
+	ENTRY(PCI_DEVICE_ID_QLOGIC_QLE824X),
+	{0,}
+};
+
+MODULE_DEVICE_TABLE(pci, qlcnic_pci_tbl);
+
+
+void
+qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
+		struct qlcnic_host_tx_ring *tx_ring)
+{
+	writel(tx_ring->producer, tx_ring->crb_cmd_producer);
+
+	if (qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH) {
+		netif_stop_queue(adapter->netdev);
+		smp_mb();
+		adapter->stats.xmit_off++;
+	}
+}
+
+static const u32 msi_tgt_status[8] = {
+	ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1,
+	ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3,
+	ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5,
+	ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7
+};
+
+static const
+struct qlcnic_legacy_intr_set legacy_intr[] = QLCNIC_LEGACY_INTR_CONFIG;
+
+static inline void qlcnic_disable_int(struct qlcnic_host_sds_ring *sds_ring)
+{
+	writel(0, sds_ring->crb_intr_mask);
+}
+
+static inline void qlcnic_enable_int(struct qlcnic_host_sds_ring *sds_ring)
+{
+	struct qlcnic_adapter *adapter = sds_ring->adapter;
+
+	writel(0x1, sds_ring->crb_intr_mask);
+
+	if (!QLCNIC_IS_MSI_FAMILY(adapter))
+		writel(0xfbff, adapter->tgt_mask_reg);
+}
+
+static int
+qlcnic_alloc_sds_rings(struct qlcnic_recv_context *recv_ctx, int count)
+{
+	int size = sizeof(struct qlcnic_host_sds_ring) * count;
+
+	recv_ctx->sds_rings = kzalloc(size, GFP_KERNEL);
+
+	return (recv_ctx->sds_rings == NULL);
+}
+
+static void
+qlcnic_free_sds_rings(struct qlcnic_recv_context *recv_ctx)
+{
+	if (recv_ctx->sds_rings != NULL)
+		kfree(recv_ctx->sds_rings);
+
+	recv_ctx->sds_rings = NULL;
+}
+
+static int
+qlcnic_napi_add(struct qlcnic_adapter *adapter, struct net_device *netdev)
+{
+	int ring;
+	struct qlcnic_host_sds_ring *sds_ring;
+	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+
+	if (qlcnic_alloc_sds_rings(recv_ctx, adapter->max_sds_rings))
+		return -ENOMEM;
+
+	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+		sds_ring = &recv_ctx->sds_rings[ring];
+		netif_napi_add(netdev, &sds_ring->napi,
+				qlcnic_poll, QLCNIC_NETDEV_WEIGHT);
+	}
+
+	return 0;
+}
+
+static void
+qlcnic_napi_del(struct qlcnic_adapter *adapter)
+{
+	int ring;
+	struct qlcnic_host_sds_ring *sds_ring;
+	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+
+	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+		sds_ring = &recv_ctx->sds_rings[ring];
+		netif_napi_del(&sds_ring->napi);
+	}
+
+	qlcnic_free_sds_rings(&adapter->recv_ctx);
+}
+
+static void
+qlcnic_napi_enable(struct qlcnic_adapter *adapter)
+{
+	int ring;
+	struct qlcnic_host_sds_ring *sds_ring;
+	struct qlcnic_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);
+		qlcnic_enable_int(sds_ring);
+	}
+}
+
+static void
+qlcnic_napi_disable(struct qlcnic_adapter *adapter)
+{
+	int ring;
+	struct qlcnic_host_sds_ring *sds_ring;
+	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+
+	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+		sds_ring = &recv_ctx->sds_rings[ring];
+		qlcnic_disable_int(sds_ring);
+		napi_synchronize(&sds_ring->napi);
+		napi_disable(&sds_ring->napi);
+	}
+}
+
+static void qlcnic_clear_stats(struct qlcnic_adapter *adapter)
+{
+	memset(&adapter->stats, 0, sizeof(adapter->stats));
+	return;
+}
+
+static int qlcnic_set_dma_mask(struct qlcnic_adapter *adapter)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	u64 mask, cmask;
+
+	adapter->pci_using_dac = 0;
+
+	mask = DMA_BIT_MASK(39);
+	cmask = mask;
+
+	if (pci_set_dma_mask(pdev, mask) == 0 &&
+			pci_set_consistent_dma_mask(pdev, cmask) == 0) {
+		adapter->pci_using_dac = 1;
+		return 0;
+	}
+
+	return -EIO;
+}
+
+/* Update addressable range if firmware supports it */
+static int
+qlcnic_update_dma_mask(struct qlcnic_adapter *adapter)
+{
+	int change, shift, err;
+	u64 mask, old_mask, old_cmask;
+	struct pci_dev *pdev = adapter->pdev;
+
+	change = 0;
+
+	shift = QLCRD32(adapter, CRB_DMA_SHIFT);
+	if (shift > 32)
+		return 0;
+
+	if (shift > 9)
+		change = 1;
+
+	if (change) {
+		old_mask = pdev->dma_mask;
+		old_cmask = pdev->dev.coherent_dma_mask;
+
+		mask = DMA_BIT_MASK(32+shift);
+
+		err = pci_set_dma_mask(pdev, mask);
+		if (err)
+			goto err_out;
+
+		err = pci_set_consistent_dma_mask(pdev, mask);
+		if (err)
+			goto err_out;
+		dev_info(&pdev->dev, "using %d-bit dma mask\n", 32+shift);
+	}
+
+	return 0;
+
+err_out:
+	pci_set_dma_mask(pdev, old_mask);
+	pci_set_consistent_dma_mask(pdev, old_cmask);
+	return err;
+}
+
+static void qlcnic_set_port_mode(struct qlcnic_adapter *adapter)
+{
+	u32 val, data;
+
+	val = adapter->ahw.board_type;
+	if ((val == QLCNIC_BRDTYPE_P3_HMEZ) ||
+		(val == QLCNIC_BRDTYPE_P3_XG_LOM)) {
+		if (port_mode == QLCNIC_PORT_MODE_802_3_AP) {
+			data = QLCNIC_PORT_MODE_802_3_AP;
+			QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data);
+		} else if (port_mode == QLCNIC_PORT_MODE_XG) {
+			data = QLCNIC_PORT_MODE_XG;
+			QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data);
+		} else if (port_mode == QLCNIC_PORT_MODE_AUTO_NEG_1G) {
+			data = QLCNIC_PORT_MODE_AUTO_NEG_1G;
+			QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data);
+		} else if (port_mode == QLCNIC_PORT_MODE_AUTO_NEG_XG) {
+			data = QLCNIC_PORT_MODE_AUTO_NEG_XG;
+			QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data);
+		} else {
+			data = QLCNIC_PORT_MODE_AUTO_NEG;
+			QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data);
+		}
+
+		if ((wol_port_mode != QLCNIC_PORT_MODE_802_3_AP) &&
+			(wol_port_mode != QLCNIC_PORT_MODE_XG) &&
+			(wol_port_mode != QLCNIC_PORT_MODE_AUTO_NEG_1G) &&
+			(wol_port_mode != QLCNIC_PORT_MODE_AUTO_NEG_XG)) {
+			wol_port_mode = QLCNIC_PORT_MODE_AUTO_NEG;
+		}
+		QLCWR32(adapter, QLCNIC_WOL_PORT_MODE, wol_port_mode);
+	}
+}
+
+static void qlcnic_set_msix_bit(struct pci_dev *pdev, int enable)
+{
+	u32 control;
+	int pos;
+
+	pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
+	if (pos) {
+		pci_read_config_dword(pdev, pos, &control);
+		if (enable)
+			control |= PCI_MSIX_FLAGS_ENABLE;
+		else
+			control = 0;
+		pci_write_config_dword(pdev, pos, control);
+	}
+}
+
+static void qlcnic_init_msix_entries(struct qlcnic_adapter *adapter, int count)
+{
+	int i;
+
+	for (i = 0; i < count; i++)
+		adapter->msix_entries[i].entry = i;
+}
+
+static int
+qlcnic_read_mac_addr(struct qlcnic_adapter *adapter)
+{
+	int i;
+	unsigned char *p;
+	u64 mac_addr;
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+
+	if (qlcnic_get_mac_addr(adapter, &mac_addr) != 0)
+		return -EIO;
+
+	p = (unsigned char *)&mac_addr;
+	for (i = 0; i < 6; i++)
+		netdev->dev_addr[i] = *(p + 5 - i);
+
+	memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
+	memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len);
+
+	/* set station address */
+
+	if (!is_valid_ether_addr(netdev->perm_addr))
+		dev_warn(&pdev->dev, "Bad MAC address %pM.\n",
+					netdev->dev_addr);
+
+	return 0;
+}
+
+static int qlcnic_set_mac(struct net_device *netdev, void *p)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct sockaddr *addr = p;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EINVAL;
+
+	if (netif_running(netdev)) {
+		netif_device_detach(netdev);
+		qlcnic_napi_disable(adapter);
+	}
+
+	memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len);
+	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+	qlcnic_set_multi(adapter->netdev);
+
+	if (netif_running(netdev)) {
+		netif_device_attach(netdev);
+		qlcnic_napi_enable(adapter);
+	}
+	return 0;
+}
+
+static const struct net_device_ops qlcnic_netdev_ops = {
+	.ndo_open	   = qlcnic_open,
+	.ndo_stop	   = qlcnic_close,
+	.ndo_start_xmit    = qlcnic_xmit_frame,
+	.ndo_get_stats	   = qlcnic_get_stats,
+	.ndo_validate_addr = eth_validate_addr,
+	.ndo_set_multicast_list = qlcnic_set_multi,
+	.ndo_set_mac_address    = qlcnic_set_mac,
+	.ndo_change_mtu	   = qlcnic_change_mtu,
+	.ndo_tx_timeout	   = qlcnic_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller = qlcnic_poll_controller,
+#endif
+};
+
+static void
+qlcnic_setup_intr(struct qlcnic_adapter *adapter)
+{
+	const struct qlcnic_legacy_intr_set *legacy_intrp;
+	struct pci_dev *pdev = adapter->pdev;
+	int err, num_msix;
+
+	if (adapter->rss_supported) {
+		num_msix = (num_online_cpus() >= MSIX_ENTRIES_PER_ADAPTER) ?
+			MSIX_ENTRIES_PER_ADAPTER : 2;
+	} else
+		num_msix = 1;
+
+	adapter->max_sds_rings = 1;
+
+	adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED);
+
+	legacy_intrp = &legacy_intr[adapter->ahw.pci_func];
+
+	adapter->int_vec_bit = legacy_intrp->int_vec_bit;
+	adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter,
+			legacy_intrp->tgt_status_reg);
+	adapter->tgt_mask_reg = qlcnic_get_ioaddr(adapter,
+			legacy_intrp->tgt_mask_reg);
+	adapter->isr_int_vec = qlcnic_get_ioaddr(adapter, ISR_INT_VECTOR);
+
+	adapter->crb_int_state_reg = qlcnic_get_ioaddr(adapter,
+			ISR_INT_STATE_REG);
+
+	qlcnic_set_msix_bit(pdev, 0);
+
+	if (adapter->msix_supported) {
+
+		qlcnic_init_msix_entries(adapter, num_msix);
+		err = pci_enable_msix(pdev, adapter->msix_entries, num_msix);
+		if (err == 0) {
+			adapter->flags |= QLCNIC_MSIX_ENABLED;
+			qlcnic_set_msix_bit(pdev, 1);
+
+			if (adapter->rss_supported)
+				adapter->max_sds_rings = num_msix;
+
+			dev_info(&pdev->dev, "using msi-x interrupts\n");
+			return;
+		}
+
+		if (err > 0)
+			pci_disable_msix(pdev);
+
+		/* fall through for msi */
+	}
+
+	if (use_msi && !pci_enable_msi(pdev)) {
+		adapter->flags |= QLCNIC_MSI_ENABLED;
+		adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter,
+				msi_tgt_status[adapter->ahw.pci_func]);
+		dev_info(&pdev->dev, "using msi interrupts\n");
+		adapter->msix_entries[0].vector = pdev->irq;
+		return;
+	}
+
+	dev_info(&pdev->dev, "using legacy interrupts\n");
+	adapter->msix_entries[0].vector = pdev->irq;
+}
+
+static void
+qlcnic_teardown_intr(struct qlcnic_adapter *adapter)
+{
+	if (adapter->flags & QLCNIC_MSIX_ENABLED)
+		pci_disable_msix(adapter->pdev);
+	if (adapter->flags & QLCNIC_MSI_ENABLED)
+		pci_disable_msi(adapter->pdev);
+}
+
+static void
+qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter)
+{
+	if (adapter->ahw.pci_base0 != NULL)
+		iounmap(adapter->ahw.pci_base0);
+}
+
+static int
+qlcnic_setup_pci_map(struct qlcnic_adapter *adapter)
+{
+	void __iomem *mem_ptr0 = NULL;
+	resource_size_t mem_base;
+	unsigned long mem_len, pci_len0 = 0;
+
+	struct pci_dev *pdev = adapter->pdev;
+	int pci_func = adapter->ahw.pci_func;
+
+	/*
+	 * 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->ahw.crb_win = -1;
+	adapter->ahw.ocm_win = -1;
+
+	/* remap phys address */
+	mem_base = pci_resource_start(pdev, 0);	/* 0 is for BAR 0 */
+	mem_len = pci_resource_len(pdev, 0);
+
+	if (mem_len == QLCNIC_PCI_2MB_SIZE) {
+
+		mem_ptr0 = pci_ioremap_bar(pdev, 0);
+		if (mem_ptr0 == NULL) {
+			dev_err(&pdev->dev, "failed to map PCI bar 0\n");
+			return -EIO;
+		}
+		pci_len0 = mem_len;
+	} else {
+		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.ocm_win_crb = qlcnic_get_ioaddr(adapter,
+		QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func)));
+
+	return 0;
+}
+
+static void get_brd_name(struct qlcnic_adapter *adapter, char *name)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	int i, found = 0;
+
+	for (i = 0; i < NUM_SUPPORTED_BOARDS; ++i) {
+		if (qlcnic_boards[i].vendor == pdev->vendor &&
+			qlcnic_boards[i].device == pdev->device &&
+			qlcnic_boards[i].sub_vendor == pdev->subsystem_vendor &&
+			qlcnic_boards[i].sub_device == pdev->subsystem_device) {
+				strcpy(name, qlcnic_boards[i].short_name);
+				found = 1;
+				break;
+		}
+
+	}
+
+	if (!found)
+		name = "Unknown";
+}
+
+static void
+qlcnic_check_options(struct qlcnic_adapter *adapter)
+{
+	u32 fw_major, fw_minor, fw_build;
+	char brd_name[QLCNIC_MAX_BOARD_NAME_LEN];
+	char serial_num[32];
+	int i, offset, val;
+	int *ptr32;
+	struct pci_dev *pdev = adapter->pdev;
+
+	adapter->driver_mismatch = 0;
+
+	ptr32 = (int *)&serial_num;
+	offset = QLCNIC_FW_SERIAL_NUM_OFFSET;
+	for (i = 0; i < 8; i++) {
+		if (qlcnic_rom_fast_read(adapter, offset, &val) == -1) {
+			dev_err(&pdev->dev, "error reading board info\n");
+			adapter->driver_mismatch = 1;
+			return;
+		}
+		ptr32[i] = cpu_to_le32(val);
+		offset += sizeof(u32);
+	}
+
+	fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR);
+	fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR);
+	fw_build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB);
+
+	adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build);
+
+	if (adapter->portnum == 0) {
+		get_brd_name(adapter, brd_name);
+
+		pr_info("%s: %s Board Chip rev 0x%x\n",
+				module_name(THIS_MODULE),
+				brd_name, adapter->ahw.revision_id);
+	}
+
+	if (adapter->fw_version < QLCNIC_VERSION_CODE(3, 4, 216)) {
+		adapter->driver_mismatch = 1;
+		dev_warn(&pdev->dev, "firmware version %d.%d.%d unsupported\n",
+				fw_major, fw_minor, fw_build);
+		return;
+	}
+
+	i = QLCRD32(adapter, QLCNIC_SRE_MISC);
+	adapter->ahw.cut_through = (i & 0x8000) ? 1 : 0;
+
+	dev_info(&pdev->dev, "firmware v%d.%d.%d [%s]\n",
+			fw_major, fw_minor, fw_build,
+			adapter->ahw.cut_through ? "cut-through" : "legacy");
+
+	if (adapter->fw_version >= QLCNIC_VERSION_CODE(4, 0, 222))
+		adapter->capabilities = QLCRD32(adapter, CRB_FW_CAPABILITIES_1);
+
+	adapter->flags &= ~QLCNIC_LRO_ENABLED;
+
+	if (adapter->ahw.port_type == QLCNIC_XGBE) {
+		adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G;
+		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
+	} else if (adapter->ahw.port_type == QLCNIC_GBE) {
+		adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G;
+		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
+	}
+
+	adapter->msix_supported = !!use_msi_x;
+	adapter->rss_supported = !!use_msi_x;
+
+	adapter->num_txd = MAX_CMD_DESCRIPTORS;
+
+	adapter->num_lro_rxd = 0;
+	adapter->max_rds_rings = 2;
+}
+
+static int
+qlcnic_start_firmware(struct qlcnic_adapter *adapter)
+{
+	int val, err, first_boot;
+
+	err = qlcnic_set_dma_mask(adapter);
+	if (err)
+		return err;
+
+	if (!qlcnic_can_start_firmware(adapter))
+		goto wait_init;
+
+	first_boot = QLCRD32(adapter, QLCNIC_CAM_RAM(0x1fc));
+	if (first_boot == 0x55555555)
+		/* This is the first boot after power up */
+		QLCWR32(adapter, QLCNIC_CAM_RAM(0x1fc), QLCNIC_BDINFO_MAGIC);
+
+	qlcnic_reject_firmware(adapter);
+
+	err = qlcnic_need_fw_reset(adapter);
+	if (err < 0)
+		goto err_out;
+	if (err == 0)
+		goto wait_init;
+
+	if (first_boot != 0x55555555) {
+		QLCWR32(adapter, CRB_CMDPEG_STATE, 0);
+		qlcnic_pinit_from_rom(adapter);
+		msleep(1);
+	}
+
+	QLCWR32(adapter, CRB_DMA_SHIFT, 0x55555555);
+	QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS1, 0);
+	QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS2, 0);
+
+	qlcnic_set_port_mode(adapter);
+
+	err = qlcnic_load_firmware(adapter);
+	if (err)
+		goto err_out;
+
+	qlcnic_release_firmware(adapter);
+
+	val = (_QLCNIC_LINUX_MAJOR << 16)
+		| ((_QLCNIC_LINUX_MINOR << 8))
+		| (_QLCNIC_LINUX_SUBVERSION);
+	QLCWR32(adapter, CRB_DRIVER_VERSION, val);
+
+wait_init:
+	/* Handshake with the card before we register the devices. */
+	err = qlcnic_phantom_init(adapter);
+	if (err)
+		goto err_out;
+
+	QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY);
+
+	qlcnic_update_dma_mask(adapter);
+
+	qlcnic_check_options(adapter);
+
+	adapter->need_fw_reset = 0;
+
+	/* fall through and release firmware */
+
+err_out:
+	qlcnic_release_firmware(adapter);
+	return err;
+}
+
+static int
+qlcnic_request_irq(struct qlcnic_adapter *adapter)
+{
+	irq_handler_t handler;
+	struct qlcnic_host_sds_ring *sds_ring;
+	int err, ring;
+
+	unsigned long flags = 0;
+	struct net_device *netdev = adapter->netdev;
+	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+
+	if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) {
+		handler = qlcnic_tmp_intr;
+		if (!QLCNIC_IS_MSI_FAMILY(adapter))
+			flags |= IRQF_SHARED;
+
+	} else {
+		if (adapter->flags & QLCNIC_MSIX_ENABLED)
+			handler = qlcnic_msix_intr;
+		else if (adapter->flags & QLCNIC_MSI_ENABLED)
+			handler = qlcnic_msi_intr;
+		else {
+			flags |= IRQF_SHARED;
+			handler = qlcnic_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, "%s[%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
+qlcnic_free_irq(struct qlcnic_adapter *adapter)
+{
+	int ring;
+	struct qlcnic_host_sds_ring *sds_ring;
+
+	struct qlcnic_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 void
+qlcnic_init_coalesce_defaults(struct qlcnic_adapter *adapter)
+{
+	adapter->coal.flags = QLCNIC_INTR_DEFAULT;
+	adapter->coal.normal.data.rx_time_us =
+		QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
+	adapter->coal.normal.data.rx_packets =
+		QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
+	adapter->coal.normal.data.tx_time_us =
+		QLCNIC_DEFAULT_INTR_COALESCE_TX_TIME_US;
+	adapter->coal.normal.data.tx_packets =
+		QLCNIC_DEFAULT_INTR_COALESCE_TX_PACKETS;
+}
+
+static int
+__qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
+{
+	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+		return -EIO;
+
+	qlcnic_set_multi(netdev);
+	qlcnic_fw_cmd_set_mtu(adapter, netdev->mtu);
+
+	adapter->ahw.linkup = 0;
+
+	if (adapter->max_sds_rings > 1)
+		qlcnic_config_rss(adapter, 1);
+
+	qlcnic_config_intr_coalesce(adapter);
+
+	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
+		qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED);
+
+	qlcnic_napi_enable(adapter);
+
+	qlcnic_linkevent_request(adapter, 1);
+
+	set_bit(__QLCNIC_DEV_UP, &adapter->state);
+	return 0;
+}
+
+/* Usage: During resume and firmware recovery module.*/
+
+static int
+qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
+{
+	int err = 0;
+
+	rtnl_lock();
+	if (netif_running(netdev))
+		err = __qlcnic_up(adapter, netdev);
+	rtnl_unlock();
+
+	return err;
+}
+
+static void
+__qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
+{
+	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+		return;
+
+	if (!test_and_clear_bit(__QLCNIC_DEV_UP, &adapter->state))
+		return;
+
+	smp_mb();
+	spin_lock(&adapter->tx_clean_lock);
+	netif_carrier_off(netdev);
+	netif_tx_disable(netdev);
+
+	qlcnic_free_mac_list(adapter);
+
+	qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE);
+
+	qlcnic_napi_disable(adapter);
+
+	qlcnic_release_tx_buffers(adapter);
+	spin_unlock(&adapter->tx_clean_lock);
+}
+
+/* Usage: During suspend and firmware recovery module */
+
+static void
+qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
+{
+	rtnl_lock();
+	if (netif_running(netdev))
+		__qlcnic_down(adapter, netdev);
+	rtnl_unlock();
+
+}
+
+static int
+qlcnic_attach(struct qlcnic_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+	int err, ring;
+	struct qlcnic_host_rds_ring *rds_ring;
+
+	if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC)
+		return 0;
+
+	err = qlcnic_init_firmware(adapter);
+	if (err)
+		return err;
+
+	err = qlcnic_napi_add(adapter, netdev);
+	if (err)
+		return err;
+
+	err = qlcnic_alloc_sw_resources(adapter);
+	if (err) {
+		dev_err(&pdev->dev, "Error in setting sw resources\n");
+		return err;
+	}
+
+	err = qlcnic_alloc_hw_resources(adapter);
+	if (err) {
+		dev_err(&pdev->dev, "Error in setting hw resources\n");
+		goto err_out_free_sw;
+	}
+
+
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		rds_ring = &adapter->recv_ctx.rds_rings[ring];
+		qlcnic_post_rx_buffers(adapter, ring, rds_ring);
+	}
+
+	err = qlcnic_request_irq(adapter);
+	if (err) {
+		dev_err(&pdev->dev, "failed to setup interrupt\n");
+		goto err_out_free_rxbuf;
+	}
+
+	qlcnic_init_coalesce_defaults(adapter);
+
+	qlcnic_create_sysfs_entries(adapter);
+
+	adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC;
+	return 0;
+
+err_out_free_rxbuf:
+	qlcnic_release_rx_buffers(adapter);
+	qlcnic_free_hw_resources(adapter);
+err_out_free_sw:
+	qlcnic_free_sw_resources(adapter);
+	return err;
+}
+
+static void
+qlcnic_detach(struct qlcnic_adapter *adapter)
+{
+	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+		return;
+
+	qlcnic_remove_sysfs_entries(adapter);
+
+	qlcnic_free_hw_resources(adapter);
+	qlcnic_release_rx_buffers(adapter);
+	qlcnic_free_irq(adapter);
+	qlcnic_napi_del(adapter);
+	qlcnic_free_sw_resources(adapter);
+
+	adapter->is_up = 0;
+}
+
+void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct qlcnic_host_sds_ring *sds_ring;
+	int ring;
+
+	if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) {
+		for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+			sds_ring = &adapter->recv_ctx.sds_rings[ring];
+			qlcnic_disable_int(sds_ring);
+		}
+	}
+
+	qlcnic_detach(adapter);
+
+	adapter->diag_test = 0;
+	adapter->max_sds_rings = max_sds_rings;
+
+	if (qlcnic_attach(adapter))
+		return;
+
+	if (netif_running(netdev))
+		__qlcnic_up(adapter, netdev);
+
+	netif_device_attach(netdev);
+}
+
+int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct qlcnic_host_sds_ring *sds_ring;
+	int ring;
+	int ret;
+
+	netif_device_detach(netdev);
+
+	if (netif_running(netdev))
+		__qlcnic_down(adapter, netdev);
+
+	qlcnic_detach(adapter);
+
+	adapter->max_sds_rings = 1;
+	adapter->diag_test = test;
+
+	ret = qlcnic_attach(adapter);
+	if (ret)
+		return ret;
+
+	if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) {
+		for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+			sds_ring = &adapter->recv_ctx.sds_rings[ring];
+			qlcnic_enable_int(sds_ring);
+		}
+	}
+
+	return 0;
+}
+
+int
+qlcnic_reset_context(struct qlcnic_adapter *adapter)
+{
+	int err = 0;
+	struct net_device *netdev = adapter->netdev;
+
+	if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+		return -EBUSY;
+
+	if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) {
+
+		netif_device_detach(netdev);
+
+		if (netif_running(netdev))
+			__qlcnic_down(adapter, netdev);
+
+		qlcnic_detach(adapter);
+
+		if (netif_running(netdev)) {
+			err = qlcnic_attach(adapter);
+			if (!err)
+				err = __qlcnic_up(adapter, netdev);
+
+			if (err)
+				goto done;
+		}
+
+		netif_device_attach(netdev);
+	}
+
+done:
+	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+	return err;
+}
+
+static int
+qlcnic_setup_netdev(struct qlcnic_adapter *adapter,
+		struct net_device *netdev)
+{
+	int err;
+	struct pci_dev *pdev = adapter->pdev;
+
+	adapter->rx_csum = 1;
+	adapter->mc_enabled = 0;
+	adapter->max_mc_count = 38;
+
+	netdev->netdev_ops	   = &qlcnic_netdev_ops;
+	netdev->watchdog_timeo     = 2*HZ;
+
+	qlcnic_change_mtu(netdev, netdev->mtu);
+
+	SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops);
+
+	netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+	netdev->features |= (NETIF_F_GRO);
+	netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+
+	netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
+	netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
+
+	if (adapter->pci_using_dac) {
+		netdev->features |= NETIF_F_HIGHDMA;
+		netdev->vlan_features |= NETIF_F_HIGHDMA;
+	}
+
+	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_FVLANTX)
+		netdev->features |= (NETIF_F_HW_VLAN_TX);
+
+	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
+		netdev->features |= NETIF_F_LRO;
+
+	netdev->irq = adapter->msix_entries[0].vector;
+
+	INIT_WORK(&adapter->tx_timeout_task, qlcnic_tx_timeout_task);
+
+	if (qlcnic_read_mac_addr(adapter))
+		dev_warn(&pdev->dev, "failed to read mac addr\n");
+
+	netif_carrier_off(netdev);
+	netif_stop_queue(netdev);
+
+	err = register_netdev(netdev);
+	if (err) {
+		dev_err(&pdev->dev, "failed to register net device\n");
+		return err;
+	}
+
+	return 0;
+}
+
+static int __devinit
+qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	struct net_device *netdev = NULL;
+	struct qlcnic_adapter *adapter = NULL;
+	int err;
+	int pci_func_id = PCI_FUNC(pdev->devfn);
+	uint8_t revision_id;
+
+	err = pci_enable_device(pdev);
+	if (err)
+		return err;
+
+	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+		err = -ENODEV;
+		goto err_out_disable_pdev;
+	}
+
+	err = pci_request_regions(pdev, qlcnic_driver_name);
+	if (err)
+		goto err_out_disable_pdev;
+
+	pci_set_master(pdev);
+
+	netdev = alloc_etherdev(sizeof(struct qlcnic_adapter));
+	if (!netdev) {
+		dev_err(&pdev->dev, "failed to allocate net_device\n");
+		err = -ENOMEM;
+		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;
+
+	rwlock_init(&adapter->ahw.crb_lock);
+	mutex_init(&adapter->ahw.mem_lock);
+
+	spin_lock_init(&adapter->tx_clean_lock);
+	INIT_LIST_HEAD(&adapter->mac_list);
+
+	err = qlcnic_setup_pci_map(adapter);
+	if (err)
+		goto err_out_free_netdev;
+
+	/* This will be reset for mezz cards  */
+	adapter->portnum = pci_func_id;
+
+	err = qlcnic_get_board_info(adapter);
+	if (err) {
+		dev_err(&pdev->dev, "Error getting board config info.\n");
+		goto err_out_iounmap;
+	}
+
+
+	err = qlcnic_start_firmware(adapter);
+	if (err)
+		goto err_out_decr_ref;
+
+	/*
+	 * See if the firmware gave us a virtual-physical port mapping.
+	 */
+	adapter->physical_port = adapter->portnum;
+
+	qlcnic_clear_stats(adapter);
+
+	qlcnic_setup_intr(adapter);
+
+	err = qlcnic_setup_netdev(adapter, netdev);
+	if (err)
+		goto err_out_disable_msi;
+
+	pci_set_drvdata(pdev, adapter);
+
+	qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY);
+
+	switch (adapter->ahw.port_type) {
+	case QLCNIC_GBE:
+		dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n",
+				adapter->netdev->name);
+		break;
+	case QLCNIC_XGBE:
+		dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n",
+				adapter->netdev->name);
+		break;
+	}
+
+	qlcnic_create_diag_entries(adapter);
+
+	return 0;
+
+err_out_disable_msi:
+	qlcnic_teardown_intr(adapter);
+
+err_out_decr_ref:
+	qlcnic_clr_all_drv_state(adapter);
+
+err_out_iounmap:
+	qlcnic_cleanup_pci_map(adapter);
+
+err_out_free_netdev:
+	free_netdev(netdev);
+
+err_out_free_res:
+	pci_release_regions(pdev);
+
+err_out_disable_pdev:
+	pci_set_drvdata(pdev, NULL);
+	pci_disable_device(pdev);
+	return err;
+}
+
+static void __devexit qlcnic_remove(struct pci_dev *pdev)
+{
+	struct qlcnic_adapter *adapter;
+	struct net_device *netdev;
+
+	adapter = pci_get_drvdata(pdev);
+	if (adapter == NULL)
+		return;
+
+	netdev = adapter->netdev;
+
+	qlcnic_cancel_fw_work(adapter);
+
+	unregister_netdev(netdev);
+
+	cancel_work_sync(&adapter->tx_timeout_task);
+
+	qlcnic_detach(adapter);
+
+	qlcnic_clr_all_drv_state(adapter);
+
+	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+
+	qlcnic_teardown_intr(adapter);
+
+	qlcnic_remove_diag_entries(adapter);
+
+	qlcnic_cleanup_pci_map(adapter);
+
+	qlcnic_release_firmware(adapter);
+
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+	pci_set_drvdata(pdev, NULL);
+
+	free_netdev(netdev);
+}
+static int __qlcnic_shutdown(struct pci_dev *pdev)
+{
+	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
+	struct net_device *netdev = adapter->netdev;
+	int retval;
+
+	netif_device_detach(netdev);
+
+	qlcnic_cancel_fw_work(adapter);
+
+	if (netif_running(netdev))
+		qlcnic_down(adapter, netdev);
+
+	cancel_work_sync(&adapter->tx_timeout_task);
+
+	qlcnic_detach(adapter);
+
+	qlcnic_clr_all_drv_state(adapter);
+
+	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+
+	retval = pci_save_state(pdev);
+	if (retval)
+		return retval;
+
+	if (qlcnic_wol_supported(adapter)) {
+		pci_enable_wake(pdev, PCI_D3cold, 1);
+		pci_enable_wake(pdev, PCI_D3hot, 1);
+	}
+
+	return 0;
+}
+
+static void qlcnic_shutdown(struct pci_dev *pdev)
+{
+	if (__qlcnic_shutdown(pdev))
+		return;
+
+	pci_disable_device(pdev);
+}
+
+#ifdef CONFIG_PM
+static int
+qlcnic_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int retval;
+
+	retval = __qlcnic_shutdown(pdev);
+	if (retval)
+		return retval;
+
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	return 0;
+}
+
+static int
+qlcnic_resume(struct pci_dev *pdev)
+{
+	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
+	struct net_device *netdev = adapter->netdev;
+	int err;
+
+	err = pci_enable_device(pdev);
+	if (err)
+		return err;
+
+	pci_set_power_state(pdev, PCI_D0);
+	pci_set_master(pdev);
+	pci_restore_state(pdev);
+
+	adapter->ahw.crb_win = -1;
+	adapter->ahw.ocm_win = -1;
+
+	err = qlcnic_start_firmware(adapter);
+	if (err) {
+		dev_err(&pdev->dev, "failed to start firmware\n");
+		return err;
+	}
+
+	if (netif_running(netdev)) {
+		err = qlcnic_attach(adapter);
+		if (err)
+			goto err_out;
+
+		err = qlcnic_up(adapter, netdev);
+		if (err)
+			goto err_out_detach;
+
+
+		qlcnic_config_indev_addr(netdev, NETDEV_UP);
+	}
+
+	netif_device_attach(netdev);
+	qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY);
+	return 0;
+
+err_out_detach:
+	qlcnic_detach(adapter);
+err_out:
+	qlcnic_clr_all_drv_state(adapter);
+	return err;
+}
+#endif
+
+static int qlcnic_open(struct net_device *netdev)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	int err;
+
+	if (adapter->driver_mismatch)
+		return -EIO;
+
+	err = qlcnic_attach(adapter);
+	if (err)
+		return err;
+
+	err = __qlcnic_up(adapter, netdev);
+	if (err)
+		goto err_out;
+
+	netif_start_queue(netdev);
+
+	return 0;
+
+err_out:
+	qlcnic_detach(adapter);
+	return err;
+}
+
+/*
+ * qlcnic_close - Disables a network interface entry point
+ */
+static int qlcnic_close(struct net_device *netdev)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+
+	__qlcnic_down(adapter, netdev);
+	return 0;
+}
+
+static void
+qlcnic_tso_check(struct net_device *netdev,
+		struct qlcnic_host_tx_ring *tx_ring,
+		struct cmd_desc_type0 *first_desc,
+		struct sk_buff *skb)
+{
+	u8 opcode = TX_ETHER_PKT;
+	__be16 protocol = skb->protocol;
+	u16 flags = 0, vid = 0;
+	u32 producer;
+	int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0;
+	struct cmd_desc_type0 *hwdesc;
+	struct vlan_ethhdr *vh;
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+
+	if (protocol == cpu_to_be16(ETH_P_8021Q)) {
+
+		vh = (struct vlan_ethhdr *)skb->data;
+		protocol = vh->h_vlan_encapsulated_proto;
+		flags = FLAGS_VLAN_TAGGED;
+
+	} else if (vlan_tx_tag_present(skb)) {
+
+		flags = FLAGS_VLAN_OOB;
+		vid = vlan_tx_tag_get(skb);
+		qlcnic_set_tx_vlan_tci(first_desc, vid);
+		vlan_oob = 1;
+	}
+
+	if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
+			skb_shinfo(skb)->gso_size > 0) {
+
+		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+
+		first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
+		first_desc->total_hdr_length = hdr_len;
+		if (vlan_oob) {
+			first_desc->total_hdr_length += VLAN_HLEN;
+			first_desc->tcp_hdr_offset = VLAN_HLEN;
+			first_desc->ip_hdr_offset = VLAN_HLEN;
+			/* Only in case of TSO on vlan device */
+			flags |= FLAGS_VLAN_TAGGED;
+		}
+
+		opcode = (protocol == cpu_to_be16(ETH_P_IPV6)) ?
+				TX_TCP_LSO6 : TX_TCP_LSO;
+		tso = 1;
+
+	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		u8 l4proto;
+
+		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 == cpu_to_be16(ETH_P_IPV6)) {
+			l4proto = ipv6_hdr(skb)->nexthdr;
+
+			if (l4proto == IPPROTO_TCP)
+				opcode = TX_TCPV6_PKT;
+			else if (l4proto == IPPROTO_UDP)
+				opcode = TX_UDPV6_PKT;
+		}
+	}
+
+	first_desc->tcp_hdr_offset += skb_transport_offset(skb);
+	first_desc->ip_hdr_offset += skb_network_offset(skb);
+	qlcnic_set_tx_flags_opcode(first_desc, flags, opcode);
+
+	if (!tso)
+		return;
+
+	/* For LSO, we need to copy the MAC/IP/TCP headers into
+	 * the descriptor ring
+	 */
+	producer = tx_ring->producer;
+	copied = 0;
+	offset = 2;
+
+	if (vlan_oob) {
+		/* Create a TSO vlan header template for firmware */
+
+		hwdesc = &tx_ring->desc_head[producer];
+		tx_ring->cmd_buf_arr[producer].skb = NULL;
+
+		copy_len = min((int)sizeof(struct cmd_desc_type0) - offset,
+				hdr_len + VLAN_HLEN);
+
+		vh = (struct vlan_ethhdr *)((char *)hwdesc + 2);
+		skb_copy_from_linear_data(skb, vh, 12);
+		vh->h_vlan_proto = htons(ETH_P_8021Q);
+		vh->h_vlan_TCI = htons(vid);
+		skb_copy_from_linear_data_offset(skb, 12,
+				(char *)vh + 16, copy_len - 16);
+
+		copied = copy_len - VLAN_HLEN;
+		offset = 0;
+
+		producer = get_next_index(producer, tx_ring->num_desc);
+	}
+
+	while (copied < hdr_len) {
+
+		copy_len = min((int)sizeof(struct cmd_desc_type0) - offset,
+				(hdr_len - copied));
+
+		hwdesc = &tx_ring->desc_head[producer];
+		tx_ring->cmd_buf_arr[producer].skb = NULL;
+
+		skb_copy_from_linear_data_offset(skb, copied,
+				 (char *)hwdesc + offset, copy_len);
+
+		copied += copy_len;
+		offset = 0;
+
+		producer = get_next_index(producer, tx_ring->num_desc);
+	}
+
+	tx_ring->producer = producer;
+	barrier();
+	adapter->stats.lso_frames++;
+}
+
+static int
+qlcnic_map_tx_skb(struct pci_dev *pdev,
+		struct sk_buff *skb, struct qlcnic_cmd_buffer *pbuf)
+{
+	struct qlcnic_skb_frag *nf;
+	struct skb_frag_struct *frag;
+	int i, nr_frags;
+	dma_addr_t map;
+
+	nr_frags = skb_shinfo(skb)->nr_frags;
+	nf = &pbuf->frag_array[0];
+
+	map = pci_map_single(pdev, skb->data,
+			skb_headlen(skb), PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(pdev, map))
+		goto out_err;
+
+	nf->dma = map;
+	nf->length = skb_headlen(skb);
+
+	for (i = 0; i < nr_frags; i++) {
+		frag = &skb_shinfo(skb)->frags[i];
+		nf = &pbuf->frag_array[i+1];
+
+		map = pci_map_page(pdev, frag->page, frag->page_offset,
+				frag->size, PCI_DMA_TODEVICE);
+		if (pci_dma_mapping_error(pdev, map))
+			goto unwind;
+
+		nf->dma = map;
+		nf->length = frag->size;
+	}
+
+	return 0;
+
+unwind:
+	while (--i >= 0) {
+		nf = &pbuf->frag_array[i+1];
+		pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE);
+	}
+
+	nf = &pbuf->frag_array[0];
+	pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE);
+
+out_err:
+	return -ENOMEM;
+}
+
+static inline void
+qlcnic_clear_cmddesc(u64 *desc)
+{
+	desc[0] = 0ULL;
+	desc[2] = 0ULL;
+}
+
+netdev_tx_t
+qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring;
+	struct qlcnic_cmd_buffer *pbuf;
+	struct qlcnic_skb_frag *buffrag;
+	struct cmd_desc_type0 *hwdesc, *first_desc;
+	struct pci_dev *pdev;
+	int i, k;
+
+	u32 producer;
+	int frag_count, no_of_desc;
+	u32 num_txd = tx_ring->num_desc;
+
+	frag_count = skb_shinfo(skb)->nr_frags + 1;
+
+	/* 4 fragments per cmd des */
+	no_of_desc = (frag_count + 3) >> 2;
+
+	if (unlikely(no_of_desc + 2 > qlcnic_tx_avail(tx_ring))) {
+		netif_stop_queue(netdev);
+		adapter->stats.xmit_off++;
+		return NETDEV_TX_BUSY;
+	}
+
+	producer = tx_ring->producer;
+	pbuf = &tx_ring->cmd_buf_arr[producer];
+
+	pdev = adapter->pdev;
+
+	if (qlcnic_map_tx_skb(pdev, skb, pbuf))
+		goto drop_packet;
+
+	pbuf->skb = skb;
+	pbuf->frag_count = frag_count;
+
+	first_desc = hwdesc = &tx_ring->desc_head[producer];
+	qlcnic_clear_cmddesc((u64 *)hwdesc);
+
+	qlcnic_set_tx_frags_len(first_desc, frag_count, skb->len);
+	qlcnic_set_tx_port(first_desc, adapter->portnum);
+
+	for (i = 0; i < frag_count; i++) {
+
+		k = i % 4;
+
+		if ((k == 0) && (i > 0)) {
+			/* move to next desc.*/
+			producer = get_next_index(producer, num_txd);
+			hwdesc = &tx_ring->desc_head[producer];
+			qlcnic_clear_cmddesc((u64 *)hwdesc);
+			tx_ring->cmd_buf_arr[producer].skb = NULL;
+		}
+
+		buffrag = &pbuf->frag_array[i];
+
+		hwdesc->buffer_length[k] = cpu_to_le16(buffrag->length);
+		switch (k) {
+		case 0:
+			hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
+			break;
+		case 1:
+			hwdesc->addr_buffer2 = cpu_to_le64(buffrag->dma);
+			break;
+		case 2:
+			hwdesc->addr_buffer3 = cpu_to_le64(buffrag->dma);
+			break;
+		case 3:
+			hwdesc->addr_buffer4 = cpu_to_le64(buffrag->dma);
+			break;
+		}
+	}
+
+	tx_ring->producer = get_next_index(producer, num_txd);
+
+	qlcnic_tso_check(netdev, tx_ring, first_desc, skb);
+
+	qlcnic_update_cmd_producer(adapter, tx_ring);
+
+	adapter->stats.txbytes += skb->len;
+	adapter->stats.xmitcalled++;
+
+	return NETDEV_TX_OK;
+
+drop_packet:
+	adapter->stats.txdropped++;
+	dev_kfree_skb_any(skb);
+	return NETDEV_TX_OK;
+}
+
+static int qlcnic_check_temp(struct qlcnic_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	u32 temp, temp_state, temp_val;
+	int rv = 0;
+
+	temp = QLCRD32(adapter, CRB_TEMP_STATE);
+
+	temp_state = qlcnic_get_temp_state(temp);
+	temp_val = qlcnic_get_temp_val(temp);
+
+	if (temp_state == QLCNIC_TEMP_PANIC) {
+		dev_err(&netdev->dev,
+		       "Device temperature %d degrees C exceeds"
+		       " maximum allowed. Hardware has been shut down.\n",
+		       temp_val);
+		rv = 1;
+	} else if (temp_state == QLCNIC_TEMP_WARN) {
+		if (adapter->temp == QLCNIC_TEMP_NORMAL) {
+			dev_err(&netdev->dev,
+			       "Device temperature %d degrees C "
+			       "exceeds operating range."
+			       " Immediate action needed.\n",
+			       temp_val);
+		}
+	} else {
+		if (adapter->temp == QLCNIC_TEMP_WARN) {
+			dev_info(&netdev->dev,
+			       "Device temperature is now %d degrees C"
+			       " in normal range.\n", temp_val);
+		}
+	}
+	adapter->temp = temp_state;
+	return rv;
+}
+
+void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup)
+{
+	struct net_device *netdev = adapter->netdev;
+
+	if (adapter->ahw.linkup && !linkup) {
+		dev_info(&netdev->dev, "NIC Link is down\n");
+		adapter->ahw.linkup = 0;
+		if (netif_running(netdev)) {
+			netif_carrier_off(netdev);
+			netif_stop_queue(netdev);
+		}
+	} else if (!adapter->ahw.linkup && linkup) {
+		dev_info(&netdev->dev, "NIC Link is up\n");
+		adapter->ahw.linkup = 1;
+		if (netif_running(netdev)) {
+			netif_carrier_on(netdev);
+			netif_wake_queue(netdev);
+		}
+	}
+}
+
+static void qlcnic_tx_timeout(struct net_device *netdev)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+
+	if (test_bit(__QLCNIC_RESETTING, &adapter->state))
+		return;
+
+	dev_err(&netdev->dev, "transmit timeout, resetting.\n");
+	schedule_work(&adapter->tx_timeout_task);
+}
+
+static void qlcnic_tx_timeout_task(struct work_struct *work)
+{
+	struct qlcnic_adapter *adapter =
+		container_of(work, struct qlcnic_adapter, tx_timeout_task);
+
+	if (!netif_running(adapter->netdev))
+		return;
+
+	if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+		return;
+
+	if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS)
+		goto request_reset;
+
+	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+	if (!qlcnic_reset_context(adapter)) {
+		adapter->netdev->trans_start = jiffies;
+		return;
+
+		/* context reset failed, fall through for fw reset */
+	}
+
+request_reset:
+	adapter->need_fw_reset = 1;
+	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+}
+
+static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct net_device_stats *stats = &netdev->stats;
+
+	memset(stats, 0, sizeof(*stats));
+
+	stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts;
+	stats->tx_packets = adapter->stats.xmitfinished;
+	stats->rx_bytes = adapter->stats.rxbytes;
+	stats->tx_bytes = adapter->stats.txbytes;
+	stats->rx_dropped = adapter->stats.rxdropped;
+	stats->tx_dropped = adapter->stats.txdropped;
+
+	return stats;
+}
+
+static irqreturn_t qlcnic_clear_legacy_intr(struct qlcnic_adapter *adapter)
+{
+	u32 status;
+
+	status = readl(adapter->isr_int_vec);
+
+	if (!(status & adapter->int_vec_bit))
+		return IRQ_NONE;
+
+	/* check interrupt state machine, to be sure */
+	status = readl(adapter->crb_int_state_reg);
+	if (!ISR_LEGACY_INT_TRIGGERED(status))
+		return IRQ_NONE;
+
+	writel(0xffffffff, adapter->tgt_status_reg);
+	/* read twice to ensure write is flushed */
+	readl(adapter->isr_int_vec);
+	readl(adapter->isr_int_vec);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t qlcnic_tmp_intr(int irq, void *data)
+{
+	struct qlcnic_host_sds_ring *sds_ring = data;
+	struct qlcnic_adapter *adapter = sds_ring->adapter;
+
+	if (adapter->flags & QLCNIC_MSIX_ENABLED)
+		goto done;
+	else if (adapter->flags & QLCNIC_MSI_ENABLED) {
+		writel(0xffffffff, adapter->tgt_status_reg);
+		goto done;
+	}
+
+	if (qlcnic_clear_legacy_intr(adapter) == IRQ_NONE)
+		return IRQ_NONE;
+
+done:
+	adapter->diag_cnt++;
+	qlcnic_enable_int(sds_ring);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t qlcnic_intr(int irq, void *data)
+{
+	struct qlcnic_host_sds_ring *sds_ring = data;
+	struct qlcnic_adapter *adapter = sds_ring->adapter;
+
+	if (qlcnic_clear_legacy_intr(adapter) == IRQ_NONE)
+		return IRQ_NONE;
+
+	napi_schedule(&sds_ring->napi);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t qlcnic_msi_intr(int irq, void *data)
+{
+	struct qlcnic_host_sds_ring *sds_ring = data;
+	struct qlcnic_adapter *adapter = sds_ring->adapter;
+
+	/* clear interrupt */
+	writel(0xffffffff, adapter->tgt_status_reg);
+
+	napi_schedule(&sds_ring->napi);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t qlcnic_msix_intr(int irq, void *data)
+{
+	struct qlcnic_host_sds_ring *sds_ring = data;
+
+	napi_schedule(&sds_ring->napi);
+	return IRQ_HANDLED;
+}
+
+static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter)
+{
+	u32 sw_consumer, hw_consumer;
+	int count = 0, i;
+	struct qlcnic_cmd_buffer *buffer;
+	struct pci_dev *pdev = adapter->pdev;
+	struct net_device *netdev = adapter->netdev;
+	struct qlcnic_skb_frag *frag;
+	int done;
+	struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring;
+
+	if (!spin_trylock(&adapter->tx_clean_lock))
+		return 1;
+
+	sw_consumer = tx_ring->sw_consumer;
+	hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
+
+	while (sw_consumer != hw_consumer) {
+		buffer = &tx_ring->cmd_buf_arr[sw_consumer];
+		if (buffer->skb) {
+			frag = &buffer->frag_array[0];
+			pci_unmap_single(pdev, frag->dma, frag->length,
+					 PCI_DMA_TODEVICE);
+			frag->dma = 0ULL;
+			for (i = 1; i < buffer->frag_count; i++) {
+				frag++;
+				pci_unmap_page(pdev, frag->dma, frag->length,
+					       PCI_DMA_TODEVICE);
+				frag->dma = 0ULL;
+			}
+
+			adapter->stats.xmitfinished++;
+			dev_kfree_skb_any(buffer->skb);
+			buffer->skb = NULL;
+		}
+
+		sw_consumer = get_next_index(sw_consumer, tx_ring->num_desc);
+		if (++count >= MAX_STATUS_HANDLE)
+			break;
+	}
+
+	if (count && netif_running(netdev)) {
+		tx_ring->sw_consumer = sw_consumer;
+
+		smp_mb();
+
+		if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) {
+			__netif_tx_lock(tx_ring->txq, smp_processor_id());
+			if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) {
+				netif_wake_queue(netdev);
+				adapter->tx_timeo_cnt = 0;
+				adapter->stats.xmit_on++;
+			}
+			__netif_tx_unlock(tx_ring->txq);
+		}
+	}
+	/*
+	 * If everything is freed up to consumer then check if the ring is full
+	 * If the ring is full then check if more needs to be freed and
+	 * schedule the call back again.
+	 *
+	 * This happens when there are 2 CPUs. One could be freeing and the
+	 * other filling it. If the ring is full when we get out of here and
+	 * the card has already interrupted the host then the host can miss the
+	 * interrupt.
+	 *
+	 * There is still a possible race condition and the host could miss an
+	 * interrupt. The card has to take care of this.
+	 */
+	hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
+	done = (sw_consumer == hw_consumer);
+	spin_unlock(&adapter->tx_clean_lock);
+
+	return done;
+}
+
+static int qlcnic_poll(struct napi_struct *napi, int budget)
+{
+	struct qlcnic_host_sds_ring *sds_ring =
+		container_of(napi, struct qlcnic_host_sds_ring, napi);
+
+	struct qlcnic_adapter *adapter = sds_ring->adapter;
+
+	int tx_complete;
+	int work_done;
+
+	tx_complete = qlcnic_process_cmd_ring(adapter);
+
+	work_done = qlcnic_process_rcv_ring(sds_ring, budget);
+
+	if ((work_done < budget) && tx_complete) {
+		napi_complete(&sds_ring->napi);
+		if (test_bit(__QLCNIC_DEV_UP, &adapter->state))
+			qlcnic_enable_int(sds_ring);
+	}
+
+	return work_done;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void qlcnic_poll_controller(struct net_device *netdev)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	disable_irq(adapter->irq);
+	qlcnic_intr(adapter->irq, adapter);
+	enable_irq(adapter->irq);
+}
+#endif
+
+static void
+qlcnic_set_drv_state(struct qlcnic_adapter *adapter, int state)
+{
+	u32  val;
+
+	WARN_ON(state != QLCNIC_DEV_NEED_RESET &&
+			state != QLCNIC_DEV_NEED_QUISCENT);
+
+	if (qlcnic_api_lock(adapter))
+		return ;
+
+	val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
+
+	if (state == QLCNIC_DEV_NEED_RESET)
+		val |= ((u32)0x1 << (adapter->portnum * 4));
+	else if (state == QLCNIC_DEV_NEED_QUISCENT)
+		val |= ((u32)0x1 << ((adapter->portnum * 4) + 1));
+
+	QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val);
+
+	qlcnic_api_unlock(adapter);
+}
+
+static int
+qlcnic_clr_drv_state(struct qlcnic_adapter *adapter)
+{
+	u32  val;
+
+	if (qlcnic_api_lock(adapter))
+		return -EBUSY;
+
+	val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
+	val &= ~((u32)0x3 << (adapter->portnum * 4));
+	QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val);
+
+	qlcnic_api_unlock(adapter);
+
+	return 0;
+}
+
+static void
+qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter)
+{
+	u32  val;
+
+	if (qlcnic_api_lock(adapter))
+		goto err;
+
+	val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT);
+	val &= ~((u32)0x1 << (adapter->portnum * 4));
+	QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val);
+
+	if (!(val & 0x11111111))
+		QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_COLD);
+
+	val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
+	val &= ~((u32)0x3 << (adapter->portnum * 4));
+	QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val);
+
+	qlcnic_api_unlock(adapter);
+err:
+	adapter->fw_fail_cnt = 0;
+	clear_bit(__QLCNIC_START_FW, &adapter->state);
+	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+}
+
+static int
+qlcnic_check_drv_state(struct qlcnic_adapter *adapter)
+{
+	int act, state;
+
+	state = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
+	act = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT);
+
+	if (((state & 0x11111111) == (act & 0x11111111)) ||
+			((act & 0x11111111) == ((state >> 1) & 0x11111111)))
+		return 0;
+	else
+		return 1;
+}
+
+static int
+qlcnic_can_start_firmware(struct qlcnic_adapter *adapter)
+{
+	u32 val, prev_state;
+	int cnt = 0;
+	int portnum = adapter->portnum;
+
+	if (qlcnic_api_lock(adapter))
+		return -1;
+
+	val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT);
+	if (!(val & ((int)0x1 << (portnum * 4)))) {
+		val |= ((u32)0x1 << (portnum * 4));
+		QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val);
+	} else if (test_and_clear_bit(__QLCNIC_START_FW, &adapter->state)) {
+		goto start_fw;
+	}
+
+	prev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
+
+	switch (prev_state) {
+	case QLCNIC_DEV_COLD:
+start_fw:
+		QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITALIZING);
+		qlcnic_api_unlock(adapter);
+		return 1;
+
+	case QLCNIC_DEV_READY:
+		qlcnic_api_unlock(adapter);
+		return 0;
+
+	case QLCNIC_DEV_NEED_RESET:
+		val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
+		val |= ((u32)0x1 << (portnum * 4));
+		QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val);
+		break;
+
+	case QLCNIC_DEV_NEED_QUISCENT:
+		val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
+		val |= ((u32)0x1 << ((portnum * 4) + 1));
+		QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val);
+		break;
+
+	case QLCNIC_DEV_FAILED:
+		qlcnic_api_unlock(adapter);
+		return -1;
+	}
+
+	qlcnic_api_unlock(adapter);
+	msleep(1000);
+	while ((QLCRD32(adapter, QLCNIC_CRB_DEV_STATE) != QLCNIC_DEV_READY) &&
+			++cnt < 20)
+		msleep(1000);
+
+	if (cnt >= 20)
+		return -1;
+
+	if (qlcnic_api_lock(adapter))
+		return -1;
+
+	val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
+	val &= ~((u32)0x3 << (portnum * 4));
+	QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val);
+
+	qlcnic_api_unlock(adapter);
+
+	return 0;
+}
+
+static void
+qlcnic_fwinit_work(struct work_struct *work)
+{
+	struct qlcnic_adapter *adapter = container_of(work,
+			struct qlcnic_adapter, fw_work.work);
+	int dev_state;
+
+	if (++adapter->fw_wait_cnt > FW_POLL_THRESH)
+		goto err_ret;
+
+	if (test_bit(__QLCNIC_START_FW, &adapter->state)) {
+
+		if (qlcnic_check_drv_state(adapter)) {
+			qlcnic_schedule_work(adapter,
+					qlcnic_fwinit_work, FW_POLL_DELAY);
+			return;
+		}
+
+		if (!qlcnic_start_firmware(adapter)) {
+			qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
+			return;
+		}
+
+		goto err_ret;
+	}
+
+	dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
+	switch (dev_state) {
+	case QLCNIC_DEV_READY:
+		if (!qlcnic_start_firmware(adapter)) {
+			qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
+			return;
+		}
+	case QLCNIC_DEV_FAILED:
+		break;
+
+	default:
+		qlcnic_schedule_work(adapter,
+			qlcnic_fwinit_work, 2 * FW_POLL_DELAY);
+		return;
+	}
+
+err_ret:
+	qlcnic_clr_all_drv_state(adapter);
+}
+
+static void
+qlcnic_detach_work(struct work_struct *work)
+{
+	struct qlcnic_adapter *adapter = container_of(work,
+			struct qlcnic_adapter, fw_work.work);
+	struct net_device *netdev = adapter->netdev;
+	u32 status;
+
+	netif_device_detach(netdev);
+
+	qlcnic_down(adapter, netdev);
+
+	rtnl_lock();
+	qlcnic_detach(adapter);
+	rtnl_unlock();
+
+	status = QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS1);
+
+	if (status & QLCNIC_RCODE_FATAL_ERROR)
+		goto err_ret;
+
+	if (adapter->temp == QLCNIC_TEMP_PANIC)
+		goto err_ret;
+
+	qlcnic_set_drv_state(adapter, adapter->dev_state);
+
+	adapter->fw_wait_cnt = 0;
+
+	qlcnic_schedule_work(adapter, qlcnic_fwinit_work, FW_POLL_DELAY);
+
+	return;
+
+err_ret:
+	qlcnic_clr_all_drv_state(adapter);
+
+}
+
+static void
+qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
+{
+	u32 state;
+
+	if (qlcnic_api_lock(adapter))
+		return;
+
+	state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
+
+	if (state != QLCNIC_DEV_INITALIZING && state != QLCNIC_DEV_NEED_RESET) {
+		QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET);
+		set_bit(__QLCNIC_START_FW, &adapter->state);
+	}
+
+	qlcnic_api_unlock(adapter);
+}
+
+static void
+qlcnic_schedule_work(struct qlcnic_adapter *adapter,
+		work_func_t func, int delay)
+{
+	INIT_DELAYED_WORK(&adapter->fw_work, func);
+	schedule_delayed_work(&adapter->fw_work, round_jiffies_relative(delay));
+}
+
+static void
+qlcnic_cancel_fw_work(struct qlcnic_adapter *adapter)
+{
+	while (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+		msleep(10);
+
+	cancel_delayed_work_sync(&adapter->fw_work);
+}
+
+static void
+qlcnic_attach_work(struct work_struct *work)
+{
+	struct qlcnic_adapter *adapter = container_of(work,
+				struct qlcnic_adapter, fw_work.work);
+	struct net_device *netdev = adapter->netdev;
+	int err;
+
+	if (netif_running(netdev)) {
+		err = qlcnic_attach(adapter);
+		if (err)
+			goto done;
+
+		err = qlcnic_up(adapter, netdev);
+		if (err) {
+			qlcnic_detach(adapter);
+			goto done;
+		}
+
+		qlcnic_config_indev_addr(netdev, NETDEV_UP);
+	}
+
+	netif_device_attach(netdev);
+
+done:
+	adapter->fw_fail_cnt = 0;
+	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+
+	if (!qlcnic_clr_drv_state(adapter))
+		qlcnic_schedule_work(adapter, qlcnic_fw_poll_work,
+							FW_POLL_DELAY);
+}
+
+static int
+qlcnic_check_health(struct qlcnic_adapter *adapter)
+{
+	u32 state = 0, heartbit;
+	struct net_device *netdev = adapter->netdev;
+
+	if (qlcnic_check_temp(adapter))
+		goto detach;
+
+	if (adapter->need_fw_reset) {
+		qlcnic_dev_request_reset(adapter);
+		goto detach;
+	}
+
+	state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
+	if (state == QLCNIC_DEV_NEED_RESET || state == QLCNIC_DEV_NEED_QUISCENT)
+		adapter->need_fw_reset = 1;
+
+	heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
+	if (heartbit != adapter->heartbit) {
+		adapter->heartbit = heartbit;
+		adapter->fw_fail_cnt = 0;
+		if (adapter->need_fw_reset)
+			goto detach;
+		return 0;
+	}
+
+	if (++adapter->fw_fail_cnt < FW_FAIL_THRESH)
+		return 0;
+
+	qlcnic_dev_request_reset(adapter);
+
+	clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state);
+
+	dev_info(&netdev->dev, "firmware hang detected\n");
+
+detach:
+	adapter->dev_state = (state == QLCNIC_DEV_NEED_QUISCENT) ? state :
+		QLCNIC_DEV_NEED_RESET;
+
+	if ((auto_fw_reset == AUTO_FW_RESET_ENABLED) &&
+			!test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+		qlcnic_schedule_work(adapter, qlcnic_detach_work, 0);
+
+	return 1;
+}
+
+static void
+qlcnic_fw_poll_work(struct work_struct *work)
+{
+	struct qlcnic_adapter *adapter = container_of(work,
+				struct qlcnic_adapter, fw_work.work);
+
+	if (test_bit(__QLCNIC_RESETTING, &adapter->state))
+		goto reschedule;
+
+
+	if (qlcnic_check_health(adapter))
+		return;
+
+reschedule:
+	qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY);
+}
+
+static ssize_t
+qlcnic_store_bridged_mode(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	unsigned long new;
+	int ret = -EINVAL;
+
+	if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG))
+		goto err_out;
+
+	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+		goto err_out;
+
+	if (strict_strtoul(buf, 2, &new))
+		goto err_out;
+
+	if (!qlcnic_config_bridged_mode(adapter, !!new))
+		ret = len;
+
+err_out:
+	return ret;
+}
+
+static ssize_t
+qlcnic_show_bridged_mode(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	int bridged_mode = 0;
+
+	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG)
+		bridged_mode = !!(adapter->flags & QLCNIC_BRIDGE_ENABLED);
+
+	return sprintf(buf, "%d\n", bridged_mode);
+}
+
+static struct device_attribute dev_attr_bridged_mode = {
+       .attr = {.name = "bridged_mode", .mode = (S_IRUGO | S_IWUSR)},
+       .show = qlcnic_show_bridged_mode,
+       .store = qlcnic_store_bridged_mode,
+};
+
+static ssize_t
+qlcnic_store_diag_mode(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	unsigned long new;
+
+	if (strict_strtoul(buf, 2, &new))
+		return -EINVAL;
+
+	if (!!new != !!(adapter->flags & QLCNIC_DIAG_ENABLED))
+		adapter->flags ^= QLCNIC_DIAG_ENABLED;
+
+	return len;
+}
+
+static ssize_t
+qlcnic_show_diag_mode(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n",
+			!!(adapter->flags & QLCNIC_DIAG_ENABLED));
+}
+
+static struct device_attribute dev_attr_diag_mode = {
+	.attr = {.name = "diag_mode", .mode = (S_IRUGO | S_IWUSR)},
+	.show = qlcnic_show_diag_mode,
+	.store = qlcnic_store_diag_mode,
+};
+
+static int
+qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter,
+		loff_t offset, size_t size)
+{
+	if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
+		return -EIO;
+
+	if ((size != 4) || (offset & 0x3))
+		return  -EINVAL;
+
+	if (offset < QLCNIC_PCI_CRBSPACE)
+		return -EINVAL;
+
+	return 0;
+}
+
+static ssize_t
+qlcnic_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr,
+		char *buf, loff_t offset, size_t size)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	u32 data;
+	int ret;
+
+	ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
+	if (ret != 0)
+		return ret;
+
+	data = QLCRD32(adapter, offset);
+	memcpy(buf, &data, size);
+	return size;
+}
+
+static ssize_t
+qlcnic_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr,
+		char *buf, loff_t offset, size_t size)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	u32 data;
+	int ret;
+
+	ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
+	if (ret != 0)
+		return ret;
+
+	memcpy(&data, buf, size);
+	QLCWR32(adapter, offset, data);
+	return size;
+}
+
+static int
+qlcnic_sysfs_validate_mem(struct qlcnic_adapter *adapter,
+		loff_t offset, size_t size)
+{
+	if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
+		return -EIO;
+
+	if ((size != 8) || (offset & 0x7))
+		return  -EIO;
+
+	return 0;
+}
+
+static ssize_t
+qlcnic_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr,
+		char *buf, loff_t offset, size_t size)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	u64 data;
+	int ret;
+
+	ret = qlcnic_sysfs_validate_mem(adapter, offset, size);
+	if (ret != 0)
+		return ret;
+
+	if (qlcnic_pci_mem_read_2M(adapter, offset, &data))
+		return -EIO;
+
+	memcpy(buf, &data, size);
+
+	return size;
+}
+
+static ssize_t
+qlcnic_sysfs_write_mem(struct kobject *kobj, struct bin_attribute *attr,
+		char *buf, loff_t offset, size_t size)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	u64 data;
+	int ret;
+
+	ret = qlcnic_sysfs_validate_mem(adapter, offset, size);
+	if (ret != 0)
+		return ret;
+
+	memcpy(&data, buf, size);
+
+	if (qlcnic_pci_mem_write_2M(adapter, offset, data))
+		return -EIO;
+
+	return size;
+}
+
+
+static struct bin_attribute bin_attr_crb = {
+	.attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)},
+	.size = 0,
+	.read = qlcnic_sysfs_read_crb,
+	.write = qlcnic_sysfs_write_crb,
+};
+
+static struct bin_attribute bin_attr_mem = {
+	.attr = {.name = "mem", .mode = (S_IRUGO | S_IWUSR)},
+	.size = 0,
+	.read = qlcnic_sysfs_read_mem,
+	.write = qlcnic_sysfs_write_mem,
+};
+
+static void
+qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter)
+{
+	struct device *dev = &adapter->pdev->dev;
+
+	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG)
+		if (device_create_file(dev, &dev_attr_bridged_mode))
+			dev_warn(dev,
+				"failed to create bridged_mode sysfs entry\n");
+}
+
+static void
+qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter)
+{
+	struct device *dev = &adapter->pdev->dev;
+
+	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG)
+		device_remove_file(dev, &dev_attr_bridged_mode);
+}
+
+static void
+qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
+{
+	struct device *dev = &adapter->pdev->dev;
+
+	if (device_create_file(dev, &dev_attr_diag_mode))
+		dev_info(dev, "failed to create diag_mode sysfs entry\n");
+	if (device_create_bin_file(dev, &bin_attr_crb))
+		dev_info(dev, "failed to create crb sysfs entry\n");
+	if (device_create_bin_file(dev, &bin_attr_mem))
+		dev_info(dev, "failed to create mem sysfs entry\n");
+}
+
+
+static void
+qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
+{
+	struct device *dev = &adapter->pdev->dev;
+
+	device_remove_file(dev, &dev_attr_diag_mode);
+	device_remove_bin_file(dev, &bin_attr_crb);
+	device_remove_bin_file(dev, &bin_attr_mem);
+}
+
+#ifdef CONFIG_INET
+
+#define is_qlcnic_netdev(dev) (dev->netdev_ops == &qlcnic_netdev_ops)
+
+static int
+qlcnic_destip_supported(struct qlcnic_adapter *adapter)
+{
+	if (adapter->ahw.cut_through)
+		return 0;
+
+	return 1;
+}
+
+static void
+qlcnic_config_indev_addr(struct net_device *dev, unsigned long event)
+{
+	struct in_device *indev;
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+
+	if (!qlcnic_destip_supported(adapter))
+		return;
+
+	indev = in_dev_get(dev);
+	if (!indev)
+		return;
+
+	for_ifa(indev) {
+		switch (event) {
+		case NETDEV_UP:
+			qlcnic_config_ipaddr(adapter,
+					ifa->ifa_address, QLCNIC_IP_UP);
+			break;
+		case NETDEV_DOWN:
+			qlcnic_config_ipaddr(adapter,
+					ifa->ifa_address, QLCNIC_IP_DOWN);
+			break;
+		default:
+			break;
+		}
+	} endfor_ifa(indev);
+
+	in_dev_put(indev);
+	return;
+}
+
+static int qlcnic_netdev_event(struct notifier_block *this,
+				 unsigned long event, void *ptr)
+{
+	struct qlcnic_adapter *adapter;
+	struct net_device *dev = (struct net_device *)ptr;
+
+recheck:
+	if (dev == NULL)
+		goto done;
+
+	if (dev->priv_flags & IFF_802_1Q_VLAN) {
+		dev = vlan_dev_real_dev(dev);
+		goto recheck;
+	}
+
+	if (!is_qlcnic_netdev(dev))
+		goto done;
+
+	adapter = netdev_priv(dev);
+
+	if (!adapter)
+		goto done;
+
+	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+		goto done;
+
+	qlcnic_config_indev_addr(dev, event);
+done:
+	return NOTIFY_DONE;
+}
+
+static int
+qlcnic_inetaddr_event(struct notifier_block *this,
+		unsigned long event, void *ptr)
+{
+	struct qlcnic_adapter *adapter;
+	struct net_device *dev;
+
+	struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
+
+	dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL;
+
+recheck:
+	if (dev == NULL || !netif_running(dev))
+		goto done;
+
+	if (dev->priv_flags & IFF_802_1Q_VLAN) {
+		dev = vlan_dev_real_dev(dev);
+		goto recheck;
+	}
+
+	if (!is_qlcnic_netdev(dev))
+		goto done;
+
+	adapter = netdev_priv(dev);
+
+	if (!adapter || !qlcnic_destip_supported(adapter))
+		goto done;
+
+	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+		goto done;
+
+	switch (event) {
+	case NETDEV_UP:
+		qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_UP);
+		break;
+	case NETDEV_DOWN:
+		qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_DOWN);
+		break;
+	default:
+		break;
+	}
+
+done:
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block	qlcnic_netdev_cb = {
+	.notifier_call = qlcnic_netdev_event,
+};
+
+static struct notifier_block qlcnic_inetaddr_cb = {
+	.notifier_call = qlcnic_inetaddr_event,
+};
+#else
+static void
+qlcnic_config_indev_addr(struct net_device *dev, unsigned long event)
+{ }
+#endif
+
+static struct pci_driver qlcnic_driver = {
+	.name = qlcnic_driver_name,
+	.id_table = qlcnic_pci_tbl,
+	.probe = qlcnic_probe,
+	.remove = __devexit_p(qlcnic_remove),
+#ifdef CONFIG_PM
+	.suspend = qlcnic_suspend,
+	.resume = qlcnic_resume,
+#endif
+	.shutdown = qlcnic_shutdown
+};
+
+static int __init qlcnic_init_module(void)
+{
+
+	printk(KERN_INFO "%s\n", qlcnic_driver_string);
+
+#ifdef CONFIG_INET
+	register_netdevice_notifier(&qlcnic_netdev_cb);
+	register_inetaddr_notifier(&qlcnic_inetaddr_cb);
+#endif
+
+
+	return pci_register_driver(&qlcnic_driver);
+}
+
+module_init(qlcnic_init_module);
+
+static void __exit qlcnic_exit_module(void)
+{
+
+	pci_unregister_driver(&qlcnic_driver);
+
+#ifdef CONFIG_INET
+	unregister_inetaddr_notifier(&qlcnic_inetaddr_cb);
+	unregister_netdevice_notifier(&qlcnic_netdev_cb);
+#endif
+}
+
+module_exit(qlcnic_exit_module);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_dbg.c linux-libre-2.6.34-gnu1/drivers/net/qlge/qlge_dbg.c
--- linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_dbg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/qlge/qlge_dbg.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,407 @@
+#include <linux/slab.h>
+
 #include "qlge.h"
 
+/* Read a NIC register from the alternate function. */
+static u32 ql_read_other_func_reg(struct ql_adapter *qdev,
+						u32 reg)
+{
+	u32 register_to_read;
+	u32 reg_val;
+	unsigned int status = 0;
+
+	register_to_read = MPI_NIC_REG_BLOCK
+				| MPI_NIC_READ
+				| (qdev->alt_func << MPI_NIC_FUNCTION_SHIFT)
+				| reg;
+	status = ql_read_mpi_reg(qdev, register_to_read, &reg_val);
+	if (status != 0)
+		return 0xffffffff;
+
+	return reg_val;
+}
+
+/* Write a NIC register from the alternate function. */
+static int ql_write_other_func_reg(struct ql_adapter *qdev,
+					u32 reg, u32 reg_val)
+{
+	u32 register_to_read;
+	int status = 0;
+
+	register_to_read = MPI_NIC_REG_BLOCK
+				| MPI_NIC_READ
+				| (qdev->alt_func << MPI_NIC_FUNCTION_SHIFT)
+				| reg;
+	status = ql_write_mpi_reg(qdev, register_to_read, reg_val);
+
+	return status;
+}
+
+static int ql_wait_other_func_reg_rdy(struct ql_adapter *qdev, u32 reg,
+					u32 bit, u32 err_bit)
+{
+	u32 temp;
+	int count = 10;
+
+	while (count) {
+		temp = ql_read_other_func_reg(qdev, reg);
+
+		/* check for errors */
+		if (temp & err_bit)
+			return -1;
+		else if (temp & bit)
+			return 0;
+		mdelay(10);
+		count--;
+	}
+	return -1;
+}
+
+static int ql_read_other_func_serdes_reg(struct ql_adapter *qdev, u32 reg,
+							u32 *data)
+{
+	int status;
+
+	/* wait for reg to come ready */
+	status = ql_wait_other_func_reg_rdy(qdev, XG_SERDES_ADDR / 4,
+						XG_SERDES_ADDR_RDY, 0);
+	if (status)
+		goto exit;
+
+	/* set up for reg read */
+	ql_write_other_func_reg(qdev, XG_SERDES_ADDR/4, reg | PROC_ADDR_R);
+
+	/* wait for reg to come ready */
+	status = ql_wait_other_func_reg_rdy(qdev, XG_SERDES_ADDR / 4,
+						XG_SERDES_ADDR_RDY, 0);
+	if (status)
+		goto exit;
+
+	/* get the data */
+	*data = ql_read_other_func_reg(qdev, (XG_SERDES_DATA / 4));
+exit:
+	return status;
+}
+
+/* Read out the SERDES registers */
+static int ql_read_serdes_reg(struct ql_adapter *qdev, u32 reg, u32 * data)
+{
+	int status;
+
+	/* wait for reg to come ready */
+	status = ql_wait_reg_rdy(qdev, XG_SERDES_ADDR, XG_SERDES_ADDR_RDY, 0);
+	if (status)
+		goto exit;
+
+	/* set up for reg read */
+	ql_write32(qdev, XG_SERDES_ADDR, reg | PROC_ADDR_R);
+
+	/* wait for reg to come ready */
+	status = ql_wait_reg_rdy(qdev, XG_SERDES_ADDR, XG_SERDES_ADDR_RDY, 0);
+	if (status)
+		goto exit;
+
+	/* get the data */
+	*data = ql_read32(qdev, XG_SERDES_DATA);
+exit:
+	return status;
+}
+
+static void ql_get_both_serdes(struct ql_adapter *qdev, u32 addr,
+			u32 *direct_ptr, u32 *indirect_ptr,
+			unsigned int direct_valid, unsigned int indirect_valid)
+{
+	unsigned int status;
+
+	status = 1;
+	if (direct_valid)
+		status = ql_read_serdes_reg(qdev, addr, direct_ptr);
+	/* Dead fill any failures or invalids. */
+	if (status)
+		*direct_ptr = 0xDEADBEEF;
+
+	status = 1;
+	if (indirect_valid)
+		status = ql_read_other_func_serdes_reg(
+						qdev, addr, indirect_ptr);
+	/* Dead fill any failures or invalids. */
+	if (status)
+		*indirect_ptr = 0xDEADBEEF;
+}
+
+static int ql_get_serdes_regs(struct ql_adapter *qdev,
+				struct ql_mpi_coredump *mpi_coredump)
+{
+	int status;
+	unsigned int xfi_direct_valid, xfi_indirect_valid, xaui_direct_valid;
+	unsigned int xaui_indirect_valid, i;
+	u32 *direct_ptr, temp;
+	u32 *indirect_ptr;
+
+	xfi_direct_valid = xfi_indirect_valid = 0;
+	xaui_direct_valid = xaui_indirect_valid = 1;
+
+	/* The XAUI needs to be read out per port */
+	if (qdev->func & 1) {
+		/* We are NIC 2	*/
+		status = ql_read_other_func_serdes_reg(qdev,
+				XG_SERDES_XAUI_HSS_PCS_START, &temp);
+		if (status)
+			temp = XG_SERDES_ADDR_XAUI_PWR_DOWN;
+		if ((temp & XG_SERDES_ADDR_XAUI_PWR_DOWN) ==
+					XG_SERDES_ADDR_XAUI_PWR_DOWN)
+			xaui_indirect_valid = 0;
+
+		status = ql_read_serdes_reg(qdev,
+				XG_SERDES_XAUI_HSS_PCS_START, &temp);
+		if (status)
+			temp = XG_SERDES_ADDR_XAUI_PWR_DOWN;
+
+		if ((temp & XG_SERDES_ADDR_XAUI_PWR_DOWN) ==
+					XG_SERDES_ADDR_XAUI_PWR_DOWN)
+			xaui_direct_valid = 0;
+	} else {
+		/* We are NIC 1	*/
+		status = ql_read_other_func_serdes_reg(qdev,
+				XG_SERDES_XAUI_HSS_PCS_START, &temp);
+		if (status)
+			temp = XG_SERDES_ADDR_XAUI_PWR_DOWN;
+		if ((temp & XG_SERDES_ADDR_XAUI_PWR_DOWN) ==
+					XG_SERDES_ADDR_XAUI_PWR_DOWN)
+			xaui_indirect_valid = 0;
+
+		status = ql_read_serdes_reg(qdev,
+				XG_SERDES_XAUI_HSS_PCS_START, &temp);
+		if (status)
+			temp = XG_SERDES_ADDR_XAUI_PWR_DOWN;
+		if ((temp & XG_SERDES_ADDR_XAUI_PWR_DOWN) ==
+					XG_SERDES_ADDR_XAUI_PWR_DOWN)
+			xaui_direct_valid = 0;
+	}
+
+	/*
+	 * XFI register is shared so only need to read one
+	 * functions and then check the bits.
+	 */
+	status = ql_read_serdes_reg(qdev, XG_SERDES_ADDR_STS, &temp);
+	if (status)
+		temp = 0;
+
+	if ((temp & XG_SERDES_ADDR_XFI1_PWR_UP) ==
+					XG_SERDES_ADDR_XFI1_PWR_UP) {
+		/* now see if i'm NIC 1 or NIC 2 */
+		if (qdev->func & 1)
+			/* I'm NIC 2, so the indirect (NIC1) xfi is up. */
+			xfi_indirect_valid = 1;
+		else
+			xfi_direct_valid = 1;
+	}
+	if ((temp & XG_SERDES_ADDR_XFI2_PWR_UP) ==
+					XG_SERDES_ADDR_XFI2_PWR_UP) {
+		/* now see if i'm NIC 1 or NIC 2 */
+		if (qdev->func & 1)
+			/* I'm NIC 2, so the indirect (NIC1) xfi is up. */
+			xfi_direct_valid = 1;
+		else
+			xfi_indirect_valid = 1;
+	}
+
+	/* Get XAUI_AN register block. */
+	if (qdev->func & 1) {
+		/* Function 2 is direct	*/
+		direct_ptr = mpi_coredump->serdes2_xaui_an;
+		indirect_ptr = mpi_coredump->serdes_xaui_an;
+	} else {
+		/* Function 1 is direct	*/
+		direct_ptr = mpi_coredump->serdes_xaui_an;
+		indirect_ptr = mpi_coredump->serdes2_xaui_an;
+	}
+
+	for (i = 0; i <= 0x000000034; i += 4, direct_ptr++, indirect_ptr++)
+		ql_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
+					xaui_direct_valid, xaui_indirect_valid);
+
+	/* Get XAUI_HSS_PCS register block. */
+	if (qdev->func & 1) {
+		direct_ptr =
+			mpi_coredump->serdes2_xaui_hss_pcs;
+		indirect_ptr =
+			mpi_coredump->serdes_xaui_hss_pcs;
+	} else {
+		direct_ptr =
+			mpi_coredump->serdes_xaui_hss_pcs;
+		indirect_ptr =
+			mpi_coredump->serdes2_xaui_hss_pcs;
+	}
+
+	for (i = 0x800; i <= 0x880; i += 4, direct_ptr++, indirect_ptr++)
+		ql_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
+					xaui_direct_valid, xaui_indirect_valid);
+
+	/* Get XAUI_XFI_AN register block. */
+	if (qdev->func & 1) {
+		direct_ptr = mpi_coredump->serdes2_xfi_an;
+		indirect_ptr = mpi_coredump->serdes_xfi_an;
+	} else {
+		direct_ptr = mpi_coredump->serdes_xfi_an;
+		indirect_ptr = mpi_coredump->serdes2_xfi_an;
+	}
+
+	for (i = 0x1000; i <= 0x1034; i += 4, direct_ptr++, indirect_ptr++)
+		ql_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
+					xfi_direct_valid, xfi_indirect_valid);
+
+	/* Get XAUI_XFI_TRAIN register block. */
+	if (qdev->func & 1) {
+		direct_ptr = mpi_coredump->serdes2_xfi_train;
+		indirect_ptr =
+			mpi_coredump->serdes_xfi_train;
+	} else {
+		direct_ptr = mpi_coredump->serdes_xfi_train;
+		indirect_ptr =
+			mpi_coredump->serdes2_xfi_train;
+	}
+
+	for (i = 0x1050; i <= 0x107c; i += 4, direct_ptr++, indirect_ptr++)
+		ql_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
+					xfi_direct_valid, xfi_indirect_valid);
+
+	/* Get XAUI_XFI_HSS_PCS register block. */
+	if (qdev->func & 1) {
+		direct_ptr =
+			mpi_coredump->serdes2_xfi_hss_pcs;
+		indirect_ptr =
+			mpi_coredump->serdes_xfi_hss_pcs;
+	} else {
+		direct_ptr =
+			mpi_coredump->serdes_xfi_hss_pcs;
+		indirect_ptr =
+			mpi_coredump->serdes2_xfi_hss_pcs;
+	}
+
+	for (i = 0x1800; i <= 0x1838; i += 4, direct_ptr++, indirect_ptr++)
+		ql_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
+					xfi_direct_valid, xfi_indirect_valid);
+
+	/* Get XAUI_XFI_HSS_TX register block. */
+	if (qdev->func & 1) {
+		direct_ptr =
+			mpi_coredump->serdes2_xfi_hss_tx;
+		indirect_ptr =
+			mpi_coredump->serdes_xfi_hss_tx;
+	} else {
+		direct_ptr = mpi_coredump->serdes_xfi_hss_tx;
+		indirect_ptr =
+			mpi_coredump->serdes2_xfi_hss_tx;
+	}
+	for (i = 0x1c00; i <= 0x1c1f; i++, direct_ptr++, indirect_ptr++)
+		ql_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
+					xfi_direct_valid, xfi_indirect_valid);
+
+	/* Get XAUI_XFI_HSS_RX register block. */
+	if (qdev->func & 1) {
+		direct_ptr =
+			mpi_coredump->serdes2_xfi_hss_rx;
+		indirect_ptr =
+			mpi_coredump->serdes_xfi_hss_rx;
+	} else {
+		direct_ptr = mpi_coredump->serdes_xfi_hss_rx;
+		indirect_ptr =
+			mpi_coredump->serdes2_xfi_hss_rx;
+	}
+
+	for (i = 0x1c40; i <= 0x1c5f; i++, direct_ptr++, indirect_ptr++)
+		ql_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
+					xfi_direct_valid, xfi_indirect_valid);
+
+
+	/* Get XAUI_XFI_HSS_PLL register block. */
+	if (qdev->func & 1) {
+		direct_ptr =
+			mpi_coredump->serdes2_xfi_hss_pll;
+		indirect_ptr =
+			mpi_coredump->serdes_xfi_hss_pll;
+	} else {
+		direct_ptr =
+			mpi_coredump->serdes_xfi_hss_pll;
+		indirect_ptr =
+			mpi_coredump->serdes2_xfi_hss_pll;
+	}
+	for (i = 0x1e00; i <= 0x1e1f; i++, direct_ptr++, indirect_ptr++)
+		ql_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
+					xfi_direct_valid, xfi_indirect_valid);
+	return 0;
+}
+
+static int ql_read_other_func_xgmac_reg(struct ql_adapter *qdev, u32 reg,
+							u32 *data)
+{
+	int status = 0;
+
+	/* wait for reg to come ready */
+	status = ql_wait_other_func_reg_rdy(qdev, XGMAC_ADDR / 4,
+						XGMAC_ADDR_RDY, XGMAC_ADDR_XME);
+	if (status)
+		goto exit;
+
+	/* set up for reg read */
+	ql_write_other_func_reg(qdev, XGMAC_ADDR / 4, reg | XGMAC_ADDR_R);
+
+	/* wait for reg to come ready */
+	status = ql_wait_other_func_reg_rdy(qdev, XGMAC_ADDR / 4,
+						XGMAC_ADDR_RDY, XGMAC_ADDR_XME);
+	if (status)
+		goto exit;
+
+	/* get the data */
+	*data = ql_read_other_func_reg(qdev, XGMAC_DATA / 4);
+exit:
+	return status;
+}
+
+/* Read the 400 xgmac control/statistics registers
+ * skipping unused locations.
+ */
+static int ql_get_xgmac_regs(struct ql_adapter *qdev, u32 * buf,
+					unsigned int other_function)
+{
+	int status = 0;
+	int i;
+
+	for (i = PAUSE_SRC_LO; i < XGMAC_REGISTER_END; i += 4, buf++) {
+		/* We're reading 400 xgmac registers, but we filter out
+		 * serveral locations that are non-responsive to reads.
+		 */
+		if ((i == 0x00000114) ||
+			(i == 0x00000118) ||
+			(i == 0x0000013c) ||
+			(i == 0x00000140) ||
+			(i > 0x00000150 && i < 0x000001fc) ||
+			(i > 0x00000278 && i < 0x000002a0) ||
+			(i > 0x000002c0 && i < 0x000002cf) ||
+			(i > 0x000002dc && i < 0x000002f0) ||
+			(i > 0x000003c8 && i < 0x00000400) ||
+			(i > 0x00000400 && i < 0x00000410) ||
+			(i > 0x00000410 && i < 0x00000420) ||
+			(i > 0x00000420 && i < 0x00000430) ||
+			(i > 0x00000430 && i < 0x00000440) ||
+			(i > 0x00000440 && i < 0x00000450) ||
+			(i > 0x00000450 && i < 0x00000500) ||
+			(i > 0x0000054c && i < 0x00000568) ||
+			(i > 0x000005c8 && i < 0x00000600)) {
+			if (other_function)
+				status =
+				ql_read_other_func_xgmac_reg(qdev, i, buf);
+			else
+				status = ql_read_xgmac_reg(qdev, i, buf);
+
+			if (status)
+				*buf = 0xdeadbeef;
+			break;
+		}
+	}
+	return status;
+}
 
 static int ql_get_ets_regs(struct ql_adapter *qdev, u32 * buf)
 {
@@ -43,8 +445,8 @@ static int ql_get_cam_entries(struct ql_
 		status = ql_get_mac_addr_reg(qdev,
 					MAC_ADDR_TYPE_CAM_MAC, i, value);
 		if (status) {
-			QPRINTK(qdev, DRV, ERR,
-				"Failed read of mac index register.\n");
+			netif_err(qdev, drv, qdev->ndev,
+				  "Failed read of mac index register.\n");
 			goto err;
 		}
 		*buf++ = value[0];	/* lower MAC address */
@@ -55,8 +457,8 @@ static int ql_get_cam_entries(struct ql_
 		status = ql_get_mac_addr_reg(qdev,
 					MAC_ADDR_TYPE_MULTI_MAC, i, value);
 		if (status) {
-			QPRINTK(qdev, DRV, ERR,
-				"Failed read of mac index register.\n");
+			netif_err(qdev, drv, qdev->ndev,
+				  "Failed read of mac index register.\n");
 			goto err;
 		}
 		*buf++ = value[0];	/* lower Mcast address */
@@ -79,8 +481,8 @@ static int ql_get_routing_entries(struct
 	for (i = 0; i < 16; i++) {
 		status = ql_get_routing_reg(qdev, i, &value);
 		if (status) {
-			QPRINTK(qdev, DRV, ERR,
-				"Failed read of routing index register.\n");
+			netif_err(qdev, drv, qdev->ndev,
+				  "Failed read of routing index register.\n");
 			goto err;
 		} else {
 			*buf++ = value;
@@ -91,6 +493,226 @@ err:
 	return status;
 }
 
+/* Read the MPI Processor shadow registers */
+static int ql_get_mpi_shadow_regs(struct ql_adapter *qdev, u32 * buf)
+{
+	u32 i;
+	int status;
+
+	for (i = 0; i < MPI_CORE_SH_REGS_CNT; i++, buf++) {
+		status = ql_write_mpi_reg(qdev, RISC_124,
+				(SHADOW_OFFSET | i << SHADOW_REG_SHIFT));
+		if (status)
+			goto end;
+		status = ql_read_mpi_reg(qdev, RISC_127, buf);
+		if (status)
+			goto end;
+	}
+end:
+	return status;
+}
+
+/* Read the MPI Processor core registers */
+static int ql_get_mpi_regs(struct ql_adapter *qdev, u32 * buf,
+				u32 offset, u32 count)
+{
+	int i, status = 0;
+	for (i = 0; i < count; i++, buf++) {
+		status = ql_read_mpi_reg(qdev, offset + i, buf);
+		if (status)
+			return status;
+	}
+	return status;
+}
+
+/* Read the ASIC probe dump */
+static unsigned int *ql_get_probe(struct ql_adapter *qdev, u32 clock,
+					u32 valid, u32 *buf)
+{
+	u32 module, mux_sel, probe, lo_val, hi_val;
+
+	for (module = 0; module < PRB_MX_ADDR_MAX_MODS; module++) {
+		if (!((valid >> module) & 1))
+			continue;
+		for (mux_sel = 0; mux_sel < PRB_MX_ADDR_MAX_MUX; mux_sel++) {
+			probe = clock
+				| PRB_MX_ADDR_ARE
+				| mux_sel
+				| (module << PRB_MX_ADDR_MOD_SEL_SHIFT);
+			ql_write32(qdev, PRB_MX_ADDR, probe);
+			lo_val = ql_read32(qdev, PRB_MX_DATA);
+			if (mux_sel == 0) {
+				*buf = probe;
+				buf++;
+			}
+			probe |= PRB_MX_ADDR_UP;
+			ql_write32(qdev, PRB_MX_ADDR, probe);
+			hi_val = ql_read32(qdev, PRB_MX_DATA);
+			*buf = lo_val;
+			buf++;
+			*buf = hi_val;
+			buf++;
+		}
+	}
+	return buf;
+}
+
+static int ql_get_probe_dump(struct ql_adapter *qdev, unsigned int *buf)
+{
+	/* First we have to enable the probe mux */
+	ql_write_mpi_reg(qdev, MPI_TEST_FUNC_PRB_CTL, MPI_TEST_FUNC_PRB_EN);
+	buf = ql_get_probe(qdev, PRB_MX_ADDR_SYS_CLOCK,
+			PRB_MX_ADDR_VALID_SYS_MOD, buf);
+	buf = ql_get_probe(qdev, PRB_MX_ADDR_PCI_CLOCK,
+			PRB_MX_ADDR_VALID_PCI_MOD, buf);
+	buf = ql_get_probe(qdev, PRB_MX_ADDR_XGM_CLOCK,
+			PRB_MX_ADDR_VALID_XGM_MOD, buf);
+	buf = ql_get_probe(qdev, PRB_MX_ADDR_FC_CLOCK,
+			PRB_MX_ADDR_VALID_FC_MOD, buf);
+	return 0;
+
+}
+
+/* Read out the routing index registers */
+static int ql_get_routing_index_registers(struct ql_adapter *qdev, u32 *buf)
+{
+	int status;
+	u32 type, index, index_max;
+	u32 result_index;
+	u32 result_data;
+	u32 val;
+
+	status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+	if (status)
+		return status;
+
+	for (type = 0; type < 4; type++) {
+		if (type < 2)
+			index_max = 8;
+		else
+			index_max = 16;
+		for (index = 0; index < index_max; index++) {
+			val = RT_IDX_RS
+				| (type << RT_IDX_TYPE_SHIFT)
+				| (index << RT_IDX_IDX_SHIFT);
+			ql_write32(qdev, RT_IDX, val);
+			result_index = 0;
+			while ((result_index & RT_IDX_MR) == 0)
+				result_index = ql_read32(qdev, RT_IDX);
+			result_data = ql_read32(qdev, RT_DATA);
+			*buf = type;
+			buf++;
+			*buf = index;
+			buf++;
+			*buf = result_index;
+			buf++;
+			*buf = result_data;
+			buf++;
+		}
+	}
+	ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
+	return status;
+}
+
+/* Read out the MAC protocol registers */
+static void ql_get_mac_protocol_registers(struct ql_adapter *qdev, u32 *buf)
+{
+	u32 result_index, result_data;
+	u32 type;
+	u32 index;
+	u32 offset;
+	u32 val;
+	u32 initial_val = MAC_ADDR_RS;
+	u32 max_index;
+	u32 max_offset;
+
+	for (type = 0; type < MAC_ADDR_TYPE_COUNT; type++) {
+		switch (type) {
+
+		case 0: /* CAM */
+			initial_val |= MAC_ADDR_ADR;
+			max_index = MAC_ADDR_MAX_CAM_ENTRIES;
+			max_offset = MAC_ADDR_MAX_CAM_WCOUNT;
+			break;
+		case 1: /* Multicast MAC Address */
+			max_index = MAC_ADDR_MAX_CAM_WCOUNT;
+			max_offset = MAC_ADDR_MAX_CAM_WCOUNT;
+			break;
+		case 2: /* VLAN filter mask */
+		case 3: /* MC filter mask */
+			max_index = MAC_ADDR_MAX_CAM_WCOUNT;
+			max_offset = MAC_ADDR_MAX_CAM_WCOUNT;
+			break;
+		case 4: /* FC MAC addresses */
+			max_index = MAC_ADDR_MAX_FC_MAC_ENTRIES;
+			max_offset = MAC_ADDR_MAX_FC_MAC_WCOUNT;
+			break;
+		case 5: /* Mgmt MAC addresses */
+			max_index = MAC_ADDR_MAX_MGMT_MAC_ENTRIES;
+			max_offset = MAC_ADDR_MAX_MGMT_MAC_WCOUNT;
+			break;
+		case 6: /* Mgmt VLAN addresses */
+			max_index = MAC_ADDR_MAX_MGMT_VLAN_ENTRIES;
+			max_offset = MAC_ADDR_MAX_MGMT_VLAN_WCOUNT;
+			break;
+		case 7: /* Mgmt IPv4 address */
+			max_index = MAC_ADDR_MAX_MGMT_V4_ENTRIES;
+			max_offset = MAC_ADDR_MAX_MGMT_V4_WCOUNT;
+			break;
+		case 8: /* Mgmt IPv6 address */
+			max_index = MAC_ADDR_MAX_MGMT_V6_ENTRIES;
+			max_offset = MAC_ADDR_MAX_MGMT_V6_WCOUNT;
+			break;
+		case 9: /* Mgmt TCP/UDP Dest port */
+			max_index = MAC_ADDR_MAX_MGMT_TU_DP_ENTRIES;
+			max_offset = MAC_ADDR_MAX_MGMT_TU_DP_WCOUNT;
+			break;
+		default:
+			printk(KERN_ERR"Bad type!!! 0x%08x\n", type);
+			max_index = 0;
+			max_offset = 0;
+			break;
+		}
+		for (index = 0; index < max_index; index++) {
+			for (offset = 0; offset < max_offset; offset++) {
+				val = initial_val
+					| (type << MAC_ADDR_TYPE_SHIFT)
+					| (index << MAC_ADDR_IDX_SHIFT)
+					| (offset);
+				ql_write32(qdev, MAC_ADDR_IDX, val);
+				result_index = 0;
+				while ((result_index & MAC_ADDR_MR) == 0) {
+					result_index = ql_read32(qdev,
+								MAC_ADDR_IDX);
+				}
+				result_data = ql_read32(qdev, MAC_ADDR_DATA);
+				*buf = result_index;
+				buf++;
+				*buf = result_data;
+				buf++;
+			}
+		}
+	}
+}
+
+static void ql_get_sem_registers(struct ql_adapter *qdev, u32 *buf)
+{
+	u32 func_num, reg, reg_val;
+	int status;
+
+	for (func_num = 0; func_num < MAX_SEMAPHORE_FUNCTIONS ; func_num++) {
+		reg = MPI_NIC_REG_BLOCK
+			| (func_num << MPI_NIC_FUNCTION_SHIFT)
+			| (SEM / 4);
+		status = ql_read_mpi_reg(qdev, reg, &reg_val);
+		*buf = reg_val;
+		/* if the read failed then dead fill the element. */
+		if (!status)
+			*buf = 0xdeadbeef;
+		buf++;
+	}
+}
+
 /* Create a coredump segment header */
 static void ql_build_coredump_seg_header(
 		struct mpi_coredump_segment_header *seg_hdr,
@@ -103,6 +725,526 @@ static void ql_build_coredump_seg_header
 	memcpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
 }
 
+/*
+ * This function should be called when a coredump / probedump
+ * is to be extracted from the HBA. It is assumed there is a
+ * qdev structure that contains the base address of the register
+ * space for this function as well as a coredump structure that
+ * will contain the dump.
+ */
+int ql_core_dump(struct ql_adapter *qdev, struct ql_mpi_coredump *mpi_coredump)
+{
+	int status;
+	int i;
+
+	if (!mpi_coredump) {
+		netif_err(qdev, drv, qdev->ndev, "No memory available.\n");
+		return -ENOMEM;
+	}
+
+	/* Try to get the spinlock, but dont worry if
+	 * it isn't available.  If the firmware died it
+	 * might be holding the sem.
+	 */
+	ql_sem_spinlock(qdev, SEM_PROC_REG_MASK);
+
+	status = ql_pause_mpi_risc(qdev);
+	if (status) {
+		netif_err(qdev, drv, qdev->ndev,
+			  "Failed RISC pause. Status = 0x%.08x\n", status);
+		goto err;
+	}
+
+	/* Insert the global header */
+	memset(&(mpi_coredump->mpi_global_header), 0,
+		sizeof(struct mpi_coredump_global_header));
+	mpi_coredump->mpi_global_header.cookie = MPI_COREDUMP_COOKIE;
+	mpi_coredump->mpi_global_header.headerSize =
+		sizeof(struct mpi_coredump_global_header);
+	mpi_coredump->mpi_global_header.imageSize =
+		sizeof(struct ql_mpi_coredump);
+	memcpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump",
+		sizeof(mpi_coredump->mpi_global_header.idString));
+
+	/* Get generic NIC reg dump */
+	ql_build_coredump_seg_header(&mpi_coredump->nic_regs_seg_hdr,
+			NIC1_CONTROL_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->nic_regs), "NIC1 Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->nic2_regs_seg_hdr,
+			NIC2_CONTROL_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->nic2_regs), "NIC2 Registers");
+
+	/* Get XGMac registers. (Segment 18, Rev C. step 21) */
+	ql_build_coredump_seg_header(&mpi_coredump->xgmac1_seg_hdr,
+			NIC1_XGMAC_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->xgmac1), "NIC1 XGMac Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->xgmac2_seg_hdr,
+			NIC2_XGMAC_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->xgmac2), "NIC2 XGMac Registers");
+
+	if (qdev->func & 1) {
+		/* Odd means our function is NIC 2 */
+		for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++)
+			mpi_coredump->nic2_regs[i] =
+					 ql_read32(qdev, i * sizeof(u32));
+
+		for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++)
+			mpi_coredump->nic_regs[i] =
+			ql_read_other_func_reg(qdev, (i * sizeof(u32)) / 4);
+
+		ql_get_xgmac_regs(qdev, &mpi_coredump->xgmac2[0], 0);
+		ql_get_xgmac_regs(qdev, &mpi_coredump->xgmac1[0], 1);
+	} else {
+		/* Even means our function is NIC 1 */
+		for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++)
+			mpi_coredump->nic_regs[i] =
+					ql_read32(qdev, i * sizeof(u32));
+		for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++)
+			mpi_coredump->nic2_regs[i] =
+			ql_read_other_func_reg(qdev, (i * sizeof(u32)) / 4);
+
+		ql_get_xgmac_regs(qdev, &mpi_coredump->xgmac1[0], 0);
+		ql_get_xgmac_regs(qdev, &mpi_coredump->xgmac2[0], 1);
+	}
+
+	/* Rev C. Step 20a */
+	ql_build_coredump_seg_header(&mpi_coredump->xaui_an_hdr,
+			XAUI_AN_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes_xaui_an),
+			"XAUI AN Registers");
+
+	/* Rev C. Step 20b */
+	ql_build_coredump_seg_header(&mpi_coredump->xaui_hss_pcs_hdr,
+			XAUI_HSS_PCS_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes_xaui_hss_pcs),
+			"XAUI HSS PCS Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->xfi_an_hdr, XFI_AN_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes_xfi_an),
+			"XFI AN Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->xfi_train_hdr,
+			XFI_TRAIN_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes_xfi_train),
+			"XFI TRAIN Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->xfi_hss_pcs_hdr,
+			XFI_HSS_PCS_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes_xfi_hss_pcs),
+			"XFI HSS PCS Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->xfi_hss_tx_hdr,
+			XFI_HSS_TX_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes_xfi_hss_tx),
+			"XFI HSS TX Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->xfi_hss_rx_hdr,
+			XFI_HSS_RX_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes_xfi_hss_rx),
+			"XFI HSS RX Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->xfi_hss_pll_hdr,
+			XFI_HSS_PLL_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes_xfi_hss_pll),
+			"XFI HSS PLL Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->xaui2_an_hdr,
+			XAUI2_AN_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes2_xaui_an),
+			"XAUI2 AN Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->xaui2_hss_pcs_hdr,
+			XAUI2_HSS_PCS_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes2_xaui_hss_pcs),
+			"XAUI2 HSS PCS Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->xfi2_an_hdr,
+			XFI2_AN_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes2_xfi_an),
+			"XFI2 AN Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->xfi2_train_hdr,
+			XFI2_TRAIN_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes2_xfi_train),
+			"XFI2 TRAIN Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->xfi2_hss_pcs_hdr,
+			XFI2_HSS_PCS_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes2_xfi_hss_pcs),
+			"XFI2 HSS PCS Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->xfi2_hss_tx_hdr,
+			XFI2_HSS_TX_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes2_xfi_hss_tx),
+			"XFI2 HSS TX Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->xfi2_hss_rx_hdr,
+			XFI2_HSS_RX_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes2_xfi_hss_rx),
+			"XFI2 HSS RX Registers");
+
+	ql_build_coredump_seg_header(&mpi_coredump->xfi2_hss_pll_hdr,
+			XFI2_HSS_PLL_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->serdes2_xfi_hss_pll),
+			"XFI2 HSS PLL Registers");
+
+	status = ql_get_serdes_regs(qdev, mpi_coredump);
+	if (status) {
+		netif_err(qdev, drv, qdev->ndev,
+			  "Failed Dump of Serdes Registers. Status = 0x%.08x\n",
+			  status);
+		goto err;
+	}
+
+	ql_build_coredump_seg_header(&mpi_coredump->core_regs_seg_hdr,
+				CORE_SEG_NUM,
+				sizeof(mpi_coredump->core_regs_seg_hdr) +
+				sizeof(mpi_coredump->mpi_core_regs) +
+				sizeof(mpi_coredump->mpi_core_sh_regs),
+				"Core Registers");
+
+	/* Get the MPI Core Registers */
+	status = ql_get_mpi_regs(qdev, &mpi_coredump->mpi_core_regs[0],
+				 MPI_CORE_REGS_ADDR, MPI_CORE_REGS_CNT);
+	if (status)
+		goto err;
+	/* Get the 16 MPI shadow registers */
+	status = ql_get_mpi_shadow_regs(qdev,
+					&mpi_coredump->mpi_core_sh_regs[0]);
+	if (status)
+		goto err;
+
+	/* Get the Test Logic Registers */
+	ql_build_coredump_seg_header(&mpi_coredump->test_logic_regs_seg_hdr,
+				TEST_LOGIC_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->test_logic_regs),
+				"Test Logic Regs");
+	status = ql_get_mpi_regs(qdev, &mpi_coredump->test_logic_regs[0],
+				 TEST_REGS_ADDR, TEST_REGS_CNT);
+	if (status)
+		goto err;
+
+	/* Get the RMII Registers */
+	ql_build_coredump_seg_header(&mpi_coredump->rmii_regs_seg_hdr,
+				RMII_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->rmii_regs),
+				"RMII Registers");
+	status = ql_get_mpi_regs(qdev, &mpi_coredump->rmii_regs[0],
+				 RMII_REGS_ADDR, RMII_REGS_CNT);
+	if (status)
+		goto err;
+
+	/* Get the FCMAC1 Registers */
+	ql_build_coredump_seg_header(&mpi_coredump->fcmac1_regs_seg_hdr,
+				FCMAC1_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->fcmac1_regs),
+				"FCMAC1 Registers");
+	status = ql_get_mpi_regs(qdev, &mpi_coredump->fcmac1_regs[0],
+				 FCMAC1_REGS_ADDR, FCMAC_REGS_CNT);
+	if (status)
+		goto err;
+
+	/* Get the FCMAC2 Registers */
+
+	ql_build_coredump_seg_header(&mpi_coredump->fcmac2_regs_seg_hdr,
+				FCMAC2_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->fcmac2_regs),
+				"FCMAC2 Registers");
+
+	status = ql_get_mpi_regs(qdev, &mpi_coredump->fcmac2_regs[0],
+				 FCMAC2_REGS_ADDR, FCMAC_REGS_CNT);
+	if (status)
+		goto err;
+
+	/* Get the FC1 MBX Registers */
+	ql_build_coredump_seg_header(&mpi_coredump->fc1_mbx_regs_seg_hdr,
+				FC1_MBOX_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->fc1_mbx_regs),
+				"FC1 MBox Regs");
+	status = ql_get_mpi_regs(qdev, &mpi_coredump->fc1_mbx_regs[0],
+				 FC1_MBX_REGS_ADDR, FC_MBX_REGS_CNT);
+	if (status)
+		goto err;
+
+	/* Get the IDE Registers */
+	ql_build_coredump_seg_header(&mpi_coredump->ide_regs_seg_hdr,
+				IDE_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->ide_regs),
+				"IDE Registers");
+	status = ql_get_mpi_regs(qdev, &mpi_coredump->ide_regs[0],
+				 IDE_REGS_ADDR, IDE_REGS_CNT);
+	if (status)
+		goto err;
+
+	/* Get the NIC1 MBX Registers */
+	ql_build_coredump_seg_header(&mpi_coredump->nic1_mbx_regs_seg_hdr,
+				NIC1_MBOX_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->nic1_mbx_regs),
+				"NIC1 MBox Regs");
+	status = ql_get_mpi_regs(qdev, &mpi_coredump->nic1_mbx_regs[0],
+				 NIC1_MBX_REGS_ADDR, NIC_MBX_REGS_CNT);
+	if (status)
+		goto err;
+
+	/* Get the SMBus Registers */
+	ql_build_coredump_seg_header(&mpi_coredump->smbus_regs_seg_hdr,
+				SMBUS_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->smbus_regs),
+				"SMBus Registers");
+	status = ql_get_mpi_regs(qdev, &mpi_coredump->smbus_regs[0],
+				 SMBUS_REGS_ADDR, SMBUS_REGS_CNT);
+	if (status)
+		goto err;
+
+	/* Get the FC2 MBX Registers */
+	ql_build_coredump_seg_header(&mpi_coredump->fc2_mbx_regs_seg_hdr,
+				FC2_MBOX_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->fc2_mbx_regs),
+				"FC2 MBox Regs");
+	status = ql_get_mpi_regs(qdev, &mpi_coredump->fc2_mbx_regs[0],
+				 FC2_MBX_REGS_ADDR, FC_MBX_REGS_CNT);
+	if (status)
+		goto err;
+
+	/* Get the NIC2 MBX Registers */
+	ql_build_coredump_seg_header(&mpi_coredump->nic2_mbx_regs_seg_hdr,
+				NIC2_MBOX_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->nic2_mbx_regs),
+				"NIC2 MBox Regs");
+	status = ql_get_mpi_regs(qdev, &mpi_coredump->nic2_mbx_regs[0],
+				 NIC2_MBX_REGS_ADDR, NIC_MBX_REGS_CNT);
+	if (status)
+		goto err;
+
+	/* Get the I2C Registers */
+	ql_build_coredump_seg_header(&mpi_coredump->i2c_regs_seg_hdr,
+				I2C_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->i2c_regs),
+				"I2C Registers");
+	status = ql_get_mpi_regs(qdev, &mpi_coredump->i2c_regs[0],
+				 I2C_REGS_ADDR, I2C_REGS_CNT);
+	if (status)
+		goto err;
+
+	/* Get the MEMC Registers */
+	ql_build_coredump_seg_header(&mpi_coredump->memc_regs_seg_hdr,
+				MEMC_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->memc_regs),
+				"MEMC Registers");
+	status = ql_get_mpi_regs(qdev, &mpi_coredump->memc_regs[0],
+				 MEMC_REGS_ADDR, MEMC_REGS_CNT);
+	if (status)
+		goto err;
+
+	/* Get the PBus Registers */
+	ql_build_coredump_seg_header(&mpi_coredump->pbus_regs_seg_hdr,
+				PBUS_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->pbus_regs),
+				"PBUS Registers");
+	status = ql_get_mpi_regs(qdev, &mpi_coredump->pbus_regs[0],
+				 PBUS_REGS_ADDR, PBUS_REGS_CNT);
+	if (status)
+		goto err;
+
+	/* Get the MDE Registers */
+	ql_build_coredump_seg_header(&mpi_coredump->mde_regs_seg_hdr,
+				MDE_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->mde_regs),
+				"MDE Registers");
+	status = ql_get_mpi_regs(qdev, &mpi_coredump->mde_regs[0],
+				 MDE_REGS_ADDR, MDE_REGS_CNT);
+	if (status)
+		goto err;
+
+	ql_build_coredump_seg_header(&mpi_coredump->misc_nic_seg_hdr,
+				MISC_NIC_INFO_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->misc_nic_info),
+				"MISC NIC INFO");
+	mpi_coredump->misc_nic_info.rx_ring_count = qdev->rx_ring_count;
+	mpi_coredump->misc_nic_info.tx_ring_count = qdev->tx_ring_count;
+	mpi_coredump->misc_nic_info.intr_count = qdev->intr_count;
+	mpi_coredump->misc_nic_info.function = qdev->func;
+
+	/* Segment 31 */
+	/* Get indexed register values. */
+	ql_build_coredump_seg_header(&mpi_coredump->intr_states_seg_hdr,
+				INTR_STATES_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->intr_states),
+				"INTR States");
+	ql_get_intr_states(qdev, &mpi_coredump->intr_states[0]);
+
+	ql_build_coredump_seg_header(&mpi_coredump->cam_entries_seg_hdr,
+				CAM_ENTRIES_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->cam_entries),
+				"CAM Entries");
+	status = ql_get_cam_entries(qdev, &mpi_coredump->cam_entries[0]);
+	if (status)
+		goto err;
+
+	ql_build_coredump_seg_header(&mpi_coredump->nic_routing_words_seg_hdr,
+				ROUTING_WORDS_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->nic_routing_words),
+				"Routing Words");
+	status = ql_get_routing_entries(qdev,
+			 &mpi_coredump->nic_routing_words[0]);
+	if (status)
+		goto err;
+
+	/* Segment 34 (Rev C. step 23) */
+	ql_build_coredump_seg_header(&mpi_coredump->ets_seg_hdr,
+				ETS_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->ets),
+				"ETS Registers");
+	status = ql_get_ets_regs(qdev, &mpi_coredump->ets[0]);
+	if (status)
+		goto err;
+
+	ql_build_coredump_seg_header(&mpi_coredump->probe_dump_seg_hdr,
+				PROBE_DUMP_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->probe_dump),
+				"Probe Dump");
+	ql_get_probe_dump(qdev, &mpi_coredump->probe_dump[0]);
+
+	ql_build_coredump_seg_header(&mpi_coredump->routing_reg_seg_hdr,
+				ROUTING_INDEX_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->routing_regs),
+				"Routing Regs");
+	status = ql_get_routing_index_registers(qdev,
+					&mpi_coredump->routing_regs[0]);
+	if (status)
+		goto err;
+
+	ql_build_coredump_seg_header(&mpi_coredump->mac_prot_reg_seg_hdr,
+				MAC_PROTOCOL_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->mac_prot_regs),
+				"MAC Prot Regs");
+	ql_get_mac_protocol_registers(qdev, &mpi_coredump->mac_prot_regs[0]);
+
+	/* Get the semaphore registers for all 5 functions */
+	ql_build_coredump_seg_header(&mpi_coredump->sem_regs_seg_hdr,
+			SEM_REGS_SEG_NUM,
+			sizeof(struct mpi_coredump_segment_header) +
+			sizeof(mpi_coredump->sem_regs),	"Sem Registers");
+
+	ql_get_sem_registers(qdev, &mpi_coredump->sem_regs[0]);
+
+	/* Prevent the mpi restarting while we dump the memory.*/
+	ql_write_mpi_reg(qdev, MPI_TEST_FUNC_RST_STS, MPI_TEST_FUNC_RST_FRC);
+
+	/* clear the pause */
+	status = ql_unpause_mpi_risc(qdev);
+	if (status) {
+		netif_err(qdev, drv, qdev->ndev,
+			  "Failed RISC unpause. Status = 0x%.08x\n", status);
+		goto err;
+	}
+
+	/* Reset the RISC so we can dump RAM */
+	status = ql_hard_reset_mpi_risc(qdev);
+	if (status) {
+		netif_err(qdev, drv, qdev->ndev,
+			  "Failed RISC reset. Status = 0x%.08x\n", status);
+		goto err;
+	}
+
+	ql_build_coredump_seg_header(&mpi_coredump->code_ram_seg_hdr,
+				WCS_RAM_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->code_ram),
+				"WCS RAM");
+	status = ql_dump_risc_ram_area(qdev, &mpi_coredump->code_ram[0],
+					CODE_RAM_ADDR, CODE_RAM_CNT);
+	if (status) {
+		netif_err(qdev, drv, qdev->ndev,
+			  "Failed Dump of CODE RAM. Status = 0x%.08x\n",
+			  status);
+		goto err;
+	}
+
+	/* Insert the segment header */
+	ql_build_coredump_seg_header(&mpi_coredump->memc_ram_seg_hdr,
+				MEMC_RAM_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->memc_ram),
+				"MEMC RAM");
+	status = ql_dump_risc_ram_area(qdev, &mpi_coredump->memc_ram[0],
+					MEMC_RAM_ADDR, MEMC_RAM_CNT);
+	if (status) {
+		netif_err(qdev, drv, qdev->ndev,
+			  "Failed Dump of MEMC RAM. Status = 0x%.08x\n",
+			  status);
+		goto err;
+	}
+err:
+	ql_sem_unlock(qdev, SEM_PROC_REG_MASK); /* does flush too */
+	return status;
+
+}
+
+static void ql_get_core_dump(struct ql_adapter *qdev)
+{
+	if (!ql_own_firmware(qdev)) {
+		netif_err(qdev, drv, qdev->ndev, "Don't own firmware!\n");
+		return;
+	}
+
+	if (!netif_running(qdev->ndev)) {
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Force Coredump can only be done from interface that is up.\n");
+		return;
+	}
+
+	if (ql_mb_sys_err(qdev)) {
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Fail force coredump with ql_mb_sys_err().\n");
+		return;
+	}
+}
+
 void ql_gen_reg_dump(struct ql_adapter *qdev,
 			struct ql_reg_dump *mpi_coredump)
 {
@@ -178,6 +1320,37 @@ void ql_gen_reg_dump(struct ql_adapter *
 	status = ql_get_ets_regs(qdev, &mpi_coredump->ets[0]);
 	if (status)
 		return;
+
+	if (test_bit(QL_FRC_COREDUMP, &qdev->flags))
+		ql_get_core_dump(qdev);
+}
+
+/* Coredump to messages log file using separate worker thread */
+void ql_mpi_core_to_log(struct work_struct *work)
+{
+	struct ql_adapter *qdev =
+		container_of(work, struct ql_adapter, mpi_core_to_log.work);
+	u32 *tmp, count;
+	int i;
+
+	count = sizeof(struct ql_mpi_coredump) / sizeof(u32);
+	tmp = (u32 *)qdev->mpi_coredump;
+	netif_printk(qdev, drv, KERN_DEBUG, qdev->ndev,
+		     "Core is dumping to log file!\n");
+
+	for (i = 0; i < count; i += 8) {
+		printk(KERN_ERR "%.08x: %.08x %.08x %.08x %.08x %.08x "
+			"%.08x %.08x %.08x \n", i,
+			tmp[i + 0],
+			tmp[i + 1],
+			tmp[i + 2],
+			tmp[i + 3],
+			tmp[i + 4],
+			tmp[i + 5],
+			tmp[i + 6],
+			tmp[i + 7]);
+		msleep(5);
+	}
 }
 
 #ifdef QL_REG_DUMP
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_ethtool.c linux-libre-2.6.34-gnu1/drivers/net/qlge/qlge_ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/qlge/qlge_ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/pagemap.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/dmapool.h>
 #include <linux/mempool.h>
 #include <linux/spinlock.h>
@@ -67,8 +66,8 @@ static int ql_update_ring_coalescing(str
 			status = ql_write_cfg(qdev, cqicb, sizeof(*cqicb),
 						CFG_LCQ, rx_ring->cq_id);
 			if (status) {
-				QPRINTK(qdev, IFUP, ERR,
-					"Failed to load CQICB.\n");
+				netif_err(qdev, ifup, qdev->ndev,
+					  "Failed to load CQICB.\n");
 				goto exit;
 			}
 		}
@@ -89,8 +88,8 @@ static int ql_update_ring_coalescing(str
 			status = ql_write_cfg(qdev, cqicb, sizeof(*cqicb),
 						CFG_LCQ, rx_ring->cq_id);
 			if (status) {
-				QPRINTK(qdev, IFUP, ERR,
-					"Failed to load CQICB.\n");
+				netif_err(qdev, ifup, qdev->ndev,
+					  "Failed to load CQICB.\n");
 				goto exit;
 			}
 		}
@@ -107,8 +106,8 @@ static void ql_update_stats(struct ql_ad
 
 	spin_lock(&qdev->stats_lock);
 	if (ql_sem_spinlock(qdev, qdev->xg_sem_mask)) {
-			QPRINTK(qdev, DRV, ERR,
-				"Couldn't get xgmac sem.\n");
+			netif_err(qdev, drv, qdev->ndev,
+				  "Couldn't get xgmac sem.\n");
 		goto quit;
 	}
 	/*
@@ -116,8 +115,9 @@ static void ql_update_stats(struct ql_ad
 	 */
 	for (i = 0x200; i < 0x280; i += 8) {
 		if (ql_read_xgmac_reg64(qdev, i, &data)) {
-			QPRINTK(qdev, DRV, ERR,
-				"Error reading status register 0x%.04x.\n", i);
+			netif_err(qdev, drv, qdev->ndev,
+				  "Error reading status register 0x%.04x.\n",
+				  i);
 			goto end;
 		} else
 			*iter = data;
@@ -129,8 +129,9 @@ static void ql_update_stats(struct ql_ad
 	 */
 	for (i = 0x300; i < 0x3d0; i += 8) {
 		if (ql_read_xgmac_reg64(qdev, i, &data)) {
-			QPRINTK(qdev, DRV, ERR,
-				"Error reading status register 0x%.04x.\n", i);
+			netif_err(qdev, drv, qdev->ndev,
+				  "Error reading status register 0x%.04x.\n",
+				  i);
 			goto end;
 		} else
 			*iter = data;
@@ -142,8 +143,9 @@ static void ql_update_stats(struct ql_ad
 	 */
 	for (i = 0x500; i < 0x540; i += 8) {
 		if (ql_read_xgmac_reg64(qdev, i, &data)) {
-			QPRINTK(qdev, DRV, ERR,
-				"Error reading status register 0x%.04x.\n", i);
+			netif_err(qdev, drv, qdev->ndev,
+				  "Error reading status register 0x%.04x.\n",
+				  i);
 			goto end;
 		} else
 			*iter = data;
@@ -155,8 +157,9 @@ static void ql_update_stats(struct ql_ad
 	 */
 	for (i = 0x568; i < 0x5a8; i += 8) {
 		if (ql_read_xgmac_reg64(qdev, i, &data)) {
-			QPRINTK(qdev, DRV, ERR,
-				"Error reading status register 0x%.04x.\n", i);
+			netif_err(qdev, drv, qdev->ndev,
+				  "Error reading status register 0x%.04x.\n",
+				  i);
 			goto end;
 		} else
 			*iter = data;
@@ -167,8 +170,8 @@ static void ql_update_stats(struct ql_ad
 	 * Get RX NIC FIFO DROP statistics.
 	 */
 	if (ql_read_xgmac_reg64(qdev, 0x5b8, &data)) {
-		QPRINTK(qdev, DRV, ERR,
-			"Error reading status register 0x%.04x.\n", i);
+		netif_err(qdev, drv, qdev->ndev,
+			  "Error reading status register 0x%.04x.\n", i);
 		goto end;
 	} else
 		*iter = data;
@@ -396,14 +399,13 @@ static int ql_set_wol(struct net_device
 		return -EINVAL;
 	qdev->wol = wol->wolopts;
 
-	QPRINTK(qdev, DRV, INFO, "Set wol option 0x%x on %s\n",
-			 qdev->wol, ndev->name);
+	netif_info(qdev, drv, qdev->ndev, "Set wol option 0x%x\n", qdev->wol);
 	if (!qdev->wol) {
 		u32 wol = 0;
 		status = ql_mb_wol_mode(qdev, wol);
-		QPRINTK(qdev, DRV, ERR, "WOL %s (wol code 0x%x) on %s\n",
-			(status == 0) ? "cleared sucessfully" : "clear failed",
-			wol, qdev->ndev->name);
+		netif_err(qdev, drv, qdev->ndev, "WOL %s (wol code 0x%x)\n",
+			  status == 0 ? "cleared successfully" : "clear failed",
+			  wol);
 	}
 
 	return 0;
@@ -500,7 +502,8 @@ static int ql_run_loopback_test(struct q
 			return -EPIPE;
 		atomic_inc(&qdev->lb_count);
 	}
-
+	/* Give queue time to settle before testing results. */
+	msleep(2);
 	ql_clean_lb_rx_ring(&qdev->rx_ring[0], 128);
 	return atomic_read(&qdev->lb_count) ? -EIO : 0;
 }
@@ -533,9 +536,13 @@ static void ql_self_test(struct net_devi
 			data[0] = 0;
 		}
 		clear_bit(QL_SELFTEST, &qdev->flags);
+		/* Give link time to come up after
+		 * port configuration changes.
+		 */
+		msleep_interruptible(4 * 1000);
 	} else {
-		QPRINTK(qdev, DRV, ERR,
-			"%s: is down, Loopback test will fail.\n", ndev->name);
+		netif_err(qdev, drv, qdev->ndev,
+			  "is down, Loopback test will fail.\n");
 		eth_test->flags |= ETH_TEST_FL_FAILED;
 	}
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge.h linux-libre-2.6.34-gnu1/drivers/net/qlge/qlge.h
--- linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/qlge/qlge.h	2010-05-16 17:17:36.000000000 -0400
@@ -19,14 +19,6 @@
 #define DRV_VERSION	"v1.00.00.23.00.00-01"
 
 #define PFX "qlge: "
-#define QPRINTK(qdev, nlevel, klevel, fmt, args...)     \
-       do {       \
-	if (!((qdev)->msg_enable & NETIF_MSG_##nlevel))		\
-		;						\
-	else							\
-		dev_printk(KERN_##klevel, &((qdev)->pdev->dev),	\
-			   "%s: " fmt, __func__, ##args);  \
-       } while (0)
 
 #define WQ_ADDR_ALIGN	0x3	/* 4 byte alignment */
 
@@ -54,12 +46,8 @@
 #define RX_RING_SHADOW_SPACE	(sizeof(u64) + \
 		MAX_DB_PAGES_PER_BQ(NUM_SMALL_BUFFERS) * sizeof(u64) + \
 		MAX_DB_PAGES_PER_BQ(NUM_LARGE_BUFFERS) * sizeof(u64))
-#define SMALL_BUFFER_SIZE 512
-#define SMALL_BUF_MAP_SIZE (SMALL_BUFFER_SIZE / 2)
 #define LARGE_BUFFER_MAX_SIZE 8192
 #define LARGE_BUFFER_MIN_SIZE 2048
-#define MAX_SPLIT_SIZE 1023
-#define QLGE_SB_PAD 32
 
 #define MAX_CQ 128
 #define DFLT_COALESCE_WAIT 100	/* 100 usec wait for coalescing */
@@ -79,15 +67,43 @@
 #define TX_DESC_PER_OAL 0
 #endif
 
+/* Word shifting for converting 64-bit
+ * address to a series of 16-bit words.
+ * This is used for some MPI firmware
+ * mailbox commands.
+ */
+#define LSW(x)  ((u16)(x))
+#define MSW(x)  ((u16)((u32)(x) >> 16))
+#define LSD(x)  ((u32)((u64)(x)))
+#define MSD(x)  ((u32)((((u64)(x)) >> 32)))
+
 /* MPI test register definitions. This register
  * is used for determining alternate NIC function's
  * PCI->func number.
  */
 enum {
 	MPI_TEST_FUNC_PORT_CFG = 0x1002,
+	MPI_TEST_FUNC_PRB_CTL = 0x100e,
+		MPI_TEST_FUNC_PRB_EN = 0x18a20000,
+	MPI_TEST_FUNC_RST_STS = 0x100a,
+		MPI_TEST_FUNC_RST_FRC = 0x00000003,
+	MPI_TEST_NIC_FUNC_MASK = 0x00000007,
+	MPI_TEST_NIC1_FUNCTION_ENABLE = (1 << 0),
+	MPI_TEST_NIC1_FUNCTION_MASK = 0x0000000e,
 	MPI_TEST_NIC1_FUNC_SHIFT = 1,
+	MPI_TEST_NIC2_FUNCTION_ENABLE = (1 << 4),
+	MPI_TEST_NIC2_FUNCTION_MASK = 0x000000e0,
 	MPI_TEST_NIC2_FUNC_SHIFT = 5,
-	MPI_TEST_NIC_FUNC_MASK = 0x00000007,
+	MPI_TEST_FC1_FUNCTION_ENABLE = (1 << 8),
+	MPI_TEST_FC1_FUNCTION_MASK	= 0x00000e00,
+	MPI_TEST_FC1_FUNCTION_SHIFT = 9,
+	MPI_TEST_FC2_FUNCTION_ENABLE = (1 << 12),
+	MPI_TEST_FC2_FUNCTION_MASK = 0x0000e000,
+	MPI_TEST_FC2_FUNCTION_SHIFT = 13,
+
+	MPI_NIC_READ = 0x00000000,
+	MPI_NIC_REG_BLOCK = 0x00020000,
+	MPI_NIC_FUNCTION_SHIFT = 6,
 };
 
 /*
@@ -468,7 +484,7 @@ enum {
 	MDIO_PORT = 0x00000440,
 	MDIO_STATUS = 0x00000450,
 
-	/* XGMAC AUX statistics  registers */
+	XGMAC_REGISTER_END = 0x00000740,
 };
 
 /*
@@ -509,6 +525,7 @@ enum {
 enum {
 	MAC_ADDR_IDX_SHIFT = 4,
 	MAC_ADDR_TYPE_SHIFT = 16,
+	MAC_ADDR_TYPE_COUNT = 10,
 	MAC_ADDR_TYPE_MASK = 0x000f0000,
 	MAC_ADDR_TYPE_CAM_MAC = 0x00000000,
 	MAC_ADDR_TYPE_MULTI_MAC = 0x00010000,
@@ -526,6 +543,30 @@ enum {
 	MAC_ADDR_MR = (1 << 30),
 	MAC_ADDR_MW = (1 << 31),
 	MAX_MULTICAST_ENTRIES = 32,
+
+	/* Entry count and words per entry
+	 * for each address type in the filter.
+	 */
+	MAC_ADDR_MAX_CAM_ENTRIES = 512,
+	MAC_ADDR_MAX_CAM_WCOUNT = 3,
+	MAC_ADDR_MAX_MULTICAST_ENTRIES = 32,
+	MAC_ADDR_MAX_MULTICAST_WCOUNT = 2,
+	MAC_ADDR_MAX_VLAN_ENTRIES = 4096,
+	MAC_ADDR_MAX_VLAN_WCOUNT = 1,
+	MAC_ADDR_MAX_MCAST_FLTR_ENTRIES = 4096,
+	MAC_ADDR_MAX_MCAST_FLTR_WCOUNT = 1,
+	MAC_ADDR_MAX_FC_MAC_ENTRIES = 4,
+	MAC_ADDR_MAX_FC_MAC_WCOUNT = 2,
+	MAC_ADDR_MAX_MGMT_MAC_ENTRIES = 8,
+	MAC_ADDR_MAX_MGMT_MAC_WCOUNT = 2,
+	MAC_ADDR_MAX_MGMT_VLAN_ENTRIES = 16,
+	MAC_ADDR_MAX_MGMT_VLAN_WCOUNT = 1,
+	MAC_ADDR_MAX_MGMT_V4_ENTRIES = 4,
+	MAC_ADDR_MAX_MGMT_V4_WCOUNT = 1,
+	MAC_ADDR_MAX_MGMT_V6_ENTRIES = 4,
+	MAC_ADDR_MAX_MGMT_V6_WCOUNT = 4,
+	MAC_ADDR_MAX_MGMT_TU_DP_ENTRIES = 4,
+	MAC_ADDR_MAX_MGMT_TU_DP_WCOUNT = 1,
 };
 
 /*
@@ -596,6 +637,7 @@ enum {
 enum {
 	RT_IDX_IDX_SHIFT = 8,
 	RT_IDX_TYPE_MASK = 0x000f0000,
+	RT_IDX_TYPE_SHIFT = 16,
 	RT_IDX_TYPE_RT = 0x00000000,
 	RT_IDX_TYPE_RT_INV = 0x00010000,
 	RT_IDX_TYPE_NICQ = 0x00020000,
@@ -664,7 +706,89 @@ enum {
 	RT_IDX_UNUSED013 = 13,
 	RT_IDX_UNUSED014 = 14,
 	RT_IDX_PROMISCUOUS_SLOT = 15,
-	RT_IDX_MAX_SLOTS = 16,
+	RT_IDX_MAX_RT_SLOTS = 8,
+	RT_IDX_MAX_NIC_SLOTS = 16,
+};
+
+/*
+ * Serdes Address Register (XG_SERDES_ADDR) bit definitions.
+ */
+enum {
+	XG_SERDES_ADDR_RDY = (1 << 31),
+	XG_SERDES_ADDR_R = (1 << 30),
+
+	XG_SERDES_ADDR_STS = 0x00001E06,
+	XG_SERDES_ADDR_XFI1_PWR_UP = 0x00000005,
+	XG_SERDES_ADDR_XFI2_PWR_UP = 0x0000000a,
+	XG_SERDES_ADDR_XAUI_PWR_DOWN = 0x00000001,
+
+	/* Serdes coredump definitions. */
+	XG_SERDES_XAUI_AN_START = 0x00000000,
+	XG_SERDES_XAUI_AN_END = 0x00000034,
+	XG_SERDES_XAUI_HSS_PCS_START = 0x00000800,
+	XG_SERDES_XAUI_HSS_PCS_END = 0x0000880,
+	XG_SERDES_XFI_AN_START = 0x00001000,
+	XG_SERDES_XFI_AN_END = 0x00001034,
+	XG_SERDES_XFI_TRAIN_START = 0x10001050,
+	XG_SERDES_XFI_TRAIN_END = 0x1000107C,
+	XG_SERDES_XFI_HSS_PCS_START = 0x00001800,
+	XG_SERDES_XFI_HSS_PCS_END = 0x00001838,
+	XG_SERDES_XFI_HSS_TX_START = 0x00001c00,
+	XG_SERDES_XFI_HSS_TX_END = 0x00001c1f,
+	XG_SERDES_XFI_HSS_RX_START = 0x00001c40,
+	XG_SERDES_XFI_HSS_RX_END = 0x00001c5f,
+	XG_SERDES_XFI_HSS_PLL_START = 0x00001e00,
+	XG_SERDES_XFI_HSS_PLL_END = 0x00001e1f,
+};
+
+/*
+ *  NIC Probe Mux Address Register (PRB_MX_ADDR) bit definitions.
+ */
+enum {
+	PRB_MX_ADDR_ARE = (1 << 16),
+	PRB_MX_ADDR_UP = (1 << 15),
+	PRB_MX_ADDR_SWP = (1 << 14),
+
+	/* Module select values. */
+	PRB_MX_ADDR_MAX_MODS = 21,
+	PRB_MX_ADDR_MOD_SEL_SHIFT = 9,
+	PRB_MX_ADDR_MOD_SEL_TBD = 0,
+	PRB_MX_ADDR_MOD_SEL_IDE1 = 1,
+	PRB_MX_ADDR_MOD_SEL_IDE2 = 2,
+	PRB_MX_ADDR_MOD_SEL_FRB = 3,
+	PRB_MX_ADDR_MOD_SEL_ODE1 = 4,
+	PRB_MX_ADDR_MOD_SEL_ODE2 = 5,
+	PRB_MX_ADDR_MOD_SEL_DA1 = 6,
+	PRB_MX_ADDR_MOD_SEL_DA2 = 7,
+	PRB_MX_ADDR_MOD_SEL_IMP1 = 8,
+	PRB_MX_ADDR_MOD_SEL_IMP2 = 9,
+	PRB_MX_ADDR_MOD_SEL_OMP1 = 10,
+	PRB_MX_ADDR_MOD_SEL_OMP2 = 11,
+	PRB_MX_ADDR_MOD_SEL_ORS1 = 12,
+	PRB_MX_ADDR_MOD_SEL_ORS2 = 13,
+	PRB_MX_ADDR_MOD_SEL_REG = 14,
+	PRB_MX_ADDR_MOD_SEL_MAC1 = 16,
+	PRB_MX_ADDR_MOD_SEL_MAC2 = 17,
+	PRB_MX_ADDR_MOD_SEL_VQM1 = 18,
+	PRB_MX_ADDR_MOD_SEL_VQM2 = 19,
+	PRB_MX_ADDR_MOD_SEL_MOP = 20,
+	/* Bit fields indicating which modules
+	 * are valid for each clock domain.
+	 */
+	PRB_MX_ADDR_VALID_SYS_MOD = 0x000f7ff7,
+	PRB_MX_ADDR_VALID_PCI_MOD = 0x000040c1,
+	PRB_MX_ADDR_VALID_XGM_MOD = 0x00037309,
+	PRB_MX_ADDR_VALID_FC_MOD = 0x00003001,
+	PRB_MX_ADDR_VALID_TOTAL = 34,
+
+	/* Clock domain values. */
+	PRB_MX_ADDR_CLOCK_SHIFT = 6,
+	PRB_MX_ADDR_SYS_CLOCK = 0,
+	PRB_MX_ADDR_PCI_CLOCK = 2,
+	PRB_MX_ADDR_FC_CLOCK = 5,
+	PRB_MX_ADDR_XGM_CLOCK = 6,
+
+	PRB_MX_ADDR_MAX_MUX = 64,
 };
 
 /*
@@ -737,6 +861,21 @@ enum {
 	PRB_MX_DATA = 0xfc,	/* Use semaphore */
 };
 
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+#define SMALL_BUFFER_SIZE 256
+#define SMALL_BUF_MAP_SIZE SMALL_BUFFER_SIZE
+#define SPLT_SETTING  FSC_DBRST_1024
+#define SPLT_LEN 0
+#define QLGE_SB_PAD 0
+#else
+#define SMALL_BUFFER_SIZE 512
+#define SMALL_BUF_MAP_SIZE (SMALL_BUFFER_SIZE / 2)
+#define SPLT_SETTING  FSC_SH
+#define SPLT_LEN (SPLT_HDR_EP | \
+	min(SMALL_BUF_MAP_SIZE, 1023))
+#define QLGE_SB_PAD 32
+#endif
+
 /*
  * CAM output format.
  */
@@ -1421,7 +1560,7 @@ struct nic_stats {
 	u64 rx_nic_fifo_drop;
 };
 
-/* Address/Length pairs for the coredump. */
+/* Firmware coredump internal register address/length pairs. */
 enum {
 	MPI_CORE_REGS_ADDR = 0x00030000,
 	MPI_CORE_REGS_CNT = 127,
@@ -1476,7 +1615,7 @@ struct mpi_coredump_segment_header {
 	u8	description[16];
 };
 
-/* Reg dump segment numbers. */
+/* Firmware coredump header segment numbers. */
 enum {
 	CORE_SEG_NUM = 1,
 	TEST_LOGIC_SEG_NUM = 2,
@@ -1527,6 +1666,67 @@ enum {
 
 };
 
+/* There are 64 generic NIC registers. */
+#define NIC_REGS_DUMP_WORD_COUNT		64
+/* XGMAC word count. */
+#define XGMAC_DUMP_WORD_COUNT		(XGMAC_REGISTER_END / 4)
+/* Word counts for the SERDES blocks. */
+#define XG_SERDES_XAUI_AN_COUNT		14
+#define XG_SERDES_XAUI_HSS_PCS_COUNT	33
+#define XG_SERDES_XFI_AN_COUNT		14
+#define XG_SERDES_XFI_TRAIN_COUNT		12
+#define XG_SERDES_XFI_HSS_PCS_COUNT	15
+#define XG_SERDES_XFI_HSS_TX_COUNT		32
+#define XG_SERDES_XFI_HSS_RX_COUNT		32
+#define XG_SERDES_XFI_HSS_PLL_COUNT	32
+
+/* There are 2 CNA ETS and 8 NIC ETS registers. */
+#define ETS_REGS_DUMP_WORD_COUNT		10
+
+/* Each probe mux entry stores the probe type plus 64 entries
+ * that are each each 64-bits in length. There are a total of
+ * 34 (PRB_MX_ADDR_VALID_TOTAL) valid probes.
+ */
+#define PRB_MX_ADDR_PRB_WORD_COUNT		(1 + (PRB_MX_ADDR_MAX_MUX * 2))
+#define PRB_MX_DUMP_TOT_COUNT		(PRB_MX_ADDR_PRB_WORD_COUNT * \
+							PRB_MX_ADDR_VALID_TOTAL)
+/* Each routing entry consists of 4 32-bit words.
+ * They are route type, index, index word, and result.
+ * There are 2 route blocks with 8 entries each and
+ *  2 NIC blocks with 16 entries each.
+ * The totol entries is 48 with 4 words each.
+ */
+#define RT_IDX_DUMP_ENTRIES			48
+#define RT_IDX_DUMP_WORDS_PER_ENTRY	4
+#define RT_IDX_DUMP_TOT_WORDS		(RT_IDX_DUMP_ENTRIES * \
+						RT_IDX_DUMP_WORDS_PER_ENTRY)
+/* There are 10 address blocks in filter, each with
+ * different entry counts and different word-count-per-entry.
+ */
+#define MAC_ADDR_DUMP_ENTRIES \
+	((MAC_ADDR_MAX_CAM_ENTRIES * MAC_ADDR_MAX_CAM_WCOUNT) + \
+	(MAC_ADDR_MAX_MULTICAST_ENTRIES * MAC_ADDR_MAX_MULTICAST_WCOUNT) + \
+	(MAC_ADDR_MAX_VLAN_ENTRIES * MAC_ADDR_MAX_VLAN_WCOUNT) + \
+	(MAC_ADDR_MAX_MCAST_FLTR_ENTRIES * MAC_ADDR_MAX_MCAST_FLTR_WCOUNT) + \
+	(MAC_ADDR_MAX_FC_MAC_ENTRIES * MAC_ADDR_MAX_FC_MAC_WCOUNT) + \
+	(MAC_ADDR_MAX_MGMT_MAC_ENTRIES * MAC_ADDR_MAX_MGMT_MAC_WCOUNT) + \
+	(MAC_ADDR_MAX_MGMT_VLAN_ENTRIES * MAC_ADDR_MAX_MGMT_VLAN_WCOUNT) + \
+	(MAC_ADDR_MAX_MGMT_V4_ENTRIES * MAC_ADDR_MAX_MGMT_V4_WCOUNT) + \
+	(MAC_ADDR_MAX_MGMT_V6_ENTRIES * MAC_ADDR_MAX_MGMT_V6_WCOUNT) + \
+	(MAC_ADDR_MAX_MGMT_TU_DP_ENTRIES * MAC_ADDR_MAX_MGMT_TU_DP_WCOUNT))
+#define MAC_ADDR_DUMP_WORDS_PER_ENTRY	2
+#define MAC_ADDR_DUMP_TOT_WORDS		(MAC_ADDR_DUMP_ENTRIES * \
+						MAC_ADDR_DUMP_WORDS_PER_ENTRY)
+/* Maximum of 4 functions whose semaphore registeres are
+ * in the coredump.
+ */
+#define MAX_SEMAPHORE_FUNCTIONS		4
+/* Defines for access the MPI shadow registers. */
+#define RISC_124		0x0003007c
+#define RISC_127		0x0003007f
+#define SHADOW_OFFSET	0xb0000000
+#define SHADOW_REG_SHIFT	20
+
 struct ql_nic_misc {
 	u32 rx_ring_count;
 	u32 tx_ring_count;
@@ -1568,6 +1768,199 @@ struct ql_reg_dump {
 	u32 ets[8+2];
 };
 
+struct ql_mpi_coredump {
+	/* segment 0 */
+	struct mpi_coredump_global_header mpi_global_header;
+
+	/* segment 1 */
+	struct mpi_coredump_segment_header core_regs_seg_hdr;
+	u32 mpi_core_regs[MPI_CORE_REGS_CNT];
+	u32 mpi_core_sh_regs[MPI_CORE_SH_REGS_CNT];
+
+	/* segment 2 */
+	struct mpi_coredump_segment_header test_logic_regs_seg_hdr;
+	u32 test_logic_regs[TEST_REGS_CNT];
+
+	/* segment 3 */
+	struct mpi_coredump_segment_header rmii_regs_seg_hdr;
+	u32 rmii_regs[RMII_REGS_CNT];
+
+	/* segment 4 */
+	struct mpi_coredump_segment_header fcmac1_regs_seg_hdr;
+	u32 fcmac1_regs[FCMAC_REGS_CNT];
+
+	/* segment 5 */
+	struct mpi_coredump_segment_header fcmac2_regs_seg_hdr;
+	u32 fcmac2_regs[FCMAC_REGS_CNT];
+
+	/* segment 6 */
+	struct mpi_coredump_segment_header fc1_mbx_regs_seg_hdr;
+	u32 fc1_mbx_regs[FC_MBX_REGS_CNT];
+
+	/* segment 7 */
+	struct mpi_coredump_segment_header ide_regs_seg_hdr;
+	u32 ide_regs[IDE_REGS_CNT];
+
+	/* segment 8 */
+	struct mpi_coredump_segment_header nic1_mbx_regs_seg_hdr;
+	u32 nic1_mbx_regs[NIC_MBX_REGS_CNT];
+
+	/* segment 9 */
+	struct mpi_coredump_segment_header smbus_regs_seg_hdr;
+	u32 smbus_regs[SMBUS_REGS_CNT];
+
+	/* segment 10 */
+	struct mpi_coredump_segment_header fc2_mbx_regs_seg_hdr;
+	u32 fc2_mbx_regs[FC_MBX_REGS_CNT];
+
+	/* segment 11 */
+	struct mpi_coredump_segment_header nic2_mbx_regs_seg_hdr;
+	u32 nic2_mbx_regs[NIC_MBX_REGS_CNT];
+
+	/* segment 12 */
+	struct mpi_coredump_segment_header i2c_regs_seg_hdr;
+	u32 i2c_regs[I2C_REGS_CNT];
+	/* segment 13 */
+	struct mpi_coredump_segment_header memc_regs_seg_hdr;
+	u32 memc_regs[MEMC_REGS_CNT];
+
+	/* segment 14 */
+	struct mpi_coredump_segment_header pbus_regs_seg_hdr;
+	u32 pbus_regs[PBUS_REGS_CNT];
+
+	/* segment 15 */
+	struct mpi_coredump_segment_header mde_regs_seg_hdr;
+	u32 mde_regs[MDE_REGS_CNT];
+
+	/* segment 16 */
+	struct mpi_coredump_segment_header nic_regs_seg_hdr;
+	u32 nic_regs[NIC_REGS_DUMP_WORD_COUNT];
+
+	/* segment 17 */
+	struct mpi_coredump_segment_header nic2_regs_seg_hdr;
+	u32 nic2_regs[NIC_REGS_DUMP_WORD_COUNT];
+
+	/* segment 18 */
+	struct mpi_coredump_segment_header xgmac1_seg_hdr;
+	u32 xgmac1[XGMAC_DUMP_WORD_COUNT];
+
+	/* segment 19 */
+	struct mpi_coredump_segment_header xgmac2_seg_hdr;
+	u32 xgmac2[XGMAC_DUMP_WORD_COUNT];
+
+	/* segment 20 */
+	struct mpi_coredump_segment_header code_ram_seg_hdr;
+	u32 code_ram[CODE_RAM_CNT];
+
+	/* segment 21 */
+	struct mpi_coredump_segment_header memc_ram_seg_hdr;
+	u32 memc_ram[MEMC_RAM_CNT];
+
+	/* segment 22 */
+	struct mpi_coredump_segment_header xaui_an_hdr;
+	u32 serdes_xaui_an[XG_SERDES_XAUI_AN_COUNT];
+
+	/* segment 23 */
+	struct mpi_coredump_segment_header xaui_hss_pcs_hdr;
+	u32 serdes_xaui_hss_pcs[XG_SERDES_XAUI_HSS_PCS_COUNT];
+
+	/* segment 24 */
+	struct mpi_coredump_segment_header xfi_an_hdr;
+	u32 serdes_xfi_an[XG_SERDES_XFI_AN_COUNT];
+
+	/* segment 25 */
+	struct mpi_coredump_segment_header xfi_train_hdr;
+	u32 serdes_xfi_train[XG_SERDES_XFI_TRAIN_COUNT];
+
+	/* segment 26 */
+	struct mpi_coredump_segment_header xfi_hss_pcs_hdr;
+	u32 serdes_xfi_hss_pcs[XG_SERDES_XFI_HSS_PCS_COUNT];
+
+	/* segment 27 */
+	struct mpi_coredump_segment_header xfi_hss_tx_hdr;
+	u32 serdes_xfi_hss_tx[XG_SERDES_XFI_HSS_TX_COUNT];
+
+	/* segment 28 */
+	struct mpi_coredump_segment_header xfi_hss_rx_hdr;
+	u32 serdes_xfi_hss_rx[XG_SERDES_XFI_HSS_RX_COUNT];
+
+	/* segment 29 */
+	struct mpi_coredump_segment_header xfi_hss_pll_hdr;
+	u32 serdes_xfi_hss_pll[XG_SERDES_XFI_HSS_PLL_COUNT];
+
+	/* segment 30 */
+	struct mpi_coredump_segment_header misc_nic_seg_hdr;
+	struct ql_nic_misc misc_nic_info;
+
+	/* segment 31 */
+	/* one interrupt state for each CQ */
+	struct mpi_coredump_segment_header intr_states_seg_hdr;
+	u32 intr_states[MAX_RX_RINGS];
+
+	/* segment 32 */
+	/* 3 cam words each for 16 unicast,
+	 * 2 cam words for each of 32 multicast.
+	 */
+	struct mpi_coredump_segment_header cam_entries_seg_hdr;
+	u32 cam_entries[(16 * 3) + (32 * 3)];
+
+	/* segment 33 */
+	struct mpi_coredump_segment_header nic_routing_words_seg_hdr;
+	u32 nic_routing_words[16];
+	/* segment 34 */
+	struct mpi_coredump_segment_header ets_seg_hdr;
+	u32 ets[ETS_REGS_DUMP_WORD_COUNT];
+
+	/* segment 35 */
+	struct mpi_coredump_segment_header probe_dump_seg_hdr;
+	u32 probe_dump[PRB_MX_DUMP_TOT_COUNT];
+
+	/* segment 36 */
+	struct mpi_coredump_segment_header routing_reg_seg_hdr;
+	u32 routing_regs[RT_IDX_DUMP_TOT_WORDS];
+
+	/* segment 37 */
+	struct mpi_coredump_segment_header mac_prot_reg_seg_hdr;
+	u32 mac_prot_regs[MAC_ADDR_DUMP_TOT_WORDS];
+
+	/* segment 38 */
+	struct mpi_coredump_segment_header xaui2_an_hdr;
+	u32 serdes2_xaui_an[XG_SERDES_XAUI_AN_COUNT];
+
+	/* segment 39 */
+	struct mpi_coredump_segment_header xaui2_hss_pcs_hdr;
+	u32 serdes2_xaui_hss_pcs[XG_SERDES_XAUI_HSS_PCS_COUNT];
+
+	/* segment 40 */
+	struct mpi_coredump_segment_header xfi2_an_hdr;
+	u32 serdes2_xfi_an[XG_SERDES_XFI_AN_COUNT];
+
+	/* segment 41 */
+	struct mpi_coredump_segment_header xfi2_train_hdr;
+	u32 serdes2_xfi_train[XG_SERDES_XFI_TRAIN_COUNT];
+
+	/* segment 42 */
+	struct mpi_coredump_segment_header xfi2_hss_pcs_hdr;
+	u32 serdes2_xfi_hss_pcs[XG_SERDES_XFI_HSS_PCS_COUNT];
+
+	/* segment 43 */
+	struct mpi_coredump_segment_header xfi2_hss_tx_hdr;
+	u32 serdes2_xfi_hss_tx[XG_SERDES_XFI_HSS_TX_COUNT];
+
+	/* segment 44 */
+	struct mpi_coredump_segment_header xfi2_hss_rx_hdr;
+	u32 serdes2_xfi_hss_rx[XG_SERDES_XFI_HSS_RX_COUNT];
+
+	/* segment 45 */
+	struct mpi_coredump_segment_header xfi2_hss_pll_hdr;
+	u32 serdes2_xfi_hss_pll[XG_SERDES_XFI_HSS_PLL_COUNT];
+
+	/* segment 50 */
+	/* semaphore register for all 5 functions */
+	struct mpi_coredump_segment_header sem_regs_seg_hdr;
+	u32 sem_regs[MAX_SEMAPHORE_FUNCTIONS];
+};
+
 /*
  * intr_context structure is used during initialization
  * to hook the interrupts.  It is also used in a single
@@ -1603,6 +1996,8 @@ enum {
 	QL_CAM_RT_SET = 8,
 	QL_SELFTEST = 9,
 	QL_LB_LINK_UP = 10,
+	QL_FRC_COREDUMP = 11,
+	QL_EEH_FATAL = 12,
 };
 
 /* link_status bit definitions */
@@ -1724,6 +2119,8 @@ struct ql_adapter {
 	u32 port_link_up;
 	u32 port_init;
 	u32 link_status;
+	struct ql_mpi_coredump *mpi_coredump;
+	u32 core_is_dumped;
 	u32 link_config;
 	u32 led_config;
 	u32 max_frame_size;
@@ -1736,10 +2133,14 @@ struct ql_adapter {
 	struct delayed_work mpi_work;
 	struct delayed_work mpi_port_cfg_work;
 	struct delayed_work mpi_idc_work;
+	struct delayed_work mpi_core_to_log;
 	struct completion ide_completion;
 	struct nic_operations *nic_ops;
 	u16 device_id;
+	struct timer_list timer;
 	atomic_t lb_count;
+	/* Keep local copy of current mac address. */
+	char current_mac_addr[6];
 };
 
 /*
@@ -1807,6 +2208,7 @@ extern int ql_write_cfg(struct ql_adapte
 void ql_queue_fw_error(struct ql_adapter *qdev);
 void ql_mpi_work(struct work_struct *work);
 void ql_mpi_reset_work(struct work_struct *work);
+void ql_mpi_core_to_log(struct work_struct *work);
 int ql_wait_reg_rdy(struct ql_adapter *qdev, u32 reg, u32 bit, u32 ebit);
 void ql_queue_asic_error(struct ql_adapter *qdev);
 u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr);
@@ -1817,6 +2219,15 @@ void ql_mpi_port_cfg_work(struct work_st
 int ql_mb_get_fw_state(struct ql_adapter *qdev);
 int ql_cam_route_initialize(struct ql_adapter *qdev);
 int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data);
+int ql_write_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 data);
+int ql_unpause_mpi_risc(struct ql_adapter *qdev);
+int ql_pause_mpi_risc(struct ql_adapter *qdev);
+int ql_hard_reset_mpi_risc(struct ql_adapter *qdev);
+int ql_dump_risc_ram_area(struct ql_adapter *qdev, void *buf,
+		u32 ram_addr, int word_count);
+int ql_core_dump(struct ql_adapter *qdev,
+		struct ql_mpi_coredump *mpi_coredump);
+int ql_mb_sys_err(struct ql_adapter *qdev);
 int ql_mb_about_fw(struct ql_adapter *qdev);
 int ql_wol(struct ql_adapter *qdev);
 int ql_mb_wol_set_magic(struct ql_adapter *qdev, u32 enable_wol);
@@ -1833,6 +2244,7 @@ void ql_gen_reg_dump(struct ql_adapter *
 			struct ql_reg_dump *mpi_coredump);
 netdev_tx_t ql_lb_send(struct sk_buff *skb, struct net_device *ndev);
 void ql_check_lb_frame(struct ql_adapter *, struct sk_buff *);
+int ql_own_firmware(struct ql_adapter *qdev);
 int ql_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget);
 
 #if 1
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_main.c linux-libre-2.6.34-gnu1/drivers/net/qlge/qlge_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/qlge/qlge_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -73,7 +73,19 @@ static int qlge_irq_type = MSIX_IRQ;
 module_param(qlge_irq_type, int, MSIX_IRQ);
 MODULE_PARM_DESC(qlge_irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");
 
-static struct pci_device_id qlge_pci_tbl[] __devinitdata = {
+static int qlge_mpi_coredump;
+module_param(qlge_mpi_coredump, int, 0);
+MODULE_PARM_DESC(qlge_mpi_coredump,
+		"Option to enable MPI firmware dump. "
+		"Default is OFF - Do Not allocate memory. ");
+
+static int qlge_force_coredump;
+module_param(qlge_force_coredump, int, 0);
+MODULE_PARM_DESC(qlge_force_coredump,
+		"Option to allow force of firmware core dump. "
+		"Default is OFF - Do not allow.");
+
+static DEFINE_PCI_DEVICE_TABLE(qlge_pci_tbl) = {
 	{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8012)},
 	{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8000)},
 	/* required last entry */
@@ -116,7 +128,7 @@ static int ql_sem_trylock(struct ql_adap
 		sem_bits = SEM_SET << SEM_PROC_REG_SHIFT;
 		break;
 	default:
-		QPRINTK(qdev, PROBE, ALERT, "Bad Semaphore mask!.\n");
+		netif_alert(qdev, probe, qdev->ndev, "bad Semaphore mask!.\n");
 		return -EINVAL;
 	}
 
@@ -156,17 +168,17 @@ int ql_wait_reg_rdy(struct ql_adapter *q
 
 		/* check for errors */
 		if (temp & err_bit) {
-			QPRINTK(qdev, PROBE, ALERT,
-				"register 0x%.08x access error, value = 0x%.08x!.\n",
-				reg, temp);
+			netif_alert(qdev, probe, qdev->ndev,
+				    "register 0x%.08x access error, value = 0x%.08x!.\n",
+				    reg, temp);
 			return -EIO;
 		} else if (temp & bit)
 			return 0;
 		udelay(UDELAY_DELAY);
 		count--;
 	}
-	QPRINTK(qdev, PROBE, ALERT,
-		"Timed out waiting for reg %x to come ready.\n", reg);
+	netif_alert(qdev, probe, qdev->ndev,
+		    "Timed out waiting for reg %x to come ready.\n", reg);
 	return -ETIMEDOUT;
 }
 
@@ -209,7 +221,7 @@ int ql_write_cfg(struct ql_adapter *qdev
 
 	map = pci_map_single(qdev->pdev, ptr, size, direction);
 	if (pci_dma_mapping_error(qdev->pdev, map)) {
-		QPRINTK(qdev, IFUP, ERR, "Couldn't map DMA area.\n");
+		netif_err(qdev, ifup, qdev->ndev, "Couldn't map DMA area.\n");
 		return -ENOMEM;
 	}
 
@@ -219,8 +231,8 @@ int ql_write_cfg(struct ql_adapter *qdev
 
 	status = ql_wait_cfg(qdev, bit);
 	if (status) {
-		QPRINTK(qdev, IFUP, ERR,
-			"Timed out waiting for CFG to come ready.\n");
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Timed out waiting for CFG to come ready.\n");
 		goto exit;
 	}
 
@@ -301,8 +313,8 @@ int ql_get_mac_addr_reg(struct ql_adapte
 	case MAC_ADDR_TYPE_VLAN:
 	case MAC_ADDR_TYPE_MULTI_FLTR:
 	default:
-		QPRINTK(qdev, IFUP, CRIT,
-			"Address type %d not yet supported.\n", type);
+		netif_crit(qdev, ifup, qdev->ndev,
+			   "Address type %d not yet supported.\n", type);
 		status = -EPERM;
 	}
 exit:
@@ -359,12 +371,11 @@ static int ql_set_mac_addr_reg(struct ql
 			    (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) |
 			    (addr[5]);
 
-			QPRINTK(qdev, IFUP, DEBUG,
-				"Adding %s address %pM"
-				" at index %d in the CAM.\n",
-				((type ==
-				  MAC_ADDR_TYPE_MULTI_MAC) ? "MULTICAST" :
-				 "UNICAST"), addr, index);
+			netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+				     "Adding %s address %pM at index %d in the CAM.\n",
+				     type == MAC_ADDR_TYPE_MULTI_MAC ?
+				     "MULTICAST" : "UNICAST",
+				     addr, index);
 
 			status =
 			    ql_wait_reg_rdy(qdev,
@@ -414,9 +425,11 @@ static int ql_set_mac_addr_reg(struct ql
 			 * addressing. It's either MAC_ADDR_E on or off.
 			 * That's bit-27 we're talking about.
 			 */
-			QPRINTK(qdev, IFUP, INFO, "%s VLAN ID %d %s the CAM.\n",
-				(enable_bit ? "Adding" : "Removing"),
-				index, (enable_bit ? "to" : "from"));
+			netif_info(qdev, ifup, qdev->ndev,
+				   "%s VLAN ID %d %s the CAM.\n",
+				   enable_bit ? "Adding" : "Removing",
+				   index,
+				   enable_bit ? "to" : "from");
 
 			status =
 			    ql_wait_reg_rdy(qdev,
@@ -431,8 +444,8 @@ static int ql_set_mac_addr_reg(struct ql
 		}
 	case MAC_ADDR_TYPE_MULTI_FLTR:
 	default:
-		QPRINTK(qdev, IFUP, CRIT,
-			"Address type %d not yet supported.\n", type);
+		netif_crit(qdev, ifup, qdev->ndev,
+			   "Address type %d not yet supported.\n", type);
 		status = -EPERM;
 	}
 exit:
@@ -450,17 +463,14 @@ static int ql_set_mac_addr(struct ql_ada
 	char *addr;
 
 	if (set) {
-		addr = &qdev->ndev->dev_addr[0];
-		QPRINTK(qdev, IFUP, DEBUG,
-			"Set Mac addr %02x:%02x:%02x:%02x:%02x:%02x\n",
-			addr[0], addr[1], addr[2], addr[3],
-			addr[4], addr[5]);
+		addr = &qdev->current_mac_addr[0];
+		netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+			     "Set Mac addr %pM\n", addr);
 	} else {
 		memset(zero_mac_addr, 0, ETH_ALEN);
 		addr = &zero_mac_addr[0];
-		QPRINTK(qdev, IFUP, DEBUG,
-				"Clearing MAC address on %s\n",
-				qdev->ndev->name);
+		netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+			     "Clearing MAC address\n");
 	}
 	status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
 	if (status)
@@ -469,23 +479,21 @@ static int ql_set_mac_addr(struct ql_ada
 			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");
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Failed to init mac address.\n");
 	return status;
 }
 
 void ql_link_on(struct ql_adapter *qdev)
 {
-	QPRINTK(qdev, LINK, ERR, "%s: Link is up.\n",
-				 qdev->ndev->name);
+	netif_err(qdev, link, qdev->ndev, "Link is up.\n");
 	netif_carrier_on(qdev->ndev);
 	ql_set_mac_addr(qdev, 1);
 }
 
 void ql_link_off(struct ql_adapter *qdev)
 {
-	QPRINTK(qdev, LINK, ERR, "%s: Link is down.\n",
-				 qdev->ndev->name);
+	netif_err(qdev, link, qdev->ndev, "Link is down.\n");
 	netif_carrier_off(qdev->ndev);
 	ql_set_mac_addr(qdev, 0);
 }
@@ -522,27 +530,27 @@ static int ql_set_routing_reg(struct ql_
 	int status = -EINVAL; /* Return error if no mask match. */
 	u32 value = 0;
 
-	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"),
-		((index == RT_IDX_ALL_ERR_SLOT) ? "MAC ERROR/ALL ERROR" : ""),
-		((index == RT_IDX_IP_CSUM_ERR_SLOT) ? "IP CSUM ERROR" : ""),
-		((index ==
-		  RT_IDX_TCP_UDP_CSUM_ERR_SLOT) ? "TCP/UDP CSUM ERROR" : ""),
-		((index == RT_IDX_BCAST_SLOT) ? "BROADCAST" : ""),
-		((index == RT_IDX_MCAST_MATCH_SLOT) ? "MULTICAST MATCH" : ""),
-		((index == RT_IDX_ALLMULTI_SLOT) ? "ALL MULTICAST MATCH" : ""),
-		((index == RT_IDX_UNUSED6_SLOT) ? "UNUSED6" : ""),
-		((index == RT_IDX_UNUSED7_SLOT) ? "UNUSED7" : ""),
-		((index == RT_IDX_RSS_MATCH_SLOT) ? "RSS ALL/IPV4 MATCH" : ""),
-		((index == RT_IDX_RSS_IPV6_SLOT) ? "RSS IPV6" : ""),
-		((index == RT_IDX_RSS_TCP4_SLOT) ? "RSS TCP4" : ""),
-		((index == RT_IDX_RSS_TCP6_SLOT) ? "RSS TCP6" : ""),
-		((index == RT_IDX_CAM_HIT_SLOT) ? "CAM HIT" : ""),
-		((index == RT_IDX_UNUSED013) ? "UNUSED13" : ""),
-		((index == RT_IDX_UNUSED014) ? "UNUSED14" : ""),
-		((index == RT_IDX_PROMISCUOUS_SLOT) ? "PROMISCUOUS" : ""),
-		(enable ? "to" : "from"));
+	netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+		     "%s %s mask %s the routing reg.\n",
+		     enable ? "Adding" : "Removing",
+		     index == RT_IDX_ALL_ERR_SLOT ? "MAC ERROR/ALL ERROR" :
+		     index == RT_IDX_IP_CSUM_ERR_SLOT ? "IP CSUM ERROR" :
+		     index == RT_IDX_TCP_UDP_CSUM_ERR_SLOT ? "TCP/UDP CSUM ERROR" :
+		     index == RT_IDX_BCAST_SLOT ? "BROADCAST" :
+		     index == RT_IDX_MCAST_MATCH_SLOT ? "MULTICAST MATCH" :
+		     index == RT_IDX_ALLMULTI_SLOT ? "ALL MULTICAST MATCH" :
+		     index == RT_IDX_UNUSED6_SLOT ? "UNUSED6" :
+		     index == RT_IDX_UNUSED7_SLOT ? "UNUSED7" :
+		     index == RT_IDX_RSS_MATCH_SLOT ? "RSS ALL/IPV4 MATCH" :
+		     index == RT_IDX_RSS_IPV6_SLOT ? "RSS IPV6" :
+		     index == RT_IDX_RSS_TCP4_SLOT ? "RSS TCP4" :
+		     index == RT_IDX_RSS_TCP6_SLOT ? "RSS TCP6" :
+		     index == RT_IDX_CAM_HIT_SLOT ? "CAM HIT" :
+		     index == RT_IDX_UNUSED013 ? "UNUSED13" :
+		     index == RT_IDX_UNUSED014 ? "UNUSED14" :
+		     index == RT_IDX_PROMISCUOUS_SLOT ? "PROMISCUOUS" :
+		     "(Bad index != RT_IDX)",
+		     enable ? "to" : "from");
 
 	switch (mask) {
 	case RT_IDX_CAM_HIT:
@@ -602,8 +610,8 @@ static int ql_set_routing_reg(struct ql_
 			break;
 		}
 	default:
-		QPRINTK(qdev, IFUP, ERR, "Mask type %d not yet supported.\n",
-			mask);
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Mask type %d not yet supported.\n", mask);
 		status = -EPERM;
 		goto exit;
 	}
@@ -709,7 +717,7 @@ static int ql_validate_flash(struct ql_a
 
 	status = strncmp((char *)&qdev->flash, str, 4);
 	if (status) {
-		QPRINTK(qdev, IFUP, ERR, "Invalid flash signature.\n");
+		netif_err(qdev, ifup, qdev->ndev, "Invalid flash signature.\n");
 		return	status;
 	}
 
@@ -717,8 +725,8 @@ static int ql_validate_flash(struct ql_a
 		csum += le16_to_cpu(*flash++);
 
 	if (csum)
-		QPRINTK(qdev, IFUP, ERR,
-			"Invalid flash checksum, csum = 0x%.04x.\n", csum);
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Invalid flash checksum, csum = 0x%.04x.\n", csum);
 
 	return csum;
 }
@@ -770,7 +778,8 @@ static int ql_get_8000_flash_params(stru
 	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");
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Error reading flash.\n");
 			goto exit;
 		}
 	}
@@ -779,7 +788,7 @@ static int ql_get_8000_flash_params(stru
 			sizeof(struct flash_params_8000) / sizeof(u16),
 			"8000");
 	if (status) {
-		QPRINTK(qdev, IFUP, ERR, "Invalid flash.\n");
+		netif_err(qdev, ifup, qdev->ndev, "Invalid flash.\n");
 		status = -EINVAL;
 		goto exit;
 	}
@@ -797,7 +806,7 @@ static int ql_get_8000_flash_params(stru
 			qdev->ndev->addr_len);
 
 	if (!is_valid_ether_addr(mac_addr)) {
-		QPRINTK(qdev, IFUP, ERR, "Invalid MAC address.\n");
+		netif_err(qdev, ifup, qdev->ndev, "Invalid MAC address.\n");
 		status = -EINVAL;
 		goto exit;
 	}
@@ -831,7 +840,8 @@ static int ql_get_8012_flash_params(stru
 	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");
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Error reading flash.\n");
 			goto exit;
 		}
 
@@ -841,7 +851,7 @@ static int ql_get_8012_flash_params(stru
 			sizeof(struct flash_params_8012) / sizeof(u16),
 			"8012");
 	if (status) {
-		QPRINTK(qdev, IFUP, ERR, "Invalid flash.\n");
+		netif_err(qdev, ifup, qdev->ndev, "Invalid flash.\n");
 		status = -EINVAL;
 		goto exit;
 	}
@@ -959,17 +969,17 @@ static int ql_8012_port_initialize(struc
 		/* Another function has the semaphore, so
 		 * wait for the port init bit to come ready.
 		 */
-		QPRINTK(qdev, LINK, INFO,
-			"Another function has the semaphore, so wait for the port init bit to come ready.\n");
+		netif_info(qdev, link, qdev->ndev,
+			   "Another function has the semaphore, so wait for the port init bit to come ready.\n");
 		status = ql_wait_reg_rdy(qdev, STS, qdev->port_init, 0);
 		if (status) {
-			QPRINTK(qdev, LINK, CRIT,
-				"Port initialize timed out.\n");
+			netif_crit(qdev, link, qdev->ndev,
+				   "Port initialize timed out.\n");
 		}
 		return status;
 	}
 
-	QPRINTK(qdev, LINK, INFO, "Got xgmac semaphore!.\n");
+	netif_info(qdev, link, qdev->ndev, "Got xgmac semaphore!.\n");
 	/* Set the core reset. */
 	status = ql_read_xgmac_reg(qdev, GLOBAL_CFG, &data);
 	if (status)
@@ -1099,8 +1109,8 @@ static int ql_get_next_chunk(struct ql_a
 						GFP_ATOMIC,
 						qdev->lbq_buf_order);
 		if (unlikely(!rx_ring->pg_chunk.page)) {
-			QPRINTK(qdev, DRV, ERR,
-				"page allocation failed.\n");
+			netif_err(qdev, drv, qdev->ndev,
+				  "page allocation failed.\n");
 			return -ENOMEM;
 		}
 		rx_ring->pg_chunk.offset = 0;
@@ -1110,8 +1120,8 @@ static int ql_get_next_chunk(struct ql_a
 		if (pci_dma_mapping_error(qdev->pdev, map)) {
 			__free_pages(rx_ring->pg_chunk.page,
 					qdev->lbq_buf_order);
-			QPRINTK(qdev, DRV, ERR,
-				"PCI mapping failed.\n");
+			netif_err(qdev, drv, qdev->ndev,
+				  "PCI mapping failed.\n");
 			return -ENOMEM;
 		}
 		rx_ring->pg_chunk.map = map;
@@ -1148,15 +1158,15 @@ static void ql_update_lbq(struct ql_adap
 
 	while (rx_ring->lbq_free_cnt > 32) {
 		for (i = 0; i < 16; i++) {
-			QPRINTK(qdev, RX_STATUS, DEBUG,
-				"lbq: try cleaning clean_idx = %d.\n",
-				clean_idx);
+			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+				     "lbq: try cleaning clean_idx = %d.\n",
+				     clean_idx);
 			lbq_desc = &rx_ring->lbq[clean_idx];
 			if (ql_get_next_chunk(qdev, rx_ring, lbq_desc)) {
-				QPRINTK(qdev, IFUP, ERR,
-					"Could not get a page chunk.\n");
-					return;
-				}
+				netif_err(qdev, ifup, qdev->ndev,
+					  "Could not get a page chunk.\n");
+				return;
+			}
 
 			map = lbq_desc->p.pg_chunk.map +
 				lbq_desc->p.pg_chunk.offset;
@@ -1181,9 +1191,9 @@ static void ql_update_lbq(struct ql_adap
 	}
 
 	if (start_idx != clean_idx) {
-		QPRINTK(qdev, RX_STATUS, DEBUG,
-			"lbq: updating prod idx = %d.\n",
-			rx_ring->lbq_prod_idx);
+		netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+			     "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);
 	}
@@ -1201,19 +1211,20 @@ static void ql_update_sbq(struct ql_adap
 	while (rx_ring->sbq_free_cnt > 16) {
 		for (i = 0; i < 16; i++) {
 			sbq_desc = &rx_ring->sbq[clean_idx];
-			QPRINTK(qdev, RX_STATUS, DEBUG,
-				"sbq: try cleaning clean_idx = %d.\n",
-				clean_idx);
+			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+				     "sbq: try cleaning clean_idx = %d.\n",
+				     clean_idx);
 			if (sbq_desc->p.skb == NULL) {
-				QPRINTK(qdev, RX_STATUS, DEBUG,
-					"sbq: getting new skb for index %d.\n",
-					sbq_desc->index);
+				netif_printk(qdev, rx_status, KERN_DEBUG,
+					     qdev->ndev,
+					     "sbq: getting new skb for index %d.\n",
+					     sbq_desc->index);
 				sbq_desc->p.skb =
 				    netdev_alloc_skb(qdev->ndev,
 						     SMALL_BUFFER_SIZE);
 				if (sbq_desc->p.skb == NULL) {
-					QPRINTK(qdev, PROBE, ERR,
-						"Couldn't get an skb.\n");
+					netif_err(qdev, probe, qdev->ndev,
+						  "Couldn't get an skb.\n");
 					rx_ring->sbq_clean_idx = clean_idx;
 					return;
 				}
@@ -1223,7 +1234,8 @@ static void ql_update_sbq(struct ql_adap
 						     rx_ring->sbq_buf_size,
 						     PCI_DMA_FROMDEVICE);
 				if (pci_dma_mapping_error(qdev->pdev, map)) {
-					QPRINTK(qdev, IFUP, ERR, "PCI mapping failed.\n");
+					netif_err(qdev, ifup, qdev->ndev,
+						  "PCI mapping failed.\n");
 					rx_ring->sbq_clean_idx = clean_idx;
 					dev_kfree_skb_any(sbq_desc->p.skb);
 					sbq_desc->p.skb = NULL;
@@ -1247,9 +1259,9 @@ static void ql_update_sbq(struct ql_adap
 	}
 
 	if (start_idx != clean_idx) {
-		QPRINTK(qdev, RX_STATUS, DEBUG,
-			"sbq: updating prod idx = %d.\n",
-			rx_ring->sbq_prod_idx);
+		netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+			     "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);
 	}
@@ -1281,8 +1293,9 @@ static void ql_unmap_send(struct ql_adap
 			 * then its an OAL.
 			 */
 			if (i == 7) {
-				QPRINTK(qdev, TX_DONE, DEBUG,
-					"unmapping OAL area.\n");
+				netif_printk(qdev, tx_done, KERN_DEBUG,
+					     qdev->ndev,
+					     "unmapping OAL area.\n");
 			}
 			pci_unmap_single(qdev->pdev,
 					 pci_unmap_addr(&tx_ring_desc->map[i],
@@ -1291,8 +1304,8 @@ static void ql_unmap_send(struct ql_adap
 						       maplen),
 					 PCI_DMA_TODEVICE);
 		} else {
-			QPRINTK(qdev, TX_DONE, DEBUG, "unmapping frag %d.\n",
-				i);
+			netif_printk(qdev, tx_done, KERN_DEBUG, qdev->ndev,
+				     "unmapping frag %d.\n", i);
 			pci_unmap_page(qdev->pdev,
 				       pci_unmap_addr(&tx_ring_desc->map[i],
 						      mapaddr),
@@ -1317,7 +1330,8 @@ static int ql_map_send(struct ql_adapter
 	int frag_cnt = skb_shinfo(skb)->nr_frags;
 
 	if (frag_cnt) {
-		QPRINTK(qdev, TX_QUEUED, DEBUG, "frag_cnt = %d.\n", frag_cnt);
+		netif_printk(qdev, tx_queued, KERN_DEBUG, qdev->ndev,
+			     "frag_cnt = %d.\n", frag_cnt);
 	}
 	/*
 	 * Map the skb buffer first.
@@ -1326,8 +1340,8 @@ static int ql_map_send(struct ql_adapter
 
 	err = pci_dma_mapping_error(qdev->pdev, map);
 	if (err) {
-		QPRINTK(qdev, TX_QUEUED, ERR,
-			"PCI mapping failed with error: %d\n", err);
+		netif_err(qdev, tx_queued, qdev->ndev,
+			  "PCI mapping failed with error: %d\n", err);
 
 		return NETDEV_TX_BUSY;
 	}
@@ -1373,9 +1387,9 @@ static int ql_map_send(struct ql_adapter
 					     PCI_DMA_TODEVICE);
 			err = pci_dma_mapping_error(qdev->pdev, map);
 			if (err) {
-				QPRINTK(qdev, TX_QUEUED, ERR,
-					"PCI mapping outbound address list with error: %d\n",
-					err);
+				netif_err(qdev, tx_queued, qdev->ndev,
+					  "PCI mapping outbound address list with error: %d\n",
+					  err);
 				goto map_error;
 			}
 
@@ -1403,9 +1417,9 @@ static int ql_map_send(struct ql_adapter
 
 		err = pci_dma_mapping_error(qdev->pdev, map);
 		if (err) {
-			QPRINTK(qdev, TX_QUEUED, ERR,
-				"PCI mapping frags failed with error: %d.\n",
-				err);
+			netif_err(qdev, tx_queued, qdev->ndev,
+				  "PCI mapping frags failed with error: %d.\n",
+				  err);
 			goto map_error;
 		}
 
@@ -1433,6 +1447,260 @@ map_error:
 	return NETDEV_TX_BUSY;
 }
 
+/* Process an inbound completion from an rx ring. */
+static void ql_process_mac_rx_gro_page(struct ql_adapter *qdev,
+					struct rx_ring *rx_ring,
+					struct ib_mac_iocb_rsp *ib_mac_rsp,
+					u32 length,
+					u16 vlan_id)
+{
+	struct sk_buff *skb;
+	struct bq_desc *lbq_desc = ql_get_curr_lchunk(qdev, rx_ring);
+	struct skb_frag_struct *rx_frag;
+	int nr_frags;
+	struct napi_struct *napi = &rx_ring->napi;
+
+	napi->dev = qdev->ndev;
+
+	skb = napi_get_frags(napi);
+	if (!skb) {
+		netif_err(qdev, drv, qdev->ndev,
+			  "Couldn't get an skb, exiting.\n");
+		rx_ring->rx_dropped++;
+		put_page(lbq_desc->p.pg_chunk.page);
+		return;
+	}
+	prefetch(lbq_desc->p.pg_chunk.va);
+	rx_frag = skb_shinfo(skb)->frags;
+	nr_frags = skb_shinfo(skb)->nr_frags;
+	rx_frag += nr_frags;
+	rx_frag->page = lbq_desc->p.pg_chunk.page;
+	rx_frag->page_offset = lbq_desc->p.pg_chunk.offset;
+	rx_frag->size = length;
+
+	skb->len += length;
+	skb->data_len += length;
+	skb->truesize += length;
+	skb_shinfo(skb)->nr_frags++;
+
+	rx_ring->rx_packets++;
+	rx_ring->rx_bytes += length;
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+	skb_record_rx_queue(skb, rx_ring->cq_id);
+	if (qdev->vlgrp && (vlan_id != 0xffff))
+		vlan_gro_frags(&rx_ring->napi, qdev->vlgrp, vlan_id);
+	else
+		napi_gro_frags(napi);
+}
+
+/* Process an inbound completion from an rx ring. */
+static void ql_process_mac_rx_page(struct ql_adapter *qdev,
+					struct rx_ring *rx_ring,
+					struct ib_mac_iocb_rsp *ib_mac_rsp,
+					u32 length,
+					u16 vlan_id)
+{
+	struct net_device *ndev = qdev->ndev;
+	struct sk_buff *skb = NULL;
+	void *addr;
+	struct bq_desc *lbq_desc = ql_get_curr_lchunk(qdev, rx_ring);
+	struct napi_struct *napi = &rx_ring->napi;
+
+	skb = netdev_alloc_skb(ndev, length);
+	if (!skb) {
+		netif_err(qdev, drv, qdev->ndev,
+			  "Couldn't get an skb, need to unwind!.\n");
+		rx_ring->rx_dropped++;
+		put_page(lbq_desc->p.pg_chunk.page);
+		return;
+	}
+
+	addr = lbq_desc->p.pg_chunk.va;
+	prefetch(addr);
+
+
+	/* Frame error, so drop the packet. */
+	if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) {
+		netif_err(qdev, drv, qdev->ndev,
+			  "Receive error, flags2 = 0x%x\n", ib_mac_rsp->flags2);
+		rx_ring->rx_errors++;
+		goto err_out;
+	}
+
+	/* The max framesize filter on this chip is set higher than
+	 * MTU since FCoE uses 2k frames.
+	 */
+	if (skb->len > ndev->mtu + ETH_HLEN) {
+		netif_err(qdev, drv, qdev->ndev,
+			  "Segment too small, dropping.\n");
+		rx_ring->rx_dropped++;
+		goto err_out;
+	}
+	memcpy(skb_put(skb, ETH_HLEN), addr, ETH_HLEN);
+	netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+		     "%d bytes of headers and data in large. Chain page to new skb and pull tail.\n",
+		     length);
+	skb_fill_page_desc(skb, 0, lbq_desc->p.pg_chunk.page,
+				lbq_desc->p.pg_chunk.offset+ETH_HLEN,
+				length-ETH_HLEN);
+	skb->len += length-ETH_HLEN;
+	skb->data_len += length-ETH_HLEN;
+	skb->truesize += length-ETH_HLEN;
+
+	rx_ring->rx_packets++;
+	rx_ring->rx_bytes += skb->len;
+	skb->protocol = eth_type_trans(skb, ndev);
+	skb->ip_summed = CHECKSUM_NONE;
+
+	if (qdev->rx_csum &&
+		!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
+		/* TCP frame. */
+		if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
+			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+				     "TCP checksum done!\n");
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+		} else if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) &&
+				(ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_V4)) {
+			/* Unfragmented ipv4 UDP frame. */
+			struct iphdr *iph = (struct iphdr *) skb->data;
+			if (!(iph->frag_off &
+				cpu_to_be16(IP_MF|IP_OFFSET))) {
+				skb->ip_summed = CHECKSUM_UNNECESSARY;
+				netif_printk(qdev, rx_status, KERN_DEBUG,
+					     qdev->ndev,
+					     "TCP checksum done!\n");
+			}
+		}
+	}
+
+	skb_record_rx_queue(skb, rx_ring->cq_id);
+	if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
+		if (qdev->vlgrp && (vlan_id != 0xffff))
+			vlan_gro_receive(napi, qdev->vlgrp, vlan_id, skb);
+		else
+			napi_gro_receive(napi, skb);
+	} else {
+		if (qdev->vlgrp && (vlan_id != 0xffff))
+			vlan_hwaccel_receive_skb(skb, qdev->vlgrp, vlan_id);
+		else
+			netif_receive_skb(skb);
+	}
+	return;
+err_out:
+	dev_kfree_skb_any(skb);
+	put_page(lbq_desc->p.pg_chunk.page);
+}
+
+/* Process an inbound completion from an rx ring. */
+static void ql_process_mac_rx_skb(struct ql_adapter *qdev,
+					struct rx_ring *rx_ring,
+					struct ib_mac_iocb_rsp *ib_mac_rsp,
+					u32 length,
+					u16 vlan_id)
+{
+	struct net_device *ndev = qdev->ndev;
+	struct sk_buff *skb = NULL;
+	struct sk_buff *new_skb = NULL;
+	struct bq_desc *sbq_desc = ql_get_curr_sbuf(rx_ring);
+
+	skb = sbq_desc->p.skb;
+	/* Allocate new_skb and copy */
+	new_skb = netdev_alloc_skb(qdev->ndev, length + NET_IP_ALIGN);
+	if (new_skb == NULL) {
+		netif_err(qdev, probe, qdev->ndev,
+			  "No skb available, drop the packet.\n");
+		rx_ring->rx_dropped++;
+		return;
+	}
+	skb_reserve(new_skb, NET_IP_ALIGN);
+	memcpy(skb_put(new_skb, length), skb->data, length);
+	skb = new_skb;
+
+	/* Frame error, so drop the packet. */
+	if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) {
+		netif_err(qdev, drv, qdev->ndev,
+			  "Receive error, flags2 = 0x%x\n", ib_mac_rsp->flags2);
+		dev_kfree_skb_any(skb);
+		rx_ring->rx_errors++;
+		return;
+	}
+
+	/* loopback self test for ethtool */
+	if (test_bit(QL_SELFTEST, &qdev->flags)) {
+		ql_check_lb_frame(qdev, skb);
+		dev_kfree_skb_any(skb);
+		return;
+	}
+
+	/* The max framesize filter on this chip is set higher than
+	 * MTU since FCoE uses 2k frames.
+	 */
+	if (skb->len > ndev->mtu + ETH_HLEN) {
+		dev_kfree_skb_any(skb);
+		rx_ring->rx_dropped++;
+		return;
+	}
+
+	prefetch(skb->data);
+	skb->dev = ndev;
+	if (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) {
+		netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+			     "%s Multicast.\n",
+			     (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) ==
+			     IB_MAC_IOCB_RSP_M_HASH ? "Hash" :
+			     (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) ==
+			     IB_MAC_IOCB_RSP_M_REG ? "Registered" :
+			     (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) ==
+			     IB_MAC_IOCB_RSP_M_PROM ? "Promiscuous" : "");
+	}
+	if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_P)
+		netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+			     "Promiscuous Packet.\n");
+
+	rx_ring->rx_packets++;
+	rx_ring->rx_bytes += skb->len;
+	skb->protocol = eth_type_trans(skb, ndev);
+	skb->ip_summed = CHECKSUM_NONE;
+
+	/* If rx checksum is on, and there are no
+	 * csum or frame errors.
+	 */
+	if (qdev->rx_csum &&
+		!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
+		/* TCP frame. */
+		if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
+			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+				     "TCP checksum done!\n");
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+		} else if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) &&
+				(ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_V4)) {
+			/* Unfragmented ipv4 UDP frame. */
+			struct iphdr *iph = (struct iphdr *) skb->data;
+			if (!(iph->frag_off &
+				cpu_to_be16(IP_MF|IP_OFFSET))) {
+				skb->ip_summed = CHECKSUM_UNNECESSARY;
+				netif_printk(qdev, rx_status, KERN_DEBUG,
+					     qdev->ndev,
+					     "TCP checksum done!\n");
+			}
+		}
+	}
+
+	skb_record_rx_queue(skb, rx_ring->cq_id);
+	if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
+		if (qdev->vlgrp && (vlan_id != 0xffff))
+			vlan_gro_receive(&rx_ring->napi, qdev->vlgrp,
+						vlan_id, skb);
+		else
+			napi_gro_receive(&rx_ring->napi, skb);
+	} else {
+		if (qdev->vlgrp && (vlan_id != 0xffff))
+			vlan_hwaccel_receive_skb(skb, qdev->vlgrp, vlan_id);
+		else
+			netif_receive_skb(skb);
+	}
+}
+
 static void ql_realign_skb(struct sk_buff *skb, int len)
 {
 	void *temp_addr = skb->data;
@@ -1467,7 +1735,8 @@ static struct sk_buff *ql_build_rx_skb(s
 	 */
 	if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HV &&
 	    ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HS) {
-		QPRINTK(qdev, RX_STATUS, DEBUG, "Header of %d bytes in small buffer.\n", hdr_len);
+		netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+			     "Header of %d bytes in small buffer.\n", hdr_len);
 		/*
 		 * Headers fit nicely into a small buffer.
 		 */
@@ -1486,15 +1755,16 @@ static struct sk_buff *ql_build_rx_skb(s
 	 * Handle the data buffer(s).
 	 */
 	if (unlikely(!length)) {	/* Is there data too? */
-		QPRINTK(qdev, RX_STATUS, DEBUG,
-			"No Data buffer in this packet.\n");
+		netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+			     "No Data buffer in this packet.\n");
 		return skb;
 	}
 
 	if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DS) {
 		if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HS) {
-			QPRINTK(qdev, RX_STATUS, DEBUG,
-				"Headers in small, data of %d bytes in small, combine them.\n", length);
+			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+				     "Headers in small, data of %d bytes in small, combine them.\n",
+				     length);
 			/*
 			 * Data is less than small buffer size so it's
 			 * stuffed in a small buffer.
@@ -1520,8 +1790,9 @@ static struct sk_buff *ql_build_rx_skb(s
 							maplen),
 						       PCI_DMA_FROMDEVICE);
 		} else {
-			QPRINTK(qdev, RX_STATUS, DEBUG,
-				"%d bytes in a single small buffer.\n", length);
+			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+				     "%d bytes in a single small buffer.\n",
+				     length);
 			sbq_desc = ql_get_curr_sbuf(rx_ring);
 			skb = sbq_desc->p.skb;
 			ql_realign_skb(skb, length);
@@ -1536,18 +1807,18 @@ static struct sk_buff *ql_build_rx_skb(s
 		}
 	} else if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DL) {
 		if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HS) {
-			QPRINTK(qdev, RX_STATUS, DEBUG,
-				"Header in small, %d bytes in large. Chain large to small!\n", length);
+			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+				     "Header in small, %d bytes in large. Chain large to small!\n",
+				     length);
 			/*
 			 * The data is in a single large buffer.  We
 			 * chain it to the header buffer's skb and let
 			 * it rip.
 			 */
 			lbq_desc = ql_get_curr_lchunk(qdev, rx_ring);
-			QPRINTK(qdev, RX_STATUS, DEBUG,
-				"Chaining page at offset = %d,"
-				"for %d bytes  to skb.\n",
-				lbq_desc->p.pg_chunk.offset, length);
+			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+				     "Chaining page at offset = %d, for %d bytes  to skb.\n",
+				     lbq_desc->p.pg_chunk.offset, length);
 			skb_fill_page_desc(skb, 0, lbq_desc->p.pg_chunk.page,
 						lbq_desc->p.pg_chunk.offset,
 						length);
@@ -1563,8 +1834,8 @@ static struct sk_buff *ql_build_rx_skb(s
 			lbq_desc = ql_get_curr_lchunk(qdev, rx_ring);
 			skb = netdev_alloc_skb(qdev->ndev, length);
 			if (skb == NULL) {
-				QPRINTK(qdev, PROBE, DEBUG,
-					"No skb available, drop the packet.\n");
+				netif_printk(qdev, probe, KERN_DEBUG, qdev->ndev,
+					     "No skb available, drop the packet.\n");
 				return NULL;
 			}
 			pci_unmap_page(qdev->pdev,
@@ -1573,8 +1844,9 @@ static struct sk_buff *ql_build_rx_skb(s
 				       pci_unmap_len(lbq_desc, maplen),
 				       PCI_DMA_FROMDEVICE);
 			skb_reserve(skb, NET_IP_ALIGN);
-			QPRINTK(qdev, RX_STATUS, DEBUG,
-				"%d bytes of headers and data in large. Chain page to new skb and pull tail.\n", length);
+			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+				     "%d bytes of headers and data in large. Chain page to new skb and pull tail.\n",
+				     length);
 			skb_fill_page_desc(skb, 0,
 						lbq_desc->p.pg_chunk.page,
 						lbq_desc->p.pg_chunk.offset,
@@ -1615,8 +1887,9 @@ static struct sk_buff *ql_build_rx_skb(s
 			 * a local buffer and use it to find the
 			 * pages to chain.
 			 */
-			QPRINTK(qdev, RX_STATUS, DEBUG,
-				"%d bytes of headers & data in chain of large.\n", length);
+			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+				     "%d bytes of headers & data in chain of large.\n",
+				     length);
 			skb = sbq_desc->p.skb;
 			sbq_desc->p.skb = NULL;
 			skb_reserve(skb, NET_IP_ALIGN);
@@ -1626,9 +1899,9 @@ static struct sk_buff *ql_build_rx_skb(s
 			size = (length < rx_ring->lbq_buf_size) ? length :
 				rx_ring->lbq_buf_size;
 
-			QPRINTK(qdev, RX_STATUS, DEBUG,
-				"Adding page %d to skb for %d bytes.\n",
-				i, size);
+			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+				     "Adding page %d to skb for %d bytes.\n",
+				     i, size);
 			skb_fill_page_desc(skb, i,
 						lbq_desc->p.pg_chunk.page,
 						lbq_desc->p.pg_chunk.offset,
@@ -1646,29 +1919,28 @@ static struct sk_buff *ql_build_rx_skb(s
 }
 
 /* Process an inbound completion from an rx ring. */
-static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
+static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev,
 				   struct rx_ring *rx_ring,
-				   struct ib_mac_iocb_rsp *ib_mac_rsp)
+				   struct ib_mac_iocb_rsp *ib_mac_rsp,
+				   u16 vlan_id)
 {
 	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);
 
 	skb = ql_build_rx_skb(qdev, rx_ring, ib_mac_rsp);
 	if (unlikely(!skb)) {
-		QPRINTK(qdev, RX_STATUS, DEBUG,
-			"No skb available, drop packet.\n");
+		netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+			     "No skb available, drop packet.\n");
 		rx_ring->rx_dropped++;
 		return;
 	}
 
 	/* Frame error, so drop the packet. */
 	if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) {
-		QPRINTK(qdev, DRV, ERR, "Receive error, flags2 = 0x%x\n",
-					ib_mac_rsp->flags2);
+		netif_err(qdev, drv, qdev->ndev,
+			  "Receive error, flags2 = 0x%x\n", ib_mac_rsp->flags2);
 		dev_kfree_skb_any(skb);
 		rx_ring->rx_errors++;
 		return;
@@ -1693,17 +1965,18 @@ static void ql_process_mac_rx_intr(struc
 	prefetch(skb->data);
 	skb->dev = ndev;
 	if (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) {
-		QPRINTK(qdev, RX_STATUS, DEBUG, "%s%s%s Multicast.\n",
-			(ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) ==
-			IB_MAC_IOCB_RSP_M_HASH ? "Hash" : "",
-			(ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) ==
-			IB_MAC_IOCB_RSP_M_REG ? "Registered" : "",
-			(ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) ==
-			IB_MAC_IOCB_RSP_M_PROM ? "Promiscuous" : "");
+		netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, "%s Multicast.\n",
+			     (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) ==
+			     IB_MAC_IOCB_RSP_M_HASH ? "Hash" :
+			     (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) ==
+			     IB_MAC_IOCB_RSP_M_REG ? "Registered" :
+			     (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) ==
+			     IB_MAC_IOCB_RSP_M_PROM ? "Promiscuous" : "");
 		rx_ring->rx_multicast++;
 	}
 	if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_P) {
-		QPRINTK(qdev, RX_STATUS, DEBUG, "Promiscuous Packet.\n");
+		netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+			     "Promiscuous Packet.\n");
 	}
 
 	skb->protocol = eth_type_trans(skb, ndev);
@@ -1716,8 +1989,8 @@ static void ql_process_mac_rx_intr(struc
 		!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
 		/* TCP frame. */
 		if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
-			QPRINTK(qdev, RX_STATUS, DEBUG,
-					"TCP checksum done!\n");
+			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+				     "TCP checksum done!\n");
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 		} else if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) &&
 				(ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_V4)) {
@@ -1726,8 +1999,8 @@ static void ql_process_mac_rx_intr(struc
 			if (!(iph->frag_off &
 				cpu_to_be16(IP_MF|IP_OFFSET))) {
 				skb->ip_summed = CHECKSUM_UNNECESSARY;
-				QPRINTK(qdev, RX_STATUS, DEBUG,
-						"TCP checksum done!\n");
+				netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+					     "TCP checksum done!\n");
 			}
 		}
 	}
@@ -1753,6 +2026,56 @@ static void ql_process_mac_rx_intr(struc
 	}
 }
 
+/* Process an inbound completion from an rx ring. */
+static unsigned long ql_process_mac_rx_intr(struct ql_adapter *qdev,
+					struct rx_ring *rx_ring,
+					struct ib_mac_iocb_rsp *ib_mac_rsp)
+{
+	u32 length = le32_to_cpu(ib_mac_rsp->data_len);
+	u16 vlan_id = (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) ?
+			((le16_to_cpu(ib_mac_rsp->vlan_id) &
+			IB_MAC_IOCB_RSP_VLAN_MASK)) : 0xffff;
+
+	QL_DUMP_IB_MAC_RSP(ib_mac_rsp);
+
+	if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HV) {
+		/* The data and headers are split into
+		 * separate buffers.
+		 */
+		ql_process_mac_split_rx_intr(qdev, rx_ring, ib_mac_rsp,
+						vlan_id);
+	} else if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DS) {
+		/* The data fit in a single small buffer.
+		 * Allocate a new skb, copy the data and
+		 * return the buffer to the free pool.
+		 */
+		ql_process_mac_rx_skb(qdev, rx_ring, ib_mac_rsp,
+						length, vlan_id);
+	} else if ((ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DL) &&
+		!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK) &&
+		(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T)) {
+		/* TCP packet in a page chunk that's been checksummed.
+		 * Tack it on to our GRO skb and let it go.
+		 */
+		ql_process_mac_rx_gro_page(qdev, rx_ring, ib_mac_rsp,
+						length, vlan_id);
+	} else if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DL) {
+		/* Non-TCP packet in a page chunk. Allocate an
+		 * skb, tack it on frags, and send it up.
+		 */
+		ql_process_mac_rx_page(qdev, rx_ring, ib_mac_rsp,
+						length, vlan_id);
+	} else {
+		/* Non-TCP/UDP large frames that span multiple buffers
+		 * can be processed corrrectly by the split frame logic.
+		 */
+		ql_process_mac_split_rx_intr(qdev, rx_ring, ib_mac_rsp,
+						vlan_id);
+	}
+
+	return (unsigned long)length;
+}
+
 /* Process an outbound completion from an rx ring. */
 static void ql_process_mac_tx_intr(struct ql_adapter *qdev,
 				   struct ob_mac_iocb_rsp *mac_rsp)
@@ -1774,20 +2097,20 @@ static void ql_process_mac_tx_intr(struc
 					OB_MAC_IOCB_RSP_L |
 					OB_MAC_IOCB_RSP_P | OB_MAC_IOCB_RSP_B))) {
 		if (mac_rsp->flags1 & OB_MAC_IOCB_RSP_E) {
-			QPRINTK(qdev, TX_DONE, WARNING,
-				"Total descriptor length did not match transfer length.\n");
+			netif_warn(qdev, tx_done, qdev->ndev,
+				   "Total descriptor length did not match transfer length.\n");
 		}
 		if (mac_rsp->flags1 & OB_MAC_IOCB_RSP_S) {
-			QPRINTK(qdev, TX_DONE, WARNING,
-				"Frame too short to be legal, not sent.\n");
+			netif_warn(qdev, tx_done, qdev->ndev,
+				   "Frame too short to be valid, not sent.\n");
 		}
 		if (mac_rsp->flags1 & OB_MAC_IOCB_RSP_L) {
-			QPRINTK(qdev, TX_DONE, WARNING,
-				"Frame too long, but sent anyway.\n");
+			netif_warn(qdev, tx_done, qdev->ndev,
+				   "Frame too long, but sent anyway.\n");
 		}
 		if (mac_rsp->flags1 & OB_MAC_IOCB_RSP_B) {
-			QPRINTK(qdev, TX_DONE, WARNING,
-				"PCI backplane error. Frame not sent.\n");
+			netif_warn(qdev, tx_done, qdev->ndev,
+				   "PCI backplane error. Frame not sent.\n");
 		}
 	}
 	atomic_inc(&tx_ring->tx_count);
@@ -1817,33 +2140,35 @@ static void ql_process_chip_ae_intr(stru
 {
 	switch (ib_ae_rsp->event) {
 	case MGMT_ERR_EVENT:
-		QPRINTK(qdev, RX_ERR, ERR,
-			"Management Processor Fatal Error.\n");
+		netif_err(qdev, rx_err, qdev->ndev,
+			  "Management Processor Fatal Error.\n");
 		ql_queue_fw_error(qdev);
 		return;
 
 	case CAM_LOOKUP_ERR_EVENT:
-		QPRINTK(qdev, LINK, ERR,
-			"Multiple CAM hits lookup occurred.\n");
-		QPRINTK(qdev, DRV, ERR, "This event shouldn't occur.\n");
+		netif_err(qdev, link, qdev->ndev,
+			  "Multiple CAM hits lookup occurred.\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "This event shouldn't occur.\n");
 		ql_queue_asic_error(qdev);
 		return;
 
 	case SOFT_ECC_ERROR_EVENT:
-		QPRINTK(qdev, RX_ERR, ERR, "Soft ECC error detected.\n");
+		netif_err(qdev, rx_err, qdev->ndev,
+			  "Soft ECC error detected.\n");
 		ql_queue_asic_error(qdev);
 		break;
 
 	case PCI_ERR_ANON_BUF_RD:
-		QPRINTK(qdev, RX_ERR, ERR,
-			"PCI error occurred when reading anonymous buffers from rx_ring %d.\n",
-			ib_ae_rsp->q_id);
+		netif_err(qdev, rx_err, qdev->ndev,
+			  "PCI error occurred when reading anonymous buffers from rx_ring %d.\n",
+			  ib_ae_rsp->q_id);
 		ql_queue_asic_error(qdev);
 		break;
 
 	default:
-		QPRINTK(qdev, DRV, ERR, "Unexpected event %d.\n",
-			ib_ae_rsp->event);
+		netif_err(qdev, drv, qdev->ndev, "Unexpected event %d.\n",
+			  ib_ae_rsp->event);
 		ql_queue_asic_error(qdev);
 		break;
 	}
@@ -1860,9 +2185,9 @@ static int ql_clean_outbound_rx_ring(str
 	/* While there are entries in the completion queue. */
 	while (prod != rx_ring->cnsmr_idx) {
 
-		QPRINTK(qdev, RX_STATUS, DEBUG,
-			"cq_id = %d, prod = %d, cnsmr = %d.\n.", rx_ring->cq_id,
-			prod, rx_ring->cnsmr_idx);
+		netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+			     "cq_id = %d, prod = %d, cnsmr = %d.\n.",
+			     rx_ring->cq_id, prod, rx_ring->cnsmr_idx);
 
 		net_rsp = (struct ob_mac_iocb_rsp *)rx_ring->curr_entry;
 		rmb();
@@ -1873,9 +2198,9 @@ static int ql_clean_outbound_rx_ring(str
 			ql_process_mac_tx_intr(qdev, net_rsp);
 			break;
 		default:
-			QPRINTK(qdev, RX_STATUS, DEBUG,
-				"Hit default case, not handled! dropping the packet, opcode = %x.\n",
-				net_rsp->opcode);
+			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+				     "Hit default case, not handled! dropping the packet, opcode = %x.\n",
+				     net_rsp->opcode);
 		}
 		count++;
 		ql_update_cq(rx_ring);
@@ -1907,9 +2232,9 @@ static int ql_clean_inbound_rx_ring(stru
 	/* While there are entries in the completion queue. */
 	while (prod != rx_ring->cnsmr_idx) {
 
-		QPRINTK(qdev, RX_STATUS, DEBUG,
-			"cq_id = %d, prod = %d, cnsmr = %d.\n.", rx_ring->cq_id,
-			prod, rx_ring->cnsmr_idx);
+		netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+			     "cq_id = %d, prod = %d, cnsmr = %d.\n.",
+			     rx_ring->cq_id, prod, rx_ring->cnsmr_idx);
 
 		net_rsp = rx_ring->curr_entry;
 		rmb();
@@ -1925,11 +2250,10 @@ static int ql_clean_inbound_rx_ring(stru
 						net_rsp);
 			break;
 		default:
-			{
-				QPRINTK(qdev, RX_STATUS, DEBUG,
-					"Hit default case, not handled! dropping the packet, opcode = %x.\n",
-					net_rsp->opcode);
-			}
+			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+				     "Hit default case, not handled! dropping the packet, opcode = %x.\n",
+				     net_rsp->opcode);
+			break;
 		}
 		count++;
 		ql_update_cq(rx_ring);
@@ -1950,8 +2274,8 @@ static int ql_napi_poll_msix(struct napi
 	int i, work_done = 0;
 	struct intr_context *ctx = &qdev->intr_context[rx_ring->cq_id];
 
-	QPRINTK(qdev, RX_STATUS, DEBUG, "Enter, NAPI POLL cq_id = %d.\n",
-		rx_ring->cq_id);
+	netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
+		     "Enter, NAPI POLL cq_id = %d.\n", rx_ring->cq_id);
 
 	/* Service the TX rings first.  They start
 	 * right after the RSS rings. */
@@ -1963,9 +2287,9 @@ static int ql_napi_poll_msix(struct napi
 		if ((ctx->irq_mask & (1 << trx_ring->cq_id)) &&
 			(ql_read_sh_reg(trx_ring->prod_idx_sh_reg) !=
 					trx_ring->cnsmr_idx)) {
-			QPRINTK(qdev, INTR, DEBUG,
-				"%s: Servicing TX completion ring %d.\n",
-				__func__, trx_ring->cq_id);
+			netif_printk(qdev, intr, KERN_DEBUG, qdev->ndev,
+				     "%s: Servicing TX completion ring %d.\n",
+				     __func__, trx_ring->cq_id);
 			ql_clean_outbound_rx_ring(trx_ring);
 		}
 	}
@@ -1975,9 +2299,9 @@ static int ql_napi_poll_msix(struct napi
 	 */
 	if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) !=
 					rx_ring->cnsmr_idx) {
-		QPRINTK(qdev, INTR, DEBUG,
-			"%s: Servicing RX completion ring %d.\n",
-			__func__, rx_ring->cq_id);
+		netif_printk(qdev, intr, KERN_DEBUG, qdev->ndev,
+			     "%s: Servicing RX completion ring %d.\n",
+			     __func__, rx_ring->cq_id);
 		work_done = ql_clean_inbound_rx_ring(rx_ring, budget);
 	}
 
@@ -1994,12 +2318,13 @@ static void qlge_vlan_rx_register(struct
 
 	qdev->vlgrp = grp;
 	if (grp) {
-		QPRINTK(qdev, IFUP, DEBUG, "Turning on VLAN in NIC_RCV_CFG.\n");
+		netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+			     "Turning on VLAN in NIC_RCV_CFG.\n");
 		ql_write32(qdev, NIC_RCV_CFG, NIC_RCV_CFG_VLAN_MASK |
 			   NIC_RCV_CFG_VLAN_MATCH_AND_NON);
 	} else {
-		QPRINTK(qdev, IFUP, DEBUG,
-			"Turning off VLAN in NIC_RCV_CFG.\n");
+		netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+			     "Turning off VLAN in NIC_RCV_CFG.\n");
 		ql_write32(qdev, NIC_RCV_CFG, NIC_RCV_CFG_VLAN_MASK);
 	}
 }
@@ -2015,7 +2340,8 @@ static void qlge_vlan_rx_add_vid(struct
 		return;
 	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");
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Failed to init vlan address.\n");
 	}
 	ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 }
@@ -2032,7 +2358,8 @@ static void qlge_vlan_rx_kill_vid(struct
 
 	if (ql_set_mac_addr_reg
 	    (qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) {
-		QPRINTK(qdev, IFUP, ERR, "Failed to clear vlan address.\n");
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Failed to clear vlan address.\n");
 	}
 	ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 
@@ -2061,7 +2388,8 @@ static irqreturn_t qlge_isr(int irq, voi
 
 	spin_lock(&qdev->hw_lock);
 	if (atomic_read(&qdev->intr_context[0].irq_cnt)) {
-		QPRINTK(qdev, INTR, DEBUG, "Shared Interrupt, Not ours!\n");
+		netif_printk(qdev, intr, KERN_DEBUG, qdev->ndev,
+			     "Shared Interrupt, Not ours!\n");
 		spin_unlock(&qdev->hw_lock);
 		return IRQ_NONE;
 	}
@@ -2074,10 +2402,11 @@ static irqreturn_t qlge_isr(int irq, voi
 	 */
 	if (var & STS_FE) {
 		ql_queue_asic_error(qdev);
-		QPRINTK(qdev, INTR, ERR, "Got fatal error, STS = %x.\n", var);
+		netif_err(qdev, intr, qdev->ndev,
+			  "Got fatal error, STS = %x.\n", var);
 		var = ql_read32(qdev, ERR_STS);
-		QPRINTK(qdev, INTR, ERR,
-			"Resetting chip. Error Status Register = 0x%x\n", var);
+		netif_err(qdev, intr, qdev->ndev,
+			  "Resetting chip. Error Status Register = 0x%x\n", var);
 		return IRQ_HANDLED;
 	}
 
@@ -2090,7 +2419,8 @@ static irqreturn_t qlge_isr(int irq, voi
 		 * We've got an async event or mailbox completion.
 		 * Handle it and clear the source of the interrupt.
 		 */
-		QPRINTK(qdev, INTR, ERR, "Got MPI processor interrupt.\n");
+		netif_err(qdev, intr, qdev->ndev,
+			  "Got MPI processor interrupt.\n");
 		ql_disable_completion_interrupt(qdev, intr_context->intr);
 		ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
 		queue_delayed_work_on(smp_processor_id(),
@@ -2105,8 +2435,8 @@ static irqreturn_t qlge_isr(int irq, voi
 	 */
 	var = ql_read32(qdev, ISR1);
 	if (var & intr_context->irq_mask) {
-		QPRINTK(qdev, INTR, INFO,
-			"Waking handler for rx_ring[0].\n");
+		netif_info(qdev, intr, qdev->ndev,
+			   "Waking handler for rx_ring[0].\n");
 		ql_disable_completion_interrupt(qdev, intr_context->intr);
 		napi_schedule(&rx_ring->napi);
 		work_done++;
@@ -2203,9 +2533,9 @@ static netdev_tx_t qlge_send(struct sk_b
 		return NETDEV_TX_OK;
 
 	if (unlikely(atomic_read(&tx_ring->tx_count) < 2)) {
-		QPRINTK(qdev, TX_QUEUED, INFO,
-			"%s: shutting down tx queue %d du to lack of resources.\n",
-			__func__, tx_ring_idx);
+		netif_info(qdev, tx_queued, qdev->ndev,
+			   "%s: shutting down tx queue %d du to lack of resources.\n",
+			   __func__, tx_ring_idx);
 		netif_stop_subqueue(ndev, tx_ring->wq_id);
 		atomic_inc(&tx_ring->queue_stopped);
 		tx_ring->tx_errors++;
@@ -2226,8 +2556,8 @@ static netdev_tx_t qlge_send(struct sk_b
 	mac_iocb_ptr->frame_len = cpu_to_le16((u16) skb->len);
 
 	if (qdev->vlgrp && vlan_tx_tag_present(skb)) {
-		QPRINTK(qdev, TX_QUEUED, DEBUG, "Adding a vlan tag %d.\n",
-			vlan_tx_tag_get(skb));
+		netif_printk(qdev, tx_queued, KERN_DEBUG, qdev->ndev,
+			     "Adding a vlan tag %d.\n", vlan_tx_tag_get(skb));
 		mac_iocb_ptr->flags3 |= OB_MAC_IOCB_V;
 		mac_iocb_ptr->vlan_tci = cpu_to_le16(vlan_tx_tag_get(skb));
 	}
@@ -2241,8 +2571,8 @@ static netdev_tx_t qlge_send(struct sk_b
 	}
 	if (ql_map_send(qdev, mac_iocb_ptr, skb, tx_ring_desc) !=
 			NETDEV_TX_OK) {
-		QPRINTK(qdev, TX_QUEUED, ERR,
-				"Could not map the segments.\n");
+		netif_err(qdev, tx_queued, qdev->ndev,
+			  "Could not map the segments.\n");
 		tx_ring->tx_errors++;
 		return NETDEV_TX_BUSY;
 	}
@@ -2253,8 +2583,9 @@ static netdev_tx_t qlge_send(struct sk_b
 	wmb();
 
 	ql_write_db_reg(tx_ring->prod_idx, tx_ring->prod_idx_db_reg);
-	QPRINTK(qdev, TX_QUEUED, DEBUG, "tx queued, slot %d, len %d\n",
-		tx_ring->prod_idx, skb->len);
+	netif_printk(qdev, tx_queued, KERN_DEBUG, qdev->ndev,
+		     "tx queued, slot %d, len %d\n",
+		     tx_ring->prod_idx, skb->len);
 
 	atomic_dec(&tx_ring->tx_count);
 	return NETDEV_TX_OK;
@@ -2285,8 +2616,8 @@ static int ql_alloc_shadow_space(struct
 	    pci_alloc_consistent(qdev->pdev,
 				 PAGE_SIZE, &qdev->rx_ring_shadow_reg_dma);
 	if (qdev->rx_ring_shadow_reg_area == NULL) {
-		QPRINTK(qdev, IFUP, ERR,
-			"Allocation of RX shadow space failed.\n");
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Allocation of RX shadow space failed.\n");
 		return -ENOMEM;
 	}
 	memset(qdev->rx_ring_shadow_reg_area, 0, PAGE_SIZE);
@@ -2294,8 +2625,8 @@ static int ql_alloc_shadow_space(struct
 	    pci_alloc_consistent(qdev->pdev, PAGE_SIZE,
 				 &qdev->tx_ring_shadow_reg_dma);
 	if (qdev->tx_ring_shadow_reg_area == NULL) {
-		QPRINTK(qdev, IFUP, ERR,
-			"Allocation of TX shadow space failed.\n");
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Allocation of TX shadow space failed.\n");
 		goto err_wqp_sh_area;
 	}
 	memset(qdev->tx_ring_shadow_reg_area, 0, PAGE_SIZE);
@@ -2349,7 +2680,7 @@ static int ql_alloc_tx_resources(struct
 
 	if ((tx_ring->wq_base == NULL) ||
 	    tx_ring->wq_base_dma & WQ_ADDR_ALIGN) {
-		QPRINTK(qdev, IFUP, ERR, "tx_ring alloc failed.\n");
+		netif_err(qdev, ifup, qdev->ndev, "tx_ring alloc failed.\n");
 		return -ENOMEM;
 	}
 	tx_ring->q =
@@ -2400,7 +2731,8 @@ static void ql_free_sbq_buffers(struct q
 	for (i = 0; i < rx_ring->sbq_len; i++) {
 		sbq_desc = &rx_ring->sbq[i];
 		if (sbq_desc == NULL) {
-			QPRINTK(qdev, IFUP, ERR, "sbq_desc %d is NULL.\n", i);
+			netif_err(qdev, ifup, qdev->ndev,
+				  "sbq_desc %d is NULL.\n", i);
 			return;
 		}
 		if (sbq_desc->p.skb) {
@@ -2527,7 +2859,7 @@ static int ql_alloc_rx_resources(struct
 				 &rx_ring->cq_base_dma);
 
 	if (rx_ring->cq_base == NULL) {
-		QPRINTK(qdev, IFUP, ERR, "rx_ring alloc failed.\n");
+		netif_err(qdev, ifup, qdev->ndev, "rx_ring alloc failed.\n");
 		return -ENOMEM;
 	}
 
@@ -2540,8 +2872,8 @@ static int ql_alloc_rx_resources(struct
 					 &rx_ring->sbq_base_dma);
 
 		if (rx_ring->sbq_base == NULL) {
-			QPRINTK(qdev, IFUP, ERR,
-				"Small buffer queue allocation failed.\n");
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Small buffer queue allocation failed.\n");
 			goto err_mem;
 		}
 
@@ -2552,8 +2884,8 @@ static int ql_alloc_rx_resources(struct
 		    kmalloc(rx_ring->sbq_len * sizeof(struct bq_desc),
 			    GFP_KERNEL);
 		if (rx_ring->sbq == NULL) {
-			QPRINTK(qdev, IFUP, ERR,
-				"Small buffer queue control block allocation failed.\n");
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Small buffer queue control block allocation failed.\n");
 			goto err_mem;
 		}
 
@@ -2569,8 +2901,8 @@ static int ql_alloc_rx_resources(struct
 					 &rx_ring->lbq_base_dma);
 
 		if (rx_ring->lbq_base == NULL) {
-			QPRINTK(qdev, IFUP, ERR,
-				"Large buffer queue allocation failed.\n");
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Large buffer queue allocation failed.\n");
 			goto err_mem;
 		}
 		/*
@@ -2580,8 +2912,8 @@ static int ql_alloc_rx_resources(struct
 		    kmalloc(rx_ring->lbq_len * sizeof(struct bq_desc),
 			    GFP_KERNEL);
 		if (rx_ring->lbq == NULL) {
-			QPRINTK(qdev, IFUP, ERR,
-				"Large buffer queue control block allocation failed.\n");
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Large buffer queue control block allocation failed.\n");
 			goto err_mem;
 		}
 
@@ -2610,10 +2942,10 @@ static void ql_tx_ring_clean(struct ql_a
 		for (i = 0; i < tx_ring->wq_len; i++) {
 			tx_ring_desc = &tx_ring->q[i];
 			if (tx_ring_desc && tx_ring_desc->skb) {
-				QPRINTK(qdev, IFDOWN, ERR,
-				"Freeing lost SKB %p, from queue %d, index %d.\n",
-					tx_ring_desc->skb, j,
-					tx_ring_desc->index);
+				netif_err(qdev, ifdown, qdev->ndev,
+					  "Freeing lost SKB %p, from queue %d, index %d.\n",
+					  tx_ring_desc->skb, j,
+					  tx_ring_desc->index);
 				ql_unmap_send(qdev, tx_ring_desc,
 					      tx_ring_desc->map_cnt);
 				dev_kfree_skb(tx_ring_desc->skb);
@@ -2644,16 +2976,16 @@ static int ql_alloc_mem_resources(struct
 
 	for (i = 0; i < qdev->rx_ring_count; i++) {
 		if (ql_alloc_rx_resources(qdev, &qdev->rx_ring[i]) != 0) {
-			QPRINTK(qdev, IFUP, ERR,
-				"RX resource allocation failed.\n");
+			netif_err(qdev, ifup, qdev->ndev,
+				  "RX resource allocation failed.\n");
 			goto err_mem;
 		}
 	}
 	/* Allocate tx queue resources */
 	for (i = 0; i < qdev->tx_ring_count; i++) {
 		if (ql_alloc_tx_resources(qdev, &qdev->tx_ring[i]) != 0) {
-			QPRINTK(qdev, IFUP, ERR,
-				"TX resource allocation failed.\n");
+			netif_err(qdev, ifup, qdev->ndev,
+				  "TX resource allocation failed.\n");
 			goto err_mem;
 		}
 	}
@@ -2788,14 +3120,15 @@ static int ql_start_rx_ring(struct ql_ad
 		cqicb->pkt_delay = cpu_to_le16(qdev->rx_max_coalesced_frames);
 		break;
 	default:
-		QPRINTK(qdev, IFUP, DEBUG, "Invalid rx_ring->type = %d.\n",
-			rx_ring->type);
+		netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+			     "Invalid rx_ring->type = %d.\n", rx_ring->type);
 	}
-	QPRINTK(qdev, IFUP, DEBUG, "Initializing rx work queue.\n");
+	netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+		     "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");
+		netif_err(qdev, ifup, qdev->ndev, "Failed to load CQICB.\n");
 		return err;
 	}
 	return err;
@@ -2841,10 +3174,11 @@ static int ql_start_tx_ring(struct ql_ad
 	err = ql_write_cfg(qdev, wqicb, sizeof(*wqicb), CFG_LRQ,
 			   (u16) tx_ring->wq_id);
 	if (err) {
-		QPRINTK(qdev, IFUP, ERR, "Failed to load tx_ring.\n");
+		netif_err(qdev, ifup, qdev->ndev, "Failed to load tx_ring.\n");
 		return err;
 	}
-	QPRINTK(qdev, IFUP, DEBUG, "Successfully loaded WQICB.\n");
+	netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+		     "Successfully loaded WQICB.\n");
 	return err;
 }
 
@@ -2898,15 +3232,15 @@ static void ql_enable_msix(struct ql_ada
 		if (err < 0) {
 			kfree(qdev->msi_x_entry);
 			qdev->msi_x_entry = NULL;
-			QPRINTK(qdev, IFUP, WARNING,
-				"MSI-X Enable failed, trying MSI.\n");
+			netif_warn(qdev, ifup, qdev->ndev,
+				   "MSI-X Enable failed, trying MSI.\n");
 			qdev->intr_count = 1;
 			qlge_irq_type = MSI_IRQ;
 		} else if (err == 0) {
 			set_bit(QL_MSIX_ENABLED, &qdev->flags);
-			QPRINTK(qdev, IFUP, INFO,
-				"MSI-X Enabled, got %d vectors.\n",
-				qdev->intr_count);
+			netif_info(qdev, ifup, qdev->ndev,
+				   "MSI-X Enabled, got %d vectors.\n",
+				   qdev->intr_count);
 			return;
 		}
 	}
@@ -2915,13 +3249,14 @@ msi:
 	if (qlge_irq_type == MSI_IRQ) {
 		if (!pci_enable_msi(qdev->pdev)) {
 			set_bit(QL_MSI_ENABLED, &qdev->flags);
-			QPRINTK(qdev, IFUP, INFO,
-				"Running with MSI interrupts.\n");
+			netif_info(qdev, ifup, qdev->ndev,
+				   "Running with MSI interrupts.\n");
 			return;
 		}
 	}
 	qlge_irq_type = LEG_IRQ;
-	QPRINTK(qdev, IFUP, DEBUG, "Running with legacy interrupts.\n");
+	netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+		     "Running with legacy interrupts.\n");
 }
 
 /* Each vector services 1 RSS ring and and 1 or more
@@ -3093,12 +3428,12 @@ 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, DEBUG,
-					"freeing msix interrupt %d.\n", i);
+				netif_printk(qdev, ifdown, KERN_DEBUG, qdev->ndev,
+					     "freeing msix interrupt %d.\n", i);
 			} else {
 				free_irq(qdev->pdev->irq, &qdev->rx_ring[0]);
-				QPRINTK(qdev, IFDOWN, DEBUG,
-					"freeing msi interrupt %d.\n", i);
+				netif_printk(qdev, ifdown, KERN_DEBUG, qdev->ndev,
+					     "freeing msi interrupt %d.\n", i);
 			}
 		}
 	}
@@ -3123,32 +3458,33 @@ static int ql_request_irq(struct ql_adap
 					     intr_context->name,
 					     &qdev->rx_ring[i]);
 			if (status) {
-				QPRINTK(qdev, IFUP, ERR,
-					"Failed request for MSIX interrupt %d.\n",
-					i);
+				netif_err(qdev, ifup, qdev->ndev,
+					  "Failed request for MSIX interrupt %d.\n",
+					  i);
 				goto err_irq;
 			} else {
-				QPRINTK(qdev, IFUP, DEBUG,
-					"Hooked intr %d, queue type %s%s%s, with name %s.\n",
-					i,
-					qdev->rx_ring[i].type ==
-					DEFAULT_Q ? "DEFAULT_Q" : "",
-					qdev->rx_ring[i].type ==
-					TX_Q ? "TX_Q" : "",
-					qdev->rx_ring[i].type ==
-					RX_Q ? "RX_Q" : "", intr_context->name);
+				netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+					     "Hooked intr %d, queue type %s, with name %s.\n",
+					     i,
+					     qdev->rx_ring[i].type == DEFAULT_Q ?
+					     "DEFAULT_Q" :
+					     qdev->rx_ring[i].type == TX_Q ?
+					     "TX_Q" :
+					     qdev->rx_ring[i].type == RX_Q ?
+					     "RX_Q" : "",
+					     intr_context->name);
 			}
 		} else {
-			QPRINTK(qdev, IFUP, DEBUG,
-				"trying msi or legacy interrupts.\n");
-			QPRINTK(qdev, IFUP, DEBUG,
-				"%s: irq = %d.\n", __func__, pdev->irq);
-			QPRINTK(qdev, IFUP, DEBUG,
-				"%s: context->name = %s.\n", __func__,
-			       intr_context->name);
-			QPRINTK(qdev, IFUP, DEBUG,
-				"%s: dev_id = 0x%p.\n", __func__,
-			       &qdev->rx_ring[0]);
+			netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+				     "trying msi or legacy interrupts.\n");
+			netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+				     "%s: irq = %d.\n", __func__, pdev->irq);
+			netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+				     "%s: context->name = %s.\n", __func__,
+				     intr_context->name);
+			netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+				     "%s: dev_id = 0x%p.\n", __func__,
+				     &qdev->rx_ring[0]);
 			status =
 			    request_irq(pdev->irq, qlge_isr,
 					test_bit(QL_MSI_ENABLED,
@@ -3158,20 +3494,20 @@ static int ql_request_irq(struct ql_adap
 			if (status)
 				goto err_irq;
 
-			QPRINTK(qdev, IFUP, ERR,
-				"Hooked intr %d, queue type %s%s%s, with name %s.\n",
-				i,
-				qdev->rx_ring[0].type ==
-				DEFAULT_Q ? "DEFAULT_Q" : "",
-				qdev->rx_ring[0].type == TX_Q ? "TX_Q" : "",
-				qdev->rx_ring[0].type == RX_Q ? "RX_Q" : "",
-				intr_context->name);
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Hooked intr %d, queue type %s, with name %s.\n",
+				  i,
+				  qdev->rx_ring[0].type == DEFAULT_Q ?
+				  "DEFAULT_Q" :
+				  qdev->rx_ring[0].type == TX_Q ? "TX_Q" :
+				  qdev->rx_ring[0].type == RX_Q ? "RX_Q" : "",
+				  intr_context->name);
 		}
 		intr_context->hooked = 1;
 	}
 	return status;
 err_irq:
-	QPRINTK(qdev, IFUP, ERR, "Failed to get the interrupts!!!/n");
+	netif_err(qdev, ifup, qdev->ndev, "Failed to get the interrupts!!!/n");
 	ql_free_irq(qdev);
 	return status;
 }
@@ -3205,14 +3541,15 @@ static int ql_start_rss(struct ql_adapte
 	memcpy((void *)&ricb->ipv6_hash_key[0], init_hash_seed, 40);
 	memcpy((void *)&ricb->ipv4_hash_key[0], init_hash_seed, 16);
 
-	QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n");
+	netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, "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");
+		netif_err(qdev, ifup, qdev->ndev, "Failed to load RICB.\n");
 		return status;
 	}
-	QPRINTK(qdev, IFUP, DEBUG, "Successfully loaded RICB.\n");
+	netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+		     "Successfully loaded RICB.\n");
 	return status;
 }
 
@@ -3227,9 +3564,8 @@ static int ql_clear_routing_entries(stru
 	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");
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Failed to init routing register for CAM packets.\n");
 			break;
 		}
 	}
@@ -3253,14 +3589,14 @@ static int ql_route_initialize(struct ql
 
 	status = ql_set_routing_reg(qdev, RT_IDX_ALL_ERR_SLOT, RT_IDX_ERR, 1);
 	if (status) {
-		QPRINTK(qdev, IFUP, ERR,
-			"Failed to init routing register for error packets.\n");
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Failed to init routing register for error packets.\n");
 		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");
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Failed to init routing register for broadcast packets.\n");
 		goto exit;
 	}
 	/* If we have more than one inbound queue, then turn on RSS in the
@@ -3270,8 +3606,8 @@ static int ql_route_initialize(struct ql
 		status = ql_set_routing_reg(qdev, RT_IDX_RSS_MATCH_SLOT,
 					RT_IDX_RSS_MATCH, 1);
 		if (status) {
-			QPRINTK(qdev, IFUP, ERR,
-				"Failed to init routing register for MATCH RSS packets.\n");
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Failed to init routing register for MATCH RSS packets.\n");
 			goto exit;
 		}
 	}
@@ -3279,8 +3615,8 @@ static int ql_route_initialize(struct ql
 	status = ql_set_routing_reg(qdev, RT_IDX_CAM_HIT_SLOT,
 				    RT_IDX_CAM_HIT, 1);
 	if (status)
-		QPRINTK(qdev, IFUP, ERR,
-			"Failed to init routing register for CAM packets.\n");
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Failed to init routing register for CAM packets.\n");
 exit:
 	ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
 	return status;
@@ -3298,13 +3634,13 @@ int ql_cam_route_initialize(struct ql_ad
 	set &= qdev->port_link_up;
 	status = ql_set_mac_addr(qdev, set);
 	if (status) {
-		QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n");
+		netif_err(qdev, ifup, qdev->ndev, "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");
+		netif_err(qdev, ifup, qdev->ndev, "Failed to init routing table.\n");
 
 	return status;
 }
@@ -3332,15 +3668,15 @@ static int ql_adapter_initialize(struct
 
 	/* Enable the function, set pagesize, enable error checking. */
 	value = FSC_FE | FSC_EPC_INBOUND | FSC_EPC_OUTBOUND |
-	    FSC_EC | FSC_VM_PAGE_4K | FSC_SH;
+	    FSC_EC | FSC_VM_PAGE_4K;
+	value |= SPLT_SETTING;
 
 	/* Set/clear header splitting. */
 	mask = FSC_VM_PAGESIZE_MASK |
 	    FSC_DBL_MASK | FSC_DBRST_MASK | (value << 16);
 	ql_write32(qdev, FSC, mask | value);
 
-	ql_write32(qdev, SPLT_HDR, SPLT_HDR_EP |
-		min(SMALL_BUF_MAP_SIZE, MAX_SPLIT_SIZE));
+	ql_write32(qdev, SPLT_HDR, SPLT_LEN);
 
 	/* Set RX packet routing to use port/pci function on which the
 	 * packet arrived on in addition to usual frame routing.
@@ -3369,8 +3705,8 @@ static int ql_adapter_initialize(struct
 	for (i = 0; i < qdev->rx_ring_count; i++) {
 		status = ql_start_rx_ring(qdev, &qdev->rx_ring[i]);
 		if (status) {
-			QPRINTK(qdev, IFUP, ERR,
-				"Failed to start rx ring[%d].\n", i);
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Failed to start rx ring[%d].\n", i);
 			return status;
 		}
 	}
@@ -3381,7 +3717,7 @@ static int ql_adapter_initialize(struct
 	if (qdev->rss_ring_count > 1) {
 		status = ql_start_rss(qdev);
 		if (status) {
-			QPRINTK(qdev, IFUP, ERR, "Failed to start RSS.\n");
+			netif_err(qdev, ifup, qdev->ndev, "Failed to start RSS.\n");
 			return status;
 		}
 	}
@@ -3390,8 +3726,8 @@ static int ql_adapter_initialize(struct
 	for (i = 0; i < qdev->tx_ring_count; i++) {
 		status = ql_start_tx_ring(qdev, &qdev->tx_ring[i]);
 		if (status) {
-			QPRINTK(qdev, IFUP, ERR,
-				"Failed to start tx ring[%d].\n", i);
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Failed to start tx ring[%d].\n", i);
 			return status;
 		}
 	}
@@ -3399,20 +3735,20 @@ static int ql_adapter_initialize(struct
 	/* Initialize the port and set the max framesize. */
 	status = qdev->nic_ops->port_initialize(qdev);
 	if (status)
-		QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n");
+		netif_err(qdev, ifup, qdev->ndev, "Failed to start port.\n");
 
 	/* Set up the MAC address and frame routing filter. */
 	status = ql_cam_route_initialize(qdev);
 	if (status) {
-		QPRINTK(qdev, IFUP, ERR,
-				"Failed to init CAM/Routing tables.\n");
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Failed to init CAM/Routing tables.\n");
 		return status;
 	}
 
 	/* Start NAPI for the RSS queues. */
 	for (i = 0; i < qdev->rss_ring_count; i++) {
-		QPRINTK(qdev, IFUP, DEBUG, "Enabling NAPI for rx_ring[%d].\n",
-			i);
+		netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+			     "Enabling NAPI for rx_ring[%d].\n", i);
 		napi_enable(&qdev->rx_ring[i].napi);
 	}
 
@@ -3429,7 +3765,7 @@ static int ql_adapter_reset(struct ql_ad
 	/* Clear all the entries in the routing table. */
 	status = ql_clear_routing_entries(qdev);
 	if (status) {
-		QPRINTK(qdev, IFUP, ERR, "Failed to clear routing bits.\n");
+		netif_err(qdev, ifup, qdev->ndev, "Failed to clear routing bits.\n");
 		return status;
 	}
 
@@ -3452,8 +3788,8 @@ static int ql_adapter_reset(struct ql_ad
 	} while (time_before(jiffies, end_jiffies));
 
 	if (value & RST_FO_FR) {
-		QPRINTK(qdev, IFDOWN, ERR,
-			"ETIMEDOUT!!! errored out of resetting the chip!\n");
+		netif_err(qdev, ifdown, qdev->ndev,
+			  "ETIMEDOUT!!! errored out of resetting the chip!\n");
 		status = -ETIMEDOUT;
 	}
 
@@ -3466,16 +3802,17 @@ static void ql_display_dev_info(struct n
 {
 	struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
 
-	QPRINTK(qdev, PROBE, INFO,
-		"Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, "
-		"XG Roll = %d, XG Rev = %d.\n",
-		qdev->func,
-		qdev->port,
-		qdev->chip_rev_id & 0x0000000f,
-		qdev->chip_rev_id >> 4 & 0x0000000f,
-		qdev->chip_rev_id >> 8 & 0x0000000f,
-		qdev->chip_rev_id >> 12 & 0x0000000f);
-	QPRINTK(qdev, PROBE, INFO, "MAC address %pM\n", ndev->dev_addr);
+	netif_info(qdev, probe, qdev->ndev,
+		   "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, "
+		   "XG Roll = %d, XG Rev = %d.\n",
+		   qdev->func,
+		   qdev->port,
+		   qdev->chip_rev_id & 0x0000000f,
+		   qdev->chip_rev_id >> 4 & 0x0000000f,
+		   qdev->chip_rev_id >> 8 & 0x0000000f,
+		   qdev->chip_rev_id >> 12 & 0x0000000f);
+	netif_info(qdev, probe, qdev->ndev,
+		   "MAC address %pM\n", ndev->dev_addr);
 }
 
 int ql_wol(struct ql_adapter *qdev)
@@ -3492,23 +3829,23 @@ int ql_wol(struct ql_adapter *qdev)
 
 	if (qdev->wol & (WAKE_ARP | WAKE_MAGICSECURE | WAKE_PHY | WAKE_UCAST |
 			WAKE_MCAST | WAKE_BCAST)) {
-		QPRINTK(qdev, IFDOWN, ERR,
-			"Unsupported WOL paramter. qdev->wol = 0x%x.\n",
-			qdev->wol);
+		netif_err(qdev, ifdown, qdev->ndev,
+			  "Unsupported WOL paramter. qdev->wol = 0x%x.\n",
+			  qdev->wol);
 		return -EINVAL;
 	}
 
 	if (qdev->wol & WAKE_MAGIC) {
 		status = ql_mb_wol_set_magic(qdev, 1);
 		if (status) {
-			QPRINTK(qdev, IFDOWN, ERR,
-				"Failed to set magic packet on %s.\n",
-				qdev->ndev->name);
+			netif_err(qdev, ifdown, qdev->ndev,
+				  "Failed to set magic packet on %s.\n",
+				  qdev->ndev->name);
 			return status;
 		} else
-			QPRINTK(qdev, DRV, INFO,
-				"Enabled magic packet successfully on %s.\n",
-				qdev->ndev->name);
+			netif_info(qdev, drv, qdev->ndev,
+				   "Enabled magic packet successfully on %s.\n",
+				   qdev->ndev->name);
 
 		wol |= MB_WOL_MAGIC_PKT;
 	}
@@ -3516,9 +3853,10 @@ int ql_wol(struct ql_adapter *qdev)
 	if (qdev->wol) {
 		wol |= MB_WOL_MODE_ON;
 		status = ql_mb_wol_mode(qdev, wol);
-		QPRINTK(qdev, DRV, ERR, "WOL %s (wol code 0x%x) on %s\n",
-			(status == 0) ? "Sucessfully set" : "Failed", wol,
-			qdev->ndev->name);
+		netif_err(qdev, drv, qdev->ndev,
+			  "WOL %s (wol code 0x%x) on %s\n",
+			  (status == 0) ? "Successfully set" : "Failed",
+			  wol, qdev->ndev->name);
 	}
 
 	return status;
@@ -3538,6 +3876,7 @@ static int ql_adapter_down(struct ql_ada
 	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_core_to_log);
 	cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
 
 	for (i = 0; i < qdev->rss_ring_count; i++)
@@ -3558,8 +3897,8 @@ static int ql_adapter_down(struct ql_ada
 
 	status = ql_adapter_reset(qdev);
 	if (status)
-		QPRINTK(qdev, IFDOWN, ERR, "reset(func #%d) FAILED!\n",
-			qdev->func);
+		netif_err(qdev, ifdown, qdev->ndev, "reset(func #%d) FAILED!\n",
+			  qdev->func);
 	return status;
 }
 
@@ -3569,7 +3908,7 @@ static int ql_adapter_up(struct ql_adapt
 
 	err = ql_adapter_initialize(qdev);
 	if (err) {
-		QPRINTK(qdev, IFUP, INFO, "Unable to initialize adapter.\n");
+		netif_info(qdev, ifup, qdev->ndev, "Unable to initialize adapter.\n");
 		goto err_init;
 	}
 	set_bit(QL_ADAPTER_UP, &qdev->flags);
@@ -3601,7 +3940,7 @@ static int ql_get_adapter_resources(stru
 	int status = 0;
 
 	if (ql_alloc_mem_resources(qdev)) {
-		QPRINTK(qdev, IFUP, ERR, "Unable to  allocate memory.\n");
+		netif_err(qdev, ifup, qdev->ndev, "Unable to  allocate memory.\n");
 		return -ENOMEM;
 	}
 	status = ql_request_irq(qdev);
@@ -3612,6 +3951,16 @@ static int qlge_close(struct net_device
 {
 	struct ql_adapter *qdev = netdev_priv(ndev);
 
+	/* If we hit pci_channel_io_perm_failure
+	 * failure condition, then we already
+	 * brought the adapter down.
+	 */
+	if (test_bit(QL_EEH_FATAL, &qdev->flags)) {
+		netif_err(qdev, drv, qdev->ndev, "EEH fatal did unload.\n");
+		clear_bit(QL_EEH_FATAL, &qdev->flags);
+		return 0;
+	}
+
 	/*
 	 * Wait for device to recover from a reset.
 	 * (Rarely happens, but possible.)
@@ -3681,9 +4030,10 @@ static int ql_configure_rings(struct ql_
 			rx_ring->lbq_size =
 			    rx_ring->lbq_len * sizeof(__le64);
 			rx_ring->lbq_buf_size = (u16)lbq_buf_len;
-			QPRINTK(qdev, IFUP, DEBUG,
-				"lbq_buf_size %d, order = %d\n",
-				rx_ring->lbq_buf_size, qdev->lbq_buf_order);
+			netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
+				     "lbq_buf_size %d, order = %d\n",
+				     rx_ring->lbq_buf_size,
+				     qdev->lbq_buf_order);
 			rx_ring->sbq_len = NUM_SMALL_BUFFERS;
 			rx_ring->sbq_size =
 			    rx_ring->sbq_len * sizeof(__le64);
@@ -3747,14 +4097,14 @@ static int ql_change_rx_buffers(struct q
 	if (!test_bit(QL_ADAPTER_UP, &qdev->flags)) {
 		int i = 3;
 		while (i-- && !test_bit(QL_ADAPTER_UP, &qdev->flags)) {
-			QPRINTK(qdev, IFUP, ERR,
-				 "Waiting for adapter UP...\n");
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Waiting for adapter UP...\n");
 			ssleep(1);
 		}
 
 		if (!i) {
-			QPRINTK(qdev, IFUP, ERR,
-			 "Timed out waiting for adapter UP\n");
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Timed out waiting for adapter UP\n");
 			return -ETIMEDOUT;
 		}
 	}
@@ -3780,8 +4130,8 @@ static int ql_change_rx_buffers(struct q
 
 	return status;
 error:
-	QPRINTK(qdev, IFUP, ALERT,
-		"Driver up/down cycle failed, closing device.\n");
+	netif_alert(qdev, ifup, qdev->ndev,
+		    "Driver up/down cycle failed, closing device.\n");
 	set_bit(QL_ADAPTER_UP, &qdev->flags);
 	dev_close(qdev->ndev);
 	return status;
@@ -3793,28 +4143,25 @@ static int qlge_change_mtu(struct net_de
 	int status;
 
 	if (ndev->mtu == 1500 && new_mtu == 9000) {
-		QPRINTK(qdev, IFUP, ERR, "Changing to jumbo MTU.\n");
+		netif_err(qdev, ifup, qdev->ndev, "Changing to jumbo MTU.\n");
 	} 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) ||
-		   (ndev->mtu == 9000 && new_mtu == 9000)) {
-		return 0;
+		netif_err(qdev, ifup, qdev->ndev, "Changing to normal MTU.\n");
 	} else
 		return -EINVAL;
 
 	queue_delayed_work(qdev->workqueue,
 			&qdev->mpi_port_cfg_work, 3*HZ);
 
+	ndev->mtu = new_mtu;
+
 	if (!netif_running(qdev->ndev)) {
-		ndev->mtu = new_mtu;
 		return 0;
 	}
 
-	ndev->mtu = new_mtu;
 	status = ql_change_rx_buffers(qdev);
 	if (status) {
-		QPRINTK(qdev, IFUP, ERR,
-			"Changing MTU failed.\n");
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Changing MTU failed.\n");
 	}
 
 	return status;
@@ -3874,8 +4221,8 @@ static void qlge_set_multicast_list(stru
 		if (!test_bit(QL_PROMISCUOUS, &qdev->flags)) {
 			if (ql_set_routing_reg
 			    (qdev, RT_IDX_PROMISCUOUS_SLOT, RT_IDX_VALID, 1)) {
-				QPRINTK(qdev, HW, ERR,
-					"Failed to set promiscous mode.\n");
+				netif_err(qdev, hw, qdev->ndev,
+					  "Failed to set promiscous mode.\n");
 			} else {
 				set_bit(QL_PROMISCUOUS, &qdev->flags);
 			}
@@ -3884,8 +4231,8 @@ static void qlge_set_multicast_list(stru
 		if (test_bit(QL_PROMISCUOUS, &qdev->flags)) {
 			if (ql_set_routing_reg
 			    (qdev, RT_IDX_PROMISCUOUS_SLOT, RT_IDX_VALID, 0)) {
-				QPRINTK(qdev, HW, ERR,
-					"Failed to clear promiscous mode.\n");
+				netif_err(qdev, hw, qdev->ndev,
+					  "Failed to clear promiscous mode.\n");
 			} else {
 				clear_bit(QL_PROMISCUOUS, &qdev->flags);
 			}
@@ -3897,12 +4244,12 @@ static void qlge_set_multicast_list(stru
 	 * transition is taking place.
 	 */
 	if ((ndev->flags & IFF_ALLMULTI) ||
-	    (ndev->mc_count > MAX_MULTICAST_ENTRIES)) {
+	    (netdev_mc_count(ndev) > MAX_MULTICAST_ENTRIES)) {
 		if (!test_bit(QL_ALLMULTI, &qdev->flags)) {
 			if (ql_set_routing_reg
 			    (qdev, RT_IDX_ALLMULTI_SLOT, RT_IDX_MCAST, 1)) {
-				QPRINTK(qdev, HW, ERR,
-					"Failed to set all-multi mode.\n");
+				netif_err(qdev, hw, qdev->ndev,
+					  "Failed to set all-multi mode.\n");
 			} else {
 				set_bit(QL_ALLMULTI, &qdev->flags);
 			}
@@ -3911,32 +4258,34 @@ static void qlge_set_multicast_list(stru
 		if (test_bit(QL_ALLMULTI, &qdev->flags)) {
 			if (ql_set_routing_reg
 			    (qdev, RT_IDX_ALLMULTI_SLOT, RT_IDX_MCAST, 0)) {
-				QPRINTK(qdev, HW, ERR,
-					"Failed to clear all-multi mode.\n");
+				netif_err(qdev, hw, qdev->ndev,
+					  "Failed to clear all-multi mode.\n");
 			} else {
 				clear_bit(QL_ALLMULTI, &qdev->flags);
 			}
 		}
 	}
 
-	if (ndev->mc_count) {
+	if (!netdev_mc_empty(ndev)) {
 		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)
+		i = 0;
+		netdev_for_each_mc_addr(mc_ptr, ndev) {
 			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");
+				netif_err(qdev, hw, qdev->ndev,
+					  "Failed to loadmulticast address.\n");
 				ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 				goto exit;
 			}
+			i++;
+		}
 		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,
-				"Failed to set multicast match mode.\n");
+			netif_err(qdev, hw, qdev->ndev,
+				  "Failed to set multicast match mode.\n");
 		} else {
 			set_bit(QL_ALLMULTI, &qdev->flags);
 		}
@@ -3954,6 +4303,8 @@ static int qlge_set_mac_address(struct n
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 	memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
+	/* Update local copy of current mac address. */
+	memcpy(qdev->current_mac_addr, ndev->dev_addr, ndev->addr_len);
 
 	status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
 	if (status)
@@ -3961,7 +4312,7 @@ static int qlge_set_mac_address(struct n
 	status = ql_set_mac_addr_reg(qdev, (u8 *) ndev->dev_addr,
 			MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
 	if (status)
-		QPRINTK(qdev, HW, ERR, "Failed to load MAC address.\n");
+		netif_err(qdev, hw, qdev->ndev, "Failed to load MAC address.\n");
 	ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 	return status;
 }
@@ -3994,8 +4345,8 @@ static void ql_asic_reset_work(struct wo
 	rtnl_unlock();
 	return;
 error:
-	QPRINTK(qdev, IFUP, ALERT,
-		"Driver up/down cycle failed, closing device\n");
+	netif_alert(qdev, ifup, qdev->ndev,
+		    "Driver up/down cycle failed, closing device\n");
 
 	set_bit(QL_ADAPTER_UP, &qdev->flags);
 	dev_close(qdev->ndev);
@@ -4094,6 +4445,7 @@ static void ql_release_all(struct pci_de
 		iounmap(qdev->reg_base);
 	if (qdev->doorbell_area)
 		iounmap(qdev->doorbell_area);
+	vfree(qdev->mpi_coredump);
 	pci_release_regions(pdev);
 	pci_set_drvdata(pdev, NULL);
 }
@@ -4175,6 +4527,17 @@ static int __devinit ql_init_device(stru
 	spin_lock_init(&qdev->hw_lock);
 	spin_lock_init(&qdev->stats_lock);
 
+	if (qlge_mpi_coredump) {
+		qdev->mpi_coredump =
+			vmalloc(sizeof(struct ql_mpi_coredump));
+		if (qdev->mpi_coredump == NULL) {
+			dev_err(&pdev->dev, "Coredump alloc failed.\n");
+			err = -ENOMEM;
+			goto err_out2;
+		}
+		if (qlge_force_coredump)
+			set_bit(QL_FRC_COREDUMP, &qdev->flags);
+	}
 	/* make sure the EEPROM is good */
 	err = qdev->nic_ops->get_flash(qdev);
 	if (err) {
@@ -4183,6 +4546,8 @@ static int __devinit ql_init_device(stru
 	}
 
 	memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
+	/* Keep local copy of current mac address. */
+	memcpy(qdev->current_mac_addr, ndev->dev_addr, ndev->addr_len);
 
 	/* Set up the default ring sizes. */
 	qdev->tx_ring_size = NUM_TX_RING_ENTRIES;
@@ -4204,6 +4569,7 @@ static int __devinit ql_init_device(stru
 	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);
+	INIT_DELAYED_WORK(&qdev->mpi_core_to_log, ql_mpi_core_to_log);
 	init_completion(&qdev->ide_completion);
 
 	if (!cards_found) {
@@ -4234,6 +4600,21 @@ static const struct net_device_ops qlge_
 	.ndo_vlan_rx_kill_vid	= qlge_vlan_rx_kill_vid,
 };
 
+static void ql_timer(unsigned long data)
+{
+	struct ql_adapter *qdev = (struct ql_adapter *)data;
+	u32 var = 0;
+
+	var = ql_read32(qdev, STS);
+	if (pci_channel_offline(qdev->pdev)) {
+		netif_err(qdev, ifup, qdev->ndev, "EEH STS = 0x%.08x.\n", var);
+		return;
+	}
+
+	qdev->timer.expires = jiffies + (5*HZ);
+	add_timer(&qdev->timer);
+}
+
 static int __devinit qlge_probe(struct pci_dev *pdev,
 				const struct pci_device_id *pci_entry)
 {
@@ -4285,6 +4666,14 @@ static int __devinit qlge_probe(struct p
 		pci_disable_device(pdev);
 		return err;
 	}
+	/* Start up the timer to trigger EEH if
+	 * the bus goes dead
+	 */
+	init_timer_deferrable(&qdev->timer);
+	qdev->timer.data = (unsigned long)qdev;
+	qdev->timer.function = ql_timer;
+	qdev->timer.expires = jiffies + (5*HZ);
+	add_timer(&qdev->timer);
 	ql_link_off(qdev);
 	ql_display_dev_info(ndev);
 	atomic_set(&qdev->lb_count, 0);
@@ -4305,6 +4694,8 @@ int ql_clean_lb_rx_ring(struct rx_ring *
 static void __devexit qlge_remove(struct pci_dev *pdev)
 {
 	struct net_device *ndev = pci_get_drvdata(pdev);
+	struct ql_adapter *qdev = netdev_priv(ndev);
+	del_timer_sync(&qdev->timer);
 	unregister_netdev(ndev);
 	ql_release_all(pdev);
 	pci_disable_device(pdev);
@@ -4327,6 +4718,7 @@ static void ql_eeh_close(struct net_devi
 	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_core_to_log);
 	cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
 
 	for (i = 0; i < qdev->rss_ring_count; i++)
@@ -4346,6 +4738,7 @@ static pci_ers_result_t qlge_io_error_de
 					       enum pci_channel_state state)
 {
 	struct net_device *ndev = pci_get_drvdata(pdev);
+	struct ql_adapter *qdev = netdev_priv(ndev);
 
 	switch (state) {
 	case pci_channel_io_normal:
@@ -4359,6 +4752,8 @@ static pci_ers_result_t qlge_io_error_de
 	case pci_channel_io_perm_failure:
 		dev_err(&pdev->dev,
 			"%s: pci_channel_io_perm_failure.\n", __func__);
+		ql_eeh_close(ndev);
+		set_bit(QL_EEH_FATAL, &qdev->flags);
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 
@@ -4381,11 +4776,18 @@ static pci_ers_result_t qlge_io_slot_res
 
 	pci_restore_state(pdev);
 	if (pci_enable_device(pdev)) {
-		QPRINTK(qdev, IFUP, ERR,
-			"Cannot re-enable PCI device after reset.\n");
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Cannot re-enable PCI device after reset.\n");
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 	pci_set_master(pdev);
+
+	if (ql_adapter_reset(qdev)) {
+		netif_err(qdev, drv, qdev->ndev, "reset FAILED!\n");
+		set_bit(QL_EEH_FATAL, &qdev->flags);
+		return PCI_ERS_RESULT_DISCONNECT;
+	}
+
 	return PCI_ERS_RESULT_RECOVERED;
 }
 
@@ -4395,19 +4797,19 @@ static void qlge_io_resume(struct pci_de
 	struct ql_adapter *qdev = netdev_priv(ndev);
 	int err = 0;
 
-	if (ql_adapter_reset(qdev))
-		QPRINTK(qdev, DRV, ERR, "reset FAILED!\n");
 	if (netif_running(ndev)) {
 		err = qlge_open(ndev);
 		if (err) {
-			QPRINTK(qdev, IFUP, ERR,
-				"Device initialization failed after reset.\n");
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Device initialization failed after reset.\n");
 			return;
 		}
 	} else {
-		QPRINTK(qdev, IFUP, ERR,
-			"Device was not running prior to EEH.\n");
+		netif_err(qdev, ifup, qdev->ndev,
+			  "Device was not running prior to EEH.\n");
 	}
+	qdev->timer.expires = jiffies + (5*HZ);
+	add_timer(&qdev->timer);
 	netif_device_attach(ndev);
 }
 
@@ -4424,6 +4826,7 @@ static int qlge_suspend(struct pci_dev *
 	int err;
 
 	netif_device_detach(ndev);
+	del_timer_sync(&qdev->timer);
 
 	if (netif_running(ndev)) {
 		err = ql_adapter_down(qdev);
@@ -4454,7 +4857,7 @@ static int qlge_resume(struct pci_dev *p
 	pci_restore_state(pdev);
 	err = pci_enable_device(pdev);
 	if (err) {
-		QPRINTK(qdev, IFUP, ERR, "Cannot enable PCI device from suspend\n");
+		netif_err(qdev, ifup, qdev->ndev, "Cannot enable PCI device from suspend\n");
 		return err;
 	}
 	pci_set_master(pdev);
@@ -4468,6 +4871,8 @@ static int qlge_resume(struct pci_dev *p
 			return err;
 	}
 
+	qdev->timer.expires = jiffies + (5*HZ);
+	add_timer(&qdev->timer);
 	netif_device_attach(ndev);
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_mpi.c linux-libre-2.6.34-gnu1/drivers/net/qlge/qlge_mpi.c
--- linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_mpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/qlge/qlge_mpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,54 @@
 #include "qlge.h"
 
+int ql_unpause_mpi_risc(struct ql_adapter *qdev)
+{
+	u32 tmp;
+
+	/* Un-pause the RISC */
+	tmp = ql_read32(qdev, CSR);
+	if (!(tmp & CSR_RP))
+		return -EIO;
+
+	ql_write32(qdev, CSR, CSR_CMD_CLR_PAUSE);
+	return 0;
+}
+
+int ql_pause_mpi_risc(struct ql_adapter *qdev)
+{
+	u32 tmp;
+	int count = UDELAY_COUNT;
+
+	/* Pause the RISC */
+	ql_write32(qdev, CSR, CSR_CMD_SET_PAUSE);
+	do {
+		tmp = ql_read32(qdev, CSR);
+		if (tmp & CSR_RP)
+			break;
+		mdelay(UDELAY_DELAY);
+		count--;
+	} while (count);
+	return (count == 0) ? -ETIMEDOUT : 0;
+}
+
+int ql_hard_reset_mpi_risc(struct ql_adapter *qdev)
+{
+	u32 tmp;
+	int count = UDELAY_COUNT;
+
+	/* Reset the RISC */
+	ql_write32(qdev, CSR, CSR_CMD_SET_RST);
+	do {
+		tmp = ql_read32(qdev, CSR);
+		if (tmp & CSR_RR) {
+			ql_write32(qdev, CSR, CSR_CMD_CLR_RST);
+			break;
+		}
+		mdelay(UDELAY_DELAY);
+		count--;
+	} while (count);
+	return (count == 0) ? -ETIMEDOUT : 0;
+}
+
 int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
 {
 	int status;
@@ -45,6 +94,35 @@ int ql_soft_reset_mpi_risc(struct ql_ada
 	return status;
 }
 
+/* Determine if we are in charge of the firwmare. If
+ * we are the lower of the 2 NIC pcie functions, or if
+ * we are the higher function and the lower function
+ * is not enabled.
+ */
+int ql_own_firmware(struct ql_adapter *qdev)
+{
+	u32 temp;
+
+	/* If we are the lower of the 2 NIC functions
+	 * on the chip the we are responsible for
+	 * core dump and firmware reset after an error.
+	 */
+	if (qdev->func < qdev->alt_func)
+		return 1;
+
+	/* If we are the higher of the 2 NIC functions
+	 * on the chip and the lower function is not
+	 * enabled, then we are responsible for
+	 * core dump and firmware reset after an error.
+	 */
+	temp =  ql_read32(qdev, STS);
+	if (!(temp & (1 << (8 + qdev->alt_func))))
+		return 1;
+
+	return 0;
+
+}
+
 static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
 {
 	int i, status;
@@ -57,7 +135,7 @@ static int ql_get_mb_sts(struct ql_adapt
 		    ql_read_mpi_reg(qdev, qdev->mailbox_out + i,
 				     &mbcp->mbox_out[i]);
 		if (status) {
-			QPRINTK(qdev, DRV, ERR, "Failed mailbox read.\n");
+			netif_err(qdev, drv, qdev->ndev, "Failed mailbox read.\n");
 			break;
 		}
 	}
@@ -130,7 +208,7 @@ static int ql_idc_req_aen(struct ql_adap
 	int status;
 	struct mbox_params *mbcp = &qdev->idc_mbc;
 
-	QPRINTK(qdev, DRV, ERR, "Enter!\n");
+	netif_err(qdev, drv, qdev->ndev, "Enter!\n");
 	/* Get the status data and start up a thread to
 	 * handle the request.
 	 */
@@ -138,8 +216,8 @@ static int ql_idc_req_aen(struct ql_adap
 	mbcp->out_count = 4;
 	status = ql_get_mb_sts(qdev, mbcp);
 	if (status) {
-		QPRINTK(qdev, DRV, ERR,
-			"Could not read MPI, resetting ASIC!\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Could not read MPI, resetting ASIC!\n");
 		ql_queue_asic_error(qdev);
 	} else	{
 		/* Begin polled mode early so
@@ -162,8 +240,8 @@ static int ql_idc_cmplt_aen(struct ql_ad
 	mbcp->out_count = 4;
 	status = ql_get_mb_sts(qdev, mbcp);
 	if (status) {
-		QPRINTK(qdev, DRV, ERR,
-			"Could not read MPI, resetting RISC!\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Could not read MPI, resetting RISC!\n");
 		ql_queue_fw_error(qdev);
 	} else
 		/* Wake up the sleeping mpi_idc_work thread that is
@@ -181,13 +259,13 @@ static void ql_link_up(struct ql_adapter
 
 	status = ql_get_mb_sts(qdev, mbcp);
 	if (status) {
-		QPRINTK(qdev, DRV, ERR,
-			"%s: Could not get mailbox status.\n", __func__);
+		netif_err(qdev, drv, qdev->ndev,
+			  "%s: Could not get mailbox status.\n", __func__);
 		return;
 	}
 
 	qdev->link_status = mbcp->mbox_out[1];
-	QPRINTK(qdev, DRV, ERR, "Link Up.\n");
+	netif_err(qdev, drv, qdev->ndev, "Link Up.\n");
 
 	/* If we're coming back from an IDC event
 	 * then set up the CAM and frame routing.
@@ -195,8 +273,8 @@ static void ql_link_up(struct ql_adapter
 	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");
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Failed to init CAM/Routing tables.\n");
 			return;
 		} else
 			clear_bit(QL_CAM_RT_SET, &qdev->flags);
@@ -207,7 +285,7 @@ static void ql_link_up(struct ql_adapter
 	 * to our liking.
 	 */
 	if (!test_bit(QL_PORT_CFG, &qdev->flags)) {
-		QPRINTK(qdev, DRV, ERR, "Queue Port Config Worker!\n");
+		netif_err(qdev, drv, qdev->ndev, "Queue Port Config Worker!\n");
 		set_bit(QL_PORT_CFG, &qdev->flags);
 		/* Begin polled mode early so
 		 * we don't get another interrupt
@@ -229,7 +307,7 @@ static void ql_link_down(struct ql_adapt
 
 	status = ql_get_mb_sts(qdev, mbcp);
 	if (status)
-		QPRINTK(qdev, DRV, ERR, "Link down AEN broken!\n");
+		netif_err(qdev, drv, qdev->ndev, "Link down AEN broken!\n");
 
 	ql_link_off(qdev);
 }
@@ -242,9 +320,9 @@ static int ql_sfp_in(struct ql_adapter *
 
 	status = ql_get_mb_sts(qdev, mbcp);
 	if (status)
-		QPRINTK(qdev, DRV, ERR, "SFP in AEN broken!\n");
+		netif_err(qdev, drv, qdev->ndev, "SFP in AEN broken!\n");
 	else
-		QPRINTK(qdev, DRV, ERR, "SFP insertion detected.\n");
+		netif_err(qdev, drv, qdev->ndev, "SFP insertion detected.\n");
 
 	return status;
 }
@@ -257,9 +335,9 @@ static int ql_sfp_out(struct ql_adapter
 
 	status = ql_get_mb_sts(qdev, mbcp);
 	if (status)
-		QPRINTK(qdev, DRV, ERR, "SFP out AEN broken!\n");
+		netif_err(qdev, drv, qdev->ndev, "SFP out AEN broken!\n");
 	else
-		QPRINTK(qdev, DRV, ERR, "SFP removal detected.\n");
+		netif_err(qdev, drv, qdev->ndev, "SFP removal detected.\n");
 
 	return status;
 }
@@ -272,13 +350,13 @@ static int ql_aen_lost(struct ql_adapter
 
 	status = ql_get_mb_sts(qdev, mbcp);
 	if (status)
-		QPRINTK(qdev, DRV, ERR, "Lost AEN broken!\n");
+		netif_err(qdev, drv, qdev->ndev, "Lost AEN broken!\n");
 	else {
 		int i;
-		QPRINTK(qdev, DRV, ERR, "Lost AEN detected.\n");
+		netif_err(qdev, drv, qdev->ndev, "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]);
+			netif_err(qdev, drv, qdev->ndev, "mbox_out[%d] = 0x%.08x.\n",
+				  i, mbcp->mbox_out[i]);
 
 	}
 
@@ -293,15 +371,15 @@ static void ql_init_fw_done(struct ql_ad
 
 	status = ql_get_mb_sts(qdev, mbcp);
 	if (status) {
-		QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
+		netif_err(qdev, drv, qdev->ndev, "Firmware did not initialize!\n");
 	} else {
-		QPRINTK(qdev, DRV, ERR, "Firmware Revision  = 0x%.08x.\n",
-			mbcp->mbox_out[1]);
+		netif_err(qdev, drv, qdev->ndev, "Firmware Revision  = 0x%.08x.\n",
+			  mbcp->mbox_out[1]);
 		qdev->fw_rev_id = mbcp->mbox_out[1];
 		status = ql_cam_route_initialize(qdev);
 		if (status)
-			QPRINTK(qdev, IFUP, ERR,
-				"Failed to init CAM/Routing tables.\n");
+			netif_err(qdev, ifup, qdev->ndev,
+				  "Failed to init CAM/Routing tables.\n");
 	}
 }
 
@@ -320,8 +398,8 @@ static int ql_mpi_handler(struct ql_adap
 	mbcp->out_count = 1;
 	status = ql_get_mb_sts(qdev, mbcp);
 	if (status) {
-		QPRINTK(qdev, DRV, ERR,
-			"Could not read MPI, resetting ASIC!\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Could not read MPI, resetting ASIC!\n");
 		ql_queue_asic_error(qdev);
 		goto end;
 	}
@@ -410,15 +488,14 @@ static int ql_mpi_handler(struct ql_adap
 			mbcp->mbox_out[0] = MB_CMD_STS_ERR;
 			return status;
 		}
-		QPRINTK(qdev, DRV, ERR,
-			"Firmware initialization failed.\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Firmware initialization failed.\n");
 		status = -EIO;
 		ql_queue_fw_error(qdev);
 		break;
 
 	case AEN_SYS_ERR:
-		QPRINTK(qdev, DRV, ERR,
-			"System Error.\n");
+		netif_err(qdev, drv, qdev->ndev, "System Error.\n");
 		ql_queue_fw_error(qdev);
 		status = -EIO;
 		break;
@@ -431,8 +508,8 @@ static int ql_mpi_handler(struct ql_adap
 		/* Need to support AEN 8110 */
 		break;
 	default:
-		QPRINTK(qdev, DRV, ERR,
-			"Unsupported AE %.08x.\n", mbcp->mbox_out[0]);
+		netif_err(qdev, drv, qdev->ndev,
+			  "Unsupported AE %.08x.\n", mbcp->mbox_out[0]);
 		/* Clear the MPI firmware status. */
 	}
 end:
@@ -505,8 +582,8 @@ static int ql_mailbox_command(struct ql_
 			goto done;
 	} while (time_before(jiffies, count));
 
-	QPRINTK(qdev, DRV, ERR,
-		"Timed out waiting for mailbox complete.\n");
+	netif_err(qdev, drv, qdev->ndev,
+		  "Timed out waiting for mailbox complete.\n");
 	status = -ETIMEDOUT;
 	goto end;
 
@@ -529,6 +606,22 @@ end:
 	return status;
 }
 
+int ql_mb_sys_err(struct ql_adapter *qdev)
+{
+	struct mbox_params mbc;
+	struct mbox_params *mbcp = &mbc;
+	int status;
+
+	memset(mbcp, 0, sizeof(struct mbox_params));
+
+	mbcp->in_count = 1;
+	mbcp->out_count = 0;
+
+	mbcp->mbox_in[0] = MB_CMD_MAKE_SYS_ERR;
+
+	status = ql_mailbox_command(qdev, mbcp);
+	return status;
+}
 
 /* Get MPI firmware version. This will be used for
  * driver banner and for ethtool info.
@@ -552,8 +645,8 @@ int ql_mb_about_fw(struct ql_adapter *qd
 		return status;
 
 	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
-		QPRINTK(qdev, DRV, ERR,
-			"Failed about firmware command\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Failed about firmware command\n");
 		status = -EIO;
 	}
 
@@ -584,8 +677,8 @@ int ql_mb_get_fw_state(struct ql_adapter
 		return status;
 
 	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
-		QPRINTK(qdev, DRV, ERR,
-			"Failed Get Firmware State.\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Failed Get Firmware State.\n");
 		status = -EIO;
 	}
 
@@ -594,8 +687,8 @@ int ql_mb_get_fw_state(struct ql_adapter
 	 * happen.
 	 */
 	if (mbcp->mbox_out[1] & 1) {
-		QPRINTK(qdev, DRV, ERR,
-			"Firmware waiting for initialization.\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Firmware waiting for initialization.\n");
 		status = -EIO;
 	}
 
@@ -627,8 +720,7 @@ int ql_mb_idc_ack(struct ql_adapter *qde
 		return status;
 
 	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
-		QPRINTK(qdev, DRV, ERR,
-			"Failed IDC ACK send.\n");
+		netif_err(qdev, drv, qdev->ndev, "Failed IDC ACK send.\n");
 		status = -EIO;
 	}
 	return status;
@@ -659,16 +751,72 @@ int ql_mb_set_port_cfg(struct ql_adapter
 		return status;
 
 	if (mbcp->mbox_out[0] == MB_CMD_STS_INTRMDT) {
-		QPRINTK(qdev, DRV, ERR,
-			"Port Config sent, wait for IDC.\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "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");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Failed Set Port Configuration.\n");
 		status = -EIO;
 	}
 	return status;
 }
 
+int ql_mb_dump_ram(struct ql_adapter *qdev, u64 req_dma, u32 addr,
+	u32 size)
+{
+	int status = 0;
+	struct mbox_params mbc;
+	struct mbox_params *mbcp = &mbc;
+
+	memset(mbcp, 0, sizeof(struct mbox_params));
+
+	mbcp->in_count = 9;
+	mbcp->out_count = 1;
+
+	mbcp->mbox_in[0] = MB_CMD_DUMP_RISC_RAM;
+	mbcp->mbox_in[1] = LSW(addr);
+	mbcp->mbox_in[2] = MSW(req_dma);
+	mbcp->mbox_in[3] = LSW(req_dma);
+	mbcp->mbox_in[4] = MSW(size);
+	mbcp->mbox_in[5] = LSW(size);
+	mbcp->mbox_in[6] = MSW(MSD(req_dma));
+	mbcp->mbox_in[7] = LSW(MSD(req_dma));
+	mbcp->mbox_in[8] = MSW(addr);
+
+
+	status = ql_mailbox_command(qdev, mbcp);
+	if (status)
+		return status;
+
+	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+		netif_err(qdev, drv, qdev->ndev, "Failed to dump risc RAM.\n");
+		status = -EIO;
+	}
+	return status;
+}
+
+/* Issue a mailbox command to dump RISC RAM. */
+int ql_dump_risc_ram_area(struct ql_adapter *qdev, void *buf,
+		u32 ram_addr, int word_count)
+{
+	int status;
+	char *my_buf;
+	dma_addr_t buf_dma;
+
+	my_buf = pci_alloc_consistent(qdev->pdev, word_count * sizeof(u32),
+					&buf_dma);
+	if (!my_buf)
+		return -EIO;
+
+	status = ql_mb_dump_ram(qdev, buf_dma, ram_addr, word_count);
+	if (!status)
+		memcpy(buf, my_buf, word_count * sizeof(u32));
+
+	pci_free_consistent(qdev->pdev, word_count * sizeof(u32), my_buf,
+				buf_dma);
+	return status;
+}
+
 /* Get link settings and maximum frame size settings
  * for the current port.
  * Most likely will block.
@@ -691,12 +839,12 @@ int ql_mb_get_port_cfg(struct ql_adapter
 		return status;
 
 	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
-		QPRINTK(qdev, DRV, ERR,
-			"Failed Get Port Configuration.\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Failed Get Port Configuration.\n");
 		status = -EIO;
 	} else	{
-		QPRINTK(qdev, DRV, DEBUG,
-			"Passed Get Port Configuration.\n");
+		netif_printk(qdev, drv, KERN_DEBUG, qdev->ndev,
+			     "Passed Get Port Configuration.\n");
 		qdev->link_config = mbcp->mbox_out[1];
 		qdev->max_frame_size = mbcp->mbox_out[2];
 	}
@@ -723,8 +871,7 @@ int ql_mb_wol_mode(struct ql_adapter *qd
 		return status;
 
 	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
-		QPRINTK(qdev, DRV, ERR,
-			"Failed to set WOL mode.\n");
+		netif_err(qdev, drv, qdev->ndev, "Failed to set WOL mode.\n");
 		status = -EIO;
 	}
 	return status;
@@ -766,8 +913,7 @@ int ql_mb_wol_set_magic(struct ql_adapte
 		return status;
 
 	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
-		QPRINTK(qdev, DRV, ERR,
-			"Failed to set WOL mode.\n");
+		netif_err(qdev, drv, qdev->ndev, "Failed to set WOL mode.\n");
 		status = -EIO;
 	}
 	return status;
@@ -793,8 +939,7 @@ static int ql_idc_wait(struct ql_adapter
 			wait_for_completion_timeout(&qdev->ide_completion,
 							wait_time);
 		if (!wait_time) {
-			QPRINTK(qdev, DRV, ERR,
-				"IDC Timeout.\n");
+			netif_err(qdev, drv, qdev->ndev, "IDC Timeout.\n");
 			break;
 		}
 		/* Now examine the response from the IDC process.
@@ -802,18 +947,17 @@ static int ql_idc_wait(struct ql_adapter
 		 * more wait time.
 		 */
 		if (mbcp->mbox_out[0] == AEN_IDC_EXT) {
-			QPRINTK(qdev, DRV, ERR,
-				"IDC Time Extension from function.\n");
+			netif_err(qdev, drv, qdev->ndev,
+				  "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");
+			netif_err(qdev, drv, qdev->ndev, "IDC Success.\n");
 			status = 0;
 			break;
 		} else {
-			QPRINTK(qdev, DRV, ERR,
-				"IDC: Invalid State 0x%.04x.\n",
-				mbcp->mbox_out[0]);
+			netif_err(qdev, drv, qdev->ndev,
+				  "IDC: Invalid State 0x%.04x.\n",
+				  mbcp->mbox_out[0]);
 			status = -EIO;
 			break;
 		}
@@ -842,8 +986,8 @@ int ql_mb_set_led_cfg(struct ql_adapter
 		return status;
 
 	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
-		QPRINTK(qdev, DRV, ERR,
-			"Failed to set LED Configuration.\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Failed to set LED Configuration.\n");
 		status = -EIO;
 	}
 
@@ -868,8 +1012,8 @@ int ql_mb_get_led_cfg(struct ql_adapter
 		return status;
 
 	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
-		QPRINTK(qdev, DRV, ERR,
-			"Failed to get LED Configuration.\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Failed to get LED Configuration.\n");
 		status = -EIO;
 	} else
 		qdev->led_config = mbcp->mbox_out[1];
@@ -899,16 +1043,16 @@ int ql_mb_set_mgmnt_traffic_ctl(struct q
 		return status;
 
 	if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) {
-		QPRINTK(qdev, DRV, ERR,
-			"Command not supported by firmware.\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Command not supported by firmware.\n");
 		status = -EINVAL;
 	} else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) {
 		/* This indicates that the firmware is
 		 * already in the state we are trying to
 		 * change it to.
 		 */
-		QPRINTK(qdev, DRV, ERR,
-			"Command parameters make no change.\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Command parameters make no change.\n");
 	}
 	return status;
 }
@@ -938,12 +1082,12 @@ static int ql_mb_get_mgmnt_traffic_ctl(s
 	}
 
 	if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) {
-		QPRINTK(qdev, DRV, ERR,
-			"Command not supported by firmware.\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Command not supported by firmware.\n");
 		status = -EINVAL;
 	} else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) {
-		QPRINTK(qdev, DRV, ERR,
-			"Failed to get MPI traffic control.\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Failed to get MPI traffic control.\n");
 		status = -EIO;
 	}
 	return status;
@@ -999,8 +1143,8 @@ void ql_mpi_port_cfg_work(struct work_st
 	status = ql_mb_get_port_cfg(qdev);
 	rtnl_unlock();
 	if (status) {
-		QPRINTK(qdev, DRV, ERR,
-			"Bug: Failed to get port config data.\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Bug: Failed to get port config data.\n");
 		goto err;
 	}
 
@@ -1013,8 +1157,8 @@ void ql_mpi_port_cfg_work(struct work_st
 	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");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Bug: Failed to set port config data.\n");
 		goto err;
 	}
 end:
@@ -1046,8 +1190,8 @@ void ql_mpi_idc_work(struct work_struct
 
 	switch (aen) {
 	default:
-		QPRINTK(qdev, DRV, ERR,
-			"Bug: Unhandled IDC action.\n");
+		netif_err(qdev, drv, qdev->ndev,
+			  "Bug: Unhandled IDC action.\n");
 		break;
 	case MB_CMD_PORT_RESET:
 	case MB_CMD_STOP_FW:
@@ -1062,11 +1206,11 @@ void ql_mpi_idc_work(struct work_struct
 		if (timeout) {
 			status = ql_mb_idc_ack(qdev);
 			if (status)
-				QPRINTK(qdev, DRV, ERR,
-					"Bug: No pending IDC!\n");
+				netif_err(qdev, drv, qdev->ndev,
+					  "Bug: No pending IDC!\n");
 		} else {
-			QPRINTK(qdev, DRV, DEBUG,
-				    "IDC ACK not required\n");
+			netif_printk(qdev, drv, KERN_DEBUG, qdev->ndev,
+				     "IDC ACK not required\n");
 			status = 0; /* success */
 		}
 		break;
@@ -1095,11 +1239,11 @@ void ql_mpi_idc_work(struct work_struct
 		if (timeout) {
 			status = ql_mb_idc_ack(qdev);
 			if (status)
-				QPRINTK(qdev, DRV, ERR,
-				    "Bug: No pending IDC!\n");
+				netif_err(qdev, drv, qdev->ndev,
+					  "Bug: No pending IDC!\n");
 		} else {
-			QPRINTK(qdev, DRV, DEBUG,
-			    "IDC ACK not required\n");
+			netif_printk(qdev, drv, KERN_DEBUG, qdev->ndev,
+				     "IDC ACK not required\n");
 			status = 0; /* success */
 		}
 		break;
@@ -1143,5 +1287,19 @@ void ql_mpi_reset_work(struct work_struc
 	cancel_delayed_work_sync(&qdev->mpi_work);
 	cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
 	cancel_delayed_work_sync(&qdev->mpi_idc_work);
+	/* If we're not the dominant NIC function,
+	 * then there is nothing to do.
+	 */
+	if (!ql_own_firmware(qdev)) {
+		netif_err(qdev, drv, qdev->ndev, "Don't own firmware!\n");
+		return;
+	}
+
+	if (!ql_core_dump(qdev, qdev->mpi_coredump)) {
+		netif_err(qdev, drv, qdev->ndev, "Core is dumped!\n");
+		qdev->core_is_dumped = 1;
+		queue_delayed_work(qdev->workqueue,
+			&qdev->mpi_core_to_log, 5 * HZ);
+	}
 	ql_soft_reset_mpi_risc(qdev);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/r6040.c linux-libre-2.6.34-gnu1/drivers/net/r6040.c
--- linux-libre-2.6.33-gnu1/drivers/net/r6040.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/r6040.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,7 +29,6 @@
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
@@ -135,7 +134,7 @@
 #define RX_DESC_SIZE	(RX_DCNT * sizeof(struct r6040_descriptor))
 #define TX_DESC_SIZE	(TX_DCNT * sizeof(struct r6040_descriptor))
 #define MBCR_DEFAULT	0x012A	/* MAC Bus Control Register */
-#define MCAST_MAX	4	/* Max number multicast addresses to filter */
+#define MCAST_MAX	3	/* Max number multicast addresses to filter */
 
 /* Descriptor status */
 #define DSC_OWNER_MAC	0x8000	/* MAC is the owner of this descriptor */
@@ -938,7 +937,7 @@ static void r6040_multicast_list(struct
 	u16 *adrp;
 	u16 reg;
 	unsigned long flags;
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	int i;
 
 	/* MAC Address */
@@ -958,25 +957,24 @@ static void r6040_multicast_list(struct
 	}
 	/* Too many multicast addresses
 	 * accept all traffic */
-	else if ((dev->mc_count > MCAST_MAX) || (dev->flags & IFF_ALLMULTI))
+	else if ((netdev_mc_count(dev) > MCAST_MAX) ||
+		 (dev->flags & IFF_ALLMULTI))
 		reg |= 0x0020;
 
 	iowrite16(reg, ioaddr);
 	spin_unlock_irqrestore(&lp->lock, flags);
 
 	/* Build the hash table */
-	if (dev->mc_count > MCAST_MAX) {
+	if (netdev_mc_count(dev) > MCAST_MAX) {
 		u16 hash_table[4];
 		u32 crc;
 
 		for (i = 0; i < 4; i++)
 			hash_table[i] = 0;
 
-		for (i = 0; i < dev->mc_count; i++) {
+		netdev_for_each_mc_addr(dmi, dev) {
 			char *addrs = dmi->dmi_addr;
 
-			dmi = dmi->next;
-
 			if (!(*addrs & 1))
 				continue;
 
@@ -984,9 +982,6 @@ static void r6040_multicast_list(struct
 			crc >>= 26;
 			hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
 		}
-		/* Write the index of the hash table */
-		for (i = 0; i < 4; i++)
-			iowrite16(hash_table[i] << 14, ioaddr + MCR1);
 		/* Fill the MAC hash tables with their values */
 		iowrite16(hash_table[0], ioaddr + MAR0);
 		iowrite16(hash_table[1], ioaddr + MAR1);
@@ -994,17 +989,19 @@ static void r6040_multicast_list(struct
 		iowrite16(hash_table[3], ioaddr + MAR3);
 	}
 	/* Multicast Address 1~4 case */
-	for (i = 0, dmi; (i < dev->mc_count) && (i < MCAST_MAX); i++) {
-		adrp = (u16 *)dmi->dmi_addr;
-		iowrite16(adrp[0], ioaddr + MID_1L + 8*i);
-		iowrite16(adrp[1], ioaddr + MID_1M + 8*i);
-		iowrite16(adrp[2], ioaddr + MID_1H + 8*i);
-		dmi = dmi->next;
-	}
-	for (i = dev->mc_count; i < MCAST_MAX; i++) {
-		iowrite16(0xffff, ioaddr + MID_0L + 8*i);
-		iowrite16(0xffff, ioaddr + MID_0M + 8*i);
-		iowrite16(0xffff, ioaddr + MID_0H + 8*i);
+	i = 0;
+	netdev_for_each_mc_addr(dmi, dev) {
+		if (i < MCAST_MAX) {
+			adrp = (u16 *) dmi->dmi_addr;
+			iowrite16(adrp[0], ioaddr + MID_1L + 8 * i);
+			iowrite16(adrp[1], ioaddr + MID_1M + 8 * i);
+			iowrite16(adrp[2], ioaddr + MID_1H + 8 * i);
+		} else {
+			iowrite16(0xffff, ioaddr + MID_1L + 8 * i);
+			iowrite16(0xffff, ioaddr + MID_1M + 8 * i);
+			iowrite16(0xffff, ioaddr + MID_1H + 8 * i);
+		}
+		i++;
 	}
 }
 
@@ -1222,7 +1219,7 @@ static void __devexit r6040_remove_one(s
 }
 
 
-static struct pci_device_id r6040_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(r6040_pci_tbl) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_RDC, 0x6040) },
 	{ 0 }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/r8169.c linux-libre-2.6.34-gnu1/drivers/net/r8169.c
--- linux-libre-2.6.33-gnu1/drivers/net/r8169.c	2013-05-03 12:08:24.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/r8169.c	2013-05-03 09:47:55.000000000 -0400
@@ -168,7 +168,7 @@ static void rtl_hw_start_8169(struct net
 static void rtl_hw_start_8168(struct net_device *);
 static void rtl_hw_start_8101(struct net_device *);
 
-static struct pci_device_id rtl8169_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8129), 0, 0, RTL_CFG_0 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8136), 0, 0, RTL_CFG_2 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8167), 0, 0, RTL_CFG_0 },
@@ -186,7 +186,12 @@ static struct pci_device_id rtl8169_pci_
 
 MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
 
-static int rx_copybreak = 200;
+/*
+ * we set our copybreak very high so that we don't have
+ * to allocate 16k frames all the time (see note in
+ * rtl8169_open()
+ */
+static int rx_copybreak = 16383;
 static int use_dac;
 static struct {
 	u32 msg_enable;
@@ -744,12 +749,10 @@ static void rtl8169_check_link_status(st
 	spin_lock_irqsave(&tp->lock, flags);
 	if (tp->link_ok(ioaddr)) {
 		netif_carrier_on(dev);
-		if (netif_msg_ifup(tp))
-			printk(KERN_INFO PFX "%s: link up\n", dev->name);
+		netif_info(tp, ifup, dev, "link up\n");
 	} else {
-		if (netif_msg_ifdown(tp))
-			printk(KERN_INFO PFX "%s: link down\n", dev->name);
 		netif_carrier_off(dev);
+		netif_info(tp, ifdown, dev, "link down\n");
 	}
 	spin_unlock_irqrestore(&tp->lock, flags);
 }
@@ -862,11 +865,8 @@ static int rtl8169_set_speed_tbi(struct
 	} else if (autoneg == AUTONEG_ENABLE)
 		RTL_W32(TBICSR, reg | TBINwEnable | TBINwRestart);
 	else {
-		if (netif_msg_link(tp)) {
-			printk(KERN_WARNING "%s: "
-			       "incorrect speed setting refused in TBI mode\n",
-			       dev->name);
-		}
+		netif_warn(tp, link, dev,
+			   "incorrect speed setting refused in TBI mode\n");
 		ret = -EOPNOTSUPP;
 	}
 
@@ -901,9 +901,9 @@ static int rtl8169_set_speed_xmii(struct
 		    (tp->mac_version != RTL_GIGA_MAC_VER_15) &&
 		    (tp->mac_version != RTL_GIGA_MAC_VER_16)) {
 			giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
-		} else if (netif_msg_link(tp)) {
-			printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n",
-			       dev->name);
+		} else {
+			netif_info(tp, link, dev,
+				   "PHY does not support 1000Mbps\n");
 		}
 
 		bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
@@ -1042,14 +1042,14 @@ static void rtl8169_vlan_rx_register(str
 }
 
 static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
-			       struct sk_buff *skb)
+			       struct sk_buff *skb, int polling)
 {
 	u32 opts2 = le32_to_cpu(desc->opts2);
 	struct vlan_group *vlgrp = tp->vlgrp;
 	int ret;
 
 	if (vlgrp && (opts2 & RxVlanTag)) {
-		vlan_hwaccel_receive_skb(skb, vlgrp, swab16(opts2 & 0xffff));
+		__vlan_hwaccel_rx(skb, vlgrp, swab16(opts2 & 0xffff), polling);
 		ret = 0;
 	} else
 		ret = -1;
@@ -1066,7 +1066,7 @@ static inline u32 rtl8169_tx_vlan_tag(st
 }
 
 static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
-			       struct sk_buff *skb)
+			       struct sk_buff *skb, int polling)
 {
 	return -1;
 }
@@ -1873,8 +1873,7 @@ static void rtl8169_phy_timer(unsigned l
 	if (tp->link_ok(ioaddr))
 		goto out_unlock;
 
-	if (netif_msg_link(tp))
-		printk(KERN_WARNING "%s: PHY reset until link up\n", dev->name);
+	netif_warn(tp, link, dev, "PHY reset until link up\n");
 
 	tp->phy_reset_enable(ioaddr);
 
@@ -1928,6 +1927,7 @@ static void rtl8169_release_board(struct
 {
 	iounmap(ioaddr);
 	pci_release_regions(pdev);
+	pci_clear_mwi(pdev);
 	pci_disable_device(pdev);
 	free_netdev(dev);
 }
@@ -1944,8 +1944,7 @@ static void rtl8169_phy_reset(struct net
 			return;
 		msleep(1);
 	}
-	if (netif_msg_link(tp))
-		printk(KERN_ERR "%s: PHY reset failed.\n", dev->name);
+	netif_err(tp, link, dev, "PHY reset failed\n");
 }
 
 static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
@@ -1979,8 +1978,8 @@ static void rtl8169_init_phy(struct net_
 	 */
 	rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL);
 
-	if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp))
-		printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
+	if (RTL_R8(PHYstatus) & TBI_Enable)
+		netif_info(tp, link, dev, "TBI auto-negotiating\n");
 }
 
 static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
@@ -1995,8 +1994,13 @@ static void rtl_rar_set(struct rtl8169_p
 	spin_lock_irq(&tp->lock);
 
 	RTL_W8(Cfg9346, Cfg9346_Unlock);
-	RTL_W32(MAC0, low);
+
 	RTL_W32(MAC4, high);
+	RTL_R32(MAC4);
+
+	RTL_W32(MAC0, low);
+	RTL_R32(MAC0);
+
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 
 	spin_unlock_irq(&tp->lock);
@@ -2180,41 +2184,34 @@ rtl8169_init_one(struct pci_dev *pdev, c
 	/* enable device (incl. PCI PM wakeup and hotplug setup) */
 	rc = pci_enable_device(pdev);
 	if (rc < 0) {
-		if (netif_msg_probe(tp))
-			dev_err(&pdev->dev, "enable failure\n");
+		netif_err(tp, probe, dev, "enable failure\n");
 		goto err_out_free_dev_1;
 	}
 
-	rc = pci_set_mwi(pdev);
-	if (rc < 0)
-		goto err_out_disable_2;
+	if (pci_set_mwi(pdev) < 0)
+		netif_info(tp, probe, dev, "Mem-Wr-Inval unavailable\n");
 
 	/* make sure PCI base addr 1 is MMIO */
 	if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) {
-		if (netif_msg_probe(tp)) {
-			dev_err(&pdev->dev,
-				"region #%d not an MMIO resource, aborting\n",
-				region);
-		}
+		netif_err(tp, probe, dev,
+			  "region #%d not an MMIO resource, aborting\n",
+			  region);
 		rc = -ENODEV;
-		goto err_out_mwi_3;
+		goto err_out_mwi_2;
 	}
 
 	/* check for weird/broken PCI region reporting */
 	if (pci_resource_len(pdev, region) < R8169_REGS_SIZE) {
-		if (netif_msg_probe(tp)) {
-			dev_err(&pdev->dev,
-				"Invalid PCI region size(s), aborting\n");
-		}
+		netif_err(tp, probe, dev,
+			  "Invalid PCI region size(s), aborting\n");
 		rc = -ENODEV;
-		goto err_out_mwi_3;
+		goto err_out_mwi_2;
 	}
 
 	rc = pci_request_regions(pdev, MODULENAME);
 	if (rc < 0) {
-		if (netif_msg_probe(tp))
-			dev_err(&pdev->dev, "could not request regions.\n");
-		goto err_out_mwi_3;
+		netif_err(tp, probe, dev, "could not request regions\n");
+		goto err_out_mwi_2;
 	}
 
 	tp->cp_cmd = PCIMulRW | RxChkSum;
@@ -2226,26 +2223,22 @@ rtl8169_init_one(struct pci_dev *pdev, c
 	} else {
 		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc < 0) {
-			if (netif_msg_probe(tp)) {
-				dev_err(&pdev->dev,
-					"DMA configuration failed.\n");
-			}
-			goto err_out_free_res_4;
+			netif_err(tp, probe, dev, "DMA configuration failed\n");
+			goto err_out_free_res_3;
 		}
 	}
 
 	/* ioremap MMIO region */
 	ioaddr = ioremap(pci_resource_start(pdev, region), R8169_REGS_SIZE);
 	if (!ioaddr) {
-		if (netif_msg_probe(tp))
-			dev_err(&pdev->dev, "cannot remap MMIO, aborting\n");
+		netif_err(tp, probe, dev, "cannot remap MMIO, aborting\n");
 		rc = -EIO;
-		goto err_out_free_res_4;
+		goto err_out_free_res_3;
 	}
 
 	tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
-	if (!tp->pcie_cap && netif_msg_probe(tp))
-		dev_info(&pdev->dev, "no PCI Express capability\n");
+	if (!tp->pcie_cap)
+		netif_info(tp, probe, dev, "no PCI Express capability\n");
 
 	RTL_W16(IntrMask, 0x0000);
 
@@ -2268,10 +2261,8 @@ rtl8169_init_one(struct pci_dev *pdev, c
 
 	/* Use appropriate default if unknown */
 	if (tp->mac_version == RTL_GIGA_MAC_NONE) {
-		if (netif_msg_probe(tp)) {
-			dev_notice(&pdev->dev,
-				   "unknown MAC, using family default\n");
-		}
+		netif_notice(tp, probe, dev,
+			     "unknown MAC, using family default\n");
 		tp->mac_version = cfg->default_ver;
 	}
 
@@ -2284,7 +2275,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
 	if (i == ARRAY_SIZE(rtl_chip_info)) {
 		dev_err(&pdev->dev,
 			"driver bug, MAC version not found in rtl_chip_info\n");
-		goto err_out_msi_5;
+		goto err_out_msi_4;
 	}
 	tp->chipset = i;
 
@@ -2349,23 +2340,14 @@ rtl8169_init_one(struct pci_dev *pdev, c
 
 	rc = register_netdev(dev);
 	if (rc < 0)
-		goto err_out_msi_5;
+		goto err_out_msi_4;
 
 	pci_set_drvdata(pdev, dev);
 
-	if (netif_msg_probe(tp)) {
-		u32 xid = RTL_R32(TxConfig) & 0x9cf0f8ff;
-
-		printk(KERN_INFO "%s: %s at 0x%lx, "
-		       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
-		       "XID %08x IRQ %d\n",
-		       dev->name,
-		       rtl_chip_info[tp->chipset].name,
-		       dev->base_addr,
-		       dev->dev_addr[0], dev->dev_addr[1],
-		       dev->dev_addr[2], dev->dev_addr[3],
-		       dev->dev_addr[4], dev->dev_addr[5], xid, dev->irq);
-	}
+	netif_info(tp, probe, dev, "%s at 0x%lx, %pM, XID %08x IRQ %d\n",
+		   rtl_chip_info[tp->chipset].name,
+		   dev->base_addr, dev->dev_addr,
+		   (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq);
 
 	rtl8169_init_phy(dev, tp);
 
@@ -2381,14 +2363,13 @@ rtl8169_init_one(struct pci_dev *pdev, c
 out:
 	return rc;
 
-err_out_msi_5:
+err_out_msi_4:
 	rtl_disable_msi(pdev, tp);
 	iounmap(ioaddr);
-err_out_free_res_4:
+err_out_free_res_3:
 	pci_release_regions(pdev);
-err_out_mwi_3:
+err_out_mwi_2:
 	pci_clear_mwi(pdev);
-err_out_disable_2:
 	pci_disable_device(pdev);
 err_out_free_dev_1:
 	free_netdev(dev);
@@ -2413,9 +2394,13 @@ static void __devexit rtl8169_remove_one
 }
 
 static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
-				  struct net_device *dev)
+				  unsigned int mtu)
 {
-	unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
+	unsigned int max_frame = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
+
+	if (max_frame != 16383)
+		printk(KERN_WARNING PFX "WARNING! Changing of MTU on this "
+			"NIC may lead to frame reception errors!\n");
 
 	tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE;
 }
@@ -2427,7 +2412,17 @@ static int rtl8169_open(struct net_devic
 	int retval = -ENOMEM;
 
 
-	rtl8169_set_rxbufsize(tp, dev);
+	/*
+	 * Note that we use a magic value here, its wierd I know
+	 * its done because, some subset of rtl8169 hardware suffers from
+	 * a problem in which frames received that are longer than
+	 * the size set in RxMaxSize register return garbage sizes
+	 * when received.  To avoid this we need to turn off filtering,
+	 * which is done by setting a value of 16383 in the RxMaxSize register
+	 * and allocating 16k frames to handle the largest possible rx value
+	 * thats what the magic math below does.
+	 */
+	rtl8169_set_rxbufsize(tp, 16383 - VLAN_ETH_HLEN - ETH_FCS_LEN);
 
 	/*
 	 * Rx and Tx desscriptors needs 256 bytes alignment.
@@ -3080,7 +3075,7 @@ static int rtl8169_change_mtu(struct net
 
 	rtl8169_down(dev);
 
-	rtl8169_set_rxbufsize(tp, dev);
+	rtl8169_set_rxbufsize(tp, dev->mtu);
 
 	ret = rtl8169_init_ring(dev);
 	if (ret < 0)
@@ -3304,10 +3299,10 @@ static void rtl8169_reinit_task(struct w
 
 	ret = rtl8169_open(dev);
 	if (unlikely(ret < 0)) {
-		if (net_ratelimit() && netif_msg_drv(tp)) {
-			printk(KERN_ERR PFX "%s: reinit failure (status = %d)."
-			       " Rescheduling.\n", dev->name, ret);
-		}
+		if (net_ratelimit())
+			netif_err(tp, drv, dev,
+				  "reinit failure (status = %d). Rescheduling\n",
+				  ret);
 		rtl8169_schedule_work(dev, rtl8169_reinit_task);
 	}
 
@@ -3337,10 +3332,8 @@ static void rtl8169_reset_task(struct wo
 		netif_wake_queue(dev);
 		rtl8169_check_link_status(dev, tp, tp->mmio_addr);
 	} else {
-		if (net_ratelimit() && netif_msg_intr(tp)) {
-			printk(KERN_EMERG PFX "%s: Rx buffers shortage\n",
-			       dev->name);
-		}
+		if (net_ratelimit())
+			netif_emerg(tp, intr, dev, "Rx buffers shortage\n");
 		rtl8169_schedule_work(dev, rtl8169_reset_task);
 	}
 
@@ -3428,11 +3421,7 @@ static netdev_tx_t rtl8169_start_xmit(st
 	u32 opts1;
 
 	if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
-		if (netif_msg_drv(tp)) {
-			printk(KERN_ERR
-			       "%s: BUG! Tx Ring full when queue awake!\n",
-			       dev->name);
-		}
+		netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n");
 		goto err_stop;
 	}
 
@@ -3465,7 +3454,7 @@ static netdev_tx_t rtl8169_start_xmit(st
 
 	tp->cur_tx += frags + 1;
 
-	smp_wmb();
+	wmb();
 
 	RTL_W8(TxPoll, NPQ);	/* set polling bit */
 
@@ -3494,11 +3483,8 @@ static void rtl8169_pcierr_interrupt(str
 	pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
 	pci_read_config_word(pdev, PCI_STATUS, &pci_status);
 
-	if (netif_msg_intr(tp)) {
-		printk(KERN_ERR
-		       "%s: PCI error (cmd = 0x%04x, status = 0x%04x).\n",
-		       dev->name, pci_cmd, pci_status);
-	}
+	netif_err(tp, intr, dev, "PCI error (cmd = 0x%04x, status = 0x%04x)\n",
+		  pci_cmd, pci_status);
 
 	/*
 	 * The recovery sequence below admits a very elaborated explanation:
@@ -3522,8 +3508,7 @@ static void rtl8169_pcierr_interrupt(str
 
 	/* The infamous DAC f*ckup only happens at boot time */
 	if ((tp->cp_cmd & PCIDAC) && !tp->dirty_rx && !tp->cur_rx) {
-		if (netif_msg_intr(tp))
-			printk(KERN_INFO "%s: disabling PCI DAC.\n", dev->name);
+		netif_info(tp, intr, dev, "disabling PCI DAC\n");
 		tp->cp_cmd &= ~PCIDAC;
 		RTL_W16(CPlusCmd, tp->cp_cmd);
 		dev->features &= ~NETIF_F_HIGHDMA;
@@ -3628,12 +3613,20 @@ out:
 	return done;
 }
 
+/*
+ * Warning : rtl8169_rx_interrupt() might be called :
+ * 1) from NAPI (softirq) context
+ *	(polling = 1 : we should call netif_receive_skb())
+ * 2) from process context (rtl8169_reset_task())
+ *	(polling = 0 : we must call netif_rx() instead)
+ */
 static int rtl8169_rx_interrupt(struct net_device *dev,
 				struct rtl8169_private *tp,
 				void __iomem *ioaddr, u32 budget)
 {
 	unsigned int cur_rx, rx_left;
 	unsigned int delta, count;
+	int polling = (budget != ~(u32)0) ? 1 : 0;
 
 	cur_rx = tp->cur_rx;
 	rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
@@ -3650,11 +3643,8 @@ static int rtl8169_rx_interrupt(struct n
 		if (status & DescOwn)
 			break;
 		if (unlikely(status & RxRES)) {
-			if (netif_msg_rx_err(tp)) {
-				printk(KERN_INFO
-				       "%s: Rx ERROR. status = %08x\n",
-				       dev->name, status);
-			}
+			netif_info(tp, rx_err, dev, "Rx ERROR. status = %08x\n",
+				   status);
 			dev->stats.rx_errors++;
 			if (status & (RxRWT | RxRUNT))
 				dev->stats.rx_length_errors++;
@@ -3698,8 +3688,12 @@ static int rtl8169_rx_interrupt(struct n
 			skb_put(skb, pkt_size);
 			skb->protocol = eth_type_trans(skb, dev);
 
-			if (rtl8169_rx_vlan_skb(tp, desc, skb) < 0)
-				netif_receive_skb(skb);
+			if (rtl8169_rx_vlan_skb(tp, desc, skb, polling) < 0) {
+				if (likely(polling))
+					netif_receive_skb(skb);
+				else
+					netif_rx(skb);
+			}
 
 			dev->stats.rx_bytes += pkt_size;
 			dev->stats.rx_packets++;
@@ -3717,8 +3711,8 @@ static int rtl8169_rx_interrupt(struct n
 	tp->cur_rx = cur_rx;
 
 	delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx);
-	if (!delta && count && netif_msg_intr(tp))
-		printk(KERN_INFO "%s: no Rx buffer allocated\n", dev->name);
+	if (!delta && count)
+		netif_info(tp, intr, dev, "no Rx buffer allocated\n");
 	tp->dirty_rx += delta;
 
 	/*
@@ -3728,8 +3722,8 @@ static int rtl8169_rx_interrupt(struct n
 	 *   after refill ?
 	 * - how do others driver handle this condition (Uh oh...).
 	 */
-	if ((tp->dirty_rx + NUM_RX_DESC == tp->cur_rx) && netif_msg_intr(tp))
-		printk(KERN_EMERG "%s: Rx buffers exhausted\n", dev->name);
+	if (tp->dirty_rx + NUM_RX_DESC == tp->cur_rx)
+		netif_emerg(tp, intr, dev, "Rx buffers exhausted\n");
 
 	return count;
 }
@@ -3784,10 +3778,9 @@ static irqreturn_t rtl8169_interrupt(int
 
 			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);
-			}
+			else
+				netif_info(tp, intr, dev,
+					   "interrupt %04x in poll\n", status);
 		}
 
 		/* We only get a new MSI interrupt when all active irq
@@ -3824,7 +3817,7 @@ static int rtl8169_poll(struct napi_stru
 		 * until it does.
 		 */
 		tp->intr_mask = 0xffff;
-		smp_wmb();
+		wmb();
 		RTL_W16(IntrMask, tp->intr_event);
 	}
 
@@ -3923,27 +3916,22 @@ static void rtl_set_rx_mode(struct net_d
 
 	if (dev->flags & IFF_PROMISC) {
 		/* Unconditionally log net taps. */
-		if (netif_msg_link(tp)) {
-			printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n",
-			       dev->name);
-		}
+		netif_notice(tp, link, dev, "Promiscuous mode enabled\n");
 		rx_mode =
 		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
 		    AcceptAllPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
-	} else if ((dev->mc_count > multicast_filter_limit) ||
+	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
 		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter perfectly -- accept all multicasts. */
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
 	} else {
 		struct dev_mc_list *mclist;
-		unsigned int i;
 
 		rx_mode = AcceptBroadcast | AcceptMyPhys;
 		mc_filter[1] = mc_filter[0] = 0;
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-		     i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
 			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
 			rx_mode |= AcceptMulticast;
@@ -3962,8 +3950,8 @@ static void rtl_set_rx_mode(struct net_d
 		mc_filter[1] = swab32(data);
 	}
 
-	RTL_W32(MAR0 + 0, mc_filter[0]);
 	RTL_W32(MAR0 + 4, mc_filter[1]);
+	RTL_W32(MAR0 + 0, mc_filter[0]);
 
 	RTL_W32(RxConfig, tmp);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/rionet.c linux-libre-2.6.34-gnu1/drivers/net/rionet.c
--- linux-libre-2.6.33-gnu1/drivers/net/rionet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/rionet.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/rio.h>
 #include <linux/rio_drv.h>
+#include <linux/slab.h>
 #include <linux/rio_ids.h>
 
 #include <linux/netdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/rrunner.c linux-libre-2.6.34-gnu1/drivers/net/rrunner.c
--- linux-libre-2.6.33-gnu1/drivers/net/rrunner.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/rrunner.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
@@ -1688,7 +1689,7 @@ static int rr_ioctl(struct net_device *d
 	}
 }
 
-static struct pci_device_id rr_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(rr_pci_tbl) = {
 	{ PCI_VENDOR_ID_ESSENTIAL, PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER,
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0,}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/s2io.c linux-libre-2.6.34-gnu1/drivers/net/s2io.c
--- linux-libre-2.6.33-gnu1/drivers/net/s2io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/s2io.c	2010-05-16 17:17:36.000000000 -0400
@@ -79,6 +79,7 @@
 #include <linux/tcp.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <net/tcp.h>
 
 #include <asm/system.h>
@@ -523,7 +524,7 @@ module_param_array(rts_frm_len, uint, NU
  * S2IO device table.
  * This table lists all the devices that this driver supports.
  */
-static struct pci_device_id s2io_tbl[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(s2io_tbl) = {
 	{PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_S2IO_WIN,
 	 PCI_ANY_ID, PCI_ANY_ID},
 	{PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_S2IO_UNI,
@@ -923,8 +924,8 @@ static int init_shared_mem(struct s2io_n
 	tmp_v_addr = mac_control->stats_mem;
 	mac_control->stats_info = (struct stat_block *)tmp_v_addr;
 	memset(tmp_v_addr, 0, size);
-	DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n", dev->name,
-		  (unsigned long long)tmp_p_addr);
+	DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n",
+		dev_name(&nic->pdev->dev), (unsigned long long)tmp_p_addr);
 	mac_control->stats_info->sw_stat.mem_allocated += mem_allocated;
 	return SUCCESS;
 }
@@ -3480,7 +3481,7 @@ static void s2io_reset(struct s2io_nic *
 	struct swStat *swstats;
 
 	DBG_PRINT(INIT_DBG, "%s: Resetting XFrame card %s\n",
-		  __func__, sp->dev->name);
+		  __func__, pci_name(sp->pdev));
 
 	/* Back up  the PCI-X CMD reg, dont want to lose MMRBC, OST settings */
 	pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd));
@@ -5055,8 +5056,8 @@ static void s2io_set_multicast(struct ne
 	}
 
 	/*  Update individual M_CAST address list */
-	if ((!sp->m_cast_flg) && dev->mc_count) {
-		if (dev->mc_count >
+	if ((!sp->m_cast_flg) && netdev_mc_count(dev)) {
+		if (netdev_mc_count(dev) >
 		    (config->max_mc_addr - config->max_mac_addr)) {
 			DBG_PRINT(ERR_DBG,
 				  "%s: No more Rx filters can be added - "
@@ -5066,7 +5067,7 @@ static void s2io_set_multicast(struct ne
 		}
 
 		prev_cnt = sp->mc_addr_count;
-		sp->mc_addr_count = dev->mc_count;
+		sp->mc_addr_count = netdev_mc_count(dev);
 
 		/* Clear out the previous list of Mc in the H/W. */
 		for (i = 0; i < prev_cnt; i++) {
@@ -5092,8 +5093,8 @@ static void s2io_set_multicast(struct ne
 		}
 
 		/* Create the new Rx filter list and update the same in H/W. */
-		for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
-		     i++, mclist = mclist->next) {
+		i = 0;
+		netdev_for_each_mc_addr(mclist, dev) {
 			memcpy(sp->usr_addrs[i].addr, mclist->dmi_addr,
 			       ETH_ALEN);
 			mac_addr = 0;
@@ -5121,6 +5122,7 @@ static void s2io_set_multicast(struct ne
 					  dev->name);
 				return;
 			}
+			i++;
 		}
 	}
 }
@@ -5818,10 +5820,8 @@ static void s2io_vpd_read(struct s2io_ni
 		}
 	}
 
-	if ((!fail) && (vpd_data[1] < VPD_STRING_LEN)) {
-		memset(nic->product_name, 0, vpd_data[1]);
+	if ((!fail) && (vpd_data[1] < VPD_STRING_LEN))
 		memcpy(nic->product_name, &vpd_data[3], vpd_data[1]);
-	}
 	kfree(vpd_data);
 	swstats->mem_freed += 256;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sb1000.c linux-libre-2.6.34-gnu1/drivers/net/sb1000.c
--- linux-libre-2.6.33-gnu1/drivers/net/sb1000.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sb1000.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,7 +42,6 @@ static char version[] = "sb1000.c:v1.1.2
 #include <linux/errno.h>
 #include <linux/if_cablemodem.h> /* for SIOGCM/SIOSCM stuff */
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
@@ -52,6 +51,7 @@ static char version[] = "sb1000.c:v1.1.2
 #include <linux/pnp.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/processor.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sb1250-mac.c linux-libre-2.6.34-gnu1/drivers/net/sb1250-mac.c
--- linux-libre-2.6.33-gnu1/drivers/net/sb1250-mac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sb1250-mac.c	2010-05-16 17:17:36.000000000 -0400
@@ -2161,13 +2161,13 @@ static void sbmac_setmulti(struct sbmac_
 	 * XXX if the table overflows */
 
 	idx = 1;		/* skip station address */
-	mclist = dev->mc_list;
-	while (mclist && (idx < MAC_ADDR_COUNT)) {
+	netdev_for_each_mc_addr(mclist, dev) {
+		if (idx == MAC_ADDR_COUNT)
+			break;
 		reg = sbmac_addr2reg(mclist->dmi_addr);
 		port = sc->sbm_base + R_MAC_ADDR_BASE+(idx * sizeof(uint64_t));
 		__raw_writeq(reg, port);
 		idx++;
-		mclist = mclist->next;
 	}
 
 	/*
@@ -2353,17 +2353,36 @@ static int sbmac_init(struct platform_de
 
 	sc->mii_bus = mdiobus_alloc();
 	if (sc->mii_bus == NULL) {
-		sbmac_uninitctx(sc);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto uninit_ctx;
 	}
 
+	sc->mii_bus->name = sbmac_mdio_string;
+	snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx);
+	sc->mii_bus->priv = sc;
+	sc->mii_bus->read = sbmac_mii_read;
+	sc->mii_bus->write = sbmac_mii_write;
+	sc->mii_bus->irq = sc->phy_irq;
+	for (i = 0; i < PHY_MAX_ADDR; ++i)
+		sc->mii_bus->irq[i] = SBMAC_PHY_INT;
+
+	sc->mii_bus->parent = &pldev->dev;
+	/*
+	 * Probe PHY address
+	 */
+	err = mdiobus_register(sc->mii_bus);
+	if (err) {
+		printk(KERN_ERR "%s: unable to register MDIO bus\n",
+		       dev->name);
+		goto free_mdio;
+	}
+	dev_set_drvdata(&pldev->dev, sc->mii_bus);
+
 	err = register_netdev(dev);
 	if (err) {
 		printk(KERN_ERR "%s.%d: unable to register netdev\n",
 		       sbmac_string, idx);
-		mdiobus_free(sc->mii_bus);
-		sbmac_uninitctx(sc);
-		return err;
+		goto unreg_mdio;
 	}
 
 	pr_info("%s.%d: registered as %s\n", sbmac_string, idx, dev->name);
@@ -2379,19 +2398,15 @@ static int sbmac_init(struct platform_de
 	pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %pM\n",
 	       dev->name, base, eaddr);
 
-	sc->mii_bus->name = sbmac_mdio_string;
-	snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx);
-	sc->mii_bus->priv = sc;
-	sc->mii_bus->read = sbmac_mii_read;
-	sc->mii_bus->write = sbmac_mii_write;
-	sc->mii_bus->irq = sc->phy_irq;
-	for (i = 0; i < PHY_MAX_ADDR; ++i)
-		sc->mii_bus->irq[i] = SBMAC_PHY_INT;
-
-	sc->mii_bus->parent = &pldev->dev;
-	dev_set_drvdata(&pldev->dev, sc->mii_bus);
-
 	return 0;
+unreg_mdio:
+	mdiobus_unregister(sc->mii_bus);
+	dev_set_drvdata(&pldev->dev, NULL);
+free_mdio:
+	mdiobus_free(sc->mii_bus);
+uninit_ctx:
+	sbmac_uninitctx(sc);
+	return err;
 }
 
 
@@ -2417,16 +2432,6 @@ static int sbmac_open(struct net_device
 		goto out_err;
 	}
 
-	/*
-	 * Probe PHY address
-	 */
-	err = mdiobus_register(sc->mii_bus);
-	if (err) {
-		printk(KERN_ERR "%s: unable to register MDIO bus\n",
-		       dev->name);
-		goto out_unirq;
-	}
-
 	sc->sbm_speed = sbmac_speed_none;
 	sc->sbm_duplex = sbmac_duplex_none;
 	sc->sbm_fc = sbmac_fc_none;
@@ -2457,11 +2462,7 @@ static int sbmac_open(struct net_device
 	return 0;
 
 out_unregister:
-	mdiobus_unregister(sc->mii_bus);
-
-out_unirq:
 	free_irq(dev->irq, dev);
-
 out_err:
 	return err;
 }
@@ -2650,9 +2651,6 @@ static int sbmac_close(struct net_device
 
 	phy_disconnect(sc->phy_dev);
 	sc->phy_dev = NULL;
-
-	mdiobus_unregister(sc->mii_bus);
-
 	free_irq(dev->irq, dev);
 
 	sbdma_emptyring(&(sc->sbm_txdma));
@@ -2760,6 +2758,7 @@ static int __exit sbmac_remove(struct pl
 
 	unregister_netdev(dev);
 	sbmac_uninitctx(sc);
+	mdiobus_unregister(sc->mii_bus);
 	mdiobus_free(sc->mii_bus);
 	iounmap(sc->sbm_base);
 	free_netdev(dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sc92031.c linux-libre-2.6.34-gnu1/drivers/net/sc92031.c
--- linux-libre-2.6.33-gnu1/drivers/net/sc92031.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sc92031.c	2010-05-16 17:17:36.000000000 -0400
@@ -429,13 +429,13 @@ static void _sc92031_set_mar(struct net_
 	u32 mar0 = 0, mar1 = 0;
 
 	if ((dev->flags & IFF_PROMISC) ||
-	    dev->mc_count > multicast_filter_limit ||
+	    netdev_mc_count(dev) > multicast_filter_limit ||
 	    (dev->flags & IFF_ALLMULTI))
 		mar0 = mar1 = 0xffffffff;
 	else if (dev->flags & IFF_MULTICAST) {
 		struct dev_mc_list *mc_list;
 
-		for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) {
+		netdev_for_each_mc_addr(mc_list, dev) {
 			u32 crc;
 			unsigned bit = 0;
 
@@ -1589,7 +1589,7 @@ out:
 	return 0;
 }
 
-static struct pci_device_id sc92031_pci_device_id_table[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(sc92031_pci_device_id_table) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x2031) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x8139) },
 	{ PCI_DEVICE(0x1088, 0x2031) },
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/seeq8005.c linux-libre-2.6.34-gnu1/drivers/net/seeq8005.c
--- linux-libre-2.6.33-gnu1/drivers/net/seeq8005.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/seeq8005.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,7 +37,6 @@ static const char version[] =
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/efx.c linux-libre-2.6.34-gnu1/drivers/net/sfc/efx.c
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/efx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/efx.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/crc32.h>
 #include <linux/ethtool.h>
 #include <linux/topology.h>
+#include <linux/gfp.h>
 #include "net_driver.h"
 #include "efx.h"
 #include "mdio_10g.h"
@@ -1602,11 +1603,10 @@ static int efx_set_mac_address(struct ne
 static void efx_set_multicast_list(struct net_device *net_dev)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
-	struct dev_mc_list *mc_list = net_dev->mc_list;
+	struct dev_mc_list *mc_list;
 	union efx_multicast_hash *mc_hash = &efx->multicast_hash;
 	u32 crc;
 	int bit;
-	int i;
 
 	efx->promiscuous = !!(net_dev->flags & IFF_PROMISC);
 
@@ -1615,11 +1615,10 @@ static void efx_set_multicast_list(struc
 		memset(mc_hash, 0xff, sizeof(*mc_hash));
 	} else {
 		memset(mc_hash, 0x00, sizeof(*mc_hash));
-		for (i = 0; i < net_dev->mc_count; i++) {
+		netdev_for_each_mc_addr(mc_list, net_dev) {
 			crc = ether_crc_le(ETH_ALEN, mc_list->dmi_addr);
 			bit = crc & (EFX_MCAST_HASH_ENTRIES - 1);
 			set_bit_le(bit, mc_hash->byte);
-			mc_list = mc_list->next;
 		}
 
 		/* Broadcast packets go through the multicast hash filter.
@@ -1862,6 +1861,7 @@ out:
 	}
 
 	if (disabled) {
+		dev_close(efx->net_dev);
 		EFX_ERR(efx, "has been disabled\n");
 		efx->state = STATE_DISABLED;
 	} else {
@@ -1885,8 +1885,7 @@ static void efx_reset_work(struct work_s
 	}
 
 	rtnl_lock();
-	if (efx_reset(efx, efx->reset_pending))
-		dev_close(efx->net_dev);
+	(void)efx_reset(efx, efx->reset_pending);
 	rtnl_unlock();
 }
 
@@ -1940,7 +1939,7 @@ void efx_schedule_reset(struct efx_nic *
  **************************************************************************/
 
 /* PCI device ID table */
-static struct pci_device_id efx_pci_table[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(efx_pci_table) = {
 	{PCI_DEVICE(EFX_VENDID_SFC, FALCON_A_P_DEVID),
 	 .driver_data = (unsigned long) &falcon_a1_nic_type},
 	{PCI_DEVICE(EFX_VENDID_SFC, FALCON_B_P_DEVID),
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/efx.h linux-libre-2.6.34-gnu1/drivers/net/sfc/efx.h
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/efx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/efx.h	2010-05-16 17:17:36.000000000 -0400
@@ -79,8 +79,6 @@ extern int efx_reset_up(struct efx_nic *
 
 /* Global */
 extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
-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, bool rx_adaptive);
 extern int efx_request_power(struct efx_nic *efx, int mw, const char *name);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/ethtool.c linux-libre-2.6.34-gnu1/drivers/net/sfc/ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -196,7 +196,7 @@ int efx_ethtool_get_settings(struct net_
 	efx->phy_op->get_settings(efx, ecmd);
 	mutex_unlock(&efx->mac_lock);
 
-	/* Falcon GMAC does not support 1000Mbps HD */
+	/* GMAC does not support 1000Mbps HD */
 	ecmd->supported &= ~SUPPORTED_1000baseT_Half;
 	/* Both MACs support pause frames (bidirectional and respond-only) */
 	ecmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
@@ -216,7 +216,7 @@ int efx_ethtool_set_settings(struct net_
 	struct efx_nic *efx = netdev_priv(net_dev);
 	int rc;
 
-	/* Falcon GMAC does not support 1000Mbps HD */
+	/* GMAC does not support 1000Mbps HD */
 	if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) {
 		EFX_LOG(efx, "rejecting unsupported 1000Mbps HD"
 			" setting\n");
@@ -342,8 +342,8 @@ static int efx_ethtool_fill_self_tests(s
 	unsigned int n = 0, i;
 	enum efx_loopback_mode mode;
 
-	efx_fill_test(n++, strings, data, &tests->mdio,
-		      "core", 0, "mdio", NULL);
+	efx_fill_test(n++, strings, data, &tests->phy_alive,
+		      "phy", 0, "alive", NULL);
 	efx_fill_test(n++, strings, data, &tests->nvram,
 		      "core", 0, "nvram", NULL);
 	efx_fill_test(n++, strings, data, &tests->interrupt,
@@ -379,7 +379,7 @@ static int efx_ethtool_fill_self_tests(s
 			if (name == NULL)
 				break;
 
-			efx_fill_test(n++, strings, data, &tests->phy[i],
+			efx_fill_test(n++, strings, data, &tests->phy_ext[i],
 				      "phy", 0, name, NULL);
 		}
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon_boards.c linux-libre-2.6.34-gnu1/drivers/net/sfc/falcon_boards.c
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon_boards.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/falcon_boards.c	2010-05-16 17:17:36.000000000 -0400
@@ -728,15 +728,7 @@ static const struct falcon_board_type bo
 	},
 };
 
-static const struct falcon_board_type falcon_dummy_board = {
-	.init		= efx_port_dummy_op_int,
-	.init_phy	= efx_port_dummy_op_void,
-	.fini		= efx_port_dummy_op_void,
-	.set_id_led	= efx_port_dummy_op_set_id_led,
-	.monitor	= efx_port_dummy_op_int,
-};
-
-void falcon_probe_board(struct efx_nic *efx, u16 revision_info)
+int falcon_probe_board(struct efx_nic *efx, u16 revision_info)
 {
 	struct falcon_board *board = falcon_board(efx);
 	u8 type_id = FALCON_BOARD_TYPE(revision_info);
@@ -754,8 +746,9 @@ void falcon_probe_board(struct efx_nic *
 			 (efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC)
 			 ? board->type->ref_model : board->type->gen_type,
 			 'A' + board->major, board->minor);
+		return 0;
 	} else {
 		EFX_ERR(efx, "unknown board type %d\n", type_id);
-		board->type = &falcon_dummy_board;
+		return -ENODEV;
 	}
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon.c linux-libre-2.6.34-gnu1/drivers/net/sfc/falcon.c
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/falcon.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/seq_file.h>
 #include <linux/i2c.h>
 #include <linux/mii.h>
+#include <linux/slab.h>
 #include "net_driver.h"
 #include "bitfield.h"
 #include "efx.h"
@@ -909,6 +910,8 @@ static int falcon_probe_port(struct efx_
 		efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
 	else
 		efx->wanted_fc = EFX_FC_RX;
+	if (efx->mdio.mmds & MDIO_DEVS_AN)
+		efx->wanted_fc |= EFX_FC_AUTO;
 
 	/* Allocate buffer for stats */
 	rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
@@ -1006,7 +1009,7 @@ static int falcon_test_nvram(struct efx_
 
 static const struct efx_nic_register_test falcon_b0_register_tests[] = {
 	{ FR_AZ_ADR_REGION,
-	  EFX_OWORD32(0x0001FFFF, 0x0001FFFF, 0x0001FFFF, 0x0001FFFF) },
+	  EFX_OWORD32(0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF) },
 	{ FR_AZ_RX_CFG,
 	  EFX_OWORD32(0xFFFFFFFE, 0x00017FFF, 0x00000000, 0x00000000) },
 	{ FR_AZ_TX_CFG,
@@ -1317,7 +1320,9 @@ static int falcon_probe_nvconfig(struct
 
 	EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mdio.prtad);
 
-	falcon_probe_board(efx, board_rev);
+	rc = falcon_probe_board(efx, board_rev);
+	if (rc)
+		goto fail2;
 
 	kfree(nvconfig);
 	return 0;
@@ -1728,7 +1733,7 @@ static int falcon_set_wol(struct efx_nic
 
 /**************************************************************************
  *
- * Revision-dependent attributes used by efx.c
+ * Revision-dependent attributes used by efx.c and nic.c
  *
  **************************************************************************
  */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi.c linux-libre-2.6.34-gnu1/drivers/net/sfc/mcdi.c
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/mcdi.c	2010-05-16 17:17:36.000000000 -0400
@@ -896,29 +896,73 @@ fail:
 	return rc;
 }
 
-int efx_mcdi_handle_assertion(struct efx_nic *efx)
+static int efx_mcdi_nvram_test(struct efx_nic *efx, unsigned int type)
 {
-	union {
-		u8 asserts[MC_CMD_GET_ASSERTS_IN_LEN];
-		u8 reboot[MC_CMD_REBOOT_IN_LEN];
-	} inbuf;
-	u8 assertion[MC_CMD_GET_ASSERTS_OUT_LEN];
+	u8 inbuf[MC_CMD_NVRAM_TEST_IN_LEN];
+	u8 outbuf[MC_CMD_NVRAM_TEST_OUT_LEN];
+	int rc;
+
+	MCDI_SET_DWORD(inbuf, NVRAM_TEST_IN_TYPE, type);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_TEST, inbuf, sizeof(inbuf),
+			  outbuf, sizeof(outbuf), NULL);
+	if (rc)
+		return rc;
+
+	switch (MCDI_DWORD(outbuf, NVRAM_TEST_OUT_RESULT)) {
+	case MC_CMD_NVRAM_TEST_PASS:
+	case MC_CMD_NVRAM_TEST_NOTSUPP:
+		return 0;
+	default:
+		return -EIO;
+	}
+}
+
+int efx_mcdi_nvram_test_all(struct efx_nic *efx)
+{
+	u32 nvram_types;
+	unsigned int type;
+	int rc;
+
+	rc = efx_mcdi_nvram_types(efx, &nvram_types);
+	if (rc)
+		return rc;
+
+	type = 0;
+	while (nvram_types != 0) {
+		if (nvram_types & 1) {
+			rc = efx_mcdi_nvram_test(efx, type);
+			if (rc)
+				return rc;
+		}
+		type++;
+		nvram_types >>= 1;
+	}
+
+	return 0;
+}
+
+static int efx_mcdi_read_assertion(struct efx_nic *efx)
+{
+	u8 inbuf[MC_CMD_GET_ASSERTS_IN_LEN];
+	u8 outbuf[MC_CMD_GET_ASSERTS_OUT_LEN];
 	unsigned int flags, index, ofst;
 	const char *reason;
 	size_t outlen;
 	int retry;
 	int rc;
 
-	/* Check if the MC is in the assertion handler, retrying twice. Once
+	/* Attempt to read any stored assertion state before we reboot
+	 * the mcfw out of the assertion handler. Retry twice, once
 	 * because a boot-time assertion might cause this command to fail
 	 * with EINTR. And once again because GET_ASSERTS can race with
 	 * MC_CMD_REBOOT running on the other port. */
 	retry = 2;
 	do {
-		MCDI_SET_DWORD(inbuf.asserts, GET_ASSERTS_IN_CLEAR, 0);
+		MCDI_SET_DWORD(inbuf, GET_ASSERTS_IN_CLEAR, 1);
 		rc = efx_mcdi_rpc(efx, MC_CMD_GET_ASSERTS,
-				  inbuf.asserts, MC_CMD_GET_ASSERTS_IN_LEN,
-				  assertion, sizeof(assertion), &outlen);
+				  inbuf, MC_CMD_GET_ASSERTS_IN_LEN,
+				  outbuf, sizeof(outbuf), &outlen);
 	} while ((rc == -EINTR || rc == -EIO) && retry-- > 0);
 
 	if (rc)
@@ -926,21 +970,11 @@ int efx_mcdi_handle_assertion(struct efx
 	if (outlen < MC_CMD_GET_ASSERTS_OUT_LEN)
 		return -EINVAL;
 
-	flags = MCDI_DWORD(assertion, GET_ASSERTS_OUT_GLOBAL_FLAGS);
+	/* Print out any recorded assertion state */
+	flags = MCDI_DWORD(outbuf, GET_ASSERTS_OUT_GLOBAL_FLAGS);
 	if (flags == MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS)
 		return 0;
 
-	/* Reset the hardware atomically such that only one port with succeed.
-	 * This command will succeed if a reboot is no longer required (because
-	 * the other port did it first), but fail with EIO if it succeeds.
-	 */
-	BUILD_BUG_ON(MC_CMD_REBOOT_OUT_LEN != 0);
-	MCDI_SET_DWORD(inbuf.reboot, REBOOT_IN_FLAGS,
-		       MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION);
-	efx_mcdi_rpc(efx, MC_CMD_REBOOT, inbuf.reboot, MC_CMD_REBOOT_IN_LEN,
-		     NULL, 0, NULL);
-
-	/* Print out the assertion */
 	reason = (flags == MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL)
 		? "system-level assertion"
 		: (flags == MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL)
@@ -949,19 +983,44 @@ int efx_mcdi_handle_assertion(struct efx
 		? "watchdog reset"
 		: "unknown assertion";
 	EFX_ERR(efx, "MCPU %s at PC = 0x%.8x in thread 0x%.8x\n", reason,
-		MCDI_DWORD(assertion, GET_ASSERTS_OUT_SAVED_PC_OFFS),
-		MCDI_DWORD(assertion, GET_ASSERTS_OUT_THREAD_OFFS));
+		MCDI_DWORD(outbuf, GET_ASSERTS_OUT_SAVED_PC_OFFS),
+		MCDI_DWORD(outbuf, GET_ASSERTS_OUT_THREAD_OFFS));
 
 	/* Print out the registers */
 	ofst = MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST;
 	for (index = 1; index < 32; index++) {
 		EFX_ERR(efx, "R%.2d (?): 0x%.8x\n", index,
-			MCDI_DWORD2(assertion, ofst));
+			MCDI_DWORD2(outbuf, ofst));
 		ofst += sizeof(efx_dword_t);
 	}
 
 	return 0;
 }
+
+static void efx_mcdi_exit_assertion(struct efx_nic *efx)
+{
+	u8 inbuf[MC_CMD_REBOOT_IN_LEN];
+
+	/* Atomically reboot the mcfw out of the assertion handler */
+	BUILD_BUG_ON(MC_CMD_REBOOT_OUT_LEN != 0);
+	MCDI_SET_DWORD(inbuf, REBOOT_IN_FLAGS,
+		       MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION);
+	efx_mcdi_rpc(efx, MC_CMD_REBOOT, inbuf, MC_CMD_REBOOT_IN_LEN,
+		     NULL, 0, NULL);
+}
+
+int efx_mcdi_handle_assertion(struct efx_nic *efx)
+{
+	int rc;
+
+	rc = efx_mcdi_read_assertion(efx);
+	if (rc)
+		return rc;
+
+	efx_mcdi_exit_assertion(efx);
+
+	return 0;
+}
 
 void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi.h linux-libre-2.6.34-gnu1/drivers/net/sfc/mcdi.h
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/mcdi.h	2010-05-16 17:17:36.000000000 -0400
@@ -116,6 +116,7 @@ extern int efx_mcdi_nvram_erase(struct e
 				loff_t offset, size_t length);
 extern int efx_mcdi_nvram_update_finish(struct efx_nic *efx,
 					unsigned int type);
+extern int efx_mcdi_nvram_test_all(struct efx_nic *efx);
 extern int efx_mcdi_handle_assertion(struct efx_nic *efx);
 extern void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);
 extern int efx_mcdi_reset_port(struct efx_nic *efx);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi_pcol.h linux-libre-2.6.34-gnu1/drivers/net/sfc/mcdi_pcol.h
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi_pcol.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/mcdi_pcol.h	2010-05-16 17:17:36.000000000 -0400
@@ -786,16 +786,18 @@
 #define MC_CMD_GET_PHY_CFG_OUT_FLAGS_OFST 0
 #define MC_CMD_GET_PHY_CFG_PRESENT_LBN 0
 #define MC_CMD_GET_PHY_CFG_PRESENT_WIDTH 1
-#define MC_CMD_GET_PHY_CFG_SHORTBIST_LBN 1
-#define MC_CMD_GET_PHY_CFG_SHORTBIST_WIDTH 1
-#define MC_CMD_GET_PHY_CFG_LONGBIST_LBN 2
-#define MC_CMD_GET_PHY_CFG_LONGBIST_WIDTH 1
+#define MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_LBN 1
+#define MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_WIDTH 1
+#define MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN 2
+#define MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_WIDTH 1
 #define MC_CMD_GET_PHY_CFG_LOWPOWER_LBN 3
 #define MC_CMD_GET_PHY_CFG_LOWPOWER_WIDTH 1
 #define MC_CMD_GET_PHY_CFG_POWEROFF_LBN 4
 #define MC_CMD_GET_PHY_CFG_POWEROFF_WIDTH 1
 #define MC_CMD_GET_PHY_CFG_TXDIS_LBN 5
 #define MC_CMD_GET_PHY_CFG_TXDIS_WIDTH 1
+#define MC_CMD_GET_PHY_CFG_BIST_LBN 6
+#define MC_CMD_GET_PHY_CFG_BIST_WIDTH 1
 #define MC_CMD_GET_PHY_CFG_OUT_TYPE_OFST 4
 /* Bitmask of supported capabilities */
 #define MC_CMD_GET_PHY_CFG_OUT_SUPPORTED_CAP_OFST 8
@@ -832,7 +834,7 @@
 #define MC_CMD_GET_PHY_CFG_OUT_REVISION_OFST 52
 #define MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN 20
 
-/* MC_CMD_START_PHY_BIST:
+/* MC_CMD_START_BIST:
  * Start a BIST test on the PHY.
  *
  * Locks required: PHY_LOCK if doing a  PHY BIST
@@ -840,34 +842,71 @@
  */
 #define MC_CMD_START_BIST 0x25
 #define MC_CMD_START_BIST_IN_LEN 4
-#define MC_CMD_START_BIST_TYPE_OFST 0
+#define MC_CMD_START_BIST_IN_TYPE_OFST 0
+#define MC_CMD_START_BIST_OUT_LEN 0
 
-/* Run the PHY's short BIST */
-#define MC_CMD_PHY_BIST_SHORT  1
-/* Run the PHY's long BIST */
-#define MC_CMD_PHY_BIST_LONG   2
+/* Run the PHY's short cable BIST */
+#define MC_CMD_PHY_BIST_CABLE_SHORT  1
+/* Run the PHY's long cable BIST */
+#define MC_CMD_PHY_BIST_CABLE_LONG   2
 /* Run BIST on the currently selected BPX Serdes (XAUI or XFI) */
 #define MC_CMD_BPX_SERDES_BIST 3
+/* Run the MC loopback tests */
+#define MC_CMD_MC_LOOPBACK_BIST 4
+/* Run the PHY's standard BIST */
+#define MC_CMD_PHY_BIST 5
 
 /* MC_CMD_POLL_PHY_BIST: (variadic output)
  * Poll for BIST completion
  *
- * Returns a single status code, and a binary blob of phy-specific
- * bist output. If the driver can't succesfully parse the BIST output,
- * it should still respect the Pass/Fail in OUT.RESULT.
+ * Returns a single status code, and optionally some PHY specific
+ * bist output. The driver should only consume the BIST output
+ * after validating OUTLEN and PHY_CFG.PHY_TYPE.
  *
- * Locks required: PHY_LOCK  if doing a  PHY BIST
+ * If a driver can't succesfully parse the BIST output, it should
+ * still respect the pass/Fail in OUT.RESULT
+ *
+ * Locks required: PHY_LOCK if doing a  PHY BIST
  * Return code: 0, EACCES (if PHY_LOCK is not held)
  */
 #define MC_CMD_POLL_BIST 0x26
 #define MC_CMD_POLL_BIST_IN_LEN 0
 #define MC_CMD_POLL_BIST_OUT_LEN UNKNOWN
+#define MC_CMD_POLL_BIST_OUT_SFT9001_LEN 40
+#define MC_CMD_POLL_BIST_OUT_MRSFP_LEN 8
 #define MC_CMD_POLL_BIST_OUT_RESULT_OFST 0
 #define MC_CMD_POLL_BIST_RUNNING 1
 #define MC_CMD_POLL_BIST_PASSED 2
 #define MC_CMD_POLL_BIST_FAILED 3
 #define MC_CMD_POLL_BIST_TIMEOUT 4
+/* Generic: */
 #define MC_CMD_POLL_BIST_OUT_PRIVATE_OFST 4
+/* SFT9001-specific: */
+/* (offset 4 unused?) */
+#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A_OFST 8
+#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B_OFST 12
+#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C_OFST 16
+#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D_OFST 20
+#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_A_OFST 24
+#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_B_OFST 28
+#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_C_OFST 32
+#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_D_OFST 36
+#define MC_CMD_POLL_BIST_SFT9001_PAIR_OK 1
+#define MC_CMD_POLL_BIST_SFT9001_PAIR_OPEN 2
+#define MC_CMD_POLL_BIST_SFT9001_INTRA_PAIR_SHORT 3
+#define MC_CMD_POLL_BIST_SFT9001_INTER_PAIR_SHORT 4
+#define MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY 9
+/* mrsfp "PHY" driver: */
+#define MC_CMD_POLL_BIST_OUT_MRSFP_TEST_OFST 4
+#define MC_CMD_POLL_BIST_MRSFP_TEST_COMPLETE 0
+#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_WRITE 1
+#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_IO_EXP 2
+#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_MODULE 3
+#define MC_CMD_POLL_BIST_MRSFP_TEST_IO_EXP_I2C_CONFIGURE 4
+#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_I2C_NO_CROSSTALK 5
+#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_PRESENCE 6
+#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_I2C_ACCESS 7
+#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_SANE_VALUE 8
 
 /* MC_CMD_PHY_SPI: (variadic in, variadic out)
  * Read/Write/Erase the PHY SPI device
@@ -1206,6 +1245,13 @@
 #define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER4_OFST	\
 	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 178)
 
+#define MC_CMD_WOL_FILTER_SET_IN_LINK_MASK_OFST	\
+	MC_CMD_WOL_FILTER_SET_IN_DATA_OFST
+#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_LBN	0
+#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_WIDTH	1
+#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_LBN	1
+#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_WIDTH 1
+
 #define MC_CMD_WOL_FILTER_SET_OUT_LEN 4
 #define MC_CMD_WOL_FILTER_SET_OUT_FILTER_ID_OFST 0
 
@@ -1216,7 +1262,8 @@
 #define MC_CMD_WOL_TYPE_IPV4_SYN   0x3
 #define MC_CMD_WOL_TYPE_IPV6_SYN   0x4
 #define MC_CMD_WOL_TYPE_BITMAP     0x5
-#define MC_CMD_WOL_TYPE_MAX        0x6
+#define MC_CMD_WOL_TYPE_LINK       0x6
+#define MC_CMD_WOL_TYPE_MAX        0x7
 
 #define MC_CMD_FILTER_MODE_SIMPLE     0x0
 #define MC_CMD_FILTER_MODE_STRUCTURED 0xffffffff
@@ -1357,14 +1404,24 @@
  * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held)
  */
 #define MC_CMD_NVRAM_UPDATE_FINISH 0x3c
-#define MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN 4
+#define MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN 8
 #define MC_CMD_NVRAM_UPDATE_FINISH_IN_TYPE_OFST 0
+#define MC_CMD_NVRAM_UPDATE_FINISH_IN_REBOOT_OFST 4
 #define MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN 0
 
 /* MC_CMD_REBOOT:
- * Reboot the MC. The AFTER_ASSERTION flag is intended to be used
- * when the driver notices an assertion failure, to allow two ports to
- * both recover (semi-)gracefully.
+ * Reboot the MC.
+ *
+ * The AFTER_ASSERTION flag is intended to be used when the driver notices
+ * an assertion failure (at which point it is expected to perform a complete
+ * tear down and reinitialise), to allow both ports to reset the MC once
+ * in an atomic fashion.
+ *
+ * Production mc firmwares are generally compiled with REBOOT_ON_ASSERT=1,
+ * which means that they will automatically reboot out of the assertion
+ * handler, so this is in practise an optional operation. It is still
+ * recommended that drivers execute this to support custom firmwares
+ * with REBOOT_ON_ASSERT=0.
  *
  * Locks required: NONE
  * Returns: Nothing. You get back a response with ERR=1, DATALEN=0
@@ -1469,11 +1526,10 @@
 	((_ofst) + 6)
 
 /* MC_CMD_READ_SENSORS
- * Returns the current (value, state) for each sensor
+ * Returns the current reading from each sensor
  *
- * Returns the current (value, state) [each 16bit] of each sensor supported by
- * this board, by DMA'ing a sparse array (indexed by the sensor type) into host
- * memory.
+ * Returns a sparse array of sensor readings (indexed by the sensor
+ * type) into host memory.  Each array element is a dword.
  *
  * The MC will send a SENSOREVT event every time any sensor changes state. The
  * driver is responsible for ensuring that it doesn't miss any events. The board
@@ -1486,6 +1542,12 @@
 #define MC_CMD_READ_SENSORS_IN_DMA_ADDR_HI_OFST 4
 #define MC_CMD_READ_SENSORS_OUT_LEN 0
 
+/* Sensor reading fields */
+#define MC_CMD_READ_SENSOR_VALUE_LBN 0
+#define MC_CMD_READ_SENSOR_VALUE_WIDTH 16
+#define MC_CMD_READ_SENSOR_STATE_LBN 16
+#define MC_CMD_READ_SENSOR_STATE_WIDTH 8
+
 
 /* MC_CMD_GET_PHY_STATE:
  * Report current state of PHY.  A "zombie" PHY is a PHY that has failed to
@@ -1577,4 +1639,98 @@
 #define MC_CMD_MAC_RESET_RESTORE_IN_LEN 0
 #define MC_CMD_MAC_RESET_RESTORE_OUT_LEN 0
 
+
+/* MC_CMD_TEST_ASSERT:
+ * Deliberately trigger an assert-detonation in the firmware for testing
+ * purposes (i.e. to allow tests that the driver copes gracefully).
+ *
+ * Locks required: None
+ * Returns: 0
+ */
+
+#define MC_CMD_TESTASSERT 0x49
+#define MC_CMD_TESTASSERT_IN_LEN 0
+#define MC_CMD_TESTASSERT_OUT_LEN 0
+
+/* MC_CMD_WORKAROUND 0x4a
+ *
+ * Enable/Disable a given workaround. The mcfw will return EINVAL if it
+ * doesn't understand the given workaround number - which should not
+ * be treated as a hard error by client code.
+ *
+ * This op does not imply any semantics about each workaround, that's between
+ * the driver and the mcfw on a per-workaround basis.
+ *
+ * Locks required: None
+ * Returns: 0, EINVAL
+ */
+#define MC_CMD_WORKAROUND 0x4a
+#define MC_CMD_WORKAROUND_IN_LEN 8
+#define MC_CMD_WORKAROUND_IN_TYPE_OFST 0
+#define MC_CMD_WORKAROUND_BUG17230 1
+#define MC_CMD_WORKAROUND_IN_ENABLED_OFST 4
+#define MC_CMD_WORKAROUND_OUT_LEN 0
+
+/* MC_CMD_GET_PHY_MEDIA_INFO:
+ * Read media-specific data from PHY (e.g. SFP/SFP+ module ID information for
+ * SFP+ PHYs).
+ *
+ * The "media type" can be found via GET_PHY_CFG (GET_PHY_CFG_OUT_MEDIA_TYPE);
+ * the valid "page number" input values, and the output data, are interpreted
+ * on a per-type basis.
+ *
+ * For SFP+: PAGE=0 or 1 returns a 128-byte block read from module I2C address
+ *           0xA0 offset 0 or 0x80.
+ * Anything else: currently undefined.
+ *
+ * Locks required: None
+ * Return code: 0
+ */
+#define MC_CMD_GET_PHY_MEDIA_INFO 0x4b
+#define MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN 4
+#define MC_CMD_GET_PHY_MEDIA_INFO_IN_PAGE_OFST 0
+#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(_num_bytes) (4 + (_num_bytes))
+#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_OFST 0
+#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST 4
+
+/* MC_CMD_NVRAM_TEST:
+ * Test a particular NVRAM partition for valid contents (where "valid"
+ * depends on the type of partition).
+ *
+ * Locks required: None
+ * Return code: 0
+ */
+#define MC_CMD_NVRAM_TEST 0x4c
+#define MC_CMD_NVRAM_TEST_IN_LEN 4
+#define MC_CMD_NVRAM_TEST_IN_TYPE_OFST 0
+#define MC_CMD_NVRAM_TEST_OUT_LEN 4
+#define MC_CMD_NVRAM_TEST_OUT_RESULT_OFST 0
+#define MC_CMD_NVRAM_TEST_PASS 0
+#define MC_CMD_NVRAM_TEST_FAIL 1
+#define MC_CMD_NVRAM_TEST_NOTSUPP 2
+
+/* MC_CMD_MRSFP_TWEAK: (debug)
+ * Read status and/or set parameters for the "mrsfp" driver in mr_rusty builds.
+ * I2C I/O expander bits are always read; if equaliser parameters are supplied,
+ * they are configured first.
+ *
+ * Locks required: None
+ * Return code: 0, EINVAL
+ */
+#define MC_CMD_MRSFP_TWEAK 0x4d
+#define MC_CMD_MRSFP_TWEAK_IN_LEN_READ_ONLY 0
+#define MC_CMD_MRSFP_TWEAK_IN_LEN_EQ_CONFIG 16
+#define MC_CMD_MRSFP_TWEAK_IN_TXEQ_LEVEL_OFST 0    /* 0-6 low->high de-emph. */
+#define MC_CMD_MRSFP_TWEAK_IN_TXEQ_DT_CFG_OFST 4   /* 0-8 low->high ref.V */
+#define MC_CMD_MRSFP_TWEAK_IN_RXEQ_BOOST_OFST 8    /* 0-8 low->high boost */
+#define MC_CMD_MRSFP_TWEAK_IN_RXEQ_DT_CFG_OFST 12  /* 0-8 low->high ref.V */
+#define MC_CMD_MRSFP_TWEAK_OUT_LEN 12
+#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_INPUTS_OFST 0     /* input bits */
+#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_OUTPUTS_OFST 4    /* output bits */
+#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OFST 8  /* dirs: 0=out, 1=in */
+
+/* Do NOT add new commands beyond 0x4f as part of 3.0 : 0x50 - 0x7f will be
+ * used for post-3.0 extensions. If you run out of space, look for gaps or
+ * commands that are unused in the existing range. */
+
 #endif /* MCDI_PCOL_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi_phy.c linux-libre-2.6.34-gnu1/drivers/net/sfc/mcdi_phy.c
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi_phy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/mcdi_phy.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
  * Driver for PHY related operations via MCDI.
  */
 
+#include <linux/slab.h>
 #include "efx.h"
 #include "phy.h"
 #include "mcdi.h"
@@ -381,6 +382,18 @@ static int efx_mcdi_phy_probe(struct efx
 	 * but by convention we don't */
 	efx->loopback_modes &= ~(1 << LOOPBACK_NONE);
 
+	/* Set the initial link mode */
+	efx_mcdi_phy_decode_link(
+		efx, &efx->link_state,
+		MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
+		MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
+		MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
+
+	/* Default to Autonegotiated flow control if the PHY supports it */
+	efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
+	if (phy_data->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
+		efx->wanted_fc |= EFX_FC_AUTO;
+
 	return 0;
 
 fail:
@@ -436,7 +449,7 @@ void efx_mcdi_phy_check_fcntl(struct efx
 
 	/* The link partner capabilities are only relevent if the
 	 * link supports flow control autonegotiation */
-	if (~phy_cfg->supported_cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
+	if (~phy_cfg->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
 		return;
 
 	/* If flow control autoneg is supported and enabled, then fine */
@@ -560,6 +573,27 @@ static int efx_mcdi_phy_set_settings(str
 	return 0;
 }
 
+static int efx_mcdi_phy_test_alive(struct efx_nic *efx)
+{
+	u8 outbuf[MC_CMD_GET_PHY_STATE_OUT_LEN];
+	size_t outlen;
+	int rc;
+
+	BUILD_BUG_ON(MC_CMD_GET_PHY_STATE_IN_LEN != 0);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_STATE, NULL, 0,
+			  outbuf, sizeof(outbuf), &outlen);
+	if (rc)
+		return rc;
+
+	if (outlen < MC_CMD_GET_PHY_STATE_OUT_LEN)
+		return -EMSGSIZE;
+	if (MCDI_DWORD(outbuf, GET_PHY_STATE_STATE) != MC_CMD_PHY_STATE_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
 struct efx_phy_operations efx_mcdi_phy_ops = {
 	.probe		= efx_mcdi_phy_probe,
 	.init 	 	= efx_port_dummy_op_int,
@@ -569,6 +603,7 @@ struct efx_phy_operations efx_mcdi_phy_o
 	.remove		= efx_mcdi_phy_remove,
 	.get_settings	= efx_mcdi_phy_get_settings,
 	.set_settings	= efx_mcdi_phy_set_settings,
+	.test_alive	= efx_mcdi_phy_test_alive,
 	.run_tests	= NULL,
 	.test_name	= NULL,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/mdio_10g.c linux-libre-2.6.34-gnu1/drivers/net/sfc/mdio_10g.c
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/mdio_10g.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/mdio_10g.c	2010-05-16 17:17:36.000000000 -0400
@@ -335,3 +335,27 @@ enum efx_fc_type efx_mdio_get_pause(stru
 		mii_advertise_flowctrl(efx->wanted_fc),
 		efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_LPA));
 }
+
+int efx_mdio_test_alive(struct efx_nic *efx)
+{
+	int rc;
+	int devad = __ffs(efx->mdio.mmds);
+	u16 physid1, physid2;
+
+	mutex_lock(&efx->mac_lock);
+
+	physid1 = efx_mdio_read(efx, devad, MDIO_DEVID1);
+	physid2 = efx_mdio_read(efx, devad, MDIO_DEVID2);
+
+	if ((physid1 == 0x0000) || (physid1 == 0xffff) ||
+	    (physid2 == 0x0000) || (physid2 == 0xffff)) {
+		EFX_ERR(efx, "no MDIO PHY present with ID %d\n",
+			efx->mdio.prtad);
+		rc = -EINVAL;
+	} else {
+		rc = efx_mdio_check_mmds(efx, efx->mdio.mmds, 0);
+	}
+
+	mutex_unlock(&efx->mac_lock);
+	return rc;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/mdio_10g.h linux-libre-2.6.34-gnu1/drivers/net/sfc/mdio_10g.h
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/mdio_10g.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/mdio_10g.h	2010-05-16 17:17:36.000000000 -0400
@@ -106,4 +106,7 @@ efx_mdio_set_flag(struct efx_nic *efx, i
 	mdio_set_flag(&efx->mdio, efx->mdio.prtad, devad, addr, mask, state);
 }
 
+/* Liveness self-test for MDIO PHYs */
+extern int efx_mdio_test_alive(struct efx_nic *efx);
+
 #endif /* EFX_MDIO_10G_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/mtd.c linux-libre-2.6.34-gnu1/drivers/net/sfc/mtd.c
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/mtd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/mtd.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/mtd/mtd.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/rtnetlink.h>
 
 #define EFX_DRIVER_NAME "sfc_mtd"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/net_driver.h linux-libre-2.6.34-gnu1/drivers/net/sfc/net_driver.h
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/net_driver.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/net_driver.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
-#include <linux/timer.h>
 #include <linux/mdio.h>
 #include <linux/list.h>
 #include <linux/pci.h>
@@ -101,9 +100,6 @@ do {if (net_ratelimit()) EFX_LOG(efx, fm
  * Special buffers are used for the event queues and the TX and RX
  * descriptor queues for each channel.  They are *not* used for the
  * actual transmit and receive buffers.
- *
- * Note that for Falcon, TX and RX descriptor queues live in host memory.
- * Allocation and freeing procedures must take this into account.
  */
 struct efx_special_buffer {
 	void *addr;
@@ -300,7 +296,7 @@ struct efx_rx_queue {
  * @dma_addr: DMA base address of the buffer
  * @len: Buffer length, in bytes
  *
- * Falcon uses these buffers for its interrupt status registers and
+ * The NIC uses these buffers for its interrupt status registers and
  * MAC stats dumps.
  */
 struct efx_buffer {
@@ -516,8 +512,9 @@ struct efx_mac_operations {
  * @set_settings: Set ethtool settings. Serialised by the mac_lock.
  * @set_npage_adv: Set abilities advertised in (Extended) Next Page
  *	(only needed where AN bit is set in mmds)
+ * @test_alive: Test that PHY is 'alive' (online)
  * @test_name: Get the name of a PHY-specific test/result
- * @run_tests: Run tests and record results as appropriate.
+ * @run_tests: Run tests and record results as appropriate (offline).
  *	Flags are the ethtool tests flags.
  */
 struct efx_phy_operations {
@@ -532,6 +529,7 @@ struct efx_phy_operations {
 	int (*set_settings) (struct efx_nic *efx,
 			     struct ethtool_cmd *ecmd);
 	void (*set_npage_adv) (struct efx_nic *efx, u32);
+	int (*test_alive) (struct efx_nic *efx);
 	const char *(*test_name) (struct efx_nic *efx, unsigned int index);
 	int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags);
 };
@@ -672,7 +670,7 @@ union efx_multicast_hash {
  * @irq_status: Interrupt status buffer
  * @last_irq_cpu: Last CPU to handle interrupt.
  *	This register is written with the SMP processor ID whenever an
- *	interrupt is handled.  It is used by falcon_test_interrupt()
+ *	interrupt is handled.  It is used by efx_nic_test_interrupt()
  *	to verify that an interrupt has occurred.
  * @spi_flash: SPI flash device
  *	This field will be %NULL if no flash device is present (or for Siena).
@@ -721,8 +719,7 @@ union efx_multicast_hash {
  * @loopback_modes: Supported loopback mode bitmask
  * @loopback_selftest: Offline self-test private state
  *
- * The @priv field of the corresponding &struct net_device points to
- * this.
+ * This is stored in the private area of the &struct net_device.
  */
 struct efx_nic {
 	char name[IFNAMSIZ];
@@ -995,7 +992,7 @@ static inline void clear_bit_le(unsigned
  * that the net driver will program into the MAC as the maximum frame
  * length.
  *
- * The 10G MAC used in Falcon requires 8-byte alignment on the frame
+ * The 10G MAC requires 8-byte alignment on the frame
  * length, so we round up to the nearest 8.
  *
  * Re-clocking by the XGXS on RX can reduce an IPG to 32 bits (half an
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/nic.c linux-libre-2.6.34-gnu1/drivers/net/sfc/nic.c
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/nic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/nic.c	2010-05-16 17:17:36.000000000 -0400
@@ -623,10 +623,6 @@ void efx_nic_remove_rx(struct efx_rx_que
  *
  * This writes the EVQ_RPTR_REG register for the specified channel's
  * event queue.
- *
- * Note that EVQ_RPTR_REG contains the index of the "last read" event,
- * whereas channel->eventq_read_ptr contains the index of the "next to
- * read" event.
  */
 void efx_nic_eventq_read_ack(struct efx_channel *channel)
 {
@@ -1384,6 +1380,15 @@ static irqreturn_t efx_legacy_interrupt(
 		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));
+	} else if (EFX_WORKAROUND_15783(efx)) {
+		/* We can't return IRQ_HANDLED more than once on seeing ISR0=0
+		 * because this might be a shared interrupt, but we do need to
+		 * check the channel every time and preemptively rearm it if
+		 * it's idle. */
+		efx_for_each_channel(channel, efx) {
+			if (!channel->work_pending)
+				efx_nic_eventq_read_ack(channel);
+		}
 	}
 
 	return result;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/nic.h linux-libre-2.6.34-gnu1/drivers/net/sfc/nic.h
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/nic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/nic.h	2010-05-16 17:17:36.000000000 -0400
@@ -156,7 +156,7 @@ extern struct efx_nic_type siena_a0_nic_
  **************************************************************************
  */
 
-extern void falcon_probe_board(struct efx_nic *efx, u16 revision_info);
+extern int falcon_probe_board(struct efx_nic *efx, u16 revision_info);
 
 /* TX data path */
 extern int efx_nic_probe_tx(struct efx_tx_queue *tx_queue);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/qt202x_phy.c linux-libre-2.6.34-gnu1/drivers/net/sfc/qt202x_phy.c
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/qt202x_phy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/qt202x_phy.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  * Driver for AMCC QT202x SFP+ and XFP adapters; see www.amcc.com for details
  */
 
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/delay.h>
 #include "efx.h"
@@ -445,4 +446,5 @@ struct efx_phy_operations falcon_qt202x_
 	.remove	  	 = qt202x_phy_remove,
 	.get_settings	 = qt202x_phy_get_settings,
 	.set_settings	 = efx_mdio_set_settings,
+	.test_alive	 = efx_mdio_test_alive,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/regs.h linux-libre-2.6.34-gnu1/drivers/net/sfc/regs.h
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/regs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/regs.h	2010-05-16 17:17:36.000000000 -0400
@@ -95,7 +95,7 @@
 #define	FRF_AA_INT_ACK_KER_FIELD_LBN 0
 #define	FRF_AA_INT_ACK_KER_FIELD_WIDTH 32
 
-/* INT_ISR0_REG: Function 0 Interrupt Acknowlege Status register */
+/* INT_ISR0_REG: Function 0 Interrupt Acknowledge Status register */
 #define	FR_BZ_INT_ISR0 0x00000090
 #define	FRF_BZ_INT_ISR_REG_LBN 0
 #define	FRF_BZ_INT_ISR_REG_WIDTH 64
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/rx.c linux-libre-2.6.34-gnu1/drivers/net/sfc/rx.c
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 
 #include <linux/socket.h>
 #include <linux/in.h>
+#include <linux/slab.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/selftest.c linux-libre-2.6.34-gnu1/drivers/net/sfc/selftest.c
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/selftest.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/selftest.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,15 +18,13 @@
 #include <linux/in.h>
 #include <linux/udp.h>
 #include <linux/rtnetlink.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include "net_driver.h"
 #include "efx.h"
 #include "nic.h"
 #include "selftest.h"
 #include "workarounds.h"
-#include "spi.h"
-#include "io.h"
-#include "mdio_10g.h"
 
 /*
  * Loopback test packet structure
@@ -76,42 +74,15 @@ struct efx_loopback_state {
  *
  **************************************************************************/
 
-static int efx_test_mdio(struct efx_nic *efx, struct efx_self_tests *tests)
+static int efx_test_phy_alive(struct efx_nic *efx, struct efx_self_tests *tests)
 {
 	int rc = 0;
-	int devad;
-	u16 physid1, physid2;
-
-	if (efx->mdio.mode_support & MDIO_SUPPORTS_C45)
-		devad = __ffs(efx->mdio.mmds);
-	else if (efx->mdio.mode_support & MDIO_SUPPORTS_C22)
-		devad = MDIO_DEVAD_NONE;
-	else
-		return 0;
 
-	mutex_lock(&efx->mac_lock);
-	tests->mdio = -1;
-
-	physid1 = efx_mdio_read(efx, devad, MDIO_DEVID1);
-	physid2 = efx_mdio_read(efx, devad, MDIO_DEVID2);
-
-	if ((physid1 == 0x0000) || (physid1 == 0xffff) ||
-	    (physid2 == 0x0000) || (physid2 == 0xffff)) {
-		EFX_ERR(efx, "no MDIO PHY present with ID %d\n",
-			efx->mdio.prtad);
-		rc = -EINVAL;
-		goto out;
-	}
-
-	if (EFX_IS10G(efx)) {
-		rc = efx_mdio_check_mmds(efx, efx->mdio.mmds, 0);
-		if (rc)
-			goto out;
+	if (efx->phy_op->test_alive) {
+		rc = efx->phy_op->test_alive(efx);
+		tests->phy_alive = rc ? -1 : 1;
 	}
 
-out:
-	mutex_unlock(&efx->mac_lock);
-	tests->mdio = rc ? -1 : 1;
 	return rc;
 }
 
@@ -258,7 +229,7 @@ static int efx_test_phy(struct efx_nic *
 		return 0;
 
 	mutex_lock(&efx->mac_lock);
-	rc = efx->phy_op->run_tests(efx, tests->phy, flags);
+	rc = efx->phy_op->run_tests(efx, tests->phy_ext, flags);
 	mutex_unlock(&efx->mac_lock);
 	return rc;
 }
@@ -684,7 +655,7 @@ int efx_selftest(struct efx_nic *efx, st
 	/* Online (i.e. non-disruptive) testing
 	 * This checks interrupt generation, event delivery and PHY presence. */
 
-	rc = efx_test_mdio(efx, tests);
+	rc = efx_test_phy_alive(efx, tests);
 	if (rc && !rc_test)
 		rc_test = rc;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/selftest.h linux-libre-2.6.34-gnu1/drivers/net/sfc/selftest.h
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/selftest.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/selftest.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,7 @@ struct efx_loopback_self_tests {
  */
 struct efx_self_tests {
 	/* online tests */
-	int mdio;
+	int phy_alive;
 	int nvram;
 	int interrupt;
 	int eventq_dma[EFX_MAX_CHANNELS];
@@ -40,7 +40,7 @@ struct efx_self_tests {
 	int eventq_poll[EFX_MAX_CHANNELS];
 	/* offline tests */
 	int registers;
-	int phy[EFX_MAX_PHY_TESTS];
+	int phy_ext[EFX_MAX_PHY_TESTS];
 	struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX + 1];
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/siena.c linux-libre-2.6.34-gnu1/drivers/net/sfc/siena.c
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/siena.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/siena.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include "net_driver.h"
 #include "bitfield.h"
 #include "efx.h"
@@ -106,16 +107,11 @@ static int siena_probe_port(struct efx_n
 	efx->mdio.mdio_read = siena_mdio_read;
 	efx->mdio.mdio_write = siena_mdio_write;
 
-	/* Fill out MDIO structure and loopback modes */
+	/* Fill out MDIO structure, loopback modes, and initial link state */
 	rc = efx->phy_op->probe(efx);
 	if (rc != 0)
 		return rc;
 
-	/* Initial assumption */
-	efx->link_state.speed = 10000;
-	efx->link_state.fd = true;
-	efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
-
 	/* Allocate buffer for stats */
 	rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
 				  MC_CMD_MAC_NSTATS * sizeof(u64));
@@ -139,7 +135,7 @@ void siena_remove_port(struct efx_nic *e
 
 static const struct efx_nic_register_test siena_register_tests[] = {
 	{ FR_AZ_ADR_REGION,
-	  EFX_OWORD32(0x0001FFFF, 0x0001FFFF, 0x0001FFFF, 0x0001FFFF) },
+	  EFX_OWORD32(0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF) },
 	{ FR_CZ_USR_EV_CFG,
 	  EFX_OWORD32(0x000103FF, 0x00000000, 0x00000000, 0x00000000) },
 	{ FR_AZ_RX_CFG,
@@ -181,6 +177,12 @@ static int siena_test_registers(struct e
 
 static int siena_reset_hw(struct efx_nic *efx, enum reset_type method)
 {
+	int rc;
+
+	/* Recover from a failed assertion pre-reset */
+	rc = efx_mcdi_handle_assertion(efx);
+	if (rc)
+		return rc;
 
 	if (method == RESET_TYPE_WORLD)
 		return efx_mcdi_reset_mc(efx);
@@ -454,8 +456,17 @@ static int siena_try_update_nic_stats(st
 
 static void siena_update_nic_stats(struct efx_nic *efx)
 {
-	while (siena_try_update_nic_stats(efx) == -EAGAIN)
-		cpu_relax();
+	int retry;
+
+	/* If we're unlucky enough to read statistics wduring the DMA, wait
+	 * up to 10ms for it to finish (typically takes <500us) */
+	for (retry = 0; retry < 100; ++retry) {
+		if (siena_try_update_nic_stats(efx) == 0)
+			return;
+		udelay(100);
+	}
+
+	/* Use the old values instead */
 }
 
 static void siena_start_nic_stats(struct efx_nic *efx)
@@ -582,6 +593,7 @@ struct efx_nic_type siena_a0_nic_type =
 	.set_wol = siena_set_wol,
 	.resume_wol = siena_init_wol,
 	.test_registers = siena_test_registers,
+	.test_nvram = efx_mcdi_nvram_test_all,
 	.default_mac_ops = &efx_mcdi_mac_operations,
 
 	.revision = EFX_REV_SIENA_A0,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/tenxpress.c linux-libre-2.6.34-gnu1/drivers/net/sfc/tenxpress.c
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/tenxpress.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/tenxpress.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/delay.h>
 #include <linux/rtnetlink.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "efx.h"
 #include "mdio_10g.h"
 #include "nic.h"
@@ -842,6 +843,7 @@ struct efx_phy_operations falcon_sfx7101
 	.get_settings	  = tenxpress_get_settings,
 	.set_settings	  = tenxpress_set_settings,
 	.set_npage_adv    = sfx7101_set_npage_adv,
+	.test_alive	  = efx_mdio_test_alive,
 	.test_name	  = sfx7101_test_name,
 	.run_tests	  = sfx7101_run_tests,
 };
@@ -856,6 +858,7 @@ struct efx_phy_operations falcon_sft9001
 	.get_settings	  = tenxpress_get_settings,
 	.set_settings	  = tenxpress_set_settings,
 	.set_npage_adv    = sft9001_set_npage_adv,
+	.test_alive	  = efx_mdio_test_alive,
 	.test_name	  = sft9001_test_name,
 	.run_tests	  = sft9001_run_tests,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sfc/tx.c linux-libre-2.6.34-gnu1/drivers/net/sfc/tx.c
--- linux-libre-2.6.33-gnu1/drivers/net/sfc/tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sfc/tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/ip.h>
 #include <linux/in.h>
 #include <linux/ipv6.h>
+#include <linux/slab.h>
 #include <net/ipv6.h>
 #include <linux/if_ether.h>
 #include <linux/highmem.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sgiseeq.c linux-libre-2.6.34-gnu1/drivers/net/sgiseeq.c
--- linux-libre-2.6.33-gnu1/drivers/net/sgiseeq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sgiseeq.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/types.h>
@@ -592,8 +593,10 @@ static int sgiseeq_start_xmit(struct sk_
 	/* Setup... */
 	len = skb->len;
 	if (len < ETH_ZLEN) {
-		if (skb_padto(skb, ETH_ZLEN))
+		if (skb_padto(skb, ETH_ZLEN)) {
+			spin_unlock_irqrestore(&sp->tx_lock, flags);
 			return NETDEV_TX_OK;
+		}
 		len = ETH_ZLEN;
 	}
 
@@ -660,7 +663,7 @@ static void sgiseeq_set_multicast(struct
 
 	if(dev->flags & IFF_PROMISC)
 		sp->mode = SEEQ_RCMD_RANY;
-	else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count)
+	else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev))
 		sp->mode = SEEQ_RCMD_RBMCAST;
 	else
 		sp->mode = SEEQ_RCMD_RBCAST;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sh_eth.c linux-libre-2.6.34-gnu1/drivers/net/sh_eth.c
--- linux-libre-2.6.33-gnu1/drivers/net/sh_eth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sh_eth.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/cache.h>
 #include <linux/io.h>
 #include <linux/pm_runtime.h>
+#include <linux/slab.h>
 #include <asm/cacheflush.h>
 
 #include "sh_eth.h"
@@ -1473,13 +1474,9 @@ static int sh_eth_drv_probe(struct platf
 	if (ret)
 		goto out_unregister;
 
-	/* pritnt device infomation */
-	pr_info("Base address at 0x%x, ",
-	       (u32)ndev->base_addr);
-
-	for (i = 0; i < 5; i++)
-		printk("%02X:", ndev->dev_addr[i]);
-	printk("%02X, IRQ %d.\n", ndev->dev_addr[i], ndev->irq);
+	/* print device infomation */
+	pr_info("Base address at 0x%x, %pM, IRQ %d.\n",
+	       (u32)ndev->base_addr, ndev->dev_addr, ndev->irq);
 
 	platform_set_drvdata(pdev, ndev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sis190.c linux-libre-2.6.34-gnu1/drivers/net/sis190.c
--- linux-libre-2.6.33-gnu1/drivers/net/sis190.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sis190.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,9 @@
 
    See the file COPYING in this distribution for more information.
 
- */
+*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -30,27 +32,16 @@
 #include <linux/delay.h>
 #include <linux/crc32.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <asm/irq.h>
 
-#define net_drv(p, arg...)	if (netif_msg_drv(p)) \
-					printk(arg)
-#define net_probe(p, arg...)	if (netif_msg_probe(p)) \
-					printk(arg)
-#define net_link(p, arg...)	if (netif_msg_link(p)) \
-					printk(arg)
-#define net_intr(p, arg...)	if (netif_msg_intr(p)) \
-					printk(arg)
-#define net_tx_err(p, arg...)	if (netif_msg_tx_err(p)) \
-					printk(arg)
-
 #define PHY_MAX_ADDR		32
 #define PHY_ID_ANY		0x1f
 #define MII_REG_ANY		0x1f
 
-#define DRV_VERSION		"1.3"
+#define DRV_VERSION		"1.4"
 #define DRV_NAME		"sis190"
 #define SIS190_DRIVER_NAME	DRV_NAME " Gigabit Ethernet driver " DRV_VERSION
-#define PFX DRV_NAME ": "
 
 #define sis190_rx_skb			netif_rx
 #define sis190_rx_quota(count, quota)	count
@@ -294,6 +285,12 @@ struct sis190_private {
 	struct mii_if_info mii_if;
 	struct list_head first_phy;
 	u32 features;
+	u32 negotiated_lpa;
+	enum {
+		LNK_OFF,
+		LNK_ON,
+		LNK_AUTONEG,
+	} link_status;
 };
 
 struct sis190_phy {
@@ -334,7 +331,7 @@ static const struct {
 	{ "SiS 191 PCI Gigabit Ethernet adapter" },
 };
 
-static struct pci_device_id sis190_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(sis190_pci_tbl) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0191), 0, 0, 1 },
 	{ 0, },
@@ -381,7 +378,7 @@ static void __mdio_cmd(void __iomem *ioa
 	}
 
 	if (i > 99)
-		printk(KERN_ERR PFX "PHY command failed !\n");
+		pr_err("PHY command failed !\n");
 }
 
 static void mdio_write(void __iomem *ioaddr, int phy_id, int reg, int val)
@@ -493,18 +490,24 @@ static struct sk_buff *sis190_alloc_rx_s
 {
 	u32 rx_buf_sz = tp->rx_buf_sz;
 	struct sk_buff *skb;
+	dma_addr_t mapping;
 
 	skb = netdev_alloc_skb(tp->dev, rx_buf_sz);
-	if (likely(skb)) {
-		dma_addr_t mapping;
-
-		mapping = pci_map_single(tp->pci_dev, skb->data, tp->rx_buf_sz,
-					 PCI_DMA_FROMDEVICE);
-		sis190_map_to_asic(desc, mapping, rx_buf_sz);
-	} else
-		sis190_make_unusable_by_asic(desc);
+	if (unlikely(!skb))
+		goto skb_alloc_failed;
+	mapping = pci_map_single(tp->pci_dev, skb->data, tp->rx_buf_sz,
+			PCI_DMA_FROMDEVICE);
+	if (pci_dma_mapping_error(tp->pci_dev, mapping))
+		goto out;
+	sis190_map_to_asic(desc, mapping, rx_buf_sz);
 
 	return skb;
+
+out:
+	dev_kfree_skb_any(skb);
+skb_alloc_failed:
+	sis190_make_unusable_by_asic(desc);
+	return NULL;
 }
 
 static u32 sis190_rx_fill(struct sis190_private *tp, struct net_device *dev,
@@ -589,8 +592,7 @@ static int sis190_rx_interrupt(struct ne
 
 		status = le32_to_cpu(desc->PSize);
 
-		// net_intr(tp, KERN_INFO "%s: Rx PSize = %08x.\n", dev->name,
-		//	 status);
+		//netif_info(tp, intr, dev, "Rx PSize = %08x\n", status);
 
 		if (sis190_rx_pkt_err(status, stats) < 0)
 			sis190_give_to_asic(desc, tp->rx_buf_sz);
@@ -601,9 +603,8 @@ static int sis190_rx_interrupt(struct ne
 			struct pci_dev *pdev = tp->pci_dev;
 
 			if (unlikely(pkt_size > tp->rx_buf_sz)) {
-				net_intr(tp, KERN_INFO
-					 "%s: (frag) status = %08x.\n",
-					 dev->name, status);
+				netif_info(tp, intr, dev,
+					   "(frag) status = %08x\n", status);
 				stats->rx_dropped++;
 				stats->rx_length_errors++;
 				sis190_give_to_asic(desc, tp->rx_buf_sz);
@@ -637,12 +638,12 @@ static int sis190_rx_interrupt(struct ne
 	tp->cur_rx = cur_rx;
 
 	delta = sis190_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx);
-	if (!delta && count && netif_msg_intr(tp))
-		printk(KERN_INFO "%s: no Rx buffer allocated.\n", dev->name);
+	if (!delta && count)
+		netif_info(tp, intr, dev, "no Rx buffer allocated\n");
 	tp->dirty_rx += delta;
 
-	if (((tp->dirty_rx + NUM_RX_DESC) == tp->cur_rx) && netif_msg_intr(tp))
-		printk(KERN_EMERG "%s: Rx buffers exhausted.\n", dev->name);
+	if ((tp->dirty_rx + NUM_RX_DESC) == tp->cur_rx)
+		netif_emerg(tp, intr, dev, "Rx buffers exhausted\n");
 
 	return count;
 }
@@ -751,10 +752,11 @@ static irqreturn_t sis190_interrupt(int
 
 	SIS_W32(IntrStatus, status);
 
-	// net_intr(tp, KERN_INFO "%s: status = %08x.\n", dev->name, status);
+//	netif_info(tp, intr, dev, "status = %08x\n", status);
 
 	if (status & LinkChange) {
-		net_intr(tp, KERN_INFO "%s: link change.\n", dev->name);
+		netif_info(tp, intr, dev, "link change\n");
+		del_timer(&tp->timer);
 		schedule_work(&tp->phy_task);
 	}
 
@@ -841,19 +843,17 @@ static void sis190_set_rx_mode(struct ne
 			AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
 			AcceptAllPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
-	} else if ((dev->mc_count > multicast_filter_limit) ||
+	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
 		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter perfectly -- accept all multicasts. */
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
 	} else {
 		struct dev_mc_list *mclist;
-		unsigned int i;
 
 		rx_mode = AcceptBroadcast | AcceptMyPhys;
 		mc_filter[1] = mc_filter[0] = 0;
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-		     i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			int bit_nr =
 				ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x3f;
 			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
@@ -929,13 +929,15 @@ static void sis190_phy_task(struct work_
 	if (val & BMCR_RESET) {
 		// FIXME: needlessly high ?  -- FR 02/07/2005
 		mod_timer(&tp->timer, jiffies + HZ/10);
-	} else if (!(mdio_read_latched(ioaddr, phy_id, MII_BMSR) &
-		     BMSR_ANEGCOMPLETE)) {
+		goto out_unlock;
+	}
+
+	val = mdio_read_latched(ioaddr, phy_id, MII_BMSR);
+	if (!(val & BMSR_ANEGCOMPLETE) && tp->link_status != LNK_AUTONEG) {
 		netif_carrier_off(dev);
-		net_link(tp, KERN_WARNING "%s: auto-negotiating...\n",
-			 dev->name);
-		mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);
-	} else {
+		netif_warn(tp, link, dev, "auto-negotiating...\n");
+		tp->link_status = LNK_AUTONEG;
+	} else if ((val & BMSR_LSTATUS) && tp->link_status != LNK_ON) {
 		/* Rejoice ! */
 		struct {
 			int val;
@@ -959,13 +961,13 @@ static void sis190_phy_task(struct work_
 		u16 adv, autoexp, gigadv, gigrec;
 
 		val = mdio_read(ioaddr, phy_id, 0x1f);
-		net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val);
+		netif_info(tp, link, dev, "mii ext = %04x\n", val);
 
 		val = mdio_read(ioaddr, phy_id, MII_LPA);
 		adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE);
 		autoexp = mdio_read(ioaddr, phy_id, MII_EXPANSION);
-		net_link(tp, KERN_INFO "%s: mii lpa=%04x adv=%04x exp=%04x.\n",
-			 dev->name, val, adv, autoexp);
+		netif_info(tp, link, dev, "mii lpa=%04x adv=%04x exp=%04x\n",
+			   val, adv, autoexp);
 
 		if (val & LPA_NPAGE && autoexp & EXPANSION_NWAY) {
 			/* check for gigabit speed */
@@ -1004,10 +1006,14 @@ static void sis190_phy_task(struct work_
 			SIS_W32(RGDelay, 0x0440);
 		}
 
-		net_link(tp, KERN_INFO "%s: link on %s mode.\n", dev->name,
-			 p->msg);
+		tp->negotiated_lpa = p->val;
+
+		netif_info(tp, link, dev, "link on %s mode\n", p->msg);
 		netif_carrier_on(dev);
-	}
+		tp->link_status = LNK_ON;
+	} else if (!(val & BMSR_LSTATUS) && tp->link_status != LNK_AUTONEG)
+		tp->link_status = LNK_OFF;
+	mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);
 
 out_unlock:
 	rtnl_unlock();
@@ -1191,13 +1197,17 @@ static netdev_tx_t sis190_start_xmit(str
 
 	if (unlikely(le32_to_cpu(desc->status) & OWNbit)) {
 		netif_stop_queue(dev);
-		net_tx_err(tp, KERN_ERR PFX
-			   "%s: BUG! Tx Ring full when queue awake!\n",
-			   dev->name);
+		netif_err(tp, tx_err, dev,
+			  "BUG! Tx Ring full when queue awake!\n");
 		return NETDEV_TX_BUSY;
 	}
 
 	mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(tp->pci_dev, mapping)) {
+		netif_err(tp, tx_err, dev,
+				"PCI mapping failed, dropping packet");
+		return NETDEV_TX_BUSY;
+	}
 
 	tp->Tx_skbuff[entry] = skb;
 
@@ -1211,6 +1221,12 @@ static netdev_tx_t sis190_start_xmit(str
 	wmb();
 
 	desc->status = cpu_to_le32(OWNbit | INTbit | DEFbit | CRCbit | PADbit);
+	if (tp->negotiated_lpa & (LPA_1000HALF | LPA_100HALF | LPA_10HALF)) {
+		/* Half Duplex */
+		desc->status |= cpu_to_le32(COLEN | CRSEN | BKFEN);
+		if (tp->negotiated_lpa & (LPA_1000HALF | LPA_1000FULL))
+			desc->status |= cpu_to_le32(EXTEN | BSTEN); /* gigabit HD */
+	}
 
 	tp->cur_tx++;
 
@@ -1287,9 +1303,9 @@ static u16 sis190_default_phy(struct net
 
 	if (mii_if->phy_id != phy_default->phy_id) {
 		mii_if->phy_id = phy_default->phy_id;
-		net_probe(tp, KERN_INFO
-		       "%s: Using transceiver at address %d as default.\n",
-		       pci_name(tp->pci_dev), mii_if->phy_id);
+		if (netif_msg_probe(tp))
+			pr_info("%s: Using transceiver at address %d as default\n",
+				pci_name(tp->pci_dev), mii_if->phy_id);
 	}
 
 	status = mdio_read(ioaddr, mii_if->phy_id, MII_BMCR);
@@ -1327,14 +1343,15 @@ static void sis190_init_phy(struct net_d
 			((mii_status & (BMSR_100FULL | BMSR_100HALF)) ?
 				LAN : HOME) : p->type;
 		tp->features |= p->feature;
-		net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n",
-			pci_name(tp->pci_dev), p->name, phy_id);
+		if (netif_msg_probe(tp))
+			pr_info("%s: %s transceiver at address %d\n",
+				pci_name(tp->pci_dev), p->name, phy_id);
 	} else {
 		phy->type = UNKNOWN;
-		net_probe(tp, KERN_INFO
-			"%s: unknown PHY 0x%x:0x%x transceiver at address %d\n",
-			pci_name(tp->pci_dev),
-			phy->id[0], (phy->id[1] & 0xfff0), phy_id);
+		if (netif_msg_probe(tp))
+			pr_info("%s: unknown PHY 0x%x:0x%x transceiver at address %d\n",
+				pci_name(tp->pci_dev),
+				phy->id[0], (phy->id[1] & 0xfff0), phy_id);
 	}
 }
 
@@ -1398,8 +1415,9 @@ static int __devinit sis190_mii_probe(st
 	}
 
 	if (list_empty(&tp->first_phy)) {
-		net_probe(tp, KERN_INFO "%s: No MII transceivers found!\n",
-			  pci_name(tp->pci_dev));
+		if (netif_msg_probe(tp))
+			pr_info("%s: No MII transceivers found!\n",
+				pci_name(tp->pci_dev));
 		rc = -EIO;
 		goto out;
 	}
@@ -1445,7 +1463,8 @@ static struct net_device * __devinit sis
 
 	dev = alloc_etherdev(sizeof(*tp));
 	if (!dev) {
-		net_drv(&debug, KERN_ERR PFX "unable to alloc new ethernet\n");
+		if (netif_msg_drv(&debug))
+			pr_err("unable to alloc new ethernet\n");
 		rc = -ENOMEM;
 		goto err_out_0;
 	}
@@ -1458,34 +1477,39 @@ static struct net_device * __devinit sis
 
 	rc = pci_enable_device(pdev);
 	if (rc < 0) {
-		net_probe(tp, KERN_ERR "%s: enable failure\n", pci_name(pdev));
+		if (netif_msg_probe(tp))
+			pr_err("%s: enable failure\n", pci_name(pdev));
 		goto err_free_dev_1;
 	}
 
 	rc = -ENODEV;
 
 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
-		net_probe(tp, KERN_ERR "%s: region #0 is no MMIO resource.\n",
-			  pci_name(pdev));
+		if (netif_msg_probe(tp))
+			pr_err("%s: region #0 is no MMIO resource\n",
+			       pci_name(pdev));
 		goto err_pci_disable_2;
 	}
 	if (pci_resource_len(pdev, 0) < SIS190_REGS_SIZE) {
-		net_probe(tp, KERN_ERR "%s: invalid PCI region size(s).\n",
-			  pci_name(pdev));
+		if (netif_msg_probe(tp))
+			pr_err("%s: invalid PCI region size(s)\n",
+			       pci_name(pdev));
 		goto err_pci_disable_2;
 	}
 
 	rc = pci_request_regions(pdev, DRV_NAME);
 	if (rc < 0) {
-		net_probe(tp, KERN_ERR PFX "%s: could not request regions.\n",
-			  pci_name(pdev));
+		if (netif_msg_probe(tp))
+			pr_err("%s: could not request regions\n",
+			       pci_name(pdev));
 		goto err_pci_disable_2;
 	}
 
 	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));
+		if (netif_msg_probe(tp))
+			pr_err("%s: DMA configuration failed\n",
+			       pci_name(pdev));
 		goto err_free_res_3;
 	}
 
@@ -1493,14 +1517,16 @@ static struct net_device * __devinit sis
 
 	ioaddr = ioremap(pci_resource_start(pdev, 0), SIS190_REGS_SIZE);
 	if (!ioaddr) {
-		net_probe(tp, KERN_ERR "%s: cannot remap MMIO, aborting\n",
-			  pci_name(pdev));
+		if (netif_msg_probe(tp))
+			pr_err("%s: cannot remap MMIO, aborting\n",
+			       pci_name(pdev));
 		rc = -EIO;
 		goto err_free_res_3;
 	}
 
 	tp->pci_dev = pdev;
 	tp->mmio_addr = ioaddr;
+	tp->link_status = LNK_OFF;
 
 	sis190_irq_mask_and_ack(ioaddr);
 
@@ -1530,9 +1556,8 @@ static void sis190_tx_timeout(struct net
 	if (tmp8 & CmdTxEnb)
 		SIS_W8(TxControl, tmp8 & ~CmdTxEnb);
 
-
-	net_tx_err(tp, KERN_INFO "%s: Transmit timeout, status %08x %08x.\n",
-		   dev->name, SIS_R32(TxControl), SIS_R32(TxSts));
+	netif_info(tp, tx_err, dev, "Transmit timeout, status %08x %08x\n",
+		   SIS_R32(TxControl), SIS_R32(TxSts));
 
 	/* Disable interrupts by clearing the interrupt mask. */
 	SIS_W32(IntrMask, 0x0000);
@@ -1561,15 +1586,16 @@ static int __devinit sis190_get_mac_addr
 	u16 sig;
 	int i;
 
-	net_probe(tp, KERN_INFO "%s: Read MAC address from EEPROM\n",
-		  pci_name(pdev));
+	if (netif_msg_probe(tp))
+		pr_info("%s: Read MAC address from EEPROM\n", pci_name(pdev));
 
 	/* Check to see if there is a sane EEPROM */
 	sig = (u16) sis190_read_eeprom(ioaddr, EEPROMSignature);
 
 	if ((sig == 0xffff) || (sig == 0x0000)) {
-		net_probe(tp, KERN_INFO "%s: Error EEPROM read %x.\n",
-			  pci_name(pdev), sig);
+		if (netif_msg_probe(tp))
+			pr_info("%s: Error EEPROM read %x\n",
+				pci_name(pdev), sig);
 		return -EIO;
 	}
 
@@ -1603,8 +1629,8 @@ static int __devinit sis190_get_mac_addr
 	u8 reg, tmp8;
 	unsigned int i;
 
-	net_probe(tp, KERN_INFO "%s: Read MAC address from APC.\n",
-		  pci_name(pdev));
+	if (netif_msg_probe(tp))
+		pr_info("%s: Read MAC address from APC\n", pci_name(pdev));
 
 	for (i = 0; i < ARRAY_SIZE(ids); i++) {
 		isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, ids[i], NULL);
@@ -1613,8 +1639,9 @@ static int __devinit sis190_get_mac_addr
 	}
 
 	if (!isa_bridge) {
-		net_probe(tp, KERN_INFO "%s: Can not find ISA bridge.\n",
-			  pci_name(pdev));
+		if (netif_msg_probe(tp))
+			pr_info("%s: Can not find ISA bridge\n",
+				pci_name(pdev));
 		return -EIO;
 	}
 
@@ -1695,7 +1722,7 @@ static void sis190_set_speed_auto(struct
 	int phy_id = tp->mii_if.phy_id;
 	int val;
 
-	net_link(tp, KERN_INFO "%s: Enabling Auto-negotiation.\n", dev->name);
+	netif_info(tp, link, dev, "Enabling Auto-negotiation\n");
 
 	val = mdio_read(ioaddr, phy_id, MII_ADVERTISE);
 
@@ -1822,7 +1849,8 @@ static int __devinit sis190_init_one(str
 	int rc;
 
 	if (!printed_version) {
-		net_drv(&debug, KERN_INFO SIS190_DRIVER_NAME " loaded.\n");
+		if (netif_msg_drv(&debug))
+			pr_info(SIS190_DRIVER_NAME " loaded\n");
 		printed_version = 1;
 	}
 
@@ -1862,12 +1890,14 @@ static int __devinit sis190_init_one(str
 	if (rc < 0)
 		goto err_remove_mii;
 
-	net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), %pM\n",
-		  pci_name(pdev), sis_chip_info[ent->driver_data].name,
-		  ioaddr, dev->irq, dev->dev_addr);
-
-	net_probe(tp, KERN_INFO "%s: %s mode.\n", dev->name,
-		  (tp->features & F_HAS_RGMII) ? "RGMII" : "GMII");
+	if (netif_msg_probe(tp)) {
+		netdev_info(dev, "%s: %s at %p (IRQ: %d), %pM\n",
+			    pci_name(pdev),
+			    sis_chip_info[ent->driver_data].name,
+			    ioaddr, dev->irq, dev->dev_addr);
+		netdev_info(dev, "%s mode.\n",
+			    (tp->features & F_HAS_RGMII) ? "RGMII" : "GMII");
+	}
 
 	netif_carrier_off(dev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sis900.c linux-libre-2.6.34-gnu1/drivers/net/sis900.c
--- linux-libre-2.6.33-gnu1/drivers/net/sis900.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sis900.c	2010-05-16 17:17:36.000000000 -0400
@@ -106,7 +106,7 @@ static const char * card_names[] = {
 	"SiS 900 PCI Fast Ethernet",
 	"SiS 7016 PCI Fast Ethernet"
 };
-static struct pci_device_id sis900_pci_tbl [] = {
+static DEFINE_PCI_DEVICE_TABLE(sis900_pci_tbl) = {
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_900,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_900},
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7016,
@@ -2288,7 +2288,7 @@ static void set_rx_mode(struct net_devic
 		rx_mode = RFPromiscuous;
 		for (i = 0; i < table_entries; i++)
 			mc_filter[i] = 0xffff;
-	} else if ((net_dev->mc_count > multicast_filter_limit) ||
+	} else if ((netdev_mc_count(net_dev) > multicast_filter_limit) ||
 		   (net_dev->flags & IFF_ALLMULTI)) {
 		/* too many multicast addresses or accept all multicast packet */
 		rx_mode = RFAAB | RFAAM;
@@ -2300,9 +2300,8 @@ static void set_rx_mode(struct net_devic
 		 * packets */
 		struct dev_mc_list *mclist;
 		rx_mode = RFAAB;
-		for (i = 0, mclist = net_dev->mc_list;
-			mclist && i < net_dev->mc_count;
-			i++, mclist = mclist->next) {
+
+		netdev_for_each_mc_addr(mclist, net_dev) {
 			unsigned int bit_nr =
 				sis900_mcast_bitnr(mclist->dmi_addr, sis_priv->chipset_rev);
 			mc_filter[bit_nr >> 4] |= (1 << (bit_nr & 0xf));
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/skfp/ess.c linux-libre-2.6.34-gnu1/drivers/net/skfp/ess.c
--- linux-libre-2.6.33-gnu1/drivers/net/skfp/ess.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/skfp/ess.c	2010-05-16 17:17:36.000000000 -0400
@@ -557,7 +557,7 @@ static void ess_send_alc_req(struct s_sm
 
 	/*
 	 * send never allocation request where the requested payload and
-	 * overhead is zero or deallocate bandwidht when no bandwidth is
+	 * overhead is zero or deallocate bandwidth when no bandwidth is
 	 * parsed
 	 */
 	if (!smc->mib.fddiESSPayload) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/skfp/skfddi.c linux-libre-2.6.34-gnu1/drivers/net/skfp/skfddi.c
--- linux-libre-2.6.33-gnu1/drivers/net/skfp/skfddi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/skfp/skfddi.c	2010-05-16 17:17:36.000000000 -0400
@@ -78,13 +78,13 @@ static const char * const boot_msg =
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/fddidevice.h>
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 
 #include <asm/byteorder.h>
 #include <asm/io.h>
@@ -149,7 +149,7 @@ extern void mac_drv_rx_mode(struct s_smc
 extern void mac_drv_clear_rx_queue(struct s_smc *smc);
 extern void enable_tx_irq(struct s_smc *smc, u_short queue);
 
-static struct pci_device_id skfddi_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(skfddi_pci_tbl) = {
 	{ PCI_VENDOR_ID_SK, PCI_DEVICE_ID_SK_FP, PCI_ANY_ID, PCI_ANY_ID, },
 	{ }			/* Terminating entry */
 };
@@ -435,13 +435,7 @@ static  int skfp_driver_init(struct net_
 		goto fail;
 	}
 	read_address(smc, NULL);
-	pr_debug(KERN_INFO "HW-Addr: %02x %02x %02x %02x %02x %02x\n",
-	       smc->hw.fddi_canon_addr.a[0],
-	       smc->hw.fddi_canon_addr.a[1],
-	       smc->hw.fddi_canon_addr.a[2],
-	       smc->hw.fddi_canon_addr.a[3],
-	       smc->hw.fddi_canon_addr.a[4],
-	       smc->hw.fddi_canon_addr.a[5]);
+	pr_debug(KERN_INFO "HW-Addr: %pMF\n", smc->hw.fddi_canon_addr.a);
 	memcpy(dev->dev_addr, smc->hw.fddi_canon_addr.a, 6);
 
 	smt_reset_defaults(smc, 0);
@@ -858,8 +852,7 @@ static void skfp_ctl_set_multicast_list(
 static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
 {
 	struct s_smc *smc = netdev_priv(dev);
-	struct dev_mc_list *dmi;	/* ptr to multicast addr entry */
-	int i;
+	struct dev_mc_list *dmi;
 
 	/* Enable promiscuous mode, if necessary */
 	if (dev->flags & IFF_PROMISC) {
@@ -878,29 +871,19 @@ static void skfp_ctl_set_multicast_list_
 		if (dev->flags & IFF_ALLMULTI) {
 			mac_drv_rx_mode(smc, RX_ENABLE_ALLMULTI);
 			pr_debug(KERN_INFO "ENABLE ALL MC ADDRESSES\n");
-		} else if (dev->mc_count > 0) {
-			if (dev->mc_count <= FPMAX_MULTICAST) {
+		} else if (!netdev_mc_empty(dev)) {
+			if (netdev_mc_count(dev) <= FPMAX_MULTICAST) {
 				/* use exact filtering */
 
 				// point to first multicast addr
-				dmi = dev->mc_list;
-
-				for (i = 0; i < dev->mc_count; i++) {
+				netdev_for_each_mc_addr(dmi, dev) {
 					mac_add_multicast(smc, 
 							  (struct fddi_addr *)dmi->dmi_addr, 
 							  1);
 
-					pr_debug(KERN_INFO "ENABLE MC ADDRESS:");
-					pr_debug(" %02x %02x %02x ",
-					       dmi->dmi_addr[0],
-					       dmi->dmi_addr[1],
-					       dmi->dmi_addr[2]);
-					pr_debug("%02x %02x %02x\n",
-					       dmi->dmi_addr[3],
-					       dmi->dmi_addr[4],
-					       dmi->dmi_addr[5]);
-					dmi = dmi->next;
-				}	// for
+					pr_debug(KERN_INFO "ENABLE MC ADDRESS: %pMF\n",
+						dmi->dmi_addr);
+				}
 
 			} else {	// more MC addresses than HW supports
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/skge.c linux-libre-2.6.34-gnu1/drivers/net/skge.c
--- linux-libre-2.6.33-gnu1/drivers/net/skge.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/skge.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,8 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/in.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -40,13 +42,13 @@
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/mii.h>
+#include <linux/slab.h>
 #include <asm/irq.h>
 
 #include "skge.h"
 
 #define DRV_NAME		"skge"
 #define DRV_VERSION		"1.13"
-#define PFX			DRV_NAME " "
 
 #define DEFAULT_TX_RING_SIZE	128
 #define DEFAULT_RX_RING_SIZE	512
@@ -70,15 +72,15 @@ MODULE_AUTHOR("Stephen Hemminger <shemmi
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
-static const u32 default_msg
-	= NETIF_MSG_DRV| NETIF_MSG_PROBE| NETIF_MSG_LINK
-	  | NETIF_MSG_IFUP| NETIF_MSG_IFDOWN;
+static const u32 default_msg = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
+				NETIF_MSG_LINK | NETIF_MSG_IFUP |
+				NETIF_MSG_IFDOWN);
 
 static int debug = -1;	/* defaults above */
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 
-static const struct pci_device_id skge_id_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(skge_id_table) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) },
@@ -187,8 +189,8 @@ static void skge_wol_init(struct skge_po
 
 	/* Force to 10/100 skge_reset will re-enable on resume	 */
 	gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
-		     PHY_AN_100FULL | PHY_AN_100HALF |
-		     PHY_AN_10FULL | PHY_AN_10HALF| PHY_AN_CSMA);
+		     (PHY_AN_100FULL | PHY_AN_100HALF |
+		      PHY_AN_10FULL | PHY_AN_10HALF | PHY_AN_CSMA));
 	/* no 1000 HD/FD */
 	gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, 0);
 	gm_phy_write(hw, port, PHY_MARV_CTRL,
@@ -257,25 +259,28 @@ static u32 skge_supported_modes(const st
 	u32 supported;
 
 	if (hw->copper) {
-		supported = SUPPORTED_10baseT_Half
-			| SUPPORTED_10baseT_Full
-			| SUPPORTED_100baseT_Half
-			| SUPPORTED_100baseT_Full
-			| SUPPORTED_1000baseT_Half
-			| SUPPORTED_1000baseT_Full
-			| SUPPORTED_Autoneg| SUPPORTED_TP;
+		supported = (SUPPORTED_10baseT_Half |
+			     SUPPORTED_10baseT_Full |
+			     SUPPORTED_100baseT_Half |
+			     SUPPORTED_100baseT_Full |
+			     SUPPORTED_1000baseT_Half |
+			     SUPPORTED_1000baseT_Full |
+			     SUPPORTED_Autoneg |
+			     SUPPORTED_TP);
 
 		if (hw->chip_id == CHIP_ID_GENESIS)
-			supported &= ~(SUPPORTED_10baseT_Half
-					     | SUPPORTED_10baseT_Full
-					     | SUPPORTED_100baseT_Half
-					     | SUPPORTED_100baseT_Full);
+			supported &= ~(SUPPORTED_10baseT_Half |
+				       SUPPORTED_10baseT_Full |
+				       SUPPORTED_100baseT_Half |
+				       SUPPORTED_100baseT_Full);
 
 		else if (hw->chip_id == CHIP_ID_YUKON)
 			supported &= ~SUPPORTED_1000baseT_Half;
 	} else
-		supported = SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half
-			| SUPPORTED_FIBRE | SUPPORTED_Autoneg;
+		supported = (SUPPORTED_1000baseT_Full |
+			     SUPPORTED_1000baseT_Half |
+			     SUPPORTED_FIBRE |
+			     SUPPORTED_Autoneg);
 
 	return supported;
 }
@@ -365,7 +370,7 @@ static int skge_set_settings(struct net_
 		}
 	}
 
-	return (0);
+	return 0;
 }
 
 static void skge_get_drvinfo(struct net_device *dev,
@@ -812,7 +817,7 @@ static int skge_get_eeprom_len(struct ne
 	u32 reg2;
 
 	pci_read_config_dword(skge->hw->pdev, PCI_DEV_REG2, &reg2);
-	return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
+	return 1 << (((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
 }
 
 static u32 skge_vpd_read(struct pci_dev *pdev, int cap, u16 offset)
@@ -1043,7 +1048,7 @@ static int skge_rx_fill(struct net_devic
 
 		skb_reserve(skb, NET_IP_ALIGN);
 		skge_rx_setup(skge, e, skb, skge->rx_buf_size);
-	} while ( (e = e->next) != ring->start);
+	} while ((e = e->next) != ring->start);
 
 	ring->to_clean = ring->start;
 	return 0;
@@ -1051,7 +1056,7 @@ static int skge_rx_fill(struct net_devic
 
 static const char *skge_pause(enum pause_status status)
 {
-	switch(status) {
+	switch (status) {
 	case FLOW_STAT_NONE:
 		return "none";
 	case FLOW_STAT_REM_SEND:
@@ -1074,13 +1079,11 @@ static void skge_link_up(struct skge_por
 	netif_carrier_on(skge->netdev);
 	netif_wake_queue(skge->netdev);
 
-	if (netif_msg_link(skge)) {
-		printk(KERN_INFO PFX
-		       "%s: Link is up at %d Mbps, %s duplex, flow control %s\n",
-		       skge->netdev->name, skge->speed,
-		       skge->duplex == DUPLEX_FULL ? "full" : "half",
-		       skge_pause(skge->flow_status));
-	}
+	netif_info(skge, link, skge->netdev,
+		   "Link is up at %d Mbps, %s duplex, flow control %s\n",
+		   skge->speed,
+		   skge->duplex == DUPLEX_FULL ? "full" : "half",
+		   skge_pause(skge->flow_status));
 }
 
 static void skge_link_down(struct skge_port *skge)
@@ -1089,8 +1092,7 @@ static void skge_link_down(struct skge_p
 	netif_carrier_off(skge->netdev);
 	netif_stop_queue(skge->netdev);
 
-	if (netif_msg_link(skge))
-		printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name);
+	netif_info(skge, link, skge->netdev, "Link is down\n");
 }
 
 
@@ -1132,8 +1134,7 @@ static u16 xm_phy_read(struct skge_hw *h
 {
 	u16 v = 0;
 	if (__xm_phy_read(hw, port, reg, &v))
-		printk(KERN_WARNING PFX "%s: phy read timed out\n",
-		       hw->dev[port]->name);
+		pr_warning("%s: phy read timed out\n", hw->dev[port]->name);
 	return v;
 }
 
@@ -1255,8 +1256,7 @@ static void bcom_check_link(struct skge_
 
 		lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP);
 		if (lpa & PHY_B_AN_RF) {
-			printk(KERN_NOTICE PFX "%s: remote fault\n",
-			       dev->name);
+			netdev_notice(dev, "remote fault\n");
 			return;
 		}
 
@@ -1271,8 +1271,7 @@ static void bcom_check_link(struct skge_
 			skge->duplex = DUPLEX_HALF;
 			break;
 		default:
-			printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
-			       dev->name);
+			netdev_notice(dev, "duplex mismatch\n");
 			return;
 		}
 
@@ -1327,7 +1326,7 @@ static void bcom_phy_init(struct skge_po
 	/* Optimize MDIO transfer by suppressing preamble. */
 	r = xm_read16(hw, port, XM_MMU_CMD);
 	r |=  XM_MMU_NO_PRE;
-	xm_write16(hw, port, XM_MMU_CMD,r);
+	xm_write16(hw, port, XM_MMU_CMD, r);
 
 	switch (id1) {
 	case PHY_BCOM_ID1_C0:
@@ -1464,8 +1463,7 @@ static int xm_check_link(struct net_devi
 
 		lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP);
 		if (lpa & PHY_B_AN_RF) {
-			printk(KERN_NOTICE PFX "%s: remote fault\n",
-			       dev->name);
+			netdev_notice(dev, "remote fault\n");
 			return 0;
 		}
 
@@ -1480,8 +1478,7 @@ static int xm_check_link(struct net_devi
 			skge->duplex = DUPLEX_HALF;
 			break;
 		default:
-			printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
-			       dev->name);
+			netdev_notice(dev, "duplex mismatch\n");
 			return 0;
 		}
 
@@ -1519,7 +1516,7 @@ static void xm_link_timer(unsigned long
 {
 	struct skge_port *skge = (struct skge_port *) arg;
 	struct net_device *dev = skge->netdev;
- 	struct skge_hw *hw = skge->hw;
+	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
 	int i;
 	unsigned long flags;
@@ -1538,7 +1535,7 @@ static void xm_link_timer(unsigned long
 			goto link_down;
 	}
 
-        /* Re-enable interrupt to detect link down */
+	/* Re-enable interrupt to detect link down */
 	if (xm_check_link(dev)) {
 		u16 msk = xm_read16(hw, port, XM_IMSK);
 		msk &= ~XM_IS_INP_ASS;
@@ -1569,7 +1566,7 @@ static void genesis_mac_init(struct skge
 		udelay(1);
 	}
 
-	printk(KERN_WARNING PFX "%s: genesis reset failed\n", dev->name);
+	netdev_warn(dev, "genesis reset failed\n");
 
  reset_ok:
 	/* Unreset the XMAC. */
@@ -1595,7 +1592,7 @@ static void genesis_mac_init(struct skge
 	}
 
 
-	switch(hw->phy_type) {
+	switch (hw->phy_type) {
 	case SK_PHY_XMAC:
 		xm_phy_init(skge);
 		break;
@@ -1702,7 +1699,7 @@ static void genesis_mac_init(struct skge
 
 	if (jumbo) {
 		/* Enable frame flushing if jumbo frames used */
-		skge_write16(hw, SK_REG(port,RX_MFF_CTRL1), MFF_ENA_FLUSH);
+		skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_FLUSH);
 	} else {
 		/* enable timeout timers if normal frames */
 		skge_write16(hw, B3_PA_CTRL,
@@ -1717,7 +1714,7 @@ static void genesis_stop(struct skge_por
 	unsigned retries = 1000;
 	u16 cmd;
 
- 	/* Disable Tx and Rx */
+	/* Disable Tx and Rx */
 	cmd = xm_read16(hw, port, XM_MMU_CMD);
 	cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
 	xm_write16(hw, port, XM_MMU_CMD, cmd);
@@ -1792,12 +1789,11 @@ static void genesis_mac_intr(struct skge
 	struct skge_port *skge = netdev_priv(dev);
 	u16 status = xm_read16(hw, port, XM_ISRC);
 
-	if (netif_msg_intr(skge))
-		printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n",
-		       dev->name, status);
+	netif_printk(skge, intr, KERN_DEBUG, skge->netdev,
+		     "mac interrupt status 0x%x\n", status);
 
 	if (hw->phy_type == SK_PHY_XMAC && (status & XM_IS_INP_ASS)) {
-  		xm_link_down(hw, port);
+		xm_link_down(hw, port);
 		mod_timer(&skge->link_timer, jiffies + 1);
 	}
 
@@ -1831,7 +1827,7 @@ static void genesis_link_up(struct skge_
 	xm_write16(hw, port, XM_MMU_CMD, cmd);
 
 	mode = xm_read32(hw, port, XM_MODE);
-	if (skge->flow_status== FLOW_STAT_SYMMETRIC ||
+	if (skge->flow_status == FLOW_STAT_SYMMETRIC ||
 	    skge->flow_status == FLOW_STAT_LOC_SEND) {
 		/*
 		 * Configure Pause Frame Generation
@@ -1898,12 +1894,11 @@ static inline void bcom_phy_intr(struct
 	u16 isrc;
 
 	isrc = xm_phy_read(hw, port, PHY_BCOM_INT_STAT);
-	if (netif_msg_intr(skge))
-		printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x\n",
-		       skge->netdev->name, isrc);
+	netif_printk(skge, intr, KERN_DEBUG, skge->netdev,
+		     "phy interrupt status 0x%x\n", isrc);
 
 	if (isrc & PHY_B_IS_PSE)
-		printk(KERN_ERR PFX "%s: uncorrectable pair swap error\n",
+		pr_err("%s: uncorrectable pair swap error\n",
 		       hw->dev[port]->name);
 
 	/* Workaround BCom Errata:
@@ -1936,8 +1931,7 @@ static int gm_phy_write(struct skge_hw *
 			return 0;
 	}
 
-	printk(KERN_WARNING PFX "%s: phy write timeout\n",
-	       hw->dev[port]->name);
+	pr_warning("%s: phy write timeout\n", hw->dev[port]->name);
 	return -EIO;
 }
 
@@ -1965,8 +1959,7 @@ static u16 gm_phy_read(struct skge_hw *h
 {
 	u16 v = 0;
 	if (__gm_phy_read(hw, port, reg, &v))
-		printk(KERN_WARNING PFX "%s: phy read timeout\n",
-	       hw->dev[port]->name);
+		pr_warning("%s: phy read timeout\n", hw->dev[port]->name);
 	return v;
 }
 
@@ -2298,9 +2291,8 @@ static void yukon_mac_intr(struct skge_h
 	struct skge_port *skge = netdev_priv(dev);
 	u8 status = skge_read8(hw, SK_REG(port, GMAC_IRQ_SRC));
 
-	if (netif_msg_intr(skge))
-		printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n",
-		       dev->name, status);
+	netif_printk(skge, intr, KERN_DEBUG, skge->netdev,
+		     "mac interrupt status 0x%x\n", status);
 
 	if (status & GM_IS_RX_FF_OR) {
 		++dev->stats.rx_fifo_errors;
@@ -2379,9 +2371,8 @@ static void yukon_phy_intr(struct skge_p
 	istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
 	phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
 
-	if (netif_msg_intr(skge))
-		printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x 0x%x\n",
-		       skge->netdev->name, istatus, phystat);
+	netif_printk(skge, intr, KERN_DEBUG, skge->netdev,
+		     "phy interrupt status 0x%x 0x%x\n", istatus, phystat);
 
 	if (istatus & PHY_M_IS_AN_COMPL) {
 		if (gm_phy_read(hw, port, PHY_MARV_AUNE_LP)
@@ -2441,8 +2432,7 @@ static void yukon_phy_intr(struct skge_p
 	}
 	return;
  failed:
-	printk(KERN_ERR PFX "%s: autonegotiation failed (%s)\n",
-	       skge->netdev->name, reason);
+	pr_err("%s: autonegotiation failed (%s)\n", skge->netdev->name, reason);
 
 	/* XXX restart autonegotiation? */
 }
@@ -2480,7 +2470,7 @@ static int skge_ioctl(struct net_device
 	if (!netif_running(dev))
 		return -ENODEV;	/* Phy still in reset */
 
-	switch(cmd) {
+	switch (cmd) {
 	case SIOCGMIIPHY:
 		data->phy_id = hw->phy_addr;
 
@@ -2571,8 +2561,7 @@ static int skge_up(struct net_device *de
 	if (!is_valid_ether_addr(dev->dev_addr))
 		return -EINVAL;
 
-	if (netif_msg_ifup(skge))
-		printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
+	netif_info(skge, ifup, skge->netdev, "enabling interface\n");
 
 	if (dev->mtu > RX_BUF_SIZE)
 		skge->rx_buf_size = dev->mtu + ETH_HLEN;
@@ -2670,8 +2659,7 @@ static int skge_down(struct net_device *
 	if (skge->mem == NULL)
 		return 0;
 
-	if (netif_msg_ifdown(skge))
-		printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
+	netif_info(skge, ifdown, skge->netdev, "disabling interface\n");
 
 	netif_tx_disable(dev);
 
@@ -2781,7 +2769,7 @@ static netdev_tx_t skge_xmit_frame(struc
 		 * does.  Looks like hardware is wrong?
 		 */
 		if (ipip_hdr(skb)->protocol == IPPROTO_UDP &&
-	            hw->chip_rev == 0 && hw->chip_id == CHIP_ID_YUKON)
+		    hw->chip_rev == 0 && hw->chip_id == CHIP_ID_YUKON)
 			control = BMU_TCP_CHECK;
 		else
 			control = BMU_UDP_CHECK;
@@ -2793,7 +2781,7 @@ static netdev_tx_t skge_xmit_frame(struc
 		control = BMU_CHECK;
 
 	if (!skb_shinfo(skb)->nr_frags) /* single buffer i.e. no fragments */
-		control |= BMU_EOF| BMU_IRQ_EOF;
+		control |= BMU_EOF | BMU_IRQ_EOF;
 	else {
 		struct skge_tx_desc *tf = td;
 
@@ -2825,15 +2813,15 @@ static netdev_tx_t skge_xmit_frame(struc
 
 	skge_write8(hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_START);
 
-	if (unlikely(netif_msg_tx_queued(skge)))
-		printk(KERN_DEBUG "%s: tx queued, slot %td, len %d\n",
-		       dev->name, e - skge->tx_ring.start, skb->len);
+	netif_printk(skge, tx_queued, KERN_DEBUG, skge->netdev,
+		     "tx queued, slot %td, len %d\n",
+		     e - skge->tx_ring.start, skb->len);
 
 	skge->tx_ring.to_use = e->next;
 	smp_wmb();
 
 	if (skge_avail(&skge->tx_ring) <= TX_LOW_WATER) {
-		pr_debug("%s: transmit queue full\n", dev->name);
+		netdev_dbg(dev, "transmit queue full\n");
 		netif_stop_queue(dev);
 	}
 
@@ -2858,9 +2846,8 @@ static void skge_tx_free(struct skge_por
 			       PCI_DMA_TODEVICE);
 
 	if (control & BMU_EOF) {
-		if (unlikely(netif_msg_tx_done(skge)))
-			printk(KERN_DEBUG PFX "%s: tx done slot %td\n",
-			       skge->netdev->name, e - skge->tx_ring.start);
+		netif_printk(skge, tx_done, KERN_DEBUG, skge->netdev,
+			     "tx done slot %td\n", e - skge->tx_ring.start);
 
 		dev_kfree_skb(e->skb);
 	}
@@ -2885,8 +2872,7 @@ static void skge_tx_timeout(struct net_d
 {
 	struct skge_port *skge = netdev_priv(dev);
 
-	if (netif_msg_timer(skge))
-		printk(KERN_DEBUG PFX "%s: tx timeout\n", dev->name);
+	netif_printk(skge, timer, KERN_DEBUG, skge->netdev, "tx timeout\n");
 
 	skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_STOP);
 	skge_tx_clean(dev);
@@ -2932,8 +2918,7 @@ static void genesis_set_multicast(struct
 	struct skge_port *skge = netdev_priv(dev);
 	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
-	int i, count = dev->mc_count;
-	struct dev_mc_list *list = dev->mc_list;
+	struct dev_mc_list *list;
 	u32 mode;
 	u8 filter[8];
 
@@ -2953,7 +2938,7 @@ static void genesis_set_multicast(struct
 		    skge->flow_status == FLOW_STAT_SYMMETRIC)
 			genesis_add_filter(filter, pause_mc_addr);
 
-		for (i = 0; list && i < count; i++, list = list->next)
+		netdev_for_each_mc_addr(list, dev)
 			genesis_add_filter(filter, list->dmi_addr);
 	}
 
@@ -2972,7 +2957,7 @@ static void yukon_set_multicast(struct n
 	struct skge_port *skge = netdev_priv(dev);
 	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
-	struct dev_mc_list *list = dev->mc_list;
+	struct dev_mc_list *list;
 	int rx_pause = (skge->flow_status == FLOW_STAT_REM_SEND ||
 			skge->flow_status == FLOW_STAT_SYMMETRIC);
 	u16 reg;
@@ -2987,16 +2972,15 @@ static void yukon_set_multicast(struct n
 		reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
 	else if (dev->flags & IFF_ALLMULTI)	/* all multicast */
 		memset(filter, 0xff, sizeof(filter));
-	else if (dev->mc_count == 0 && !rx_pause)/* no multicast */
+	else if (netdev_mc_empty(dev) && !rx_pause)/* no multicast */
 		reg &= ~GM_RXCR_MCF_ENA;
 	else {
-		int i;
 		reg |= GM_RXCR_MCF_ENA;
 
 		if (rx_pause)
 			yukon_add_filter(filter, pause_mc_addr);
 
-		for (i = 0; list && i < dev->mc_count; i++, list = list->next)
+		netdev_for_each_mc_addr(list, dev)
 			yukon_add_filter(filter, list->dmi_addr);
 	}
 
@@ -3054,10 +3038,9 @@ static struct sk_buff *skge_rx_get(struc
 	struct sk_buff *skb;
 	u16 len = control & BMU_BBC;
 
-	if (unlikely(netif_msg_rx_status(skge)))
-		printk(KERN_DEBUG PFX "%s: rx slot %td status 0x%x len %d\n",
-		       dev->name, e - skge->rx_ring.start,
-		       status, len);
+	netif_printk(skge, rx_status, KERN_DEBUG, skge->netdev,
+		     "rx slot %td status 0x%x len %d\n",
+		     e - skge->rx_ring.start, status, len);
 
 	if (len > skge->rx_buf_size)
 		goto error;
@@ -3096,7 +3079,7 @@ static struct sk_buff *skge_rx_get(struc
 				 pci_unmap_len(e, maplen),
 				 PCI_DMA_FROMDEVICE);
 		skb = e->skb;
-  		prefetch(skb->data);
+		prefetch(skb->data);
 		skge_rx_setup(skge, e, nskb, skge->rx_buf_size);
 	}
 
@@ -3111,10 +3094,9 @@ static struct sk_buff *skge_rx_get(struc
 	return skb;
 error:
 
-	if (netif_msg_rx_err(skge))
-		printk(KERN_DEBUG PFX "%s: rx err, slot %td control 0x%x status 0x%x\n",
-		       dev->name, e - skge->rx_ring.start,
-		       control, status);
+	netif_printk(skge, rx_err, KERN_DEBUG, skge->netdev,
+		     "rx err, slot %td control 0x%x status 0x%x\n",
+		     e - skge->rx_ring.start, control, status);
 
 	if (skge->hw->chip_id == CHIP_ID_GENESIS) {
 		if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR))
@@ -3574,8 +3556,7 @@ static int skge_reset(struct skge_hw *hw
 			hw->ram_offset = 0x80000;
 		} else
 			hw->ram_size = t8 * 512;
-	}
-	else if (t8 == 0)
+	} else if (t8 == 0)
 		hw->ram_size = 0x20000;
 	else
 		hw->ram_size = t8 * 4096;
@@ -3729,7 +3710,7 @@ static int skge_device_event(struct noti
 		goto done;
 
 	skge = netdev_priv(dev);
-	switch(event) {
+	switch (event) {
 	case NETDEV_CHANGENAME:
 		if (skge->debugfs) {
 			d = debugfs_rename(skge_debug, skge->debugfs,
@@ -3737,7 +3718,7 @@ static int skge_device_event(struct noti
 			if (d)
 				skge->debugfs = d;
 			else {
-				pr_info(PFX "%s: rename failed\n", dev->name);
+				netdev_info(dev, "rename failed\n");
 				debugfs_remove(skge->debugfs);
 			}
 		}
@@ -3755,8 +3736,7 @@ static int skge_device_event(struct noti
 					skge_debug, dev,
 					&skge_debug_fops);
 		if (!d || IS_ERR(d))
-			pr_info(PFX "%s: debugfs create failed\n",
-			       dev->name);
+			netdev_info(dev, "debugfs create failed\n");
 		else
 			skge->debugfs = d;
 		break;
@@ -3777,7 +3757,7 @@ static __init void skge_debug_init(void)
 
 	ent = debugfs_create_dir("skge", NULL);
 	if (!ent || IS_ERR(ent)) {
-		pr_info(PFX "debugfs create directory failed\n");
+		pr_info("debugfs create directory failed\n");
 		return;
 	}
 
@@ -3885,9 +3865,7 @@ static void __devinit skge_show_addr(str
 {
 	const struct skge_port *skge = netdev_priv(dev);
 
-	if (netif_msg_probe(skge))
-		printk(KERN_INFO PFX "%s: addr %pM\n",
-		       dev->name, dev->dev_addr);
+	netif_info(skge, probe, skge->netdev, "addr %pM\n", dev->dev_addr);
 }
 
 static int __devinit skge_probe(struct pci_dev *pdev,
@@ -3937,7 +3915,7 @@ static int __devinit skge_probe(struct p
 
 	err = -ENOMEM;
 	/* space for skge@pci:0000:04:00.0 */
-	hw = kzalloc(sizeof(*hw) + strlen(DRV_NAME "@pci:" )
+	hw = kzalloc(sizeof(*hw) + strlen(DRV_NAME "@pci:")
 		     + strlen(pci_name(pdev)) + 1, GFP_KERNEL);
 	if (!hw) {
 		dev_err(&pdev->dev, "cannot allocate hardware struct\n");
@@ -3960,9 +3938,10 @@ static int __devinit skge_probe(struct p
 	if (err)
 		goto err_out_iounmap;
 
-	printk(KERN_INFO PFX DRV_VERSION " addr 0x%llx irq %d chip %s rev %d\n",
-	       (unsigned long long)pci_resource_start(pdev, 0), pdev->irq,
-	       skge_board_name(hw), hw->chip_rev);
+	pr_info("%s addr 0x%llx irq %d chip %s rev %d\n",
+		DRV_VERSION,
+		(unsigned long long)pci_resource_start(pdev, 0), pdev->irq,
+		skge_board_name(hw), hw->chip_rev);
 
 	dev = skge_devinit(hw, 0, using_dac);
 	if (!dev)
@@ -4032,7 +4011,8 @@ static void __devexit skge_remove(struct
 
 	flush_scheduled_work();
 
-	if ((dev1 = hw->dev[1]))
+	dev1 = hw->dev[1];
+	if (dev1)
 		unregister_netdev(dev1);
 	dev0 = hw->dev[0];
 	unregister_netdev(dev0);
@@ -4119,8 +4099,7 @@ static int skge_resume(struct pci_dev *p
 			err = skge_up(dev);
 
 			if (err) {
-				printk(KERN_ERR PFX "%s: could not up: %d\n",
-				       dev->name, err);
+				netdev_err(dev, "could not up: %d\n", err);
 				dev_close(dev);
 				goto out;
 			}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sky2.c linux-libre-2.6.34-gnu1/drivers/net/sky2.c
--- linux-libre-2.6.33-gnu1/drivers/net/sky2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sky2.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,8 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/crc32.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -31,6 +33,7 @@
 #include <linux/ethtool.h>
 #include <linux/pci.h>
 #include <linux/ip.h>
+#include <linux/slab.h>
 #include <net/ip.h>
 #include <linux/tcp.h>
 #include <linux/in.h>
@@ -50,8 +53,7 @@
 #include "sky2.h"
 
 #define DRV_NAME		"sky2"
-#define DRV_VERSION		"1.26"
-#define PFX			DRV_NAME " "
+#define DRV_VERSION		"1.27"
 
 /*
  * The Yukon II chipset takes 64 bit command blocks (called list elements)
@@ -251,6 +253,8 @@ static void sky2_power_on(struct sky2_hw
 
 		sky2_pci_write32(hw, PCI_CFG_REG_1, 0);
 
+		sky2_write16(hw, B0_CTST, Y2_HW_WOL_ON);
+
 		/* Enable workaround for dev 4.107 on Yukon-Ultra & Extreme */
 		reg = sky2_read32(hw, B2_GP_IO);
 		reg |= GLB_GPIO_STAT_RACE_DIS;
@@ -731,7 +735,6 @@ static void sky2_wol_init(struct sky2_po
 	unsigned port = sky2->port;
 	enum flow_control save_mode;
 	u16 ctrl;
-	u32 reg1;
 
 	/* Bring hardware out of reset */
 	sky2_write16(hw, B0_CTST, CS_RST_CLR);
@@ -782,14 +785,11 @@ static void sky2_wol_init(struct sky2_po
 	ctrl |= WOL_CTL_DIS_PME_ON_PATTERN|WOL_CTL_DIS_PATTERN_UNIT;
 	sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), ctrl);
 
-	/* Turn on legacy PCI-Express PME mode */
-	reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
-	reg1 |= PCI_Y2_PME_LEGACY;
-	sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
+	/* Disable PiG firmware */
+	sky2_write16(hw, B0_CTST, Y2_HW_WOL_OFF);
 
 	/* block receiver */
 	sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
-
 }
 
 static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port)
@@ -800,29 +800,15 @@ static void sky2_set_tx_stfwd(struct sky
 	      hw->chip_rev != CHIP_REV_YU_EX_A0) ||
 	     hw->chip_id >= CHIP_ID_YUKON_FE_P) {
 		/* Yukon-Extreme B0 and further Extreme devices */
-		/* enable Store & Forward mode for TX */
-
-		if (dev->mtu <= ETH_DATA_LEN)
-			sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
-				     TX_JUMBO_DIS | TX_STFW_ENA);
-
-		else
-			sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
-				     TX_JUMBO_ENA| TX_STFW_ENA);
-	} else {
-		if (dev->mtu <= ETH_DATA_LEN)
-			sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_ENA);
-		else {
-			/* set Tx GMAC FIFO Almost Empty Threshold */
-			sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
-				     (ECU_JUMBO_WM << 16) | ECU_AE_THR);
-
-			sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_DIS);
+		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_ENA);
+	} else if (dev->mtu > ETH_DATA_LEN) {
+		/* set Tx GMAC FIFO Almost Empty Threshold */
+		sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
+			     (ECU_JUMBO_WM << 16) | ECU_AE_THR);
 
-			/* Can't do offload because of lack of store/forward */
-			dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | NETIF_F_ALL_CSUM);
-		}
-	}
+		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_DIS);
+	} else
+		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_ENA);
 }
 
 static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
@@ -1065,6 +1051,40 @@ static inline struct sky2_rx_le *sky2_ne
 	return le;
 }
 
+static unsigned sky2_get_rx_threshold(struct sky2_port* sky2)
+{
+	unsigned size;
+
+	/* Space needed for frame data + headers rounded up */
+	size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8);
+
+	/* Stopping point for hardware truncation */
+	return (size - 8) / sizeof(u32);
+}
+
+static unsigned sky2_get_rx_data_size(struct sky2_port* sky2)
+{
+	struct rx_ring_info *re;
+	unsigned size;
+
+	/* Space needed for frame data + headers rounded up */
+	size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8);
+
+	sky2->rx_nfrags = size >> PAGE_SHIFT;
+	BUG_ON(sky2->rx_nfrags > ARRAY_SIZE(re->frag_addr));
+
+	/* Compute residue after pages */
+	size -= sky2->rx_nfrags << PAGE_SHIFT;
+
+	/* Optimize to handle small packets and headers */
+	if (size < copybreak)
+		size = copybreak;
+	if (size < ETH_HLEN)
+		size = ETH_HLEN;
+
+	return size;
+}
+
 /* Build description to hardware for one receive segment */
 static void sky2_rx_add(struct sky2_port *sky2,  u8 op,
 			dma_addr_t map, unsigned len)
@@ -1103,18 +1123,39 @@ static int sky2_rx_map_skb(struct pci_de
 	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;
+	if (pci_dma_mapping_error(pdev, re->data_addr))
+		goto mapping_error;
 
 	pci_unmap_len_set(re, data_size, size);
 
-	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-		re->frag_addr[i] = pci_map_page(pdev,
-						skb_shinfo(skb)->frags[i].page,
-						skb_shinfo(skb)->frags[i].page_offset,
-						skb_shinfo(skb)->frags[i].size,
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+		re->frag_addr[i] = pci_map_page(pdev, frag->page,
+						frag->page_offset,
+						frag->size,
 						PCI_DMA_FROMDEVICE);
+
+		if (pci_dma_mapping_error(pdev, re->frag_addr[i]))
+			goto map_page_error;
+	}
 	return 0;
+
+map_page_error:
+	while (--i >= 0) {
+		pci_unmap_page(pdev, re->frag_addr[i],
+			       skb_shinfo(skb)->frags[i].size,
+			       PCI_DMA_FROMDEVICE);
+	}
+
+	pci_unmap_single(pdev, re->data_addr, pci_unmap_len(re, data_size),
+			 PCI_DMA_FROMDEVICE);
+
+mapping_error:
+	if (net_ratelimit())
+		dev_warn(&pdev->dev, "%s: rx mapping error\n",
+			 skb->dev->name);
+	return -EIO;
 }
 
 static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re)
@@ -1173,8 +1214,7 @@ static void sky2_rx_stop(struct sky2_por
 		    == sky2_read8(hw, RB_ADDR(rxq, Q_RL)))
 			goto stopped;
 
-	printk(KERN_WARNING PFX "%s: receiver stop failed\n",
-	       sky2->netdev->name);
+	netdev_warn(sky2->netdev, "receiver stop failed\n");
 stopped:
 	sky2_write32(hw, Q_ADDR(rxq, Q_CSR), BMU_RST_SET | BMU_FIFO_RST);
 
@@ -1324,8 +1364,32 @@ static inline void sky2_rx_update(struct
 	sky2_put_idx(sky2->hw, rxq, sky2->rx_put);
 }
 
+static int sky2_alloc_rx_skbs(struct sky2_port *sky2)
+{
+	struct sky2_hw *hw = sky2->hw;
+	unsigned i;
+
+	sky2->rx_data_size = sky2_get_rx_data_size(sky2);
+
+	/* Fill Rx ring */
+	for (i = 0; i < sky2->rx_pending; i++) {
+		struct rx_ring_info *re = sky2->rx_ring + i;
+
+		re->skb = sky2_rx_alloc(sky2);
+		if (!re->skb)
+			return -ENOMEM;
+
+		if (sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size)) {
+			dev_kfree_skb(re->skb);
+			re->skb = NULL;
+			return -ENOMEM;
+		}
+	}
+	return 0;
+}
+
 /*
- * Allocate and setup receiver buffer pool.
+ * Setup receiver buffer pool.
  * Normal case this ends up creating one list element for skb
  * in the receive ring. Worst case if using large MTU and each
  * allocation falls on a different 64 bit region, that results
@@ -1333,12 +1397,12 @@ static inline void sky2_rx_update(struct
  * One element is used for checksum enable/disable, and one
  * extra to avoid wrap.
  */
-static int sky2_rx_start(struct sky2_port *sky2)
+static void sky2_rx_start(struct sky2_port *sky2)
 {
 	struct sky2_hw *hw = sky2->hw;
 	struct rx_ring_info *re;
 	unsigned rxq = rxqaddr[sky2->port];
-	unsigned i, size, thresh;
+	unsigned i, thresh;
 
 	sky2->rx_put = sky2->rx_next = 0;
 	sky2_qset(hw, rxq);
@@ -1359,40 +1423,9 @@ static int sky2_rx_start(struct sky2_por
 	if (!(hw->flags & SKY2_HW_NEW_LE))
 		rx_set_checksum(sky2);
 
-	/* Space needed for frame data + headers rounded up */
-	size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8);
-
-	/* Stopping point for hardware truncation */
-	thresh = (size - 8) / sizeof(u32);
-
-	sky2->rx_nfrags = size >> PAGE_SHIFT;
-	BUG_ON(sky2->rx_nfrags > ARRAY_SIZE(re->frag_addr));
-
-	/* Compute residue after pages */
-	size -= sky2->rx_nfrags << PAGE_SHIFT;
-
-	/* Optimize to handle small packets and headers */
-	if (size < copybreak)
-		size = copybreak;
-	if (size < ETH_HLEN)
-		size = ETH_HLEN;
-
-	sky2->rx_data_size = size;
-
-	/* Fill Rx ring */
+	/* submit Rx ring */
 	for (i = 0; i < sky2->rx_pending; i++) {
 		re = sky2->rx_ring + i;
-
-		re->skb = sky2_rx_alloc(sky2);
-		if (!re->skb)
-			goto nomem;
-
-		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);
 	}
 
@@ -1402,6 +1435,7 @@ static int sky2_rx_start(struct sky2_por
 	 * the register is limited to 9 bits, so if you do frames > 2052
 	 * you better get the MTU right!
 	 */
+	thresh = sky2_get_rx_threshold(sky2);
 	if (thresh > 0x1ff)
 		sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF);
 	else {
@@ -1433,13 +1467,6 @@ static int sky2_rx_start(struct sky2_por
 		sky2_write32(hw, Q_ADDR(txqaddr[sky2->port], Q_TEST),
 			     TBMU_TEST_HOME_ADD_FIX_EN | TBMU_TEST_ROUTING_ADD_FIX_EN);
 	}
-
-
-
-	return 0;
-nomem:
-	sky2_rx_clean(sky2);
-	return -ENOMEM;
 }
 
 static int sky2_alloc_buffers(struct sky2_port *sky2)
@@ -1470,7 +1497,7 @@ static int sky2_alloc_buffers(struct sky
 	if (!sky2->rx_ring)
 		goto nomem;
 
-	return 0;
+	return sky2_alloc_rx_skbs(sky2);
 nomem:
 	return -ENOMEM;
 }
@@ -1479,6 +1506,8 @@ static void sky2_free_buffers(struct sky
 {
 	struct sky2_hw *hw = sky2->hw;
 
+	sky2_rx_clean(sky2);
+
 	if (sky2->rx_le) {
 		pci_free_consistent(hw->pdev, RX_LE_BYTES,
 				    sky2->rx_le, sky2->rx_le_map);
@@ -1497,16 +1526,16 @@ static void sky2_free_buffers(struct sky
 	sky2->rx_ring = NULL;
 }
 
-/* Bring up network interface. */
-static int sky2_up(struct net_device *dev)
+static void sky2_hw_up(struct sky2_port *sky2)
 {
-	struct sky2_port *sky2 = netdev_priv(dev);
 	struct sky2_hw *hw = sky2->hw;
 	unsigned port = sky2->port;
-	u32 imask, ramsize;
-	int cap, err;
+	u32 ramsize;
+	int cap;
 	struct net_device *otherdev = hw->dev[sky2->port^1];
 
+	tx_init(sky2);
+
 	/*
  	 * On dual port PCI-X card, there is an problem where status
 	 * can be received out of order due to split transactions
@@ -1518,16 +1547,7 @@ static int sky2_up(struct net_device *de
 		cmd = sky2_pci_read16(hw, cap + PCI_X_CMD);
  		cmd &= ~PCI_X_CMD_MAX_SPLIT;
  		sky2_pci_write16(hw, cap + PCI_X_CMD, cmd);
-
- 	}
-
-	netif_carrier_off(dev);
-
-	err = sky2_alloc_buffers(sky2);
-	if (err)
-		goto err_out;
-
-	tx_init(sky2);
+	}
 
 	sky2_mac_init(hw, port);
 
@@ -1536,7 +1556,7 @@ static int sky2_up(struct net_device *de
 	if (ramsize > 0) {
 		u32 rxspace;
 
-		pr_debug(PFX "%s: ram buffer %dK\n", dev->name, ramsize);
+		netdev_dbg(sky2->netdev, "ram buffer %dK\n", ramsize);
 		if (ramsize < 16)
 			rxspace = ramsize / 2;
 		else
@@ -1568,18 +1588,33 @@ static int sky2_up(struct net_device *de
 	sky2_set_vlan_mode(hw, port, sky2->vlgrp != NULL);
 #endif
 
-	err = sky2_rx_start(sky2);
+	sky2_rx_start(sky2);
+}
+
+/* Bring up network interface. */
+static int sky2_up(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	u32 imask;
+	int err;
+
+	netif_carrier_off(dev);
+
+	err = sky2_alloc_buffers(sky2);
 	if (err)
 		goto err_out;
 
+	sky2_hw_up(sky2);
+
 	/* Enable interrupts from phy/mac for port */
 	imask = sky2_read32(hw, B0_IMSK);
 	imask |= portirq_msk[port];
 	sky2_write32(hw, B0_IMSK, imask);
 	sky2_read32(hw, B0_IMSK);
 
-	if (netif_msg_ifup(sky2))
-		printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
+	netif_info(sky2, ifup, dev, "enabling interface\n");
 
 	return 0;
 
@@ -1662,9 +1697,8 @@ static netdev_tx_t sky2_xmit_frame(struc
 		goto mapping_error;
 
 	slot = sky2->tx_prod;
-	if (unlikely(netif_msg_tx_queued(sky2)))
-		printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
-		       dev->name, slot, skb->len);
+	netif_printk(sky2, tx_queued, KERN_DEBUG, dev,
+		     "tx queued, slot %u, len %d\n", slot, skb->len);
 
 	/* Send high bits if needed */
 	upper = upper_32_bits(mapping);
@@ -1829,9 +1863,8 @@ static void sky2_tx_complete(struct sky2
 		sky2_tx_unmap(sky2->hw->pdev, re);
 
 		if (skb) {
-			if (unlikely(netif_msg_tx_done(sky2)))
-				printk(KERN_DEBUG "%s: tx done %u\n",
-				       dev->name, idx);
+			netif_printk(sky2, tx_done, KERN_DEBUG, dev,
+				     "tx done %u\n", idx);
 
 			dev->stats.tx_packets++;
 			dev->stats.tx_bytes += skb->len;
@@ -1845,10 +1878,6 @@ static void sky2_tx_complete(struct sky2
 
 	sky2->tx_cons = idx;
 	smp_mb();
-
-	/* Wake unless it's detached, and called e.g. from sky2_down() */
-	if (tx_avail(sky2) > MAX_SKB_TX_LE + 4 && netif_device_present(dev))
-		netif_wake_queue(dev);
 }
 
 static void sky2_tx_reset(struct sky2_hw *hw, unsigned port)
@@ -1873,21 +1902,11 @@ static void sky2_tx_reset(struct sky2_hw
 	sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
 }
 
-/* Network shutdown */
-static int sky2_down(struct net_device *dev)
+static void sky2_hw_down(struct sky2_port *sky2)
 {
-	struct sky2_port *sky2 = netdev_priv(dev);
 	struct sky2_hw *hw = sky2->hw;
 	unsigned port = sky2->port;
 	u16 ctrl;
-	u32 imask;
-
-	/* Never really got started! */
-	if (!sky2->tx_le)
-		return 0;
-
-	if (netif_msg_ifdown(sky2))
-		printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
 
 	/* Force flow control off */
 	sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
@@ -1920,15 +1939,6 @@ static int sky2_down(struct net_device *
 
 	sky2_rx_stop(sky2);
 
-	/* Disable port IRQ */
-	imask = sky2_read32(hw, B0_IMSK);
-	imask &= ~portirq_msk[port];
-	sky2_write32(hw, B0_IMSK, imask);
-	sky2_read32(hw, B0_IMSK);
-
-	synchronize_irq(hw->pdev->irq);
-	napi_synchronize(&hw->napi);
-
 	spin_lock_bh(&sky2->phy_lock);
 	sky2_phy_power_down(hw, port);
 	spin_unlock_bh(&sky2->phy_lock);
@@ -1937,8 +1947,29 @@ static int sky2_down(struct net_device *
 
 	/* Free any pending frames stuck in HW queue */
 	sky2_tx_complete(sky2, sky2->tx_prod);
+}
 
-	sky2_rx_clean(sky2);
+/* Network shutdown */
+static int sky2_down(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+
+	/* Never really got started! */
+	if (!sky2->tx_le)
+		return 0;
+
+	netif_info(sky2, ifdown, dev, "disabling interface\n");
+
+	/* Disable port IRQ */
+	sky2_write32(hw, B0_IMSK,
+		     sky2_read32(hw, B0_IMSK) & ~portirq_msk[sky2->port]);
+	sky2_read32(hw, B0_IMSK);
+
+	synchronize_irq(hw->pdev->irq);
+	napi_synchronize(&hw->napi);
+
+	sky2_hw_down(sky2);
 
 	sky2_free_buffers(sky2);
 
@@ -1994,12 +2025,11 @@ static void sky2_link_up(struct sky2_por
 	sky2_write8(hw, SK_REG(port, LNK_LED_REG),
 		    LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
 
-	if (netif_msg_link(sky2))
-		printk(KERN_INFO PFX
-		       "%s: Link is up at %d Mbps, %s duplex, flow control %s\n",
-		       sky2->netdev->name, sky2->speed,
-		       sky2->duplex == DUPLEX_FULL ? "full" : "half",
-		       fc_name[sky2->flow_status]);
+	netif_info(sky2, link, sky2->netdev,
+		   "Link is up at %d Mbps, %s duplex, flow control %s\n",
+		   sky2->speed,
+		   sky2->duplex == DUPLEX_FULL ? "full" : "half",
+		   fc_name[sky2->flow_status]);
 }
 
 static void sky2_link_down(struct sky2_port *sky2)
@@ -2019,8 +2049,7 @@ static void sky2_link_down(struct sky2_p
 	/* Turn off link LED */
 	sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
 
-	if (netif_msg_link(sky2))
-		printk(KERN_INFO PFX "%s: Link is down.\n", sky2->netdev->name);
+	netif_info(sky2, link, sky2->netdev, "Link is down\n");
 
 	sky2_phy_init(hw, port);
 }
@@ -2042,13 +2071,12 @@ static int sky2_autoneg_done(struct sky2
 	advert = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
 	lpa = gm_phy_read(hw, port, PHY_MARV_AUNE_LP);
 	if (lpa & PHY_M_AN_RF) {
-		printk(KERN_ERR PFX "%s: remote fault", sky2->netdev->name);
+		netdev_err(sky2->netdev, "remote fault\n");
 		return -1;
 	}
 
 	if (!(aux & PHY_M_PS_SPDUP_RES)) {
-		printk(KERN_ERR PFX "%s: speed/duplex mismatch",
-		       sky2->netdev->name);
+		netdev_err(sky2->netdev, "speed/duplex mismatch\n");
 		return -1;
 	}
 
@@ -2110,9 +2138,8 @@ static void sky2_phy_intr(struct sky2_hw
 	istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
 	phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
 
-	if (netif_msg_intr(sky2))
-		printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n",
-		       sky2->netdev->name, istatus, phystat);
+	netif_info(sky2, intr, sky2->netdev, "phy interrupt status 0x%x 0x%x\n",
+		   istatus, phystat);
 
 	if (istatus & PHY_M_IS_AN_COMPL) {
 		if (sky2_autoneg_done(sky2, phystat) == 0)
@@ -2166,13 +2193,12 @@ static void sky2_tx_timeout(struct net_d
 	struct sky2_port *sky2 = netdev_priv(dev);
 	struct sky2_hw *hw = sky2->hw;
 
-	if (netif_msg_timer(sky2))
-		printk(KERN_ERR PFX "%s: tx timeout\n", dev->name);
+	netif_err(sky2, timer, dev, "tx timeout\n");
 
-	printk(KERN_DEBUG PFX "%s: transmit ring %u .. %u report=%u done=%u\n",
-	       dev->name, sky2->tx_cons, sky2->tx_prod,
-	       sky2_read16(hw, sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX),
-	       sky2_read16(hw, Q_ADDR(txqaddr[sky2->port], Q_DONE)));
+	netdev_printk(KERN_DEBUG, dev, "transmit ring %u .. %u report=%u done=%u\n",
+		      sky2->tx_cons, sky2->tx_prod,
+		      sky2_read16(hw, sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX),
+		      sky2_read16(hw, Q_ADDR(txqaddr[sky2->port], Q_DONE)));
 
 	/* can't restart safely under softirq */
 	schedule_work(&hw->restart_work);
@@ -2187,14 +2213,20 @@ static int sky2_change_mtu(struct net_de
 	u16 ctl, mode;
 	u32 imask;
 
+	/* MTU size outside the spec */
 	if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
 		return -EINVAL;
 
+	/* MTU > 1500 on yukon FE and FE+ not allowed */
 	if (new_mtu > ETH_DATA_LEN &&
 	    (hw->chip_id == CHIP_ID_YUKON_FE ||
 	     hw->chip_id == CHIP_ID_YUKON_FE_P))
 		return -EINVAL;
 
+	/* TSO, etc on Yukon Ultra and MTU > 1500 not supported */
+	if (new_mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U)
+		dev->features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM);
+
 	if (!netif_running(dev)) {
 		dev->mtu = new_mtu;
 		return 0;
@@ -2229,7 +2261,11 @@ static int sky2_change_mtu(struct net_de
 
 	sky2_write8(hw, RB_ADDR(rxqaddr[port], RB_CTRL), RB_ENA_OP_MD);
 
-	err = sky2_rx_start(sky2);
+	err = sky2_alloc_rx_skbs(sky2);
+	if (!err)
+		sky2_rx_start(sky2);
+	else
+		sky2_rx_clean(sky2);
 	sky2_write32(hw, B0_IMSK, imask);
 
 	sky2_read32(hw, B0_Y2_SP_LISR);
@@ -2306,30 +2342,32 @@ static struct sk_buff *receive_new(struc
 				   struct rx_ring_info *re,
 				   unsigned int length)
 {
-	struct sk_buff *skb, *nskb;
+	struct sk_buff *skb;
+	struct rx_ring_info nre;
 	unsigned hdr_space = sky2->rx_data_size;
 
-	/* Don't be tricky about reusing pages (yet) */
-	nskb = sky2_rx_alloc(sky2);
-	if (unlikely(!nskb))
-		return NULL;
+	nre.skb = sky2_rx_alloc(sky2);
+	if (unlikely(!nre.skb))
+		goto nobuf;
+
+	if (sky2_rx_map_skb(sky2->hw->pdev, &nre, hdr_space))
+		goto nomap;
 
 	skb = re->skb;
 	sky2_rx_unmap_skb(sky2->hw->pdev, re);
-
 	prefetch(skb->data);
-	re->skb = nskb;
-	if (sky2_rx_map_skb(sky2->hw->pdev, re, hdr_space)) {
-		dev_kfree_skb(nskb);
-		re->skb = skb;
-		return NULL;
-	}
+	*re = nre;
 
 	if (skb_shinfo(skb)->nr_frags)
 		skb_put_frags(skb, hdr_space, length);
 	else
 		skb_put(skb, length);
 	return skb;
+
+nomap:
+	dev_kfree_skb(nre.skb);
+nobuf:
+	return NULL;
 }
 
 /*
@@ -2350,9 +2388,9 @@ static struct sk_buff *sky2_receive(stru
 		count -= VLAN_HLEN;
 #endif
 
-	if (unlikely(netif_msg_rx_status(sky2)))
-		printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n",
-		       dev->name, sky2->rx_next, status, length);
+	netif_printk(sky2, rx_status, KERN_DEBUG, dev,
+		     "rx slot %u status 0x%x len %d\n",
+		     sky2->rx_next, status, length);
 
 	sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
 	prefetch(sky2->rx_ring + sky2->rx_next);
@@ -2381,6 +2419,9 @@ okay:
 		skb = receive_copy(sky2, re, length);
 	else
 		skb = receive_new(sky2, re, length);
+
+	dev->stats.rx_dropped += (skb == NULL);
+
 resubmit:
 	sky2_rx_submit(sky2, re);
 
@@ -2390,9 +2431,10 @@ len_error:
 	/* Truncation of overlength packets
 	   causes PHY length to not match MAC length */
 	++dev->stats.rx_length_errors;
-	if (netif_msg_rx_err(sky2) && net_ratelimit())
-		pr_info(PFX "%s: rx length error: status %#x length %d\n",
-			dev->name, status, length);
+	if (net_ratelimit())
+		netif_info(sky2, rx_err, dev,
+			   "rx length error: status %#x length %d\n",
+			   status, length);
 	goto resubmit;
 
 error:
@@ -2402,9 +2444,9 @@ error:
 		goto resubmit;
 	}
 
-	if (netif_msg_rx_err(sky2) && net_ratelimit())
-		printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n",
-		       dev->name, status, length);
+	if (net_ratelimit())
+		netif_info(sky2, rx_err, dev,
+			   "rx error, status 0x%x length %d\n", status, length);
 
 	if (status & (GMR_FS_LONG_ERR | GMR_FS_UN_SIZE))
 		dev->stats.rx_length_errors++;
@@ -2421,8 +2463,13 @@ static inline void sky2_tx_done(struct n
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
 
-	if (netif_running(dev))
+	if (netif_running(dev)) {
 		sky2_tx_complete(sky2, last);
+
+		/* Wake unless it's detached, and called e.g. from sky2_down() */
+		if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
+			netif_wake_queue(dev);
+	}
 }
 
 static inline void sky2_skb_rx(const struct sky2_port *sky2,
@@ -2458,6 +2505,32 @@ static inline void sky2_rx_done(struct s
 	}
 }
 
+static void sky2_rx_checksum(struct sky2_port *sky2, u32 status)
+{
+	/* If this happens then driver assuming wrong format for chip type */
+	BUG_ON(sky2->hw->flags & SKY2_HW_NEW_LE);
+
+	/* Both checksum counters are programmed to start at
+	 * the same offset, so unless there is a problem they
+	 * should match. This failure is an early indication that
+	 * hardware receive checksumming won't work.
+	 */
+	if (likely((u16)(status >> 16) == (u16)status)) {
+		struct sk_buff *skb = sky2->rx_ring[sky2->rx_next].skb;
+		skb->ip_summed = CHECKSUM_COMPLETE;
+		skb->csum = le16_to_cpu(status);
+	} else {
+		dev_notice(&sky2->hw->pdev->dev,
+			   "%s: receive checksum problem (status = %#x)\n",
+			   sky2->netdev->name, status);
+
+		/* Disable checksum offload */
+		sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM;
+		sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+			     BMU_DIS_RX_CHKSUM);
+	}
+}
+
 /* Process status response ring */
 static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
 {
@@ -2492,11 +2565,10 @@ static int sky2_status_intr(struct sky2_
 		case OP_RXSTAT:
 			total_packets[port]++;
 			total_bytes[port] += length;
+
 			skb = sky2_receive(dev, length, status);
-			if (unlikely(!skb)) {
-				dev->stats.rx_dropped++;
+			if (!skb)
 				break;
-			}
 
 			/* This chip reports checksum status differently */
 			if (hw->flags & SKY2_HW_NEW_LE) {
@@ -2527,37 +2599,8 @@ static int sky2_status_intr(struct sky2_
 			/* fall through */
 #endif
 		case OP_RXCHKS:
-			if (!(sky2->flags & SKY2_FLAG_RX_CHECKSUM))
-				break;
-
-			/* If this happens then driver assuming wrong format */
-			if (unlikely(hw->flags & SKY2_HW_NEW_LE)) {
-				if (net_ratelimit())
-					printk(KERN_NOTICE "%s: unexpected"
-					       " checksum status\n",
-					       dev->name);
-				break;
-			}
-
-			/* Both checksum counters are programmed to start at
-			 * the same offset, so unless there is a problem they
-			 * should match. This failure is an early indication that
-			 * hardware receive checksumming won't work.
-			 */
-			if (likely(status >> 16 == (status & 0xffff))) {
-				skb = sky2->rx_ring[sky2->rx_next].skb;
-				skb->ip_summed = CHECKSUM_COMPLETE;
-				skb->csum = le16_to_cpu(status);
-			} else {
-				printk(KERN_NOTICE PFX "%s: hardware receive "
-				       "checksum problem (status = %#x)\n",
-				       dev->name, status);
-				sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM;
-
-				sky2_write32(sky2->hw,
-					     Q_ADDR(rxqaddr[port], Q_CSR),
-					     BMU_DIS_RX_CHKSUM);
-			}
+			if (likely(sky2->flags & SKY2_FLAG_RX_CHECKSUM))
+				sky2_rx_checksum(sky2, status);
 			break;
 
 		case OP_TXINDEXLE:
@@ -2571,8 +2614,7 @@ static int sky2_status_intr(struct sky2_
 
 		default:
 			if (net_ratelimit())
-				printk(KERN_WARNING PFX
-				       "unknown status opcode 0x%x\n", opcode);
+				pr_warning("unknown status opcode 0x%x\n", opcode);
 		}
 	} while (hw->st_idx != idx);
 
@@ -2591,41 +2633,37 @@ static void sky2_hw_error(struct sky2_hw
 	struct net_device *dev = hw->dev[port];
 
 	if (net_ratelimit())
-		printk(KERN_INFO PFX "%s: hw error interrupt status 0x%x\n",
-		       dev->name, status);
+		netdev_info(dev, "hw error interrupt status 0x%x\n", status);
 
 	if (status & Y2_IS_PAR_RD1) {
 		if (net_ratelimit())
-			printk(KERN_ERR PFX "%s: ram data read parity error\n",
-			       dev->name);
+			netdev_err(dev, "ram data read parity error\n");
 		/* Clear IRQ */
 		sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_RD_PERR);
 	}
 
 	if (status & Y2_IS_PAR_WR1) {
 		if (net_ratelimit())
-			printk(KERN_ERR PFX "%s: ram data write parity error\n",
-			       dev->name);
+			netdev_err(dev, "ram data write parity error\n");
 
 		sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_WR_PERR);
 	}
 
 	if (status & Y2_IS_PAR_MAC1) {
 		if (net_ratelimit())
-			printk(KERN_ERR PFX "%s: MAC parity error\n", dev->name);
+			netdev_err(dev, "MAC parity error\n");
 		sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_PE);
 	}
 
 	if (status & Y2_IS_PAR_RX1) {
 		if (net_ratelimit())
-			printk(KERN_ERR PFX "%s: RX parity error\n", dev->name);
+			netdev_err(dev, "RX parity error\n");
 		sky2_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), BMU_CLR_IRQ_PAR);
 	}
 
 	if (status & Y2_IS_TCP_TXA1) {
 		if (net_ratelimit())
-			printk(KERN_ERR PFX "%s: TCP segmentation error\n",
-			       dev->name);
+			netdev_err(dev, "TCP segmentation error\n");
 		sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_CLR_IRQ_TCP);
 	}
 }
@@ -2683,9 +2721,7 @@ static void sky2_mac_intr(struct sky2_hw
 	struct sky2_port *sky2 = netdev_priv(dev);
 	u8 status = sky2_read8(hw, SK_REG(port, GMAC_IRQ_SRC));
 
-	if (netif_msg_intr(sky2))
-		printk(KERN_INFO PFX "%s: mac interrupt status 0x%x\n",
-		       dev->name, status);
+	netif_info(sky2, intr, dev, "mac interrupt status 0x%x\n", status);
 
 	if (status & GM_IS_RX_CO_OV)
 		gma_read16(hw, port, GM_RX_IRQ_SRC);
@@ -2710,8 +2746,7 @@ static void sky2_le_error(struct sky2_hw
 	struct net_device *dev = hw->dev[port];
 	u16 idx = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX));
 
-	dev_err(&hw->pdev->dev, PFX
-		"%s: descriptor error q=%#x get=%u put=%u\n",
+	dev_err(&hw->pdev->dev, "%s: descriptor error q=%#x get=%u put=%u\n",
 		dev->name, (unsigned) q, (unsigned) idx,
 		(unsigned) sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX)));
 
@@ -2736,9 +2771,10 @@ static int sky2_rx_hung(struct net_devic
 	     /* Check if the PCI RX hang */
 	     (fifo_rp == sky2->check.fifo_rp &&
 	      fifo_lev != 0 && fifo_lev >= sky2->check.fifo_lev))) {
-		printk(KERN_DEBUG PFX "%s: hung mac %d:%d fifo %d (%d:%d)\n",
-		       dev->name, mac_lev, mac_rp, fifo_lev, fifo_rp,
-		       sky2_read8(hw, Q_ADDR(rxq, Q_WP)));
+		netdev_printk(KERN_DEBUG, dev,
+			      "hung mac %d:%d fifo %d (%d:%d)\n",
+			      mac_lev, mac_rp, fifo_lev,
+			      fifo_rp, sky2_read8(hw, Q_ADDR(rxq, Q_WP)));
 		return 1;
 	} else {
 		sky2->check.last = dev->last_rx;
@@ -2769,8 +2805,7 @@ static void sky2_watchdog(unsigned long
 			/* For chips with Rx FIFO, check if stuck */
 			if ((hw->flags & SKY2_HW_RAM_BUFFER) &&
 			     sky2_rx_hung(dev)) {
-				pr_info(PFX "%s: receiver hang detected\n",
-					dev->name);
+				netdev_info(dev, "receiver hang detected\n");
 				schedule_work(&hw->restart_work);
 				return;
 			}
@@ -3010,11 +3045,20 @@ static void sky2_reset(struct sky2_hw *h
 	u32 hwe_mask = Y2_HWE_ALL_MASK;
 
 	/* disable ASF */
-	if (hw->chip_id == CHIP_ID_YUKON_EX) {
+	if (hw->chip_id == CHIP_ID_YUKON_EX
+	    || hw->chip_id == CHIP_ID_YUKON_SUPR) {
+		sky2_write32(hw, CPU_WDOG, 0);
 		status = sky2_read16(hw, HCU_CCSR);
 		status &= ~(HCU_CCSR_AHB_RST | HCU_CCSR_CPU_RST_MODE |
 			    HCU_CCSR_UC_STATE_MSK);
+		/*
+		 * CPU clock divider shouldn't be used because
+		 * - ASF firmware may malfunction
+		 * - Yukon-Supreme: Parallel FLASH doesn't support divided clocks
+		 */
+		status &= ~HCU_CCSR_CPU_CLK_DIVIDE_MSK;
 		sky2_write16(hw, HCU_CCSR, status);
+		sky2_write32(hw, CPU_WDOG, 0);
 	} else
 		sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
 	sky2_write16(hw, B0_CTST, Y2_ASF_DISABLE);
@@ -3097,7 +3141,7 @@ static void sky2_reset(struct sky2_hw *h
 		/* check if PSMv2 was running before */
 		reg = sky2_pci_read16(hw, PSM_CONFIG_REG3);
 		if (reg & PCI_EXP_LNKCTL_ASPMC) {
-			int cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+			cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
 			/* restore the PCIe Link Control register */
 			sky2_pci_write16(hw, cap + PCI_EXP_LNKCTL, reg);
 		}
@@ -3188,7 +3232,9 @@ static void sky2_reset(struct sky2_hw *h
 static void sky2_detach(struct net_device *dev)
 {
 	if (netif_running(dev)) {
+		netif_tx_lock(dev);
 		netif_device_detach(dev);	/* stop txq */
+		netif_tx_unlock(dev);
 		sky2_down(dev);
 	}
 }
@@ -3201,8 +3247,7 @@ static int sky2_reattach(struct net_devi
 	if (netif_running(dev)) {
 		err = sky2_up(dev);
 		if (err) {
-			printk(KERN_INFO PFX "%s: could not restart %d\n",
-			       dev->name, err);
+			netdev_info(dev, "could not restart %d\n", err);
 			dev_close(dev);
 		} else {
 			netif_device_attach(dev);
@@ -3216,48 +3261,53 @@ static int sky2_reattach(struct net_devi
 static void sky2_restart(struct work_struct *work)
 {
 	struct sky2_hw *hw = container_of(work, struct sky2_hw, restart_work);
+	u32 imask;
 	int i;
 
 	rtnl_lock();
-	for (i = 0; i < hw->ports; i++)
-		sky2_detach(hw->dev[i]);
 
 	napi_disable(&hw->napi);
+	synchronize_irq(hw->pdev->irq);
+	imask = sky2_read32(hw, B0_IMSK);
 	sky2_write32(hw, B0_IMSK, 0);
-	sky2_reset(hw);
-	sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
-	napi_enable(&hw->napi);
 
-	for (i = 0; i < hw->ports; i++)
-		sky2_reattach(hw->dev[i]);
+	for (i = 0; i < hw->ports; i++) {
+		struct net_device *dev = hw->dev[i];
+		struct sky2_port *sky2 = netdev_priv(dev);
 
-	rtnl_unlock();
-}
+		if (!netif_running(dev))
+			continue;
 
-static inline u8 sky2_wol_supported(const struct sky2_hw *hw)
-{
-	return sky2_is_copper(hw) ? (WAKE_PHY | WAKE_MAGIC) : 0;
-}
+		netif_carrier_off(dev);
+		netif_tx_disable(dev);
+		sky2_hw_down(sky2);
+	}
 
-static void sky2_hw_set_wol(struct sky2_hw *hw)
-{
-	int wol = 0;
-	int i;
+	sky2_reset(hw);
 
 	for (i = 0; i < hw->ports; i++) {
 		struct net_device *dev = hw->dev[i];
 		struct sky2_port *sky2 = netdev_priv(dev);
 
-		if (sky2->wol)
-			wol = 1;
+		if (!netif_running(dev))
+			continue;
+
+		sky2_hw_up(sky2);
+		netif_wake_queue(dev);
 	}
 
-	if (hw->chip_id == CHIP_ID_YUKON_EC_U ||
-	    hw->chip_id == CHIP_ID_YUKON_EX ||
-	    hw->chip_id == CHIP_ID_YUKON_FE_P)
-		sky2_write32(hw, B0_CTST, wol ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF);
+	sky2_write32(hw, B0_IMSK, imask);
+	sky2_read32(hw, B0_IMSK);
 
-	device_set_wakeup_enable(&hw->pdev->dev, wol);
+	sky2_read32(hw, B0_Y2_SP_LISR);
+	napi_enable(&hw->napi);
+
+	rtnl_unlock();
+}
+
+static inline u8 sky2_wol_supported(const struct sky2_hw *hw)
+{
+	return sky2_is_copper(hw) ? (WAKE_PHY | WAKE_MAGIC) : 0;
 }
 
 static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
@@ -3278,11 +3328,6 @@ static int sky2_set_wol(struct net_devic
 		return -EOPNOTSUPP;
 
 	sky2->wol = wol->wolopts;
-
-	sky2_hw_set_wol(hw);
-
-	if (!netif_running(dev))
-		sky2_wol_init(sky2);
 	return 0;
 }
 
@@ -3577,7 +3622,7 @@ static void sky2_set_multicast(struct ne
 	struct sky2_port *sky2 = netdev_priv(dev);
 	struct sky2_hw *hw = sky2->hw;
 	unsigned port = sky2->port;
-	struct dev_mc_list *list = dev->mc_list;
+	struct dev_mc_list *list;
 	u16 reg;
 	u8 filter[8];
 	int rx_pause;
@@ -3593,16 +3638,15 @@ static void sky2_set_multicast(struct ne
 		reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
 	else if (dev->flags & IFF_ALLMULTI)
 		memset(filter, 0xff, sizeof(filter));
-	else if (dev->mc_count == 0 && !rx_pause)
+	else if (netdev_mc_empty(dev) && !rx_pause)
 		reg &= ~GM_RXCR_MCF_ENA;
 	else {
-		int i;
 		reg |= GM_RXCR_MCF_ENA;
 
 		if (rx_pause)
 			sky2_add_filter(filter, pause_mc_addr);
 
-		for (i = 0; list && i < dev->mc_count; i++, list = list->next)
+		netdev_for_each_mc_addr(list, dev)
 			sky2_add_filter(filter, list->dmi_addr);
 	}
 
@@ -3864,6 +3908,50 @@ static int sky2_get_regs_len(struct net_
 	return 0x4000;
 }
 
+static int sky2_reg_access_ok(struct sky2_hw *hw, unsigned int b)
+{
+	/* This complicated switch statement is to make sure and
+	 * only access regions that are unreserved.
+	 * Some blocks are only valid on dual port cards.
+	 */
+	switch (b) {
+	/* second port */
+	case 5:		/* Tx Arbiter 2 */
+	case 9:		/* RX2 */
+	case 14 ... 15:	/* TX2 */
+	case 17: case 19: /* Ram Buffer 2 */
+	case 22 ... 23: /* Tx Ram Buffer 2 */
+	case 25:	/* Rx MAC Fifo 1 */
+	case 27:	/* Tx MAC Fifo 2 */
+	case 31:	/* GPHY 2 */
+	case 40 ... 47: /* Pattern Ram 2 */
+	case 52: case 54: /* TCP Segmentation 2 */
+	case 112 ... 116: /* GMAC 2 */
+		return hw->ports > 1;
+
+	case 0:		/* Control */
+	case 2:		/* Mac address */
+	case 4:		/* Tx Arbiter 1 */
+	case 7:		/* PCI express reg */
+	case 8:		/* RX1 */
+	case 12 ... 13: /* TX1 */
+	case 16: case 18:/* Rx Ram Buffer 1 */
+	case 20 ... 21: /* Tx Ram Buffer 1 */
+	case 24:	/* Rx MAC Fifo 1 */
+	case 26:	/* Tx MAC Fifo 1 */
+	case 28 ... 29: /* Descriptor and status unit */
+	case 30:	/* GPHY 1*/
+	case 32 ... 39: /* Pattern Ram 1 */
+	case 48: case 50: /* TCP Segmentation 1 */
+	case 56 ... 60:	/* PCI space */
+	case 80 ... 84:	/* GMAC 1 */
+		return 1;
+
+	default:
+		return 0;
+	}
+}
+
 /*
  * Returns copy of control register region
  * Note: ethtool_get_regs always provides full size (16k) buffer
@@ -3878,55 +3966,13 @@ static void sky2_get_regs(struct net_dev
 	regs->version = 1;
 
 	for (b = 0; b < 128; b++) {
-		/* This complicated switch statement is to make sure and
-		 * only access regions that are unreserved.
-		 * Some blocks are only valid on dual port cards.
-		 * and block 3 has some special diagnostic registers that
-		 * are poison.
-		 */
-		switch (b) {
-		case 3:
-			/* skip diagnostic ram region */
+		/* skip poisonous diagnostic ram region in block 3 */
+		if (b == 3)
 			memcpy_fromio(p + 0x10, io + 0x10, 128 - 0x10);
-			break;
-
-		/* dual port cards only */
-		case 5:		/* Tx Arbiter 2 */
-		case 9: 	/* RX2 */
-		case 14 ... 15:	/* TX2 */
-		case 17: case 19: /* Ram Buffer 2 */
-		case 22 ... 23: /* Tx Ram Buffer 2 */
-		case 25: 	/* Rx MAC Fifo 1 */
-		case 27: 	/* Tx MAC Fifo 2 */
-		case 31:	/* GPHY 2 */
-		case 40 ... 47: /* Pattern Ram 2 */
-		case 52: case 54: /* TCP Segmentation 2 */
-		case 112 ... 116: /* GMAC 2 */
-			if (sky2->hw->ports == 1)
-				goto reserved;
-			/* fall through */
-		case 0:		/* Control */
-		case 2:		/* Mac address */
-		case 4:		/* Tx Arbiter 1 */
-		case 7:		/* PCI express reg */
-		case 8:		/* RX1 */
-		case 12 ... 13: /* TX1 */
-		case 16: case 18:/* Rx Ram Buffer 1 */
-		case 20 ... 21: /* Tx Ram Buffer 1 */
-		case 24: 	/* Rx MAC Fifo 1 */
-		case 26: 	/* Tx MAC Fifo 1 */
-		case 28 ... 29: /* Descriptor and status unit */
-		case 30:	/* GPHY 1*/
-		case 32 ... 39: /* Pattern Ram 1 */
-		case 48: case 50: /* TCP Segmentation 1 */
-		case 56 ... 60:	/* PCI space */
-		case 80 ... 84:	/* GMAC 1 */
+		else if (sky2_reg_access_ok(sky2->hw, b))
 			memcpy_fromio(p, io, 128);
-			break;
-		default:
-reserved:
+		else
 			memset(p, 0, 128);
-		}
 
 		p += 128;
 		io += 128;
@@ -3978,7 +4024,7 @@ static int sky2_vpd_wait(const struct sk
 	while ( (sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F) == busy) {
 		/* Can take up to 10.6 ms for write */
 		if (time_after(jiffies, start + HZ/4)) {
-			dev_err(&hw->pdev->dev, PFX "VPD cycle timed out");
+			dev_err(&hw->pdev->dev, "VPD cycle timed out\n");
 			return -ETIMEDOUT;
 		}
 		mdelay(1);
@@ -4312,8 +4358,7 @@ static int sky2_device_event(struct noti
 
 	case NETDEV_GOING_DOWN:
 		if (sky2->debugfs) {
-			printk(KERN_DEBUG PFX "%s: remove debugfs\n",
-			       dev->name);
+			netdev_printk(KERN_DEBUG, dev, "remove debugfs\n");
 			debugfs_remove(sky2->debugfs);
 			sky2->debugfs = NULL;
 		}
@@ -4466,9 +4511,7 @@ static void __devinit sky2_show_addr(str
 {
 	const struct sky2_port *sky2 = netdev_priv(dev);
 
-	if (netif_msg_probe(sky2))
-		printk(KERN_INFO PFX "%s: addr %pM\n",
-		       dev->name, dev->dev_addr);
+	netif_info(sky2, probe, dev, "addr %pM\n", dev->dev_addr);
 }
 
 /* Handle software interrupt used during MSI test */
@@ -4774,7 +4817,6 @@ static void __devexit sky2_remove(struct
 	pci_set_drvdata(pdev, NULL);
 }
 
-#ifdef CONFIG_PM
 static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct sky2_hw *hw = pci_get_drvdata(pdev);
@@ -4799,6 +4841,8 @@ static int sky2_suspend(struct pci_dev *
 		wol |= sky2->wol;
 	}
 
+	device_set_wakeup_enable(&pdev->dev, wol != 0);
+
 	sky2_write32(hw, B0_IMSK, 0);
 	napi_disable(&hw->napi);
 	sky2_power_aux(hw);
@@ -4811,6 +4855,7 @@ static int sky2_suspend(struct pci_dev *
 	return 0;
 }
 
+#ifdef CONFIG_PM
 static int sky2_resume(struct pci_dev *pdev)
 {
 	struct sky2_hw *hw = pci_get_drvdata(pdev);
@@ -4819,6 +4864,7 @@ static int sky2_resume(struct pci_dev *p
 	if (!hw)
 		return 0;
 
+	rtnl_lock();
 	err = pci_set_power_state(pdev, PCI_D0);
 	if (err)
 		goto out;
@@ -4830,16 +4876,16 @@ static int sky2_resume(struct pci_dev *p
 	pci_enable_wake(pdev, PCI_D0, 0);
 
 	/* Re-enable all clocks */
-	if (hw->chip_id == CHIP_ID_YUKON_EX ||
-	    hw->chip_id == CHIP_ID_YUKON_EC_U ||
-	    hw->chip_id == CHIP_ID_YUKON_FE_P)
-		sky2_pci_write32(hw, PCI_DEV_REG3, 0);
+	err = pci_write_config_dword(pdev, PCI_DEV_REG3, 0);
+	if (err) {
+		dev_err(&pdev->dev, "PCI write config failed\n");
+		goto out;
+	}
 
 	sky2_reset(hw);
 	sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
 	napi_enable(&hw->napi);
 
-	rtnl_lock();
 	for (i = 0; i < hw->ports; i++) {
 		err = sky2_reattach(hw->dev[i]);
 		if (err)
@@ -4859,34 +4905,7 @@ out:
 
 static void sky2_shutdown(struct pci_dev *pdev)
 {
-	struct sky2_hw *hw = pci_get_drvdata(pdev);
-	int i, wol = 0;
-
-	if (!hw)
-		return;
-
-	rtnl_lock();
-	del_timer_sync(&hw->watchdog_timer);
-
-	for (i = 0; i < hw->ports; i++) {
-		struct net_device *dev = hw->dev[i];
-		struct sky2_port *sky2 = netdev_priv(dev);
-
-		if (sky2->wol) {
-			wol = 1;
-			sky2_wol_init(sky2);
-		}
-	}
-
-	if (wol)
-		sky2_power_aux(hw);
-	rtnl_unlock();
-
-	pci_enable_wake(pdev, PCI_D3hot, wol);
-	pci_enable_wake(pdev, PCI_D3cold, wol);
-
-	pci_disable_device(pdev);
-	pci_set_power_state(pdev, PCI_D3hot);
+	sky2_suspend(pdev, PMSG_SUSPEND);
 }
 
 static struct pci_driver sky2_driver = {
@@ -4903,7 +4922,7 @@ static struct pci_driver sky2_driver = {
 
 static int __init sky2_init_module(void)
 {
-	pr_info(PFX "driver version " DRV_VERSION "\n");
+	pr_info("driver version " DRV_VERSION "\n");
 
 	sky2_debug_init();
 	return pci_register_driver(&sky2_driver);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sky2.h linux-libre-2.6.34-gnu1/drivers/net/sky2.h
--- linux-libre-2.6.33-gnu1/drivers/net/sky2.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sky2.h	2010-05-16 17:17:36.000000000 -0400
@@ -1895,14 +1895,14 @@ enum {
 
 /*	TX_GMF_CTRL_T	32 bit	Tx GMAC FIFO Control/Test */
 enum {
-	TX_STFW_DIS	= 1<<31,/* Disable Store & Forward (Yukon-EC Ultra) */
-	TX_STFW_ENA	= 1<<30,/* Enable  Store & Forward (Yukon-EC Ultra) */
+	TX_STFW_DIS	= 1<<31,/* Disable Store & Forward */
+	TX_STFW_ENA	= 1<<30,/* Enable  Store & Forward */
 
 	TX_VLAN_TAG_ON	= 1<<25,/* enable  VLAN tagging */
 	TX_VLAN_TAG_OFF	= 1<<24,/* disable VLAN tagging */
 
-	TX_JUMBO_ENA	= 1<<23,/* PCI Jumbo Mode enable (Yukon-EC Ultra) */
-	TX_JUMBO_DIS	= 1<<22,/* PCI Jumbo Mode enable (Yukon-EC Ultra) */
+	TX_PCI_JUM_ENA  = 1<<23,/* PCI Jumbo Mode enable */
+	TX_PCI_JUM_DIS  = 1<<22,/* PCI Jumbo Mode enable */
 
 	GMF_WSP_TST_ON	= 1<<18,/* Write Shadow Pointer Test On */
 	GMF_WSP_TST_OFF	= 1<<17,/* Write Shadow Pointer Test Off */
@@ -2156,7 +2156,7 @@ struct tx_ring_info {
 	struct sk_buff	*skb;
 	unsigned long flags;
 #define TX_MAP_SINGLE   0x0001
-#define TX_MAP_PAGE     000002
+#define TX_MAP_PAGE     0x0002
 	DECLARE_PCI_UNMAP_ADDR(mapaddr);
 	DECLARE_PCI_UNMAP_LEN(maplen);
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/slhc.c linux-libre-2.6.34-gnu1/drivers/net/slhc.c
--- linux-libre-2.6.33-gnu1/drivers/net/slhc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/slhc.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,6 +51,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/errno.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/slip.c linux-libre-2.6.34-gnu1/drivers/net/slip.c
--- linux-libre-2.6.33-gnu1/drivers/net/slip.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/slip.c	2010-05-16 17:17:36.000000000 -0400
@@ -83,6 +83,7 @@
 #include <linux/compat.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include "slip.h"
 #ifdef CONFIG_INET
 #include <linux/ip.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/smc911x.c linux-libre-2.6.34-gnu1/drivers/net/smc911x.c
--- linux-libre-2.6.33-gnu1/drivers/net/smc911x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/smc911x.c	2010-05-16 17:17:36.000000000 -0400
@@ -59,7 +59,6 @@ static const char version[] =
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
@@ -1323,7 +1322,7 @@ static void smc911x_set_multicast_list(s
 	 * I don't need to zero the multicast table, because the flag is
 	 * checked before the table is
 	 */
-	else if (dev->flags & IFF_ALLMULTI || dev->mc_count > 16) {
+	else if (dev->flags & IFF_ALLMULTI || netdev_mc_count(dev) > 16) {
 		DBG(SMC_DEBUG_MISC, "%s: RCR_ALMUL\n", dev->name);
 		mcr |= MAC_CR_MCPAS_;
 	}
@@ -1340,8 +1339,7 @@ static void smc911x_set_multicast_list(s
 	 * the number of the 32 bit register, while the low 5 bits are the bit
 	 * within that register.
 	 */
-	else if (dev->mc_count)  {
-		int i;
+	else if (!netdev_mc_empty(dev)) {
 		struct dev_mc_list *cur_addr;
 
 		/* Set the Hash perfec mode */
@@ -1350,8 +1348,7 @@ static void smc911x_set_multicast_list(s
 		/* start with a table of all zeros: reject all */
 		memset(multicast_table, 0, sizeof(multicast_table));
 
-		cur_addr = dev->mc_list;
-		for (i = 0; i < dev->mc_count; i++, cur_addr = cur_addr->next) {
+		netdev_for_each_mc_addr(cur_addr, dev) {
 			u32 position;
 
 			/* do we have a pointer here? */
@@ -2017,10 +2014,8 @@ static int __devinit smc911x_probe(struc
 					"set using ifconfig\n", dev->name);
 		} else {
 			/* Print the Ethernet address */
-			printk("%s: Ethernet addr: ", dev->name);
-			for (i = 0; i < 5; i++)
-				printk("%2.2x:", dev->dev_addr[i]);
-			printk("%2.2x\n", dev->dev_addr[5]);
+			printk("%s: Ethernet addr: %pM\n",
+				dev->name, dev->dev_addr);
 		}
 
 		if (lp->phy_type == 0) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/smc911x.h linux-libre-2.6.34-gnu1/drivers/net/smc911x.h
--- linux-libre-2.6.33-gnu1/drivers/net/smc911x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/smc911x.h	2010-05-16 17:17:36.000000000 -0400
@@ -42,12 +42,12 @@
   #define SMC_USE_16BIT		0
   #define SMC_USE_32BIT		1
   #define SMC_IRQ_SENSE		IRQF_TRIGGER_LOW
-#elif defined(CONFIG_ARCH_OMAP34XX)
+#elif defined(CONFIG_ARCH_OMAP3)
   #define SMC_USE_16BIT		0
   #define SMC_USE_32BIT		1
   #define SMC_IRQ_SENSE		IRQF_TRIGGER_LOW
   #define SMC_MEM_RESERVED	1
-#elif defined(CONFIG_ARCH_OMAP24XX)
+#elif defined(CONFIG_ARCH_OMAP2)
   #define SMC_USE_16BIT		0
   #define SMC_USE_32BIT		1
   #define SMC_IRQ_SENSE		IRQF_TRIGGER_LOW
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/smc9194.c linux-libre-2.6.34-gnu1/drivers/net/smc9194.c
--- linux-libre-2.6.33-gnu1/drivers/net/smc9194.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/smc9194.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,7 +64,6 @@ static const char version[] =
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
@@ -434,18 +433,18 @@ static void smc_shutdown( int ioaddr )
 */
 
 
-static void smc_setmulticast( int ioaddr, int count, struct dev_mc_list * addrs ) {
+static void smc_setmulticast(int ioaddr, struct net_device *dev)
+{
 	int			i;
 	unsigned char		multicast_table[ 8 ];
-	struct dev_mc_list	* cur_addr;
+	struct dev_mc_list *cur_addr;
 	/* table for flipping the order of 3 bits */
 	unsigned char invert3[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
 
 	/* start with a table of all zeros: reject all */
 	memset( multicast_table, 0, sizeof( multicast_table ) );
 
-	cur_addr = addrs;
-	for ( i = 0; i < count ; i ++, cur_addr = cur_addr->next  ) {
+	netdev_for_each_mc_addr(cur_addr, dev) {
 		int position;
 
 		/* do we have a pointer here? */
@@ -1542,7 +1541,7 @@ static void smc_set_multicast_list(struc
 	/* We just get all multicast packets even if we only want them
 	 . from one source.  This will be changed at some future
 	 . point. */
-	else if (dev->mc_count )  {
+	else if (!netdev_mc_empty(dev)) {
 		/* support hardware multicasting */
 
 		/* be sure I get rid of flags I might have set */
@@ -1550,7 +1549,7 @@ static void smc_set_multicast_list(struc
 			ioaddr + RCR );
 		/* NOTE: this has to set the bank, so make sure it is the
 		   last thing called.  The bank is set to zero at the top */
-		smc_setmulticast( ioaddr, dev->mc_count, dev->mc_list );
+		smc_setmulticast(ioaddr, dev);
 	}
 	else  {
 		outw( inw( ioaddr + RCR ) & ~(RCR_PROMISC | RCR_ALMUL),
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/smc91x.c linux-libre-2.6.34-gnu1/drivers/net/smc91x.c
--- linux-libre-2.6.33-gnu1/drivers/net/smc91x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/smc91x.c	2010-05-16 17:17:36.000000000 -0400
@@ -70,7 +70,6 @@ static const char version[] =
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
@@ -1395,7 +1394,7 @@ static void smc_set_multicast_list(struc
 	 * I don't need to zero the multicast table, because the flag is
 	 * checked before the table is
 	 */
-	else if (dev->flags & IFF_ALLMULTI || dev->mc_count > 16) {
+	else if (dev->flags & IFF_ALLMULTI || netdev_mc_count(dev) > 16) {
 		DBG(2, "%s: RCR_ALMUL\n", dev->name);
 		lp->rcr_cur_mode |= RCR_ALMUL;
 	}
@@ -1412,8 +1411,7 @@ static void smc_set_multicast_list(struc
 	 * the number of the 8 bit register, while the low 3 bits are the bit
 	 * within that register.
 	 */
-	else if (dev->mc_count)  {
-		int i;
+	else if (!netdev_mc_empty(dev)) {
 		struct dev_mc_list *cur_addr;
 
 		/* table for flipping the order of 3 bits */
@@ -1422,13 +1420,9 @@ static void smc_set_multicast_list(struc
 		/* start with a table of all zeros: reject all */
 		memset(multicast_table, 0, sizeof(multicast_table));
 
-		cur_addr = dev->mc_list;
-		for (i = 0; i < dev->mc_count; i++, cur_addr = cur_addr->next) {
+		netdev_for_each_mc_addr(cur_addr, dev) {
 			int position;
 
-			/* do we have a pointer here? */
-			if (!cur_addr)
-				break;
 			/* make sure this is a multicast address -
 		   	   shouldn't this be a given if we have it here ? */
 			if (!(*cur_addr->dmi_addr & 1))
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/smc91x.h linux-libre-2.6.34-gnu1/drivers/net/smc91x.h
--- linux-libre-2.6.33-gnu1/drivers/net/smc91x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/smc91x.h	2010-05-16 17:17:36.000000000 -0400
@@ -330,6 +330,48 @@ static inline void LPD7_SMC_outsw (unsig
 
 #include <unit/smc91111.h>
 
+#elif defined(CONFIG_ARCH_MSM)
+
+#define SMC_CAN_USE_8BIT	0
+#define SMC_CAN_USE_16BIT	1
+#define SMC_CAN_USE_32BIT	0
+#define SMC_NOWAIT		1
+
+#define SMC_inw(a, r)		readw((a) + (r))
+#define SMC_outw(v, a, r)	writew(v, (a) + (r))
+#define SMC_insw(a, r, p, l)	readsw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l)	writesw((a) + (r), p, l)
+
+#define SMC_IRQ_FLAGS		IRQF_TRIGGER_HIGH
+
+#elif defined(CONFIG_COLDFIRE)
+
+#define SMC_CAN_USE_8BIT	0
+#define SMC_CAN_USE_16BIT	1
+#define SMC_CAN_USE_32BIT	0
+#define SMC_NOWAIT		1
+
+static inline void mcf_insw(void *a, unsigned char *p, int l)
+{
+	u16 *wp = (u16 *) p;
+	while (l-- > 0)
+		*wp++ = readw(a);
+}
+
+static inline void mcf_outsw(void *a, unsigned char *p, int l)
+{
+	u16 *wp = (u16 *) p;
+	while (l-- > 0)
+		writew(*wp++, a);
+}
+
+#define SMC_inw(a, r)		_swapw(readw((a) + (r)))
+#define SMC_outw(v, a, r)	writew(_swapw(v), (a) + (r))
+#define SMC_insw(a, r, p, l)	mcf_insw(a + r, p, l)
+#define SMC_outsw(a, r, p, l)	mcf_outsw(a + r, p, l)
+
+#define SMC_IRQ_FLAGS		(IRQF_DISABLED)
+
 #else
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/smsc911x.c linux-libre-2.6.34-gnu1/drivers/net/smsc911x.c
--- linux-libre-2.6.33-gnu1/drivers/net/smsc911x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/smsc911x.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,6 @@
 #include <linux/netdevice.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/bug.h>
 #include <linux/bitops.h>
@@ -770,29 +769,25 @@ static int smsc911x_mii_probe(struct net
 {
 	struct smsc911x_data *pdata = netdev_priv(dev);
 	struct phy_device *phydev = NULL;
-	int phy_addr;
+	int ret;
 
 	/* find the first phy */
-	for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
-		if (pdata->mii_bus->phy_map[phy_addr]) {
-			phydev = pdata->mii_bus->phy_map[phy_addr];
-			SMSC_TRACE(PROBE, "PHY %d: addr %d, phy_id 0x%08X",
-				phy_addr, phydev->addr, phydev->phy_id);
-			break;
-		}
-	}
-
+	phydev = phy_find_first(pdata->mii_bus);
 	if (!phydev) {
 		pr_err("%s: no PHY found\n", dev->name);
 		return -ENODEV;
 	}
 
-	phydev = phy_connect(dev, dev_name(&phydev->dev),
-		&smsc911x_phy_adjust_link, 0, pdata->config.phy_interface);
+	SMSC_TRACE(PROBE, "PHY %d: addr %d, phy_id 0x%08X",
+			phy_addr, phydev->addr, phydev->phy_id);
 
-	if (IS_ERR(phydev)) {
+	ret = phy_connect_direct(dev, phydev,
+			&smsc911x_phy_adjust_link, 0,
+			pdata->config.phy_interface);
+
+	if (ret) {
 		pr_err("%s: Could not attach to PHY\n", dev->name);
-		return PTR_ERR(phydev);
+		return ret;
 	}
 
 	pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
@@ -1383,33 +1378,24 @@ static void smsc911x_set_multicast_list(
 		pdata->clear_bits_mask = (MAC_CR_PRMS_ | MAC_CR_HPFILT_);
 		pdata->hashhi = 0;
 		pdata->hashlo = 0;
-	} else if (dev->mc_count > 0) {
+	} else if (!netdev_mc_empty(dev)) {
 		/* Enabling specific multicast addresses */
 		unsigned int hash_high = 0;
 		unsigned int hash_low = 0;
-		unsigned int count = 0;
-		struct dev_mc_list *mc_list = dev->mc_list;
+		struct dev_mc_list *mc_list;
 
 		pdata->set_bits_mask = MAC_CR_HPFILT_;
 		pdata->clear_bits_mask = (MAC_CR_PRMS_ | MAC_CR_MCPAS_);
 
-		while (mc_list) {
-			count++;
-			if ((mc_list->dmi_addrlen) == ETH_ALEN) {
-				unsigned int bitnum =
-				    smsc911x_hash(mc_list->dmi_addr);
-				unsigned int mask = 0x01 << (bitnum & 0x1F);
-				if (bitnum & 0x20)
-					hash_high |= mask;
-				else
-					hash_low |= mask;
-			} else {
-				SMSC_WARNING(DRV, "dmi_addrlen != 6");
-			}
-			mc_list = mc_list->next;
+		netdev_for_each_mc_addr(mc_list, dev) {
+			unsigned int bitnum = smsc911x_hash(mc_list->dmi_addr);
+			unsigned int mask = 0x01 << (bitnum & 0x1F);
+
+			if (bitnum & 0x20)
+				hash_high |= mask;
+			else
+				hash_low |= mask;
 		}
-		if (count != (unsigned int)dev->mc_count)
-			SMSC_WARNING(DRV, "mc_count != dev->mc_count");
 
 		pdata->hashhi = hash_high;
 		pdata->hashlo = hash_low;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/smsc9420.c linux-libre-2.6.34-gnu1/drivers/net/smsc9420.c
--- linux-libre-2.6.33-gnu1/drivers/net/smsc9420.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/smsc9420.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/if_vlan.h>
 #include <linux/dma-mapping.h>
 #include <linux/crc32.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include "smsc9420.h"
 
@@ -80,7 +81,7 @@ struct smsc9420_pdata {
 	int last_carrier;
 };
 
-static const struct pci_device_id smsc9420_id_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(smsc9420_id_table) = {
 	{ PCI_VENDOR_ID_9420, PCI_DEVICE_ID_9420, PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0, }
 };
@@ -1062,12 +1063,12 @@ static void smsc9420_set_multicast_list(
 		mac_cr &= (~MAC_CR_PRMS_);
 		mac_cr |= MAC_CR_MCPAS_;
 		mac_cr &= (~MAC_CR_HPFILT_);
-	} else if (dev->mc_count > 0) {
-		struct dev_mc_list *mc_list = dev->mc_list;
+	} else if (!netdev_mc_empty(dev)) {
+		struct dev_mc_list *mc_list;
 		u32 hash_lo = 0, hash_hi = 0;
 
 		smsc_dbg(HW, "Multicast filter enabled");
-		while (mc_list) {
+		netdev_for_each_mc_addr(mc_list, dev) {
 			u32 bit_num = smsc9420_hash(mc_list->dmi_addr);
 			u32 mask = 1 << (bit_num & 0x1F);
 
@@ -1076,7 +1077,6 @@ static void smsc9420_set_multicast_list(
 			else
 				hash_lo |= mask;
 
-			mc_list = mc_list->next;
 		}
 		smsc9420_reg_write(pd, HASHH, hash_hi);
 		smsc9420_reg_write(pd, HASHL, hash_lo);
@@ -1348,7 +1348,7 @@ static int smsc9420_open(struct net_devi
 
 	netif_carrier_off(dev);
 
-	/* disable, mask and acknowlege all interrupts */
+	/* disable, mask and acknowledge all interrupts */
 	spin_lock_irqsave(&pd->int_lock, flags);
 	int_cfg = smsc9420_reg_read(pd, INT_CFG) & (~INT_CFG_IRQ_EN_);
 	smsc9420_reg_write(pd, INT_CFG, int_cfg);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sni_82596.c linux-libre-2.6.34-gnu1/drivers/net/sni_82596.c
--- linux-libre-2.6.33-gnu1/drivers/net/sni_82596.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sni_82596.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sonic.c linux-libre-2.6.34-gnu1/drivers/net/sonic.c
--- linux-libre-2.6.33-gnu1/drivers/net/sonic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sonic.c	2010-05-16 17:17:36.000000000 -0400
@@ -531,7 +531,7 @@ static void sonic_multicast_list(struct
 {
 	struct sonic_local *lp = netdev_priv(dev);
 	unsigned int rcr;
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	unsigned char *addr;
 	int i;
 
@@ -541,19 +541,22 @@ static void sonic_multicast_list(struct
 	if (dev->flags & IFF_PROMISC) {	/* set promiscuous mode */
 		rcr |= SONIC_RCR_PRO;
 	} else {
-		if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 15)) {
+		if ((dev->flags & IFF_ALLMULTI) ||
+		    (netdev_mc_count(dev) > 15)) {
 			rcr |= SONIC_RCR_AMC;
 		} else {
 			if (sonic_debug > 2)
-				printk("sonic_multicast_list: mc_count %d\n", dev->mc_count);
+				printk("sonic_multicast_list: mc_count %d\n",
+				       netdev_mc_count(dev));
 			sonic_set_cam_enable(dev, 1);  /* always enable our own address */
-			for (i = 1; i <= dev->mc_count; i++) {
+			i = 1;
+			netdev_for_each_mc_addr(dmi, dev) {
 				addr = dmi->dmi_addr;
-				dmi = dmi->next;
 				sonic_cda_put(dev, i, SONIC_CD_CAP0, addr[1] << 8 | addr[0]);
 				sonic_cda_put(dev, i, SONIC_CD_CAP1, addr[3] << 8 | addr[2]);
 				sonic_cda_put(dev, i, SONIC_CD_CAP2, addr[5] << 8 | addr[4]);
 				sonic_set_cam_enable(dev, sonic_get_cam_enable(dev) | (1 << i));
+				i++;
 			}
 			SONIC_WRITE(SONIC_CDC, 16);
 			/* issue Load CAM command */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/spider_net.c linux-libre-2.6.34-gnu1/drivers/net/spider_net.c
--- linux-libre-2.6.33-gnu1/drivers/net/spider_net.c	2013-05-03 12:08:30.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/spider_net.c	2013-05-03 09:48:01.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/if_vlan.h>
 #include <linux/in.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/ioport.h>
 #include <linux/ip.h>
 #include <linux/kernel.h>
@@ -40,7 +41,6 @@
 #include <linux/device.h>
 #include <linux/pci.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
@@ -72,7 +72,7 @@ MODULE_PARM_DESC(tx_descriptors, "number
 
 char spider_net_driver_name[] = "spidernet";
 
-static struct pci_device_id spider_net_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(spider_net_pci_tbl) = {
 	{ PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SPIDER_NET,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{ 0, }
@@ -474,7 +474,7 @@ spider_net_prepare_rx_descr(struct spide
  * spider_net_enable_rxchtails - sets RX dmac chain tail addresses
  * @card: card structure
  *
- * spider_net_enable_rxchtails sets the RX DMAC chain tail adresses in the
+ * spider_net_enable_rxchtails sets the RX DMAC chain tail addresses in the
  * chip by writing to the appropriate register. DMA is enabled in
  * spider_net_enable_rxdmac.
  */
@@ -646,7 +646,7 @@ spider_net_set_multi(struct net_device *
 	hash = spider_net_get_multicast_hash(netdev, netdev->broadcast); */
 	set_bit(0xfd, bitmask);
 
-	for (mc = netdev->mc_list; mc; mc = mc->next) {
+	netdev_for_each_mc_addr(mc, netdev) {
 		hash = spider_net_get_multicast_hash(netdev, mc->dmi_addr);
 		set_bit(hash, bitmask);
 	}
@@ -1820,7 +1820,7 @@ spider_net_enable_card(struct spider_net
 
 	spider_net_write_reg(card, SPIDER_NET_ECMODE, SPIDER_NET_ECMODE_VALUE);
 
-	/* set chain tail adress for RX chains and
+	/* set chain tail address for RX chains and
 	 * enable DMA */
 	spider_net_enable_rxchtails(card);
 	spider_net_enable_rxdmac(card);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/starfire.c linux-libre-2.6.34-gnu1/drivers/net/starfire.c
--- linux-libre-2.6.33-gnu1/drivers/net/starfire.c	2013-05-03 12:07:43.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/starfire.c	2013-05-03 09:47:06.000000000 -0400
@@ -300,7 +300,7 @@ enum chipset {
 	CH_6915 = 0,
 };
 
-static struct pci_device_id starfire_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(starfire_pci_tbl) = {
 	{ 0x9004, 0x6915, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_6915 },
 	{ 0, }
 };
@@ -1795,22 +1795,22 @@ static void set_rx_mode(struct net_devic
 
 	if (dev->flags & IFF_PROMISC) {	/* Set promiscuous. */
 		rx_mode |= AcceptAll;
-	} else if ((dev->mc_count > multicast_filter_limit) ||
+	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
 		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
 		rx_mode |= AcceptBroadcast|AcceptAllMulticast|PerfectFilter;
-	} else if (dev->mc_count <= 14) {
+	} else if (netdev_mc_count(dev) <= 14) {
 		/* Use the 16 element perfect filter, skip first two entries. */
 		void __iomem *filter_addr = ioaddr + PerfFilterTable + 2 * 16;
 		__be16 *eaddrs;
-		for (i = 2, mclist = dev->mc_list; mclist && i < dev->mc_count + 2;
-		     i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			eaddrs = (__be16 *)mclist->dmi_addr;
 			writew(be16_to_cpu(eaddrs[2]), filter_addr); filter_addr += 4;
 			writew(be16_to_cpu(eaddrs[1]), filter_addr); filter_addr += 4;
 			writew(be16_to_cpu(eaddrs[0]), filter_addr); filter_addr += 8;
 		}
 		eaddrs = (__be16 *)dev->dev_addr;
+		i = netdev_mc_count(dev) + 2;
 		while (i++ < 16) {
 			writew(be16_to_cpu(eaddrs[0]), filter_addr); filter_addr += 4;
 			writew(be16_to_cpu(eaddrs[1]), filter_addr); filter_addr += 4;
@@ -1824,8 +1824,7 @@ static void set_rx_mode(struct net_devic
 		__le16 mc_filter[32] __attribute__ ((aligned(sizeof(long))));	/* Multicast hash filter */
 
 		memset(mc_filter, 0, sizeof(mc_filter));
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-		     i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			/* The chip uses the upper 9 CRC bits
 			   as index into the hash table */
 			int bit_nr = ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 23;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/common.h linux-libre-2.6.34-gnu1/drivers/net/stmmac/common.h
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/common.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,132 +23,7 @@
 *******************************************************************************/
 
 #include "descs.h"
-#include <linux/io.h>
-
-/* *********************************************
-   DMA CRS Control and Status Register Mapping
- * *********************************************/
-#define DMA_BUS_MODE		0x00001000	/* Bus Mode */
-#define DMA_XMT_POLL_DEMAND	0x00001004	/* Transmit Poll Demand */
-#define DMA_RCV_POLL_DEMAND	0x00001008	/* Received Poll Demand */
-#define DMA_RCV_BASE_ADDR	0x0000100c	/* Receive List Base */
-#define DMA_TX_BASE_ADDR	0x00001010	/* Transmit List Base */
-#define DMA_STATUS		0x00001014	/* Status Register */
-#define DMA_CONTROL		0x00001018	/* Ctrl (Operational Mode) */
-#define DMA_INTR_ENA		0x0000101c	/* Interrupt Enable */
-#define DMA_MISSED_FRAME_CTR	0x00001020	/* Missed Frame Counter */
-#define DMA_CUR_TX_BUF_ADDR	0x00001050	/* Current Host Tx Buffer */
-#define DMA_CUR_RX_BUF_ADDR	0x00001054	/* Current Host Rx Buffer */
-
-/* ********************************
-   DMA Control register defines
- * ********************************/
-#define DMA_CONTROL_ST		0x00002000	/* Start/Stop Transmission */
-#define DMA_CONTROL_SR		0x00000002	/* Start/Stop Receive */
-
-/* **************************************
-   DMA Interrupt Enable register defines
- * **************************************/
-/**** NORMAL INTERRUPT ****/
-#define DMA_INTR_ENA_NIE 0x00010000	/* Normal Summary */
-#define DMA_INTR_ENA_TIE 0x00000001	/* Transmit Interrupt */
-#define DMA_INTR_ENA_TUE 0x00000004	/* Transmit Buffer Unavailable */
-#define DMA_INTR_ENA_RIE 0x00000040	/* Receive Interrupt */
-#define DMA_INTR_ENA_ERE 0x00004000	/* Early Receive */
-
-#define DMA_INTR_NORMAL	(DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \
-			DMA_INTR_ENA_TIE)
-
-/**** ABNORMAL INTERRUPT ****/
-#define DMA_INTR_ENA_AIE 0x00008000	/* Abnormal Summary */
-#define DMA_INTR_ENA_FBE 0x00002000	/* Fatal Bus Error */
-#define DMA_INTR_ENA_ETE 0x00000400	/* Early Transmit */
-#define DMA_INTR_ENA_RWE 0x00000200	/* Receive Watchdog */
-#define DMA_INTR_ENA_RSE 0x00000100	/* Receive Stopped */
-#define DMA_INTR_ENA_RUE 0x00000080	/* Receive Buffer Unavailable */
-#define DMA_INTR_ENA_UNE 0x00000020	/* Tx Underflow */
-#define DMA_INTR_ENA_OVE 0x00000010	/* Receive Overflow */
-#define DMA_INTR_ENA_TJE 0x00000008	/* Transmit Jabber */
-#define DMA_INTR_ENA_TSE 0x00000002	/* Transmit Stopped */
-
-#define DMA_INTR_ABNORMAL	(DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \
-				DMA_INTR_ENA_UNE)
-
-/* DMA default interrupt mask */
-#define DMA_INTR_DEFAULT_MASK	(DMA_INTR_NORMAL | DMA_INTR_ABNORMAL)
-
-/* ****************************
- *  DMA Status register defines
- * ****************************/
-#define DMA_STATUS_GPI		0x10000000	/* PMT interrupt */
-#define DMA_STATUS_GMI		0x08000000	/* MMC interrupt */
-#define DMA_STATUS_GLI		0x04000000	/* GMAC Line interface int. */
-#define DMA_STATUS_GMI		0x08000000
-#define DMA_STATUS_GLI		0x04000000
-#define DMA_STATUS_EB_MASK	0x00380000	/* Error Bits Mask */
-#define DMA_STATUS_EB_TX_ABORT	0x00080000	/* Error Bits - TX Abort */
-#define DMA_STATUS_EB_RX_ABORT	0x00100000	/* Error Bits - RX Abort */
-#define DMA_STATUS_TS_MASK	0x00700000	/* Transmit Process State */
-#define DMA_STATUS_TS_SHIFT	20
-#define DMA_STATUS_RS_MASK	0x000e0000	/* Receive Process State */
-#define DMA_STATUS_RS_SHIFT	17
-#define DMA_STATUS_NIS	0x00010000	/* Normal Interrupt Summary */
-#define DMA_STATUS_AIS	0x00008000	/* Abnormal Interrupt Summary */
-#define DMA_STATUS_ERI	0x00004000	/* Early Receive Interrupt */
-#define DMA_STATUS_FBI	0x00002000	/* Fatal Bus Error Interrupt */
-#define DMA_STATUS_ETI	0x00000400	/* Early Transmit Interrupt */
-#define DMA_STATUS_RWT	0x00000200	/* Receive Watchdog Timeout */
-#define DMA_STATUS_RPS	0x00000100	/* Receive Process Stopped */
-#define DMA_STATUS_RU	0x00000080	/* Receive Buffer Unavailable */
-#define DMA_STATUS_RI	0x00000040	/* Receive Interrupt */
-#define DMA_STATUS_UNF	0x00000020	/* Transmit Underflow */
-#define DMA_STATUS_OVF	0x00000010	/* Receive Overflow */
-#define DMA_STATUS_TJT	0x00000008	/* Transmit Jabber Timeout */
-#define DMA_STATUS_TU	0x00000004	/* Transmit Buffer Unavailable */
-#define DMA_STATUS_TPS	0x00000002	/* Transmit Process Stopped */
-#define DMA_STATUS_TI	0x00000001	/* Transmit Interrupt */
-
-/* Other defines */
-#define HASH_TABLE_SIZE 64
-#define PAUSE_TIME 0x200
-
-/* Flow Control defines */
-#define FLOW_OFF	0
-#define FLOW_RX		1
-#define FLOW_TX		2
-#define FLOW_AUTO	(FLOW_TX | FLOW_RX)
-
-/* DMA STORE-AND-FORWARD Operation Mode */
-#define SF_DMA_MODE 1
-
-#define HW_CSUM 1
-#define NO_HW_CSUM 0
-
-/* GMAC TX FIFO is 8K, Rx FIFO is 16K */
-#define BUF_SIZE_16KiB 16384
-#define BUF_SIZE_8KiB 8192
-#define BUF_SIZE_4KiB 4096
-#define BUF_SIZE_2KiB 2048
-
-/* Power Down and WOL */
-#define PMT_NOT_SUPPORTED 0
-#define PMT_SUPPORTED 1
-
-/* Common MAC defines */
-#define MAC_CTRL_REG		0x00000000	/* MAC Control */
-#define MAC_ENABLE_TX		0x00000008	/* Transmitter Enable */
-#define MAC_RNABLE_RX		0x00000004	/* Receiver Enable */
-
-/* MAC Management Counters register */
-#define MMC_CONTROL		0x00000100	/* MMC Control */
-#define MMC_HIGH_INTR		0x00000104	/* MMC High Interrupt */
-#define MMC_LOW_INTR		0x00000108	/* MMC Low Interrupt */
-#define MMC_HIGH_INTR_MASK	0x0000010c	/* MMC High Interrupt Mask */
-#define MMC_LOW_INTR_MASK	0x00000110	/* MMC Low Interrupt Mask */
-
-#define MMC_CONTROL_MAX_FRM_MASK	0x0003ff8	/* Maximum Frame Size */
-#define MMC_CONTROL_MAX_FRM_SHIFT	3
-#define MMC_CONTROL_MAX_FRAME		0x7FF
+#include <linux/netdevice.h>
 
 struct stmmac_extra_stats {
 	/* Transmit errors */
@@ -169,7 +44,7 @@ struct stmmac_extra_stats {
 	unsigned long rx_toolong;
 	unsigned long rx_collision;
 	unsigned long rx_crc;
-	unsigned long rx_lenght;
+	unsigned long rx_length;
 	unsigned long rx_mii;
 	unsigned long rx_multicast;
 	unsigned long rx_gmac_overflow;
@@ -198,66 +73,62 @@ struct stmmac_extra_stats {
 	unsigned long normal_irq_n;
 };
 
-/* GMAC core can compute the checksums in HW. */
-enum rx_frame_status {
+#define HASH_TABLE_SIZE 64
+#define PAUSE_TIME 0x200
+
+/* Flow Control defines */
+#define FLOW_OFF	0
+#define FLOW_RX		1
+#define FLOW_TX		2
+#define FLOW_AUTO	(FLOW_TX | FLOW_RX)
+
+#define SF_DMA_MODE 1 /* DMA STORE-AND-FORWARD Operation Mode */
+
+#define HW_CSUM 1
+#define NO_HW_CSUM 0
+enum rx_frame_status { /* IPC status */
 	good_frame = 0,
 	discard_frame = 1,
 	csum_none = 2,
 };
 
-static inline void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
-			 unsigned int high, unsigned int low)
-{
-	unsigned long data;
-
-	data = (addr[5] << 8) | addr[4];
-	writel(data, ioaddr + high);
-	data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
-	writel(data, ioaddr + low);
+enum tx_dma_irq_status {
+	tx_hard_error = 1,
+	tx_hard_error_bump_tc = 2,
+	handle_tx_rx = 3,
+};
 
-	return;
-}
+/* GMAC TX FIFO is 8K, Rx FIFO is 16K */
+#define BUF_SIZE_16KiB 16384
+#define BUF_SIZE_8KiB 8192
+#define BUF_SIZE_4KiB 4096
+#define BUF_SIZE_2KiB 2048
 
-static inline void stmmac_get_mac_addr(unsigned long ioaddr,
-				unsigned char *addr, unsigned int high,
-				unsigned int low)
-{
-	unsigned int hi_addr, lo_addr;
+/* Power Down and WOL */
+#define PMT_NOT_SUPPORTED 0
+#define PMT_SUPPORTED 1
 
-	/* Read the MAC address from the hardware */
-	hi_addr = readl(ioaddr + high);
-	lo_addr = readl(ioaddr + low);
+/* Common MAC defines */
+#define MAC_CTRL_REG		0x00000000	/* MAC Control */
+#define MAC_ENABLE_TX		0x00000008	/* Transmitter Enable */
+#define MAC_RNABLE_RX		0x00000004	/* Receiver Enable */
 
-	/* Extract the MAC address from the high and low words */
-	addr[0] = lo_addr & 0xff;
-	addr[1] = (lo_addr >> 8) & 0xff;
-	addr[2] = (lo_addr >> 16) & 0xff;
-	addr[3] = (lo_addr >> 24) & 0xff;
-	addr[4] = hi_addr & 0xff;
-	addr[5] = (hi_addr >> 8) & 0xff;
+/* MAC Management Counters register */
+#define MMC_CONTROL		0x00000100	/* MMC Control */
+#define MMC_HIGH_INTR		0x00000104	/* MMC High Interrupt */
+#define MMC_LOW_INTR		0x00000108	/* MMC Low Interrupt */
+#define MMC_HIGH_INTR_MASK	0x0000010c	/* MMC High Interrupt Mask */
+#define MMC_LOW_INTR_MASK	0x00000110	/* MMC Low Interrupt Mask */
 
-	return;
-}
+#define MMC_CONTROL_MAX_FRM_MASK	0x0003ff8	/* Maximum Frame Size */
+#define MMC_CONTROL_MAX_FRM_SHIFT	3
+#define MMC_CONTROL_MAX_FRAME		0x7FF
 
-struct stmmac_ops {
-	/* MAC core initialization */
-	void (*core_init) (unsigned long ioaddr) ____cacheline_aligned;
-	/* DMA core initialization */
-	int (*dma_init) (unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx);
-	/* Dump MAC registers */
-	void (*dump_mac_regs) (unsigned long ioaddr);
-	/* Dump DMA registers */
-	void (*dump_dma_regs) (unsigned long ioaddr);
-	/* Set tx/rx threshold in the csr6 register
-	 * An invalid value enables the store-and-forward mode */
-	void (*dma_mode) (unsigned long ioaddr, int txmode, int rxmode);
-	/* To track extra statistic (if supported) */
-	void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
-				   unsigned long ioaddr);
-	/* RX descriptor ring initialization */
+struct stmmac_desc_ops {
+	/* DMA RX descriptor ring initialization */
 	void (*init_rx_desc) (struct dma_desc *p, unsigned int ring_size,
-				int disable_rx_ic);
-	/* TX descriptor ring initialization */
+			      int disable_rx_ic);
+	/* DMA TX descriptor ring initialization */
 	void (*init_tx_desc) (struct dma_desc *p, unsigned int ring_size);
 
 	/* Invoked by the xmit function to prepare the tx descriptor */
@@ -281,7 +152,6 @@ struct stmmac_ops {
 	/* Get the buffer size from the descriptor */
 	int (*get_tx_len) (struct dma_desc *p);
 	/* Handle extra events on specific interrupts hw dependent */
-	void (*host_irq_status) (unsigned long ioaddr);
 	int (*get_rx_owner) (struct dma_desc *p);
 	void (*set_rx_owner) (struct dma_desc *p);
 	/* Get the receive frame size */
@@ -289,6 +159,37 @@ struct stmmac_ops {
 	/* Return the reception status looking at the RDES1 */
 	int (*rx_status) (void *data, struct stmmac_extra_stats *x,
 			  struct dma_desc *p);
+};
+
+struct stmmac_dma_ops {
+	/* DMA core initialization */
+	int (*init) (unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx);
+	/* Dump DMA registers */
+	void (*dump_regs) (unsigned long ioaddr);
+	/* Set tx/rx threshold in the csr6 register
+	 * An invalid value enables the store-and-forward mode */
+	void (*dma_mode) (unsigned long ioaddr, int txmode, int rxmode);
+	/* To track extra statistic (if supported) */
+	void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
+				   unsigned long ioaddr);
+	void (*enable_dma_transmission) (unsigned long ioaddr);
+	void (*enable_dma_irq) (unsigned long ioaddr);
+	void (*disable_dma_irq) (unsigned long ioaddr);
+	void (*start_tx) (unsigned long ioaddr);
+	void (*stop_tx) (unsigned long ioaddr);
+	void (*start_rx) (unsigned long ioaddr);
+	void (*stop_rx) (unsigned long ioaddr);
+	int (*dma_interrupt) (unsigned long ioaddr,
+			      struct stmmac_extra_stats *x);
+};
+
+struct stmmac_ops {
+	/* MAC core initialization */
+	void (*core_init) (unsigned long ioaddr) ____cacheline_aligned;
+	/* Dump MAC registers */
+	void (*dump_regs) (unsigned long ioaddr);
+	/* Handle extra events on specific interrupts hw dependent */
+	void (*host_irq_status) (unsigned long ioaddr);
 	/* Multicast filter setting */
 	void (*set_filter) (struct net_device *dev);
 	/* Flow control setting */
@@ -298,9 +199,9 @@ struct stmmac_ops {
 	void (*pmt) (unsigned long ioaddr, unsigned long mode);
 	/* Set/Get Unicast MAC addresses */
 	void (*set_umac_addr) (unsigned long ioaddr, unsigned char *addr,
-			     unsigned int reg_n);
+			       unsigned int reg_n);
 	void (*get_umac_addr) (unsigned long ioaddr, unsigned char *addr,
-			     unsigned int reg_n);
+			       unsigned int reg_n);
 };
 
 struct mac_link {
@@ -314,17 +215,19 @@ struct mii_regs {
 	unsigned int data;	/* MII Data */
 };
 
-struct hw_cap {
-	unsigned int version;	/* Core Version register (GMAC) */
-	unsigned int pmt;	/* Power-Down mode (GMAC) */
+struct mac_device_info {
+	struct stmmac_ops	*mac;
+	struct stmmac_desc_ops	*desc;
+	struct stmmac_dma_ops	*dma;
+	unsigned int pmt;	/* support Power-Down */
+	struct mii_regs mii;	/* MII register Addresses */
 	struct mac_link link;
-	struct mii_regs mii;
 };
 
-struct mac_device_info {
-	struct hw_cap hw;
-	struct stmmac_ops *ops;
-};
+struct mac_device_info *dwmac1000_setup(unsigned long addr);
+struct mac_device_info *dwmac100_setup(unsigned long addr);
 
-struct mac_device_info *gmac_setup(unsigned long addr);
-struct mac_device_info *mac100_setup(unsigned long addr);
+extern void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
+				unsigned int high, unsigned int low);
+extern void stmmac_get_mac_addr(unsigned long ioaddr, unsigned char *addr,
+				unsigned int high, unsigned int low);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/descs.h linux-libre-2.6.34-gnu1/drivers/net/stmmac/descs.h
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/descs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/descs.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /*******************************************************************************
-  Header File to describe the DMA descriptors
-  Use enhanced descriptors in case of GMAC Cores.
+  Header File to describe the DMA descriptors.
+  Enhanced descriptors have been in case of DWMAC1000 Cores.
 
   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.33-gnu1/drivers/net/stmmac/dwmac1000_core.c linux-libre-2.6.34-gnu1/drivers/net/stmmac/dwmac1000_core.c
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/dwmac1000_core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/dwmac1000_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,244 @@
+/*******************************************************************************
+  This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
+  DWC Ether MAC 10/100/1000 Universal version 3.41a  has been used for
+  developing this code.
+
+  This only implements the mac core functions for this chip.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  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".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/crc32.h>
+#include <linux/slab.h>
+#include "dwmac1000.h"
+
+static void dwmac1000_core_init(unsigned long ioaddr)
+{
+	u32 value = readl(ioaddr + GMAC_CONTROL);
+	value |= GMAC_CORE_INIT;
+	writel(value, ioaddr + GMAC_CONTROL);
+
+	/* STBus Bridge Configuration */
+	/*writel(0xc5608, ioaddr + 0x00007000);*/
+
+	/* Freeze MMC counters */
+	writel(0x8, ioaddr + GMAC_MMC_CTRL);
+	/* Mask GMAC interrupts */
+	writel(0x207, ioaddr + GMAC_INT_MASK);
+
+#ifdef STMMAC_VLAN_TAG_USED
+	/* Tag detection without filtering */
+	writel(0x0, ioaddr + GMAC_VLAN_TAG);
+#endif
+	return;
+}
+
+static void dwmac1000_dump_regs(unsigned long ioaddr)
+{
+	int i;
+	pr_info("\tDWMAC1000 regs (base addr = 0x%8x)\n", (unsigned int)ioaddr);
+
+	for (i = 0; i < 55; i++) {
+		int offset = i * 4;
+		pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
+			offset, readl(ioaddr + offset));
+	}
+	return;
+}
+
+static void dwmac1000_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
+				unsigned int reg_n)
+{
+	stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
+				GMAC_ADDR_LOW(reg_n));
+}
+
+static void dwmac1000_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
+				unsigned int reg_n)
+{
+	stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
+				GMAC_ADDR_LOW(reg_n));
+}
+
+static void dwmac1000_set_filter(struct net_device *dev)
+{
+	unsigned long ioaddr = dev->base_addr;
+	unsigned int value = 0;
+
+	DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
+	    __func__, netdev_mc_count(dev), netdev_uc_count(dev));
+
+	if (dev->flags & IFF_PROMISC)
+		value = GMAC_FRAME_FILTER_PR;
+	else if ((netdev_mc_count(dev) > HASH_TABLE_SIZE)
+		   || (dev->flags & IFF_ALLMULTI)) {
+		value = GMAC_FRAME_FILTER_PM;	/* pass all multi */
+		writel(0xffffffff, ioaddr + GMAC_HASH_HIGH);
+		writel(0xffffffff, ioaddr + GMAC_HASH_LOW);
+	} else if (!netdev_mc_empty(dev)) {
+		u32 mc_filter[2];
+		struct dev_mc_list *mclist;
+
+		/* Hash filter for multicast */
+		value = GMAC_FRAME_FILTER_HMC;
+
+		memset(mc_filter, 0, sizeof(mc_filter));
+		netdev_for_each_mc_addr(mclist, dev) {
+			/* The upper 6 bits of the calculated CRC are used to
+			   index the contens of the hash table */
+			int bit_nr =
+			    bitrev32(~crc32_le(~0, mclist->dmi_addr, 6)) >> 26;
+			/* The most significant bit determines the register to
+			 * use (H/L) while the other 5 bits determine the bit
+			 * within the register. */
+			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
+		}
+		writel(mc_filter[0], ioaddr + GMAC_HASH_LOW);
+		writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH);
+	}
+
+	/* Handle multiple unicast addresses (perfect filtering)*/
+	if (netdev_uc_count(dev) > GMAC_MAX_UNICAST_ADDRESSES)
+		/* Switch to promiscuous mode is more than 16 addrs
+		   are required */
+		value |= GMAC_FRAME_FILTER_PR;
+	else {
+		int reg = 1;
+		struct netdev_hw_addr *ha;
+
+		netdev_for_each_uc_addr(ha, dev) {
+			dwmac1000_set_umac_addr(ioaddr, ha->addr, reg);
+			reg++;
+		}
+	}
+
+#ifdef FRAME_FILTER_DEBUG
+	/* Enable Receive all mode (to debug filtering_fail errors) */
+	value |= GMAC_FRAME_FILTER_RA;
+#endif
+	writel(value, ioaddr + GMAC_FRAME_FILTER);
+
+	DBG(KERN_INFO "\tFrame Filter reg: 0x%08x\n\tHash regs: "
+	    "HI 0x%08x, LO 0x%08x\n", readl(ioaddr + GMAC_FRAME_FILTER),
+	    readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
+
+	return;
+}
+
+static void dwmac1000_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
+			   unsigned int fc, unsigned int pause_time)
+{
+	unsigned int flow = 0;
+
+	DBG(KERN_DEBUG "GMAC Flow-Control:\n");
+	if (fc & FLOW_RX) {
+		DBG(KERN_DEBUG "\tReceive Flow-Control ON\n");
+		flow |= GMAC_FLOW_CTRL_RFE;
+	}
+	if (fc & FLOW_TX) {
+		DBG(KERN_DEBUG "\tTransmit Flow-Control ON\n");
+		flow |= GMAC_FLOW_CTRL_TFE;
+	}
+
+	if (duplex) {
+		DBG(KERN_DEBUG "\tduplex mode: pause time: %d\n", pause_time);
+		flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
+	}
+
+	writel(flow, ioaddr + GMAC_FLOW_CTRL);
+	return;
+}
+
+static void dwmac1000_pmt(unsigned long ioaddr, unsigned long mode)
+{
+	unsigned int pmt = 0;
+
+	if (mode == WAKE_MAGIC) {
+		DBG(KERN_DEBUG "GMAC: WOL Magic frame\n");
+		pmt |= power_down | magic_pkt_en;
+	} else if (mode == WAKE_UCAST) {
+		DBG(KERN_DEBUG "GMAC: WOL on global unicast\n");
+		pmt |= global_unicast;
+	}
+
+	writel(pmt, ioaddr + GMAC_PMT);
+	return;
+}
+
+
+static void dwmac1000_irq_status(unsigned long ioaddr)
+{
+	u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
+
+	/* Not used events (e.g. MMC interrupts) are not handled. */
+	if ((intr_status & mmc_tx_irq))
+		DBG(KERN_DEBUG "GMAC: MMC tx interrupt: 0x%08x\n",
+		    readl(ioaddr + GMAC_MMC_TX_INTR));
+	if (unlikely(intr_status & mmc_rx_irq))
+		DBG(KERN_DEBUG "GMAC: MMC rx interrupt: 0x%08x\n",
+		    readl(ioaddr + GMAC_MMC_RX_INTR));
+	if (unlikely(intr_status & mmc_rx_csum_offload_irq))
+		DBG(KERN_DEBUG "GMAC: MMC rx csum offload: 0x%08x\n",
+		    readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
+	if (unlikely(intr_status & pmt_irq)) {
+		DBG(KERN_DEBUG "GMAC: received Magic frame\n");
+		/* clear the PMT bits 5 and 6 by reading the PMT
+		 * status register. */
+		readl(ioaddr + GMAC_PMT);
+	}
+
+	return;
+}
+
+struct stmmac_ops dwmac1000_ops = {
+	.core_init = dwmac1000_core_init,
+	.dump_regs = dwmac1000_dump_regs,
+	.host_irq_status = dwmac1000_irq_status,
+	.set_filter = dwmac1000_set_filter,
+	.flow_ctrl = dwmac1000_flow_ctrl,
+	.pmt = dwmac1000_pmt,
+	.set_umac_addr = dwmac1000_set_umac_addr,
+	.get_umac_addr = dwmac1000_get_umac_addr,
+};
+
+struct mac_device_info *dwmac1000_setup(unsigned long ioaddr)
+{
+	struct mac_device_info *mac;
+	u32 uid = readl(ioaddr + GMAC_VERSION);
+
+	pr_info("\tDWMAC1000 - user ID: 0x%x, Synopsys ID: 0x%x\n",
+		((uid & 0x0000ff00) >> 8), (uid & 0x000000ff));
+
+	mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
+
+	mac->mac = &dwmac1000_ops;
+	mac->desc = &dwmac1000_desc_ops;
+	mac->dma = &dwmac1000_dma_ops;
+
+	mac->pmt = PMT_SUPPORTED;
+	mac->link.port = GMAC_CONTROL_PS;
+	mac->link.duplex = GMAC_CONTROL_DM;
+	mac->link.speed = GMAC_CONTROL_FES;
+	mac->mii.addr = GMAC_MII_ADDR;
+	mac->mii.data = GMAC_MII_DATA;
+
+	return mac;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/dwmac1000_dma.c linux-libre-2.6.34-gnu1/drivers/net/stmmac/dwmac1000_dma.c
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/dwmac1000_dma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/dwmac1000_dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,474 @@
+/*******************************************************************************
+  This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
+  DWC Ether MAC 10/100/1000 Universal version 3.41a  has been used for
+  developing this code.
+
+  This contains the functions to handle the dma and descriptors.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  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".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include "dwmac1000.h"
+#include "dwmac_dma.h"
+
+static int dwmac1000_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
+			      u32 dma_rx)
+{
+	u32 value = readl(ioaddr + DMA_BUS_MODE);
+	/* DMA SW reset */
+	value |= DMA_BUS_MODE_SFT_RESET;
+	writel(value, ioaddr + DMA_BUS_MODE);
+	do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
+
+	value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL |
+	    ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
+	     (pbl << DMA_BUS_MODE_RPBL_SHIFT));
+
+#ifdef CONFIG_STMMAC_DA
+	value |= DMA_BUS_MODE_DA;	/* Rx has priority over tx */
+#endif
+	writel(value, ioaddr + DMA_BUS_MODE);
+
+	/* Mask interrupts by writing to CSR7 */
+	writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
+
+	/* The base address of the RX/TX descriptor lists must be written into
+	 * DMA CSR3 and CSR4, respectively. */
+	writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
+	writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
+
+	return 0;
+}
+
+/* Transmit FIFO flush operation */
+static void dwmac1000_flush_tx_fifo(unsigned long ioaddr)
+{
+	u32 csr6 = readl(ioaddr + DMA_CONTROL);
+	writel((csr6 | DMA_CONTROL_FTF), ioaddr + DMA_CONTROL);
+
+	do {} while ((readl(ioaddr + DMA_CONTROL) & DMA_CONTROL_FTF));
+}
+
+static void dwmac1000_dma_operation_mode(unsigned long ioaddr, int txmode,
+				    int rxmode)
+{
+	u32 csr6 = readl(ioaddr + DMA_CONTROL);
+
+	if (txmode == SF_DMA_MODE) {
+		DBG(KERN_DEBUG "GMAC: enabling TX store and forward mode\n");
+		/* Transmit COE type 2 cannot be done in cut-through mode. */
+		csr6 |= DMA_CONTROL_TSF;
+		/* Operating on second frame increase the performance
+		 * especially when transmit store-and-forward is used.*/
+		csr6 |= DMA_CONTROL_OSF;
+	} else {
+		DBG(KERN_DEBUG "GMAC: disabling TX store and forward mode"
+			      " (threshold = %d)\n", txmode);
+		csr6 &= ~DMA_CONTROL_TSF;
+		csr6 &= DMA_CONTROL_TC_TX_MASK;
+		/* Set the transmit threshold */
+		if (txmode <= 32)
+			csr6 |= DMA_CONTROL_TTC_32;
+		else if (txmode <= 64)
+			csr6 |= DMA_CONTROL_TTC_64;
+		else if (txmode <= 128)
+			csr6 |= DMA_CONTROL_TTC_128;
+		else if (txmode <= 192)
+			csr6 |= DMA_CONTROL_TTC_192;
+		else
+			csr6 |= DMA_CONTROL_TTC_256;
+	}
+
+	if (rxmode == SF_DMA_MODE) {
+		DBG(KERN_DEBUG "GMAC: enabling RX store and forward mode\n");
+		csr6 |= DMA_CONTROL_RSF;
+	} else {
+		DBG(KERN_DEBUG "GMAC: disabling RX store and forward mode"
+			      " (threshold = %d)\n", rxmode);
+		csr6 &= ~DMA_CONTROL_RSF;
+		csr6 &= DMA_CONTROL_TC_RX_MASK;
+		if (rxmode <= 32)
+			csr6 |= DMA_CONTROL_RTC_32;
+		else if (rxmode <= 64)
+			csr6 |= DMA_CONTROL_RTC_64;
+		else if (rxmode <= 96)
+			csr6 |= DMA_CONTROL_RTC_96;
+		else
+			csr6 |= DMA_CONTROL_RTC_128;
+	}
+
+	writel(csr6, ioaddr + DMA_CONTROL);
+	return;
+}
+
+/* Not yet implemented --- no RMON module */
+static void dwmac1000_dma_diagnostic_fr(void *data,
+		  struct stmmac_extra_stats *x, unsigned long ioaddr)
+{
+	return;
+}
+
+static void dwmac1000_dump_dma_regs(unsigned long ioaddr)
+{
+	int i;
+	pr_info(" DMA registers\n");
+	for (i = 0; i < 22; i++) {
+		if ((i < 9) || (i > 17)) {
+			int offset = i * 4;
+			pr_err("\t Reg No. %d (offset 0x%x): 0x%08x\n", i,
+			       (DMA_BUS_MODE + offset),
+			       readl(ioaddr + DMA_BUS_MODE + offset));
+		}
+	}
+	return;
+}
+
+static int dwmac1000_get_tx_frame_status(void *data,
+				struct stmmac_extra_stats *x,
+				struct dma_desc *p, unsigned long ioaddr)
+{
+	int ret = 0;
+	struct net_device_stats *stats = (struct net_device_stats *)data;
+
+	if (unlikely(p->des01.etx.error_summary)) {
+		DBG(KERN_ERR "GMAC TX error... 0x%08x\n", p->des01.etx);
+		if (unlikely(p->des01.etx.jabber_timeout)) {
+			DBG(KERN_ERR "\tjabber_timeout error\n");
+			x->tx_jabber++;
+		}
+
+		if (unlikely(p->des01.etx.frame_flushed)) {
+			DBG(KERN_ERR "\tframe_flushed error\n");
+			x->tx_frame_flushed++;
+			dwmac1000_flush_tx_fifo(ioaddr);
+		}
+
+		if (unlikely(p->des01.etx.loss_carrier)) {
+			DBG(KERN_ERR "\tloss_carrier error\n");
+			x->tx_losscarrier++;
+			stats->tx_carrier_errors++;
+		}
+		if (unlikely(p->des01.etx.no_carrier)) {
+			DBG(KERN_ERR "\tno_carrier error\n");
+			x->tx_carrier++;
+			stats->tx_carrier_errors++;
+		}
+		if (unlikely(p->des01.etx.late_collision)) {
+			DBG(KERN_ERR "\tlate_collision error\n");
+			stats->collisions += p->des01.etx.collision_count;
+		}
+		if (unlikely(p->des01.etx.excessive_collisions)) {
+			DBG(KERN_ERR "\texcessive_collisions\n");
+			stats->collisions += p->des01.etx.collision_count;
+		}
+		if (unlikely(p->des01.etx.excessive_deferral)) {
+			DBG(KERN_INFO "\texcessive tx_deferral\n");
+			x->tx_deferred++;
+		}
+
+		if (unlikely(p->des01.etx.underflow_error)) {
+			DBG(KERN_ERR "\tunderflow error\n");
+			dwmac1000_flush_tx_fifo(ioaddr);
+			x->tx_underflow++;
+		}
+
+		if (unlikely(p->des01.etx.ip_header_error)) {
+			DBG(KERN_ERR "\tTX IP header csum error\n");
+			x->tx_ip_header_error++;
+		}
+
+		if (unlikely(p->des01.etx.payload_error)) {
+			DBG(KERN_ERR "\tAddr/Payload csum error\n");
+			x->tx_payload_error++;
+			dwmac1000_flush_tx_fifo(ioaddr);
+		}
+
+		ret = -1;
+	}
+
+	if (unlikely(p->des01.etx.deferred)) {
+		DBG(KERN_INFO "GMAC TX status: tx deferred\n");
+		x->tx_deferred++;
+	}
+#ifdef STMMAC_VLAN_TAG_USED
+	if (p->des01.etx.vlan_frame) {
+		DBG(KERN_INFO "GMAC TX status: VLAN frame\n");
+		x->tx_vlan++;
+	}
+#endif
+
+	return ret;
+}
+
+static int dwmac1000_get_tx_len(struct dma_desc *p)
+{
+	return p->des01.etx.buffer1_size;
+}
+
+static int dwmac1000_coe_rdes0(int ipc_err, int type, int payload_err)
+{
+	int ret = good_frame;
+	u32 status = (type << 2 | ipc_err << 1 | payload_err) & 0x7;
+
+	/* bits 5 7 0 | Frame status
+	 * ----------------------------------------------------------
+	 *      0 0 0 | IEEE 802.3 Type frame (length < 1536 octects)
+	 *      1 0 0 | IPv4/6 No CSUM errorS.
+	 *      1 0 1 | IPv4/6 CSUM PAYLOAD error
+	 *      1 1 0 | IPv4/6 CSUM IP HR error
+	 *      1 1 1 | IPv4/6 IP PAYLOAD AND HEADER errorS
+	 *      0 0 1 | IPv4/6 unsupported IP PAYLOAD
+	 *      0 1 1 | COE bypassed.. no IPv4/6 frame
+	 *      0 1 0 | Reserved.
+	 */
+	if (status == 0x0) {
+		DBG(KERN_INFO "RX Des0 status: IEEE 802.3 Type frame.\n");
+		ret = good_frame;
+	} else if (status == 0x4) {
+		DBG(KERN_INFO "RX Des0 status: IPv4/6 No CSUM errorS.\n");
+		ret = good_frame;
+	} else if (status == 0x5) {
+		DBG(KERN_ERR "RX Des0 status: IPv4/6 Payload Error.\n");
+		ret = csum_none;
+	} else if (status == 0x6) {
+		DBG(KERN_ERR "RX Des0 status: IPv4/6 Header Error.\n");
+		ret = csum_none;
+	} else if (status == 0x7) {
+		DBG(KERN_ERR
+		    "RX Des0 status: IPv4/6 Header and Payload Error.\n");
+		ret = csum_none;
+	} else if (status == 0x1) {
+		DBG(KERN_ERR
+		    "RX Des0 status: IPv4/6 unsupported IP PAYLOAD.\n");
+		ret = discard_frame;
+	} else if (status == 0x3) {
+		DBG(KERN_ERR "RX Des0 status: No IPv4, IPv6 frame.\n");
+		ret = discard_frame;
+	}
+	return ret;
+}
+
+static int dwmac1000_get_rx_frame_status(void *data,
+			struct stmmac_extra_stats *x, struct dma_desc *p)
+{
+	int ret = good_frame;
+	struct net_device_stats *stats = (struct net_device_stats *)data;
+
+	if (unlikely(p->des01.erx.error_summary)) {
+		DBG(KERN_ERR "GMAC RX Error Summary... 0x%08x\n", p->des01.erx);
+		if (unlikely(p->des01.erx.descriptor_error)) {
+			DBG(KERN_ERR "\tdescriptor error\n");
+			x->rx_desc++;
+			stats->rx_length_errors++;
+		}
+		if (unlikely(p->des01.erx.overflow_error)) {
+			DBG(KERN_ERR "\toverflow error\n");
+			x->rx_gmac_overflow++;
+		}
+
+		if (unlikely(p->des01.erx.ipc_csum_error))
+			DBG(KERN_ERR "\tIPC Csum Error/Giant frame\n");
+
+		if (unlikely(p->des01.erx.late_collision)) {
+			DBG(KERN_ERR "\tlate_collision error\n");
+			stats->collisions++;
+			stats->collisions++;
+		}
+		if (unlikely(p->des01.erx.receive_watchdog)) {
+			DBG(KERN_ERR "\treceive_watchdog error\n");
+			x->rx_watchdog++;
+		}
+		if (unlikely(p->des01.erx.error_gmii)) {
+			DBG(KERN_ERR "\tReceive Error\n");
+			x->rx_mii++;
+		}
+		if (unlikely(p->des01.erx.crc_error)) {
+			DBG(KERN_ERR "\tCRC error\n");
+			x->rx_crc++;
+			stats->rx_crc_errors++;
+		}
+		ret = discard_frame;
+	}
+
+	/* After a payload csum error, the ES bit is set.
+	 * It doesn't match with the information reported into the databook.
+	 * At any rate, we need to understand if the CSUM hw computation is ok
+	 * and report this info to the upper layers. */
+	ret = dwmac1000_coe_rdes0(p->des01.erx.ipc_csum_error,
+		p->des01.erx.frame_type, p->des01.erx.payload_csum_error);
+
+	if (unlikely(p->des01.erx.dribbling)) {
+		DBG(KERN_ERR "GMAC RX: dribbling error\n");
+		ret = discard_frame;
+	}
+	if (unlikely(p->des01.erx.sa_filter_fail)) {
+		DBG(KERN_ERR "GMAC RX : Source Address filter fail\n");
+		x->sa_rx_filter_fail++;
+		ret = discard_frame;
+	}
+	if (unlikely(p->des01.erx.da_filter_fail)) {
+		DBG(KERN_ERR "GMAC RX : Destination Address filter fail\n");
+		x->da_rx_filter_fail++;
+		ret = discard_frame;
+	}
+	if (unlikely(p->des01.erx.length_error)) {
+		DBG(KERN_ERR "GMAC RX: length_error error\n");
+		x->rx_length++;
+		ret = discard_frame;
+	}
+#ifdef STMMAC_VLAN_TAG_USED
+	if (p->des01.erx.vlan_tag) {
+		DBG(KERN_INFO "GMAC RX: VLAN frame tagged\n");
+		x->rx_vlan++;
+	}
+#endif
+	return ret;
+}
+
+static void dwmac1000_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
+				int disable_rx_ic)
+{
+	int i;
+	for (i = 0; i < ring_size; i++) {
+		p->des01.erx.own = 1;
+		p->des01.erx.buffer1_size = BUF_SIZE_8KiB - 1;
+		/* To support jumbo frames */
+		p->des01.erx.buffer2_size = BUF_SIZE_8KiB - 1;
+		if (i == ring_size - 1)
+			p->des01.erx.end_ring = 1;
+		if (disable_rx_ic)
+			p->des01.erx.disable_ic = 1;
+		p++;
+	}
+	return;
+}
+
+static void dwmac1000_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
+{
+	int i;
+
+	for (i = 0; i < ring_size; i++) {
+		p->des01.etx.own = 0;
+		if (i == ring_size - 1)
+			p->des01.etx.end_ring = 1;
+		p++;
+	}
+
+	return;
+}
+
+static int dwmac1000_get_tx_owner(struct dma_desc *p)
+{
+	return p->des01.etx.own;
+}
+
+static int dwmac1000_get_rx_owner(struct dma_desc *p)
+{
+	return p->des01.erx.own;
+}
+
+static void dwmac1000_set_tx_owner(struct dma_desc *p)
+{
+	p->des01.etx.own = 1;
+}
+
+static void dwmac1000_set_rx_owner(struct dma_desc *p)
+{
+	p->des01.erx.own = 1;
+}
+
+static int dwmac1000_get_tx_ls(struct dma_desc *p)
+{
+	return p->des01.etx.last_segment;
+}
+
+static void dwmac1000_release_tx_desc(struct dma_desc *p)
+{
+	int ter = p->des01.etx.end_ring;
+
+	memset(p, 0, sizeof(struct dma_desc));
+	p->des01.etx.end_ring = ter;
+
+	return;
+}
+
+static void dwmac1000_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
+				 int csum_flag)
+{
+	p->des01.etx.first_segment = is_fs;
+	if (unlikely(len > BUF_SIZE_4KiB)) {
+		p->des01.etx.buffer1_size = BUF_SIZE_4KiB;
+		p->des01.etx.buffer2_size = len - BUF_SIZE_4KiB;
+	} else {
+		p->des01.etx.buffer1_size = len;
+	}
+	if (likely(csum_flag))
+		p->des01.etx.checksum_insertion = cic_full;
+}
+
+static void dwmac1000_clear_tx_ic(struct dma_desc *p)
+{
+	p->des01.etx.interrupt = 0;
+}
+
+static void dwmac1000_close_tx_desc(struct dma_desc *p)
+{
+	p->des01.etx.last_segment = 1;
+	p->des01.etx.interrupt = 1;
+}
+
+static int dwmac1000_get_rx_frame_len(struct dma_desc *p)
+{
+	return p->des01.erx.frame_length;
+}
+
+struct stmmac_dma_ops dwmac1000_dma_ops = {
+	.init = dwmac1000_dma_init,
+	.dump_regs = dwmac1000_dump_dma_regs,
+	.dma_mode = dwmac1000_dma_operation_mode,
+	.dma_diagnostic_fr = dwmac1000_dma_diagnostic_fr,
+	.enable_dma_transmission = dwmac_enable_dma_transmission,
+	.enable_dma_irq = dwmac_enable_dma_irq,
+	.disable_dma_irq = dwmac_disable_dma_irq,
+	.start_tx = dwmac_dma_start_tx,
+	.stop_tx = dwmac_dma_stop_tx,
+	.start_rx = dwmac_dma_start_rx,
+	.stop_rx = dwmac_dma_stop_rx,
+	.dma_interrupt = dwmac_dma_interrupt,
+};
+
+struct stmmac_desc_ops dwmac1000_desc_ops = {
+	.tx_status = dwmac1000_get_tx_frame_status,
+	.rx_status = dwmac1000_get_rx_frame_status,
+	.get_tx_len = dwmac1000_get_tx_len,
+	.init_rx_desc = dwmac1000_init_rx_desc,
+	.init_tx_desc = dwmac1000_init_tx_desc,
+	.get_tx_owner = dwmac1000_get_tx_owner,
+	.get_rx_owner = dwmac1000_get_rx_owner,
+	.release_tx_desc = dwmac1000_release_tx_desc,
+	.prepare_tx_desc = dwmac1000_prepare_tx_desc,
+	.clear_tx_ic = dwmac1000_clear_tx_ic,
+	.close_tx_desc = dwmac1000_close_tx_desc,
+	.get_tx_ls = dwmac1000_get_tx_ls,
+	.set_tx_owner = dwmac1000_set_tx_owner,
+	.set_rx_owner = dwmac1000_set_rx_owner,
+	.get_rx_frame_len = dwmac1000_get_rx_frame_len,
+};
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/dwmac1000.h linux-libre-2.6.34-gnu1/drivers/net/stmmac/dwmac1000.h
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/dwmac1000.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/dwmac1000.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,220 @@
+/*******************************************************************************
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  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".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/phy.h>
+#include "common.h"
+
+#define GMAC_CONTROL		0x00000000	/* Configuration */
+#define GMAC_FRAME_FILTER	0x00000004	/* Frame Filter */
+#define GMAC_HASH_HIGH		0x00000008	/* Multicast Hash Table High */
+#define GMAC_HASH_LOW		0x0000000c	/* Multicast Hash Table Low */
+#define GMAC_MII_ADDR		0x00000010	/* MII Address */
+#define GMAC_MII_DATA		0x00000014	/* MII Data */
+#define GMAC_FLOW_CTRL		0x00000018	/* Flow Control */
+#define GMAC_VLAN_TAG		0x0000001c	/* VLAN Tag */
+#define GMAC_VERSION		0x00000020	/* GMAC CORE Version */
+#define GMAC_WAKEUP_FILTER	0x00000028	/* Wake-up Frame Filter */
+
+#define GMAC_INT_STATUS		0x00000038	/* interrupt status register */
+enum dwmac1000_irq_status {
+	time_stamp_irq = 0x0200,
+	mmc_rx_csum_offload_irq = 0x0080,
+	mmc_tx_irq = 0x0040,
+	mmc_rx_irq = 0x0020,
+	mmc_irq = 0x0010,
+	pmt_irq = 0x0008,
+	pcs_ane_irq = 0x0004,
+	pcs_link_irq = 0x0002,
+	rgmii_irq = 0x0001,
+};
+#define GMAC_INT_MASK		0x0000003c	/* interrupt mask register */
+
+/* PMT Control and Status */
+#define GMAC_PMT		0x0000002c
+enum power_event {
+	pointer_reset = 0x80000000,
+	global_unicast = 0x00000200,
+	wake_up_rx_frame = 0x00000040,
+	magic_frame = 0x00000020,
+	wake_up_frame_en = 0x00000004,
+	magic_pkt_en = 0x00000002,
+	power_down = 0x00000001,
+};
+
+/* GMAC HW ADDR regs */
+#define GMAC_ADDR_HIGH(reg)		(0x00000040+(reg * 8))
+#define GMAC_ADDR_LOW(reg)		(0x00000044+(reg * 8))
+#define GMAC_MAX_UNICAST_ADDRESSES	16
+
+#define GMAC_AN_CTRL	0x000000c0	/* AN control */
+#define GMAC_AN_STATUS	0x000000c4	/* AN status */
+#define GMAC_ANE_ADV	0x000000c8	/* Auto-Neg. Advertisement */
+#define GMAC_ANE_LINK	0x000000cc	/* Auto-Neg. link partener ability */
+#define GMAC_ANE_EXP	0x000000d0	/* ANE expansion */
+#define GMAC_TBI	0x000000d4	/* TBI extend status */
+#define GMAC_GMII_STATUS 0x000000d8	/* S/R-GMII status */
+
+/* GMAC Configuration defines */
+#define GMAC_CONTROL_TC	0x01000000	/* Transmit Conf. in RGMII/SGMII */
+#define GMAC_CONTROL_WD	0x00800000	/* Disable Watchdog on receive */
+#define GMAC_CONTROL_JD	0x00400000	/* Jabber disable */
+#define GMAC_CONTROL_BE	0x00200000	/* Frame Burst Enable */
+#define GMAC_CONTROL_JE	0x00100000	/* Jumbo frame */
+enum inter_frame_gap {
+	GMAC_CONTROL_IFG_88 = 0x00040000,
+	GMAC_CONTROL_IFG_80 = 0x00020000,
+	GMAC_CONTROL_IFG_40 = 0x000e0000,
+};
+#define GMAC_CONTROL_DCRS	0x00010000 /* Disable carrier sense during tx */
+#define GMAC_CONTROL_PS		0x00008000 /* Port Select 0:GMI 1:MII */
+#define GMAC_CONTROL_FES	0x00004000 /* Speed 0:10 1:100 */
+#define GMAC_CONTROL_DO		0x00002000 /* Disable Rx Own */
+#define GMAC_CONTROL_LM		0x00001000 /* Loop-back mode */
+#define GMAC_CONTROL_DM		0x00000800 /* Duplex Mode */
+#define GMAC_CONTROL_IPC	0x00000400 /* Checksum Offload */
+#define GMAC_CONTROL_DR		0x00000200 /* Disable Retry */
+#define GMAC_CONTROL_LUD	0x00000100 /* Link up/down */
+#define GMAC_CONTROL_ACS	0x00000080 /* Automatic Pad Stripping */
+#define GMAC_CONTROL_DC		0x00000010 /* Deferral Check */
+#define GMAC_CONTROL_TE		0x00000008 /* Transmitter Enable */
+#define GMAC_CONTROL_RE		0x00000004 /* Receiver Enable */
+
+#define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \
+			GMAC_CONTROL_IPC | GMAC_CONTROL_JE | GMAC_CONTROL_BE)
+
+/* GMAC Frame Filter defines */
+#define GMAC_FRAME_FILTER_PR	0x00000001	/* Promiscuous Mode */
+#define GMAC_FRAME_FILTER_HUC	0x00000002	/* Hash Unicast */
+#define GMAC_FRAME_FILTER_HMC	0x00000004	/* Hash Multicast */
+#define GMAC_FRAME_FILTER_DAIF	0x00000008	/* DA Inverse Filtering */
+#define GMAC_FRAME_FILTER_PM	0x00000010	/* Pass all multicast */
+#define GMAC_FRAME_FILTER_DBF	0x00000020	/* Disable Broadcast frames */
+#define GMAC_FRAME_FILTER_SAIF	0x00000100	/* Inverse Filtering */
+#define GMAC_FRAME_FILTER_SAF	0x00000200	/* Source Address Filter */
+#define GMAC_FRAME_FILTER_HPF	0x00000400	/* Hash or perfect Filter */
+#define GMAC_FRAME_FILTER_RA	0x80000000	/* Receive all mode */
+/* GMII ADDR  defines */
+#define GMAC_MII_ADDR_WRITE	0x00000002	/* MII Write */
+#define GMAC_MII_ADDR_BUSY	0x00000001	/* MII Busy */
+/* GMAC FLOW CTRL defines */
+#define GMAC_FLOW_CTRL_PT_MASK	0xffff0000	/* Pause Time Mask */
+#define GMAC_FLOW_CTRL_PT_SHIFT	16
+#define GMAC_FLOW_CTRL_RFE	0x00000004	/* Rx Flow Control Enable */
+#define GMAC_FLOW_CTRL_TFE	0x00000002	/* Tx Flow Control Enable */
+#define GMAC_FLOW_CTRL_FCB_BPA	0x00000001	/* Flow Control Busy ... */
+
+/*--- DMA BLOCK defines ---*/
+/* DMA Bus Mode register defines */
+#define DMA_BUS_MODE_SFT_RESET	0x00000001	/* Software Reset */
+#define DMA_BUS_MODE_DA		0x00000002	/* Arbitration scheme */
+#define DMA_BUS_MODE_DSL_MASK	0x0000007c	/* Descriptor Skip Length */
+#define DMA_BUS_MODE_DSL_SHIFT	2	/*   (in DWORDS)      */
+/* Programmable burst length (passed thorugh platform)*/
+#define DMA_BUS_MODE_PBL_MASK	0x00003f00	/* Programmable Burst Len */
+#define DMA_BUS_MODE_PBL_SHIFT	8
+
+enum rx_tx_priority_ratio {
+	double_ratio = 0x00004000,	/*2:1 */
+	triple_ratio = 0x00008000,	/*3:1 */
+	quadruple_ratio = 0x0000c000,	/*4:1 */
+};
+
+#define DMA_BUS_MODE_FB		0x00010000	/* Fixed burst */
+#define DMA_BUS_MODE_RPBL_MASK	0x003e0000	/* Rx-Programmable Burst Len */
+#define DMA_BUS_MODE_RPBL_SHIFT	17
+#define DMA_BUS_MODE_USP	0x00800000
+#define DMA_BUS_MODE_4PBL	0x01000000
+#define DMA_BUS_MODE_AAL	0x02000000
+
+/* DMA CRS Control and Status Register Mapping */
+#define DMA_HOST_TX_DESC	  0x00001048	/* Current Host Tx descriptor */
+#define DMA_HOST_RX_DESC	  0x0000104c	/* Current Host Rx descriptor */
+/*  DMA Bus Mode register defines */
+#define DMA_BUS_PR_RATIO_MASK	  0x0000c000	/* Rx/Tx priority ratio */
+#define DMA_BUS_PR_RATIO_SHIFT	  14
+#define DMA_BUS_FB	  	  0x00010000	/* Fixed Burst */
+
+/* DMA operation mode defines (start/stop tx/rx are placed in common header)*/
+#define DMA_CONTROL_DT		0x04000000 /* Disable Drop TCP/IP csum error */
+#define DMA_CONTROL_RSF		0x02000000 /* Receive Store and Forward */
+#define DMA_CONTROL_DFF		0x01000000 /* Disaable flushing */
+/* Threshold for Activating the FC */
+enum rfa {
+	act_full_minus_1 = 0x00800000,
+	act_full_minus_2 = 0x00800200,
+	act_full_minus_3 = 0x00800400,
+	act_full_minus_4 = 0x00800600,
+};
+/* Threshold for Deactivating the FC */
+enum rfd {
+	deac_full_minus_1 = 0x00400000,
+	deac_full_minus_2 = 0x00400800,
+	deac_full_minus_3 = 0x00401000,
+	deac_full_minus_4 = 0x00401800,
+};
+#define DMA_CONTROL_TSF		0x00200000 /* Transmit  Store and Forward */
+#define DMA_CONTROL_FTF		0x00100000 /* Flush transmit FIFO */
+
+enum ttc_control {
+	DMA_CONTROL_TTC_64 = 0x00000000,
+	DMA_CONTROL_TTC_128 = 0x00004000,
+	DMA_CONTROL_TTC_192 = 0x00008000,
+	DMA_CONTROL_TTC_256 = 0x0000c000,
+	DMA_CONTROL_TTC_40 = 0x00010000,
+	DMA_CONTROL_TTC_32 = 0x00014000,
+	DMA_CONTROL_TTC_24 = 0x00018000,
+	DMA_CONTROL_TTC_16 = 0x0001c000,
+};
+#define DMA_CONTROL_TC_TX_MASK	0xfffe3fff
+
+#define DMA_CONTROL_EFC		0x00000100
+#define DMA_CONTROL_FEF		0x00000080
+#define DMA_CONTROL_FUF		0x00000040
+
+enum rtc_control {
+	DMA_CONTROL_RTC_64 = 0x00000000,
+	DMA_CONTROL_RTC_32 = 0x00000008,
+	DMA_CONTROL_RTC_96 = 0x00000010,
+	DMA_CONTROL_RTC_128 = 0x00000018,
+};
+#define DMA_CONTROL_TC_RX_MASK	0xffffffe7
+
+#define DMA_CONTROL_OSF	0x00000004	/* Operate on second frame */
+
+/* MMC registers offset */
+#define GMAC_MMC_CTRL      0x100
+#define GMAC_MMC_RX_INTR   0x104
+#define GMAC_MMC_TX_INTR   0x108
+#define GMAC_MMC_RX_CSUM_OFFLOAD   0x208
+
+#undef DWMAC1000_DEBUG
+/* #define DWMAC1000__DEBUG */
+#undef FRAME_FILTER_DEBUG
+/* #define FRAME_FILTER_DEBUG */
+#ifdef DWMAC1000__DEBUG
+#define DBG(fmt, args...)  printk(fmt, ## args)
+#else
+#define DBG(fmt, args...)  do { } while (0)
+#endif
+
+extern struct stmmac_dma_ops dwmac1000_dma_ops;
+extern struct stmmac_desc_ops dwmac1000_desc_ops;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/dwmac100.c linux-libre-2.6.34-gnu1/drivers/net/stmmac/dwmac100.c
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/dwmac100.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/dwmac100.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,538 @@
+/*******************************************************************************
+  This is the driver for the MAC 10/100 on-chip Ethernet controller
+  currently tested on all the ST boards based on STb7109 and stx7200 SoCs.
+
+  DWC Ether MAC 10/100 Universal version 4.0 has been used for developing
+  this code.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  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".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/slab.h>
+
+#include "common.h"
+#include "dwmac100.h"
+#include "dwmac_dma.h"
+
+#undef DWMAC100_DEBUG
+/*#define DWMAC100_DEBUG*/
+#ifdef DWMAC100_DEBUG
+#define DBG(fmt, args...)  printk(fmt, ## args)
+#else
+#define DBG(fmt, args...)  do { } while (0)
+#endif
+
+static void dwmac100_core_init(unsigned long ioaddr)
+{
+	u32 value = readl(ioaddr + MAC_CONTROL);
+
+	writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
+
+#ifdef STMMAC_VLAN_TAG_USED
+	writel(ETH_P_8021Q, ioaddr + MAC_VLAN1);
+#endif
+	return;
+}
+
+static void dwmac100_dump_mac_regs(unsigned long ioaddr)
+{
+	pr_info("\t----------------------------------------------\n"
+		"\t  DWMAC 100 CSR (base addr = 0x%8x)\n"
+		"\t----------------------------------------------\n",
+		(unsigned int)ioaddr);
+	pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
+		readl(ioaddr + MAC_CONTROL));
+	pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
+		readl(ioaddr + MAC_ADDR_HIGH));
+	pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW,
+		readl(ioaddr + MAC_ADDR_LOW));
+	pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n",
+		MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH));
+	pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n",
+		MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW));
+	pr_info("\tflow control (offset 0x%x): 0x%08x\n",
+		MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL));
+	pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1,
+		readl(ioaddr + MAC_VLAN1));
+	pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2,
+		readl(ioaddr + MAC_VLAN2));
+	pr_info("\n\tMAC management counter registers\n");
+	pr_info("\t MMC crtl (offset 0x%x): 0x%08x\n",
+		MMC_CONTROL, readl(ioaddr + MMC_CONTROL));
+	pr_info("\t MMC High Interrupt (offset 0x%x): 0x%08x\n",
+		MMC_HIGH_INTR, readl(ioaddr + MMC_HIGH_INTR));
+	pr_info("\t MMC Low Interrupt (offset 0x%x): 0x%08x\n",
+		MMC_LOW_INTR, readl(ioaddr + MMC_LOW_INTR));
+	pr_info("\t MMC High Interrupt Mask (offset 0x%x): 0x%08x\n",
+		MMC_HIGH_INTR_MASK, readl(ioaddr + MMC_HIGH_INTR_MASK));
+	pr_info("\t MMC Low Interrupt Mask (offset 0x%x): 0x%08x\n",
+		MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
+	return;
+}
+
+static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
+			   u32 dma_rx)
+{
+	u32 value = readl(ioaddr + DMA_BUS_MODE);
+	/* DMA SW reset */
+	value |= DMA_BUS_MODE_SFT_RESET;
+	writel(value, ioaddr + DMA_BUS_MODE);
+	do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
+
+	/* Enable Application Access by writing to DMA CSR0 */
+	writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
+	       ioaddr + DMA_BUS_MODE);
+
+	/* Mask interrupts by writing to CSR7 */
+	writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
+
+	/* The base address of the RX/TX descriptor lists must be written into
+	 * DMA CSR3 and CSR4, respectively. */
+	writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
+	writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
+
+	return 0;
+}
+
+/* Store and Forward capability is not used at all..
+ * The transmit threshold can be programmed by
+ * setting the TTC bits in the DMA control register.*/
+static void dwmac100_dma_operation_mode(unsigned long ioaddr, int txmode,
+				      int rxmode)
+{
+	u32 csr6 = readl(ioaddr + DMA_CONTROL);
+
+	if (txmode <= 32)
+		csr6 |= DMA_CONTROL_TTC_32;
+	else if (txmode <= 64)
+		csr6 |= DMA_CONTROL_TTC_64;
+	else
+		csr6 |= DMA_CONTROL_TTC_128;
+
+	writel(csr6, ioaddr + DMA_CONTROL);
+
+	return;
+}
+
+static void dwmac100_dump_dma_regs(unsigned long ioaddr)
+{
+	int i;
+
+	DBG(KERN_DEBUG "DWMAC 100 DMA CSR \n");
+	for (i = 0; i < 9; i++)
+		pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i,
+		       (DMA_BUS_MODE + i * 4),
+		       readl(ioaddr + DMA_BUS_MODE + i * 4));
+	DBG(KERN_DEBUG "\t CSR20 (offset 0x%x): 0x%08x\n",
+	    DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR));
+	DBG(KERN_DEBUG "\t CSR21 (offset 0x%x): 0x%08x\n",
+	    DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR));
+	return;
+}
+
+/* DMA controller has two counters to track the number of
+ * the receive missed frames. */
+static void dwmac100_dma_diagnostic_fr(void *data,
+				     struct stmmac_extra_stats *x,
+				     unsigned long ioaddr)
+{
+	struct net_device_stats *stats = (struct net_device_stats *)data;
+	u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
+
+	if (unlikely(csr8)) {
+		if (csr8 & DMA_MISSED_FRAME_OVE) {
+			stats->rx_over_errors += 0x800;
+			x->rx_overflow_cntr += 0x800;
+		} else {
+			unsigned int ove_cntr;
+			ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17);
+			stats->rx_over_errors += ove_cntr;
+			x->rx_overflow_cntr += ove_cntr;
+		}
+
+		if (csr8 & DMA_MISSED_FRAME_OVE_M) {
+			stats->rx_missed_errors += 0xffff;
+			x->rx_missed_cntr += 0xffff;
+		} else {
+			unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR);
+			stats->rx_missed_errors += miss_f;
+			x->rx_missed_cntr += miss_f;
+		}
+	}
+	return;
+}
+
+static int dwmac100_get_tx_frame_status(void *data,
+				      struct stmmac_extra_stats *x,
+				      struct dma_desc *p, unsigned long ioaddr)
+{
+	int ret = 0;
+	struct net_device_stats *stats = (struct net_device_stats *)data;
+
+	if (unlikely(p->des01.tx.error_summary)) {
+		if (unlikely(p->des01.tx.underflow_error)) {
+			x->tx_underflow++;
+			stats->tx_fifo_errors++;
+		}
+		if (unlikely(p->des01.tx.no_carrier)) {
+			x->tx_carrier++;
+			stats->tx_carrier_errors++;
+		}
+		if (unlikely(p->des01.tx.loss_carrier)) {
+			x->tx_losscarrier++;
+			stats->tx_carrier_errors++;
+		}
+		if (unlikely((p->des01.tx.excessive_deferral) ||
+			     (p->des01.tx.excessive_collisions) ||
+			     (p->des01.tx.late_collision)))
+			stats->collisions += p->des01.tx.collision_count;
+		ret = -1;
+	}
+	if (unlikely(p->des01.tx.heartbeat_fail)) {
+		x->tx_heartbeat++;
+		stats->tx_heartbeat_errors++;
+		ret = -1;
+	}
+	if (unlikely(p->des01.tx.deferred))
+		x->tx_deferred++;
+
+	return ret;
+}
+
+static int dwmac100_get_tx_len(struct dma_desc *p)
+{
+	return p->des01.tx.buffer1_size;
+}
+
+/* This function verifies if each incoming frame has some errors
+ * and, if required, updates the multicast statistics.
+ * In case of success, it returns csum_none becasue the device
+ * is not able to compute the csum in HW. */
+static int dwmac100_get_rx_frame_status(void *data,
+				      struct stmmac_extra_stats *x,
+				      struct dma_desc *p)
+{
+	int ret = csum_none;
+	struct net_device_stats *stats = (struct net_device_stats *)data;
+
+	if (unlikely(p->des01.rx.last_descriptor == 0)) {
+		pr_warning("dwmac100 Error: Oversized Ethernet "
+			   "frame spanned multiple buffers\n");
+		stats->rx_length_errors++;
+		return discard_frame;
+	}
+
+	if (unlikely(p->des01.rx.error_summary)) {
+		if (unlikely(p->des01.rx.descriptor_error))
+			x->rx_desc++;
+		if (unlikely(p->des01.rx.partial_frame_error))
+			x->rx_partial++;
+		if (unlikely(p->des01.rx.run_frame))
+			x->rx_runt++;
+		if (unlikely(p->des01.rx.frame_too_long))
+			x->rx_toolong++;
+		if (unlikely(p->des01.rx.collision)) {
+			x->rx_collision++;
+			stats->collisions++;
+		}
+		if (unlikely(p->des01.rx.crc_error)) {
+			x->rx_crc++;
+			stats->rx_crc_errors++;
+		}
+		ret = discard_frame;
+	}
+	if (unlikely(p->des01.rx.dribbling))
+		ret = discard_frame;
+
+	if (unlikely(p->des01.rx.length_error)) {
+		x->rx_length++;
+		ret = discard_frame;
+	}
+	if (unlikely(p->des01.rx.mii_error)) {
+		x->rx_mii++;
+		ret = discard_frame;
+	}
+	if (p->des01.rx.multicast_frame) {
+		x->rx_multicast++;
+		stats->multicast++;
+	}
+	return ret;
+}
+
+static void dwmac100_irq_status(unsigned long ioaddr)
+{
+	return;
+}
+
+static void dwmac100_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
+			  unsigned int reg_n)
+{
+	stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
+}
+
+static void dwmac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
+			  unsigned int reg_n)
+{
+	stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
+}
+
+static void dwmac100_set_filter(struct net_device *dev)
+{
+	unsigned long ioaddr = dev->base_addr;
+	u32 value = readl(ioaddr + MAC_CONTROL);
+
+	if (dev->flags & IFF_PROMISC) {
+		value |= MAC_CONTROL_PR;
+		value &= ~(MAC_CONTROL_PM | MAC_CONTROL_IF | MAC_CONTROL_HO |
+			   MAC_CONTROL_HP);
+	} else if ((netdev_mc_count(dev) > HASH_TABLE_SIZE)
+		   || (dev->flags & IFF_ALLMULTI)) {
+		value |= MAC_CONTROL_PM;
+		value &= ~(MAC_CONTROL_PR | MAC_CONTROL_IF | MAC_CONTROL_HO);
+		writel(0xffffffff, ioaddr + MAC_HASH_HIGH);
+		writel(0xffffffff, ioaddr + MAC_HASH_LOW);
+	} else if (netdev_mc_empty(dev)) {	/* no multicast */
+		value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF |
+			   MAC_CONTROL_HO | MAC_CONTROL_HP);
+	} else {
+		u32 mc_filter[2];
+		struct dev_mc_list *mclist;
+
+		/* Perfect filter mode for physical address and Hash
+		   filter for multicast */
+		value |= MAC_CONTROL_HP;
+		value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR |
+			   MAC_CONTROL_IF | MAC_CONTROL_HO);
+
+		memset(mc_filter, 0, sizeof(mc_filter));
+		netdev_for_each_mc_addr(mclist, dev) {
+			/* The upper 6 bits of the calculated CRC are used to
+			 * index the contens of the hash table */
+			int bit_nr =
+			    ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+			/* The most significant bit determines the register to
+			 * use (H/L) while the other 5 bits determine the bit
+			 * within the register. */
+			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
+		}
+		writel(mc_filter[0], ioaddr + MAC_HASH_LOW);
+		writel(mc_filter[1], ioaddr + MAC_HASH_HIGH);
+	}
+
+	writel(value, ioaddr + MAC_CONTROL);
+
+	DBG(KERN_INFO "%s: CTRL reg: 0x%08x Hash regs: "
+	    "HI 0x%08x, LO 0x%08x\n",
+	    __func__, readl(ioaddr + MAC_CONTROL),
+	    readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
+	return;
+}
+
+static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
+			     unsigned int fc, unsigned int pause_time)
+{
+	unsigned int flow = MAC_FLOW_CTRL_ENABLE;
+
+	if (duplex)
+		flow |= (pause_time << MAC_FLOW_CTRL_PT_SHIFT);
+	writel(flow, ioaddr + MAC_FLOW_CTRL);
+
+	return;
+}
+
+/* No PMT module supported for this Ethernet Controller.
+ * Tested on ST platforms only.
+ */
+static void dwmac100_pmt(unsigned long ioaddr, unsigned long mode)
+{
+	return;
+}
+
+static void dwmac100_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
+				int disable_rx_ic)
+{
+	int i;
+	for (i = 0; i < ring_size; i++) {
+		p->des01.rx.own = 1;
+		p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
+		if (i == ring_size - 1)
+			p->des01.rx.end_ring = 1;
+		if (disable_rx_ic)
+			p->des01.rx.disable_ic = 1;
+		p++;
+	}
+	return;
+}
+
+static void dwmac100_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
+{
+	int i;
+	for (i = 0; i < ring_size; i++) {
+		p->des01.tx.own = 0;
+		if (i == ring_size - 1)
+			p->des01.tx.end_ring = 1;
+		p++;
+	}
+	return;
+}
+
+static int dwmac100_get_tx_owner(struct dma_desc *p)
+{
+	return p->des01.tx.own;
+}
+
+static int dwmac100_get_rx_owner(struct dma_desc *p)
+{
+	return p->des01.rx.own;
+}
+
+static void dwmac100_set_tx_owner(struct dma_desc *p)
+{
+	p->des01.tx.own = 1;
+}
+
+static void dwmac100_set_rx_owner(struct dma_desc *p)
+{
+	p->des01.rx.own = 1;
+}
+
+static int dwmac100_get_tx_ls(struct dma_desc *p)
+{
+	return p->des01.tx.last_segment;
+}
+
+static void dwmac100_release_tx_desc(struct dma_desc *p)
+{
+	int ter = p->des01.tx.end_ring;
+
+	/* clean field used within the xmit */
+	p->des01.tx.first_segment = 0;
+	p->des01.tx.last_segment = 0;
+	p->des01.tx.buffer1_size = 0;
+
+	/* clean status reported */
+	p->des01.tx.error_summary = 0;
+	p->des01.tx.underflow_error = 0;
+	p->des01.tx.no_carrier = 0;
+	p->des01.tx.loss_carrier = 0;
+	p->des01.tx.excessive_deferral = 0;
+	p->des01.tx.excessive_collisions = 0;
+	p->des01.tx.late_collision = 0;
+	p->des01.tx.heartbeat_fail = 0;
+	p->des01.tx.deferred = 0;
+
+	/* set termination field */
+	p->des01.tx.end_ring = ter;
+
+	return;
+}
+
+static void dwmac100_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
+				   int csum_flag)
+{
+	p->des01.tx.first_segment = is_fs;
+	p->des01.tx.buffer1_size = len;
+}
+
+static void dwmac100_clear_tx_ic(struct dma_desc *p)
+{
+	p->des01.tx.interrupt = 0;
+}
+
+static void dwmac100_close_tx_desc(struct dma_desc *p)
+{
+	p->des01.tx.last_segment = 1;
+	p->des01.tx.interrupt = 1;
+}
+
+static int dwmac100_get_rx_frame_len(struct dma_desc *p)
+{
+	return p->des01.rx.frame_length;
+}
+
+struct stmmac_ops dwmac100_ops = {
+	.core_init = dwmac100_core_init,
+	.dump_regs = dwmac100_dump_mac_regs,
+	.host_irq_status = dwmac100_irq_status,
+	.set_filter = dwmac100_set_filter,
+	.flow_ctrl = dwmac100_flow_ctrl,
+	.pmt = dwmac100_pmt,
+	.set_umac_addr = dwmac100_set_umac_addr,
+	.get_umac_addr = dwmac100_get_umac_addr,
+};
+
+struct stmmac_dma_ops dwmac100_dma_ops = {
+	.init = dwmac100_dma_init,
+	.dump_regs = dwmac100_dump_dma_regs,
+	.dma_mode = dwmac100_dma_operation_mode,
+	.dma_diagnostic_fr = dwmac100_dma_diagnostic_fr,
+	.enable_dma_transmission = dwmac_enable_dma_transmission,
+	.enable_dma_irq = dwmac_enable_dma_irq,
+	.disable_dma_irq = dwmac_disable_dma_irq,
+	.start_tx = dwmac_dma_start_tx,
+	.stop_tx = dwmac_dma_stop_tx,
+	.start_rx = dwmac_dma_start_rx,
+	.stop_rx = dwmac_dma_stop_rx,
+	.dma_interrupt = dwmac_dma_interrupt,
+};
+
+struct stmmac_desc_ops dwmac100_desc_ops = {
+	.tx_status = dwmac100_get_tx_frame_status,
+	.rx_status = dwmac100_get_rx_frame_status,
+	.get_tx_len = dwmac100_get_tx_len,
+	.init_rx_desc = dwmac100_init_rx_desc,
+	.init_tx_desc = dwmac100_init_tx_desc,
+	.get_tx_owner = dwmac100_get_tx_owner,
+	.get_rx_owner = dwmac100_get_rx_owner,
+	.release_tx_desc = dwmac100_release_tx_desc,
+	.prepare_tx_desc = dwmac100_prepare_tx_desc,
+	.clear_tx_ic = dwmac100_clear_tx_ic,
+	.close_tx_desc = dwmac100_close_tx_desc,
+	.get_tx_ls = dwmac100_get_tx_ls,
+	.set_tx_owner = dwmac100_set_tx_owner,
+	.set_rx_owner = dwmac100_set_rx_owner,
+	.get_rx_frame_len = dwmac100_get_rx_frame_len,
+};
+
+struct mac_device_info *dwmac100_setup(unsigned long ioaddr)
+{
+	struct mac_device_info *mac;
+
+	mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
+
+	pr_info("\tDWMAC100\n");
+
+	mac->mac = &dwmac100_ops;
+	mac->desc = &dwmac100_desc_ops;
+	mac->dma = &dwmac100_dma_ops;
+
+	mac->pmt = PMT_NOT_SUPPORTED;
+	mac->link.port = MAC_CONTROL_PS;
+	mac->link.duplex = MAC_CONTROL_F;
+	mac->link.speed = 0;
+	mac->mii.addr = MAC_MII_ADDR;
+	mac->mii.data = MAC_MII_DATA;
+
+	return mac;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/dwmac100.h linux-libre-2.6.34-gnu1/drivers/net/stmmac/dwmac100.h
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/dwmac100.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/dwmac100.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,116 @@
+/*******************************************************************************
+  MAC 10/100 Header File
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  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".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+/*----------------------------------------------------------------------------
+ *	 			MAC BLOCK defines
+ *---------------------------------------------------------------------------*/
+/* MAC CSR offset */
+#define MAC_CONTROL	0x00000000	/* MAC Control */
+#define MAC_ADDR_HIGH	0x00000004	/* MAC Address High */
+#define MAC_ADDR_LOW	0x00000008	/* MAC Address Low */
+#define MAC_HASH_HIGH	0x0000000c	/* Multicast Hash Table High */
+#define MAC_HASH_LOW	0x00000010	/* Multicast Hash Table Low */
+#define MAC_MII_ADDR	0x00000014	/* MII Address */
+#define MAC_MII_DATA	0x00000018	/* MII Data */
+#define MAC_FLOW_CTRL	0x0000001c	/* Flow Control */
+#define MAC_VLAN1	0x00000020	/* VLAN1 Tag */
+#define MAC_VLAN2	0x00000024	/* VLAN2 Tag */
+
+/* MAC CTRL defines */
+#define MAC_CONTROL_RA	0x80000000	/* Receive All Mode */
+#define MAC_CONTROL_BLE	0x40000000	/* Endian Mode */
+#define MAC_CONTROL_HBD	0x10000000	/* Heartbeat Disable */
+#define MAC_CONTROL_PS	0x08000000	/* Port Select */
+#define MAC_CONTROL_DRO	0x00800000	/* Disable Receive Own */
+#define MAC_CONTROL_EXT_LOOPBACK 0x00400000	/* Reserved (ext loopback?) */
+#define MAC_CONTROL_OM	0x00200000	/* Loopback Operating Mode */
+#define MAC_CONTROL_F	0x00100000	/* Full Duplex Mode */
+#define MAC_CONTROL_PM	0x00080000	/* Pass All Multicast */
+#define MAC_CONTROL_PR	0x00040000	/* Promiscuous Mode */
+#define MAC_CONTROL_IF	0x00020000	/* Inverse Filtering */
+#define MAC_CONTROL_PB	0x00010000	/* Pass Bad Frames */
+#define MAC_CONTROL_HO	0x00008000	/* Hash Only Filtering Mode */
+#define MAC_CONTROL_HP	0x00002000	/* Hash/Perfect Filtering Mode */
+#define MAC_CONTROL_LCC	0x00001000	/* Late Collision Control */
+#define MAC_CONTROL_DBF	0x00000800	/* Disable Broadcast Frames */
+#define MAC_CONTROL_DRTY	0x00000400	/* Disable Retry */
+#define MAC_CONTROL_ASTP	0x00000100	/* Automatic Pad Stripping */
+#define MAC_CONTROL_BOLMT_10	0x00000000	/* Back Off Limit 10 */
+#define MAC_CONTROL_BOLMT_8	0x00000040	/* Back Off Limit 8 */
+#define MAC_CONTROL_BOLMT_4	0x00000080	/* Back Off Limit 4 */
+#define MAC_CONTROL_BOLMT_1	0x000000c0	/* Back Off Limit 1 */
+#define MAC_CONTROL_DC		0x00000020	/* Deferral Check */
+#define MAC_CONTROL_TE		0x00000008	/* Transmitter Enable */
+#define MAC_CONTROL_RE		0x00000004	/* Receiver Enable */
+
+#define MAC_CORE_INIT (MAC_CONTROL_HBD | MAC_CONTROL_ASTP)
+
+/* MAC FLOW CTRL defines */
+#define MAC_FLOW_CTRL_PT_MASK	0xffff0000	/* Pause Time Mask */
+#define MAC_FLOW_CTRL_PT_SHIFT	16
+#define MAC_FLOW_CTRL_PASS	0x00000004	/* Pass Control Frames */
+#define MAC_FLOW_CTRL_ENABLE	0x00000002	/* Flow Control Enable */
+#define MAC_FLOW_CTRL_PAUSE	0x00000001	/* Flow Control Busy ... */
+
+/* MII ADDR  defines */
+#define MAC_MII_ADDR_WRITE	0x00000002	/* MII Write */
+#define MAC_MII_ADDR_BUSY	0x00000001	/* MII Busy */
+
+/*----------------------------------------------------------------------------
+ * 				DMA BLOCK defines
+ *---------------------------------------------------------------------------*/
+
+/* DMA Bus Mode register defines */
+#define DMA_BUS_MODE_DBO	0x00100000	/* Descriptor Byte Ordering */
+#define DMA_BUS_MODE_BLE	0x00000080	/* Big Endian/Little Endian */
+#define DMA_BUS_MODE_PBL_MASK	0x00003f00	/* Programmable Burst Len */
+#define DMA_BUS_MODE_PBL_SHIFT	8
+#define DMA_BUS_MODE_DSL_MASK	0x0000007c	/* Descriptor Skip Length */
+#define DMA_BUS_MODE_DSL_SHIFT	2	/*   (in DWORDS)      */
+#define DMA_BUS_MODE_BAR_BUS	0x00000002	/* Bar-Bus Arbitration */
+#define DMA_BUS_MODE_SFT_RESET	0x00000001	/* Software Reset */
+#define DMA_BUS_MODE_DEFAULT	0x00000000
+
+/* DMA Control register defines */
+#define DMA_CONTROL_SF		0x00200000	/* Store And Forward */
+
+/* Transmit Threshold Control */
+enum ttc_control {
+	DMA_CONTROL_TTC_DEFAULT = 0x00000000,	/* Threshold is 32 DWORDS */
+	DMA_CONTROL_TTC_64 = 0x00004000,	/* Threshold is 64 DWORDS */
+	DMA_CONTROL_TTC_128 = 0x00008000,	/* Threshold is 128 DWORDS */
+	DMA_CONTROL_TTC_256 = 0x0000c000,	/* Threshold is 256 DWORDS */
+	DMA_CONTROL_TTC_18 = 0x00400000,	/* Threshold is 18 DWORDS */
+	DMA_CONTROL_TTC_24 = 0x00404000,	/* Threshold is 24 DWORDS */
+	DMA_CONTROL_TTC_32 = 0x00408000,	/* Threshold is 32 DWORDS */
+	DMA_CONTROL_TTC_40 = 0x0040c000,	/* Threshold is 40 DWORDS */
+	DMA_CONTROL_SE = 0x00000008,	/* Stop On Empty */
+	DMA_CONTROL_OSF = 0x00000004,	/* Operate On 2nd Frame */
+};
+
+/* STMAC110 DMA Missed Frame Counter register defines */
+#define DMA_MISSED_FRAME_OVE	0x10000000	/* FIFO Overflow Overflow */
+#define DMA_MISSED_FRAME_OVE_CNTR 0x0ffe0000	/* Overflow Frame Counter */
+#define DMA_MISSED_FRAME_OVE_M	0x00010000	/* Missed Frame Overflow */
+#define DMA_MISSED_FRAME_M_CNTR	0x0000ffff	/* Missed Frame Couinter */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/dwmac_dma.h linux-libre-2.6.34-gnu1/drivers/net/stmmac/dwmac_dma.h
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/dwmac_dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/dwmac_dma.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,107 @@
+/*******************************************************************************
+  DWMAC DMA Header file.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  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".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+/* DMA CRS Control and Status Register Mapping */
+#define DMA_BUS_MODE		0x00001000	/* Bus Mode */
+#define DMA_XMT_POLL_DEMAND	0x00001004	/* Transmit Poll Demand */
+#define DMA_RCV_POLL_DEMAND	0x00001008	/* Received Poll Demand */
+#define DMA_RCV_BASE_ADDR	0x0000100c	/* Receive List Base */
+#define DMA_TX_BASE_ADDR	0x00001010	/* Transmit List Base */
+#define DMA_STATUS		0x00001014	/* Status Register */
+#define DMA_CONTROL		0x00001018	/* Ctrl (Operational Mode) */
+#define DMA_INTR_ENA		0x0000101c	/* Interrupt Enable */
+#define DMA_MISSED_FRAME_CTR	0x00001020	/* Missed Frame Counter */
+#define DMA_CUR_TX_BUF_ADDR	0x00001050	/* Current Host Tx Buffer */
+#define DMA_CUR_RX_BUF_ADDR	0x00001054	/* Current Host Rx Buffer */
+
+/* DMA Control register defines */
+#define DMA_CONTROL_ST		0x00002000	/* Start/Stop Transmission */
+#define DMA_CONTROL_SR		0x00000002	/* Start/Stop Receive */
+
+/* DMA Normal interrupt */
+#define DMA_INTR_ENA_NIE 0x00010000	/* Normal Summary */
+#define DMA_INTR_ENA_TIE 0x00000001	/* Transmit Interrupt */
+#define DMA_INTR_ENA_TUE 0x00000004	/* Transmit Buffer Unavailable */
+#define DMA_INTR_ENA_RIE 0x00000040	/* Receive Interrupt */
+#define DMA_INTR_ENA_ERE 0x00004000	/* Early Receive */
+
+#define DMA_INTR_NORMAL	(DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \
+			DMA_INTR_ENA_TIE)
+
+/* DMA Abnormal interrupt */
+#define DMA_INTR_ENA_AIE 0x00008000	/* Abnormal Summary */
+#define DMA_INTR_ENA_FBE 0x00002000	/* Fatal Bus Error */
+#define DMA_INTR_ENA_ETE 0x00000400	/* Early Transmit */
+#define DMA_INTR_ENA_RWE 0x00000200	/* Receive Watchdog */
+#define DMA_INTR_ENA_RSE 0x00000100	/* Receive Stopped */
+#define DMA_INTR_ENA_RUE 0x00000080	/* Receive Buffer Unavailable */
+#define DMA_INTR_ENA_UNE 0x00000020	/* Tx Underflow */
+#define DMA_INTR_ENA_OVE 0x00000010	/* Receive Overflow */
+#define DMA_INTR_ENA_TJE 0x00000008	/* Transmit Jabber */
+#define DMA_INTR_ENA_TSE 0x00000002	/* Transmit Stopped */
+
+#define DMA_INTR_ABNORMAL	(DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \
+				DMA_INTR_ENA_UNE)
+
+/* DMA default interrupt mask */
+#define DMA_INTR_DEFAULT_MASK	(DMA_INTR_NORMAL | DMA_INTR_ABNORMAL)
+
+/* DMA Status register defines */
+#define DMA_STATUS_GPI		0x10000000	/* PMT interrupt */
+#define DMA_STATUS_GMI		0x08000000	/* MMC interrupt */
+#define DMA_STATUS_GLI		0x04000000	/* GMAC Line interface int */
+#define DMA_STATUS_GMI		0x08000000
+#define DMA_STATUS_GLI		0x04000000
+#define DMA_STATUS_EB_MASK	0x00380000	/* Error Bits Mask */
+#define DMA_STATUS_EB_TX_ABORT	0x00080000	/* Error Bits - TX Abort */
+#define DMA_STATUS_EB_RX_ABORT	0x00100000	/* Error Bits - RX Abort */
+#define DMA_STATUS_TS_MASK	0x00700000	/* Transmit Process State */
+#define DMA_STATUS_TS_SHIFT	20
+#define DMA_STATUS_RS_MASK	0x000e0000	/* Receive Process State */
+#define DMA_STATUS_RS_SHIFT	17
+#define DMA_STATUS_NIS	0x00010000	/* Normal Interrupt Summary */
+#define DMA_STATUS_AIS	0x00008000	/* Abnormal Interrupt Summary */
+#define DMA_STATUS_ERI	0x00004000	/* Early Receive Interrupt */
+#define DMA_STATUS_FBI	0x00002000	/* Fatal Bus Error Interrupt */
+#define DMA_STATUS_ETI	0x00000400	/* Early Transmit Interrupt */
+#define DMA_STATUS_RWT	0x00000200	/* Receive Watchdog Timeout */
+#define DMA_STATUS_RPS	0x00000100	/* Receive Process Stopped */
+#define DMA_STATUS_RU	0x00000080	/* Receive Buffer Unavailable */
+#define DMA_STATUS_RI	0x00000040	/* Receive Interrupt */
+#define DMA_STATUS_UNF	0x00000020	/* Transmit Underflow */
+#define DMA_STATUS_OVF	0x00000010	/* Receive Overflow */
+#define DMA_STATUS_TJT	0x00000008	/* Transmit Jabber Timeout */
+#define DMA_STATUS_TU	0x00000004	/* Transmit Buffer Unavailable */
+#define DMA_STATUS_TPS	0x00000002	/* Transmit Process Stopped */
+#define DMA_STATUS_TI	0x00000001	/* Transmit Interrupt */
+
+extern void dwmac_enable_dma_transmission(unsigned long ioaddr);
+extern void dwmac_enable_dma_irq(unsigned long ioaddr);
+extern void dwmac_disable_dma_irq(unsigned long ioaddr);
+extern void dwmac_dma_start_tx(unsigned long ioaddr);
+extern void dwmac_dma_stop_tx(unsigned long ioaddr);
+extern void dwmac_dma_start_rx(unsigned long ioaddr);
+extern void dwmac_dma_stop_rx(unsigned long ioaddr);
+extern int dwmac_dma_interrupt(unsigned long ioaddr,
+				struct stmmac_extra_stats *x);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/dwmac_lib.c linux-libre-2.6.34-gnu1/drivers/net/stmmac/dwmac_lib.c
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/dwmac_lib.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/dwmac_lib.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,263 @@
+/*******************************************************************************
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  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".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/io.h>
+#include "common.h"
+#include "dwmac_dma.h"
+
+#undef DWMAC_DMA_DEBUG
+#ifdef DWMAC_DMA_DEBUG
+#define DBG(fmt, args...)  printk(fmt, ## args)
+#else
+#define DBG(fmt, args...)  do { } while (0)
+#endif
+
+/* CSR1 enables the transmit DMA to check for new descriptor */
+void dwmac_enable_dma_transmission(unsigned long ioaddr)
+{
+	writel(1, ioaddr + DMA_XMT_POLL_DEMAND);
+}
+
+void dwmac_enable_dma_irq(unsigned long ioaddr)
+{
+	writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
+}
+
+void dwmac_disable_dma_irq(unsigned long ioaddr)
+{
+	writel(0, ioaddr + DMA_INTR_ENA);
+}
+
+void dwmac_dma_start_tx(unsigned long ioaddr)
+{
+	u32 value = readl(ioaddr + DMA_CONTROL);
+	value |= DMA_CONTROL_ST;
+	writel(value, ioaddr + DMA_CONTROL);
+	return;
+}
+
+void dwmac_dma_stop_tx(unsigned long ioaddr)
+{
+	u32 value = readl(ioaddr + DMA_CONTROL);
+	value &= ~DMA_CONTROL_ST;
+	writel(value, ioaddr + DMA_CONTROL);
+	return;
+}
+
+void dwmac_dma_start_rx(unsigned long ioaddr)
+{
+	u32 value = readl(ioaddr + DMA_CONTROL);
+	value |= DMA_CONTROL_SR;
+	writel(value, ioaddr + DMA_CONTROL);
+
+	return;
+}
+
+void dwmac_dma_stop_rx(unsigned long ioaddr)
+{
+	u32 value = readl(ioaddr + DMA_CONTROL);
+	value &= ~DMA_CONTROL_SR;
+	writel(value, ioaddr + DMA_CONTROL);
+
+	return;
+}
+
+#ifdef DWMAC_DMA_DEBUG
+static void show_tx_process_state(unsigned int status)
+{
+	unsigned int state;
+	state = (status & DMA_STATUS_TS_MASK) >> DMA_STATUS_TS_SHIFT;
+
+	switch (state) {
+	case 0:
+		pr_info("- TX (Stopped): Reset or Stop command\n");
+		break;
+	case 1:
+		pr_info("- TX (Running):Fetching the Tx desc\n");
+		break;
+	case 2:
+		pr_info("- TX (Running): Waiting for end of tx\n");
+		break;
+	case 3:
+		pr_info("- TX (Running): Reading the data "
+		       "and queuing the data into the Tx buf\n");
+		break;
+	case 6:
+		pr_info("- TX (Suspended): Tx Buff Underflow "
+		       "or an unavailable Transmit descriptor\n");
+		break;
+	case 7:
+		pr_info("- TX (Running): Closing Tx descriptor\n");
+		break;
+	default:
+		break;
+	}
+	return;
+}
+
+static void show_rx_process_state(unsigned int status)
+{
+	unsigned int state;
+	state = (status & DMA_STATUS_RS_MASK) >> DMA_STATUS_RS_SHIFT;
+
+	switch (state) {
+	case 0:
+		pr_info("- RX (Stopped): Reset or Stop command\n");
+		break;
+	case 1:
+		pr_info("- RX (Running): Fetching the Rx desc\n");
+		break;
+	case 2:
+		pr_info("- RX (Running):Checking for end of pkt\n");
+		break;
+	case 3:
+		pr_info("- RX (Running): Waiting for Rx pkt\n");
+		break;
+	case 4:
+		pr_info("- RX (Suspended): Unavailable Rx buf\n");
+		break;
+	case 5:
+		pr_info("- RX (Running): Closing Rx descriptor\n");
+		break;
+	case 6:
+		pr_info("- RX(Running): Flushing the current frame"
+		       " from the Rx buf\n");
+		break;
+	case 7:
+		pr_info("- RX (Running): Queuing the Rx frame"
+		       " from the Rx buf into memory\n");
+		break;
+	default:
+		break;
+	}
+	return;
+}
+#endif
+
+int dwmac_dma_interrupt(unsigned long ioaddr,
+			struct stmmac_extra_stats *x)
+{
+	int ret = 0;
+	/* read the status register (CSR5) */
+	u32 intr_status = readl(ioaddr + DMA_STATUS);
+
+	DBG(INFO, "%s: [CSR5: 0x%08x]\n", __func__, intr_status);
+#ifdef DWMAC_DMA_DEBUG
+	/* It displays the DMA process states (CSR5 register) */
+	show_tx_process_state(intr_status);
+	show_rx_process_state(intr_status);
+#endif
+	/* ABNORMAL interrupts */
+	if (unlikely(intr_status & DMA_STATUS_AIS)) {
+		DBG(INFO, "CSR5[15] DMA ABNORMAL IRQ: ");
+		if (unlikely(intr_status & DMA_STATUS_UNF)) {
+			DBG(INFO, "transmit underflow\n");
+			ret = tx_hard_error_bump_tc;
+			x->tx_undeflow_irq++;
+		}
+		if (unlikely(intr_status & DMA_STATUS_TJT)) {
+			DBG(INFO, "transmit jabber\n");
+			x->tx_jabber_irq++;
+		}
+		if (unlikely(intr_status & DMA_STATUS_OVF)) {
+			DBG(INFO, "recv overflow\n");
+			x->rx_overflow_irq++;
+		}
+		if (unlikely(intr_status & DMA_STATUS_RU)) {
+			DBG(INFO, "receive buffer unavailable\n");
+			x->rx_buf_unav_irq++;
+		}
+		if (unlikely(intr_status & DMA_STATUS_RPS)) {
+			DBG(INFO, "receive process stopped\n");
+			x->rx_process_stopped_irq++;
+		}
+		if (unlikely(intr_status & DMA_STATUS_RWT)) {
+			DBG(INFO, "receive watchdog\n");
+			x->rx_watchdog_irq++;
+		}
+		if (unlikely(intr_status & DMA_STATUS_ETI)) {
+			DBG(INFO, "transmit early interrupt\n");
+			x->tx_early_irq++;
+		}
+		if (unlikely(intr_status & DMA_STATUS_TPS)) {
+			DBG(INFO, "transmit process stopped\n");
+			x->tx_process_stopped_irq++;
+			ret = tx_hard_error;
+		}
+		if (unlikely(intr_status & DMA_STATUS_FBI)) {
+			DBG(INFO, "fatal bus error\n");
+			x->fatal_bus_error_irq++;
+			ret = tx_hard_error;
+		}
+	}
+	/* TX/RX NORMAL interrupts */
+	if (intr_status & DMA_STATUS_NIS) {
+		x->normal_irq_n++;
+		if (likely((intr_status & DMA_STATUS_RI) ||
+			 (intr_status & (DMA_STATUS_TI))))
+				ret = handle_tx_rx;
+	}
+	/* Optional hardware blocks, interrupts should be disabled */
+	if (unlikely(intr_status &
+		     (DMA_STATUS_GPI | DMA_STATUS_GMI | DMA_STATUS_GLI)))
+		pr_info("%s: unexpected status %08x\n", __func__, intr_status);
+	/* Clear the interrupt by writing a logic 1 to the CSR5[15-0] */
+	writel((intr_status & 0x1ffff), ioaddr + DMA_STATUS);
+
+	DBG(INFO, "\n\n");
+	return ret;
+}
+
+
+void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
+			 unsigned int high, unsigned int low)
+{
+	unsigned long data;
+
+	data = (addr[5] << 8) | addr[4];
+	writel(data, ioaddr + high);
+	data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
+	writel(data, ioaddr + low);
+
+	return;
+}
+
+void stmmac_get_mac_addr(unsigned long ioaddr, unsigned char *addr,
+			 unsigned int high, unsigned int low)
+{
+	unsigned int hi_addr, lo_addr;
+
+	/* Read the MAC address from the hardware */
+	hi_addr = readl(ioaddr + high);
+	lo_addr = readl(ioaddr + low);
+
+	/* Extract the MAC address from the high and low words */
+	addr[0] = lo_addr & 0xff;
+	addr[1] = (lo_addr >> 8) & 0xff;
+	addr[2] = (lo_addr >> 16) & 0xff;
+	addr[3] = (lo_addr >> 24) & 0xff;
+	addr[4] = hi_addr & 0xff;
+	addr[5] = (hi_addr >> 8) & 0xff;
+
+	return;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/gmac.c linux-libre-2.6.34-gnu1/drivers/net/stmmac/gmac.c
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/gmac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/gmac.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,693 +0,0 @@
-/*******************************************************************************
-  This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
-  DWC Ether MAC 10/100/1000 Universal version 3.41a  has been used for
-  developing this code.
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  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".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include <linux/netdevice.h>
-#include <linux/crc32.h>
-#include <linux/mii.h>
-#include <linux/phy.h>
-
-#include "stmmac.h"
-#include "gmac.h"
-
-#undef GMAC_DEBUG
-/*#define GMAC_DEBUG*/
-#undef FRAME_FILTER_DEBUG
-/*#define FRAME_FILTER_DEBUG*/
-#ifdef GMAC_DEBUG
-#define DBG(fmt, args...)  printk(fmt, ## args)
-#else
-#define DBG(fmt, args...)  do { } while (0)
-#endif
-
-static void gmac_dump_regs(unsigned long ioaddr)
-{
-	int i;
-	pr_info("\t----------------------------------------------\n"
-	       "\t  GMAC registers (base addr = 0x%8x)\n"
-	       "\t----------------------------------------------\n",
-	       (unsigned int)ioaddr);
-
-	for (i = 0; i < 55; i++) {
-		int offset = i * 4;
-		pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
-		       offset, readl(ioaddr + offset));
-	}
-	return;
-}
-
-static int gmac_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx)
-{
-	u32 value = readl(ioaddr + DMA_BUS_MODE);
-	/* DMA SW reset */
-	value |= DMA_BUS_MODE_SFT_RESET;
-	writel(value, ioaddr + DMA_BUS_MODE);
-	do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
-
-	value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL |
-	    ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
-	     (pbl << DMA_BUS_MODE_RPBL_SHIFT));
-
-#ifdef CONFIG_STMMAC_DA
-	value |= DMA_BUS_MODE_DA;	/* Rx has priority over tx */
-#endif
-	writel(value, ioaddr + DMA_BUS_MODE);
-
-	/* Mask interrupts by writing to CSR7 */
-	writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
-
-	/* The base address of the RX/TX descriptor lists must be written into
-	 * DMA CSR3 and CSR4, respectively. */
-	writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
-	writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
-
-	return 0;
-}
-
-/* Transmit FIFO flush operation */
-static void gmac_flush_tx_fifo(unsigned long ioaddr)
-{
-	u32 csr6 = readl(ioaddr + DMA_CONTROL);
-	writel((csr6 | DMA_CONTROL_FTF), ioaddr + DMA_CONTROL);
-
-	do {} while ((readl(ioaddr + DMA_CONTROL) & DMA_CONTROL_FTF));
-}
-
-static void gmac_dma_operation_mode(unsigned long ioaddr, int txmode,
-				    int rxmode)
-{
-	u32 csr6 = readl(ioaddr + DMA_CONTROL);
-
-	if (txmode == SF_DMA_MODE) {
-		DBG(KERN_DEBUG "GMAC: enabling TX store and forward mode\n");
-		/* Transmit COE type 2 cannot be done in cut-through mode. */
-		csr6 |= DMA_CONTROL_TSF;
-		/* Operating on second frame increase the performance
-		 * especially when transmit store-and-forward is used.*/
-		csr6 |= DMA_CONTROL_OSF;
-	} else {
-		DBG(KERN_DEBUG "GMAC: disabling TX store and forward mode"
-			      " (threshold = %d)\n", txmode);
-		csr6 &= ~DMA_CONTROL_TSF;
-		csr6 &= DMA_CONTROL_TC_TX_MASK;
-		/* Set the transmit threshold */
-		if (txmode <= 32)
-			csr6 |= DMA_CONTROL_TTC_32;
-		else if (txmode <= 64)
-			csr6 |= DMA_CONTROL_TTC_64;
-		else if (txmode <= 128)
-			csr6 |= DMA_CONTROL_TTC_128;
-		else if (txmode <= 192)
-			csr6 |= DMA_CONTROL_TTC_192;
-		else
-			csr6 |= DMA_CONTROL_TTC_256;
-	}
-
-	if (rxmode == SF_DMA_MODE) {
-		DBG(KERN_DEBUG "GMAC: enabling RX store and forward mode\n");
-		csr6 |= DMA_CONTROL_RSF;
-	} else {
-		DBG(KERN_DEBUG "GMAC: disabling RX store and forward mode"
-			      " (threshold = %d)\n", rxmode);
-		csr6 &= ~DMA_CONTROL_RSF;
-		csr6 &= DMA_CONTROL_TC_RX_MASK;
-		if (rxmode <= 32)
-			csr6 |= DMA_CONTROL_RTC_32;
-		else if (rxmode <= 64)
-			csr6 |= DMA_CONTROL_RTC_64;
-		else if (rxmode <= 96)
-			csr6 |= DMA_CONTROL_RTC_96;
-		else
-			csr6 |= DMA_CONTROL_RTC_128;
-	}
-
-	writel(csr6, ioaddr + DMA_CONTROL);
-	return;
-}
-
-/* Not yet implemented --- no RMON module */
-static void gmac_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
-				   unsigned long ioaddr)
-{
-	return;
-}
-
-static void gmac_dump_dma_regs(unsigned long ioaddr)
-{
-	int i;
-	pr_info(" DMA registers\n");
-	for (i = 0; i < 22; i++) {
-		if ((i < 9) || (i > 17)) {
-			int offset = i * 4;
-			pr_err("\t Reg No. %d (offset 0x%x): 0x%08x\n", i,
-			       (DMA_BUS_MODE + offset),
-			       readl(ioaddr + DMA_BUS_MODE + offset));
-		}
-	}
-	return;
-}
-
-static int gmac_get_tx_frame_status(void *data, struct stmmac_extra_stats *x,
-				    struct dma_desc *p, unsigned long ioaddr)
-{
-	int ret = 0;
-	struct net_device_stats *stats = (struct net_device_stats *)data;
-
-	if (unlikely(p->des01.etx.error_summary)) {
-		DBG(KERN_ERR "GMAC TX error... 0x%08x\n", p->des01.etx);
-		if (unlikely(p->des01.etx.jabber_timeout)) {
-			DBG(KERN_ERR "\tjabber_timeout error\n");
-			x->tx_jabber++;
-		}
-
-		if (unlikely(p->des01.etx.frame_flushed)) {
-			DBG(KERN_ERR "\tframe_flushed error\n");
-			x->tx_frame_flushed++;
-			gmac_flush_tx_fifo(ioaddr);
-		}
-
-		if (unlikely(p->des01.etx.loss_carrier)) {
-			DBG(KERN_ERR "\tloss_carrier error\n");
-			x->tx_losscarrier++;
-			stats->tx_carrier_errors++;
-		}
-		if (unlikely(p->des01.etx.no_carrier)) {
-			DBG(KERN_ERR "\tno_carrier error\n");
-			x->tx_carrier++;
-			stats->tx_carrier_errors++;
-		}
-		if (unlikely(p->des01.etx.late_collision)) {
-			DBG(KERN_ERR "\tlate_collision error\n");
-			stats->collisions += p->des01.etx.collision_count;
-		}
-		if (unlikely(p->des01.etx.excessive_collisions)) {
-			DBG(KERN_ERR "\texcessive_collisions\n");
-			stats->collisions += p->des01.etx.collision_count;
-		}
-		if (unlikely(p->des01.etx.excessive_deferral)) {
-			DBG(KERN_INFO "\texcessive tx_deferral\n");
-			x->tx_deferred++;
-		}
-
-		if (unlikely(p->des01.etx.underflow_error)) {
-			DBG(KERN_ERR "\tunderflow error\n");
-			gmac_flush_tx_fifo(ioaddr);
-			x->tx_underflow++;
-		}
-
-		if (unlikely(p->des01.etx.ip_header_error)) {
-			DBG(KERN_ERR "\tTX IP header csum error\n");
-			x->tx_ip_header_error++;
-		}
-
-		if (unlikely(p->des01.etx.payload_error)) {
-			DBG(KERN_ERR "\tAddr/Payload csum error\n");
-			x->tx_payload_error++;
-			gmac_flush_tx_fifo(ioaddr);
-		}
-
-		ret = -1;
-	}
-
-	if (unlikely(p->des01.etx.deferred)) {
-		DBG(KERN_INFO "GMAC TX status: tx deferred\n");
-		x->tx_deferred++;
-	}
-#ifdef STMMAC_VLAN_TAG_USED
-	if (p->des01.etx.vlan_frame) {
-		DBG(KERN_INFO "GMAC TX status: VLAN frame\n");
-		x->tx_vlan++;
-	}
-#endif
-
-	return ret;
-}
-
-static int gmac_get_tx_len(struct dma_desc *p)
-{
-	return p->des01.etx.buffer1_size;
-}
-
-static int gmac_coe_rdes0(int ipc_err, int type, int payload_err)
-{
-	int ret = good_frame;
-	u32 status = (type << 2 | ipc_err << 1 | payload_err) & 0x7;
-
-	/* bits 5 7 0 | Frame status
-	 * ----------------------------------------------------------
-	 *      0 0 0 | IEEE 802.3 Type frame (lenght < 1536 octects)
-	 *      1 0 0 | IPv4/6 No CSUM errorS.
-	 *      1 0 1 | IPv4/6 CSUM PAYLOAD error
-	 *      1 1 0 | IPv4/6 CSUM IP HR error
-	 *      1 1 1 | IPv4/6 IP PAYLOAD AND HEADER errorS
-	 *      0 0 1 | IPv4/6 unsupported IP PAYLOAD
-	 *      0 1 1 | COE bypassed.. no IPv4/6 frame
-	 *      0 1 0 | Reserved.
-	 */
-	if (status == 0x0) {
-		DBG(KERN_INFO "RX Des0 status: IEEE 802.3 Type frame.\n");
-		ret = good_frame;
-	} else if (status == 0x4) {
-		DBG(KERN_INFO "RX Des0 status: IPv4/6 No CSUM errorS.\n");
-		ret = good_frame;
-	} else if (status == 0x5) {
-		DBG(KERN_ERR "RX Des0 status: IPv4/6 Payload Error.\n");
-		ret = csum_none;
-	} else if (status == 0x6) {
-		DBG(KERN_ERR "RX Des0 status: IPv4/6 Header Error.\n");
-		ret = csum_none;
-	} else if (status == 0x7) {
-		DBG(KERN_ERR
-		    "RX Des0 status: IPv4/6 Header and Payload Error.\n");
-		ret = csum_none;
-	} else if (status == 0x1) {
-		DBG(KERN_ERR
-		    "RX Des0 status: IPv4/6 unsupported IP PAYLOAD.\n");
-		ret = discard_frame;
-	} else if (status == 0x3) {
-		DBG(KERN_ERR "RX Des0 status: No IPv4, IPv6 frame.\n");
-		ret = discard_frame;
-	}
-	return ret;
-}
-
-static int gmac_get_rx_frame_status(void *data, struct stmmac_extra_stats *x,
-				    struct dma_desc *p)
-{
-	int ret = good_frame;
-	struct net_device_stats *stats = (struct net_device_stats *)data;
-
-	if (unlikely(p->des01.erx.error_summary)) {
-		DBG(KERN_ERR "GMAC RX Error Summary... 0x%08x\n", p->des01.erx);
-		if (unlikely(p->des01.erx.descriptor_error)) {
-			DBG(KERN_ERR "\tdescriptor error\n");
-			x->rx_desc++;
-			stats->rx_length_errors++;
-		}
-		if (unlikely(p->des01.erx.overflow_error)) {
-			DBG(KERN_ERR "\toverflow error\n");
-			x->rx_gmac_overflow++;
-		}
-
-		if (unlikely(p->des01.erx.ipc_csum_error))
-			DBG(KERN_ERR "\tIPC Csum Error/Giant frame\n");
-
-		if (unlikely(p->des01.erx.late_collision)) {
-			DBG(KERN_ERR "\tlate_collision error\n");
-			stats->collisions++;
-			stats->collisions++;
-		}
-		if (unlikely(p->des01.erx.receive_watchdog)) {
-			DBG(KERN_ERR "\treceive_watchdog error\n");
-			x->rx_watchdog++;
-		}
-		if (unlikely(p->des01.erx.error_gmii)) {
-			DBG(KERN_ERR "\tReceive Error\n");
-			x->rx_mii++;
-		}
-		if (unlikely(p->des01.erx.crc_error)) {
-			DBG(KERN_ERR "\tCRC error\n");
-			x->rx_crc++;
-			stats->rx_crc_errors++;
-		}
-		ret = discard_frame;
-	}
-
-	/* After a payload csum error, the ES bit is set.
-	 * It doesn't match with the information reported into the databook.
-	 * At any rate, we need to understand if the CSUM hw computation is ok
-	 * and report this info to the upper layers. */
-	ret = gmac_coe_rdes0(p->des01.erx.ipc_csum_error,
-		p->des01.erx.frame_type, p->des01.erx.payload_csum_error);
-
-	if (unlikely(p->des01.erx.dribbling)) {
-		DBG(KERN_ERR "GMAC RX: dribbling error\n");
-		ret = discard_frame;
-	}
-	if (unlikely(p->des01.erx.sa_filter_fail)) {
-		DBG(KERN_ERR "GMAC RX : Source Address filter fail\n");
-		x->sa_rx_filter_fail++;
-		ret = discard_frame;
-	}
-	if (unlikely(p->des01.erx.da_filter_fail)) {
-		DBG(KERN_ERR "GMAC RX : Destination Address filter fail\n");
-		x->da_rx_filter_fail++;
-		ret = discard_frame;
-	}
-	if (unlikely(p->des01.erx.length_error)) {
-		DBG(KERN_ERR "GMAC RX: length_error error\n");
-		x->rx_lenght++;
-		ret = discard_frame;
-	}
-#ifdef STMMAC_VLAN_TAG_USED
-	if (p->des01.erx.vlan_tag) {
-		DBG(KERN_INFO "GMAC RX: VLAN frame tagged\n");
-		x->rx_vlan++;
-	}
-#endif
-	return ret;
-}
-
-static void gmac_irq_status(unsigned long ioaddr)
-{
-	u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
-
-	/* Not used events (e.g. MMC interrupts) are not handled. */
-	if ((intr_status & mmc_tx_irq))
-		DBG(KERN_DEBUG "GMAC: MMC tx interrupt: 0x%08x\n",
-		    readl(ioaddr + GMAC_MMC_TX_INTR));
-	if (unlikely(intr_status & mmc_rx_irq))
-		DBG(KERN_DEBUG "GMAC: MMC rx interrupt: 0x%08x\n",
-		    readl(ioaddr + GMAC_MMC_RX_INTR));
-	if (unlikely(intr_status & mmc_rx_csum_offload_irq))
-		DBG(KERN_DEBUG "GMAC: MMC rx csum offload: 0x%08x\n",
-		    readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
-	if (unlikely(intr_status & pmt_irq)) {
-		DBG(KERN_DEBUG "GMAC: received Magic frame\n");
-		/* clear the PMT bits 5 and 6 by reading the PMT
-		 * status register. */
-		readl(ioaddr + GMAC_PMT);
-	}
-
-	return;
-}
-
-static void gmac_core_init(unsigned long ioaddr)
-{
-	u32 value = readl(ioaddr + GMAC_CONTROL);
-	value |= GMAC_CORE_INIT;
-	writel(value, ioaddr + GMAC_CONTROL);
-
-	/* STBus Bridge Configuration */
-	/*writel(0xc5608, ioaddr + 0x00007000);*/
-
-	/* Freeze MMC counters */
-	writel(0x8, ioaddr + GMAC_MMC_CTRL);
-	/* Mask GMAC interrupts */
-	writel(0x207, ioaddr + GMAC_INT_MASK);
-
-#ifdef STMMAC_VLAN_TAG_USED
-	/* Tag detection without filtering */
-	writel(0x0, ioaddr + GMAC_VLAN_TAG);
-#endif
-	return;
-}
-
-static void gmac_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
-				unsigned int reg_n)
-{
-	stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
-				GMAC_ADDR_LOW(reg_n));
-}
-
-static void gmac_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
-				unsigned int reg_n)
-{
-	stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
-				GMAC_ADDR_LOW(reg_n));
-}
-
-static void gmac_set_filter(struct net_device *dev)
-{
-	unsigned long ioaddr = dev->base_addr;
-	unsigned int value = 0;
-
-	DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
-	    __func__, dev->mc_count, dev->uc_count);
-
-	if (dev->flags & IFF_PROMISC)
-		value = GMAC_FRAME_FILTER_PR;
-	else if ((dev->mc_count > HASH_TABLE_SIZE)
-		   || (dev->flags & IFF_ALLMULTI)) {
-		value = GMAC_FRAME_FILTER_PM;	/* pass all multi */
-		writel(0xffffffff, ioaddr + GMAC_HASH_HIGH);
-		writel(0xffffffff, ioaddr + GMAC_HASH_LOW);
-	} else if (dev->mc_count > 0) {
-		int i;
-		u32 mc_filter[2];
-		struct dev_mc_list *mclist;
-
-		/* Hash filter for multicast */
-		value = GMAC_FRAME_FILTER_HMC;
-
-		memset(mc_filter, 0, sizeof(mc_filter));
-		for (i = 0, mclist = dev->mc_list;
-		     mclist && i < dev->mc_count; i++, mclist = mclist->next) {
-			/* The upper 6 bits of the calculated CRC are used to
-			   index the contens of the hash table */
-			int bit_nr =
-			    bitrev32(~crc32_le(~0, mclist->dmi_addr, 6)) >> 26;
-			/* The most significant bit determines the register to
-			 * use (H/L) while the other 5 bits determine the bit
-			 * within the register. */
-			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
-		}
-		writel(mc_filter[0], ioaddr + GMAC_HASH_LOW);
-		writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH);
-	}
-
-	/* Handle multiple unicast addresses (perfect filtering)*/
-	if (dev->uc_count > GMAC_MAX_UNICAST_ADDRESSES)
-		/* Switch to promiscuous mode is more than 16 addrs
-		   are required */
-		value |= GMAC_FRAME_FILTER_PR;
-	else {
-		int i;
-		struct dev_addr_list *uc_ptr = dev->uc_list;
-
-			for (i = 0; i < dev->uc_count; i++) {
-				gmac_set_umac_addr(ioaddr, uc_ptr->da_addr,
-						i + 1);
-
-				DBG(KERN_INFO "\t%d "
-				"- Unicast addr %02x:%02x:%02x:%02x:%02x:"
-				"%02x\n", i + 1,
-				uc_ptr->da_addr[0], uc_ptr->da_addr[1],
-				uc_ptr->da_addr[2], uc_ptr->da_addr[3],
-				uc_ptr->da_addr[4], uc_ptr->da_addr[5]);
-				uc_ptr = uc_ptr->next;
-		}
-	}
-
-#ifdef FRAME_FILTER_DEBUG
-	/* Enable Receive all mode (to debug filtering_fail errors) */
-	value |= GMAC_FRAME_FILTER_RA;
-#endif
-	writel(value, ioaddr + GMAC_FRAME_FILTER);
-
-	DBG(KERN_INFO "\tFrame Filter reg: 0x%08x\n\tHash regs: "
-	    "HI 0x%08x, LO 0x%08x\n", readl(ioaddr + GMAC_FRAME_FILTER),
-	    readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
-
-	return;
-}
-
-static void gmac_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
-			   unsigned int fc, unsigned int pause_time)
-{
-	unsigned int flow = 0;
-
-	DBG(KERN_DEBUG "GMAC Flow-Control:\n");
-	if (fc & FLOW_RX) {
-		DBG(KERN_DEBUG "\tReceive Flow-Control ON\n");
-		flow |= GMAC_FLOW_CTRL_RFE;
-	}
-	if (fc & FLOW_TX) {
-		DBG(KERN_DEBUG "\tTransmit Flow-Control ON\n");
-		flow |= GMAC_FLOW_CTRL_TFE;
-	}
-
-	if (duplex) {
-		DBG(KERN_DEBUG "\tduplex mode: pause time: %d\n", pause_time);
-		flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
-	}
-
-	writel(flow, ioaddr + GMAC_FLOW_CTRL);
-	return;
-}
-
-static void gmac_pmt(unsigned long ioaddr, unsigned long mode)
-{
-	unsigned int pmt = 0;
-
-	if (mode == WAKE_MAGIC) {
-		DBG(KERN_DEBUG "GMAC: WOL Magic frame\n");
-		pmt |= power_down | magic_pkt_en;
-	} else if (mode == WAKE_UCAST) {
-		DBG(KERN_DEBUG "GMAC: WOL on global unicast\n");
-		pmt |= global_unicast;
-	}
-
-	writel(pmt, ioaddr + GMAC_PMT);
-	return;
-}
-
-static void gmac_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
-				int disable_rx_ic)
-{
-	int i;
-	for (i = 0; i < ring_size; i++) {
-		p->des01.erx.own = 1;
-		p->des01.erx.buffer1_size = BUF_SIZE_8KiB - 1;
-		/* To support jumbo frames */
-		p->des01.erx.buffer2_size = BUF_SIZE_8KiB - 1;
-		if (i == ring_size - 1)
-			p->des01.erx.end_ring = 1;
-		if (disable_rx_ic)
-			p->des01.erx.disable_ic = 1;
-		p++;
-	}
-	return;
-}
-
-static void gmac_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
-{
-	int i;
-
-	for (i = 0; i < ring_size; i++) {
-		p->des01.etx.own = 0;
-		if (i == ring_size - 1)
-			p->des01.etx.end_ring = 1;
-		p++;
-	}
-
-	return;
-}
-
-static int gmac_get_tx_owner(struct dma_desc *p)
-{
-	return p->des01.etx.own;
-}
-
-static int gmac_get_rx_owner(struct dma_desc *p)
-{
-	return p->des01.erx.own;
-}
-
-static void gmac_set_tx_owner(struct dma_desc *p)
-{
-	p->des01.etx.own = 1;
-}
-
-static void gmac_set_rx_owner(struct dma_desc *p)
-{
-	p->des01.erx.own = 1;
-}
-
-static int gmac_get_tx_ls(struct dma_desc *p)
-{
-	return p->des01.etx.last_segment;
-}
-
-static void gmac_release_tx_desc(struct dma_desc *p)
-{
-	int ter = p->des01.etx.end_ring;
-
-	memset(p, 0, sizeof(struct dma_desc));
-	p->des01.etx.end_ring = ter;
-
-	return;
-}
-
-static void gmac_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
-				 int csum_flag)
-{
-	p->des01.etx.first_segment = is_fs;
-	if (unlikely(len > BUF_SIZE_4KiB)) {
-		p->des01.etx.buffer1_size = BUF_SIZE_4KiB;
-		p->des01.etx.buffer2_size = len - BUF_SIZE_4KiB;
-	} else {
-		p->des01.etx.buffer1_size = len;
-	}
-	if (likely(csum_flag))
-		p->des01.etx.checksum_insertion = cic_full;
-}
-
-static void gmac_clear_tx_ic(struct dma_desc *p)
-{
-	p->des01.etx.interrupt = 0;
-}
-
-static void gmac_close_tx_desc(struct dma_desc *p)
-{
-	p->des01.etx.last_segment = 1;
-	p->des01.etx.interrupt = 1;
-}
-
-static int gmac_get_rx_frame_len(struct dma_desc *p)
-{
-	return p->des01.erx.frame_length;
-}
-
-struct stmmac_ops gmac_driver = {
-	.core_init = gmac_core_init,
-	.dump_mac_regs = gmac_dump_regs,
-	.dma_init = gmac_dma_init,
-	.dump_dma_regs = gmac_dump_dma_regs,
-	.dma_mode = gmac_dma_operation_mode,
-	.dma_diagnostic_fr = gmac_dma_diagnostic_fr,
-	.tx_status = gmac_get_tx_frame_status,
-	.rx_status = gmac_get_rx_frame_status,
-	.get_tx_len = gmac_get_tx_len,
-	.set_filter = gmac_set_filter,
-	.flow_ctrl = gmac_flow_ctrl,
-	.pmt = gmac_pmt,
-	.init_rx_desc = gmac_init_rx_desc,
-	.init_tx_desc = gmac_init_tx_desc,
-	.get_tx_owner = gmac_get_tx_owner,
-	.get_rx_owner = gmac_get_rx_owner,
-	.release_tx_desc = gmac_release_tx_desc,
-	.prepare_tx_desc = gmac_prepare_tx_desc,
-	.clear_tx_ic = gmac_clear_tx_ic,
-	.close_tx_desc = gmac_close_tx_desc,
-	.get_tx_ls = gmac_get_tx_ls,
-	.set_tx_owner = gmac_set_tx_owner,
-	.set_rx_owner = gmac_set_rx_owner,
-	.get_rx_frame_len = gmac_get_rx_frame_len,
-	.host_irq_status = gmac_irq_status,
-	.set_umac_addr = gmac_set_umac_addr,
-	.get_umac_addr = gmac_get_umac_addr,
-};
-
-struct mac_device_info *gmac_setup(unsigned long ioaddr)
-{
-	struct mac_device_info *mac;
-	u32 uid = readl(ioaddr + GMAC_VERSION);
-
-	pr_info("\tGMAC - user ID: 0x%x, Synopsys ID: 0x%x\n",
-	       ((uid & 0x0000ff00) >> 8), (uid & 0x000000ff));
-
-	mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
-
-	mac->ops = &gmac_driver;
-	mac->hw.pmt = PMT_SUPPORTED;
-	mac->hw.link.port = GMAC_CONTROL_PS;
-	mac->hw.link.duplex = GMAC_CONTROL_DM;
-	mac->hw.link.speed = GMAC_CONTROL_FES;
-	mac->hw.mii.addr = GMAC_MII_ADDR;
-	mac->hw.mii.data = GMAC_MII_DATA;
-
-	return mac;
-}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/gmac.h linux-libre-2.6.34-gnu1/drivers/net/stmmac/gmac.h
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/gmac.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/gmac.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,204 +0,0 @@
-/*******************************************************************************
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  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".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#define GMAC_CONTROL		0x00000000	/* Configuration */
-#define GMAC_FRAME_FILTER	0x00000004	/* Frame Filter */
-#define GMAC_HASH_HIGH		0x00000008	/* Multicast Hash Table High */
-#define GMAC_HASH_LOW		0x0000000c	/* Multicast Hash Table Low */
-#define GMAC_MII_ADDR		0x00000010	/* MII Address */
-#define GMAC_MII_DATA		0x00000014	/* MII Data */
-#define GMAC_FLOW_CTRL		0x00000018	/* Flow Control */
-#define GMAC_VLAN_TAG		0x0000001c	/* VLAN Tag */
-#define GMAC_VERSION		0x00000020	/* GMAC CORE Version */
-#define GMAC_WAKEUP_FILTER	0x00000028	/* Wake-up Frame Filter */
-
-#define GMAC_INT_STATUS		0x00000038	/* interrupt status register */
-enum gmac_irq_status {
-	time_stamp_irq = 0x0200,
-	mmc_rx_csum_offload_irq = 0x0080,
-	mmc_tx_irq = 0x0040,
-	mmc_rx_irq = 0x0020,
-	mmc_irq = 0x0010,
-	pmt_irq = 0x0008,
-	pcs_ane_irq = 0x0004,
-	pcs_link_irq = 0x0002,
-	rgmii_irq = 0x0001,
-};
-#define GMAC_INT_MASK		0x0000003c	/* interrupt mask register */
-
-/* PMT Control and Status */
-#define GMAC_PMT		0x0000002c
-enum power_event {
-	pointer_reset = 0x80000000,
-	global_unicast = 0x00000200,
-	wake_up_rx_frame = 0x00000040,
-	magic_frame = 0x00000020,
-	wake_up_frame_en = 0x00000004,
-	magic_pkt_en = 0x00000002,
-	power_down = 0x00000001,
-};
-
-/* GMAC HW ADDR regs */
-#define GMAC_ADDR_HIGH(reg)		(0x00000040+(reg * 8))
-#define GMAC_ADDR_LOW(reg)		(0x00000044+(reg * 8))
-#define GMAC_MAX_UNICAST_ADDRESSES	16
-
-#define GMAC_AN_CTRL	0x000000c0	/* AN control */
-#define GMAC_AN_STATUS	0x000000c4	/* AN status */
-#define GMAC_ANE_ADV	0x000000c8	/* Auto-Neg. Advertisement */
-#define GMAC_ANE_LINK	0x000000cc	/* Auto-Neg. link partener ability */
-#define GMAC_ANE_EXP	0x000000d0	/* ANE expansion */
-#define GMAC_TBI	0x000000d4	/* TBI extend status */
-#define GMAC_GMII_STATUS 0x000000d8	/* S/R-GMII status */
-
-/* GMAC Configuration defines */
-#define GMAC_CONTROL_TC	0x01000000	/* Transmit Conf. in RGMII/SGMII */
-#define GMAC_CONTROL_WD	0x00800000	/* Disable Watchdog on receive */
-#define GMAC_CONTROL_JD	0x00400000	/* Jabber disable */
-#define GMAC_CONTROL_BE	0x00200000	/* Frame Burst Enable */
-#define GMAC_CONTROL_JE	0x00100000	/* Jumbo frame */
-enum inter_frame_gap {
-	GMAC_CONTROL_IFG_88 = 0x00040000,
-	GMAC_CONTROL_IFG_80 = 0x00020000,
-	GMAC_CONTROL_IFG_40 = 0x000e0000,
-};
-#define GMAC_CONTROL_DCRS	0x00010000 /* Disable carrier sense during tx */
-#define GMAC_CONTROL_PS		0x00008000 /* Port Select 0:GMI 1:MII */
-#define GMAC_CONTROL_FES	0x00004000 /* Speed 0:10 1:100 */
-#define GMAC_CONTROL_DO		0x00002000 /* Disable Rx Own */
-#define GMAC_CONTROL_LM		0x00001000 /* Loop-back mode */
-#define GMAC_CONTROL_DM		0x00000800 /* Duplex Mode */
-#define GMAC_CONTROL_IPC	0x00000400 /* Checksum Offload */
-#define GMAC_CONTROL_DR		0x00000200 /* Disable Retry */
-#define GMAC_CONTROL_LUD	0x00000100 /* Link up/down */
-#define GMAC_CONTROL_ACS	0x00000080 /* Automatic Pad Stripping */
-#define GMAC_CONTROL_DC		0x00000010 /* Deferral Check */
-#define GMAC_CONTROL_TE		0x00000008 /* Transmitter Enable */
-#define GMAC_CONTROL_RE		0x00000004 /* Receiver Enable */
-
-#define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \
-			GMAC_CONTROL_IPC | GMAC_CONTROL_JE | GMAC_CONTROL_BE)
-
-/* GMAC Frame Filter defines */
-#define GMAC_FRAME_FILTER_PR	0x00000001	/* Promiscuous Mode */
-#define GMAC_FRAME_FILTER_HUC	0x00000002	/* Hash Unicast */
-#define GMAC_FRAME_FILTER_HMC	0x00000004	/* Hash Multicast */
-#define GMAC_FRAME_FILTER_DAIF	0x00000008	/* DA Inverse Filtering */
-#define GMAC_FRAME_FILTER_PM	0x00000010	/* Pass all multicast */
-#define GMAC_FRAME_FILTER_DBF	0x00000020	/* Disable Broadcast frames */
-#define GMAC_FRAME_FILTER_SAIF	0x00000100	/* Inverse Filtering */
-#define GMAC_FRAME_FILTER_SAF	0x00000200	/* Source Address Filter */
-#define GMAC_FRAME_FILTER_HPF	0x00000400	/* Hash or perfect Filter */
-#define GMAC_FRAME_FILTER_RA	0x80000000	/* Receive all mode */
-/* GMII ADDR  defines */
-#define GMAC_MII_ADDR_WRITE	0x00000002	/* MII Write */
-#define GMAC_MII_ADDR_BUSY	0x00000001	/* MII Busy */
-/* GMAC FLOW CTRL defines */
-#define GMAC_FLOW_CTRL_PT_MASK	0xffff0000	/* Pause Time Mask */
-#define GMAC_FLOW_CTRL_PT_SHIFT	16
-#define GMAC_FLOW_CTRL_RFE	0x00000004	/* Rx Flow Control Enable */
-#define GMAC_FLOW_CTRL_TFE	0x00000002	/* Tx Flow Control Enable */
-#define GMAC_FLOW_CTRL_FCB_BPA	0x00000001	/* Flow Control Busy ... */
-
-/*--- DMA BLOCK defines ---*/
-/* DMA Bus Mode register defines */
-#define DMA_BUS_MODE_SFT_RESET	0x00000001	/* Software Reset */
-#define DMA_BUS_MODE_DA		0x00000002	/* Arbitration scheme */
-#define DMA_BUS_MODE_DSL_MASK	0x0000007c	/* Descriptor Skip Length */
-#define DMA_BUS_MODE_DSL_SHIFT	2	/*   (in DWORDS)      */
-/* Programmable burst length (passed thorugh platform)*/
-#define DMA_BUS_MODE_PBL_MASK	0x00003f00	/* Programmable Burst Len */
-#define DMA_BUS_MODE_PBL_SHIFT	8
-
-enum rx_tx_priority_ratio {
-	double_ratio = 0x00004000,	/*2:1 */
-	triple_ratio = 0x00008000,	/*3:1 */
-	quadruple_ratio = 0x0000c000,	/*4:1 */
-};
-
-#define DMA_BUS_MODE_FB		0x00010000	/* Fixed burst */
-#define DMA_BUS_MODE_RPBL_MASK	0x003e0000	/* Rx-Programmable Burst Len */
-#define DMA_BUS_MODE_RPBL_SHIFT	17
-#define DMA_BUS_MODE_USP	0x00800000
-#define DMA_BUS_MODE_4PBL	0x01000000
-#define DMA_BUS_MODE_AAL	0x02000000
-
-/* DMA CRS Control and Status Register Mapping */
-#define DMA_HOST_TX_DESC	  0x00001048	/* Current Host Tx descriptor */
-#define DMA_HOST_RX_DESC	  0x0000104c	/* Current Host Rx descriptor */
-/*  DMA Bus Mode register defines */
-#define DMA_BUS_PR_RATIO_MASK	  0x0000c000	/* Rx/Tx priority ratio */
-#define DMA_BUS_PR_RATIO_SHIFT	  14
-#define DMA_BUS_FB	  	  0x00010000	/* Fixed Burst */
-
-/* DMA operation mode defines (start/stop tx/rx are placed in common header)*/
-#define DMA_CONTROL_DT		0x04000000 /* Disable Drop TCP/IP csum error */
-#define DMA_CONTROL_RSF		0x02000000 /* Receive Store and Forward */
-#define DMA_CONTROL_DFF		0x01000000 /* Disaable flushing */
-/* Threshold for Activating the FC */
-enum rfa {
-	act_full_minus_1 = 0x00800000,
-	act_full_minus_2 = 0x00800200,
-	act_full_minus_3 = 0x00800400,
-	act_full_minus_4 = 0x00800600,
-};
-/* Threshold for Deactivating the FC */
-enum rfd {
-	deac_full_minus_1 = 0x00400000,
-	deac_full_minus_2 = 0x00400800,
-	deac_full_minus_3 = 0x00401000,
-	deac_full_minus_4 = 0x00401800,
-};
-#define DMA_CONTROL_TSF		0x00200000 /* Transmit  Store and Forward */
-#define DMA_CONTROL_FTF		0x00100000 /* Flush transmit FIFO */
-
-enum ttc_control {
-	DMA_CONTROL_TTC_64 = 0x00000000,
-	DMA_CONTROL_TTC_128 = 0x00004000,
-	DMA_CONTROL_TTC_192 = 0x00008000,
-	DMA_CONTROL_TTC_256 = 0x0000c000,
-	DMA_CONTROL_TTC_40 = 0x00010000,
-	DMA_CONTROL_TTC_32 = 0x00014000,
-	DMA_CONTROL_TTC_24 = 0x00018000,
-	DMA_CONTROL_TTC_16 = 0x0001c000,
-};
-#define DMA_CONTROL_TC_TX_MASK	0xfffe3fff
-
-#define DMA_CONTROL_EFC		0x00000100
-#define DMA_CONTROL_FEF		0x00000080
-#define DMA_CONTROL_FUF		0x00000040
-
-enum rtc_control {
-	DMA_CONTROL_RTC_64 = 0x00000000,
-	DMA_CONTROL_RTC_32 = 0x00000008,
-	DMA_CONTROL_RTC_96 = 0x00000010,
-	DMA_CONTROL_RTC_128 = 0x00000018,
-};
-#define DMA_CONTROL_TC_RX_MASK	0xffffffe7
-
-#define DMA_CONTROL_OSF	0x00000004	/* Operate on second frame */
-
-/* MMC registers offset */
-#define GMAC_MMC_CTRL      0x100
-#define GMAC_MMC_RX_INTR   0x104
-#define GMAC_MMC_TX_INTR   0x108
-#define GMAC_MMC_RX_CSUM_OFFLOAD   0x208
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/Kconfig linux-libre-2.6.34-gnu1/drivers/net/stmmac/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -2,10 +2,12 @@ config STMMAC_ETH
 	tristate "STMicroelectronics 10/100/1000 Ethernet driver"
 	select MII
 	select PHYLIB
+	select CRC32
 	depends on NETDEVICES && CPU_SUBTYPE_ST40
 	help
-	  This is the driver for the ST MAC 10/100/1000 on-chip Ethernet
-	  controllers. ST Ethernet IPs are built around a Synopsys IP Core.
+	  This is the driver for the Ethernet IPs are built around a
+	  Synopsys IP Core and fully tested on the STMicroelectronics
+	  platforms.
 
 if STMMAC_ETH
 
@@ -32,7 +34,8 @@ config STMMAC_TIMER
 	default n
 	help
 	  Use an external timer for mitigating the number of network
-	  interrupts.
+	  interrupts. Currently, for SH architectures, it is possible
+	  to use the TMU channel 2 and the SH-RTC device.
 
 choice
         prompt "Select Timer device"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/mac100.c linux-libre-2.6.34-gnu1/drivers/net/stmmac/mac100.c
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/mac100.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/mac100.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,517 +0,0 @@
-/*******************************************************************************
-  This is the driver for the MAC 10/100 on-chip Ethernet controller
-  currently tested on all the ST boards based on STb7109 and stx7200 SoCs.
-
-  DWC Ether MAC 10/100 Universal version 4.0 has been used for developing
-  this code.
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  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".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include <linux/netdevice.h>
-#include <linux/crc32.h>
-#include <linux/mii.h>
-#include <linux/phy.h>
-
-#include "common.h"
-#include "mac100.h"
-
-#undef MAC100_DEBUG
-/*#define MAC100_DEBUG*/
-#ifdef MAC100_DEBUG
-#define DBG(fmt, args...)  printk(fmt, ## args)
-#else
-#define DBG(fmt, args...)  do { } while (0)
-#endif
-
-static void mac100_core_init(unsigned long ioaddr)
-{
-	u32 value = readl(ioaddr + MAC_CONTROL);
-
-	writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
-
-#ifdef STMMAC_VLAN_TAG_USED
-	writel(ETH_P_8021Q, ioaddr + MAC_VLAN1);
-#endif
-	return;
-}
-
-static void mac100_dump_mac_regs(unsigned long ioaddr)
-{
-	pr_info("\t----------------------------------------------\n"
-	       "\t  MAC100 CSR (base addr = 0x%8x)\n"
-	       "\t----------------------------------------------\n",
-	       (unsigned int)ioaddr);
-	pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
-	       readl(ioaddr + MAC_CONTROL));
-	pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
-	       readl(ioaddr + MAC_ADDR_HIGH));
-	pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW,
-	       readl(ioaddr + MAC_ADDR_LOW));
-	pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n",
-			MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH));
-	pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n",
-			MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW));
-	pr_info("\tflow control (offset 0x%x): 0x%08x\n",
-		MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL));
-	pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1,
-	       readl(ioaddr + MAC_VLAN1));
-	pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2,
-	       readl(ioaddr + MAC_VLAN2));
-	pr_info("\n\tMAC management counter registers\n");
-	pr_info("\t MMC crtl (offset 0x%x): 0x%08x\n",
-	       MMC_CONTROL, readl(ioaddr + MMC_CONTROL));
-	pr_info("\t MMC High Interrupt (offset 0x%x): 0x%08x\n",
-	       MMC_HIGH_INTR, readl(ioaddr + MMC_HIGH_INTR));
-	pr_info("\t MMC Low Interrupt (offset 0x%x): 0x%08x\n",
-	       MMC_LOW_INTR, readl(ioaddr + MMC_LOW_INTR));
-	pr_info("\t MMC High Interrupt Mask (offset 0x%x): 0x%08x\n",
-	       MMC_HIGH_INTR_MASK, readl(ioaddr + MMC_HIGH_INTR_MASK));
-	pr_info("\t MMC Low Interrupt Mask (offset 0x%x): 0x%08x\n",
-	       MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
-	return;
-}
-
-static int mac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
-			   u32 dma_rx)
-{
-	u32 value = readl(ioaddr + DMA_BUS_MODE);
-	/* DMA SW reset */
-	value |= DMA_BUS_MODE_SFT_RESET;
-	writel(value, ioaddr + DMA_BUS_MODE);
-	do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
-
-	/* Enable Application Access by writing to DMA CSR0 */
-	writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
-	       ioaddr + DMA_BUS_MODE);
-
-	/* Mask interrupts by writing to CSR7 */
-	writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
-
-	/* The base address of the RX/TX descriptor lists must be written into
-	 * DMA CSR3 and CSR4, respectively. */
-	writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
-	writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
-
-	return 0;
-}
-
-/* Store and Forward capability is not used at all..
- * The transmit threshold can be programmed by
- * setting the TTC bits in the DMA control register.*/
-static void mac100_dma_operation_mode(unsigned long ioaddr, int txmode,
-				      int rxmode)
-{
-	u32 csr6 = readl(ioaddr + DMA_CONTROL);
-
-	if (txmode <= 32)
-		csr6 |= DMA_CONTROL_TTC_32;
-	else if (txmode <= 64)
-		csr6 |= DMA_CONTROL_TTC_64;
-	else
-		csr6 |= DMA_CONTROL_TTC_128;
-
-	writel(csr6, ioaddr + DMA_CONTROL);
-
-	return;
-}
-
-static void mac100_dump_dma_regs(unsigned long ioaddr)
-{
-	int i;
-
-	DBG(KERN_DEBUG "MAC100 DMA CSR \n");
-	for (i = 0; i < 9; i++)
-		pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i,
-		       (DMA_BUS_MODE + i * 4),
-		       readl(ioaddr + DMA_BUS_MODE + i * 4));
-	DBG(KERN_DEBUG "\t CSR20 (offset 0x%x): 0x%08x\n",
-	    DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR));
-	DBG(KERN_DEBUG "\t CSR21 (offset 0x%x): 0x%08x\n",
-	    DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR));
-	return;
-}
-
-/* DMA controller has two counters to track the number of
-   the receive missed frames. */
-static void mac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
-				     unsigned long ioaddr)
-{
-	struct net_device_stats *stats = (struct net_device_stats *)data;
-	u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
-
-	if (unlikely(csr8)) {
-		if (csr8 & DMA_MISSED_FRAME_OVE) {
-			stats->rx_over_errors += 0x800;
-			x->rx_overflow_cntr += 0x800;
-		} else {
-			unsigned int ove_cntr;
-			ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17);
-			stats->rx_over_errors += ove_cntr;
-			x->rx_overflow_cntr += ove_cntr;
-		}
-
-		if (csr8 & DMA_MISSED_FRAME_OVE_M) {
-			stats->rx_missed_errors += 0xffff;
-			x->rx_missed_cntr += 0xffff;
-		} else {
-			unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR);
-			stats->rx_missed_errors += miss_f;
-			x->rx_missed_cntr += miss_f;
-		}
-	}
-	return;
-}
-
-static int mac100_get_tx_frame_status(void *data, struct stmmac_extra_stats *x,
-				      struct dma_desc *p, unsigned long ioaddr)
-{
-	int ret = 0;
-	struct net_device_stats *stats = (struct net_device_stats *)data;
-
-	if (unlikely(p->des01.tx.error_summary)) {
-		if (unlikely(p->des01.tx.underflow_error)) {
-			x->tx_underflow++;
-			stats->tx_fifo_errors++;
-		}
-		if (unlikely(p->des01.tx.no_carrier)) {
-			x->tx_carrier++;
-			stats->tx_carrier_errors++;
-		}
-		if (unlikely(p->des01.tx.loss_carrier)) {
-			x->tx_losscarrier++;
-			stats->tx_carrier_errors++;
-		}
-		if (unlikely((p->des01.tx.excessive_deferral) ||
-			     (p->des01.tx.excessive_collisions) ||
-			     (p->des01.tx.late_collision)))
-			stats->collisions += p->des01.tx.collision_count;
-		ret = -1;
-	}
-	if (unlikely(p->des01.tx.heartbeat_fail)) {
-		x->tx_heartbeat++;
-		stats->tx_heartbeat_errors++;
-		ret = -1;
-	}
-	if (unlikely(p->des01.tx.deferred))
-		x->tx_deferred++;
-
-	return ret;
-}
-
-static int mac100_get_tx_len(struct dma_desc *p)
-{
-	return p->des01.tx.buffer1_size;
-}
-
-/* This function verifies if each incoming frame has some errors
- * and, if required, updates the multicast statistics.
- * In case of success, it returns csum_none becasue the device
- * is not able to compute the csum in HW. */
-static int mac100_get_rx_frame_status(void *data, struct stmmac_extra_stats *x,
-				      struct dma_desc *p)
-{
-	int ret = csum_none;
-	struct net_device_stats *stats = (struct net_device_stats *)data;
-
-	if (unlikely(p->des01.rx.last_descriptor == 0)) {
-		pr_warning("mac100 Error: Oversized Ethernet "
-			   "frame spanned multiple buffers\n");
-		stats->rx_length_errors++;
-		return discard_frame;
-	}
-
-	if (unlikely(p->des01.rx.error_summary)) {
-		if (unlikely(p->des01.rx.descriptor_error))
-			x->rx_desc++;
-		if (unlikely(p->des01.rx.partial_frame_error))
-			x->rx_partial++;
-		if (unlikely(p->des01.rx.run_frame))
-			x->rx_runt++;
-		if (unlikely(p->des01.rx.frame_too_long))
-			x->rx_toolong++;
-		if (unlikely(p->des01.rx.collision)) {
-			x->rx_collision++;
-			stats->collisions++;
-		}
-		if (unlikely(p->des01.rx.crc_error)) {
-			x->rx_crc++;
-			stats->rx_crc_errors++;
-		}
-		ret = discard_frame;
-	}
-	if (unlikely(p->des01.rx.dribbling))
-		ret = discard_frame;
-
-	if (unlikely(p->des01.rx.length_error)) {
-		x->rx_lenght++;
-		ret = discard_frame;
-	}
-	if (unlikely(p->des01.rx.mii_error)) {
-		x->rx_mii++;
-		ret = discard_frame;
-	}
-	if (p->des01.rx.multicast_frame) {
-		x->rx_multicast++;
-		stats->multicast++;
-	}
-	return ret;
-}
-
-static void mac100_irq_status(unsigned long ioaddr)
-{
-	return;
-}
-
-static void mac100_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
-			  unsigned int reg_n)
-{
-	stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
-}
-
-static void mac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
-			  unsigned int reg_n)
-{
-	stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
-}
-
-static void mac100_set_filter(struct net_device *dev)
-{
-	unsigned long ioaddr = dev->base_addr;
-	u32 value = readl(ioaddr + MAC_CONTROL);
-
-	if (dev->flags & IFF_PROMISC) {
-		value |= MAC_CONTROL_PR;
-		value &= ~(MAC_CONTROL_PM | MAC_CONTROL_IF | MAC_CONTROL_HO |
-			   MAC_CONTROL_HP);
-	} else if ((dev->mc_count > HASH_TABLE_SIZE)
-		   || (dev->flags & IFF_ALLMULTI)) {
-		value |= MAC_CONTROL_PM;
-		value &= ~(MAC_CONTROL_PR | MAC_CONTROL_IF | MAC_CONTROL_HO);
-		writel(0xffffffff, ioaddr + MAC_HASH_HIGH);
-		writel(0xffffffff, ioaddr + MAC_HASH_LOW);
-	} else if (dev->mc_count == 0) {	/* no multicast */
-		value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF |
-			   MAC_CONTROL_HO | MAC_CONTROL_HP);
-	} else {
-		int i;
-		u32 mc_filter[2];
-		struct dev_mc_list *mclist;
-
-		/* Perfect filter mode for physical address and Hash
-		   filter for multicast */
-		value |= MAC_CONTROL_HP;
-		value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF
-			   | MAC_CONTROL_HO);
-
-		memset(mc_filter, 0, sizeof(mc_filter));
-		for (i = 0, mclist = dev->mc_list;
-		     mclist && i < dev->mc_count; i++, mclist = mclist->next) {
-			/* The upper 6 bits of the calculated CRC are used to
-			 * index the contens of the hash table */
-			int bit_nr =
-			    ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
-			/* The most significant bit determines the register to
-			 * use (H/L) while the other 5 bits determine the bit
-			 * within the register. */
-			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
-		}
-		writel(mc_filter[0], ioaddr + MAC_HASH_LOW);
-		writel(mc_filter[1], ioaddr + MAC_HASH_HIGH);
-	}
-
-	writel(value, ioaddr + MAC_CONTROL);
-
-	DBG(KERN_INFO "%s: CTRL reg: 0x%08x Hash regs: "
-	    "HI 0x%08x, LO 0x%08x\n",
-	    __func__, readl(ioaddr + MAC_CONTROL),
-	    readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
-	return;
-}
-
-static void mac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
-			     unsigned int fc, unsigned int pause_time)
-{
-	unsigned int flow = MAC_FLOW_CTRL_ENABLE;
-
-	if (duplex)
-		flow |= (pause_time << MAC_FLOW_CTRL_PT_SHIFT);
-	writel(flow, ioaddr + MAC_FLOW_CTRL);
-
-	return;
-}
-
-/* No PMT module supported in our SoC  for the Ethernet Controller. */
-static void mac100_pmt(unsigned long ioaddr, unsigned long mode)
-{
-	return;
-}
-
-static void mac100_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
-				int disable_rx_ic)
-{
-	int i;
-	for (i = 0; i < ring_size; i++) {
-		p->des01.rx.own = 1;
-		p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
-		if (i == ring_size - 1)
-			p->des01.rx.end_ring = 1;
-		if (disable_rx_ic)
-			p->des01.rx.disable_ic = 1;
-		p++;
-	}
-	return;
-}
-
-static void mac100_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
-{
-	int i;
-	for (i = 0; i < ring_size; i++) {
-		p->des01.tx.own = 0;
-		if (i == ring_size - 1)
-			p->des01.tx.end_ring = 1;
-		p++;
-	}
-	return;
-}
-
-static int mac100_get_tx_owner(struct dma_desc *p)
-{
-	return p->des01.tx.own;
-}
-
-static int mac100_get_rx_owner(struct dma_desc *p)
-{
-	return p->des01.rx.own;
-}
-
-static void mac100_set_tx_owner(struct dma_desc *p)
-{
-	p->des01.tx.own = 1;
-}
-
-static void mac100_set_rx_owner(struct dma_desc *p)
-{
-	p->des01.rx.own = 1;
-}
-
-static int mac100_get_tx_ls(struct dma_desc *p)
-{
-	return p->des01.tx.last_segment;
-}
-
-static void mac100_release_tx_desc(struct dma_desc *p)
-{
-	int ter = p->des01.tx.end_ring;
-
-	/* clean field used within the xmit */
-	p->des01.tx.first_segment = 0;
-	p->des01.tx.last_segment = 0;
-	p->des01.tx.buffer1_size = 0;
-
-	/* clean status reported */
-	p->des01.tx.error_summary = 0;
-	p->des01.tx.underflow_error = 0;
-	p->des01.tx.no_carrier = 0;
-	p->des01.tx.loss_carrier = 0;
-	p->des01.tx.excessive_deferral = 0;
-	p->des01.tx.excessive_collisions = 0;
-	p->des01.tx.late_collision = 0;
-	p->des01.tx.heartbeat_fail = 0;
-	p->des01.tx.deferred = 0;
-
-	/* set termination field */
-	p->des01.tx.end_ring = ter;
-
-	return;
-}
-
-static void mac100_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
-				   int csum_flag)
-{
-	p->des01.tx.first_segment = is_fs;
-	p->des01.tx.buffer1_size = len;
-}
-
-static void mac100_clear_tx_ic(struct dma_desc *p)
-{
-	p->des01.tx.interrupt = 0;
-}
-
-static void mac100_close_tx_desc(struct dma_desc *p)
-{
-	p->des01.tx.last_segment = 1;
-	p->des01.tx.interrupt = 1;
-}
-
-static int mac100_get_rx_frame_len(struct dma_desc *p)
-{
-	return p->des01.rx.frame_length;
-}
-
-struct stmmac_ops mac100_driver = {
-	.core_init = mac100_core_init,
-	.dump_mac_regs = mac100_dump_mac_regs,
-	.dma_init = mac100_dma_init,
-	.dump_dma_regs = mac100_dump_dma_regs,
-	.dma_mode = mac100_dma_operation_mode,
-	.dma_diagnostic_fr = mac100_dma_diagnostic_fr,
-	.tx_status = mac100_get_tx_frame_status,
-	.rx_status = mac100_get_rx_frame_status,
-	.get_tx_len = mac100_get_tx_len,
-	.set_filter = mac100_set_filter,
-	.flow_ctrl = mac100_flow_ctrl,
-	.pmt = mac100_pmt,
-	.init_rx_desc = mac100_init_rx_desc,
-	.init_tx_desc = mac100_init_tx_desc,
-	.get_tx_owner = mac100_get_tx_owner,
-	.get_rx_owner = mac100_get_rx_owner,
-	.release_tx_desc = mac100_release_tx_desc,
-	.prepare_tx_desc = mac100_prepare_tx_desc,
-	.clear_tx_ic = mac100_clear_tx_ic,
-	.close_tx_desc = mac100_close_tx_desc,
-	.get_tx_ls = mac100_get_tx_ls,
-	.set_tx_owner = mac100_set_tx_owner,
-	.set_rx_owner = mac100_set_rx_owner,
-	.get_rx_frame_len = mac100_get_rx_frame_len,
-	.host_irq_status = mac100_irq_status,
-	.set_umac_addr = mac100_set_umac_addr,
-	.get_umac_addr = mac100_get_umac_addr,
-};
-
-struct mac_device_info *mac100_setup(unsigned long ioaddr)
-{
-	struct mac_device_info *mac;
-
-	mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
-
-	pr_info("\tMAC 10/100\n");
-
-	mac->ops = &mac100_driver;
-	mac->hw.pmt = PMT_NOT_SUPPORTED;
-	mac->hw.link.port = MAC_CONTROL_PS;
-	mac->hw.link.duplex = MAC_CONTROL_F;
-	mac->hw.link.speed = 0;
-	mac->hw.mii.addr = MAC_MII_ADDR;
-	mac->hw.mii.data = MAC_MII_DATA;
-
-	return mac;
-}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/mac100.h linux-libre-2.6.34-gnu1/drivers/net/stmmac/mac100.h
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/mac100.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/mac100.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,116 +0,0 @@
-/*******************************************************************************
-  MAC 10/100 Header File
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  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".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-/*----------------------------------------------------------------------------
- *	 			MAC BLOCK defines
- *---------------------------------------------------------------------------*/
-/* MAC CSR offset */
-#define MAC_CONTROL	0x00000000	/* MAC Control */
-#define MAC_ADDR_HIGH	0x00000004	/* MAC Address High */
-#define MAC_ADDR_LOW	0x00000008	/* MAC Address Low */
-#define MAC_HASH_HIGH	0x0000000c	/* Multicast Hash Table High */
-#define MAC_HASH_LOW	0x00000010	/* Multicast Hash Table Low */
-#define MAC_MII_ADDR	0x00000014	/* MII Address */
-#define MAC_MII_DATA	0x00000018	/* MII Data */
-#define MAC_FLOW_CTRL	0x0000001c	/* Flow Control */
-#define MAC_VLAN1	0x00000020	/* VLAN1 Tag */
-#define MAC_VLAN2	0x00000024	/* VLAN2 Tag */
-
-/* MAC CTRL defines */
-#define MAC_CONTROL_RA	0x80000000	/* Receive All Mode */
-#define MAC_CONTROL_BLE	0x40000000	/* Endian Mode */
-#define MAC_CONTROL_HBD	0x10000000	/* Heartbeat Disable */
-#define MAC_CONTROL_PS	0x08000000	/* Port Select */
-#define MAC_CONTROL_DRO	0x00800000	/* Disable Receive Own */
-#define MAC_CONTROL_EXT_LOOPBACK 0x00400000	/* Reserved (ext loopback?) */
-#define MAC_CONTROL_OM	0x00200000	/* Loopback Operating Mode */
-#define MAC_CONTROL_F	0x00100000	/* Full Duplex Mode */
-#define MAC_CONTROL_PM	0x00080000	/* Pass All Multicast */
-#define MAC_CONTROL_PR	0x00040000	/* Promiscuous Mode */
-#define MAC_CONTROL_IF	0x00020000	/* Inverse Filtering */
-#define MAC_CONTROL_PB	0x00010000	/* Pass Bad Frames */
-#define MAC_CONTROL_HO	0x00008000	/* Hash Only Filtering Mode */
-#define MAC_CONTROL_HP	0x00002000	/* Hash/Perfect Filtering Mode */
-#define MAC_CONTROL_LCC	0x00001000	/* Late Collision Control */
-#define MAC_CONTROL_DBF	0x00000800	/* Disable Broadcast Frames */
-#define MAC_CONTROL_DRTY	0x00000400	/* Disable Retry */
-#define MAC_CONTROL_ASTP	0x00000100	/* Automatic Pad Stripping */
-#define MAC_CONTROL_BOLMT_10	0x00000000	/* Back Off Limit 10 */
-#define MAC_CONTROL_BOLMT_8	0x00000040	/* Back Off Limit 8 */
-#define MAC_CONTROL_BOLMT_4	0x00000080	/* Back Off Limit 4 */
-#define MAC_CONTROL_BOLMT_1	0x000000c0	/* Back Off Limit 1 */
-#define MAC_CONTROL_DC		0x00000020	/* Deferral Check */
-#define MAC_CONTROL_TE		0x00000008	/* Transmitter Enable */
-#define MAC_CONTROL_RE		0x00000004	/* Receiver Enable */
-
-#define MAC_CORE_INIT (MAC_CONTROL_HBD | MAC_CONTROL_ASTP)
-
-/* MAC FLOW CTRL defines */
-#define MAC_FLOW_CTRL_PT_MASK	0xffff0000	/* Pause Time Mask */
-#define MAC_FLOW_CTRL_PT_SHIFT	16
-#define MAC_FLOW_CTRL_PASS	0x00000004	/* Pass Control Frames */
-#define MAC_FLOW_CTRL_ENABLE	0x00000002	/* Flow Control Enable */
-#define MAC_FLOW_CTRL_PAUSE	0x00000001	/* Flow Control Busy ... */
-
-/* MII ADDR  defines */
-#define MAC_MII_ADDR_WRITE	0x00000002	/* MII Write */
-#define MAC_MII_ADDR_BUSY	0x00000001	/* MII Busy */
-
-/*----------------------------------------------------------------------------
- * 				DMA BLOCK defines
- *---------------------------------------------------------------------------*/
-
-/* DMA Bus Mode register defines */
-#define DMA_BUS_MODE_DBO	0x00100000	/* Descriptor Byte Ordering */
-#define DMA_BUS_MODE_BLE	0x00000080	/* Big Endian/Little Endian */
-#define DMA_BUS_MODE_PBL_MASK	0x00003f00	/* Programmable Burst Len */
-#define DMA_BUS_MODE_PBL_SHIFT	8
-#define DMA_BUS_MODE_DSL_MASK	0x0000007c	/* Descriptor Skip Length */
-#define DMA_BUS_MODE_DSL_SHIFT	2	/*   (in DWORDS)      */
-#define DMA_BUS_MODE_BAR_BUS	0x00000002	/* Bar-Bus Arbitration */
-#define DMA_BUS_MODE_SFT_RESET	0x00000001	/* Software Reset */
-#define DMA_BUS_MODE_DEFAULT	0x00000000
-
-/* DMA Control register defines */
-#define DMA_CONTROL_SF		0x00200000	/* Store And Forward */
-
-/* Transmit Threshold Control */
-enum ttc_control {
-	DMA_CONTROL_TTC_DEFAULT = 0x00000000,	/* Threshold is 32 DWORDS */
-	DMA_CONTROL_TTC_64 = 0x00004000,	/* Threshold is 64 DWORDS */
-	DMA_CONTROL_TTC_128 = 0x00008000,	/* Threshold is 128 DWORDS */
-	DMA_CONTROL_TTC_256 = 0x0000c000,	/* Threshold is 256 DWORDS */
-	DMA_CONTROL_TTC_18 = 0x00400000,	/* Threshold is 18 DWORDS */
-	DMA_CONTROL_TTC_24 = 0x00404000,	/* Threshold is 24 DWORDS */
-	DMA_CONTROL_TTC_32 = 0x00408000,	/* Threshold is 32 DWORDS */
-	DMA_CONTROL_TTC_40 = 0x0040c000,	/* Threshold is 40 DWORDS */
-	DMA_CONTROL_SE = 0x00000008,	/* Stop On Empty */
-	DMA_CONTROL_OSF = 0x00000004,	/* Operate On 2nd Frame */
-};
-
-/* STMAC110 DMA Missed Frame Counter register defines */
-#define DMA_MISSED_FRAME_OVE	0x10000000	/* FIFO Overflow Overflow */
-#define DMA_MISSED_FRAME_OVE_CNTR 0x0ffe0000	/* Overflow Frame Counter */
-#define DMA_MISSED_FRAME_OVE_M	0x00010000	/* Missed Frame Overflow */
-#define DMA_MISSED_FRAME_M_CNTR	0x0000ffff	/* Missed Frame Couinter */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/Makefile linux-libre-2.6.34-gnu1/drivers/net/stmmac/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,5 @@
 obj-$(CONFIG_STMMAC_ETH) += stmmac.o
 stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
-stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \
-		mac100.o  gmac.o $(stmmac-y)
+stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o	\
+	      dwmac_lib.o dwmac1000_core.o  dwmac1000_dma.o	\
+	      dwmac100.o $(stmmac-y)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/stmmac_ethtool.c linux-libre-2.6.34-gnu1/drivers/net/stmmac/stmmac_ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/stmmac_ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/stmmac_ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/phy.h>
 
 #include "stmmac.h"
+#include "dwmac_dma.h"
 
 #define REG_SPACE_SIZE	0x1054
 #define MAC100_ETHTOOL_NAME	"st_mac100"
@@ -61,7 +62,7 @@ static const struct  stmmac_stats stmmac
 	STMMAC_STAT(rx_toolong),
 	STMMAC_STAT(rx_collision),
 	STMMAC_STAT(rx_crc),
-	STMMAC_STAT(rx_lenght),
+	STMMAC_STAT(rx_length),
 	STMMAC_STAT(rx_mii),
 	STMMAC_STAT(rx_multicast),
 	STMMAC_STAT(rx_gmac_overflow),
@@ -268,8 +269,8 @@ stmmac_set_pauseparam(struct net_device
 		}
 	} else {
 		unsigned long ioaddr = netdev->base_addr;
-		priv->mac_type->ops->flow_ctrl(ioaddr, phy->duplex,
-					       priv->flow_ctrl, priv->pause);
+		priv->hw->mac->flow_ctrl(ioaddr, phy->duplex,
+					 priv->flow_ctrl, priv->pause);
 	}
 	spin_unlock(&priv->lock);
 	return ret;
@@ -283,8 +284,8 @@ static void stmmac_get_ethtool_stats(str
 	int i;
 
 	/* Update HW stats if supported */
-	priv->mac_type->ops->dma_diagnostic_fr(&dev->stats, &priv->xstats,
-					       ioaddr);
+	priv->hw->dma->dma_diagnostic_fr(&dev->stats, (void *) &priv->xstats,
+					 ioaddr);
 
 	for (i = 0; i < STMMAC_STATS_LEN; i++) {
 		char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/stmmac.h linux-libre-2.6.34-gnu1/drivers/net/stmmac/stmmac.h
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/stmmac.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/stmmac.h	2010-05-16 17:17:36.000000000 -0400
@@ -20,7 +20,8 @@
   Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
 *******************************************************************************/
 
-#define DRV_MODULE_VERSION	"Oct_09"
+#define DRV_MODULE_VERSION	"Jan_2010"
+#include <linux/stmmac.h>
 
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 #define STMMAC_VLAN_TAG_USED
@@ -57,7 +58,7 @@ struct stmmac_priv {
 	int rx_csum;
 	unsigned int dma_buf_sz;
 	struct device *device;
-	struct mac_device_info *mac_type;
+	struct mac_device_info *hw;
 
 	struct stmmac_extra_stats xstats;
 	struct napi_struct napi;
@@ -69,6 +70,7 @@ struct stmmac_priv {
 	int phy_mask;
 	int (*phy_reset) (void *priv);
 	void (*fix_mac_speed) (void *priv, unsigned int speed);
+	void (*bus_setup)(unsigned long ioaddr);
 	void *bsp_priv;
 
 	int phy_irq;
@@ -93,6 +95,28 @@ struct stmmac_priv {
 #endif
 };
 
+#ifdef CONFIG_STM_DRIVERS
+#include <linux/stm/pad.h>
+static inline int stmmac_claim_resource(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct plat_stmmacenet_data *plat_dat = pdev->dev.platform_data;
+
+	/* Pad routing setup */
+	if (IS_ERR(devm_stm_pad_claim(&pdev->dev, plat_dat->pad_config,
+			dev_name(&pdev->dev)))) {
+		printk(KERN_ERR "%s: Failed to request pads!\n", __func__);
+		ret = -ENODEV;
+	}
+	return ret;
+}
+#else
+static inline int stmmac_claim_resource(struct platform_device *pdev)
+{
+	return 0;
+}
+#endif
+
 extern int stmmac_mdio_unregister(struct net_device *ndev);
 extern int stmmac_mdio_register(struct net_device *ndev);
 extern void stmmac_set_ethtool_ops(struct net_device *netdev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/stmmac_main.c linux-libre-2.6.34-gnu1/drivers/net/stmmac/stmmac_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/stmmac_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/stmmac_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/platform_device.h>
 #include <linux/ip.h>
@@ -45,7 +44,7 @@
 #include <linux/phy.h>
 #include <linux/if_vlan.h>
 #include <linux/dma-mapping.h>
-#include <linux/stm/soc.h>
+#include <linux/slab.h>
 #include "stmmac.h"
 
 #define STMMAC_RESOURCE_NAME	"stmmaceth"
@@ -226,41 +225,38 @@ static void stmmac_adjust_link(struct ne
 		if (phydev->duplex != priv->oldduplex) {
 			new_state = 1;
 			if (!(phydev->duplex))
-				ctrl &= ~priv->mac_type->hw.link.duplex;
+				ctrl &= ~priv->hw->link.duplex;
 			else
-				ctrl |= priv->mac_type->hw.link.duplex;
+				ctrl |= priv->hw->link.duplex;
 			priv->oldduplex = phydev->duplex;
 		}
 		/* Flow Control operation */
 		if (phydev->pause)
-			priv->mac_type->ops->flow_ctrl(ioaddr, phydev->duplex,
-						       fc, pause_time);
+			priv->hw->mac->flow_ctrl(ioaddr, phydev->duplex,
+						 fc, pause_time);
 
 		if (phydev->speed != priv->speed) {
 			new_state = 1;
 			switch (phydev->speed) {
 			case 1000:
 				if (likely(priv->is_gmac))
-					ctrl &= ~priv->mac_type->hw.link.port;
+					ctrl &= ~priv->hw->link.port;
 				break;
 			case 100:
 			case 10:
 				if (priv->is_gmac) {
-					ctrl |= priv->mac_type->hw.link.port;
+					ctrl |= priv->hw->link.port;
 					if (phydev->speed == SPEED_100) {
-						ctrl |=
-						    priv->mac_type->hw.link.
-						    speed;
+						ctrl |= priv->hw->link.speed;
 					} else {
-						ctrl &=
-						    ~(priv->mac_type->hw.
-						      link.speed);
+						ctrl &= ~(priv->hw->link.speed);
 					}
 				} else {
-					ctrl &= ~priv->mac_type->hw.link.port;
+					ctrl &= ~priv->hw->link.port;
 				}
-				priv->fix_mac_speed(priv->bsp_priv,
-						    phydev->speed);
+				if (likely(priv->fix_mac_speed))
+					priv->fix_mac_speed(priv->bsp_priv,
+							    phydev->speed);
 				break;
 			default:
 				if (netif_msg_link(priv))
@@ -305,8 +301,8 @@ static int stmmac_init_phy(struct net_de
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
 	struct phy_device *phydev;
-	char phy_id[BUS_ID_SIZE];	/* PHY to connect */
-	char bus_id[BUS_ID_SIZE];
+	char phy_id[MII_BUS_ID_SIZE + 3];
+	char bus_id[MII_BUS_ID_SIZE];
 
 	priv->oldlink = 0;
 	priv->speed = 0;
@@ -318,7 +314,8 @@ static int stmmac_init_phy(struct net_de
 	}
 
 	snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->bus_id);
-	snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, bus_id, priv->phy_addr);
+	snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
+		 priv->phy_addr);
 	pr_debug("stmmac_init_phy:  trying to attach to %s\n", phy_id);
 
 	phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0,
@@ -508,8 +505,8 @@ static void init_dma_desc_rings(struct n
 	priv->cur_tx = 0;
 
 	/* Clear the Rx/Tx descriptors */
-	priv->mac_type->ops->init_rx_desc(priv->dma_rx, rxsize, dis_ic);
-	priv->mac_type->ops->init_tx_desc(priv->dma_tx, txsize);
+	priv->hw->desc->init_rx_desc(priv->dma_rx, rxsize, dis_ic);
+	priv->hw->desc->init_tx_desc(priv->dma_tx, txsize);
 
 	if (netif_msg_hw(priv)) {
 		pr_info("RX descriptor ring:\n");
@@ -544,8 +541,8 @@ static void dma_free_tx_skbufs(struct st
 			struct dma_desc *p = priv->dma_tx + i;
 			if (p->des2)
 				dma_unmap_single(priv->device, p->des2,
-				 priv->mac_type->ops->get_tx_len(p),
-				 DMA_TO_DEVICE);
+						 priv->hw->desc->get_tx_len(p),
+						 DMA_TO_DEVICE);
 			dev_kfree_skb_any(priv->tx_skbuff[i]);
 			priv->tx_skbuff[i] = NULL;
 		}
@@ -575,50 +572,6 @@ static void free_dma_desc_resources(stru
 }
 
 /**
- * stmmac_dma_start_tx
- * @ioaddr: device I/O address
- * Description:  this function starts the DMA tx process.
- */
-static void stmmac_dma_start_tx(unsigned long ioaddr)
-{
-	u32 value = readl(ioaddr + DMA_CONTROL);
-	value |= DMA_CONTROL_ST;
-	writel(value, ioaddr + DMA_CONTROL);
-	return;
-}
-
-static void stmmac_dma_stop_tx(unsigned long ioaddr)
-{
-	u32 value = readl(ioaddr + DMA_CONTROL);
-	value &= ~DMA_CONTROL_ST;
-	writel(value, ioaddr + DMA_CONTROL);
-	return;
-}
-
-/**
- * stmmac_dma_start_rx
- * @ioaddr: device I/O address
- * Description:  this function starts the DMA rx process.
- */
-static void stmmac_dma_start_rx(unsigned long ioaddr)
-{
-	u32 value = readl(ioaddr + DMA_CONTROL);
-	value |= DMA_CONTROL_SR;
-	writel(value, ioaddr + DMA_CONTROL);
-
-	return;
-}
-
-static void stmmac_dma_stop_rx(unsigned long ioaddr)
-{
-	u32 value = readl(ioaddr + DMA_CONTROL);
-	value &= ~DMA_CONTROL_SR;
-	writel(value, ioaddr + DMA_CONTROL);
-
-	return;
-}
-
-/**
  *  stmmac_dma_operation_mode - HW DMA operation mode
  *  @priv : pointer to the private device structure.
  *  Description: it sets the DMA operation mode: tx/rx DMA thresholds
@@ -629,18 +582,18 @@ static void stmmac_dma_operation_mode(st
 {
 	if (!priv->is_gmac) {
 		/* MAC 10/100 */
-		priv->mac_type->ops->dma_mode(priv->dev->base_addr, tc, 0);
+		priv->hw->dma->dma_mode(priv->dev->base_addr, tc, 0);
 		priv->tx_coe = NO_HW_CSUM;
 	} else {
 		if ((priv->dev->mtu <= ETH_DATA_LEN) && (tx_coe)) {
-			priv->mac_type->ops->dma_mode(priv->dev->base_addr,
-						      SF_DMA_MODE, SF_DMA_MODE);
+			priv->hw->dma->dma_mode(priv->dev->base_addr,
+						SF_DMA_MODE, SF_DMA_MODE);
 			tc = SF_DMA_MODE;
 			priv->tx_coe = HW_CSUM;
 		} else {
 			/* Checksum computation is performed in software. */
-			priv->mac_type->ops->dma_mode(priv->dev->base_addr, tc,
-						      SF_DMA_MODE);
+			priv->hw->dma->dma_mode(priv->dev->base_addr, tc,
+						SF_DMA_MODE);
 			priv->tx_coe = NO_HW_CSUM;
 		}
 	}
@@ -649,88 +602,6 @@ static void stmmac_dma_operation_mode(st
 	return;
 }
 
-#ifdef STMMAC_DEBUG
-/**
- * show_tx_process_state
- * @status: tx descriptor status field
- * Description: it shows the Transmit Process State for CSR5[22:20]
- */
-static void show_tx_process_state(unsigned int status)
-{
-	unsigned int state;
-	state = (status & DMA_STATUS_TS_MASK) >> DMA_STATUS_TS_SHIFT;
-
-	switch (state) {
-	case 0:
-		pr_info("- TX (Stopped): Reset or Stop command\n");
-		break;
-	case 1:
-		pr_info("- TX (Running):Fetching the Tx desc\n");
-		break;
-	case 2:
-		pr_info("- TX (Running): Waiting for end of tx\n");
-		break;
-	case 3:
-		pr_info("- TX (Running): Reading the data "
-		       "and queuing the data into the Tx buf\n");
-		break;
-	case 6:
-		pr_info("- TX (Suspended): Tx Buff Underflow "
-		       "or an unavailable Transmit descriptor\n");
-		break;
-	case 7:
-		pr_info("- TX (Running): Closing Tx descriptor\n");
-		break;
-	default:
-		break;
-	}
-	return;
-}
-
-/**
- * show_rx_process_state
- * @status: rx descriptor status field
- * Description: it shows the  Receive Process State for CSR5[19:17]
- */
-static void show_rx_process_state(unsigned int status)
-{
-	unsigned int state;
-	state = (status & DMA_STATUS_RS_MASK) >> DMA_STATUS_RS_SHIFT;
-
-	switch (state) {
-	case 0:
-		pr_info("- RX (Stopped): Reset or Stop command\n");
-		break;
-	case 1:
-		pr_info("- RX (Running): Fetching the Rx desc\n");
-		break;
-	case 2:
-		pr_info("- RX (Running):Checking for end of pkt\n");
-		break;
-	case 3:
-		pr_info("- RX (Running): Waiting for Rx pkt\n");
-		break;
-	case 4:
-		pr_info("- RX (Suspended): Unavailable Rx buf\n");
-		break;
-	case 5:
-		pr_info("- RX (Running): Closing Rx descriptor\n");
-		break;
-	case 6:
-		pr_info("- RX(Running): Flushing the current frame"
-		       " from the Rx buf\n");
-		break;
-	case 7:
-		pr_info("- RX (Running): Queuing the Rx frame"
-		       " from the Rx buf into memory\n");
-		break;
-	default:
-		break;
-	}
-	return;
-}
-#endif
-
 /**
  * stmmac_tx:
  * @priv: private driver structure
@@ -748,16 +619,16 @@ static void stmmac_tx(struct stmmac_priv
 		struct dma_desc *p = priv->dma_tx + entry;
 
 		/* Check if the descriptor is owned by the DMA. */
-		if (priv->mac_type->ops->get_tx_owner(p))
+		if (priv->hw->desc->get_tx_owner(p))
 			break;
 
 		/* Verify tx error by looking at the last segment */
-		last = priv->mac_type->ops->get_tx_ls(p);
+		last = priv->hw->desc->get_tx_ls(p);
 		if (likely(last)) {
 			int tx_error =
-			    priv->mac_type->ops->tx_status(&priv->dev->stats,
-							   &priv->xstats,
-							   p, ioaddr);
+				priv->hw->desc->tx_status(&priv->dev->stats,
+							  &priv->xstats, p,
+							  ioaddr);
 			if (likely(tx_error == 0)) {
 				priv->dev->stats.tx_packets++;
 				priv->xstats.tx_pkt_n++;
@@ -769,7 +640,7 @@ static void stmmac_tx(struct stmmac_priv
 
 		if (likely(p->des2))
 			dma_unmap_single(priv->device, p->des2,
-					 priv->mac_type->ops->get_tx_len(p),
+					 priv->hw->desc->get_tx_len(p),
 					 DMA_TO_DEVICE);
 		if (unlikely(p->des3))
 			p->des3 = 0;
@@ -790,7 +661,7 @@ static void stmmac_tx(struct stmmac_priv
 			priv->tx_skbuff[entry] = NULL;
 		}
 
-		priv->mac_type->ops->release_tx_desc(p);
+		priv->hw->desc->release_tx_desc(p);
 
 		entry = (++priv->dirty_tx) % txsize;
 	}
@@ -814,7 +685,7 @@ static inline void stmmac_enable_irq(str
 		priv->tm->timer_start(tmrate);
 	else
 #endif
-	writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA);
+		priv->hw->dma->enable_dma_irq(priv->dev->base_addr);
 }
 
 static inline void stmmac_disable_irq(struct stmmac_priv *priv)
@@ -824,7 +695,7 @@ static inline void stmmac_disable_irq(st
 		priv->tm->timer_stop();
 	else
 #endif
-	writel(0, priv->dev->base_addr + DMA_INTR_ENA);
+		priv->hw->dma->disable_dma_irq(priv->dev->base_addr);
 }
 
 static int stmmac_has_work(struct stmmac_priv *priv)
@@ -832,7 +703,7 @@ static int stmmac_has_work(struct stmmac
 	unsigned int has_work = 0;
 	int rxret, tx_work = 0;
 
-	rxret = priv->mac_type->ops->get_rx_owner(priv->dma_rx +
+	rxret = priv->hw->desc->get_rx_owner(priv->dma_rx +
 		(priv->cur_rx % priv->dma_rx_size));
 
 	if (priv->dirty_tx != priv->cur_tx)
@@ -883,12 +754,12 @@ static void stmmac_tx_err(struct stmmac_
 {
 	netif_stop_queue(priv->dev);
 
-	stmmac_dma_stop_tx(priv->dev->base_addr);
+	priv->hw->dma->stop_tx(priv->dev->base_addr);
 	dma_free_tx_skbufs(priv);
-	priv->mac_type->ops->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
+	priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
 	priv->dirty_tx = 0;
 	priv->cur_tx = 0;
-	stmmac_dma_start_tx(priv->dev->base_addr);
+	priv->hw->dma->start_tx(priv->dev->base_addr);
 
 	priv->dev->stats.tx_errors++;
 	netif_wake_queue(priv->dev);
@@ -896,95 +767,27 @@ static void stmmac_tx_err(struct stmmac_
 	return;
 }
 
-/**
- * stmmac_dma_interrupt - Interrupt handler for the driver
- * @dev: net device structure
- * Description: Interrupt handler for the driver (DMA).
- */
-static void stmmac_dma_interrupt(struct net_device *dev)
+
+static void stmmac_dma_interrupt(struct stmmac_priv *priv)
 {
-	unsigned long ioaddr = dev->base_addr;
-	struct stmmac_priv *priv = netdev_priv(dev);
-	/* read the status register (CSR5) */
-	u32 intr_status = readl(ioaddr + DMA_STATUS);
+	unsigned long ioaddr = priv->dev->base_addr;
+	int status;
 
-	DBG(intr, INFO, "%s: [CSR5: 0x%08x]\n", __func__, intr_status);
+	status = priv->hw->dma->dma_interrupt(priv->dev->base_addr,
+					      &priv->xstats);
+	if (likely(status == handle_tx_rx))
+		_stmmac_schedule(priv);
 
-#ifdef STMMAC_DEBUG
-	/* It displays the DMA transmit process state (CSR5 register) */
-	if (netif_msg_tx_done(priv))
-		show_tx_process_state(intr_status);
-	if (netif_msg_rx_status(priv))
-		show_rx_process_state(intr_status);
-#endif
-	/* ABNORMAL interrupts */
-	if (unlikely(intr_status & DMA_STATUS_AIS)) {
-		DBG(intr, INFO, "CSR5[15] DMA ABNORMAL IRQ: ");
-		if (unlikely(intr_status & DMA_STATUS_UNF)) {
-			DBG(intr, INFO, "transmit underflow\n");
-			if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) {
-				/* Try to bump up the threshold */
-				tc += 64;
-				priv->mac_type->ops->dma_mode(ioaddr, tc,
-					      SF_DMA_MODE);
-				priv->xstats.threshold = tc;
-			}
-			stmmac_tx_err(priv);
-			priv->xstats.tx_undeflow_irq++;
-		}
-		if (unlikely(intr_status & DMA_STATUS_TJT)) {
-			DBG(intr, INFO, "transmit jabber\n");
-			priv->xstats.tx_jabber_irq++;
-		}
-		if (unlikely(intr_status & DMA_STATUS_OVF)) {
-			DBG(intr, INFO, "recv overflow\n");
-			priv->xstats.rx_overflow_irq++;
-		}
-		if (unlikely(intr_status & DMA_STATUS_RU)) {
-			DBG(intr, INFO, "receive buffer unavailable\n");
-			priv->xstats.rx_buf_unav_irq++;
-		}
-		if (unlikely(intr_status & DMA_STATUS_RPS)) {
-			DBG(intr, INFO, "receive process stopped\n");
-			priv->xstats.rx_process_stopped_irq++;
-		}
-		if (unlikely(intr_status & DMA_STATUS_RWT)) {
-			DBG(intr, INFO, "receive watchdog\n");
-			priv->xstats.rx_watchdog_irq++;
-		}
-		if (unlikely(intr_status & DMA_STATUS_ETI)) {
-			DBG(intr, INFO, "transmit early interrupt\n");
-			priv->xstats.tx_early_irq++;
-		}
-		if (unlikely(intr_status & DMA_STATUS_TPS)) {
-			DBG(intr, INFO, "transmit process stopped\n");
-			priv->xstats.tx_process_stopped_irq++;
-			stmmac_tx_err(priv);
-		}
-		if (unlikely(intr_status & DMA_STATUS_FBI)) {
-			DBG(intr, INFO, "fatal bus error\n");
-			priv->xstats.fatal_bus_error_irq++;
-			stmmac_tx_err(priv);
+	else if (unlikely(status == tx_hard_error_bump_tc)) {
+		/* Try to bump up the dma threshold on this failure */
+		if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) {
+			tc += 64;
+			priv->hw->dma->dma_mode(ioaddr, tc, SF_DMA_MODE);
+			priv->xstats.threshold = tc;
 		}
-	}
-
-	/* TX/RX NORMAL interrupts */
-	if (intr_status & DMA_STATUS_NIS) {
-		priv->xstats.normal_irq_n++;
-		if (likely((intr_status & DMA_STATUS_RI) ||
-			 (intr_status & (DMA_STATUS_TI))))
-				_stmmac_schedule(priv);
-	}
-
-	/* Optional hardware blocks, interrupts should be disabled */
-	if (unlikely(intr_status &
-		     (DMA_STATUS_GPI | DMA_STATUS_GMI | DMA_STATUS_GLI)))
-		pr_info("%s: unexpected status %08x\n", __func__, intr_status);
-
-	/* Clear the interrupt by writing a logic 1 to the CSR5[15-0] */
-	writel((intr_status & 0x1ffff), ioaddr + DMA_STATUS);
-
-	DBG(intr, INFO, "\n\n");
+		stmmac_tx_err(priv);
+	} else if (unlikely(status == tx_hard_error))
+		stmmac_tx_err(priv);
 
 	return;
 }
@@ -1058,17 +861,20 @@ static int stmmac_open(struct net_device
 	init_dma_desc_rings(dev);
 
 	/* DMA initialization and SW reset */
-	if (unlikely(priv->mac_type->ops->dma_init(ioaddr,
-		priv->pbl, priv->dma_tx_phy, priv->dma_rx_phy) < 0)) {
+	if (unlikely(priv->hw->dma->init(ioaddr, priv->pbl, priv->dma_tx_phy,
+					 priv->dma_rx_phy) < 0)) {
 
 		pr_err("%s: DMA initialization failed\n", __func__);
 		return -1;
 	}
 
 	/* Copy the MAC addr into the HW  */
-	priv->mac_type->ops->set_umac_addr(ioaddr, dev->dev_addr, 0);
+	priv->hw->mac->set_umac_addr(ioaddr, dev->dev_addr, 0);
+	/* If required, perform hw setup of the bus. */
+	if (priv->bus_setup)
+		priv->bus_setup(ioaddr);
 	/* Initialize the MAC Core */
-	priv->mac_type->ops->core_init(ioaddr);
+	priv->hw->mac->core_init(ioaddr);
 
 	priv->shutdown = 0;
 
@@ -1089,16 +895,16 @@ static int stmmac_open(struct net_device
 
 	/* Start the ball rolling... */
 	DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
-	stmmac_dma_start_tx(ioaddr);
-	stmmac_dma_start_rx(ioaddr);
+	priv->hw->dma->start_tx(ioaddr);
+	priv->hw->dma->start_rx(ioaddr);
 
 #ifdef CONFIG_STMMAC_TIMER
 	priv->tm->timer_start(tmrate);
 #endif
 	/* Dump DMA/MAC registers */
 	if (netif_msg_hw(priv)) {
-		priv->mac_type->ops->dump_mac_regs(ioaddr);
-		priv->mac_type->ops->dump_dma_regs(ioaddr);
+		priv->hw->mac->dump_regs(ioaddr);
+		priv->hw->dma->dump_regs(ioaddr);
 	}
 
 	if (priv->phydev)
@@ -1142,8 +948,8 @@ static int stmmac_release(struct net_dev
 	free_irq(dev->irq, dev);
 
 	/* Stop TX/RX DMA and clear the descriptors */
-	stmmac_dma_stop_tx(dev->base_addr);
-	stmmac_dma_stop_rx(dev->base_addr);
+	priv->hw->dma->stop_tx(dev->base_addr);
+	priv->hw->dma->stop_rx(dev->base_addr);
 
 	/* Release and free the Rx/Tx resources */
 	free_dma_desc_resources(priv);
@@ -1214,8 +1020,8 @@ static unsigned int stmmac_handle_jumbo_
 		desc->des2 = dma_map_single(priv->device, skb->data,
 					    BUF_SIZE_8KiB, DMA_TO_DEVICE);
 		desc->des3 = desc->des2 + BUF_SIZE_4KiB;
-		priv->mac_type->ops->prepare_tx_desc(desc, 1, BUF_SIZE_8KiB,
-						     csum_insertion);
+		priv->hw->desc->prepare_tx_desc(desc, 1, BUF_SIZE_8KiB,
+						csum_insertion);
 
 		entry = (++priv->cur_tx) % txsize;
 		desc = priv->dma_tx + entry;
@@ -1224,16 +1030,16 @@ static unsigned int stmmac_handle_jumbo_
 					skb->data + BUF_SIZE_8KiB,
 					buf2_size, DMA_TO_DEVICE);
 		desc->des3 = desc->des2 + BUF_SIZE_4KiB;
-		priv->mac_type->ops->prepare_tx_desc(desc, 0,
-						     buf2_size, csum_insertion);
-		priv->mac_type->ops->set_tx_owner(desc);
+		priv->hw->desc->prepare_tx_desc(desc, 0, buf2_size,
+						csum_insertion);
+		priv->hw->desc->set_tx_owner(desc);
 		priv->tx_skbuff[entry] = NULL;
 	} else {
 		desc->des2 = dma_map_single(priv->device, skb->data,
 					nopaged_len, DMA_TO_DEVICE);
 		desc->des3 = desc->des2 + BUF_SIZE_4KiB;
-		priv->mac_type->ops->prepare_tx_desc(desc, 1, nopaged_len,
-						     csum_insertion);
+		priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
+						csum_insertion);
 	}
 	return entry;
 }
@@ -1301,8 +1107,8 @@ static netdev_tx_t stmmac_xmit(struct sk
 		unsigned int nopaged_len = skb_headlen(skb);
 		desc->des2 = dma_map_single(priv->device, skb->data,
 					nopaged_len, DMA_TO_DEVICE);
-		priv->mac_type->ops->prepare_tx_desc(desc, 1, nopaged_len,
-						     csum_insertion);
+		priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
+						csum_insertion);
 	}
 
 	for (i = 0; i < nfrags; i++) {
@@ -1317,21 +1123,20 @@ static netdev_tx_t stmmac_xmit(struct sk
 					  frag->page_offset,
 					  len, DMA_TO_DEVICE);
 		priv->tx_skbuff[entry] = NULL;
-		priv->mac_type->ops->prepare_tx_desc(desc, 0, len,
-						     csum_insertion);
-		priv->mac_type->ops->set_tx_owner(desc);
+		priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion);
+		priv->hw->desc->set_tx_owner(desc);
 	}
 
 	/* Interrupt on completition only for the latest segment */
-	priv->mac_type->ops->close_tx_desc(desc);
+	priv->hw->desc->close_tx_desc(desc);
 
 #ifdef CONFIG_STMMAC_TIMER
 	/* Clean IC while using timer */
 	if (likely(priv->tm->enable))
-		priv->mac_type->ops->clear_tx_ic(desc);
+		priv->hw->desc->clear_tx_ic(desc);
 #endif
 	/* To avoid raise condition */
-	priv->mac_type->ops->set_tx_owner(first);
+	priv->hw->desc->set_tx_owner(first);
 
 	priv->cur_tx++;
 
@@ -1353,8 +1158,7 @@ static netdev_tx_t stmmac_xmit(struct sk
 
 	dev->stats.tx_bytes += skb->len;
 
-	/* CSR1 enables the transmit DMA to check for new descriptor */
-	writel(1, dev->base_addr + DMA_XMT_POLL_DEMAND);
+	priv->hw->dma->enable_dma_transmission(dev->base_addr);
 
 	return NETDEV_TX_OK;
 }
@@ -1391,7 +1195,7 @@ static inline void stmmac_rx_refill(stru
 			}
 			RX_DBG(KERN_INFO "\trefill entry #%d\n", entry);
 		}
-		priv->mac_type->ops->set_rx_owner(p + entry);
+		priv->hw->desc->set_rx_owner(p + entry);
 	}
 	return;
 }
@@ -1412,7 +1216,7 @@ static int stmmac_rx(struct stmmac_priv
 	}
 #endif
 	count = 0;
-	while (!priv->mac_type->ops->get_rx_owner(p)) {
+	while (!priv->hw->desc->get_rx_owner(p)) {
 		int status;
 
 		if (count >= limit)
@@ -1425,15 +1229,14 @@ static int stmmac_rx(struct stmmac_priv
 		prefetch(p_next);
 
 		/* read the status of the incoming frame */
-		status = (priv->mac_type->ops->rx_status(&priv->dev->stats,
-							 &priv->xstats, p));
+		status = (priv->hw->desc->rx_status(&priv->dev->stats,
+						    &priv->xstats, p));
 		if (unlikely(status == discard_frame))
 			priv->dev->stats.rx_errors++;
 		else {
 			struct sk_buff *skb;
 			/* Length should omit the CRC */
-			int frame_len =
-			    priv->mac_type->ops->get_rx_frame_len(p) - 4;
+			int frame_len = priv->hw->desc->get_rx_frame_len(p) - 4;
 
 #ifdef STMMAC_RX_DEBUG
 			if (frame_len > ETH_FRAME_LEN)
@@ -1569,7 +1372,7 @@ static void stmmac_multicast_list(struct
 	struct stmmac_priv *priv = netdev_priv(dev);
 
 	spin_lock(&priv->lock);
-	priv->mac_type->ops->set_filter(dev);
+	priv->hw->mac->set_filter(dev);
 	spin_unlock(&priv->lock);
 	return;
 }
@@ -1623,9 +1426,10 @@ static irqreturn_t stmmac_interrupt(int
 	if (priv->is_gmac) {
 		unsigned long ioaddr = dev->base_addr;
 		/* To handle GMAC own interrupts */
-		priv->mac_type->ops->host_irq_status(ioaddr);
+		priv->hw->mac->host_irq_status(ioaddr);
 	}
-	stmmac_dma_interrupt(dev);
+
+	stmmac_dma_interrupt(priv);
 
 	return IRQ_HANDLED;
 }
@@ -1744,7 +1548,7 @@ static int stmmac_probe(struct net_devic
 	netif_napi_add(dev, &priv->napi, stmmac_poll, 64);
 
 	/* Get the MAC address */
-	priv->mac_type->ops->get_umac_addr(dev->base_addr, dev->dev_addr, 0);
+	priv->hw->mac->get_umac_addr(dev->base_addr, dev->dev_addr, 0);
 
 	if (!is_valid_ether_addr(dev->dev_addr))
 		pr_warning("\tno valid MAC address;"
@@ -1779,16 +1583,16 @@ static int stmmac_mac_device_setup(struc
 	struct mac_device_info *device;
 
 	if (priv->is_gmac)
-		device = gmac_setup(ioaddr);
+		device = dwmac1000_setup(ioaddr);
 	else
-		device = mac100_setup(ioaddr);
+		device = dwmac100_setup(ioaddr);
 
 	if (!device)
 		return -ENOMEM;
 
-	priv->mac_type = device;
+	priv->hw = device;
 
-	priv->wolenabled = priv->mac_type->hw.pmt;	/* PMT supported */
+	priv->wolenabled = priv->hw->pmt;	/* PMT supported */
 	if (priv->wolenabled == PMT_SUPPORTED)
 		priv->wolopts = WAKE_MAGIC;		/* Magic Frame */
 
@@ -1797,8 +1601,7 @@ static int stmmac_mac_device_setup(struc
 
 static int stmmacphy_dvr_probe(struct platform_device *pdev)
 {
-	struct plat_stmmacphy_data *plat_dat;
-	plat_dat = (struct plat_stmmacphy_data *)((pdev->dev).platform_data);
+	struct plat_stmmacphy_data *plat_dat = pdev->dev.platform_data;
 
 	pr_debug("stmmacphy_dvr_probe: added phy for bus %d\n",
 	       plat_dat->bus_id);
@@ -1830,9 +1633,7 @@ static struct platform_driver stmmacphy_
 static int stmmac_associate_phy(struct device *dev, void *data)
 {
 	struct stmmac_priv *priv = (struct stmmac_priv *)data;
-	struct plat_stmmacphy_data *plat_dat;
-
-	plat_dat = (struct plat_stmmacphy_data *)(dev->platform_data);
+	struct plat_stmmacphy_data *plat_dat = dev->platform_data;
 
 	DBG(probe, DEBUG, "%s: checking phy for bus %d\n", __func__,
 		plat_dat->bus_id);
@@ -1885,7 +1686,7 @@ static int stmmac_dvr_probe(struct platf
 	}
 	pr_info("done!\n");
 
-	if (!request_mem_region(res->start, (res->end - res->start),
+	if (!request_mem_region(res->start, resource_size(res),
 				pdev->name)) {
 		pr_err("%s: ERROR: memory allocation failed"
 		       "cannot get the I/O addr 0x%x\n",
@@ -1894,9 +1695,9 @@ static int stmmac_dvr_probe(struct platf
 		goto out;
 	}
 
-	addr = ioremap(res->start, (res->end - res->start));
+	addr = ioremap(res->start, resource_size(res));
 	if (!addr) {
-		pr_err("%s: ERROR: memory mapping failed \n", __func__);
+		pr_err("%s: ERROR: memory mapping failed\n", __func__);
 		ret = -ENOMEM;
 		goto out;
 	}
@@ -1922,7 +1723,7 @@ static int stmmac_dvr_probe(struct platf
 	priv = netdev_priv(ndev);
 	priv->device = &(pdev->dev);
 	priv->dev = ndev;
-	plat_dat = (struct plat_stmmacenet_data *)((pdev->dev).platform_data);
+	plat_dat = pdev->dev.platform_data;
 	priv->bus_id = plat_dat->bus_id;
 	priv->pbl = plat_dat->pbl;	/* TLI */
 	priv->is_gmac = plat_dat->has_gmac;	/* GMAC is on board */
@@ -1932,6 +1733,11 @@ static int stmmac_dvr_probe(struct platf
 	/* Set the I/O base addr */
 	ndev->base_addr = (unsigned long)addr;
 
+	/* Verify embedded resource for the platform */
+	ret = stmmac_claim_resource(pdev);
+	if (ret < 0)
+		goto out;
+
 	/* MAC HW revice detection */
 	ret = stmmac_mac_device_setup(ndev);
 	if (ret < 0)
@@ -1952,6 +1758,7 @@ static int stmmac_dvr_probe(struct platf
 	}
 
 	priv->fix_mac_speed = plat_dat->fix_mac_speed;
+	priv->bus_setup = plat_dat->bus_setup;
 	priv->bsp_priv = plat_dat->bsp_priv;
 
 	pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n"
@@ -1968,7 +1775,7 @@ static int stmmac_dvr_probe(struct platf
 out:
 	if (ret < 0) {
 		platform_set_drvdata(pdev, NULL);
-		release_mem_region(res->start, (res->end - res->start));
+		release_mem_region(res->start, resource_size(res));
 		if (addr != NULL)
 			iounmap(addr);
 	}
@@ -1986,12 +1793,13 @@ out:
 static int stmmac_dvr_remove(struct platform_device *pdev)
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct stmmac_priv *priv = netdev_priv(ndev);
 	struct resource *res;
 
 	pr_info("%s:\n\tremoving driver", __func__);
 
-	stmmac_dma_stop_rx(ndev->base_addr);
-	stmmac_dma_stop_tx(ndev->base_addr);
+	priv->hw->dma->stop_rx(ndev->base_addr);
+	priv->hw->dma->stop_tx(ndev->base_addr);
 
 	stmmac_mac_disable_rx(ndev->base_addr);
 	stmmac_mac_disable_tx(ndev->base_addr);
@@ -2005,7 +1813,7 @@ static int stmmac_dvr_remove(struct plat
 
 	iounmap((void *)ndev->base_addr);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(res->start, (res->end - res->start));
+	release_mem_region(res->start, resource_size(res));
 
 	free_netdev(ndev);
 
@@ -2038,21 +1846,20 @@ static int stmmac_suspend(struct platfor
 		napi_disable(&priv->napi);
 
 		/* Stop TX/RX DMA */
-		stmmac_dma_stop_tx(dev->base_addr);
-		stmmac_dma_stop_rx(dev->base_addr);
+		priv->hw->dma->stop_tx(dev->base_addr);
+		priv->hw->dma->stop_rx(dev->base_addr);
 		/* Clear the Rx/Tx descriptors */
-		priv->mac_type->ops->init_rx_desc(priv->dma_rx,
-						  priv->dma_rx_size, dis_ic);
-		priv->mac_type->ops->init_tx_desc(priv->dma_tx,
-						  priv->dma_tx_size);
+		priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
+					     dis_ic);
+		priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
 
 		stmmac_mac_disable_tx(dev->base_addr);
 
 		if (device_may_wakeup(&(pdev->dev))) {
 			/* Enable Power down mode by programming the PMT regs */
 			if (priv->wolenabled == PMT_SUPPORTED)
-				priv->mac_type->ops->pmt(dev->base_addr,
-							 priv->wolopts);
+				priv->hw->mac->pmt(dev->base_addr,
+						   priv->wolopts);
 		} else {
 			stmmac_mac_disable_rx(dev->base_addr);
 		}
@@ -2093,15 +1900,15 @@ static int stmmac_resume(struct platform
 	 * from another devices (e.g. serial console). */
 	if (device_may_wakeup(&(pdev->dev)))
 		if (priv->wolenabled == PMT_SUPPORTED)
-			priv->mac_type->ops->pmt(dev->base_addr, 0);
+			priv->hw->mac->pmt(dev->base_addr, 0);
 
 	netif_device_attach(dev);
 
 	/* Enable the MAC and DMA */
 	stmmac_mac_enable_rx(ioaddr);
 	stmmac_mac_enable_tx(ioaddr);
-	stmmac_dma_start_tx(ioaddr);
-	stmmac_dma_start_rx(ioaddr);
+	priv->hw->dma->start_tx(ioaddr);
+	priv->hw->dma->start_rx(ioaddr);
 
 #ifdef CONFIG_STMMAC_TIMER
 	priv->tm->timer_start(tmrate);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/stmmac/stmmac_mdio.c linux-libre-2.6.34-gnu1/drivers/net/stmmac/stmmac_mdio.c
--- linux-libre-2.6.33-gnu1/drivers/net/stmmac/stmmac_mdio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/stmmac/stmmac_mdio.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,9 +24,9 @@
   Maintainer: Giuseppe Cavallaro <peppe.cavallaro@st.com>
 *******************************************************************************/
 
-#include <linux/netdevice.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
+#include <linux/slab.h>
 
 #include "stmmac.h"
 
@@ -48,8 +48,8 @@ static int stmmac_mdio_read(struct mii_b
 	struct net_device *ndev = bus->priv;
 	struct stmmac_priv *priv = netdev_priv(ndev);
 	unsigned long ioaddr = ndev->base_addr;
-	unsigned int mii_address = priv->mac_type->hw.mii.addr;
-	unsigned int mii_data = priv->mac_type->hw.mii.data;
+	unsigned int mii_address = priv->hw->mii.addr;
+	unsigned int mii_data = priv->hw->mii.data;
 
 	int data;
 	u16 regValue = (((phyaddr << 11) & (0x0000F800)) |
@@ -80,8 +80,8 @@ static int stmmac_mdio_write(struct mii_
 	struct net_device *ndev = bus->priv;
 	struct stmmac_priv *priv = netdev_priv(ndev);
 	unsigned long ioaddr = ndev->base_addr;
-	unsigned int mii_address = priv->mac_type->hw.mii.addr;
-	unsigned int mii_data = priv->mac_type->hw.mii.data;
+	unsigned int mii_address = priv->hw->mii.addr;
+	unsigned int mii_data = priv->hw->mii.data;
 
 	u16 value =
 	    (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0)))
@@ -112,7 +112,7 @@ static int stmmac_mdio_reset(struct mii_
 	struct net_device *ndev = bus->priv;
 	struct stmmac_priv *priv = netdev_priv(ndev);
 	unsigned long ioaddr = ndev->base_addr;
-	unsigned int mii_address = priv->mac_type->hw.mii.addr;
+	unsigned int mii_address = priv->hw->mii.addr;
 
 	if (priv->phy_reset) {
 		pr_debug("stmmac_mdio_reset: calling phy_reset\n");
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sun3_82586.c linux-libre-2.6.34-gnu1/drivers/net/sun3_82586.c
--- linux-libre-2.6.33-gnu1/drivers/net/sun3_82586.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sun3_82586.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,6 @@ static int fifo=0x8;	/* don't change */
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -413,8 +412,8 @@ static int init586(struct net_device *de
 	volatile struct iasetup_cmd_struct *ias_cmd;
 	volatile struct tdr_cmd_struct *tdr_cmd;
 	volatile struct mcsetup_cmd_struct *mc_cmd;
-	struct dev_mc_list *dmi=dev->mc_list;
-	int num_addrs=dev->mc_count;
+	struct dev_mc_list *dmi;
+	int num_addrs=netdev_mc_count(dev);
 
 	ptr = (void *) ((char *)p->scb + sizeof(struct scb_struct));
 
@@ -536,8 +535,10 @@ static int init586(struct net_device *de
 		mc_cmd->cmd_link = 0xffff;
 		mc_cmd->mc_cnt = swab16(num_addrs * 6);
 
-		for(i=0;i<num_addrs;i++,dmi=dmi->next)
-			memcpy((char *) mc_cmd->mc_list[i], dmi->dmi_addr,6);
+		i = 0;
+		netdev_for_each_mc_addr(dmi, dev)
+			memcpy((char *) mc_cmd->mc_list[i++],
+			       dmi->dmi_addr, ETH_ALEN);
 
 		p->scb->cbl_offset = make16(mc_cmd);
 		p->scb->cmd_cuc = CUC_START;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sun3lance.c linux-libre-2.6.34-gnu1/drivers/net/sun3lance.c
--- linux-libre-2.6.33-gnu1/drivers/net/sun3lance.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sun3lance.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,6 @@ static char *version = "sun3lance.c: v1.
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
@@ -917,7 +916,7 @@ static void set_multicast_list( struct n
 		REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */
 	} else {
 		short multicast_table[4];
-		int num_addrs = dev->mc_count;
+		int num_addrs = netdev_mc_count(dev);
 		int i;
 		/* We don't use the multicast table, but rely on upper-layer
 		 * filtering. */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sunbmac.c linux-libre-2.6.34-gnu1/drivers/net/sunbmac.c
--- linux-libre-2.6.33-gnu1/drivers/net/sunbmac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sunbmac.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -25,6 +24,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/gfp.h>
 
 #include <asm/auxio.h>
 #include <asm/byteorder.h>
@@ -999,7 +999,7 @@ static void bigmac_set_multicast(struct
 {
 	struct bigmac *bp = netdev_priv(dev);
 	void __iomem *bregs = bp->bregs;
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	char *addrs;
 	int i;
 	u32 tmp, crc;
@@ -1013,7 +1013,7 @@ static void bigmac_set_multicast(struct
 	while ((sbus_readl(bregs + BMAC_RXCFG) & BIGMAC_RXCFG_ENABLE) != 0)
 		udelay(20);
 
-	if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) {
+	if ((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 64)) {
 		sbus_writel(0xffff, bregs + BMAC_HTABLE0);
 		sbus_writel(0xffff, bregs + BMAC_HTABLE1);
 		sbus_writel(0xffff, bregs + BMAC_HTABLE2);
@@ -1028,9 +1028,8 @@ static void bigmac_set_multicast(struct
 		for (i = 0; i < 4; i++)
 			hash_table[i] = 0;
 
-		for (i = 0; i < dev->mc_count; i++) {
+		netdev_for_each_mc_addr(dmi, dev) {
 			addrs = dmi->dmi_addr;
-			dmi = dmi->next;
 
 			if (!(*addrs & 1))
 				continue;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sundance.c linux-libre-2.6.34-gnu1/drivers/net/sundance.c
--- linux-libre-2.6.33-gnu1/drivers/net/sundance.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sundance.c	2010-05-16 17:17:36.000000000 -0400
@@ -84,7 +84,6 @@ static char *media[MAX_UNITS];
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
@@ -206,7 +205,7 @@ IVc. Errata
 #define USE_IO_OPS 1
 #endif
 
-static const struct pci_device_id sundance_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(sundance_pci_tbl) = {
 	{ 0x1186, 0x1002, 0x1186, 0x1002, 0, 0, 0 },
 	{ 0x1186, 0x1002, 0x1186, 0x1003, 0, 0, 1 },
 	{ 0x1186, 0x1002, 0x1186, 0x1012, 0, 0, 2 },
@@ -1517,19 +1516,18 @@ static void set_rx_mode(struct net_devic
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptAll | AcceptMyPhys;
-	} else if ((dev->mc_count > multicast_filter_limit) ||
+	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
 		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
-	} else if (dev->mc_count) {
+	} else if (!netdev_mc_empty(dev)) {
 		struct dev_mc_list *mclist;
 		int bit;
 		int index;
 		int crc;
 		memset (mc_filter, 0, sizeof (mc_filter));
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-		     i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr);
 			for (index=0, bit=0; bit < 6; bit++, crc <<= 1)
 				if (crc & 0x80000000) index |= 1 << bit;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sungem.c linux-libre-2.6.34-gnu1/drivers/net/sungem.c
--- linux-libre-2.6.33-gnu1/drivers/net/sungem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sungem.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,6 @@
 #include <linux/ioport.h>
 #include <linux/in.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -58,6 +57,7 @@
 #include <linux/bitops.h>
 #include <linux/mutex.h>
 #include <linux/mm.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -107,7 +107,7 @@ MODULE_LICENSE("GPL");
 #define GEM_MODULE_NAME	"gem"
 #define PFX GEM_MODULE_NAME ": "
 
-static struct pci_device_id gem_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(gem_pci_tbl) = {
 	{ PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_GEM,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 
@@ -782,7 +782,7 @@ static int gem_rx(struct gem *gp, int wo
 			break;
 
 		/* When writing back RX descriptor, GEM writes status
-		 * then buffer address, possibly in seperate transactions.
+		 * then buffer address, possibly in separate transactions.
 		 * If we don't wait for the chip to write both, we could
 		 * post a new buffer to this descriptor then have GEM spam
 		 * on the buffer address.  We sync on the RX completion
@@ -1837,7 +1837,7 @@ static u32 gem_setup_multicast(struct ge
 	int i;
 
 	if ((gp->dev->flags & IFF_ALLMULTI) ||
-	    (gp->dev->mc_count > 256)) {
+	    (netdev_mc_count(gp->dev) > 256)) {
 	    	for (i=0; i<16; i++)
 			writel(0xffff, gp->regs + MAC_HASH0 + (i << 2));
 		rxcfg |= MAC_RXCFG_HFE;
@@ -1846,17 +1846,13 @@ static u32 gem_setup_multicast(struct ge
 	} else {
 		u16 hash_table[16];
 		u32 crc;
-		struct dev_mc_list *dmi = gp->dev->mc_list;
+		struct dev_mc_list *dmi;
 		int i;
 
-		for (i = 0; i < 16; i++)
-			hash_table[i] = 0;
-
-		for (i = 0; i < gp->dev->mc_count; i++) {
+		memset(hash_table, 0, sizeof(hash_table));
+		netdev_for_each_mc_addr(dmi, gp->dev) {
 			char *addrs = dmi->dmi_addr;
 
-			dmi = dmi->next;
-
 			if (!(*addrs & 1))
 				continue;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sunhme.c linux-libre-2.6.34-gnu1/drivers/net/sunhme.c
--- linux-libre-2.6.33-gnu1/drivers/net/sunhme.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sunhme.c	2010-05-16 17:17:36.000000000 -0400
@@ -1516,24 +1516,20 @@ static int happy_meal_init(struct happy_
 
 	HMD(("htable, "));
 	if ((hp->dev->flags & IFF_ALLMULTI) ||
-	    (hp->dev->mc_count > 64)) {
+	    (netdev_mc_count(hp->dev) > 64)) {
 		hme_write32(hp, bregs + BMAC_HTABLE0, 0xffff);
 		hme_write32(hp, bregs + BMAC_HTABLE1, 0xffff);
 		hme_write32(hp, bregs + BMAC_HTABLE2, 0xffff);
 		hme_write32(hp, bregs + BMAC_HTABLE3, 0xffff);
 	} else if ((hp->dev->flags & IFF_PROMISC) == 0) {
 		u16 hash_table[4];
-		struct dev_mc_list *dmi = hp->dev->mc_list;
+		struct dev_mc_list *dmi;
 		char *addrs;
-		int i;
 		u32 crc;
 
-		for (i = 0; i < 4; i++)
-			hash_table[i] = 0;
-
-		for (i = 0; i < hp->dev->mc_count; i++) {
+		memset(hash_table, 0, sizeof(hash_table));
+		netdev_for_each_mc_addr(dmi, hp->dev) {
 			addrs = dmi->dmi_addr;
-			dmi = dmi->next;
 
 			if (!(*addrs & 1))
 				continue;
@@ -2366,14 +2362,13 @@ static void happy_meal_set_multicast(str
 {
 	struct happy_meal *hp = netdev_priv(dev);
 	void __iomem *bregs = hp->bigmacregs;
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	char *addrs;
-	int i;
 	u32 crc;
 
 	spin_lock_irq(&hp->happy_lock);
 
-	if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) {
+	if ((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 64)) {
 		hme_write32(hp, bregs + BMAC_HTABLE0, 0xffff);
 		hme_write32(hp, bregs + BMAC_HTABLE1, 0xffff);
 		hme_write32(hp, bregs + BMAC_HTABLE2, 0xffff);
@@ -2384,12 +2379,9 @@ static void happy_meal_set_multicast(str
 	} else {
 		u16 hash_table[4];
 
-		for (i = 0; i < 4; i++)
-			hash_table[i] = 0;
-
-		for (i = 0; i < dev->mc_count; i++) {
+		memset(hash_table, 0, sizeof(hash_table));
+		netdev_for_each_mc_addr(dmi, dev) {
 			addrs = dmi->dmi_addr;
-			dmi = dmi->next;
 
 			if (!(*addrs & 1))
 				continue;
@@ -3211,7 +3203,7 @@ static void __devexit happy_meal_pci_rem
 	dev_set_drvdata(&pdev->dev, NULL);
 }
 
-static struct pci_device_id happymeal_pci_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(happymeal_pci_ids) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_HAPPYMEAL) },
 	{ }			/* Terminating entry */
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sunlance.c linux-libre-2.6.34-gnu1/drivers/net/sunlance.c
--- linux-libre-2.6.33-gnu1/drivers/net/sunlance.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sunlance.c	2010-05-16 17:17:36.000000000 -0400
@@ -78,7 +78,6 @@ static char lancestr[] = "LANCE";
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -94,6 +93,7 @@ static char lancestr[] = "LANCE";
 #include <linux/dma-mapping.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -1170,9 +1170,8 @@ static int lance_start_xmit(struct sk_bu
 static void lance_load_multicast(struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	char *addrs;
-	int i;
 	u32 crc;
 	u32 val;
 
@@ -1196,9 +1195,8 @@ static void lance_load_multicast(struct
 		return;
 
 	/* Add addresses */
-	for (i = 0; i < dev->mc_count; i++) {
+	netdev_for_each_mc_addr(dmi, dev) {
 		addrs = dmi->dmi_addr;
-		dmi   = dmi->next;
 
 		/* multicast address? */
 		if (!(*addrs & 1))
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sunqe.c linux-libre-2.6.34-gnu1/drivers/net/sunqe.c
--- linux-libre-2.6.33-gnu1/drivers/net/sunqe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sunqe.c	2010-05-16 17:17:36.000000000 -0400
@@ -627,7 +627,7 @@ static int qe_start_xmit(struct sk_buff
 static void qe_set_multicast(struct net_device *dev)
 {
 	struct sunqe *qep = netdev_priv(dev);
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	u8 new_mconfig = qep->mconfig;
 	char *addrs;
 	int i;
@@ -636,7 +636,7 @@ static void qe_set_multicast(struct net_
 	/* Lock out others. */
 	netif_stop_queue(dev);
 
-	if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) {
+	if ((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 64)) {
 		sbus_writeb(MREGS_IACONFIG_ACHNGE | MREGS_IACONFIG_LARESET,
 			    qep->mregs + MREGS_IACONFIG);
 		while ((sbus_readb(qep->mregs + MREGS_IACONFIG) & MREGS_IACONFIG_ACHNGE) != 0)
@@ -650,12 +650,9 @@ static void qe_set_multicast(struct net_
 		u16 hash_table[4];
 		u8 *hbytes = (unsigned char *) &hash_table[0];
 
-		for (i = 0; i < 4; i++)
-			hash_table[i] = 0;
-
-		for (i = 0; i < dev->mc_count; i++) {
+		memset(hash_table, 0, sizeof(hash_table));
+		netdev_for_each_mc_addr(dmi, dev) {
 			addrs = dmi->dmi_addr;
-			dmi = dmi->next;
 
 			if (!(*addrs & 1))
 				continue;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/sunvnet.c linux-libre-2.6.34-gnu1/drivers/net/sunvnet.c
--- linux-libre-2.6.33-gnu1/drivers/net/sunvnet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/sunvnet.c	2010-05-16 17:17:36.000000000 -0400
@@ -765,7 +765,7 @@ static void __update_mc_list(struct vnet
 {
 	struct dev_addr_list *p;
 
-	for (p = dev->mc_list; p; p = p->next) {
+	netdev_for_each_mc_addr(p, dev) {
 		struct vnet_mcast_entry *m;
 
 		m = __vnet_mc_find(vp, p->dmi_addr);
@@ -1062,10 +1062,7 @@ static struct vnet * __devinit vnet_new(
 		goto err_out_free_dev;
 	}
 
-	printk(KERN_INFO "%s: Sun LDOM vnet ", dev->name);
-
-	for (i = 0; i < 6; i++)
-		printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
+	printk(KERN_INFO "%s: Sun LDOM vnet %pM\n", dev->name, dev->dev_addr);
 
 	list_add(&vp->list, &vnet_list);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tc35815.c linux-libre-2.6.34-gnu1/drivers/net/tc35815.c
--- linux-libre-2.6.33-gnu1/drivers/net/tc35815.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tc35815.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,7 +65,7 @@ static const struct {
 	{ "TOSHIBA TC35815/TX4939" },
 };
 
-static const struct pci_device_id tc35815_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(tc35815_pci_tbl) = {
 	{PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC35815CF), .driver_data = TC35815CF },
 	{PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC35815_NWU), .driver_data = TC35815_NWU },
 	{PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC35815_TX4939), .driver_data = TC35815_TX4939 },
@@ -402,6 +402,7 @@ struct tc35815_local {
 	 * by this lock as well.
 	 */
 	spinlock_t lock;
+	spinlock_t rx_lock;
 
 	struct mii_bus *mii_bus;
 	struct phy_device *phy_dev;
@@ -835,6 +836,7 @@ static int __devinit tc35815_init_one(st
 
 	INIT_WORK(&lp->restart_work, tc35815_restart_work);
 	spin_lock_init(&lp->lock);
+	spin_lock_init(&lp->rx_lock);
 	lp->pci_dev = pdev;
 	lp->chiptype = ent->driver_data;
 
@@ -1186,6 +1188,7 @@ static void tc35815_restart(struct net_d
 			printk(KERN_ERR "%s: BMCR reset failed.\n", dev->name);
 	}
 
+	spin_lock_bh(&lp->rx_lock);
 	spin_lock_irq(&lp->lock);
 	tc35815_chip_reset(dev);
 	tc35815_clear_queues(dev);
@@ -1193,6 +1196,7 @@ static void tc35815_restart(struct net_d
 	/* Reconfigure CAM again since tc35815_chip_init() initialize it. */
 	tc35815_set_multicast_list(dev);
 	spin_unlock_irq(&lp->lock);
+	spin_unlock_bh(&lp->rx_lock);
 
 	netif_wake_queue(dev);
 }
@@ -1211,11 +1215,14 @@ static void tc35815_schedule_restart(str
 	struct tc35815_local *lp = netdev_priv(dev);
 	struct tc35815_regs __iomem *tr =
 		(struct tc35815_regs __iomem *)dev->base_addr;
+	unsigned long flags;
 
 	/* disable interrupts */
+	spin_lock_irqsave(&lp->lock, flags);
 	tc_writel(0, &tr->Int_En);
 	tc_writel(tc_readl(&tr->DMA_Ctl) | DMA_IntMask, &tr->DMA_Ctl);
 	schedule_work(&lp->restart_work);
+	spin_unlock_irqrestore(&lp->lock, flags);
 }
 
 static void tc35815_tx_timeout(struct net_device *dev)
@@ -1436,7 +1443,9 @@ static int tc35815_do_interrupt(struct n
 	if (status & Int_IntMacTx) {
 		/* Transmit complete. */
 		lp->lstats.tx_ints++;
+		spin_lock_irq(&lp->lock);
 		tc35815_txdone(dev);
+		spin_unlock_irq(&lp->lock);
 		if (ret < 0)
 			ret = 0;
 	}
@@ -1649,7 +1658,7 @@ static int tc35815_poll(struct napi_stru
 	int received = 0, handled;
 	u32 status;
 
-	spin_lock(&lp->lock);
+	spin_lock(&lp->rx_lock);
 	status = tc_readl(&tr->Int_Src);
 	do {
 		/* BLEx, FDAEx will be cleared later */
@@ -1667,7 +1676,7 @@ static int tc35815_poll(struct napi_stru
 		}
 		status = tc_readl(&tr->Int_Src);
 	} while (status);
-	spin_unlock(&lp->lock);
+	spin_unlock(&lp->rx_lock);
 
 	if (received < budget) {
 		napi_complete(napi);
@@ -1940,23 +1949,23 @@ tc35815_set_multicast_list(struct net_de
 		/* Enable promiscuous mode */
 		tc_writel(CAM_CompEn | CAM_BroadAcc | CAM_GroupAcc | CAM_StationAcc, &tr->CAM_Ctl);
 	} else if ((dev->flags & IFF_ALLMULTI) ||
-		  dev->mc_count > CAM_ENTRY_MAX - 3) {
+		  netdev_mc_count(dev) > CAM_ENTRY_MAX - 3) {
 		/* CAM 0, 1, 20 are reserved. */
 		/* Disable promiscuous mode, use normal mode. */
 		tc_writel(CAM_CompEn | CAM_BroadAcc | CAM_GroupAcc, &tr->CAM_Ctl);
-	} else if (dev->mc_count) {
-		struct dev_mc_list *cur_addr = dev->mc_list;
+	} else if (!netdev_mc_empty(dev)) {
+		struct dev_mc_list *cur_addr;
 		int i;
 		int ena_bits = CAM_Ena_Bit(CAM_ENTRY_SOURCE);
 
 		tc_writel(0, &tr->CAM_Ctl);
 		/* Walk the address list, and load the filter */
-		for (i = 0; i < dev->mc_count; i++, cur_addr = cur_addr->next) {
-			if (!cur_addr)
-				break;
+		i = 0;
+		netdev_for_each_mc_addr(cur_addr, dev) {
 			/* entry 0,1 is reserved. */
 			tc35815_set_cam_entry(dev, i + 2, cur_addr->dmi_addr);
 			ena_bits |= CAM_Ena_Bit(i + 2);
+			i++;
 		}
 		tc_writel(ena_bits, &tr->CAM_Ena);
 		tc_writel(CAM_CompEn | CAM_BroadAcc, &tr->CAM_Ctl);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tehuti.c linux-libre-2.6.34-gnu1/drivers/net/tehuti.c
--- linux-libre-2.6.33-gnu1/drivers/net/tehuti.c	2013-05-03 12:08:35.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/tehuti.c	2013-05-03 09:48:06.000000000 -0400
@@ -62,9 +62,11 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include "tehuti.h"
 
-static struct pci_device_id __devinitdata bdx_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(bdx_pci_tbl) = {
 	{0x1FC9, 0x3009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x1FC9, 0x3010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x1FC9, 0x3014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -105,26 +107,24 @@ static void print_hw_id(struct pci_dev *
 	pci_read_config_word(pdev, PCI_LINK_STATUS_REG, &pci_link_status);
 	pci_read_config_word(pdev, PCI_DEV_CTRL_REG, &pci_ctrl);
 
-	printk(KERN_INFO "tehuti: %s%s\n", BDX_NIC_NAME,
-	       nic->port_num == 1 ? "" : ", 2-Port");
-	printk(KERN_INFO
-	       "tehuti: srom 0x%x fpga %d build %u lane# %d"
-	       " max_pl 0x%x mrrs 0x%x\n",
-	       readl(nic->regs + SROM_VER), readl(nic->regs + FPGA_VER) & 0xFFF,
-	       readl(nic->regs + FPGA_SEED),
-	       GET_LINK_STATUS_LANES(pci_link_status),
-	       GET_DEV_CTRL_MAXPL(pci_ctrl), GET_DEV_CTRL_MRRS(pci_ctrl));
+	pr_info("%s%s\n", BDX_NIC_NAME,
+		nic->port_num == 1 ? "" : ", 2-Port");
+	pr_info("srom 0x%x fpga %d build %u lane# %d max_pl 0x%x mrrs 0x%x\n",
+		readl(nic->regs + SROM_VER), readl(nic->regs + FPGA_VER) & 0xFFF,
+		readl(nic->regs + FPGA_SEED),
+		GET_LINK_STATUS_LANES(pci_link_status),
+		GET_DEV_CTRL_MAXPL(pci_ctrl), GET_DEV_CTRL_MRRS(pci_ctrl));
 }
 
 static void print_fw_id(struct pci_nic *nic)
 {
-	printk(KERN_INFO "tehuti: fw 0x%x\n", readl(nic->regs + FW_VER));
+	pr_info("fw 0x%x\n", readl(nic->regs + FW_VER));
 }
 
 static void print_eth_id(struct net_device *ndev)
 {
-	printk(KERN_INFO "%s: %s, Port %c\n", ndev->name, BDX_NIC_NAME,
-	       (ndev->if_port == 0) ? 'A' : 'B');
+	netdev_info(ndev, "%s, Port %c\n",
+		    BDX_NIC_NAME, (ndev->if_port == 0) ? 'A' : 'B');
 
 }
 
@@ -160,7 +160,7 @@ bdx_fifo_init(struct bdx_priv *priv, str
 	f->va = pci_alloc_consistent(priv->pdev,
 				     memsz + FIFO_EXTRA_SPACE, &f->da);
 	if (!f->va) {
-		ERR("pci_alloc_consistent failed\n");
+		pr_err("pci_alloc_consistent failed\n");
 		RET(-ENOMEM);
 	}
 	f->reg_CFG0 = reg_CFG0;
@@ -204,13 +204,13 @@ static void bdx_link_changed(struct bdx_
 		if (netif_carrier_ok(priv->ndev)) {
 			netif_stop_queue(priv->ndev);
 			netif_carrier_off(priv->ndev);
-			ERR("%s: Link Down\n", priv->ndev->name);
+			netdev_err(priv->ndev, "Link Down\n");
 		}
 	} else {
 		if (!netif_carrier_ok(priv->ndev)) {
 			netif_wake_queue(priv->ndev);
 			netif_carrier_on(priv->ndev);
-			ERR("%s: Link Up\n", priv->ndev->name);
+			netdev_err(priv->ndev, "Link Up\n");
 		}
 	}
 }
@@ -226,10 +226,10 @@ static void bdx_isr_extra(struct bdx_pri
 		bdx_link_changed(priv);
 
 	if (isr & IR_PCIE_LINK)
-		ERR("%s: PCI-E Link Fault\n", priv->ndev->name);
+		netdev_err(priv->ndev, "PCI-E Link Fault\n");
 
 	if (isr & IR_PCIE_TOUT)
-		ERR("%s: PCI-E Time Out\n", priv->ndev->name);
+		netdev_err(priv->ndev, "PCI-E Time Out\n");
 
 }
 
@@ -345,7 +345,7 @@ out:
 		release_firmware(fw);
 
 	if (rc) {
-		ERR("%s: firmware loading failed\n", priv->ndev->name);
+		netdev_err(priv->ndev, "firmware loading failed\n");
 		if (rc == -EIO)
 			DBG("VPC = 0x%x VIC = 0x%x INIT_STATUS = 0x%x i=%d\n",
 			    READ_REG(priv, regVPC),
@@ -419,9 +419,11 @@ static int bdx_hw_start(struct bdx_priv
 	WRITE_REG(priv, regGMAC_RXF_A, GMAC_RX_FILTER_OSEN |
 		  GMAC_RX_FILTER_AM | GMAC_RX_FILTER_AB);
 
-#define BDX_IRQ_TYPE	((priv->nic->irq_type == IRQ_MSI)?0:IRQF_SHARED)
-	if ((rc = request_irq(priv->pdev->irq, bdx_isr_napi, BDX_IRQ_TYPE,
-			 ndev->name, ndev)))
+#define BDX_IRQ_TYPE	((priv->nic->irq_type == IRQ_MSI) ? 0 : IRQF_SHARED)
+
+	rc = request_irq(priv->pdev->irq, bdx_isr_napi, BDX_IRQ_TYPE,
+			 ndev->name, ndev);
+	if (rc)
 		goto err_irq;
 	bdx_enable_interrupts(priv);
 
@@ -462,7 +464,7 @@ static int bdx_hw_reset_direct(void __io
 			readl(regs + regRXD_CFG0_0);
 			return 0;
 		}
-	ERR("tehuti: HW reset failed\n");
+	pr_err("HW reset failed\n");
 	return 1;		/* failure */
 }
 
@@ -486,7 +488,7 @@ static int bdx_hw_reset(struct bdx_priv
 			READ_REG(priv, regRXD_CFG0_0);
 			return 0;
 		}
-	ERR("tehuti: HW reset failed\n");
+	pr_err("HW reset failed\n");
 	return 1;		/* failure */
 }
 
@@ -510,8 +512,7 @@ static int bdx_sw_reset(struct bdx_priv
 		mdelay(10);
 	}
 	if (i == 50)
-		ERR("%s: SW reset timeout. continuing anyway\n",
-		    priv->ndev->name);
+		netdev_err(priv->ndev, "SW reset timeout. continuing anyway\n");
 
 	/* 6. disable intrs */
 	WRITE_REG(priv, regRDINTCM0, 0);
@@ -604,18 +605,15 @@ static int bdx_open(struct net_device *n
 	if (netif_running(ndev))
 		netif_stop_queue(priv->ndev);
 
-	if ((rc = bdx_tx_init(priv)))
-		goto err;
-
-	if ((rc = bdx_rx_init(priv)))
-		goto err;
-
-	if ((rc = bdx_fw_load(priv)))
+	if ((rc = bdx_tx_init(priv)) ||
+	    (rc = bdx_rx_init(priv)) ||
+	    (rc = bdx_fw_load(priv)))
 		goto err;
 
 	bdx_rx_alloc_skbs(priv, &priv->rxf_fifo0);
 
-	if ((rc = bdx_hw_start(priv)))
+	rc = bdx_hw_start(priv);
+	if (rc)
 		goto err;
 
 	napi_enable(&priv->napi);
@@ -647,7 +645,7 @@ static int bdx_ioctl_priv(struct net_dev
 	if (cmd != SIOCDEVPRIVATE) {
 		error = copy_from_user(data, ifr->ifr_data, sizeof(data));
 		if (error) {
-			ERR("cant copy from user\n");
+			pr_err("cant copy from user\n");
 			RET(error);
 		}
 		DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]);
@@ -708,7 +706,7 @@ static void __bdx_vlan_rx_vid(struct net
 	ENTER;
 	DBG2("vid=%d value=%d\n", (int)vid, enable);
 	if (unlikely(vid >= 4096)) {
-		ERR("tehuti: invalid VID: %u (> 4096)\n", vid);
+		pr_err("invalid VID: %u (> 4096)\n", vid);
 		RET();
 	}
 	reg = regVLAN_0 + (vid / 32) * 4;
@@ -776,8 +774,8 @@ static int bdx_change_mtu(struct net_dev
 
 	/* enforce minimum frame size */
 	if (new_mtu < ETH_ZLEN) {
-		ERR("%s: %s mtu %d is less then minimal %d\n",
-		    BDX_DRV_NAME, ndev->name, new_mtu, ETH_ZLEN);
+		netdev_err(ndev, "mtu %d is less then minimal %d\n",
+			   new_mtu, ETH_ZLEN);
 		RET(-EINVAL);
 	}
 
@@ -808,7 +806,7 @@ static void bdx_setmulti(struct net_devi
 		/* set IMF to accept all multicast frmaes */
 		for (i = 0; i < MAC_MCST_HASH_NUM; i++)
 			WRITE_REG(priv, regRX_MCST_HASH0 + i * 4, ~0);
-	} else if (ndev->mc_count) {
+	} else if (!netdev_mc_empty(ndev)) {
 		u8 hash;
 		struct dev_mc_list *mclist;
 		u32 reg, val;
@@ -826,10 +824,8 @@ static void bdx_setmulti(struct net_devi
 		/* TBD: sort addreses and write them in ascending order
 		 * into RX_MAC_MCST regs. we skip this phase now and accept ALL
 		 * multicast frames throu IMF */
-		mclist = ndev->mc_list;
-
 		/* accept the rest of addresses throu IMF */
-		for (; mclist; mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, ndev) {
 			hash = 0;
 			for (i = 0; i < ETH_ALEN; i++)
 				hash ^= mclist->dmi_addr[i];
@@ -840,7 +836,7 @@ static void bdx_setmulti(struct net_devi
 		}
 
 	} else {
-		DBG("only own mac %d\n", ndev->mc_count);
+		DBG("only own mac %d\n", netdev_mc_count(ndev));
 		rxf_val |= GMAC_RX_FILTER_AB;
 	}
 	WRITE_REG(priv, regGMAC_RXF_A, rxf_val);
@@ -1028,17 +1024,16 @@ static int bdx_rx_init(struct bdx_priv *
 			  regRXF_CFG0_0, regRXF_CFG1_0,
 			  regRXF_RPTR_0, regRXF_WPTR_0))
 		goto err_mem;
-	if (!
-	    (priv->rxdb =
-	     bdx_rxdb_create(priv->rxf_fifo0.m.memsz /
-			     sizeof(struct rxf_desc))))
+	priv->rxdb = bdx_rxdb_create(priv->rxf_fifo0.m.memsz /
+				     sizeof(struct rxf_desc));
+	if (!priv->rxdb)
 		goto err_mem;
 
 	priv->rxf_fifo0.m.pktsz = priv->ndev->mtu + VLAN_ETH_HLEN;
 	return 0;
 
 err_mem:
-	ERR("%s: %s: Rx init failed\n", BDX_DRV_NAME, priv->ndev->name);
+	netdev_err(priv->ndev, "Rx init failed\n");
 	return -ENOMEM;
 }
 
@@ -1115,8 +1110,9 @@ static void bdx_rx_alloc_skbs(struct bdx
 	ENTER;
 	dno = bdx_rxdb_available(db) - 1;
 	while (dno > 0) {
-		if (!(skb = dev_alloc_skb(f->m.pktsz + NET_IP_ALIGN))) {
-			ERR("NO MEM: dev_alloc_skb failed\n");
+		skb = dev_alloc_skb(f->m.pktsz + NET_IP_ALIGN);
+		if (!skb) {
+			pr_err("NO MEM: dev_alloc_skb failed\n");
 			break;
 		}
 		skb->dev = priv->ndev;
@@ -1337,9 +1333,7 @@ static int bdx_rx_receive(struct bdx_pri
 static void print_rxdd(struct rxd_desc *rxdd, u32 rxd_val1, u16 len,
 		       u16 rxd_vlan)
 {
-	DBG("ERROR: rxdd bc %d rxfq %d to %d type %d err %d rxp %d "
-	    "pkt_id %d vtag %d len %d vlan_id %d cfi %d prio %d "
-	    "va_lo %d va_hi %d\n",
+	DBG("ERROR: rxdd bc %d rxfq %d to %d type %d err %d rxp %d pkt_id %d vtag %d len %d vlan_id %d cfi %d prio %d va_lo %d va_hi %d\n",
 	    GET_RXD_BC(rxd_val1), GET_RXD_RXFQ(rxd_val1), GET_RXD_TO(rxd_val1),
 	    GET_RXD_TYPE(rxd_val1), GET_RXD_ERR(rxd_val1),
 	    GET_RXD_RXP(rxd_val1), GET_RXD_PKT_ID(rxd_val1),
@@ -1591,7 +1585,7 @@ static int bdx_tx_init(struct bdx_priv *
 	return 0;
 
 err_mem:
-	ERR("tehuti: %s: Tx init failed\n", priv->ndev->name);
+	netdev_err(priv->ndev, "Tx init failed\n");
 	return -ENOMEM;
 }
 
@@ -1609,7 +1603,7 @@ static inline int bdx_tx_space(struct bd
 	fsize = f->m.rptr - f->m.wptr;
 	if (fsize <= 0)
 		fsize = f->m.memsz + fsize;
-	return (fsize);
+	return fsize;
 }
 
 /* bdx_tx_transmit - send packet to NIC
@@ -1857,7 +1851,7 @@ static void bdx_tx_push_desc(struct bdx_
  * @data - desc's data
  * @size - desc's size
  *
- * NOTE: this func does check for available space and, if neccessary, waits for
+ * NOTE: this func does check for available space and, if necessary, waits for
  *   NIC to read existing data before writing new one.
  */
 static void bdx_tx_push_desc_safe(struct bdx_priv *priv, void *data, int size)
@@ -1937,8 +1931,9 @@ bdx_probe(struct pci_dev *pdev, const st
 		RET(-ENOMEM);
 
     /************** pci *****************/
-	if ((err = pci_enable_device(pdev)))	/* it trigers interrupt, dunno why. */
-		goto err_pci;			/* it's not a problem though */
+	err = pci_enable_device(pdev);
+	if (err)			/* it triggers interrupt, dunno why. */
+		goto err_pci;		/* it's not a problem though */
 
 	if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) &&
 	    !(err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))) {
@@ -1946,14 +1941,14 @@ bdx_probe(struct pci_dev *pdev, const st
 	} else {
 		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");
+			pr_err("No usable DMA configuration, aborting\n");
 			goto err_dma;
 		}
 		pci_using_dac = 0;
 	}
 
-	if ((err = pci_request_regions(pdev, BDX_DRV_NAME)))
+	err = pci_request_regions(pdev, BDX_DRV_NAME);
+	if (err)
 		goto err_dma;
 
 	pci_set_master(pdev);
@@ -1961,25 +1956,26 @@ bdx_probe(struct pci_dev *pdev, const st
 	pciaddr = pci_resource_start(pdev, 0);
 	if (!pciaddr) {
 		err = -EIO;
-		ERR("tehuti: no MMIO resource\n");
+		pr_err("no MMIO resource\n");
 		goto err_out_res;
 	}
-	if ((regionSize = pci_resource_len(pdev, 0)) < BDX_REGS_SIZE) {
+	regionSize = pci_resource_len(pdev, 0);
+	if (regionSize < BDX_REGS_SIZE) {
 		err = -EIO;
-		ERR("tehuti: MMIO resource (%x) too small\n", regionSize);
+		pr_err("MMIO resource (%x) too small\n", regionSize);
 		goto err_out_res;
 	}
 
 	nic->regs = ioremap(pciaddr, regionSize);
 	if (!nic->regs) {
 		err = -EIO;
-		ERR("tehuti: ioremap failed\n");
+		pr_err("ioremap failed\n");
 		goto err_out_res;
 	}
 
 	if (pdev->irq < 2) {
 		err = -EIO;
-		ERR("tehuti: invalid irq (%d)\n", pdev->irq);
+		pr_err("invalid irq (%d)\n", pdev->irq);
 		goto err_out_iomap;
 	}
 	pci_set_drvdata(pdev, nic);
@@ -1996,8 +1992,9 @@ bdx_probe(struct pci_dev *pdev, const st
 	nic->irq_type = IRQ_INTX;
 #ifdef BDX_MSI
 	if ((readl(nic->regs + FPGA_VER) & 0xFFF) >= 378) {
-		if ((err = pci_enable_msi(pdev)))
-			ERR("Tehuti: Can't eneble msi. error is %d\n", err);
+		err = pci_enable_msi(pdev);
+		if (err)
+			pr_err("Can't eneble msi. error is %d\n", err);
 		else
 			nic->irq_type = IRQ_MSI;
 	} else
@@ -2006,9 +2003,10 @@ bdx_probe(struct pci_dev *pdev, const st
 
     /************** netdev **************/
 	for (port = 0; port < nic->port_num; port++) {
-		if (!(ndev = alloc_etherdev(sizeof(struct bdx_priv)))) {
+		ndev = alloc_etherdev(sizeof(struct bdx_priv));
+		if (!ndev) {
 			err = -ENOMEM;
-			printk(KERN_ERR "tehuti: alloc_etherdev failed\n");
+			pr_err("alloc_etherdev failed\n");
 			goto err_out_iomap;
 		}
 
@@ -2075,12 +2073,13 @@ bdx_probe(struct pci_dev *pdev, const st
 
 		/*bdx_hw_reset(priv); */
 		if (bdx_read_mac(priv)) {
-			printk(KERN_ERR "tehuti: load MAC address failed\n");
+			pr_err("load MAC address failed\n");
 			goto err_out_iomap;
 		}
 		SET_NETDEV_DEV(ndev, &pdev->dev);
-		if ((err = register_netdev(ndev))) {
-			printk(KERN_ERR "tehuti: register_netdev failed\n");
+		err = register_netdev(ndev);
+		if (err) {
+			pr_err("register_netdev failed\n");
 			goto err_out_free;
 		}
 		netif_carrier_off(ndev);
@@ -2294,13 +2293,13 @@ bdx_set_coalesce(struct net_device *netd
 /* Convert RX fifo size to number of pending packets */
 static inline int bdx_rx_fifo_size_to_packets(int rx_size)
 {
-	return ((FIFO_SIZE * (1 << rx_size)) / sizeof(struct rxf_desc));
+	return (FIFO_SIZE * (1 << rx_size)) / sizeof(struct rxf_desc);
 }
 
 /* Convert TX fifo size to number of pending packets */
 static inline int bdx_tx_fifo_size_to_packets(int tx_size)
 {
-	return ((FIFO_SIZE * (1 << tx_size)) / BDX_TXF_DESC_SZ);
+	return (FIFO_SIZE * (1 << tx_size)) / BDX_TXF_DESC_SZ;
 }
 
 /*
@@ -2392,10 +2391,10 @@ static int bdx_get_sset_count(struct net
 	case ETH_SS_STATS:
 		BDX_ASSERT(ARRAY_SIZE(bdx_stat_names)
 			   != sizeof(struct bdx_stats) / sizeof(u64));
-		return ((priv->stats_flag) ? ARRAY_SIZE(bdx_stat_names)	: 0);
-	default:
-		return -EINVAL;
+		return (priv->stats_flag) ? ARRAY_SIZE(bdx_stat_names)	: 0;
 	}
+
+	return -EINVAL;
 }
 
 /*
@@ -2493,10 +2492,8 @@ static struct pci_driver bdx_pci_driver
  */
 static void __init print_driver_id(void)
 {
-	printk(KERN_INFO "%s: %s, %s\n", BDX_DRV_NAME, BDX_DRV_DESC,
-	       BDX_DRV_VERSION);
-	printk(KERN_INFO "%s: Options: hw_csum %s\n", BDX_DRV_NAME,
-	       BDX_MSI_STRING);
+	pr_info("%s, %s\n", BDX_DRV_DESC, BDX_DRV_VERSION);
+	pr_info("Options: hw_csum %s\n", BDX_MSI_STRING);
 }
 
 static int __init bdx_module_init(void)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tehuti.h linux-libre-2.6.34-gnu1/drivers/net/tehuti.h
--- linux-libre-2.6.33-gnu1/drivers/net/tehuti.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tehuti.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/firmware.h>
 #include <asm/byteorder.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 /* Compile Time Switches */
 /* start */
@@ -529,28 +530,34 @@ struct txd_desc {
 
 /* Debugging Macros */
 
-#define ERR(fmt, args...) printk(KERN_ERR fmt, ## args)
-#define DBG2(fmt, args...)	\
-	printk(KERN_ERR  "%s:%-5d: " fmt, __func__, __LINE__, ## args)
+#define DBG2(fmt, args...)					\
+	pr_err("%s:%-5d: " fmt, __func__, __LINE__, ## args)
 
 #define BDX_ASSERT(x) BUG_ON(x)
 
 #ifdef DEBUG
 
-#define ENTER          do { \
-	printk(KERN_ERR  "%s:%-5d: ENTER\n", __func__, __LINE__); \
+#define ENTER						\
+do {							\
+	pr_err("%s:%-5d: ENTER\n", __func__, __LINE__); \
 } while (0)
 
-#define RET(args...)   do { \
-	printk(KERN_ERR  "%s:%-5d: RETURN\n", __func__, __LINE__); \
-return args; } while (0)
+#define RET(args...)					 \
+do {							 \
+	pr_err("%s:%-5d: RETURN\n", __func__, __LINE__); \
+	return args;					 \
+} while (0)
 
-#define DBG(fmt, args...)	\
-	printk(KERN_ERR  "%s:%-5d: " fmt, __func__, __LINE__, ## args)
+#define DBG(fmt, args...)					\
+	pr_err("%s:%-5d: " fmt, __func__, __LINE__, ## args)
 #else
-#define ENTER         do {  } while (0)
+#define ENTER do {  } while (0)
 #define RET(args...)   return args
-#define DBG(fmt, args...)   do {  } while (0)
+#define DBG(fmt, args...)			\
+do {						\
+	if (0)					\
+		pr_err(fmt, ##args);		\
+} while (0)
 #endif
 
 #endif /* _BDX__H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tg3.c linux-libre-2.6.34-gnu1/drivers/net/tg3.c
--- linux-libre-2.6.33-gnu1/drivers/net/tg3.c	2013-05-03 12:08:42.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/tg3.c	2013-05-03 09:48:13.000000000 -0400
@@ -60,9 +60,8 @@
 #include "tg3.h"
 
 #define DRV_MODULE_NAME		"tg3"
-#define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.106"
-#define DRV_MODULE_RELDATE	"January 12, 2010"
+#define DRV_MODULE_VERSION	"3.108"
+#define DRV_MODULE_RELDATE	"February 17, 2010"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -151,7 +150,7 @@
 #define FIRMWARE_TG3TSO5	"/*(DEBLOBBED)*/"
 
 static char version[] __devinitdata =
-	DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+	DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")";
 
 MODULE_AUTHOR("David S. Miller (davem@redhat.com) and Jeff Garzik (jgarzik@pobox.com)");
 MODULE_DESCRIPTION("Broadcom Tigon3 ethernet driver");
@@ -165,7 +164,7 @@ static int tg3_debug = -1;	/* -1 == use
 module_param(tg3_debug, int, 0);
 MODULE_PARM_DESC(tg3_debug, "Tigon3 bitmapped debugging message enable value");
 
-static struct pci_device_id tg3_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = {
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5700)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5701)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702)},
@@ -235,6 +234,12 @@ static struct pci_device_id tg3_pci_tbl[
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5717)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5718)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5724)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57781)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57785)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57761)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57765)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57791)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57795)},
 	{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
 	{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
 	{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -627,7 +632,6 @@ static void tg3_disable_ints(struct tg3
 static void tg3_enable_ints(struct tg3 *tp)
 {
 	int i;
-	u32 coal_now = 0;
 
 	tp->irq_sync = 0;
 	wmb();
@@ -635,13 +639,14 @@ static void tg3_enable_ints(struct tg3 *
 	tw32(TG3PCI_MISC_HOST_CTRL,
 	     (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
 
+	tp->coal_now = tp->coalesce_mode | HOSTCC_MODE_ENABLE;
 	for (i = 0; i < tp->irq_cnt; i++) {
 		struct tg3_napi *tnapi = &tp->napi[i];
 		tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
 		if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
 			tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
 
-		coal_now |= tnapi->coal_now;
+		tp->coal_now |= tnapi->coal_now;
 	}
 
 	/* Force an initial interrupt */
@@ -649,8 +654,9 @@ static void tg3_enable_ints(struct tg3 *
 	    (tp->napi[0].hw_status->status & SD_STATUS_UPDATED))
 		tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
 	else
-		tw32(HOSTCC_MODE, tp->coalesce_mode |
-		     HOSTCC_MODE_ENABLE | coal_now);
+		tw32(HOSTCC_MODE, tp->coal_now);
+
+	tp->coal_now &= ~(tp->napi[0].coal_now | tp->napi[1].coal_now);
 }
 
 static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
@@ -939,17 +945,17 @@ static void tg3_mdio_config_5785(struct
 
 	phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 	switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
-	case TG3_PHY_ID_BCM50610:
-	case TG3_PHY_ID_BCM50610M:
+	case PHY_ID_BCM50610:
+	case PHY_ID_BCM50610M:
 		val = MAC_PHYCFG2_50610_LED_MODES;
 		break;
-	case TG3_PHY_ID_BCMAC131:
+	case PHY_ID_BCMAC131:
 		val = MAC_PHYCFG2_AC131_LED_MODES;
 		break;
-	case TG3_PHY_ID_RTL8211C:
+	case PHY_ID_RTL8211C:
 		val = MAC_PHYCFG2_RTL8211C_LED_MODES;
 		break;
-	case TG3_PHY_ID_RTL8201E:
+	case PHY_ID_RTL8201E:
 		val = MAC_PHYCFG2_RTL8201E_LED_MODES;
 		break;
 	default:
@@ -968,7 +974,7 @@ static void tg3_mdio_config_5785(struct
 		return;
 	}
 
-	if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE))
+	if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_INBAND_DISABLE))
 		val |= MAC_PHYCFG2_EMODE_MASK_MASK |
 		       MAC_PHYCFG2_FMODE_MASK_MASK |
 		       MAC_PHYCFG2_GMODE_MASK_MASK |
@@ -981,7 +987,7 @@ static void tg3_mdio_config_5785(struct
 	val = tr32(MAC_PHYCFG1);
 	val &= ~(MAC_PHYCFG1_RXCLK_TO_MASK | MAC_PHYCFG1_TXCLK_TO_MASK |
 		 MAC_PHYCFG1_RGMII_EXT_RX_DEC | MAC_PHYCFG1_RGMII_SND_STAT_EN);
-	if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)) {
+	if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_INBAND_DISABLE)) {
 		if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
 			val |= MAC_PHYCFG1_RGMII_EXT_RX_DEC;
 		if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
@@ -999,7 +1005,7 @@ static void tg3_mdio_config_5785(struct
 		 MAC_RGMII_MODE_TX_ENABLE |
 		 MAC_RGMII_MODE_TX_LOWPWR |
 		 MAC_RGMII_MODE_TX_RESET);
-	if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)) {
+	if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_INBAND_DISABLE)) {
 		if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
 			val |= MAC_RGMII_MODE_RX_INT_B |
 			       MAC_RGMII_MODE_RX_QUALITY |
@@ -1019,6 +1025,17 @@ static void tg3_mdio_start(struct tg3 *t
 	tw32_f(MAC_MI_MODE, tp->mi_mode);
 	udelay(80);
 
+	if ((tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+		tg3_mdio_config_5785(tp);
+}
+
+static int tg3_mdio_init(struct tg3 *tp)
+{
+	int i;
+	u32 reg;
+	struct phy_device *phydev;
+
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
 		u32 funcnum, is_serdes;
 
@@ -1038,17 +1055,6 @@ static void tg3_mdio_start(struct tg3 *t
 	} else
 		tp->phy_addr = TG3_PHY_MII_ADDR;
 
-	if ((tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
-		tg3_mdio_config_5785(tp);
-}
-
-static int tg3_mdio_init(struct tg3 *tp)
-{
-	int i;
-	u32 reg;
-	struct phy_device *phydev;
-
 	tg3_mdio_start(tp);
 
 	if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) ||
@@ -1083,8 +1089,7 @@ static int tg3_mdio_init(struct tg3 *tp)
 
 	i = mdiobus_register(tp->mdio_bus);
 	if (i) {
-		printk(KERN_WARNING "%s: mdiobus_reg failed (0x%x)\n",
-			tp->dev->name, i);
+		netdev_warn(tp->dev, "mdiobus_reg failed (0x%x)\n", i);
 		mdiobus_free(tp->mdio_bus);
 		return i;
 	}
@@ -1092,35 +1097,35 @@ static int tg3_mdio_init(struct tg3 *tp)
 	phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
 	if (!phydev || !phydev->drv) {
-		printk(KERN_WARNING "%s: No PHY devices\n", tp->dev->name);
+		netdev_warn(tp->dev, "No PHY devices\n");
 		mdiobus_unregister(tp->mdio_bus);
 		mdiobus_free(tp->mdio_bus);
 		return -ENODEV;
 	}
 
 	switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
-	case TG3_PHY_ID_BCM57780:
+	case PHY_ID_BCM57780:
 		phydev->interface = PHY_INTERFACE_MODE_GMII;
 		phydev->dev_flags |= PHY_BRCM_AUTO_PWRDWN_ENABLE;
 		break;
-	case TG3_PHY_ID_BCM50610:
-	case TG3_PHY_ID_BCM50610M:
+	case PHY_ID_BCM50610:
+	case PHY_ID_BCM50610M:
 		phydev->dev_flags |= PHY_BRCM_CLEAR_RGMII_MODE |
 				     PHY_BRCM_RX_REFCLK_UNUSED |
 				     PHY_BRCM_DIS_TXCRXC_NOENRGY |
 				     PHY_BRCM_AUTO_PWRDWN_ENABLE;
-		if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)
+		if (tp->tg3_flags3 & TG3_FLG3_RGMII_INBAND_DISABLE)
 			phydev->dev_flags |= PHY_BRCM_STD_IBND_DISABLE;
 		if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
 			phydev->dev_flags |= PHY_BRCM_EXT_IBND_RX_ENABLE;
 		if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
 			phydev->dev_flags |= PHY_BRCM_EXT_IBND_TX_ENABLE;
 		/* fallthru */
-	case TG3_PHY_ID_RTL8211C:
+	case PHY_ID_RTL8211C:
 		phydev->interface = PHY_INTERFACE_MODE_RGMII;
 		break;
-	case TG3_PHY_ID_RTL8201E:
-	case TG3_PHY_ID_BCMAC131:
+	case PHY_ID_RTL8201E:
+	case PHY_ID_BCMAC131:
 		phydev->interface = PHY_INTERFACE_MODE_MII;
 		phydev->dev_flags |= PHY_BRCM_AUTO_PWRDWN_ENABLE;
 		tp->tg3_flags3 |= TG3_FLG3_PHY_IS_FET;
@@ -1236,27 +1241,22 @@ static void tg3_ump_link_report(struct t
 static void tg3_link_report(struct tg3 *tp)
 {
 	if (!netif_carrier_ok(tp->dev)) {
-		if (netif_msg_link(tp))
-			printk(KERN_INFO PFX "%s: Link is down.\n",
-			       tp->dev->name);
+		netif_info(tp, link, tp->dev, "Link is down\n");
 		tg3_ump_link_report(tp);
 	} else if (netif_msg_link(tp)) {
-		printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n",
-		       tp->dev->name,
-		       (tp->link_config.active_speed == SPEED_1000 ?
-			1000 :
-			(tp->link_config.active_speed == SPEED_100 ?
-			 100 : 10)),
-		       (tp->link_config.active_duplex == DUPLEX_FULL ?
-			"full" : "half"));
+		netdev_info(tp->dev, "Link is up at %d Mbps, %s duplex\n",
+			    (tp->link_config.active_speed == SPEED_1000 ?
+			     1000 :
+			     (tp->link_config.active_speed == SPEED_100 ?
+			      100 : 10)),
+			    (tp->link_config.active_duplex == DUPLEX_FULL ?
+			     "full" : "half"));
 
-		printk(KERN_INFO PFX
-		       "%s: Flow control is %s for TX and %s for RX.\n",
-		       tp->dev->name,
-		       (tp->link_config.active_flowctrl & FLOW_CTRL_TX) ?
-		       "on" : "off",
-		       (tp->link_config.active_flowctrl & FLOW_CTRL_RX) ?
-		       "on" : "off");
+		netdev_info(tp->dev, "Flow control is %s for TX and %s for RX\n",
+			    (tp->link_config.active_flowctrl & FLOW_CTRL_TX) ?
+			    "on" : "off",
+			    (tp->link_config.active_flowctrl & FLOW_CTRL_RX) ?
+			    "on" : "off");
 		tg3_ump_link_report(tp);
 	}
 }
@@ -1455,7 +1455,7 @@ static int tg3_phy_init(struct tg3 *tp)
 	phydev = phy_connect(tp->dev, dev_name(&phydev->dev), tg3_adjust_link,
 			     phydev->dev_flags, phydev->interface);
 	if (IS_ERR(phydev)) {
-		printk(KERN_ERR "%s: Could not attach to PHY\n", tp->dev->name);
+		netdev_err(tp->dev, "Could not attach to PHY\n");
 		return PTR_ERR(phydev);
 	}
 
@@ -1555,7 +1555,9 @@ static void tg3_phy_toggle_apd(struct tg
 {
 	u32 reg;
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
+		(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
+	     (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)))
 		return;
 
 	if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
@@ -1930,6 +1932,10 @@ static int tg3_phy_reset(struct tg3 *tp)
 		}
 	}
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
+	    (tp->tg3_flags2 & TG3_FLG2_MII_SERDES))
+		return 0;
+
 	tg3_phy_apply_otp(tp);
 
 	if (tp->tg3_flags3 & TG3_FLG3_PHY_ENABLE_APD)
@@ -1973,7 +1979,7 @@ out:
 	}
 	/* Set Extended packet length bit (bit 14) on all chips that */
 	/* support jumbo frames */
-	if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
+	if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5401) {
 		/* Cannot do read-modify-write on 5401 */
 		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
 	} else if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
@@ -2010,7 +2016,9 @@ static void tg3_frob_aux_power(struct tg
 {
 	struct tg3 *tp_peer = tp;
 
-	if ((tp->tg3_flags2 & TG3_FLG2_IS_NIC) == 0)
+	/* The GPIOs do something completely different on 57765. */
+	if ((tp->tg3_flags2 & TG3_FLG2_IS_NIC) == 0 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
 		return;
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
@@ -2123,7 +2131,7 @@ static int tg3_5700_link_polarity(struct
 {
 	if (tp->led_ctrl == LED_CTRL_MODE_PHY_2)
 		return 1;
-	else if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5411) {
+	else if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5411) {
 		if (speed != SPEED_10)
 			return 1;
 	} else if (speed == SPEED_10)
@@ -2476,8 +2484,8 @@ static int tg3_set_power_state(struct tg
 		break;
 
 	default:
-		printk(KERN_ERR PFX "%s: Invalid power state (D%d) requested\n",
-			tp->dev->name, state);
+		netdev_err(tp->dev, "Invalid power state (D%d) requested\n",
+			   state);
 		return -EINVAL;
 	}
 
@@ -2539,11 +2547,11 @@ static int tg3_set_power_state(struct tg
 			phy_start_aneg(phydev);
 
 			phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask;
-			if (phyid != TG3_PHY_ID_BCMAC131) {
-				phyid &= TG3_PHY_OUI_MASK;
-				if (phyid == TG3_PHY_OUI_1 ||
-				    phyid == TG3_PHY_OUI_2 ||
-				    phyid == TG3_PHY_OUI_3)
+			if (phyid != PHY_ID_BCMAC131) {
+				phyid &= PHY_BCM_OUI_MASK;
+				if (phyid == PHY_BCM_OUI_1 ||
+				    phyid == PHY_BCM_OUI_2 ||
+				    phyid == PHY_BCM_OUI_3)
 					do_low_power = true;
 			}
 		}
@@ -3053,7 +3061,7 @@ static int tg3_setup_copper_phy(struct t
 	if (force_reset)
 		tg3_phy_reset(tp);
 
-	if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
+	if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5401) {
 		tg3_readphy(tp, MII_BMSR, &bmsr);
 		if (tg3_readphy(tp, MII_BMSR, &bmsr) ||
 		    !(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE))
@@ -3074,7 +3082,8 @@ static int tg3_setup_copper_phy(struct t
 				}
 			}
 
-			if ((tp->phy_id & PHY_ID_REV_MASK) == PHY_REV_BCM5401_B0 &&
+			if ((tp->phy_id & TG3_PHY_ID_REV_MASK) ==
+			    TG3_PHY_REV_BCM5401_B0 &&
 			    !(bmsr & BMSR_LSTATUS) &&
 			    tp->link_config.active_speed == SPEED_1000) {
 				err = tg3_phy_reset(tp);
@@ -3229,7 +3238,7 @@ relink:
 	/* ??? Without this setting Netgear GA302T PHY does not
 	 * ??? send/receive packets...
 	 */
-	if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5411 &&
+	if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5411 &&
 	    tp->pci_chip_rev_id == CHIPREV_ID_5700_ALTIMA) {
 		tp->mi_mode |= MAC_MI_MODE_AUTO_POLL;
 		tw32_f(MAC_MI_MODE, tp->mi_mode);
@@ -3944,7 +3953,7 @@ static int tg3_setup_fiber_phy(struct tg
 	tw32_f(MAC_MODE, tp->mac_mode);
 	udelay(40);
 
-	if (tp->phy_id == PHY_ID_BCM8002)
+	if (tp->phy_id == TG3_PHY_ID_BCM8002)
 		tg3_init_bcm8002(tp);
 
 	/* Enable link change event even when serdes polling.  */
@@ -4317,10 +4326,8 @@ static void tg3_tx_recover(struct tg3 *t
 	BUG_ON((tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) ||
 	       tp->write32_tx_mbox == tg3_write_indirect_mbox);
 
-	printk(KERN_WARNING PFX "%s: The system may be re-ordering memory-"
-	       "mapped I/O cycles to the network device, attempting to "
-	       "recover. Please report the problem to the driver maintainer "
-	       "and include system chipset information.\n", tp->dev->name);
+	netdev_warn(tp->dev, "The system may be re-ordering memory-mapped I/O cycles to the network device, attempting to recover\n"
+		    "Please report the problem to the driver maintainer and include system chipset information.\n");
 
 	spin_lock(&tp->lock);
 	tp->tg3_flags |= TG3_FLAG_TX_RECOVERY_PENDING;
@@ -4529,6 +4536,12 @@ static void tg3_recycle_rx(struct tg3_na
 			   pci_unmap_addr(src_map, mapping));
 	dest_desc->addr_hi = src_desc->addr_hi;
 	dest_desc->addr_lo = src_desc->addr_lo;
+
+	/* Ensure that the update to the skb happens after the physical
+	 * addresses have been transferred to the new BD location.
+	 */
+	smp_wmb();
+
 	src_map->skb = NULL;
 }
 
@@ -4629,11 +4642,16 @@ static int tg3_rx(struct tg3_napi *tnapi
 			if (skb_size < 0)
 				goto drop_it;
 
-			ri->skb = NULL;
-
 			pci_unmap_single(tp->pdev, dma_addr, skb_size,
 					 PCI_DMA_FROMDEVICE);
 
+			/* Ensure that the update to the skb happens
+			 * after the usage of the old DMA mapping.
+			 */
+			smp_wmb();
+
+			ri->skb = NULL;
+
 			skb_put(skb, len);
 		} else {
 			struct sk_buff *copy_skb;
@@ -4710,7 +4728,7 @@ next_pkt_nopost:
 	tw32_rx_mbox(tnapi->consmbox, sw_idx);
 
 	/* Refill RX ring(s). */
-	if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) || tnapi == &tp->napi[1]) {
+	if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)) {
 		if (work_mask & RXD_OPAQUE_RING_STD) {
 			tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
 			tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
@@ -4732,7 +4750,8 @@ next_pkt_nopost:
 		tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
 		tpr->rx_jmb_prod_idx = jmb_prod_idx % TG3_RX_JUMBO_RING_SIZE;
 
-		napi_schedule(&tp->napi[1].napi);
+		if (tnapi != &tp->napi[1])
+			napi_schedule(&tp->napi[1].napi);
 	}
 
 	return received;
@@ -4764,12 +4783,12 @@ static void tg3_poll_link(struct tg3 *tp
 	}
 }
 
-static void tg3_rx_prodring_xfer(struct tg3 *tp,
-				 struct tg3_rx_prodring_set *dpr,
-				 struct tg3_rx_prodring_set *spr)
+static int tg3_rx_prodring_xfer(struct tg3 *tp,
+				struct tg3_rx_prodring_set *dpr,
+				struct tg3_rx_prodring_set *spr)
 {
 	u32 si, di, cpycnt, src_prod_idx;
-	int i;
+	int i, err = 0;
 
 	while (1) {
 		src_prod_idx = spr->rx_std_prod_idx;
@@ -4792,6 +4811,23 @@ static void tg3_rx_prodring_xfer(struct
 		si = spr->rx_std_cons_idx;
 		di = dpr->rx_std_prod_idx;
 
+		for (i = di; i < di + cpycnt; i++) {
+			if (dpr->rx_std_buffers[i].skb) {
+				cpycnt = i - di;
+				err = -ENOSPC;
+				break;
+			}
+		}
+
+		if (!cpycnt)
+			break;
+
+		/* Ensure that updates to the rx_std_buffers ring and the
+		 * shadowed hardware producer ring from tg3_recycle_skb() are
+		 * ordered correctly WRT the skb check above.
+		 */
+		smp_rmb();
+
 		memcpy(&dpr->rx_std_buffers[di],
 		       &spr->rx_std_buffers[si],
 		       cpycnt * sizeof(struct ring_info));
@@ -4832,6 +4868,23 @@ static void tg3_rx_prodring_xfer(struct
 		si = spr->rx_jmb_cons_idx;
 		di = dpr->rx_jmb_prod_idx;
 
+		for (i = di; i < di + cpycnt; i++) {
+			if (dpr->rx_jmb_buffers[i].skb) {
+				cpycnt = i - di;
+				err = -ENOSPC;
+				break;
+			}
+		}
+
+		if (!cpycnt)
+			break;
+
+		/* Ensure that updates to the rx_jmb_buffers ring and the
+		 * shadowed hardware producer ring from tg3_recycle_skb() are
+		 * ordered correctly WRT the skb check above.
+		 */
+		smp_rmb();
+
 		memcpy(&dpr->rx_jmb_buffers[di],
 		       &spr->rx_jmb_buffers[si],
 		       cpycnt * sizeof(struct ring_info));
@@ -4849,6 +4902,8 @@ static void tg3_rx_prodring_xfer(struct
 		dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) %
 				       TG3_RX_JUMBO_RING_SIZE;
 	}
+
+	return err;
 }
 
 static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
@@ -4870,27 +4925,29 @@ static int tg3_poll_work(struct tg3_napi
 		work_done += tg3_rx(tnapi, budget - work_done);
 
 	if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) {
-		int i;
-		u32 std_prod_idx = tp->prodring[0].rx_std_prod_idx;
-		u32 jmb_prod_idx = tp->prodring[0].rx_jmb_prod_idx;
+		struct tg3_rx_prodring_set *dpr = &tp->prodring[0];
+		int i, err = 0;
+		u32 std_prod_idx = dpr->rx_std_prod_idx;
+		u32 jmb_prod_idx = dpr->rx_jmb_prod_idx;
 
-		for (i = 2; i < tp->irq_cnt; i++)
-			tg3_rx_prodring_xfer(tp, tnapi->prodring,
-					     tp->napi[i].prodring);
+		for (i = 1; i < tp->irq_cnt; i++)
+			err |= tg3_rx_prodring_xfer(tp, dpr,
+						    tp->napi[i].prodring);
 
 		wmb();
 
-		if (std_prod_idx != tp->prodring[0].rx_std_prod_idx) {
-			u32 mbox = TG3_RX_STD_PROD_IDX_REG;
-			tw32_rx_mbox(mbox, tp->prodring[0].rx_std_prod_idx);
-		}
+		if (std_prod_idx != dpr->rx_std_prod_idx)
+			tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
+				     dpr->rx_std_prod_idx);
 
-		if (jmb_prod_idx != tp->prodring[0].rx_jmb_prod_idx) {
-			u32 mbox = TG3_RX_JMB_PROD_IDX_REG;
-			tw32_rx_mbox(mbox, tp->prodring[0].rx_jmb_prod_idx);
-		}
+		if (jmb_prod_idx != dpr->rx_jmb_prod_idx)
+			tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG,
+				     dpr->rx_jmb_prod_idx);
 
 		mmiowb();
+
+		if (err)
+			tw32_f(HOSTCC_MODE, tp->coal_now);
 	}
 
 	return work_done;
@@ -5194,8 +5251,7 @@ static int tg3_restart_hw(struct tg3 *tp
 
 	err = tg3_init_hw(tp, reset_phy);
 	if (err) {
-		printk(KERN_ERR PFX "%s: Failed to re-initialize device, "
-		       "aborting.\n", tp->dev->name);
+		netdev_err(tp->dev, "Failed to re-initialize device, aborting\n");
 		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 		tg3_full_unlock(tp);
 		del_timer_sync(&tp->timer);
@@ -5214,7 +5270,7 @@ static void tg3_poll_controller(struct n
 	struct tg3 *tp = netdev_priv(dev);
 
 	for (i = 0; i < tp->irq_cnt; i++)
-		tg3_interrupt(tp->napi[i].irq_vec, dev);
+		tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]);
 }
 #endif
 
@@ -5268,10 +5324,10 @@ out:
 
 static void tg3_dump_short_state(struct tg3 *tp)
 {
-	printk(KERN_ERR PFX "DEBUG: MAC_TX_STATUS[%08x] MAC_RX_STATUS[%08x]\n",
-	       tr32(MAC_TX_STATUS), tr32(MAC_RX_STATUS));
-	printk(KERN_ERR PFX "DEBUG: RDMAC_STATUS[%08x] WDMAC_STATUS[%08x]\n",
-	       tr32(RDMAC_STATUS), tr32(WDMAC_STATUS));
+	netdev_err(tp->dev, "DEBUG: MAC_TX_STATUS[%08x] MAC_RX_STATUS[%08x]\n",
+		   tr32(MAC_TX_STATUS), tr32(MAC_RX_STATUS));
+	netdev_err(tp->dev, "DEBUG: RDMAC_STATUS[%08x] WDMAC_STATUS[%08x]\n",
+		   tr32(RDMAC_STATUS), tr32(WDMAC_STATUS));
 }
 
 static void tg3_tx_timeout(struct net_device *dev)
@@ -5279,8 +5335,7 @@ static void tg3_tx_timeout(struct net_de
 	struct tg3 *tp = netdev_priv(dev);
 
 	if (netif_msg_tx_err(tp)) {
-		printk(KERN_ERR PFX "%s: transmit timed out, resetting\n",
-		       dev->name);
+		netdev_err(dev, "transmit timed out, resetting\n");
 		tg3_dump_short_state(tp);
 	}
 
@@ -5444,8 +5499,7 @@ static netdev_tx_t tg3_start_xmit(struct
 			netif_tx_stop_queue(txq);
 
 			/* This is a hard error, log it. */
-			printk(KERN_ERR PFX "%s: BUG! Tx Ring full when "
-			       "queue awake!\n", dev->name);
+			netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
 		}
 		return NETDEV_TX_BUSY;
 	}
@@ -5648,8 +5702,7 @@ static netdev_tx_t tg3_start_xmit_dma_bu
 			netif_tx_stop_queue(txq);
 
 			/* This is a hard error, log it. */
-			printk(KERN_ERR PFX "%s: BUG! Tx Ring full when "
-			       "queue awake!\n", dev->name);
+			netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
 		}
 		return NETDEV_TX_BUSY;
 	}
@@ -5996,11 +6049,8 @@ static int tg3_rx_prodring_alloc(struct
 	/* Now allocate fresh SKBs for each rx ring. */
 	for (i = 0; i < tp->rx_pending; i++) {
 		if (tg3_alloc_rx_skb(tp, tpr, RXD_OPAQUE_RING_STD, i) < 0) {
-			printk(KERN_WARNING PFX
-			       "%s: Using a smaller RX standard ring, "
-			       "only %d out of %d buffers were allocated "
-			       "successfully.\n",
-			       tp->dev->name, i, tp->rx_pending);
+			netdev_warn(tp->dev, "Using a smaller RX standard ring, only %d out of %d buffers were allocated successfully\n",
+				    i, tp->rx_pending);
 			if (i == 0)
 				goto initfail;
 			tp->rx_pending = i;
@@ -6013,31 +6063,28 @@ static int tg3_rx_prodring_alloc(struct
 
 	memset(tpr->rx_jmb, 0, TG3_RX_JUMBO_RING_BYTES);
 
-	if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
-		for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
-			struct tg3_rx_buffer_desc *rxd;
+	if (!(tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE))
+		goto done;
 
-			rxd = &tpr->rx_jmb[i].std;
-			rxd->idx_len = TG3_RX_JMB_DMA_SZ << RXD_LEN_SHIFT;
-			rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT) |
-				RXD_FLAG_JUMBO;
-			rxd->opaque = (RXD_OPAQUE_RING_JUMBO |
-			       (i << RXD_OPAQUE_INDEX_SHIFT));
-		}
+	for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
+		struct tg3_rx_buffer_desc *rxd;
 
-		for (i = 0; i < tp->rx_jumbo_pending; i++) {
-			if (tg3_alloc_rx_skb(tp, tpr, RXD_OPAQUE_RING_JUMBO,
-					     i) < 0) {
-				printk(KERN_WARNING PFX
-				       "%s: Using a smaller RX jumbo ring, "
-				       "only %d out of %d buffers were "
-				       "allocated successfully.\n",
-				       tp->dev->name, i, tp->rx_jumbo_pending);
-				if (i == 0)
-					goto initfail;
-				tp->rx_jumbo_pending = i;
-				break;
-			}
+		rxd = &tpr->rx_jmb[i].std;
+		rxd->idx_len = TG3_RX_JMB_DMA_SZ << RXD_LEN_SHIFT;
+		rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT) |
+				  RXD_FLAG_JUMBO;
+		rxd->opaque = (RXD_OPAQUE_RING_JUMBO |
+		       (i << RXD_OPAQUE_INDEX_SHIFT));
+	}
+
+	for (i = 0; i < tp->rx_jumbo_pending; i++) {
+		if (tg3_alloc_rx_skb(tp, tpr, RXD_OPAQUE_RING_JUMBO, i) < 0) {
+			netdev_warn(tp->dev, "Using a smaller RX jumbo ring, only %d out of %d buffers were allocated successfully\n",
+				    i, tp->rx_jumbo_pending);
+			if (i == 0)
+				goto initfail;
+			tp->rx_jumbo_pending = i;
+			break;
 		}
 	}
 
@@ -6150,8 +6197,7 @@ static void tg3_free_rings(struct tg3 *t
 			dev_kfree_skb_any(skb);
 		}
 
-		if (tp->irq_cnt == 1 || j != tp->irq_cnt - 1)
-			tg3_rx_prodring_free(tp, &tp->prodring[j]);
+		tg3_rx_prodring_free(tp, &tp->prodring[j]);
 	}
 }
 
@@ -6187,9 +6233,10 @@ static int tg3_init_rings(struct tg3 *tp
 		if (tnapi->rx_rcb)
 			memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
 
-		if ((tp->irq_cnt == 1 || i != tp->irq_cnt - 1) &&
-			tg3_rx_prodring_alloc(tp, &tp->prodring[i]))
+		if (tg3_rx_prodring_alloc(tp, &tp->prodring[i])) {
+			tg3_free_rings(tp);
 			return -ENOMEM;
+		}
 	}
 
 	return 0;
@@ -6236,7 +6283,7 @@ static void tg3_free_consistent(struct t
 		tp->hw_stats = NULL;
 	}
 
-	for (i = 0; i < (tp->irq_cnt == 1 ? 1 : tp->irq_cnt - 1); i++)
+	for (i = 0; i < tp->irq_cnt; i++)
 		tg3_rx_prodring_fini(tp, &tp->prodring[i]);
 }
 
@@ -6248,7 +6295,7 @@ static int tg3_alloc_consistent(struct t
 {
 	int i;
 
-	for (i = 0; i < (tp->irq_cnt == 1 ? 1 : tp->irq_cnt - 1); i++) {
+	for (i = 0; i < tp->irq_cnt; i++) {
 		if (tg3_rx_prodring_init(tp, &tp->prodring[i]))
 			goto err_out;
 	}
@@ -6313,10 +6360,7 @@ static int tg3_alloc_consistent(struct t
 			break;
 		}
 
-		if (tp->irq_cnt == 1)
-			tnapi->prodring = &tp->prodring[0];
-		else if (i)
-			tnapi->prodring = &tp->prodring[i - 1];
+		tnapi->prodring = &tp->prodring[i];
 
 		/*
 		 * If multivector RSS is enabled, vector 0 does not handle
@@ -6380,8 +6424,7 @@ static int tg3_stop_block(struct tg3 *tp
 	}
 
 	if (i == MAX_WAIT_CNT && !silent) {
-		printk(KERN_ERR PFX "tg3_stop_block timed out, "
-		       "ofs=%lx enable_bit=%x\n",
+		pr_err("tg3_stop_block timed out, ofs=%lx enable_bit=%x\n",
 		       ofs, enable_bit);
 		return -ENODEV;
 	}
@@ -6428,9 +6471,8 @@ static int tg3_abort_hw(struct tg3 *tp,
 			break;
 	}
 	if (i >= MAX_WAIT_CNT) {
-		printk(KERN_ERR PFX "tg3_abort_hw timed out for %s, "
-		       "TX_MODE_ENABLE will not clear MAC_TX_MODE=%08x\n",
-		       tp->dev->name, tr32(MAC_TX_MODE));
+		netdev_err(tp->dev, "%s timed out, TX_MODE_ENABLE will not clear MAC_TX_MODE=%08x\n",
+			   __func__, tr32(MAC_TX_MODE));
 		err |= -ENODEV;
 	}
 
@@ -6651,8 +6693,14 @@ static int tg3_poll_fw(struct tg3 *tp)
 	    !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) {
 		tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED;
 
-		printk(KERN_INFO PFX "%s: No firmware running.\n",
-		       tp->dev->name);
+		netdev_info(tp->dev, "No firmware running\n");
+	}
+
+	if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0) {
+		/* The 57765 A0 needs a little more
+		 * time to do some important work.
+		 */
+		mdelay(10);
 	}
 
 	return 0;
@@ -7073,10 +7121,8 @@ static int tg3_halt_cpu(struct tg3 *tp,
 	}
 
 	if (i >= 10000) {
-		printk(KERN_ERR PFX "tg3_reset_cpu timed out for %s, "
-		       "and %s CPU\n",
-		       tp->dev->name,
-		       (offset == RX_CPU_BASE ? "RX" : "TX"));
+		netdev_err(tp->dev, "%s timed out, %s CPU\n",
+			   __func__, offset == RX_CPU_BASE ? "RX" : "TX");
 		return -ENODEV;
 	}
 
@@ -7101,9 +7147,8 @@ static int tg3_load_firmware_cpu(struct
 
 	if (cpu_base == TX_CPU_BASE &&
 	    (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
-		printk(KERN_ERR PFX "tg3_load_firmware_cpu: Trying to load "
-		       "TX cpu firmware on %s which is 5705.\n",
-		       tp->dev->name);
+		netdev_err(tp->dev, "%s: Trying to load TX cpu firmware which is 5705\n",
+			   __func__);
 		return -EINVAL;
 	}
 
@@ -7182,10 +7227,8 @@ static int tg3_load_5701_a0_firmware_fix
 		udelay(1000);
 	}
 	if (i >= 5) {
-		printk(KERN_ERR PFX "tg3_load_firmware fails for %s "
-		       "to set RX CPU PC, is %08x should be %08x\n",
-		       tp->dev->name, tr32(RX_CPU_BASE + CPU_PC),
-		       info.fw_base);
+		netdev_err(tp->dev, "tg3_load_firmware fails to set RX CPU PC, is %08x should be %08x\n",
+			   tr32(RX_CPU_BASE + CPU_PC), info.fw_base);
 		return -ENODEV;
 	}
 	tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
@@ -7248,10 +7291,8 @@ static int tg3_load_tso_firmware(struct
 		udelay(1000);
 	}
 	if (i >= 5) {
-		printk(KERN_ERR PFX "tg3_load_tso_firmware fails for %s "
-		       "to set CPU PC, is %08x should be %08x\n",
-		       tp->dev->name, tr32(cpu_base + CPU_PC),
-		       info.fw_base);
+		netdev_err(tp->dev, "%s fails to set CPU PC, is %08x should be %08x\n",
+			   __func__, tr32(cpu_base + CPU_PC), info.fw_base);
 		return -ENODEV;
 	}
 	tw32(cpu_base + CPU_STATE, 0xffffffff);
@@ -7430,10 +7471,13 @@ static void tg3_rings_reset(struct tg3 *
 		for (i = 1; i < TG3_IRQ_MAX_VECS; i++) {
 			tp->napi[i].tx_prod = 0;
 			tp->napi[i].tx_cons = 0;
-			tw32_mailbox(tp->napi[i].prodmbox, 0);
+			if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+				tw32_mailbox(tp->napi[i].prodmbox, 0);
 			tw32_rx_mbox(tp->napi[i].consmbox, 0);
 			tw32_mailbox_f(tp->napi[i].int_mbox, 1);
 		}
+		if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS))
+			tw32_mailbox(tp->napi[0].prodmbox, 0);
 	} else {
 		tp->napi[0].tx_prod = 0;
 		tp->napi[0].tx_cons = 0;
@@ -7519,8 +7563,7 @@ static int tg3_reset_hw(struct tg3 *tp,
 		tg3_abort_hw(tp, 1);
 	}
 
-	if (reset_phy &&
-	    !(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB))
+	if (reset_phy)
 		tg3_phy_reset(tp);
 
 	err = tg3_chip_reset(tp);
@@ -7565,6 +7608,20 @@ static int tg3_reset_hw(struct tg3 *tp,
 		tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS);
 	}
 
+	if (tp->tg3_flags3 & TG3_FLG3_L1PLLPD_EN) {
+		u32 grc_mode = tr32(GRC_MODE);
+
+		/* Access the lower 1K of PL PCIE block registers. */
+		val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK;
+		tw32(GRC_MODE, val | GRC_MODE_PCIE_PL_SEL);
+
+		val = tr32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL1);
+		tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL1,
+		     val | TG3_PCIE_PL_LO_PHYCTL1_L1PLLPD_EN);
+
+		tw32(GRC_MODE, grc_mode);
+	}
+
 	/* This works around an issue with Athlon chipsets on
 	 * B3 tigon3 silicon.  This bit has no effect on any
 	 * other revision.  But do not set this on PCI Express
@@ -7696,8 +7753,7 @@ static int tg3_reset_hw(struct tg3 *tp,
 		udelay(10);
 	}
 	if (i >= 2000) {
-		printk(KERN_ERR PFX "tg3_reset_hw cannot enable BUFMGR for %s.\n",
-		       tp->dev->name);
+		netdev_err(tp->dev, "%s cannot enable BUFMGR\n", __func__);
 		return -ENODEV;
 	}
 
@@ -7763,7 +7819,7 @@ static int tg3_reset_hw(struct tg3 *tp,
 			tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
 			     (RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT) |
 			     BDINFO_FLAGS_USE_EXT_RECV);
-			if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+			if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
 				tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
 				     NIC_SRAM_RX_JUMBO_BUFFER_DESC);
 		} else {
@@ -7825,6 +7881,9 @@ static int tg3_reset_hw(struct tg3 *tp,
 		      RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
 		      RDMAC_MODE_LNGREAD_ENAB);
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+		rdmac_mode |= RDMAC_MODE_MULT_DMA_RD_DIS;
+
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
@@ -8134,7 +8193,11 @@ static int tg3_reset_hw(struct tg3 *tp,
 	/* Prevent chip from dropping frames when flow control
 	 * is enabled.
 	 */
-	tw32_f(MAC_LOW_WMARK_MAX_RX_FRAME, 2);
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+		val = 1;
+	else
+		val = 2;
+	tw32_f(MAC_LOW_WMARK_MAX_RX_FRAME, val);
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
 	    (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
@@ -8553,16 +8616,15 @@ static int tg3_test_msi(struct tg3 *tp)
 		return err;
 
 	/* MSI test failed, go back to INTx mode */
-	printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, "
-	       "switching to INTx mode. Please report this failure to "
-	       "the PCI maintainer and include system chipset information.\n",
-		       tp->dev->name);
+	netdev_warn(tp->dev, "No interrupt was generated using MSI, switching to INTx mode\n"
+		    "Please report this failure to the PCI maintainer and include system chipset information\n");
 
 	free_irq(tp->napi[0].irq_vec, &tp->napi[0]);
 
 	pci_disable_msi(tp->pdev);
 
 	tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
+	tp->napi[0].irq_vec = tp->pdev->irq;
 
 	err = tg3_request_irq(tp, 0);
 	if (err)
@@ -8589,8 +8651,8 @@ static int tg3_reject_firmware(struct tg
 	const __be32 *fw_data;
 
 	if (reject_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) {
-		printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n",
-		       tp->dev->name, tp->fw_needed);
+		netdev_err(tp->dev, "Failed to load firmware \"%s\"\n",
+			   tp->fw_needed);
 		return -ENOENT;
 	}
 
@@ -8603,8 +8665,8 @@ static int tg3_reject_firmware(struct tg
 
 	tp->fw_len = be32_to_cpu(fw_data[2]);	/* includes bss */
 	if (tp->fw_len < (tp->fw->size - 12)) {
-		printk(KERN_ERR "%s: bogus length %d in \"%s\"\n",
-		       tp->dev->name, tp->fw_len, tp->fw_needed);
+		netdev_err(tp->dev, "bogus length %d in \"%s\"\n",
+			   tp->fw_len, tp->fw_needed);
 		release_firmware(tp->fw);
 		tp->fw = NULL;
 		return -EINVAL;
@@ -8642,9 +8704,8 @@ static bool tg3_enable_msix(struct tg3 *
 			return false;
 		if (pci_enable_msix(tp->pdev, msix_ent, rc))
 			return false;
-		printk(KERN_NOTICE
-		       "%s: Requested %d MSI-X vectors, received %d\n",
-		       tp->dev->name, tp->irq_cnt, rc);
+		netdev_notice(tp->dev, "Requested %d MSI-X vectors, received %d\n",
+			      tp->irq_cnt, rc);
 		tp->irq_cnt = rc;
 	}
 
@@ -8669,8 +8730,7 @@ static void tg3_ints_init(struct tg3 *tp
 		/* All MSI supporting chips should support tagged
 		 * status.  Assert that this is the case.
 		 */
-		printk(KERN_WARNING PFX "%s: MSI without TAGGED? "
-		       "Not using MSI.\n", tp->dev->name);
+		netdev_warn(tp->dev, "MSI without TAGGED? Not using MSI\n");
 		goto defcfg;
 	}
 
@@ -8715,12 +8775,10 @@ static int tg3_open(struct net_device *d
 			if (err)
 				return err;
 		} else if (err) {
-			printk(KERN_WARNING "%s: TSO capability disabled.\n",
-			       tp->dev->name);
+			netdev_warn(tp->dev, "TSO capability disabled\n");
 			tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
 		} else if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) {
-			printk(KERN_NOTICE "%s: TSO capability restored.\n",
-			       tp->dev->name);
+			netdev_notice(tp->dev, "TSO capability restored\n");
 			tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
 		}
 	}
@@ -9386,21 +9444,18 @@ static void __tg3_set_rx_mode(struct net
 	} else if (dev->flags & IFF_ALLMULTI) {
 		/* Accept all multicast. */
 		tg3_set_multi (tp, 1);
-	} else if (dev->mc_count < 1) {
+	} else if (netdev_mc_empty(dev)) {
 		/* Reject all multicast. */
 		tg3_set_multi (tp, 0);
 	} else {
 		/* Accept one or more multicast(s). */
 		struct dev_mc_list *mclist;
-		unsigned int i;
 		u32 mc_filter[4] = { 0, };
 		u32 regidx;
 		u32 bit;
 		u32 crc;
 
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-		     i++, mclist = mclist->next) {
-
+		netdev_for_each_mc_addr(mclist, dev) {
 			crc = calc_crc (mclist->dmi_addr, ETH_ALEN);
 			bit = ~crc & 0x7f;
 			regidx = (bit & 0x60) >> 5;
@@ -9713,7 +9768,7 @@ static int tg3_set_settings(struct net_d
 			   ADVERTISED_Pause |
 			   ADVERTISED_Asym_Pause;
 
-		if (!(tp->tg3_flags2 & TG3_FLAG_10_100_ONLY))
+		if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
 			mask |= ADVERTISED_1000baseT_Half |
 				ADVERTISED_1000baseT_Full;
 
@@ -9992,56 +10047,66 @@ static int tg3_set_pauseparam(struct net
 	int err = 0;
 
 	if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
-		if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
-			return -EAGAIN;
+		u32 newadv;
+		struct phy_device *phydev;
 
-		if (epause->autoneg) {
-			u32 newadv;
-			struct phy_device *phydev;
+		phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
-			phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+		if (!(phydev->supported & SUPPORTED_Pause) ||
+		    (!(phydev->supported & SUPPORTED_Asym_Pause) &&
+		     ((epause->rx_pause && !epause->tx_pause) ||
+		      (!epause->rx_pause && epause->tx_pause))))
+			return -EINVAL;
 
-			if (epause->rx_pause) {
-				if (epause->tx_pause)
-					newadv = ADVERTISED_Pause;
-				else
-					newadv = ADVERTISED_Pause |
-						 ADVERTISED_Asym_Pause;
-			} else if (epause->tx_pause) {
-				newadv = ADVERTISED_Asym_Pause;
+		tp->link_config.flowctrl = 0;
+		if (epause->rx_pause) {
+			tp->link_config.flowctrl |= FLOW_CTRL_RX;
+
+			if (epause->tx_pause) {
+				tp->link_config.flowctrl |= FLOW_CTRL_TX;
+				newadv = ADVERTISED_Pause;
 			} else
-				newadv = 0;
+				newadv = ADVERTISED_Pause |
+					 ADVERTISED_Asym_Pause;
+		} else if (epause->tx_pause) {
+			tp->link_config.flowctrl |= FLOW_CTRL_TX;
+			newadv = ADVERTISED_Asym_Pause;
+		} else
+			newadv = 0;
 
-			if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
-				u32 oldadv = phydev->advertising &
-					     (ADVERTISED_Pause |
-					      ADVERTISED_Asym_Pause);
-				if (oldadv != newadv) {
-					phydev->advertising &=
-						~(ADVERTISED_Pause |
-						  ADVERTISED_Asym_Pause);
-					phydev->advertising |= newadv;
-					err = phy_start_aneg(phydev);
+		if (epause->autoneg)
+			tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
+		else
+			tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
+
+		if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
+			u32 oldadv = phydev->advertising &
+				     (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
+			if (oldadv != newadv) {
+				phydev->advertising &=
+					~(ADVERTISED_Pause |
+					  ADVERTISED_Asym_Pause);
+				phydev->advertising |= newadv;
+				if (phydev->autoneg) {
+					/*
+					 * Always renegotiate the link to
+					 * inform our link partner of our
+					 * flow control settings, even if the
+					 * flow control is forced.  Let
+					 * tg3_adjust_link() do the final
+					 * flow control setup.
+					 */
+					return phy_start_aneg(phydev);
 				}
-			} else {
-				tp->link_config.advertising &=
-						~(ADVERTISED_Pause |
-						  ADVERTISED_Asym_Pause);
-				tp->link_config.advertising |= newadv;
 			}
-		} else {
-			if (epause->rx_pause)
-				tp->link_config.flowctrl |= FLOW_CTRL_RX;
-			else
-				tp->link_config.flowctrl &= ~FLOW_CTRL_RX;
 
-			if (epause->tx_pause)
-				tp->link_config.flowctrl |= FLOW_CTRL_TX;
-			else
-				tp->link_config.flowctrl &= ~FLOW_CTRL_TX;
-
-			if (netif_running(dev))
+			if (!epause->autoneg)
 				tg3_setup_flow_control(tp, 0, 0);
+		} else {
+			tp->link_config.orig_advertising &=
+					~(ADVERTISED_Pause |
+					  ADVERTISED_Asym_Pause);
+			tp->link_config.orig_advertising |= newadv;
 		}
 	} else {
 		int irq_sync = 0;
@@ -10575,8 +10640,7 @@ static int tg3_test_registers(struct tg3
 
 out:
 	if (netif_msg_hw(tp))
-		printk(KERN_ERR PFX "Register test failed at offset %x\n",
-		       offset);
+		pr_err("Register test failed at offset %x\n", offset);
 	tw32(offset, save_val);
 	return -EIO;
 }
@@ -10631,12 +10695,27 @@ static int tg3_test_memory(struct tg3 *t
 		{ 0x00008000, 0x01000},
 		{ 0x00010000, 0x01000},
 		{ 0xffffffff, 0x00000}
+	}, mem_tbl_5717[] = {
+		{ 0x00000200, 0x00008},
+		{ 0x00010000, 0x0a000},
+		{ 0x00020000, 0x13c00},
+		{ 0xffffffff, 0x00000}
+	}, mem_tbl_57765[] = {
+		{ 0x00000200, 0x00008},
+		{ 0x00004000, 0x00800},
+		{ 0x00006000, 0x09800},
+		{ 0x00010000, 0x0a000},
+		{ 0xffffffff, 0x00000}
 	};
 	struct mem_entry *mem_tbl;
 	int err = 0;
 	int i;
 
-	if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+		mem_tbl = mem_tbl_5717;
+	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+		mem_tbl = mem_tbl_57765;
+	else if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
 		mem_tbl = mem_tbl_5755;
 	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
 		mem_tbl = mem_tbl_5906;
@@ -10669,12 +10748,12 @@ static int tg3_run_loopback(struct tg3 *
 	struct tg3_napi *tnapi, *rnapi;
 	struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
 
+	tnapi = &tp->napi[0];
+	rnapi = &tp->napi[0];
 	if (tp->irq_cnt > 1) {
-		tnapi = &tp->napi[1];
 		rnapi = &tp->napi[1];
-	} else {
-		tnapi = &tp->napi[0];
-		rnapi = &tp->napi[0];
+		if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+			tnapi = &tp->napi[1];
 	}
 	coal_now = tnapi->coal_now | rnapi->coal_now;
 
@@ -10711,8 +10790,12 @@ static int tg3_run_loopback(struct tg3 *
 
 		mac_mode = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
 		if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
-			if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
-				tg3_writephy(tp, MII_TG3_FET_PTEST, 0x1800);
+			tg3_writephy(tp, MII_TG3_FET_PTEST,
+				     MII_TG3_FET_PTEST_FRC_TX_LINK |
+				     MII_TG3_FET_PTEST_FRC_TX_LOCK);
+			/* The write needs to be flushed for the AC131 */
+			if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+				tg3_readphy(tp, MII_TG3_FET_PTEST, &val);
 			mac_mode |= MAC_MODE_PORT_MODE_MII;
 		} else
 			mac_mode |= MAC_MODE_PORT_MODE_GMII;
@@ -10724,9 +10807,10 @@ static int tg3_run_loopback(struct tg3 *
 			tw32_f(MAC_RX_MODE, tp->rx_mode);
 		}
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
-			if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401)
+			u32 masked_phy_id = tp->phy_id & TG3_PHY_ID_MASK;
+			if (masked_phy_id == TG3_PHY_ID_BCM5401)
 				mac_mode &= ~MAC_MODE_LINK_POLARITY;
-			else if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5411)
+			else if (masked_phy_id == TG3_PHY_ID_BCM5411)
 				mac_mode |= MAC_MODE_LINK_POLARITY;
 			tg3_writephy(tp, MII_TG3_EXT_CTRL,
 				     MII_TG3_EXT_CTRL_LNK3_LED_MODE);
@@ -11683,8 +11767,8 @@ static void __devinit tg3_nvram_init(str
 		tp->tg3_flags |= TG3_FLAG_NVRAM;
 
 		if (tg3_nvram_lock(tp)) {
-			printk(KERN_WARNING PFX "%s: Cannot get nvarm lock, "
-			       "tg3_nvram_init failed.\n", tp->dev->name);
+			netdev_warn(tp->dev, "Cannot get nvram lock, %s failed\n",
+				    __func__);
 			return;
 		}
 		tg3_enable_nvram_access(tp);
@@ -11982,45 +12066,71 @@ struct subsys_tbl_ent {
 	u32 phy_id;
 };
 
-static struct subsys_tbl_ent subsys_id_to_phy_id[] = {
+static struct subsys_tbl_ent subsys_id_to_phy_id[] __devinitdata = {
 	/* Broadcom boards. */
-	{ PCI_VENDOR_ID_BROADCOM, 0x1644, PHY_ID_BCM5401 }, /* BCM95700A6 */
-	{ PCI_VENDOR_ID_BROADCOM, 0x0001, PHY_ID_BCM5701 }, /* BCM95701A5 */
-	{ PCI_VENDOR_ID_BROADCOM, 0x0002, PHY_ID_BCM8002 }, /* BCM95700T6 */
-	{ PCI_VENDOR_ID_BROADCOM, 0x0003, 0 },		    /* BCM95700A9 */
-	{ PCI_VENDOR_ID_BROADCOM, 0x0005, PHY_ID_BCM5701 }, /* BCM95701T1 */
-	{ PCI_VENDOR_ID_BROADCOM, 0x0006, PHY_ID_BCM5701 }, /* BCM95701T8 */
-	{ PCI_VENDOR_ID_BROADCOM, 0x0007, 0 },		    /* BCM95701A7 */
-	{ PCI_VENDOR_ID_BROADCOM, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */
-	{ PCI_VENDOR_ID_BROADCOM, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */
-	{ PCI_VENDOR_ID_BROADCOM, 0x0009, PHY_ID_BCM5703 }, /* BCM95703Ax1 */
-	{ PCI_VENDOR_ID_BROADCOM, 0x8009, PHY_ID_BCM5703 }, /* BCM95703Ax2 */
+	{ TG3PCI_SUBVENDOR_ID_BROADCOM,
+	  TG3PCI_SUBDEVICE_ID_BROADCOM_95700A6, TG3_PHY_ID_BCM5401 },
+	{ TG3PCI_SUBVENDOR_ID_BROADCOM,
+	  TG3PCI_SUBDEVICE_ID_BROADCOM_95701A5, TG3_PHY_ID_BCM5701 },
+	{ TG3PCI_SUBVENDOR_ID_BROADCOM,
+	  TG3PCI_SUBDEVICE_ID_BROADCOM_95700T6, TG3_PHY_ID_BCM8002 },
+	{ TG3PCI_SUBVENDOR_ID_BROADCOM,
+	  TG3PCI_SUBDEVICE_ID_BROADCOM_95700A9, 0 },
+	{ TG3PCI_SUBVENDOR_ID_BROADCOM,
+	  TG3PCI_SUBDEVICE_ID_BROADCOM_95701T1, TG3_PHY_ID_BCM5701 },
+	{ TG3PCI_SUBVENDOR_ID_BROADCOM,
+	  TG3PCI_SUBDEVICE_ID_BROADCOM_95701T8, TG3_PHY_ID_BCM5701 },
+	{ TG3PCI_SUBVENDOR_ID_BROADCOM,
+	  TG3PCI_SUBDEVICE_ID_BROADCOM_95701A7, 0 },
+	{ TG3PCI_SUBVENDOR_ID_BROADCOM,
+	  TG3PCI_SUBDEVICE_ID_BROADCOM_95701A10, TG3_PHY_ID_BCM5701 },
+	{ TG3PCI_SUBVENDOR_ID_BROADCOM,
+	  TG3PCI_SUBDEVICE_ID_BROADCOM_95701A12, TG3_PHY_ID_BCM5701 },
+	{ TG3PCI_SUBVENDOR_ID_BROADCOM,
+	  TG3PCI_SUBDEVICE_ID_BROADCOM_95703AX1, TG3_PHY_ID_BCM5703 },
+	{ TG3PCI_SUBVENDOR_ID_BROADCOM,
+	  TG3PCI_SUBDEVICE_ID_BROADCOM_95703AX2, TG3_PHY_ID_BCM5703 },
 
 	/* 3com boards. */
-	{ PCI_VENDOR_ID_3COM, 0x1000, PHY_ID_BCM5401 }, /* 3C996T */
-	{ PCI_VENDOR_ID_3COM, 0x1006, PHY_ID_BCM5701 }, /* 3C996BT */
-	{ PCI_VENDOR_ID_3COM, 0x1004, 0 },		/* 3C996SX */
-	{ PCI_VENDOR_ID_3COM, 0x1007, PHY_ID_BCM5701 }, /* 3C1000T */
-	{ PCI_VENDOR_ID_3COM, 0x1008, PHY_ID_BCM5701 }, /* 3C940BR01 */
+	{ TG3PCI_SUBVENDOR_ID_3COM,
+	  TG3PCI_SUBDEVICE_ID_3COM_3C996T, TG3_PHY_ID_BCM5401 },
+	{ TG3PCI_SUBVENDOR_ID_3COM,
+	  TG3PCI_SUBDEVICE_ID_3COM_3C996BT, TG3_PHY_ID_BCM5701 },
+	{ TG3PCI_SUBVENDOR_ID_3COM,
+	  TG3PCI_SUBDEVICE_ID_3COM_3C996SX, 0 },
+	{ TG3PCI_SUBVENDOR_ID_3COM,
+	  TG3PCI_SUBDEVICE_ID_3COM_3C1000T, TG3_PHY_ID_BCM5701 },
+	{ TG3PCI_SUBVENDOR_ID_3COM,
+	  TG3PCI_SUBDEVICE_ID_3COM_3C940BR01, TG3_PHY_ID_BCM5701 },
 
 	/* DELL boards. */
-	{ PCI_VENDOR_ID_DELL, 0x00d1, PHY_ID_BCM5401 }, /* VIPER */
-	{ PCI_VENDOR_ID_DELL, 0x0106, PHY_ID_BCM5401 }, /* JAGUAR */
-	{ PCI_VENDOR_ID_DELL, 0x0109, PHY_ID_BCM5411 }, /* MERLOT */
-	{ PCI_VENDOR_ID_DELL, 0x010a, PHY_ID_BCM5411 }, /* SLIM_MERLOT */
+	{ TG3PCI_SUBVENDOR_ID_DELL,
+	  TG3PCI_SUBDEVICE_ID_DELL_VIPER, TG3_PHY_ID_BCM5401 },
+	{ TG3PCI_SUBVENDOR_ID_DELL,
+	  TG3PCI_SUBDEVICE_ID_DELL_JAGUAR, TG3_PHY_ID_BCM5401 },
+	{ TG3PCI_SUBVENDOR_ID_DELL,
+	  TG3PCI_SUBDEVICE_ID_DELL_MERLOT, TG3_PHY_ID_BCM5411 },
+	{ TG3PCI_SUBVENDOR_ID_DELL,
+	  TG3PCI_SUBDEVICE_ID_DELL_SLIM_MERLOT, TG3_PHY_ID_BCM5411 },
 
 	/* Compaq boards. */
-	{ PCI_VENDOR_ID_COMPAQ, 0x007c, PHY_ID_BCM5701 }, /* BANSHEE */
-	{ PCI_VENDOR_ID_COMPAQ, 0x009a, PHY_ID_BCM5701 }, /* BANSHEE_2 */
-	{ PCI_VENDOR_ID_COMPAQ, 0x007d, 0 },		  /* CHANGELING */
-	{ PCI_VENDOR_ID_COMPAQ, 0x0085, PHY_ID_BCM5701 }, /* NC7780 */
-	{ PCI_VENDOR_ID_COMPAQ, 0x0099, PHY_ID_BCM5701 }, /* NC7780_2 */
+	{ TG3PCI_SUBVENDOR_ID_COMPAQ,
+	  TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE, TG3_PHY_ID_BCM5701 },
+	{ TG3PCI_SUBVENDOR_ID_COMPAQ,
+	  TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE_2, TG3_PHY_ID_BCM5701 },
+	{ TG3PCI_SUBVENDOR_ID_COMPAQ,
+	  TG3PCI_SUBDEVICE_ID_COMPAQ_CHANGELING, 0 },
+	{ TG3PCI_SUBVENDOR_ID_COMPAQ,
+	  TG3PCI_SUBDEVICE_ID_COMPAQ_NC7780, TG3_PHY_ID_BCM5701 },
+	{ TG3PCI_SUBVENDOR_ID_COMPAQ,
+	  TG3PCI_SUBDEVICE_ID_COMPAQ_NC7780_2, TG3_PHY_ID_BCM5701 },
 
 	/* IBM boards. */
-	{ PCI_VENDOR_ID_IBM, 0x0281, 0 } /* IBM??? */
+	{ TG3PCI_SUBVENDOR_ID_IBM,
+	  TG3PCI_SUBDEVICE_ID_IBM_5703SAX2, 0 }
 };
 
-static inline struct subsys_tbl_ent *lookup_by_subsys(struct tg3 *tp)
+static struct subsys_tbl_ent * __devinit tg3_lookup_by_subsys(struct tg3 *tp)
 {
 	int i;
 
@@ -12061,7 +12171,7 @@ static void __devinit tg3_get_eeprom_hw_
 	val = tr32(MEMARB_MODE);
 	tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE);
 
-	tp->phy_id = PHY_ID_INVALID;
+	tp->phy_id = TG3_PHY_ID_INVALID;
 	tp->led_ctrl = LED_CTRL_MODE_PHY_1;
 
 	/* Assume an onboard device and WOL capable by default.  */
@@ -12235,8 +12345,8 @@ static void __devinit tg3_get_eeprom_hw_
 				tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND;
 		}
 
-		if (cfg4 & NIC_SRAM_RGMII_STD_IBND_DISABLE)
-			tp->tg3_flags3 |= TG3_FLG3_RGMII_STD_IBND_DISABLE;
+		if (cfg4 & NIC_SRAM_RGMII_INBAND_DISABLE)
+			tp->tg3_flags3 |= TG3_FLG3_RGMII_INBAND_DISABLE;
 		if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_RX_EN)
 			tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_RX_EN;
 		if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_TX_EN)
@@ -12312,7 +12422,7 @@ static int __devinit tg3_phy_probe(struc
 	err = 0;
 	if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
 	    (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
-		hw_phy_id = hw_phy_id_masked = PHY_ID_INVALID;
+		hw_phy_id = hw_phy_id_masked = TG3_PHY_ID_INVALID;
 	} else {
 		/* Now read the physical PHY_ID from the chip and verify
 		 * that it is sane.  If it doesn't look good, we fall back
@@ -12326,17 +12436,17 @@ static int __devinit tg3_phy_probe(struc
 		hw_phy_id |= (hw_phy_id_2 & 0xfc00) << 16;
 		hw_phy_id |= (hw_phy_id_2 & 0x03ff) <<  0;
 
-		hw_phy_id_masked = hw_phy_id & PHY_ID_MASK;
+		hw_phy_id_masked = hw_phy_id & TG3_PHY_ID_MASK;
 	}
 
-	if (!err && KNOWN_PHY_ID(hw_phy_id_masked)) {
+	if (!err && TG3_KNOWN_PHY_ID(hw_phy_id_masked)) {
 		tp->phy_id = hw_phy_id;
-		if (hw_phy_id_masked == PHY_ID_BCM8002)
+		if (hw_phy_id_masked == TG3_PHY_ID_BCM8002)
 			tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
 		else
 			tp->tg3_flags2 &= ~TG3_FLG2_PHY_SERDES;
 	} else {
-		if (tp->phy_id != PHY_ID_INVALID) {
+		if (tp->phy_id != TG3_PHY_ID_INVALID) {
 			/* Do nothing, phy ID already set up in
 			 * tg3_get_eeprom_hw_cfg().
 			 */
@@ -12346,13 +12456,13 @@ static int __devinit tg3_phy_probe(struc
 			/* No eeprom signature?  Try the hardcoded
 			 * subsys device table.
 			 */
-			p = lookup_by_subsys(tp);
+			p = tg3_lookup_by_subsys(tp);
 			if (!p)
 				return -ENODEV;
 
 			tp->phy_id = p->phy_id;
 			if (!tp->phy_id ||
-			    tp->phy_id == PHY_ID_BCM8002)
+			    tp->phy_id == TG3_PHY_ID_BCM8002)
 				tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
 		}
 	}
@@ -12404,13 +12514,11 @@ static int __devinit tg3_phy_probe(struc
 	}
 
 skip_phy_reset:
-	if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
+	if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5401) {
 		err = tg3_init_5401phy_dsp(tp);
 		if (err)
 			return err;
-	}
 
-	if (!err && ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401)) {
 		err = tg3_init_5401phy_dsp(tp);
 	}
 
@@ -12431,7 +12539,8 @@ skip_phy_reset:
 static void __devinit tg3_read_partno(struct tg3 *tp)
 {
 	unsigned char vpd_data[TG3_NVM_VPD_LEN];   /* in little-endian format */
-	unsigned int i;
+	unsigned int block_end, rosize, len;
+	int i = 0;
 	u32 magic;
 
 	if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
@@ -12453,7 +12562,7 @@ static void __devinit tg3_read_partno(st
 		}
 	} else {
 		ssize_t cnt;
-		unsigned int pos = 0, i = 0;
+		unsigned int pos = 0;
 
 		for (; pos < TG3_NVM_VPD_LEN && i < 3; i++, pos += cnt) {
 			cnt = pci_read_vpd(tp->pdev, pos,
@@ -12468,51 +12577,33 @@ static void __devinit tg3_read_partno(st
 			goto out_not_found;
 	}
 
-	/* Now parse and find the part number. */
-	for (i = 0; i < TG3_NVM_VPD_LEN - 2; ) {
-		unsigned char val = vpd_data[i];
-		unsigned int block_end;
-
-		if (val == 0x82 || val == 0x91) {
-			i = (i + 3 +
-			     (vpd_data[i + 1] +
-			      (vpd_data[i + 2] << 8)));
-			continue;
-		}
-
-		if (val != 0x90)
-			goto out_not_found;
+	i = pci_vpd_find_tag(vpd_data, 0, TG3_NVM_VPD_LEN,
+			     PCI_VPD_LRDT_RO_DATA);
+	if (i < 0)
+		goto out_not_found;
 
-		block_end = (i + 3 +
-			     (vpd_data[i + 1] +
-			      (vpd_data[i + 2] << 8)));
-		i += 3;
+	rosize = pci_vpd_lrdt_size(&vpd_data[i]);
+	block_end = i + PCI_VPD_LRDT_TAG_SIZE + rosize;
+	i += PCI_VPD_LRDT_TAG_SIZE;
 
-		if (block_end > TG3_NVM_VPD_LEN)
-			goto out_not_found;
+	if (block_end > TG3_NVM_VPD_LEN)
+		goto out_not_found;
 
-		while (i < (block_end - 2)) {
-			if (vpd_data[i + 0] == 'P' &&
-			    vpd_data[i + 1] == 'N') {
-				int partno_len = vpd_data[i + 2];
+	i = pci_vpd_find_info_keyword(vpd_data, i, rosize,
+				      PCI_VPD_RO_KEYWORD_PARTNO);
+	if (i < 0)
+		goto out_not_found;
 
-				i += 3;
-				if (partno_len > TG3_BPN_SIZE ||
-				    (partno_len + i) > TG3_NVM_VPD_LEN)
-					goto out_not_found;
+	len = pci_vpd_info_field_size(&vpd_data[i]);
 
-				memcpy(tp->board_part_number,
-				       &vpd_data[i], partno_len);
+	i += PCI_VPD_INFO_FLD_HDR_SIZE;
+	if (len > TG3_BPN_SIZE ||
+	    (len + i) > TG3_NVM_VPD_LEN)
+		goto out_not_found;
 
-				/* Success. */
-				return;
-			}
-			i += 3 + vpd_data[i + 2];
-		}
+	memcpy(tp->board_part_number, &vpd_data[i], len);
 
-		/* Part number not found. */
-		goto out_not_found;
-	}
+	return;
 
 out_not_found:
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
@@ -12529,8 +12620,24 @@ out_not_found:
 	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
 		 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57788)
 		strcpy(tp->board_part_number, "BCM57788");
-	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
+		 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57761)
+		strcpy(tp->board_part_number, "BCM57761");
+	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
+		 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57765)
 		strcpy(tp->board_part_number, "BCM57765");
+	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
+		 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781)
+		strcpy(tp->board_part_number, "BCM57781");
+	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
+		 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785)
+		strcpy(tp->board_part_number, "BCM57785");
+	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
+		 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791)
+		strcpy(tp->board_part_number, "BCM57791");
+	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
+		 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795)
+		strcpy(tp->board_part_number, "BCM57795");
 	else
 		strcpy(tp->board_part_number, "none");
 }
@@ -12633,6 +12740,12 @@ static void __devinit tg3_read_sb_ver(st
 	case TG3_EEPROM_SB_REVISION_3:
 		offset = TG3_EEPROM_SB_F1R3_EDH_OFF;
 		break;
+	case TG3_EEPROM_SB_REVISION_4:
+		offset = TG3_EEPROM_SB_F1R4_EDH_OFF;
+		break;
+	case TG3_EEPROM_SB_REVISION_5:
+		offset = TG3_EEPROM_SB_F1R5_EDH_OFF;
+		break;
 	default:
 		return;
 	}
@@ -13093,6 +13206,8 @@ static int __devinit tg3_get_invariants(
 			    tp->pci_chip_rev_id == CHIPREV_ID_57780_A0 ||
 			    tp->pci_chip_rev_id == CHIPREV_ID_57780_A1)
 				tp->tg3_flags3 |= TG3_FLG3_CLKREQ_BUG;
+		} else if (tp->pci_chip_rev_id == CHIPREV_ID_5717_A0) {
+			tp->tg3_flags3 |= TG3_FLG3_L1PLLPD_EN;
 		}
 	} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
 		tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
@@ -13100,8 +13215,7 @@ static int __devinit tg3_get_invariants(
 		   (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
 		tp->pcix_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_PCIX);
 		if (!tp->pcix_cap) {
-			printk(KERN_ERR PFX "Cannot find PCI-X "
-					    "capability, aborting.\n");
+			pr_err("Cannot find PCI-X capability, aborting\n");
 			return -EIO;
 		}
 
@@ -13281,7 +13395,8 @@ static int __devinit tg3_get_invariants(
 		tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
 		tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
 
 	if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
@@ -13297,8 +13412,7 @@ static int __devinit tg3_get_invariants(
 	/* Force the chip into D0. */
 	err = tg3_set_power_state(tp, PCI_D0);
 	if (err) {
-		printk(KERN_ERR PFX "(%s) transition to D0 failed\n",
-		       pci_name(tp->pdev));
+		pr_err("(%s) transition to D0 failed\n", pci_name(tp->pdev));
 		return err;
 	}
 
@@ -13465,12 +13579,14 @@ static int __devinit tg3_get_invariants(
 	      tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F ||
 	      tp->pdev->device == PCI_DEVICE_ID_TIGON3_5787F)) ||
 	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790 ||
+	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791 ||
+	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795 ||
 	    (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET))
 		tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
 
 	err = tg3_phy_probe(tp);
 	if (err) {
-		printk(KERN_ERR PFX "(%s) phy probe failed, err %d\n",
+		pr_err("(%s) phy probe failed, err %d\n",
 		       pci_name(tp->pdev), err);
 		/* ... but do not return immediately ... */
 		tg3_mdio_fini(tp);
@@ -13980,7 +14096,8 @@ static int __devinit tg3_test_dma(struct
 		/* Send the buffer to the chip. */
 		ret = tg3_do_test_dma(tp, buf, buf_dma, TEST_BUFFER_SIZE, 1);
 		if (ret) {
-			printk(KERN_ERR "tg3_test_dma() Write the buffer failed %d\n", ret);
+			pr_err("tg3_test_dma() Write the buffer failed %d\n",
+			       ret);
 			break;
 		}
 
@@ -13990,7 +14107,8 @@ static int __devinit tg3_test_dma(struct
 			u32 val;
 			tg3_read_mem(tp, 0x2100 + (i*4), &val);
 			if (le32_to_cpu(val) != p[i]) {
-				printk(KERN_ERR "  tg3_test_dma()  Card buffer corrupted on write! (%d != %d)\n", val, i);
+				pr_err("  tg3_test_dma()  Card buffer corrupted on write! (%d != %d)\n",
+				       val, i);
 				/* ret = -ENODEV here? */
 			}
 			p[i] = 0;
@@ -13999,7 +14117,8 @@ static int __devinit tg3_test_dma(struct
 		/* Now read it back. */
 		ret = tg3_do_test_dma(tp, buf, buf_dma, TEST_BUFFER_SIZE, 0);
 		if (ret) {
-			printk(KERN_ERR "tg3_test_dma() Read the buffer failed %d\n", ret);
+			pr_err("tg3_test_dma() Read the buffer failed %d\n",
+			       ret);
 
 			break;
 		}
@@ -14016,7 +14135,8 @@ static int __devinit tg3_test_dma(struct
 				tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
 				break;
 			} else {
-				printk(KERN_ERR "tg3_test_dma() buffer corrupted on read back! (%d != %d)\n", p[i], i);
+				pr_err("tg3_test_dma() buffer corrupted on read back! (%d != %d)\n",
+				       p[i], i);
 				ret = -ENODEV;
 				goto out;
 			}
@@ -14077,9 +14197,22 @@ static void __devinit tg3_init_link_conf
 
 static void __devinit tg3_init_bufmgr_config(struct tg3 *tp)
 {
-	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765) {
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+		tp->bufmgr_config.mbuf_read_dma_low_water =
+			DEFAULT_MB_RDMA_LOW_WATER_5705;
+		tp->bufmgr_config.mbuf_mac_rx_low_water =
+			DEFAULT_MB_MACRX_LOW_WATER_57765;
+		tp->bufmgr_config.mbuf_high_water =
+			DEFAULT_MB_HIGH_WATER_57765;
+
+		tp->bufmgr_config.mbuf_read_dma_low_water_jumbo =
+			DEFAULT_MB_RDMA_LOW_WATER_5705;
+		tp->bufmgr_config.mbuf_mac_rx_low_water_jumbo =
+			DEFAULT_MB_MACRX_LOW_WATER_JUMBO_57765;
+		tp->bufmgr_config.mbuf_high_water_jumbo =
+			DEFAULT_MB_HIGH_WATER_JUMBO_57765;
+	} else if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
 		tp->bufmgr_config.mbuf_read_dma_low_water =
 			DEFAULT_MB_RDMA_LOW_WATER_5705;
 		tp->bufmgr_config.mbuf_mac_rx_low_water =
@@ -14121,26 +14254,28 @@ static void __devinit tg3_init_bufmgr_co
 
 static char * __devinit tg3_phy_string(struct tg3 *tp)
 {
-	switch (tp->phy_id & PHY_ID_MASK) {
-	case PHY_ID_BCM5400:	return "5400";
-	case PHY_ID_BCM5401:	return "5401";
-	case PHY_ID_BCM5411:	return "5411";
-	case PHY_ID_BCM5701:	return "5701";
-	case PHY_ID_BCM5703:	return "5703";
-	case PHY_ID_BCM5704:	return "5704";
-	case PHY_ID_BCM5705:	return "5705";
-	case PHY_ID_BCM5750:	return "5750";
-	case PHY_ID_BCM5752:	return "5752";
-	case PHY_ID_BCM5714:	return "5714";
-	case PHY_ID_BCM5780:	return "5780";
-	case PHY_ID_BCM5755:	return "5755";
-	case PHY_ID_BCM5787:	return "5787";
-	case PHY_ID_BCM5784:	return "5784";
-	case PHY_ID_BCM5756:	return "5722/5756";
-	case PHY_ID_BCM5906:	return "5906";
-	case PHY_ID_BCM5761:	return "5761";
-	case PHY_ID_BCM5717:	return "5717";
-	case PHY_ID_BCM8002:	return "8002/serdes";
+	switch (tp->phy_id & TG3_PHY_ID_MASK) {
+	case TG3_PHY_ID_BCM5400:	return "5400";
+	case TG3_PHY_ID_BCM5401:	return "5401";
+	case TG3_PHY_ID_BCM5411:	return "5411";
+	case TG3_PHY_ID_BCM5701:	return "5701";
+	case TG3_PHY_ID_BCM5703:	return "5703";
+	case TG3_PHY_ID_BCM5704:	return "5704";
+	case TG3_PHY_ID_BCM5705:	return "5705";
+	case TG3_PHY_ID_BCM5750:	return "5750";
+	case TG3_PHY_ID_BCM5752:	return "5752";
+	case TG3_PHY_ID_BCM5714:	return "5714";
+	case TG3_PHY_ID_BCM5780:	return "5780";
+	case TG3_PHY_ID_BCM5755:	return "5755";
+	case TG3_PHY_ID_BCM5787:	return "5787";
+	case TG3_PHY_ID_BCM5784:	return "5784";
+	case TG3_PHY_ID_BCM5756:	return "5722/5756";
+	case TG3_PHY_ID_BCM5906:	return "5906";
+	case TG3_PHY_ID_BCM5761:	return "5761";
+	case TG3_PHY_ID_BCM5718C:	return "5718C";
+	case TG3_PHY_ID_BCM5718S:	return "5718S";
+	case TG3_PHY_ID_BCM57765:	return "57765";
+	case TG3_PHY_ID_BCM8002:	return "8002/serdes";
 	case 0:			return "serdes";
 	default:		return "unknown";
 	}
@@ -14282,7 +14417,6 @@ static const struct net_device_ops tg3_n
 static int __devinit tg3_init_one(struct pci_dev *pdev,
 				  const struct pci_device_id *ent)
 {
-	static int tg3_version_printed = 0;
 	struct net_device *dev;
 	struct tg3 *tp;
 	int i, err, pm_cap;
@@ -14290,20 +14424,17 @@ static int __devinit tg3_init_one(struct
 	char str[40];
 	u64 dma_mask, persist_dma_mask;
 
-	if (tg3_version_printed++ == 0)
-		printk(KERN_INFO "%s", version);
+	printk_once(KERN_INFO "%s\n", version);
 
 	err = pci_enable_device(pdev);
 	if (err) {
-		printk(KERN_ERR PFX "Cannot enable PCI device, "
-		       "aborting.\n");
+		pr_err("Cannot enable PCI device, aborting\n");
 		return err;
 	}
 
 	err = pci_request_regions(pdev, DRV_MODULE_NAME);
 	if (err) {
-		printk(KERN_ERR PFX "Cannot obtain PCI resources, "
-		       "aborting.\n");
+		pr_err("Cannot obtain PCI resources, aborting\n");
 		goto err_out_disable_pdev;
 	}
 
@@ -14312,15 +14443,14 @@ static int __devinit tg3_init_one(struct
 	/* Find power-management capability. */
 	pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
 	if (pm_cap == 0) {
-		printk(KERN_ERR PFX "Cannot find PowerManagement capability, "
-		       "aborting.\n");
+		pr_err("Cannot find PowerManagement capability, aborting\n");
 		err = -EIO;
 		goto err_out_free_res;
 	}
 
 	dev = alloc_etherdev_mq(sizeof(*tp), TG3_IRQ_MAX_VECS);
 	if (!dev) {
-		printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
+		pr_err("Etherdev alloc failed, aborting\n");
 		err = -ENOMEM;
 		goto err_out_free_res;
 	}
@@ -14370,8 +14500,7 @@ static int __devinit tg3_init_one(struct
 
 	tp->regs = pci_ioremap_bar(pdev, BAR_0);
 	if (!tp->regs) {
-		printk(KERN_ERR PFX "Cannot map device registers, "
-		       "aborting.\n");
+		netdev_err(dev, "Cannot map device registers, aborting\n");
 		err = -ENOMEM;
 		goto err_out_free_dev;
 	}
@@ -14387,8 +14516,7 @@ static int __devinit tg3_init_one(struct
 
 	err = tg3_get_invariants(tp);
 	if (err) {
-		printk(KERN_ERR PFX "Problem fetching invariants of chip, "
-		       "aborting.\n");
+		netdev_err(dev, "Problem fetching invariants of chip, aborting\n");
 		goto err_out_iounmap;
 	}
 
@@ -14423,8 +14551,7 @@ static int __devinit tg3_init_one(struct
 			err = pci_set_consistent_dma_mask(pdev,
 							  persist_dma_mask);
 			if (err < 0) {
-				printk(KERN_ERR PFX "Unable to obtain 64 bit "
-				       "DMA for consistent allocations\n");
+				netdev_err(dev, "Unable to obtain 64 bit DMA for consistent allocations\n");
 				goto err_out_iounmap;
 			}
 		}
@@ -14432,8 +14559,7 @@ static int __devinit tg3_init_one(struct
 	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");
+			netdev_err(dev, "No usable DMA configuration, aborting\n");
 			goto err_out_iounmap;
 		}
 	}
@@ -14482,16 +14608,14 @@ static int __devinit tg3_init_one(struct
 
 	err = tg3_get_device_address(tp);
 	if (err) {
-		printk(KERN_ERR PFX "Could not obtain valid ethernet address, "
-		       "aborting.\n");
+		netdev_err(dev, "Could not obtain valid ethernet address, aborting\n");
 		goto err_out_iounmap;
 	}
 
 	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
 		tp->aperegs = pci_ioremap_bar(pdev, BAR_2);
 		if (!tp->aperegs) {
-			printk(KERN_ERR PFX "Cannot map APE registers, "
-			       "aborting.\n");
+			netdev_err(dev, "Cannot map APE registers, aborting\n");
 			err = -ENOMEM;
 			goto err_out_iounmap;
 		}
@@ -14515,7 +14639,7 @@ static int __devinit tg3_init_one(struct
 
 	err = tg3_test_dma(tp);
 	if (err) {
-		printk(KERN_ERR PFX "DMA engine test failed, aborting.\n");
+		netdev_err(dev, "DMA engine test failed, aborting\n");
 		goto err_out_apeunmap;
 	}
 
@@ -14576,45 +14700,39 @@ static int __devinit tg3_init_one(struct
 
 	err = register_netdev(dev);
 	if (err) {
-		printk(KERN_ERR PFX "Cannot register net device, "
-		       "aborting.\n");
+		netdev_err(dev, "Cannot register net device, aborting\n");
 		goto err_out_apeunmap;
 	}
 
-	printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x] (%s) MAC address %pM\n",
-	       dev->name,
-	       tp->board_part_number,
-	       tp->pci_chip_rev_id,
-	       tg3_bus_string(tp, str),
-	       dev->dev_addr);
+	netdev_info(dev, "Tigon3 [partno(%s) rev %04x] (%s) MAC address %pM\n",
+		    tp->board_part_number,
+		    tp->pci_chip_rev_id,
+		    tg3_bus_string(tp, str),
+		    dev->dev_addr);
 
 	if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
 		struct phy_device *phydev;
 		phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
-		printk(KERN_INFO
-		       "%s: attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
-		       tp->dev->name, phydev->drv->name,
-		       dev_name(&phydev->dev));
+		netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
+			    phydev->drv->name, dev_name(&phydev->dev));
 	} else
-		printk(KERN_INFO
-		       "%s: attached PHY is %s (%s Ethernet) (WireSpeed[%d])\n",
-		       tp->dev->name, tg3_phy_string(tp),
-		       ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100Base-TX" :
-			((tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) ? "1000Base-SX" :
-			 "10/100/1000Base-T")),
-		       (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0);
+		netdev_info(dev, "attached PHY is %s (%s Ethernet) (WireSpeed[%d])\n",
+			    tg3_phy_string(tp),
+			    ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100Base-TX" :
+			     ((tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) ? "1000Base-SX" :
+			      "10/100/1000Base-T")),
+			    (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0);
 
-	printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] MIirq[%d] ASF[%d] TSOcap[%d]\n",
-	       dev->name,
-	       (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0,
-	       (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0,
-	       (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0,
-	       (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0,
-	       (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_BIT_MASK(32)) ? 32 :
-	        (((u64) pdev->dma_mask == DMA_BIT_MASK(40)) ? 40 : 64));
+	netdev_info(dev, "RXcsums[%d] LinkChgREG[%d] MIirq[%d] ASF[%d] TSOcap[%d]\n",
+		    (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0,
+		    (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0,
+		    (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0,
+		    (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0,
+		    (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
+	netdev_info(dev, "dma_rwctrl[%08x] dma_mask[%d-bit]\n",
+		    tp->dma_rwctrl,
+		    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.33-gnu1/drivers/net/tg3.h linux-libre-2.6.34-gnu1/drivers/net/tg3.h
--- linux-libre-2.6.33-gnu1/drivers/net/tg3.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tg3.h	2010-05-16 17:17:36.000000000 -0400
@@ -56,7 +56,39 @@
 #define  TG3PCI_DEVICE_TIGON3_57765	 0x16b4
 #define  TG3PCI_DEVICE_TIGON3_57791	 0x16b2
 #define  TG3PCI_DEVICE_TIGON3_57795	 0x16b6
-/* 0x04 --> 0x64 unused */
+/* 0x04 --> 0x2c unused */
+#define TG3PCI_SUBVENDOR_ID_BROADCOM		PCI_VENDOR_ID_BROADCOM
+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95700A6	0x1644
+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95701A5	0x0001
+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95700T6	0x0002
+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95700A9	0x0003
+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95701T1	0x0005
+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95701T8	0x0006
+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95701A7	0x0007
+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95701A10	0x0008
+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95701A12	0x8008
+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95703AX1	0x0009
+#define TG3PCI_SUBDEVICE_ID_BROADCOM_95703AX2	0x8009
+#define TG3PCI_SUBVENDOR_ID_3COM		PCI_VENDOR_ID_3COM
+#define TG3PCI_SUBDEVICE_ID_3COM_3C996T		0x1000
+#define TG3PCI_SUBDEVICE_ID_3COM_3C996BT	0x1006
+#define TG3PCI_SUBDEVICE_ID_3COM_3C996SX	0x1004
+#define TG3PCI_SUBDEVICE_ID_3COM_3C1000T	0x1007
+#define TG3PCI_SUBDEVICE_ID_3COM_3C940BR01	0x1008
+#define TG3PCI_SUBVENDOR_ID_DELL		PCI_VENDOR_ID_DELL
+#define TG3PCI_SUBDEVICE_ID_DELL_VIPER		0x00d1
+#define TG3PCI_SUBDEVICE_ID_DELL_JAGUAR		0x0106
+#define TG3PCI_SUBDEVICE_ID_DELL_MERLOT		0x0109
+#define TG3PCI_SUBDEVICE_ID_DELL_SLIM_MERLOT	0x010a
+#define TG3PCI_SUBVENDOR_ID_COMPAQ		PCI_VENDOR_ID_COMPAQ
+#define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE	0x007c
+#define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE_2	0x009a
+#define TG3PCI_SUBDEVICE_ID_COMPAQ_CHANGELING	0x007d
+#define TG3PCI_SUBDEVICE_ID_COMPAQ_NC7780	0x0085
+#define TG3PCI_SUBDEVICE_ID_COMPAQ_NC7780_2	0x0099
+#define TG3PCI_SUBVENDOR_ID_IBM			PCI_VENDOR_ID_IBM
+#define TG3PCI_SUBDEVICE_ID_IBM_5703SAX2	0x0281
+/* 0x30 --> 0x64 unused */
 #define TG3PCI_MSI_DATA			0x00000064
 /* 0x66 --> 0x68 unused */
 #define TG3PCI_MISC_HOST_CTRL		0x00000068
@@ -110,6 +142,7 @@
 #define  CHIPREV_ID_57780_A0		 0x57780000
 #define  CHIPREV_ID_57780_A1		 0x57780001
 #define  CHIPREV_ID_5717_A0		 0x05717000
+#define  CHIPREV_ID_57765_A0		 0x57785000
 #define  GET_ASIC_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 12)
 #define   ASIC_REV_5700			 0x07
 #define   ASIC_REV_5701			 0x00
@@ -1206,14 +1239,18 @@
 #define  DEFAULT_MB_MACRX_LOW_WATER	  0x00000020
 #define  DEFAULT_MB_MACRX_LOW_WATER_5705  0x00000010
 #define  DEFAULT_MB_MACRX_LOW_WATER_5906  0x00000004
+#define  DEFAULT_MB_MACRX_LOW_WATER_57765 0x0000002a
 #define  DEFAULT_MB_MACRX_LOW_WATER_JUMBO 0x00000098
 #define  DEFAULT_MB_MACRX_LOW_WATER_JUMBO_5780 0x0000004b
+#define  DEFAULT_MB_MACRX_LOW_WATER_JUMBO_57765 0x0000007e
 #define BUFMGR_MB_HIGH_WATER		0x00004418
 #define  DEFAULT_MB_HIGH_WATER		 0x00000060
 #define  DEFAULT_MB_HIGH_WATER_5705	 0x00000060
 #define  DEFAULT_MB_HIGH_WATER_5906	 0x00000010
+#define  DEFAULT_MB_HIGH_WATER_57765	 0x000000a0
 #define  DEFAULT_MB_HIGH_WATER_JUMBO	 0x0000017c
 #define  DEFAULT_MB_HIGH_WATER_JUMBO_5780 0x00000096
+#define  DEFAULT_MB_HIGH_WATER_JUMBO_57765 0x000000ea
 #define BUFMGR_RX_MB_ALLOC_REQ		0x0000441c
 #define  BUFMGR_MB_ALLOC_BIT		 0x10000000
 #define BUFMGR_RX_MB_ALLOC_RESP		0x00004420
@@ -1253,6 +1290,7 @@
 #define  RDMAC_MODE_MBUF_SBD_CRPT_ENAB	 0x00002000
 #define  RDMAC_MODE_FIFO_SIZE_128	 0x00020000
 #define  RDMAC_MODE_FIFO_LONG_BURST	 0x00030000
+#define  RDMAC_MODE_MULT_DMA_RD_DIS	 0x01000000
 #define  RDMAC_MODE_IPV4_LSO_EN		 0x08000000
 #define  RDMAC_MODE_IPV6_LSO_EN		 0x10000000
 #define RDMAC_STATUS			0x00004804
@@ -1543,6 +1581,8 @@
 #define  GRC_MODE_HOST_SENDBDS		0x00020000
 #define  GRC_MODE_NO_TX_PHDR_CSUM	0x00100000
 #define  GRC_MODE_NVRAM_WR_ENABLE	0x00200000
+#define  GRC_MODE_PCIE_TL_SEL		0x00000000
+#define  GRC_MODE_PCIE_PL_SEL		0x00400000
 #define  GRC_MODE_NO_RX_PHDR_CSUM	0x00800000
 #define  GRC_MODE_IRQ_ON_TX_CPU_ATTN	0x01000000
 #define  GRC_MODE_IRQ_ON_RX_CPU_ATTN	0x02000000
@@ -1550,7 +1590,13 @@
 #define  GRC_MODE_IRQ_ON_DMA_ATTN	0x08000000
 #define  GRC_MODE_IRQ_ON_FLOW_ATTN	0x10000000
 #define  GRC_MODE_4X_NIC_SEND_RINGS	0x20000000
+#define  GRC_MODE_PCIE_DL_SEL		0x20000000
 #define  GRC_MODE_MCAST_FRM_ENABLE	0x40000000
+#define  GRC_MODE_PCIE_HI_1K_EN		0x80000000
+#define  GRC_MODE_PCIE_PORT_MASK	(GRC_MODE_PCIE_TL_SEL | \
+					 GRC_MODE_PCIE_PL_SEL | \
+					 GRC_MODE_PCIE_DL_SEL | \
+					 GRC_MODE_PCIE_HI_1K_EN)
 #define GRC_MISC_CFG			0x00006804
 #define  GRC_MISC_CFG_CORECLK_RESET	0x00000001
 #define  GRC_MISC_CFG_PRESCALAR_MASK	0x000000fe
@@ -1804,6 +1850,11 @@
 /* 0x7e74 --> 0x8000 unused */
 
 
+/* Alternate PCIE definitions */
+#define TG3_PCIE_TLDLPL_PORT		0x00007c00
+#define TG3_PCIE_PL_LO_PHYCTL1		 0x00000004
+#define TG3_PCIE_PL_LO_PHYCTL1_L1PLLPD_EN	  0x00001000
+
 /* OTP bit definitions */
 #define TG3_OTP_AGCTGT_MASK		0x000000e0
 #define TG3_OTP_AGCTGT_SHIFT		1
@@ -1845,6 +1896,8 @@
 #define TG3_EEPROM_SB_REVISION_0	0x00000000
 #define TG3_EEPROM_SB_REVISION_2	0x00020000
 #define TG3_EEPROM_SB_REVISION_3	0x00030000
+#define TG3_EEPROM_SB_REVISION_4	0x00040000
+#define TG3_EEPROM_SB_REVISION_5	0x00050000
 #define TG3_EEPROM_MAGIC_HW		0xabcd
 #define TG3_EEPROM_MAGIC_HW_MSK		0xffff
 
@@ -1862,6 +1915,8 @@
 #define TG3_EEPROM_SB_F1R2_EDH_OFF	0x14
 #define TG3_EEPROM_SB_F1R2_MBA_OFF	0x10
 #define TG3_EEPROM_SB_F1R3_EDH_OFF	0x18
+#define TG3_EEPROM_SB_F1R4_EDH_OFF	0x1c
+#define TG3_EEPROM_SB_F1R5_EDH_OFF	0x20
 #define TG3_EEPROM_SB_EDH_MAJ_MASK	0x00000700
 #define TG3_EEPROM_SB_EDH_MAJ_SHFT	8
 #define TG3_EEPROM_SB_EDH_MIN_MASK	0x000000ff
@@ -1956,7 +2011,7 @@
 
 #define NIC_SRAM_DATA_CFG_4		0x00000d60
 #define  NIC_SRAM_GMII_MODE		 0x00000002
-#define  NIC_SRAM_RGMII_STD_IBND_DISABLE 0x00000004
+#define  NIC_SRAM_RGMII_INBAND_DISABLE	 0x00000004
 #define  NIC_SRAM_RGMII_EXT_IBND_RX_EN	 0x00000008
 #define  NIC_SRAM_RGMII_EXT_IBND_TX_EN	 0x00000010
 
@@ -2093,6 +2148,9 @@
 
 /* Fast Ethernet Tranceiver definitions */
 #define MII_TG3_FET_PTEST		0x17
+#define  MII_TG3_FET_PTEST_FRC_TX_LINK	0x1000
+#define  MII_TG3_FET_PTEST_FRC_TX_LOCK	0x0800
+
 #define MII_TG3_FET_TEST		0x1f
 #define  MII_TG3_FET_SHADOW_EN		0x0080
 
@@ -2682,6 +2740,7 @@ struct tg3 {
 	struct net_device		*dev;
 	struct pci_dev			*pdev;
 
+	u32				coal_now;
 	u32				msg_enable;
 
 	/* begin "tx thread" cacheline section */
@@ -2700,7 +2759,7 @@ struct tg3 {
 	struct vlan_group		*vlgrp;
 #endif
 
-	struct tg3_rx_prodring_set	prodring[TG3_IRQ_MAX_VECS - 1];
+	struct tg3_rx_prodring_set	prodring[TG3_IRQ_MAX_VECS];
 
 
 	/* begin "everything else" cacheline(s) section */
@@ -2798,7 +2857,7 @@ struct tg3 {
 #define TG3_FLG3_USE_PHYLIB		0x00000010
 #define TG3_FLG3_MDIOBUS_INITED		0x00000020
 #define TG3_FLG3_PHY_CONNECTED		0x00000080
-#define TG3_FLG3_RGMII_STD_IBND_DISABLE	0x00000100
+#define TG3_FLG3_RGMII_INBAND_DISABLE	0x00000100
 #define TG3_FLG3_RGMII_EXT_IBND_RX_EN	0x00000200
 #define TG3_FLG3_RGMII_EXT_IBND_TX_EN	0x00000400
 #define TG3_FLG3_CLKREQ_BUG		0x00000800
@@ -2812,6 +2871,7 @@ struct tg3 {
 #define TG3_FLG3_40BIT_DMA_LIMIT_BUG	0x00100000
 #define TG3_FLG3_SHORT_DMA_BUG		0x00200000
 #define TG3_FLG3_USE_JUMBO_BDFLAG	0x00400000
+#define TG3_FLG3_L1PLLPD_EN		0x00800000
 
 	struct timer_list		timer;
 	u16				timer_counter;
@@ -2861,42 +2921,50 @@ struct tg3 {
 
 	/* PHY info */
 	u32				phy_id;
-#define PHY_ID_MASK			0xfffffff0
-#define PHY_ID_BCM5400			0x60008040
-#define PHY_ID_BCM5401			0x60008050
-#define PHY_ID_BCM5411			0x60008070
-#define PHY_ID_BCM5701			0x60008110
-#define PHY_ID_BCM5703			0x60008160
-#define PHY_ID_BCM5704			0x60008190
-#define PHY_ID_BCM5705			0x600081a0
-#define PHY_ID_BCM5750			0x60008180
-#define PHY_ID_BCM5752			0x60008100
-#define PHY_ID_BCM5714			0x60008340
-#define PHY_ID_BCM5780			0x60008350
-#define PHY_ID_BCM5755			0xbc050cc0
-#define PHY_ID_BCM5787			0xbc050ce0
-#define PHY_ID_BCM5756			0xbc050ed0
-#define PHY_ID_BCM5784			0xbc050fa0
-#define PHY_ID_BCM5761			0xbc050fd0
-#define PHY_ID_BCM5717			0x5c0d8a00
-#define PHY_ID_BCM5906			0xdc00ac40
-#define PHY_ID_BCM8002			0x60010140
-#define PHY_ID_INVALID			0xffffffff
-#define PHY_ID_REV_MASK			0x0000000f
-#define PHY_REV_BCM5401_B0		0x1
-#define PHY_REV_BCM5401_B2		0x3
-#define PHY_REV_BCM5401_C0		0x6
-#define PHY_REV_BCM5411_X0		0x1 /* Found on Netgear GA302T */
-#define TG3_PHY_ID_BCM50610		0x143bd60
-#define TG3_PHY_ID_BCM50610M	0x143bd70
-#define TG3_PHY_ID_BCMAC131		0x143bc70
-#define TG3_PHY_ID_RTL8211C		0x001cc910
-#define TG3_PHY_ID_RTL8201E		0x00008200
-#define TG3_PHY_ID_BCM57780		0x03625d90
-#define TG3_PHY_OUI_MASK		0xfffffc00
-#define TG3_PHY_OUI_1			0x00206000
-#define TG3_PHY_OUI_2			0x0143bc00
-#define TG3_PHY_OUI_3			0x03625c00
+#define TG3_PHY_ID_MASK			0xfffffff0
+#define TG3_PHY_ID_BCM5400		0x60008040
+#define TG3_PHY_ID_BCM5401		0x60008050
+#define TG3_PHY_ID_BCM5411		0x60008070
+#define TG3_PHY_ID_BCM5701		0x60008110
+#define TG3_PHY_ID_BCM5703		0x60008160
+#define TG3_PHY_ID_BCM5704		0x60008190
+#define TG3_PHY_ID_BCM5705		0x600081a0
+#define TG3_PHY_ID_BCM5750		0x60008180
+#define TG3_PHY_ID_BCM5752		0x60008100
+#define TG3_PHY_ID_BCM5714		0x60008340
+#define TG3_PHY_ID_BCM5780		0x60008350
+#define TG3_PHY_ID_BCM5755		0xbc050cc0
+#define TG3_PHY_ID_BCM5787		0xbc050ce0
+#define TG3_PHY_ID_BCM5756		0xbc050ed0
+#define TG3_PHY_ID_BCM5784		0xbc050fa0
+#define TG3_PHY_ID_BCM5761		0xbc050fd0
+#define TG3_PHY_ID_BCM5718C		0x5c0d8a00
+#define TG3_PHY_ID_BCM5718S		0xbc050ff0
+#define TG3_PHY_ID_BCM57765		0x5c0d8a40
+#define TG3_PHY_ID_BCM5906		0xdc00ac40
+#define TG3_PHY_ID_BCM8002		0x60010140
+#define TG3_PHY_ID_INVALID		0xffffffff
+
+#define PHY_ID_RTL8211C			0x001cc910
+#define PHY_ID_RTL8201E			0x00008200
+
+#define TG3_PHY_ID_REV_MASK		0x0000000f
+#define TG3_PHY_REV_BCM5401_B0		0x1
+
+	/* This macro assumes the passed PHY ID is
+	 * already masked with TG3_PHY_ID_MASK.
+	 */
+#define TG3_KNOWN_PHY_ID(X)		\
+	((X) == TG3_PHY_ID_BCM5400 || (X) == TG3_PHY_ID_BCM5401 || \
+	 (X) == TG3_PHY_ID_BCM5411 || (X) == TG3_PHY_ID_BCM5701 || \
+	 (X) == TG3_PHY_ID_BCM5703 || (X) == TG3_PHY_ID_BCM5704 || \
+	 (X) == TG3_PHY_ID_BCM5705 || (X) == TG3_PHY_ID_BCM5750 || \
+	 (X) == TG3_PHY_ID_BCM5752 || (X) == TG3_PHY_ID_BCM5714 || \
+	 (X) == TG3_PHY_ID_BCM5780 || (X) == TG3_PHY_ID_BCM5787 || \
+	 (X) == TG3_PHY_ID_BCM5755 || (X) == TG3_PHY_ID_BCM5756 || \
+	 (X) == TG3_PHY_ID_BCM5906 || (X) == TG3_PHY_ID_BCM5761 || \
+	 (X) == TG3_PHY_ID_BCM5718C || (X) == TG3_PHY_ID_BCM5718S || \
+	 (X) == TG3_PHY_ID_BCM57765 || (X) == TG3_PHY_ID_BCM8002)
 
 	u32				led_ctrl;
 	u32				phy_otp;
@@ -2909,20 +2977,6 @@ struct tg3 {
 	u32				pci_clock_ctrl;
 	struct pci_dev			*pdev_peer;
 
-	/* This macro assumes the passed PHY ID is already masked
-	 * with PHY_ID_MASK.
-	 */
-#define KNOWN_PHY_ID(X)		\
-	((X) == PHY_ID_BCM5400 || (X) == PHY_ID_BCM5401 || \
-	 (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \
-	 (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \
-	 (X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \
-	 (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \
-	 (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM5787 || \
-	 (X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM5756 || \
-	 (X) == PHY_ID_BCM5906 || (X) == PHY_ID_BCM5761 || \
-	 (X) == PHY_ID_BCM5717 || (X) == PHY_ID_BCM8002)
-
 	struct tg3_hw_stats		*hw_stats;
 	dma_addr_t			stats_mapping;
 	struct work_struct		reset_task;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tlan.c linux-libre-2.6.34-gnu1/drivers/net/tlan.c
--- linux-libre-2.6.33-gnu1/drivers/net/tlan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tlan.c	2010-05-16 17:17:36.000000000 -0400
@@ -254,7 +254,7 @@ static struct board {
 	{ "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card */
 };
 
-static struct pci_device_id tlan_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(tlan_pci_tbl) = {
 	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL10,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100,
@@ -338,7 +338,7 @@ static int	TLan_PhyInternalService( stru
 static int	TLan_PhyDp83840aCheck( struct net_device * );
 */
 
-static int	TLan_MiiReadReg( struct net_device *, u16, u16, u16 * );
+static bool	TLan_MiiReadReg( struct net_device *, u16, u16, u16 * );
 static void	TLan_MiiSendData( u16, u32, unsigned );
 static void	TLan_MiiSync( u16 );
 static void	TLan_MiiWriteReg( struct net_device *, u16, u16, u16 );
@@ -1314,7 +1314,7 @@ static struct net_device_stats *TLan_Get
 
 static void TLan_SetMulticastList( struct net_device *dev )
 {
-	struct dev_mc_list	*dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	u32			hash1 = 0;
 	u32			hash2 = 0;
 	int			i;
@@ -1335,7 +1335,8 @@ static void TLan_SetMulticastList( struc
 			TLan_DioWrite32( dev->base_addr, TLAN_HASH_1, 0xFFFFFFFF );
 			TLan_DioWrite32( dev->base_addr, TLAN_HASH_2, 0xFFFFFFFF );
 		} else {
-			for ( i = 0; i < dev->mc_count; i++ ) {
+			i = 0;
+			netdev_for_each_mc_addr(dmi, dev) {
 				if ( i < 3 ) {
 					TLan_SetMac( dev, i + 1,
 						     (char *) &dmi->dmi_addr );
@@ -1346,7 +1347,7 @@ static void TLan_SetMulticastList( struc
 					else
 						hash2 |= ( 1 << ( offset - 32 ) );
 				}
-				dmi = dmi->next;
+				i++;
 			}
 			for ( ; i < 3; i++ )
 				TLan_SetMac( dev, i + 1, NULL );
@@ -2204,7 +2205,7 @@ TLan_ResetAdapter( struct net_device *de
 	u32		data;
 	u8		data8;
 
-	priv->tlanFullDuplex = FALSE;
+	priv->tlanFullDuplex = false;
 	priv->phyOnline=0;
 	netif_carrier_off(dev);
 
@@ -2259,7 +2260,7 @@ TLan_ResetAdapter( struct net_device *de
 			TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x0a );
 		} else if ( priv->duplex == TLAN_DUPLEX_FULL ) {
 			TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x00 );
-			priv->tlanFullDuplex = TRUE;
+			priv->tlanFullDuplex = true;
 		} else {
 			TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x08 );
 		}
@@ -2651,14 +2652,14 @@ static void TLan_PhyStartLink( struct ne
 			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0000);
 		} else if ( priv->speed == TLAN_SPEED_10 &&
 			    priv->duplex == TLAN_DUPLEX_FULL) {
-			priv->tlanFullDuplex = TRUE;
+			priv->tlanFullDuplex = true;
 			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0100);
 		} else if ( priv->speed == TLAN_SPEED_100 &&
 			    priv->duplex == TLAN_DUPLEX_HALF) {
 			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2000);
 		} else if ( priv->speed == TLAN_SPEED_100 &&
 			    priv->duplex == TLAN_DUPLEX_FULL) {
-			priv->tlanFullDuplex = TRUE;
+			priv->tlanFullDuplex = true;
 			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2100);
 		} else {
 
@@ -2695,7 +2696,7 @@ static void TLan_PhyStartLink( struct ne
                 	tctl &= ~TLAN_TC_AUISEL;
 			if ( priv->duplex == TLAN_DUPLEX_FULL ) {
 				control |= MII_GC_DUPLEX;
-				priv->tlanFullDuplex = TRUE;
+				priv->tlanFullDuplex = true;
 			}
 			if ( priv->speed == TLAN_SPEED_100 ) {
 				control |= MII_GC_SPEEDSEL;
@@ -2750,9 +2751,9 @@ static void TLan_PhyFinishAutoNeg( struc
 	TLan_MiiReadReg( dev, phy, MII_AN_LPA, &an_lpa );
 	mode = an_adv & an_lpa & 0x03E0;
 	if ( mode & 0x0100 ) {
-		priv->tlanFullDuplex = TRUE;
+		priv->tlanFullDuplex = true;
 	} else if ( ! ( mode & 0x0080 ) && ( mode & 0x0040 ) ) {
-		priv->tlanFullDuplex = TRUE;
+		priv->tlanFullDuplex = true;
 	}
 
 	if ( ( ! ( mode & 0x0180 ) ) &&
@@ -2855,8 +2856,8 @@ void TLan_PhyMonitor( struct net_device
 	 *	TLan_MiiReadReg
 	 *
 	 *	Returns:
-	 *		0	if ack received ok
-	 *		1	otherwise.
+	 *		false	if ack received ok
+	 *		true	if no ack received or other error
 	 *
 	 *	Parms:
 	 *		dev		The device structure containing
@@ -2875,17 +2876,17 @@ void TLan_PhyMonitor( struct net_device
 	 *
 	 **************************************************************/
 
-static int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
+static bool TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
 {
 	u8	nack;
 	u16	sio, tmp;
  	u32	i;
-	int	err;
+	bool	err;
 	int	minten;
 	TLanPrivateInfo *priv = netdev_priv(dev);
 	unsigned long flags = 0;
 
-	err = FALSE;
+	err = false;
 	outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
 	sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
 
@@ -2918,7 +2919,7 @@ static int TLan_MiiReadReg( struct net_d
 			TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
 		}
 		tmp = 0xffff;
-		err = TRUE;
+		err = true;
 	} else {					/* ACK, so read data */
 		for (tmp = 0, i = 0x8000; i; i >>= 1) {
 			TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tlan.h linux-libre-2.6.34-gnu1/drivers/net/tlan.h
--- linux-libre-2.6.33-gnu1/drivers/net/tlan.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tlan.h	2010-05-16 17:17:36.000000000 -0400
@@ -31,9 +31,6 @@
 	 *
 	 ****************************************************************/
 
-#define FALSE			0
-#define TRUE			1
-
 #define TLAN_MIN_FRAME_SIZE	64
 #define TLAN_MAX_FRAME_SIZE	1600
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tokenring/3c359.c linux-libre-2.6.34-gnu1/drivers/net/tokenring/3c359.c
--- linux-libre-2.6.33-gnu1/drivers/net/tokenring/3c359.c	2013-05-03 12:08:58.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/tokenring/3c359.c	2013-05-03 09:48:29.000000000 -0400
@@ -63,6 +63,7 @@
 #include <linux/spinlock.h>
 #include <linux/bitops.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #include <net/checksum.h>
 
@@ -117,7 +118,7 @@ MODULE_PARM_DESC(message_level, "3c359:
  *	will be stuck with 1555 lines of hex #'s in the code.
  */
 
-static struct pci_device_id xl_pci_tbl[] =
+static DEFINE_PCI_DEVICE_TABLE(xl_pci_tbl) =
 {
 	{PCI_VENDOR_ID_3COM,PCI_DEVICE_ID_3COM_3C359, PCI_ANY_ID, PCI_ANY_ID, },
 	{ }			/* terminate list */
@@ -1390,10 +1391,9 @@ static int xl_close(struct net_device *d
 static void xl_set_rx_mode(struct net_device *dev) 
 {
 	struct xl_private *xl_priv = netdev_priv(dev);
-	struct dev_mc_list *dmi ; 
+	struct dev_mc_list *dmi;
 	unsigned char dev_mc_address[4] ; 
 	u16 options ; 
-	int i ; 
 
 	if (dev->flags & IFF_PROMISC)
 		options = 0x0004 ; 
@@ -1408,7 +1408,7 @@ static void xl_set_rx_mode(struct net_de
 
 	dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ;
 
-        for (i=0,dmi=dev->mc_list;i < dev->mc_count; i++,dmi = dmi->next) {
+	netdev_for_each_mc_addr(dmi, dev) {
                 dev_mc_address[0] |= dmi->dmi_addr[2] ;
                 dev_mc_address[1] |= dmi->dmi_addr[3] ;
                 dev_mc_address[2] |= dmi->dmi_addr[4] ;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tokenring/abyss.c linux-libre-2.6.34-gnu1/drivers/net/tokenring/abyss.c
--- linux-libre-2.6.33-gnu1/drivers/net/tokenring/abyss.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tokenring/abyss.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,7 +45,7 @@ static char version[] __devinitdata =
 
 #define ABYSS_IO_EXTENT 64
 
-static struct pci_device_id abyss_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(abyss_pci_tbl) = {
 	{ PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_MK2,
 	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_TOKEN_RING << 8, 0x00ffffff, },
 	{ }			/* Terminating entry */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tokenring/ibmtr.c linux-libre-2.6.34-gnu1/drivers/net/tokenring/ibmtr.c
--- linux-libre-2.6.33-gnu1/drivers/net/tokenring/ibmtr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tokenring/ibmtr.c	2010-05-16 17:17:36.000000000 -0400
@@ -995,13 +995,11 @@ static void tok_set_multicast_list(struc
 	/*BMS ifconfig tr down or hot unplug a PCMCIA card ??hownowbrowncow*/
 	if (/*BMSHELPdev->start == 0 ||*/ ti->open_status != OPEN) return;
 	address[0] = address[1] = address[2] = address[3] = 0;
-	mclist = dev->mc_list;
-	for (i = 0; i < dev->mc_count; i++) {
+	netdev_for_each_mc_addr(mclist, dev) {
 		address[0] |= mclist->dmi_addr[2];
 		address[1] |= mclist->dmi_addr[3];
 		address[2] |= mclist->dmi_addr[4];
 		address[3] |= mclist->dmi_addr[5];
-		mclist = mclist->next;
 	}
 	SET_PAGE(ti->srb_page);
 	for (i = 0; i < sizeof(struct srb_set_funct_addr); i++)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tokenring/lanstreamer.c linux-libre-2.6.34-gnu1/drivers/net/tokenring/lanstreamer.c
--- linux-libre-2.6.33-gnu1/drivers/net/tokenring/lanstreamer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tokenring/lanstreamer.c	2010-05-16 17:17:36.000000000 -0400
@@ -121,6 +121,7 @@
 #include <linux/spinlock.h>
 #include <linux/bitops.h>
 #include <linux/jiffies.h>
+#include <linux/slab.h>
 
 #include <net/net_namespace.h>
 #include <net/checksum.h>
@@ -146,7 +147,7 @@
 static char version[] = "LanStreamer.c v0.4.0 03/08/01 - Mike Sullivan\n"
                         "              v0.5.3 11/13/02 - Kent Yoder";
 
-static struct pci_device_id streamer_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(streamer_pci_tbl) = {
 	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR, PCI_ANY_ID, PCI_ANY_ID,},
 	{}	/* terminating entry */
 };
@@ -1268,7 +1269,6 @@ static void streamer_set_rx_mode(struct
 	__u8 options = 0;
 	struct dev_mc_list *dmi;
 	unsigned char dev_mc_address[5];
-	int i;
 
 	writel(streamer_priv->srb, streamer_mmio + LAPA);
 	options = streamer_priv->streamer_copy_all_options;
@@ -1303,8 +1303,7 @@ static void streamer_set_rx_mode(struct
 	writel(streamer_priv->srb,streamer_mmio+LAPA);
 	dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ; 
   
-	for (i=0,dmi=dev->mc_list;i < dev->mc_count; i++,dmi = dmi->next) 
-	{ 
+	netdev_for_each_mc_addr(dmi, dev) {
    	        dev_mc_address[0] |= dmi->dmi_addr[2] ; 
 		dev_mc_address[1] |= dmi->dmi_addr[3] ; 
 		dev_mc_address[2] |= dmi->dmi_addr[4] ; 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tokenring/madgemc.c linux-libre-2.6.34-gnu1/drivers/net/tokenring/madgemc.c
--- linux-libre-2.6.33-gnu1/drivers/net/tokenring/madgemc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tokenring/madgemc.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@ static const char version[] = "madgemc.c
 
 #include <linux/module.h>
 #include <linux/mca.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tokenring/olympic.c linux-libre-2.6.34-gnu1/drivers/net/tokenring/olympic.c
--- linux-libre-2.6.33-gnu1/drivers/net/tokenring/olympic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tokenring/olympic.c	2010-05-16 17:17:36.000000000 -0400
@@ -172,7 +172,7 @@ module_param_array(message_level, int, N
 static int network_monitor[OLYMPIC_MAX_ADAPTERS] = {0,};
 module_param_array(network_monitor, int, NULL, 0);
 
-static struct pci_device_id olympic_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(olympic_pci_tbl) = {
 	{PCI_VENDOR_ID_IBM,PCI_DEVICE_ID_IBM_TR_WAKE,PCI_ANY_ID,PCI_ANY_ID,},
 	{ } 	/* Terminating Entry */
 };
@@ -1139,9 +1139,8 @@ static void olympic_set_rx_mode(struct n
    	u8 __iomem *olympic_mmio = olympic_priv->olympic_mmio ; 
 	u8 options = 0; 
 	u8 __iomem *srb;
-	struct dev_mc_list *dmi ; 
+	struct dev_mc_list *dmi;
 	unsigned char dev_mc_address[4] ; 
-	int i ; 
 
 	writel(olympic_priv->srb,olympic_mmio+LAPA);
 	srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));
@@ -1178,7 +1177,7 @@ static void olympic_set_rx_mode(struct n
 
 	dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ; 
 
-	for (i=0,dmi=dev->mc_list;i < dev->mc_count; i++,dmi = dmi->next) { 
+	netdev_for_each_mc_addr(dmi, dev) {
 		dev_mc_address[0] |= dmi->dmi_addr[2] ; 
 		dev_mc_address[1] |= dmi->dmi_addr[3] ; 
 		dev_mc_address[2] |= dmi->dmi_addr[4] ; 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tokenring/smctr.c linux-libre-2.6.34-gnu1/drivers/net/tokenring/smctr.c
--- linux-libre-2.6.33-gnu1/drivers/net/tokenring/smctr.c	2013-05-03 12:09:02.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/tokenring/smctr.c	2013-05-03 09:48:33.000000000 -0400
@@ -36,7 +36,6 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/time.h>
 #include <linux/errno.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tokenring/tms380tr.c linux-libre-2.6.34-gnu1/drivers/net/tokenring/tms380tr.c
--- linux-libre-2.6.33-gnu1/drivers/net/tokenring/tms380tr.c	2013-05-03 12:09:05.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/tokenring/tms380tr.c	2013-05-03 09:48:36.000000000 -0400
@@ -85,7 +85,6 @@ static const char version[] = "tms380tr.
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/time.h>
 #include <linux/errno.h>
@@ -693,7 +692,7 @@ static netdev_tx_t tms380tr_hardware_sen
  * NOTE: This function should be used whenever the status of any TPL must be
  * modified by the driver, because the compiler may otherwise change the
  * order of instructions such that writing the TPL status may be executed at
- * an undesireable time. When this function is used, the status is always
+ * an undesirable time. When this function is used, the status is always
  * written when the function is called.
  */
 static void tms380tr_write_tpl_status(TPL *tpl, unsigned int Status)
@@ -1212,10 +1211,9 @@ static void tms380tr_set_multicast_list(
 		}
 		else
 		{
-			int i;
-			struct dev_mc_list *mclist = dev->mc_list;
-			for (i=0; i< dev->mc_count; i++)
-			{
+			struct dev_mc_list *mclist;
+
+			netdev_for_each_mc_addr(mclist, dev) {
 				((char *)(&tp->ocpl.FunctAddr))[0] |=
 					mclist->dmi_addr[2];
 				((char *)(&tp->ocpl.FunctAddr))[1] |=
@@ -1224,7 +1222,6 @@ static void tms380tr_set_multicast_list(
 					mclist->dmi_addr[4];
 				((char *)(&tp->ocpl.FunctAddr))[3] |=
 					mclist->dmi_addr[5];
-				mclist = mclist->next;
 			}
 		}
 		tms380tr_exec_cmd(dev, OC_SET_FUNCT_ADDR);
@@ -2266,7 +2263,7 @@ static void tms380tr_rcv_status_irq(stru
  * This function should be used whenever the status of any RPL must be
  * modified by the driver, because the compiler may otherwise change the
  * order of instructions such that writing the RPL status may be executed
- * at an undesireable time. When this function is used, the status is
+ * at an undesirable time. When this function is used, the status is
  * always written when the function is called.
  */
 static void tms380tr_write_rpl_status(RPL *rpl, unsigned int Status)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tokenring/tmspci.c linux-libre-2.6.34-gnu1/drivers/net/tokenring/tmspci.c
--- linux-libre-2.6.33-gnu1/drivers/net/tokenring/tmspci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tokenring/tmspci.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,7 +57,7 @@ static struct card_info card_info_table[
 	{ {0x03, 0x01}, "3Com Token Link Velocity"},
 };
 
-static struct pci_device_id tmspci_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(tmspci_pci_tbl) = {
 	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TOKENRING, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_TR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
 	{ PCI_VENDOR_ID_TCONRAD, PCI_DEVICE_ID_TCONRAD_TOKENRING, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tsi108_eth.c linux-libre-2.6.34-gnu1/drivers/net/tsi108_eth.c
--- linux-libre-2.6.33-gnu1/drivers/net/tsi108_eth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tsi108_eth.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,7 +38,6 @@
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/delay.h>
 #include <linux/crc32.h>
@@ -48,6 +47,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/timer.h>
 #include <linux/platform_device.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -1184,29 +1184,19 @@ static void tsi108_set_rx_mode(struct ne
 
 	rxcfg &= ~(TSI108_EC_RXCFG_UFE | TSI108_EC_RXCFG_MFE);
 
-	if (dev->flags & IFF_ALLMULTI || dev->mc_count) {
+	if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev)) {
 		int i;
-		struct dev_mc_list *mc = dev->mc_list;
+		struct dev_mc_list *mc;
 		rxcfg |= TSI108_EC_RXCFG_MFE | TSI108_EC_RXCFG_MC_HASH;
 
 		memset(data->mc_hash, 0, sizeof(data->mc_hash));
 
-		while (mc) {
+		netdev_for_each_mc_addr(mc, dev) {
 			u32 hash, crc;
 
-			if (mc->dmi_addrlen == 6) {
-				crc = ether_crc(6, mc->dmi_addr);
-				hash = crc >> 23;
-
-				__set_bit(hash, &data->mc_hash[0]);
-			} else {
-				printk(KERN_ERR
-		"%s: got multicast address of length %d instead of 6.\n",
-				       dev->name,
-				       mc->dmi_addrlen);
-			}
-
-			mc = mc->next;
+			crc = ether_crc(6, mc->dmi_addr);
+			hash = crc >> 23;
+			__set_bit(hash, &data->mc_hash[0]);
 		}
 
 		TSI_WRITE(TSI108_EC_HASHADDR,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tulip/21142.c linux-libre-2.6.34-gnu1/drivers/net/tulip/21142.c
--- linux-libre-2.6.33-gnu1/drivers/net/tulip/21142.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tulip/21142.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,8 +43,8 @@ void t21142_media_task(struct work_struc
 	if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000)
 		csr12 |= 6;
 	if (tulip_debug > 2)
-		printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n",
-			   dev->name, csr12, medianame[dev->if_port]);
+		dev_info(&dev->dev, "21143 negotiation status %08x, %s\n",
+			 csr12, medianame[dev->if_port]);
 	if (tulip_media_cap[dev->if_port] & MediaIsMII) {
 		if (tulip_check_duplex(dev) < 0) {
 			netif_carrier_off(dev);
@@ -56,23 +56,26 @@ void t21142_media_task(struct work_struc
 	} else if (tp->nwayset) {
 		/* Don't screw up a negotiated session! */
 		if (tulip_debug > 1)
-			printk(KERN_INFO"%s: Using NWay-set %s media, csr12 %8.8x.\n",
-				   dev->name, medianame[dev->if_port], csr12);
+			dev_info(&dev->dev,
+				 "Using NWay-set %s media, csr12 %08x\n",
+				 medianame[dev->if_port], csr12);
 	} else if (tp->medialock) {
 			;
 	} else if (dev->if_port == 3) {
 		if (csr12 & 2) {	/* No 100mbps link beat, revert to 10mbps. */
 			if (tulip_debug > 1)
-				printk(KERN_INFO"%s: No 21143 100baseTx link beat, %8.8x, "
-					   "trying NWay.\n", dev->name, csr12);
+				dev_info(&dev->dev,
+					 "No 21143 100baseTx link beat, %08x, trying NWay\n",
+					 csr12);
 			t21142_start_nway(dev);
 			next_tick = 3*HZ;
 		}
 	} else if ((csr12 & 0x7000) != 0x5000) {
 		/* Negotiation failed.  Search media types. */
 		if (tulip_debug > 1)
-			printk(KERN_INFO"%s: 21143 negotiation failed, status %8.8x.\n",
-				   dev->name, csr12);
+			dev_info(&dev->dev,
+				 "21143 negotiation failed, status %08x\n",
+				 csr12);
 		if (!(csr12 & 4)) {		/* 10mbps link beat good. */
 			new_csr6 = 0x82420000;
 			dev->if_port = 0;
@@ -90,8 +93,8 @@ void t21142_media_task(struct work_struc
 			iowrite32(1, ioaddr + CSR13);
 		}
 		if (tulip_debug > 1)
-			printk(KERN_INFO"%s: Testing new 21143 media %s.\n",
-				   dev->name, medianame[dev->if_port]);
+			dev_info(&dev->dev, "Testing new 21143 media %s\n",
+				 medianame[dev->if_port]);
 		if (new_csr6 != (tp->csr6 & ~0x00D5)) {
 			tp->csr6 &= 0x00D5;
 			tp->csr6 |= new_csr6;
@@ -119,8 +122,8 @@ void t21142_start_nway(struct net_device
 	tp->nway = tp->mediasense = 1;
 	tp->nwayset = tp->lpar = 0;
 	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: Restarting 21143 autonegotiation, csr14=%8.8x.\n",
-			   dev->name, csr14);
+		printk(KERN_DEBUG "%s: Restarting 21143 autonegotiation, csr14=%08x\n",
+		       dev->name, csr14);
 	iowrite32(0x0001, ioaddr + CSR13);
 	udelay(100);
 	iowrite32(csr14, ioaddr + CSR14);
@@ -147,8 +150,9 @@ void t21142_lnk_change(struct net_device
 	if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000)
 		csr12 |= 6;
 	if (tulip_debug > 1)
-		printk(KERN_INFO"%s: 21143 link status interrupt %8.8x, CSR5 %x, "
-			   "%8.8x.\n", dev->name, csr12, csr5, csr14);
+		dev_info(&dev->dev,
+			 "21143 link status interrupt %08x, CSR5 %x, %08x\n",
+			 csr12, csr5, csr14);
 
 	/* If NWay finished and we have a negotiated partner capability. */
 	if (tp->nway  &&  !tp->nwayset  &&  (csr12 & 0x7000) == 0x5000) {
@@ -171,14 +175,15 @@ void t21142_lnk_change(struct net_device
 
 		if (tulip_debug > 1) {
 			if (tp->nwayset)
-				printk(KERN_INFO "%s: Switching to %s based on link "
-					   "negotiation %4.4x & %4.4x = %4.4x.\n",
-					   dev->name, medianame[dev->if_port], tp->sym_advertise,
-					   tp->lpar, negotiated);
+				dev_info(&dev->dev,
+					 "Switching to %s based on link negotiation %04x & %04x = %04x\n",
+					 medianame[dev->if_port],
+					 tp->sym_advertise, tp->lpar,
+					 negotiated);
 			else
-				printk(KERN_INFO "%s: Autonegotiation failed, using %s,"
-					   " link beat status %4.4x.\n",
-					   dev->name, medianame[dev->if_port], csr12);
+				dev_info(&dev->dev,
+					 "Autonegotiation failed, using %s, link beat status %04x\n",
+					 medianame[dev->if_port], csr12);
 		}
 
 		if (tp->mtable) {
@@ -201,14 +206,14 @@ void t21142_lnk_change(struct net_device
 #if 0							/* Restart shouldn't be needed. */
 		iowrite32(tp->csr6 | RxOn, ioaddr + CSR6);
 		if (tulip_debug > 2)
-			printk(KERN_DEBUG "%s:  Restarting Tx and Rx, CSR5 is %8.8x.\n",
-				   dev->name, ioread32(ioaddr + CSR5));
+			printk(KERN_DEBUG "%s:  Restarting Tx and Rx, CSR5 is %08x\n",
+			       dev->name, ioread32(ioaddr + CSR5));
 #endif
 		tulip_start_rxtx(tp);
 		if (tulip_debug > 2)
-			printk(KERN_DEBUG "%s:  Setting CSR6 %8.8x/%x CSR12 %8.8x.\n",
-				   dev->name, tp->csr6, ioread32(ioaddr + CSR6),
-				   ioread32(ioaddr + CSR12));
+			printk(KERN_DEBUG "%s:  Setting CSR6 %08x/%x CSR12 %08x\n",
+			       dev->name, tp->csr6, ioread32(ioaddr + CSR6),
+			       ioread32(ioaddr + CSR12));
 	} else if ((tp->nwayset  &&  (csr5 & 0x08000000) &&
 		    (dev->if_port == 3  ||  dev->if_port == 5) &&
 		    (csr12 & 2) == 2) ||
@@ -220,9 +225,9 @@ void t21142_lnk_change(struct net_device
 		add_timer(&tp->timer);
 	} else if (dev->if_port == 3  ||  dev->if_port == 5) {
 		if (tulip_debug > 1)
-			printk(KERN_INFO"%s: 21143 %s link beat %s.\n",
-				   dev->name, medianame[dev->if_port],
-				   (csr12 & 2) ? "failed" : "good");
+			dev_info(&dev->dev, "21143 %s link beat %s\n",
+				 medianame[dev->if_port],
+				 (csr12 & 2) ? "failed" : "good");
 		if ((csr12 & 2)  &&  ! tp->medialock) {
 			del_timer_sync(&tp->timer);
 			t21142_start_nway(dev);
@@ -232,21 +237,18 @@ void t21142_lnk_change(struct net_device
 			iowrite32(csr14 & ~0x080, ioaddr + CSR14);
 	} else if (dev->if_port == 0  ||  dev->if_port == 4) {
 		if ((csr12 & 4) == 0)
-			printk(KERN_INFO"%s: 21143 10baseT link beat good.\n",
-				   dev->name);
+			dev_info(&dev->dev, "21143 10baseT link beat good\n");
 	} else if (!(csr12 & 4)) {		/* 10mbps link beat good. */
 		if (tulip_debug)
-			printk(KERN_INFO"%s: 21143 10mbps sensed media.\n",
-				   dev->name);
+			dev_info(&dev->dev, "21143 10mbps sensed media\n");
 		dev->if_port = 0;
 	} else if (tp->nwayset) {
 		if (tulip_debug)
-			printk(KERN_INFO"%s: 21143 using NWay-set %s, csr6 %8.8x.\n",
-				   dev->name, medianame[dev->if_port], tp->csr6);
+			dev_info(&dev->dev, "21143 using NWay-set %s, csr6 %08x\n",
+				 medianame[dev->if_port], tp->csr6);
 	} else {		/* 100mbps link beat good. */
 		if (tulip_debug)
-			printk(KERN_INFO"%s: 21143 100baseTx sensed media.\n",
-				   dev->name);
+			dev_info(&dev->dev, "21143 100baseTx sensed media\n");
 		dev->if_port = 3;
 		tp->csr6 = 0x838E0000 | (tp->csr6 & 0x20ff);
 		iowrite32(0x0003FF7F, ioaddr + CSR14);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tulip/de2104x.c linux-libre-2.6.34-gnu1/drivers/net/tulip/de2104x.c
--- linux-libre-2.6.33-gnu1/drivers/net/tulip/de2104x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tulip/de2104x.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/compiler.h>
 #include <linux/rtnetlink.h>
 #include <linux/crc32.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -337,7 +338,7 @@ static void de21041_media_timer (unsigne
 static unsigned int de_ok_to_advertise (struct de_private *de, u32 new_media);
 
 
-static struct pci_device_id de_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(de_pci_tbl) = {
 	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS,
@@ -382,9 +383,9 @@ static void de_rx_err_acct (struct de_pr
 		/* Ingore earlier buffers. */
 		if ((status & 0xffff) != 0x7fff) {
 			if (netif_msg_rx_err(de))
-				printk(KERN_WARNING "%s: Oversized Ethernet frame "
-					   "spanned multiple buffers, status %8.8x!\n",
-					   de->dev->name, status);
+				dev_warn(&de->dev->dev,
+					 "Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
+					 status);
 			de->net_stats.rx_length_errors++;
 		}
 	} else if (status & RxError) {
@@ -487,7 +488,7 @@ rx_next:
 	}
 
 	if (!rx_work)
-		printk(KERN_WARNING "%s: rx work limit reached\n", de->dev->name);
+		dev_warn(&de->dev->dev, "rx work limit reached\n");
 
 	de->rx_tail = rx_tail;
 }
@@ -504,7 +505,8 @@ static irqreturn_t de_interrupt (int irq
 
 	if (netif_msg_intr(de))
 		printk(KERN_DEBUG "%s: intr, status %08x mode %08x desc %u/%u/%u\n",
-		        dev->name, status, dr32(MacMode), de->rx_tail, de->tx_head, de->tx_tail);
+		       dev->name, status, dr32(MacMode),
+		       de->rx_tail, de->tx_head, de->tx_tail);
 
 	dw32(MacStatus, status);
 
@@ -529,8 +531,9 @@ static irqreturn_t de_interrupt (int irq
 
 		pci_read_config_word(de->pdev, PCI_STATUS, &pci_status);
 		pci_write_config_word(de->pdev, PCI_STATUS, pci_status);
-		printk(KERN_ERR "%s: PCI bus error, status=%08x, PCI status=%04x\n",
-		       dev->name, status, pci_status);
+		dev_err(&de->dev->dev,
+			"PCI bus error, status=%08x, PCI status=%04x\n",
+			status, pci_status);
 	}
 
 	return IRQ_HANDLED;
@@ -582,7 +585,8 @@ static void de_tx (struct de_private *de
 				de->net_stats.tx_packets++;
 				de->net_stats.tx_bytes += skb->len;
 				if (netif_msg_tx_done(de))
-					printk(KERN_DEBUG "%s: tx done, slot %d\n", de->dev->name, tx_tail);
+					printk(KERN_DEBUG "%s: tx done, slot %d\n",
+					       de->dev->name, tx_tail);
 			}
 			dev_kfree_skb_irq(skb);
 		}
@@ -674,18 +678,17 @@ static void build_setup_frame_hash(u16 *
 	memset(hash_table, 0, sizeof(hash_table));
 	set_bit_le(255, hash_table); 			/* Broadcast entry */
 	/* This should work on big-endian machines as well. */
-	for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-	     i++, mclist = mclist->next) {
+	netdev_for_each_mc_addr(mclist, dev) {
 		int index = ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x1ff;
 
 		set_bit_le(index, hash_table);
+	}
 
-		for (i = 0; i < 32; i++) {
-			*setup_frm++ = hash_table[i];
-			*setup_frm++ = hash_table[i];
-		}
-		setup_frm = &de->setup_frame[13*6];
+	for (i = 0; i < 32; i++) {
+		*setup_frm++ = hash_table[i];
+		*setup_frm++ = hash_table[i];
 	}
+	setup_frm = &de->setup_frame[13*6];
 
 	/* Fill the final entry with our physical address. */
 	eaddrs = (u16 *)dev->dev_addr;
@@ -698,20 +701,18 @@ static void build_setup_frame_perfect(u1
 {
 	struct de_private *de = netdev_priv(dev);
 	struct dev_mc_list *mclist;
-	int i;
 	u16 *eaddrs;
 
 	/* We have <= 14 addresses so we can use the wonderful
 	   16 address perfect filtering of the Tulip. */
-	for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
-	     i++, mclist = mclist->next) {
+	netdev_for_each_mc_addr(mclist, dev) {
 		eaddrs = (u16 *)mclist->dmi_addr;
 		*setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++;
 		*setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++;
 		*setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++;
 	}
 	/* Fill the unused entries with the broadcast address. */
-	memset(setup_frm, 0xff, (15-i)*12);
+	memset(setup_frm, 0xff, (15 - netdev_mc_count(dev)) * 12);
 	setup_frm = &de->setup_frame[15*6];
 
 	/* Fill the final entry with our physical address. */
@@ -738,7 +739,7 @@ static void __de_set_rx_mode (struct net
 		goto out;
 	}
 
-	if ((dev->mc_count > 1000) || (dev->flags & IFF_ALLMULTI)) {
+	if ((netdev_mc_count(dev) > 1000) || (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter well -- accept all multicasts. */
 		macmode |= AcceptAllMulticast;
 		goto out;
@@ -746,7 +747,7 @@ static void __de_set_rx_mode (struct net
 
 	/* Note that only the low-address shortword of setup_frame is valid!
 	   The values are doubled for big-endian architectures. */
-	if (dev->mc_count > 14)	/* Must use a multicast hash table. */
+	if (netdev_mc_count(dev) > 14)	/* Must use a multicast hash table. */
 		build_setup_frame_hash (de->setup_frame, dev);
 	else
 		build_setup_frame_perfect (de->setup_frame, dev);
@@ -870,7 +871,7 @@ static void de_stop_rxtx (struct de_priv
 		udelay(100);
 	}
 
-	printk(KERN_WARNING "%s: timeout expired stopping DMA\n", de->dev->name);
+	dev_warn(&de->dev->dev, "timeout expired stopping DMA\n");
 }
 
 static inline void de_start_rxtx (struct de_private *de)
@@ -905,8 +906,8 @@ static void de_link_up(struct de_private
 	if (!netif_carrier_ok(de->dev)) {
 		netif_carrier_on(de->dev);
 		if (netif_msg_link(de))
-			printk(KERN_INFO "%s: link up, media %s\n",
-			       de->dev->name, media_name[de->media_type]);
+			dev_info(&de->dev->dev, "link up, media %s\n",
+				 media_name[de->media_type]);
 	}
 }
 
@@ -915,7 +916,7 @@ static void de_link_down(struct de_priva
 	if (netif_carrier_ok(de->dev)) {
 		netif_carrier_off(de->dev);
 		if (netif_msg_link(de))
-			printk(KERN_INFO "%s: link down\n", de->dev->name);
+			dev_info(&de->dev->dev, "link down\n");
 	}
 }
 
@@ -925,7 +926,8 @@ static void de_set_media (struct de_priv
 	u32 macmode = dr32(MacMode);
 
 	if (de_is_running(de))
-		printk(KERN_WARNING "%s: chip is running while changing media!\n", de->dev->name);
+		dev_warn(&de->dev->dev,
+			 "chip is running while changing media!\n");
 
 	if (de->de21040)
 		dw32(CSR11, FULL_DUPLEX_MAGIC);
@@ -945,15 +947,15 @@ static void de_set_media (struct de_priv
 		macmode &= ~FullDuplex;
 
 	if (netif_msg_link(de)) {
-		printk(KERN_INFO
-		       "%s: set link %s\n"
-		       "%s:    mode 0x%x, sia 0x%x,0x%x,0x%x,0x%x\n"
-		       "%s:    set mode 0x%x, set sia 0x%x,0x%x,0x%x\n",
-		       de->dev->name, media_name[media],
-		       de->dev->name, dr32(MacMode), dr32(SIAStatus),
-		       dr32(CSR13), dr32(CSR14), dr32(CSR15),
-		       de->dev->name, macmode, de->media[media].csr13,
-		       de->media[media].csr14, de->media[media].csr15);
+		dev_info(&de->dev->dev, "set link %s\n", media_name[media]);
+		dev_info(&de->dev->dev, "mode 0x%x, sia 0x%x,0x%x,0x%x,0x%x\n",
+			 dr32(MacMode), dr32(SIAStatus),
+			 dr32(CSR13), dr32(CSR14), dr32(CSR15));
+
+		dev_info(&de->dev->dev,
+			 "set mode 0x%x, set sia 0x%x,0x%x,0x%x\n",
+			 macmode, de->media[media].csr13,
+			 de->media[media].csr14, de->media[media].csr15);
 	}
 	if (macmode != dr32(MacMode))
 		dw32(MacMode, macmode);
@@ -992,9 +994,8 @@ static void de21040_media_timer (unsigne
 			de_link_up(de);
 		else
 			if (netif_msg_timer(de))
-				printk(KERN_INFO "%s: %s link ok, status %x\n",
-				       dev->name, media_name[de->media_type],
-				       status);
+				dev_info(&dev->dev, "%s link ok, status %x\n",
+					 media_name[de->media_type], status);
 		return;
 	}
 
@@ -1022,8 +1023,8 @@ no_link_yet:
 	add_timer(&de->media_timer);
 
 	if (netif_msg_timer(de))
-		printk(KERN_INFO "%s: no link, trying media %s, status %x\n",
-		       dev->name, media_name[de->media_type], status);
+		dev_info(&dev->dev, "no link, trying media %s, status %x\n",
+			 media_name[de->media_type], status);
 }
 
 static unsigned int de_ok_to_advertise (struct de_private *de, u32 new_media)
@@ -1079,9 +1080,10 @@ static void de21041_media_timer (unsigne
 			de_link_up(de);
 		else
 			if (netif_msg_timer(de))
-				printk(KERN_INFO "%s: %s link ok, mode %x status %x\n",
-				       dev->name, media_name[de->media_type],
-				       dr32(MacMode), status);
+				dev_info(&dev->dev,
+					 "%s link ok, mode %x status %x\n",
+					 media_name[de->media_type],
+					 dr32(MacMode), status);
 		return;
 	}
 
@@ -1150,8 +1152,8 @@ no_link_yet:
 	add_timer(&de->media_timer);
 
 	if (netif_msg_timer(de))
-		printk(KERN_INFO "%s: no link, trying media %s, status %x\n",
-		       dev->name, media_name[de->media_type], status);
+		dev_info(&dev->dev, "no link, trying media %s, status %x\n",
+			 media_name[de->media_type], status);
 }
 
 static void de_media_interrupt (struct de_private *de, u32 status)
@@ -1378,8 +1380,7 @@ static int de_open (struct net_device *d
 
 	rc = de_alloc_rings(de);
 	if (rc) {
-		printk(KERN_ERR "%s: ring allocation failure, err=%d\n",
-		       dev->name, rc);
+		dev_err(&dev->dev, "ring allocation failure, err=%d\n", rc);
 		return rc;
 	}
 
@@ -1387,15 +1388,14 @@ static int de_open (struct net_device *d
 
 	rc = request_irq(dev->irq, de_interrupt, IRQF_SHARED, dev->name, dev);
 	if (rc) {
-		printk(KERN_ERR "%s: IRQ %d request failure, err=%d\n",
-		       dev->name, dev->irq, rc);
+		dev_err(&dev->dev, "IRQ %d request failure, err=%d\n",
+			dev->irq, rc);
 		goto err_out_free;
 	}
 
 	rc = de_init_hw(de);
 	if (rc) {
-		printk(KERN_ERR "%s: h/w init failure, err=%d\n",
-		       dev->name, rc);
+		dev_err(&dev->dev, "h/w init failure, err=%d\n", rc);
 		goto err_out_free_irq;
 	}
 
@@ -1666,8 +1666,8 @@ static int de_nway_reset(struct net_devi
 	status = dr32(SIAStatus);
 	dw32(SIAStatus, (status & ~NWayState) | NWayRestart);
 	if (netif_msg_link(de))
-		printk(KERN_INFO "%s: link nway restart, status %x,%x\n",
-		       de->dev->name, status, dr32(SIAStatus));
+		dev_info(&de->dev->dev, "link nway restart, status %x,%x\n",
+			 status, dr32(SIAStatus));
 	return 0;
 }
 
@@ -1711,7 +1711,7 @@ static void __devinit de21040_get_mac_ad
 		de->dev->dev_addr[i] = value;
 		udelay(1);
 		if (boguscnt <= 0)
-			printk(KERN_WARNING PFX "timeout reading 21040 MAC address byte %u\n", i);
+			pr_warning(PFX "timeout reading 21040 MAC address byte %u\n", i);
 	}
 }
 
@@ -1830,9 +1830,8 @@ static void __devinit de21041_get_srom_i
 	}
 
 	if (netif_msg_probe(de))
-		printk(KERN_INFO "de%d: SROM leaf offset %u, default media %s\n",
-		       de->board_idx, ofs,
-		       media_name[de->media_type]);
+		pr_info("de%d: SROM leaf offset %u, default media %s\n",
+		       de->board_idx, ofs, media_name[de->media_type]);
 
 	/* init SIA register values to defaults */
 	for (i = 0; i < DE_MAX_MEDIA; i++) {
@@ -1879,9 +1878,9 @@ static void __devinit de21041_get_srom_i
 		de->media[idx].type = idx;
 
 		if (netif_msg_probe(de))
-			printk(KERN_INFO "de%d:   media block #%u: %s",
-			       de->board_idx, i,
-			       media_name[de->media[idx].type]);
+			pr_info("de%d:   media block #%u: %s",
+				de->board_idx, i,
+				media_name[de->media[idx].type]);
 
 		bufp += sizeof (ib->opts);
 
@@ -1893,13 +1892,13 @@ static void __devinit de21041_get_srom_i
 				sizeof(ib->csr15);
 
 			if (netif_msg_probe(de))
-				printk(" (%x,%x,%x)\n",
-				       de->media[idx].csr13,
-				       de->media[idx].csr14,
-				       de->media[idx].csr15);
+				pr_cont(" (%x,%x,%x)\n",
+					de->media[idx].csr13,
+					de->media[idx].csr14,
+					de->media[idx].csr15);
 
 		} else if (netif_msg_probe(de))
-			printk("\n");
+			pr_cont("\n");
 
 		if (bufp > ((void *)&ee_data[DE_EEPROM_SIZE - 3]))
 			break;
@@ -2005,7 +2004,7 @@ static int __devinit de_init_one (struct
 	/* check for invalid IRQ value */
 	if (pdev->irq < 2) {
 		rc = -EIO;
-		printk(KERN_ERR PFX "invalid irq (%d) for pci dev %s\n",
+		pr_err(PFX "invalid irq (%d) for pci dev %s\n",
 		       pdev->irq, pci_name(pdev));
 		goto err_out_res;
 	}
@@ -2016,14 +2015,14 @@ static int __devinit de_init_one (struct
 	pciaddr = pci_resource_start(pdev, 1);
 	if (!pciaddr) {
 		rc = -EIO;
-		printk(KERN_ERR PFX "no MMIO resource for pci dev %s\n",
-		       pci_name(pdev));
+		pr_err(PFX "no MMIO resource for pci dev %s\n", pci_name(pdev));
 		goto err_out_res;
 	}
 	if (pci_resource_len(pdev, 1) < DE_REGS_SIZE) {
 		rc = -EIO;
-		printk(KERN_ERR PFX "MMIO resource (%llx) too small on pci dev %s\n",
-		       (unsigned long long)pci_resource_len(pdev, 1), pci_name(pdev));
+		pr_err(PFX "MMIO resource (%llx) too small on pci dev %s\n",
+		       (unsigned long long)pci_resource_len(pdev, 1),
+		       pci_name(pdev));
 		goto err_out_res;
 	}
 
@@ -2031,9 +2030,9 @@ static int __devinit de_init_one (struct
 	regs = ioremap_nocache(pciaddr, DE_REGS_SIZE);
 	if (!regs) {
 		rc = -EIO;
-		printk(KERN_ERR PFX "Cannot map PCI MMIO (%llx@%lx) on pci dev %s\n",
-			(unsigned long long)pci_resource_len(pdev, 1),
-			pciaddr, pci_name(pdev));
+		pr_err(PFX "Cannot map PCI MMIO (%llx@%lx) on pci dev %s\n",
+		       (unsigned long long)pci_resource_len(pdev, 1),
+		       pciaddr, pci_name(pdev));
 		goto err_out_res;
 	}
 	dev->base_addr = (unsigned long) regs;
@@ -2044,8 +2043,7 @@ static int __devinit de_init_one (struct
 	/* make sure hardware is not running */
 	rc = de_reset_mac(de);
 	if (rc) {
-		printk(KERN_ERR PFX "Cannot reset MAC, pci dev %s\n",
-		       pci_name(pdev));
+		pr_err(PFX "Cannot reset MAC, pci dev %s\n", pci_name(pdev));
 		goto err_out_iomap;
 	}
 
@@ -2065,12 +2063,11 @@ static int __devinit de_init_one (struct
 		goto err_out_iomap;
 
 	/* print info about board and interface just registered */
-	printk (KERN_INFO "%s: %s at 0x%lx, %pM, IRQ %d\n",
-		dev->name,
-		de->de21040 ? "21040" : "21041",
-		dev->base_addr,
-		dev->dev_addr,
-		dev->irq);
+	dev_info(&dev->dev, "%s at 0x%lx, %pM, IRQ %d\n",
+		 de->de21040 ? "21040" : "21041",
+		 dev->base_addr,
+		 dev->dev_addr,
+		 dev->irq);
 
 	pci_set_drvdata(pdev, dev);
 
@@ -2158,8 +2155,7 @@ static int de_resume (struct pci_dev *pd
 	if (!netif_running(dev))
 		goto out_attach;
 	if ((retval = pci_enable_device(pdev))) {
-		printk (KERN_ERR "%s: pci_enable_device failed in resume\n",
-			dev->name);
+		dev_err(&dev->dev, "pci_enable_device failed in resume\n");
 		goto out;
 	}
 	de_init_hw(de);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tulip/de4x5.c linux-libre-2.6.34-gnu1/drivers/net/tulip/de4x5.c
--- linux-libre-2.6.33-gnu1/drivers/net/tulip/de4x5.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tulip/de4x5.c	2010-05-16 17:17:36.000000000 -0400
@@ -450,7 +450,6 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/eisa.h>
 #include <linux/delay.h>
@@ -467,6 +466,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/moduleparam.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -1951,9 +1951,9 @@ static void
 SetMulticastFilter(struct net_device *dev)
 {
     struct de4x5_private *lp = netdev_priv(dev);
-    struct dev_mc_list *dmi=dev->mc_list;
+    struct dev_mc_list *dmi;
     u_long iobase = dev->base_addr;
-    int i, j, bit, byte;
+    int i, bit, byte;
     u16 hashcode;
     u32 omr, crc;
     char *pa;
@@ -1963,12 +1963,11 @@ SetMulticastFilter(struct net_device *de
     omr &= ~(OMR_PR | OMR_PM);
     pa = build_setup_frame(dev, ALL);        /* Build the basic frame */
 
-    if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 14)) {
+    if ((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 14)) {
 	omr |= OMR_PM;                       /* Pass all multicasts */
     } else if (lp->setup_f == HASH_PERF) {   /* Hash Filtering */
-	for (i=0;i<dev->mc_count;i++) {      /* for each address in the list */
-	    addrs=dmi->dmi_addr;
-	    dmi=dmi->next;
+	netdev_for_each_mc_addr(dmi, dev) {
+	    addrs = dmi->dmi_addr;
 	    if ((*addrs & 0x01) == 1) {      /* multicast address? */
 		crc = ether_crc_le(ETH_ALEN, addrs);
 		hashcode = crc & HASH_BITS;  /* hashcode is 9 LSb of CRC */
@@ -1984,9 +1983,8 @@ SetMulticastFilter(struct net_device *de
 	    }
 	}
     } else {                                 /* Perfect filtering */
-	for (j=0; j<dev->mc_count; j++) {
-	    addrs=dmi->dmi_addr;
-	    dmi=dmi->next;
+	netdev_for_each_mc_addr(dmi, dev) {
+	    addrs = dmi->dmi_addr;
 	    for (i=0; i<ETH_ALEN; i++) {
 		*(pa + (i&1)) = *addrs++;
 		if (i & 0x01) pa += 4;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tulip/dmfe.c linux-libre-2.6.34-gnu1/drivers/net/tulip/dmfe.c
--- linux-libre-2.6.33-gnu1/drivers/net/tulip/dmfe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tulip/dmfe.c	2010-05-16 17:17:36.000000000 -0400
@@ -61,6 +61,8 @@
     Test and make sure PCI latency is now correct for all cases.
 */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #define DRV_NAME	"dmfe"
 #define DRV_VERSION	"1.36.4"
 #define DRV_RELDATE	"2002-01-17"
@@ -72,7 +74,6 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
@@ -149,16 +150,17 @@
 #define DMFE_TX_TIMEOUT ((3*HZ)/2)	/* tx packet time-out time 1.5 s" */
 #define DMFE_TX_KICK 	(HZ/2)	/* tx packet Kick-out time 0.5 s" */
 
-#define DMFE_DBUG(dbug_now, msg, value) \
-	do { \
- 		if (dmfe_debug || (dbug_now)) \
-			printk(KERN_ERR DRV_NAME ": %s %lx\n",\
- 				(msg), (long) (value)); \
+#define DMFE_DBUG(dbug_now, msg, value)			\
+	do {						\
+		if (dmfe_debug || (dbug_now))		\
+			pr_err("%s %lx\n",		\
+			       (msg), (long) (value));	\
 	} while (0)
 
-#define SHOW_MEDIA_TYPE(mode) \
-	printk (KERN_INFO DRV_NAME ": Change Speed to %sMhz %s duplex\n" , \
-		(mode & 1) ? "100":"10", (mode & 4) ? "full":"half");
+#define SHOW_MEDIA_TYPE(mode)				\
+	pr_info("Change Speed to %sMhz %s duplex\n" ,	\
+		(mode & 1) ? "100":"10",		\
+		(mode & 4) ? "full":"half");
 
 
 /* CR9 definition: SROM/MII */
@@ -327,8 +329,8 @@ static void poll_dmfe (struct net_device
 static void dmfe_descriptor_init(struct dmfe_board_info *, unsigned long);
 static void allocate_rx_buffer(struct dmfe_board_info *);
 static void update_cr6(u32, unsigned long);
-static void send_filter_frame(struct DEVICE * ,int);
-static void dm9132_id_table(struct DEVICE * ,int);
+static void send_filter_frame(struct DEVICE *);
+static void dm9132_id_table(struct DEVICE *);
 static u16 phy_read(unsigned long, u8, u8, u32);
 static void phy_write(unsigned long, u8, u8, u16, u32);
 static void phy_write_1bit(unsigned long, u32);
@@ -391,8 +393,7 @@ static int __devinit dmfe_init_one (stru
 		struct device_node *dp = pci_device_to_OF_node(pdev);
 
 		if (dp && of_get_property(dp, "local-mac-address", NULL)) {
-			printk(KERN_INFO DRV_NAME
-			       ": skipping on-board DM910x (use tulip)\n");
+			pr_info("skipping on-board DM910x (use tulip)\n");
 			return -ENODEV;
 		}
 	}
@@ -405,8 +406,7 @@ static int __devinit dmfe_init_one (stru
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
-		printk(KERN_WARNING DRV_NAME
-			": 32-bit PCI DMA not available.\n");
+		pr_warning("32-bit PCI DMA not available\n");
 		err = -ENODEV;
 		goto err_out_free;
 	}
@@ -417,13 +417,13 @@ static int __devinit dmfe_init_one (stru
 		goto err_out_free;
 
 	if (!pci_resource_start(pdev, 0)) {
-		printk(KERN_ERR DRV_NAME ": I/O base is zero\n");
+		pr_err("I/O base is zero\n");
 		err = -ENODEV;
 		goto err_out_disable;
 	}
 
 	if (pci_resource_len(pdev, 0) < (CHK_IO_SIZE(pdev)) ) {
-		printk(KERN_ERR DRV_NAME ": Allocated I/O size too small\n");
+		pr_err("Allocated I/O size too small\n");
 		err = -ENODEV;
 		goto err_out_disable;
 	}
@@ -438,7 +438,7 @@ static int __devinit dmfe_init_one (stru
 #endif
 
 	if (pci_request_regions(pdev, DRV_NAME)) {
-		printk(KERN_ERR DRV_NAME ": Failed to request PCI regions\n");
+		pr_err("Failed to request PCI regions\n");
 		err = -ENODEV;
 		goto err_out_disable;
 	}
@@ -497,12 +497,9 @@ static int __devinit dmfe_init_one (stru
 	if (err)
 		goto err_out_free_buf;
 
-	printk(KERN_INFO "%s: Davicom DM%04lx at pci%s, %pM, irq %d.\n",
-	       dev->name,
-	       ent->driver_data >> 16,
-	       pci_name(pdev),
-	       dev->dev_addr,
-	       dev->irq);
+	dev_info(&dev->dev, "Davicom DM%04lx at pci%s, %pM, irq %d\n",
+		 ent->driver_data >> 16,
+		 pci_name(pdev), dev->dev_addr, dev->irq);
 
 	pci_set_master(pdev);
 
@@ -660,9 +657,9 @@ static void dmfe_init_dm910x(struct DEVI
 
 	/* Send setup frame */
 	if (db->chip_id == PCI_DM9132_ID)
-		dm9132_id_table(dev, dev->mc_count);	/* DM9132 */
+		dm9132_id_table(dev);	/* DM9132 */
 	else
-		send_filter_frame(dev, dev->mc_count);	/* DM9102/DM9102A */
+		send_filter_frame(dev);	/* DM9102/DM9102A */
 
 	/* Init CR7, interrupt active bit */
 	db->cr7_data = CR7_DEFAULT;
@@ -696,7 +693,7 @@ static netdev_tx_t dmfe_start_xmit(struc
 
 	/* Too large packet check */
 	if (skb->len > MAX_PACKET_SIZE) {
-		printk(KERN_ERR DRV_NAME ": big packet = %d\n", (u16)skb->len);
+		pr_err("big packet = %d\n", (u16)skb->len);
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
 	}
@@ -706,8 +703,7 @@ static netdev_tx_t dmfe_start_xmit(struc
 	/* No Tx resource check, it never happen nromally */
 	if (db->tx_queue_cnt >= TX_FREE_DESC_CNT) {
 		spin_unlock_irqrestore(&db->lock, flags);
-		printk(KERN_ERR DRV_NAME ": No Tx resource %ld\n",
-		       db->tx_queue_cnt);
+		pr_err("No Tx resource %ld\n", db->tx_queue_cnt);
 		return NETDEV_TX_BUSY;
 	}
 
@@ -779,12 +775,11 @@ static int dmfe_stop(struct DEVICE *dev)
 
 #if 0
 	/* show statistic counter */
-	printk(DRV_NAME ": FU:%lx EC:%lx LC:%lx NC:%lx"
-		" LOC:%lx TXJT:%lx RESET:%lx RCR8:%lx FAL:%lx TT:%lx\n",
-		db->tx_fifo_underrun, db->tx_excessive_collision,
-		db->tx_late_collision, db->tx_no_carrier, db->tx_loss_carrier,
-		db->tx_jabber_timeout, db->reset_count, db->reset_cr8,
-		db->reset_fatal, db->reset_TXtimeout);
+	printk("FU:%lx EC:%lx LC:%lx NC:%lx LOC:%lx TXJT:%lx RESET:%lx RCR8:%lx FAL:%lx TT:%lx\n",
+	       db->tx_fifo_underrun, db->tx_excessive_collision,
+	       db->tx_late_collision, db->tx_no_carrier, db->tx_loss_carrier,
+	       db->tx_jabber_timeout, db->reset_count, db->reset_cr8,
+	       db->reset_fatal, db->reset_TXtimeout);
 #endif
 
 	return 0;
@@ -885,7 +880,7 @@ static void dmfe_free_tx_pkt(struct DEVI
 	txptr = db->tx_remove_ptr;
 	while(db->tx_packet_cnt) {
 		tdes0 = le32_to_cpu(txptr->tdes0);
-		/* printk(DRV_NAME ": tdes0=%x\n", tdes0); */
+		pr_debug("tdes0=%x\n", tdes0);
 		if (tdes0 & 0x80000000)
 			break;
 
@@ -895,7 +890,7 @@ static void dmfe_free_tx_pkt(struct DEVI
 
 		/* Transmit statistic counter */
 		if ( tdes0 != 0x7fffffff ) {
-			/* printk(DRV_NAME ": tdes0=%x\n", tdes0); */
+			pr_debug("tdes0=%x\n", tdes0);
 			dev->stats.collisions += (tdes0 >> 3) & 0xf;
 			dev->stats.tx_bytes += le32_to_cpu(txptr->tdes1) & 0x7ff;
 			if (tdes0 & TDES0_ERR_MASK) {
@@ -992,7 +987,7 @@ static void dmfe_rx_packet(struct DEVICE
 			/* error summary bit check */
 			if (rdes0 & 0x8000) {
 				/* This is a error packet */
-				//printk(DRV_NAME ": rdes0: %lx\n", rdes0);
+				pr_debug("rdes0: %x\n", rdes0);
 				dev->stats.rx_errors++;
 				if (rdes0 & 1)
 					dev->stats.rx_fifo_errors++;
@@ -1056,6 +1051,7 @@ static void dmfe_set_filter_mode(struct
 {
 	struct dmfe_board_info *db = netdev_priv(dev);
 	unsigned long flags;
+	int mc_count = netdev_mc_count(dev);
 
 	DMFE_DBUG(0, "dmfe_set_filter_mode()", 0);
 	spin_lock_irqsave(&db->lock, flags);
@@ -1068,19 +1064,19 @@ static void dmfe_set_filter_mode(struct
 		return;
 	}
 
-	if (dev->flags & IFF_ALLMULTI || dev->mc_count > DMFE_MAX_MULTICAST) {
-		DMFE_DBUG(0, "Pass all multicast address", dev->mc_count);
+	if (dev->flags & IFF_ALLMULTI || mc_count > DMFE_MAX_MULTICAST) {
+		DMFE_DBUG(0, "Pass all multicast address", mc_count);
 		db->cr6_data &= ~(CR6_PM | CR6_PBF);
 		db->cr6_data |= CR6_PAM;
 		spin_unlock_irqrestore(&db->lock, flags);
 		return;
 	}
 
-	DMFE_DBUG(0, "Set multicast address", dev->mc_count);
+	DMFE_DBUG(0, "Set multicast address", mc_count);
 	if (db->chip_id == PCI_DM9132_ID)
-		dm9132_id_table(dev, dev->mc_count);	/* DM9132 */
+		dm9132_id_table(dev);	/* DM9132 */
 	else
-		send_filter_frame(dev, dev->mc_count); 	/* DM9102/DM9102A */
+		send_filter_frame(dev);	/* DM9102/DM9102A */
 	spin_unlock_irqrestore(&db->lock, flags);
 }
 
@@ -1191,8 +1187,7 @@ static void dmfe_timer(unsigned long dat
 		if ( time_after(jiffies, dev->trans_start + DMFE_TX_TIMEOUT) ) {
 			db->reset_TXtimeout++;
 			db->wait_reset = 1;
-			printk(KERN_WARNING "%s: Tx timeout - resetting\n",
-			       dev->name);
+			dev_warn(&dev->dev, "Tx timeout - resetting\n");
 		}
 	}
 
@@ -1456,7 +1451,7 @@ static void update_cr6(u32 cr6_data, uns
  *	This setup frame initilize DM910X address filter mode
 */
 
-static void dm9132_id_table(struct DEVICE *dev, int mc_cnt)
+static void dm9132_id_table(struct DEVICE *dev)
 {
 	struct dev_mc_list *mcptr;
 	u16 * addrptr;
@@ -1476,15 +1471,14 @@ static void dm9132_id_table(struct DEVIC
 	ioaddr += 4;
 
 	/* Clear Hash Table */
-	for (i = 0; i < 4; i++)
-		hash_table[i] = 0x0;
+	memset(hash_table, 0, sizeof(hash_table));
 
 	/* broadcast address */
 	hash_table[3] = 0x8000;
 
 	/* the multicast address in Hash Table : 64 bits */
-	for (mcptr = dev->mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
-		hash_val = cal_CRC( (char *) mcptr->dmi_addr, 6, 0) & 0x3f;
+	netdev_for_each_mc_addr(mcptr, dev) {
+		hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f;
 		hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
 	}
 
@@ -1499,7 +1493,7 @@ static void dm9132_id_table(struct DEVIC
  *	This setup frame initilize DM910X address filter mode
  */
 
-static void send_filter_frame(struct DEVICE *dev, int mc_cnt)
+static void send_filter_frame(struct DEVICE *dev)
 {
 	struct dmfe_board_info *db = netdev_priv(dev);
 	struct dev_mc_list *mcptr;
@@ -1525,14 +1519,14 @@ static void send_filter_frame(struct DEV
 	*suptr++ = 0xffff;
 
 	/* fit the multicast address */
-	for (mcptr = dev->mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
+	netdev_for_each_mc_addr(mcptr, dev) {
 		addrptr = (u16 *) mcptr->dmi_addr;
 		*suptr++ = addrptr[0];
 		*suptr++ = addrptr[1];
 		*suptr++ = addrptr[2];
 	}
 
-	for (; i<14; i++) {
+	for (i = netdev_mc_count(dev); i < 14; i++) {
 		*suptr++ = 0xffff;
 		*suptr++ = 0xffff;
 		*suptr++ = 0xffff;
@@ -1646,7 +1640,7 @@ static u8 dmfe_sense_speed(struct dmfe_b
 		else 				/* DM9102/DM9102A */
 			phy_mode = phy_read(db->ioaddr,
 				    db->phy_addr, 17, db->chip_id) & 0xf000;
-		/* printk(DRV_NAME ": Phy_mode %x ",phy_mode); */
+		pr_debug("Phy_mode %x\n", phy_mode);
 		switch (phy_mode) {
 		case 0x1000: db->op_mode = DMFE_10MHF; break;
 		case 0x2000: db->op_mode = DMFE_10MFD; break;
@@ -2089,7 +2083,7 @@ static void dmfe_HPNA_remote_cmd_chk(str
 
 
 
-static struct pci_device_id dmfe_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(dmfe_pci_tbl) = {
 	{ 0x1282, 0x9132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_DM9132_ID },
 	{ 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_DM9102_ID },
 	{ 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_DM9100_ID },
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tulip/eeprom.c linux-libre-2.6.34-gnu1/drivers/net/tulip/eeprom.c
--- linux-libre-2.6.33-gnu1/drivers/net/tulip/eeprom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tulip/eeprom.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include "tulip.h"
 #include <linux/init.h>
 #include <asm/unaligned.h>
@@ -143,6 +144,12 @@ static void __devinit tulip_build_fake_m
 
 void __devinit tulip_parse_eeprom(struct net_device *dev)
 {
+	/*
+	  dev is not registered at this point, so logging messages can't
+	  use dev_<level> or netdev_<level> but dev->name is good via a
+	  hack in the caller
+	*/
+
 	/* The last media info list parsed, for multiport boards.  */
 	static struct mediatable *last_mediatable;
 	static unsigned char *last_ee_data;
@@ -161,15 +168,14 @@ void __devinit tulip_parse_eeprom(struct
 		if (ee_data[0] == 0xff) {
 			if (last_mediatable) {
 				controller_index++;
-				printk(KERN_INFO "%s:  Controller %d of multiport board.\n",
-					   dev->name, controller_index);
+				pr_info("%s: Controller %d of multiport board\n",
+					dev->name, controller_index);
 				tp->mtable = last_mediatable;
 				ee_data = last_ee_data;
 				goto subsequent_board;
 			} else
-				printk(KERN_INFO "%s:  Missing EEPROM, this interface may "
-					   "not work correctly!\n",
-			   dev->name);
+				pr_info("%s: Missing EEPROM, this interface may not work correctly!\n",
+					dev->name);
 			return;
 		}
 	  /* Do a fix-up based on the vendor half of the station address prefix. */
@@ -181,16 +187,14 @@ void __devinit tulip_parse_eeprom(struct
 			  i++;			/* An Accton EN1207, not an outlaw Maxtech. */
 		  memcpy(ee_data + 26, eeprom_fixups[i].newtable,
 				 sizeof(eeprom_fixups[i].newtable));
-		  printk(KERN_INFO "%s: Old format EEPROM on '%s' board.  Using"
-				 " substitute media control info.\n",
-				 dev->name, eeprom_fixups[i].name);
+		  pr_info("%s: Old format EEPROM on '%s' board.  Using substitute media control info\n",
+			  dev->name, eeprom_fixups[i].name);
 		  break;
 		}
 	  }
 	  if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
-		  printk(KERN_INFO "%s: Old style EEPROM with no media selection "
-				 "information.\n",
-			   dev->name);
+		  pr_info("%s: Old style EEPROM with no media selection information\n",
+			  dev->name);
 		return;
 	  }
 	}
@@ -218,7 +222,8 @@ subsequent_board:
 	        /* there is no phy information, don't even try to build mtable */
 	        if (count == 0) {
 			if (tulip_debug > 0)
-				printk(KERN_WARNING "%s: no phy info, aborting mtable build\n", dev->name);
+				pr_warning("%s: no phy info, aborting mtable build\n",
+					   dev->name);
 		        return;
 		}
 
@@ -234,8 +239,10 @@ subsequent_board:
 		mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
 		mtable->csr15dir = mtable->csr15val = 0;
 
-		printk(KERN_INFO "%s:  EEPROM default media type %s.\n", dev->name,
-			   media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]);
+		pr_info("%s: EEPROM default media type %s\n",
+			dev->name,
+			media & 0x0800 ? "Autosense"
+				       : medianame[media & MEDIA_MASK]);
 		for (i = 0; i < count; i++) {
 			struct medialeaf *leaf = &mtable->mleaf[i];
 
@@ -298,16 +305,17 @@ subsequent_board:
 			}
 			if (tulip_debug > 1  &&  leaf->media == 11) {
 				unsigned char *bp = leaf->leafdata;
-				printk(KERN_INFO "%s:  MII interface PHY %d, setup/reset "
-					   "sequences %d/%d long, capabilities %2.2x %2.2x.\n",
-					   dev->name, bp[0], bp[1], bp[2 + bp[1]*2],
-					   bp[5 + bp[2 + bp[1]*2]*2], bp[4 + bp[2 + bp[1]*2]*2]);
+				pr_info("%s: MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %02x %02x\n",
+					dev->name,
+					bp[0], bp[1], bp[2 + bp[1]*2],
+					bp[5 + bp[2 + bp[1]*2]*2],
+					bp[4 + bp[2 + bp[1]*2]*2]);
 			}
-			printk(KERN_INFO "%s:  Index #%d - Media %s (#%d) described "
-				   "by a %s (%d) block.\n",
-				   dev->name, i, medianame[leaf->media & 15], leaf->media,
-				   leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>",
-				   leaf->type);
+			pr_info("%s: Index #%d - Media %s (#%d) described by a %s (%d) block\n",
+				dev->name,
+				i, medianame[leaf->media & 15], leaf->media,
+				leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>",
+				leaf->type);
 		}
 		if (new_advertise)
 			tp->sym_advertise = new_advertise;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tulip/interrupt.c linux-libre-2.6.34-gnu1/drivers/net/tulip/interrupt.c
--- linux-libre-2.6.33-gnu1/drivers/net/tulip/interrupt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tulip/interrupt.c	2010-05-16 17:17:36.000000000 -0400
@@ -125,12 +125,12 @@ int tulip_poll(struct napi_struct *napi,
 #endif
 
 	if (tulip_debug > 4)
-		printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry,
-			   tp->rx_ring[entry].status);
+		printk(KERN_DEBUG " In tulip_rx(), entry %d %08x\n",
+		       entry, tp->rx_ring[entry].status);
 
        do {
 		if (ioread32(tp->base_addr + CSR5) == 0xffffffff) {
-			printk(KERN_DEBUG " In tulip_poll(), hardware disappeared.\n");
+			printk(KERN_DEBUG " In tulip_poll(), hardware disappeared\n");
 			break;
 		}
                /* Acknowledge current RX interrupt sources. */
@@ -146,7 +146,7 @@ int tulip_poll(struct napi_struct *napi,
                                break;
 
                        if (tulip_debug > 5)
-                               printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n",
+                               printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %08x\n",
                                       dev->name, entry, status);
 
 		       if (++work_done >= budget)
@@ -177,15 +177,15 @@ int tulip_poll(struct napi_struct *napi,
                                 /* Ingore earlier buffers. */
                                        if ((status & 0xffff) != 0x7fff) {
                                                if (tulip_debug > 1)
-                                                       printk(KERN_WARNING "%s: Oversized Ethernet frame "
-                                                              "spanned multiple buffers, status %8.8x!\n",
-                                                              dev->name, status);
+                                                       dev_warn(&dev->dev,
+								"Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
+								status);
                                                tp->stats.rx_length_errors++;
                                        }
 			       } else {
                                 /* There was a fatal error. */
                                        if (tulip_debug > 2)
-                                               printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
+                                               printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n",
                                                       dev->name, status);
                                        tp->stats.rx_errors++; /* end of a packet.*/
 				       if (pkt_len > 1518 ||
@@ -226,12 +226,11 @@ int tulip_poll(struct napi_struct *napi,
 #ifndef final_version
                                        if (tp->rx_buffers[entry].mapping !=
                                            le32_to_cpu(tp->rx_ring[entry].buffer1)) {
-                                               printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
-                                                      "do not match in tulip_rx: %08x vs. %08llx %p / %p.\n",
-                                                      dev->name,
-                                                      le32_to_cpu(tp->rx_ring[entry].buffer1),
-                                                      (unsigned long long)tp->rx_buffers[entry].mapping,
-                                                      skb->head, temp);
+                                               dev_err(&dev->dev,
+						       "Internal fault: The skbuff addresses do not match in tulip_rx: %08x vs. %08llx %p / %p\n",
+						       le32_to_cpu(tp->rx_ring[entry].buffer1),
+						       (unsigned long long)tp->rx_buffers[entry].mapping,
+						       skb->head, temp);
                                        }
 #endif
 
@@ -365,16 +364,16 @@ static int tulip_rx(struct net_device *d
 	int received = 0;
 
 	if (tulip_debug > 4)
-		printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry,
-			   tp->rx_ring[entry].status);
+		printk(KERN_DEBUG " In tulip_rx(), entry %d %08x\n",
+		       entry, tp->rx_ring[entry].status);
 	/* 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);
+			printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %08x\n",
+			       dev->name, entry, status);
 		if (--rx_work_limit < 0)
 			break;
 
@@ -402,16 +401,16 @@ static int tulip_rx(struct net_device *d
 				/* Ingore earlier buffers. */
 				if ((status & 0xffff) != 0x7fff) {
 					if (tulip_debug > 1)
-						printk(KERN_WARNING "%s: Oversized Ethernet frame "
-							   "spanned multiple buffers, status %8.8x!\n",
-							   dev->name, status);
+						dev_warn(&dev->dev,
+							 "Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
+							 status);
 					tp->stats.rx_length_errors++;
 				}
 			} else {
 				/* There was a fatal error. */
 				if (tulip_debug > 2)
-					printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
-						   dev->name, status);
+					printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n",
+					       dev->name, status);
 				tp->stats.rx_errors++; /* end of a packet.*/
 				if (pkt_len > 1518 ||
 				    (status & RxDescRunt))
@@ -450,12 +449,11 @@ static int tulip_rx(struct net_device *d
 #ifndef final_version
 				if (tp->rx_buffers[entry].mapping !=
 				    le32_to_cpu(tp->rx_ring[entry].buffer1)) {
-					printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
-					       "do not match in tulip_rx: %08x vs. %Lx %p / %p.\n",
-					       dev->name,
-					       le32_to_cpu(tp->rx_ring[entry].buffer1),
-					       (long long)tp->rx_buffers[entry].mapping,
-					       skb->head, temp);
+					dev_err(&dev->dev,
+						"Internal fault: The skbuff addresses do not match in tulip_rx: %08x vs. %Lx %p / %p\n",
+						le32_to_cpu(tp->rx_ring[entry].buffer1),
+						(long long)tp->rx_buffers[entry].mapping,
+						skb->head, temp);
 				}
 #endif
 
@@ -569,7 +567,7 @@ irqreturn_t tulip_interrupt(int irq, voi
 #endif /*  CONFIG_TULIP_NAPI */
 
 		if (tulip_debug > 4)
-			printk(KERN_DEBUG "%s: interrupt  csr5=%#8.8x new csr5=%#8.8x.\n",
+			printk(KERN_DEBUG "%s: interrupt  csr5=%#8.8x new csr5=%#8.8x\n",
 			       dev->name, csr5, ioread32(ioaddr + CSR5));
 
 
@@ -601,8 +599,8 @@ irqreturn_t tulip_interrupt(int irq, voi
 					/* There was an major error, log it. */
 #ifndef final_version
 					if (tulip_debug > 1)
-						printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
-							   dev->name, status);
+						printk(KERN_DEBUG "%s: Transmit error, Tx status %08x\n",
+						       dev->name, status);
 #endif
 					tp->stats.tx_errors++;
 					if (status & 0x4104) tp->stats.tx_aborted_errors++;
@@ -631,8 +629,9 @@ irqreturn_t tulip_interrupt(int irq, voi
 
 #ifndef final_version
 			if (tp->cur_tx - dirty_tx > TX_RING_SIZE) {
-				printk(KERN_ERR "%s: Out-of-sync dirty pointer, %d vs. %d.\n",
-					   dev->name, dirty_tx, tp->cur_tx);
+				dev_err(&dev->dev,
+					"Out-of-sync dirty pointer, %d vs. %d\n",
+					dirty_tx, tp->cur_tx);
 				dirty_tx += TX_RING_SIZE;
 			}
 #endif
@@ -643,9 +642,10 @@ irqreturn_t tulip_interrupt(int irq, voi
 			tp->dirty_tx = dirty_tx;
 			if (csr5 & TxDied) {
 				if (tulip_debug > 2)
-					printk(KERN_WARNING "%s: The transmitter stopped."
-						   "  CSR5 is %x, CSR6 %x, new CSR6 %x.\n",
-						   dev->name, csr5, ioread32(ioaddr + CSR6), tp->csr6);
+					dev_warn(&dev->dev,
+						 "The transmitter stopped.  CSR5 is %x, CSR6 %x, new CSR6 %x\n",
+						 csr5, ioread32(ioaddr + CSR6),
+						 tp->csr6);
 				tulip_restart_rxtx(tp);
 			}
 			spin_unlock(&tp->lock);
@@ -696,8 +696,9 @@ irqreturn_t tulip_interrupt(int irq, voi
 				 * to the 21142/3 docs that is).
 				 *   -- rmk
 				 */
-				printk(KERN_ERR "%s: (%lu) System Error occurred (%d)\n",
-					dev->name, tp->nir, error);
+				dev_err(&dev->dev,
+					"(%lu) System Error occurred (%d)\n",
+					tp->nir, error);
 			}
 			/* Clear all error sources, included undocumented ones! */
 			iowrite32(0x0800f7ba, ioaddr + CSR5);
@@ -706,16 +707,17 @@ irqreturn_t tulip_interrupt(int irq, voi
 		if (csr5 & TimerInt) {
 
 			if (tulip_debug > 2)
-				printk(KERN_ERR "%s: Re-enabling interrupts, %8.8x.\n",
-					   dev->name, csr5);
+				dev_err(&dev->dev,
+					"Re-enabling interrupts, %08x\n",
+					csr5);
 			iowrite32(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
 			tp->ttimer = 0;
 			oi++;
 		}
 		if (tx > maxtx || rx > maxrx || oi > maxoi) {
 			if (tulip_debug > 1)
-				printk(KERN_WARNING "%s: Too much work during an interrupt, "
-					   "csr5=0x%8.8x. (%lu) (%d,%d,%d)\n", dev->name, csr5, tp->nir, tx, rx, oi);
+				dev_warn(&dev->dev, "Too much work during an interrupt, csr5=0x%08x. (%lu) (%d,%d,%d)\n",
+					 csr5, tp->nir, tx, rx, oi);
 
                        /* Acknowledge all interrupt sources. */
                         iowrite32(0x8001ffff, ioaddr + CSR5);
@@ -764,14 +766,18 @@ irqreturn_t tulip_interrupt(int irq, voi
 	entry = tp->dirty_rx % RX_RING_SIZE;
 	if (tp->rx_buffers[entry].skb == NULL) {
 		if (tulip_debug > 1)
-			printk(KERN_WARNING "%s: in rx suspend mode: (%lu) (tp->cur_rx = %u, ttimer = %d, rx = %d) go/stay in suspend mode\n", dev->name, tp->nir, tp->cur_rx, tp->ttimer, rx);
+			dev_warn(&dev->dev,
+				 "in rx suspend mode: (%lu) (tp->cur_rx = %u, ttimer = %d, rx = %d) go/stay in suspend mode\n",
+				 tp->nir, tp->cur_rx, tp->ttimer, rx);
 		if (tp->chip_id == LC82C168) {
 			iowrite32(0x00, ioaddr + CSR7);
 			mod_timer(&tp->timer, RUN_AT(HZ/50));
 		} else {
 			if (tp->ttimer == 0 || (ioread32(ioaddr + CSR11) & 0xffff) == 0) {
 				if (tulip_debug > 1)
-					printk(KERN_WARNING "%s: in rx suspend mode: (%lu) set timer\n", dev->name, tp->nir);
+					dev_warn(&dev->dev,
+						 "in rx suspend mode: (%lu) set timer\n",
+						 tp->nir);
 				iowrite32(tulip_tbl[tp->chip_id].valid_intrs | TimerInt,
 					ioaddr + CSR7);
 				iowrite32(TimerInt, ioaddr + CSR5);
@@ -787,8 +793,8 @@ irqreturn_t tulip_interrupt(int irq, voi
 	}
 
 	if (tulip_debug > 4)
-		printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#4.4x.\n",
-			   dev->name, ioread32(ioaddr + CSR5));
+		printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#04x\n",
+		       dev->name, ioread32(ioaddr + CSR5));
 
 	return IRQ_HANDLED;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tulip/media.c linux-libre-2.6.34-gnu1/drivers/net/tulip/media.c
--- linux-libre-2.6.33-gnu1/drivers/net/tulip/media.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tulip/media.c	2010-05-16 17:17:36.000000000 -0400
@@ -182,9 +182,8 @@ void tulip_select_media(struct net_devic
 		switch (mleaf->type) {
 		case 0:					/* 21140 non-MII xcvr. */
 			if (tulip_debug > 1)
-				printk(KERN_DEBUG "%s: Using a 21140 non-MII transceiver"
-					   " with control setting %2.2x.\n",
-					   dev->name, p[1]);
+				printk(KERN_DEBUG "%s: Using a 21140 non-MII transceiver with control setting %02x\n",
+				       dev->name, p[1]);
 			dev->if_port = p[0];
 			if (startup)
 				iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12);
@@ -205,15 +204,15 @@ void tulip_select_media(struct net_devic
 				struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
 				unsigned char *rst = rleaf->leafdata;
 				if (tulip_debug > 1)
-					printk(KERN_DEBUG "%s: Resetting the transceiver.\n",
-						   dev->name);
+					printk(KERN_DEBUG "%s: Resetting the transceiver\n",
+					       dev->name);
 				for (i = 0; i < rst[0]; i++)
 					iowrite32(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
 			}
 			if (tulip_debug > 1)
-				printk(KERN_DEBUG "%s: 21143 non-MII %s transceiver control "
-					   "%4.4x/%4.4x.\n",
-					   dev->name, medianame[dev->if_port], setup[0], setup[1]);
+				printk(KERN_DEBUG "%s: 21143 non-MII %s transceiver control %04x/%04x\n",
+				       dev->name, medianame[dev->if_port],
+				       setup[0], setup[1]);
 			if (p[0] & 0x40) {	/* SIA (CSR13-15) setup values are provided. */
 				csr13val = setup[0];
 				csr14val = setup[1];
@@ -240,8 +239,8 @@ void tulip_select_media(struct net_devic
 				if (startup) iowrite32(csr13val, ioaddr + CSR13);
 			}
 			if (tulip_debug > 1)
-				printk(KERN_DEBUG "%s:  Setting CSR15 to %8.8x/%8.8x.\n",
-					   dev->name, csr15dir, csr15val);
+				printk(KERN_DEBUG "%s:  Setting CSR15 to %08x/%08x\n",
+				       dev->name, csr15dir, csr15val);
 			if (mleaf->type == 4)
 				new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18);
 			else
@@ -317,8 +316,9 @@ void tulip_select_media(struct net_devic
 				if (tp->mii_advertise == 0)
 					tp->mii_advertise = tp->advertising[phy_num];
 				if (tulip_debug > 1)
-					printk(KERN_DEBUG "%s:  Advertising %4.4x on MII %d.\n",
-					       dev->name, tp->mii_advertise, tp->phys[phy_num]);
+					printk(KERN_DEBUG "%s:  Advertising %04x on MII %d\n",
+					       dev->name, tp->mii_advertise,
+					       tp->phys[phy_num]);
 				tulip_mdio_write(dev, tp->phys[phy_num], 4, tp->mii_advertise);
 			}
 			break;
@@ -335,8 +335,8 @@ void tulip_select_media(struct net_devic
 				struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
 				unsigned char *rst = rleaf->leafdata;
 				if (tulip_debug > 1)
-					printk(KERN_DEBUG "%s: Resetting the transceiver.\n",
-						   dev->name);
+					printk(KERN_DEBUG "%s: Resetting the transceiver\n",
+					       dev->name);
 				for (i = 0; i < rst[0]; i++)
 					iowrite32(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
 			}
@@ -344,20 +344,20 @@ void tulip_select_media(struct net_devic
 			break;
 		}
 		default:
-			printk(KERN_DEBUG "%s:  Invalid media table selection %d.\n",
-					   dev->name, mleaf->type);
+			printk(KERN_DEBUG "%s:  Invalid media table selection %d\n",
+			       dev->name, mleaf->type);
 			new_csr6 = 0x020E0000;
 		}
 		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: Using media type %s, CSR12 is %2.2x.\n",
-				   dev->name, medianame[dev->if_port],
+			printk(KERN_DEBUG "%s: Using media type %s, CSR12 is %02x\n",
+			       dev->name, medianame[dev->if_port],
 				   ioread32(ioaddr + CSR12) & 0xff);
 	} else if (tp->chip_id == LC82C168) {
 		if (startup && ! tp->medialock)
 			dev->if_port = tp->mii_cnt ? 11 : 0;
 		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: PNIC PHY status is %3.3x, media %s.\n",
-				   dev->name, ioread32(ioaddr + 0xB8), medianame[dev->if_port]);
+			printk(KERN_DEBUG "%s: PNIC PHY status is %3.3x, media %s\n",
+			       dev->name, ioread32(ioaddr + 0xB8), medianame[dev->if_port]);
 		if (tp->mii_cnt) {
 			new_csr6 = 0x810C0000;
 			iowrite32(0x0001, ioaddr + CSR15);
@@ -388,10 +388,9 @@ void tulip_select_media(struct net_devic
 		} else
 			new_csr6 = 0x03860000;
 		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: No media description table, assuming "
-				   "%s transceiver, CSR12 %2.2x.\n",
-				   dev->name, medianame[dev->if_port],
-				   ioread32(ioaddr + CSR12));
+			printk(KERN_DEBUG "%s: No media description table, assuming %s transceiver, CSR12 %02x\n",
+			       dev->name, medianame[dev->if_port],
+			       ioread32(ioaddr + CSR12));
 	}
 
 	tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0);
@@ -415,16 +414,17 @@ int tulip_check_duplex(struct net_device
 	bmsr = tulip_mdio_read(dev, tp->phys[0], MII_BMSR);
 	lpa = tulip_mdio_read(dev, tp->phys[0], MII_LPA);
 	if (tulip_debug > 1)
-		printk(KERN_INFO "%s: MII status %4.4x, Link partner report "
-			   "%4.4x.\n", dev->name, bmsr, lpa);
+		dev_info(&dev->dev, "MII status %04x, Link partner report %04x\n",
+			 bmsr, lpa);
 	if (bmsr == 0xffff)
 		return -2;
 	if ((bmsr & BMSR_LSTATUS) == 0) {
 		int new_bmsr = tulip_mdio_read(dev, tp->phys[0], MII_BMSR);
 		if ((new_bmsr & BMSR_LSTATUS) == 0) {
 			if (tulip_debug  > 1)
-				printk(KERN_INFO "%s: No link beat on the MII interface,"
-					   " status %4.4x.\n", dev->name, new_bmsr);
+				dev_info(&dev->dev,
+					 "No link beat on the MII interface, status %04x\n",
+					 new_bmsr);
 			return -1;
 		}
 	}
@@ -443,10 +443,10 @@ int tulip_check_duplex(struct net_device
 		tulip_restart_rxtx(tp);
 
 		if (tulip_debug > 0)
-			printk(KERN_INFO "%s: Setting %s-duplex based on MII"
-				   "#%d link partner capability of %4.4x.\n",
-				   dev->name, tp->full_duplex ? "full" : "half",
-				   tp->phys[0], lpa);
+			dev_info(&dev->dev,
+				 "Setting %s-duplex based on MII#%d link partner capability of %04x\n",
+				 tp->full_duplex ? "full" : "half",
+				 tp->phys[0], lpa);
 		return 1;
 	}
 
@@ -501,15 +501,13 @@ void __devinit tulip_find_mii (struct ne
 
 		tp->phys[phy_idx++] = phy;
 
-		printk (KERN_INFO "tulip%d:  MII transceiver #%d "
-			"config %4.4x status %4.4x advertising %4.4x.\n",
+		pr_info("tulip%d:  MII transceiver #%d config %04x status %04x advertising %04x\n",
 			board_idx, phy, mii_reg0, mii_status, mii_advert);
 
 		/* Fixup for DLink with miswired PHY. */
 		if (mii_advert != to_advert) {
-			printk (KERN_DEBUG "tulip%d:  Advertising %4.4x on PHY %d,"
-				" previously advertising %4.4x.\n",
-				board_idx, to_advert, phy, mii_advert);
+			printk(KERN_DEBUG "tulip%d:  Advertising %04x on PHY %d, previously advertising %04x\n",
+			       board_idx, to_advert, phy, mii_advert);
 			tulip_mdio_write (dev, phy, 4, to_advert);
 		}
 
@@ -554,7 +552,7 @@ void __devinit tulip_find_mii (struct ne
 	}
 	tp->mii_cnt = phy_idx;
 	if (tp->mtable && tp->mtable->has_mii && phy_idx == 0) {
-		printk (KERN_INFO "tulip%d: ***WARNING***: No MII transceiver found!\n",
+		pr_info("tulip%d: ***WARNING***: No MII transceiver found!\n",
 			board_idx);
 		tp->phys[0] = 1;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tulip/pnic2.c linux-libre-2.6.34-gnu1/drivers/net/tulip/pnic2.c
--- linux-libre-2.6.33-gnu1/drivers/net/tulip/pnic2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tulip/pnic2.c	2010-05-16 17:17:36.000000000 -0400
@@ -87,8 +87,8 @@ void pnic2_timer(unsigned long data)
 	int next_tick = 60*HZ;
 
 	if (tulip_debug > 3)
-		printk(KERN_INFO"%s: PNIC2 negotiation status %8.8x.\n",
-                    dev->name,ioread32(ioaddr + CSR12));
+		dev_info(&dev->dev, "PNIC2 negotiation status %08x\n",
+			 ioread32(ioaddr + CSR12));
 
 	if (next_tick) {
 		mod_timer(&tp->timer, RUN_AT(next_tick));
@@ -125,8 +125,8 @@ void pnic2_start_nway(struct net_device
         csr14 |= 0x00001184;
 
 	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: Restarting PNIC2 autonegotiation, "
-                      "csr14=%8.8x.\n", dev->name, csr14);
+		printk(KERN_DEBUG "%s: Restarting PNIC2 autonegotiation, csr14=%08x\n",
+		       dev->name, csr14);
 
         /* tell pnic2_lnk_change we are doing an nway negotiation */
 	dev->if_port = 0;
@@ -137,8 +137,8 @@ void pnic2_start_nway(struct net_device
 
 	tp->csr6 = ioread32(ioaddr + CSR6);
 	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: On Entry to Nway, "
-                      "csr6=%8.8x.\n", dev->name, tp->csr6);
+		printk(KERN_DEBUG "%s: On Entry to Nway, csr6=%08x\n",
+		       dev->name, tp->csr6);
 
         /* mask off any bits not to touch
          * comment at top of file explains mask value
@@ -181,9 +181,9 @@ void pnic2_lnk_change(struct net_device
 	int csr12 = ioread32(ioaddr + CSR12);
 
 	if (tulip_debug > 1)
-		printk(KERN_INFO"%s: PNIC2 link status interrupt %8.8x, "
-                       " CSR5 %x, %8.8x.\n", dev->name, csr12,
-                       csr5, ioread32(ioaddr + CSR14));
+		dev_info(&dev->dev,
+			 "PNIC2 link status interrupt %08x,  CSR5 %x, %08x\n",
+			 csr12, csr5, ioread32(ioaddr + CSR14));
 
 	/* If NWay finished and we have a negotiated partner capability.
          * check bits 14:12 for bit pattern 101 - all is good
@@ -215,9 +215,9 @@ void pnic2_lnk_change(struct net_device
 			else if (negotiated & 0x0020)	dev->if_port = 0;
 			else {
 			     if (tulip_debug > 1)
-		                   printk(KERN_INFO "%s: funny autonegotiate result "
-                                        "csr12 %8.8x advertising %4.4x\n",
-			                 dev->name, csr12, tp->sym_advertise);
+				     dev_info(&dev->dev,
+					      "funny autonegotiate result csr12 %08x advertising %04x\n",
+					      csr12, tp->sym_advertise);
 			     tp->nwayset = 0;
 			     /* so check  if 100baseTx link state is okay */
 			     if ((csr12 & 2) == 0  &&  (tp->sym_advertise & 0x0180))
@@ -231,10 +231,11 @@ void pnic2_lnk_change(struct net_device
 
 			if (tulip_debug > 1) {
 			       if (tp->nwayset)
-			             printk(KERN_INFO "%s: Switching to %s based on link "
-				    "negotiation %4.4x & %4.4x = %4.4x.\n",
-				     dev->name, medianame[dev->if_port],
-                                     tp->sym_advertise, tp->lpar, negotiated);
+				       dev_info(&dev->dev,
+						"Switching to %s based on link negotiation %04x & %04x = %04x\n",
+						medianame[dev->if_port],
+						tp->sym_advertise, tp->lpar,
+						negotiated);
 			}
 
                         /* remember to turn off bit 7 - autonegotiate
@@ -270,9 +271,9 @@ void pnic2_lnk_change(struct net_device
 			iowrite32(1, ioaddr + CSR13);
 
 			if (tulip_debug > 2)
-			        printk(KERN_DEBUG "%s:  Setting CSR6 %8.8x/%x CSR12 "
-                                      "%8.8x.\n", dev->name, tp->csr6,
-                                      ioread32(ioaddr + CSR6), ioread32(ioaddr + CSR12));
+			        printk(KERN_DEBUG "%s: Setting CSR6 %08x/%x CSR12 %08x\n",
+				       dev->name, tp->csr6,
+				       ioread32(ioaddr + CSR6), ioread32(ioaddr + CSR12));
 
 			/* now the following actually writes out the
 			 * new csr6 values
@@ -282,9 +283,9 @@ void pnic2_lnk_change(struct net_device
                         return;
 
 	        } else {
-	                printk(KERN_INFO "%s: Autonegotiation failed, "
-                                    "using %s, link beat status %4.4x.\n",
-				     dev->name, medianame[dev->if_port], csr12);
+	                dev_info(&dev->dev,
+				 "Autonegotiation failed, using %s, link beat status %04x\n",
+				 medianame[dev->if_port], csr12);
 
                         /* remember to turn off bit 7 - autonegotiate
                          * enable so we don't forget
@@ -339,9 +340,9 @@ void pnic2_lnk_change(struct net_device
 	        /* we are at 100mb and a potential link change occurred */
 
 		if (tulip_debug > 1)
-			printk(KERN_INFO"%s: PNIC2 %s link beat %s.\n",
-				   dev->name, medianame[dev->if_port],
-				   (csr12 & 2) ? "failed" : "good");
+			dev_info(&dev->dev, "PNIC2 %s link beat %s\n",
+				 medianame[dev->if_port],
+				 (csr12 & 2) ? "failed" : "good");
 
                 /* check 100 link beat */
 
@@ -364,9 +365,9 @@ void pnic2_lnk_change(struct net_device
 	        /* we are at 10mb and a potential link change occurred */
 
 		if (tulip_debug > 1)
-			printk(KERN_INFO"%s: PNIC2 %s link beat %s.\n",
-				   dev->name, medianame[dev->if_port],
-				   (csr12 & 4) ? "failed" : "good");
+			dev_info(&dev->dev, "PNIC2 %s link beat %s\n",
+				 medianame[dev->if_port],
+				 (csr12 & 4) ? "failed" : "good");
 
 
                 tp->nway = 0;
@@ -385,7 +386,7 @@ void pnic2_lnk_change(struct net_device
 
 
 	if (tulip_debug > 1)
-		printk(KERN_INFO"%s: PNIC2 Link Change Default?\n",dev->name);
+		dev_info(&dev->dev, "PNIC2 Link Change Default?\n");
 
         /* if all else fails default to trying 10baseT-HD */
 	dev->if_port = 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tulip/pnic.c linux-libre-2.6.34-gnu1/drivers/net/tulip/pnic.c
--- linux-libre-2.6.33-gnu1/drivers/net/tulip/pnic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tulip/pnic.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,8 +40,8 @@ void pnic_do_nway(struct net_device *dev
 			new_csr6 |= 0x00000200;
 		}
 		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: PNIC autonegotiated status %8.8x, %s.\n",
-				   dev->name, phy_reg, medianame[dev->if_port]);
+			printk(KERN_DEBUG "%s: PNIC autonegotiated status %08x, %s\n",
+			       dev->name, phy_reg, medianame[dev->if_port]);
 		if (tp->csr6 != new_csr6) {
 			tp->csr6 = new_csr6;
 			/* Restart Tx */
@@ -58,8 +58,8 @@ void pnic_lnk_change(struct net_device *
 	int phy_reg = ioread32(ioaddr + 0xB8);
 
 	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: PNIC link changed state %8.8x, CSR5 %8.8x.\n",
-			   dev->name, phy_reg, csr5);
+		printk(KERN_DEBUG "%s: PNIC link changed state %08x, CSR5 %08x\n",
+		       dev->name, phy_reg, csr5);
 	if (ioread32(ioaddr + CSR5) & TPLnkFail) {
 		iowrite32((ioread32(ioaddr + CSR7) & ~TPLnkFail) | TPLnkPass, ioaddr + CSR7);
 		/* If we use an external MII, then we mustn't use the
@@ -114,9 +114,8 @@ void pnic_timer(unsigned long data)
 		int csr5 = ioread32(ioaddr + CSR5);
 
 		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: PNIC timer PHY status %8.8x, %s "
-				   "CSR5 %8.8x.\n",
-				   dev->name, phy_reg, medianame[dev->if_port], csr5);
+			printk(KERN_DEBUG "%s: PNIC timer PHY status %08x, %s CSR5 %08x\n",
+			       dev->name, phy_reg, medianame[dev->if_port], csr5);
 		if (phy_reg & 0x04000000) {	/* Remote link fault */
 			iowrite32(0x0201F078, ioaddr + 0xB8);
 			next_tick = 1*HZ;
@@ -126,10 +125,11 @@ void pnic_timer(unsigned long data)
 			next_tick = 60*HZ;
 		} else if (csr5 & TPLnkFail) { /* 100baseTx link beat */
 			if (tulip_debug > 1)
-				printk(KERN_DEBUG "%s: %s link beat failed, CSR12 %4.4x, "
-					   "CSR5 %8.8x, PHY %3.3x.\n",
-					   dev->name, medianame[dev->if_port], csr12,
-					   ioread32(ioaddr + CSR5), ioread32(ioaddr + 0xB8));
+				printk(KERN_DEBUG "%s: %s link beat failed, CSR12 %04x, CSR5 %08x, PHY %03x\n",
+				       dev->name, medianame[dev->if_port],
+				       csr12,
+				       ioread32(ioaddr + CSR5),
+				       ioread32(ioaddr + 0xB8));
 			next_tick = 3*HZ;
 			if (tp->medialock) {
 			} else if (tp->nwayset  &&  (dev->if_port & 1)) {
@@ -151,10 +151,11 @@ void pnic_timer(unsigned long data)
 				tulip_restart_rxtx(tp);
 				dev->trans_start = jiffies;
 				if (tulip_debug > 1)
-					printk(KERN_INFO "%s: Changing PNIC configuration to %s "
-						   "%s-duplex, CSR6 %8.8x.\n",
-						   dev->name, medianame[dev->if_port],
-						   tp->full_duplex ? "full" : "half", new_csr6);
+					dev_info(&dev->dev,
+						 "Changing PNIC configuration to %s %s-duplex, CSR6 %08x\n",
+						 medianame[dev->if_port],
+						 tp->full_duplex ? "full" : "half",
+						 new_csr6);
 			}
 		}
 	}
@@ -162,7 +163,7 @@ too_good_connection:
 	mod_timer(&tp->timer, RUN_AT(next_tick));
 	if(!ioread32(ioaddr + CSR7)) {
 		if (tulip_debug > 1)
-			printk(KERN_INFO "%s: sw timer wakeup.\n", dev->name);
+			dev_info(&dev->dev, "sw timer wakeup\n");
 		disable_irq(dev->irq);
 		tulip_refill_rx(dev);
 		enable_irq(dev->irq);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tulip/timer.c linux-libre-2.6.34-gnu1/drivers/net/tulip/timer.c
--- linux-libre-2.6.33-gnu1/drivers/net/tulip/timer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tulip/timer.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,11 +28,11 @@ void tulip_media_task(struct work_struct
 	unsigned long flags;
 
 	if (tulip_debug > 2) {
-		printk(KERN_DEBUG "%s: Media selection tick, %s, status %8.8x mode"
-			   " %8.8x SIA %8.8x %8.8x %8.8x %8.8x.\n",
-			   dev->name, medianame[dev->if_port], ioread32(ioaddr + CSR5),
-			   ioread32(ioaddr + CSR6), csr12, ioread32(ioaddr + CSR13),
-			   ioread32(ioaddr + CSR14), ioread32(ioaddr + CSR15));
+		printk(KERN_DEBUG "%s: Media selection tick, %s, status %08x mode %08x SIA %08x %08x %08x %08x\n",
+		       dev->name, medianame[dev->if_port],
+		       ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR6),
+		       csr12, ioread32(ioaddr + CSR13),
+		       ioread32(ioaddr + CSR14), ioread32(ioaddr + CSR15));
 	}
 	switch (tp->chip_id) {
 	case DC21140:
@@ -48,9 +48,9 @@ void tulip_media_task(struct work_struct
 			   Assume this a generic MII or SYM transceiver. */
 			next_tick = 60*HZ;
 			if (tulip_debug > 2)
-				printk(KERN_DEBUG "%s: network media monitor CSR6 %8.8x "
-					   "CSR12 0x%2.2x.\n",
-					   dev->name, ioread32(ioaddr + CSR6), csr12 & 0xff);
+				printk(KERN_DEBUG "%s: network media monitor CSR6 %08x CSR12 0x%02x\n",
+				       dev->name,
+				       ioread32(ioaddr + CSR6), csr12 & 0xff);
 			break;
 		}
 		mleaf = &tp->mtable->mleaf[tp->cur_index];
@@ -62,9 +62,8 @@ void tulip_media_task(struct work_struct
 			s8 bitnum = p[offset];
 			if (p[offset+1] & 0x80) {
 				if (tulip_debug > 1)
-					printk(KERN_DEBUG"%s: Transceiver monitor tick "
-						   "CSR12=%#2.2x, no media sense.\n",
-						   dev->name, csr12);
+					printk(KERN_DEBUG "%s: Transceiver monitor tick CSR12=%#02x, no media sense\n",
+					       dev->name, csr12);
 				if (mleaf->type == 4) {
 					if (mleaf->media == 3 && (csr12 & 0x02))
 						goto select_next_media;
@@ -72,16 +71,16 @@ void tulip_media_task(struct work_struct
 				break;
 			}
 			if (tulip_debug > 2)
-				printk(KERN_DEBUG "%s: Transceiver monitor tick: CSR12=%#2.2x"
-					   " bit %d is %d, expecting %d.\n",
-					   dev->name, csr12, (bitnum >> 1) & 7,
-					   (csr12 & (1 << ((bitnum >> 1) & 7))) != 0,
-					   (bitnum >= 0));
+				printk(KERN_DEBUG "%s: Transceiver monitor tick: CSR12=%#02x bit %d is %d, expecting %d\n",
+				       dev->name, csr12, (bitnum >> 1) & 7,
+				       (csr12 & (1 << ((bitnum >> 1) & 7))) != 0,
+				       (bitnum >= 0));
 			/* Check that the specified bit has the proper value. */
 			if ((bitnum < 0) !=
 				((csr12 & (1 << ((bitnum >> 1) & 7))) != 0)) {
 				if (tulip_debug > 2)
-					printk(KERN_DEBUG "%s: Link beat detected for %s.\n", dev->name,
+					printk(KERN_DEBUG "%s: Link beat detected for %s\n",
+					       dev->name,
 					       medianame[mleaf->media & MEDIA_MASK]);
 				if ((p[2] & 0x61) == 0x01)	/* Bogus Znyx board. */
 					goto actually_mii;
@@ -100,9 +99,9 @@ void tulip_media_task(struct work_struct
 			if (tulip_media_cap[dev->if_port] & MediaIsFD)
 				goto select_next_media; /* Skip FD entries. */
 			if (tulip_debug > 1)
-				printk(KERN_DEBUG "%s: No link beat on media %s,"
-				       " trying transceiver type %s.\n",
-				       dev->name, medianame[mleaf->media & MEDIA_MASK],
+				printk(KERN_DEBUG "%s: No link beat on media %s, trying transceiver type %s\n",
+				       dev->name,
+				       medianame[mleaf->media & MEDIA_MASK],
 				       medianame[tp->mtable->mleaf[tp->cur_index].media]);
 			tulip_select_media(dev, 0);
 			/* Restart the transmit process. */
@@ -151,8 +150,8 @@ void mxic_timer(unsigned long data)
 	int next_tick = 60*HZ;
 
 	if (tulip_debug > 3) {
-		printk(KERN_INFO"%s: MXIC negotiation status %8.8x.\n", dev->name,
-			   ioread32(ioaddr + CSR12));
+		dev_info(&dev->dev, "MXIC negotiation status %08x\n",
+			 ioread32(ioaddr + CSR12));
 	}
 	if (next_tick) {
 		mod_timer(&tp->timer, RUN_AT(next_tick));
@@ -167,11 +166,10 @@ void comet_timer(unsigned long data)
 	int next_tick = 60*HZ;
 
 	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: Comet link status %4.4x partner capability "
-			   "%4.4x.\n",
-			   dev->name,
-			   tulip_mdio_read(dev, tp->phys[0], 1),
-			   tulip_mdio_read(dev, tp->phys[0], 5));
+		printk(KERN_DEBUG "%s: Comet link status %04x partner capability %04x\n",
+		       dev->name,
+		       tulip_mdio_read(dev, tp->phys[0], 1),
+		       tulip_mdio_read(dev, tp->phys[0], 5));
 	/* mod_timer synchronizes us with potential add_timer calls
 	 * from interrupts.
 	 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tulip/tulip_core.c linux-libre-2.6.34-gnu1/drivers/net/tulip/tulip_core.c
--- linux-libre-2.6.33-gnu1/drivers/net/tulip/tulip_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tulip/tulip_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include "tulip.h"
 #include <linux/init.h>
 #include <linux/etherdevice.h>
@@ -41,7 +42,6 @@
 static char version[] __devinitdata =
 	"Linux Tulip driver version " DRV_VERSION " (" DRV_RELDATE ")\n";
 
-
 /* A few user-configurable values. */
 
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
@@ -211,7 +211,7 @@ struct tulip_chip_table tulip_tbl[] = {
 };
 
 
-static struct pci_device_id tulip_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(tulip_pci_tbl) = {
 	{ 0x1011, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21140 },
 	{ 0x1011, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21143 },
 	{ 0x11AD, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, LC82C168 },
@@ -326,7 +326,8 @@ static void tulip_up(struct net_device *
 	udelay(100);
 
 	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: tulip_up(), irq==%d.\n", dev->name, dev->irq);
+		printk(KERN_DEBUG "%s: tulip_up(), irq==%d\n",
+		       dev->name, dev->irq);
 
 	iowrite32(tp->rx_ring_dma, ioaddr + CSR3);
 	iowrite32(tp->tx_ring_dma, ioaddr + CSR4);
@@ -387,8 +388,9 @@ static void tulip_up(struct net_device *
 			(dev->if_port == 12 ? 0 : dev->if_port);
 		for (i = 0; i < tp->mtable->leafcount; i++)
 			if (tp->mtable->mleaf[i].media == looking_for) {
-				printk(KERN_INFO "%s: Using user-specified media %s.\n",
-					   dev->name, medianame[dev->if_port]);
+				dev_info(&dev->dev,
+					 "Using user-specified media %s\n",
+					 medianame[dev->if_port]);
 				goto media_picked;
 			}
 	}
@@ -396,8 +398,9 @@ static void tulip_up(struct net_device *
 		int looking_for = tp->mtable->defaultmedia & MEDIA_MASK;
 		for (i = 0; i < tp->mtable->leafcount; i++)
 			if (tp->mtable->mleaf[i].media == looking_for) {
-				printk(KERN_INFO "%s: Using EEPROM-set media %s.\n",
-					   dev->name, medianame[looking_for]);
+				dev_info(&dev->dev,
+					 "Using EEPROM-set media %s\n",
+					 medianame[looking_for]);
 				goto media_picked;
 			}
 	}
@@ -424,9 +427,10 @@ media_picked:
 		if (tp->mii_cnt) {
 			tulip_select_media(dev, 1);
 			if (tulip_debug > 1)
-				printk(KERN_INFO "%s: Using MII transceiver %d, status "
-					   "%4.4x.\n",
-					   dev->name, tp->phys[0], tulip_mdio_read(dev, tp->phys[0], 1));
+				dev_info(&dev->dev,
+					 "Using MII transceiver %d, status %04x\n",
+					 tp->phys[0],
+					 tulip_mdio_read(dev, tp->phys[0], 1));
 			iowrite32(csr6_mask_defstate, ioaddr + CSR6);
 			tp->csr6 = csr6_mask_hdcap;
 			dev->if_port = 11;
@@ -490,9 +494,10 @@ media_picked:
 	iowrite32(0, ioaddr + CSR2);		/* Rx poll demand */
 
 	if (tulip_debug > 2) {
-		printk(KERN_DEBUG "%s: Done tulip_up(), CSR0 %8.8x, CSR5 %8.8x CSR6 %8.8x.\n",
-			   dev->name, ioread32(ioaddr + CSR0), ioread32(ioaddr + CSR5),
-			   ioread32(ioaddr + CSR6));
+		printk(KERN_DEBUG "%s: Done tulip_up(), CSR0 %08x, CSR5 %08x CSR6 %08x\n",
+		       dev->name, ioread32(ioaddr + CSR0),
+		       ioread32(ioaddr + CSR5),
+		       ioread32(ioaddr + CSR6));
 	}
 
 	/* Set the timer to switch to check for link beat and perhaps switch
@@ -540,27 +545,30 @@ static void tulip_tx_timeout(struct net_
 	if (tulip_media_cap[dev->if_port] & MediaIsMII) {
 		/* Do nothing -- the media monitor should handle this. */
 		if (tulip_debug > 1)
-			printk(KERN_WARNING "%s: Transmit timeout using MII device.\n",
-				   dev->name);
+			dev_warn(&dev->dev,
+				 "Transmit timeout using MII device\n");
 	} else if (tp->chip_id == DC21140 || tp->chip_id == DC21142 ||
 		   tp->chip_id == MX98713 || tp->chip_id == COMPEX9881 ||
 		   tp->chip_id == DM910X) {
-		printk(KERN_WARNING "%s: 21140 transmit timed out, status %8.8x, "
-			   "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n",
-			   dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12),
-			   ioread32(ioaddr + CSR13), ioread32(ioaddr + CSR14), ioread32(ioaddr + CSR15));
+		dev_warn(&dev->dev,
+			 "21140 transmit timed out, status %08x, SIA %08x %08x %08x %08x, resetting...\n",
+			 ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12),
+			 ioread32(ioaddr + CSR13), ioread32(ioaddr + CSR14),
+			 ioread32(ioaddr + CSR15));
 		tp->timeout_recovery = 1;
 		schedule_work(&tp->media_work);
 		goto out_unlock;
 	} else if (tp->chip_id == PNIC2) {
-		printk(KERN_WARNING "%s: PNIC2 transmit timed out, status %8.8x, "
-		       "CSR6/7 %8.8x / %8.8x CSR12 %8.8x, resetting...\n",
-		       dev->name, (int)ioread32(ioaddr + CSR5), (int)ioread32(ioaddr + CSR6),
-		       (int)ioread32(ioaddr + CSR7), (int)ioread32(ioaddr + CSR12));
+		dev_warn(&dev->dev,
+			 "PNIC2 transmit timed out, status %08x, CSR6/7 %08x / %08x CSR12 %08x, resetting...\n",
+			 (int)ioread32(ioaddr + CSR5),
+			 (int)ioread32(ioaddr + CSR6),
+			 (int)ioread32(ioaddr + CSR7),
+			 (int)ioread32(ioaddr + CSR12));
 	} else {
-		printk(KERN_WARNING "%s: Transmit timed out, status %8.8x, CSR12 "
-			   "%8.8x, resetting...\n",
-			   dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12));
+		dev_warn(&dev->dev,
+			 "Transmit timed out, status %08x, CSR12 %08x, resetting...\n",
+			 ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12));
 		dev->if_port = 0;
 	}
 
@@ -570,26 +578,26 @@ static void tulip_tx_timeout(struct net_
 		for (i = 0; i < RX_RING_SIZE; i++) {
 			u8 *buf = (u8 *)(tp->rx_ring[i].buffer1);
 			int j;
-			printk(KERN_DEBUG "%2d: %8.8x %8.8x %8.8x %8.8x  "
-				   "%2.2x %2.2x %2.2x.\n",
-				   i, (unsigned int)tp->rx_ring[i].status,
-				   (unsigned int)tp->rx_ring[i].length,
-				   (unsigned int)tp->rx_ring[i].buffer1,
-				   (unsigned int)tp->rx_ring[i].buffer2,
-				   buf[0], buf[1], buf[2]);
+			printk(KERN_DEBUG
+			       "%2d: %08x %08x %08x %08x  %02x %02x %02x\n",
+			       i,
+			       (unsigned int)tp->rx_ring[i].status,
+			       (unsigned int)tp->rx_ring[i].length,
+			       (unsigned int)tp->rx_ring[i].buffer1,
+			       (unsigned int)tp->rx_ring[i].buffer2,
+			       buf[0], buf[1], buf[2]);
 			for (j = 0; buf[j] != 0xee && j < 1600; j++)
 				if (j < 100)
-					printk(KERN_CONT " %2.2x", buf[j]);
-			printk(KERN_CONT " j=%d.\n", j);
+					pr_cont(" %02x", buf[j]);
+			pr_cont(" j=%d\n", j);
 		}
-		printk(KERN_DEBUG "  Rx ring %8.8x: ", (int)tp->rx_ring);
+		printk(KERN_DEBUG "  Rx ring %08x: ", (int)tp->rx_ring);
 		for (i = 0; i < RX_RING_SIZE; i++)
-			printk(KERN_CONT " %8.8x",
-			       (unsigned int)tp->rx_ring[i].status);
-		printk(KERN_DEBUG "  Tx ring %8.8x: ", (int)tp->tx_ring);
+			pr_cont(" %08x", (unsigned int)tp->rx_ring[i].status);
+		printk(KERN_DEBUG "  Tx ring %08x: ", (int)tp->tx_ring);
 		for (i = 0; i < TX_RING_SIZE; i++)
-			printk(KERN_CONT " %8.8x", (unsigned int)tp->tx_ring[i].status);
-		printk(KERN_CONT "\n");
+			pr_cont(" %08x", (unsigned int)tp->tx_ring[i].status);
+		pr_cont("\n");
 	}
 #endif
 
@@ -832,8 +840,9 @@ static int tulip_close (struct net_devic
 	tulip_down (dev);
 
 	if (tulip_debug > 1)
-		printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
-			dev->name, ioread32 (ioaddr + CSR5));
+		dev_printk(KERN_DEBUG, &dev->dev,
+			   "Shutting down ethercard, status was %02x\n",
+			   ioread32 (ioaddr + CSR5));
 
 	free_irq (dev->irq, dev);
 
@@ -989,12 +998,10 @@ static void build_setup_frame_hash(u16 *
 	memset(hash_table, 0, sizeof(hash_table));
 	set_bit_le(255, hash_table); 			/* Broadcast entry */
 	/* This should work on big-endian machines as well. */
-	for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-	     i++, mclist = mclist->next) {
+	netdev_for_each_mc_addr(mclist, dev) {
 		int index = ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x1ff;
 
 		set_bit_le(index, hash_table);
-
 	}
 	for (i = 0; i < 32; i++) {
 		*setup_frm++ = hash_table[i];
@@ -1013,20 +1020,18 @@ static void build_setup_frame_perfect(u1
 {
 	struct tulip_private *tp = netdev_priv(dev);
 	struct dev_mc_list *mclist;
-	int i;
 	u16 *eaddrs;
 
 	/* We have <= 14 addresses so we can use the wonderful
 	   16 address perfect filtering of the Tulip. */
-	for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
-	     i++, mclist = mclist->next) {
+	netdev_for_each_mc_addr(mclist, dev) {
 		eaddrs = (u16 *)mclist->dmi_addr;
 		*setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++;
 		*setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++;
 		*setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++;
 	}
 	/* Fill the unused entries with the broadcast address. */
-	memset(setup_frm, 0xff, (15-i)*12);
+	memset(setup_frm, 0xff, (15 - netdev_mc_count(dev)) * 12);
 	setup_frm = &tp->setup_frame[15*6];
 
 	/* Fill the final entry with our physical address. */
@@ -1049,7 +1054,8 @@ static void set_rx_mode(struct net_devic
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		tp->csr6 |= AcceptAllMulticast | AcceptAllPhys;
 		csr6 |= AcceptAllMulticast | AcceptAllPhys;
-	} else if ((dev->mc_count > 1000)  ||  (dev->flags & IFF_ALLMULTI)) {
+	} else if ((netdev_mc_count(dev) > 1000) ||
+		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter well -- accept all multicasts. */
 		tp->csr6 |= AcceptAllMulticast;
 		csr6 |= AcceptAllMulticast;
@@ -1057,15 +1063,14 @@ static void set_rx_mode(struct net_devic
 		/* Some work-alikes have only a 64-entry hash filter table. */
 		/* Should verify correctness on big-endian/__powerpc__ */
 		struct dev_mc_list *mclist;
-		int i;
-		if (dev->mc_count > 64) {		/* Arbitrary non-effective limit. */
+		if (netdev_mc_count(dev) > 64) {
+			/* Arbitrary non-effective limit. */
 			tp->csr6 |= AcceptAllMulticast;
 			csr6 |= AcceptAllMulticast;
 		} else {
 			u32 mc_filter[2] = {0, 0};		 /* Multicast hash filter */
 			int filterbit;
-			for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-				 i++, mclist = mclist->next) {
+			netdev_for_each_mc_addr(mclist, dev) {
 				if (tp->flags & COMET_MAC_ADDR)
 					filterbit = ether_crc_le(ETH_ALEN, mclist->dmi_addr);
 				else
@@ -1073,10 +1078,10 @@ static void set_rx_mode(struct net_devic
 				filterbit &= 0x3f;
 				mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
 				if (tulip_debug > 2)
-					printk(KERN_INFO "%s: Added filter for %pM"
-					       "  %8.8x bit %d.\n",
-					       dev->name, mclist->dmi_addr,
-					       ether_crc(ETH_ALEN, mclist->dmi_addr), filterbit);
+					dev_info(&dev->dev,
+						 "Added filter for %pM  %08x bit %d\n",
+						 mclist->dmi_addr,
+						 ether_crc(ETH_ALEN, mclist->dmi_addr), filterbit);
 			}
 			if (mc_filter[0] == tp->mc_filter[0]  &&
 				mc_filter[1] == tp->mc_filter[1])
@@ -1099,7 +1104,8 @@ static void set_rx_mode(struct net_devic
 
 		/* Note that only the low-address shortword of setup_frame is valid!
 		   The values are doubled for big-endian architectures. */
-		if (dev->mc_count > 14) { /* Must use a multicast hash table. */
+		if (netdev_mc_count(dev) > 14) {
+			/* Must use a multicast hash table. */
 			build_setup_frame_hash(tp->setup_frame, dev);
 			tx_flags = 0x08400000 | 192;
 		} else {
@@ -1288,9 +1294,8 @@ static int __devinit tulip_init_one (str
 	unsigned int force_csr0 = 0;
 
 #ifndef MODULE
-	static int did_version;		/* Already printed version info. */
-	if (tulip_debug > 0  &&  did_version++ == 0)
-		printk (KERN_INFO "%s", version);
+	if (tulip_debug > 0)
+		printk_once(KERN_INFO "%s", version);
 #endif
 
 	board_idx++;
@@ -1301,7 +1306,7 @@ static int __devinit tulip_init_one (str
 	 */
 
         if (pdev->subsystem_vendor == PCI_VENDOR_ID_LMC) {
-		printk (KERN_ERR PFX "skipping LMC card.\n");
+		pr_err(PFX "skipping LMC card\n");
 		return -ENODEV;
 	}
 
@@ -1317,15 +1322,13 @@ static int __devinit tulip_init_one (str
 
 		if (pdev->vendor == 0x1282 && pdev->device == 0x9100 &&
 		    pdev->revision < 0x30) {
-			printk(KERN_INFO PFX
-			       "skipping early DM9100 with Crc bug (use dmfe)\n");
+			pr_info(PFX "skipping early DM9100 with Crc bug (use dmfe)\n");
 			return -ENODEV;
 		}
 
 		dp = pci_device_to_OF_node(pdev);
 		if (!(dp && of_get_property(dp, "local-mac-address", NULL))) {
-			printk(KERN_INFO PFX
-			       "skipping DM910x expansion card (use dmfe)\n");
+			pr_info(PFX "skipping DM910x expansion card (use dmfe)\n");
 			return -ENODEV;
 		}
 	}
@@ -1372,9 +1375,8 @@ static int __devinit tulip_init_one (str
 
 	i = pci_enable_device(pdev);
 	if (i) {
-		printk (KERN_ERR PFX
-			"Cannot enable tulip board #%d, aborting\n",
-			board_idx);
+		pr_err(PFX "Cannot enable tulip board #%d, aborting\n",
+		       board_idx);
 		return i;
 	}
 
@@ -1383,22 +1385,22 @@ static int __devinit tulip_init_one (str
 	/* alloc_etherdev ensures aligned and zeroed private structures */
 	dev = alloc_etherdev (sizeof (*tp));
 	if (!dev) {
-		printk (KERN_ERR PFX "ether device alloc failed, aborting\n");
+		pr_err(PFX "ether device alloc failed, aborting\n");
 		return -ENOMEM;
 	}
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
 	if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) {
-		printk (KERN_ERR PFX "%s: I/O region (0x%llx@0x%llx) too small, "
-			"aborting\n", pci_name(pdev),
-			(unsigned long long)pci_resource_len (pdev, 0),
-			(unsigned long long)pci_resource_start (pdev, 0));
+		pr_err(PFX "%s: I/O region (0x%llx@0x%llx) too small, aborting\n",
+		       pci_name(pdev),
+		       (unsigned long long)pci_resource_len (pdev, 0),
+		       (unsigned long long)pci_resource_start (pdev, 0));
 		goto err_out_free_netdev;
 	}
 
 	/* grab all resources from both PIO and MMIO regions, as we
 	 * don't want anyone else messing around with our hardware */
-	if (pci_request_regions (pdev, "tulip"))
+	if (pci_request_regions (pdev, DRV_NAME))
 		goto err_out_free_netdev;
 
 	ioaddr =  pci_iomap(pdev, TULIP_BAR, tulip_tbl[chip_idx].io_size);
@@ -1611,8 +1613,8 @@ static int __devinit tulip_init_one (str
 	if (dev->mem_start & MEDIA_MASK)
 		tp->default_port = dev->mem_start & MEDIA_MASK;
 	if (tp->default_port) {
-		printk(KERN_INFO "tulip%d: Transceiver selection forced to %s.\n",
-		       board_idx, medianame[tp->default_port & MEDIA_MASK]);
+		pr_info(DRV_NAME "%d: Transceiver selection forced to %s\n",
+			board_idx, medianame[tp->default_port & MEDIA_MASK]);
 		tp->medialock = 1;
 		if (tulip_media_cap[tp->default_port] & MediaAlwaysFD)
 			tp->full_duplex = 1;
@@ -1627,7 +1629,7 @@ static int __devinit tulip_init_one (str
 	}
 
 	if (tp->flags & HAS_MEDIA_TABLE) {
-		sprintf(dev->name, "tulip%d", board_idx);	/* hack */
+		sprintf(dev->name, DRV_NAME "%d", board_idx);	/* hack */
 		tulip_parse_eeprom(dev);
 		strcpy(dev->name, "eth%d");			/* un-hack */
 	}
@@ -1663,20 +1665,18 @@ static int __devinit tulip_init_one (str
 	if (register_netdev(dev))
 		goto err_out_free_ring;
 
-	printk(KERN_INFO "%s: %s rev %d at "
+	pci_set_drvdata(pdev, dev);
+
+	dev_info(&dev->dev,
 #ifdef CONFIG_TULIP_MMIO
-		"MMIO"
+		 "%s rev %d at MMIO %#llx,%s %pM, IRQ %d\n",
 #else
-		"Port"
+		 "%s rev %d at Port %#llx,%s %pM, IRQ %d\n",
 #endif
-		" %#llx,", dev->name, chip_name, pdev->revision,
-		(unsigned long long) pci_resource_start(pdev, TULIP_BAR));
-	pci_set_drvdata(pdev, dev);
-
-	if (eeprom_missing)
-		printk(" EEPROM not present,");
-	printk(" %pM", dev->dev_addr);
-	printk(", IRQ %d.\n", irq);
+		 chip_name, pdev->revision,
+		 (unsigned long long)pci_resource_start(pdev, TULIP_BAR),
+		 eeprom_missing ? " EEPROM not present," : "",
+		 dev->dev_addr, irq);
 
         if (tp->chip_id == PNIC2)
 		tp->link_change = pnic2_lnk_change;
@@ -1799,12 +1799,12 @@ static int tulip_resume(struct pci_dev *
 		return 0;
 
 	if ((retval = pci_enable_device(pdev))) {
-		printk (KERN_ERR "tulip: pci_enable_device failed in resume\n");
+		pr_err(PFX "pci_enable_device failed in resume\n");
 		return retval;
 	}
 
 	if ((retval = request_irq(dev->irq, tulip_interrupt, IRQF_SHARED, dev->name, dev))) {
-		printk (KERN_ERR "tulip: request_irq failed in resume\n");
+		pr_err(PFX "request_irq failed in resume\n");
 		return retval;
 	}
 
@@ -1874,7 +1874,7 @@ static struct pci_driver tulip_driver =
 static int __init tulip_init (void)
 {
 #ifdef MODULE
-	printk (KERN_INFO "%s", version);
+	pr_info("%s", version);
 #endif
 
 	/* copy module parms into globals */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tulip/uli526x.c linux-libre-2.6.34-gnu1/drivers/net/tulip/uli526x.c
--- linux-libre-2.6.33-gnu1/drivers/net/tulip/uli526x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tulip/uli526x.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,8 @@
 
 */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #define DRV_NAME	"uli526x"
 #define DRV_VERSION	"0.9.3"
 #define DRV_RELDATE	"2005-7-29"
@@ -23,7 +25,6 @@
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -82,9 +83,16 @@
 #define ULI526X_TX_TIMEOUT ((16*HZ)/2)	/* tx packet time-out time 8 s" */
 #define ULI526X_TX_KICK 	(4*HZ/2)	/* tx packet Kick-out time 2 s" */
 
-#define ULI526X_DBUG(dbug_now, msg, value) if (uli526x_debug || (dbug_now)) printk(KERN_ERR DRV_NAME ": %s %lx\n", (msg), (long) (value))
+#define ULI526X_DBUG(dbug_now, msg, value)			\
+do {								\
+	if (uli526x_debug || (dbug_now))			\
+		pr_err("%s %lx\n", (msg), (long) (value));	\
+} while (0)
 
-#define SHOW_MEDIA_TYPE(mode) printk(KERN_ERR DRV_NAME ": Change Speed to %sMhz %s duplex\n",mode & 1 ?"100":"10", mode & 4 ? "full":"half");
+#define SHOW_MEDIA_TYPE(mode)					\
+	pr_err("Change Speed to %sMhz %s duplex\n",		\
+	       mode & 1 ? "100" : "10",				\
+	       mode & 4 ? "full" : "half");
 
 
 /* CR9 definition: SROM/MII */
@@ -284,7 +292,7 @@ static int __devinit uli526x_init_one (s
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
-		printk(KERN_WARNING DRV_NAME ": 32-bit PCI DMA not available.\n");
+		pr_warning("32-bit PCI DMA not available\n");
 		err = -ENODEV;
 		goto err_out_free;
 	}
@@ -295,19 +303,19 @@ static int __devinit uli526x_init_one (s
 		goto err_out_free;
 
 	if (!pci_resource_start(pdev, 0)) {
-		printk(KERN_ERR DRV_NAME ": I/O base is zero\n");
+		pr_err("I/O base is zero\n");
 		err = -ENODEV;
 		goto err_out_disable;
 	}
 
 	if (pci_resource_len(pdev, 0) < (ULI526X_IO_SIZE) ) {
-		printk(KERN_ERR DRV_NAME ": Allocated I/O size too small\n");
+		pr_err("Allocated I/O size too small\n");
 		err = -ENODEV;
 		goto err_out_disable;
 	}
 
 	if (pci_request_regions(pdev, DRV_NAME)) {
-		printk(KERN_ERR DRV_NAME ": Failed to request PCI regions\n");
+		pr_err("Failed to request PCI regions\n");
 		err = -ENODEV;
 		goto err_out_disable;
 	}
@@ -382,9 +390,9 @@ static int __devinit uli526x_init_one (s
 	if (err)
 		goto err_out_res;
 
-	printk(KERN_INFO "%s: ULi M%04lx at pci%s, %pM, irq %d.\n",
-	       dev->name,ent->driver_data >> 16,pci_name(pdev),
-	       dev->dev_addr, dev->irq);
+	dev_info(&dev->dev, "ULi M%04lx at pci%s, %pM, irq %d\n",
+		 ent->driver_data >> 16, pci_name(pdev),
+		 dev->dev_addr, dev->irq);
 
 	pci_set_master(pdev);
 
@@ -516,7 +524,7 @@ static void uli526x_init(struct net_devi
 		}
 	}
 	if(phy_tmp == 32)
-		printk(KERN_WARNING "Can not find the phy address!!!");
+		pr_warning("Can not find the phy address!!!");
 	/* Parser SROM and media mode */
 	db->media_mode = uli526x_media_mode;
 
@@ -548,7 +556,7 @@ static void uli526x_init(struct net_devi
 	update_cr6(db->cr6_data, ioaddr);
 
 	/* Send setup frame */
-	send_filter_frame(dev, dev->mc_count);	/* M5261/M5263 */
+	send_filter_frame(dev, netdev_mc_count(dev));	/* M5261/M5263 */
 
 	/* Init CR7, interrupt active bit */
 	db->cr7_data = CR7_DEFAULT;
@@ -582,7 +590,7 @@ static netdev_tx_t uli526x_start_xmit(st
 
 	/* Too large packet check */
 	if (skb->len > MAX_PACKET_SIZE) {
-		printk(KERN_ERR DRV_NAME ": big packet = %d\n", (u16)skb->len);
+		pr_err("big packet = %d\n", (u16)skb->len);
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
 	}
@@ -592,7 +600,7 @@ static netdev_tx_t uli526x_start_xmit(st
 	/* No Tx resource check, it never happen nromally */
 	if (db->tx_packet_cnt >= TX_FREE_DESC_CNT) {
 		spin_unlock_irqrestore(&db->lock, flags);
-		printk(KERN_ERR DRV_NAME ": No Tx resource %ld\n", db->tx_packet_cnt);
+		pr_err("No Tx resource %ld\n", db->tx_packet_cnt);
 		return NETDEV_TX_BUSY;
 	}
 
@@ -842,13 +850,15 @@ static void uli526x_rx_packet(struct net
 
 			if ( !(rdes0 & 0x8000) ||
 				((db->cr6_data & CR6_PM) && (rxlen>6)) ) {
+				struct sk_buff *new_skb = NULL;
+
 				skb = rxptr->rx_skb_ptr;
 
 				/* Good packet, send to upper layer */
 				/* Shorst packet used new SKB */
-				if ( (rxlen < RX_COPY_SIZE) &&
-					( (skb = dev_alloc_skb(rxlen + 2) )
-					!= NULL) ) {
+				if ((rxlen < RX_COPY_SIZE) &&
+				    (((new_skb = dev_alloc_skb(rxlen + 2)) != NULL))) {
+					skb = new_skb;
 					/* size less than COPY_SIZE, allocate a rxlen SKB */
 					skb_reserve(skb, 2); /* 16byte align */
 					memcpy(skb_put(skb, rxlen),
@@ -897,16 +907,18 @@ static void uli526x_set_filter_mode(stru
 		return;
 	}
 
-	if (dev->flags & IFF_ALLMULTI || dev->mc_count > ULI5261_MAX_MULTICAST) {
-		ULI526X_DBUG(0, "Pass all multicast address", dev->mc_count);
+	if (dev->flags & IFF_ALLMULTI ||
+	    netdev_mc_count(dev) > ULI5261_MAX_MULTICAST) {
+		ULI526X_DBUG(0, "Pass all multicast address",
+			     netdev_mc_count(dev));
 		db->cr6_data &= ~(CR6_PM | CR6_PBF);
 		db->cr6_data |= CR6_PAM;
 		spin_unlock_irqrestore(&db->lock, flags);
 		return;
 	}
 
-	ULI526X_DBUG(0, "Set multicast address", dev->mc_count);
-	send_filter_frame(dev, dev->mc_count); 	/* M5261/M5263 */
+	ULI526X_DBUG(0, "Set multicast address", netdev_mc_count(dev));
+	send_filter_frame(dev, netdev_mc_count(dev)); 	/* M5261/M5263 */
 	spin_unlock_irqrestore(&db->lock, flags);
 }
 
@@ -1058,7 +1070,7 @@ static void uli526x_timer(unsigned long
 		/* Link Failed */
 		ULI526X_DBUG(0, "Link Failed", tmp_cr12);
 		netif_carrier_off(dev);
-		printk(KERN_INFO "uli526x: %s NIC Link is Down\n",dev->name);
+		pr_info("%s NIC Link is Down\n",dev->name);
 		db->link_failed = 1;
 
 		/* For Force 10/100M Half/Full mode: Enable Auto-Nego mode */
@@ -1090,11 +1102,11 @@ static void uli526x_timer(unsigned long
 				}
 				if(db->op_mode==ULI526X_10MFD || db->op_mode==ULI526X_100MFD)
 				{
-					printk(KERN_INFO "uli526x: %s NIC Link is Up %d Mbps Full duplex\n",dev->name,TmpSpeed);
+					pr_info("%s NIC Link is Up %d Mbps Full duplex\n",dev->name,TmpSpeed);
 				}
 				else
 				{
-					printk(KERN_INFO "uli526x: %s NIC Link is Up %d Mbps Half duplex\n",dev->name,TmpSpeed);
+					pr_info("%s NIC Link is Up %d Mbps Half duplex\n",dev->name,TmpSpeed);
 				}
 				netif_carrier_on(dev);
 			}
@@ -1104,7 +1116,7 @@ static void uli526x_timer(unsigned long
 		{
 			if(db->init==1)
 			{
-				printk(KERN_INFO "uli526x: %s NIC Link is Down\n",dev->name);
+				pr_info("%s NIC Link is Down\n",dev->name);
 				netif_carrier_off(dev);
 			}
 		}
@@ -1230,8 +1242,7 @@ static int uli526x_resume(struct pci_dev
 
 	err = pci_set_power_state(pdev, PCI_D0);
 	if (err) {
-		printk(KERN_WARNING "%s: Could not put device into D0\n",
-			dev->name);
+		dev_warn(&dev->dev, "Could not put device into D0\n");
 		return err;
 	}
 
@@ -1405,14 +1416,14 @@ static void send_filter_frame(struct net
 	*suptr++ = 0xffff << FLT_SHIFT;
 
 	/* fit the multicast address */
-	for (mcptr = dev->mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
+	netdev_for_each_mc_addr(mcptr, dev) {
 		addrptr = (u16 *) mcptr->dmi_addr;
 		*suptr++ = addrptr[0] << FLT_SHIFT;
 		*suptr++ = addrptr[1] << FLT_SHIFT;
 		*suptr++ = addrptr[2] << FLT_SHIFT;
 	}
 
-	for (; i<14; i++) {
+	for (i = netdev_mc_count(dev); i < 14; i++) {
 		*suptr++ = 0xffff << FLT_SHIFT;
 		*suptr++ = 0xffff << FLT_SHIFT;
 		*suptr++ = 0xffff << FLT_SHIFT;
@@ -1432,7 +1443,7 @@ static void send_filter_frame(struct net
 		update_cr6(db->cr6_data, dev->base_addr);
 		dev->trans_start = jiffies;
 	} else
-		printk(KERN_ERR DRV_NAME ": No Tx resource - Send_filter_frame!\n");
+		pr_err("No Tx resource - Send_filter_frame!\n");
 }
 
 
@@ -1783,7 +1794,7 @@ static u16 phy_read_1bit(unsigned long i
 }
 
 
-static struct pci_device_id uli526x_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(uli526x_pci_tbl) = {
 	{ 0x10B9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_ULI5261_ID },
 	{ 0x10B9, 0x5263, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_ULI5263_ID },
 	{ 0, }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tulip/winbond-840.c linux-libre-2.6.34-gnu1/drivers/net/tulip/winbond-840.c
--- linux-libre-2.6.33-gnu1/drivers/net/tulip/winbond-840.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tulip/winbond-840.c	2010-05-16 17:17:36.000000000 -0400
@@ -114,7 +114,6 @@ static int full_duplex[MAX_UNITS] = {-1,
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
@@ -218,7 +217,7 @@ enum chip_capability_flags {
 	CanHaveMII=1, HasBrokenTx=2, AlwaysFDX=4, FDXOnNoMII=8,
 };
 
-static const struct pci_device_id w840_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(w840_pci_tbl) = {
 	{ 0x1050, 0x0840, PCI_ANY_ID, 0x8153,     0, 0, 0 },
 	{ 0x1050, 0x0840, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
 	{ 0x11f6, 0x2011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
@@ -376,8 +375,8 @@ static int __devinit w840_probe1 (struct
 	irq = pdev->irq;
 
 	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));
+		pr_warning("Winbond-840: Device %s disabled due to DMA limitations\n",
+			   pci_name(pdev));
 		return -EIO;
 	}
 	dev = alloc_etherdev(sizeof(*np));
@@ -422,8 +421,9 @@ static int __devinit w840_probe1 (struct
 		if (option & 0x200)
 			np->mii_if.full_duplex = 1;
 		if (option & 15)
-			printk(KERN_INFO "%s: ignoring user supplied media type %d",
-				dev->name, option & 15);
+			dev_info(&dev->dev,
+				 "ignoring user supplied media type %d",
+				 option & 15);
 	}
 	if (find_cnt < MAX_UNITS  &&  full_duplex[find_cnt] > 0)
 		np->mii_if.full_duplex = 1;
@@ -440,9 +440,8 @@ static int __devinit w840_probe1 (struct
 	if (i)
 		goto err_out_cleardev;
 
-	printk(KERN_INFO "%s: %s at %p, %pM, IRQ %d.\n",
-	       dev->name, pci_id_tbl[chip_idx].name, ioaddr,
-	       dev->dev_addr, irq);
+	dev_info(&dev->dev, "%s at %p, %pM, IRQ %d\n",
+		 pci_id_tbl[chip_idx].name, ioaddr, dev->dev_addr, irq);
 
 	if (np->drv_flags & CanHaveMII) {
 		int phy, phy_idx = 0;
@@ -453,16 +452,17 @@ static int __devinit w840_probe1 (struct
 				np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE);
 				np->mii = (mdio_read(dev, phy, MII_PHYSID1) << 16)+
 						mdio_read(dev, phy, MII_PHYSID2);
-				printk(KERN_INFO "%s: MII PHY %8.8xh found at address %d, status "
-					   "0x%4.4x advertising %4.4x.\n",
-					   dev->name, np->mii, phy, mii_status, np->mii_if.advertising);
+				dev_info(&dev->dev,
+					 "MII PHY %08xh found at address %d, status 0x%04x advertising %04x\n",
+					 np->mii, phy, mii_status,
+					 np->mii_if.advertising);
 			}
 		}
 		np->mii_cnt = phy_idx;
 		np->mii_if.phy_id = np->phys[0];
 		if (phy_idx == 0) {
-				printk(KERN_WARNING "%s: MII PHY not found -- this device may "
-					   "not operate correctly.\n", dev->name);
+			dev_warn(&dev->dev,
+				 "MII PHY not found -- this device may not operate correctly\n");
 		}
 	}
 
@@ -644,8 +644,8 @@ static int netdev_open(struct net_device
 		goto out_err;
 
 	if (debug > 1)
-		printk(KERN_DEBUG "%s: w89c840_open() irq %d.\n",
-			   dev->name, dev->irq);
+		printk(KERN_DEBUG "%s: w89c840_open() irq %d\n",
+		       dev->name, dev->irq);
 
 	if((i=alloc_ringdesc(dev)))
 		goto out_err;
@@ -657,7 +657,7 @@ static int netdev_open(struct net_device
 
 	netif_start_queue(dev);
 	if (debug > 2)
-		printk(KERN_DEBUG "%s: Done netdev_open().\n", dev->name);
+		printk(KERN_DEBUG "%s: Done netdev_open()\n", dev->name);
 
 	/* Set the timer to check for link beat. */
 	init_timer(&np->timer);
@@ -688,16 +688,18 @@ static int update_link(struct net_device
 	if (!(mii_reg & 0x4)) {
 		if (netif_carrier_ok(dev)) {
 			if (debug)
-				printk(KERN_INFO "%s: MII #%d reports no link. Disabling watchdog.\n",
-					dev->name, np->phys[0]);
+				dev_info(&dev->dev,
+					 "MII #%d reports no link. Disabling watchdog\n",
+					 np->phys[0]);
 			netif_carrier_off(dev);
 		}
 		return np->csr6;
 	}
 	if (!netif_carrier_ok(dev)) {
 		if (debug)
-			printk(KERN_INFO "%s: MII #%d link is back. Enabling watchdog.\n",
-				dev->name, np->phys[0]);
+			dev_info(&dev->dev,
+				 "MII #%d link is back. Enabling watchdog\n",
+				 np->phys[0]);
 		netif_carrier_on(dev);
 	}
 
@@ -729,9 +731,10 @@ static int update_link(struct net_device
 	if (fasteth)
 		result |= 0x20000000;
 	if (result != np->csr6 && debug)
-		printk(KERN_INFO "%s: Setting %dMBit-%s-duplex based on MII#%d\n",
-				 dev->name, fasteth ? 100 : 10,
-			   	duplex ? "full" : "half", np->phys[0]);
+		dev_info(&dev->dev,
+			 "Setting %dMBit-%s-duplex based on MII#%d\n",
+			 fasteth ? 100 : 10, duplex ? "full" : "half",
+			 np->phys[0]);
 	return result;
 }
 
@@ -763,8 +766,8 @@ static inline void update_csr6(struct ne
 
 		limit--;
 		if(!limit) {
-			printk(KERN_INFO "%s: couldn't stop rxtx, IntrStatus %xh.\n",
-					dev->name, csr5);
+			dev_info(&dev->dev,
+				 "couldn't stop rxtx, IntrStatus %xh\n", csr5);
 			break;
 		}
 		udelay(1);
@@ -783,10 +786,9 @@ static void netdev_timer(unsigned long d
 	void __iomem *ioaddr = np->base_addr;
 
 	if (debug > 2)
-		printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8x "
-			   "config %8.8x.\n",
-			   dev->name, ioread32(ioaddr + IntrStatus),
-			   ioread32(ioaddr + NetworkConfig));
+		printk(KERN_DEBUG "%s: Media selection timer tick, status %08x config %08x\n",
+		       dev->name, ioread32(ioaddr + IntrStatus),
+		       ioread32(ioaddr + NetworkConfig));
 	spin_lock_irq(&np->lock);
 	update_csr6(dev, update_link(dev));
 	spin_unlock_irq(&np->lock);
@@ -899,8 +901,8 @@ static void init_registers(struct net_de
 	/* When not a module we can work around broken '486 PCI boards. */
 	if (boot_cpu_data.x86 <= 4) {
 		i |= 0x4800;
-		printk(KERN_INFO "%s: This is a 386/486 PCI system, setting cache "
-			   "alignment to 8 longwords.\n", dev->name);
+		dev_info(&dev->dev,
+			 "This is a 386/486 PCI system, setting cache alignment to 8 longwords\n");
 	} else {
 		i |= 0xE000;
 	}
@@ -931,22 +933,23 @@ static void tx_timeout(struct net_device
 	struct netdev_private *np = netdev_priv(dev);
 	void __iomem *ioaddr = np->base_addr;
 
-	printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
-		   " resetting...\n", dev->name, ioread32(ioaddr + IntrStatus));
+	dev_warn(&dev->dev, "Transmit timed out, status %08x, resetting...\n",
+		 ioread32(ioaddr + IntrStatus));
 
 	{
 		int i;
 		printk(KERN_DEBUG "  Rx ring %p: ", np->rx_ring);
 		for (i = 0; i < RX_RING_SIZE; i++)
-			printk(" %8.8x", (unsigned int)np->rx_ring[i].status);
-		printk(KERN_DEBUG"  Tx ring %p: ", np->tx_ring);
+			printk(KERN_CONT " %08x", (unsigned int)np->rx_ring[i].status);
+		printk(KERN_CONT "\n");
+		printk(KERN_DEBUG "  Tx ring %p: ", np->tx_ring);
 		for (i = 0; i < TX_RING_SIZE; i++)
-			printk(" %8.8x", np->tx_ring[i].status);
-		printk("\n");
+			printk(KERN_CONT " %08x", np->tx_ring[i].status);
+		printk(KERN_CONT "\n");
 	}
-	printk(KERN_DEBUG "Tx cur %d Tx dirty %d Tx Full %d, q bytes %d.\n",
-				np->cur_tx, np->dirty_tx, np->tx_full, np->tx_q_bytes);
-	printk(KERN_DEBUG "Tx Descriptor addr %xh.\n",ioread32(ioaddr+0x4C));
+	printk(KERN_DEBUG "Tx cur %d Tx dirty %d Tx Full %d, q bytes %d\n",
+	       np->cur_tx, np->dirty_tx, np->tx_full, np->tx_q_bytes);
+	printk(KERN_DEBUG "Tx Descriptor addr %xh\n", ioread32(ioaddr+0x4C));
 
 	disable_irq(dev->irq);
 	spin_lock_irq(&np->lock);
@@ -1055,8 +1058,8 @@ static netdev_tx_t start_tx(struct sk_bu
 	dev->trans_start = jiffies;
 
 	if (debug > 4) {
-		printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
-			   dev->name, np->cur_tx, entry);
+		printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d\n",
+		       dev->name, np->cur_tx, entry);
 	}
 	return NETDEV_TX_OK;
 }
@@ -1073,8 +1076,8 @@ static void netdev_tx_done(struct net_de
 		if (tx_status & 0x8000) { 	/* There was an error, log it. */
 #ifndef final_version
 			if (debug > 1)
-				printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
-					   dev->name, tx_status);
+				printk(KERN_DEBUG "%s: Transmit error, Tx status %08x\n",
+				       dev->name, tx_status);
 #endif
 			np->stats.tx_errors++;
 			if (tx_status & 0x0104) np->stats.tx_aborted_errors++;
@@ -1086,8 +1089,8 @@ static void netdev_tx_done(struct net_de
 		} else {
 #ifndef final_version
 			if (debug > 3)
-				printk(KERN_DEBUG "%s: Transmit slot %d ok, Tx status %8.8x.\n",
-					   dev->name, entry, tx_status);
+				printk(KERN_DEBUG "%s: Transmit slot %d ok, Tx status %08x\n",
+				       dev->name, entry, tx_status);
 #endif
 			np->stats.tx_bytes += np->tx_skbuff[entry]->len;
 			np->stats.collisions += (tx_status >> 3) & 15;
@@ -1130,8 +1133,8 @@ static irqreturn_t intr_handler(int irq,
 		iowrite32(intr_status & 0x001ffff, ioaddr + IntrStatus);
 
 		if (debug > 4)
-			printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n",
-				   dev->name, intr_status);
+			printk(KERN_DEBUG "%s: Interrupt, status %04x\n",
+			       dev->name, intr_status);
 
 		if ((intr_status & (NormalIntr|AbnormalIntr)) == 0)
 			break;
@@ -1156,8 +1159,9 @@ static irqreturn_t intr_handler(int irq,
 			netdev_error(dev, intr_status);
 
 		if (--work_limit < 0) {
-			printk(KERN_WARNING "%s: Too much work at interrupt, "
-				   "status=0x%4.4x.\n", dev->name, intr_status);
+			dev_warn(&dev->dev,
+				 "Too much work at interrupt, status=0x%04x\n",
+				 intr_status);
 			/* Set the timer to re-enable the other interrupts after
 			   10*82usec ticks. */
 			spin_lock(&np->lock);
@@ -1171,8 +1175,8 @@ static irqreturn_t intr_handler(int irq,
 	} while (1);
 
 	if (debug > 3)
-		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
-			   dev->name, ioread32(ioaddr + IntrStatus));
+		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x\n",
+		       dev->name, ioread32(ioaddr + IntrStatus));
 	return IRQ_RETVAL(handled);
 }
 
@@ -1185,8 +1189,8 @@ static int netdev_rx(struct net_device *
 	int work_limit = np->dirty_rx + RX_RING_SIZE - np->cur_rx;
 
 	if (debug > 4) {
-		printk(KERN_DEBUG " In netdev_rx(), entry %d status %4.4x.\n",
-			   entry, np->rx_ring[entry].status);
+		printk(KERN_DEBUG " In netdev_rx(), entry %d status %04x\n",
+		       entry, np->rx_ring[entry].status);
 	}
 
 	/* If EOP is set on the next entry, it's a new packet. Send it up. */
@@ -1195,24 +1199,24 @@ static int netdev_rx(struct net_device *
 		s32 status = desc->status;
 
 		if (debug > 4)
-			printk(KERN_DEBUG "  netdev_rx() status was %8.8x.\n",
-				   status);
+			printk(KERN_DEBUG "  netdev_rx() status was %08x\n",
+			       status);
 		if (status < 0)
 			break;
 		if ((status & 0x38008300) != 0x0300) {
 			if ((status & 0x38000300) != 0x0300) {
 				/* Ingore earlier buffers. */
 				if ((status & 0xffff) != 0x7fff) {
-					printk(KERN_WARNING "%s: Oversized Ethernet frame spanned "
-						   "multiple buffers, entry %#x status %4.4x!\n",
-						   dev->name, np->cur_rx, status);
+					dev_warn(&dev->dev,
+						 "Oversized Ethernet frame spanned multiple buffers, entry %#x status %04x!\n",
+						 np->cur_rx, status);
 					np->stats.rx_length_errors++;
 				}
 			} else if (status & 0x8000) {
 				/* There was a fatal error. */
 				if (debug > 2)
-					printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
-						   dev->name, status);
+					printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n",
+					       dev->name, status);
 				np->stats.rx_errors++; /* end of a packet.*/
 				if (status & 0x0890) np->stats.rx_length_errors++;
 				if (status & 0x004C) np->stats.rx_frame_errors++;
@@ -1225,8 +1229,8 @@ static int netdev_rx(struct net_device *
 
 #ifndef final_version
 			if (debug > 4)
-				printk(KERN_DEBUG "  netdev_rx() normal Rx pkt length %d"
-					   " status %x.\n", pkt_len, status);
+				printk(KERN_DEBUG "  netdev_rx() normal Rx pkt length %d status %x\n",
+				       pkt_len, status);
 #endif
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
@@ -1251,11 +1255,10 @@ static int netdev_rx(struct net_device *
 #ifndef final_version				/* Remove after testing. */
 			/* You will want this info for the initial debug. */
 			if (debug > 5)
-				printk(KERN_DEBUG "  Rx data %pM %pM"
-				       " %2.2x%2.2x %d.%d.%d.%d.\n",
+				printk(KERN_DEBUG "  Rx data %pM %pM %02x%02x %pI4\n",
 				       &skb->data[0], &skb->data[6],
 				       skb->data[12], skb->data[13],
-				       skb->data[14], skb->data[15], skb->data[16], skb->data[17]);
+				       &skb->data[14]);
 #endif
 			skb->protocol = eth_type_trans(skb, dev);
 			netif_rx(skb);
@@ -1293,8 +1296,8 @@ static void netdev_error(struct net_devi
 	void __iomem *ioaddr = np->base_addr;
 
 	if (debug > 2)
-		printk(KERN_DEBUG "%s: Abnormal event, %8.8x.\n",
-			   dev->name, intr_status);
+		printk(KERN_DEBUG "%s: Abnormal event, %08x\n",
+		       dev->name, intr_status);
 	if (intr_status == 0xffffffff)
 		return;
 	spin_lock(&np->lock);
@@ -1314,8 +1317,8 @@ static void netdev_error(struct net_devi
 		 	new = 127; /* load full packet before starting */
 		new = (np->csr6 & ~(0x7F << 14)) | (new<<14);
 #endif
-		printk(KERN_DEBUG "%s: Tx underflow, new csr6 %8.8x.\n",
-			   dev->name, new);
+		printk(KERN_DEBUG "%s: Tx underflow, new csr6 %08x\n",
+		       dev->name, new);
 		update_csr6(dev, new);
 	}
 	if (intr_status & RxDied) {		/* Missed a Rx frame. */
@@ -1357,17 +1360,16 @@ static u32 __set_rx_mode(struct net_devi
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		rx_mode = RxAcceptBroadcast | AcceptMulticast | RxAcceptAllPhys
 			| AcceptMyPhys;
-	} else if ((dev->mc_count > multicast_filter_limit) ||
+	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
 		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		rx_mode = RxAcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 	} else {
 		struct dev_mc_list *mclist;
-		int i;
+
 		memset(mc_filter, 0, sizeof(mc_filter));
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-			 i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			int filterbit = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F;
 			filterbit &= 0x3f;
 			mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
@@ -1487,11 +1489,13 @@ static int netdev_close(struct net_devic
 	netif_stop_queue(dev);
 
 	if (debug > 1) {
-		printk(KERN_DEBUG "%s: Shutting down ethercard, status was %8.8x "
-			   "Config %8.8x.\n", dev->name, ioread32(ioaddr + IntrStatus),
-			   ioread32(ioaddr + NetworkConfig));
-		printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d,  Rx %d / %d.\n",
-			   dev->name, np->cur_tx, np->dirty_tx, np->cur_rx, np->dirty_rx);
+		printk(KERN_DEBUG "%s: Shutting down ethercard, status was %08x Config %08x\n",
+		       dev->name, ioread32(ioaddr + IntrStatus),
+		       ioread32(ioaddr + NetworkConfig));
+		printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d,  Rx %d / %d\n",
+		       dev->name,
+		       np->cur_tx, np->dirty_tx,
+		       np->cur_rx, np->dirty_rx);
 	}
 
  	/* Stop the chip's Tx and Rx processes. */
@@ -1512,18 +1516,16 @@ static int netdev_close(struct net_devic
 	if (debug > 2) {
 		int i;
 
-		printk(KERN_DEBUG"  Tx ring at %8.8x:\n",
-			   (int)np->tx_ring);
+		printk(KERN_DEBUG"  Tx ring at %08x:\n", (int)np->tx_ring);
 		for (i = 0; i < TX_RING_SIZE; i++)
-			printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x.\n",
-				   i, np->tx_ring[i].length,
-				   np->tx_ring[i].status, np->tx_ring[i].buffer1);
-		printk(KERN_DEBUG "  Rx ring %8.8x:\n",
-			   (int)np->rx_ring);
+			printk(KERN_DEBUG " #%d desc. %04x %04x %08x\n",
+			       i, np->tx_ring[i].length,
+			       np->tx_ring[i].status, np->tx_ring[i].buffer1);
+		printk(KERN_DEBUG "  Rx ring %08x:\n", (int)np->rx_ring);
 		for (i = 0; i < RX_RING_SIZE; i++) {
-			printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x\n",
-				   i, np->rx_ring[i].length,
-				   np->rx_ring[i].status, np->rx_ring[i].buffer1);
+			printk(KERN_DEBUG " #%d desc. %04x %04x %08x\n",
+			       i, np->rx_ring[i].length,
+			       np->rx_ring[i].status, np->rx_ring[i].buffer1);
 		}
 	}
 #endif /* __i386__ debugging only */
@@ -1622,9 +1624,8 @@ static int w840_resume (struct pci_dev *
 		goto out; /* device not suspended */
 	if (netif_running(dev)) {
 		if ((retval = pci_enable_device(pdev))) {
-			printk (KERN_ERR
-				"%s: pci_enable_device failed in resume\n",
-				dev->name);
+			dev_err(&dev->dev,
+				"pci_enable_device failed in resume\n");
 			goto out;
 		}
 		spin_lock_irq(&np->lock);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tulip/xircom_cb.c linux-libre-2.6.34-gnu1/drivers/net/tulip/xircom_cb.c
--- linux-libre-2.6.33-gnu1/drivers/net/tulip/xircom_cb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tulip/xircom_cb.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,8 @@
  * 	$Id: xircom_cb.c,v 1.33 2001/03/19 14:02:07 arjanv Exp $
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -144,7 +146,7 @@ static int link_status(struct xircom_pri
 
 
 
-static struct pci_device_id xircom_pci_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(xircom_pci_table) = {
 	{0x115D, 0x0003, PCI_ANY_ID, PCI_ANY_ID,},
 	{0,},
 };
@@ -234,7 +236,7 @@ static int __devinit xircom_probe(struct
 	pci_write_config_word (pdev, PCI_STATUS,tmp16);
 
 	if (!request_region(pci_resource_start(pdev, 0), 128, "xircom_cb")) {
-		printk(KERN_ERR "xircom_probe: failed to allocate io-region\n");
+		pr_err("%s: failed to allocate io-region\n", __func__);
 		return -ENODEV;
 	}
 
@@ -245,7 +247,7 @@ static int __devinit xircom_probe(struct
 	 */
 	dev = alloc_etherdev(sizeof(struct xircom_private));
 	if (!dev) {
-		printk(KERN_ERR "xircom_probe: failed to allocate etherdev\n");
+		pr_err("%s: failed to allocate etherdev\n", __func__);
 		goto device_fail;
 	}
 	private = netdev_priv(dev);
@@ -253,12 +255,12 @@ static int __devinit xircom_probe(struct
 	/* Allocate the send/receive buffers */
 	private->rx_buffer = pci_alloc_consistent(pdev,8192,&private->rx_dma_handle);
 	if (private->rx_buffer == NULL) {
- 		printk(KERN_ERR "xircom_probe: no memory for rx buffer \n");
+		pr_err("%s: no memory for rx buffer\n", __func__);
 		goto rx_buf_fail;
 	}
 	private->tx_buffer = pci_alloc_consistent(pdev,8192,&private->tx_dma_handle);
 	if (private->tx_buffer == NULL) {
-		printk(KERN_ERR "xircom_probe: no memory for tx buffer \n");
+		pr_err("%s: no memory for tx buffer\n", __func__);
 		goto tx_buf_fail;
 	}
 
@@ -281,11 +283,12 @@ static int __devinit xircom_probe(struct
 	pci_set_drvdata(pdev, dev);
 
 	if (register_netdev(dev)) {
-		printk(KERN_ERR "xircom_probe: netdevice registration failed.\n");
+		pr_err("%s: netdevice registration failed\n", __func__);
 		goto reg_fail;
 	}
 
-	printk(KERN_INFO "%s: Xircom cardbus revision %i at irq %i \n", dev->name, pdev->revision, pdev->irq);
+	dev_info(&dev->dev, "Xircom cardbus revision %i at irq %i\n",
+		 pdev->revision, pdev->irq);
 	/* start the transmitter to get a heartbeat */
 	/* TODO: send 2 dummy packets here */
 	transceiver_voodoo(private);
@@ -347,8 +350,10 @@ static irqreturn_t xircom_interrupt(int
 
 #ifdef DEBUG
 	print_binary(status);
-	printk("tx status 0x%08x 0x%08x \n",card->tx_buffer[0],card->tx_buffer[4]);
-	printk("rx status 0x%08x 0x%08x \n",card->rx_buffer[0],card->rx_buffer[4]);
+	printk("tx status 0x%08x 0x%08x \n",
+	       card->tx_buffer[0], card->tx_buffer[4]);
+	printk("rx status 0x%08x 0x%08x \n",
+	       card->rx_buffer[0], card->rx_buffer[4]);
 #endif
 	/* Handle shared irq and hotplug */
 	if (status == 0 || status == 0xffffffff) {
@@ -358,9 +363,9 @@ static irqreturn_t xircom_interrupt(int
 
 	if (link_status_changed(card)) {
 		int newlink;
-		printk(KERN_DEBUG "xircom_cb: Link status has changed \n");
+		printk(KERN_DEBUG "xircom_cb: Link status has changed\n");
 		newlink = link_status(card);
-		printk(KERN_INFO  "xircom_cb: Link is %i mbit \n",newlink);
+		dev_info(&dev->dev, "Link is %i mbit\n", newlink);
 		if (newlink)
 			netif_carrier_on(dev);
 		else
@@ -457,7 +462,8 @@ static int xircom_open(struct net_device
 	struct xircom_private *xp = netdev_priv(dev);
 	int retval;
 	enter("xircom_open");
-	printk(KERN_INFO "xircom cardbus adaptor found, registering as %s, using irq %i \n",dev->name,dev->irq);
+	pr_info("xircom cardbus adaptor found, registering as %s, using irq %i \n",
+		dev->name, dev->irq);
 	retval = request_irq(dev->irq, xircom_interrupt, IRQF_SHARED, dev->name, dev);
 	if (retval) {
 		leave("xircom_open - No IRQ");
@@ -770,7 +776,7 @@ static void activate_receiver(struct xir
 		udelay(50);
 		counter--;
 		if (counter <= 0)
-			printk(KERN_ERR "xircom_cb: Receiver failed to deactivate\n");
+			pr_err("Receiver failed to deactivate\n");
 	}
 
 	/* enable the receiver */
@@ -787,7 +793,7 @@ static void activate_receiver(struct xir
 		udelay(50);
 		counter--;
 		if (counter <= 0)
-			printk(KERN_ERR "xircom_cb: Receiver failed to re-activate\n");
+			pr_err("Receiver failed to re-activate\n");
 	}
 
 	leave("activate_receiver");
@@ -818,7 +824,7 @@ static void deactivate_receiver(struct x
 		udelay(50);
 		counter--;
 		if (counter <= 0)
-			printk(KERN_ERR "xircom_cb: Receiver failed to deactivate\n");
+			pr_err("Receiver failed to deactivate\n");
 	}
 
 
@@ -861,7 +867,7 @@ static void activate_transmitter(struct
 		udelay(50);
 		counter--;
 		if (counter <= 0)
-			printk(KERN_ERR "xircom_cb: Transmitter failed to deactivate\n");
+			pr_err("Transmitter failed to deactivate\n");
 	}
 
 	/* enable the transmitter */
@@ -878,7 +884,7 @@ static void activate_transmitter(struct
 		udelay(50);
 		counter--;
 		if (counter <= 0)
-			printk(KERN_ERR "xircom_cb: Transmitter failed to re-activate\n");
+			pr_err("Transmitter failed to re-activate\n");
 	}
 
 	leave("activate_transmitter");
@@ -909,7 +915,7 @@ static void deactivate_transmitter(struc
 		udelay(50);
 		counter--;
 		if (counter <= 0)
-			printk(KERN_ERR "xircom_cb: Transmitter failed to deactivate\n");
+			pr_err("Transmitter failed to deactivate\n");
 	}
 
 
@@ -1184,7 +1190,7 @@ static void investigate_read_descriptor(
 			struct sk_buff *skb;
 
 			if (pkt_len > 1518) {
-				printk(KERN_ERR "xircom_cb: Packet length %i is bogus \n",pkt_len);
+				pr_err("Packet length %i is bogus\n", pkt_len);
 				pkt_len = 1518;
 			}
 
@@ -1222,7 +1228,7 @@ static void investigate_write_descriptor
 		status = le32_to_cpu(card->tx_buffer[4*descnr]);
 #if 0
 		if (status & 0x8000) {	/* Major error */
-			printk(KERN_ERR "Major transmit error status %x \n", status);
+			pr_err("Major transmit error status %x\n", status);
 			card->tx_buffer[4*descnr] = 0;
 			netif_wake_queue (dev);
 		}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/tun.c linux-libre-2.6.34-gnu1/drivers/net/tun.c
--- linux-libre-2.6.33-gnu1/drivers/net/tun.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/tun.c	2010-05-16 17:17:36.000000000 -0400
@@ -61,6 +61,7 @@
 #include <linux/crc32.h>
 #include <linux/nsproxy.h>
 #include <linux/virtio_net.h>
+#include <linux/rcupdate.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 #include <net/rtnetlink.h>
@@ -144,6 +145,7 @@ static int tun_attach(struct tun_struct
 	err = 0;
 	tfile->tun = tun;
 	tun->tfile = tfile;
+	tun->socket.file = file;
 	dev_hold(tun->dev);
 	sock_hold(tun->socket.sk);
 	atomic_inc(&tfile->count);
@@ -158,6 +160,7 @@ static void __tun_detach(struct tun_stru
 	/* Detach from net device */
 	netif_tx_lock_bh(tun->dev);
 	tun->tfile = NULL;
+	tun->socket.file = NULL;
 	netif_tx_unlock_bh(tun->dev);
 
 	/* Drop read queue */
@@ -364,6 +367,10 @@ static netdev_tx_t tun_net_xmit(struct s
 	if (!check_filter(&tun->txflt, skb))
 		goto drop;
 
+	if (tun->socket.sk->sk_filter &&
+	    sk_filter(tun->socket.sk, skb))
+		goto drop;
+
 	if (skb_queue_len(&tun->socket.sk->sk_receive_queue) >= dev->tx_queue_len) {
 		if (!(tun->flags & TUN_ONE_QUEUE)) {
 			/* Normal queueing mode. */
@@ -380,6 +387,10 @@ static netdev_tx_t tun_net_xmit(struct s
 		}
 	}
 
+	/* Orphan the skb - required as we might hang on to it
+	 * for indefinite time. */
+	skb_orphan(skb);
+
 	/* Enqueue packet */
 	skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb);
 	dev->trans_start = jiffies;
@@ -387,7 +398,8 @@ static netdev_tx_t tun_net_xmit(struct s
 	/* Notify and wake up reader process */
 	if (tun->flags & TUN_FASYNC)
 		kill_fasync(&tun->fasync, SIGIO, POLL_IN);
-	wake_up_interruptible(&tun->socket.wait);
+	wake_up_interruptible_poll(&tun->socket.wait, POLLIN |
+				   POLLRDNORM | POLLRDBAND);
 	return NETDEV_TX_OK;
 
 drop:
@@ -743,7 +755,7 @@ static __inline__ ssize_t tun_put_user(s
 	len = min_t(int, skb->len, len);
 
 	skb_copy_datagram_const_iovec(skb, 0, iv, total, len);
-	total += len;
+	total += skb->len;
 
 	tun->dev->stats.tx_packets++;
 	tun->dev->stats.tx_bytes += len;
@@ -751,34 +763,23 @@ static __inline__ ssize_t tun_put_user(s
 	return total;
 }
 
-static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
-			    unsigned long count, loff_t pos)
+static ssize_t tun_do_read(struct tun_struct *tun,
+			   struct kiocb *iocb, const struct iovec *iv,
+			   ssize_t len, int noblock)
 {
-	struct file *file = iocb->ki_filp;
-	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;
-
-	if (!tun)
-		return -EBADFD;
+	ssize_t ret = 0;
 
 	DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name);
 
-	len = iov_length(iv, count);
-	if (len < 0) {
-		ret = -EINVAL;
-		goto out;
-	}
-
 	add_wait_queue(&tun->socket.wait, &wait);
 	while (len) {
 		current->state = TASK_INTERRUPTIBLE;
 
 		/* Read frames from the queue */
 		if (!(skb=skb_dequeue(&tun->socket.sk->sk_receive_queue))) {
-			if (file->f_flags & O_NONBLOCK) {
+			if (noblock) {
 				ret = -EAGAIN;
 				break;
 			}
@@ -805,6 +806,27 @@ static ssize_t tun_chr_aio_read(struct k
 	current->state = TASK_RUNNING;
 	remove_wait_queue(&tun->socket.wait, &wait);
 
+	return ret;
+}
+
+static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
+			    unsigned long count, loff_t pos)
+{
+	struct file *file = iocb->ki_filp;
+	struct tun_file *tfile = file->private_data;
+	struct tun_struct *tun = __tun_get(tfile);
+	ssize_t len, ret;
+
+	if (!tun)
+		return -EBADFD;
+	len = iov_length(iv, count);
+	if (len < 0) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = tun_do_read(tun, iocb, iv, len, file->f_flags & O_NONBLOCK);
+	ret = min_t(ssize_t, ret, len);
 out:
 	tun_put(tun);
 	return ret;
@@ -847,7 +869,8 @@ static void tun_sock_write_space(struct
 		return;
 
 	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
-		wake_up_interruptible_sync(sk->sk_sleep);
+		wake_up_interruptible_sync_poll(sk->sk_sleep, POLLOUT |
+						POLLWRNORM | POLLWRBAND);
 
 	tun = tun_sk(sk)->tun;
 	kill_fasync(&tun->fasync, SIGIO, POLL_OUT);
@@ -858,6 +881,37 @@ static void tun_sock_destruct(struct soc
 	free_netdev(tun_sk(sk)->tun->dev);
 }
 
+static int tun_sendmsg(struct kiocb *iocb, struct socket *sock,
+		       struct msghdr *m, size_t total_len)
+{
+	struct tun_struct *tun = container_of(sock, struct tun_struct, socket);
+	return tun_get_user(tun, m->msg_iov, total_len,
+			    m->msg_flags & MSG_DONTWAIT);
+}
+
+static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
+		       struct msghdr *m, size_t total_len,
+		       int flags)
+{
+	struct tun_struct *tun = container_of(sock, struct tun_struct, socket);
+	int ret;
+	if (flags & ~(MSG_DONTWAIT|MSG_TRUNC))
+		return -EINVAL;
+	ret = tun_do_read(tun, iocb, m->msg_iov, total_len,
+			  flags & MSG_DONTWAIT);
+	if (ret > total_len) {
+		m->msg_flags |= MSG_TRUNC;
+		ret = flags & MSG_TRUNC ? ret : total_len;
+	}
+	return ret;
+}
+
+/* Ops structure to mimic raw sockets with tun */
+static const struct proto_ops tun_socket_ops = {
+	.sendmsg = tun_sendmsg,
+	.recvmsg = tun_recvmsg,
+};
+
 static struct proto tun_proto = {
 	.name		= "tun",
 	.owner		= THIS_MODULE,
@@ -986,6 +1040,7 @@ static int tun_set_iff(struct net *net,
 			goto err_free_dev;
 
 		init_waitqueue_head(&tun->socket.wait);
+		tun->socket.ops = &tun_socket_ops;
 		sock_init_data(&tun->socket, sk);
 		sk->sk_write_space = tun_sock_write_space;
 		sk->sk_sndbuf = INT_MAX;
@@ -1116,6 +1171,7 @@ static long __tun_chr_ioctl(struct file
 	struct tun_file *tfile = file->private_data;
 	struct tun_struct *tun;
 	void __user* argp = (void __user*)arg;
+	struct sock_fprog fprog;
 	struct ifreq ifr;
 	int sndbuf;
 	int ret;
@@ -1263,6 +1319,26 @@ static long __tun_chr_ioctl(struct file
 		tun->socket.sk->sk_sndbuf = sndbuf;
 		break;
 
+	case TUNATTACHFILTER:
+		/* Can be set only for TAPs */
+		ret = -EINVAL;
+		if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
+			break;
+		ret = -EFAULT;
+		if (copy_from_user(&fprog, argp, sizeof(fprog)))
+			break;
+
+		ret = sk_attach_filter(&fprog, tun->socket.sk);
+		break;
+
+	case TUNDETACHFILTER:
+		/* Can be set only for TAPs */
+		ret = -EINVAL;
+		if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
+			break;
+		ret = sk_detach_filter(tun->socket.sk);
+		break;
+
 	default:
 		ret = -EINVAL;
 		break;
@@ -1365,7 +1441,7 @@ static int tun_chr_close(struct inode *i
 
 		__tun_detach(tun);
 
-		/* If desireable, unregister the netdevice. */
+		/* If desirable, unregister the netdevice. */
 		if (!(tun->flags & TUN_PERSIST)) {
 			rtnl_lock();
 			if (dev->reg_state == NETREG_REGISTERED)
@@ -1525,6 +1601,23 @@ static void tun_cleanup(void)
 	rtnl_link_unregister(&tun_link_ops);
 }
 
+/* Get an underlying socket object from tun file.  Returns error unless file is
+ * attached to a device.  The returned object works like a packet socket, it
+ * can be used for sock_sendmsg/sock_recvmsg.  The caller is responsible for
+ * holding a reference to the file for as long as the socket is in use. */
+struct socket *tun_get_socket(struct file *file)
+{
+	struct tun_struct *tun;
+	if (file->f_op != &tun_fops)
+		return ERR_PTR(-EINVAL);
+	tun = tun_get(file);
+	if (!tun)
+		return ERR_PTR(-EBADFD);
+	tun_put(tun);
+	return &tun->socket;
+}
+EXPORT_SYMBOL_GPL(tun_get_socket);
+
 module_init(tun_init);
 module_exit(tun_cleanup);
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/typhoon.c linux-libre-2.6.34-gnu1/drivers/net/typhoon.c
--- linux-libre-2.6.33-gnu1/drivers/net/typhoon.c	2013-05-03 12:08:45.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/typhoon.c	2013-05-03 09:48:16.000000000 -0400
@@ -98,14 +98,10 @@ static const int multicast_filter_limit
 #define TX_TIMEOUT  (2*HZ)
 
 #define PKT_BUF_SZ		1536
-
-#define DRV_MODULE_NAME		"typhoon"
-#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)*/"
 
+#define pr_fmt(fmt)		KBUILD_MODNAME " " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -113,7 +109,6 @@ static const int multicast_filter_limit
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
@@ -132,14 +127,12 @@ static const int multicast_filter_limit
 #include <linux/in6.h>
 #include <linux/dma-mapping.h>
 #include <linux/firmware.h>
+#include <generated/utsrelease.h>
 
 #include "typhoon.h"
 
-static char version[] __devinitdata =
-    "typhoon.c: version " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
-
 MODULE_AUTHOR("David Dillow <dave@thedillows.org>");
-MODULE_VERSION(DRV_MODULE_VERSION);
+MODULE_VERSION(UTS_RELEASE);
 MODULE_LICENSE("GPL");
 /*(DEBLOBBED)*/
 MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)");
@@ -161,8 +154,8 @@ module_param(use_mmio, int, 0);
 #endif
 
 struct typhoon_card_info {
-	char *name;
-	int capabilities;
+	const char *name;
+	const int capabilities;
 };
 
 #define TYPHOON_CRYPTO_NONE		0x00
@@ -215,7 +208,7 @@ static struct typhoon_card_info typhoon_
  * bit 8 indicates if this is a (0) copper or (1) fiber card
  * bits 12-16 indicate card type: (0) client and (1) server
  */
-static struct pci_device_id typhoon_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(typhoon_pci_tbl) = {
 	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0,TYPHOON_TX },
 	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_TX_95,
@@ -299,7 +292,6 @@ struct typhoon {
 	struct basic_ring	respRing;
 	struct net_device_stats	stats;
 	struct net_device_stats	stats_saved;
-	const char *		name;
 	struct typhoon_shared *	shared;
 	dma_addr_t		shared_dma;
 	__le16			xcvr_select;
@@ -487,7 +479,7 @@ typhoon_hello(struct typhoon *tp)
 		typhoon_inc_cmd_index(&ring->lastWrite, 1);
 
 		INIT_COMMAND_NO_RESPONSE(cmd, TYPHOON_CMD_HELLO_RESP);
-		smp_wmb();
+		wmb();
 		iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY);
 		spin_unlock(&tp->command_lock);
 	}
@@ -534,13 +526,13 @@ typhoon_process_response(struct typhoon
 		} else if(resp->cmd == TYPHOON_CMD_HELLO_RESP) {
 			typhoon_hello(tp);
 		} else {
-			printk(KERN_ERR "%s: dumping unexpected response "
-			       "0x%04x:%d:0x%02x:0x%04x:%08x:%08x\n",
-			       tp->name, le16_to_cpu(resp->cmd),
-			       resp->numDesc, resp->flags,
-			       le16_to_cpu(resp->parm1),
-			       le32_to_cpu(resp->parm2),
-			       le32_to_cpu(resp->parm3));
+			netdev_err(tp->dev,
+				   "dumping unexpected response 0x%04x:%d:0x%02x:0x%04x:%08x:%08x\n",
+				   le16_to_cpu(resp->cmd),
+				   resp->numDesc, resp->flags,
+				   le16_to_cpu(resp->parm1),
+				   le32_to_cpu(resp->parm2),
+				   le32_to_cpu(resp->parm3));
 		}
 
 cleanup:
@@ -606,9 +598,8 @@ typhoon_issue_command(struct typhoon *tp
 	freeResp = typhoon_num_free_resp(tp);
 
 	if(freeCmd < num_cmd || freeResp < num_resp) {
-		printk("%s: no descs for cmd, had (needed) %d (%d) cmd, "
-			"%d (%d) resp\n", tp->name, freeCmd, num_cmd,
-			freeResp, num_resp);
+		netdev_err(tp->dev, "no descs for cmd, had (needed) %d (%d) cmd, %d (%d) resp\n",
+			   freeCmd, num_cmd, freeResp, num_resp);
 		err = -ENOMEM;
 		goto out;
 	}
@@ -733,7 +724,7 @@ typhoon_vlan_rx_register(struct net_devi
 		spin_unlock_bh(&tp->state_lock);
 		err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
 		if(err < 0)
-			printk("%s: vlan offload error %d\n", tp->name, -err);
+			netdev_err(tp->dev, "vlan offload error %d\n", -err);
 		spin_lock_bh(&tp->state_lock);
 	}
 
@@ -924,17 +915,15 @@ typhoon_set_rx_mode(struct net_device *d
 	filter = TYPHOON_RX_FILTER_DIRECTED | TYPHOON_RX_FILTER_BROADCAST;
 	if(dev->flags & IFF_PROMISC) {
 		filter |= TYPHOON_RX_FILTER_PROMISCOUS;
-	} else if((dev->mc_count > multicast_filter_limit) ||
+	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
 		  (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
 		filter |= TYPHOON_RX_FILTER_ALL_MCAST;
-	} else if(dev->mc_count) {
+	} else if (!netdev_mc_empty(dev)) {
 		struct dev_mc_list *mclist;
-		int i;
 
 		memset(mc_filter, 0, sizeof(mc_filter));
-		for(i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-		    i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			int bit = ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x3f;
 			mc_filter[bit >> 5] |= 1 << (bit & 0x1f);
 		}
@@ -1020,7 +1009,7 @@ typhoon_get_stats(struct net_device *dev
 		return saved;
 
 	if(typhoon_do_get_stats(tp) < 0) {
-		printk(KERN_ERR "%s: error getting stats\n", dev->name);
+		netdev_err(dev, "error getting stats\n");
 		return saved;
 	}
 
@@ -1062,8 +1051,8 @@ typhoon_get_drvinfo(struct net_device *d
 		}
 	}
 
-	strcpy(info->driver, DRV_MODULE_NAME);
-	strcpy(info->version, DRV_MODULE_VERSION);
+	strcpy(info->driver, KBUILD_MODNAME);
+	strcpy(info->version, UTS_RELEASE);
 	strcpy(info->bus_info, pci_name(pci_dev));
 }
 
@@ -1321,13 +1310,15 @@ typhoon_init_interface(struct typhoon *t
 
 	tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr);
 	tp->card_state = Sleeping;
-	smp_wmb();
 
 	tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM;
 	tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON;
 
 	spin_lock_init(&tp->command_lock);
 	spin_lock_init(&tp->state_lock);
+
+	/* Force the writes to the shared memory area out before continuing. */
+	wmb();
 }
 
 static void
@@ -1365,8 +1356,8 @@ typhoon_reject_firmware(struct typhoon *
 
 	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);
+		netdev_err(tp->dev, "Failed to load firmware \"%s\"\n",
+			   FIRMWARE_NAME);
 		return err;
 	}
 
@@ -1401,7 +1392,7 @@ typhoon_reject_firmware(struct typhoon *
 	return 0;
 
 invalid_fw:
-	printk(KERN_ERR "%s: Invalid firmware image\n", tp->name);
+	netdev_err(tp->dev, "Invalid firmware image\n");
 	release_firmware(typhoon_fw);
 	typhoon_fw = NULL;
 	return -EINVAL;
@@ -1438,7 +1429,7 @@ typhoon_download_firmware(struct typhoon
 	err = -ENOMEM;
 	dpage = pci_alloc_consistent(pdev, PAGE_SIZE, &dpage_dma);
 	if(!dpage) {
-		printk(KERN_ERR "%s: no DMA mem for firmware\n", tp->name);
+		netdev_err(tp->dev, "no DMA mem for firmware\n");
 		goto err_out;
 	}
 
@@ -1451,7 +1442,7 @@ typhoon_download_firmware(struct typhoon
 
 	err = -ETIMEDOUT;
 	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
-		printk(KERN_ERR "%s: card ready timeout\n", tp->name);
+		netdev_err(tp->dev, "card ready timeout\n");
 		goto err_out_irq;
 	}
 
@@ -1491,8 +1482,7 @@ typhoon_download_firmware(struct typhoon
 			if(typhoon_wait_interrupt(ioaddr) < 0 ||
 			   ioread32(ioaddr + TYPHOON_REG_STATUS) !=
 			   TYPHOON_STATUS_WAITING_FOR_SEGMENT) {
-				printk(KERN_ERR "%s: segment ready timeout\n",
-				       tp->name);
+				netdev_err(tp->dev, "segment ready timeout\n");
 				goto err_out_irq;
 			}
 
@@ -1502,8 +1492,8 @@ typhoon_download_firmware(struct typhoon
 			 * the checksum, we can do this once, at the end.
 			 */
 			csum = csum_fold(csum_partial_copy_nocheck(image_data,
-								  dpage, len,
-								  0));
+								   dpage, len,
+								   0));
 
 			iowrite32(len, ioaddr + TYPHOON_REG_BOOT_LENGTH);
 			iowrite32(le16_to_cpu((__force __le16)csum),
@@ -1514,7 +1504,7 @@ typhoon_download_firmware(struct typhoon
 			iowrite32(dpage_dma, ioaddr + TYPHOON_REG_BOOT_DATA_LO);
 			typhoon_post_pci_writes(ioaddr);
 			iowrite32(TYPHOON_BOOTCMD_SEG_AVAILABLE,
-			       ioaddr + TYPHOON_REG_COMMAND);
+					ioaddr + TYPHOON_REG_COMMAND);
 
 			image_data += len;
 			load_addr += len;
@@ -1525,15 +1515,15 @@ typhoon_download_firmware(struct typhoon
 	if(typhoon_wait_interrupt(ioaddr) < 0 ||
 	   ioread32(ioaddr + TYPHOON_REG_STATUS) !=
 	   TYPHOON_STATUS_WAITING_FOR_SEGMENT) {
-		printk(KERN_ERR "%s: final segment ready timeout\n", tp->name);
+		netdev_err(tp->dev, "final segment ready timeout\n");
 		goto err_out_irq;
 	}
 
 	iowrite32(TYPHOON_BOOTCMD_DNLD_COMPLETE, ioaddr + TYPHOON_REG_COMMAND);
 
 	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_BOOT) < 0) {
-		printk(KERN_ERR "%s: boot ready timeout, status 0x%0x\n",
-		       tp->name, ioread32(ioaddr + TYPHOON_REG_STATUS));
+		netdev_err(tp->dev, "boot ready timeout, status 0x%0x\n",
+			   ioread32(ioaddr + TYPHOON_REG_STATUS));
 		goto err_out_irq;
 	}
 
@@ -1555,7 +1545,7 @@ typhoon_boot_3XP(struct typhoon *tp, u32
 	void __iomem *ioaddr = tp->ioaddr;
 
 	if(typhoon_wait_status(ioaddr, initial_status) < 0) {
-		printk(KERN_ERR "%s: boot ready timeout\n", tp->name);
+		netdev_err(tp->dev, "boot ready timeout\n");
 		goto out_timeout;
 	}
 
@@ -1566,8 +1556,8 @@ typhoon_boot_3XP(struct typhoon *tp, u32
 				ioaddr + TYPHOON_REG_COMMAND);
 
 	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_RUNNING) < 0) {
-		printk(KERN_ERR "%s: boot finish timeout (status 0x%x)\n",
-		       tp->name, ioread32(ioaddr + TYPHOON_REG_STATUS));
+		netdev_err(tp->dev, "boot finish timeout (status 0x%x)\n",
+			   ioread32(ioaddr + TYPHOON_REG_STATUS));
 		goto out_timeout;
 	}
 
@@ -1866,8 +1856,7 @@ typhoon_interrupt(int irq, void *dev_ins
 		typhoon_post_pci_writes(ioaddr);
 		__napi_schedule(&tp->napi);
 	} else {
-		printk(KERN_ERR "%s: Error, poll already scheduled\n",
-                       dev->name);
+		netdev_err(dev, "Error, poll already scheduled\n");
 	}
 	return IRQ_HANDLED;
 }
@@ -1900,16 +1889,15 @@ typhoon_sleep(struct typhoon *tp, pci_po
 	xp_cmd.parm1 = events;
 	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
 	if(err < 0) {
-		printk(KERN_ERR "%s: typhoon_sleep(): wake events cmd err %d\n",
-				tp->name, err);
+		netdev_err(tp->dev, "typhoon_sleep(): wake events cmd err %d\n",
+			   err);
 		return err;
 	}
 
 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_GOTO_SLEEP);
 	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
 	if(err < 0) {
-		printk(KERN_ERR "%s: typhoon_sleep(): sleep cmd err %d\n",
-				tp->name, err);
+		netdev_err(tp->dev, "typhoon_sleep(): sleep cmd err %d\n", err);
 		return err;
 	}
 
@@ -1960,12 +1948,12 @@ typhoon_start_runtime(struct typhoon *tp
 
 	err = typhoon_download_firmware(tp);
 	if(err < 0) {
-		printk("%s: cannot load runtime on 3XP\n", tp->name);
+		netdev_err(tp->dev, "cannot load runtime on 3XP\n");
 		goto error_out;
 	}
 
 	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_BOOT) < 0) {
-		printk("%s: cannot boot 3XP\n", tp->name);
+		netdev_err(tp->dev, "cannot boot 3XP\n");
 		err = -EIO;
 		goto error_out;
 	}
@@ -2069,9 +2057,7 @@ typhoon_stop_runtime(struct typhoon *tp,
 	}
 
 	if(i == TYPHOON_WAIT_TIMEOUT)
-		printk(KERN_ERR
-		       "%s: halt timed out waiting for Tx to complete\n",
-		       tp->name);
+		netdev_err(tp->dev, "halt timed out waiting for Tx to complete\n");
 
 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_TX_DISABLE);
 	typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
@@ -2088,11 +2074,10 @@ typhoon_stop_runtime(struct typhoon *tp,
 	typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
 
 	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_HALTED) < 0)
-		printk(KERN_ERR "%s: timed out waiting for 3XP to halt\n",
-		       tp->name);
+		netdev_err(tp->dev, "timed out waiting for 3XP to halt\n");
 
 	if(typhoon_reset(ioaddr, wait_type) < 0) {
-		printk(KERN_ERR "%s: unable to reset 3XP\n", tp->name);
+		netdev_err(tp->dev, "unable to reset 3XP\n");
 		return -ETIMEDOUT;
 	}
 
@@ -2111,9 +2096,8 @@ typhoon_tx_timeout(struct net_device *de
 	struct typhoon *tp = netdev_priv(dev);
 
 	if(typhoon_reset(tp->ioaddr, WaitNoSleep) < 0) {
-		printk(KERN_WARNING "%s: could not reset in tx timeout\n",
-					dev->name);
-		goto truely_dead;
+		netdev_warn(dev, "could not reset in tx timeout\n");
+		goto truly_dead;
 	}
 
 	/* If we ever start using the Hi ring, it will need cleaning too */
@@ -2121,15 +2105,14 @@ typhoon_tx_timeout(struct net_device *de
 	typhoon_free_rx_rings(tp);
 
 	if(typhoon_start_runtime(tp) < 0) {
-		printk(KERN_ERR "%s: could not start runtime in tx timeout\n",
-					dev->name);
-		goto truely_dead;
+		netdev_err(dev, "could not start runtime in tx timeout\n");
+		goto truly_dead;
         }
 
 	netif_wake_queue(dev);
 	return;
 
-truely_dead:
+truly_dead:
 	/* Reset the hardware, and turn off carrier to avoid more timeouts */
 	typhoon_reset(tp->ioaddr, NoWait);
 	netif_carrier_off(dev);
@@ -2147,7 +2130,7 @@ typhoon_open(struct net_device *dev)
 
 	err = typhoon_wakeup(tp, WaitSleep);
 	if(err < 0) {
-		printk(KERN_ERR "%s: unable to wakeup device\n", dev->name);
+		netdev_err(dev, "unable to wakeup device\n");
 		goto out_sleep;
 	}
 
@@ -2172,14 +2155,13 @@ out_irq:
 
 out_sleep:
 	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
-		printk(KERN_ERR "%s: unable to reboot into sleep img\n",
-				dev->name);
+		netdev_err(dev, "unable to reboot into sleep img\n");
 		typhoon_reset(tp->ioaddr, NoWait);
 		goto out;
 	}
 
 	if(typhoon_sleep(tp, PCI_D3hot, 0) < 0)
-		printk(KERN_ERR "%s: unable to go back to sleep\n", dev->name);
+		netdev_err(dev, "unable to go back to sleep\n");
 
 out:
 	return err;
@@ -2194,7 +2176,7 @@ typhoon_close(struct net_device *dev)
 	napi_disable(&tp->napi);
 
 	if(typhoon_stop_runtime(tp, WaitSleep) < 0)
-		printk(KERN_ERR "%s: unable to stop runtime\n", dev->name);
+		netdev_err(dev, "unable to stop runtime\n");
 
 	/* Make sure there is no irq handler running on a different CPU. */
 	free_irq(dev->irq, dev);
@@ -2203,10 +2185,10 @@ typhoon_close(struct net_device *dev)
 	typhoon_init_rings(tp);
 
 	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0)
-		printk(KERN_ERR "%s: unable to boot sleep image\n", dev->name);
+		netdev_err(dev, "unable to boot sleep image\n");
 
 	if(typhoon_sleep(tp, PCI_D3hot, 0) < 0)
-		printk(KERN_ERR "%s: unable to put card to sleep\n", dev->name);
+		netdev_err(dev, "unable to put card to sleep\n");
 
 	return 0;
 }
@@ -2224,14 +2206,12 @@ typhoon_resume(struct pci_dev *pdev)
 		return 0;
 
 	if(typhoon_wakeup(tp, WaitNoSleep) < 0) {
-		printk(KERN_ERR "%s: critical: could not wake up in resume\n",
-				dev->name);
+		netdev_err(dev, "critical: could not wake up in resume\n");
 		goto reset;
 	}
 
 	if(typhoon_start_runtime(tp) < 0) {
-		printk(KERN_ERR "%s: critical: could not start runtime in "
-				"resume\n", dev->name);
+		netdev_err(dev, "critical: could not start runtime in resume\n");
 		goto reset;
 	}
 
@@ -2258,8 +2238,7 @@ typhoon_suspend(struct pci_dev *pdev, pm
 	spin_lock_bh(&tp->state_lock);
 	if(tp->vlgrp && tp->wol_events & TYPHOON_WAKE_MAGIC_PKT) {
 		spin_unlock_bh(&tp->state_lock);
-		printk(KERN_ERR "%s: cannot do WAKE_MAGIC with VLANS\n",
-				dev->name);
+		netdev_err(dev, "cannot do WAKE_MAGIC with VLANS\n");
 		return -EBUSY;
 	}
 	spin_unlock_bh(&tp->state_lock);
@@ -2267,7 +2246,7 @@ typhoon_suspend(struct pci_dev *pdev, pm
 	netif_device_detach(dev);
 
 	if(typhoon_stop_runtime(tp, WaitNoSleep) < 0) {
-		printk(KERN_ERR "%s: unable to stop runtime\n", dev->name);
+		netdev_err(dev, "unable to stop runtime\n");
 		goto need_resume;
 	}
 
@@ -2275,7 +2254,7 @@ typhoon_suspend(struct pci_dev *pdev, pm
 	typhoon_init_rings(tp);
 
 	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
-		printk(KERN_ERR "%s: unable to boot sleep image\n", dev->name);
+		netdev_err(dev, "unable to boot sleep image\n");
 		goto need_resume;
 	}
 
@@ -2283,21 +2262,19 @@ typhoon_suspend(struct pci_dev *pdev, pm
 	xp_cmd.parm1 = cpu_to_le16(ntohs(*(__be16 *)&dev->dev_addr[0]));
 	xp_cmd.parm2 = cpu_to_le32(ntohl(*(__be32 *)&dev->dev_addr[2]));
 	if(typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL) < 0) {
-		printk(KERN_ERR "%s: unable to set mac address in suspend\n",
-				dev->name);
+		netdev_err(dev, "unable to set mac address in suspend\n");
 		goto need_resume;
 	}
 
 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_RX_FILTER);
 	xp_cmd.parm1 = TYPHOON_RX_FILTER_DIRECTED | TYPHOON_RX_FILTER_BROADCAST;
 	if(typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL) < 0) {
-		printk(KERN_ERR "%s: unable to set rx filter in suspend\n",
-				dev->name);
+		netdev_err(dev, "unable to set rx filter in suspend\n");
 		goto need_resume;
 	}
 
 	if(typhoon_sleep(tp, pci_choose_state(pdev, state), tp->wol_events) < 0) {
-		printk(KERN_ERR "%s: unable to put card to sleep\n", dev->name);
+		netdev_err(dev, "unable to put card to sleep\n");
 		goto need_resume;
 	}
 
@@ -2351,7 +2328,7 @@ out_unmap:
 
 out:
 	if(!mode)
-		printk(KERN_INFO PFX "falling back to port IO\n");
+		pr_info("%s: falling back to port IO\n", pci_name(pdev));
 	return mode;
 }
 
@@ -2371,7 +2348,6 @@ static const struct net_device_ops typho
 static int __devinit
 typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	static int did_version = 0;
 	struct net_device *dev;
 	struct typhoon *tp;
 	int card_id = (int) ent->driver_data;
@@ -2381,14 +2357,11 @@ typhoon_init_one(struct pci_dev *pdev, c
 	struct cmd_desc xp_cmd;
 	struct resp_desc xp_resp[3];
 	int err = 0;
-
-	if(!did_version++)
-		printk(KERN_INFO "%s", version);
+	const char *err_msg;
 
 	dev = alloc_etherdev(sizeof(*tp));
 	if(dev == NULL) {
-		printk(ERR_PFX "%s: unable to alloc new net device\n",
-		       pci_name(pdev));
+		err_msg = "unable to alloc new net device";
 		err = -ENOMEM;
 		goto error_out;
 	}
@@ -2396,57 +2369,48 @@ typhoon_init_one(struct pci_dev *pdev, c
 
 	err = pci_enable_device(pdev);
 	if(err < 0) {
-		printk(ERR_PFX "%s: unable to enable device\n",
-		       pci_name(pdev));
+		err_msg = "unable to enable device";
 		goto error_out_dev;
 	}
 
 	err = pci_set_mwi(pdev);
 	if(err < 0) {
-		printk(ERR_PFX "%s: unable to set MWI\n", pci_name(pdev));
+		err_msg = "unable to set MWI";
 		goto error_out_disable;
 	}
 
 	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));
+		err_msg = "No usable DMA configuration";
 		goto error_out_mwi;
 	}
 
 	/* sanity checks on IO and MMIO BARs
 	 */
 	if(!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) {
-		printk(ERR_PFX
-		       "%s: region #1 not a PCI IO resource, aborting\n",
-		       pci_name(pdev));
+		err_msg = "region #1 not a PCI IO resource, aborting";
 		err = -ENODEV;
 		goto error_out_mwi;
 	}
 	if(pci_resource_len(pdev, 0) < 128) {
-		printk(ERR_PFX "%s: Invalid PCI IO region size, aborting\n",
-		       pci_name(pdev));
+		err_msg = "Invalid PCI IO region size, aborting";
 		err = -ENODEV;
 		goto error_out_mwi;
 	}
 	if(!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
-		printk(ERR_PFX
-		       "%s: region #1 not a PCI MMIO resource, aborting\n",
-		       pci_name(pdev));
+		err_msg = "region #1 not a PCI MMIO resource, aborting";
 		err = -ENODEV;
 		goto error_out_mwi;
 	}
 	if(pci_resource_len(pdev, 1) < 128) {
-		printk(ERR_PFX "%s: Invalid PCI MMIO region size, aborting\n",
-		       pci_name(pdev));
+		err_msg = "Invalid PCI MMIO region size, aborting";
 		err = -ENODEV;
 		goto error_out_mwi;
 	}
 
-	err = pci_request_regions(pdev, "typhoon");
+	err = pci_request_regions(pdev, KBUILD_MODNAME);
 	if(err < 0) {
-		printk(ERR_PFX "%s: could not request regions\n",
-		       pci_name(pdev));
+		err_msg = "could not request regions";
 		goto error_out_mwi;
 	}
 
@@ -2457,8 +2421,7 @@ typhoon_init_one(struct pci_dev *pdev, c
 
 	ioaddr = pci_iomap(pdev, use_mmio, 128);
 	if (!ioaddr) {
-		printk(ERR_PFX "%s: cannot remap registers, aborting\n",
-		       pci_name(pdev));
+		err_msg = "cannot remap registers, aborting";
 		err = -EIO;
 		goto error_out_regions;
 	}
@@ -2468,8 +2431,7 @@ typhoon_init_one(struct pci_dev *pdev, c
 	shared = pci_alloc_consistent(pdev, sizeof(struct typhoon_shared),
 				      &shared_dma);
 	if(!shared) {
-		printk(ERR_PFX "%s: could not allocate DMA memory\n",
-		       pci_name(pdev));
+		err_msg = "could not allocate DMA memory";
 		err = -ENOMEM;
 		goto error_out_remap;
 	}
@@ -2492,7 +2454,7 @@ typhoon_init_one(struct pci_dev *pdev, c
 	 * 5) Put the card to sleep.
 	 */
 	if (typhoon_reset(ioaddr, WaitSleep) < 0) {
-		printk(ERR_PFX "%s: could not reset 3XP\n", pci_name(pdev));
+		err_msg = "could not reset 3XP";
 		err = -EIO;
 		goto error_out_dma;
 	}
@@ -2504,26 +2466,18 @@ typhoon_init_one(struct pci_dev *pdev, c
 	pci_set_master(pdev);
 	pci_save_state(pdev);
 
-	/* dev->name is not valid until we register, but we need to
-	 * use some common routines to initialize the card. So that those
-	 * routines print the right name, we keep our oun pointer to the name
-	 */
-	tp->name = pci_name(pdev);
-
 	typhoon_init_interface(tp);
 	typhoon_init_rings(tp);
 
 	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
-		printk(ERR_PFX "%s: cannot boot 3XP sleep image\n",
-		       pci_name(pdev));
+		err_msg = "cannot boot 3XP sleep image";
 		err = -EIO;
 		goto error_out_reset;
 	}
 
 	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_MAC_ADDRESS);
 	if(typhoon_issue_command(tp, 1, &xp_cmd, 1, xp_resp) < 0) {
-		printk(ERR_PFX "%s: cannot read MAC address\n",
-		       pci_name(pdev));
+		err_msg = "cannot read MAC address";
 		err = -EIO;
 		goto error_out_reset;
 	}
@@ -2532,8 +2486,7 @@ typhoon_init_one(struct pci_dev *pdev, c
 	*(__be32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp[0].parm2));
 
 	if(!is_valid_ether_addr(dev->dev_addr)) {
-		printk(ERR_PFX "%s: Could not obtain valid ethernet address, "
-		       "aborting\n", pci_name(pdev));
+		err_msg = "Could not obtain valid ethernet address, aborting";
 		goto error_out_reset;
 	}
 
@@ -2542,8 +2495,7 @@ typhoon_init_one(struct pci_dev *pdev, c
 	 */
 	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS);
 	if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) {
-		printk(ERR_PFX "%s: Could not get Sleep Image version\n",
-			pci_name(pdev));
+		err_msg = "Could not get Sleep Image version";
 		goto error_out_reset;
 	}
 
@@ -2560,8 +2512,7 @@ typhoon_init_one(struct pci_dev *pdev, c
 		tp->capabilities |= TYPHOON_WAKEUP_NEEDS_RESET;
 
 	if(typhoon_sleep(tp, PCI_D3hot, 0) < 0) {
-		printk(ERR_PFX "%s: cannot put adapter to sleep\n",
-		       pci_name(pdev));
+		err_msg = "cannot put adapter to sleep";
 		err = -EIO;
 		goto error_out_reset;
 	}
@@ -2580,19 +2531,18 @@ typhoon_init_one(struct pci_dev *pdev, c
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 	dev->features |= NETIF_F_TSO;
 
-	if(register_netdev(dev) < 0)
+	if(register_netdev(dev) < 0) {
+		err_msg = "unable to register netdev";
 		goto error_out_reset;
-
-	/* fixup our local name */
-	tp->name = dev->name;
+	}
 
 	pci_set_drvdata(pdev, dev);
 
-	printk(KERN_INFO "%s: %s at %s 0x%llx, %pM\n",
-	       dev->name, typhoon_card_info[card_id].name,
-	       use_mmio ? "MMIO" : "IO",
-	       (unsigned long long)pci_resource_start(pdev, use_mmio),
-	       dev->dev_addr);
+	netdev_info(dev, "%s at %s 0x%llx, %pM\n",
+		    typhoon_card_info[card_id].name,
+		    use_mmio ? "MMIO" : "IO",
+		    (unsigned long long)pci_resource_start(pdev, use_mmio),
+		    dev->dev_addr);
 
 	/* xp_resp still contains the response to the READ_VERSIONS command.
 	 * For debugging, let the user know what version he has.
@@ -2602,23 +2552,20 @@ typhoon_init_one(struct pci_dev *pdev, c
 		 * of version is Month/Day of build.
 		 */
 		u16 monthday = le32_to_cpu(xp_resp[0].parm2) & 0xffff;
-		printk(KERN_INFO "%s: Typhoon 1.0 Sleep Image built "
-			"%02u/%02u/2000\n", dev->name, monthday >> 8,
-			monthday & 0xff);
+		netdev_info(dev, "Typhoon 1.0 Sleep Image built %02u/%02u/2000\n",
+			    monthday >> 8, monthday & 0xff);
 	} else if(xp_resp[0].numDesc == 2) {
 		/* This is the Typhoon 1.1+ type Sleep Image
 		 */
 		u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2);
 		u8 *ver_string = (u8 *) &xp_resp[1];
 		ver_string[25] = 0;
-		printk(KERN_INFO "%s: Typhoon 1.1+ Sleep Image version "
-			"%02x.%03x.%03x %s\n", dev->name, sleep_ver >> 24,
-			(sleep_ver >> 12) & 0xfff, sleep_ver & 0xfff,
-			ver_string);
+		netdev_info(dev, "Typhoon 1.1+ Sleep Image version %02x.%03x.%03x %s\n",
+			    sleep_ver >> 24, (sleep_ver >> 12) & 0xfff,
+			    sleep_ver & 0xfff, ver_string);
 	} else {
-		printk(KERN_WARNING "%s: Unknown Sleep Image version "
-			"(%u:%04x)\n", dev->name, xp_resp[0].numDesc,
-			le32_to_cpu(xp_resp[0].parm2));
+		netdev_warn(dev, "Unknown Sleep Image version (%u:%04x)\n",
+			    xp_resp[0].numDesc, le32_to_cpu(xp_resp[0].parm2));
 	}
 
 	return 0;
@@ -2640,6 +2587,7 @@ error_out_disable:
 error_out_dev:
 	free_netdev(dev);
 error_out:
+	pr_err("%s: %s\n", pci_name(pdev), err_msg);
 	return err;
 }
 
@@ -2664,7 +2612,7 @@ typhoon_remove_one(struct pci_dev *pdev)
 }
 
 static struct pci_driver typhoon_driver = {
-	.name		= DRV_MODULE_NAME,
+	.name		= KBUILD_MODNAME,
 	.id_table	= typhoon_pci_tbl,
 	.probe		= typhoon_init_one,
 	.remove		= __devexit_p(typhoon_remove_one),
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ucc_geth.c linux-libre-2.6.34-gnu1/drivers/net/ucc_geth.c
--- linux-libre-2.6.33-gnu1/drivers/net/ucc_geth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ucc_geth.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <asm/qe.h>
 #include <asm/ucc.h>
 #include <asm/ucc_fast.h>
+#include <asm/machdep.h>
 
 #include "ucc_geth.h"
 #include "fsl_pq_mdio.h"
@@ -429,7 +430,7 @@ static void hw_add_addr_in_hash(struct u
 	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
 
 	/* Ethernet frames are defined in Little Endian mode,
-	therefor to insert */
+	therefore to insert */
 	/* the address to the hash (Big Endian mode), we reverse the bytes.*/
 
 	set_mac_addr(&p_82xx_addr_filt->taddr.h, p_enet_addr);
@@ -1334,7 +1335,7 @@ static int adjust_enet_interface(struct
 	struct ucc_geth __iomem *ug_regs;
 	struct ucc_fast __iomem *uf_regs;
 	int ret_val;
-	u32 upsmr, maccfg2, tbiBaseAddress;
+	u32 upsmr, maccfg2;
 	u16 value;
 
 	ugeth_vdbg("%s: IN", __func__);
@@ -1389,14 +1390,20 @@ static int adjust_enet_interface(struct
 	/* Note that this depends on proper setting in utbipar register. */
 	if ((ugeth->phy_interface == PHY_INTERFACE_MODE_TBI) ||
 	    (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
-		tbiBaseAddress = in_be32(&ug_regs->utbipar);
-		tbiBaseAddress &= UTBIPAR_PHY_ADDRESS_MASK;
-		tbiBaseAddress >>= UTBIPAR_PHY_ADDRESS_SHIFT;
-		value = ugeth->phydev->bus->read(ugeth->phydev->bus,
-				(u8) tbiBaseAddress, ENET_TBI_MII_CR);
+		struct ucc_geth_info *ug_info = ugeth->ug_info;
+		struct phy_device *tbiphy;
+
+		if (!ug_info->tbi_node)
+			ugeth_warn("TBI mode requires that the device "
+				"tree specify a tbi-handle\n");
+
+		tbiphy = of_phy_find_device(ug_info->tbi_node);
+		if (!tbiphy)
+			ugeth_warn("Could not get TBI device\n");
+
+		value = phy_read(tbiphy, ENET_TBI_MII_CR);
 		value &= ~0x1000;	/* Turn off autonegotiation */
-		ugeth->phydev->bus->write(ugeth->phydev->bus,
-				(u8) tbiBaseAddress, ENET_TBI_MII_CR, value);
+		phy_write(tbiphy, ENET_TBI_MII_CR, value);
 	}
 
 	init_check_frame_length_mode(ug_info->lengthCheckRx, &ug_regs->maccfg2);
@@ -1995,7 +2002,6 @@ static void ucc_geth_set_multi(struct ne
 	struct dev_mc_list *dmi;
 	struct ucc_fast __iomem *uf_regs;
 	struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
-	int i;
 
 	ugeth = netdev_priv(dev);
 
@@ -2022,10 +2028,7 @@ static void ucc_geth_set_multi(struct ne
 			out_be32(&p_82xx_addr_filt->gaddr_h, 0x0);
 			out_be32(&p_82xx_addr_filt->gaddr_l, 0x0);
 
-			dmi = dev->mc_list;
-
-			for (i = 0; i < dev->mc_count; i++, dmi = dmi->next) {
-
+			netdev_for_each_mc_addr(dmi, dev) {
 				/* Only support group multicast for now.
 				 */
 				if (!(dmi->dmi_addr[0] & 1))
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/ucc_geth_ethtool.c linux-libre-2.6.34-gnu1/drivers/net/ucc_geth_ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/ucc_geth_ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/ucc_geth_ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/stddef.h>
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/asix.c linux-libre-2.6.34-gnu1/drivers/net/usb/asix.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/asix.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/asix.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/usb.h>
 #include <linux/crc32.h>
 #include <linux/usb/usbnet.h>
+#include <linux/slab.h>
 
 #define DRIVER_VERSION "14-Jun-2006"
 static const char driver_name [] = "asix";
@@ -54,6 +55,7 @@ static const char driver_name [] = "asix
 #define AX_CMD_WRITE_IPG0		0x12
 #define AX_CMD_WRITE_IPG1		0x13
 #define AX_CMD_READ_NODE_ID		0x13
+#define AX_CMD_WRITE_NODE_ID		0x14
 #define AX_CMD_WRITE_IPG2		0x14
 #define AX_CMD_WRITE_MULTI_FILTER	0x16
 #define AX88172_CMD_READ_NODE_ID	0x17
@@ -165,6 +167,7 @@ static const char driver_name [] = "asix
 /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
 struct asix_data {
 	u8 multi_filter[AX_MCAST_FILTER_SIZE];
+	u8 mac_addr[ETH_ALEN];
 	u8 phymode;
 	u8 ledmode;
 	u8 eeprom_len;
@@ -184,8 +187,8 @@ static int asix_read_cmd(struct usbnet *
 	void *buf;
 	int err = -ENOMEM;
 
-	devdbg(dev,"asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d",
-		cmd, value, index, size);
+	netdev_dbg(dev->net, "asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
+		   cmd, value, index, size);
 
 	buf = kmalloc(size, GFP_KERNEL);
 	if (!buf)
@@ -217,8 +220,8 @@ static int asix_write_cmd(struct usbnet
 	void *buf = NULL;
 	int err = -ENOMEM;
 
-	devdbg(dev,"asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d",
-		cmd, value, index, size);
+	netdev_dbg(dev->net, "asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
+		   cmd, value, index, size);
 
 	if (data) {
 		buf = kmalloc(size, GFP_KERNEL);
@@ -264,15 +267,15 @@ asix_write_cmd_async(struct usbnet *dev,
 	int status;
 	struct urb *urb;
 
-	devdbg(dev,"asix_write_cmd_async() cmd=0x%02x value=0x%04x index=0x%04x size=%d",
-		cmd, value, index, size);
+	netdev_dbg(dev->net, "asix_write_cmd_async() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
+		   cmd, value, index, size);
 	if ((urb = usb_alloc_urb(0, GFP_ATOMIC)) == NULL) {
-		deverr(dev, "Error allocating URB in write_cmd_async!");
+		netdev_err(dev->net, "Error allocating URB in write_cmd_async!\n");
 		return;
 	}
 
 	if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) {
-		deverr(dev, "Failed to allocate memory for control request");
+		netdev_err(dev->net, "Failed to allocate memory for control request\n");
 		usb_free_urb(urb);
 		return;
 	}
@@ -289,8 +292,8 @@ asix_write_cmd_async(struct usbnet *dev,
 			     asix_async_cmd_callback, req);
 
 	if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
-		deverr(dev, "Error submitting the control message: status=%d",
-				status);
+		netdev_err(dev->net, "Error submitting the control message: status=%d\n",
+			   status);
 		kfree(req);
 		usb_free_urb(urb);
 	}
@@ -314,7 +317,7 @@ static int asix_rx_fixup(struct usbnet *
 	while (skb->len > 0) {
 		if ((short)(header & 0x0000ffff) !=
 		    ~((short)((header & 0xffff0000) >> 16))) {
-			deverr(dev,"asix_rx_fixup() Bad Header Length");
+			netdev_err(dev->net, "asix_rx_fixup() Bad Header Length\n");
 		}
 		/* get the packet length */
 		size = (u16) (header & 0x0000ffff);
@@ -322,7 +325,8 @@ static int asix_rx_fixup(struct usbnet *
 		if ((skb->len) - ((size + 1) & 0xfffe) == 0)
 			return 2;
 		if (size > ETH_FRAME_LEN) {
-			deverr(dev,"asix_rx_fixup() Bad RX Length %d", size);
+			netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n",
+				   size);
 			return 0;
 		}
 		ax_skb = skb_clone(skb, GFP_ATOMIC);
@@ -348,7 +352,8 @@ static int asix_rx_fixup(struct usbnet *
 	}
 
 	if (skb->len < 0) {
-		deverr(dev,"asix_rx_fixup() Bad SKB Length %d", skb->len);
+		netdev_err(dev->net, "asix_rx_fixup() Bad SKB Length %d\n",
+			   skb->len);
 		return 0;
 	}
 	return 1;
@@ -409,7 +414,7 @@ static void asix_status(struct usbnet *d
 			usbnet_defer_kevent (dev, EVENT_LINK_RESET );
 		} else
 			netif_carrier_off(dev->net);
-		devdbg(dev, "Link Status is: %d", link);
+		netdev_dbg(dev->net, "Link Status is: %d\n", link);
 	}
 }
 
@@ -418,7 +423,7 @@ static inline int asix_set_sw_mii(struct
 	int ret;
 	ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL);
 	if (ret < 0)
-		deverr(dev, "Failed to enable software MII access");
+		netdev_err(dev->net, "Failed to enable software MII access\n");
 	return ret;
 }
 
@@ -427,7 +432,7 @@ static inline int asix_set_hw_mii(struct
 	int ret;
 	ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL);
 	if (ret < 0)
-		deverr(dev, "Failed to enable hardware MII access");
+		netdev_err(dev->net, "Failed to enable hardware MII access\n");
 	return ret;
 }
 
@@ -436,13 +441,14 @@ static inline int asix_get_phy_addr(stru
 	u8 buf[2];
 	int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf);
 
-	devdbg(dev, "asix_get_phy_addr()");
+	netdev_dbg(dev->net, "asix_get_phy_addr()\n");
 
 	if (ret < 0) {
-		deverr(dev, "Error reading PHYID register: %02x", ret);
+		netdev_err(dev->net, "Error reading PHYID register: %02x\n", ret);
 		goto out;
 	}
-	devdbg(dev, "asix_get_phy_addr() returning 0x%04x", *((__le16 *)buf));
+	netdev_dbg(dev->net, "asix_get_phy_addr() returning 0x%04x\n",
+		   *((__le16 *)buf));
 	ret = buf[1];
 
 out:
@@ -455,7 +461,7 @@ static int asix_sw_reset(struct usbnet *
 
         ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL);
 	if (ret < 0)
-		deverr(dev,"Failed to send software reset: %02x", ret);
+		netdev_err(dev->net, "Failed to send software reset: %02x\n", ret);
 
 	return ret;
 }
@@ -466,7 +472,7 @@ static u16 asix_read_rx_ctl(struct usbne
 	int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v);
 
 	if (ret < 0) {
-		deverr(dev, "Error reading RX_CTL register: %02x", ret);
+		netdev_err(dev->net, "Error reading RX_CTL register: %02x\n", ret);
 		goto out;
 	}
 	ret = le16_to_cpu(v);
@@ -478,11 +484,11 @@ static int asix_write_rx_ctl(struct usbn
 {
 	int ret;
 
-	devdbg(dev,"asix_write_rx_ctl() - mode = 0x%04x", mode);
+	netdev_dbg(dev->net, "asix_write_rx_ctl() - mode = 0x%04x\n", mode);
 	ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL);
 	if (ret < 0)
-		deverr(dev, "Failed to write RX_CTL mode to 0x%04x: %02x",
-		       mode, ret);
+		netdev_err(dev->net, "Failed to write RX_CTL mode to 0x%04x: %02x\n",
+			   mode, ret);
 
 	return ret;
 }
@@ -493,7 +499,8 @@ static u16 asix_read_medium_status(struc
 	int ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v);
 
 	if (ret < 0) {
-		deverr(dev, "Error reading Medium Status register: %02x", ret);
+		netdev_err(dev->net, "Error reading Medium Status register: %02x\n",
+			   ret);
 		goto out;
 	}
 	ret = le16_to_cpu(v);
@@ -505,11 +512,11 @@ static int asix_write_medium_mode(struct
 {
 	int ret;
 
-	devdbg(dev,"asix_write_medium_mode() - mode = 0x%04x", mode);
+	netdev_dbg(dev->net, "asix_write_medium_mode() - mode = 0x%04x\n", mode);
 	ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
 	if (ret < 0)
-		deverr(dev, "Failed to write Medium Mode mode to 0x%04x: %02x",
-			mode, ret);
+		netdev_err(dev->net, "Failed to write Medium Mode mode to 0x%04x: %02x\n",
+			   mode, ret);
 
 	return ret;
 }
@@ -518,11 +525,11 @@ static int asix_write_gpio(struct usbnet
 {
 	int ret;
 
-	devdbg(dev,"asix_write_gpio() - value = 0x%04x", value);
+	netdev_dbg(dev->net, "asix_write_gpio() - value = 0x%04x\n", value);
 	ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL);
 	if (ret < 0)
-		deverr(dev, "Failed to write GPIO value 0x%04x: %02x",
-			value, ret);
+		netdev_err(dev->net, "Failed to write GPIO value 0x%04x: %02x\n",
+			   value, ret);
 
 	if (sleep)
 		msleep(sleep);
@@ -542,29 +549,27 @@ static void asix_set_multicast(struct ne
 	if (net->flags & IFF_PROMISC) {
 		rx_ctl |= AX_RX_CTL_PRO;
 	} else if (net->flags & IFF_ALLMULTI ||
-		   net->mc_count > AX_MAX_MCAST) {
+		   netdev_mc_count(net) > AX_MAX_MCAST) {
 		rx_ctl |= AX_RX_CTL_AMALL;
-	} else if (net->mc_count == 0) {
+	} else if (netdev_mc_empty(net)) {
 		/* just broadcast and directed */
 	} else {
 		/* We use the 20 byte dev->data
 		 * for our 8 byte filter buffer
 		 * to avoid allocating memory that
 		 * is tricky to free later */
-		struct dev_mc_list *mc_list = net->mc_list;
+		struct dev_mc_list *mc_list;
 		u32 crc_bits;
-		int i;
 
 		memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE);
 
 		/* Build the multicast hash filter. */
-		for (i = 0; i < net->mc_count; i++) {
+		netdev_for_each_mc_addr(mc_list, net) {
 			crc_bits =
 			    ether_crc(ETH_ALEN,
 				      mc_list->dmi_addr) >> 26;
 			data->multi_filter[crc_bits >> 3] |=
 			    1 << (crc_bits & 7);
-			mc_list = mc_list->next;
 		}
 
 		asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
@@ -588,7 +593,8 @@ static int asix_mdio_read(struct net_dev
 	asix_set_hw_mii(dev);
 	mutex_unlock(&dev->phy_mutex);
 
-	devdbg(dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", phy_id, loc, le16_to_cpu(res));
+	netdev_dbg(dev->net, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
+		   phy_id, loc, le16_to_cpu(res));
 
 	return le16_to_cpu(res);
 }
@@ -599,7 +605,8 @@ asix_mdio_write(struct net_device *netde
 	struct usbnet *dev = netdev_priv(netdev);
 	__le16 res = cpu_to_le16(val);
 
-	devdbg(dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", phy_id, loc, val);
+	netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
+		   phy_id, loc, val);
 	mutex_lock(&dev->phy_mutex);
 	asix_set_sw_mii(dev);
 	asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res);
@@ -728,6 +735,30 @@ static int asix_ioctl (struct net_device
 	return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
 }
 
+static int asix_set_mac_address(struct net_device *net, void *p)
+{
+	struct usbnet *dev = netdev_priv(net);
+	struct asix_data *data = (struct asix_data *)&dev->data;
+	struct sockaddr *addr = p;
+
+	if (netif_running(net))
+		return -EBUSY;
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(net->dev_addr, addr->sa_data, ETH_ALEN);
+
+	/* We use the 20 byte dev->data
+	 * for our 6 byte mac buffer
+	 * to avoid allocating memory that
+	 * is tricky to free later */
+	memcpy(data->mac_addr, addr->sa_data, ETH_ALEN);
+	asix_write_cmd_async(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN,
+							data->mac_addr);
+
+	return 0;
+}
+
 /* We need to override some ethtool_ops so we require our
    own structure so we don't interfere with other usbnet
    devices that may be connected at the same time. */
@@ -754,29 +785,27 @@ static void ax88172_set_multicast(struct
 	if (net->flags & IFF_PROMISC) {
 		rx_ctl |= 0x01;
 	} else if (net->flags & IFF_ALLMULTI ||
-		   net->mc_count > AX_MAX_MCAST) {
+		   netdev_mc_count(net) > AX_MAX_MCAST) {
 		rx_ctl |= 0x02;
-	} else if (net->mc_count == 0) {
+	} else if (netdev_mc_empty(net)) {
 		/* just broadcast and directed */
 	} else {
 		/* We use the 20 byte dev->data
 		 * for our 8 byte filter buffer
 		 * to avoid allocating memory that
 		 * is tricky to free later */
-		struct dev_mc_list *mc_list = net->mc_list;
+		struct dev_mc_list *mc_list;
 		u32 crc_bits;
-		int i;
 
 		memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE);
 
 		/* Build the multicast hash filter. */
-		for (i = 0; i < net->mc_count; i++) {
+		netdev_for_each_mc_addr(mc_list, net) {
 			crc_bits =
 			    ether_crc(ETH_ALEN,
 				      mc_list->dmi_addr) >> 26;
 			data->multi_filter[crc_bits >> 3] |=
 			    1 << (crc_bits & 7);
-			mc_list = mc_list->next;
 		}
 
 		asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
@@ -800,7 +829,8 @@ static int ax88172_link_reset(struct usb
 	if (ecmd.duplex != DUPLEX_FULL)
 		mode |= ~AX88172_MEDIUM_FD;
 
-	devdbg(dev, "ax88172_link_reset() speed: %d duplex: %d setting mode to 0x%04x", ecmd.speed, ecmd.duplex, mode);
+	netdev_dbg(dev->net, "ax88172_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n",
+		   ecmd.speed, ecmd.duplex, mode);
 
 	asix_write_medium_mode(dev, mode);
 
@@ -902,7 +932,8 @@ static int ax88772_link_reset(struct usb
 	if (ecmd.duplex != DUPLEX_FULL)
 		mode &= ~AX_MEDIUM_FD;
 
-	devdbg(dev, "ax88772_link_reset() speed: %d duplex: %d setting mode to 0x%04x", ecmd.speed, ecmd.duplex, mode);
+	netdev_dbg(dev->net, "ax88772_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n",
+		   ecmd.speed, ecmd.duplex, mode);
 
 	asix_write_medium_mode(dev, mode);
 
@@ -915,7 +946,7 @@ static const struct net_device_ops ax887
 	.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_set_mac_address 	= asix_set_mac_address,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_do_ioctl		= asix_ioctl,
 	.ndo_set_multicast_list = asix_set_multicast,
@@ -1059,10 +1090,10 @@ static int marvell_phy_init(struct usbne
 	struct asix_data *data = (struct asix_data *)&dev->data;
 	u16 reg;
 
-	devdbg(dev,"marvell_phy_init()");
+	netdev_dbg(dev->net, "marvell_phy_init()\n");
 
 	reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_MARVELL_STATUS);
-	devdbg(dev,"MII_MARVELL_STATUS = 0x%04x", reg);
+	netdev_dbg(dev->net, "MII_MARVELL_STATUS = 0x%04x\n", reg);
 
 	asix_mdio_write(dev->net, dev->mii.phy_id, MII_MARVELL_CTRL,
 			MARVELL_CTRL_RXDELAY | MARVELL_CTRL_TXDELAY);
@@ -1070,7 +1101,7 @@ static int marvell_phy_init(struct usbne
 	if (data->ledmode) {
 		reg = asix_mdio_read(dev->net, dev->mii.phy_id,
 			MII_MARVELL_LED_CTRL);
-		devdbg(dev,"MII_MARVELL_LED_CTRL (1) = 0x%04x", reg);
+		netdev_dbg(dev->net, "MII_MARVELL_LED_CTRL (1) = 0x%04x\n", reg);
 
 		reg &= 0xf8ff;
 		reg |= (1 + 0x0100);
@@ -1079,7 +1110,7 @@ static int marvell_phy_init(struct usbne
 
 		reg = asix_mdio_read(dev->net, dev->mii.phy_id,
 			MII_MARVELL_LED_CTRL);
-		devdbg(dev,"MII_MARVELL_LED_CTRL (2) = 0x%04x", reg);
+		netdev_dbg(dev->net, "MII_MARVELL_LED_CTRL (2) = 0x%04x\n", reg);
 		reg &= 0xfc0f;
 	}
 
@@ -1090,7 +1121,7 @@ static int marvell_led_status(struct usb
 {
 	u16 reg = asix_mdio_read(dev->net, dev->mii.phy_id, MARVELL_LED_MANUAL);
 
-	devdbg(dev, "marvell_led_status() read 0x%04x", reg);
+	netdev_dbg(dev->net, "marvell_led_status() read 0x%04x\n", reg);
 
 	/* Clear out the center LED bits - 0x03F0 */
 	reg &= 0xfc0f;
@@ -1106,7 +1137,7 @@ static int marvell_led_status(struct usb
 			reg |= 0x02f0;
 	}
 
-	devdbg(dev, "marvell_led_status() writing 0x%04x", reg);
+	netdev_dbg(dev->net, "marvell_led_status() writing 0x%04x\n", reg);
 	asix_mdio_write(dev->net, dev->mii.phy_id, MARVELL_LED_MANUAL, reg);
 
 	return 0;
@@ -1118,7 +1149,7 @@ static int ax88178_link_reset(struct usb
 	struct ethtool_cmd ecmd;
 	struct asix_data *data = (struct asix_data *)&dev->data;
 
-	devdbg(dev,"ax88178_link_reset()");
+	netdev_dbg(dev->net, "ax88178_link_reset()\n");
 
 	mii_check_media(&dev->mii, 1, 1);
 	mii_ethtool_gset(&dev->mii, &ecmd);
@@ -1138,7 +1169,8 @@ static int ax88178_link_reset(struct usb
 	else
 		mode &= ~AX_MEDIUM_FD;
 
-	devdbg(dev, "ax88178_link_reset() speed: %d duplex: %d setting mode to 0x%04x", ecmd.speed, ecmd.duplex, mode);
+	netdev_dbg(dev->net, "ax88178_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n",
+		   ecmd.speed, ecmd.duplex, mode);
 
 	asix_write_medium_mode(dev, mode);
 
@@ -1188,7 +1220,7 @@ static int ax88178_change_mtu(struct net
 	struct usbnet *dev = netdev_priv(net);
 	int ll_mtu = new_mtu + net->hard_header_len + 4;
 
-	devdbg(dev, "ax88178_change_mtu() new_mtu=%d", new_mtu);
+	netdev_dbg(dev->net, "ax88178_change_mtu() new_mtu=%d\n", new_mtu);
 
 	if (new_mtu <= 0 || ll_mtu > 16384)
 		return -EINVAL;
@@ -1208,7 +1240,7 @@ static const struct net_device_ops ax881
 	.ndo_stop		= usbnet_stop,
 	.ndo_start_xmit		= usbnet_start_xmit,
 	.ndo_tx_timeout		= usbnet_tx_timeout,
-	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_set_mac_address 	= asix_set_mac_address,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_multicast_list = asix_set_multicast,
 	.ndo_do_ioctl 		= asix_ioctl,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/catc.c linux-libre-2.6.34-gnu1/drivers/net/usb/catc.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/catc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/catc.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,7 +36,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
@@ -44,6 +43,7 @@
 #include <linux/ethtool.h>
 #include <linux/crc32.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 
 #undef DEBUG
@@ -632,7 +632,6 @@ static void catc_set_multicast_list(stru
 	struct dev_mc_list *mc;
 	u8 broadcast[6];
 	u8 rx = RxEnable | RxPolarity | RxMultiCast;
-	int i;
 
 	memset(broadcast, 0xff, 6);
 	memset(catc->multicast, 0, 64);
@@ -648,7 +647,7 @@ static void catc_set_multicast_list(stru
 	if (netdev->flags & IFF_ALLMULTI) {
 		memset(catc->multicast, 0xff, 64);
 	} else {
-		for (i = 0, mc = netdev->mc_list; mc && i < netdev->mc_count; i++, mc = mc->next) {
+		netdev_for_each_mc_addr(mc, netdev) {
 			u32 crc = ether_crc_le(6, mc->dmi_addr);
 			if (!catc->is_f5u011) {
 				catc->multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7);
@@ -897,11 +896,9 @@ static int catc_probe(struct usb_interfa
 		f5u011_rxmode(catc, catc->rxmode);
 	}
 	dbg("Init done.");
-	printk(KERN_INFO "%s: %s USB Ethernet at usb-%s-%s, ",
+	printk(KERN_INFO "%s: %s USB Ethernet at usb-%s-%s, %pM.\n",
 	       netdev->name, (catc->is_f5u011) ? "Belkin F5U011" : "CATC EL1210A NetMate",
-	       usbdev->bus->bus_name, usbdev->devpath);
-	for (i = 0; i < 5; i++) printk("%2.2x:", netdev->dev_addr[i]);
-	printk("%2.2x.\n", netdev->dev_addr[i]);
+	       usbdev->bus->bus_name, usbdev->devpath, netdev->dev_addr);
 	usb_set_intfdata(intf, catc);
 
 	SET_NETDEV_DEV(netdev, &intf->dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/cdc_eem.c linux-libre-2.6.34-gnu1/drivers/net/usb/cdc_eem.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/cdc_eem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/cdc_eem.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/crc32.h>
 #include <linux/usb/cdc.h>
 #include <linux/usb/usbnet.h>
+#include <linux/gfp.h>
 
 
 /*
@@ -73,7 +74,7 @@ static void eem_linkcmd(struct usbnet *d
 		usb_free_urb(urb);
 fail:
 		dev_kfree_skb(skb);
-		devwarn(dev, "link cmd failure\n");
+		netdev_warn(dev->net, "link cmd failure\n");
 		return;
 	}
 }
@@ -212,7 +213,8 @@ static int eem_rx_fixup(struct usbnet *d
 			 * b15:		1 (EEM command)
 			 */
 			if (header & BIT(14)) {
-				devdbg(dev, "reserved command %04x\n", header);
+				netdev_dbg(dev->net, "reserved command %04x\n",
+					   header);
 				continue;
 			}
 
@@ -255,8 +257,9 @@ static int eem_rx_fixup(struct usbnet *d
 			case 1:		/* Echo response */
 			case 5:		/* Tickle */
 			default:	/* reserved */
-				devwarn(dev, "unexpected link command %d\n",
-						bmEEMCmd);
+				netdev_warn(dev->net,
+					    "unexpected link command %d\n",
+					    bmEEMCmd);
 				continue;
 			}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/cdc_ether.c linux-libre-2.6.34-gnu1/drivers/net/usb/cdc_ether.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/cdc_ether.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/cdc_ether.c	2010-05-16 17:17:36.000000000 -0400
@@ -339,10 +339,10 @@ EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
 
 static void dumpspeed(struct usbnet *dev, __le32 *speeds)
 {
-	if (netif_msg_timer(dev))
-		devinfo(dev, "link speeds: %u kbps up, %u kbps down",
-			__le32_to_cpu(speeds[0]) / 1000,
-		__le32_to_cpu(speeds[1]) / 1000);
+	netif_info(dev, timer, dev->net,
+		   "link speeds: %u kbps up, %u kbps down\n",
+		   __le32_to_cpu(speeds[0]) / 1000,
+		   __le32_to_cpu(speeds[1]) / 1000);
 }
 
 static void cdc_status(struct usbnet *dev, struct urb *urb)
@@ -361,18 +361,16 @@ static void cdc_status(struct usbnet *de
 	event = urb->transfer_buffer;
 	switch (event->bNotificationType) {
 	case USB_CDC_NOTIFY_NETWORK_CONNECTION:
-		if (netif_msg_timer(dev))
-			devdbg(dev, "CDC: carrier %s",
-					event->wValue ? "on" : "off");
+		netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
+			  event->wValue ? "on" : "off");
 		if (event->wValue)
 			netif_carrier_on(dev->net);
 		else
 			netif_carrier_off(dev->net);
 		break;
 	case USB_CDC_NOTIFY_SPEED_CHANGE:	/* tx/rx rates */
-		if (netif_msg_timer(dev))
-			devdbg(dev, "CDC: speed change (len %d)",
-					urb->actual_length);
+		netif_dbg(dev, timer, dev->net, "CDC: speed change (len %d)\n",
+			  urb->actual_length);
 		if (urb->actual_length != (sizeof *event + 8))
 			set_bit(EVENT_STS_SPLIT, &dev->flags);
 		else
@@ -382,8 +380,8 @@ static void cdc_status(struct usbnet *de
 	 * but there are no standard formats for the response data.
 	 */
 	default:
-		deverr(dev, "CDC: unexpected notification %02x!",
-				 event->bNotificationType);
+		netdev_err(dev->net, "CDC: unexpected notification %02x!\n",
+			   event->bNotificationType);
 		break;
 	}
 }
@@ -433,6 +431,7 @@ static const struct driver_info mbm_info
 	.bind = 	cdc_bind,
 	.unbind =	usbnet_cdc_unbind,
 	.status =	cdc_status,
+	.manage_power =	cdc_manage_power,
 };
 
 /*-------------------------------------------------------------------------*/
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/cdc-phonet.c linux-libre-2.6.34-gnu1/drivers/net/usb/cdc-phonet.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/cdc-phonet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/cdc-phonet.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/usb.h>
 #include <linux/usb/cdc.h>
 #include <linux/netdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/dm9601.c linux-libre-2.6.34-gnu1/drivers/net/usb/dm9601.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/dm9601.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/dm9601.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/usb.h>
 #include <linux/crc32.h>
 #include <linux/usb/usbnet.h>
+#include <linux/slab.h>
 
 /* datasheet:
  http://ptm2.cc.utu.fi/ftp/network/cards/DM9601/From_NET/DM9601-DS-P01-930914.pdf
@@ -58,7 +59,7 @@ static int dm_read(struct usbnet *dev, u
 	void *buf;
 	int err = -ENOMEM;
 
-	devdbg(dev, "dm_read() reg=0x%02x length=%d", reg, length);
+	netdev_dbg(dev->net, "dm_read() reg=0x%02x length=%d\n", reg, length);
 
 	buf = kmalloc(length, GFP_KERNEL);
 	if (!buf)
@@ -89,7 +90,7 @@ static int dm_write(struct usbnet *dev,
 	void *buf = NULL;
 	int err = -ENOMEM;
 
-	devdbg(dev, "dm_write() reg=0x%02x, length=%d", reg, length);
+	netdev_dbg(dev->net, "dm_write() reg=0x%02x, length=%d\n", reg, length);
 
 	if (data) {
 		buf = kmalloc(length, GFP_KERNEL);
@@ -112,7 +113,8 @@ static int dm_write(struct usbnet *dev,
 
 static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value)
 {
-	devdbg(dev, "dm_write_reg() reg=0x%02x, value=0x%02x", reg, value);
+	netdev_dbg(dev->net, "dm_write_reg() reg=0x%02x, value=0x%02x\n",
+		   reg, value);
 	return usb_control_msg(dev->udev,
 			       usb_sndctrlpipe(dev->udev, 0),
 			       DM_WRITE_REG,
@@ -142,13 +144,13 @@ static void dm_write_async_helper(struct
 
 	urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!urb) {
-		deverr(dev, "Error allocating URB in dm_write_async_helper!");
+		netdev_err(dev->net, "Error allocating URB in dm_write_async_helper!\n");
 		return;
 	}
 
 	req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
 	if (!req) {
-		deverr(dev, "Failed to allocate memory for control request");
+		netdev_err(dev->net, "Failed to allocate memory for control request\n");
 		usb_free_urb(urb);
 		return;
 	}
@@ -166,8 +168,8 @@ static void dm_write_async_helper(struct
 
 	status = usb_submit_urb(urb, GFP_ATOMIC);
 	if (status < 0) {
-		deverr(dev, "Error submitting the control message: status=%d",
-		       status);
+		netdev_err(dev->net, "Error submitting the control message: status=%d\n",
+			   status);
 		kfree(req);
 		usb_free_urb(urb);
 	}
@@ -175,15 +177,15 @@ static void dm_write_async_helper(struct
 
 static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
 {
-	devdbg(dev, "dm_write_async() reg=0x%02x length=%d", reg, length);
+	netdev_dbg(dev->net, "dm_write_async() reg=0x%02x length=%d\n", reg, length);
 
 	dm_write_async_helper(dev, reg, 0, length, data);
 }
 
 static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
 {
-	devdbg(dev, "dm_write_reg_async() reg=0x%02x value=0x%02x",
-	       reg, value);
+	netdev_dbg(dev->net, "dm_write_reg_async() reg=0x%02x value=0x%02x\n",
+		   reg, value);
 
 	dm_write_async_helper(dev, reg, value, 0, NULL);
 }
@@ -211,7 +213,7 @@ static int dm_read_shared_word(struct us
 	}
 
 	if (i == DM_TIMEOUT) {
-		deverr(dev, "%s read timed out!", phy ? "phy" : "eeprom");
+		netdev_err(dev->net, "%s read timed out!\n", phy ? "phy" : "eeprom");
 		ret = -EIO;
 		goto out;
 	}
@@ -219,8 +221,8 @@ static int dm_read_shared_word(struct us
 	dm_write_reg(dev, DM_SHARED_CTRL, 0x0);
 	ret = dm_read(dev, DM_SHARED_DATA, 2, value);
 
-	devdbg(dev, "read shared %d 0x%02x returned 0x%04x, %d",
-	       phy, reg, *value, ret);
+	netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n",
+		   phy, reg, *value, ret);
 
  out:
 	mutex_unlock(&dev->phy_mutex);
@@ -238,7 +240,7 @@ static int dm_write_shared_word(struct u
 		goto out;
 
 	dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg);
-	dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1c : 0x14);
+	dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1a : 0x12);
 
 	for (i = 0; i < DM_TIMEOUT; i++) {
 		u8 tmp;
@@ -254,7 +256,7 @@ static int dm_write_shared_word(struct u
 	}
 
 	if (i == DM_TIMEOUT) {
-		deverr(dev, "%s write timed out!", phy ? "phy" : "eeprom");
+		netdev_err(dev->net, "%s write timed out!\n", phy ? "phy" : "eeprom");
 		ret = -EIO;
 		goto out;
 	}
@@ -304,15 +306,15 @@ static int dm9601_mdio_read(struct net_d
 	__le16 res;
 
 	if (phy_id) {
-		devdbg(dev, "Only internal phy supported");
+		netdev_dbg(dev->net, "Only internal phy supported\n");
 		return 0;
 	}
 
 	dm_read_shared_word(dev, 1, loc, &res);
 
-	devdbg(dev,
-	       "dm9601_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x",
-	       phy_id, loc, le16_to_cpu(res));
+	netdev_dbg(dev->net,
+		   "dm9601_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
+		   phy_id, loc, le16_to_cpu(res));
 
 	return le16_to_cpu(res);
 }
@@ -324,12 +326,12 @@ static void dm9601_mdio_write(struct net
 	__le16 res = cpu_to_le16(val);
 
 	if (phy_id) {
-		devdbg(dev, "Only internal phy supported");
+		netdev_dbg(dev->net, "Only internal phy supported\n");
 		return;
 	}
 
-	devdbg(dev,"dm9601_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x",
-	       phy_id, loc, val);
+	netdev_dbg(dev->net, "dm9601_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
+		   phy_id, loc, val);
 
 	dm_write_shared_word(dev, 1, loc, res);
 }
@@ -381,13 +383,13 @@ static void dm9601_set_multicast(struct
 
 	if (net->flags & IFF_PROMISC) {
 		rx_ctl |= 0x02;
-	} else if (net->flags & IFF_ALLMULTI || net->mc_count > DM_MAX_MCAST) {
+	} else if (net->flags & IFF_ALLMULTI ||
+		   netdev_mc_count(net) > DM_MAX_MCAST) {
 		rx_ctl |= 0x04;
-	} else if (net->mc_count) {
-		struct dev_mc_list *mc_list = net->mc_list;
-		int i;
+	} else if (!netdev_mc_empty(net)) {
+		struct dev_mc_list *mc_list;
 
-		for (i = 0; i < net->mc_count; i++, mc_list = mc_list->next) {
+		netdev_for_each_mc_addr(mc_list, net) {
 			u32 crc = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26;
 			hashes[crc >> 3] |= 1 << (crc & 0x7);
 		}
@@ -592,7 +594,7 @@ static void dm9601_status(struct usbnet
 		}
 		else
 			netif_carrier_off(dev->net);
-		devdbg(dev, "Link Status is: %d", link);
+		netdev_dbg(dev->net, "Link Status is: %d\n", link);
 	}
 }
 
@@ -603,8 +605,8 @@ static int dm9601_link_reset(struct usbn
 	mii_check_media(&dev->mii, 1, 1);
 	mii_ethtool_gset(&dev->mii, &ecmd);
 
-	devdbg(dev, "link_reset() speed: %d duplex: %d",
-	       ecmd.speed, ecmd.duplex);
+	netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n",
+		   ecmd.speed, ecmd.duplex);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/gl620a.c linux-libre-2.6.34-gnu1/drivers/net/usb/gl620a.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/gl620a.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/gl620a.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/usb/usbnet.h>
+#include <linux/gfp.h>
 
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/hso.c linux-libre-2.6.34-gnu1/drivers/net/usb/hso.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/hso.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/hso.c	2010-05-16 17:17:36.000000000 -0400
@@ -1155,9 +1155,6 @@ static void _hso_serial_set_termios(stru
 static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb)
 {
 	int result;
-#ifdef CONFIG_HSO_AUTOPM
-	usb_mark_last_busy(urb->dev);
-#endif
 	/* We are done with this URB, resubmit it. Prep the USB to wait for
 	 * another frame */
 	usb_fill_bulk_urb(urb, serial->parent->usb,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/int51x1.c linux-libre-2.6.34-gnu1/drivers/net/usb/int51x1.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/int51x1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/int51x1.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
+#include <linux/slab.h>
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/usb/usbnet.h>
@@ -51,7 +52,7 @@ static int int51x1_rx_fixup(struct usbne
 	int len;
 
 	if (!(pskb_may_pull(skb, INT51X1_HEADER_SIZE))) {
-		deverr(dev, "unexpected tiny rx frame");
+		netdev_err(dev->net, "unexpected tiny rx frame\n");
 		return 0;
 	}
 
@@ -138,25 +139,25 @@ static void int51x1_set_multicast(struct
 	if (netdev->flags & IFF_PROMISC) {
 		/* do not expect to see traffic of other PLCs */
 		filter |= PACKET_TYPE_PROMISCUOUS;
-		devinfo(dev, "promiscuous mode enabled");
-	} else if (netdev->mc_count ||
+		netdev_info(dev->net, "promiscuous mode enabled\n");
+	} else if (!netdev_mc_empty(netdev) ||
 		  (netdev->flags & IFF_ALLMULTI)) {
 		filter |= PACKET_TYPE_ALL_MULTICAST;
-		devdbg(dev, "receive all multicast enabled");
+		netdev_dbg(dev->net, "receive all multicast enabled\n");
 	} else {
 		/* ~PROMISCUOUS, ~MULTICAST */
-		devdbg(dev, "receive own packets only");
+		netdev_dbg(dev->net, "receive own packets only\n");
 	}
 
 	urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!urb) {
-		devwarn(dev, "Error allocating URB");
+		netdev_warn(dev->net, "Error allocating URB\n");
 		return;
 	}
 
 	req = kmalloc(sizeof(*req), GFP_ATOMIC);
 	if (!req) {
-		devwarn(dev, "Error allocating control msg");
+		netdev_warn(dev->net, "Error allocating control msg\n");
 		goto out;
 	}
 
@@ -173,7 +174,8 @@ static void int51x1_set_multicast(struct
 
 	status = usb_submit_urb(urb, GFP_ATOMIC);
 	if (status < 0) {
-		devwarn(dev, "Error submitting control msg, sts=%d", status);
+		netdev_warn(dev->net, "Error submitting control msg, sts=%d\n",
+			    status);
 		goto out1;
 	}
 	return;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/ipheth.c linux-libre-2.6.34-gnu1/drivers/net/usb/ipheth.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/ipheth.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/ipheth.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,569 @@
+/*
+ * ipheth.c - Apple iPhone USB Ethernet driver
+ *
+ * Copyright (c) 2009 Diego Giagio <diego@giagio.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.
+ * 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.
+ * 3. Neither the name of GIAGIO.COM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * The provided data structures and external interfaces from this code
+ * are not restricted to be used by modules with a GPL compatible license.
+ *
+ * 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.
+ *
+ *
+ * Attention: iPhone device must be paired, otherwise it won't respond to our
+ * driver. For more info: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/usb.h>
+#include <linux/workqueue.h>
+
+#define USB_VENDOR_APPLE        0x05ac
+#define USB_PRODUCT_IPHONE      0x1290
+#define USB_PRODUCT_IPHONE_3G   0x1292
+#define USB_PRODUCT_IPHONE_3GS  0x1294
+
+#define IPHETH_USBINTF_CLASS    255
+#define IPHETH_USBINTF_SUBCLASS 253
+#define IPHETH_USBINTF_PROTO    1
+
+#define IPHETH_BUF_SIZE         1516
+#define IPHETH_TX_TIMEOUT       (5 * HZ)
+
+#define IPHETH_INTFNUM          2
+#define IPHETH_ALT_INTFNUM      1
+
+#define IPHETH_CTRL_ENDP        0x00
+#define IPHETH_CTRL_BUF_SIZE    0x40
+#define IPHETH_CTRL_TIMEOUT     (5 * HZ)
+
+#define IPHETH_CMD_GET_MACADDR   0x00
+#define IPHETH_CMD_CARRIER_CHECK 0x45
+
+#define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ)
+#define IPHETH_CARRIER_ON       0x04
+
+static struct usb_device_id ipheth_table[] = {
+	{ USB_DEVICE_AND_INTERFACE_INFO(
+		USB_VENDOR_APPLE, USB_PRODUCT_IPHONE,
+		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+		IPHETH_USBINTF_PROTO) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(
+		USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3G,
+		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+		IPHETH_USBINTF_PROTO) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(
+		USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3GS,
+		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+		IPHETH_USBINTF_PROTO) },
+	{ }
+};
+MODULE_DEVICE_TABLE(usb, ipheth_table);
+
+struct ipheth_device {
+	struct usb_device *udev;
+	struct usb_interface *intf;
+	struct net_device *net;
+	struct sk_buff *tx_skb;
+	struct urb *tx_urb;
+	struct urb *rx_urb;
+	unsigned char *tx_buf;
+	unsigned char *rx_buf;
+	unsigned char *ctrl_buf;
+	u8 bulk_in;
+	u8 bulk_out;
+	struct delayed_work carrier_work;
+};
+
+static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags);
+
+static int ipheth_alloc_urbs(struct ipheth_device *iphone)
+{
+	struct urb *tx_urb = NULL;
+	struct urb *rx_urb = NULL;
+	u8 *tx_buf = NULL;
+	u8 *rx_buf = NULL;
+
+	tx_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (tx_urb == NULL)
+		goto error_nomem;
+
+	rx_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (rx_urb == NULL)
+		goto free_tx_urb;
+
+	tx_buf = usb_buffer_alloc(iphone->udev,
+				  IPHETH_BUF_SIZE,
+				  GFP_KERNEL,
+				  &tx_urb->transfer_dma);
+	if (tx_buf == NULL)
+		goto free_rx_urb;
+
+	rx_buf = usb_buffer_alloc(iphone->udev,
+				  IPHETH_BUF_SIZE,
+				  GFP_KERNEL,
+				  &rx_urb->transfer_dma);
+	if (rx_buf == NULL)
+		goto free_tx_buf;
+
+
+	iphone->tx_urb = tx_urb;
+	iphone->rx_urb = rx_urb;
+	iphone->tx_buf = tx_buf;
+	iphone->rx_buf = rx_buf;
+	return 0;
+
+free_tx_buf:
+	usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, tx_buf,
+			tx_urb->transfer_dma);
+free_rx_urb:
+	usb_free_urb(rx_urb);
+free_tx_urb:
+	usb_free_urb(tx_urb);
+error_nomem:
+	return -ENOMEM;
+}
+
+static void ipheth_free_urbs(struct ipheth_device *iphone)
+{
+	usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, iphone->rx_buf,
+			iphone->rx_urb->transfer_dma);
+	usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf,
+			iphone->tx_urb->transfer_dma);
+	usb_free_urb(iphone->rx_urb);
+	usb_free_urb(iphone->tx_urb);
+}
+
+static void ipheth_kill_urbs(struct ipheth_device *dev)
+{
+	usb_kill_urb(dev->tx_urb);
+	usb_kill_urb(dev->rx_urb);
+}
+
+static void ipheth_rcvbulk_callback(struct urb *urb)
+{
+	struct ipheth_device *dev;
+	struct sk_buff *skb;
+	int status;
+	char *buf;
+	int len;
+
+	dev = urb->context;
+	if (dev == NULL)
+		return;
+
+	status = urb->status;
+	switch (status) {
+	case -ENOENT:
+	case -ECONNRESET:
+	case -ESHUTDOWN:
+		return;
+	case 0:
+		break;
+	default:
+		err("%s: urb status: %d", __func__, urb->status);
+		return;
+	}
+
+	len = urb->actual_length;
+	buf = urb->transfer_buffer;
+
+	skb = dev_alloc_skb(NET_IP_ALIGN + len);
+	if (!skb) {
+		err("%s: dev_alloc_skb: -ENOMEM", __func__);
+		dev->net->stats.rx_dropped++;
+		return;
+	}
+
+	skb_reserve(skb, NET_IP_ALIGN);
+	memcpy(skb_put(skb, len), buf + NET_IP_ALIGN, len - NET_IP_ALIGN);
+	skb->dev = dev->net;
+	skb->protocol = eth_type_trans(skb, dev->net);
+
+	dev->net->stats.rx_packets++;
+	dev->net->stats.rx_bytes += len;
+
+	netif_rx(skb);
+	ipheth_rx_submit(dev, GFP_ATOMIC);
+}
+
+static void ipheth_sndbulk_callback(struct urb *urb)
+{
+	struct ipheth_device *dev;
+
+	dev = urb->context;
+	if (dev == NULL)
+		return;
+
+	if (urb->status != 0 &&
+	    urb->status != -ENOENT &&
+	    urb->status != -ECONNRESET &&
+	    urb->status != -ESHUTDOWN)
+		err("%s: urb status: %d", __func__, urb->status);
+
+	dev_kfree_skb_irq(dev->tx_skb);
+	netif_wake_queue(dev->net);
+}
+
+static int ipheth_carrier_set(struct ipheth_device *dev)
+{
+	struct usb_device *udev = dev->udev;
+	int retval;
+
+	retval = usb_control_msg(udev,
+			usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP),
+			IPHETH_CMD_CARRIER_CHECK, /* request */
+			0xc0, /* request type */
+			0x00, /* value */
+			0x02, /* index */
+			dev->ctrl_buf, IPHETH_CTRL_BUF_SIZE,
+			IPHETH_CTRL_TIMEOUT);
+	if (retval < 0) {
+		err("%s: usb_control_msg: %d", __func__, retval);
+		return retval;
+	}
+
+	if (dev->ctrl_buf[0] == IPHETH_CARRIER_ON)
+		netif_carrier_on(dev->net);
+	else
+		netif_carrier_off(dev->net);
+
+	return 0;
+}
+
+static void ipheth_carrier_check_work(struct work_struct *work)
+{
+	struct ipheth_device *dev = container_of(work, struct ipheth_device,
+						 carrier_work.work);
+
+	ipheth_carrier_set(dev);
+	schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT);
+}
+
+static int ipheth_get_macaddr(struct ipheth_device *dev)
+{
+	struct usb_device *udev = dev->udev;
+	struct net_device *net = dev->net;
+	int retval;
+
+	retval = usb_control_msg(udev,
+				 usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP),
+				 IPHETH_CMD_GET_MACADDR, /* request */
+				 0xc0, /* request type */
+				 0x00, /* value */
+				 0x02, /* index */
+				 dev->ctrl_buf,
+				 IPHETH_CTRL_BUF_SIZE,
+				 IPHETH_CTRL_TIMEOUT);
+	if (retval < 0) {
+		err("%s: usb_control_msg: %d", __func__, retval);
+	} else if (retval < ETH_ALEN) {
+		err("%s: usb_control_msg: short packet: %d bytes",
+			__func__, retval);
+		retval = -EINVAL;
+	} else {
+		memcpy(net->dev_addr, dev->ctrl_buf, ETH_ALEN);
+		retval = 0;
+	}
+
+	return retval;
+}
+
+static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags)
+{
+	struct usb_device *udev = dev->udev;
+	int retval;
+
+	usb_fill_bulk_urb(dev->rx_urb, udev,
+			  usb_rcvbulkpipe(udev, dev->bulk_in),
+			  dev->rx_buf, IPHETH_BUF_SIZE,
+			  ipheth_rcvbulk_callback,
+			  dev);
+	dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+	retval = usb_submit_urb(dev->rx_urb, mem_flags);
+	if (retval)
+		err("%s: usb_submit_urb: %d", __func__, retval);
+	return retval;
+}
+
+static int ipheth_open(struct net_device *net)
+{
+	struct ipheth_device *dev = netdev_priv(net);
+	struct usb_device *udev = dev->udev;
+	int retval = 0;
+
+	usb_set_interface(udev, IPHETH_INTFNUM, IPHETH_ALT_INTFNUM);
+
+	retval = ipheth_carrier_set(dev);
+	if (retval)
+		return retval;
+
+	retval = ipheth_rx_submit(dev, GFP_KERNEL);
+	if (retval)
+		return retval;
+
+	schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT);
+	netif_start_queue(net);
+	return retval;
+}
+
+static int ipheth_close(struct net_device *net)
+{
+	struct ipheth_device *dev = netdev_priv(net);
+
+	cancel_delayed_work_sync(&dev->carrier_work);
+	netif_stop_queue(net);
+	return 0;
+}
+
+static int ipheth_tx(struct sk_buff *skb, struct net_device *net)
+{
+	struct ipheth_device *dev = netdev_priv(net);
+	struct usb_device *udev = dev->udev;
+	int retval;
+
+	/* Paranoid */
+	if (skb->len > IPHETH_BUF_SIZE) {
+		WARN(1, "%s: skb too large: %d bytes", __func__, skb->len);
+		dev->net->stats.tx_dropped++;
+		dev_kfree_skb_irq(skb);
+		return NETDEV_TX_OK;
+	}
+
+	memcpy(dev->tx_buf, skb->data, skb->len);
+	if (skb->len < IPHETH_BUF_SIZE)
+		memset(dev->tx_buf + skb->len, 0, IPHETH_BUF_SIZE - skb->len);
+
+	usb_fill_bulk_urb(dev->tx_urb, udev,
+			  usb_sndbulkpipe(udev, dev->bulk_out),
+			  dev->tx_buf, IPHETH_BUF_SIZE,
+			  ipheth_sndbulk_callback,
+			  dev);
+	dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+	retval = usb_submit_urb(dev->tx_urb, GFP_ATOMIC);
+	if (retval) {
+		err("%s: usb_submit_urb: %d", __func__, retval);
+		dev->net->stats.tx_errors++;
+		dev_kfree_skb_irq(skb);
+	} else {
+		dev->tx_skb = skb;
+
+		dev->net->stats.tx_packets++;
+		dev->net->stats.tx_bytes += skb->len;
+		netif_stop_queue(net);
+	}
+
+	return NETDEV_TX_OK;
+}
+
+static void ipheth_tx_timeout(struct net_device *net)
+{
+	struct ipheth_device *dev = netdev_priv(net);
+
+	err("%s: TX timeout", __func__);
+	dev->net->stats.tx_errors++;
+	usb_unlink_urb(dev->tx_urb);
+}
+
+static struct net_device_stats *ipheth_stats(struct net_device *net)
+{
+	struct ipheth_device *dev = netdev_priv(net);
+	return &dev->net->stats;
+}
+
+static u32 ipheth_ethtool_op_get_link(struct net_device *net)
+{
+	struct ipheth_device *dev = netdev_priv(net);
+	return netif_carrier_ok(dev->net);
+}
+
+static struct ethtool_ops ops = {
+	.get_link = ipheth_ethtool_op_get_link
+};
+
+static const struct net_device_ops ipheth_netdev_ops = {
+	.ndo_open = &ipheth_open,
+	.ndo_stop = &ipheth_close,
+	.ndo_start_xmit = &ipheth_tx,
+	.ndo_tx_timeout = &ipheth_tx_timeout,
+	.ndo_get_stats = &ipheth_stats,
+};
+
+static struct device_type ipheth_type = {
+	.name	= "wwan",
+};
+
+static int ipheth_probe(struct usb_interface *intf,
+			const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_host_interface *hintf;
+	struct usb_endpoint_descriptor *endp;
+	struct ipheth_device *dev;
+	struct net_device *netdev;
+	int i;
+	int retval;
+
+	netdev = alloc_etherdev(sizeof(struct ipheth_device));
+	if (!netdev)
+		return -ENOMEM;
+
+	netdev->netdev_ops = &ipheth_netdev_ops;
+	netdev->watchdog_timeo = IPHETH_TX_TIMEOUT;
+	strcpy(netdev->name, "wwan%d");
+
+	dev = netdev_priv(netdev);
+	dev->udev = udev;
+	dev->net = netdev;
+	dev->intf = intf;
+
+	/* Set up endpoints */
+	hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM);
+	if (hintf == NULL) {
+		retval = -ENODEV;
+		err("Unable to find alternate settings interface");
+		goto err_endpoints;
+	}
+
+	for (i = 0; i < hintf->desc.bNumEndpoints; i++) {
+		endp = &hintf->endpoint[i].desc;
+		if (usb_endpoint_is_bulk_in(endp))
+			dev->bulk_in = endp->bEndpointAddress;
+		else if (usb_endpoint_is_bulk_out(endp))
+			dev->bulk_out = endp->bEndpointAddress;
+	}
+	if (!(dev->bulk_in && dev->bulk_out)) {
+		retval = -ENODEV;
+		err("Unable to find endpoints");
+		goto err_endpoints;
+	}
+
+	dev->ctrl_buf = kmalloc(IPHETH_CTRL_BUF_SIZE, GFP_KERNEL);
+	if (dev->ctrl_buf == NULL) {
+		retval = -ENOMEM;
+		goto err_alloc_ctrl_buf;
+	}
+
+	retval = ipheth_get_macaddr(dev);
+	if (retval)
+		goto err_get_macaddr;
+
+	INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work);
+
+	retval = ipheth_alloc_urbs(dev);
+	if (retval) {
+		err("error allocating urbs: %d", retval);
+		goto err_alloc_urbs;
+	}
+
+	usb_set_intfdata(intf, dev);
+
+	SET_NETDEV_DEV(netdev, &intf->dev);
+	SET_ETHTOOL_OPS(netdev, &ops);
+	SET_NETDEV_DEVTYPE(netdev, &ipheth_type);
+
+	retval = register_netdev(netdev);
+	if (retval) {
+		err("error registering netdev: %d", retval);
+		retval = -EIO;
+		goto err_register_netdev;
+	}
+
+	dev_info(&intf->dev, "Apple iPhone USB Ethernet device attached\n");
+	return 0;
+
+err_register_netdev:
+	ipheth_free_urbs(dev);
+err_alloc_urbs:
+err_get_macaddr:
+err_alloc_ctrl_buf:
+	kfree(dev->ctrl_buf);
+err_endpoints:
+	free_netdev(netdev);
+	return retval;
+}
+
+static void ipheth_disconnect(struct usb_interface *intf)
+{
+	struct ipheth_device *dev;
+
+	dev = usb_get_intfdata(intf);
+	if (dev != NULL) {
+		unregister_netdev(dev->net);
+		ipheth_kill_urbs(dev);
+		ipheth_free_urbs(dev);
+		kfree(dev->ctrl_buf);
+		free_netdev(dev->net);
+	}
+	usb_set_intfdata(intf, NULL);
+	dev_info(&intf->dev, "Apple iPhone USB Ethernet now disconnected\n");
+}
+
+static struct usb_driver ipheth_driver = {
+	.name =		"ipheth",
+	.probe =	ipheth_probe,
+	.disconnect =	ipheth_disconnect,
+	.id_table =	ipheth_table,
+};
+
+static int __init ipheth_init(void)
+{
+	int retval;
+
+	retval = usb_register(&ipheth_driver);
+	if (retval) {
+		err("usb_register failed: %d", retval);
+		return retval;
+	}
+	return 0;
+}
+
+static void __exit ipheth_exit(void)
+{
+	usb_deregister(&ipheth_driver);
+}
+
+module_init(ipheth_init);
+module_exit(ipheth_exit);
+
+MODULE_AUTHOR("Diego Giagio <diego@giagio.com>");
+MODULE_DESCRIPTION("Apple iPhone USB Ethernet driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/kaweth.c linux-libre-2.6.34-gnu1/drivers/net/usb/kaweth.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/kaweth.c	2013-05-03 12:09:07.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/kaweth.c	2013-05-03 09:48:38.000000000 -0400
@@ -142,6 +142,7 @@ static struct usb_device_id usb_klsi_tab
 	{ USB_DEVICE(0x0707, 0x0100) }, /* SMC 2202USB */
 	{ USB_DEVICE(0x07aa, 0x0001) }, /* Correga K.K. */
 	{ USB_DEVICE(0x07b8, 0x4000) }, /* D-Link DU-E10 */
+	{ USB_DEVICE(0x07c9, 0xb010) }, /* Allied Telesyn AT-USB10 USB Ethernet Adapter */
 	{ USB_DEVICE(0x0846, 0x1001) }, /* NetGear EA-101 */
 	{ USB_DEVICE(0x0846, 0x1002) }, /* NetGear EA-101 */
 	{ USB_DEVICE(0x085a, 0x0008) }, /* PortGear Ethernet Adapter */
@@ -878,7 +879,7 @@ static void kaweth_set_rx_mode(struct ne
 	if (net->flags & IFF_PROMISC) {
 		packet_filter_bitmap |= KAWETH_PACKET_FILTER_PROMISCUOUS;
 	}
-	else if ((net->mc_count) || (net->flags & IFF_ALLMULTI)) {
+	else if (!netdev_mc_empty(net) || (net->flags & IFF_ALLMULTI)) {
 		packet_filter_bitmap |= KAWETH_PACKET_FILTER_ALL_MULTICAST;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/Kconfig linux-libre-2.6.34-gnu1/drivers/net/usb/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/net/usb/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -204,6 +204,14 @@ config USB_NET_DM9601
 	  This option adds support for Davicom DM9601 based USB 1.1
 	  10/100 Ethernet adapters.
 
+config USB_NET_SMSC75XX
+	tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices"
+	depends on USB_USBNET
+	select CRC32
+	help
+	  This option adds support for SMSC LAN95XX based USB 2.0
+	  Gigabit Ethernet adapters.
+
 config USB_NET_SMSC95XX
 	tristate "SMSC LAN95XX based USB 2.0 10/100 ethernet devices"
 	depends on USB_USBNET
@@ -377,4 +385,25 @@ config USB_CDC_PHONET
 	  cellular modem, as found on most Nokia handsets with the
 	  "PC suite" USB profile.
 
+config USB_IPHETH
+	tristate "Apple iPhone USB Ethernet driver"
+	default n
+	---help---
+	  Module used to share Internet connection (tethering) from your
+	  iPhone (Original, 3G and 3GS) to your system.
+	  Note that you need userspace libraries and programs that are needed
+	  to pair your device with your system and that understand the iPhone
+	  protocol.
+
+	  For more information: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver
+
+config USB_SIERRA_NET
+	tristate "USB-to-WWAN Driver for Sierra Wireless modems"
+	depends on USB_USBNET
+	help
+	  Choose this option if you have a Sierra Wireless USB-to-WWAN device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called sierra_net.
+
 endmenu
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/Makefile linux-libre-2.6.34-gnu1/drivers/net/usb/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/usb/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@ 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_SMSC75XX)	+= smsc75xx.o
 obj-$(CONFIG_USB_NET_SMSC95XX)	+= smsc95xx.o
 obj-$(CONFIG_USB_NET_GL620A)	+= gl620a.o
 obj-$(CONFIG_USB_NET_NET1080)	+= net1080.o
@@ -22,4 +23,6 @@ obj-$(CONFIG_USB_NET_MCS7830)	+= mcs7830
 obj-$(CONFIG_USB_USBNET)	+= usbnet.o
 obj-$(CONFIG_USB_NET_INT51X1)	+= int51x1.o
 obj-$(CONFIG_USB_CDC_PHONET)	+= cdc-phonet.o
+obj-$(CONFIG_USB_IPHETH)	+= ipheth.o
+obj-$(CONFIG_USB_SIERRA_NET)	+= sierra_net.o
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/mcs7830.c linux-libre-2.6.34-gnu1/drivers/net/usb/mcs7830.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/mcs7830.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/mcs7830.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,13 +1,27 @@
 /*
- * MosChips MCS7830 based USB 2.0 Ethernet Devices
+ * MOSCHIP MCS7830 based USB 2.0 Ethernet Devices
  *
  * based on usbnet.c, asix.c and the vendor provided mcs7830 driver
  *
+ * Copyright (C) 2010 Andreas Mohr <andi@lisas.de>
  * Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>
  * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
  * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
  * Copyright (c) 2002-2003 TiVo Inc.
  *
+ * Definitions gathered from MOSCHIP, Data Sheet_7830DA.pdf (thanks!).
+ *
+ * TODO:
+ * - support HIF_REG_CONFIG_SLEEPMODE/HIF_REG_CONFIG_TXENABLE (via autopm?)
+ * - implement ethtool_ops get_pauseparam/set_pauseparam
+ *   via HIF_REG_PAUSE_THRESHOLD (>= revision C only!)
+ * - implement get_eeprom/[set_eeprom]
+ * - switch PHY on/off on ifup/ifdown (perhaps in usbnet.c, via MII)
+ * - mcs7830_get_regs() handling is weird: for rev 2 we return 32 regs,
+ *   can access only ~ 24, remaining user buffer is uninitialized garbage
+ * - anything else?
+ *
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -30,6 +44,7 @@
 #include <linux/mii.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/usbnet.h>
 
@@ -55,7 +70,7 @@
 				 ADVERTISE_100HALF | ADVERTISE_10FULL | \
 				 ADVERTISE_10HALF | ADVERTISE_CSMA)
 
-/* HIF_REG_XX coressponding index value */
+/* HIF_REG_XX corresponding index value */
 enum {
 	HIF_REG_MULTICAST_HASH			= 0x00,
 	HIF_REG_PACKET_GAP1			= 0x08,
@@ -69,6 +84,7 @@ enum {
 	   HIF_REG_PHY_CMD2_PEND_FLAG_BIT	= 0x80,
 	   HIF_REG_PHY_CMD2_READY_FLAG_BIT	= 0x40,
 	HIF_REG_CONFIG				= 0x0e,
+	/* hmm, spec sez: "R/W", "Except bit 3" (likely TXENABLE). */
 	   HIF_REG_CONFIG_CFG			= 0x80,
 	   HIF_REG_CONFIG_SPEED100		= 0x40,
 	   HIF_REG_CONFIG_FULLDUPLEX_ENABLE	= 0x20,
@@ -76,13 +92,24 @@ enum {
 	   HIF_REG_CONFIG_TXENABLE		= 0x08,
 	   HIF_REG_CONFIG_SLEEPMODE		= 0x04,
 	   HIF_REG_CONFIG_ALLMULTICAST		= 0x02,
-	   HIF_REG_CONFIG_PROMISCIOUS		= 0x01,
+	   HIF_REG_CONFIG_PROMISCUOUS		= 0x01,
 	HIF_REG_ETHERNET_ADDR			= 0x0f,
-	HIF_REG_22				= 0x15,
+	HIF_REG_FRAME_DROP_COUNTER		= 0x15, /* 0..ff; reset: 0 */
 	HIF_REG_PAUSE_THRESHOLD			= 0x16,
 	   HIF_REG_PAUSE_THRESHOLD_DEFAULT	= 0,
 };
 
+/* Trailing status byte in Ethernet Rx frame */
+enum {
+	MCS7830_RX_SHORT_FRAME		= 0x01, /* < 64 bytes */
+	MCS7830_RX_LENGTH_ERROR		= 0x02, /* framelen != Ethernet length field */
+	MCS7830_RX_ALIGNMENT_ERROR	= 0x04, /* non-even number of nibbles */
+	MCS7830_RX_CRC_ERROR		= 0x08,
+	MCS7830_RX_LARGE_FRAME		= 0x10, /* > 1518 bytes */
+	MCS7830_RX_FRAME_CORRECT	= 0x20, /* frame is correct */
+	/* [7:6] reserved */
+};
+
 struct mcs7830_data {
 	u8 multi_filter[8];
 	u8 config;
@@ -109,7 +136,7 @@ static int mcs7830_get_reg(struct usbnet
 	return ret;
 }
 
-static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, void *data)
+static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, const void *data)
 {
 	struct usb_device *xdev = dev->udev;
 	int ret;
@@ -183,13 +210,43 @@ out:
 	usb_free_urb(urb);
 }
 
-static int mcs7830_get_address(struct usbnet *dev)
+static int mcs7830_hif_get_mac_address(struct usbnet *dev, unsigned char *addr)
+{
+	int ret = mcs7830_get_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN, addr);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static int mcs7830_hif_set_mac_address(struct usbnet *dev, unsigned char *addr)
+{
+	int ret = mcs7830_set_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN, addr);
+
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static int mcs7830_set_mac_address(struct net_device *netdev, void *p)
 {
 	int ret;
-	ret = mcs7830_get_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN,
-				   dev->net->dev_addr);
+	struct usbnet *dev = netdev_priv(netdev);
+	struct sockaddr *addr = p;
+
+	if (netif_running(netdev))
+		return -EBUSY;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EINVAL;
+
+	ret = mcs7830_hif_set_mac_address(dev, addr->sa_data);
+
 	if (ret < 0)
 		return ret;
+
+	/* it worked --> adopt it on netdev side */
+	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+
 	return 0;
 }
 
@@ -307,7 +364,7 @@ static int mcs7830_get_rev(struct usbnet
 {
 	u8 dummy[2];
 	int ret;
-	ret = mcs7830_get_reg(dev, HIF_REG_22, 2, dummy);
+	ret = mcs7830_get_reg(dev, HIF_REG_FRAME_DROP_COUNTER, 2, dummy);
 	if (ret > 0)
 		return 2; /* Rev C or later */
 	return 1; /* earlier revision */
@@ -331,33 +388,6 @@ static void mcs7830_rev_C_fixup(struct u
 	}
 }
 
-static int mcs7830_init_dev(struct usbnet *dev)
-{
-	int ret;
-	int retry;
-
-	/* Read MAC address from EEPROM */
-	ret = -EINVAL;
-	for (retry = 0; retry < 5 && ret; retry++)
-		ret = mcs7830_get_address(dev);
-	if (ret) {
-		dev_warn(&dev->udev->dev, "Cannot read MAC address\n");
-		goto out;
-	}
-
-	/* Set up PHY */
-	ret = mcs7830_set_autoneg(dev, 0);
-	if (ret) {
-		dev_info(&dev->udev->dev, "Cannot set autoneg\n");
-		goto out;
-	}
-
-	mcs7830_rev_C_fixup(dev);
-	ret = 0;
-out:
-	return ret;
-}
-
 static int mcs7830_mdio_read(struct net_device *netdev, int phy_id,
 			     int location)
 {
@@ -378,11 +408,33 @@ static int mcs7830_ioctl(struct net_devi
 	return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
 }
 
-/* credits go to asix_set_multicast */
-static void mcs7830_set_multicast(struct net_device *net)
+static inline struct mcs7830_data *mcs7830_get_data(struct usbnet *dev)
+{
+	return (struct mcs7830_data *)&dev->data;
+}
+
+static void mcs7830_hif_update_multicast_hash(struct usbnet *dev)
+{
+	struct mcs7830_data *data = mcs7830_get_data(dev);
+	mcs7830_set_reg_async(dev, HIF_REG_MULTICAST_HASH,
+				sizeof data->multi_filter,
+				data->multi_filter);
+}
+
+static void mcs7830_hif_update_config(struct usbnet *dev)
+{
+	/* implementation specific to data->config
+           (argument needs to be heap-based anyway - USB DMA!) */
+	struct mcs7830_data *data = mcs7830_get_data(dev);
+	mcs7830_set_reg_async(dev, HIF_REG_CONFIG, 1, &data->config);
+}
+
+static void mcs7830_data_set_multicast(struct net_device *net)
 {
 	struct usbnet *dev = netdev_priv(net);
-	struct mcs7830_data *data = (struct mcs7830_data *)&dev->data;
+	struct mcs7830_data *data = mcs7830_get_data(dev);
+
+	memset(data->multi_filter, 0, sizeof data->multi_filter);
 
 	data->config = HIF_REG_CONFIG_TXENABLE;
 
@@ -390,36 +442,64 @@ static void mcs7830_set_multicast(struct
 	data->config |= HIF_REG_CONFIG_ALLMULTICAST;
 
 	if (net->flags & IFF_PROMISC) {
-		data->config |= HIF_REG_CONFIG_PROMISCIOUS;
+		data->config |= HIF_REG_CONFIG_PROMISCUOUS;
 	} else if (net->flags & IFF_ALLMULTI ||
-		   net->mc_count > MCS7830_MAX_MCAST) {
+		   netdev_mc_count(net) > MCS7830_MAX_MCAST) {
 		data->config |= HIF_REG_CONFIG_ALLMULTICAST;
-	} else if (net->mc_count == 0) {
+	} else if (netdev_mc_empty(net)) {
 		/* just broadcast and directed */
 	} else {
 		/* We use the 20 byte dev->data
 		 * for our 8 byte filter buffer
 		 * to avoid allocating memory that
 		 * is tricky to free later */
-		struct dev_mc_list *mc_list = net->mc_list;
+		struct dev_mc_list *mc_list;
 		u32 crc_bits;
-		int i;
-
-		memset(data->multi_filter, 0, sizeof data->multi_filter);
 
 		/* Build the multicast hash filter. */
-		for (i = 0; i < net->mc_count; i++) {
+		netdev_for_each_mc_addr(mc_list, net) {
 			crc_bits = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26;
 			data->multi_filter[crc_bits >> 3] |= 1 << (crc_bits & 7);
-			mc_list = mc_list->next;
 		}
+	}
+}
 
-		mcs7830_set_reg_async(dev, HIF_REG_MULTICAST_HASH,
-				sizeof data->multi_filter,
-				data->multi_filter);
+static int mcs7830_apply_base_config(struct usbnet *dev)
+{
+	int ret;
+
+	/* re-configure known MAC (suspend case etc.) */
+	ret = mcs7830_hif_set_mac_address(dev, dev->net->dev_addr);
+	if (ret) {
+		dev_info(&dev->udev->dev, "Cannot set MAC address\n");
+		goto out;
 	}
 
-	mcs7830_set_reg_async(dev, HIF_REG_CONFIG, 1, &data->config);
+	/* Set up PHY */
+	ret = mcs7830_set_autoneg(dev, 0);
+	if (ret) {
+		dev_info(&dev->udev->dev, "Cannot set autoneg\n");
+		goto out;
+	}
+
+	mcs7830_hif_update_multicast_hash(dev);
+	mcs7830_hif_update_config(dev);
+
+	mcs7830_rev_C_fixup(dev);
+	ret = 0;
+out:
+	return ret;
+}
+
+/* credits go to asix_set_multicast */
+static void mcs7830_set_multicast(struct net_device *net)
+{
+	struct usbnet *dev = netdev_priv(net);
+
+	mcs7830_data_set_multicast(net);
+
+	mcs7830_hif_update_multicast_hash(dev);
+	mcs7830_hif_update_config(dev);
 }
 
 static int mcs7830_get_regs_len(struct net_device *net)
@@ -463,29 +543,6 @@ static const struct ethtool_ops mcs7830_
 	.nway_reset		= usbnet_nway_reset,
 };
 
-static int mcs7830_set_mac_address(struct net_device *netdev, void *p)
-{
-	int ret;
-	struct usbnet *dev = netdev_priv(netdev);
-	struct sockaddr *addr = p;
-
-	if (netif_running(netdev))
-		return -EBUSY;
-
-	if (!is_valid_ether_addr(addr->sa_data))
-		return -EINVAL;
-
-	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-
-	ret = mcs7830_set_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN,
-			netdev->dev_addr);
-
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
 static const struct net_device_ops mcs7830_netdev_ops = {
 	.ndo_open		= usbnet_open,
 	.ndo_stop		= usbnet_stop,
@@ -495,21 +552,32 @@ static const struct net_device_ops mcs78
 	.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,
+	.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;
 	int ret;
+	int retry;
 
-	ret = mcs7830_init_dev(dev);
+	/* Initial startup: Gather MAC address setting from EEPROM */
+	ret = -EINVAL;
+	for (retry = 0; retry < 5 && ret; retry++)
+		ret = mcs7830_hif_get_mac_address(dev, net->dev_addr);
+	if (ret) {
+		dev_warn(&dev->udev->dev, "Cannot read MAC address\n");
+		goto out;
+	}
+
+	mcs7830_data_set_multicast(net);
+
+	ret = mcs7830_apply_base_config(dev);
 	if (ret)
 		goto out;
 
 	net->ethtool_ops = &mcs7830_ethtool_ops;
 	net->netdev_ops = &mcs7830_netdev_ops;
-	mcs7830_set_multicast(net);
 
 	/* reserve space for the status byte on rx */
 	dev->rx_urb_size = ETH_FRAME_LEN + 1;
@@ -526,7 +594,7 @@ out:
 	return ret;
 }
 
-/* The chip always appends a status bytes that we need to strip */
+/* The chip always appends a status byte that we need to strip */
 static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 {
 	u8 status;
@@ -539,9 +607,23 @@ static int mcs7830_rx_fixup(struct usbne
 	skb_trim(skb, skb->len - 1);
 	status = skb->data[skb->len];
 
-	if (status != 0x20)
+	if (status != MCS7830_RX_FRAME_CORRECT) {
 		dev_dbg(&dev->udev->dev, "rx fixup status %x\n", status);
 
+		/* hmm, perhaps usbnet.c already sees a globally visible
+		   frame error and increments rx_errors on its own already? */
+		dev->net->stats.rx_errors++;
+
+		if (status &	(MCS7830_RX_SHORT_FRAME
+				|MCS7830_RX_LENGTH_ERROR
+				|MCS7830_RX_LARGE_FRAME))
+			dev->net->stats.rx_length_errors++;
+		if (status & MCS7830_RX_ALIGNMENT_ERROR)
+			dev->net->stats.rx_frame_errors++;
+		if (status & MCS7830_RX_CRC_ERROR)
+			dev->net->stats.rx_crc_errors++;
+	}
+
 	return skb->len > 0;
 }
 
@@ -580,6 +662,20 @@ static const struct usb_device_id produc
 };
 MODULE_DEVICE_TABLE(usb, products);
 
+static int mcs7830_reset_resume (struct usb_interface *intf)
+{
+ 	/* YES, this function is successful enough that ethtool -d
+           does show same output pre-/post-suspend */
+
+	struct usbnet		*dev = usb_get_intfdata(intf);
+
+	mcs7830_apply_base_config(dev);
+
+	usbnet_resume(intf);
+
+	return 0;
+}
+
 static struct usb_driver mcs7830_driver = {
 	.name = driver_name,
 	.id_table = products,
@@ -587,6 +683,7 @@ static struct usb_driver mcs7830_driver
 	.disconnect = usbnet_disconnect,
 	.suspend = usbnet_suspend,
 	.resume = usbnet_resume,
+	.reset_resume = mcs7830_reset_resume,
 };
 
 static int __init mcs7830_init(void)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/net1080.c linux-libre-2.6.34-gnu1/drivers/net/usb/net1080.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/net1080.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/net1080.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/usb/usbnet.h>
+#include <linux/slab.h>
 
 #include <asm/unaligned.h>
 
@@ -203,25 +204,23 @@ static void nc_dump_registers(struct usb
 
 static inline void nc_dump_usbctl(struct usbnet *dev, u16 usbctl)
 {
-	if (!netif_msg_link(dev))
-		return;
-	devdbg(dev, "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s;"
-			" this%s%s;"
-			" other%s%s; r/o 0x%x",
-		dev->udev->bus->bus_name, dev->udev->devpath,
-		usbctl,
-		(usbctl & USBCTL_ENABLE_LANG) ? " lang" : "",
-		(usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "",
-		(usbctl & USBCTL_ENABLE_PROD) ? " prod" : "",
-		(usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "",
-		(usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "",
+	netif_dbg(dev, link, dev->net,
+		  "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s; this%s%s; other%s%s; r/o 0x%x\n",
+		  dev->udev->bus->bus_name, dev->udev->devpath,
+		  usbctl,
+		  (usbctl & USBCTL_ENABLE_LANG) ? " lang" : "",
+		  (usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "",
+		  (usbctl & USBCTL_ENABLE_PROD) ? " prod" : "",
+		  (usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "",
+		  (usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "",
 
-		(usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "",
-		(usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "",
-		(usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "",
-		(usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "",
-		usbctl & ~USBCTL_WRITABLE_MASK
-		);
+		  (usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "",
+		  (usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "",
+
+		  (usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "",
+		  (usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "",
+
+		  usbctl & ~USBCTL_WRITABLE_MASK);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -248,30 +247,26 @@ static inline void nc_dump_usbctl(struct
 
 static inline void nc_dump_status(struct usbnet *dev, u16 status)
 {
-	if (!netif_msg_link(dev))
-		return;
-	devdbg(dev, "net1080 %s-%s status 0x%x:"
-			" this (%c) PKT=%d%s%s%s;"
-			" other PKT=%d%s%s%s; unspec 0x%x",
-		dev->udev->bus->bus_name, dev->udev->devpath,
-		status,
+	netif_dbg(dev, link, dev->net,
+		  "net1080 %s-%s status 0x%x: this (%c) PKT=%d%s%s%s; other PKT=%d%s%s%s; unspec 0x%x\n",
+		  dev->udev->bus->bus_name, dev->udev->devpath,
+		  status,
 
-		// XXX the packet counts don't seem right
-		// (1 at reset, not 0); maybe UNSPEC too
+		  // XXX the packet counts don't seem right
+		  // (1 at reset, not 0); maybe UNSPEC too
 
-		(status & STATUS_PORT_A) ? 'A' : 'B',
-		STATUS_PACKETS_THIS(status),
-		(status & STATUS_CONN_THIS) ? " CON" : "",
-		(status & STATUS_SUSPEND_THIS) ? " SUS" : "",
-		(status & STATUS_MAILBOX_THIS) ? " MBOX" : "",
+		  (status & STATUS_PORT_A) ? 'A' : 'B',
+		  STATUS_PACKETS_THIS(status),
+		  (status & STATUS_CONN_THIS) ? " CON" : "",
+		  (status & STATUS_SUSPEND_THIS) ? " SUS" : "",
+		  (status & STATUS_MAILBOX_THIS) ? " MBOX" : "",
 
-		STATUS_PACKETS_OTHER(status),
-		(status & STATUS_CONN_OTHER) ? " CON" : "",
-		(status & STATUS_SUSPEND_OTHER) ? " SUS" : "",
-		(status & STATUS_MAILBOX_OTHER) ? " MBOX" : "",
+		  STATUS_PACKETS_OTHER(status),
+		  (status & STATUS_CONN_OTHER) ? " CON" : "",
+		  (status & STATUS_SUSPEND_OTHER) ? " SUS" : "",
+		  (status & STATUS_MAILBOX_OTHER) ? " MBOX" : "",
 
-		status & STATUS_UNSPEC_MASK
-		);
+		  status & STATUS_UNSPEC_MASK);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -286,10 +281,9 @@ static inline void nc_dump_status(struct
 
 static inline void nc_dump_ttl(struct usbnet *dev, u16 ttl)
 {
-	if (netif_msg_link(dev))
-		devdbg(dev, "net1080 %s-%s ttl 0x%x this = %d, other = %d",
-			dev->udev->bus->bus_name, dev->udev->devpath,
-			ttl, TTL_THIS(ttl), TTL_OTHER(ttl));
+	netif_dbg(dev, link, dev->net, "net1080 %s-%s ttl 0x%x this = %d, other = %d\n",
+		  dev->udev->bus->bus_name, dev->udev->devpath,
+		  ttl, TTL_THIS(ttl), TTL_OTHER(ttl));
 }
 
 /*-------------------------------------------------------------------------*/
@@ -334,11 +328,9 @@ static int net1080_reset(struct usbnet *
 			MK_TTL(NC_READ_TTL_MS, TTL_OTHER(ttl)) );
 	dbg("%s: assigned TTL, %d ms", dev->net->name, NC_READ_TTL_MS);
 
-	if (netif_msg_link(dev))
-		devinfo(dev, "port %c, peer %sconnected",
-			(status & STATUS_PORT_A) ? 'A' : 'B',
-			(status & STATUS_CONN_OTHER) ? "" : "dis"
-			);
+	netif_info(dev, link, dev->net, "port %c, peer %sconnected\n",
+		   (status & STATUS_PORT_A) ? 'A' : 'B',
+		   (status & STATUS_CONN_OTHER) ? "" : "dis");
 	retval = 0;
 
 done:
@@ -415,8 +407,8 @@ static void nc_ensure_sync(struct usbnet
 			return;
 		}
 
-		if (netif_msg_rx_err(dev))
-			devdbg(dev, "flush net1080; too many framing errors");
+		netif_dbg(dev, rx_err, dev->net,
+			  "flush net1080; too many framing errors\n");
 		dev->frame_errors = 0;
 	}
 }
@@ -486,8 +478,8 @@ static int net1080_rx_fixup(struct usbne
 		return 0;
 	}
 #if 0
-	devdbg(dev, "frame <rx h %d p %d id %d", header->hdr_len,
-		header->packet_len, header->packet_id);
+	netdev_dbg(dev->net, "frame <rx h %d p %d id %d\n", header->hdr_len,
+		   header->packet_len, header->packet_id);
 #endif
 	dev->frame_errors = 0;
 	return 1;
@@ -547,9 +539,9 @@ encapsulate:
 	trailer = (struct nc_trailer *) skb_put(skb, sizeof *trailer);
 	put_unaligned(header->packet_id, &trailer->packet_id);
 #if 0
-	devdbg(dev, "frame >tx h %d p %d id %d",
-		header->hdr_len, header->packet_len,
-		header->packet_id);
+	netdev_dbg(dev->net, "frame >tx h %d p %d id %d\n",
+		   header->hdr_len, header->packet_len,
+		   header->packet_id);
 #endif
 	return skb;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/pegasus.c linux-libre-2.6.34-gnu1/drivers/net/usb/pegasus.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/pegasus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/pegasus.c	2010-05-16 17:17:36.000000000 -0400
@@ -132,9 +132,10 @@ static void ctrl_callback(struct urb *ur
 	case -ENOENT:
 		break;
 	default:
-		if (netif_msg_drv(pegasus) && printk_ratelimit())
-			dev_dbg(&pegasus->intf->dev, "%s, status %d\n",
-				__func__, status);
+		if (net_ratelimit())
+			netif_dbg(pegasus, drv, pegasus->net,
+				  "%s, status %d\n", __func__, status);
+		break;
 	}
 	pegasus->flags &= ~ETH_REGS_CHANGED;
 	wake_up(&pegasus->ctrl_wait);
@@ -149,9 +150,8 @@ static int get_registers(pegasus_t * peg
 
 	buffer = kmalloc(size, GFP_KERNEL);
 	if (!buffer) {
-		if (netif_msg_drv(pegasus))
-			dev_warn(&pegasus->intf->dev, "out of memory in %s\n",
-					__func__);
+		netif_warn(pegasus, drv, pegasus->net,
+			   "out of memory in %s\n", __func__);
 		return -ENOMEM;
 	}
 	add_wait_queue(&pegasus->ctrl_wait, &wait);
@@ -181,9 +181,9 @@ static int get_registers(pegasus_t * peg
 		set_current_state(TASK_RUNNING);
 		if (ret == -ENODEV)
 			netif_device_detach(pegasus->net);
-		if (netif_msg_drv(pegasus) && printk_ratelimit())
-			dev_err(&pegasus->intf->dev, "%s, status %d\n",
-					__func__, ret);
+		if (net_ratelimit())
+			netif_err(pegasus, drv, pegasus->net,
+				  "%s, status %d\n", __func__, ret);
 		goto out;
 	}
 
@@ -205,9 +205,8 @@ static int set_registers(pegasus_t * peg
 
 	buffer = kmalloc(size, GFP_KERNEL);
 	if (!buffer) {
-		if (netif_msg_drv(pegasus))
-			dev_warn(&pegasus->intf->dev, "out of memory in %s\n",
-					__func__);
+		netif_warn(pegasus, drv, pegasus->net,
+			   "out of memory in %s\n", __func__);
 		return -ENOMEM;
 	}
 	memcpy(buffer, data, size);
@@ -237,9 +236,8 @@ static int set_registers(pegasus_t * peg
 	if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
 		if (ret == -ENODEV)
 			netif_device_detach(pegasus->net);
-		if (netif_msg_drv(pegasus))
-			dev_err(&pegasus->intf->dev, "%s, status %d\n",
-					__func__, ret);
+		netif_err(pegasus, drv, pegasus->net,
+			  "%s, status %d\n", __func__, ret);
 		goto out;
 	}
 
@@ -259,9 +257,8 @@ static int set_register(pegasus_t * pega
 
 	tmp = kmalloc(1, GFP_KERNEL);
 	if (!tmp) {
-		if (netif_msg_drv(pegasus))
-			dev_warn(&pegasus->intf->dev, "out of memory in %s\n",
-					__func__);
+		netif_warn(pegasus, drv, pegasus->net,
+			   "out of memory in %s\n", __func__);
 		return -ENOMEM;
 	}
 	memcpy(tmp, &data, 1);
@@ -290,9 +287,9 @@ static int set_register(pegasus_t * pega
 	if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
 		if (ret == -ENODEV)
 			netif_device_detach(pegasus->net);
-		if (netif_msg_drv(pegasus) && printk_ratelimit())
-			dev_err(&pegasus->intf->dev, "%s, status %d\n",
-					__func__, ret);
+		if (net_ratelimit())
+			netif_err(pegasus, drv, pegasus->net,
+				  "%s, status %d\n", __func__, ret);
 		goto out;
 	}
 
@@ -323,9 +320,8 @@ static int update_eth_regs_async(pegasus
 	if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
 		if (ret == -ENODEV)
 			netif_device_detach(pegasus->net);
-		if (netif_msg_drv(pegasus))
-			dev_err(&pegasus->intf->dev, "%s, status %d\n",
-					__func__, ret);
+		netif_err(pegasus, drv, pegasus->net,
+			  "%s, status %d\n", __func__, ret);
 	}
 
 	return ret;
@@ -349,14 +345,16 @@ static int read_mii_word(pegasus_t * peg
 		if (data[0] & PHY_DONE)
 			break;
 	}
-	if (i < REG_TIMEOUT) {
-		ret = get_registers(pegasus, PhyData, 2, &regdi);
-		*regd = le16_to_cpu(regdi);
-		return ret;
-	}
+
+	if (i >= REG_TIMEOUT)
+		goto fail;
+
+	ret = get_registers(pegasus, PhyData, 2, &regdi);
+	*regd = le16_to_cpu(regdi);
+	return ret;
+
 fail:
-	if (netif_msg_drv(pegasus))
-		dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
+	netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__);
 
 	return ret;
 }
@@ -388,12 +386,14 @@ static int write_mii_word(pegasus_t * pe
 		if (data[0] & PHY_DONE)
 			break;
 	}
-	if (i < REG_TIMEOUT)
-		return ret;
+
+	if (i >= REG_TIMEOUT)
+		goto fail;
+
+	return ret;
 
 fail:
-	if (netif_msg_drv(pegasus))
-		dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
+	netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__);
 	return -ETIMEDOUT;
 }
 
@@ -422,15 +422,15 @@ static int read_eprom_word(pegasus_t * p
 		if (ret == -ESHUTDOWN)
 			goto fail;
 	}
-	if (i < REG_TIMEOUT) {
-		ret = get_registers(pegasus, EpromData, 2, &retdatai);
-		*retdata = le16_to_cpu(retdatai);
-		return ret;
-	}
+	if (i >= REG_TIMEOUT)
+		goto fail;
+
+	ret = get_registers(pegasus, EpromData, 2, &retdatai);
+	*retdata = le16_to_cpu(retdatai);
+	return ret;
 
 fail:
-	if (netif_msg_drv(pegasus))
-		dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
+	netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__);
 	return -ETIMEDOUT;
 }
 
@@ -475,11 +475,13 @@ static int write_eprom_word(pegasus_t *
 			break;
 	}
 	disable_eprom_write(pegasus);
-	if (i < REG_TIMEOUT)
-		return ret;
+	if (i >= REG_TIMEOUT)
+		goto fail;
+
+	return ret;
+
 fail:
-	if (netif_msg_drv(pegasus))
-		dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
+	netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__);
 	return -ETIMEDOUT;
 }
 #endif				/* PEGASUS_WRITE_EEPROM */
@@ -642,25 +644,20 @@ static void read_bulk_callback(struct ur
 	case 0:
 		break;
 	case -ETIME:
-		if (netif_msg_rx_err(pegasus))
-			pr_debug("%s: reset MAC\n", net->name);
+		netif_dbg(pegasus, rx_err, net, "reset MAC\n");
 		pegasus->flags &= ~PEGASUS_RX_BUSY;
 		break;
 	case -EPIPE:		/* stall, or disconnect from TT */
 		/* FIXME schedule work to clear the halt */
-		if (netif_msg_rx_err(pegasus))
-			printk(KERN_WARNING "%s: no rx stall recovery\n",
-					net->name);
+		netif_warn(pegasus, rx_err, net, "no rx stall recovery\n");
 		return;
 	case -ENOENT:
 	case -ECONNRESET:
 	case -ESHUTDOWN:
-		if (netif_msg_ifdown(pegasus))
-			pr_debug("%s: rx unlink, %d\n", net->name, status);
+		netif_dbg(pegasus, ifdown, net, "rx unlink, %d\n", status);
 		return;
 	default:
-		if (netif_msg_rx_err(pegasus))
-			pr_debug("%s: RX status %d\n", net->name, status);
+		netif_dbg(pegasus, rx_err, net, "RX status %d\n", status);
 		goto goon;
 	}
 
@@ -669,9 +666,8 @@ static void read_bulk_callback(struct ur
 
 	rx_status = buf[count - 2];
 	if (rx_status & 0x1e) {
-		if (netif_msg_rx_err(pegasus))
-			pr_debug("%s: RX packet error %x\n",
-					net->name, rx_status);
+		netif_dbg(pegasus, rx_err, net,
+			  "RX packet error %x\n", rx_status);
 		pegasus->stats.rx_errors++;
 		if (rx_status & 0x06)	// long or runt
 			pegasus->stats.rx_length_errors++;
@@ -758,9 +754,7 @@ static void rx_fixup(unsigned long data)
 		pegasus->rx_skb = pull_skb(pegasus);
 	}
 	if (pegasus->rx_skb == NULL) {
-		if (netif_msg_rx_err(pegasus))
-			printk(KERN_WARNING "%s: low on memory\n",
-					pegasus->net->name);
+		netif_warn(pegasus, rx_err, pegasus->net, "low on memory\n");
 		tasklet_schedule(&pegasus->rx_tl);
 		goto done;
 	}
@@ -800,19 +794,15 @@ static void write_bulk_callback(struct u
 	case -EPIPE:
 		/* FIXME schedule_work() to clear the tx halt */
 		netif_stop_queue(net);
-		if (netif_msg_tx_err(pegasus))
-			printk(KERN_WARNING "%s: no tx stall recovery\n",
-					net->name);
+		netif_warn(pegasus, tx_err, net, "no tx stall recovery\n");
 		return;
 	case -ENOENT:
 	case -ECONNRESET:
 	case -ESHUTDOWN:
-		if (netif_msg_ifdown(pegasus))
-			pr_debug("%s: tx unlink, %d\n", net->name, status);
+		netif_dbg(pegasus, ifdown, net, "tx unlink, %d\n", status);
 		return;
 	default:
-		if (netif_msg_tx_err(pegasus))
-			pr_info("%s: TX status %d\n", net->name, status);
+		netif_info(pegasus, tx_err, net, "TX status %d\n", status);
 		/* FALL THROUGH */
 	case 0:
 		break;
@@ -843,9 +833,7 @@ static void intr_callback(struct urb *ur
 		/* some Pegasus-I products report LOTS of data
 		 * toggle errors... avoid log spamming
 		 */
-		if (netif_msg_timer(pegasus))
-			pr_debug("%s: intr status %d\n", net->name,
-					status);
+		netif_dbg(pegasus, timer, net, "intr status %d\n", status);
 	}
 
 	if (urb->actual_length >= 6) {
@@ -875,16 +863,15 @@ static void intr_callback(struct urb *ur
 	res = usb_submit_urb(urb, GFP_ATOMIC);
 	if (res == -ENODEV)
 		netif_device_detach(pegasus->net);
-	if (res && netif_msg_timer(pegasus))
-		printk(KERN_ERR "%s: can't resubmit interrupt urb, %d\n",
-				net->name, res);
+	if (res)
+		netif_err(pegasus, timer, net,
+			  "can't resubmit interrupt urb, %d\n", res);
 }
 
 static void pegasus_tx_timeout(struct net_device *net)
 {
 	pegasus_t *pegasus = netdev_priv(net);
-	if (netif_msg_timer(pegasus))
-		printk(KERN_WARNING "%s: tx timeout\n", net->name);
+	netif_warn(pegasus, timer, net, "tx timeout\n");
 	usb_unlink_urb(pegasus->tx_urb);
 	pegasus->stats.tx_errors++;
 }
@@ -906,9 +893,7 @@ static netdev_tx_t pegasus_start_xmit(st
 			  pegasus->tx_buff, count,
 			  write_bulk_callback, pegasus);
 	if ((res = usb_submit_urb(pegasus->tx_urb, GFP_ATOMIC))) {
-		if (netif_msg_tx_err(pegasus))
-			printk(KERN_WARNING "%s: fail tx, %d\n",
-					net->name, res);
+		netif_warn(pegasus, tx_err, net, "fail tx, %d\n", res);
 		switch (res) {
 		case -EPIPE:		/* stall, or disconnect from TT */
 			/* cleanup should already have been scheduled */
@@ -952,10 +937,9 @@ static inline void get_interrupt_interva
 	interval = data >> 8;
 	if (pegasus->usb->speed != USB_SPEED_HIGH) {
 		if (interval < 0x80) {
-			if (netif_msg_timer(pegasus))
-				dev_info(&pegasus->intf->dev, "intr interval "
-					"changed from %ums to %ums\n",
-					interval, 0x80);
+			netif_info(pegasus, timer, pegasus->net,
+				   "intr interval changed from %ums to %ums\n",
+				   interval, 0x80);
 			interval = 0x80;
 			data = (data & 0x00FF) | ((u16)interval << 8);
 #ifdef PEGASUS_WRITE_EEPROM
@@ -1046,8 +1030,7 @@ static int pegasus_open(struct net_devic
 	if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) {
 		if (res == -ENODEV)
 			netif_device_detach(pegasus->net);
-		if (netif_msg_ifup(pegasus))
-			pr_debug("%s: failed rx_urb, %d", net->name, res);
+		netif_dbg(pegasus, ifup, net, "failed rx_urb, %d\n", res);
 		goto exit;
 	}
 
@@ -1058,15 +1041,13 @@ static int pegasus_open(struct net_devic
 	if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) {
 		if (res == -ENODEV)
 			netif_device_detach(pegasus->net);
-		if (netif_msg_ifup(pegasus))
-			pr_debug("%s: failed intr_urb, %d\n", net->name, res);
+		netif_dbg(pegasus, ifup, net, "failed intr_urb, %d\n", res);
 		usb_kill_urb(pegasus->rx_urb);
 		goto exit;
 	}
 	if ((res = enable_net_traffic(net, pegasus->usb))) {
-		if (netif_msg_ifup(pegasus))
-			pr_debug("%s: can't enable_net_traffic() - %d\n",
-					net->name, res);
+		netif_dbg(pegasus, ifup, net,
+			  "can't enable_net_traffic() - %d\n", res);
 		res = -EIO;
 		usb_kill_urb(pegasus->rx_urb);
 		usb_kill_urb(pegasus->intr_urb);
@@ -1075,8 +1056,7 @@ static int pegasus_open(struct net_devic
 	}
 	set_carrier(net);
 	netif_start_queue(net);
-	if (netif_msg_ifup(pegasus))
-		pr_debug("%s: open\n", net->name);
+	netif_dbg(pegasus, ifup, net, "open\n");
 	res = 0;
 exit:
 	return res;
@@ -1230,13 +1210,11 @@ static void pegasus_set_multicast(struct
 
 	if (net->flags & IFF_PROMISC) {
 		pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS;
-		if (netif_msg_link(pegasus))
-			pr_info("%s: Promiscuous mode enabled.\n", net->name);
-	} else if (net->mc_count || (net->flags & IFF_ALLMULTI)) {
+		netif_info(pegasus, link, net, "Promiscuous mode enabled\n");
+	} else if (!netdev_mc_empty(net) || (net->flags & IFF_ALLMULTI)) {
 		pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST;
 		pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
-		if (netif_msg_link(pegasus))
-			pr_debug("%s: set allmulti\n", net->name);
+		netif_dbg(pegasus, link, net, "set allmulti\n");
 	} else {
 		pegasus->eth_regs[EthCtrl0] &= ~RX_MULTICAST;
 		pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/pegasus.h linux-libre-2.6.34-gnu1/drivers/net/usb/pegasus.h
--- linux-libre-2.6.33-gnu1/drivers/net/usb/pegasus.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/pegasus.h	2010-05-16 17:17:36.000000000 -0400
@@ -177,7 +177,7 @@ PEGASUS_DEV( "USB 10/100 Fast Ethernet",
 PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1,
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c,
-		DEFAULT_GPIO_RESET | PEGASUS_II ) 	
+		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
@@ -208,6 +208,8 @@ PEGASUS_DEV( "Allied Telesyn Int. AT-USB
  */
 PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "Belkin F5U122 10/100 USB Ethernet", VENDOR_BELKIN, 0x0122,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
@@ -249,7 +251,7 @@ PEGASUS_DEV( "GIGABYTE GN-BR402W Wireles
 PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c,
-		DEFAULT_GPIO_RESET | PEGASUS_II )	
+		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/rndis_host.c linux-libre-2.6.34-gnu1/drivers/net/usb/rndis_host.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/rndis_host.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/rndis_host.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/usb/cdc.h>
@@ -57,8 +58,8 @@
  */
 void rndis_status(struct usbnet *dev, struct urb *urb)
 {
-	devdbg(dev, "rndis status urb, len %d stat %d",
-		urb->actual_length, urb->status);
+	netdev_dbg(dev->net, "rndis status urb, len %d stat %d\n",
+		   urb->actual_length, urb->status);
 	// FIXME for keepalives, respond immediately (asynchronously)
 	// if not an RNDIS status, do like cdc_status(dev,urb) does
 }
@@ -335,8 +336,8 @@ generic_rndis_bind(struct usbnet *dev, s
 
 	dev->maxpacket = usb_maxpacket(dev->udev, dev->out, 1);
 	if (dev->maxpacket == 0) {
-		if (netif_msg_probe(dev))
-			dev_dbg(&intf->dev, "dev->maxpacket can't be 0\n");
+		netif_dbg(dev, probe, dev->net,
+			  "dev->maxpacket can't be 0\n");
 		retval = -EINVAL;
 		goto fail_and_release;
 	}
@@ -394,17 +395,15 @@ generic_rndis_bind(struct usbnet *dev, s
 	}
 	if ((flags & FLAG_RNDIS_PHYM_WIRELESS) &&
 			*phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
-		if (netif_msg_probe(dev))
-			dev_dbg(&intf->dev, "driver requires wireless "
-				"physical medium, but device is not.\n");
+		netif_dbg(dev, probe, dev->net,
+			  "driver requires wireless physical medium, but device is not\n");
 		retval = -ENODEV;
 		goto halt_fail_and_release;
 	}
 	if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) &&
 			*phym == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
-		if (netif_msg_probe(dev))
-			dev_dbg(&intf->dev, "driver requires non-wireless "
-				"physical medium, but device is wireless.\n");
+		netif_dbg(dev, probe, dev->net,
+			  "driver requires non-wireless physical medium, but device is wireless.\n");
 		retval = -ENODEV;
 		goto halt_fail_and_release;
 	}
@@ -497,9 +496,9 @@ int rndis_rx_fixup(struct usbnet *dev, s
 			     skb->len < msg_len ||
 			     (data_offset + data_len + 8) > msg_len)) {
 			dev->net->stats.rx_frame_errors++;
-			devdbg(dev, "bad rndis message %d/%d/%d/%d, len %d",
-				le32_to_cpu(hdr->msg_type),
-				msg_len, data_offset, data_len, skb->len);
+			netdev_dbg(dev->net, "bad rndis message %d/%d/%d/%d, len %d\n",
+				   le32_to_cpu(hdr->msg_type),
+				   msg_len, data_offset, data_len, skb->len);
 			return 0;
 		}
 		skb_pull(skb, 8 + data_offset);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/rtl8150.c linux-libre-2.6.34-gnu1/drivers/net/usb/rtl8150.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/rtl8150.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/rtl8150.c	2010-05-16 17:17:36.000000000 -0400
@@ -313,20 +313,17 @@ static int rtl8150_set_mac_address(struc
 {
 	struct sockaddr *addr = p;
 	rtl8150_t *dev = netdev_priv(netdev);
-	int i;
 
 	if (netif_running(netdev))
 		return -EBUSY;
 
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-	dbg("%s: Setting MAC address to ", netdev->name);
-	for (i = 0; i < 5; i++)
-		dbg("%02X:", netdev->dev_addr[i]);
-	dbg("%02X\n", netdev->dev_addr[i]);
+	dbg("%s: Setting MAC address to %pM\n", netdev->name, netdev->dev_addr);
 	/* Set the IDR registers. */
 	set_registers(dev, IDR, netdev->addr_len, netdev->dev_addr);
 #ifdef EEPROM_WRITE
 	{
+	int i;
 	u8 cr;
 	/* Get the CR contents. */
 	get_registers(dev, CR, 1, &cr);
@@ -714,7 +711,7 @@ static void rtl8150_set_multicast(struct
 	if (netdev->flags & IFF_PROMISC) {
 		dev->rx_creg |= cpu_to_le16(0x0001);
 		dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name);
-	} else if (netdev->mc_count ||
+	} else if (!netdev_mc_empty(netdev) ||
 		   (netdev->flags & IFF_ALLMULTI)) {
 		dev->rx_creg &= cpu_to_le16(0xfffe);
 		dev->rx_creg |= cpu_to_le16(0x0002);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/sierra_net.c linux-libre-2.6.34-gnu1/drivers/net/usb/sierra_net.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/sierra_net.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/sierra_net.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1004 @@
+/*
+ * USB-to-WWAN Driver for Sierra Wireless modems
+ *
+ * Copyright (C) 2008, 2009, 2010 Paxton Smith, Matthew Safar, Rory Filer
+ *                          <linux@sierrawireless.com>
+ *
+ * Portions of this based on the cdc_ether driver by David Brownell (2003-2005)
+ * and Ole Andre Vadla Ravnas (ActiveSync) (2006).
+ *
+ * IMPORTANT DISCLAIMER: This driver is not commercially supported by
+ * Sierra Wireless. Use at your own risk.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 DRIVER_VERSION "v.2.0"
+#define DRIVER_AUTHOR "Paxton Smith, Matthew Safar, Rory Filer"
+#define DRIVER_DESC "USB-to-WWAN Driver for Sierra Wireless modems"
+static const char driver_name[] = "sierra_net";
+
+/* if defined debug messages enabled */
+/*#define	DEBUG*/
+
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/usb.h>
+#include <linux/usb/cdc.h>
+#include <net/ip.h>
+#include <net/udp.h>
+#include <asm/unaligned.h>
+#include <linux/usb/usbnet.h>
+
+#define SWI_USB_REQUEST_GET_FW_ATTR	0x06
+#define SWI_GET_FW_ATTR_MASK		0x08
+
+/* atomic counter partially included in MAC address to make sure 2 devices
+ * do not end up with the same MAC - concept breaks in case of > 255 ifaces
+ */
+static	atomic_t iface_counter = ATOMIC_INIT(0);
+
+/*
+ * SYNC Timer Delay definition used to set the expiry time
+ */
+#define SIERRA_NET_SYNCDELAY (2*HZ)
+
+/* Max. MTU supported. The modem buffers are limited to 1500 */
+#define SIERRA_NET_MAX_SUPPORTED_MTU	1500
+
+/* The SIERRA_NET_USBCTL_BUF_LEN defines a buffer size allocated for control
+ * message reception ... and thus the max. received packet.
+ * (May be the cause for parse_hip returning -EINVAL)
+ */
+#define SIERRA_NET_USBCTL_BUF_LEN	1024
+
+/* list of interface numbers - used for constructing interface lists */
+struct sierra_net_iface_info {
+	const u32 infolen;	/* number of interface numbers on list */
+	const u8  *ifaceinfo;	/* pointer to the array holding the numbers */
+};
+
+struct sierra_net_info_data {
+	u16 rx_urb_size;
+	struct sierra_net_iface_info whitelist;
+};
+
+/* Private data structure */
+struct sierra_net_data {
+
+	u8 ethr_hdr_tmpl[ETH_HLEN]; /* ethernet header template for rx'd pkts */
+
+	u16 link_up;		/* air link up or down */
+	u8 tx_hdr_template[4];	/* part of HIP hdr for tx'd packets */
+
+	u8 sync_msg[4];		/* SYNC message */
+	u8 shdwn_msg[4];	/* Shutdown message */
+
+	/* Backpointer to the container */
+	struct usbnet *usbnet;
+
+	u8 ifnum;	/* interface number */
+
+/* Bit masks, must be a power of 2 */
+#define SIERRA_NET_EVENT_RESP_AVAIL    0x01
+#define SIERRA_NET_TIMER_EXPIRY        0x02
+	unsigned long kevent_flags;
+	struct work_struct sierra_net_kevent;
+	struct timer_list sync_timer; /* For retrying SYNC sequence */
+};
+
+struct param {
+	int is_present;
+	union {
+		void  *ptr;
+		u32    dword;
+		u16    word;
+		u8     byte;
+	};
+};
+
+/* HIP message type */
+#define SIERRA_NET_HIP_EXTENDEDID	0x7F
+#define SIERRA_NET_HIP_HSYNC_ID		0x60	/* Modem -> host */
+#define SIERRA_NET_HIP_RESTART_ID	0x62	/* Modem -> host */
+#define SIERRA_NET_HIP_MSYNC_ID		0x20	/* Host -> modem */
+#define SIERRA_NET_HIP_SHUTD_ID		0x26	/* Host -> modem */
+
+#define SIERRA_NET_HIP_EXT_IP_IN_ID   0x0202
+#define SIERRA_NET_HIP_EXT_IP_OUT_ID  0x0002
+
+/* 3G UMTS Link Sense Indication definitions */
+#define SIERRA_NET_HIP_LSI_UMTSID	0x78
+
+/* Reverse Channel Grant Indication HIP message */
+#define SIERRA_NET_HIP_RCGI		0x64
+
+/* LSI Protocol types */
+#define SIERRA_NET_PROTOCOL_UMTS      0x01
+/* LSI Coverage */
+#define SIERRA_NET_COVERAGE_NONE      0x00
+#define SIERRA_NET_COVERAGE_NOPACKET  0x01
+
+/* LSI Session */
+#define SIERRA_NET_SESSION_IDLE       0x00
+/* LSI Link types */
+#define SIERRA_NET_AS_LINK_TYPE_IPv4  0x00
+
+struct lsi_umts {
+	u8 protocol;
+	u8 unused1;
+	__be16 length;
+	/* eventually use a union for the rest - assume umts for now */
+	u8 coverage;
+	u8 unused2[41];
+	u8 session_state;
+	u8 unused3[33];
+	u8 link_type;
+	u8 pdp_addr_len; /* NW-supplied PDP address len */
+	u8 pdp_addr[16]; /* NW-supplied PDP address (bigendian)) */
+	u8 unused4[23];
+	u8 dns1_addr_len; /* NW-supplied 1st DNS address len (bigendian) */
+	u8 dns1_addr[16]; /* NW-supplied 1st DNS address */
+	u8 dns2_addr_len; /* NW-supplied 2nd DNS address len */
+	u8 dns2_addr[16]; /* NW-supplied 2nd DNS address (bigendian)*/
+	u8 wins1_addr_len; /* NW-supplied 1st Wins address len */
+	u8 wins1_addr[16]; /* NW-supplied 1st Wins address (bigendian)*/
+	u8 wins2_addr_len; /* NW-supplied 2nd Wins address len */
+	u8 wins2_addr[16]; /* NW-supplied 2nd Wins address (bigendian) */
+	u8 unused5[4];
+	u8 gw_addr_len; /* NW-supplied GW address len */
+	u8 gw_addr[16]; /* NW-supplied GW address (bigendian) */
+	u8 reserved[8];
+} __attribute__ ((packed));
+
+#define SIERRA_NET_LSI_COMMON_LEN      4
+#define SIERRA_NET_LSI_UMTS_LEN        (sizeof(struct lsi_umts))
+#define SIERRA_NET_LSI_UMTS_STATUS_LEN \
+	(SIERRA_NET_LSI_UMTS_LEN - SIERRA_NET_LSI_COMMON_LEN)
+
+/* Forward definitions */
+static void sierra_sync_timer(unsigned long syncdata);
+static int sierra_net_change_mtu(struct net_device *net, int new_mtu);
+
+/* Our own net device operations structure */
+static const struct net_device_ops sierra_net_device_ops = {
+	.ndo_open               = usbnet_open,
+	.ndo_stop               = usbnet_stop,
+	.ndo_start_xmit         = usbnet_start_xmit,
+	.ndo_tx_timeout         = usbnet_tx_timeout,
+	.ndo_change_mtu         = sierra_net_change_mtu,
+	.ndo_set_mac_address    = eth_mac_addr,
+	.ndo_validate_addr      = eth_validate_addr,
+};
+
+/* get private data associated with passed in usbnet device */
+static inline struct sierra_net_data *sierra_net_get_private(struct usbnet *dev)
+{
+	return (struct sierra_net_data *)dev->data[0];
+}
+
+/* set private data associated with passed in usbnet device */
+static inline void sierra_net_set_private(struct usbnet *dev,
+			struct sierra_net_data *priv)
+{
+	dev->data[0] = (unsigned long)priv;
+}
+
+/* is packet IPv4 */
+static inline int is_ip(struct sk_buff *skb)
+{
+	return (skb->protocol == cpu_to_be16(ETH_P_IP));
+}
+
+/*
+ * check passed in packet and make sure that:
+ *  - it is linear (no scatter/gather)
+ *  - it is ethernet (mac_header properly set)
+ */
+static int check_ethip_packet(struct sk_buff *skb, struct usbnet *dev)
+{
+	skb_reset_mac_header(skb); /* ethernet header */
+
+	if (skb_is_nonlinear(skb)) {
+		netdev_err(dev->net, "Non linear buffer-dropping\n");
+		return 0;
+	}
+
+	if (!pskb_may_pull(skb, ETH_HLEN))
+		return 0;
+	skb->protocol = eth_hdr(skb)->h_proto;
+
+	return 1;
+}
+
+static const u8 *save16bit(struct param *p, const u8 *datap)
+{
+	p->is_present = 1;
+	p->word = get_unaligned_be16(datap);
+	return datap + sizeof(p->word);
+}
+
+static const u8 *save8bit(struct param *p, const u8 *datap)
+{
+	p->is_present = 1;
+	p->byte = *datap;
+	return datap + sizeof(p->byte);
+}
+
+/*----------------------------------------------------------------------------*
+ *                              BEGIN HIP                                     *
+ *----------------------------------------------------------------------------*/
+/* HIP header */
+#define SIERRA_NET_HIP_HDR_LEN 4
+/* Extended HIP header */
+#define SIERRA_NET_HIP_EXT_HDR_LEN 6
+
+struct hip_hdr {
+	int    hdrlen;
+	struct param payload_len;
+	struct param msgid;
+	struct param msgspecific;
+	struct param extmsgid;
+};
+
+static int parse_hip(const u8 *buf, const u32 buflen, struct hip_hdr *hh)
+{
+	const u8 *curp = buf;
+	int    padded;
+
+	if (buflen < SIERRA_NET_HIP_HDR_LEN)
+		return -EPROTO;
+
+	curp = save16bit(&hh->payload_len, curp);
+	curp = save8bit(&hh->msgid, curp);
+	curp = save8bit(&hh->msgspecific, curp);
+
+	padded = hh->msgid.byte & 0x80;
+	hh->msgid.byte &= 0x7F;			/* 7 bits */
+
+	hh->extmsgid.is_present = (hh->msgid.byte == SIERRA_NET_HIP_EXTENDEDID);
+	if (hh->extmsgid.is_present) {
+		if (buflen < SIERRA_NET_HIP_EXT_HDR_LEN)
+			return -EPROTO;
+
+		hh->payload_len.word &= 0x3FFF; /* 14 bits */
+
+		curp = save16bit(&hh->extmsgid, curp);
+		hh->extmsgid.word &= 0x03FF;	/* 10 bits */
+
+		hh->hdrlen = SIERRA_NET_HIP_EXT_HDR_LEN;
+	} else {
+		hh->payload_len.word &= 0x07FF;	/* 11 bits */
+		hh->hdrlen = SIERRA_NET_HIP_HDR_LEN;
+	}
+
+	if (padded) {
+		hh->hdrlen++;
+		hh->payload_len.word--;
+	}
+
+	/* if real packet shorter than the claimed length */
+	if (buflen < (hh->hdrlen + hh->payload_len.word))
+		return -EINVAL;
+
+	return 0;
+}
+
+static void build_hip(u8 *buf, const u16 payloadlen,
+		struct sierra_net_data *priv)
+{
+	/* the following doesn't have the full functionality. We
+	 * currently build only one kind of header, so it is faster this way
+	 */
+	put_unaligned_be16(payloadlen, buf);
+	memcpy(buf+2, priv->tx_hdr_template, sizeof(priv->tx_hdr_template));
+}
+/*----------------------------------------------------------------------------*
+ *                              END HIP                                       *
+ *----------------------------------------------------------------------------*/
+
+static int sierra_net_send_cmd(struct usbnet *dev,
+		u8 *cmd, int cmdlen, const char * cmd_name)
+{
+	struct sierra_net_data *priv = sierra_net_get_private(dev);
+	int  status;
+
+	status = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+			USB_CDC_SEND_ENCAPSULATED_COMMAND,
+			USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE,	0,
+			priv->ifnum, cmd, cmdlen, USB_CTRL_SET_TIMEOUT);
+
+	if (status != cmdlen && status != -ENODEV)
+		netdev_err(dev->net, "Submit %s failed %d\n", cmd_name, status);
+
+	return status;
+}
+
+static int sierra_net_send_sync(struct usbnet *dev)
+{
+	int  status;
+	struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+
+	status = sierra_net_send_cmd(dev, priv->sync_msg,
+			sizeof(priv->sync_msg), "SYNC");
+
+	return status;
+}
+
+static void sierra_net_set_ctx_index(struct sierra_net_data *priv, u8 ctx_ix)
+{
+	dev_dbg(&(priv->usbnet->udev->dev), "%s %d", __func__, ctx_ix);
+	priv->tx_hdr_template[0] = 0x3F;
+	priv->tx_hdr_template[1] = ctx_ix;
+	*((u16 *)&priv->tx_hdr_template[2]) =
+		cpu_to_be16(SIERRA_NET_HIP_EXT_IP_OUT_ID);
+}
+
+static inline int sierra_net_is_valid_addrlen(u8 len)
+{
+	return (len == sizeof(struct in_addr));
+}
+
+static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen)
+{
+	struct lsi_umts *lsi = (struct lsi_umts *)data;
+
+	if (datalen < sizeof(struct lsi_umts)) {
+		netdev_err(dev->net, "%s: Data length %d, exp %Zu\n",
+				__func__, datalen,
+				sizeof(struct lsi_umts));
+		return -1;
+	}
+
+	if (lsi->length != cpu_to_be16(SIERRA_NET_LSI_UMTS_STATUS_LEN)) {
+		netdev_err(dev->net, "%s: LSI_UMTS_STATUS_LEN %d, exp %u\n",
+				__func__, be16_to_cpu(lsi->length),
+				(u32)SIERRA_NET_LSI_UMTS_STATUS_LEN);
+		return -1;
+	}
+
+	/* Validate the protocol  - only support UMTS for now */
+	if (lsi->protocol != SIERRA_NET_PROTOCOL_UMTS) {
+		netdev_err(dev->net, "Protocol unsupported, 0x%02x\n",
+			lsi->protocol);
+		return -1;
+	}
+
+	/* Validate the link type */
+	if (lsi->link_type != SIERRA_NET_AS_LINK_TYPE_IPv4) {
+		netdev_err(dev->net, "Link type unsupported: 0x%02x\n",
+			lsi->link_type);
+		return -1;
+	}
+
+	/* Validate the coverage */
+	if (lsi->coverage == SIERRA_NET_COVERAGE_NONE
+	   || lsi->coverage == SIERRA_NET_COVERAGE_NOPACKET) {
+		netdev_err(dev->net, "No coverage, 0x%02x\n", lsi->coverage);
+		return 0;
+	}
+
+	/* Validate the session state */
+	if (lsi->session_state == SIERRA_NET_SESSION_IDLE) {
+		netdev_err(dev->net, "Session idle, 0x%02x\n",
+			lsi->session_state);
+		return 0;
+	}
+
+	/* Set link_sense true */
+	return 1;
+}
+
+static void sierra_net_handle_lsi(struct usbnet *dev, char *data,
+		struct hip_hdr	*hh)
+{
+	struct sierra_net_data *priv = sierra_net_get_private(dev);
+	int link_up;
+
+	link_up = sierra_net_parse_lsi(dev, data + hh->hdrlen,
+					hh->payload_len.word);
+	if (link_up < 0) {
+		netdev_err(dev->net, "Invalid LSI\n");
+		return;
+	}
+	if (link_up) {
+		sierra_net_set_ctx_index(priv, hh->msgspecific.byte);
+		priv->link_up = 1;
+		netif_carrier_on(dev->net);
+	} else {
+		priv->link_up = 0;
+		netif_carrier_off(dev->net);
+	}
+}
+
+static void sierra_net_dosync(struct usbnet *dev)
+{
+	int status;
+	struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+
+	/* tell modem we are ready */
+	status = sierra_net_send_sync(dev);
+	if (status < 0)
+		netdev_err(dev->net,
+			"Send SYNC failed, status %d\n", status);
+	status = sierra_net_send_sync(dev);
+	if (status < 0)
+		netdev_err(dev->net,
+			"Send SYNC failed, status %d\n", status);
+
+	/* Now, start a timer and make sure we get the Restart Indication */
+	priv->sync_timer.function = sierra_sync_timer;
+	priv->sync_timer.data = (unsigned long) dev;
+	priv->sync_timer.expires = jiffies + SIERRA_NET_SYNCDELAY;
+	add_timer(&priv->sync_timer);
+}
+
+static void sierra_net_kevent(struct work_struct *work)
+{
+	struct sierra_net_data *priv =
+		container_of(work, struct sierra_net_data, sierra_net_kevent);
+	struct usbnet *dev = priv->usbnet;
+	int  len;
+	int  err;
+	u8  *buf;
+	u8   ifnum;
+
+	if (test_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags)) {
+		clear_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags);
+
+		/* Query the modem for the LSI message */
+		buf = kzalloc(SIERRA_NET_USBCTL_BUF_LEN, GFP_KERNEL);
+		if (!buf) {
+			netdev_err(dev->net,
+				"failed to allocate buf for LS msg\n");
+			return;
+		}
+		ifnum = priv->ifnum;
+		len = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
+				USB_CDC_GET_ENCAPSULATED_RESPONSE,
+				USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE,
+				0, ifnum, buf, SIERRA_NET_USBCTL_BUF_LEN,
+				USB_CTRL_SET_TIMEOUT);
+
+		if (len < 0) {
+			netdev_err(dev->net,
+				"usb_control_msg failed, status %d\n", len);
+		} else {
+			struct hip_hdr	hh;
+
+			dev_dbg(&dev->udev->dev, "%s: Received status message,"
+				" %04x bytes", __func__, len);
+
+			err = parse_hip(buf, len, &hh);
+			if (err) {
+				netdev_err(dev->net, "%s: Bad packet,"
+					" parse result %d\n", __func__, err);
+				kfree(buf);
+				return;
+			}
+
+			/* Validate packet length */
+			if (len != hh.hdrlen + hh.payload_len.word) {
+				netdev_err(dev->net, "%s: Bad packet, received"
+					" %d, expected %d\n",	__func__, len,
+					hh.hdrlen + hh.payload_len.word);
+				kfree(buf);
+				return;
+			}
+
+			/* Switch on received message types */
+			switch (hh.msgid.byte) {
+			case SIERRA_NET_HIP_LSI_UMTSID:
+				dev_dbg(&dev->udev->dev, "LSI for ctx:%d",
+					hh.msgspecific.byte);
+				sierra_net_handle_lsi(dev, buf, &hh);
+				break;
+			case SIERRA_NET_HIP_RESTART_ID:
+				dev_dbg(&dev->udev->dev, "Restart reported: %d,"
+						" stopping sync timer",
+						hh.msgspecific.byte);
+				/* Got sync resp - stop timer & clear mask */
+				del_timer_sync(&priv->sync_timer);
+				clear_bit(SIERRA_NET_TIMER_EXPIRY,
+					  &priv->kevent_flags);
+				break;
+			case SIERRA_NET_HIP_HSYNC_ID:
+				dev_dbg(&dev->udev->dev, "SYNC received");
+				err = sierra_net_send_sync(dev);
+				if (err < 0)
+					netdev_err(dev->net,
+						"Send SYNC failed %d\n", err);
+				break;
+			case SIERRA_NET_HIP_EXTENDEDID:
+				netdev_err(dev->net, "Unrecognized HIP msg, "
+					"extmsgid 0x%04x\n", hh.extmsgid.word);
+				break;
+			case SIERRA_NET_HIP_RCGI:
+				/* Ignored */
+				break;
+			default:
+				netdev_err(dev->net, "Unrecognized HIP msg, "
+					"msgid 0x%02x\n", hh.msgid.byte);
+				break;
+			}
+		}
+		kfree(buf);
+	}
+	/* The sync timer bit might be set */
+	if (test_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags)) {
+		clear_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags);
+		dev_dbg(&dev->udev->dev, "Deferred sync timer expiry");
+		sierra_net_dosync(priv->usbnet);
+	}
+
+	if (priv->kevent_flags)
+		dev_dbg(&dev->udev->dev, "sierra_net_kevent done, "
+			"kevent_flags = 0x%lx", priv->kevent_flags);
+}
+
+static void sierra_net_defer_kevent(struct usbnet *dev, int work)
+{
+	struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+	set_bit(work, &priv->kevent_flags);
+	schedule_work(&priv->sierra_net_kevent);
+}
+
+/*
+ * Sync Retransmit Timer Handler. On expiry, kick the work queue
+ */
+void sierra_sync_timer(unsigned long syncdata)
+{
+	struct usbnet *dev = (struct usbnet *)syncdata;
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+	/* Kick the tasklet */
+	sierra_net_defer_kevent(dev, SIERRA_NET_TIMER_EXPIRY);
+}
+
+static void sierra_net_status(struct usbnet *dev, struct urb *urb)
+{
+	struct usb_cdc_notification *event;
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+
+	if (urb->actual_length < sizeof *event)
+		return;
+
+	/* Add cases to handle other standard notifications. */
+	event = urb->transfer_buffer;
+	switch (event->bNotificationType) {
+	case USB_CDC_NOTIFY_NETWORK_CONNECTION:
+	case USB_CDC_NOTIFY_SPEED_CHANGE:
+		/* USB 305 sends those */
+		break;
+	case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
+		sierra_net_defer_kevent(dev, SIERRA_NET_EVENT_RESP_AVAIL);
+		break;
+	default:
+		netdev_err(dev->net, ": unexpected notification %02x!\n",
+				event->bNotificationType);
+		break;
+	}
+}
+
+static void sierra_net_get_drvinfo(struct net_device *net,
+		struct ethtool_drvinfo *info)
+{
+	/* Inherit standard device info */
+	usbnet_get_drvinfo(net, info);
+	strncpy(info->driver, driver_name, sizeof info->driver);
+	strncpy(info->version, DRIVER_VERSION, sizeof info->version);
+}
+
+static u32 sierra_net_get_link(struct net_device *net)
+{
+	struct usbnet *dev = netdev_priv(net);
+	/* Report link is down whenever the interface is down */
+	return sierra_net_get_private(dev)->link_up && netif_running(net);
+}
+
+static struct ethtool_ops sierra_net_ethtool_ops = {
+	.get_drvinfo = sierra_net_get_drvinfo,
+	.get_link = sierra_net_get_link,
+	.get_msglevel = usbnet_get_msglevel,
+	.set_msglevel = usbnet_set_msglevel,
+	.get_settings = usbnet_get_settings,
+	.set_settings = usbnet_set_settings,
+	.nway_reset = usbnet_nway_reset,
+};
+
+/* MTU can not be more than 1500 bytes, enforce it. */
+static int sierra_net_change_mtu(struct net_device *net, int new_mtu)
+{
+	if (new_mtu > SIERRA_NET_MAX_SUPPORTED_MTU)
+		return -EINVAL;
+
+	return usbnet_change_mtu(net, new_mtu);
+}
+
+static int is_whitelisted(const u8 ifnum,
+			const struct sierra_net_iface_info *whitelist)
+{
+	if (whitelist) {
+		const u8 *list = whitelist->ifaceinfo;
+		int i;
+
+		for (i = 0; i < whitelist->infolen; i++) {
+			if (list[i] == ifnum)
+				return 1;
+		}
+	}
+	return 0;
+}
+
+static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap)
+{
+	int result = 0;
+	u16 *attrdata;
+
+	attrdata = kmalloc(sizeof(*attrdata), GFP_KERNEL);
+	if (!attrdata)
+		return -ENOMEM;
+
+	result = usb_control_msg(
+			dev->udev,
+			usb_rcvctrlpipe(dev->udev, 0),
+			/* _u8 vendor specific request */
+			SWI_USB_REQUEST_GET_FW_ATTR,
+			USB_DIR_IN | USB_TYPE_VENDOR,	/* __u8 request type */
+			0x0000,		/* __u16 value not used */
+			0x0000,		/* __u16 index  not used */
+			attrdata,	/* char *data */
+			sizeof(*attrdata),		/* __u16 size */
+			USB_CTRL_SET_TIMEOUT);	/* int timeout */
+
+	if (result < 0) {
+		kfree(attrdata);
+		return -EIO;
+	}
+
+	*datap = *attrdata;
+
+	kfree(attrdata);
+	return result;
+}
+
+/*
+ * collects the bulk endpoints, the status endpoint.
+ */
+static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+	u8	ifacenum;
+	u8	numendpoints;
+	u16	fwattr = 0;
+	int	status;
+	struct ethhdr *eth;
+	struct sierra_net_data *priv;
+	static const u8 sync_tmplate[sizeof(priv->sync_msg)] = {
+		0x00, 0x00, SIERRA_NET_HIP_MSYNC_ID, 0x00};
+	static const u8 shdwn_tmplate[sizeof(priv->shdwn_msg)] = {
+		0x00, 0x00, SIERRA_NET_HIP_SHUTD_ID, 0x00};
+
+	struct sierra_net_info_data *data =
+			(struct sierra_net_info_data *)dev->driver_info->data;
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+
+	ifacenum = intf->cur_altsetting->desc.bInterfaceNumber;
+	/* We only accept certain interfaces */
+	if (!is_whitelisted(ifacenum, &data->whitelist)) {
+		dev_dbg(&dev->udev->dev, "Ignoring interface: %d", ifacenum);
+		return -ENODEV;
+	}
+	numendpoints = intf->cur_altsetting->desc.bNumEndpoints;
+	/* We have three endpoints, bulk in and out, and a status */
+	if (numendpoints != 3) {
+		dev_err(&dev->udev->dev, "Expected 3 endpoints, found: %d",
+			numendpoints);
+		return -ENODEV;
+	}
+	/* Status endpoint set in usbnet_get_endpoints() */
+	dev->status = NULL;
+	status = usbnet_get_endpoints(dev, intf);
+	if (status < 0) {
+		dev_err(&dev->udev->dev, "Error in usbnet_get_endpoints (%d)",
+			status);
+		return -ENODEV;
+	}
+	/* Initialize sierra private data */
+	priv = kzalloc(sizeof *priv, GFP_KERNEL);
+	if (!priv) {
+		dev_err(&dev->udev->dev, "No memory");
+		return -ENOMEM;
+	}
+
+	priv->usbnet = dev;
+	priv->ifnum = ifacenum;
+	dev->net->netdev_ops = &sierra_net_device_ops;
+
+	/* change MAC addr to include, ifacenum, and to be unique */
+	dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter);
+	dev->net->dev_addr[ETH_ALEN-1] = ifacenum;
+
+	/* we will have to manufacture ethernet headers, prepare template */
+	eth = (struct ethhdr *)priv->ethr_hdr_tmpl;
+	memcpy(&eth->h_dest, dev->net->dev_addr, ETH_ALEN);
+	eth->h_proto = cpu_to_be16(ETH_P_IP);
+
+	/* prepare shutdown message template */
+	memcpy(priv->shdwn_msg, shdwn_tmplate, sizeof(priv->shdwn_msg));
+	/* set context index initially to 0 - prepares tx hdr template */
+	sierra_net_set_ctx_index(priv, 0);
+
+	/* decrease the rx_urb_size and max_tx_size to 4k on USB 1.1 */
+	dev->rx_urb_size  = data->rx_urb_size;
+	if (dev->udev->speed != USB_SPEED_HIGH)
+		dev->rx_urb_size  = min_t(size_t, 4096, data->rx_urb_size);
+
+	dev->net->hard_header_len += SIERRA_NET_HIP_EXT_HDR_LEN;
+	dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+
+	/* Set up the netdev */
+	dev->net->flags |= IFF_NOARP;
+	dev->net->ethtool_ops = &sierra_net_ethtool_ops;
+	netif_carrier_off(dev->net);
+
+	sierra_net_set_private(dev, priv);
+
+	priv->kevent_flags = 0;
+
+	/* Use the shared workqueue */
+	INIT_WORK(&priv->sierra_net_kevent, sierra_net_kevent);
+
+	/* Only need to do this once */
+	init_timer(&priv->sync_timer);
+
+	/* verify fw attributes */
+	status = sierra_net_get_fw_attr(dev, &fwattr);
+	dev_dbg(&dev->udev->dev, "Fw attr: %x\n", fwattr);
+
+	/* test whether firmware supports DHCP */
+	if (!(status == sizeof(fwattr) && (fwattr & SWI_GET_FW_ATTR_MASK))) {
+		/* found incompatible firmware version */
+		dev_err(&dev->udev->dev, "Incompatible driver and firmware"
+			" versions\n");
+		kfree(priv);
+		return -ENODEV;
+	}
+	/* prepare sync message from template */
+	memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg));
+
+	/* initiate the sync sequence */
+	sierra_net_dosync(dev);
+
+	return 0;
+}
+
+static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+	int status;
+	struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+
+	/* Kill the timer then flush the work queue */
+	del_timer_sync(&priv->sync_timer);
+
+	flush_scheduled_work();
+
+	/* tell modem we are going away */
+	status = sierra_net_send_cmd(dev, priv->shdwn_msg,
+			sizeof(priv->shdwn_msg), "Shutdown");
+	if (status < 0)
+		netdev_err(dev->net,
+			"usb_control_msg failed, status %d\n", status);
+
+	sierra_net_set_private(dev, NULL);
+
+	kfree(priv);
+}
+
+static struct sk_buff *sierra_net_skb_clone(struct usbnet *dev,
+		struct sk_buff *skb, int len)
+{
+	struct sk_buff *new_skb;
+
+	/* clone skb */
+	new_skb = skb_clone(skb, GFP_ATOMIC);
+
+	/* remove len bytes from original */
+	skb_pull(skb, len);
+
+	/* trim next packet to it's length */
+	if (new_skb) {
+		skb_trim(new_skb, len);
+	} else {
+		if (netif_msg_rx_err(dev))
+			netdev_err(dev->net, "failed to get skb\n");
+		dev->net->stats.rx_dropped++;
+	}
+
+	return new_skb;
+}
+
+/* ---------------------------- Receive data path ----------------------*/
+static int sierra_net_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+	int err;
+	struct hip_hdr  hh;
+	struct sk_buff *new_skb;
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+
+	/* could contain multiple packets */
+	while (likely(skb->len)) {
+		err = parse_hip(skb->data, skb->len, &hh);
+		if (err) {
+			if (netif_msg_rx_err(dev))
+				netdev_err(dev->net, "Invalid HIP header %d\n",
+					err);
+			/* dev->net->stats.rx_errors incremented by caller */
+			dev->net->stats.rx_length_errors++;
+			return 0;
+		}
+
+		/* Validate Extended HIP header */
+		if (!hh.extmsgid.is_present
+		    || hh.extmsgid.word != SIERRA_NET_HIP_EXT_IP_IN_ID) {
+			if (netif_msg_rx_err(dev))
+				netdev_err(dev->net, "HIP/ETH: Invalid pkt\n");
+
+			dev->net->stats.rx_frame_errors++;
+			/* dev->net->stats.rx_errors incremented by caller */;
+			return 0;
+		}
+
+		skb_pull(skb, hh.hdrlen);
+
+		/* We are going to accept this packet, prepare it */
+		memcpy(skb->data, sierra_net_get_private(dev)->ethr_hdr_tmpl,
+			ETH_HLEN);
+
+		/* Last packet in batch handled by usbnet */
+		if (hh.payload_len.word == skb->len)
+			return 1;
+
+		new_skb = sierra_net_skb_clone(dev, skb, hh.payload_len.word);
+		if (new_skb)
+			usbnet_skb_return(dev, new_skb);
+
+	} /* while */
+
+	return 0;
+}
+
+/* ---------------------------- Transmit data path ----------------------*/
+struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+		gfp_t flags)
+{
+	struct sierra_net_data *priv = sierra_net_get_private(dev);
+	u16 len;
+	bool need_tail;
+
+	dev_dbg(&dev->udev->dev, "%s", __func__);
+	if (priv->link_up && check_ethip_packet(skb, dev) && is_ip(skb)) {
+		/* enough head room as is? */
+		if (SIERRA_NET_HIP_EXT_HDR_LEN <= skb_headroom(skb)) {
+			/* Save the Eth/IP length and set up HIP hdr */
+			len = skb->len;
+			skb_push(skb, SIERRA_NET_HIP_EXT_HDR_LEN);
+			/* Handle ZLP issue */
+			need_tail = ((len + SIERRA_NET_HIP_EXT_HDR_LEN)
+				% dev->maxpacket == 0);
+			if (need_tail) {
+				if (unlikely(skb_tailroom(skb) == 0)) {
+					netdev_err(dev->net, "tx_fixup:"
+						"no room for packet\n");
+					dev_kfree_skb_any(skb);
+					return NULL;
+				} else {
+					skb->data[skb->len] = 0;
+					__skb_put(skb, 1);
+					len = len + 1;
+				}
+			}
+			build_hip(skb->data, len, priv);
+			return skb;
+		} else {
+			/*
+			 * compensate in the future if necessary
+			 */
+			netdev_err(dev->net, "tx_fixup: no room for HIP\n");
+		} /* headroom */
+	}
+
+	if (!priv->link_up)
+		dev->net->stats.tx_carrier_errors++;
+
+	/* tx_dropped incremented by usbnet */
+
+	/* filter the packet out, release it  */
+	dev_kfree_skb_any(skb);
+	return NULL;
+}
+
+static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 };
+static const struct sierra_net_info_data sierra_net_info_data_68A3 = {
+	.rx_urb_size = 8 * 1024,
+	.whitelist = {
+		.infolen = ARRAY_SIZE(sierra_net_ifnum_list),
+		.ifaceinfo = sierra_net_ifnum_list
+	}
+};
+
+static const struct driver_info sierra_net_info_68A3 = {
+	.description = "Sierra Wireless USB-to-WWAN Modem",
+	.flags = FLAG_WWAN | FLAG_SEND_ZLP,
+	.bind = sierra_net_bind,
+	.unbind = sierra_net_unbind,
+	.status = sierra_net_status,
+	.rx_fixup = sierra_net_rx_fixup,
+	.tx_fixup = sierra_net_tx_fixup,
+	.data = (unsigned long)&sierra_net_info_data_68A3,
+};
+
+static const struct usb_device_id products[] = {
+	{USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */
+	.driver_info = (unsigned long) &sierra_net_info_68A3},
+
+	{}, /* last item */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+/* We are based on usbnet, so let it handle the USB driver specifics */
+static struct usb_driver sierra_net_driver = {
+	.name = "sierra_net",
+	.id_table = products,
+	.probe = usbnet_probe,
+	.disconnect = usbnet_disconnect,
+	.suspend = usbnet_suspend,
+	.resume = usbnet_resume,
+	.no_dynamic_id = 1,
+};
+
+static int __init sierra_net_init(void)
+{
+	BUILD_BUG_ON(FIELD_SIZEOF(struct usbnet, data)
+				< sizeof(struct cdc_state));
+
+	return usb_register(&sierra_net_driver);
+}
+
+static void __exit sierra_net_exit(void)
+{
+	usb_deregister(&sierra_net_driver);
+}
+
+module_exit(sierra_net_exit);
+module_init(sierra_net_init);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/smsc75xx.c linux-libre-2.6.34-gnu1/drivers/net/usb/smsc75xx.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/smsc75xx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/smsc75xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1289 @@
+ /***************************************************************************
+ *
+ * Copyright (C) 2007-2010 SMSC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/kmod.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+#include <linux/usb/usbnet.h>
+#include <linux/slab.h>
+#include "smsc75xx.h"
+
+#define SMSC_CHIPNAME			"smsc75xx"
+#define SMSC_DRIVER_VERSION		"1.0.0"
+#define HS_USB_PKT_SIZE			(512)
+#define FS_USB_PKT_SIZE			(64)
+#define DEFAULT_HS_BURST_CAP_SIZE	(16 * 1024 + 5 * HS_USB_PKT_SIZE)
+#define DEFAULT_FS_BURST_CAP_SIZE	(6 * 1024 + 33 * FS_USB_PKT_SIZE)
+#define DEFAULT_BULK_IN_DELAY		(0x00002000)
+#define MAX_SINGLE_PACKET_SIZE		(9000)
+#define LAN75XX_EEPROM_MAGIC		(0x7500)
+#define EEPROM_MAC_OFFSET		(0x01)
+#define DEFAULT_TX_CSUM_ENABLE		(true)
+#define DEFAULT_RX_CSUM_ENABLE		(true)
+#define DEFAULT_TSO_ENABLE		(true)
+#define SMSC75XX_INTERNAL_PHY_ID	(1)
+#define SMSC75XX_TX_OVERHEAD		(8)
+#define MAX_RX_FIFO_SIZE		(20 * 1024)
+#define MAX_TX_FIFO_SIZE		(12 * 1024)
+#define USB_VENDOR_ID_SMSC		(0x0424)
+#define USB_PRODUCT_ID_LAN7500		(0x7500)
+#define USB_PRODUCT_ID_LAN7505		(0x7505)
+
+#define check_warn(ret, fmt, args...) \
+	({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })
+
+#define check_warn_return(ret, fmt, args...) \
+	({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); return ret; } })
+
+#define check_warn_goto_done(ret, fmt, args...) \
+	({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); goto done; } })
+
+struct smsc75xx_priv {
+	struct usbnet *dev;
+	u32 rfe_ctl;
+	u32 multicast_hash_table[DP_SEL_VHF_HASH_LEN];
+	bool use_rx_csum;
+	struct mutex dataport_mutex;
+	spinlock_t rfe_ctl_lock;
+	struct work_struct set_multicast;
+};
+
+struct usb_context {
+	struct usb_ctrlrequest req;
+	struct usbnet *dev;
+};
+
+static int turbo_mode = true;
+module_param(turbo_mode, bool, 0644);
+MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
+
+static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index,
+					  u32 *data)
+{
+	u32 *buf = kmalloc(4, GFP_KERNEL);
+	int ret;
+
+	BUG_ON(!dev);
+
+	if (!buf)
+		return -ENOMEM;
+
+	ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
+		USB_VENDOR_REQUEST_READ_REGISTER,
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		00, index, buf, 4, USB_CTRL_GET_TIMEOUT);
+
+	if (unlikely(ret < 0))
+		netdev_warn(dev->net,
+			"Failed to read register index 0x%08x", index);
+
+	le32_to_cpus(buf);
+	*data = *buf;
+	kfree(buf);
+
+	return ret;
+}
+
+static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index,
+					   u32 data)
+{
+	u32 *buf = kmalloc(4, GFP_KERNEL);
+	int ret;
+
+	BUG_ON(!dev);
+
+	if (!buf)
+		return -ENOMEM;
+
+	*buf = data;
+	cpu_to_le32s(buf);
+
+	ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+		USB_VENDOR_REQUEST_WRITE_REGISTER,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		00, index, buf, 4, USB_CTRL_SET_TIMEOUT);
+
+	if (unlikely(ret < 0))
+		netdev_warn(dev->net,
+			"Failed to write register index 0x%08x", index);
+
+	kfree(buf);
+
+	return ret;
+}
+
+/* Loop until the read is completed with timeout
+ * called with phy_mutex held */
+static int smsc75xx_phy_wait_not_busy(struct usbnet *dev)
+{
+	unsigned long start_time = jiffies;
+	u32 val;
+	int ret;
+
+	do {
+		ret = smsc75xx_read_reg(dev, MII_ACCESS, &val);
+		check_warn_return(ret, "Error reading MII_ACCESS");
+
+		if (!(val & MII_ACCESS_BUSY))
+			return 0;
+	} while (!time_after(jiffies, start_time + HZ));
+
+	return -EIO;
+}
+
+static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	u32 val, addr;
+	int ret;
+
+	mutex_lock(&dev->phy_mutex);
+
+	/* confirm MII not busy */
+	ret = smsc75xx_phy_wait_not_busy(dev);
+	check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_read");
+
+	/* set the address, index & direction (read from PHY) */
+	phy_id &= dev->mii.phy_id_mask;
+	idx &= dev->mii.reg_num_mask;
+	addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
+		| ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
+		| MII_ACCESS_READ;
+	ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
+	check_warn_goto_done(ret, "Error writing MII_ACCESS");
+
+	ret = smsc75xx_phy_wait_not_busy(dev);
+	check_warn_goto_done(ret, "Timed out reading MII reg %02X", idx);
+
+	ret = smsc75xx_read_reg(dev, MII_DATA, &val);
+	check_warn_goto_done(ret, "Error reading MII_DATA");
+
+	ret = (u16)(val & 0xFFFF);
+
+done:
+	mutex_unlock(&dev->phy_mutex);
+	return ret;
+}
+
+static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx,
+				int regval)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	u32 val, addr;
+	int ret;
+
+	mutex_lock(&dev->phy_mutex);
+
+	/* confirm MII not busy */
+	ret = smsc75xx_phy_wait_not_busy(dev);
+	check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_write");
+
+	val = regval;
+	ret = smsc75xx_write_reg(dev, MII_DATA, val);
+	check_warn_goto_done(ret, "Error writing MII_DATA");
+
+	/* set the address, index & direction (write to PHY) */
+	phy_id &= dev->mii.phy_id_mask;
+	idx &= dev->mii.reg_num_mask;
+	addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
+		| ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
+		| MII_ACCESS_WRITE;
+	ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
+	check_warn_goto_done(ret, "Error writing MII_ACCESS");
+
+	ret = smsc75xx_phy_wait_not_busy(dev);
+	check_warn_goto_done(ret, "Timed out writing MII reg %02X", idx);
+
+done:
+	mutex_unlock(&dev->phy_mutex);
+}
+
+static int smsc75xx_wait_eeprom(struct usbnet *dev)
+{
+	unsigned long start_time = jiffies;
+	u32 val;
+	int ret;
+
+	do {
+		ret = smsc75xx_read_reg(dev, E2P_CMD, &val);
+		check_warn_return(ret, "Error reading E2P_CMD");
+
+		if (!(val & E2P_CMD_BUSY) || (val & E2P_CMD_TIMEOUT))
+			break;
+		udelay(40);
+	} while (!time_after(jiffies, start_time + HZ));
+
+	if (val & (E2P_CMD_TIMEOUT | E2P_CMD_BUSY)) {
+		netdev_warn(dev->net, "EEPROM read operation timeout");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int smsc75xx_eeprom_confirm_not_busy(struct usbnet *dev)
+{
+	unsigned long start_time = jiffies;
+	u32 val;
+	int ret;
+
+	do {
+		ret = smsc75xx_read_reg(dev, E2P_CMD, &val);
+		check_warn_return(ret, "Error reading E2P_CMD");
+
+		if (!(val & E2P_CMD_BUSY))
+			return 0;
+
+		udelay(40);
+	} while (!time_after(jiffies, start_time + HZ));
+
+	netdev_warn(dev->net, "EEPROM is busy");
+	return -EIO;
+}
+
+static int smsc75xx_read_eeprom(struct usbnet *dev, u32 offset, u32 length,
+				u8 *data)
+{
+	u32 val;
+	int i, ret;
+
+	BUG_ON(!dev);
+	BUG_ON(!data);
+
+	ret = smsc75xx_eeprom_confirm_not_busy(dev);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < length; i++) {
+		val = E2P_CMD_BUSY | E2P_CMD_READ | (offset & E2P_CMD_ADDR);
+		ret = smsc75xx_write_reg(dev, E2P_CMD, val);
+		check_warn_return(ret, "Error writing E2P_CMD");
+
+		ret = smsc75xx_wait_eeprom(dev);
+		if (ret < 0)
+			return ret;
+
+		ret = smsc75xx_read_reg(dev, E2P_DATA, &val);
+		check_warn_return(ret, "Error reading E2P_DATA");
+
+		data[i] = val & 0xFF;
+		offset++;
+	}
+
+	return 0;
+}
+
+static int smsc75xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length,
+				 u8 *data)
+{
+	u32 val;
+	int i, ret;
+
+	BUG_ON(!dev);
+	BUG_ON(!data);
+
+	ret = smsc75xx_eeprom_confirm_not_busy(dev);
+	if (ret)
+		return ret;
+
+	/* Issue write/erase enable command */
+	val = E2P_CMD_BUSY | E2P_CMD_EWEN;
+	ret = smsc75xx_write_reg(dev, E2P_CMD, val);
+	check_warn_return(ret, "Error writing E2P_CMD");
+
+	ret = smsc75xx_wait_eeprom(dev);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < length; i++) {
+
+		/* Fill data register */
+		val = data[i];
+		ret = smsc75xx_write_reg(dev, E2P_DATA, val);
+		check_warn_return(ret, "Error writing E2P_DATA");
+
+		/* Send "write" command */
+		val = E2P_CMD_BUSY | E2P_CMD_WRITE | (offset & E2P_CMD_ADDR);
+		ret = smsc75xx_write_reg(dev, E2P_CMD, val);
+		check_warn_return(ret, "Error writing E2P_CMD");
+
+		ret = smsc75xx_wait_eeprom(dev);
+		if (ret < 0)
+			return ret;
+
+		offset++;
+	}
+
+	return 0;
+}
+
+static int smsc75xx_dataport_wait_not_busy(struct usbnet *dev)
+{
+	int i, ret;
+
+	for (i = 0; i < 100; i++) {
+		u32 dp_sel;
+		ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel);
+		check_warn_return(ret, "Error reading DP_SEL");
+
+		if (dp_sel & DP_SEL_DPRDY)
+			return 0;
+
+		udelay(40);
+	}
+
+	netdev_warn(dev->net, "smsc75xx_dataport_wait_not_busy timed out");
+
+	return -EIO;
+}
+
+static int smsc75xx_dataport_write(struct usbnet *dev, u32 ram_select, u32 addr,
+				   u32 length, u32 *buf)
+{
+	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+	u32 dp_sel;
+	int i, ret;
+
+	mutex_lock(&pdata->dataport_mutex);
+
+	ret = smsc75xx_dataport_wait_not_busy(dev);
+	check_warn_goto_done(ret, "smsc75xx_dataport_write busy on entry");
+
+	ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel);
+	check_warn_goto_done(ret, "Error reading DP_SEL");
+
+	dp_sel &= ~DP_SEL_RSEL;
+	dp_sel |= ram_select;
+	ret = smsc75xx_write_reg(dev, DP_SEL, dp_sel);
+	check_warn_goto_done(ret, "Error writing DP_SEL");
+
+	for (i = 0; i < length; i++) {
+		ret = smsc75xx_write_reg(dev, DP_ADDR, addr + i);
+		check_warn_goto_done(ret, "Error writing DP_ADDR");
+
+		ret = smsc75xx_write_reg(dev, DP_DATA, buf[i]);
+		check_warn_goto_done(ret, "Error writing DP_DATA");
+
+		ret = smsc75xx_write_reg(dev, DP_CMD, DP_CMD_WRITE);
+		check_warn_goto_done(ret, "Error writing DP_CMD");
+
+		ret = smsc75xx_dataport_wait_not_busy(dev);
+		check_warn_goto_done(ret, "smsc75xx_dataport_write timeout");
+	}
+
+done:
+	mutex_unlock(&pdata->dataport_mutex);
+	return ret;
+}
+
+/* returns hash bit number for given MAC address */
+static u32 smsc75xx_hash(char addr[ETH_ALEN])
+{
+	return (ether_crc(ETH_ALEN, addr) >> 23) & 0x1ff;
+}
+
+static void smsc75xx_deferred_multicast_write(struct work_struct *param)
+{
+	struct smsc75xx_priv *pdata =
+		container_of(param, struct smsc75xx_priv, set_multicast);
+	struct usbnet *dev = pdata->dev;
+	int ret;
+
+	netif_dbg(dev, drv, dev->net, "deferred multicast write 0x%08x",
+		pdata->rfe_ctl);
+
+	smsc75xx_dataport_write(dev, DP_SEL_VHF, DP_SEL_VHF_VLAN_LEN,
+		DP_SEL_VHF_HASH_LEN, pdata->multicast_hash_table);
+
+	ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+	check_warn(ret, "Error writing RFE_CRL");
+}
+
+static void smsc75xx_set_multicast(struct net_device *netdev)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+	unsigned long flags;
+	int i;
+
+	spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);
+
+	pdata->rfe_ctl &=
+		~(RFE_CTL_AU | RFE_CTL_AM | RFE_CTL_DPF | RFE_CTL_MHF);
+	pdata->rfe_ctl |= RFE_CTL_AB;
+
+	for (i = 0; i < DP_SEL_VHF_HASH_LEN; i++)
+		pdata->multicast_hash_table[i] = 0;
+
+	if (dev->net->flags & IFF_PROMISC) {
+		netif_dbg(dev, drv, dev->net, "promiscuous mode enabled");
+		pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_AU;
+	} else if (dev->net->flags & IFF_ALLMULTI) {
+		netif_dbg(dev, drv, dev->net, "receive all multicast enabled");
+		pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_DPF;
+	} else if (!netdev_mc_empty(dev->net)) {
+		struct dev_mc_list *mc_list;
+
+		netif_dbg(dev, drv, dev->net, "receive multicast hash filter");
+
+		pdata->rfe_ctl |= RFE_CTL_MHF | RFE_CTL_DPF;
+
+		netdev_for_each_mc_addr(mc_list, netdev) {
+			u32 bitnum = smsc75xx_hash(mc_list->dmi_addr);
+			pdata->multicast_hash_table[bitnum / 32] |=
+				(1 << (bitnum % 32));
+		}
+	} else {
+		netif_dbg(dev, drv, dev->net, "receive own packets only");
+		pdata->rfe_ctl |= RFE_CTL_DPF;
+	}
+
+	spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);
+
+	/* defer register writes to a sleepable context */
+	schedule_work(&pdata->set_multicast);
+}
+
+static int smsc75xx_update_flowcontrol(struct usbnet *dev, u8 duplex,
+					    u16 lcladv, u16 rmtadv)
+{
+	u32 flow = 0, fct_flow = 0;
+	int ret;
+
+	if (duplex == DUPLEX_FULL) {
+		u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv);
+
+		if (cap & FLOW_CTRL_TX) {
+			flow = (FLOW_TX_FCEN | 0xFFFF);
+			/* set fct_flow thresholds to 20% and 80% */
+			fct_flow = (8 << 8) | 32;
+		}
+
+		if (cap & FLOW_CTRL_RX)
+			flow |= FLOW_RX_FCEN;
+
+		netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s",
+			(cap & FLOW_CTRL_RX ? "enabled" : "disabled"),
+			(cap & FLOW_CTRL_TX ? "enabled" : "disabled"));
+	} else {
+		netif_dbg(dev, link, dev->net, "half duplex");
+	}
+
+	ret = smsc75xx_write_reg(dev, FLOW, flow);
+	check_warn_return(ret, "Error writing FLOW");
+
+	ret = smsc75xx_write_reg(dev, FCT_FLOW, fct_flow);
+	check_warn_return(ret, "Error writing FCT_FLOW");
+
+	return 0;
+}
+
+static int smsc75xx_link_reset(struct usbnet *dev)
+{
+	struct mii_if_info *mii = &dev->mii;
+	struct ethtool_cmd ecmd;
+	u16 lcladv, rmtadv;
+	int ret;
+
+	/* clear interrupt status */
+	ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);
+	check_warn_return(ret, "Error reading PHY_INT_SRC");
+
+	ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
+	check_warn_return(ret, "Error writing INT_STS");
+
+	mii_check_media(mii, 1, 1);
+	mii_ethtool_gset(&dev->mii, &ecmd);
+	lcladv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
+	rmtadv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_LPA);
+
+	netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x"
+		" rmtadv: %04x", ecmd.speed, ecmd.duplex, lcladv, rmtadv);
+
+	return smsc75xx_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv);
+}
+
+static void smsc75xx_status(struct usbnet *dev, struct urb *urb)
+{
+	u32 intdata;
+
+	if (urb->actual_length != 4) {
+		netdev_warn(dev->net,
+			"unexpected urb length %d", urb->actual_length);
+		return;
+	}
+
+	memcpy(&intdata, urb->transfer_buffer, 4);
+	le32_to_cpus(&intdata);
+
+	netif_dbg(dev, link, dev->net, "intdata: 0x%08X", intdata);
+
+	if (intdata & INT_ENP_PHY_INT)
+		usbnet_defer_kevent(dev, EVENT_LINK_RESET);
+	else
+		netdev_warn(dev->net,
+			"unexpected interrupt, intdata=0x%08X", intdata);
+}
+
+/* Enable or disable Rx checksum offload engine */
+static int smsc75xx_set_rx_csum_offload(struct usbnet *dev)
+{
+	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);
+
+	if (pdata->use_rx_csum)
+		pdata->rfe_ctl |= RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM;
+	else
+		pdata->rfe_ctl &= ~(RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM);
+
+	spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);
+
+	ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+	check_warn_return(ret, "Error writing RFE_CTL");
+
+	return 0;
+}
+
+static int smsc75xx_ethtool_get_eeprom_len(struct net_device *net)
+{
+	return MAX_EEPROM_SIZE;
+}
+
+static int smsc75xx_ethtool_get_eeprom(struct net_device *netdev,
+				       struct ethtool_eeprom *ee, u8 *data)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+
+	ee->magic = LAN75XX_EEPROM_MAGIC;
+
+	return smsc75xx_read_eeprom(dev, ee->offset, ee->len, data);
+}
+
+static int smsc75xx_ethtool_set_eeprom(struct net_device *netdev,
+				       struct ethtool_eeprom *ee, u8 *data)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+
+	if (ee->magic != LAN75XX_EEPROM_MAGIC) {
+		netdev_warn(dev->net,
+			"EEPROM: magic value mismatch: 0x%x", ee->magic);
+		return -EINVAL;
+	}
+
+	return smsc75xx_write_eeprom(dev, ee->offset, ee->len, data);
+}
+
+static u32 smsc75xx_ethtool_get_rx_csum(struct net_device *netdev)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+
+	return pdata->use_rx_csum;
+}
+
+static int smsc75xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+
+	pdata->use_rx_csum = !!val;
+
+	return smsc75xx_set_rx_csum_offload(dev);
+}
+
+static int smsc75xx_ethtool_set_tso(struct net_device *netdev, u32 data)
+{
+	if (data)
+		netdev->features |= NETIF_F_TSO | NETIF_F_TSO6;
+	else
+		netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+
+	return 0;
+}
+
+static const struct ethtool_ops smsc75xx_ethtool_ops = {
+	.get_link	= usbnet_get_link,
+	.nway_reset	= usbnet_nway_reset,
+	.get_drvinfo	= usbnet_get_drvinfo,
+	.get_msglevel	= usbnet_get_msglevel,
+	.set_msglevel	= usbnet_set_msglevel,
+	.get_settings	= usbnet_get_settings,
+	.set_settings	= usbnet_set_settings,
+	.get_eeprom_len	= smsc75xx_ethtool_get_eeprom_len,
+	.get_eeprom	= smsc75xx_ethtool_get_eeprom,
+	.set_eeprom	= smsc75xx_ethtool_set_eeprom,
+	.get_tx_csum	= ethtool_op_get_tx_csum,
+	.set_tx_csum	= ethtool_op_set_tx_hw_csum,
+	.get_rx_csum	= smsc75xx_ethtool_get_rx_csum,
+	.set_rx_csum	= smsc75xx_ethtool_set_rx_csum,
+	.get_tso	= ethtool_op_get_tso,
+	.set_tso	= smsc75xx_ethtool_set_tso,
+};
+
+static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+
+	if (!netif_running(netdev))
+		return -EINVAL;
+
+	return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
+}
+
+static void smsc75xx_init_mac_address(struct usbnet *dev)
+{
+	/* try reading mac address from EEPROM */
+	if (smsc75xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
+			dev->net->dev_addr) == 0) {
+		if (is_valid_ether_addr(dev->net->dev_addr)) {
+			/* eeprom values are valid so use them */
+			netif_dbg(dev, ifup, dev->net,
+				"MAC address read from EEPROM");
+			return;
+		}
+	}
+
+	/* no eeprom, or eeprom values are invalid. generate random MAC */
+	random_ether_addr(dev->net->dev_addr);
+	netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr");
+}
+
+static int smsc75xx_set_mac_address(struct usbnet *dev)
+{
+	u32 addr_lo = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 |
+		dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24;
+	u32 addr_hi = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8;
+
+	int ret = smsc75xx_write_reg(dev, RX_ADDRH, addr_hi);
+	check_warn_return(ret, "Failed to write RX_ADDRH: %d", ret);
+
+	ret = smsc75xx_write_reg(dev, RX_ADDRL, addr_lo);
+	check_warn_return(ret, "Failed to write RX_ADDRL: %d", ret);
+
+	addr_hi |= ADDR_FILTX_FB_VALID;
+	ret = smsc75xx_write_reg(dev, ADDR_FILTX, addr_hi);
+	check_warn_return(ret, "Failed to write ADDR_FILTX: %d", ret);
+
+	ret = smsc75xx_write_reg(dev, ADDR_FILTX + 4, addr_lo);
+	check_warn_return(ret, "Failed to write ADDR_FILTX+4: %d", ret);
+
+	return 0;
+}
+
+static int smsc75xx_phy_initialize(struct usbnet *dev)
+{
+	int bmcr, timeout = 0;
+
+	/* Initialize MII structure */
+	dev->mii.dev = dev->net;
+	dev->mii.mdio_read = smsc75xx_mdio_read;
+	dev->mii.mdio_write = smsc75xx_mdio_write;
+	dev->mii.phy_id_mask = 0x1f;
+	dev->mii.reg_num_mask = 0x1f;
+	dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID;
+
+	/* reset phy and wait for reset to complete */
+	smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
+
+	do {
+		msleep(10);
+		bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
+		check_warn_return(bmcr, "Error reading MII_BMCR");
+		timeout++;
+	} while ((bmcr & MII_BMCR) && (timeout < 100));
+
+	if (timeout >= 100) {
+		netdev_warn(dev->net, "timeout on PHY Reset");
+		return -EIO;
+	}
+
+	smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
+		ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
+		ADVERTISE_PAUSE_ASYM);
+
+	/* read to clear */
+	smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
+	check_warn_return(bmcr, "Error reading PHY_INT_SRC");
+
+	smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK,
+		PHY_INT_MASK_DEFAULT);
+	mii_nway_restart(&dev->mii);
+
+	netif_dbg(dev, ifup, dev->net, "phy initialised successfully");
+	return 0;
+}
+
+static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size)
+{
+	int ret = 0;
+	u32 buf;
+	bool rxenabled;
+
+	ret = smsc75xx_read_reg(dev, MAC_RX, &buf);
+	check_warn_return(ret, "Failed to read MAC_RX: %d", ret);
+
+	rxenabled = ((buf & MAC_RX_RXEN) != 0);
+
+	if (rxenabled) {
+		buf &= ~MAC_RX_RXEN;
+		ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+		check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+	}
+
+	/* add 4 to size for FCS */
+	buf &= ~MAC_RX_MAX_SIZE;
+	buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT) & MAC_RX_MAX_SIZE);
+
+	ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+	check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+
+	if (rxenabled) {
+		buf |= MAC_RX_RXEN;
+		ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+		check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+	}
+
+	return 0;
+}
+
+static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+
+	int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu);
+	check_warn_return(ret, "Failed to set mac rx frame length");
+
+	return usbnet_change_mtu(netdev, new_mtu);
+}
+
+static int smsc75xx_reset(struct usbnet *dev)
+{
+	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+	u32 buf;
+	int ret = 0, timeout;
+
+	netif_dbg(dev, ifup, dev->net, "entering smsc75xx_reset");
+
+	ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+	check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+	buf |= HW_CFG_LRST;
+
+	ret = smsc75xx_write_reg(dev, HW_CFG, buf);
+	check_warn_return(ret, "Failed to write HW_CFG: %d", ret);
+
+	timeout = 0;
+	do {
+		msleep(10);
+		ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+		check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+		timeout++;
+	} while ((buf & HW_CFG_LRST) && (timeout < 100));
+
+	if (timeout >= 100) {
+		netdev_warn(dev->net, "timeout on completion of Lite Reset");
+		return -EIO;
+	}
+
+	netif_dbg(dev, ifup, dev->net, "Lite reset complete, resetting PHY");
+
+	ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
+	check_warn_return(ret, "Failed to read PMT_CTL: %d", ret);
+
+	buf |= PMT_CTL_PHY_RST;
+
+	ret = smsc75xx_write_reg(dev, PMT_CTL, buf);
+	check_warn_return(ret, "Failed to write PMT_CTL: %d", ret);
+
+	timeout = 0;
+	do {
+		msleep(10);
+		ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
+		check_warn_return(ret, "Failed to read PMT_CTL: %d", ret);
+		timeout++;
+	} while ((buf & PMT_CTL_PHY_RST) && (timeout < 100));
+
+	if (timeout >= 100) {
+		netdev_warn(dev->net, "timeout waiting for PHY Reset");
+		return -EIO;
+	}
+
+	netif_dbg(dev, ifup, dev->net, "PHY reset complete");
+
+	smsc75xx_init_mac_address(dev);
+
+	ret = smsc75xx_set_mac_address(dev);
+	check_warn_return(ret, "Failed to set mac address");
+
+	netif_dbg(dev, ifup, dev->net, "MAC Address: %pM", dev->net->dev_addr);
+
+	ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+	check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+	netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG : 0x%08x", buf);
+
+	buf |= HW_CFG_BIR;
+
+	ret = smsc75xx_write_reg(dev, HW_CFG, buf);
+	check_warn_return(ret, "Failed to write HW_CFG: %d", ret);
+
+	ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+	check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+	netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG after "
+			"writing HW_CFG_BIR: 0x%08x", buf);
+
+	if (!turbo_mode) {
+		buf = 0;
+		dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE;
+	} else if (dev->udev->speed == USB_SPEED_HIGH) {
+		buf = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
+		dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE;
+	} else {
+		buf = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE;
+		dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE;
+	}
+
+	netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld",
+		(ulong)dev->rx_urb_size);
+
+	ret = smsc75xx_write_reg(dev, BURST_CAP, buf);
+	check_warn_return(ret, "Failed to write BURST_CAP: %d", ret);
+
+	ret = smsc75xx_read_reg(dev, BURST_CAP, &buf);
+	check_warn_return(ret, "Failed to read BURST_CAP: %d", ret);
+
+	netif_dbg(dev, ifup, dev->net,
+		"Read Value from BURST_CAP after writing: 0x%08x", buf);
+
+	ret = smsc75xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY);
+	check_warn_return(ret, "Failed to write BULK_IN_DLY: %d", ret);
+
+	ret = smsc75xx_read_reg(dev, BULK_IN_DLY, &buf);
+	check_warn_return(ret, "Failed to read BULK_IN_DLY: %d", ret);
+
+	netif_dbg(dev, ifup, dev->net,
+		"Read Value from BULK_IN_DLY after writing: 0x%08x", buf);
+
+	if (turbo_mode) {
+		ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+		check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+		netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf);
+
+		buf |= (HW_CFG_MEF | HW_CFG_BCE);
+
+		ret = smsc75xx_write_reg(dev, HW_CFG, buf);
+		check_warn_return(ret, "Failed to write HW_CFG: %d", ret);
+
+		ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+		check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+		netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf);
+	}
+
+	/* set FIFO sizes */
+	buf = (MAX_RX_FIFO_SIZE - 512) / 512;
+	ret = smsc75xx_write_reg(dev, FCT_RX_FIFO_END, buf);
+	check_warn_return(ret, "Failed to write FCT_RX_FIFO_END: %d", ret);
+
+	netif_dbg(dev, ifup, dev->net, "FCT_RX_FIFO_END set to 0x%08x", buf);
+
+	buf = (MAX_TX_FIFO_SIZE - 512) / 512;
+	ret = smsc75xx_write_reg(dev, FCT_TX_FIFO_END, buf);
+	check_warn_return(ret, "Failed to write FCT_TX_FIFO_END: %d", ret);
+
+	netif_dbg(dev, ifup, dev->net, "FCT_TX_FIFO_END set to 0x%08x", buf);
+
+	ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
+	check_warn_return(ret, "Failed to write INT_STS: %d", ret);
+
+	ret = smsc75xx_read_reg(dev, ID_REV, &buf);
+	check_warn_return(ret, "Failed to read ID_REV: %d", ret);
+
+	netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x", buf);
+
+	/* Configure GPIO pins as LED outputs */
+	ret = smsc75xx_read_reg(dev, LED_GPIO_CFG, &buf);
+	check_warn_return(ret, "Failed to read LED_GPIO_CFG: %d", ret);
+
+	buf &= ~(LED_GPIO_CFG_LED2_FUN_SEL | LED_GPIO_CFG_LED10_FUN_SEL);
+	buf |= LED_GPIO_CFG_LEDGPIO_EN | LED_GPIO_CFG_LED2_FUN_SEL;
+
+	ret = smsc75xx_write_reg(dev, LED_GPIO_CFG, buf);
+	check_warn_return(ret, "Failed to write LED_GPIO_CFG: %d", ret);
+
+	ret = smsc75xx_write_reg(dev, FLOW, 0);
+	check_warn_return(ret, "Failed to write FLOW: %d", ret);
+
+	ret = smsc75xx_write_reg(dev, FCT_FLOW, 0);
+	check_warn_return(ret, "Failed to write FCT_FLOW: %d", ret);
+
+	/* Don't need rfe_ctl_lock during initialisation */
+	ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
+	check_warn_return(ret, "Failed to read RFE_CTL: %d", ret);
+
+	pdata->rfe_ctl |= RFE_CTL_AB | RFE_CTL_DPF;
+
+	ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+	check_warn_return(ret, "Failed to write RFE_CTL: %d", ret);
+
+	ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
+	check_warn_return(ret, "Failed to read RFE_CTL: %d", ret);
+
+	netif_dbg(dev, ifup, dev->net, "RFE_CTL set to 0x%08x", pdata->rfe_ctl);
+
+	/* Enable or disable checksum offload engines */
+	ethtool_op_set_tx_hw_csum(dev->net, DEFAULT_TX_CSUM_ENABLE);
+	ret = smsc75xx_set_rx_csum_offload(dev);
+	check_warn_return(ret, "Failed to set rx csum offload: %d", ret);
+
+	smsc75xx_ethtool_set_tso(dev->net, DEFAULT_TSO_ENABLE);
+
+	smsc75xx_set_multicast(dev->net);
+
+	ret = smsc75xx_phy_initialize(dev);
+	check_warn_return(ret, "Failed to initialize PHY: %d", ret);
+
+	ret = smsc75xx_read_reg(dev, INT_EP_CTL, &buf);
+	check_warn_return(ret, "Failed to read INT_EP_CTL: %d", ret);
+
+	/* enable PHY interrupts */
+	buf |= INT_ENP_PHY_INT;
+
+	ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf);
+	check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret);
+
+	ret = smsc75xx_read_reg(dev, MAC_TX, &buf);
+	check_warn_return(ret, "Failed to read MAC_TX: %d", ret);
+
+	buf |= MAC_TX_TXEN;
+
+	ret = smsc75xx_write_reg(dev, MAC_TX, buf);
+	check_warn_return(ret, "Failed to write MAC_TX: %d", ret);
+
+	netif_dbg(dev, ifup, dev->net, "MAC_TX set to 0x%08x", buf);
+
+	ret = smsc75xx_read_reg(dev, FCT_TX_CTL, &buf);
+	check_warn_return(ret, "Failed to read FCT_TX_CTL: %d", ret);
+
+	buf |= FCT_TX_CTL_EN;
+
+	ret = smsc75xx_write_reg(dev, FCT_TX_CTL, buf);
+	check_warn_return(ret, "Failed to write FCT_TX_CTL: %d", ret);
+
+	netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x", buf);
+
+	ret = smsc75xx_set_rx_max_frame_length(dev, 1514);
+	check_warn_return(ret, "Failed to set max rx frame length");
+
+	ret = smsc75xx_read_reg(dev, MAC_RX, &buf);
+	check_warn_return(ret, "Failed to read MAC_RX: %d", ret);
+
+	buf |= MAC_RX_RXEN;
+
+	ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+	check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+
+	netif_dbg(dev, ifup, dev->net, "MAC_RX set to 0x%08x", buf);
+
+	ret = smsc75xx_read_reg(dev, FCT_RX_CTL, &buf);
+	check_warn_return(ret, "Failed to read FCT_RX_CTL: %d", ret);
+
+	buf |= FCT_RX_CTL_EN;
+
+	ret = smsc75xx_write_reg(dev, FCT_RX_CTL, buf);
+	check_warn_return(ret, "Failed to write FCT_RX_CTL: %d", ret);
+
+	netif_dbg(dev, ifup, dev->net, "FCT_RX_CTL set to 0x%08x", buf);
+
+	netif_dbg(dev, ifup, dev->net, "smsc75xx_reset, return 0");
+	return 0;
+}
+
+static const struct net_device_ops smsc75xx_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		= smsc75xx_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_do_ioctl 		= smsc75xx_ioctl,
+	.ndo_set_multicast_list = smsc75xx_set_multicast,
+};
+
+static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+	struct smsc75xx_priv *pdata = NULL;
+	int ret;
+
+	printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n");
+
+	ret = usbnet_get_endpoints(dev, intf);
+	check_warn_return(ret, "usbnet_get_endpoints failed: %d", ret);
+
+	dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc75xx_priv),
+		GFP_KERNEL);
+
+	pdata = (struct smsc75xx_priv *)(dev->data[0]);
+	if (!pdata) {
+		netdev_warn(dev->net, "Unable to allocate smsc75xx_priv");
+		return -ENOMEM;
+	}
+
+	pdata->dev = dev;
+
+	spin_lock_init(&pdata->rfe_ctl_lock);
+	mutex_init(&pdata->dataport_mutex);
+
+	INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write);
+
+	pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE;
+
+	/* We have to advertise SG otherwise TSO cannot be enabled */
+	dev->net->features |= NETIF_F_SG;
+
+	/* Init all registers */
+	ret = smsc75xx_reset(dev);
+
+	dev->net->netdev_ops = &smsc75xx_netdev_ops;
+	dev->net->ethtool_ops = &smsc75xx_ethtool_ops;
+	dev->net->flags |= IFF_MULTICAST;
+	dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD;
+	return 0;
+}
+
+static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+	if (pdata) {
+		netif_dbg(dev, ifdown, dev->net, "free pdata");
+		kfree(pdata);
+		pdata = NULL;
+		dev->data[0] = 0;
+	}
+}
+
+static void smsc75xx_rx_csum_offload(struct sk_buff *skb, u32 rx_cmd_a,
+				     u32 rx_cmd_b)
+{
+	if (unlikely(rx_cmd_a & RX_CMD_A_LCSM)) {
+		skb->ip_summed = CHECKSUM_NONE;
+	} else {
+		skb->csum = ntohs((u16)(rx_cmd_b >> RX_CMD_B_CSUM_SHIFT));
+		skb->ip_summed = CHECKSUM_COMPLETE;
+	}
+}
+
+static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+
+	while (skb->len > 0) {
+		u32 rx_cmd_a, rx_cmd_b, align_count, size;
+		struct sk_buff *ax_skb;
+		unsigned char *packet;
+
+		memcpy(&rx_cmd_a, skb->data, sizeof(rx_cmd_a));
+		le32_to_cpus(&rx_cmd_a);
+		skb_pull(skb, 4);
+
+		memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b));
+		le32_to_cpus(&rx_cmd_b);
+		skb_pull(skb, 4 + NET_IP_ALIGN);
+
+		packet = skb->data;
+
+		/* get the packet length */
+		size = (rx_cmd_a & RX_CMD_A_LEN) - NET_IP_ALIGN;
+		align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4;
+
+		if (unlikely(rx_cmd_a & RX_CMD_A_RED)) {
+			netif_dbg(dev, rx_err, dev->net,
+				"Error rx_cmd_a=0x%08x", rx_cmd_a);
+			dev->net->stats.rx_errors++;
+			dev->net->stats.rx_dropped++;
+
+			if (rx_cmd_a & RX_CMD_A_FCS)
+				dev->net->stats.rx_crc_errors++;
+			else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT))
+				dev->net->stats.rx_frame_errors++;
+		} else {
+			/* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */
+			if (unlikely(size > (ETH_FRAME_LEN + 12))) {
+				netif_dbg(dev, rx_err, dev->net,
+					"size err rx_cmd_a=0x%08x", rx_cmd_a);
+				return 0;
+			}
+
+			/* last frame in this batch */
+			if (skb->len == size) {
+				if (pdata->use_rx_csum)
+					smsc75xx_rx_csum_offload(skb, rx_cmd_a,
+						rx_cmd_b);
+				else
+					skb->ip_summed = CHECKSUM_NONE;
+
+				skb_trim(skb, skb->len - 4); /* remove fcs */
+				skb->truesize = size + sizeof(struct sk_buff);
+
+				return 1;
+			}
+
+			ax_skb = skb_clone(skb, GFP_ATOMIC);
+			if (unlikely(!ax_skb)) {
+				netdev_warn(dev->net, "Error allocating skb");
+				return 0;
+			}
+
+			ax_skb->len = size;
+			ax_skb->data = packet;
+			skb_set_tail_pointer(ax_skb, size);
+
+			if (pdata->use_rx_csum)
+				smsc75xx_rx_csum_offload(ax_skb, rx_cmd_a,
+					rx_cmd_b);
+			else
+				ax_skb->ip_summed = CHECKSUM_NONE;
+
+			skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
+			ax_skb->truesize = size + sizeof(struct sk_buff);
+
+			usbnet_skb_return(dev, ax_skb);
+		}
+
+		skb_pull(skb, size);
+
+		/* padding bytes before the next frame starts */
+		if (skb->len)
+			skb_pull(skb, align_count);
+	}
+
+	if (unlikely(skb->len < 0)) {
+		netdev_warn(dev->net, "invalid rx length<0 %d", skb->len);
+		return 0;
+	}
+
+	return 1;
+}
+
+static struct sk_buff *smsc75xx_tx_fixup(struct usbnet *dev,
+					 struct sk_buff *skb, gfp_t flags)
+{
+	u32 tx_cmd_a, tx_cmd_b;
+
+	skb_linearize(skb);
+
+	if (skb_headroom(skb) < SMSC75XX_TX_OVERHEAD) {
+		struct sk_buff *skb2 =
+			skb_copy_expand(skb, SMSC75XX_TX_OVERHEAD, 0, flags);
+		dev_kfree_skb_any(skb);
+		skb = skb2;
+		if (!skb)
+			return NULL;
+	}
+
+	tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN) | TX_CMD_A_FCS;
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL)
+		tx_cmd_a |= TX_CMD_A_IPE | TX_CMD_A_TPE;
+
+	if (skb_is_gso(skb)) {
+		u16 mss = max(skb_shinfo(skb)->gso_size, TX_MSS_MIN);
+		tx_cmd_b = (mss << TX_CMD_B_MSS_SHIFT) & TX_CMD_B_MSS;
+
+		tx_cmd_a |= TX_CMD_A_LSO;
+	} else {
+		tx_cmd_b = 0;
+	}
+
+	skb_push(skb, 4);
+	cpu_to_le32s(&tx_cmd_b);
+	memcpy(skb->data, &tx_cmd_b, 4);
+
+	skb_push(skb, 4);
+	cpu_to_le32s(&tx_cmd_a);
+	memcpy(skb->data, &tx_cmd_a, 4);
+
+	return skb;
+}
+
+static const struct driver_info smsc75xx_info = {
+	.description	= "smsc75xx USB 2.0 Gigabit Ethernet",
+	.bind		= smsc75xx_bind,
+	.unbind		= smsc75xx_unbind,
+	.link_reset	= smsc75xx_link_reset,
+	.reset		= smsc75xx_reset,
+	.rx_fixup	= smsc75xx_rx_fixup,
+	.tx_fixup	= smsc75xx_tx_fixup,
+	.status		= smsc75xx_status,
+	.flags		= FLAG_ETHER | FLAG_SEND_ZLP,
+};
+
+static const struct usb_device_id products[] = {
+	{
+		/* SMSC7500 USB Gigabit Ethernet Device */
+		USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7500),
+		.driver_info = (unsigned long) &smsc75xx_info,
+	},
+	{
+		/* SMSC7500 USB Gigabit Ethernet Device */
+		USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7505),
+		.driver_info = (unsigned long) &smsc75xx_info,
+	},
+	{ },		/* END */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver smsc75xx_driver = {
+	.name		= SMSC_CHIPNAME,
+	.id_table	= products,
+	.probe		= usbnet_probe,
+	.suspend	= usbnet_suspend,
+	.resume		= usbnet_resume,
+	.disconnect	= usbnet_disconnect,
+};
+
+static int __init smsc75xx_init(void)
+{
+	return usb_register(&smsc75xx_driver);
+}
+module_init(smsc75xx_init);
+
+static void __exit smsc75xx_exit(void)
+{
+	usb_deregister(&smsc75xx_driver);
+}
+module_exit(smsc75xx_exit);
+
+MODULE_AUTHOR("Nancy Lin");
+MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>");
+MODULE_DESCRIPTION("SMSC75XX USB 2.0 Gigabit Ethernet Devices");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/smsc75xx.h linux-libre-2.6.34-gnu1/drivers/net/usb/smsc75xx.h
--- linux-libre-2.6.33-gnu1/drivers/net/usb/smsc75xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/smsc75xx.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,421 @@
+ /***************************************************************************
+ *
+ * Copyright (C) 2007-2010 SMSC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 _SMSC75XX_H
+#define _SMSC75XX_H
+
+/* Tx command words */
+#define TX_CMD_A_LSO			(0x08000000)
+#define TX_CMD_A_IPE			(0x04000000)
+#define TX_CMD_A_TPE			(0x02000000)
+#define TX_CMD_A_IVTG			(0x01000000)
+#define TX_CMD_A_RVTG			(0x00800000)
+#define TX_CMD_A_FCS			(0x00400000)
+#define TX_CMD_A_LEN			(0x000FFFFF)
+
+#define TX_CMD_B_MSS			(0x3FFF0000)
+#define TX_CMD_B_MSS_SHIFT		(16)
+#define TX_MSS_MIN			((u16)8)
+#define TX_CMD_B_VTAG			(0x0000FFFF)
+
+/* Rx command words */
+#define RX_CMD_A_ICE			(0x80000000)
+#define RX_CMD_A_TCE			(0x40000000)
+#define RX_CMD_A_IPV			(0x20000000)
+#define RX_CMD_A_PID			(0x18000000)
+#define RX_CMD_A_PID_NIP		(0x00000000)
+#define RX_CMD_A_PID_TCP		(0x08000000)
+#define RX_CMD_A_PID_UDP		(0x10000000)
+#define RX_CMD_A_PID_PP			(0x18000000)
+#define RX_CMD_A_PFF			(0x04000000)
+#define RX_CMD_A_BAM			(0x02000000)
+#define RX_CMD_A_MAM			(0x01000000)
+#define RX_CMD_A_FVTG			(0x00800000)
+#define RX_CMD_A_RED			(0x00400000)
+#define RX_CMD_A_RWT			(0x00200000)
+#define RX_CMD_A_RUNT			(0x00100000)
+#define RX_CMD_A_LONG			(0x00080000)
+#define RX_CMD_A_RXE			(0x00040000)
+#define RX_CMD_A_DRB			(0x00020000)
+#define RX_CMD_A_FCS			(0x00010000)
+#define RX_CMD_A_UAM			(0x00008000)
+#define RX_CMD_A_LCSM			(0x00004000)
+#define RX_CMD_A_LEN			(0x00003FFF)
+
+#define RX_CMD_B_CSUM			(0xFFFF0000)
+#define RX_CMD_B_CSUM_SHIFT		(16)
+#define RX_CMD_B_VTAG			(0x0000FFFF)
+
+/* SCSRs */
+#define ID_REV				(0x0000)
+
+#define FPGA_REV			(0x0004)
+
+#define BOND_CTL			(0x0008)
+
+#define INT_STS				(0x000C)
+#define INT_STS_RDFO_INT		(0x00400000)
+#define INT_STS_TXE_INT			(0x00200000)
+#define INT_STS_MACRTO_INT		(0x00100000)
+#define INT_STS_TX_DIS_INT		(0x00080000)
+#define INT_STS_RX_DIS_INT		(0x00040000)
+#define INT_STS_PHY_INT_		(0x00020000)
+#define INT_STS_MAC_ERR_INT		(0x00008000)
+#define INT_STS_TDFU			(0x00004000)
+#define INT_STS_TDFO			(0x00002000)
+#define INT_STS_GPIOS			(0x00000FFF)
+#define INT_STS_CLEAR_ALL		(0xFFFFFFFF)
+
+#define HW_CFG				(0x0010)
+#define HW_CFG_SMDET_STS		(0x00008000)
+#define HW_CFG_SMDET_EN			(0x00004000)
+#define HW_CFG_EEM			(0x00002000)
+#define HW_CFG_RST_PROTECT		(0x00001000)
+#define HW_CFG_PORT_SWAP		(0x00000800)
+#define HW_CFG_PHY_BOOST		(0x00000600)
+#define HW_CFG_PHY_BOOST_NORMAL		(0x00000000)
+#define HW_CFG_PHY_BOOST_4		(0x00002000)
+#define HW_CFG_PHY_BOOST_8		(0x00004000)
+#define HW_CFG_PHY_BOOST_12		(0x00006000)
+#define HW_CFG_LEDB			(0x00000100)
+#define HW_CFG_BIR			(0x00000080)
+#define HW_CFG_SBP			(0x00000040)
+#define HW_CFG_IME			(0x00000020)
+#define HW_CFG_MEF			(0x00000010)
+#define HW_CFG_ETC			(0x00000008)
+#define HW_CFG_BCE			(0x00000004)
+#define HW_CFG_LRST			(0x00000002)
+#define HW_CFG_SRST			(0x00000001)
+
+#define PMT_CTL				(0x0014)
+#define PMT_CTL_PHY_PWRUP		(0x00000400)
+#define PMT_CTL_RES_CLR_WKP_EN		(0x00000100)
+#define PMT_CTL_DEV_RDY			(0x00000080)
+#define PMT_CTL_SUS_MODE		(0x00000060)
+#define PMT_CTL_SUS_MODE_0		(0x00000000)
+#define PMT_CTL_SUS_MODE_1		(0x00000020)
+#define PMT_CTL_SUS_MODE_2		(0x00000040)
+#define PMT_CTL_SUS_MODE_3		(0x00000060)
+#define PMT_CTL_PHY_RST			(0x00000010)
+#define PMT_CTL_WOL_EN			(0x00000008)
+#define PMT_CTL_ED_EN			(0x00000004)
+#define PMT_CTL_WUPS			(0x00000003)
+#define PMT_CTL_WUPS_NO			(0x00000000)
+#define PMT_CTL_WUPS_ED			(0x00000001)
+#define PMT_CTL_WUPS_WOL		(0x00000002)
+#define PMT_CTL_WUPS_MULTI		(0x00000003)
+
+#define LED_GPIO_CFG			(0x0018)
+#define LED_GPIO_CFG_LED2_FUN_SEL	(0x80000000)
+#define LED_GPIO_CFG_LED10_FUN_SEL	(0x40000000)
+#define LED_GPIO_CFG_LEDGPIO_EN		(0x0000F000)
+#define LED_GPIO_CFG_LEDGPIO_EN_0	(0x00001000)
+#define LED_GPIO_CFG_LEDGPIO_EN_1	(0x00002000)
+#define LED_GPIO_CFG_LEDGPIO_EN_2	(0x00004000)
+#define LED_GPIO_CFG_LEDGPIO_EN_3	(0x00008000)
+#define LED_GPIO_CFG_GPBUF		(0x00000F00)
+#define LED_GPIO_CFG_GPBUF_0		(0x00000100)
+#define LED_GPIO_CFG_GPBUF_1		(0x00000200)
+#define LED_GPIO_CFG_GPBUF_2		(0x00000400)
+#define LED_GPIO_CFG_GPBUF_3		(0x00000800)
+#define LED_GPIO_CFG_GPDIR		(0x000000F0)
+#define LED_GPIO_CFG_GPDIR_0		(0x00000010)
+#define LED_GPIO_CFG_GPDIR_1		(0x00000020)
+#define LED_GPIO_CFG_GPDIR_2		(0x00000040)
+#define LED_GPIO_CFG_GPDIR_3		(0x00000080)
+#define LED_GPIO_CFG_GPDATA		(0x0000000F)
+#define LED_GPIO_CFG_GPDATA_0		(0x00000001)
+#define LED_GPIO_CFG_GPDATA_1		(0x00000002)
+#define LED_GPIO_CFG_GPDATA_2		(0x00000004)
+#define LED_GPIO_CFG_GPDATA_3		(0x00000008)
+
+#define GPIO_CFG			(0x001C)
+#define GPIO_CFG_SHIFT			(24)
+#define GPIO_CFG_GPEN			(0xFF000000)
+#define GPIO_CFG_GPBUF			(0x00FF0000)
+#define GPIO_CFG_GPDIR			(0x0000FF00)
+#define GPIO_CFG_GPDATA			(0x000000FF)
+
+#define GPIO_WAKE			(0x0020)
+#define GPIO_WAKE_PHY_LINKUP_EN		(0x80000000)
+#define GPIO_WAKE_POL			(0x0FFF0000)
+#define GPIO_WAKE_POL_SHIFT		(16)
+#define GPIO_WAKE_WK			(0x00000FFF)
+
+#define DP_SEL				(0x0024)
+#define DP_SEL_DPRDY			(0x80000000)
+#define DP_SEL_RSEL			(0x0000000F)
+#define DP_SEL_URX			(0x00000000)
+#define DP_SEL_VHF			(0x00000001)
+#define DP_SEL_VHF_HASH_LEN		(16)
+#define DP_SEL_VHF_VLAN_LEN		(128)
+#define DP_SEL_LSO_HEAD			(0x00000002)
+#define DP_SEL_FCT_RX			(0x00000003)
+#define DP_SEL_FCT_TX			(0x00000004)
+#define DP_SEL_DESCRIPTOR		(0x00000005)
+#define DP_SEL_WOL			(0x00000006)
+
+#define DP_CMD				(0x0028)
+#define DP_CMD_WRITE			(0x01)
+#define DP_CMD_READ			(0x00)
+
+#define DP_ADDR				(0x002C)
+
+#define DP_DATA				(0x0030)
+
+#define BURST_CAP			(0x0034)
+#define BURST_CAP_MASK			(0x0000000F)
+
+#define INT_EP_CTL			(0x0038)
+#define INT_EP_CTL_INTEP_ON		(0x80000000)
+#define INT_EP_CTL_RDFO_EN		(0x00400000)
+#define INT_EP_CTL_TXE_EN		(0x00200000)
+#define INT_EP_CTL_MACROTO_EN		(0x00100000)
+#define INT_EP_CTL_TX_DIS_EN		(0x00080000)
+#define INT_EP_CTL_RX_DIS_EN		(0x00040000)
+#define INT_EP_CTL_PHY_EN_		(0x00020000)
+#define INT_EP_CTL_MAC_ERR_EN		(0x00008000)
+#define INT_EP_CTL_TDFU_EN		(0x00004000)
+#define INT_EP_CTL_TDFO_EN		(0x00002000)
+#define INT_EP_CTL_RX_FIFO_EN		(0x00001000)
+#define INT_EP_CTL_GPIOX_EN		(0x00000FFF)
+
+#define BULK_IN_DLY			(0x003C)
+#define BULK_IN_DLY_MASK		(0xFFFF)
+
+#define E2P_CMD				(0x0040)
+#define E2P_CMD_BUSY			(0x80000000)
+#define E2P_CMD_MASK			(0x70000000)
+#define E2P_CMD_READ			(0x00000000)
+#define E2P_CMD_EWDS			(0x10000000)
+#define E2P_CMD_EWEN			(0x20000000)
+#define E2P_CMD_WRITE			(0x30000000)
+#define E2P_CMD_WRAL			(0x40000000)
+#define E2P_CMD_ERASE			(0x50000000)
+#define E2P_CMD_ERAL			(0x60000000)
+#define E2P_CMD_RELOAD			(0x70000000)
+#define E2P_CMD_TIMEOUT			(0x00000400)
+#define E2P_CMD_LOADED			(0x00000200)
+#define E2P_CMD_ADDR			(0x000001FF)
+
+#define MAX_EEPROM_SIZE			(512)
+
+#define E2P_DATA			(0x0044)
+#define E2P_DATA_MASK_			(0x000000FF)
+
+#define RFE_CTL				(0x0060)
+#define RFE_CTL_TCPUDP_CKM		(0x00001000)
+#define RFE_CTL_IP_CKM			(0x00000800)
+#define RFE_CTL_AB			(0x00000400)
+#define RFE_CTL_AM			(0x00000200)
+#define RFE_CTL_AU			(0x00000100)
+#define RFE_CTL_VS			(0x00000080)
+#define RFE_CTL_UF			(0x00000040)
+#define RFE_CTL_VF			(0x00000020)
+#define RFE_CTL_SPF			(0x00000010)
+#define RFE_CTL_MHF			(0x00000008)
+#define RFE_CTL_DHF			(0x00000004)
+#define RFE_CTL_DPF			(0x00000002)
+#define RFE_CTL_RST_RF			(0x00000001)
+
+#define VLAN_TYPE			(0x0064)
+#define VLAN_TYPE_MASK			(0x0000FFFF)
+
+#define FCT_RX_CTL			(0x0090)
+#define FCT_RX_CTL_EN			(0x80000000)
+#define FCT_RX_CTL_RST			(0x40000000)
+#define FCT_RX_CTL_SBF			(0x02000000)
+#define FCT_RX_CTL_OVERFLOW		(0x01000000)
+#define FCT_RX_CTL_FRM_DROP		(0x00800000)
+#define FCT_RX_CTL_RX_NOT_EMPTY		(0x00400000)
+#define FCT_RX_CTL_RX_EMPTY		(0x00200000)
+#define FCT_RX_CTL_RX_DISABLED		(0x00100000)
+#define FCT_RX_CTL_RXUSED		(0x0000FFFF)
+
+#define FCT_TX_CTL			(0x0094)
+#define FCT_TX_CTL_EN			(0x80000000)
+#define FCT_TX_CTL_RST			(0x40000000)
+#define FCT_TX_CTL_TX_NOT_EMPTY		(0x00400000)
+#define FCT_TX_CTL_TX_EMPTY		(0x00200000)
+#define FCT_TX_CTL_TX_DISABLED		(0x00100000)
+#define FCT_TX_CTL_TXUSED		(0x0000FFFF)
+
+#define FCT_RX_FIFO_END			(0x0098)
+#define FCT_RX_FIFO_END_MASK		(0x0000007F)
+
+#define FCT_TX_FIFO_END			(0x009C)
+#define FCT_TX_FIFO_END_MASK		(0x0000003F)
+
+#define FCT_FLOW			(0x00A0)
+#define FCT_FLOW_THRESHOLD_OFF		(0x00007F00)
+#define FCT_FLOW_THRESHOLD_OFF_SHIFT	(8)
+#define FCT_FLOW_THRESHOLD_ON		(0x0000007F)
+
+/* MAC CSRs */
+#define MAC_CR				(0x100)
+#define MAC_CR_ADP			(0x00002000)
+#define MAC_CR_ADD			(0x00001000)
+#define MAC_CR_ASD			(0x00000800)
+#define MAC_CR_INT_LOOP			(0x00000400)
+#define MAC_CR_BOLMT			(0x000000C0)
+#define MAC_CR_FDPX			(0x00000008)
+#define MAC_CR_CFG			(0x00000006)
+#define MAC_CR_CFG_10			(0x00000000)
+#define MAC_CR_CFG_100			(0x00000002)
+#define MAC_CR_CFG_1000			(0x00000004)
+#define MAC_CR_RST			(0x00000001)
+
+#define MAC_RX				(0x104)
+#define MAC_RX_MAX_SIZE			(0x3FFF0000)
+#define MAC_RX_MAX_SIZE_SHIFT		(16)
+#define MAC_RX_FCS_STRIP		(0x00000010)
+#define MAC_RX_FSE			(0x00000004)
+#define MAC_RX_RXD			(0x00000002)
+#define MAC_RX_RXEN			(0x00000001)
+
+#define MAC_TX				(0x108)
+#define MAC_TX_BFCS			(0x00000004)
+#define MAC_TX_TXD			(0x00000002)
+#define MAC_TX_TXEN			(0x00000001)
+
+#define FLOW				(0x10C)
+#define FLOW_FORCE_FC			(0x80000000)
+#define FLOW_TX_FCEN			(0x40000000)
+#define FLOW_RX_FCEN			(0x20000000)
+#define FLOW_FPF			(0x10000000)
+#define FLOW_PAUSE_TIME			(0x0000FFFF)
+
+#define RAND_SEED			(0x110)
+#define RAND_SEED_MASK			(0x0000FFFF)
+
+#define ERR_STS				(0x114)
+#define ERR_STS_FCS_ERR			(0x00000100)
+#define ERR_STS_LFRM_ERR		(0x00000080)
+#define ERR_STS_RUNT_ERR		(0x00000040)
+#define ERR_STS_COLLISION_ERR		(0x00000010)
+#define ERR_STS_ALIGN_ERR		(0x00000008)
+#define ERR_STS_URUN_ERR		(0x00000004)
+
+#define RX_ADDRH			(0x118)
+#define RX_ADDRH_MASK			(0x0000FFFF)
+
+#define RX_ADDRL			(0x11C)
+
+#define MII_ACCESS			(0x120)
+#define MII_ACCESS_PHY_ADDR		(0x0000F800)
+#define MII_ACCESS_PHY_ADDR_SHIFT	(11)
+#define MII_ACCESS_REG_ADDR		(0x000007C0)
+#define MII_ACCESS_REG_ADDR_SHIFT	(6)
+#define MII_ACCESS_READ			(0x00000000)
+#define MII_ACCESS_WRITE		(0x00000002)
+#define MII_ACCESS_BUSY			(0x00000001)
+
+#define MII_DATA			(0x124)
+#define MII_DATA_MASK			(0x0000FFFF)
+
+#define WUCSR				(0x140)
+#define WUCSR_PFDA_FR			(0x00000080)
+#define WUCSR_WUFR			(0x00000040)
+#define WUCSR_MPR			(0x00000020)
+#define WUCSR_BCAST_FR			(0x00000010)
+#define WUCSR_PFDA_EN			(0x00000008)
+#define WUCSR_WUEN			(0x00000004)
+#define WUCSR_MPEN			(0x00000002)
+#define WUCSR_BCST_EN			(0x00000001)
+
+#define WUF_CFGX			(0x144)
+#define WUF_CFGX_EN			(0x80000000)
+#define WUF_CFGX_ATYPE			(0x03000000)
+#define WUF_CFGX_ATYPE_UNICAST		(0x00000000)
+#define WUF_CFGX_ATYPE_MULTICAST	(0x02000000)
+#define WUF_CFGX_ATYPE_ALL		(0x03000000)
+#define WUF_CFGX_PATTERN_OFFSET		(0x007F0000)
+#define WUF_CFGX_PATTERN_OFFSET_SHIFT	(16)
+#define WUF_CFGX_CRC16			(0x0000FFFF)
+#define WUF_NUM				(8)
+
+#define WUF_MASKX			(0x170)
+#define WUF_MASKX_AVALID		(0x80000000)
+#define WUF_MASKX_ATYPE			(0x40000000)
+
+#define ADDR_FILTX			(0x300)
+#define ADDR_FILTX_FB_VALID		(0x80000000)
+#define ADDR_FILTX_FB_TYPE		(0x40000000)
+#define ADDR_FILTX_FB_ADDRHI		(0x0000FFFF)
+#define ADDR_FILTX_SB_ADDRLO		(0xFFFFFFFF)
+
+#define WUCSR2				(0x500)
+#define WUCSR2_NS_RCD			(0x00000040)
+#define WUCSR2_ARP_RCD			(0x00000020)
+#define WUCSR2_TCPSYN_RCD		(0x00000010)
+#define WUCSR2_NS_OFFLOAD		(0x00000004)
+#define WUCSR2_ARP_OFFLOAD		(0x00000002)
+#define WUCSR2_TCPSYN_OFFLOAD		(0x00000001)
+
+#define WOL_FIFO_STS			(0x504)
+
+#define IPV6_ADDRX			(0x510)
+
+#define IPV4_ADDRX			(0x590)
+
+
+/* Vendor-specific PHY Definitions */
+
+/* Mode Control/Status Register */
+#define PHY_MODE_CTRL_STS		(17)
+#define MODE_CTRL_STS_EDPWRDOWN		((u16)0x2000)
+#define MODE_CTRL_STS_ENERGYON		((u16)0x0002)
+
+#define PHY_INT_SRC			(29)
+#define PHY_INT_SRC_ENERGY_ON		((u16)0x0080)
+#define PHY_INT_SRC_ANEG_COMP		((u16)0x0040)
+#define PHY_INT_SRC_REMOTE_FAULT	((u16)0x0020)
+#define PHY_INT_SRC_LINK_DOWN		((u16)0x0010)
+
+#define PHY_INT_MASK			(30)
+#define PHY_INT_MASK_ENERGY_ON		((u16)0x0080)
+#define PHY_INT_MASK_ANEG_COMP		((u16)0x0040)
+#define PHY_INT_MASK_REMOTE_FAULT	((u16)0x0020)
+#define PHY_INT_MASK_LINK_DOWN		((u16)0x0010)
+#define PHY_INT_MASK_DEFAULT		(PHY_INT_MASK_ANEG_COMP | \
+					 PHY_INT_MASK_LINK_DOWN)
+
+#define PHY_SPECIAL			(31)
+#define PHY_SPECIAL_SPD			((u16)0x001C)
+#define PHY_SPECIAL_SPD_10HALF		((u16)0x0004)
+#define PHY_SPECIAL_SPD_10FULL		((u16)0x0014)
+#define PHY_SPECIAL_SPD_100HALF		((u16)0x0008)
+#define PHY_SPECIAL_SPD_100FULL		((u16)0x0018)
+
+/* USB Vendor Requests */
+#define USB_VENDOR_REQUEST_WRITE_REGISTER	0xA0
+#define USB_VENDOR_REQUEST_READ_REGISTER	0xA1
+#define USB_VENDOR_REQUEST_GET_STATS		0xA2
+
+/* Interrupt Endpoint status word bitfields */
+#define INT_ENP_RDFO_INT		((u32)BIT(22))
+#define INT_ENP_TXE_INT			((u32)BIT(21))
+#define INT_ENP_TX_DIS_INT		((u32)BIT(19))
+#define INT_ENP_RX_DIS_INT		((u32)BIT(18))
+#define INT_ENP_PHY_INT			((u32)BIT(17))
+#define INT_ENP_MAC_ERR_INT		((u32)BIT(15))
+#define INT_ENP_RX_FIFO_DATA_INT	((u32)BIT(12))
+
+#endif /* _SMSC75XX_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/smsc95xx.c linux-libre-2.6.34-gnu1/drivers/net/usb/smsc95xx.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/smsc95xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/smsc95xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/usb.h>
 #include <linux/crc32.h>
 #include <linux/usb/usbnet.h>
+#include <linux/slab.h>
 #include "smsc95xx.h"
 
 #define SMSC_CHIPNAME			"smsc95xx"
@@ -78,7 +79,7 @@ static int smsc95xx_read_reg(struct usbn
 		00, index, buf, 4, USB_CTRL_GET_TIMEOUT);
 
 	if (unlikely(ret < 0))
-		devwarn(dev, "Failed to read register index 0x%08x", index);
+		netdev_warn(dev->net, "Failed to read register index 0x%08x\n", index);
 
 	le32_to_cpus(buf);
 	*data = *buf;
@@ -106,7 +107,7 @@ static int smsc95xx_write_reg(struct usb
 		00, index, buf, 4, USB_CTRL_SET_TIMEOUT);
 
 	if (unlikely(ret < 0))
-		devwarn(dev, "Failed to write register index 0x%08x", index);
+		netdev_warn(dev->net, "Failed to write register index 0x%08x\n", index);
 
 	kfree(buf);
 
@@ -138,7 +139,7 @@ static int smsc95xx_mdio_read(struct net
 
 	/* confirm MII not busy */
 	if (smsc95xx_phy_wait_not_busy(dev)) {
-		devwarn(dev, "MII is busy in smsc95xx_mdio_read");
+		netdev_warn(dev->net, "MII is busy in smsc95xx_mdio_read\n");
 		mutex_unlock(&dev->phy_mutex);
 		return -EIO;
 	}
@@ -150,7 +151,7 @@ static int smsc95xx_mdio_read(struct net
 	smsc95xx_write_reg(dev, MII_ADDR, addr);
 
 	if (smsc95xx_phy_wait_not_busy(dev)) {
-		devwarn(dev, "Timed out reading MII reg %02X", idx);
+		netdev_warn(dev->net, "Timed out reading MII reg %02X\n", idx);
 		mutex_unlock(&dev->phy_mutex);
 		return -EIO;
 	}
@@ -172,7 +173,7 @@ static void smsc95xx_mdio_write(struct n
 
 	/* confirm MII not busy */
 	if (smsc95xx_phy_wait_not_busy(dev)) {
-		devwarn(dev, "MII is busy in smsc95xx_mdio_write");
+		netdev_warn(dev->net, "MII is busy in smsc95xx_mdio_write\n");
 		mutex_unlock(&dev->phy_mutex);
 		return;
 	}
@@ -187,7 +188,7 @@ static void smsc95xx_mdio_write(struct n
 	smsc95xx_write_reg(dev, MII_ADDR, addr);
 
 	if (smsc95xx_phy_wait_not_busy(dev))
-		devwarn(dev, "Timed out writing MII reg %02X", idx);
+		netdev_warn(dev->net, "Timed out writing MII reg %02X\n", idx);
 
 	mutex_unlock(&dev->phy_mutex);
 }
@@ -205,7 +206,7 @@ static int smsc95xx_wait_eeprom(struct u
 	} while (!time_after(jiffies, start_time + HZ));
 
 	if (val & (E2P_CMD_TIMEOUT_ | E2P_CMD_BUSY_)) {
-		devwarn(dev, "EEPROM read operation timeout");
+		netdev_warn(dev->net, "EEPROM read operation timeout\n");
 		return -EIO;
 	}
 
@@ -226,7 +227,7 @@ static int smsc95xx_eeprom_confirm_not_b
 		udelay(40);
 	} while (!time_after(jiffies, start_time + HZ));
 
-	devwarn(dev, "EEPROM is busy");
+	netdev_warn(dev->net, "EEPROM is busy\n");
 	return -EIO;
 }
 
@@ -308,7 +309,7 @@ static void smsc95xx_async_cmd_callback(
 	int status = urb->status;
 
 	if (status < 0)
-		devwarn(dev, "async callback failed with %d", status);
+		netdev_warn(dev->net, "async callback failed with %d\n", status);
 
 	kfree(usb_context);
 	usb_free_urb(urb);
@@ -323,13 +324,13 @@ static int smsc95xx_write_reg_async(stru
 
 	urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!urb) {
-		devwarn(dev, "Error allocating URB");
+		netdev_warn(dev->net, "Error allocating URB\n");
 		return -ENOMEM;
 	}
 
 	usb_context = kmalloc(sizeof(struct usb_context), GFP_ATOMIC);
 	if (usb_context == NULL) {
-		devwarn(dev, "Error allocating control msg");
+		netdev_warn(dev->net, "Error allocating control msg\n");
 		usb_free_urb(urb);
 		return -ENOMEM;
 	}
@@ -348,7 +349,8 @@ static int smsc95xx_write_reg_async(stru
 
 	status = usb_submit_urb(urb, GFP_ATOMIC);
 	if (status < 0) {
-		devwarn(dev, "Error submitting control msg, sts=%d", status);
+		netdev_warn(dev->net, "Error submitting control msg, sts=%d\n",
+			    status);
 		kfree(usb_context);
 		usb_free_urb(urb);
 	}
@@ -375,46 +377,32 @@ static void smsc95xx_set_multicast(struc
 	spin_lock_irqsave(&pdata->mac_cr_lock, flags);
 
 	if (dev->net->flags & IFF_PROMISC) {
-		if (netif_msg_drv(dev))
-			devdbg(dev, "promiscuous mode enabled");
+		netif_dbg(dev, drv, dev->net, "promiscuous mode enabled\n");
 		pdata->mac_cr |= MAC_CR_PRMS_;
 		pdata->mac_cr &= ~(MAC_CR_MCPAS_ | MAC_CR_HPFILT_);
 	} else if (dev->net->flags & IFF_ALLMULTI) {
-		if (netif_msg_drv(dev))
-			devdbg(dev, "receive all multicast enabled");
+		netif_dbg(dev, drv, dev->net, "receive all multicast enabled\n");
 		pdata->mac_cr |= MAC_CR_MCPAS_;
 		pdata->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_HPFILT_);
-	} else if (dev->net->mc_count > 0) {
-		struct dev_mc_list *mc_list = dev->net->mc_list;
-		int count = 0;
+	} else if (!netdev_mc_empty(dev->net)) {
+		struct dev_mc_list *mc_list;
 
 		pdata->mac_cr |= MAC_CR_HPFILT_;
 		pdata->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_);
 
-		while (mc_list) {
-			count++;
-			if (mc_list->dmi_addrlen == ETH_ALEN) {
-				u32 bitnum = smsc95xx_hash(mc_list->dmi_addr);
-				u32 mask = 0x01 << (bitnum & 0x1F);
-				if (bitnum & 0x20)
-					hash_hi |= mask;
-				else
-					hash_lo |= mask;
-			} else {
-				devwarn(dev, "dmi_addrlen != 6");
-			}
-			mc_list = mc_list->next;
+		netdev_for_each_mc_addr(mc_list, netdev) {
+			u32 bitnum = smsc95xx_hash(mc_list->dmi_addr);
+			u32 mask = 0x01 << (bitnum & 0x1F);
+			if (bitnum & 0x20)
+				hash_hi |= mask;
+			else
+				hash_lo |= mask;
 		}
 
-		if (count != ((u32)dev->net->mc_count))
-			devwarn(dev, "mc_count != dev->mc_count");
-
-		if (netif_msg_drv(dev))
-			devdbg(dev, "HASHH=0x%08X, HASHL=0x%08X", hash_hi,
-				hash_lo);
+		netif_dbg(dev, drv, dev->net, "HASHH=0x%08X, HASHL=0x%08X\n",
+				   hash_hi, hash_lo);
 	} else {
-		if (netif_msg_drv(dev))
-			devdbg(dev, "receive own packets only");
+		netif_dbg(dev, drv, dev->net, "receive own packets only\n");
 		pdata->mac_cr &=
 			~(MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_);
 	}
@@ -434,7 +422,7 @@ static void smsc95xx_phy_update_flowcont
 
 	int ret = smsc95xx_read_reg(dev, AFC_CFG, &afc_cfg);
 	if (ret < 0) {
-		devwarn(dev, "error reading AFC_CFG");
+		netdev_warn(dev->net, "error reading AFC_CFG\n");
 		return;
 	}
 
@@ -451,13 +439,11 @@ static void smsc95xx_phy_update_flowcont
 		else
 			afc_cfg &= ~0xF;
 
-		if (netif_msg_link(dev))
-			devdbg(dev, "rx pause %s, tx pause %s",
-				(cap & FLOW_CTRL_RX ? "enabled" : "disabled"),
-				(cap & FLOW_CTRL_TX ? "enabled" : "disabled"));
+		netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s\n",
+				   cap & FLOW_CTRL_RX ? "enabled" : "disabled",
+				   cap & FLOW_CTRL_TX ? "enabled" : "disabled");
 	} else {
-		if (netif_msg_link(dev))
-			devdbg(dev, "half duplex");
+		netif_dbg(dev, link, dev->net, "half duplex\n");
 		flow = 0;
 		afc_cfg |= 0xF;
 	}
@@ -485,9 +471,8 @@ static int smsc95xx_link_reset(struct us
 	lcladv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
 	rmtadv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_LPA);
 
-	if (netif_msg_link(dev))
-		devdbg(dev, "speed: %d duplex: %d lcladv: %04x rmtadv: %04x",
-			ecmd.speed, ecmd.duplex, lcladv, rmtadv);
+	netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x rmtadv: %04x\n",
+		  ecmd.speed, ecmd.duplex, lcladv, rmtadv);
 
 	spin_lock_irqsave(&pdata->mac_cr_lock, flags);
 	if (ecmd.duplex != DUPLEX_FULL) {
@@ -511,20 +496,21 @@ static void smsc95xx_status(struct usbne
 	u32 intdata;
 
 	if (urb->actual_length != 4) {
-		devwarn(dev, "unexpected urb length %d", urb->actual_length);
+		netdev_warn(dev->net, "unexpected urb length %d\n",
+			    urb->actual_length);
 		return;
 	}
 
 	memcpy(&intdata, urb->transfer_buffer, 4);
 	le32_to_cpus(&intdata);
 
-	if (netif_msg_link(dev))
-		devdbg(dev, "intdata: 0x%08X", intdata);
+	netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata);
 
 	if (intdata & INT_ENP_PHY_INT_)
 		usbnet_defer_kevent(dev, EVENT_LINK_RESET);
 	else
-		devwarn(dev, "unexpected interrupt, intdata=0x%08X", intdata);
+		netdev_warn(dev->net, "unexpected interrupt, intdata=0x%08X\n",
+			    intdata);
 }
 
 /* Enable or disable Tx & Rx checksum offload engines */
@@ -534,7 +520,7 @@ static int smsc95xx_set_csums(struct usb
 	u32 read_buf;
 	int ret = smsc95xx_read_reg(dev, COE_CR, &read_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to read COE_CR: %d", ret);
+		netdev_warn(dev->net, "Failed to read COE_CR: %d\n", ret);
 		return ret;
 	}
 
@@ -550,12 +536,11 @@ static int smsc95xx_set_csums(struct usb
 
 	ret = smsc95xx_write_reg(dev, COE_CR, read_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to write COE_CR: %d", ret);
+		netdev_warn(dev->net, "Failed to write COE_CR: %d\n", ret);
 		return ret;
 	}
 
-	if (netif_msg_hw(dev))
-		devdbg(dev, "COE_CR = 0x%08x", read_buf);
+	netif_dbg(dev, hw, dev->net, "COE_CR = 0x%08x\n", read_buf);
 	return 0;
 }
 
@@ -580,8 +565,8 @@ static int smsc95xx_ethtool_set_eeprom(s
 	struct usbnet *dev = netdev_priv(netdev);
 
 	if (ee->magic != LAN95XX_EEPROM_MAGIC) {
-		devwarn(dev, "EEPROM: magic value mismatch, magic = 0x%x",
-			ee->magic);
+		netdev_warn(dev->net, "EEPROM: magic value mismatch, magic = 0x%x\n",
+			    ee->magic);
 		return -EINVAL;
 	}
 
@@ -659,16 +644,14 @@ static void smsc95xx_init_mac_address(st
 			dev->net->dev_addr) == 0) {
 		if (is_valid_ether_addr(dev->net->dev_addr)) {
 			/* eeprom values are valid so use them */
-			if (netif_msg_ifup(dev))
-				devdbg(dev, "MAC address read from EEPROM");
+			netif_dbg(dev, ifup, dev->net, "MAC address read from EEPROM\n");
 			return;
 		}
 	}
 
 	/* no eeprom, or eeprom values are invalid. generate random MAC */
 	random_ether_addr(dev->net->dev_addr);
-	if (netif_msg_ifup(dev))
-		devdbg(dev, "MAC address set to random_ether_addr");
+	netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr\n");
 }
 
 static int smsc95xx_set_mac_address(struct usbnet *dev)
@@ -680,13 +663,13 @@ static int smsc95xx_set_mac_address(stru
 
 	ret = smsc95xx_write_reg(dev, ADDRL, addr_lo);
 	if (ret < 0) {
-		devwarn(dev, "Failed to write ADDRL: %d", ret);
+		netdev_warn(dev->net, "Failed to write ADDRL: %d\n", ret);
 		return ret;
 	}
 
 	ret = smsc95xx_write_reg(dev, ADDRH, addr_hi);
 	if (ret < 0) {
-		devwarn(dev, "Failed to write ADDRH: %d", ret);
+		netdev_warn(dev->net, "Failed to write ADDRH: %d\n", ret);
 		return ret;
 	}
 
@@ -727,6 +710,8 @@ static void smsc95xx_start_rx_path(struc
 
 static int smsc95xx_phy_initialize(struct usbnet *dev)
 {
+	int bmcr, timeout = 0;
+
 	/* Initialize MII structure */
 	dev->mii.dev = dev->net;
 	dev->mii.mdio_read = smsc95xx_mdio_read;
@@ -735,7 +720,20 @@ static int smsc95xx_phy_initialize(struc
 	dev->mii.reg_num_mask = 0x1f;
 	dev->mii.phy_id = SMSC95XX_INTERNAL_PHY_ID;
 
+	/* reset phy and wait for reset to complete */
 	smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
+
+	do {
+		msleep(10);
+		bmcr = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
+		timeout++;
+	} while ((bmcr & MII_BMCR) && (timeout < 100));
+
+	if (timeout >= 100) {
+		netdev_warn(dev->net, "timeout on PHY Reset");
+		return -EIO;
+	}
+
 	smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
 		ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
 		ADVERTISE_PAUSE_ASYM);
@@ -747,8 +745,7 @@ static int smsc95xx_phy_initialize(struc
 		PHY_INT_MASK_DEFAULT_);
 	mii_nway_restart(&dev->mii);
 
-	if (netif_msg_ifup(dev))
-		devdbg(dev, "phy initialised successfully");
+	netif_dbg(dev, ifup, dev->net, "phy initialised successfully\n");
 	return 0;
 }
 
@@ -759,14 +756,13 @@ static int smsc95xx_reset(struct usbnet
 	u32 read_buf, write_buf, burst_cap;
 	int ret = 0, timeout;
 
-	if (netif_msg_ifup(dev))
-		devdbg(dev, "entering smsc95xx_reset");
+	netif_dbg(dev, ifup, dev->net, "entering smsc95xx_reset\n");
 
 	write_buf = HW_CFG_LRST_;
 	ret = smsc95xx_write_reg(dev, HW_CFG, write_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to write HW_CFG_LRST_ bit in HW_CFG "
-			"register, ret = %d", ret);
+		netdev_warn(dev->net, "Failed to write HW_CFG_LRST_ bit in HW_CFG register, ret = %d\n",
+			    ret);
 		return ret;
 	}
 
@@ -774,7 +770,7 @@ static int smsc95xx_reset(struct usbnet
 	do {
 		ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
 		if (ret < 0) {
-			devwarn(dev, "Failed to read HW_CFG: %d", ret);
+			netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
 			return ret;
 		}
 		msleep(10);
@@ -782,14 +778,14 @@ static int smsc95xx_reset(struct usbnet
 	} while ((read_buf & HW_CFG_LRST_) && (timeout < 100));
 
 	if (timeout >= 100) {
-		devwarn(dev, "timeout waiting for completion of Lite Reset");
+		netdev_warn(dev->net, "timeout waiting for completion of Lite Reset\n");
 		return ret;
 	}
 
 	write_buf = PM_CTL_PHY_RST_;
 	ret = smsc95xx_write_reg(dev, PM_CTRL, write_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to write PM_CTRL: %d", ret);
+		netdev_warn(dev->net, "Failed to write PM_CTRL: %d\n", ret);
 		return ret;
 	}
 
@@ -797,7 +793,7 @@ static int smsc95xx_reset(struct usbnet
 	do {
 		ret = smsc95xx_read_reg(dev, PM_CTRL, &read_buf);
 		if (ret < 0) {
-			devwarn(dev, "Failed to read PM_CTRL: %d", ret);
+			netdev_warn(dev->net, "Failed to read PM_CTRL: %d\n", ret);
 			return ret;
 		}
 		msleep(10);
@@ -805,7 +801,7 @@ static int smsc95xx_reset(struct usbnet
 	} while ((read_buf & PM_CTL_PHY_RST_) && (timeout < 100));
 
 	if (timeout >= 100) {
-		devwarn(dev, "timeout waiting for PHY Reset");
+		netdev_warn(dev->net, "timeout waiting for PHY Reset\n");
 		return ret;
 	}
 
@@ -815,35 +811,35 @@ static int smsc95xx_reset(struct usbnet
 	if (ret < 0)
 		return ret;
 
-	if (netif_msg_ifup(dev))
-		devdbg(dev, "MAC Address: %pM", dev->net->dev_addr);
+	netif_dbg(dev, ifup, dev->net,
+		  "MAC Address: %pM\n", dev->net->dev_addr);
 
 	ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to read HW_CFG: %d", ret);
+		netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
 		return ret;
 	}
 
-	if (netif_msg_ifup(dev))
-		devdbg(dev, "Read Value from HW_CFG : 0x%08x", read_buf);
+	netif_dbg(dev, ifup, dev->net,
+		  "Read Value from HW_CFG : 0x%08x\n", read_buf);
 
 	read_buf |= HW_CFG_BIR_;
 
 	ret = smsc95xx_write_reg(dev, HW_CFG, read_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to write HW_CFG_BIR_ bit in HW_CFG "
-			"register, ret = %d", ret);
+		netdev_warn(dev->net, "Failed to write HW_CFG_BIR_ bit in HW_CFG register, ret = %d\n",
+			    ret);
 		return ret;
 	}
 
 	ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to read HW_CFG: %d", ret);
+		netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
 		return ret;
 	}
-	if (netif_msg_ifup(dev))
-		devdbg(dev, "Read Value from HW_CFG after writing "
-			"HW_CFG_BIR_: 0x%08x", read_buf);
+	netif_dbg(dev, ifup, dev->net,
+		  "Read Value from HW_CFG after writing HW_CFG_BIR_: 0x%08x\n",
+		  read_buf);
 
 	if (!turbo_mode) {
 		burst_cap = 0;
@@ -856,47 +852,47 @@ static int smsc95xx_reset(struct usbnet
 		dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE;
 	}
 
-	if (netif_msg_ifup(dev))
-		devdbg(dev, "rx_urb_size=%ld", (ulong)dev->rx_urb_size);
+	netif_dbg(dev, ifup, dev->net,
+		  "rx_urb_size=%ld\n", (ulong)dev->rx_urb_size);
 
 	ret = smsc95xx_write_reg(dev, BURST_CAP, burst_cap);
 	if (ret < 0) {
-		devwarn(dev, "Failed to write BURST_CAP: %d", ret);
+		netdev_warn(dev->net, "Failed to write BURST_CAP: %d\n", ret);
 		return ret;
 	}
 
 	ret = smsc95xx_read_reg(dev, BURST_CAP, &read_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to read BURST_CAP: %d", ret);
+		netdev_warn(dev->net, "Failed to read BURST_CAP: %d\n", ret);
 		return ret;
 	}
-	if (netif_msg_ifup(dev))
-		devdbg(dev, "Read Value from BURST_CAP after writing: 0x%08x",
-			read_buf);
+	netif_dbg(dev, ifup, dev->net,
+		  "Read Value from BURST_CAP after writing: 0x%08x\n",
+		  read_buf);
 
 	read_buf = DEFAULT_BULK_IN_DELAY;
 	ret = smsc95xx_write_reg(dev, BULK_IN_DLY, read_buf);
 	if (ret < 0) {
-		devwarn(dev, "ret = %d", ret);
+		netdev_warn(dev->net, "ret = %d\n", ret);
 		return ret;
 	}
 
 	ret = smsc95xx_read_reg(dev, BULK_IN_DLY, &read_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to read BULK_IN_DLY: %d", ret);
+		netdev_warn(dev->net, "Failed to read BULK_IN_DLY: %d\n", ret);
 		return ret;
 	}
-	if (netif_msg_ifup(dev))
-		devdbg(dev, "Read Value from BULK_IN_DLY after writing: "
-			"0x%08x", read_buf);
+	netif_dbg(dev, ifup, dev->net,
+		  "Read Value from BULK_IN_DLY after writing: 0x%08x\n",
+		  read_buf);
 
 	ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to read HW_CFG: %d", ret);
+		netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
 		return ret;
 	}
-	if (netif_msg_ifup(dev))
-		devdbg(dev, "Read Value from HW_CFG: 0x%08x", read_buf);
+	netif_dbg(dev, ifup, dev->net,
+		  "Read Value from HW_CFG: 0x%08x\n", read_buf);
 
 	if (turbo_mode)
 		read_buf |= (HW_CFG_MEF_ | HW_CFG_BCE_);
@@ -908,41 +904,41 @@ static int smsc95xx_reset(struct usbnet
 
 	ret = smsc95xx_write_reg(dev, HW_CFG, read_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to write HW_CFG register, ret=%d", ret);
+		netdev_warn(dev->net, "Failed to write HW_CFG register, ret=%d\n",
+			    ret);
 		return ret;
 	}
 
 	ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to read HW_CFG: %d", ret);
+		netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
 		return ret;
 	}
-	if (netif_msg_ifup(dev))
-		devdbg(dev, "Read Value from HW_CFG after writing: 0x%08x",
-			read_buf);
+	netif_dbg(dev, ifup, dev->net,
+		  "Read Value from HW_CFG after writing: 0x%08x\n", read_buf);
 
 	write_buf = 0xFFFFFFFF;
 	ret = smsc95xx_write_reg(dev, INT_STS, write_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to write INT_STS register, ret=%d", ret);
+		netdev_warn(dev->net, "Failed to write INT_STS register, ret=%d\n",
+			    ret);
 		return ret;
 	}
 
 	ret = smsc95xx_read_reg(dev, ID_REV, &read_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to read ID_REV: %d", ret);
+		netdev_warn(dev->net, "Failed to read ID_REV: %d\n", ret);
 		return ret;
 	}
-	if (netif_msg_ifup(dev))
-		devdbg(dev, "ID_REV = 0x%08x", read_buf);
+	netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x\n", 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);
+		netdev_warn(dev->net, "Failed to write LED_GPIO_CFG register, ret=%d\n",
+			    ret);
 		return ret;
 	}
 
@@ -950,21 +946,21 @@ static int smsc95xx_reset(struct usbnet
 	write_buf = 0;
 	ret = smsc95xx_write_reg(dev, FLOW, write_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to write FLOW: %d", ret);
+		netdev_warn(dev->net, "Failed to write FLOW: %d\n", ret);
 		return ret;
 	}
 
 	read_buf = AFC_CFG_DEFAULT;
 	ret = smsc95xx_write_reg(dev, AFC_CFG, read_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to write AFC_CFG: %d", ret);
+		netdev_warn(dev->net, "Failed to write AFC_CFG: %d\n", ret);
 		return ret;
 	}
 
 	/* Don't need mac_cr_lock during initialisation */
 	ret = smsc95xx_read_reg(dev, MAC_CR, &pdata->mac_cr);
 	if (ret < 0) {
-		devwarn(dev, "Failed to read MAC_CR: %d", ret);
+		netdev_warn(dev->net, "Failed to read MAC_CR: %d\n", ret);
 		return ret;
 	}
 
@@ -973,7 +969,7 @@ static int smsc95xx_reset(struct usbnet
 	write_buf = (u32)ETH_P_8021Q;
 	ret = smsc95xx_write_reg(dev, VLAN1, write_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to write VAN1: %d", ret);
+		netdev_warn(dev->net, "Failed to write VAN1: %d\n", ret);
 		return ret;
 	}
 
@@ -981,7 +977,7 @@ static int smsc95xx_reset(struct usbnet
 	ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum);
 	ret = smsc95xx_set_csums(dev);
 	if (ret < 0) {
-		devwarn(dev, "Failed to set csum offload: %d", ret);
+		netdev_warn(dev->net, "Failed to set csum offload: %d\n", ret);
 		return ret;
 	}
 
@@ -992,7 +988,7 @@ static int smsc95xx_reset(struct usbnet
 
 	ret = smsc95xx_read_reg(dev, INT_EP_CTL, &read_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to read INT_EP_CTL: %d", ret);
+		netdev_warn(dev->net, "Failed to read INT_EP_CTL: %d\n", ret);
 		return ret;
 	}
 
@@ -1001,15 +997,14 @@ static int smsc95xx_reset(struct usbnet
 
 	ret = smsc95xx_write_reg(dev, INT_EP_CTL, read_buf);
 	if (ret < 0) {
-		devwarn(dev, "Failed to write INT_EP_CTL: %d", ret);
+		netdev_warn(dev->net, "Failed to write INT_EP_CTL: %d\n", ret);
 		return ret;
 	}
 
 	smsc95xx_start_tx_path(dev);
 	smsc95xx_start_rx_path(dev);
 
-	if (netif_msg_ifup(dev))
-		devdbg(dev, "smsc95xx_reset, return 0");
+	netif_dbg(dev, ifup, dev->net, "smsc95xx_reset, return 0\n");
 	return 0;
 }
 
@@ -1034,7 +1029,7 @@ static int smsc95xx_bind(struct usbnet *
 
 	ret = usbnet_get_endpoints(dev, intf);
 	if (ret < 0) {
-		devwarn(dev, "usbnet_get_endpoints failed: %d", ret);
+		netdev_warn(dev->net, "usbnet_get_endpoints failed: %d\n", ret);
 		return ret;
 	}
 
@@ -1043,7 +1038,7 @@ static int smsc95xx_bind(struct usbnet *
 
 	pdata = (struct smsc95xx_priv *)(dev->data[0]);
 	if (!pdata) {
-		devwarn(dev, "Unable to allocate struct smsc95xx_priv");
+		netdev_warn(dev->net, "Unable to allocate struct smsc95xx_priv\n");
 		return -ENOMEM;
 	}
 
@@ -1066,8 +1061,7 @@ static void smsc95xx_unbind(struct usbne
 {
 	struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
 	if (pdata) {
-		if (netif_msg_ifdown(dev))
-			devdbg(dev, "free pdata");
+		netif_dbg(dev, ifdown, dev->net, "free pdata\n");
 		kfree(pdata);
 		pdata = NULL;
 		dev->data[0] = 0;
@@ -1101,8 +1095,8 @@ static int smsc95xx_rx_fixup(struct usbn
 		align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4;
 
 		if (unlikely(header & RX_STS_ES_)) {
-			if (netif_msg_rx_err(dev))
-				devdbg(dev, "Error header=0x%08x", header);
+			netif_dbg(dev, rx_err, dev->net,
+				  "Error header=0x%08x\n", header);
 			dev->net->stats.rx_errors++;
 			dev->net->stats.rx_dropped++;
 
@@ -1119,9 +1113,8 @@ static int smsc95xx_rx_fixup(struct usbn
 		} else {
 			/* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */
 			if (unlikely(size > (ETH_FRAME_LEN + 12))) {
-				if (netif_msg_rx_err(dev))
-					devdbg(dev, "size err header=0x%08x",
-						header);
+				netif_dbg(dev, rx_err, dev->net,
+					  "size err header=0x%08x\n", header);
 				return 0;
 			}
 
@@ -1137,7 +1130,7 @@ static int smsc95xx_rx_fixup(struct usbn
 
 			ax_skb = skb_clone(skb, GFP_ATOMIC);
 			if (unlikely(!ax_skb)) {
-				devwarn(dev, "Error allocating skb");
+				netdev_warn(dev->net, "Error allocating skb\n");
 				return 0;
 			}
 
@@ -1161,7 +1154,7 @@ static int smsc95xx_rx_fixup(struct usbn
 	}
 
 	if (unlikely(skb->len < 0)) {
-		devwarn(dev, "invalid rx length<0 %d", skb->len);
+		netdev_warn(dev->net, "invalid rx length<0 %d\n", skb->len);
 		return 0;
 	}
 
@@ -1197,9 +1190,21 @@ static struct sk_buff *smsc95xx_tx_fixup
 	}
 
 	if (csum) {
-		u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
-		skb_push(skb, 4);
-		memcpy(skb->data, &csum_preamble, 4);
+		if (skb->len <= 45) {
+			/* workaround - hardware tx checksum does not work
+			 * properly with extremely small packets */
+			long csstart = skb->csum_start - skb_headroom(skb);
+			__wsum calc = csum_partial(skb->data + csstart,
+				skb->len - csstart, 0);
+			*((__sum16 *)(skb->data + csstart
+				+ skb->csum_offset)) = csum_fold(calc);
+
+			csum = false;
+		} else {
+			u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
+			skb_push(skb, 4);
+			memcpy(skb->data, &csum_preamble, 4);
+		}
 	}
 
 	skb_push(skb, 4);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/usb/usbnet.c linux-libre-2.6.34-gnu1/drivers/net/usb/usbnet.c
--- linux-libre-2.6.33-gnu1/drivers/net/usb/usbnet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/usb/usbnet.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,7 @@
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/usb/usbnet.h>
+#include <linux/slab.h>
 
 #define DRIVER_VERSION		"22-Aug-2005"
 
@@ -242,13 +243,13 @@ void usbnet_skb_return (struct usbnet *d
 	dev->net->stats.rx_packets++;
 	dev->net->stats.rx_bytes += skb->len;
 
-	if (netif_msg_rx_status (dev))
-		devdbg (dev, "< rx, len %zu, type 0x%x",
-			skb->len + sizeof (struct ethhdr), skb->protocol);
+	netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n",
+		  skb->len + sizeof (struct ethhdr), skb->protocol);
 	memset (skb->cb, 0, sizeof (struct skb_data));
 	status = netif_rx (skb);
-	if (status != NET_RX_SUCCESS && netif_msg_rx_err (dev))
-		devdbg (dev, "netif_rx status %d", status);
+	if (status != NET_RX_SUCCESS)
+		netif_dbg(dev, rx_err, dev->net,
+			  "netif_rx status %d\n", status);
 }
 EXPORT_SYMBOL_GPL(usbnet_skb_return);
 
@@ -313,9 +314,9 @@ void usbnet_defer_kevent (struct usbnet
 {
 	set_bit (work, &dev->flags);
 	if (!schedule_work (&dev->kevent))
-		deverr (dev, "kevent %d may have been dropped", work);
+		netdev_err(dev->net, "kevent %d may have been dropped\n", work);
 	else
-		devdbg (dev, "kevent %d scheduled", work);
+		netdev_dbg(dev->net, "kevent %d scheduled\n", work);
 }
 EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
 
@@ -332,8 +333,7 @@ static void rx_submit (struct usbnet *de
 	size_t			size = dev->rx_urb_size;
 
 	if ((skb = alloc_skb (size + NET_IP_ALIGN, flags)) == NULL) {
-		if (netif_msg_rx_err (dev))
-			devdbg (dev, "no rx skb");
+		netif_dbg(dev, rx_err, dev->net, "no rx skb\n");
 		usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
 		usb_free_urb (urb);
 		return;
@@ -363,21 +363,19 @@ static void rx_submit (struct usbnet *de
 			usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
 			break;
 		case -ENODEV:
-			if (netif_msg_ifdown (dev))
-				devdbg (dev, "device gone");
+			netif_dbg(dev, ifdown, dev->net, "device gone\n");
 			netif_device_detach (dev->net);
 			break;
 		default:
-			if (netif_msg_rx_err (dev))
-				devdbg (dev, "rx submit, %d", retval);
+			netif_dbg(dev, rx_err, dev->net,
+				  "rx submit, %d\n", retval);
 			tasklet_schedule (&dev->bh);
 			break;
 		case 0:
 			__skb_queue_tail (&dev->rxq, skb);
 		}
 	} else {
-		if (netif_msg_ifdown (dev))
-			devdbg (dev, "rx: stopped");
+		netif_dbg(dev, ifdown, dev->net, "rx: stopped\n");
 		retval = -ENOLINK;
 	}
 	spin_unlock_irqrestore (&dev->rxq.lock, lockflags);
@@ -400,8 +398,7 @@ static inline void rx_process (struct us
 	if (skb->len)
 		usbnet_skb_return (dev, skb);
 	else {
-		if (netif_msg_rx_err (dev))
-			devdbg (dev, "drop");
+		netif_dbg(dev, rx_err, dev->net, "drop\n");
 error:
 		dev->net->stats.rx_errors++;
 		skb_queue_tail (&dev->done, skb);
@@ -428,8 +425,8 @@ static void rx_complete (struct urb *urb
 			entry->state = rx_cleanup;
 			dev->net->stats.rx_errors++;
 			dev->net->stats.rx_length_errors++;
-			if (netif_msg_rx_err (dev))
-				devdbg (dev, "rx length %d", skb->len);
+			netif_dbg(dev, rx_err, dev->net,
+				  "rx length %d\n", skb->len);
 		}
 		break;
 
@@ -446,8 +443,8 @@ static void rx_complete (struct urb *urb
 	/* software-driven interface shutdown */
 	case -ECONNRESET:		/* async unlink */
 	case -ESHUTDOWN:		/* hardware gone */
-		if (netif_msg_ifdown (dev))
-			devdbg (dev, "rx shutdown, code %d", urb_status);
+		netif_dbg(dev, ifdown, dev->net,
+			  "rx shutdown, code %d\n", urb_status);
 		goto block;
 
 	/* we get controller i/o faults during khubd disconnect() delays.
@@ -460,8 +457,8 @@ static void rx_complete (struct urb *urb
 		dev->net->stats.rx_errors++;
 		if (!timer_pending (&dev->delay)) {
 			mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES);
-			if (netif_msg_link (dev))
-				devdbg (dev, "rx throttle %d", urb_status);
+			netif_dbg(dev, link, dev->net,
+				  "rx throttle %d\n", urb_status);
 		}
 block:
 		entry->state = rx_cleanup;
@@ -477,8 +474,7 @@ block:
 	default:
 		entry->state = rx_cleanup;
 		dev->net->stats.rx_errors++;
-		if (netif_msg_rx_err (dev))
-			devdbg (dev, "rx status %d", urb_status);
+		netif_dbg(dev, rx_err, dev->net, "rx status %d\n", urb_status);
 		break;
 	}
 
@@ -492,8 +488,7 @@ block:
 		}
 		usb_free_urb (urb);
 	}
-	if (netif_msg_rx_err (dev))
-		devdbg (dev, "no read resubmitted");
+	netif_dbg(dev, rx_err, dev->net, "no read resubmitted\n");
 }
 
 static void intr_complete (struct urb *urb)
@@ -510,15 +505,15 @@ static void intr_complete (struct urb *u
 	/* software-driven interface shutdown */
 	case -ENOENT:		/* urb killed */
 	case -ESHUTDOWN:	/* hardware gone */
-		if (netif_msg_ifdown (dev))
-			devdbg (dev, "intr shutdown, code %d", status);
+		netif_dbg(dev, ifdown, dev->net,
+			  "intr shutdown, code %d\n", status);
 		return;
 
 	/* NOTE:  not throttling like RX/TX, since this endpoint
 	 * already polls infrequently
 	 */
 	default:
-		devdbg (dev, "intr status %d", status);
+		netdev_dbg(dev->net, "intr status %d\n", status);
 		break;
 	}
 
@@ -527,8 +522,9 @@ static void intr_complete (struct urb *u
 
 	memset(urb->transfer_buffer, 0, urb->transfer_buffer_length);
 	status = usb_submit_urb (urb, GFP_ATOMIC);
-	if (status != 0 && netif_msg_timer (dev))
-		deverr(dev, "intr resubmit --> %d", status);
+	if (status != 0)
+		netif_err(dev, timer, dev->net,
+			  "intr resubmit --> %d\n", status);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -536,8 +532,7 @@ void usbnet_pause_rx(struct usbnet *dev)
 {
 	set_bit(EVENT_RX_PAUSED, &dev->flags);
 
-	if (netif_msg_rx_status(dev))
-		devdbg(dev, "paused rx queue enabled");
+	netif_dbg(dev, rx_status, dev->net, "paused rx queue enabled\n");
 }
 EXPORT_SYMBOL_GPL(usbnet_pause_rx);
 
@@ -555,8 +550,8 @@ void usbnet_resume_rx(struct usbnet *dev
 
 	tasklet_schedule(&dev->bh);
 
-	if (netif_msg_rx_status(dev))
-		devdbg(dev, "paused rx queue disabled, %d skbs requeued", num);
+	netif_dbg(dev, rx_status, dev->net,
+		  "paused rx queue disabled, %d skbs requeued\n", num);
 }
 EXPORT_SYMBOL_GPL(usbnet_resume_rx);
 
@@ -589,7 +584,7 @@ static int unlink_urbs (struct usbnet *d
 		// these (async) unlinks complete immediately
 		retval = usb_unlink_urb (urb);
 		if (retval != -EINPROGRESS && retval != 0)
-			devdbg (dev, "unlink urb err, %d", retval);
+			netdev_dbg(dev->net, "unlink urb err, %d\n", retval);
 		else
 			count++;
 	}
@@ -631,9 +626,8 @@ static void usbnet_terminate_urbs(struct
 		&& !skb_queue_empty(&dev->done)) {
 			schedule_timeout(UNLINK_TIMEOUT_MS);
 			set_current_state(TASK_UNINTERRUPTIBLE);
-			if (netif_msg_ifdown(dev))
-				devdbg(dev, "waited for %d urb completions",
-					temp);
+			netif_dbg(dev, ifdown, dev->net,
+				  "waited for %d urb completions\n", temp);
 	}
 	set_current_state(TASK_RUNNING);
 	dev->wait = NULL;
@@ -648,22 +642,21 @@ int usbnet_stop (struct net_device *net)
 
 	netif_stop_queue (net);
 
-	if (netif_msg_ifdown (dev))
-		devinfo (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld",
-			net->stats.rx_packets, net->stats.tx_packets,
-			net->stats.rx_errors, net->stats.tx_errors
-			);
+	netif_info(dev, ifdown, dev->net,
+		   "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n",
+		   net->stats.rx_packets, net->stats.tx_packets,
+		   net->stats.rx_errors, net->stats.tx_errors);
 
 	/* allow minidriver to stop correctly (wireless devices to turn off
 	 * radio etc) */
 	if (info->stop) {
 		retval = info->stop(dev);
-		if (retval < 0 && netif_msg_ifdown(dev))
-			devinfo(dev,
-				"stop fail (%d) usbnet usb-%s-%s, %s",
-				retval,
-				dev->udev->bus->bus_name, dev->udev->devpath,
-				info->description);
+		if (retval < 0)
+			netif_info(dev, ifdown, dev->net,
+				   "stop fail (%d) usbnet usb-%s-%s, %s\n",
+				   retval,
+				   dev->udev->bus->bus_name, dev->udev->devpath,
+				   info->description);
 	}
 
 	if (!(info->flags & FLAG_AVOID_UNLINK_URBS))
@@ -702,30 +695,29 @@ int usbnet_open (struct net_device *net)
 	struct driver_info	*info = dev->driver_info;
 
 	if ((retval = usb_autopm_get_interface(dev->intf)) < 0) {
-		if (netif_msg_ifup (dev))
-			devinfo (dev,
-				"resumption fail (%d) usbnet usb-%s-%s, %s",
-				retval,
-				dev->udev->bus->bus_name, dev->udev->devpath,
-			info->description);
+		netif_info(dev, ifup, dev->net,
+			   "resumption fail (%d) usbnet usb-%s-%s, %s\n",
+			   retval,
+			   dev->udev->bus->bus_name,
+			   dev->udev->devpath,
+			   info->description);
 		goto done_nopm;
 	}
 
 	// put into "known safe" state
 	if (info->reset && (retval = info->reset (dev)) < 0) {
-		if (netif_msg_ifup (dev))
-			devinfo (dev,
-				"open reset fail (%d) usbnet usb-%s-%s, %s",
-				retval,
-				dev->udev->bus->bus_name, dev->udev->devpath,
-			info->description);
+		netif_info(dev, ifup, dev->net,
+			   "open reset fail (%d) usbnet usb-%s-%s, %s\n",
+			   retval,
+			   dev->udev->bus->bus_name,
+			   dev->udev->devpath,
+			   info->description);
 		goto done;
 	}
 
 	// insist peer be connected
 	if (info->check_connect && (retval = info->check_connect (dev)) < 0) {
-		if (netif_msg_ifup (dev))
-			devdbg (dev, "can't open; %d", retval);
+		netif_dbg(dev, ifup, dev->net, "can't open; %d\n", retval);
 		goto done;
 	}
 
@@ -733,34 +725,23 @@ int usbnet_open (struct net_device *net)
 	if (dev->interrupt) {
 		retval = usb_submit_urb (dev->interrupt, GFP_KERNEL);
 		if (retval < 0) {
-			if (netif_msg_ifup (dev))
-				deverr (dev, "intr submit %d", retval);
+			netif_err(dev, ifup, dev->net,
+				  "intr submit %d\n", retval);
 			goto done;
 		}
 	}
 
 	netif_start_queue (net);
-	if (netif_msg_ifup (dev)) {
-		char	*framing;
-
-		if (dev->driver_info->flags & FLAG_FRAMING_NC)
-			framing = "NetChip";
-		else if (dev->driver_info->flags & FLAG_FRAMING_GL)
-			framing = "GeneSys";
-		else if (dev->driver_info->flags & FLAG_FRAMING_Z)
-			framing = "Zaurus";
-		else if (dev->driver_info->flags & FLAG_FRAMING_RN)
-			framing = "RNDIS";
-		else if (dev->driver_info->flags & FLAG_FRAMING_AX)
-			framing = "ASIX";
-		else
-			framing = "simple";
-
-		devinfo (dev, "open: enable queueing "
-				"(rx %d, tx %d) mtu %d %s framing",
-			(int)RX_QLEN (dev), (int)TX_QLEN (dev), dev->net->mtu,
-			framing);
-	}
+	netif_info(dev, ifup, dev->net,
+		   "open: enable queueing (rx %d, tx %d) mtu %d %s framing\n",
+		   (int)RX_QLEN(dev), (int)TX_QLEN(dev),
+		   dev->net->mtu,
+		   (dev->driver_info->flags & FLAG_FRAMING_NC) ? "NetChip" :
+		   (dev->driver_info->flags & FLAG_FRAMING_GL) ? "GeneSys" :
+		   (dev->driver_info->flags & FLAG_FRAMING_Z) ? "Zaurus" :
+		   (dev->driver_info->flags & FLAG_FRAMING_RN) ? "RNDIS" :
+		   (dev->driver_info->flags & FLAG_FRAMING_AX) ? "ASIX" :
+		   "simple");
 
 	// delay posting reads until we're fully open
 	tasklet_schedule (&dev->bh);
@@ -771,6 +752,7 @@ int usbnet_open (struct net_device *net)
 		usb_autopm_put_interface(dev->intf);
 	}
 	return retval;
+
 done:
 	usb_autopm_put_interface(dev->intf);
 done_nopm:
@@ -908,8 +890,8 @@ kevent (struct work_struct *work)
 		    status != -ESHUTDOWN) {
 			if (netif_msg_tx_err (dev))
 fail_pipe:
-				deverr (dev, "can't clear tx halt, status %d",
-					status);
+				netdev_err(dev->net, "can't clear tx halt, status %d\n",
+					   status);
 		} else {
 			clear_bit (EVENT_TX_HALT, &dev->flags);
 			if (status != -ESHUTDOWN)
@@ -928,8 +910,8 @@ fail_pipe:
 		    status != -ESHUTDOWN) {
 			if (netif_msg_rx_err (dev))
 fail_halt:
-				deverr (dev, "can't clear rx halt, status %d",
-					status);
+				netdev_err(dev->net, "can't clear rx halt, status %d\n",
+					   status);
 		} else {
 			clear_bit (EVENT_RX_HALT, &dev->flags);
 			tasklet_schedule (&dev->bh);
@@ -967,18 +949,18 @@ fail_lowmem:
 		if(info->link_reset && (retval = info->link_reset(dev)) < 0) {
 			usb_autopm_put_interface(dev->intf);
 skip_reset:
-			devinfo(dev, "link reset failed (%d) usbnet usb-%s-%s, %s",
-				retval,
-				dev->udev->bus->bus_name, dev->udev->devpath,
-				info->description);
+			netdev_info(dev->net, "link reset failed (%d) usbnet usb-%s-%s, %s\n",
+				    retval,
+				    dev->udev->bus->bus_name,
+				    dev->udev->devpath,
+				    info->description);
 		} else {
 			usb_autopm_put_interface(dev->intf);
 		}
 	}
 
 	if (dev->flags)
-		devdbg (dev, "kevent done, flags = 0x%lx",
-			dev->flags);
+		netdev_dbg(dev->net, "kevent done, flags = 0x%lx\n", dev->flags);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1014,15 +996,14 @@ static void tx_complete (struct urb *urb
 			if (!timer_pending (&dev->delay)) {
 				mod_timer (&dev->delay,
 					jiffies + THROTTLE_JIFFIES);
-				if (netif_msg_link (dev))
-					devdbg (dev, "tx throttle %d",
-							urb->status);
+				netif_dbg(dev, link, dev->net,
+					  "tx throttle %d\n", urb->status);
 			}
 			netif_stop_queue (dev->net);
 			break;
 		default:
-			if (netif_msg_tx_err (dev))
-				devdbg (dev, "tx err %d", entry->urb->status);
+			netif_dbg(dev, tx_err, dev->net,
+				  "tx err %d\n", entry->urb->status);
 			break;
 		}
 	}
@@ -1064,16 +1045,14 @@ netdev_tx_t usbnet_start_xmit (struct sk
 	if (info->tx_fixup) {
 		skb = info->tx_fixup (dev, skb, GFP_ATOMIC);
 		if (!skb) {
-			if (netif_msg_tx_err (dev))
-				devdbg (dev, "can't tx_fixup skb");
+			netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n");
 			goto drop;
 		}
 	}
 	length = skb->len;
 
 	if (!(urb = usb_alloc_urb (0, GFP_ATOMIC))) {
-		if (netif_msg_tx_err (dev))
-			devdbg (dev, "no urb");
+		netif_dbg(dev, tx_err, dev->net, "no urb\n");
 		goto drop;
 	}
 
@@ -1113,7 +1092,7 @@ netdev_tx_t usbnet_start_xmit (struct sk
 		/* no use to process more packets */
 		netif_stop_queue(net);
 		spin_unlock_irqrestore(&dev->txq.lock, flags);
-		devdbg(dev, "Delaying transmission for resumption");
+		netdev_dbg(dev->net, "Delaying transmission for resumption\n");
 		goto deferred;
 	}
 #endif
@@ -1126,8 +1105,8 @@ netdev_tx_t usbnet_start_xmit (struct sk
 		break;
 	default:
 		usb_autopm_put_interface_async(dev->intf);
-		if (netif_msg_tx_err (dev))
-			devdbg (dev, "tx: submit urb err %d", retval);
+		netif_dbg(dev, tx_err, dev->net,
+			  "tx: submit urb err %d\n", retval);
 		break;
 	case 0:
 		net->trans_start = jiffies;
@@ -1138,17 +1117,15 @@ netdev_tx_t usbnet_start_xmit (struct sk
 	spin_unlock_irqrestore (&dev->txq.lock, flags);
 
 	if (retval) {
-		if (netif_msg_tx_err (dev))
-			devdbg (dev, "drop, code %d", retval);
+		netif_dbg(dev, tx_err, dev->net, "drop, code %d\n", retval);
 drop:
 		dev->net->stats.tx_dropped++;
 		if (skb)
 			dev_kfree_skb_any (skb);
 		usb_free_urb (urb);
-	} else if (netif_msg_tx_queued (dev)) {
-		devdbg (dev, "> tx, len %d, type 0x%x",
-			length, skb->protocol);
-	}
+	} else
+		netif_dbg(dev, tx_queued, dev->net,
+			  "> tx, len %d, type 0x%x\n", length, skb->protocol);
 #ifdef CONFIG_PM
 deferred:
 #endif
@@ -1179,7 +1156,7 @@ static void usbnet_bh (unsigned long par
 			dev_kfree_skb (skb);
 			continue;
 		default:
-			devdbg (dev, "bogus skb state %d", entry->state);
+			netdev_dbg(dev->net, "bogus skb state %d\n", entry->state);
 		}
 	}
 
@@ -1207,9 +1184,10 @@ static void usbnet_bh (unsigned long par
 				if (urb != NULL)
 					rx_submit (dev, urb, GFP_ATOMIC);
 			}
-			if (temp != dev->rxq.qlen && netif_msg_link (dev))
-				devdbg (dev, "rxqlen %d --> %d",
-						temp, dev->rxq.qlen);
+			if (temp != dev->rxq.qlen)
+				netif_dbg(dev, link, dev->net,
+					  "rxqlen %d --> %d\n",
+					  temp, dev->rxq.qlen);
 			if (dev->rxq.qlen < qlen)
 				tasklet_schedule (&dev->bh);
 		}
@@ -1240,11 +1218,10 @@ void usbnet_disconnect (struct usb_inter
 
 	xdev = interface_to_usbdev (intf);
 
-	if (netif_msg_probe (dev))
-		devinfo (dev, "unregister '%s' usb-%s-%s, %s",
-			intf->dev.driver->name,
-			xdev->bus->bus_name, xdev->devpath,
-			dev->driver_info->description);
+	netif_info(dev, probe, dev->net, "unregister '%s' usb-%s-%s, %s\n",
+		   intf->dev.driver->name,
+		   xdev->bus->bus_name, xdev->devpath,
+		   dev->driver_info->description);
 
 	net = dev->net;
 	unregister_netdev (net);
@@ -1407,12 +1384,12 @@ usbnet_probe (struct usb_interface *udev
 	status = register_netdev (net);
 	if (status)
 		goto out3;
-	if (netif_msg_probe (dev))
-		devinfo (dev, "register '%s' at usb-%s-%s, %s, %pM",
-			udev->dev.driver->name,
-			xdev->bus->bus_name, xdev->devpath,
-			dev->driver_info->description,
-			net->dev_addr);
+	netif_info(dev, probe, dev->net,
+		   "register '%s' at usb-%s-%s, %s, %pM\n",
+		   udev->dev.driver->name,
+		   xdev->bus->bus_name, xdev->devpath,
+		   dev->driver_info->description,
+		   net->dev_addr);
 
 	// ok, it's ready to go.
 	usb_set_intfdata (udev, dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/veth.c linux-libre-2.6.34-gnu1/drivers/net/veth.c
--- linux-libre-2.6.33-gnu1/drivers/net/veth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/veth.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  */
 
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/ethtool.h>
 #include <linux/etherdevice.h>
 
@@ -34,7 +35,7 @@ struct veth_net_stats {
 
 struct veth_priv {
 	struct net_device *peer;
-	struct veth_net_stats *stats;
+	struct veth_net_stats __percpu *stats;
 	unsigned ip_summed;
 };
 
@@ -186,7 +187,6 @@ tx_drop:
 	return NETDEV_TX_OK;
 
 rx_drop:
-	kfree_skb(skb);
 	rcv_stats->rx_dropped++;
 	return NETDEV_TX_OK;
 }
@@ -263,7 +263,7 @@ static int veth_change_mtu(struct net_de
 
 static int veth_dev_init(struct net_device *dev)
 {
-	struct veth_net_stats *stats;
+	struct veth_net_stats __percpu *stats;
 	struct veth_priv *priv;
 
 	stats = alloc_percpu(struct veth_net_stats);
@@ -333,19 +333,17 @@ static int veth_newlink(struct net *src_
 	struct veth_priv *priv;
 	char ifname[IFNAMSIZ];
 	struct nlattr *peer_tb[IFLA_MAX + 1], **tbp;
+	struct ifinfomsg *ifmp;
 	struct net *net;
 
 	/*
 	 * create and register peer first
-	 *
-	 * struct ifinfomsg is at the head of VETH_INFO_PEER, but we
-	 * skip it since no info from it is useful yet
 	 */
-
 	if (data != NULL && data[VETH_INFO_PEER] != NULL) {
 		struct nlattr *nla_peer;
 
 		nla_peer = data[VETH_INFO_PEER];
+		ifmp = nla_data(nla_peer);
 		err = nla_parse(peer_tb, IFLA_MAX,
 				nla_data(nla_peer) + sizeof(struct ifinfomsg),
 				nla_len(nla_peer) - sizeof(struct ifinfomsg),
@@ -358,8 +356,10 @@ static int veth_newlink(struct net *src_
 			return err;
 
 		tbp = peer_tb;
-	} else
+	} else {
+		ifmp = NULL;
 		tbp = tb;
+	}
 
 	if (tbp[IFLA_IFNAME])
 		nla_strlcpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
@@ -387,6 +387,10 @@ static int veth_newlink(struct net *src_
 
 	netif_carrier_off(peer);
 
+	err = rtnl_configure_link(peer, ifmp);
+	if (err < 0)
+		goto err_configure_peer;
+
 	/*
 	 * register dev last
 	 *
@@ -428,6 +432,7 @@ static int veth_newlink(struct net *src_
 err_register_dev:
 	/* nothing to do */
 err_alloc_name:
+err_configure_peer:
 	unregister_netdevice(peer);
 	return err;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/via-rhine.c linux-libre-2.6.34-gnu1/drivers/net/via-rhine.c
--- linux-libre-2.6.33-gnu1/drivers/net/via-rhine.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/via-rhine.c	2010-05-16 17:17:36.000000000 -0400
@@ -89,7 +89,6 @@ static const int multicast_filter_limit
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
@@ -267,7 +266,7 @@ enum rhine_quirks {
 /* Beware of PCI posted writes */
 #define IOSYNC	do { ioread8(ioaddr + StationAddr); } while (0)
 
-static const struct pci_device_id rhine_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(rhine_pci_tbl) = {
 	{ 0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, },	/* VT86C100A */
 	{ 0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, },	/* VT6102 */
 	{ 0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, },	/* 6105{,L,LOM} */
@@ -1697,7 +1696,7 @@ static void rhine_set_rx_mode(struct net
 		rx_mode = 0x1C;
 		iowrite32(0xffffffff, ioaddr + MulticastFilter0);
 		iowrite32(0xffffffff, ioaddr + MulticastFilter1);
-	} else if ((dev->mc_count > multicast_filter_limit) ||
+	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
 		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
 		iowrite32(0xffffffff, ioaddr + MulticastFilter0);
@@ -1705,10 +1704,9 @@ static void rhine_set_rx_mode(struct net
 		rx_mode = 0x0C;
 	} else {
 		struct dev_mc_list *mclist;
-		int i;
+
 		memset(mc_filter, 0, sizeof(mc_filter));
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-		     i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
 
 			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/via-velocity.c linux-libre-2.6.34-gnu1/drivers/net/via-velocity.c
--- linux-libre-2.6.33-gnu1/drivers/net/via-velocity.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/via-velocity.c	2010-05-16 17:17:36.000000000 -0400
@@ -361,7 +361,7 @@ static struct velocity_info_tbl chip_inf
  *	Describe the PCI device identifiers that we support in this
  *	device driver. Used for hotplug autoloading.
  */
-static const struct pci_device_id velocity_id_table[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(velocity_id_table) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_612X) },
 	{ }
 };
@@ -812,7 +812,7 @@ static void set_mii_flow_control(struct
 
 	case FLOW_CNTL_TX_RX:
 		MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
-		MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
+		MII_REG_BITS_OFF(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
 		break;
 
 	case FLOW_CNTL_DISABLE:
@@ -1132,7 +1132,7 @@ static void velocity_set_multi(struct ne
 		writel(0xffffffff, &regs->MARCAM[0]);
 		writel(0xffffffff, &regs->MARCAM[4]);
 		rx_mode = (RCR_AM | RCR_AB | RCR_PROM);
-	} else if ((dev->mc_count > vptr->multicast_limit) ||
+	} else if ((netdev_mc_count(dev) > vptr->multicast_limit) ||
 		   (dev->flags & IFF_ALLMULTI)) {
 		writel(0xffffffff, &regs->MARCAM[0]);
 		writel(0xffffffff, &regs->MARCAM[4]);
@@ -1141,9 +1141,11 @@ static void velocity_set_multi(struct ne
 		int offset = MCAM_SIZE - vptr->multicast_limit;
 		mac_get_cam_mask(regs, vptr->mCAMmask);
 
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) {
+		i = 0;
+		netdev_for_each_mc_addr(mclist, dev) {
 			mac_set_cam(regs, i + offset, mclist->dmi_addr);
 			vptr->mCAMmask[(offset + i) / 8] |= 1 << ((offset + i) & 7);
+			i++;
 		}
 
 		mac_set_cam_mask(regs, vptr->mCAMmask);
@@ -2698,10 +2700,8 @@ static void __devinit velocity_print_inf
 	struct net_device *dev = vptr->dev;
 
 	printk(KERN_INFO "%s: %s\n", dev->name, get_chip_name(vptr->chip_id));
-	printk(KERN_INFO "%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
-		dev->name,
-		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+	printk(KERN_INFO "%s: Ethernet Address: %pM\n",
+		dev->name, dev->dev_addr);
 }
 
 static u32 velocity_get_link(struct net_device *dev)
@@ -2825,7 +2825,7 @@ static int __devinit velocity_found1(str
 	netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT);
 
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
-		NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM;
+		NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM | NETIF_F_SG;
 
 	ret = register_netdev(dev);
 	if (ret < 0)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/virtio_net.c linux-libre-2.6.34-gnu1/drivers/net/virtio_net.c
--- linux-libre-2.6.33-gnu1/drivers/net/virtio_net.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/virtio_net.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/virtio_net.h>
 #include <linux/scatterlist.h>
 #include <linux/if_vlan.h>
+#include <linux/slab.h>
 
 static int napi_weight = 128;
 module_param(napi_weight, int, 0444);
@@ -56,10 +57,6 @@ struct virtnet_info
 	/* Host will merge rx buffers for big packets (shake it! shake it!) */
 	bool mergeable_rx_bufs;
 
-	/* Receive & send queues. */
-	struct sk_buff_head recv;
-	struct sk_buff_head send;
-
 	/* Work struct for refilling if we run low on memory. */
 	struct delayed_work refill;
 
@@ -75,34 +72,44 @@ struct skb_vnet_hdr {
 	unsigned int num_sg;
 };
 
+struct padded_vnet_hdr {
+	struct virtio_net_hdr hdr;
+	/*
+	 * virtio_net_hdr should be in a separated sg buffer because of a
+	 * QEMU bug, and data sg buffer shares same page with this header sg.
+	 * This padding makes next sg 16 byte aligned after virtio_net_hdr.
+	 */
+	char padding[6];
+};
+
 static inline struct skb_vnet_hdr *skb_vnet_hdr(struct sk_buff *skb)
 {
 	return (struct skb_vnet_hdr *)skb->cb;
 }
 
-static void give_a_page(struct virtnet_info *vi, struct page *page)
-{
-	page->private = (unsigned long)vi->pages;
-	vi->pages = page;
-}
-
-static void trim_pages(struct virtnet_info *vi, struct sk_buff *skb)
+/*
+ * private is used to chain pages for big packets, put the whole
+ * most recent used list in the beginning for reuse
+ */
+static void give_pages(struct virtnet_info *vi, struct page *page)
 {
-	unsigned int i;
+	struct page *end;
 
-	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-		give_a_page(vi, skb_shinfo(skb)->frags[i].page);
-	skb_shinfo(skb)->nr_frags = 0;
-	skb->data_len = 0;
+	/* Find end of list, sew whole thing into vi->pages. */
+	for (end = page; end->private; end = (struct page *)end->private);
+	end->private = (unsigned long)vi->pages;
+	vi->pages = page;
 }
 
 static struct page *get_a_page(struct virtnet_info *vi, gfp_t gfp_mask)
 {
 	struct page *p = vi->pages;
 
-	if (p)
+	if (p) {
 		vi->pages = (struct page *)p->private;
-	else
+		/* clear private here, it is used to chain pages */
+		p->private = 0;
+	} else
 		p = alloc_page(gfp_mask);
 	return p;
 }
@@ -118,99 +125,142 @@ static void skb_xmit_done(struct virtque
 	netif_wake_queue(vi->dev);
 }
 
-static void receive_skb(struct net_device *dev, struct sk_buff *skb,
-			unsigned len)
+static void set_skb_frag(struct sk_buff *skb, struct page *page,
+			 unsigned int offset, unsigned int *len)
 {
-	struct virtnet_info *vi = netdev_priv(dev);
-	struct skb_vnet_hdr *hdr = skb_vnet_hdr(skb);
-	int err;
-	int i;
+	int i = skb_shinfo(skb)->nr_frags;
+	skb_frag_t *f;
 
-	if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
-		pr_debug("%s: short packet %i\n", dev->name, len);
-		dev->stats.rx_length_errors++;
-		goto drop;
-	}
+	f = &skb_shinfo(skb)->frags[i];
+	f->size = min((unsigned)PAGE_SIZE - offset, *len);
+	f->page_offset = offset;
+	f->page = page;
 
-	if (vi->mergeable_rx_bufs) {
-		unsigned int copy;
-		char *p = page_address(skb_shinfo(skb)->frags[0].page);
+	skb->data_len += f->size;
+	skb->len += f->size;
+	skb_shinfo(skb)->nr_frags++;
+	*len -= f->size;
+}
 
-		if (len > PAGE_SIZE)
-			len = PAGE_SIZE;
-		len -= sizeof(struct virtio_net_hdr_mrg_rxbuf);
+static struct sk_buff *page_to_skb(struct virtnet_info *vi,
+				   struct page *page, unsigned int len)
+{
+	struct sk_buff *skb;
+	struct skb_vnet_hdr *hdr;
+	unsigned int copy, hdr_len, offset;
+	char *p;
 
-		memcpy(&hdr->mhdr, p, sizeof(hdr->mhdr));
-		p += sizeof(hdr->mhdr);
+	p = page_address(page);
 
-		copy = len;
-		if (copy > skb_tailroom(skb))
-			copy = skb_tailroom(skb);
+	/* copy small packet so we can reuse these pages for small data */
+	skb = netdev_alloc_skb_ip_align(vi->dev, GOOD_COPY_LEN);
+	if (unlikely(!skb))
+		return NULL;
 
-		memcpy(skb_put(skb, copy), p, copy);
+	hdr = skb_vnet_hdr(skb);
 
-		len -= copy;
+	if (vi->mergeable_rx_bufs) {
+		hdr_len = sizeof hdr->mhdr;
+		offset = hdr_len;
+	} else {
+		hdr_len = sizeof hdr->hdr;
+		offset = sizeof(struct padded_vnet_hdr);
+	}
 
-		if (!len) {
-			give_a_page(vi, skb_shinfo(skb)->frags[0].page);
-			skb_shinfo(skb)->nr_frags--;
-		} else {
-			skb_shinfo(skb)->frags[0].page_offset +=
-				sizeof(hdr->mhdr) + copy;
-			skb_shinfo(skb)->frags[0].size = len;
-			skb->data_len += len;
-			skb->len += len;
-		}
+	memcpy(hdr, p, hdr_len);
 
-		while (--hdr->mhdr.num_buffers) {
-			struct sk_buff *nskb;
+	len -= hdr_len;
+	p += offset;
 
-			i = skb_shinfo(skb)->nr_frags;
-			if (i >= MAX_SKB_FRAGS) {
-				pr_debug("%s: packet too long %d\n", dev->name,
-					 len);
-				dev->stats.rx_length_errors++;
-				goto drop;
-			}
+	copy = len;
+	if (copy > skb_tailroom(skb))
+		copy = skb_tailroom(skb);
+	memcpy(skb_put(skb, copy), p, copy);
 
-			nskb = vi->rvq->vq_ops->get_buf(vi->rvq, &len);
-			if (!nskb) {
-				pr_debug("%s: rx error: %d buffers missing\n",
-					 dev->name, hdr->mhdr.num_buffers);
-				dev->stats.rx_length_errors++;
-				goto drop;
-			}
+	len -= copy;
+	offset += copy;
 
-			__skb_unlink(nskb, &vi->recv);
-			vi->num--;
+	while (len) {
+		set_skb_frag(skb, page, offset, &len);
+		page = (struct page *)page->private;
+		offset = 0;
+	}
 
-			skb_shinfo(skb)->frags[i] = skb_shinfo(nskb)->frags[0];
-			skb_shinfo(nskb)->nr_frags = 0;
-			kfree_skb(nskb);
+	if (page)
+		give_pages(vi, page);
 
-			if (len > PAGE_SIZE)
-				len = PAGE_SIZE;
+	return skb;
+}
 
-			skb_shinfo(skb)->frags[i].size = len;
-			skb_shinfo(skb)->nr_frags++;
-			skb->data_len += len;
-			skb->len += len;
+static int receive_mergeable(struct virtnet_info *vi, struct sk_buff *skb)
+{
+	struct skb_vnet_hdr *hdr = skb_vnet_hdr(skb);
+	struct page *page;
+	int num_buf, i, len;
+
+	num_buf = hdr->mhdr.num_buffers;
+	while (--num_buf) {
+		i = skb_shinfo(skb)->nr_frags;
+		if (i >= MAX_SKB_FRAGS) {
+			pr_debug("%s: packet too long\n", skb->dev->name);
+			skb->dev->stats.rx_length_errors++;
+			return -EINVAL;
 		}
-	} else {
-		len -= sizeof(hdr->hdr);
 
-		if (len <= MAX_PACKET_LEN)
-			trim_pages(vi, skb);
+		page = vi->rvq->vq_ops->get_buf(vi->rvq, &len);
+		if (!page) {
+			pr_debug("%s: rx error: %d buffers missing\n",
+				 skb->dev->name, hdr->mhdr.num_buffers);
+			skb->dev->stats.rx_length_errors++;
+			return -EINVAL;
+		}
+		if (len > PAGE_SIZE)
+			len = PAGE_SIZE;
 
-		err = pskb_trim(skb, len);
-		if (err) {
-			pr_debug("%s: pskb_trim failed %i %d\n", dev->name,
-				 len, err);
+		set_skb_frag(skb, page, 0, &len);
+
+		--vi->num;
+	}
+	return 0;
+}
+
+static void receive_buf(struct net_device *dev, void *buf, unsigned int len)
+{
+	struct virtnet_info *vi = netdev_priv(dev);
+	struct sk_buff *skb;
+	struct page *page;
+	struct skb_vnet_hdr *hdr;
+
+	if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
+		pr_debug("%s: short packet %i\n", dev->name, len);
+		dev->stats.rx_length_errors++;
+		if (vi->mergeable_rx_bufs || vi->big_packets)
+			give_pages(vi, buf);
+		else
+			dev_kfree_skb(buf);
+		return;
+	}
+
+	if (!vi->mergeable_rx_bufs && !vi->big_packets) {
+		skb = buf;
+		len -= sizeof(struct virtio_net_hdr);
+		skb_trim(skb, len);
+	} else {
+		page = buf;
+		skb = page_to_skb(vi, page, len);
+		if (unlikely(!skb)) {
 			dev->stats.rx_dropped++;
-			goto drop;
+			give_pages(vi, page);
+			return;
 		}
+		if (vi->mergeable_rx_bufs)
+			if (receive_mergeable(vi, skb)) {
+				dev_kfree_skb(skb);
+				return;
+			}
 	}
 
+	hdr = skb_vnet_hdr(skb);
 	skb->truesize += skb->data_len;
 	dev->stats.rx_bytes += skb->len;
 	dev->stats.rx_packets++;
@@ -267,110 +317,121 @@ static void receive_skb(struct net_devic
 
 frame_err:
 	dev->stats.rx_frame_errors++;
-drop:
 	dev_kfree_skb(skb);
 }
 
-static bool try_fill_recv_maxbufs(struct virtnet_info *vi, gfp_t gfp)
+static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)
 {
 	struct sk_buff *skb;
-	struct scatterlist sg[2+MAX_SKB_FRAGS];
-	int num, err, i;
-	bool oom = false;
+	struct skb_vnet_hdr *hdr;
+	struct scatterlist sg[2];
+	int err;
 
-	sg_init_table(sg, 2+MAX_SKB_FRAGS);
-	do {
-		struct skb_vnet_hdr *hdr;
+	sg_init_table(sg, 2);
+	skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN);
+	if (unlikely(!skb))
+		return -ENOMEM;
 
-		skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN);
-		if (unlikely(!skb)) {
-			oom = true;
-			break;
-		}
+	skb_put(skb, MAX_PACKET_LEN);
 
-		skb_put(skb, MAX_PACKET_LEN);
+	hdr = skb_vnet_hdr(skb);
+	sg_set_buf(sg, &hdr->hdr, sizeof hdr->hdr);
 
-		hdr = skb_vnet_hdr(skb);
-		sg_set_buf(sg, &hdr->hdr, sizeof(hdr->hdr));
+	skb_to_sgvec(skb, sg + 1, 0, skb->len);
 
-		if (vi->big_packets) {
-			for (i = 0; i < MAX_SKB_FRAGS; i++) {
-				skb_frag_t *f = &skb_shinfo(skb)->frags[i];
-				f->page = get_a_page(vi, gfp);
-				if (!f->page)
-					break;
+	err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, 2, skb);
+	if (err < 0)
+		dev_kfree_skb(skb);
 
-				f->page_offset = 0;
-				f->size = PAGE_SIZE;
+	return err;
+}
 
-				skb->data_len += PAGE_SIZE;
-				skb->len += PAGE_SIZE;
+static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
+{
+	struct scatterlist sg[MAX_SKB_FRAGS + 2];
+	struct page *first, *list = NULL;
+	char *p;
+	int i, err, offset;
 
-				skb_shinfo(skb)->nr_frags++;
-			}
+	sg_init_table(sg, MAX_SKB_FRAGS + 2);
+	/* page in sg[MAX_SKB_FRAGS + 1] is list tail */
+	for (i = MAX_SKB_FRAGS + 1; i > 1; --i) {
+		first = get_a_page(vi, gfp);
+		if (!first) {
+			if (list)
+				give_pages(vi, list);
+			return -ENOMEM;
 		}
+		sg_set_buf(&sg[i], page_address(first), PAGE_SIZE);
 
-		num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
-		skb_queue_head(&vi->recv, skb);
+		/* chain new page in list head to match sg */
+		first->private = (unsigned long)list;
+		list = first;
+	}
 
-		err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb);
-		if (err < 0) {
-			skb_unlink(skb, &vi->recv);
-			trim_pages(vi, skb);
-			kfree_skb(skb);
-			break;
-		}
-		vi->num++;
-	} while (err >= num);
-	if (unlikely(vi->num > vi->max))
-		vi->max = vi->num;
-	vi->rvq->vq_ops->kick(vi->rvq);
-	return !oom;
+	first = get_a_page(vi, gfp);
+	if (!first) {
+		give_pages(vi, list);
+		return -ENOMEM;
+	}
+	p = page_address(first);
+
+	/* sg[0], sg[1] share the same page */
+	/* a separated sg[0] for  virtio_net_hdr only during to QEMU bug*/
+	sg_set_buf(&sg[0], p, sizeof(struct virtio_net_hdr));
+
+	/* sg[1] for data packet, from offset */
+	offset = sizeof(struct padded_vnet_hdr);
+	sg_set_buf(&sg[1], p + offset, PAGE_SIZE - offset);
+
+	/* chain first in list head */
+	first->private = (unsigned long)list;
+	err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, MAX_SKB_FRAGS + 2,
+				       first);
+	if (err < 0)
+		give_pages(vi, first);
+
+	return err;
 }
 
-/* Returns false if we couldn't fill entirely (OOM). */
-static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
+static int add_recvbuf_mergeable(struct virtnet_info *vi, gfp_t gfp)
 {
-	struct sk_buff *skb;
-	struct scatterlist sg[1];
+	struct page *page;
+	struct scatterlist sg;
 	int err;
-	bool oom = false;
 
-	if (!vi->mergeable_rx_bufs)
-		return try_fill_recv_maxbufs(vi, gfp);
-
-	do {
-		skb_frag_t *f;
+	page = get_a_page(vi, gfp);
+	if (!page)
+		return -ENOMEM;
 
-		skb = netdev_alloc_skb_ip_align(vi->dev, GOOD_COPY_LEN);
-		if (unlikely(!skb)) {
-			oom = true;
-			break;
-		}
+	sg_init_one(&sg, page_address(page), PAGE_SIZE);
 
-		f = &skb_shinfo(skb)->frags[0];
-		f->page = get_a_page(vi, gfp);
-		if (!f->page) {
-			oom = true;
-			kfree_skb(skb);
-			break;
-		}
+	err = vi->rvq->vq_ops->add_buf(vi->rvq, &sg, 0, 1, page);
+	if (err < 0)
+		give_pages(vi, page);
 
-		f->page_offset = 0;
-		f->size = PAGE_SIZE;
+	return err;
+}
 
-		skb_shinfo(skb)->nr_frags++;
+/* Returns false if we couldn't fill entirely (OOM). */
+static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
+{
+	int err;
+	bool oom = false;
 
-		sg_init_one(sg, page_address(f->page), PAGE_SIZE);
-		skb_queue_head(&vi->recv, skb);
+	do {
+		if (vi->mergeable_rx_bufs)
+			err = add_recvbuf_mergeable(vi, gfp);
+		else if (vi->big_packets)
+			err = add_recvbuf_big(vi, gfp);
+		else
+			err = add_recvbuf_small(vi, gfp);
 
-		err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, 1, skb);
 		if (err < 0) {
-			skb_unlink(skb, &vi->recv);
-			kfree_skb(skb);
+			oom = true;
 			break;
 		}
-		vi->num++;
+		++vi->num;
 	} while (err > 0);
 	if (unlikely(vi->num > vi->max))
 		vi->max = vi->num;
@@ -407,15 +468,14 @@ static void refill_work(struct work_stru
 static int virtnet_poll(struct napi_struct *napi, int budget)
 {
 	struct virtnet_info *vi = container_of(napi, struct virtnet_info, napi);
-	struct sk_buff *skb = NULL;
+	void *buf;
 	unsigned int len, received = 0;
 
 again:
 	while (received < budget &&
-	       (skb = vi->rvq->vq_ops->get_buf(vi->rvq, &len)) != NULL) {
-		__skb_unlink(skb, &vi->recv);
-		receive_skb(vi->dev, skb, len);
-		vi->num--;
+	       (buf = vi->rvq->vq_ops->get_buf(vi->rvq, &len)) != NULL) {
+		receive_buf(vi->dev, buf, len);
+		--vi->num;
 		received++;
 	}
 
@@ -445,7 +505,6 @@ static unsigned int free_old_xmit_skbs(s
 
 	while ((skb = vi->svq->vq_ops->get_buf(vi->svq, &len)) != NULL) {
 		pr_debug("Sent skb %p\n", skb);
-		__skb_unlink(skb, &vi->send);
 		vi->dev->stats.tx_bytes += skb->len;
 		vi->dev->stats.tx_packets++;
 		tot_sgs += skb_vnet_hdr(skb)->num_sg;
@@ -495,9 +554,9 @@ static int xmit_skb(struct virtnet_info
 
 	/* Encode metadata header at front. */
 	if (vi->mergeable_rx_bufs)
-		sg_set_buf(sg, &hdr->mhdr, sizeof(hdr->mhdr));
+		sg_set_buf(sg, &hdr->mhdr, sizeof hdr->mhdr);
 	else
-		sg_set_buf(sg, &hdr->hdr, sizeof(hdr->hdr));
+		sg_set_buf(sg, &hdr->hdr, sizeof hdr->hdr);
 
 	hdr->num_sg = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
 	return vi->svq->vq_ops->add_buf(vi->svq, sg, hdr->num_sg, 0, skb);
@@ -528,15 +587,6 @@ again:
 	}
 	vi->svq->vq_ops->kick(vi->svq);
 
-	/*
-	 * Put new one in send queue.  You'd expect we'd need this before
-	 * xmit_skb calls add_buf(), since the callback can be triggered
-	 * immediately after that.  But since the callback just triggers
-	 * another call back here, normal network xmit locking prevents the
-	 * race.
-	 */
-	__skb_queue_head(&vi->send, skb);
-
 	/* Don't wait up for transmitted skbs to be freed. */
 	skb_orphan(skb);
 	nf_reset(skb);
@@ -674,6 +724,8 @@ static void virtnet_set_rx_mode(struct n
 	struct virtio_net_ctrl_mac *mac_data;
 	struct dev_addr_list *addr;
 	struct netdev_hw_addr *ha;
+	int uc_count;
+	int mc_count;
 	void *buf;
 	int i;
 
@@ -700,9 +752,12 @@ static void virtnet_set_rx_mode(struct n
 		dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n",
 			 allmulti ? "en" : "dis");
 
+	uc_count = netdev_uc_count(dev);
+	mc_count = netdev_mc_count(dev);
 	/* 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);
+	buf = kzalloc(((uc_count + mc_count) * ETH_ALEN) +
+		      (2 * sizeof(mac_data->entries)), GFP_ATOMIC);
+	mac_data = buf;
 	if (!buf) {
 		dev_warn(&dev->dev, "No memory for MAC address buffer\n");
 		return;
@@ -711,24 +766,24 @@ static void virtnet_set_rx_mode(struct n
 	sg_init_table(sg, 2);
 
 	/* Store the unicast list and count in the front of the buffer */
-	mac_data->entries = dev->uc.count;
+	mac_data->entries = uc_count;
 	i = 0;
-	list_for_each_entry(ha, &dev->uc.list, list)
+	netdev_for_each_uc_addr(ha, dev)
 		memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN);
 
 	sg_set_buf(&sg[0], mac_data,
-		   sizeof(mac_data->entries) + (dev->uc.count * ETH_ALEN));
+		   sizeof(mac_data->entries) + (uc_count * ETH_ALEN));
 
 	/* multicast list and count fill the end */
-	mac_data = (void *)&mac_data->macs[dev->uc.count][0];
+	mac_data = (void *)&mac_data->macs[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);
+	mac_data->entries = mc_count;
+	i = 0;
+	netdev_for_each_mc_addr(addr, dev)
+		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));
+		   sizeof(mac_data->entries) + (mc_count * ETH_ALEN));
 
 	if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC,
 				  VIRTIO_NET_CTRL_MAC_TABLE_SET,
@@ -915,10 +970,6 @@ static int virtnet_probe(struct virtio_d
 			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);
-
 	err = register_netdev(dev);
 	if (err) {
 		pr_debug("virtio_net: registering device failed\n");
@@ -951,26 +1002,42 @@ free:
 	return err;
 }
 
+static void free_unused_bufs(struct virtnet_info *vi)
+{
+	void *buf;
+	while (1) {
+		buf = vi->svq->vq_ops->detach_unused_buf(vi->svq);
+		if (!buf)
+			break;
+		dev_kfree_skb(buf);
+	}
+	while (1) {
+		buf = vi->rvq->vq_ops->detach_unused_buf(vi->rvq);
+		if (!buf)
+			break;
+		if (vi->mergeable_rx_bufs || vi->big_packets)
+			give_pages(vi, buf);
+		else
+			dev_kfree_skb(buf);
+		--vi->num;
+	}
+	BUG_ON(vi->num != 0);
+}
+
 static void __devexit virtnet_remove(struct virtio_device *vdev)
 {
 	struct virtnet_info *vi = vdev->priv;
-	struct sk_buff *skb;
 
 	/* Stop all the virtqueues. */
 	vdev->config->reset(vdev);
 
-	/* Free our skbs in send and recv queues, if any. */
-	while ((skb = __skb_dequeue(&vi->recv)) != NULL) {
-		kfree_skb(skb);
-		vi->num--;
-	}
-	__skb_queue_purge(&vi->send);
-
-	BUG_ON(vi->num != 0);
 
 	unregister_netdev(vi->dev);
 	cancel_delayed_work_sync(&vi->refill);
 
+	/* Free unused buffers in both send and recv, if any. */
+	free_unused_bufs(vi);
+
 	vdev->config->del_vqs(vi->vdev);
 
 	while (vi->pages)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/vmxnet3/vmxnet3_drv.c linux-libre-2.6.34-gnu1/drivers/net/vmxnet3/vmxnet3_drv.c
--- linux-libre-2.6.33-gnu1/drivers/net/vmxnet3/vmxnet3_drv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/vmxnet3/vmxnet3_drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,7 +35,7 @@ char vmxnet3_driver_name[] = "vmxnet3";
  * PCI Device ID Table
  * Last entry must be all 0s
  */
-static const struct pci_device_id vmxnet3_pciid_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(vmxnet3_pciid_table) = {
 	{PCI_VDEVICE(VMWARE, PCI_DEVICE_ID_VMWARE_VMXNET3)},
 	{0}
 };
@@ -1668,22 +1668,19 @@ static u8 *
 vmxnet3_copy_mc(struct net_device *netdev)
 {
 	u8 *buf = NULL;
-	u32 sz = netdev->mc_count * ETH_ALEN;
+	u32 sz = netdev_mc_count(netdev) * ETH_ALEN;
 
 	/* struct Vmxnet3_RxFilterConf.mfTableLen is u16. */
 	if (sz <= 0xffff) {
 		/* We may be called with BH disabled */
 		buf = kmalloc(sz, GFP_ATOMIC);
 		if (buf) {
-			int i;
-			struct dev_mc_list *mc = netdev->mc_list;
+			struct dev_mc_list *mc;
+			int i = 0;
 
-			for (i = 0; i < netdev->mc_count; i++) {
-				BUG_ON(!mc);
-				memcpy(buf + i * ETH_ALEN, mc->dmi_addr,
+			netdev_for_each_mc_addr(mc, netdev)
+				memcpy(buf + i++ * ETH_ALEN, mc->dmi_addr,
 				       ETH_ALEN);
-				mc = mc->next;
-			}
 		}
 	}
 	return buf;
@@ -1708,12 +1705,12 @@ vmxnet3_set_mc(struct net_device *netdev
 	if (netdev->flags & IFF_ALLMULTI)
 		new_mode |= VMXNET3_RXM_ALL_MULTI;
 	else
-		if (netdev->mc_count > 0) {
+		if (!netdev_mc_empty(netdev)) {
 			new_table = vmxnet3_copy_mc(netdev);
 			if (new_table) {
 				new_mode |= VMXNET3_RXM_MCAST;
 				rxConf->mfTableLen = cpu_to_le16(
-						netdev->mc_count * ETH_ALEN);
+					netdev_mc_count(netdev) * ETH_ALEN);
 				rxConf->mfTablePA = cpu_to_le64(virt_to_phys(
 						    new_table));
 			} else {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-config.c linux-libre-2.6.34-gnu1/drivers/net/vxge/vxge-config.c
--- linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-config.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/vxge/vxge-config.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/etherdevice.h>
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
+#include <linux/slab.h>
 
 #include "vxge-traffic.h"
 #include "vxge-config.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-config.h linux-libre-2.6.34-gnu1/drivers/net/vxge/vxge-config.h
--- linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-config.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/vxge/vxge-config.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #ifndef VXGE_CONFIG_H
 #define VXGE_CONFIG_H
 #include <linux/list.h>
+#include <linux/slab.h>
 
 #ifndef VXGE_CACHE_LINE_SIZE
 #define VXGE_CACHE_LINE_SIZE 128
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-ethtool.c linux-libre-2.6.34-gnu1/drivers/net/vxge/vxge-ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/vxge/vxge-ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
  * Copyright(c) 2002-2009 Neterion Inc.
  ******************************************************************************/
 #include<linux/ethtool.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/etherdevice.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-main.c linux-libre-2.6.34-gnu1/drivers/net/vxge/vxge-main.c
--- linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/vxge/vxge-main.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,7 @@
 
 #include <linux/if_vlan.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/tcp.h>
 #include <net/ip.h>
 #include <linux/netdevice.h>
@@ -54,7 +55,7 @@ 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 = {
+static DEFINE_PCI_DEVICE_TABLE(vxge_id_table) = {
 	{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,
@@ -1178,11 +1179,11 @@ static void vxge_set_multicast(struct ne
 
 	memset(&mac_info, 0, sizeof(struct macInfo));
 	/* Update individual M_CAST address list */
-	if ((!vdev->all_multi_flg) && dev->mc_count) {
+	if ((!vdev->all_multi_flg) && netdev_mc_count(dev)) {
 
 		mcast_cnt = vdev->vpaths[0].mcast_addr_cnt;
 		list_head = &vdev->vpaths[0].mac_addr_list;
-		if ((dev->mc_count +
+		if ((netdev_mc_count(dev) +
 			(vdev->vpaths[0].mac_addr_cnt - mcast_cnt)) >
 				vdev->vpaths[0].max_mac_addr_cnt)
 			goto _set_all_mcast;
@@ -1217,9 +1218,7 @@ static void vxge_set_multicast(struct ne
 		}
 
 		/* Add new ones */
-		for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
-			i++, mclist = mclist->next) {
-
+		netdev_for_each_mc_addr(mclist, dev) {
 			memcpy(mac_info.macaddr, mclist->dmi_addr, ETH_ALEN);
 			for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath;
 					vpath_idx++) {
@@ -4297,10 +4296,8 @@ vxge_probe(struct pci_dev *pdev, const s
 	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: MAC ADDR: %pM",
+		vdev->ndev->name, macaddr);
 
 	vxge_debug_init(VXGE_TRACE, "%s: Link Width x%d",
 		vdev->ndev->name, vxge_hw_device_link_width_get(hldev));
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/cosa.c linux-libre-2.6.34-gnu1/drivers/net/wan/cosa.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/cosa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/cosa.c	2010-05-16 17:17:36.000000000 -0400
@@ -811,7 +811,7 @@ static ssize_t cosa_read(struct file *fi
 	cosa_enable_rx(chan);
 	spin_lock_irqsave(&cosa->lock, flags);
 	add_wait_queue(&chan->rxwaitq, &wait);
-	while(!chan->rx_status) {
+	while (!chan->rx_status) {
 		current->state = TASK_INTERRUPTIBLE;
 		spin_unlock_irqrestore(&cosa->lock, flags);
 		schedule();
@@ -896,7 +896,7 @@ static ssize_t cosa_write(struct file *f
 
 	spin_lock_irqsave(&cosa->lock, flags);
 	add_wait_queue(&chan->txwaitq, &wait);
-	while(!chan->tx_status) {
+	while (!chan->tx_status) {
 		current->state = TASK_INTERRUPTIBLE;
 		spin_unlock_irqrestore(&cosa->lock, flags);
 		schedule();
@@ -1153,7 +1153,7 @@ static int cosa_ioctl_common(struct cosa
 	struct channel_data *channel, unsigned int cmd, unsigned long arg)
 {
 	void __user *argp = (void __user *)arg;
-	switch(cmd) {
+	switch (cmd) {
 	case COSAIORSET:	/* Reset the device */
 		if (!capable(CAP_NET_ADMIN))
 			return -EACCES;
@@ -1704,7 +1704,7 @@ static inline void tx_interrupt(struct c
 			spin_unlock_irqrestore(&cosa->lock, flags);
 			return;
 		}
-		while(1) {
+		while (1) {
 			cosa->txchan++;
 			i++;
 			if (cosa->txchan >= cosa->nchannels)
@@ -2010,7 +2010,7 @@ again:
 static void debug_status_in(struct cosa_data *cosa, int status)
 {
 	char *s;
-	switch(status & SR_CMD_FROM_SRP_MASK) {
+	switch (status & SR_CMD_FROM_SRP_MASK) {
 	case SR_UP_REQUEST:
 		s = "RX_REQ";
 		break;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/dscc4.c linux-libre-2.6.34-gnu1/drivers/net/wan/dscc4.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/dscc4.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/dscc4.c	2010-05-16 17:17:36.000000000 -0400
@@ -89,6 +89,7 @@
 #include <linux/pci.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/cache.h>
@@ -2050,7 +2051,7 @@ static int __init dscc4_setup(char *str)
 __setup("dscc4.setup=", dscc4_setup);
 #endif
 
-static struct pci_device_id dscc4_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(dscc4_pci_tbl) = {
 	{ PCI_VENDOR_ID_SIEMENS, PCI_DEVICE_ID_SIEMENS_DSCC4,
 	        PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0,}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/farsync.c linux-libre-2.6.34-gnu1/drivers/net/wan/farsync.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/farsync.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/farsync.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/version.h>
 #include <linux/pci.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/if.h>
@@ -528,7 +529,7 @@ static int fst_debug_mask = { FST_DEBUG
 /*
  *      PCI ID lookup table
  */
-static struct pci_device_id fst_pci_dev_id[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(fst_pci_dev_id) = {
 	{PCI_VENDOR_ID_FARSITE, PCI_DEVICE_ID_FARSITE_T2P, PCI_ANY_ID, 
 	 PCI_ANY_ID, 0, 0, FST_TYPE_T2P},
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/hd64570.c linux-libre-2.6.34-gnu1/drivers/net/wan/hd64570.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/hd64570.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/hd64570.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,7 +37,6 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/hd64572.c linux-libre-2.6.34-gnu1/drivers/net/wan/hd64572.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/hd64572.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/hd64572.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,7 +37,6 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/hdlc_cisco.c linux-libre-2.6.34-gnu1/drivers/net/wan/hdlc_cisco.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/hdlc_cisco.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/hdlc_cisco.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,7 +20,6 @@
 #include <linux/poll.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 
 #undef DEBUG_HARD_HEADER
 
@@ -141,7 +140,7 @@ static __be16 cisco_type_trans(struct sk
 	    data->address != CISCO_UNICAST)
 		return cpu_to_be16(ETH_P_HDLC);
 
-	switch(data->protocol) {
+	switch (data->protocol) {
 	case cpu_to_be16(ETH_P_IP):
 	case cpu_to_be16(ETH_P_IPX):
 	case cpu_to_be16(ETH_P_IPV6):
@@ -190,7 +189,7 @@ static int cisco_rx(struct sk_buff *skb)
 		cisco_data = (struct cisco_packet*)(skb->data + sizeof
 						    (struct hdlc_header));
 
-		switch(ntohl (cisco_data->type)) {
+		switch (ntohl (cisco_data->type)) {
 		case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */
 			in_dev = dev->ip_ptr;
 			addr = 0;
@@ -245,8 +244,8 @@ static int cisco_rx(struct sk_buff *skb)
 
 			dev_kfree_skb_any(skb);
 			return NET_RX_SUCCESS;
-		} /* switch(keepalive type) */
-	} /* switch(protocol) */
+		} /* switch (keepalive type) */
+	} /* switch (protocol) */
 
 	printk(KERN_INFO "%s: Unsupported protocol %x\n", dev->name,
 	       ntohs(data->protocol));
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/hdlc_ppp.c linux-libre-2.6.34-gnu1/drivers/net/wan/hdlc_ppp.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/hdlc_ppp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/hdlc_ppp.c	2010-05-16 17:17:36.000000000 -0400
@@ -628,9 +628,15 @@ static void ppp_stop(struct net_device *
 	ppp_cp_event(dev, PID_LCP, STOP, 0, 0, 0, NULL);
 }
 
+static void ppp_close(struct net_device *dev)
+{
+	ppp_tx_flush();
+}
+
 static struct hdlc_proto proto = {
 	.start		= ppp_start,
 	.stop		= ppp_stop,
+	.close		= ppp_close,
 	.type_trans	= ppp_type_trans,
 	.ioctl		= ppp_ioctl,
 	.netif_rx	= ppp_rx,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/hdlc_raw.c linux-libre-2.6.34-gnu1/drivers/net/wan/hdlc_raw.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/hdlc_raw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/hdlc_raw.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,7 +20,6 @@
 #include <linux/poll.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 
 
 static int raw_ioctl(struct net_device *dev, struct ifreq *ifr);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/hdlc_raw_eth.c linux-libre-2.6.34-gnu1/drivers/net/wan/hdlc_raw_eth.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/hdlc_raw_eth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/hdlc_raw_eth.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <linux/errno.h>
 #include <linux/etherdevice.h>
+#include <linux/gfp.h>
 #include <linux/hdlc.h>
 #include <linux/if_arp.h>
 #include <linux/inetdevice.h>
@@ -21,7 +22,6 @@
 #include <linux/poll.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 
 static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/hdlc_x25.c linux-libre-2.6.34-gnu1/drivers/net/wan/hdlc_x25.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/hdlc_x25.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/hdlc_x25.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/hdlc.h>
 #include <linux/if_arp.h>
 #include <linux/inetdevice.h>
@@ -21,7 +22,6 @@
 #include <linux/poll.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <net/x25device.h>
 
 static int x25_ioctl(struct net_device *dev, struct ifreq *ifr);
@@ -202,10 +202,10 @@ static int x25_ioctl(struct net_device *
 		return 0; /* return protocol only, no settable parameters */
 
 	case IF_PROTO_X25:
-		if(!capable(CAP_NET_ADMIN))
+		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 
-		if(dev->flags & IFF_UP)
+		if (dev->flags & IFF_UP)
 			return -EBUSY;
 
 		result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/hostess_sv11.c linux-libre-2.6.34-gnu1/drivers/net/wan/hostess_sv11.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/hostess_sv11.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/hostess_sv11.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/delay.h>
 #include <linux/hdlc.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 
 #include <asm/irq.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/ixp4xx_hss.c linux-libre-2.6.34-gnu1/drivers/net/wan/ixp4xx_hss.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/ixp4xx_hss.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/ixp4xx_hss.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <mach/npe.h>
 #include <mach/qmgr.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/lapbether.c linux-libre-2.6.34-gnu1/drivers/net/wan/lapbether.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/lapbether.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/lapbether.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/types.h>
 #include <linux/socket.h>
 #include <linux/in.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/net.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/lmc/lmc_main.c linux-libre-2.6.34-gnu1/drivers/net/wan/lmc/lmc_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/lmc/lmc_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/lmc/lmc_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -77,7 +77,7 @@
 
 static int LMC_PKT_BUF_SZ = 1542;
 
-static struct pci_device_id lmc_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(lmc_pci_tbl) = {
 	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
 	  PCI_VENDOR_ID_LMC, PCI_ANY_ID },
 	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/lmc/lmc_media.c linux-libre-2.6.34-gnu1/drivers/net/wan/lmc/lmc_media.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/lmc/lmc_media.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/lmc/lmc_media.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,6 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/if_arp.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/lmc/lmc_proto.c linux-libre-2.6.34-gnu1/drivers/net/wan/lmc/lmc_proto.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/lmc/lmc_proto.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/lmc/lmc_proto.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,6 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/if_arp.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/pc300_drv.c linux-libre-2.6.34-gnu1/drivers/net/wan/pc300_drv.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/pc300_drv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/pc300_drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -228,6 +228,7 @@ static char rcsid[] =
 #include <linux/etherdevice.h>
 #include <linux/spinlock.h>
 #include <linux/if.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 
 #include <asm/io.h>
@@ -251,7 +252,7 @@ static char rcsid[] =
 #undef	PC300_DEBUG_RX
 #undef	PC300_DEBUG_OTHER
 
-static struct pci_device_id cpc_pci_dev_id[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(cpc_pci_dev_id) = {
 	/* PC300/RSV or PC300/X21, 2 chan */
 	{0x120e, 0x300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x300},
 	/* PC300/RSV or PC300/X21, 1 chan */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/pc300too.c linux-libre-2.6.34-gnu1/drivers/net/wan/pc300too.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/pc300too.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/pc300too.c	2010-05-16 17:17:36.000000000 -0400
@@ -481,7 +481,7 @@ static int __devinit pc300_pci_init_one(
 
 
 
-static struct pci_device_id pc300_pci_tbl[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(pc300_pci_tbl) = {
 	{ PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_PC300_RX_1, PCI_ANY_ID,
 	  PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_PC300_RX_2, PCI_ANY_ID,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/pci200syn.c linux-libre-2.6.34-gnu1/drivers/net/wan/pci200syn.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/pci200syn.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/pci200syn.c	2010-05-16 17:17:36.000000000 -0400
@@ -417,7 +417,7 @@ static int __devinit pci200_pci_init_one
 
 
 
-static struct pci_device_id pci200_pci_tbl[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(pci200_pci_tbl) = {
 	{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_PLX,
 	  PCI_DEVICE_ID_PLX_PCI200SYN, 0, 0, 0 },
 	{ 0, }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/sbni.c linux-libre-2.6.34-gnu1/drivers/net/wan/sbni.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/sbni.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/sbni.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,7 +43,6 @@
 #include <linux/fcntl.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/sealevel.c linux-libre-2.6.34-gnu1/drivers/net/wan/sealevel.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/sealevel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/sealevel.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/hdlc.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 
 #include <asm/irq.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/wanxl.c linux-libre-2.6.34-gnu1/drivers/net/wan/wanxl.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/wanxl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/wanxl.c	2010-05-16 17:17:36.000000000 -0400
@@ -814,7 +814,7 @@ static int __devinit wanxl_pci_init_one(
 	return 0;
 }
 
-static struct pci_device_id wanxl_pci_tbl[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(wanxl_pci_tbl) = {
 	{ PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_SBE_WANXL100, PCI_ANY_ID,
 	  PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_SBE_WANXL200, PCI_ANY_ID,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/x25_asy.c linux-libre-2.6.34-gnu1/drivers/net/wan/x25_asy.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/x25_asy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/x25_asy.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/compat.h>
+#include <linux/slab.h>
 #include "x25_asy.h"
 
 #include <net/x25device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wan/z85230.c linux-libre-2.6.34-gnu1/drivers/net/wan/z85230.c
--- linux-libre-2.6.33-gnu1/drivers/net/wan/z85230.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wan/z85230.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,7 @@
 #include <linux/hdlc.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <asm/dma.h>
 #include <asm/io.h>
 #define RT_LOCK
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/control.c linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/control.c
--- linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/control.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/control.c	2010-05-16 17:17:36.000000000 -0400
@@ -76,6 +76,7 @@
 #include <stdarg.h>
 #include "i2400m.h"
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/wimax/i2400m.h>
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/driver.c linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/driver.c
--- linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/driver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/driver.c	2010-05-16 17:17:36.000000000 -0400
@@ -69,6 +69,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/suspend.h>
+#include <linux/slab.h>
 
 #define D_SUBMODULE driver
 #include "debug-levels.h"
@@ -301,24 +302,15 @@ int i2400m_check_mac_addr(struct i2400m
 	/* Extract MAC addresss */
 	ddi = (void *) skb->data;
 	BUILD_BUG_ON(ETH_ALEN != sizeof(ddi->mac_address));
-	d_printf(2, dev, "GET DEVICE INFO: mac addr "
-		 "%02x:%02x:%02x:%02x:%02x:%02x\n",
-		 ddi->mac_address[0], ddi->mac_address[1],
-		 ddi->mac_address[2], ddi->mac_address[3],
-		 ddi->mac_address[4], ddi->mac_address[5]);
+	d_printf(2, dev, "GET DEVICE INFO: mac addr %pM\n",
+		 ddi->mac_address);
 	if (!memcmp(net_dev->perm_addr, ddi->mac_address,
 		   sizeof(ddi->mac_address)))
 		goto ok;
 	dev_warn(dev, "warning: device reports a different MAC address "
 		 "to that of boot mode's\n");
-	dev_warn(dev, "device reports     %02x:%02x:%02x:%02x:%02x:%02x\n",
-		 ddi->mac_address[0], ddi->mac_address[1],
-		 ddi->mac_address[2], ddi->mac_address[3],
-		 ddi->mac_address[4], ddi->mac_address[5]);
-	dev_warn(dev, "boot mode reported %02x:%02x:%02x:%02x:%02x:%02x\n",
-		 net_dev->perm_addr[0], net_dev->perm_addr[1],
-		 net_dev->perm_addr[2], net_dev->perm_addr[3],
-		 net_dev->perm_addr[4], net_dev->perm_addr[5]);
+	dev_warn(dev, "device reports     %pM\n", ddi->mac_address);
+	dev_warn(dev, "boot mode reported %pM\n", net_dev->perm_addr);
 	if (!memcmp(zeromac, ddi->mac_address, sizeof(zeromac)))
 		dev_err(dev, "device reports an invalid MAC address, "
 			"not updating\n");
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/fw.c linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/fw.c
--- linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/fw.c	2013-05-03 12:12:01.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/fw.c	2013-05-03 09:51:34.000000000 -0400
@@ -156,6 +156,7 @@
  */
 #include <linux/firmware.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include "i2400m.h"
 
@@ -612,7 +613,7 @@ ssize_t i2400m_bm_cmd(struct i2400m *i24
 		goto error_wait_for_ack;
 	}
 	rx_bytes = result;
-	/* verify the ack and read more if neccessary [result is the
+	/* verify the ack and read more if necessary [result is the
 	 * final amount of bytes we get in the ack]  */
 	result = __i2400m_bm_ack_verify(i2400m, opcode, ack, ack_size, flags);
 	if (result < 0)
@@ -1041,21 +1042,14 @@ int i2400m_read_mac_addr(struct i2400m *
 		dev_err(dev, "BM: read mac addr failed: %d\n", result);
 		goto error_read_mac;
 	}
-	d_printf(2, dev,
-		 "mac addr is %02x:%02x:%02x:%02x:%02x:%02x\n",
-		 ack_buf.ack_pl[0], ack_buf.ack_pl[1],
-		 ack_buf.ack_pl[2], ack_buf.ack_pl[3],
-		 ack_buf.ack_pl[4], ack_buf.ack_pl[5]);
+	d_printf(2, dev, "mac addr is %pM\n", ack_buf.ack_pl);
 	if (i2400m->bus_bm_mac_addr_impaired == 1) {
 		ack_buf.ack_pl[0] = 0x00;
 		ack_buf.ack_pl[1] = 0x16;
 		ack_buf.ack_pl[2] = 0xd3;
 		get_random_bytes(&ack_buf.ack_pl[3], 3);
 		dev_err(dev, "BM is MAC addr impaired, faking MAC addr to "
-			"mac addr is %02x:%02x:%02x:%02x:%02x:%02x\n",
-			ack_buf.ack_pl[0], ack_buf.ack_pl[1],
-			ack_buf.ack_pl[2], ack_buf.ack_pl[3],
-			ack_buf.ack_pl[4], ack_buf.ack_pl[5]);
+			"mac addr is %pM\n", ack_buf.ack_pl);
 		result = 0;
 	}
 	net_dev->addr_len = ETH_ALEN;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/i2400m.h linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/i2400m.h
--- linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/i2400m.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/i2400m.h	2010-05-16 17:17:36.000000000 -0400
@@ -627,7 +627,7 @@ enum i2400m_bm_cmd_flags {
  * @I2400M_BRI_NO_REBOOT: Do not reboot the device and proceed
  *     directly to wait for a reboot barker from the device.
  * @I2400M_BRI_MAC_REINIT: We need to reinitialize the boot
- *     rom after reading the MAC adress. This is quite a dirty hack,
+ *     rom after reading the MAC address. This is quite a dirty hack,
  *     if you ask me -- the device requires the bootrom to be
  *     intialized after reading the MAC address.
  */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/netdev.c linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/netdev.c
--- linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/netdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/netdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -73,6 +73,7 @@
  *                        alloc_netdev.
  */
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
 #include "i2400m.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/op-rfkill.c linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/op-rfkill.c
--- linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/op-rfkill.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/op-rfkill.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
  */
 #include "i2400m.h"
 #include <linux/wimax/i2400m.h>
+#include <linux/slab.h>
 
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/rx.c linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/rx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -144,6 +144,7 @@
  *       i2400m_msg_size_check
  *       wimax_msg
  */
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/sdio.c linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/sdio.c
--- linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/sdio.c	2013-05-03 12:12:03.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/sdio.c	2013-05-03 09:51:36.000000000 -0400
@@ -48,6 +48,7 @@
  *     __i2400ms_send_barker()
  */
 
+#include <linux/slab.h>
 #include <linux/debugfs.h>
 #include <linux/mmc/sdio_ids.h>
 #include <linux/mmc/sdio.h>
@@ -304,7 +305,7 @@ error_kzalloc:
  *
  * The device will be fully reset internally, but won't be
  * disconnected from the bus (so no reenumeration will
- * happen). Firmware upload will be neccessary.
+ * happen). Firmware upload will be necessary.
  *
  * The device will send a reboot barker that will trigger the driver
  * to reinitialize the state via __i2400m_dev_reset_handle.
@@ -314,7 +315,7 @@ error_kzalloc:
  *
  * The device will be fully reset internally, disconnected from the
  * bus an a reenumeration will happen. Firmware upload will be
- * neccessary. Thus, we don't do any locking or struct
+ * necessary. Thus, we don't do any locking or struct
  * reinitialization, as we are going to be fully disconnected and
  * reenumerated.
  *
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/sdio-rx.c linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/sdio-rx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/sdio-rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/sdio-rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,6 +65,7 @@
 #include <linux/skbuff.h>
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/sdio_func.h>
+#include <linux/slab.h>
 #include "i2400m-sdio.h"
 
 #define D_SUBMODULE rx
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/tx.c linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/tx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -244,6 +244,7 @@
  *                               (FIFO empty).
  */
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include "i2400m.h"
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb.c linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/usb.c
--- linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb.c	2013-05-03 12:12:06.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/usb.c	2013-05-03 09:51:38.000000000 -0400
@@ -66,6 +66,7 @@
 #include "i2400m-usb.h"
 #include <linux/wimax/i2400m.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 
 #define D_SUBMODULE usb
@@ -246,7 +247,7 @@ error_kzalloc:
  *
  * The device will be fully reset internally, but won't be
  * disconnected from the USB bus (so no reenumeration will
- * happen). Firmware upload will be neccessary.
+ * happen). Firmware upload will be necessary.
  *
  * The device will send a reboot barker in the notification endpoint
  * that will trigger the driver to reinitialize the state
@@ -257,7 +258,7 @@ error_kzalloc:
  *
  * The device will be fully reset internally, disconnected from the
  * USB bus an a reenumeration will happen. Firmware upload will be
- * neccessary. Thus, we don't do any locking or struct
+ * necessary. Thus, we don't do any locking or struct
  * reinitialization, as we are going to be fully disconnected and
  * reenumerated.
  *
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb-fw.c linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/usb-fw.c
--- linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb-fw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/usb-fw.c	2010-05-16 17:17:36.000000000 -0400
@@ -73,6 +73,7 @@
  *   i2400m_notif_submit
  */
 #include <linux/usb.h>
+#include <linux/gfp.h>
 #include "i2400m-usb.h"
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb-notif.c linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/usb-notif.c
--- linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb-notif.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/usb-notif.c	2010-05-16 17:17:36.000000000 -0400
@@ -56,6 +56,7 @@
  *     i2400mu_rx_kick()
  */
 #include <linux/usb.h>
+#include <linux/slab.h>
 #include "i2400m-usb.h"
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb-rx.c linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/usb-rx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb-rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wimax/i2400m/usb-rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -83,6 +83,7 @@
  * i2400mu_rx_release()            called from i2400mu_bus_dev_stop()
  */
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include "i2400m-usb.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/adm8211.c linux-libre-2.6.34-gnu1/drivers/net/wireless/adm8211.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/adm8211.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/adm8211.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/if.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/etherdevice.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
@@ -39,7 +40,7 @@ static unsigned int rx_ring_size __read_
 module_param(tx_ring_size, uint, 0);
 module_param(rx_ring_size, uint, 0);
 
-static struct pci_device_id adm8211_pci_id_table[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(adm8211_pci_id_table) = {
 	/* ADMtek ADM8211 */
 	{ PCI_DEVICE(0x10B7, 0x6000) }, /* 3Com 3CRSHPW796 */
 	{ PCI_DEVICE(0x1200, 0x8201) }, /* ? */
@@ -302,18 +303,6 @@ static int adm8211_get_stats(struct ieee
 	return 0;
 }
 
-static int adm8211_get_tx_stats(struct ieee80211_hw *dev,
-				struct ieee80211_tx_queue_stats *stats)
-{
-	struct adm8211_priv *priv = dev->priv;
-
-	stats[0].len = priv->cur_tx - priv->dirty_tx;
-	stats[0].limit = priv->tx_ring_size - 2;
-	stats[0].count = priv->dirty_tx;
-
-	return 0;
-}
-
 static void adm8211_interrupt_tci(struct ieee80211_hw *dev)
 {
 	struct adm8211_priv *priv = dev->priv;
@@ -1400,15 +1389,15 @@ static void adm8211_configure_filter(str
 }
 
 static int adm8211_add_interface(struct ieee80211_hw *dev,
-				 struct ieee80211_if_init_conf *conf)
+				 struct ieee80211_vif *vif)
 {
 	struct adm8211_priv *priv = dev->priv;
 	if (priv->mode != NL80211_IFTYPE_MONITOR)
 		return -EOPNOTSUPP;
 
-	switch (conf->type) {
+	switch (vif->type) {
 	case NL80211_IFTYPE_STATION:
-		priv->mode = conf->type;
+		priv->mode = vif->type;
 		break;
 	default:
 		return -EOPNOTSUPP;
@@ -1416,8 +1405,8 @@ static int adm8211_add_interface(struct
 
 	ADM8211_IDLE();
 
-	ADM8211_CSR_WRITE(PAR0, le32_to_cpu(*(__le32 *)conf->mac_addr));
-	ADM8211_CSR_WRITE(PAR1, le16_to_cpu(*(__le16 *)(conf->mac_addr + 4)));
+	ADM8211_CSR_WRITE(PAR0, le32_to_cpu(*(__le32 *)vif->addr));
+	ADM8211_CSR_WRITE(PAR1, le16_to_cpu(*(__le16 *)(vif->addr + 4)));
 
 	adm8211_update_mode(dev);
 
@@ -1427,7 +1416,7 @@ static int adm8211_add_interface(struct
 }
 
 static void adm8211_remove_interface(struct ieee80211_hw *dev,
-				     struct ieee80211_if_init_conf *conf)
+				     struct ieee80211_vif *vif)
 {
 	struct adm8211_priv *priv = dev->priv;
 	priv->mode = NL80211_IFTYPE_MONITOR;
@@ -1773,7 +1762,6 @@ static const struct ieee80211_ops adm821
 	.prepare_multicast	= adm8211_prepare_multicast,
 	.configure_filter	= adm8211_configure_filter,
 	.get_stats		= adm8211_get_stats,
-	.get_tx_stats		= adm8211_get_tx_stats,
 	.get_tsf		= adm8211_get_tsft
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/airo.c linux-libre-2.6.34-gnu1/drivers/net/wireless/airo.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/airo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/airo.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,13 +51,14 @@
 #include <linux/freezer.h>
 
 #include <linux/ieee80211.h>
+#include <net/iw_handler.h>
 
 #include "airo.h"
 
 #define DRV_NAME "airo"
 
 #ifdef CONFIG_PCI
-static struct pci_device_id card_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(card_ids) = {
 	{ 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0x14b9, 0x4500, PCI_ANY_ID, PCI_ANY_ID },
 	{ 0x14b9, 0x4800, PCI_ANY_ID, PCI_ANY_ID, },
@@ -2310,7 +2311,7 @@ static void airo_set_multicast_list(stru
 			airo_set_promisc(ai);
 	}
 
-	if ((dev->flags&IFF_ALLMULTI)||dev->mc_count>0) {
+	if ((dev->flags&IFF_ALLMULTI) || !netdev_mc_empty(dev)) {
 		/* Turn on multicast.  (Should be already setup...) */
 	}
 }
@@ -5254,11 +5255,8 @@ static int set_wep_key(struct airo_info
 	WepKeyRid wkr;
 	int rc;
 
-	if (keylen == 0) {
-		airo_print_err(ai->dev->name, "%s: key length to set was zero",
-			       __func__);
+	if (WARN_ON(keylen == 0))
 		return -1;
-	}
 
 	memset(&wkr, 0, sizeof(wkr));
 	wkr.len = cpu_to_le16(sizeof(wkr));
@@ -6405,11 +6403,7 @@ static int airo_set_encode(struct net_de
 		if (dwrq->length > MIN_KEY_SIZE)
 			key.len = MAX_KEY_SIZE;
 		else
-			if (dwrq->length > 0)
-				key.len = MIN_KEY_SIZE;
-			else
-				/* Disable the key */
-				key.len = 0;
+			key.len = MIN_KEY_SIZE;
 		/* Check if the key is not marked as invalid */
 		if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
 			/* Cleanup */
@@ -6590,12 +6584,22 @@ static int airo_set_encodeext(struct net
 		default:
 			return -EINVAL;
 		}
-		/* Send the key to the card */
-		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;
+		if (key.len == 0) {
+			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;
+			}
+		} else {
+			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;
+			}
 		}
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/at76c50x-usb.c linux-libre-2.6.34-gnu1/drivers/net/wireless/at76c50x-usb.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/at76c50x-usb.c	2013-05-03 12:09:14.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/at76c50x-usb.c	2013-05-03 09:48:45.000000000 -0400
@@ -1782,7 +1782,7 @@ static void at76_mac80211_stop(struct ie
 }
 
 static int at76_add_interface(struct ieee80211_hw *hw,
-			      struct ieee80211_if_init_conf *conf)
+			      struct ieee80211_vif *vif)
 {
 	struct at76_priv *priv = hw->priv;
 	int ret = 0;
@@ -1791,7 +1791,7 @@ static int at76_add_interface(struct iee
 
 	mutex_lock(&priv->mtx);
 
-	switch (conf->type) {
+	switch (vif->type) {
 	case NL80211_IFTYPE_STATION:
 		priv->iw_mode = IW_MODE_INFRA;
 		break;
@@ -1807,7 +1807,7 @@ exit:
 }
 
 static void at76_remove_interface(struct ieee80211_hw *hw,
-				  struct ieee80211_if_init_conf *conf)
+				  struct ieee80211_vif *vif)
 {
 	at76_dbg(DBG_MAC80211, "%s()", __func__);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/ar9170.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ar9170/ar9170.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/ar9170.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ar9170/ar9170.h	2010-05-16 17:17:36.000000000 -0400
@@ -109,7 +109,6 @@ struct ar9170_rxstream_mpdu_merge {
 	bool has_plcp;
 };
 
-#define AR9170_NUM_MAX_BA_RETRY	5
 #define AR9170_NUM_TID	16
 #define WME_BA_BMP_SIZE         64
 #define AR9170_NUM_MAX_AGG_LEN	(2 * WME_BA_BMP_SIZE)
@@ -143,7 +142,12 @@ struct ar9170_sta_tid {
 	u16 tid;
 	enum ar9170_tid_state state;
 	bool active;
-	u8 retry;
+};
+
+struct ar9170_tx_queue_stats {
+	unsigned int len;
+	unsigned int limit;
+	unsigned int count;
 };
 
 #define AR9170_QUEUE_TIMEOUT		64
@@ -154,12 +158,15 @@ struct ar9170_sta_tid {
 
 #define AR9170_NUM_TX_STATUS		128
 #define AR9170_NUM_TX_AGG_MAX		30
+#define AR9170_NUM_TX_LIMIT_HARD       AR9170_TXQ_DEPTH
+#define AR9170_NUM_TX_LIMIT_SOFT       (AR9170_TXQ_DEPTH - 10)
 
 struct ar9170 {
 	struct ieee80211_hw *hw;
 	struct ath_common common;
 	struct mutex mutex;
 	enum ar9170_device_state state;
+	bool registered;
 	unsigned long bad_hw_nagger;
 
 	int (*open)(struct ar9170 *);
@@ -211,7 +218,7 @@ struct ar9170 {
 
 	/* qos queue settings */
 	spinlock_t tx_stats_lock;
-	struct ieee80211_tx_queue_stats tx_stats[5];
+	struct ar9170_tx_queue_stats tx_stats[5];
 	struct ieee80211_tx_queue_params edcf[5];
 
 	spinlock_t cmdlock;
@@ -248,13 +255,8 @@ struct ar9170_sta_info {
 	unsigned int ampdu_max_len;
 };
 
-#define AR9170_TX_FLAG_WAIT_FOR_ACK	BIT(0)
-#define AR9170_TX_FLAG_NO_ACK		BIT(1)
-#define AR9170_TX_FLAG_BLOCK_ACK	BIT(2)
-
 struct ar9170_tx_info {
 	unsigned long timeout;
-	unsigned int flags;
 };
 
 #define IS_STARTED(a)		(((struct ar9170 *)a)->state >= AR9170_STARTED)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/hw.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ar9170/hw.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ar9170/hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -276,6 +276,7 @@ struct ar9170_tx_control {
 #define AR9170_TX_MAC_RATE_PROBE		0x8000
 
 /* either-or */
+#define AR9170_TX_PHY_MOD_MASK			0x00000003
 #define AR9170_TX_PHY_MOD_CCK			0x00000000
 #define AR9170_TX_PHY_MOD_OFDM			0x00000001
 #define AR9170_TX_PHY_MOD_HT			0x00000002
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/mac.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ar9170/mac.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/mac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ar9170/mac.c	2010-05-16 17:17:36.000000000 -0400
@@ -117,7 +117,7 @@ int ar9170_set_qos(struct ar9170 *ar)
 	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);
+			ar->edcf[2].txop | ar->edcf[3].txop << 16);
 
 	ar9170_regwrite_finish();
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/main.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ar9170/main.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ar9170/main.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/etherdevice.h>
 #include <net/mac80211.h>
@@ -194,12 +195,15 @@ static inline u16 ar9170_get_seq(struct
 	return ar9170_get_seq_h((void *) txc->frame_data);
 }
 
+static inline u16 ar9170_get_tid_h(struct ieee80211_hdr *hdr)
+{
+	return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
+}
+
 static inline u16 ar9170_get_tid(struct sk_buff *skb)
 {
 	struct ar9170_tx_control *txc = (void *) skb->data;
-	struct ieee80211_hdr *hdr = (void *) txc->frame_data;
-
-	return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
+	return ar9170_get_tid_h((struct ieee80211_hdr *) txc->frame_data);
 }
 
 #define GET_NEXT_SEQ(seq)	((seq + 1) & 0x0fff)
@@ -213,10 +217,10 @@ static void ar9170_print_txheader(struct
 	struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
 	struct ieee80211_hdr *hdr = (void *) txc->frame_data;
 
-	printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x s:%d "
+	printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] s:%d "
 			  "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
 	       wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
-	       ieee80211_get_DA(hdr), arinfo->flags, ar9170_get_seq_h(hdr),
+	       ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr),
 	       le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
 	       jiffies_to_msecs(arinfo->timeout - jiffies));
 }
@@ -391,7 +395,7 @@ static void ar9170_tx_fake_ampdu_status(
 		ieee80211_tx_status_irqsafe(ar->hw, skb);
 	}
 
-	for_each_bit(i, &queue_bitmap, BITS_PER_BYTE) {
+	for_each_set_bit(i, &queue_bitmap, BITS_PER_BYTE) {
 #ifdef AR9170_QUEUE_STOP_DEBUG
 		printk(KERN_DEBUG "%s: wake queue %d\n",
 		       wiphy_name(ar->hw->wiphy), i);
@@ -430,7 +434,7 @@ void ar9170_tx_callback(struct ar9170 *a
 	spin_lock_irqsave(&ar->tx_stats_lock, flags);
 	ar->tx_stats[queue].len--;
 
-	if (skb_queue_empty(&ar->tx_pending[queue])) {
+	if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) {
 #ifdef AR9170_QUEUE_STOP_DEBUG
 		printk(KERN_DEBUG "%s: wake queue %d\n",
 		       wiphy_name(ar->hw->wiphy), queue);
@@ -440,22 +444,17 @@ void ar9170_tx_callback(struct ar9170 *a
 	}
 	spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
 
-	if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) {
-		ar9170_tx_ampdu_callback(ar, skb);
-	} else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) {
-		arinfo->timeout = jiffies +
-				  msecs_to_jiffies(AR9170_TX_TIMEOUT);
-
-		skb_queue_tail(&ar->tx_status[queue], skb);
-	} else if (arinfo->flags & AR9170_TX_FLAG_NO_ACK) {
+	if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
 		ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED);
 	} else {
-#ifdef AR9170_QUEUE_DEBUG
-		printk(KERN_DEBUG "%s: unsupported frame flags!\n",
-		       wiphy_name(ar->hw->wiphy));
-		ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
-		dev_kfree_skb_any(skb);
+		if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+			ar9170_tx_ampdu_callback(ar, skb);
+		} else {
+			arinfo->timeout = jiffies +
+				  msecs_to_jiffies(AR9170_TX_TIMEOUT);
+
+			skb_queue_tail(&ar->tx_status[queue], skb);
+		}
 	}
 
 	if (!ar->tx_stats[queue].len &&
@@ -1407,17 +1406,6 @@ static int ar9170_tx_prepare(struct ar91
 
 	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
 	     (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
-		if (info->flags & IEEE80211_TX_CTL_AMPDU) {
-			if (unlikely(!info->control.sta))
-				goto err_out;
-
-			txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
-			arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK;
-
-			goto out;
-		}
-
-		txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
 		/*
 		 * WARNING:
 		 * Putting the QoS queue bits into an unexplored territory is
@@ -1431,12 +1419,17 @@ static int ar9170_tx_prepare(struct ar91
 
 		txc->phy_control |=
 			cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
-		arinfo->flags = AR9170_TX_FLAG_WAIT_FOR_ACK;
-	} else {
-		arinfo->flags = AR9170_TX_FLAG_NO_ACK;
+
+		if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+			if (unlikely(!info->control.sta))
+				goto err_out;
+
+			txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
+		} else {
+			txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
+		}
 	}
 
-out:
 	return 0;
 
 err_out:
@@ -1671,8 +1664,7 @@ static bool ar9170_tx_ampdu(struct ar917
 		 * tell the FW/HW that this is the last frame,
 		 * that way it will wait for the immediate block ack.
 		 */
-		if (likely(skb_peek_tail(&agg)))
-			ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg));
+		ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg));
 
 #ifdef AR9170_TXAGG_DEBUG
 		printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n",
@@ -1716,6 +1708,21 @@ static void ar9170_tx(struct ar9170 *ar)
 
 	for (i = 0; i < __AR9170_NUM_TXQ; i++) {
 		spin_lock_irqsave(&ar->tx_stats_lock, flags);
+		frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
+			     skb_queue_len(&ar->tx_pending[i]));
+
+		if (remaining_space < frames) {
+#ifdef AR9170_QUEUE_DEBUG
+			printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
+			       "remaining slots:%d, needed:%d\n",
+			       wiphy_name(ar->hw->wiphy), i, remaining_space,
+			       frames);
+#endif /* AR9170_QUEUE_DEBUG */
+			frames = remaining_space;
+		}
+
+		ar->tx_stats[i].len += frames;
+		ar->tx_stats[i].count += frames;
 		if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
 #ifdef AR9170_QUEUE_DEBUG
 			printk(KERN_DEBUG "%s: queue %d full\n",
@@ -1733,25 +1740,8 @@ static void ar9170_tx(struct ar9170 *ar)
 			__ar9170_dump_txstats(ar);
 #endif /* AR9170_QUEUE_STOP_DEBUG */
 			ieee80211_stop_queue(ar->hw, i);
-			spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-			continue;
-		}
-
-		frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
-			     skb_queue_len(&ar->tx_pending[i]));
-
-		if (remaining_space < frames) {
-#ifdef AR9170_QUEUE_DEBUG
-			printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
-			       "remaining slots:%d, needed:%d\n",
-			       wiphy_name(ar->hw->wiphy), i, remaining_space,
-			       frames);
-#endif /* AR9170_QUEUE_DEBUG */
-			frames = remaining_space;
 		}
 
-		ar->tx_stats[i].len += frames;
-		ar->tx_stats[i].count += frames;
 		spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
 
 		if (!frames)
@@ -1773,7 +1763,7 @@ static void ar9170_tx(struct ar9170 *ar)
 			arinfo->timeout = jiffies +
 					  msecs_to_jiffies(AR9170_TX_TIMEOUT);
 
-			if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK)
+			if (info->flags & IEEE80211_TX_CTL_AMPDU)
 				atomic_inc(&ar->tx_ampdu_pending);
 
 #ifdef AR9170_QUEUE_DEBUG
@@ -1784,7 +1774,7 @@ static void ar9170_tx(struct ar9170 *ar)
 
 			err = ar->tx(ar, skb);
 			if (unlikely(err)) {
-				if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK)
+				if (info->flags & IEEE80211_TX_CTL_AMPDU)
 					atomic_dec(&ar->tx_ampdu_pending);
 
 				frames_failed++;
@@ -1950,7 +1940,7 @@ err_free:
 }
 
 static int ar9170_op_add_interface(struct ieee80211_hw *hw,
-				   struct ieee80211_if_init_conf *conf)
+				   struct ieee80211_vif *vif)
 {
 	struct ar9170 *ar = hw->priv;
 	struct ath_common *common = &ar->common;
@@ -1963,8 +1953,8 @@ static int ar9170_op_add_interface(struc
 		goto unlock;
 	}
 
-	ar->vif = conf->vif;
-	memcpy(common->macaddr, conf->mac_addr, ETH_ALEN);
+	ar->vif = vif;
+	memcpy(common->macaddr, vif->addr, ETH_ALEN);
 
 	if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
 		ar->rx_software_decryption = true;
@@ -1984,7 +1974,7 @@ unlock:
 }
 
 static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
-				       struct ieee80211_if_init_conf *conf)
+				       struct ieee80211_vif *vif)
 {
 	struct ar9170 *ar = hw->priv;
 
@@ -2340,55 +2330,55 @@ out:
 	return err;
 }
 
-static void ar9170_sta_notify(struct ieee80211_hw *hw,
-			      struct ieee80211_vif *vif,
-			      enum sta_notify_cmd cmd,
-			      struct ieee80211_sta *sta)
+static int ar9170_sta_add(struct ieee80211_hw *hw,
+			  struct ieee80211_vif *vif,
+			  struct ieee80211_sta *sta)
 {
 	struct ar9170 *ar = hw->priv;
 	struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
 	unsigned int i;
 
-	switch (cmd) {
-	case STA_NOTIFY_ADD:
-		memset(sta_info, 0, sizeof(*sta_info));
+	memset(sta_info, 0, sizeof(*sta_info));
 
-		if (!sta->ht_cap.ht_supported)
-			break;
+	if (!sta->ht_cap.ht_supported)
+		return 0;
 
-		if (sta->ht_cap.ampdu_density > ar->global_ampdu_density)
-			ar->global_ampdu_density = sta->ht_cap.ampdu_density;
+	if (sta->ht_cap.ampdu_density > ar->global_ampdu_density)
+		ar->global_ampdu_density = sta->ht_cap.ampdu_density;
 
-		if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor)
-			ar->global_ampdu_factor = sta->ht_cap.ampdu_factor;
+	if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor)
+		ar->global_ampdu_factor = sta->ht_cap.ampdu_factor;
 
-		for (i = 0; i < AR9170_NUM_TID; i++) {
-			sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN;
-			sta_info->agg[i].active = false;
-			sta_info->agg[i].ssn = 0;
-			sta_info->agg[i].retry = 0;
-			sta_info->agg[i].tid = i;
-			INIT_LIST_HEAD(&sta_info->agg[i].list);
-			skb_queue_head_init(&sta_info->agg[i].queue);
-		}
+	for (i = 0; i < AR9170_NUM_TID; i++) {
+		sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN;
+		sta_info->agg[i].active = false;
+		sta_info->agg[i].ssn = 0;
+		sta_info->agg[i].tid = i;
+		INIT_LIST_HEAD(&sta_info->agg[i].list);
+		skb_queue_head_init(&sta_info->agg[i].queue);
+	}
 
-		sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor);
-		break;
+	sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor);
 
-	case STA_NOTIFY_REMOVE:
-		if (!sta->ht_cap.ht_supported)
-			break;
+	return 0;
+}
 
-		for (i = 0; i < AR9170_NUM_TID; i++) {
-			sta_info->agg[i].state = AR9170_TID_STATE_INVALID;
-			skb_queue_purge(&sta_info->agg[i].queue);
-		}
+static int ar9170_sta_remove(struct ieee80211_hw *hw,
+			     struct ieee80211_vif *vif,
+			     struct ieee80211_sta *sta)
+{
+	struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
+	unsigned int i;
 
-		break;
+	if (!sta->ht_cap.ht_supported)
+		return 0;
 
-	default:
-		break;
+	for (i = 0; i < AR9170_NUM_TID; i++) {
+		sta_info->agg[i].state = AR9170_TID_STATE_INVALID;
+		skb_queue_purge(&sta_info->agg[i].queue);
 	}
+
+	return 0;
 }
 
 static int ar9170_get_stats(struct ieee80211_hw *hw,
@@ -2408,18 +2398,6 @@ static int ar9170_get_stats(struct ieee8
 	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)
 {
@@ -2519,9 +2497,9 @@ static const struct ieee80211_ops ar9170
 	.bss_info_changed	= ar9170_op_bss_info_changed,
 	.get_tsf		= ar9170_op_get_tsf,
 	.set_key		= ar9170_set_key,
-	.sta_notify		= ar9170_sta_notify,
+	.sta_add		= ar9170_sta_add,
+	.sta_remove		= ar9170_sta_remove,
 	.get_stats		= ar9170_get_stats,
-	.get_tx_stats		= ar9170_get_tx_stats,
 	.ampdu_action		= ar9170_ampdu_action,
 };
 
@@ -2535,7 +2513,7 @@ void *ar9170_alloc(size_t priv_size)
 	/*
 	 * this buffer is used for rx stream reconstruction.
 	 * Under heavy load this device (or the transport layer?)
-	 * tends to split the streams into seperate rx descriptors.
+	 * tends to split the streams into separate rx descriptors.
 	 */
 
 	skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL);
@@ -2724,7 +2702,8 @@ int ar9170_register(struct ar9170 *ar, s
 	dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
 		 wiphy_name(ar->hw->wiphy));
 
-	return err;
+	ar->registered = true;
+	return 0;
 
 err_unreg:
 	ieee80211_unregister_hw(ar->hw);
@@ -2735,11 +2714,14 @@ err_out:
 
 void ar9170_unregister(struct ar9170 *ar)
 {
+	if (ar->registered) {
 #ifdef CONFIG_AR9170_LEDS
-	ar9170_unregister_leds(ar);
+		ar9170_unregister_leds(ar);
 #endif /* CONFIG_AR9170_LEDS */
 
-	kfree_skb(ar->rx_failover);
 	ieee80211_unregister_hw(ar->hw);
+	}
+
+	kfree_skb(ar->rx_failover);
 	mutex_destroy(&ar->mutex);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/usb.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ar9170/usb.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ar9170/usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
@@ -84,6 +85,8 @@ static struct usb_device_id ar9170_usb_i
 	{ USB_DEVICE(0x0cde, 0x0023) },
 	/* Z-Com UB82 ABG */
 	{ USB_DEVICE(0x0cde, 0x0026) },
+	/* Sphairon Homelink 1202 */
+	{ USB_DEVICE(0x0cde, 0x0027) },
 	/* Arcadyan WN7512 */
 	{ USB_DEVICE(0x083a, 0xf522) },
 	/* Planex GWUS300 */
@@ -92,6 +95,8 @@ static struct usb_device_id ar9170_usb_i
 	{ USB_DEVICE(0x04bb, 0x093f) },
 	/* AVM FRITZ!WLAN USB Stick N */
 	{ USB_DEVICE(0x057C, 0x8401) },
+	/* NEC WL300NU-G */
+	{ USB_DEVICE(0x0409, 0x0249) },
 	/* AVM FRITZ!WLAN USB Stick N 2.4 */
 	{ USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
 
@@ -414,7 +419,7 @@ static int ar9170_usb_exec_cmd(struct ar
 	spin_unlock_irqrestore(&aru->common.cmdlock, flags);
 
 	usb_fill_int_urb(urb, aru->udev,
-			 usb_sndbulkpipe(aru->udev, AR9170_EP_CMD),
+			 usb_sndintpipe(aru->udev, AR9170_EP_CMD),
 			 aru->common.cmdbuf, plen + 4,
 			 ar9170_usb_tx_urb_complete, NULL, 1);
 
@@ -580,43 +585,6 @@ static int ar9170_usb_upload(struct ar91
 	return 0;
 }
 
-static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
-{
-	int err = 0;
-
-	err = request_firmware(&aru->firmware, "ar9170.fw",
-			       &aru->udev->dev);
-	if (!err) {
-		aru->init_values = NULL;
-		return 0;
-	}
-
-	if (aru->req_one_stage_fw) {
-		dev_err(&aru->udev->dev, "ar9170.fw firmware file "
-			"not found and is required for this device\n");
-		return -EINVAL;
-	}
-
-	dev_err(&aru->udev->dev, "ar9170.fw firmware file "
-		"not found, trying old firmware...\n");
-
-	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);
@@ -755,6 +723,109 @@ err_out:
 	return err;
 }
 
+static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
+{
+	struct device *parent = aru->udev->dev.parent;
+
+	complete(&aru->firmware_loading_complete);
+
+	/* unbind anything failed */
+	if (parent)
+		down(&parent->sem);
+	device_release_driver(&aru->udev->dev);
+	if (parent)
+		up(&parent->sem);
+
+	usb_put_dev(aru->udev);
+}
+
+static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
+{
+	struct ar9170_usb *aru = context;
+	int err;
+
+	aru->firmware = fw;
+
+	if (!fw) {
+		dev_err(&aru->udev->dev, "firmware file not found.\n");
+		goto err_freefw;
+	}
+
+	err = ar9170_usb_init_device(aru);
+	if (err)
+		goto err_freefw;
+
+	err = ar9170_usb_open(&aru->common);
+	if (err)
+		goto err_unrx;
+
+	err = ar9170_register(&aru->common, &aru->udev->dev);
+
+	ar9170_usb_stop(&aru->common);
+	if (err)
+		goto err_unrx;
+
+	complete(&aru->firmware_loading_complete);
+	usb_put_dev(aru->udev);
+	return;
+
+ err_unrx:
+	ar9170_usb_cancel_urbs(aru);
+
+ err_freefw:
+	ar9170_usb_firmware_failed(aru);
+}
+
+static void ar9170_usb_firmware_inits(const struct firmware *fw,
+				      void *context)
+{
+	struct ar9170_usb *aru = context;
+	int err;
+
+	if (!fw) {
+		dev_err(&aru->udev->dev, "file with init values not found.\n");
+		ar9170_usb_firmware_failed(aru);
+		return;
+	}
+
+	aru->init_values = fw;
+
+	/* ok so we have the init values -- get code for two-stage */
+
+	err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-2.fw",
+				      &aru->udev->dev, GFP_KERNEL, aru,
+				      ar9170_usb_firmware_finish);
+	if (err)
+		ar9170_usb_firmware_failed(aru);
+}
+
+static void ar9170_usb_firmware_step2(const struct firmware *fw, void *context)
+{
+	struct ar9170_usb *aru = context;
+	int err;
+
+	if (fw) {
+		ar9170_usb_firmware_finish(fw, context);
+		return;
+	}
+
+	if (aru->req_one_stage_fw) {
+		dev_err(&aru->udev->dev, "ar9170.fw firmware file "
+			"not found and is required for this device\n");
+		ar9170_usb_firmware_failed(aru);
+		return;
+	}
+
+	dev_err(&aru->udev->dev, "ar9170.fw firmware file "
+		"not found, trying old firmware...\n");
+
+	err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-1.fw",
+				      &aru->udev->dev, GFP_KERNEL, aru,
+				      ar9170_usb_firmware_inits);
+	if (err)
+		ar9170_usb_firmware_failed(aru);
+}
+
 static bool ar9170_requires_one_stage(const struct usb_device_id *id)
 {
 	if (!id->driver_info)
@@ -793,6 +864,7 @@ static int ar9170_usb_probe(struct usb_i
 	init_usb_anchor(&aru->tx_pending);
 	init_usb_anchor(&aru->tx_submitted);
 	init_completion(&aru->cmd_wait);
+	init_completion(&aru->firmware_loading_complete);
 	spin_lock_init(&aru->tx_urb_lock);
 
 	aru->tx_pending_urbs = 0;
@@ -812,33 +884,10 @@ static int ar9170_usb_probe(struct usb_i
 	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);
-
+	usb_get_dev(aru->udev);
+	return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw",
+				       &aru->udev->dev, GFP_KERNEL, aru,
+				       ar9170_usb_firmware_step2);
 err_freehw:
 	usb_set_intfdata(intf, NULL);
 	usb_put_dev(udev);
@@ -855,15 +904,18 @@ static void ar9170_usb_disconnect(struct
 		return;
 
 	aru->common.state = AR9170_IDLE;
+
+	wait_for_completion(&aru->firmware_loading_complete);
+
 	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);
+
+	release_firmware(aru->init_values);
+	release_firmware(aru->firmware);
 }
 
 #ifdef CONFIG_PM
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/usb.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ar9170/usb.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/usb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ar9170/usb.h	2010-05-16 17:17:36.000000000 -0400
@@ -71,6 +71,7 @@ struct ar9170_usb {
 	unsigned int tx_pending_urbs;
 
 	struct completion cmd_wait;
+	struct completion firmware_loading_complete;
 	int readlen;
 	u8 *readbuf;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/ath5k.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/ath5k.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/ath5k.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/ath5k.h	2010-05-16 17:17:36.000000000 -0400
@@ -535,13 +535,12 @@ struct ath5k_txq_info {
 	u32	tqi_cbr_period; /* Constant bit rate period */
 	u32	tqi_cbr_overflow_limit;
 	u32	tqi_burst_time;
-	u32	tqi_ready_time; /* Not used */
+	u32	tqi_ready_time; /* Time queue waits after an event */
 };
 
 /*
  * Transmit packet types.
  * used on tx control descriptor
- * TODO: Use them inside base.c corectly
  */
 enum ath5k_pkt_type {
 	AR5K_PKT_TYPE_NORMAL		= 0,
@@ -1063,6 +1062,7 @@ struct ath5k_hw {
 	u32			ah_cw_min;
 	u32			ah_cw_max;
 	u32			ah_limit_tx_retries;
+	u8			ah_coverage_class;
 
 	/* Antenna Control */
 	u32			ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
@@ -1200,6 +1200,7 @@ extern bool ath5k_eeprom_is_hb63(struct
 
 /* Protocol Control Unit Functions */
 extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
+extern void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
 /* BSSID Functions */
 extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
 extern void ath5k_hw_set_associd(struct ath5k_hw *ah);
@@ -1231,6 +1232,10 @@ extern int ath5k_hw_set_ack_timeout(stru
 extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah);
 extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout);
 extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah);
+/* Clock rate related functions */
+unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
+unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
+unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah);
 /* Key table (WEP) functions */
 extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
 extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry);
@@ -1310,24 +1315,6 @@ extern int ath5k_hw_set_txpower_limit(st
  * Functions used internaly
  */
 
-/*
- * Translate usec to hw clock units
- * TODO: Half/quarter rate
- */
-static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
-{
-	return turbo ? (usec * 80) : (usec * 40);
-}
-
-/*
- * Translate hw clock units to usec
- * TODO: Half/quarter rate
- */
-static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
-{
-	return turbo ? (clock / 80) : (clock / 40);
-}
-
 static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah)
 {
         return &ah->common;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/attach.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/attach.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/attach.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/attach.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 \*************************************/
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include "ath5k.h"
 #include "reg.h"
 #include "debug.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/base.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/base.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/base.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/base.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,6 +50,7 @@
 #include <linux/pci.h>
 #include <linux/ethtool.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 
 #include <net/ieee80211_radiotap.h>
 
@@ -83,7 +84,7 @@ MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
 
 
 /* Known PCI ids */
-static const struct pci_device_id ath5k_pci_id_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = {
 	{ PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */
 	{ PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */
 	{ PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/
@@ -225,9 +226,9 @@ static int ath5k_reset_wake(struct ath5k
 static int ath5k_start(struct ieee80211_hw *hw);
 static void ath5k_stop(struct ieee80211_hw *hw);
 static int ath5k_add_interface(struct ieee80211_hw *hw,
-		struct ieee80211_if_init_conf *conf);
+		struct ieee80211_vif *vif);
 static void ath5k_remove_interface(struct ieee80211_hw *hw,
-		struct ieee80211_if_init_conf *conf);
+		struct ieee80211_vif *vif);
 static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
 static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
 				   int mc_count, struct dev_addr_list *mc_list);
@@ -241,8 +242,6 @@ static int ath5k_set_key(struct ieee8021
 		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);
@@ -254,6 +253,8 @@ static void ath5k_bss_info_changed(struc
 		u32 changes);
 static void ath5k_sw_scan_start(struct ieee80211_hw *hw);
 static void ath5k_sw_scan_complete(struct ieee80211_hw *hw);
+static void ath5k_set_coverage_class(struct ieee80211_hw *hw,
+		u8 coverage_class);
 
 static const struct ieee80211_ops ath5k_hw_ops = {
 	.tx 		= ath5k_tx,
@@ -267,13 +268,13 @@ static const struct ieee80211_ops ath5k_
 	.set_key 	= ath5k_set_key,
 	.get_stats 	= ath5k_get_stats,
 	.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,
 	.sw_scan_start	= ath5k_sw_scan_start,
 	.sw_scan_complete = ath5k_sw_scan_complete,
+	.set_coverage_class = ath5k_set_coverage_class,
 };
 
 /*
@@ -1246,6 +1247,29 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc
 	return 0;
 }
 
+static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr;
+	enum ath5k_pkt_type htype;
+	__le16 fc;
+
+	hdr = (struct ieee80211_hdr *)skb->data;
+	fc = hdr->frame_control;
+
+	if (ieee80211_is_beacon(fc))
+		htype = AR5K_PKT_TYPE_BEACON;
+	else if (ieee80211_is_probe_resp(fc))
+		htype = AR5K_PKT_TYPE_PROBE_RESP;
+	else if (ieee80211_is_atim(fc))
+		htype = AR5K_PKT_TYPE_ATIM;
+	else if (ieee80211_is_pspoll(fc))
+		htype = AR5K_PKT_TYPE_PSPOLL;
+	else
+		htype = AR5K_PKT_TYPE_NORMAL;
+
+	return htype;
+}
+
 static int
 ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
 		  struct ath5k_txq *txq)
@@ -1300,7 +1324,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc
 			sc->vif, pktlen, info));
 	}
 	ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
-		ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
+		ieee80211_get_hdrlen_from_skb(skb),
+		get_hw_packet_type(skb),
 		(sc->power_level * 2),
 		hw_rate,
 		info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
@@ -1329,7 +1354,6 @@ ath5k_txbuf_setup(struct ath5k_softc *sc
 
 	spin_lock_bh(&txq->lock);
 	list_add_tail(&bf->list, &txq->q);
-	sc->tx_stats[txq->qnum].len++;
 	if (txq->link == NULL) /* is this first packet? */
 		ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr);
 	else /* no, so only link it */
@@ -1513,7 +1537,8 @@ ath5k_beaconq_config(struct ath5k_softc
 
 	ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi);
 	if (ret)
-		return ret;
+		goto err;
+
 	if (sc->opmode == NL80211_IFTYPE_AP ||
 		sc->opmode == NL80211_IFTYPE_MESH_POINT) {
 		/*
@@ -1540,10 +1565,25 @@ ath5k_beaconq_config(struct ath5k_softc
 	if (ret) {
 		ATH5K_ERR(sc, "%s: unable to update parameters for beacon "
 			"hardware queue!\n", __func__);
-		return ret;
+		goto err;
 	}
+	ret = ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */
+	if (ret)
+		goto err;
 
-	return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */;
+	/* reconfigure cabq with ready time to 80% of beacon_interval */
+	ret = ath5k_hw_get_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi);
+	if (ret)
+		goto err;
+
+	qi.tqi_ready_time = (sc->bintval * 80) / 100;
+	ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi);
+	if (ret)
+		goto err;
+
+	ret = ath5k_hw_reset_tx_queue(ah, AR5K_TX_QUEUE_ID_CAB);
+err:
+	return ret;
 }
 
 static void
@@ -1562,7 +1602,6 @@ ath5k_txq_drainq(struct ath5k_softc *sc,
 		ath5k_txbuf_free(sc, bf);
 
 		spin_lock_bh(&sc->txbuflock);
-		sc->tx_stats[txq->qnum].len--;
 		list_move_tail(&bf->list, &sc->txbuf);
 		sc->txbuf_len++;
 		spin_unlock_bh(&sc->txbuflock);
@@ -1992,10 +2031,8 @@ ath5k_tx_processq(struct ath5k_softc *sc
 		}
 
 		ieee80211_tx_status(sc->hw, skb);
-		sc->tx_stats[txq->qnum].count++;
 
 		spin_lock(&sc->txbuflock);
-		sc->tx_stats[txq->qnum].len--;
 		list_move_tail(&bf->list, &sc->txbuf);
 		sc->txbuf_len++;
 		spin_unlock(&sc->txbuflock);
@@ -2773,7 +2810,7 @@ static void ath5k_stop(struct ieee80211_
 }
 
 static int ath5k_add_interface(struct ieee80211_hw *hw,
-		struct ieee80211_if_init_conf *conf)
+		struct ieee80211_vif *vif)
 {
 	struct ath5k_softc *sc = hw->priv;
 	int ret;
@@ -2784,22 +2821,22 @@ static int ath5k_add_interface(struct ie
 		goto end;
 	}
 
-	sc->vif = conf->vif;
+	sc->vif = vif;
 
-	switch (conf->type) {
+	switch (vif->type) {
 	case NL80211_IFTYPE_AP:
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_ADHOC:
 	case NL80211_IFTYPE_MESH_POINT:
 	case NL80211_IFTYPE_MONITOR:
-		sc->opmode = conf->type;
+		sc->opmode = vif->type;
 		break;
 	default:
 		ret = -EOPNOTSUPP;
 		goto end;
 	}
 
-	ath5k_hw_set_lladdr(sc->ah, conf->mac_addr);
+	ath5k_hw_set_lladdr(sc->ah, vif->addr);
 	ath5k_mode_setup(sc);
 
 	ret = 0;
@@ -2810,13 +2847,13 @@ end:
 
 static void
 ath5k_remove_interface(struct ieee80211_hw *hw,
-			struct ieee80211_if_init_conf *conf)
+			struct ieee80211_vif *vif)
 {
 	struct ath5k_softc *sc = hw->priv;
 	u8 mac[ETH_ALEN] = {};
 
 	mutex_lock(&sc->lock);
-	if (sc->vif != conf->vif)
+	if (sc->vif != vif)
 		goto end;
 
 	ath5k_hw_set_lladdr(sc->ah, mac);
@@ -3097,17 +3134,6 @@ ath5k_get_stats(struct ieee80211_hw *hw,
 	return 0;
 }
 
-static int
-ath5k_get_tx_stats(struct ieee80211_hw *hw,
-		struct ieee80211_tx_queue_stats *stats)
-{
-	struct ath5k_softc *sc = hw->priv;
-
-	memcpy(stats, &sc->tx_stats, sizeof(sc->tx_stats));
-
-	return 0;
-}
-
 static u64
 ath5k_get_tsf(struct ieee80211_hw *hw)
 {
@@ -3262,3 +3288,22 @@ static void ath5k_sw_scan_complete(struc
 	ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
 		AR5K_LED_ASSOC : AR5K_LED_INIT);
 }
+
+/**
+ * ath5k_set_coverage_class - Set IEEE 802.11 coverage class
+ *
+ * @hw: struct ieee80211_hw pointer
+ * @coverage_class: IEEE 802.11 coverage class number
+ *
+ * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given
+ * coverage class. The values are persistent, they are restored after device
+ * reset.
+ */
+static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
+{
+	struct ath5k_softc *sc = hw->priv;
+
+	mutex_lock(&sc->lock);
+	ath5k_hw_set_coverage_class(sc->ah, coverage_class);
+	mutex_unlock(&sc->lock);
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/base.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/base.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/base.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/base.h	2010-05-16 17:17:36.000000000 -0400
@@ -117,7 +117,6 @@ struct ath5k_softc {
 	struct pci_dev		*pdev;		/* for dma mapping */
 	void __iomem		*iobase;	/* address of the device */
 	struct mutex		lock;		/* dev-level lock */
-	struct ieee80211_tx_queue_stats tx_stats[AR5K_NUM_TX_QUEUES];
 	struct ieee80211_low_level_stats ll_stats;
 	struct ieee80211_hw	*hw;		/* IEEE 802.11 common */
 	struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/eeprom.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/eeprom.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/eeprom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/eeprom.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,8 @@
 * EEPROM access functions and helpers *
 \*************************************/
 
+#include <linux/slab.h>
+
 #include "ath5k.h"
 #include "reg.h"
 #include "debug.h"
@@ -429,8 +431,8 @@ static int ath5k_eeprom_read_modes(struc
 			ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
 
 		AR5K_EEPROM_READ(o++, val);
-		ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
-		ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
+		ee->ee_i_cal[mode] = (val >> 5) & 0x3f;
+		ee->ee_q_cal[mode] = val & 0x1f;
 
 		if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
 			AR5K_EEPROM_READ(o++, val);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/led.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/led.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/led.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/led.c	2010-05-16 17:17:36.000000000 -0400
@@ -77,6 +77,8 @@ static const struct pci_device_id ath5k_
 	{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) },
 	/* HP Compaq C700 (nitrousnrg@gmail.com) */
 	{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) },
+	/* LiteOn AR5BXB63 (magooz@salug.it) */
+	{ ATH_SDEVICE(PCI_VENDOR_ID_ATHEROS, 0x3067), ATH_LED(3, 0) },
 	/* IBM-specific AR5212 (all others) */
 	{ PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
 	/* Dell Vostro A860 (shahar@shahar-or.co.il) */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/pcu.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/pcu.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/pcu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/pcu.c	2010-05-16 17:17:36.000000000 -0400
@@ -187,8 +187,8 @@ unsigned int ath5k_hw_get_ack_timeout(st
 {
 	ATH5K_TRACE(ah->ah_sc);
 
-	return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
-			AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo);
+	return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah,
+			AR5K_TIME_OUT), AR5K_TIME_OUT_ACK));
 }
 
 /**
@@ -200,12 +200,12 @@ unsigned int ath5k_hw_get_ack_timeout(st
 int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
 {
 	ATH5K_TRACE(ah->ah_sc);
-	if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK),
-			ah->ah_turbo) <= timeout)
+	if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK))
+			<= timeout)
 		return -EINVAL;
 
 	AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
-		ath5k_hw_htoclock(timeout, ah->ah_turbo));
+		ath5k_hw_htoclock(ah, timeout));
 
 	return 0;
 }
@@ -218,8 +218,8 @@ int ath5k_hw_set_ack_timeout(struct ath5
 unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
 {
 	ATH5K_TRACE(ah->ah_sc);
-	return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
-			AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo);
+	return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah,
+			AR5K_TIME_OUT), AR5K_TIME_OUT_CTS));
 }
 
 /**
@@ -231,17 +231,97 @@ unsigned int ath5k_hw_get_cts_timeout(st
 int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
 {
 	ATH5K_TRACE(ah->ah_sc);
-	if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS),
-			ah->ah_turbo) <= timeout)
+	if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS))
+			<= timeout)
 		return -EINVAL;
 
 	AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
-			ath5k_hw_htoclock(timeout, ah->ah_turbo));
+			ath5k_hw_htoclock(ah, timeout));
 
 	return 0;
 }
 
 /**
+ * ath5k_hw_htoclock - Translate usec to hw clock units
+ *
+ * @ah: The &struct ath5k_hw
+ * @usec: value in microseconds
+ */
+unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
+{
+	return usec * ath5k_hw_get_clockrate(ah);
+}
+
+/**
+ * ath5k_hw_clocktoh - Translate hw clock units to usec
+ * @clock: value in hw clock units
+ */
+unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
+{
+	return clock / ath5k_hw_get_clockrate(ah);
+}
+
+/**
+ * ath5k_hw_get_clockrate - Get the clock rate for current mode
+ *
+ * @ah: The &struct ath5k_hw
+ */
+unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
+{
+	struct ieee80211_channel *channel = ah->ah_current_channel;
+	int clock;
+
+	if (channel->hw_value & CHANNEL_5GHZ)
+		clock = 40; /* 802.11a */
+	else if (channel->hw_value & CHANNEL_CCK)
+		clock = 22; /* 802.11b */
+	else
+		clock = 44; /* 802.11g */
+
+	/* Clock rate in turbo modes is twice the normal rate */
+	if (channel->hw_value & CHANNEL_TURBO)
+		clock *= 2;
+
+	return clock;
+}
+
+/**
+ * ath5k_hw_get_default_slottime - Get the default slot time for current mode
+ *
+ * @ah: The &struct ath5k_hw
+ */
+unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
+{
+	struct ieee80211_channel *channel = ah->ah_current_channel;
+
+	if (channel->hw_value & CHANNEL_TURBO)
+		return 6; /* both turbo modes */
+
+	if (channel->hw_value & CHANNEL_CCK)
+		return 20; /* 802.11b */
+
+	return 9; /* 802.11 a/g */
+}
+
+/**
+ * ath5k_hw_get_default_sifs - Get the default SIFS for current mode
+ *
+ * @ah: The &struct ath5k_hw
+ */
+unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
+{
+	struct ieee80211_channel *channel = ah->ah_current_channel;
+
+	if (channel->hw_value & CHANNEL_TURBO)
+		return 8; /* both turbo modes */
+
+	if (channel->hw_value & CHANNEL_5GHZ)
+		return 16; /* 802.11a */
+
+	return 10; /* 802.11 b/g */
+}
+
+/**
  * ath5k_hw_set_lladdr - Set station id
  *
  * @ah: The &struct ath5k_hw
@@ -1050,3 +1130,24 @@ int ath5k_hw_set_key_lladdr(struct ath5k
 	return 0;
 }
 
+/**
+ * ath5k_hw_set_coverage_class - Set IEEE 802.11 coverage class
+ *
+ * @ah: The &struct ath5k_hw
+ * @coverage_class: IEEE 802.11 coverage class number
+ *
+ * Sets slot time, ACK timeout and CTS timeout for given coverage class.
+ */
+void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
+{
+	/* As defined by IEEE 802.11-2007 17.3.8.6 */
+	int slot_time = ath5k_hw_get_default_slottime(ah) + 3 * coverage_class;
+	int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time;
+	int cts_timeout = ack_timeout;
+
+	ath5k_hw_set_slot_time(ah, slot_time);
+	ath5k_hw_set_ack_timeout(ah, ack_timeout);
+	ath5k_hw_set_cts_timeout(ah, cts_timeout);
+
+	ah->ah_coverage_class = coverage_class;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/phy.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/phy.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/phy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/phy.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #define _ATH5K_PHY
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "ath5k.h"
 #include "reg.h"
@@ -1386,38 +1387,39 @@ static int ath5k_hw_rf511x_calibrate(str
 		goto done;
 
 	/* Calibration has finished, get the results and re-run */
+
+	/* work around empty results which can apparently happen on 5212 */
 	for (i = 0; i <= 10; i++) {
 		iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
 		i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
 		q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
+		ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+			"iq_corr:%x i_pwr:%x q_pwr:%x", iq_corr, i_pwr, q_pwr);
+		if (i_pwr && q_pwr)
+			break;
 	}
 
 	i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
 	q_coffd = q_pwr >> 7;
 
-	/* No correction */
-	if (i_coffd == 0 || q_coffd == 0)
+	/* protect against divide by 0 and loss of sign bits */
+	if (i_coffd == 0 || q_coffd < 2)
 		goto done;
 
-	i_coff = ((-iq_corr) / i_coffd);
-
-	/* Boundary check */
-	if (i_coff > 31)
-		i_coff = 31;
-	if (i_coff < -32)
-		i_coff = -32;
+	i_coff = (-iq_corr) / i_coffd;
+	i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */
 
-	q_coff = (((s32)i_pwr / q_coffd) - 128);
+	q_coff = (i_pwr / q_coffd) - 128;
+	q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */
 
-	/* Boundary check */
-	if (q_coff > 15)
-		q_coff = 15;
-	if (q_coff < -16)
-		q_coff = -16;
+	ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+			"new I:%d Q:%d (i_coffd:%x q_coffd:%x)",
+			i_coff, q_coff, i_coffd, q_coffd);
 
-	/* Commit new I/Q value */
-	AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE |
-		((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S));
+	/* Commit new I/Q values (set enable bit last to match HAL sources) */
+	AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, i_coff);
+	AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, q_coff);
+	AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
 
 	/* Re-enable calibration -if we don't we'll commit
 	 * the same values again and again */
@@ -1873,7 +1875,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_h
 		break;
 	case AR5K_ANTMODE_FIXED_A:
 		def_ant = 1;
-		tx_ant = 0;
+		tx_ant = 1;
 		use_def_for_tx = true;
 		update_def_on_tx = false;
 		use_def_for_rts = true;
@@ -1882,7 +1884,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_h
 		break;
 	case AR5K_ANTMODE_FIXED_B:
 		def_ant = 2;
-		tx_ant = 0;
+		tx_ant = 2;
 		use_def_for_tx = true;
 		update_def_on_tx = false;
 		use_def_for_rts = true;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/qcu.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/qcu.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/qcu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/qcu.c	2010-05-16 17:17:36.000000000 -0400
@@ -408,12 +408,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k
 			break;
 
 		case AR5K_TX_QUEUE_CAB:
+			/* XXX: use BCN_SENT_GT, if we can figure out how */
 			AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
-				AR5K_QCU_MISC_FRSHED_BCN_SENT_GT |
+				AR5K_QCU_MISC_FRSHED_DBA_GT |
 				AR5K_QCU_MISC_CBREXP_DIS |
 				AR5K_QCU_MISC_CBREXP_BCN_DIS);
 
-			ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
+			ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
 				(AR5K_TUNE_SW_BEACON_RESP -
 				AR5K_TUNE_DMA_BEACON_RESP) -
 				AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
@@ -520,12 +521,16 @@ int ath5k_hw_reset_tx_queue(struct ath5k
  */
 unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
 {
+	unsigned int slot_time_clock;
+
 	ATH5K_TRACE(ah->ah_sc);
+
 	if (ah->ah_version == AR5K_AR5210)
-		return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah,
-				AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
+		slot_time_clock = ath5k_hw_reg_read(ah, AR5K_SLOT_TIME);
 	else
-		return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff;
+		slot_time_clock = ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT);
+
+	return ath5k_hw_clocktoh(ah, slot_time_clock & 0xffff);
 }
 
 /*
@@ -533,15 +538,17 @@ unsigned int ath5k_hw_get_slot_time(stru
  */
 int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
 {
+	u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
+
 	ATH5K_TRACE(ah->ah_sc);
-	if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX)
+
+	if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)
 		return -EINVAL;
 
 	if (ah->ah_version == AR5K_AR5210)
-		ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time,
-				ah->ah_turbo), AR5K_SLOT_TIME);
+		ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);
 	else
-		ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT);
+		ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/reg.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/reg.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/reg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/reg.h	2010-05-16 17:17:36.000000000 -0400
@@ -2187,6 +2187,7 @@
  */
 #define	AR5K_PHY_IQ			0x9920			/* Register Address */
 #define	AR5K_PHY_IQ_CORR_Q_Q_COFF	0x0000001f	/* Mask for q correction info */
+#define	AR5K_PHY_IQ_CORR_Q_Q_COFF_S	0
 #define	AR5K_PHY_IQ_CORR_Q_I_COFF	0x000007e0	/* Mask for i correction info */
 #define	AR5K_PHY_IQ_CORR_Q_I_COFF_S	5
 #define	AR5K_PHY_IQ_CORR_ENABLE		0x00000800	/* Enable i/q correction */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/reset.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/reset.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/reset.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath5k/reset.c	2010-05-16 17:17:36.000000000 -0400
@@ -60,12 +60,11 @@ static inline int ath5k_hw_write_ofdm_ti
 		!(channel->hw_value & CHANNEL_OFDM));
 
 	/* Get coefficient
-	 * ALGO: coef = (5 * clock * carrier_freq) / 2)
+	 * 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);
-
+	clock =  (channel->hw_value & CHANNEL_TURBO) ? 80 : 40;
 	coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
 
 	/* Get exponent
@@ -852,12 +851,15 @@ static void ath5k_hw_commit_eeprom_setti
 				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]);
+	/* I/Q correction (set enable bit last to match HAL sources) */
+	/* TODO: Per channel i/q infos ? */
+	if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
+		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF,
+			    ee->ee_i_cal[ee_mode]);
+		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF,
+			    ee->ee_q_cal[ee_mode]);
+		AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
+	}
 
 	/* Heavy clipping -disable for now */
 	if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
@@ -1317,6 +1319,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 	/* Restore antenna mode */
 	ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
 
+	/* Restore slot time and ACK timeouts */
+	if (ah->ah_coverage_class > 0)
+		ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);
+
 	/*
 	 * Configure QCUs/DCUs
 	 */
@@ -1371,15 +1377,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 	 * 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);
+	if (ah->ah_version == AR5K_AR5212 &&
+	    ah->ah_op_mode != NL80211_IFTYPE_AP)
+		ath5k_hw_set_sleep_clock(ah, true);
 
 	/*
-	 * Disable beacons and reset the register
+	 * Disable beacons and reset the TSF
 	 */
-	AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
-			AR5K_BEACON_RESET_TSF);
-
+	AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
+	ath5k_hw_reset_tsf(ah);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/ahb.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/ahb.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/ahb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/ahb.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,12 +27,6 @@ static void ath_ahb_read_cachesize(struc
 	*csz = L1_CACHE_BYTES >> 2;
 }
 
-static void ath_ahb_cleanup(struct ath_common *common)
-{
-	struct ath_softc *sc = (struct ath_softc *)common->priv;
-	iounmap(sc->mem);
-}
-
 static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
 {
 	struct ath_softc *sc = (struct ath_softc *)common->priv;
@@ -54,8 +48,6 @@ static bool ath_ahb_eeprom_read(struct a
 
 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,
 };
 
@@ -121,16 +113,19 @@ static int ath_ahb_probe(struct platform
 	sc->mem = mem;
 	sc->irq = irq;
 
-	ret = ath_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops);
+	/* Will be cleared in ath9k_start() */
+	sc->sc_flags |= SC_OP_INVALID;
+
+	ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
 	if (ret) {
-		dev_err(&pdev->dev, "failed to initialize device\n");
+		dev_err(&pdev->dev, "request_irq failed\n");
 		goto err_free_hw;
 	}
 
-	ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
+	ret = ath9k_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops);
 	if (ret) {
-		dev_err(&pdev->dev, "request_irq failed\n");
-		goto err_detach;
+		dev_err(&pdev->dev, "failed to initialize device\n");
+		goto err_irq;
 	}
 
 	ah = sc->sc_ah;
@@ -143,8 +138,8 @@ static int ath_ahb_probe(struct platform
 
 	return 0;
 
- err_detach:
-	ath_detach(sc);
+ err_irq:
+	free_irq(irq, sc);
  err_free_hw:
 	ieee80211_free_hw(hw);
 	platform_set_drvdata(pdev, NULL);
@@ -161,8 +156,12 @@ static int ath_ahb_remove(struct platfor
 	if (hw) {
 		struct ath_wiphy *aphy = hw->priv;
 		struct ath_softc *sc = aphy->sc;
+		void __iomem *mem = sc->mem;
 
-		ath_cleanup(sc);
+		ath9k_deinit_device(sc);
+		free_irq(sc->irq, sc);
+		ieee80211_free_hw(sc->hw);
+		iounmap(mem);
 		platform_set_drvdata(pdev, NULL);
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/ath9k.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/ath9k.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/ath9k.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/ath9k.h	2010-05-16 17:17:36.000000000 -0400
@@ -267,6 +267,7 @@ void ath_tx_aggr_start(struct ath_softc
 		       u16 tid, u16 *ssn);
 void 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);
+void ath9k_enable_ps(struct ath_softc *sc);
 
 /********/
 /* VIFs */
@@ -341,6 +342,12 @@ int ath_beaconq_config(struct ath_softc
 #define ATH_LONG_CALINTERVAL      30000   /* 30 seconds */
 #define ATH_RESTART_CALINTERVAL   1200000 /* 20 minutes */
 
+void ath_ani_calibrate(unsigned long data);
+
+/**********/
+/* BTCOEX */
+/**********/
+
 /* Defines the BT AR_BT_COEX_WGHT used */
 enum ath_stomp_type {
 	ATH_BTCOEX_NO_STOMP,
@@ -358,9 +365,14 @@ struct ath_btcoex {
 	int bt_stomp_type; /* Types of BT stomping */
 	u32 btcoex_no_stomp; /* in usec */
 	u32 btcoex_period; /* in usec */
+	u32 btscan_no_stomp; /* in usec */
 	struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */
 };
 
+int ath_init_btcoex_timer(struct ath_softc *sc);
+void ath9k_btcoex_timer_resume(struct ath_softc *sc);
+void ath9k_btcoex_timer_pause(struct ath_softc *sc);
+
 /********************/
 /*   LED Control    */
 /********************/
@@ -385,6 +397,9 @@ struct ath_led {
 	bool registered;
 };
 
+void ath_init_leds(struct ath_softc *sc);
+void ath_deinit_leds(struct ath_softc *sc);
+
 /********************/
 /* Main driver core */
 /********************/
@@ -403,26 +418,29 @@ struct ath_led {
 #define ATH_TXPOWER_MAX         100     /* .5 dBm units */
 #define ATH_RATE_DUMMY_MARKER   0
 
-#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_FULL_RESET        BIT(4)
-#define SC_OP_PREAMBLE_SHORT    BIT(5)
-#define SC_OP_PROTECT_ENABLE    BIT(6)
-#define SC_OP_RXFLUSH           BIT(7)
-#define SC_OP_LED_ASSOCIATED    BIT(8)
-#define SC_OP_WAIT_FOR_BEACON   BIT(12)
-#define SC_OP_LED_ON            BIT(13)
-#define SC_OP_SCANNING          BIT(14)
-#define SC_OP_TSF_RESET         BIT(15)
-#define SC_OP_WAIT_FOR_CAB      BIT(16)
-#define SC_OP_WAIT_FOR_PSPOLL_DATA BIT(17)
-#define SC_OP_WAIT_FOR_TX_ACK   BIT(18)
-#define SC_OP_BEACON_SYNC       BIT(19)
-#define SC_OP_BT_PRIORITY_DETECTED BIT(21)
-#define SC_OP_NULLFUNC_COMPLETED BIT(22)
-#define SC_OP_PS_ENABLED	BIT(23)
+#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_FULL_RESET             BIT(4)
+#define SC_OP_PREAMBLE_SHORT         BIT(5)
+#define SC_OP_PROTECT_ENABLE         BIT(6)
+#define SC_OP_RXFLUSH                BIT(7)
+#define SC_OP_LED_ASSOCIATED         BIT(8)
+#define SC_OP_LED_ON                 BIT(9)
+#define SC_OP_SCANNING               BIT(10)
+#define SC_OP_TSF_RESET              BIT(11)
+#define SC_OP_BT_PRIORITY_DETECTED   BIT(12)
+#define SC_OP_BT_SCAN		     BIT(13)
+
+/* Powersave flags */
+#define PS_WAIT_FOR_BEACON        BIT(0)
+#define PS_WAIT_FOR_CAB           BIT(1)
+#define PS_WAIT_FOR_PSPOLL_DATA   BIT(2)
+#define PS_WAIT_FOR_TX_ACK        BIT(3)
+#define PS_BEACON_SYNC            BIT(4)
+#define PS_NULLFUNC_COMPLETED     BIT(5)
+#define PS_ENABLED                BIT(6)
 
 struct ath_wiphy;
 struct ath_rate_table;
@@ -453,16 +471,17 @@ struct ath_softc {
 	int irq;
 	spinlock_t sc_resetlock;
 	spinlock_t sc_serial_rw;
-	spinlock_t ani_lock;
 	spinlock_t sc_pm_lock;
 	struct mutex mutex;
 
 	u32 intrstatus;
 	u32 sc_flags; /* SC_OP_* */
+	u16 ps_flags; /* PS_* */
 	u16 curtxpow;
 	u8 nbcnvifs;
 	u16 nvifs;
 	bool ps_enabled;
+	bool ps_idle;
 	unsigned long ps_usecount;
 	enum ath9k_int imask;
 
@@ -509,6 +528,7 @@ struct ath_wiphy {
 	int chan_is_ht;
 };
 
+void ath9k_tasklet(unsigned long data);
 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);
@@ -519,21 +539,16 @@ static inline void ath_read_cachesize(st
 	common->bus_ops->read_cachesize(common, csz);
 }
 
-static inline void ath_bus_cleanup(struct ath_common *common)
-{
-	common->bus_ops->cleanup(common);
-}
-
 extern struct ieee80211_ops ath9k_ops;
+extern int modparam_nohwcrypt;
 
 irqreturn_t ath_isr(int irq, void *dev);
-void ath_cleanup(struct ath_softc *sc);
-int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
+int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
 		    const struct ath_bus_ops *bus_ops);
-void ath_detach(struct ath_softc *sc);
+void ath9k_deinit_device(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_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);
@@ -542,6 +557,7 @@ int ath_set_channel(struct ath_softc *sc
 
 void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw);
 void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
+bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode);
 
 #ifdef CONFIG_PCI
 int ath_pci_init(void);
@@ -583,4 +599,8 @@ void ath_mac80211_stop_queue(struct ath_
 void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue);
 
 int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
+
+void ath_start_rfkill_poll(struct ath_softc *sc);
+extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw);
+
 #endif /* ATH9K_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/beacon.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/beacon.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/beacon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/beacon.c	2010-05-16 17:17:36.000000000 -0400
@@ -62,7 +62,7 @@ int ath_beaconq_config(struct ath_softc
  *  Beacons are always sent out at the lowest rate, and are not retried.
 */
 static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
-			     struct ath_buf *bf)
+			     struct ath_buf *bf, int rateidx)
 {
 	struct sk_buff *skb = bf->bf_mpdu;
 	struct ath_hw *ah = sc->sc_ah;
@@ -96,9 +96,9 @@ static void ath_beacon_setup(struct ath_
 	ds->ds_data = bf->bf_buf_addr;
 
 	sband = &sc->sbands[common->hw->conf.channel->band];
-	rate = sband->bitrates[0].hw_value;
+	rate = sband->bitrates[rateidx].hw_value;
 	if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
-		rate |= sband->bitrates[0].hw_value_short;
+		rate |= sband->bitrates[rateidx].hw_value_short;
 
 	ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
 			       ATH9K_PKT_TYPE_BEACON,
@@ -206,7 +206,7 @@ static struct ath_buf *ath_beacon_genera
 		}
 	}
 
-	ath_beacon_setup(sc, avp, bf);
+	ath_beacon_setup(sc, avp, bf, info->control.rates[0].idx);
 
 	while (skb) {
 		ath_tx_cabq(hw, skb);
@@ -237,7 +237,7 @@ static void ath_beacon_start_adhoc(struc
 	bf = avp->av_bcbuf;
 	skb = bf->bf_mpdu;
 
-	ath_beacon_setup(sc, avp, bf);
+	ath_beacon_setup(sc, avp, bf, 0);
 
 	/* NB: caller is known to have already stopped tx dma */
 	ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
@@ -480,7 +480,8 @@ void ath_beacon_tasklet(unsigned long da
 		sc->beacon.updateslot = COMMIT; /* commit next beacon */
 		sc->beacon.slotupdate = slot;
 	} else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
-		ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime);
+		ah->slottime = sc->beacon.slottime;
+		ath9k_hw_init_global_settings(ah);
 		sc->beacon.updateslot = OK;
 	}
 	if (bfaddr != 0) {
@@ -525,16 +526,13 @@ static void ath_beacon_config_ap(struct
 {
 	u32 nexttbtt, intval;
 
-	/* Configure the timers only when the TSF has to be reset */
-
-	if (!(sc->sc_flags & SC_OP_TSF_RESET))
-		return;
-
 	/* 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;
+
+	if (sc->sc_flags & SC_OP_TSF_RESET)
+		intval |= ATH9K_BEACON_RESET_TSF;
 
 	/*
 	 * In AP mode we enable the beacon timers and SWBA interrupts to
@@ -576,6 +574,13 @@ static void ath_beacon_config_sta(struct
 	u64 tsf;
 	int num_beacons, offset, dtim_dec_count, cfp_dec_count;
 
+	/* No need to configure beacon if we are not associated */
+	if (!common->curaid) {
+		ath_print(common, ATH_DBG_BEACON,
+			 "STA is not yet associated..skipping beacon config\n");
+		return;
+	}
+
 	memset(&bs, 0, sizeof(bs));
 	intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
 
@@ -738,7 +743,6 @@ void ath_beacon_config(struct ath_softc
 	enum nl80211_iftype iftype;
 
 	/* Setup the beacon configuration parameters */
-
 	if (vif) {
 		struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/btcoex.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/btcoex.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/btcoex.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/btcoex.h	2010-05-16 17:17:36.000000000 -0400
@@ -25,10 +25,12 @@
 
 #define ATH_BTCOEX_DEF_BT_PERIOD  45
 #define ATH_BTCOEX_DEF_DUTY_CYCLE 55
+#define ATH_BTCOEX_BTSCAN_DUTY_CYCLE 90
 #define ATH_BTCOEX_BMISS_THRESH   50
 
 #define ATH_BT_PRIORITY_TIME_THRESHOLD 1000 /* ms */
 #define ATH_BT_CNT_THRESHOLD	       3
+#define ATH_BT_CNT_SCAN_THRESHOLD      15
 
 enum ath_btcoex_scheme {
 	ATH_BTCOEX_CFG_NONE,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/debug.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/debug.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/debug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/debug.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #include "ath9k.h"
@@ -75,17 +76,24 @@ static const struct file_operations fops
 
 #endif
 
+#define DMA_BUF_LEN 1024
+
 static ssize_t read_file_dma(struct file *file, char __user *user_buf,
 			     size_t count, loff_t *ppos)
 {
 	struct ath_softc *sc = file->private_data;
 	struct ath_hw *ah = sc->sc_ah;
-	char buf[1024];
+	char *buf;
+	int retval;
 	unsigned int len = 0;
 	u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
 	int i, qcuOffset = 0, dcuOffset = 0;
 	u32 *qcuBase = &val[0], *dcuBase = &val[4];
 
+	buf = kmalloc(DMA_BUF_LEN, GFP_KERNEL);
+	if (!buf)
+		return 0;
+
 	ath9k_ps_wakeup(sc);
 
 	REG_WRITE_D(ah, AR_MACMISC,
@@ -93,20 +101,20 @@ static ssize_t read_file_dma(struct file
 		   (AR_MACMISC_MISC_OBS_BUS_1 <<
 		    AR_MACMISC_MISC_OBS_BUS_MSB_S)));
 
-	len += snprintf(buf + len, sizeof(buf) - len,
+	len += snprintf(buf + len, DMA_BUF_LEN - len,
 			"Raw DMA Debug values:\n");
 
 	for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
 		if (i % 4 == 0)
-			len += snprintf(buf + len, sizeof(buf) - len, "\n");
+			len += snprintf(buf + len, DMA_BUF_LEN - len, "\n");
 
 		val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32)));
-		len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ",
+		len += snprintf(buf + len, DMA_BUF_LEN - len, "%d: %08x ",
 				i, val[i]);
 	}
 
-	len += snprintf(buf + len, sizeof(buf) - len, "\n\n");
-	len += snprintf(buf + len, sizeof(buf) - len,
+	len += snprintf(buf + len, DMA_BUF_LEN - len, "\n\n");
+	len += snprintf(buf + len, DMA_BUF_LEN - len,
 			"Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
 
 	for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) {
@@ -120,7 +128,7 @@ static ssize_t read_file_dma(struct file
 			dcuBase++;
 		}
 
-		len += snprintf(buf + len, sizeof(buf) - len,
+		len += snprintf(buf + len, DMA_BUF_LEN - len,
 			"%2d          %2x      %1x     %2x           %2x\n",
 			i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
 			(*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
@@ -128,35 +136,37 @@ static ssize_t read_file_dma(struct file
 			(*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
 	}
 
-	len += snprintf(buf + len, sizeof(buf) - len, "\n");
+	len += snprintf(buf + len, DMA_BUF_LEN - len, "\n");
 
-	len += snprintf(buf + len, sizeof(buf) - len,
+	len += snprintf(buf + len, DMA_BUF_LEN - len,
 		"qcu_stitch state:   %2x    qcu_fetch state:        %2x\n",
 		(val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
-	len += snprintf(buf + len, sizeof(buf) - len,
+	len += snprintf(buf + len, DMA_BUF_LEN - len,
 		"qcu_complete state: %2x    dcu_complete state:     %2x\n",
 		(val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
-	len += snprintf(buf + len, sizeof(buf) - len,
+	len += snprintf(buf + len, DMA_BUF_LEN - len,
 		"dcu_arb state:      %2x    dcu_fp state:           %2x\n",
 		(val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
-	len += snprintf(buf + len, sizeof(buf) - len,
+	len += snprintf(buf + len, DMA_BUF_LEN - len,
 		"chan_idle_dur:     %3d    chan_idle_dur_valid:     %1d\n",
 		(val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
-	len += snprintf(buf + len, sizeof(buf) - len,
+	len += snprintf(buf + len, DMA_BUF_LEN - len,
 		"txfifo_valid_0:      %1d    txfifo_valid_1:          %1d\n",
 		(val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
-	len += snprintf(buf + len, sizeof(buf) - len,
+	len += snprintf(buf + len, DMA_BUF_LEN - len,
 		"txfifo_dcu_num_0:   %2d    txfifo_dcu_num_1:       %2d\n",
 		(val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
 
-	len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n",
+	len += snprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x \n",
 			REG_READ_D(ah, AR_OBS_BUS_1));
-	len += snprintf(buf + len, sizeof(buf) - len,
+	len += snprintf(buf + len, DMA_BUF_LEN - len,
 			"AR_CR: 0x%x \n", REG_READ_D(ah, AR_CR));
 
 	ath9k_ps_restore(sc);
 
-	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	kfree(buf);
+	return retval;
 }
 
 static const struct file_operations fops_dma = {
@@ -289,23 +299,49 @@ static ssize_t read_file_rcstat(struct f
 	if (sc->cur_rate_table == NULL)
 		return 0;
 
-	max = 80 + sc->cur_rate_table->rate_cnt * 64;
+	max = 80 + sc->cur_rate_table->rate_cnt * 1024;
 	buf = kmalloc(max + 1, GFP_KERNEL);
 	if (buf == NULL)
 		return 0;
 	buf[max] = 0;
 
-	len += sprintf(buf, "%5s %15s %8s %9s %3s\n\n", "Rate", "Success",
-		       "Retries", "XRetries", "PER");
+	len += sprintf(buf, "%6s %6s %6s "
+		       "%10s %10s %10s %10s\n",
+		       "HT", "MCS", "Rate",
+		       "Success", "Retries", "XRetries", "PER");
 
 	for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
 		u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
 		struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
+		char mcs[5];
+		char htmode[5];
+		int used_mcs = 0, used_htmode = 0;
+
+		if (WLAN_RC_PHY_HT(sc->cur_rate_table->info[i].phy)) {
+			used_mcs = snprintf(mcs, 5, "%d",
+				sc->cur_rate_table->info[i].ratecode);
+
+			if (WLAN_RC_PHY_40(sc->cur_rate_table->info[i].phy))
+				used_htmode = snprintf(htmode, 5, "HT40");
+			else if (WLAN_RC_PHY_20(sc->cur_rate_table->info[i].phy))
+				used_htmode = snprintf(htmode, 5, "HT20");
+			else
+				used_htmode = snprintf(htmode, 5, "????");
+		}
+
+		mcs[used_mcs] = '\0';
+		htmode[used_htmode] = '\0';
 
 		len += snprintf(buf + len, max - len,
-			"%3u.%d: %8u %8u %8u %8u\n", ratekbps / 1000,
-			(ratekbps % 1000) / 100, stats->success,
-			stats->retries, stats->xretries,
+			"%6s %6s %3u.%d: "
+			"%10u %10u %10u %10u\n",
+			htmode,
+			mcs,
+			ratekbps / 1000,
+			(ratekbps % 1000) / 100,
+			stats->success,
+			stats->retries,
+			stats->xretries,
 			stats->per);
 	}
 
@@ -554,6 +590,116 @@ static const struct file_operations fops
 	.owner = THIS_MODULE
 };
 
+static ssize_t read_file_recv(struct file *file, char __user *user_buf,
+			      size_t count, loff_t *ppos)
+{
+#define PHY_ERR(s, p) \
+	len += snprintf(buf + len, size - len, "%18s : %10u\n", s, \
+			sc->debug.stats.rxstats.phy_err_stats[p]);
+
+	struct ath_softc *sc = file->private_data;
+	char *buf;
+	unsigned int len = 0, size = 1152;
+	ssize_t retval = 0;
+
+	buf = kzalloc(size, GFP_KERNEL);
+	if (buf == NULL)
+		return 0;
+
+	len += snprintf(buf + len, size - len,
+			"%18s : %10u\n", "CRC ERR",
+			sc->debug.stats.rxstats.crc_err);
+	len += snprintf(buf + len, size - len,
+			"%18s : %10u\n", "DECRYPT CRC ERR",
+			sc->debug.stats.rxstats.decrypt_crc_err);
+	len += snprintf(buf + len, size - len,
+			"%18s : %10u\n", "PHY ERR",
+			sc->debug.stats.rxstats.phy_err);
+	len += snprintf(buf + len, size - len,
+			"%18s : %10u\n", "MIC ERR",
+			sc->debug.stats.rxstats.mic_err);
+	len += snprintf(buf + len, size - len,
+			"%18s : %10u\n", "PRE-DELIM CRC ERR",
+			sc->debug.stats.rxstats.pre_delim_crc_err);
+	len += snprintf(buf + len, size - len,
+			"%18s : %10u\n", "POST-DELIM CRC ERR",
+			sc->debug.stats.rxstats.post_delim_crc_err);
+	len += snprintf(buf + len, size - len,
+			"%18s : %10u\n", "DECRYPT BUSY ERR",
+			sc->debug.stats.rxstats.decrypt_busy_err);
+
+	PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN);
+	PHY_ERR("TIMING", ATH9K_PHYERR_TIMING);
+	PHY_ERR("PARITY", ATH9K_PHYERR_PARITY);
+	PHY_ERR("RATE", ATH9K_PHYERR_RATE);
+	PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH);
+	PHY_ERR("RADAR", ATH9K_PHYERR_RADAR);
+	PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE);
+	PHY_ERR("TOR", ATH9K_PHYERR_TOR);
+	PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING);
+	PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
+	PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
+	PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
+	PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP);
+	PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE);
+	PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART);
+	PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT);
+	PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING);
+	PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC);
+	PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
+	PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE);
+	PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART);
+	PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
+	PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP);
+	PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR);
+	PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
+	PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
+
+	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	kfree(buf);
+
+	return retval;
+
+#undef PHY_ERR
+}
+
+void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf)
+{
+#define RX_STAT_INC(c) sc->debug.stats.rxstats.c++
+#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++
+
+	struct ath_desc *ds = bf->bf_desc;
+	u32 phyerr;
+
+	if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
+		RX_STAT_INC(crc_err);
+	if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT)
+		RX_STAT_INC(decrypt_crc_err);
+	if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC)
+		RX_STAT_INC(mic_err);
+	if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_PRE)
+		RX_STAT_INC(pre_delim_crc_err);
+	if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_POST)
+		RX_STAT_INC(post_delim_crc_err);
+	if (ds->ds_rxstat.rs_status & ATH9K_RX_DECRYPT_BUSY)
+		RX_STAT_INC(decrypt_busy_err);
+
+	if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) {
+		RX_STAT_INC(phy_err);
+		phyerr = ds->ds_rxstat.rs_phyerr & 0x24;
+		RX_PHY_ERR_INC(phyerr);
+	}
+
+#undef RX_STAT_INC
+#undef RX_PHY_ERR_INC
+}
+
+static const struct file_operations fops_recv = {
+	.read = read_file_recv,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE
+};
+
 int ath9k_init_debug(struct ath_hw *ah)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
@@ -606,6 +752,13 @@ int ath9k_init_debug(struct ath_hw *ah)
 	if (!sc->debug.debugfs_xmit)
 		goto err;
 
+	sc->debug.debugfs_recv = debugfs_create_file("recv",
+						     S_IRUSR,
+						     sc->debug.debugfs_phy,
+						     sc, &fops_recv);
+	if (!sc->debug.debugfs_recv)
+		goto err;
+
 	return 0;
 err:
 	ath9k_exit_debug(ah);
@@ -617,6 +770,7 @@ void ath9k_exit_debug(struct ath_hw *ah)
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_softc *sc = (struct ath_softc *) common->priv;
 
+	debugfs_remove(sc->debug.debugfs_recv);
 	debugfs_remove(sc->debug.debugfs_xmit);
 	debugfs_remove(sc->debug.debugfs_wiphy);
 	debugfs_remove(sc->debug.debugfs_rcstat);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/debug.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/debug.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/debug.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/debug.h	2010-05-16 17:17:36.000000000 -0400
@@ -116,10 +116,35 @@ struct ath_tx_stats {
 	u32 delim_underrun;
 };
 
+/**
+ * struct ath_rx_stats - RX Statistics
+ * @crc_err: No. of frames with incorrect CRC value
+ * @decrypt_crc_err: No. of frames whose CRC check failed after
+	decryption process completed
+ * @phy_err: No. of frames whose reception failed because the PHY
+	encountered an error
+ * @mic_err: No. of frames with incorrect TKIP MIC verification failure
+ * @pre_delim_crc_err: Pre-Frame delimiter CRC error detections
+ * @post_delim_crc_err: Post-Frame delimiter CRC error detections
+ * @decrypt_busy_err: Decryption interruptions counter
+ * @phy_err_stats: Individual PHY error statistics
+ */
+struct ath_rx_stats {
+	u32 crc_err;
+	u32 decrypt_crc_err;
+	u32 phy_err;
+	u32 mic_err;
+	u32 pre_delim_crc_err;
+	u32 post_delim_crc_err;
+	u32 decrypt_busy_err;
+	u32 phy_err_stats[ATH9K_PHYERR_MAX];
+};
+
 struct ath_stats {
 	struct ath_interrupt_stats istats;
 	struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
 	struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
+	struct ath_rx_stats rxstats;
 };
 
 struct ath9k_debug {
@@ -130,6 +155,7 @@ struct ath9k_debug {
 	struct dentry *debugfs_rcstat;
 	struct dentry *debugfs_wiphy;
 	struct dentry *debugfs_xmit;
+	struct dentry *debugfs_recv;
 	struct ath_stats stats;
 };
 
@@ -142,6 +168,7 @@ void ath_debug_stat_interrupt(struct ath
 void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
 void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
 		       struct ath_buf *bf);
+void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf);
 void ath_debug_stat_retries(struct ath_softc *sc, int rix,
 			    int xretries, int retries, u8 per);
 
@@ -180,6 +207,11 @@ static inline void ath_debug_stat_tx(str
 				     struct ath_buf *bf)
 {
 }
+
+static inline void ath_debug_stat_rx(struct ath_softc *sc,
+				     struct ath_buf *bf)
+{
+}
 
 static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
 					  int xretries, int retries, u8 per)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/gpio.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/gpio.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,442 @@
+/*
+ * 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"
+
+/********************************/
+/*	 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, sc->sc_ah->led_pin, 0);
+	else
+		ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
+				  (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
+
+	ieee80211_queue_delayed_work(sc->hw,
+				     &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)
+{
+	struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
+	struct ath_softc *sc = led->sc;
+
+	switch (brightness) {
+	case LED_OFF:
+		if (led->led_type == ATH_LED_ASSOC ||
+		    led->led_type == ATH_LED_RADIO) {
+			ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
+				(led->led_type == ATH_LED_RADIO));
+			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) {
+			sc->sc_flags |= SC_OP_LED_ASSOCIATED;
+			ieee80211_queue_delayed_work(sc->hw,
+						     &sc->ath_led_blink_work, 0);
+		} else if (led->led_type == ATH_LED_RADIO) {
+			ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
+			sc->sc_flags |= SC_OP_LED_ON;
+		} else {
+			sc->led_on_cnt++;
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
+			    char *trigger)
+{
+	int ret;
+
+	led->sc = sc;
+	led->led_cdev.name = led->name;
+	led->led_cdev.default_trigger = trigger;
+	led->led_cdev.brightness_set = ath_led_brightness;
+
+	ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
+	if (ret)
+		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
+			  "Failed to register led:%s", led->name);
+	else
+		led->registered = 1;
+	return ret;
+}
+
+static void ath_unregister_led(struct ath_led *led)
+{
+	if (led->registered) {
+		led_classdev_unregister(&led->led_cdev);
+		led->registered = 0;
+	}
+}
+
+void ath_deinit_leds(struct ath_softc *sc)
+{
+	ath_unregister_led(&sc->assoc_led);
+	sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
+	ath_unregister_led(&sc->tx_led);
+	ath_unregister_led(&sc->rx_led);
+	ath_unregister_led(&sc->radio_led);
+	ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
+}
+
+void ath_init_leds(struct ath_softc *sc)
+{
+	char *trigger;
+	int ret;
+
+	if (AR_SREV_9287(sc->sc_ah))
+		sc->sc_ah->led_pin = ATH_LED_PIN_9287;
+	else
+		sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
+
+	/* Configure gpio 1 for output */
+	ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
+			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+	/* LED off, active low */
+	ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->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));
+	ret = ath_register_led(sc, &sc->radio_led, trigger);
+	sc->radio_led.led_type = ATH_LED_RADIO;
+	if (ret)
+		goto fail;
+
+	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));
+	ret = ath_register_led(sc, &sc->assoc_led, trigger);
+	sc->assoc_led.led_type = ATH_LED_ASSOC;
+	if (ret)
+		goto fail;
+
+	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));
+	ret = ath_register_led(sc, &sc->tx_led, trigger);
+	sc->tx_led.led_type = ATH_LED_TX;
+	if (ret)
+		goto fail;
+
+	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));
+	ret = ath_register_led(sc, &sc->rx_led, trigger);
+	sc->rx_led.led_type = ATH_LED_RX;
+	if (ret)
+		goto fail;
+
+	return;
+
+fail:
+	cancel_delayed_work_sync(&sc->ath_led_blink_work);
+	ath_deinit_leds(sc);
+}
+
+/*******************/
+/*	Rfkill	   */
+/*******************/
+
+static bool ath_is_rfkill_set(struct ath_softc *sc)
+{
+	struct ath_hw *ah = sc->sc_ah;
+
+	return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
+				  ah->rfkill_polarity;
+}
+
+void ath9k_rfkill_poll_state(struct ieee80211_hw *hw)
+{
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+	bool blocked = !!ath_is_rfkill_set(sc);
+
+	wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
+}
+
+void ath_start_rfkill_poll(struct ath_softc *sc)
+{
+	struct ath_hw *ah = sc->sc_ah;
+
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+		wiphy_rfkill_start_polling(sc->hw->wiphy);
+}
+
+/******************/
+/*     BTCOEX     */
+/******************/
+
+/*
+ * Detects if there is any priority bt traffic
+ */
+static void ath_detect_bt_priority(struct ath_softc *sc)
+{
+	struct ath_btcoex *btcoex = &sc->btcoex;
+	struct ath_hw *ah = sc->sc_ah;
+
+	if (ath9k_hw_gpio_get(sc->sc_ah, ah->btcoex_hw.btpriority_gpio))
+		btcoex->bt_priority_cnt++;
+
+	if (time_after(jiffies, btcoex->bt_priority_time +
+			msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
+		sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN);
+		/* Detect if colocated bt started scanning */
+		if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) {
+			ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
+				  "BT scan detected");
+			sc->sc_flags |= (SC_OP_BT_SCAN |
+					 SC_OP_BT_PRIORITY_DETECTED);
+		} else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
+			ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
+				  "BT priority traffic detected");
+			sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
+		}
+
+		btcoex->bt_priority_cnt = 0;
+		btcoex->bt_priority_time = jiffies;
+	}
+}
+
+/*
+ * Configures appropriate weight based on stomp type.
+ */
+static void ath9k_btcoex_bt_stomp(struct ath_softc *sc,
+				  enum ath_stomp_type stomp_type)
+{
+	struct ath_hw *ah = sc->sc_ah;
+
+	switch (stomp_type) {
+	case ATH_BTCOEX_STOMP_ALL:
+		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+					   AR_STOMP_ALL_WLAN_WGHT);
+		break;
+	case ATH_BTCOEX_STOMP_LOW:
+		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+					   AR_STOMP_LOW_WLAN_WGHT);
+		break;
+	case ATH_BTCOEX_STOMP_NONE:
+		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+					   AR_STOMP_NONE_WLAN_WGHT);
+		break;
+	default:
+		ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+			  "Invalid Stomptype\n");
+		break;
+	}
+
+	ath9k_hw_btcoex_enable(ah);
+}
+
+static void ath9k_gen_timer_start(struct ath_hw *ah,
+				  struct ath_gen_timer *timer,
+				  u32 timer_next,
+				  u32 timer_period)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
+
+	ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
+
+	if ((sc->imask & ATH9K_INT_GENTIMER) == 0) {
+		ath9k_hw_set_interrupts(ah, 0);
+		sc->imask |= ATH9K_INT_GENTIMER;
+		ath9k_hw_set_interrupts(ah, sc->imask);
+	}
+}
+
+static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
+	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
+
+	ath9k_hw_gen_timer_stop(ah, timer);
+
+	/* if no timer is enabled, turn off interrupt mask */
+	if (timer_table->timer_mask.val == 0) {
+		ath9k_hw_set_interrupts(ah, 0);
+		sc->imask &= ~ATH9K_INT_GENTIMER;
+		ath9k_hw_set_interrupts(ah, sc->imask);
+	}
+}
+
+/*
+ * This is the master bt coex timer which runs for every
+ * 45ms, bt traffic will be given priority during 55% of this
+ * period while wlan gets remaining 45%
+ */
+static void ath_btcoex_period_timer(unsigned long data)
+{
+	struct ath_softc *sc = (struct ath_softc *) data;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_btcoex *btcoex = &sc->btcoex;
+	u32 timer_period;
+	bool is_btscan;
+
+	ath_detect_bt_priority(sc);
+
+	is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
+
+	spin_lock_bh(&btcoex->btcoex_lock);
+
+	ath9k_btcoex_bt_stomp(sc, is_btscan ? ATH_BTCOEX_STOMP_ALL :
+			      btcoex->bt_stomp_type);
+
+	spin_unlock_bh(&btcoex->btcoex_lock);
+
+	if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) {
+		if (btcoex->hw_timer_enabled)
+			ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
+
+		timer_period = is_btscan ? btcoex->btscan_no_stomp :
+					   btcoex->btcoex_no_stomp;
+		ath9k_gen_timer_start(ah,
+				      btcoex->no_stomp_timer,
+				      (ath9k_hw_gettsf32(ah) +
+				       timer_period), timer_period * 10);
+		btcoex->hw_timer_enabled = true;
+	}
+
+	mod_timer(&btcoex->period_timer, jiffies +
+				  msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
+}
+
+/*
+ * Generic tsf based hw timer which configures weight
+ * registers to time slice between wlan and bt traffic
+ */
+static void ath_btcoex_no_stomp_timer(void *arg)
+{
+	struct ath_softc *sc = (struct ath_softc *)arg;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_btcoex *btcoex = &sc->btcoex;
+	bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
+
+	ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+		  "no stomp timer running \n");
+
+	spin_lock_bh(&btcoex->btcoex_lock);
+
+	if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
+		ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE);
+	 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
+		ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW);
+
+	spin_unlock_bh(&btcoex->btcoex_lock);
+}
+
+int ath_init_btcoex_timer(struct ath_softc *sc)
+{
+	struct ath_btcoex *btcoex = &sc->btcoex;
+
+	btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
+	btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
+		btcoex->btcoex_period / 100;
+	btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) *
+				   btcoex->btcoex_period / 100;
+
+	setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
+			(unsigned long) sc);
+
+	spin_lock_init(&btcoex->btcoex_lock);
+
+	btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah,
+			ath_btcoex_no_stomp_timer,
+			ath_btcoex_no_stomp_timer,
+			(void *) sc, AR_FIRST_NDP_TIMER);
+
+	if (!btcoex->no_stomp_timer)
+		return -ENOMEM;
+
+	return 0;
+}
+
+/*
+ * (Re)start btcoex timers
+ */
+void ath9k_btcoex_timer_resume(struct ath_softc *sc)
+{
+	struct ath_btcoex *btcoex = &sc->btcoex;
+	struct ath_hw *ah = sc->sc_ah;
+
+	ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+		  "Starting btcoex timers");
+
+	/* make sure duty cycle timer is also stopped when resuming */
+	if (btcoex->hw_timer_enabled)
+		ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
+
+	btcoex->bt_priority_cnt = 0;
+	btcoex->bt_priority_time = jiffies;
+	sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN);
+
+	mod_timer(&btcoex->period_timer, jiffies);
+}
+
+
+/*
+ * Pause btcoex timer and bt duty cycle timer
+ */
+void ath9k_btcoex_timer_pause(struct ath_softc *sc)
+{
+	struct ath_btcoex *btcoex = &sc->btcoex;
+	struct ath_hw *ah = sc->sc_ah;
+
+	del_timer_sync(&btcoex->period_timer);
+
+	if (btcoex->hw_timer_enabled)
+		ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
+
+	btcoex->hw_timer_enabled = false;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/hw.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/hw.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/hw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/hw.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
  */
 
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #include "hw.h"
@@ -52,28 +53,6 @@ module_exit(ath9k_exit);
 /* Helper Functions */
 /********************/
 
-static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
-{
-	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-
-	if (!ah->curchan) /* should really check for CCK instead */
-		return clks / ATH9K_CLOCK_RATE_CCK;
-	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_hw *ah, u32 clks)
-{
-	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-
-	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_hw *ah, u32 usecs)
 {
 	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
@@ -343,30 +322,6 @@ static bool ath9k_hw_chip_test(struct at
 	return true;
 }
 
-static const char *ath9k_hw_devname(u16 devid)
-{
-	switch (devid) {
-	case AR5416_DEVID_PCI:
-		return "Atheros 5416";
-	case AR5416_DEVID_PCIE:
-		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";
-	case AR9285_DEVID_PCIE:
-		return "Atheros 9285";
-	case AR5416_DEVID_AR9287_PCI:
-	case AR5416_DEVID_AR9287_PCIE:
-		return "Atheros 9287";
-	}
-
-	return NULL;
-}
-
 static void ath9k_hw_init_config(struct ath_hw *ah)
 {
 	int i;
@@ -380,7 +335,6 @@ static void ath9k_hw_init_config(struct
 	ah->config.pcie_clock_req = 0;
 	ah->config.pcie_waen = 0;
 	ah->config.analog_shiftreg = 1;
-	ah->config.ht_enable = 1;
 	ah->config.ofdm_trig_low = 200;
 	ah->config.ofdm_trig_high = 500;
 	ah->config.cck_trig_high = 200;
@@ -392,7 +346,12 @@ static void ath9k_hw_init_config(struct
 		ah->config.spurchans[i][1] = AR_NO_SPUR;
 	}
 
-	ah->config.intr_mitigation = true;
+	if (ah->hw_version.devid != AR2427_DEVID_PCIE)
+		ah->config.ht_enable = 1;
+	else
+		ah->config.ht_enable = 0;
+
+	ah->config.rx_intr_mitigation = true;
 
 	/*
 	 * We need this for PCI devices only (Cardbus, PCI, miniPCI)
@@ -437,8 +396,6 @@ static void ath9k_hw_init_defaults(struc
 	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;
 	ah->power_mode = ATH9K_PM_UNDEFINED;
 }
@@ -590,6 +547,7 @@ static bool ath9k_hw_devid_supported(u16
 	case AR5416_DEVID_AR9287_PCI:
 	case AR5416_DEVID_AR9287_PCIE:
 	case AR9271_USB:
+	case AR2427_DEVID_PCIE:
 		return true;
 	default:
 		break;
@@ -1183,7 +1141,7 @@ static void ath9k_hw_init_interrupt_mask
 		AR_IMR_RXORN |
 		AR_IMR_BCNMISC;
 
-	if (ah->config.intr_mitigation)
+	if (ah->config.rx_intr_mitigation)
 		ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
 	else
 		ah->mask_reg |= AR_IMR_RXOK;
@@ -1203,34 +1161,25 @@ static void ath9k_hw_init_interrupt_mask
 	}
 }
 
-static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
+static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
 {
-	if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
-		ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
-			  "bad ack timeout %u\n", us);
-		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));
-		ah->acktimeout = us;
-		return true;
-	}
+	u32 val = ath9k_hw_mac_to_clks(ah, us);
+	val = min(val, (u32) 0xFFFF);
+	REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val);
 }
 
-static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
+static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
 {
-	if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
-		ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
-			  "bad cts timeout %u\n", us);
-		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));
-		ah->ctstimeout = us;
-		return true;
-	}
+	u32 val = ath9k_hw_mac_to_clks(ah, us);
+	val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK));
+	REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val);
+}
+
+static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
+{
+	u32 val = ath9k_hw_mac_to_clks(ah, us);
+	val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS));
+	REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, val);
 }
 
 static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
@@ -1247,31 +1196,48 @@ static bool ath9k_hw_set_global_txtimeou
 	}
 }
 
-static void ath9k_hw_init_user_settings(struct ath_hw *ah)
+void ath9k_hw_init_global_settings(struct ath_hw *ah)
 {
+	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
+	int acktimeout;
+	int slottime;
+	int sifstime;
+
 	ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
 		  ah->misc_mode);
 
 	if (ah->misc_mode != 0)
 		REG_WRITE(ah, AR_PCU_MISC,
 			  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 (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ)
+		sifstime = 16;
+	else
+		sifstime = 10;
+
+	/* As defined by IEEE 802.11-2007 17.3.8.6 */
+	slottime = ah->slottime + 3 * ah->coverage_class;
+	acktimeout = slottime + sifstime;
+
+	/*
+	 * Workaround for early ACK timeouts, add an offset to match the
+	 * initval's 64us ack timeout value.
+	 * This was initially only meant to work around an issue with delayed
+	 * BA frames in some implementations, but it has been found to fix ACK
+	 * timeout issues in other cases as well.
+	 */
+	if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
+		acktimeout += 64 - sifstime - ah->slottime;
+
+	ath9k_hw_setslottime(ah, slottime);
+	ath9k_hw_set_ack_timeout(ah, acktimeout);
+	ath9k_hw_set_cts_timeout(ah, acktimeout);
 	if (ah->globaltxtimeout != (u32) -1)
 		ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
 }
+EXPORT_SYMBOL(ath9k_hw_init_global_settings);
 
-const char *ath9k_hw_probe(u16 vendorid, u16 devid)
-{
-	return vendorid == ATHEROS_VENDOR_ID ?
-		ath9k_hw_devname(devid) : NULL;
-}
-
-void ath9k_hw_detach(struct ath_hw *ah)
+void ath9k_hw_deinit(struct ath_hw *ah)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 
@@ -1289,7 +1255,7 @@ free_hw:
 	kfree(ah);
 	ah = NULL;
 }
-EXPORT_SYMBOL(ath9k_hw_detach);
+EXPORT_SYMBOL(ath9k_hw_deinit);
 
 /*******/
 /* INI */
@@ -1345,6 +1311,16 @@ static void ath9k_hw_override_ini(struct
 	 * Necessary to avoid issues on AR5416 2.0
 	 */
 	REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
+
+	/*
+	 * Disable RIFS search on some chips to avoid baseband
+	 * hang issues.
+	 */
+	if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) {
+		val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS);
+		val &= ~AR_PHY_RIFS_INIT_DELAY;
+		REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val);
+	}
 }
 
 static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah,
@@ -2090,7 +2066,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 	if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
 		ath9k_enable_rfkill(ah);
 
-	ath9k_hw_init_user_settings(ah);
+	ath9k_hw_init_global_settings(ah);
 
 	if (AR_SREV_9287_12_OR_LATER(ah)) {
 		REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
@@ -2120,7 +2096,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 
 	REG_WRITE(ah, AR_OBS, 8);
 
-	if (ah->config.intr_mitigation) {
+	if (ah->config.rx_intr_mitigation) {
 		REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
 		REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
 	}
@@ -2780,7 +2756,7 @@ bool ath9k_hw_getisr(struct ath_hw *ah,
 
 		*masked = isr & ATH9K_INT_COMMON;
 
-		if (ah->config.intr_mitigation) {
+		if (ah->config.rx_intr_mitigation) {
 			if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
 				*masked |= ATH9K_INT_RX;
 		}
@@ -2913,7 +2889,7 @@ enum ath9k_int ath9k_hw_set_interrupts(s
 	}
 	if (ints & ATH9K_INT_RX) {
 		mask |= AR_IMR_RXERR;
-		if (ah->config.intr_mitigation)
+		if (ah->config.rx_intr_mitigation)
 			mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
 		else
 			mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
@@ -3687,21 +3663,6 @@ u64 ath9k_hw_extend_tsf(struct ath_hw *a
 }
 EXPORT_SYMBOL(ath9k_hw_extend_tsf);
 
-bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
-{
-	if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
-		ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
-			  "bad slot time %u\n", us);
-		ah->slottime = (u32) -1;
-		return false;
-	} else {
-		REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
-		ah->slottime = us;
-		return true;
-	}
-}
-EXPORT_SYMBOL(ath9k_hw_setslottime);
-
 void ath9k_hw_set11nmac2040(struct ath_hw *ah)
 {
 	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/hw.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/hw.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #define AR9280_DEVID_PCI	0x0029
 #define AR9280_DEVID_PCIE	0x002a
 #define AR9285_DEVID_PCIE	0x002b
+#define AR2427_DEVID_PCIE	0x002c
 
 #define AR5416_AR9100_DEVID	0x000b
 
@@ -212,7 +213,7 @@ struct ath9k_ops_config {
 	u32 cck_trig_low;
 	u32 enable_ani;
 	int serialize_regmode;
-	bool intr_mitigation;
+	bool rx_intr_mitigation;
 #define SPUR_DISABLE        	0
 #define SPUR_ENABLE_IOCTL   	1
 #define SPUR_ENABLE_EEPROM  	2
@@ -551,10 +552,9 @@ struct ath_hw {
 	u32 *bank6Temp;
 
 	int16_t txpower_indexoffset;
+	int coverage_class;
 	u32 beacon_interval;
 	u32 slottime;
-	u32 acktimeout;
-	u32 ctstimeout;
 	u32 globaltxtimeout;
 
 	/* ANI */
@@ -616,7 +616,7 @@ static inline struct ath_regulatory *ath
 
 /* Initialization, Detach, Reset */
 const char *ath9k_hw_probe(u16 vendorid, u16 devid);
-void ath9k_hw_detach(struct ath_hw *ah);
+void ath9k_hw_deinit(struct ath_hw *ah);
 int ath9k_hw_init(struct ath_hw *ah);
 int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 		   bool bChannelChange);
@@ -668,7 +668,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah
 void ath9k_hw_reset_tsf(struct ath_hw *ah);
 void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
 u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp);
-bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
+void ath9k_hw_init_global_settings(struct ath_hw *ah);
 void ath9k_hw_set11nmac2040(struct ath_hw *ah);
 void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
 void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/init.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/init.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/init.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,865 @@
+/*
+ * 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/slab.h>
+
+#include "ath9k.h"
+
+static char *dev_info = "ath9k";
+
+MODULE_AUTHOR("Atheros Communications");
+MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
+MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
+MODULE_LICENSE("Dual BSD/GPL");
+
+static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
+module_param_named(debug, ath9k_debug, uint, 0);
+MODULE_PARM_DESC(debug, "Debugging mask");
+
+int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
+
+/* We use the hw_value as an index into our private channel structure */
+
+#define CHAN2G(_freq, _idx)  { \
+	.center_freq = (_freq), \
+	.hw_value = (_idx), \
+	.max_power = 20, \
+}
+
+#define CHAN5G(_freq, _idx) { \
+	.band = IEEE80211_BAND_5GHZ, \
+	.center_freq = (_freq), \
+	.hw_value = (_idx), \
+	.max_power = 20, \
+}
+
+/* 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 */
+};
+
+/* 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 */
+};
+
+/* Atheros hardware rate code addition for short premble */
+#define SHPCHECK(__hw_rate, __flags) \
+	((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
+
+#define RATE(_bitrate, _hw_rate, _flags) {              \
+	.bitrate        = (_bitrate),                   \
+	.flags          = (_flags),                     \
+	.hw_value       = (_hw_rate),                   \
+	.hw_value_short = (SHPCHECK(_hw_rate, _flags))  \
+}
+
+static struct ieee80211_rate ath9k_legacy_rates[] = {
+	RATE(10, 0x1b, 0),
+	RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
+	RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
+	RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
+	RATE(60, 0x0b, 0),
+	RATE(90, 0x0f, 0),
+	RATE(120, 0x0a, 0),
+	RATE(180, 0x0e, 0),
+	RATE(240, 0x09, 0),
+	RATE(360, 0x0d, 0),
+	RATE(480, 0x08, 0),
+	RATE(540, 0x0c, 0),
+};
+
+static void ath9k_deinit_softc(struct ath_softc *sc);
+
+/*
+ * 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.
+ */
+
+static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
+{
+	struct ath_hw *ah = (struct ath_hw *) hw_priv;
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
+
+	if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+		unsigned long flags;
+		spin_lock_irqsave(&sc->sc_serial_rw, flags);
+		iowrite32(val, sc->mem + reg_offset);
+		spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
+	} else
+		iowrite32(val, sc->mem + reg_offset);
+}
+
+static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
+{
+	struct ath_hw *ah = (struct ath_hw *) hw_priv;
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
+	u32 val;
+
+	if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+		unsigned long flags;
+		spin_lock_irqsave(&sc->sc_serial_rw, flags);
+		val = ioread32(sc->mem + reg_offset);
+		spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
+	} else
+		val = ioread32(sc->mem + reg_offset);
+	return val;
+}
+
+static const struct ath_ops ath9k_common_ops = {
+	.read = ath9k_ioread32,
+	.write = ath9k_iowrite32,
+};
+
+/**************************/
+/*     Initialization     */
+/**************************/
+
+static void setup_ht_cap(struct ath_softc *sc,
+			 struct ieee80211_sta_ht_cap *ht_info)
+{
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	u8 tx_streams, rx_streams;
+
+	ht_info->ht_supported = true;
+	ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+		       IEEE80211_HT_CAP_SM_PS |
+		       IEEE80211_HT_CAP_SGI_40 |
+		       IEEE80211_HT_CAP_DSSSCCK40;
+
+	ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+	ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
+
+	/* set up supported mcs set */
+	memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
+	tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ?
+		     1 : 2;
+	rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ?
+		     1 : 2;
+
+	if (tx_streams != rx_streams) {
+		ath_print(common, ATH_DBG_CONFIG,
+			  "TX streams %d, RX streams: %d\n",
+			  tx_streams, rx_streams);
+		ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
+		ht_info->mcs.tx_params |= ((tx_streams - 1) <<
+				IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
+	}
+
+	ht_info->mcs.rx_mask[0] = 0xff;
+	if (rx_streams >= 2)
+		ht_info->mcs.rx_mask[1] = 0xff;
+
+	ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
+}
+
+static int ath9k_reg_notifier(struct wiphy *wiphy,
+			      struct regulatory_request *request)
+{
+	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+	struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
+
+	return ath_reg_notifier_apply(wiphy, request, reg);
+}
+
+/*
+ *  This function will allocate both the DMA descriptor structure, and the
+ *  buffers it contains.  These are used to contain the descriptors used
+ *  by the system.
+*/
+int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
+		      struct list_head *head, const char *name,
+		      int nbuf, int ndesc)
+{
+#define	DS2PHYS(_dd, _ds)						\
+	((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
+#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
+#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	struct ath_desc *ds;
+	struct ath_buf *bf;
+	int i, bsize, error;
+
+	ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
+		  name, nbuf, ndesc);
+
+	INIT_LIST_HEAD(head);
+	/* ath_desc must be a multiple of DWORDs */
+	if ((sizeof(struct ath_desc) % 4) != 0) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "ath_desc not DWORD aligned\n");
+		BUG_ON((sizeof(struct ath_desc) % 4) != 0);
+		error = -ENOMEM;
+		goto fail;
+	}
+
+	dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
+
+	/*
+	 * Need additional DMA memory because we can't use
+	 * descriptors that cross the 4K page boundary. Assume
+	 * one skipped descriptor per 4K page.
+	 */
+	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;
+
+		while (ndesc_skipped) {
+			dma_len = ndesc_skipped * sizeof(struct ath_desc);
+			dd->dd_desc_len += dma_len;
+
+			ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
+		};
+	}
+
+	/* allocate descriptors */
+	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;
+	}
+	ds = dd->dd_desc;
+	ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
+		  name, ds, (u32) dd->dd_desc_len,
+		  ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
+
+	/* allocate buffers */
+	bsize = sizeof(struct ath_buf) * nbuf;
+	bf = kzalloc(bsize, GFP_KERNEL);
+	if (bf == NULL) {
+		error = -ENOMEM;
+		goto fail2;
+	}
+	dd->dd_bufptr = bf;
+
+	for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
+		bf->bf_desc = ds;
+		bf->bf_daddr = DS2PHYS(dd, ds);
+
+		if (!(sc->sc_ah->caps.hw_caps &
+		      ATH9K_HW_CAP_4KB_SPLITTRANS)) {
+			/*
+			 * Skip descriptor addresses which can cause 4KB
+			 * boundary crossing (addr + length) with a 32 dword
+			 * descriptor fetch.
+			 */
+			while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
+				BUG_ON((caddr_t) bf->bf_desc >=
+				       ((caddr_t) dd->dd_desc +
+					dd->dd_desc_len));
+
+				ds += ndesc;
+				bf->bf_desc = ds;
+				bf->bf_daddr = DS2PHYS(dd, ds);
+			}
+		}
+		list_add_tail(&bf->list, head);
+	}
+	return 0;
+fail2:
+	dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
+			  dd->dd_desc_paddr);
+fail:
+	memset(dd, 0, sizeof(*dd));
+	return error;
+#undef ATH_DESC_4KB_BOUND_CHECK
+#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
+#undef DS2PHYS
+}
+
+static void ath9k_init_crypto(struct ath_softc *sc)
+{
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	int i = 0;
+
+	/* Get the hardware key cache size. */
+	common->keymax = sc->sc_ah->caps.keycache_size;
+	if (common->keymax > ATH_KEYMAX) {
+		ath_print(common, ATH_DBG_ANY,
+			  "Warning, using only %u entries in %u key cache\n",
+			  ATH_KEYMAX, common->keymax);
+		common->keymax = ATH_KEYMAX;
+	}
+
+	/*
+	 * Reset the key cache since some parts do not
+	 * reset the contents on initial power up.
+	 */
+	for (i = 0; i < common->keymax; i++)
+		ath9k_hw_keyreset(sc->sc_ah, (u16) i);
+
+	if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER,
+				   ATH9K_CIPHER_TKIP, NULL)) {
+		/*
+		 * Whether we should enable h/w TKIP MIC.
+		 * XXX: if we don't support WME TKIP MIC, then we wouldn't
+		 * report WMM capable, so it's always safe to turn on
+		 * TKIP MIC in this case.
+		 */
+		ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL);
+	}
+
+	/*
+	 * Check whether the separate key cache entries
+	 * are required to handle both tx+rx MIC keys.
+	 * With split mic keys the number of stations is limited
+	 * to 27 otherwise 59.
+	 */
+	if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER,
+				   ATH9K_CIPHER_TKIP, NULL)
+	    && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER,
+				      ATH9K_CIPHER_MIC, NULL)
+	    && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_TKIP_SPLIT,
+				      0, NULL))
+		common->splitmic = 1;
+
+	/* turn on mcast key search if possible */
+	if (!ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
+		(void)ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH,
+					     1, 1, NULL);
+
+}
+
+static int ath9k_init_btcoex(struct ath_softc *sc)
+{
+	int r, qnum;
+
+	switch (sc->sc_ah->btcoex_hw.scheme) {
+	case ATH_BTCOEX_CFG_NONE:
+		break;
+	case ATH_BTCOEX_CFG_2WIRE:
+		ath9k_hw_btcoex_init_2wire(sc->sc_ah);
+		break;
+	case ATH_BTCOEX_CFG_3WIRE:
+		ath9k_hw_btcoex_init_3wire(sc->sc_ah);
+		r = ath_init_btcoex_timer(sc);
+		if (r)
+			return -1;
+		qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
+		ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum);
+		sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
+		break;
+	default:
+		WARN_ON(1);
+		break;
+	}
+
+	return 0;
+}
+
+static int ath9k_init_queues(struct ath_softc *sc)
+{
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	int i = 0;
+
+	for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
+		sc->tx.hwq_map[i] = -1;
+
+	sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
+	if (sc->beacon.beaconq == -1) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to setup a beacon xmit queue\n");
+		goto err;
+	}
+
+	sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
+	if (sc->beacon.cabq == NULL) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to setup CAB xmit queue\n");
+		goto err;
+	}
+
+	sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
+	ath_cabq_update(sc);
+
+	if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to setup xmit queue for BK traffic\n");
+		goto err;
+	}
+
+	if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to setup xmit queue for BE traffic\n");
+		goto err;
+	}
+	if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to setup xmit queue for VI traffic\n");
+		goto err;
+	}
+	if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to setup xmit queue for VO traffic\n");
+		goto err;
+	}
+
+	return 0;
+
+err:
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+		if (ATH_TXQ_SETUP(sc, i))
+			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
+
+	return -EIO;
+}
+
+static void ath9k_init_channels_rates(struct ath_softc *sc)
+{
+	if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) {
+		sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
+		sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
+		sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
+			ARRAY_SIZE(ath9k_2ghz_chantable);
+		sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
+		sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
+			ARRAY_SIZE(ath9k_legacy_rates);
+	}
+
+	if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
+		sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
+		sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
+		sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
+			ARRAY_SIZE(ath9k_5ghz_chantable);
+		sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
+			ath9k_legacy_rates + 4;
+		sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
+			ARRAY_SIZE(ath9k_legacy_rates) - 4;
+	}
+}
+
+static void ath9k_init_misc(struct ath_softc *sc)
+{
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	int i = 0;
+
+	common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
+	setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
+
+	sc->config.txpowlimit = ATH_TXPOWER_MAX;
+
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
+		sc->sc_flags |= SC_OP_TXAGGR;
+		sc->sc_flags |= SC_OP_RXAGGR;
+	}
+
+	common->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
+	common->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
+
+	ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
+	sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
+
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+		memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
+
+	sc->beacon.slottime = ATH9K_SLOT_TIME_9;
+
+	for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
+		sc->beacon.bslot[i] = NULL;
+		sc->beacon.bslot_aphy[i] = NULL;
+	}
+}
+
+static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
+			    const struct ath_bus_ops *bus_ops)
+{
+	struct ath_hw *ah = NULL;
+	struct ath_common *common;
+	int ret = 0, i;
+	int csz = 0;
+
+	ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
+	if (!ah)
+		return -ENOMEM;
+
+	ah->hw_version.devid = devid;
+	ah->hw_version.subsysid = subsysid;
+	sc->sc_ah = ah;
+
+	common = ath9k_hw_common(ah);
+	common->ops = &ath9k_common_ops;
+	common->bus_ops = bus_ops;
+	common->ah = ah;
+	common->hw = sc->hw;
+	common->priv = sc;
+	common->debug_mask = ath9k_debug;
+
+	spin_lock_init(&sc->wiphy_lock);
+	spin_lock_init(&sc->sc_resetlock);
+	spin_lock_init(&sc->sc_serial_rw);
+	spin_lock_init(&sc->sc_pm_lock);
+	mutex_init(&sc->mutex);
+	tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
+	tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
+		     (unsigned long)sc);
+
+	/*
+	 * Cache line size is used to size and align various
+	 * structures used to communicate with the hardware.
+	 */
+	ath_read_cachesize(common, &csz);
+	common->cachelsz = csz << 2; /* convert to bytes */
+
+	ret = ath9k_hw_init(ah);
+	if (ret) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to initialize hardware; "
+			  "initialization status: %d\n", ret);
+		goto err_hw;
+	}
+
+	ret = ath9k_init_debug(ah);
+	if (ret) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to create debugfs files\n");
+		goto err_debug;
+	}
+
+	ret = ath9k_init_queues(sc);
+	if (ret)
+		goto err_queues;
+
+	ret =  ath9k_init_btcoex(sc);
+	if (ret)
+		goto err_btcoex;
+
+	ath9k_init_crypto(sc);
+	ath9k_init_channels_rates(sc);
+	ath9k_init_misc(sc);
+
+	return 0;
+
+err_btcoex:
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+		if (ATH_TXQ_SETUP(sc, i))
+			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
+err_queues:
+	ath9k_exit_debug(ah);
+err_debug:
+	ath9k_hw_deinit(ah);
+err_hw:
+	tasklet_kill(&sc->intr_tq);
+	tasklet_kill(&sc->bcon_tasklet);
+
+	kfree(ah);
+	sc->sc_ah = NULL;
+
+	return ret;
+}
+
+void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
+{
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+
+	hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+		IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+		IEEE80211_HW_SIGNAL_DBM |
+		IEEE80211_HW_SUPPORTS_PS |
+		IEEE80211_HW_PS_NULLFUNC_STACK |
+		IEEE80211_HW_SPECTRUM_MGMT |
+		IEEE80211_HW_REPORTS_TX_ACK_STATUS;
+
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
+		 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
+
+	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_MESH_POINT);
+
+	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+
+	hw->queues = 4;
+	hw->max_rates = 4;
+	hw->channel_change_time = 5000;
+	hw->max_listen_interval = 10;
+	hw->max_rate_tries = 10;
+	hw->sta_data_size = sizeof(struct ath_node);
+	hw->vif_data_size = sizeof(struct ath_vif);
+
+	hw->rate_control_algorithm = "ath9k_rate_control";
+
+	if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
+		hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+			&sc->sbands[IEEE80211_BAND_2GHZ];
+	if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
+		hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+			&sc->sbands[IEEE80211_BAND_5GHZ];
+
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
+		if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
+			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);
+	}
+
+	SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
+}
+
+int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
+		    const struct ath_bus_ops *bus_ops)
+{
+	struct ieee80211_hw *hw = sc->hw;
+	struct ath_common *common;
+	struct ath_hw *ah;
+	int error = 0;
+	struct ath_regulatory *reg;
+
+	/* Bring up device */
+	error = ath9k_init_softc(devid, sc, subsysid, bus_ops);
+	if (error != 0)
+		goto error_init;
+
+	ah = sc->sc_ah;
+	common = ath9k_hw_common(ah);
+	ath9k_set_hw_capab(sc, hw);
+
+	/* Initialize regulatory */
+	error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
+			      ath9k_reg_notifier);
+	if (error)
+		goto error_regd;
+
+	reg = &common->regulatory;
+
+	/* Setup TX DMA */
+	error = ath_tx_init(sc, ATH_TXBUF);
+	if (error != 0)
+		goto error_tx;
+
+	/* Setup RX DMA */
+	error = ath_rx_init(sc, ATH_RXBUF);
+	if (error != 0)
+		goto error_rx;
+
+	/* Register with mac80211 */
+	error = ieee80211_register_hw(hw);
+	if (error)
+		goto error_register;
+
+	/* Handle world regulatory */
+	if (!ath_is_world_regd(reg)) {
+		error = regulatory_hint(hw->wiphy, reg->alpha2);
+		if (error)
+			goto error_world;
+	}
+
+	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);
+
+	ath_init_leds(sc);
+	ath_start_rfkill_poll(sc);
+
+	return 0;
+
+error_world:
+	ieee80211_unregister_hw(hw);
+error_register:
+	ath_rx_cleanup(sc);
+error_rx:
+	ath_tx_cleanup(sc);
+error_tx:
+	/* Nothing */
+error_regd:
+	ath9k_deinit_softc(sc);
+error_init:
+	return error;
+}
+
+/*****************************/
+/*     De-Initialization     */
+/*****************************/
+
+static void ath9k_deinit_softc(struct ath_softc *sc)
+{
+	int i = 0;
+
+        if ((sc->btcoex.no_stomp_timer) &&
+	    sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
+		ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
+
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+		if (ATH_TXQ_SETUP(sc, i))
+			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
+
+	ath9k_exit_debug(sc->sc_ah);
+	ath9k_hw_deinit(sc->sc_ah);
+
+	tasklet_kill(&sc->intr_tq);
+	tasklet_kill(&sc->bcon_tasklet);
+}
+
+void ath9k_deinit_device(struct ath_softc *sc)
+{
+	struct ieee80211_hw *hw = sc->hw;
+	int i = 0;
+
+	ath9k_ps_wakeup(sc);
+
+	wiphy_rfkill_stop_polling(sc->hw->wiphy);
+	ath_deinit_leds(sc);
+
+	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);
+	}
+	kfree(sc->sec_wiphy);
+
+	ieee80211_unregister_hw(hw);
+	ath_rx_cleanup(sc);
+	ath_tx_cleanup(sc);
+	ath9k_deinit_softc(sc);
+}
+
+void ath_descdma_cleanup(struct ath_softc *sc,
+			 struct ath_descdma *dd,
+			 struct list_head *head)
+{
+	dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
+			  dd->dd_desc_paddr);
+
+	INIT_LIST_HEAD(head);
+	kfree(dd->dd_bufptr);
+	memset(dd, 0, sizeof(*dd));
+}
+
+/************************/
+/*     Module Hooks     */
+/************************/
+
+static int __init ath9k_init(void)
+{
+	int error;
+
+	/* Register rate control algorithm */
+	error = ath_rate_control_register();
+	if (error != 0) {
+		printk(KERN_ERR
+			"ath9k: Unable to register rate control "
+			"algorithm: %d\n",
+			error);
+		goto err_out;
+	}
+
+	error = ath9k_debug_create_root();
+	if (error) {
+		printk(KERN_ERR
+			"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(ath9k_init);
+
+static void __exit ath9k_exit(void)
+{
+	ath_ahb_exit();
+	ath_pci_exit();
+	ath9k_debug_remove_root();
+	ath_rate_control_unregister();
+	printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
+}
+module_exit(ath9k_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/mac.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/mac.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/mac.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/mac.h	2010-05-16 17:17:36.000000000 -0400
@@ -167,6 +167,40 @@ struct ath_rx_status {
 #define ATH9K_RXKEYIX_INVALID	((u8)-1)
 #define ATH9K_TXKEYIX_INVALID	((u32)-1)
 
+enum ath9k_phyerr {
+	ATH9K_PHYERR_UNDERRUN             = 0,  /* Transmit underrun */
+	ATH9K_PHYERR_TIMING               = 1,  /* Timing error */
+	ATH9K_PHYERR_PARITY               = 2,  /* Illegal parity */
+	ATH9K_PHYERR_RATE                 = 3,  /* Illegal rate */
+	ATH9K_PHYERR_LENGTH               = 4,  /* Illegal length */
+	ATH9K_PHYERR_RADAR                = 5,  /* Radar detect */
+	ATH9K_PHYERR_SERVICE              = 6,  /* Illegal service */
+	ATH9K_PHYERR_TOR                  = 7,  /* Transmit override receive */
+
+	ATH9K_PHYERR_OFDM_TIMING          = 17,
+	ATH9K_PHYERR_OFDM_SIGNAL_PARITY   = 18,
+	ATH9K_PHYERR_OFDM_RATE_ILLEGAL    = 19,
+	ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL  = 20,
+	ATH9K_PHYERR_OFDM_POWER_DROP      = 21,
+	ATH9K_PHYERR_OFDM_SERVICE         = 22,
+	ATH9K_PHYERR_OFDM_RESTART         = 23,
+	ATH9K_PHYERR_FALSE_RADAR_EXT      = 24,
+
+	ATH9K_PHYERR_CCK_TIMING           = 25,
+	ATH9K_PHYERR_CCK_HEADER_CRC       = 26,
+	ATH9K_PHYERR_CCK_RATE_ILLEGAL     = 27,
+	ATH9K_PHYERR_CCK_SERVICE          = 30,
+	ATH9K_PHYERR_CCK_RESTART          = 31,
+	ATH9K_PHYERR_CCK_LENGTH_ILLEGAL   = 32,
+	ATH9K_PHYERR_CCK_POWER_DROP       = 33,
+
+	ATH9K_PHYERR_HT_CRC_ERROR         = 34,
+	ATH9K_PHYERR_HT_LENGTH_ILLEGAL    = 35,
+	ATH9K_PHYERR_HT_RATE_ILLEGAL      = 36,
+
+	ATH9K_PHYERR_MAX                  = 37,
+};
+
 struct ath_desc {
 	u32 ds_link;
 	u32 ds_data;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/main.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/main.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/main.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,118 +18,6 @@
 #include "ath9k.h"
 #include "btcoex.h"
 
-static char *dev_info = "ath9k";
-
-MODULE_AUTHOR("Atheros Communications");
-MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
-MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
-MODULE_LICENSE("Dual BSD/GPL");
-
-static int modparam_nohwcrypt;
-module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
-MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
-
-static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
-module_param_named(debug, ath9k_debug, uint, 0);
-MODULE_PARM_DESC(debug, "Debugging mask");
-
-/* We use the hw_value as an index into our private channel structure */
-
-#define CHAN2G(_freq, _idx)  { \
-	.center_freq = (_freq), \
-	.hw_value = (_idx), \
-	.max_power = 20, \
-}
-
-#define CHAN5G(_freq, _idx) { \
-	.band = IEEE80211_BAND_5GHZ, \
-	.center_freq = (_freq), \
-	.hw_value = (_idx), \
-	.max_power = 20, \
-}
-
-/* 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 */
-};
-
-/* 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 */
-};
-
-/* Atheros hardware rate code addition for short premble */
-#define SHPCHECK(__hw_rate, __flags) \
-	((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
-
-#define RATE(_bitrate, _hw_rate, _flags) {              \
-	.bitrate        = (_bitrate),                   \
-	.flags          = (_flags),                     \
-	.hw_value       = (_hw_rate),                   \
-	.hw_value_short = (SHPCHECK(_hw_rate, _flags))  \
-}
-
-static struct ieee80211_rate ath9k_legacy_rates[] = {
-	RATE(10, 0x1b, 0),
-	RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
-	RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
-	RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
-	RATE(60, 0x0b, 0),
-	RATE(90, 0x0f, 0),
-	RATE(120, 0x0a, 0),
-	RATE(180, 0x0e, 0),
-	RATE(240, 0x09, 0),
-	RATE(360, 0x0d, 0),
-	RATE(480, 0x08, 0),
-	RATE(540, 0x0c, 0),
-};
-
 static void ath_cache_conf_rate(struct ath_softc *sc,
 				struct ieee80211_conf *conf)
 {
@@ -221,7 +109,7 @@ static struct ath9k_channel *ath_get_cur
 	return channel;
 }
 
-static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
+bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
 {
 	unsigned long flags;
 	bool ret;
@@ -255,11 +143,13 @@ void ath9k_ps_restore(struct ath_softc *
 	if (--sc->ps_usecount != 0)
 		goto unlock;
 
-	if (sc->ps_enabled &&
-	    !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
-			      SC_OP_WAIT_FOR_CAB |
-			      SC_OP_WAIT_FOR_PSPOLL_DATA |
-			      SC_OP_WAIT_FOR_TX_ACK)))
+	if (sc->ps_idle)
+		ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
+	else if (sc->ps_enabled &&
+		 !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
+			      PS_WAIT_FOR_CAB |
+			      PS_WAIT_FOR_PSPOLL_DATA |
+			      PS_WAIT_FOR_TX_ACK)))
 		ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
 
  unlock:
@@ -316,7 +206,7 @@ int ath_set_channel(struct ath_softc *sc
 	r = ath9k_hw_reset(ah, hchan, fastcc);
 	if (r) {
 		ath_print(common, ATH_DBG_FATAL,
-			  "Unable to reset channel (%u Mhz) "
+			  "Unable to reset channel (%u MHz), "
 			  "reset status %d\n",
 			  channel->center_freq, r);
 		spin_unlock_bh(&sc->sc_resetlock);
@@ -349,7 +239,7 @@ int ath_set_channel(struct ath_softc *sc
  *  When the task is complete, it reschedules itself depending on the
  *  appropriate interval that was calculated.
  */
-static void ath_ani_calibrate(unsigned long data)
+void ath_ani_calibrate(unsigned long data)
 {
 	struct ath_softc *sc = (struct ath_softc *)data;
 	struct ath_hw *ah = sc->sc_ah;
@@ -363,14 +253,6 @@ static void ath_ani_calibrate(unsigned l
 	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.
-	*/
-	spin_lock(&sc->ani_lock);
-	if (sc->sc_flags & SC_OP_SCANNING)
-		goto set_timer;
-
 	/* Only calibrate if awake */
 	if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE)
 		goto set_timer;
@@ -437,7 +319,6 @@ static void ath_ani_calibrate(unsigned l
 	ath9k_ps_restore(sc);
 
 set_timer:
-	spin_unlock(&sc->ani_lock);
 	/*
 	* Set timer interval based on previous results.
 	* The interval must be the shortest necessary to satisfy ANI,
@@ -513,7 +394,7 @@ static void ath_node_detach(struct ath_s
 		ath_tx_node_cleanup(sc, an);
 }
 
-static void ath9k_tasklet(unsigned long data)
+void ath9k_tasklet(unsigned long data)
 {
 	struct ath_softc *sc = (struct ath_softc *)data;
 	struct ath_hw *ah = sc->sc_ah;
@@ -545,7 +426,7 @@ static void ath9k_tasklet(unsigned long
 		 */
 		ath_print(common, ATH_DBG_PS,
 			  "TSFOOR - Sync with next Beacon\n");
-		sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC;
+		sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
 	}
 
 	if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
@@ -646,7 +527,7 @@ irqreturn_t ath_isr(int irq, void *dev)
 			 * receive frames */
 			ath9k_setpower(sc, ATH9K_PM_AWAKE);
 			ath9k_hw_setrxabort(sc->sc_ah, 0);
-			sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
+			sc->ps_flags |= PS_WAIT_FOR_BEACON;
 		}
 
 chip_reset:
@@ -928,49 +809,12 @@ static void ath_key_delete(struct ath_co
 
 	clear_bit(key->hw_key_idx + 64, common->keymap);
 	if (common->splitmic) {
+		ath9k_hw_keyreset(ah, key->hw_key_idx + 32);
 		clear_bit(key->hw_key_idx + 32, common->keymap);
 		clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
 	}
 }
 
-static void setup_ht_cap(struct ath_softc *sc,
-			 struct ieee80211_sta_ht_cap *ht_info)
-{
-	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-	u8 tx_streams, rx_streams;
-
-	ht_info->ht_supported = true;
-	ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
-		       IEEE80211_HT_CAP_SM_PS |
-		       IEEE80211_HT_CAP_SGI_40 |
-		       IEEE80211_HT_CAP_DSSSCCK40;
-
-	ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
-	ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
-
-	/* set up supported mcs set */
-	memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
-	tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ?
-		     1 : 2;
-	rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ?
-		     1 : 2;
-
-	if (tx_streams != rx_streams) {
-		ath_print(common, ATH_DBG_CONFIG,
-			  "TX streams %d, RX streams: %d\n",
-			  tx_streams, rx_streams);
-		ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
-		ht_info->mcs.tx_params |= ((tx_streams - 1) <<
-				IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
-	}
-
-	ht_info->mcs.rx_mask[0] = 0xff;
-	if (rx_streams >= 2)
-		ht_info->mcs.rx_mask[1] = 0xff;
-
-	ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
-}
-
 static void ath9k_bss_assoc_info(struct ath_softc *sc,
 				 struct ieee80211_vif *vif,
 				 struct ieee80211_bss_conf *bss_conf)
@@ -992,7 +836,7 @@ static void ath9k_bss_assoc_info(struct
 		 * on the receipt of the first Beacon frame (i.e.,
 		 * after time sync with the AP).
 		 */
-		sc->sc_flags |= SC_OP_BEACON_SYNC;
+		sc->ps_flags |= PS_BEACON_SYNC;
 
 		/* Configure the beacon */
 		ath_beacon_config(sc, vif);
@@ -1009,174 +853,6 @@ 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, sc->sc_ah->led_pin, 0);
-	else
-		ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
-				  (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
-
-	ieee80211_queue_delayed_work(sc->hw,
-				     &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)
-{
-	struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
-	struct ath_softc *sc = led->sc;
-
-	switch (brightness) {
-	case LED_OFF:
-		if (led->led_type == ATH_LED_ASSOC ||
-		    led->led_type == ATH_LED_RADIO) {
-			ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
-				(led->led_type == ATH_LED_RADIO));
-			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) {
-			sc->sc_flags |= SC_OP_LED_ASSOCIATED;
-			ieee80211_queue_delayed_work(sc->hw,
-						     &sc->ath_led_blink_work, 0);
-		} else if (led->led_type == ATH_LED_RADIO) {
-			ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
-			sc->sc_flags |= SC_OP_LED_ON;
-		} else {
-			sc->led_on_cnt++;
-		}
-		break;
-	default:
-		break;
-	}
-}
-
-static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
-			    char *trigger)
-{
-	int ret;
-
-	led->sc = sc;
-	led->led_cdev.name = led->name;
-	led->led_cdev.default_trigger = trigger;
-	led->led_cdev.brightness_set = ath_led_brightness;
-
-	ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
-	if (ret)
-		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
-			  "Failed to register led:%s", led->name);
-	else
-		led->registered = 1;
-	return ret;
-}
-
-static void ath_unregister_led(struct ath_led *led)
-{
-	if (led->registered) {
-		led_classdev_unregister(&led->led_cdev);
-		led->registered = 0;
-	}
-}
-
-static void ath_deinit_leds(struct ath_softc *sc)
-{
-	ath_unregister_led(&sc->assoc_led);
-	sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
-	ath_unregister_led(&sc->tx_led);
-	ath_unregister_led(&sc->rx_led);
-	ath_unregister_led(&sc->radio_led);
-	ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
-}
-
-static void ath_init_leds(struct ath_softc *sc)
-{
-	char *trigger;
-	int ret;
-
-	if (AR_SREV_9287(sc->sc_ah))
-		sc->sc_ah->led_pin = ATH_LED_PIN_9287;
-	else
-		sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
-
-	/* Configure gpio 1 for output */
-	ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
-			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-	/* LED off, active low */
-	ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->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));
-	ret = ath_register_led(sc, &sc->radio_led, trigger);
-	sc->radio_led.led_type = ATH_LED_RADIO;
-	if (ret)
-		goto fail;
-
-	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));
-	ret = ath_register_led(sc, &sc->assoc_led, trigger);
-	sc->assoc_led.led_type = ATH_LED_ASSOC;
-	if (ret)
-		goto fail;
-
-	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));
-	ret = ath_register_led(sc, &sc->tx_led, trigger);
-	sc->tx_led.led_type = ATH_LED_TX;
-	if (ret)
-		goto fail;
-
-	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));
-	ret = ath_register_led(sc, &sc->rx_led, trigger);
-	sc->rx_led.led_type = ATH_LED_RX;
-	if (ret)
-		goto fail;
-
-	return;
-
-fail:
-	cancel_delayed_work_sync(&sc->ath_led_blink_work);
-	ath_deinit_leds(sc);
-}
-
 void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
 {
 	struct ath_hw *ah = sc->sc_ah;
@@ -1194,7 +870,7 @@ void ath_radio_enable(struct ath_softc *
 	r = ath9k_hw_reset(ah, ah->curchan, false);
 	if (r) {
 		ath_print(common, ATH_DBG_FATAL,
-			  "Unable to reset channel %u (%uMhz) ",
+			  "Unable to reset channel (%u MHz), "
 			  "reset status %d\n",
 			  channel->center_freq, r);
 	}
@@ -1249,7 +925,7 @@ void ath_radio_disable(struct ath_softc
 	r = ath9k_hw_reset(ah, ah->curchan, false);
 	if (r) {
 		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
-			  "Unable to reset channel %u (%uMhz) "
+			  "Unable to reset channel (%u MHz), "
 			  "reset status %d\n",
 			  channel->center_freq, r);
 	}
@@ -1261,711 +937,6 @@ void ath_radio_disable(struct ath_softc
 	ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
 }
 
-/*******************/
-/*	Rfkill	   */
-/*******************/
-
-static bool ath_is_rfkill_set(struct ath_softc *sc)
-{
-	struct ath_hw *ah = sc->sc_ah;
-
-	return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
-				  ah->rfkill_polarity;
-}
-
-static void ath9k_rfkill_poll_state(struct ieee80211_hw *hw)
-{
-	struct ath_wiphy *aphy = hw->priv;
-	struct ath_softc *sc = aphy->sc;
-	bool blocked = !!ath_is_rfkill_set(sc);
-
-	wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
-}
-
-static void ath_start_rfkill_poll(struct ath_softc *sc)
-{
-	struct ath_hw *ah = sc->sc_ah;
-
-	if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-		wiphy_rfkill_start_polling(sc->hw->wiphy);
-}
-
-static void ath9k_uninit_hw(struct ath_softc *sc)
-{
-	struct ath_hw *ah = sc->sc_ah;
-
-	BUG_ON(!ah);
-
-	ath9k_exit_debug(ah);
-	ath9k_hw_detach(ah);
-	sc->sc_ah = NULL;
-}
-
-static void ath_clean_core(struct ath_softc *sc)
-{
-	struct ieee80211_hw *hw = sc->hw;
-	struct ath_hw *ah = sc->sc_ah;
-	int i = 0;
-
-	ath9k_ps_wakeup(sc);
-
-	dev_dbg(sc->dev, "Detach ATH hw\n");
-
-	ath_deinit_leds(sc);
-	wiphy_rfkill_stop_polling(sc->hw->wiphy);
-
-	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);
-
-	tasklet_kill(&sc->intr_tq);
-	tasklet_kill(&sc->bcon_tasklet);
-
-	if (!(sc->sc_flags & SC_OP_INVALID))
-		ath9k_setpower(sc, ATH9K_PM_AWAKE);
-
-	/* cleanup tx queues */
-	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
-		if (ATH_TXQ_SETUP(sc, i))
-			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
-
-	if ((sc->btcoex.no_stomp_timer) &&
-	    ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
-		ath_gen_timer_free(ah, sc->btcoex.no_stomp_timer);
-}
-
-void ath_detach(struct ath_softc *sc)
-{
-	ath_clean_core(sc);
-	ath9k_uninit_hw(sc);
-}
-
-void ath_cleanup(struct ath_softc *sc)
-{
-	struct ath_hw *ah = sc->sc_ah;
-	struct ath_common *common = ath9k_hw_common(ah);
-
-	ath_clean_core(sc);
-	free_irq(sc->irq, sc);
-	ath_bus_cleanup(common);
-	kfree(sc->sec_wiphy);
-	ieee80211_free_hw(sc->hw);
-
-	ath9k_uninit_hw(sc);
-}
-
-static int ath9k_reg_notifier(struct wiphy *wiphy,
-			      struct regulatory_request *request)
-{
-	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
-	struct ath_wiphy *aphy = hw->priv;
-	struct ath_softc *sc = aphy->sc;
-	struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
-
-	return ath_reg_notifier_apply(wiphy, request, reg);
-}
-
-/*
- * Detects if there is any priority bt traffic
- */
-static void ath_detect_bt_priority(struct ath_softc *sc)
-{
-	struct ath_btcoex *btcoex = &sc->btcoex;
-	struct ath_hw *ah = sc->sc_ah;
-
-	if (ath9k_hw_gpio_get(sc->sc_ah, ah->btcoex_hw.btpriority_gpio))
-		btcoex->bt_priority_cnt++;
-
-	if (time_after(jiffies, btcoex->bt_priority_time +
-			msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
-		if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
-			ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
-				  "BT priority traffic detected");
-			sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
-		} else {
-			sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
-		}
-
-		btcoex->bt_priority_cnt = 0;
-		btcoex->bt_priority_time = jiffies;
-	}
-}
-
-/*
- * Configures appropriate weight based on stomp type.
- */
-static void ath9k_btcoex_bt_stomp(struct ath_softc *sc,
-				  enum ath_stomp_type stomp_type)
-{
-	struct ath_hw *ah = sc->sc_ah;
-
-	switch (stomp_type) {
-	case ATH_BTCOEX_STOMP_ALL:
-		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
-					   AR_STOMP_ALL_WLAN_WGHT);
-		break;
-	case ATH_BTCOEX_STOMP_LOW:
-		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
-					   AR_STOMP_LOW_WLAN_WGHT);
-		break;
-	case ATH_BTCOEX_STOMP_NONE:
-		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
-					   AR_STOMP_NONE_WLAN_WGHT);
-		break;
-	default:
-		ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
-			  "Invalid Stomptype\n");
-		break;
-	}
-
-	ath9k_hw_btcoex_enable(ah);
-}
-
-static void ath9k_gen_timer_start(struct ath_hw *ah,
-				  struct ath_gen_timer *timer,
-				  u32 timer_next,
-				  u32 timer_period)
-{
-	struct ath_common *common = ath9k_hw_common(ah);
-	struct ath_softc *sc = (struct ath_softc *) common->priv;
-
-	ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
-
-	if ((sc->imask & ATH9K_INT_GENTIMER) == 0) {
-		ath9k_hw_set_interrupts(ah, 0);
-		sc->imask |= ATH9K_INT_GENTIMER;
-		ath9k_hw_set_interrupts(ah, sc->imask);
-	}
-}
-
-static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
-{
-	struct ath_common *common = ath9k_hw_common(ah);
-	struct ath_softc *sc = (struct ath_softc *) common->priv;
-	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
-
-	ath9k_hw_gen_timer_stop(ah, timer);
-
-	/* if no timer is enabled, turn off interrupt mask */
-	if (timer_table->timer_mask.val == 0) {
-		ath9k_hw_set_interrupts(ah, 0);
-		sc->imask &= ~ATH9K_INT_GENTIMER;
-		ath9k_hw_set_interrupts(ah, sc->imask);
-	}
-}
-
-/*
- * This is the master bt coex timer which runs for every
- * 45ms, bt traffic will be given priority during 55% of this
- * period while wlan gets remaining 45%
- */
-static void ath_btcoex_period_timer(unsigned long data)
-{
-	struct ath_softc *sc = (struct ath_softc *) data;
-	struct ath_hw *ah = sc->sc_ah;
-	struct ath_btcoex *btcoex = &sc->btcoex;
-
-	ath_detect_bt_priority(sc);
-
-	spin_lock_bh(&btcoex->btcoex_lock);
-
-	ath9k_btcoex_bt_stomp(sc, btcoex->bt_stomp_type);
-
-	spin_unlock_bh(&btcoex->btcoex_lock);
-
-	if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) {
-		if (btcoex->hw_timer_enabled)
-			ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
-
-		ath9k_gen_timer_start(ah,
-				      btcoex->no_stomp_timer,
-				      (ath9k_hw_gettsf32(ah) +
-				       btcoex->btcoex_no_stomp),
-				       btcoex->btcoex_no_stomp * 10);
-		btcoex->hw_timer_enabled = true;
-	}
-
-	mod_timer(&btcoex->period_timer, jiffies +
-				  msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
-}
-
-/*
- * Generic tsf based hw timer which configures weight
- * registers to time slice between wlan and bt traffic
- */
-static void ath_btcoex_no_stomp_timer(void *arg)
-{
-	struct ath_softc *sc = (struct ath_softc *)arg;
-	struct ath_hw *ah = sc->sc_ah;
-	struct ath_btcoex *btcoex = &sc->btcoex;
-
-	ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
-		  "no stomp timer running \n");
-
-	spin_lock_bh(&btcoex->btcoex_lock);
-
-	if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
-		ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE);
-	 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
-		ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW);
-
-	spin_unlock_bh(&btcoex->btcoex_lock);
-}
-
-static int ath_init_btcoex_timer(struct ath_softc *sc)
-{
-	struct ath_btcoex *btcoex = &sc->btcoex;
-
-	btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
-	btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
-		btcoex->btcoex_period / 100;
-
-	setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
-			(unsigned long) sc);
-
-	spin_lock_init(&btcoex->btcoex_lock);
-
-	btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah,
-			ath_btcoex_no_stomp_timer,
-			ath_btcoex_no_stomp_timer,
-			(void *) sc, AR_FIRST_NDP_TIMER);
-
-	if (!btcoex->no_stomp_timer)
-		return -ENOMEM;
-
-	return 0;
-}
-
-/*
- * Read and write, they both share the same lock. We do this to serialize
- * reads and writes on Atheros 802.11n PCI devices only. This is required
- * as the FIFO on these devices can only accept sanely 2 requests. After
- * that the device goes bananas. Serializing the reads/writes prevents this
- * from happening.
- */
-
-static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
-{
-	struct ath_hw *ah = (struct ath_hw *) hw_priv;
-	struct ath_common *common = ath9k_hw_common(ah);
-	struct ath_softc *sc = (struct ath_softc *) common->priv;
-
-	if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
-		unsigned long flags;
-		spin_lock_irqsave(&sc->sc_serial_rw, flags);
-		iowrite32(val, sc->mem + reg_offset);
-		spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
-	} else
-		iowrite32(val, sc->mem + reg_offset);
-}
-
-static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
-{
-	struct ath_hw *ah = (struct ath_hw *) hw_priv;
-	struct ath_common *common = ath9k_hw_common(ah);
-	struct ath_softc *sc = (struct ath_softc *) common->priv;
-	u32 val;
-
-	if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
-		unsigned long flags;
-		spin_lock_irqsave(&sc->sc_serial_rw, flags);
-		val = ioread32(sc->mem + reg_offset);
-		spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
-	} else
-		val = ioread32(sc->mem + reg_offset);
-	return val;
-}
-
-static const struct ath_ops ath9k_common_ops = {
-	.read = ath9k_ioread32,
-	.write = ath9k_iowrite32,
-};
-
-/*
- * Initialize and fill ath_softc, ath_sofct is the
- * "Software Carrier" struct. Historically it has existed
- * to allow the separation between hardware specific
- * variables (now in ath_hw) and driver specific variables.
- */
-static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
-			  const struct ath_bus_ops *bus_ops)
-{
-	struct ath_hw *ah = NULL;
-	struct ath_common *common;
-	int r = 0, i;
-	int csz = 0;
-	int qnum;
-
-	/* XXX: hardware will not be ready until ath_open() being called */
-	sc->sc_flags |= SC_OP_INVALID;
-
-	spin_lock_init(&sc->wiphy_lock);
-	spin_lock_init(&sc->sc_resetlock);
-	spin_lock_init(&sc->sc_serial_rw);
-	spin_lock_init(&sc->ani_lock);
-	spin_lock_init(&sc->sc_pm_lock);
-	mutex_init(&sc->mutex);
-	tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
-	tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
-		     (unsigned long)sc);
-
-	ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
-	if (!ah)
-		return -ENOMEM;
-
-	ah->hw_version.devid = devid;
-	ah->hw_version.subsysid = subsysid;
-	sc->sc_ah = ah;
-
-	common = ath9k_hw_common(ah);
-	common->ops = &ath9k_common_ops;
-	common->bus_ops = bus_ops;
-	common->ah = ah;
-	common->hw = sc->hw;
-	common->priv = sc;
-	common->debug_mask = ath9k_debug;
-
-	/*
-	 * Cache line size is used to size and align various
-	 * structures used to communicate with the hardware.
-	 */
-	ath_read_cachesize(common, &csz);
-	/* XXX assert csz is non-zero */
-	common->cachelsz = csz << 2;	/* convert to bytes */
-
-	r = ath9k_hw_init(ah);
-	if (r) {
-		ath_print(common, ATH_DBG_FATAL,
-			  "Unable to initialize hardware; "
-			  "initialization status: %d\n", r);
-		goto bad_free_hw;
-	}
-
-	if (ath9k_init_debug(ah) < 0) {
-		ath_print(common, ATH_DBG_FATAL,
-			  "Unable to create debugfs files\n");
-		goto bad_free_hw;
-	}
-
-	/* Get the hardware key cache size. */
-	common->keymax = ah->caps.keycache_size;
-	if (common->keymax > ATH_KEYMAX) {
-		ath_print(common, ATH_DBG_ANY,
-			  "Warning, using only %u entries in %u key cache\n",
-			  ATH_KEYMAX, common->keymax);
-		common->keymax = ATH_KEYMAX;
-	}
-
-	/*
-	 * Reset the key cache since some parts do not
-	 * reset the contents on initial power up.
-	 */
-	for (i = 0; i < common->keymax; i++)
-		ath9k_hw_keyreset(ah, (u16) i);
-
-	/* default to MONITOR mode */
-	sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
-
-	/*
-	 * Allocate hardware transmit queues: one queue for
-	 * beacon frames and one data queue for each QoS
-	 * priority.  Note that the hal handles reseting
-	 * these queues at the needed time.
-	 */
-	sc->beacon.beaconq = ath9k_hw_beaconq_setup(ah);
-	if (sc->beacon.beaconq == -1) {
-		ath_print(common, ATH_DBG_FATAL,
-			  "Unable to setup a beacon xmit queue\n");
-		r = -EIO;
-		goto bad2;
-	}
-	sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
-	if (sc->beacon.cabq == NULL) {
-		ath_print(common, ATH_DBG_FATAL,
-			  "Unable to setup CAB xmit queue\n");
-		r = -EIO;
-		goto bad2;
-	}
-
-	sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
-	ath_cabq_update(sc);
-
-	for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
-		sc->tx.hwq_map[i] = -1;
-
-	/* Setup data queues */
-	/* NB: ensure BK queue is the lowest priority h/w queue */
-	if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
-		ath_print(common, ATH_DBG_FATAL,
-			  "Unable to setup xmit queue for BK traffic\n");
-		r = -EIO;
-		goto bad2;
-	}
-
-	if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
-		ath_print(common, ATH_DBG_FATAL,
-			  "Unable to setup xmit queue for BE traffic\n");
-		r = -EIO;
-		goto bad2;
-	}
-	if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
-		ath_print(common, ATH_DBG_FATAL,
-			  "Unable to setup xmit queue for VI traffic\n");
-		r = -EIO;
-		goto bad2;
-	}
-	if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
-		ath_print(common, ATH_DBG_FATAL,
-			  "Unable to setup xmit queue for VO traffic\n");
-		r = -EIO;
-		goto bad2;
-	}
-
-	/* Initializes the noise floor to a reasonable default value.
-	 * Later on this will be updated during ANI processing. */
-
-	common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
-	setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
-
-	if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
-				   ATH9K_CIPHER_TKIP, NULL)) {
-		/*
-		 * Whether we should enable h/w TKIP MIC.
-		 * XXX: if we don't support WME TKIP MIC, then we wouldn't
-		 * report WMM capable, so it's always safe to turn on
-		 * TKIP MIC in this case.
-		 */
-		ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC,
-				       0, 1, NULL);
-	}
-
-	/*
-	 * Check whether the separate key cache entries
-	 * are required to handle both tx+rx MIC keys.
-	 * With split mic keys the number of stations is limited
-	 * to 27 otherwise 59.
-	 */
-	if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
-				   ATH9K_CIPHER_TKIP, NULL)
-	    && ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
-				      ATH9K_CIPHER_MIC, NULL)
-	    && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT,
-				      0, NULL))
-		common->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->config.txpowlimit = ATH_TXPOWER_MAX;
-
-	/* 11n Capabilities */
-	if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
-		sc->sc_flags |= SC_OP_TXAGGR;
-		sc->sc_flags |= SC_OP_RXAGGR;
-	}
-
-	common->tx_chainmask = ah->caps.tx_chainmask;
-	common->rx_chainmask = ah->caps.rx_chainmask;
-
-	ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
-	sc->rx.defant = ath9k_hw_getdefantenna(ah);
-
-	if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
-		memcpy(common->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] = NULL;
-		sc->beacon.bslot_aphy[i] = NULL;
-	}
-
-	/* setup channels and rates */
-
-	if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) {
-		sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
-		sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
-		sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
-			ARRAY_SIZE(ath9k_2ghz_chantable);
-		sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
-		sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
-			ARRAY_SIZE(ath9k_legacy_rates);
-	}
-
-	if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
-		sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
-		sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
-		sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
-			ARRAY_SIZE(ath9k_5ghz_chantable);
-		sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
-			ath9k_legacy_rates + 4;
-		sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
-			ARRAY_SIZE(ath9k_legacy_rates) - 4;
-	}
-
-	switch (ah->btcoex_hw.scheme) {
-	case ATH_BTCOEX_CFG_NONE:
-		break;
-	case ATH_BTCOEX_CFG_2WIRE:
-		ath9k_hw_btcoex_init_2wire(ah);
-		break;
-	case ATH_BTCOEX_CFG_3WIRE:
-		ath9k_hw_btcoex_init_3wire(ah);
-		r = ath_init_btcoex_timer(sc);
-		if (r)
-			goto bad2;
-		qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
-		ath9k_hw_init_btcoex_hw(ah, qnum);
-		sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
-		break;
-	default:
-		WARN_ON(1);
-		break;
-	}
-
-	return 0;
-bad2:
-	/* cleanup tx queues */
-	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
-		if (ATH_TXQ_SETUP(sc, i))
-			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
-
-bad_free_hw:
-	ath9k_uninit_hw(sc);
-	return r;
-}
-
-void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
-{
-	hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
-		IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-		IEEE80211_HW_SIGNAL_DBM |
-		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_MESH_POINT);
-
-	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
-
-	hw->queues = 4;
-	hw->max_rates = 4;
-	hw->channel_change_time = 5000;
-	hw->max_listen_interval = 10;
-	/* Hardware supports 10 but we use 4 */
-	hw->max_rate_tries = 4;
-	hw->sta_data_size = sizeof(struct ath_node);
-	hw->vif_data_size = sizeof(struct ath_vif);
-
-	hw->rate_control_algorithm = "ath9k_rate_control";
-
-	if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
-		hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
-			&sc->sbands[IEEE80211_BAND_2GHZ];
-	if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
-		hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
-			&sc->sbands[IEEE80211_BAND_5GHZ];
-}
-
-/* Device driver core initialization */
-int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
-		    const struct ath_bus_ops *bus_ops)
-{
-	struct ieee80211_hw *hw = sc->hw;
-	struct ath_common *common;
-	struct ath_hw *ah;
-	int error = 0, i;
-	struct ath_regulatory *reg;
-
-	dev_dbg(sc->dev, "Attach ATH hw\n");
-
-	error = ath_init_softc(devid, sc, subsysid, bus_ops);
-	if (error != 0)
-		return error;
-
-	ah = sc->sc_ah;
-	common = ath9k_hw_common(ah);
-
-	/* get mac address from hardware and set in mac80211 */
-
-	SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
-
-	ath_set_hw_capab(sc, hw);
-
-	error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
-			      ath9k_reg_notifier);
-	if (error)
-		return error;
-
-	reg = &common->regulatory;
-
-	if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
-		if (test_bit(ATH9K_MODE_11G, ah->caps.wireless_modes))
-			setup_ht_cap(sc,
-				     &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
-		if (test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes))
-			setup_ht_cap(sc,
-				     &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
-	}
-
-	/* initialize tx/rx engine */
-	error = ath_tx_init(sc, ATH_TXBUF);
-	if (error != 0)
-		goto error_attach;
-
-	error = ath_rx_init(sc, ATH_RXBUF);
-	if (error != 0)
-		goto error_attach;
-
-	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 (!ath_is_world_regd(reg)) {
-		error = regulatory_hint(hw->wiphy, reg->alpha2);
-		if (error)
-			goto error_attach;
-	}
-
-	/* Initialize LED control */
-	ath_init_leds(sc);
-
-	ath_start_rfkill_poll(sc);
-
-	return 0;
-
-error_attach:
-	/* cleanup tx queues */
-	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
-		if (ATH_TXQ_SETUP(sc, i))
-			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
-
-	ath9k_uninit_hw(sc);
-
-	return error;
-}
-
 int ath_reset(struct ath_softc *sc, bool retry_tx)
 {
 	struct ath_hw *ah = sc->sc_ah;
@@ -1976,6 +947,8 @@ int ath_reset(struct ath_softc *sc, bool
 	/* Stop ANI */
 	del_timer_sync(&common->ani.timer);
 
+	ieee80211_stop_queues(hw);
+
 	ath9k_hw_set_interrupts(ah, 0);
 	ath_drain_all_txq(sc, retry_tx);
 	ath_stoprecv(sc);
@@ -2017,131 +990,14 @@ int ath_reset(struct ath_softc *sc, bool
 		}
 	}
 
+	ieee80211_wake_queues(hw);
+
 	/* Start ANI */
 	ath_start_ani(common);
 
 	return r;
 }
 
-/*
- *  This function will allocate both the DMA descriptor structure, and the
- *  buffers it contains.  These are used to contain the descriptors used
- *  by the system.
-*/
-int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
-		      struct list_head *head, const char *name,
-		      int nbuf, int ndesc)
-{
-#define	DS2PHYS(_dd, _ds)						\
-	((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
-#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
-#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
-	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-	struct ath_desc *ds;
-	struct ath_buf *bf;
-	int i, bsize, error;
-
-	ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
-		  name, nbuf, ndesc);
-
-	INIT_LIST_HEAD(head);
-	/* ath_desc must be a multiple of DWORDs */
-	if ((sizeof(struct ath_desc) % 4) != 0) {
-		ath_print(common, ATH_DBG_FATAL,
-			  "ath_desc not DWORD aligned\n");
-		BUG_ON((sizeof(struct ath_desc) % 4) != 0);
-		error = -ENOMEM;
-		goto fail;
-	}
-
-	dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
-
-	/*
-	 * Need additional DMA memory because we can't use
-	 * descriptors that cross the 4K page boundary. Assume
-	 * one skipped descriptor per 4K page.
-	 */
-	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;
-
-		while (ndesc_skipped) {
-			dma_len = ndesc_skipped * sizeof(struct ath_desc);
-			dd->dd_desc_len += dma_len;
-
-			ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
-		};
-	}
-
-	/* allocate descriptors */
-	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;
-	}
-	ds = dd->dd_desc;
-	ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
-		  name, ds, (u32) dd->dd_desc_len,
-		  ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
-
-	/* allocate buffers */
-	bsize = sizeof(struct ath_buf) * nbuf;
-	bf = kzalloc(bsize, GFP_KERNEL);
-	if (bf == NULL) {
-		error = -ENOMEM;
-		goto fail2;
-	}
-	dd->dd_bufptr = bf;
-
-	for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
-		bf->bf_desc = ds;
-		bf->bf_daddr = DS2PHYS(dd, ds);
-
-		if (!(sc->sc_ah->caps.hw_caps &
-		      ATH9K_HW_CAP_4KB_SPLITTRANS)) {
-			/*
-			 * Skip descriptor addresses which can cause 4KB
-			 * boundary crossing (addr + length) with a 32 dword
-			 * descriptor fetch.
-			 */
-			while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
-				BUG_ON((caddr_t) bf->bf_desc >=
-				       ((caddr_t) dd->dd_desc +
-					dd->dd_desc_len));
-
-				ds += ndesc;
-				bf->bf_desc = ds;
-				bf->bf_daddr = DS2PHYS(dd, ds);
-			}
-		}
-		list_add_tail(&bf->list, head);
-	}
-	return 0;
-fail2:
-	dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
-			  dd->dd_desc_paddr);
-fail:
-	memset(dd, 0, sizeof(*dd));
-	return error;
-#undef ATH_DESC_4KB_BOUND_CHECK
-#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
-#undef DS2PHYS
-}
-
-void ath_descdma_cleanup(struct ath_softc *sc,
-			 struct ath_descdma *dd,
-			 struct list_head *head)
-{
-	dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
-			  dd->dd_desc_paddr);
-
-	INIT_LIST_HEAD(head);
-	kfree(dd->dd_bufptr);
-	memset(dd, 0, sizeof(*dd));
-}
-
 int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
 {
 	int qnum;
@@ -2220,28 +1076,6 @@ void ath9k_update_ichannel(struct ath_so
 /* mac80211 callbacks */
 /**********************/
 
-/*
- * (Re)start btcoex timers
- */
-static void ath9k_btcoex_timer_resume(struct ath_softc *sc)
-{
-	struct ath_btcoex *btcoex = &sc->btcoex;
-	struct ath_hw *ah = sc->sc_ah;
-
-	ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
-		  "Starting btcoex timers");
-
-	/* make sure duty cycle timer is also stopped when resuming */
-	if (btcoex->hw_timer_enabled)
-		ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
-
-	btcoex->bt_priority_cnt = 0;
-	btcoex->bt_priority_time = jiffies;
-	sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
-
-	mod_timer(&btcoex->period_timer, jiffies);
-}
-
 static int ath9k_start(struct ieee80211_hw *hw)
 {
 	struct ath_wiphy *aphy = hw->priv;
@@ -2411,11 +1245,11 @@ static int ath9k_tx(struct ieee80211_hw
 		if (ieee80211_is_pspoll(hdr->frame_control)) {
 			ath_print(common, ATH_DBG_PS,
 				  "Sending PS-Poll to pick a buffered frame\n");
-			sc->sc_flags |= SC_OP_WAIT_FOR_PSPOLL_DATA;
+			sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA;
 		} else {
 			ath_print(common, ATH_DBG_PS,
 				  "Wake up to complete TX\n");
-			sc->sc_flags |= SC_OP_WAIT_FOR_TX_ACK;
+			sc->ps_flags |= PS_WAIT_FOR_TX_ACK;
 		}
 		/*
 		 * The actual restore operation will happen only after
@@ -2468,22 +1302,6 @@ exit:
 	return 0;
 }
 
-/*
- * Pause btcoex timer and bt duty cycle timer
- */
-static void ath9k_btcoex_timer_pause(struct ath_softc *sc)
-{
-	struct ath_btcoex *btcoex = &sc->btcoex;
-	struct ath_hw *ah = sc->sc_ah;
-
-	del_timer_sync(&btcoex->period_timer);
-
-	if (btcoex->hw_timer_enabled)
-		ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
-
-	btcoex->hw_timer_enabled = false;
-}
-
 static void ath9k_stop(struct ieee80211_hw *hw)
 {
 	struct ath_wiphy *aphy = hw->priv;
@@ -2550,12 +1368,12 @@ static void ath9k_stop(struct ieee80211_
 }
 
 static int ath9k_add_interface(struct ieee80211_hw *hw,
-			       struct ieee80211_if_init_conf *conf)
+			       struct ieee80211_vif *vif)
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-	struct ath_vif *avp = (void *)conf->vif->drv_priv;
+	struct ath_vif *avp = (void *)vif->drv_priv;
 	enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
 	int ret = 0;
 
@@ -2567,7 +1385,7 @@ static int ath9k_add_interface(struct ie
 		goto out;
 	}
 
-	switch (conf->type) {
+	switch (vif->type) {
 	case NL80211_IFTYPE_STATION:
 		ic_opmode = NL80211_IFTYPE_STATION;
 		break;
@@ -2578,11 +1396,11 @@ static int ath9k_add_interface(struct ie
 			ret = -ENOBUFS;
 			goto out;
 		}
-		ic_opmode = conf->type;
+		ic_opmode = vif->type;
 		break;
 	default:
 		ath_print(common, ATH_DBG_FATAL,
-			"Interface type %d not yet supported\n", conf->type);
+			"Interface type %d not yet supported\n", vif->type);
 		ret = -EOPNOTSUPP;
 		goto out;
 	}
@@ -2614,18 +1432,18 @@ static int ath9k_add_interface(struct ie
 	 * 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 ((vif->type == NL80211_IFTYPE_STATION) ||
+	    (vif->type == NL80211_IFTYPE_ADHOC) ||
+	    (vif->type == NL80211_IFTYPE_MESH_POINT)) {
 		sc->imask |= ATH9K_INT_MIB;
 		sc->imask |= ATH9K_INT_TSFOOR;
 	}
 
 	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
 
-	if (conf->type == NL80211_IFTYPE_AP    ||
-	    conf->type == NL80211_IFTYPE_ADHOC ||
-	    conf->type == NL80211_IFTYPE_MONITOR)
+	if (vif->type == NL80211_IFTYPE_AP    ||
+	    vif->type == NL80211_IFTYPE_ADHOC ||
+	    vif->type == NL80211_IFTYPE_MONITOR)
 		ath_start_ani(common);
 
 out:
@@ -2634,12 +1452,12 @@ out:
 }
 
 static void ath9k_remove_interface(struct ieee80211_hw *hw,
-				   struct ieee80211_if_init_conf *conf)
+				   struct ieee80211_vif *vif)
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-	struct ath_vif *avp = (void *)conf->vif->drv_priv;
+	struct ath_vif *avp = (void *)vif->drv_priv;
 	int i;
 
 	ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
@@ -2662,7 +1480,7 @@ static void ath9k_remove_interface(struc
 	sc->sc_flags &= ~SC_OP_BEACONS;
 
 	for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
-		if (sc->beacon.bslot[i] == conf->vif) {
+		if (sc->beacon.bslot[i] == vif) {
 			printk(KERN_DEBUG "%s: vif had allocated beacon "
 			       "slot\n", __func__);
 			sc->beacon.bslot[i] = NULL;
@@ -2675,6 +1493,19 @@ static void ath9k_remove_interface(struc
 	mutex_unlock(&sc->mutex);
 }
 
+void ath9k_enable_ps(struct ath_softc *sc)
+{
+	sc->ps_enabled = true;
+	if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+		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);
+}
+
 static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 {
 	struct ath_wiphy *aphy = hw->priv;
@@ -2701,8 +1532,7 @@ static int ath9k_config(struct ieee80211
 		all_wiphys_idle =  ath9k_all_wiphys_idle(sc);
 		ath9k_set_wiphy_idle(aphy, idle);
 
-		if (!idle && all_wiphys_idle)
-			enable_radio = true;
+		enable_radio = (!idle && all_wiphys_idle);
 
 		/*
 		 * After we unlock here its possible another wiphy
@@ -2713,6 +1543,7 @@ static int ath9k_config(struct ieee80211
 		spin_unlock_bh(&sc->wiphy_lock);
 
 		if (enable_radio) {
+			sc->ps_idle = false;
 			ath_radio_enable(sc, hw);
 			ath_print(common, ATH_DBG_CONFIG,
 				  "not-idle: enabling radio\n");
@@ -2727,36 +1558,27 @@ static int ath9k_config(struct ieee80211
 	 */
 	if (changed & IEEE80211_CONF_CHANGE_PS) {
 		if (conf->flags & IEEE80211_CONF_PS) {
-			sc->sc_flags |= SC_OP_PS_ENABLED;
-			if (!(ah->caps.hw_caps &
-			      ATH9K_HW_CAP_AUTOSLEEP)) {
-				if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
-					sc->imask |= ATH9K_INT_TIM_TIMER;
-					ath9k_hw_set_interrupts(sc->sc_ah,
-							sc->imask);
-				}
-			}
+			sc->ps_flags |= PS_ENABLED;
 			/*
 			 * At this point we know hardware has received an ACK
 			 * of a previously sent null data frame.
 			 */
-			if ((sc->sc_flags & SC_OP_NULLFUNC_COMPLETED)) {
-				sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED;
-				sc->ps_enabled = true;
-				ath9k_hw_setrxabort(sc->sc_ah, 1);
+			if ((sc->ps_flags & PS_NULLFUNC_COMPLETED)) {
+				sc->ps_flags &= ~PS_NULLFUNC_COMPLETED;
+				ath9k_enable_ps(sc);
                         }
 		} else {
 			sc->ps_enabled = false;
-			sc->sc_flags &= ~(SC_OP_PS_ENABLED |
-					  SC_OP_NULLFUNC_COMPLETED);
+			sc->ps_flags &= ~(PS_ENABLED |
+					  PS_NULLFUNC_COMPLETED);
 			ath9k_setpower(sc, ATH9K_PM_AWAKE);
 			if (!(ah->caps.hw_caps &
 			      ATH9K_HW_CAP_AUTOSLEEP)) {
 				ath9k_hw_setrxabort(sc->sc_ah, 0);
-				sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON |
-						  SC_OP_WAIT_FOR_CAB |
-						  SC_OP_WAIT_FOR_PSPOLL_DATA |
-						  SC_OP_WAIT_FOR_TX_ACK);
+				sc->ps_flags &= ~(PS_WAIT_FOR_BEACON |
+						  PS_WAIT_FOR_CAB |
+						  PS_WAIT_FOR_PSPOLL_DATA |
+						  PS_WAIT_FOR_TX_ACK);
 				if (sc->imask & ATH9K_INT_TIM_TIMER) {
 					sc->imask &= ~ATH9K_INT_TIM_TIMER;
 					ath9k_hw_set_interrupts(sc->sc_ah,
@@ -2766,6 +1588,14 @@ static int ath9k_config(struct ieee80211
 		}
 	}
 
+	if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
+		if (conf->flags & IEEE80211_CONF_MONITOR) {
+			ath_print(common, ATH_DBG_CONFIG,
+				  "HW opmode set to Monitor mode\n");
+			sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
+		}
+	}
+
 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
 		struct ieee80211_channel *curchan = hw->conf.channel;
 		int pos = curchan->hw_value;
@@ -2801,8 +1631,10 @@ static int ath9k_config(struct ieee80211
 	}
 
 skip_chan_change:
-	if (changed & IEEE80211_CONF_CHANGE_POWER)
+	if (changed & IEEE80211_CONF_CHANGE_POWER) {
 		sc->config.txpowlimit = 2 * conf->power_level;
+		ath_update_txpow(sc);
+	}
 
 	spin_lock_bh(&sc->wiphy_lock);
 	disable_radio = ath9k_all_wiphys_idle(sc);
@@ -2810,6 +1642,7 @@ skip_chan_change:
 
 	if (disable_radio) {
 		ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
+		sc->ps_idle = true;
 		ath_radio_disable(sc, hw);
 	}
 
@@ -2850,24 +1683,28 @@ static void ath9k_configure_filter(struc
 		  "Set HW RX filter: 0x%x\n", rfilt);
 }
 
-static void ath9k_sta_notify(struct ieee80211_hw *hw,
-			     struct ieee80211_vif *vif,
-			     enum sta_notify_cmd cmd,
-			     struct ieee80211_sta *sta)
+static int ath9k_sta_add(struct ieee80211_hw *hw,
+			 struct ieee80211_vif *vif,
+			 struct ieee80211_sta *sta)
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
 
-	switch (cmd) {
-	case STA_NOTIFY_ADD:
-		ath_node_attach(sc, sta);
-		break;
-	case STA_NOTIFY_REMOVE:
-		ath_node_detach(sc, sta);
-		break;
-	default:
-		break;
-	}
+	ath_node_attach(sc, sta);
+
+	return 0;
+}
+
+static int ath9k_sta_remove(struct ieee80211_hw *hw,
+			    struct ieee80211_vif *vif,
+			    struct ieee80211_sta *sta)
+{
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+
+	ath_node_detach(sc, sta);
+
+	return 0;
 }
 
 static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
@@ -2966,6 +1803,7 @@ static void ath9k_bss_info_changed(struc
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_vif *avp = (void *)vif->drv_priv;
+	int slottime;
 	int error;
 
 	mutex_lock(&sc->mutex);
@@ -3001,6 +1839,25 @@ static void ath9k_bss_info_changed(struc
 			ath_beacon_config(sc, vif);
 	}
 
+	if (changed & BSS_CHANGED_ERP_SLOT) {
+		if (bss_conf->use_short_slot)
+			slottime = 9;
+		else
+			slottime = 20;
+		if (vif->type == NL80211_IFTYPE_AP) {
+			/*
+			 * Defer update, so that connected stations can adjust
+			 * their settings at the same time.
+			 * See beacon.c for more details
+			 */
+			sc->beacon.slottime = slottime;
+			sc->beacon.updateslot = UPDATE;
+		} else {
+			ah->slottime = slottime;
+			ath9k_hw_init_global_settings(ah);
+		}
+	}
+
 	/* Disable transmission of beacons */
 	if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon)
 		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
@@ -3133,6 +1990,7 @@ static void ath9k_sw_scan_start(struct i
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 
 	mutex_lock(&sc->mutex);
 	if (ath9k_wiphy_scanning(sc)) {
@@ -3148,10 +2006,9 @@ static void ath9k_sw_scan_start(struct i
 
 	aphy->state = ATH_WIPHY_SCAN;
 	ath9k_wiphy_pause_all_forced(sc, aphy);
-
-	spin_lock_bh(&sc->ani_lock);
 	sc->sc_flags |= SC_OP_SCANNING;
-	spin_unlock_bh(&sc->ani_lock);
+	del_timer_sync(&common->ani.timer);
+	cancel_delayed_work_sync(&sc->tx_complete_work);
 	mutex_unlock(&sc->mutex);
 }
 
@@ -3159,17 +2016,30 @@ static void ath9k_sw_scan_complete(struc
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 
 	mutex_lock(&sc->mutex);
-	spin_lock_bh(&sc->ani_lock);
 	aphy->state = ATH_WIPHY_ACTIVE;
 	sc->sc_flags &= ~SC_OP_SCANNING;
 	sc->sc_flags |= SC_OP_FULL_RESET;
-	spin_unlock_bh(&sc->ani_lock);
+	ath_start_ani(common);
+	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
 	ath_beacon_config(sc, NULL);
 	mutex_unlock(&sc->mutex);
 }
 
+static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
+{
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+	struct ath_hw *ah = sc->sc_ah;
+
+	mutex_lock(&sc->mutex);
+	ah->coverage_class = coverage_class;
+	ath9k_hw_init_global_settings(ah);
+	mutex_unlock(&sc->mutex);
+}
+
 struct ieee80211_ops ath9k_ops = {
 	.tx 		    = ath9k_tx,
 	.start 		    = ath9k_start,
@@ -3178,7 +2048,8 @@ struct ieee80211_ops ath9k_ops = {
 	.remove_interface   = ath9k_remove_interface,
 	.config 	    = ath9k_config,
 	.configure_filter   = ath9k_configure_filter,
-	.sta_notify         = ath9k_sta_notify,
+	.sta_add	    = ath9k_sta_add,
+	.sta_remove	    = ath9k_sta_remove,
 	.conf_tx 	    = ath9k_conf_tx,
 	.bss_info_changed   = ath9k_bss_info_changed,
 	.set_key            = ath9k_set_key,
@@ -3189,64 +2060,5 @@ struct ieee80211_ops ath9k_ops = {
 	.sw_scan_start      = ath9k_sw_scan_start,
 	.sw_scan_complete   = ath9k_sw_scan_complete,
 	.rfkill_poll        = ath9k_rfkill_poll_state,
+	.set_coverage_class = ath9k_set_coverage_class,
 };
-
-static int __init ath9k_init(void)
-{
-	int error;
-
-	/* Register rate control algorithm */
-	error = ath_rate_control_register();
-	if (error != 0) {
-		printk(KERN_ERR
-			"ath9k: Unable to register rate control "
-			"algorithm: %d\n",
-			error);
-		goto err_out;
-	}
-
-	error = ath9k_debug_create_root();
-	if (error) {
-		printk(KERN_ERR
-			"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(ath9k_init);
-
-static void __exit ath9k_exit(void)
-{
-	ath_ahb_exit();
-	ath_pci_exit();
-	ath9k_debug_remove_root();
-	ath_rate_control_unregister();
-	printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
-}
-module_exit(ath9k_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/Makefile linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,6 @@
 ath9k-y +=	beacon.o \
+		gpio.o \
+		init.o \
 		main.o \
 		recv.o \
 		xmit.o \
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/pci.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/pci.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,13 +18,14 @@
 #include <linux/pci.h>
 #include "ath9k.h"
 
-static struct pci_device_id ath_pci_id_table[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
 	{ 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 */
+	{ PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
 	{ PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI   */
 	{ PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
 	{ 0 }
@@ -49,16 +50,6 @@ static void ath_pci_read_cachesize(struc
 		*csz = DEFAULT_CACHELINE >> 2;   /* Use the default size */
 }
 
-static void ath_pci_cleanup(struct ath_common *common)
-{
-	struct ath_softc *sc = (struct ath_softc *) common->priv;
-	struct pci_dev *pdev = to_pci_dev(sc->dev);
-
-	pci_iounmap(pdev, sc->mem);
-	pci_disable_device(pdev);
-	pci_release_region(pdev, 0);
-}
-
 static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
 {
 	struct ath_hw *ah = (struct ath_hw *) common->ah;
@@ -98,7 +89,6 @@ static void ath_pci_bt_coex_prep(struct
 
 static const struct ath_bus_ops ath_pci_bus_ops = {
 	.read_cachesize = ath_pci_read_cachesize,
-	.cleanup = ath_pci_cleanup,
 	.eeprom_read = ath_pci_eeprom_read,
 	.bt_coex_prep = ath_pci_bt_coex_prep,
 };
@@ -113,25 +103,22 @@ static int ath_pci_probe(struct pci_dev
 	u16 subsysid;
 	u32 val;
 	int ret = 0;
-	struct ath_hw *ah;
 	char hw_name[64];
 
 	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;
+		goto err_dma;
 	}
 
 	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;
+		goto err_dma;
 	}
 
 	/*
@@ -171,22 +158,22 @@ static int ath_pci_probe(struct pci_dev
 	if (ret) {
 		dev_err(&pdev->dev, "PCI memory region reserve error\n");
 		ret = -ENODEV;
-		goto bad;
+		goto err_region;
 	}
 
 	mem = pci_iomap(pdev, 0, 0);
 	if (!mem) {
 		printk(KERN_ERR "PCI memory map error\n") ;
 		ret = -EIO;
-		goto bad1;
+		goto err_iomap;
 	}
 
 	hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
 				sizeof(struct ath_softc), &ath9k_ops);
 	if (!hw) {
-		dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
+		dev_err(&pdev->dev, "No memory for ieee80211_hw\n");
 		ret = -ENOMEM;
-		goto bad2;
+		goto err_alloc_hw;
 	}
 
 	SET_IEEE80211_DEV(hw, &pdev->dev);
@@ -201,25 +188,25 @@ static int ath_pci_probe(struct pci_dev
 	sc->dev = &pdev->dev;
 	sc->mem = mem;
 
-	pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid);
-	ret = ath_init_device(id->device, sc, subsysid, &ath_pci_bus_ops);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to initialize device\n");
-		goto bad3;
-	}
-
-	/* setup interrupt service routine */
+	/* Will be cleared in ath9k_start() */
+	sc->sc_flags |= SC_OP_INVALID;
 
 	ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc);
 	if (ret) {
 		dev_err(&pdev->dev, "request_irq failed\n");
-		goto bad4;
+		goto err_irq;
 	}
 
 	sc->irq = pdev->irq;
 
-	ah = sc->sc_ah;
-	ath9k_hw_name(ah, hw_name, sizeof(hw_name));
+	pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid);
+	ret = ath9k_init_device(id->device, sc, subsysid, &ath_pci_bus_ops);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to initialize device\n");
+		goto err_init;
+	}
+
+	ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name));
 	printk(KERN_INFO
 	       "%s: %s mem=0x%lx, irq=%d\n",
 	       wiphy_name(hw->wiphy),
@@ -227,15 +214,18 @@ static int ath_pci_probe(struct pci_dev
 	       (unsigned long)mem, pdev->irq);
 
 	return 0;
-bad4:
-	ath_detach(sc);
-bad3:
+
+err_init:
+	free_irq(sc->irq, sc);
+err_irq:
 	ieee80211_free_hw(hw);
-bad2:
+err_alloc_hw:
 	pci_iounmap(pdev, mem);
-bad1:
+err_iomap:
 	pci_release_region(pdev, 0);
-bad:
+err_region:
+	/* Nothing */
+err_dma:
 	pci_disable_device(pdev);
 	return ret;
 }
@@ -245,8 +235,15 @@ static void ath_pci_remove(struct pci_de
 	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	void __iomem *mem = sc->mem;
 
-	ath_cleanup(sc);
+	ath9k_deinit_device(sc);
+	free_irq(sc->irq, sc);
+	ieee80211_free_hw(sc->hw);
+
+	pci_iounmap(pdev, mem);
+	pci_disable_device(pdev);
+	pci_release_region(pdev, 0);
 }
 
 #ifdef CONFIG_PM
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/phy.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/phy.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/phy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/phy.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,8 @@
  * AR9287 - 11n single-band 1x1 MIMO for USB
  */
 
+#include <linux/slab.h>
+
 #include "hw.h"
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/phy.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/phy.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/phy.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/phy.h	2010-05-16 17:17:36.000000000 -0400
@@ -384,6 +384,9 @@ bool ath9k_hw_set_rf_regs(struct ath_hw
 
 #define AR_PHY_HEAVY_CLIP_ENABLE         0x99E0
 
+#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS    0x99EC
+#define AR_PHY_RIFS_INIT_DELAY         0x03ff0000
+
 #define AR_PHY_M_SLEEP      0x99f0
 #define AR_PHY_REFCLKDLY    0x99f4
 #define AR_PHY_REFCLKPD     0x99f8
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/rc.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/rc.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/rc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/rc.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "ath9k.h"
 
 static const struct ath_rate_table ar5416_11na_ratetable = {
@@ -668,7 +670,7 @@ static void ath_get_rate(void *priv, str
 	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, i = 0, rix, nrix;
+	u8 try_per_rate, i = 0, rix;
 	int is_probe = 0;
 
 	if (rate_control_send_low(sta, priv_sta, txrc))
@@ -678,48 +680,47 @@ static void ath_get_rate(void *priv, str
 	 * For Multi Rate Retry we use a different number of
 	 * retry attempt counts. This ends up looking like this:
 	 *
-	 * MRR[0] = 2
-	 * MRR[1] = 2
-	 * MRR[2] = 2
-	 * MRR[3] = 4
+	 * MRR[0] = 4
+	 * MRR[1] = 4
+	 * MRR[2] = 4
+	 * MRR[3] = 8
 	 *
 	 */
-	try_per_rate = sc->hw->max_rate_tries;
+	try_per_rate = 4;
 
 	rate_table = sc->cur_rate_table;
 	rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
-	nrix = rix;
 
 	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++], txrc,
-				       1, nrix, 0);
+				       1, rix, 0);
 
 		/* Get the next tried/allowed rate. No RTS for the next series
 		 * after the probe rate
 		 */
-		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
+		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);
 		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
-				       try_per_rate, nrix, 0);
+				       try_per_rate, rix, 0);
 
 		tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
 	} else {
 		/* Set the choosen rate. No RTS for first series entry. */
 		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
-				       try_per_rate, nrix, 0);
+				       try_per_rate, rix, 0);
 	}
 
 	/* Fill in the other rates for multirate retry */
 	for ( ; i < 4; i++) {
 		/* Use twice the number of tries for the last MRR segment. */
 		if (i + 1 == 4)
-			try_per_rate = 4;
+			try_per_rate = 8;
 
-		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
+		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);
 		/* All other rates in the series have RTS enabled */
 		ath_rc_rate_set_series(rate_table, &rates[i], txrc,
-				       try_per_rate, nrix, 1);
+				       try_per_rate, rix, 1);
 	}
 
 	/*
@@ -1324,7 +1325,7 @@ static void ath_rate_init(void *priv, st
 
 static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
 			    struct ieee80211_sta *sta, void *priv_sta,
-			    u32 changed)
+			    u32 changed, enum nl80211_channel_type oper_chan_type)
 {
 	struct ath_softc *sc = priv;
 	struct ath_rate_priv *ath_rc_priv = priv_sta;
@@ -1341,8 +1342,8 @@ static void ath_rate_update(void *priv,
 		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)
+		if (oper_chan_type == NL80211_CHAN_HT40MINUS ||
+		    oper_chan_type == NL80211_CHAN_HT40PLUS)
 			oper_cw40 = true;
 
 		oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/rc.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/rc.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/rc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/rc.h	2010-05-16 17:17:36.000000000 -0400
@@ -57,6 +57,10 @@ enum {
 				|| (_phy == WLAN_RC_PHY_HT_40_DS)	\
 				|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI)	\
 				|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
+#define WLAN_RC_PHY_20(_phy)   ((_phy == WLAN_RC_PHY_HT_20_SS)		\
+				|| (_phy == WLAN_RC_PHY_HT_20_DS)	\
+				|| (_phy == WLAN_RC_PHY_HT_20_SS_HGI)	\
+				|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI))
 #define WLAN_RC_PHY_40(_phy)   ((_phy == WLAN_RC_PHY_HT_40_SS)		\
 				|| (_phy == WLAN_RC_PHY_HT_40_DS)	\
 				|| (_phy == WLAN_RC_PHY_HT_40_SS_HGI)	\
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/recv.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/recv.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/recv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/recv.c	2010-05-16 17:17:36.000000000 -0400
@@ -364,10 +364,10 @@ static void ath_rx_ps_beacon(struct ath_
 	if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0)
 		return; /* not from our current AP */
 
-	sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
+	sc->ps_flags &= ~PS_WAIT_FOR_BEACON;
 
-	if (sc->sc_flags & SC_OP_BEACON_SYNC) {
-		sc->sc_flags &= ~SC_OP_BEACON_SYNC;
+	if (sc->ps_flags & PS_BEACON_SYNC) {
+		sc->ps_flags &= ~PS_BEACON_SYNC;
 		ath_print(common, ATH_DBG_PS,
 			  "Reconfigure Beacon timers based on "
 			  "timestamp from the AP\n");
@@ -384,17 +384,17 @@ static void ath_rx_ps_beacon(struct ath_
 		 */
 		ath_print(common, ATH_DBG_PS, "Received DTIM beacon indicating "
 			  "buffered broadcast/multicast frame(s)\n");
-		sc->sc_flags |= SC_OP_WAIT_FOR_CAB | SC_OP_WAIT_FOR_BEACON;
+		sc->ps_flags |= PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON;
 		return;
 	}
 
-	if (sc->sc_flags & SC_OP_WAIT_FOR_CAB) {
+	if (sc->ps_flags & PS_WAIT_FOR_CAB) {
 		/*
 		 * This can happen if a broadcast frame is dropped or the AP
 		 * fails to send a frame indicating that all CAB frames have
 		 * been delivered.
 		 */
-		sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB;
+		sc->ps_flags &= ~PS_WAIT_FOR_CAB;
 		ath_print(common, ATH_DBG_PS,
 			  "PS wait for CAB frames timed out\n");
 	}
@@ -408,10 +408,10 @@ static void ath_rx_ps(struct ath_softc *
 	hdr = (struct ieee80211_hdr *)skb->data;
 
 	/* Process Beacon and CAB receive in PS state */
-	if ((sc->sc_flags & SC_OP_WAIT_FOR_BEACON) &&
+	if ((sc->ps_flags & PS_WAIT_FOR_BEACON) &&
 	    ieee80211_is_beacon(hdr->frame_control))
 		ath_rx_ps_beacon(sc, skb);
-	else if ((sc->sc_flags & SC_OP_WAIT_FOR_CAB) &&
+	else if ((sc->ps_flags & PS_WAIT_FOR_CAB) &&
 		 (ieee80211_is_data(hdr->frame_control) ||
 		  ieee80211_is_action(hdr->frame_control)) &&
 		 is_multicast_ether_addr(hdr->addr1) &&
@@ -420,20 +420,20 @@ static void ath_rx_ps(struct ath_softc *
 		 * No more broadcast/multicast frames to be received at this
 		 * point.
 		 */
-		sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB;
+		sc->ps_flags &= ~PS_WAIT_FOR_CAB;
 		ath_print(common, ATH_DBG_PS,
 			  "All PS CAB frames received, back to sleep\n");
-	} else if ((sc->sc_flags & SC_OP_WAIT_FOR_PSPOLL_DATA) &&
+	} else if ((sc->ps_flags & PS_WAIT_FOR_PSPOLL_DATA) &&
 		   !is_multicast_ether_addr(hdr->addr1) &&
 		   !ieee80211_has_morefrags(hdr->frame_control)) {
-		sc->sc_flags &= ~SC_OP_WAIT_FOR_PSPOLL_DATA;
+		sc->ps_flags &= ~PS_WAIT_FOR_PSPOLL_DATA;
 		ath_print(common, ATH_DBG_PS,
 			  "Going back to sleep after having received "
-			  "PS-Poll data (0x%x)\n",
-			sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
-					SC_OP_WAIT_FOR_CAB |
-					SC_OP_WAIT_FOR_PSPOLL_DATA |
-					SC_OP_WAIT_FOR_TX_ACK));
+			  "PS-Poll data (0x%lx)\n",
+			sc->ps_flags & (PS_WAIT_FOR_BEACON |
+					PS_WAIT_FOR_CAB |
+					PS_WAIT_FOR_PSPOLL_DATA |
+					PS_WAIT_FOR_TX_ACK));
 	}
 }
 
@@ -571,6 +571,8 @@ int ath_rx_tasklet(struct ath_softc *sc,
 		hw = ath_get_virt_hw(sc, hdr);
 		rx_stats = &ds->ds_rxstat;
 
+		ath_debug_stat_rx(sc, bf);
+
 		/*
 		 * If we're asked to flush receive queue, directly
 		 * chain it back at the queue without processing it.
@@ -631,9 +633,9 @@ int ath_rx_tasklet(struct ath_softc *sc,
 			sc->rx.rxotherant = 0;
 		}
 
-		if (unlikely(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
-					     SC_OP_WAIT_FOR_CAB |
-					     SC_OP_WAIT_FOR_PSPOLL_DATA)))
+		if (unlikely(sc->ps_flags & (PS_WAIT_FOR_BEACON |
+					     PS_WAIT_FOR_CAB |
+					     PS_WAIT_FOR_PSPOLL_DATA)))
 			ath_rx_ps(sc, skb);
 
 		ath_rx_send_to_mac80211(hw, sc, skb, rxs);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/reg.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/reg.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/reg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/reg.h	2010-05-16 17:17:36.000000000 -0400
@@ -1547,9 +1547,9 @@ enum {
 
 #define AR_BT_COEX_WEIGHT          0x8174
 #define AR_BT_COEX_WGHT		   0xff55
-#define AR_STOMP_ALL_WLAN_WGHT	   0xffcc
-#define AR_STOMP_LOW_WLAN_WGHT	   0xaaa8
-#define AR_STOMP_NONE_WLAN_WGHT	   0xaa00
+#define AR_STOMP_ALL_WLAN_WGHT	   0xfcfc
+#define AR_STOMP_LOW_WLAN_WGHT	   0xa8a8
+#define AR_STOMP_NONE_WLAN_WGHT	   0x0000
 #define AR_BTCOEX_BT_WGHT          0x0000ffff
 #define AR_BTCOEX_BT_WGHT_S        0
 #define AR_BTCOEX_WL_WGHT          0xffff0000
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/virtual.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/virtual.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/virtual.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/virtual.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "ath9k.h"
 
 struct ath9k_vif_iter_data {
@@ -152,7 +154,7 @@ int ath9k_wiphy_add(struct ath_softc *sc
 
 	SET_IEEE80211_PERM_ADDR(hw, addr);
 
-	ath_set_hw_capab(sc, hw);
+	ath9k_set_hw_capab(sc, hw);
 
 	error = ieee80211_register_hw(hw);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/xmit.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/xmit.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/xmit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath9k/xmit.c	2010-05-16 17:17:36.000000000 -0400
@@ -1353,25 +1353,6 @@ static enum ath9k_pkt_type get_hw_packet
 	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);
@@ -1498,26 +1479,6 @@ static void ath_buf_set_rate(struct ath_
 	if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
 		ctsrate |= rate->hw_value_short;
 
-	/*
-	 * 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++) {
 		bool is_40, is_sgi, is_sp;
 		int phy;
@@ -1529,8 +1490,15 @@ static void ath_buf_set_rate(struct ath_
 		series[i].Tries = rates[i].count;
 		series[i].ChSel = common->tx_chainmask;
 
-		if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)
+		if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) ||
+		    (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) {
 			series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
+			flags |= ATH9K_TXDESC_RTSENA;
+		} else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+			series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
+			flags |= ATH9K_TXDESC_CTSENA;
+		}
+
 		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)
@@ -1568,6 +1536,14 @@ static void ath_buf_set_rate(struct ath_
 			phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp);
 	}
 
+	/* 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;
+
+	/* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */
+	if (flags & ATH9K_TXDESC_RTSENA)
+		flags &= ~ATH9K_TXDESC_CTSENA;
+
 	/* 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,
@@ -1648,7 +1624,7 @@ static int ath_tx_setup_buffer(struct ie
 	/* tag if this is a nullfunc frame to enable PS when AP acks it */
 	if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) {
 		bf->bf_isnullfunc = true;
-		sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED;
+		sc->ps_flags &= ~PS_NULLFUNC_COMPLETED;
 	} else
 		bf->bf_isnullfunc = false;
 
@@ -1701,7 +1677,7 @@ static void ath_tx_start_dma(struct ath_
 			goto tx_done;
 		}
 
-		if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && !is_pae(skb)) {
+		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
 			/*
 			 * Try aggregation if it's a unicast data frame
 			 * and the destination is HT capable.
@@ -1858,15 +1834,15 @@ static void ath_tx_complete(struct ath_s
 		skb_pull(skb, padsize);
 	}
 
-	if (sc->sc_flags & SC_OP_WAIT_FOR_TX_ACK) {
-		sc->sc_flags &= ~SC_OP_WAIT_FOR_TX_ACK;
+	if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) {
+		sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK;
 		ath_print(common, ATH_DBG_PS,
 			  "Going back to sleep after having "
-			  "received TX status (0x%x)\n",
-			sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
-					SC_OP_WAIT_FOR_CAB |
-					SC_OP_WAIT_FOR_PSPOLL_DATA |
-					SC_OP_WAIT_FOR_TX_ACK));
+			  "received TX status (0x%lx)\n",
+			sc->ps_flags & (PS_WAIT_FOR_BEACON |
+					PS_WAIT_FOR_CAB |
+					PS_WAIT_FOR_PSPOLL_DATA |
+					PS_WAIT_FOR_TX_ACK));
 	}
 
 	if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL))
@@ -2053,11 +2029,10 @@ static void ath_tx_processq(struct ath_s
 		 */
 		if (bf->bf_isnullfunc &&
 		    (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) {
-			if ((sc->sc_flags & SC_OP_PS_ENABLED)) {
-				sc->ps_enabled = true;
-				ath9k_hw_setrxabort(sc->sc_ah, 1);
-			} else
-				sc->sc_flags |= SC_OP_NULLFUNC_COMPLETED;
+			if ((sc->ps_flags & PS_ENABLED))
+				ath9k_enable_ps(sc);
+			else
+				sc->ps_flags |= PS_NULLFUNC_COMPLETED;
 		}
 
 		/*
@@ -2264,7 +2239,7 @@ void ath_tx_node_cleanup(struct ath_soft
 		if (ATH_TXQ_SETUP(sc, i)) {
 			txq = &sc->tx.txq[i];
 
-			spin_lock(&txq->axq_lock);
+			spin_lock_bh(&txq->axq_lock);
 
 			list_for_each_entry_safe(ac,
 					ac_tmp, &txq->axq_acq, list) {
@@ -2285,7 +2260,7 @@ void ath_tx_node_cleanup(struct ath_soft
 				}
 			}
 
-			spin_unlock(&txq->axq_lock);
+			spin_unlock_bh(&txq->axq_lock);
 		}
 	}
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/ath.h	2010-05-16 17:17:36.000000000 -0400
@@ -74,7 +74,6 @@ struct ath_common;
 
 struct ath_bus_ops {
 	void		(*read_cachesize)(struct ath_common *common, int *csz);
-	void		(*cleanup)(struct ath_common *common);
 	bool		(*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
 	void		(*bt_coex_prep)(struct ath_common *common);
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/debug.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/debug.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/debug.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/debug.h	2010-05-16 17:17:36.000000000 -0400
@@ -65,11 +65,11 @@ enum ATH_DEBUG {
 #define ATH_DBG_DEFAULT (ATH_DBG_FATAL)
 
 #ifdef CONFIG_ATH_DEBUG
-void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...);
+void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
+	__attribute__ ((format (printf, 3, 4)));
 #else
-static inline void ath_print(struct ath_common *common,
-			     int dbg_mask,
-			     const char *fmt, ...)
+static inline void __attribute__ ((format (printf, 3, 4)))
+ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
 {
 }
 #endif /* CONFIG_ATH_DEBUG */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/regd.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/regd.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/regd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ath/regd.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <net/cfg80211.h>
 #include <net/mac80211.h>
 #include "regd.h"
@@ -110,8 +109,9 @@ static const struct ieee80211_regdomain
 
 static inline bool is_wwr_sku(u16 regd)
 {
-	return ((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
-		(regd == WORLD);
+	return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
+		(((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
+		(regd == WORLD));
 }
 
 static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/atmel_pci.c linux-libre-2.6.34-gnu1/drivers/net/wireless/atmel_pci.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/atmel_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/atmel_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,7 @@ MODULE_DESCRIPTION("Support for Atmel at
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("Atmel at76c506 PCI wireless cards");
 
-static struct pci_device_id card_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(card_ids) = {
 	{ 0x1114, 0x0506, PCI_ANY_ID, PCI_ANY_ID },
 	{ 0, }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/b43.h linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/b43.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/b43.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/b43.h	2010-05-16 17:17:36.000000000 -0400
@@ -254,6 +254,14 @@ enum {
 #define B43_SHM_SH_MAXBFRAMES		0x0080	/* Maximum number of frames in a burst */
 #define B43_SHM_SH_SPUWKUP		0x0094	/* pre-wakeup for synth PU in us */
 #define B43_SHM_SH_PRETBTT		0x0096	/* pre-TBTT in us */
+/* SHM_SHARED tx iq workarounds */
+#define B43_SHM_SH_NPHY_TXIQW0		0x0700
+#define B43_SHM_SH_NPHY_TXIQW1		0x0702
+#define B43_SHM_SH_NPHY_TXIQW2		0x0704
+#define B43_SHM_SH_NPHY_TXIQW3		0x0706
+/* SHM_SHARED tx pwr ctrl */
+#define B43_SHM_SH_NPHY_TXPWR_INDX0	0x0708
+#define B43_SHM_SH_NPHY_TXPWR_INDX1	0x070E
 
 /* SHM_SCRATCH offsets */
 #define B43_SHM_SC_MINCONT		0x0003	/* Minimum contention window */
@@ -694,6 +702,7 @@ struct b43_wldev {
 	bool radio_hw_enable;	/* saved state of radio hardware enabled state */
 	bool qos_enabled;		/* TRUE, if QoS is used. */
 	bool hwcrypto_enabled;		/* TRUE, if HW crypto acceleration is enabled. */
+	bool use_pio;			/* TRUE if next init should use PIO */
 
 	/* PHY/Radio device. */
 	struct b43_phy phy;
@@ -822,11 +831,9 @@ struct b43_wl {
 	/* The device LEDs. */
 	struct b43_leds leds;
 
-#ifdef CONFIG_B43_PIO
 	/* Kmalloc'ed scratch space for PIO TX/RX. Protected by wl->mutex. */
 	u8 pio_scratchspace[110] __attribute__((__aligned__(8)));
 	u8 pio_tailspace[4] __attribute__((__aligned__(8)));
-#endif /* CONFIG_B43_PIO */
 };
 
 static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw)
@@ -877,20 +884,15 @@ static inline void b43_write32(struct b4
 
 static inline bool b43_using_pio_transfers(struct b43_wldev *dev)
 {
-#ifdef CONFIG_B43_PIO
 	return dev->__using_pio_transfers;
-#else
-	return 0;
-#endif
 }
 
 #ifdef CONFIG_B43_FORCE_PIO
-# define B43_FORCE_PIO	1
+# define B43_PIO_DEFAULT 1
 #else
-# define B43_FORCE_PIO	0
+# define B43_PIO_DEFAULT 0
 #endif
 
-
 /* Message printing */
 void b43info(struct b43_wl *wl, const char *fmt, ...)
     __attribute__ ((format(printf, 2, 3)));
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/dma.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/dma.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <asm/div64.h>
 
 
@@ -1369,7 +1370,6 @@ int b43_dma_tx(struct b43_wldev *dev, st
 		b43err(dev->wl, "DMA tx mapping failure\n");
 		goto out;
 	}
-	ring->nr_tx_packets++;
 	if ((free_slots(ring) < TX_SLOTS_PER_FRAME) ||
 	    should_inject_overflow(ring)) {
 		/* This TX ring is full. */
@@ -1500,22 +1500,6 @@ void b43_dma_handle_txstatus(struct b43_
 	}
 }
 
-void b43_dma_get_tx_stats(struct b43_wldev *dev,
-			  struct ieee80211_tx_queue_stats *stats)
-{
-	const int nr_queues = dev->wl->hw->queues;
-	struct b43_dmaring *ring;
-	int i;
-
-	for (i = 0; i < nr_queues; i++) {
-		ring = select_ring_by_priority(dev, i);
-
-		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;
-	}
-}
-
 static void dma_rx(struct b43_dmaring *ring, int *slot)
 {
 	const struct b43_dma_ops *ops = ring->ops;
@@ -1653,7 +1637,6 @@ void b43_dma_tx_resume(struct b43_wldev
 	b43_power_saving_ctl_bits(dev, 0);
 }
 
-#ifdef CONFIG_B43_PIO
 static void direct_fifo_rx(struct b43_wldev *dev, enum b43_dmatype type,
 			   u16 mmio_base, bool enable)
 {
@@ -1687,4 +1670,3 @@ void b43_dma_direct_fifo_rx(struct b43_w
 	mmio_base = b43_dmacontroller_base(type, engine_index);
 	direct_fifo_rx(dev, type, mmio_base, enable);
 }
-#endif /* CONFIG_B43_PIO */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/dma.h linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/dma.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/dma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/dma.h	2010-05-16 17:17:36.000000000 -0400
@@ -228,8 +228,6 @@ struct b43_dmaring {
 	int used_slots;
 	/* Currently used slot in the ring. */
 	int current_slot;
-	/* Total number of packets sent. Statistics only. */
-	unsigned int nr_tx_packets;
 	/* Frameoffset in octets. */
 	u32 frameoffset;
 	/* Descriptor buffer size. */
@@ -278,9 +276,6 @@ void b43_dma_free(struct b43_wldev *dev)
 void b43_dma_tx_suspend(struct b43_wldev *dev);
 void b43_dma_tx_resume(struct b43_wldev *dev);
 
-void b43_dma_get_tx_stats(struct b43_wldev *dev,
-			  struct ieee80211_tx_queue_stats *stats);
-
 int b43_dma_tx(struct b43_wldev *dev,
 	       struct sk_buff *skb);
 void b43_dma_handle_txstatus(struct b43_wldev *dev,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/Kconfig linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -78,11 +78,11 @@ config B43_SDIO
 
 	  If unsure, say N.
 
-# Data transfers to the device via PIO
-# This is only needed on PCMCIA and SDIO devices. All others can do DMA properly.
+#Data transfers to the device via PIO. We want it as a fallback even
+# if we can do DMA.
 config B43_PIO
 	bool
-	depends on B43 && (B43_SDIO || B43_PCMCIA || B43_FORCE_PIO)
+	depends on B43
 	select SSB_BLOCKIO
 	default y
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/lo.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/lo.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/lo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/lo.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 
 #include <linux/delay.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 
 static struct b43_lo_calib *b43_find_lo_calib(struct b43_txpower_lo_control *lo,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/main.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/main.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/main.c	2013-05-03 12:09:17.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/main.c	2013-05-03 09:48:49.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/skbuff.h>
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #include "b43.h"
@@ -68,7 +69,6 @@ MODULE_LICENSE("GPL");
 
 /*(DEBLOBBED)*/
 
-
 static int modparam_bad_frames_preempt;
 module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
 MODULE_PARM_DESC(bad_frames_preempt,
@@ -102,6 +102,9 @@ int b43_modparam_verbose = B43_VERBOSITY
 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");
 
+int b43_modparam_pio = B43_PIO_DEFAULT;
+module_param_named(pio, b43_modparam_pio, int, 0644);
+MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
 
 static const struct ssb_device_id b43_ssb_tbl[] = {
 	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
@@ -110,6 +113,7 @@ static const struct ssb_device_id b43_ss
 	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9),
 	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, 12),
 	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),
@@ -842,8 +846,10 @@ static void rx_tkip_phase1_write(struct
 }
 
 static void b43_op_update_tkip_key(struct ieee80211_hw *hw,
-			struct ieee80211_key_conf *keyconf, const u8 *addr,
-			u32 iv32, u16 *phase1key)
+				   struct ieee80211_vif *vif,
+				   struct ieee80211_key_conf *keyconf,
+				   struct ieee80211_sta *sta,
+				   u32 iv32, u16 *phase1key)
 {
 	struct b43_wl *wl = hw_to_b43_wl(hw);
 	struct b43_wldev *dev;
@@ -852,19 +858,19 @@ static void b43_op_update_tkip_key(struc
 	if (B43_WARN_ON(!modparam_hwtkip))
 		return;
 
-	mutex_lock(&wl->mutex);
-
+	/* This is only called from the RX path through mac80211, where
+	 * our mutex is already locked. */
+	B43_WARN_ON(!mutex_is_locked(&wl->mutex));
 	dev = wl->current_dev;
-	if (!dev || b43_status(dev) < B43_STAT_INITIALIZED)
-		goto out_unlock;
+	B43_WARN_ON(!dev || b43_status(dev) < B43_STAT_INITIALIZED);
 
 	keymac_write(dev, index, NULL);	/* First zero out mac to avoid race */
 
 	rx_tkip_phase1_write(dev, index, iv32, phase1key);
-	keymac_write(dev, index, addr);
-
-out_unlock:
-	mutex_unlock(&wl->mutex);
+	/* only pairwise TKIP keys are supported right now */
+	if (WARN_ON(!sta))
+		return;
+	keymac_write(dev, index, sta->addr);
 }
 
 static void do_key_write(struct b43_wldev *dev,
@@ -1793,8 +1799,9 @@ static void b43_do_interrupt_thread(stru
 			       dma_reason[4], dma_reason[5]);
 			b43err(dev->wl, "This device does not support DMA "
 			       "on your system. Please use PIO instead.\n");
-			b43err(dev->wl, "CONFIG_B43_FORCE_PIO must be set in "
-			       "your kernel configuration.\n");
+			/* Fall back to PIO transfers if we get fatal DMA errors! */
+			dev->use_pio = 1;
+			b43_controller_restart(dev, "DMA error");
 			return;
 		}
 		if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) {
@@ -3347,27 +3354,6 @@ out_unlock:
 	return err;
 }
 
-static int b43_op_get_tx_stats(struct ieee80211_hw *hw,
-			       struct ieee80211_tx_queue_stats *stats)
-{
-	struct b43_wl *wl = hw_to_b43_wl(hw);
-	struct b43_wldev *dev;
-	int err = -ENODEV;
-
-	mutex_lock(&wl->mutex);
-	dev = wl->current_dev;
-	if (dev && b43_status(dev) >= B43_STAT_STARTED) {
-		if (b43_using_pio_transfers(dev))
-			b43_pio_get_tx_stats(dev, stats);
-		else
-			b43_dma_get_tx_stats(dev, stats);
-		err = 0;
-	}
-	mutex_unlock(&wl->mutex);
-
-	return err;
-}
-
 static int b43_op_get_stats(struct ieee80211_hw *hw,
 			    struct ieee80211_low_level_stats *stats)
 {
@@ -3571,6 +3557,12 @@ static int b43_op_config(struct ieee8021
 	dev = wl->current_dev;
 	phy = &dev->phy;
 
+	if (conf_is_ht(conf))
+		phy->is_40mhz =
+			(conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf));
+	else
+		phy->is_40mhz = false;
+
 	b43_mac_suspend(dev);
 
 	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
@@ -3972,6 +3964,7 @@ static int b43_wireless_core_start(struc
 	}
 
 	/* We are ready to run. */
+	ieee80211_wake_queues(dev->wl->hw);
 	b43_set_status(dev, B43_STAT_STARTED);
 
 	/* Start data flow (TX/RX). */
@@ -4362,7 +4355,7 @@ static int b43_wireless_core_init(struct
 
 	if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) ||
 	    (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) ||
-	    B43_FORCE_PIO) {
+	    dev->use_pio) {
 		dev->__using_pio_transfers = 1;
 		err = b43_pio_init(dev);
 	} else {
@@ -4381,8 +4374,6 @@ static int b43_wireless_core_init(struct
 
 	ieee80211_wake_queues(dev->wl->hw);
 
-	ieee80211_wake_queues(dev->wl->hw);
-
 	b43_set_status(dev, B43_STAT_INITIALIZED);
 
 out:
@@ -4397,7 +4388,7 @@ err_busdown:
 }
 
 static int b43_op_add_interface(struct ieee80211_hw *hw,
-				struct ieee80211_if_init_conf *conf)
+				struct ieee80211_vif *vif)
 {
 	struct b43_wl *wl = hw_to_b43_wl(hw);
 	struct b43_wldev *dev;
@@ -4405,24 +4396,24 @@ static int b43_op_add_interface(struct i
 
 	/* TODO: allow WDS/AP devices to coexist */
 
-	if (conf->type != NL80211_IFTYPE_AP &&
-	    conf->type != NL80211_IFTYPE_MESH_POINT &&
-	    conf->type != NL80211_IFTYPE_STATION &&
-	    conf->type != NL80211_IFTYPE_WDS &&
-	    conf->type != NL80211_IFTYPE_ADHOC)
+	if (vif->type != NL80211_IFTYPE_AP &&
+	    vif->type != NL80211_IFTYPE_MESH_POINT &&
+	    vif->type != NL80211_IFTYPE_STATION &&
+	    vif->type != NL80211_IFTYPE_WDS &&
+	    vif->type != NL80211_IFTYPE_ADHOC)
 		return -EOPNOTSUPP;
 
 	mutex_lock(&wl->mutex);
 	if (wl->operating)
 		goto out_mutex_unlock;
 
-	b43dbg(wl, "Adding Interface type %d\n", conf->type);
+	b43dbg(wl, "Adding Interface type %d\n", vif->type);
 
 	dev = wl->current_dev;
 	wl->operating = 1;
-	wl->vif = conf->vif;
-	wl->if_type = conf->type;
-	memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
+	wl->vif = vif;
+	wl->if_type = vif->type;
+	memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
 
 	b43_adjust_opmode(dev);
 	b43_set_pretbtt(dev);
@@ -4437,17 +4428,17 @@ static int b43_op_add_interface(struct i
 }
 
 static void b43_op_remove_interface(struct ieee80211_hw *hw,
-				    struct ieee80211_if_init_conf *conf)
+				    struct ieee80211_vif *vif)
 {
 	struct b43_wl *wl = hw_to_b43_wl(hw);
 	struct b43_wldev *dev = wl->current_dev;
 
-	b43dbg(wl, "Removing Interface type %d\n", conf->type);
+	b43dbg(wl, "Removing Interface type %d\n", vif->type);
 
 	mutex_lock(&wl->mutex);
 
 	B43_WARN_ON(!wl->operating);
-	B43_WARN_ON(wl->vif != conf->vif);
+	B43_WARN_ON(wl->vif != vif);
 	wl->vif = NULL;
 
 	wl->operating = 0;
@@ -4588,7 +4579,6 @@ static const struct ieee80211_ops b43_hw
 	.set_key		= b43_op_set_key,
 	.update_tkip_key	= b43_op_update_tkip_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,
@@ -4832,6 +4822,7 @@ static int b43_one_core_attach(struct ss
 	if (!wldev)
 		goto out;
 
+	wldev->use_pio = b43_modparam_pio;
 	wldev->dev = dev;
 	wldev->wl = wl;
 	b43_set_status(wldev, B43_STAT_UNINIT);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/Makefile linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,7 @@ b43-y				+= xmit.o
 b43-y				+= lo.o
 b43-y				+= wa.o
 b43-y				+= dma.o
-b43-$(CONFIG_B43_PIO)		+= pio.o
+b43-y				+= pio.o
 b43-y				+= rfkill.o
 b43-$(CONFIG_B43_LEDS)		+= leds.o
 b43-$(CONFIG_B43_PCMCIA)	+= pcmcia.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/pcmcia.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/pcmcia.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/pcmcia.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/pcmcia.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include "pcmcia.h"
 
 #include <linux/ssb/ssb.h>
+#include <linux/slab.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_a.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/phy_a.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_a.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/phy_a.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,8 @@
 
 */
 
+#include <linux/slab.h>
+
 #include "b43.h"
 #include "phy_a.h"
 #include "phy_common.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_common.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/phy_common.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/phy_common.c	2010-05-16 17:17:36.000000000 -0400
@@ -421,3 +421,48 @@ void b43_phyop_switch_analog_generic(str
 {
 	b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4);
 }
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */
+struct b43_c32 b43_cordic(int theta)
+{
+	u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
+		      58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
+		      229, 115, 57, 29, };
+	u8 i;
+	s32 tmp;
+	s8 signx = 1;
+	u32 angle = 0;
+	struct b43_c32 ret = { .i = 39797, .q = 0, };
+
+	while (theta > (180 << 16))
+		theta -= (360 << 16);
+	while (theta < -(180 << 16))
+		theta += (360 << 16);
+
+	if (theta > (90 << 16)) {
+		theta -= (180 << 16);
+		signx = -1;
+	} else if (theta < -(90 << 16)) {
+		theta += (180 << 16);
+		signx = -1;
+	}
+
+	for (i = 0; i <= 17; i++) {
+		if (theta > angle) {
+			tmp = ret.i - (ret.q >> i);
+			ret.q += ret.i >> i;
+			ret.i = tmp;
+			angle += arctg[i];
+		} else {
+			tmp = ret.i + (ret.q >> i);
+			ret.q -= ret.i >> i;
+			ret.i = tmp;
+			angle -= arctg[i];
+		}
+	}
+
+	ret.i *= signx;
+	ret.q *= signx;
+
+	return ret;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_common.h linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/phy_common.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/phy_common.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,12 @@
 
 struct b43_wldev;
 
+/* Complex number using 2 32-bit signed integers */
+struct b43_c32 { s32 i, q; };
+
+#define CORDIC_CONVERT(value)	(((value) >= 0) ? \
+				 ((((value) >> 15) + 1) >> 1) : \
+				 -((((-(value)) >> 15) + 1) >> 1))
 
 /* PHY register routing bits */
 #define B43_PHYROUTE			0x0C00 /* PHY register routing bits mask */
@@ -212,6 +218,9 @@ struct b43_phy {
 	bool supports_2ghz;
 	bool supports_5ghz;
 
+	/* HT info */
+	bool is_40mhz;
+
 	/* GMODE bit enabled? */
 	bool gmode;
 
@@ -418,5 +427,6 @@ int b43_phy_shm_tssi_read(struct b43_wld
  */
 void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
 
+struct b43_c32 b43_cordic(int theta);
 
 #endif /* LINUX_B43_PHY_COMMON_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_g.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/phy_g.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_g.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/phy_g.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include "main.h"
 
 #include <linux/bitrev.h>
+#include <linux/slab.h>
 
 
 static const s8 b43_tssi2dbm_g_table[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_lp.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/phy_lp.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_lp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/phy_lp.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,8 @@
 
 */
 
+#include <linux/slab.h>
+
 #include "b43.h"
 #include "main.h"
 #include "phy_lp.h"
@@ -80,6 +82,7 @@ static void b43_lpphy_op_free(struct b43
 	dev->phy.lp = NULL;
 }
 
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/LP/ReadBandSrom */
 static void lpphy_read_band_sprom(struct b43_wldev *dev)
 {
 	struct b43_phy_lp *lpphy = dev->phy.lp;
@@ -101,6 +104,12 @@ static void lpphy_read_band_sprom(struct
 		maxpwr = bus->sprom.maxpwr_bg;
 		lpphy->max_tx_pwr_med_band = maxpwr;
 		cckpo = bus->sprom.cck2gpo;
+		/*
+		 * We don't read SPROM's opo as specs say. On rev8 SPROMs
+		 * opo == ofdm2gpo and we don't know any SSB with LP-PHY
+		 * and SPROM rev below 8.
+		 */
+		B43_WARN_ON(bus->sprom.revision < 8);
 		ofdmpo = bus->sprom.ofdm2gpo;
 		if (cckpo) {
 			for (i = 0; i < 4; i++) {
@@ -1703,19 +1712,6 @@ static const struct lpphy_rx_iq_comp lpp
 	.c0 = 0,
 };
 
-static u8 lpphy_nbits(s32 val)
-{
-	u32 tmp = abs(val);
-	u8 nbits = 0;
-
-	while (tmp != 0) {
-		nbits++;
-		tmp >>= 1;
-	}
-
-	return nbits;
-}
-
 static int lpphy_calc_rx_iq_comp(struct b43_wldev *dev, u16 samples)
 {
 	struct lpphy_iq_est iq_est;
@@ -1742,8 +1738,8 @@ static int lpphy_calc_rx_iq_comp(struct
 		goto out;
 	}
 
-	prod_msb = lpphy_nbits(prod);
-	q_msb = lpphy_nbits(qpwr);
+	prod_msb = fls(abs(prod));
+	q_msb = fls(abs(qpwr));
 	tmp1 = prod_msb - 20;
 
 	if (tmp1 >= 0) {
@@ -1773,47 +1769,6 @@ out:
 	return ret;
 }
 
-/* Complex number using 2 32-bit signed integers */
-typedef struct {s32 i, q;} lpphy_c32;
-
-static lpphy_c32 lpphy_cordic(int theta)
-{
-	u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
-		      58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
-		      229, 115, 57, 29, };
-	int i, tmp, signx = 1, angle = 0;
-	lpphy_c32 ret = { .i = 39797, .q = 0, };
-
-	theta = clamp_t(int, theta, -180, 180);
-
-	if (theta > 90) {
-		theta -= 180;
-		signx = -1;
-	} else if (theta < -90) {
-		theta += 180;
-		signx = -1;
-	}
-
-	for (i = 0; i <= 17; i++) {
-		if (theta > angle) {
-			tmp = ret.i - (ret.q >> i);
-			ret.q += ret.i >> i;
-			ret.i = tmp;
-			angle += arctg[i];
-		} else {
-			tmp = ret.i + (ret.q >> i);
-			ret.q -= ret.i >> i;
-			ret.i = tmp;
-			angle -= arctg[i];
-		}
-	}
-
-	ret.i *= signx;
-	ret.q *= signx;
-
-	return ret;
-}
-
 static void lpphy_run_samples(struct b43_wldev *dev, u16 samples, u16 loops,
 			      u16 wait)
 {
@@ -1831,8 +1786,9 @@ static void lpphy_start_tx_tone(struct b
 {
 	struct b43_phy_lp *lpphy = dev->phy.lp;
 	u16 buf[64];
-	int i, samples = 0, angle = 0, rotation = (9 * freq) / 500;
-	lpphy_c32 sample;
+	int i, samples = 0, angle = 0;
+	int rotation = (((36 * freq) / 20) << 16) / 100;
+	struct b43_c32 sample;
 
 	lpphy->tx_tone_freq = freq;
 
@@ -1848,10 +1804,10 @@ static void lpphy_start_tx_tone(struct b
 	}
 
 	for (i = 0; i < samples; i++) {
-		sample = lpphy_cordic(angle);
+		sample = b43_cordic(angle);
 		angle += rotation;
-		buf[i] = ((sample.i * max) & 0xFF) << 8;
-		buf[i] |= (sample.q * max) & 0xFF;
+		buf[i] = CORDIC_CONVERT((sample.i * max) & 0xFF) << 8;
+		buf[i] |= CORDIC_CONVERT((sample.q * max) & 0xFF);
 	}
 
 	b43_lptab_write_bulk(dev, B43_LPTAB16(5, 0), samples, buf);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_n.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/phy_n.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_n.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/phy_n.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,12 +23,56 @@
 */
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include "b43.h"
 #include "phy_n.h"
 #include "tables_nphy.h"
+#include "main.h"
+
+struct nphy_txgains {
+	u16 txgm[2];
+	u16 pga[2];
+	u16 pad[2];
+	u16 ipa[2];
+};
+
+struct nphy_iqcal_params {
+	u16 txgm;
+	u16 pga;
+	u16 pad;
+	u16 ipa;
+	u16 cal_gain;
+	u16 ncorr[5];
+};
+
+struct nphy_iq_est {
+	s32 iq0_prod;
+	u32 i0_pwr;
+	u32 q0_pwr;
+	s32 iq1_prod;
+	u32 i1_pwr;
+	u32 q1_pwr;
+};
+
+enum b43_nphy_rf_sequence {
+	B43_RFSEQ_RX2TX,
+	B43_RFSEQ_TX2RX,
+	B43_RFSEQ_RESET2RX,
+	B43_RFSEQ_UPDATE_GAINH,
+	B43_RFSEQ_UPDATE_GAINL,
+	B43_RFSEQ_UPDATE_GAINU,
+};
 
+static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
+					u8 *events, u8 *delays, u8 length);
+static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
+				       enum b43_nphy_rf_sequence seq);
+static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
+						u16 value, u8 core, bool off);
+static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
+						u16 value, u8 core);
 
 void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
 {//TODO
@@ -197,173 +241,1020 @@ void b43_nphy_radio_turn_off(struct b43_
 		     ~B43_NPHY_RFCTL_CMD_EN);
 }
 
-#define ntab_upload(dev, offset, data) do { \
-		unsigned int i;						\
-		for (i = 0; i < (offset##_SIZE); i++)			\
-			b43_ntab_write(dev, (offset) + i, (data)[i]);	\
-	} while (0)
-
-/* Upload the N-PHY tables. */
+/*
+ * Upload the N-PHY tables.
+ * http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables
+ */
 static void b43_nphy_tables_init(struct b43_wldev *dev)
 {
-	/* Static tables */
-	ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
-	ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
-	ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
-	ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
-	ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
-	ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
-	ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt);
-	ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
-	ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
-	ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
-	ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
-	ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
-	ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
-	ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
+	if (dev->phy.rev < 3)
+		b43_nphy_rev0_1_2_tables_init(dev);
+	else
+		b43_nphy_rev3plus_tables_init(dev);
+}
 
-	/* Volatile tables */
-	ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
-	ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
-	ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0);
-	ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1);
-	ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0);
-	ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1);
-	ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0);
-	ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1);
-	ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0);
-	ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1);
-	ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0);
-	ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1);
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */
+static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+	enum ieee80211_band band;
+	u16 tmp;
+
+	if (!enable) {
+		nphy->rfctrl_intc1_save = b43_phy_read(dev,
+						       B43_NPHY_RFCTL_INTC1);
+		nphy->rfctrl_intc2_save = b43_phy_read(dev,
+						       B43_NPHY_RFCTL_INTC2);
+		band = b43_current_band(dev->wl);
+		if (dev->phy.rev >= 3) {
+			if (band == IEEE80211_BAND_5GHZ)
+				tmp = 0x600;
+			else
+				tmp = 0x480;
+		} else {
+			if (band == IEEE80211_BAND_5GHZ)
+				tmp = 0x180;
+			else
+				tmp = 0x120;
+		}
+		b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, tmp);
+		b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, tmp);
+	} else {
+		b43_phy_write(dev, B43_NPHY_RFCTL_INTC1,
+				nphy->rfctrl_intc1_save);
+		b43_phy_write(dev, B43_NPHY_RFCTL_INTC2,
+				nphy->rfctrl_intc2_save);
+	}
 }
 
-static void b43_nphy_workarounds(struct b43_wldev *dev)
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */
+static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+	u16 tmp;
+	enum ieee80211_band band = b43_current_band(dev->wl);
+	bool ipa = (nphy->ipa2g_on && band == IEEE80211_BAND_2GHZ) ||
+			(nphy->ipa5g_on && band == IEEE80211_BAND_5GHZ);
+
+	if (dev->phy.rev >= 3) {
+		if (ipa) {
+			tmp = 4;
+			b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
+			      (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
+		}
+
+		tmp = 1;
+		b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S2,
+			      (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
+	}
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
+static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force)
+{
+	u32 tmslow;
+
+	if (dev->phy.type != B43_PHYTYPE_N)
+		return;
+
+	tmslow = ssb_read32(dev->dev, SSB_TMSLOW);
+	if (force)
+		tmslow |= SSB_TMSLOW_FGC;
+	else
+		tmslow &= ~SSB_TMSLOW_FGC;
+	ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */
+static void b43_nphy_reset_cca(struct b43_wldev *dev)
+{
+	u16 bbcfg;
+
+	b43_nphy_bmac_clock_fgc(dev, 1);
+	bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG);
+	b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg | B43_NPHY_BBCFG_RSTCCA);
+	udelay(1);
+	b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA);
+	b43_nphy_bmac_clock_fgc(dev, 0);
+	b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */
+static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble)
+{
+	u16 mimocfg = b43_phy_read(dev, B43_NPHY_MIMOCFG);
+
+	mimocfg |= B43_NPHY_MIMOCFG_AUTO;
+	if (preamble == 1)
+		mimocfg |= B43_NPHY_MIMOCFG_GFMIX;
+	else
+		mimocfg &= ~B43_NPHY_MIMOCFG_GFMIX;
+
+	b43_phy_write(dev, B43_NPHY_MIMOCFG, mimocfg);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */
+static void b43_nphy_update_txrx_chain(struct b43_wldev *dev)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+
+	bool override = false;
+	u16 chain = 0x33;
+
+	if (nphy->txrx_chain == 0) {
+		chain = 0x11;
+		override = true;
+	} else if (nphy->txrx_chain == 1) {
+		chain = 0x22;
+		override = true;
+	}
+
+	b43_phy_maskset(dev, B43_NPHY_RFSEQCA,
+			~(B43_NPHY_RFSEQCA_TXEN | B43_NPHY_RFSEQCA_RXEN),
+			chain);
+
+	if (override)
+		b43_phy_set(dev, B43_NPHY_RFSEQMODE,
+				B43_NPHY_RFSEQMODE_CAOVER);
+	else
+		b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
+				~B43_NPHY_RFSEQMODE_CAOVER);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */
+static void b43_nphy_rx_iq_est(struct b43_wldev *dev, struct nphy_iq_est *est,
+				u16 samps, u8 time, bool wait)
+{
+	int i;
+	u16 tmp;
+
+	b43_phy_write(dev, B43_NPHY_IQEST_SAMCNT, samps);
+	b43_phy_maskset(dev, B43_NPHY_IQEST_WT, ~B43_NPHY_IQEST_WT_VAL, time);
+	if (wait)
+		b43_phy_set(dev, B43_NPHY_IQEST_CMD, B43_NPHY_IQEST_CMD_MODE);
+	else
+		b43_phy_mask(dev, B43_NPHY_IQEST_CMD, ~B43_NPHY_IQEST_CMD_MODE);
+
+	b43_phy_set(dev, B43_NPHY_IQEST_CMD, B43_NPHY_IQEST_CMD_START);
+
+	for (i = 1000; i; i--) {
+		tmp = b43_phy_read(dev, B43_NPHY_IQEST_CMD);
+		if (!(tmp & B43_NPHY_IQEST_CMD_START)) {
+			est->i0_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_IPACC_HI0) << 16) |
+					b43_phy_read(dev, B43_NPHY_IQEST_IPACC_LO0);
+			est->q0_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_QPACC_HI0) << 16) |
+					b43_phy_read(dev, B43_NPHY_IQEST_QPACC_LO0);
+			est->iq0_prod = (b43_phy_read(dev, B43_NPHY_IQEST_IQACC_HI0) << 16) |
+					b43_phy_read(dev, B43_NPHY_IQEST_IQACC_LO0);
+
+			est->i1_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_IPACC_HI1) << 16) |
+					b43_phy_read(dev, B43_NPHY_IQEST_IPACC_LO1);
+			est->q1_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_QPACC_HI1) << 16) |
+					b43_phy_read(dev, B43_NPHY_IQEST_QPACC_LO1);
+			est->iq1_prod = (b43_phy_read(dev, B43_NPHY_IQEST_IQACC_HI1) << 16) |
+					b43_phy_read(dev, B43_NPHY_IQEST_IQACC_LO1);
+			return;
+		}
+		udelay(10);
+	}
+	memset(est, 0, sizeof(*est));
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqCoeffs */
+static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write,
+					struct b43_phy_n_iq_comp *pcomp)
+{
+	if (write) {
+		b43_phy_write(dev, B43_NPHY_C1_RXIQ_COMPA0, pcomp->a0);
+		b43_phy_write(dev, B43_NPHY_C1_RXIQ_COMPB0, pcomp->b0);
+		b43_phy_write(dev, B43_NPHY_C2_RXIQ_COMPA1, pcomp->a1);
+		b43_phy_write(dev, B43_NPHY_C2_RXIQ_COMPB1, pcomp->b1);
+	} else {
+		pcomp->a0 = b43_phy_read(dev, B43_NPHY_C1_RXIQ_COMPA0);
+		pcomp->b0 = b43_phy_read(dev, B43_NPHY_C1_RXIQ_COMPB0);
+		pcomp->a1 = b43_phy_read(dev, B43_NPHY_C2_RXIQ_COMPA1);
+		pcomp->b1 = b43_phy_read(dev, B43_NPHY_C2_RXIQ_COMPB1);
+	}
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhyCleanup */
+static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core)
+{
+	u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
+
+	b43_phy_write(dev, B43_NPHY_RFSEQCA, regs[0]);
+	if (core == 0) {
+		b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[1]);
+		b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]);
+	} else {
+		b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]);
+		b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]);
+	}
+	b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[3]);
+	b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[4]);
+	b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, regs[5]);
+	b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, regs[6]);
+	b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, regs[7]);
+	b43_phy_write(dev, B43_NPHY_RFCTL_OVER, regs[8]);
+	b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]);
+	b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhySetup */
+static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core)
+{
+	u8 rxval, txval;
+	u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
+
+	regs[0] = b43_phy_read(dev, B43_NPHY_RFSEQCA);
+	if (core == 0) {
+		regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
+		regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
+	} else {
+		regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
+		regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
+	}
+	regs[3] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
+	regs[4] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
+	regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
+	regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
+	regs[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S1);
+	regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
+	regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0);
+	regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
+
+	b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001);
+	b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001);
+
+	b43_phy_maskset(dev, B43_NPHY_RFSEQCA, (u16)~B43_NPHY_RFSEQCA_RXDIS,
+			((1 - core) << B43_NPHY_RFSEQCA_RXDIS_SHIFT));
+	b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN,
+			((1 - core) << B43_NPHY_RFSEQCA_TXEN_SHIFT));
+	b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_RXEN,
+			(core << B43_NPHY_RFSEQCA_RXEN_SHIFT));
+	b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXDIS,
+			(core << B43_NPHY_RFSEQCA_TXDIS_SHIFT));
+
+	if (core == 0) {
+		b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x0007);
+		b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0007);
+	} else {
+		b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x0007);
+		b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0007);
+	}
+
+	b43_nphy_rf_control_intc_override(dev, 2, 0, 3);
+	b43_nphy_rf_control_override(dev, 8, 0, 3, false);
+	b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
+
+	if (core == 0) {
+		rxval = 1;
+		txval = 8;
+	} else {
+		rxval = 4;
+		txval = 2;
+	}
+	b43_nphy_rf_control_intc_override(dev, 1, rxval, (core + 1));
+	b43_nphy_rf_control_intc_override(dev, 1, txval, (2 - core));
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */
+static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask)
+{
+	int i;
+	s32 iq;
+	u32 ii;
+	u32 qq;
+	int iq_nbits, qq_nbits;
+	int arsh, brsh;
+	u16 tmp, a, b;
+
+	struct nphy_iq_est est;
+	struct b43_phy_n_iq_comp old;
+	struct b43_phy_n_iq_comp new = { };
+	bool error = false;
+
+	if (mask == 0)
+		return;
+
+	b43_nphy_rx_iq_coeffs(dev, false, &old);
+	b43_nphy_rx_iq_coeffs(dev, true, &new);
+	b43_nphy_rx_iq_est(dev, &est, 0x4000, 32, false);
+	new = old;
+
+	for (i = 0; i < 2; i++) {
+		if (i == 0 && (mask & 1)) {
+			iq = est.iq0_prod;
+			ii = est.i0_pwr;
+			qq = est.q0_pwr;
+		} else if (i == 1 && (mask & 2)) {
+			iq = est.iq1_prod;
+			ii = est.i1_pwr;
+			qq = est.q1_pwr;
+		} else {
+			B43_WARN_ON(1);
+			continue;
+		}
+
+		if (ii + qq < 2) {
+			error = true;
+			break;
+		}
+
+		iq_nbits = fls(abs(iq));
+		qq_nbits = fls(qq);
+
+		arsh = iq_nbits - 20;
+		if (arsh >= 0) {
+			a = -((iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
+			tmp = ii >> arsh;
+		} else {
+			a = -((iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
+			tmp = ii << -arsh;
+		}
+		if (tmp == 0) {
+			error = true;
+			break;
+		}
+		a /= tmp;
+
+		brsh = qq_nbits - 11;
+		if (brsh >= 0) {
+			b = (qq << (31 - qq_nbits));
+			tmp = ii >> brsh;
+		} else {
+			b = (qq << (31 - qq_nbits));
+			tmp = ii << -brsh;
+		}
+		if (tmp == 0) {
+			error = true;
+			break;
+		}
+		b = int_sqrt(b / tmp - a * a) - (1 << 10);
+
+		if (i == 0 && (mask & 0x1)) {
+			if (dev->phy.rev >= 3) {
+				new.a0 = a & 0x3FF;
+				new.b0 = b & 0x3FF;
+			} else {
+				new.a0 = b & 0x3FF;
+				new.b0 = a & 0x3FF;
+			}
+		} else if (i == 1 && (mask & 0x2)) {
+			if (dev->phy.rev >= 3) {
+				new.a1 = a & 0x3FF;
+				new.b1 = b & 0x3FF;
+			} else {
+				new.a1 = b & 0x3FF;
+				new.b1 = a & 0x3FF;
+			}
+		}
+	}
+
+	if (error)
+		new = old;
+
+	b43_nphy_rx_iq_coeffs(dev, true, &new);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxIqWar */
+static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev)
+{
+	u16 array[4];
+	int i;
+
+	b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C50);
+	for (i = 0; i < 4; i++)
+		array[i] = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
+
+	b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW0, array[0]);
+	b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW1, array[1]);
+	b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW2, array[2]);
+	b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW3, array[3]);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */
+static void b43_nphy_write_clip_detection(struct b43_wldev *dev, u16 *clip_st)
+{
+	b43_phy_write(dev, B43_NPHY_C1_CLIP1THRES, clip_st[0]);
+	b43_phy_write(dev, B43_NPHY_C2_CLIP1THRES, clip_st[1]);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */
+static void b43_nphy_read_clip_detection(struct b43_wldev *dev, u16 *clip_st)
+{
+	clip_st[0] = b43_phy_read(dev, B43_NPHY_C1_CLIP1THRES);
+	clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */
+static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
+{
+	u16 tmp;
+
+	if (dev->dev->id.revision == 16)
+		b43_mac_suspend(dev);
+
+	tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL);
+	tmp &= (B43_NPHY_CLASSCTL_CCKEN | B43_NPHY_CLASSCTL_OFDMEN |
+		B43_NPHY_CLASSCTL_WAITEDEN);
+	tmp &= ~mask;
+	tmp |= (val & mask);
+	b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp);
+
+	if (dev->dev->id.revision == 16)
+		b43_mac_enable(dev);
+
+	return tmp;
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/carriersearch */
+static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable)
 {
 	struct b43_phy *phy = &dev->phy;
-	unsigned int i;
+	struct b43_phy_n *nphy = phy->n;
 
-	b43_phy_set(dev, B43_NPHY_IQFLIP,
-		    B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
-	if (1 /* FIXME band is 2.4GHz */) {
-		b43_phy_set(dev, B43_NPHY_CLASSCTL,
-			    B43_NPHY_CLASSCTL_CCKEN);
+	if (enable) {
+		u16 clip[] = { 0xFFFF, 0xFFFF };
+		if (nphy->deaf_count++ == 0) {
+			nphy->classifier_state = b43_nphy_classifier(dev, 0, 0);
+			b43_nphy_classifier(dev, 0x7, 0);
+			b43_nphy_read_clip_detection(dev, nphy->clip_state);
+			b43_nphy_write_clip_detection(dev, clip);
+		}
+		b43_nphy_reset_cca(dev);
 	} else {
-		b43_phy_mask(dev, B43_NPHY_CLASSCTL,
-			     ~B43_NPHY_CLASSCTL_CCKEN);
+		if (--nphy->deaf_count == 0) {
+			b43_nphy_classifier(dev, 0x7, nphy->classifier_state);
+			b43_nphy_write_clip_detection(dev, nphy->clip_state);
+		}
 	}
-	b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8);
-	b43_phy_write(dev, B43_NPHY_TXFRAMEDELAY, 8);
+}
 
-	/* Fixup some tables */
-	b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0xA);
-	b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0xA);
-	b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA);
-	b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA);
-	b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0);
-	b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0);
-	b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB);
-	b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB);
-	b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x800);
-	b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x800);
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */
+static void b43_nphy_stop_playback(struct b43_wldev *dev)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+	u16 tmp;
 
-	b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
-	b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
-	b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
-	b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, 1);
 
-	//TODO set RF sequence
+	tmp = b43_phy_read(dev, B43_NPHY_SAMP_STAT);
+	if (tmp & 0x1)
+		b43_phy_set(dev, B43_NPHY_SAMP_CMD, B43_NPHY_SAMP_CMD_STOP);
+	else if (tmp & 0x2)
+		b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, (u16)~0x8000);
 
-	/* Set narrowband clip threshold */
-	b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 66);
-	b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 66);
+	b43_phy_mask(dev, B43_NPHY_SAMP_CMD, ~0x0004);
 
-	/* Set wideband clip 2 threshold */
-	b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES,
-			~B43_NPHY_C1_CLIPWBTHRES_CLIP2,
-			21 << B43_NPHY_C1_CLIPWBTHRES_CLIP2_SHIFT);
-	b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
-			~B43_NPHY_C2_CLIPWBTHRES_CLIP2,
-			21 << B43_NPHY_C2_CLIPWBTHRES_CLIP2_SHIFT);
+	if (nphy->bb_mult_save & 0x80000000) {
+		tmp = nphy->bb_mult_save & 0xFFFF;
+		b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
+		nphy->bb_mult_save = 0;
+	}
 
-	/* Set Clip 2 detect */
-	b43_phy_set(dev, B43_NPHY_C1_CGAINI,
-		    B43_NPHY_C1_CGAINI_CL2DETECT);
-	b43_phy_set(dev, B43_NPHY_C2_CGAINI,
-		    B43_NPHY_C2_CGAINI_CL2DETECT);
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, 0);
+}
 
-	if (0 /*FIXME*/) {
-		/* Set dwell lengths */
-		b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 43);
-		b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 43);
-		b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 9);
-		b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 9);
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SpurWar */
+static void b43_nphy_spur_workaround(struct b43_wldev *dev)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
 
-		/* Set gain backoff */
-		b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
-				~B43_NPHY_C1_CGAINI_GAINBKOFF,
-				1 << B43_NPHY_C1_CGAINI_GAINBKOFF_SHIFT);
-		b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
-				~B43_NPHY_C2_CGAINI_GAINBKOFF,
-				1 << B43_NPHY_C2_CGAINI_GAINBKOFF_SHIFT);
+	unsigned int channel;
+	int tone[2] = { 57, 58 };
+	u32 noise[2] = { 0x3FF, 0x3FF };
+
+	B43_WARN_ON(dev->phy.rev < 3);
+
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, 1);
+
+	/* FIXME: channel = radio_chanspec */
+
+	if (nphy->gband_spurwar_en) {
+		/* TODO: N PHY Adjust Analog Pfbw (7) */
+		if (channel == 11 && dev->phy.is_40mhz)
+			; /* TODO: N PHY Adjust Min Noise Var(2, tone, noise)*/
+		else
+			; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
+		/* TODO: N PHY Adjust CRS Min Power (0x1E) */
+	}
+
+	if (nphy->aband_spurwar_en) {
+		if (channel == 54) {
+			tone[0] = 0x20;
+			noise[0] = 0x25F;
+		} else if (channel == 38 || channel == 102 || channel == 118) {
+			if (0 /* FIXME */) {
+				tone[0] = 0x20;
+				noise[0] = 0x21F;
+			} else {
+				tone[0] = 0;
+				noise[0] = 0;
+			}
+		} else if (channel == 134) {
+			tone[0] = 0x20;
+			noise[0] = 0x21F;
+		} else if (channel == 151) {
+			tone[0] = 0x10;
+			noise[0] = 0x23F;
+		} else if (channel == 153 || channel == 161) {
+			tone[0] = 0x30;
+			noise[0] = 0x23F;
+		} else {
+			tone[0] = 0;
+			noise[0] = 0;
+		}
+
+		if (!tone[0] && !noise[0])
+			; /* TODO: N PHY Adjust Min Noise Var(1, tone, noise)*/
+		else
+			; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
+	}
+
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, 0);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
+static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+	u8 i, j;
+	u8 code;
+
+	/* TODO: for PHY >= 3
+	s8 *lna1_gain, *lna2_gain;
+	u8 *gain_db, *gain_bits;
+	u16 *rfseq_init;
+	u8 lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 };
+	u8 lpf_bits[6] = { 0, 1, 2, 3, 3, 3 };
+	*/
+
+	u8 rfseq_events[3] = { 6, 8, 7 };
+	u8 rfseq_delays[3] = { 10, 30, 1 };
+
+	if (dev->phy.rev >= 3) {
+		/* TODO */
+	} else {
+		/* Set Clip 2 detect */
+		b43_phy_set(dev, B43_NPHY_C1_CGAINI,
+				B43_NPHY_C1_CGAINI_CL2DETECT);
+		b43_phy_set(dev, B43_NPHY_C2_CGAINI,
+				B43_NPHY_C2_CGAINI_CL2DETECT);
+
+		/* Set narrowband clip threshold */
+		b43_phy_set(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
+		b43_phy_set(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
+
+		if (!dev->phy.is_40mhz) {
+			/* Set dwell lengths */
+			b43_phy_set(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
+			b43_phy_set(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
+			b43_phy_set(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009);
+			b43_phy_set(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009);
+		}
+
+		/* Set wideband clip 2 threshold */
+		b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES,
+				~B43_NPHY_C1_CLIPWBTHRES_CLIP2,
+				21);
+		b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
+				~B43_NPHY_C2_CLIPWBTHRES_CLIP2,
+				21);
+
+		if (!dev->phy.is_40mhz) {
+			b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
+				~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1);
+			b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
+				~B43_NPHY_C2_CGAINI_GAINBKOFF, 0x1);
+			b43_phy_maskset(dev, B43_NPHY_C1_CCK_CGAINI,
+				~B43_NPHY_C1_CCK_CGAINI_GAINBKOFF, 0x1);
+			b43_phy_maskset(dev, B43_NPHY_C2_CCK_CGAINI,
+				~B43_NPHY_C2_CCK_CGAINI_GAINBKOFF, 0x1);
+		}
+
+		b43_phy_set(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C);
+
+		if (nphy->gain_boost) {
+			if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ &&
+			    dev->phy.is_40mhz)
+				code = 4;
+			else
+				code = 5;
+		} else {
+			code = dev->phy.is_40mhz ? 6 : 7;
+		}
 
 		/* Set HPVGA2 index */
 		b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN,
 				~B43_NPHY_C1_INITGAIN_HPVGA2,
-				6 << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT);
+				code << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT);
 		b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN,
 				~B43_NPHY_C2_INITGAIN_HPVGA2,
-				6 << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT);
+				code << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT);
 
-		//FIXME verify that the specs really mean to use autoinc here.
-		for (i = 0; i < 3; i++)
-			b43_ntab_write(dev, B43_NTAB16(7, 0x106) + i, 0x673);
+		b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
+		b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
+					(code << 8 | 0x7C));
+		b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
+					(code << 8 | 0x7C));
+
+		/* TODO: b43_nphy_adjust_lna_gain_table(dev); */
+
+		if (nphy->elna_gain_config) {
+			b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
+
+			b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0C08);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
+
+			b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
+					(code << 8 | 0x74));
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
+					(code << 8 | 0x74));
+		}
+
+		if (dev->phy.rev == 2) {
+			for (i = 0; i < 4; i++) {
+				b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
+						(0x0400 * i) + 0x0020);
+				for (j = 0; j < 21; j++)
+					b43_phy_write(dev,
+						B43_NPHY_TABLE_DATALO, 3 * j);
+			}
+
+			b43_nphy_set_rf_sequence(dev, 5,
+					rfseq_events, rfseq_delays, 3);
+			b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1,
+				(u16)~B43_NPHY_OVER_DGAIN_CCKDGECV,
+				0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT);
+
+			if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+				b43_phy_maskset(dev, B43_PHY_N(0xC5D),
+						0xFF80, 4);
+		}
 	}
+}
 
-	/* Set minimum gain value */
-	b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN,
-			~B43_NPHY_C1_MINGAIN,
-			23 << B43_NPHY_C1_MINGAIN_SHIFT);
-	b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN,
-			~B43_NPHY_C2_MINGAIN,
-			23 << B43_NPHY_C2_MINGAIN_SHIFT);
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */
+static void b43_nphy_workarounds(struct b43_wldev *dev)
+{
+	struct ssb_bus *bus = dev->dev->bus;
+	struct b43_phy *phy = &dev->phy;
+	struct b43_phy_n *nphy = phy->n;
 
-	if (phy->rev < 2) {
-		b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL,
-			     ~B43_NPHY_SCRAM_SIGCTL_SCM);
+	u8 events1[7] = { 0x0, 0x1, 0x2, 0x8, 0x4, 0x5, 0x3 };
+	u8 delays1[7] = { 0x8, 0x6, 0x6, 0x2, 0x4, 0x3C, 0x1 };
+
+	u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 };
+	u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 };
+
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+		b43_nphy_classifier(dev, 1, 0);
+	else
+		b43_nphy_classifier(dev, 1, 1);
+
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, 1);
+
+	b43_phy_set(dev, B43_NPHY_IQFLIP,
+		    B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
+
+	if (dev->phy.rev >= 3) {
+		/* TODO */
+	} else {
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ &&
+		    nphy->band5g_pwrgain) {
+			b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8);
+			b43_radio_mask(dev, B2055_C2_TX_RF_SPARE, ~0x8);
+		} else {
+			b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8);
+			b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8);
+		}
+
+		/* TODO: convert to b43_ntab_write? */
+		b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2000);
+		b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A);
+		b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2010);
+		b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A);
+		b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2002);
+		b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
+		b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2012);
+		b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
+
+		if (dev->phy.rev < 2) {
+			b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2008);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000);
+			b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2018);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000);
+			b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2007);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB);
+			b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2017);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB);
+			b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2006);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
+			b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2016);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
+		}
+
+		b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
+		b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
+		b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
+		b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
+
+		if (bus->sprom.boardflags2_lo & 0x100 &&
+		    bus->boardinfo.type == 0x8B) {
+			delays1[0] = 0x1;
+			delays1[5] = 0x14;
+		}
+		b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7);
+		b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7);
+
+		b43_nphy_gain_crtl_workarounds(dev);
+
+		if (dev->phy.rev < 2) {
+			if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2)
+				; /*TODO: b43_mhf(dev, 2, 0x0010, 0x0010, 3);*/
+		} else if (dev->phy.rev == 2) {
+			b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0);
+			b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0);
+		}
+
+		if (dev->phy.rev < 2)
+			b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL,
+					~B43_NPHY_SCRAM_SIGCTL_SCM);
+
+		/* Set phase track alpha and beta */
+		b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125);
+		b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3);
+		b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105);
+		b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E);
+		b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD);
+		b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20);
+
+		b43_phy_mask(dev, B43_NPHY_PIL_DW1,
+				(u16)~B43_NPHY_PIL_DW_64QAM);
+		b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5);
+		b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4);
+		b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00);
+
+		if (dev->phy.rev == 2)
+			b43_phy_set(dev, B43_NPHY_FINERX2_CGC,
+					B43_NPHY_FINERX2_CGC_DECGC);
 	}
 
-	/* Set phase track alpha and beta */
-	b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125);
-	b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3);
-	b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105);
-	b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E);
-	b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD);
-	b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20);
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, 0);
 }
 
-static void b43_nphy_reset_cca(struct b43_wldev *dev)
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/LoadSampleTable */
+static int b43_nphy_load_samples(struct b43_wldev *dev,
+					struct b43_c32 *samples, u16 len) {
+	struct b43_phy_n *nphy = dev->phy.n;
+	u16 i;
+	u32 *data;
+
+	data = kzalloc(len * sizeof(u32), GFP_KERNEL);
+	if (!data) {
+		b43err(dev->wl, "allocation for samples loading failed\n");
+		return -ENOMEM;
+	}
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, 1);
+
+	for (i = 0; i < len; i++) {
+		data[i] = (samples[i].i & 0x3FF << 10);
+		data[i] |= samples[i].q & 0x3FF;
+	}
+	b43_ntab_write_bulk(dev, B43_NTAB32(17, 0), len, data);
+
+	kfree(data);
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, 0);
+	return 0;
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */
+static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
+					bool test)
 {
-	u16 bbcfg;
+	int i;
+	u16 bw, len, rot, angle;
+	struct b43_c32 *samples;
 
-	ssb_write32(dev->dev, SSB_TMSLOW,
-		    ssb_read32(dev->dev, SSB_TMSLOW) | SSB_TMSLOW_FGC);
-	bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG);
-	b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTCCA);
-	b43_phy_write(dev, B43_NPHY_BBCFG,
-		      bbcfg & ~B43_NPHY_BBCFG_RSTCCA);
-	ssb_write32(dev->dev, SSB_TMSLOW,
-		    ssb_read32(dev->dev, SSB_TMSLOW) & ~SSB_TMSLOW_FGC);
+
+	bw = (dev->phy.is_40mhz) ? 40 : 20;
+	len = bw << 3;
+
+	if (test) {
+		if (b43_phy_read(dev, B43_NPHY_BBCFG) & B43_NPHY_BBCFG_RSTRX)
+			bw = 82;
+		else
+			bw = 80;
+
+		if (dev->phy.is_40mhz)
+			bw <<= 1;
+
+		len = bw << 1;
+	}
+
+	samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL);
+	if (!samples) {
+		b43err(dev->wl, "allocation for samples generation failed\n");
+		return 0;
+	}
+	rot = (((freq * 36) / bw) << 16) / 100;
+	angle = 0;
+
+	for (i = 0; i < len; i++) {
+		samples[i] = b43_cordic(angle);
+		angle += rot;
+		samples[i].q = CORDIC_CONVERT(samples[i].q * max);
+		samples[i].i = CORDIC_CONVERT(samples[i].i * max);
+	}
+
+	i = b43_nphy_load_samples(dev, samples, len);
+	kfree(samples);
+	return (i < 0) ? 0 : len;
 }
 
-enum b43_nphy_rf_sequence {
-	B43_RFSEQ_RX2TX,
-	B43_RFSEQ_TX2RX,
-	B43_RFSEQ_RESET2RX,
-	B43_RFSEQ_UPDATE_GAINH,
-	B43_RFSEQ_UPDATE_GAINL,
-	B43_RFSEQ_UPDATE_GAINU,
-};
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
+static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
+					u16 wait, bool iqmode, bool dac_test)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+	int i;
+	u16 seq_mode;
+	u32 tmp;
+
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, true);
+
+	if ((nphy->bb_mult_save & 0x80000000) == 0) {
+		tmp = b43_ntab_read(dev, B43_NTAB16(15, 87));
+		nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000;
+	}
+
+	if (!dev->phy.is_40mhz)
+		tmp = 0x6464;
+	else
+		tmp = 0x4747;
+	b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
+
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, false);
+
+	b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1));
+
+	if (loops != 0xFFFF)
+		b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, (loops - 1));
+	else
+		b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, loops);
+
+	b43_phy_write(dev, B43_NPHY_SAMP_WAITCNT, wait);
+
+	seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE);
+
+	b43_phy_set(dev, B43_NPHY_RFSEQMODE, B43_NPHY_RFSEQMODE_CAOVER);
+	if (iqmode) {
+		b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF);
+		b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000);
+	} else {
+		if (dac_test)
+			b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5);
+		else
+			b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1);
+	}
+	for (i = 0; i < 100; i++) {
+		if (b43_phy_read(dev, B43_NPHY_RFSEQST) & 1) {
+			i = 0;
+			break;
+		}
+		udelay(10);
+	}
+	if (i)
+		b43err(dev->wl, "run samples timeout\n");
+
+	b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
+}
+
+/*
+ * Transmits a known value for LO calibration
+ * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
+ */
+static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
+				bool iqmode, bool dac_test)
+{
+	u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test);
+	if (samp == 0)
+		return -1;
+	b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test);
+	return 0;
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */
+static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+	int i, j;
+	u32 tmp;
+	u32 cur_real, cur_imag, real_part, imag_part;
+
+	u16 buffer[7];
+
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, true);
+
+	b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
+
+	for (i = 0; i < 2; i++) {
+		tmp = ((buffer[i * 2] & 0x3FF) << 10) |
+			(buffer[i * 2 + 1] & 0x3FF);
+		b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
+				(((i + 26) << 10) | 320));
+		for (j = 0; j < 128; j++) {
+			b43_phy_write(dev, B43_NPHY_TABLE_DATAHI,
+					((tmp >> 16) & 0xFFFF));
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
+					(tmp & 0xFFFF));
+		}
+	}
+
+	for (i = 0; i < 2; i++) {
+		tmp = buffer[5 + i];
+		real_part = (tmp >> 8) & 0xFF;
+		imag_part = (tmp & 0xFF);
+		b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
+				(((i + 26) << 10) | 448));
+
+		if (dev->phy.rev >= 3) {
+			cur_real = real_part;
+			cur_imag = imag_part;
+			tmp = ((cur_real & 0xFF) << 8) | (cur_imag & 0xFF);
+		}
 
+		for (j = 0; j < 128; j++) {
+			if (dev->phy.rev < 3) {
+				cur_real = (real_part * loscale[j] + 128) >> 8;
+				cur_imag = (imag_part * loscale[j] + 128) >> 8;
+				tmp = ((cur_real & 0xFF) << 8) |
+					(cur_imag & 0xFF);
+			}
+			b43_phy_write(dev, B43_NPHY_TABLE_DATAHI,
+					((tmp >> 16) & 0xFFFF));
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
+					(tmp & 0xFFFF));
+		}
+	}
+
+	if (dev->phy.rev >= 3) {
+		b43_shm_write16(dev, B43_SHM_SHARED,
+				B43_SHM_SH_NPHY_TXPWR_INDX0, 0xFFFF);
+		b43_shm_write16(dev, B43_SHM_SHARED,
+				B43_SHM_SH_NPHY_TXPWR_INDX1, 0xFFFF);
+	}
+
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, false);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRfSeq */
+static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
+					u8 *events, u8 *delays, u8 length)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+	u8 i;
+	u8 end = (dev->phy.rev >= 3) ? 0x1F : 0x0F;
+	u16 offset1 = cmd << 4;
+	u16 offset2 = offset1 + 0x80;
+
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, true);
+
+	b43_ntab_write_bulk(dev, B43_NTAB8(7, offset1), length, events);
+	b43_ntab_write_bulk(dev, B43_NTAB8(7, offset2), length, delays);
+
+	for (i = length; i < 16; i++) {
+		b43_ntab_write(dev, B43_NTAB8(7, offset1 + i), end);
+		b43_ntab_write(dev, B43_NTAB8(7, offset2 + i), 1);
+	}
+
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, false);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */
 static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
 				       enum b43_nphy_rf_sequence seq)
 {
@@ -376,6 +1267,7 @@ static void b43_nphy_force_rf_sequence(s
 		[B43_RFSEQ_UPDATE_GAINU]	= B43_NPHY_RFSEQTR_UPGU,
 	};
 	int i;
+	u16 seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE);
 
 	B43_WARN_ON(seq >= ARRAY_SIZE(trigger));
 
@@ -389,8 +1281,181 @@ static void b43_nphy_force_rf_sequence(s
 	}
 	b43err(dev->wl, "RF sequence status timeout\n");
 ok:
-	b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
-		     ~(B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER));
+	b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */
+static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
+						u16 value, u8 core, bool off)
+{
+	int i;
+	u8 index = fls(field);
+	u8 addr, en_addr, val_addr;
+	/* we expect only one bit set */
+	B43_WARN_ON(field & (~(1 << (index - 1))));
+
+	if (dev->phy.rev >= 3) {
+		const struct nphy_rf_control_override_rev3 *rf_ctrl;
+		for (i = 0; i < 2; i++) {
+			if (index == 0 || index == 16) {
+				b43err(dev->wl,
+					"Unsupported RF Ctrl Override call\n");
+				return;
+			}
+
+			rf_ctrl = &tbl_rf_control_override_rev3[index - 1];
+			en_addr = B43_PHY_N((i == 0) ?
+				rf_ctrl->en_addr0 : rf_ctrl->en_addr1);
+			val_addr = B43_PHY_N((i == 0) ?
+				rf_ctrl->val_addr0 : rf_ctrl->val_addr1);
+
+			if (off) {
+				b43_phy_mask(dev, en_addr, ~(field));
+				b43_phy_mask(dev, val_addr,
+						~(rf_ctrl->val_mask));
+			} else {
+				if (core == 0 || ((1 << core) & i) != 0) {
+					b43_phy_set(dev, en_addr, field);
+					b43_phy_maskset(dev, val_addr,
+						~(rf_ctrl->val_mask),
+						(value << rf_ctrl->val_shift));
+				}
+			}
+		}
+	} else {
+		const struct nphy_rf_control_override_rev2 *rf_ctrl;
+		if (off) {
+			b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~(field));
+			value = 0;
+		} else {
+			b43_phy_set(dev, B43_NPHY_RFCTL_OVER, field);
+		}
+
+		for (i = 0; i < 2; i++) {
+			if (index <= 1 || index == 16) {
+				b43err(dev->wl,
+					"Unsupported RF Ctrl Override call\n");
+				return;
+			}
+
+			if (index == 2 || index == 10 ||
+			    (index >= 13 && index <= 15)) {
+				core = 1;
+			}
+
+			rf_ctrl = &tbl_rf_control_override_rev2[index - 2];
+			addr = B43_PHY_N((i == 0) ?
+				rf_ctrl->addr0 : rf_ctrl->addr1);
+
+			if ((core & (1 << i)) != 0)
+				b43_phy_maskset(dev, addr, ~(rf_ctrl->bmask),
+						(value << rf_ctrl->shift));
+
+			b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1);
+			b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
+					B43_NPHY_RFCTL_CMD_START);
+			udelay(1);
+			b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, 0xFFFE);
+		}
+	}
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */
+static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
+						u16 value, u8 core)
+{
+	u8 i, j;
+	u16 reg, tmp, val;
+
+	B43_WARN_ON(dev->phy.rev < 3);
+	B43_WARN_ON(field > 4);
+
+	for (i = 0; i < 2; i++) {
+		if ((core == 1 && i == 1) || (core == 2 && !i))
+			continue;
+
+		reg = (i == 0) ?
+			B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2;
+		b43_phy_mask(dev, reg, 0xFBFF);
+
+		switch (field) {
+		case 0:
+			b43_phy_write(dev, reg, 0);
+			b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
+			break;
+		case 1:
+			if (!i) {
+				b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC1,
+						0xFC3F, (value << 6));
+				b43_phy_maskset(dev, B43_NPHY_TXF_40CO_B1S1,
+						0xFFFE, 1);
+				b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
+						B43_NPHY_RFCTL_CMD_START);
+				for (j = 0; j < 100; j++) {
+					if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START) {
+						j = 0;
+						break;
+					}
+					udelay(10);
+				}
+				if (j)
+					b43err(dev->wl,
+						"intc override timeout\n");
+				b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1,
+						0xFFFE);
+			} else {
+				b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC2,
+						0xFC3F, (value << 6));
+				b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
+						0xFFFE, 1);
+				b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
+						B43_NPHY_RFCTL_CMD_RXTX);
+				for (j = 0; j < 100; j++) {
+					if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX) {
+						j = 0;
+						break;
+					}
+					udelay(10);
+				}
+				if (j)
+					b43err(dev->wl,
+						"intc override timeout\n");
+				b43_phy_mask(dev, B43_NPHY_RFCTL_OVER,
+						0xFFFE);
+			}
+			break;
+		case 2:
+			if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
+				tmp = 0x0020;
+				val = value << 5;
+			} else {
+				tmp = 0x0010;
+				val = value << 4;
+			}
+			b43_phy_maskset(dev, reg, ~tmp, val);
+			break;
+		case 3:
+			if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
+				tmp = 0x0001;
+				val = value;
+			} else {
+				tmp = 0x0004;
+				val = value << 2;
+			}
+			b43_phy_maskset(dev, reg, ~tmp, val);
+			break;
+		case 4:
+			if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
+				tmp = 0x0002;
+				val = value << 1;
+			} else {
+				tmp = 0x0008;
+				val = value << 3;
+			}
+			b43_phy_maskset(dev, reg, ~tmp, val);
+			break;
+		}
+	}
 }
 
 static void b43_nphy_bphy_init(struct b43_wldev *dev)
@@ -411,81 +1476,1680 @@ static void b43_nphy_bphy_init(struct b4
 	b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668);
 }
 
-/* RSSI Calibration */
-static void b43_nphy_rssi_cal(struct b43_wldev *dev, u8 type)
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */
+static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
+				       s8 offset, u8 core, u8 rail, u8 type)
 {
-	//TODO
+	u16 tmp;
+	bool core1or5 = (core == 1) || (core == 5);
+	bool core2or5 = (core == 2) || (core == 5);
+
+	offset = clamp_val(offset, -32, 31);
+	tmp = ((scale & 0x3F) << 8) | (offset & 0x3F);
+
+	if (core1or5 && (rail == 0) && (type == 2))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp);
+	if (core1or5 && (rail == 1) && (type == 2))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp);
+	if (core2or5 && (rail == 0) && (type == 2))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp);
+	if (core2or5 && (rail == 1) && (type == 2))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp);
+	if (core1or5 && (rail == 0) && (type == 0))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp);
+	if (core1or5 && (rail == 1) && (type == 0))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp);
+	if (core2or5 && (rail == 0) && (type == 0))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp);
+	if (core2or5 && (rail == 1) && (type == 0))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp);
+	if (core1or5 && (rail == 0) && (type == 1))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp);
+	if (core1or5 && (rail == 1) && (type == 1))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp);
+	if (core2or5 && (rail == 0) && (type == 1))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp);
+	if (core2or5 && (rail == 1) && (type == 1))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp);
+	if (core1or5 && (rail == 0) && (type == 6))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp);
+	if (core1or5 && (rail == 1) && (type == 6))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp);
+	if (core2or5 && (rail == 0) && (type == 6))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp);
+	if (core2or5 && (rail == 1) && (type == 6))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp);
+	if (core1or5 && (rail == 0) && (type == 3))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp);
+	if (core1or5 && (rail == 1) && (type == 3))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp);
+	if (core2or5 && (rail == 0) && (type == 3))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp);
+	if (core2or5 && (rail == 1) && (type == 3))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp);
+	if (core1or5 && (type == 4))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp);
+	if (core2or5 && (type == 4))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp);
+	if (core1or5 && (type == 5))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp);
+	if (core2or5 && (type == 5))
+		b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp);
+}
+
+static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
+{
+	u16 val;
+
+	if (type < 3)
+		val = 0;
+	else if (type == 6)
+		val = 1;
+	else if (type == 3)
+		val = 2;
+	else
+		val = 3;
+
+	val = (val << 12) | (val << 14);
+	b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val);
+	b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val);
+
+	if (type < 3) {
+		b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF,
+				(type + 1) << 4);
+		b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF,
+				(type + 1) << 4);
+	}
+
+	/* TODO use some definitions */
+	if (code == 0) {
+		b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0);
+		if (type < 3) {
+			b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFEC7, 0);
+			b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xEFDC, 0);
+			b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0);
+			udelay(20);
+			b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0);
+		}
+	} else {
+		b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF,
+				0x3000);
+		if (type < 3) {
+			b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
+					0xFEC7, 0x0180);
+			b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
+					0xEFDC, (code << 1 | 0x1021));
+			b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0x1);
+			udelay(20);
+			b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0);
+		}
+	}
+}
+
+static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+	u8 i;
+	u16 reg, val;
+
+	if (code == 0) {
+		b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, 0xFDFF);
+		b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, 0xFDFF);
+		b43_phy_mask(dev, B43_NPHY_AFECTL_C1, 0xFCFF);
+		b43_phy_mask(dev, B43_NPHY_AFECTL_C2, 0xFCFF);
+		b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S0, 0xFFDF);
+		b43_phy_mask(dev, B43_NPHY_TXF_40CO_B32S1, 0xFFDF);
+		b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0xFFC3);
+		b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0xFFC3);
+	} else {
+		for (i = 0; i < 2; i++) {
+			if ((code == 1 && i == 1) || (code == 2 && !i))
+				continue;
+
+			reg = (i == 0) ?
+				B43_NPHY_AFECTL_OVER1 : B43_NPHY_AFECTL_OVER;
+			b43_phy_maskset(dev, reg, 0xFDFF, 0x0200);
+
+			if (type < 3) {
+				reg = (i == 0) ?
+					B43_NPHY_AFECTL_C1 :
+					B43_NPHY_AFECTL_C2;
+				b43_phy_maskset(dev, reg, 0xFCFF, 0);
+
+				reg = (i == 0) ?
+					B43_NPHY_RFCTL_LUT_TRSW_UP1 :
+					B43_NPHY_RFCTL_LUT_TRSW_UP2;
+				b43_phy_maskset(dev, reg, 0xFFC3, 0);
+
+				if (type == 0)
+					val = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 4 : 8;
+				else if (type == 1)
+					val = 16;
+				else
+					val = 32;
+				b43_phy_set(dev, reg, val);
+
+				reg = (i == 0) ?
+					B43_NPHY_TXF_40CO_B1S0 :
+					B43_NPHY_TXF_40CO_B32S1;
+				b43_phy_set(dev, reg, 0x0020);
+			} else {
+				if (type == 6)
+					val = 0x0100;
+				else if (type == 3)
+					val = 0x0200;
+				else
+					val = 0x0300;
+
+				reg = (i == 0) ?
+					B43_NPHY_AFECTL_C1 :
+					B43_NPHY_AFECTL_C2;
+
+				b43_phy_maskset(dev, reg, 0xFCFF, val);
+				b43_phy_maskset(dev, reg, 0xF3FF, val << 2);
+
+				if (type != 3 && type != 6) {
+					enum ieee80211_band band =
+						b43_current_band(dev->wl);
+
+					if ((nphy->ipa2g_on &&
+						band == IEEE80211_BAND_2GHZ) ||
+						(nphy->ipa5g_on &&
+						band == IEEE80211_BAND_5GHZ))
+						val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
+					else
+						val = 0x11;
+					reg = (i == 0) ? 0x2000 : 0x3000;
+					reg |= B2055_PADDRV;
+					b43_radio_write16(dev, reg, val);
+
+					reg = (i == 0) ?
+						B43_NPHY_AFECTL_OVER1 :
+						B43_NPHY_AFECTL_OVER;
+					b43_phy_set(dev, reg, 0x0200);
+				}
+			}
+		}
+	}
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */
+static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
+{
+	if (dev->phy.rev >= 3)
+		b43_nphy_rev3_rssi_select(dev, code, type);
+	else
+		b43_nphy_rev2_rssi_select(dev, code, type);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */
+static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf)
+{
+	int i;
+	for (i = 0; i < 2; i++) {
+		if (type == 2) {
+			if (i == 0) {
+				b43_radio_maskset(dev, B2055_C1_B0NB_RSSIVCM,
+						  0xFC, buf[0]);
+				b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
+						  0xFC, buf[1]);
+			} else {
+				b43_radio_maskset(dev, B2055_C2_B0NB_RSSIVCM,
+						  0xFC, buf[2 * i]);
+				b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
+						  0xFC, buf[2 * i + 1]);
+			}
+		} else {
+			if (i == 0)
+				b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
+						  0xF3, buf[0] << 2);
+			else
+				b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
+						  0xF3, buf[2 * i + 1] << 2);
+		}
+	}
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */
+static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
+				u8 nsamp)
+{
+	int i;
+	int out;
+	u16 save_regs_phy[9];
+	u16 s[2];
+
+	if (dev->phy.rev >= 3) {
+		save_regs_phy[0] = b43_phy_read(dev,
+						B43_NPHY_RFCTL_LUT_TRSW_UP1);
+		save_regs_phy[1] = b43_phy_read(dev,
+						B43_NPHY_RFCTL_LUT_TRSW_UP2);
+		save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
+		save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
+		save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
+		save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
+		save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
+		save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
+	}
+
+	b43_nphy_rssi_select(dev, 5, type);
+
+	if (dev->phy.rev < 2) {
+		save_regs_phy[8] = b43_phy_read(dev, B43_NPHY_GPIO_SEL);
+		b43_phy_write(dev, B43_NPHY_GPIO_SEL, 5);
+	}
+
+	for (i = 0; i < 4; i++)
+		buf[i] = 0;
+
+	for (i = 0; i < nsamp; i++) {
+		if (dev->phy.rev < 2) {
+			s[0] = b43_phy_read(dev, B43_NPHY_GPIO_LOOUT);
+			s[1] = b43_phy_read(dev, B43_NPHY_GPIO_HIOUT);
+		} else {
+			s[0] = b43_phy_read(dev, B43_NPHY_RSSI1);
+			s[1] = b43_phy_read(dev, B43_NPHY_RSSI2);
+		}
+
+		buf[0] += ((s8)((s[0] & 0x3F) << 2)) >> 2;
+		buf[1] += ((s8)(((s[0] >> 8) & 0x3F) << 2)) >> 2;
+		buf[2] += ((s8)((s[1] & 0x3F) << 2)) >> 2;
+		buf[3] += ((s8)(((s[1] >> 8) & 0x3F) << 2)) >> 2;
+	}
+	out = (buf[0] & 0xFF) << 24 | (buf[1] & 0xFF) << 16 |
+		(buf[2] & 0xFF) << 8 | (buf[3] & 0xFF);
+
+	if (dev->phy.rev < 2)
+		b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]);
+
+	if (dev->phy.rev >= 3) {
+		b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1,
+				save_regs_phy[0]);
+		b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2,
+				save_regs_phy[1]);
+		b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[2]);
+		b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[3]);
+		b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]);
+		b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]);
+		b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]);
+		b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]);
+	}
+
+	return out;
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
+static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
+{
+	int i, j;
+	u8 state[4];
+	u8 code, val;
+	u16 class, override;
+	u8 regs_save_radio[2];
+	u16 regs_save_phy[2];
+	s8 offset[4];
+
+	u16 clip_state[2];
+	u16 clip_off[2] = { 0xFFFF, 0xFFFF };
+	s32 results_min[4] = { };
+	u8 vcm_final[4] = { };
+	s32 results[4][4] = { };
+	s32 miniq[4][2] = { };
+
+	if (type == 2) {
+		code = 0;
+		val = 6;
+	} else if (type < 2) {
+		code = 25;
+		val = 4;
+	} else {
+		B43_WARN_ON(1);
+		return;
+	}
+
+	class = b43_nphy_classifier(dev, 0, 0);
+	b43_nphy_classifier(dev, 7, 4);
+	b43_nphy_read_clip_detection(dev, clip_state);
+	b43_nphy_write_clip_detection(dev, clip_off);
+
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
+		override = 0x140;
+	else
+		override = 0x110;
+
+	regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
+	regs_save_radio[0] = b43_radio_read16(dev, B2055_C1_PD_RXTX);
+	b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override);
+	b43_radio_write16(dev, B2055_C1_PD_RXTX, val);
+
+	regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
+	regs_save_radio[1] = b43_radio_read16(dev, B2055_C2_PD_RXTX);
+	b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override);
+	b43_radio_write16(dev, B2055_C2_PD_RXTX, val);
+
+	state[0] = b43_radio_read16(dev, B2055_C1_PD_RSSIMISC) & 0x07;
+	state[1] = b43_radio_read16(dev, B2055_C2_PD_RSSIMISC) & 0x07;
+	b43_radio_mask(dev, B2055_C1_PD_RSSIMISC, 0xF8);
+	b43_radio_mask(dev, B2055_C2_PD_RSSIMISC, 0xF8);
+	state[2] = b43_radio_read16(dev, B2055_C1_SP_RSSI) & 0x07;
+	state[3] = b43_radio_read16(dev, B2055_C2_SP_RSSI) & 0x07;
+
+	b43_nphy_rssi_select(dev, 5, type);
+	b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 0, type);
+	b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 1, type);
+
+	for (i = 0; i < 4; i++) {
+		u8 tmp[4];
+		for (j = 0; j < 4; j++)
+			tmp[j] = i;
+		if (type != 1)
+			b43_nphy_set_rssi_2055_vcm(dev, type, tmp);
+		b43_nphy_poll_rssi(dev, type, results[i], 8);
+		if (type < 2)
+			for (j = 0; j < 2; j++)
+				miniq[i][j] = min(results[i][2 * j],
+						results[i][2 * j + 1]);
+	}
+
+	for (i = 0; i < 4; i++) {
+		s32 mind = 40;
+		u8 minvcm = 0;
+		s32 minpoll = 249;
+		s32 curr;
+		for (j = 0; j < 4; j++) {
+			if (type == 2)
+				curr = abs(results[j][i]);
+			else
+				curr = abs(miniq[j][i / 2] - code * 8);
+
+			if (curr < mind) {
+				mind = curr;
+				minvcm = j;
+			}
+
+			if (results[j][i] < minpoll)
+				minpoll = results[j][i];
+		}
+		results_min[i] = minpoll;
+		vcm_final[i] = minvcm;
+	}
+
+	if (type != 1)
+		b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final);
+
+	for (i = 0; i < 4; i++) {
+		offset[i] = (code * 8) - results[vcm_final[i]][i];
+
+		if (offset[i] < 0)
+			offset[i] = -((abs(offset[i]) + 4) / 8);
+		else
+			offset[i] = (offset[i] + 4) / 8;
+
+		if (results_min[i] == 248)
+			offset[i] = code - 32;
+
+		if (i % 2 == 0)
+			b43_nphy_scale_offset_rssi(dev, 0, offset[i], 1, 0,
+							type);
+		else
+			b43_nphy_scale_offset_rssi(dev, 0, offset[i], 2, 1,
+							type);
+	}
+
+	b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]);
+	b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[1]);
+
+	switch (state[2]) {
+	case 1:
+		b43_nphy_rssi_select(dev, 1, 2);
+		break;
+	case 4:
+		b43_nphy_rssi_select(dev, 1, 0);
+		break;
+	case 2:
+		b43_nphy_rssi_select(dev, 1, 1);
+		break;
+	default:
+		b43_nphy_rssi_select(dev, 1, 1);
+		break;
+	}
+
+	switch (state[3]) {
+	case 1:
+		b43_nphy_rssi_select(dev, 2, 2);
+		break;
+	case 4:
+		b43_nphy_rssi_select(dev, 2, 0);
+		break;
+	default:
+		b43_nphy_rssi_select(dev, 2, 1);
+		break;
+	}
+
+	b43_nphy_rssi_select(dev, 0, type);
+
+	b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]);
+	b43_radio_write16(dev, B2055_C1_PD_RXTX, regs_save_radio[0]);
+	b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]);
+	b43_radio_write16(dev, B2055_C2_PD_RXTX, regs_save_radio[1]);
+
+	b43_nphy_classifier(dev, 7, class);
+	b43_nphy_write_clip_detection(dev, clip_state);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
+static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
+{
+	/* TODO */
+}
+
+/*
+ * RSSI Calibration
+ * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal
+ */
+static void b43_nphy_rssi_cal(struct b43_wldev *dev)
+{
+	if (dev->phy.rev >= 3) {
+		b43_nphy_rev3_rssi_cal(dev);
+	} else {
+		b43_nphy_rev2_rssi_cal(dev, 2);
+		b43_nphy_rev2_rssi_cal(dev, 0);
+		b43_nphy_rev2_rssi_cal(dev, 1);
+	}
+}
+
+/*
+ * Restore RSSI Calibration
+ * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreRssiCal
+ */
+static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+
+	u16 *rssical_radio_regs = NULL;
+	u16 *rssical_phy_regs = NULL;
+
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+		if (!nphy->rssical_chanspec_2G)
+			return;
+		rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
+		rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
+	} else {
+		if (!nphy->rssical_chanspec_5G)
+			return;
+		rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
+		rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
+	}
+
+	/* TODO use some definitions */
+	b43_radio_maskset(dev, 0x602B, 0xE3, rssical_radio_regs[0]);
+	b43_radio_maskset(dev, 0x702B, 0xE3, rssical_radio_regs[1]);
+
+	b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, rssical_phy_regs[0]);
+	b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, rssical_phy_regs[1]);
+	b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, rssical_phy_regs[2]);
+	b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, rssical_phy_regs[3]);
+
+	b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, rssical_phy_regs[4]);
+	b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, rssical_phy_regs[5]);
+	b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, rssical_phy_regs[6]);
+	b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, rssical_phy_regs[7]);
+
+	b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, rssical_phy_regs[8]);
+	b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, rssical_phy_regs[9]);
+	b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, rssical_phy_regs[10]);
+	b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, rssical_phy_regs[11]);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
+static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
+{
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+		if (dev->phy.rev >= 6) {
+			/* TODO If the chip is 47162
+				return txpwrctrl_tx_gain_ipa_rev5 */
+			return txpwrctrl_tx_gain_ipa_rev6;
+		} else if (dev->phy.rev >= 5) {
+			return txpwrctrl_tx_gain_ipa_rev5;
+		} else {
+			return txpwrctrl_tx_gain_ipa;
+		}
+	} else {
+		return txpwrctrl_tx_gain_ipa_5g;
+	}
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalRadioSetup */
+static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+	u16 *save = nphy->tx_rx_cal_radio_saveregs;
+	u16 tmp;
+	u8 offset, i;
+
+	if (dev->phy.rev >= 3) {
+	    for (i = 0; i < 2; i++) {
+		tmp = (i == 0) ? 0x2000 : 0x3000;
+		offset = i * 11;
+
+		save[offset + 0] = b43_radio_read16(dev, B2055_CAL_RVARCTL);
+		save[offset + 1] = b43_radio_read16(dev, B2055_CAL_LPOCTL);
+		save[offset + 2] = b43_radio_read16(dev, B2055_CAL_TS);
+		save[offset + 3] = b43_radio_read16(dev, B2055_CAL_RCCALRTS);
+		save[offset + 4] = b43_radio_read16(dev, B2055_CAL_RCALRTS);
+		save[offset + 5] = b43_radio_read16(dev, B2055_PADDRV);
+		save[offset + 6] = b43_radio_read16(dev, B2055_XOCTL1);
+		save[offset + 7] = b43_radio_read16(dev, B2055_XOCTL2);
+		save[offset + 8] = b43_radio_read16(dev, B2055_XOREGUL);
+		save[offset + 9] = b43_radio_read16(dev, B2055_XOMISC);
+		save[offset + 10] = b43_radio_read16(dev, B2055_PLL_LFC1);
+
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
+			b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x0A);
+			b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40);
+			b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55);
+			b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0);
+			b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0);
+			if (nphy->ipa5g_on) {
+				b43_radio_write16(dev, tmp | B2055_PADDRV, 4);
+				b43_radio_write16(dev, tmp | B2055_XOCTL1, 1);
+			} else {
+				b43_radio_write16(dev, tmp | B2055_PADDRV, 0);
+				b43_radio_write16(dev, tmp | B2055_XOCTL1, 0x2F);
+			}
+			b43_radio_write16(dev, tmp | B2055_XOCTL2, 0);
+		} else {
+			b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x06);
+			b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40);
+			b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55);
+			b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0);
+			b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0);
+			b43_radio_write16(dev, tmp | B2055_XOCTL1, 0);
+			if (nphy->ipa2g_on) {
+				b43_radio_write16(dev, tmp | B2055_PADDRV, 6);
+				b43_radio_write16(dev, tmp | B2055_XOCTL2,
+					(dev->phy.rev < 5) ? 0x11 : 0x01);
+			} else {
+				b43_radio_write16(dev, tmp | B2055_PADDRV, 0);
+				b43_radio_write16(dev, tmp | B2055_XOCTL2, 0);
+			}
+		}
+		b43_radio_write16(dev, tmp | B2055_XOREGUL, 0);
+		b43_radio_write16(dev, tmp | B2055_XOMISC, 0);
+		b43_radio_write16(dev, tmp | B2055_PLL_LFC1, 0);
+	    }
+	} else {
+		save[0] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL1);
+		b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL1, 0x29);
+
+		save[1] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL2);
+		b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL2, 0x54);
+
+		save[2] = b43_radio_read16(dev, B2055_C2_TX_RF_IQCAL1);
+		b43_radio_write16(dev, B2055_C2_TX_RF_IQCAL1, 0x29);
+
+		save[3] = b43_radio_read16(dev, B2055_C2_TX_RF_IQCAL2);
+		b43_radio_write16(dev, B2055_C2_TX_RF_IQCAL2, 0x54);
+
+		save[3] = b43_radio_read16(dev, B2055_C1_PWRDET_RXTX);
+		save[4] = b43_radio_read16(dev, B2055_C2_PWRDET_RXTX);
+
+		if (!(b43_phy_read(dev, B43_NPHY_BANDCTL) &
+		    B43_NPHY_BANDCTL_5GHZ)) {
+			b43_radio_write16(dev, B2055_C1_PWRDET_RXTX, 0x04);
+			b43_radio_write16(dev, B2055_C2_PWRDET_RXTX, 0x04);
+		} else {
+			b43_radio_write16(dev, B2055_C1_PWRDET_RXTX, 0x20);
+			b43_radio_write16(dev, B2055_C2_PWRDET_RXTX, 0x20);
+		}
+
+		if (dev->phy.rev < 2) {
+			b43_radio_set(dev, B2055_C1_TX_BB_MXGM, 0x20);
+			b43_radio_set(dev, B2055_C2_TX_BB_MXGM, 0x20);
+		} else {
+			b43_radio_mask(dev, B2055_C1_TX_BB_MXGM, ~0x20);
+			b43_radio_mask(dev, B2055_C2_TX_BB_MXGM, ~0x20);
+		}
+	}
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IqCalGainParams */
+static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core,
+					struct nphy_txgains target,
+					struct nphy_iqcal_params *params)
+{
+	int i, j, indx;
+	u16 gain;
+
+	if (dev->phy.rev >= 3) {
+		params->txgm = target.txgm[core];
+		params->pga = target.pga[core];
+		params->pad = target.pad[core];
+		params->ipa = target.ipa[core];
+		params->cal_gain = (params->txgm << 12) | (params->pga << 8) |
+					(params->pad << 4) | (params->ipa);
+		for (j = 0; j < 5; j++)
+			params->ncorr[j] = 0x79;
+	} else {
+		gain = (target.pad[core]) | (target.pga[core] << 4) |
+			(target.txgm[core] << 8);
+
+		indx = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ?
+			1 : 0;
+		for (i = 0; i < 9; i++)
+			if (tbl_iqcal_gainparams[indx][i][0] == gain)
+				break;
+		i = min(i, 8);
+
+		params->txgm = tbl_iqcal_gainparams[indx][i][1];
+		params->pga = tbl_iqcal_gainparams[indx][i][2];
+		params->pad = tbl_iqcal_gainparams[indx][i][3];
+		params->cal_gain = (params->txgm << 7) | (params->pga << 4) |
+					(params->pad << 2);
+		for (j = 0; j < 4; j++)
+			params->ncorr[j] = tbl_iqcal_gainparams[indx][i][4 + j];
+	}
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/UpdateTxCalLadder */
+static void b43_nphy_update_tx_cal_ladder(struct b43_wldev *dev, u16 core)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+	int i;
+	u16 scale, entry;
+
+	u16 tmp = nphy->txcal_bbmult;
+	if (core == 0)
+		tmp >>= 8;
+	tmp &= 0xff;
+
+	for (i = 0; i < 18; i++) {
+		scale = (ladder_lo[i].percent * tmp) / 100;
+		entry = ((scale & 0xFF) << 8) | ladder_lo[i].g_env;
+		b43_ntab_write(dev, B43_NTAB16(15, i), entry);
+
+		scale = (ladder_iq[i].percent * tmp) / 100;
+		entry = ((scale & 0xFF) << 8) | ladder_iq[i].g_env;
+		b43_ntab_write(dev, B43_NTAB16(15, i + 32), entry);
+	}
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ExtPaSetTxDigiFilts */
+static void b43_nphy_ext_pa_set_tx_dig_filters(struct b43_wldev *dev)
+{
+	int i;
+	for (i = 0; i < 15; i++)
+		b43_phy_write(dev, B43_PHY_N(0x2C5 + i),
+				tbl_tx_filter_coef_rev4[2][i]);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IpaSetTxDigiFilts */
+static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev)
+{
+	int i, j;
+	/* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */
+	u16 offset[] = { 0x186, 0x195, 0x2C5 };
+
+	for (i = 0; i < 3; i++)
+		for (j = 0; j < 15; j++)
+			b43_phy_write(dev, B43_PHY_N(offset[i] + j),
+					tbl_tx_filter_coef_rev4[i][j]);
+
+	if (dev->phy.is_40mhz) {
+		for (j = 0; j < 15; j++)
+			b43_phy_write(dev, B43_PHY_N(offset[0] + j),
+					tbl_tx_filter_coef_rev4[3][j]);
+	} else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
+		for (j = 0; j < 15; j++)
+			b43_phy_write(dev, B43_PHY_N(offset[0] + j),
+					tbl_tx_filter_coef_rev4[5][j]);
+	}
+
+	if (dev->phy.channel == 14)
+		for (j = 0; j < 15; j++)
+			b43_phy_write(dev, B43_PHY_N(offset[0] + j),
+					tbl_tx_filter_coef_rev4[6][j]);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */
+static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+
+	u16 curr_gain[2];
+	struct nphy_txgains target;
+	const u32 *table = NULL;
+
+	if (nphy->txpwrctrl == 0) {
+		int i;
+
+		if (nphy->hang_avoid)
+			b43_nphy_stay_in_carrier_search(dev, true);
+		b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, curr_gain);
+		if (nphy->hang_avoid)
+			b43_nphy_stay_in_carrier_search(dev, false);
+
+		for (i = 0; i < 2; ++i) {
+			if (dev->phy.rev >= 3) {
+				target.ipa[i] = curr_gain[i] & 0x000F;
+				target.pad[i] = (curr_gain[i] & 0x00F0) >> 4;
+				target.pga[i] = (curr_gain[i] & 0x0F00) >> 8;
+				target.txgm[i] = (curr_gain[i] & 0x7000) >> 12;
+			} else {
+				target.ipa[i] = curr_gain[i] & 0x0003;
+				target.pad[i] = (curr_gain[i] & 0x000C) >> 2;
+				target.pga[i] = (curr_gain[i] & 0x0070) >> 4;
+				target.txgm[i] = (curr_gain[i] & 0x0380) >> 7;
+			}
+		}
+	} else {
+		int i;
+		u16 index[2];
+		index[0] = (b43_phy_read(dev, B43_NPHY_C1_TXPCTL_STAT) &
+			B43_NPHY_TXPCTL_STAT_BIDX) >>
+			B43_NPHY_TXPCTL_STAT_BIDX_SHIFT;
+		index[1] = (b43_phy_read(dev, B43_NPHY_C2_TXPCTL_STAT) &
+			B43_NPHY_TXPCTL_STAT_BIDX) >>
+			B43_NPHY_TXPCTL_STAT_BIDX_SHIFT;
+
+		for (i = 0; i < 2; ++i) {
+			if (dev->phy.rev >= 3) {
+				enum ieee80211_band band =
+					b43_current_band(dev->wl);
+
+				if ((nphy->ipa2g_on &&
+				     band == IEEE80211_BAND_2GHZ) ||
+				    (nphy->ipa5g_on &&
+				     band == IEEE80211_BAND_5GHZ)) {
+					table = b43_nphy_get_ipa_gain_table(dev);
+				} else {
+					if (band == IEEE80211_BAND_5GHZ) {
+						if (dev->phy.rev == 3)
+							table = b43_ntab_tx_gain_rev3_5ghz;
+						else if (dev->phy.rev == 4)
+							table = b43_ntab_tx_gain_rev4_5ghz;
+						else
+							table = b43_ntab_tx_gain_rev5plus_5ghz;
+					} else {
+						table = b43_ntab_tx_gain_rev3plus_2ghz;
+					}
+				}
+
+				target.ipa[i] = (table[index[i]] >> 16) & 0xF;
+				target.pad[i] = (table[index[i]] >> 20) & 0xF;
+				target.pga[i] = (table[index[i]] >> 24) & 0xF;
+				target.txgm[i] = (table[index[i]] >> 28) & 0xF;
+			} else {
+				table = b43_ntab_tx_gain_rev0_1_2;
+
+				target.ipa[i] = (table[index[i]] >> 16) & 0x3;
+				target.pad[i] = (table[index[i]] >> 18) & 0x3;
+				target.pga[i] = (table[index[i]] >> 20) & 0x7;
+				target.txgm[i] = (table[index[i]] >> 23) & 0x7;
+			}
+		}
+	}
+
+	return target;
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhyCleanup */
+static void b43_nphy_tx_cal_phy_cleanup(struct b43_wldev *dev)
+{
+	u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
+
+	if (dev->phy.rev >= 3) {
+		b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[0]);
+		b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]);
+		b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]);
+		b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[3]);
+		b43_phy_write(dev, B43_NPHY_BBCFG, regs[4]);
+		b43_ntab_write(dev, B43_NTAB16(8, 3), regs[5]);
+		b43_ntab_write(dev, B43_NTAB16(8, 19), regs[6]);
+		b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[7]);
+		b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[8]);
+		b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]);
+		b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]);
+		b43_nphy_reset_cca(dev);
+	} else {
+		b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, regs[0]);
+		b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, regs[1]);
+		b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]);
+		b43_ntab_write(dev, B43_NTAB16(8, 2), regs[3]);
+		b43_ntab_write(dev, B43_NTAB16(8, 18), regs[4]);
+		b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[5]);
+		b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[6]);
+	}
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhySetup */
+static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
+{
+	u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
+	u16 tmp;
+
+	regs[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
+	regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
+	if (dev->phy.rev >= 3) {
+		b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0xF0FF, 0x0A00);
+		b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0xF0FF, 0x0A00);
+
+		tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
+		regs[2] = tmp;
+		b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, tmp | 0x0600);
+
+		tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
+		regs[3] = tmp;
+		b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x0600);
+
+		regs[4] = b43_phy_read(dev, B43_NPHY_BBCFG);
+		b43_phy_mask(dev, B43_NPHY_BBCFG, (u16)~B43_NPHY_BBCFG_RSTRX);
+
+		tmp = b43_ntab_read(dev, B43_NTAB16(8, 3));
+		regs[5] = tmp;
+		b43_ntab_write(dev, B43_NTAB16(8, 3), 0);
+
+		tmp = b43_ntab_read(dev, B43_NTAB16(8, 19));
+		regs[6] = tmp;
+		b43_ntab_write(dev, B43_NTAB16(8, 19), 0);
+		regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
+		regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
+
+		b43_nphy_rf_control_intc_override(dev, 2, 1, 3);
+		b43_nphy_rf_control_intc_override(dev, 1, 2, 1);
+		b43_nphy_rf_control_intc_override(dev, 1, 8, 2);
+
+		regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0);
+		regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
+		b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001);
+		b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001);
+	} else {
+		b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, 0xA000);
+		b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, 0xA000);
+		tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
+		regs[2] = tmp;
+		b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x3000);
+		tmp = b43_ntab_read(dev, B43_NTAB16(8, 2));
+		regs[3] = tmp;
+		tmp |= 0x2000;
+		b43_ntab_write(dev, B43_NTAB16(8, 2), tmp);
+		tmp = b43_ntab_read(dev, B43_NTAB16(8, 18));
+		regs[4] = tmp;
+		tmp |= 0x2000;
+		b43_ntab_write(dev, B43_NTAB16(8, 18), tmp);
+		regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
+		regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
+			tmp = 0x0180;
+		else
+			tmp = 0x0120;
+		b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, tmp);
+		b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, tmp);
+	}
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SaveCal */
+static void b43_nphy_save_cal(struct b43_wldev *dev)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+
+	struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
+	u16 *txcal_radio_regs = NULL;
+	u8 *iqcal_chanspec;
+	u16 *table = NULL;
+
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, 1);
+
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+		rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_2G;
+		txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_2G;
+		iqcal_chanspec = &nphy->iqcal_chanspec_2G;
+		table = nphy->cal_cache.txcal_coeffs_2G;
+	} else {
+		rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_5G;
+		txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_5G;
+		iqcal_chanspec = &nphy->iqcal_chanspec_5G;
+		table = nphy->cal_cache.txcal_coeffs_5G;
+	}
+
+	b43_nphy_rx_iq_coeffs(dev, false, rxcal_coeffs);
+	/* TODO use some definitions */
+	if (dev->phy.rev >= 3) {
+		txcal_radio_regs[0] = b43_radio_read(dev, 0x2021);
+		txcal_radio_regs[1] = b43_radio_read(dev, 0x2022);
+		txcal_radio_regs[2] = b43_radio_read(dev, 0x3021);
+		txcal_radio_regs[3] = b43_radio_read(dev, 0x3022);
+		txcal_radio_regs[4] = b43_radio_read(dev, 0x2023);
+		txcal_radio_regs[5] = b43_radio_read(dev, 0x2024);
+		txcal_radio_regs[6] = b43_radio_read(dev, 0x3023);
+		txcal_radio_regs[7] = b43_radio_read(dev, 0x3024);
+	} else {
+		txcal_radio_regs[0] = b43_radio_read(dev, 0x8B);
+		txcal_radio_regs[1] = b43_radio_read(dev, 0xBA);
+		txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
+		txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
+	}
+	*iqcal_chanspec = nphy->radio_chanspec;
+	b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 8, table);
+
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, 0);
 }
 
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */
+static void b43_nphy_restore_cal(struct b43_wldev *dev)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+
+	u16 coef[4];
+	u16 *loft = NULL;
+	u16 *table = NULL;
+
+	int i;
+	u16 *txcal_radio_regs = NULL;
+	struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
+
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+		if (nphy->iqcal_chanspec_2G == 0)
+			return;
+		table = nphy->cal_cache.txcal_coeffs_2G;
+		loft = &nphy->cal_cache.txcal_coeffs_2G[5];
+	} else {
+		if (nphy->iqcal_chanspec_5G == 0)
+			return;
+		table = nphy->cal_cache.txcal_coeffs_5G;
+		loft = &nphy->cal_cache.txcal_coeffs_5G[5];
+	}
+
+	b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 4, table);
+
+	for (i = 0; i < 4; i++) {
+		if (dev->phy.rev >= 3)
+			table[i] = coef[i];
+		else
+			coef[i] = 0;
+	}
+
+	b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4, coef);
+	b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2, loft);
+	b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2, loft);
+
+	if (dev->phy.rev < 2)
+		b43_nphy_tx_iq_workaround(dev);
+
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+		txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_2G;
+		rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_2G;
+	} else {
+		txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_5G;
+		rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_5G;
+	}
+
+	/* TODO use some definitions */
+	if (dev->phy.rev >= 3) {
+		b43_radio_write(dev, 0x2021, txcal_radio_regs[0]);
+		b43_radio_write(dev, 0x2022, txcal_radio_regs[1]);
+		b43_radio_write(dev, 0x3021, txcal_radio_regs[2]);
+		b43_radio_write(dev, 0x3022, txcal_radio_regs[3]);
+		b43_radio_write(dev, 0x2023, txcal_radio_regs[4]);
+		b43_radio_write(dev, 0x2024, txcal_radio_regs[5]);
+		b43_radio_write(dev, 0x3023, txcal_radio_regs[6]);
+		b43_radio_write(dev, 0x3024, txcal_radio_regs[7]);
+	} else {
+		b43_radio_write(dev, 0x8B, txcal_radio_regs[0]);
+		b43_radio_write(dev, 0xBA, txcal_radio_regs[1]);
+		b43_radio_write(dev, 0x8D, txcal_radio_regs[2]);
+		b43_radio_write(dev, 0xBC, txcal_radio_regs[3]);
+	}
+	b43_nphy_rx_iq_coeffs(dev, true, rxcal_coeffs);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalTxIqlo */
+static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
+				struct nphy_txgains target,
+				bool full, bool mphase)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+	int i;
+	int error = 0;
+	int freq;
+	bool avoid = false;
+	u8 length;
+	u16 tmp, core, type, count, max, numb, last, cmd;
+	const u16 *table;
+	bool phy6or5x;
+
+	u16 buffer[11];
+	u16 diq_start = 0;
+	u16 save[2];
+	u16 gain[2];
+	struct nphy_iqcal_params params[2];
+	bool updated[2] = { };
+
+	b43_nphy_stay_in_carrier_search(dev, true);
+
+	if (dev->phy.rev >= 4) {
+		avoid = nphy->hang_avoid;
+		nphy->hang_avoid = 0;
+	}
+
+	b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, save);
+
+	for (i = 0; i < 2; i++) {
+		b43_nphy_iq_cal_gain_params(dev, i, target, &params[i]);
+		gain[i] = params[i].cal_gain;
+	}
+
+	b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain);
+
+	b43_nphy_tx_cal_radio_setup(dev);
+	b43_nphy_tx_cal_phy_setup(dev);
+
+	phy6or5x = dev->phy.rev >= 6 ||
+		(dev->phy.rev == 5 && nphy->ipa2g_on &&
+		b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ);
+	if (phy6or5x) {
+		if (dev->phy.is_40mhz) {
+			b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
+					tbl_tx_iqlo_cal_loft_ladder_40);
+			b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
+					tbl_tx_iqlo_cal_iqimb_ladder_40);
+		} else {
+			b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
+					tbl_tx_iqlo_cal_loft_ladder_20);
+			b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
+					tbl_tx_iqlo_cal_iqimb_ladder_20);
+		}
+	}
+
+	b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
+
+	if (!dev->phy.is_40mhz)
+		freq = 2500;
+	else
+		freq = 5000;
+
+	if (nphy->mphase_cal_phase_id > 2)
+		b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8,
+					0xFFFF, 0, true, false);
+	else
+		error = b43_nphy_tx_tone(dev, freq, 250, true, false);
+
+	if (error == 0) {
+		if (nphy->mphase_cal_phase_id > 2) {
+			table = nphy->mphase_txcal_bestcoeffs;
+			length = 11;
+			if (dev->phy.rev < 3)
+				length -= 2;
+		} else {
+			if (!full && nphy->txiqlocal_coeffsvalid) {
+				table = nphy->txiqlocal_bestc;
+				length = 11;
+				if (dev->phy.rev < 3)
+					length -= 2;
+			} else {
+				full = true;
+				if (dev->phy.rev >= 3) {
+					table = tbl_tx_iqlo_cal_startcoefs_nphyrev3;
+					length = B43_NTAB_TX_IQLO_CAL_STARTCOEFS_REV3;
+				} else {
+					table = tbl_tx_iqlo_cal_startcoefs;
+					length = B43_NTAB_TX_IQLO_CAL_STARTCOEFS;
+				}
+			}
+		}
+
+		b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length, table);
+
+		if (full) {
+			if (dev->phy.rev >= 3)
+				max = B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3;
+			else
+				max = B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL;
+		} else {
+			if (dev->phy.rev >= 3)
+				max = B43_NTAB_TX_IQLO_CAL_CMDS_RECAL_REV3;
+			else
+				max = B43_NTAB_TX_IQLO_CAL_CMDS_RECAL;
+		}
+
+		if (mphase) {
+			count = nphy->mphase_txcal_cmdidx;
+			numb = min(max,
+				(u16)(count + nphy->mphase_txcal_numcmds));
+		} else {
+			count = 0;
+			numb = max;
+		}
+
+		for (; count < numb; count++) {
+			if (full) {
+				if (dev->phy.rev >= 3)
+					cmd = tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[count];
+				else
+					cmd = tbl_tx_iqlo_cal_cmds_fullcal[count];
+			} else {
+				if (dev->phy.rev >= 3)
+					cmd = tbl_tx_iqlo_cal_cmds_recal_nphyrev3[count];
+				else
+					cmd = tbl_tx_iqlo_cal_cmds_recal[count];
+			}
+
+			core = (cmd & 0x3000) >> 12;
+			type = (cmd & 0x0F00) >> 8;
+
+			if (phy6or5x && updated[core] == 0) {
+				b43_nphy_update_tx_cal_ladder(dev, core);
+				updated[core] = 1;
+			}
+
+			tmp = (params[core].ncorr[type] << 8) | 0x66;
+			b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDNNUM, tmp);
+
+			if (type == 1 || type == 3 || type == 4) {
+				buffer[0] = b43_ntab_read(dev,
+						B43_NTAB16(15, 69 + core));
+				diq_start = buffer[0];
+				buffer[0] = 0;
+				b43_ntab_write(dev, B43_NTAB16(15, 69 + core),
+						0);
+			}
+
+			b43_phy_write(dev, B43_NPHY_IQLOCAL_CMD, cmd);
+			for (i = 0; i < 2000; i++) {
+				tmp = b43_phy_read(dev, B43_NPHY_IQLOCAL_CMD);
+				if (tmp & 0xC000)
+					break;
+				udelay(10);
+			}
+
+			b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
+						buffer);
+			b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length,
+						buffer);
+
+			if (type == 1 || type == 3 || type == 4)
+				buffer[0] = diq_start;
+		}
+
+		if (mphase)
+			nphy->mphase_txcal_cmdidx = (numb >= max) ? 0 : numb;
+
+		last = (dev->phy.rev < 3) ? 6 : 7;
+
+		if (!mphase || nphy->mphase_cal_phase_id == last) {
+			b43_ntab_write_bulk(dev, B43_NTAB16(15, 96), 4, buffer);
+			b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 4, buffer);
+			if (dev->phy.rev < 3) {
+				buffer[0] = 0;
+				buffer[1] = 0;
+				buffer[2] = 0;
+				buffer[3] = 0;
+			}
+			b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4,
+						buffer);
+			b43_ntab_write_bulk(dev, B43_NTAB16(15, 101), 2,
+						buffer);
+			b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2,
+						buffer);
+			b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2,
+						buffer);
+			length = 11;
+			if (dev->phy.rev < 3)
+				length -= 2;
+			b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
+						nphy->txiqlocal_bestc);
+			nphy->txiqlocal_coeffsvalid = true;
+			/* TODO: Set nphy->txiqlocal_chanspec to
+				the current channel */
+		} else {
+			length = 11;
+			if (dev->phy.rev < 3)
+				length -= 2;
+			b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
+						nphy->mphase_txcal_bestcoeffs);
+		}
+
+		b43_nphy_stop_playback(dev);
+		b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0);
+	}
+
+	b43_nphy_tx_cal_phy_cleanup(dev);
+	b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, save);
+
+	if (dev->phy.rev < 2 && (!mphase || nphy->mphase_cal_phase_id == last))
+		b43_nphy_tx_iq_workaround(dev);
+
+	if (dev->phy.rev >= 4)
+		nphy->hang_avoid = avoid;
+
+	b43_nphy_stay_in_carrier_search(dev, false);
+
+	return error;
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ReapplyTxCalCoeffs */
+static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+	u8 i;
+	u16 buffer[7];
+	bool equal = true;
+
+	if (!nphy->txiqlocal_coeffsvalid || 1 /* FIXME */)
+		return;
+
+	b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
+	for (i = 0; i < 4; i++) {
+		if (buffer[i] != nphy->txiqlocal_bestc[i]) {
+			equal = false;
+			break;
+		}
+	}
+
+	if (!equal) {
+		b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 4,
+					nphy->txiqlocal_bestc);
+		for (i = 0; i < 4; i++)
+			buffer[i] = 0;
+		b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4,
+					buffer);
+		b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2,
+					&nphy->txiqlocal_bestc[5]);
+		b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2,
+					&nphy->txiqlocal_bestc[5]);
+	}
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIqRev2 */
+static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
+			struct nphy_txgains target, u8 type, bool debug)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+	int i, j, index;
+	u8 rfctl[2];
+	u8 afectl_core;
+	u16 tmp[6];
+	u16 cur_hpf1, cur_hpf2, cur_lna;
+	u32 real, imag;
+	enum ieee80211_band band;
+
+	u8 use;
+	u16 cur_hpf;
+	u16 lna[3] = { 3, 3, 1 };
+	u16 hpf1[3] = { 7, 2, 0 };
+	u16 hpf2[3] = { 2, 0, 0 };
+	u32 power[3] = { };
+	u16 gain_save[2];
+	u16 cal_gain[2];
+	struct nphy_iqcal_params cal_params[2];
+	struct nphy_iq_est est;
+	int ret = 0;
+	bool playtone = true;
+	int desired = 13;
+
+	b43_nphy_stay_in_carrier_search(dev, 1);
+
+	if (dev->phy.rev < 2)
+		b43_nphy_reapply_tx_cal_coeffs(dev);
+	b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save);
+	for (i = 0; i < 2; i++) {
+		b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]);
+		cal_gain[i] = cal_params[i].cal_gain;
+	}
+	b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, cal_gain);
+
+	for (i = 0; i < 2; i++) {
+		if (i == 0) {
+			rfctl[0] = B43_NPHY_RFCTL_INTC1;
+			rfctl[1] = B43_NPHY_RFCTL_INTC2;
+			afectl_core = B43_NPHY_AFECTL_C1;
+		} else {
+			rfctl[0] = B43_NPHY_RFCTL_INTC2;
+			rfctl[1] = B43_NPHY_RFCTL_INTC1;
+			afectl_core = B43_NPHY_AFECTL_C2;
+		}
+
+		tmp[1] = b43_phy_read(dev, B43_NPHY_RFSEQCA);
+		tmp[2] = b43_phy_read(dev, afectl_core);
+		tmp[3] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
+		tmp[4] = b43_phy_read(dev, rfctl[0]);
+		tmp[5] = b43_phy_read(dev, rfctl[1]);
+
+		b43_phy_maskset(dev, B43_NPHY_RFSEQCA,
+				(u16)~B43_NPHY_RFSEQCA_RXDIS,
+				((1 - i) << B43_NPHY_RFSEQCA_RXDIS_SHIFT));
+		b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN,
+				(1 - i));
+		b43_phy_set(dev, afectl_core, 0x0006);
+		b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0006);
+
+		band = b43_current_band(dev->wl);
+
+		if (nphy->rxcalparams & 0xFF000000) {
+			if (band == IEEE80211_BAND_5GHZ)
+				b43_phy_write(dev, rfctl[0], 0x140);
+			else
+				b43_phy_write(dev, rfctl[0], 0x110);
+		} else {
+			if (band == IEEE80211_BAND_5GHZ)
+				b43_phy_write(dev, rfctl[0], 0x180);
+			else
+				b43_phy_write(dev, rfctl[0], 0x120);
+		}
+
+		if (band == IEEE80211_BAND_5GHZ)
+			b43_phy_write(dev, rfctl[1], 0x148);
+		else
+			b43_phy_write(dev, rfctl[1], 0x114);
+
+		if (nphy->rxcalparams & 0x10000) {
+			b43_radio_maskset(dev, B2055_C1_GENSPARE2, 0xFC,
+					(i + 1));
+			b43_radio_maskset(dev, B2055_C2_GENSPARE2, 0xFC,
+					(2 - i));
+		}
+
+		for (j = 0; i < 4; j++) {
+			if (j < 3) {
+				cur_lna = lna[j];
+				cur_hpf1 = hpf1[j];
+				cur_hpf2 = hpf2[j];
+			} else {
+				if (power[1] > 10000) {
+					use = 1;
+					cur_hpf = cur_hpf1;
+					index = 2;
+				} else {
+					if (power[0] > 10000) {
+						use = 1;
+						cur_hpf = cur_hpf1;
+						index = 1;
+					} else {
+						index = 0;
+						use = 2;
+						cur_hpf = cur_hpf2;
+					}
+				}
+				cur_lna = lna[index];
+				cur_hpf1 = hpf1[index];
+				cur_hpf2 = hpf2[index];
+				cur_hpf += desired - hweight32(power[index]);
+				cur_hpf = clamp_val(cur_hpf, 0, 10);
+				if (use == 1)
+					cur_hpf1 = cur_hpf;
+				else
+					cur_hpf2 = cur_hpf;
+			}
+
+			tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) |
+					(cur_lna << 2));
+			b43_nphy_rf_control_override(dev, 0x400, tmp[0], 3,
+									false);
+			b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
+			b43_nphy_stop_playback(dev);
+
+			if (playtone) {
+				ret = b43_nphy_tx_tone(dev, 4000,
+						(nphy->rxcalparams & 0xFFFF),
+						false, false);
+				playtone = false;
+			} else {
+				b43_nphy_run_samples(dev, 160, 0xFFFF, 0,
+							false, false);
+			}
+
+			if (ret == 0) {
+				if (j < 3) {
+					b43_nphy_rx_iq_est(dev, &est, 1024, 32,
+									false);
+					if (i == 0) {
+						real = est.i0_pwr;
+						imag = est.q0_pwr;
+					} else {
+						real = est.i1_pwr;
+						imag = est.q1_pwr;
+					}
+					power[i] = ((real + imag) / 1024) + 1;
+				} else {
+					b43_nphy_calc_rx_iq_comp(dev, 1 << i);
+				}
+				b43_nphy_stop_playback(dev);
+			}
+
+			if (ret != 0)
+				break;
+		}
+
+		b43_radio_mask(dev, B2055_C1_GENSPARE2, 0xFC);
+		b43_radio_mask(dev, B2055_C2_GENSPARE2, 0xFC);
+		b43_phy_write(dev, rfctl[1], tmp[5]);
+		b43_phy_write(dev, rfctl[0], tmp[4]);
+		b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp[3]);
+		b43_phy_write(dev, afectl_core, tmp[2]);
+		b43_phy_write(dev, B43_NPHY_RFSEQCA, tmp[1]);
+
+		if (ret != 0)
+			break;
+	}
+
+	b43_nphy_rf_control_override(dev, 0x400, 0, 3, true);
+	b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
+	b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save);
+
+	b43_nphy_stay_in_carrier_search(dev, 0);
+
+	return ret;
+}
+
+static int b43_nphy_rev3_cal_rx_iq(struct b43_wldev *dev,
+			struct nphy_txgains target, u8 type, bool debug)
+{
+	return -1;
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIq */
+static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
+			struct nphy_txgains target, u8 type, bool debug)
+{
+	if (dev->phy.rev >= 3)
+		return b43_nphy_rev3_cal_rx_iq(dev, target, type, debug);
+	else
+		return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug);
+}
+
+/*
+ * Init N-PHY
+ * http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N
+ */
 int b43_phy_initn(struct b43_wldev *dev)
 {
+	struct ssb_bus *bus = dev->dev->bus;
 	struct b43_phy *phy = &dev->phy;
+	struct b43_phy_n *nphy = phy->n;
+	u8 tx_pwr_state;
+	struct nphy_txgains target;
 	u16 tmp;
+	enum ieee80211_band tmp2;
+	bool do_rssi_cal;
 
-	//TODO: Spectral management
+	u16 clip[2];
+	bool do_cal = false;
+
+	if ((dev->phy.rev >= 3) &&
+	   (bus->sprom.boardflags_lo & B43_BFL_EXTLNA) &&
+	   (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) {
+		chipco_set32(&dev->dev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40);
+	}
+	nphy->deaf_count = 0;
 	b43_nphy_tables_init(dev);
+	nphy->crsminpwr_adjusted = false;
+	nphy->noisevars_adjusted = false;
 
 	/* Clear all overrides */
-	b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
+	if (dev->phy.rev >= 3) {
+		b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, 0);
+		b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
+		b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, 0);
+		b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, 0);
+	} else {
+		b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
+	}
 	b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, 0);
 	b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, 0);
-	b43_phy_write(dev, B43_NPHY_RFCTL_INTC3, 0);
-	b43_phy_write(dev, B43_NPHY_RFCTL_INTC4, 0);
+	if (dev->phy.rev < 6) {
+		b43_phy_write(dev, B43_NPHY_RFCTL_INTC3, 0);
+		b43_phy_write(dev, B43_NPHY_RFCTL_INTC4, 0);
+	}
 	b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
 		     ~(B43_NPHY_RFSEQMODE_CAOVER |
 		       B43_NPHY_RFSEQMODE_TROVER));
+	if (dev->phy.rev >= 3)
+		b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, 0);
 	b43_phy_write(dev, B43_NPHY_AFECTL_OVER, 0);
 
-	tmp = (phy->rev < 2) ? 64 : 59;
-	b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
-			~B43_NPHY_BPHY_CTL3_SCALE,
-			tmp << B43_NPHY_BPHY_CTL3_SCALE_SHIFT);
-
+	if (dev->phy.rev <= 2) {
+		tmp = (dev->phy.rev == 2) ? 0x3B : 0x40;
+		b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
+				~B43_NPHY_BPHY_CTL3_SCALE,
+				tmp << B43_NPHY_BPHY_CTL3_SCALE_SHIFT);
+	}
 	b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20);
 	b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20);
 
-	b43_phy_write(dev, B43_NPHY_TXREALFD, 184);
-	b43_phy_write(dev, B43_NPHY_MIMO_CRSTXEXT, 200);
-	b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 80);
-	b43_phy_write(dev, B43_NPHY_C2_BCLIPBKOFF, 511);
+	if (bus->sprom.boardflags2_lo & 0x100 ||
+	    (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
+	     bus->boardinfo.type == 0x8B))
+		b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0);
+	else
+		b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8);
+	b43_phy_write(dev, B43_NPHY_MIMO_CRSTXEXT, 0xC8);
+	b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50);
+	b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30);
 
-	//TODO MIMO-Config
-	//TODO Update TX/RX chain
+	b43_nphy_update_mimo_config(dev, nphy->preamble_override);
+	b43_nphy_update_txrx_chain(dev);
 
 	if (phy->rev < 2) {
 		b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8);
 		b43_phy_write(dev, B43_NPHY_DUP40_BL, 0x9A4);
 	}
+
+	tmp2 = b43_current_band(dev->wl);
+	if ((nphy->ipa2g_on && tmp2 == IEEE80211_BAND_2GHZ) ||
+	    (nphy->ipa5g_on && tmp2 == IEEE80211_BAND_5GHZ)) {
+		b43_phy_set(dev, B43_NPHY_PAPD_EN0, 0x1);
+		b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ0, 0x007F,
+				nphy->papd_epsilon_offset[0] << 7);
+		b43_phy_set(dev, B43_NPHY_PAPD_EN1, 0x1);
+		b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ1, 0x007F,
+				nphy->papd_epsilon_offset[1] << 7);
+		b43_nphy_int_pa_set_tx_dig_filters(dev);
+	} else if (phy->rev >= 5) {
+		b43_nphy_ext_pa_set_tx_dig_filters(dev);
+	}
+
 	b43_nphy_workarounds(dev);
-	b43_nphy_reset_cca(dev);
 
-	ssb_write32(dev->dev, SSB_TMSLOW,
-		    ssb_read32(dev->dev, SSB_TMSLOW) | B43_TMSLOW_MACPHYCLKEN);
+	/* Reset CCA, in init code it differs a little from standard way */
+	b43_nphy_bmac_clock_fgc(dev, 1);
+	tmp = b43_phy_read(dev, B43_NPHY_BBCFG);
+	b43_phy_write(dev, B43_NPHY_BBCFG, tmp | B43_NPHY_BBCFG_RSTCCA);
+	b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA);
+	b43_nphy_bmac_clock_fgc(dev, 0);
+
+	/* TODO N PHY MAC PHY Clock Set with argument 1 */
+
+	b43_nphy_pa_override(dev, false);
 	b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
 	b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
+	b43_nphy_pa_override(dev, true);
 
-	b43_phy_read(dev, B43_NPHY_CLASSCTL); /* dummy read */
-	//TODO read core1/2 clip1 thres regs
+	b43_nphy_classifier(dev, 0, 0);
+	b43_nphy_read_clip_detection(dev, clip);
+	tx_pwr_state = nphy->txpwrctrl;
+	/* TODO N PHY TX power control with argument 0
+		(turning off power control) */
+	/* TODO Fix the TX Power Settings */
+	/* TODO N PHY TX Power Control Idle TSSI */
+	/* TODO N PHY TX Power Control Setup */
 
-	if (1 /* FIXME Band is 2.4GHz */)
-		b43_nphy_bphy_init(dev);
-	//TODO disable TX power control
-	//TODO Fix the TX power settings
-	//TODO Init periodic calibration with reason 3
-	b43_nphy_rssi_cal(dev, 2);
-	b43_nphy_rssi_cal(dev, 0);
-	b43_nphy_rssi_cal(dev, 1);
-	//TODO get TX gain
-	//TODO init superswitch
-	//TODO calibrate LO
-	//TODO idle TSSI TX pctl
-	//TODO TX power control power setup
-	//TODO table writes
-	//TODO TX power control coefficients
-	//TODO enable TX power control
-	//TODO control antenna selection
-	//TODO init radar detection
-	//TODO reset channel if changed
+	if (phy->rev >= 3) {
+		/* TODO */
+	} else {
+		b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128,
+					b43_ntab_tx_gain_rev0_1_2);
+		b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128,
+					b43_ntab_tx_gain_rev0_1_2);
+	}
+
+	if (nphy->phyrxchain != 3)
+		;/* TODO N PHY RX Core Set State with phyrxchain as argument */
+	if (nphy->mphase_cal_phase_id > 0)
+		;/* TODO PHY Periodic Calibration Multi-Phase Restart */
+
+	do_rssi_cal = false;
+	if (phy->rev >= 3) {
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+			do_rssi_cal = (nphy->rssical_chanspec_2G == 0);
+		else
+			do_rssi_cal = (nphy->rssical_chanspec_5G == 0);
+
+		if (do_rssi_cal)
+			b43_nphy_rssi_cal(dev);
+		else
+			b43_nphy_restore_rssi_cal(dev);
+	} else {
+		b43_nphy_rssi_cal(dev);
+	}
+
+	if (!((nphy->measure_hold & 0x6) != 0)) {
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+			do_cal = (nphy->iqcal_chanspec_2G == 0);
+		else
+			do_cal = (nphy->iqcal_chanspec_5G == 0);
+
+		if (nphy->mute)
+			do_cal = false;
+
+		if (do_cal) {
+			target = b43_nphy_get_tx_gains(dev);
+
+			if (nphy->antsel_type == 2)
+				;/*TODO NPHY Superswitch Init with argument 1*/
+			if (nphy->perical != 2) {
+				b43_nphy_rssi_cal(dev);
+				if (phy->rev >= 3) {
+					nphy->cal_orig_pwr_idx[0] =
+					    nphy->txpwrindex[0].index_internal;
+					nphy->cal_orig_pwr_idx[1] =
+					    nphy->txpwrindex[1].index_internal;
+					/* TODO N PHY Pre Calibrate TX Gain */
+					target = b43_nphy_get_tx_gains(dev);
+				}
+			}
+		}
+	}
+
+	if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) {
+		if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0)
+			b43_nphy_save_cal(dev);
+		else if (nphy->mphase_cal_phase_id == 0)
+			;/* N PHY Periodic Calibration with argument 3 */
+	} else {
+		b43_nphy_restore_cal(dev);
+	}
+
+	b43_nphy_tx_pwr_ctrl_coef_setup(dev);
+	/* TODO N PHY TX Power Control Enable with argument tx_pwr_state */
+	b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015);
+	b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
+	if (phy->rev >= 3 && phy->rev <= 6)
+		b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0014);
+	b43_nphy_tx_lp_fbw(dev);
+	if (phy->rev >= 3)
+		b43_nphy_spur_workaround(dev);
 
 	b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n");
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_n.h linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/phy_n.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_n.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/phy_n.h	2010-05-16 17:17:36.000000000 -0400
@@ -231,6 +231,7 @@
 #define B43_NPHY_C2_TXIQ_COMP_OFF		B43_PHY_N(0x088) /* Core 2 TX I/Q comp offset */
 #define B43_NPHY_C1_TXCTL			B43_PHY_N(0x08B) /* Core 1 TX control */
 #define B43_NPHY_C2_TXCTL			B43_PHY_N(0x08C) /* Core 2 TX control */
+#define B43_NPHY_AFECTL_OVER1			B43_PHY_N(0x08F) /* AFE control override 1 */
 #define B43_NPHY_SCRAM_SIGCTL			B43_PHY_N(0x090) /* Scram signal control */
 #define  B43_NPHY_SCRAM_SIGCTL_INITST		0x007F /* Initial state value */
 #define  B43_NPHY_SCRAM_SIGCTL_INITST_SHIFT	0
@@ -705,6 +706,10 @@
 #define B43_NPHY_TXPCTL_INIT			B43_PHY_N(0x222) /* TX power controll init */
 #define  B43_NPHY_TXPCTL_INIT_PIDXI1		0x00FF /* Power index init 1 */
 #define  B43_NPHY_TXPCTL_INIT_PIDXI1_SHIFT	0
+#define B43_NPHY_PAPD_EN0			B43_PHY_N(0x297) /* PAPD Enable0 TBD */
+#define B43_NPHY_EPS_TABLE_ADJ0			B43_PHY_N(0x298) /* EPS Table Adj0 TBD */
+#define B43_NPHY_PAPD_EN1			B43_PHY_N(0x29B) /* PAPD Enable1 TBD */
+#define B43_NPHY_EPS_TABLE_ADJ1			B43_PHY_N(0x29C) /* EPS Table Adj1 TBD */
 
 
 
@@ -919,8 +924,99 @@
 
 struct b43_wldev;
 
+struct b43_phy_n_iq_comp {
+	s16 a0;
+	s16 b0;
+	s16 a1;
+	s16 b1;
+};
+
+struct b43_phy_n_rssical_cache {
+	u16 rssical_radio_regs_2G[2];
+	u16 rssical_phy_regs_2G[12];
+
+	u16 rssical_radio_regs_5G[2];
+	u16 rssical_phy_regs_5G[12];
+};
+
+struct b43_phy_n_cal_cache {
+	u16 txcal_radio_regs_2G[8];
+	u16 txcal_coeffs_2G[8];
+	struct b43_phy_n_iq_comp rxcal_coeffs_2G;
+
+	u16 txcal_radio_regs_5G[8];
+	u16 txcal_coeffs_5G[8];
+	struct b43_phy_n_iq_comp rxcal_coeffs_5G;
+};
+
+struct b43_phy_n_txpwrindex {
+	s8 index;
+	s8 index_internal;
+	s8 index_internal_save;
+	u16 AfectrlOverride;
+	u16 AfeCtrlDacGain;
+	u16 rad_gain;
+	u8 bbmult;
+	u16 iqcomp_a;
+	u16 iqcomp_b;
+	u16 locomp;
+};
+
 struct b43_phy_n {
-	//TODO lots of missing stuff
+	u8 antsel_type;
+	u8 cal_orig_pwr_idx[2];
+	u8 measure_hold;
+	u8 phyrxchain;
+	u8 perical;
+	u32 deaf_count;
+	u32 rxcalparams;
+	bool hang_avoid;
+	bool mute;
+	u16 papd_epsilon_offset[2];
+	s32 preamble_override;
+	u32 bb_mult_save;
+	u16 radio_chanspec;
+
+	bool gain_boost;
+	bool elna_gain_config;
+	bool band5g_pwrgain;
+
+	u8 mphase_cal_phase_id;
+	u16 mphase_txcal_cmdidx;
+	u16 mphase_txcal_numcmds;
+	u16 mphase_txcal_bestcoeffs[11];
+
+	u8 txpwrctrl;
+	u16 txcal_bbmult;
+	u16 txiqlocal_bestc[11];
+	bool txiqlocal_coeffsvalid;
+	struct b43_phy_n_txpwrindex txpwrindex[2];
+
+	u8 txrx_chain;
+	u16 tx_rx_cal_phy_saveregs[11];
+	u16 tx_rx_cal_radio_saveregs[22];
+
+	u16 rfctrl_intc1_save;
+	u16 rfctrl_intc2_save;
+
+	u16 classifier_state;
+	u16 clip_state[2];
+
+	bool aband_spurwar_en;
+	bool gband_spurwar_en;
+
+	bool ipa2g_on;
+	u8 iqcal_chanspec_2G;
+	u8 rssical_chanspec_2G;
+
+	bool ipa5g_on;
+	u8 iqcal_chanspec_5G;
+	u8 rssical_chanspec_5G;
+
+	struct b43_phy_n_rssical_cache rssical_cache;
+	struct b43_phy_n_cal_cache cal_cache;
+	bool crsminpwr_adjusted;
+	bool noisevars_adjusted;
 };
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/pio.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/pio.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/pio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/pio.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 
 #include <linux/delay.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 
 static u16 generate_cookie(struct b43_pio_txqueue *q,
@@ -559,7 +560,6 @@ int b43_pio_tx(struct b43_wldev *dev, st
 		b43err(dev->wl, "PIO transmission failure\n");
 		goto out;
 	}
-	q->nr_tx_packets++;
 
 	B43_WARN_ON(q->buffer_used > q->buffer_size);
 	if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) ||
@@ -605,22 +605,6 @@ void b43_pio_handle_txstatus(struct b43_
 	}
 }
 
-void b43_pio_get_tx_stats(struct b43_wldev *dev,
-			  struct ieee80211_tx_queue_stats *stats)
-{
-	const int nr_queues = dev->wl->hw->queues;
-	struct b43_pio_txqueue *q;
-	int i;
-
-	for (i = 0; i < nr_queues; i++) {
-		q = select_queue_by_priority(dev, i);
-
-		stats[i].len = B43_PIO_MAX_NR_TXPACKETS - q->free_packet_slots;
-		stats[i].limit = B43_PIO_MAX_NR_TXPACKETS;
-		stats[i].count = q->nr_tx_packets;
-	}
-}
-
 /* Returns whether we should fetch another frame. */
 static bool pio_rx_frame(struct b43_pio_rxqueue *q)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/pio.h linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/pio.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/pio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/pio.h	2010-05-16 17:17:36.000000000 -0400
@@ -55,8 +55,6 @@
 #define B43_PIO_MAX_NR_TXPACKETS	32
 
 
-#ifdef CONFIG_B43_PIO
-
 struct b43_pio_txpacket {
 	/* Pointer to the TX queue we belong to. */
 	struct b43_pio_txqueue *queue;
@@ -92,9 +90,6 @@ struct b43_pio_txqueue {
 	struct b43_pio_txpacket packets[B43_PIO_MAX_NR_TXPACKETS];
 	struct list_head packets_list;
 
-	/* Total number of transmitted packets. */
-	unsigned int nr_tx_packets;
-
 	/* Shortcut to the 802.11 core revision. This is to
 	 * avoid horrible pointer dereferencing in the fastpaths. */
 	u8 rev;
@@ -162,49 +157,9 @@ void b43_pio_free(struct b43_wldev *dev)
 int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb);
 void b43_pio_handle_txstatus(struct b43_wldev *dev,
 			     const struct b43_txstatus *status);
-void b43_pio_get_tx_stats(struct b43_wldev *dev,
-			  struct ieee80211_tx_queue_stats *stats);
 void b43_pio_rx(struct b43_pio_rxqueue *q);
 
 void b43_pio_tx_suspend(struct b43_wldev *dev);
 void b43_pio_tx_resume(struct b43_wldev *dev);
 
-
-#else /* CONFIG_B43_PIO */
-
-
-static inline int b43_pio_init(struct b43_wldev *dev)
-{
-	return 0;
-}
-static inline void b43_pio_free(struct b43_wldev *dev)
-{
-}
-static inline void b43_pio_stop(struct b43_wldev *dev)
-{
-}
-static inline int b43_pio_tx(struct b43_wldev *dev,
-			     struct sk_buff *skb)
-{
-	return 0;
-}
-static inline void b43_pio_handle_txstatus(struct b43_wldev *dev,
-					   const struct b43_txstatus *status)
-{
-}
-static inline void b43_pio_get_tx_stats(struct b43_wldev *dev,
-					struct ieee80211_tx_queue_stats *stats)
-{
-}
-static inline void b43_pio_rx(struct b43_pio_rxqueue *q)
-{
-}
-static inline void b43_pio_tx_suspend(struct b43_wldev *dev)
-{
-}
-static inline void b43_pio_tx_resume(struct b43_wldev *dev)
-{
-}
-
-#endif /* CONFIG_B43_PIO */
 #endif /* B43_PIO_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/sdio.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/sdio.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/sdio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/sdio.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/mmc/card.h>
 #include <linux/mmc/sdio_func.h>
 #include <linux/mmc/sdio_ids.h>
+#include <linux/slab.h>
 #include <linux/ssb/ssb.h>
 
 #include "sdio.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/tables_nphy.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/tables_nphy.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/tables_nphy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/tables_nphy.c	2010-05-16 17:17:36.000000000 -0400
@@ -1336,7 +1336,7 @@ b43_nphy_get_chantabent(struct b43_wldev
 }
 
 
-const u8 b43_ntab_adjustpower0[] = {
+static const u8 b43_ntab_adjustpower0[] = {
 	0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
 	0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
 	0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
@@ -1355,7 +1355,7 @@ const u8 b43_ntab_adjustpower0[] = {
 	0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F,
 };
 
-const u8 b43_ntab_adjustpower1[] = {
+static const u8 b43_ntab_adjustpower1[] = {
 	0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
 	0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
 	0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
@@ -1374,11 +1374,11 @@ const u8 b43_ntab_adjustpower1[] = {
 	0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F,
 };
 
-const u16 b43_ntab_bdi[] = {
+static const u16 b43_ntab_bdi[] = {
 	0x0070, 0x0126, 0x012C, 0x0246, 0x048D, 0x04D2,
 };
 
-const u32 b43_ntab_channelest[] = {
+static const u32 b43_ntab_channelest[] = {
 	0x44444444, 0x44444444, 0x44444444, 0x44444444,
 	0x44444444, 0x44444444, 0x44444444, 0x44444444,
 	0x10101010, 0x10101010, 0x10101010, 0x10101010,
@@ -1405,7 +1405,7 @@ const u32 b43_ntab_channelest[] = {
 	0x10101010, 0x10101010, 0x10101010, 0x10101010,
 };
 
-const u8 b43_ntab_estimatepowerlt0[] = {
+static const u8 b43_ntab_estimatepowerlt0[] = {
 	0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49,
 	0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41,
 	0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39,
@@ -1416,7 +1416,7 @@ const u8 b43_ntab_estimatepowerlt0[] = {
 	0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
 };
 
-const u8 b43_ntab_estimatepowerlt1[] = {
+static const u8 b43_ntab_estimatepowerlt1[] = {
 	0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49,
 	0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41,
 	0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39,
@@ -1427,14 +1427,14 @@ const u8 b43_ntab_estimatepowerlt1[] = {
 	0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
 };
 
-const u8 b43_ntab_framelookup[] = {
+static const u8 b43_ntab_framelookup[] = {
 	0x02, 0x04, 0x14, 0x14, 0x03, 0x05, 0x16, 0x16,
 	0x0A, 0x0C, 0x1C, 0x1C, 0x0B, 0x0D, 0x1E, 0x1E,
 	0x06, 0x08, 0x18, 0x18, 0x07, 0x09, 0x1A, 0x1A,
 	0x0E, 0x10, 0x20, 0x28, 0x0F, 0x11, 0x22, 0x2A,
 };
 
-const u32 b43_ntab_framestruct[] = {
+static const u32 b43_ntab_framestruct[] = {
 	0x08004A04, 0x00100000, 0x01000A05, 0x00100020,
 	0x09804506, 0x00100030, 0x09804507, 0x00100030,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -1645,7 +1645,7 @@ const u32 b43_ntab_framestruct[] = {
 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
 };
 
-const u32 b43_ntab_gainctl0[] = {
+static const u32 b43_ntab_gainctl0[] = {
 	0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E,
 	0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C,
 	0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A,
@@ -1680,7 +1680,7 @@ const u32 b43_ntab_gainctl0[] = {
 	0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00,
 };
 
-const u32 b43_ntab_gainctl1[] = {
+static const u32 b43_ntab_gainctl1[] = {
 	0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E,
 	0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C,
 	0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A,
@@ -1715,12 +1715,12 @@ const u32 b43_ntab_gainctl1[] = {
 	0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00,
 };
 
-const u32 b43_ntab_intlevel[] = {
+static const u32 b43_ntab_intlevel[] = {
 	0x00802070, 0x0671188D, 0x0A60192C, 0x0A300E46,
 	0x00C1188D, 0x080024D2, 0x00000070,
 };
 
-const u32 b43_ntab_iqlt0[] = {
+static const u32 b43_ntab_iqlt0[] = {
 	0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
 	0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
 	0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
@@ -1755,7 +1755,7 @@ const u32 b43_ntab_iqlt0[] = {
 	0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
 };
 
-const u32 b43_ntab_iqlt1[] = {
+static const u32 b43_ntab_iqlt1[] = {
 	0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
 	0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
 	0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
@@ -1790,7 +1790,7 @@ const u32 b43_ntab_iqlt1[] = {
 	0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
 };
 
-const u16 b43_ntab_loftlt0[] = {
+static const u16 b43_ntab_loftlt0[] = {
 	0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
 	0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
 	0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
@@ -1815,7 +1815,7 @@ const u16 b43_ntab_loftlt0[] = {
 	0x0002, 0x0103,
 };
 
-const u16 b43_ntab_loftlt1[] = {
+static const u16 b43_ntab_loftlt1[] = {
 	0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
 	0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
 	0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
@@ -1840,7 +1840,7 @@ const u16 b43_ntab_loftlt1[] = {
 	0x0002, 0x0103,
 };
 
-const u8 b43_ntab_mcs[] = {
+static const u8 b43_ntab_mcs[] = {
 	0x00, 0x08, 0x0A, 0x10, 0x12, 0x19, 0x1A, 0x1C,
 	0x40, 0x48, 0x4A, 0x50, 0x52, 0x59, 0x5A, 0x5C,
 	0x80, 0x88, 0x8A, 0x90, 0x92, 0x99, 0x9A, 0x9C,
@@ -1859,7 +1859,7 @@ const u8 b43_ntab_mcs[] = {
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
 
-const u32 b43_ntab_noisevar10[] = {
+static const u32 b43_ntab_noisevar10[] = {
 	0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
 	0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
 	0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
@@ -1926,7 +1926,7 @@ const u32 b43_ntab_noisevar10[] = {
 	0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
 };
 
-const u32 b43_ntab_noisevar11[] = {
+static const u32 b43_ntab_noisevar11[] = {
 	0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
 	0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
 	0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
@@ -1993,7 +1993,7 @@ const u32 b43_ntab_noisevar11[] = {
 	0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
 };
 
-const u16 b43_ntab_pilot[] = {
+static const u16 b43_ntab_pilot[] = {
 	0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08,
 	0xFF08, 0xFF08, 0x80D5, 0x80D5, 0x80D5, 0x80D5,
 	0x80D5, 0x80D5, 0x80D5, 0x80D5, 0xFF0A, 0xFF82,
@@ -2011,12 +2011,12 @@ const u16 b43_ntab_pilot[] = {
 	0xF0A0, 0xF028, 0xFFFF, 0xFFFF,
 };
 
-const u32 b43_ntab_pilotlt[] = {
+static const u32 b43_ntab_pilotlt[] = {
 	0x76540123, 0x62407351, 0x76543201, 0x76540213,
 	0x76540123, 0x76430521,
 };
 
-const u32 b43_ntab_tdi20a0[] = {
+static const u32 b43_ntab_tdi20a0[] = {
 	0x00091226, 0x000A1429, 0x000B56AD, 0x000C58B0,
 	0x000D5AB3, 0x000E9CB6, 0x000F9EBA, 0x0000C13D,
 	0x00020301, 0x00030504, 0x00040708, 0x0005090B,
@@ -2033,7 +2033,7 @@ const u32 b43_ntab_tdi20a0[] = {
 	0x00000000, 0x00000000, 0x00000000,
 };
 
-const u32 b43_ntab_tdi20a1[] = {
+static const u32 b43_ntab_tdi20a1[] = {
 	0x00014B26, 0x00028D29, 0x000393AD, 0x00049630,
 	0x0005D833, 0x0006DA36, 0x00099C3A, 0x000A9E3D,
 	0x000BC081, 0x000CC284, 0x000DC488, 0x000F068B,
@@ -2050,7 +2050,7 @@ const u32 b43_ntab_tdi20a1[] = {
 	0x00000000, 0x00000000, 0x00000000,
 };
 
-const u32 b43_ntab_tdi40a0[] = {
+static const u32 b43_ntab_tdi40a0[] = {
 	0x0011A346, 0x00136CCF, 0x0014F5D9, 0x001641E2,
 	0x0017CB6B, 0x00195475, 0x001B2383, 0x001CAD0C,
 	0x001E7616, 0x0000821F, 0x00020BA8, 0x0003D4B2,
@@ -2081,7 +2081,7 @@ const u32 b43_ntab_tdi40a0[] = {
 	0x00000000, 0x00000000,
 };
 
-const u32 b43_ntab_tdi40a1[] = {
+static const u32 b43_ntab_tdi40a1[] = {
 	0x001EDB36, 0x000129CA, 0x0002B353, 0x00047CDD,
 	0x0005C8E6, 0x000791EF, 0x00091BF9, 0x000AAA07,
 	0x000C3391, 0x000DFD1A, 0x00120923, 0x0013D22D,
@@ -2112,7 +2112,7 @@ const u32 b43_ntab_tdi40a1[] = {
 	0x00000000, 0x00000000,
 };
 
-const u32 b43_ntab_tdtrn[] = {
+static const u32 b43_ntab_tdtrn[] = {
 	0x061C061C, 0x0050EE68, 0xF592FE36, 0xFE5212F6,
 	0x00000C38, 0xFE5212F6, 0xF592FE36, 0x0050EE68,
 	0x061C061C, 0xEE680050, 0xFE36F592, 0x12F6FE52,
@@ -2291,7 +2291,7 @@ const u32 b43_ntab_tdtrn[] = {
 	0xFA58FC00, 0x0B64FC7E, 0x0800F7B6, 0x00F006BE,
 };
 
-const u32 b43_ntab_tmap[] = {
+static const u32 b43_ntab_tmap[] = {
 	0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x00000888,
 	0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8,
 	0xF1111110, 0x11111111, 0x11F11111, 0x00000111,
@@ -2406,6 +2406,544 @@ const u32 b43_ntab_tmap[] = {
 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
 };
 
+const u32 b43_ntab_tx_gain_rev0_1_2[] = {
+	0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
+	0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
+	0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844,
+	0x03c82842, 0x03c42b44, 0x03c42b42, 0x03c42a44,
+	0x03c42a42, 0x03c42944, 0x03c42942, 0x03c42844,
+	0x03c42842, 0x03c42744, 0x03c42742, 0x03c42644,
+	0x03c42642, 0x03c42544, 0x03c42542, 0x03c42444,
+	0x03c42442, 0x03c02b44, 0x03c02b42, 0x03c02a44,
+	0x03c02a42, 0x03c02944, 0x03c02942, 0x03c02844,
+	0x03c02842, 0x03c02744, 0x03c02742, 0x03b02b44,
+	0x03b02b42, 0x03b02a44, 0x03b02a42, 0x03b02944,
+	0x03b02942, 0x03b02844, 0x03b02842, 0x03b02744,
+	0x03b02742, 0x03b02644, 0x03b02642, 0x03b02544,
+	0x03b02542, 0x03a02b44, 0x03a02b42, 0x03a02a44,
+	0x03a02a42, 0x03a02944, 0x03a02942, 0x03a02844,
+	0x03a02842, 0x03a02744, 0x03a02742, 0x03902b44,
+	0x03902b42, 0x03902a44, 0x03902a42, 0x03902944,
+	0x03902942, 0x03902844, 0x03902842, 0x03902744,
+	0x03902742, 0x03902644, 0x03902642, 0x03902544,
+	0x03902542, 0x03802b44, 0x03802b42, 0x03802a44,
+	0x03802a42, 0x03802944, 0x03802942, 0x03802844,
+	0x03802842, 0x03802744, 0x03802742, 0x03802644,
+	0x03802642, 0x03802544, 0x03802542, 0x03802444,
+	0x03802442, 0x03802344, 0x03802342, 0x03802244,
+	0x03802242, 0x03802144, 0x03802142, 0x03802044,
+	0x03802042, 0x03801f44, 0x03801f42, 0x03801e44,
+	0x03801e42, 0x03801d44, 0x03801d42, 0x03801c44,
+	0x03801c42, 0x03801b44, 0x03801b42, 0x03801a44,
+	0x03801a42, 0x03801944, 0x03801942, 0x03801844,
+	0x03801842, 0x03801744, 0x03801742, 0x03801644,
+	0x03801642, 0x03801544, 0x03801542, 0x03801444,
+	0x03801442, 0x03801344, 0x03801342, 0x00002b00,
+};
+
+const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
+	0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
+	0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
+	0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
+	0x1e41003c, 0x1e41003b, 0x1e410039, 0x1e410037,
+	0x1d410044, 0x1d410042, 0x1d410040, 0x1d41003e,
+	0x1d41003c, 0x1d41003b, 0x1d410039, 0x1d410037,
+	0x1c410044, 0x1c410042, 0x1c410040, 0x1c41003e,
+	0x1c41003c, 0x1c41003b, 0x1c410039, 0x1c410037,
+	0x1b410044, 0x1b410042, 0x1b410040, 0x1b41003e,
+	0x1b41003c, 0x1b41003b, 0x1b410039, 0x1b410037,
+	0x1a410044, 0x1a410042, 0x1a410040, 0x1a41003e,
+	0x1a41003c, 0x1a41003b, 0x1a410039, 0x1a410037,
+	0x19410044, 0x19410042, 0x19410040, 0x1941003e,
+	0x1941003c, 0x1941003b, 0x19410039, 0x19410037,
+	0x18410044, 0x18410042, 0x18410040, 0x1841003e,
+	0x1841003c, 0x1841003b, 0x18410039, 0x18410037,
+	0x17410044, 0x17410042, 0x17410040, 0x1741003e,
+	0x1741003c, 0x1741003b, 0x17410039, 0x17410037,
+	0x16410044, 0x16410042, 0x16410040, 0x1641003e,
+	0x1641003c, 0x1641003b, 0x16410039, 0x16410037,
+	0x15410044, 0x15410042, 0x15410040, 0x1541003e,
+	0x1541003c, 0x1541003b, 0x15410039, 0x15410037,
+	0x14410044, 0x14410042, 0x14410040, 0x1441003e,
+	0x1441003c, 0x1441003b, 0x14410039, 0x14410037,
+	0x13410044, 0x13410042, 0x13410040, 0x1341003e,
+	0x1341003c, 0x1341003b, 0x13410039, 0x13410037,
+	0x12410044, 0x12410042, 0x12410040, 0x1241003e,
+	0x1241003c, 0x1241003b, 0x12410039, 0x12410037,
+	0x11410044, 0x11410042, 0x11410040, 0x1141003e,
+	0x1141003c, 0x1141003b, 0x11410039, 0x11410037,
+	0x10410044, 0x10410042, 0x10410040, 0x1041003e,
+	0x1041003c, 0x1041003b, 0x10410039, 0x10410037,
+};
+
+const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
+	0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
+	0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
+	0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
+	0xcef7003c, 0xcef7003b, 0xcef70039, 0xcef70037,
+	0xcdf70044, 0xcdf70042, 0xcdf70040, 0xcdf7003e,
+	0xcdf7003c, 0xcdf7003b, 0xcdf70039, 0xcdf70037,
+	0xccf70044, 0xccf70042, 0xccf70040, 0xccf7003e,
+	0xccf7003c, 0xccf7003b, 0xccf70039, 0xccf70037,
+	0xcbf70044, 0xcbf70042, 0xcbf70040, 0xcbf7003e,
+	0xcbf7003c, 0xcbf7003b, 0xcbf70039, 0xcbf70037,
+	0xcaf70044, 0xcaf70042, 0xcaf70040, 0xcaf7003e,
+	0xcaf7003c, 0xcaf7003b, 0xcaf70039, 0xcaf70037,
+	0xc9f70044, 0xc9f70042, 0xc9f70040, 0xc9f7003e,
+	0xc9f7003c, 0xc9f7003b, 0xc9f70039, 0xc9f70037,
+	0xc8f70044, 0xc8f70042, 0xc8f70040, 0xc8f7003e,
+	0xc8f7003c, 0xc8f7003b, 0xc8f70039, 0xc8f70037,
+	0xc7f70044, 0xc7f70042, 0xc7f70040, 0xc7f7003e,
+	0xc7f7003c, 0xc7f7003b, 0xc7f70039, 0xc7f70037,
+	0xc6f70044, 0xc6f70042, 0xc6f70040, 0xc6f7003e,
+	0xc6f7003c, 0xc6f7003b, 0xc6f70039, 0xc6f70037,
+	0xc5f70044, 0xc5f70042, 0xc5f70040, 0xc5f7003e,
+	0xc5f7003c, 0xc5f7003b, 0xc5f70039, 0xc5f70037,
+	0xc4f70044, 0xc4f70042, 0xc4f70040, 0xc4f7003e,
+	0xc4f7003c, 0xc4f7003b, 0xc4f70039, 0xc4f70037,
+	0xc3f70044, 0xc3f70042, 0xc3f70040, 0xc3f7003e,
+	0xc3f7003c, 0xc3f7003b, 0xc3f70039, 0xc3f70037,
+	0xc2f70044, 0xc2f70042, 0xc2f70040, 0xc2f7003e,
+	0xc2f7003c, 0xc2f7003b, 0xc2f70039, 0xc2f70037,
+	0xc1f70044, 0xc1f70042, 0xc1f70040, 0xc1f7003e,
+	0xc1f7003c, 0xc1f7003b, 0xc1f70039, 0xc1f70037,
+	0xc0f70044, 0xc0f70042, 0xc0f70040, 0xc0f7003e,
+	0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037,
+};
+
+const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
+	0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
+	0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
+	0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
+	0x2ef2003c, 0x2ef2003b, 0x2ef20039, 0x2ef20037,
+	0x2df20044, 0x2df20042, 0x2df20040, 0x2df2003e,
+	0x2df2003c, 0x2df2003b, 0x2df20039, 0x2df20037,
+	0x2cf20044, 0x2cf20042, 0x2cf20040, 0x2cf2003e,
+	0x2cf2003c, 0x2cf2003b, 0x2cf20039, 0x2cf20037,
+	0x2bf20044, 0x2bf20042, 0x2bf20040, 0x2bf2003e,
+	0x2bf2003c, 0x2bf2003b, 0x2bf20039, 0x2bf20037,
+	0x2af20044, 0x2af20042, 0x2af20040, 0x2af2003e,
+	0x2af2003c, 0x2af2003b, 0x2af20039, 0x2af20037,
+	0x29f20044, 0x29f20042, 0x29f20040, 0x29f2003e,
+	0x29f2003c, 0x29f2003b, 0x29f20039, 0x29f20037,
+	0x28f20044, 0x28f20042, 0x28f20040, 0x28f2003e,
+	0x28f2003c, 0x28f2003b, 0x28f20039, 0x28f20037,
+	0x27f20044, 0x27f20042, 0x27f20040, 0x27f2003e,
+	0x27f2003c, 0x27f2003b, 0x27f20039, 0x27f20037,
+	0x26f20044, 0x26f20042, 0x26f20040, 0x26f2003e,
+	0x26f2003c, 0x26f2003b, 0x26f20039, 0x26f20037,
+	0x25f20044, 0x25f20042, 0x25f20040, 0x25f2003e,
+	0x25f2003c, 0x25f2003b, 0x25f20039, 0x25f20037,
+	0x24f20044, 0x24f20042, 0x24f20040, 0x24f2003e,
+	0x24f2003c, 0x24f2003b, 0x24f20039, 0x24f20038,
+	0x23f20041, 0x23f20040, 0x23f2003f, 0x23f2003e,
+	0x23f2003c, 0x23f2003b, 0x23f20039, 0x23f20037,
+	0x22f20044, 0x22f20042, 0x22f20040, 0x22f2003e,
+	0x22f2003c, 0x22f2003b, 0x22f20039, 0x22f20037,
+	0x21f20044, 0x21f20042, 0x21f20040, 0x21f2003e,
+	0x21f2003c, 0x21f2003b, 0x21f20039, 0x21f20037,
+	0x20d20043, 0x20d20041, 0x20d2003e, 0x20d2003c,
+	0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034,
+};
+
+const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
+	0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
+	0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
+	0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
+	0x0e62003c, 0x0e62003d, 0x0e62003b, 0x0e62003a,
+	0x0d620043, 0x0d620041, 0x0d620040, 0x0d62003e,
+	0x0d62003d, 0x0d62003c, 0x0d62003b, 0x0d62003a,
+	0x0c620041, 0x0c620040, 0x0c62003f, 0x0c62003e,
+	0x0c62003c, 0x0c62003b, 0x0c620039, 0x0c620037,
+	0x0b620046, 0x0b620044, 0x0b620042, 0x0b620040,
+	0x0b62003e, 0x0b62003c, 0x0b62003b, 0x0b62003a,
+	0x0a620041, 0x0a620040, 0x0a62003e, 0x0a62003c,
+	0x0a62003b, 0x0a62003a, 0x0a620039, 0x0a620038,
+	0x0962003e, 0x0962003d, 0x0962003c, 0x0962003b,
+	0x09620039, 0x09620037, 0x09620035, 0x09620033,
+	0x08620044, 0x08620042, 0x08620040, 0x0862003e,
+	0x0862003c, 0x0862003b, 0x0862003a, 0x08620039,
+	0x07620043, 0x07620042, 0x07620040, 0x0762003f,
+	0x0762003d, 0x0762003b, 0x0762003a, 0x07620039,
+	0x0662003e, 0x0662003d, 0x0662003c, 0x0662003b,
+	0x06620039, 0x06620037, 0x06620035, 0x06620033,
+	0x05620046, 0x05620044, 0x05620042, 0x05620040,
+	0x0562003e, 0x0562003c, 0x0562003b, 0x05620039,
+	0x04620044, 0x04620042, 0x04620040, 0x0462003e,
+	0x0462003c, 0x0462003b, 0x04620039, 0x04620038,
+	0x0362003c, 0x0362003b, 0x0362003a, 0x03620039,
+	0x03620038, 0x03620037, 0x03620035, 0x03620033,
+	0x0262004c, 0x0262004a, 0x02620048, 0x02620047,
+	0x02620046, 0x02620044, 0x02620043, 0x02620042,
+	0x0162004a, 0x01620048, 0x01620046, 0x01620044,
+	0x01620043, 0x01620042, 0x01620041, 0x01620040,
+	0x00620042, 0x00620040, 0x0062003e, 0x0062003c,
+	0x0062003b, 0x00620039, 0x00620037, 0x00620035,
+};
+
+const u32 txpwrctrl_tx_gain_ipa[] = {
+	0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
+	0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
+	0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
+	0x5ef70028, 0x5ef70027, 0x5ef70026, 0x5ef70025,
+	0x5df7002d, 0x5df7002b, 0x5df7002a, 0x5df70029,
+	0x5df70028, 0x5df70027, 0x5df70026, 0x5df70025,
+	0x5cf7002d, 0x5cf7002b, 0x5cf7002a, 0x5cf70029,
+	0x5cf70028, 0x5cf70027, 0x5cf70026, 0x5cf70025,
+	0x5bf7002d, 0x5bf7002b, 0x5bf7002a, 0x5bf70029,
+	0x5bf70028, 0x5bf70027, 0x5bf70026, 0x5bf70025,
+	0x5af7002d, 0x5af7002b, 0x5af7002a, 0x5af70029,
+	0x5af70028, 0x5af70027, 0x5af70026, 0x5af70025,
+	0x59f7002d, 0x59f7002b, 0x59f7002a, 0x59f70029,
+	0x59f70028, 0x59f70027, 0x59f70026, 0x59f70025,
+	0x58f7002d, 0x58f7002b, 0x58f7002a, 0x58f70029,
+	0x58f70028, 0x58f70027, 0x58f70026, 0x58f70025,
+	0x57f7002d, 0x57f7002b, 0x57f7002a, 0x57f70029,
+	0x57f70028, 0x57f70027, 0x57f70026, 0x57f70025,
+	0x56f7002d, 0x56f7002b, 0x56f7002a, 0x56f70029,
+	0x56f70028, 0x56f70027, 0x56f70026, 0x56f70025,
+	0x55f7002d, 0x55f7002b, 0x55f7002a, 0x55f70029,
+	0x55f70028, 0x55f70027, 0x55f70026, 0x55f70025,
+	0x54f7002d, 0x54f7002b, 0x54f7002a, 0x54f70029,
+	0x54f70028, 0x54f70027, 0x54f70026, 0x54f70025,
+	0x53f7002d, 0x53f7002b, 0x53f7002a, 0x53f70029,
+	0x53f70028, 0x53f70027, 0x53f70026, 0x53f70025,
+	0x52f7002d, 0x52f7002b, 0x52f7002a, 0x52f70029,
+	0x52f70028, 0x52f70027, 0x52f70026, 0x52f70025,
+	0x51f7002d, 0x51f7002b, 0x51f7002a, 0x51f70029,
+	0x51f70028, 0x51f70027, 0x51f70026, 0x51f70025,
+	0x50f7002d, 0x50f7002b, 0x50f7002a, 0x50f70029,
+	0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025,
+};
+
+const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
+	0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
+	0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
+	0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
+	0x1ef70028, 0x1ef70027, 0x1ef70026, 0x1ef70025,
+	0x1df7002d, 0x1df7002b, 0x1df7002a, 0x1df70029,
+	0x1df70028, 0x1df70027, 0x1df70026, 0x1df70025,
+	0x1cf7002d, 0x1cf7002b, 0x1cf7002a, 0x1cf70029,
+	0x1cf70028, 0x1cf70027, 0x1cf70026, 0x1cf70025,
+	0x1bf7002d, 0x1bf7002b, 0x1bf7002a, 0x1bf70029,
+	0x1bf70028, 0x1bf70027, 0x1bf70026, 0x1bf70025,
+	0x1af7002d, 0x1af7002b, 0x1af7002a, 0x1af70029,
+	0x1af70028, 0x1af70027, 0x1af70026, 0x1af70025,
+	0x19f7002d, 0x19f7002b, 0x19f7002a, 0x19f70029,
+	0x19f70028, 0x19f70027, 0x19f70026, 0x19f70025,
+	0x18f7002d, 0x18f7002b, 0x18f7002a, 0x18f70029,
+	0x18f70028, 0x18f70027, 0x18f70026, 0x18f70025,
+	0x17f7002d, 0x17f7002b, 0x17f7002a, 0x17f70029,
+	0x17f70028, 0x17f70027, 0x17f70026, 0x17f70025,
+	0x16f7002d, 0x16f7002b, 0x16f7002a, 0x16f70029,
+	0x16f70028, 0x16f70027, 0x16f70026, 0x16f70025,
+	0x15f7002d, 0x15f7002b, 0x15f7002a, 0x15f70029,
+	0x15f70028, 0x15f70027, 0x15f70026, 0x15f70025,
+	0x14f7002d, 0x14f7002b, 0x14f7002a, 0x14f70029,
+	0x14f70028, 0x14f70027, 0x14f70026, 0x14f70025,
+	0x13f7002d, 0x13f7002b, 0x13f7002a, 0x13f70029,
+	0x13f70028, 0x13f70027, 0x13f70026, 0x13f70025,
+	0x12f7002d, 0x12f7002b, 0x12f7002a, 0x12f70029,
+	0x12f70028, 0x12f70027, 0x12f70026, 0x12f70025,
+	0x11f7002d, 0x11f7002b, 0x11f7002a, 0x11f70029,
+	0x11f70028, 0x11f70027, 0x11f70026, 0x11f70025,
+	0x10f7002d, 0x10f7002b, 0x10f7002a, 0x10f70029,
+	0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025,
+};
+
+const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
+	0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
+	0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
+	0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
+	0x0ef70028, 0x0ef70027, 0x0ef70026, 0x0ef70025,
+	0x0df7002d, 0x0df7002b, 0x0df7002a, 0x0df70029,
+	0x0df70028, 0x0df70027, 0x0df70026, 0x0df70025,
+	0x0cf7002d, 0x0cf7002b, 0x0cf7002a, 0x0cf70029,
+	0x0cf70028, 0x0cf70027, 0x0cf70026, 0x0cf70025,
+	0x0bf7002d, 0x0bf7002b, 0x0bf7002a, 0x0bf70029,
+	0x0bf70028, 0x0bf70027, 0x0bf70026, 0x0bf70025,
+	0x0af7002d, 0x0af7002b, 0x0af7002a, 0x0af70029,
+	0x0af70028, 0x0af70027, 0x0af70026, 0x0af70025,
+	0x09f7002d, 0x09f7002b, 0x09f7002a, 0x09f70029,
+	0x09f70028, 0x09f70027, 0x09f70026, 0x09f70025,
+	0x08f7002d, 0x08f7002b, 0x08f7002a, 0x08f70029,
+	0x08f70028, 0x08f70027, 0x08f70026, 0x08f70025,
+	0x07f7002d, 0x07f7002b, 0x07f7002a, 0x07f70029,
+	0x07f70028, 0x07f70027, 0x07f70026, 0x07f70025,
+	0x06f7002d, 0x06f7002b, 0x06f7002a, 0x06f70029,
+	0x06f70028, 0x06f70027, 0x06f70026, 0x06f70025,
+	0x05f7002d, 0x05f7002b, 0x05f7002a, 0x05f70029,
+	0x05f70028, 0x05f70027, 0x05f70026, 0x05f70025,
+	0x04f7002d, 0x04f7002b, 0x04f7002a, 0x04f70029,
+	0x04f70028, 0x04f70027, 0x04f70026, 0x04f70025,
+	0x03f7002d, 0x03f7002b, 0x03f7002a, 0x03f70029,
+	0x03f70028, 0x03f70027, 0x03f70026, 0x03f70025,
+	0x02f7002d, 0x02f7002b, 0x02f7002a, 0x02f70029,
+	0x02f70028, 0x02f70027, 0x02f70026, 0x02f70025,
+	0x01f7002d, 0x01f7002b, 0x01f7002a, 0x01f70029,
+	0x01f70028, 0x01f70027, 0x01f70026, 0x01f70025,
+	0x00f7002d, 0x00f7002b, 0x00f7002a, 0x00f70029,
+	0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025,
+};
+
+const u32 txpwrctrl_tx_gain_ipa_5g[] = {
+	0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
+	0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
+	0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
+	0x7ff70026, 0x7ff70024, 0x7ff70023, 0x7ff70022,
+	0x7ef70028, 0x7ef70027, 0x7ef70026, 0x7ef70025,
+	0x7ef70024, 0x7ef70023, 0x7df70028, 0x7df70027,
+	0x7df70026, 0x7df70025, 0x7df70024, 0x7df70023,
+	0x7df70022, 0x7cf70029, 0x7cf70028, 0x7cf70027,
+	0x7cf70026, 0x7cf70025, 0x7cf70023, 0x7cf70022,
+	0x7bf70029, 0x7bf70028, 0x7bf70026, 0x7bf70025,
+	0x7bf70024, 0x7bf70023, 0x7bf70022, 0x7bf70021,
+	0x7af70029, 0x7af70028, 0x7af70027, 0x7af70026,
+	0x7af70025, 0x7af70024, 0x7af70023, 0x7af70022,
+	0x79f70029, 0x79f70028, 0x79f70027, 0x79f70026,
+	0x79f70025, 0x79f70024, 0x79f70023, 0x79f70022,
+	0x78f70029, 0x78f70028, 0x78f70027, 0x78f70026,
+	0x78f70025, 0x78f70024, 0x78f70023, 0x78f70022,
+	0x77f70029, 0x77f70028, 0x77f70027, 0x77f70026,
+	0x77f70025, 0x77f70024, 0x77f70023, 0x77f70022,
+	0x76f70029, 0x76f70028, 0x76f70027, 0x76f70026,
+	0x76f70024, 0x76f70023, 0x76f70022, 0x76f70021,
+	0x75f70029, 0x75f70028, 0x75f70027, 0x75f70026,
+	0x75f70025, 0x75f70024, 0x75f70023, 0x74f70029,
+	0x74f70028, 0x74f70026, 0x74f70025, 0x74f70024,
+	0x74f70023, 0x74f70022, 0x73f70029, 0x73f70027,
+	0x73f70026, 0x73f70025, 0x73f70024, 0x73f70023,
+	0x73f70022, 0x72f70028, 0x72f70027, 0x72f70026,
+	0x72f70025, 0x72f70024, 0x72f70023, 0x72f70022,
+	0x71f70028, 0x71f70027, 0x71f70026, 0x71f70025,
+	0x71f70024, 0x71f70023, 0x70f70028, 0x70f70027,
+	0x70f70026, 0x70f70024, 0x70f70023, 0x70f70022,
+	0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f,
+};
+
+const u16 tbl_iqcal_gainparams[2][9][8] = {
+	{
+		{ 0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69 },
+		{ 0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69 },
+		{ 0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68 },
+		{ 0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67 },
+		{ 0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66 },
+		{ 0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65 },
+		{ 0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65 },
+		{ 0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65 },
+		{ 0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65 }
+	},
+	{
+		{ 0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79 },
+		{ 0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79 },
+		{ 0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79 },
+		{ 0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78 },
+		{ 0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78 },
+		{ 0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78 },
+		{ 0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78 },
+		{ 0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78 },
+		{ 0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78 }
+	}
+};
+
+const struct nphy_txiqcal_ladder ladder_lo[] = {
+	{ 3, 0 },
+	{ 4, 0 },
+	{ 6, 0 },
+	{ 9, 0 },
+	{ 13, 0 },
+	{ 18, 0 },
+	{ 25, 0 },
+	{ 25, 1 },
+	{ 25, 2 },
+	{ 25, 3 },
+	{ 25, 4 },
+	{ 25, 5 },
+	{ 25, 6 },
+	{ 25, 7 },
+	{ 35, 7 },
+	{ 50, 7 },
+	{ 71, 7 },
+	{ 100, 7 }
+};
+
+const struct nphy_txiqcal_ladder ladder_iq[] = {
+	{ 3, 0 },
+	{ 4, 0 },
+	{ 6, 0 },
+	{ 9, 0 },
+	{ 13, 0 },
+	{ 18, 0 },
+	{ 25, 0 },
+	{ 35, 0 },
+	{ 50, 0 },
+	{ 71, 0 },
+	{ 100, 0 },
+	{ 100, 1 },
+	{ 100, 2 },
+	{ 100, 3 },
+	{ 100, 4 },
+	{ 100, 5 },
+	{ 100, 6 },
+	{ 100, 7 }
+};
+
+const u16 loscale[] = {
+	256, 256, 271, 271,
+	287, 256, 256, 271,
+	271, 287, 287, 304,
+	304, 256, 256, 271,
+	271, 287, 287, 304,
+	304, 322, 322, 341,
+	341, 362, 362, 383,
+	383, 256, 256, 271,
+	271, 287, 287, 304,
+	304, 322, 322, 256,
+	256, 271, 271, 287,
+	287, 304, 304, 322,
+	322, 341, 341, 362,
+	362, 256, 256, 271,
+	271, 287, 287, 304,
+	304, 322, 322, 256,
+	256, 271, 271, 287,
+	287, 304, 304, 322,
+	322, 341, 341, 362,
+	362, 256, 256, 271,
+	271, 287, 287, 304,
+	304, 322, 322, 341,
+	341, 362, 362, 383,
+	383, 406, 406, 430,
+	430, 455, 455, 482,
+	482, 511, 511, 541,
+	541, 573, 573, 607,
+	607, 643, 643, 681,
+	681, 722, 722, 764,
+	764, 810, 810, 858,
+	858, 908, 908, 962,
+	962, 1019, 1019, 256
+};
+
+const u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
+	0x0200, 0x0300, 0x0400, 0x0700,
+	0x0900, 0x0c00, 0x1200, 0x1201,
+	0x1202, 0x1203, 0x1204, 0x1205,
+	0x1206, 0x1207, 0x1907, 0x2307,
+	0x3207, 0x4707
+};
+
+const u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
+	0x0300, 0x0500, 0x0700, 0x0900,
+	0x0d00, 0x1100, 0x1900, 0x1901,
+	0x1902, 0x1903, 0x1904, 0x1905,
+	0x1906, 0x1907, 0x2407, 0x3207,
+	0x4607, 0x6407
+};
+
+const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
+	0x0100, 0x0200, 0x0400, 0x0700,
+	0x0900, 0x0c00, 0x1200, 0x1900,
+	0x2300, 0x3200, 0x4700, 0x4701,
+	0x4702, 0x4703, 0x4704, 0x4705,
+	0x4706, 0x4707
+};
+
+const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
+	0x0200, 0x0300, 0x0600, 0x0900,
+	0x0d00, 0x1100, 0x1900, 0x2400,
+	0x3200, 0x4600, 0x6400, 0x6401,
+	0x6402, 0x6403, 0x6404, 0x6405,
+	0x6406, 0x6407
+};
+
+const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[B43_NTAB_TX_IQLO_CAL_STARTCOEFS_REV3] = { };
+
+const u16 tbl_tx_iqlo_cal_startcoefs[B43_NTAB_TX_IQLO_CAL_STARTCOEFS] = { };
+
+const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
+	0x8423, 0x8323, 0x8073, 0x8256,
+	0x8045, 0x8223, 0x9423, 0x9323,
+	0x9073, 0x9256, 0x9045, 0x9223
+};
+
+const u16 tbl_tx_iqlo_cal_cmds_recal[] = {
+	0x8101, 0x8253, 0x8053, 0x8234,
+	0x8034, 0x9101, 0x9253, 0x9053,
+	0x9234, 0x9034
+};
+
+const u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
+	0x8123, 0x8264, 0x8086, 0x8245,
+	0x8056, 0x9123, 0x9264, 0x9086,
+	0x9245, 0x9056
+};
+
+const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
+	0x8434, 0x8334, 0x8084, 0x8267,
+	0x8056, 0x8234, 0x9434, 0x9334,
+	0x9084, 0x9267, 0x9056, 0x9234
+};
+
+const s16 tbl_tx_filter_coef_rev4[7][15] = {
+	{  -377,   137,  -407,   208, -1527,
+	    956,    93,   186,    93,   230,
+	    -44,   230,    20,  -191,   201 },
+	{   -77,    20,   -98,    49,   -93,
+	     60,    56,   111,    56,    26,
+	     -5,    26,    34,   -32,    34 },
+	{  -360,   164,  -376,   164, -1533,
+	    576,   308,  -314,   308,   121,
+	    -73,   121,    91,   124,    91 },
+	{  -295,   200,  -363,   142, -1391,
+	    826,   151,   301,   151,   151,
+	    301,   151,   602,  -752,   602 },
+	{   -92,    58,   -96,    49,  -104,
+	     44,    17,    35,    17,    12,
+	     25,    12,    13,    27,    13 },
+	{  -375,   136,  -399,   209, -1479,
+	    949,   130,   260,   130,   230,
+	    -44,   230,   201,  -191,   201 },
+	{ 0xed9,  0xc8, 0xe95,  0x8e, 0xa91,
+	  0x33a,  0x97, 0x12d,  0x97,  0x97,
+	  0x12d,  0x97, 0x25a, 0xd10, 0x25a }
+};
+
+/* addr0,  addr1,  bmask,  shift */
+const struct nphy_rf_control_override_rev2 tbl_rf_control_override_rev2[] = {
+	{ 0x78, 0x78, 0x0038,  3 }, /* for field == 0x0002 (fls == 2) */
+	{ 0x7A, 0x7D, 0x0001,  0 }, /* for field == 0x0004 (fls == 3) */
+	{ 0x7A, 0x7D, 0x0002,  1 }, /* for field == 0x0008 (fls == 4) */
+	{ 0x7A, 0x7D, 0x0004,  2 }, /* for field == 0x0010 (fls == 5) */
+	{ 0x7A, 0x7D, 0x0030,  4 }, /* for field == 0x0020 (fls == 6) */
+	{ 0x7A, 0x7D, 0x00C0,  6 }, /* for field == 0x0040 (fls == 7) */
+	{ 0x7A, 0x7D, 0x0100,  8 }, /* for field == 0x0080 (fls == 8) */
+	{ 0x7A, 0x7D, 0x0200,  9 }, /* for field == 0x0100 (fls == 9) */
+	{ 0x78, 0x78, 0x0004,  2 }, /* for field == 0x0200 (fls == 10) */
+	{ 0x7B, 0x7E, 0x01FF,  0 }, /* for field == 0x0400 (fls == 11) */
+	{ 0x7C, 0x7F, 0x01FF,  0 }, /* for field == 0x0800 (fls == 12) */
+	{ 0x78, 0x78, 0x0100,  8 }, /* for field == 0x1000 (fls == 13) */
+	{ 0x78, 0x78, 0x0200,  9 }, /* for field == 0x2000 (fls == 14) */
+	{ 0x78, 0x78, 0xF000, 12 }  /* for field == 0x4000 (fls == 15) */
+};
+
+/* val_mask, val_shift, en_addr0, val_addr0, en_addr1, val_addr1 */
+const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = {
+	{ 0x8000, 15, 0xE5, 0xF9, 0xE6, 0xFB }, /* field == 0x0001 (fls 1) */
+	{ 0x0001,  0, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0002 (fls 2) */
+	{ 0x0002,  1, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0004 (fls 3) */
+	{ 0x0004,  2, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0008 (fls 4) */
+	{ 0x0016,  4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */
+	{ 0x0020,  5, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0020 (fls 6) */
+	{ 0x0040,  6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0040 (fls 7) */
+	{ 0x0080,  6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */
+	{ 0x0100,  7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */
+	{ 0x0007,  0, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0200 (fls 10) */
+	{ 0x0070,  4, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0400 (fls 11) */
+	{ 0xE000, 13, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0800 (fls 12) */
+	{ 0xFFFF,  0, 0xE7, 0x7B, 0xEC, 0x7E }, /* field == 0x1000 (fls 13) */
+	{ 0xFFFF,  0, 0xE7, 0x7C, 0xEC, 0x7F }, /* field == 0x2000 (fls 14) */
+	{ 0x00C0,  6, 0xE7, 0xF9, 0xEC, 0xFB }  /* field == 0x4000 (fls 15) */
+};
+
 static inline void assert_ntab_array_sizes(void)
 {
 #undef check
@@ -2442,6 +2980,72 @@ static inline void assert_ntab_array_siz
 #undef check
 }
 
+u32 b43_ntab_read(struct b43_wldev *dev, u32 offset)
+{
+	u32 type, value;
+
+	type = offset & B43_NTAB_TYPEMASK;
+	offset &= ~B43_NTAB_TYPEMASK;
+	B43_WARN_ON(offset > 0xFFFF);
+
+	switch (type) {
+	case B43_NTAB_8BIT:
+		b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
+		value = b43_phy_read(dev, B43_NPHY_TABLE_DATALO) & 0xFF;
+		break;
+	case B43_NTAB_16BIT:
+		b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
+		value = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
+		break;
+	case B43_NTAB_32BIT:
+		b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
+		value = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI);
+		value <<= 16;
+		value |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
+		break;
+	default:
+		B43_WARN_ON(1);
+		value = 0;
+	}
+
+	return value;
+}
+
+void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset,
+			 unsigned int nr_elements, void *_data)
+{
+	u32 type;
+	u8 *data = _data;
+	unsigned int i;
+
+	type = offset & B43_NTAB_TYPEMASK;
+	offset &= ~B43_NTAB_TYPEMASK;
+	B43_WARN_ON(offset > 0xFFFF);
+
+	b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
+
+	for (i = 0; i < nr_elements; i++) {
+		switch (type) {
+		case B43_NTAB_8BIT:
+			*data = b43_phy_read(dev, B43_NPHY_TABLE_DATALO) & 0xFF;
+			data++;
+			break;
+		case B43_NTAB_16BIT:
+			*((u16 *)data) = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
+			data += 2;
+			break;
+		case B43_NTAB_32BIT:
+			*((u32 *)data) = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI);
+			*((u32 *)data) <<= 16;
+			*((u32 *)data) |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
+			data += 4;
+			break;
+		default:
+			B43_WARN_ON(1);
+		}
+	}
+}
+
 void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value)
 {
 	u32 type;
@@ -2474,3 +3078,91 @@ void b43_ntab_write(struct b43_wldev *de
 	/* Some compiletime assertions... */
 	assert_ntab_array_sizes();
 }
+
+void b43_ntab_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_NTAB_TYPEMASK;
+	offset &= ~B43_NTAB_TYPEMASK;
+	B43_WARN_ON(offset > 0xFFFF);
+
+	b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
+
+	for (i = 0; i < nr_elements; i++) {
+		switch (type) {
+		case B43_NTAB_8BIT:
+			value = *data;
+			data++;
+			B43_WARN_ON(value & ~0xFF);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value);
+			break;
+		case B43_NTAB_16BIT:
+			value = *((u16 *)data);
+			data += 2;
+			B43_WARN_ON(value & ~0xFFFF);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value);
+			break;
+		case B43_NTAB_32BIT:
+			value = *((u32 *)data);
+			data += 4;
+			b43_phy_write(dev, B43_NPHY_TABLE_DATAHI, value >> 16);
+			b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
+					value & 0xFFFF);
+			break;
+		default:
+			B43_WARN_ON(1);
+		}
+	}
+}
+
+#define ntab_upload(dev, offset, data) do { \
+		unsigned int i;						\
+		for (i = 0; i < (offset##_SIZE); i++)			\
+			b43_ntab_write(dev, (offset) + i, (data)[i]);	\
+	} while (0)
+
+void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev)
+{
+	/* Static tables */
+	ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
+	ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
+	ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
+	ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
+	ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
+	ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
+	ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt);
+	ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
+	ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
+	ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
+	ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
+	ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
+	ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
+	ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
+
+	/* Volatile tables */
+	ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
+	ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
+	ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0);
+	ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1);
+	ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0);
+	ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1);
+	ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0);
+	ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1);
+	ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0);
+	ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1);
+	ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0);
+	ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1);
+}
+
+void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev)
+{
+	/* Static tables */
+	/* TODO */
+
+	/* Volatile tables */
+	/* TODO */
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/tables_nphy.h linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/tables_nphy.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/tables_nphy.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43/tables_nphy.h	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,27 @@ struct b43_nphy_channeltab_entry {
 
 struct b43_wldev;
 
+struct nphy_txiqcal_ladder {
+	u8 percent;
+	u8 g_env;
+};
+
+struct nphy_rf_control_override_rev2 {
+	u8 addr0;
+	u8 addr1;
+	u16 bmask;
+	u8 shift;
+};
+
+struct nphy_rf_control_override_rev3 {
+	u16 val_mask;
+	u8 val_shift;
+	u8 en_addr0;
+	u8 val_addr0;
+	u8 en_addr1;
+	u8 val_addr1;
+};
+
 /* Upload the default register value table.
  * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz
  * table is uploaded. If "ignore_uploadflag" is true, we upload any value
@@ -126,34 +147,57 @@ b43_nphy_get_chantabent(struct b43_wldev
 #define B43_NTAB_C1_LOFEEDTH		B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */
 #define B43_NTAB_C1_LOFEEDTH_SIZE	128
 
+#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE	18
+#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE	18
+#define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE	18
+#define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_20_SIZE	18
+#define B43_NTAB_TX_IQLO_CAL_STARTCOEFS_REV3		11
+#define B43_NTAB_TX_IQLO_CAL_STARTCOEFS			9
+#define B43_NTAB_TX_IQLO_CAL_CMDS_RECAL_REV3		12
+#define B43_NTAB_TX_IQLO_CAL_CMDS_RECAL			10
+#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL		10
+#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3		12
+
+u32 b43_ntab_read(struct b43_wldev *dev, u32 offset);
+void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset,
+			 unsigned int nr_elements, void *_data);
 void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value);
+void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
+			  unsigned int nr_elements, const void *_data);
 
-extern const u8 b43_ntab_adjustpower0[];
-extern const u8 b43_ntab_adjustpower1[];
-extern const u16 b43_ntab_bdi[];
-extern const u32 b43_ntab_channelest[];
-extern const u8 b43_ntab_estimatepowerlt0[];
-extern const u8 b43_ntab_estimatepowerlt1[];
-extern const u8 b43_ntab_framelookup[];
-extern const u32 b43_ntab_framestruct[];
-extern const u32 b43_ntab_gainctl0[];
-extern const u32 b43_ntab_gainctl1[];
-extern const u32 b43_ntab_intlevel[];
-extern const u32 b43_ntab_iqlt0[];
-extern const u32 b43_ntab_iqlt1[];
-extern const u16 b43_ntab_loftlt0[];
-extern const u16 b43_ntab_loftlt1[];
-extern const u8 b43_ntab_mcs[];
-extern const u32 b43_ntab_noisevar10[];
-extern const u32 b43_ntab_noisevar11[];
-extern const u16 b43_ntab_pilot[];
-extern const u32 b43_ntab_pilotlt[];
-extern const u32 b43_ntab_tdi20a0[];
-extern const u32 b43_ntab_tdi20a1[];
-extern const u32 b43_ntab_tdi40a0[];
-extern const u32 b43_ntab_tdi40a1[];
-extern const u32 b43_ntab_tdtrn[];
-extern const u32 b43_ntab_tmap[];
+void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev);
+void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev);
+
+extern const u32 b43_ntab_tx_gain_rev0_1_2[];
+extern const u32 b43_ntab_tx_gain_rev3plus_2ghz[];
+extern const u32 b43_ntab_tx_gain_rev3_5ghz[];
+extern const u32 b43_ntab_tx_gain_rev4_5ghz[];
+extern const u32 b43_ntab_tx_gain_rev5plus_5ghz[];
+
+extern const u32 txpwrctrl_tx_gain_ipa[];
+extern const u32 txpwrctrl_tx_gain_ipa_rev5[];
+extern const u32 txpwrctrl_tx_gain_ipa_rev6[];
+extern const u32 txpwrctrl_tx_gain_ipa_5g[];
+extern const u16 tbl_iqcal_gainparams[2][9][8];
+extern const struct nphy_txiqcal_ladder ladder_lo[];
+extern const struct nphy_txiqcal_ladder ladder_iq[];
+extern const u16 loscale[];
+
+extern const u16 tbl_tx_iqlo_cal_loft_ladder_40[];
+extern const u16 tbl_tx_iqlo_cal_loft_ladder_20[];
+extern const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[];
+extern const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[];
+extern const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[];
+extern const u16 tbl_tx_iqlo_cal_startcoefs[];
+extern const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[];
+extern const u16 tbl_tx_iqlo_cal_cmds_recal[];
+extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[];
+extern const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[];
+extern const s16 tbl_tx_filter_coef_rev4[7][15];
 
+extern const struct nphy_rf_control_override_rev2
+	tbl_rf_control_override_rev2[];
+extern const struct nphy_rf_control_override_rev3
+	tbl_rf_control_override_rev3[];
 
 #endif /* B43_TABLES_NPHY_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/dma.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43legacy/dma.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43legacy/dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/dst.h>
 
 /* 32bit DMA ops. */
@@ -1411,7 +1412,6 @@ int b43legacy_dma_tx(struct b43legacy_wl
 		b43legacyerr(dev->wl, "DMA tx mapping failure\n");
 		goto out_unlock;
 	}
-	ring->nr_tx_packets++;
 	if ((free_slots(ring) < SLOTS_PER_PACKET) ||
 	    should_inject_overflow(ring)) {
 		/* This TX ring is full. */
@@ -1527,25 +1527,6 @@ void b43legacy_dma_handle_txstatus(struc
 	spin_unlock(&ring->lock);
 }
 
-void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
-			      struct ieee80211_tx_queue_stats *stats)
-{
-	const int nr_queues = dev->wl->hw->queues;
-	struct b43legacy_dmaring *ring;
-	unsigned long flags;
-	int i;
-
-	for (i = 0; i < nr_queues; i++) {
-		ring = priority_to_txring(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].count = ring->nr_tx_packets;
-		spin_unlock_irqrestore(&ring->lock, flags);
-	}
-}
-
 static void dma_rx(struct b43legacy_dmaring *ring,
 		   int *slot)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/dma.h linux-libre-2.6.34-gnu1/drivers/net/wireless/b43legacy/dma.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/dma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43legacy/dma.h	2010-05-16 17:17:36.000000000 -0400
@@ -243,8 +243,6 @@ struct b43legacy_dmaring {
 	int used_slots;
 	/* Currently used slot in the ring. */
 	int current_slot;
-	/* Total number of packets sent. Statistics only. */
-	unsigned int nr_tx_packets;
 	/* Frameoffset in octets. */
 	u32 frameoffset;
 	/* Descriptor buffer size. */
@@ -292,9 +290,6 @@ void b43legacy_dma_free(struct b43legacy
 void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev);
 void b43legacy_dma_tx_resume(struct b43legacy_wldev *dev);
 
-void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
-				struct ieee80211_tx_queue_stats *stats);
-
 int b43legacy_dma_tx(struct b43legacy_wldev *dev,
 		     struct sk_buff *skb);
 void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
@@ -315,11 +310,6 @@ void b43legacy_dma_free(struct b43legacy
 {
 }
 static inline
-void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
-				struct ieee80211_tx_queue_stats *stats)
-{
-}
-static inline
 int b43legacy_dma_tx(struct b43legacy_wldev *dev,
 		     struct sk_buff *skb)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/leds.h linux-libre-2.6.34-gnu1/drivers/net/wireless/b43legacy/leds.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/leds.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43legacy/leds.h	2010-05-16 17:17:36.000000000 -0400
@@ -45,7 +45,7 @@ enum b43legacy_led_behaviour {
 void b43legacy_leds_init(struct b43legacy_wldev *dev);
 void b43legacy_leds_exit(struct b43legacy_wldev *dev);
 
-#else /* CONFIG_B43EGACY_LEDS */
+#else /* CONFIG_B43LEGACY_LEDS */
 /* LED support disabled */
 
 struct b43legacy_led {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/main.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43legacy/main.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/main.c	2013-05-03 12:09:21.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43legacy/main.c	2013-05-03 09:48:52.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/sched.h>
 #include <linux/skbuff.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <net/dst.h>
 #include <asm/unaligned.h>
 
@@ -2442,29 +2443,6 @@ static int b43legacy_op_conf_tx(struct i
 	return 0;
 }
 
-static int b43legacy_op_get_tx_stats(struct ieee80211_hw *hw,
-				     struct ieee80211_tx_queue_stats *stats)
-{
-	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
-	struct b43legacy_wldev *dev = wl->current_dev;
-	unsigned long flags;
-	int err = -ENODEV;
-
-	if (!dev)
-		goto out;
-	spin_lock_irqsave(&wl->irq_lock, flags);
-	if (likely(b43legacy_status(dev) >= B43legacy_STAT_STARTED)) {
-		if (b43legacy_using_pio(dev))
-			b43legacy_pio_get_tx_stats(dev, stats);
-		else
-			b43legacy_dma_get_tx_stats(dev, stats);
-		err = 0;
-	}
-	spin_unlock_irqrestore(&wl->irq_lock, flags);
-out:
-	return err;
-}
-
 static int b43legacy_op_get_stats(struct ieee80211_hw *hw,
 				  struct ieee80211_low_level_stats *stats)
 {
@@ -2919,6 +2897,7 @@ static int b43legacy_wireless_core_start
 		goto out;
 	}
 	/* We are ready to run. */
+	ieee80211_wake_queues(dev->wl->hw);
 	b43legacy_set_status(dev, B43legacy_STAT_STARTED);
 
 	/* Start data flow (TX/RX) */
@@ -3339,6 +3318,7 @@ static int b43legacy_wireless_core_init(
 	b43legacy_security_init(dev);
 	b43legacy_rng_init(wl);
 
+	ieee80211_wake_queues(dev->wl->hw);
 	b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED);
 
 	b43legacy_leds_init(dev);
@@ -3359,7 +3339,7 @@ err_kfree_lo_control:
 }
 
 static int b43legacy_op_add_interface(struct ieee80211_hw *hw,
-				      struct ieee80211_if_init_conf *conf)
+				      struct ieee80211_vif *vif)
 {
 	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
 	struct b43legacy_wldev *dev;
@@ -3368,23 +3348,23 @@ static int b43legacy_op_add_interface(st
 
 	/* TODO: allow WDS/AP devices to coexist */
 
-	if (conf->type != NL80211_IFTYPE_AP &&
-	    conf->type != NL80211_IFTYPE_STATION &&
-	    conf->type != NL80211_IFTYPE_WDS &&
-	    conf->type != NL80211_IFTYPE_ADHOC)
+	if (vif->type != NL80211_IFTYPE_AP &&
+	    vif->type != NL80211_IFTYPE_STATION &&
+	    vif->type != NL80211_IFTYPE_WDS &&
+	    vif->type != NL80211_IFTYPE_ADHOC)
 		return -EOPNOTSUPP;
 
 	mutex_lock(&wl->mutex);
 	if (wl->operating)
 		goto out_mutex_unlock;
 
-	b43legacydbg(wl, "Adding Interface type %d\n", conf->type);
+	b43legacydbg(wl, "Adding Interface type %d\n", vif->type);
 
 	dev = wl->current_dev;
 	wl->operating = 1;
-	wl->vif = conf->vif;
-	wl->if_type = conf->type;
-	memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
+	wl->vif = vif;
+	wl->if_type = vif->type;
+	memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
 
 	spin_lock_irqsave(&wl->irq_lock, flags);
 	b43legacy_adjust_opmode(dev);
@@ -3401,18 +3381,18 @@ static int b43legacy_op_add_interface(st
 }
 
 static void b43legacy_op_remove_interface(struct ieee80211_hw *hw,
-					  struct ieee80211_if_init_conf *conf)
+					  struct ieee80211_vif *vif)
 {
 	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
 	struct b43legacy_wldev *dev = wl->current_dev;
 	unsigned long flags;
 
-	b43legacydbg(wl, "Removing Interface type %d\n", conf->type);
+	b43legacydbg(wl, "Removing Interface type %d\n", vif->type);
 
 	mutex_lock(&wl->mutex);
 
 	B43legacy_WARN_ON(!wl->operating);
-	B43legacy_WARN_ON(wl->vif != conf->vif);
+	B43legacy_WARN_ON(wl->vif != vif);
 	wl->vif = NULL;
 
 	wl->operating = 0;
@@ -3507,7 +3487,6 @@ static const struct ieee80211_ops b43leg
 	.bss_info_changed	= b43legacy_op_bss_info_changed,
 	.configure_filter	= b43legacy_op_configure_filter,
 	.get_stats		= b43legacy_op_get_stats,
-	.get_tx_stats		= b43legacy_op_get_tx_stats,
 	.start			= b43legacy_op_start,
 	.stop			= b43legacy_op_stop,
 	.set_tim		= b43legacy_op_beacon_set_tim,
@@ -3958,7 +3937,7 @@ static struct ssb_driver b43legacy_ssb_d
 
 static void b43legacy_print_driverinfo(void)
 {
-	const char *feat_pci = "", *feat_leds = "", *feat_rfkill = "",
+	const char *feat_pci = "", *feat_leds = "",
 		   *feat_pio = "", *feat_dma = "";
 
 #ifdef CONFIG_B43LEGACY_PCI_AUTOSELECT
@@ -3967,9 +3946,6 @@ static void b43legacy_print_driverinfo(v
 #ifdef CONFIG_B43LEGACY_LEDS
 	feat_leds = "L";
 #endif
-#ifdef CONFIG_B43LEGACY_RFKILL
-	feat_rfkill = "R";
-#endif
 #ifdef CONFIG_B43LEGACY_PIO
 	feat_pio = "I";
 #endif
@@ -3977,9 +3953,9 @@ static void b43legacy_print_driverinfo(v
 	feat_dma = "D";
 #endif
 	printk(KERN_INFO "Broadcom 43xx-legacy driver loaded "
-	       "[ Features: %s%s%s%s%s, Firmware-ID: "
+	       "[ Features: %s%s%s%s, Firmware-ID: "
 	       B43legacy_SUPPORTED_FIRMWARE_ID " ]\n",
-	       feat_pci, feat_leds, feat_rfkill, feat_pio, feat_dma);
+	       feat_pci, feat_leds, feat_pio, feat_dma);
 }
 
 static int __init b43legacy_init(void)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/phy.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43legacy/phy.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/phy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43legacy/phy.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include "b43legacy.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/pio.c linux-libre-2.6.34-gnu1/drivers/net/wireless/b43legacy/pio.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/pio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43legacy/pio.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include "xmit.h"
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 
 static void tx_start(struct b43legacy_pioqueue *queue)
@@ -477,7 +478,6 @@ int b43legacy_pio_tx(struct b43legacy_wl
 
 	list_move_tail(&packet->list, &queue->txqueue);
 	queue->nr_txfree--;
-	queue->nr_tx_packets++;
 	B43legacy_WARN_ON(queue->nr_txfree >= B43legacy_PIO_MAXTXPACKETS);
 
 	tasklet_schedule(&queue->txtask);
@@ -546,18 +546,6 @@ void b43legacy_pio_handle_txstatus(struc
 		tasklet_schedule(&queue->txtask);
 }
 
-void b43legacy_pio_get_tx_stats(struct b43legacy_wldev *dev,
-				struct ieee80211_tx_queue_stats *stats)
-{
-	struct b43legacy_pio *pio = &dev->pio;
-	struct b43legacy_pioqueue *queue;
-
-	queue = pio->queue1;
-	stats[0].len = B43legacy_PIO_MAXTXPACKETS - queue->nr_txfree;
-	stats[0].limit = B43legacy_PIO_MAXTXPACKETS;
-	stats[0].count = queue->nr_tx_packets;
-}
-
 static void pio_rx_error(struct b43legacy_pioqueue *queue,
 			 int clear_buffers,
 			 const char *error)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/pio.h linux-libre-2.6.34-gnu1/drivers/net/wireless/b43legacy/pio.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/pio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/b43legacy/pio.h	2010-05-16 17:17:36.000000000 -0400
@@ -74,10 +74,6 @@ struct b43legacy_pioqueue {
 	 * posted to the device. We are waiting for the txstatus.
 	 */
 	struct list_head txrunning;
-	/* Total number or packets sent.
-	 * (This counter can obviously wrap).
-	 */
-	unsigned int nr_tx_packets;
 	struct tasklet_struct txtask;
 	struct b43legacy_pio_txpacket
 			 tx_packets_cache[B43legacy_PIO_MAXTXPACKETS];
@@ -106,8 +102,6 @@ int b43legacy_pio_tx(struct b43legacy_wl
 		   struct sk_buff *skb);
 void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
 				 const struct b43legacy_txstatus *status);
-void b43legacy_pio_get_tx_stats(struct b43legacy_wldev *dev,
-			      struct ieee80211_tx_queue_stats *stats);
 void b43legacy_pio_rx(struct b43legacy_pioqueue *queue);
 
 /* Suspend TX queue in hardware. */
@@ -140,11 +134,6 @@ void b43legacy_pio_handle_txstatus(struc
 {
 }
 static inline
-void b43legacy_pio_get_tx_stats(struct b43legacy_wldev *dev,
-			      struct ieee80211_tx_queue_stats *stats)
-{
-}
-static inline
 void b43legacy_pio_rx(struct b43legacy_pioqueue *queue)
 {
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_80211_rx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_80211_rx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_80211_rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_80211_rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,5 @@
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <net/lib80211.h>
 #include <linux/if_arp.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_80211_tx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_80211_tx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_80211_tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_80211_tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,3 +1,5 @@
+#include <linux/slab.h>
+
 #include "hostap_80211.h"
 #include "hostap_common.h"
 #include "hostap_wlan.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_ap.c linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_ap.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_ap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_ap.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/random.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 
 #include "hostap_wlan.h"
 #include "hostap.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_cs.c linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_cs.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/if.h>
+#include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/timer.h>
 #include <linux/skbuff.h>
@@ -794,13 +795,6 @@ static struct pcmcia_device_id hostap_cs
 	PCMCIA_MFC_DEVICE_PROD_ID12(0, "SanDisk", "ConnectPlus",
 				    0x7a954bd9, 0x74be00c6),
 	PCMCIA_DEVICE_PROD_ID123(
-		"Intersil", "PRISM 2_5 PCMCIA ADAPTER",	"ISL37300P",
-		0x4b801a17, 0x6345a0bf, 0xc9049a39),
-	/* D-Link DWL-650 Rev. P1; manfid 0x000b, 0x7110 */
-	PCMCIA_DEVICE_PROD_ID123(
-		"D-Link", "DWL-650 Wireless PC Card RevP", "ISL37101P-10",
-		0x1a424a1c, 0x6ea57632, 0xdd97a26b),
-	PCMCIA_DEVICE_PROD_ID123(
 		"Addtron", "AWP-100 Wireless PCMCIA", "Version 01.02",
 		0xe6ec52ce, 0x08649af2, 0x4b74baa0),
 	PCMCIA_DEVICE_PROD_ID123(
@@ -834,14 +828,12 @@ static struct pcmcia_device_id hostap_cs
 		"Ver. 1.00",
 		0x5cd01705, 0x4271660f, 0x9d08ee12),
 	PCMCIA_DEVICE_PROD_ID123(
-		"corega", "WL PCCL-11", "ISL37300P",
-		0xa21501a, 0x59868926, 0xc9049a39),
-	PCMCIA_DEVICE_PROD_ID123(
-		"The Linksys Group, Inc.", "Wireless Network CF Card", "ISL37300P",
-		0xa5f472c2, 0x9c05598d, 0xc9049a39),
-	PCMCIA_DEVICE_PROD_ID123(
 		"Wireless LAN" , "11Mbps PC Card", "Version 01.02",
 		0x4b8870ff, 0x70e946d1, 0x4b74baa0),
+	PCMCIA_DEVICE_PROD_ID3("HFA3863", 0x355cb092),
+	PCMCIA_DEVICE_PROD_ID3("ISL37100P", 0x630d52b2),
+	PCMCIA_DEVICE_PROD_ID3("ISL37101P-10", 0xdd97a26b),
+	PCMCIA_DEVICE_PROD_ID3("ISL37300P", 0xc9049a39),
 	PCMCIA_DEVICE_NULL
 };
 MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_hw.c linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_hw.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_hw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_hw.c	2010-05-16 17:17:36.000000000 -0400
@@ -2618,6 +2618,15 @@ static irqreturn_t prism2_interrupt(int
 	int events = 0;
 	u16 ev;
 
+	/* Detect early interrupt before driver is fully configued */
+	if (!dev->base_addr) {
+		if (net_ratelimit()) {
+			printk(KERN_DEBUG "%s: Interrupt, but dev not configured\n",
+			       dev->name);
+		}
+		return IRQ_HANDLED;
+	}
+
 	iface = netdev_priv(dev);
 	local = iface->local;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_info.c linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_info.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_info.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_info.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
 
 #include <linux/if_arp.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "hostap_wlan.h"
 #include "hostap.h"
 #include "hostap_ap.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_ioctl.c linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_ioctl.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,6 @@
 /* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/ethtool.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_pci.c linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_pci.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/if.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
@@ -39,7 +40,7 @@ struct hostap_pci_priv {
 /* FIX: do we need mb/wmb/rmb with memory operations? */
 
 
-static struct pci_device_id prism2_pci_id_table[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(prism2_pci_id_table) = {
 	/* Intersil Prism3 ISL3872 11Mb/s WLAN Controller */
 	{ 0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID },
 	/* Intersil Prism2.5 ISL3874 11Mb/s WLAN Controller */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_plx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_plx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_plx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/hostap/hostap_plx.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/if.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
@@ -60,7 +61,7 @@ struct hostap_plx_priv {
 
 #define PLXDEV(vendor,dev,str) { vendor, dev, PCI_ANY_ID, PCI_ANY_ID }
 
-static struct pci_device_id prism2_plx_id_table[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(prism2_plx_id_table) = {
 	PLXDEV(0x10b7, 0x7770, "3Com AirConnect PCI 777A"),
 	PLXDEV(0x111a, 0x1023, "Siemens SpeedStream SS1023"),
 	PLXDEV(0x126c, 0x8030, "Nortel emobility"),
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/ipw2100.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ipw2x00/ipw2100.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/ipw2100.c	2013-05-03 12:09:38.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ipw2x00/ipw2100.c	2013-05-03 09:49:09.000000000 -0400
@@ -6585,7 +6585,7 @@ static void ipw2100_shutdown(struct pci_
 
 #define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x }
 
-static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(ipw2100_pci_id_table) = {
 	IPW2100_DEV_ID(0x2520),	/* IN 2100A mPCI 3A */
 	IPW2100_DEV_ID(0x2521),	/* IN 2100A mPCI 3B */
 	IPW2100_DEV_ID(0x2524),	/* IN 2100A mPCI 3B */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/ipw2200.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ipw2x00/ipw2200.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/ipw2200.c	2013-05-03 12:09:44.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ipw2x00/ipw2200.c	2013-05-03 09:49:15.000000000 -0400
@@ -31,6 +31,7 @@
 ******************************************************************************/
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "ipw2200.h"
 
 
@@ -3177,14 +3178,27 @@ static int ipw_load_firmware(struct ipw_
 	int total_nr = 0;
 	int i;
 	struct pci_pool *pool;
-	u32 *virts[CB_NUMBER_OF_ELEMENTS_SMALL];
-	dma_addr_t phys[CB_NUMBER_OF_ELEMENTS_SMALL];
+	void **virts;
+	dma_addr_t *phys;
 
 	IPW_DEBUG_TRACE("<< : \n");
 
+	virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL,
+			GFP_KERNEL);
+	if (!virts)
+		return -ENOMEM;
+
+	phys = kmalloc(sizeof(dma_addr_t) * CB_NUMBER_OF_ELEMENTS_SMALL,
+			GFP_KERNEL);
+	if (!phys) {
+		kfree(virts);
+		return -ENOMEM;
+	}
 	pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0);
 	if (!pool) {
 		IPW_ERROR("pci_pool_create failed\n");
+		kfree(phys);
+		kfree(virts);
 		return -ENOMEM;
 	}
 
@@ -3254,6 +3268,8 @@ static int ipw_load_firmware(struct ipw_
 		pci_pool_free(pool, virts[i], phys[i]);
 
 	pci_pool_destroy(pool);
+	kfree(phys);
+	kfree(virts);
 
 	return ret;
 }
@@ -11524,7 +11540,7 @@ out:
 }
 
 /* PCI driver stuff */
-static struct pci_device_id card_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(card_ids) = {
 	{PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2701, 0, 0, 0},
 	{PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2702, 0, 0, 0},
 	{PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2711, 0, 0, 0},
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/libipw_geo.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ipw2x00/libipw_geo.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/libipw_geo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ipw2x00/libipw_geo.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,6 @@
 #include <linux/netdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
 #include <linux/wireless.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/libipw.h linux-libre-2.6.34-gnu1/drivers/net/wireless/ipw2x00/libipw.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/libipw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ipw2x00/libipw.h	2010-05-16 17:17:36.000000000 -0400
@@ -797,7 +797,7 @@ struct libipw_device {
 	/* Probe / Beacon management */
 	struct list_head network_free_list;
 	struct list_head network_list;
-	struct libipw_network *networks;
+	struct libipw_network *networks[MAX_NETWORK_COUNT];
 	int scans;
 	int scan_age;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/libipw_module.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ipw2x00/libipw_module.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/libipw_module.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ipw2x00/libipw_module.c	2010-05-16 17:17:36.000000000 -0400
@@ -67,16 +67,17 @@ void *libipw_wiphy_privid = &libipw_wiph
 
 static int libipw_networks_allocate(struct libipw_device *ieee)
 {
-	if (ieee->networks)
-		return 0;
+	int i, j;
 
-	ieee->networks =
-	    kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network),
-		    GFP_KERNEL);
-	if (!ieee->networks) {
-		printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
-		       ieee->dev->name);
-		return -ENOMEM;
+	for (i = 0; i < MAX_NETWORK_COUNT; i++) {
+		ieee->networks[i] = kzalloc(sizeof(struct libipw_network),
+					    GFP_KERNEL);
+		if (!ieee->networks[i]) {
+			LIBIPW_ERROR("Out of memory allocating beacons\n");
+			for (j = 0; j < i; j++)
+				kfree(ieee->networks[j]);
+			return -ENOMEM;
+		}
 	}
 
 	return 0;
@@ -97,15 +98,11 @@ static inline void libipw_networks_free(
 {
 	int i;
 
-	if (!ieee->networks)
-		return;
-
-	for (i = 0; i < MAX_NETWORK_COUNT; i++)
-		if (ieee->networks[i].ibss_dfs)
-			kfree(ieee->networks[i].ibss_dfs);
-
-	kfree(ieee->networks);
-	ieee->networks = NULL;
+	for (i = 0; i < MAX_NETWORK_COUNT; i++) {
+		if (ieee->networks[i]->ibss_dfs)
+			kfree(ieee->networks[i]->ibss_dfs);
+		kfree(ieee->networks[i]);
+	}
 }
 
 void libipw_networks_age(struct libipw_device *ieee,
@@ -130,7 +127,7 @@ static void libipw_networks_initialize(s
 	INIT_LIST_HEAD(&ieee->network_free_list);
 	INIT_LIST_HEAD(&ieee->network_list);
 	for (i = 0; i < MAX_NETWORK_COUNT; i++)
-		list_add_tail(&ieee->networks[i].list,
+		list_add_tail(&ieee->networks[i]->list,
 			      &ieee->network_free_list);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/libipw_rx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ipw2x00/libipw_rx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/libipw_rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ipw2x00/libipw_rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/if_arp.h>
 #include <linux/in6.h>
+#include <linux/gfp.h>
 #include <linux/in.h>
 #include <linux/ip.h>
 #include <linux/kernel.h>
@@ -24,7 +25,6 @@
 #include <linux/netdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
 #include <linux/wireless.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/libipw_wx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ipw2x00/libipw_wx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/libipw_wx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ipw2x00/libipw_wx.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 ******************************************************************************/
 
 #include <linux/kmod.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/jiffies.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-1000.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-1000.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-1000.c	2013-05-03 12:10:02.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-1000.c	2013-05-03 09:49:33.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2008-2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -89,8 +89,78 @@ static void iwl1000_nic_config(struct iw
 				~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
 }
 
+static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
+	.min_nrg_cck = 95,
+	.max_nrg_cck = 0, /* not used, set to 0 */
+	.auto_corr_min_ofdm = 90,
+	.auto_corr_min_ofdm_mrc = 170,
+	.auto_corr_min_ofdm_x1 = 120,
+	.auto_corr_min_ofdm_mrc_x1 = 240,
+
+	.auto_corr_max_ofdm = 120,
+	.auto_corr_max_ofdm_mrc = 210,
+	.auto_corr_max_ofdm_x1 = 155,
+	.auto_corr_max_ofdm_mrc_x1 = 290,
+
+	.auto_corr_min_cck = 125,
+	.auto_corr_max_cck = 200,
+	.auto_corr_min_cck_mrc = 170,
+	.auto_corr_max_cck_mrc = 400,
+	.nrg_th_cck = 95,
+	.nrg_th_ofdm = 95,
+
+	.barker_corr_th_min = 190,
+	.barker_corr_th_min_mrc = 390,
+	.nrg_th_cca = 62,
+};
+
+static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
+{
+	if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
+	    priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES)
+		priv->cfg->num_of_queues =
+			priv->cfg->mod_params->num_of_queues;
+
+	priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
+	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
+	priv->hw_params.scd_bc_tbls_size =
+			priv->cfg->num_of_queues *
+			sizeof(struct iwl5000_scd_bc_tbl);
+	priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
+	priv->hw_params.max_stations = IWL5000_STATION_COUNT;
+	priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
+
+	priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
+	priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
+
+	priv->hw_params.max_bsm_size = 0;
+	priv->hw_params.ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
+					BIT(IEEE80211_BAND_5GHZ);
+	priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
+
+	priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
+	priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
+	priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
+	priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
+
+	if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
+		priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+
+	/* Set initial sensitivity parameters */
+	/* Set initial calibration set */
+	priv->hw_params.sens = &iwl1000_sensitivity;
+	priv->hw_params.calib_init_cfg =
+			BIT(IWL_CALIB_XTAL)		|
+			BIT(IWL_CALIB_LO)		|
+			BIT(IWL_CALIB_TX_IQ) 		|
+			BIT(IWL_CALIB_TX_IQ_PERD)	|
+			BIT(IWL_CALIB_BASE_BAND);
+
+	return 0;
+}
+
 static struct iwl_lib_ops iwl1000_lib = {
-	.set_hw_params = iwl5000_hw_set_hw_params,
+	.set_hw_params = iwl1000_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,
@@ -105,6 +175,8 @@ static struct iwl_lib_ops iwl1000_lib =
 	.load_ucode = iwl5000_load_ucode,
 	.dump_nic_event_log = iwl_dump_nic_event_log,
 	.dump_nic_error_log = iwl_dump_nic_error_log,
+	.dump_csr = iwl_dump_csr,
+	.dump_fh = iwl_dump_fh,
 	.init_alive_start = iwl5000_init_alive_start,
 	.alive_notify = iwl5000_alive_notify,
 	.send_tx_power = iwl5000_send_tx_power,
@@ -138,9 +210,10 @@ static struct iwl_lib_ops iwl1000_lib =
 		.temperature = iwl5000_temperature,
 		.set_ct_kill = iwl1000_set_ct_threshold,
 	 },
+	.add_bcast_station = iwl_add_bcast_station,
 };
 
-static struct iwl_ops iwl1000_ops = {
+static const struct iwl_ops iwl1000_ops = {
 	.ucode = &iwl5000_ucode,
 	.lib = &iwl1000_lib,
 	.hcmd = &iwl5000_hcmd,
@@ -173,7 +246,8 @@ struct iwl_cfg iwl1000_bgn_cfg = {
 	.use_rts_for_ht = true, /* use rts/cts protection */
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 	.support_ct_kill_exit = true,
-	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
 };
 
 struct iwl_cfg iwl1000_bg_cfg = {
@@ -200,6 +274,8 @@ struct iwl_cfg iwl1000_bg_cfg = {
 	.led_compensation = 51,
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 	.support_ct_kill_exit = true,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
 };
 
 /*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c	2013-05-03 12:09:48.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c	2013-05-03 09:49:19.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 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.
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
@@ -53,9 +54,10 @@
 #include "iwl-commands.h"
 #include "iwl-sta.h"
 #include "iwl-3945.h"
-#include "iwl-helpers.h"
 #include "iwl-core.h"
+#include "iwl-helpers.h"
 #include "iwl-dev.h"
+#include "iwl-spectrum.h"
 
 /*
  * module name, copyright, version, etc.
@@ -70,14 +72,13 @@
 #define VD
 #endif
 
-#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
-#define VS "s"
-#else
-#define VS
-#endif
-
-#define DRV_VERSION  IWLWIFI_VERSION VD VS
-#define DRV_COPYRIGHT	"Copyright(c) 2003-2009 Intel Corporation"
+/*
+ * add "s" to indicate spectrum measurement included.
+ * we add it here to be consistent with previous releases in which
+ * this was configurable.
+ */
+#define DRV_VERSION  IWLWIFI_VERSION VD "s"
+#define DRV_COPYRIGHT	"Copyright(c) 2003-2010 Intel Corporation"
 #define DRV_AUTHOR     "<ilw@linux.intel.com>"
 
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -352,10 +353,10 @@ static int iwl3945_send_beacon_cmd(struc
 static void iwl3945_unset_hw_params(struct iwl_priv *priv)
 {
 	if (priv->shared_virt)
-		pci_free_consistent(priv->pci_dev,
-				    sizeof(struct iwl3945_shared),
-				    priv->shared_virt,
-				    priv->shared_phys);
+		dma_free_coherent(&priv->pci_dev->dev,
+				  sizeof(struct iwl3945_shared),
+				  priv->shared_virt,
+				  priv->shared_phys);
 }
 
 static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
@@ -478,7 +479,6 @@ static int iwl3945_tx_skb(struct iwl_pri
 	u8 wait_write_ptr = 0;
 	u8 *qc = NULL;
 	unsigned long flags;
-	int rc;
 
 	spin_lock_irqsave(&priv->lock, flags);
 	if (iwl_is_rfkill(priv)) {
@@ -663,12 +663,9 @@ static int iwl3945_tx_skb(struct iwl_pri
 
 	/* 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 = iwl_txq_update_write_ptr(priv, txq);
+	iwl_txq_update_write_ptr(priv, txq);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	if (rc)
-		return rc;
-
 	if ((iwl_queue_space(q) < q->high_mark)
 	    && priv->mac80211_registered) {
 		if (wait_write_ptr) {
@@ -689,10 +686,6 @@ drop:
 	return -1;
 }
 
-#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
-
-#include "iwl-spectrum.h"
-
 #define BEACON_TIME_MASK_LOW	0x00FFFFFF
 #define BEACON_TIME_MASK_HIGH	0xFF000000
 #define TIME_UNIT		1024
@@ -819,7 +812,6 @@ static int iwl3945_get_measurement(struc
 
 	return rc;
 }
-#endif
 
 static void iwl3945_rx_reply_alive(struct iwl_priv *priv,
 			       struct iwl_rx_mem_buffer *rxb)
@@ -962,6 +954,8 @@ static void iwl3945_setup_rx_handlers(st
 	priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta;
 	priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
 	priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
+	priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
+			iwl_rx_spectrum_measure_notif;
 	priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
 	priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
 	    iwl_rx_pm_debug_statistics_notif;
@@ -975,7 +969,6 @@ 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;
 
-	iwl_setup_spectrum_handlers(priv);
 	iwl_setup_rx_scan_handlers(priv);
 	priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
 
@@ -1067,13 +1060,13 @@ 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 iwl_priv *priv)
+static void iwl3945_rx_queue_restock(struct iwl_priv *priv)
 {
 	struct iwl_rx_queue *rxq = &priv->rxq;
 	struct list_head *element;
 	struct iwl_rx_mem_buffer *rxb;
 	unsigned long flags;
-	int write, rc;
+	int write;
 
 	spin_lock_irqsave(&rxq->lock, flags);
 	write = rxq->write & ~0x7;
@@ -1103,12 +1096,8 @@ static int iwl3945_rx_queue_restock(stru
 		spin_lock_irqsave(&rxq->lock, flags);
 		rxq->need_update = 1;
 		spin_unlock_irqrestore(&rxq->lock, flags);
-		rc = iwl_rx_queue_update_write_ptr(priv, rxq);
-		if (rc)
-			return rc;
+		iwl_rx_queue_update_write_ptr(priv, rxq);
 	}
-
-	return 0;
 }
 
 /**
@@ -1253,10 +1242,10 @@ static void iwl3945_rx_queue_free(struct
 		}
 	}
 
-	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);
+	dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,
+			  rxq->dma_addr);
+	dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status),
+			  rxq->rb_stts, rxq->rb_stts_dma);
 	rxq->bd = NULL;
 	rxq->rb_stts  = NULL;
 }
@@ -1518,8 +1507,9 @@ void iwl3945_dump_nic_error_log(struct i
  * iwl3945_print_event_log - Dump error event log to syslog
  *
  */
-static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
-				u32 num_events, u32 mode)
+static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
+				  u32 num_events, u32 mode,
+				  int pos, char **buf, size_t bufsz)
 {
 	u32 i;
 	u32 base;       /* SRAM byte address of event log header */
@@ -1529,7 +1519,7 @@ static void iwl3945_print_event_log(stru
 	unsigned long reg_flags;
 
 	if (num_events == 0)
-		return;
+		return pos;
 
 	base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
 
@@ -1555,26 +1545,43 @@ static void iwl3945_print_event_log(stru
 		time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
 		if (mode == 0) {
 			/* data, ev */
-			IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
-			trace_iwlwifi_dev_ucode_event(priv, 0, time, ev);
+			if (bufsz) {
+				pos += scnprintf(*buf + pos, bufsz - pos,
+						"0x%08x:%04u\n",
+						time, ev);
+			} else {
+				IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
+				trace_iwlwifi_dev_ucode_event(priv, 0,
+							      time, ev);
+			}
 		} else {
 			data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
-			IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev);
-			trace_iwlwifi_dev_ucode_event(priv, time, data, ev);
+			if (bufsz) {
+				pos += scnprintf(*buf + pos, bufsz - pos,
+						"%010u:0x%08x:%04u\n",
+						 time, data, ev);
+			} else {
+				IWL_ERR(priv, "%010u\t0x%08x\t%04u\n",
+					time, data, ev);
+				trace_iwlwifi_dev_ucode_event(priv, time,
+							      data, ev);
+			}
 		}
 	}
 
 	/* Allow device to power down */
 	iwl_release_nic_access(priv);
 	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
+	return pos;
 }
 
 /**
  * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog
  */
-static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
+static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
 				      u32 num_wraps, u32 next_entry,
-				      u32 size, u32 mode)
+				      u32 size, u32 mode,
+				      int pos, char **buf, size_t bufsz)
 {
 	/*
 	 * display the newest DEFAULT_LOG_ENTRIES entries
@@ -1582,21 +1589,28 @@ static void iwl3945_print_last_event_log
 	 */
 	if (num_wraps) {
 		if (next_entry < size) {
-			iwl3945_print_event_log(priv,
-					capacity - (size - next_entry),
-					size - next_entry, mode);
-			iwl3945_print_event_log(priv, 0,
-				    next_entry, mode);
+			pos = iwl3945_print_event_log(priv,
+					     capacity - (size - next_entry),
+					     size - next_entry, mode,
+					     pos, buf, bufsz);
+			pos = iwl3945_print_event_log(priv, 0,
+						      next_entry, mode,
+						      pos, buf, bufsz);
 		} else
-			iwl3945_print_event_log(priv, next_entry - size,
-				    size, mode);
+			pos = iwl3945_print_event_log(priv, next_entry - size,
+						      size, mode,
+						      pos, buf, bufsz);
 	} else {
 		if (next_entry < size)
-			iwl3945_print_event_log(priv, 0, next_entry, mode);
+			pos = iwl3945_print_event_log(priv, 0,
+						      next_entry, mode,
+						      pos, buf, bufsz);
 		else
-			iwl3945_print_event_log(priv, next_entry - size,
-					    size, mode);
+			pos = iwl3945_print_event_log(priv, next_entry - size,
+						      size, mode,
+						      pos, buf, bufsz);
 	}
+	return pos;
 }
 
 /* For sanity check only.  Actual size is determined by uCode, typ. 512 */
@@ -1604,7 +1618,8 @@ static void iwl3945_print_last_event_log
 
 #define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20)
 
-void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
+int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
+			    char **buf, bool display)
 {
 	u32 base;       /* SRAM byte address of event log header */
 	u32 capacity;   /* event log capacity in # entries */
@@ -1612,11 +1627,13 @@ void iwl3945_dump_nic_event_log(struct i
 	u32 num_wraps;  /* # times uCode wrapped to top of log */
 	u32 next_entry; /* index of next entry to be written by uCode */
 	u32 size;       /* # entries that we'll print */
+	int pos = 0;
+	size_t bufsz = 0;
 
 	base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
 	if (!iwl3945_hw_valid_rtc_data_addr(base)) {
 		IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
-		return;
+		return  -EINVAL;
 	}
 
 	/* event log header */
@@ -1642,7 +1659,7 @@ void iwl3945_dump_nic_event_log(struct i
 	/* bail out if nothing in log */
 	if (size == 0) {
 		IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
-		return;
+		return pos;
 	}
 
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -1658,25 +1675,38 @@ void iwl3945_dump_nic_event_log(struct i
 		  size);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
+	if (display) {
+		if (full_log)
+			bufsz = capacity * 48;
+		else
+			bufsz = size * 48;
+		*buf = kmalloc(bufsz, GFP_KERNEL);
+		if (!*buf)
+			return -ENOMEM;
+	}
 	if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
 		/* if uCode has wrapped back to top of log,
 		 * start at the oldest entry,
 		 * i.e the next one that uCode would fill.
 		 */
 		if (num_wraps)
-			iwl3945_print_event_log(priv, next_entry,
-				    capacity - next_entry, mode);
+			pos = iwl3945_print_event_log(priv, next_entry,
+						capacity - next_entry, mode,
+						pos, buf, bufsz);
 
 		/* (then/else) start at top of log */
-		iwl3945_print_event_log(priv, 0, next_entry, mode);
+		pos = iwl3945_print_event_log(priv, 0, next_entry, mode,
+					      pos, buf, bufsz);
 	} else
-		iwl3945_print_last_event_logs(priv, capacity, num_wraps,
-					next_entry, size, mode);
+		pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps,
+						    next_entry, size, mode,
+						    pos, buf, bufsz);
 #else
-	iwl3945_print_last_event_logs(priv, capacity, num_wraps,
-				next_entry, size, mode);
+	pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps,
+					    next_entry, size, mode,
+					    pos, buf, bufsz);
 #endif
-
+	return pos;
 }
 
 static void iwl3945_irq_tasklet(struct iwl_priv *priv)
@@ -1926,7 +1956,7 @@ static void iwl3945_init_hw_rates(struct
 {
 	int i;
 
-	for (i = 0; i < IWL_RATE_COUNT; i++) {
+	for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
 		rates[i].bitrate = iwl3945_rates[i].ieee * 5;
 		rates[i].hw_value = i; /* Rate scaling will work on indexes */
 		rates[i].hw_value_short = i;
@@ -2937,7 +2967,8 @@ static void iwl3945_bg_request_scan(stru
 		 * is marked passive, we can do active scanning if we
 		 * detect transmissions.
 		 */
-		scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
+		scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+						IWL_GOOD_CRC_TH_DISABLED;
 		band = IEEE80211_BAND_5GHZ;
 	} else {
 		IWL_WARN(priv, "Invalid scan band count\n");
@@ -2996,18 +3027,6 @@ static void iwl3945_bg_request_scan(stru
 	mutex_unlock(&priv->mutex);
 }
 
-static void iwl3945_bg_up(struct work_struct *data)
-{
-	struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
-
-	mutex_lock(&priv->mutex);
-	__iwl3945_up(priv);
-	mutex_unlock(&priv->mutex);
-}
-
 static void iwl3945_bg_restart(struct work_struct *data)
 {
 	struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -3024,7 +3043,13 @@ static void iwl3945_bg_restart(struct wo
 		ieee80211_restart_hw(priv->hw);
 	} else {
 		iwl3945_down(priv);
-		queue_work(priv->workqueue, &priv->up);
+
+		if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+			return;
+
+		mutex_lock(&priv->mutex);
+		__iwl3945_up(priv);
+		mutex_unlock(&priv->mutex);
 	}
 }
 
@@ -3528,8 +3553,6 @@ static ssize_t store_filter_flags(struct
 static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
 		   store_filter_flags);
 
-#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
-
 static ssize_t show_measurement(struct device *d,
 				struct device_attribute *attr, char *buf)
 {
@@ -3599,7 +3622,6 @@ static ssize_t store_measurement(struct
 
 static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
 		   show_measurement, store_measurement);
-#endif /* CONFIG_IWL3945_SPECTRUM_MEASUREMENT */
 
 static ssize_t store_retry_rate(struct device *d,
 				struct device_attribute *attr,
@@ -3748,7 +3770,6 @@ static void iwl3945_setup_deferred_work(
 
 	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->beacon_update, iwl3945_bg_beacon_update);
@@ -3782,9 +3803,7 @@ static struct attribute *iwl3945_sysfs_e
 	&dev_attr_dump_errors.attr,
 	&dev_attr_flags.attr,
 	&dev_attr_filter_flags.attr,
-#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
 	&dev_attr_measurement.attr,
-#endif
 	&dev_attr_retry_rate.attr,
 	&dev_attr_statistics.attr,
 	&dev_attr_status.attr,
@@ -3810,7 +3829,6 @@ static struct ieee80211_ops iwl3945_hw_o
 	.config = iwl_mac_config,
 	.configure_filter = iwl_configure_filter,
 	.set_key = iwl3945_mac_set_key,
-	.get_tx_stats = iwl_mac_get_tx_stats,
 	.conf_tx = iwl_mac_conf_tx,
 	.reset_tsf = iwl_mac_reset_tsf,
 	.bss_info_changed = iwl_bss_info_changed,
@@ -3831,6 +3849,7 @@ static int iwl3945_init_drv(struct iwl_p
 	INIT_LIST_HEAD(&priv->free_frames);
 
 	mutex_init(&priv->mutex);
+	mutex_init(&priv->sync_cmd_mutex);
 
 	/* Clear the driver's (not device's) station table */
 	iwl_clear_stations_table(priv);
@@ -3840,6 +3859,7 @@ static int iwl3945_init_drv(struct iwl_p
 	priv->band = IEEE80211_BAND_2GHZ;
 
 	priv->iw_mode = NL80211_IFTYPE_STATION;
+	priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
 
 	iwl_reset_qos(priv);
 
@@ -3903,7 +3923,7 @@ static int iwl3945_setup_mac(struct iwl_
 		BIT(NL80211_IFTYPE_STATION) |
 		BIT(NL80211_IFTYPE_ADHOC);
 
-	hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY |
+	hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
 			    WIPHY_FLAG_DISABLE_BEACON_HINTS;
 
 	hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;
@@ -4022,6 +4042,13 @@ static int iwl3945_pci_probe(struct pci_
 	spin_lock_init(&priv->reg_lock);
 	spin_lock_init(&priv->lock);
 
+	/*
+	 * stop and reset the on-board processor just in case it is in a
+	 * strange state ... like being left stranded by a primary kernel
+	 * and this is now the kdump kernel trying to start up
+	 */
+	iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+
 	/***********************
 	 * 4. Read EEPROM
 	 * ********************/
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
@@ -45,8 +46,8 @@
 #include "iwl-sta.h"
 #include "iwl-3945.h"
 #include "iwl-eeprom.h"
-#include "iwl-helpers.h"
 #include "iwl-core.h"
+#include "iwl-helpers.h"
 #include "iwl-led.h"
 #include "iwl-3945-led.h"
 
@@ -184,7 +185,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8
 {
 	int idx;
 
-	for (idx = 0; idx < IWL_RATE_COUNT; idx++)
+	for (idx = 0; idx < IWL_RATE_COUNT_3945; idx++)
 		if (iwl3945_rates[idx].plcp == plcp)
 			return idx;
 	return -1;
@@ -805,7 +806,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct
 				  int sta_id, int tx_id)
 {
 	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_index = min(hw_value & 0xffff, IWL_RATE_COUNT_3945);
 	u16 rate_mask;
 	int rate;
 	u8 rts_retry_limit;
@@ -1951,11 +1952,7 @@ static int iwl3945_commit_rxon(struct iw
 	}
 
 	/* Add the broadcast address so we can send broadcast frames */
-	if (iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL) ==
-	    IWL_INVALID_STATION) {
-		IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
-		return -EIO;
-	}
+	priv->cfg->ops->lib->add_bcast_station(priv);
 
 	/* If we have set the ASSOC_MSK and we are in BSS mode then
 	 * add the IWL_AP_ID to the station rate table */
@@ -2150,7 +2147,7 @@ static void iwl3945_hw_reg_init_channel_
 
 		/* fill in channel group's nominal powers for each rate */
 		for (rate_index = 0;
-		     rate_index < IWL_RATE_COUNT; rate_index++, clip_pwrs++) {
+		     rate_index < IWL_RATE_COUNT_3945; rate_index++, clip_pwrs++) {
 			switch (rate_index) {
 			case IWL_RATE_36M_INDEX_TABLE:
 				if (i == 0)	/* B/G */
@@ -2474,11 +2471,9 @@ int iwl3945_hw_set_hw_params(struct iwl_
 	memset((void *)&priv->hw_params, 0,
 	       sizeof(struct iwl_hw_params));
 
-	priv->shared_virt =
-	    pci_alloc_consistent(priv->pci_dev,
-				 sizeof(struct iwl3945_shared),
-				 &priv->shared_phys);
-
+	priv->shared_virt = dma_alloc_coherent(&priv->pci_dev->dev,
+					       sizeof(struct iwl3945_shared),
+					       &priv->shared_phys, GFP_KERNEL);
 	if (!priv->shared_virt) {
 		IWL_ERR(priv, "failed to allocate pci memory\n");
 		mutex_unlock(&priv->mutex);
@@ -2796,6 +2791,7 @@ static struct iwl_lib_ops iwl3945_lib =
 	.post_associate = iwl3945_post_associate,
 	.isr = iwl_isr_legacy,
 	.config_ap = iwl3945_config_ap,
+	.add_bcast_station = iwl3945_add_bcast_station,
 };
 
 static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
@@ -2804,7 +2800,7 @@ static struct iwl_hcmd_utils_ops iwl3945
 	.rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
 };
 
-static struct iwl_ops iwl3945_ops = {
+static const struct iwl_ops iwl3945_ops = {
 	.ucode = &iwl3945_ucode,
 	.lib = &iwl3945_lib,
 	.hcmd = &iwl3945_hcmd,
@@ -2830,6 +2826,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
 	.ht_greenfield_support = false,
 	.led_compensation = 64,
 	.broken_powersave = true,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
 };
 
 static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2847,9 +2844,10 @@ static struct iwl_cfg iwl3945_abg_cfg =
 	.ht_greenfield_support = false,
 	.led_compensation = 64,
 	.broken_powersave = true,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
 };
 
-struct pci_device_id iwl3945_hw_card_ids[] = {
+DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
 	{IWL_PCI_DEVICE(0x4222, 0x1005, iwl3945_bg_cfg)},
 	{IWL_PCI_DEVICE(0x4222, 0x1034, iwl3945_bg_cfg)},
 	{IWL_PCI_DEVICE(0x4222, 0x1044, iwl3945_bg_cfg)},
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-fh.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-fh.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-fh.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 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.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.h	2013-05-03 12:09:50.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.h	2013-05-03 09:49:21.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -37,7 +37,7 @@
 #include <net/ieee80211_radiotap.h>
 
 /* Hardware specific file defines the PCI IDs table for that hardware module */
-extern struct pci_device_id iwl3945_hw_card_ids[];
+extern const struct pci_device_id iwl3945_hw_card_ids[];
 
 #include "iwl-csr.h"
 #include "iwl-prph.h"
@@ -171,24 +171,6 @@ struct iwl3945_frame {
 
 #define SCAN_INTERVAL 100
 
-#define STATUS_HCMD_ACTIVE	0	/* host command in progress */
-#define STATUS_HCMD_SYNC_ACTIVE	1	/* sync host command in progress */
-#define STATUS_INT_ENABLED	2
-#define STATUS_RF_KILL_HW	3
-#define STATUS_INIT		5
-#define STATUS_ALIVE		6
-#define STATUS_READY		7
-#define STATUS_TEMPERATURE	8
-#define STATUS_GEO_CONFIGURED	9
-#define STATUS_EXIT_PENDING	10
-#define STATUS_STATISTICS	12
-#define STATUS_SCANNING		13
-#define STATUS_SCAN_ABORTING	14
-#define STATUS_SCAN_HW		15
-#define STATUS_POWER_PMI	16
-#define STATUS_FW_ERROR		17
-#define STATUS_CONF_PENDING	18
-
 #define MAX_TID_COUNT        9
 
 #define IWL_INVALID_RATE     0xFF
@@ -226,7 +208,8 @@ extern void iwl3945_rx_replenish(void *d
 extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
 extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
 					struct ieee80211_hdr *hdr,int left);
-extern void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log);
+extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
+				       char **buf, bool display);
 extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-hw.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 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.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/wireless.h>
 #include <net/mac80211.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-4965.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-4965.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-4965.c	2013-05-03 12:09:56.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-4965.c	2013-05-03 09:49:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -581,6 +581,13 @@ static int iwl4965_alive_notify(struct i
 
 	iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
 
+	/* make sure all queue are not stopped */
+	memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
+	for (i = 0; i < 4; i++)
+		atomic_set(&priv->queue_stop_count[i], 0);
+
+	/* reset to 0 to enable all the queue first */
+	priv->txq_ctx_active_msk = 0;
 	/* Map each Tx/cmd queue to its corresponding fifo */
 	for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
 		int ac = default_queue_to_tx_fifo[i];
@@ -2008,7 +2015,9 @@ static void iwl4965_rx_reply_tx(struct i
 			IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
 					   "%d index %d\n", scd_ssn , index);
 			freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-			iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
+			if (qc)
+				iwl_free_tfds_in_queue(priv, sta_id,
+						       tid, freed);
 
 			if (priv->mac80211_registered &&
 			    (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
@@ -2035,13 +2044,14 @@ static void iwl4965_rx_reply_tx(struct i
 
 		freed = iwl_tx_queue_reclaim(priv, txq_id, index);
 		if (qc && likely(sta_id != IWL_INVALID_STATION))
-			priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+			iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
+		else if (sta_id == IWL_INVALID_STATION)
+			IWL_DEBUG_TX_REPLY(priv, "Station not known\n");
 
 		if (priv->mac80211_registered &&
 		    (iwl_queue_space(&txq->q) > txq->q.low_mark))
 			iwl_wake_queue(priv, txq_id);
 	}
-
 	if (qc && likely(sta_id != IWL_INVALID_STATION))
 		iwl_txq_check_empty(priv, sta_id, tid, txq_id);
 
@@ -2206,9 +2216,10 @@ static struct iwl_lib_ops iwl4965_lib =
 		.temperature = iwl4965_temperature_calib,
 		.set_ct_kill = iwl4965_set_ct_threshold,
 	},
+	.add_bcast_station = iwl_add_bcast_station,
 };
 
-static struct iwl_ops iwl4965_ops = {
+static const struct iwl_ops iwl4965_ops = {
 	.ucode = &iwl4965_ucode,
 	.lib = &iwl4965_lib,
 	.hcmd = &iwl4965_hcmd,
@@ -2239,7 +2250,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
 	.broken_powersave = true,
 	.led_compensation = 61,
 	.chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
-	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
 };
 
 /* Module firmware */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-4965-hw.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-4965-hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-4965-hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 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.33-gnu1/drivers/net/wireless/iwlwifi/iwl-5000.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-5000.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-5000.c	2013-05-03 12:09:58.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-5000.c	2013-05-03 09:49:29.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -179,14 +179,24 @@ static void iwl5000_gain_computation(str
 			data->delta_gain_code[i] = 0;
 			continue;
 		}
-		delta_g = (1000 * ((s32)average_noise[default_chain] -
+
+		delta_g = (priv->cfg->chain_noise_scale *
+			((s32)average_noise[default_chain] -
 			(s32)average_noise[i])) / 1500;
+
 		/* bound gain by 2 bits value max, 3rd bit is sign */
 		data->delta_gain_code[i] =
 			min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
 
 		if (delta_g < 0)
-			/* set negative sign */
+			/*
+			 * set negative sign ...
+			 * note to Intel developers:  This is uCode API format,
+			 *   not the format of any internal device registers.
+			 *   Do not change this format for e.g. 6050 or similar
+			 *   devices.  Change format only if more resolution
+			 *   (i.e. more than 2 bits magnitude) is needed.
+			 */
 			data->delta_gain_code[i] |= (1 << 2);
 	}
 
@@ -263,8 +273,8 @@ static struct iwl_sensitivity_ranges iwl
 
 	.auto_corr_max_ofdm = 120,
 	.auto_corr_max_ofdm_mrc = 210,
-	.auto_corr_max_ofdm_x1 = 155,
-	.auto_corr_max_ofdm_mrc_x1 = 290,
+	.auto_corr_max_ofdm_x1 = 120,
+	.auto_corr_max_ofdm_mrc_x1 = 240,
 
 	.auto_corr_min_cck = 125,
 	.auto_corr_max_cck = 200,
@@ -412,12 +422,14 @@ static void iwl5000_rx_calib_complete(st
 /*
  * ucode
  */
-static int iwl5000_load_section(struct iwl_priv *priv,
-				struct fw_desc *image,
-				u32 dst_addr)
+static int iwl5000_load_section(struct iwl_priv *priv, const char *name,
+				struct fw_desc *image, u32 dst_addr)
 {
 	dma_addr_t phy_addr = image->p_addr;
 	u32 byte_cnt = image->len;
+	int ret;
+
+	priv->ucode_write_complete = 0;
 
 	iwl_write_direct32(priv,
 		FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
@@ -447,57 +459,36 @@ static int iwl5000_load_section(struct i
 		FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE	|
 		FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
 
-	return 0;
-}
-
-static int iwl5000_load_given_ucode(struct iwl_priv *priv,
-		struct fw_desc *inst_image,
-		struct fw_desc *data_image)
-{
-	int ret = 0;
-
-	ret = iwl5000_load_section(priv, inst_image,
-				   IWL50_RTC_INST_LOWER_BOUND);
-	if (ret)
-		return ret;
-
-	IWL_DEBUG_INFO(priv, "INST uCode section being loaded...\n");
+	IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name);
 	ret = wait_event_interruptible_timeout(priv->wait_command_queue,
 					priv->ucode_write_complete, 5 * HZ);
 	if (ret == -ERESTARTSYS) {
-		IWL_ERR(priv, "Could not load the INST uCode section due "
-			"to interrupt\n");
+		IWL_ERR(priv, "Could not load the %s uCode section due "
+			"to interrupt\n", name);
 		return ret;
 	}
 	if (!ret) {
-		IWL_ERR(priv, "Could not load the INST uCode section\n");
+		IWL_ERR(priv, "Could not load the %s uCode section\n",
+			name);
 		return -ETIMEDOUT;
 	}
 
-	priv->ucode_write_complete = 0;
-
-	ret = iwl5000_load_section(
-		priv, data_image, IWL50_RTC_DATA_LOWER_BOUND);
-	if (ret)
-		return ret;
+	return 0;
+}
 
-	IWL_DEBUG_INFO(priv, "DATA uCode section being loaded...\n");
+static int iwl5000_load_given_ucode(struct iwl_priv *priv,
+		struct fw_desc *inst_image,
+		struct fw_desc *data_image)
+{
+	int ret = 0;
 
-	ret = wait_event_interruptible_timeout(priv->wait_command_queue,
-				priv->ucode_write_complete, 5 * HZ);
-	if (ret == -ERESTARTSYS) {
-		IWL_ERR(priv, "Could not load the INST uCode section due "
-			"to interrupt\n");
+	ret = iwl5000_load_section(priv, "INST", inst_image,
+				   IWL50_RTC_INST_LOWER_BOUND);
+	if (ret)
 		return ret;
-	} else if (!ret) {
-		IWL_ERR(priv, "Could not load the DATA uCode section\n");
-		return -ETIMEDOUT;
-	} else
-		ret = 0;
 
-	priv->ucode_write_complete = 0;
-
-	return ret;
+	return iwl5000_load_section(priv, "DATA", data_image,
+				    IWL50_RTC_DATA_LOWER_BOUND);
 }
 
 int iwl5000_load_ucode(struct iwl_priv *priv)
@@ -657,6 +648,13 @@ int iwl5000_alive_notify(struct iwl_priv
 
 	iwl5000_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
 
+	/* make sure all queue are not stopped */
+	memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
+	for (i = 0; i < 4; i++)
+		atomic_set(&priv->queue_stop_count[i], 0);
+
+	/* reset to 0 to enable all the queue first */
+	priv->txq_ctx_active_msk = 0;
 	/* map qos queues to fifos one-to-one */
 	for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) {
 		int ac = iwl5000_default_queue_to_tx_fifo[i];
@@ -781,7 +779,7 @@ void iwl5000_txq_update_byte_cnt_tbl(str
 
 	scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
 
-	if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
+	if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
 		scd_bc_tbl[txq_id].
 			tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
 }
@@ -800,12 +798,12 @@ void iwl5000_txq_inval_byte_cnt_tbl(stru
 	if (txq_id != IWL_CMD_QUEUE_NUM)
 		sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
 
-	bc_ent =  cpu_to_le16(1 | (sta_id << 12));
+	bc_ent = cpu_to_le16(1 | (sta_id << 12));
 	scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
 
-	if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
+	if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
 		scd_bc_tbl[txq_id].
-			tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] =  bc_ent;
+			tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
 }
 
 static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
@@ -1464,6 +1462,8 @@ struct iwl_lib_ops iwl5000_lib = {
 	.is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
 	.dump_nic_event_log = iwl_dump_nic_event_log,
 	.dump_nic_error_log = iwl_dump_nic_error_log,
+	.dump_csr = iwl_dump_csr,
+	.dump_fh = iwl_dump_fh,
 	.load_ucode = iwl5000_load_ucode,
 	.init_alive_start = iwl5000_init_alive_start,
 	.alive_notify = iwl5000_alive_notify,
@@ -1499,6 +1499,7 @@ struct iwl_lib_ops iwl5000_lib = {
 		.temperature = iwl5000_temperature,
 		.set_ct_kill = iwl5000_set_ct_threshold,
 	 },
+	.add_bcast_station = iwl_add_bcast_station,
 };
 
 static struct iwl_lib_ops iwl5150_lib = {
@@ -1516,6 +1517,7 @@ static struct iwl_lib_ops iwl5150_lib =
 	.is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
 	.dump_nic_event_log = iwl_dump_nic_event_log,
 	.dump_nic_error_log = iwl_dump_nic_error_log,
+	.dump_csr = iwl_dump_csr,
 	.load_ucode = iwl5000_load_ucode,
 	.init_alive_start = iwl5000_init_alive_start,
 	.alive_notify = iwl5000_alive_notify,
@@ -1551,9 +1553,10 @@ static struct iwl_lib_ops iwl5150_lib =
 		.temperature = iwl5150_temperature,
 		.set_ct_kill = iwl5150_set_ct_threshold,
 	 },
+	.add_bcast_station = iwl_add_bcast_station,
 };
 
-static struct iwl_ops iwl5000_ops = {
+static const struct iwl_ops iwl5000_ops = {
 	.ucode = &iwl5000_ucode,
 	.lib = &iwl5000_lib,
 	.hcmd = &iwl5000_hcmd,
@@ -1561,7 +1564,7 @@ static struct iwl_ops iwl5000_ops = {
 	.led = &iwlagn_led_ops,
 };
 
-static struct iwl_ops iwl5150_ops = {
+static const struct iwl_ops iwl5150_ops = {
 	.ucode = &iwl5000_ucode,
 	.lib = &iwl5150_lib,
 	.hcmd = &iwl5000_hcmd,
@@ -1598,7 +1601,8 @@ struct iwl_cfg iwl5300_agn_cfg = {
 	.led_compensation = 51,
 	.use_rts_for_ht = true, /* use rts/cts protection */
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
-	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
 };
 
 struct iwl_cfg iwl5100_bgn_cfg = {
@@ -1623,6 +1627,8 @@ struct iwl_cfg iwl5100_bgn_cfg = {
 	.led_compensation = 51,
 	.use_rts_for_ht = true, /* use rts/cts protection */
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
 };
 
 struct iwl_cfg iwl5100_abg_cfg = {
@@ -1645,6 +1651,8 @@ struct iwl_cfg iwl5100_abg_cfg = {
 	.use_bsm = false,
 	.led_compensation = 51,
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
 };
 
 struct iwl_cfg iwl5100_agn_cfg = {
@@ -1669,7 +1677,8 @@ struct iwl_cfg iwl5100_agn_cfg = {
 	.led_compensation = 51,
 	.use_rts_for_ht = true, /* use rts/cts protection */
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
-	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
 };
 
 struct iwl_cfg iwl5350_agn_cfg = {
@@ -1694,7 +1703,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
 	.led_compensation = 51,
 	.use_rts_for_ht = true, /* use rts/cts protection */
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
-	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
 };
 
 struct iwl_cfg iwl5150_agn_cfg = {
@@ -1719,7 +1729,8 @@ struct iwl_cfg iwl5150_agn_cfg = {
 	.led_compensation = 51,
 	.use_rts_for_ht = true, /* use rts/cts protection */
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
-	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
 };
 
 struct iwl_cfg iwl5150_abg_cfg = {
@@ -1742,6 +1753,8 @@ struct iwl_cfg iwl5150_abg_cfg = {
 	.use_bsm = false,
 	.led_compensation = 51,
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
 };
 
 /*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-5000-hw.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-5000-hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-5000-hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 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.33-gnu1/drivers/net/wireless/iwlwifi/iwl-6000.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-6000.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-6000.c	2013-05-03 12:10:00.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-6000.c	2013-05-03 09:49:31.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2008-2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -70,6 +70,14 @@ static void iwl6000_set_ct_threshold(str
 	priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
 }
 
+/* Indicate calibration version to uCode. */
+static void iwl6050_set_calib_version(struct iwl_priv *priv)
+{
+	if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
+		iwl_set_bit(priv, CSR_GP_DRIVER_REG,
+				CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
+}
+
 /* NIC configuration for 6000 series */
 static void iwl6000_nic_config(struct iwl_priv *priv)
 {
@@ -96,6 +104,8 @@ static void iwl6000_nic_config(struct iw
 			     CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
 	}
 	/* else do nothing, uCode configured */
+	if (priv->cfg->ops->lib->temp_ops.set_calib_version)
+		priv->cfg->ops->lib->temp_ops.set_calib_version(priv);
 }
 
 static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
@@ -108,7 +118,7 @@ static struct iwl_sensitivity_ranges iwl
 
 	.auto_corr_max_ofdm = 145,
 	.auto_corr_max_ofdm_mrc = 232,
-	.auto_corr_max_ofdm_x1 = 145,
+	.auto_corr_max_ofdm_x1 = 110,
 	.auto_corr_max_ofdm_mrc_x1 = 232,
 
 	.auto_corr_min_cck = 125,
@@ -158,11 +168,25 @@ static int iwl6000_hw_set_hw_params(stru
 	/* Set initial sensitivity parameters */
 	/* Set initial calibration set */
 	priv->hw_params.sens = &iwl6000_sensitivity;
-	priv->hw_params.calib_init_cfg =
+	switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+	case CSR_HW_REV_TYPE_6x50:
+		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_BASE_BAND);
+
+		break;
+	default:
+		priv->hw_params.calib_init_cfg =
+			BIT(IWL_CALIB_XTAL)		|
+			BIT(IWL_CALIB_LO)		|
+			BIT(IWL_CALIB_TX_IQ) 		|
+			BIT(IWL_CALIB_BASE_BAND);
+		break;
+	}
+
 	return 0;
 }
 
@@ -215,6 +239,8 @@ static struct iwl_lib_ops iwl6000_lib =
 	.load_ucode = iwl5000_load_ucode,
 	.dump_nic_event_log = iwl_dump_nic_event_log,
 	.dump_nic_error_log = iwl_dump_nic_error_log,
+	.dump_csr = iwl_dump_csr,
+	.dump_fh = iwl_dump_fh,
 	.init_alive_start = iwl5000_init_alive_start,
 	.alive_notify = iwl5000_alive_notify,
 	.send_tx_power = iwl5000_send_tx_power,
@@ -233,7 +259,7 @@ static struct iwl_lib_ops iwl6000_lib =
 			EEPROM_5000_REG_BAND_3_CHANNELS,
 			EEPROM_5000_REG_BAND_4_CHANNELS,
 			EEPROM_5000_REG_BAND_5_CHANNELS,
-			EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
+			EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_5000_REG_BAND_52_HT40_CHANNELS
 		},
 		.verify_signature  = iwlcore_eeprom_verify_signature,
@@ -250,9 +276,10 @@ static struct iwl_lib_ops iwl6000_lib =
 		.temperature = iwl5000_temperature,
 		.set_ct_kill = iwl6000_set_ct_threshold,
 	 },
+	.add_bcast_station = iwl_add_bcast_station,
 };
 
-static struct iwl_ops iwl6000_ops = {
+static const struct iwl_ops iwl6000_ops = {
 	.ucode = &iwl5000_ucode,
 	.lib = &iwl6000_lib,
 	.hcmd = &iwl5000_hcmd,
@@ -260,18 +287,68 @@ static struct iwl_ops iwl6000_ops = {
 	.led = &iwlagn_led_ops,
 };
 
-static struct iwl_hcmd_utils_ops iwl6050_hcmd_utils = {
-	.get_hcmd_size = iwl5000_get_hcmd_size,
-	.build_addsta_hcmd = iwl5000_build_addsta_hcmd,
-	.rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
-	.calc_rssi = iwl5000_calc_rssi,
+static struct iwl_lib_ops iwl6050_lib = {
+	.set_hw_params = iwl6000_hw_set_hw_params,
+	.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
+	.txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
+	.txq_set_sched = iwl5000_txq_set_sched,
+	.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,
+	.load_ucode = iwl5000_load_ucode,
+	.dump_nic_event_log = iwl_dump_nic_event_log,
+	.dump_nic_error_log = iwl_dump_nic_error_log,
+	.dump_csr = iwl_dump_csr,
+	.dump_fh = iwl_dump_fh,
+	.init_alive_start = iwl5000_init_alive_start,
+	.alive_notify = iwl5000_alive_notify,
+	.send_tx_power = iwl5000_send_tx_power,
+	.update_chain_flags = iwl_update_chain_flags,
+	.set_channel_switch = iwl6000_hw_channel_switch,
+	.apm_ops = {
+		.init = iwl_apm_init,
+		.stop = iwl_apm_stop,
+		.config = iwl6000_nic_config,
+		.set_pwr_src = iwl_set_pwr_src,
+	},
+	.eeprom_ops = {
+		.regulatory_bands = {
+			EEPROM_5000_REG_BAND_1_CHANNELS,
+			EEPROM_5000_REG_BAND_2_CHANNELS,
+			EEPROM_5000_REG_BAND_3_CHANNELS,
+			EEPROM_5000_REG_BAND_4_CHANNELS,
+			EEPROM_5000_REG_BAND_5_CHANNELS,
+			EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
+			EEPROM_5000_REG_BAND_52_HT40_CHANNELS
+		},
+		.verify_signature  = iwlcore_eeprom_verify_signature,
+		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
+		.release_semaphore = iwlcore_eeprom_release_semaphore,
+		.calib_version	= iwl5000_eeprom_calib_version,
+		.query_addr = iwl5000_eeprom_query_addr,
+		.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
+	},
+	.post_associate = iwl_post_associate,
+	.isr = iwl_isr_ict,
+	.config_ap = iwl_config_ap,
+	.temp_ops = {
+		.temperature = iwl5000_temperature,
+		.set_ct_kill = iwl6000_set_ct_threshold,
+		.set_calib_version = iwl6050_set_calib_version,
+	 },
+	.add_bcast_station = iwl_add_bcast_station,
 };
 
-static struct iwl_ops iwl6050_ops = {
+static const struct iwl_ops iwl6050_ops = {
 	.ucode = &iwl5000_ucode,
-	.lib = &iwl6000_lib,
+	.lib = &iwl6050_lib,
 	.hcmd = &iwl5000_hcmd,
-	.utils = &iwl6050_hcmd_utils,
+	.utils = &iwl5000_hcmd_utils,
 	.led = &iwlagn_led_ops,
 };
 
@@ -306,7 +383,8 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
 	.supports_idle = true,
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
-	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
 };
 
 struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -336,6 +414,8 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
 	.supports_idle = true,
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
 };
 
 struct iwl_cfg iwl6000i_2bg_cfg = {
@@ -365,6 +445,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
 	.supports_idle = true,
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
 };
 
 struct iwl_cfg iwl6050_2agn_cfg = {
@@ -395,7 +477,8 @@ struct iwl_cfg iwl6050_2agn_cfg = {
 	.supports_idle = true,
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
-	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DYNAMIC,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+	.chain_noise_scale = 1500,
 };
 
 struct iwl_cfg iwl6050_2abg_cfg = {
@@ -425,6 +508,8 @@ struct iwl_cfg iwl6050_2abg_cfg = {
 	.supports_idle = true,
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+	.chain_noise_scale = 1500,
 };
 
 struct iwl_cfg iwl6000_3agn_cfg = {
@@ -455,7 +540,8 @@ struct iwl_cfg iwl6000_3agn_cfg = {
 	.supports_idle = true,
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
-	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
 };
 
 /*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-6000-hw.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-6000-hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-6000-hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 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.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c	2013-05-03 12:09:53.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c	2013-05-03 09:49:24.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 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.
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
@@ -73,13 +74,7 @@
 #define VD
 #endif
 
-#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
-#define VS "s"
-#else
-#define VS
-#endif
-
-#define DRV_VERSION     IWLWIFI_VERSION VD VS
+#define DRV_VERSION     IWLWIFI_VERSION VD
 
 
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -203,7 +198,8 @@ int iwl_commit_rxon(struct iwl_priv *pri
 	priv->start_calib = 0;
 
 	/* Add the broadcast address so we can send broadcast frames */
-	iwl_add_bcast_station(priv);
+	priv->cfg->ops->lib->add_bcast_station(priv);
+
 
 	/* If we have set the ASSOC_MSK and we are in BSS mode then
 	 * add the IWL_AP_ID to the station rate table */
@@ -657,6 +653,131 @@ static void iwl_bg_statistics_periodic(u
 	iwl_send_statistics_request(priv, CMD_ASYNC, false);
 }
 
+
+static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
+					u32 start_idx, u32 num_events,
+					u32 mode)
+{
+	u32 i;
+	u32 ptr;        /* SRAM byte address of log data */
+	u32 ev, time, data; /* event log data */
+	unsigned long reg_flags;
+
+	if (mode == 0)
+		ptr = base + (4 * sizeof(u32)) + (start_idx * 2 * sizeof(u32));
+	else
+		ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32));
+
+	/* Make sure device is powered up for SRAM reads */
+	spin_lock_irqsave(&priv->reg_lock, reg_flags);
+	if (iwl_grab_nic_access(priv)) {
+		spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
+		return;
+	}
+
+	/* Set starting address; reads will auto-increment */
+	_iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
+	rmb();
+
+	/*
+	 * "time" is actually "data" for mode 0 (no timestamp).
+	 * place event id # at far right for easier visual parsing.
+	 */
+	for (i = 0; i < num_events; i++) {
+		ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+		time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+		if (mode == 0) {
+			trace_iwlwifi_dev_ucode_cont_event(priv,
+							0, time, ev);
+		} else {
+			data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+			trace_iwlwifi_dev_ucode_cont_event(priv,
+						time, data, ev);
+		}
+	}
+	/* Allow device to power down */
+	iwl_release_nic_access(priv);
+	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
+}
+
+static void iwl_continuous_event_trace(struct iwl_priv *priv)
+{
+	u32 capacity;   /* event log capacity in # entries */
+	u32 base;       /* SRAM byte address of event log header */
+	u32 mode;       /* 0 - no timestamp, 1 - timestamp recorded */
+	u32 num_wraps;  /* # times uCode wrapped to top of log */
+	u32 next_entry; /* index of next entry to be written by uCode */
+
+	if (priv->ucode_type == UCODE_INIT)
+		base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
+	else
+		base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
+	if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
+		capacity = iwl_read_targ_mem(priv, base);
+		num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
+		mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
+		next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
+	} else
+		return;
+
+	if (num_wraps == priv->event_log.num_wraps) {
+		iwl_print_cont_event_trace(priv,
+				       base, priv->event_log.next_entry,
+				       next_entry - priv->event_log.next_entry,
+				       mode);
+		priv->event_log.non_wraps_count++;
+	} else {
+		if ((num_wraps - priv->event_log.num_wraps) > 1)
+			priv->event_log.wraps_more_count++;
+		else
+			priv->event_log.wraps_once_count++;
+		trace_iwlwifi_dev_ucode_wrap_event(priv,
+				num_wraps - priv->event_log.num_wraps,
+				next_entry, priv->event_log.next_entry);
+		if (next_entry < priv->event_log.next_entry) {
+			iwl_print_cont_event_trace(priv, base,
+			       priv->event_log.next_entry,
+			       capacity - priv->event_log.next_entry,
+			       mode);
+
+			iwl_print_cont_event_trace(priv, base, 0,
+				next_entry, mode);
+		} else {
+			iwl_print_cont_event_trace(priv, base,
+			       next_entry, capacity - next_entry,
+			       mode);
+
+			iwl_print_cont_event_trace(priv, base, 0,
+				next_entry, mode);
+		}
+	}
+	priv->event_log.num_wraps = num_wraps;
+	priv->event_log.next_entry = next_entry;
+}
+
+/**
+ * iwl_bg_ucode_trace - Timer callback to log ucode event
+ *
+ * The timer is continually set to execute every
+ * UCODE_TRACE_PERIOD milliseconds after the last timer expired
+ * this function is to perform continuous uCode event logging operation
+ * if enabled
+ */
+static void iwl_bg_ucode_trace(unsigned long data)
+{
+	struct iwl_priv *priv = (struct iwl_priv *)data;
+
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		return;
+
+	if (priv->event_log.ucode_trace) {
+		iwl_continuous_event_trace(priv);
+		/* Reschedule the timer to occur in UCODE_TRACE_PERIOD */
+		mod_timer(&priv->ucode_trace,
+			 jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
+	}
+}
+
 static void iwl_rx_beacon_notif(struct iwl_priv *priv,
 				struct iwl_rx_mem_buffer *rxb)
 {
@@ -689,12 +810,14 @@ 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(priv, "Card state received: HW:%s SW:%s\n",
+	IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n",
 			  (flags & HW_CARD_DISABLED) ? "Kill" : "On",
-			  (flags & SW_CARD_DISABLED) ? "Kill" : "On");
+			  (flags & SW_CARD_DISABLED) ? "Kill" : "On",
+			  (flags & CT_CARD_DISABLED) ?
+			  "Reached" : "Not reached");
 
 	if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
-		     RF_CARD_DISABLED)) {
+		     CT_CARD_DISABLED)) {
 
 		iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
 			    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
@@ -708,10 +831,10 @@ static void iwl_rx_card_state_notif(stru
 			iwl_write_direct32(priv, HBUS_TARG_MBX_C,
 					HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
 		}
-		if (flags & RF_CARD_DISABLED)
+		if (flags & CT_CARD_DISABLED)
 			iwl_tt_enter_ct_kill(priv);
 	}
-	if (!(flags & RF_CARD_DISABLED))
+	if (!(flags & CT_CARD_DISABLED))
 		iwl_tt_exit_ct_kill(priv);
 
 	if (flags & HW_CARD_DISABLED)
@@ -761,6 +884,8 @@ static void iwl_setup_rx_handlers(struct
 	priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
 	priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
 	priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
+	priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
+			iwl_rx_spectrum_measure_notif;
 	priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
 	priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
 	    iwl_rx_pm_debug_statistics_notif;
@@ -774,7 +899,6 @@ static void iwl_setup_rx_handlers(struct
 	priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics;
 	priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
 
-	iwl_setup_spectrum_handlers(priv);
 	iwl_setup_rx_scan_handlers(priv);
 
 	/* status change handler */
@@ -1135,7 +1259,15 @@ static void iwl_irq_tasklet(struct iwl_p
 	/* Ack/clear/reset pending uCode interrupts.
 	 * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
 	 */
-	iwl_write32(priv, CSR_INT, priv->inta);
+	/* There is a hardware bug in the interrupt mask function that some
+	 * interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if
+	 * they are disabled in the CSR_INT_MASK register. Furthermore the
+	 * ICT interrupt handling mechanism has another bug that might cause
+	 * these unmasked interrupts fail to be detected. We workaround the
+	 * hardware bugs here by ACKing all the possible interrupts so that
+	 * interrupt coalescing can still be achieved.
+	 */
+	iwl_write32(priv, CSR_INT, priv->inta | ~priv->inta_mask);
 
 	inta = priv->inta;
 
@@ -1340,59 +1472,65 @@ static void iwl_nic_start(struct iwl_pri
 }
 
 
+static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
+static int iwl_mac_setup_register(struct iwl_priv *priv);
+
+static int __must_check iwl_reject_firmware(struct iwl_priv *priv, bool first)
+{
+	const char *name_pre = priv->cfg->fw_name_pre;
+
+	if (first)
+		priv->fw_index = priv->cfg->ucode_api_max;
+	else
+		priv->fw_index--;
+
+	if (priv->fw_index < priv->cfg->ucode_api_min) {
+		IWL_ERR(priv, "no suitable firmware found!\n");
+		return -ENOENT;
+	}
+
+	sprintf(priv->firmware_name, "/*(DEBLOBBED)*/");
+
+	IWL_DEBUG_INFO(priv, "attempting to load firmware '%s'\n",
+		       priv->firmware_name);
+
+	return reject_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
+				       &priv->pci_dev->dev, GFP_KERNEL, priv,
+				       iwl_ucode_callback);
+}
+
 /**
- * iwl_read_ucode - Read uCode images from disk file.
+ * iwl_ucode_callback - callback when firmware was loaded
  *
- * Copy into buffers for card to fetch via bus-mastering
+ * If loaded successfully, copies the firmware into buffers
+ * for the card to fetch (via DMA).
  */
-static int iwl_read_ucode(struct iwl_priv *priv)
+static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
 {
+	struct iwl_priv *priv = context;
 	struct iwl_ucode_header *ucode;
-	int ret = -EINVAL, index;
-	const struct firmware *ucode_raw;
-	const char *name_pre = priv->cfg->fw_name_pre;
 	const unsigned int api_max = priv->cfg->ucode_api_max;
 	const unsigned int api_min = priv->cfg->ucode_api_min;
-	char buf[25];
 	u8 *src;
 	size_t len;
 	u32 api_ver, build;
 	u32 inst_size, data_size, init_size, init_data_size, boot_size;
+	int err;
 	u16 eeprom_ver;
 
-	/* Ask kernel firmware_class module to get the boot firmware off disk.
-	 * reject_firmware() is synchronous, file is in memory on return. */
-	for (index = api_max; index >= api_min; index--) {
-		sprintf(buf, "/*(DEBLOBBED)*/");
-		ret = reject_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
-		if (ret < 0) {
-			IWL_ERR(priv, "%s firmware file req failed: %d\n",
-				  buf, ret);
-			if (ret == -ENOENT)
-				continue;
-			else
-				goto error;
-		} else {
-			if (index < api_max)
-				IWL_ERR(priv, "Loaded firmware %s, "
-					"which is deprecated. "
-					"Please use API v%u instead.\n",
-					  buf, api_max);
-
-			IWL_DEBUG_INFO(priv, "Got firmware '%s' file (%zd bytes) from disk\n",
-				       buf, ucode_raw->size);
-			break;
-		}
+	if (!ucode_raw) {
+		IWL_ERR(priv, "request for firmware file '%s' failed.\n",
+			priv->firmware_name);
+		goto try_again;
 	}
 
-	if (ret < 0)
-		goto error;
+	IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n",
+		       priv->firmware_name, ucode_raw->size);
 
 	/* Make sure that we got at least the v1 header! */
 	if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) {
 		IWL_ERR(priv, "File size way too small!\n");
-		ret = -EINVAL;
-		goto err_release;
+		goto try_again;
 	}
 
 	/* Data from ucode file:  header followed by uCode images */
@@ -1417,10 +1555,9 @@ static int iwl_read_ucode(struct iwl_pri
 		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;
-		ret = -EINVAL;
-		goto err_release;
+		goto try_again;
 	}
+
 	if (api_ver != api_max)
 		IWL_ERR(priv, "Firmware has old API version. Expected v%u, "
 			  "got v%u. New firmware can be obtained "
@@ -1462,6 +1599,12 @@ static int iwl_read_ucode(struct iwl_pri
 	IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
 		       boot_size);
 
+	/*
+	 * For any of the failures below (before allocating pci memory)
+	 * we will try to load a version with a smaller API -- maybe the
+	 * user just got a corrupted version of the latest API.
+	 */
+
 	/* Verify size of file vs. image size info in file's header */
 	if (ucode_raw->size !=
 		priv->cfg->ops->ucode->get_header_size(api_ver) +
@@ -1471,41 +1614,35 @@ static int iwl_read_ucode(struct iwl_pri
 		IWL_DEBUG_INFO(priv,
 			"uCode file size %d does not match expected size\n",
 			(int)ucode_raw->size);
-		ret = -EINVAL;
-		goto err_release;
+		goto try_again;
 	}
 
 	/* Verify that uCode images will fit in card's SRAM */
 	if (inst_size > priv->hw_params.max_inst_size) {
 		IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n",
 			       inst_size);
-		ret = -EINVAL;
-		goto err_release;
+		goto try_again;
 	}
 
 	if (data_size > priv->hw_params.max_data_size) {
 		IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n",
 				data_size);
-		ret = -EINVAL;
-		goto err_release;
+		goto try_again;
 	}
 	if (init_size > priv->hw_params.max_inst_size) {
 		IWL_INFO(priv, "uCode init instr len %d too large to fit in\n",
 			init_size);
-		ret = -EINVAL;
-		goto err_release;
+		goto try_again;
 	}
 	if (init_data_size > priv->hw_params.max_data_size) {
 		IWL_INFO(priv, "uCode init data len %d too large to fit in\n",
 		      init_data_size);
-		ret = -EINVAL;
-		goto err_release;
+		goto try_again;
 	}
 	if (boot_size > priv->hw_params.max_bsm_size) {
 		IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n",
 			boot_size);
-		ret = -EINVAL;
-		goto err_release;
+		goto try_again;
 	}
 
 	/* Allocate ucode buffers for card's bus-master loading ... */
@@ -1589,20 +1726,36 @@ static int iwl_read_ucode(struct iwl_pri
 	IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
 	memcpy(priv->ucode_boot.v_addr, src, len);
 
+	/**************************************************
+	 * This is still part of probe() in a sense...
+	 *
+	 * 9. Setup and register with mac80211 and debugfs
+	 **************************************************/
+	err = iwl_mac_setup_register(priv);
+	if (err)
+		goto out_unbind;
+
+	err = iwl_dbgfs_register(priv, DRV_NAME);
+	if (err)
+		IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
+
 	/* We have our copies now, allow OS release its copies */
 	release_firmware(ucode_raw);
-	return 0;
+	return;
+
+ try_again:
+	/* try next, if any */
+	if (iwl_reject_firmware(priv, false))
+		goto out_unbind;
+	release_firmware(ucode_raw);
+	return;
 
  err_pci_alloc:
 	IWL_ERR(priv, "failed to allocate pci memory\n");
-	ret = -ENOMEM;
 	iwl_dealloc_ucode_pci(priv);
-
- err_release:
+ out_unbind:
+	device_release_driver(&priv->pci_dev->dev);
 	release_firmware(ucode_raw);
-
- error:
-	return ret;
 }
 
 static const char *desc_lookup_text[] = {
@@ -1634,7 +1787,7 @@ static const char *desc_lookup_text[] =
 	"DEBUG_1",
 	"DEBUG_2",
 	"DEBUG_3",
-	"UNKNOWN"
+	"ADVANCED SYSASSERT"
 };
 
 static const char *desc_lookup(int i)
@@ -1705,8 +1858,9 @@ void iwl_dump_nic_error_log(struct iwl_p
  * iwl_print_event_log - Dump error event log to syslog
  *
  */
-static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
-				u32 num_events, u32 mode)
+static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
+			       u32 num_events, u32 mode,
+			       int pos, char **buf, size_t bufsz)
 {
 	u32 i;
 	u32 base;       /* SRAM byte address of event log header */
@@ -1716,7 +1870,7 @@ static void iwl_print_event_log(struct i
 	unsigned long reg_flags;
 
 	if (num_events == 0)
-		return;
+		return pos;
 	if (priv->ucode_type == UCODE_INIT)
 		base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
 	else
@@ -1744,27 +1898,44 @@ static void iwl_print_event_log(struct i
 		time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
 		if (mode == 0) {
 			/* data, ev */
-			trace_iwlwifi_dev_ucode_event(priv, 0, time, ev);
-			IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
+			if (bufsz) {
+				pos += scnprintf(*buf + pos, bufsz - pos,
+						"EVT_LOG:0x%08x:%04u\n",
+						time, ev);
+			} else {
+				trace_iwlwifi_dev_ucode_event(priv, 0,
+					time, ev);
+				IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n",
+					time, ev);
+			}
 		} else {
 			data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
-			IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
+			if (bufsz) {
+				pos += scnprintf(*buf + pos, bufsz - pos,
+						"EVT_LOGT:%010u:0x%08x:%04u\n",
+						 time, data, ev);
+			} else {
+				IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
 					time, data, ev);
-			trace_iwlwifi_dev_ucode_event(priv, time, data, ev);
+				trace_iwlwifi_dev_ucode_event(priv, time,
+					data, ev);
+			}
 		}
 	}
 
 	/* Allow device to power down */
 	iwl_release_nic_access(priv);
 	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
+	return pos;
 }
 
 /**
  * iwl_print_last_event_logs - Dump the newest # of event log to syslog
  */
-static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
-				      u32 num_wraps, u32 next_entry,
-				      u32 size, u32 mode)
+static int iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
+				    u32 num_wraps, u32 next_entry,
+				    u32 size, u32 mode,
+				    int pos, char **buf, size_t bufsz)
 {
 	/*
 	 * display the newest DEFAULT_LOG_ENTRIES entries
@@ -1772,21 +1943,26 @@ static void iwl_print_last_event_logs(st
 	 */
 	if (num_wraps) {
 		if (next_entry < size) {
-			iwl_print_event_log(priv,
-					capacity - (size - next_entry),
-					size - next_entry, mode);
-			iwl_print_event_log(priv, 0,
-				    next_entry, mode);
+			pos = iwl_print_event_log(priv,
+						capacity - (size - next_entry),
+						size - next_entry, mode,
+						pos, buf, bufsz);
+			pos = iwl_print_event_log(priv, 0,
+						  next_entry, mode,
+						  pos, buf, bufsz);
 		} else
-			iwl_print_event_log(priv, next_entry - size,
-				    size, mode);
+			pos = iwl_print_event_log(priv, next_entry - size,
+						  size, mode, pos, buf, bufsz);
 	} else {
-		if (next_entry < size)
-			iwl_print_event_log(priv, 0, next_entry, mode);
-		else
-			iwl_print_event_log(priv, next_entry - size,
-					    size, mode);
+		if (next_entry < size) {
+			pos = iwl_print_event_log(priv, 0, next_entry,
+						  mode, pos, buf, bufsz);
+		} else {
+			pos = iwl_print_event_log(priv, next_entry - size,
+						  size, mode, pos, buf, bufsz);
+		}
 	}
+	return pos;
 }
 
 /* For sanity check only.  Actual size is determined by uCode, typ. 512 */
@@ -1794,7 +1970,8 @@ static void iwl_print_last_event_logs(st
 
 #define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20)
 
-void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
+int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
+			    char **buf, bool display)
 {
 	u32 base;       /* SRAM byte address of event log header */
 	u32 capacity;   /* event log capacity in # entries */
@@ -1802,6 +1979,8 @@ void iwl_dump_nic_event_log(struct iwl_p
 	u32 num_wraps;  /* # times uCode wrapped to top of log */
 	u32 next_entry; /* index of next entry to be written by uCode */
 	u32 size;       /* # entries that we'll print */
+	int pos = 0;
+	size_t bufsz = 0;
 
 	if (priv->ucode_type == UCODE_INIT)
 		base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
@@ -1812,7 +1991,7 @@ void iwl_dump_nic_event_log(struct iwl_p
 		IWL_ERR(priv,
 			"Invalid event log pointer 0x%08X for %s uCode\n",
 			base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
-		return;
+		return -EINVAL;
 	}
 
 	/* event log header */
@@ -1838,7 +2017,7 @@ void iwl_dump_nic_event_log(struct iwl_p
 	/* bail out if nothing in log */
 	if (size == 0) {
 		IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
-		return;
+		return pos;
 	}
 
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -1853,6 +2032,15 @@ void iwl_dump_nic_event_log(struct iwl_p
 		size);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
+	if (display) {
+		if (full_log)
+			bufsz = capacity * 48;
+		else
+			bufsz = size * 48;
+		*buf = kmalloc(bufsz, GFP_KERNEL);
+		if (!*buf)
+			return -ENOMEM;
+	}
 	if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
 		/*
 		 * if uCode has wrapped back to top of log,
@@ -1860,17 +2048,22 @@ void iwl_dump_nic_event_log(struct iwl_p
 		 * i.e the next one that uCode would fill.
 		 */
 		if (num_wraps)
-			iwl_print_event_log(priv, next_entry,
-					    capacity - next_entry, mode);
+			pos = iwl_print_event_log(priv, next_entry,
+						capacity - next_entry, mode,
+						pos, buf, bufsz);
 		/* (then/else) start at top of log */
-		iwl_print_event_log(priv, 0, next_entry, mode);
+		pos = iwl_print_event_log(priv, 0,
+					  next_entry, mode, pos, buf, bufsz);
 	} else
-		iwl_print_last_event_logs(priv, capacity, num_wraps,
-					next_entry, size, mode);
+		pos = iwl_print_last_event_logs(priv, capacity, num_wraps,
+						next_entry, size, mode,
+						pos, buf, bufsz);
 #else
-	iwl_print_last_event_logs(priv, capacity, num_wraps,
-				next_entry, size, mode);
+	pos = iwl_print_last_event_logs(priv, capacity, num_wraps,
+					next_entry, size, mode,
+					pos, buf, bufsz);
 #endif
+	return pos;
 }
 
 /**
@@ -2276,18 +2469,6 @@ static void iwl_bg_run_time_calib_work(s
 	return;
 }
 
-static void iwl_bg_up(struct work_struct *data)
-{
-	struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
-
-	mutex_lock(&priv->mutex);
-	__iwl_up(priv);
-	mutex_unlock(&priv->mutex);
-}
-
 static void iwl_bg_restart(struct work_struct *data)
 {
 	struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -2304,7 +2485,13 @@ static void iwl_bg_restart(struct work_s
 		ieee80211_restart_hw(priv->hw);
 	} else {
 		iwl_down(priv);
-		queue_work(priv->workqueue, &priv->up);
+
+		if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+			return;
+
+		mutex_lock(&priv->mutex);
+		__iwl_up(priv);
+		mutex_unlock(&priv->mutex);
 	}
 }
 
@@ -2440,7 +2627,7 @@ void iwl_post_associate(struct iwl_priv
  * Not a mac80211 entry point function, but it fits in with all the
  * other mac80211 functions grouped here.
  */
-static int iwl_setup_mac(struct iwl_priv *priv)
+static int iwl_mac_setup_register(struct iwl_priv *priv)
 {
 	int ret;
 	struct ieee80211_hw *hw = priv->hw;
@@ -2456,12 +2643,16 @@ static int iwl_setup_mac(struct iwl_priv
 		hw->flags |= IEEE80211_HW_SUPPORTS_PS |
 			     IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
 
+	if (priv->cfg->sku & IWL_SKU_N)
+		hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
+			     IEEE80211_HW_SUPPORTS_STATIC_SMPS;
+
 	hw->sta_data_size = sizeof(struct iwl_station_priv);
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_STATION) |
 		BIT(NL80211_IFTYPE_ADHOC);
 
-	hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY |
+	hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
 			    WIPHY_FLAG_DISABLE_BEACON_HINTS;
 
 	/*
@@ -2506,21 +2697,7 @@ static int iwl_mac_start(struct ieee8021
 
 	/* we should be verifying the device is ready to be opened */
 	mutex_lock(&priv->mutex);
-
-	/* 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 = iwl_read_ucode(priv);
-		if (ret) {
-			IWL_ERR(priv, "Could not read microcode: %d\n", ret);
-			mutex_unlock(&priv->mutex);
-			return ret;
-		}
-	}
-
 	ret = __iwl_up(priv);
-
 	mutex_unlock(&priv->mutex);
 
 	if (ret)
@@ -2668,14 +2845,18 @@ void iwl_config_ap(struct iwl_priv *priv
 }
 
 static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
-			struct ieee80211_key_conf *keyconf, const u8 *addr,
-			u32 iv32, u16 *phase1key)
+				    struct ieee80211_vif *vif,
+				    struct ieee80211_key_conf *keyconf,
+				    struct ieee80211_sta *sta,
+				    u32 iv32, u16 *phase1key)
 {
 
 	struct iwl_priv *priv = hw->priv;
 	IWL_DEBUG_MAC80211(priv, "enter\n");
 
-	iwl_update_tkip_key(priv, keyconf, addr, iv32, phase1key);
+	iwl_update_tkip_key(priv, keyconf,
+			    sta ? sta->addr : iwl_bcast_addr,
+			    iv32, phase1key);
 
 	IWL_DEBUG_MAC80211(priv, "leave\n");
 }
@@ -2784,6 +2965,9 @@ static int iwl_mac_ampdu_action(struct i
 			return 0;
 		else
 			return ret;
+	case IEEE80211_AMPDU_TX_OPERATIONAL:
+		/* do nothing */
+		return -EOPNOTSUPP;
 	default:
 		IWL_DEBUG_HT(priv, "unknown\n");
 		return -EINVAL;
@@ -2833,6 +3017,8 @@ static void iwl_mac_sta_notify(struct ie
 		break;
 	case STA_NOTIFY_AWAKE:
 		WARN_ON(!sta_priv->client);
+		if (!sta_priv->asleep)
+			break;
 		sta_priv->asleep = false;
 		sta_id = iwl_find_station(priv, sta->addr);
 		if (sta_id != IWL_INVALID_STATION)
@@ -3109,7 +3295,6 @@ static void iwl_setup_deferred_work(stru
 
 	init_waitqueue_head(&priv->wait_command_queue);
 
-	INIT_WORK(&priv->up, iwl_bg_up);
 	INIT_WORK(&priv->restart, iwl_bg_restart);
 	INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
 	INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
@@ -3126,6 +3311,10 @@ static void iwl_setup_deferred_work(stru
 	priv->statistics_periodic.data = (unsigned long)priv;
 	priv->statistics_periodic.function = iwl_bg_statistics_periodic;
 
+	init_timer(&priv->ucode_trace);
+	priv->ucode_trace.data = (unsigned long)priv;
+	priv->ucode_trace.function = iwl_bg_ucode_trace;
+
 	if (!priv->cfg->use_isr_legacy)
 		tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
 			iwl_irq_tasklet, (unsigned long)priv);
@@ -3141,9 +3330,11 @@ static void iwl_cancel_deferred_work(str
 
 	cancel_delayed_work_sync(&priv->init_alive_start);
 	cancel_delayed_work(&priv->scan_check);
+	cancel_work_sync(&priv->start_internal_scan);
 	cancel_delayed_work(&priv->alive_start);
 	cancel_work_sync(&priv->beacon_update);
 	del_timer_sync(&priv->statistics_periodic);
+	del_timer_sync(&priv->ucode_trace);
 }
 
 static void iwl_init_hw_rates(struct iwl_priv *priv,
@@ -3179,6 +3370,7 @@ static int iwl_init_drv(struct iwl_priv
 	INIT_LIST_HEAD(&priv->free_frames);
 
 	mutex_init(&priv->mutex);
+	mutex_init(&priv->sync_cmd_mutex);
 
 	/* Clear the driver's (not device's) station table */
 	iwl_clear_stations_table(priv);
@@ -3188,6 +3380,14 @@ static int iwl_init_drv(struct iwl_priv
 	priv->band = IEEE80211_BAND_2GHZ;
 
 	priv->iw_mode = NL80211_IFTYPE_STATION;
+	priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
+	priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
+
+	/* initialize force reset */
+	priv->force_reset[IWL_RF_RESET].reset_duration =
+		IWL_DELAY_NEXT_FORCE_RF_RESET;
+	priv->force_reset[IWL_FW_RESET].reset_duration =
+		IWL_DELAY_NEXT_FORCE_FW_RELOAD;
 
 	/* Choose which receivers/antennas to use */
 	if (priv->cfg->ops->hcmd->set_rxon_chain)
@@ -3264,7 +3464,6 @@ static struct ieee80211_ops iwl_hw_ops =
 	.set_key = iwl_mac_set_key,
 	.update_tkip_key = iwl_mac_update_tkip_key,
 	.get_stats = iwl_mac_get_stats,
-	.get_tx_stats = iwl_mac_get_tx_stats,
 	.conf_tx = iwl_mac_conf_tx,
 	.reset_tsf = iwl_mac_reset_tsf,
 	.bss_info_changed = iwl_bss_info_changed,
@@ -3365,6 +3564,14 @@ static int iwl_pci_probe(struct pci_dev
 	 */
 	spin_lock_init(&priv->reg_lock);
 	spin_lock_init(&priv->lock);
+
+	/*
+	 * stop and reset the on-board processor just in case it is in a
+	 * strange state ... like being left stranded by a primary kernel
+	 * and this is now the kdump kernel trying to start up
+	 */
+	iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+
 	iwl_hw_detect(priv);
 	IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n",
 		priv->cfg->name, priv->hw_rev);
@@ -3439,9 +3646,9 @@ static int iwl_pci_probe(struct pci_dev
 	iwl_setup_deferred_work(priv);
 	iwl_setup_rx_handlers(priv);
 
-	/**********************************
-	 * 8. Setup and register mac80211
-	 **********************************/
+	/*********************************************
+	 * 8. Enable interrupts and read RFKILL state
+	 *********************************************/
 
 	/* enable interrupts if needed: hw bug w/a */
 	pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
@@ -3452,14 +3659,6 @@ static int iwl_pci_probe(struct pci_dev
 
 	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_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
-
 	/* 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);
@@ -3471,6 +3670,11 @@ static int iwl_pci_probe(struct pci_dev
 
 	iwl_power_initialize(priv);
 	iwl_tt_initialize(priv);
+
+	err = iwl_reject_firmware(priv, true);
+	if (err)
+		goto out_remove_sysfs;
+
 	return 0;
 
  out_remove_sysfs:
@@ -3589,7 +3793,7 @@ static void __devexit iwl_pci_remove(str
  *****************************************************************************/
 
 /* Hardware specific file defines the PCI IDs table for that hardware module */
-static struct pci_device_id iwl_hw_card_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
 #ifdef CONFIG_IWL4965
 	{IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)},
 	{IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)},
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/wireless.h>
 #include <net/mac80211.h>
 
@@ -298,10 +299,23 @@ static void rs_tl_turn_on_agg_for_tid(st
 				      struct iwl_lq_sta *lq_data, u8 tid,
 				      struct ieee80211_sta *sta)
 {
+	int ret;
+
 	if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
 		IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
 				sta->addr, tid);
-		ieee80211_start_tx_ba_session(sta, tid);
+		ret = ieee80211_start_tx_ba_session(sta, tid);
+		if (ret == -EAGAIN) {
+			/*
+			 * driver and mac80211 is out of sync
+			 * this might be cause by reloading firmware
+			 * stop the tx ba session here
+			 */
+			IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n",
+				tid);
+			ret = ieee80211_stop_tx_ba_session(sta, tid,
+						WLAN_BACK_INITIATOR);
+		}
 	}
 }
 
@@ -332,6 +346,17 @@ static inline int get_num_of_ant_from_ra
 	       !!(rate_n_flags & RATE_MCS_ANT_C_MSK);
 }
 
+/*
+ * Static function to get the expected throughput from an iwl_scale_tbl_info
+ * that wraps a NULL pointer check
+ */
+static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
+{
+	if (tbl->expected_tpt)
+		return tbl->expected_tpt[rs_index];
+	return 0;
+}
+
 /**
  * rs_collect_tx_data - Update the success/failure sliding window
  *
@@ -339,19 +364,21 @@ static inline int get_num_of_ant_from_ra
  * at this rate.  window->data contains the bitmask of successful
  * packets.
  */
-static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
-			      int scale_index, s32 tpt, int attempts,
-			      int successes)
+static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
+			      int scale_index, int attempts, int successes)
 {
 	struct iwl_rate_scale_data *window = NULL;
 	static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
-	s32 fail_count;
+	s32 fail_count, tpt;
 
 	if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
 		return -EINVAL;
 
 	/* Select window for current tx bit rate */
-	window = &(windows[scale_index]);
+	window = &(tbl->win[scale_index]);
+
+	/* Get expected throughput */
+	tpt = get_expected_tpt(tbl, scale_index);
 
 	/*
 	 * Keep track of only the latest 62 tx frame attempts in this rate's
@@ -725,16 +752,6 @@ static bool table_type_matches(struct iw
 	return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
 		(a->is_SGI == b->is_SGI);
 }
-/*
- * Static function to get the expected throughput from an iwl_scale_tbl_info
- * that wraps a NULL pointer check
- */
-static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
-{
-	if (tbl->expected_tpt)
-		return tbl->expected_tpt[rs_index];
-	return 0;
-}
 
 /*
  * mac80211 sends us Tx status
@@ -751,12 +768,10 @@ static void rs_tx_status(void *priv_r, s
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct iwl_priv *priv = (struct iwl_priv *)priv_r;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	struct iwl_rate_scale_data *window = NULL;
 	enum mac80211_rate_control_flags mac_flags;
 	u32 tx_rate;
 	struct iwl_scale_tbl_info tbl_type;
-	struct iwl_scale_tbl_info *curr_tbl, *other_tbl;
-	s32 tpt = 0;
+	struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
 
 	IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
 
@@ -839,7 +854,6 @@ static void rs_tx_status(void *priv_r, s
 		IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
 		return;
 	}
-	window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
 
 	/*
 	 * Updating the frame history depends on whether packets were
@@ -852,8 +866,7 @@ static void rs_tx_status(void *priv_r, s
 		tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
 		rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,
 				&rs_index);
-		tpt = get_expected_tpt(curr_tbl, rs_index);
-		rs_collect_tx_data(window, rs_index, tpt,
+		rs_collect_tx_data(curr_tbl, rs_index,
 				   info->status.ampdu_ack_len,
 				   info->status.ampdu_ack_map);
 
@@ -883,19 +896,13 @@ static void rs_tx_status(void *priv_r, s
 			 * table as active/search.
 			 */
 			if (table_type_matches(&tbl_type, curr_tbl))
-				tpt = get_expected_tpt(curr_tbl, rs_index);
+				tmp_tbl = curr_tbl;
 			else if (table_type_matches(&tbl_type, other_tbl))
-				tpt = get_expected_tpt(other_tbl, rs_index);
+				tmp_tbl = other_tbl;
 			else
 				continue;
-
-			/* Constants mean 1 transmission, 0 successes */
-			if (i < retries)
-				rs_collect_tx_data(window, rs_index, tpt, 1,
-						0);
-			else
-				rs_collect_tx_data(window, rs_index, tpt, 1,
-						legacy_success);
+			rs_collect_tx_data(tmp_tbl, rs_index, 1,
+					   i < retries ? 0 : legacy_success);
 		}
 
 		/* Update success/fail counts if not searching for new mode */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -191,7 +191,7 @@ enum {
 	IWL_RATE_2M_MASK)
 
 #define IWL_CCK_RATES_MASK          \
-       (IWL_BASIC_RATES_MASK      | \
+       (IWL_CCK_BASIC_RATES_MASK  | \
 	IWL_RATE_5M_MASK          | \
 	IWL_RATE_11M_MASK)
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -60,6 +60,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
+#include <linux/slab.h>
 #include <net/mac80211.h>
 
 #include "iwl-dev.h"
@@ -414,7 +415,6 @@ static int iwl_sens_auto_corr_ofdm(struc
 /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
 static int iwl_sensitivity_write(struct iwl_priv *priv)
 {
-	int ret = 0;
 	struct iwl_sensitivity_cmd cmd ;
 	struct iwl_sensitivity_data *data = NULL;
 	struct iwl_host_cmd cmd_out = {
@@ -477,11 +477,7 @@ static int iwl_sensitivity_write(struct
 	memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]),
 	       sizeof(u16)*HD_TABLE_SIZE);
 
-	ret = iwl_send_cmd(priv, &cmd_out);
-	if (ret)
-		IWL_ERR(priv, "SENSITIVITY_CMD failed\n");
-
-	return ret;
+	return iwl_send_cmd(priv, &cmd_out);
 }
 
 void iwl_init_sensitivity(struct iwl_priv *priv)
@@ -812,6 +808,18 @@ void iwl_chain_noise_calibration(struct
 		}
 	}
 
+	/*
+	 * The above algorithm sometimes fails when the ucode
+	 * reports 0 for all chains. It's not clear why that
+	 * happens to start with, but it is then causing trouble
+	 * because this can make us enable more chains than the
+	 * hardware really has.
+	 *
+	 * To be safe, simply mask out any chains that we know
+	 * are not on the device.
+	 */
+	active_chains &= priv->hw_params.valid_rx_ant;
+
 	num_tx_chains = 0;
 	for (i = 0; i < NUM_RX_CHAINS; i++) {
 		/* loops on all the bits of
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 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.33-gnu1/drivers/net/wireless/iwlwifi/iwl-commands.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-commands.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-commands.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-commands.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -120,7 +120,6 @@ enum {
 	CALIBRATION_COMPLETE_NOTIFICATION = 0x67,
 
 	/* 802.11h related */
-	RADAR_NOTIFICATION = 0x70,	/* not used */
 	REPLY_QUIET_CMD = 0x71,		/* not used */
 	REPLY_CHANNEL_SWITCH = 0x72,
 	CHANNEL_SWITCH_NOTIFICATION = 0x73,
@@ -2248,10 +2247,22 @@ struct iwl_link_quality_cmd {
 	__le32 reserved2;
 } __attribute__ ((packed));
 
+/*
+ * BT configuration enable flags:
+ *   bit 0 - 1: BT channel announcement enabled
+ *           0: disable
+ *   bit 1 - 1: priority of BT device enabled
+ *           0: disable
+ *   bit 2 - 1: BT 2 wire support enabled
+ *           0: disable
+ */
 #define BT_COEX_DISABLE (0x0)
-#define BT_COEX_MODE_2W (0x1)
-#define BT_COEX_MODE_3W (0x2)
-#define BT_COEX_MODE_4W (0x3)
+#define BT_ENABLE_CHANNEL_ANNOUNCE BIT(0)
+#define BT_ENABLE_PRIORITY	   BIT(1)
+#define BT_ENABLE_2_WIRE	   BIT(2)
+
+#define BT_COEX_DISABLE (0x0)
+#define BT_COEX_ENABLE  (BT_ENABLE_CHANNEL_ANNOUNCE | BT_ENABLE_PRIORITY)
 
 #define BT_LEAD_TIME_MIN (0x0)
 #define BT_LEAD_TIME_DEF (0x1E)
@@ -2510,7 +2521,7 @@ struct iwl_card_state_notif {
 
 #define HW_CARD_DISABLED   0x01
 #define SW_CARD_DISABLED   0x02
-#define RF_CARD_DISABLED   0x04
+#define CT_CARD_DISABLED   0x04
 #define RXON_CARD_DISABLED 0x10
 
 struct iwl_ct_kill_config {
@@ -2610,8 +2621,11 @@ struct iwl_ssid_ie {
 #define PROBE_OPTION_MAX_3945		4
 #define PROBE_OPTION_MAX		20
 #define TX_CMD_LIFE_TIME_INFINITE	cpu_to_le32(0xFFFFFFFF)
-#define IWL_GOOD_CRC_TH			cpu_to_le16(1)
+#define IWL_GOOD_CRC_TH_DISABLED	0
+#define IWL_GOOD_CRC_TH_DEFAULT		cpu_to_le16(1)
+#define IWL_GOOD_CRC_TH_NEVER		cpu_to_le16(0xffff)
 #define IWL_MAX_SCAN_SIZE 1024
+#define IWL_MAX_CMD_SIZE 4096
 #define IWL_MAX_PROBE_REQUEST		200
 
 /*
@@ -2984,7 +2998,7 @@ struct statistics_rx_ht_phy {
 	__le32 agg_crc32_good;
 	__le32 agg_mpdu_cnt;
 	__le32 agg_cnt;
-	__le32 reserved2;
+	__le32 unsupport_mcs;
 } __attribute__ ((packed));
 
 #define INTERFERENCE_DATA_AVAILABLE      cpu_to_le32(1)
@@ -3087,8 +3101,8 @@ struct statistics_div {
 } __attribute__ ((packed));
 
 struct statistics_general {
-	__le32 temperature;
-	__le32 temperature_m;
+	__le32 temperature;   /* radio temperature */
+	__le32 temperature_m; /* for 5000 and up, this is radio voltage */
 	struct statistics_dbg dbg;
 	__le32 sleep_time;
 	__le32 slots_out;
@@ -3096,7 +3110,12 @@ struct statistics_general {
 	__le32 ttl_timestamp;
 	struct statistics_div div;
 	__le32 rx_enable_counter;
-	__le32 reserved1;
+	/*
+	 * num_of_sos_states:
+	 *  count the number of times we have to re-tune
+	 *  in order to get out of bad PHY status
+	 */
+	__le32 num_of_sos_states;
 	__le32 reserved2;
 	__le32 reserved3;
 } __attribute__ ((packed));
@@ -3161,13 +3180,30 @@ struct iwl_notif_statistics {
 
 /*
  * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
+ *
+ * uCode send MISSED_BEACONS_NOTIFICATION to driver when detect beacon missed
+ * in regardless of how many missed beacons, which mean when driver receive the
+ * notification, inside the command, it can find all the beacons information
+ * which include number of total missed beacons, number of consecutive missed
+ * beacons, number of beacons received and number of beacons expected to
+ * receive.
+ *
+ * If uCode detected consecutive_missed_beacons > 5, it will reset the radio
+ * in order to bring the radio/PHY back to working state; which has no relation
+ * to when driver will perform sensitivity calibration.
+ *
+ * Driver should set it own missed_beacon_threshold to decide when to perform
+ * sensitivity calibration based on number of consecutive missed beacons in
+ * order to improve overall performance, especially in noisy environment.
+ *
  */
-/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row,
- * then this notification will be sent. */
-#define CONSECUTIVE_MISSED_BCONS_TH 20
+
+#define IWL_MISSED_BEACON_THRESHOLD_MIN	(1)
+#define IWL_MISSED_BEACON_THRESHOLD_DEF	(5)
+#define IWL_MISSED_BEACON_THRESHOLD_MAX	IWL_MISSED_BEACON_THRESHOLD_DEF
 
 struct iwl_missed_beacon_notif {
-	__le32 consequtive_missed_beacons;
+	__le32 consecutive_missed_beacons;
 	__le32 total_missed_becons;
 	__le32 num_expected_beacons;
 	__le32 num_recvd_beacons;
@@ -3437,11 +3473,7 @@ enum {
 	IWL_PHY_CALIBRATE_DIFF_GAIN_CMD		= 7,
 	IWL_PHY_CALIBRATE_DC_CMD		= 8,
 	IWL_PHY_CALIBRATE_LO_CMD		= 9,
-	IWL_PHY_CALIBRATE_RX_BB_CMD		= 10,
 	IWL_PHY_CALIBRATE_TX_IQ_CMD		= 11,
-	IWL_PHY_CALIBRATE_RX_IQ_CMD		= 12,
-	IWL_PHY_CALIBRATION_NOISE_CMD		= 13,
-	IWL_PHY_CALIBRATE_AGC_TABLE_CMD		= 14,
 	IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD	= 15,
 	IWL_PHY_CALIBRATE_BASE_BAND_CMD		= 16,
 	IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD	= 17,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-core.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-core.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/etherdevice.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 
 #include "iwl-eeprom.h"
@@ -47,6 +48,26 @@ MODULE_VERSION(IWLWIFI_VERSION);
 MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
 MODULE_LICENSE("GPL");
 
+/*
+ * set bt_coex_active to true, uCode will do kill/defer
+ * every time the priority line is asserted (BT is sending signals on the
+ * priority line in the PCIx).
+ * set bt_coex_active to false, uCode will ignore the BT activity and
+ * perform the normal operation
+ *
+ * User might experience transmit issue on some platform due to WiFi/BT
+ * co-exist problem. The possible behaviors are:
+ *   Able to scan and finding all the available AP
+ *   Not able to associate with any AP
+ * On those platforms, WiFi communication can be restored by set
+ * "bt_coex_active" module parameter to "false"
+ *
+ * default: bt_coex_active = true (BT_COEX_ENABLE)
+ */
+static bool bt_coex_active = true;
+module_param(bt_coex_active, bool, S_IRUGO);
+MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist\n");
+
 static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
 	{COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
 	 0, COEX_UNASSOC_IDLE_FLAGS},
@@ -257,8 +278,8 @@ int iwl_hw_nic_init(struct iwl_priv *pri
 	spin_lock_irqsave(&priv->lock, flags);
 	priv->cfg->ops->lib->apm_ops.init(priv);
 
-	/* Set interrupt coalescing timer to 512 usecs */
-	iwl_write8(priv, CSR_INT_COALESCING, 512 / 32);
+	/* Set interrupt coalescing calibration timer to default (512 usecs) */
+	iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -287,10 +308,13 @@ int iwl_hw_nic_init(struct iwl_priv *pri
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	/* Allocate and init all Tx and Command queues */
-	ret = iwl_txq_ctx_reset(priv);
-	if (ret)
-		return ret;
+	/* Allocate or reset and init all Tx and Command queues */
+	if (!priv->txq) {
+		ret = iwl_txq_ctx_alloc(priv);
+		if (ret)
+			return ret;
+	} else
+		iwl_txq_ctx_reset(priv);
 
 	set_bit(STATUS_INIT, &priv->status);
 
@@ -450,8 +474,6 @@ static void iwlcore_init_ht_hw_capab(con
 	if (priv->cfg->ht_greenfield_support)
 		ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
 	ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
-	ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
-			     (priv->cfg->sm_ps_mode << 2));
 	max_bit_rate = MAX_BIT_RATE_20_MHZ;
 	if (priv->hw_params.ht40_channel & BIT(band)) {
 		ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
@@ -636,7 +658,7 @@ EXPORT_SYMBOL(iwlcore_rts_tx_cmd_flag);
 
 static bool is_single_rx_stream(struct iwl_priv *priv)
 {
-	return !priv->current_ht_config.is_ht ||
+	return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
 	       priv->current_ht_config.single_chain_sufficient;
 }
 
@@ -1003,28 +1025,18 @@ static int iwl_get_active_rx_chain_count
  */
 static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
 {
-	int idle_cnt = active_cnt;
-	bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
-
-	/* # Rx chains when idling and maybe trying to save power */
-	switch (priv->cfg->sm_ps_mode) {
-	case WLAN_HT_CAP_SM_PS_STATIC:
-		idle_cnt = (is_cam) ? active_cnt : IWL_NUM_IDLE_CHAINS_SINGLE;
-		break;
-	case WLAN_HT_CAP_SM_PS_DYNAMIC:
-		idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
-			IWL_NUM_IDLE_CHAINS_SINGLE;
-		break;
-	case WLAN_HT_CAP_SM_PS_DISABLED:
-		break;
-	case WLAN_HT_CAP_SM_PS_INVALID:
+	/* # Rx chains when idling, depending on SMPS mode */
+	switch (priv->current_ht_config.smps) {
+	case IEEE80211_SMPS_STATIC:
+	case IEEE80211_SMPS_DYNAMIC:
+		return IWL_NUM_IDLE_CHAINS_SINGLE;
+	case IEEE80211_SMPS_OFF:
+		return active_cnt;
 	default:
-		IWL_ERR(priv, "invalid sm_ps mode %u\n",
-			priv->cfg->sm_ps_mode);
-		WARN_ON(1);
-		break;
+		WARN(1, "invalid SMPS mode %d",
+		     priv->current_ht_config.smps);
+		return active_cnt;
 	}
-	return idle_cnt;
 }
 
 /* up to 4 chains */
@@ -1363,7 +1375,11 @@ void iwl_irq_handle_error(struct iwl_pri
 	clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
 
 	priv->cfg->ops->lib->dump_nic_error_log(priv);
-	priv->cfg->ops->lib->dump_nic_event_log(priv, false);
+	if (priv->cfg->ops->lib->dump_csr)
+		priv->cfg->ops->lib->dump_csr(priv);
+	if (priv->cfg->ops->lib->dump_fh)
+		priv->cfg->ops->lib->dump_fh(priv, NULL, false);
+	priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false);
 #ifdef CONFIG_IWLWIFI_DEBUG
 	if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
 		iwl_print_rx_config_cmd(priv);
@@ -1658,9 +1674,9 @@ EXPORT_SYMBOL(iwl_set_tx_power);
 void iwl_free_isr_ict(struct iwl_priv *priv)
 {
 	if (priv->ict_tbl_vir) {
-		pci_free_consistent(priv->pci_dev, (sizeof(u32) * ICT_COUNT) +
-					PAGE_SIZE, priv->ict_tbl_vir,
-					priv->ict_tbl_dma);
+		dma_free_coherent(&priv->pci_dev->dev,
+				  (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
+				  priv->ict_tbl_vir, priv->ict_tbl_dma);
 		priv->ict_tbl_vir = NULL;
 	}
 }
@@ -1676,9 +1692,9 @@ int iwl_alloc_isr_ict(struct iwl_priv *p
 	if (priv->cfg->use_isr_legacy)
 		return 0;
 	/* allocate shrared data table */
-	priv->ict_tbl_vir = pci_alloc_consistent(priv->pci_dev, (sizeof(u32) *
-						  ICT_COUNT) + PAGE_SIZE,
-						  &priv->ict_tbl_dma);
+	priv->ict_tbl_vir = dma_alloc_coherent(&priv->pci_dev->dev,
+					(sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
+					&priv->ict_tbl_dma, GFP_KERNEL);
 	if (!priv->ict_tbl_vir)
 		return -ENOMEM;
 
@@ -1813,6 +1829,16 @@ irqreturn_t iwl_isr_ict(int irq, void *d
 	if (val == 0xffffffff)
 		val = 0;
 
+	/*
+	 * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit
+	 * (bit 15 before shifting it to 31) to clear when using interrupt
+	 * coalescing. fortunately, bits 18 and 19 stay set when this happens
+	 * so we use them to decide on the real state of the Rx bit.
+	 * In order words, bit 15 is set if bit 18 or bit 19 are set.
+	 */
+	if (val & 0xC0000)
+		val |= 0x8000;
+
 	inta = (0xff & val) | ((0xff00 & val) << 16);
 	IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n",
 			inta, inta_mask, val);
@@ -1975,13 +2001,20 @@ EXPORT_SYMBOL(iwl_isr_legacy);
 int iwl_send_bt_config(struct iwl_priv *priv)
 {
 	struct iwl_bt_cmd bt_cmd = {
-		.flags = BT_COEX_MODE_4W,
 		.lead_time = BT_LEAD_TIME_DEF,
 		.max_kill = BT_MAX_KILL_DEF,
 		.kill_ack_mask = 0,
 		.kill_cts_mask = 0,
 	};
 
+	if (!bt_coex_active)
+		bt_cmd.flags = BT_COEX_DISABLE;
+	else
+		bt_cmd.flags = BT_COEX_ENABLE;
+
+	IWL_DEBUG_INFO(priv, "BT coex %s\n",
+		(bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
+
 	return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
 				sizeof(struct iwl_bt_cmd), &bt_cmd);
 }
@@ -2599,44 +2632,43 @@ int iwl_set_mode(struct iwl_priv *priv,
 EXPORT_SYMBOL(iwl_set_mode);
 
 int iwl_mac_add_interface(struct ieee80211_hw *hw,
-				 struct ieee80211_if_init_conf *conf)
+				 struct ieee80211_vif *vif)
 {
 	struct iwl_priv *priv = hw->priv;
-	unsigned long flags;
+	int err = 0;
 
-	IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
+	IWL_DEBUG_MAC80211(priv, "enter: type %d\n", vif->type);
+
+	mutex_lock(&priv->mutex);
 
 	if (priv->vif) {
 		IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
-		return -EOPNOTSUPP;
+		err = -EOPNOTSUPP;
+		goto out;
 	}
 
-	spin_lock_irqsave(&priv->lock, flags);
-	priv->vif = conf->vif;
-	priv->iw_mode = conf->type;
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	mutex_lock(&priv->mutex);
+	priv->vif = vif;
+	priv->iw_mode = vif->type;
 
-	if (conf->mac_addr) {
-		IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr);
-		memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
+	if (vif->addr) {
+		IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr);
+		memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
 	}
 
-	if (iwl_set_mode(priv, conf->type) == -EAGAIN)
+	if (iwl_set_mode(priv, vif->type) == -EAGAIN)
 		/* we are not ready, will run again when ready */
 		set_bit(STATUS_MODE_PENDING, &priv->status);
 
+ out:
 	mutex_unlock(&priv->mutex);
 
 	IWL_DEBUG_MAC80211(priv, "leave\n");
-	return 0;
+	return err;
 }
 EXPORT_SYMBOL(iwl_mac_add_interface);
 
 void iwl_mac_remove_interface(struct ieee80211_hw *hw,
-				     struct ieee80211_if_init_conf *conf)
+				     struct ieee80211_vif *vif)
 {
 	struct iwl_priv *priv = hw->priv;
 
@@ -2649,7 +2681,7 @@ void iwl_mac_remove_interface(struct iee
 		priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 		iwlcore_commit_rxon(priv);
 	}
-	if (priv->vif == conf->vif) {
+	if (priv->vif == vif) {
 		priv->vif = NULL;
 		memset(priv->bssid, 0, ETH_ALEN);
 	}
@@ -2689,6 +2721,21 @@ int iwl_mac_config(struct ieee80211_hw *
 		IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
 	}
 
+	if (changed & (IEEE80211_CONF_CHANGE_SMPS |
+		       IEEE80211_CONF_CHANGE_CHANNEL)) {
+		/* mac80211 uses static for non-HT which is what we want */
+		priv->current_ht_config.smps = conf->smps_mode;
+
+		/*
+		 * Recalculate chain counts.
+		 *
+		 * If monitor mode is enabled then mac80211 will
+		 * set up the SM PS mode to OFF if an HT channel is
+		 * configured.
+		 */
+		if (priv->cfg->ops->hcmd->set_rxon_chain)
+			priv->cfg->ops->hcmd->set_rxon_chain(priv);
+	}
 
 	/* during scanning mac80211 will delay channel setting until
 	 * scan finish with changed = 0
@@ -2786,10 +2833,6 @@ int iwl_mac_config(struct ieee80211_hw *
 		iwl_set_tx_power(priv, conf->power_level, false);
 	}
 
-	/* call to ensure that 4965 rx_chain is set properly in monitor mode */
-	if (priv->cfg->ops->hcmd->set_rxon_chain)
-		priv->cfg->ops->hcmd->set_rxon_chain(priv);
-
 	if (!iwl_is_ready(priv)) {
 		IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
 		goto out;
@@ -2812,42 +2855,6 @@ out:
 }
 EXPORT_SYMBOL(iwl_mac_config);
 
-int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
-			 struct ieee80211_tx_queue_stats *stats)
-{
-	struct iwl_priv *priv = hw->priv;
-	int i, avail;
-	struct iwl_tx_queue *txq;
-	struct iwl_queue *q;
-	unsigned long flags;
-
-	IWL_DEBUG_MAC80211(priv, "enter\n");
-
-	if (!iwl_is_ready_rf(priv)) {
-		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
-		return -EIO;
-	}
-
-	spin_lock_irqsave(&priv->lock, flags);
-
-	for (i = 0; i < AC_NUM; i++) {
-		txq = &priv->txq[i];
-		q = &txq->q;
-		avail = iwl_queue_space(q);
-
-		stats[i].len = q->n_window - avail;
-		stats[i].limit = q->n_window - q->high_mark;
-		stats[i].count = q->n_window;
-
-	}
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	IWL_DEBUG_MAC80211(priv, "leave\n");
-
-	return 0;
-}
-EXPORT_SYMBOL(iwl_mac_get_tx_stats);
-
 void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
 {
 	struct iwl_priv *priv = hw->priv;
@@ -3197,6 +3204,206 @@ void iwl_update_stats(struct iwl_priv *p
 EXPORT_SYMBOL(iwl_update_stats);
 #endif
 
+const static char *get_csr_string(int cmd)
+{
+	switch (cmd) {
+		IWL_CMD(CSR_HW_IF_CONFIG_REG);
+		IWL_CMD(CSR_INT_COALESCING);
+		IWL_CMD(CSR_INT);
+		IWL_CMD(CSR_INT_MASK);
+		IWL_CMD(CSR_FH_INT_STATUS);
+		IWL_CMD(CSR_GPIO_IN);
+		IWL_CMD(CSR_RESET);
+		IWL_CMD(CSR_GP_CNTRL);
+		IWL_CMD(CSR_HW_REV);
+		IWL_CMD(CSR_EEPROM_REG);
+		IWL_CMD(CSR_EEPROM_GP);
+		IWL_CMD(CSR_OTP_GP_REG);
+		IWL_CMD(CSR_GIO_REG);
+		IWL_CMD(CSR_GP_UCODE_REG);
+		IWL_CMD(CSR_GP_DRIVER_REG);
+		IWL_CMD(CSR_UCODE_DRV_GP1);
+		IWL_CMD(CSR_UCODE_DRV_GP2);
+		IWL_CMD(CSR_LED_REG);
+		IWL_CMD(CSR_DRAM_INT_TBL_REG);
+		IWL_CMD(CSR_GIO_CHICKEN_BITS);
+		IWL_CMD(CSR_ANA_PLL_CFG);
+		IWL_CMD(CSR_HW_REV_WA_REG);
+		IWL_CMD(CSR_DBG_HPET_MEM_REG);
+	default:
+		return "UNKNOWN";
+
+	}
+}
+
+void iwl_dump_csr(struct iwl_priv *priv)
+{
+	int i;
+	u32 csr_tbl[] = {
+		CSR_HW_IF_CONFIG_REG,
+		CSR_INT_COALESCING,
+		CSR_INT,
+		CSR_INT_MASK,
+		CSR_FH_INT_STATUS,
+		CSR_GPIO_IN,
+		CSR_RESET,
+		CSR_GP_CNTRL,
+		CSR_HW_REV,
+		CSR_EEPROM_REG,
+		CSR_EEPROM_GP,
+		CSR_OTP_GP_REG,
+		CSR_GIO_REG,
+		CSR_GP_UCODE_REG,
+		CSR_GP_DRIVER_REG,
+		CSR_UCODE_DRV_GP1,
+		CSR_UCODE_DRV_GP2,
+		CSR_LED_REG,
+		CSR_DRAM_INT_TBL_REG,
+		CSR_GIO_CHICKEN_BITS,
+		CSR_ANA_PLL_CFG,
+		CSR_HW_REV_WA_REG,
+		CSR_DBG_HPET_MEM_REG
+	};
+	IWL_ERR(priv, "CSR values:\n");
+	IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is "
+		"CSR_INT_PERIODIC_REG)\n");
+	for (i = 0; i <  ARRAY_SIZE(csr_tbl); i++) {
+		IWL_ERR(priv, "  %25s: 0X%08x\n",
+			get_csr_string(csr_tbl[i]),
+			iwl_read32(priv, csr_tbl[i]));
+	}
+}
+EXPORT_SYMBOL(iwl_dump_csr);
+
+const static char *get_fh_string(int cmd)
+{
+	switch (cmd) {
+		IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
+		IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
+		IWL_CMD(FH_RSCSR_CHNL0_WPTR);
+		IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
+		IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
+		IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
+		IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
+		IWL_CMD(FH_TSSR_TX_STATUS_REG);
+		IWL_CMD(FH_TSSR_TX_ERROR_REG);
+	default:
+		return "UNKNOWN";
+
+	}
+}
+
+int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
+{
+	int i;
+#ifdef CONFIG_IWLWIFI_DEBUG
+	int pos = 0;
+	size_t bufsz = 0;
+#endif
+	u32 fh_tbl[] = {
+		FH_RSCSR_CHNL0_STTS_WPTR_REG,
+		FH_RSCSR_CHNL0_RBDCB_BASE_REG,
+		FH_RSCSR_CHNL0_WPTR,
+		FH_MEM_RCSR_CHNL0_CONFIG_REG,
+		FH_MEM_RSSR_SHARED_CTRL_REG,
+		FH_MEM_RSSR_RX_STATUS_REG,
+		FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
+		FH_TSSR_TX_STATUS_REG,
+		FH_TSSR_TX_ERROR_REG
+	};
+#ifdef CONFIG_IWLWIFI_DEBUG
+	if (display) {
+		bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
+		*buf = kmalloc(bufsz, GFP_KERNEL);
+		if (!*buf)
+			return -ENOMEM;
+		pos += scnprintf(*buf + pos, bufsz - pos,
+				"FH register values:\n");
+		for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
+			pos += scnprintf(*buf + pos, bufsz - pos,
+				"  %34s: 0X%08x\n",
+				get_fh_string(fh_tbl[i]),
+				iwl_read_direct32(priv, fh_tbl[i]));
+		}
+		return pos;
+	}
+#endif
+	IWL_ERR(priv, "FH register values:\n");
+	for (i = 0; i <  ARRAY_SIZE(fh_tbl); i++) {
+		IWL_ERR(priv, "  %34s: 0X%08x\n",
+			get_fh_string(fh_tbl[i]),
+			iwl_read_direct32(priv, fh_tbl[i]));
+	}
+	return 0;
+}
+EXPORT_SYMBOL(iwl_dump_fh);
+
+static void iwl_force_rf_reset(struct iwl_priv *priv)
+{
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		return;
+
+	if (!iwl_is_associated(priv)) {
+		IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n");
+		return;
+	}
+	/*
+	 * There is no easy and better way to force reset the radio,
+	 * the only known method is switching channel which will force to
+	 * reset and tune the radio.
+	 * Use internal short scan (single channel) operation to should
+	 * achieve this objective.
+	 * Driver should reset the radio when number of consecutive missed
+	 * beacon, or any other uCode error condition detected.
+	 */
+	IWL_DEBUG_INFO(priv, "perform radio reset.\n");
+	iwl_internal_short_hw_scan(priv);
+}
+
+
+int iwl_force_reset(struct iwl_priv *priv, int mode)
+{
+	struct iwl_force_reset *force_reset;
+
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		return -EINVAL;
+
+	if (mode >= IWL_MAX_FORCE_RESET) {
+		IWL_DEBUG_INFO(priv, "invalid reset request.\n");
+		return -EINVAL;
+	}
+	force_reset = &priv->force_reset[mode];
+	force_reset->reset_request_count++;
+	if (force_reset->last_force_reset_jiffies &&
+	    time_after(force_reset->last_force_reset_jiffies +
+	    force_reset->reset_duration, jiffies)) {
+		IWL_DEBUG_INFO(priv, "force reset rejected\n");
+		force_reset->reset_reject_count++;
+		return -EAGAIN;
+	}
+	force_reset->reset_success_count++;
+	force_reset->last_force_reset_jiffies = jiffies;
+	IWL_DEBUG_INFO(priv, "perform force reset (%d)\n", mode);
+	switch (mode) {
+	case IWL_RF_RESET:
+		iwl_force_rf_reset(priv);
+		break;
+	case IWL_FW_RESET:
+		IWL_ERR(priv, "On demand firmware reload\n");
+		/* Set the FW error flag -- cleared on iwl_down */
+		set_bit(STATUS_FW_ERROR, &priv->status);
+		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);
+		queue_work(priv->workqueue, &priv->restart);
+		break;
+	}
+	return 0;
+}
+
 #ifdef CONFIG_PM
 
 int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-core.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-core.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-core.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,8 +63,6 @@
 #ifndef __iwl_core_h__
 #define __iwl_core_h__
 
-#include <generated/utsrelease.h>
-
 /************************
  * forward declarations *
  ************************/
@@ -72,8 +70,8 @@ struct iwl_host_cmd;
 struct iwl_cmd;
 
 
-#define IWLWIFI_VERSION UTS_RELEASE "-k"
-#define DRV_COPYRIGHT	"Copyright(c) 2003-2009 Intel Corporation"
+#define IWLWIFI_VERSION "in-tree:"
+#define DRV_COPYRIGHT	"Copyright(c) 2003-2010 Intel Corporation"
 #define DRV_AUTHOR     "<ilw@linux.intel.com>"
 
 #define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -119,6 +117,7 @@ struct iwl_apm_ops {
 struct iwl_temp_ops {
 	void (*temperature)(struct iwl_priv *priv);
 	void (*set_ct_kill)(struct iwl_priv *priv);
+	void (*set_calib_version)(struct iwl_priv *priv);
 };
 
 struct iwl_ucode_ops {
@@ -169,8 +168,11 @@ struct iwl_lib_ops {
 	int (*is_valid_rtc_data_addr)(u32 addr);
 	/* 1st ucode load */
 	int (*load_ucode)(struct iwl_priv *priv);
-	void (*dump_nic_event_log)(struct iwl_priv *priv, bool full_log);
+	int (*dump_nic_event_log)(struct iwl_priv *priv,
+				  bool full_log, char **buf, bool display);
 	void (*dump_nic_error_log)(struct iwl_priv *priv);
+	void (*dump_csr)(struct iwl_priv *priv);
+	int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display);
 	int (*set_channel_switch)(struct iwl_priv *priv, u16 channel);
 	/* power management */
 	struct iwl_apm_ops apm_ops;
@@ -187,6 +189,8 @@ struct iwl_lib_ops {
 
 	/* temperature */
 	struct iwl_temp_ops temp_ops;
+	/* station management */
+	void (*add_bcast_station)(struct iwl_priv *priv);
 };
 
 struct iwl_led_ops {
@@ -230,8 +234,9 @@ struct iwl_mod_params {
  * @chain_noise_num_beacons: number of beacons used to compute chain noise
  * @adv_thermal_throttle: support advance thermal throttle
  * @support_ct_kill_exit: support ct kill exit condition
- * @sm_ps_mode: spatial multiplexing power save mode
  * @support_wimax_coexist: support wimax/wifi co-exist
+ * @plcp_delta_threshold: plcp error rate threshold used to trigger
+ *	radio tuning when there is a high receiving plcp error rate
  *
  * We enable the driver to be backward compatible wrt API version. The
  * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -287,8 +292,9 @@ struct iwl_cfg {
 	const bool supports_idle;
 	bool adv_thermal_throttle;
 	bool support_ct_kill_exit;
-	u8 sm_ps_mode;
 	const bool support_wimax_coexist;
+	u8 plcp_delta_threshold;
+	s32 chain_noise_scale;
 };
 
 /***************************
@@ -332,13 +338,11 @@ int iwl_mac_beacon_update(struct ieee802
 int iwl_commit_rxon(struct iwl_priv *priv);
 int iwl_set_mode(struct iwl_priv *priv, int mode);
 int iwl_mac_add_interface(struct ieee80211_hw *hw,
-				 struct ieee80211_if_init_conf *conf);
+			  struct ieee80211_vif *vif);
 void iwl_mac_remove_interface(struct ieee80211_hw *hw,
-				 struct ieee80211_if_init_conf *conf);
+			      struct ieee80211_vif *vif);
 int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
 void iwl_config_ap(struct iwl_priv *priv);
-int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
-			 struct ieee80211_tx_queue_stats *stats);
 void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
 int iwl_alloc_txq_mem(struct iwl_priv *priv);
 void iwl_free_txq_mem(struct iwl_priv *priv);
@@ -411,13 +415,13 @@ void iwl_rx_queue_free(struct iwl_priv *
 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,
+void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
 				  struct iwl_rx_queue *q);
 void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
 void iwl_rx_replenish(struct iwl_priv *priv);
 void iwl_rx_replenish_now(struct iwl_priv *priv);
 int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
-int iwl_rx_queue_restock(struct iwl_priv *priv);
+void iwl_rx_queue_restock(struct iwl_priv *priv);
 int iwl_rx_queue_space(const struct iwl_rx_queue *q);
 void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority);
 void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
@@ -425,6 +429,8 @@ int iwl_tx_queue_reclaim(struct iwl_priv
 /* Handlers */
 void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
 			       struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
+					  struct iwl_rx_mem_buffer *rxb);
 void iwl_rx_statistics(struct iwl_priv *priv,
 			      struct iwl_rx_mem_buffer *rxb);
 void iwl_reply_statistics(struct iwl_priv *priv,
@@ -436,7 +442,8 @@ void iwl_rx_csa(struct iwl_priv *priv, s
 /*****************************************************
 * TX
 ******************************************************/
-int iwl_txq_ctx_reset(struct iwl_priv *priv);
+int iwl_txq_ctx_alloc(struct iwl_priv *priv);
+void 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,
@@ -445,11 +452,13 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 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);
 void iwl_free_tfds_in_queue(struct iwl_priv *priv,
 			    int sta_id, int tid, int freed);
+void 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_reset(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);
@@ -497,6 +506,8 @@ 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_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
+void iwl_internal_short_hw_scan(struct iwl_priv *priv);
+int iwl_force_reset(struct iwl_priv *priv, int mode);
 u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
 		       const u8 *ie, int ie_len, int left);
 void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
@@ -527,14 +538,6 @@ int iwl_send_calib_results(struct iwl_pr
 int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
 void iwl_calib_free_results(struct iwl_priv *priv);
 
-/*******************************************************************************
- * Spectrum Measureemtns in  iwl-spectrum.c
- ******************************************************************************/
-#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) {}
-#endif
 /*****************************************************
  *   S e n d i n g     H o s t     C o m m a n d s   *
  *****************************************************/
@@ -583,7 +586,10 @@ int iwl_pci_resume(struct pci_dev *pdev)
 *  Error Handling Debugging
 ******************************************************/
 void iwl_dump_nic_error_log(struct iwl_priv *priv);
-void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log);
+int iwl_dump_nic_event_log(struct iwl_priv *priv,
+			   bool full_log, char **buf, bool display);
+void iwl_dump_csr(struct iwl_priv *priv);
+int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
 #ifdef CONFIG_IWLWIFI_DEBUG
 void iwl_print_rx_config_cmd(struct iwl_priv *priv);
 #else
@@ -603,7 +609,7 @@ void iwlcore_free_geos(struct iwl_priv *
 /*************** DRIVER STATUS FUNCTIONS   *****/
 
 #define STATUS_HCMD_ACTIVE	0	/* host command in progress */
-#define STATUS_HCMD_SYNC_ACTIVE	1	/* sync host command in progress */
+/* 1 is unused (used to be STATUS_HCMD_SYNC_ACTIVE) */
 #define STATUS_INT_ENABLED	2
 #define STATUS_RF_KILL_HW	3
 #define STATUS_CT_KILL		4
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-csr.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-csr.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-csr.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-csr.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -369,7 +369,7 @@
 #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_3x3_HYB	    (0x00000000)
 #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB	    (0x00000001)
 #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA	    (0x00000002)
-
+#define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6	(0x00000004)
 
 /* GIO Chicken Bits (PCI Express bus link power management) */
 #define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX  (0x00800000)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-debugfs.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-debugfs.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-debugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-debugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -26,6 +26,7 @@
  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  *****************************************************************************/
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/debugfs.h>
@@ -41,43 +42,28 @@
 #include "iwl-calib.h"
 
 /* create and remove of files */
-#define DEBUGFS_ADD_DIR(name, parent) do {                              \
-	dbgfs->dir_##name = debugfs_create_dir(#name, parent);          \
-	if (!(dbgfs->dir_##name))                                       \
-		goto err; 						\
-} while (0)
-
-#define DEBUGFS_ADD_FILE(name, parent, mode) do {                       \
-	dbgfs->dbgfs_##parent##_files.file_##name =                     \
-	debugfs_create_file(#name, mode,                                \
-				dbgfs->dir_##parent, priv,              \
-				&iwl_dbgfs_##name##_ops);               \
-	if (!(dbgfs->dbgfs_##parent##_files.file_##name))               \
-		goto err;                                               \
+#define DEBUGFS_ADD_FILE(name, parent, mode) do {			\
+	if (!debugfs_create_file(#name, mode, parent, priv,		\
+				 &iwl_dbgfs_##name##_ops))		\
+		goto err;						\
 } while (0)
 
-#define DEBUGFS_ADD_BOOL(name, parent, ptr) do {                        \
-	dbgfs->dbgfs_##parent##_files.file_##name =                     \
-	debugfs_create_bool(#name, S_IWUSR | S_IRUSR,                   \
-			    dbgfs->dir_##parent, ptr);                  \
-	if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name)		\
-			|| !dbgfs->dbgfs_##parent##_files.file_##name)	\
-		goto err;                                               \
+#define DEBUGFS_ADD_BOOL(name, parent, ptr) do {			\
+	struct dentry *__tmp;						\
+	__tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR,		\
+				    parent, ptr);			\
+	if (IS_ERR(__tmp) || !__tmp)					\
+		goto err;						\
 } while (0)
 
-#define DEBUGFS_ADD_X32(name, parent, ptr) do {                        \
-	dbgfs->dbgfs_##parent##_files.file_##name =                     \
-	debugfs_create_x32(#name, S_IRUSR, dbgfs->dir_##parent, ptr);   \
-	if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name)		\
-			|| !dbgfs->dbgfs_##parent##_files.file_##name)	\
-		goto err;                                               \
+#define DEBUGFS_ADD_X32(name, parent, ptr) do {				\
+	struct dentry *__tmp;						\
+	__tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR,		\
+				   parent, ptr);			\
+	if (IS_ERR(__tmp) || !__tmp)					\
+		goto err;						\
 } while (0)
 
-#define DEBUGFS_REMOVE(name)  do {              \
-	debugfs_remove(name);                   \
-	name = NULL;                            \
-} while (0);
-
 /* file operation */
 #define DEBUGFS_READ_FUNC(name)                                         \
 static ssize_t iwl_dbgfs_##name##_read(struct file *file,               \
@@ -125,7 +111,7 @@ static ssize_t iwl_dbgfs_tx_statistics_r
 						char __user *user_buf,
 						size_t count, loff_t *ppos) {
 
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	char *buf;
 	int pos = 0;
 
@@ -184,7 +170,7 @@ static ssize_t iwl_dbgfs_rx_statistics_r
 						char __user *user_buf,
 						size_t count, loff_t *ppos) {
 
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	char *buf;
 	int pos = 0;
 	int cnt;
@@ -232,28 +218,28 @@ static ssize_t iwl_dbgfs_sram_read(struc
 	ssize_t ret;
 	int i;
 	int pos = 0;
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	size_t bufsz;
 
 	/* default is to dump the entire data segment */
-	if (!priv->dbgfs->sram_offset && !priv->dbgfs->sram_len) {
-		priv->dbgfs->sram_offset = 0x800000;
+	if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
+		priv->dbgfs_sram_offset = 0x800000;
 		if (priv->ucode_type == UCODE_INIT)
-			priv->dbgfs->sram_len = priv->ucode_init_data.len;
+			priv->dbgfs_sram_len = priv->ucode_init_data.len;
 		else
-			priv->dbgfs->sram_len = priv->ucode_data.len;
+			priv->dbgfs_sram_len = priv->ucode_data.len;
 	}
-	bufsz =  30 + priv->dbgfs->sram_len * sizeof(char) * 10;
+	bufsz =  30 + priv->dbgfs_sram_len * sizeof(char) * 10;
 	buf = kmalloc(bufsz, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 	pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
-			priv->dbgfs->sram_len);
+			priv->dbgfs_sram_len);
 	pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
-			priv->dbgfs->sram_offset);
-	for (i = priv->dbgfs->sram_len; i > 0; i -= 4) {
-		val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \
-					priv->dbgfs->sram_len - i);
+			priv->dbgfs_sram_offset);
+	for (i = priv->dbgfs_sram_len; i > 0; i -= 4) {
+		val = iwl_read_targ_mem(priv, priv->dbgfs_sram_offset + \
+					priv->dbgfs_sram_len - i);
 		if (i < 4) {
 			switch (i) {
 			case 1:
@@ -293,11 +279,11 @@ static ssize_t iwl_dbgfs_sram_write(stru
 		return -EFAULT;
 
 	if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
-		priv->dbgfs->sram_offset = offset;
-		priv->dbgfs->sram_len = len;
+		priv->dbgfs_sram_offset = offset;
+		priv->dbgfs_sram_len = len;
 	} else {
-		priv->dbgfs->sram_offset = 0;
-		priv->dbgfs->sram_len = 0;
+		priv->dbgfs_sram_offset = 0;
+		priv->dbgfs_sram_len = 0;
 	}
 
 	return count;
@@ -306,7 +292,7 @@ static ssize_t iwl_dbgfs_sram_write(stru
 static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
 					size_t count, loff_t *ppos)
 {
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	struct iwl_station_entry *station;
 	int max_sta = priv->hw_params.max_stations;
 	char *buf;
@@ -376,7 +362,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct
 				       loff_t *ppos)
 {
 	ssize_t ret;
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	int pos = 0, ofs = 0, buf_size = 0;
 	const u8 *ptr;
 	char *buf;
@@ -420,6 +406,24 @@ static ssize_t iwl_dbgfs_nvm_read(struct
 	return ret;
 }
 
+static ssize_t iwl_dbgfs_log_event_read(struct file *file,
+					 char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = file->private_data;
+	char *buf;
+	int pos = 0;
+	ssize_t ret = -ENOMEM;
+
+	ret = pos = priv->cfg->ops->lib->dump_nic_event_log(
+					priv, true, &buf, true);
+	if (buf) {
+		ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+		kfree(buf);
+	}
+	return ret;
+}
+
 static ssize_t iwl_dbgfs_log_event_write(struct file *file,
 					const char __user *user_buf,
 					size_t count, loff_t *ppos)
@@ -436,7 +440,8 @@ static ssize_t iwl_dbgfs_log_event_write
 	if (sscanf(buf, "%d", &event_log_flag) != 1)
 		return -EFAULT;
 	if (event_log_flag == 1)
-		priv->cfg->ops->lib->dump_nic_event_log(priv, true);
+		priv->cfg->ops->lib->dump_nic_event_log(priv, true,
+							NULL, false);
 
 	return count;
 }
@@ -446,7 +451,7 @@ static ssize_t iwl_dbgfs_log_event_write
 static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
 				       size_t count, loff_t *ppos)
 {
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	struct ieee80211_channel *channels = NULL;
 	const struct ieee80211_supported_band *supp_band = NULL;
 	int pos = 0, i, bufsz = PAGE_SIZE;
@@ -519,15 +524,13 @@ static ssize_t iwl_dbgfs_status_read(str
 						char __user *user_buf,
 						size_t count, loff_t *ppos) {
 
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *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",
@@ -567,7 +570,7 @@ static ssize_t iwl_dbgfs_interrupt_read(
 					char __user *user_buf,
 					size_t count, loff_t *ppos) {
 
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	int pos = 0;
 	int cnt = 0;
 	char *buf;
@@ -654,7 +657,7 @@ static ssize_t iwl_dbgfs_interrupt_write
 static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
 				       size_t count, loff_t *ppos)
 {
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	int pos = 0, i;
 	char buf[256];
 	const size_t bufsz = sizeof(buf);
@@ -677,7 +680,7 @@ static ssize_t iwl_dbgfs_qos_read(struct
 static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
 				  size_t count, loff_t *ppos)
 {
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	int pos = 0;
 	char buf[256];
 	const size_t bufsz = sizeof(buf);
@@ -703,7 +706,7 @@ static ssize_t iwl_dbgfs_thermal_throttl
 				char __user *user_buf,
 				size_t count, loff_t *ppos)
 {
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 	struct iwl_tt_restriction *restriction;
 	char buf[100];
@@ -763,7 +766,7 @@ static ssize_t iwl_dbgfs_disable_ht40_re
 					 char __user *user_buf,
 					 size_t count, loff_t *ppos)
 {
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	char buf[100];
 	int pos = 0;
 	const size_t bufsz = sizeof(buf);
@@ -811,7 +814,9 @@ static ssize_t iwl_dbgfs_sleep_level_ove
 
 	priv->power_data.debug_sleep_level_override = value;
 
+	mutex_lock(&priv->mutex);
 	iwl_power_update_mode(priv, true);
+	mutex_unlock(&priv->mutex);
 
 	return count;
 }
@@ -820,7 +825,7 @@ static ssize_t iwl_dbgfs_sleep_level_ove
 						   char __user *user_buf,
 						   size_t count, loff_t *ppos)
 {
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	char buf[10];
 	int pos, value;
 	const size_t bufsz = sizeof(buf);
@@ -838,7 +843,7 @@ static ssize_t iwl_dbgfs_current_sleep_c
 						    char __user *user_buf,
 						    size_t count, loff_t *ppos)
 {
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	char buf[200];
 	int pos = 0, i;
 	const size_t bufsz = sizeof(buf);
@@ -859,7 +864,7 @@ static ssize_t iwl_dbgfs_current_sleep_c
 }
 
 DEBUGFS_READ_WRITE_FILE_OPS(sram);
-DEBUGFS_WRITE_FILE_OPS(log_event);
+DEBUGFS_READ_WRITE_FILE_OPS(log_event);
 DEBUGFS_READ_FILE_OPS(nvm);
 DEBUGFS_READ_FILE_OPS(stations);
 DEBUGFS_READ_FILE_OPS(channels);
@@ -976,7 +981,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(s
 						char __user *user_buf,
 						size_t count, loff_t *ppos) {
 
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	struct iwl_tx_queue *txq;
 	struct iwl_queue *q;
 	char *buf;
@@ -1022,7 +1027,7 @@ static ssize_t iwl_dbgfs_rx_queue_read(s
 						char __user *user_buf,
 						size_t count, loff_t *ppos) {
 
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	struct iwl_rx_queue *rxq = &priv->rxq;
 	char buf[256];
 	int pos = 0;
@@ -1063,36 +1068,33 @@ static int iwl_dbgfs_statistics_flag(str
 	return p;
 }
 
+static const char ucode_stats_header[] =
+	"%-32s     current  acumulative       delta         max\n";
+static const char ucode_stats_short_format[] =
+	"  %-30s %10u\n";
+static const char ucode_stats_format[] =
+	"  %-30s %10u  %10u  %10u  %10u\n";
 
 static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
 					char __user *user_buf,
 					size_t count, loff_t *ppos)
 {
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	int pos = 0;
 	char *buf;
-	int bufsz = sizeof(struct statistics_rx_phy) * 20 +
-		sizeof(struct statistics_rx_non_phy) * 20 +
-		sizeof(struct statistics_rx_ht_phy) * 20 + 400;
+	int bufsz = sizeof(struct statistics_rx_phy) * 40 +
+		sizeof(struct statistics_rx_non_phy) * 40 +
+		sizeof(struct statistics_rx_ht_phy) * 40 + 400;
 	ssize_t ret;
-	struct statistics_rx_phy *ofdm, *accum_ofdm;
-	struct statistics_rx_phy *cck, *accum_cck;
+	struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
+	struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
 	struct statistics_rx_non_phy *general, *accum_general;
-	struct statistics_rx_ht_phy *ht, *accum_ht;
+	struct statistics_rx_non_phy *delta_general, *max_general;
+	struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
 
 	if (!iwl_is_alive(priv))
 		return -EAGAIN;
 
-	/* make request to uCode to retrieve statistics information */
-	mutex_lock(&priv->mutex);
-	ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
-	mutex_unlock(&priv->mutex);
-
-	if (ret) {
-		IWL_ERR(priv,
-			"Error sending statistics request: %zd\n", ret);
-		return -EAGAIN;
-	}
 	buf = kzalloc(bufsz, GFP_KERNEL);
 	if (!buf) {
 		IWL_ERR(priv, "Can not allocate Buffer\n");
@@ -1111,264 +1113,401 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_
 	accum_cck = &priv->accum_statistics.rx.cck;
 	accum_general = &priv->accum_statistics.rx.general;
 	accum_ht = &priv->accum_statistics.rx.ofdm_ht;
+	delta_ofdm = &priv->delta_statistics.rx.ofdm;
+	delta_cck = &priv->delta_statistics.rx.cck;
+	delta_general = &priv->delta_statistics.rx.general;
+	delta_ht = &priv->delta_statistics.rx.ofdm_ht;
+	max_ofdm = &priv->max_delta.rx.ofdm;
+	max_cck = &priv->max_delta.rx.cck;
+	max_general = &priv->max_delta.rx.general;
+	max_ht = &priv->max_delta.rx.ofdm_ht;
+
 	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
-	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM:\n");
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"\t\t\tcurrent\t\t\taccumulative\n");
-	pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(ofdm->ina_cnt), accum_ofdm->ina_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err);
-	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "overrun_err:\t\t%u\t\t\t%u\n",
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
+			 "Statistics_Rx - OFDM:");
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "ina_cnt:", le32_to_cpu(ofdm->ina_cnt),
+			 accum_ofdm->ina_cnt,
+			 delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "fina_cnt:",
+			 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
+			 delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "plcp_err:",
+			 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
+			 delta_ofdm->plcp_err, max_ofdm->plcp_err);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "crc32_err:",
+			 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
+			 delta_ofdm->crc32_err, max_ofdm->crc32_err);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "overrun_err:",
 			 le32_to_cpu(ofdm->overrun_err),
-			 accum_ofdm->overrun_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "early_overrun_err:\t%u\t\t\t%u\n",
+			 accum_ofdm->overrun_err,
+			 delta_ofdm->overrun_err, max_ofdm->overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "early_overrun_err:",
 			 le32_to_cpu(ofdm->early_overrun_err),
-			 accum_ofdm->early_overrun_err);
-	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n",
+			 accum_ofdm->early_overrun_err,
+			 delta_ofdm->early_overrun_err,
+			 max_ofdm->early_overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "crc32_good:",
 			 le32_to_cpu(ofdm->crc32_good),
-			 accum_ofdm->crc32_good);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "false_alarm_cnt:\t%u\t\t\t%u\n",
+			 accum_ofdm->crc32_good,
+			 delta_ofdm->crc32_good, max_ofdm->crc32_good);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "false_alarm_cnt:",
 			 le32_to_cpu(ofdm->false_alarm_cnt),
-			 accum_ofdm->false_alarm_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "fina_sync_err_cnt:\t%u\t\t\t%u\n",
+			 accum_ofdm->false_alarm_cnt,
+			 delta_ofdm->false_alarm_cnt,
+			 max_ofdm->false_alarm_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "fina_sync_err_cnt:",
 			 le32_to_cpu(ofdm->fina_sync_err_cnt),
-			 accum_ofdm->fina_sync_err_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "sfd_timeout:\t\t%u\t\t\t%u\n",
+			 accum_ofdm->fina_sync_err_cnt,
+			 delta_ofdm->fina_sync_err_cnt,
+			 max_ofdm->fina_sync_err_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "sfd_timeout:",
 			 le32_to_cpu(ofdm->sfd_timeout),
-			 accum_ofdm->sfd_timeout);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "fina_timeout:\t\t%u\t\t\t%u\n",
+			 accum_ofdm->sfd_timeout,
+			 delta_ofdm->sfd_timeout,
+			 max_ofdm->sfd_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "fina_timeout:",
 			 le32_to_cpu(ofdm->fina_timeout),
-			 accum_ofdm->fina_timeout);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "unresponded_rts:\t%u\t\t\t%u\n",
+			 accum_ofdm->fina_timeout,
+			 delta_ofdm->fina_timeout,
+			 max_ofdm->fina_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "unresponded_rts:",
 			 le32_to_cpu(ofdm->unresponded_rts),
-			 accum_ofdm->unresponded_rts);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n",
+			 accum_ofdm->unresponded_rts,
+			 delta_ofdm->unresponded_rts,
+			 max_ofdm->unresponded_rts);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			"rxe_frame_lmt_ovrun:",
 			 le32_to_cpu(ofdm->rxe_frame_limit_overrun),
-			 accum_ofdm->rxe_frame_limit_overrun);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "sent_ack_cnt:\t\t%u\t\t\t%u\n",
+			 accum_ofdm->rxe_frame_limit_overrun,
+			 delta_ofdm->rxe_frame_limit_overrun,
+			 max_ofdm->rxe_frame_limit_overrun);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "sent_ack_cnt:",
 			 le32_to_cpu(ofdm->sent_ack_cnt),
-			 accum_ofdm->sent_ack_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "sent_cts_cnt:\t\t%u\t\t\t%u\n",
+			 accum_ofdm->sent_ack_cnt,
+			 delta_ofdm->sent_ack_cnt,
+			 max_ofdm->sent_ack_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "sent_cts_cnt:",
 			 le32_to_cpu(ofdm->sent_cts_cnt),
-			 accum_ofdm->sent_cts_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n",
+			 accum_ofdm->sent_cts_cnt,
+			 delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "sent_ba_rsp_cnt:",
 			 le32_to_cpu(ofdm->sent_ba_rsp_cnt),
-			 accum_ofdm->sent_ba_rsp_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "dsp_self_kill:\t\t%u\t\t\t%u\n",
+			 accum_ofdm->sent_ba_rsp_cnt,
+			 delta_ofdm->sent_ba_rsp_cnt,
+			 max_ofdm->sent_ba_rsp_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "dsp_self_kill:",
 			 le32_to_cpu(ofdm->dsp_self_kill),
-			 accum_ofdm->dsp_self_kill);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "mh_format_err:\t\t%u\t\t\t%u\n",
+			 accum_ofdm->dsp_self_kill,
+			 delta_ofdm->dsp_self_kill,
+			 max_ofdm->dsp_self_kill);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "mh_format_err:",
 			 le32_to_cpu(ofdm->mh_format_err),
-			 accum_ofdm->mh_format_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n",
+			 accum_ofdm->mh_format_err,
+			 delta_ofdm->mh_format_err,
+			 max_ofdm->mh_format_err);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "re_acq_main_rssi_sum:",
 			 le32_to_cpu(ofdm->re_acq_main_rssi_sum),
-			 accum_ofdm->re_acq_main_rssi_sum);
+			 accum_ofdm->re_acq_main_rssi_sum,
+			 delta_ofdm->re_acq_main_rssi_sum,
+			max_ofdm->re_acq_main_rssi_sum);
 
-	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - CCK:\n");
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"\t\t\tcurrent\t\t\taccumulative\n");
-	pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err);
-	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "overrun_err:\t\t%u\t\t\t%u\n",
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
+			 "Statistics_Rx - CCK:");
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "ina_cnt:",
+			 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
+			 delta_cck->ina_cnt, max_cck->ina_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "fina_cnt:",
+			 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
+			 delta_cck->fina_cnt, max_cck->fina_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "plcp_err:",
+			 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
+			 delta_cck->plcp_err, max_cck->plcp_err);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "crc32_err:",
+			 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
+			 delta_cck->crc32_err, max_cck->crc32_err);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "overrun_err:",
 			 le32_to_cpu(cck->overrun_err),
-			 accum_cck->overrun_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "early_overrun_err:\t%u\t\t\t%u\n",
+			 accum_cck->overrun_err,
+			 delta_cck->overrun_err, max_cck->overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "early_overrun_err:",
 			 le32_to_cpu(cck->early_overrun_err),
-			 accum_cck->early_overrun_err);
-	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "false_alarm_cnt:\t%u\t\t\t%u\n",
+			 accum_cck->early_overrun_err,
+			 delta_cck->early_overrun_err,
+			 max_cck->early_overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "crc32_good:",
+			 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
+			 delta_cck->crc32_good,
+			 max_cck->crc32_good);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "false_alarm_cnt:",
 			 le32_to_cpu(cck->false_alarm_cnt),
-			 accum_cck->false_alarm_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "fina_sync_err_cnt:\t%u\t\t\t%u\n",
+			 accum_cck->false_alarm_cnt,
+			 delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "fina_sync_err_cnt:",
 			 le32_to_cpu(cck->fina_sync_err_cnt),
-			 accum_cck->fina_sync_err_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "sfd_timeout:\t\t%u\t\t\t%u\n",
+			 accum_cck->fina_sync_err_cnt,
+			 delta_cck->fina_sync_err_cnt,
+			 max_cck->fina_sync_err_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "sfd_timeout:",
 			 le32_to_cpu(cck->sfd_timeout),
-			 accum_cck->sfd_timeout);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "fina_timeout:\t\t%u\t\t\t%u\n",
+			 accum_cck->sfd_timeout,
+			 delta_cck->sfd_timeout, max_cck->sfd_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "fina_timeout:",
 			 le32_to_cpu(cck->fina_timeout),
-			 accum_cck->fina_timeout);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "unresponded_rts:\t%u\t\t\t%u\n",
+			 accum_cck->fina_timeout,
+			 delta_cck->fina_timeout, max_cck->fina_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "unresponded_rts:",
 			 le32_to_cpu(cck->unresponded_rts),
-			 accum_cck->unresponded_rts);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n",
+			 accum_cck->unresponded_rts,
+			 delta_cck->unresponded_rts,
+			 max_cck->unresponded_rts);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			"rxe_frame_lmt_ovrun:",
 			 le32_to_cpu(cck->rxe_frame_limit_overrun),
-			 accum_cck->rxe_frame_limit_overrun);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "sent_ack_cnt:\t\t%u\t\t\t%u\n",
+			 accum_cck->rxe_frame_limit_overrun,
+			 delta_cck->rxe_frame_limit_overrun,
+			 max_cck->rxe_frame_limit_overrun);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "sent_ack_cnt:",
 			 le32_to_cpu(cck->sent_ack_cnt),
-			 accum_cck->sent_ack_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "sent_cts_cnt:\t\t%u\t\t\t%u\n",
+			 accum_cck->sent_ack_cnt,
+			 delta_cck->sent_ack_cnt,
+			 max_cck->sent_ack_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "sent_cts_cnt:",
 			 le32_to_cpu(cck->sent_cts_cnt),
-			 accum_cck->sent_cts_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n",
+			 accum_cck->sent_cts_cnt,
+			 delta_cck->sent_cts_cnt,
+			 max_cck->sent_cts_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "sent_ba_rsp_cnt:",
 			 le32_to_cpu(cck->sent_ba_rsp_cnt),
-			 accum_cck->sent_ba_rsp_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "dsp_self_kill:\t\t%u\t\t\t%u\n",
+			 accum_cck->sent_ba_rsp_cnt,
+			 delta_cck->sent_ba_rsp_cnt,
+			 max_cck->sent_ba_rsp_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "dsp_self_kill:",
 			 le32_to_cpu(cck->dsp_self_kill),
-			 accum_cck->dsp_self_kill);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "mh_format_err:\t\t%u\t\t\t%u\n",
+			 accum_cck->dsp_self_kill,
+			 delta_cck->dsp_self_kill,
+			 max_cck->dsp_self_kill);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "mh_format_err:",
 			 le32_to_cpu(cck->mh_format_err),
-			 accum_cck->mh_format_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n",
+			 accum_cck->mh_format_err,
+			 delta_cck->mh_format_err, max_cck->mh_format_err);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "re_acq_main_rssi_sum:",
 			 le32_to_cpu(cck->re_acq_main_rssi_sum),
-			 accum_cck->re_acq_main_rssi_sum);
+			 accum_cck->re_acq_main_rssi_sum,
+			 delta_cck->re_acq_main_rssi_sum,
+			 max_cck->re_acq_main_rssi_sum);
 
-	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - GENERAL:\n");
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"\t\t\tcurrent\t\t\taccumulative\n");
-	pos += scnprintf(buf + pos, bufsz - pos, "bogus_cts:\t\t%u\t\t\t%u\n",
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
+			"Statistics_Rx - GENERAL:");
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "bogus_cts:",
 			 le32_to_cpu(general->bogus_cts),
-			 accum_general->bogus_cts);
-	pos += scnprintf(buf + pos, bufsz - pos, "bogus_ack:\t\t%u\t\t\t%u\n",
+			 accum_general->bogus_cts,
+			 delta_general->bogus_cts, max_general->bogus_cts);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "bogus_ack:",
 			 le32_to_cpu(general->bogus_ack),
-			 accum_general->bogus_ack);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "non_bssid_frames:\t%u\t\t\t%u\n",
+			 accum_general->bogus_ack,
+			 delta_general->bogus_ack, max_general->bogus_ack);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "non_bssid_frames:",
 			 le32_to_cpu(general->non_bssid_frames),
-			 accum_general->non_bssid_frames);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "filtered_frames:\t%u\t\t\t%u\n",
+			 accum_general->non_bssid_frames,
+			 delta_general->non_bssid_frames,
+			 max_general->non_bssid_frames);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "filtered_frames:",
 			 le32_to_cpu(general->filtered_frames),
-			 accum_general->filtered_frames);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "non_channel_beacons:\t%u\t\t\t%u\n",
+			 accum_general->filtered_frames,
+			 delta_general->filtered_frames,
+			 max_general->filtered_frames);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "non_channel_beacons:",
 			 le32_to_cpu(general->non_channel_beacons),
-			 accum_general->non_channel_beacons);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "channel_beacons:\t%u\t\t\t%u\n",
+			 accum_general->non_channel_beacons,
+			 delta_general->non_channel_beacons,
+			 max_general->non_channel_beacons);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "channel_beacons:",
 			 le32_to_cpu(general->channel_beacons),
-			 accum_general->channel_beacons);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "num_missed_bcon:\t%u\t\t\t%u\n",
+			 accum_general->channel_beacons,
+			 delta_general->channel_beacons,
+			 max_general->channel_beacons);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "num_missed_bcon:",
 			 le32_to_cpu(general->num_missed_bcon),
-			 accum_general->num_missed_bcon);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"adc_rx_saturation_time:\t%u\t\t\t%u\n",
+			 accum_general->num_missed_bcon,
+			 delta_general->num_missed_bcon,
+			 max_general->num_missed_bcon);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			"adc_rx_saturation_time:",
 			 le32_to_cpu(general->adc_rx_saturation_time),
-			 accum_general->adc_rx_saturation_time);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"ina_detect_search_tm:\t%u\t\t\t%u\n",
+			 accum_general->adc_rx_saturation_time,
+			 delta_general->adc_rx_saturation_time,
+			 max_general->adc_rx_saturation_time);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			"ina_detect_search_tm:",
 			 le32_to_cpu(general->ina_detection_search_time),
-			 accum_general->ina_detection_search_time);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "beacon_silence_rssi_a:\t%u\t\t\t%u\n",
+			 accum_general->ina_detection_search_time,
+			 delta_general->ina_detection_search_time,
+			 max_general->ina_detection_search_time);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "beacon_silence_rssi_a:",
 			 le32_to_cpu(general->beacon_silence_rssi_a),
-			 accum_general->beacon_silence_rssi_a);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "beacon_silence_rssi_b:\t%u\t\t\t%u\n",
+			 accum_general->beacon_silence_rssi_a,
+			 delta_general->beacon_silence_rssi_a,
+			 max_general->beacon_silence_rssi_a);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "beacon_silence_rssi_b:",
 			 le32_to_cpu(general->beacon_silence_rssi_b),
-			 accum_general->beacon_silence_rssi_b);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "beacon_silence_rssi_c:\t%u\t\t\t%u\n",
+			 accum_general->beacon_silence_rssi_b,
+			 delta_general->beacon_silence_rssi_b,
+			 max_general->beacon_silence_rssi_b);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "beacon_silence_rssi_c:",
 			 le32_to_cpu(general->beacon_silence_rssi_c),
-			 accum_general->beacon_silence_rssi_c);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"interference_data_flag:\t%u\t\t\t%u\n",
+			 accum_general->beacon_silence_rssi_c,
+			 delta_general->beacon_silence_rssi_c,
+			 max_general->beacon_silence_rssi_c);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			"interference_data_flag:",
 			 le32_to_cpu(general->interference_data_flag),
-			 accum_general->interference_data_flag);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "channel_load:\t\t%u\t\t\t%u\n",
+			 accum_general->interference_data_flag,
+			 delta_general->interference_data_flag,
+			 max_general->interference_data_flag);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "channel_load:",
 			 le32_to_cpu(general->channel_load),
-			 accum_general->channel_load);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "dsp_false_alarms:\t%u\t\t\t%u\n",
+			 accum_general->channel_load,
+			 delta_general->channel_load,
+			 max_general->channel_load);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "dsp_false_alarms:",
 			 le32_to_cpu(general->dsp_false_alarms),
-			 accum_general->dsp_false_alarms);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "beacon_rssi_a:\t\t%u\t\t\t%u\n",
+			 accum_general->dsp_false_alarms,
+			 delta_general->dsp_false_alarms,
+			 max_general->dsp_false_alarms);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "beacon_rssi_a:",
 			 le32_to_cpu(general->beacon_rssi_a),
-			 accum_general->beacon_rssi_a);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "beacon_rssi_b:\t\t%u\t\t\t%u\n",
+			 accum_general->beacon_rssi_a,
+			 delta_general->beacon_rssi_a,
+			 max_general->beacon_rssi_a);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "beacon_rssi_b:",
 			 le32_to_cpu(general->beacon_rssi_b),
-			 accum_general->beacon_rssi_b);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "beacon_rssi_c:\t\t%u\t\t\t%u\n",
+			 accum_general->beacon_rssi_b,
+			 delta_general->beacon_rssi_b,
+			 max_general->beacon_rssi_b);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "beacon_rssi_c:",
 			 le32_to_cpu(general->beacon_rssi_c),
-			 accum_general->beacon_rssi_c);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "beacon_energy_a:\t%u\t\t\t%u\n",
+			 accum_general->beacon_rssi_c,
+			 delta_general->beacon_rssi_c,
+			 max_general->beacon_rssi_c);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "beacon_energy_a:",
 			 le32_to_cpu(general->beacon_energy_a),
-			 accum_general->beacon_energy_a);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "beacon_energy_b:\t%u\t\t\t%u\n",
+			 accum_general->beacon_energy_a,
+			 delta_general->beacon_energy_a,
+			 max_general->beacon_energy_a);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "beacon_energy_b:",
 			 le32_to_cpu(general->beacon_energy_b),
-			 accum_general->beacon_energy_b);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "beacon_energy_c:\t%u\t\t\t%u\n",
+			 accum_general->beacon_energy_b,
+			 delta_general->beacon_energy_b,
+			 max_general->beacon_energy_b);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "beacon_energy_c:",
 			 le32_to_cpu(general->beacon_energy_c),
-			 accum_general->beacon_energy_c);
+			 accum_general->beacon_energy_c,
+			 delta_general->beacon_energy_c,
+			 max_general->beacon_energy_c);
 
 	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"\t\t\tcurrent\t\t\taccumulative\n");
-	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "overrun_err:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "early_overrun_err:\t%u\t\t\t%u\n",
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
+			"Statistics_Rx - OFDM_HT:");
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "plcp_err:",
+			 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
+			 delta_ht->plcp_err, max_ht->plcp_err);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "overrun_err:",
+			 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
+			 delta_ht->overrun_err, max_ht->overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "early_overrun_err:",
 			 le32_to_cpu(ht->early_overrun_err),
-			 accum_ht->early_overrun_err);
-	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good);
-	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "mh_format_err:\t\t%u\t\t\t%u\n",
+			 accum_ht->early_overrun_err,
+			 delta_ht->early_overrun_err,
+			 max_ht->early_overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "crc32_good:",
+			 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
+			 delta_ht->crc32_good, max_ht->crc32_good);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "crc32_err:",
+			 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
+			 delta_ht->crc32_err, max_ht->crc32_err);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "mh_format_err:",
 			 le32_to_cpu(ht->mh_format_err),
-			 accum_ht->mh_format_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "agg_crc32_good:\t\t%u\t\t\t%u\n",
+			 accum_ht->mh_format_err,
+			 delta_ht->mh_format_err, max_ht->mh_format_err);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "agg_crc32_good:",
 			 le32_to_cpu(ht->agg_crc32_good),
-			 accum_ht->agg_crc32_good);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "agg_mpdu_cnt:\t\t%u\t\t\t%u\n",
+			 accum_ht->agg_crc32_good,
+			 delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "agg_mpdu_cnt:",
 			 le32_to_cpu(ht->agg_mpdu_cnt),
-			 accum_ht->agg_mpdu_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt);
+			 accum_ht->agg_mpdu_cnt,
+			 delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "agg_cnt:",
+			 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
+			 delta_ht->agg_cnt, max_ht->agg_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "unsupport_mcs:",
+			 le32_to_cpu(ht->unsupport_mcs),
+			 accum_ht->unsupport_mcs,
+			 delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
 
 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 	kfree(buf);
@@ -1379,26 +1518,16 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_
 					char __user *user_buf,
 					size_t count, loff_t *ppos)
 {
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	int pos = 0;
 	char *buf;
-	int bufsz = (sizeof(struct statistics_tx) * 24) + 250;
+	int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
 	ssize_t ret;
-	struct statistics_tx *tx, *accum_tx;
+	struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
 
 	if (!iwl_is_alive(priv))
 		return -EAGAIN;
 
-	/* make request to uCode to retrieve statistics information */
-	mutex_lock(&priv->mutex);
-	ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
-	mutex_unlock(&priv->mutex);
-
-	if (ret) {
-		IWL_ERR(priv,
-			"Error sending statistics request: %zd\n", ret);
-		return -EAGAIN;
-	}
 	buf = kzalloc(bufsz, GFP_KERNEL);
 	if (!buf) {
 		IWL_ERR(priv, "Can not allocate Buffer\n");
@@ -1411,106 +1540,148 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_
 	 */
 	tx = &priv->statistics.tx;
 	accum_tx = &priv->accum_statistics.tx;
+	delta_tx = &priv->delta_statistics.tx;
+	max_tx = &priv->max_delta.tx;
 	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
-	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Tx:\n");
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"\t\t\tcurrent\t\t\taccumulative\n");
-	pos += scnprintf(buf + pos, bufsz - pos, "preamble:\t\t\t%u\t\t\t%u\n",
+	pos += scnprintf(buf + pos, bufsz - pos,  ucode_stats_header,
+			"Statistics_Tx:");
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "preamble:",
 			 le32_to_cpu(tx->preamble_cnt),
-			 accum_tx->preamble_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "rx_detected_cnt:\t\t%u\t\t\t%u\n",
+			 accum_tx->preamble_cnt,
+			 delta_tx->preamble_cnt, max_tx->preamble_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "rx_detected_cnt:",
 			 le32_to_cpu(tx->rx_detected_cnt),
-			 accum_tx->rx_detected_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "bt_prio_defer_cnt:\t\t%u\t\t\t%u\n",
+			 accum_tx->rx_detected_cnt,
+			 delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "bt_prio_defer_cnt:",
 			 le32_to_cpu(tx->bt_prio_defer_cnt),
-			 accum_tx->bt_prio_defer_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "bt_prio_kill_cnt:\t\t%u\t\t\t%u\n",
+			 accum_tx->bt_prio_defer_cnt,
+			 delta_tx->bt_prio_defer_cnt,
+			 max_tx->bt_prio_defer_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "bt_prio_kill_cnt:",
 			 le32_to_cpu(tx->bt_prio_kill_cnt),
-			 accum_tx->bt_prio_kill_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "few_bytes_cnt:\t\t\t%u\t\t\t%u\n",
+			 accum_tx->bt_prio_kill_cnt,
+			 delta_tx->bt_prio_kill_cnt,
+			 max_tx->bt_prio_kill_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "few_bytes_cnt:",
 			 le32_to_cpu(tx->few_bytes_cnt),
-			 accum_tx->few_bytes_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "cts_timeout:\t\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "ack_timeout:\t\t\t%u\t\t\t%u\n",
+			 accum_tx->few_bytes_cnt,
+			 delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "cts_timeout:",
+			 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
+			 delta_tx->cts_timeout, max_tx->cts_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "ack_timeout:",
 			 le32_to_cpu(tx->ack_timeout),
-			 accum_tx->ack_timeout);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "expected_ack_cnt:\t\t%u\t\t\t%u\n",
+			 accum_tx->ack_timeout,
+			 delta_tx->ack_timeout, max_tx->ack_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "expected_ack_cnt:",
 			 le32_to_cpu(tx->expected_ack_cnt),
-			 accum_tx->expected_ack_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "actual_ack_cnt:\t\t\t%u\t\t\t%u\n",
+			 accum_tx->expected_ack_cnt,
+			 delta_tx->expected_ack_cnt,
+			 max_tx->expected_ack_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "actual_ack_cnt:",
 			 le32_to_cpu(tx->actual_ack_cnt),
-			 accum_tx->actual_ack_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "dump_msdu_cnt:\t\t\t%u\t\t\t%u\n",
+			 accum_tx->actual_ack_cnt,
+			 delta_tx->actual_ack_cnt,
+			 max_tx->actual_ack_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "dump_msdu_cnt:",
 			 le32_to_cpu(tx->dump_msdu_cnt),
-			 accum_tx->dump_msdu_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "abort_nxt_frame_mismatch:"
-			 "\t%u\t\t\t%u\n",
+			 accum_tx->dump_msdu_cnt,
+			 delta_tx->dump_msdu_cnt,
+			 max_tx->dump_msdu_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "abort_nxt_frame_mismatch:",
 			 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
-			 accum_tx->burst_abort_next_frame_mismatch_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "abort_missing_nxt_frame:"
-			 "\t%u\t\t\t%u\n",
+			 accum_tx->burst_abort_next_frame_mismatch_cnt,
+			 delta_tx->burst_abort_next_frame_mismatch_cnt,
+			 max_tx->burst_abort_next_frame_mismatch_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "abort_missing_nxt_frame:",
 			 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
-			 accum_tx->burst_abort_missing_next_frame_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "cts_timeout_collision:\t\t%u\t\t\t%u\n",
+			 accum_tx->burst_abort_missing_next_frame_cnt,
+			 delta_tx->burst_abort_missing_next_frame_cnt,
+			 max_tx->burst_abort_missing_next_frame_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "cts_timeout_collision:",
 			 le32_to_cpu(tx->cts_timeout_collision),
-			 accum_tx->cts_timeout_collision);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"ack_ba_timeout_collision:\t%u\t\t\t%u\n",
+			 accum_tx->cts_timeout_collision,
+			 delta_tx->cts_timeout_collision,
+			 max_tx->cts_timeout_collision);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			"ack_ba_timeout_collision:",
 			 le32_to_cpu(tx->ack_or_ba_timeout_collision),
-			 accum_tx->ack_or_ba_timeout_collision);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "agg ba_timeout:\t\t\t%u\t\t\t%u\n",
+			 accum_tx->ack_or_ba_timeout_collision,
+			 delta_tx->ack_or_ba_timeout_collision,
+			 max_tx->ack_or_ba_timeout_collision);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "agg ba_timeout:",
 			 le32_to_cpu(tx->agg.ba_timeout),
-			 accum_tx->agg.ba_timeout);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"agg ba_resched_frames:\t\t%u\t\t\t%u\n",
+			 accum_tx->agg.ba_timeout,
+			 delta_tx->agg.ba_timeout,
+			 max_tx->agg.ba_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			"agg ba_resched_frames:",
 			 le32_to_cpu(tx->agg.ba_reschedule_frames),
-			 accum_tx->agg.ba_reschedule_frames);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"agg scd_query_agg_frame:\t%u\t\t\t%u\n",
+			 accum_tx->agg.ba_reschedule_frames,
+			 delta_tx->agg.ba_reschedule_frames,
+			 max_tx->agg.ba_reschedule_frames);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			"agg scd_query_agg_frame:",
 			 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
-			 accum_tx->agg.scd_query_agg_frame_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "agg scd_query_no_agg:\t\t%u\t\t\t%u\n",
+			 accum_tx->agg.scd_query_agg_frame_cnt,
+			 delta_tx->agg.scd_query_agg_frame_cnt,
+			 max_tx->agg.scd_query_agg_frame_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "agg scd_query_no_agg:",
 			 le32_to_cpu(tx->agg.scd_query_no_agg),
-			 accum_tx->agg.scd_query_no_agg);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "agg scd_query_agg:\t\t%u\t\t\t%u\n",
+			 accum_tx->agg.scd_query_no_agg,
+			 delta_tx->agg.scd_query_no_agg,
+			 max_tx->agg.scd_query_no_agg);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "agg scd_query_agg:",
 			 le32_to_cpu(tx->agg.scd_query_agg),
-			 accum_tx->agg.scd_query_agg);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"agg scd_query_mismatch:\t\t%u\t\t\t%u\n",
+			 accum_tx->agg.scd_query_agg,
+			 delta_tx->agg.scd_query_agg,
+			 max_tx->agg.scd_query_agg);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			"agg scd_query_mismatch:",
 			 le32_to_cpu(tx->agg.scd_query_mismatch),
-			 accum_tx->agg.scd_query_mismatch);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "agg frame_not_ready:\t\t%u\t\t\t%u\n",
+			 accum_tx->agg.scd_query_mismatch,
+			 delta_tx->agg.scd_query_mismatch,
+			 max_tx->agg.scd_query_mismatch);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "agg frame_not_ready:",
 			 le32_to_cpu(tx->agg.frame_not_ready),
-			 accum_tx->agg.frame_not_ready);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "agg underrun:\t\t\t%u\t\t\t%u\n",
+			 accum_tx->agg.frame_not_ready,
+			 delta_tx->agg.frame_not_ready,
+			 max_tx->agg.frame_not_ready);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "agg underrun:",
 			 le32_to_cpu(tx->agg.underrun),
-			 accum_tx->agg.underrun);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "agg bt_prio_kill:\t\t%u\t\t\t%u\n",
+			 accum_tx->agg.underrun,
+			 delta_tx->agg.underrun, max_tx->agg.underrun);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "agg bt_prio_kill:",
 			 le32_to_cpu(tx->agg.bt_prio_kill),
-			 accum_tx->agg.bt_prio_kill);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "agg rx_ba_rsp_cnt:\t\t%u\t\t\t%u\n",
+			 accum_tx->agg.bt_prio_kill,
+			 delta_tx->agg.bt_prio_kill,
+			 max_tx->agg.bt_prio_kill);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "agg rx_ba_rsp_cnt:",
 			 le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
-			 accum_tx->agg.rx_ba_rsp_cnt);
+			 accum_tx->agg.rx_ba_rsp_cnt,
+			 delta_tx->agg.rx_ba_rsp_cnt,
+			 max_tx->agg.rx_ba_rsp_cnt);
 
 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 	kfree(buf);
@@ -1521,28 +1692,19 @@ static ssize_t iwl_dbgfs_ucode_general_s
 					char __user *user_buf,
 					size_t count, loff_t *ppos)
 {
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	int pos = 0;
 	char *buf;
-	int bufsz = sizeof(struct statistics_general) * 4 + 250;
+	int bufsz = sizeof(struct statistics_general) * 10 + 300;
 	ssize_t ret;
 	struct statistics_general *general, *accum_general;
-	struct statistics_dbg *dbg, *accum_dbg;
-	struct statistics_div *div, *accum_div;
+	struct statistics_general *delta_general, *max_general;
+	struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
+	struct statistics_div *div, *accum_div, *delta_div, *max_div;
 
 	if (!iwl_is_alive(priv))
 		return -EAGAIN;
 
-	/* make request to uCode to retrieve statistics information */
-	mutex_lock(&priv->mutex);
-	ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
-	mutex_unlock(&priv->mutex);
-
-	if (ret) {
-		IWL_ERR(priv,
-			"Error sending statistics request: %zd\n", ret);
-		return -EAGAIN;
-	}
 	buf = kzalloc(bufsz, GFP_KERNEL);
 	if (!buf) {
 		IWL_ERR(priv, "Can not allocate Buffer\n");
@@ -1557,52 +1719,78 @@ static ssize_t iwl_dbgfs_ucode_general_s
 	dbg = &priv->statistics.general.dbg;
 	div = &priv->statistics.general.div;
 	accum_general = &priv->accum_statistics.general;
+	delta_general = &priv->delta_statistics.general;
+	max_general = &priv->max_delta.general;
 	accum_dbg = &priv->accum_statistics.general.dbg;
+	delta_dbg = &priv->delta_statistics.general.dbg;
+	max_dbg = &priv->max_delta.general.dbg;
 	accum_div = &priv->accum_statistics.general.div;
+	delta_div = &priv->delta_statistics.general.div;
+	max_div = &priv->max_delta.general.div;
 	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
-	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_General:\n");
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"\t\t\tcurrent\t\t\taccumulative\n");
-	pos += scnprintf(buf + pos, bufsz - pos, "temperature:\t\t\t%u\n",
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
+			"Statistics_General:");
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
+			 "temperature:",
 			 le32_to_cpu(general->temperature));
-	pos += scnprintf(buf + pos, bufsz - pos, "temperature_m:\t\t\t%u\n",
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
+			 "temperature_m:",
 			 le32_to_cpu(general->temperature_m));
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "burst_check:\t\t\t%u\t\t\t%u\n",
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "burst_check:",
 			 le32_to_cpu(dbg->burst_check),
-			 accum_dbg->burst_check);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "burst_count:\t\t\t%u\t\t\t%u\n",
+			 accum_dbg->burst_check,
+			 delta_dbg->burst_check, max_dbg->burst_check);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "burst_count:",
 			 le32_to_cpu(dbg->burst_count),
-			 accum_dbg->burst_count);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "sleep_time:\t\t\t%u\t\t\t%u\n",
+			 accum_dbg->burst_count,
+			 delta_dbg->burst_count, max_dbg->burst_count);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "sleep_time:",
 			 le32_to_cpu(general->sleep_time),
-			 accum_general->sleep_time);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "slots_out:\t\t\t%u\t\t\t%u\n",
+			 accum_general->sleep_time,
+			 delta_general->sleep_time, max_general->sleep_time);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "slots_out:",
 			 le32_to_cpu(general->slots_out),
-			 accum_general->slots_out);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "slots_idle:\t\t\t%u\t\t\t%u\n",
+			 accum_general->slots_out,
+			 delta_general->slots_out, max_general->slots_out);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "slots_idle:",
 			 le32_to_cpu(general->slots_idle),
-			 accum_general->slots_idle);
+			 accum_general->slots_idle,
+			 delta_general->slots_idle, max_general->slots_idle);
 	pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
 			 le32_to_cpu(general->ttl_timestamp));
-	pos += scnprintf(buf + pos, bufsz - pos, "tx_on_a:\t\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a);
-	pos += scnprintf(buf + pos, bufsz - pos, "tx_on_b:\t\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "exec_time:\t\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(div->exec_time), accum_div->exec_time);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "probe_time:\t\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(div->probe_time), accum_div->probe_time);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "rx_enable_counter:\t\t%u\t\t\t%u\n",
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "tx_on_a:",
+			 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
+			 delta_div->tx_on_a, max_div->tx_on_a);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "tx_on_b:",
+			 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
+			 delta_div->tx_on_b, max_div->tx_on_b);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "exec_time:",
+			 le32_to_cpu(div->exec_time), accum_div->exec_time,
+			 delta_div->exec_time, max_div->exec_time);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "probe_time:",
+			 le32_to_cpu(div->probe_time), accum_div->probe_time,
+			 delta_div->probe_time, max_div->probe_time);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "rx_enable_counter:",
 			 le32_to_cpu(general->rx_enable_counter),
-			 accum_general->rx_enable_counter);
+			 accum_general->rx_enable_counter,
+			 delta_general->rx_enable_counter,
+			 max_general->rx_enable_counter);
+	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
+			 "num_of_sos_states:",
+			 le32_to_cpu(general->num_of_sos_states),
+			 accum_general->num_of_sos_states,
+			 delta_general->num_of_sos_states,
+			 max_general->num_of_sos_states);
 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 	kfree(buf);
 	return ret;
@@ -1612,7 +1800,7 @@ static ssize_t iwl_dbgfs_sensitivity_rea
 					char __user *user_buf,
 					size_t count, loff_t *ppos) {
 
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	int pos = 0;
 	int cnt = 0;
 	char *buf;
@@ -1693,7 +1881,7 @@ static ssize_t iwl_dbgfs_chain_noise_rea
 					char __user *user_buf,
 					size_t count, loff_t *ppos) {
 
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	int pos = 0;
 	int cnt = 0;
 	char *buf;
@@ -1751,26 +1939,15 @@ static ssize_t iwl_dbgfs_tx_power_read(s
 					char __user *user_buf,
 					size_t count, loff_t *ppos) {
 
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	char buf[128];
 	int pos = 0;
-	ssize_t ret;
 	const size_t bufsz = sizeof(buf);
 	struct statistics_tx *tx;
 
 	if (!iwl_is_alive(priv))
 		pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
 	else {
-		/* make request to uCode to retrieve statistics information */
-		mutex_lock(&priv->mutex);
-		ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
-		mutex_unlock(&priv->mutex);
-
-		if (ret) {
-			IWL_ERR(priv, "Error sending statistics request: %zd\n",
-				ret);
-			return -EAGAIN;
-		}
 		tx = &priv->statistics.tx;
 		if (tx->tx_power.ant_a ||
 		    tx->tx_power.ant_b ||
@@ -1802,7 +1979,7 @@ static ssize_t iwl_dbgfs_power_save_stat
 						    char __user *user_buf,
 						    size_t count, loff_t *ppos)
 {
-	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_priv *priv = file->private_data;
 	char buf[60];
 	int pos = 0;
 	const size_t bufsz = sizeof(buf);
@@ -1845,6 +2022,262 @@ static ssize_t iwl_dbgfs_clear_ucode_sta
 	return count;
 }
 
+static ssize_t iwl_dbgfs_csr_write(struct file *file,
+					 const char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = file->private_data;
+	char buf[8];
+	int buf_size;
+	int csr;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+	if (sscanf(buf, "%d", &csr) != 1)
+		return -EFAULT;
+
+	if (priv->cfg->ops->lib->dump_csr)
+		priv->cfg->ops->lib->dump_csr(priv);
+
+	return count;
+}
+
+static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file,
+					char __user *user_buf,
+					size_t count, loff_t *ppos) {
+
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	int pos = 0;
+	char buf[128];
+	const size_t bufsz = sizeof(buf);
+	ssize_t ret;
+
+	pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n",
+			priv->event_log.ucode_trace ? "On" : "Off");
+	pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n",
+			priv->event_log.non_wraps_count);
+	pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n",
+			priv->event_log.wraps_once_count);
+	pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n",
+			priv->event_log.wraps_more_count);
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	return ret;
+}
+
+static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
+					 const char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = file->private_data;
+	char buf[8];
+	int buf_size;
+	int trace;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+	if (sscanf(buf, "%d", &trace) != 1)
+		return -EFAULT;
+
+	if (trace) {
+		priv->event_log.ucode_trace = true;
+		/* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
+		mod_timer(&priv->ucode_trace,
+			jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
+	} else {
+		priv->event_log.ucode_trace = false;
+		del_timer_sync(&priv->ucode_trace);
+	}
+
+	return count;
+}
+
+static ssize_t iwl_dbgfs_fh_reg_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;
+	int pos = 0;
+	ssize_t ret = -EFAULT;
+
+	if (priv->cfg->ops->lib->dump_fh) {
+		ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true);
+		if (buf) {
+			ret = simple_read_from_buffer(user_buf,
+						      count, ppos, buf, pos);
+			kfree(buf);
+		}
+	}
+
+	return ret;
+}
+
+static ssize_t iwl_dbgfs_missed_beacon_read(struct file *file,
+					char __user *user_buf,
+					size_t count, loff_t *ppos) {
+
+	struct iwl_priv *priv = file->private_data;
+	int pos = 0;
+	char buf[12];
+	const size_t bufsz = sizeof(buf);
+	ssize_t ret;
+
+	pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
+			priv->missed_beacon_threshold);
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	return ret;
+}
+
+static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file,
+					 const char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = file->private_data;
+	char buf[8];
+	int buf_size;
+	int missed;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+	if (sscanf(buf, "%d", &missed) != 1)
+		return -EINVAL;
+
+	if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN ||
+	    missed > IWL_MISSED_BEACON_THRESHOLD_MAX)
+		priv->missed_beacon_threshold =
+			IWL_MISSED_BEACON_THRESHOLD_DEF;
+	else
+		priv->missed_beacon_threshold = missed;
+
+	return count;
+}
+
+static ssize_t iwl_dbgfs_internal_scan_write(struct file *file,
+					 const char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = file->private_data;
+	char buf[8];
+	int buf_size;
+	int scan;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+	if (sscanf(buf, "%d", &scan) != 1)
+		return -EINVAL;
+
+	iwl_internal_short_hw_scan(priv);
+
+	return count;
+}
+
+static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
+					char __user *user_buf,
+					size_t count, loff_t *ppos) {
+
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	int pos = 0;
+	char buf[12];
+	const size_t bufsz = sizeof(buf);
+	ssize_t ret;
+
+	pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
+			priv->cfg->plcp_delta_threshold);
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	return ret;
+}
+
+static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
+					const char __user *user_buf,
+					size_t count, loff_t *ppos) {
+
+	struct iwl_priv *priv = file->private_data;
+	char buf[8];
+	int buf_size;
+	int plcp;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+	if (sscanf(buf, "%d", &plcp) != 1)
+		return -EINVAL;
+	if ((plcp <= IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
+		(plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
+		priv->cfg->plcp_delta_threshold =
+			IWL_MAX_PLCP_ERR_THRESHOLD_DEF;
+	else
+		priv->cfg->plcp_delta_threshold = plcp;
+	return count;
+}
+
+static ssize_t iwl_dbgfs_force_reset_read(struct file *file,
+					char __user *user_buf,
+					size_t count, loff_t *ppos) {
+
+	struct iwl_priv *priv = file->private_data;
+	int i, pos = 0;
+	char buf[300];
+	const size_t bufsz = sizeof(buf);
+	struct iwl_force_reset *force_reset;
+
+	for (i = 0; i < IWL_MAX_FORCE_RESET; i++) {
+		force_reset = &priv->force_reset[i];
+		pos += scnprintf(buf + pos, bufsz - pos,
+				"Force reset method %d\n", i);
+		pos += scnprintf(buf + pos, bufsz - pos,
+				"\tnumber of reset request: %d\n",
+				force_reset->reset_request_count);
+		pos += scnprintf(buf + pos, bufsz - pos,
+				"\tnumber of reset request success: %d\n",
+				force_reset->reset_success_count);
+		pos += scnprintf(buf + pos, bufsz - pos,
+				"\tnumber of reset request reject: %d\n",
+				force_reset->reset_reject_count);
+		pos += scnprintf(buf + pos, bufsz - pos,
+				"\treset duration: %lu\n",
+				force_reset->reset_duration);
+	}
+	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
+static ssize_t iwl_dbgfs_force_reset_write(struct file *file,
+					const char __user *user_buf,
+					size_t count, loff_t *ppos) {
+
+	struct iwl_priv *priv = file->private_data;
+	char buf[8];
+	int buf_size;
+	int reset, ret;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+	if (sscanf(buf, "%d", &reset) != 1)
+		return -EINVAL;
+	switch (reset) {
+	case IWL_RF_RESET:
+	case IWL_FW_RESET:
+		ret = iwl_force_reset(priv, reset);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return ret ? ret : count;
+}
+
 DEBUGFS_READ_FILE_OPS(rx_statistics);
 DEBUGFS_READ_FILE_OPS(tx_statistics);
 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1859,6 +2292,13 @@ DEBUGFS_READ_FILE_OPS(tx_power);
 DEBUGFS_READ_FILE_OPS(power_save_status);
 DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
 DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
+DEBUGFS_WRITE_FILE_OPS(csr);
+DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
+DEBUGFS_READ_FILE_OPS(fh_reg);
+DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
+DEBUGFS_WRITE_FILE_OPS(internal_scan);
+DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
+DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
 
 /*
  * Create the debugfs files and directories
@@ -1866,69 +2306,74 @@ DEBUGFS_WRITE_FILE_OPS(clear_traffic_sta
  */
 int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
 {
-	struct iwl_debugfs *dbgfs;
 	struct dentry *phyd = priv->hw->wiphy->debugfsdir;
-	int ret = 0;
+	struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
 
-	dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL);
-	if (!dbgfs) {
-		ret = -ENOMEM;
-		goto err;
-	}
+	dir_drv = debugfs_create_dir(name, phyd);
+	if (!dir_drv)
+		return -ENOMEM;
 
-	priv->dbgfs = dbgfs;
-	dbgfs->name = name;
-	dbgfs->dir_drv = debugfs_create_dir(name, phyd);
-	if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)) {
-		ret = -ENOENT;
+	priv->debugfs_dir = dir_drv;
+
+	dir_data = debugfs_create_dir("data", dir_drv);
+	if (!dir_data)
+		goto err;
+	dir_rf = debugfs_create_dir("rf", dir_drv);
+	if (!dir_rf)
+		goto err;
+	dir_debug = debugfs_create_dir("debug", dir_drv);
+	if (!dir_debug)
 		goto err;
-	}
 
-	DEBUGFS_ADD_DIR(data, dbgfs->dir_drv);
-	DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv);
-	DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv);
-	DEBUGFS_ADD_FILE(nvm, data, S_IRUSR);
-	DEBUGFS_ADD_FILE(sram, data, S_IWUSR | S_IRUSR);
-	DEBUGFS_ADD_FILE(log_event, data, S_IWUSR);
-	DEBUGFS_ADD_FILE(stations, data, S_IRUSR);
-	DEBUGFS_ADD_FILE(channels, data, S_IRUSR);
-	DEBUGFS_ADD_FILE(status, data, S_IRUSR);
-	DEBUGFS_ADD_FILE(interrupt, data, S_IWUSR | S_IRUSR);
-	DEBUGFS_ADD_FILE(qos, data, S_IRUSR);
-	DEBUGFS_ADD_FILE(led, data, S_IRUSR);
-	DEBUGFS_ADD_FILE(sleep_level_override, data, S_IWUSR | S_IRUSR);
-	DEBUGFS_ADD_FILE(current_sleep_command, data, S_IRUSR);
-	DEBUGFS_ADD_FILE(thermal_throttling, data, S_IRUSR);
-	DEBUGFS_ADD_FILE(disable_ht40, data, S_IWUSR | S_IRUSR);
-	DEBUGFS_ADD_FILE(rx_statistics, debug, S_IRUSR);
-	DEBUGFS_ADD_FILE(tx_statistics, debug, S_IRUSR);
-	DEBUGFS_ADD_FILE(traffic_log, debug, S_IWUSR | S_IRUSR);
-	DEBUGFS_ADD_FILE(rx_queue, debug, S_IRUSR);
-	DEBUGFS_ADD_FILE(tx_queue, debug, S_IRUSR);
-	DEBUGFS_ADD_FILE(tx_power, debug, S_IRUSR);
-	DEBUGFS_ADD_FILE(power_save_status, debug, S_IRUSR);
-	DEBUGFS_ADD_FILE(clear_ucode_statistics, debug, S_IWUSR);
-	DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR);
+	DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
+	DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
+	DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR);
+	DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
+	DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
+	DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
+	DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
+	DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
+	DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR);
+	DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR);
+	DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
+	DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
+	DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
+	DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
+	DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR);
+	DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
+	DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
+	DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
+	DEBUGFS_ADD_FILE(tx_power, dir_debug, S_IRUSR);
+	DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
+	DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
+	DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
+	DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR);
+	DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
+	DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
+	DEBUGFS_ADD_FILE(internal_scan, dir_debug, S_IWUSR);
+	DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
+	DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
 	if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
-		DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR);
-		DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR);
-		DEBUGFS_ADD_FILE(ucode_general_stats, debug, S_IRUSR);
-		DEBUGFS_ADD_FILE(sensitivity, debug, S_IRUSR);
-		DEBUGFS_ADD_FILE(chain_noise, debug, S_IRUSR);
+		DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
+		DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
+		DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
+		DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
+		DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
+		DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
 	}
-	DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
-	DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
+	DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal);
+	DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
 			 &priv->disable_chain_noise_cal);
 	if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
 	    ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
-		DEBUGFS_ADD_BOOL(disable_tx_power, rf,
+		DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
 				&priv->disable_tx_power_cal);
 	return 0;
 
 err:
-	IWL_ERR(priv, "Can't open the debugfs directory\n");
+	IWL_ERR(priv, "Can't create the debugfs directory\n");
 	iwl_dbgfs_unregister(priv);
-	return ret;
+	return -ENOMEM;
 }
 EXPORT_SYMBOL(iwl_dbgfs_register);
 
@@ -1938,56 +2383,11 @@ EXPORT_SYMBOL(iwl_dbgfs_register);
  */
 void iwl_dbgfs_unregister(struct iwl_priv *priv)
 {
-	if (!priv->dbgfs)
+	if (!priv->debugfs_dir)
 		return;
 
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sleep_level_override);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_current_sleep_command);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram);
-	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->dbgfs_data_files.file_interrupt);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_qos);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40);
-	DEBUGFS_REMOVE(priv->dbgfs->dir_data);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_statistics);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_statistics);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_traffic_log);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_queue);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
-			file_clear_ucode_statistics);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
-			file_clear_traffic_statistics);
-	if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
-		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
-			file_ucode_rx_stats);
-		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
-			file_ucode_tx_stats);
-		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
-			file_ucode_general_stats);
-		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
-			file_sensitivity);
-		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
-			file_chain_noise);
-	}
-	DEBUGFS_REMOVE(priv->dbgfs->dir_debug);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
-	if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
-	    ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
-		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power);
-	DEBUGFS_REMOVE(priv->dbgfs->dir_rf);
-	DEBUGFS_REMOVE(priv->dbgfs->dir_drv);
-	kfree(priv->dbgfs);
-	priv->dbgfs = NULL;
+	debugfs_remove_recursive(priv->debugfs_dir);
+	priv->debugfs_dir = NULL;
 }
 EXPORT_SYMBOL(iwl_dbgfs_unregister);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-debug.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-debug.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-debug.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-debug.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project.
  *
@@ -67,57 +67,6 @@ do {
 			       DUMP_PREFIX_OFFSET, 16, 1, p, len, 1);	\
 } while (0)
 
-#ifdef CONFIG_IWLWIFI_DEBUGFS
-struct iwl_debugfs {
-	const char *name;
-	struct dentry *dir_drv;
-	struct dentry *dir_data;
-	struct dentry *dir_debug;
-	struct dentry *dir_rf;
-	struct dir_data_files {
-		struct dentry *file_sram;
-		struct dentry *file_nvm;
-		struct dentry *file_stations;
-		struct dentry *file_log_event;
-		struct dentry *file_channels;
-		struct dentry *file_status;
-		struct dentry *file_interrupt;
-		struct dentry *file_qos;
-		struct dentry *file_thermal_throttling;
-		struct dentry *file_led;
-		struct dentry *file_disable_ht40;
-		struct dentry *file_sleep_level_override;
-		struct dentry *file_current_sleep_command;
-	} dbgfs_data_files;
-	struct dir_rf_files {
-		struct dentry *file_disable_sensitivity;
-		struct dentry *file_disable_chain_noise;
-		struct dentry *file_disable_tx_power;
-	} dbgfs_rf_files;
-	struct dir_debug_files {
-		struct dentry *file_rx_statistics;
-		struct dentry *file_tx_statistics;
-		struct dentry *file_traffic_log;
-		struct dentry *file_rx_queue;
-		struct dentry *file_tx_queue;
-		struct dentry *file_ucode_rx_stats;
-		struct dentry *file_ucode_tx_stats;
-		struct dentry *file_ucode_general_stats;
-		struct dentry *file_sensitivity;
-		struct dentry *file_chain_noise;
-		struct dentry *file_tx_power;
-		struct dentry *file_power_save_status;
-		struct dentry *file_clear_ucode_statistics;
-		struct dentry *file_clear_traffic_statistics;
-	} dbgfs_debug_files;
-	u32 sram_offset;
-	u32 sram_len;
-};
-
-int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
-void iwl_dbgfs_unregister(struct iwl_priv *priv);
-#endif
-
 #else
 #define IWL_DEBUG(__priv, level, fmt, args...)
 #define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)
@@ -126,9 +75,10 @@ static inline void iwl_print_hex_dump(st
 {}
 #endif				/* CONFIG_IWLWIFI_DEBUG */
 
-
-
-#ifndef CONFIG_IWLWIFI_DEBUGFS
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
+void iwl_dbgfs_unregister(struct iwl_priv *priv);
+#else
 static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
 {
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-dev.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-dev.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-dev.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-dev.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -512,6 +512,7 @@ struct iwl_ht_config {
 	bool is_ht;
 	bool is_40mhz;
 	bool single_chain_sufficient;
+	enum ieee80211_smps_mode smps; /* current smps mode */
 	/* BSS related data */
 	u8 extension_chan_offset;
 	u8 ht_protection;
@@ -984,6 +985,74 @@ struct iwl_switch_rxon {
 	__le16 channel;
 };
 
+/*
+ * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
+ * to perform continuous uCode event logging operation if enabled
+ */
+#define UCODE_TRACE_PERIOD (100)
+
+/*
+ * iwl_event_log: current uCode event log position
+ *
+ * @ucode_trace: enable/disable ucode continuous trace timer
+ * @num_wraps: how many times the event buffer wraps
+ * @next_entry:  the entry just before the next one that uCode would fill
+ * @non_wraps_count: counter for no wrap detected when dump ucode events
+ * @wraps_once_count: counter for wrap once detected when dump ucode events
+ * @wraps_more_count: counter for wrap more than once detected
+ *		      when dump ucode events
+ */
+struct iwl_event_log {
+	bool ucode_trace;
+	u32 num_wraps;
+	u32 next_entry;
+	int non_wraps_count;
+	int wraps_once_count;
+	int wraps_more_count;
+};
+
+/*
+ * host interrupt timeout value
+ * used with setting interrupt coalescing timer
+ * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit
+ *
+ * default interrupt coalescing timer is 64 x 32 = 2048 usecs
+ * default interrupt coalescing calibration timer is 16 x 32 = 512 usecs
+ */
+#define IWL_HOST_INT_TIMEOUT_MAX	(0xFF)
+#define IWL_HOST_INT_TIMEOUT_DEF	(0x40)
+#define IWL_HOST_INT_TIMEOUT_MIN	(0x0)
+#define IWL_HOST_INT_CALIB_TIMEOUT_MAX	(0xFF)
+#define IWL_HOST_INT_CALIB_TIMEOUT_DEF	(0x10)
+#define IWL_HOST_INT_CALIB_TIMEOUT_MIN	(0x0)
+
+/*
+ * This is the threshold value of plcp error rate per 100mSecs.  It is
+ * used to set and check for the validity of plcp_delta.
+ */
+#define IWL_MAX_PLCP_ERR_THRESHOLD_MIN	(0)
+#define IWL_MAX_PLCP_ERR_THRESHOLD_DEF	(50)
+#define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF	(100)
+#define IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF	(200)
+#define IWL_MAX_PLCP_ERR_THRESHOLD_MAX	(255)
+
+#define IWL_DELAY_NEXT_FORCE_RF_RESET  (HZ*3)
+#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5)
+
+enum iwl_reset {
+	IWL_RF_RESET = 0,
+	IWL_FW_RESET,
+	IWL_MAX_FORCE_RESET,
+};
+
+struct iwl_force_reset {
+	int reset_request_count;
+	int reset_success_count;
+	int reset_reject_count;
+	unsigned long reset_duration;
+	unsigned long last_force_reset_jiffies;
+};
+
 struct iwl_priv {
 
 	/* ieee device used by generic ieee processing code */
@@ -1004,13 +1073,19 @@ struct iwl_priv {
 
 	struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
 
-#if defined(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) || defined(CONFIG_IWL3945_SPECTRUM_MEASUREMENT)
 	/* spectrum measurement report caching */
 	struct iwl_spectrum_notification measure_report;
 	u8 measurement_status;
-#endif
+
 	/* ucode beacon time */
 	u32 ucode_beacon_time;
+	int missed_beacon_threshold;
+
+	/* storing the jiffies when the plcp error rate is received */
+	unsigned long plcp_jiffies;
+
+	/* force reset */
+	struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET];
 
 	/* we allocate array of iwl4965_channel_info for NIC's valid channels.
 	 *    Access via channel # using indirect index array */
@@ -1029,7 +1104,6 @@ struct iwl_priv {
 	struct iwl_calib_result calib_results[IWL_CALIB_MAX];
 
 	/* Scan related variables */
-	unsigned long last_scan_jiffies;
 	unsigned long next_scan_jiffies;
 	unsigned long scan_start;
 	unsigned long scan_pass_start;
@@ -1037,6 +1111,7 @@ struct iwl_priv {
 	void *scan;
 	int scan_bands;
 	struct cfg80211_scan_request *scan_request;
+	bool is_internal_short_scan;
 	u8 scan_tx_ant[IEEE80211_NUM_BANDS];
 	u8 mgmt_tx_ant;
 
@@ -1045,6 +1120,7 @@ struct iwl_priv {
 	spinlock_t hcmd_lock;	/* protect hcmd */
 	spinlock_t reg_lock;	/* protect hw register access */
 	struct mutex mutex;
+	struct mutex sync_cmd_mutex; /* enable serialization of sync commands */
 
 	/* basic pci-network driver stuff */
 	struct pci_dev *pci_dev;
@@ -1056,6 +1132,7 @@ struct iwl_priv {
 	u8   rev_id;
 
 	/* uCode images, save to reload in case of failure */
+	int fw_index;			/* firmware we're trying to load */
 	u32 ucode_ver;			/* version of ucode, copy of
 					   iwl_ucode.ver */
 	struct fw_desc ucode_code;	/* runtime inst */
@@ -1066,6 +1143,7 @@ struct iwl_priv {
 	struct fw_desc ucode_boot;	/* bootstrap inst */
 	enum ucode_type ucode_type;
 	u8 ucode_write_complete;	/* the image write is complete */
+	char firmware_name[25];
 
 
 	struct iwl_rxon_time_cmd rxon_timing;
@@ -1135,6 +1213,8 @@ struct iwl_priv {
 	struct iwl_notif_statistics statistics;
 #ifdef CONFIG_IWLWIFI_DEBUG
 	struct iwl_notif_statistics accum_statistics;
+	struct iwl_notif_statistics delta_statistics;
+	struct iwl_notif_statistics max_delta;
 #endif
 
 	/* context information */
@@ -1207,20 +1287,16 @@ struct iwl_priv {
 
 	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 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 work_struct tt_work;
 	struct work_struct ct_enter;
 	struct work_struct ct_exit;
+	struct work_struct start_internal_scan;
 
 	struct tasklet_struct irq_tasklet;
 
@@ -1251,7 +1327,8 @@ struct iwl_priv {
 	u16 rx_traffic_idx;
 	u8 *tx_traffic;
 	u8 *rx_traffic;
-	struct iwl_debugfs *dbgfs;
+	struct dentry *debugfs_dir;
+	u32 dbgfs_sram_offset, dbgfs_sram_len;
 #endif /* CONFIG_IWLWIFI_DEBUGFS */
 #endif /* CONFIG_IWLWIFI_DEBUG */
 
@@ -1261,6 +1338,7 @@ struct iwl_priv {
 	u32 disable_tx_power_cal;
 	struct work_struct run_time_calib_work;
 	struct timer_list statistics_periodic;
+	struct timer_list ucode_trace;
 	bool hw_ready;
 	/*For 3945*/
 #define IWL_DEFAULT_TX_POWER 0x0F
@@ -1268,6 +1346,8 @@ struct iwl_priv {
 	struct iwl3945_notif_statistics statistics_39;
 
 	u32 sta_supp_rates;
+
+	struct iwl_event_log event_log;
 }; /*iwl_priv */
 
 static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,8 @@
 
 /* sparse doesn't like tracepoint macros */
 #ifndef __CHECKER__
+#include "iwl-dev.h"
+
 #define CREATE_TRACE_POINTS
 #include "iwl-devtrace.h"
 
@@ -37,4 +39,6 @@ EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iow
 EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx);
 EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event);
 EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error);
+EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event);
+EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event);
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.h	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,6 @@
 #define __IWLWIFI_DEVICE_TRACE
 
 #include <linux/tracepoint.h>
-#include "iwl-dev.h"
 
 #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__)
 #undef TRACE_EVENT
@@ -91,6 +90,50 @@ TRACE_EVENT(iwlwifi_dev_iowrite32,
 );
 
 #undef TRACE_SYSTEM
+#define TRACE_SYSTEM iwlwifi_ucode
+
+TRACE_EVENT(iwlwifi_dev_ucode_cont_event,
+	TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev),
+	TP_ARGS(priv, time, data, ev),
+	TP_STRUCT__entry(
+		PRIV_ENTRY
+
+		__field(u32, time)
+		__field(u32, data)
+		__field(u32, ev)
+	),
+	TP_fast_assign(
+		PRIV_ASSIGN;
+		__entry->time = time;
+		__entry->data = data;
+		__entry->ev = ev;
+	),
+	TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u",
+		  __entry->priv, __entry->time, __entry->data, __entry->ev)
+);
+
+TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
+	TP_PROTO(struct iwl_priv *priv, u32 wraps, u32 n_entry, u32 p_entry),
+	TP_ARGS(priv, wraps, n_entry, p_entry),
+	TP_STRUCT__entry(
+		PRIV_ENTRY
+
+		__field(u32, wraps)
+		__field(u32, n_entry)
+		__field(u32, p_entry)
+	),
+	TP_fast_assign(
+		PRIV_ASSIGN;
+		__entry->wraps = wraps;
+		__entry->n_entry = n_entry;
+		__entry->p_entry = p_entry;
+	),
+	TP_printk("[%p] wraps=#%02d n=0x%X p=0x%X",
+		  __entry->priv, __entry->wraps, __entry->n_entry,
+		  __entry->p_entry)
+);
+
+#undef TRACE_SYSTEM
 #define TRACE_SYSTEM iwlwifi
 
 TRACE_EVENT(iwlwifi_dev_hcmd,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,6 +63,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #include <net/mac80211.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -203,6 +203,10 @@ struct iwl_eeprom_enhanced_txpwr {
 #define EEPROM_5000_REG_BAND_52_HT40_CHANNELS  ((0x92)\
 		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 22  bytes */
 
+/* 6000 regulatory - indirect access */
+#define EEPROM_6000_REG_BAND_24_HT40_CHANNELS  ((0x80)\
+		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 14  bytes */
+
 /* 6000 and up regulatory tx power - indirect access */
 /* max. elements per section */
 #define EEPROM_MAX_TXPOWER_SECTION_ELEMENTS	(8)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-fh.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-fh.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-fh.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-fh.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -379,6 +379,25 @@
 
 #define FH_TSSR_TX_STATUS_REG		(FH_TSSR_LOWER_BOUND + 0x010)
 
+/**
+ * Bit fields for TSSR(Tx Shared Status & Control) error status register:
+ * 31:  Indicates an address error when accessed to internal memory
+ *	uCode/driver must write "1" in order to clear this flag
+ * 30:  Indicates that Host did not send the expected number of dwords to FH
+ *	uCode/driver must write "1" in order to clear this flag
+ * 16-9:Each status bit is for one channel. Indicates that an (Error) ActDMA
+ *	command was received from the scheduler while the TRB was already full
+ *	with previous command
+ *	uCode/driver must write "1" in order to clear this flag
+ * 7-0: Each status bit indicates a channel's TxCredit error. When an error
+ *	bit is set, it indicates that the FH has received a full indication
+ *	from the RTC TxFIFO and the current value of the TxCredit counter was
+ *	not equal to zero. This mean that the credit mechanism was not
+ *	synchronized to the TxFIFO status
+ *	uCode/driver must write "1" in order to clear this flag
+ */
+#define FH_TSSR_TX_ERROR_REG		(FH_TSSR_LOWER_BOUND + 0x018)
+
 #define FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) ((1 << (_chnl)) << 24)
 #define FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl) ((1 << (_chnl)) << 16)
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-hcmd.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-hcmd.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-hcmd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-hcmd.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -58,7 +58,6 @@ const char *get_cmd_string(u8 cmd)
 		IWL_CMD(COEX_PRIORITY_TABLE_CMD);
 		IWL_CMD(COEX_MEDIUM_NOTIFICATION);
 		IWL_CMD(COEX_EVENT_CMD);
-		IWL_CMD(RADAR_NOTIFICATION);
 		IWL_CMD(REPLY_QUIET_CMD);
 		IWL_CMD(REPLY_CHANNEL_SWITCH);
 		IWL_CMD(CHANNEL_SWITCH_NOTIFICATION);
@@ -165,15 +164,13 @@ int iwl_send_cmd_sync(struct iwl_priv *p
 	 /* A synchronous command can not have a callback set. */
 	BUG_ON(cmd->callback);
 
-	if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {
-		IWL_ERR(priv,
-			"Error sending %s: Already sending a host command\n",
+	IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",
 			get_cmd_string(cmd->id));
-		ret = -EBUSY;
-		goto out;
-	}
+	mutex_lock(&priv->sync_cmd_mutex);
 
 	set_bit(STATUS_HCMD_ACTIVE, &priv->status);
+	IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s \n",
+			get_cmd_string(cmd->id));
 
 	cmd_idx = iwl_enqueue_hcmd(priv, cmd);
 	if (cmd_idx < 0) {
@@ -194,6 +191,8 @@ int iwl_send_cmd_sync(struct iwl_priv *p
 				jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
 
 			clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+			IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s \n",
+				       get_cmd_string(cmd->id));
 			ret = -ETIMEDOUT;
 			goto cancel;
 		}
@@ -238,7 +237,7 @@ fail:
 		cmd->reply_page = 0;
 	}
 out:
-	clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);
+	mutex_unlock(&priv->sync_cmd_mutex);
 	return ret;
 }
 EXPORT_SYMBOL(iwl_send_cmd_sync);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-helpers.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-helpers.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-helpers.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-helpers.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 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.
@@ -80,8 +80,8 @@ static inline void iwl_free_fw_desc(stru
 				    struct fw_desc *desc)
 {
 	if (desc->v_addr)
-		pci_free_consistent(pci_dev, desc->len,
-				    desc->v_addr, desc->p_addr);
+		dma_free_coherent(&pci_dev->dev, desc->len,
+				  desc->v_addr, desc->p_addr);
 	desc->v_addr = NULL;
 	desc->len = 0;
 }
@@ -89,7 +89,8 @@ static inline void iwl_free_fw_desc(stru
 static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
 				    struct fw_desc *desc)
 {
-	desc->v_addr = pci_alloc_consistent(pci_dev, desc->len, &desc->p_addr);
+	desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len,
+					  &desc->p_addr, GFP_KERNEL);
 	return (desc->v_addr != NULL) ? 0 : -ENOMEM;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-io.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-io.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-io.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-io.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project.
  *
@@ -31,6 +31,7 @@
 
 #include <linux/io.h>
 
+#include "iwl-dev.h"
 #include "iwl-debug.h"
 #include "iwl-devtrace.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-led.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-led.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-led.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-led.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-led.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-led.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-led.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-led.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-power.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-power.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-power.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-power.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2010 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.
@@ -29,6 +29,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #include <net/mac80211.h>
@@ -303,13 +304,12 @@ static int iwl_set_power(struct iwl_priv
 				sizeof(struct iwl_powertable_cmd), cmd);
 }
 
-
+/* priv->mutex must be held */
 int iwl_power_update_mode(struct iwl_priv *priv, bool force)
 {
 	int ret = 0;
 	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
-	bool enabled = (priv->iw_mode == NL80211_IFTYPE_STATION) &&
-			(priv->hw->conf.flags & IEEE80211_CONF_PS);
+	bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS;
 	bool update_chains;
 	struct iwl_powertable_cmd cmd;
 	int dtimper;
@@ -319,7 +319,7 @@ int iwl_power_update_mode(struct iwl_pri
 			priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
 
 	if (priv->vif)
-		dtimper = priv->vif->bss_conf.dtim_period;
+		dtimper = priv->hw->conf.ps_dtim_period;
 	else
 		dtimper = 1;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-power.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-power.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-power.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-power.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2010 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.33-gnu1/drivers/net/wireless/iwlwifi/iwl-prph.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-prph.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-prph.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-prph.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2010 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.33-gnu1/drivers/net/wireless/iwlwifi/iwl-rx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-rx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 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.
@@ -28,6 +28,7 @@
  *****************************************************************************/
 
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 #include <asm/unaligned.h>
 #include "iwl-eeprom.h"
@@ -123,12 +124,11 @@ EXPORT_SYMBOL(iwl_rx_queue_space);
 /**
  * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue
  */
-int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
+void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
 {
 	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);
 
@@ -161,7 +161,6 @@ int iwl_rx_queue_update_write_ptr(struct
 
  exit_unlock:
 	spin_unlock_irqrestore(&q->lock, flags);
-	return ret;
 }
 EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr);
 /**
@@ -184,14 +183,13 @@ static inline __le32 iwl_dma_addr2rbd_pt
  * also updates the memory address in the firmware to reference the new
  * target buffer.
  */
-int iwl_rx_queue_restock(struct iwl_priv *priv)
+void iwl_rx_queue_restock(struct iwl_priv *priv)
 {
 	struct iwl_rx_queue *rxq = &priv->rxq;
 	struct list_head *element;
 	struct iwl_rx_mem_buffer *rxb;
 	unsigned long flags;
 	int write;
-	int ret = 0;
 
 	spin_lock_irqsave(&rxq->lock, flags);
 	write = rxq->write & ~0x7;
@@ -220,10 +218,8 @@ int iwl_rx_queue_restock(struct iwl_priv
 		spin_lock_irqsave(&rxq->lock, flags);
 		rxq->need_update = 1;
 		spin_unlock_irqrestore(&rxq->lock, flags);
-		ret = iwl_rx_queue_update_write_ptr(priv, rxq);
+		iwl_rx_queue_update_write_ptr(priv, rxq);
 	}
-
-	return ret;
 }
 EXPORT_SYMBOL(iwl_rx_queue_restock);
 
@@ -350,10 +346,10 @@ void iwl_rx_queue_free(struct iwl_priv *
 		}
 	}
 
-	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);
+	dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,
+			  rxq->dma_addr);
+	dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status),
+			  rxq->rb_stts, rxq->rb_stts_dma);
 	rxq->bd = NULL;
 	rxq->rb_stts  = NULL;
 }
@@ -362,7 +358,7 @@ EXPORT_SYMBOL(iwl_rx_queue_free);
 int iwl_rx_queue_alloc(struct iwl_priv *priv)
 {
 	struct iwl_rx_queue *rxq = &priv->rxq;
-	struct pci_dev *dev = priv->pci_dev;
+	struct device *dev = &priv->pci_dev->dev;
 	int i;
 
 	spin_lock_init(&rxq->lock);
@@ -370,12 +366,13 @@ int iwl_rx_queue_alloc(struct iwl_priv *
 	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);
+	rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr,
+				     GFP_KERNEL);
 	if (!rxq->bd)
 		goto err_bd;
 
-	rxq->rb_stts = pci_alloc_consistent(dev, sizeof(struct iwl_rb_status),
-					&rxq->rb_stts_dma);
+	rxq->rb_stts = dma_alloc_coherent(dev, sizeof(struct iwl_rb_status),
+					  &rxq->rb_stts_dma, GFP_KERNEL);
 	if (!rxq->rb_stts)
 		goto err_rb;
 
@@ -392,8 +389,8 @@ int iwl_rx_queue_alloc(struct iwl_priv *
 	return 0;
 
 err_rb:
-	pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
-			    rxq->dma_addr);
+	dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,
+			  rxq->dma_addr);
 err_bd:
 	return -ENOMEM;
 }
@@ -473,8 +470,8 @@ int iwl_rx_init(struct iwl_priv *priv, s
 			   (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
 			   (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
 
-	/* Set interrupt coalescing timer to 64 x 32 = 2048 usecs */
-	iwl_write8(priv, CSR_INT_COALESCING, 0x40);
+	/* Set interrupt coalescing timer to default (2048 usecs) */
+	iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
 
 	return 0;
 }
@@ -499,9 +496,10 @@ void iwl_rx_missed_beacon_notif(struct i
 	struct iwl_missed_beacon_notif *missed_beacon;
 
 	missed_beacon = &pkt->u.missed_beacon;
-	if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) {
+	if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) >
+	    priv->missed_beacon_threshold) {
 		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->consecutive_missed_beacons),
 		    le32_to_cpu(missed_beacon->total_missed_becons),
 		    le32_to_cpu(missed_beacon->num_recvd_beacons),
 		    le32_to_cpu(missed_beacon->num_expected_beacons));
@@ -511,6 +509,24 @@ void iwl_rx_missed_beacon_notif(struct i
 }
 EXPORT_SYMBOL(iwl_rx_missed_beacon_notif);
 
+void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
+					  struct iwl_rx_mem_buffer *rxb)
+{
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
+	struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
+
+	if (!report->state) {
+		IWL_DEBUG_11H(priv,
+			"Spectrum Measure Notification: Start\n");
+		return;
+	}
+
+	memcpy(&priv->measure_report, report, sizeof(*report));
+	priv->measurement_status |= MEASUREMENT_READY;
+}
+EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif);
+
+
 
 /* Calculate noise level, based on measurements during network silence just
  *   before arriving beacon.  This measurement can be done only if we know
@@ -564,15 +580,24 @@ static void iwl_accumulative_statistics(
 	int i;
 	__le32 *prev_stats;
 	u32 *accum_stats;
+	u32 *delta, *max_delta;
 
 	prev_stats = (__le32 *)&priv->statistics;
 	accum_stats = (u32 *)&priv->accum_statistics;
+	delta = (u32 *)&priv->delta_statistics;
+	max_delta = (u32 *)&priv->max_delta;
 
 	for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics);
-	     i += sizeof(__le32), stats++, prev_stats++, accum_stats++)
-		if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats))
-			*accum_stats += (le32_to_cpu(*stats) -
+	     i += sizeof(__le32), stats++, prev_stats++, delta++,
+	     max_delta++, accum_stats++) {
+		if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
+			*delta = (le32_to_cpu(*stats) -
 				le32_to_cpu(*prev_stats));
+			*accum_stats += *delta;
+			if (*delta > *max_delta)
+				*max_delta = *delta;
+		}
+	}
 
 	/* reset accumulative statistics for "no-counter" type statistics */
 	priv->accum_statistics.general.temperature =
@@ -592,11 +617,15 @@ static void iwl_accumulative_statistics(
 
 #define REG_RECALIB_PERIOD (60)
 
+#define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n"
 void iwl_rx_statistics(struct iwl_priv *priv,
 			      struct iwl_rx_mem_buffer *rxb)
 {
 	int change;
 	struct iwl_rx_packet *pkt = rxb_addr(rxb);
+	int combined_plcp_delta;
+	unsigned int plcp_msec;
+	unsigned long plcp_received_jiffies;
 
 	IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
 		     (int)sizeof(priv->statistics),
@@ -611,6 +640,56 @@ void iwl_rx_statistics(struct iwl_priv *
 #ifdef CONFIG_IWLWIFI_DEBUG
 	iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
 #endif
+	/*
+	 * check for plcp_err and trigger radio reset if it exceeds
+	 * the plcp error threshold plcp_delta.
+	 */
+	plcp_received_jiffies = jiffies;
+	plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
+					(long) priv->plcp_jiffies);
+	priv->plcp_jiffies = plcp_received_jiffies;
+	/*
+	 * check to make sure plcp_msec is not 0 to prevent division
+	 * by zero.
+	 */
+	if (plcp_msec) {
+		combined_plcp_delta =
+			(le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) -
+			le32_to_cpu(priv->statistics.rx.ofdm.plcp_err)) +
+			(le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) -
+			le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err));
+
+		if ((combined_plcp_delta > 0) &&
+			((combined_plcp_delta * 100) / plcp_msec) >
+			priv->cfg->plcp_delta_threshold) {
+			/*
+			 * if plcp_err exceed the threshold, the following
+			 * data is printed in csv format:
+			 *    Text: plcp_err exceeded %d,
+			 *    Received ofdm.plcp_err,
+			 *    Current ofdm.plcp_err,
+			 *    Received ofdm_ht.plcp_err,
+			 *    Current ofdm_ht.plcp_err,
+			 *    combined_plcp_delta,
+			 *    plcp_msec
+			 */
+			IWL_DEBUG_RADIO(priv, PLCP_MSG,
+				priv->cfg->plcp_delta_threshold,
+				le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
+				le32_to_cpu(priv->statistics.rx.ofdm.plcp_err),
+				le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
+				le32_to_cpu(
+					priv->statistics.rx.ofdm_ht.plcp_err),
+				combined_plcp_delta, plcp_msec);
+
+			/*
+			 * Reset the RF radio due to the high plcp
+			 * error rate
+			 */
+			iwl_force_reset(priv, IWL_RF_RESET);
+		}
+	}
+
 	memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
 
 	set_bit(STATUS_STATISTICS, &priv->status);
@@ -638,11 +717,13 @@ void iwl_reply_statistics(struct iwl_pri
 	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 
 	if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
-		memset(&priv->statistics, 0,
-			sizeof(struct iwl_notif_statistics));
 #ifdef CONFIG_IWLWIFI_DEBUG
 		memset(&priv->accum_statistics, 0,
 			sizeof(struct iwl_notif_statistics));
+		memset(&priv->delta_statistics, 0,
+			sizeof(struct iwl_notif_statistics));
+		memset(&priv->max_delta, 0,
+			sizeof(struct iwl_notif_statistics));
 #endif
 		IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-scan.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-scan.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-scan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-scan.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -25,6 +25,7 @@
  *  Intel Linux Wireless <ilw@linux.intel.com>
  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  *****************************************************************************/
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/etherdevice.h>
 #include <net/mac80211.h>
@@ -192,19 +193,17 @@ static void iwl_rx_scan_results_notif(st
 	IWL_DEBUG_SCAN(priv, "Scan ch.res: "
 		       "%d [802.11%s] "
 		       "(TSF: 0x%08X:%08X) - %d "
-		       "elapsed=%lu usec (%dms since last)\n",
+		       "elapsed=%lu usec\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)));
+		       le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf);
 #endif
 
-	priv->last_scan_jiffies = jiffies;
-	priv->next_scan_jiffies = 0;
+	if (!priv->is_internal_short_scan)
+		priv->next_scan_jiffies = 0;
 }
 
 /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
@@ -250,8 +249,9 @@ static void iwl_rx_scan_complete_notif(s
 			goto reschedule;
 	}
 
-	priv->last_scan_jiffies = jiffies;
-	priv->next_scan_jiffies = 0;
+	if (!priv->is_internal_short_scan)
+		priv->next_scan_jiffies = 0;
+
 	IWL_DEBUG_INFO(priv, "Setting scan to off\n");
 
 	clear_bit(STATUS_SCANNING, &priv->status);
@@ -314,6 +314,72 @@ u16 iwl_get_passive_dwell_time(struct iw
 }
 EXPORT_SYMBOL(iwl_get_passive_dwell_time);
 
+static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
+				     enum ieee80211_band band,
+				     struct iwl_scan_channel *scan_ch)
+{
+	const struct ieee80211_supported_band *sband;
+	const struct iwl_channel_info *ch_info;
+	u16 passive_dwell = 0;
+	u16 active_dwell = 0;
+	int i, added = 0;
+	u16 channel = 0;
+
+	sband = iwl_get_hw_mode(priv, band);
+	if (!sband) {
+		IWL_ERR(priv, "invalid band\n");
+		return added;
+	}
+
+	active_dwell = iwl_get_active_dwell_time(priv, band, 0);
+	passive_dwell = iwl_get_passive_dwell_time(priv, band);
+
+	if (passive_dwell <= active_dwell)
+		passive_dwell = active_dwell + 1;
+
+	/* only scan single channel, good enough to reset the RF */
+	/* pick the first valid not in-use channel */
+	if (band == IEEE80211_BAND_5GHZ) {
+		for (i = 14; i < priv->channel_count; i++) {
+			if (priv->channel_info[i].channel !=
+			    le16_to_cpu(priv->staging_rxon.channel)) {
+				channel = priv->channel_info[i].channel;
+				ch_info = iwl_get_channel_info(priv,
+					band, channel);
+				if (is_channel_valid(ch_info))
+					break;
+			}
+		}
+	} else {
+		for (i = 0; i < 14; i++) {
+			if (priv->channel_info[i].channel !=
+			    le16_to_cpu(priv->staging_rxon.channel)) {
+					channel =
+						priv->channel_info[i].channel;
+					ch_info = iwl_get_channel_info(priv,
+						band, channel);
+					if (is_channel_valid(ch_info))
+						break;
+			}
+		}
+	}
+	if (channel) {
+		scan_ch->channel = cpu_to_le16(channel);
+		scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
+		scan_ch->active_dwell = cpu_to_le16(active_dwell);
+		scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
+		/* Set txpower levels to defaults */
+		scan_ch->dsp_atten = 110;
+		if (band == IEEE80211_BAND_5GHZ)
+			scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
+		else
+			scan_ch->tx_gain = ((1 << 5) | (5 << 3));
+		added++;
+	} else
+		IWL_ERR(priv, "no valid channel found\n");
+	return added;
+}
+
 static int iwl_get_channels_for_scan(struct iwl_priv *priv,
 				     enum ieee80211_band band,
 				     u8 is_active, u8 n_probes,
@@ -404,23 +470,11 @@ EXPORT_SYMBOL(iwl_init_scan_params);
 
 static int iwl_scan_initiate(struct iwl_priv *priv)
 {
-	if (!iwl_is_ready_rf(priv)) {
-		IWL_DEBUG_SCAN(priv, "Aborting scan due to not ready.\n");
-		return -EIO;
-	}
-
-	if (test_bit(STATUS_SCANNING, &priv->status)) {
-		IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
-		return -EAGAIN;
-	}
-
-	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
-		return -EAGAIN;
-	}
+	WARN_ON(!mutex_is_locked(&priv->mutex));
 
 	IWL_DEBUG_INFO(priv, "Starting scan...\n");
 	set_bit(STATUS_SCANNING, &priv->status);
+	priv->is_internal_short_scan = false;
 	priv->scan_start = jiffies;
 	priv->scan_pass_start = priv->scan_start;
 
@@ -449,6 +503,18 @@ int iwl_mac_hw_scan(struct ieee80211_hw
 		goto out_unlock;
 	}
 
+	if (test_bit(STATUS_SCANNING, &priv->status)) {
+		IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
+		ret = -EAGAIN;
+		goto out_unlock;
+	}
+
+	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+		IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
+		ret = -EAGAIN;
+		goto out_unlock;
+	}
+
 	/* We don't schedule scan within next_scan_jiffies period.
 	 * Avoid scanning during possible EAPOL exchange, return
 	 * success immediately.
@@ -461,15 +527,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw
 		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;
-	}
-
 	priv->scan_bands = 0;
 	for (i = 0; i < req->n_channels; i++)
 		priv->scan_bands |= BIT(req->channels[i]->band);
@@ -488,6 +545,52 @@ out_unlock:
 }
 EXPORT_SYMBOL(iwl_mac_hw_scan);
 
+/*
+ * internal short scan, this function should only been called while associated.
+ * It will reset and tune the radio to prevent possible RF related problem
+ */
+void iwl_internal_short_hw_scan(struct iwl_priv *priv)
+{
+	queue_work(priv->workqueue, &priv->start_internal_scan);
+}
+
+static void iwl_bg_start_internal_scan(struct work_struct *work)
+{
+	struct iwl_priv *priv =
+		container_of(work, struct iwl_priv, start_internal_scan);
+
+	mutex_lock(&priv->mutex);
+
+	if (!iwl_is_ready_rf(priv)) {
+		IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
+		goto unlock;
+	}
+
+	if (test_bit(STATUS_SCANNING, &priv->status)) {
+		IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
+		goto unlock;
+	}
+
+	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+		IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
+		goto unlock;
+	}
+
+	priv->scan_bands = 0;
+	if (priv->band == IEEE80211_BAND_5GHZ)
+		priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
+	else
+		priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
+
+	IWL_DEBUG_SCAN(priv, "Start internal short scan...\n");
+	set_bit(STATUS_SCANNING, &priv->status);
+	priv->is_internal_short_scan = true;
+	queue_work(priv->workqueue, &priv->request_scan);
+ unlock:
+	mutex_unlock(&priv->mutex);
+}
+EXPORT_SYMBOL(iwl_internal_short_hw_scan);
+
 #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
 
 void iwl_bg_scan_check(struct work_struct *data)
@@ -551,7 +654,8 @@ u16 iwl_fill_probe_req(struct iwl_priv *
 	if (WARN_ON(left < ie_len))
 		return len;
 
-	memcpy(pos, ies, ie_len);
+	if (ies)
+		memcpy(pos, ies, ie_len);
 	len += ie_len;
 	left -= ie_len;
 
@@ -654,7 +758,6 @@ static void iwl_bg_request_scan(struct w
 		unsigned long flags;
 
 		IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
-
 		spin_lock_irqsave(&priv->lock, flags);
 		interval = priv->beacon_int;
 		spin_unlock_irqrestore(&priv->lock, flags);
@@ -672,7 +775,9 @@ static void iwl_bg_request_scan(struct w
 			       scan_suspend_time, interval);
 	}
 
-	if (priv->scan_request->n_ssids) {
+	if (priv->is_internal_short_scan) {
+		IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
+	} else if (priv->scan_request->n_ssids) {
 		int i, p = 0;
 		IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
 		for (i = 0; i < priv->scan_request->n_ssids; i++) {
@@ -708,16 +813,29 @@ static void iwl_bg_request_scan(struct w
 			rate = IWL_RATE_1M_PLCP;
 			rate_flags = RATE_MCS_CCK_MSK;
 		}
-		scan->good_CRC_th = 0;
+		scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED;
 	} else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
 		band = IEEE80211_BAND_5GHZ;
 		rate = IWL_RATE_6M_PLCP;
 		/*
-		 * If active scaning is requested but a certain channel
-		 * is marked passive, we can do active scanning if we
-		 * detect transmissions.
+		 * If active scanning is requested but a certain channel is
+		 * marked passive, we can do active scanning if we detect
+		 * transmissions.
+		 *
+		 * There is an issue with some firmware versions that triggers
+		 * a sysassert on a "good CRC threshold" of zero (== disabled),
+		 * on a radar channel even though this means that we should NOT
+		 * send probes.
+		 *
+		 * The "good CRC threshold" is the number of frames that we
+		 * need to receive during our dwell time on a channel before
+		 * sending out probes -- setting this to a huge value will
+		 * mean we never reach it, but at the same time work around
+		 * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
+		 * here instead of IWL_GOOD_CRC_TH_DISABLED.
 		 */
-		scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
+		scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+						IWL_GOOD_CRC_TH_NEVER;
 
 		/* Force use of chains B and C (0x6) for scan Rx for 4965
 		 * Avoid A (0x1) because of its off-channel reception on A-band.
@@ -753,24 +871,38 @@ static void iwl_bg_request_scan(struct w
 	rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
 	rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
 	scan->rx_chain = cpu_to_le16(rx_chain);
-	cmd_len = iwl_fill_probe_req(priv,
-				(struct ieee80211_mgmt *)scan->data,
-				priv->scan_request->ie,
-				priv->scan_request->ie_len,
-				IWL_MAX_SCAN_SIZE - sizeof(*scan));
+	if (!priv->is_internal_short_scan) {
+		cmd_len = iwl_fill_probe_req(priv,
+					(struct ieee80211_mgmt *)scan->data,
+					priv->scan_request->ie,
+					priv->scan_request->ie_len,
+					IWL_MAX_SCAN_SIZE - sizeof(*scan));
+	} else {
+		cmd_len = iwl_fill_probe_req(priv,
+					(struct ieee80211_mgmt *)scan->data,
+					NULL, 0,
+					IWL_MAX_SCAN_SIZE - sizeof(*scan));
 
+	}
 	scan->tx_cmd.len = cpu_to_le16(cmd_len);
-
 	if (iwl_is_monitor_mode(priv))
 		scan->filter_flags = RXON_FILTER_PROMISC_MSK;
 
 	scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
 			       RXON_FILTER_BCON_AWARE_MSK);
 
-	scan->channel_count =
-		iwl_get_channels_for_scan(priv, band, is_active, n_probes,
-			(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
-
+	if (priv->is_internal_short_scan) {
+		scan->channel_count =
+			iwl_get_single_channel_for_scan(priv, band,
+				(void *)&scan->data[le16_to_cpu(
+				scan->tx_cmd.len)]);
+	} else {
+		scan->channel_count =
+			iwl_get_channels_for_scan(priv, band,
+				is_active, n_probes,
+				(void *)&scan->data[le16_to_cpu(
+				scan->tx_cmd.len)]);
+	}
 	if (scan->channel_count == 0) {
 		IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
 		goto done;
@@ -831,7 +963,12 @@ void iwl_bg_scan_completed(struct work_s
 
 	cancel_delayed_work(&priv->scan_check);
 
-	ieee80211_scan_completed(priv->hw, false);
+	if (!priv->is_internal_short_scan)
+		ieee80211_scan_completed(priv->hw, false);
+	else {
+		priv->is_internal_short_scan = false;
+		IWL_DEBUG_SCAN(priv, "internal short scan completed\n");
+	}
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 		return;
@@ -849,6 +986,7 @@ void iwl_setup_scan_deferred_work(struct
 	INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
 	INIT_WORK(&priv->request_scan, iwl_bg_request_scan);
 	INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
+	INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan);
 	INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
 }
 EXPORT_SYMBOL(iwl_setup_scan_deferred_work);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,198 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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/delay.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/wireless.h>
-
-#include <net/mac80211.h>
-
-#include "iwl-eeprom.h"
-#include "iwl-dev.h"
-#include "iwl-core.h"
-#include "iwl-io.h"
-#include "iwl-spectrum.h"
-
-#define BEACON_TIME_MASK_LOW	0x00FFFFFF
-#define BEACON_TIME_MASK_HIGH	0xFF000000
-#define TIME_UNIT		1024
-
-/*
- * extended beacon time format
- * time in usec will be changed into a 32-bit value in 8:24 format
- * the high 1 byte is the beacon counts
- * the lower 3 bytes is the time in usec within one beacon interval
- */
-
-/* TOOD: was used in sysfs debug interface need to add to mac */
-#if 0
-static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
-{
-	u32 quot;
-	u32 rem;
-	u32 interval = beacon_interval * 1024;
-
-	if (!interval || !usec)
-		return 0;
-
-	quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
-	rem = (usec % interval) & BEACON_TIME_MASK_LOW;
-
-	return (quot << 24) + rem;
-}
-
-/* base is usually what we get from ucode with each received frame,
- * the same as HW timer counter counting down
- */
-
-static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
-{
-	u32 base_low = base & BEACON_TIME_MASK_LOW;
-	u32 addon_low = addon & BEACON_TIME_MASK_LOW;
-	u32 interval = beacon_interval * TIME_UNIT;
-	u32 res = (base & BEACON_TIME_MASK_HIGH) +
-	    (addon & BEACON_TIME_MASK_HIGH);
-
-	if (base_low > addon_low)
-		res += base_low - addon_low;
-	else if (base_low < addon_low) {
-		res += interval + base_low - addon_low;
-		res += (1 << 24);
-	} else
-		res += (1 << 24);
-
-	return cpu_to_le32(res);
-}
-static int iwl_get_measurement(struct iwl_priv *priv,
-			       struct ieee80211_measurement_params *params,
-			       u8 type)
-{
-	struct iwl4965_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,
-	};
-	u32 add_time = le64_to_cpu(params->start_time);
-	int rc;
-	int spectrum_resp_status;
-	int duration = le16_to_cpu(params->duration);
-
-	if (iwl_is_associated(priv))
-		add_time =
-		    iwl_usecs_to_beacons(
-			le64_to_cpu(params->start_time) - priv->last_tsf,
-			le16_to_cpu(priv->rxon_timing.beacon_interval));
-
-	memset(&spectrum, 0, sizeof(spectrum));
-
-	spectrum.channel_count = cpu_to_le16(1);
-	spectrum.flags =
-	    RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK;
-	spectrum.filter_flags = MEASUREMENT_FILTER_FLAG;
-	cmd.len = sizeof(spectrum);
-	spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
-
-	if (iwl_is_associated(priv))
-		spectrum.start_time =
-		    iwl_add_beacon_time(priv->last_beacon_time,
-				add_time,
-				le16_to_cpu(priv->rxon_timing.beacon_interval));
-	else
-		spectrum.start_time = 0;
-
-	spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
-	spectrum.channels[0].channel = params->channel;
-	spectrum.channels[0].type = type;
-	if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
-		spectrum.flags |= RXON_FLG_BAND_24G_MSK |
-		    RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
-
-	rc = iwl_send_cmd_sync(priv, &cmd);
-	if (rc)
-		return rc;
-
-	res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
-	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
-		IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
-		rc = -EIO;
-	}
-
-	spectrum_resp_status = le16_to_cpu(res->u.spectrum.status);
-	switch (spectrum_resp_status) {
-	case 0:		/* Command will be handled */
-		if (res->u.spectrum.id != 0xff) {
-			IWL_DEBUG_INFO(priv,
-				"Replaced existing measurement: %d\n",
-				res->u.spectrum.id);
-			priv->measurement_status &= ~MEASUREMENT_READY;
-		}
-		priv->measurement_status |= MEASUREMENT_ACTIVE;
-		rc = 0;
-		break;
-
-	case 1:		/* Command will not be handled */
-		rc = -EAGAIN;
-		break;
-	}
-
-	dev_kfree_skb_any(cmd.meta.u.skb);
-
-	return rc;
-}
-#endif
-
-static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
-					  struct iwl_rx_mem_buffer *rxb)
-{
-	struct iwl_rx_packet *pkt = rxb_addr(rxb);
-	struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
-
-	if (!report->state) {
-		IWL_DEBUG_11H(priv,
-			"Spectrum Measure Notification: Start\n");
-		return;
-	}
-
-	memcpy(&priv->measure_report, report, sizeof(*report));
-	priv->measurement_status |= MEASUREMENT_READY;
-}
-
-void iwl_setup_spectrum_handlers(struct iwl_priv *priv)
-{
-	priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
-			iwl_rx_spectrum_measure_notif;
-}
-EXPORT_SYMBOL(iwl_setup_spectrum_handlers);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ieee80211 subsystem header files.
  *
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 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.
@@ -80,46 +80,103 @@ int iwl_get_ra_sta_id(struct iwl_priv *p
 }
 EXPORT_SYMBOL(iwl_get_ra_sta_id);
 
+/* priv->sta_lock must be held */
 static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&priv->sta_lock, flags);
 
 	if (!(priv->stations[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(priv, "Added STA to Ucode: %pM\n",
-			priv->stations[sta_id].sta.sta.addr);
+		IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u addr %pM\n",
+			sta_id, priv->stations[sta_id].sta.sta.addr);
 
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
+	if (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) {
+		IWL_DEBUG_ASSOC(priv,
+				"STA id %u addr %pM already present in uCode (according to driver)\n",
+				sta_id, priv->stations[sta_id].sta.sta.addr);
+	} else {
+		priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
+		IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n",
+				sta_id, priv->stations[sta_id].sta.sta.addr);
+	}
 }
 
-static void iwl_add_sta_callback(struct iwl_priv *priv,
-				 struct iwl_device_cmd *cmd,
-				 struct iwl_rx_packet *pkt)
+static void iwl_process_add_sta_resp(struct iwl_priv *priv,
+				     struct iwl_addsta_cmd *addsta,
+				     struct iwl_rx_packet *pkt,
+				     bool sync)
 {
-	struct iwl_addsta_cmd *addsta =
-		(struct iwl_addsta_cmd *)cmd->cmd.payload;
 	u8 sta_id = addsta->sta.sta_id;
+	unsigned long flags;
 
 	if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
 		IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
-			  pkt->hdr.flags);
+			pkt->hdr.flags);
 		return;
 	}
 
+	IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",
+		       sta_id);
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+
 	switch (pkt->u.add_sta.status) {
 	case ADD_STA_SUCCESS_MSK:
+		IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
 		iwl_sta_ucode_activate(priv, sta_id);
-		 /* fall through */
+		break;
+	case ADD_STA_NO_ROOM_IN_TABLE:
+		IWL_ERR(priv, "Adding station %d failed, no room in table.\n",
+			sta_id);
+		break;
+	case ADD_STA_NO_BLOCK_ACK_RESOURCE:
+		IWL_ERR(priv, "Adding station %d failed, no block ack resource.\n",
+			sta_id);
+		break;
+	case ADD_STA_MODIFY_NON_EXIST_STA:
+		IWL_ERR(priv, "Attempting to modify non-existing station %d \n",
+			sta_id);
+		break;
 	default:
-		IWL_DEBUG_HC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
-			     pkt->u.add_sta.status);
+		IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
+				pkt->u.add_sta.status);
 		break;
 	}
+
+	IWL_DEBUG_INFO(priv, "%s station id %u addr %pM\n",
+		       priv->stations[sta_id].sta.mode ==
+		       STA_CONTROL_MODIFY_MSK ?  "Modified" : "Added",
+		       sta_id, priv->stations[sta_id].sta.sta.addr);
+
+	/*
+	 * XXX: The MAC address in the command buffer is often changed from
+	 * the original sent to the device. That is, the MAC address
+	 * written to the command buffer often is not the same MAC adress
+	 * read from the command buffer when the command returns. This
+	 * issue has not yet been resolved and this debugging is left to
+	 * observe the problem.
+	 */
+	IWL_DEBUG_INFO(priv, "%s station according to cmd buffer %pM\n",
+		       priv->stations[sta_id].sta.mode ==
+		       STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
+		       addsta->sta.addr);
+
+	/*
+	 * Determine if we wanted to modify or add a station,
+	 * if adding a station succeeded we have some more initialization
+	 * to do when using station notification. TODO
+	 */
+
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+}
+
+static void iwl_add_sta_callback(struct iwl_priv *priv,
+				 struct iwl_device_cmd *cmd,
+				 struct iwl_rx_packet *pkt)
+{
+	struct iwl_addsta_cmd *addsta =
+		(struct iwl_addsta_cmd *)cmd->cmd.payload;
+
+	iwl_process_add_sta_resp(priv, addsta, pkt, false);
+
 }
 
 int iwl_send_add_sta(struct iwl_priv *priv,
@@ -145,24 +202,9 @@ int iwl_send_add_sta(struct iwl_priv *pr
 	if (ret || (flags & CMD_ASYNC))
 		return ret;
 
-	pkt = (struct iwl_rx_packet *)cmd.reply_page;
-	if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
-		IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
-			  pkt->hdr.flags);
-		ret = -EIO;
-	}
-
 	if (ret == 0) {
-		switch (pkt->u.add_sta.status) {
-		case ADD_STA_SUCCESS_MSK:
-			iwl_sta_ucode_activate(priv, sta->sta.sta_id);
-			IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
-			break;
-		default:
-			ret = -EIO;
-			IWL_WARN(priv, "REPLY_ADD_STA failed\n");
-			break;
-		}
+		pkt = (struct iwl_rx_packet *)cmd.reply_page;
+		iwl_process_add_sta_resp(priv, sta, pkt, true);
 	}
 	iwl_free_pages(priv, cmd.reply_page);
 
@@ -1003,24 +1045,19 @@ int iwl_rxon_add_station(struct iwl_priv
 	struct ieee80211_sta_ht_cap *cur_ht_config = NULL;
 	u8 sta_id;
 
-	/* Add station to device's station table */
-
 	/*
-	 * XXX: This check is definitely not correct, if we're an AP
-	 *	it'll always be false which is not what we want, but
-	 *	it doesn't look like iwlagn is prepared to be an HT
-	 *	AP anyway.
+	 * Set HT capabilities. It is ok to set this struct even if not using
+	 * HT config: the priv->current_ht_config.is_ht flag will just be false
 	 */
-	if (priv->current_ht_config.is_ht) {
-		rcu_read_lock();
-		sta = ieee80211_find_sta(priv->vif, addr);
-		if (sta) {
-			memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config));
-			cur_ht_config = &ht_config;
-		}
-		rcu_read_unlock();
+	rcu_read_lock();
+	sta = ieee80211_find_sta(priv->vif, addr);
+	if (sta) {
+		memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config));
+		cur_ht_config = &ht_config;
 	}
+	rcu_read_unlock();
 
+	/* Add station to device's station table */
 	sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config);
 
 	/* Set up default rate scaling table in device's station table */
@@ -1085,6 +1122,7 @@ static void iwl_sta_init_bcast_lq(struct
  */
 void iwl_add_bcast_station(struct iwl_priv *priv)
 {
+	IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
 	iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL);
 
 	/* Set up default rate scaling table in device's station table */
@@ -1093,6 +1131,16 @@ void iwl_add_bcast_station(struct iwl_pr
 EXPORT_SYMBOL(iwl_add_bcast_station);
 
 /**
+ * iwl3945_add_bcast_station - add broadcast station into station table.
+ */
+void iwl3945_add_bcast_station(struct iwl_priv *priv)
+{
+	IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
+	iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL);
+}
+EXPORT_SYMBOL(iwl3945_add_bcast_station);
+
+/**
  * iwl_get_sta_id - Find station's index within station table
  *
  * If new IBSS station, create new entry in station table
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 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.
@@ -53,6 +53,7 @@ void iwl_update_tkip_key(struct iwl_priv
 
 int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
 void iwl_add_bcast_station(struct iwl_priv *priv);
+void iwl3945_add_bcast_station(struct iwl_priv *priv);
 int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
 void iwl_clear_stations_table(struct iwl_priv *priv);
 int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-tx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-tx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/iwl-tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2010 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.
@@ -29,6 +29,7 @@
 
 #include <linux/etherdevice.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
@@ -60,7 +61,8 @@ static const u16 default_tid_to_tx_fifo[
 static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv,
 				    struct iwl_dma_ptr *ptr, size_t size)
 {
-	ptr->addr = pci_alloc_consistent(priv->pci_dev, size, &ptr->dma);
+	ptr->addr = dma_alloc_coherent(&priv->pci_dev->dev, size, &ptr->dma,
+				       GFP_KERNEL);
 	if (!ptr->addr)
 		return -ENOMEM;
 	ptr->size = size;
@@ -73,21 +75,20 @@ static inline void iwl_free_dma_ptr(stru
 	if (unlikely(!ptr->addr))
 		return;
 
-	pci_free_consistent(priv->pci_dev, ptr->size, ptr->addr, ptr->dma);
+	dma_free_coherent(&priv->pci_dev->dev, ptr->size, ptr->addr, ptr->dma);
 	memset(ptr, 0, sizeof(*ptr));
 }
 
 /**
  * iwl_txq_update_write_ptr - Send new write index to hardware
  */
-int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
 {
 	u32 reg = 0;
-	int ret = 0;
 	int txq_id = txq->q.id;
 
 	if (txq->need_update == 0)
-		return ret;
+		return;
 
 	/* if we're trying to save power */
 	if (test_bit(STATUS_POWER_PMI, &priv->status)) {
@@ -101,7 +102,7 @@ int iwl_txq_update_write_ptr(struct iwl_
 				      txq_id, reg);
 			iwl_set_bit(priv, CSR_GP_CNTRL,
 				    CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-			return ret;
+			return;
 		}
 
 		iwl_write_direct32(priv, HBUS_TARG_WRPTR,
@@ -114,8 +115,6 @@ int iwl_txq_update_write_ptr(struct iwl_
 			    txq->q.write_ptr | (txq_id << 8));
 
 	txq->need_update = 0;
-
-	return ret;
 }
 EXPORT_SYMBOL(iwl_txq_update_write_ptr);
 
@@ -126,7 +125,7 @@ void iwl_free_tfds_in_queue(struct iwl_p
 	if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
 		priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
 	else {
-		IWL_ERR(priv, "free more than tfds_in_queue (%u:%d)\n",
+		IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n",
 			priv->stations[sta_id].tid[tid].tfds_in_queue,
 			freed);
 		priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
@@ -146,7 +145,7 @@ void iwl_tx_queue_free(struct iwl_priv *
 {
 	struct iwl_tx_queue *txq = &priv->txq[txq_id];
 	struct iwl_queue *q = &txq->q;
-	struct pci_dev *dev = priv->pci_dev;
+	struct device *dev = &priv->pci_dev->dev;
 	int i;
 
 	if (q->n_bd == 0)
@@ -163,8 +162,8 @@ void iwl_tx_queue_free(struct iwl_priv *
 
 	/* De-alloc circular buffer of TFDs */
 	if (txq->q.n_bd)
-		pci_free_consistent(dev, priv->hw_params.tfd_size *
-				    txq->q.n_bd, txq->tfds, txq->q.dma_addr);
+		dma_free_coherent(dev, priv->hw_params.tfd_size *
+				  txq->q.n_bd, txq->tfds, txq->q.dma_addr);
 
 	/* De-alloc array of per-TFD driver data */
 	kfree(txq->txb);
@@ -193,20 +192,44 @@ void iwl_cmd_queue_free(struct iwl_priv
 {
 	struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
 	struct iwl_queue *q = &txq->q;
-	struct pci_dev *dev = priv->pci_dev;
+	struct device *dev = &priv->pci_dev->dev;
 	int i;
+	bool huge = false;
 
 	if (q->n_bd == 0)
 		return;
 
+	for (; q->read_ptr != q->write_ptr;
+	     q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+		/* we have no way to tell if it is a huge cmd ATM */
+		i = get_cmd_index(q, q->read_ptr, 0);
+
+		if (txq->meta[i].flags & CMD_SIZE_HUGE) {
+			huge = true;
+			continue;
+		}
+
+		pci_unmap_single(priv->pci_dev,
+				 pci_unmap_addr(&txq->meta[i], mapping),
+				 pci_unmap_len(&txq->meta[i], len),
+				 PCI_DMA_BIDIRECTIONAL);
+	}
+	if (huge) {
+		i = q->n_window;
+		pci_unmap_single(priv->pci_dev,
+				 pci_unmap_addr(&txq->meta[i], mapping),
+				 pci_unmap_len(&txq->meta[i], len),
+				 PCI_DMA_BIDIRECTIONAL);
+	}
+
 	/* De-alloc array of command/tx buffers */
 	for (i = 0; i <= TFD_CMD_SLOTS; i++)
 		kfree(txq->cmd[i]);
 
 	/* De-alloc circular buffer of TFDs */
 	if (txq->q.n_bd)
-		pci_free_consistent(dev, priv->hw_params.tfd_size *
-				    txq->q.n_bd, txq->tfds, txq->q.dma_addr);
+		dma_free_coherent(dev, priv->hw_params.tfd_size * txq->q.n_bd,
+				  txq->tfds, txq->q.dma_addr);
 
 	/* deallocate arrays */
 	kfree(txq->cmd);
@@ -297,7 +320,7 @@ static int iwl_queue_init(struct iwl_pri
 static int iwl_tx_queue_alloc(struct iwl_priv *priv,
 			      struct iwl_tx_queue *txq, u32 id)
 {
-	struct pci_dev *dev = priv->pci_dev;
+	struct device *dev = &priv->pci_dev->dev;
 	size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX;
 
 	/* Driver private data, only for Tx (not command) queues,
@@ -316,8 +339,8 @@ static int iwl_tx_queue_alloc(struct iwl
 
 	/* Circular buffer of transmit frame descriptors (TFDs),
 	 * shared with device */
-	txq->tfds = pci_alloc_consistent(dev, tfd_sz, &txq->q.dma_addr);
-
+	txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr,
+				       GFP_KERNEL);
 	if (!txq->tfds) {
 		IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz);
 		goto error;
@@ -366,7 +389,7 @@ int iwl_tx_queue_init(struct iwl_priv *p
 	for (i = 0; i < actual_slots; i++) {
 		/* only happens for cmd queue */
 		if (i == slots_num)
-			len += IWL_MAX_SCAN_SIZE;
+			len = IWL_MAX_CMD_SIZE;
 
 		txq->cmd[i] = kmalloc(len, GFP_KERNEL);
 		if (!txq->cmd[i])
@@ -411,6 +434,26 @@ out_free_arrays:
 }
 EXPORT_SYMBOL(iwl_tx_queue_init);
 
+void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+			int slots_num, u32 txq_id)
+{
+	int actual_slots = slots_num;
+
+	if (txq_id == IWL_CMD_QUEUE_NUM)
+		actual_slots++;
+
+	memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
+
+	txq->need_update = 0;
+
+	/* Initialize queue's high/low-water marks, and head/tail indexes */
+	iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+
+	/* Tell device where to find queue */
+	priv->cfg->ops->lib->txq_init(priv, txq);
+}
+EXPORT_SYMBOL(iwl_tx_queue_reset);
+
 /**
  * iwl_hw_txq_ctx_free - Free TXQ Context
  *
@@ -422,8 +465,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv
 
 	/* Tx queues */
 	if (priv->txq) {
-		for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
-		     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
@@ -439,15 +481,15 @@ void iwl_hw_txq_ctx_free(struct iwl_priv
 EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
 
 /**
- * iwl_txq_ctx_reset - Reset TX queue context
- * Destroys all DMA structures and initialize them again
+ * iwl_txq_ctx_alloc - allocate TX queue context
+ * Allocate all Tx DMA structures and initialize them
  *
  * @param priv
  * @return error code
  */
-int iwl_txq_ctx_reset(struct iwl_priv *priv)
+int iwl_txq_ctx_alloc(struct iwl_priv *priv)
 {
-	int ret = 0;
+	int ret;
 	int txq_id, slots_num;
 	unsigned long flags;
 
@@ -505,8 +547,31 @@ int iwl_txq_ctx_reset(struct iwl_priv *p
 	return ret;
 }
 
+void iwl_txq_ctx_reset(struct iwl_priv *priv)
+{
+	int txq_id, slots_num;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	/* Turn off all Tx DMA fifos */
+	priv->cfg->ops->lib->txq_set_sched(priv, 0);
+
+	/* Tell NIC where to find the "keep warm" buffer */
+	iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	/* Alloc and init all Tx queues, including the command queue (#4) */
+	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;
+		iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
+	}
+}
+
 /**
- * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory
+ * iwl_txq_ctx_stop - Stop all Tx DMA channels
  */
 void iwl_txq_ctx_stop(struct iwl_priv *priv)
 {
@@ -526,9 +591,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *p
 				    1000);
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
-
-	/* Deallocate memory for all Tx queues */
-	iwl_hw_txq_ctx_free(priv);
 }
 EXPORT_SYMBOL(iwl_txq_ctx_stop);
 
@@ -745,7 +807,6 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 	u8 tid = 0;
 	u8 *qc = NULL;
 	unsigned long flags;
-	int ret;
 
 	spin_lock_irqsave(&priv->lock, flags);
 	if (iwl_is_rfkill(priv)) {
@@ -820,8 +881,10 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 		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 &&
+		    priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) {
 			txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
+		}
 	}
 
 	txq = &priv->txq[txq_id];
@@ -963,7 +1026,7 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 
 	/* Tell device the write index *just past* this latest filled TFD */
 	q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
-	ret = iwl_txq_update_write_ptr(priv, txq);
+	iwl_txq_update_write_ptr(priv, txq);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	/*
@@ -977,9 +1040,6 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 	if (sta_priv && sta_priv->client)
 		atomic_inc(&sta_priv->pending_frames);
 
-	if (ret)
-		return ret;
-
 	if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) {
 		if (wait_write_ptr) {
 			spin_lock_irqsave(&priv->lock, flags);
@@ -1018,7 +1078,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *pr
 	struct iwl_cmd_meta *out_meta;
 	dma_addr_t phys_addr;
 	unsigned long flags;
-	int len, ret;
+	int len;
 	u32 idx;
 	u16 fix_size;
 
@@ -1027,9 +1087,12 @@ int iwl_enqueue_hcmd(struct iwl_priv *pr
 
 	/* 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 */
+	 * we will need to increase the size of the TFD entries
+	 * Also, check to see if command buffer should not exceed the size
+	 * of device_cmd and max_cmd_size. */
 	BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
 	       !(cmd->flags & CMD_SIZE_HUGE));
+	BUG_ON(fix_size > IWL_MAX_CMD_SIZE);
 
 	if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) {
 		IWL_WARN(priv, "Not sending command - %s KILL\n",
@@ -1050,6 +1113,14 @@ int iwl_enqueue_hcmd(struct iwl_priv *pr
 
 	spin_lock_irqsave(&priv->hcmd_lock, flags);
 
+	/* If this is a huge cmd, mark the huge flag also on the meta.flags
+	 * of the _original_ cmd. This is used for DMA mapping clean up.
+	 */
+	if (cmd->flags & CMD_SIZE_HUGE) {
+		idx = get_cmd_index(q, q->write_ptr, 0);
+		txq->meta[idx].flags = CMD_SIZE_HUGE;
+	}
+
 	idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
 	out_cmd = txq->cmd[idx];
 	out_meta = &txq->meta[idx];
@@ -1073,8 +1144,8 @@ int iwl_enqueue_hcmd(struct iwl_priv *pr
 	if (cmd->flags & CMD_SIZE_HUGE)
 		out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
 	len = sizeof(struct iwl_device_cmd);
-	len += (idx == TFD_CMD_SLOTS) ?  IWL_MAX_SCAN_SIZE : 0;
-
+	if (idx == TFD_CMD_SLOTS)
+		len = IWL_MAX_CMD_SIZE;
 
 #ifdef CONFIG_IWLWIFI_DEBUG
 	switch (out_cmd->hdr.cmd) {
@@ -1115,10 +1186,10 @@ int iwl_enqueue_hcmd(struct iwl_priv *pr
 
 	/* Increment and update queue's write index */
 	q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
-	ret = iwl_txq_update_write_ptr(priv, txq);
+	iwl_txq_update_write_ptr(priv, txq);
 
 	spin_unlock_irqrestore(&priv->hcmd_lock, flags);
-	return ret ? ret : idx;
+	return idx;
 }
 
 static void iwl_tx_status(struct iwl_priv *priv, struct sk_buff *skb)
@@ -1227,6 +1298,7 @@ void iwl_tx_cmd_complete(struct iwl_priv
 	bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
 	struct iwl_device_cmd *cmd;
 	struct iwl_cmd_meta *meta;
+	struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
 
 	/* If a Tx command is being handled and it isn't in the actual
 	 * command queue then there a command routing bug has been introduced
@@ -1240,9 +1312,17 @@ void iwl_tx_cmd_complete(struct iwl_priv
 		return;
 	}
 
-	cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
-	cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
-	meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index];
+	/* If this is a huge cmd, clear the huge flag on the meta.flags
+	 * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap
+	 * the DMA buffer for the scan (huge) command.
+	 */
+	if (huge) {
+		cmd_index = get_cmd_index(&txq->q, index, 0);
+		txq->meta[cmd_index].flags = 0;
+	}
+	cmd_index = get_cmd_index(&txq->q, index, huge);
+	cmd = txq->cmd[cmd_index];
+	meta = &txq->meta[cmd_index];
 
 	pci_unmap_single(priv->pci_dev,
 			 pci_unmap_addr(meta, mapping),
@@ -1260,8 +1340,11 @@ void iwl_tx_cmd_complete(struct iwl_priv
 
 	if (!(meta->flags & CMD_ASYNC)) {
 		clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+		IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s \n",
+			       get_cmd_string(cmd->hdr.cmd));
 		wake_up_interruptible(&priv->wait_command_queue);
 	}
+	meta->flags = 0;
 }
 EXPORT_SYMBOL(iwl_tx_cmd_complete);
 
@@ -1346,7 +1429,7 @@ int iwl_tx_agg_stop(struct iwl_priv *pri
 {
 	int tx_fifo_id, txq_id, sta_id, ssn = -1;
 	struct iwl_tid_data *tid_data;
-	int ret, write_ptr, read_ptr;
+	int write_ptr, read_ptr;
 	unsigned long flags;
 
 	if (!ra) {
@@ -1398,13 +1481,17 @@ int iwl_tx_agg_stop(struct iwl_priv *pri
 	priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
 
 	spin_lock_irqsave(&priv->lock, flags);
-	ret = priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn,
+	/*
+	 * the only reason this call can fail is queue number out of range,
+	 * which can happen if uCode is reloaded and all the station
+	 * information are lost. if it is outside the range, there is no need
+	 * to deactivate the uCode queue, just return "success" to allow
+	 *  mac80211 to clean up it own data.
+	 */
+	priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn,
 						   tx_fifo_id);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	if (ret)
-		return ret;
-
 	ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/Kconfig linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,14 +1,8 @@
 config IWLWIFI
 	tristate "Intel Wireless Wifi"
-	depends on PCI && MAC80211 && EXPERIMENTAL
+	depends on PCI && MAC80211
 	select FW_LOADER
 
-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 and iwl3945 drivers"
 	depends on IWLWIFI
@@ -120,9 +114,3 @@ config IWL3945
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/kbuild/modules.txt>.  The
 	  module will be called iwl3945.
-
-config IWL3945_SPECTRUM_MEASUREMENT
-	bool "Enable Spectrum Measurement in iwl3945 driver"
-	depends on IWL3945
-	---help---
-	  This option will enable spectrum measurement for the iwl3945 driver.
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/Makefile linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwlwifi/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,6 @@ iwlcore-objs 		:= iwl-core.o iwl-eeprom.
 iwlcore-objs 		+= iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o
 iwlcore-objs 		+= iwl-scan.o iwl-led.o
 iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
-iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
 iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
 
 CFLAGS_iwl-devtrace.o := -I$(src)
@@ -20,3 +19,5 @@ iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
 # 3945
 obj-$(CONFIG_IWL3945)	+= iwl3945.o
 iwl3945-objs		:= iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o
+
+ccflags-y += -D__CHECK_ENDIAN__
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/cfg80211.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/cfg80211.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/cfg80211.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/cfg80211.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
 #include <linux/ieee80211.h>
+#include <linux/slab.h>
 #include <net/cfg80211.h>
 
 #include "iwm.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/commands.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/commands.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/commands.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/commands.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@
 #include <linux/etherdevice.h>
 #include <linux/ieee80211.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include "iwm.h"
 #include "bus.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/debugfs.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/debugfs.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/debugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/debugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/bitops.h>
 #include <linux/debugfs.h>
@@ -89,7 +90,7 @@ static int iwm_debugfs_dbg_modules_write
 	for (i = 0; i < __IWM_DM_NR; i++)
 		iwm->dbg.dbg_module[i] = 0;
 
-	for_each_bit(bit, &iwm->dbg.dbg_modules, __IWM_DM_NR)
+	for_each_set_bit(bit, &iwm->dbg.dbg_modules, __IWM_DM_NR)
 		iwm->dbg.dbg_module[bit] = iwm->dbg.dbg_level;
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/eeprom.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/eeprom.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/eeprom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/eeprom.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "iwm.h"
 #include "umac.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/hal.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/hal.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/hal.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/hal.c	2010-05-16 17:17:36.000000000 -0400
@@ -98,6 +98,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 
 #include "iwm.h"
 #include "bus.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/iwm.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/iwm.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/iwm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/iwm.h	2010-05-16 17:17:36.000000000 -0400
@@ -268,7 +268,7 @@ struct iwm_priv {
 
 	struct sk_buff_head rx_list;
 	struct list_head rx_tickets;
-	struct list_head rx_packets[IWM_RX_ID_HASH + 1];
+	struct list_head rx_packets[IWM_RX_ID_HASH];
 	struct workqueue_struct *rx_wq;
 	struct work_struct rx_worker;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/lmac.h linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/lmac.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/lmac.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/lmac.h	2010-05-16 17:17:36.000000000 -0400
@@ -262,7 +262,7 @@ struct iwm_ct_kill_cfg_cmd {
 
 /* Power Management */
 #define POWER_TABLE_CMD			0x77
-#define SAVE_RESTORE_ADRESS_CMD		0x78
+#define SAVE_RESTORE_ADDRESS_CMD		0x78
 #define REPLY_WATERMARK_CMD		0x79
 #define PM_DEBUG_STATISTIC_NOTIFIC	0x7B
 #define PD_FLUSH_N_NOTIFICATION		0x7C
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/main.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/main.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/main.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@
 #include <linux/sched.h>
 #include <linux/ieee80211.h>
 #include <linux/wireless.h>
+#include <linux/slab.h>
 
 #include "iwm.h"
 #include "debug.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/netdev.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/netdev.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/netdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/netdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,7 @@
  *              -> sdio_disable_func()
  */
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 
 #include "iwm.h"
 #include "commands.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/rx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/rx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,7 @@
 #include <linux/ieee80211.h>
 #include <linux/if_arp.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <net/iw_handler.h>
 
 #include "iwm.h"
@@ -868,36 +869,35 @@ static int iwm_mlme_mgt_frame(struct iwm
 	struct iwm_umac_notif_mgt_frame *mgt_frame =
 			(struct iwm_umac_notif_mgt_frame *)buf;
 	struct ieee80211_mgmt *mgt = (struct ieee80211_mgmt *)mgt_frame->frame;
-	u8 *ie;
 
 	IWM_HEXDUMP(iwm, DBG, MLME, "MGT: ", mgt_frame->frame,
 		    le16_to_cpu(mgt_frame->len));
 
 	if (ieee80211_is_assoc_req(mgt->frame_control)) {
-		ie = mgt->u.assoc_req.variable;;
-		iwm->req_ie_len =
-				le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
+		iwm->req_ie_len = le16_to_cpu(mgt_frame->len)
+				  - offsetof(struct ieee80211_mgmt,
+					     u.assoc_req.variable);
 		kfree(iwm->req_ie);
 		iwm->req_ie = kmemdup(mgt->u.assoc_req.variable,
 				      iwm->req_ie_len, GFP_KERNEL);
 	} else if (ieee80211_is_reassoc_req(mgt->frame_control)) {
-		ie = mgt->u.reassoc_req.variable;;
-		iwm->req_ie_len =
-				le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
+		iwm->req_ie_len = le16_to_cpu(mgt_frame->len)
+				  - offsetof(struct ieee80211_mgmt,
+					     u.reassoc_req.variable);
 		kfree(iwm->req_ie);
 		iwm->req_ie = kmemdup(mgt->u.reassoc_req.variable,
 				      iwm->req_ie_len, GFP_KERNEL);
 	} else if (ieee80211_is_assoc_resp(mgt->frame_control)) {
-		ie = mgt->u.assoc_resp.variable;;
-		iwm->resp_ie_len =
-				le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
+		iwm->resp_ie_len = le16_to_cpu(mgt_frame->len)
+				   - offsetof(struct ieee80211_mgmt,
+					      u.assoc_resp.variable);
 		kfree(iwm->resp_ie);
 		iwm->resp_ie = kmemdup(mgt->u.assoc_resp.variable,
 				       iwm->resp_ie_len, GFP_KERNEL);
 	} else if (ieee80211_is_reassoc_resp(mgt->frame_control)) {
-		ie = mgt->u.reassoc_resp.variable;;
-		iwm->resp_ie_len =
-				le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
+		iwm->resp_ie_len = le16_to_cpu(mgt_frame->len)
+				   - offsetof(struct ieee80211_mgmt,
+					      u.reassoc_resp.variable);
 		kfree(iwm->resp_ie);
 		iwm->resp_ie = kmemdup(mgt->u.reassoc_resp.variable,
 				       iwm->resp_ie_len, GFP_KERNEL);
@@ -1117,7 +1117,7 @@ static int iwm_ntf_stop_resume_tx(struct
 		return -EINVAL;
 	}
 
-	for_each_bit(bit, (unsigned long *)&tid_msk, IWM_UMAC_TID_NR) {
+	for_each_set_bit(bit, (unsigned long *)&tid_msk, IWM_UMAC_TID_NR) {
 		tid_info = &sta_info->tid_info[bit];
 
 		mutex_lock(&tid_info->mutex);
@@ -1534,6 +1534,33 @@ static void classify8023(struct sk_buff
 	}
 }
 
+static void iwm_rx_process_amsdu(struct iwm_priv *iwm, struct sk_buff *skb)
+{
+	struct wireless_dev *wdev = iwm_to_wdev(iwm);
+	struct net_device *ndev = iwm_to_ndev(iwm);
+	struct sk_buff_head list;
+	struct sk_buff *frame;
+
+	IWM_HEXDUMP(iwm, DBG, RX, "A-MSDU: ", skb->data, skb->len);
+
+	__skb_queue_head_init(&list);
+	ieee80211_amsdu_to_8023s(skb, &list, ndev->dev_addr, wdev->iftype, 0);
+
+	while ((frame = __skb_dequeue(&list))) {
+		ndev->stats.rx_packets++;
+		ndev->stats.rx_bytes += frame->len;
+
+		frame->protocol = eth_type_trans(frame, ndev);
+		frame->ip_summed = CHECKSUM_NONE;
+		memset(frame->cb, 0, sizeof(frame->cb));
+
+		if (netif_rx_ni(frame) == NET_RX_DROP) {
+			IWM_ERR(iwm, "Packet dropped\n");
+			ndev->stats.rx_dropped++;
+		}
+	}
+}
+
 static void iwm_rx_process_packet(struct iwm_priv *iwm,
 				  struct iwm_rx_packet *packet,
 				  struct iwm_rx_ticket_node *ticket_node)
@@ -1548,25 +1575,34 @@ static void iwm_rx_process_packet(struct
 	switch (le16_to_cpu(ticket_node->ticket->action)) {
 	case IWM_RX_TICKET_RELEASE:
 		IWM_DBG_RX(iwm, DBG, "RELEASE packet\n");
-		classify8023(skb);
+
 		iwm_rx_adjust_packet(iwm, packet, ticket_node);
+		skb->dev = iwm_to_ndev(iwm);
+		classify8023(skb);
+
+		if (le16_to_cpu(ticket_node->ticket->flags) &
+		    IWM_RX_TICKET_AMSDU_MSK) {
+			iwm_rx_process_amsdu(iwm, skb);
+			break;
+		}
+
 		ret = ieee80211_data_to_8023(skb, ndev->dev_addr, wdev->iftype);
 		if (ret < 0) {
 			IWM_DBG_RX(iwm, DBG, "Couldn't convert 802.11 header - "
 				   "%d\n", ret);
+			kfree_skb(packet->skb);
 			break;
 		}
 
 		IWM_HEXDUMP(iwm, DBG, RX, "802.3: ", skb->data, skb->len);
 
-		skb->dev = iwm_to_ndev(iwm);
+		ndev->stats.rx_packets++;
+		ndev->stats.rx_bytes += skb->len;
+
 		skb->protocol = eth_type_trans(skb, ndev);
 		skb->ip_summed = CHECKSUM_NONE;
 		memset(skb->cb, 0, sizeof(skb->cb));
 
-		ndev->stats.rx_packets++;
-		ndev->stats.rx_bytes += skb->len;
-
 		if (netif_rx_ni(skb) == NET_RX_DROP) {
 			IWM_ERR(iwm, "Packet dropped\n");
 			ndev->stats.rx_dropped++;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/sdio.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/sdio.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/sdio.c	2013-05-03 12:10:04.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/sdio.c	2013-05-03 09:49:35.000000000 -0400
@@ -63,6 +63,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/debugfs.h>
 #include <linux/mmc/sdio_ids.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/tx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/tx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/iwmc3200wifi/tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,6 +64,7 @@
  * (i.e. half of the max size). [iwm_tx_worker]
  */
 
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/ieee80211.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/Kconfig linux-libre-2.6.34-gnu1/drivers/net/wireless/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -112,6 +112,7 @@ config AIRO_CS
 	depends on PCMCIA && (BROKEN || !M32R)
 	select WIRELESS_EXT
 	select WEXT_SPY
+	select WEXT_PRIV
 	select CRYPTO
 	select CRYPTO_AES
 	---help---
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/assoc.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/assoc.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/assoc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/assoc.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
 #include <linux/etherdevice.h>
 #include <linux/ieee80211.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <net/lib80211.h>
 
 #include "assoc.h"
@@ -390,10 +391,8 @@ int lbs_cmd_802_11_rate_adapt_rateset(st
 	cmd.enablehwauto = cpu_to_le16(priv->enablehwauto);
 	cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto);
 	ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd);
-	if (!ret && cmd_action == CMD_ACT_GET) {
-		priv->ratebitmap = le16_to_cpu(cmd.bitmap);
+	if (!ret && cmd_action == CMD_ACT_GET)
 		priv->enablehwauto = le16_to_cpu(cmd.enablehwauto);
-	}
 
 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
 	return ret;
@@ -807,8 +806,7 @@ static int lbs_try_associate(struct lbs_
 	}
 
 	/* Use short preamble only when both the BSS and firmware support it */
-	if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
-	    (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE))
+	if (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
 		preamble = RADIO_PREAMBLE_SHORT;
 
 	ret = lbs_set_radio(priv, preamble, 1);
@@ -939,8 +937,7 @@ static int lbs_adhoc_join(struct lbs_pri
 	}
 
 	/* Use short preamble only when both the BSS and firmware support it */
-	if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
-	    (bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
+	if (bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) {
 		lbs_deb_join("AdhocJoin: Short preamble\n");
 		preamble = RADIO_PREAMBLE_SHORT;
 	}
@@ -1049,7 +1046,7 @@ static int lbs_adhoc_start(struct lbs_pr
 	struct assoc_request *assoc_req)
 {
 	struct cmd_ds_802_11_ad_hoc_start cmd;
-	u8 preamble = RADIO_PREAMBLE_LONG;
+	u8 preamble = RADIO_PREAMBLE_SHORT;
 	size_t ratesize = 0;
 	u16 tmpcap = 0;
 	int ret = 0;
@@ -1057,11 +1054,6 @@ static int lbs_adhoc_start(struct lbs_pr
 
 	lbs_deb_enter(LBS_DEB_ASSOC);
 
-	if (priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) {
-		lbs_deb_join("ADHOC_START: Will use short preamble\n");
-		preamble = RADIO_PREAMBLE_SHORT;
-	}
-
 	ret = lbs_set_radio(priv, preamble, 1);
 	if (ret)
 		goto out;
@@ -1169,11 +1161,11 @@ int lbs_adhoc_stop(struct lbs_private *p
 static inline int match_bss_no_security(struct lbs_802_11_security *secinfo,
 					struct bss_descriptor *match_bss)
 {
-	if (!secinfo->wep_enabled  && !secinfo->WPAenabled
-	    && !secinfo->WPA2enabled
-	    && match_bss->wpa_ie[0] != WLAN_EID_GENERIC
-	    && match_bss->rsn_ie[0] != WLAN_EID_RSN
-	    && !(match_bss->capability & WLAN_CAPABILITY_PRIVACY))
+	if (!secinfo->wep_enabled &&
+	    !secinfo->WPAenabled && !secinfo->WPA2enabled &&
+	    match_bss->wpa_ie[0] != WLAN_EID_GENERIC &&
+	    match_bss->rsn_ie[0] != WLAN_EID_RSN &&
+	    !(match_bss->capability & WLAN_CAPABILITY_PRIVACY))
 		return 1;
 	else
 		return 0;
@@ -1182,9 +1174,9 @@ static inline int match_bss_no_security(
 static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo,
 				       struct bss_descriptor *match_bss)
 {
-	if (secinfo->wep_enabled && !secinfo->WPAenabled
-	    && !secinfo->WPA2enabled
-	    && (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
+	if (secinfo->wep_enabled &&
+	    !secinfo->WPAenabled && !secinfo->WPA2enabled &&
+	    (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
 		return 1;
 	else
 		return 0;
@@ -1193,8 +1185,8 @@ static inline int match_bss_static_wep(s
 static inline int match_bss_wpa(struct lbs_802_11_security *secinfo,
 				struct bss_descriptor *match_bss)
 {
-	if (!secinfo->wep_enabled && secinfo->WPAenabled
-	    && (match_bss->wpa_ie[0] == WLAN_EID_GENERIC)
+	if (!secinfo->wep_enabled && secinfo->WPAenabled &&
+	    (match_bss->wpa_ie[0] == WLAN_EID_GENERIC)
 	    /* privacy bit may NOT be set in some APs like LinkSys WRT54G
 	    && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */
 	   )
@@ -1219,11 +1211,11 @@ static inline int match_bss_wpa2(struct
 static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo,
 					struct bss_descriptor *match_bss)
 {
-	if (!secinfo->wep_enabled && !secinfo->WPAenabled
-	    && !secinfo->WPA2enabled
-	    && (match_bss->wpa_ie[0] != WLAN_EID_GENERIC)
-	    && (match_bss->rsn_ie[0] != WLAN_EID_RSN)
-	    && (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
+	if (!secinfo->wep_enabled &&
+	    !secinfo->WPAenabled && !secinfo->WPA2enabled &&
+	    (match_bss->wpa_ie[0] != WLAN_EID_GENERIC) &&
+	    (match_bss->rsn_ie[0] != WLAN_EID_RSN) &&
+	    (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
 		return 1;
 	else
 		return 0;
@@ -1534,8 +1526,8 @@ static int assoc_helper_associate(struct
 	/* If we're given and 'any' BSSID, try associating based on SSID */
 
 	if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
-		if (compare_ether_addr(bssid_any, assoc_req->bssid)
-		    && compare_ether_addr(bssid_off, assoc_req->bssid)) {
+		if (compare_ether_addr(bssid_any, assoc_req->bssid) &&
+		    compare_ether_addr(bssid_off, assoc_req->bssid)) {
 			ret = assoc_helper_bssid(priv, assoc_req);
 			done = 1;
 		}
@@ -1621,11 +1613,9 @@ static int assoc_helper_channel(struct l
 		goto restore_mesh;
 	}
 
-	if (   assoc_req->secinfo.wep_enabled
-	    &&   (assoc_req->wep_keys[0].len
-	       || assoc_req->wep_keys[1].len
-	       || assoc_req->wep_keys[2].len
-	       || assoc_req->wep_keys[3].len)) {
+	if (assoc_req->secinfo.wep_enabled &&
+	    (assoc_req->wep_keys[0].len || assoc_req->wep_keys[1].len ||
+	     assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len)) {
 		/* Make sure WEP keys are re-sent to firmware */
 		set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
 	}
@@ -1992,14 +1982,14 @@ void lbs_association_worker(struct work_
 		assoc_req->secinfo.auth_mode);
 
 	/* If 'any' SSID was specified, find an SSID to associate with */
-	if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)
-	    && !assoc_req->ssid_len)
+	if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) &&
+	    !assoc_req->ssid_len)
 		find_any_ssid = 1;
 
 	/* But don't use 'any' SSID if there's a valid locked BSSID to use */
 	if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
-		if (compare_ether_addr(assoc_req->bssid, bssid_any)
-		    && compare_ether_addr(assoc_req->bssid, bssid_off))
+		if (compare_ether_addr(assoc_req->bssid, bssid_any) &&
+		    compare_ether_addr(assoc_req->bssid, bssid_off))
 			find_any_ssid = 0;
 	}
 
@@ -2061,13 +2051,6 @@ void lbs_association_worker(struct work_
 			goto out;
 	}
 
-	if (   test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)
-	    || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
-		ret = assoc_helper_wep_keys(priv, assoc_req);
-		if (ret)
-			goto out;
-	}
-
 	if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
 		ret = assoc_helper_secinfo(priv, assoc_req);
 		if (ret)
@@ -2080,18 +2063,31 @@ void lbs_association_worker(struct work_
 			goto out;
 	}
 
-	if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)
-	    || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
+	/*
+	 * v10 FW wants WPA keys to be set/cleared before WEP key operations,
+	 * otherwise it will fail to correctly associate to WEP networks.
+	 * Other firmware versions don't appear to care.
+	 */
+	if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) ||
+	    test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
 		ret = assoc_helper_wpa_keys(priv, assoc_req);
 		if (ret)
 			goto out;
 	}
 
+	if (test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) ||
+	    test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
+		ret = assoc_helper_wep_keys(priv, assoc_req);
+		if (ret)
+			goto out;
+	}
+
+
 	/* SSID/BSSID should be the _last_ config option set, because they
 	 * trigger the association attempt.
 	 */
-	if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)
-	    || test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
+	if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) ||
+	    test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
 		int success = 1;
 
 		ret = assoc_helper_associate(priv, assoc_req);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cfg.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/cfg.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cfg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/cfg.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <net/cfg80211.h>
 
 #include "cfg.h"
@@ -172,6 +173,8 @@ int lbs_cfg_register(struct lbs_private
 	if (ret < 0)
 		lbs_pr_err("cannot register wiphy device\n");
 
+	priv->wiphy_registered = true;
+
 	ret = register_netdev(priv->dev);
 	if (ret)
 		lbs_pr_err("cannot register network device\n");
@@ -190,9 +193,11 @@ void lbs_cfg_free(struct lbs_private *pr
 	if (!wdev)
 		return;
 
-	if (wdev->wiphy) {
+	if (priv->wiphy_registered)
 		wiphy_unregister(wdev->wiphy);
+
+	if (wdev->wiphy)
 		wiphy_free(wdev->wiphy);
-	}
+
 	kfree(wdev);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cmd.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/cmd.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cmd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/cmd.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
 
 #include <linux/kfifo.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include "host.h"
 #include "decl.h"
@@ -143,19 +144,6 @@ int lbs_update_hw_spec(struct lbs_privat
 	lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
 		    cmd.hwifversion, cmd.version);
 
-	/* Determine mesh_fw_ver from fwrelease and fwcapinfo */
-	/* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */
-	/* 5.110.22 have mesh command with 0xa3 command id */
-	/* 10.0.0.p0 FW brings in mesh config command with different id */
-	/* Check FW version MSB and initialize mesh_fw_ver */
-	if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5)
-		priv->mesh_fw_ver = MESH_FW_OLD;
-	else if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
-		(priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK))
-		priv->mesh_fw_ver = MESH_FW_NEW;
-	else
-		priv->mesh_fw_ver = MESH_NONE;
-
 	/* Clamp region code to 8-bit since FW spec indicates that it should
 	 * only ever be 8-bit, even though the field size is 16-bit.  Some firmware
 	 * returns non-zero high 8 bits here.
@@ -855,9 +843,6 @@ int lbs_set_radio(struct lbs_private *pr
 	if (priv->fwrelease < 0x09000000) {
 		switch (preamble) {
 		case RADIO_PREAMBLE_SHORT:
-			if (!(priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE))
-				goto out;
-			/* Fall through */
 		case RADIO_PREAMBLE_AUTO:
 		case RADIO_PREAMBLE_LONG:
 			cmd.control = cpu_to_le16(preamble);
@@ -1011,6 +996,8 @@ int lbs_prepare_and_send_command(struct
 		ret = 0;
 		break;
 
+#ifdef CONFIG_LIBERTAS_MESH
+
 	case CMD_BT_ACCESS:
 		ret = lbs_cmd_bt_access(cmdptr, cmd_action, pdata_buf);
 		break;
@@ -1019,6 +1006,8 @@ int lbs_prepare_and_send_command(struct
 		ret = lbs_cmd_fwt_access(cmdptr, cmd_action, pdata_buf);
 		break;
 
+#endif
+
 	case CMD_802_11_BEACON_CTRL:
 		ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action);
 		break;
@@ -1317,7 +1306,7 @@ int lbs_execute_next_command(struct lbs_
 		if ((priv->psmode != LBS802_11POWERMODECAM) &&
 		    (priv->psstate == PS_STATE_FULL_POWER) &&
 		    ((priv->connect_status == LBS_CONNECTED) ||
-		    (priv->mesh_connect_status == LBS_CONNECTED))) {
+		    lbs_mesh_connected(priv))) {
 			if (priv->secinfo.WPAenabled ||
 			    priv->secinfo.WPA2enabled) {
 				/* check for valid WPA group keys */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cmd.h linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/cmd.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cmd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/cmd.h	2010-05-16 17:17:36.000000000 -0400
@@ -110,18 +110,6 @@ int lbs_set_snmp_mib(struct lbs_private
 int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val);
 
 
-/* Mesh related */
-
-int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
-		    struct cmd_ds_mesh_access *cmd);
-
-int lbs_mesh_config_send(struct lbs_private *priv,
-			 struct cmd_ds_mesh_config *cmd,
-			 uint16_t action, uint16_t type);
-
-int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
-
-
 /* Commands only used in wext.c, assoc. and scan.c */
 
 int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cmdresp.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/cmdresp.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cmdresp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/cmdresp.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
   * This file contains the handling of command
   * responses as well as events generated by firmware.
   */
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/if_arp.h>
@@ -240,11 +241,6 @@ int lbs_process_command_response(struct
 	/* Now we got response from FW, cancel the command timer */
 	del_timer(&priv->command_timer);
 	priv->cmd_timed_out = 0;
-	if (priv->nr_retries) {
-		lbs_pr_info("Received result %x to command %x after %d retries\n",
-			    result, curcmd, priv->nr_retries);
-		priv->nr_retries = 0;
-	}
 
 	/* Store the response code to cur_cmd_retcode. */
 	priv->cur_cmd_retcode = result;
@@ -485,20 +481,8 @@ int lbs_process_event(struct lbs_private
 		break;
 
 	case MACREG_INT_CODE_MESH_AUTO_STARTED:
-		/* Ignore spurious autostart events if autostart is disabled */
-		if (!priv->mesh_autostart_enabled) {
-			lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n");
-			break;
-		}
-		lbs_pr_info("EVENT: MESH_AUTO_STARTED\n");
-		priv->mesh_connect_status = LBS_CONNECTED;
-		if (priv->mesh_open) {
-			netif_carrier_on(priv->mesh_dev);
-			if (!priv->tx_pending_len)
-				netif_wake_queue(priv->mesh_dev);
-		}
-		priv->mode = IW_MODE_ADHOC;
-		schedule_work(&priv->sync_channel);
+		/* Ignore spurious autostart events */
+		lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n");
 		break;
 
 	default:
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/debugfs.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/debugfs.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/debugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/debugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
 #include <linux/delay.h>
 #include <linux/mm.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <net/iw_handler.h>
 #include <net/lib80211.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/defs.h linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/defs.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/defs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/defs.h	2010-05-16 17:17:36.000000000 -0400
@@ -397,13 +397,6 @@ enum KEY_INFO_WPA {
 	KEY_INFO_WPA_ENABLED = 0x04
 };
 
-/** mesh_fw_ver */
-enum _mesh_fw_ver {
-	MESH_NONE = 0, /* MESH is not supported */
-	MESH_FW_OLD,   /* MESH is supported in FW V5 */
-	MESH_FW_NEW,   /* MESH is supported in FW V10 and newer */
-};
-
 /* Default values for fwt commands. */
 #define FWT_DEFAULT_METRIC 0
 #define FWT_DEFAULT_DIR 1
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/dev.h linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/dev.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/dev.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/dev.h	2010-05-16 17:17:36.000000000 -0400
@@ -36,18 +36,18 @@ struct lbs_private {
 
 	/* CFG80211 */
 	struct wireless_dev *wdev;
+	bool wiphy_registered;
 
 	/* Mesh */
 	struct net_device *mesh_dev; /* Virtual device */
+#ifdef CONFIG_LIBERTAS_MESH
 	u32 mesh_connect_status;
 	struct lbs_mesh_stats mstats;
 	int mesh_open;
-	int mesh_fw_ver;
-	int mesh_autostart_enabled;
 	uint16_t mesh_tlv;
 	u8 mesh_ssid[IEEE80211_MAX_SSID_LEN + 1];
 	u8 mesh_ssid_len;
-	struct work_struct sync_channel;
+#endif
 
 	/* Monitor mode */
 	struct net_device *rtap_net_dev;
@@ -110,7 +110,6 @@ struct lbs_private {
 	struct list_head cmdpendingq; /* pending command buffers */
 	wait_queue_head_t cmd_pending;
 	struct timer_list command_timer;
-	int nr_retries;
 	int cmd_timed_out;
 
 	/* Command responses sent from the hardware to the driver */
@@ -176,9 +175,7 @@ struct lbs_private {
 	struct bss_descriptor *networks;
 	struct assoc_request * pending_assoc_req;
 	struct assoc_request * in_progress_assoc_req;
-	u16 capability;
 	uint16_t enablehwauto;
-	uint16_t ratebitmap;
 
 	/* ADHOC */
 	u16 beacon_period;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/ethtool.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/ethtool.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/ethtool.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/ethtool.c	2010-05-16 17:17:36.000000000 -0400
@@ -114,9 +114,11 @@ const struct ethtool_ops lbs_ethtool_ops
 	.get_drvinfo = lbs_ethtool_get_drvinfo,
 	.get_eeprom =  lbs_ethtool_get_eeprom,
 	.get_eeprom_len = lbs_ethtool_get_eeprom_len,
+#ifdef CONFIG_LIBERTAS_MESH
 	.get_sset_count = lbs_mesh_ethtool_get_sset_count,
 	.get_ethtool_stats = lbs_mesh_ethtool_get_stats,
 	.get_strings = lbs_mesh_ethtool_get_strings,
+#endif
 	.get_wol = lbs_ethtool_get_wol,
 	.set_wol = lbs_ethtool_set_wol,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_cs.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/if_cs.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_cs.c	2013-05-03 12:10:08.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/if_cs.c	2013-05-03 09:49:40.000000000 -0400
@@ -22,6 +22,7 @@
 */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_sdio.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/if_sdio.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_sdio.c	2013-05-03 12:10:10.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/if_sdio.c	2013-05-03 09:49:42.000000000 -0400
@@ -28,6 +28,7 @@
 
 #include <linux/kernel.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/netdevice.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_spi.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/if_spi.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_spi.c	2013-05-03 12:10:13.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/if_spi.c	2013-05-03 09:49:44.000000000 -0400
@@ -23,6 +23,8 @@
 #include <linux/kthread.h>
 #include <linux/list.h>
 #include <linux/netdevice.h>
+#include <linux/semaphore.h>
+#include <linux/slab.h>
 #include <linux/spi/libertas_spi.h>
 #include <linux/spi/spi.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_usb.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/if_usb.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_usb.c	2013-05-03 12:10:15.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/if_usb.c	2013-05-03 09:49:46.000000000 -0400
@@ -5,6 +5,7 @@
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #ifdef CONFIG_OLPC
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/Kconfig linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -37,3 +37,9 @@ config LIBERTAS_DEBUG
 	depends on LIBERTAS
 	---help---
 	  Debugging support.
+
+config LIBERTAS_MESH
+	bool "Enable mesh support"
+	depends on LIBERTAS
+	help
+	  This enables Libertas' MESH support, used by e.g. the OLPC people.
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/main.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/main.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/main.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/kfifo.h>
 #include <linux/stddef.h>
 #include <linux/ieee80211.h>
+#include <linux/slab.h>
 #include <net/iw_handler.h>
 #include <net/cfg80211.h>
 
@@ -123,7 +124,7 @@ static ssize_t lbs_rtap_set(struct devic
 		if (priv->monitormode == monitor_mode)
 			return strlen(buf);
 		if (!priv->monitormode) {
-			if (priv->infra_open || priv->mesh_open)
+			if (priv->infra_open || lbs_mesh_open(priv))
 				return -EBUSY;
 			if (priv->mode == IW_MODE_INFRA)
 				lbs_cmd_80211_deauthenticate(priv,
@@ -319,15 +320,18 @@ static int lbs_add_mcast_addrs(struct cm
 {
 	int i = nr_addrs;
 	struct dev_mc_list *mc_list;
+	int cnt;
 
 	if ((dev->flags & (IFF_UP|IFF_MULTICAST)) != (IFF_UP|IFF_MULTICAST))
 		return nr_addrs;
 
 	netif_addr_lock_bh(dev);
-	for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) {
+	cnt = netdev_mc_count(dev);
+	netdev_for_each_mc_addr(mc_list, dev) {
 		if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) {
 			lbs_deb_net("mcast address %s:%pM skipped\n", dev->name,
 				    mc_list->dmi_addr);
+			cnt--;
 			continue;
 		}
 
@@ -337,9 +341,10 @@ static int lbs_add_mcast_addrs(struct cm
 		lbs_deb_net("mcast address %s:%pM added to filter\n", dev->name,
 			    mc_list->dmi_addr);
 		i++;
+		cnt--;
 	}
 	netif_addr_unlock_bh(dev);
-	if (mc_list)
+	if (cnt)
 		return -EOVERFLOW;
 
 	return i;
@@ -536,31 +541,14 @@ static int lbs_thread(void *data)
 		if (priv->cmd_timed_out && priv->cur_cmd) {
 			struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
 
-			if (++priv->nr_retries > 3) {
-				lbs_pr_info("Excessive timeouts submitting "
-					"command 0x%04x\n",
-					le16_to_cpu(cmdnode->cmdbuf->command));
-				lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
-				priv->nr_retries = 0;
-				if (priv->reset_card)
-					priv->reset_card(priv);
-			} else {
-				priv->cur_cmd = NULL;
-				priv->dnld_sent = DNLD_RES_RECEIVED;
-				lbs_pr_info("requeueing command 0x%04x due "
-					"to timeout (#%d)\n",
-					le16_to_cpu(cmdnode->cmdbuf->command),
-					priv->nr_retries);
-
-				/* Stick it back at the _top_ of the pending queue
-				   for immediate resubmission */
-				list_add(&cmdnode->list, &priv->cmdpendingq);
-			}
+			lbs_pr_info("Timeout submitting command 0x%04x\n",
+				le16_to_cpu(cmdnode->cmdbuf->command));
+			lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
+			if (priv->reset_card)
+				priv->reset_card(priv);
 		}
 		priv->cmd_timed_out = 0;
 
-
-
 		if (!priv->fw_ready)
 			continue;
 
@@ -622,7 +610,7 @@ static int lbs_thread(void *data)
 				if (priv->connect_status == LBS_CONNECTED)
 					netif_wake_queue(priv->dev);
 				if (priv->mesh_dev &&
-				    priv->mesh_connect_status == LBS_CONNECTED)
+				    lbs_mesh_connected(priv))
 					netif_wake_queue(priv->mesh_dev);
 			}
 		}
@@ -732,7 +720,7 @@ done:
  *  This function handles the timeout of command sending.
  *  It will re-send the same command again.
  */
-static void command_timer_fn(unsigned long data)
+static void lbs_cmd_timeout_handler(unsigned long data)
 {
 	struct lbs_private *priv = (struct lbs_private *)data;
 	unsigned long flags;
@@ -809,18 +797,6 @@ int lbs_exit_auto_deep_sleep(struct lbs_
 	return 0;
 }
 
-static void lbs_sync_channel_worker(struct work_struct *work)
-{
-	struct lbs_private *priv = container_of(work, struct lbs_private,
-		sync_channel);
-
-	lbs_deb_enter(LBS_DEB_MAIN);
-	if (lbs_update_channel(priv))
-		lbs_pr_info("Channel synchronization failed.");
-	lbs_deb_leave(LBS_DEB_MAIN);
-}
-
-
 static int lbs_init_adapter(struct lbs_private *priv)
 {
 	size_t bufsize;
@@ -848,14 +824,12 @@ static int lbs_init_adapter(struct lbs_p
 	memset(priv->current_addr, 0xff, ETH_ALEN);
 
 	priv->connect_status = LBS_DISCONNECTED;
-	priv->mesh_connect_status = LBS_DISCONNECTED;
 	priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
 	priv->mode = IW_MODE_INFRA;
 	priv->channel = DEFAULT_AD_HOC_CHANNEL;
 	priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
 	priv->radio_on = 1;
 	priv->enablehwauto = 1;
-	priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
 	priv->psmode = LBS802_11POWERMODECAM;
 	priv->psstate = PS_STATE_FULL_POWER;
 	priv->is_deep_sleep = 0;
@@ -865,7 +839,7 @@ static int lbs_init_adapter(struct lbs_p
 
 	mutex_init(&priv->lock);
 
-	setup_timer(&priv->command_timer, command_timer_fn,
+	setup_timer(&priv->command_timer, lbs_cmd_timeout_handler,
 		(unsigned long)priv);
 	setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn,
 			(unsigned long)priv);
@@ -998,11 +972,6 @@ struct lbs_private *lbs_add_card(void *c
 	INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker);
 	INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
 	INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
-	INIT_WORK(&priv->sync_channel, lbs_sync_channel_worker);
-
-	priv->mesh_open = 0;
-	sprintf(priv->mesh_ssid, "mesh");
-	priv->mesh_ssid_len = 4;
 
 	priv->wol_criteria = 0xffffffff;
 	priv->wol_gpio = 0xff;
@@ -1076,6 +1045,17 @@ void lbs_remove_card(struct lbs_private
 EXPORT_SYMBOL_GPL(lbs_remove_card);
 
 
+static int lbs_rtap_supported(struct lbs_private *priv)
+{
+	if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5)
+		return 1;
+
+	/* newer firmware use a capability mask */
+	return ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
+		(priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK));
+}
+
+
 int lbs_start_card(struct lbs_private *priv)
 {
 	struct net_device *dev = priv->dev;
@@ -1095,12 +1075,14 @@ int lbs_start_card(struct lbs_private *p
 
 	lbs_update_channel(priv);
 
+	lbs_init_mesh(priv);
+
 	/*
 	 * While rtap isn't related to mesh, only mesh-enabled
 	 * firmware implements the rtap functionality via
 	 * CMD_802_11_MONITOR_MODE.
 	 */
-	if (lbs_init_mesh(priv)) {
+	if (lbs_rtap_supported(priv)) {
 		if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
 			lbs_pr_err("cannot register lbs_rtap attribute\n");
 	}
@@ -1134,7 +1116,9 @@ void lbs_stop_card(struct lbs_private *p
 	netif_carrier_off(dev);
 
 	lbs_debugfs_remove_one(priv);
-	if (lbs_deinit_mesh(priv))
+	lbs_deinit_mesh(priv);
+
+	if (lbs_rtap_supported(priv))
 		device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
 
 	/* Delete the timeout of the currently processing command */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/Makefile linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,11 +5,11 @@ libertas-y += cmdresp.o
 libertas-y += debugfs.o
 libertas-y += ethtool.o
 libertas-y += main.o
-libertas-y += mesh.o
 libertas-y += rx.o
 libertas-y += scan.o
 libertas-y += tx.o
 libertas-y += wext.o
+libertas-$(CONFIG_LIBERTAS_MESH) += mesh.o
 
 usb8xxx-objs += if_usb.o
 libertas_cs-objs += if_cs.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/mesh.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/mesh.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/mesh.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/mesh.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,3 @@
-#include <linux/moduleparam.h>
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/netdevice.h>
@@ -197,7 +196,14 @@ int lbs_init_mesh(struct lbs_private *pr
 
 	lbs_deb_enter(LBS_DEB_MESH);
 
-	if (priv->mesh_fw_ver == MESH_FW_OLD) {
+	priv->mesh_connect_status = LBS_DISCONNECTED;
+
+	/* Determine mesh_fw_ver from fwrelease and fwcapinfo */
+	/* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */
+	/* 5.110.22 have mesh command with 0xa3 command id */
+	/* 10.0.0.p0 FW brings in mesh config command with different id */
+	/* Check FW version MSB and initialize mesh_fw_ver */
+	if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) {
 		/* Enable mesh, if supported, and work out which TLV it uses.
 		   0x100 + 291 is an unofficial value used in 5.110.20.pXX
 		   0x100 + 37 is the official value used in 5.110.21.pXX
@@ -219,7 +225,9 @@ int lbs_init_mesh(struct lbs_private *pr
 					    priv->channel))
 				priv->mesh_tlv = 0;
 		}
-	} else if (priv->mesh_fw_ver == MESH_FW_NEW) {
+	} else
+	if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
+		(priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK)) {
 		/* 10.0.0.pXX new firmwares should succeed with TLV
 		 * 0x100+37; Do not invoke command with old TLV.
 		 */
@@ -228,7 +236,12 @@ int lbs_init_mesh(struct lbs_private *pr
 				    priv->channel))
 			priv->mesh_tlv = 0;
 	}
+
+
 	if (priv->mesh_tlv) {
+		sprintf(priv->mesh_ssid, "mesh");
+		priv->mesh_ssid_len = 4;
+
 		lbs_add_mesh(priv);
 
 		if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
@@ -416,10 +429,10 @@ struct net_device *lbs_mesh_set_dev(stru
 	struct net_device *dev, struct rxpd *rxpd)
 {
 	if (priv->mesh_dev) {
-		if (priv->mesh_fw_ver == MESH_FW_OLD) {
+		if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID) {
 			if (rxpd->rx_control & RxPD_MESH_FRAME)
 				dev = priv->mesh_dev;
-		} else if (priv->mesh_fw_ver == MESH_FW_NEW) {
+		} else if (priv->mesh_tlv == TLV_TYPE_MESH_ID) {
 			if (rxpd->u.bss.bss_num == MESH_IFACE_ID)
 				dev = priv->mesh_dev;
 		}
@@ -432,9 +445,9 @@ void lbs_mesh_set_txpd(struct lbs_privat
 	struct net_device *dev, struct txpd *txpd)
 {
 	if (dev == priv->mesh_dev) {
-		if (priv->mesh_fw_ver == MESH_FW_OLD)
+		if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID)
 			txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
-		else if (priv->mesh_fw_ver == MESH_FW_NEW)
+		else if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
 			txpd->u.bss.bss_num = MESH_IFACE_ID;
 	}
 }
@@ -538,7 +551,7 @@ static int __lbs_mesh_config_send(struct
 	 * Command id is 0xac for v10 FW along with mesh interface
 	 * id in bits 14-13-12.
 	 */
-	if (priv->mesh_fw_ver == MESH_FW_NEW)
+	if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
 		command = CMD_MESH_CONFIG |
 			  (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/mesh.h linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/mesh.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/mesh.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/mesh.h	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,8 @@
 #include <net/lib80211.h>
 
 
+#ifdef CONFIG_LIBERTAS_MESH
+
 /* Mesh statistics */
 struct lbs_mesh_stats {
 	u32	fwd_bcast_cnt;		/* Fwd: Broadcast counter */
@@ -46,11 +48,20 @@ void lbs_mesh_set_txpd(struct lbs_privat
 /* Command handling */
 
 struct cmd_ds_command;
+struct cmd_ds_mesh_access;
+struct cmd_ds_mesh_config;
 
 int lbs_cmd_bt_access(struct cmd_ds_command *cmd,
 	u16 cmd_action, void *pdata_buf);
 int lbs_cmd_fwt_access(struct cmd_ds_command *cmd,
 	u16 cmd_action, void *pdata_buf);
+int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
+		    struct cmd_ds_mesh_access *cmd);
+int lbs_mesh_config_send(struct lbs_private *priv,
+			 struct cmd_ds_mesh_config *cmd,
+			 uint16_t action, uint16_t type);
+int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
+
 
 
 /* Persistent configuration */
@@ -75,4 +86,25 @@ void lbs_mesh_ethtool_get_strings(struct
 	uint32_t stringset, uint8_t *s);
 
 
+/* Accessors */
+
+#define lbs_mesh_open(priv) (priv->mesh_open)
+#define lbs_mesh_connected(priv) (priv->mesh_connect_status == LBS_CONNECTED)
+
+#else
+
+#define lbs_init_mesh(priv)
+#define lbs_deinit_mesh(priv)
+#define lbs_add_mesh(priv)
+#define lbs_remove_mesh(priv)
+#define lbs_mesh_set_dev(priv, dev, rxpd) (dev)
+#define lbs_mesh_set_txpd(priv, dev, txpd)
+#define lbs_mesh_config(priv, enable, chan)
+#define lbs_mesh_open(priv) (0)
+#define lbs_mesh_connected(priv) (0)
+
+#endif
+
+
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/rx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/rx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
   * This file contains the handling of RX in wlan driver.
   */
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include "host.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/scan.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/scan.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/scan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/scan.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
   * IOCTL handlers as well as command preperation and response routines
   *  for sending scan commands to the firmware.
   */
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/etherdevice.h>
@@ -635,7 +636,7 @@ out:
 	if (priv->connect_status == LBS_CONNECTED && !priv->tx_pending_len)
 		netif_wake_queue(priv->dev);
 
-	if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED) &&
+	if (priv->mesh_dev && lbs_mesh_connected(priv) &&
 	    !priv->tx_pending_len)
 		netif_wake_queue(priv->mesh_dev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/tx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/tx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -198,7 +198,7 @@ void lbs_send_tx_feedback(struct lbs_pri
 	if (priv->connect_status == LBS_CONNECTED)
 		netif_wake_queue(priv->dev);
 
-	if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED))
+	if (priv->mesh_dev && lbs_mesh_connected(priv))
 		netif_wake_queue(priv->mesh_dev);
 }
 EXPORT_SYMBOL_GPL(lbs_send_tx_feedback);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/wext.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/wext.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/wext.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas/wext.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
   * This file contains ioctl functions
   */
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/if.h>
 #include <linux/if_arp.h>
@@ -192,7 +193,7 @@ static void copy_active_data_rates(struc
 	lbs_deb_enter(LBS_DEB_WEXT);
 
 	if ((priv->connect_status != LBS_CONNECTED) &&
-		(priv->mesh_connect_status != LBS_CONNECTED))
+		!lbs_mesh_connected(priv))
 		memcpy(rates, lbs_bg_rates, MAX_RATES);
 	else
 		memcpy(rates, priv->curbssparams.rates, MAX_RATES);
@@ -298,6 +299,7 @@ static int lbs_get_nick(struct net_devic
 	return 0;
 }
 
+#ifdef CONFIG_LIBERTAS_MESH
 static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
 			 struct iw_point *dwrq, char *extra)
 {
@@ -307,7 +309,7 @@ static int mesh_get_nick(struct net_devi
 
 	/* Use nickname to indicate that mesh is on */
 
-	if (priv->mesh_connect_status == LBS_CONNECTED) {
+	if (lbs_mesh_connected(priv)) {
 		strncpy(extra, "Mesh", 12);
 		extra[12] = '\0';
 		dwrq->length = strlen(extra);
@@ -321,6 +323,7 @@ static int mesh_get_nick(struct net_devi
 	lbs_deb_leave(LBS_DEB_WEXT);
 	return 0;
 }
+#endif
 
 static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
 			struct iw_param *vwrq, char *extra)
@@ -422,6 +425,7 @@ static int lbs_get_mode(struct net_devic
 	return 0;
 }
 
+#ifdef CONFIG_LIBERTAS_MESH
 static int mesh_wlan_get_mode(struct net_device *dev,
 		              struct iw_request_info *info, u32 * uwrq,
 			      char *extra)
@@ -433,6 +437,7 @@ static int mesh_wlan_get_mode(struct net
 	lbs_deb_leave(LBS_DEB_WEXT);
 	return 0;
 }
+#endif
 
 static int lbs_get_txpow(struct net_device *dev,
 			  struct iw_request_info *info,
@@ -863,7 +868,7 @@ static struct iw_statistics *lbs_get_wir
 
 	/* If we're not associated, all quality values are meaningless */
 	if ((priv->connect_status != LBS_CONNECTED) &&
-	    (priv->mesh_connect_status != LBS_CONNECTED))
+	    !lbs_mesh_connected(priv))
 		goto out;
 
 	/* Quality by RSSI */
@@ -1010,6 +1015,7 @@ out:
 	return ret;
 }
 
+#ifdef CONFIG_LIBERTAS_MESH
 static int lbs_mesh_set_freq(struct net_device *dev,
 			     struct iw_request_info *info,
 			     struct iw_freq *fwrq, char *extra)
@@ -1061,6 +1067,7 @@ out:
 	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
 	return ret;
 }
+#endif
 
 static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
 		  struct iw_param *vwrq, char *extra)
@@ -2108,6 +2115,7 @@ out:
 	return ret;
 }
 
+#ifdef CONFIG_LIBERTAS_MESH
 static int lbs_mesh_get_essid(struct net_device *dev,
 			      struct iw_request_info *info,
 			      struct iw_point *dwrq, char *extra)
@@ -2161,6 +2169,7 @@ static int lbs_mesh_set_essid(struct net
 	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
 	return ret;
 }
+#endif
 
 /**
  *  @brief Connect to the AP or Ad-hoc Network with specific bssid
@@ -2267,7 +2276,13 @@ static const iw_handler lbs_handler[] =
 	(iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
 	(iw_handler) NULL,		/* SIOCSIWPMKSA */
 };
+struct iw_handler_def lbs_handler_def = {
+	.num_standard	= ARRAY_SIZE(lbs_handler),
+	.standard	= (iw_handler *) lbs_handler,
+	.get_wireless_stats = lbs_get_wireless_stats,
+};
 
+#ifdef CONFIG_LIBERTAS_MESH
 static const iw_handler mesh_wlan_handler[] = {
 	(iw_handler) NULL,	/* SIOCSIWCOMMIT */
 	(iw_handler) lbs_get_name,	/* SIOCGIWNAME */
@@ -2325,14 +2340,10 @@ static const iw_handler mesh_wlan_handle
 	(iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
 	(iw_handler) NULL,		/* SIOCSIWPMKSA */
 };
-struct iw_handler_def lbs_handler_def = {
-	.num_standard	= ARRAY_SIZE(lbs_handler),
-	.standard	= (iw_handler *) lbs_handler,
-	.get_wireless_stats = lbs_get_wireless_stats,
-};
 
 struct iw_handler_def mesh_handler_def = {
 	.num_standard	= ARRAY_SIZE(mesh_wlan_handler),
 	.standard	= (iw_handler *) mesh_wlan_handler,
 	.get_wireless_stats = lbs_get_wireless_stats,
 };
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas_tf/cmd.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas_tf/cmd.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas_tf/cmd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas_tf/cmd.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,8 @@
  *  the Free Software Foundation; either version 2 of the License, or (at
  *  your option) any later version.
  */
+#include <linux/slab.h>
+
 #include "libertas_tf.h"
 
 static const struct channel_range channel_ranges[] = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas_tf/if_usb.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas_tf/if_usb.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas_tf/if_usb.c	2013-05-03 12:10:19.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas_tf/if_usb.c	2013-05-03 09:49:50.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #define DRV_NAME "lbtf_usb"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas_tf/main.c linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas_tf/main.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas_tf/main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/libertas_tf/main.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,8 @@
  *  the Free Software Foundation; either version 2 of the License, or (at
  *  your option) any later version.
  */
+#include <linux/slab.h>
+
 #include "libertas_tf.h"
 #include "linux/etherdevice.h"
 
@@ -318,14 +320,14 @@ static void lbtf_op_stop(struct ieee8021
 }
 
 static int lbtf_op_add_interface(struct ieee80211_hw *hw,
-			struct ieee80211_if_init_conf *conf)
+			struct ieee80211_vif *vif)
 {
 	struct lbtf_private *priv = hw->priv;
 	if (priv->vif != NULL)
 		return -EOPNOTSUPP;
 
-	priv->vif = conf->vif;
-	switch (conf->type) {
+	priv->vif = vif;
+	switch (vif->type) {
 	case NL80211_IFTYPE_MESH_POINT:
 	case NL80211_IFTYPE_AP:
 		lbtf_set_mode(priv, LBTF_AP_MODE);
@@ -337,12 +339,12 @@ static int lbtf_op_add_interface(struct
 		priv->vif = NULL;
 		return -EOPNOTSUPP;
 	}
-	lbtf_set_mac_address(priv, (u8 *) conf->mac_addr);
+	lbtf_set_mac_address(priv, (u8 *) vif->addr);
 	return 0;
 }
 
 static void lbtf_op_remove_interface(struct ieee80211_hw *hw,
-			struct ieee80211_if_init_conf *conf)
+			struct ieee80211_vif *vif)
 {
 	struct lbtf_private *priv = hw->priv;
 
@@ -555,6 +557,9 @@ struct lbtf_private *lbtf_add_card(void
 	priv->band.n_channels = ARRAY_SIZE(lbtf_channels);
 	priv->band.channels = priv->channels;
 	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
+	hw->wiphy->interface_modes =
+		BIT(NL80211_IFTYPE_STATION) |
+		BIT(NL80211_IFTYPE_ADHOC);
 	skb_queue_head_init(&priv->bc_ps_buf);
 
 	SET_IEEE80211_DEV(hw, dmdev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/mac80211_hwsim.c linux-libre-2.6.34-gnu1/drivers/net/wireless/mac80211_hwsim.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/mac80211_hwsim.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/mac80211_hwsim.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
  */
 
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <net/dst.h>
 #include <net/xfrm.h>
@@ -32,6 +33,10 @@ static int radios = 2;
 module_param(radios, int, 0444);
 MODULE_PARM_DESC(radios, "Number of simulated radios");
 
+static bool fake_hw_scan;
+module_param(fake_hw_scan, bool, 0444);
+MODULE_PARM_DESC(fake_hw_scan, "Install fake (no-op) hw-scan handler");
+
 /**
  * enum hwsim_regtest - the type of regulatory tests we offer
  *
@@ -281,6 +286,8 @@ struct mac80211_hwsim_data {
 	struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
 	struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
 
+	struct mac_address addresses[2];
+
 	struct ieee80211_channel *channel;
 	unsigned long beacon_int; /* in jiffies unit */
 	unsigned int rx_filter;
@@ -436,6 +443,38 @@ static bool hwsim_ps_rx_ok(struct mac802
 }
 
 
+struct mac80211_hwsim_addr_match_data {
+	bool ret;
+	const u8 *addr;
+};
+
+static void mac80211_hwsim_addr_iter(void *data, u8 *mac,
+				     struct ieee80211_vif *vif)
+{
+	struct mac80211_hwsim_addr_match_data *md = data;
+	if (memcmp(mac, md->addr, ETH_ALEN) == 0)
+		md->ret = true;
+}
+
+
+static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data,
+				      const u8 *addr)
+{
+	struct mac80211_hwsim_addr_match_data md;
+
+	if (memcmp(addr, data->hw->wiphy->perm_addr, ETH_ALEN) == 0)
+		return true;
+
+	md.ret = false;
+	md.addr = addr;
+	ieee80211_iterate_active_interfaces_atomic(data->hw,
+						   mac80211_hwsim_addr_iter,
+						   &md);
+
+	return md.ret;
+}
+
+
 static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
 				    struct sk_buff *skb)
 {
@@ -488,8 +527,7 @@ static bool mac80211_hwsim_tx_frame(stru
 		if (nskb == NULL)
 			continue;
 
-		if (memcmp(hdr->addr1, data2->hw->wiphy->perm_addr,
-			   ETH_ALEN) == 0)
+		if (mac80211_hwsim_addr_match(data2, hdr->addr1))
 			ack = true;
 		memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status));
 		ieee80211_rx_irqsafe(data2->hw, nskb);
@@ -553,24 +591,24 @@ static void mac80211_hwsim_stop(struct i
 
 
 static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
-					struct ieee80211_if_init_conf *conf)
+					struct ieee80211_vif *vif)
 {
 	printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n",
-	       wiphy_name(hw->wiphy), __func__, conf->type,
-	       conf->mac_addr);
-	hwsim_set_magic(conf->vif);
+	       wiphy_name(hw->wiphy), __func__, vif->type,
+	       vif->addr);
+	hwsim_set_magic(vif);
 	return 0;
 }
 
 
 static void mac80211_hwsim_remove_interface(
-	struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf)
+	struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
 	printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n",
-	       wiphy_name(hw->wiphy), __func__, conf->type,
-	       conf->mac_addr);
-	hwsim_check_magic(conf->vif);
-	hwsim_clear_magic(conf->vif);
+	       wiphy_name(hw->wiphy), __func__, vif->type,
+	       vif->addr);
+	hwsim_check_magic(vif);
+	hwsim_clear_magic(vif);
 }
 
 
@@ -618,12 +656,26 @@ static int mac80211_hwsim_config(struct
 {
 	struct mac80211_hwsim_data *data = hw->priv;
 	struct ieee80211_conf *conf = &hw->conf;
+	static const char *chantypes[4] = {
+		[NL80211_CHAN_NO_HT] = "noht",
+		[NL80211_CHAN_HT20] = "ht20",
+		[NL80211_CHAN_HT40MINUS] = "ht40-",
+		[NL80211_CHAN_HT40PLUS] = "ht40+",
+	};
+	static const char *smps_modes[IEEE80211_SMPS_NUM_MODES] = {
+		[IEEE80211_SMPS_AUTOMATIC] = "auto",
+		[IEEE80211_SMPS_OFF] = "off",
+		[IEEE80211_SMPS_STATIC] = "static",
+		[IEEE80211_SMPS_DYNAMIC] = "dynamic",
+	};
 
-	printk(KERN_DEBUG "%s:%s (freq=%d idle=%d ps=%d)\n",
+	printk(KERN_DEBUG "%s:%s (freq=%d/%s idle=%d ps=%d smps=%s)\n",
 	       wiphy_name(hw->wiphy), __func__,
 	       conf->channel->center_freq,
+	       chantypes[conf->channel_type],
 	       !!(conf->flags & IEEE80211_CONF_IDLE),
-	       !!(conf->flags & IEEE80211_CONF_PS));
+	       !!(conf->flags & IEEE80211_CONF_PS),
+	       smps_modes[conf->smps_mode]);
 
 	data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
 
@@ -720,23 +772,41 @@ static void mac80211_hwsim_bss_info_chan
 	}
 }
 
+static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw,
+				  struct ieee80211_vif *vif,
+				  struct ieee80211_sta *sta)
+{
+	hwsim_check_magic(vif);
+	hwsim_set_sta_magic(sta);
+
+	return 0;
+}
+
+static int mac80211_hwsim_sta_remove(struct ieee80211_hw *hw,
+				     struct ieee80211_vif *vif,
+				     struct ieee80211_sta *sta)
+{
+	hwsim_check_magic(vif);
+	hwsim_clear_sta_magic(sta);
+
+	return 0;
+}
+
 static void mac80211_hwsim_sta_notify(struct ieee80211_hw *hw,
 				      struct ieee80211_vif *vif,
 				      enum sta_notify_cmd cmd,
 				      struct ieee80211_sta *sta)
 {
 	hwsim_check_magic(vif);
+
 	switch (cmd) {
-	case STA_NOTIFY_ADD:
-		hwsim_set_sta_magic(sta);
-		break;
-	case STA_NOTIFY_REMOVE:
-		hwsim_clear_sta_magic(sta);
-		break;
 	case STA_NOTIFY_SLEEP:
 	case STA_NOTIFY_AWAKE:
 		/* TODO: make good use of these flags */
 		break;
+	default:
+		WARN(1, "Invalid sta notify: %d\n", cmd);
+		break;
 	}
 }
 
@@ -827,7 +897,77 @@ static int mac80211_hwsim_testmode_cmd(s
 }
 #endif
 
-static const struct ieee80211_ops mac80211_hwsim_ops =
+static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
+				       struct ieee80211_vif *vif,
+				       enum ieee80211_ampdu_mlme_action action,
+				       struct ieee80211_sta *sta, u16 tid, u16 *ssn)
+{
+	switch (action) {
+	case IEEE80211_AMPDU_TX_START:
+		ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+		break;
+	case IEEE80211_AMPDU_TX_STOP:
+		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+		break;
+	case IEEE80211_AMPDU_TX_OPERATIONAL:
+		break;
+	case IEEE80211_AMPDU_RX_START:
+	case IEEE80211_AMPDU_RX_STOP:
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop)
+{
+	/*
+	 * In this special case, there's nothing we need to
+	 * do because hwsim does transmission synchronously.
+	 * In the future, when it does transmissions via
+	 * userspace, we may need to do something.
+	 */
+}
+
+struct hw_scan_done {
+	struct delayed_work w;
+	struct ieee80211_hw *hw;
+};
+
+static void hw_scan_done(struct work_struct *work)
+{
+	struct hw_scan_done *hsd =
+		container_of(work, struct hw_scan_done, w.work);
+
+	ieee80211_scan_completed(hsd->hw, false);
+	kfree(hsd);
+}
+
+static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
+				  struct cfg80211_scan_request *req)
+{
+	struct hw_scan_done *hsd = kzalloc(sizeof(*hsd), GFP_KERNEL);
+	int i;
+
+	if (!hsd)
+		return -ENOMEM;
+
+	hsd->hw = hw;
+	INIT_DELAYED_WORK(&hsd->w, hw_scan_done);
+
+	printk(KERN_DEBUG "hwsim scan request\n");
+	for (i = 0; i < req->n_channels; i++)
+		printk(KERN_DEBUG "hwsim scan freq %d\n",
+			req->channels[i]->center_freq);
+
+	ieee80211_queue_delayed_work(hw, &hsd->w, 2 * HZ);
+
+	return 0;
+}
+
+static struct ieee80211_ops mac80211_hwsim_ops =
 {
 	.tx = mac80211_hwsim_tx,
 	.start = mac80211_hwsim_start,
@@ -837,10 +977,14 @@ static const struct ieee80211_ops mac802
 	.config = mac80211_hwsim_config,
 	.configure_filter = mac80211_hwsim_configure_filter,
 	.bss_info_changed = mac80211_hwsim_bss_info_changed,
+	.sta_add = mac80211_hwsim_sta_add,
+	.sta_remove = mac80211_hwsim_sta_remove,
 	.sta_notify = mac80211_hwsim_sta_notify,
 	.set_tim = mac80211_hwsim_set_tim,
 	.conf_tx = mac80211_hwsim_conf_tx,
 	CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd)
+	.ampdu_action = mac80211_hwsim_ampdu_action,
+	.flush = mac80211_hwsim_flush,
 };
 
 
@@ -1035,6 +1179,9 @@ static int __init init_mac80211_hwsim(vo
 	if (radios < 1 || radios > 100)
 		return -EINVAL;
 
+	if (fake_hw_scan)
+		mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan;
+
 	spin_lock_init(&hwsim_radio_lock);
 	INIT_LIST_HEAD(&hwsim_radios);
 
@@ -1072,7 +1219,11 @@ static int __init init_mac80211_hwsim(vo
 		SET_IEEE80211_DEV(hw, data->dev);
 		addr[3] = i >> 8;
 		addr[4] = i;
-		SET_IEEE80211_PERM_ADDR(hw, addr);
+		memcpy(data->addresses[0].addr, addr, ETH_ALEN);
+		memcpy(data->addresses[1].addr, addr, ETH_ALEN);
+		data->addresses[1].addr[0] |= 0x40;
+		hw->wiphy->n_addresses = 2;
+		hw->wiphy->addresses = data->addresses;
 
 		hw->channel_change_time = 1;
 		hw->queues = 4;
@@ -1082,7 +1233,9 @@ static int __init init_mac80211_hwsim(vo
 			BIT(NL80211_IFTYPE_MESH_POINT);
 
 		hw->flags = IEEE80211_HW_MFP_CAPABLE |
-			    IEEE80211_HW_SIGNAL_DBM;
+			    IEEE80211_HW_SIGNAL_DBM |
+			    IEEE80211_HW_SUPPORTS_STATIC_SMPS |
+			    IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS;
 
 		/* ask mac80211 to reserve space for magic */
 		hw->vif_data_size = sizeof(struct hwsim_vif_priv);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/mwl8k.c linux-libre-2.6.34-gnu1/drivers/net/wireless/mwl8k.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/mwl8k.c	2013-05-03 12:10:22.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/mwl8k.c	2013-05-03 09:49:53.000000000 -0400
@@ -2,7 +2,7 @@
  * drivers/net/wireless/mwl8k.c
  * Driver for Marvell TOPDOG 802.11 Wireless cards
  *
- * Copyright (C) 2008-2009 Marvell Semiconductor Inc.
+ * Copyright (C) 2008, 2009, 2010 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
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/completion.h>
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
@@ -26,7 +27,7 @@
 
 #define MWL8K_DESC	"Marvell TOPDOG(R) 802.11 Wireless Network Driver"
 #define MWL8K_NAME	KBUILD_MODNAME
-#define MWL8K_VERSION	"0.10"
+#define MWL8K_VERSION	"0.12"
 
 /* Register definitions */
 #define MWL8K_HIU_GEN_PTR			0x00000c10
@@ -92,8 +93,7 @@ struct mwl8k_device_info {
 	char *part_name;
 	char *helper_image;
 	char *fw_image;
-	struct rxd_ops *rxd_ops;
-	u16 modes;
+	struct rxd_ops *ap_rxd_ops;
 };
 
 struct mwl8k_rx_queue {
@@ -120,34 +120,36 @@ struct mwl8k_tx_queue {
 	/* sw appends here */
 	int tail;
 
-	struct ieee80211_tx_queue_stats stats;
+	unsigned int len;
 	struct mwl8k_tx_desc *txd;
 	dma_addr_t txd_dma;
 	struct sk_buff **skb;
 };
 
-/* Pointers to the firmware data and meta information about it.  */
-struct mwl8k_firmware {
-	/* Boot helper code */
-	struct firmware *helper;
+struct mwl8k_priv {
+	struct ieee80211_hw *hw;
+	struct pci_dev *pdev;
 
-	/* Microcode */
-	struct firmware *ucode;
-};
+	struct mwl8k_device_info *device_info;
 
-struct mwl8k_priv {
 	void __iomem *sram;
 	void __iomem *regs;
-	struct ieee80211_hw *hw;
 
-	struct pci_dev *pdev;
+	/* firmware */
+	struct firmware *fw_helper;
+	struct firmware *fw_ucode;
 
-	struct mwl8k_device_info *device_info;
+	/* hardware/firmware parameters */
 	bool ap_fw;
 	struct rxd_ops *rxd_ops;
-
-	/* firmware files and meta data */
-	struct mwl8k_firmware fw;
+	struct ieee80211_supported_band band_24;
+	struct ieee80211_channel channels_24[14];
+	struct ieee80211_rate rates_24[14];
+	struct ieee80211_supported_band band_50;
+	struct ieee80211_channel channels_50[4];
+	struct ieee80211_rate rates_50[9];
+	u32 ap_macids_supported;
+	u32 sta_macids_supported;
 
 	/* firmware access */
 	struct mutex fw_mutex;
@@ -161,9 +163,9 @@ struct mwl8k_priv {
 	/* TX quiesce completion, protected by fw_mutex and tx_lock */
 	struct completion *tx_wait;
 
-	struct ieee80211_vif *vif;
-
-	struct ieee80211_channel *current_channel;
+	/* List of interfaces.  */
+	u32 macids_used;
+	struct list_head vif_list;
 
 	/* power management status cookie from firmware */
 	u32 *cookie;
@@ -182,11 +184,6 @@ struct mwl8k_priv {
 	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[14];
-
 	bool radio_on;
 	bool radio_short_preamble;
 	bool sniffer_enabled;
@@ -205,32 +202,33 @@ struct mwl8k_priv {
 	 */
 	struct work_struct finalize_join_worker;
 
-	/* Tasklet to reclaim TX descriptors and buffers after tx */
-	struct tasklet_struct tx_reclaim_task;
+	/* Tasklet to perform TX reclaim.  */
+	struct tasklet_struct poll_tx_task;
+
+	/* Tasklet to perform RX.  */
+	struct tasklet_struct poll_rx_task;
 };
 
 /* Per interface specific private data */
 struct mwl8k_vif {
-	/* 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[ETH_ALEN];
-	u8	mac_addr[ETH_ALEN];
+	struct list_head list;
+	struct ieee80211_vif *vif;
 
-	 /* Index into station database.Returned by update_sta_db call */
-	u8	peer_id;
+	/* Firmware macid for this vif.  */
+	int macid;
 
-	/* Non AMPDU sequence number assigned by driver */
-	u16	seqno;
+	/* Non AMPDU sequence number assigned by driver.  */
+	u16 seqno;
 };
-
 #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
 
-static const struct ieee80211_channel mwl8k_channels[] = {
+struct mwl8k_sta {
+	/* Index into station database. Returned by UPDATE_STADB.  */
+	u8 peer_id;
+};
+#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
+
+static const struct ieee80211_channel mwl8k_channels_24[] = {
 	{ .center_freq = 2412, .hw_value = 1, },
 	{ .center_freq = 2417, .hw_value = 2, },
 	{ .center_freq = 2422, .hw_value = 3, },
@@ -242,9 +240,12 @@ static const struct ieee80211_channel mw
 	{ .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 const struct ieee80211_rate mwl8k_rates[] = {
+static const struct ieee80211_rate mwl8k_rates_24[] = {
 	{ .bitrate = 10, .hw_value = 2, },
 	{ .bitrate = 20, .hw_value = 4, },
 	{ .bitrate = 55, .hw_value = 11, },
@@ -261,8 +262,23 @@ static const struct ieee80211_rate mwl8k
 	{ .bitrate = 720, .hw_value = 144, },
 };
 
-static const u8 mwl8k_rateids[12] = {
-	2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108,
+static const struct ieee80211_channel mwl8k_channels_50[] = {
+	{ .center_freq = 5180, .hw_value = 36, },
+	{ .center_freq = 5200, .hw_value = 40, },
+	{ .center_freq = 5220, .hw_value = 44, },
+	{ .center_freq = 5240, .hw_value = 48, },
+};
+
+static const struct ieee80211_rate mwl8k_rates_50[] = {
+	{ .bitrate = 60, .hw_value = 12, },
+	{ .bitrate = 90, .hw_value = 18, },
+	{ .bitrate = 120, .hw_value = 24, },
+	{ .bitrate = 180, .hw_value = 36, },
+	{ .bitrate = 240, .hw_value = 48, },
+	{ .bitrate = 360, .hw_value = 72, },
+	{ .bitrate = 480, .hw_value = 96, },
+	{ .bitrate = 540, .hw_value = 108, },
+	{ .bitrate = 720, .hw_value = 144, },
 };
 
 /* Set or get info from Firmware */
@@ -278,6 +294,7 @@ static const u8 mwl8k_rateids[12] = {
 #define MWL8K_CMD_RADIO_CONTROL		0x001c
 #define MWL8K_CMD_RF_TX_POWER		0x001e
 #define MWL8K_CMD_RF_ANTENNA		0x0020
+#define MWL8K_CMD_SET_BEACON		0x0100		/* per-vif */
 #define MWL8K_CMD_SET_PRE_SCAN		0x0107
 #define MWL8K_CMD_SET_POST_SCAN		0x0108
 #define MWL8K_CMD_SET_RF_CHANNEL	0x010a
@@ -291,8 +308,10 @@ static const u8 mwl8k_rateids[12] = {
 #define MWL8K_CMD_MIMO_CONFIG		0x0125
 #define MWL8K_CMD_USE_FIXED_RATE	0x0126
 #define MWL8K_CMD_ENABLE_SNIFFER	0x0150
-#define MWL8K_CMD_SET_MAC_ADDR		0x0202
+#define MWL8K_CMD_SET_MAC_ADDR		0x0202		/* per-vif */
 #define MWL8K_CMD_SET_RATEADAPT_MODE	0x0203
+#define MWL8K_CMD_BSS_START		0x1100		/* per-vif */
+#define MWL8K_CMD_SET_NEW_STN		0x1111		/* per-vif */
 #define MWL8K_CMD_UPDATE_STADB		0x1123
 
 static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
@@ -310,6 +329,7 @@ static const char *mwl8k_cmd_name(u16 cm
 		MWL8K_CMDNAME(RADIO_CONTROL);
 		MWL8K_CMDNAME(RF_TX_POWER);
 		MWL8K_CMDNAME(RF_ANTENNA);
+		MWL8K_CMDNAME(SET_BEACON);
 		MWL8K_CMDNAME(SET_PRE_SCAN);
 		MWL8K_CMDNAME(SET_POST_SCAN);
 		MWL8K_CMDNAME(SET_RF_CHANNEL);
@@ -325,6 +345,8 @@ static const char *mwl8k_cmd_name(u16 cm
 		MWL8K_CMDNAME(ENABLE_SNIFFER);
 		MWL8K_CMDNAME(SET_MAC_ADDR);
 		MWL8K_CMDNAME(SET_RATEADAPT_MODE);
+		MWL8K_CMDNAME(BSS_START);
+		MWL8K_CMDNAME(SET_NEW_STN);
 		MWL8K_CMDNAME(UPDATE_STADB);
 	default:
 		snprintf(buf, bufsize, "0x%x", cmd);
@@ -355,8 +377,8 @@ static void mwl8k_release_fw(struct firm
 
 static void mwl8k_release_firmware(struct mwl8k_priv *priv)
 {
-	mwl8k_release_fw(&priv->fw.ucode);
-	mwl8k_release_fw(&priv->fw.helper);
+	mwl8k_release_fw(&priv->fw_ucode);
+	mwl8k_release_fw(&priv->fw_helper);
 }
 
 /* Request fw image */
@@ -377,7 +399,7 @@ static int mwl8k_reject_firmware(struct
 	int rc;
 
 	if (di->helper_image != NULL) {
-		rc = mwl8k_request_fw(priv, di->helper_image, &priv->fw.helper);
+		rc = mwl8k_request_fw(priv, di->helper_image, &priv->fw_helper);
 		if (rc) {
 			printk(KERN_ERR "%s: Error requesting helper "
 			       "firmware file %s\n", pci_name(priv->pdev),
@@ -386,23 +408,22 @@ static int mwl8k_reject_firmware(struct
 		}
 	}
 
-	rc = mwl8k_request_fw(priv, di->fw_image, &priv->fw.ucode);
+	rc = mwl8k_request_fw(priv, di->fw_image, &priv->fw_ucode);
 	if (rc) {
 		printk(KERN_ERR "%s: Error requesting firmware file %s\n",
 		       pci_name(priv->pdev), di->fw_image);
-		mwl8k_release_fw(&priv->fw.helper);
+		mwl8k_release_fw(&priv->fw_helper);
 		return rc;
 	}
 
 	return 0;
 }
 
-/*(DEBLOBBED)*/
-
 struct mwl8k_cmd_pkt {
 	__le16	code;
 	__le16	length;
-	__le16	seq_num;
+	__u8	seq_num;
+	__u8	macid;
 	__le16	result;
 	char	payload[0];
 } __attribute__((packed));
@@ -460,6 +481,7 @@ static int mwl8k_load_fw_image(struct mw
 
 	cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD);
 	cmd->seq_num = 0;
+	cmd->macid = 0;
 	cmd->result = 0;
 
 	done = 0;
@@ -550,13 +572,12 @@ static int mwl8k_feed_fw_image(struct mw
 static int mwl8k_load_firmware(struct ieee80211_hw *hw)
 {
 	struct mwl8k_priv *priv = hw->priv;
-	struct firmware *fw = priv->fw.ucode;
-	struct mwl8k_device_info *di = priv->device_info;
+	struct firmware *fw = priv->fw_ucode;
 	int rc;
 	int loops;
 
 	if (!memcmp(fw->data, "\x01\x00\x00\x00", 4)) {
-		struct firmware *helper = priv->fw.helper;
+		struct firmware *helper = priv->fw_helper;
 
 		if (helper == NULL) {
 			printk(KERN_ERR "%s: helper image needed but none "
@@ -583,10 +604,7 @@ static int mwl8k_load_firmware(struct ie
 		return rc;
 	}
 
-	if (di->modes & BIT(NL80211_IFTYPE_AP))
-		iowrite32(MWL8K_MODE_AP, priv->regs + MWL8K_HIU_GEN_PTR);
-	else
-		iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
+	iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
 
 	loops = 500000;
 	do {
@@ -609,91 +627,6 @@ static int mwl8k_load_firmware(struct ie
 }
 
 
-/*
- * 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
-
-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[12];
-
-	/* HT rate table. Intersection of our rates and peer rates.  */
-	__u8	ht_rates[16];
-	__u8	pad[16];
-
-	/* 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_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;
@@ -760,9 +693,9 @@ static inline void mwl8k_add_dma_header(
 
 
 /*
- * Packet reception for 88w8366.
+ * Packet reception for 88w8366 AP firmware.
  */
-struct mwl8k_rxd_8366 {
+struct mwl8k_rxd_8366_ap {
 	__le16 pkt_len;
 	__u8 sq2;
 	__u8 rate;
@@ -780,23 +713,23 @@ struct mwl8k_rxd_8366 {
 	__u8 rx_ctrl;
 } __attribute__((packed));
 
-#define MWL8K_8366_RATE_INFO_MCS_FORMAT		0x80
-#define MWL8K_8366_RATE_INFO_40MHZ		0x40
-#define MWL8K_8366_RATE_INFO_RATEID(x)		((x) & 0x3f)
+#define MWL8K_8366_AP_RATE_INFO_MCS_FORMAT	0x80
+#define MWL8K_8366_AP_RATE_INFO_40MHZ		0x40
+#define MWL8K_8366_AP_RATE_INFO_RATEID(x)	((x) & 0x3f)
 
-#define MWL8K_8366_RX_CTRL_OWNED_BY_HOST	0x80
+#define MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST	0x80
 
-static void mwl8k_rxd_8366_init(void *_rxd, dma_addr_t next_dma_addr)
+static void mwl8k_rxd_8366_ap_init(void *_rxd, dma_addr_t next_dma_addr)
 {
-	struct mwl8k_rxd_8366 *rxd = _rxd;
+	struct mwl8k_rxd_8366_ap *rxd = _rxd;
 
 	rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
-	rxd->rx_ctrl = MWL8K_8366_RX_CTRL_OWNED_BY_HOST;
+	rxd->rx_ctrl = MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST;
 }
 
-static void mwl8k_rxd_8366_refill(void *_rxd, dma_addr_t addr, int len)
+static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len)
 {
-	struct mwl8k_rxd_8366 *rxd = _rxd;
+	struct mwl8k_rxd_8366_ap *rxd = _rxd;
 
 	rxd->pkt_len = cpu_to_le16(len);
 	rxd->pkt_phys_addr = cpu_to_le32(addr);
@@ -805,12 +738,12 @@ static void mwl8k_rxd_8366_refill(void *
 }
 
 static int
-mwl8k_rxd_8366_process(void *_rxd, struct ieee80211_rx_status *status,
-		       __le16 *qos)
+mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
+			  __le16 *qos)
 {
-	struct mwl8k_rxd_8366 *rxd = _rxd;
+	struct mwl8k_rxd_8366_ap *rxd = _rxd;
 
-	if (!(rxd->rx_ctrl & MWL8K_8366_RX_CTRL_OWNED_BY_HOST))
+	if (!(rxd->rx_ctrl & MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST))
 		return -1;
 	rmb();
 
@@ -819,23 +752,29 @@ mwl8k_rxd_8366_process(void *_rxd, struc
 	status->signal = -rxd->rssi;
 	status->noise = -rxd->noise_floor;
 
-	if (rxd->rate & MWL8K_8366_RATE_INFO_MCS_FORMAT) {
+	if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) {
 		status->flag |= RX_FLAG_HT;
-		if (rxd->rate & MWL8K_8366_RATE_INFO_40MHZ)
+		if (rxd->rate & MWL8K_8366_AP_RATE_INFO_40MHZ)
 			status->flag |= RX_FLAG_40MHZ;
-		status->rate_idx = MWL8K_8366_RATE_INFO_RATEID(rxd->rate);
+		status->rate_idx = MWL8K_8366_AP_RATE_INFO_RATEID(rxd->rate);
 	} else {
 		int i;
 
-		for (i = 0; i < ARRAY_SIZE(mwl8k_rates); i++) {
-			if (mwl8k_rates[i].hw_value == rxd->rate) {
+		for (i = 0; i < ARRAY_SIZE(mwl8k_rates_24); i++) {
+			if (mwl8k_rates_24[i].hw_value == rxd->rate) {
 				status->rate_idx = i;
 				break;
 			}
 		}
 	}
 
-	status->band = IEEE80211_BAND_2GHZ;
+	if (rxd->channel > 14) {
+		status->band = IEEE80211_BAND_5GHZ;
+		if (!(status->flag & RX_FLAG_HT))
+			status->rate_idx -= 5;
+	} else {
+		status->band = IEEE80211_BAND_2GHZ;
+	}
 	status->freq = ieee80211_channel_to_frequency(rxd->channel);
 
 	*qos = rxd->qos_control;
@@ -843,17 +782,17 @@ mwl8k_rxd_8366_process(void *_rxd, struc
 	return le16_to_cpu(rxd->pkt_len);
 }
 
-static struct rxd_ops rxd_8366_ops = {
-	.rxd_size	= sizeof(struct mwl8k_rxd_8366),
-	.rxd_init	= mwl8k_rxd_8366_init,
-	.rxd_refill	= mwl8k_rxd_8366_refill,
-	.rxd_process	= mwl8k_rxd_8366_process,
+static struct rxd_ops rxd_8366_ap_ops = {
+	.rxd_size	= sizeof(struct mwl8k_rxd_8366_ap),
+	.rxd_init	= mwl8k_rxd_8366_ap_init,
+	.rxd_refill	= mwl8k_rxd_8366_ap_refill,
+	.rxd_process	= mwl8k_rxd_8366_ap_process,
 };
 
 /*
- * Packet reception for 88w8687.
+ * Packet reception for STA firmware.
  */
-struct mwl8k_rxd_8687 {
+struct mwl8k_rxd_sta {
 	__le16 pkt_len;
 	__u8 link_quality;
 	__u8 noise_level;
@@ -870,26 +809,26 @@ struct mwl8k_rxd_8687 {
 	__u8 pad2[2];
 } __attribute__((packed));
 
-#define MWL8K_8687_RATE_INFO_SHORTPRE		0x8000
-#define MWL8K_8687_RATE_INFO_ANTSELECT(x)	(((x) >> 11) & 0x3)
-#define MWL8K_8687_RATE_INFO_RATEID(x)		(((x) >> 3) & 0x3f)
-#define MWL8K_8687_RATE_INFO_40MHZ		0x0004
-#define MWL8K_8687_RATE_INFO_SHORTGI		0x0002
-#define MWL8K_8687_RATE_INFO_MCS_FORMAT		0x0001
+#define MWL8K_STA_RATE_INFO_SHORTPRE		0x8000
+#define MWL8K_STA_RATE_INFO_ANTSELECT(x)	(((x) >> 11) & 0x3)
+#define MWL8K_STA_RATE_INFO_RATEID(x)		(((x) >> 3) & 0x3f)
+#define MWL8K_STA_RATE_INFO_40MHZ		0x0004
+#define MWL8K_STA_RATE_INFO_SHORTGI		0x0002
+#define MWL8K_STA_RATE_INFO_MCS_FORMAT		0x0001
 
-#define MWL8K_8687_RX_CTRL_OWNED_BY_HOST	0x02
+#define MWL8K_STA_RX_CTRL_OWNED_BY_HOST		0x02
 
-static void mwl8k_rxd_8687_init(void *_rxd, dma_addr_t next_dma_addr)
+static void mwl8k_rxd_sta_init(void *_rxd, dma_addr_t next_dma_addr)
 {
-	struct mwl8k_rxd_8687 *rxd = _rxd;
+	struct mwl8k_rxd_sta *rxd = _rxd;
 
 	rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
-	rxd->rx_ctrl = MWL8K_8687_RX_CTRL_OWNED_BY_HOST;
+	rxd->rx_ctrl = MWL8K_STA_RX_CTRL_OWNED_BY_HOST;
 }
 
-static void mwl8k_rxd_8687_refill(void *_rxd, dma_addr_t addr, int len)
+static void mwl8k_rxd_sta_refill(void *_rxd, dma_addr_t addr, int len)
 {
-	struct mwl8k_rxd_8687 *rxd = _rxd;
+	struct mwl8k_rxd_sta *rxd = _rxd;
 
 	rxd->pkt_len = cpu_to_le16(len);
 	rxd->pkt_phys_addr = cpu_to_le32(addr);
@@ -898,13 +837,13 @@ static void mwl8k_rxd_8687_refill(void *
 }
 
 static int
-mwl8k_rxd_8687_process(void *_rxd, struct ieee80211_rx_status *status,
+mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
 		       __le16 *qos)
 {
-	struct mwl8k_rxd_8687 *rxd = _rxd;
+	struct mwl8k_rxd_sta *rxd = _rxd;
 	u16 rate_info;
 
-	if (!(rxd->rx_ctrl & MWL8K_8687_RX_CTRL_OWNED_BY_HOST))
+	if (!(rxd->rx_ctrl & MWL8K_STA_RX_CTRL_OWNED_BY_HOST))
 		return -1;
 	rmb();
 
@@ -914,19 +853,25 @@ mwl8k_rxd_8687_process(void *_rxd, struc
 
 	status->signal = -rxd->rssi;
 	status->noise = -rxd->noise_level;
-	status->antenna = MWL8K_8687_RATE_INFO_ANTSELECT(rate_info);
-	status->rate_idx = MWL8K_8687_RATE_INFO_RATEID(rate_info);
+	status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info);
+	status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info);
 
-	if (rate_info & MWL8K_8687_RATE_INFO_SHORTPRE)
+	if (rate_info & MWL8K_STA_RATE_INFO_SHORTPRE)
 		status->flag |= RX_FLAG_SHORTPRE;
-	if (rate_info & MWL8K_8687_RATE_INFO_40MHZ)
+	if (rate_info & MWL8K_STA_RATE_INFO_40MHZ)
 		status->flag |= RX_FLAG_40MHZ;
-	if (rate_info & MWL8K_8687_RATE_INFO_SHORTGI)
+	if (rate_info & MWL8K_STA_RATE_INFO_SHORTGI)
 		status->flag |= RX_FLAG_SHORT_GI;
-	if (rate_info & MWL8K_8687_RATE_INFO_MCS_FORMAT)
+	if (rate_info & MWL8K_STA_RATE_INFO_MCS_FORMAT)
 		status->flag |= RX_FLAG_HT;
 
-	status->band = IEEE80211_BAND_2GHZ;
+	if (rxd->channel > 14) {
+		status->band = IEEE80211_BAND_5GHZ;
+		if (!(status->flag & RX_FLAG_HT))
+			status->rate_idx -= 5;
+	} else {
+		status->band = IEEE80211_BAND_2GHZ;
+	}
 	status->freq = ieee80211_channel_to_frequency(rxd->channel);
 
 	*qos = rxd->qos_control;
@@ -934,11 +879,11 @@ mwl8k_rxd_8687_process(void *_rxd, struc
 	return le16_to_cpu(rxd->pkt_len);
 }
 
-static struct rxd_ops rxd_8687_ops = {
-	.rxd_size	= sizeof(struct mwl8k_rxd_8687),
-	.rxd_init	= mwl8k_rxd_8687_init,
-	.rxd_refill	= mwl8k_rxd_8687_refill,
-	.rxd_process	= mwl8k_rxd_8687_process,
+static struct rxd_ops rxd_sta_ops = {
+	.rxd_size	= sizeof(struct mwl8k_rxd_sta),
+	.rxd_init	= mwl8k_rxd_sta_init,
+	.rxd_refill	= mwl8k_rxd_sta_refill,
+	.rxd_process	= mwl8k_rxd_sta_process,
 };
 
 
@@ -1152,16 +1097,18 @@ static int rxq_process(struct ieee80211_
  * Packet transmission.
  */
 
-/* Transmit packet ACK policy */
-#define MWL8K_TXD_ACK_POLICY_NORMAL		0
-#define MWL8K_TXD_ACK_POLICY_BLOCKACK		3
-
 #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_FW_OWNED		0x80000000
 
+#define MWL8K_QOS_QLEN_UNSPEC			0xff00
+#define MWL8K_QOS_ACK_POLICY_MASK		0x0060
+#define MWL8K_QOS_ACK_POLICY_NORMAL		0x0000
+#define MWL8K_QOS_ACK_POLICY_BLOCKACK		0x0060
+#define MWL8K_QOS_EOSP				0x0010
+
 struct mwl8k_tx_desc {
 	__le32 status;
 	__u8 data_rate;
@@ -1186,8 +1133,7 @@ static int mwl8k_txq_init(struct ieee802
 	int size;
 	int i;
 
-	memset(&txq->stats, 0, sizeof(struct ieee80211_tx_queue_stats));
-	txq->stats.limit = MWL8K_TX_DESCS;
+	txq->len = 0;
 	txq->head = 0;
 	txq->tail = 0;
 
@@ -1263,7 +1209,7 @@ static void mwl8k_dump_tx_rings(struct i
 		printk(KERN_ERR "%s: txq[%d] len=%d head=%d tail=%d "
 		       "fw_owned=%d drv_owned=%d unused=%d\n",
 		       wiphy_name(hw->wiphy), i,
-		       txq->stats.len, txq->head, txq->tail,
+		       txq->len, txq->head, txq->tail,
 		       fw_owned, drv_owned, unused);
 	}
 }
@@ -1271,7 +1217,7 @@ static void mwl8k_dump_tx_rings(struct i
 /*
  * Must be called with priv->fw_mutex held and tx queues stopped.
  */
-#define MWL8K_TX_WAIT_TIMEOUT_MS	1000
+#define MWL8K_TX_WAIT_TIMEOUT_MS	5000
 
 static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
 {
@@ -1315,8 +1261,8 @@ static int mwl8k_tx_wait_empty(struct ie
 		}
 
 		if (priv->pending_tx_pkts < oldcount) {
-			printk(KERN_NOTICE "%s: timeout waiting for tx "
-			       "rings to drain (%d -> %d pkts), retrying\n",
+			printk(KERN_NOTICE "%s: waiting for tx rings "
+			       "to drain (%d -> %d pkts)\n",
 			       wiphy_name(hw->wiphy), oldcount,
 			       priv->pending_tx_pkts);
 			retry = 1;
@@ -1341,13 +1287,15 @@ static int mwl8k_tx_wait_empty(struct ie
 		     MWL8K_TXD_STATUS_OK_RETRY |		\
 		     MWL8K_TXD_STATUS_OK_MORE_RETRY))
 
-static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
+static int
+mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
 {
 	struct mwl8k_priv *priv = hw->priv;
 	struct mwl8k_tx_queue *txq = priv->txq + index;
-	int wake = 0;
+	int processed;
 
-	while (txq->stats.len > 0) {
+	processed = 0;
+	while (txq->len > 0 && limit--) {
 		int tx;
 		struct mwl8k_tx_desc *tx_desc;
 		unsigned long addr;
@@ -1369,8 +1317,8 @@ static void mwl8k_txq_reclaim(struct iee
 		}
 
 		txq->head = (tx + 1) % MWL8K_TX_DESCS;
-		BUG_ON(txq->stats.len == 0);
-		txq->stats.len--;
+		BUG_ON(txq->len == 0);
+		txq->len--;
 		priv->pending_tx_pkts--;
 
 		addr = le32_to_cpu(tx_desc->pkt_phys_addr);
@@ -1394,11 +1342,13 @@ static void mwl8k_txq_reclaim(struct iee
 
 		ieee80211_tx_status_irqsafe(hw, skb);
 
-		wake = 1;
+		processed++;
 	}
 
-	if (wake && priv->radio_on && !mutex_is_locked(&priv->fw_mutex))
+	if (processed && priv->radio_on && !mutex_is_locked(&priv->fw_mutex))
 		ieee80211_wake_queue(hw, index);
+
+	return processed;
 }
 
 /* must be called only when the card's transmit is completely halted */
@@ -1407,7 +1357,7 @@ static void mwl8k_txq_deinit(struct ieee
 	struct mwl8k_priv *priv = hw->priv;
 	struct mwl8k_tx_queue *txq = priv->txq + index;
 
-	mwl8k_txq_reclaim(hw, index, 1);
+	mwl8k_txq_reclaim(hw, index, INT_MAX, 1);
 
 	kfree(txq->skb);
 	txq->skb = NULL;
@@ -1445,11 +1395,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
 	mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
 
 	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;
+		wh->seq_ctrl |= cpu_to_le16(mwl8k_vif->seqno);
+		mwl8k_vif->seqno += 0x10;
 	}
 
 	/* Setup firmware control bit fields for each frame type.  */
@@ -1458,24 +1406,17 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
 	if (ieee80211_is_mgmt(wh->frame_control) ||
 	    ieee80211_is_ctl(wh->frame_control)) {
 		txdatarate = 0;
-		qos = mwl8k_qos_setbit_eosp(qos);
-		/* Set Queue size to unspecified */
-		qos = mwl8k_qos_setbit_qlen(qos, 0xff);
+		qos |= MWL8K_QOS_QLEN_UNSPEC | MWL8K_QOS_EOSP;
 	} else if (ieee80211_is_data(wh->frame_control)) {
 		txdatarate = 1;
 		if (is_multicast_ether_addr(wh->addr1))
 			txstatus |= MWL8K_TXD_STATUS_MULTICAST_TX;
 
-		/* Send pkt in an aggregate if AMPDU frame.  */
+		qos &= ~MWL8K_QOS_ACK_POLICY_MASK;
 		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
-			qos = mwl8k_qos_setbit_ack(qos,
-				MWL8K_TXD_ACK_POLICY_BLOCKACK);
+			qos |= MWL8K_QOS_ACK_POLICY_BLOCKACK;
 		else
-			qos = mwl8k_qos_setbit_ack(qos,
-				MWL8K_TXD_ACK_POLICY_NORMAL);
-
-		if (qos & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
-			qos = mwl8k_qos_setbit_amsdu(qos);
+			qos |= MWL8K_QOS_ACK_POLICY_NORMAL;
 	}
 
 	dma = pci_map_single(priv->pdev, skb->data,
@@ -1502,12 +1443,14 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
 	tx->pkt_phys_addr = cpu_to_le32(dma);
 	tx->pkt_len = cpu_to_le16(skb->len);
 	tx->rate_info = 0;
-	tx->peer_id = mwl8k_vif->peer_id;
+	if (!priv->ap_fw && tx_info->control.sta != NULL)
+		tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id;
+	else
+		tx->peer_id = 0;
 	wmb();
 	tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
 
-	txq->stats.count++;
-	txq->stats.len++;
+	txq->len++;
 	priv->pending_tx_pkts++;
 
 	txq->tail++;
@@ -1655,6 +1598,56 @@ static int mwl8k_post_cmd(struct ieee802
 	return rc;
 }
 
+static int mwl8k_post_pervif_cmd(struct ieee80211_hw *hw,
+				 struct ieee80211_vif *vif,
+				 struct mwl8k_cmd_pkt *cmd)
+{
+	if (vif != NULL)
+		cmd->macid = MWL8K_VIF(vif)->macid;
+	return mwl8k_post_cmd(hw, cmd);
+}
+
+/*
+ * Setup code shared between STA and AP firmware images.
+ */
+static void mwl8k_setup_2ghz_band(struct ieee80211_hw *hw)
+{
+	struct mwl8k_priv *priv = hw->priv;
+
+	BUILD_BUG_ON(sizeof(priv->channels_24) != sizeof(mwl8k_channels_24));
+	memcpy(priv->channels_24, mwl8k_channels_24, sizeof(mwl8k_channels_24));
+
+	BUILD_BUG_ON(sizeof(priv->rates_24) != sizeof(mwl8k_rates_24));
+	memcpy(priv->rates_24, mwl8k_rates_24, sizeof(mwl8k_rates_24));
+
+	priv->band_24.band = IEEE80211_BAND_2GHZ;
+	priv->band_24.channels = priv->channels_24;
+	priv->band_24.n_channels = ARRAY_SIZE(mwl8k_channels_24);
+	priv->band_24.bitrates = priv->rates_24;
+	priv->band_24.n_bitrates = ARRAY_SIZE(mwl8k_rates_24);
+
+	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band_24;
+}
+
+static void mwl8k_setup_5ghz_band(struct ieee80211_hw *hw)
+{
+	struct mwl8k_priv *priv = hw->priv;
+
+	BUILD_BUG_ON(sizeof(priv->channels_50) != sizeof(mwl8k_channels_50));
+	memcpy(priv->channels_50, mwl8k_channels_50, sizeof(mwl8k_channels_50));
+
+	BUILD_BUG_ON(sizeof(priv->rates_50) != sizeof(mwl8k_rates_50));
+	memcpy(priv->rates_50, mwl8k_rates_50, sizeof(mwl8k_rates_50));
+
+	priv->band_50.band = IEEE80211_BAND_5GHZ;
+	priv->band_50.channels = priv->channels_50;
+	priv->band_50.n_channels = ARRAY_SIZE(mwl8k_channels_50);
+	priv->band_50.bitrates = priv->rates_50;
+	priv->band_50.n_bitrates = ARRAY_SIZE(mwl8k_rates_50);
+
+	hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->band_50;
+}
+
 /*
  * CMD_GET_HW_SPEC (STA version).
  */
@@ -1677,6 +1670,89 @@ struct mwl8k_cmd_get_hw_spec_sta {
 	__le32 total_rxd;
 } __attribute__((packed));
 
+#define MWL8K_CAP_MAX_AMSDU		0x20000000
+#define MWL8K_CAP_GREENFIELD		0x08000000
+#define MWL8K_CAP_AMPDU			0x04000000
+#define MWL8K_CAP_RX_STBC		0x01000000
+#define MWL8K_CAP_TX_STBC		0x00800000
+#define MWL8K_CAP_SHORTGI_40MHZ		0x00400000
+#define MWL8K_CAP_SHORTGI_20MHZ		0x00200000
+#define MWL8K_CAP_RX_ANTENNA_MASK	0x000e0000
+#define MWL8K_CAP_TX_ANTENNA_MASK	0x0001c000
+#define MWL8K_CAP_DELAY_BA		0x00003000
+#define MWL8K_CAP_MIMO			0x00000200
+#define MWL8K_CAP_40MHZ			0x00000100
+#define MWL8K_CAP_BAND_MASK		0x00000007
+#define MWL8K_CAP_5GHZ			0x00000004
+#define MWL8K_CAP_2GHZ4			0x00000001
+
+static void
+mwl8k_set_ht_caps(struct ieee80211_hw *hw,
+		  struct ieee80211_supported_band *band, u32 cap)
+{
+	int rx_streams;
+	int tx_streams;
+
+	band->ht_cap.ht_supported = 1;
+
+	if (cap & MWL8K_CAP_MAX_AMSDU)
+		band->ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
+	if (cap & MWL8K_CAP_GREENFIELD)
+		band->ht_cap.cap |= IEEE80211_HT_CAP_GRN_FLD;
+	if (cap & MWL8K_CAP_AMPDU) {
+		hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
+		band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+		band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
+	}
+	if (cap & MWL8K_CAP_RX_STBC)
+		band->ht_cap.cap |= IEEE80211_HT_CAP_RX_STBC;
+	if (cap & MWL8K_CAP_TX_STBC)
+		band->ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
+	if (cap & MWL8K_CAP_SHORTGI_40MHZ)
+		band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
+	if (cap & MWL8K_CAP_SHORTGI_20MHZ)
+		band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
+	if (cap & MWL8K_CAP_DELAY_BA)
+		band->ht_cap.cap |= IEEE80211_HT_CAP_DELAY_BA;
+	if (cap & MWL8K_CAP_40MHZ)
+		band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+
+	rx_streams = hweight32(cap & MWL8K_CAP_RX_ANTENNA_MASK);
+	tx_streams = hweight32(cap & MWL8K_CAP_TX_ANTENNA_MASK);
+
+	band->ht_cap.mcs.rx_mask[0] = 0xff;
+	if (rx_streams >= 2)
+		band->ht_cap.mcs.rx_mask[1] = 0xff;
+	if (rx_streams >= 3)
+		band->ht_cap.mcs.rx_mask[2] = 0xff;
+	band->ht_cap.mcs.rx_mask[4] = 0x01;
+	band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+
+	if (rx_streams != tx_streams) {
+		band->ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
+		band->ht_cap.mcs.tx_params |= (tx_streams - 1) <<
+				IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
+	}
+}
+
+static void
+mwl8k_set_caps(struct ieee80211_hw *hw, u32 caps)
+{
+	struct mwl8k_priv *priv = hw->priv;
+
+	if ((caps & MWL8K_CAP_2GHZ4) || !(caps & MWL8K_CAP_BAND_MASK)) {
+		mwl8k_setup_2ghz_band(hw);
+		if (caps & MWL8K_CAP_MIMO)
+			mwl8k_set_ht_caps(hw, &priv->band_24, caps);
+	}
+
+	if (caps & MWL8K_CAP_5GHZ) {
+		mwl8k_setup_5ghz_band(hw);
+		if (caps & MWL8K_CAP_MIMO)
+			mwl8k_set_ht_caps(hw, &priv->band_50, caps);
+	}
+}
+
 static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
 {
 	struct mwl8k_priv *priv = hw->priv;
@@ -1707,6 +1783,9 @@ static int mwl8k_cmd_get_hw_spec_sta(str
 		priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
 		priv->fw_rev = le32_to_cpu(cmd->fw_rev);
 		priv->hw_rev = cmd->hw_rev;
+		mwl8k_set_caps(hw, le32_to_cpu(cmd->caps));
+		priv->ap_macids_supported = 0x00000000;
+		priv->sta_macids_supported = 0x00000001;
 	}
 
 	kfree(cmd);
@@ -1760,6 +1839,9 @@ static int mwl8k_cmd_get_hw_spec_ap(stru
 		priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
 		priv->fw_rev = le32_to_cpu(cmd->fw_rev);
 		priv->hw_rev = cmd->hw_rev;
+		mwl8k_setup_2ghz_band(hw);
+		priv->ap_macids_supported = 0x000000ff;
+		priv->sta_macids_supported = 0x00000000;
 
 		off = le32_to_cpu(cmd->wcbbase0) & 0xffff;
 		iowrite32(cpu_to_le32(priv->txq[0].txd_dma), priv->sram + off);
@@ -1805,7 +1887,9 @@ struct mwl8k_cmd_set_hw_spec {
 	__le32 total_rxd;
 } __attribute__((packed));
 
-#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT	0x00000080
+#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT		0x00000080
+#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP	0x00000020
+#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON		0x00000010
 
 static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
 {
@@ -1826,7 +1910,9 @@ static int mwl8k_cmd_set_hw_spec(struct
 	cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
 	for (i = 0; i < MWL8K_TX_QUEUES; i++)
 		cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
-	cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT);
+	cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT |
+				 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP |
+				 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON);
 	cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
 	cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
 
@@ -1896,9 +1982,9 @@ __mwl8k_cmd_mac_multicast_adr(struct iee
 }
 
 /*
- * CMD_802_11_GET_STAT.
+ * CMD_GET_STAT.
  */
-struct mwl8k_cmd_802_11_get_stat {
+struct mwl8k_cmd_get_stat {
 	struct mwl8k_cmd_pkt header;
 	__le32 stats[64];
 } __attribute__((packed));
@@ -1908,10 +1994,10 @@ struct mwl8k_cmd_802_11_get_stat {
 #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)
+static int mwl8k_cmd_get_stat(struct ieee80211_hw *hw,
+			      struct ieee80211_low_level_stats *stats)
 {
-	struct mwl8k_cmd_802_11_get_stat *cmd;
+	struct mwl8k_cmd_get_stat *cmd;
 	int rc;
 
 	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -1938,9 +2024,9 @@ static int mwl8k_cmd_802_11_get_stat(str
 }
 
 /*
- * CMD_802_11_RADIO_CONTROL.
+ * CMD_RADIO_CONTROL.
  */
-struct mwl8k_cmd_802_11_radio_control {
+struct mwl8k_cmd_radio_control {
 	struct mwl8k_cmd_pkt header;
 	__le16 action;
 	__le16 control;
@@ -1948,10 +2034,10 @@ struct mwl8k_cmd_802_11_radio_control {
 } __attribute__((packed));
 
 static int
-mwl8k_cmd_802_11_radio_control(struct ieee80211_hw *hw, bool enable, bool force)
+mwl8k_cmd_radio_control(struct ieee80211_hw *hw, bool enable, bool force)
 {
 	struct mwl8k_priv *priv = hw->priv;
-	struct mwl8k_cmd_802_11_radio_control *cmd;
+	struct mwl8k_cmd_radio_control *cmd;
 	int rc;
 
 	if (enable == priv->radio_on && !force)
@@ -1976,36 +2062,32 @@ mwl8k_cmd_802_11_radio_control(struct ie
 	return rc;
 }
 
-static int mwl8k_cmd_802_11_radio_disable(struct ieee80211_hw *hw)
+static int mwl8k_cmd_radio_disable(struct ieee80211_hw *hw)
 {
-	return mwl8k_cmd_802_11_radio_control(hw, 0, 0);
+	return mwl8k_cmd_radio_control(hw, 0, 0);
 }
 
-static int mwl8k_cmd_802_11_radio_enable(struct ieee80211_hw *hw)
+static int mwl8k_cmd_radio_enable(struct ieee80211_hw *hw)
 {
-	return mwl8k_cmd_802_11_radio_control(hw, 1, 0);
+	return mwl8k_cmd_radio_control(hw, 1, 0);
 }
 
 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;
+	struct mwl8k_priv *priv = hw->priv;
 
 	priv->radio_short_preamble = short_preamble;
 
-	return mwl8k_cmd_802_11_radio_control(hw, 1, 1);
+	return mwl8k_cmd_radio_control(hw, 1, 1);
 }
 
 /*
- * CMD_802_11_RF_TX_POWER.
+ * CMD_RF_TX_POWER.
  */
 #define MWL8K_TX_POWER_LEVEL_TOTAL	8
 
-struct mwl8k_cmd_802_11_rf_tx_power {
+struct mwl8k_cmd_rf_tx_power {
 	struct mwl8k_cmd_pkt header;
 	__le16 action;
 	__le16 support_level;
@@ -2014,9 +2096,9 @@ struct mwl8k_cmd_802_11_rf_tx_power {
 	__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)
+static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm)
 {
-	struct mwl8k_cmd_802_11_rf_tx_power *cmd;
+	struct mwl8k_cmd_rf_tx_power *cmd;
 	int rc;
 
 	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -2068,6 +2150,36 @@ mwl8k_cmd_rf_antenna(struct ieee80211_hw
 }
 
 /*
+ * CMD_SET_BEACON.
+ */
+struct mwl8k_cmd_set_beacon {
+	struct mwl8k_cmd_pkt header;
+	__le16 beacon_len;
+	__u8 beacon[0];
+};
+
+static int mwl8k_cmd_set_beacon(struct ieee80211_hw *hw,
+				struct ieee80211_vif *vif, u8 *beacon, int len)
+{
+	struct mwl8k_cmd_set_beacon *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd) + len, GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_BEACON);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd) + len);
+	cmd->beacon_len = cpu_to_le16(len);
+	memcpy(cmd->beacon, beacon, len);
+
+	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
  * CMD_SET_PRE_SCAN.
  */
 struct mwl8k_cmd_set_pre_scan {
@@ -2102,7 +2214,7 @@ struct mwl8k_cmd_set_post_scan {
 } __attribute__((packed));
 
 static int
-mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, __u8 *mac)
+mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, const __u8 *mac)
 {
 	struct mwl8k_cmd_set_post_scan *cmd;
 	int rc;
@@ -2133,8 +2245,9 @@ struct mwl8k_cmd_set_rf_channel {
 } __attribute__((packed));
 
 static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
-				    struct ieee80211_channel *channel)
+				    struct ieee80211_conf *conf)
 {
+	struct ieee80211_channel *channel = conf->channel;
 	struct mwl8k_cmd_set_rf_channel *cmd;
 	int rc;
 
@@ -2146,10 +2259,19 @@ static int mwl8k_cmd_set_rf_channel(stru
 	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);
+		cmd->channel_flags |= cpu_to_le32(0x00000001);
+	else if (channel->band == IEEE80211_BAND_5GHZ)
+		cmd->channel_flags |= cpu_to_le32(0x00000004);
+
+	if (conf->channel_type == NL80211_CHAN_NO_HT ||
+	    conf->channel_type == NL80211_CHAN_HT20)
+		cmd->channel_flags |= cpu_to_le32(0x00000080);
+	else if (conf->channel_type == NL80211_CHAN_HT40MINUS)
+		cmd->channel_flags |= cpu_to_le32(0x000001900);
+	else if (conf->channel_type == NL80211_CHAN_HT40PLUS)
+		cmd->channel_flags |= cpu_to_le32(0x000000900);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
@@ -2158,85 +2280,75 @@ static int mwl8k_cmd_set_rf_channel(stru
 }
 
 /*
- * CMD_SET_SLOT.
+ * CMD_SET_AID.
  */
-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, bool short_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 = short_slot_time;
-
-	rc = mwl8k_post_cmd(hw, &cmd->header);
-	kfree(cmd);
+#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
 
-	return rc;
-}
+struct mwl8k_cmd_update_set_aid {
+	struct	mwl8k_cmd_pkt header;
+	__le16	aid;
 
-/*
- * CMD_MIMO_CONFIG.
- */
-struct mwl8k_cmd_mimo_config {
-	struct mwl8k_cmd_pkt header;
-	__le32 action;
-	__u8 rx_antenna_map;
-	__u8 tx_antenna_map;
+	 /* AP's MAC address (BSSID) */
+	__u8	bssid[ETH_ALEN];
+	__le16	protection_mode;
+	__u8	supp_rates[14];
 } __attribute__((packed));
 
-static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx)
+static void legacy_rate_mask_to_array(u8 *rates, u32 mask)
 {
-	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;
+	int i;
+	int j;
 
-	rc = mwl8k_post_cmd(hw, &cmd->header);
-	kfree(cmd);
+	/*
+	 * Clear nonstandard rates 4 and 13.
+	 */
+	mask &= 0x1fef;
 
-	return rc;
+	for (i = 0, j = 0; i < 14; i++) {
+		if (mask & (1 << i))
+			rates[j++] = mwl8k_rates_24[i].hw_value;
+	}
 }
 
-/*
- * 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)
+static int
+mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
+		  struct ieee80211_vif *vif, u32 legacy_rate_mask)
 {
-	struct mwl8k_cmd_enable_sniffer *cmd;
+	struct mwl8k_cmd_update_set_aid *cmd;
+	u16 prot_mode;
 	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.code = cpu_to_le16(MWL8K_CMD_SET_AID);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
-	cmd->action = cpu_to_le32(!!enable);
+	cmd->aid = cpu_to_le16(vif->bss_conf.aid);
+	memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
+
+	if (vif->bss_conf.use_cts_prot) {
+		prot_mode = MWL8K_FRAME_PROT_11G;
+	} else {
+		switch (vif->bss_conf.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);
+
+	legacy_rate_mask_to_array(cmd->supp_rates, legacy_rate_mask);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
@@ -2245,37 +2357,32 @@ static int mwl8k_enable_sniffer(struct i
 }
 
 /*
- * CMD_SET_MAC_ADDR.
+ * CMD_SET_RATE.
  */
-struct mwl8k_cmd_set_mac_addr {
-	struct mwl8k_cmd_pkt header;
-	union {
-		struct {
-			__le16 mac_type;
-			__u8 mac_addr[ETH_ALEN];
-		} mbss;
-		__u8 mac_addr[ETH_ALEN];
-	};
+struct mwl8k_cmd_set_rate {
+	struct	mwl8k_cmd_pkt header;
+	__u8	legacy_rates[14];
+
+	/* Bitmap for supported MCS codes.  */
+	__u8	mcs_set[16];
+	__u8	reserved[16];
 } __attribute__((packed));
 
-static int mwl8k_set_mac_addr(struct ieee80211_hw *hw, u8 *mac)
+static int
+mwl8k_cmd_set_rate(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		   u32 legacy_rate_mask, u8 *mcs_rates)
 {
-	struct mwl8k_priv *priv = hw->priv;
-	struct mwl8k_cmd_set_mac_addr *cmd;
+	struct mwl8k_cmd_set_rate *cmd;
 	int rc;
 
 	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 	if (cmd == NULL)
 		return -ENOMEM;
 
-	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR);
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
-	if (priv->ap_fw) {
-		cmd->mbss.mac_type = 0;
-		memcpy(cmd->mbss.mac_addr, mac, ETH_ALEN);
-	} else {
-		memcpy(cmd->mac_addr, mac, ETH_ALEN);
-	}
+	legacy_rate_mask_to_array(cmd->legacy_rates, legacy_rate_mask);
+	memcpy(cmd->mcs_set, mcs_rates, 16);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
@@ -2283,29 +2390,40 @@ static int mwl8k_set_mac_addr(struct iee
 	return rc;
 }
 
-
 /*
- * CMD_SET_RATEADAPT_MODE.
+ * CMD_FINALIZE_JOIN.
  */
-struct mwl8k_cmd_set_rate_adapt_mode {
+#define MWL8K_FJ_BEACON_MAXLEN	128
+
+struct mwl8k_cmd_finalize_join {
 	struct mwl8k_cmd_pkt header;
-	__le16 action;
-	__le16 mode;
+	__le32 sleep_interval;	/* Number of beacon periods to sleep */
+	__u8 beacon_data[MWL8K_FJ_BEACON_MAXLEN];
 } __attribute__((packed));
 
-static int mwl8k_cmd_setrateadaptmode(struct ieee80211_hw *hw, __u16 mode)
+static int mwl8k_cmd_finalize_join(struct ieee80211_hw *hw, void *frame,
+				   int framelen, int dtim)
 {
-	struct mwl8k_cmd_set_rate_adapt_mode *cmd;
+	struct mwl8k_cmd_finalize_join *cmd;
+	struct ieee80211_mgmt *payload = frame;
+	int payload_len;
 	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.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
-	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
-	cmd->mode = cpu_to_le16(mode);
+	cmd->sleep_interval = cpu_to_le32(dtim ? dtim : 1);
+
+	payload_len = framelen - ieee80211_hdrlen(payload->frame_control);
+	if (payload_len < 0)
+		payload_len = 0;
+	else if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
+		payload_len = MWL8K_FJ_BEACON_MAXLEN;
+
+	memcpy(cmd->beacon_data, &payload->u.beacon, payload_len);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
@@ -2314,59 +2432,57 @@ static int mwl8k_cmd_setrateadaptmode(st
 }
 
 /*
- * CMD_SET_WMM_MODE.
+ * CMD_SET_RTS_THRESHOLD.
  */
-struct mwl8k_cmd_set_wmm {
+struct mwl8k_cmd_set_rts_threshold {
 	struct mwl8k_cmd_pkt header;
 	__le16 action;
+	__le16 threshold;
 } __attribute__((packed));
 
-static int mwl8k_set_wmm(struct ieee80211_hw *hw, bool enable)
+static int
+mwl8k_cmd_set_rts_threshold(struct ieee80211_hw *hw, int rts_thresh)
 {
-	struct mwl8k_priv *priv = hw->priv;
-	struct mwl8k_cmd_set_wmm *cmd;
+	struct mwl8k_cmd_set_rts_threshold *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.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
-	cmd->action = cpu_to_le16(!!enable);
+	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+	cmd->threshold = cpu_to_le16(rts_thresh);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
 
-	if (!rc)
-		priv->wmm_enabled = enable;
-
 	return rc;
 }
 
 /*
- * CMD_SET_RTS_THRESHOLD.
+ * CMD_SET_SLOT.
  */
-struct mwl8k_cmd_rts_threshold {
+struct mwl8k_cmd_set_slot {
 	struct mwl8k_cmd_pkt header;
 	__le16 action;
-	__le16 threshold;
+	__u8 short_slot;
 } __attribute__((packed));
 
-static int mwl8k_rts_threshold(struct ieee80211_hw *hw,
-			       u16 action, u16 threshold)
+static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, bool short_slot_time)
 {
-	struct mwl8k_cmd_rts_threshold *cmd;
+	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_RTS_THRESHOLD);
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
-	cmd->action = cpu_to_le16(action);
-	cmd->threshold = cpu_to_le16(threshold);
+	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+	cmd->short_slot = short_slot_time;
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
@@ -2425,9 +2541,9 @@ struct mwl8k_cmd_set_edca_params {
 				 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)
+mwl8k_cmd_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
+			  __u16 cw_min, __u16 cw_max,
+			  __u8 aifs, __u16 txop)
 {
 	struct mwl8k_priv *priv = hw->priv;
 	struct mwl8k_cmd_set_edca_params *cmd;
@@ -2437,12 +2553,6 @@ mwl8k_set_edca_params(struct ieee80211_h
 	if (cmd == NULL)
 		return -ENOMEM;
 
-	/*
-	 * Queues 0 (BE) and 1 (BK) are swapped in hardware for
-	 * this call.
-	 */
-	qnum ^= !(qnum >> 1);
-
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
 	cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL);
@@ -2466,170 +2576,259 @@ mwl8k_set_edca_params(struct ieee80211_h
 }
 
 /*
- * CMD_FINALIZE_JOIN.
+ * CMD_SET_WMM_MODE.
  */
-#define MWL8K_FJ_BEACON_MAXLEN	128
-
-struct mwl8k_cmd_finalize_join {
+struct mwl8k_cmd_set_wmm_mode {
 	struct mwl8k_cmd_pkt header;
-	__le32 sleep_interval;	/* Number of beacon periods to sleep */
-	__u8 beacon_data[MWL8K_FJ_BEACON_MAXLEN];
+	__le16 action;
 } __attribute__((packed));
 
-static int mwl8k_finalize_join(struct ieee80211_hw *hw, void *frame,
-			       int framelen, int dtim)
+static int mwl8k_cmd_set_wmm_mode(struct ieee80211_hw *hw, bool enable)
 {
-	struct mwl8k_cmd_finalize_join *cmd;
-	struct ieee80211_mgmt *payload = frame;
-	int payload_len;
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_cmd_set_wmm_mode *cmd;
 	int rc;
 
 	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 	if (cmd == NULL)
 		return -ENOMEM;
 
-	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN);
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
-	cmd->sleep_interval = cpu_to_le32(dtim ? dtim : 1);
-
-	payload_len = framelen - ieee80211_hdrlen(payload->frame_control);
-	if (payload_len < 0)
-		payload_len = 0;
-	else if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
-		payload_len = MWL8K_FJ_BEACON_MAXLEN;
-
-	memcpy(cmd->beacon_data, &payload->u.beacon, payload_len);
+	cmd->action = cpu_to_le16(!!enable);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
 
+	if (!rc)
+		priv->wmm_enabled = enable;
+
 	return rc;
 }
 
 /*
- * CMD_UPDATE_STADB.
+ * CMD_MIMO_CONFIG.
  */
-struct mwl8k_cmd_update_sta_db {
+struct mwl8k_cmd_mimo_config {
 	struct mwl8k_cmd_pkt header;
+	__le32 action;
+	__u8 rx_antenna_map;
+	__u8 tx_antenna_map;
+} __attribute__((packed));
 
-	/* See STADB_ACTION_TYPE */
-	__le32	action;
+static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx)
+{
+	struct mwl8k_cmd_mimo_config *cmd;
+	int rc;
 
-	/* Peer MAC address */
-	__u8	peer_addr[ETH_ALEN];
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
 
-	__le32	reserved;
+	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;
 
-	/* Peer info - valid during add/update.  */
-	struct peer_capability_info	peer_info;
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_USE_FIXED_RATE (STA version).
+ */
+struct mwl8k_cmd_use_fixed_rate_sta {
+	struct mwl8k_cmd_pkt header;
+	__le32 action;
+	__le32 allow_rate_drop;
+	__le32 num_rates;
+	struct {
+		__le32 is_ht_rate;
+		__le32 enable_retry;
+		__le32 rate;
+		__le32 retry_count;
+	} rate_entry[8];
+	__le32 rate_type;
+	__le32 reserved1;
+	__le32 reserved2;
 } __attribute__((packed));
 
-static int mwl8k_cmd_update_sta_db(struct ieee80211_hw *hw,
-		struct ieee80211_vif *vif, __u32 action)
+#define MWL8K_USE_AUTO_RATE	0x0002
+#define MWL8K_UCAST_RATE	0
+
+static int mwl8k_cmd_use_fixed_rate_sta(struct ieee80211_hw *hw)
 {
-	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 mwl8k_cmd_use_fixed_rate_sta *cmd;
 	int rc;
 
 	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 	if (cmd == NULL)
 		return -ENOMEM;
 
-	cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE);
+	cmd->rate_type = cpu_to_le32(MWL8K_UCAST_RATE);
 
-	cmd->action = cpu_to_le32(action);
-	peer_info = &cmd->peer_info;
-	memcpy(cmd->peer_addr, mv_vif->bssid, ETH_ALEN);
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
 
-	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);
-		memcpy(peer_info->legacy_rates, mwl8k_rateids,
-		       sizeof(mwl8k_rateids));
-		peer_info->interop = 1;
-		peer_info->amsdu_enabled = 0;
+	return rc;
+}
 
-		rc = mwl8k_post_cmd(hw, &cmd->header);
-		if (rc == 0)
-			mv_vif->peer_id = peer_info->station_id;
+/*
+ * CMD_USE_FIXED_RATE (AP version).
+ */
+struct mwl8k_cmd_use_fixed_rate_ap {
+	struct mwl8k_cmd_pkt header;
+	__le32 action;
+	__le32 allow_rate_drop;
+	__le32 num_rates;
+	struct mwl8k_rate_entry_ap {
+		__le32 is_ht_rate;
+		__le32 enable_retry;
+		__le32 rate;
+		__le32 retry_count;
+	} rate_entry[4];
+	u8 multicast_rate;
+	u8 multicast_rate_type;
+	u8 management_rate;
+} __attribute__((packed));
 
-		break;
+static int
+mwl8k_cmd_use_fixed_rate_ap(struct ieee80211_hw *hw, int mcast, int mgmt)
+{
+	struct mwl8k_cmd_use_fixed_rate_ap *cmd;
+	int rc;
 
-	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;
-	}
+	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(MWL8K_USE_AUTO_RATE);
+	cmd->multicast_rate = mcast;
+	cmd->management_rate = mgmt;
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
 
 	return rc;
 }
 
 /*
- * CMD_SET_AID.
+ * CMD_ENABLE_SNIFFER.
  */
-#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
-
-struct mwl8k_cmd_update_set_aid {
-	struct	mwl8k_cmd_pkt header;
-	__le16	aid;
-
-	 /* AP's MAC address (BSSID) */
-	__u8	bssid[ETH_ALEN];
-	__le16	protection_mode;
-	__u8	supp_rates[14];
+struct mwl8k_cmd_enable_sniffer {
+	struct mwl8k_cmd_pkt header;
+	__le32 action;
 } __attribute__((packed));
 
-static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
-					struct ieee80211_vif *vif)
+static int mwl8k_cmd_enable_sniffer(struct ieee80211_hw *hw, bool enable)
 {
-	struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
-	struct ieee80211_bss_conf *info = &mv_vif->bss_info;
-	struct mwl8k_cmd_update_set_aid *cmd;
-	u16 prot_mode;
+	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_SET_AID);
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
-	cmd->aid = cpu_to_le16(info->aid);
+	cmd->action = cpu_to_le32(!!enable);
 
-	memcpy(cmd->bssid, mv_vif->bssid, ETH_ALEN);
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
 
-	if (info->use_cts_prot) {
-		prot_mode = MWL8K_FRAME_PROT_11G;
+	return rc;
+}
+
+/*
+ * CMD_SET_MAC_ADDR.
+ */
+struct mwl8k_cmd_set_mac_addr {
+	struct mwl8k_cmd_pkt header;
+	union {
+		struct {
+			__le16 mac_type;
+			__u8 mac_addr[ETH_ALEN];
+		} mbss;
+		__u8 mac_addr[ETH_ALEN];
+	};
+} __attribute__((packed));
+
+#define MWL8K_MAC_TYPE_PRIMARY_CLIENT		0
+#define MWL8K_MAC_TYPE_SECONDARY_CLIENT		1
+#define MWL8K_MAC_TYPE_PRIMARY_AP		2
+#define MWL8K_MAC_TYPE_SECONDARY_AP		3
+
+static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw,
+				  struct ieee80211_vif *vif, u8 *mac)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
+	struct mwl8k_cmd_set_mac_addr *cmd;
+	int mac_type;
+	int rc;
+
+	mac_type = MWL8K_MAC_TYPE_PRIMARY_AP;
+	if (vif != NULL && vif->type == NL80211_IFTYPE_STATION) {
+		if (mwl8k_vif->macid + 1 == ffs(priv->sta_macids_supported))
+			mac_type = MWL8K_MAC_TYPE_PRIMARY_CLIENT;
+		else
+			mac_type = MWL8K_MAC_TYPE_SECONDARY_CLIENT;
+	} else if (vif != NULL && vif->type == NL80211_IFTYPE_AP) {
+		if (mwl8k_vif->macid + 1 == ffs(priv->ap_macids_supported))
+			mac_type = MWL8K_MAC_TYPE_PRIMARY_AP;
+		else
+			mac_type = MWL8K_MAC_TYPE_SECONDARY_AP;
+	}
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	if (priv->ap_fw) {
+		cmd->mbss.mac_type = cpu_to_le16(mac_type);
+		memcpy(cmd->mbss.mac_addr, mac, ETH_ALEN);
 	} 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;
-		}
+		memcpy(cmd->mac_addr, mac, ETH_ALEN);
 	}
-	cmd->protection_mode = cpu_to_le16(prot_mode);
 
-	memcpy(cmd->supp_rates, mwl8k_rateids, sizeof(mwl8k_rateids));
+	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_SET_RATEADAPT_MODE.
+ */
+struct mwl8k_cmd_set_rate_adapt_mode {
+	struct mwl8k_cmd_pkt header;
+	__le16 action;
+	__le16 mode;
+} __attribute__((packed));
+
+static int mwl8k_cmd_set_rateadapt_mode(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);
@@ -2638,115 +2837,255 @@ static int mwl8k_cmd_set_aid(struct ieee
 }
 
 /*
- * CMD_SET_RATE.
+ * CMD_BSS_START.
  */
-struct mwl8k_cmd_update_rateset {
-	struct	mwl8k_cmd_pkt header;
-	__u8	legacy_rates[14];
-
-	/* Bitmap for supported MCS codes.  */
-	__u8	mcs_set[16];
-	__u8	reserved[16];
+struct mwl8k_cmd_bss_start {
+	struct mwl8k_cmd_pkt header;
+	__le32 enable;
 } __attribute__((packed));
 
-static int mwl8k_update_rateset(struct ieee80211_hw *hw,
-		struct ieee80211_vif *vif)
+static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
+			       struct ieee80211_vif *vif, int enable)
 {
-	struct mwl8k_cmd_update_rateset *cmd;
+	struct mwl8k_cmd_bss_start *cmd;
 	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.code = cpu_to_le16(MWL8K_CMD_BSS_START);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
-	memcpy(cmd->legacy_rates, mwl8k_rateids, sizeof(mwl8k_rateids));
+	cmd->enable = cpu_to_le32(enable);
 
-	rc = mwl8k_post_cmd(hw, &cmd->header);
+	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
 	kfree(cmd);
 
 	return rc;
 }
 
 /*
- * CMD_USE_FIXED_RATE.
+ * CMD_SET_NEW_STN.
  */
-#define MWL8K_RATE_TABLE_SIZE	8
-#define MWL8K_UCAST_RATE	0
-#define MWL8K_USE_AUTO_RATE	0x0002
+struct mwl8k_cmd_set_new_stn {
+	struct mwl8k_cmd_pkt header;
+	__le16 aid;
+	__u8 mac_addr[6];
+	__le16 stn_id;
+	__le16 action;
+	__le16 rsvd;
+	__le32 legacy_rates;
+	__u8 ht_rates[4];
+	__le16 cap_info;
+	__le16 ht_capabilities_info;
+	__u8 mac_ht_param_info;
+	__u8 rev;
+	__u8 control_channel;
+	__u8 add_channel;
+	__le16 op_mode;
+	__le16 stbc;
+	__u8 add_qos_info;
+	__u8 is_qos_sta;
+	__le32 fw_sta_ptr;
+} __attribute__((packed));
 
-struct mwl8k_rate_entry {
-	/* Set to 1 if HT rate, 0 if legacy.  */
-	__le32	is_ht_rate;
+#define MWL8K_STA_ACTION_ADD		0
+#define MWL8K_STA_ACTION_REMOVE		2
 
-	/* Set to 1 to use retry_count field.  */
-	__le32	enable_retry;
+static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw,
+				     struct ieee80211_vif *vif,
+				     struct ieee80211_sta *sta)
+{
+	struct mwl8k_cmd_set_new_stn *cmd;
+	u32 rates;
+	int rc;
 
-	/* Specified legacy rate or MCS.  */
-	__le32	rate;
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
 
-	/* Number of allowed retries.  */
-	__le32	retry_count;
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->aid = cpu_to_le16(sta->aid);
+	memcpy(cmd->mac_addr, sta->addr, ETH_ALEN);
+	cmd->stn_id = cpu_to_le16(sta->aid);
+	cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD);
+	if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+		rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
+	else
+		rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
+	cmd->legacy_rates = cpu_to_le32(rates);
+	if (sta->ht_cap.ht_supported) {
+		cmd->ht_rates[0] = sta->ht_cap.mcs.rx_mask[0];
+		cmd->ht_rates[1] = sta->ht_cap.mcs.rx_mask[1];
+		cmd->ht_rates[2] = sta->ht_cap.mcs.rx_mask[2];
+		cmd->ht_rates[3] = sta->ht_cap.mcs.rx_mask[3];
+		cmd->ht_capabilities_info = cpu_to_le16(sta->ht_cap.cap);
+		cmd->mac_ht_param_info = (sta->ht_cap.ampdu_factor & 3) |
+			((sta->ht_cap.ampdu_density & 7) << 2);
+		cmd->is_qos_sta = 1;
+	}
+
+	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+static int mwl8k_cmd_set_new_stn_add_self(struct ieee80211_hw *hw,
+					  struct ieee80211_vif *vif)
+{
+	struct mwl8k_cmd_set_new_stn *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	memcpy(cmd->mac_addr, vif->addr, ETH_ALEN);
+
+	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+static int mwl8k_cmd_set_new_stn_del(struct ieee80211_hw *hw,
+				     struct ieee80211_vif *vif, u8 *addr)
+{
+	struct mwl8k_cmd_set_new_stn *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	memcpy(cmd->mac_addr, addr, ETH_ALEN);
+	cmd->action = cpu_to_le16(MWL8K_STA_ACTION_REMOVE);
+
+	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_UPDATE_STADB.
+ */
+struct ewc_ht_info {
+	__le16	control1;
+	__le16	control2;
+	__le16	control3;
 } __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];
+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[12];
+
+	/* HT rate table. Intersection of our rates and peer rates.  */
+	__u8	ht_rates[16];
+	__u8	pad[16];
+
+	/* If set, interoperability mode, no proprietary extensions.  */
+	__u8	interop;
+	__u8	pad2;
+	__u8	station_id;
+	__le16	amsdu_enabled;
 } __attribute__((packed));
 
-struct mwl8k_cmd_use_fixed_rate {
-	struct	mwl8k_cmd_pkt header;
+struct mwl8k_cmd_update_stadb {
+	struct mwl8k_cmd_pkt header;
+
+	/* See STADB_ACTION_TYPE */
 	__le32	action;
-	struct mwl8k_rate_table rate_table;
 
-	/* Unicast, Broadcast or Multicast */
-	__le32	rate_type;
-	__le32	reserved1;
-	__le32	reserved2;
+	/* Peer MAC address */
+	__u8	peer_addr[ETH_ALEN];
+
+	__le32	reserved;
+
+	/* Peer info - valid during add/update.  */
+	struct peer_capability_info	peer_info;
 } __attribute__((packed));
 
-static int mwl8k_cmd_use_fixed_rate(struct ieee80211_hw *hw,
-	u32 action, u32 rate_type, struct mwl8k_rate_table *rate_table)
+#define MWL8K_STA_DB_MODIFY_ENTRY	1
+#define MWL8K_STA_DB_DEL_ENTRY		2
+
+/* Peer Entry flags - used to define the type of the peer node */
+#define MWL8K_PEER_TYPE_ACCESSPOINT	2
+
+static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw,
+				      struct ieee80211_vif *vif,
+				      struct ieee80211_sta *sta)
 {
-	struct mwl8k_cmd_use_fixed_rate *cmd;
-	int count;
+	struct mwl8k_cmd_update_stadb *cmd;
+	struct peer_capability_info *p;
+	u32 rates;
 	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.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->action = cpu_to_le32(MWL8K_STA_DB_MODIFY_ENTRY);
+	memcpy(cmd->peer_addr, sta->addr, ETH_ALEN);
 
-	cmd->action = cpu_to_le32(action);
-	cmd->rate_type = cpu_to_le32(rate_type);
+	p = &cmd->peer_info;
+	p->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT;
+	p->basic_caps = cpu_to_le16(vif->bss_conf.assoc_capability);
+	p->ht_support = sta->ht_cap.ht_supported;
+	p->ht_caps = sta->ht_cap.cap;
+	p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) |
+		((sta->ht_cap.ampdu_density & 7) << 2);
+	if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+		rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
+	else
+		rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
+	legacy_rate_mask_to_array(p->legacy_rates, rates);
+	memcpy(p->ht_rates, sta->ht_cap.mcs.rx_mask, 16);
+	p->interop = 1;
+	p->amsdu_enabled = 0;
 
-	if (rate_table != NULL) {
-		/*
-		 * Copy over each field manually so that endian
-		 * conversion can be done.
-		 */
-		cmd->rate_table.allow_rate_drop =
-				cpu_to_le32(rate_table->allow_rate_drop);
-		cmd->rate_table.num_rates =
-				cpu_to_le32(rate_table->num_rates);
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
 
-		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];
+	return rc ? rc : p->station_id;
+}
 
-			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);
-		}
-	}
+static int mwl8k_cmd_update_stadb_del(struct ieee80211_hw *hw,
+				      struct ieee80211_vif *vif, u8 *addr)
+{
+	struct mwl8k_cmd_update_stadb *cmd;
+	int rc;
+
+	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(MWL8K_STA_DB_DEL_ENTRY);
+	memcpy(cmd->peer_addr, addr, ETH_ALEN);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
@@ -2765,19 +3104,22 @@ static irqreturn_t mwl8k_interrupt(int i
 	u32 status;
 
 	status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
-	iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
-
 	if (!status)
 		return IRQ_NONE;
 
-	if (status & MWL8K_A2H_INT_TX_DONE)
-		tasklet_schedule(&priv->tx_reclaim_task);
+	if (status & MWL8K_A2H_INT_TX_DONE) {
+		status &= ~MWL8K_A2H_INT_TX_DONE;
+		tasklet_schedule(&priv->poll_tx_task);
+	}
 
 	if (status & MWL8K_A2H_INT_RX_READY) {
-		while (rxq_process(hw, 0, 1))
-			rxq_refill(hw, 0, 1);
+		status &= ~MWL8K_A2H_INT_RX_READY;
+		tasklet_schedule(&priv->poll_rx_task);
 	}
 
+	if (status)
+		iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+
 	if (status & MWL8K_A2H_INT_OPC_DONE) {
 		if (priv->hostcmd_wait != NULL)
 			complete(priv->hostcmd_wait);
@@ -2792,6 +3134,53 @@ static irqreturn_t mwl8k_interrupt(int i
 	return IRQ_HANDLED;
 }
 
+static void mwl8k_tx_poll(unsigned long data)
+{
+	struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
+	struct mwl8k_priv *priv = hw->priv;
+	int limit;
+	int i;
+
+	limit = 32;
+
+	spin_lock_bh(&priv->tx_lock);
+
+	for (i = 0; i < MWL8K_TX_QUEUES; i++)
+		limit -= mwl8k_txq_reclaim(hw, i, limit, 0);
+
+	if (!priv->pending_tx_pkts && priv->tx_wait != NULL) {
+		complete(priv->tx_wait);
+		priv->tx_wait = NULL;
+	}
+
+	spin_unlock_bh(&priv->tx_lock);
+
+	if (limit) {
+		writel(~MWL8K_A2H_INT_TX_DONE,
+		       priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+	} else {
+		tasklet_schedule(&priv->poll_tx_task);
+	}
+}
+
+static void mwl8k_rx_poll(unsigned long data)
+{
+	struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
+	struct mwl8k_priv *priv = hw->priv;
+	int limit;
+
+	limit = 32;
+	limit -= rxq_process(hw, 0, limit);
+	limit -= rxq_refill(hw, 0, limit);
+
+	if (limit) {
+		writel(~MWL8K_A2H_INT_RX_READY,
+		       priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+	} else {
+		tasklet_schedule(&priv->poll_rx_task);
+	}
+}
+
 
 /*
  * Core driver operations.
@@ -2802,7 +3191,7 @@ static int mwl8k_tx(struct ieee80211_hw
 	int index = skb_get_queue_mapping(skb);
 	int rc;
 
-	if (priv->current_channel == NULL) {
+	if (!priv->radio_on) {
 		printk(KERN_DEBUG "%s: dropped TX frame since radio "
 		       "disabled\n", wiphy_name(hw->wiphy));
 		dev_kfree_skb(skb);
@@ -2827,19 +3216,20 @@ static int mwl8k_start(struct ieee80211_
 		return -EIO;
 	}
 
-	/* Enable tx reclaim tasklet */
-	tasklet_enable(&priv->tx_reclaim_task);
+	/* Enable TX reclaim and RX tasklets.  */
+	tasklet_enable(&priv->poll_tx_task);
+	tasklet_enable(&priv->poll_rx_task);
 
 	/* Enable interrupts */
 	iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
 
 	rc = mwl8k_fw_lock(hw);
 	if (!rc) {
-		rc = mwl8k_cmd_802_11_radio_enable(hw);
+		rc = mwl8k_cmd_radio_enable(hw);
 
 		if (!priv->ap_fw) {
 			if (!rc)
-				rc = mwl8k_enable_sniffer(hw, 0);
+				rc = mwl8k_cmd_enable_sniffer(hw, 0);
 
 			if (!rc)
 				rc = mwl8k_cmd_set_pre_scan(hw);
@@ -2850,10 +3240,10 @@ static int mwl8k_start(struct ieee80211_
 		}
 
 		if (!rc)
-			rc = mwl8k_cmd_setrateadaptmode(hw, 0);
+			rc = mwl8k_cmd_set_rateadapt_mode(hw, 0);
 
 		if (!rc)
-			rc = mwl8k_set_wmm(hw, 0);
+			rc = mwl8k_cmd_set_wmm_mode(hw, 0);
 
 		mwl8k_fw_unlock(hw);
 	}
@@ -2861,7 +3251,8 @@ static int mwl8k_start(struct ieee80211_
 	if (rc) {
 		iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
 		free_irq(priv->pdev->irq, hw);
-		tasklet_disable(&priv->tx_reclaim_task);
+		tasklet_disable(&priv->poll_tx_task);
+		tasklet_disable(&priv->poll_rx_task);
 	}
 
 	return rc;
@@ -2872,7 +3263,7 @@ static void mwl8k_stop(struct ieee80211_
 	struct mwl8k_priv *priv = hw->priv;
 	int i;
 
-	mwl8k_cmd_802_11_radio_disable(hw);
+	mwl8k_cmd_radio_disable(hw);
 
 	ieee80211_stop_queues(hw);
 
@@ -2885,36 +3276,27 @@ static void mwl8k_stop(struct ieee80211_
 	if (priv->beacon_skb != NULL)
 		dev_kfree_skb(priv->beacon_skb);
 
-	/* Stop tx reclaim tasklet */
-	tasklet_disable(&priv->tx_reclaim_task);
+	/* Stop TX reclaim and RX tasklets.  */
+	tasklet_disable(&priv->poll_tx_task);
+	tasklet_disable(&priv->poll_rx_task);
 
 	/* Return all skbs to mac80211 */
 	for (i = 0; i < MWL8K_TX_QUEUES; i++)
-		mwl8k_txq_reclaim(hw, i, 1);
+		mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
 }
 
 static int mwl8k_add_interface(struct ieee80211_hw *hw,
-				struct ieee80211_if_init_conf *conf)
+			       struct ieee80211_vif *vif)
 {
 	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)
-		return -EINVAL;
+	u32 macids_supported;
+	int macid;
 
 	/*
 	 * Reject interface creation if sniffer mode is active, as
 	 * STA operation is mutually exclusive with hardware sniffer
-	 * mode.
+	 * mode.  (Sniffer mode is only used on STA firmware.)
 	 */
 	if (priv->sniffer_enabled) {
 		printk(KERN_INFO "%s: unable to create STA "
@@ -2923,37 +3305,54 @@ static int mwl8k_add_interface(struct ie
 		return -EINVAL;
 	}
 
-	/* Clean out driver private area */
-	mwl8k_vif = MWL8K_VIF(conf->vif);
-	memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
 
-	/* Set and save the mac address */
-	mwl8k_set_mac_addr(hw, conf->mac_addr);
-	memcpy(mwl8k_vif->mac_addr, conf->mac_addr, ETH_ALEN);
+	switch (vif->type) {
+	case NL80211_IFTYPE_AP:
+		macids_supported = priv->ap_macids_supported;
+		break;
+	case NL80211_IFTYPE_STATION:
+		macids_supported = priv->sta_macids_supported;
+		break;
+	default:
+		return -EINVAL;
+	}
 
-	/* Back pointer to parent config block */
-	mwl8k_vif->priv = priv;
+	macid = ffs(macids_supported & ~priv->macids_used);
+	if (!macid--)
+		return -EBUSY;
 
-	/* Set Initial sequence number to zero */
+	/* Setup driver private area. */
+	mwl8k_vif = MWL8K_VIF(vif);
+	memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
+	mwl8k_vif->vif = vif;
+	mwl8k_vif->macid = macid;
 	mwl8k_vif->seqno = 0;
 
-	priv->vif = conf->vif;
-	priv->current_channel = NULL;
+	/* Set the mac address.  */
+	mwl8k_cmd_set_mac_addr(hw, vif, vif->addr);
+
+	if (priv->ap_fw)
+		mwl8k_cmd_set_new_stn_add_self(hw, vif);
+
+	priv->macids_used |= 1 << mwl8k_vif->macid;
+	list_add_tail(&mwl8k_vif->list, &priv->vif_list);
 
 	return 0;
 }
 
 static void mwl8k_remove_interface(struct ieee80211_hw *hw,
-				   struct ieee80211_if_init_conf *conf)
+				   struct ieee80211_vif *vif)
 {
 	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
 
-	if (priv->vif == NULL)
-		return;
+	if (priv->ap_fw)
+		mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr);
 
-	mwl8k_set_mac_addr(hw, "\x00\x00\x00\x00\x00\x00");
+	mwl8k_cmd_set_mac_addr(hw, vif, "\x00\x00\x00\x00\x00\x00");
 
-	priv->vif = NULL;
+	priv->macids_used &= ~(1 << mwl8k_vif->macid);
+	list_del(&mwl8k_vif->list);
 }
 
 static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
@@ -2963,8 +3362,7 @@ static int mwl8k_config(struct ieee80211
 	int rc;
 
 	if (conf->flags & IEEE80211_CONF_IDLE) {
-		mwl8k_cmd_802_11_radio_disable(hw);
-		priv->current_channel = NULL;
+		mwl8k_cmd_radio_disable(hw);
 		return 0;
 	}
 
@@ -2972,19 +3370,17 @@ static int mwl8k_config(struct ieee80211
 	if (rc)
 		return rc;
 
-	rc = mwl8k_cmd_802_11_radio_enable(hw);
+	rc = mwl8k_cmd_radio_enable(hw);
 	if (rc)
 		goto out;
 
-	rc = mwl8k_cmd_set_rf_channel(hw, conf->channel);
+	rc = mwl8k_cmd_set_rf_channel(hw, conf);
 	if (rc)
 		goto out;
 
-	priv->current_channel = conf->channel;
-
 	if (conf->power_level > 18)
 		conf->power_level = 18;
-	rc = mwl8k_cmd_802_11_rf_tx_power(hw, conf->power_level);
+	rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level);
 	if (rc)
 		goto out;
 
@@ -3002,79 +3398,160 @@ out:
 	return rc;
 }
 
-static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
-				   struct ieee80211_vif *vif,
-				   struct ieee80211_bss_conf *info,
-				   u32 changed)
+static void
+mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+			   struct ieee80211_bss_conf *info, u32 changed)
 {
 	struct mwl8k_priv *priv = hw->priv;
-	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
+	u32 ap_legacy_rates;
+	u8 ap_mcs_rates[16];
 	int rc;
 
-	if ((changed & BSS_CHANGED_ASSOC) == 0)
+	if (mwl8k_fw_lock(hw))
 		return;
 
-	priv->capture_beacon = false;
-
-	rc = mwl8k_fw_lock(hw);
-	if (rc)
-		return;
+	/*
+	 * No need to capture a beacon if we're no longer associated.
+	 */
+	if ((changed & BSS_CHANGED_ASSOC) && !vif->bss_conf.assoc)
+		priv->capture_beacon = false;
 
-	if (info->assoc) {
-		memcpy(&mwl8k_vif->bss_info, info,
-			sizeof(struct ieee80211_bss_conf));
+	/*
+	 * Get the AP's legacy and MCS rates.
+	 */
+	if (vif->bss_conf.assoc) {
+		struct ieee80211_sta *ap;
 
-		memcpy(mwl8k_vif->bssid, info->bssid, ETH_ALEN);
+		rcu_read_lock();
 
-		/* Install rates */
-		rc = mwl8k_update_rateset(hw, vif);
-		if (rc)
+		ap = ieee80211_find_sta(vif, vif->bss_conf.bssid);
+		if (ap == NULL) {
+			rcu_read_unlock();
 			goto out;
+		}
 
-		/* Turn on rate adaptation */
-		rc = mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE,
-			MWL8K_UCAST_RATE, NULL);
+		if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
+			ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ];
+		} else {
+			ap_legacy_rates =
+				ap->supp_rates[IEEE80211_BAND_5GHZ] << 5;
+		}
+		memcpy(ap_mcs_rates, ap->ht_cap.mcs.rx_mask, 16);
+
+		rcu_read_unlock();
+	}
+
+	if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc) {
+		rc = mwl8k_cmd_set_rate(hw, vif, ap_legacy_rates, ap_mcs_rates);
 		if (rc)
 			goto out;
 
-		/* Set radio preamble */
-		rc = mwl8k_set_radio_preamble(hw, info->use_short_preamble);
+		rc = mwl8k_cmd_use_fixed_rate_sta(hw);
 		if (rc)
 			goto out;
+	}
 
-		/* Set slot time */
-		rc = mwl8k_cmd_set_slot(hw, info->use_short_slot);
+	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+		rc = mwl8k_set_radio_preamble(hw,
+				vif->bss_conf.use_short_preamble);
 		if (rc)
 			goto out;
+	}
 
-		/* Update peer rate info */
-		rc = mwl8k_cmd_update_sta_db(hw, vif,
-				MWL8K_STA_DB_MODIFY_ENTRY);
+	if (changed & BSS_CHANGED_ERP_SLOT) {
+		rc = mwl8k_cmd_set_slot(hw, vif->bss_conf.use_short_slot);
 		if (rc)
 			goto out;
+	}
 
-		/* Set AID */
-		rc = mwl8k_cmd_set_aid(hw, vif);
+	if (vif->bss_conf.assoc &&
+	    (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_CTS_PROT |
+			BSS_CHANGED_HT))) {
+		rc = mwl8k_cmd_set_aid(hw, vif, ap_legacy_rates);
 		if (rc)
 			goto out;
+	}
 
+	if (vif->bss_conf.assoc &&
+	    (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BEACON_INT))) {
 		/*
 		 * Finalize the join.  Tell rx handler to process
 		 * next beacon from our BSSID.
 		 */
-		memcpy(priv->capture_bssid, mwl8k_vif->bssid, ETH_ALEN);
+		memcpy(priv->capture_bssid, vif->bss_conf.bssid, ETH_ALEN);
 		priv->capture_beacon = true;
-	} else {
-		rc = 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, ETH_ALEN);
 	}
 
 out:
 	mwl8k_fw_unlock(hw);
 }
 
+static void
+mwl8k_bss_info_changed_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+			  struct ieee80211_bss_conf *info, u32 changed)
+{
+	int rc;
+
+	if (mwl8k_fw_lock(hw))
+		return;
+
+	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+		rc = mwl8k_set_radio_preamble(hw,
+				vif->bss_conf.use_short_preamble);
+		if (rc)
+			goto out;
+	}
+
+	if (changed & BSS_CHANGED_BASIC_RATES) {
+		int idx;
+		int rate;
+
+		/*
+		 * Use lowest supported basic rate for multicasts
+		 * and management frames (such as probe responses --
+		 * beacons will always go out at 1 Mb/s).
+		 */
+		idx = ffs(vif->bss_conf.basic_rates);
+		if (idx)
+			idx--;
+
+		if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+			rate = mwl8k_rates_24[idx].hw_value;
+		else
+			rate = mwl8k_rates_50[idx].hw_value;
+
+		mwl8k_cmd_use_fixed_rate_ap(hw, rate, rate);
+	}
+
+	if (changed & (BSS_CHANGED_BEACON_INT | BSS_CHANGED_BEACON)) {
+		struct sk_buff *skb;
+
+		skb = ieee80211_beacon_get(hw, vif);
+		if (skb != NULL) {
+			mwl8k_cmd_set_beacon(hw, vif, skb->data, skb->len);
+			kfree_skb(skb);
+		}
+	}
+
+	if (changed & BSS_CHANGED_BEACON_ENABLED)
+		mwl8k_cmd_bss_start(hw, vif, info->enable_beacon);
+
+out:
+	mwl8k_fw_unlock(hw);
+}
+
+static void
+mwl8k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		       struct ieee80211_bss_conf *info, u32 changed)
+{
+	struct mwl8k_priv *priv = hw->priv;
+
+	if (!priv->ap_fw)
+		mwl8k_bss_info_changed_sta(hw, vif, info, changed);
+	else
+		mwl8k_bss_info_changed_ap(hw, vif, info, changed);
+}
+
 static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
 				   int mc_count, struct dev_addr_list *mclist)
 {
@@ -3104,7 +3581,7 @@ mwl8k_configure_filter_sniffer(struct ie
 	 * operation, so refuse to enable sniffer mode if a STA
 	 * interface is active.
 	 */
-	if (priv->vif != NULL) {
+	if (!list_empty(&priv->vif_list)) {
 		if (net_ratelimit())
 			printk(KERN_INFO "%s: not enabling sniffer "
 			       "mode because STA interface is active\n",
@@ -3113,7 +3590,7 @@ mwl8k_configure_filter_sniffer(struct ie
 	}
 
 	if (!priv->sniffer_enabled) {
-		if (mwl8k_enable_sniffer(hw, 1))
+		if (mwl8k_cmd_enable_sniffer(hw, 1))
 			return 0;
 		priv->sniffer_enabled = true;
 	}
@@ -3125,6 +3602,14 @@ mwl8k_configure_filter_sniffer(struct ie
 	return 1;
 }
 
+static struct mwl8k_vif *mwl8k_first_vif(struct mwl8k_priv *priv)
+{
+	if (!list_empty(&priv->vif_list))
+		return list_entry(priv->vif_list.next, struct mwl8k_vif, list);
+
+	return NULL;
+}
+
 static void mwl8k_configure_filter(struct ieee80211_hw *hw,
 				   unsigned int changed_flags,
 				   unsigned int *total_flags,
@@ -3162,7 +3647,7 @@ static void mwl8k_configure_filter(struc
 	}
 
 	if (priv->sniffer_enabled) {
-		mwl8k_enable_sniffer(hw, 0);
+		mwl8k_cmd_enable_sniffer(hw, 0);
 		priv->sniffer_enabled = false;
 	}
 
@@ -3173,7 +3658,8 @@ static void mwl8k_configure_filter(struc
 			 */
 			mwl8k_cmd_set_pre_scan(hw);
 		} else {
-			u8 *bssid;
+			struct mwl8k_vif *mwl8k_vif;
+			const u8 *bssid;
 
 			/*
 			 * Enable the BSS filter.
@@ -3183,9 +3669,11 @@ static void mwl8k_configure_filter(struc
 			 * (where the OUI part needs to be nonzero for
 			 * the BSSID to be accepted by POST_SCAN).
 			 */
-			bssid = "\x01\x00\x00\x00\x00\x00";
-			if (priv->vif != NULL)
-				bssid = MWL8K_VIF(priv->vif)->bssid;
+			mwl8k_vif = mwl8k_first_vif(priv);
+			if (mwl8k_vif != NULL)
+				bssid = mwl8k_vif->vif->bss_conf.bssid;
+			else
+				bssid = "\x01\x00\x00\x00\x00\x00";
 
 			mwl8k_cmd_set_post_scan(hw, bssid);
 		}
@@ -3212,7 +3700,39 @@ static void mwl8k_configure_filter(struc
 
 static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
 {
-	return mwl8k_rts_threshold(hw, MWL8K_CMD_SET, value);
+	return mwl8k_cmd_set_rts_threshold(hw, value);
+}
+
+static int mwl8k_sta_remove(struct ieee80211_hw *hw,
+			    struct ieee80211_vif *vif,
+			    struct ieee80211_sta *sta)
+{
+	struct mwl8k_priv *priv = hw->priv;
+
+	if (priv->ap_fw)
+		return mwl8k_cmd_set_new_stn_del(hw, vif, sta->addr);
+	else
+		return mwl8k_cmd_update_stadb_del(hw, vif, sta->addr);
+}
+
+static int mwl8k_sta_add(struct ieee80211_hw *hw,
+			 struct ieee80211_vif *vif,
+			 struct ieee80211_sta *sta)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	int ret;
+
+	if (!priv->ap_fw) {
+		ret = mwl8k_cmd_update_stadb_add(hw, vif, sta);
+		if (ret >= 0) {
+			MWL8K_STA(sta)->peer_id = ret;
+			return 0;
+		}
+
+		return ret;
+	}
+
+	return mwl8k_cmd_set_new_stn_add(hw, vif, sta);
 }
 
 static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
@@ -3224,14 +3744,14 @@ static int mwl8k_conf_tx(struct ieee8021
 	rc = mwl8k_fw_lock(hw);
 	if (!rc) {
 		if (!priv->wmm_enabled)
-			rc = mwl8k_set_wmm(hw, 1);
+			rc = mwl8k_cmd_set_wmm_mode(hw, 1);
 
 		if (!rc)
-			rc = mwl8k_set_edca_params(hw, queue,
-						   params->cw_min,
-						   params->cw_max,
-						   params->aifs,
-						   params->txop);
+			rc = mwl8k_cmd_set_edca_params(hw, queue,
+						       params->cw_min,
+						       params->cw_max,
+						       params->aifs,
+						       params->txop);
 
 		mwl8k_fw_unlock(hw);
 	}
@@ -3239,28 +3759,26 @@ static int mwl8k_conf_tx(struct ieee8021
 	return rc;
 }
 
-static int mwl8k_get_tx_stats(struct ieee80211_hw *hw,
-			      struct ieee80211_tx_queue_stats *stats)
+static int mwl8k_get_stats(struct ieee80211_hw *hw,
+			   struct ieee80211_low_level_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->stats,
-			sizeof(struct ieee80211_tx_queue_stats));
-	}
-	spin_unlock_bh(&priv->tx_lock);
-
-	return 0;
+	return mwl8k_cmd_get_stat(hw, stats);
 }
 
-static int mwl8k_get_stats(struct ieee80211_hw *hw,
-			   struct ieee80211_low_level_stats *stats)
+static int
+mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		   enum ieee80211_ampdu_mlme_action action,
+		   struct ieee80211_sta *sta, u16 tid, u16 *ssn)
 {
-	return mwl8k_cmd_802_11_get_stat(hw, stats);
+	switch (action) {
+	case IEEE80211_AMPDU_RX_START:
+	case IEEE80211_AMPDU_RX_STOP:
+		if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
+			return -ENOTSUPP;
+		return 0;
+	default:
+		return -ENOTSUPP;
+	}
 }
 
 static const struct ieee80211_ops mwl8k_ops = {
@@ -3274,67 +3792,68 @@ static const struct ieee80211_ops mwl8k_
 	.prepare_multicast	= mwl8k_prepare_multicast,
 	.configure_filter	= mwl8k_configure_filter,
 	.set_rts_threshold	= mwl8k_set_rts_threshold,
+	.sta_add		= mwl8k_sta_add,
+	.sta_remove		= mwl8k_sta_remove,
 	.conf_tx		= mwl8k_conf_tx,
-	.get_tx_stats		= mwl8k_get_tx_stats,
 	.get_stats		= mwl8k_get_stats,
+	.ampdu_action		= mwl8k_ampdu_action,
 };
 
-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 && !priv->pending_tx_pkts) {
-		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;
+	struct ieee80211_mgmt *mgmt = (void *)skb->data;
+	int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
+	const u8 *tim = cfg80211_find_ie(WLAN_EID_TIM,
+					 mgmt->u.beacon.variable, len);
+	int dtim_period = 1;
 
-	mwl8k_finalize_join(priv->hw, skb->data, skb->len, dtim);
-	dev_kfree_skb(skb);
+	if (tim && tim[1] >= 2)
+		dtim_period = tim[3];
 
+	mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period);
+
+	dev_kfree_skb(skb);
 	priv->beacon_skb = NULL;
 }
 
 enum {
-	MWL8687 = 0,
+	MWL8363 = 0,
+	MWL8687,
 	MWL8366,
 };
 
 static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = {
-	{
+	[MWL8363] = {
+		.part_name	= "88w8363",
+		.helper_image	= "/*(DEBLOBBED)*/",
+		.fw_image	= "/*(DEBLOBBED)*/",
+	},
+	[MWL8687] = {
 		.part_name	= "88w8687",
 		.helper_image	= "/*(DEBLOBBED)*/",
 		.fw_image	= "/*(DEBLOBBED)*/",
-		.rxd_ops	= &rxd_8687_ops,
-		.modes		= BIT(NL80211_IFTYPE_STATION),
 	},
-	{
+	[MWL8366] = {
 		.part_name	= "88w8366",
 		.helper_image	= "/*(DEBLOBBED)*/",
 		.fw_image	= "/*(DEBLOBBED)*/",
-		.rxd_ops	= &rxd_8366_ops,
-		.modes		= 0,
+		.ap_rxd_ops	= &rxd_8366_ap_ops,
 	},
 };
 
+/*(DEBLOBBED)*/
+
 static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
+	{ PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
+	{ PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },
+	{ PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, },
 	{ PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, },
 	{ PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = MWL8687, },
 	{ PCI_VDEVICE(MARVELL, 0x2a40), .driver_data = MWL8366, },
+	{ PCI_VDEVICE(MARVELL, 0x2a43), .driver_data = MWL8366, },
 	{ },
 };
 MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table);
@@ -3353,6 +3872,7 @@ static int __devinit mwl8k_probe(struct
 		printed_version = 1;
 	}
 
+
 	rc = pci_enable_device(pdev);
 	if (rc) {
 		printk(KERN_ERR "%s: Cannot enable new PCI device\n",
@@ -3369,6 +3889,7 @@ static int __devinit mwl8k_probe(struct
 
 	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);
@@ -3376,17 +3897,14 @@ static int __devinit mwl8k_probe(struct
 		goto err_free_reg;
 	}
 
+	SET_IEEE80211_DEV(hw, &pdev->dev);
+	pci_set_drvdata(pdev, hw);
+
 	priv = hw->priv;
 	priv->hw = hw;
 	priv->pdev = pdev;
 	priv->device_info = &mwl8k_info_tbl[id->driver_data];
-	priv->rxd_ops = priv->device_info->rxd_ops;
-	priv->sniffer_enabled = false;
-	priv->wmm_enabled = false;
-	priv->pending_tx_pkts = 0;
 
-	SET_IEEE80211_DEV(hw, &pdev->dev);
-	pci_set_drvdata(pdev, hw);
 
 	priv->sram = pci_iomap(pdev, 0, 0x10000);
 	if (priv->sram == NULL) {
@@ -3409,16 +3927,46 @@ static int __devinit mwl8k_probe(struct
 		}
 	}
 
-	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));
+	/* Reset firmware and hardware */
+	mwl8k_hw_reset(priv);
+
+	/* Ask userland hotplug daemon for the device firmware */
+	rc = mwl8k_reject_firmware(priv);
+	if (rc) {
+		printk(KERN_ERR "%s: Firmware files not found\n",
+		       wiphy_name(hw->wiphy));
+		goto err_stop_firmware;
+	}
+
+	/* Load firmware into hardware */
+	rc = mwl8k_load_firmware(hw);
+	if (rc) {
+		printk(KERN_ERR "%s: Cannot start firmware\n",
+		       wiphy_name(hw->wiphy));
+		goto err_stop_firmware;
+	}
+
+	/* Reclaim memory once firmware is successfully loaded */
+	mwl8k_release_firmware(priv);
+
+
+	if (priv->ap_fw) {
+		priv->rxd_ops = priv->device_info->ap_rxd_ops;
+		if (priv->rxd_ops == NULL) {
+			printk(KERN_ERR "%s: Driver does not have AP "
+			       "firmware image support for this hardware\n",
+			       wiphy_name(hw->wiphy));
+			goto err_stop_firmware;
+		}
+	} else {
+		priv->rxd_ops = &rxd_sta_ops;
+	}
+
+	priv->sniffer_enabled = false;
+	priv->wmm_enabled = false;
+	priv->pending_tx_pkts = 0;
+
 
 	/*
 	 * Extra headroom is the size of the required DMA header
@@ -3431,12 +3979,13 @@ static int __devinit mwl8k_probe(struct
 
 	hw->queues = MWL8K_TX_QUEUES;
 
-	hw->wiphy->interface_modes = priv->device_info->modes;
-
 	/* Set rssi and noise values to dBm */
 	hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM;
 	hw->vif_data_size = sizeof(struct mwl8k_vif);
-	priv->vif = NULL;
+	hw->sta_data_size = sizeof(struct mwl8k_sta);
+
+	priv->macids_used = 0;
+	INIT_LIST_HEAD(&priv->vif_list);
 
 	/* Set default radio state and preamble */
 	priv->radio_on = 0;
@@ -3445,19 +3994,20 @@ static int __devinit mwl8k_probe(struct
 	/* 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);
+	/* TX reclaim and RX tasklets.  */
+	tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
+	tasklet_disable(&priv->poll_tx_task);
+	tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw);
+	tasklet_disable(&priv->poll_rx_task);
 
 	/* Power management cookie */
 	priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
 	if (priv->cookie == NULL)
-		goto err_iounmap;
+		goto err_stop_firmware;
 
 	rc = mwl8k_rxq_init(hw, 0);
 	if (rc)
-		goto err_iounmap;
+		goto err_free_cookie;
 	rxq_refill(hw, 0, INT_MAX);
 
 	mutex_init(&priv->fw_mutex);
@@ -3477,7 +4027,8 @@ static int __devinit mwl8k_probe(struct
 
 	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
 	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
-	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
+	iowrite32(MWL8K_A2H_INT_TX_DONE | MWL8K_A2H_INT_RX_READY,
+		  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,
@@ -3488,31 +4039,9 @@ static int __devinit mwl8k_probe(struct
 		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);
-	if (rc) {
-		printk(KERN_ERR "%s: Firmware files not found\n",
-		       wiphy_name(hw->wiphy));
-		goto err_free_irq;
-	}
-
-	/* Load firmware into hardware */
-	rc = mwl8k_load_firmware(hw);
-	if (rc) {
-		printk(KERN_ERR "%s: Cannot start firmware\n",
-		       wiphy_name(hw->wiphy));
-		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
+	 * commands use interrupts and avoid polling.  Disable
 	 * interrupts when done.
 	 */
 	iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
@@ -3528,22 +4057,29 @@ static int __devinit mwl8k_probe(struct
 	if (rc) {
 		printk(KERN_ERR "%s: Cannot initialise firmware\n",
 		       wiphy_name(hw->wiphy));
-		goto err_stop_firmware;
+		goto err_free_irq;
 	}
 
+	hw->wiphy->interface_modes = 0;
+	if (priv->ap_macids_supported)
+		hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
+	if (priv->sta_macids_supported)
+		hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
+
+
 	/* Turn radio off */
-	rc = mwl8k_cmd_802_11_radio_disable(hw);
+	rc = mwl8k_cmd_radio_disable(hw);
 	if (rc) {
 		printk(KERN_ERR "%s: Cannot disable\n", wiphy_name(hw->wiphy));
-		goto err_stop_firmware;
+		goto err_free_irq;
 	}
 
 	/* Clear MAC address */
-	rc = mwl8k_set_mac_addr(hw, "\x00\x00\x00\x00\x00\x00");
+	rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00");
 	if (rc) {
 		printk(KERN_ERR "%s: Cannot clear MAC address\n",
 		       wiphy_name(hw->wiphy));
-		goto err_stop_firmware;
+		goto err_free_irq;
 	}
 
 	/* Disable interrupts */
@@ -3554,7 +4090,7 @@ static int __devinit mwl8k_probe(struct
 	if (rc) {
 		printk(KERN_ERR "%s: Cannot register device\n",
 		       wiphy_name(hw->wiphy));
-		goto err_stop_firmware;
+		goto err_free_queues;
 	}
 
 	printk(KERN_INFO "%s: %s v%d, %pM, %s firmware %u.%u.%u.%u\n",
@@ -3566,10 +4102,6 @@ static int __devinit mwl8k_probe(struct
 
 	return 0;
 
-err_stop_firmware:
-	mwl8k_hw_reset(priv);
-	mwl8k_release_firmware(priv);
-
 err_free_irq:
 	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
 	free_irq(priv->pdev->irq, hw);
@@ -3579,11 +4111,16 @@ err_free_queues:
 		mwl8k_txq_deinit(hw, i);
 	mwl8k_rxq_deinit(hw, 0);
 
-err_iounmap:
+err_free_cookie:
 	if (priv->cookie != NULL)
 		pci_free_consistent(priv->pdev, 4,
 				priv->cookie, priv->cookie_dma);
 
+err_stop_firmware:
+	mwl8k_hw_reset(priv);
+	mwl8k_release_firmware(priv);
+
+err_iounmap:
 	if (priv->regs != NULL)
 		pci_iounmap(pdev, priv->regs);
 
@@ -3621,15 +4158,16 @@ static void __devexit mwl8k_remove(struc
 
 	ieee80211_unregister_hw(hw);
 
-	/* Remove tx reclaim tasklet */
-	tasklet_kill(&priv->tx_reclaim_task);
+	/* Remove TX reclaim and RX tasklets.  */
+	tasklet_kill(&priv->poll_tx_task);
+	tasklet_kill(&priv->poll_rx_task);
 
 	/* 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);
+		mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
 
 	for (i = 0; i < MWL8K_TX_QUEUES; i++)
 		mwl8k_txq_deinit(hw, i);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/fw.c linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/fw.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/fw.c	2013-05-03 12:09:23.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/fw.c	2013-05-03 09:48:54.000000000 -0400
@@ -3,6 +3,7 @@
  * See copyright notice in main.c
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/device.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/hw.c linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/hw.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/hw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/hw.c	2010-05-16 17:17:36.000000000 -0400
@@ -1028,7 +1028,7 @@ int orinoco_clear_tkip_key(struct orinoc
 }
 
 int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
-				    struct dev_addr_list *mc_list,
+				    struct net_device *dev,
 				    int mc_count, int promisc)
 {
 	hermes_t *hw = &priv->hw;
@@ -1049,24 +1049,16 @@ int __orinoco_hw_set_multicast_list(stru
 	 * 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 dev_mc_list *p;
 		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);
+		int i = 0;
 
-			memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
-			p = p->next;
+		netdev_for_each_mc_addr(p, dev) {
+			if (i == mc_count)
+				break;
+			memcpy(mclist.addr[i++], p->dmi_addr, ETH_ALEN);
 		}
 
-		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),
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/hw.h linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/hw.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -43,7 +43,7 @@ int __orinoco_hw_set_tkip_key(struct ori
 			      u8 *tsc, size_t tsc_len);
 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,
+				    struct net_device *dev,
 				    int mc_count, int promisc);
 int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
 			 char buf[IW_ESSID_MAX_SIZE+1]);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/main.c linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/main.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/main.c	2010-05-16 17:17:36.000000000 -0400
@@ -78,6 +78,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/device.h>
@@ -1668,16 +1669,15 @@ __orinoco_set_multicast_list(struct net_
 	/* 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))) {
+	    (netdev_mc_count(dev) > MAX_MULTICAST(priv))) {
 		promisc = 1;
 		mc_count = 0;
 	} else {
 		promisc = 0;
-		mc_count = dev->mc_count;
+		mc_count = netdev_mc_count(dev);
 	}
 
-	err = __orinoco_hw_set_multicast_list(priv, dev->mc_list, mc_count,
-					      promisc);
+	err = __orinoco_hw_set_multicast_list(priv, dev, mc_count, promisc);
 
 	return err;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/orinoco_cs.c linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/orinoco_cs.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/orinoco_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/orinoco_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -407,7 +407,6 @@ static struct pcmcia_device_id orinoco_c
 	PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
 	PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5),
 	PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2),
-	PCMCIA_DEVICE_PROD_ID123("AIRVAST", "IEEE 802.11b Wireless PCMCIA Card", "HFA3863", 0xea569531, 0x4bcb9645, 0x355cb092),
 	PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f),
 	PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842),
 	PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e),
@@ -417,7 +416,6 @@ static struct pcmcia_device_id orinoco_c
 	PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18),
 	PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90),
 	PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b),
-	PCMCIA_DEVICE_PROD_ID123("corega", "WL PCCL-11", "ISL37300P", 0x0a21501a, 0x59868926, 0xc9049a39),
 	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584),
 	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9),
 	PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae),
@@ -432,7 +430,6 @@ static struct pcmcia_device_id orinoco_c
 	PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18),
 	PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77),
 	PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf),
-	PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2),
 	PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92),
 	PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395),
 	PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
@@ -445,7 +442,6 @@ static struct pcmcia_device_id orinoco_c
 	PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767),
 	PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6),
 	PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed),
-	PCMCIA_DEVICE_PROD_ID123("PCMCIA", "11M WLAN Card v2.5", "ISL37300P", 0x281f1c5d, 0x6e440487, 0xc9049a39),
 	PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264),
 	PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178),
 	PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
@@ -454,8 +450,11 @@ static struct pcmcia_device_id orinoco_c
 	PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757),
 	PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a),
 	PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
-	PCMCIA_DEVICE_PROD_ID123("The Linksys Group, Inc.", "Instant Wireless Network PC Card", "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39),
 	PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee),
+	PCMCIA_DEVICE_PROD_ID3("HFA3863", 0x355cb092),
+	PCMCIA_DEVICE_PROD_ID3("ISL37100P", 0x630d52b2),
+	PCMCIA_DEVICE_PROD_ID3("ISL37101P-10", 0xdd97a26b),
+	PCMCIA_DEVICE_PROD_ID3("ISL37300P", 0xc9049a39),
 	PCMCIA_DEVICE_NULL,
 };
 MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/orinoco_nortel.c linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/orinoco_nortel.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/orinoco_nortel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/orinoco_nortel.c	2010-05-16 17:17:36.000000000 -0400
@@ -274,7 +274,7 @@ static void __devexit orinoco_nortel_rem
 	pci_disable_device(pdev);
 }
 
-static struct pci_device_id orinoco_nortel_id_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(orinoco_nortel_id_table) = {
 	/* Nortel emobility PCI */
 	{0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,},
 	/* Symbol LA-4123 PCI */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/orinoco_pci.c linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/orinoco_pci.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/orinoco_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/orinoco_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -212,7 +212,7 @@ static void __devexit orinoco_pci_remove
 	pci_disable_device(pdev);
 }
 
-static struct pci_device_id orinoco_pci_id_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(orinoco_pci_id_table) = {
 	/* Intersil Prism 3 */
 	{0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID,},
 	/* Intersil Prism 2.5 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/orinoco_plx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/orinoco_plx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/orinoco_plx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/orinoco_plx.c	2010-05-16 17:17:36.000000000 -0400
@@ -310,7 +310,7 @@ static void __devexit orinoco_plx_remove
 	pci_disable_device(pdev);
 }
 
-static struct pci_device_id orinoco_plx_id_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(orinoco_plx_id_table) = {
 	{0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,},	/* Siemens SpeedStream SS1023 */
 	{0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,},	/* Netgear MA301 */
 	{0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,},	/* Correga  - does this work? */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/orinoco_tmd.c linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/orinoco_tmd.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/orinoco_tmd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/orinoco_tmd.c	2010-05-16 17:17:36.000000000 -0400
@@ -203,7 +203,7 @@ static void __devexit orinoco_tmd_remove
 	pci_disable_device(pdev);
 }
 
-static struct pci_device_id orinoco_tmd_id_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(orinoco_tmd_id_table) = {
 	{0x15e8, 0x0131, PCI_ANY_ID, PCI_ANY_ID,},      /* NDC and OEMs, e.g. pheecom */
 	{0,},
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/scan.c linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/scan.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/scan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/scan.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
  * See copyright notice in main.c
  */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/ieee80211.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/wext.c linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/wext.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/wext.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/orinoco/wext.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
  *
  * See copyright notice in main.c
  */
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/if_arp.h>
 #include <linux/wireless.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/eeprom.c linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/eeprom.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/eeprom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/eeprom.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/sort.h>
+#include <linux/slab.h>
 
 #include <net/mac80211.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/fwio.c linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/fwio.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/fwio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/fwio.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/main.c linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/main.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/main.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 
@@ -33,21 +34,29 @@ MODULE_DESCRIPTION("Softmac Prism54 comm
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("prism54common");
 
+static int p54_sta_add_remove(struct ieee80211_hw *hw,
+			      struct ieee80211_vif *vif,
+			      struct ieee80211_sta *sta)
+{
+	struct p54_common *priv = hw->priv;
+
+	/*
+	 * Notify the firmware that we don't want or we don't
+	 * need to buffer frames for this station anymore.
+	 */
+
+	p54_sta_unlock(priv, sta->addr);
+
+	return 0;
+}
+
 static void p54_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
 			      enum sta_notify_cmd notify_cmd,
 			      struct ieee80211_sta *sta)
 {
 	struct p54_common *priv = dev->priv;
-	switch (notify_cmd) {
-	case STA_NOTIFY_ADD:
-	case STA_NOTIFY_REMOVE:
-		/*
-		 * Notify the firmware that we don't want or we don't
-		 * need to buffer frames for this station anymore.
-		 */
 
-		p54_sta_unlock(priv, sta->addr);
-		break;
+	switch (notify_cmd) {
 	case STA_NOTIFY_AWAKE:
 		/* update the firmware's filter table */
 		p54_sta_unlock(priv, sta->addr);
@@ -216,7 +225,7 @@ static void p54_stop(struct ieee80211_hw
 }
 
 static int p54_add_interface(struct ieee80211_hw *dev,
-			     struct ieee80211_if_init_conf *conf)
+			     struct ieee80211_vif *vif)
 {
 	struct p54_common *priv = dev->priv;
 
@@ -226,28 +235,28 @@ static int p54_add_interface(struct ieee
 		return -EOPNOTSUPP;
 	}
 
-	priv->vif = conf->vif;
+	priv->vif = vif;
 
-	switch (conf->type) {
+	switch (vif->type) {
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_ADHOC:
 	case NL80211_IFTYPE_AP:
 	case NL80211_IFTYPE_MESH_POINT:
-		priv->mode = conf->type;
+		priv->mode = vif->type;
 		break;
 	default:
 		mutex_unlock(&priv->conf_mutex);
 		return -EOPNOTSUPP;
 	}
 
-	memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
+	memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
 	p54_setup_mac(priv);
 	mutex_unlock(&priv->conf_mutex);
 	return 0;
 }
 
 static void p54_remove_interface(struct ieee80211_hw *dev,
-				 struct ieee80211_if_init_conf *conf)
+				 struct ieee80211_vif *vif)
 {
 	struct p54_common *priv = dev->priv;
 
@@ -358,16 +367,6 @@ static int p54_get_stats(struct ieee8021
 	return 0;
 }
 
-static int p54_get_tx_stats(struct ieee80211_hw *dev,
-			    struct ieee80211_tx_queue_stats *stats)
-{
-	struct p54_common *priv = dev->priv;
-
-	memcpy(stats, &priv->tx_stats[P54_QUEUE_DATA],
-	       sizeof(stats[0]) * dev->queues);
-	return 0;
-}
-
 static void p54_bss_info_changed(struct ieee80211_hw *dev,
 				 struct ieee80211_vif *vif,
 				 struct ieee80211_bss_conf *info,
@@ -516,13 +515,14 @@ static const struct ieee80211_ops p54_op
 	.remove_interface	= p54_remove_interface,
 	.set_tim		= p54_set_tim,
 	.sta_notify		= p54_sta_notify,
+	.sta_add		= p54_sta_add_remove,
+	.sta_remove		= p54_sta_add_remove,
 	.set_key		= p54_set_key,
 	.config			= p54_config,
 	.bss_info_changed	= p54_bss_info_changed,
 	.configure_filter	= p54_configure_filter,
 	.conf_tx		= p54_conf_tx,
 	.get_stats		= p54_get_stats,
-	.get_tx_stats		= p54_get_tx_stats
 };
 
 struct ieee80211_hw *p54_init_common(size_t priv_data_len)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/p54.h linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/p54.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/p54.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/p54.h	2010-05-16 17:17:36.000000000 -0400
@@ -157,6 +157,12 @@ struct p54_led_dev {
 
 #endif /* CONFIG_P54_LEDS */
 
+struct p54_tx_queue_stats {
+	unsigned int len;
+	unsigned int limit;
+	unsigned int count;
+};
+
 struct p54_common {
 	struct ieee80211_hw *hw;
 	struct ieee80211_vif *vif;
@@ -183,7 +189,7 @@ struct p54_common {
 	/* (e)DCF / QOS state */
 	bool use_short_slot;
 	spinlock_t tx_stats_lock;
-	struct ieee80211_tx_queue_stats tx_stats[8];
+	struct p54_tx_queue_stats tx_stats[8];
 	struct p54_edcf_queue_param qos_params[8];
 
 	/* Radio data */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/p54pci.c linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/p54pci.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/p54pci.c	2013-05-03 12:10:52.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/p54pci.c	2013-05-03 09:50:24.000000000 -0400
@@ -15,6 +15,7 @@
 
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
@@ -31,7 +32,7 @@ MODULE_LICENSE("GPL");
 MODULE_ALIAS("prism54pci");
 /*(DEBLOBBED)*/
 
-static struct pci_device_id p54p_table[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(p54p_table) = {
 	/* Intersil PRISM Duette/Prism GT Wireless LAN adapter */
 	{ PCI_DEVICE(0x1260, 0x3890) },
 	/* 3COM 3CRWE154G72 Wireless LAN adapter */
@@ -157,6 +158,14 @@ static void p54p_refill_rx_ring(struct i
 						 skb_tail_pointer(skb),
 						 priv->common.rx_mtu + 32,
 						 PCI_DMA_FROMDEVICE);
+
+			if (pci_dma_mapping_error(priv->pdev, mapping)) {
+				dev_kfree_skb_any(skb);
+				dev_err(&priv->pdev->dev,
+					"RX DMA Mapping error\n");
+				break;
+			}
+
 			desc->host_addr = cpu_to_le32(mapping);
 			desc->device_addr = 0;	// FIXME: necessary?
 			desc->len = cpu_to_le16(priv->common.rx_mtu + 32);
@@ -226,25 +235,24 @@ static void p54p_check_rx_ring(struct ie
 	p54p_refill_rx_ring(dev, ring_index, ring, ring_limit, rx_buf);
 }
 
-/* caller must hold priv->lock */
 static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
 	int ring_index, struct p54p_desc *ring, u32 ring_limit,
-	void **tx_buf)
+	struct sk_buff **tx_buf)
 {
 	struct p54p_priv *priv = dev->priv;
 	struct p54p_ring_control *ring_control = priv->ring_control;
 	struct p54p_desc *desc;
+	struct sk_buff *skb;
 	u32 idx, i;
 
 	i = (*index) % ring_limit;
-	(*index) = idx = le32_to_cpu(ring_control->device_idx[1]);
+	(*index) = idx = le32_to_cpu(ring_control->device_idx[ring_index]);
 	idx %= ring_limit;
 
 	while (i != idx) {
 		desc = &ring[i];
-		if (tx_buf[i])
-			if (FREE_AFTER_TX((struct sk_buff *) tx_buf[i]))
-				p54_free_skb(dev, tx_buf[i]);
+
+		skb = tx_buf[i];
 		tx_buf[i] = NULL;
 
 		pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
@@ -255,17 +263,28 @@ static void p54p_check_tx_ring(struct ie
 		desc->len = 0;
 		desc->flags = 0;
 
+		if (skb && FREE_AFTER_TX(skb))
+			p54_free_skb(dev, skb);
+
 		i++;
 		i %= ring_limit;
 	}
 }
 
-static void p54p_rx_tasklet(unsigned long dev_id)
+static void p54p_tasklet(unsigned long dev_id)
 {
 	struct ieee80211_hw *dev = (struct ieee80211_hw *)dev_id;
 	struct p54p_priv *priv = dev->priv;
 	struct p54p_ring_control *ring_control = priv->ring_control;
 
+	p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 3, ring_control->tx_mgmt,
+			   ARRAY_SIZE(ring_control->tx_mgmt),
+			   priv->tx_buf_mgmt);
+
+	p54p_check_tx_ring(dev, &priv->tx_idx_data, 1, ring_control->tx_data,
+			   ARRAY_SIZE(ring_control->tx_data),
+			   priv->tx_buf_data);
+
 	p54p_check_rx_ring(dev, &priv->rx_idx_mgmt, 2, ring_control->rx_mgmt,
 		ARRAY_SIZE(ring_control->rx_mgmt), priv->rx_buf_mgmt);
 
@@ -280,59 +299,49 @@ static irqreturn_t p54p_interrupt(int ir
 {
 	struct ieee80211_hw *dev = dev_id;
 	struct p54p_priv *priv = dev->priv;
-	struct p54p_ring_control *ring_control = priv->ring_control;
 	__le32 reg;
 
-	spin_lock(&priv->lock);
 	reg = P54P_READ(int_ident);
 	if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) {
-		spin_unlock(&priv->lock);
-		return IRQ_HANDLED;
+		goto out;
 	}
-
 	P54P_WRITE(int_ack, reg);
 
 	reg &= P54P_READ(int_enable);
 
-	if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)) {
-		p54p_check_tx_ring(dev, &priv->tx_idx_mgmt,
-				   3, ring_control->tx_mgmt,
-				   ARRAY_SIZE(ring_control->tx_mgmt),
-				   priv->tx_buf_mgmt);
-
-		p54p_check_tx_ring(dev, &priv->tx_idx_data,
-				   1, ring_control->tx_data,
-				   ARRAY_SIZE(ring_control->tx_data),
-				   priv->tx_buf_data);
-
-		tasklet_schedule(&priv->rx_tasklet);
-
-	} else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT))
+	if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE))
+		tasklet_schedule(&priv->tasklet);
+	else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT))
 		complete(&priv->boot_comp);
 
-	spin_unlock(&priv->lock);
-
+out:
 	return reg ? IRQ_HANDLED : IRQ_NONE;
 }
 
 static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
+	unsigned long flags;
 	struct p54p_priv *priv = dev->priv;
 	struct p54p_ring_control *ring_control = priv->ring_control;
-	unsigned long flags;
 	struct p54p_desc *desc;
 	dma_addr_t mapping;
 	u32 device_idx, idx, i;
 
 	spin_lock_irqsave(&priv->lock, flags);
-
 	device_idx = le32_to_cpu(ring_control->device_idx[1]);
 	idx = le32_to_cpu(ring_control->host_idx[1]);
 	i = idx % ARRAY_SIZE(ring_control->tx_data);
 
-	priv->tx_buf_data[i] = skb;
 	mapping = pci_map_single(priv->pdev, skb->data, skb->len,
 				 PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(priv->pdev, mapping)) {
+		spin_unlock_irqrestore(&priv->lock, flags);
+		p54_free_skb(dev, skb);
+		dev_err(&priv->pdev->dev, "TX DMA mapping error\n");
+		return ;
+	}
+	priv->tx_buf_data[i] = skb;
+
 	desc = &ring_control->tx_data[i];
 	desc->host_addr = cpu_to_le32(mapping);
 	desc->device_addr = ((struct p54_hdr *)skb->data)->req_id;
@@ -354,14 +363,14 @@ static void p54p_stop(struct ieee80211_h
 	unsigned int i;
 	struct p54p_desc *desc;
 
-	tasklet_kill(&priv->rx_tasklet);
-
 	P54P_WRITE(int_enable, cpu_to_le32(0));
 	P54P_READ(int_enable);
 	udelay(10);
 
 	free_irq(priv->pdev->irq, dev);
 
+	tasklet_kill(&priv->tasklet);
+
 	P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
 
 	for (i = 0; i < ARRAY_SIZE(priv->rx_buf_data); i++) {
@@ -545,7 +554,7 @@ static int __devinit p54p_probe(struct p
 	priv->common.tx = p54p_tx;
 
 	spin_lock_init(&priv->lock);
-	tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev);
+	tasklet_init(&priv->tasklet, p54p_tasklet, (unsigned long)dev);
 
 	err = reject_firmware(&priv->firmware, "/*(DEBLOBBED)*/",
 			       &priv->pdev->dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/p54pci.h linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/p54pci.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/p54pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/p54pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -92,7 +92,7 @@ struct p54p_priv {
 	struct p54_common common;
 	struct pci_dev *pdev;
 	struct p54p_csr __iomem *map;
-	struct tasklet_struct rx_tasklet;
+	struct tasklet_struct tasklet;
 	const struct firmware *firmware;
 	spinlock_t lock;
 	struct p54p_ring_control *ring_control;
@@ -101,8 +101,8 @@ struct p54p_priv {
 	u32 rx_idx_mgmt, tx_idx_mgmt;
 	struct sk_buff *rx_buf_data[8];
 	struct sk_buff *rx_buf_mgmt[4];
-	void *tx_buf_data[32];
-	void *tx_buf_mgmt[4];
+	struct sk_buff *tx_buf_data[32];
+	struct sk_buff *tx_buf_mgmt[4];
 	struct completion boot_comp;
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/p54spi.c linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/p54spi.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/p54spi.c	2013-05-03 12:10:54.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/p54spi.c	2013-05-03 09:50:26.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/spi/spi.h>
 #include <linux/etherdevice.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include "p54spi.h"
 #include "p54spi_eeprom.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/p54usb.c linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/p54usb.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/p54usb.c	2013-05-03 12:10:56.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/p54usb.c	2013-05-03 09:50:28.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/usb.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
@@ -34,7 +35,9 @@ MODULE_ALIAS("prism54usb");
 static struct usb_device_id p54u_table[] __devinitdata = {
 	/* Version 1 devices (pci chip + net2280) */
 	{USB_DEVICE(0x0506, 0x0a11)},	/* 3COM 3CRWE254G72 */
+	{USB_DEVICE(0x06b9, 0x0120)},	/* Thomson SpeedTouch 120g */
 	{USB_DEVICE(0x0707, 0xee06)},	/* SMC 2862W-G */
+	{USB_DEVICE(0x07aa, 0x001c)},	/* Corega CG-WLUSB2GT */
 	{USB_DEVICE(0x083a, 0x4501)},	/* Accton 802.11g WN4501 USB */
 	{USB_DEVICE(0x083a, 0x4502)},	/* Siemens Gigaset USB Adapter */
 	{USB_DEVICE(0x083a, 0x5501)},	/* Phillips CPWUA054 */
@@ -59,6 +62,7 @@ static struct usb_device_id p54u_table[]
 	{USB_DEVICE(0x06b9, 0x0121)},	/* Thomson SpeedTouch 121g */
 	{USB_DEVICE(0x0707, 0xee13)},   /* SMC 2862W-G version 2 */
 	{USB_DEVICE(0x083a, 0x4521)},   /* Siemens Gigaset USB Adapter 54 version 2 */
+	{USB_DEVICE(0x083a, 0xf503)},	/* Accton FD7050E ver 1010ec  */
 	{USB_DEVICE(0x0846, 0x4240)},	/* Netgear WG111 (v2) */
 	{USB_DEVICE(0x0915, 0x2000)},	/* Cohiba Proto board */
 	{USB_DEVICE(0x0915, 0x2002)},	/* Cohiba Proto board */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/txrx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/txrx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/txrx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/p54/txrx.c	2010-05-16 17:17:36.000000000 -0400
@@ -183,10 +183,10 @@ static int p54_tx_qos_accounting_alloc(s
 				       struct sk_buff *skb,
 				       const u16 p54_queue)
 {
-	struct ieee80211_tx_queue_stats *queue;
+	struct p54_tx_queue_stats *queue;
 	unsigned long flags;
 
-	if (WARN_ON(p54_queue > P54_QUEUE_NUM))
+	if (WARN_ON(p54_queue >= P54_QUEUE_NUM))
 		return -EINVAL;
 
 	queue = &priv->tx_stats[p54_queue];
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/isl_ioctl.c linux-libre-2.6.34-gnu1/drivers/net/wireless/prism54/isl_ioctl.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/isl_ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/prism54/isl_ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/islpci_dev.c linux-libre-2.6.34-gnu1/drivers/net/wireless/prism54/islpci_dev.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/islpci_dev.c	2013-05-03 12:11:00.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/prism54/islpci_dev.c	2013-05-03 09:50:32.000000000 -0400
@@ -19,6 +19,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/islpci_eth.c linux-libre-2.6.34-gnu1/drivers/net/wireless/prism54/islpci_eth.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/islpci_eth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/prism54/islpci_eth.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 
 #include <linux/pci.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/islpci_hotplug.c linux-libre-2.6.34-gnu1/drivers/net/wireless/prism54/islpci_hotplug.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/islpci_hotplug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/prism54/islpci_hotplug.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,7 @@ module_param(init_pcitm, int, 0);
  * driver_data
  * If you have an update for this please contact prism54-devel@prism54.org
  * The latest list can be found at http://prism54.org/supported_cards.php */
-static const struct pci_device_id prism54_id_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(prism54_id_tbl) = {
 	/* Intersil PRISM Duette/Prism GT Wireless LAN adapter */
 	{
 	 0x1260, 0x3890,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/islpci_mgt.c linux-libre-2.6.34-gnu1/drivers/net/wireless/prism54/islpci_mgt.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/islpci_mgt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/prism54/islpci_mgt.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/islpci_mgt.h linux-libre-2.6.34-gnu1/drivers/net/wireless/prism54/islpci_mgt.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/islpci_mgt.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/prism54/islpci_mgt.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/wireless.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 
 /*
  *  Function definitions
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/oid_mgt.c linux-libre-2.6.34-gnu1/drivers/net/wireless/prism54/oid_mgt.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/oid_mgt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/prism54/oid_mgt.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "prismcompat.h"
 #include "islpci_dev.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/ray_cs.c linux-libre-2.6.34-gnu1/drivers/net/wireless/ray_cs.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/ray_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/ray_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,7 +35,6 @@
 #include <linux/proc_fs.h>
 #include <linux/ptrace.h>
 #include <linux/seq_file.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/init.h>
@@ -1871,10 +1870,8 @@ static void ray_update_parm(struct net_d
 /*===========================================================================*/
 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;
@@ -1895,9 +1892,11 @@ static void ray_update_multi_list(struct
 		writeb(0xff, &pccs->var);
 		local->num_multi = 0xff;
 	} else {
+		struct dev_mc_list *dmi;
+		int i = 0;
+
 		/* Copy the kernel's list of MC addresses to card */
-		for (dmip = &dev->mc_list; (dmi = *dmip) != NULL;
-		     dmip = &dmi->next) {
+		netdev_for_each_mc_addr(dmi, dev) {
 			memcpy_toio(p, dmi->dmi_addr, ETH_ALEN);
 			dev_dbg(&link->dev,
 			      "ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",
@@ -1950,7 +1949,7 @@ static void set_multicast_list(struct ne
 	if (dev->flags & IFF_ALLMULTI)
 		ray_update_multi_list(dev, 1);
 	else {
-		if (local->num_multi != dev->mc_count)
+		if (local->num_multi != netdev_mc_count(dev))
 			ray_update_multi_list(dev, 0);
 	}
 } /* end set_multicast_list */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rndis_wlan.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rndis_wlan.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rndis_wlan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rndis_wlan.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@
 #include <linux/if_arp.h>
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <net/iw_handler.h>
 #include <net/cfg80211.h>
 #include <linux/usb/usbnet.h>
@@ -728,9 +729,9 @@ static int rndis_query_oid(struct usbnet
 	ret = rndis_command(dev, u.header, buflen);
 	priv->current_command_oid = 0;
 	if (ret < 0)
-		devdbg(dev, "rndis_query_oid(%s): rndis_command() failed, %d "
-			"(%08x)", oid_to_string(oid), ret,
-			le32_to_cpu(u.get_c->status));
+		netdev_dbg(dev->net, "%s(%s): rndis_command() failed, %d (%08x)\n",
+			   __func__, oid_to_string(oid), ret,
+			   le32_to_cpu(u.get_c->status));
 
 	if (ret == 0) {
 		memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len);
@@ -741,9 +742,9 @@ static int rndis_query_oid(struct usbnet
 
 		ret = rndis_error_status(u.get_c->status);
 		if (ret < 0)
-			devdbg(dev, "rndis_query_oid(%s): device returned "
-				"error,  0x%08x (%d)", oid_to_string(oid),
-				le32_to_cpu(u.get_c->status), ret);
+			netdev_dbg(dev->net, "%s(%s): device returned error,  0x%08x (%d)\n",
+				   __func__, oid_to_string(oid),
+				   le32_to_cpu(u.get_c->status), ret);
 	}
 
 	mutex_unlock(&priv->command_lock);
@@ -791,17 +792,17 @@ static int rndis_set_oid(struct usbnet *
 	ret = rndis_command(dev, u.header, buflen);
 	priv->current_command_oid = 0;
 	if (ret < 0)
-		devdbg(dev, "rndis_set_oid(%s): rndis_command() failed, %d "
-			"(%08x)", oid_to_string(oid), ret,
-			le32_to_cpu(u.set_c->status));
+		netdev_dbg(dev->net, "%s(%s): rndis_command() failed, %d (%08x)\n",
+			   __func__, oid_to_string(oid), ret,
+			   le32_to_cpu(u.set_c->status));
 
 	if (ret == 0) {
 		ret = rndis_error_status(u.set_c->status);
 
 		if (ret < 0)
-			devdbg(dev, "rndis_set_oid(%s): device returned error, "
-				"0x%08x (%d)", oid_to_string(oid),
-				le32_to_cpu(u.set_c->status), ret);
+			netdev_dbg(dev->net, "%s(%s): device returned error, 0x%08x (%d)\n",
+				   __func__, oid_to_string(oid),
+				   le32_to_cpu(u.set_c->status), ret);
 	}
 
 	mutex_unlock(&priv->command_lock);
@@ -870,11 +871,11 @@ static int rndis_set_config_parameter(st
 #endif
 
 	if (value_type == 2)
-		devdbg(dev, "setting config parameter: %s, value: %s",
-						param, (u8 *)value);
+		netdev_dbg(dev->net, "setting config parameter: %s, value: %s\n",
+			   param, (u8 *)value);
 	else
-		devdbg(dev, "setting config parameter: %s, value: %d",
-						param, *(u32 *)value);
+		netdev_dbg(dev->net, "setting config parameter: %s, value: %d\n",
+			   param, *(u32 *)value);
 
 	infobuf->name_offs = cpu_to_le32(sizeof(*infobuf));
 	infobuf->name_length = cpu_to_le32(param_len);
@@ -897,20 +898,21 @@ static int rndis_set_config_parameter(st
 	}
 
 #ifdef DEBUG
-	devdbg(dev, "info buffer (len: %d):", info_len);
+	netdev_dbg(dev->net, "info buffer (len: %d)\n", info_len);
 	for (i = 0; i < info_len; i += 12) {
 		u32 *tmp = (u32 *)((u8 *)infobuf + i);
-		devdbg(dev, "%08X:%08X:%08X",
-			cpu_to_be32(tmp[0]),
-			cpu_to_be32(tmp[1]),
-			cpu_to_be32(tmp[2]));
+		netdev_dbg(dev->net, "%08X:%08X:%08X\n",
+			   cpu_to_be32(tmp[0]),
+			   cpu_to_be32(tmp[1]),
+			   cpu_to_be32(tmp[2]));
 	}
 #endif
 
 	ret = rndis_set_oid(dev, OID_GEN_RNDIS_CONFIG_PARAMETER,
 							infobuf, info_len);
 	if (ret != 0)
-		devdbg(dev, "setting rndis config parameter failed, %d.", ret);
+		netdev_dbg(dev->net, "setting rndis config parameter failed, %d\n",
+			   ret);
 
 	kfree(infobuf);
 	return ret;
@@ -945,13 +947,13 @@ static int set_essid(struct usbnet *usbd
 
 	ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid));
 	if (ret < 0) {
-		devwarn(usbdev, "setting SSID failed (%08X)", ret);
+		netdev_warn(usbdev->net, "setting SSID failed (%08X)\n", ret);
 		return ret;
 	}
 	if (ret == 0) {
 		memcpy(&priv->essid, ssid, sizeof(priv->essid));
 		priv->radio_on = true;
-		devdbg(usbdev, "set_essid: radio_on = true");
+		netdev_dbg(usbdev->net, "%s(): radio_on = true\n", __func__);
 	}
 
 	return ret;
@@ -963,7 +965,8 @@ static int set_bssid(struct usbnet *usbd
 
 	ret = rndis_set_oid(usbdev, OID_802_11_BSSID, bssid, ETH_ALEN);
 	if (ret < 0) {
-		devwarn(usbdev, "setting BSSID[%pM] failed (%08X)", bssid, ret);
+		netdev_warn(usbdev->net, "setting BSSID[%pM] failed (%08X)\n",
+			    bssid, ret);
 		return ret;
 	}
 
@@ -1021,7 +1024,8 @@ static int disassociate(struct usbnet *u
 		ret = rndis_set_oid(usbdev, OID_802_11_DISASSOCIATE, NULL, 0);
 		if (ret == 0) {
 			priv->radio_on = false;
-			devdbg(usbdev, "disassociate: radio_on = false");
+			netdev_dbg(usbdev->net, "%s(): radio_on = false\n",
+				   __func__);
 
 			if (reset_ssid)
 				msleep(100);
@@ -1054,8 +1058,8 @@ static int set_auth_mode(struct usbnet *
 	__le32 tmp;
 	int auth_mode, ret;
 
-	devdbg(usbdev, "set_auth_mode: wpa_version=0x%x authalg=0x%x "
-		"keymgmt=0x%x", wpa_version, auth_type, keymgmt);
+	netdev_dbg(usbdev->net, "%s(): wpa_version=0x%x authalg=0x%x keymgmt=0x%x\n",
+		   __func__, wpa_version, auth_type, keymgmt);
 
 	if (wpa_version & NL80211_WPA_VERSION_2) {
 		if (keymgmt & RNDIS_WLAN_KEY_MGMT_802_1X)
@@ -1082,7 +1086,8 @@ static int set_auth_mode(struct usbnet *
 	ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp,
 								sizeof(tmp));
 	if (ret != 0) {
-		devwarn(usbdev, "setting auth mode failed (%08X)", ret);
+		netdev_warn(usbdev->net, "setting auth mode failed (%08X)\n",
+			    ret);
 		return ret;
 	}
 
@@ -1098,7 +1103,8 @@ static int set_priv_filter(struct usbnet
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 	__le32 tmp;
 
-	devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version);
+	netdev_dbg(usbdev->net, "%s(): wpa_version=0x%x\n",
+		   __func__, priv->wpa_version);
 
 	if (priv->wpa_version & NL80211_WPA_VERSION_2 ||
 	    priv->wpa_version & NL80211_WPA_VERSION_1)
@@ -1116,8 +1122,8 @@ static int set_encr_mode(struct usbnet *
 	__le32 tmp;
 	int encr_mode, ret;
 
-	devdbg(usbdev, "set_encr_mode: cipher_pair=0x%x cipher_group=0x%x",
-		pairwise, groupwise);
+	netdev_dbg(usbdev->net, "%s(): cipher_pair=0x%x cipher_group=0x%x\n",
+		   __func__, pairwise, groupwise);
 
 	if (pairwise & RNDIS_WLAN_ALG_CCMP)
 		encr_mode = NDIS_80211_ENCR_CCMP_ENABLED;
@@ -1136,7 +1142,8 @@ static int set_encr_mode(struct usbnet *
 	ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp,
 								sizeof(tmp));
 	if (ret != 0) {
-		devwarn(usbdev, "setting encr mode failed (%08X)", ret);
+		netdev_warn(usbdev->net, "setting encr mode failed (%08X)\n",
+			    ret);
 		return ret;
 	}
 
@@ -1151,13 +1158,15 @@ static int set_infra_mode(struct usbnet
 	__le32 tmp;
 	int ret;
 
-	devdbg(usbdev, "set_infra_mode: infra_mode=0x%x", priv->infra_mode);
+	netdev_dbg(usbdev->net, "%s(): infra_mode=0x%x\n",
+		   __func__, priv->infra_mode);
 
 	tmp = cpu_to_le32(mode);
 	ret = rndis_set_oid(usbdev, OID_802_11_INFRASTRUCTURE_MODE, &tmp,
 								sizeof(tmp));
 	if (ret != 0) {
-		devwarn(usbdev, "setting infra mode failed (%08X)", ret);
+		netdev_warn(usbdev->net, "setting infra mode failed (%08X)\n",
+			    ret);
 		return ret;
 	}
 
@@ -1174,7 +1183,7 @@ static int set_rts_threshold(struct usbn
 {
 	__le32 tmp;
 
-	devdbg(usbdev, "set_rts_threshold %i", rts_threshold);
+	netdev_dbg(usbdev->net, "%s(): %i\n", __func__, rts_threshold);
 
 	if (rts_threshold < 0 || rts_threshold > 2347)
 		rts_threshold = 2347;
@@ -1188,7 +1197,7 @@ static int set_frag_threshold(struct usb
 {
 	__le32 tmp;
 
-	devdbg(usbdev, "set_frag_threshold %i", frag_threshold);
+	netdev_dbg(usbdev->net, "%s(): %i\n", __func__, frag_threshold);
 
 	if (frag_threshold < 256 || frag_threshold > 2346)
 		frag_threshold = 2346;
@@ -1222,7 +1231,7 @@ static int set_channel(struct usbnet *us
 	unsigned int dsconfig;
 	int len, ret;
 
-	devdbg(usbdev, "set_channel(%d)", channel);
+	netdev_dbg(usbdev->net, "%s(%d)\n", __func__, channel);
 
 	/* this OID is valid only when not associated */
 	if (is_associated(usbdev))
@@ -1233,7 +1242,8 @@ static int set_channel(struct usbnet *us
 	len = sizeof(config);
 	ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
 	if (ret < 0) {
-		devdbg(usbdev, "set_channel: querying configuration failed");
+		netdev_dbg(usbdev->net, "%s(): querying configuration failed\n",
+			   __func__);
 		return ret;
 	}
 
@@ -1241,7 +1251,7 @@ static int set_channel(struct usbnet *us
 	ret = rndis_set_oid(usbdev, OID_802_11_CONFIGURATION, &config,
 								sizeof(config));
 
-	devdbg(usbdev, "set_channel: %d -> %d", channel, ret);
+	netdev_dbg(usbdev->net, "%s(): %d -> %d\n", __func__, channel, ret);
 
 	return ret;
 }
@@ -1255,7 +1265,8 @@ static int add_wep_key(struct usbnet *us
 	u32 cipher;
 	int ret;
 
-	devdbg(usbdev, "add_wep_key(idx: %d, len: %d)", index, key_len);
+	netdev_dbg(usbdev->net, "%s(idx: %d, len: %d)\n",
+		   __func__, index, key_len);
 
 	if ((key_len != 5 && key_len != 13) || index < 0 || index > 3)
 		return -EINVAL;
@@ -1277,15 +1288,15 @@ static int add_wep_key(struct usbnet *us
 		ret = set_encr_mode(usbdev, RNDIS_WLAN_ALG_WEP,
 							RNDIS_WLAN_ALG_NONE);
 		if (ret)
-			devwarn(usbdev, "encryption couldn't be enabled (%08X)",
-									ret);
+			netdev_warn(usbdev->net, "encryption couldn't be enabled (%08X)\n",
+				    ret);
 	}
 
 	ret = rndis_set_oid(usbdev, OID_802_11_ADD_WEP, &ndis_key,
 							sizeof(ndis_key));
 	if (ret != 0) {
-		devwarn(usbdev, "adding encryption key %d failed (%08X)",
-							index+1, ret);
+		netdev_warn(usbdev->net, "adding encryption key %d failed (%08X)\n",
+			    index + 1, ret);
 		return ret;
 	}
 
@@ -1307,22 +1318,23 @@ static int add_wpa_key(struct usbnet *us
 	int ret;
 
 	if (index < 0 || index >= 4) {
-		devdbg(usbdev, "add_wpa_key: index out of range (%i)", index);
+		netdev_dbg(usbdev->net, "%s(): index out of range (%i)\n",
+			   __func__, index);
 		return -EINVAL;
 	}
 	if (key_len > sizeof(ndis_key.material) || key_len < 0) {
-		devdbg(usbdev, "add_wpa_key: key length out of range (%i)",
-			key_len);
+		netdev_dbg(usbdev->net, "%s(): key length out of range (%i)\n",
+			   __func__, key_len);
 		return -EINVAL;
 	}
 	if (flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) {
 		if (!rx_seq || seq_len <= 0) {
-			devdbg(usbdev, "add_wpa_key: recv seq flag without"
-					"buffer");
+			netdev_dbg(usbdev->net, "%s(): recv seq flag without buffer\n",
+				   __func__);
 			return -EINVAL;
 		}
 		if (rx_seq && seq_len > sizeof(ndis_key.rsc)) {
-			devdbg(usbdev, "add_wpa_key: too big recv seq buffer");
+			netdev_dbg(usbdev->net, "%s(): too big recv seq buffer\n", __func__);
 			return -EINVAL;
 		}
 	}
@@ -1330,15 +1342,16 @@ static int add_wpa_key(struct usbnet *us
 	is_addr_ok = addr && !is_zero_ether_addr(addr) &&
 					!is_broadcast_ether_addr(addr);
 	if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !is_addr_ok) {
-		devdbg(usbdev, "add_wpa_key: pairwise but bssid invalid (%pM)",
-			addr);
+		netdev_dbg(usbdev->net, "%s(): pairwise but bssid invalid (%pM)\n",
+			   __func__, addr);
 		return -EINVAL;
 	}
 
-	devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index,
-			!!(flags & NDIS_80211_ADDKEY_TRANSMIT_KEY),
-			!!(flags & NDIS_80211_ADDKEY_PAIRWISE_KEY),
-			!!(flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ));
+	netdev_dbg(usbdev->net, "%s(%i): flags:%i%i%i\n",
+		   __func__, index,
+		   !!(flags & NDIS_80211_ADDKEY_TRANSMIT_KEY),
+		   !!(flags & NDIS_80211_ADDKEY_PAIRWISE_KEY),
+		   !!(flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ));
 
 	memset(&ndis_key, 0, sizeof(ndis_key));
 
@@ -1372,7 +1385,8 @@ static int add_wpa_key(struct usbnet *us
 
 	ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key,
 					le32_to_cpu(ndis_key.size));
-	devdbg(usbdev, "add_wpa_key: OID_802_11_ADD_KEY -> %08X", ret);
+	netdev_dbg(usbdev->net, "%s(): OID_802_11_ADD_KEY -> %08X\n",
+		   __func__, ret);
 	if (ret != 0)
 		return ret;
 
@@ -1401,7 +1415,7 @@ static int restore_key(struct usbnet *us
 
 	key = priv->encr_keys[key_idx];
 
-	devdbg(usbdev, "restore_key: %i:%i", key_idx, key.len);
+	netdev_dbg(usbdev->net, "%s(): %i:%i\n", __func__, key_idx, key.len);
 
 	if (key.len == 0)
 		return 0;
@@ -1436,8 +1450,9 @@ static int remove_key(struct usbnet *usb
 
 	is_wpa = is_wpa_key(priv, index);
 
-	devdbg(usbdev, "remove_key: %i:%s:%i", index, is_wpa ? "wpa" : "wep",
-		priv->encr_keys[index].len);
+	netdev_dbg(usbdev->net, "%s(): %i:%s:%i\n",
+		   __func__, index, is_wpa ? "wpa" : "wep",
+		   priv->encr_keys[index].len);
 
 	clear_key(priv, index);
 
@@ -1464,9 +1479,9 @@ static int remove_key(struct usbnet *usb
 		ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_WEP, &keyindex,
 							sizeof(keyindex));
 		if (ret != 0) {
-			devwarn(usbdev,
-				"removing encryption key %d failed (%08X)",
-				index, ret);
+			netdev_warn(usbdev->net,
+				    "removing encryption key %d failed (%08X)\n",
+				    index, ret);
 			return ret;
 		}
 	}
@@ -1482,59 +1497,76 @@ static void set_multicast_list(struct us
 {
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 	struct dev_mc_list *mclist;
-	__le32 filter;
-	int ret, i, size;
-	char *buf;
+	__le32 filter, basefilter;
+	int ret;
+	char *mc_addrs = NULL;
+	int mc_count;
 
-	filter = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
+	basefilter = filter = RNDIS_PACKET_TYPE_DIRECTED |
+			      RNDIS_PACKET_TYPE_BROADCAST;
 
 	if (usbdev->net->flags & IFF_PROMISC) {
 		filter |= RNDIS_PACKET_TYPE_PROMISCUOUS |
 			RNDIS_PACKET_TYPE_ALL_LOCAL;
-	} else if (usbdev->net->flags & IFF_ALLMULTI ||
-		   usbdev->net->mc_count > priv->multicast_size) {
+	} else if (usbdev->net->flags & IFF_ALLMULTI) {
 		filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
-	} else if (usbdev->net->mc_count > 0) {
-		size = min(priv->multicast_size, usbdev->net->mc_count);
-		buf = kmalloc(size * ETH_ALEN, GFP_KERNEL);
-		if (!buf) {
-			devwarn(usbdev,
-				"couldn't alloc %d bytes of memory",
-				size * ETH_ALEN);
+	}
+
+	if (filter != basefilter)
+		goto set_filter;
+
+	/*
+	 * mc_list should be accessed holding the lock, so copy addresses to
+	 * local buffer first.
+	 */
+	netif_addr_lock_bh(usbdev->net);
+	mc_count = netdev_mc_count(usbdev->net);
+	if (mc_count > priv->multicast_size) {
+		filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
+	} else if (mc_count) {
+		int i = 0;
+
+		mc_addrs = kmalloc(mc_count * ETH_ALEN, GFP_ATOMIC);
+		if (!mc_addrs) {
+			netdev_warn(usbdev->net,
+				    "couldn't alloc %d bytes of memory\n",
+				    mc_count * ETH_ALEN);
+			netif_addr_unlock_bh(usbdev->net);
 			return;
 		}
 
-		mclist = usbdev->net->mc_list;
-		for (i = 0; i < size && mclist; mclist = mclist->next) {
-			if (mclist->dmi_addrlen != ETH_ALEN)
-				continue;
+		netdev_for_each_mc_addr(mclist, usbdev->net)
+			memcpy(mc_addrs + i++ * ETH_ALEN,
+			       mclist->dmi_addr, ETH_ALEN);
+	}
+	netif_addr_unlock_bh(usbdev->net);
 
-			memcpy(buf + i * ETH_ALEN, mclist->dmi_addr, ETH_ALEN);
-			i++;
-		}
+	if (filter != basefilter)
+		goto set_filter;
 
-		ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, buf,
-								i * ETH_ALEN);
-		if (ret == 0 && i > 0)
+	if (mc_count) {
+		ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, mc_addrs,
+				    mc_count * ETH_ALEN);
+		kfree(mc_addrs);
+		if (ret == 0)
 			filter |= RNDIS_PACKET_TYPE_MULTICAST;
 		else
 			filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
 
-		devdbg(usbdev, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d",
-						i, priv->multicast_size, ret);
-
-		kfree(buf);
+		netdev_dbg(usbdev->net, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n",
+			   mc_count, priv->multicast_size, ret);
 	}
 
+set_filter:
 	ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter,
 							sizeof(filter));
 	if (ret < 0) {
-		devwarn(usbdev, "couldn't set packet filter: %08x",
-							le32_to_cpu(filter));
+		netdev_warn(usbdev->net, "couldn't set packet filter: %08x\n",
+			    le32_to_cpu(filter));
 	}
 
-	devdbg(usbdev, "OID_GEN_CURRENT_PACKET_FILTER(%08x) -> %d",
-						le32_to_cpu(filter), ret);
+	netdev_dbg(usbdev->net, "OID_GEN_CURRENT_PACKET_FILTER(%08x) -> %d\n",
+		   le32_to_cpu(filter), ret);
 }
 
 /*
@@ -1592,7 +1624,8 @@ static int rndis_set_tx_power(struct wip
 	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
 	struct usbnet *usbdev = priv->usbdev;
 
-	devdbg(usbdev, "rndis_set_tx_power type:0x%x dbm:%i", type, dbm);
+	netdev_dbg(usbdev->net, "%s(): type:0x%x dbm:%i\n",
+		   __func__, type, dbm);
 
 	/* Device doesn't support changing txpower after initialization, only
 	 * turn off/on radio. Support 'auto' mode and setting same dBm that is
@@ -1615,7 +1648,7 @@ static int rndis_get_tx_power(struct wip
 
 	*dbm = get_bcm4320_power_dbm(priv);
 
-	devdbg(usbdev, "rndis_get_tx_power dbm:%i", *dbm);
+	netdev_dbg(usbdev->net, "%s(): dbm:%i\n", __func__, *dbm);
 
 	return 0;
 }
@@ -1629,7 +1662,7 @@ static int rndis_scan(struct wiphy *wiph
 	int ret;
 	__le32 tmp;
 
-	devdbg(usbdev, "cfg80211.scan");
+	netdev_dbg(usbdev->net, "cfg80211.scan\n");
 
 	/* Get current bssid list from device before new scan, as new scan
 	 * clears internal bssid list.
@@ -1669,8 +1702,8 @@ static struct cfg80211_bss *rndis_bss_in
 	int ie_len, bssid_len;
 	u8 *ie;
 
-	devdbg(usbdev, " found bssid: '%.32s' [%pM]", bssid->ssid.essid,
-							bssid->mac);
+	netdev_dbg(usbdev->net, " found bssid: '%.32s' [%pM]\n",
+		   bssid->ssid.essid, bssid->mac);
 
 	/* parse bssid structure */
 	bssid_len = le32_to_cpu(bssid->length);
@@ -1712,7 +1745,7 @@ static int rndis_check_bssid_list(struct
 	int ret = -EINVAL, len, count, bssid_len;
 	bool resized = false;
 
-	devdbg(usbdev, "check_bssid_list");
+	netdev_dbg(usbdev->net, "check_bssid_list\n");
 
 	len = CONTROL_BUFFER_SIZE;
 resize_buf:
@@ -1736,8 +1769,8 @@ resize_buf:
 	bssid = bssid_list->bssid;
 	bssid_len = le32_to_cpu(bssid->length);
 	count = le32_to_cpu(bssid_list->num_items);
-	devdbg(usbdev, "check_bssid_list: %d BSSIDs found (buflen: %d)", count,
-									len);
+	netdev_dbg(usbdev->net, "check_bssid_list: %d BSSIDs found (buflen: %d)\n",
+		   count, len);
 
 	while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
 		rndis_bss_info_update(usbdev, bssid);
@@ -1759,7 +1792,7 @@ static void rndis_get_scan_results(struc
 	struct usbnet *usbdev = priv->usbdev;
 	int ret;
 
-	devdbg(usbdev, "get_scan_results");
+	netdev_dbg(usbdev->net, "get_scan_results\n");
 
 	if (!priv->scan_request)
 		return;
@@ -1793,7 +1826,7 @@ static int rndis_connect(struct wiphy *w
 
 	if (sme->crypto.n_ciphers_pairwise > 0 &&
 			pairwise == RNDIS_WLAN_ALG_NONE) {
-		deverr(usbdev, "Unsupported pairwise cipher");
+		netdev_err(usbdev->net, "Unsupported pairwise cipher\n");
 		return -ENOTSUPP;
 	}
 
@@ -1803,28 +1836,30 @@ static int rndis_connect(struct wiphy *w
 
 	if (sme->crypto.n_akm_suites > 0 &&
 			keymgmt == RNDIS_WLAN_KEY_MGMT_NONE) {
-		deverr(usbdev, "Invalid keymgmt");
+		netdev_err(usbdev->net, "Invalid keymgmt\n");
 		return -ENOTSUPP;
 	}
 
-	devdbg(usbdev, "cfg80211.connect('%.32s':[%pM]:%d:[%d,0x%x:0x%x]:[0x%x:"
-			"0x%x]:0x%x)", sme->ssid, sme->bssid, chan,
-			sme->privacy, sme->crypto.wpa_versions, sme->auth_type,
-			groupwise, pairwise, keymgmt);
+	netdev_dbg(usbdev->net, "cfg80211.connect('%.32s':[%pM]:%d:[%d,0x%x:0x%x]:[0x%x:0x%x]:0x%x)\n",
+		   sme->ssid, sme->bssid, chan,
+		   sme->privacy, sme->crypto.wpa_versions, sme->auth_type,
+		   groupwise, pairwise, keymgmt);
 
 	if (is_associated(usbdev))
 		disassociate(usbdev, false);
 
 	ret = set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA);
 	if (ret < 0) {
-		devdbg(usbdev, "connect: set_infra_mode failed, %d", ret);
+		netdev_dbg(usbdev->net, "connect: set_infra_mode failed, %d\n",
+			   ret);
 		goto err_turn_radio_on;
 	}
 
 	ret = set_auth_mode(usbdev, sme->crypto.wpa_versions, sme->auth_type,
 								keymgmt);
 	if (ret < 0) {
-		devdbg(usbdev, "connect: set_auth_mode failed, %d", ret);
+		netdev_dbg(usbdev->net, "connect: set_auth_mode failed, %d\n",
+			   ret);
 		goto err_turn_radio_on;
 	}
 
@@ -1832,14 +1867,16 @@ static int rndis_connect(struct wiphy *w
 
 	ret = set_encr_mode(usbdev, pairwise, groupwise);
 	if (ret < 0) {
-		devdbg(usbdev, "connect: set_encr_mode failed, %d", ret);
+		netdev_dbg(usbdev->net, "connect: set_encr_mode failed, %d\n",
+			   ret);
 		goto err_turn_radio_on;
 	}
 
 	if (channel) {
 		ret = set_channel(usbdev, chan);
 		if (ret < 0) {
-			devdbg(usbdev, "connect: set_channel failed, %d", ret);
+			netdev_dbg(usbdev->net, "connect: set_channel failed, %d\n",
+				   ret);
 			goto err_turn_radio_on;
 		}
 	}
@@ -1848,8 +1885,8 @@ static int rndis_connect(struct wiphy *w
 		priv->encr_tx_key_index = sme->key_idx;
 		ret = add_wep_key(usbdev, sme->key, sme->key_len, sme->key_idx);
 		if (ret < 0) {
-			devdbg(usbdev, "connect: add_wep_key failed, %d "
-				"(%d, %d)", ret, sme->key_len, sme->key_idx);
+			netdev_dbg(usbdev->net, "connect: add_wep_key failed, %d (%d, %d)\n",
+				   ret, sme->key_len, sme->key_idx);
 			goto err_turn_radio_on;
 		}
 	}
@@ -1858,7 +1895,8 @@ static int rndis_connect(struct wiphy *w
 				!is_broadcast_ether_addr(sme->bssid)) {
 		ret = set_bssid(usbdev, sme->bssid);
 		if (ret < 0) {
-			devdbg(usbdev, "connect: set_bssid failed, %d", ret);
+			netdev_dbg(usbdev->net, "connect: set_bssid failed, %d\n",
+				   ret);
 			goto err_turn_radio_on;
 		}
 	} else
@@ -1880,7 +1918,7 @@ static int rndis_connect(struct wiphy *w
 
 	ret = set_essid(usbdev, &ssid);
 	if (ret < 0)
-		devdbg(usbdev, "connect: set_essid failed, %d", ret);
+		netdev_dbg(usbdev->net, "connect: set_essid failed, %d\n", ret);
 	return ret;
 
 err_turn_radio_on:
@@ -1895,7 +1933,7 @@ static int rndis_disconnect(struct wiphy
 	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
 	struct usbnet *usbdev = priv->usbdev;
 
-	devdbg(usbdev, "cfg80211.disconnect(%d)", reason_code);
+	netdev_dbg(usbdev->net, "cfg80211.disconnect(%d)\n", reason_code);
 
 	priv->connected = false;
 	memset(priv->bssid, 0, ETH_ALEN);
@@ -1929,21 +1967,23 @@ static int rndis_join_ibss(struct wiphy
 		alg = RNDIS_WLAN_ALG_NONE;
 	}
 
-	devdbg(usbdev, "cfg80211.join_ibss('%.32s':[%pM]:%d:%d)", params->ssid,
-					params->bssid, chan, params->privacy);
+	netdev_dbg(usbdev->net, "cfg80211.join_ibss('%.32s':[%pM]:%d:%d)\n",
+		   params->ssid, params->bssid, chan, params->privacy);
 
 	if (is_associated(usbdev))
 		disassociate(usbdev, false);
 
 	ret = set_infra_mode(usbdev, NDIS_80211_INFRA_ADHOC);
 	if (ret < 0) {
-		devdbg(usbdev, "join_ibss: set_infra_mode failed, %d", ret);
+		netdev_dbg(usbdev->net, "join_ibss: set_infra_mode failed, %d\n",
+			   ret);
 		goto err_turn_radio_on;
 	}
 
 	ret = set_auth_mode(usbdev, 0, auth_type, RNDIS_WLAN_KEY_MGMT_NONE);
 	if (ret < 0) {
-		devdbg(usbdev, "join_ibss: set_auth_mode failed, %d", ret);
+		netdev_dbg(usbdev->net, "join_ibss: set_auth_mode failed, %d\n",
+			   ret);
 		goto err_turn_radio_on;
 	}
 
@@ -1951,15 +1991,16 @@ static int rndis_join_ibss(struct wiphy
 
 	ret = set_encr_mode(usbdev, alg, RNDIS_WLAN_ALG_NONE);
 	if (ret < 0) {
-		devdbg(usbdev, "join_ibss: set_encr_mode failed, %d", ret);
+		netdev_dbg(usbdev->net, "join_ibss: set_encr_mode failed, %d\n",
+			   ret);
 		goto err_turn_radio_on;
 	}
 
 	if (channel) {
 		ret = set_channel(usbdev, chan);
 		if (ret < 0) {
-			devdbg(usbdev, "join_ibss: set_channel failed, %d",
-				ret);
+			netdev_dbg(usbdev->net, "join_ibss: set_channel failed, %d\n",
+				   ret);
 			goto err_turn_radio_on;
 		}
 	}
@@ -1968,7 +2009,8 @@ static int rndis_join_ibss(struct wiphy
 				!is_broadcast_ether_addr(params->bssid)) {
 		ret = set_bssid(usbdev, params->bssid);
 		if (ret < 0) {
-			devdbg(usbdev, "join_ibss: set_bssid failed, %d", ret);
+			netdev_dbg(usbdev->net, "join_ibss: set_bssid failed, %d\n",
+				   ret);
 			goto err_turn_radio_on;
 		}
 	} else
@@ -1988,7 +2030,8 @@ static int rndis_join_ibss(struct wiphy
 
 	ret = set_essid(usbdev, &ssid);
 	if (ret < 0)
-		devdbg(usbdev, "join_ibss: set_essid failed, %d", ret);
+		netdev_dbg(usbdev->net, "join_ibss: set_essid failed, %d\n",
+			   ret);
 	return ret;
 
 err_turn_radio_on:
@@ -2002,7 +2045,7 @@ static int rndis_leave_ibss(struct wiphy
 	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
 	struct usbnet *usbdev = priv->usbdev;
 
-	devdbg(usbdev, "cfg80211.leave_ibss()");
+	netdev_dbg(usbdev->net, "cfg80211.leave_ibss()\n");
 
 	priv->connected = false;
 	memset(priv->bssid, 0, ETH_ALEN);
@@ -2028,8 +2071,8 @@ static int rndis_add_key(struct wiphy *w
 	struct usbnet *usbdev = priv->usbdev;
 	__le32 flags;
 
-	devdbg(usbdev, "rndis_add_key(%i, %pM, %08x)", key_index, mac_addr,
-							params->cipher);
+	netdev_dbg(usbdev->net, "%s(%i, %pM, %08x)\n",
+		   __func__, key_index, mac_addr, params->cipher);
 
 	switch (params->cipher) {
 	case WLAN_CIPHER_SUITE_WEP40:
@@ -2050,8 +2093,8 @@ static int rndis_add_key(struct wiphy *w
 				key_index, mac_addr, params->seq,
 				params->seq_len, params->cipher, flags);
 	default:
-		devdbg(usbdev, "rndis_add_key: unsupported cipher %08x",
-							params->cipher);
+		netdev_dbg(usbdev->net, "%s(): unsupported cipher %08x\n",
+			   __func__, params->cipher);
 		return -ENOTSUPP;
 	}
 }
@@ -2062,7 +2105,7 @@ static int rndis_del_key(struct wiphy *w
 	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
 	struct usbnet *usbdev = priv->usbdev;
 
-	devdbg(usbdev, "rndis_del_key(%i, %pM)", key_index, mac_addr);
+	netdev_dbg(usbdev->net, "%s(%i, %pM)\n", __func__, key_index, mac_addr);
 
 	return remove_key(usbdev, key_index, mac_addr);
 }
@@ -2074,7 +2117,7 @@ static int rndis_set_default_key(struct
 	struct usbnet *usbdev = priv->usbdev;
 	struct rndis_wlan_encr_key key;
 
-	devdbg(usbdev, "rndis_set_default_key(%i)", key_index);
+	netdev_dbg(usbdev->net, "%s(%i)\n", __func__, key_index);
 
 	priv->encr_tx_key_index = key_index;
 
@@ -2188,7 +2231,8 @@ static void rndis_wlan_do_link_up_work(s
 	if (ret < 0)
 		memset(bssid, 0, sizeof(bssid));
 
-	devdbg(usbdev, "link up work: [%pM] %s", bssid, roamed ? "roamed" : "");
+	netdev_dbg(usbdev->net, "link up work: [%pM]%s\n",
+		   bssid, roamed ? " roamed" : "");
 
 	/* Internal bss list in device always contains at least the currently
 	 * connected bss and we can get it to cfg80211 with
@@ -2270,8 +2314,8 @@ static void rndis_wlan_auth_indication(s
 	/* must have at least one array entry */
 	if (len < offsetof(struct ndis_80211_status_indication, u) +
 				sizeof(struct ndis_80211_auth_request)) {
-		devinfo(usbdev, "authentication indication: "
-				"too short message (%i)", len);
+		netdev_info(usbdev->net, "authentication indication: too short message (%i)\n",
+			    len);
 		return;
 	}
 
@@ -2298,8 +2342,8 @@ static void rndis_wlan_auth_indication(s
 			type = "group_error";
 		}
 
-		devinfo(usbdev, "authentication indication: %s (0x%08x)", type,
-				le32_to_cpu(auth_req->flags));
+		netdev_info(usbdev->net, "authentication indication: %s (0x%08x)\n",
+			    type, le32_to_cpu(auth_req->flags));
 
 		if (pairwise_error) {
 			key_type = NL80211_KEYTYPE_PAIRWISE;
@@ -2335,8 +2379,8 @@ static void rndis_wlan_pmkid_cand_list_i
 
 	if (len < offsetof(struct ndis_80211_status_indication, u) +
 				sizeof(struct ndis_80211_pmkid_cand_list)) {
-		devinfo(usbdev, "pmkid candidate list indication: "
-				"too short message (%i)", len);
+		netdev_info(usbdev->net, "pmkid candidate list indication: too short message (%i)\n",
+			    len);
 		return;
 	}
 
@@ -2346,18 +2390,16 @@ static void rndis_wlan_pmkid_cand_list_i
 			offsetof(struct ndis_80211_status_indication, u);
 
 	if (len < expected_len) {
-		devinfo(usbdev, "pmkid candidate list indication: "
-				"list larger than buffer (%i < %i)",
-				len, expected_len);
+		netdev_info(usbdev->net, "pmkid candidate list indication: list larger than buffer (%i < %i)\n",
+			    len, expected_len);
 		return;
 	}
 
 	cand_list = &indication->u.cand_list;
 
-	devinfo(usbdev, "pmkid candidate list indication: "
-			"version %i, candidates %i",
-			le32_to_cpu(cand_list->version),
-			le32_to_cpu(cand_list->num_candidates));
+	netdev_info(usbdev->net, "pmkid candidate list indication: version %i, candidates %i\n",
+		    le32_to_cpu(cand_list->version),
+		    le32_to_cpu(cand_list->num_candidates));
 
 	if (le32_to_cpu(cand_list->version) != 1)
 		return;
@@ -2366,8 +2408,8 @@ static void rndis_wlan_pmkid_cand_list_i
 		struct ndis_80211_pmkid_candidate *cand =
 						&cand_list->candidate_list[i];
 
-		devdbg(usbdev, "cand[%i]: flags: 0x%08x, bssid: %pM",
-				i, le32_to_cpu(cand->flags), cand->bssid);
+		netdev_dbg(usbdev->net, "cand[%i]: flags: 0x%08x, bssid: %pM\n",
+			   i, le32_to_cpu(cand->flags), cand->bssid);
 
 #if 0
 		struct iw_pmkid_cand pcand;
@@ -2398,15 +2440,14 @@ static void rndis_wlan_media_specific_in
 	len = le32_to_cpu(msg->length);
 
 	if (len < 8) {
-		devinfo(usbdev, "media specific indication, "
-				"ignore too short message (%i < 8)", len);
+		netdev_info(usbdev->net, "media specific indication, ignore too short message (%i < 8)\n",
+			    len);
 		return;
 	}
 
 	if (offset + len > buflen) {
-		devinfo(usbdev, "media specific indication, "
-				"too large to fit to buffer (%i > %i)",
-				offset + len, buflen);
+		netdev_info(usbdev->net, "media specific indication, too large to fit to buffer (%i > %i)\n",
+			    offset + len, buflen);
 		return;
 	}
 
@@ -2414,13 +2455,13 @@ static void rndis_wlan_media_specific_in
 
 	switch (le32_to_cpu(indication->status_type)) {
 	case NDIS_80211_STATUSTYPE_RADIOSTATE:
-		devinfo(usbdev, "radio state indication: %i",
-			le32_to_cpu(indication->u.radio_status));
+		netdev_info(usbdev->net, "radio state indication: %i\n",
+			    le32_to_cpu(indication->u.radio_status));
 		return;
 
 	case NDIS_80211_STATUSTYPE_MEDIASTREAMMODE:
-		devinfo(usbdev, "media stream mode indication: %i",
-			le32_to_cpu(indication->u.media_stream_mode));
+		netdev_info(usbdev->net, "media stream mode indication: %i\n",
+			    le32_to_cpu(indication->u.media_stream_mode));
 		return;
 
 	case NDIS_80211_STATUSTYPE_AUTHENTICATION:
@@ -2432,9 +2473,8 @@ static void rndis_wlan_media_specific_in
 		return;
 
 	default:
-		devinfo(usbdev, "media specific indication: "
-				"unknown status type 0x%08x",
-				le32_to_cpu(indication->status_type));
+		netdev_info(usbdev->net, "media specific indication: unknown status type 0x%08x\n",
+			    le32_to_cpu(indication->status_type));
 	}
 }
 
@@ -2451,14 +2491,13 @@ static void rndis_wlan_indication(struct
 			 * and userspace to think that device is
 			 * roaming/reassociating when it isn't.
 			 */
-			devdbg(usbdev, "ignored OID_802_11_ADD_KEY triggered "
-					"'media connect'");
+			netdev_dbg(usbdev->net, "ignored OID_802_11_ADD_KEY triggered 'media connect'\n");
 			return;
 		}
 
 		usbnet_pause_rx(usbdev);
 
-		devinfo(usbdev, "media connect");
+		netdev_info(usbdev->net, "media connect\n");
 
 		/* queue work to avoid recursive calls into rndis_command */
 		set_bit(WORK_LINK_UP, &priv->work_pending);
@@ -2466,7 +2505,7 @@ static void rndis_wlan_indication(struct
 		break;
 
 	case RNDIS_STATUS_MEDIA_DISCONNECT:
-		devinfo(usbdev, "media disconnect");
+		netdev_info(usbdev->net, "media disconnect\n");
 
 		/* queue work to avoid recursive calls into rndis_command */
 		set_bit(WORK_LINK_DOWN, &priv->work_pending);
@@ -2478,8 +2517,8 @@ static void rndis_wlan_indication(struct
 		break;
 
 	default:
-		devinfo(usbdev, "indication: 0x%08x",
-				le32_to_cpu(msg->status));
+		netdev_info(usbdev->net, "indication: 0x%08x\n",
+			    le32_to_cpu(msg->status));
 		break;
 	}
 }
@@ -2544,8 +2583,8 @@ static void rndis_device_poller(struct w
 	if (ret == 0)
 		priv->last_qual = level_to_qual(le32_to_cpu(rssi));
 
-	devdbg(usbdev, "dev-poller: OID_802_11_RSSI -> %d, rssi:%d, qual: %d",
-		ret, le32_to_cpu(rssi), level_to_qual(le32_to_cpu(rssi)));
+	netdev_dbg(usbdev->net, "dev-poller: OID_802_11_RSSI -> %d, rssi:%d, qual: %d\n",
+		   ret, le32_to_cpu(rssi), level_to_qual(le32_to_cpu(rssi)));
 
 	/* Workaround transfer stalls on poor quality links.
 	 * TODO: find right way to fix these stalls (as stalls do not happen
@@ -2594,23 +2633,9 @@ end:
 /*
  * driver/device initialization
  */
-static int bcm4320a_early_init(struct usbnet *usbdev)
-{
-	/* bcm4320a doesn't handle configuration parameters well. Try
-	 * set any and you get partially zeroed mac and broken device.
-	 */
-
-	return 0;
-}
-
-static int bcm4320b_early_init(struct usbnet *usbdev)
+static void rndis_copy_module_params(struct usbnet *usbdev)
 {
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
-	char buf[8];
-
-	/* Early initialization settings, setting these won't have effect
-	 * if called after generic_rndis_bind().
-	 */
 
 	priv->param_country[0] = modparam_country[0];
 	priv->param_country[1] = modparam_country[1];
@@ -2652,6 +2677,32 @@ static int bcm4320b_early_init(struct us
 		priv->param_workaround_interval = 500;
 	else
 		priv->param_workaround_interval = modparam_workaround_interval;
+}
+
+static int bcm4320a_early_init(struct usbnet *usbdev)
+{
+	/* copy module parameters for bcm4320a so that iwconfig reports txpower
+	 * and workaround parameter is copied to private structure correctly.
+	 */
+	rndis_copy_module_params(usbdev);
+
+	/* bcm4320a doesn't handle configuration parameters well. Try
+	 * set any and you get partially zeroed mac and broken device.
+	 */
+
+	return 0;
+}
+
+static int bcm4320b_early_init(struct usbnet *usbdev)
+{
+	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+	char buf[8];
+
+	rndis_copy_module_params(usbdev);
+
+	/* Early initialization settings, setting these won't have effect
+	 * if called after generic_rndis_bind().
+	 */
 
 	rndis_set_config_parameter_str(usbdev, "Country", priv->param_country);
 	rndis_set_config_parameter_str(usbdev, "FrameBursting",
@@ -2826,11 +2877,11 @@ static int rndis_wlan_reset(struct usbne
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 	int retval;
 
-	devdbg(usbdev, "rndis_wlan_reset");
+	netdev_dbg(usbdev->net, "%s()\n", __func__);
 
 	retval = rndis_reset(usbdev);
 	if (retval)
-		devwarn(usbdev, "rndis_reset() failed: %d", retval);
+		netdev_warn(usbdev->net, "rndis_reset failed: %d\n", retval);
 
 	/* rndis_reset cleared multicast list, so restore here.
 	   (set_multicast_list() also turns on current packet filter) */
@@ -2848,7 +2899,7 @@ static int rndis_wlan_stop(struct usbnet
 	int retval;
 	__le32 filter;
 
-	devdbg(usbdev, "rndis_wlan_stop");
+	netdev_dbg(usbdev->net, "%s()\n", __func__);
 
 	retval = disassociate(usbdev, false);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/Kconfig linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -54,17 +54,17 @@ config RT61PCI
 	  When compiled as a module, this driver will be called rt61pci.
 
 config RT2800PCI_PCI
-	tristate
+	boolean
 	depends on PCI
 	default y
 
 config RT2800PCI_SOC
-	tristate
+	boolean
 	depends on RALINK_RT288X || RALINK_RT305X
 	default y
 
 config RT2800PCI
-	tristate "Ralink rt2800 (PCI/PCMCIA) support (VERY EXPERIMENTAL)"
+	tristate "Ralink rt28xx/rt30xx/rt35xx (PCI/PCIe/PCMCIA) support (EXPERIMENTAL)"
 	depends on (RT2800PCI_PCI || RT2800PCI_SOC) && EXPERIMENTAL
 	select RT2800_LIB
 	select RT2X00_LIB_PCI if RT2800PCI_PCI
@@ -75,7 +75,7 @@ config RT2800PCI
 	select CRC_CCITT
 	select EEPROM_93CX6
 	---help---
-	  This adds support for rt2800 wireless chipset family.
+	  This adds support for rt2800/rt3000/rt3500 wireless chipset family.
 	  Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890 & RT3052
 
 	  This driver is non-functional at the moment and is intended for
@@ -83,6 +83,32 @@ config RT2800PCI
 
 	  When compiled as a module, this driver will be called "rt2800pci.ko".
 
+if RT2800PCI
+
+config RT2800PCI_RT30XX
+	bool "rt2800pci - Include support for rt30xx (PCI/PCIe/PCMCIA) devices"
+	default n
+	---help---
+	  This adds support for rt30xx wireless chipset family to the
+	  rt2800pci driver.
+	  Supported chips: RT3090, RT3091 & RT3092
+
+	  Support for these devices is non-functional at the moment and is
+	  intended for testers and developers.
+
+config RT2800PCI_RT35XX
+	bool "rt2800pci - Include support for rt35xx (PCI/PCIe/PCMCIA) devices"
+	default n
+	---help---
+	  This adds support for rt35xx wireless chipset family to the
+	  rt2800pci driver.
+	  Supported chips: RT3060, RT3062, RT3562, RT3592
+
+	  Support for these devices is non-functional at the moment and is
+	  intended for testers and developers.
+
+endif
+
 config RT2500USB
 	tristate "Ralink rt2500 (USB) support"
 	depends on USB
@@ -126,6 +152,43 @@ config RT2800USB
 
 	  When compiled as a module, this driver will be called "rt2800usb.ko".
 
+if RT2800USB
+
+config RT2800USB_RT30XX
+	bool "rt2800usb - Include support for rt30xx (USB) devices"
+	default n
+	---help---
+	  This adds support for rt30xx wireless chipset family to the
+	  rt2800usb driver.
+	  Supported chips: RT3070, RT3071 & RT3072
+
+	  Support for these devices is non-functional at the moment and is
+	  intended for testers and developers.
+
+config RT2800USB_RT35XX
+	bool "rt2800usb - Include support for rt35xx (USB) devices"
+	default n
+	---help---
+	  This adds support for rt35xx wireless chipset family to the
+	  rt2800usb driver.
+	  Supported chips: RT3572
+
+	  Support for these devices is non-functional at the moment and is
+	  intended for testers and developers.
+
+config RT2800USB_UNKNOWN
+	bool "rt2800usb - Include support for unknown (USB) devices"
+	default n
+	---help---
+	  This adds support for rt2800 family devices that are known to
+	  have a rt2800 family chipset, but for which the exact chipset
+	  is unknown.
+
+	  Support status for these devices is unknown, and enabling these
+	  devices may or may not work.
+
+endif
+
 config RT2800_LIB
 	tristate
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2400pci.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2400pci.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2400pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2400pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/eeprom_93cx6.h>
+#include <linux/slab.h>
 
 #include "rt2x00.h"
 #include "rt2x00pci.h"
@@ -451,7 +452,7 @@ static void rt2400pci_config_channel(str
 	/*
 	 * RF2420 chipset don't need any additional actions.
 	 */
-	if (rt2x00_rf(&rt2x00dev->chip, RF2420))
+	if (rt2x00_rf(rt2x00dev, RF2420))
 		return;
 
 	/*
@@ -1340,11 +1341,10 @@ static int rt2400pci_init_eeprom(struct
 	 */
 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
 	rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
-	rt2x00_set_chip_rf(rt2x00dev, value, reg);
-	rt2x00_print_chip(rt2x00dev);
+	rt2x00_set_chip(rt2x00dev, RT2460, value,
+			rt2x00_get_field32(reg, CSR0_REVISION));
 
-	if (!rt2x00_rf(&rt2x00dev->chip, RF2420) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2421)) {
+	if (!rt2x00_rf(rt2x00dev, RF2420) && !rt2x00_rf(rt2x00dev, RF2421)) {
 		ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
 		return -ENODEV;
 	}
@@ -1562,7 +1562,6 @@ static const struct ieee80211_ops rt2400
 	.get_stats		= rt2x00mac_get_stats,
 	.bss_info_changed	= rt2x00mac_bss_info_changed,
 	.conf_tx		= rt2400pci_conf_tx,
-	.get_tx_stats		= rt2x00mac_get_tx_stats,
 	.get_tsf		= rt2400pci_get_tsf,
 	.tx_last_beacon		= rt2400pci_tx_last_beacon,
 	.rfkill_poll		= rt2x00mac_rfkill_poll,
@@ -1643,7 +1642,7 @@ static const struct rt2x00_ops rt2400pci
 /*
  * RT2400pci module information.
  */
-static struct pci_device_id rt2400pci_device_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(rt2400pci_device_table) = {
 	{ PCI_DEVICE(0x1814, 0x0101), PCI_DEVICE_DATA(&rt2400pci_ops) },
 	{ 0, }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2400pci.h linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2400pci.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2400pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2400pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -65,6 +65,7 @@
  * CSR0: ASIC revision number.
  */
 #define CSR0				0x0000
+#define CSR0_REVISION			FIELD32(0x0000ffff)
 
 /*
  * CSR1: System control register.
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2500pci.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2500pci.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2500pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2500pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/eeprom_93cx6.h>
+#include <linux/slab.h>
 
 #include "rt2x00.h"
 #include "rt2x00pci.h"
@@ -440,8 +441,7 @@ static void rt2500pci_config_ant(struct
 	/*
 	 * RT2525E and RT5222 need to flip TX I/Q
 	 */
-	if (rt2x00_rf(&rt2x00dev->chip, RF2525E) ||
-	    rt2x00_rf(&rt2x00dev->chip, RF5222)) {
+	if (rt2x00_rf(rt2x00dev, RF2525E) || rt2x00_rf(rt2x00dev, RF5222)) {
 		rt2x00_set_field8(&r2, BBP_R2_TX_IQ_FLIP, 1);
 		rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 1);
 		rt2x00_set_field32(&reg, BBPCSR1_OFDM_FLIP, 1);
@@ -449,7 +449,7 @@ static void rt2500pci_config_ant(struct
 		/*
 		 * RT2525E does not need RX I/Q Flip.
 		 */
-		if (rt2x00_rf(&rt2x00dev->chip, RF2525E))
+		if (rt2x00_rf(rt2x00dev, RF2525E))
 			rt2x00_set_field8(&r14, BBP_R14_RX_IQ_FLIP, 0);
 	} else {
 		rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 0);
@@ -475,14 +475,14 @@ static void rt2500pci_config_channel(str
 	 * Switch on tuning bits.
 	 * For RT2523 devices we do not need to update the R1 register.
 	 */
-	if (!rt2x00_rf(&rt2x00dev->chip, RF2523))
+	if (!rt2x00_rf(rt2x00dev, RF2523))
 		rt2x00_set_field32(&rf->rf1, RF1_TUNER, 1);
 	rt2x00_set_field32(&rf->rf3, RF3_TUNER, 1);
 
 	/*
 	 * For RT2525 we should first set the channel to half band higher.
 	 */
-	if (rt2x00_rf(&rt2x00dev->chip, RF2525)) {
+	if (rt2x00_rf(rt2x00dev, RF2525)) {
 		static const u32 vals[] = {
 			0x00080cbe, 0x00080d02, 0x00080d06, 0x00080d0a,
 			0x00080d0e, 0x00080d12, 0x00080d16, 0x00080d1a,
@@ -516,7 +516,7 @@ static void rt2500pci_config_channel(str
 	 * Switch off tuning bits.
 	 * For RT2523 devices we do not need to update the R1 register.
 	 */
-	if (!rt2x00_rf(&rt2x00dev->chip, RF2523)) {
+	if (!rt2x00_rf(rt2x00dev, RF2523)) {
 		rt2x00_set_field32(&rf->rf1, RF1_TUNER, 0);
 		rt2500pci_rf_write(rt2x00dev, 1, rf->rf1);
 	}
@@ -640,7 +640,7 @@ static void rt2500pci_link_tuner(struct
 	 * up to version C the link tuning should halt after 20
 	 * seconds while being associated.
 	 */
-	if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D &&
+	if (rt2x00_rev(rt2x00dev) < RT2560_VERSION_D &&
 	    rt2x00dev->intf_associated && count > 20)
 		return;
 
@@ -650,7 +650,7 @@ static void rt2500pci_link_tuner(struct
 	 * should go straight to dynamic CCA tuning when they
 	 * are not associated.
 	 */
-	if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D ||
+	if (rt2x00_rev(rt2x00dev) < RT2560_VERSION_D ||
 	    !rt2x00dev->intf_associated)
 		goto dynamic_cca_tune;
 
@@ -1504,15 +1504,15 @@ static int rt2500pci_init_eeprom(struct
 	 */
 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
 	rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
-	rt2x00_set_chip_rf(rt2x00dev, value, reg);
-	rt2x00_print_chip(rt2x00dev);
+	rt2x00_set_chip(rt2x00dev, RT2560, value,
+			rt2x00_get_field32(reg, CSR0_REVISION));
 
-	if (!rt2x00_rf(&rt2x00dev->chip, RF2522) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2523) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2524) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2525) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2525E) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF5222)) {
+	if (!rt2x00_rf(rt2x00dev, RF2522) &&
+	    !rt2x00_rf(rt2x00dev, RF2523) &&
+	    !rt2x00_rf(rt2x00dev, RF2524) &&
+	    !rt2x00_rf(rt2x00dev, RF2525) &&
+	    !rt2x00_rf(rt2x00dev, RF2525E) &&
+	    !rt2x00_rf(rt2x00dev, RF5222)) {
 		ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
 		return -ENODEV;
 	}
@@ -1744,22 +1744,22 @@ static int rt2500pci_probe_hw_mode(struc
 	spec->supported_bands = SUPPORT_BAND_2GHZ;
 	spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
 
-	if (rt2x00_rf(&rt2x00dev->chip, RF2522)) {
+	if (rt2x00_rf(rt2x00dev, RF2522)) {
 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522);
 		spec->channels = rf_vals_bg_2522;
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF2523)) {
+	} else if (rt2x00_rf(rt2x00dev, RF2523)) {
 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2523);
 		spec->channels = rf_vals_bg_2523;
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF2524)) {
+	} else if (rt2x00_rf(rt2x00dev, RF2524)) {
 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2524);
 		spec->channels = rf_vals_bg_2524;
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF2525)) {
+	} else if (rt2x00_rf(rt2x00dev, RF2525)) {
 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525);
 		spec->channels = rf_vals_bg_2525;
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) {
+	} else if (rt2x00_rf(rt2x00dev, RF2525E)) {
 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
 		spec->channels = rf_vals_bg_2525e;
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) {
+	} else if (rt2x00_rf(rt2x00dev, RF5222)) {
 		spec->supported_bands |= SUPPORT_BAND_5GHZ;
 		spec->num_channels = ARRAY_SIZE(rf_vals_5222);
 		spec->channels = rf_vals_5222;
@@ -1860,7 +1860,6 @@ static const struct ieee80211_ops rt2500
 	.get_stats		= rt2x00mac_get_stats,
 	.bss_info_changed	= rt2x00mac_bss_info_changed,
 	.conf_tx		= rt2x00mac_conf_tx,
-	.get_tx_stats		= rt2x00mac_get_tx_stats,
 	.get_tsf		= rt2500pci_get_tsf,
 	.tx_last_beacon		= rt2500pci_tx_last_beacon,
 	.rfkill_poll		= rt2x00mac_rfkill_poll,
@@ -1941,7 +1940,7 @@ static const struct rt2x00_ops rt2500pci
 /*
  * RT2500pci module information.
  */
-static struct pci_device_id rt2500pci_device_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(rt2500pci_device_table) = {
 	{ PCI_DEVICE(0x1814, 0x0201), PCI_DEVICE_DATA(&rt2500pci_ops) },
 	{ 0, }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2500pci.h linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2500pci.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2500pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2500pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -76,6 +76,7 @@
  * CSR0: ASIC revision number.
  */
 #define CSR0				0x0000
+#define CSR0_REVISION			FIELD32(0x0000ffff)
 
 /*
  * CSR1: System control register.
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2500usb.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2500usb.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2500usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2500usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "rt2x00.h"
@@ -368,7 +369,7 @@ static int rt2500usb_config_key(struct r
 
 		/*
 		 * The encryption key doesn't fit within the CSR cache,
-		 * this means we should allocate it seperately and use
+		 * this means we should allocate it separately and use
 		 * rt2x00usb_vendor_request() to send the key to the hardware.
 		 */
 		reg = KEY_ENTRY(key->hw_key_idx);
@@ -382,7 +383,7 @@ static int rt2500usb_config_key(struct r
 		/*
 		 * The driver does not support the IV/EIV generation
 		 * in hardware. However it demands the data to be provided
-		 * both seperately as well as inside the frame.
+		 * both separately as well as inside the frame.
 		 * We already provided the CONFIG_CRYPTO_COPY_IV to rt2x00lib
 		 * to ensure rt2x00lib will not strip the data from the
 		 * frame after the copy, now we must tell mac80211
@@ -565,8 +566,7 @@ static void rt2500usb_config_ant(struct
 	/*
 	 * RT2525E and RT5222 need to flip TX I/Q
 	 */
-	if (rt2x00_rf(&rt2x00dev->chip, RF2525E) ||
-	    rt2x00_rf(&rt2x00dev->chip, RF5222)) {
+	if (rt2x00_rf(rt2x00dev, RF2525E) || rt2x00_rf(rt2x00dev, RF5222)) {
 		rt2x00_set_field8(&r2, BBP_R2_TX_IQ_FLIP, 1);
 		rt2x00_set_field16(&csr5, PHY_CSR5_CCK_FLIP, 1);
 		rt2x00_set_field16(&csr6, PHY_CSR6_OFDM_FLIP, 1);
@@ -574,7 +574,7 @@ static void rt2500usb_config_ant(struct
 		/*
 		 * RT2525E does not need RX I/Q Flip.
 		 */
-		if (rt2x00_rf(&rt2x00dev->chip, RF2525E))
+		if (rt2x00_rf(rt2x00dev, RF2525E))
 			rt2x00_set_field8(&r14, BBP_R14_RX_IQ_FLIP, 0);
 	} else {
 		rt2x00_set_field16(&csr5, PHY_CSR5_CCK_FLIP, 0);
@@ -598,7 +598,7 @@ static void rt2500usb_config_channel(str
 	/*
 	 * For RT2525E we should first set the channel to half band higher.
 	 */
-	if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) {
+	if (rt2x00_rf(rt2x00dev, RF2525E)) {
 		static const u32 vals[] = {
 			0x000008aa, 0x000008ae, 0x000008ae, 0x000008b2,
 			0x000008b2, 0x000008b6, 0x000008b6, 0x000008ba,
@@ -793,7 +793,7 @@ static int rt2500usb_init_registers(stru
 	rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 1);
 	rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg);
 
-	if (rt2x00_rev(&rt2x00dev->chip) >= RT2570_VERSION_C) {
+	if (rt2x00_rev(rt2x00dev) >= RT2570_VERSION_C) {
 		rt2500usb_register_read(rt2x00dev, PHY_CSR2, &reg);
 		rt2x00_set_field16(&reg, PHY_CSR2_LNA, 0);
 	} else {
@@ -1409,21 +1409,18 @@ static int rt2500usb_init_eeprom(struct
 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
 	rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg);
 	rt2x00_set_chip(rt2x00dev, RT2570, value, reg);
-	rt2x00_print_chip(rt2x00dev);
-
-	if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0) ||
-	    rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) {
 
+	if (((reg & 0xfff0) != 0) || ((reg & 0x0000000f) == 0)) {
 		ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
 		return -ENODEV;
 	}
 
-	if (!rt2x00_rf(&rt2x00dev->chip, RF2522) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2523) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2524) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2525) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2525E) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF5222)) {
+	if (!rt2x00_rf(rt2x00dev, RF2522) &&
+	    !rt2x00_rf(rt2x00dev, RF2523) &&
+	    !rt2x00_rf(rt2x00dev, RF2524) &&
+	    !rt2x00_rf(rt2x00dev, RF2525) &&
+	    !rt2x00_rf(rt2x00dev, RF2525E) &&
+	    !rt2x00_rf(rt2x00dev, RF5222)) {
 		ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
 		return -ENODEV;
 	}
@@ -1647,6 +1644,11 @@ static int rt2500usb_probe_hw_mode(struc
 	unsigned int i;
 
 	/*
+	 * Disable powersaving as default.
+	 */
+	rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+
+	/*
 	 * Initialize all hw fields.
 	 */
 	rt2x00dev->hw->flags =
@@ -1667,22 +1669,22 @@ static int rt2500usb_probe_hw_mode(struc
 	spec->supported_bands = SUPPORT_BAND_2GHZ;
 	spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
 
-	if (rt2x00_rf(&rt2x00dev->chip, RF2522)) {
+	if (rt2x00_rf(rt2x00dev, RF2522)) {
 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522);
 		spec->channels = rf_vals_bg_2522;
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF2523)) {
+	} else if (rt2x00_rf(rt2x00dev, RF2523)) {
 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2523);
 		spec->channels = rf_vals_bg_2523;
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF2524)) {
+	} else if (rt2x00_rf(rt2x00dev, RF2524)) {
 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2524);
 		spec->channels = rf_vals_bg_2524;
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF2525)) {
+	} else if (rt2x00_rf(rt2x00dev, RF2525)) {
 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525);
 		spec->channels = rf_vals_bg_2525;
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) {
+	} else if (rt2x00_rf(rt2x00dev, RF2525E)) {
 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
 		spec->channels = rf_vals_bg_2525e;
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) {
+	} else if (rt2x00_rf(rt2x00dev, RF5222)) {
 		spec->supported_bands |= SUPPORT_BAND_5GHZ;
 		spec->num_channels = ARRAY_SIZE(rf_vals_5222);
 		spec->channels = rf_vals_5222;
@@ -1763,7 +1765,6 @@ static const struct ieee80211_ops rt2500
 	.get_stats		= rt2x00mac_get_stats,
 	.bss_info_changed	= rt2x00mac_bss_info_changed,
 	.conf_tx		= rt2x00mac_conf_tx,
-	.get_tx_stats		= rt2x00mac_get_tx_stats,
 	.rfkill_poll		= rt2x00mac_rfkill_poll,
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800.h linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2800.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2800.h	2010-05-16 17:17:36.000000000 -0400
@@ -60,11 +60,11 @@
 /*
  * Chipset version.
  */
-#define RT2860C_VERSION			0x28600100
-#define RT2860D_VERSION			0x28600101
-#define RT2880E_VERSION			0x28720200
-#define RT2883_VERSION			0x28830300
-#define RT3070_VERSION			0x30700200
+#define RT2860C_VERSION			0x0100
+#define RT2860D_VERSION			0x0101
+#define RT2880E_VERSION			0x0200
+#define RT2883_VERSION			0x0300
+#define RT3070_VERSION			0x0200
 
 /*
  * Signal information.
@@ -408,8 +408,8 @@
  * ASIC_VER: 2860 or 2870
  */
 #define MAC_CSR0			0x1000
-#define MAC_CSR0_ASIC_REV		FIELD32(0x0000ffff)
-#define MAC_CSR0_ASIC_VER		FIELD32(0xffff0000)
+#define MAC_CSR0_REVISION		FIELD32(0x0000ffff)
+#define MAC_CSR0_CHIPSET		FIELD32(0xffff0000)
 
 /*
  * MAC_SYS_CTRL:
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800lib.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2800lib.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800lib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2800lib.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,11 +35,15 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "rt2x00.h"
-#if defined(CONFIG_RT2800USB) || defined(CONFIG_RT2800USB_MODULE)
+#if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE)
 #include "rt2x00usb.h"
 #endif
+#if defined(CONFIG_RT2X00_LIB_PCI) || defined(CONFIG_RT2X00_LIB_PCI_MODULE)
+#include "rt2x00pci.h"
+#endif
 #include "rt2800lib.h"
 #include "rt2800.h"
 #include "rt2800usb.h"
@@ -89,7 +93,7 @@ static void rt2800_bbp_write(struct rt2x
 		rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word);
 		rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1);
 		rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 0);
-		if (rt2x00_intf_is_pci(rt2x00dev))
+		if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev))
 			rt2x00_set_field32(&reg, BBP_CSR_CFG_BBP_RW_MODE, 1);
 
 		rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
@@ -118,7 +122,7 @@ static void rt2800_bbp_read(struct rt2x0
 		rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word);
 		rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1);
 		rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 1);
-		if (rt2x00_intf_is_pci(rt2x00dev))
+		if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev))
 			rt2x00_set_field32(&reg, BBP_CSR_CFG_BBP_RW_MODE, 1);
 
 		rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
@@ -218,10 +222,9 @@ void rt2800_mcu_request(struct rt2x00_de
 	u32 reg;
 
 	/*
-	 * RT2880 and RT3052 don't support MCU requests.
+	 * SOC devices don't support MCU requests.
 	 */
-	if (rt2x00_rt(&rt2x00dev->chip, RT2880) ||
-	    rt2x00_rt(&rt2x00dev->chip, RT3052))
+	if (rt2x00_is_soc(rt2x00dev))
 		return;
 
 	mutex_lock(&rt2x00dev->csr_mutex);
@@ -246,6 +249,25 @@ void rt2800_mcu_request(struct rt2x00_de
 }
 EXPORT_SYMBOL_GPL(rt2800_mcu_request);
 
+int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
+{
+	unsigned int i;
+	u32 reg;
+
+	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+		rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+		if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
+		    !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
+			return 0;
+
+		msleep(1);
+	}
+
+	ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
+	return -EACCES;
+}
+EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready);
+
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
 const struct rt2x00debug rt2800_rt2x00debug = {
 	.owner	= THIS_MODULE,
@@ -348,7 +370,7 @@ static int rt2800_blink_set(struct led_c
 	return 0;
 }
 
-void rt2800_init_led(struct rt2x00_dev *rt2x00dev,
+static void rt2800_init_led(struct rt2x00_dev *rt2x00dev,
 		     struct rt2x00_led *led, enum led_type type)
 {
 	led->rt2x00dev = rt2x00dev;
@@ -357,7 +379,6 @@ void rt2800_init_led(struct rt2x00_dev *
 	led->led_dev.blink_set = rt2800_blink_set;
 	led->flags = LED_INITIALIZED;
 }
-EXPORT_SYMBOL_GPL(rt2800_init_led);
 #endif /* CONFIG_RT2X00_LIB_LEDS */
 
 /*
@@ -643,7 +664,7 @@ void rt2800_config_ant(struct rt2x00_dev
 	switch ((int)ant->tx) {
 	case 1:
 		rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
-		if (rt2x00_intf_is_pci(rt2x00dev))
+		if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev))
 			rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
 		break;
 	case 2:
@@ -792,9 +813,9 @@ static void rt2800_config_channel_rt3x(s
 	rt2800_rfcsr_write(rt2x00dev, 24,
 			      rt2x00dev->calibration[conf_is_ht40(conf)]);
 
-	rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
+	rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
 	rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
-	rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
+	rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
 }
 
 static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
@@ -806,12 +827,12 @@ static void rt2800_config_channel(struct
 	unsigned int tx_pin;
 	u8 bbp;
 
-	if ((rt2x00_rt(&rt2x00dev->chip, RT3070) ||
-	     rt2x00_rt(&rt2x00dev->chip, RT3090)) &&
-	    (rt2x00_rf(&rt2x00dev->chip, RF2020) ||
-	     rt2x00_rf(&rt2x00dev->chip, RF3020) ||
-	     rt2x00_rf(&rt2x00dev->chip, RF3021) ||
-	     rt2x00_rf(&rt2x00dev->chip, RF3022)))
+	if ((rt2x00_rt(rt2x00dev, RT3070) ||
+	     rt2x00_rt(rt2x00dev, RT3090)) &&
+	    (rt2x00_rf(rt2x00dev, RF2020) ||
+	     rt2x00_rf(rt2x00dev, RF3020) ||
+	     rt2x00_rf(rt2x00dev, RF3021) ||
+	     rt2x00_rf(rt2x00dev, RF3022)))
 		rt2800_config_channel_rt3x(rt2x00dev, conf, rf, info);
 	else
 		rt2800_config_channel_rt2x(rt2x00dev, conf, rf, info);
@@ -878,7 +899,8 @@ static void rt2800_config_channel(struct
 	rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf));
 	rt2800_bbp_write(rt2x00dev, 3, bbp);
 
-	if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
+	if (rt2x00_rt(rt2x00dev, RT2860) &&
+	    (rt2x00_rev(rt2x00dev) == RT2860C_VERSION)) {
 		if (conf_is_ht40(conf)) {
 			rt2800_bbp_write(rt2x00dev, 69, 0x1a);
 			rt2800_bbp_write(rt2x00dev, 70, 0x0a);
@@ -1040,8 +1062,9 @@ EXPORT_SYMBOL_GPL(rt2800_link_stats);
 static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
 {
 	if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
-		if (rt2x00_intf_is_usb(rt2x00dev) &&
-		    rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION)
+		if (rt2x00_is_usb(rt2x00dev) &&
+		    rt2x00_rt(rt2x00dev, RT3070) &&
+		    (rt2x00_rev(rt2x00dev) == RT3070_VERSION))
 			return 0x1c + (2 * rt2x00dev->lna_gain);
 		else
 			return 0x2e + rt2x00dev->lna_gain;
@@ -1072,7 +1095,8 @@ EXPORT_SYMBOL_GPL(rt2800_reset_tuner);
 void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
 		       const u32 count)
 {
-	if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION)
+	if (rt2x00_rt(rt2x00dev, RT2860) &&
+	    (rt2x00_rev(rt2x00dev) == RT2860C_VERSION))
 		return;
 
 	/*
@@ -1092,7 +1116,7 @@ int rt2800_init_registers(struct rt2x00_
 	u32 reg;
 	unsigned int i;
 
-	if (rt2x00_intf_is_usb(rt2x00dev)) {
+	if (rt2x00_is_usb(rt2x00dev)) {
 		/*
 		 * Wait until BBP and RF are ready.
 		 */
@@ -1111,7 +1135,7 @@ int rt2800_init_registers(struct rt2x00_
 		rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
 		rt2800_register_write(rt2x00dev, PBF_SYS_CTRL,
 				      reg & ~0x00002000);
-	} else if (rt2x00_intf_is_pci(rt2x00dev))
+	} else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev))
 		rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
 
 	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
@@ -1119,9 +1143,9 @@ int rt2800_init_registers(struct rt2x00_
 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
 	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
 
-	if (rt2x00_intf_is_usb(rt2x00dev)) {
+	if (rt2x00_is_usb(rt2x00dev)) {
 		rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
-#if defined(CONFIG_RT2800USB) || defined(CONFIG_RT2800USB_MODULE)
+#if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE)
 		rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
 					    USB_MODE_RESET, REGISTER_TIMEOUT);
 #endif
@@ -1157,8 +1181,9 @@ int rt2800_init_registers(struct rt2x00_
 	rt2x00_set_field32(&reg, BCN_TIME_CFG_TX_TIME_COMPENSATE, 0);
 	rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
 
-	if (rt2x00_intf_is_usb(rt2x00dev) &&
-	    rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
+	if (rt2x00_is_usb(rt2x00dev) &&
+	    rt2x00_rt(rt2x00dev, RT3070) &&
+	    (rt2x00_rev(rt2x00dev) == RT3070_VERSION)) {
 		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
 		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
 		rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
@@ -1185,8 +1210,14 @@ int rt2800_init_registers(struct rt2x00_
 
 	rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
 	rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
-	if (rt2x00_rev(&rt2x00dev->chip) >= RT2880E_VERSION &&
-	    rt2x00_rev(&rt2x00dev->chip) < RT3070_VERSION)
+	if ((rt2x00_rt(rt2x00dev, RT2872) &&
+	     (rt2x00_rev(rt2x00dev) >= RT2880E_VERSION)) ||
+	    rt2x00_rt(rt2x00dev, RT2880) ||
+	    rt2x00_rt(rt2x00dev, RT2883) ||
+	    rt2x00_rt(rt2x00dev, RT2890) ||
+	    rt2x00_rt(rt2x00dev, RT3052) ||
+	    (rt2x00_rt(rt2x00dev, RT3070) &&
+	     (rt2x00_rev(rt2x00dev) < RT3070_VERSION)))
 		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
 	else
 		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
@@ -1276,7 +1307,7 @@ int rt2800_init_registers(struct rt2x00_
 	rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
 	rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg);
 
-	if (rt2x00_intf_is_usb(rt2x00dev)) {
+	if (rt2x00_is_usb(rt2x00dev)) {
 		rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
 
 		rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
@@ -1336,7 +1367,7 @@ int rt2800_init_registers(struct rt2x00_
 	rt2800_register_write(rt2x00dev, HW_BEACON_BASE6, 0);
 	rt2800_register_write(rt2x00dev, HW_BEACON_BASE7, 0);
 
-	if (rt2x00_intf_is_usb(rt2x00dev)) {
+	if (rt2x00_is_usb(rt2x00dev)) {
 		rt2800_register_read(rt2x00dev, USB_CYC_CFG, &reg);
 		rt2x00_set_field32(&reg, USB_CYC_CFG_CLOCK_CYCLE, 30);
 		rt2800_register_write(rt2x00dev, USB_CYC_CFG, reg);
@@ -1465,22 +1496,25 @@ int rt2800_init_bbp(struct rt2x00_dev *r
 	rt2800_bbp_write(rt2x00dev, 103, 0x00);
 	rt2800_bbp_write(rt2x00dev, 105, 0x05);
 
-	if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
+	if (rt2x00_rt(rt2x00dev, RT2860) &&
+	    (rt2x00_rev(rt2x00dev) == RT2860C_VERSION)) {
 		rt2800_bbp_write(rt2x00dev, 69, 0x16);
 		rt2800_bbp_write(rt2x00dev, 73, 0x12);
 	}
 
-	if (rt2x00_rev(&rt2x00dev->chip) > RT2860D_VERSION)
+	if (rt2x00_rt(rt2x00dev, RT2860) &&
+	    (rt2x00_rev(rt2x00dev) > RT2860D_VERSION))
 		rt2800_bbp_write(rt2x00dev, 84, 0x19);
 
-	if (rt2x00_intf_is_usb(rt2x00dev) &&
-	    rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
+	if (rt2x00_is_usb(rt2x00dev) &&
+	    rt2x00_rt(rt2x00dev, RT3070) &&
+	    (rt2x00_rev(rt2x00dev) == RT3070_VERSION)) {
 		rt2800_bbp_write(rt2x00dev, 70, 0x0a);
 		rt2800_bbp_write(rt2x00dev, 84, 0x99);
 		rt2800_bbp_write(rt2x00dev, 105, 0x05);
 	}
 
-	if (rt2x00_rt(&rt2x00dev->chip, RT3052)) {
+	if (rt2x00_rt(rt2x00dev, RT3052)) {
 		rt2800_bbp_write(rt2x00dev, 31, 0x08);
 		rt2800_bbp_write(rt2x00dev, 78, 0x0e);
 		rt2800_bbp_write(rt2x00dev, 80, 0x08);
@@ -1565,14 +1599,15 @@ int rt2800_init_rfcsr(struct rt2x00_dev
 	u8 rfcsr;
 	u8 bbp;
 
-	if (rt2x00_intf_is_usb(rt2x00dev) &&
-	    rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION)
+	if (rt2x00_is_usb(rt2x00dev) &&
+	    rt2x00_rt(rt2x00dev, RT3070) &&
+	    (rt2x00_rev(rt2x00dev) != RT3070_VERSION))
 		return 0;
 
-	if (rt2x00_intf_is_pci(rt2x00dev)) {
-		if (!rt2x00_rf(&rt2x00dev->chip, RF3020) &&
-		    !rt2x00_rf(&rt2x00dev->chip, RF3021) &&
-		    !rt2x00_rf(&rt2x00dev->chip, RF3022))
+	if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
+		if (!rt2x00_rf(rt2x00dev, RF3020) &&
+		    !rt2x00_rf(rt2x00dev, RF3021) &&
+		    !rt2x00_rf(rt2x00dev, RF3022))
 			return 0;
 	}
 
@@ -1586,7 +1621,7 @@ int rt2800_init_rfcsr(struct rt2x00_dev
 	rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
 	rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
 
-	if (rt2x00_intf_is_usb(rt2x00dev)) {
+	if (rt2x00_is_usb(rt2x00dev)) {
 		rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
 		rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
 		rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
@@ -1607,7 +1642,7 @@ int rt2800_init_rfcsr(struct rt2x00_dev
 		rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
 		rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
 		rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
-	} else if (rt2x00_intf_is_pci(rt2x00dev)) {
+	} else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
 		rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
 		rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
 		rt2800_rfcsr_write(rt2x00dev, 2, 0xf7);
@@ -1737,7 +1772,12 @@ int rt2800_validate_eeprom(struct rt2x00
 		rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820);
 		rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
 		EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
-	} else if (rt2x00_rev(&rt2x00dev->chip) < RT2883_VERSION) {
+	} else if (rt2x00_rt(rt2x00dev, RT2860) ||
+		   rt2x00_rt(rt2x00dev, RT2870) ||
+		   rt2x00_rt(rt2x00dev, RT2872) ||
+		   rt2x00_rt(rt2x00dev, RT2880) ||
+		   (rt2x00_rt(rt2x00dev, RT2883) &&
+		    (rt2x00_rev(rt2x00dev) < RT2883_VERSION))) {
 		/*
 		 * There is a max of 2 RX streams for RT28x0 series
 		 */
@@ -1836,36 +1876,34 @@ int rt2800_init_eeprom(struct rt2x00_dev
 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
 	rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
 
-	rt2x00_set_chip_rf(rt2x00dev, value, reg);
-
-	if (rt2x00_intf_is_usb(rt2x00dev)) {
-		struct rt2x00_chip *chip = &rt2x00dev->chip;
+	rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET),
+			value, rt2x00_get_field32(reg, MAC_CSR0_REVISION));
 
-		/*
-		 * The check for rt2860 is not a typo, some rt2870 hardware
-		 * identifies itself as rt2860 in the CSR register.
-		 */
-		if (rt2x00_check_rev(chip, 0xfff00000, 0x28600000) ||
-		    rt2x00_check_rev(chip, 0xfff00000, 0x28700000) ||
-		    rt2x00_check_rev(chip, 0xfff00000, 0x28800000)) {
-			rt2x00_set_chip_rt(rt2x00dev, RT2870);
-		} else if (rt2x00_check_rev(chip, 0xffff0000, 0x30700000)) {
-			rt2x00_set_chip_rt(rt2x00dev, RT3070);
-		} else {
-			ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
-			return -ENODEV;
-		}
+	if (!rt2x00_rt(rt2x00dev, RT2860) &&
+	    !rt2x00_rt(rt2x00dev, RT2870) &&
+	    !rt2x00_rt(rt2x00dev, RT2872) &&
+	    !rt2x00_rt(rt2x00dev, RT2880) &&
+	    !rt2x00_rt(rt2x00dev, RT2883) &&
+	    !rt2x00_rt(rt2x00dev, RT2890) &&
+	    !rt2x00_rt(rt2x00dev, RT3052) &&
+	    !rt2x00_rt(rt2x00dev, RT3070) &&
+	    !rt2x00_rt(rt2x00dev, RT3071) &&
+	    !rt2x00_rt(rt2x00dev, RT3090) &&
+	    !rt2x00_rt(rt2x00dev, RT3390) &&
+	    !rt2x00_rt(rt2x00dev, RT3572)) {
+		ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
+		return -ENODEV;
 	}
-	rt2x00_print_chip(rt2x00dev);
 
-	if (!rt2x00_rf(&rt2x00dev->chip, RF2820) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2850) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2720) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2750) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF3020) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2020) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF3021) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF3022)) {
+	if (!rt2x00_rf(rt2x00dev, RF2820) &&
+	    !rt2x00_rf(rt2x00dev, RF2850) &&
+	    !rt2x00_rf(rt2x00dev, RF2720) &&
+	    !rt2x00_rf(rt2x00dev, RF2750) &&
+	    !rt2x00_rf(rt2x00dev, RF3020) &&
+	    !rt2x00_rf(rt2x00dev, RF2020) &&
+	    !rt2x00_rf(rt2x00dev, RF3021) &&
+	    !rt2x00_rf(rt2x00dev, RF3022) &&
+	    !rt2x00_rf(rt2x00dev, RF3052)) {
 		ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
 		return -ENODEV;
 	}
@@ -2013,7 +2051,6 @@ static const struct rf_channel rf_vals_3
 
 int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 {
-	struct rt2x00_chip *chip = &rt2x00dev->chip;
 	struct hw_mode_spec *spec = &rt2x00dev->spec;
 	struct channel_info *info;
 	char *tx_power1;
@@ -2024,7 +2061,7 @@ int rt2800_probe_hw_mode(struct rt2x00_d
 	/*
 	 * Disable powersaving as default on PCI devices.
 	 */
-	if (rt2x00_intf_is_pci(rt2x00dev))
+	if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev))
 		rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 
 	/*
@@ -2049,19 +2086,19 @@ int rt2800_probe_hw_mode(struct rt2x00_d
 	spec->supported_bands = SUPPORT_BAND_2GHZ;
 	spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
 
-	if (rt2x00_rf(chip, RF2820) ||
-	    rt2x00_rf(chip, RF2720) ||
-	    (rt2x00_intf_is_pci(rt2x00dev) && rt2x00_rf(chip, RF3052))) {
+	if (rt2x00_rf(rt2x00dev, RF2820) ||
+	    rt2x00_rf(rt2x00dev, RF2720) ||
+	    rt2x00_rf(rt2x00dev, RF3052)) {
 		spec->num_channels = 14;
 		spec->channels = rf_vals;
-	} else if (rt2x00_rf(chip, RF2850) || rt2x00_rf(chip, RF2750)) {
+	} else if (rt2x00_rf(rt2x00dev, RF2850) || rt2x00_rf(rt2x00dev, RF2750)) {
 		spec->supported_bands |= SUPPORT_BAND_5GHZ;
 		spec->num_channels = ARRAY_SIZE(rf_vals);
 		spec->channels = rf_vals;
-	} else if (rt2x00_rf(chip, RF3020) ||
-		   rt2x00_rf(chip, RF2020) ||
-		   rt2x00_rf(chip, RF3021) ||
-		   rt2x00_rf(chip, RF3022)) {
+	} else if (rt2x00_rf(rt2x00dev, RF3020) ||
+		   rt2x00_rf(rt2x00dev, RF2020) ||
+		   rt2x00_rf(rt2x00dev, RF3021) ||
+		   rt2x00_rf(rt2x00dev, RF3022)) {
 		spec->num_channels = ARRAY_SIZE(rf_vals_302x);
 		spec->channels = rf_vals_302x;
 	}
@@ -2069,7 +2106,7 @@ int rt2800_probe_hw_mode(struct rt2x00_d
 	/*
 	 * Initialize HT information.
 	 */
-	if (!rt2x00_rf(chip, RF2020))
+	if (!rt2x00_rf(rt2x00dev, RF2020))
 		spec->ht.ht_supported = true;
 	else
 		spec->ht.ht_supported = false;
@@ -2282,7 +2319,6 @@ const struct ieee80211_ops rt2800_mac802
 	.set_rts_threshold	= rt2800_set_rts_threshold,
 	.bss_info_changed	= rt2x00mac_bss_info_changed,
 	.conf_tx		= rt2800_conf_tx,
-	.get_tx_stats		= rt2x00mac_get_tx_stats,
 	.get_tsf		= rt2800_get_tsf,
 	.rfkill_poll		= rt2x00mac_rfkill_poll,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800lib.h linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2800lib.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800lib.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2800lib.h	2010-05-16 17:17:36.000000000 -0400
@@ -114,8 +114,6 @@ void rt2800_mcu_request(struct rt2x00_de
 extern const struct rt2x00debug rt2800_rt2x00debug;
 
 int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev);
-void rt2800_init_led(struct rt2x00_dev *rt2x00dev,
-		     struct rt2x00_led *led, enum led_type type);
 int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
 			     struct rt2x00lib_crypto *crypto,
 			     struct ieee80211_key_conf *key);
@@ -139,6 +137,7 @@ void rt2800_link_tuner(struct rt2x00_dev
 int rt2800_init_registers(struct rt2x00_dev *rt2x00dev);
 int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev);
 int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev);
+int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev);
 
 int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev);
 void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800pci.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2800pci.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800pci.c	2013-05-03 12:11:15.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2800pci.c	2013-05-03 09:50:46.000000000 -0400
@@ -48,14 +48,6 @@
 #include "rt2800.h"
 #include "rt2800pci.h"
 
-#ifdef CONFIG_RT2800PCI_PCI_MODULE
-#define CONFIG_RT2800PCI_PCI
-#endif
-
-#ifdef CONFIG_RT2800PCI_WISOC_MODULE
-#define CONFIG_RT2800PCI_WISOC
-#endif
-
 /*
  * Allow hardware encryption to be disabled.
  */
@@ -87,7 +79,7 @@ static void rt2800pci_mcu_status(struct
 	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
 }
 
-#ifdef CONFIG_RT2800PCI_WISOC
+#ifdef CONFIG_RT2800PCI_SOC
 static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
 {
 	u32 *base_addr = (u32 *) KSEG1ADDR(0x1F040000); /* XXX for RT3052 */
@@ -98,7 +90,7 @@ static void rt2800pci_read_eeprom_soc(st
 static inline void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
 {
 }
-#endif /* CONFIG_RT2800PCI_WISOC */
+#endif /* CONFIG_RT2800PCI_SOC */
 
 #ifdef CONFIG_RT2800PCI_PCI
 static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
@@ -461,24 +453,6 @@ static void rt2800pci_toggle_irq(struct
 	rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
 }
 
-static int rt2800pci_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
-{
-	unsigned int i;
-	u32 reg;
-
-	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-		rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
-		if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
-		    !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
-			return 0;
-
-		msleep(1);
-	}
-
-	ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
-	return -EACCES;
-}
-
 static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
 {
 	u32 reg;
@@ -487,10 +461,10 @@ static int rt2800pci_enable_radio(struct
 	/*
 	 * Initialize all registers.
 	 */
-	if (unlikely(rt2800pci_wait_wpdma_ready(rt2x00dev) ||
+	if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) ||
 		     rt2800pci_init_queues(rt2x00dev) ||
 		     rt2800_init_registers(rt2x00dev) ||
-		     rt2800pci_wait_wpdma_ready(rt2x00dev) ||
+		     rt2800_wait_wpdma_ready(rt2x00dev) ||
 		     rt2800_init_bbp(rt2x00dev) ||
 		     rt2800_init_rfcsr(rt2x00dev)))
 		return -EIO;
@@ -570,7 +544,7 @@ static void rt2800pci_disable_radio(stru
 	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
 
 	/* Wait for DMA, ignore error */
-	rt2800pci_wait_wpdma_ready(rt2x00dev);
+	rt2800_wait_wpdma_ready(rt2x00dev);
 }
 
 static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
@@ -835,7 +809,6 @@ static void rt2800pci_fill_rxdone(struct
 				  struct rxdone_entry_desc *rxdesc)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
-	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
 	struct queue_entry_priv_pci *entry_priv = entry->priv_data;
 	__le32 *rxd = entry_priv->desc;
 	__le32 *rxwi = (__le32 *)entry->skb->data;
@@ -883,10 +856,8 @@ static void rt2800pci_fill_rxdone(struct
 	if (rt2x00_get_field32(rxd3, RXD_W3_MY_BSS))
 		rxdesc->dev_flags |= RXDONE_MY_BSS;
 
-	if (rt2x00_get_field32(rxd3, RXD_W3_L2PAD)) {
+	if (rt2x00_get_field32(rxd3, RXD_W3_L2PAD))
 		rxdesc->dev_flags |= RXDONE_L2PAD;
-		skbdesc->flags |= SKBDESC_L2_PADDED;
-	}
 
 	if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
 		rxdesc->flags |= RX_FLAG_SHORT_GI;
@@ -927,7 +898,6 @@ static void rt2800pci_fill_rxdone(struct
 	 * Remove TXWI descriptor from start of buffer.
 	 */
 	skb_pull(entry->skb, RXWI_DESC_SIZE);
-	skb_trim(entry->skb, rxdesc->size);
 }
 
 /*
@@ -1071,18 +1041,12 @@ static int rt2800pci_validate_eeprom(str
 	/*
 	 * Read EEPROM into buffer
 	 */
-	switch (rt2x00dev->chip.rt) {
-	case RT2880:
-	case RT3052:
+	if (rt2x00_is_soc(rt2x00dev))
 		rt2800pci_read_eeprom_soc(rt2x00dev);
-		break;
-	default:
-		if (rt2800pci_efuse_detect(rt2x00dev))
-			rt2800pci_read_eeprom_efuse(rt2x00dev);
-		else
-			rt2800pci_read_eeprom_pci(rt2x00dev);
-		break;
-	}
+	else if (rt2800pci_efuse_detect(rt2x00dev))
+		rt2800pci_read_eeprom_efuse(rt2x00dev);
+	else
+		rt2800pci_read_eeprom_pci(rt2x00dev);
 
 	return rt2800_validate_eeprom(rt2x00dev);
 }
@@ -1133,8 +1097,7 @@ static int rt2800pci_probe_hw(struct rt2
 	/*
 	 * This device requires firmware.
 	 */
-	if (!rt2x00_rt(&rt2x00dev->chip, RT2880) &&
-	    !rt2x00_rt(&rt2x00dev->chip, RT3052))
+	if (!rt2x00_is_soc(rt2x00dev))
 		__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
 	__set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
 	__set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
@@ -1221,8 +1184,11 @@ static const struct rt2x00_ops rt2800pci
 /*
  * RT2800pci module information.
  */
-static struct pci_device_id rt2800pci_device_table[] = {
-	{ PCI_DEVICE(0x1462, 0x891a), PCI_DEVICE_DATA(&rt2800pci_ops) },
+static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
+	{ PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x0701), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x0781), PCI_DEVICE_DATA(&rt2800pci_ops) },
 	{ PCI_DEVICE(0x1432, 0x7708), PCI_DEVICE_DATA(&rt2800pci_ops) },
 	{ PCI_DEVICE(0x1432, 0x7727), PCI_DEVICE_DATA(&rt2800pci_ops) },
 	{ PCI_DEVICE(0x1432, 0x7728), PCI_DEVICE_DATA(&rt2800pci_ops) },
@@ -1230,18 +1196,19 @@ static struct pci_device_id rt2800pci_de
 	{ PCI_DEVICE(0x1432, 0x7748), PCI_DEVICE_DATA(&rt2800pci_ops) },
 	{ PCI_DEVICE(0x1432, 0x7758), PCI_DEVICE_DATA(&rt2800pci_ops) },
 	{ PCI_DEVICE(0x1432, 0x7768), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1814, 0x0701), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1814, 0x0781), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) },
+#ifdef CONFIG_RT2800PCI_RT30XX
 	{ PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) },
 	{ PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) },
 	{ PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1462, 0x891a), PCI_DEVICE_DATA(&rt2800pci_ops) },
+#endif
+#ifdef CONFIG_RT2800PCI_RT35XX
+	{ PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) },
 	{ PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) },
 	{ PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) },
+#endif
 	{ 0, }
 };
 
@@ -1255,12 +1222,11 @@ MODULE_DEVICE_TABLE(pci, rt2800pci_devic
 #endif /* CONFIG_RT2800PCI_PCI */
 MODULE_LICENSE("GPL");
 
-#ifdef CONFIG_RT2800PCI_WISOC
-#if defined(CONFIG_RALINK_RT288X)
-__rt2x00soc_probe(RT2880, &rt2800pci_ops);
-#elif defined(CONFIG_RALINK_RT305X)
-__rt2x00soc_probe(RT3052, &rt2800pci_ops);
-#endif
+#ifdef CONFIG_RT2800PCI_SOC
+static int rt2800soc_probe(struct platform_device *pdev)
+{
+	return rt2x00soc_probe(pdev, &rt2800pci_ops);
+}
 
 static struct platform_driver rt2800soc_driver = {
 	.driver		= {
@@ -1268,12 +1234,12 @@ static struct platform_driver rt2800soc_
 		.owner		= THIS_MODULE,
 		.mod_name	= KBUILD_MODNAME,
 	},
-	.probe		= __rt2x00soc_probe,
+	.probe		= rt2800soc_probe,
 	.remove		= __devexit_p(rt2x00soc_remove),
 	.suspend	= rt2x00soc_suspend,
 	.resume		= rt2x00soc_resume,
 };
-#endif /* CONFIG_RT2800PCI_WISOC */
+#endif /* CONFIG_RT2800PCI_SOC */
 
 #ifdef CONFIG_RT2800PCI_PCI
 static struct pci_driver rt2800pci_driver = {
@@ -1290,7 +1256,7 @@ static int __init rt2800pci_init(void)
 {
 	int ret = 0;
 
-#ifdef CONFIG_RT2800PCI_WISOC
+#ifdef CONFIG_RT2800PCI_SOC
 	ret = platform_driver_register(&rt2800soc_driver);
 	if (ret)
 		return ret;
@@ -1298,7 +1264,7 @@ static int __init rt2800pci_init(void)
 #ifdef CONFIG_RT2800PCI_PCI
 	ret = pci_register_driver(&rt2800pci_driver);
 	if (ret) {
-#ifdef CONFIG_RT2800PCI_WISOC
+#ifdef CONFIG_RT2800PCI_SOC
 		platform_driver_unregister(&rt2800soc_driver);
 #endif
 		return ret;
@@ -1313,7 +1279,7 @@ static void __exit rt2800pci_exit(void)
 #ifdef CONFIG_RT2800PCI_PCI
 	pci_unregister_driver(&rt2800pci_driver);
 #endif
-#ifdef CONFIG_RT2800PCI_WISOC
+#ifdef CONFIG_RT2800PCI_SOC
 	platform_driver_unregister(&rt2800soc_driver);
 #endif
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800usb.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2800usb.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800usb.c	2013-05-03 12:11:19.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2800usb.c	2013-05-03 09:50:50.000000000 -0400
@@ -92,7 +92,6 @@ static bool rt2800usb_check_crc(const u8
 static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev,
 				    const u8 *data, const size_t len)
 {
-	u16 chipset = (rt2x00_rev(&rt2x00dev->chip) >> 16) & 0xffff;
 	size_t offset = 0;
 
 	/*
@@ -100,7 +99,7 @@ static int rt2800usb_check_firmware(stru
 	 * There are 2 variations of the rt2870 firmware.
 	 * a) size: 4kb
 	 * b) size: 8kb
-	 * Note that (b) contains 2 seperate firmware blobs of 4k
+	 * Note that (b) contains 2 separate firmware blobs of 4k
 	 * within the file. The first blob is the same firmware as (a),
 	 * but the second blob is for the additional chipsets.
 	 */
@@ -111,14 +110,14 @@ static int rt2800usb_check_firmware(stru
 	 * Check if we need the upper 4kb firmware data or not.
 	 */
 	if ((len == 4096) &&
-	    (chipset != 0x2860) &&
-	    (chipset != 0x2872) &&
-	    (chipset != 0x3070))
+	    !rt2x00_rt(rt2x00dev, RT2860) &&
+	    !rt2x00_rt(rt2x00dev, RT2872) &&
+	    !rt2x00_rt(rt2x00dev, RT3070))
 		return FW_BAD_VERSION;
 
 	/*
 	 * 8kb firmware files must be checked as if it were
-	 * 2 seperate firmware files.
+	 * 2 separate firmware files.
 	 */
 	while (offset < len) {
 		if (!rt2800usb_check_crc(data + offset, 4096))
@@ -138,14 +137,13 @@ static int rt2800usb_load_firmware(struc
 	u32 reg;
 	u32 offset;
 	u32 length;
-	u16 chipset = (rt2x00_rev(&rt2x00dev->chip) >> 16) & 0xffff;
 
 	/*
 	 * Check which section of the firmware we need.
 	 */
-	if ((chipset == 0x2860) ||
-	    (chipset == 0x2872) ||
-	    (chipset == 0x3070)) {
+	if (rt2x00_rt(rt2x00dev, RT2860) ||
+	    rt2x00_rt(rt2x00dev, RT2872) ||
+	    rt2x00_rt(rt2x00dev, RT3070)) {
 		offset = 0;
 		length = 4096;
 	} else {
@@ -200,9 +198,9 @@ static int rt2800usb_load_firmware(struc
 	 */
 	rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0);
 
-	if ((chipset == 0x3070) ||
-	    (chipset == 0x3071) ||
-	    (chipset == 0x3572)) {
+	if (rt2x00_rt(rt2x00dev, RT3070) ||
+	    rt2x00_rt(rt2x00dev, RT3071) ||
+	    rt2x00_rt(rt2x00dev, RT3572)) {
 		udelay(200);
 		rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0);
 		udelay(10);
@@ -248,24 +246,6 @@ static void rt2800usb_toggle_rx(struct r
 	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
 }
 
-static int rt2800usb_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
-{
-	unsigned int i;
-	u32 reg;
-
-	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-		rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
-		if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
-		    !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
-			return 0;
-
-		msleep(1);
-	}
-
-	ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
-	return -EACCES;
-}
-
 static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
 {
 	u32 reg;
@@ -274,7 +254,7 @@ static int rt2800usb_enable_radio(struct
 	/*
 	 * Initialize all registers.
 	 */
-	if (unlikely(rt2800usb_wait_wpdma_ready(rt2x00dev) ||
+	if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) ||
 		     rt2800_init_registers(rt2x00dev) ||
 		     rt2800_init_bbp(rt2x00dev) ||
 		     rt2800_init_rfcsr(rt2x00dev)))
@@ -295,9 +275,7 @@ static int rt2800usb_enable_radio(struct
 
 	rt2800_register_read(rt2x00dev, USB_DMA_CFG, &reg);
 	rt2x00_set_field32(&reg, USB_DMA_CFG_PHY_CLEAR, 0);
-	/* Don't use bulk in aggregation when working with USB 1.1 */
-	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN,
-			   (rt2x00dev->rx->usb_maxpacket == 512));
+	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN, 0);
 	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128);
 	/*
 	 * Total room for RX frames in kilobytes, PBF might still exceed
@@ -346,7 +324,7 @@ static void rt2800usb_disable_radio(stru
 	rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0);
 
 	/* Wait for DMA, ignore error */
-	rt2800usb_wait_wpdma_ready(rt2x00dev);
+	rt2800_wait_wpdma_ready(rt2x00dev);
 
 	rt2x00usb_disable_radio(rt2x00dev);
 }
@@ -573,41 +551,57 @@ static void rt2800usb_fill_rxdone(struct
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
-	__le32 *rxd = (__le32 *)entry->skb->data;
+	__le32 *rxi = (__le32 *)entry->skb->data;
 	__le32 *rxwi;
-	u32 rxd0;
+	__le32 *rxd;
+	u32 rxi0;
 	u32 rxwi0;
 	u32 rxwi1;
 	u32 rxwi2;
 	u32 rxwi3;
+	u32 rxd0;
+	int rx_pkt_len;
+
+	/*
+	 * RX frame format is :
+	 * | RXINFO | RXWI | header | L2 pad | payload | pad | RXD | USB pad |
+	 *          |<------------ rx_pkt_len -------------->|
+	 */
+	rt2x00_desc_read(rxi, 0, &rxi0);
+	rx_pkt_len = rt2x00_get_field32(rxi0, RXINFO_W0_USB_DMA_RX_PKT_LEN);
+
+	rxwi = (__le32 *)(entry->skb->data + RXINFO_DESC_SIZE);
+
+	/*
+	 * FIXME : we need to check for rx_pkt_len validity
+	 */
+	rxd = (__le32 *)(entry->skb->data + RXINFO_DESC_SIZE + rx_pkt_len);
 
 	/*
 	 * Copy descriptor to the skbdesc->desc buffer, making it safe from
 	 * moving of frame data in rt2x00usb.
 	 */
-	memcpy(skbdesc->desc, rxd, skbdesc->desc_len);
-	rxd = (__le32 *)skbdesc->desc;
-	rxwi = &rxd[RXINFO_DESC_SIZE / sizeof(__le32)];
+	memcpy(skbdesc->desc, rxi, skbdesc->desc_len);
 
 	/*
 	 * It is now safe to read the descriptor on all architectures.
 	 */
-	rt2x00_desc_read(rxd, 0, &rxd0);
 	rt2x00_desc_read(rxwi, 0, &rxwi0);
 	rt2x00_desc_read(rxwi, 1, &rxwi1);
 	rt2x00_desc_read(rxwi, 2, &rxwi2);
 	rt2x00_desc_read(rxwi, 3, &rxwi3);
+	rt2x00_desc_read(rxd, 0, &rxd0);
 
-	if (rt2x00_get_field32(rxd0, RXINFO_W0_CRC_ERROR))
+	if (rt2x00_get_field32(rxd0, RXD_W0_CRC_ERROR))
 		rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
 
 	if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
 		rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
 		rxdesc->cipher_status =
-		    rt2x00_get_field32(rxd0, RXINFO_W0_CIPHER_ERROR);
+		    rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR);
 	}
 
-	if (rt2x00_get_field32(rxd0, RXINFO_W0_DECRYPTED)) {
+	if (rt2x00_get_field32(rxd0, RXD_W0_DECRYPTED)) {
 		/*
 		 * Hardware has stripped IV/EIV data from 802.11 frame during
 		 * decryption. Unfortunately the descriptor doesn't contain
@@ -622,13 +616,11 @@ static void rt2800usb_fill_rxdone(struct
 			rxdesc->flags |= RX_FLAG_MMIC_ERROR;
 	}
 
-	if (rt2x00_get_field32(rxd0, RXINFO_W0_MY_BSS))
+	if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS))
 		rxdesc->dev_flags |= RXDONE_MY_BSS;
 
-	if (rt2x00_get_field32(rxd0, RXINFO_W0_L2PAD)) {
+	if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD))
 		rxdesc->dev_flags |= RXDONE_L2PAD;
-		skbdesc->flags |= SKBDESC_L2_PADDED;
-	}
 
 	if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
 		rxdesc->flags |= RX_FLAG_SHORT_GI;
@@ -663,7 +655,6 @@ static void rt2800usb_fill_rxdone(struct
 	 * Remove RXWI descriptor from start of buffer.
 	 */
 	skb_pull(entry->skb, skbdesc->desc_len);
-	skb_trim(entry->skb, rxdesc->size);
 }
 
 /*
@@ -814,51 +805,27 @@ static struct usb_device_id rt2800usb_de
 	/* Abocom */
 	{ USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
-	/* AirTies */
-	{ USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
-	/* Amigo */
-	{ USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Amit */
 	{ USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Askey */
 	{ USB_DEVICE(0x1690, 0x0740), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1690, 0x0744), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* ASUS */
 	{ USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* AzureWave */
 	{ USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Belkin */
 	{ USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x050d, 0x815c), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Buffalo */
 	{ USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0411, 0x012e), USB_DEVICE_DATA(&rt2800usb_ops) },
-	/* Cisco */
-	{ USB_DEVICE(0x167b, 0x4001), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Conceptronic */
 	{ USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -867,157 +834,257 @@ static struct usb_device_id rt2800usb_de
 	{ USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x07aa, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x07aa, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x18c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* D-Link */
 	{ USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Edimax */
+	{ USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* EnGenius */
+	{ USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Gigabyte */
+	{ USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Hawking */
+	{ USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Linksys */
+	{ USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Logitec */
+	{ USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Motorola */
+	{ USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* MSI */
+	{ USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Philips */
+	{ USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Planex */
+	{ USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Ralink */
+	{ USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Samsung */
+	{ USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Siemens */
+	{ USB_DEVICE(0x129b, 0x1828), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Sitecom */
+	{ USB_DEVICE(0x0df6, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0df6, 0x002b), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0df6, 0x002c), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0df6, 0x002d), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* SMC */
+	{ USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Sparklan */
+	{ USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Sweex */
+	{ USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* U-Media*/
+	{ USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* ZCOM */
+	{ USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Zinwell */
+	{ USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Zyxel */
+	{ USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
+#ifdef CONFIG_RT2800USB_RT30XX
+	/* Abocom */
+	{ USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* AirTies */
+	{ USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* AzureWave */
+	{ USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Conceptronic */
+	{ USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Corega */
+	{ USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* D-Link */
 	{ USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Edimax */
 	{ USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Encore */
 	{ USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* EnGenius */
-	{ USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Gigabyte */
+	{ USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* I-O DATA */
+	{ USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* MSI */
+	{ USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Pegatron */
+	{ USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Planex */
+	{ USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Quanta */
+	{ USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Ralink */
+	{ USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Sitecom */
+	{ USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* SMC */
+	{ USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Zinwell */
+	{ USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
+#endif
+#ifdef CONFIG_RT2800USB_RT35XX
+	/* Askey */
+	{ USB_DEVICE(0x1690, 0x0744), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Cisco */
+	{ USB_DEVICE(0x167b, 0x4001), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* EnGenius */
+	{ USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* I-O DATA */
+	{ USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Ralink */
+	{ USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Sitecom */
+	{ USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Zinwell */
+	{ USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) },
+#endif
+#ifdef CONFIG_RT2800USB_UNKNOWN
+	/*
+	 * Unclear what kind of devices these are (they aren't supported by the
+	 * vendor driver).
+	 */
+	/* Allwin */
+	{ USB_DEVICE(0x8516, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x8516, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x8516, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x8516, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Amigo */
+	{ USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Askey */
+	{ USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* ASUS */
+	{ USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0b05, 0x1790), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1761, 0x0b05), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* AzureWave */
+	{ USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Belkin */
+	{ USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Buffalo */
+	{ USB_DEVICE(0x0411, 0x012e), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0411, 0x0148), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0411, 0x0150), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0411, 0x015d), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Conceptronic */
+	{ USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Corega */
+	{ USB_DEVICE(0x07aa, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x07aa, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x18c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* D-Link */
+	{ USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Encore */
+	{ USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* EnGenius */
 	{ USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Gemtek */
 	{ USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Gigabyte */
-	{ USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1044, 0x800c), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Hawking */
-	{ USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* I-O DATA */
-	{ USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* LevelOne */
 	{ USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Linksys */
-	{ USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1737, 0x0078), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) },
-	/* Logitec */
-	{ USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Motorola */
-	{ USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* MSI */
-	{ USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0db0, 0x871a), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Ovislink */
 	{ USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Para */
 	{ USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Pegatron */
+	{ USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
-	/* Philips */
-	{ USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1d4d, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Planex */
-	{ USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Qcom */
 	{ USB_DEVICE(0x18e8, 0x6259), USB_DEVICE_DATA(&rt2800usb_ops) },
-	/* Quanta */
-	{ USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
-	/* Ralink */
-	{ USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
-	/* Samsung */
-	{ USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) },
-	/* Siemens */
-	{ USB_DEVICE(0x129b, 0x1828), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Sitecom */
-	{ USB_DEVICE(0x0df6, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0df6, 0x002b), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0df6, 0x002c), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0df6, 0x002d), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0df6, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0df6, 0x004a), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0df6, 0x004d), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* SMC */
-	{ USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) },
-	/* Sparklan */
-	{ USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x083a, 0xd522), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Sweex */
 	{ USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) },
-	/* U-Media*/
-	{ USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) },
-	/* ZCOM */
-	{ USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) },
-	/* Zinwell */
-	{ USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Zyxel */
-	{ USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) },
+#endif
 	{ 0, }
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800usb.h linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2800usb.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800usb.h	2013-05-03 12:11:16.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2800usb.h	2013-05-03 09:50:48.000000000 -0400
@@ -79,6 +79,8 @@
  */
 #define TXINFO_DESC_SIZE		( 1 * sizeof(__le32) )
 #define RXINFO_DESC_SIZE		( 1 * sizeof(__le32) )
+#define RXWI_DESC_SIZE			( 4 * sizeof(__le32) )
+#define RXD_DESC_SIZE			( 1 * sizeof(__le32) )
 
 /*
  * TX Info structure
@@ -101,6 +103,54 @@
 #define TXINFO_W0_USB_DMA_TX_BURST	FIELD32(0x80000000)
 
 /*
+ * RX Info structure
+ */
+
+/*
+ * Word 0
+ */
+
+#define RXINFO_W0_USB_DMA_RX_PKT_LEN	FIELD32(0x0000ffff)
+
+/*
+ * RX WI structure
+ */
+
+/*
+ * Word0
+ */
+#define RXWI_W0_WIRELESS_CLI_ID		FIELD32(0x000000ff)
+#define RXWI_W0_KEY_INDEX		FIELD32(0x00000300)
+#define RXWI_W0_BSSID			FIELD32(0x00001c00)
+#define RXWI_W0_UDF			FIELD32(0x0000e000)
+#define RXWI_W0_MPDU_TOTAL_BYTE_COUNT	FIELD32(0x0fff0000)
+#define RXWI_W0_TID			FIELD32(0xf0000000)
+
+/*
+ * Word1
+ */
+#define RXWI_W1_FRAG			FIELD32(0x0000000f)
+#define RXWI_W1_SEQUENCE		FIELD32(0x0000fff0)
+#define RXWI_W1_MCS			FIELD32(0x007f0000)
+#define RXWI_W1_BW			FIELD32(0x00800000)
+#define RXWI_W1_SHORT_GI		FIELD32(0x01000000)
+#define RXWI_W1_STBC			FIELD32(0x06000000)
+#define RXWI_W1_PHYMODE			FIELD32(0xc0000000)
+
+/*
+ * Word2
+ */
+#define RXWI_W2_RSSI0			FIELD32(0x000000ff)
+#define RXWI_W2_RSSI1			FIELD32(0x0000ff00)
+#define RXWI_W2_RSSI2			FIELD32(0x00ff0000)
+
+/*
+ * Word3
+ */
+#define RXWI_W3_SNR0			FIELD32(0x000000ff)
+#define RXWI_W3_SNR1			FIELD32(0x0000ff00)
+
+/*
  * RX descriptor format for RX Ring.
  */
 
@@ -115,25 +165,25 @@
  * AMSDU: rx with 802.3 header, not 802.11 header.
  */
 
-#define RXINFO_W0_BA			FIELD32(0x00000001)
-#define RXINFO_W0_DATA			FIELD32(0x00000002)
-#define RXINFO_W0_NULLDATA		FIELD32(0x00000004)
-#define RXINFO_W0_FRAG			FIELD32(0x00000008)
-#define RXINFO_W0_UNICAST_TO_ME		FIELD32(0x00000010)
-#define RXINFO_W0_MULTICAST		FIELD32(0x00000020)
-#define RXINFO_W0_BROADCAST		FIELD32(0x00000040)
-#define RXINFO_W0_MY_BSS		FIELD32(0x00000080)
-#define RXINFO_W0_CRC_ERROR		FIELD32(0x00000100)
-#define RXINFO_W0_CIPHER_ERROR		FIELD32(0x00000600)
-#define RXINFO_W0_AMSDU			FIELD32(0x00000800)
-#define RXINFO_W0_HTC			FIELD32(0x00001000)
-#define RXINFO_W0_RSSI			FIELD32(0x00002000)
-#define RXINFO_W0_L2PAD			FIELD32(0x00004000)
-#define RXINFO_W0_AMPDU			FIELD32(0x00008000)
-#define RXINFO_W0_DECRYPTED		FIELD32(0x00010000)
-#define RXINFO_W0_PLCP_RSSI		FIELD32(0x00020000)
-#define RXINFO_W0_CIPHER_ALG		FIELD32(0x00040000)
-#define RXINFO_W0_LAST_AMSDU		FIELD32(0x00080000)
-#define RXINFO_W0_PLCP_SIGNAL		FIELD32(0xfff00000)
+#define RXD_W0_BA			FIELD32(0x00000001)
+#define RXD_W0_DATA			FIELD32(0x00000002)
+#define RXD_W0_NULLDATA			FIELD32(0x00000004)
+#define RXD_W0_FRAG			FIELD32(0x00000008)
+#define RXD_W0_UNICAST_TO_ME		FIELD32(0x00000010)
+#define RXD_W0_MULTICAST		FIELD32(0x00000020)
+#define RXD_W0_BROADCAST		FIELD32(0x00000040)
+#define RXD_W0_MY_BSS			FIELD32(0x00000080)
+#define RXD_W0_CRC_ERROR		FIELD32(0x00000100)
+#define RXD_W0_CIPHER_ERROR		FIELD32(0x00000600)
+#define RXD_W0_AMSDU			FIELD32(0x00000800)
+#define RXD_W0_HTC			FIELD32(0x00001000)
+#define RXD_W0_RSSI			FIELD32(0x00002000)
+#define RXD_W0_L2PAD			FIELD32(0x00004000)
+#define RXD_W0_AMPDU			FIELD32(0x00008000)
+#define RXD_W0_DECRYPTED		FIELD32(0x00010000)
+#define RXD_W0_PLCP_RSSI		FIELD32(0x00020000)
+#define RXD_W0_CIPHER_ALG		FIELD32(0x00040000)
+#define RXD_W0_LAST_AMSDU		FIELD32(0x00080000)
+#define RXD_W0_PLCP_SIGNAL		FIELD32(0xfff00000)
 
 #endif /* RT2800USB_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/module.h>
 #include <linux/poll.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 
 #include "rt2x00.h"
@@ -109,7 +110,7 @@ struct rt2x00debug_intf {
 
 	/*
 	 * HW crypto statistics.
-	 * All statistics are stored seperately per cipher type.
+	 * All statistics are stored separately per cipher type.
 	 */
 	struct rt2x00debug_crypto crypto_stats[CIPHER_MAX];
 
@@ -184,7 +185,7 @@ void rt2x00debug_dump_frame(struct rt2x0
 	dump_hdr->data_length = cpu_to_le32(skb->len);
 	dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt);
 	dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf);
-	dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev);
+	dump_hdr->chip_rev = cpu_to_le16(rt2x00dev->chip.rev);
 	dump_hdr->type = cpu_to_le16(type);
 	dump_hdr->queue_index = desc->entry->queue->qid;
 	dump_hdr->entry_index = desc->entry->entry_idx;
@@ -573,7 +574,7 @@ static struct dentry *rt2x00debug_create
 	blob->data = data;
 	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, "revision:\t%04x\n", intf->rt2x00dev->chip.rev);
 	data += sprintf(data, "\n");
 	data += sprintf(data, "register\tbase\twords\twordsize\n");
 	data += sprintf(data, "csr\t%d\t%d\t%d\n",
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00dev.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00dev.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "rt2x00.h"
 #include "rt2x00lib.h"
@@ -385,9 +386,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev
 	memset(&rxdesc, 0, sizeof(rxdesc));
 	rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
 
-	/* Trim buffer to correct size */
-	skb_trim(entry->skb, rxdesc.size);
-
 	/*
 	 * The data behind the ieee80211 header must be
 	 * aligned on a 4 byte boundary.
@@ -397,18 +395,23 @@ void rt2x00lib_rxdone(struct rt2x00_dev
 	/*
 	 * Hardware might have stripped the IV/EIV/ICV data,
 	 * in that case it is possible that the data was
-	 * provided seperately (through hardware descriptor)
+	 * provided separately (through hardware descriptor)
 	 * in which case we should reinsert the data into the frame.
 	 */
 	if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) &&
 	    (rxdesc.flags & RX_FLAG_IV_STRIPPED))
 		rt2x00crypto_rx_insert_iv(entry->skb, header_length,
 					  &rxdesc);
-	else if (rxdesc.dev_flags & RXDONE_L2PAD)
+	else if (header_length &&
+		 (rxdesc.size > header_length) &&
+		 (rxdesc.dev_flags & RXDONE_L2PAD))
 		rt2x00queue_remove_l2pad(entry->skb, header_length);
 	else
 		rt2x00queue_align_payload(entry->skb, header_length);
 
+	/* Trim buffer to correct size */
+	skb_trim(entry->skb, rxdesc.size);
+
 	/*
 	 * Check if the frame was received using HT. In that case,
 	 * the rate is the MCS index and should be passed to mac80211
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00.h linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00.h	2010-05-16 17:17:36.000000000 -0400
@@ -104,6 +104,12 @@
 #define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate))
 
 /*
+ * Determine the number of L2 padding bytes required between the header and
+ * the payload.
+ */
+#define L2PAD_SIZE(__hdrlen)	(-(__hdrlen) & 3)
+
+/*
  * Determine the alignment requirement,
  * to make sure the 802.11 payload is padded to a 4-byte boundrary
  * we must determine the address of the payload and calculate the
@@ -154,6 +160,7 @@ struct avg_val {
 enum rt2x00_chip_intf {
 	RT2X00_CHIP_INTF_PCI,
 	RT2X00_CHIP_INTF_USB,
+	RT2X00_CHIP_INTF_SOC,
 };
 
 /*
@@ -163,25 +170,26 @@ enum rt2x00_chip_intf {
  */
 struct rt2x00_chip {
 	u16 rt;
-#define RT2460		0x0101
-#define RT2560		0x0201
-#define RT2570		0x1201
-#define RT2561s		0x0301	/* Turbo */
-#define RT2561		0x0302
-#define RT2661		0x0401
-#define RT2571		0x1300
-#define RT2860		0x0601	/* 2.4GHz PCI/CB */
-#define RT2860D		0x0681	/* 2.4GHz, 5GHz PCI/CB */
-#define RT2890		0x0701	/* 2.4GHz PCIe */
-#define RT2890D		0x0781	/* 2.4GHz, 5GHz PCIe */
+#define RT2460		0x2460
+#define RT2560		0x2560
+#define RT2570		0x2570
+#define RT2661		0x2661
+#define RT2573		0x2573
+#define RT2860		0x2860	/* 2.4GHz PCI/CB */
+#define RT2870		0x2870
+#define RT2872		0x2872
 #define RT2880		0x2880	/* WSOC */
+#define RT2883		0x2883	/* WSOC */
+#define RT2890		0x2890	/* 2.4GHz PCIe */
 #define RT3052		0x3052	/* WSOC */
+#define RT3070		0x3070
+#define RT3071		0x3071
 #define RT3090		0x3090	/* 2.4GHz PCIe */
-#define RT2870		0x1600
-#define RT3070		0x1800
+#define RT3390		0x3390
+#define RT3572		0x3572
 
 	u16 rf;
-	u32 rev;
+	u16 rev;
 
 	enum rt2x00_chip_intf intf;
 };
@@ -911,51 +919,30 @@ static inline void rt2x00_eeprom_write(s
  * Chipset handlers
  */
 static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev,
-				   const u16 rt, const u16 rf, const u32 rev)
+				   const u16 rt, const u16 rf, const u16 rev)
 {
 	rt2x00dev->chip.rt = rt;
 	rt2x00dev->chip.rf = rf;
 	rt2x00dev->chip.rev = rev;
-}
-
-static inline void rt2x00_set_chip_rt(struct rt2x00_dev *rt2x00dev,
-				      const u16 rt)
-{
-	rt2x00dev->chip.rt = rt;
-}
-
-static inline void rt2x00_set_chip_rf(struct rt2x00_dev *rt2x00dev,
-				      const u16 rf, const u32 rev)
-{
-	rt2x00_set_chip(rt2x00dev, rt2x00dev->chip.rt, rf, rev);
-}
 
-static inline void rt2x00_print_chip(struct rt2x00_dev *rt2x00dev)
-{
 	INFO(rt2x00dev,
-	     "Chipset detected - rt: %04x, rf: %04x, rev: %08x.\n",
+	     "Chipset detected - rt: %04x, rf: %04x, rev: %04x.\n",
 	     rt2x00dev->chip.rt, rt2x00dev->chip.rf, rt2x00dev->chip.rev);
 }
 
-static inline char rt2x00_rt(const struct rt2x00_chip *chipset, const u16 chip)
-{
-	return (chipset->rt == chip);
-}
-
-static inline char rt2x00_rf(const struct rt2x00_chip *chipset, const u16 chip)
+static inline char rt2x00_rt(struct rt2x00_dev *rt2x00dev, const u16 rt)
 {
-	return (chipset->rf == chip);
+	return (rt2x00dev->chip.rt == rt);
 }
 
-static inline u32 rt2x00_rev(const struct rt2x00_chip *chipset)
+static inline char rt2x00_rf(struct rt2x00_dev *rt2x00dev, const u16 rf)
 {
-	return chipset->rev;
+	return (rt2x00dev->chip.rf == rf);
 }
 
-static inline bool rt2x00_check_rev(const struct rt2x00_chip *chipset,
-				    const u32 mask, const u32 rev)
+static inline u16 rt2x00_rev(struct rt2x00_dev *rt2x00dev)
 {
-	return ((chipset->rev & mask) == rev);
+	return rt2x00dev->chip.rev;
 }
 
 static inline void rt2x00_set_chip_intf(struct rt2x00_dev *rt2x00dev,
@@ -964,20 +951,25 @@ static inline void rt2x00_set_chip_intf(
 	rt2x00dev->chip.intf = intf;
 }
 
-static inline bool rt2x00_intf(const struct rt2x00_chip *chipset,
+static inline bool rt2x00_intf(struct rt2x00_dev *rt2x00dev,
 			       enum rt2x00_chip_intf intf)
 {
-	return (chipset->intf == intf);
+	return (rt2x00dev->chip.intf == intf);
 }
 
-static inline bool rt2x00_intf_is_pci(struct rt2x00_dev *rt2x00dev)
+static inline bool rt2x00_is_pci(struct rt2x00_dev *rt2x00dev)
 {
-	return rt2x00_intf(&rt2x00dev->chip, RT2X00_CHIP_INTF_PCI);
+	return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
 }
 
-static inline bool rt2x00_intf_is_usb(struct rt2x00_dev *rt2x00dev)
+static inline bool rt2x00_is_usb(struct rt2x00_dev *rt2x00dev)
 {
-	return rt2x00_intf(&rt2x00dev->chip, RT2X00_CHIP_INTF_USB);
+	return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_USB);
+}
+
+static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev)
+{
+	return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC);
 }
 
 /**
@@ -1019,9 +1011,9 @@ int rt2x00mac_tx(struct ieee80211_hw *hw
 int rt2x00mac_start(struct ieee80211_hw *hw);
 void rt2x00mac_stop(struct ieee80211_hw *hw);
 int rt2x00mac_add_interface(struct ieee80211_hw *hw,
-			    struct ieee80211_if_init_conf *conf);
+			    struct ieee80211_vif *vif);
 void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
-				struct ieee80211_if_init_conf *conf);
+				struct ieee80211_vif *vif);
 int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed);
 void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
 				unsigned int changed_flags,
@@ -1038,8 +1030,6 @@ int rt2x00mac_set_key(struct ieee80211_h
 #endif /* CONFIG_RT2X00_LIB_CRYPTO */
 int rt2x00mac_get_stats(struct ieee80211_hw *hw,
 			struct ieee80211_low_level_stats *stats);
-int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
-			   struct ieee80211_tx_queue_stats *stats);
 void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
 				struct ieee80211_vif *vif,
 				struct ieee80211_bss_conf *bss_conf,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00mac.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00mac.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00mac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00mac.c	2010-05-16 17:17:36.000000000 -0400
@@ -187,10 +187,10 @@ void rt2x00mac_stop(struct ieee80211_hw
 EXPORT_SYMBOL_GPL(rt2x00mac_stop);
 
 int rt2x00mac_add_interface(struct ieee80211_hw *hw,
-			    struct ieee80211_if_init_conf *conf)
+			    struct ieee80211_vif *vif)
 {
 	struct rt2x00_dev *rt2x00dev = hw->priv;
-	struct rt2x00_intf *intf = vif_to_intf(conf->vif);
+	struct rt2x00_intf *intf = vif_to_intf(vif);
 	struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, QID_BEACON);
 	struct queue_entry *entry = NULL;
 	unsigned int i;
@@ -203,7 +203,7 @@ int rt2x00mac_add_interface(struct ieee8
 	    !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
 		return -ENODEV;
 
-	switch (conf->type) {
+	switch (vif->type) {
 	case NL80211_IFTYPE_AP:
 		/*
 		 * We don't support mixed combinations of
@@ -263,7 +263,7 @@ int rt2x00mac_add_interface(struct ieee8
 	 * increase interface count and start initialization.
 	 */
 
-	if (conf->type == NL80211_IFTYPE_AP)
+	if (vif->type == NL80211_IFTYPE_AP)
 		rt2x00dev->intf_ap_count++;
 	else
 		rt2x00dev->intf_sta_count++;
@@ -273,16 +273,16 @@ int rt2x00mac_add_interface(struct ieee8
 	mutex_init(&intf->beacon_skb_mutex);
 	intf->beacon = entry;
 
-	if (conf->type == NL80211_IFTYPE_AP)
-		memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN);
-	memcpy(&intf->mac, conf->mac_addr, ETH_ALEN);
+	if (vif->type == NL80211_IFTYPE_AP)
+		memcpy(&intf->bssid, vif->addr, ETH_ALEN);
+	memcpy(&intf->mac, vif->addr, ETH_ALEN);
 
 	/*
 	 * The MAC adddress must be configured after the device
 	 * has been initialized. Otherwise the device can reset
 	 * the MAC registers.
 	 */
-	rt2x00lib_config_intf(rt2x00dev, intf, conf->type, intf->mac, NULL);
+	rt2x00lib_config_intf(rt2x00dev, intf, vif->type, intf->mac, NULL);
 
 	/*
 	 * Some filters depend on the current working mode. We can force
@@ -296,10 +296,10 @@ int rt2x00mac_add_interface(struct ieee8
 EXPORT_SYMBOL_GPL(rt2x00mac_add_interface);
 
 void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
-				struct ieee80211_if_init_conf *conf)
+				struct ieee80211_vif *vif)
 {
 	struct rt2x00_dev *rt2x00dev = hw->priv;
-	struct rt2x00_intf *intf = vif_to_intf(conf->vif);
+	struct rt2x00_intf *intf = vif_to_intf(vif);
 
 	/*
 	 * Don't allow interfaces to be remove while
@@ -307,11 +307,11 @@ void rt2x00mac_remove_interface(struct i
 	 * no interface is present.
 	 */
 	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
-	    (conf->type == NL80211_IFTYPE_AP && !rt2x00dev->intf_ap_count) ||
-	    (conf->type != NL80211_IFTYPE_AP && !rt2x00dev->intf_sta_count))
+	    (vif->type == NL80211_IFTYPE_AP && !rt2x00dev->intf_ap_count) ||
+	    (vif->type != NL80211_IFTYPE_AP && !rt2x00dev->intf_sta_count))
 		return;
 
-	if (conf->type == NL80211_IFTYPE_AP)
+	if (vif->type == NL80211_IFTYPE_AP)
 		rt2x00dev->intf_ap_count--;
 	else
 		rt2x00dev->intf_sta_count--;
@@ -555,22 +555,6 @@ int rt2x00mac_get_stats(struct ieee80211
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_get_stats);
 
-int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
-			   struct ieee80211_tx_queue_stats *stats)
-{
-	struct rt2x00_dev *rt2x00dev = hw->priv;
-	unsigned int i;
-
-	for (i = 0; i < rt2x00dev->ops->tx_queues; i++) {
-		stats[i].len = rt2x00dev->tx[i].length;
-		stats[i].limit = rt2x00dev->tx[i].limit;
-		stats[i].count = rt2x00dev->tx[i].count;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(rt2x00mac_get_tx_stats);
-
 void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
 				struct ieee80211_vif *vif,
 				struct ieee80211_bss_conf *bss_conf,
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "rt2x00.h"
 #include "rt2x00pci.h"
@@ -41,6 +42,9 @@ int rt2x00pci_regbusy_read(struct rt2x00
 {
 	unsigned int i;
 
+	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+		return 0;
+
 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
 		rt2x00pci_register_read(rt2x00dev, offset, reg);
 		if (!rt2x00_get_field32(*reg, field))
@@ -269,7 +273,6 @@ int rt2x00pci_probe(struct pci_dev *pci_
 	struct ieee80211_hw *hw;
 	struct rt2x00_dev *rt2x00dev;
 	int retval;
-	u16 chip;
 
 	retval = pci_request_regions(pci_dev, pci_name(pci_dev));
 	if (retval) {
@@ -312,12 +315,6 @@ int rt2x00pci_probe(struct pci_dev *pci_
 
 	rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
 
-	/*
-	 * Determine RT chipset by reading PCI header.
-	 */
-	pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip);
-	rt2x00_set_chip_rt(rt2x00dev, chip);
-
 	retval = rt2x00pci_alloc_reg(rt2x00dev);
 	if (retval)
 		goto exit_free_device;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.h linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #define RT2X00PCI_H
 
 #include <linux/io.h>
+#include <linux/pci.h>
 
 /*
  * This variable should be used with the
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 	Abstract: rt2x00 queue specific routines.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/dma-mapping.h>
@@ -177,55 +178,45 @@ void rt2x00queue_align_payload(struct sk
 
 void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
 {
-	struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
-	unsigned int frame_length = skb->len;
+	unsigned int payload_length = skb->len - header_length;
 	unsigned int header_align = ALIGN_SIZE(skb, 0);
 	unsigned int payload_align = ALIGN_SIZE(skb, header_length);
-	unsigned int l2pad = 4 - (payload_align - header_align);
+	unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0;
 
-	if (header_align == payload_align) {
-		/*
-		 * Both header and payload must be moved the same
-		 * amount of bytes to align them properly. This means
-		 * we don't use the L2 padding but just move the entire
-		 * frame.
-		 */
-		rt2x00queue_align_frame(skb);
-	} else if (!payload_align) {
-		/*
-		 * Simple L2 padding, only the header needs to be moved,
-		 * the payload is already properly aligned.
-		 */
-		skb_push(skb, header_align);
-		memmove(skb->data, skb->data + header_align, frame_length);
-		skbdesc->flags |= SKBDESC_L2_PADDED;
-	} else {
-		/*
-		 *
-		 * Complicated L2 padding, both header and payload need
-		 * to be moved. By default we only move to the start
-		 * of the buffer, so our header alignment needs to be
-		 * increased if there is not enough room for the header
-		 * to be moved.
-		 */
-		if (payload_align > header_align)
-			header_align += 4;
+	/*
+	 * Adjust the header alignment if the payload needs to be moved more
+	 * than the header.
+	 */
+	if (payload_align > header_align)
+		header_align += 4;
 
-		skb_push(skb, header_align);
-		memmove(skb->data, skb->data + header_align, header_length);
+	/* There is nothing to do if no alignment is needed */
+	if (!header_align)
+		return;
+
+	/* Reserve the amount of space needed in front of the frame */
+	skb_push(skb, header_align);
+
+	/*
+	 * Move the header.
+	 */
+	memmove(skb->data, skb->data + header_align, header_length);
+
+	/* Move the payload, if present and if required */
+	if (payload_length && payload_align)
 		memmove(skb->data + header_length + l2pad,
 			skb->data + header_length + l2pad + payload_align,
-			frame_length - header_length);
-		skbdesc->flags |= SKBDESC_L2_PADDED;
-	}
+			payload_length);
+
+	/* Trim the skb to the correct size */
+	skb_trim(skb, header_length + l2pad + payload_length);
 }
 
 void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
 {
-	struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
-	unsigned int l2pad = 4 - (header_length & 3);
+	unsigned int l2pad = L2PAD_SIZE(header_length);
 
-	if (!l2pad || (skbdesc->flags & SKBDESC_L2_PADDED))
+	if (!l2pad)
 		return;
 
 	memmove(skb->data + l2pad, skb->data, header_length);
@@ -346,7 +337,9 @@ static void rt2x00queue_create_tx_descri
 	 * Header and alignment information.
 	 */
 	txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
-	txdesc->l2pad = ALIGN_SIZE(entry->skb, txdesc->header_length);
+	if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags) &&
+	    (entry->skb->len > txdesc->header_length))
+		txdesc->l2pad = L2PAD_SIZE(txdesc->header_length);
 
 	/*
 	 * Check whether this frame is to be acked.
@@ -387,10 +380,13 @@ static void rt2x00queue_create_tx_descri
 
 	/*
 	 * Beacons and probe responses require the tsf timestamp
-	 * to be inserted into the frame.
+	 * to be inserted into the frame, except for a frame that has been injected
+	 * through a monitor interface. This latter is needed for testing a
+	 * monitor interface.
 	 */
-	if (ieee80211_is_beacon(hdr->frame_control) ||
-	    ieee80211_is_probe_resp(hdr->frame_control))
+	if ((ieee80211_is_beacon(hdr->frame_control) ||
+	    ieee80211_is_probe_resp(hdr->frame_control)) &&
+	    (!(tx_info->flags & IEEE80211_TX_CTL_INJECTED)))
 		__set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags);
 
 	/*
@@ -502,7 +498,7 @@ int rt2x00queue_write_tx_frame(struct da
 	/*
 	 * When hardware encryption is supported, and this frame
 	 * is to be encrypted, we should strip the IV/EIV data from
-	 * the frame so we can provide it to the driver seperately.
+	 * the frame so we can provide it to the driver separately.
 	 */
 	if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
 	    !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.h linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.h	2010-05-16 17:17:36.000000000 -0400
@@ -92,8 +92,6 @@ enum data_queue_qid {
  * @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX
  * @SKBDESC_IV_STRIPPED: Frame contained a IV/EIV provided by
  *	mac80211 but was stripped for processing by the driver.
- * @SKBDESC_L2_PADDED: Payload has been padded for 4-byte alignment,
- *	the padded bytes are located between header and payload.
  * @SKBDESC_NOT_MAC80211: Frame didn't originate from mac80211,
  *	don't try to pass it back.
  */
@@ -101,8 +99,7 @@ enum skb_frame_desc_flags {
 	SKBDESC_DMA_MAPPED_RX = 1 << 0,
 	SKBDESC_DMA_MAPPED_TX = 1 << 1,
 	SKBDESC_IV_STRIPPED = 1 << 2,
-	SKBDESC_L2_PADDED = 1 << 3,
-	SKBDESC_NOT_MAC80211 = 1 << 4,
+	SKBDESC_NOT_MAC80211 = 1 << 3,
 };
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include "rt2x00.h"
 #include "rt2x00soc.h"
@@ -71,9 +72,7 @@ exit:
 	return -ENOMEM;
 }
 
-int rt2x00soc_probe(struct platform_device *pdev,
-		    const unsigned short chipset,
-		    const struct rt2x00_ops *ops)
+int rt2x00soc_probe(struct platform_device *pdev, const struct rt2x00_ops *ops)
 {
 	struct ieee80211_hw *hw;
 	struct rt2x00_dev *rt2x00dev;
@@ -94,12 +93,7 @@ int rt2x00soc_probe(struct platform_devi
 	rt2x00dev->irq = platform_get_irq(pdev, 0);
 	rt2x00dev->name = pdev->dev.driver->name;
 
-	/*
-	 * SoC devices mimic PCI behavior.
-	 */
-	rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
-
-	rt2x00_set_chip_rt(rt2x00dev, chipset);
+	rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC);
 
 	retval = rt2x00soc_alloc_reg(rt2x00dev);
 	if (retval)
@@ -119,6 +113,7 @@ exit_free_device:
 
 	return retval;
 }
+EXPORT_SYMBOL_GPL(rt2x00soc_probe);
 
 int rt2x00soc_remove(struct platform_device *pdev)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.h linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,20 +26,10 @@
 #ifndef RT2X00SOC_H
 #define RT2X00SOC_H
 
-#define KSEG1ADDR(__ptr) __ptr
-
-#define __rt2x00soc_probe(__chipset, __ops) \
-static int __rt2x00soc_probe(struct platform_device *pdev) \
-{ \
-	return rt2x00soc_probe(pdev, (__chipset), (__ops)); \
-}
-
 /*
  * SoC driver handlers.
  */
-int rt2x00soc_probe(struct platform_device *pdev,
-		    const unsigned short chipset,
-		    const struct rt2x00_ops *ops);
+int rt2x00soc_probe(struct platform_device *pdev, const struct rt2x00_ops *ops);
 int rt2x00soc_remove(struct platform_device *pdev);
 #ifdef CONFIG_PM
 int rt2x00soc_suspend(struct platform_device *pdev, pm_message_t state);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/bug.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt61pci.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt61pci.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt61pci.c	2013-05-03 12:11:05.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt61pci.c	2013-05-03 09:50:37.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/eeprom_93cx6.h>
 
@@ -476,7 +477,7 @@ static int rt61pci_config_pairwise_key(s
 		 * The driver does not support the IV/EIV generation
 		 * in hardware. However it doesn't support the IV/EIV
 		 * inside the ieee80211 frame either, but requires it
-		 * to be provided seperately for the descriptor.
+		 * to be provided separately for the descriptor.
 		 * rt2x00lib will cut the IV/EIV data out of all frames
 		 * given to us by mac80211, but we must tell mac80211
 		 * to generate the IV/EIV data.
@@ -637,8 +638,7 @@ static void rt61pci_config_antenna_5x(st
 	rt61pci_bbp_read(rt2x00dev, 4, &r4);
 	rt61pci_bbp_read(rt2x00dev, 77, &r77);
 
-	rt2x00_set_field8(&r3, BBP_R3_SMART_MODE,
-			  rt2x00_rf(&rt2x00dev->chip, RF5325));
+	rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, rt2x00_rf(rt2x00dev, RF5325));
 
 	/*
 	 * Configure the RX antenna.
@@ -684,8 +684,7 @@ static void rt61pci_config_antenna_2x(st
 	rt61pci_bbp_read(rt2x00dev, 4, &r4);
 	rt61pci_bbp_read(rt2x00dev, 77, &r77);
 
-	rt2x00_set_field8(&r3, BBP_R3_SMART_MODE,
-			  rt2x00_rf(&rt2x00dev->chip, RF2529));
+	rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, rt2x00_rf(rt2x00dev, RF2529));
 	rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
 			  !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
 
@@ -833,12 +832,11 @@ static void rt61pci_config_ant(struct rt
 
 	rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg);
 
-	if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-	    rt2x00_rf(&rt2x00dev->chip, RF5325))
+	if (rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF5325))
 		rt61pci_config_antenna_5x(rt2x00dev, ant);
-	else if (rt2x00_rf(&rt2x00dev->chip, RF2527))
+	else if (rt2x00_rf(rt2x00dev, RF2527))
 		rt61pci_config_antenna_2x(rt2x00dev, ant);
-	else if (rt2x00_rf(&rt2x00dev->chip, RF2529)) {
+	else if (rt2x00_rf(rt2x00dev, RF2529)) {
 		if (test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags))
 			rt61pci_config_antenna_2x(rt2x00dev, ant);
 		else
@@ -879,8 +877,7 @@ static void rt61pci_config_channel(struc
 	rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
 	rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
 
-	smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-		  rt2x00_rf(&rt2x00dev->chip, RF2527));
+	smart = !(rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF2527));
 
 	rt61pci_bbp_read(rt2x00dev, 3, &r3);
 	rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
@@ -1135,16 +1132,18 @@ dynamic_cca_tune:
  */
 static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
 {
+	u16 chip;
 	char *fw_name;
 
-	switch (rt2x00dev->chip.rt) {
-	case RT2561:
+	pci_read_config_word(to_pci_dev(rt2x00dev->dev), PCI_DEVICE_ID, &chip);
+	switch (chip) {
+	case RT2561_PCI_ID:
 		fw_name = FIRMWARE_RT2561;
 		break;
-	case RT2561s:
+	case RT2561s_PCI_ID:
 		fw_name = FIRMWARE_RT2561s;
 		break;
-	case RT2661:
+	case RT2661_PCI_ID:
 		fw_name = FIRMWARE_RT2661;
 		break;
 	default:
@@ -2299,13 +2298,13 @@ static int rt61pci_init_eeprom(struct rt
 	 */
 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
 	rt2x00pci_register_read(rt2x00dev, MAC_CSR0, &reg);
-	rt2x00_set_chip_rf(rt2x00dev, value, reg);
-	rt2x00_print_chip(rt2x00dev);
+	rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET),
+			value, rt2x00_get_field32(reg, MAC_CSR0_REVISION));
 
-	if (!rt2x00_rf(&rt2x00dev->chip, RF5225) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF5325) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2527) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2529)) {
+	if (!rt2x00_rf(rt2x00dev, RF5225) &&
+	    !rt2x00_rf(rt2x00dev, RF5325) &&
+	    !rt2x00_rf(rt2x00dev, RF2527) &&
+	    !rt2x00_rf(rt2x00dev, RF2529)) {
 		ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
 		return -ENODEV;
 	}
@@ -2360,7 +2359,7 @@ static int rt61pci_init_eeprom(struct rt
 	 * the antenna settings should be gathered from the NIC
 	 * eeprom word.
 	 */
-	if (rt2x00_rf(&rt2x00dev->chip, RF2529) &&
+	if (rt2x00_rf(rt2x00dev, RF2529) &&
 	    !test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) {
 		rt2x00dev->default_ant.rx =
 		    ANTENNA_A + rt2x00_get_field16(eeprom, EEPROM_NIC_RX_FIXED);
@@ -2571,8 +2570,7 @@ static int rt61pci_probe_hw_mode(struct
 		spec->channels = rf_vals_seq;
 	}
 
-	if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-	    rt2x00_rf(&rt2x00dev->chip, RF5325)) {
+	if (rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF5325)) {
 		spec->supported_bands |= SUPPORT_BAND_5GHZ;
 		spec->num_channels = ARRAY_SIZE(rf_vals_seq);
 	}
@@ -2735,7 +2733,6 @@ static const struct ieee80211_ops rt61pc
 	.get_stats		= rt2x00mac_get_stats,
 	.bss_info_changed	= rt2x00mac_bss_info_changed,
 	.conf_tx		= rt61pci_conf_tx,
-	.get_tx_stats		= rt2x00mac_get_tx_stats,
 	.get_tsf		= rt61pci_get_tsf,
 	.rfkill_poll		= rt2x00mac_rfkill_poll,
 };
@@ -2812,7 +2809,7 @@ static const struct rt2x00_ops rt61pci_o
 /*
  * RT61pci module information.
  */
-static struct pci_device_id rt61pci_device_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(rt61pci_device_table) = {
 	/* RT2561s */
 	{ PCI_DEVICE(0x1814, 0x0301), PCI_DEVICE_DATA(&rt61pci_ops) },
 	/* RT2561 v2 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt61pci.h linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt61pci.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt61pci.h	2013-05-03 12:11:03.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt61pci.h	2013-05-03 09:50:34.000000000 -0400
@@ -28,6 +28,13 @@
 #define RT61PCI_H
 
 /*
+ * RT chip PCI IDs.
+ */
+#define RT2561s_PCI_ID			0x0301
+#define RT2561_PCI_ID			0x0302
+#define RT2661_PCI_ID			0x0401
+
+/*
  * RF chip defines.
  */
 #define RF5225				0x0001
@@ -225,6 +232,8 @@ struct hw_pairwise_ta_entry {
  * MAC_CSR0: ASIC revision number.
  */
 #define MAC_CSR0			0x3000
+#define MAC_CSR0_REVISION		FIELD32(0x0000000f)
+#define MAC_CSR0_CHIPSET		FIELD32(0x000ffff0)
 
 /*
  * MAC_CSR1: System control register.
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt73usb.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt73usb.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt73usb.c	2013-05-03 12:11:10.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt73usb.c	2013-05-03 09:50:42.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "rt2x00.h"
@@ -136,8 +137,8 @@ static void rt73usb_rf_write(struct rt2x
 		 * all others contain 20 bits.
 		 */
 		rt2x00_set_field32(&reg, PHY_CSR4_NUMBER_OF_BITS,
-				   20 + (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-					 rt2x00_rf(&rt2x00dev->chip, RF2527)));
+				   20 + (rt2x00_rf(rt2x00dev, RF5225) ||
+					 rt2x00_rf(rt2x00dev, RF2527)));
 		rt2x00_set_field32(&reg, PHY_CSR4_IF_SELECT, 0);
 		rt2x00_set_field32(&reg, PHY_CSR4_BUSY, 1);
 
@@ -339,7 +340,7 @@ static int rt73usb_config_shared_key(str
 		 * The driver does not support the IV/EIV generation
 		 * in hardware. However it doesn't support the IV/EIV
 		 * inside the ieee80211 frame either, but requires it
-		 * to be provided seperately for the descriptor.
+		 * to be provided separately for the descriptor.
 		 * rt2x00lib will cut the IV/EIV data out of all frames
 		 * given to us by mac80211, but we must tell mac80211
 		 * to generate the IV/EIV data.
@@ -439,7 +440,7 @@ static int rt73usb_config_pairwise_key(s
 		 * The driver does not support the IV/EIV generation
 		 * in hardware. However it doesn't support the IV/EIV
 		 * inside the ieee80211 frame either, but requires it
-		 * to be provided seperately for the descriptor.
+		 * to be provided separately for the descriptor.
 		 * rt2x00lib will cut the IV/EIV data out of all frames
 		 * given to us by mac80211, but we must tell mac80211
 		 * to generate the IV/EIV data.
@@ -741,11 +742,9 @@ static void rt73usb_config_ant(struct rt
 
 	rt2x00usb_register_write(rt2x00dev, PHY_CSR0, reg);
 
-	if (rt2x00_rf(&rt2x00dev->chip, RF5226) ||
-	    rt2x00_rf(&rt2x00dev->chip, RF5225))
+	if (rt2x00_rf(rt2x00dev, RF5226) || rt2x00_rf(rt2x00dev, RF5225))
 		rt73usb_config_antenna_5x(rt2x00dev, ant);
-	else if (rt2x00_rf(&rt2x00dev->chip, RF2528) ||
-		 rt2x00_rf(&rt2x00dev->chip, RF2527))
+	else if (rt2x00_rf(rt2x00dev, RF2528) || rt2x00_rf(rt2x00dev, RF2527))
 		rt73usb_config_antenna_2x(rt2x00dev, ant);
 }
 
@@ -779,8 +778,7 @@ static void rt73usb_config_channel(struc
 	rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
 	rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
 
-	smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-		  rt2x00_rf(&rt2x00dev->chip, RF2527));
+	smart = !(rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF2527));
 
 	rt73usb_bbp_read(rt2x00dev, 3, &r3);
 	rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
@@ -1210,8 +1208,7 @@ static int rt73usb_init_registers(struct
 	rt2x00usb_register_write(rt2x00dev, SEC_CSR5, 0x00000000);
 
 	reg = 0x000023b0;
-	if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-	    rt2x00_rf(&rt2x00dev->chip, RF2527))
+	if (rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF2527))
 		rt2x00_set_field32(&reg, PHY_CSR1_RF_RPI, 1);
 	rt2x00usb_register_write(rt2x00dev, PHY_CSR1, reg);
 
@@ -1665,7 +1662,7 @@ static void rt73usb_fill_rxdone(struct q
 
 		/*
 		 * Hardware has stripped IV/EIV data from 802.11 frame during
-		 * decryption. It has provided the data seperately but rt2x00lib
+		 * decryption. It has provided the data separately but rt2x00lib
 		 * should decide if it should be reinserted.
 		 */
 		rxdesc->flags |= RX_FLAG_IV_STRIPPED;
@@ -1824,19 +1821,18 @@ static int rt73usb_init_eeprom(struct rt
 	 */
 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
 	rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
-	rt2x00_set_chip(rt2x00dev, RT2571, value, reg);
-	rt2x00_print_chip(rt2x00dev);
+	rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET),
+			value, rt2x00_get_field32(reg, MAC_CSR0_REVISION));
 
-	if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0x25730) ||
-	    rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) {
+	if (!rt2x00_rt(rt2x00dev, RT2573) || (rt2x00_rev(rt2x00dev) == 0)) {
 		ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
 		return -ENODEV;
 	}
 
-	if (!rt2x00_rf(&rt2x00dev->chip, RF5226) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2528) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF5225) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2527)) {
+	if (!rt2x00_rf(rt2x00dev, RF5226) &&
+	    !rt2x00_rf(rt2x00dev, RF2528) &&
+	    !rt2x00_rf(rt2x00dev, RF5225) &&
+	    !rt2x00_rf(rt2x00dev, RF2527)) {
 		ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
 		return -ENODEV;
 	}
@@ -2081,17 +2077,17 @@ static int rt73usb_probe_hw_mode(struct
 	spec->supported_bands = SUPPORT_BAND_2GHZ;
 	spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
 
-	if (rt2x00_rf(&rt2x00dev->chip, RF2528)) {
+	if (rt2x00_rf(rt2x00dev, RF2528)) {
 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528);
 		spec->channels = rf_vals_bg_2528;
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) {
+	} else if (rt2x00_rf(rt2x00dev, RF5226)) {
 		spec->supported_bands |= SUPPORT_BAND_5GHZ;
 		spec->num_channels = ARRAY_SIZE(rf_vals_5226);
 		spec->channels = rf_vals_5226;
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) {
+	} else if (rt2x00_rf(rt2x00dev, RF2527)) {
 		spec->num_channels = 14;
 		spec->channels = rf_vals_5225_2527;
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) {
+	} else if (rt2x00_rf(rt2x00dev, RF5225)) {
 		spec->supported_bands |= SUPPORT_BAND_5GHZ;
 		spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527);
 		spec->channels = rf_vals_5225_2527;
@@ -2249,7 +2245,6 @@ static const struct ieee80211_ops rt73us
 	.get_stats		= rt2x00mac_get_stats,
 	.bss_info_changed	= rt2x00mac_bss_info_changed,
 	.conf_tx		= rt73usb_conf_tx,
-	.get_tx_stats		= rt2x00mac_get_tx_stats,
 	.get_tsf		= rt73usb_get_tsf,
 	.rfkill_poll		= rt2x00mac_rfkill_poll,
 };
@@ -2354,9 +2349,12 @@ static struct usb_device_id rt73usb_devi
 	{ USB_DEVICE(0x08dd, 0x0120), USB_DEVICE_DATA(&rt73usb_ops) },
 	/* Buffalo */
 	{ USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x0411, 0x00d9), 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) },
+	/* CEIVA */
+	{ USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) },
 	/* CNet */
 	{ USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) },
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt73usb.h linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt73usb.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt73usb.h	2013-05-03 12:11:08.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rt2x00/rt73usb.h	2013-05-03 09:50:39.000000000 -0400
@@ -142,6 +142,8 @@ struct hw_pairwise_ta_entry {
  * MAC_CSR0: ASIC revision number.
  */
 #define MAC_CSR0			0x3000
+#define MAC_CSR0_REVISION		FIELD32(0x0000000f)
+#define MAC_CSR0_CHIPSET		FIELD32(0x000ffff0)
 
 /*
  * MAC_CSR1: System control register.
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8180_dev.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rtl818x/rtl8180_dev.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8180_dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rtl818x/rtl8180_dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/eeprom_93cx6.h>
@@ -33,7 +34,7 @@ MODULE_AUTHOR("Andrea Merello <andreamrl
 MODULE_DESCRIPTION("RTL8180 / RTL8185 PCI wireless driver");
 MODULE_LICENSE("GPL");
 
-static struct pci_device_id rtl8180_table[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(rtl8180_table) = {
 	/* rtl8185 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x700f) },
@@ -82,8 +83,6 @@ static const struct ieee80211_channel rt
 };
 
 
-
-
 void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
 {
 	struct rtl8180_priv *priv = dev->priv;
@@ -615,7 +614,6 @@ static int rtl8180_start(struct ieee8021
 	reg |= RTL818X_CMD_TX_ENABLE;
 	rtl818x_iowrite8(priv, &priv->map->CMD, reg);
 
-	priv->mode = NL80211_IFTYPE_MONITOR;
 	return 0;
 
  err_free_rings:
@@ -633,8 +631,6 @@ static void rtl8180_stop(struct ieee8021
 	u8 reg;
 	int i;
 
-	priv->mode = NL80211_IFTYPE_UNSPECIFIED;
-
 	rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
 
 	reg = rtl818x_ioread8(priv, &priv->map->CMD);
@@ -657,38 +653,39 @@ static void rtl8180_stop(struct ieee8021
 }
 
 static int rtl8180_add_interface(struct ieee80211_hw *dev,
-				 struct ieee80211_if_init_conf *conf)
+				 struct ieee80211_vif *vif)
 {
 	struct rtl8180_priv *priv = dev->priv;
 
-	if (priv->mode != NL80211_IFTYPE_MONITOR)
-		return -EOPNOTSUPP;
+	/*
+	 * We only support one active interface at a time.
+	 */
+	if (priv->vif)
+		return -EBUSY;
 
-	switch (conf->type) {
+	switch (vif->type) {
 	case NL80211_IFTYPE_STATION:
-		priv->mode = conf->type;
 		break;
 	default:
 		return -EOPNOTSUPP;
 	}
 
-	priv->vif = conf->vif;
+	priv->vif = vif;
 
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
 	rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0],
-			  le32_to_cpu(*(__le32 *)conf->mac_addr));
+			  le32_to_cpu(*(__le32 *)vif->addr));
 	rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->MAC[4],
-			  le16_to_cpu(*(__le16 *)(conf->mac_addr + 4)));
+			  le16_to_cpu(*(__le16 *)(vif->addr + 4)));
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 
 	return 0;
 }
 
 static void rtl8180_remove_interface(struct ieee80211_hw *dev,
-				     struct ieee80211_if_init_conf *conf)
+				     struct ieee80211_vif *vif)
 {
 	struct rtl8180_priv *priv = dev->priv;
-	priv->mode = NL80211_IFTYPE_MONITOR;
 	priv->vif = NULL;
 }
 
@@ -765,6 +762,14 @@ static void rtl8180_configure_filter(str
 	rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf);
 }
 
+static u64 rtl8180_get_tsf(struct ieee80211_hw *dev)
+{
+	struct rtl8180_priv *priv = dev->priv;
+
+	return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
+	       (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
+}
+
 static const struct ieee80211_ops rtl8180_ops = {
 	.tx			= rtl8180_tx,
 	.start			= rtl8180_start,
@@ -775,6 +780,7 @@ static const struct ieee80211_ops rtl818
 	.bss_info_changed	= rtl8180_bss_info_changed,
 	.prepare_multicast	= rtl8180_prepare_multicast,
 	.configure_filter	= rtl8180_configure_filter,
+	.get_tsf		= rtl8180_get_tsf,
 };
 
 static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8180.h linux-libre-2.6.34-gnu1/drivers/net/wireless/rtl818x/rtl8180.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8180.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rtl818x/rtl8180.h	2010-05-16 17:17:36.000000000 -0400
@@ -60,7 +60,6 @@ struct rtl8180_priv {
 	struct rtl818x_csr __iomem *map;
 	const struct rtl818x_rf_ops *rf;
 	struct ieee80211_vif *vif;
-	int mode;
 
 	/* rtl8180 driver specific */
 	spinlock_t lock;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187_dev.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rtl818x/rtl8187_dev.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187_dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rtl818x/rtl8187_dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/init.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/eeprom_93cx6.h>
@@ -1019,31 +1020,30 @@ static void rtl8187_stop(struct ieee8021
 }
 
 static int rtl8187_add_interface(struct ieee80211_hw *dev,
-				 struct ieee80211_if_init_conf *conf)
+				 struct ieee80211_vif *vif)
 {
 	struct rtl8187_priv *priv = dev->priv;
 	int i;
 	int ret = -EOPNOTSUPP;
 
 	mutex_lock(&priv->conf_mutex);
-	if (priv->mode != NL80211_IFTYPE_MONITOR)
+	if (priv->vif)
 		goto exit;
 
-	switch (conf->type) {
+	switch (vif->type) {
 	case NL80211_IFTYPE_STATION:
-		priv->mode = conf->type;
 		break;
 	default:
 		goto exit;
 	}
 
 	ret = 0;
-	priv->vif = conf->vif;
+	priv->vif = vif;
 
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
 	for (i = 0; i < ETH_ALEN; i++)
 		rtl818x_iowrite8(priv, &priv->map->MAC[i],
-				 ((u8 *)conf->mac_addr)[i]);
+				 ((u8 *)vif->addr)[i]);
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 
 exit:
@@ -1052,11 +1052,10 @@ exit:
 }
 
 static void rtl8187_remove_interface(struct ieee80211_hw *dev,
-				     struct ieee80211_if_init_conf *conf)
+				     struct ieee80211_vif *vif)
 {
 	struct rtl8187_priv *priv = dev->priv;
 	mutex_lock(&priv->conf_mutex);
-	priv->mode = NL80211_IFTYPE_MONITOR;
 	priv->vif = NULL;
 	mutex_unlock(&priv->conf_mutex);
 }
@@ -1268,6 +1267,14 @@ static int rtl8187_conf_tx(struct ieee80
 	return 0;
 }
 
+static u64 rtl8187_get_tsf(struct ieee80211_hw *dev)
+{
+	struct rtl8187_priv *priv = dev->priv;
+
+	return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
+	       (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
+}
+
 static const struct ieee80211_ops rtl8187_ops = {
 	.tx			= rtl8187_tx,
 	.start			= rtl8187_start,
@@ -1279,7 +1286,8 @@ static const struct ieee80211_ops rtl818
 	.prepare_multicast	= rtl8187_prepare_multicast,
 	.configure_filter	= rtl8187_configure_filter,
 	.conf_tx		= rtl8187_conf_tx,
-	.rfkill_poll		= rtl8187_rfkill_poll
+	.rfkill_poll		= rtl8187_rfkill_poll,
+	.get_tsf		= rtl8187_get_tsf,
 };
 
 static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom)
@@ -1366,7 +1374,6 @@ static int __devinit rtl8187_probe(struc
 	dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
 
 
-	priv->mode = NL80211_IFTYPE_MONITOR;
 	dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
 		     IEEE80211_HW_SIGNAL_DBM |
 		     IEEE80211_HW_RX_INCLUDES_FCS;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187.h linux-libre-2.6.34-gnu1/drivers/net/wireless/rtl818x/rtl8187.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rtl818x/rtl8187.h	2010-05-16 17:17:36.000000000 -0400
@@ -92,7 +92,7 @@ struct rtl8187_priv {
 	struct rtl818x_csr *map;
 	const struct rtl818x_rf_ops *rf;
 	struct ieee80211_vif *vif;
-	int mode;
+
 	/* The mutex protects the TX loopback state.
 	 * Any attempt to set channels concurrently locks the device.
 	 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.c linux-libre-2.6.34-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,7 @@ static void led_turn_on(struct work_stru
 	struct rtl8187_led *led = &priv->led_tx;
 
 	/* Don't change the LED, when the device is down. */
-	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+	if (!priv->vif || priv->vif->type == NL80211_IFTYPE_UNSPECIFIED)
 		return ;
 
 	/* Skip if the LED is not registered. */
@@ -71,7 +71,7 @@ static void led_turn_off(struct work_str
 	struct rtl8187_led *led = &priv->led_tx;
 
 	/* Don't change the LED, when the device is down. */
-	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+	if (!priv->vif || priv->vif->type == NL80211_IFTYPE_UNSPECIFIED)
 		return ;
 
 	/* Skip if the LED is not registered. */
@@ -241,5 +241,5 @@ void rtl8187_leds_exit(struct ieee80211_
 	cancel_delayed_work_sync(&priv->led_off);
 	cancel_delayed_work_sync(&priv->led_on);
 }
-#endif /* def CONFIG_RTL8187_LED */
+#endif /* def CONFIG_RTL8187_LEDS */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.h linux-libre-2.6.34-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.h	2010-05-16 17:17:36.000000000 -0400
@@ -54,6 +54,6 @@ struct rtl8187_led {
 void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code);
 void rtl8187_leds_exit(struct ieee80211_hw *dev);
 
-#endif /* def CONFIG_RTL8187_LED */
+#endif /* def CONFIG_RTL8187_LEDS */
 
 #endif /* RTL8187_LED_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/Makefile linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/Makefile
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -10,5 +10,7 @@ obj-$(CONFIG_WL1251_SDIO)	+= wl1251_sdio
 wl1271-objs		= wl1271_main.o  wl1271_spi.o wl1271_cmd.o  \
 			  wl1271_event.o wl1271_tx.o  wl1271_rx.o   \
 			  wl1271_ps.o    wl1271_acx.o wl1271_boot.o \
-			  wl1271_init.o  wl1271_debugfs.o
+			  wl1271_init.o  wl1271_debugfs.o wl1271_io.o
+
+wl1271-$(CONFIG_NL80211_TESTMODE)	+= wl1271_testmode.o
 obj-$(CONFIG_WL1271)	+= wl1271.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 #include "wl1251_acx.h"
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/crc7.h>
 
 #include "wl1251.h"
@@ -972,6 +973,75 @@ int wl1251_acx_wr_tbtt_and_dtim(struct w
 		goto out;
 	}
 
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
+		      u8 aifs, u16 txop)
+{
+	struct wl1251_acx_ac_cfg *acx;
+	int ret = 0;
+
+	wl1251_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
+		     "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop);
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->ac = ac;
+	acx->cw_min = cw_min;
+	acx->cw_max = cw_max;
+	acx->aifsn = aifs;
+	acx->txop_limit = txop;
+
+	ret = wl1251_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1251_warning("acx ac cfg failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
+		       enum wl1251_acx_channel_type type,
+		       u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
+		       enum wl1251_acx_ack_policy ack_policy)
+{
+	struct wl1251_acx_tid_cfg *acx;
+	int ret = 0;
+
+	wl1251_debug(DEBUG_ACX, "acx tid cfg %d type %d tsid %d "
+		     "ps_scheme %d ack_policy %d", queue, type, tsid,
+		     ps_scheme, ack_policy);
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->queue = queue;
+	acx->type = type;
+	acx->tsid = tsid;
+	acx->ps_scheme = ps_scheme;
+	acx->ack_policy = ack_policy;
+
+	ret = wl1251_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1251_warning("acx tid cfg failed: %d", ret);
+		goto out;
+	}
+
 out:
 	kfree(acx);
 	return ret;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.h	2010-05-16 17:17:36.000000000 -0400
@@ -1166,6 +1166,87 @@ struct wl1251_acx_wr_tbtt_and_dtim {
 	u8  padding;
 } __attribute__ ((packed));
 
+struct wl1251_acx_ac_cfg {
+	struct acx_header header;
+
+	/*
+	 * Access Category - The TX queue's access category
+	 * (refer to AccessCategory_enum)
+	 */
+	u8 ac;
+
+	/*
+	 * The contention window minimum size (in slots) for
+	 * the access class.
+	 */
+	u8 cw_min;
+
+	/*
+	 * The contention window maximum size (in slots) for
+	 * the access class.
+	 */
+	u16 cw_max;
+
+	/* The AIF value (in slots) for the access class. */
+	u8 aifsn;
+
+	u8 reserved;
+
+	/* The TX Op Limit (in microseconds) for the access class. */
+	u16 txop_limit;
+} __attribute__ ((packed));
+
+
+enum wl1251_acx_channel_type {
+	CHANNEL_TYPE_DCF	= 0,
+	CHANNEL_TYPE_EDCF	= 1,
+	CHANNEL_TYPE_HCCA	= 2,
+};
+
+enum wl1251_acx_ps_scheme {
+	/* regular ps: simple sending of packets */
+	WL1251_ACX_PS_SCHEME_LEGACY	= 0,
+
+	/* sending a packet triggers a unscheduled apsd downstream */
+	WL1251_ACX_PS_SCHEME_UPSD_TRIGGER	= 1,
+
+	/* a pspoll packet will be sent before every data packet */
+	WL1251_ACX_PS_SCHEME_LEGACY_PSPOLL	= 2,
+
+	/* scheduled apsd mode */
+	WL1251_ACX_PS_SCHEME_SAPSD		= 3,
+};
+
+enum wl1251_acx_ack_policy {
+	WL1251_ACX_ACK_POLICY_LEGACY	= 0,
+	WL1251_ACX_ACK_POLICY_NO_ACK	= 1,
+	WL1251_ACX_ACK_POLICY_BLOCK	= 2,
+};
+
+struct wl1251_acx_tid_cfg {
+	struct acx_header header;
+
+	/* tx queue id number (0-7) */
+	u8 queue;
+
+	/* channel access type for the queue, enum wl1251_acx_channel_type */
+	u8 type;
+
+	/* EDCA: ac index (0-3), HCCA: traffic stream id (8-15) */
+	u8 tsid;
+
+	/* ps scheme of the specified queue, enum wl1251_acx_ps_scheme */
+	u8 ps_scheme;
+
+	/* the tx queue ack policy, enum wl1251_acx_ack_policy */
+	u8 ack_policy;
+
+	u8 padding[3];
+
+	/* not supported */
+	u32 apsdconf[2];
+} __attribute__ ((packed));
+
 /*************************************************************************
 
     Host Interrupt Register (WiLink -> Host)
@@ -1322,5 +1403,11 @@ int wl1251_acx_tsf_info(struct wl1251 *w
 int wl1251_acx_rate_policies(struct wl1251 *wl);
 int wl1251_acx_mem_cfg(struct wl1251 *wl);
 int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim);
+int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
+		      u8 aifs, u16 txop);
+int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
+		       enum wl1251_acx_channel_type type,
+		       u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
+		       enum wl1251_acx_ack_policy ack_policy);
 
 #endif /* __WL1251_ACX_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_boot.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_boot.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_boot.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_boot.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  */
 
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include "wl1251_reg.h"
 #include "wl1251_boot.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_cmd.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_cmd.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_cmd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_cmd.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 #include "wl1251_cmd.h"
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/crc7.h>
 
 #include "wl1251.h"
@@ -406,6 +407,89 @@ int wl1251_cmd_template_set(struct wl125
 		goto out;
 	}
 
+out:
+	kfree(cmd);
+	return ret;
+}
+
+int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
+		    struct ieee80211_channel *channels[],
+		    unsigned int n_channels, unsigned int n_probes)
+{
+	struct wl1251_cmd_scan *cmd;
+	int i, ret = 0;
+
+	wl1251_debug(DEBUG_CMD, "cmd scan");
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
+	cmd->params.rx_filter_options = cpu_to_le32(CFG_RX_PRSP_EN |
+						    CFG_RX_MGMT_EN |
+						    CFG_RX_BCN_EN);
+	cmd->params.scan_options = 0;
+	cmd->params.num_channels = n_channels;
+	cmd->params.num_probe_requests = n_probes;
+	cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
+	cmd->params.tid_trigger = 0;
+
+	for (i = 0; i < n_channels; i++) {
+		cmd->channels[i].min_duration =
+			cpu_to_le32(WL1251_SCAN_MIN_DURATION);
+		cmd->channels[i].max_duration =
+			cpu_to_le32(WL1251_SCAN_MAX_DURATION);
+		memset(&cmd->channels[i].bssid_lsb, 0xff, 4);
+		memset(&cmd->channels[i].bssid_msb, 0xff, 2);
+		cmd->channels[i].early_termination = 0;
+		cmd->channels[i].tx_power_att = 0;
+		cmd->channels[i].channel = channels[i]->hw_value;
+	}
+
+	cmd->params.ssid_len = ssid_len;
+	if (ssid)
+		memcpy(cmd->params.ssid, ssid, ssid_len);
+
+	ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd));
+	if (ret < 0) {
+		wl1251_error("cmd scan failed: %d", ret);
+		goto out;
+	}
+
+	wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
+
+	if (cmd->header.status != CMD_STATUS_SUCCESS) {
+		wl1251_error("cmd scan status wasn't success: %d",
+			     cmd->header.status);
+		ret = -EIO;
+		goto out;
+	}
+
+out:
+	kfree(cmd);
+	return ret;
+}
+
+int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout)
+{
+	struct wl1251_cmd_trigger_scan_to *cmd;
+	int ret;
+
+	wl1251_debug(DEBUG_CMD, "cmd trigger scan to");
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->timeout = timeout;
+
+	ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd));
+	if (ret < 0) {
+		wl1251_error("cmd trigger scan to failed: %d", ret);
+		goto out;
+	}
+
 out:
 	kfree(cmd);
 	return ret;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_cmd.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_cmd.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_cmd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_cmd.h	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,8 @@
 
 #include "wl1251.h"
 
+#include <net/cfg80211.h>
+
 struct acx_header;
 
 int wl1251_cmd_send(struct wl1251 *wl, u16 type, void *buf, size_t buf_len);
@@ -43,6 +45,10 @@ int wl1251_cmd_read_memory(struct wl1251
 			   size_t len);
 int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id,
 			    void *buf, size_t buf_len);
+int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
+		    struct ieee80211_channel *channels[],
+		    unsigned int n_channels, unsigned int n_probes);
+int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout);
 
 /* unit ms */
 #define WL1251_COMMAND_TIMEOUT 2000
@@ -163,8 +169,12 @@ struct cmd_read_write_memory {
 #define CMDMBOX_HEADER_LEN 4
 #define CMDMBOX_INFO_ELEM_HEADER_LEN 4
 
+#define WL1251_SCAN_MIN_DURATION 30000
+#define WL1251_SCAN_MAX_DURATION 60000
 
-struct basic_scan_parameters {
+#define WL1251_SCAN_NUM_PROBES 3
+
+struct wl1251_scan_parameters {
 	u32 rx_config_options;
 	u32 rx_filter_options;
 
@@ -189,11 +199,11 @@ struct basic_scan_parameters {
 
 	u8 tid_trigger;
 	u8 ssid_len;
-	u32 ssid[8];
+	u8 ssid[32];
 
 } __attribute__ ((packed));
 
-struct basic_scan_channel_parameters {
+struct wl1251_scan_ch_parameters {
 	u32 min_duration; /* in TU */
 	u32 max_duration; /* in TU */
 	u32 bssid_lsb;
@@ -213,11 +223,11 @@ struct basic_scan_channel_parameters {
 /* SCAN parameters */
 #define SCAN_MAX_NUM_OF_CHANNELS 16
 
-struct cmd_scan {
+struct wl1251_cmd_scan {
 	struct wl1251_cmd_header header;
 
-	struct basic_scan_parameters params;
-	struct basic_scan_channel_parameters channels[SCAN_MAX_NUM_OF_CHANNELS];
+	struct wl1251_scan_parameters params;
+	struct wl1251_scan_ch_parameters channels[SCAN_MAX_NUM_OF_CHANNELS];
 } __attribute__ ((packed));
 
 enum {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_debugfs.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_debugfs.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_debugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_debugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include "wl1251_debugfs.h"
 
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 
 #include "wl1251.h"
 #include "wl1251_acx.h"
@@ -237,6 +238,27 @@ static const struct file_operations tx_q
 	.open = wl1251_open_file_generic,
 };
 
+static ssize_t tx_queue_status_read(struct file *file, char __user *userbuf,
+				    size_t count, loff_t *ppos)
+{
+	struct wl1251 *wl = file->private_data;
+	char buf[3], status;
+	int len;
+
+	if (wl->tx_queue_stopped)
+		status = 's';
+	else
+		status = 'r';
+
+	len = scnprintf(buf, sizeof(buf), "%c\n", status);
+	return simple_read_from_buffer(userbuf, count, ppos, buf, len);
+}
+
+static const struct file_operations tx_queue_status_ops = {
+	.read = tx_queue_status_read,
+	.open = wl1251_open_file_generic,
+};
+
 static void wl1251_debugfs_delete_files(struct wl1251 *wl)
 {
 	DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
@@ -331,6 +353,7 @@ static void wl1251_debugfs_delete_files(
 	DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
 
 	DEBUGFS_DEL(tx_queue_len);
+	DEBUGFS_DEL(tx_queue_status);
 	DEBUGFS_DEL(retry_count);
 	DEBUGFS_DEL(excessive_retries);
 }
@@ -431,6 +454,7 @@ static int wl1251_debugfs_add_files(stru
 	DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
 
 	DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
+	DEBUGFS_ADD(tx_queue_status, wl->debugfs.rootdir);
 	DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
 	DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
 
@@ -443,7 +467,8 @@ out:
 
 void wl1251_debugfs_reset(struct wl1251 *wl)
 {
-	memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
+	if (wl->stats.fw_stats != NULL)
+		memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
 	wl->stats.retry_count = 0;
 	wl->stats.excessive_retries = 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251.h	2013-05-03 12:11:41.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251.h	2013-05-03 09:51:12.000000000 -0400
@@ -247,6 +247,7 @@ struct wl1251_debugfs {
 	struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
 
 	struct dentry *tx_queue_len;
+	struct dentry *tx_queue_status;
 
 	struct dentry *retry_count;
 	struct dentry *excessive_retries;
@@ -340,9 +341,6 @@ struct wl1251 {
 	/* Are we currently scanning */
 	bool scanning;
 
-	/* Our association ID */
-	u16 aid;
-
 	/* Default key (for WEP) */
 	u32 default_key;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_init.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_init.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "wl1251_init.h"
 #include "wl12xx_80211.h"
@@ -294,6 +295,11 @@ static int wl1251_hw_init_tx_queue_confi
 			goto out;
 	}
 
+	wl1251_acx_ac_cfg(wl, AC_BE, CWMIN_BE, CWMAX_BE, AIFS_DIFS, TXOP_BE);
+	wl1251_acx_ac_cfg(wl, AC_BK, CWMIN_BK, CWMAX_BK, AIFS_DIFS, TXOP_BK);
+	wl1251_acx_ac_cfg(wl, AC_VI, CWMIN_VI, CWMAX_VI, AIFS_DIFS, TXOP_VI);
+	wl1251_acx_ac_cfg(wl, AC_VO, CWMIN_VO, CWMAX_VO, AIFS_DIFS, TXOP_VO);
+
 out:
 	kfree(config);
 	return ret;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_init.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_init.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_init.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_init.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,53 @@
 
 #include "wl1251.h"
 
+enum {
+	/* best effort/legacy */
+	AC_BE = 0,
+
+	/* background */
+	AC_BK = 1,
+
+	/* video */
+	AC_VI = 2,
+
+	/* voice */
+	AC_VO = 3,
+
+	/* broadcast dummy access category */
+	AC_BCAST = 4,
+
+	NUM_ACCESS_CATEGORIES = 4
+};
+
+/* following are defult values for the IE fields*/
+#define CWMIN_BK  15
+#define CWMIN_BE  15
+#define CWMIN_VI  7
+#define CWMIN_VO  3
+#define CWMAX_BK  1023
+#define CWMAX_BE  63
+#define CWMAX_VI  15
+#define CWMAX_VO  7
+
+/* slot number setting to start transmission at PIFS interval */
+#define AIFS_PIFS 1
+
+/*
+ * slot number setting to start transmission at DIFS interval - normal DCF
+ * access
+ */
+#define AIFS_DIFS 2
+
+#define AIFSN_BK  7
+#define AIFSN_BE  3
+#define AIFSN_VI  AIFS_PIFS
+#define AIFSN_VO  AIFS_PIFS
+#define TXOP_BK   0
+#define TXOP_BE   0
+#define TXOP_VI   3008
+#define TXOP_VO   1504
+
 int wl1251_hw_init_hwenc_config(struct wl1251 *wl);
 int wl1251_hw_init_templates_config(struct wl1251 *wl);
 int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_main.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_main.c	2013-05-03 12:11:39.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_main.c	2013-05-03 09:51:11.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/crc32.h>
 #include <linux/etherdevice.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include "wl1251.h"
 #include "wl12xx_80211.h"
@@ -395,6 +396,7 @@ static int wl1251_op_tx(struct ieee80211
 	 * the queue here, otherwise the queue will get too long.
 	 */
 	if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) {
+		wl1251_debug(DEBUG_TX, "op_tx: tx_queue full, stop queues");
 		ieee80211_stop_queues(wl->hw);
 
 		/*
@@ -510,13 +512,13 @@ static void wl1251_op_stop(struct ieee80
 }
 
 static int wl1251_op_add_interface(struct ieee80211_hw *hw,
-				   struct ieee80211_if_init_conf *conf)
+				   struct ieee80211_vif *vif)
 {
 	struct wl1251 *wl = hw->priv;
 	int ret = 0;
 
 	wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
-		     conf->type, conf->mac_addr);
+		     vif->type, vif->addr);
 
 	mutex_lock(&wl->mutex);
 	if (wl->vif) {
@@ -524,9 +526,9 @@ static int wl1251_op_add_interface(struc
 		goto out;
 	}
 
-	wl->vif = conf->vif;
+	wl->vif = vif;
 
-	switch (conf->type) {
+	switch (vif->type) {
 	case NL80211_IFTYPE_STATION:
 		wl->bss_type = BSS_TYPE_STA_BSS;
 		break;
@@ -538,8 +540,8 @@ static int wl1251_op_add_interface(struc
 		goto out;
 	}
 
-	if (memcmp(wl->mac_addr, conf->mac_addr, ETH_ALEN)) {
-		memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
+	if (memcmp(wl->mac_addr, vif->addr, ETH_ALEN)) {
+		memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
 		SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
 		ret = wl1251_acx_station_id(wl);
 		if (ret < 0)
@@ -552,7 +554,7 @@ out:
 }
 
 static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
-					 struct ieee80211_if_init_conf *conf)
+					 struct ieee80211_vif *vif)
 {
 	struct wl1251 *wl = hw->priv;
 
@@ -562,43 +564,25 @@ static void wl1251_op_remove_interface(s
 	mutex_unlock(&wl->mutex);
 }
 
-static int wl1251_build_null_data(struct wl1251 *wl)
+static int wl1251_build_qos_null_data(struct wl1251 *wl)
 {
-	struct wl12xx_null_data_template template;
-
-	if (!is_zero_ether_addr(wl->bssid)) {
-		memcpy(template.header.da, wl->bssid, ETH_ALEN);
-		memcpy(template.header.bssid, wl->bssid, ETH_ALEN);
-	} else {
-		memset(template.header.da, 0xff, ETH_ALEN);
-		memset(template.header.bssid, 0xff, ETH_ALEN);
-	}
-
-	memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
-	template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
-						IEEE80211_STYPE_NULLFUNC |
-						IEEE80211_FCTL_TODS);
-
-	return wl1251_cmd_template_set(wl, CMD_NULL_DATA, &template,
-				       sizeof(template));
-
-}
+	struct ieee80211_qos_hdr template;
 
-static int wl1251_build_ps_poll(struct wl1251 *wl, u16 aid)
-{
-	struct wl12xx_ps_poll_template template;
+	memset(&template, 0, sizeof(template));
 
-	memcpy(template.bssid, wl->bssid, ETH_ALEN);
-	memcpy(template.ta, wl->mac_addr, ETH_ALEN);
+	memcpy(template.addr1, wl->bssid, ETH_ALEN);
+	memcpy(template.addr2, wl->mac_addr, ETH_ALEN);
+	memcpy(template.addr3, wl->bssid, ETH_ALEN);
 
-	/* aid in PS-Poll has its two MSBs each set to 1 */
-	template.aid = cpu_to_le16(1 << 15 | 1 << 14 | aid);
+	template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
+					     IEEE80211_STYPE_QOS_NULLFUNC |
+					     IEEE80211_FCTL_TODS);
 
-	template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
+	/* FIXME: not sure what priority to use here */
+	template.qos_ctrl = cpu_to_le16(0);
 
-	return wl1251_cmd_template_set(wl, CMD_PS_POLL, &template,
+	return wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, &template,
 				       sizeof(template));
-
 }
 
 static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
@@ -634,26 +618,34 @@ static int wl1251_op_config(struct ieee8
 
 		wl->psm_requested = true;
 
+		wl->dtim_period = conf->ps_dtim_period;
+
+		ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
+						  wl->dtim_period);
+
 		/*
-		 * We enter PSM only if we're already associated.
-		 * If we're not, we'll enter it when joining an SSID,
-		 * through the bss_info_changed() hook.
+		 * mac80211 enables PSM only if we're already associated.
 		 */
 		ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+		if (ret < 0)
+			goto out_sleep;
 	} else if (!(conf->flags & IEEE80211_CONF_PS) &&
 		   wl->psm_requested) {
 		wl1251_debug(DEBUG_PSM, "psm disabled");
 
 		wl->psm_requested = false;
 
-		if (wl->psm)
+		if (wl->psm) {
 			ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
+			if (ret < 0)
+				goto out_sleep;
+		}
 	}
 
 	if (conf->power_level != wl->power_level) {
 		ret = wl1251_acx_tx_power(wl, conf->power_level);
 		if (ret < 0)
-			goto out;
+			goto out_sleep;
 
 		wl->power_level = conf->power_level;
 	}
@@ -864,199 +856,61 @@ out:
 	return ret;
 }
 
-static int wl1251_build_basic_rates(char *rates)
-{
-	u8 index = 0;
-
-	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
-	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
-	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
-	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
-
-	return index;
-}
-
-static int wl1251_build_extended_rates(char *rates)
-{
-	u8 index = 0;
-
-	rates[index++] = IEEE80211_OFDM_RATE_6MB;
-	rates[index++] = IEEE80211_OFDM_RATE_9MB;
-	rates[index++] = IEEE80211_OFDM_RATE_12MB;
-	rates[index++] = IEEE80211_OFDM_RATE_18MB;
-	rates[index++] = IEEE80211_OFDM_RATE_24MB;
-	rates[index++] = IEEE80211_OFDM_RATE_36MB;
-	rates[index++] = IEEE80211_OFDM_RATE_48MB;
-	rates[index++] = IEEE80211_OFDM_RATE_54MB;
-
-	return index;
-}
-
-
-static int wl1251_build_probe_req(struct wl1251 *wl, u8 *ssid, size_t ssid_len)
-{
-	struct wl12xx_probe_req_template template;
-	struct wl12xx_ie_rates *rates;
-	char *ptr;
-	u16 size;
-
-	ptr = (char *)&template;
-	size = sizeof(struct ieee80211_header);
-
-	memset(template.header.da, 0xff, ETH_ALEN);
-	memset(template.header.bssid, 0xff, ETH_ALEN);
-	memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
-	template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
-
-	/* IEs */
-	/* SSID */
-	template.ssid.header.id = WLAN_EID_SSID;
-	template.ssid.header.len = ssid_len;
-	if (ssid_len && ssid)
-		memcpy(template.ssid.ssid, ssid, ssid_len);
-	size += sizeof(struct wl12xx_ie_header) + ssid_len;
-	ptr += size;
-
-	/* Basic Rates */
-	rates = (struct wl12xx_ie_rates *)ptr;
-	rates->header.id = WLAN_EID_SUPP_RATES;
-	rates->header.len = wl1251_build_basic_rates(rates->rates);
-	size += sizeof(struct wl12xx_ie_header) + rates->header.len;
-	ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
-
-	/* Extended rates */
-	rates = (struct wl12xx_ie_rates *)ptr;
-	rates->header.id = WLAN_EID_EXT_SUPP_RATES;
-	rates->header.len = wl1251_build_extended_rates(rates->rates);
-	size += sizeof(struct wl12xx_ie_header) + rates->header.len;
-
-	wl1251_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
-
-	return wl1251_cmd_template_set(wl, CMD_PROBE_REQ, &template,
-				      size);
-}
-
-static int wl1251_hw_scan(struct wl1251 *wl, u8 *ssid, size_t len,
-			  u8 active_scan, u8 high_prio, u8 num_channels,
-			  u8 probe_requests)
+static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
+			     struct cfg80211_scan_request *req)
 {
-	struct wl1251_cmd_trigger_scan_to *trigger = NULL;
-	struct cmd_scan *params = NULL;
-	int i, ret;
-	u16 scan_options = 0;
-
-	if (wl->scanning)
-		return -EINVAL;
-
-	params = kzalloc(sizeof(*params), GFP_KERNEL);
-	if (!params)
-		return -ENOMEM;
-
-	params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
-	params->params.rx_filter_options =
-		cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
-
-	/* High priority scan */
-	if (!active_scan)
-		scan_options |= SCAN_PASSIVE;
-	if (high_prio)
-		scan_options |= SCAN_PRIORITY_HIGH;
-	params->params.scan_options = scan_options;
+	struct wl1251 *wl = hw->priv;
+	struct sk_buff *skb;
+	size_t ssid_len = 0;
+	u8 *ssid = NULL;
+	int ret;
 
-	params->params.num_channels = num_channels;
-	params->params.num_probe_requests = probe_requests;
-	params->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
-	params->params.tid_trigger = 0;
+	wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
 
-	for (i = 0; i < num_channels; i++) {
-		params->channels[i].min_duration = cpu_to_le32(30000);
-		params->channels[i].max_duration = cpu_to_le32(60000);
-		memset(&params->channels[i].bssid_lsb, 0xff, 4);
-		memset(&params->channels[i].bssid_msb, 0xff, 2);
-		params->channels[i].early_termination = 0;
-		params->channels[i].tx_power_att = 0;
-		params->channels[i].channel = i + 1;
-		memset(params->channels[i].pad, 0, 3);
+	if (req->n_ssids) {
+		ssid = req->ssids[0].ssid;
+		ssid_len = req->ssids[0].ssid_len;
 	}
 
-	for (i = num_channels; i < SCAN_MAX_NUM_OF_CHANNELS; i++)
-		memset(&params->channels[i], 0,
-		       sizeof(struct basic_scan_channel_parameters));
-
-	if (len && ssid) {
-		params->params.ssid_len = len;
-		memcpy(params->params.ssid, ssid, len);
-	} else {
-		params->params.ssid_len = 0;
-		memset(params->params.ssid, 0, 32);
-	}
+	mutex_lock(&wl->mutex);
 
-	ret = wl1251_build_probe_req(wl, ssid, len);
-	if (ret < 0) {
-		wl1251_error("PROBE request template failed");
+	if (wl->scanning) {
+		wl1251_debug(DEBUG_SCAN, "scan already in progress");
+		ret = -EINVAL;
 		goto out;
 	}
 
-	trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
-	if (!trigger)
+	ret = wl1251_ps_elp_wakeup(wl);
+	if (ret < 0)
 		goto out;
 
-	trigger->timeout = 0;
-
-	ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
-			      sizeof(*trigger));
-	if (ret < 0) {
-		wl1251_error("trigger scan to failed for hw scan");
+	skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
+				     req->ie, req->ie_len);
+	if (!skb) {
+		ret = -ENOMEM;
 		goto out;
 	}
 
-	wl1251_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
-
-	wl->scanning = true;
+	ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, skb->data,
+				      skb->len);
+	dev_kfree_skb(skb);
+	if (ret < 0)
+		goto out_sleep;
 
-	ret = wl1251_cmd_send(wl, CMD_SCAN, params, sizeof(*params));
+	ret = wl1251_cmd_trigger_scan_to(wl, 0);
 	if (ret < 0)
-		wl1251_error("SCAN failed");
+		goto out_sleep;
 
-	wl1251_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
+	wl->scanning = true;
 
-	if (params->header.status != CMD_STATUS_SUCCESS) {
-		wl1251_error("TEST command answer error: %d",
-			     params->header.status);
+	ret = wl1251_cmd_scan(wl, ssid, ssid_len, req->channels,
+			      req->n_channels, WL1251_SCAN_NUM_PROBES);
+	if (ret < 0) {
 		wl->scanning = false;
-		ret = -EIO;
-		goto out;
-	}
-
-out:
-	kfree(params);
-	return ret;
-
-}
-
-static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
-			     struct cfg80211_scan_request *req)
-{
-	struct wl1251 *wl = hw->priv;
-	int ret;
-	u8 *ssid = NULL;
-	size_t ssid_len = 0;
-
-	wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
-
-	if (req->n_ssids) {
-		ssid = req->ssids[0].ssid;
-		ssid_len = req->ssids[0].ssid_len;
+		goto out_sleep;
 	}
 
-	mutex_lock(&wl->mutex);
-
-	ret = wl1251_ps_elp_wakeup(wl);
-	if (ret < 0)
-		goto out;
-
-	ret = wl1251_hw_scan(hw->priv, ssid, ssid_len, 1, 0, 13, 3);
-
+out_sleep:
 	wl1251_ps_elp_sleep(wl);
 
 out:
@@ -1093,9 +947,8 @@ static void wl1251_op_bss_info_changed(s
 				       struct ieee80211_bss_conf *bss_conf,
 				       u32 changed)
 {
-	enum wl1251_cmd_ps_mode mode;
 	struct wl1251 *wl = hw->priv;
-	struct sk_buff *beacon;
+	struct sk_buff *beacon, *skb;
 	int ret;
 
 	wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed");
@@ -1109,7 +962,17 @@ static void wl1251_op_bss_info_changed(s
 	if (changed & BSS_CHANGED_BSSID) {
 		memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
 
-		ret = wl1251_build_null_data(wl);
+		skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
+		if (!skb)
+			goto out_sleep;
+
+		ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA,
+					      skb->data, skb->len);
+		dev_kfree_skb(skb);
+		if (ret < 0)
+			goto out_sleep;
+
+		ret = wl1251_build_qos_null_data(wl);
 		if (ret < 0)
 			goto out;
 
@@ -1124,27 +987,21 @@ static void wl1251_op_bss_info_changed(s
 	if (changed & BSS_CHANGED_ASSOC) {
 		if (bss_conf->assoc) {
 			wl->beacon_int = bss_conf->beacon_int;
-			wl->dtim_period = bss_conf->dtim_period;
 
-			ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
-							  wl->dtim_period);
-			wl->aid = bss_conf->aid;
+			skb = ieee80211_pspoll_get(wl->hw, wl->vif);
+			if (!skb)
+				goto out_sleep;
 
-			ret = wl1251_build_ps_poll(wl, wl->aid);
+			ret = wl1251_cmd_template_set(wl, CMD_PS_POLL,
+						      skb->data,
+						      skb->len);
+			dev_kfree_skb(skb);
 			if (ret < 0)
 				goto out_sleep;
 
-			ret = wl1251_acx_aid(wl, wl->aid);
+			ret = wl1251_acx_aid(wl, bss_conf->aid);
 			if (ret < 0)
 				goto out_sleep;
-
-			/* If we want to go in PSM but we're not there yet */
-			if (wl->psm_requested && !wl->psm) {
-				mode = STATION_POWER_SAVE_MODE;
-				ret = wl1251_ps_set_mode(wl, mode);
-				if (ret < 0)
-					goto out_sleep;
-			}
 		} else {
 			/* use defaults when not associated */
 			wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
@@ -1176,7 +1033,7 @@ static void wl1251_op_bss_info_changed(s
 			ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE);
 		if (ret < 0) {
 			wl1251_warning("Set ctsprotect failed %d", ret);
-			goto out;
+			goto out_sleep;
 		}
 	}
 
@@ -1187,7 +1044,7 @@ static void wl1251_op_bss_info_changed(s
 
 		if (ret < 0) {
 			dev_kfree_skb(beacon);
-			goto out;
+			goto out_sleep;
 		}
 
 		ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data,
@@ -1196,13 +1053,13 @@ static void wl1251_op_bss_info_changed(s
 		dev_kfree_skb(beacon);
 
 		if (ret < 0)
-			goto out;
+			goto out_sleep;
 
 		ret = wl1251_join(wl, wl->bss_type, wl->beacon_int,
 				  wl->channel, wl->dtim_period);
 
 		if (ret < 0)
-			goto out;
+			goto out_sleep;
 	}
 
 out_sleep:
@@ -1273,6 +1130,49 @@ static struct ieee80211_channel wl1251_c
 	{ .hw_value = 13, .center_freq = 2472},
 };
 
+static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
+			     const struct ieee80211_tx_queue_params *params)
+{
+	enum wl1251_acx_ps_scheme ps_scheme;
+	struct wl1251 *wl = hw->priv;
+	int ret;
+
+	mutex_lock(&wl->mutex);
+
+	wl1251_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
+
+	ret = wl1251_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	/* mac80211 uses units of 32 usec */
+	ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue),
+				params->cw_min, params->cw_max,
+				params->aifs, params->txop * 32);
+	if (ret < 0)
+		goto out_sleep;
+
+	if (params->uapsd)
+		ps_scheme = WL1251_ACX_PS_SCHEME_UPSD_TRIGGER;
+	else
+		ps_scheme = WL1251_ACX_PS_SCHEME_LEGACY;
+
+	ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue),
+				 CHANNEL_TYPE_EDCF,
+				 wl1251_tx_get_queue(queue), ps_scheme,
+				 WL1251_ACX_ACK_POLICY_LEGACY);
+	if (ret < 0)
+		goto out_sleep;
+
+out_sleep:
+	wl1251_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
 /* can't be const, mac80211 writes to this */
 static struct ieee80211_supported_band wl1251_band_2ghz = {
 	.channels = wl1251_channels,
@@ -1293,6 +1193,7 @@ static const struct ieee80211_ops wl1251
 	.hw_scan = wl1251_op_hw_scan,
 	.bss_info_changed = wl1251_op_bss_info_changed,
 	.set_rts_threshold = wl1251_op_set_rts_threshold,
+	.conf_tx = wl1251_op_conf_tx,
 };
 
 static int wl1251_register_hw(struct wl1251 *wl)
@@ -1332,12 +1233,15 @@ int wl1251_init_ieee80211(struct wl1251
 	wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
 		IEEE80211_HW_NOISE_DBM |
 		IEEE80211_HW_SUPPORTS_PS |
-		IEEE80211_HW_BEACON_FILTER;
+		IEEE80211_HW_BEACON_FILTER |
+		IEEE80211_HW_SUPPORTS_UAPSD;
 
 	wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
 	wl->hw->wiphy->max_scan_ssids = 1;
 	wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz;
 
+	wl->hw->queues = 4;
+
 	ret = wl1251_register_hw(wl);
 	if (ret)
 		goto out;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_ps.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_ps.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_ps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_ps.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,8 @@
 #include "wl1251_cmd.h"
 #include "wl1251_io.h"
 
-#define WL1251_WAKEUP_TIMEOUT 2000
+/* in ms */
+#define WL1251_WAKEUP_TIMEOUT 100
 
 void wl1251_elp_work(struct work_struct *work)
 {
@@ -67,7 +68,7 @@ void wl1251_ps_elp_sleep(struct wl1251 *
 
 int wl1251_ps_elp_wakeup(struct wl1251 *wl)
 {
-	unsigned long timeout;
+	unsigned long timeout, start;
 	u32 elp_reg;
 
 	if (!wl->elp)
@@ -75,6 +76,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *
 
 	wl1251_debug(DEBUG_PSM, "waking up chip from elp");
 
+	start = jiffies;
 	timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT);
 
 	wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
@@ -95,8 +97,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *
 	}
 
 	wl1251_debug(DEBUG_PSM, "wakeup time: %u ms",
-		     jiffies_to_msecs(jiffies) -
-		     (jiffies_to_msecs(timeout) - WL1251_WAKEUP_TIMEOUT));
+		     jiffies_to_msecs(jiffies - start));
 
 	wl->elp = false;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_rx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_rx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
  */
 
 #include <linux/skbuff.h>
+#include <linux/gfp.h>
 #include <net/mac80211.h>
 
 #include "wl1251.h"
@@ -126,7 +127,7 @@ static void wl1251_rx_body(struct wl1251
 	if (wl->rx_current_buffer)
 		rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
 
-	skb = dev_alloc_skb(length);
+	skb = __dev_alloc_skb(length, GFP_KERNEL);
 	if (!skb) {
 		wl1251_error("Couldn't allocate RX frame");
 		return;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_spi.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_spi.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_spi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 
 #include <linux/irq.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/crc7.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/wl12xx.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_tx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_tx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -167,8 +167,7 @@ static int wl1251_tx_fill_hdr(struct wl1
 	tx_hdr->expiry_time = cpu_to_le32(1 << 16);
 	tx_hdr->id = id;
 
-	/* FIXME: how to get the correct queue id? */
-	tx_hdr->xmit_queue = 0;
+	tx_hdr->xmit_queue = wl1251_tx_get_queue(skb_get_queue_mapping(skb));
 
 	wl1251_tx_control(tx_hdr, control, fc);
 	wl1251_tx_frag_block_num(tx_hdr);
@@ -220,6 +219,7 @@ static int wl1251_tx_send_packet(struct
 			/* align the buffer on a 4-byte boundary */
 			skb_reserve(skb, offset);
 			memmove(skb->data, src, skb->len);
+			tx_hdr = (struct tx_double_buffer_desc *) skb->data;
 		} else {
 			wl1251_info("No handler, fixme!");
 			return -EINVAL;
@@ -237,8 +237,9 @@ static int wl1251_tx_send_packet(struct
 
 	wl1251_mem_write(wl, addr, skb->data, len);
 
-	wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x",
-		     tx_hdr->id, skb, tx_hdr->length, tx_hdr->rate);
+	wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x "
+		     "queue %d", tx_hdr->id, skb, tx_hdr->length,
+		     tx_hdr->rate, tx_hdr->xmit_queue);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_tx.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_tx.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_tx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1251_tx.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #define __WL1251_TX_H__
 
 #include <linux/bitops.h>
+#include "wl1251_acx.h"
 
 /*
  *
@@ -209,6 +210,22 @@ struct tx_result {
 	u8 done_2;
 } __attribute__ ((packed));
 
+static inline int wl1251_tx_get_queue(int queue)
+{
+	switch (queue) {
+	case 0:
+		return QOS_AC_VO;
+	case 1:
+		return QOS_AC_VI;
+	case 2:
+		return QOS_AC_BE;
+	case 3:
+		return QOS_AC_BK;
+	default:
+		return QOS_AC_BE;
+	}
+}
+
 void wl1251_tx_work(struct work_struct *work);
 void wl1251_tx_complete(struct wl1251 *wl);
 void wl1251_tx_flush(struct wl1251 *wl);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/platform_device.h>
 #include <linux/crc7.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 
 #include "wl1271.h"
 #include "wl12xx_80211.h"
@@ -390,6 +391,35 @@ out:
 	return ret;
 }
 
+int wl1271_acx_dco_itrim_params(struct wl1271 *wl)
+{
+	struct acx_dco_itrim_params *dco;
+	struct conf_itrim_settings *c = &wl->conf.itrim;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx dco itrim parameters");
+
+	dco = kzalloc(sizeof(*dco), GFP_KERNEL);
+	if (!dco) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	dco->enable = c->enable;
+	dco->timeout = cpu_to_le32(c->timeout);
+
+	ret = wl1271_cmd_configure(wl, ACX_SET_DCO_ITRIM_PARAMS,
+				   dco, sizeof(*dco));
+	if (ret < 0) {
+		wl1271_warning("failed to set dco itrim parameters: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(dco);
+	return ret;
+}
+
 int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter)
 {
 	struct acx_beacon_filter_option *beacon_filter = NULL;
@@ -758,10 +788,11 @@ int wl1271_acx_statistics(struct wl1271
 	return 0;
 }
 
-int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates)
+int wl1271_acx_rate_policies(struct wl1271 *wl)
 {
 	struct acx_rate_policy *acx;
 	struct conf_tx_rate_class *c = &wl->conf.tx.rc_conf;
+	int idx = 0;
 	int ret = 0;
 
 	wl1271_debug(DEBUG_ACX, "acx rate policies");
@@ -773,12 +804,21 @@ int wl1271_acx_rate_policies(struct wl12
 		goto out;
 	}
 
-	/* configure one default (one-size-fits-all) rate class */
-	acx->rate_class_cnt = cpu_to_le32(1);
-	acx->rate_class[0].enabled_rates = cpu_to_le32(enabled_rates);
-	acx->rate_class[0].short_retry_limit = c->short_retry_limit;
-	acx->rate_class[0].long_retry_limit = c->long_retry_limit;
-	acx->rate_class[0].aflags = c->aflags;
+	/* configure one basic rate class */
+	idx = ACX_TX_BASIC_RATE;
+	acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate_set);
+	acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
+	acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
+	acx->rate_class[idx].aflags = c->aflags;
+
+	/* configure one AP supported rate class */
+	idx = ACX_TX_AP_FULL_RATE;
+	acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->rate_set);
+	acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
+	acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
+	acx->rate_class[idx].aflags = c->aflags;
+
+	acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT);
 
 	ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
 	if (ret < 0) {
@@ -791,12 +831,14 @@ out:
 	return ret;
 }
 
-int wl1271_acx_ac_cfg(struct wl1271 *wl)
+int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max,
+		      u8 aifsn, u16 txop)
 {
 	struct acx_ac_cfg *acx;
-	int i, ret = 0;
+	int ret = 0;
 
-	wl1271_debug(DEBUG_ACX, "acx access category config");
+	wl1271_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
+		     "aifs %d txop %d", ac, cw_min, cw_max, aifsn, txop);
 
 	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 
@@ -805,21 +847,16 @@ int wl1271_acx_ac_cfg(struct wl1271 *wl)
 		goto out;
 	}
 
-	for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
-		struct conf_tx_ac_category *c = &(wl->conf.tx.ac_conf[i]);
-		acx->ac = c->ac;
-		acx->cw_min = c->cw_min;
-		acx->cw_max = cpu_to_le16(c->cw_max);
-		acx->aifsn = c->aifsn;
-		acx->reserved = 0;
-		acx->tx_op_limit = cpu_to_le16(c->tx_op_limit);
+	acx->ac = ac;
+	acx->cw_min = cw_min;
+	acx->cw_max = cpu_to_le16(cw_max);
+	acx->aifsn = aifsn;
+	acx->tx_op_limit = cpu_to_le16(txop);
 
-		ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
-		if (ret < 0) {
-			wl1271_warning("Setting of access category "
-				       "config: %d", ret);
-			goto out;
-		}
+	ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("acx ac cfg failed: %d", ret);
+		goto out;
 	}
 
 out:
@@ -827,10 +864,12 @@ out:
 	return ret;
 }
 
-int wl1271_acx_tid_cfg(struct wl1271 *wl)
+int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
+		       u8 tsid, u8 ps_scheme, u8 ack_policy,
+		       u32 apsd_conf0, u32 apsd_conf1)
 {
 	struct acx_tid_config *acx;
-	int i, ret = 0;
+	int ret = 0;
 
 	wl1271_debug(DEBUG_ACX, "acx tid config");
 
@@ -841,21 +880,18 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl
 		goto out;
 	}
 
-	for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
-		struct conf_tx_tid *c = &(wl->conf.tx.tid_conf[i]);
-		acx->queue_id = c->queue_id;
-		acx->channel_type = c->channel_type;
-		acx->tsid = c->tsid;
-		acx->ps_scheme = c->ps_scheme;
-		acx->ack_policy = c->ack_policy;
-		acx->apsd_conf[0] = cpu_to_le32(c->apsd_conf[0]);
-		acx->apsd_conf[1] = cpu_to_le32(c->apsd_conf[1]);
+	acx->queue_id = queue_id;
+	acx->channel_type = channel_type;
+	acx->tsid = tsid;
+	acx->ps_scheme = ps_scheme;
+	acx->ack_policy = ack_policy;
+	acx->apsd_conf[0] = cpu_to_le32(apsd_conf0);
+	acx->apsd_conf[1] = cpu_to_le32(apsd_conf1);
 
-		ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
-		if (ret < 0) {
-			wl1271_warning("Setting of tid config failed: %d", ret);
-			goto out;
-		}
+	ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("Setting of tid config failed: %d", ret);
+		goto out;
 	}
 
 out:
@@ -1012,59 +1048,6 @@ out:
 	return ret;
 }
 
-int wl1271_acx_smart_reflex(struct wl1271 *wl)
-{
-	struct acx_smart_reflex_state *sr_state = NULL;
-	struct acx_smart_reflex_config_params *sr_param = NULL;
-	int i, ret;
-
-	wl1271_debug(DEBUG_ACX, "acx smart reflex");
-
-	sr_param = kzalloc(sizeof(*sr_param), GFP_KERNEL);
-	if (!sr_param) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	for (i = 0; i < CONF_SR_ERR_TBL_COUNT; i++) {
-		struct conf_mart_reflex_err_table *e =
-			&(wl->conf.init.sr_err_tbl[i]);
-
-		sr_param->error_table[i].len = e->len;
-		sr_param->error_table[i].upper_limit = e->upper_limit;
-		memcpy(sr_param->error_table[i].values, e->values, e->len);
-	}
-
-	ret = wl1271_cmd_configure(wl, ACX_SET_SMART_REFLEX_PARAMS,
-				   sr_param, sizeof(*sr_param));
-	if (ret < 0) {
-		wl1271_warning("failed to set smart reflex params: %d", ret);
-		goto out;
-	}
-
-	sr_state = kzalloc(sizeof(*sr_state), GFP_KERNEL);
-	if (!sr_state) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	/* enable smart reflex */
-	sr_state->enable = wl->conf.init.sr_enable;
-
-	ret = wl1271_cmd_configure(wl, ACX_SET_SMART_REFLEX_STATE,
-				   sr_state, sizeof(*sr_state));
-	if (ret < 0) {
-		wl1271_warning("failed to set smart reflex params: %d", ret);
-		goto out;
-	}
-
-out:
-	kfree(sr_state);
-	kfree(sr_param);
-	return ret;
-
-}
-
 int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable)
 {
 	struct wl1271_acx_bet_enable *acx = NULL;
@@ -1128,6 +1111,34 @@ int wl1271_acx_arp_ip_filter(struct wl12
 		goto out;
 	}
 
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1271_acx_pm_config(struct wl1271 *wl)
+{
+	struct wl1271_acx_pm_config *acx = NULL;
+	struct  conf_pm_config_settings *c = &wl->conf.pm_config;
+	int ret = 0;
+
+	wl1271_debug(DEBUG_ACX, "acx pm config");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->host_clk_settling_time = cpu_to_le32(c->host_clk_settling_time);
+	acx->host_fast_wakeup_support = c->host_fast_wakeup_support;
+
+	ret = wl1271_cmd_configure(wl, ACX_PM_CONFIG, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("acx pm config failed: %d", ret);
+		goto out;
+	}
+
 out:
 	kfree(acx);
 	return ret;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  * This file is part of wl1271
  *
  * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
- * Copyright (C) 2008-2009 Nokia Corporation
+ * Copyright (C) 2008-2010 Nokia Corporation
  *
  * Contact: Luciano Coelho <luciano.coelho@nokia.com>
  *
@@ -348,7 +348,7 @@ struct acx_beacon_filter_option {
  * ACXBeaconFilterEntry (not 221)
  * Byte Offset     Size (Bytes)    Definition
  * ===========     ============    ==========
- * 0				1               IE identifier
+ * 0               1               IE identifier
  * 1               1               Treatment bit mask
  *
  * ACXBeaconFilterEntry (221)
@@ -381,8 +381,8 @@ struct acx_beacon_filter_ie_table {
 	struct acx_header header;
 
 	u8 num_ie;
-	u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
 	u8 pad[3];
+	u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
 } __attribute__ ((packed));
 
 struct acx_conn_monit_params {
@@ -415,23 +415,12 @@ struct acx_bt_wlan_coex {
 	u8 pad[3];
 } __attribute__ ((packed));
 
-struct acx_smart_reflex_state {
+struct acx_dco_itrim_params {
 	struct acx_header header;
 
 	u8 enable;
 	u8 padding[3];
-} __attribute__ ((packed));
-
-struct smart_reflex_err_table {
-	u8 len;
-	s8 upper_limit;
-	s8 values[14];
-} __attribute__ ((packed));
-
-struct acx_smart_reflex_config_params {
-	struct acx_header header;
-
-	struct smart_reflex_err_table error_table[3];
+	__le32 timeout;
 } __attribute__ ((packed));
 
 #define PTA_ANTENNA_TYPE_DEF		  (0)
@@ -837,6 +826,9 @@ struct acx_rate_class {
 	u8 reserved;
 };
 
+#define ACX_TX_BASIC_RATE      0
+#define ACX_TX_AP_FULL_RATE    1
+#define ACX_TX_RATE_POLICY_CNT 2
 struct acx_rate_policy {
 	struct acx_header header;
 
@@ -877,8 +869,8 @@ struct acx_tx_config_options {
 	__le16 tx_compl_threshold;   /* number of packets */
 } __attribute__ ((packed));
 
-#define ACX_RX_MEM_BLOCKS     64
-#define ACX_TX_MIN_MEM_BLOCKS 64
+#define ACX_RX_MEM_BLOCKS     70
+#define ACX_TX_MIN_MEM_BLOCKS 40
 #define ACX_TX_DESCRIPTORS    32
 #define ACX_NUM_SSID_PROFILES 1
 
@@ -969,6 +961,13 @@ struct wl1271_acx_arp_filter {
 			       used. */
 } __attribute__((packed));
 
+struct wl1271_acx_pm_config {
+	struct acx_header header;
+
+	__le32 host_clk_settling_time;
+	u8 host_fast_wakeup_support;
+	u8 padding[3];
+} __attribute__ ((packed));
 
 enum {
 	ACX_WAKE_UP_CONDITIONS      = 0x0002,
@@ -1027,13 +1026,13 @@ enum {
 	ACX_HT_BSS_OPERATION        = 0x0058,
 	ACX_COEX_ACTIVITY           = 0x0059,
 	ACX_SET_SMART_REFLEX_DEBUG  = 0x005A,
-	ACX_SET_SMART_REFLEX_STATE  = 0x005B,
-	ACX_SET_SMART_REFLEX_PARAMS = 0x005F,
+	ACX_SET_DCO_ITRIM_PARAMS    = 0x0061,
 	DOT11_RX_MSDU_LIFE_TIME     = 0x1004,
 	DOT11_CUR_TX_PWR            = 0x100D,
 	DOT11_RX_DOT11_MODE         = 0x1012,
 	DOT11_RTS_THRESHOLD         = 0x1013,
 	DOT11_GROUP_ADDRESS_TBL     = 0x1014,
+	ACX_PM_CONFIG               = 0x1016,
 
 	MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,
 
@@ -1056,6 +1055,7 @@ int wl1271_acx_group_address_tbl(struct
 				 void *mc_list, u32 mc_list_len);
 int wl1271_acx_service_period_timeout(struct wl1271 *wl);
 int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold);
+int wl1271_acx_dco_itrim_params(struct wl1271 *wl);
 int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter);
 int wl1271_acx_beacon_filter_table(struct wl1271 *wl);
 int wl1271_acx_conn_monit_params(struct wl1271 *wl);
@@ -1069,9 +1069,12 @@ int wl1271_acx_set_preamble(struct wl127
 int wl1271_acx_cts_protect(struct wl1271 *wl,
 			   enum acx_ctsprotect_type ctsprotect);
 int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats);
-int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates);
-int wl1271_acx_ac_cfg(struct wl1271 *wl);
-int wl1271_acx_tid_cfg(struct wl1271 *wl);
+int wl1271_acx_rate_policies(struct wl1271 *wl);
+int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max,
+		      u8 aifsn, u16 txop);
+int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
+		       u8 tsid, u8 ps_scheme, u8 ack_policy,
+		       u32 apsd_conf0, u32 apsd_conf1);
 int wl1271_acx_frag_threshold(struct wl1271 *wl);
 int wl1271_acx_tx_config_options(struct wl1271 *wl);
 int wl1271_acx_mem_cfg(struct wl1271 *wl);
@@ -1081,5 +1084,6 @@ int wl1271_acx_smart_reflex(struct wl127
 int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable);
 int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address,
 			     u8 version);
+int wl1271_acx_pm_config(struct wl1271 *wl);
 
 #endif /* __WL1271_ACX_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_boot.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_boot.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_boot.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_boot.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,11 +22,13 @@
  */
 
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include "wl1271_acx.h"
 #include "wl1271_reg.h"
 #include "wl1271_boot.h"
 #include "wl1271_spi.h"
+#include "wl1271_io.h"
 #include "wl1271_event.h"
 
 static struct wl1271_partition_set part_table[PART_TABLE_LEN] = {
@@ -93,19 +95,19 @@ static void wl1271_boot_set_ecpu_ctrl(st
 	u32 cpu_ctrl;
 
 	/* 10.5.0 run the firmware (I) */
-	cpu_ctrl = wl1271_spi_read32(wl, ACX_REG_ECPU_CONTROL);
+	cpu_ctrl = wl1271_read32(wl, ACX_REG_ECPU_CONTROL);
 
 	/* 10.5.1 run the firmware (II) */
 	cpu_ctrl |= flag;
-	wl1271_spi_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
+	wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
 }
 
 static void wl1271_boot_fw_version(struct wl1271 *wl)
 {
 	struct wl1271_static_data static_data;
 
-	wl1271_spi_read(wl, wl->cmd_box_addr,
-			&static_data, sizeof(static_data), false);
+	wl1271_read(wl, wl->cmd_box_addr, &static_data, sizeof(static_data),
+		    false);
 
 	strncpy(wl->chip.fw_ver, static_data.fw_version,
 		sizeof(wl->chip.fw_ver));
@@ -164,7 +166,7 @@ static int wl1271_boot_upload_firmware_c
 		memcpy(chunk, p, CHUNK_SIZE);
 		wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
 			     p, addr);
-		wl1271_spi_write(wl, addr, chunk, CHUNK_SIZE, false);
+		wl1271_write(wl, addr, chunk, CHUNK_SIZE, false);
 
 		chunk_num++;
 	}
@@ -175,7 +177,7 @@ static int wl1271_boot_upload_firmware_c
 	memcpy(chunk, p, fw_data_len % CHUNK_SIZE);
 	wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x",
 		     fw_data_len % CHUNK_SIZE, p, addr);
-	wl1271_spi_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false);
+	wl1271_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false);
 
 	kfree(chunk);
 	return 0;
@@ -219,23 +221,14 @@ static int wl1271_boot_upload_nvs(struct
 	size_t nvs_len, burst_len;
 	int i;
 	u32 dest_addr, val;
-	u8 *nvs_ptr, *nvs, *nvs_aligned;
+	u8 *nvs_ptr, *nvs_aligned;
 
-	nvs = wl->nvs;
-	if (nvs == NULL)
+	if (wl->nvs == NULL)
 		return -ENODEV;
 
-	nvs_ptr = nvs;
-
-	nvs_len = wl->nvs_len;
-
-	/* Update the device MAC address into the nvs */
-	nvs[11] = wl->mac_addr[0];
-	nvs[10] = wl->mac_addr[1];
-	nvs[6] = wl->mac_addr[2];
-	nvs[5] = wl->mac_addr[3];
-	nvs[4] = wl->mac_addr[4];
-	nvs[3] = wl->mac_addr[5];
+	/* only the first part of the NVS needs to be uploaded */
+	nvs_len = sizeof(wl->nvs->nvs);
+	nvs_ptr = (u8 *)wl->nvs->nvs;
 
 	/*
 	 * Layout before the actual NVS tables:
@@ -265,7 +258,7 @@ static int wl1271_boot_upload_nvs(struct
 			wl1271_debug(DEBUG_BOOT,
 				     "nvs burst write 0x%x: 0x%x",
 				     dest_addr, val);
-			wl1271_spi_write32(wl, dest_addr, val);
+			wl1271_write32(wl, dest_addr, val);
 
 			nvs_ptr += 4;
 			dest_addr += 4;
@@ -277,7 +270,7 @@ static int wl1271_boot_upload_nvs(struct
 	 * is 7 bytes further.
 	 */
 	nvs_ptr += 7;
-	nvs_len -= nvs_ptr - nvs;
+	nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs;
 	nvs_len = ALIGN(nvs_len, 4);
 
 	/* FIXME: The driver sets the partition here, but this is not needed,
@@ -286,15 +279,20 @@ static int wl1271_boot_upload_nvs(struct
 	wl1271_set_partition(wl, &part_table[PART_WORK]);
 
 	/* Copy the NVS tables to a new block to ensure alignment */
-	nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
-	if (!nvs_aligned)
-		return -ENOMEM;
+	/* FIXME: We jump 3 more bytes before uploading the NVS.  It seems
+	that our NVS files have three extra zeros here.  I'm not sure whether
+	the problem is in our NVS generation or we should really jumpt these
+	3 bytes here */
+	nvs_ptr += 3;
+
+	nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); if
+	(!nvs_aligned) return -ENOMEM;
 
 	/* And finally we upload the NVS tables */
 	/* FIXME: In wl1271, we upload everything at once.
 	   No endianness handling needed here?! The ref driver doesn't do
 	   anything about it at this point */
-	wl1271_spi_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false);
+	wl1271_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false);
 
 	kfree(nvs_aligned);
 	return 0;
@@ -303,9 +301,9 @@ static int wl1271_boot_upload_nvs(struct
 static void wl1271_boot_enable_interrupts(struct wl1271 *wl)
 {
 	enable_irq(wl->irq);
-	wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK,
-			   WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
-	wl1271_spi_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
+	wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
+		       WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
+	wl1271_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
 }
 
 static int wl1271_boot_soft_reset(struct wl1271 *wl)
@@ -314,13 +312,12 @@ static int wl1271_boot_soft_reset(struct
 	u32 boot_data;
 
 	/* perform soft reset */
-	wl1271_spi_write32(wl, ACX_REG_SLV_SOFT_RESET,
-			   ACX_SLV_SOFT_RESET_BIT);
+	wl1271_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
 
 	/* SOFT_RESET is self clearing */
 	timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
 	while (1) {
-		boot_data = wl1271_spi_read32(wl, ACX_REG_SLV_SOFT_RESET);
+		boot_data = wl1271_read32(wl, ACX_REG_SLV_SOFT_RESET);
 		wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
 		if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
 			break;
@@ -336,10 +333,10 @@ static int wl1271_boot_soft_reset(struct
 	}
 
 	/* disable Rx/Tx */
-	wl1271_spi_write32(wl, ENABLE, 0x0);
+	wl1271_write32(wl, ENABLE, 0x0);
 
 	/* disable auto calibration on start*/
-	wl1271_spi_write32(wl, SPARE_A2, 0xffff);
+	wl1271_write32(wl, SPARE_A2, 0xffff);
 
 	return 0;
 }
@@ -351,7 +348,7 @@ static int wl1271_boot_run_firmware(stru
 
 	wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
 
-	chip_id = wl1271_spi_read32(wl, CHIP_ID_B);
+	chip_id = wl1271_read32(wl, CHIP_ID_B);
 
 	wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
 
@@ -364,8 +361,7 @@ static int wl1271_boot_run_firmware(stru
 	loop = 0;
 	while (loop++ < INIT_LOOP) {
 		udelay(INIT_LOOP_DELAY);
-		interrupt = wl1271_spi_read32(wl,
-					      ACX_REG_INTERRUPT_NO_CLEAR);
+		interrupt = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
 
 		if (interrupt == 0xffffffff) {
 			wl1271_error("error reading hardware complete "
@@ -374,8 +370,8 @@ static int wl1271_boot_run_firmware(stru
 		}
 		/* check that ACX_INTR_INIT_COMPLETE is enabled */
 		else if (interrupt & WL1271_ACX_INTR_INIT_COMPLETE) {
-			wl1271_spi_write32(wl, ACX_REG_INTERRUPT_ACK,
-					   WL1271_ACX_INTR_INIT_COMPLETE);
+			wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
+				       WL1271_ACX_INTR_INIT_COMPLETE);
 			break;
 		}
 	}
@@ -387,10 +383,10 @@ static int wl1271_boot_run_firmware(stru
 	}
 
 	/* get hardware config command mail box */
-	wl->cmd_box_addr = wl1271_spi_read32(wl, REG_COMMAND_MAILBOX_PTR);
+	wl->cmd_box_addr = wl1271_read32(wl, REG_COMMAND_MAILBOX_PTR);
 
 	/* get hardware config event mail box */
-	wl->event_box_addr = wl1271_spi_read32(wl, REG_EVENT_MAILBOX_PTR);
+	wl->event_box_addr = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR);
 
 	/* set the working partition to its "running" mode offset */
 	wl1271_set_partition(wl, &part_table[PART_WORK]);
@@ -463,9 +459,9 @@ int wl1271_boot(struct wl1271 *wl)
 		wl1271_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
 	}
 
-	wl1271_spi_write32(wl, PLL_PARAMETERS, clk);
+	wl1271_write32(wl, PLL_PARAMETERS, clk);
 
-	pause = wl1271_spi_read32(wl, PLL_PARAMETERS);
+	pause = wl1271_read32(wl, PLL_PARAMETERS);
 
 	wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
 
@@ -474,10 +470,10 @@ int wl1271_boot(struct wl1271 *wl)
 					   * 0x3ff (magic number ).  How does
 					   * this work?! */
 	pause |= WU_COUNTER_PAUSE_VAL;
-	wl1271_spi_write32(wl, WU_COUNTER_PAUSE, pause);
+	wl1271_write32(wl, WU_COUNTER_PAUSE, pause);
 
 	/* Continue the ELP wake up sequence */
-	wl1271_spi_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
+	wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
 	udelay(500);
 
 	wl1271_set_partition(wl, &part_table[PART_DRPW]);
@@ -487,18 +483,18 @@ int wl1271_boot(struct wl1271 *wl)
 	   before taking DRPw out of reset */
 
 	wl1271_debug(DEBUG_BOOT, "DRPW_SCRATCH_START %08x", DRPW_SCRATCH_START);
-	clk = wl1271_spi_read32(wl, DRPW_SCRATCH_START);
+	clk = wl1271_read32(wl, DRPW_SCRATCH_START);
 
 	wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
 
 	/* 2 */
 	clk |= (REF_CLOCK << 1) << 4;
-	wl1271_spi_write32(wl, DRPW_SCRATCH_START, clk);
+	wl1271_write32(wl, DRPW_SCRATCH_START, clk);
 
 	wl1271_set_partition(wl, &part_table[PART_WORK]);
 
 	/* Disable interrupts */
-	wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
+	wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
 
 	ret = wl1271_boot_soft_reset(wl);
 	if (ret < 0)
@@ -513,23 +509,22 @@ int wl1271_boot(struct wl1271 *wl)
 	 * ACX_EEPROMLESS_IND_REG */
 	wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
 
-	wl1271_spi_write32(wl, ACX_EEPROMLESS_IND_REG,
-			   ACX_EEPROMLESS_IND_REG);
+	wl1271_write32(wl, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG);
 
-	tmp = wl1271_spi_read32(wl, CHIP_ID_B);
+	tmp = wl1271_read32(wl, CHIP_ID_B);
 
 	wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
 
 	/* 6. read the EEPROM parameters */
-	tmp = wl1271_spi_read32(wl, SCR_PAD2);
+	tmp = wl1271_read32(wl, SCR_PAD2);
 
 	ret = wl1271_boot_write_irq_polarity(wl);
 	if (ret < 0)
 		goto out;
 
 	/* FIXME: Need to check whether this is really what we want */
-	wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK,
-			   WL1271_ACX_ALL_EVENTS_VECTOR);
+	wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
+		       WL1271_ACX_ALL_EVENTS_VECTOR);
 
 	/* WL1271: The reference driver skips steps 7 to 10 (jumps directly
 	 * to upload_fw) */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,10 +26,12 @@
 #include <linux/crc7.h>
 #include <linux/spi/spi.h>
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 
 #include "wl1271.h"
 #include "wl1271_reg.h"
 #include "wl1271_spi.h"
+#include "wl1271_io.h"
 #include "wl1271_acx.h"
 #include "wl12xx_80211.h"
 #include "wl1271_cmd.h"
@@ -57,13 +59,13 @@ int wl1271_cmd_send(struct wl1271 *wl, u
 
 	WARN_ON(len % 4 != 0);
 
-	wl1271_spi_write(wl, wl->cmd_box_addr, buf, len, false);
+	wl1271_write(wl, wl->cmd_box_addr, buf, len, false);
 
-	wl1271_spi_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
+	wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
 
 	timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT);
 
-	intr = wl1271_spi_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+	intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
 	while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) {
 		if (time_after(jiffies, timeout)) {
 			wl1271_error("command complete timeout");
@@ -73,13 +75,13 @@ int wl1271_cmd_send(struct wl1271 *wl, u
 
 		msleep(1);
 
-		intr = wl1271_spi_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+		intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
 	}
 
 	/* read back the status code of the command */
 	if (res_len == 0)
 		res_len = sizeof(struct wl1271_cmd_header);
-	wl1271_spi_read(wl, wl->cmd_box_addr, cmd, res_len, false);
+	wl1271_read(wl, wl->cmd_box_addr, cmd, res_len, false);
 
 	status = le16_to_cpu(cmd->status);
 	if (status != CMD_STATUS_SUCCESS) {
@@ -87,8 +89,8 @@ int wl1271_cmd_send(struct wl1271 *wl, u
 		ret = -EIO;
 	}
 
-	wl1271_spi_write32(wl, ACX_REG_INTERRUPT_ACK,
-			   WL1271_ACX_INTR_CMD_COMPLETE);
+	wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
+		       WL1271_ACX_INTR_CMD_COMPLETE);
 
 out:
 	return ret;
@@ -191,23 +193,19 @@ static int wl1271_cmd_cal(struct wl1271
 int wl1271_cmd_general_parms(struct wl1271 *wl)
 {
 	struct wl1271_general_parms_cmd *gen_parms;
-	struct conf_general_parms *g = &wl->conf.init.genparam;
 	int ret;
 
+	if (!wl->nvs)
+		return -ENODEV;
+
 	gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
 	if (!gen_parms)
 		return -ENOMEM;
 
 	gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
 
-	gen_parms->ref_clk = g->ref_clk;
-	gen_parms->settling_time = g->settling_time;
-	gen_parms->clk_valid_on_wakeup = g->clk_valid_on_wakeup;
-	gen_parms->dc2dcmode = g->dc2dcmode;
-	gen_parms->single_dual_band = g->single_dual_band;
-	gen_parms->tx_bip_fem_autodetect = g->tx_bip_fem_autodetect;
-	gen_parms->tx_bip_fem_manufacturer = g->tx_bip_fem_manufacturer;
-	gen_parms->settings = g->settings;
+	memcpy(gen_parms->params, wl->nvs->general_params,
+	       WL1271_NVS_GENERAL_PARAMS_SIZE);
 
 	ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0);
 	if (ret < 0)
@@ -220,8 +218,11 @@ int wl1271_cmd_general_parms(struct wl12
 int wl1271_cmd_radio_parms(struct wl1271 *wl)
 {
 	struct wl1271_radio_parms_cmd *radio_parms;
-	struct conf_radio_parms *r = &wl->conf.init.radioparam;
-	int i, ret;
+	struct conf_radio_parms *rparam = &wl->conf.init.radioparam;
+	int ret;
+
+	if (!wl->nvs)
+		return -ENODEV;
 
 	radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
 	if (!radio_parms)
@@ -229,60 +230,13 @@ int wl1271_cmd_radio_parms(struct wl1271
 
 	radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
 
-	/* Static radio parameters */
-	radio_parms->rx_trace_loss = r->rx_trace_loss;
-	radio_parms->tx_trace_loss = r->tx_trace_loss;
-	memcpy(radio_parms->rx_rssi_and_proc_compens,
-	       r->rx_rssi_and_proc_compens,
-	       CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE);
-
-	memcpy(radio_parms->rx_trace_loss_5, r->rx_trace_loss_5,
-	       CONF_NUMBER_OF_SUB_BANDS_5);
-	memcpy(radio_parms->tx_trace_loss_5, r->tx_trace_loss_5,
-	       CONF_NUMBER_OF_SUB_BANDS_5);
-	memcpy(radio_parms->rx_rssi_and_proc_compens_5,
-	       r->rx_rssi_and_proc_compens_5,
-	       CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE);
-
-	/* Dynamic radio parameters */
-	radio_parms->tx_ref_pd_voltage = cpu_to_le16(r->tx_ref_pd_voltage);
-	radio_parms->tx_ref_power = r->tx_ref_power;
-	radio_parms->tx_offset_db = r->tx_offset_db;
-
-	memcpy(radio_parms->tx_rate_limits_normal, r->tx_rate_limits_normal,
-	       CONF_NUMBER_OF_RATE_GROUPS);
-	memcpy(radio_parms->tx_rate_limits_degraded, r->tx_rate_limits_degraded,
-	       CONF_NUMBER_OF_RATE_GROUPS);
-
-	memcpy(radio_parms->tx_channel_limits_11b, r->tx_channel_limits_11b,
-	       CONF_NUMBER_OF_CHANNELS_2_4);
-	memcpy(radio_parms->tx_channel_limits_ofdm, r->tx_channel_limits_ofdm,
-	       CONF_NUMBER_OF_CHANNELS_2_4);
-	memcpy(radio_parms->tx_pdv_rate_offsets, r->tx_pdv_rate_offsets,
-	       CONF_NUMBER_OF_RATE_GROUPS);
-	memcpy(radio_parms->tx_ibias, r->tx_ibias, CONF_NUMBER_OF_RATE_GROUPS);
-
-	radio_parms->rx_fem_insertion_loss = r->rx_fem_insertion_loss;
+	memcpy(radio_parms->stat_radio_params, wl->nvs->stat_radio_params,
+	       WL1271_NVS_STAT_RADIO_PARAMS_SIZE);
+	memcpy(radio_parms->dyn_radio_params,
+	       wl->nvs->dyn_radio_params[rparam->fem],
+	       WL1271_NVS_DYN_RADIO_PARAMS_SIZE);
 
-	for (i = 0; i < CONF_NUMBER_OF_SUB_BANDS_5; i++)
-		radio_parms->tx_ref_pd_voltage_5[i] =
-			cpu_to_le16(r->tx_ref_pd_voltage_5[i]);
-	memcpy(radio_parms->tx_ref_power_5, r->tx_ref_power_5,
-	       CONF_NUMBER_OF_SUB_BANDS_5);
-	memcpy(radio_parms->tx_offset_db_5, r->tx_offset_db_5,
-	       CONF_NUMBER_OF_SUB_BANDS_5);
-	memcpy(radio_parms->tx_rate_limits_normal_5,
-	       r->tx_rate_limits_normal_5, CONF_NUMBER_OF_RATE_GROUPS);
-	memcpy(radio_parms->tx_rate_limits_degraded_5,
-	       r->tx_rate_limits_degraded_5, CONF_NUMBER_OF_RATE_GROUPS);
-	memcpy(radio_parms->tx_channel_limits_ofdm_5,
-	       r->tx_channel_limits_ofdm_5, CONF_NUMBER_OF_CHANNELS_5);
-	memcpy(radio_parms->tx_pdv_rate_offsets_5, r->tx_pdv_rate_offsets_5,
-	       CONF_NUMBER_OF_RATE_GROUPS);
-	memcpy(radio_parms->tx_ibias_5, r->tx_ibias_5,
-	       CONF_NUMBER_OF_RATE_GROUPS);
-	memcpy(radio_parms->rx_fem_insertion_loss_5,
-	       r->rx_fem_insertion_loss_5, CONF_NUMBER_OF_SUB_BANDS_5);
+	/* FIXME: current NVS is missing 5GHz parameters */
 
 	wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
 		    radio_parms, sizeof(*radio_parms));
@@ -311,19 +265,6 @@ int wl1271_cmd_join(struct wl1271 *wl)
 			do_cal = false;
 	}
 
-	/* FIXME: This is a workaround, because with the current stack, we
-	 * cannot know when we have disassociated.  So, if we have already
-	 * joined, we disconnect before joining again. */
-	if (wl->joined) {
-		ret = wl1271_cmd_disconnect(wl);
-		if (ret < 0) {
-			wl1271_error("failed to disconnect before rejoining");
-			goto out;
-		}
-
-		wl->joined = false;
-	}
-
 	join = kzalloc(sizeof(*join), GFP_KERNEL);
 	if (!join) {
 		ret = -ENOMEM;
@@ -388,8 +329,6 @@ int wl1271_cmd_join(struct wl1271 *wl)
 		goto out_free;
 	}
 
-	wl->joined = true;
-
 	/*
 	 * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to
 	 * simplify locking we just sleep instead, for now
@@ -487,7 +426,7 @@ int wl1271_cmd_configure(struct wl1271 *
 	return 0;
 }
 
-int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable)
+int wl1271_cmd_data_path(struct wl1271 *wl, bool enable)
 {
 	struct cmd_enabledisable_path *cmd;
 	int ret;
@@ -501,7 +440,8 @@ int wl1271_cmd_data_path(struct wl1271 *
 		goto out;
 	}
 
-	cmd->channel = channel;
+	/* the channel here is only used for calibration, so hardcoded to 1 */
+	cmd->channel = 1;
 
 	if (enable) {
 		cmd_rx = CMD_ENABLE_RX;
@@ -514,29 +454,29 @@ int wl1271_cmd_data_path(struct wl1271 *
 	ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd), 0);
 	if (ret < 0) {
 		wl1271_error("rx %s cmd for channel %d failed",
-			     enable ? "start" : "stop", channel);
+			     enable ? "start" : "stop", cmd->channel);
 		goto out;
 	}
 
 	wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d",
-		     enable ? "start" : "stop", channel);
+		     enable ? "start" : "stop", cmd->channel);
 
 	ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd), 0);
 	if (ret < 0) {
 		wl1271_error("tx %s cmd for channel %d failed",
-			     enable ? "start" : "stop", channel);
+			     enable ? "start" : "stop", cmd->channel);
 		return ret;
 	}
 
 	wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d",
-		     enable ? "start" : "stop", channel);
+		     enable ? "start" : "stop", cmd->channel);
 
 out:
 	kfree(cmd);
 	return ret;
 }
 
-int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
+int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send)
 {
 	struct wl1271_cmd_ps_params *ps_params = NULL;
 	int ret = 0;
@@ -557,7 +497,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl
 	}
 
 	ps_params->ps_mode = ps_mode;
-	ps_params->send_null_data = 1;
+	ps_params->send_null_data = send;
 	ps_params->retries = 5;
 	ps_params->hang_over_period = 128;
 	ps_params->null_data_rate = cpu_to_le32(1); /* 1 Mbps */
@@ -636,7 +576,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, u
 	channels = wl->hw->wiphy->bands[ieee_band]->channels;
 	n_ch = wl->hw->wiphy->bands[ieee_band]->n_channels;
 
-	if (wl->scanning)
+	if (test_bit(WL1271_FLAG_SCANNING, &wl->flags))
 		return -EINVAL;
 
 	params = kzalloc(sizeof(*params), GFP_KERNEL);
@@ -711,7 +651,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, u
 
 	wl1271_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
 
-	wl->scanning = true;
+	set_bit(WL1271_FLAG_SCANNING, &wl->flags);
 	if (wl1271_11a_enabled()) {
 		wl->scan.state = band;
 		if (band == WL1271_SCAN_BAND_DUAL) {
@@ -729,7 +669,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, u
 	ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params), 0);
 	if (ret < 0) {
 		wl1271_error("SCAN failed");
-		wl->scanning = false;
+		clear_bit(WL1271_FLAG_SCANNING, &wl->flags);
 		goto out;
 	}
 
@@ -1003,7 +943,7 @@ int wl1271_cmd_set_key(struct wl1271 *wl
 	ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
 	if (ret < 0) {
 		wl1271_warning("could not set keys");
-		goto out;
+	goto out;
 	}
 
 out:
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.h	2010-05-16 17:17:36.000000000 -0400
@@ -37,8 +37,8 @@ int wl1271_cmd_join(struct wl1271 *wl);
 int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
 int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
 int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
-int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable);
-int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode);
+int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
+int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send);
 int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
 			   size_t len);
 int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
@@ -428,67 +428,24 @@ struct wl1271_general_parms_cmd {
 
 	struct wl1271_cmd_test_header test;
 
-	u8 ref_clk;
-	u8 settling_time;
-	u8 clk_valid_on_wakeup;
-	u8 dc2dcmode;
-	u8 single_dual_band;
-
-	u8 tx_bip_fem_autodetect;
-	u8 tx_bip_fem_manufacturer;
-	u8 settings;
+	u8 params[WL1271_NVS_GENERAL_PARAMS_SIZE];
+	s8 reserved[23];
 } __attribute__ ((packed));
 
+#define WL1271_STAT_RADIO_PARAMS_5_SIZE    29
+#define WL1271_DYN_RADIO_PARAMS_5_SIZE    104
+
 struct wl1271_radio_parms_cmd {
 	struct wl1271_cmd_header header;
 
 	struct wl1271_cmd_test_header test;
 
-	/* Static radio parameters */
-	/* 2.4GHz */
-	u8 rx_trace_loss;
-	u8 tx_trace_loss;
-	s8 rx_rssi_and_proc_compens[CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE];
-
-	/* 5GHz */
-	u8 rx_trace_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
-	u8 tx_trace_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
-	s8 rx_rssi_and_proc_compens_5[CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE];
-
-	/* Dynamic radio parameters */
-	/* 2.4GHz */
-	__le16 tx_ref_pd_voltage;
-	s8  tx_ref_power;
-	s8  tx_offset_db;
-
-	s8  tx_rate_limits_normal[CONF_NUMBER_OF_RATE_GROUPS];
-	s8  tx_rate_limits_degraded[CONF_NUMBER_OF_RATE_GROUPS];
-
-	s8  tx_channel_limits_11b[CONF_NUMBER_OF_CHANNELS_2_4];
-	s8  tx_channel_limits_ofdm[CONF_NUMBER_OF_CHANNELS_2_4];
-	s8  tx_pdv_rate_offsets[CONF_NUMBER_OF_RATE_GROUPS];
-
-	u8  tx_ibias[CONF_NUMBER_OF_RATE_GROUPS];
-	u8  rx_fem_insertion_loss;
-
-	u8 padding2;
-
-	/* 5GHz */
-	__le16 tx_ref_pd_voltage_5[CONF_NUMBER_OF_SUB_BANDS_5];
-	s8  tx_ref_power_5[CONF_NUMBER_OF_SUB_BANDS_5];
-	s8  tx_offset_db_5[CONF_NUMBER_OF_SUB_BANDS_5];
-
-	s8  tx_rate_limits_normal_5[CONF_NUMBER_OF_RATE_GROUPS];
-	s8  tx_rate_limits_degraded_5[CONF_NUMBER_OF_RATE_GROUPS];
-
-	s8  tx_channel_limits_ofdm_5[CONF_NUMBER_OF_CHANNELS_5];
-	s8  tx_pdv_rate_offsets_5[CONF_NUMBER_OF_RATE_GROUPS];
-
-	/* FIXME: this is inconsistent with the types for 2.4GHz */
-	s8  tx_ibias_5[CONF_NUMBER_OF_RATE_GROUPS];
-	s8  rx_fem_insertion_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
+	u8 stat_radio_params[WL1271_NVS_STAT_RADIO_PARAMS_SIZE];
+	u8 stat_radio_params_5[WL1271_STAT_RADIO_PARAMS_5_SIZE];
 
-	u8 padding3[2];
+	u8 dyn_radio_params[WL1271_NVS_DYN_RADIO_PARAMS_SIZE];
+	u8 reserved;
+	u8 dyn_radio_params_5[WL1271_DYN_RADIO_PARAMS_5_SIZE];
 } __attribute__ ((packed));
 
 struct wl1271_cmd_cal_channel_tune {
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_conf.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_conf.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_conf.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_conf.h	2010-05-16 17:17:36.000000000 -0400
@@ -258,7 +258,8 @@ struct conf_rx_settings {
 #define CONF_TX_MAX_RATE_CLASSES       8
 
 #define CONF_TX_RATE_MASK_UNSPECIFIED  0
-#define CONF_TX_RATE_MASK_ALL          0x1eff
+#define CONF_TX_RATE_MASK_BASIC        (CONF_HW_BIT_RATE_1MBPS | \
+					CONF_HW_BIT_RATE_2MBPS)
 #define CONF_TX_RATE_RETRY_LIMIT       10
 
 struct conf_tx_rate_class {
@@ -722,31 +723,6 @@ struct conf_conn_settings {
 	u8 psm_entry_retries;
 };
 
-#define CONF_SR_ERR_TBL_MAX_VALUES   14
-
-struct conf_mart_reflex_err_table {
-	/*
-	 * Length of the error table values table.
-	 *
-	 * Range: 0 - CONF_SR_ERR_TBL_MAX_VALUES
-	 */
-	u8 len;
-
-	/*
-	 * Smart Reflex error table upper limit.
-	 *
-	 * Range: s8
-	 */
-	s8 upper_limit;
-
-	/*
-	 * Smart Reflex error table values.
-	 *
-	 * Range: s8
-	 */
-	s8 values[CONF_SR_ERR_TBL_MAX_VALUES];
-};
-
 enum {
 	CONF_REF_CLK_19_2_E,
 	CONF_REF_CLK_26_E,
@@ -759,64 +735,6 @@ enum single_dual_band_enum {
 	CONF_DUAL_BAND
 };
 
-struct conf_general_parms {
-	/*
-	 * RF Reference Clock type / speed
-	 *
-	 * Range: CONF_REF_CLK_*
-	 */
-	u8 ref_clk;
-
-	/*
-	 * Settling time of the reference clock after boot.
-	 *
-	 * Range: u8
-	 */
-	u8 settling_time;
-
-	/*
-	 * Flag defining whether clock is valid on wakeup.
-	 *
-	 * Range: 0 - not valid on wakeup, 1 - valid on wakeup
-	 */
-	u8 clk_valid_on_wakeup;
-
-	/*
-	 * DC-to-DC mode.
-	 *
-	 * Range: Unknown
-	 */
-	u8 dc2dcmode;
-
-	/*
-	 * Flag defining whether used as single or dual-band.
-	 *
-	 * Range: CONF_SINGLE_BAND, CONF_DUAL_BAND
-	 */
-	u8 single_dual_band;
-
-	/*
-	 * TX bip fem autodetect flag.
-	 *
-	 * Range: Unknown
-	 */
-	u8 tx_bip_fem_autodetect;
-
-	/*
-	 * TX bip gem manufacturer.
-	 *
-	 * Range: Unknown
-	 */
-	u8 tx_bip_fem_manufacturer;
-
-	/*
-	 * Settings flags.
-	 *
-	 * Range: Unknown
-	 */
-	u8 settings;
-};
-
 #define CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE 15
 #define CONF_NUMBER_OF_SUB_BANDS_5  7
 #define CONF_NUMBER_OF_RATE_GROUPS  6
@@ -825,87 +743,43 @@ struct conf_general_parms {
 
 struct conf_radio_parms {
 	/*
-	 * Static radio parameters for 2.4GHz
-	 *
-	 * Range: unknown
-	 */
-	u8 rx_trace_loss;
-	u8 tx_trace_loss;
-	s8 rx_rssi_and_proc_compens[CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE];
-
-	/*
-	 * Static radio parameters for 5GHz
-	 *
-	 * Range: unknown
-	 */
-	u8 rx_trace_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
-	u8 tx_trace_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
-	s8 rx_rssi_and_proc_compens_5[CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE];
-
-	/*
-	 * Dynamic radio parameters for 2.4GHz
+	 * FEM parameter set to use
 	 *
-	 * Range: unknown
+	 * Range: 0 or 1
 	 */
-	s16 tx_ref_pd_voltage;
-	s8  tx_ref_power;
-	s8  tx_offset_db;
-
-	s8  tx_rate_limits_normal[CONF_NUMBER_OF_RATE_GROUPS];
-	s8  tx_rate_limits_degraded[CONF_NUMBER_OF_RATE_GROUPS];
-
-	s8  tx_channel_limits_11b[CONF_NUMBER_OF_CHANNELS_2_4];
-	s8  tx_channel_limits_ofdm[CONF_NUMBER_OF_CHANNELS_2_4];
-	s8  tx_pdv_rate_offsets[CONF_NUMBER_OF_RATE_GROUPS];
-
-	u8  tx_ibias[CONF_NUMBER_OF_RATE_GROUPS];
-	u8  rx_fem_insertion_loss;
+	u8 fem;
+};
 
+struct conf_init_settings {
 	/*
-	 * Dynamic radio parameters for 5GHz
-	 *
-	 * Range: unknown
+	 * Configure radio parameters.
 	 */
-	s16 tx_ref_pd_voltage_5[CONF_NUMBER_OF_SUB_BANDS_5];
-	s8  tx_ref_power_5[CONF_NUMBER_OF_SUB_BANDS_5];
-	s8  tx_offset_db_5[CONF_NUMBER_OF_SUB_BANDS_5];
-
-	s8  tx_rate_limits_normal_5[CONF_NUMBER_OF_RATE_GROUPS];
-	s8  tx_rate_limits_degraded_5[CONF_NUMBER_OF_RATE_GROUPS];
-
-	s8  tx_channel_limits_ofdm_5[CONF_NUMBER_OF_CHANNELS_5];
-	s8  tx_pdv_rate_offsets_5[CONF_NUMBER_OF_RATE_GROUPS];
+	struct conf_radio_parms radioparam;
 
-	/* FIXME: this is inconsistent with the types for 2.4GHz */
-	s8  tx_ibias_5[CONF_NUMBER_OF_RATE_GROUPS];
-	s8  rx_fem_insertion_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
 };
 
-#define CONF_SR_ERR_TBL_COUNT        3
+struct conf_itrim_settings {
+	/* enable dco itrim */
+	u8 enable;
 
-struct conf_init_settings {
-	/*
-	 * Configure Smart Reflex error table values.
-	 */
-	struct conf_mart_reflex_err_table sr_err_tbl[CONF_SR_ERR_TBL_COUNT];
+	/* moderation timeout in microsecs from the last TX */
+	u32 timeout;
+};
 
+struct conf_pm_config_settings {
 	/*
-	 * Smart Reflex enable flag.
+	 * Host clock settling time
 	 *
-	 * Range: 1 - Smart Reflex enabled, 0 - Smart Reflex disabled
-	 */
-	u8 sr_enable;
-
-	/*
-	 * Configure general parameters.
+	 * Range: 0 - 30000 us
 	 */
-	struct conf_general_parms genparam;
+	u32 host_clk_settling_time;
 
 	/*
-	 * Configure radio parameters.
+	 * Host fast wakeup support
+	 *
+	 * Range: true, false
 	 */
-	struct conf_radio_parms radioparam;
-
+	bool host_fast_wakeup_support;
 };
 
 struct conf_drv_settings {
@@ -914,6 +788,8 @@ struct conf_drv_settings {
 	struct conf_tx_settings tx;
 	struct conf_conn_settings conn;
 	struct conf_init_settings init;
+	struct conf_itrim_settings itrim;
+	struct conf_pm_config_settings pm_config;
 };
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_debugfs.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_debugfs.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_debugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_debugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include "wl1271_debugfs.h"
 
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 
 #include "wl1271.h"
 #include "wl1271_acx.h"
@@ -237,6 +238,64 @@ static const struct file_operations tx_q
 	.open = wl1271_open_file_generic,
 };
 
+static ssize_t gpio_power_read(struct file *file, char __user *user_buf,
+			  size_t count, loff_t *ppos)
+{
+	struct wl1271 *wl = file->private_data;
+	bool state = test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
+
+	int res;
+	char buf[10];
+
+	res = scnprintf(buf, sizeof(buf), "%d\n", state);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, res);
+}
+
+static ssize_t gpio_power_write(struct file *file,
+			   const char __user *user_buf,
+			   size_t count, loff_t *ppos)
+{
+	struct wl1271 *wl = file->private_data;
+	char buf[10];
+	size_t len;
+	unsigned long value;
+	int ret;
+
+	mutex_lock(&wl->mutex);
+
+	len = min(count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, len)) {
+		ret = -EFAULT;
+		goto out;
+	}
+	buf[len] = '\0';
+
+	ret = strict_strtoul(buf, 0, &value);
+	if (ret < 0) {
+		wl1271_warning("illegal value in gpio_power");
+		goto out;
+	}
+
+	if (value) {
+		wl->set_power(true);
+		set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
+	} else {
+		wl->set_power(false);
+		clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
+	}
+
+out:
+	mutex_unlock(&wl->mutex);
+	return count;
+}
+
+static const struct file_operations gpio_power_ops = {
+	.read = gpio_power_read,
+	.write = gpio_power_write,
+	.open = wl1271_open_file_generic
+};
+
 static void wl1271_debugfs_delete_files(struct wl1271 *wl)
 {
 	DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
@@ -333,6 +392,8 @@ static void wl1271_debugfs_delete_files(
 	DEBUGFS_DEL(tx_queue_len);
 	DEBUGFS_DEL(retry_count);
 	DEBUGFS_DEL(excessive_retries);
+
+	DEBUGFS_DEL(gpio_power);
 }
 
 static int wl1271_debugfs_add_files(struct wl1271 *wl)
@@ -434,6 +495,8 @@ static int wl1271_debugfs_add_files(stru
 	DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
 	DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
 
+	DEBUGFS_ADD(gpio_power, wl->debugfs.rootdir);
+
 out:
 	if (ret < 0)
 		wl1271_debugfs_delete_files(wl);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_event.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_event.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_event.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_event.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include "wl1271.h"
 #include "wl1271_reg.h"
 #include "wl1271_spi.h"
+#include "wl1271_io.h"
 #include "wl1271_event.h"
 #include "wl1271_ps.h"
 #include "wl12xx_80211.h"
@@ -35,7 +36,7 @@ static int wl1271_event_scan_complete(st
 	wl1271_debug(DEBUG_EVENT, "status: 0x%x",
 		     mbox->scheduled_scan_status);
 
-	if (wl->scanning) {
+	if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) {
 		if (wl->scan.state == WL1271_SCAN_BAND_DUAL) {
 			wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
 						NULL, size);
@@ -43,7 +44,7 @@ static int wl1271_event_scan_complete(st
 			 * to the wl1271_cmd_scan function that we are not
 			 * scanning as it checks that.
 			 */
-			wl->scanning = false;
+			clear_bit(WL1271_FLAG_SCANNING, &wl->flags);
 			wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len,
 						wl->scan.active,
 						wl->scan.high_prio,
@@ -62,7 +63,7 @@ static int wl1271_event_scan_complete(st
 			mutex_unlock(&wl->mutex);
 			ieee80211_scan_completed(wl->hw, false);
 			mutex_lock(&wl->mutex);
-			wl->scanning = false;
+			clear_bit(WL1271_FLAG_SCANNING, &wl->flags);
 		}
 	}
 	return 0;
@@ -78,25 +79,61 @@ static int wl1271_event_ps_report(struct
 
 	switch (mbox->ps_status) {
 	case EVENT_ENTER_POWER_SAVE_FAIL:
-		if (!wl->psm) {
+		wl1271_debug(DEBUG_PSM, "PSM entry failed");
+
+		if (!test_bit(WL1271_FLAG_PSM, &wl->flags)) {
+			/* remain in active mode */
 			wl->psm_entry_retry = 0;
 			break;
 		}
 
 		if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) {
 			wl->psm_entry_retry++;
-			ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+			ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
+						 true);
 		} else {
 			wl1271_error("PSM entry failed, giving up.\n");
+			/* FIXME: this may need to be reconsidered. for now it
+			   is not possible to indicate to the mac80211
+			   afterwards that PSM entry failed. To maximize
+			   functionality (receiving data and remaining
+			   associated) make sure that we are in sync with the
+			   AP in regard of PSM mode. */
+			ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
+						 false);
 			wl->psm_entry_retry = 0;
-			*beacon_loss = true;
 		}
 		break;
 	case EVENT_ENTER_POWER_SAVE_SUCCESS:
 		wl->psm_entry_retry = 0;
+
+		/* enable beacon filtering */
+		ret = wl1271_acx_beacon_filter_opt(wl, true);
+		if (ret < 0)
+			break;
+
+		/* enable beacon early termination */
+		ret = wl1271_acx_bet_enable(wl, true);
+		if (ret < 0)
+			break;
+
+		/* go to extremely low power mode */
+		wl1271_ps_elp_sleep(wl);
+		if (ret < 0)
+			break;
 		break;
 	case EVENT_EXIT_POWER_SAVE_FAIL:
-		wl1271_info("PSM exit failed");
+		wl1271_debug(DEBUG_PSM, "PSM exit failed");
+
+		if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {
+			wl->psm_entry_retry = 0;
+			break;
+		}
+
+		/* make sure the firmware goes to active mode - the frame to
+		   be sent next will indicate to the AP, that we are active. */
+		ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
+					 false);
 		break;
 	case EVENT_EXIT_POWER_SAVE_SUCCESS:
 	default:
@@ -136,7 +173,8 @@ static int wl1271_event_process(struct w
 	 * filtering) is enabled. Without PSM, the stack will receive all
 	 * beacons and can detect beacon loss by itself.
 	 */
-	if (vector & BSS_LOSE_EVENT_ID && wl->psm) {
+	if (vector & BSS_LOSE_EVENT_ID &&
+	    test_bit(WL1271_FLAG_PSM, &wl->flags)) {
 		wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
 
 		/* indicate to the stack, that beacons have been lost */
@@ -150,7 +188,7 @@ static int wl1271_event_process(struct w
 			return ret;
 	}
 
-	if (beacon_loss) {
+	if (wl->vif && beacon_loss) {
 		/* Obviously, it's dangerous to release the mutex while
 		   we are holding many of the variables in the wl struct.
 		   That's why it's done last in the function, and care must
@@ -177,14 +215,14 @@ int wl1271_event_unmask(struct wl1271 *w
 
 void wl1271_event_mbox_config(struct wl1271 *wl)
 {
-	wl->mbox_ptr[0] = wl1271_spi_read32(wl, REG_EVENT_MAILBOX_PTR);
+	wl->mbox_ptr[0] = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR);
 	wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
 
 	wl1271_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
 		     wl->mbox_ptr[0], wl->mbox_ptr[1]);
 }
 
-int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num, bool do_ack)
+int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
 {
 	struct event_mailbox mbox;
 	int ret;
@@ -195,8 +233,8 @@ int wl1271_event_handle(struct wl1271 *w
 		return -EINVAL;
 
 	/* first we read the mbox descriptor */
-	wl1271_spi_read(wl, wl->mbox_ptr[mbox_num], &mbox,
-			sizeof(struct event_mailbox), false);
+	wl1271_read(wl, wl->mbox_ptr[mbox_num], &mbox,
+		    sizeof(struct event_mailbox), false);
 
 	/* process the descriptor */
 	ret = wl1271_event_process(wl, &mbox);
@@ -204,9 +242,7 @@ int wl1271_event_handle(struct wl1271 *w
 		return ret;
 
 	/* then we let the firmware know it can go on...*/
-	if (do_ack)
-		wl1271_spi_write32(wl, ACX_REG_INTERRUPT_TRIG,
-				   INTR_TRIG_EVENT_ACK);
+	wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_event.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_event.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_event.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_event.h	2010-05-16 17:17:36.000000000 -0400
@@ -112,6 +112,6 @@ struct event_mailbox {
 
 int wl1271_event_unmask(struct wl1271 *wl);
 void wl1271_event_mbox_config(struct wl1271 *wl);
-int wl1271_event_handle(struct wl1271 *wl, u8 mbox, bool do_ack);
+int wl1271_event_handle(struct wl1271 *wl, u8 mbox);
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271.h	2013-05-03 12:11:45.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271.h	2013-05-03 09:51:17.000000000 -0400
@@ -43,7 +43,7 @@ enum {
 	DEBUG_SPI	= BIT(1),
 	DEBUG_BOOT	= BIT(2),
 	DEBUG_MAILBOX	= BIT(3),
-	DEBUG_NETLINK	= BIT(4),
+	DEBUG_TESTMODE	= BIT(4),
 	DEBUG_EVENT	= BIT(5),
 	DEBUG_TX	= BIT(6),
 	DEBUG_RX	= BIT(7),
@@ -107,11 +107,36 @@ enum {
 				  CFG_RX_CTL_EN | CFG_RX_BCN_EN |     \
 				  CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
 
-#define WL1271_DEFAULT_BASIC_RATE_SET (CONF_TX_RATE_MASK_ALL)
-
 #define WL1271_FW_NAME "/*(DEBLOBBED)*/"
 #define WL1271_NVS_NAME "/*(DEBLOBBED)*/"
 
+/* NVS data structure */
+#define WL1271_NVS_SECTION_SIZE                  468
+
+#define WL1271_NVS_GENERAL_PARAMS_SIZE            57
+#define WL1271_NVS_GENERAL_PARAMS_SIZE_PADDED \
+	(WL1271_NVS_GENERAL_PARAMS_SIZE + 1)
+#define WL1271_NVS_STAT_RADIO_PARAMS_SIZE         17
+#define WL1271_NVS_STAT_RADIO_PARAMS_SIZE_PADDED \
+	(WL1271_NVS_STAT_RADIO_PARAMS_SIZE + 1)
+#define WL1271_NVS_DYN_RADIO_PARAMS_SIZE          65
+#define WL1271_NVS_DYN_RADIO_PARAMS_SIZE_PADDED \
+	(WL1271_NVS_DYN_RADIO_PARAMS_SIZE + 1)
+#define WL1271_NVS_FEM_COUNT                       2
+#define WL1271_NVS_INI_SPARE_SIZE                124
+
+struct wl1271_nvs_file {
+	/* NVS section */
+	u8 nvs[WL1271_NVS_SECTION_SIZE];
+
+	/* INI section */
+	u8 general_params[WL1271_NVS_GENERAL_PARAMS_SIZE_PADDED];
+	u8 stat_radio_params[WL1271_NVS_STAT_RADIO_PARAMS_SIZE_PADDED];
+	u8 dyn_radio_params[WL1271_NVS_FEM_COUNT]
+			   [WL1271_NVS_DYN_RADIO_PARAMS_SIZE_PADDED];
+	u8 ini_spare[WL1271_NVS_INI_SPARE_SIZE];
+} __attribute__ ((packed));
+
 /*
  * Enable/disable 802.11a support for WL1273
  */
@@ -276,6 +301,7 @@ struct wl1271_debugfs {
 
 	struct dentry *retry_count;
 	struct dentry *excessive_retries;
+	struct dentry *gpio_power;
 };
 
 #define NUM_TX_QUEUES              4
@@ -322,6 +348,17 @@ struct wl1271 {
 	enum wl1271_state state;
 	struct mutex mutex;
 
+#define WL1271_FLAG_STA_RATES_CHANGED  (0)
+#define WL1271_FLAG_STA_ASSOCIATED     (1)
+#define WL1271_FLAG_JOINED             (2)
+#define WL1271_FLAG_GPIO_POWER         (3)
+#define WL1271_FLAG_TX_QUEUE_STOPPED   (4)
+#define WL1271_FLAG_SCANNING           (5)
+#define WL1271_FLAG_IN_ELP             (6)
+#define WL1271_FLAG_PSM                (7)
+#define WL1271_FLAG_PSM_REQUESTED      (8)
+	unsigned long flags;
+
 	struct wl1271_partition_set part;
 
 	struct wl1271_chip chip;
@@ -331,8 +368,7 @@ struct wl1271 {
 
 	u8 *fw;
 	size_t fw_len;
-	u8 *nvs;
-	size_t nvs_len;
+	struct wl1271_nvs_file *nvs;
 
 	u8 bssid[ETH_ALEN];
 	u8 mac_addr[ETH_ALEN];
@@ -359,7 +395,6 @@ struct wl1271 {
 
 	/* Frames scheduled for transmission, not handled yet */
 	struct sk_buff_head tx_queue;
-	bool tx_queue_stopped;
 
 	struct work_struct tx_work;
 
@@ -387,14 +422,15 @@ struct wl1271 {
 	u32 mbox_ptr[2];
 
 	/* Are we currently scanning */
-	bool scanning;
 	struct wl1271_scan scan;
 
 	/* Our association ID */
 	u16 aid;
 
 	/* currently configured rate set */
+	u32 sta_rate_set;
 	u32 basic_rate_set;
+	u32 rate_set;
 
 	/* The current band */
 	enum ieee80211_band band;
@@ -405,18 +441,9 @@ struct wl1271 {
 	unsigned int rx_config;
 	unsigned int rx_filter;
 
-	/* is firmware in elp mode */
-	bool elp;
-
 	struct completion *elp_compl;
 	struct delayed_work elp_work;
 
-	/* we can be in psm, but not in elp, we have to differentiate */
-	bool psm;
-
-	/* PSM mode requested */
-	bool psm_requested;
-
 	/* retry counter for PSM entries */
 	u8 psm_entry_retry;
 
@@ -435,9 +462,6 @@ struct wl1271 {
 
 	struct ieee80211_vif *vif;
 
-	/* Used for a workaround to send disconnect before rejoining */
-	bool joined;
-
 	/* Current chipset configuration */
 	struct conf_drv_settings conf;
 
@@ -455,11 +479,14 @@ int wl1271_plt_stop(struct wl1271 *wl);
 
 #define WL1271_TX_QUEUE_MAX_LENGTH 20
 
-/* WL1271 needs a 200ms sleep after power on */
+/* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power
+   on in case is has been shut down shortly before */
+#define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */
 #define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */
 
 static inline bool wl1271_11a_enabled(void)
 {
+	/* FIXME: this could be determined based on the NVS-INI file */
 #ifdef WL1271_80211A_ENABLED
 	return true;
 #else
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_init.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_init.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "wl1271_init.h"
 #include "wl12xx_80211.h"
@@ -49,7 +50,7 @@ static int wl1271_init_hwenc_config(stru
 	return 0;
 }
 
-static int wl1271_init_templates_config(struct wl1271 *wl)
+int wl1271_init_templates_config(struct wl1271 *wl)
 {
 	int ret;
 
@@ -113,7 +114,7 @@ static int wl1271_init_rx_config(struct
 	return 0;
 }
 
-static int wl1271_init_phy_config(struct wl1271 *wl)
+int wl1271_init_phy_config(struct wl1271 *wl)
 {
 	int ret;
 
@@ -156,7 +157,7 @@ static int wl1271_init_beacon_filter(str
 	return 0;
 }
 
-static int wl1271_init_pta(struct wl1271 *wl)
+int wl1271_init_pta(struct wl1271 *wl)
 {
 	int ret;
 
@@ -171,7 +172,7 @@ static int wl1271_init_pta(struct wl1271
 	return 0;
 }
 
-static int wl1271_init_energy_detection(struct wl1271 *wl)
+int wl1271_init_energy_detection(struct wl1271 *wl)
 {
 	int ret;
 
@@ -195,7 +196,9 @@ static int wl1271_init_beacon_broadcast(
 
 int wl1271_hw_init(struct wl1271 *wl)
 {
-	int ret;
+	struct conf_tx_ac_category *conf_ac;
+	struct conf_tx_tid *conf_tid;
+	int ret, i;
 
 	ret = wl1271_cmd_general_parms(wl);
 	if (ret < 0)
@@ -229,6 +232,10 @@ int wl1271_hw_init(struct wl1271 *wl)
 	if (ret < 0)
 		goto out_free_memmap;
 
+	ret = wl1271_acx_dco_itrim_params(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
 	/* Initialize connection monitoring thresholds */
 	ret = wl1271_acx_conn_monit_params(wl);
 	if (ret < 0)
@@ -270,22 +277,36 @@ int wl1271_hw_init(struct wl1271 *wl)
 		goto out_free_memmap;
 
 	/* Default TID configuration */
-	ret = wl1271_acx_tid_cfg(wl);
-	if (ret < 0)
-		goto out_free_memmap;
+	for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
+		conf_tid = &wl->conf.tx.tid_conf[i];
+		ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id,
+					 conf_tid->channel_type,
+					 conf_tid->tsid,
+					 conf_tid->ps_scheme,
+					 conf_tid->ack_policy,
+					 conf_tid->apsd_conf[0],
+					 conf_tid->apsd_conf[1]);
+		if (ret < 0)
+			goto out_free_memmap;
+	}
 
 	/* Default AC configuration */
-	ret = wl1271_acx_ac_cfg(wl);
-	if (ret < 0)
-		goto out_free_memmap;
+	for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
+		conf_ac = &wl->conf.tx.ac_conf[i];
+		ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
+					conf_ac->cw_max, conf_ac->aifsn,
+					conf_ac->tx_op_limit);
+		if (ret < 0)
+			goto out_free_memmap;
+	}
 
 	/* Configure TX rate classes */
-	ret = wl1271_acx_rate_policies(wl, CONF_TX_RATE_MASK_ALL);
+	ret = wl1271_acx_rate_policies(wl);
 	if (ret < 0)
 		goto out_free_memmap;
 
 	/* Enable data path */
-	ret = wl1271_cmd_data_path(wl, wl->channel, 1);
+	ret = wl1271_cmd_data_path(wl, 1);
 	if (ret < 0)
 		goto out_free_memmap;
 
@@ -299,8 +320,8 @@ int wl1271_hw_init(struct wl1271 *wl)
 	if (ret < 0)
 		goto out_free_memmap;
 
-	/* Configure smart reflex */
-	ret = wl1271_acx_smart_reflex(wl);
+	/* configure PM */
+	ret = wl1271_acx_pm_config(wl);
 	if (ret < 0)
 		goto out_free_memmap;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_init.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_init.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_init.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_init.h	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,10 @@
 #include "wl1271.h"
 
 int wl1271_hw_init_power_auth(struct wl1271 *wl);
+int wl1271_init_templates_config(struct wl1271 *wl);
+int wl1271_init_phy_config(struct wl1271 *wl);
+int wl1271_init_pta(struct wl1271 *wl);
+int wl1271_init_energy_detection(struct wl1271 *wl);
 int wl1271_hw_init(struct wl1271 *wl);
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_io.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_io.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_io.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_io.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,213 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/crc7.h>
+#include <linux/spi/spi.h>
+
+#include "wl1271.h"
+#include "wl12xx_80211.h"
+#include "wl1271_spi.h"
+#include "wl1271_io.h"
+
+static int wl1271_translate_addr(struct wl1271 *wl, int addr)
+{
+	/*
+	 * To translate, first check to which window of addresses the
+	 * particular address belongs. Then subtract the starting address
+	 * of that window from the address. Then, add offset of the
+	 * translated region.
+	 *
+	 * The translated regions occur next to each other in physical device
+	 * memory, so just add the sizes of the preceeding address regions to
+	 * get the offset to the new region.
+	 *
+	 * Currently, only the two first regions are addressed, and the
+	 * assumption is that all addresses will fall into either of those
+	 * two.
+	 */
+	if ((addr >= wl->part.reg.start) &&
+	    (addr < wl->part.reg.start + wl->part.reg.size))
+		return addr - wl->part.reg.start + wl->part.mem.size;
+	else
+		return addr - wl->part.mem.start;
+}
+
+/* Set the SPI partitions to access the chip addresses
+ *
+ * To simplify driver code, a fixed (virtual) memory map is defined for
+ * register and memory addresses. Because in the chipset, in different stages
+ * of operation, those addresses will move around, an address translation
+ * mechanism is required.
+ *
+ * There are four partitions (three memory and one register partition),
+ * which are mapped to two different areas of the hardware memory.
+ *
+ *                                Virtual address
+ *                                     space
+ *
+ *                                    |    |
+ *                                 ...+----+--> mem.start
+ *          Physical address    ...   |    |
+ *               space       ...      |    | [PART_0]
+ *                        ...         |    |
+ *  00000000  <--+----+...         ...+----+--> mem.start + mem.size
+ *               |    |         ...   |    |
+ *               |MEM |      ...      |    |
+ *               |    |   ...         |    |
+ *  mem.size  <--+----+...            |    | {unused area)
+ *               |    |   ...         |    |
+ *               |REG |      ...      |    |
+ *  mem.size     |    |         ...   |    |
+ *      +     <--+----+...         ...+----+--> reg.start
+ *  reg.size     |    |   ...         |    |
+ *               |MEM2|      ...      |    | [PART_1]
+ *               |    |         ...   |    |
+ *                                 ...+----+--> reg.start + reg.size
+ *                                    |    |
+ *
+ */
+int wl1271_set_partition(struct wl1271 *wl,
+			 struct wl1271_partition_set *p)
+{
+	/* copy partition info */
+	memcpy(&wl->part, p, sizeof(*p));
+
+	wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+		     p->mem.start, p->mem.size);
+	wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+		     p->reg.start, p->reg.size);
+	wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X",
+		     p->mem2.start, p->mem2.size);
+	wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X",
+		     p->mem3.start, p->mem3.size);
+
+	/* write partition info to the chipset */
+	wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start);
+	wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size);
+	wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start);
+	wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size);
+	wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start);
+	wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size);
+	wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start);
+
+	return 0;
+}
+
+void wl1271_io_reset(struct wl1271 *wl)
+{
+	wl1271_spi_reset(wl);
+}
+
+void wl1271_io_init(struct wl1271 *wl)
+{
+	wl1271_spi_init(wl);
+}
+
+void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf,
+		      size_t len, bool fixed)
+{
+	wl1271_spi_raw_write(wl, addr, buf, len, fixed);
+}
+
+void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf,
+		     size_t len, bool fixed)
+{
+	wl1271_spi_raw_read(wl, addr, buf, len, fixed);
+}
+
+void wl1271_read(struct wl1271 *wl, int addr, void *buf, size_t len,
+		     bool fixed)
+{
+	int physical;
+
+	physical = wl1271_translate_addr(wl, addr);
+
+	wl1271_spi_raw_read(wl, physical, buf, len, fixed);
+}
+
+void wl1271_write(struct wl1271 *wl, int addr, void *buf, size_t len,
+		  bool fixed)
+{
+	int physical;
+
+	physical = wl1271_translate_addr(wl, addr);
+
+	wl1271_spi_raw_write(wl, physical, buf, len, fixed);
+}
+
+u32 wl1271_read32(struct wl1271 *wl, int addr)
+{
+	return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr));
+}
+
+void wl1271_write32(struct wl1271 *wl, int addr, u32 val)
+{
+	wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val);
+}
+
+void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val)
+{
+	/* write address >> 1 + 0x30000 to OCP_POR_CTR */
+	addr = (addr >> 1) + 0x30000;
+	wl1271_write32(wl, OCP_POR_CTR, addr);
+
+	/* write value to OCP_POR_WDATA */
+	wl1271_write32(wl, OCP_DATA_WRITE, val);
+
+	/* write 1 to OCP_CMD */
+	wl1271_write32(wl, OCP_CMD, OCP_CMD_WRITE);
+}
+
+u16 wl1271_top_reg_read(struct wl1271 *wl, int addr)
+{
+	u32 val;
+	int timeout = OCP_CMD_LOOP;
+
+	/* write address >> 1 + 0x30000 to OCP_POR_CTR */
+	addr = (addr >> 1) + 0x30000;
+	wl1271_write32(wl, OCP_POR_CTR, addr);
+
+	/* write 2 to OCP_CMD */
+	wl1271_write32(wl, OCP_CMD, OCP_CMD_READ);
+
+	/* poll for data ready */
+	do {
+		val = wl1271_read32(wl, OCP_DATA_READ);
+	} while (!(val & OCP_READY_MASK) && --timeout);
+
+	if (!timeout) {
+		wl1271_warning("Top register access timed out.");
+		return 0xffff;
+	}
+
+	/* check data status and return if OK */
+	if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)
+		return val & 0xffff;
+	else {
+		wl1271_warning("Top register access returned error.");
+		return 0xffff;
+	}
+}
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_io.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_io.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_io.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,68 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL1271_IO_H__
+#define __WL1271_IO_H__
+
+struct wl1271;
+
+void wl1271_io_reset(struct wl1271 *wl);
+void wl1271_io_init(struct wl1271 *wl);
+
+/* Raw target IO, address is not translated */
+void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf,
+		      size_t len, bool fixed);
+void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf,
+		     size_t len, bool fixed);
+
+/* Translated target IO */
+void wl1271_read(struct wl1271 *wl, int addr, void *buf, size_t len,
+		     bool fixed);
+void wl1271_write(struct wl1271 *wl, int addr, void *buf, size_t len,
+		      bool fixed);
+u32 wl1271_read32(struct wl1271 *wl, int addr);
+void wl1271_write32(struct wl1271 *wl, int addr, u32 val);
+
+/* Top Register IO */
+void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val);
+u16 wl1271_top_reg_read(struct wl1271 *wl, int addr);
+
+int wl1271_set_partition(struct wl1271 *wl,
+			 struct wl1271_partition_set *p);
+
+static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr)
+{
+	wl1271_raw_read(wl, addr, &wl->buffer_32,
+			    sizeof(wl->buffer_32), false);
+
+	return wl->buffer_32;
+}
+
+static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val)
+{
+	wl->buffer_32 = val;
+	wl1271_raw_write(wl, addr, &wl->buffer_32,
+			     sizeof(wl->buffer_32), false);
+}
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_main.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_main.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_main.c	2013-05-03 12:11:43.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_main.c	2013-05-03 09:51:15.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * This file is part of wl1271
  *
- * Copyright (C) 2008-2009 Nokia Corporation
+ * Copyright (C) 2008-2010 Nokia Corporation
  *
  * Contact: Luciano Coelho <luciano.coelho@nokia.com>
  *
@@ -33,11 +33,13 @@
 #include <linux/vmalloc.h>
 #include <linux/spi/wl12xx.h>
 #include <linux/inetdevice.h>
+#include <linux/slab.h>
 
 #include "wl1271.h"
 #include "wl12xx_80211.h"
 #include "wl1271_reg.h"
 #include "wl1271_spi.h"
+#include "wl1271_io.h"
 #include "wl1271_event.h"
 #include "wl1271_tx.h"
 #include "wl1271_rx.h"
@@ -46,6 +48,9 @@
 #include "wl1271_debugfs.h"
 #include "wl1271_cmd.h"
 #include "wl1271_boot.h"
+#include "wl1271_testmode.h"
+
+#define WL1271_BOOT_RETRIES 3
 
 static struct conf_drv_settings default_conf = {
 	.sg = {
@@ -67,16 +72,17 @@ static struct conf_drv_settings default_
 		.ps_poll_timeout             = 15,
 		.upsd_timeout                = 15,
 		.rts_threshold               = 2347,
-		.rx_cca_threshold            = 0xFFEF,
-		.irq_blk_threshold           = 0,
-		.irq_pkt_threshold           = USHORT_MAX,
-		.irq_timeout                 = 5,
+		.rx_cca_threshold            = 0,
+		.irq_blk_threshold           = 0xFFFF,
+		.irq_pkt_threshold           = 0,
+		.irq_timeout                 = 600,
 		.queue_type                  = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
 	},
 	.tx = {
 		.tx_energy_detection         = 0,
 		.rc_conf                     = {
-			.enabled_rates       = CONF_TX_RATE_MASK_UNSPECIFIED,
+			.enabled_rates       = CONF_HW_BIT_RATE_1MBPS |
+					       CONF_HW_BIT_RATE_2MBPS,
 			.short_retry_limit   = 10,
 			.long_retry_limit    = 10,
 			.aflags              = 0
@@ -172,8 +178,8 @@ static struct conf_drv_settings default_
 			}
 		},
 		.frag_threshold              = IEEE80211_MAX_FRAG_THRESHOLD,
-		.tx_compl_timeout            = 5,
-		.tx_compl_threshold          = 5
+		.tx_compl_timeout            = 700,
+		.tx_compl_threshold          = 4
 	},
 	.conn = {
 		.wake_up_event               = CONF_WAKE_UP_EVENT_DTIM,
@@ -186,12 +192,12 @@ static struct conf_drv_settings default_
 				.rule        = CONF_BCN_RULE_PASS_ON_APPEARANCE,
 			}
 		},
-		.synch_fail_thold            = 5,
+		.synch_fail_thold            = 10,
 		.bss_lose_timeout            = 100,
 		.beacon_rx_timeout           = 10000,
 		.broadcast_timeout           = 20000,
 		.rx_broadcast_in_ps          = 1,
-		.ps_poll_threshold           = 4,
+		.ps_poll_threshold           = 20,
 		.sig_trigger_count           = 2,
 		.sig_trigger = {
 			[0] = {
@@ -226,97 +232,17 @@ static struct conf_drv_settings default_
 		.psm_entry_retries           = 3
 	},
 	.init = {
-		.sr_err_tbl = {
-			[0] = {
-				.len         = 7,
-				.upper_limit = 0x03,
-				.values      = {
-					0x18, 0x10, 0x05, 0xfb, 0xf0, 0xe8,
-					0x00 }
-			},
-			[1] = {
-				.len         = 7,
-				.upper_limit = 0x03,
-				.values      = {
-					0x18, 0x10, 0x05, 0xf6, 0xf0, 0xe8,
-					0x00 }
-			},
-			[2] = {
-				.len         = 7,
-				.upper_limit = 0x03,
-				.values      = {
-					0x18, 0x10, 0x05, 0xfb, 0xf0, 0xe8,
-					0x00 }
-			}
-		},
-		.sr_enable                   = 1,
-		.genparam                    = {
-			.ref_clk             = CONF_REF_CLK_38_4_E,
-			.settling_time       = 5,
-			.clk_valid_on_wakeup = 0,
-			.dc2dcmode           = 0,
-			.single_dual_band    = CONF_SINGLE_BAND,
-			.tx_bip_fem_autodetect = 0,
-			.tx_bip_fem_manufacturer = 1,
-			.settings = 1,
-		},
 		.radioparam = {
-			.rx_trace_loss       = 10,
-			.tx_trace_loss       = 10,
-			.rx_rssi_and_proc_compens = {
-				0xec, 0xf6, 0x00, 0x0c, 0x18, 0xf8,
-				0xfc, 0x00, 0x08, 0x10, 0xf0, 0xf8,
-				0x00, 0x0a, 0x14 },
-			.rx_trace_loss_5     = { 0, 0, 0, 0, 0, 0, 0 },
-			.tx_trace_loss_5     = { 0, 0, 0, 0, 0, 0, 0 },
-			.rx_rssi_and_proc_compens_5 = {
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00, 0x00, 0x00 },
-			.tx_ref_pd_voltage   = 0x24e,
-			.tx_ref_power        = 0x78,
-			.tx_offset_db        = 0x0,
-			.tx_rate_limits_normal = {
-				0x1e, 0x1f, 0x22, 0x24, 0x28, 0x29 },
-			.tx_rate_limits_degraded = {
-				0x1b, 0x1c, 0x1e, 0x20, 0x24, 0x25 },
-			.tx_channel_limits_11b = {
-				0x22, 0x50, 0x50, 0x50, 0x50, 0x50,
-				0x50, 0x50, 0x50, 0x50, 0x22, 0x50,
-				0x22, 0x50 },
-			.tx_channel_limits_ofdm = {
-				0x20, 0x50, 0x50, 0x50, 0x50, 0x50,
-				0x50, 0x50, 0x50, 0x50, 0x20, 0x50,
-				0x20, 0x50 },
-			.tx_pdv_rate_offsets = {
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-			.tx_ibias            = {
-				0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x27 },
-			.rx_fem_insertion_loss = 0x14,
-			.tx_ref_pd_voltage_5 = {
-				0x0190, 0x01a4, 0x01c3, 0x01d8,
-				0x020a, 0x021c },
-			.tx_ref_power_5      = {
-				0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 },
-			.tx_offset_db_5      = {
-				0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-			.tx_rate_limits_normal_5 = {
-				0x1b, 0x1e, 0x21, 0x23, 0x27, 0x00 },
-			.tx_rate_limits_degraded_5 = {
-				0x1b, 0x1e, 0x21, 0x23, 0x27, 0x00 },
-			.tx_channel_limits_ofdm_5 = {
-				0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
-				0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
-				0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
-				0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
-				0x50, 0x50, 0x50 },
-			.tx_pdv_rate_offsets_5 = {
-				0x01, 0x02, 0x02, 0x02, 0x02, 0x00 },
-			.tx_ibias_5          = {
-				0x10, 0x10, 0x10, 0x10, 0x10, 0x10 },
-			.rx_fem_insertion_loss_5 = {
-				0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }
+			.fem                 = 1,
 		}
+	},
+	.itrim = {
+		.enable = false,
+		.timeout = 50000,
+	},
+	.pm_config = {
+		.host_clk_settling_time = 5000,
+		.host_fast_wakeup_support = false
 	}
 };
 
@@ -337,15 +263,14 @@ static void wl1271_conf_init(struct wl12
 
 	/* apply driver default configuration */
 	memcpy(&wl->conf, &default_conf, sizeof(default_conf));
-
-	if (wl1271_11a_enabled())
-		wl->conf.init.genparam.single_dual_band = CONF_DUAL_BAND;
 }
 
 
 static int wl1271_plt_init(struct wl1271 *wl)
 {
-	int ret;
+	struct conf_tx_ac_category *conf_ac;
+	struct conf_tx_tid *conf_tid;
+	int ret, i;
 
 	ret = wl1271_cmd_general_parms(wl);
 	if (ret < 0)
@@ -355,15 +280,89 @@ static int wl1271_plt_init(struct wl1271
 	if (ret < 0)
 		return ret;
 
-	ret = wl1271_acx_init_mem_config(wl);
+	ret = wl1271_init_templates_config(wl);
 	if (ret < 0)
 		return ret;
 
-	ret = wl1271_cmd_data_path(wl, wl->channel, 1);
+	ret = wl1271_acx_init_mem_config(wl);
 	if (ret < 0)
 		return ret;
 
+	/* PHY layer config */
+	ret = wl1271_init_phy_config(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	ret = wl1271_acx_dco_itrim_params(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Initialize connection monitoring thresholds */
+	ret = wl1271_acx_conn_monit_params(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Bluetooth WLAN coexistence */
+	ret = wl1271_init_pta(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Energy detection */
+	ret = wl1271_init_energy_detection(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Default fragmentation threshold */
+	ret = wl1271_acx_frag_threshold(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Default TID configuration */
+	for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
+		conf_tid = &wl->conf.tx.tid_conf[i];
+		ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id,
+					 conf_tid->channel_type,
+					 conf_tid->tsid,
+					 conf_tid->ps_scheme,
+					 conf_tid->ack_policy,
+					 conf_tid->apsd_conf[0],
+					 conf_tid->apsd_conf[1]);
+		if (ret < 0)
+			goto out_free_memmap;
+	}
+
+	/* Default AC configuration */
+	for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
+		conf_ac = &wl->conf.tx.ac_conf[i];
+		ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
+					conf_ac->cw_max, conf_ac->aifsn,
+					conf_ac->tx_op_limit);
+		if (ret < 0)
+			goto out_free_memmap;
+	}
+
+	/* Enable data path */
+	ret = wl1271_cmd_data_path(wl, 1);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Configure for CAM power saving (ie. always active) */
+	ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* configure PM */
+	ret = wl1271_acx_pm_config(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
 	return 0;
+
+ out_free_memmap:
+	kfree(wl->target_mem_map);
+	wl->target_mem_map = NULL;
+
+	return ret;
 }
 
 static void wl1271_disable_interrupts(struct wl1271 *wl)
@@ -374,11 +373,13 @@ static void wl1271_disable_interrupts(st
 static void wl1271_power_off(struct wl1271 *wl)
 {
 	wl->set_power(false);
+	clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
 }
 
 static void wl1271_power_on(struct wl1271 *wl)
 {
 	wl->set_power(true);
+	set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
 }
 
 static void wl1271_fw_status(struct wl1271 *wl,
@@ -387,8 +388,7 @@ static void wl1271_fw_status(struct wl12
 	u32 total = 0;
 	int i;
 
-	wl1271_spi_read(wl, FW_STATUS_ADDR, status,
-			sizeof(*status), false);
+	wl1271_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false);
 
 	wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
 		     "drv_rx_counter = %d, tx_results_counter = %d)",
@@ -435,7 +435,7 @@ static void wl1271_irq_work(struct work_
 	if (ret < 0)
 		goto out;
 
-	wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
+	wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
 
 	wl1271_fw_status(wl, wl->fw_status);
 	intr = le32_to_cpu(wl->fw_status->intr);
@@ -447,14 +447,13 @@ static void wl1271_irq_work(struct work_
 	intr &= WL1271_INTR_MASK;
 
 	if (intr & WL1271_ACX_INTR_EVENT_A) {
-		bool do_ack = (intr & WL1271_ACX_INTR_EVENT_B) ? false : true;
 		wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A");
-		wl1271_event_handle(wl, 0, do_ack);
+		wl1271_event_handle(wl, 0);
 	}
 
 	if (intr & WL1271_ACX_INTR_EVENT_B) {
 		wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B");
-		wl1271_event_handle(wl, 1, true);
+		wl1271_event_handle(wl, 1);
 	}
 
 	if (intr & WL1271_ACX_INTR_INIT_COMPLETE)
@@ -478,8 +477,8 @@ static void wl1271_irq_work(struct work_
 	}
 
 out_sleep:
-	wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK,
-			   WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
+	wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
+		       WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
 	wl1271_ps_elp_sleep(wl);
 
 out:
@@ -546,6 +545,40 @@ out:
 	return ret;
 }
 
+static int wl1271_update_mac_addr(struct wl1271 *wl)
+{
+	int ret = 0;
+	u8 *nvs_ptr = (u8 *)wl->nvs->nvs;
+
+	/* get mac address from the NVS */
+	wl->mac_addr[0] = nvs_ptr[11];
+	wl->mac_addr[1] = nvs_ptr[10];
+	wl->mac_addr[2] = nvs_ptr[6];
+	wl->mac_addr[3] = nvs_ptr[5];
+	wl->mac_addr[4] = nvs_ptr[4];
+	wl->mac_addr[5] = nvs_ptr[3];
+
+	/* FIXME: if it is a zero-address, we should bail out. Now, instead,
+	   we randomize an address */
+	if (is_zero_ether_addr(wl->mac_addr)) {
+		static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
+		memcpy(wl->mac_addr, nokia_oui, 3);
+		get_random_bytes(wl->mac_addr + 3, 3);
+
+		/* update this address to the NVS */
+		nvs_ptr[11] = wl->mac_addr[0];
+		nvs_ptr[10] = wl->mac_addr[1];
+		nvs_ptr[6] = wl->mac_addr[2];
+		nvs_ptr[5] = wl->mac_addr[3];
+		nvs_ptr[4] = wl->mac_addr[4];
+		nvs_ptr[3] = wl->mac_addr[5];
+	}
+
+	SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
+
+	return ret;
+}
+
 static int wl1271_fetch_nvs(struct wl1271 *wl)
 {
 	const struct firmware *fw;
@@ -558,15 +591,14 @@ static int wl1271_fetch_nvs(struct wl127
 		return ret;
 	}
 
-	if (fw->size % 4) {
-		wl1271_error("nvs size is not multiple of 32 bits: %zu",
-			     fw->size);
+	if (fw->size != sizeof(struct wl1271_nvs_file)) {
+		wl1271_error("nvs size is not as expected: %zu != %zu",
+			     fw->size, sizeof(struct wl1271_nvs_file));
 		ret = -EILSEQ;
 		goto out;
 	}
 
-	wl->nvs_len = fw->size;
-	wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL);
+	wl->nvs = kmalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL);
 
 	if (!wl->nvs) {
 		wl1271_error("could not allocate memory for the nvs file");
@@ -574,9 +606,9 @@ static int wl1271_fetch_nvs(struct wl127
 		goto out;
 	}
 
-	memcpy(wl->nvs, fw->data, wl->nvs_len);
+	memcpy(wl->nvs, fw->data, sizeof(struct wl1271_nvs_file));
 
-	ret = 0;
+	ret = wl1271_update_mac_addr(wl);
 
 out:
 	release_firmware(fw);
@@ -614,10 +646,11 @@ static int wl1271_chip_wakeup(struct wl1
 	struct wl1271_partition_set partition;
 	int ret = 0;
 
+	msleep(WL1271_PRE_POWER_ON_SLEEP);
 	wl1271_power_on(wl);
 	msleep(WL1271_POWER_ON_SLEEP);
-	wl1271_spi_reset(wl);
-	wl1271_spi_init(wl);
+	wl1271_io_reset(wl);
+	wl1271_io_init(wl);
 
 	/* We don't need a real memory partition here, because we only want
 	 * to use the registers at this point. */
@@ -632,7 +665,7 @@ static int wl1271_chip_wakeup(struct wl1
 	/* whal_FwCtrl_BootSm() */
 
 	/* 0. read chip id from CHIP_ID */
-	wl->chip.id = wl1271_spi_read32(wl, CHIP_ID_B);
+	wl->chip.id = wl1271_read32(wl, CHIP_ID_B);
 
 	/* 1. check if chip id is valid */
 
@@ -643,7 +676,7 @@ static int wl1271_chip_wakeup(struct wl1
 
 		ret = wl1271_setup(wl);
 		if (ret < 0)
-			goto out_power_off;
+			goto out;
 		break;
 	case CHIP_ID_1271_PG20:
 		wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
@@ -651,38 +684,34 @@ static int wl1271_chip_wakeup(struct wl1
 
 		ret = wl1271_setup(wl);
 		if (ret < 0)
-			goto out_power_off;
+			goto out;
 		break;
 	default:
-		wl1271_error("unsupported chip id: 0x%x", wl->chip.id);
+		wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
 		ret = -ENODEV;
-		goto out_power_off;
+		goto out;
 	}
 
 	if (wl->fw == NULL) {
 		ret = wl1271_fetch_firmware(wl);
 		if (ret < 0)
-			goto out_power_off;
+			goto out;
 	}
 
 	/* No NVS from netlink, try to get it from the filesystem */
 	if (wl->nvs == NULL) {
 		ret = wl1271_fetch_nvs(wl);
 		if (ret < 0)
-			goto out_power_off;
+			goto out;
 	}
 
-	goto out;
-
-out_power_off:
-	wl1271_power_off(wl);
-
 out:
 	return ret;
 }
 
 int wl1271_plt_start(struct wl1271 *wl)
 {
+	int retries = WL1271_BOOT_RETRIES;
 	int ret;
 
 	mutex_lock(&wl->mutex);
@@ -696,35 +725,43 @@ int wl1271_plt_start(struct wl1271 *wl)
 		goto out;
 	}
 
-	wl->state = WL1271_STATE_PLT;
-
-	ret = wl1271_chip_wakeup(wl);
-	if (ret < 0)
-		goto out;
-
-	ret = wl1271_boot(wl);
-	if (ret < 0)
-		goto out_power_off;
-
-	wl1271_notice("firmware booted in PLT mode (%s)", wl->chip.fw_ver);
-
-	ret = wl1271_plt_init(wl);
-	if (ret < 0)
-		goto out_irq_disable;
+	while (retries) {
+		retries--;
+		ret = wl1271_chip_wakeup(wl);
+		if (ret < 0)
+			goto power_off;
 
-	/* Make sure power saving is disabled */
-	ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
-	if (ret < 0)
-		goto out_irq_disable;
+		ret = wl1271_boot(wl);
+		if (ret < 0)
+			goto power_off;
 
-	goto out;
+		ret = wl1271_plt_init(wl);
+		if (ret < 0)
+			goto irq_disable;
 
-out_irq_disable:
-	wl1271_disable_interrupts(wl);
+		wl->state = WL1271_STATE_PLT;
+		wl1271_notice("firmware booted in PLT mode (%s)",
+			      wl->chip.fw_ver);
+		goto out;
 
-out_power_off:
-	wl1271_power_off(wl);
+irq_disable:
+		wl1271_disable_interrupts(wl);
+		mutex_unlock(&wl->mutex);
+		/* Unlocking the mutex in the middle of handling is
+		   inherently unsafe. In this case we deem it safe to do,
+		   because we need to let any possibly pending IRQ out of
+		   the system (and while we are WL1271_STATE_OFF the IRQ
+		   work function will not do anything.) Also, any other
+		   possible concurrent operations will fail due to the
+		   current state, hence the wl1271 struct should be safe. */
+		cancel_work_sync(&wl->irq_work);
+		mutex_lock(&wl->mutex);
+power_off:
+		wl1271_power_off(wl);
+	}
 
+	wl1271_error("firmware boot in PLT mode failed despite %d retries",
+		     WL1271_BOOT_RETRIES);
 out:
 	mutex_unlock(&wl->mutex);
 
@@ -762,7 +799,20 @@ out:
 static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 	struct wl1271 *wl = hw->priv;
+	struct ieee80211_conf *conf = &hw->conf;
+	struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
+	struct ieee80211_sta *sta = txinfo->control.sta;
+	unsigned long flags;
+
+	/* peek into the rates configured in the STA entry */
+	spin_lock_irqsave(&wl->wl_lock, flags);
+	if (sta && sta->supp_rates[conf->channel->band] != wl->sta_rate_set) {
+		wl->sta_rate_set = sta->supp_rates[conf->channel->band];
+		set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
+	}
+	spin_unlock_irqrestore(&wl->wl_lock, flags);
 
+	/* queue the packet */
 	skb_queue_tail(&wl->tx_queue, skb);
 
 	/*
@@ -784,7 +834,7 @@ static int wl1271_op_tx(struct ieee80211
 		 * protected. Maybe fix this by removing the stupid
 		 * variable altogether and checking the real queue state?
 		 */
-		wl->tx_queue_stopped = true;
+		set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
 	}
 
 	return NETDEV_TX_OK;
@@ -880,6 +930,7 @@ static struct notifier_block wl1271_dev_
 static int wl1271_op_start(struct ieee80211_hw *hw)
 {
 	struct wl1271 *wl = hw->priv;
+	int retries = WL1271_BOOT_RETRIES;
 	int ret = 0;
 
 	wl1271_debug(DEBUG_MAC80211, "mac80211 start");
@@ -893,30 +944,42 @@ static int wl1271_op_start(struct ieee80
 		goto out;
 	}
 
-	ret = wl1271_chip_wakeup(wl);
-	if (ret < 0)
-		goto out;
-
-	ret = wl1271_boot(wl);
-	if (ret < 0)
-		goto out_power_off;
-
-	ret = wl1271_hw_init(wl);
-	if (ret < 0)
-		goto out_irq_disable;
-
-	wl->state = WL1271_STATE_ON;
+	while (retries) {
+		retries--;
+		ret = wl1271_chip_wakeup(wl);
+		if (ret < 0)
+			goto power_off;
 
-	wl1271_info("firmware booted (%s)", wl->chip.fw_ver);
+		ret = wl1271_boot(wl);
+		if (ret < 0)
+			goto power_off;
 
-	goto out;
+		ret = wl1271_hw_init(wl);
+		if (ret < 0)
+			goto irq_disable;
 
-out_irq_disable:
-	wl1271_disable_interrupts(wl);
+		wl->state = WL1271_STATE_ON;
+		wl1271_info("firmware booted (%s)", wl->chip.fw_ver);
+		goto out;
 
-out_power_off:
-	wl1271_power_off(wl);
+irq_disable:
+		wl1271_disable_interrupts(wl);
+		mutex_unlock(&wl->mutex);
+		/* Unlocking the mutex in the middle of handling is
+		   inherently unsafe. In this case we deem it safe to do,
+		   because we need to let any possibly pending IRQ out of
+		   the system (and while we are WL1271_STATE_OFF the IRQ
+		   work function will not do anything.) Also, any other
+		   possible concurrent operations will fail due to the
+		   current state, hence the wl1271 struct should be safe. */
+		cancel_work_sync(&wl->irq_work);
+		mutex_lock(&wl->mutex);
+power_off:
+		wl1271_power_off(wl);
+	}
 
+	wl1271_error("firmware boot failed despite %d retries",
+		     WL1271_BOOT_RETRIES);
 out:
 	mutex_unlock(&wl->mutex);
 
@@ -944,11 +1007,10 @@ static void wl1271_op_stop(struct ieee80
 
 	WARN_ON(wl->state != WL1271_STATE_ON);
 
-	if (wl->scanning) {
+	if (test_and_clear_bit(WL1271_FLAG_SCANNING, &wl->flags)) {
 		mutex_unlock(&wl->mutex);
 		ieee80211_scan_completed(wl->hw, true);
 		mutex_lock(&wl->mutex);
-		wl->scanning = false;
 	}
 
 	wl->state = WL1271_STATE_OFF;
@@ -973,10 +1035,7 @@ static void wl1271_op_stop(struct ieee80
 	wl->band = IEEE80211_BAND_2GHZ;
 
 	wl->rx_counter = 0;
-	wl->elp = false;
-	wl->psm = 0;
 	wl->psm_entry_retry = 0;
-	wl->tx_queue_stopped = false;
 	wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
 	wl->tx_blocks_available = 0;
 	wl->tx_results_count = 0;
@@ -986,7 +1045,9 @@ static void wl1271_op_stop(struct ieee80
 	wl->tx_security_seq_32 = 0;
 	wl->time_offset = 0;
 	wl->session_counter = 0;
-	wl->joined = false;
+	wl->rate_set = CONF_TX_RATE_MASK_BASIC;
+	wl->sta_rate_set = 0;
+	wl->flags = 0;
 
 	for (i = 0; i < NUM_TX_QUEUES; i++)
 		wl->tx_blocks_freed[i] = 0;
@@ -996,13 +1057,13 @@ static void wl1271_op_stop(struct ieee80
 }
 
 static int wl1271_op_add_interface(struct ieee80211_hw *hw,
-				   struct ieee80211_if_init_conf *conf)
+				   struct ieee80211_vif *vif)
 {
 	struct wl1271 *wl = hw->priv;
 	int ret = 0;
 
 	wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
-		     conf->type, conf->mac_addr);
+		     vif->type, vif->addr);
 
 	mutex_lock(&wl->mutex);
 	if (wl->vif) {
@@ -1010,9 +1071,9 @@ static int wl1271_op_add_interface(struc
 		goto out;
 	}
 
-	wl->vif = conf->vif;
+	wl->vif = vif;
 
-	switch (conf->type) {
+	switch (vif->type) {
 	case NL80211_IFTYPE_STATION:
 		wl->bss_type = BSS_TYPE_STA_BSS;
 		break;
@@ -1032,7 +1093,7 @@ out:
 }
 
 static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
-					 struct ieee80211_if_init_conf *conf)
+					 struct ieee80211_vif *vif)
 {
 	struct wl1271 *wl = hw->priv;
 
@@ -1109,6 +1170,51 @@ out:
 }
 #endif
 
+static int wl1271_join_channel(struct wl1271 *wl, int channel)
+{
+	int ret = 0;
+	/* we need to use a dummy BSSID for now */
+	static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde,
+						  0xad, 0xbe, 0xef };
+
+	/* the dummy join is not required for ad-hoc */
+	if (wl->bss_type == BSS_TYPE_IBSS)
+		goto out;
+
+	/* disable mac filter, so we hear everything */
+	wl->rx_config &= ~CFG_BSSID_FILTER_EN;
+
+	wl->channel = channel;
+	memcpy(wl->bssid, dummy_bssid, ETH_ALEN);
+
+	ret = wl1271_cmd_join(wl);
+	if (ret < 0)
+		goto out;
+
+	set_bit(WL1271_FLAG_JOINED, &wl->flags);
+
+out:
+	return ret;
+}
+
+static int wl1271_unjoin_channel(struct wl1271 *wl)
+{
+	int ret;
+
+	/* to stop listening to a channel, we disconnect */
+	ret = wl1271_cmd_disconnect(wl);
+	if (ret < 0)
+		goto out;
+
+	clear_bit(WL1271_FLAG_JOINED, &wl->flags);
+	wl->channel = 0;
+	memset(wl->bssid, 0, ETH_ALEN);
+	wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
+
+out:
+	return ret;
+}
+
 static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
 {
 	struct wl1271 *wl = hw->priv;
@@ -1117,10 +1223,11 @@ static int wl1271_op_config(struct ieee8
 
 	channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
 
-	wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
+	wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d %s",
 		     channel,
 		     conf->flags & IEEE80211_CONF_PS ? "on" : "off",
-		     conf->power_level);
+		     conf->power_level,
+		     conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use");
 
 	mutex_lock(&wl->mutex);
 
@@ -1130,35 +1237,55 @@ static int wl1271_op_config(struct ieee8
 	if (ret < 0)
 		goto out;
 
-	if (channel != wl->channel) {
-		/*
-		 * We assume that the stack will configure the right channel
-		 * before associating, so we don't need to send a join
-		 * command here.  We will join the right channel when the
-		 * BSSID changes
-		 */
-		wl->channel = channel;
+	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+		if (conf->flags & IEEE80211_CONF_IDLE &&
+		    test_bit(WL1271_FLAG_JOINED, &wl->flags))
+			wl1271_unjoin_channel(wl);
+		else if (!(conf->flags & IEEE80211_CONF_IDLE))
+			wl1271_join_channel(wl, channel);
+
+		if (conf->flags & IEEE80211_CONF_IDLE) {
+			wl->rate_set = CONF_TX_RATE_MASK_BASIC;
+			wl->sta_rate_set = 0;
+			wl1271_acx_rate_policies(wl);
+		}
 	}
 
-	if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
-		wl1271_info("psm enabled");
+	/* if the channel changes while joined, join again */
+	if (channel != wl->channel &&
+	    test_bit(WL1271_FLAG_JOINED, &wl->flags)) {
+		wl->channel = channel;
+		/* FIXME: maybe use CMD_CHANNEL_SWITCH for this? */
+		ret = wl1271_cmd_join(wl);
+		if (ret < 0)
+			wl1271_warning("cmd join to update channel failed %d",
+				       ret);
+	} else
+		wl->channel = channel;
 
-		wl->psm_requested = true;
+	if (conf->flags & IEEE80211_CONF_PS &&
+	    !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {
+		set_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags);
 
 		/*
 		 * We enter PSM only if we're already associated.
 		 * If we're not, we'll enter it when joining an SSID,
 		 * through the bss_info_changed() hook.
 		 */
-		ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+		if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) {
+			wl1271_info("psm enabled");
+			ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
+						 true);
+		}
 	} else if (!(conf->flags & IEEE80211_CONF_PS) &&
-		   wl->psm_requested) {
+		   test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {
 		wl1271_info("psm disabled");
 
-		wl->psm_requested = false;
+		clear_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags);
 
-		if (wl->psm)
-			ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE);
+		if (test_bit(WL1271_FLAG_PSM, &wl->flags))
+			ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
+						 true);
 	}
 
 	if (conf->power_level != wl->power_level) {
@@ -1350,9 +1477,24 @@ static int wl1271_op_set_key(struct ieee
 			wl1271_error("Could not add or replace key");
 			goto out_sleep;
 		}
+
+		/* the default WEP key needs to be configured at least once */
+		if (key_type == KEY_WEP) {
+			ret = wl1271_cmd_set_default_wep_key(wl,
+							     wl->default_key);
+			if (ret < 0)
+				goto out_sleep;
+		}
 		break;
 
 	case DISABLE_KEY:
+		/* The wl1271 does not allow to remove unicast keys - they
+		   will be cleared automatically on next CMD_JOIN. Ignore the
+		   request silently, as we dont want the mac80211 to emit
+		   an error message. */
+		if (!is_broadcast_ether_addr(addr))
+			break;
+
 		ret = wl1271_cmd_set_key(wl, KEY_REMOVE,
 					 key_conf->keyidx, key_type,
 					 key_conf->keylen, key_conf->key,
@@ -1440,20 +1582,21 @@ out:
 	return ret;
 }
 
-static u32 wl1271_enabled_rates_get(struct wl1271 *wl, u64 basic_rate_set)
+static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *beacon)
 {
-	struct ieee80211_supported_band *band;
-	u32 enabled_rates = 0;
-	int bit;
+	u8 *ptr = beacon->data +
+		offsetof(struct ieee80211_mgmt, u.beacon.variable);
 
-	band = wl->hw->wiphy->bands[wl->band];
-	for (bit = 0; bit < band->n_bitrates; bit++) {
-		if (basic_rate_set & 0x1)
-			enabled_rates |= band->bitrates[bit].hw_value;
-		basic_rate_set >>= 1;
+	/* find the location of the ssid in the beacon */
+	while (ptr < beacon->data + beacon->len) {
+		if (ptr[0] == WLAN_EID_SSID) {
+			wl->ssid_len = ptr[1];
+			memcpy(wl->ssid, ptr+2, wl->ssid_len);
+			return;
+		}
+		ptr += ptr[1];
 	}
-
-	return enabled_rates;
+	wl1271_error("ad-hoc beacon template has no SSID!\n");
 }
 
 static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
@@ -1463,6 +1606,7 @@ static void wl1271_op_bss_info_changed(s
 {
 	enum wl1271_cmd_ps_mode mode;
 	struct wl1271 *wl = hw->priv;
+	bool do_join = false;
 	int ret;
 
 	wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed");
@@ -1473,9 +1617,67 @@ static void wl1271_op_bss_info_changed(s
 	if (ret < 0)
 		goto out;
 
+	if (wl->bss_type == BSS_TYPE_IBSS) {
+		/* FIXME: This implements rudimentary ad-hoc support -
+		   proper templates are on the wish list and notification
+		   on when they change. This patch will update the templates
+		   on every call to this function. */
+		struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
+
+		if (beacon) {
+			struct ieee80211_hdr *hdr;
+
+			wl1271_ssid_set(wl, beacon);
+			ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
+						      beacon->data,
+						      beacon->len);
+
+			if (ret < 0) {
+				dev_kfree_skb(beacon);
+				goto out_sleep;
+			}
+
+			hdr = (struct ieee80211_hdr *) beacon->data;
+			hdr->frame_control = cpu_to_le16(
+				IEEE80211_FTYPE_MGMT |
+				IEEE80211_STYPE_PROBE_RESP);
+
+			ret = wl1271_cmd_template_set(wl,
+						      CMD_TEMPL_PROBE_RESPONSE,
+						      beacon->data,
+						      beacon->len);
+			dev_kfree_skb(beacon);
+			if (ret < 0)
+				goto out_sleep;
+
+			/* Need to update the SSID (for filtering etc) */
+			do_join = true;
+		}
+	}
+
+	if ((changed & BSS_CHANGED_BSSID) &&
+	    /*
+	     * Now we know the correct bssid, so we send a new join command
+	     * and enable the BSSID filter
+	     */
+	    memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) {
+			wl->rx_config |= CFG_BSSID_FILTER_EN;
+			memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
+			ret = wl1271_cmd_build_null_data(wl);
+			if (ret < 0) {
+				wl1271_warning("cmd buld null data failed %d",
+					       ret);
+				goto out_sleep;
+			}
+
+			/* Need to update the BSSID (for filtering etc) */
+			do_join = true;
+	}
+
 	if (changed & BSS_CHANGED_ASSOC) {
 		if (bss_conf->assoc) {
 			wl->aid = bss_conf->aid;
+			set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
 
 			/*
 			 * with wl1271, we don't need to update the
@@ -1492,15 +1694,16 @@ static void wl1271_op_bss_info_changed(s
 				goto out_sleep;
 
 			/* If we want to go in PSM but we're not there yet */
-			if (wl->psm_requested && !wl->psm) {
+			if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) &&
+			    !test_bit(WL1271_FLAG_PSM, &wl->flags)) {
 				mode = STATION_POWER_SAVE_MODE;
-				ret = wl1271_ps_set_mode(wl, mode);
+				ret = wl1271_ps_set_mode(wl, mode, true);
 				if (ret < 0)
 					goto out_sleep;
 			}
 		} else {
 			/* use defaults when not associated */
-			wl->basic_rate_set = WL1271_DEFAULT_BASIC_RATE_SET;
+			clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
 			wl->aid = 0;
 		}
 
@@ -1535,15 +1738,13 @@ static void wl1271_op_bss_info_changed(s
 		}
 	}
 
-	if (changed & BSS_CHANGED_BASIC_RATES) {
-		wl->basic_rate_set = wl1271_enabled_rates_get(
-			wl, bss_conf->basic_rates);
-
-		ret = wl1271_acx_rate_policies(wl, wl->basic_rate_set);
+	if (do_join) {
+		ret = wl1271_cmd_join(wl);
 		if (ret < 0) {
-			wl1271_warning("Set rate policies failed %d", ret);
+			wl1271_warning("cmd join failed %d", ret);
 			goto out_sleep;
 		}
+		set_bit(WL1271_FLAG_JOINED, &wl->flags);
 	}
 
 out_sleep:
@@ -1553,6 +1754,43 @@ out:
 	mutex_unlock(&wl->mutex);
 }
 
+static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
+			     const struct ieee80211_tx_queue_params *params)
+{
+	struct wl1271 *wl = hw->priv;
+	int ret;
+
+	mutex_lock(&wl->mutex);
+
+	wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
+
+	ret = wl1271_ps_elp_wakeup(wl, false);
+	if (ret < 0)
+		goto out;
+
+	ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue),
+				params->cw_min, params->cw_max,
+				params->aifs, params->txop);
+	if (ret < 0)
+		goto out_sleep;
+
+	ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue),
+				 CONF_CHANNEL_TYPE_EDCF,
+				 wl1271_tx_get_queue(queue),
+				 CONF_PS_SCHEME_LEGACY_PSPOLL,
+				 CONF_ACK_POLICY_LEGACY, 0, 0);
+	if (ret < 0)
+		goto out_sleep;
+
+out_sleep:
+	wl1271_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
 
 /* can't be const, mac80211 writes to this */
 static struct ieee80211_rate wl1271_rates[] = {
@@ -1599,19 +1837,19 @@ static struct ieee80211_rate wl1271_rate
 
 /* can't be const, mac80211 writes to this */
 static struct ieee80211_channel wl1271_channels[] = {
-	{ .hw_value = 1, .center_freq = 2412},
-	{ .hw_value = 2, .center_freq = 2417},
-	{ .hw_value = 3, .center_freq = 2422},
-	{ .hw_value = 4, .center_freq = 2427},
-	{ .hw_value = 5, .center_freq = 2432},
-	{ .hw_value = 6, .center_freq = 2437},
-	{ .hw_value = 7, .center_freq = 2442},
-	{ .hw_value = 8, .center_freq = 2447},
-	{ .hw_value = 9, .center_freq = 2452},
-	{ .hw_value = 10, .center_freq = 2457},
-	{ .hw_value = 11, .center_freq = 2462},
-	{ .hw_value = 12, .center_freq = 2467},
-	{ .hw_value = 13, .center_freq = 2472},
+	{ .hw_value = 1, .center_freq = 2412, .max_power = 25 },
+	{ .hw_value = 2, .center_freq = 2417, .max_power = 25 },
+	{ .hw_value = 3, .center_freq = 2422, .max_power = 25 },
+	{ .hw_value = 4, .center_freq = 2427, .max_power = 25 },
+	{ .hw_value = 5, .center_freq = 2432, .max_power = 25 },
+	{ .hw_value = 6, .center_freq = 2437, .max_power = 25 },
+	{ .hw_value = 7, .center_freq = 2442, .max_power = 25 },
+	{ .hw_value = 8, .center_freq = 2447, .max_power = 25 },
+	{ .hw_value = 9, .center_freq = 2452, .max_power = 25 },
+	{ .hw_value = 10, .center_freq = 2457, .max_power = 25 },
+	{ .hw_value = 11, .center_freq = 2462, .max_power = 25 },
+	{ .hw_value = 12, .center_freq = 2467, .max_power = 25 },
+	{ .hw_value = 13, .center_freq = 2472, .max_power = 25 },
 };
 
 /* can't be const, mac80211 writes to this */
@@ -1718,6 +1956,8 @@ static const struct ieee80211_ops wl1271
 	.hw_scan = wl1271_op_hw_scan,
 	.bss_info_changed = wl1271_op_bss_info_changed,
 	.set_rts_threshold = wl1271_op_set_rts_threshold,
+	.conf_tx = wl1271_op_conf_tx,
+	CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
 };
 
 static int wl1271_register_hw(struct wl1271 *wl)
@@ -1757,7 +1997,8 @@ static int wl1271_init_ieee80211(struct
 		IEEE80211_HW_BEACON_FILTER |
 		IEEE80211_HW_SUPPORTS_PS;
 
-	wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+	wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+		BIT(NL80211_IFTYPE_ADHOC);
 	wl->hw->wiphy->max_scan_ssids = 1;
 	wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz;
 
@@ -1785,24 +2026,17 @@ static struct platform_device wl1271_dev
 };
 
 #define WL1271_DEFAULT_CHANNEL 0
-static int __devinit wl1271_probe(struct spi_device *spi)
+
+static struct ieee80211_hw *wl1271_alloc_hw(void)
 {
-	struct wl12xx_platform_data *pdata;
 	struct ieee80211_hw *hw;
 	struct wl1271 *wl;
-	int ret, i;
-	static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
-
-	pdata = spi->dev.platform_data;
-	if (!pdata) {
-		wl1271_error("no platform data");
-		return -ENODEV;
-	}
+	int i;
 
 	hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
 	if (!hw) {
 		wl1271_error("could not alloc ieee80211_hw");
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 	}
 
 	wl = hw->priv;
@@ -1811,44 +2045,80 @@ static int __devinit wl1271_probe(struct
 	INIT_LIST_HEAD(&wl->list);
 
 	wl->hw = hw;
-	dev_set_drvdata(&spi->dev, wl);
-	wl->spi = spi;
 
 	skb_queue_head_init(&wl->tx_queue);
 
 	INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
 	wl->channel = WL1271_DEFAULT_CHANNEL;
-	wl->scanning = false;
 	wl->default_key = 0;
 	wl->rx_counter = 0;
 	wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
 	wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
-	wl->elp = false;
-	wl->psm = 0;
-	wl->psm_requested = false;
 	wl->psm_entry_retry = 0;
-	wl->tx_queue_stopped = false;
 	wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
-	wl->basic_rate_set = WL1271_DEFAULT_BASIC_RATE_SET;
+	wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
+	wl->rate_set = CONF_TX_RATE_MASK_BASIC;
+	wl->sta_rate_set = 0;
 	wl->band = IEEE80211_BAND_2GHZ;
 	wl->vif = NULL;
-	wl->joined = false;
+	wl->flags = 0;
 
 	for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
 		wl->tx_frames[i] = NULL;
 
 	spin_lock_init(&wl->wl_lock);
 
-	/*
-	 * In case our MAC address is not correctly set,
-	 * we use a random but Nokia MAC.
-	 */
-	memcpy(wl->mac_addr, nokia_oui, 3);
-	get_random_bytes(wl->mac_addr + 3, 3);
-
 	wl->state = WL1271_STATE_OFF;
 	mutex_init(&wl->mutex);
 
+	/* Apply default driver configuration. */
+	wl1271_conf_init(wl);
+
+	return hw;
+}
+
+int wl1271_free_hw(struct wl1271 *wl)
+{
+	ieee80211_unregister_hw(wl->hw);
+
+	wl1271_debugfs_exit(wl);
+
+	kfree(wl->target_mem_map);
+	vfree(wl->fw);
+	wl->fw = NULL;
+	kfree(wl->nvs);
+	wl->nvs = NULL;
+
+	kfree(wl->fw_status);
+	kfree(wl->tx_res_if);
+
+	ieee80211_free_hw(wl->hw);
+
+	return 0;
+}
+
+static int __devinit wl1271_probe(struct spi_device *spi)
+{
+	struct wl12xx_platform_data *pdata;
+	struct ieee80211_hw *hw;
+	struct wl1271 *wl;
+	int ret;
+
+	pdata = spi->dev.platform_data;
+	if (!pdata) {
+		wl1271_error("no platform data");
+		return -ENODEV;
+	}
+
+	hw = wl1271_alloc_hw();
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	wl = hw->priv;
+
+	dev_set_drvdata(&spi->dev, wl);
+	wl->spi = spi;
+
 	/* This is the only SPI value that we need to set here, the rest
 	 * comes from the board-peripherals file */
 	spi->bits_per_word = 32;
@@ -1890,9 +2160,6 @@ static int __devinit wl1271_probe(struct
 	}
 	dev_set_drvdata(&wl1271_device.dev, wl);
 
-	/* Apply default driver configuration. */
-	wl1271_conf_init(wl);
-
 	ret = wl1271_init_ieee80211(wl);
 	if (ret)
 		goto out_platform;
@@ -1923,21 +2190,10 @@ static int __devexit wl1271_remove(struc
 {
 	struct wl1271 *wl = dev_get_drvdata(&spi->dev);
 
-	ieee80211_unregister_hw(wl->hw);
-
-	wl1271_debugfs_exit(wl);
 	platform_device_unregister(&wl1271_device);
 	free_irq(wl->irq, wl);
-	kfree(wl->target_mem_map);
-	vfree(wl->fw);
-	wl->fw = NULL;
-	kfree(wl->nvs);
-	wl->nvs = NULL;
-
-	kfree(wl->fw_status);
-	kfree(wl->tx_res_if);
 
-	ieee80211_free_hw(wl->hw);
+	wl1271_free_hw(wl);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include "wl1271_reg.h"
 #include "wl1271_ps.h"
 #include "wl1271_spi.h"
+#include "wl1271_io.h"
 
 #define WL1271_WAKEUP_TIMEOUT 500
 
@@ -39,12 +40,13 @@ void wl1271_elp_work(struct work_struct
 
 	mutex_lock(&wl->mutex);
 
-	if (wl->elp || !wl->psm)
+	if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) ||
+	    !test_bit(WL1271_FLAG_PSM, &wl->flags))
 		goto out;
 
 	wl1271_debug(DEBUG_PSM, "chip to elp");
 	wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
-	wl->elp = true;
+	set_bit(WL1271_FLAG_IN_ELP, &wl->flags);
 
 out:
 	mutex_unlock(&wl->mutex);
@@ -55,7 +57,7 @@ out:
 /* Routines to toggle sleep mode while in ELP */
 void wl1271_ps_elp_sleep(struct wl1271 *wl)
 {
-	if (wl->psm) {
+	if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {
 		cancel_delayed_work(&wl->elp_work);
 		ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
 					msecs_to_jiffies(ELP_ENTRY_DELAY));
@@ -70,7 +72,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *
 	u32 start_time = jiffies;
 	bool pending = false;
 
-	if (!wl->elp)
+	if (!test_bit(WL1271_FLAG_IN_ELP, &wl->flags))
 		return 0;
 
 	wl1271_debug(DEBUG_PSM, "waking up chip from elp");
@@ -101,7 +103,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *
 		}
 	}
 
-	wl->elp = false;
+	clear_bit(WL1271_FLAG_IN_ELP, &wl->flags);
 
 	wl1271_debug(DEBUG_PSM, "wakeup time: %u ms",
 		     jiffies_to_msecs(jiffies - start_time));
@@ -117,7 +119,8 @@ out:
 	return 0;
 }
 
-int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode)
+int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
+		       bool send)
 {
 	int ret;
 
@@ -125,25 +128,11 @@ int wl1271_ps_set_mode(struct wl1271 *wl
 	case STATION_POWER_SAVE_MODE:
 		wl1271_debug(DEBUG_PSM, "entering psm");
 
-		/* enable beacon filtering */
-		ret = wl1271_acx_beacon_filter_opt(wl, true);
-		if (ret < 0)
-			return ret;
-
-		/* enable beacon early termination */
-		ret = wl1271_acx_bet_enable(wl, true);
-		if (ret < 0)
-			return ret;
-
-		ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
-		if (ret < 0)
-			return ret;
-
-		wl1271_ps_elp_sleep(wl);
+		ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, send);
 		if (ret < 0)
 			return ret;
 
-		wl->psm = 1;
+		set_bit(WL1271_FLAG_PSM, &wl->flags);
 		break;
 	case STATION_ACTIVE_MODE:
 	default:
@@ -162,11 +151,11 @@ int wl1271_ps_set_mode(struct wl1271 *wl
 		if (ret < 0)
 			return ret;
 
-		ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
+		ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, send);
 		if (ret < 0)
 			return ret;
 
-		wl->psm = 0;
+		clear_bit(WL1271_FLAG_PSM, &wl->flags);
 		break;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.h	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,8 @@
 #include "wl1271.h"
 #include "wl1271_acx.h"
 
-int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode);
+int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
+		       bool send);
 void wl1271_ps_elp_sleep(struct wl1271 *wl);
 int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake);
 void wl1271_elp_work(struct work_struct *work);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_reg.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_reg.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_reg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_reg.h	2010-05-16 17:17:36.000000000 -0400
@@ -62,73 +62,10 @@
 #define WL1271_SLV_REG_DATA            (REGISTERS_BASE + 0x0008)
 #define WL1271_SLV_REG_ADATA           (REGISTERS_BASE + 0x000c)
 #define WL1271_SLV_MEM_DATA            (REGISTERS_BASE + 0x0018)
-/*
- * Interrupt registers.
- * 64 bit interrupt sources registers ws ced.
- * sme interupts were removed and new ones were added.
- * Order was changed.
- */
-#define FIQ_MASK                       (REGISTERS_BASE + 0x0400)
-#define FIQ_MASK_L                     (REGISTERS_BASE + 0x0400)
-#define FIQ_MASK_H                     (REGISTERS_BASE + 0x0404)
-#define FIQ_MASK_SET                   (REGISTERS_BASE + 0x0408)
-#define FIQ_MASK_SET_L                 (REGISTERS_BASE + 0x0408)
-#define FIQ_MASK_SET_H                 (REGISTERS_BASE + 0x040C)
-#define FIQ_MASK_CLR                   (REGISTERS_BASE + 0x0410)
-#define FIQ_MASK_CLR_L                 (REGISTERS_BASE + 0x0410)
-#define FIQ_MASK_CLR_H                 (REGISTERS_BASE + 0x0414)
-#define IRQ_MASK                       (REGISTERS_BASE + 0x0418)
-#define IRQ_MASK_L                     (REGISTERS_BASE + 0x0418)
-#define IRQ_MASK_H                     (REGISTERS_BASE + 0x041C)
-#define IRQ_MASK_SET                   (REGISTERS_BASE + 0x0420)
-#define IRQ_MASK_SET_L                 (REGISTERS_BASE + 0x0420)
-#define IRQ_MASK_SET_H                 (REGISTERS_BASE + 0x0424)
-#define IRQ_MASK_CLR                   (REGISTERS_BASE + 0x0428)
-#define IRQ_MASK_CLR_L                 (REGISTERS_BASE + 0x0428)
-#define IRQ_MASK_CLR_H                 (REGISTERS_BASE + 0x042C)
-#define ECPU_MASK                      (REGISTERS_BASE + 0x0448)
-#define FIQ_STS_L                      (REGISTERS_BASE + 0x044C)
-#define FIQ_STS_H                      (REGISTERS_BASE + 0x0450)
-#define IRQ_STS_L                      (REGISTERS_BASE + 0x0454)
-#define IRQ_STS_H                      (REGISTERS_BASE + 0x0458)
-#define INT_STS_ND                     (REGISTERS_BASE + 0x0464)
-#define INT_STS_RAW_L                  (REGISTERS_BASE + 0x0464)
-#define INT_STS_RAW_H                  (REGISTERS_BASE + 0x0468)
-#define INT_STS_CLR                    (REGISTERS_BASE + 0x04B4)
-#define INT_STS_CLR_L                  (REGISTERS_BASE + 0x04B4)
-#define INT_STS_CLR_H                  (REGISTERS_BASE + 0x04B8)
-#define INT_ACK                        (REGISTERS_BASE + 0x046C)
-#define INT_ACK_L                      (REGISTERS_BASE + 0x046C)
-#define INT_ACK_H                      (REGISTERS_BASE + 0x0470)
-#define INT_TRIG                       (REGISTERS_BASE + 0x0474)
-#define INT_TRIG_L                     (REGISTERS_BASE + 0x0474)
-#define INT_TRIG_H                     (REGISTERS_BASE + 0x0478)
-#define HOST_STS_L                     (REGISTERS_BASE + 0x045C)
-#define HOST_STS_H                     (REGISTERS_BASE + 0x0460)
-#define HOST_MASK                      (REGISTERS_BASE + 0x0430)
-#define HOST_MASK_L                    (REGISTERS_BASE + 0x0430)
-#define HOST_MASK_H                    (REGISTERS_BASE + 0x0434)
-#define HOST_MASK_SET                  (REGISTERS_BASE + 0x0438)
-#define HOST_MASK_SET_L                (REGISTERS_BASE + 0x0438)
-#define HOST_MASK_SET_H                (REGISTERS_BASE + 0x043C)
-#define HOST_MASK_CLR                  (REGISTERS_BASE + 0x0440)
-#define HOST_MASK_CLR_L                (REGISTERS_BASE + 0x0440)
-#define HOST_MASK_CLR_H                (REGISTERS_BASE + 0x0444)
 
 #define ACX_REG_INTERRUPT_TRIG         (REGISTERS_BASE + 0x0474)
 #define ACX_REG_INTERRUPT_TRIG_H       (REGISTERS_BASE + 0x0478)
 
-/* Host Interrupts*/
-#define HINT_MASK                      (REGISTERS_BASE + 0x0494)
-#define HINT_MASK_SET                  (REGISTERS_BASE + 0x0498)
-#define HINT_MASK_CLR                  (REGISTERS_BASE + 0x049C)
-#define HINT_STS_ND_MASKED             (REGISTERS_BASE + 0x04A0)
-/*1150 spec calls this HINT_STS_RAW*/
-#define HINT_STS_ND		       (REGISTERS_BASE + 0x04B0)
-#define HINT_STS_CLR                   (REGISTERS_BASE + 0x04A4)
-#define HINT_ACK                       (REGISTERS_BASE + 0x04A8)
-#define HINT_TRIG                      (REGISTERS_BASE + 0x04AC)
-
 /*=============================================
   Host Interrupt Mask Register - 32bit (RW)
   ------------------------------------------
@@ -433,16 +370,6 @@
 
 
 /*===============================================
-  Phy regs
- ===============================================*/
-#define ACX_PHY_ADDR_REG                SBB_ADDR
-#define ACX_PHY_DATA_REG                SBB_DATA
-#define ACX_PHY_CTRL_REG                SBB_CTL
-#define ACX_PHY_REG_WR_MASK             0x00000001ul
-#define ACX_PHY_REG_RD_MASK             0x00000002ul
-
-
-/*===============================================
  EEPROM Read/Write Request 32bit RW
  ------------------------------------------
  1 EE_READ - EEPROM Read Request 1 - Setting this bit
@@ -511,28 +438,6 @@
 #define ACX_CONT_WIND_MIN_MASK   0x0000007f
 #define ACX_CONT_WIND_MAX        0x03ff0000
 
-/*
- * Indirect slave register/memory registers
- * ----------------------------------------
- */
-#define HW_SLAVE_REG_ADDR_REG		0x00000004
-#define HW_SLAVE_REG_DATA_REG		0x00000008
-#define HW_SLAVE_REG_CTRL_REG		0x0000000c
-
-#define SLAVE_AUTO_INC				0x00010000
-#define SLAVE_NO_AUTO_INC			0x00000000
-#define SLAVE_HOST_LITTLE_ENDIAN	0x00000000
-
-#define HW_SLAVE_MEM_ADDR_REG		SLV_MEM_ADDR
-#define HW_SLAVE_MEM_DATA_REG		SLV_MEM_DATA
-#define HW_SLAVE_MEM_CTRL_REG		SLV_MEM_CTL
-#define HW_SLAVE_MEM_ENDIAN_REG		SLV_END_CTL
-
-#define HW_FUNC_EVENT_INT_EN		0x8000
-#define HW_FUNC_EVENT_MASK_REG		0x00000034
-
-#define ACX_MAC_TIMESTAMP_REG	(MAC_TIMESTAMP)
-
 /*===============================================
   HI_CFG Interface Configuration Register Values
   ------------------------------------------
@@ -647,10 +552,6 @@ b12-b0 - Supported Rate indicator bits a
 ******************************************************************************/
 
 
-#define TNETW1251_CHIP_ID_PG1_0         0x07010101
-#define TNETW1251_CHIP_ID_PG1_1         0x07020101
-#define TNETW1251_CHIP_ID_PG1_2	        0x07030101
-
 /*************************************************************************
 
     Interrupt Trigger Register (Host -> WiLink)
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_rx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_rx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,11 +21,14 @@
  *
  */
 
+#include <linux/gfp.h>
+
 #include "wl1271.h"
 #include "wl1271_acx.h"
 #include "wl1271_reg.h"
 #include "wl1271_rx.h"
 #include "wl1271_spi.h"
+#include "wl1271_io.h"
 
 static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status,
 				  u32 drv_rx_counter)
@@ -166,7 +169,7 @@ static void wl1271_rx_handle_data(struct
 	}
 
 	buf = skb_put(skb, length);
-	wl1271_spi_read(wl, WL1271_SLV_MEM_DATA, buf, length, true);
+	wl1271_read(wl, WL1271_SLV_MEM_DATA, buf, length, true);
 
 	/* the data read starts with the descriptor */
 	desc = (struct wl1271_rx_descriptor *) buf;
@@ -210,15 +213,13 @@ void wl1271_rx(struct wl1271 *wl, struct
 			wl->rx_mem_pool_addr.addr + 4;
 
 		/* Choose the block we want to read */
-		wl1271_spi_write(wl, WL1271_SLV_REG_DATA,
-				 &wl->rx_mem_pool_addr,
-				 sizeof(wl->rx_mem_pool_addr), false);
+		wl1271_write(wl, WL1271_SLV_REG_DATA, &wl->rx_mem_pool_addr,
+			     sizeof(wl->rx_mem_pool_addr), false);
 
 		wl1271_rx_handle_data(wl, buf_size);
 
 		wl->rx_counter++;
 		drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
+		wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
 	}
-
-	wl1271_spi_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,33 +25,12 @@
 #include <linux/platform_device.h>
 #include <linux/crc7.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 
 #include "wl1271.h"
 #include "wl12xx_80211.h"
 #include "wl1271_spi.h"
 
-static int wl1271_translate_addr(struct wl1271 *wl, int addr)
-{
-	/*
-	 * To translate, first check to which window of addresses the
-	 * particular address belongs. Then subtract the starting address
-	 * of that window from the address. Then, add offset of the
-	 * translated region.
-	 *
-	 * The translated regions occur next to each other in physical device
-	 * memory, so just add the sizes of the preceeding address regions to
-	 * get the offset to the new region.
-	 *
-	 * Currently, only the two first regions are addressed, and the
-	 * assumption is that all addresses will fall into either of those
-	 * two.
-	 */
-	if ((addr >= wl->part.reg.start) &&
-	    (addr < wl->part.reg.start + wl->part.reg.size))
-		return addr - wl->part.reg.start + wl->part.mem.size;
-	else
-		return addr - wl->part.mem.start;
-}
 
 void wl1271_spi_reset(struct wl1271 *wl)
 {
@@ -133,67 +112,6 @@ void wl1271_spi_init(struct wl1271 *wl)
 	wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
 }
 
-/* Set the SPI partitions to access the chip addresses
- *
- * To simplify driver code, a fixed (virtual) memory map is defined for
- * register and memory addresses. Because in the chipset, in different stages
- * of operation, those addresses will move around, an address translation
- * mechanism is required.
- *
- * There are four partitions (three memory and one register partition),
- * which are mapped to two different areas of the hardware memory.
- *
- *                                Virtual address
- *                                     space
- *
- *                                    |    |
- *                                 ...+----+--> mem.start
- *          Physical address    ...   |    |
- *               space       ...      |    | [PART_0]
- *                        ...         |    |
- *  00000000  <--+----+...         ...+----+--> mem.start + mem.size
- *               |    |         ...   |    |
- *               |MEM |      ...      |    |
- *               |    |   ...         |    |
- *  mem.size  <--+----+...            |    | {unused area)
- *               |    |   ...         |    |
- *               |REG |      ...      |    |
- *  mem.size     |    |         ...   |    |
- *      +     <--+----+...         ...+----+--> reg.start
- *  reg.size     |    |   ...         |    |
- *               |MEM2|      ...      |    | [PART_1]
- *               |    |         ...   |    |
- *                                 ...+----+--> reg.start + reg.size
- *                                    |    |
- *
- */
-int wl1271_set_partition(struct wl1271 *wl,
-			 struct wl1271_partition_set *p)
-{
-	/* copy partition info */
-	memcpy(&wl->part, p, sizeof(*p));
-
-	wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-		     p->mem.start, p->mem.size);
-	wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-		     p->reg.start, p->reg.size);
-	wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X",
-		     p->mem2.start, p->mem2.size);
-	wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X",
-		     p->mem3.start, p->mem3.size);
-
-	/* write partition info to the chipset */
-	wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start);
-	wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size);
-	wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start);
-	wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size);
-	wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start);
-	wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size);
-	wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start);
-
-	return 0;
-}
-
 #define WL1271_BUSY_WORD_TIMEOUT 1000
 
 /* FIXME: Check busy words, removed due to SPI bug */
@@ -338,78 +256,3 @@ void wl1271_spi_raw_write(struct wl1271
 	wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
 	wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
 }
-
-void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf, size_t len,
-		     bool fixed)
-{
-	int physical;
-
-	physical = wl1271_translate_addr(wl, addr);
-
-	wl1271_spi_raw_read(wl, physical, buf, len, fixed);
-}
-
-void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf, size_t len,
-		      bool fixed)
-{
-	int physical;
-
-	physical = wl1271_translate_addr(wl, addr);
-
-	wl1271_spi_raw_write(wl, physical, buf, len, fixed);
-}
-
-u32 wl1271_spi_read32(struct wl1271 *wl, int addr)
-{
-	return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr));
-}
-
-void wl1271_spi_write32(struct wl1271 *wl, int addr, u32 val)
-{
-	wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val);
-}
-
-void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val)
-{
-	/* write address >> 1 + 0x30000 to OCP_POR_CTR */
-	addr = (addr >> 1) + 0x30000;
-	wl1271_spi_write32(wl, OCP_POR_CTR, addr);
-
-	/* write value to OCP_POR_WDATA */
-	wl1271_spi_write32(wl, OCP_DATA_WRITE, val);
-
-	/* write 1 to OCP_CMD */
-	wl1271_spi_write32(wl, OCP_CMD, OCP_CMD_WRITE);
-}
-
-u16 wl1271_top_reg_read(struct wl1271 *wl, int addr)
-{
-	u32 val;
-	int timeout = OCP_CMD_LOOP;
-
-	/* write address >> 1 + 0x30000 to OCP_POR_CTR */
-	addr = (addr >> 1) + 0x30000;
-	wl1271_spi_write32(wl, OCP_POR_CTR, addr);
-
-	/* write 2 to OCP_CMD */
-	wl1271_spi_write32(wl, OCP_CMD, OCP_CMD_READ);
-
-	/* poll for data ready */
-	do {
-		val = wl1271_spi_read32(wl, OCP_DATA_READ);
-		timeout--;
-	} while (!(val & OCP_READY_MASK) && timeout);
-
-	if (!timeout) {
-		wl1271_warning("Top register access timed out.");
-		return 0xffff;
-	}
-
-	/* check data status and return if OK */
-	if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)
-		return val & 0xffff;
-	else {
-		wl1271_warning("Top register access returned error.");
-		return 0xffff;
-	}
-}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.h	2010-05-16 17:17:36.000000000 -0400
@@ -90,37 +90,7 @@ void wl1271_spi_raw_write(struct wl1271
 void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
 		     size_t len, bool fixed);
 
-/* Translated target IO */
-void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf, size_t len,
-		     bool fixed);
-void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf, size_t len,
-		      bool fixed);
-u32 wl1271_spi_read32(struct wl1271 *wl, int addr);
-void wl1271_spi_write32(struct wl1271 *wl, int addr, u32 val);
-
-/* Top Register IO */
-void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val);
-u16 wl1271_top_reg_read(struct wl1271 *wl, int addr);
-
 /* INIT and RESET words */
 void wl1271_spi_reset(struct wl1271 *wl);
 void wl1271_spi_init(struct wl1271 *wl);
-int wl1271_set_partition(struct wl1271 *wl,
-			 struct wl1271_partition_set *p);
-
-static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr)
-{
-	wl1271_spi_raw_read(wl, addr, &wl->buffer_32,
-			    sizeof(wl->buffer_32), false);
-
-	return wl->buffer_32;
-}
-
-static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val)
-{
-	wl->buffer_32 = val;
-	wl1271_spi_raw_write(wl, addr, &wl->buffer_32,
-			     sizeof(wl->buffer_32), false);
-}
-
 #endif /* __WL1271_SPI_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_testmode.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_testmode.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_testmode.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_testmode.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,284 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#include "wl1271_testmode.h"
+
+#include <linux/slab.h>
+#include <net/genetlink.h>
+
+#include "wl1271.h"
+#include "wl1271_spi.h"
+#include "wl1271_acx.h"
+
+#define WL1271_TM_MAX_DATA_LENGTH 1024
+
+enum wl1271_tm_commands {
+	WL1271_TM_CMD_UNSPEC,
+	WL1271_TM_CMD_TEST,
+	WL1271_TM_CMD_INTERROGATE,
+	WL1271_TM_CMD_CONFIGURE,
+	WL1271_TM_CMD_NVS_PUSH,
+	WL1271_TM_CMD_SET_PLT_MODE,
+
+	__WL1271_TM_CMD_AFTER_LAST
+};
+#define WL1271_TM_CMD_MAX (__WL1271_TM_CMD_AFTER_LAST - 1)
+
+enum wl1271_tm_attrs {
+	WL1271_TM_ATTR_UNSPEC,
+	WL1271_TM_ATTR_CMD_ID,
+	WL1271_TM_ATTR_ANSWER,
+	WL1271_TM_ATTR_DATA,
+	WL1271_TM_ATTR_IE_ID,
+	WL1271_TM_ATTR_PLT_MODE,
+
+	__WL1271_TM_ATTR_AFTER_LAST
+};
+#define WL1271_TM_ATTR_MAX (__WL1271_TM_ATTR_AFTER_LAST - 1)
+
+static struct nla_policy wl1271_tm_policy[WL1271_TM_ATTR_MAX + 1] = {
+	[WL1271_TM_ATTR_CMD_ID] =	{ .type = NLA_U32 },
+	[WL1271_TM_ATTR_ANSWER] =	{ .type = NLA_U8 },
+	[WL1271_TM_ATTR_DATA] =		{ .type = NLA_BINARY,
+					  .len = WL1271_TM_MAX_DATA_LENGTH },
+	[WL1271_TM_ATTR_IE_ID] =	{ .type = NLA_U32 },
+	[WL1271_TM_ATTR_PLT_MODE] =	{ .type = NLA_U32 },
+};
+
+
+static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[])
+{
+	int buf_len, ret, len;
+	struct sk_buff *skb;
+	void *buf;
+	u8 answer = 0;
+
+	wl1271_debug(DEBUG_TESTMODE, "testmode cmd test");
+
+	if (!tb[WL1271_TM_ATTR_DATA])
+		return -EINVAL;
+
+	buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
+	buf_len = nla_len(tb[WL1271_TM_ATTR_DATA]);
+
+	if (tb[WL1271_TM_ATTR_ANSWER])
+		answer = nla_get_u8(tb[WL1271_TM_ATTR_ANSWER]);
+
+	if (buf_len > sizeof(struct wl1271_command))
+		return -EMSGSIZE;
+
+	mutex_lock(&wl->mutex);
+	ret = wl1271_cmd_test(wl, buf, buf_len, answer);
+	mutex_unlock(&wl->mutex);
+
+	if (ret < 0) {
+		wl1271_warning("testmode cmd test failed: %d", ret);
+		return ret;
+	}
+
+	if (answer) {
+		len = nla_total_size(buf_len);
+		skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, len);
+		if (!skb)
+			return -ENOMEM;
+
+		NLA_PUT(skb, WL1271_TM_ATTR_DATA, buf_len, buf);
+		ret = cfg80211_testmode_reply(skb);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -EMSGSIZE;
+}
+
+static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[])
+{
+	int ret;
+	struct wl1271_command *cmd;
+	struct sk_buff *skb;
+	u8 ie_id;
+
+	wl1271_debug(DEBUG_TESTMODE, "testmode cmd interrogate");
+
+	if (!tb[WL1271_TM_ATTR_IE_ID])
+		return -EINVAL;
+
+	ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]);
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	mutex_lock(&wl->mutex);
+	ret = wl1271_cmd_interrogate(wl, ie_id, cmd, sizeof(*cmd));
+	mutex_unlock(&wl->mutex);
+
+	if (ret < 0) {
+		wl1271_warning("testmode cmd interrogate failed: %d", ret);
+		return ret;
+	}
+
+	skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	NLA_PUT(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd);
+
+	return 0;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -EMSGSIZE;
+}
+
+static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[])
+{
+	int buf_len, ret;
+	void *buf;
+	u8 ie_id;
+
+	wl1271_debug(DEBUG_TESTMODE, "testmode cmd configure");
+
+	if (!tb[WL1271_TM_ATTR_DATA])
+		return -EINVAL;
+	if (!tb[WL1271_TM_ATTR_IE_ID])
+		return -EINVAL;
+
+	ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]);
+	buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
+	buf_len = nla_len(tb[WL1271_TM_ATTR_DATA]);
+
+	if (buf_len > sizeof(struct wl1271_command))
+		return -EMSGSIZE;
+
+	mutex_lock(&wl->mutex);
+	ret = wl1271_cmd_configure(wl, ie_id, buf, buf_len);
+	mutex_unlock(&wl->mutex);
+
+	if (ret < 0) {
+		wl1271_warning("testmode cmd configure failed: %d", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
+{
+	int ret = 0;
+	size_t len;
+	void *buf;
+
+	wl1271_debug(DEBUG_TESTMODE, "testmode cmd nvs push");
+
+	if (!tb[WL1271_TM_ATTR_DATA])
+		return -EINVAL;
+
+	buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
+	len = nla_len(tb[WL1271_TM_ATTR_DATA]);
+
+	if (len != sizeof(struct wl1271_nvs_file)) {
+		wl1271_error("nvs size is not as expected: %zu != %zu",
+			     len, sizeof(struct wl1271_nvs_file));
+		return -EMSGSIZE;
+	}
+
+	mutex_lock(&wl->mutex);
+
+	kfree(wl->nvs);
+
+	wl->nvs = kmalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL);
+	if (!wl->nvs) {
+		wl1271_error("could not allocate memory for the nvs file");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy(wl->nvs, buf, len);
+
+	wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs");
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
+static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[])
+{
+	u32 val;
+	int ret;
+
+	wl1271_debug(DEBUG_TESTMODE, "testmode cmd set plt mode");
+
+	if (!tb[WL1271_TM_ATTR_PLT_MODE])
+		return -EINVAL;
+
+	val = nla_get_u32(tb[WL1271_TM_ATTR_PLT_MODE]);
+
+	switch (val) {
+	case 0:
+		ret = wl1271_plt_stop(wl);
+		break;
+	case 1:
+		ret = wl1271_plt_start(wl);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)
+{
+	struct wl1271 *wl = hw->priv;
+	struct nlattr *tb[WL1271_TM_ATTR_MAX + 1];
+	int err;
+
+	err = nla_parse(tb, WL1271_TM_ATTR_MAX, data, len, wl1271_tm_policy);
+	if (err)
+		return err;
+
+	if (!tb[WL1271_TM_ATTR_CMD_ID])
+		return -EINVAL;
+
+	switch (nla_get_u32(tb[WL1271_TM_ATTR_CMD_ID])) {
+	case WL1271_TM_CMD_TEST:
+		return wl1271_tm_cmd_test(wl, tb);
+	case WL1271_TM_CMD_INTERROGATE:
+		return wl1271_tm_cmd_interrogate(wl, tb);
+	case WL1271_TM_CMD_CONFIGURE:
+		return wl1271_tm_cmd_configure(wl, tb);
+	case WL1271_TM_CMD_NVS_PUSH:
+		return wl1271_tm_cmd_nvs_push(wl, tb);
+	case WL1271_TM_CMD_SET_PLT_MODE:
+		return wl1271_tm_cmd_set_plt_mode(wl, tb);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_testmode.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_testmode.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_testmode.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_testmode.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,31 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL1271_TESTMODE_H__
+#define __WL1271_TESTMODE_H__
+
+#include <net/mac80211.h>
+
+int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len);
+
+#endif /* __WL1271_TESTMODE_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.c linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 
 #include "wl1271.h"
 #include "wl1271_spi.h"
+#include "wl1271_io.h"
 #include "wl1271_reg.h"
 #include "wl1271_ps.h"
 #include "wl1271_tx.h"
@@ -87,7 +88,7 @@ static int wl1271_tx_fill_hdr(struct wl1
 			      u32 extra, struct ieee80211_tx_info *control)
 {
 	struct wl1271_tx_hw_descr *desc;
-	int pad;
+	int pad, ac;
 	u16 tx_attr;
 
 	desc = (struct wl1271_tx_hw_descr *) skb->data;
@@ -107,9 +108,11 @@ static int wl1271_tx_fill_hdr(struct wl1
 
 	/* configure the tx attributes */
 	tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
-	/* FIXME: do we know the packet priority? can we identify mgmt
-	   packets, and use max prio for them at least? */
-	desc->tid = 0;
+
+	/* queue */
+	ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
+	desc->tid = wl1271_tx_ac_to_tid(ac);
+
 	desc->aid = TX_HW_DEFAULT_AID;
 	desc->reserved = 0;
 
@@ -121,6 +124,11 @@ static int wl1271_tx_fill_hdr(struct wl1
 	pad = pad - skb->len;
 	tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD;
 
+	/* if the packets are destined for AP (have a STA entry) send them
+	   with AP rate policies, otherwise use default basic rates */
+	if (control->control.sta)
+		tx_attr |= ACX_TX_AP_FULL_RATE << TX_HW_ATTR_OFST_RATE_POLICY;
+
 	desc->tx_attr = cpu_to_le16(tx_attr);
 
 	wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad);
@@ -158,11 +166,11 @@ static int wl1271_tx_send_packet(struct
 	len = WL1271_TX_ALIGN(skb->len);
 
 	/* perform a fixed address block write with the packet */
-	wl1271_spi_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true);
+	wl1271_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true);
 
 	/* write packet new counter into the write access register */
 	wl->tx_packets_count++;
-	wl1271_spi_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
+	wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
 
 	desc = (struct wl1271_tx_hw_descr *) skb->data;
 	wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)",
@@ -196,6 +204,7 @@ static int wl1271_tx_frame(struct wl1271
 			ret = wl1271_cmd_set_default_wep_key(wl, idx);
 			if (ret < 0)
 				return ret;
+			wl->default_key = idx;
 		}
 	}
 
@@ -214,18 +223,50 @@ static int wl1271_tx_frame(struct wl1271
 	return ret;
 }
 
+static u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
+{
+	struct ieee80211_supported_band *band;
+	u32 enabled_rates = 0;
+	int bit;
+
+	band = wl->hw->wiphy->bands[wl->band];
+	for (bit = 0; bit < band->n_bitrates; bit++) {
+		if (rate_set & 0x1)
+			enabled_rates |= band->bitrates[bit].hw_value;
+		rate_set >>= 1;
+	}
+
+	return enabled_rates;
+}
+
 void wl1271_tx_work(struct work_struct *work)
 {
 	struct wl1271 *wl = container_of(work, struct wl1271, tx_work);
 	struct sk_buff *skb;
 	bool woken_up = false;
+	u32 sta_rates = 0;
 	int ret;
 
+	/* check if the rates supported by the AP have changed */
+	if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED,
+					&wl->flags))) {
+		unsigned long flags;
+		spin_lock_irqsave(&wl->wl_lock, flags);
+		sta_rates = wl->sta_rate_set;
+		spin_unlock_irqrestore(&wl->wl_lock, flags);
+	}
+
 	mutex_lock(&wl->mutex);
 
 	if (unlikely(wl->state == WL1271_STATE_OFF))
 		goto out;
 
+	/* if rates have changed, re-configure the rate policy */
+	if (unlikely(sta_rates)) {
+		wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates);
+		wl1271_acx_rate_policies(wl);
+	}
+
 	while ((skb = skb_dequeue(&wl->tx_queue))) {
 		if (!woken_up) {
 			ret = wl1271_ps_elp_wakeup(wl, false);
@@ -240,18 +281,18 @@ void wl1271_tx_work(struct work_struct *
 			wl1271_debug(DEBUG_TX, "tx_work: fw buffer full, "
 				     "stop queues");
 			ieee80211_stop_queues(wl->hw);
-			wl->tx_queue_stopped = true;
+			set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
 			skb_queue_head(&wl->tx_queue, skb);
 			goto out;
 		} else if (ret < 0) {
 			dev_kfree_skb(skb);
 			goto out;
-		} else if (wl->tx_queue_stopped) {
+		} else if (test_and_clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED,
+					      &wl->flags)) {
 			/* firmware buffer has space, restart queues */
 			wl1271_debug(DEBUG_TX,
 				     "complete_packet: waking queues");
 			ieee80211_wake_queues(wl->hw);
-			wl->tx_queue_stopped = false;
 		}
 	}
 
@@ -335,8 +376,8 @@ void wl1271_tx_complete(struct wl1271 *w
 	wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count);
 
 	/* read the tx results from the chipset */
-	wl1271_spi_read(wl, le32_to_cpu(memmap->tx_result),
-			wl->tx_res_if, sizeof(*wl->tx_res_if), false);
+	wl1271_read(wl, le32_to_cpu(memmap->tx_result),
+		    wl->tx_res_if, sizeof(*wl->tx_res_if), false);
 
 	/* verify that the result buffer is not getting overrun */
 	if (count > TX_HW_RESULT_QUEUE_LEN) {
@@ -357,10 +398,10 @@ void wl1271_tx_complete(struct wl1271 *w
 	}
 
 	/* write host counter to chipset (to ack) */
-	wl1271_spi_write32(wl, le32_to_cpu(memmap->tx_result) +
-			   offsetof(struct wl1271_tx_hw_res_if,
-				    tx_result_host_counter),
-			   le32_to_cpu(wl->tx_res_if->tx_result_fw_counter));
+	wl1271_write32(wl, le32_to_cpu(memmap->tx_result) +
+		       offsetof(struct wl1271_tx_hw_res_if,
+		       tx_result_host_counter),
+		       le32_to_cpu(wl->tx_res_if->tx_result_fw_counter));
 }
 
 /* caller must hold wl->mutex */
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.h linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.h
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.h	2010-05-16 17:17:36.000000000 -0400
@@ -123,6 +123,42 @@ struct wl1271_tx_hw_res_if {
 	struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN];
 } __attribute__ ((packed));
 
+static inline int wl1271_tx_get_queue(int queue)
+{
+	/* FIXME: use best effort until WMM is enabled */
+	return CONF_TX_AC_BE;
+
+	switch (queue) {
+	case 0:
+		return CONF_TX_AC_VO;
+	case 1:
+		return CONF_TX_AC_VI;
+	case 2:
+		return CONF_TX_AC_BE;
+	case 3:
+		return CONF_TX_AC_BK;
+	default:
+		return CONF_TX_AC_BE;
+	}
+}
+
+/* wl1271 tx descriptor needs the tid and we need to convert it from ac */
+static inline int wl1271_tx_ac_to_tid(int ac)
+{
+	switch (ac) {
+	case 0:
+		return 0;
+	case 1:
+		return 2;
+	case 2:
+		return 4;
+	case 3:
+		return 6;
+	default:
+		return 0;
+	}
+}
+
 void wl1271_tx_work(struct work_struct *work);
 void wl1271_tx_complete(struct wl1271 *wl, u32 count);
 void wl1271_tx_flush(struct wl1271 *wl);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1201.c linux-libre-2.6.34-gnu1/drivers/net/wireless/zd1201.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1201.c	2013-05-03 12:11:47.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/zd1201.c	2013-05-03 09:51:19.000000000 -0400
@@ -14,6 +14,7 @@
 
 #include <linux/module.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
@@ -874,20 +875,18 @@ static struct iw_statistics *zd1201_get_
 static void zd1201_set_multicast(struct net_device *dev)
 {
 	struct zd1201 *zd = netdev_priv(dev);
-	struct dev_mc_list *mc = dev->mc_list;
+	struct dev_mc_list *mc;
 	unsigned char reqbuf[ETH_ALEN*ZD1201_MAXMULTI];
 	int i;
 
-	if (dev->mc_count > ZD1201_MAXMULTI)
+	if (netdev_mc_count(dev) > ZD1201_MAXMULTI)
 		return;
 
-	for (i=0; i<dev->mc_count; i++) {
-		memcpy(reqbuf+i*ETH_ALEN, mc->dmi_addr, ETH_ALEN);
-		mc = mc->next;
-	}
+	i = 0;
+	netdev_for_each_mc_addr(mc, dev)
+		memcpy(reqbuf + i++ * ETH_ALEN, mc->dmi_addr, ETH_ALEN);
 	zd1201_setconfig(zd, ZD1201_RID_CNFGROUPADDRESS, reqbuf,
-	    dev->mc_count*ETH_ALEN, 0);
-	
+			 netdev_mc_count(dev) * ETH_ALEN, 0);
 }
 
 static int zd1201_config_commit(struct net_device *dev, 
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_chip.c linux-libre-2.6.34-gnu1/drivers/net/wireless/zd1211rw/zd_chip.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_chip.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/zd1211rw/zd_chip.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 
 #include "zd_def.h"
 #include "zd_chip.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_mac.c linux-libre-2.6.34-gnu1/drivers/net/wireless/zd1211rw/zd_mac.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_mac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/zd1211rw/zd_mac.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/jiffies.h>
 #include <net/ieee80211_radiotap.h>
@@ -350,7 +351,7 @@ static void zd_mac_tx_status(struct ieee
 	first_idx = info->status.rates[0].idx;
 	ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates));
 	retries = &zd_retry_rates[first_idx];
-	ZD_ASSERT(0<=retry && retry<=retries->count);
+	ZD_ASSERT(1 <= retry && retry <= retries->count);
 
 	info->status.rates[0].idx = retries->rate[0];
 	info->status.rates[0].count = 1; // (retry > 1 ? 2 : 1);
@@ -360,7 +361,7 @@ static void zd_mac_tx_status(struct ieee
 		info->status.rates[i].count = 1; // ((i==retry-1) && success ? 1:2);
 	}
 	for (; i<IEEE80211_TX_MAX_RATES && i<retry; i++) {
-		info->status.rates[i].idx = retries->rate[retry-1];
+		info->status.rates[i].idx = retries->rate[retry - 1];
 		info->status.rates[i].count = 1; // (success ? 1:2);
 	}
 	if (i<IEEE80211_TX_MAX_RATES)
@@ -374,7 +375,7 @@ static void zd_mac_tx_status(struct ieee
  * zd_mac_tx_failed - callback for failed frames
  * @dev: the mac80211 wireless device
  *
- * This function is called if a frame couldn't be successfully be
+ * This function is called if a frame couldn't be successfully
  * transferred. The first frame from the tx queue, will be selected and
  * reported as error to the upper layers.
  */
@@ -424,12 +425,10 @@ void zd_mac_tx_failed(struct urb *urb)
 		first_idx = info->status.rates[0].idx;
 		ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates));
 		retries = &zd_retry_rates[first_idx];
-		if (retry < 0 || retry > retries->count) {
+		if (retry <= 0 || retry > retries->count)
 			continue;
-		}
 
-		ZD_ASSERT(0<=retry && retry<=retries->count);
-		final_idx = retries->rate[retry-1];
+		final_idx = retries->rate[retry - 1];
 		final_rate = zd_rates[final_idx].hw_value;
 
 		if (final_rate != tx_status->rate) {
@@ -869,7 +868,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, c
 }
 
 static int zd_op_add_interface(struct ieee80211_hw *hw,
-				struct ieee80211_if_init_conf *conf)
+				struct ieee80211_vif *vif)
 {
 	struct zd_mac *mac = zd_hw_mac(hw);
 
@@ -877,22 +876,22 @@ static int zd_op_add_interface(struct ie
 	if (mac->type != NL80211_IFTYPE_UNSPECIFIED)
 		return -EOPNOTSUPP;
 
-	switch (conf->type) {
+	switch (vif->type) {
 	case NL80211_IFTYPE_MONITOR:
 	case NL80211_IFTYPE_MESH_POINT:
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_ADHOC:
-		mac->type = conf->type;
+		mac->type = vif->type;
 		break;
 	default:
 		return -EOPNOTSUPP;
 	}
 
-	return zd_write_mac_addr(&mac->chip, conf->mac_addr);
+	return zd_write_mac_addr(&mac->chip, vif->addr);
 }
 
 static void zd_op_remove_interface(struct ieee80211_hw *hw,
-				    struct ieee80211_if_init_conf *conf)
+				    struct ieee80211_vif *vif)
 {
 	struct zd_mac *mac = zd_hw_mac(hw);
 	mac->type = NL80211_IFTYPE_UNSPECIFIED;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c linux-libre-2.6.34-gnu1/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "zd_rf.h"
 #include "zd_usb.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_usb.c linux-libre-2.6.34-gnu1/drivers/net/wireless/zd1211rw/zd_usb.c
--- linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_usb.c	2013-05-03 12:11:50.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/net/wireless/zd1211rw/zd_usb.c	2013-05-03 09:51:22.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/firmware.h>
 #include <linux/device.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/usb.h>
 #include <linux/workqueue.h>
@@ -1074,11 +1075,15 @@ static int eject_installer(struct usb_in
 	int r;
 
 	/* Find bulk out endpoint */
-	endpoint = &iface_desc->endpoint[1].desc;
-	if (usb_endpoint_dir_out(endpoint) &&
-	    usb_endpoint_xfer_bulk(endpoint)) {
-		bulk_out_ep = endpoint->bEndpointAddress;
-	} else {
+	for (r = 1; r >= 0; r--) {
+		endpoint = &iface_desc->endpoint[r].desc;
+		if (usb_endpoint_dir_out(endpoint) &&
+		    usb_endpoint_xfer_bulk(endpoint)) {
+			bulk_out_ep = endpoint->bEndpointAddress;
+			break;
+		}
+	}
+	if (r == -1) {
 		dev_err(&udev->dev,
 			"zd1211rw: Could not find bulk out endpoint\n");
 		return -ENODEV;
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/xen-netfront.c linux-libre-2.6.34-gnu1/drivers/net/xen-netfront.c
--- linux-libre-2.6.33-gnu1/drivers/net/xen-netfront.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/xen-netfront.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/udp.h>
 #include <linux/moduleparam.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <net/ip.h>
 
 #include <xen/xen.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/xilinx_emaclite.c linux-libre-2.6.34-gnu1/drivers/net/xilinx_emaclite.c
--- linux-libre-2.6.33-gnu1/drivers/net/xilinx_emaclite.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/xilinx_emaclite.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,14 +19,21 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
 
 #define DRIVER_NAME "xilinx_emaclite"
 
 /* Register offsets for the EmacLite Core */
 #define XEL_TXBUFF_OFFSET 	0x0		/* Transmit Buffer */
+#define XEL_MDIOADDR_OFFSET	0x07E4		/* MDIO Address Register */
+#define XEL_MDIOWR_OFFSET	0x07E8		/* MDIO Write Data Register */
+#define XEL_MDIORD_OFFSET	0x07EC		/* MDIO Read Data Register */
+#define XEL_MDIOCTRL_OFFSET	0x07F0		/* MDIO Control Register */
 #define XEL_GIER_OFFSET		0x07F8		/* GIE Register */
 #define XEL_TSR_OFFSET		0x07FC		/* Tx status */
 #define XEL_TPLR_OFFSET		0x07F4		/* Tx packet length */
@@ -37,6 +44,22 @@
 
 #define XEL_BUFFER_OFFSET	0x0800		/* Next Tx/Rx buffer's offset */
 
+/* MDIO Address Register Bit Masks */
+#define XEL_MDIOADDR_REGADR_MASK  0x0000001F	/* Register Address */
+#define XEL_MDIOADDR_PHYADR_MASK  0x000003E0	/* PHY Address */
+#define XEL_MDIOADDR_PHYADR_SHIFT 5
+#define XEL_MDIOADDR_OP_MASK	  0x00000400	/* RD/WR Operation */
+
+/* MDIO Write Data Register Bit Masks */
+#define XEL_MDIOWR_WRDATA_MASK	  0x0000FFFF	/* Data to be Written */
+
+/* MDIO Read Data Register Bit Masks */
+#define XEL_MDIORD_RDDATA_MASK	  0x0000FFFF	/* Data to be Read */
+
+/* MDIO Control Register Bit Masks */
+#define XEL_MDIOCTRL_MDIOSTS_MASK 0x00000001	/* MDIO Status Mask */
+#define XEL_MDIOCTRL_MDIOEN_MASK  0x00000008	/* MDIO Enable */
+
 /* Global Interrupt Enable Register (GIER) Bit Masks */
 #define XEL_GIER_GIE_MASK	0x80000000 	/* Global Enable */
 
@@ -87,6 +110,12 @@
  * @reset_lock:		lock used for synchronization
  * @deferred_skb:	holds an skb (for transmission at a later time) when the
  *			Tx buffer is not free
+ * @phy_dev:		pointer to the PHY device
+ * @phy_node:		pointer to the PHY device node
+ * @mii_bus:		pointer to the MII bus
+ * @mdio_irqs:		IRQs table for MDIO bus
+ * @last_link:		last link status
+ * @has_mdio:		indicates whether MDIO is included in the HW
  */
 struct net_local {
 
@@ -100,6 +129,15 @@ struct net_local {
 
 	spinlock_t reset_lock;
 	struct sk_buff *deferred_skb;
+
+	struct phy_device *phy_dev;
+	struct device_node *phy_node;
+
+	struct mii_bus *mii_bus;
+	int mdio_irqs[PHY_MAX_ADDR];
+
+	int last_link;
+	bool has_mdio;
 };
 
 
@@ -431,7 +469,7 @@ static u16 xemaclite_recv_data(struct ne
 }
 
 /**
- * xemaclite_set_mac_address - Set the MAC address for this device
+ * xemaclite_update_address - Update the MAC address in the device
  * @drvdata:	Pointer to the Emaclite device private data
  * @address_ptr:Pointer to the MAC address (MAC address is a 48-bit value)
  *
@@ -441,8 +479,8 @@ static u16 xemaclite_recv_data(struct ne
  * The MAC address can be programmed using any of the two transmit
  * buffers (if configured).
  */
-static void xemaclite_set_mac_address(struct net_local *drvdata,
-				      u8 *address_ptr)
+static void xemaclite_update_address(struct net_local *drvdata,
+				     u8 *address_ptr)
 {
 	void __iomem *addr;
 	u32 reg_data;
@@ -465,6 +503,30 @@ static void xemaclite_set_mac_address(st
 }
 
 /**
+ * xemaclite_set_mac_address - Set the MAC address for this device
+ * @dev:	Pointer to the network device instance
+ * @addr:	Void pointer to the sockaddr structure
+ *
+ * This function copies the HW address from the sockaddr strucutre to the
+ * net_device structure and updates the address in HW.
+ *
+ * Return:	Error if the net device is busy or 0 if the addr is set
+ *		successfully
+ */
+static int xemaclite_set_mac_address(struct net_device *dev, void *address)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	struct sockaddr *addr = address;
+
+	if (netif_running(dev))
+		return -EBUSY;
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+	xemaclite_update_address(lp, dev->dev_addr);
+	return 0;
+}
+
+/**
  * xemaclite_tx_timeout - Callback for Tx Timeout
  * @dev:	Pointer to the network device
  *
@@ -641,12 +703,219 @@ static irqreturn_t xemaclite_interrupt(i
 	return IRQ_HANDLED;
 }
 
+/**********************/
+/* MDIO Bus functions */
+/**********************/
+
+/**
+ * xemaclite_mdio_wait - Wait for the MDIO to be ready to use
+ * @lp:		Pointer to the Emaclite device private data
+ *
+ * This function waits till the device is ready to accept a new MDIO
+ * request.
+ *
+ * Return:	0 for success or ETIMEDOUT for a timeout
+ */
+
+static int xemaclite_mdio_wait(struct net_local *lp)
+{
+	long end = jiffies + 2;
+
+	/* wait for the MDIO interface to not be busy or timeout
+	   after some time.
+	*/
+	while (in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET) &
+			XEL_MDIOCTRL_MDIOSTS_MASK) {
+		if (end - jiffies <= 0) {
+			WARN_ON(1);
+			return -ETIMEDOUT;
+		}
+		msleep(1);
+	}
+	return 0;
+}
+
+/**
+ * xemaclite_mdio_read - Read from a given MII management register
+ * @bus:	the mii_bus struct
+ * @phy_id:	the phy address
+ * @reg:	register number to read from
+ *
+ * This function waits till the device is ready to accept a new MDIO
+ * request and then writes the phy address to the MDIO Address register
+ * and reads data from MDIO Read Data register, when its available.
+ *
+ * Return:	Value read from the MII management register
+ */
+static int xemaclite_mdio_read(struct mii_bus *bus, int phy_id, int reg)
+{
+	struct net_local *lp = bus->priv;
+	u32 ctrl_reg;
+	u32 rc;
+
+	if (xemaclite_mdio_wait(lp))
+		return -ETIMEDOUT;
+
+	/* Write the PHY address, register number and set the OP bit in the
+	 * MDIO Address register. Set the Status bit in the MDIO Control
+	 * register to start a MDIO read transaction.
+	 */
+	ctrl_reg = in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET);
+	out_be32(lp->base_addr + XEL_MDIOADDR_OFFSET,
+		 XEL_MDIOADDR_OP_MASK |
+		 ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg));
+	out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET,
+		 ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK);
+
+	if (xemaclite_mdio_wait(lp))
+		return -ETIMEDOUT;
+
+	rc = in_be32(lp->base_addr + XEL_MDIORD_OFFSET);
+
+	dev_dbg(&lp->ndev->dev,
+		"xemaclite_mdio_read(phy_id=%i, reg=%x) == %x\n",
+		phy_id, reg, rc);
+
+	return rc;
+}
+
+/**
+ * xemaclite_mdio_write - Write to a given MII management register
+ * @bus:	the mii_bus struct
+ * @phy_id:	the phy address
+ * @reg:	register number to write to
+ * @val:	value to write to the register number specified by reg
+ *
+ * This fucntion waits till the device is ready to accept a new MDIO
+ * request and then writes the val to the MDIO Write Data register.
+ */
+static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg,
+				u16 val)
+{
+	struct net_local *lp = bus->priv;
+	u32 ctrl_reg;
+
+	dev_dbg(&lp->ndev->dev,
+		"xemaclite_mdio_write(phy_id=%i, reg=%x, val=%x)\n",
+		phy_id, reg, val);
+
+	if (xemaclite_mdio_wait(lp))
+		return -ETIMEDOUT;
+
+	/* Write the PHY address, register number and clear the OP bit in the
+	 * MDIO Address register and then write the value into the MDIO Write
+	 * Data register. Finally, set the Status bit in the MDIO Control
+	 * register to start a MDIO write transaction.
+	 */
+	ctrl_reg = in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET);
+	out_be32(lp->base_addr + XEL_MDIOADDR_OFFSET,
+		 ~XEL_MDIOADDR_OP_MASK &
+		 ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg));
+	out_be32(lp->base_addr + XEL_MDIOWR_OFFSET, val);
+	out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET,
+		 ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK);
+
+	return 0;
+}
+
+/**
+ * xemaclite_mdio_reset - Reset the mdio bus.
+ * @bus:	Pointer to the MII bus
+ *
+ * This function is required(?) as per Documentation/networking/phy.txt.
+ * There is no reset in this device; this function always returns 0.
+ */
+static int xemaclite_mdio_reset(struct mii_bus *bus)
+{
+	return 0;
+}
+
+/**
+ * xemaclite_mdio_setup - Register mii_bus for the Emaclite device
+ * @lp:		Pointer to the Emaclite device private data
+ * @ofdev:	Pointer to OF device structure
+ *
+ * This function enables MDIO bus in the Emaclite device and registers a
+ * mii_bus.
+ *
+ * Return:	0 upon success or a negative error upon failure
+ */
+static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev)
+{
+	struct mii_bus *bus;
+	int rc;
+	struct resource res;
+	struct device_node *np = of_get_parent(lp->phy_node);
+
+	/* Don't register the MDIO bus if the phy_node or its parent node
+	 * can't be found.
+	 */
+	if (!np)
+		return -ENODEV;
+
+	/* Enable the MDIO bus by asserting the enable bit in MDIO Control
+	 * register.
+	 */
+	out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET,
+		 XEL_MDIOCTRL_MDIOEN_MASK);
+
+	bus = mdiobus_alloc();
+	if (!bus)
+		return -ENOMEM;
+
+	of_address_to_resource(np, 0, &res);
+	snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx",
+		 (unsigned long long)res.start);
+	bus->priv = lp;
+	bus->name = "Xilinx Emaclite MDIO";
+	bus->read = xemaclite_mdio_read;
+	bus->write = xemaclite_mdio_write;
+	bus->reset = xemaclite_mdio_reset;
+	bus->parent = dev;
+	bus->irq = lp->mdio_irqs; /* preallocated IRQ table */
+
+	lp->mii_bus = bus;
+
+	rc = of_mdiobus_register(bus, np);
+	if (rc)
+		goto err_register;
+
+	return 0;
+
+err_register:
+	mdiobus_free(bus);
+	return rc;
+}
+
+/**
+ * xemaclite_adjust_link - Link state callback for the Emaclite device
+ * @ndev: pointer to net_device struct
+ *
+ * There's nothing in the Emaclite device to be configured when the link
+ * state changes. We just print the status.
+ */
+void xemaclite_adjust_link(struct net_device *ndev)
+{
+	struct net_local *lp = netdev_priv(ndev);
+	struct phy_device *phy = lp->phy_dev;
+	int link_state;
+
+	/* hash together the state values to decide if something has changed */
+	link_state = phy->speed | (phy->duplex << 1) | phy->link;
+
+	if (lp->last_link != link_state) {
+		lp->last_link = link_state;
+		phy_print_status(phy);
+	}
+}
+
 /**
  * xemaclite_open - Open the network device
  * @dev:	Pointer to the network device
  *
  * This function sets the MAC address, requests an IRQ and enables interrupts
  * for the Emaclite device and starts the Tx queue.
+ * It also connects to the phy device, if MDIO is included in Emaclite device.
  */
 static int xemaclite_open(struct net_device *dev)
 {
@@ -656,14 +925,47 @@ static int xemaclite_open(struct net_dev
 	/* Just to be safe, stop the device first */
 	xemaclite_disable_interrupts(lp);
 
+	if (lp->phy_node) {
+		u32 bmcr;
+
+		lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node,
+					     xemaclite_adjust_link, 0,
+					     PHY_INTERFACE_MODE_MII);
+		if (!lp->phy_dev) {
+			dev_err(&lp->ndev->dev, "of_phy_connect() failed\n");
+			return -ENODEV;
+		}
+
+		/* EmacLite doesn't support giga-bit speeds */
+		lp->phy_dev->supported &= (PHY_BASIC_FEATURES);
+		lp->phy_dev->advertising = lp->phy_dev->supported;
+
+		/* Don't advertise 1000BASE-T Full/Half duplex speeds */
+		phy_write(lp->phy_dev, MII_CTRL1000, 0);
+
+		/* Advertise only 10 and 100mbps full/half duplex speeds */
+		phy_write(lp->phy_dev, MII_ADVERTISE, ADVERTISE_ALL);
+
+		/* Restart auto negotiation */
+		bmcr = phy_read(lp->phy_dev, MII_BMCR);
+		bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
+		phy_write(lp->phy_dev, MII_BMCR, bmcr);
+
+		phy_start(lp->phy_dev);
+	}
+
 	/* Set the MAC address each time opened */
-	xemaclite_set_mac_address(lp, dev->dev_addr);
+	xemaclite_update_address(lp, dev->dev_addr);
 
 	/* Grab the IRQ */
 	retval = request_irq(dev->irq, xemaclite_interrupt, 0, dev->name, dev);
 	if (retval) {
 		dev_err(&lp->ndev->dev, "Could not allocate interrupt %d\n",
 			dev->irq);
+		if (lp->phy_dev)
+			phy_disconnect(lp->phy_dev);
+		lp->phy_dev = NULL;
+
 		return retval;
 	}
 
@@ -682,6 +984,7 @@ static int xemaclite_open(struct net_dev
  *
  * This function stops the Tx queue, disables interrupts and frees the IRQ for
  * the Emaclite device.
+ * It also disconnects the phy device associated with the Emaclite device.
  */
 static int xemaclite_close(struct net_device *dev)
 {
@@ -691,6 +994,10 @@ static int xemaclite_close(struct net_de
 	xemaclite_disable_interrupts(lp);
 	free_irq(dev->irq, dev);
 
+	if (lp->phy_dev)
+		phy_disconnect(lp->phy_dev);
+	lp->phy_dev = NULL;
+
 	return 0;
 }
 
@@ -754,42 +1061,6 @@ static int xemaclite_send(struct sk_buff
 }
 
 /**
- * xemaclite_ioctl - Perform IO Control operations on the network device
- * @dev:	Pointer to the network device
- * @rq:		Pointer to the interface request structure
- * @cmd:	IOCTL command
- *
- * The only IOCTL operation supported by this function is setting the MAC
- * address. An error is reported if any other operations are requested.
- *
- * Return:	0 to indicate success, or a negative error for failure.
- */
-static int xemaclite_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-	struct net_local *lp = (struct net_local *) netdev_priv(dev);
-	struct hw_addr_data *hw_addr = (struct hw_addr_data *) &rq->ifr_hwaddr;
-
-	switch (cmd) {
-	case SIOCETHTOOL:
-		return -EIO;
-
-	case SIOCSIFHWADDR:
-		dev_err(&lp->ndev->dev, "SIOCSIFHWADDR\n");
-
-		/* Copy MAC address in from user space */
-		copy_from_user((void __force *) dev->dev_addr,
-			       (void __user __force *) hw_addr,
-			       IFHWADDRLEN);
-		xemaclite_set_mac_address(lp, dev->dev_addr);
-		break;
-	default:
-		return -EOPNOTSUPP;
-	}
-
-	return 0;
-}
-
-/**
  * xemaclite_remove_ndev - Free the network device
  * @ndev:	Pointer to the network device to be freed
  *
@@ -840,6 +1111,8 @@ static struct net_device_ops xemaclite_n
  * This function probes for the Emaclite device in the device tree.
  * It initializes the driver data structure and the hardware, sets the MAC
  * address and registers the network device.
+ * It also registers a mii_bus for the Emaclite device, if MDIO is included
+ * in the device.
  *
  * Return:	0, if the driver is bound to the Emaclite device, or
  *		a negative error if there is failure.
@@ -880,6 +1153,7 @@ static int __devinit xemaclite_of_probe(
 	}
 
 	dev_set_drvdata(dev, ndev);
+	SET_NETDEV_DEV(ndev, &ofdev->dev);
 
 	ndev->irq = r_irq.start;
 	ndev->mem_start = r_mem.start;
@@ -923,13 +1197,14 @@ static int __devinit xemaclite_of_probe(
 	out_be32(lp->base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET, 0);
 
 	/* Set the MAC address in the EmacLite device */
-	xemaclite_set_mac_address(lp, ndev->dev_addr);
+	xemaclite_update_address(lp, ndev->dev_addr);
 
-	dev_info(dev,
-		 "MAC address is now %2x:%2x:%2x:%2x:%2x:%2x\n",
-		 ndev->dev_addr[0], ndev->dev_addr[1],
-		 ndev->dev_addr[2], ndev->dev_addr[3],
-		 ndev->dev_addr[4], ndev->dev_addr[5]);
+	lp->phy_node = of_parse_phandle(ofdev->node, "phy-handle", 0);
+	rc = xemaclite_mdio_setup(lp, &ofdev->dev);
+	if (rc)
+		dev_warn(&ofdev->dev, "error registering MDIO bus\n");
+
+	dev_info(dev, "MAC address is now %pM\n", ndev->dev_addr);
 
 	ndev->netdev_ops = &xemaclite_netdev_ops;
 	ndev->flags &= ~IFF_MULTICAST;
@@ -972,12 +1247,25 @@ static int __devexit xemaclite_of_remove
 	struct device *dev = &of_dev->dev;
 	struct net_device *ndev = dev_get_drvdata(dev);
 
+	struct net_local *lp = (struct net_local *) netdev_priv(ndev);
+
+	/* Un-register the mii_bus, if configured */
+	if (lp->has_mdio) {
+		mdiobus_unregister(lp->mii_bus);
+		kfree(lp->mii_bus->irq);
+		mdiobus_free(lp->mii_bus);
+		lp->mii_bus = NULL;
+	}
+
 	unregister_netdev(ndev);
 
+	if (lp->phy_node)
+		of_node_put(lp->phy_node);
+	lp->phy_node = NULL;
+
 	release_mem_region(ndev->mem_start, ndev->mem_end-ndev->mem_start + 1);
 
 	xemaclite_remove_ndev(ndev);
-
 	dev_set_drvdata(dev, NULL);
 
 	return 0;
@@ -987,7 +1275,7 @@ static struct net_device_ops xemaclite_n
 	.ndo_open		= xemaclite_open,
 	.ndo_stop		= xemaclite_close,
 	.ndo_start_xmit		= xemaclite_send,
-	.ndo_do_ioctl		= xemaclite_ioctl,
+	.ndo_set_mac_address	= xemaclite_set_mac_address,
 	.ndo_tx_timeout		= xemaclite_tx_timeout,
 	.ndo_get_stats		= xemaclite_get_stats,
 };
@@ -999,6 +1287,7 @@ static struct of_device_id xemaclite_of_
 	{ .compatible = "xlnx,xps-ethernetlite-1.00.a", },
 	{ .compatible = "xlnx,xps-ethernetlite-2.00.a", },
 	{ .compatible = "xlnx,xps-ethernetlite-2.01.a", },
+	{ .compatible = "xlnx,xps-ethernetlite-3.00.a", },
 	{ /* end of list */ },
 };
 MODULE_DEVICE_TABLE(of, xemaclite_of_match);
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/xtsonic.c linux-libre-2.6.34-gnu1/drivers/net/xtsonic.c
--- linux-libre-2.6.33-gnu1/drivers/net/xtsonic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/xtsonic.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,11 +20,11 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
+#include <linux/gfp.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
@@ -33,6 +33,7 @@
 #include <linux/skbuff.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/pgtable.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/yellowfin.c linux-libre-2.6.34-gnu1/drivers/net/yellowfin.c
--- linux-libre-2.6.33-gnu1/drivers/net/yellowfin.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/yellowfin.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,12 +23,12 @@
 
 */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #define DRV_NAME	"yellowfin"
 #define DRV_VERSION	"2.1"
 #define DRV_RELDATE	"Sep 11, 2006"
 
-#define PFX DRV_NAME ": "
-
 /* The user-configurable values.
    These may be modified when a driver module is loaded.*/
 
@@ -90,7 +90,6 @@ static int gx_fix;
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -237,7 +236,7 @@ static const struct pci_id_info pci_id_t
 	{ }
 };
 
-static const struct pci_device_id yellowfin_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(yellowfin_pci_tbl) = {
 	{ 0x1000, 0x0702, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ 0x1000, 0x0701, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
 	{ }
@@ -399,7 +398,7 @@ static int __devinit yellowfin_init_one(
 
 	dev = alloc_etherdev(sizeof(*np));
 	if (!dev) {
-		printk (KERN_ERR PFX "cannot allocate ethernet device\n");
+		pr_err("cannot allocate ethernet device\n");
 		return -ENOMEM;
 	}
 	SET_NETDEV_DEV(dev, &pdev->dev);
@@ -487,10 +486,10 @@ static int __devinit yellowfin_init_one(
 	if (i)
 		goto err_out_unmap_status;
 
-	printk(KERN_INFO "%s: %s type %8x at %p, %pM, IRQ %d.\n",
-		   dev->name, pci_id_tbl[chip_idx].name,
-		   ioread32(ioaddr + ChipRev), ioaddr,
-		   dev->dev_addr, irq);
+	netdev_info(dev, "%s type %8x at %p, %pM, IRQ %d\n",
+		    pci_id_tbl[chip_idx].name,
+		    ioread32(ioaddr + ChipRev), ioaddr,
+		    dev->dev_addr, irq);
 
 	if (np->drv_flags & HasMII) {
 		int phy, phy_idx = 0;
@@ -499,9 +498,8 @@ static int __devinit yellowfin_init_one(
 			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
 				np->phys[phy_idx++] = phy;
 				np->advertising = mdio_read(ioaddr, phy, 4);
-				printk(KERN_INFO "%s: MII PHY found at address %d, status "
-					   "0x%4.4x advertising %4.4x.\n",
-					   dev->name, phy, mii_status, np->advertising);
+				netdev_info(dev, "MII PHY found at address %d, status 0x%04x advertising %04x\n",
+					    phy, mii_status, np->advertising);
 			}
 		}
 		np->mii_cnt = phy_idx;
@@ -584,8 +582,8 @@ static int yellowfin_open(struct net_dev
 		return ret;
 
 	if (yellowfin_debug > 1)
-		printk(KERN_DEBUG "%s: yellowfin_open() irq %d.\n",
-			   dev->name, dev->irq);
+		netdev_printk(KERN_DEBUG, dev, "%s() irq %d\n",
+			      __func__, dev->irq);
 
 	ret = yellowfin_init_ring(dev);
 	if (ret) {
@@ -642,8 +640,7 @@ static int yellowfin_open(struct net_dev
 	iowrite32(0x80008000, ioaddr + TxCtrl);
 
 	if (yellowfin_debug > 2) {
-		printk(KERN_DEBUG "%s: Done yellowfin_open().\n",
-			   dev->name);
+		netdev_printk(KERN_DEBUG, dev, "Done %s()\n", __func__);
 	}
 
 	/* Set the timer to check for link beat. */
@@ -664,8 +661,8 @@ static void yellowfin_timer(unsigned lon
 	int next_tick = 60*HZ;
 
 	if (yellowfin_debug > 3) {
-		printk(KERN_DEBUG "%s: Yellowfin timer tick, status %8.8x.\n",
-			   dev->name, ioread16(ioaddr + IntrStatus));
+		netdev_printk(KERN_DEBUG, dev, "Yellowfin timer tick, status %08x\n",
+			      ioread16(ioaddr + IntrStatus));
 	}
 
 	if (yp->mii_cnt) {
@@ -673,9 +670,8 @@ static void yellowfin_timer(unsigned lon
 		int lpa = mdio_read(ioaddr, yp->phys[0], MII_LPA);
 		int negotiated = lpa & yp->advertising;
 		if (yellowfin_debug > 1)
-			printk(KERN_DEBUG "%s: MII #%d status register is %4.4x, "
-				   "link partner capability %4.4x.\n",
-				   dev->name, yp->phys[0], bmsr, lpa);
+			netdev_printk(KERN_DEBUG, dev, "MII #%d status register is %04x, link partner capability %04x\n",
+				      yp->phys[0], bmsr, lpa);
 
 		yp->full_duplex = mii_duplex(yp->duplex_lock, negotiated);
 
@@ -696,25 +692,24 @@ static void yellowfin_tx_timeout(struct
 	struct yellowfin_private *yp = netdev_priv(dev);
 	void __iomem *ioaddr = yp->base;
 
-	printk(KERN_WARNING "%s: Yellowfin transmit timed out at %d/%d Tx "
-		   "status %4.4x, Rx status %4.4x, resetting...\n",
-		   dev->name, yp->cur_tx, yp->dirty_tx,
-		   ioread32(ioaddr + TxStatus), ioread32(ioaddr + RxStatus));
+	netdev_warn(dev, "Yellowfin transmit timed out at %d/%d Tx status %04x, Rx status %04x, resetting...\n",
+		    yp->cur_tx, yp->dirty_tx,
+		    ioread32(ioaddr + TxStatus),
+		    ioread32(ioaddr + RxStatus));
 
 	/* Note: these should be KERN_DEBUG. */
 	if (yellowfin_debug) {
 		int i;
-		printk(KERN_WARNING "  Rx ring %p: ", yp->rx_ring);
+		pr_warning("  Rx ring %p: ", yp->rx_ring);
 		for (i = 0; i < RX_RING_SIZE; i++)
-			printk(KERN_CONT " %8.8x",
-			       yp->rx_ring[i].result_status);
-		printk(KERN_CONT "\n");
-		printk(KERN_WARNING"  Tx ring %p: ", yp->tx_ring);
+			pr_cont(" %08x", yp->rx_ring[i].result_status);
+		pr_cont("\n");
+		pr_warning("  Tx ring %p: ", yp->tx_ring);
 		for (i = 0; i < TX_RING_SIZE; i++)
-			printk(KERN_CONT " %4.4x /%8.8x",
+			pr_cont(" %04x /%08x",
 			       yp->tx_status[i].tx_errs,
 			       yp->tx_ring[i].result_status);
-		printk(KERN_CONT "\n");
+		pr_cont("\n");
 	}
 
 	/* If the hardware is found to hang regularly, we will update the code
@@ -891,8 +886,8 @@ static netdev_tx_t yellowfin_start_xmit(
 		yp->tx_full = 1;
 
 	if (yellowfin_debug > 4) {
-		printk(KERN_DEBUG "%s: Yellowfin transmit frame #%d queued in slot %d.\n",
-			   dev->name, yp->cur_tx, entry);
+		netdev_printk(KERN_DEBUG, dev, "Yellowfin transmit frame #%d queued in slot %d\n",
+			      yp->cur_tx, entry);
 	}
 	return NETDEV_TX_OK;
 }
@@ -916,8 +911,8 @@ static irqreturn_t yellowfin_interrupt(i
 		u16 intr_status = ioread16(ioaddr + IntrClear);
 
 		if (yellowfin_debug > 4)
-			printk(KERN_DEBUG "%s: Yellowfin interrupt, status %4.4x.\n",
-				   dev->name, intr_status);
+			netdev_printk(KERN_DEBUG, dev, "Yellowfin interrupt, status %04x\n",
+				      intr_status);
 
 		if (intr_status == 0)
 			break;
@@ -963,13 +958,12 @@ static irqreturn_t yellowfin_interrupt(i
 
 #ifndef final_version
 				if (yellowfin_debug > 5)
-					printk(KERN_DEBUG "%s: Tx queue %d check, Tx status "
-						   "%4.4x %4.4x %4.4x %4.4x.\n",
-						   dev->name, entry,
-						   yp->tx_status[entry].tx_cnt,
-						   yp->tx_status[entry].tx_errs,
-						   yp->tx_status[entry].total_tx_cnt,
-						   yp->tx_status[entry].paused);
+					netdev_printk(KERN_DEBUG, dev, "Tx queue %d check, Tx status %04x %04x %04x %04x\n",
+						      entry,
+						      yp->tx_status[entry].tx_cnt,
+						      yp->tx_status[entry].tx_errs,
+						      yp->tx_status[entry].total_tx_cnt,
+						      yp->tx_status[entry].paused);
 #endif
 				if (tx_errs == 0)
 					break;	/* It still hasn't been Txed */
@@ -978,8 +972,8 @@ static irqreturn_t yellowfin_interrupt(i
 					/* There was an major error, log it. */
 #ifndef final_version
 					if (yellowfin_debug > 1)
-						printk(KERN_DEBUG "%s: Transmit error, Tx status %4.4x.\n",
-							   dev->name, tx_errs);
+						netdev_printk(KERN_DEBUG, dev, "Transmit error, Tx status %04x\n",
+							      tx_errs);
 #endif
 					dev->stats.tx_errors++;
 					if (tx_errs & 0xF800) dev->stats.tx_aborted_errors++;
@@ -989,8 +983,8 @@ static irqreturn_t yellowfin_interrupt(i
 				} else {
 #ifndef final_version
 					if (yellowfin_debug > 4)
-						printk(KERN_DEBUG "%s: Normal transmit, Tx status %4.4x.\n",
-							   dev->name, tx_errs);
+						netdev_printk(KERN_DEBUG, dev, "Normal transmit, Tx status %04x\n",
+							      tx_errs);
 #endif
 					dev->stats.tx_bytes += skb->len;
 					dev->stats.collisions += tx_errs & 15;
@@ -1008,8 +1002,8 @@ static irqreturn_t yellowfin_interrupt(i
 
 #ifndef final_version
 			if (yp->cur_tx - dirty_tx > TX_RING_SIZE) {
-				printk(KERN_ERR "%s: Out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
-					   dev->name, dirty_tx, yp->cur_tx, yp->tx_full);
+				netdev_err(dev, "Out-of-sync dirty pointer, %d vs. %d, full=%d\n",
+					   dirty_tx, yp->cur_tx, yp->tx_full);
 				dirty_tx += TX_RING_SIZE;
 			}
 #endif
@@ -1031,16 +1025,15 @@ static irqreturn_t yellowfin_interrupt(i
 			yellowfin_error(dev, intr_status);
 
 		if (--boguscnt < 0) {
-			printk(KERN_WARNING "%s: Too much work at interrupt, "
-				   "status=0x%4.4x.\n",
-				   dev->name, intr_status);
+			netdev_warn(dev, "Too much work at interrupt, status=%#04x\n",
+				    intr_status);
 			break;
 		}
 	} while (1);
 
 	if (yellowfin_debug > 3)
-		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
-			   dev->name, ioread16(ioaddr + IntrStatus));
+		netdev_printk(KERN_DEBUG, dev, "exiting interrupt, status=%#04x\n",
+			      ioread16(ioaddr + IntrStatus));
 
 	spin_unlock (&yp->lock);
 	return IRQ_RETVAL(handled);
@@ -1055,9 +1048,9 @@ static int yellowfin_rx(struct net_devic
 	int boguscnt = yp->dirty_rx + RX_RING_SIZE - yp->cur_rx;
 
 	if (yellowfin_debug > 4) {
-		printk(KERN_DEBUG " In yellowfin_rx(), entry %d status %8.8x.\n",
+		printk(KERN_DEBUG " In yellowfin_rx(), entry %d status %08x\n",
 			   entry, yp->rx_ring[entry].result_status);
-		printk(KERN_DEBUG "   #%d desc. %8.8x %8.8x %8.8x.\n",
+		printk(KERN_DEBUG "   #%d desc. %08x %08x %08x\n",
 			   entry, yp->rx_ring[entry].dbdma_cmd, yp->rx_ring[entry].addr,
 			   yp->rx_ring[entry].result_status);
 	}
@@ -1081,20 +1074,20 @@ static int yellowfin_rx(struct net_devic
 			le32_to_cpu(desc->result_status)) & 0xffff;
 		frame_status = get_unaligned_le16(&(buf_addr[data_size - 2]));
 		if (yellowfin_debug > 4)
-			printk(KERN_DEBUG "  yellowfin_rx() status was %4.4x.\n",
-				   frame_status);
+			printk(KERN_DEBUG "  %s() status was %04x\n",
+			       __func__, frame_status);
 		if (--boguscnt < 0)
 			break;
 		if ( ! (desc_status & RX_EOP)) {
 			if (data_size != 0)
-				printk(KERN_WARNING "%s: Oversized Ethernet frame spanned multiple buffers,"
-					   " status %4.4x, data_size %d!\n", dev->name, desc_status, data_size);
+				netdev_warn(dev, "Oversized Ethernet frame spanned multiple buffers, status %04x, data_size %d!\n",
+					    desc_status, data_size);
 			dev->stats.rx_length_errors++;
 		} else if ((yp->drv_flags & IsGigabit)  &&  (frame_status & 0x0038)) {
 			/* There was a error. */
 			if (yellowfin_debug > 3)
-				printk(KERN_DEBUG "  yellowfin_rx() Rx error was %4.4x.\n",
-					   frame_status);
+				printk(KERN_DEBUG "  %s() Rx error was %04x\n",
+				       __func__, frame_status);
 			dev->stats.rx_errors++;
 			if (frame_status & 0x0060) dev->stats.rx_length_errors++;
 			if (frame_status & 0x0008) dev->stats.rx_frame_errors++;
@@ -1118,8 +1111,8 @@ static int yellowfin_rx(struct net_devic
 				entry*sizeof(struct yellowfin_desc)),
 				"\377\377\377\377\377\377", 6) != 0) {
 			if (bogus_rx++ == 0)
-				printk(KERN_WARNING "%s: Bad frame to %pM\n",
-					   dev->name, buf_addr);
+				netdev_warn(dev, "Bad frame to %pM\n",
+					    buf_addr);
 #endif
 		} else {
 			struct sk_buff *skb;
@@ -1129,9 +1122,8 @@ static int yellowfin_rx(struct net_devic
 
 #ifndef final_version
 			if (yellowfin_debug > 4)
-				printk(KERN_DEBUG "  yellowfin_rx() normal Rx pkt length %d"
-					   " of %d, bogus_cnt %d.\n",
-					   pkt_len, data_size, boguscnt);
+				printk(KERN_DEBUG "  %s() normal Rx pkt length %d of %d, bogus_cnt %d\n",
+				       __func__, pkt_len, data_size, boguscnt);
 #endif
 			/* Check if the packet is long enough to just pass up the skbuff
 			   without copying to a properly sized skbuff. */
@@ -1191,8 +1183,7 @@ static int yellowfin_rx(struct net_devic
 
 static void yellowfin_error(struct net_device *dev, int intr_status)
 {
-	printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
-		   dev->name, intr_status);
+	netdev_err(dev, "Something Wicked happened! %04x\n", intr_status);
 	/* Hmmmmm, it's not clear what to do here. */
 	if (intr_status & (IntrTxPCIErr | IntrTxPCIFault))
 		dev->stats.tx_errors++;
@@ -1209,13 +1200,13 @@ static int yellowfin_close(struct net_de
 	netif_stop_queue (dev);
 
 	if (yellowfin_debug > 1) {
-		printk(KERN_DEBUG "%s: Shutting down ethercard, status was Tx %4.4x "
-			   "Rx %4.4x Int %2.2x.\n",
-			   dev->name, ioread16(ioaddr + TxStatus),
-			   ioread16(ioaddr + RxStatus),
-			   ioread16(ioaddr + IntrStatus));
-		printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d,  Rx %d / %d.\n",
-			   dev->name, yp->cur_tx, yp->dirty_tx, yp->cur_rx, yp->dirty_rx);
+		netdev_printk(KERN_DEBUG, dev, "Shutting down ethercard, status was Tx %04x Rx %04x Int %02x\n",
+			      ioread16(ioaddr + TxStatus),
+			      ioread16(ioaddr + RxStatus),
+			      ioread16(ioaddr + IntrStatus));
+		netdev_printk(KERN_DEBUG, dev, "Queue pointers were Tx %d / %d,  Rx %d / %d\n",
+			      yp->cur_tx, yp->dirty_tx,
+			      yp->cur_rx, yp->dirty_rx);
 	}
 
 	/* Disable interrupts by clearing the interrupt mask. */
@@ -1229,33 +1220,35 @@ static int yellowfin_close(struct net_de
 
 #if defined(__i386__)
 	if (yellowfin_debug > 2) {
-		printk(KERN_DEBUG"  Tx ring at %8.8llx:\n",
+		printk(KERN_DEBUG "  Tx ring at %08llx:\n",
 				(unsigned long long)yp->tx_ring_dma);
 		for (i = 0; i < TX_RING_SIZE*2; i++)
-			printk(KERN_DEBUG " %c #%d desc. %8.8x %8.8x %8.8x %8.8x.\n",
+			printk(KERN_DEBUG " %c #%d desc. %08x %08x %08x %08x\n",
 				   ioread32(ioaddr + TxPtr) == (long)&yp->tx_ring[i] ? '>' : ' ',
 				   i, yp->tx_ring[i].dbdma_cmd, yp->tx_ring[i].addr,
 				   yp->tx_ring[i].branch_addr, yp->tx_ring[i].result_status);
 		printk(KERN_DEBUG "  Tx status %p:\n", yp->tx_status);
 		for (i = 0; i < TX_RING_SIZE; i++)
-			printk(KERN_DEBUG "   #%d status %4.4x %4.4x %4.4x %4.4x.\n",
+			printk(KERN_DEBUG "   #%d status %04x %04x %04x %04x\n",
 				   i, yp->tx_status[i].tx_cnt, yp->tx_status[i].tx_errs,
 				   yp->tx_status[i].total_tx_cnt, yp->tx_status[i].paused);
 
-		printk(KERN_DEBUG "  Rx ring %8.8llx:\n",
+		printk(KERN_DEBUG "  Rx ring %08llx:\n",
 				(unsigned long long)yp->rx_ring_dma);
 		for (i = 0; i < RX_RING_SIZE; i++) {
-			printk(KERN_DEBUG " %c #%d desc. %8.8x %8.8x %8.8x\n",
+			printk(KERN_DEBUG " %c #%d desc. %08x %08x %08x\n",
 				   ioread32(ioaddr + RxPtr) == (long)&yp->rx_ring[i] ? '>' : ' ',
 				   i, yp->rx_ring[i].dbdma_cmd, yp->rx_ring[i].addr,
 				   yp->rx_ring[i].result_status);
 			if (yellowfin_debug > 6) {
 				if (get_unaligned((u8*)yp->rx_ring[i].addr) != 0x69) {
 					int j;
+
+					printk(KERN_DEBUG);
 					for (j = 0; j < 0x50; j++)
-						printk(" %4.4x",
-							   get_unaligned(((u16*)yp->rx_ring[i].addr) + j));
-					printk("\n");
+						pr_cont(" %04x",
+							get_unaligned(((u16*)yp->rx_ring[i].addr) + j));
+					pr_cont("\n");
 				}
 			}
 		}
@@ -1281,8 +1274,8 @@ static int yellowfin_close(struct net_de
 
 #ifdef YF_PROTOTYPE			/* Support for prototype hardware errata. */
 	if (yellowfin_debug > 0) {
-		printk(KERN_DEBUG "%s: Received %d frames that we should not have.\n",
-			   dev->name, bogus_rx);
+		netdev_printk(KERN_DEBUG, dev, "Received %d frames that we should not have\n",
+			      bogus_rx);
 	}
 #endif
 
@@ -1301,16 +1294,17 @@ static void set_rx_mode(struct net_devic
 	iowrite16(cfg_value & ~0x1000, ioaddr + Cnfg);
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		iowrite16(0x000F, ioaddr + AddrMode);
-	} else if ((dev->mc_count > 64)  ||  (dev->flags & IFF_ALLMULTI)) {
+	} else if ((netdev_mc_count(dev) > 64) ||
+		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter well, or accept all multicasts. */
 		iowrite16(0x000B, ioaddr + AddrMode);
-	} else if (dev->mc_count > 0) { /* Must use the multicast hash table. */
+	} else if (!netdev_mc_empty(dev)) { /* Must use the multicast hash table. */
 		struct dev_mc_list *mclist;
 		u16 hash_table[4];
 		int i;
+
 		memset(hash_table, 0, sizeof(hash_table));
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-			 i++, mclist = mclist->next) {
+		netdev_for_each_mc_addr(mclist, dev) {
 			unsigned int bit;
 
 			/* Due to a bug in the early chip versions, multiple filter
diff -druNp linux-libre-2.6.33-gnu1/drivers/net/znet.c linux-libre-2.6.34-gnu1/drivers/net/znet.c
--- linux-libre-2.6.33-gnu1/drivers/net/znet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/net/znet.c	2010-05-16 17:17:36.000000000 -0400
@@ -88,6 +88,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
@@ -313,7 +314,8 @@ static void znet_set_multicast_list (str
 	/* Byte D */
 	cfblk->dummy_1 = 1; 	/* set to 1 */
 	cfblk->tx_ifs_retrig = 3; /* Hmm... Disabled */
-	cfblk->mc_all = (dev->mc_list || (dev->flags&IFF_ALLMULTI));/* multicast all mode */
+	cfblk->mc_all = (!netdev_mc_empty(dev) ||
+			(dev->flags & IFF_ALLMULTI)); /* multicast all mode */
 	cfblk->rcv_mon = 0;	/* Monitor mode disabled */
 	cfblk->frag_acpt = 0;	/* Do not accept fragments */
 	cfblk->tstrttrs = 0;	/* No start transmission threshold */
diff -druNp linux-libre-2.6.33-gnu1/drivers/nubus/nubus.c linux-libre-2.6.34-gnu1/drivers/nubus/nubus.c
--- linux-libre-2.6.33-gnu1/drivers/nubus/nubus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/nubus/nubus.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/setup.h>
 #include <asm/system.h>
 #include <asm/page.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/of/base.c linux-libre-2.6.34-gnu1/drivers/of/base.c
--- linux-libre-2.6.33-gnu1/drivers/of/base.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/of/base.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,8 +20,11 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
 
 struct device_node *allnodes;
+struct device_node *of_chosen;
 
 /* use when traversing tree through the allnext, child, sibling,
  * or parent members of struct device_node.
@@ -37,7 +40,7 @@ int of_n_addr_cells(struct device_node *
 			np = np->parent;
 		ip = of_get_property(np, "#address-cells", NULL);
 		if (ip)
-			return *ip;
+			return be32_to_cpup(ip);
 	} while (np->parent);
 	/* No #address-cells property for the root node */
 	return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
@@ -53,13 +56,88 @@ int of_n_size_cells(struct device_node *
 			np = np->parent;
 		ip = of_get_property(np, "#size-cells", NULL);
 		if (ip)
-			return *ip;
+			return be32_to_cpup(ip);
 	} while (np->parent);
 	/* No #size-cells property for the root node */
 	return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
 }
 EXPORT_SYMBOL(of_n_size_cells);
 
+#if !defined(CONFIG_SPARC)   /* SPARC doesn't do ref counting (yet) */
+/**
+ *	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)) {
+		pr_err("ERROR: 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);
+#endif /* !CONFIG_SPARC */
+
 struct property *of_find_property(const struct device_node *np,
 				  const char *name,
 				  int *lenp)
@@ -144,6 +222,27 @@ int of_device_is_compatible(const struct
 EXPORT_SYMBOL(of_device_is_compatible);
 
 /**
+ * of_machine_is_compatible - Test root of device tree for a given compatible value
+ * @compat: compatible string to look for in root node's compatible property.
+ *
+ * Returns true if the root node has the given value in its
+ * compatible property.
+ */
+int of_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(of_machine_is_compatible);
+
+/**
  *  of_device_is_available - check if a device is available for use
  *
  *  @device: Node to check for availability
@@ -519,6 +618,27 @@ int of_modalias_node(struct device_node
 EXPORT_SYMBOL_GPL(of_modalias_node);
 
 /**
+ * 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; np = np->allnext)
+		if (np->phandle == handle)
+			break;
+	of_node_get(np);
+	read_unlock(&devtree_lock);
+	return np;
+}
+EXPORT_SYMBOL(of_find_node_by_phandle);
+
+/**
  * of_parse_phandle - Resolve a phandle property to a device_node pointer
  * @np: Pointer to device node holding phandle property
  * @phandle_name: Name of property holding a phandle value
@@ -578,8 +698,8 @@ int of_parse_phandles_with_args(struct d
 				const void **out_args)
 {
 	int ret = -EINVAL;
-	const u32 *list;
-	const u32 *list_end;
+	const __be32 *list;
+	const __be32 *list_end;
 	int size;
 	int cur_index = 0;
 	struct device_node *node = NULL;
@@ -593,7 +713,7 @@ int of_parse_phandles_with_args(struct d
 	list_end = list + size / sizeof(*list);
 
 	while (list < list_end) {
-		const u32 *cells;
+		const __be32 *cells;
 		const phandle *phandle;
 
 		phandle = list++;
@@ -617,7 +737,7 @@ int of_parse_phandles_with_args(struct d
 			goto err1;
 		}
 
-		list += *cells;
+		list += be32_to_cpup(cells);
 		if (list > list_end) {
 			pr_debug("%s: insufficient arguments length\n",
 				 np->full_name);
@@ -658,3 +778,190 @@ err0:
 	return ret;
 }
 EXPORT_SYMBOL(of_parse_phandles_with_args);
+
+/**
+ * prom_add_property - 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;
+}
+
+/**
+ * prom_remove_property - 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;
+}
+
+/*
+ * prom_update_property - 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_OF_DYNAMIC)
+/*
+ * Support for dynamic device trees.
+ *
+ * On some platforms, the device tree can be manipulated at runtime.
+ * The routines in this section support adding, removing and changing
+ * device tree nodes.
+ */
+
+/**
+ * of_attach_node - 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);
+}
+
+/**
+ * of_detach_node - "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);
+}
+#endif /* defined(CONFIG_OF_DYNAMIC) */
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/of/fdt.c linux-libre-2.6.34-gnu1/drivers/of/fdt.c
--- linux-libre-2.6.33-gnu1/drivers/of/fdt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/of/fdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,593 @@
+/*
+ * Functions for working with the Flattened Device Tree data format
+ *
+ * Copyright 2009 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
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/initrd.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+
+#ifdef CONFIG_PPC
+#include <asm/machdep.h>
+#endif /* CONFIG_PPC */
+
+#include <asm/page.h>
+
+int __initdata dt_root_addr_cells;
+int __initdata dt_root_size_cells;
+
+struct boot_param_header *initial_boot_params;
+
+char *find_flat_dt_string(u32 offset)
+{
+	return ((char *)initial_boot_params) +
+		be32_to_cpu(initial_boot_params->off_dt_strings) + offset;
+}
+
+/**
+ * of_scan_flat_dt - scan flattened tree blob and call callback on each.
+ * @it: callback function
+ * @data: context data pointer
+ *
+ * This function is used to scan the flattened device-tree, it is
+ * used to extract the memory information 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) +
+		be32_to_cpu(initial_boot_params->off_dt_struct);
+	int rc = 0;
+	int depth = -1;
+
+	do {
+		u32 tag = be32_to_cpup((__be32 *)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 = be32_to_cpup((__be32 *)p);
+			p += 8;
+			if (be32_to_cpu(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) {
+			pr_err("Invalid tag %x in flat 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;
+}
+
+/**
+ * of_get_flat_dt_root - find the root node in the flat blob
+ */
+unsigned long __init of_get_flat_dt_root(void)
+{
+	unsigned long p = ((unsigned long)initial_boot_params) +
+		be32_to_cpu(initial_boot_params->off_dt_struct);
+
+	while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
+		p += 4;
+	BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
+	p += 4;
+	return _ALIGN(p + strlen((char *)p) + 1, 4);
+}
+
+/**
+ * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
+ *
+ * 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 = be32_to_cpup((__be32 *)p);
+		u32 sz, noff;
+		const char *nstr;
+
+		p += 4;
+		if (tag == OF_DT_NOP)
+			continue;
+		if (tag != OF_DT_PROP)
+			return NULL;
+
+		sz = be32_to_cpup((__be32 *)p);
+		noff = be32_to_cpup((__be32 *)(p + 4));
+		p += 8;
+		if (be32_to_cpu(initial_boot_params->version) < 0x10)
+			p = _ALIGN(p, sz >= 8 ? 8 : 4);
+
+		nstr = find_flat_dt_string(noff);
+		if (nstr == NULL) {
+			pr_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);
+}
+
+/**
+ * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
+ * @node: node to test
+ * @compat: compatible string to compare with compatible list.
+ */
+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;
+}
+
+/**
+ * unflatten_dt_node - Alloc and populate a device_node from the flat tree
+ * @p: pointer to node in flat tree
+ * @dad: Parent struct device_node
+ * @allnextpp: pointer to ->allnext from last allocated device_node
+ * @fpsize: Size of the node path up at the current depth.
+ */
+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 = be32_to_cpup((__be32 *)(*p));
+	if (tag != OF_DT_BEGIN_NODE) {
+		pr_err("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 *fn = np->full_name;
+			/* rebuild full path for new format */
+			if (dad && dad->parent) {
+				strcpy(fn, dad->full_name);
+#ifdef DEBUG
+				if ((strlen(fn) + l + 1) != allocl) {
+					pr_debug("%s: p: %d, l: %d, a: %d\n",
+						pathp, (int)strlen(fn),
+						l, allocl);
+				}
+#endif
+				fn += strlen(fn);
+			}
+			*(fn++) = '/';
+			memcpy(fn, 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 = be32_to_cpup((__be32 *)(*p));
+		if (tag == OF_DT_NOP) {
+			*p += 4;
+			continue;
+		}
+		if (tag != OF_DT_PROP)
+			break;
+		*p += 4;
+		sz = be32_to_cpup((__be32 *)(*p));
+		noff = be32_to_cpup((__be32 *)((*p) + 4));
+		*p += 8;
+		if (be32_to_cpu(initial_boot_params->version) < 0x10)
+			*p = _ALIGN(*p, sz >= 8 ? 8 : 4);
+
+		pname = find_flat_dt_string(noff);
+		if (pname == NULL) {
+			pr_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) {
+			/* We accept flattened tree phandles either in
+			 * ePAPR-style "phandle" properties, or the
+			 * legacy "linux,phandle" properties.  If both
+			 * appear and have different values, things
+			 * will get weird.  Don't do that. */
+			if ((strcmp(pname, "phandle") == 0) ||
+			    (strcmp(pname, "linux,phandle") == 0)) {
+				if (np->phandle == 0)
+					np->phandle = *((u32 *)*p);
+			}
+			/* And we process the "ibm,phandle" property
+			 * used in pSeries dynamic device tree
+			 * stuff */
+			if (strcmp(pname, "ibm,phandle") == 0)
+				np->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 || tag == OF_DT_NOP) {
+		if (tag == OF_DT_NOP)
+			*p += 4;
+		else
+			mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
+		tag = be32_to_cpup((__be32 *)(*p));
+	}
+	if (tag != OF_DT_END_NODE) {
+		pr_err("Weird tag at end of node: %x\n", tag);
+		return mem;
+	}
+	*p += 4;
+	return mem;
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+/**
+ * early_init_dt_check_for_initrd - Decode initrd location from flat tree
+ * @node: reference to node containing initrd location ('chosen')
+ */
+void __init early_init_dt_check_for_initrd(unsigned long node)
+{
+	unsigned long start, end, len;
+	__be32 *prop;
+
+	pr_debug("Looking for initrd properties... ");
+
+	prop = of_get_flat_dt_prop(node, "linux,initrd-start", &len);
+	if (!prop)
+		return;
+	start = of_read_ulong(prop, len/4);
+
+	prop = of_get_flat_dt_prop(node, "linux,initrd-end", &len);
+	if (!prop)
+		return;
+	end = of_read_ulong(prop, len/4);
+
+	early_init_dt_setup_initrd_arch(start, end);
+	pr_debug("initrd_start=0x%lx  initrd_end=0x%lx\n", start, end);
+}
+#else
+inline void early_init_dt_check_for_initrd(unsigned long node)
+{
+}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+/**
+ * early_init_dt_scan_root - fetch the top level address and size cells
+ */
+int __init early_init_dt_scan_root(unsigned long node, const char *uname,
+				   int depth, void *data)
+{
+	__be32 *prop;
+
+	if (depth != 0)
+		return 0;
+
+	dt_root_size_cells = OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
+	dt_root_addr_cells = OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
+
+	prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
+	if (prop)
+		dt_root_size_cells = be32_to_cpup(prop);
+	pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
+
+	prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
+	if (prop)
+		dt_root_addr_cells = be32_to_cpup(prop);
+	pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
+
+	/* break now */
+	return 1;
+}
+
+u64 __init dt_mem_next_cell(int s, __be32 **cellp)
+{
+	__be32 *p = *cellp;
+
+	*cellp = p + s;
+	return of_read_number(p, s);
+}
+
+/**
+ * early_init_dt_scan_memory - Look for an parse memory nodes
+ */
+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);
+	__be32 *reg, *endp;
+	unsigned long l;
+
+	/* 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 = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
+	if (reg == NULL)
+		reg = of_get_flat_dt_prop(node, "reg", &l);
+	if (reg == NULL)
+		return 0;
+
+	endp = reg + (l / sizeof(__be32));
+
+	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);
+
+		early_init_dt_add_memory_arch(base, size);
+	}
+
+	return 0;
+}
+
+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;
+
+	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
+#ifndef CONFIG_CMDLINE_FORCE
+	if (p == NULL || l == 0 || (l == 1 && (*p) == 0))
+#endif
+		strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+#endif /* CONFIG_CMDLINE */
+
+	early_init_dt_scan_chosen_arch(node);
+
+	pr_debug("Command line is: %s\n", cmd_line);
+
+	/* break now */
+	return 1;
+}
+
+/**
+ * unflatten_device_tree - create tree of device_nodes from flat blob
+ *
+ * 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.
+ */
+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) +
+		be32_to_cpu(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 = early_init_dt_alloc_memory_arch(size + 4,
+			__alignof__(struct device_node));
+	mem = (unsigned long) __va(mem);
+
+	((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
+
+	pr_debug("  unflattening %lx...\n", mem);
+
+	/* Second pass, do actual unflattening */
+	start = ((unsigned long)initial_boot_params) +
+		be32_to_cpu(initial_boot_params->off_dt_struct);
+	unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
+	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
+		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
+	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
+		pr_warning("End of tree marker overwritten: %08x\n",
+			   be32_to_cpu(((__be32 *)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");
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/of/gpio.c linux-libre-2.6.34-gnu1/drivers/of/gpio.c
--- linux-libre-2.6.33-gnu1/drivers/of/gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/of/gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/errno.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/slab.h>
 #include <linux/of_gpio.h>
 #include <asm/prom.h>
 
@@ -36,7 +37,7 @@ int of_get_gpio_flags(struct device_node
 	struct of_gpio_chip *of_gc = NULL;
 	int size;
 	const void *gpio_spec;
-	const u32 *gpio_cells;
+	const __be32 *gpio_cells;
 
 	ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index,
 					  &gc, &gpio_spec);
@@ -55,7 +56,7 @@ int of_get_gpio_flags(struct device_node
 
 	gpio_cells = of_get_property(gc, "#gpio-cells", &size);
 	if (!gpio_cells || size != sizeof(*gpio_cells) ||
-			*gpio_cells != of_gc->gpio_cells) {
+			be32_to_cpup(gpio_cells) != of_gc->gpio_cells) {
 		pr_debug("%s: wrong #gpio-cells for %s\n",
 			 np->full_name, gc->full_name);
 		ret = -EINVAL;
@@ -127,7 +128,8 @@ EXPORT_SYMBOL(of_gpio_count);
 int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np,
 			 const void *gpio_spec, enum of_gpio_flags *flags)
 {
-	const u32 *gpio = gpio_spec;
+	const __be32 *gpio = gpio_spec;
+	const u32 n = be32_to_cpup(gpio);
 
 	/*
 	 * We're discouraging gpio_cells < 2, since that way you'll have to
@@ -140,13 +142,13 @@ int of_gpio_simple_xlate(struct of_gpio_
 		return -EINVAL;
 	}
 
-	if (*gpio > of_gc->gc.ngpio)
+	if (n > of_gc->gc.ngpio)
 		return -EINVAL;
 
 	if (flags)
-		*flags = gpio[1];
+		*flags = be32_to_cpu(gpio[1]);
 
-	return *gpio;
+	return n;
 }
 EXPORT_SYMBOL(of_gpio_simple_xlate);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/of/Kconfig linux-libre-2.6.34-gnu1/drivers/of/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/of/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/of/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,3 +1,11 @@
+config OF_FLATTREE
+	bool
+	depends on OF
+
+config OF_DYNAMIC
+	def_bool y
+	depends on OF && PPC_OF
+
 config OF_DEVICE
 	def_bool y
 	depends on OF && (SPARC || PPC_OF || MICROBLAZE)
diff -druNp linux-libre-2.6.33-gnu1/drivers/of/Makefile linux-libre-2.6.34-gnu1/drivers/of/Makefile
--- linux-libre-2.6.33-gnu1/drivers/of/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/of/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,5 @@
 obj-y = base.o
+obj-$(CONFIG_OF_FLATTREE) += fdt.o
 obj-$(CONFIG_OF_DEVICE) += device.o platform.o
 obj-$(CONFIG_OF_GPIO)   += gpio.o
 obj-$(CONFIG_OF_I2C)	+= of_i2c.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/of/of_i2c.c linux-libre-2.6.34-gnu1/drivers/of/of_i2c.c
--- linux-libre-2.6.33-gnu1/drivers/of/of_i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/of/of_i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,7 @@ void of_register_i2c_devices(struct i2c_
 	for_each_child_of_node(adap_node, node) {
 		struct i2c_board_info info = {};
 		struct dev_archdata dev_ad = {};
-		const u32 *addr;
+		const __be32 *addr;
 		int len;
 
 		if (of_modalias_node(node, info.type, sizeof(info.type)) < 0)
@@ -40,7 +40,7 @@ void of_register_i2c_devices(struct i2c_
 
 		info.irq = irq_of_parse_and_map(node, 0);
 
-		info.addr = *addr;
+		info.addr = be32_to_cpup(addr);
 
 		dev_archdata_set_node(&dev_ad, node);
 		info.archdata = &dev_ad;
diff -druNp linux-libre-2.6.33-gnu1/drivers/of/of_mdio.c linux-libre-2.6.34-gnu1/drivers/of/of_mdio.c
--- linux-libre-2.6.33-gnu1/drivers/of/of_mdio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/of/of_mdio.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,7 +51,7 @@ int of_mdiobus_register(struct mii_bus *
 
 	/* Loop over the child nodes and register a phy_device for each one */
 	for_each_child_of_node(np, child) {
-		const u32 *addr;
+		const __be32 *addr;
 		int len;
 
 		/* A PHY must have a reg property in the range [0-31] */
@@ -68,8 +68,8 @@ int of_mdiobus_register(struct mii_bus *
 				mdio->irq[*addr] = PHY_POLL;
 		}
 
-		phy = get_phy_device(mdio, *addr);
-		if (!phy) {
+		phy = get_phy_device(mdio, be32_to_cpup(addr));
+		if (!phy || IS_ERR(phy)) {
 			dev_err(&mdio->dev, "error probing PHY at address %i\n",
 				*addr);
 			continue;
@@ -160,7 +160,7 @@ struct phy_device *of_phy_connect_fixed_
 	struct device_node *net_np;
 	char bus_id[MII_BUS_ID_SIZE + 3];
 	struct phy_device *phy;
-	const u32 *phy_id;
+	const __be32 *phy_id;
 	int sz;
 
 	if (!dev->dev.parent)
@@ -174,7 +174,7 @@ struct phy_device *of_phy_connect_fixed_
 	if (!phy_id || sz < sizeof(*phy_id))
 		return NULL;
 
-	sprintf(bus_id, PHY_ID_FMT, "0", phy_id[0]);
+	sprintf(bus_id, PHY_ID_FMT, "0", be32_to_cpu(phy_id[0]));
 
 	phy = phy_connect(dev, bus_id, hndlr, 0, iface);
 	return IS_ERR(phy) ? NULL : phy;
diff -druNp linux-libre-2.6.33-gnu1/drivers/of/of_spi.c linux-libre-2.6.34-gnu1/drivers/of/of_spi.c
--- linux-libre-2.6.33-gnu1/drivers/of/of_spi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/of/of_spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,7 @@ void of_register_spi_devices(struct spi_
 {
 	struct spi_device *spi;
 	struct device_node *nc;
-	const u32 *prop;
+	const __be32 *prop;
 	int rc;
 	int len;
 
@@ -54,7 +54,7 @@ void of_register_spi_devices(struct spi_
 			spi_dev_put(spi);
 			continue;
 		}
-		spi->chip_select = *prop;
+		spi->chip_select = be32_to_cpup(prop);
 
 		/* Mode (clock phase/polarity/etc.) */
 		if (of_find_property(nc, "spi-cpha", NULL))
@@ -72,7 +72,7 @@ void of_register_spi_devices(struct spi_
 			spi_dev_put(spi);
 			continue;
 		}
-		spi->max_speed_hz = *prop;
+		spi->max_speed_hz = be32_to_cpup(prop);
 
 		/* IRQ */
 		spi->irq = irq_of_parse_and_map(nc, 0);
diff -druNp linux-libre-2.6.33-gnu1/drivers/oprofile/buffer_sync.c linux-libre-2.6.34-gnu1/drivers/oprofile/buffer_sync.c
--- linux-libre-2.6.33-gnu1/drivers/oprofile/buffer_sync.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/oprofile/buffer_sync.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/fs.h>
 #include <linux/oprofile.h>
 #include <linux/sched.h>
+#include <linux/gfp.h>
 
 #include "oprofile_stats.h"
 #include "event_buffer.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/parisc/asp.c linux-libre-2.6.34-gnu1/drivers/parisc/asp.c
--- linux-libre-2.6.33-gnu1/drivers/parisc/asp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/parisc/asp.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/types.h>
 #include <asm/io.h>
 #include <asm/led.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/parisc/ccio-rm-dma.c linux-libre-2.6.34-gnu1/drivers/parisc/ccio-rm-dma.c
--- linux-libre-2.6.33-gnu1/drivers/parisc/ccio-rm-dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/parisc/ccio-rm-dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 
 #include <asm/uaccess.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/parisc/eisa_enumerator.c linux-libre-2.6.34-gnu1/drivers/parisc/eisa_enumerator.c
--- linux-libre-2.6.33-gnu1/drivers/parisc/eisa_enumerator.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/parisc/eisa_enumerator.c	2010-05-16 17:17:36.000000000 -0400
@@ -460,7 +460,7 @@ static int init_slot(int slot, struct ee
 			       slot, id_string);
 			
 			print_eisa_id(id_string, es->eisa_slot_id);
-			printk(" expected %s \n", id_string);
+			printk(" expected %s\n", id_string);
 		
 			return -1;	
 			
diff -druNp linux-libre-2.6.33-gnu1/drivers/parisc/gsc.c linux-libre-2.6.34-gnu1/drivers/parisc/gsc.c
--- linux-libre-2.6.33-gnu1/drivers/parisc/gsc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/parisc/gsc.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/types.h>
 
 #include <asm/hardware.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/parisc/pdc_stable.c linux-libre-2.6.34-gnu1/drivers/parisc/pdc_stable.c
--- linux-libre-2.6.33-gnu1/drivers/parisc/pdc_stable.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/parisc/pdc_stable.c	2010-05-16 17:17:36.000000000 -0400
@@ -481,7 +481,7 @@ pdcspath_attr_store(struct kobject *kobj
 	return ret;
 }
 
-static struct sysfs_ops pdcspath_attr_ops = {
+static const struct sysfs_ops pdcspath_attr_ops = {
 	.show = pdcspath_attr_show,
 	.store = pdcspath_attr_store,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/parisc/superio.c linux-libre-2.6.34-gnu1/drivers/parisc/superio.c
--- linux-libre-2.6.33-gnu1/drivers/parisc/superio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/parisc/superio.c	2010-05-16 17:17:36.000000000 -0400
@@ -169,7 +169,7 @@ superio_init(struct pci_dev *pcidev)
 	/* ...then properly fixup the USB to point at suckyio PIC */
 	sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev);
 
-	printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i) \n",
+	printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i)\n",
 	       pci_name(pdev), pdev->irq);
 
 	pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base);
diff -druNp linux-libre-2.6.33-gnu1/drivers/parport/ChangeLog linux-libre-2.6.34-gnu1/drivers/parport/ChangeLog
--- linux-libre-2.6.33-gnu1/drivers/parport/ChangeLog	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/parport/ChangeLog	1969-12-31 19:00:00.000000000 -0500
@@ -1,583 +0,0 @@
-2001-10-11  Tim Waugh  <twaugh@redhat.com>
-	* parport_pc.c, parport_serial.c: Support for NetMos cards.
-	+ Patch originally from Michael Reinelt <reinelt@eunet.at>.
-
-2002-04-25  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_serial.c, parport_pc.c: Move some SIIG cards around.
-	Patch from Andrey Panin.
-
-2002-01-20  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_pc_compat_write_block_pio,
-	parport_pc_ecp_write_block_pio, parport_pc_ecp_read_block_pio):
-	Use the default implementations if the caller wants to use
-	O_NONBLOCK.
-
-2002-02-25  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c: Make sure that priv->ctr_writable includes IntEn
-	even if IRQ is given as a parameter.
-
-2002-01-21  Tim Waugh  <twaugh@redhat.com>
-
-	* daisy.c: Apply patch from Max Vorobiev to make parport_daisy_select
-	work for ECP/EPP modes.
-
-2002-01-13  Niels Kristian Bech Jensen  <nkbj@image.dk>
-
-	* parport_pc.c: Change some occurrences of frob_set_mode to
-	ECR_WRITE.  This fixes PLIP.
-
-2002-01-04  Tim Waugh  <twaugh@redhat.com>
-
-	* share.c (parport_claim_or_block): Sleep interruptibly to prevent
-	a possible deadlock.
-
-2001-12-07  Damian Gruszka  <damian.gruszka@VisionSystems.de>
-
-	* parport_pc.c (ECR_WRITE): Define.  If there are forbidden bits
-	in the ECR register for some chips, this will be a useful place to
-	put that knowledge.
-	(change_mode): Use ECR_WRITE.
-	(parport_pc_restore_state): Likewise.
-	(parport_ECPPS2_supported): Likewise.
-	(parport_ECPEPP_supported): Likewise.
-	(irq_probe_EPP): Likewise.
-	(programmable_irq_support): Likewise.
-	(programmable_dma_support): Likewise.
-	(parport_pc_probe_port): Likewise.
-
-	(frob_set_mode): New function.  Set the mode bits of the ECR.
-	(get_fifo_residue): Use frob_set_mode.
-	(parport_pc_ecpepp_read_data): Likewise.
-	(parport_pc_ecpepp_write_data): Likewise.
-	(parport_pc_ecpepp_read_addr): Likewise.
-	(parport_pc_ecpepp_write_addr): Likewise.
-	(parport_pc_compat_write_block_pio): Likewise.
-	(parport_pc_ecp_write_block_pio): Likewise.
-	(parport_ECR_present): Likewise.
-	(parport_ECP_supported): Likewise.
-	(parport_EPP_supported): Likewise.
-	(parport_ECPEPP_supported): Likewise.
-	(programmable_irq_support): Likewise.
-	(irq_probe_ECP): Likewise.
-	(programmable_dma_support): Likewise.
-
-	(parport_pc_enable_irq): Only enable interrupts if we know which
-	IRQ line they will come from.
-	(parport_pc_init_state): Set nErrIntrEn at initialisation.
-	(parport_pc_restore_state): Only write writable bits of CTR.
-	(parport_irq_probe): If no IRQ is found, take ackIntEn out of the
-	writable bit set.
-
-2001-12-07  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_pc_fifo_write_block_pio): Correct typo.
-	(parport_pc_init_state): Only set ackIntEn if we know which IRQ
-	line the interrupts will come from.
-
-2001-12-07  Tim Waugh  <twaugh@redhat.com>
-
-	* ieee1284_ops.c (parport_ieee1284_epp_write_addr,
-	parport_ieee1284_epp_read_addr): Actually do something useful.
-
-2001-12-07  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (dmaval): Don't use DMA by default.  It seems to be
-	too buggy at the moment.  Use 'dma=auto' to restore the previous
-	behaviour.
-
-2001-12-07  Tim Waugh  <twaugh@redhat.com>
-
-	* daisy.c (DEBUG): Undefine.
-
-2001-12-06  Tim Waugh  <twaugh@redhat.com>
-
-	* ieee1284_ops.c (parport_ieee1284_ecp_read_data): Mask off
-	PARPORT_CONTROL_AUTOFD as well.  Bug spotted by Joe
-	<joeja@mindspring.com>.
-
-2001-12-03  Rich Liu  <Rich.Liu@ite.com.tw>
-
-	* parport_pc.c (sio_ite_8872_probe): ITE8873 is a single-port
-	serial board, not a serial+parallel.
-
-2001-11-30  Niels Kristian Bech Jensen  <nkbj@image.dk>
-
-	* parport_pc.c: Fix compiler warning.
-
-2001-11-14  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_pc_pci_probe): Hooks for PCI cards before
-	and after probing for ports.
-	* parport_serial.c (parport_register): Likewise.
-
-2001-11-12  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (init_module): Warn when parameters are ignored.
-
-2001-11-01  Damian Gruszka  <damian.gruszka@VisionSystems.de>
-
-	* parport_serial.c (serial_register): Set base_baud before
-	calling register_serial.
-
-2001-10-26  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_irq_probe): When ECR programmable IRQ
-	support fails, generate interrupts using the FIFO even if we don't
-	want to use the FIFO for real data transfers.
-	(parport_pc_probe_port): Display the ECR address if we have an
-	ECR, not just if we will use the FIFO.
-
-2001-10-24  Dave Strauss  <D.Strauss@motorola.com>
-
-	* parport_pc.c (parport_pc_compat_write_block_pio,
-	parport_pc_ecp_write_block_pio): Allow a few seconds for an ECP
-	transfer to finish up.
-
-2001-10-11  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc (sio_ite_8872_probe): New function, submitted by Rich
-	Liu from ITE.  Cleaned up, removed bogus phys_to_virt calls.
-
-2001-10-24  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c: Support for AKS AladdinCARD.  Patch from
-	Aladdin Knowledge Systems (Christian Groessler).
-
-2001-10-24  Tim Waugh  <twaugh@redhat.com>
-	
-	* ieee1284_ops.c (parport_ieee1284_ecp_read_data): Try to minimise
-	turnaround time.
-
-	* ieee1284.c (parport_poll_peripheral): Try a couple of times
-	first without delaying.
-
-2001-10-10  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c: Support for OX16PCI954 PCI card.
-
-2001-10-10  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c: Support for OX12PCI840 PCI card (reported by
-	mk@daveg.com).  Lock-ups diagnosed by Ronnie Arosa (and now we
-	just don't trust its ECR).
-
-2001-10-10  Gunther Mayer  <gunther.mayer@braunschweig.okersurf.de>
-
-	* parport_pc.c: Support for AVLAB cards.
-
-2001-10-10  Tim Waugh  <twaugh@redhat.com>
-
-	* ieee1284_ops.c (ecp_forward_to_reverse, ecp_reverse_to_forward):
-	Remember to retry direction switch if it fails.  Patch from David
-	Lambert.
-
-2001-10-08  David C. Hansen  <haveblue@us.ibm.com>
-
-	* share.c: Make driverlist_lock and parportlist_lock static.
-
-2001-10-08  Philip Blundell  <philb@gnu.org>
-
-	* parport_pc.c: New modular parameter verbose_logging.
-	Make port->modes indicate the modes that we are prepared to use,
-	rather than the modes that are available.
-
-2001-10-07  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_pc_probe_port): Fix memory leak spotted by
-	Kipp Cannon.
-
-2001-10-07  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_serial.c: Remove NetMos support, since it causes problems
-	for some people.
-
-2001-08-30  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_serial.c (parport_serial_pci_probe): Clean-up on partial
-	registration failure.
-
-2001-08-14  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_pc_init_superio): Allow for more than one
-	SuperIO device.  Patch from Rich Lio (ITE).
-
-2001-08-11  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c: Support for Titan Electronics cards.
-
-2001-08-08  Tim Waugh  <twaugh@redhat.com>
-
-	* share.c (parport_unregister_device): Remove device from wait list
-	too.
-
-2001-06-20  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c: Make 'io_hi=0' work.
-
-2001-05-31  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_serial.c: New file.
-
-2001-06-05  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_pc_unregister_port): New exported function.
-	Do the opposite of parport_pc_probe_port.
-	(cleanup_module): Use it.
-
-2001-05-22  Juan Quintela  <quintela@mandrakesoft.com>
-
-	* parport_amiga.c: Set printk levels.
-	* parport_gsc.c: Likewise.
-	* parport_mfc3.c: Likewise.
-	* parport_pc.c: Likewise.
-	* parport_sunbpp.c: Likewise.
-	* probe.c: Likewise.
-	* share.c: Likewise.
-
-2001-05-10  Fred Barnes  <frmb2@ukc.ac.uk>
-
-       * parport_pc.c (parport_pc_epp_read_data): added support for
-       reading from a w91284pic peripheral, flag is PARPORT_W91284PIC.
-
-2001-05-07  Fred Barnes  <frmb2@ukc.ac.uk>
- 
- 	* parport_pc.c (parport_pc_epp_read_data,
-	parport_pc_epp_write_data, parport_pc_epp_read_addr,
-	parport_pc_epp_write_addr): support for fast reads/writes using
-	the PARPORT_EPP_FAST flag.
- 
- 	* ieee1284.c (parport_read, parport_write): added code to handle
-	software EPP mode (IEEE1284_MODE_EPPSWE).  Added code to allow
-	BYTE mode reverse transfers (previously always went for NIBBLE
-	mode).
- 
- 	* ieee1284_ops.c (parport_ieee1284_epp_read_data,
-	parport_ieee1284_epp_write_data): fixed various polarity problems.
-	Also (theoretically) fixed address versions (.._addr), but no
-	hardware to test this on.
- 
- 	* parport_pc.h: added parport_dump_state() function for debugging.
- 	Needs to have DEBUG_PARPORT to be defined for it to be included.
- 
-2001-05-03  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c: Fix the compile problem I introduce from the last
-	change.
-
-2001-04-20  Paul Gortmaker  <p_gortmaker@yahoo.com>
-
-	* parport_pc.c: Cut down the size quite a bit (more than 4k off
-	the object, about 1k off the zImage) for the older non-PCI
-	machines which are typically resource starved anyway...
-
-2001-03-26  R Horn  <rjh@world.std.com>
-
-	* parport_pc.c: Some commentary changes.
-
-2001-04-19  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_pc_probe_port): Remove __devinit
-	attribute.  Export unconditionally.
-
-2001-04-14  Jeff Garzik  <jgarzik@pobox.com>
-
-	Merged:  2001-03-30  Tim Waugh  <twaugh@redhat.com>
-
-        * drivers/parport/parport_pc.c: Make Via SuperIO chipsets behave
-        like everything else with respect to irq= and dma= parameters.
-
-2001-04-08  Tim Waugh  <twaugh@redhat.com>
-
-      * parport_pc.c (parport_pc_save_state): Read from the soft copy of
-      the control port.
-      (parport_pc_restore_state): Update the soft copy of the control
-      port.
-
-2001-03-26  Tim Waugh  <twaugh@redhat.com>
-
-	* share.c (parport_find_number, parport_find_base): Trigger
-	a lowlevel driver load if there are no ports yet.
-
-2001-03-26  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_ECP_supported): Remove the IRQ conflict
-	check since it seems totally unreliable.
-
-2001-03-02  Tim Waugh  <twaugh@redhat.com>
-
-	* ieee1284_ops.c (parport_ieee1284_read_nibble): Reset nAutoFd
-	on timeout.  Matches 2.2.x behaviour.
-
-2001-03-02  Andrew Morton
-
-	* parport_pc.c (registered_parport): New static variable.
-	(parport_pc_find_ports): Set it when we register PCI driver.
-	(init_module): Unregister PCI driver if necessary when we
-	fail.
-
-2001-03-02  Tim Waugh  <twaugh@redhat.com>
-
-	* ieee1284_ops.c (parport_ieee1284_write_compat): Don't use
-	down_trylock to reset the IRQ count.  Don't even use sema_init,
-	because it's not even necessary to reset the count.  I can't
-	remember why we ever did.
-
-2001-01-04  Peter Osterlund  <peter.osterlund@mailbox.swipnet.se>
-
-	* ieee1284.c (parport_negotiate): Fix missing printk argument.
-
-2001-01-03  Paul Schleger  <Paul.Schleger@t-online.de>
-
-	* probe.c (parse_data): Get rid of trailing blanks in values.
-	Needed for XEROX XJ8C printer.
-
-2001-01-03  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_pc_probe_port): Say something when probes
-	are omitted.
-
-2001-01-03  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (sio_via_686a_probe): Correct dma=255 fix.
-
-2000-11-21  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_pc_ecp_write_block_pio): Fix
-	reverse-to-forward logic.  Spotted by Roland Kuck
-	<rci@cityweb.de>.
-
-2000-09-16  Cesar Eduardo Barros  <cesarb@nitnet.com.br>
-
-	* parport_pc.c (sio_via_686a_probe): Handle case
-	where hardware returns 255 for IRQ or DMA.
-
-2000-07-20  Eddie C. Dost  <ecd@skynet.be>
-
-	* share.c (attach_driver_chain): attach[i](port) needs to be
-	replaced by attach[count](port).
-
-2000-07-20  Eddie C. Dost  <ecd@skynet.be>
-
-	* daisy.c (add_dev): kmalloc args are in wrong order.
-
-2000-07-12  Tim Waugh  <twaugh@redhat.com>
-
-	* share.c: Documentation for parport_{get,port}_port,
-	parport_find_{number,base}.
-
-2000-07-12  Tim Waugh  <twaugh@redhat.com>
-
-	* share.c (parport_unregister_device): Remove unneeded locking
-	(test cad==dev).
-	(parport_claim): Likewise.
-	(parport_find_number): New function.
-
-2000-07-12  Tim Waugh  <twaugh@redhat.com>
-
-	* share.c (parport_register_port): Hold the parportlist_lock while
-	looking for a free parport number.
-	(parport_register_driver): Make sure that attach can block.
-	(attach_driver_chain): Likewise.
-
-2000-07-12  Tim Waugh  <twaugh@redhat.com>
-
-	* share.c (call_driver_chain): Do reference counting things.
-	(parport_get_port): New function.
-	(parport_put_port): New function.
-	(parport_register_port): Initialise reference count to zero.
-	(parport_unregister_port): Check reference count rather than
-	driver list to see if we can free the port.
-
-2000-07-12  Tim Waugh  <twaugh@redhat.com>
-
-	* share.c: Clarifications in doc comments.
-
-2000-07-12  Tim Waugh  <twaugh@redhat.com>
-
-	* share.c (parport_unregister_port): Fix typo in comment.
-
-2000-07-11  Gunther Mayer  <gunther.mayer@braunschweig.okersurf.de>
-
-	* parport_pc.c: Support for the full range of Timedia cards.
-
-2000-07-08  Tim Waugh  <twaugh@redhat.com>
-
-	* daisy.c: License block comments as part of parportbook.
-	* ieee1284.c: Likewise.
-	* share.c: Likewise.
-
-2000-06-30  Petr Vandrovec  <vandrove@vc.cvut.cz>
-
-	* procfs.c (do_hardware_modes): Generated string can be up to 34
-	chars long.
-
-2000-06-20  Gunther Mayer  <gunther.mayer@braunschweig.okersurf.de>
-
-	* parport_pc.c (parport_pc_compat_write_block_pio): Warn about
-	change_mode failures.
-	(parport_pc_ecp_write_block_pio): Likewise.
-	(parport_pc_ecp_read_block_pio): Likewise.
-
-2000-06-20  Gunther Mayer  <gunther.mayer@braunschweig.okersurf.de>
-
-	* parport_pc.c (parport_SPP_supported): Warn more about possibly
-	incorrect parameters.
-
-2000-06-15  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_ECP_supported): Set PARPORT_MODE_COMPAT
-	for ECP ports, since they can all do hardware accelerated
-	compatibility mode (I assume).
-
-2000-06-13  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (cleanup_module): Remark about possible bugs.
-
-2000-06-13  Tim Waugh  <twaugh@redhat.com>
-
-	* procfs.c: Break 'hardware' out into separate files.
-
-2000-05-28  Gunther Mayer  <gunther.mayer@braunschweig.okersurf.de>
-
-	* Fix PCI ID printk for non-superio PCI cards.
-
-2000-05-28  Tim Waugh  <twaugh@redhat.com>
-
-	* share.c (call_driver_chain): Get the driverlist_lock.
-	(parport_register_device): Make sure that port->devices always
-	looks consistent.
-	(parport_register_driver): Ensure that parport drivers are given
-	parameters that are valid for the duration of the callback by
-	locking the portlist against changes.
-	(parport_unregister_driver): Likewise.
-	(parport_claim): Don't overwrite flags.
-
-2000-05-28  Tim Waugh  <twaugh@redhat.com>
-
-	* daisy.c (assign_addrs): Avoid double-probing daisy-chain devices
-	if the first probe succeeds.
-
-2000-05-16  Tim Waugh  <twaugh@redhat.com>
-
-	* share.c (parport_claim): Fix SMP race.
-
-2000-05-15  Gunther Mayer  <gunther.mayer@braunschweig.okersurf.de>
-
-	* parport_pc.c (parport_pc_compat_write_block_pio): Check for
-	timeouts.
-	(parport_pc_ecp_write_block_pio): Likewise.
-	(parport_pc_ecp_read_block_pio): Likewise.
-
-2000-05-02  Gunther Mayer  <gunther.mayer@braunschweig.okersurf.de>
-
-	* parport_pc.c: PCI SYBA patch and verbose PCI detection.
-
-2000-05-02  Gunther Mayer  <gunther.mayer@braunschweig.okersurf.de>
-
-	* parport_pc.c (decode_smsc): Fix SMSC 665/666 identification.
-
-2000-04-28  Tim Waugh  <twaugh@redhat.com>
-
-	* ieee1284.c: Short function descriptions can't be multiline.
-
-	* daisy.c: Short function descriptions can't be multiline.
-
-2000-04-19  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_pc_fifo_write_block_dma): Make maxlen
-	calculation a bit clearer.
-
-	* ieee1284.c (parport_negotiate): Turn on data line drivers.
-
-	* ieee1284_ops.c (parport_ieee1284_read_byte): Turn off data line
-	drivers.
-	(parport_ieee1284_write_compat): Turn on data line drivers.
-
-	* daisy.c (assign_addrs): Turn on data line drivers.
-	(cpp_mux): Likewise.
-	(cpp_daisy): Likewise.
-
-2000-04-04  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c: Add support for another PCI card.
-
-2000-04-04  Tim Waugh  <twaugh@redhat.com>
-
-	* daisy.c: Documentation in kernel-doc format.
-
-	* ieee1284.c: Likewise.
-
-	* share.c: Likewise.
-
-2000-04-01  Tim Waugh  <twaugh@redhat.com>
-
-	* share.c (parport_register_device): Need to hold the module
-	reference counts before sleeping.
-
-2000-03-27  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_pc_ecp_read_block_pio): Correct operation
-	when peripheral is trying to send data when we stop listening.
-
-2000-03-22  Tim Waugh  <twaugh@redhat.com>
-
-	* init.c (parport_setup): Fix return value.
-
-2000-03-21  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_pc_pci_probe): Fix return value; call
-	pci_enable_device.
-
-2000-03-16  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_ECP_supported): This seems to trigger on
-	machines that don't have an IRQ conflict; toned down the warning
-	message accordingly.
-
-2000-03-16  Gunther Mayer  <gunther.mayer@braunschweig.netsurf.de>
-
-	* parport_pc.c (show_parconfig_smsc37c669): Fix typo.
-	(decode_winbond): More IDs.
-	(winbond_check): Protect against false positives.
-	(winbond_check2): Likewise.
-	(smsc_check): Likewise.
-
-2000-03-15  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (cleanup_module): Don't call pci_unregister_driver
-	if we didn't call pci_register_driver first.
-
-2000-03-13  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (parport_pc_init): Moved from asm/parport.h.
-
-	* Config.in: CONFIG_PARPORT_PC_SUPERIO: new option.
-
-	* parport_pc.c (show_parconfig_smsc37c669): Make __devinit.
-	(show_parconfig_winbond): Likewise.
-	(decode_winbond): Likewise.
-	(decode_smsc): Likewise.
-	(winbond_check): Likewise.
-	(winbond_check2): Likewise.
-	(smsc_check): Likewise.
-	(detect_and_report_winbond): Likewise.
-	(detect_and_report_smsc): Likewise.
-	(get_superio_dma): Likewise.
-	(get_superio_irq): Likewise.
-	(parport_pc_find_isa_ports): New function.
-	(parport_pc_find_ports): New function.
-	(init_module): Make superio a config option, not a parameter.
-
-2000-03-10  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c (decode_winbond): Use correct 83877ATF chip ID.
-	(decode_winbond): Fix typo.
-
-2000-03-09  Tim Waugh  <twaugh@redhat.com>
-
-	* parport_pc.c: Integrate SuperIO PCI probe with normal PCI card
-	probe, so that the MODULE_DEVICE_TABLE is complete.
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/parport/daisy.c linux-libre-2.6.34-gnu1/drivers/parport/daisy.c
--- linux-libre-2.6.33-gnu1/drivers/parport/daisy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/parport/daisy.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/parport.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #include <asm/current.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/parport/parport_ax88796.c linux-libre-2.6.34-gnu1/drivers/parport/parport_ax88796.c
--- linux-libre-2.6.33-gnu1/drivers/parport/parport_ax88796.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/parport/parport_ax88796.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/interrupt.h>
 #include <linux/errno.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/parport/parport_ip32.c linux-libre-2.6.34-gnu1/drivers/parport/parport_ip32.c
--- linux-libre-2.6.33-gnu1/drivers/parport/parport_ip32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/parport/parport_ip32.c	2010-05-16 17:17:36.000000000 -0400
@@ -103,6 +103,7 @@
 #include <linux/module.h>
 #include <linux/parport.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/stddef.h>
 #include <linux/types.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/parport/parport_pc.c linux-libre-2.6.34-gnu1/drivers/parport/parport_pc.c
--- linux-libre-2.6.33-gnu1/drivers/parport/parport_pc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/parport/parport_pc.c	2010-05-16 17:17:36.000000000 -0400
@@ -2908,6 +2908,7 @@ enum parport_pc_pci_cards {
 	netmos_9805,
 	netmos_9815,
 	netmos_9901,
+	netmos_9865,
 	quatech_sppxp100,
 };
 
@@ -2989,6 +2990,7 @@ static struct parport_pc_pci {
 	/* netmos_9805 */               { 1, { { 0, -1 }, } },
 	/* netmos_9815 */               { 2, { { 0, -1 }, { 2, -1 }, } },
 	/* netmos_9901 */               { 1, { { 0, -1 }, } },
+	/* netmos_9865 */               { 1, { { 0, -1 }, } },
 	/* quatech_sppxp100 */		{ 1, { { 0, 1 }, } },
 };
 
@@ -3092,6 +3094,10 @@ static const struct pci_device_id parpor
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 },
 	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901,
 	  0xA000, 0x2000, 0, 0, netmos_9901 },
+	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
+	  0xA000, 0x1000, 0, 0, netmos_9865 },
+	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
+	  0xA000, 0x2000, 0, 0, netmos_9865 },
 	/* Quatech SPPXP-100 Parallel port PCI ExpressCard */
 	{ PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 },
diff -druNp linux-libre-2.6.33-gnu1/drivers/parport/parport_serial.c linux-libre-2.6.34-gnu1/drivers/parport/parport_serial.c
--- linux-libre-2.6.33-gnu1/drivers/parport/parport_serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/parport/parport_serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/parport.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/parport/probe.c linux-libre-2.6.34-gnu1/drivers/parport/probe.c
--- linux-libre-2.6.33-gnu1/drivers/parport/probe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/parport/probe.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/parport.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 static const struct {
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/access.c linux-libre-2.6.34-gnu1/drivers/pci/access.c
--- linux-libre-2.6.33-gnu1/drivers/pci/access.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/access.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/wait.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/bus.c linux-libre-2.6.34-gnu1/drivers/pci/bus.c
--- linux-libre-2.6.33-gnu1/drivers/pci/bus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/bus.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,9 +14,56 @@
 #include <linux/ioport.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include "pci.h"
 
+void pci_bus_add_resource(struct pci_bus *bus, struct resource *res,
+			  unsigned int flags)
+{
+	struct pci_bus_resource *bus_res;
+
+	bus_res = kzalloc(sizeof(struct pci_bus_resource), GFP_KERNEL);
+	if (!bus_res) {
+		dev_err(&bus->dev, "can't add %pR resource\n", res);
+		return;
+	}
+
+	bus_res->res = res;
+	bus_res->flags = flags;
+	list_add_tail(&bus_res->list, &bus->resources);
+}
+
+struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n)
+{
+	struct pci_bus_resource *bus_res;
+
+	if (n < PCI_BRIDGE_RESOURCE_NUM)
+		return bus->resource[n];
+
+	n -= PCI_BRIDGE_RESOURCE_NUM;
+	list_for_each_entry(bus_res, &bus->resources, list) {
+		if (n-- == 0)
+			return bus_res->res;
+	}
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(pci_bus_resource_n);
+
+void pci_bus_remove_resources(struct pci_bus *bus)
+{
+	struct pci_bus_resource *bus_res, *tmp;
+	int i;
+
+	for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++)
+		bus->resource[i] = 0;
+
+	list_for_each_entry_safe(bus_res, tmp, &bus->resources, list) {
+		list_del(&bus_res->list);
+		kfree(bus_res);
+	}
+}
+
 /**
  * pci_bus_alloc_resource - allocate a resource from a parent bus
  * @bus: PCI bus
@@ -36,11 +83,14 @@ int
 pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
 		resource_size_t size, resource_size_t align,
 		resource_size_t min, unsigned int type_mask,
-		void (*alignf)(void *, struct resource *, resource_size_t,
-				resource_size_t),
+		resource_size_t (*alignf)(void *,
+					  const struct resource *,
+					  resource_size_t,
+					  resource_size_t),
 		void *alignf_data)
 {
 	int i, ret = -ENOMEM;
+	struct resource *r;
 	resource_size_t max = -1;
 
 	type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
@@ -49,8 +99,7 @@ pci_bus_alloc_resource(struct pci_bus *b
 	if (!(res->flags & IORESOURCE_MEM_64))
 		max = PCIBIOS_MAX_MEM_32;
 
-	for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
-		struct resource *r = bus->resource[i];
+	pci_bus_for_each_resource(bus, r, i) {
 		if (!r)
 			continue;
 
@@ -240,9 +289,9 @@ void pci_walk_bus(struct pci_bus *top, i
 			next = dev->bus_list.next;
 
 		/* Run device routines with the device locked */
-		down(&dev->dev.sem);
+		device_lock(&dev->dev);
 		retval = cb(dev, userdata);
-		up(&dev->dev.sem);
+		device_unlock(&dev->dev);
 		if (retval)
 			break;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/dmar.c linux-libre-2.6.34-gnu1/drivers/pci/dmar.c
--- linux-libre-2.6.33-gnu1/drivers/pci/dmar.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/dmar.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/interrupt.h>
 #include <linux/tboot.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 
 #define PREFIX "DMAR: "
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpi_pcihp.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/acpi_pcihp.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpi_pcihp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/acpi_pcihp.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/pci_hotplug.h>
 #include <linux/acpi.h>
 #include <linux/pci-acpi.h>
+#include <linux/slab.h>
 
 #define MY_NAME	"acpi_pcihp"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpiphp_core.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/acpiphp_core.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpiphp_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/acpiphp_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -332,8 +332,6 @@ int acpiphp_register_hotplug_slot(struct
 	slot->hotplug_slot->info->attention_status = 0;
 	slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot);
 	slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot);
-	slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
-	slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
 
 	acpiphp_slot->slot = slot;
 	snprintf(name, SLOT_NAME_SIZE, "%llu", slot->acpi_slot->sun);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpiphp_glue.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/acpiphp_glue.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpiphp_glue.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/acpiphp_glue.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,7 @@
 #include <linux/pci_hotplug.h>
 #include <linux/pci-acpi.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include "../pci.h"
 #include "acpiphp.h"
@@ -749,6 +750,24 @@ static int acpiphp_bus_trim(acpi_handle
 	return retval;
 }
 
+static void acpiphp_set_acpi_region(struct acpiphp_slot *slot)
+{
+	struct acpiphp_func *func;
+	union acpi_object params[2];
+	struct acpi_object_list arg_list;
+
+	list_for_each_entry(func, &slot->funcs, sibling) {
+		arg_list.count = 2;
+		arg_list.pointer = params;
+		params[0].type = ACPI_TYPE_INTEGER;
+		params[0].integer.value = ACPI_ADR_SPACE_PCI_CONFIG;
+		params[1].type = ACPI_TYPE_INTEGER;
+		params[1].integer.value = 1;
+		/* _REG is optional, we don't care about if there is failure */
+		acpi_evaluate_object(func->handle, "_REG", &arg_list, NULL);
+	}
+}
+
 /**
  * enable_device - enable, configure a slot
  * @slot: slot to be enabled
@@ -805,6 +824,7 @@ static int __ref enable_device(struct ac
 	pci_bus_assign_resources(bus);
 	acpiphp_sanitize_bus(bus);
 	acpiphp_set_hpp_values(bus);
+	acpiphp_set_acpi_region(slot);
 	pci_enable_bridges(bus);
 	pci_bus_add_devices(bus);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpiphp_ibm.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/acpiphp_ibm.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpiphp_ibm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/acpiphp_ibm.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <acpi/acpi_bus.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/cpcihp_generic.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/cpcihp_generic.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/cpcihp_generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/cpcihp_generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -162,6 +162,7 @@ static int __init cpcihp_generic_init(vo
 	dev = pci_get_slot(bus, PCI_DEVFN(bridge_slot, 0));
 	if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
 		err("Invalid bridge device %s", bridge);
+		pci_dev_put(dev);
 		return -EINVAL;
 	}
 	bus = dev->subordinate;
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/cpqphp_core.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/cpqphp_core.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/cpqphp_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/cpqphp_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -583,30 +583,6 @@ static int get_adapter_status(struct hot
 	return 0;
 }
 
-static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
-{
-	struct slot *slot = hotplug_slot->private;
-	struct controller *ctrl = slot->ctrl;
-
-	dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
-
-	*value = ctrl->speed_capability;
-
-	return 0;
-}
-
-static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
-{
-	struct slot *slot = hotplug_slot->private;
-	struct controller *ctrl = slot->ctrl;
-
-	dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
-
-	*value = ctrl->speed;
-
-	return 0;
-}
-
 static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
 	.set_attention_status =	set_attention_status,
 	.enable_slot =		process_SI,
@@ -616,8 +592,6 @@ static struct hotplug_slot_ops cpqphp_ho
 	.get_attention_status =	get_attention_status,
 	.get_latch_status =	get_latch_status,
 	.get_adapter_status =	get_adapter_status,
-	.get_max_bus_speed =	get_max_bus_speed,
-	.get_cur_bus_speed =	get_cur_bus_speed,
 };
 
 #define SLOT_NAME_SIZE 10
@@ -629,6 +603,7 @@ static int ctrl_slot_setup(struct contro
 	struct slot *slot;
 	struct hotplug_slot *hotplug_slot;
 	struct hotplug_slot_info *hotplug_slot_info;
+	struct pci_bus *bus = ctrl->pci_bus;
 	u8 number_of_slots;
 	u8 slot_device;
 	u8 slot_number;
@@ -694,7 +669,7 @@ static int ctrl_slot_setup(struct contro
 			slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
 		if (is_slot66mhz(slot))
 			slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
-		if (ctrl->speed == PCI_SPEED_66MHz)
+		if (bus->cur_bus_speed == PCI_SPEED_66MHz)
 			slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
 
 		ctrl_slot =
@@ -844,6 +819,7 @@ static int cpqhpc_probe(struct pci_dev *
 	u32 rc;
 	struct controller *ctrl;
 	struct pci_func *func;
+	struct pci_bus *bus;
 	int err;
 
 	err = pci_enable_device(pdev);
@@ -852,6 +828,7 @@ static int cpqhpc_probe(struct pci_dev *
 			pci_name(pdev), err);
 		return err;
 	}
+	bus = pdev->subordinate;
 
 	/* Need to read VID early b/c it's used to differentiate CPQ and INTC
 	 * discovery
@@ -929,22 +906,22 @@ static int cpqhpc_probe(struct pci_dev *
 			pci_read_config_byte(pdev, 0x41, &bus_cap);
 			if (bus_cap & 0x80) {
 				dbg("bus max supports 133MHz PCI-X\n");
-				ctrl->speed_capability = PCI_SPEED_133MHz_PCIX;
+				bus->max_bus_speed = PCI_SPEED_133MHz_PCIX;
 				break;
 			}
 			if (bus_cap & 0x40) {
 				dbg("bus max supports 100MHz PCI-X\n");
-				ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
+				bus->max_bus_speed = PCI_SPEED_100MHz_PCIX;
 				break;
 			}
 			if (bus_cap & 20) {
 				dbg("bus max supports 66MHz PCI-X\n");
-				ctrl->speed_capability = PCI_SPEED_66MHz_PCIX;
+				bus->max_bus_speed = PCI_SPEED_66MHz_PCIX;
 				break;
 			}
 			if (bus_cap & 10) {
 				dbg("bus max supports 66MHz PCI\n");
-				ctrl->speed_capability = PCI_SPEED_66MHz;
+				bus->max_bus_speed = PCI_SPEED_66MHz;
 				break;
 			}
 
@@ -955,7 +932,7 @@ static int cpqhpc_probe(struct pci_dev *
 		case PCI_SUB_HPC_ID:
 			/* Original 6500/7000 implementation */
 			ctrl->slot_switch_type = 1;
-			ctrl->speed_capability = PCI_SPEED_33MHz;
+			bus->max_bus_speed = PCI_SPEED_33MHz;
 			ctrl->push_button = 0;
 			ctrl->pci_config_space = 1;
 			ctrl->defeature_PHP = 1;
@@ -966,7 +943,7 @@ static int cpqhpc_probe(struct pci_dev *
 			/* First Pushbutton implementation */
 			ctrl->push_flag = 1;
 			ctrl->slot_switch_type = 1;
-			ctrl->speed_capability = PCI_SPEED_33MHz;
+			bus->max_bus_speed = PCI_SPEED_33MHz;
 			ctrl->push_button = 1;
 			ctrl->pci_config_space = 1;
 			ctrl->defeature_PHP = 1;
@@ -976,7 +953,7 @@ static int cpqhpc_probe(struct pci_dev *
 		case PCI_SUB_HPC_ID_INTC:
 			/* Third party (6500/7000) */
 			ctrl->slot_switch_type = 1;
-			ctrl->speed_capability = PCI_SPEED_33MHz;
+			bus->max_bus_speed = PCI_SPEED_33MHz;
 			ctrl->push_button = 0;
 			ctrl->pci_config_space = 1;
 			ctrl->defeature_PHP = 1;
@@ -987,7 +964,7 @@ static int cpqhpc_probe(struct pci_dev *
 			/* First 66 Mhz implementation */
 			ctrl->push_flag = 1;
 			ctrl->slot_switch_type = 1;
-			ctrl->speed_capability = PCI_SPEED_66MHz;
+			bus->max_bus_speed = PCI_SPEED_66MHz;
 			ctrl->push_button = 1;
 			ctrl->pci_config_space = 1;
 			ctrl->defeature_PHP = 1;
@@ -998,7 +975,7 @@ static int cpqhpc_probe(struct pci_dev *
 			/* First PCI-X implementation, 100MHz */
 			ctrl->push_flag = 1;
 			ctrl->slot_switch_type = 1;
-			ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
+			bus->max_bus_speed = PCI_SPEED_100MHz_PCIX;
 			ctrl->push_button = 1;
 			ctrl->pci_config_space = 1;
 			ctrl->defeature_PHP = 1;
@@ -1015,9 +992,9 @@ static int cpqhpc_probe(struct pci_dev *
 	case PCI_VENDOR_ID_INTEL:
 		/* Check for speed capability (0=33, 1=66) */
 		if (subsystem_deviceid & 0x0001)
-			ctrl->speed_capability = PCI_SPEED_66MHz;
+			bus->max_bus_speed = PCI_SPEED_66MHz;
 		else
-			ctrl->speed_capability = PCI_SPEED_33MHz;
+			bus->max_bus_speed = PCI_SPEED_33MHz;
 
 		/* Check for push button */
 		if (subsystem_deviceid & 0x0002)
@@ -1079,7 +1056,7 @@ static int cpqhpc_probe(struct pci_dev *
 					pdev->bus->number);
 
 	dbg("Hotplug controller capabilities:\n");
-	dbg("    speed_capability       %d\n", ctrl->speed_capability);
+	dbg("    speed_capability       %d\n", bus->max_bus_speed);
 	dbg("    slot_switch_type       %s\n", ctrl->slot_switch_type ?
 					"switch present" : "no switch");
 	dbg("    defeature_PHP          %s\n", ctrl->defeature_PHP ?
@@ -1142,7 +1119,7 @@ static int cpqhpc_probe(struct pci_dev *
 	}
 
 	/* Check for 66Mhz operation */
-	ctrl->speed = get_controller_speed(ctrl);
+	bus->cur_bus_speed = get_controller_speed(ctrl);
 
 
 	/********************************************************
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/cpqphp_ctrl.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/cpqphp_ctrl.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/cpqphp_ctrl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/cpqphp_ctrl.c	2010-05-16 17:17:36.000000000 -0400
@@ -1130,12 +1130,13 @@ static int is_bridge(struct pci_func * f
 static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot)
 {
 	struct slot *slot;
+	struct pci_bus *bus = ctrl->pci_bus;
 	u8 reg;
 	u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
 	u16 reg16;
 	u32 leds = readl(ctrl->hpc_reg + LED_CONTROL);
 
-	if (ctrl->speed == adapter_speed)
+	if (bus->cur_bus_speed == adapter_speed)
 		return 0;
 
 	/* We don't allow freq/mode changes if we find another adapter running
@@ -1152,7 +1153,7 @@ static u8 set_controller_speed(struct co
 		 * lower speed/mode, we allow the new adapter to function at
 		 * this rate if supported
 		 */
-		if (ctrl->speed < adapter_speed)
+		if (bus->cur_bus_speed < adapter_speed)
 			return 0;
 
 		return 1;
@@ -1161,20 +1162,20 @@ static u8 set_controller_speed(struct co
 	/* If the controller doesn't support freq/mode changes and the
 	 * controller is running at a higher mode, we bail
 	 */
-	if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability))
+	if ((bus->cur_bus_speed > adapter_speed) && (!ctrl->pcix_speed_capability))
 		return 1;
 
 	/* But we allow the adapter to run at a lower rate if possible */
-	if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability))
+	if ((bus->cur_bus_speed < adapter_speed) && (!ctrl->pcix_speed_capability))
 		return 0;
 
 	/* We try to set the max speed supported by both the adapter and
 	 * controller
 	 */
-	if (ctrl->speed_capability < adapter_speed) {
-		if (ctrl->speed == ctrl->speed_capability)
+	if (bus->max_bus_speed < adapter_speed) {
+		if (bus->cur_bus_speed == bus->max_bus_speed)
 			return 0;
-		adapter_speed = ctrl->speed_capability;
+		adapter_speed = bus->max_bus_speed;
 	}
 
 	writel(0x0L, ctrl->hpc_reg + LED_CONTROL);
@@ -1229,8 +1230,8 @@ static u8 set_controller_speed(struct co
 	pci_write_config_byte(ctrl->pci_dev, 0x43, reg);
 
 	/* Only if mode change...*/
-	if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) ||
-		((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) 
+	if (((bus->cur_bus_speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) ||
+		((bus->cur_bus_speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) 
 			set_SOGO(ctrl);
 
 	wait_for_ctrl_irq(ctrl);
@@ -1243,7 +1244,7 @@ static u8 set_controller_speed(struct co
 	set_SOGO(ctrl);
 	wait_for_ctrl_irq(ctrl);
 
-	ctrl->speed = adapter_speed;
+	bus->cur_bus_speed = adapter_speed;
 	slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
 
 	info("Successfully changed frequency/mode for adapter in slot %d\n",
@@ -1269,6 +1270,7 @@ static u8 set_controller_speed(struct co
  */
 static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
 {
+	struct pci_bus *bus = ctrl->pci_bus;
 	u8 hp_slot;
 	u8 temp_byte;
 	u8 adapter_speed;
@@ -1309,7 +1311,7 @@ static u32 board_replaced(struct pci_fun
 		wait_for_ctrl_irq (ctrl);
 
 		adapter_speed = get_adapter_speed(ctrl, hp_slot);
-		if (ctrl->speed != adapter_speed)
+		if (bus->cur_bus_speed != adapter_speed)
 			if (set_controller_speed(ctrl, adapter_speed, hp_slot))
 				rc = WRONG_BUS_FREQUENCY;
 
@@ -1426,6 +1428,7 @@ static u32 board_added(struct pci_func *
 	u32 temp_register = 0xFFFFFFFF;
 	u32 rc = 0;
 	struct pci_func *new_slot = NULL;
+	struct pci_bus *bus = ctrl->pci_bus;
 	struct slot *p_slot;
 	struct resource_lists res_lists;
 
@@ -1456,7 +1459,7 @@ static u32 board_added(struct pci_func *
 	wait_for_ctrl_irq (ctrl);
 
 	adapter_speed = get_adapter_speed(ctrl, hp_slot);
-	if (ctrl->speed != adapter_speed)
+	if (bus->cur_bus_speed != adapter_speed)
 		if (set_controller_speed(ctrl, adapter_speed, hp_slot))
 			rc = WRONG_BUS_FREQUENCY;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/cpqphp.h linux-libre-2.6.34-gnu1/drivers/pci/hotplug/cpqphp.h
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/cpqphp.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/cpqphp.h	2010-05-16 17:17:36.000000000 -0400
@@ -310,8 +310,6 @@ struct controller {
 	u8 first_slot;
 	u8 add_support;
 	u8 push_flag;
-	enum pci_bus_speed speed;
-	enum pci_bus_speed speed_capability;
 	u8 push_button;			/* 0 = no pushbutton, 1 = pushbutton present */
 	u8 slot_switch_type;		/* 0 = no switch, 1 = switch present */
 	u8 defeature_PHP;		/* 0 = PHP not supported, 1 = PHP supported */
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/cpqphp_sysfs.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/cpqphp_sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/cpqphp_sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/cpqphp_sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/workqueue.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/fakephp.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/fakephp.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/fakephp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/fakephp.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include "../pci.h"
 
 struct legacy_slot {
@@ -73,7 +74,7 @@ static void legacy_release(struct kobjec
 }
 
 static struct kobj_type legacy_ktype = {
-	.sysfs_ops = &(struct sysfs_ops){
+	.sysfs_ops = &(const struct sysfs_ops){
 		.store = legacy_store, .show = legacy_show
 	},
 	.release = &legacy_release,
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/ibmphp_core.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/ibmphp_core.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/ibmphp_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/ibmphp_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -395,89 +395,40 @@ static int get_adapter_present(struct ho
 	return rc;
 }
 
-static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
+static int get_max_bus_speed(struct slot *slot)
 {
-	int rc = -ENODEV;
-	struct slot *pslot;
+	int rc;
 	u8 mode = 0;
+	enum pci_bus_speed speed;
+	struct pci_bus *bus = slot->hotplug_slot->pci_slot->bus;
 
-	debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__,
-		hotplug_slot, value);
+	debug("%s - Entry slot[%p]\n", __func__, slot);
 
 	ibmphp_lock_operations();
-
-	if (hotplug_slot) {
-		pslot = hotplug_slot->private;
-		if (pslot) {
-			rc = 0;
-			mode = pslot->supported_bus_mode;
-			*value = pslot->supported_speed; 
-			switch (*value) {
-			case BUS_SPEED_33:
-				break;
-			case BUS_SPEED_66:
-				if (mode == BUS_MODE_PCIX) 
-					*value += 0x01;
-				break;
-			case BUS_SPEED_100:
-			case BUS_SPEED_133:
-				*value = pslot->supported_speed + 0x01;
-				break;
-			default:
-				/* Note (will need to change): there would be soon 256, 512 also */
-				rc = -ENODEV;
-			}
-		}
-	}
-
+	mode = slot->supported_bus_mode;
+	speed = slot->supported_speed; 
 	ibmphp_unlock_operations();
-	debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value);
-	return rc;
-}
 
-static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
-{
-	int rc = -ENODEV;
-	struct slot *pslot;
-	u8 mode = 0;
-
-	debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__,
-		hotplug_slot, value);
-
-	ibmphp_lock_operations();
-
-	if (hotplug_slot) {
-		pslot = hotplug_slot->private;
-		if (pslot) {
-			rc = get_cur_bus_info(&pslot);
-			if (!rc) {
-				mode = pslot->bus_on->current_bus_mode;
-				*value = pslot->bus_on->current_speed;
-				switch (*value) {
-				case BUS_SPEED_33:
-					break;
-				case BUS_SPEED_66:
-					if (mode == BUS_MODE_PCIX) 
-						*value += 0x01;
-					else if (mode == BUS_MODE_PCI)
-						;
-					else
-						*value = PCI_SPEED_UNKNOWN;
-					break;
-				case BUS_SPEED_100:
-				case BUS_SPEED_133:
-					*value += 0x01;
-					break;
-				default:
-					/* Note of change: there would also be 256, 512 soon */
-					rc = -ENODEV;
-				}
-			}
-		}
+	switch (speed) {
+	case BUS_SPEED_33:
+		break;
+	case BUS_SPEED_66:
+		if (mode == BUS_MODE_PCIX) 
+			speed += 0x01;
+		break;
+	case BUS_SPEED_100:
+	case BUS_SPEED_133:
+		speed += 0x01;
+		break;
+	default:
+		/* Note (will need to change): there would be soon 256, 512 also */
+		rc = -ENODEV;
 	}
 
-	ibmphp_unlock_operations();
-	debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value);
+	if (!rc)
+		bus->max_bus_speed = speed;
+
+	debug("%s - Exit rc[%d] speed[%x]\n", __func__, rc, speed);
 	return rc;
 }
 
@@ -572,6 +523,7 @@ static int __init init_ops(void)
 		if (slot_cur->bus_on->current_speed == 0xFF) 
 			if (get_cur_bus_info(&slot_cur)) 
 				return -1;
+		get_max_bus_speed(slot_cur);
 
 		if (slot_cur->ctrl->options == 0xFF)
 			if (get_hpc_options(slot_cur, &slot_cur->ctrl->options))
@@ -655,6 +607,7 @@ static int validate(struct slot *slot_cu
 int ibmphp_update_slot_info(struct slot *slot_cur)
 {
 	struct hotplug_slot_info *info;
+	struct pci_bus *bus = slot_cur->hotplug_slot->pci_slot->bus;
 	int rc;
 	u8 bus_speed;
 	u8 mode;
@@ -700,8 +653,7 @@ int ibmphp_update_slot_info(struct slot
 			bus_speed = PCI_SPEED_UNKNOWN;
 	}
 
-	info->cur_bus_speed = bus_speed;
-	info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
+	bus->cur_bus_speed = bus_speed;
 	// To do: bus_names 
 	
 	rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info);
@@ -1326,8 +1278,6 @@ struct hotplug_slot_ops ibmphp_hotplug_s
 	.get_attention_status =		get_attention_status,
 	.get_latch_status =		get_latch_status,
 	.get_adapter_status =		get_adapter_present,
-	.get_max_bus_speed =		get_max_bus_speed,
-	.get_cur_bus_speed =		get_cur_bus_speed,
 /*	.get_max_adapter_speed =	get_max_adapter_speed,
 	.get_bus_name_status =		get_bus_name,
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/ibmphp_ebda.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/ibmphp_ebda.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/ibmphp_ebda.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/ibmphp_ebda.c	2010-05-16 17:17:36.000000000 -0400
@@ -245,7 +245,7 @@ static void __init print_ebda_hpc (void)
 
 int __init ibmphp_access_ebda (void)
 {
-	u8 format, num_ctlrs, rio_complete, hs_complete;
+	u8 format, num_ctlrs, rio_complete, hs_complete, ebda_sz;
 	u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, re, rc_id, re_id, base;
 	int rc = 0;
 
@@ -260,7 +260,16 @@ int __init ibmphp_access_ebda (void)
 	iounmap (io_mem);
 	debug ("returned ebda segment: %x\n", ebda_seg);
 	
-	io_mem = ioremap(ebda_seg<<4, 1024);
+	io_mem = ioremap(ebda_seg<<4, 1);
+	if (!io_mem)
+		return -ENOMEM;
+	ebda_sz = readb(io_mem);
+	iounmap(io_mem);
+	debug("ebda size: %d(KiB)\n", ebda_sz);
+	if (ebda_sz == 0)
+		return -ENOMEM;
+
+	io_mem = ioremap(ebda_seg<<4, (ebda_sz * 1024));
 	if (!io_mem )
 		return -ENOMEM;
 	next_offset = 0x180;
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/ibmphp_hpc.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/ibmphp_hpc.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/ibmphp_hpc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/ibmphp_hpc.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/init.h>
 #include <linux/mutex.h>
 #include <linux/sched.h>
+#include <linux/semaphore.h>
 #include <linux/kthread.h>
 #include "ibmphp.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/ibmphp_res.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/ibmphp_res.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/ibmphp_res.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/ibmphp_res.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,7 +40,7 @@ static void update_resources (struct bus
 static int once_over (void);
 static int remove_ranges (struct bus_node *, struct bus_node *);
 static int update_bridge_ranges (struct bus_node **);
-static int add_range (int type, struct range_node *, struct bus_node *);
+static int add_bus_range (int type, struct range_node *, struct bus_node *);
 static void fix_resources (struct bus_node *);
 static struct bus_node *find_bus_wprev (u8, struct bus_node **, u8);
 
@@ -133,7 +133,7 @@ static int __init alloc_bus_range (struc
 		newrange->rangeno = 1;
 	else {
 		/* need to insert our range */
-		add_range (flag, newrange, newbus);
+		add_bus_range (flag, newrange, newbus);
 		debug ("%d resource Primary Bus inserted on bus %x [%x - %x]\n", flag, newbus->busno, newrange->start, newrange->end);
 	}
 
@@ -384,7 +384,7 @@ int __init ibmphp_rsrc_init (void)
  * Input: type of the resource, range to add, current bus
  * Output: 0 or -1, bus and range ptrs 
  ********************************************************************************/
-static int add_range (int type, struct range_node *range, struct bus_node *bus_cur)
+static int add_bus_range (int type, struct range_node *range, struct bus_node *bus_cur)
 {
 	struct range_node *range_cur = NULL;
 	struct range_node *range_prev;
@@ -455,7 +455,7 @@ static int add_range (int type, struct r
 
 /*******************************************************************************
  * This routine goes through the list of resources of type 'type' and updates
- * the range numbers that they correspond to.  It was called from add_range fnc
+ * the range numbers that they correspond to.  It was called from add_bus_range fnc
  *
  * Input: bus, type of the resource, the rangeno starting from which to update
  ******************************************************************************/
@@ -1999,7 +1999,7 @@ static int __init update_bridge_ranges (
 
 							if (bus_sec->noIORanges > 0) {
 								if (!range_exists_already (range, bus_sec, IO)) {
-									add_range (IO, range, bus_sec);
+									add_bus_range (IO, range, bus_sec);
 									++bus_sec->noIORanges;
 								} else {
 									kfree (range);
@@ -2048,7 +2048,7 @@ static int __init update_bridge_ranges (
 
 							if (bus_sec->noMemRanges > 0) {
 								if (!range_exists_already (range, bus_sec, MEM)) {
-									add_range (MEM, range, bus_sec);
+									add_bus_range (MEM, range, bus_sec);
 									++bus_sec->noMemRanges;
 								} else {
 									kfree (range);
@@ -2102,7 +2102,7 @@ static int __init update_bridge_ranges (
 
 							if (bus_sec->noPFMemRanges > 0) {
 								if (!range_exists_already (range, bus_sec, PFMEM)) {
-									add_range (PFMEM, range, bus_sec);
+									add_bus_range (PFMEM, range, bus_sec);
 									++bus_sec->noPFMemRanges;
 								} else {
 									kfree (range);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_acpi.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/pciehp_acpi.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_acpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/pciehp_acpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/acpi.h>
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
+#include <linux/slab.h>
 #include "pciehp.h"
 
 #define PCIEHP_DETECT_PCIE	(0)
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_core.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/pciehp_core.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/pciehp_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include "pciehp.h"
@@ -69,8 +70,6 @@ static int get_power_status	(struct hotp
 static int get_attention_status	(struct hotplug_slot *slot, u8 *value);
 static int get_latch_status	(struct hotplug_slot *slot, u8 *value);
 static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
-static int get_max_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
-static int get_cur_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
 
 /**
  * release_slot - free up the memory used by a slot
@@ -113,8 +112,6 @@ static int init_slot(struct controller *
 	ops->disable_slot = disable_slot;
 	ops->get_power_status = get_power_status;
 	ops->get_adapter_status = get_adapter_status;
-	ops->get_max_bus_speed = get_max_bus_speed;
-	ops->get_cur_bus_speed = get_cur_bus_speed;
 	if (MRL_SENS(ctrl))
 		ops->get_latch_status = get_latch_status;
 	if (ATTN_LED(ctrl)) {
@@ -227,27 +224,6 @@ static int get_adapter_status(struct hot
 	return pciehp_get_adapter_status(slot, value);
 }
 
-static int get_max_bus_speed(struct hotplug_slot *hotplug_slot,
-				enum pci_bus_speed *value)
-{
-	struct slot *slot = hotplug_slot->private;
-
-	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
-		 __func__, slot_name(slot));
-
-	return pciehp_get_max_link_speed(slot, value);
-}
-
-static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
-{
-	struct slot *slot = hotplug_slot->private;
-
-	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
-		 __func__, slot_name(slot));
-
-	return pciehp_get_cur_link_speed(slot, value);
-}
-
 static int pciehp_probe(struct pcie_device *dev)
 {
 	int rc;
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_ctrl.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/pciehp_ctrl.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_ctrl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/pciehp_ctrl.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/workqueue.h>
 #include "../pci.h"
@@ -341,6 +342,7 @@ void pciehp_queue_pushbutton_work(struct
 		p_slot->state = POWERON_STATE;
 		break;
 	default:
+		kfree(info);
 		goto out;
 	}
 	queue_work(pciehp_wq, &info->work);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_hpc.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/pciehp_hpc.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_hpc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/pciehp_hpc.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/time.h>
+#include <linux/slab.h>
 
 #include "../pci.h"
 #include "pciehp.h"
@@ -492,6 +493,7 @@ int pciehp_power_on_slot(struct slot * s
 	u16 slot_cmd;
 	u16 cmd_mask;
 	u16 slot_status;
+	u16 lnk_status;
 	int retval = 0;
 
 	/* Clear sticky power-fault bit from previous power failures */
@@ -523,6 +525,14 @@ int pciehp_power_on_slot(struct slot * s
 	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
 		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 
+	retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status);
+	if (retval) {
+		ctrl_err(ctrl, "%s: Cannot read LNKSTA register\n",
+				__func__);
+		return retval;
+	}
+	pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status);
+
 	return retval;
 }
 
@@ -610,37 +620,6 @@ static irqreturn_t pcie_isr(int irq, voi
 	return IRQ_HANDLED;
 }
 
-int pciehp_get_max_link_speed(struct slot *slot, enum pci_bus_speed *value)
-{
-	struct controller *ctrl = slot->ctrl;
-	enum pcie_link_speed lnk_speed;
-	u32	lnk_cap;
-	int retval = 0;
-
-	retval = pciehp_readl(ctrl, PCI_EXP_LNKCAP, &lnk_cap);
-	if (retval) {
-		ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__);
-		return retval;
-	}
-
-	switch (lnk_cap & 0x000F) {
-	case 1:
-		lnk_speed = PCIE_2_5GB;
-		break;
-	case 2:
-		lnk_speed = PCIE_5_0GB;
-		break;
-	default:
-		lnk_speed = PCIE_LNK_SPEED_UNKNOWN;
-		break;
-	}
-
-	*value = lnk_speed;
-	ctrl_dbg(ctrl, "Max link speed = %d\n", lnk_speed);
-
-	return retval;
-}
-
 int pciehp_get_max_lnk_width(struct slot *slot,
 				 enum pcie_link_width *value)
 {
@@ -691,38 +670,6 @@ int pciehp_get_max_lnk_width(struct slot
 	return retval;
 }
 
-int pciehp_get_cur_link_speed(struct slot *slot, enum pci_bus_speed *value)
-{
-	struct controller *ctrl = slot->ctrl;
-	enum pcie_link_speed lnk_speed = PCI_SPEED_UNKNOWN;
-	int retval = 0;
-	u16 lnk_status;
-
-	retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status);
-	if (retval) {
-		ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n",
-			 __func__);
-		return retval;
-	}
-
-	switch (lnk_status & PCI_EXP_LNKSTA_CLS) {
-	case 1:
-		lnk_speed = PCIE_2_5GB;
-		break;
-	case 2:
-		lnk_speed = PCIE_5_0GB;
-		break;
-	default:
-		lnk_speed = PCIE_LNK_SPEED_UNKNOWN;
-		break;
-	}
-
-	*value = lnk_speed;
-	ctrl_dbg(ctrl, "Current link speed = %d\n", lnk_speed);
-
-	return retval;
-}
-
 int pciehp_get_cur_lnk_width(struct slot *slot,
 				 enum pcie_link_width *value)
 {
@@ -886,9 +833,8 @@ static inline void dbg_ctrl(struct contr
 	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
 		if (!pci_resource_len(pdev, i))
 			continue;
-		ctrl_info(ctrl, "  PCI resource [%d]     : 0x%llx@0x%llx\n",
-			  i, (unsigned long long)pci_resource_len(pdev, i),
-			  (unsigned long long)pci_resource_start(pdev, i));
+		ctrl_info(ctrl, "  PCI resource [%d]     : %pR\n",
+			  i, &pdev->resource[i]);
 	}
 	ctrl_info(ctrl, "Slot Capabilities      : 0x%08x\n", ctrl->slot_cap);
 	ctrl_info(ctrl, "  Physical Slot Number : %d\n", PSN(ctrl));
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_pci.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/pciehp_pci.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/pciehp_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,17 +53,15 @@ static int __ref pciehp_add_bridge(struc
 		busnr = pci_scan_bridge(parent, dev, busnr, pass);
 	if (!dev->subordinate)
 		return -1;
-	pci_bus_size_bridges(dev->subordinate);
-	pci_bus_assign_resources(parent);
-	pci_enable_bridges(parent);
-	pci_bus_add_devices(parent);
+
 	return 0;
 }
 
 int pciehp_configure_device(struct slot *p_slot)
 {
 	struct pci_dev *dev;
-	struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate;
+	struct pci_dev *bridge = p_slot->ctrl->pcie->port;
+	struct pci_bus *parent = bridge->subordinate;
 	int num, fn;
 	struct controller *ctrl = p_slot->ctrl;
 
@@ -96,12 +94,25 @@ int pciehp_configure_device(struct slot
 				(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
 			pciehp_add_bridge(dev);
 		}
+		pci_dev_put(dev);
+	}
+
+	pci_assign_unassigned_bridge_resources(bridge);
+
+	for (fn = 0; fn < 8; fn++) {
+		dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
+		if (!dev)
+			continue;
+		if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
+			pci_dev_put(dev);
+			continue;
+		}
 		pci_configure_slot(dev);
 		pci_dev_put(dev);
 	}
 
-	pci_bus_assign_resources(parent);
 	pci_bus_add_devices(parent);
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pci_hotplug_core.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/pci_hotplug_core.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pci_hotplug_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/pci_hotplug_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,6 @@
 #include <linux/kobject.h>
 #include <linux/sysfs.h>
 #include <linux/pagemap.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
@@ -64,32 +63,6 @@ static int debug;
 static LIST_HEAD(pci_hotplug_slot_list);
 static DEFINE_MUTEX(pci_hp_mutex);
 
-/* these strings match up with the values in pci_bus_speed */
-static char *pci_bus_speed_strings[] = {
-	"33 MHz PCI",		/* 0x00 */
-	"66 MHz PCI",		/* 0x01 */
-	"66 MHz PCI-X",		/* 0x02 */
-	"100 MHz PCI-X",	/* 0x03 */
-	"133 MHz PCI-X",	/* 0x04 */
-	NULL,			/* 0x05 */
-	NULL,			/* 0x06 */
-	NULL,			/* 0x07 */
-	NULL,			/* 0x08 */
-	"66 MHz PCI-X 266",	/* 0x09 */
-	"100 MHz PCI-X 266",	/* 0x0a */
-	"133 MHz PCI-X 266",	/* 0x0b */
-	NULL,			/* 0x0c */
-	NULL,			/* 0x0d */
-	NULL,			/* 0x0e */
-	NULL,			/* 0x0f */
-	NULL,			/* 0x10 */
-	"66 MHz PCI-X 533",	/* 0x11 */
-	"100 MHz PCI-X 533",	/* 0x12 */
-	"133 MHz PCI-X 533",	/* 0x13 */
-	"2.5 GT/s PCIe",	/* 0x14 */
-	"5.0 GT/s PCIe",	/* 0x15 */
-};
-
 #ifdef CONFIG_HOTPLUG_PCI_CPCI
 extern int cpci_hotplug_init(int debug);
 extern void cpci_hotplug_exit(void);
@@ -118,8 +91,6 @@ GET_STATUS(power_status, u8)
 GET_STATUS(attention_status, u8)
 GET_STATUS(latch_status, u8)
 GET_STATUS(adapter_status, u8)
-GET_STATUS(max_bus_speed, enum pci_bus_speed)
-GET_STATUS(cur_bus_speed, enum pci_bus_speed)
 
 static ssize_t power_read_file(struct pci_slot *slot, char *buf)
 {
@@ -263,60 +234,6 @@ static struct pci_slot_attribute hotplug
 	.show = presence_read_file,
 };
 
-static char *unknown_speed = "Unknown bus speed";
-
-static ssize_t max_bus_speed_read_file(struct pci_slot *slot, char *buf)
-{
-	char *speed_string;
-	int retval;
-	enum pci_bus_speed value;
-	
-	retval = get_max_bus_speed(slot->hotplug, &value);
-	if (retval)
-		goto exit;
-
-	if (value == PCI_SPEED_UNKNOWN)
-		speed_string = unknown_speed;
-	else
-		speed_string = pci_bus_speed_strings[value];
-	
-	retval = sprintf (buf, "%s\n", speed_string);
-
-exit:
-	return retval;
-}
-
-static struct pci_slot_attribute hotplug_slot_attr_max_bus_speed = {
-	.attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO},
-	.show = max_bus_speed_read_file,
-};
-
-static ssize_t cur_bus_speed_read_file(struct pci_slot *slot, char *buf)
-{
-	char *speed_string;
-	int retval;
-	enum pci_bus_speed value;
-
-	retval = get_cur_bus_speed(slot->hotplug, &value);
-	if (retval)
-		goto exit;
-
-	if (value == PCI_SPEED_UNKNOWN)
-		speed_string = unknown_speed;
-	else
-		speed_string = pci_bus_speed_strings[value];
-	
-	retval = sprintf (buf, "%s\n", speed_string);
-
-exit:
-	return retval;
-}
-
-static struct pci_slot_attribute hotplug_slot_attr_cur_bus_speed = {
-	.attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO},
-	.show = cur_bus_speed_read_file,
-};
-
 static ssize_t test_write_file(struct pci_slot *pci_slot, const char *buf,
 		size_t count)
 {
@@ -391,26 +308,6 @@ static bool has_adapter_file(struct pci_
 	return false;
 }
 
-static bool has_max_bus_speed_file(struct pci_slot *pci_slot)
-{
-	struct hotplug_slot *slot = pci_slot->hotplug;
-	if ((!slot) || (!slot->ops))
-		return false;
-	if (slot->ops->get_max_bus_speed)
-		return true;
-	return false;
-}
-
-static bool has_cur_bus_speed_file(struct pci_slot *pci_slot)
-{
-	struct hotplug_slot *slot = pci_slot->hotplug;
-	if ((!slot) || (!slot->ops))
-		return false;
-	if (slot->ops->get_cur_bus_speed)
-		return true;
-	return false;
-}
-
 static bool has_test_file(struct pci_slot *pci_slot)
 {
 	struct hotplug_slot *slot = pci_slot->hotplug;
@@ -456,20 +353,6 @@ static int fs_add_slot(struct pci_slot *
 			goto exit_adapter;
 	}
 
-	if (has_max_bus_speed_file(slot)) {
-		retval = sysfs_create_file(&slot->kobj,
-					&hotplug_slot_attr_max_bus_speed.attr);
-		if (retval)
-			goto exit_max_speed;
-	}
-
-	if (has_cur_bus_speed_file(slot)) {
-		retval = sysfs_create_file(&slot->kobj,
-					&hotplug_slot_attr_cur_bus_speed.attr);
-		if (retval)
-			goto exit_cur_speed;
-	}
-
 	if (has_test_file(slot)) {
 		retval = sysfs_create_file(&slot->kobj,
 					   &hotplug_slot_attr_test.attr);
@@ -480,14 +363,6 @@ static int fs_add_slot(struct pci_slot *
 	goto exit;
 
 exit_test:
-	if (has_cur_bus_speed_file(slot))
-		sysfs_remove_file(&slot->kobj,
-				  &hotplug_slot_attr_cur_bus_speed.attr);
-exit_cur_speed:
-	if (has_max_bus_speed_file(slot))
-		sysfs_remove_file(&slot->kobj,
-				  &hotplug_slot_attr_max_bus_speed.attr);
-exit_max_speed:
 	if (has_adapter_file(slot))
 		sysfs_remove_file(&slot->kobj,
 				  &hotplug_slot_attr_presence.attr);
@@ -523,14 +398,6 @@ static void fs_remove_slot(struct pci_sl
 		sysfs_remove_file(&slot->kobj,
 				  &hotplug_slot_attr_presence.attr);
 
-	if (has_max_bus_speed_file(slot))
-		sysfs_remove_file(&slot->kobj,
-				  &hotplug_slot_attr_max_bus_speed.attr);
-
-	if (has_cur_bus_speed_file(slot))
-		sysfs_remove_file(&slot->kobj,
-				  &hotplug_slot_attr_cur_bus_speed.attr);
-
 	if (has_test_file(slot))
 		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/rpadlpar_core.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/rpadlpar_core.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/rpadlpar_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/rpadlpar_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/string.h>
+#include <linux/vmalloc.h>
 
 #include <asm/pci-bridge.h>
 #include <linux/mutex.h>
@@ -430,6 +431,8 @@ int dlpar_remove_slot(char *drc_name)
 			rc = dlpar_remove_pci_slot(drc_name, dn);
 			break;
 	}
+	vm_unmap_aliases();
+
 	printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name);
 exit:
 	mutex_unlock(&rpadlpar_mutex);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/rpaphp_core.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/rpaphp_core.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/rpaphp_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/rpaphp_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,9 +27,9 @@
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
-#include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/init.h>
+#include <linux/vmalloc.h>
 #include <asm/eeh.h>       /* for eeh_add_device() */
 #include <asm/rtas.h>		/* rtas_call */
 #include <asm/pci-bridge.h>	/* for pci_controller */
@@ -130,10 +130,9 @@ static int get_adapter_status(struct hot
 	return 0;
 }
 
-static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
+static enum pci_bus_speed get_max_bus_speed(struct slot *slot)
 {
-	struct slot *slot = (struct slot *)hotplug_slot->private;
-
+	enum pci_bus_speed speed;
 	switch (slot->type) {
 	case 1:
 	case 2:
@@ -141,30 +140,30 @@ static int get_max_bus_speed(struct hotp
 	case 4:
 	case 5:
 	case 6:
-		*value = PCI_SPEED_33MHz;	/* speed for case 1-6 */
+		speed = PCI_SPEED_33MHz;	/* speed for case 1-6 */
 		break;
 	case 7:
 	case 8:
-		*value = PCI_SPEED_66MHz;
+		speed = PCI_SPEED_66MHz;
 		break;
 	case 11:
 	case 14:
-		*value = PCI_SPEED_66MHz_PCIX;
+		speed = PCI_SPEED_66MHz_PCIX;
 		break;
 	case 12:
 	case 15:
-		*value = PCI_SPEED_100MHz_PCIX;
+		speed = PCI_SPEED_100MHz_PCIX;
 		break;
 	case 13:
 	case 16:
-		*value = PCI_SPEED_133MHz_PCIX;
+		speed = PCI_SPEED_133MHz_PCIX;
 		break;
 	default:
-		*value = PCI_SPEED_UNKNOWN;
+		speed = PCI_SPEED_UNKNOWN;
 		break;
-
 	}
-	return 0;
+
+	return speed;
 }
 
 static int get_children_props(struct device_node *dn, const int **drc_indexes,
@@ -408,6 +407,8 @@ static int enable_slot(struct hotplug_sl
 		slot->state = NOT_VALID;
 		return -EINVAL;
 	}
+
+	slot->bus->max_bus_speed = get_max_bus_speed(slot);
 	return 0;
 }
 
@@ -418,6 +419,8 @@ static int disable_slot(struct hotplug_s
 		return -EINVAL;
 
 	pcibios_remove_pci_devices(slot->bus);
+	vm_unmap_aliases();
+
 	slot->state = NOT_CONFIGURED;
 	return 0;
 }
@@ -429,7 +432,6 @@ struct hotplug_slot_ops rpaphp_hotplug_s
 	.get_power_status = get_power_status,
 	.get_attention_status = get_attention_status,
 	.get_adapter_status = get_adapter_status,
-	.get_max_bus_speed = get_max_bus_speed,
 };
 
 module_init(rpaphp_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/sgi_hotplug.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/sgi_hotplug.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/sgi_hotplug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/sgi_hotplug.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/mutex.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/shpchp_core.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/shpchp_core.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/shpchp_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/shpchp_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/workqueue.h>
 #include "shpchp.h"
@@ -65,8 +66,6 @@ static int get_power_status	(struct hotp
 static int get_attention_status	(struct hotplug_slot *slot, u8 *value);
 static int get_latch_status	(struct hotplug_slot *slot, u8 *value);
 static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
-static int get_max_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
-static int get_cur_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
 
 static struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
 	.set_attention_status =	set_attention_status,
@@ -76,8 +75,6 @@ static struct hotplug_slot_ops shpchp_ho
 	.get_attention_status =	get_attention_status,
 	.get_latch_status =	get_latch_status,
 	.get_adapter_status =	get_adapter_status,
-	.get_max_bus_speed =	get_max_bus_speed,
-	.get_cur_bus_speed =	get_cur_bus_speed,
 };
 
 /**
@@ -278,37 +275,6 @@ static int get_adapter_status (struct ho
 
 	return 0;
 }
-
-static int get_max_bus_speed(struct hotplug_slot *hotplug_slot,
-				enum pci_bus_speed *value)
-{
-	struct slot *slot = get_slot(hotplug_slot);
-	int retval;
-
-	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
-		 __func__, slot_name(slot));
-
-	retval = slot->hpc_ops->get_max_bus_speed(slot, value);
-	if (retval < 0)
-		*value = PCI_SPEED_UNKNOWN;
-
-	return 0;
-}
-
-static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
-{
-	struct slot *slot = get_slot(hotplug_slot);
-	int retval;
-
-	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
-		 __func__, slot_name(slot));
-
-	retval = slot->hpc_ops->get_cur_bus_speed(slot, value);
-	if (retval < 0)
-		*value = PCI_SPEED_UNKNOWN;
-
-	return 0;
-}
 
 static int is_shpc_capable(struct pci_dev *dev)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/shpchp_ctrl.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/shpchp_ctrl.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/shpchp_ctrl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/shpchp_ctrl.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/workqueue.h>
 #include "../pci.h"
@@ -285,17 +286,8 @@ static int board_added(struct slot *p_sl
 		return WRONG_BUS_FREQUENCY;
 	}
 
-	rc = p_slot->hpc_ops->get_cur_bus_speed(p_slot, &bsp);
-	if (rc) {
-		ctrl_err(ctrl, "Can't get bus operation speed\n");
-		return WRONG_BUS_FREQUENCY;
-	}
-
-	rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &msp);
-	if (rc) {
-		ctrl_err(ctrl, "Can't get max bus operation speed\n");
-		msp = bsp;
-	}
+	bsp = ctrl->pci_dev->bus->cur_bus_speed;
+	msp = ctrl->pci_dev->bus->max_bus_speed;
 
 	/* Check if there are other slots or devices on the same bus */
 	if (!list_empty(&ctrl->pci_dev->subordinate->devices))
@@ -462,6 +454,7 @@ void shpchp_queue_pushbutton_work(struct
 		p_slot->state = POWERON_STATE;
 		break;
 	default:
+		kfree(info);
 		goto out;
 	}
 	queue_work(shpchp_wq, &info->work);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/shpchp.h linux-libre-2.6.34-gnu1/drivers/pci/hotplug/shpchp.h
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/shpchp.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/shpchp.h	2010-05-16 17:17:36.000000000 -0400
@@ -333,8 +333,6 @@ struct hpc_ops {
 	int (*set_attention_status)(struct slot *slot, u8 status);
 	int (*get_latch_status)(struct slot *slot, u8 *status);
 	int (*get_adapter_status)(struct slot *slot, u8 *status);
-	int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
-	int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
 	int (*get_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed);
 	int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode);
 	int (*get_prog_int)(struct slot *slot, u8 *prog_int);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/shpchp_hpc.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/shpchp_hpc.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/shpchp_hpc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/shpchp_hpc.c	2010-05-16 17:17:36.000000000 -0400
@@ -660,6 +660,75 @@ static int hpc_slot_disable(struct slot
 	return retval;
 }
 
+static int shpc_get_cur_bus_speed(struct controller *ctrl)
+{
+	int retval = 0;
+	struct pci_bus *bus = ctrl->pci_dev->subordinate;
+	enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
+	u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG);
+	u8 pi = shpc_readb(ctrl, PROG_INTERFACE);
+	u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7);
+
+	if ((pi == 1) && (speed_mode > 4)) {
+		retval = -ENODEV;
+		goto out;
+	}
+
+	switch (speed_mode) {
+	case 0x0:
+		bus_speed = PCI_SPEED_33MHz;
+		break;
+	case 0x1:
+		bus_speed = PCI_SPEED_66MHz;
+		break;
+	case 0x2:
+		bus_speed = PCI_SPEED_66MHz_PCIX;
+		break;
+	case 0x3:
+		bus_speed = PCI_SPEED_100MHz_PCIX;
+		break;
+	case 0x4:
+		bus_speed = PCI_SPEED_133MHz_PCIX;
+		break;
+	case 0x5:
+		bus_speed = PCI_SPEED_66MHz_PCIX_ECC;
+		break;
+	case 0x6:
+		bus_speed = PCI_SPEED_100MHz_PCIX_ECC;
+		break;
+	case 0x7:
+		bus_speed = PCI_SPEED_133MHz_PCIX_ECC;
+		break;
+	case 0x8:
+		bus_speed = PCI_SPEED_66MHz_PCIX_266;
+		break;
+	case 0x9:
+		bus_speed = PCI_SPEED_100MHz_PCIX_266;
+		break;
+	case 0xa:
+		bus_speed = PCI_SPEED_133MHz_PCIX_266;
+		break;
+	case 0xb:
+		bus_speed = PCI_SPEED_66MHz_PCIX_533;
+		break;
+	case 0xc:
+		bus_speed = PCI_SPEED_100MHz_PCIX_533;
+		break;
+	case 0xd:
+		bus_speed = PCI_SPEED_133MHz_PCIX_533;
+		break;
+	default:
+		retval = -ENODEV;
+		break;
+	}
+
+ out:
+	bus->cur_bus_speed = bus_speed;
+	dbg("Current bus speed = %d\n", bus_speed);
+	return retval;
+}
+
+
 static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
 {
 	int retval;
@@ -720,6 +789,8 @@ static int hpc_set_bus_speed_mode(struct
 	retval = shpc_write_cmd(slot, 0, cmd);
 	if (retval)
 		ctrl_err(ctrl, "%s: Write command failed!\n", __func__);
+	else
+		shpc_get_cur_bus_speed(ctrl);
 
 	return retval;
 }
@@ -803,10 +874,10 @@ static irqreturn_t shpc_isr(int irq, voi
 	return IRQ_HANDLED;
 }
 
-static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value)
+static int shpc_get_max_bus_speed(struct controller *ctrl)
 {
 	int retval = 0;
-	struct controller *ctrl = slot->ctrl;
+	struct pci_bus *bus = ctrl->pci_dev->subordinate;
 	enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
 	u8 pi = shpc_readb(ctrl, PROG_INTERFACE);
 	u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1);
@@ -842,79 +913,12 @@ static int hpc_get_max_bus_speed (struct
 			retval = -ENODEV;
 	}
 
-	*value = bus_speed;
+	bus->max_bus_speed = bus_speed;
 	ctrl_dbg(ctrl, "Max bus speed = %d\n", bus_speed);
 
 	return retval;
 }
 
-static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value)
-{
-	int retval = 0;
-	struct controller *ctrl = slot->ctrl;
-	enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
-	u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG);
-	u8 pi = shpc_readb(ctrl, PROG_INTERFACE);
-	u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7);
-
-	if ((pi == 1) && (speed_mode > 4)) {
-		*value = PCI_SPEED_UNKNOWN;
-		return -ENODEV;
-	}
-
-	switch (speed_mode) {
-	case 0x0:
-		*value = PCI_SPEED_33MHz;
-		break;
-	case 0x1:
-		*value = PCI_SPEED_66MHz;
-		break;
-	case 0x2:
-		*value = PCI_SPEED_66MHz_PCIX;
-		break;
-	case 0x3:
-		*value = PCI_SPEED_100MHz_PCIX;
-		break;
-	case 0x4:
-		*value = PCI_SPEED_133MHz_PCIX;
-		break;
-	case 0x5:
-		*value = PCI_SPEED_66MHz_PCIX_ECC;
-		break;
-	case 0x6:
-		*value = PCI_SPEED_100MHz_PCIX_ECC;
-		break;
-	case 0x7:
-		*value = PCI_SPEED_133MHz_PCIX_ECC;
-		break;
-	case 0x8:
-		*value = PCI_SPEED_66MHz_PCIX_266;
-		break;
-	case 0x9:
-		*value = PCI_SPEED_100MHz_PCIX_266;
-		break;
-	case 0xa:
-		*value = PCI_SPEED_133MHz_PCIX_266;
-		break;
-	case 0xb:
-		*value = PCI_SPEED_66MHz_PCIX_533;
-		break;
-	case 0xc:
-		*value = PCI_SPEED_100MHz_PCIX_533;
-		break;
-	case 0xd:
-		*value = PCI_SPEED_133MHz_PCIX_533;
-		break;
-	default:
-		*value = PCI_SPEED_UNKNOWN;
-		retval = -ENODEV;
-		break;
-	}
-
-	ctrl_dbg(ctrl, "Current bus speed = %d\n", bus_speed);
-	return retval;
-}
-
 static struct hpc_ops shpchp_hpc_ops = {
 	.power_on_slot			= hpc_power_on_slot,
 	.slot_enable			= hpc_slot_enable,
@@ -926,8 +930,6 @@ static struct hpc_ops shpchp_hpc_ops = {
 	.get_latch_status		= hpc_get_latch_status,
 	.get_adapter_status		= hpc_get_adapter_status,
 
-	.get_max_bus_speed		= hpc_get_max_bus_speed,
-	.get_cur_bus_speed		= hpc_get_cur_bus_speed,
 	.get_adapter_speed		= hpc_get_adapter_speed,
 	.get_mode1_ECC_cap		= hpc_get_mode1_ECC_cap,
 	.get_prog_int			= hpc_get_prog_int,
@@ -1086,6 +1088,9 @@ int shpc_init(struct controller *ctrl, s
 	}
 	ctrl_dbg(ctrl, "HPC at %s irq=%x\n", pci_name(pdev), pdev->irq);
 
+	shpc_get_max_bus_speed(ctrl);
+	shpc_get_cur_bus_speed(ctrl);
+
 	/*
 	 * If this is the first controller to be initialized,
 	 * initialize the shpchpd work queue
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/hotplug/shpchp_sysfs.c linux-libre-2.6.34-gnu1/drivers/pci/hotplug/shpchp_sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/pci/hotplug/shpchp_sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/hotplug/shpchp_sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,8 +47,7 @@ static ssize_t show_ctrl (struct device
 	bus = pdev->subordinate;
 
 	out += sprintf(buf, "Free resources: memory\n");
-	for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) {
-		res = bus->resource[index];
+	pci_bus_for_each_resource(bus, res, index) {
 		if (res && (res->flags & IORESOURCE_MEM) &&
 				!(res->flags & IORESOURCE_PREFETCH)) {
 			out += sprintf(out, "start = %8.8llx, "
@@ -58,8 +57,7 @@ static ssize_t show_ctrl (struct device
 		}
 	}
 	out += sprintf(out, "Free resources: prefetchable memory\n");
-	for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) {
-		res = bus->resource[index];
+	pci_bus_for_each_resource(bus, res, index) {
 		if (res && (res->flags & IORESOURCE_MEM) &&
 			       (res->flags & IORESOURCE_PREFETCH)) {
 			out += sprintf(out, "start = %8.8llx, "
@@ -69,8 +67,7 @@ static ssize_t show_ctrl (struct device
 		}
 	}
 	out += sprintf(out, "Free resources: IO\n");
-	for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) {
-		res = bus->resource[index];
+	pci_bus_for_each_resource(bus, res, index) {
 		if (res && (res->flags & IORESOURCE_IO)) {
 			out += sprintf(out, "start = %8.8llx, "
 					"length = %8.8llx\n",
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/htirq.c linux-libre-2.6.34-gnu1/drivers/pci/htirq.c
--- linux-libre-2.6.33-gnu1/drivers/pci/htirq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/htirq.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
-#include <linux/gfp.h>
 #include <linux/htirq.h>
 
 /* Global ht irq lock.
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/intr_remapping.c linux-libre-2.6.34-gnu1/drivers/pci/intr_remapping.c
--- linux-libre-2.6.33-gnu1/drivers/pci/intr_remapping.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/intr_remapping.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 #include <linux/interrupt.h>
 #include <linux/dmar.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/jiffies.h>
 #include <linux/hpet.h>
 #include <linux/pci.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/ioapic.c linux-libre-2.6.34-gnu1/drivers/pci/ioapic.c
--- linux-libre-2.6.33-gnu1/drivers/pci/ioapic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/ioapic.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 
 #include <linux/pci.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 
 struct ioapic {
@@ -31,9 +32,9 @@ static int ioapic_probe(struct pci_dev *
 	acpi_status status;
 	unsigned long long gsb;
 	struct ioapic *ioapic;
-	u64 addr;
 	int ret;
 	char *type;
+	struct resource *res;
 
 	handle = DEVICE_ACPI_HANDLE(&dev->dev);
 	if (!handle)
@@ -69,13 +70,12 @@ static int ioapic_probe(struct pci_dev *
 	if (pci_request_region(dev, 0, type))
 		goto exit_disable;
 
-	addr = pci_resource_start(dev, 0);
-	if (acpi_register_ioapic(ioapic->handle, addr, ioapic->gsi_base))
+	res = &dev->resource[0];
+	if (acpi_register_ioapic(ioapic->handle, res->start, ioapic->gsi_base))
 		goto exit_release;
 
 	pci_set_drvdata(dev, ioapic);
-	dev_info(&dev->dev, "%s at %#llx, GSI %u\n", type, addr,
-		 ioapic->gsi_base);
+	dev_info(&dev->dev, "%s at %pR, GSI %u\n", type, res, ioapic->gsi_base);
 	return 0;
 
 exit_release:
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/iov.c linux-libre-2.6.34-gnu1/drivers/pci/iov.c
--- linux-libre-2.6.33-gnu1/drivers/pci/iov.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/iov.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/string.h>
 #include <linux/delay.h>
@@ -706,6 +707,21 @@ irqreturn_t pci_sriov_migration(struct p
 }
 EXPORT_SYMBOL_GPL(pci_sriov_migration);
 
+/**
+ * pci_num_vf - return number of VFs associated with a PF device_release_driver
+ * @dev: the PCI device
+ *
+ * Returns number of VFs, or 0 if SR-IOV is not enabled.
+ */
+int pci_num_vf(struct pci_dev *dev)
+{
+	if (!dev || !dev->is_physfn)
+		return 0;
+	else
+		return dev->sriov->nr_virtfn;
+}
+EXPORT_SYMBOL_GPL(pci_num_vf);
+
 static int ats_alloc_one(struct pci_dev *dev, int ps)
 {
 	int pos;
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/Kconfig linux-libre-2.6.34-gnu1/drivers/pci/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/pci/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -21,17 +21,6 @@ config PCI_MSI
 
 	   If you don't know what to do here, say N.
 
-config PCI_LEGACY
-	bool "Enable deprecated pci_find_* API"
-	depends on PCI
-	default y
-	help
-	  Say Y here if you want to include support for the deprecated
-	  pci_find_device() API.  Most drivers have been converted over
-	  to using the proper hotplug APIs, so this option serves to
-	  include/exclude only a few drivers that are still using this
-	  API.
-
 config PCI_DEBUG
 	bool "PCI Debugging"
 	depends on PCI && DEBUG_KERNEL
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/legacy.c linux-libre-2.6.34-gnu1/drivers/pci/legacy.c
--- linux-libre-2.6.33-gnu1/drivers/pci/legacy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/legacy.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,34 +0,0 @@
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include "pci.h"
-
-/**
- * pci_find_device - begin or continue searching for a PCI device by vendor/device id
- * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
- * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
- * @from: Previous PCI device found in search, or %NULL for new search.
- *
- * Iterates through the list of known PCI devices.  If a PCI device is found
- * with a matching @vendor and @device, a pointer to its device structure is
- * returned.  Otherwise, %NULL is returned.
- * A new search is initiated by passing %NULL as the @from argument.
- * Otherwise if @from is not %NULL, searches continue from next device
- * on the global list.
- *
- * NOTE: Do not use this function any more; use pci_get_device() instead, as
- * the PCI device returned by this function can disappear at any moment in
- * time.
- */
-struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device,
-				struct pci_dev *from)
-{
-	struct pci_dev *pdev;
-
-	pci_dev_get(from);
-	pdev = pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
-	pci_dev_put(pdev);
-	return pdev;
-}
-EXPORT_SYMBOL(pci_find_device);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/Makefile linux-libre-2.6.34-gnu1/drivers/pci/Makefile
--- linux-libre-2.6.33-gnu1/drivers/pci/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -2,14 +2,13 @@
 # Makefile for the PCI bus specific drivers.
 #
 
-obj-y		+= access.o bus.o probe.o remove.o pci.o quirks.o \
+obj-y		+= access.o bus.o probe.o remove.o pci.o \
 			pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \
-			irq.o
+			irq.o vpd.o
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_SYSFS) += slot.o
 
-obj-$(CONFIG_PCI_LEGACY) += legacy.o
-CFLAGS_legacy.o += -Wno-deprecated-declarations
+obj-$(CONFIG_PCI_QUIRKS) += quirks.o
 
 # Build PCI Express stuff if needed
 obj-$(CONFIG_PCIEPORTBUS) += pcie/
@@ -49,6 +48,7 @@ obj-$(CONFIG_PPC) += setup-bus.o
 obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
 obj-$(CONFIG_X86_VISWS) += setup-irq.o
 obj-$(CONFIG_MN10300) += setup-bus.o
+obj-$(CONFIG_MICROBLAZE) += setup-bus.o
 
 #
 # ACPI Related PCI FW Functions
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/msi.c linux-libre-2.6.34-gnu1/drivers/pci/msi.c
--- linux-libre-2.6.33-gnu1/drivers/pci/msi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/msi.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/smp.h>
 #include <linux/errno.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include "pci.h"
 #include "msi.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pci-acpi.c linux-libre-2.6.34-gnu1/drivers/pci/pci-acpi.c
--- linux-libre-2.6.33-gnu1/drivers/pci/pci-acpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pci-acpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,8 +16,144 @@
 #include <acpi/acpi_bus.h>
 
 #include <linux/pci-acpi.h>
+#include <linux/pm_runtime.h>
 #include "pci.h"
 
+static DEFINE_MUTEX(pci_acpi_pm_notify_mtx);
+
+/**
+ * pci_acpi_wake_bus - Wake-up notification handler for root buses.
+ * @handle: ACPI handle of a device the notification is for.
+ * @event: Type of the signaled event.
+ * @context: PCI root bus to wake up devices on.
+ */
+static void pci_acpi_wake_bus(acpi_handle handle, u32 event, void *context)
+{
+	struct pci_bus *pci_bus = context;
+
+	if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_bus)
+		pci_pme_wakeup_bus(pci_bus);
+}
+
+/**
+ * pci_acpi_wake_dev - Wake-up notification handler for PCI devices.
+ * @handle: ACPI handle of a device the notification is for.
+ * @event: Type of the signaled event.
+ * @context: PCI device object to wake up.
+ */
+static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
+{
+	struct pci_dev *pci_dev = context;
+
+	if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) {
+		pci_check_pme_status(pci_dev);
+		pm_runtime_resume(&pci_dev->dev);
+		if (pci_dev->subordinate)
+			pci_pme_wakeup_bus(pci_dev->subordinate);
+	}
+}
+
+/**
+ * add_pm_notifier - Register PM notifier for given ACPI device.
+ * @dev: ACPI device to add the notifier for.
+ * @context: PCI device or bus to check for PME status if an event is signaled.
+ *
+ * NOTE: @dev need not be a run-wake or wake-up device to be a valid source of
+ * PM wake-up events.  For example, wake-up events may be generated for bridges
+ * if one of the devices below the bridge is signaling PME, even if the bridge
+ * itself doesn't have a wake-up GPE associated with it.
+ */
+static acpi_status add_pm_notifier(struct acpi_device *dev,
+				   acpi_notify_handler handler,
+				   void *context)
+{
+	acpi_status status = AE_ALREADY_EXISTS;
+
+	mutex_lock(&pci_acpi_pm_notify_mtx);
+
+	if (dev->wakeup.flags.notifier_present)
+		goto out;
+
+	status = acpi_install_notify_handler(dev->handle,
+					     ACPI_SYSTEM_NOTIFY,
+					     handler, context);
+	if (ACPI_FAILURE(status))
+		goto out;
+
+	dev->wakeup.flags.notifier_present = true;
+
+ out:
+	mutex_unlock(&pci_acpi_pm_notify_mtx);
+	return status;
+}
+
+/**
+ * remove_pm_notifier - Unregister PM notifier from given ACPI device.
+ * @dev: ACPI device to remove the notifier from.
+ */
+static acpi_status remove_pm_notifier(struct acpi_device *dev,
+				      acpi_notify_handler handler)
+{
+	acpi_status status = AE_BAD_PARAMETER;
+
+	mutex_lock(&pci_acpi_pm_notify_mtx);
+
+	if (!dev->wakeup.flags.notifier_present)
+		goto out;
+
+	status = acpi_remove_notify_handler(dev->handle,
+					    ACPI_SYSTEM_NOTIFY,
+					    handler);
+	if (ACPI_FAILURE(status))
+		goto out;
+
+	dev->wakeup.flags.notifier_present = false;
+
+ out:
+	mutex_unlock(&pci_acpi_pm_notify_mtx);
+	return status;
+}
+
+/**
+ * pci_acpi_add_bus_pm_notifier - Register PM notifier for given PCI bus.
+ * @dev: ACPI device to add the notifier for.
+ * @pci_bus: PCI bus to walk checking for PME status if an event is signaled.
+ */
+acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev,
+					 struct pci_bus *pci_bus)
+{
+	return add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus);
+}
+
+/**
+ * pci_acpi_remove_bus_pm_notifier - Unregister PCI bus PM notifier.
+ * @dev: ACPI device to remove the notifier from.
+ */
+acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev)
+{
+	return remove_pm_notifier(dev, pci_acpi_wake_bus);
+}
+
+/**
+ * pci_acpi_add_pm_notifier - Register PM notifier for given PCI device.
+ * @dev: ACPI device to add the notifier for.
+ * @pci_dev: PCI device to check for the PME status if an event is signaled.
+ */
+acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
+				     struct pci_dev *pci_dev)
+{
+	return add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev);
+}
+
+/**
+ * pci_acpi_remove_pm_notifier - Unregister PCI device PM notifier.
+ * @dev: ACPI device to remove the notifier from.
+ */
+acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
+{
+	return remove_pm_notifier(dev, pci_acpi_wake_dev);
+}
+
 /*
  * _SxD returns the D-state with the highest power
  * (lowest D-state number) supported in the S-state "x".
@@ -131,19 +267,94 @@ static int acpi_pci_sleep_wake(struct pc
 	return 0;
 }
 
+/**
+ * acpi_dev_run_wake - Enable/disable wake-up for given device.
+ * @phys_dev: Device to enable/disable the platform to wake-up the system for.
+ * @enable: Whether enable or disable the wake-up functionality.
+ *
+ * Find the ACPI device object corresponding to @pci_dev and try to
+ * enable/disable the GPE associated with it.
+ */
+static int acpi_dev_run_wake(struct device *phys_dev, bool enable)
+{
+	struct acpi_device *dev;
+	acpi_handle handle;
+	int error = -ENODEV;
+
+	if (!device_run_wake(phys_dev))
+		return -EINVAL;
+
+	handle = DEVICE_ACPI_HANDLE(phys_dev);
+	if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) {
+		dev_dbg(phys_dev, "ACPI handle has no context in %s!\n",
+			__func__);
+		return -ENODEV;
+	}
+
+	if (enable) {
+		if (!dev->wakeup.run_wake_count++) {
+			acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0);
+			acpi_enable_gpe(dev->wakeup.gpe_device,
+					dev->wakeup.gpe_number,
+					ACPI_GPE_TYPE_RUNTIME);
+		}
+	} else if (dev->wakeup.run_wake_count > 0) {
+		if (!--dev->wakeup.run_wake_count) {
+			acpi_disable_gpe(dev->wakeup.gpe_device,
+					 dev->wakeup.gpe_number,
+					 ACPI_GPE_TYPE_RUNTIME);
+			acpi_disable_wakeup_device_power(dev);
+		}
+	} else {
+		error = -EALREADY;
+	}
+
+	return error;
+}
+
+static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable)
+{
+	while (bus->parent) {
+		struct pci_dev *bridge = bus->self;
+
+		if (bridge->pme_interrupt)
+			return;
+		if (!acpi_dev_run_wake(&bridge->dev, enable))
+			return;
+		bus = bus->parent;
+	}
+
+	/* We have reached the root bus. */
+	if (bus->bridge)
+		acpi_dev_run_wake(bus->bridge, enable);
+}
+
+static int acpi_pci_run_wake(struct pci_dev *dev, bool enable)
+{
+	if (dev->pme_interrupt)
+		return 0;
+
+	if (!acpi_dev_run_wake(&dev->dev, enable))
+		return 0;
+
+	acpi_pci_propagate_run_wake(dev->bus, enable);
+	return 0;
+}
+
 static struct pci_platform_pm_ops acpi_pci_platform_pm = {
 	.is_manageable = acpi_pci_power_manageable,
 	.set_state = acpi_pci_set_power_state,
 	.choose_state = acpi_pci_choose_state,
 	.can_wakeup = acpi_pci_can_wakeup,
 	.sleep_wake = acpi_pci_sleep_wake,
+	.run_wake = acpi_pci_run_wake,
 };
 
 /* ACPI bus type */
 static int acpi_pci_find_device(struct device *dev, acpi_handle *handle)
 {
 	struct pci_dev * pci_dev;
-	acpi_integer	addr;
+	u64	addr;
 
 	pci_dev = to_pci_dev(dev);
 	/* Please ref to ACPI spec for the syntax of _ADR */
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pci.c linux-libre-2.6.34-gnu1/drivers/pci/pci.c
--- linux-libre-2.6.33-gnu1/drivers/pci/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pm.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
@@ -19,8 +20,8 @@
 #include <linux/pci-aspm.h>
 #include <linux/pm_wakeup.h>
 #include <linux/interrupt.h>
-#include <asm/dma.h>	/* isa_dma_bridge_buggy */
 #include <linux/device.h>
+#include <linux/pm_runtime.h>
 #include <asm/setup.h>
 #include "pci.h"
 
@@ -29,6 +30,12 @@ const char *pci_power_names[] = {
 };
 EXPORT_SYMBOL_GPL(pci_power_names);
 
+int isa_dma_bridge_buggy;
+EXPORT_SYMBOL(isa_dma_bridge_buggy);
+
+int pci_pci_problems;
+EXPORT_SYMBOL(pci_pci_problems);
+
 unsigned int pci_pm_d3_delay;
 
 static void pci_dev_d3_sleep(struct pci_dev *dev)
@@ -297,6 +304,49 @@ int pci_find_ext_capability(struct pci_d
 }
 EXPORT_SYMBOL_GPL(pci_find_ext_capability);
 
+/**
+ * pci_bus_find_ext_capability - find an extended capability
+ * @bus:   the PCI bus to query
+ * @devfn: PCI device to query
+ * @cap:   capability code
+ *
+ * Like pci_find_ext_capability() but works for pci devices that do not have a
+ * pci_dev structure set up yet.
+ *
+ * Returns the address of the requested capability structure within the
+ * device's PCI configuration space or 0 in case the device does not
+ * support it.
+ */
+int pci_bus_find_ext_capability(struct pci_bus *bus, unsigned int devfn,
+				int cap)
+{
+	u32 header;
+	int ttl;
+	int pos = PCI_CFG_SPACE_SIZE;
+
+	/* minimum 8 bytes per capability */
+	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
+
+	if (!pci_bus_read_config_dword(bus, devfn, pos, &header))
+		return 0;
+	if (header == 0xffffffff || header == 0)
+		return 0;
+
+	while (ttl-- > 0) {
+		if (PCI_EXT_CAP_ID(header) == cap)
+			return pos;
+
+		pos = PCI_EXT_CAP_NEXT(header);
+		if (pos < PCI_CFG_SPACE_SIZE)
+			break;
+
+		if (!pci_bus_read_config_dword(bus, devfn, pos, &header))
+			break;
+	}
+
+	return 0;
+}
+
 static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap)
 {
 	int rc, ttl = PCI_FIND_CAP_TTL;
@@ -380,10 +430,9 @@ pci_find_parent_resource(const struct pc
 {
 	const struct pci_bus *bus = dev->bus;
 	int i;
-	struct resource *best = NULL;
+	struct resource *best = NULL, *r;
 
-	for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
-		struct resource *r = bus->resource[i];
+	pci_bus_for_each_resource(bus, r, i) {
 		if (!r)
 			continue;
 		if (res->start && !(res->start >= r->start && res->end <= r->end))
@@ -457,6 +506,12 @@ static inline int platform_pci_sleep_wak
 			pci_platform_pm->sleep_wake(dev, enable) : -ENODEV;
 }
 
+static inline int platform_pci_run_wake(struct pci_dev *dev, bool enable)
+{
+	return pci_platform_pm ?
+			pci_platform_pm->run_wake(dev, enable) : -ENODEV;
+}
+
 /**
  * pci_raw_set_power_state - Use PCI PM registers to set the power state of
  *                           given PCI device
@@ -624,7 +679,7 @@ static void __pci_start_power_transition
  */
 int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state)
 {
-	return state > PCI_D0 ?
+	return state >= PCI_D0 ?
 			pci_platform_power_transition(dev, state) : -EINVAL;
 }
 EXPORT_SYMBOL_GPL(__pci_complete_power_transition);
@@ -661,10 +716,6 @@ int pci_set_power_state(struct pci_dev *
 		 */
 		return 0;
 
-	/* 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
@@ -1190,6 +1241,66 @@ int pci_set_pcie_reset_state(struct pci_
 }
 
 /**
+ * pci_check_pme_status - Check if given device has generated PME.
+ * @dev: Device to check.
+ *
+ * Check the PME status of the device and if set, clear it and clear PME enable
+ * (if set).  Return 'true' if PME status and PME enable were both set or
+ * 'false' otherwise.
+ */
+bool pci_check_pme_status(struct pci_dev *dev)
+{
+	int pmcsr_pos;
+	u16 pmcsr;
+	bool ret = false;
+
+	if (!dev->pm_cap)
+		return false;
+
+	pmcsr_pos = dev->pm_cap + PCI_PM_CTRL;
+	pci_read_config_word(dev, pmcsr_pos, &pmcsr);
+	if (!(pmcsr & PCI_PM_CTRL_PME_STATUS))
+		return false;
+
+	/* Clear PME status. */
+	pmcsr |= PCI_PM_CTRL_PME_STATUS;
+	if (pmcsr & PCI_PM_CTRL_PME_ENABLE) {
+		/* Disable PME to avoid interrupt flood. */
+		pmcsr &= ~PCI_PM_CTRL_PME_ENABLE;
+		ret = true;
+	}
+
+	pci_write_config_word(dev, pmcsr_pos, pmcsr);
+
+	return ret;
+}
+
+/**
+ * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set.
+ * @dev: Device to handle.
+ * @ign: Ignored.
+ *
+ * Check if @dev has generated PME and queue a resume request for it in that
+ * case.
+ */
+static int pci_pme_wakeup(struct pci_dev *dev, void *ign)
+{
+	if (pci_check_pme_status(dev))
+		pm_request_resume(&dev->dev);
+	return 0;
+}
+
+/**
+ * pci_pme_wakeup_bus - Walk given bus and wake up devices on it, if necessary.
+ * @bus: Top bus of the subtree to walk.
+ */
+void pci_pme_wakeup_bus(struct pci_bus *bus)
+{
+	if (bus)
+		pci_walk_bus(bus, pci_pme_wakeup, NULL);
+}
+
+/**
  * pci_pme_capable - check the capability of PCI device to generate PME#
  * @dev: PCI device to handle.
  * @state: PCI state from which device will issue PME#.
@@ -1230,9 +1341,10 @@ void pci_pme_active(struct pci_dev *dev,
 }
 
 /**
- * pci_enable_wake - enable PCI device as wakeup event source
+ * __pci_enable_wake - enable PCI device as wakeup event source
  * @dev: PCI device affected
  * @state: PCI state from which device will issue wakeup events
+ * @runtime: True if the events are to be generated at run time
  * @enable: True to enable event generation; false to disable
  *
  * This enables the device as a wakeup event source, or disables it.
@@ -1248,11 +1360,12 @@ void pci_pme_active(struct pci_dev *dev,
  * Error code depending on the platform is returned if both the platform and
  * the native mechanism fail to enable the generation of wake-up events
  */
-int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable)
+int __pci_enable_wake(struct pci_dev *dev, pci_power_t state,
+		      bool runtime, bool enable)
 {
 	int ret = 0;
 
-	if (enable && !device_may_wakeup(&dev->dev))
+	if (enable && !runtime && !device_may_wakeup(&dev->dev))
 		return -EINVAL;
 
 	/* Don't do the same thing twice in a row for one device. */
@@ -1272,19 +1385,24 @@ int pci_enable_wake(struct pci_dev *dev,
 			pci_pme_active(dev, true);
 		else
 			ret = 1;
-		error = platform_pci_sleep_wake(dev, true);
+		error = runtime ? platform_pci_run_wake(dev, true) :
+					platform_pci_sleep_wake(dev, true);
 		if (ret)
 			ret = error;
 		if (!ret)
 			dev->wakeup_prepared = true;
 	} else {
-		platform_pci_sleep_wake(dev, false);
+		if (runtime)
+			platform_pci_run_wake(dev, false);
+		else
+			platform_pci_sleep_wake(dev, false);
 		pci_pme_active(dev, false);
 		dev->wakeup_prepared = false;
 	}
 
 	return ret;
 }
+EXPORT_SYMBOL(__pci_enable_wake);
 
 /**
  * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold
@@ -1394,6 +1512,66 @@ int pci_back_from_sleep(struct pci_dev *
 }
 
 /**
+ * pci_finish_runtime_suspend - Carry out PCI-specific part of runtime suspend.
+ * @dev: PCI device being suspended.
+ *
+ * Prepare @dev to generate wake-up events at run time and put it into a low
+ * power state.
+ */
+int pci_finish_runtime_suspend(struct pci_dev *dev)
+{
+	pci_power_t target_state = pci_target_state(dev);
+	int error;
+
+	if (target_state == PCI_POWER_ERROR)
+		return -EIO;
+
+	__pci_enable_wake(dev, target_state, true, pci_dev_run_wake(dev));
+
+	error = pci_set_power_state(dev, target_state);
+
+	if (error)
+		__pci_enable_wake(dev, target_state, true, false);
+
+	return error;
+}
+
+/**
+ * pci_dev_run_wake - Check if device can generate run-time wake-up events.
+ * @dev: Device to check.
+ *
+ * Return true if the device itself is cabable of generating wake-up events
+ * (through the platform or using the native PCIe PME) or if the device supports
+ * PME and one of its upstream bridges can generate wake-up events.
+ */
+bool pci_dev_run_wake(struct pci_dev *dev)
+{
+	struct pci_bus *bus = dev->bus;
+
+	if (device_run_wake(&dev->dev))
+		return true;
+
+	if (!dev->pme_support)
+		return false;
+
+	while (bus->parent) {
+		struct pci_dev *bridge = bus->self;
+
+		if (device_run_wake(&bridge->dev))
+			return true;
+
+		bus = bus->parent;
+	}
+
+	/* We have reached the root bus. */
+	if (bus->bridge)
+		return device_run_wake(bus->bridge);
+
+	return false;
+}
+EXPORT_SYMBOL_GPL(pci_dev_run_wake);
+
+/**
  * pci_pm_init - Initialize PM functions of given PCI device
  * @dev: PCI device to handle.
  */
@@ -1402,7 +1580,10 @@ void pci_pm_init(struct pci_dev *dev)
 	int pm;
 	u16 pmc;
 
+	pm_runtime_forbid(&dev->dev);
+	device_enable_async_suspend(&dev->dev);
 	dev->wakeup_prepared = false;
+
 	dev->pm_cap = 0;
 
 	/* find PCI PM capability in list */
@@ -2114,35 +2295,6 @@ void pci_msi_off(struct pci_dev *dev)
 	}
 }
 
-#ifndef HAVE_ARCH_PCI_SET_DMA_MASK
-/*
- * These can be overridden by arch-specific implementations
- */
-int
-pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
-	if (!pci_dma_supported(dev, mask))
-		return -EIO;
-
-	dev->dma_mask = mask;
-	dev_dbg(&dev->dev, "using %dbit DMA mask\n", fls64(mask));
-
-	return 0;
-}
-    
-int
-pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
-	if (!pci_dma_supported(dev, mask))
-		return -EIO;
-
-	dev->dev.coherent_dma_mask = mask;
-	dev_dbg(&dev->dev, "using %dbit consistent DMA mask\n", fls64(mask));
-
-	return 0;
-}
-#endif
-
 #ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE
 int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size)
 {
@@ -2304,7 +2456,7 @@ static int pci_dev_reset(struct pci_dev
 	if (!probe) {
 		pci_block_user_cfg_access(dev);
 		/* block PM suspend, driver probe, etc. */
-		down(&dev->dev.sem);
+		device_lock(&dev->dev);
 	}
 
 	rc = pci_dev_specific_reset(dev, probe);
@@ -2326,7 +2478,7 @@ static int pci_dev_reset(struct pci_dev
 	rc = pci_parent_bus_reset(dev, probe);
 done:
 	if (!probe) {
-		up(&dev->dev.sem);
+		device_unlock(&dev->dev);
 		pci_unblock_user_cfg_access(dev);
 	}
 
@@ -2421,18 +2573,17 @@ EXPORT_SYMBOL_GPL(pci_reset_function);
  */
 int pcix_get_max_mmrbc(struct pci_dev *dev)
 {
-	int err, cap;
+	int cap;
 	u32 stat;
 
 	cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
 	if (!cap)
 		return -EINVAL;
 
-	err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat);
-	if (err)
+	if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat))
 		return -EINVAL;
 
-	return (stat & PCI_X_STATUS_MAX_READ) >> 12;
+	return 512 << ((stat & PCI_X_STATUS_MAX_READ) >> 21);
 }
 EXPORT_SYMBOL(pcix_get_max_mmrbc);
 
@@ -2445,18 +2596,17 @@ EXPORT_SYMBOL(pcix_get_max_mmrbc);
  */
 int pcix_get_mmrbc(struct pci_dev *dev)
 {
-	int ret, cap;
-	u32 cmd;
+	int cap;
+	u16 cmd;
 
 	cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
 	if (!cap)
 		return -EINVAL;
 
-	ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd);
-	if (!ret)
-		ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2);
+	if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd))
+		return -EINVAL;
 
-	return ret;
+	return 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2);
 }
 EXPORT_SYMBOL(pcix_get_mmrbc);
 
@@ -2471,28 +2621,27 @@ EXPORT_SYMBOL(pcix_get_mmrbc);
  */
 int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc)
 {
-	int cap, err = -EINVAL;
-	u32 stat, cmd, v, o;
+	int cap;
+	u32 stat, v, o;
+	u16 cmd;
 
 	if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc))
-		goto out;
+		return -EINVAL;
 
 	v = ffs(mmrbc) - 10;
 
 	cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
 	if (!cap)
-		goto out;
+		return -EINVAL;
 
-	err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat);
-	if (err)
-		goto out;
+	if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat))
+		return -EINVAL;
 
 	if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21)
 		return -E2BIG;
 
-	err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd);
-	if (err)
-		goto out;
+	if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd))
+		return -EINVAL;
 
 	o = (cmd & PCI_X_CMD_MAX_READ) >> 2;
 	if (o != v) {
@@ -2502,10 +2651,10 @@ int pcix_set_mmrbc(struct pci_dev *dev,
 
 		cmd &= ~PCI_X_CMD_MAX_READ;
 		cmd |= v << 2;
-		err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd);
+		if (pci_write_config_word(dev, cap + PCI_X_CMD, cmd))
+			return -EIO;
 	}
-out:
-	return err;
+	return 0;
 }
 EXPORT_SYMBOL(pcix_set_mmrbc);
 
@@ -2615,6 +2764,23 @@ int pci_resource_bar(struct pci_dev *dev
 	return 0;
 }
 
+/* Some architectures require additional programming to enable VGA */
+static arch_set_vga_state_t arch_set_vga_state;
+
+void __init pci_register_set_vga_state(arch_set_vga_state_t func)
+{
+	arch_set_vga_state = func;	/* NULL disables */
+}
+
+static int pci_set_vga_state_arch(struct pci_dev *dev, bool decode,
+		      unsigned int command_bits, bool change_bridge)
+{
+	if (arch_set_vga_state)
+		return arch_set_vga_state(dev, decode, command_bits,
+						change_bridge);
+	return 0;
+}
+
 /**
  * pci_set_vga_state - set VGA decode state on device and parents if requested
  * @dev: the PCI device
@@ -2628,9 +2794,15 @@ int pci_set_vga_state(struct pci_dev *de
 	struct pci_bus *bus;
 	struct pci_dev *bridge;
 	u16 cmd;
+	int rc;
 
 	WARN_ON(command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY));
 
+	/* ARCH specific VGA enables */
+	rc = pci_set_vga_state_arch(dev, decode, command_bits, change_bridge);
+	if (rc)
+		return rc;
+
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	if (decode == true)
 		cmd |= command_bits;
@@ -2860,8 +3032,6 @@ EXPORT_SYMBOL(pci_set_mwi);
 EXPORT_SYMBOL(pci_try_set_mwi);
 EXPORT_SYMBOL(pci_clear_mwi);
 EXPORT_SYMBOL_GPL(pci_intx);
-EXPORT_SYMBOL(pci_set_dma_mask);
-EXPORT_SYMBOL(pci_set_consistent_dma_mask);
 EXPORT_SYMBOL(pci_assign_resource);
 EXPORT_SYMBOL(pci_find_parent_resource);
 EXPORT_SYMBOL(pci_select_bars);
@@ -2871,10 +3041,8 @@ EXPORT_SYMBOL(pci_save_state);
 EXPORT_SYMBOL(pci_restore_state);
 EXPORT_SYMBOL(pci_pme_capable);
 EXPORT_SYMBOL(pci_pme_active);
-EXPORT_SYMBOL(pci_enable_wake);
 EXPORT_SYMBOL(pci_wake_from_d3);
 EXPORT_SYMBOL(pci_target_state);
 EXPORT_SYMBOL(pci_prepare_to_sleep);
 EXPORT_SYMBOL(pci_back_from_sleep);
 EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state);
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pci-driver.c linux-libre-2.6.34-gnu1/drivers/pci/pci-driver.c
--- linux-libre-2.6.33-gnu1/drivers/pci/pci-driver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pci-driver.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/cpu.h>
+#include <linux/pm_runtime.h>
 #include "pci.h"
 
 struct pci_dynid {
@@ -404,6 +405,35 @@ static void pci_device_shutdown(struct d
 	pci_msix_shutdown(pci_dev);
 }
 
+#ifdef CONFIG_PM_OPS
+
+/* Auxiliary functions used for system resume and run-time resume. */
+
+/**
+ * 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_restore_state(pci_dev);
+}
+
+static void pci_pm_default_resume_early(struct pci_dev *pci_dev)
+{
+	pci_restore_standard_config(pci_dev);
+	pci_fixup_device(pci_fixup_resume_early, pci_dev);
+}
+
+#endif
+
 #ifdef CONFIG_PM_SLEEP
 
 /*
@@ -520,29 +550,6 @@ 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_restore_state(pci_dev);
-}
-
-static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
-{
-	pci_restore_standard_config(pci_dev);
-	pci_fixup_device(pci_fixup_resume_early, pci_dev);
-}
-
 static void pci_pm_default_resume(struct pci_dev *pci_dev)
 {
 	pci_fixup_device(pci_fixup_resume, pci_dev);
@@ -581,6 +588,17 @@ static int pci_pm_prepare(struct device
 	struct device_driver *drv = dev->driver;
 	int error = 0;
 
+	/*
+	 * PCI devices suspended at run time need to be resumed at this
+	 * point, because in general it is necessary to reconfigure them for
+	 * system suspend.  Namely, if the device is supposed to wake up the
+	 * system from the sleep state, we may need to reconfigure it for this
+	 * purpose.  In turn, if the device is not supposed to wake up the
+	 * system from the sleep state, we'll have to prevent it from signaling
+	 * wake-up.
+	 */
+	pm_runtime_resume(dev);
+
 	if (drv && drv->pm && drv->pm->prepare)
 		error = drv->pm->prepare(dev);
 
@@ -595,6 +613,13 @@ static void pci_pm_complete(struct devic
 		drv->pm->complete(dev);
 }
 
+#else /* !CONFIG_PM_SLEEP */
+
+#define pci_pm_prepare	NULL
+#define pci_pm_complete	NULL
+
+#endif /* !CONFIG_PM_SLEEP */
+
 #ifdef CONFIG_SUSPEND
 
 static int pci_pm_suspend(struct device *dev)
@@ -681,7 +706,7 @@ static int pci_pm_resume_noirq(struct de
 	struct device_driver *drv = dev->driver;
 	int error = 0;
 
-	pci_pm_default_resume_noirq(pci_dev);
+	pci_pm_default_resume_early(pci_dev);
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_resume_early(dev);
@@ -879,7 +904,7 @@ static int pci_pm_restore_noirq(struct d
 	struct device_driver *drv = dev->driver;
 	int error = 0;
 
-	pci_pm_default_resume_noirq(pci_dev);
+	pci_pm_default_resume_early(pci_dev);
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_resume_early(dev);
@@ -931,6 +956,84 @@ static int pci_pm_restore(struct device
 
 #endif /* !CONFIG_HIBERNATION */
 
+#ifdef CONFIG_PM_RUNTIME
+
+static int pci_pm_runtime_suspend(struct device *dev)
+{
+	struct pci_dev *pci_dev = to_pci_dev(dev);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	pci_power_t prev = pci_dev->current_state;
+	int error;
+
+	if (!pm || !pm->runtime_suspend)
+		return -ENOSYS;
+
+	error = pm->runtime_suspend(dev);
+	suspend_report_result(pm->runtime_suspend, error);
+	if (error)
+		return error;
+
+	pci_fixup_device(pci_fixup_suspend, pci_dev);
+
+	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->runtime_suspend);
+		return 0;
+	}
+
+	if (!pci_dev->state_saved)
+		pci_save_state(pci_dev);
+
+	pci_finish_runtime_suspend(pci_dev);
+
+	return 0;
+}
+
+static int pci_pm_runtime_resume(struct device *dev)
+{
+	struct pci_dev *pci_dev = to_pci_dev(dev);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	if (!pm || !pm->runtime_resume)
+		return -ENOSYS;
+
+	pci_pm_default_resume_early(pci_dev);
+	__pci_enable_wake(pci_dev, PCI_D0, true, false);
+	pci_fixup_device(pci_fixup_resume, pci_dev);
+
+	return pm->runtime_resume(dev);
+}
+
+static int pci_pm_runtime_idle(struct device *dev)
+{
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	if (!pm)
+		return -ENOSYS;
+
+	if (pm->runtime_idle) {
+		int ret = pm->runtime_idle(dev);
+		if (ret)
+			return ret;
+	}
+
+	pm_runtime_suspend(dev);
+
+	return 0;
+}
+
+#else /* !CONFIG_PM_RUNTIME */
+
+#define pci_pm_runtime_suspend	NULL
+#define pci_pm_runtime_resume	NULL
+#define pci_pm_runtime_idle	NULL
+
+#endif /* !CONFIG_PM_RUNTIME */
+
+#ifdef CONFIG_PM_OPS
+
 const struct dev_pm_ops pci_dev_pm_ops = {
 	.prepare = pci_pm_prepare,
 	.complete = pci_pm_complete,
@@ -946,15 +1049,18 @@ const struct dev_pm_ops pci_dev_pm_ops =
 	.thaw_noirq = pci_pm_thaw_noirq,
 	.poweroff_noirq = pci_pm_poweroff_noirq,
 	.restore_noirq = pci_pm_restore_noirq,
+	.runtime_suspend = pci_pm_runtime_suspend,
+	.runtime_resume = pci_pm_runtime_resume,
+	.runtime_idle = pci_pm_runtime_idle,
 };
 
 #define PCI_PM_OPS_PTR	(&pci_dev_pm_ops)
 
-#else /* !CONFIG_PM_SLEEP */
+#else /* !COMFIG_PM_OPS */
 
 #define PCI_PM_OPS_PTR	NULL
 
-#endif /* !CONFIG_PM_SLEEP */
+#endif /* !COMFIG_PM_OPS */
 
 /**
  * __pci_register_driver - register a new pci driver
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aerdrv.c linux-libre-2.6.34-gnu1/drivers/pci/pcie/aer/aerdrv.c
--- linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aerdrv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pcie/aer/aerdrv.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/pcieport_if.h>
+#include <linux/slab.h>
 
 #include "aerdrv.h"
 #include "../../pci.h"
@@ -243,11 +244,17 @@ static pci_ers_result_t aer_root_reset(s
 
 	/* Assert Secondary Bus Reset */
 	pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &p2p_ctrl);
-	p2p_ctrl |= PCI_CB_BRIDGE_CTL_CB_RESET;
+	p2p_ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
 	pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl);
 
+	/*
+	 * we should send hot reset message for 2ms to allow it time to
+	 * propogate to all downstream ports
+	 */
+	msleep(2);
+
 	/* De-assert Secondary Bus Reset */
-	p2p_ctrl &= ~PCI_CB_BRIDGE_CTL_CB_RESET;
+	p2p_ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
 	pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl);
 
 	/*
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aerdrv_core.c linux-libre-2.6.34-gnu1/drivers/pci/pcie/aer/aerdrv_core.c
--- linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aerdrv_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pcie/aer/aerdrv_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/pm.h>
 #include <linux/suspend.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include "aerdrv.h"
 
 static int forceload;
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aer_inject.c linux-libre-2.6.34-gnu1/drivers/pci/pcie/aer/aer_inject.c
--- linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aer_inject.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pcie/aer/aer_inject.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/uaccess.h>
 #include <linux/stddef.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pcie/Kconfig linux-libre-2.6.34-gnu1/drivers/pci/pcie/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/pci/pcie/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pcie/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -46,3 +46,7 @@ config PCIEASPM_DEBUG
 	help
 	  This enables PCI Express ASPM debug support. It will add per-device
 	  interface to control ASPM.
+
+config PCIE_PME
+	def_bool y
+	depends on PCIEPORTBUS && PM_RUNTIME && EXPERIMENTAL && ACPI
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pcie/Makefile linux-libre-2.6.34-gnu1/drivers/pci/pcie/Makefile
--- linux-libre-2.6.33-gnu1/drivers/pci/pcie/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pcie/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -11,3 +11,5 @@ obj-$(CONFIG_PCIEPORTBUS)	+= pcieportdrv
 
 # Build PCI Express AER if needed
 obj-$(CONFIG_PCIEAER)		+= aer/
+
+obj-$(CONFIG_PCIE_PME) += pme/
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pcie/pme/Makefile linux-libre-2.6.34-gnu1/drivers/pci/pcie/pme/Makefile
--- linux-libre-2.6.33-gnu1/drivers/pci/pcie/pme/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pcie/pme/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,8 @@
+#
+# Makefile for PCI-Express Root Port PME signaling driver
+#
+
+obj-$(CONFIG_PCIE_PME) += pmedriver.o
+
+pmedriver-objs := pcie_pme.o
+pmedriver-$(CONFIG_ACPI) += pcie_pme_acpi.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pcie/pme/pcie_pme_acpi.c linux-libre-2.6.34-gnu1/drivers/pci/pcie/pme/pcie_pme_acpi.c
--- linux-libre-2.6.33-gnu1/drivers/pci/pcie/pme/pcie_pme_acpi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pcie/pme/pcie_pme_acpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,54 @@
+/*
+ * PCIe Native PME support, ACPI-related part
+ *
+ * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
+ *
+ * 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.
+ */
+
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/acpi.h>
+#include <linux/pci-acpi.h>
+#include <linux/pcieport_if.h>
+
+/**
+ * pcie_pme_acpi_setup - Request the ACPI BIOS to release control over PCIe PME.
+ * @srv - PCIe PME service for a root port or event collector.
+ *
+ * Invoked when the PCIe bus type loads PCIe PME service driver.  To avoid
+ * conflict with the BIOS PCIe support requires the BIOS to yield PCIe PME
+ * control to the kernel.
+ */
+int pcie_pme_acpi_setup(struct pcie_device *srv)
+{
+	acpi_status status = AE_NOT_FOUND;
+	struct pci_dev *port = srv->port;
+	acpi_handle handle;
+	int error = 0;
+
+	if (acpi_pci_disabled)
+		return -ENOSYS;
+
+	dev_info(&port->dev, "Requesting control of PCIe PME from ACPI BIOS\n");
+
+	handle = acpi_find_root_bridge_handle(port);
+	if (!handle)
+		return -EINVAL;
+
+	status = acpi_pci_osc_control_set(handle,
+			OSC_PCI_EXPRESS_PME_CONTROL |
+			OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
+	if (ACPI_FAILURE(status)) {
+		dev_info(&port->dev,
+			"Failed to receive control of PCIe PME service: %s\n",
+			(status == AE_SUPPORT || status == AE_NOT_FOUND) ?
+			"no _OSC support" : "ACPI _OSC failed");
+		error = -ENODEV;
+	}
+
+	return error;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pcie/pme/pcie_pme.c linux-libre-2.6.34-gnu1/drivers/pci/pcie/pme/pcie_pme.c
--- linux-libre-2.6.33-gnu1/drivers/pci/pcie/pme/pcie_pme.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pcie/pme/pcie_pme.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,506 @@
+/*
+ * PCIe Native PME support
+ *
+ * Copyright (C) 2007 - 2009 Intel Corp
+ * Copyright (C) 2007 - 2009 Shaohua Li <shaohua.li@intel.com>
+ * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/pcieport_if.h>
+#include <linux/acpi.h>
+#include <linux/pci-acpi.h>
+#include <linux/pm_runtime.h>
+
+#include "../../pci.h"
+#include "pcie_pme.h"
+
+#define PCI_EXP_RTSTA_PME	0x10000 /* PME status */
+#define PCI_EXP_RTSTA_PENDING	0x20000 /* PME pending */
+
+/*
+ * If set, this switch will prevent the PCIe root port PME service driver from
+ * being registered.  Consequently, the interrupt-based PCIe PME signaling will
+ * not be used by any PCIe root ports in that case.
+ */
+static bool pcie_pme_disabled;
+
+/*
+ * The PCI Express Base Specification 2.0, Section 6.1.8, states the following:
+ * "In order to maintain compatibility with non-PCI Express-aware system
+ * software, system power management logic must be configured by firmware to use
+ * the legacy mechanism of signaling PME by default.  PCI Express-aware system
+ * software must notify the firmware prior to enabling native, interrupt-based
+ * PME signaling."  However, if the platform doesn't provide us with a suitable
+ * notification mechanism or the notification fails, it is not clear whether or
+ * not we are supposed to use the interrupt-based PCIe PME signaling.  The
+ * switch below can be used to indicate the desired behaviour.  When set, it
+ * will make the kernel use the interrupt-based PCIe PME signaling regardless of
+ * the platform notification status, although the kernel will attempt to notify
+ * the platform anyway.  When unset, it will prevent the kernel from using the
+ * the interrupt-based PCIe PME signaling if the platform notification fails,
+ * which is the default.
+ */
+static bool pcie_pme_force_enable;
+
+/*
+ * If this switch is set, MSI will not be used for PCIe PME signaling.  This
+ * causes the PCIe port driver to use INTx interrupts only, but it turns out
+ * that using MSI for PCIe PME signaling doesn't play well with PCIe PME-based
+ * wake-up from system sleep states.
+ */
+bool pcie_pme_msi_disabled;
+
+static int __init pcie_pme_setup(char *str)
+{
+	if (!strcmp(str, "off"))
+		pcie_pme_disabled = true;
+	else if (!strcmp(str, "force"))
+		pcie_pme_force_enable = true;
+	else if (!strcmp(str, "nomsi"))
+		pcie_pme_msi_disabled = true;
+	return 1;
+}
+__setup("pcie_pme=", pcie_pme_setup);
+
+/**
+ * pcie_pme_platform_setup - Ensure that the kernel controls the PCIe PME.
+ * @srv: PCIe PME root port service to use for carrying out the check.
+ *
+ * Notify the platform that the native PCIe PME is going to be used and return
+ * 'true' if the control of the PCIe PME registers has been acquired from the
+ * platform.
+ */
+static bool pcie_pme_platform_setup(struct pcie_device *srv)
+{
+	if (!pcie_pme_platform_notify(srv))
+		return true;
+	return pcie_pme_force_enable;
+}
+
+struct pcie_pme_service_data {
+	spinlock_t lock;
+	struct pcie_device *srv;
+	struct work_struct work;
+	bool noirq; /* Don't enable the PME interrupt used by this service. */
+};
+
+/**
+ * pcie_pme_interrupt_enable - Enable/disable PCIe PME interrupt generation.
+ * @dev: PCIe root port or event collector.
+ * @enable: Enable or disable the interrupt.
+ */
+static void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable)
+{
+	int rtctl_pos;
+	u16 rtctl;
+
+	rtctl_pos = pci_pcie_cap(dev) + PCI_EXP_RTCTL;
+
+	pci_read_config_word(dev, rtctl_pos, &rtctl);
+	if (enable)
+		rtctl |= PCI_EXP_RTCTL_PMEIE;
+	else
+		rtctl &= ~PCI_EXP_RTCTL_PMEIE;
+	pci_write_config_word(dev, rtctl_pos, rtctl);
+}
+
+/**
+ * pcie_pme_clear_status - Clear root port PME interrupt status.
+ * @dev: PCIe root port or event collector.
+ */
+static void pcie_pme_clear_status(struct pci_dev *dev)
+{
+	int rtsta_pos;
+	u32 rtsta;
+
+	rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA;
+
+	pci_read_config_dword(dev, rtsta_pos, &rtsta);
+	rtsta |= PCI_EXP_RTSTA_PME;
+	pci_write_config_dword(dev, rtsta_pos, rtsta);
+}
+
+/**
+ * pcie_pme_walk_bus - Scan a PCI bus for devices asserting PME#.
+ * @bus: PCI bus to scan.
+ *
+ * Scan given PCI bus and all buses under it for devices asserting PME#.
+ */
+static bool pcie_pme_walk_bus(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+	bool ret = false;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		/* Skip PCIe devices in case we started from a root port. */
+		if (!pci_is_pcie(dev) && pci_check_pme_status(dev)) {
+			pm_request_resume(&dev->dev);
+			ret = true;
+		}
+
+		if (dev->subordinate && pcie_pme_walk_bus(dev->subordinate))
+			ret = true;
+	}
+
+	return ret;
+}
+
+/**
+ * pcie_pme_from_pci_bridge - Check if PCIe-PCI bridge generated a PME.
+ * @bus: Secondary bus of the bridge.
+ * @devfn: Device/function number to check.
+ *
+ * PME from PCI devices under a PCIe-PCI bridge may be converted to an in-band
+ * PCIe PME message.  In such that case the bridge should use the Requester ID
+ * of device/function number 0 on its secondary bus.
+ */
+static bool pcie_pme_from_pci_bridge(struct pci_bus *bus, u8 devfn)
+{
+	struct pci_dev *dev;
+	bool found = false;
+
+	if (devfn)
+		return false;
+
+	dev = pci_dev_get(bus->self);
+	if (!dev)
+		return false;
+
+	if (pci_is_pcie(dev) && dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) {
+		down_read(&pci_bus_sem);
+		if (pcie_pme_walk_bus(bus))
+			found = true;
+		up_read(&pci_bus_sem);
+	}
+
+	pci_dev_put(dev);
+	return found;
+}
+
+/**
+ * pcie_pme_handle_request - Find device that generated PME and handle it.
+ * @port: Root port or event collector that generated the PME interrupt.
+ * @req_id: PCIe Requester ID of the device that generated the PME.
+ */
+static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id)
+{
+	u8 busnr = req_id >> 8, devfn = req_id & 0xff;
+	struct pci_bus *bus;
+	struct pci_dev *dev;
+	bool found = false;
+
+	/* First, check if the PME is from the root port itself. */
+	if (port->devfn == devfn && port->bus->number == busnr) {
+		if (pci_check_pme_status(port)) {
+			pm_request_resume(&port->dev);
+			found = true;
+		} else {
+			/*
+			 * Apparently, the root port generated the PME on behalf
+			 * of a non-PCIe device downstream.  If this is done by
+			 * a root port, the Requester ID field in its status
+			 * register may contain either the root port's, or the
+			 * source device's information (PCI Express Base
+			 * Specification, Rev. 2.0, Section 6.1.9).
+			 */
+			down_read(&pci_bus_sem);
+			found = pcie_pme_walk_bus(port->subordinate);
+			up_read(&pci_bus_sem);
+		}
+		goto out;
+	}
+
+	/* Second, find the bus the source device is on. */
+	bus = pci_find_bus(pci_domain_nr(port->bus), busnr);
+	if (!bus)
+		goto out;
+
+	/* Next, check if the PME is from a PCIe-PCI bridge. */
+	found = pcie_pme_from_pci_bridge(bus, devfn);
+	if (found)
+		goto out;
+
+	/* Finally, try to find the PME source on the bus. */
+	down_read(&pci_bus_sem);
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		pci_dev_get(dev);
+		if (dev->devfn == devfn) {
+			found = true;
+			break;
+		}
+		pci_dev_put(dev);
+	}
+	up_read(&pci_bus_sem);
+
+	if (found) {
+		/* The device is there, but we have to check its PME status. */
+		found = pci_check_pme_status(dev);
+		if (found)
+			pm_request_resume(&dev->dev);
+		pci_dev_put(dev);
+	} else if (devfn) {
+		/*
+		 * The device is not there, but we can still try to recover by
+		 * assuming that the PME was reported by a PCIe-PCI bridge that
+		 * used devfn different from zero.
+		 */
+		dev_dbg(&port->dev, "PME interrupt generated for "
+			"non-existent device %02x:%02x.%d\n",
+			busnr, PCI_SLOT(devfn), PCI_FUNC(devfn));
+		found = pcie_pme_from_pci_bridge(bus, 0);
+	}
+
+ out:
+	if (!found)
+		dev_dbg(&port->dev, "Spurious native PME interrupt!\n");
+}
+
+/**
+ * pcie_pme_work_fn - Work handler for PCIe PME interrupt.
+ * @work: Work structure giving access to service data.
+ */
+static void pcie_pme_work_fn(struct work_struct *work)
+{
+	struct pcie_pme_service_data *data =
+			container_of(work, struct pcie_pme_service_data, work);
+	struct pci_dev *port = data->srv->port;
+	int rtsta_pos;
+	u32 rtsta;
+
+	rtsta_pos = pci_pcie_cap(port) + PCI_EXP_RTSTA;
+
+	spin_lock_irq(&data->lock);
+
+	for (;;) {
+		if (data->noirq)
+			break;
+
+		pci_read_config_dword(port, rtsta_pos, &rtsta);
+		if (rtsta & PCI_EXP_RTSTA_PME) {
+			/*
+			 * Clear PME status of the port.  If there are other
+			 * pending PMEs, the status will be set again.
+			 */
+			pcie_pme_clear_status(port);
+
+			spin_unlock_irq(&data->lock);
+			pcie_pme_handle_request(port, rtsta & 0xffff);
+			spin_lock_irq(&data->lock);
+
+			continue;
+		}
+
+		/* No need to loop if there are no more PMEs pending. */
+		if (!(rtsta & PCI_EXP_RTSTA_PENDING))
+			break;
+
+		spin_unlock_irq(&data->lock);
+		cpu_relax();
+		spin_lock_irq(&data->lock);
+	}
+
+	if (!data->noirq)
+		pcie_pme_interrupt_enable(port, true);
+
+	spin_unlock_irq(&data->lock);
+}
+
+/**
+ * pcie_pme_irq - Interrupt handler for PCIe root port PME interrupt.
+ * @irq: Interrupt vector.
+ * @context: Interrupt context pointer.
+ */
+static irqreturn_t pcie_pme_irq(int irq, void *context)
+{
+	struct pci_dev *port;
+	struct pcie_pme_service_data *data;
+	int rtsta_pos;
+	u32 rtsta;
+	unsigned long flags;
+
+	port = ((struct pcie_device *)context)->port;
+	data = get_service_data((struct pcie_device *)context);
+
+	rtsta_pos = pci_pcie_cap(port) + PCI_EXP_RTSTA;
+
+	spin_lock_irqsave(&data->lock, flags);
+	pci_read_config_dword(port, rtsta_pos, &rtsta);
+
+	if (!(rtsta & PCI_EXP_RTSTA_PME)) {
+		spin_unlock_irqrestore(&data->lock, flags);
+		return IRQ_NONE;
+	}
+
+	pcie_pme_interrupt_enable(port, false);
+	spin_unlock_irqrestore(&data->lock, flags);
+
+	/* We don't use pm_wq, because it's freezable. */
+	schedule_work(&data->work);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * pcie_pme_set_native - Set the PME interrupt flag for given device.
+ * @dev: PCI device to handle.
+ * @ign: Ignored.
+ */
+static int pcie_pme_set_native(struct pci_dev *dev, void *ign)
+{
+	dev_info(&dev->dev, "Signaling PME through PCIe PME interrupt\n");
+
+	device_set_run_wake(&dev->dev, true);
+	dev->pme_interrupt = true;
+	return 0;
+}
+
+/**
+ * pcie_pme_mark_devices - Set the PME interrupt flag for devices below a port.
+ * @port: PCIe root port or event collector to handle.
+ *
+ * For each device below given root port, including the port itself (or for each
+ * root complex integrated endpoint if @port is a root complex event collector)
+ * set the flag indicating that it can signal run-time wake-up events via PCIe
+ * PME interrupts.
+ */
+static void pcie_pme_mark_devices(struct pci_dev *port)
+{
+	pcie_pme_set_native(port, NULL);
+	if (port->subordinate) {
+		pci_walk_bus(port->subordinate, pcie_pme_set_native, NULL);
+	} else {
+		struct pci_bus *bus = port->bus;
+		struct pci_dev *dev;
+
+		/* Check if this is a root port event collector. */
+		if (port->pcie_type != PCI_EXP_TYPE_RC_EC || !bus)
+			return;
+
+		down_read(&pci_bus_sem);
+		list_for_each_entry(dev, &bus->devices, bus_list)
+			if (pci_is_pcie(dev)
+			    && dev->pcie_type == PCI_EXP_TYPE_RC_END)
+				pcie_pme_set_native(dev, NULL);
+		up_read(&pci_bus_sem);
+	}
+}
+
+/**
+ * pcie_pme_probe - Initialize PCIe PME service for given root port.
+ * @srv: PCIe service to initialize.
+ */
+static int pcie_pme_probe(struct pcie_device *srv)
+{
+	struct pci_dev *port;
+	struct pcie_pme_service_data *data;
+	int ret;
+
+	if (!pcie_pme_platform_setup(srv))
+		return -EACCES;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	spin_lock_init(&data->lock);
+	INIT_WORK(&data->work, pcie_pme_work_fn);
+	data->srv = srv;
+	set_service_data(srv, data);
+
+	port = srv->port;
+	pcie_pme_interrupt_enable(port, false);
+	pcie_pme_clear_status(port);
+
+	ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv);
+	if (ret) {
+		kfree(data);
+	} else {
+		pcie_pme_mark_devices(port);
+		pcie_pme_interrupt_enable(port, true);
+	}
+
+	return ret;
+}
+
+/**
+ * pcie_pme_suspend - Suspend PCIe PME service device.
+ * @srv: PCIe service device to suspend.
+ */
+static int pcie_pme_suspend(struct pcie_device *srv)
+{
+	struct pcie_pme_service_data *data = get_service_data(srv);
+	struct pci_dev *port = srv->port;
+
+	spin_lock_irq(&data->lock);
+	pcie_pme_interrupt_enable(port, false);
+	pcie_pme_clear_status(port);
+	data->noirq = true;
+	spin_unlock_irq(&data->lock);
+
+	synchronize_irq(srv->irq);
+
+	return 0;
+}
+
+/**
+ * pcie_pme_resume - Resume PCIe PME service device.
+ * @srv - PCIe service device to resume.
+ */
+static int pcie_pme_resume(struct pcie_device *srv)
+{
+	struct pcie_pme_service_data *data = get_service_data(srv);
+	struct pci_dev *port = srv->port;
+
+	spin_lock_irq(&data->lock);
+	data->noirq = false;
+	pcie_pme_clear_status(port);
+	pcie_pme_interrupt_enable(port, true);
+	spin_unlock_irq(&data->lock);
+
+	return 0;
+}
+
+/**
+ * pcie_pme_remove - Prepare PCIe PME service device for removal.
+ * @srv - PCIe service device to resume.
+ */
+static void pcie_pme_remove(struct pcie_device *srv)
+{
+	pcie_pme_suspend(srv);
+	free_irq(srv->irq, srv);
+	kfree(get_service_data(srv));
+}
+
+static struct pcie_port_service_driver pcie_pme_driver = {
+	.name		= "pcie_pme",
+	.port_type 	= PCI_EXP_TYPE_ROOT_PORT,
+	.service 	= PCIE_PORT_SERVICE_PME,
+
+	.probe		= pcie_pme_probe,
+	.suspend	= pcie_pme_suspend,
+	.resume		= pcie_pme_resume,
+	.remove		= pcie_pme_remove,
+};
+
+/**
+ * pcie_pme_service_init - Register the PCIe PME service driver.
+ */
+static int __init pcie_pme_service_init(void)
+{
+	return pcie_pme_disabled ?
+		-ENODEV : pcie_port_service_register(&pcie_pme_driver);
+}
+
+module_init(pcie_pme_service_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pcie/pme/pcie_pme.h linux-libre-2.6.34-gnu1/drivers/pci/pcie/pme/pcie_pme.h
--- linux-libre-2.6.33-gnu1/drivers/pci/pcie/pme/pcie_pme.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pcie/pme/pcie_pme.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,28 @@
+/*
+ * drivers/pci/pcie/pme/pcie_pme.h
+ *
+ * PCI Express Root Port PME signaling support
+ *
+ * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
+ */
+
+#ifndef _PCIE_PME_H_
+#define _PCIE_PME_H_
+
+struct pcie_device;
+
+#ifdef CONFIG_ACPI
+extern int pcie_pme_acpi_setup(struct pcie_device *srv);
+
+static inline int pcie_pme_platform_notify(struct pcie_device *srv)
+{
+	return pcie_pme_acpi_setup(srv);
+}
+#else /* !CONFIG_ACPI */
+static inline int pcie_pme_platform_notify(struct pcie_device *srv)
+{
+	return 0;
+}
+#endif /* !CONFIG_ACPI */
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pcie/portdrv_core.c linux-libre-2.6.34-gnu1/drivers/pci/pcie/portdrv_core.c
--- linux-libre-2.6.33-gnu1/drivers/pci/pcie/portdrv_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pcie/portdrv_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -186,16 +186,24 @@ static int pcie_port_enable_msix(struct
  */
 static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask)
 {
-	int i, irq;
+	int i, irq = -1;
+
+	/* We have to use INTx if MSI cannot be used for PCIe PME. */
+	if ((mask & PCIE_PORT_SERVICE_PME) && pcie_pme_no_msi()) {
+		if (dev->pin)
+			irq = dev->irq;
+		goto no_msi;
+	}
 
 	/* Try to use MSI-X if supported */
 	if (!pcie_port_enable_msix(dev, irqs, mask))
 		return 0;
+
 	/* We're not going to use MSI-X, so try MSI and fall back to INTx */
-	irq = -1;
 	if (!pci_enable_msi(dev) || dev->pin)
 		irq = dev->irq;
 
+ no_msi:
 	for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
 		irqs[i] = irq;
 	irqs[PCIE_PORT_SERVICE_VC_SHIFT] = -1;
@@ -277,6 +285,7 @@ static int pcie_device_init(struct pci_d
 		     pci_name(pdev),
 		     get_descriptor_id(pdev->pcie_type, service));
 	device->parent = &pdev->dev;
+	device_enable_async_suspend(device);
 
 	retval = device_register(device);
 	if (retval)
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pcie/portdrv.h linux-libre-2.6.34-gnu1/drivers/pci/pcie/portdrv.h
--- linux-libre-2.6.33-gnu1/drivers/pci/pcie/portdrv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pcie/portdrv.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,4 +30,21 @@ extern void pcie_port_device_remove(stru
 extern int __must_check pcie_port_bus_register(void);
 extern void pcie_port_bus_unregister(void);
 
+#ifdef CONFIG_PCIE_PME
+extern bool pcie_pme_msi_disabled;
+
+static inline void pcie_pme_disable_msi(void)
+{
+	pcie_pme_msi_disabled = true;
+}
+
+static inline bool pcie_pme_no_msi(void)
+{
+	return pcie_pme_msi_disabled;
+}
+#else /* !CONFIG_PCIE_PME */
+static inline void pcie_pme_disable_msi(void) {}
+static inline bool pcie_pme_no_msi(void) { return false; }
+#endif /* !CONFIG_PCIE_PME */
+
 #endif /* _PORTDRV_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pcie/portdrv_pci.c linux-libre-2.6.34-gnu1/drivers/pci/pcie/portdrv_pci.c
--- linux-libre-2.6.33-gnu1/drivers/pci/pcie/portdrv_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pcie/portdrv_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,9 +12,9 @@
 #include <linux/errno.h>
 #include <linux/pm.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/pcieport_if.h>
 #include <linux/aer.h>
+#include <linux/dmi.h>
 
 #include "portdrv.h"
 #include "aer/aerdrv.h"
@@ -273,10 +273,36 @@ static struct pci_driver pcie_portdriver
 	.driver.pm 	= PCIE_PORTDRV_PM_OPS,
 };
 
+static int __init dmi_pcie_pme_disable_msi(const struct dmi_system_id *d)
+{
+	pr_notice("%s detected: will not use MSI for PCIe PME signaling\n",
+			d->ident);
+	pcie_pme_disable_msi();
+	return 0;
+}
+
+static struct dmi_system_id __initdata pcie_portdrv_dmi_table[] = {
+	/*
+	 * Boxes that should not use MSI for PCIe PME signaling.
+	 */
+	{
+	 .callback = dmi_pcie_pme_disable_msi,
+	 .ident = "MSI Wind U-100",
+	 .matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR,
+		     		"MICRO-STAR INTERNATIONAL CO., LTD"),
+		     DMI_MATCH(DMI_PRODUCT_NAME, "U-100"),
+		     },
+	 },
+	 {}
+};
+
 static int __init pcie_portdrv_init(void)
 {
 	int retval;
 
+	dmi_check_system(pcie_portdrv_dmi_table);
+
 	retval = pcie_port_bus_register();
 	if (retval) {
 		printk(KERN_WARNING "PCIE: bus_register error: %d\n", retval);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pci.h linux-libre-2.6.34-gnu1/drivers/pci/pci.h
--- linux-libre-2.6.33-gnu1/drivers/pci/pci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pci.h	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,10 @@ int pci_probe_reset_function(struct pci_
  *
  * @sleep_wake: enables/disables the system wake up capability of given device
  *
+ * @run_wake: enables/disables the platform to generate run-time wake-up events
+ *		for given device (the device's wake-up capability has to be
+ *		enabled by @sleep_wake for this feature to work)
+ *
  * If given platform is generally capable of power managing PCI devices, all of
  * these callbacks are mandatory.
  */
@@ -44,11 +48,16 @@ struct pci_platform_pm_ops {
 	pci_power_t (*choose_state)(struct pci_dev *dev);
 	bool (*can_wakeup)(struct pci_dev *dev);
 	int (*sleep_wake)(struct pci_dev *dev, bool enable);
+	int (*run_wake)(struct pci_dev *dev, bool enable);
 };
 
 extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops);
 extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state);
 extern void pci_disable_enabled_device(struct pci_dev *dev);
+extern bool pci_check_pme_status(struct pci_dev *dev);
+extern int pci_finish_runtime_suspend(struct pci_dev *dev);
+extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign);
+extern void pci_pme_wakeup_bus(struct pci_bus *bus);
 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);
@@ -319,6 +328,13 @@ struct pci_dev_reset_methods {
 	int (*reset)(struct pci_dev *dev, int probe);
 };
 
+#ifdef CONFIG_PCI_QUIRKS
 extern int pci_dev_specific_reset(struct pci_dev *dev, int probe);
+#else
+static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
+{
+	return -ENOTTY;
+}
+#endif
 
 #endif /* DRIVERS_PCI_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/pci-sysfs.c linux-libre-2.6.34-gnu1/drivers/pci/pci-sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/pci/pci-sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/pci-sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/mm.h>
 #include <linux/capability.h>
 #include <linux/pci-aspm.h>
+#include <linux/slab.h>
 #include "pci.h"
 
 static int sysfs_initialized;	/* = 0 */
@@ -642,6 +643,7 @@ void pci_create_legacy_files(struct pci_
 	if (!b->legacy_io)
 		goto kzalloc_err;
 
+	sysfs_bin_attr_init(b->legacy_io);
 	b->legacy_io->attr.name = "legacy_io";
 	b->legacy_io->size = 0xffff;
 	b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
@@ -655,6 +657,7 @@ void pci_create_legacy_files(struct pci_
 
 	/* Allocated above after the legacy_io struct */
 	b->legacy_mem = b->legacy_io + 1;
+	sysfs_bin_attr_init(b->legacy_mem);
 	b->legacy_mem->attr.name = "legacy_mem";
 	b->legacy_mem->size = 1024*1024;
 	b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
@@ -800,6 +803,7 @@ static int pci_create_attr(struct pci_de
 	if (res_attr) {
 		char *res_attr_name = (char *)(res_attr + 1);
 
+		sysfs_bin_attr_init(res_attr);
 		if (write_combine) {
 			pdev->res_attr_wc[num] = res_attr;
 			sprintf(res_attr_name, "resource%d_wc", num);
@@ -972,6 +976,7 @@ static int pci_create_capabilities_sysfs
 		if (!attr)
 			return -ENOMEM;
 
+		sysfs_bin_attr_init(attr);
 		attr->size = dev->vpd->len;
 		attr->attr.name = "vpd";
 		attr->attr.mode = S_IRUSR | S_IWUSR;
@@ -1038,6 +1043,7 @@ int __must_check pci_create_sysfs_dev_fi
 			retval = -ENOMEM;
 			goto err_resource_files;
 		}
+		sysfs_bin_attr_init(attr);
 		attr->size = rom_size;
 		attr->attr.name = "rom";
 		attr->attr.mode = S_IRUSR;
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/probe.c linux-libre-2.6.34-gnu1/drivers/pci/probe.c
--- linux-libre-2.6.33-gnu1/drivers/pci/probe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/probe.c	2010-05-16 17:17:36.000000000 -0400
@@ -89,6 +89,7 @@ static void release_pcibus_dev(struct de
 
 	if (pci_bus->bridge)
 		put_device(pci_bus->bridge);
+	pci_bus_remove_resources(pci_bus);
 	kfree(pci_bus);
 }
 
@@ -281,26 +282,12 @@ static void pci_read_bases(struct pci_de
 	}
 }
 
-void __devinit pci_read_bridge_bases(struct pci_bus *child)
+static void __devinit pci_read_bridge_io(struct pci_bus *child)
 {
 	struct pci_dev *dev = child->self;
 	u8 io_base_lo, io_limit_lo;
-	u16 mem_base_lo, mem_limit_lo;
 	unsigned long base, limit;
 	struct resource *res;
-	int i;
-
-	if (pci_is_root_bus(child))	/* It's a host bus, nothing to read */
-		return;
-
-	dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n",
-		 child->secondary, child->subordinate,
-		 dev->transparent ? " (subtractive decode)": "");
-
-	if (dev->transparent) {
-		for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
-			child->resource[i] = child->parent->resource[i - 3];
-	}
 
 	res = child->resource[0];
 	pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
@@ -316,26 +303,50 @@ void __devinit pci_read_bridge_bases(str
 		limit |= (io_limit_hi << 16);
 	}
 
-	if (base <= limit) {
+	if (base && base <= limit) {
 		res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
 		if (!res->start)
 			res->start = base;
 		if (!res->end)
 			res->end = limit + 0xfff;
 		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
+	} else {
+		dev_printk(KERN_DEBUG, &dev->dev,
+			 "  bridge window [io  %#06lx-%#06lx] (disabled)\n",
+				 base, limit);
 	}
+}
+
+static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
+{
+	struct pci_dev *dev = child->self;
+	u16 mem_base_lo, mem_limit_lo;
+	unsigned long base, limit;
+	struct resource *res;
 
 	res = child->resource[1];
 	pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo);
 	pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
 	base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16;
 	limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16;
-	if (base <= limit) {
+	if (base && base <= limit) {
 		res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
 		res->start = base;
 		res->end = limit + 0xfffff;
 		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
+	} else {
+		dev_printk(KERN_DEBUG, &dev->dev,
+			"  bridge window [mem %#010lx-%#010lx] (disabled)\n",
+					 base, limit + 0xfffff);
 	}
+}
+
+static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
+{
+	struct pci_dev *dev = child->self;
+	u16 mem_base_lo, mem_limit_lo;
+	unsigned long base, limit;
+	struct resource *res;
 
 	res = child->resource[2];
 	pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
@@ -366,7 +377,7 @@ void __devinit pci_read_bridge_bases(str
 #endif
 		}
 	}
-	if (base <= limit) {
+	if (base && base <= limit) {
 		res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) |
 					 IORESOURCE_MEM | IORESOURCE_PREFETCH;
 		if (res->flags & PCI_PREF_RANGE_TYPE_64)
@@ -374,6 +385,44 @@ void __devinit pci_read_bridge_bases(str
 		res->start = base;
 		res->end = limit + 0xfffff;
 		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
+	} else {
+		dev_printk(KERN_DEBUG, &dev->dev,
+		     "  bridge window [mem %#010lx-%#010lx pref] (disabled)\n",
+					 base, limit + 0xfffff);
+	}
+}
+
+void __devinit pci_read_bridge_bases(struct pci_bus *child)
+{
+	struct pci_dev *dev = child->self;
+	struct resource *res;
+	int i;
+
+	if (pci_is_root_bus(child))	/* It's a host bus, nothing to read */
+		return;
+
+	dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n",
+		 child->secondary, child->subordinate,
+		 dev->transparent ? " (subtractive decode)" : "");
+
+	pci_bus_remove_resources(child);
+	for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++)
+		child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
+
+	pci_read_bridge_io(child);
+	pci_read_bridge_mmio(child);
+	pci_read_bridge_mmio_pref(child);
+
+	if (dev->transparent) {
+		pci_bus_for_each_resource(child->parent, res, i) {
+			if (res) {
+				pci_bus_add_resource(child, res,
+						     PCI_SUBTRACTIVE_DECODE);
+				dev_printk(KERN_DEBUG, &dev->dev,
+					   "  bridge window %pR (subtractive decode)\n",
+					   res);
+			}
+		}
 	}
 }
 
@@ -387,10 +436,147 @@ static struct pci_bus * pci_alloc_bus(vo
 		INIT_LIST_HEAD(&b->children);
 		INIT_LIST_HEAD(&b->devices);
 		INIT_LIST_HEAD(&b->slots);
+		INIT_LIST_HEAD(&b->resources);
+		b->max_bus_speed = PCI_SPEED_UNKNOWN;
+		b->cur_bus_speed = PCI_SPEED_UNKNOWN;
 	}
 	return b;
 }
 
+static unsigned char pcix_bus_speed[] = {
+	PCI_SPEED_UNKNOWN,		/* 0 */
+	PCI_SPEED_66MHz_PCIX,		/* 1 */
+	PCI_SPEED_100MHz_PCIX,		/* 2 */
+	PCI_SPEED_133MHz_PCIX,		/* 3 */
+	PCI_SPEED_UNKNOWN,		/* 4 */
+	PCI_SPEED_66MHz_PCIX_ECC,	/* 5 */
+	PCI_SPEED_100MHz_PCIX_ECC,	/* 6 */
+	PCI_SPEED_133MHz_PCIX_ECC,	/* 7 */
+	PCI_SPEED_UNKNOWN,		/* 8 */
+	PCI_SPEED_66MHz_PCIX_266,	/* 9 */
+	PCI_SPEED_100MHz_PCIX_266,	/* A */
+	PCI_SPEED_133MHz_PCIX_266,	/* B */
+	PCI_SPEED_UNKNOWN,		/* C */
+	PCI_SPEED_66MHz_PCIX_533,	/* D */
+	PCI_SPEED_100MHz_PCIX_533,	/* E */
+	PCI_SPEED_133MHz_PCIX_533	/* F */
+};
+
+static unsigned char pcie_link_speed[] = {
+	PCI_SPEED_UNKNOWN,		/* 0 */
+	PCIE_SPEED_2_5GT,		/* 1 */
+	PCIE_SPEED_5_0GT,		/* 2 */
+	PCIE_SPEED_8_0GT,		/* 3 */
+	PCI_SPEED_UNKNOWN,		/* 4 */
+	PCI_SPEED_UNKNOWN,		/* 5 */
+	PCI_SPEED_UNKNOWN,		/* 6 */
+	PCI_SPEED_UNKNOWN,		/* 7 */
+	PCI_SPEED_UNKNOWN,		/* 8 */
+	PCI_SPEED_UNKNOWN,		/* 9 */
+	PCI_SPEED_UNKNOWN,		/* A */
+	PCI_SPEED_UNKNOWN,		/* B */
+	PCI_SPEED_UNKNOWN,		/* C */
+	PCI_SPEED_UNKNOWN,		/* D */
+	PCI_SPEED_UNKNOWN,		/* E */
+	PCI_SPEED_UNKNOWN		/* F */
+};
+
+void pcie_update_link_speed(struct pci_bus *bus, u16 linksta)
+{
+	bus->cur_bus_speed = pcie_link_speed[linksta & 0xf];
+}
+EXPORT_SYMBOL_GPL(pcie_update_link_speed);
+
+static unsigned char agp_speeds[] = {
+	AGP_UNKNOWN,
+	AGP_1X,
+	AGP_2X,
+	AGP_4X,
+	AGP_8X
+};
+
+static enum pci_bus_speed agp_speed(int agp3, int agpstat)
+{
+	int index = 0;
+
+	if (agpstat & 4)
+		index = 3;
+	else if (agpstat & 2)
+		index = 2;
+	else if (agpstat & 1)
+		index = 1;
+	else
+		goto out;
+	
+	if (agp3) {
+		index += 2;
+		if (index == 5)
+			index = 0;
+	}
+
+ out:
+	return agp_speeds[index];
+}
+
+
+static void pci_set_bus_speed(struct pci_bus *bus)
+{
+	struct pci_dev *bridge = bus->self;
+	int pos;
+
+	pos = pci_find_capability(bridge, PCI_CAP_ID_AGP);
+	if (!pos)
+		pos = pci_find_capability(bridge, PCI_CAP_ID_AGP3);
+	if (pos) {
+		u32 agpstat, agpcmd;
+
+		pci_read_config_dword(bridge, pos + PCI_AGP_STATUS, &agpstat);
+		bus->max_bus_speed = agp_speed(agpstat & 8, agpstat & 7);
+
+		pci_read_config_dword(bridge, pos + PCI_AGP_COMMAND, &agpcmd);
+		bus->cur_bus_speed = agp_speed(agpstat & 8, agpcmd & 7);
+	}
+
+	pos = pci_find_capability(bridge, PCI_CAP_ID_PCIX);
+	if (pos) {
+		u16 status;
+		enum pci_bus_speed max;
+		pci_read_config_word(bridge, pos + 2, &status);
+
+		if (status & 0x8000) {
+			max = PCI_SPEED_133MHz_PCIX_533;
+		} else if (status & 0x4000) {
+			max = PCI_SPEED_133MHz_PCIX_266;
+		} else if (status & 0x0002) {
+			if (((status >> 12) & 0x3) == 2) {
+				max = PCI_SPEED_133MHz_PCIX_ECC;
+			} else {
+				max = PCI_SPEED_133MHz_PCIX;
+			}
+		} else {
+			max = PCI_SPEED_66MHz_PCIX;
+		}
+
+		bus->max_bus_speed = max;
+		bus->cur_bus_speed = pcix_bus_speed[(status >> 6) & 0xf];
+
+		return;
+	}
+
+	pos = pci_find_capability(bridge, PCI_CAP_ID_EXP);
+	if (pos) {
+		u32 linkcap;
+		u16 linksta;
+
+		pci_read_config_dword(bridge, pos + PCI_EXP_LNKCAP, &linkcap);
+		bus->max_bus_speed = pcie_link_speed[linkcap & 0xf];
+
+		pci_read_config_word(bridge, pos + PCI_EXP_LNKSTA, &linksta);
+		pcie_update_link_speed(bus, linksta);
+	}
+}
+
+
 static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
 					   struct pci_dev *bridge, int busnr)
 {
@@ -430,6 +616,8 @@ static struct pci_bus *pci_alloc_child_b
 	child->self = bridge;
 	child->bridge = get_device(&bridge->dev);
 
+	pci_set_bus_speed(child);
+
 	/* Set up default resource pointers and names.. */
 	for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
 		child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i];
@@ -485,16 +673,20 @@ int __devinit pci_scan_bridge(struct pci
 	int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
 	u32 buses, i, j = 0;
 	u16 bctl;
+	u8 primary, secondary, subordinate;
 	int broken = 0;
 
 	pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
+	primary = buses & 0xFF;
+	secondary = (buses >> 8) & 0xFF;
+	subordinate = (buses >> 16) & 0xFF;
 
-	dev_dbg(&dev->dev, "scanning behind bridge, config %06x, pass %d\n",
-		buses & 0xffffff, pass);
+	dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n",
+		secondary, subordinate, pass);
 
 	/* Check if setup is sensible at all */
 	if (!pass &&
-	    ((buses & 0xff) != bus->number || ((buses >> 8) & 0xff) <= bus->number)) {
+	    (primary != bus->number || secondary <= bus->number)) {
 		dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n");
 		broken = 1;
 	}
@@ -505,15 +697,15 @@ int __devinit pci_scan_bridge(struct pci
 	pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
 			      bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
 
-	if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus && !broken) {
-		unsigned int cmax, busnr;
+	if ((secondary || subordinate) && !pcibios_assign_all_busses() &&
+	    !is_cardbus && !broken) {
+		unsigned int cmax;
 		/*
 		 * Bus already configured by firmware, process it in the first
 		 * pass and just note the configuration.
 		 */
 		if (pass)
 			goto out;
-		busnr = (buses >> 8) & 0xFF;
 
 		/*
 		 * If we already got to this bus through a different bridge,
@@ -522,13 +714,13 @@ int __devinit pci_scan_bridge(struct pci
 		 * However, we continue to descend down the hierarchy and
 		 * scan remaining child buses.
 		 */
-		child = pci_find_bus(pci_domain_nr(bus), busnr);
+		child = pci_find_bus(pci_domain_nr(bus), secondary);
 		if (!child) {
-			child = pci_add_new_bus(bus, dev, busnr);
+			child = pci_add_new_bus(bus, dev, secondary);
 			if (!child)
 				goto out;
-			child->primary = buses & 0xFF;
-			child->subordinate = (buses >> 16) & 0xFF;
+			child->primary = primary;
+			child->subordinate = subordinate;
 			child->bridge_ctl = bctl;
 		}
 
@@ -1081,6 +1273,45 @@ struct pci_dev *__ref pci_scan_single_de
 }
 EXPORT_SYMBOL(pci_scan_single_device);
 
+static unsigned next_ari_fn(struct pci_dev *dev, unsigned fn)
+{
+	u16 cap;
+	unsigned pos, next_fn;
+
+	if (!dev)
+		return 0;
+
+	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI);
+	if (!pos)
+		return 0;
+	pci_read_config_word(dev, pos + 4, &cap);
+	next_fn = cap >> 8;
+	if (next_fn <= fn)
+		return 0;
+	return next_fn;
+}
+
+static unsigned next_trad_fn(struct pci_dev *dev, unsigned fn)
+{
+	return (fn + 1) % 8;
+}
+
+static unsigned no_next_fn(struct pci_dev *dev, unsigned fn)
+{
+	return 0;
+}
+
+static int only_one_child(struct pci_bus *bus)
+{
+	struct pci_dev *parent = bus->self;
+	if (!parent || !pci_is_pcie(parent))
+		return 0;
+	if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
+	    parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
+		return 1;
+	return 0;
+}
+
 /**
  * pci_scan_slot - scan a PCI slot on a bus for devices.
  * @bus: PCI bus to scan
@@ -1094,21 +1325,30 @@ EXPORT_SYMBOL(pci_scan_single_device);
  */
 int pci_scan_slot(struct pci_bus *bus, int devfn)
 {
-	int fn, nr = 0;
+	unsigned fn, nr = 0;
 	struct pci_dev *dev;
+	unsigned (*next_fn)(struct pci_dev *, unsigned) = no_next_fn;
+
+	if (only_one_child(bus) && (devfn > 0))
+		return 0; /* Already scanned the entire slot */
 
 	dev = pci_scan_single_device(bus, devfn);
-	if (dev && !dev->is_added)	/* new device? */
+	if (!dev)
+		return 0;
+	if (!dev->is_added)
 		nr++;
 
-	if (dev && dev->multifunction) {
-		for (fn = 1; fn < 8; fn++) {
-			dev = pci_scan_single_device(bus, devfn + fn);
-			if (dev) {
-				if (!dev->is_added)
-					nr++;
-				dev->multifunction = 1;
-			}
+	if (pci_ari_enabled(bus))
+		next_fn = next_ari_fn;
+	else if (dev->multifunction)
+		next_fn = next_trad_fn;
+
+	for (fn = next_fn(dev, 0); fn > 0; fn = next_fn(dev, fn)) {
+		dev = pci_scan_single_device(bus, devfn + fn);
+		if (dev) {
+			if (!dev->is_added)
+				nr++;
+			dev->multifunction = 1;
 		}
 	}
 
@@ -1200,6 +1440,7 @@ struct pci_bus * pci_create_bus(struct d
 	if (error)
 		goto dev_reg_err;
 	b->bridge = get_device(dev);
+	device_enable_async_suspend(b->bridge);
 
 	if (!parent)
 		set_dev_node(b->bridge, pcibus_to_node(b));
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/proc.c linux-libre-2.6.34-gnu1/drivers/pci/proc.c
--- linux-libre-2.6.33-gnu1/drivers/pci/proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
 
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/quirks.c linux-libre-2.6.34-gnu1/drivers/pci/quirks.c
--- linux-libre-2.6.33-gnu1/drivers/pci/quirks.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/quirks.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,14 +25,9 @@
 #include <linux/dmi.h>
 #include <linux/pci-aspm.h>
 #include <linux/ioport.h>
+#include <asm/dma.h>	/* isa_dma_bridge_buggy */
 #include "pci.h"
 
-int isa_dma_bridge_buggy;
-EXPORT_SYMBOL(isa_dma_bridge_buggy);
-int pci_pci_problems;
-EXPORT_SYMBOL(pci_pci_problems);
-
-#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='.
@@ -373,8 +368,9 @@ static void __devinit quirk_io_region(st
 		bus_region.end = res->end;
 		pcibios_bus_to_resource(dev, res, &bus_region);
 
-		pci_claim_resource(dev, nr);
-		dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name);
+		if (pci_claim_resource(dev, nr) == 0)
+			dev_info(&dev->dev, "quirk: %pR claimed by %s\n",
+				 res, name);
 	}
 }	
 
@@ -1982,11 +1978,25 @@ static void __devinit quirk_via_cx700_pc
 	/*
 	 * Disable PCI Bus Parking and PCI Master read caching on CX700
 	 * which causes unspecified timing errors with a VT6212L on the PCI
-	 * bus leading to USB2.0 packet loss. The defaults are that these
-	 * features are turned off but some BIOSes turn them on.
+	 * bus leading to USB2.0 packet loss.
+	 *
+	 * This quirk is only enabled if a second (on the external PCI bus)
+	 * VT6212L is found -- the CX700 core itself also contains a USB
+	 * host controller with the same PCI ID as the VT6212L.
 	 */
 
+	/* Count VT6212L instances */
+	struct pci_dev *p = pci_get_device(PCI_VENDOR_ID_VIA,
+		PCI_DEVICE_ID_VIA_8235_USB_2, NULL);
 	uint8_t b;
+
+	/* p should contain the first (internal) VT6212L -- see if we have
+	   an external one by searching again */
+	p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, p);
+	if (!p)
+		return;
+	pci_dev_put(p);
+
 	if (pci_read_config_byte(dev, 0x76, &b) == 0) {
 		if (b & 0x40) {
 			/* Turn off PCI Bus Parking */
@@ -2013,7 +2023,7 @@ static void __devinit quirk_via_cx700_pc
 		}
 	}
 }
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching);
 
 /*
  * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the
@@ -2113,6 +2123,10 @@ static void __devinit quirk_disable_msi(
 	}
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9602, quirk_disable_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, 0x9602, quirk_disable_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AI, 0x9602, quirk_disable_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi);
 
 /* Go through the list of Hypertransport capabilities and
  * return 1 if a HT MSI capability is found and enabled */
@@ -2534,9 +2548,95 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e8, quirk_i82576_sriov);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150a, quirk_i82576_sriov);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150d, quirk_i82576_sriov);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1518, quirk_i82576_sriov);
 
 #endif	/* CONFIG_PCI_IOV */
 
+/*
+ * This is a quirk for the Ricoh MMC controller found as a part of
+ * some mulifunction chips.
+
+ * This is very similiar and based on the ricoh_mmc driver written by
+ * Philip Langdale. Thank you for these magic sequences.
+ *
+ * These chips implement the four main memory card controllers (SD, MMC, MS, xD)
+ * and one or both of cardbus or firewire.
+ *
+ * It happens that they implement SD and MMC
+ * support as separate controllers (and PCI functions). The linux SDHCI
+ * driver supports MMC cards but the chip detects MMC cards in hardware
+ * and directs them to the MMC controller - so the SDHCI driver never sees
+ * them.
+ *
+ * To get around this, we must disable the useless MMC controller.
+ * At that point, the SDHCI controller will start seeing them
+ * It seems to be the case that the relevant PCI registers to deactivate the
+ * MMC controller live on PCI function 0, which might be the cardbus controller
+ * or the firewire controller, depending on the particular chip in question
+ *
+ * This has to be done early, because as soon as we disable the MMC controller
+ * other pci functions shift up one level, e.g. function #2 becomes function
+ * #1, and this will confuse the pci core.
+ */
+
+#ifdef CONFIG_MMC_RICOH_MMC
+static void ricoh_mmc_fixup_rl5c476(struct pci_dev *dev)
+{
+	/* disable via cardbus interface */
+	u8 write_enable;
+	u8 write_target;
+	u8 disable;
+
+	/* disable must be done via function #0 */
+	if (PCI_FUNC(dev->devfn))
+		return;
+
+	pci_read_config_byte(dev, 0xB7, &disable);
+	if (disable & 0x02)
+		return;
+
+	pci_read_config_byte(dev, 0x8E, &write_enable);
+	pci_write_config_byte(dev, 0x8E, 0xAA);
+	pci_read_config_byte(dev, 0x8D, &write_target);
+	pci_write_config_byte(dev, 0x8D, 0xB7);
+	pci_write_config_byte(dev, 0xB7, disable | 0x02);
+	pci_write_config_byte(dev, 0x8E, write_enable);
+	pci_write_config_byte(dev, 0x8D, write_target);
+
+	dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via cardbus function)\n");
+	dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476);
+
+static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev)
+{
+	/* disable via firewire interface */
+	u8 write_enable;
+	u8 disable;
+
+	/* disable must be done via function #0 */
+	if (PCI_FUNC(dev->devfn))
+		return;
+
+	pci_read_config_byte(dev, 0xCB, &disable);
+
+	if (disable & 0x02)
+		return;
+
+	pci_read_config_byte(dev, 0xCA, &write_enable);
+	pci_write_config_byte(dev, 0xCA, 0x57);
+	pci_write_config_byte(dev, 0xCB, disable | 0x02);
+	pci_write_config_byte(dev, 0xCA, write_enable);
+
+	dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n");
+	dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
+#endif /*CONFIG_MMC_RICOH_MMC*/
+
+
 static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
 			  struct pci_fixup *end)
 {
@@ -2612,6 +2712,7 @@ void pci_fixup_device(enum pci_fixup_pas
 	}
 	pci_do_fixups(dev, start, end);
 }
+EXPORT_SYMBOL(pci_fixup_device);
 
 static int __init pci_apply_final_quirks(void)
 {
@@ -2723,9 +2824,3 @@ int pci_dev_specific_reset(struct pci_de
 
 	return -ENOTTY;
 }
-
-#else
-void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {}
-int pci_dev_specific_reset(struct pci_dev *dev, int probe) { return -ENOTTY; }
-#endif
-EXPORT_SYMBOL(pci_fixup_device);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/search.c linux-libre-2.6.34-gnu1/drivers/pci/search.c
--- linux-libre-2.6.33-gnu1/drivers/pci/search.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/search.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include "pci.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/setup-bus.c linux-libre-2.6.34-gnu1/drivers/pci/setup-bus.c
--- linux-libre-2.6.33-gnu1/drivers/pci/setup-bus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/setup-bus.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,37 +27,91 @@
 #include <linux/slab.h>
 #include "pci.h"
 
-static void pbus_assign_resources_sorted(const struct pci_bus *bus)
-{
-	struct pci_dev *dev;
+struct resource_list_x {
+	struct resource_list_x *next;
 	struct resource *res;
-	struct resource_list head, *list, *tmp;
-	int idx;
+	struct pci_dev *dev;
+	resource_size_t start;
+	resource_size_t end;
+	unsigned long flags;
+};
 
-	head.next = NULL;
-	list_for_each_entry(dev, &bus->devices, bus_list) {
-		u16 class = dev->class >> 8;
+static void add_to_failed_list(struct resource_list_x *head,
+				 struct pci_dev *dev, struct resource *res)
+{
+	struct resource_list_x *list = head;
+	struct resource_list_x *ln = list->next;
+	struct resource_list_x *tmp;
 
-		/* Don't touch classless devices or host bridges or ioapics.  */
-		if (class == PCI_CLASS_NOT_DEFINED ||
-		    class == PCI_CLASS_BRIDGE_HOST)
-			continue;
+	tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
+	if (!tmp) {
+		pr_warning("add_to_failed_list: kmalloc() failed!\n");
+		return;
+	}
 
-		/* Don't touch ioapic devices already enabled by firmware */
-		if (class == PCI_CLASS_SYSTEM_PIC) {
-			u16 command;
-			pci_read_config_word(dev, PCI_COMMAND, &command);
-			if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY))
-				continue;
-		}
+	tmp->next = ln;
+	tmp->res = res;
+	tmp->dev = dev;
+	tmp->start = res->start;
+	tmp->end = res->end;
+	tmp->flags = res->flags;
+	list->next = tmp;
+}
 
-		pdev_sort_resources(dev, &head);
+static void free_failed_list(struct resource_list_x *head)
+{
+	struct resource_list_x *list, *tmp;
+
+	for (list = head->next; list;) {
+		tmp = list;
+		list = list->next;
+		kfree(tmp);
 	}
 
-	for (list = head.next; list;) {
+	head->next = NULL;
+}
+
+static void __dev_sort_resources(struct pci_dev *dev,
+				 struct resource_list *head)
+{
+	u16 class = dev->class >> 8;
+
+	/* Don't touch classless devices or host bridges or ioapics.  */
+	if (class == PCI_CLASS_NOT_DEFINED || class == PCI_CLASS_BRIDGE_HOST)
+		return;
+
+	/* Don't touch ioapic devices already enabled by firmware */
+	if (class == PCI_CLASS_SYSTEM_PIC) {
+		u16 command;
+		pci_read_config_word(dev, PCI_COMMAND, &command);
+		if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY))
+			return;
+	}
+
+	pdev_sort_resources(dev, head);
+}
+
+static void __assign_resources_sorted(struct resource_list *head,
+				 struct resource_list_x *fail_head)
+{
+	struct resource *res;
+	struct resource_list *list, *tmp;
+	int idx;
+
+	for (list = head->next; list;) {
 		res = list->res;
 		idx = res - &list->dev->resource[0];
+
 		if (pci_assign_resource(list->dev, idx)) {
+			if (fail_head && !pci_is_root_bus(list->dev->bus)) {
+				/*
+				 * if the failed res is for ROM BAR, and it will
+				 * be enabled later, don't add it to the list
+				 */
+				if (!((idx == PCI_ROM_RESOURCE) &&
+				      (!(res->flags & IORESOURCE_ROM_ENABLE))))
+					add_to_failed_list(fail_head, list->dev, res);
+			}
 			res->start = 0;
 			res->end = 0;
 			res->flags = 0;
@@ -68,6 +122,30 @@ static void pbus_assign_resources_sorted
 	}
 }
 
+static void pdev_assign_resources_sorted(struct pci_dev *dev,
+				 struct resource_list_x *fail_head)
+{
+	struct resource_list head;
+
+	head.next = NULL;
+	__dev_sort_resources(dev, &head);
+	__assign_resources_sorted(&head, fail_head);
+
+}
+
+static void pbus_assign_resources_sorted(const struct pci_bus *bus,
+					 struct resource_list_x *fail_head)
+{
+	struct pci_dev *dev;
+	struct resource_list head;
+
+	head.next = NULL;
+	list_for_each_entry(dev, &bus->devices, bus_list)
+		__dev_sort_resources(dev, &head);
+
+	__assign_resources_sorted(&head, fail_head);
+}
+
 void pci_setup_cardbus(struct pci_bus *bus)
 {
 	struct pci_dev *bridge = bus->self;
@@ -134,18 +212,12 @@ EXPORT_SYMBOL(pci_setup_cardbus);
    config space writes, so it's quite possible that an I/O window of
    the bridge will have some undesirable address (e.g. 0) after the
    first write. Ditto 64-bit prefetchable MMIO.  */
-static void pci_setup_bridge(struct pci_bus *bus)
+static void pci_setup_bridge_io(struct pci_bus *bus)
 {
 	struct pci_dev *bridge = bus->self;
 	struct resource *res;
 	struct pci_bus_region region;
-	u32 l, bu, lu, io_upper16;
-
-	if (pci_is_enabled(bridge))
-		return;
-
-	dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n",
-		 bus->secondary, bus->subordinate);
+	u32 l, io_upper16;
 
 	/* Set up the top and bottom of the PCI I/O segment for this bus. */
 	res = bus->resource[0];
@@ -158,8 +230,7 @@ static void pci_setup_bridge(struct pci_
 		/* Set up upper 16 bits of I/O base/limit. */
 		io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
 		dev_info(&bridge->dev, "  bridge window %pR\n", res);
-	}
-	else {
+	} else {
 		/* Clear upper 16 bits of I/O base/limit. */
 		io_upper16 = 0;
 		l = 0x00f0;
@@ -171,21 +242,35 @@ static void pci_setup_bridge(struct pci_
 	pci_write_config_dword(bridge, PCI_IO_BASE, l);
 	/* Update upper 16 bits of I/O base/limit. */
 	pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16);
+}
 
-	/* Set up the top and bottom of the PCI Memory segment
-	   for this bus. */
+static void pci_setup_bridge_mmio(struct pci_bus *bus)
+{
+	struct pci_dev *bridge = bus->self;
+	struct resource *res;
+	struct pci_bus_region region;
+	u32 l;
+
+	/* Set up the top and bottom of the PCI Memory segment for this bus. */
 	res = bus->resource[1];
 	pcibios_resource_to_bus(bridge, &region, res);
 	if (res->flags & IORESOURCE_MEM) {
 		l = (region.start >> 16) & 0xfff0;
 		l |= region.end & 0xfff00000;
 		dev_info(&bridge->dev, "  bridge window %pR\n", res);
-	}
-	else {
+	} else {
 		l = 0x0000fff0;
 		dev_info(&bridge->dev, "  bridge window [mem disabled]\n");
 	}
 	pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
+}
+
+static void pci_setup_bridge_mmio_pref(struct pci_bus *bus)
+{
+	struct pci_dev *bridge = bus->self;
+	struct resource *res;
+	struct pci_bus_region region;
+	u32 l, bu, lu;
 
 	/* Clear out the upper 32 bits of PREF limit.
 	   If PCI_PREF_BASE_UPPER32 was non-zero, this temporarily
@@ -204,8 +289,7 @@ static void pci_setup_bridge(struct pci_
 			lu = upper_32_bits(region.end);
 		}
 		dev_info(&bridge->dev, "  bridge window %pR\n", res);
-	}
-	else {
+	} else {
 		l = 0x0000fff0;
 		dev_info(&bridge->dev, "  bridge window [mem pref disabled]\n");
 	}
@@ -214,10 +298,35 @@ static void pci_setup_bridge(struct pci_
 	/* Set the upper 32 bits of PREF base & limit. */
 	pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
 	pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
+}
+
+static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type)
+{
+	struct pci_dev *bridge = bus->self;
+
+	dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n",
+		 bus->secondary, bus->subordinate);
+
+	if (type & IORESOURCE_IO)
+		pci_setup_bridge_io(bus);
+
+	if (type & IORESOURCE_MEM)
+		pci_setup_bridge_mmio(bus);
+
+	if (type & IORESOURCE_PREFETCH)
+		pci_setup_bridge_mmio_pref(bus);
 
 	pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
 }
 
+static void pci_setup_bridge(struct pci_bus *bus)
+{
+	unsigned long type = IORESOURCE_IO | IORESOURCE_MEM |
+				  IORESOURCE_PREFETCH;
+
+	__pci_setup_bridge(bus, type);
+}
+
 /* Check whether the bridge supports optional I/O and
    prefetchable memory ranges. If not, the respective
    base/limit registers must be read-only and read as 0. */
@@ -253,8 +362,11 @@ static void pci_bridge_check_ranges(stru
 	}
 	if (pmem) {
 		b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
-		if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64)
+		if ((pmem & PCI_PREF_RANGE_TYPE_MASK) ==
+		    PCI_PREF_RANGE_TYPE_64) {
 			b_res[2].flags |= IORESOURCE_MEM_64;
+			b_res[2].flags |= PCI_PREF_RANGE_TYPE_64;
+		}
 	}
 
 	/* double check if bridge does support 64 bit pref */
@@ -283,8 +395,7 @@ static struct resource *find_free_bus_re
 	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
 				  IORESOURCE_PREFETCH;
 
-	for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
-		r = bus->resource[i];
+	pci_bus_for_each_resource(bus, r, i) {
 		if (r == &ioport_resource || r == &iomem_resource)
 			continue;
 		if (r && (r->flags & type_mask) == type && !r->parent)
@@ -301,7 +412,7 @@ static void pbus_size_io(struct pci_bus
 {
 	struct pci_dev *dev;
 	struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
-	unsigned long size = 0, size1 = 0;
+	unsigned long size = 0, size1 = 0, old_size;
 
 	if (!b_res)
  		return;
@@ -326,12 +437,17 @@ static void pbus_size_io(struct pci_bus
 	}
 	if (size < min_size)
 		size = min_size;
+	old_size = resource_size(b_res);
+	if (old_size == 1)
+		old_size = 0;
 /* To be fixed in 2.5: we should have sort of HAVE_ISA
    flag in the struct pci_bus. */
 #if defined(CONFIG_ISA) || defined(CONFIG_EISA)
 	size = (size & 0xff) + ((size & ~0xffUL) << 2);
 #endif
 	size = ALIGN(size + size1, 4096);
+	if (size < old_size)
+		size = old_size;
 	if (!size) {
 		if (b_res->start || b_res->end)
 			dev_info(&bus->self->dev, "disabling bridge window "
@@ -352,7 +468,7 @@ static int pbus_size_mem(struct pci_bus
 			 unsigned long type, resource_size_t min_size)
 {
 	struct pci_dev *dev;
-	resource_size_t min_align, align, size;
+	resource_size_t min_align, align, size, old_size;
 	resource_size_t aligns[12];	/* Alignments from 1Mb to 2Gb */
 	int order, max_order;
 	struct resource *b_res = find_free_bus_resource(bus, type);
@@ -402,6 +518,11 @@ static int pbus_size_mem(struct pci_bus
 	}
 	if (size < min_size)
 		size = min_size;
+	old_size = resource_size(b_res);
+	if (old_size == 1)
+		old_size = 0;
+	if (size < old_size)
+		size = old_size;
 
 	align = 0;
 	min_align = 0;
@@ -538,23 +659,25 @@ void __ref pci_bus_size_bridges(struct p
 }
 EXPORT_SYMBOL(pci_bus_size_bridges);
 
-void __ref pci_bus_assign_resources(const struct pci_bus *bus)
+static void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
+					 struct resource_list_x *fail_head)
 {
 	struct pci_bus *b;
 	struct pci_dev *dev;
 
-	pbus_assign_resources_sorted(bus);
+	pbus_assign_resources_sorted(bus, fail_head);
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		b = dev->subordinate;
 		if (!b)
 			continue;
 
-		pci_bus_assign_resources(b);
+		__pci_bus_assign_resources(b, fail_head);
 
 		switch (dev->class >> 8) {
 		case PCI_CLASS_BRIDGE_PCI:
-			pci_setup_bridge(b);
+			if (!pci_is_enabled(dev))
+				pci_setup_bridge(b);
 			break;
 
 		case PCI_CLASS_BRIDGE_CARDBUS:
@@ -568,15 +691,130 @@ void __ref pci_bus_assign_resources(cons
 		}
 	}
 }
+
+void __ref pci_bus_assign_resources(const struct pci_bus *bus)
+{
+	__pci_bus_assign_resources(bus, NULL);
+}
 EXPORT_SYMBOL(pci_bus_assign_resources);
 
+static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge,
+					 struct resource_list_x *fail_head)
+{
+	struct pci_bus *b;
+
+	pdev_assign_resources_sorted((struct pci_dev *)bridge, fail_head);
+
+	b = bridge->subordinate;
+	if (!b)
+		return;
+
+	__pci_bus_assign_resources(b, fail_head);
+
+	switch (bridge->class >> 8) {
+	case PCI_CLASS_BRIDGE_PCI:
+		pci_setup_bridge(b);
+		break;
+
+	case PCI_CLASS_BRIDGE_CARDBUS:
+		pci_setup_cardbus(b);
+		break;
+
+	default:
+		dev_info(&bridge->dev, "not setting up bridge for bus "
+			 "%04x:%02x\n", pci_domain_nr(b), b->number);
+		break;
+	}
+}
+static void pci_bridge_release_resources(struct pci_bus *bus,
+					  unsigned long type)
+{
+	int idx;
+	bool changed = false;
+	struct pci_dev *dev;
+	struct resource *r;
+	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
+				  IORESOURCE_PREFETCH;
+
+	dev = bus->self;
+	for (idx = PCI_BRIDGE_RESOURCES; idx <= PCI_BRIDGE_RESOURCE_END;
+	     idx++) {
+		r = &dev->resource[idx];
+		if ((r->flags & type_mask) != type)
+			continue;
+		if (!r->parent)
+			continue;
+		/*
+		 * if there are children under that, we should release them
+		 *  all
+		 */
+		release_child_resources(r);
+		if (!release_resource(r)) {
+			dev_printk(KERN_DEBUG, &dev->dev,
+				 "resource %d %pR released\n", idx, r);
+			/* keep the old size */
+			r->end = resource_size(r) - 1;
+			r->start = 0;
+			r->flags = 0;
+			changed = true;
+		}
+	}
+
+	if (changed) {
+		/* avoiding touch the one without PREF */
+		if (type & IORESOURCE_PREFETCH)
+			type = IORESOURCE_PREFETCH;
+		__pci_setup_bridge(bus, type);
+	}
+}
+
+enum release_type {
+	leaf_only,
+	whole_subtree,
+};
+/*
+ * try to release pci bridge resources that is from leaf bridge,
+ * so we can allocate big new one later
+ */
+static void __ref pci_bus_release_bridge_resources(struct pci_bus *bus,
+						   unsigned long type,
+						   enum release_type rel_type)
+{
+	struct pci_dev *dev;
+	bool is_leaf_bridge = true;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		struct pci_bus *b = dev->subordinate;
+		if (!b)
+			continue;
+
+		is_leaf_bridge = false;
+
+		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+			continue;
+
+		if (rel_type == whole_subtree)
+			pci_bus_release_bridge_resources(b, type,
+						 whole_subtree);
+	}
+
+	if (pci_is_root_bus(bus))
+		return;
+
+	if ((bus->self->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+		return;
+
+	if ((rel_type == whole_subtree) || is_leaf_bridge)
+		pci_bridge_release_resources(bus, type);
+}
+
 static void pci_bus_dump_res(struct pci_bus *bus)
 {
-        int i;
+	struct resource *res;
+	int i;
 
-        for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
-                struct resource *res = bus->resource[i];
-                if (!res || !res->end)
+	pci_bus_for_each_resource(bus, res, i) {
+		if (!res || !res->end || !res->flags)
                         continue;
 
 		dev_printk(KERN_DEBUG, &bus->dev, "resource %d %pR\n", i, res);
@@ -621,3 +859,65 @@ pci_assign_unassigned_resources(void)
 		pci_bus_dump_resources(bus);
 	}
 }
+
+void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
+{
+	struct pci_bus *parent = bridge->subordinate;
+	int tried_times = 0;
+	struct resource_list_x head, *list;
+	int retval;
+	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
+				  IORESOURCE_PREFETCH;
+
+	head.next = NULL;
+
+again:
+	pci_bus_size_bridges(parent);
+	__pci_bridge_assign_resources(bridge, &head);
+	retval = pci_reenable_device(bridge);
+	pci_set_master(bridge);
+	pci_enable_bridges(parent);
+
+	tried_times++;
+
+	if (!head.next)
+		return;
+
+	if (tried_times >= 2) {
+		/* still fail, don't need to try more */
+		free_failed_list(&head);
+		return;
+	}
+
+	printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
+			 tried_times + 1);
+
+	/*
+	 * Try to release leaf bridge's resources that doesn't fit resource of
+	 * child device under that bridge
+	 */
+	for (list = head.next; list;) {
+		struct pci_bus *bus = list->dev->bus;
+		unsigned long flags = list->flags;
+
+		pci_bus_release_bridge_resources(bus, flags & type_mask,
+						 whole_subtree);
+		list = list->next;
+	}
+	/* restore size and flags */
+	for (list = head.next; list;) {
+		struct resource *res = list->res;
+
+		res->start = list->start;
+		res->end = list->end;
+		res->flags = list->flags;
+		if (list->dev->subordinate)
+			res->flags = 0;
+
+		list = list->next;
+	}
+	free_failed_list(&head);
+
+	goto again;
+}
+EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/setup-res.c linux-libre-2.6.34-gnu1/drivers/pci/setup-res.c
--- linux-libre-2.6.33-gnu1/drivers/pci/setup-res.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/setup-res.c	2010-05-16 17:17:36.000000000 -0400
@@ -93,8 +93,7 @@ void pci_update_resource(struct pci_dev
 int pci_claim_resource(struct pci_dev *dev, int resource)
 {
 	struct resource *res = &dev->resource[resource];
-	struct resource *root;
-	int err;
+	struct resource *root, *conflict;
 
 	root = pci_find_parent_resource(dev, res);
 	if (!root) {
@@ -103,12 +102,15 @@ int pci_claim_resource(struct pci_dev *d
 		return -EINVAL;
 	}
 
-	err = request_resource(root, res);
-	if (err)
+	conflict = request_resource_conflict(root, res);
+	if (conflict) {
 		dev_err(&dev->dev,
-			"address space collision: %pR already in use\n", res);
+			"address space collision: %pR conflicts with %s %pR\n",
+			res, conflict->name, conflict);
+		return -EBUSY;
+	}
 
-	return err;
+	return 0;
 }
 EXPORT_SYMBOL(pci_claim_resource);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/slot.c linux-libre-2.6.34-gnu1/drivers/pci/slot.c
--- linux-libre-2.6.33-gnu1/drivers/pci/slot.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/slot.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
  */
 
 #include <linux/kobject.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/err.h>
 #include "pci.h"
@@ -29,7 +30,7 @@ static ssize_t pci_slot_attr_store(struc
 	return attribute->store ? attribute->store(slot, buf, len) : -EIO;
 }
 
-static struct sysfs_ops pci_slot_sysfs_ops = {
+static const struct sysfs_ops pci_slot_sysfs_ops = {
 	.show = pci_slot_attr_show,
 	.store = pci_slot_attr_store,
 };
@@ -47,6 +48,55 @@ static ssize_t address_read_file(struct
 				slot->number);
 }
 
+/* these strings match up with the values in pci_bus_speed */
+static char *pci_bus_speed_strings[] = {
+	"33 MHz PCI",		/* 0x00 */
+	"66 MHz PCI",		/* 0x01 */
+	"66 MHz PCI-X", 	/* 0x02 */
+	"100 MHz PCI-X",	/* 0x03 */
+	"133 MHz PCI-X",	/* 0x04 */
+	NULL,			/* 0x05 */
+	NULL,			/* 0x06 */
+	NULL,			/* 0x07 */
+	NULL,			/* 0x08 */
+	"66 MHz PCI-X 266",	/* 0x09 */
+	"100 MHz PCI-X 266",	/* 0x0a */
+	"133 MHz PCI-X 266",	/* 0x0b */
+	"Unknown AGP",		/* 0x0c */
+	"1x AGP",		/* 0x0d */
+	"2x AGP",		/* 0x0e */
+	"4x AGP",		/* 0x0f */
+	"8x AGP",		/* 0x10 */
+	"66 MHz PCI-X 533",	/* 0x11 */
+	"100 MHz PCI-X 533",	/* 0x12 */
+	"133 MHz PCI-X 533",	/* 0x13 */
+	"2.5 GT/s PCIe",	/* 0x14 */
+	"5.0 GT/s PCIe",	/* 0x15 */
+	"8.0 GT/s PCIe",	/* 0x16 */
+};
+
+static ssize_t bus_speed_read(enum pci_bus_speed speed, char *buf)
+{
+	const char *speed_string;
+
+	if (speed < ARRAY_SIZE(pci_bus_speed_strings))
+		speed_string = pci_bus_speed_strings[speed];
+	else
+		speed_string = "Unknown";
+
+	return sprintf(buf, "%s\n", speed_string);
+}
+
+static ssize_t max_speed_read_file(struct pci_slot *slot, char *buf)
+{
+	return bus_speed_read(slot->bus->max_bus_speed, buf);
+}
+
+static ssize_t cur_speed_read_file(struct pci_slot *slot, char *buf)
+{
+	return bus_speed_read(slot->bus->cur_bus_speed, buf);
+}
+
 static void pci_slot_release(struct kobject *kobj)
 {
 	struct pci_dev *dev;
@@ -66,9 +116,15 @@ static void pci_slot_release(struct kobj
 
 static struct pci_slot_attribute pci_slot_attr_address =
 	__ATTR(address, (S_IFREG | S_IRUGO), address_read_file, NULL);
+static struct pci_slot_attribute pci_slot_attr_max_speed =
+	__ATTR(max_bus_speed, (S_IFREG | S_IRUGO), max_speed_read_file, NULL);
+static struct pci_slot_attribute pci_slot_attr_cur_speed =
+	__ATTR(cur_bus_speed, (S_IFREG | S_IRUGO), cur_speed_read_file, NULL);
 
 static struct attribute *pci_slot_default_attrs[] = {
 	&pci_slot_attr_address.attr,
+	&pci_slot_attr_max_speed.attr,
+	&pci_slot_attr_cur_speed.attr,
 	NULL,
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pci/vpd.c linux-libre-2.6.34-gnu1/drivers/pci/vpd.c
--- linux-libre-2.6.33-gnu1/drivers/pci/vpd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pci/vpd.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,61 @@
+/*
+ * File:	vpd.c
+ * Purpose:	Provide PCI VPD support
+ *
+ * Copyright (C) 2010 Broadcom Corporation.
+ */
+
+#include <linux/pci.h>
+
+int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt)
+{
+	int i;
+
+	for (i = off; i < len; ) {
+		u8 val = buf[i];
+
+		if (val & PCI_VPD_LRDT) {
+			/* Don't return success of the tag isn't complete */
+			if (i + PCI_VPD_LRDT_TAG_SIZE > len)
+				break;
+
+			if (val == rdt)
+				return i;
+
+			i += PCI_VPD_LRDT_TAG_SIZE +
+			     pci_vpd_lrdt_size(&buf[i]);
+		} else {
+			u8 tag = val & ~PCI_VPD_SRDT_LEN_MASK;
+
+			if (tag == rdt)
+				return i;
+
+			if (tag == PCI_VPD_SRDT_END)
+				break;
+
+			i += PCI_VPD_SRDT_TAG_SIZE +
+			     pci_vpd_srdt_size(&buf[i]);
+		}
+	}
+
+	return -ENOENT;
+}
+EXPORT_SYMBOL_GPL(pci_vpd_find_tag);
+
+int pci_vpd_find_info_keyword(const u8 *buf, unsigned int off,
+			      unsigned int len, const char *kw)
+{
+	int i;
+
+	for (i = off; i + PCI_VPD_INFO_FLD_HDR_SIZE <= off + len;) {
+		if (buf[i + 0] == kw[0] &&
+		    buf[i + 1] == kw[1])
+			return i;
+
+		i += PCI_VPD_INFO_FLD_HDR_SIZE +
+		     pci_vpd_info_field_size(&buf[i]);
+	}
+
+	return -ENOENT;
+}
+EXPORT_SYMBOL_GPL(pci_vpd_find_info_keyword);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/at91_cf.c linux-libre-2.6.34-gnu1/drivers/pcmcia/at91_cf.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/at91_cf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/at91_cf.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include <pcmcia/ss.h>
 
@@ -52,8 +53,6 @@ struct at91_cf_socket {
 	unsigned long		phys_baseaddr;
 };
 
-#define	SZ_2K			(2 * SZ_1K)
-
 static inline int at91_cf_present(struct at91_cf_socket *cf)
 {
 	return !gpio_get_value(cf->board->det_pin);
@@ -363,7 +362,6 @@ static int at91_cf_suspend(struct platfo
 	struct at91_cf_socket	*cf = platform_get_drvdata(pdev);
 	struct at91_cf_data	*board = cf->board;
 
-	pcmcia_socket_dev_suspend(&pdev->dev);
 	if (device_may_wakeup(&pdev->dev)) {
 		enable_irq_wake(board->det_pin);
 		if (board->irq_pin)
@@ -383,7 +381,6 @@ static int at91_cf_resume(struct platfor
 			disable_irq_wake(board->irq_pin);
 	}
 
-	pcmcia_socket_dev_resume(&pdev->dev);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/au1000_db1x00.c linux-libre-2.6.34-gnu1/drivers/pcmcia/au1000_db1x00.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/au1000_db1x00.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/au1000_db1x00.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,305 +0,0 @@
-/*
- *
- * Alchemy Semi Db1x00 boards specific pcmcia routines.
- *
- * Copyright 2002 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- * Copyright 2004 Pete Popov, updated the driver to 2.6.
- * Followed the sa11xx API and largely copied many of the hardware
- * independent functions.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/init.h>
-
-#include <asm/irq.h>
-#include <asm/signal.h>
-#include <asm/mach-au1x00/au1000.h>
-
-#if defined(CONFIG_MIPS_DB1200)
-	#include <db1200.h>
-#elif defined(CONFIG_MIPS_PB1200)
-	#include <pb1200.h>
-#else
-	#include <asm/mach-db1x00/db1x00.h>
-	static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
-#endif
-
-#include "au1000_generic.h"
-
-#if 0
-#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
-#else
-#define debug(x,args...)
-#endif
-
-
-struct au1000_pcmcia_socket au1000_pcmcia_socket[PCMCIA_NUM_SOCKS];
-extern int au1x00_pcmcia_socket_probe(struct device *, struct pcmcia_low_level *, int, int);
-
-static int db1x00_pcmcia_hw_init(struct au1000_pcmcia_socket *skt)
-{
-#ifdef CONFIG_MIPS_DB1550
-	skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_3;
-#elif defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
-	skt->irq = skt->nr ? BOARD_PC1_INT : BOARD_PC0_INT;
-#else
-	skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_2;
-#endif
-	return 0;
-}
-
-static void db1x00_pcmcia_shutdown(struct au1000_pcmcia_socket *skt)
-{
-	bcsr->pcmcia = 0; /* turn off power */
-	au_sync_delay(2);
-}
-
-static void
-db1x00_pcmcia_socket_state(struct au1000_pcmcia_socket *skt, struct pcmcia_state *state)
-{
-	u32 inserted;
-	unsigned char vs;
-
-	state->ready = 0;
-	state->vs_Xv = 0;
-	state->vs_3v = 0;
-	state->detect = 0;
-
-	switch (skt->nr) {
-	case 0:
-		vs = bcsr->status & 0x3;
-#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
-		inserted = BOARD_CARD_INSERTED(0);
-#else
-		inserted = !(bcsr->status & (1<<4));
-#endif
-		break;
-	case 1:
-		vs = (bcsr->status & 0xC)>>2;
-#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
-		inserted = BOARD_CARD_INSERTED(1);
-#else
-		inserted = !(bcsr->status & (1<<5));
-#endif
-		break;
-	default:/* should never happen */
-		return;
-	}
-
-	if (inserted)
-		debug("db1x00 socket %d: inserted %d, vs %d pcmcia %x\n",
-				skt->nr, inserted, vs, bcsr->pcmcia);
-
-	if (inserted) {
-		switch (vs) {
-			case 0:
-			case 2:
-				state->vs_3v=1;
-				break;
-			case 3: /* 5V */
-				break;
-			default:
-				/* return without setting 'detect' */
-				printk(KERN_ERR "db1x00 bad VS (%d)\n",
-						vs);
-		}
-		state->detect = 1;
-		state->ready = 1;
-	}
-	else {
-		/* if the card was previously inserted and then ejected,
-		 * we should turn off power to it
-		 */
-		if ((skt->nr == 0) && (bcsr->pcmcia & BCSR_PCMCIA_PC0RST)) {
-			bcsr->pcmcia &= ~(BCSR_PCMCIA_PC0RST |
-					BCSR_PCMCIA_PC0DRVEN |
-					BCSR_PCMCIA_PC0VPP |
-					BCSR_PCMCIA_PC0VCC);
-			au_sync_delay(10);
-		}
-		else if ((skt->nr == 1) && bcsr->pcmcia & BCSR_PCMCIA_PC1RST) {
-			bcsr->pcmcia &= ~(BCSR_PCMCIA_PC1RST |
-					BCSR_PCMCIA_PC1DRVEN |
-					BCSR_PCMCIA_PC1VPP |
-					BCSR_PCMCIA_PC1VCC);
-			au_sync_delay(10);
-		}
-	}
-
-	state->bvd1=1;
-	state->bvd2=1;
-	state->wrprot=0;
-}
-
-static int
-db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_state_t *state)
-{
-	u16 pwr;
-	int sock = skt->nr;
-
-	debug("config_skt %d Vcc %dV Vpp %dV, reset %d\n",
-			sock, state->Vcc, state->Vpp,
-			state->flags & SS_RESET);
-
-	/* pcmcia reg was set to zero at init time. Be careful when
-	 * initializing a socket not to wipe out the settings of the
-	 * other socket.
-	 */
-	pwr = bcsr->pcmcia;
-	pwr &= ~(0xf << sock*8); /* clear voltage settings */
-
-	state->Vpp = 0;
-	switch(state->Vcc){
-		case 0:  /* Vcc 0 */
-			pwr |= SET_VCC_VPP(0,0,sock);
-			break;
-		case 50: /* Vcc 5V */
-			switch(state->Vpp) {
-				case 0:
-					pwr |= SET_VCC_VPP(2,0,sock);
-					break;
-				case 50:
-					pwr |= SET_VCC_VPP(2,1,sock);
-					break;
-				case 12:
-					pwr |= SET_VCC_VPP(2,2,sock);
-					break;
-				case 33:
-				default:
-					pwr |= SET_VCC_VPP(0,0,sock);
-					printk("%s: bad Vcc/Vpp (%d:%d)\n",
-							__func__,
-							state->Vcc,
-							state->Vpp);
-					break;
-			}
-			break;
-		case 33: /* Vcc 3.3V */
-			switch(state->Vpp) {
-				case 0:
-					pwr |= SET_VCC_VPP(1,0,sock);
-					break;
-				case 12:
-					pwr |= SET_VCC_VPP(1,2,sock);
-					break;
-				case 33:
-					pwr |= SET_VCC_VPP(1,1,sock);
-					break;
-				case 50:
-				default:
-					pwr |= SET_VCC_VPP(0,0,sock);
-					printk("%s: bad Vcc/Vpp (%d:%d)\n",
-							__func__,
-							state->Vcc,
-							state->Vpp);
-					break;
-			}
-			break;
-		default: /* what's this ? */
-			pwr |= SET_VCC_VPP(0,0,sock);
-			printk(KERN_ERR "%s: bad Vcc %d\n",
-					__func__, state->Vcc);
-			break;
-	}
-
-	bcsr->pcmcia = pwr;
-	au_sync_delay(300);
-
-	if (sock == 0) {
-		if (!(state->flags & SS_RESET)) {
-			pwr |= BCSR_PCMCIA_PC0DRVEN;
-			bcsr->pcmcia = pwr;
-			au_sync_delay(300);
-			pwr |= BCSR_PCMCIA_PC0RST;
-			bcsr->pcmcia = pwr;
-			au_sync_delay(100);
-		}
-		else {
-			pwr &= ~(BCSR_PCMCIA_PC0RST | BCSR_PCMCIA_PC0DRVEN);
-			bcsr->pcmcia = pwr;
-			au_sync_delay(100);
-		}
-	}
-	else {
-		if (!(state->flags & SS_RESET)) {
-			pwr |= BCSR_PCMCIA_PC1DRVEN;
-			bcsr->pcmcia = pwr;
-			au_sync_delay(300);
-			pwr |= BCSR_PCMCIA_PC1RST;
-			bcsr->pcmcia = pwr;
-			au_sync_delay(100);
-		}
-		else {
-			pwr &= ~(BCSR_PCMCIA_PC1RST | BCSR_PCMCIA_PC1DRVEN);
-			bcsr->pcmcia = pwr;
-			au_sync_delay(100);
-		}
-	}
-	return 0;
-}
-
-/*
- * Enable card status IRQs on (re-)initialisation.  This can
- * be called at initialisation, power management event, or
- * pcmcia event.
- */
-void db1x00_socket_init(struct au1000_pcmcia_socket *skt)
-{
-	/* nothing to do for now */
-}
-
-/*
- * Disable card status IRQs and PCMCIA bus on suspend.
- */
-void db1x00_socket_suspend(struct au1000_pcmcia_socket *skt)
-{
-	/* nothing to do for now */
-}
-
-struct pcmcia_low_level db1x00_pcmcia_ops = {
-	.owner			= THIS_MODULE,
-
-	.hw_init 		= db1x00_pcmcia_hw_init,
-	.hw_shutdown		= db1x00_pcmcia_shutdown,
-
-	.socket_state		= db1x00_pcmcia_socket_state,
-	.configure_socket	= db1x00_pcmcia_configure_socket,
-
-	.socket_init		= db1x00_socket_init,
-	.socket_suspend		= db1x00_socket_suspend
-};
-
-int au1x_board_init(struct device *dev)
-{
-	int ret = -ENODEV;
-	bcsr->pcmcia = 0; /* turn off power, if it's not already off */
-	au_sync_delay(2);
-	ret = au1x00_pcmcia_socket_probe(dev, &db1x00_pcmcia_ops, 0, 2);
-	return ret;
-}
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/au1000_generic.c linux-libre-2.6.34-gnu1/drivers/pcmcia/au1000_generic.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/au1000_generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/au1000_generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,7 @@
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -405,18 +406,16 @@ int au1x00_pcmcia_socket_probe(struct de
 			skt->virt_io = (void *)
 				(ioremap((phys_t)AU1X_SOCK0_IO, 0x1000) -
 				(u32)mips_io_port_base);
-			skt->phys_attr = AU1X_SOCK0_PSEUDO_PHYS_ATTR;
-			skt->phys_mem = AU1X_SOCK0_PSEUDO_PHYS_MEM;
+			skt->phys_attr = AU1X_SOCK0_PHYS_ATTR;
+			skt->phys_mem = AU1X_SOCK0_PHYS_MEM;
 		}
-#ifndef CONFIG_MIPS_XXS1500
 		else  {
 			skt->virt_io = (void *)
 				(ioremap((phys_t)AU1X_SOCK1_IO, 0x1000) -
 				(u32)mips_io_port_base);
-			skt->phys_attr = AU1X_SOCK1_PSEUDO_PHYS_ATTR;
-			skt->phys_mem = AU1X_SOCK1_PSEUDO_PHYS_MEM;
+			skt->phys_attr = AU1X_SOCK1_PHYS_ATTR;
+			skt->phys_mem = AU1X_SOCK1_PHYS_MEM;
 		}
-#endif
 		pcmcia_base_vaddrs[i] = (u32 *)skt->virt_io;
 		ret = ops->hw_init(skt);
 
@@ -512,17 +511,6 @@ 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);
-}
-
-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",
@@ -530,8 +518,6 @@ static struct platform_driver au1x00_pcm
 	},
 	.probe		= au1x00_drv_pcmcia_probe,
 	.remove		= au1x00_drv_pcmcia_remove,
-	.suspend 	= au1x00_drv_pcmcia_suspend,
-	.resume 	= au1x00_drv_pcmcia_resume,
 };
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/au1000_generic.h linux-libre-2.6.34-gnu1/drivers/pcmcia/au1000_generic.h
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/au1000_generic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/au1000_generic.h	2010-05-16 17:17:36.000000000 -0400
@@ -36,30 +36,14 @@
 #define AU1X_SOCK0_IO        0xF00000000ULL
 #define AU1X_SOCK0_PHYS_ATTR 0xF40000000ULL
 #define AU1X_SOCK0_PHYS_MEM  0xF80000000ULL
-/* pseudo 32 bit phys addresses, which get fixed up to the
- * real 36 bit address in fixup_bigphys_addr() */
-#define AU1X_SOCK0_PSEUDO_PHYS_ATTR 0xF4000000
-#define AU1X_SOCK0_PSEUDO_PHYS_MEM  0xF8000000
 
 /* pcmcia socket 1 needs external glue logic so the memory map
  * differs from board to board.
  */
-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || \
-    defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1550) || \
-    defined(CONFIG_MIPS_PB1200)
+#if defined(CONFIG_MIPS_PB1000)
 #define AU1X_SOCK1_IO        0xF08000000ULL
 #define AU1X_SOCK1_PHYS_ATTR 0xF48000000ULL
 #define AU1X_SOCK1_PHYS_MEM  0xF88000000ULL
-#define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4800000
-#define AU1X_SOCK1_PSEUDO_PHYS_MEM  0xF8800000
-#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || \
-      defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550) || \
-      defined(CONFIG_MIPS_DB1200)
-#define AU1X_SOCK1_IO        0xF04000000ULL
-#define AU1X_SOCK1_PHYS_ATTR 0xF44000000ULL
-#define AU1X_SOCK1_PHYS_MEM  0xF84000000ULL
-#define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4400000
-#define AU1X_SOCK1_PSEUDO_PHYS_MEM  0xF8400000
 #endif
 
 struct pcmcia_state {
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/au1000_pb1x00.c linux-libre-2.6.34-gnu1/drivers/pcmcia/au1000_pb1x00.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/au1000_pb1x00.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/au1000_pb1x00.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  *
- * Alchemy Semi Pb1x00 boards specific pcmcia routines.
+ * Alchemy Semi Pb1000 boards specific pcmcia routines.
  *
  * Copyright 2002 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
@@ -46,20 +46,11 @@
 
 #define debug(fmt, arg...) do { } while (0)
 
-#ifdef CONFIG_MIPS_PB1000
 #include <asm/pb1000.h>
 #define PCMCIA_IRQ AU1000_GPIO_15
-#elif defined (CONFIG_MIPS_PB1500)
-#include <asm/pb1500.h>
-#define PCMCIA_IRQ AU1500_GPIO_203
-#elif defined (CONFIG_MIPS_PB1100)
-#include <asm/pb1100.h>
-#define PCMCIA_IRQ AU1000_GPIO_11
-#endif
 
 static int pb1x00_pcmcia_init(struct pcmcia_init *init)
 {
-#ifdef CONFIG_MIPS_PB1000
 	u16 pcr;
 	pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST;
 
@@ -74,21 +65,10 @@ static int pb1x00_pcmcia_init(struct pcm
 	au_sync_delay(20);
 	  
 	return PCMCIA_NUM_SOCKS;
-
-#else /* fixme -- take care of the Pb1500 at some point */
-
-	u16 pcr;
-	pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */
-	pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
-	au_writew(pcr, PCMCIA_BOARD_REG);
-	au_sync_delay(500);
-	return PCMCIA_NUM_SOCKS;
-#endif
 }
 
 static int pb1x00_pcmcia_shutdown(void)
 {
-#ifdef CONFIG_MIPS_PB1000
 	u16 pcr;
 	pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST;
 	pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0);
@@ -96,14 +76,6 @@ static int pb1x00_pcmcia_shutdown(void)
 	au_writel(pcr, PB1000_PCR);
 	au_sync_delay(20);
 	return 0;
-#else
-	u16 pcr;
-	pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */
-	pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
-	au_writew(pcr, PCMCIA_BOARD_REG);
-	au_sync_delay(2);
-	return 0;
-#endif
 }
 
 static int 
@@ -112,21 +84,11 @@ pb1x00_pcmcia_socket_state(unsigned sock
 	u32 inserted0, inserted1;
 	u16 vs0, vs1;
 
-#ifdef CONFIG_MIPS_PB1000
 	vs0 = vs1 = (u16)au_readl(PB1000_ACR1);
 	inserted0 = !(vs0 & (ACR1_SLOT_0_CD1 | ACR1_SLOT_0_CD2));
 	inserted1 = !(vs1 & (ACR1_SLOT_1_CD1 | ACR1_SLOT_1_CD2));
 	vs0 = (vs0 >> 4) & 0x3;
 	vs1 = (vs1 >> 12) & 0x3;
-#else
-	vs0 = (au_readw(BOARD_STATUS_REG) >> 4) & 0x3;
-#ifdef CONFIG_MIPS_PB1500
-	inserted0 = !((au_readl(GPIO2_PINSTATE) >> 1) & 0x1); /* gpio 201 */
-#else /* Pb1100 */
-	inserted0 = !((au_readl(SYS_PINSTATERD) >> 9) & 0x1); /* gpio 9 */
-#endif
-	inserted1 = 0;
-#endif
 
 	state->ready = 0;
 	state->vs_Xv = 0;
@@ -203,7 +165,6 @@ pb1x00_pcmcia_configure_socket(const str
 
 	if(configure->sock > PCMCIA_MAX_SOCK) return -1;
 
-#ifdef CONFIG_MIPS_PB1000
 	pcr = au_readl(PB1000_PCR);
 
 	if (configure->sock == 0) {
@@ -323,84 +284,6 @@ pb1x00_pcmcia_configure_socket(const str
 	au_writel(pcr, PB1000_PCR);
 	au_sync_delay(300);
 
-#else
-
-	pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf;
-
-	debug("Vcc %dV Vpp %dV, pcr %x, reset %d\n", 
-			configure->vcc, configure->vpp, pcr, configure->reset);
-
-
-	switch(configure->vcc){
-		case 0:  /* Vcc 0 */
-			pcr |= SET_VCC_VPP(0,0);
-			break;
-		case 50: /* Vcc 5V */
-			switch(configure->vpp) {
-				case 0:
-					pcr |= SET_VCC_VPP(2,0);
-					break;
-				case 50:
-					pcr |= SET_VCC_VPP(2,1);
-					break;
-				case 12:
-					pcr |= SET_VCC_VPP(2,2);
-					break;
-				case 33:
-				default:
-					pcr |= SET_VCC_VPP(0,0);
-					printk("%s: bad Vcc/Vpp (%d:%d)\n", 
-							__func__,
-							configure->vcc, 
-							configure->vpp);
-					break;
-			}
-			break;
-		case 33: /* Vcc 3.3V */
-			switch(configure->vpp) {
-				case 0:
-					pcr |= SET_VCC_VPP(1,0);
-					break;
-				case 12:
-					pcr |= SET_VCC_VPP(1,2);
-					break;
-				case 33:
-					pcr |= SET_VCC_VPP(1,1);
-					break;
-				case 50:
-				default:
-					pcr |= SET_VCC_VPP(0,0);
-					printk("%s: bad Vcc/Vpp (%d:%d)\n", 
-							__func__,
-							configure->vcc, 
-							configure->vpp);
-					break;
-			}
-			break;
-		default: /* what's this ? */
-			pcr |= SET_VCC_VPP(0,0);
-			printk(KERN_ERR "%s: bad Vcc %d\n", 
-					__func__, configure->vcc);
-			break;
-	}
-
-	au_writew(pcr, PCMCIA_BOARD_REG);
-	au_sync_delay(300);
-
-	if (!configure->reset) {
-		pcr |= PC_DRV_EN;
-		au_writew(pcr, PCMCIA_BOARD_REG);
-		au_sync_delay(100);
-		pcr |= PC_DEASSERT_RST;
-		au_writew(pcr, PCMCIA_BOARD_REG);
-		au_sync_delay(100);
-	}
-	else {
-		pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
-		au_writew(pcr, PCMCIA_BOARD_REG);
-		au_sync_delay(100);
-	}
-#endif
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/au1000_xxs1500.c linux-libre-2.6.34-gnu1/drivers/pcmcia/au1000_xxs1500.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/au1000_xxs1500.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/au1000_xxs1500.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,188 +0,0 @@
-/*
- *
- * MyCable board specific pcmcia routines.
- *
- * Copyright 2003 MontaVista Software Inc.
- * Author: Pete Popov, MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- *
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/proc_fs.h>
-#include <linux/types.h>
-
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/ss.h>
-#include <pcmcia/cistpl.h>
-#include <pcmcia/bus_ops.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-
-#include <asm/au1000.h>
-#include <asm/au1000_pcmcia.h>
-
-#define PCMCIA_MAX_SOCK		0
-#define PCMCIA_NUM_SOCKS	(PCMCIA_MAX_SOCK + 1)
-#define PCMCIA_IRQ		AU1000_GPIO_4
-
-#if 0
-#define DEBUG(x, args...)	printk(__func__ ": " x, ##args)
-#else
-#define DEBUG(x,args...)
-#endif
-
-static int xxs1500_pcmcia_init(struct pcmcia_init *init)
-{
-	return PCMCIA_NUM_SOCKS;
-}
-
-static int xxs1500_pcmcia_shutdown(void)
-{
-	/* turn off power */
-	au_writel(au_readl(GPIO2_PINSTATE) | (1<<14)|(1<<30),
-			GPIO2_OUTPUT);
-	au_sync_delay(100);
-
-	/* assert reset */
-	au_writel(au_readl(GPIO2_PINSTATE) | (1<<4)|(1<<20),
-			GPIO2_OUTPUT);
-	au_sync_delay(100);
-	return 0;
-}
-
-
-static int
-xxs1500_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
-{
-	u32 inserted; u32 vs;
-	unsigned long gpio, gpio2;
-
-	if(sock > PCMCIA_MAX_SOCK) return -1;
-
-	gpio = au_readl(SYS_PINSTATERD);
-	gpio2 = au_readl(GPIO2_PINSTATE);
-
-	vs = gpio2 & ((1<<8) | (1<<9));
-	inserted = (!(gpio & 0x1) && !(gpio & 0x2));
-
-	state->ready = 0;
-	state->vs_Xv = 0;
-	state->vs_3v = 0;
-	state->detect = 0;
-
-	if (inserted) {
-		switch (vs) {
-			case 0:
-			case 1:
-			case 2:
-				state->vs_3v=1;
-				break;
-			case 3: /* 5V */
-			default:
-				/* return without setting 'detect' */
-				printk(KERN_ERR "au1x00_cs: unsupported VS\n",
-						vs);
-				return;
-		}
-		state->detect = 1;
-	}
-
-	if (state->detect) {
-		state->ready = 1;
-	}
-
-	state->bvd1= gpio2 & (1<<10);
-	state->bvd2 = gpio2 & (1<<11);
-	state->wrprot=0;
-	return 1;
-}
-
-
-static int xxs1500_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-{
-
-	if(info->sock > PCMCIA_MAX_SOCK) return -1;
-	info->irq = PCMCIA_IRQ;
-	return 0;
-}
-
-
-static int
-xxs1500_pcmcia_configure_socket(const struct pcmcia_configure *configure)
-{
-
-	if(configure->sock > PCMCIA_MAX_SOCK) return -1;
-
-	DEBUG("Vcc %dV Vpp %dV, reset %d\n",
-			configure->vcc, configure->vpp, configure->reset);
-
-	switch(configure->vcc){
-		case 33: /* Vcc 3.3V */
-			/* turn on power */
-			DEBUG("turn on power\n");
-			au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<14))|(1<<30),
-					GPIO2_OUTPUT);
-			au_sync_delay(100);
-			break;
-		case 50: /* Vcc 5V */
-		default: /* what's this ? */
-			printk(KERN_ERR "au1x00_cs: unsupported VCC\n");
-		case 0:  /* Vcc 0 */
-			/* turn off power */
-			au_sync_delay(100);
-			au_writel(au_readl(GPIO2_PINSTATE) | (1<<14)|(1<<30),
-					GPIO2_OUTPUT);
-			break;
-	}
-
-	if (!configure->reset) {
-		DEBUG("deassert reset\n");
-		au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<4))|(1<<20),
-				GPIO2_OUTPUT);
-		au_sync_delay(100);
-		au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<5))|(1<<21),
-				GPIO2_OUTPUT);
-	}
-	else {
-		DEBUG("assert reset\n");
-		au_writel(au_readl(GPIO2_PINSTATE) | (1<<4)|(1<<20),
-				GPIO2_OUTPUT);
-	}
-	au_sync_delay(100);
-	return 0;
-}
-
-struct pcmcia_low_level xxs1500_pcmcia_ops = {
-	xxs1500_pcmcia_init,
-	xxs1500_pcmcia_shutdown,
-	xxs1500_pcmcia_socket_state,
-	xxs1500_pcmcia_get_irq_info,
-	xxs1500_pcmcia_configure_socket
-};
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/bcm63xx_pcmcia.c linux-libre-2.6.34-gnu1/drivers/pcmcia/bcm63xx_pcmcia.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/bcm63xx_pcmcia.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/bcm63xx_pcmcia.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/ioport.h>
 #include <linux/timer.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/gpio.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/bfin_cf_pcmcia.c linux-libre-2.6.34-gnu1/drivers/pcmcia/bfin_cf_pcmcia.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/bfin_cf_pcmcia.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/bfin_cf_pcmcia.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/platform_device.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
@@ -205,7 +206,7 @@ static int __devinit bfin_cf_probe(struc
 	dev_info(&pdev->dev, "Blackfin CompactFlash/PCMCIA Socket Driver\n");
 
 	irq = platform_get_irq(pdev, 0);
-	if (!irq)
+	if (irq <= 0)
 		return -EINVAL;
 
 	cd_pfx = platform_get_irq(pdev, 1);	/*Card Detect GPIO PIN */
@@ -300,16 +301,6 @@ static int __devexit bfin_cf_remove(stru
 	return 0;
 }
 
-static int bfin_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
-	return pcmcia_socket_dev_suspend(&pdev->dev);
-}
-
-static int bfin_cf_resume(struct platform_device *pdev)
-{
-	return pcmcia_socket_dev_resume(&pdev->dev);
-}
-
 static struct platform_driver bfin_cf_driver = {
 	.driver = {
 		   .name = (char *)driver_name,
@@ -317,8 +308,6 @@ static struct platform_driver bfin_cf_dr
 		   },
 	.probe = bfin_cf_probe,
 	.remove = __devexit_p(bfin_cf_remove),
-	.suspend = bfin_cf_suspend,
-	.resume = bfin_cf_resume,
 };
 
 static int __init bfin_cf_init(void)
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/cardbus.c linux-libre-2.6.34-gnu1/drivers/pcmcia/cardbus.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/cardbus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/cardbus.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,170 +20,12 @@
  */
 
 
-#include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/pci.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <asm/irq.h>
 
-#include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
-#include "cs_internal.h"
 
-/*====================================================================*/
-
-/* Offsets in the Expansion ROM Image Header */
-#define ROM_SIGNATURE		0x0000	/* 2 bytes */
-#define ROM_DATA_PTR		0x0018	/* 2 bytes */
-
-/* Offsets in the CardBus PC Card Data Structure */
-#define PCDATA_SIGNATURE	0x0000	/* 4 bytes */
-#define PCDATA_VPD_PTR		0x0008	/* 2 bytes */
-#define PCDATA_LENGTH		0x000a	/* 2 bytes */
-#define PCDATA_REVISION		0x000c
-#define PCDATA_IMAGE_SZ		0x0010	/* 2 bytes */
-#define PCDATA_ROM_LEVEL	0x0012	/* 2 bytes */
-#define PCDATA_CODE_TYPE	0x0014
-#define PCDATA_INDICATOR	0x0015
-
-/*=====================================================================
-
-    Expansion ROM's have a special layout, and pointers specify an
-    image number and an offset within that image.  xlate_rom_addr()
-    converts an image/offset address to an absolute offset from the
-    ROM's base address.
-
-=====================================================================*/
-
-static u_int xlate_rom_addr(void __iomem *b, u_int addr)
-{
-	u_int img = 0, ofs = 0, sz;
-	u_short data;
-	while ((readb(b) == 0x55) && (readb(b + 1) == 0xaa)) {
-		if (img == (addr >> 28))
-			return (addr & 0x0fffffff) + ofs;
-		data = readb(b + ROM_DATA_PTR) + (readb(b + ROM_DATA_PTR + 1) << 8);
-		sz = 512 * (readb(b + data + PCDATA_IMAGE_SZ) +
-			    (readb(b + data + PCDATA_IMAGE_SZ + 1) << 8));
-		if ((sz == 0) || (readb(b + data + PCDATA_INDICATOR) & 0x80))
-			break;
-		b += sz;
-		ofs += sz;
-		img++;
-	}
-	return 0;
-}
-
-/*=====================================================================
-
-    These are similar to setup_cis_mem and release_cis_mem for 16-bit
-    cards.  The "result" that is used externally is the cb_cis_virt
-    pointer in the struct pcmcia_socket structure.
-
-=====================================================================*/
-
-static void cb_release_cis_mem(struct pcmcia_socket *s)
-{
-	if (s->cb_cis_virt) {
-		dev_dbg(&s->dev, "cb_release_cis_mem()\n");
-		iounmap(s->cb_cis_virt);
-		s->cb_cis_virt = NULL;
-		s->cb_cis_res = NULL;
-	}
-}
-
-static int cb_setup_cis_mem(struct pcmcia_socket *s, struct resource *res)
-{
-	unsigned int start, size;
-
-	if (res == s->cb_cis_res)
-		return 0;
-
-	if (s->cb_cis_res)
-		cb_release_cis_mem(s);
-
-	start = res->start;
-	size = res->end - start + 1;
-	s->cb_cis_virt = ioremap(start, size);
-
-	if (!s->cb_cis_virt)
-		return -1;
-
-	s->cb_cis_res = res;
-
-	return 0;
-}
-
-/*=====================================================================
-
-    This is used by the CIS processing code to read CIS information
-    from a CardBus device.
-
-=====================================================================*/
-
-int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len,
-		void *ptr)
-{
-	struct pci_dev *dev;
-	struct resource *res;
-
-	dev_dbg(&s->dev, "read_cb_mem(%d, %#x, %u)\n", space, addr, len);
-
-	dev = pci_get_slot(s->cb_dev->subordinate, 0);
-	if (!dev)
-		goto fail;
-
-	/* Config space? */
-	if (space == 0) {
-		if (addr + len > 0x100)
-			goto failput;
-		for (; len; addr++, ptr++, len--)
-			pci_read_config_byte(dev, addr, ptr);
-		return 0;
-	}
-
-	res = dev->resource + space - 1;
-
-	pci_dev_put(dev);
-
-	if (!res->flags)
-		goto fail;
-
-	if (cb_setup_cis_mem(s, res) != 0)
-		goto fail;
-
-	if (space == 7) {
-		addr = xlate_rom_addr(s->cb_cis_virt, addr);
-		if (addr == 0)
-			goto fail;
-	}
-
-	if (addr + len > res->end - res->start)
-		goto fail;
-
-	memcpy_fromio(ptr, s->cb_cis_virt + addr, len);
-	return 0;
-
-failput:
-	pci_dev_put(dev);
-fail:
-	memset(ptr, 0xff, len);
-	return -1;
-}
-
-/*=====================================================================
-
-    cb_alloc() and cb_free() allocate and free the kernel data
-    structures for a Cardbus device, and handle the lowest level PCI
-    device setup issues.
-
-=====================================================================*/
 
 static void cardbus_config_irq_and_cls(struct pci_bus *bus, int irq)
 {
@@ -215,6 +57,13 @@ static void cardbus_config_irq_and_cls(s
 	}
 }
 
+/**
+ * cb_alloc() - add CardBus device
+ * @s:		the pcmcia_socket where the CardBus device is located
+ *
+ * cb_alloc() allocates the kernel data structures for a Cardbus device
+ * and handles the lowest level PCI device setup issues.
+ */
 int __ref cb_alloc(struct pcmcia_socket *s)
 {
 	struct pci_bus *bus = s->cb_dev->subordinate;
@@ -222,7 +71,7 @@ int __ref cb_alloc(struct pcmcia_socket
 	unsigned int max, pass;
 
 	s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0));
-	pci_fixup_cardbus(bus); 
+	pci_fixup_cardbus(bus);
 
 	max = bus->secondary;
 	for (pass = 0; pass < 2; pass++)
@@ -249,12 +98,16 @@ int __ref cb_alloc(struct pcmcia_socket
 	return 0;
 }
 
+/**
+ * cb_free() - remove CardBus device
+ * @s:		the pcmcia_socket where the CardBus device was located
+ *
+ * cb_free() handles the lowest level PCI device cleanup.
+ */
 void cb_free(struct pcmcia_socket *s)
 {
 	struct pci_dev *bridge = s->cb_dev;
 
-	cb_release_cis_mem(s);
-
 	if (bridge)
 		pci_remove_behind_bridge(bridge);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/cistpl.c linux-libre-2.6.34-gnu1/drivers/pcmcia/cistpl.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/cistpl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/cistpl.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,43 +54,44 @@ static const u_int exponent[] = {
 /* Upper limit on reasonable # of tuples */
 #define MAX_TUPLES		200
 
-/*====================================================================*/
-
-/* Parameters that can be set with 'insmod' */
-
 /* 16-bit CIS? */
 static int cis_width;
 module_param(cis_width, int, 0444);
 
 void release_cis_mem(struct pcmcia_socket *s)
 {
-    if (s->cis_mem.flags & MAP_ACTIVE) {
-	s->cis_mem.flags &= ~MAP_ACTIVE;
-	s->ops->set_mem_map(s, &s->cis_mem);
-	if (s->cis_mem.res) {
-	    release_resource(s->cis_mem.res);
-	    kfree(s->cis_mem.res);
-	    s->cis_mem.res = NULL;
+	mutex_lock(&s->ops_mutex);
+	if (s->cis_mem.flags & MAP_ACTIVE) {
+		s->cis_mem.flags &= ~MAP_ACTIVE;
+		s->ops->set_mem_map(s, &s->cis_mem);
+		if (s->cis_mem.res) {
+			release_resource(s->cis_mem.res);
+			kfree(s->cis_mem.res);
+			s->cis_mem.res = NULL;
+		}
+		iounmap(s->cis_virt);
+		s->cis_virt = NULL;
 	}
-	iounmap(s->cis_virt);
-	s->cis_virt = NULL;
-    }
+	mutex_unlock(&s->ops_mutex);
 }
-EXPORT_SYMBOL(release_cis_mem);
 
-/*
- * Map the card memory at "card_offset" into virtual space.
+/**
+ * set_cis_map() - map the card memory at "card_offset" into virtual space.
+ *
  * If flags & MAP_ATTRIB, map the attribute space, otherwise
  * map the memory space.
+ *
+ * Must be called with ops_mutex held.
  */
-static void __iomem *
-set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags)
+static void __iomem *set_cis_map(struct pcmcia_socket *s,
+				unsigned int card_offset, unsigned int flags)
 {
 	pccard_mem_map *mem = &s->cis_mem;
 	int ret;
 
 	if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) {
-		mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s);
+		mem->res = pcmcia_find_mem_region(0, s->map_size,
+						s->map_size, 0, s);
 		if (mem->res == NULL) {
 			dev_printk(KERN_NOTICE, &s->dev,
 				   "cs: unable to map card memory!\n");
@@ -121,176 +122,200 @@ set_cis_map(struct pcmcia_socket *s, uns
 	return s->cis_virt;
 }
 
-/*======================================================================
-
-    Low-level functions to read and write CIS memory.  I think the
-    write routine is only useful for writing one-byte registers.
-
-======================================================================*/
 
 /* Bits in attr field */
 #define IS_ATTR		1
 #define IS_INDIRECT	8
 
+/**
+ * pcmcia_read_cis_mem() - low-level function to read CIS memory
+ */
 int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
 		 u_int len, void *ptr)
 {
-    void __iomem *sys, *end;
-    unsigned char *buf = ptr;
+	void __iomem *sys, *end;
+	unsigned char *buf = ptr;
 
-    dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+	dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
 
-    if (attr & IS_INDIRECT) {
-	/* Indirect accesses use a bunch of special registers at fixed
-	   locations in common memory */
-	u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
-	if (attr & IS_ATTR) {
-	    addr *= 2;
-	    flags = ICTRL0_AUTOINC;
-	}
+	mutex_lock(&s->ops_mutex);
+	if (attr & IS_INDIRECT) {
+		/* Indirect accesses use a bunch of special registers at fixed
+		   locations in common memory */
+		u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
+		if (attr & IS_ATTR) {
+			addr *= 2;
+			flags = ICTRL0_AUTOINC;
+		}
 
-	sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0));
-	if (!sys) {
-	    memset(ptr, 0xff, len);
-	    return -1;
-	}
+		sys = set_cis_map(s, 0, MAP_ACTIVE |
+				((cis_width) ? MAP_16BIT : 0));
+		if (!sys) {
+			dev_dbg(&s->dev, "could not map memory\n");
+			memset(ptr, 0xff, len);
+			mutex_unlock(&s->ops_mutex);
+			return -1;
+		}
 
-	writeb(flags, sys+CISREG_ICTRL0);
-	writeb(addr & 0xff, sys+CISREG_IADDR0);
-	writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
-	writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
-	writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
-	for ( ; len > 0; len--, buf++)
-	    *buf = readb(sys+CISREG_IDATA0);
-    } else {
-	u_int inc = 1, card_offset, flags;
+		writeb(flags, sys+CISREG_ICTRL0);
+		writeb(addr & 0xff, sys+CISREG_IADDR0);
+		writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
+		writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
+		writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
+		for ( ; len > 0; len--, buf++)
+			*buf = readb(sys+CISREG_IDATA0);
+	} else {
+		u_int inc = 1, card_offset, flags;
 
-	flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
-	if (attr) {
-	    flags |= MAP_ATTRIB;
-	    inc++;
-	    addr *= 2;
-	}
+		if (addr > CISTPL_MAX_CIS_SIZE)
+			dev_dbg(&s->dev,
+				"attempt to read CIS mem at addr %#x", addr);
 
-	card_offset = addr & ~(s->map_size-1);
-	while (len) {
-	    sys = set_cis_map(s, card_offset, flags);
-	    if (!sys) {
-		memset(ptr, 0xff, len);
-		return -1;
-	    }
-	    end = sys + s->map_size;
-	    sys = sys + (addr & (s->map_size-1));
-	    for ( ; len > 0; len--, buf++, sys += inc) {
-		if (sys == end)
-		    break;
-		*buf = readb(sys);
-	    }
-	    card_offset += s->map_size;
-	    addr = 0;
+		flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
+		if (attr) {
+			flags |= MAP_ATTRIB;
+			inc++;
+			addr *= 2;
+		}
+
+		card_offset = addr & ~(s->map_size-1);
+		while (len) {
+			sys = set_cis_map(s, card_offset, flags);
+			if (!sys) {
+				dev_dbg(&s->dev, "could not map memory\n");
+				memset(ptr, 0xff, len);
+				mutex_unlock(&s->ops_mutex);
+				return -1;
+			}
+			end = sys + s->map_size;
+			sys = sys + (addr & (s->map_size-1));
+			for ( ; len > 0; len--, buf++, sys += inc) {
+				if (sys == end)
+					break;
+				*buf = readb(sys);
+			}
+			card_offset += s->map_size;
+			addr = 0;
+		}
 	}
-    }
-    dev_dbg(&s->dev, "  %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
-	  *(u_char *)(ptr+0), *(u_char *)(ptr+1),
-	  *(u_char *)(ptr+2), *(u_char *)(ptr+3));
-    return 0;
+	mutex_unlock(&s->ops_mutex);
+	dev_dbg(&s->dev, "  %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
+		*(u_char *)(ptr+0), *(u_char *)(ptr+1),
+		*(u_char *)(ptr+2), *(u_char *)(ptr+3));
+	return 0;
 }
-EXPORT_SYMBOL(pcmcia_read_cis_mem);
 
 
+/**
+ * pcmcia_write_cis_mem() - low-level function to write CIS memory
+ *
+ * Probably only useful for writing one-byte registers.
+ */
 void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
 		   u_int len, void *ptr)
 {
-    void __iomem *sys, *end;
-    unsigned char *buf = ptr;
+	void __iomem *sys, *end;
+	unsigned char *buf = ptr;
 
-    dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+	dev_dbg(&s->dev,
+		"pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
 
-    if (attr & IS_INDIRECT) {
-	/* Indirect accesses use a bunch of special registers at fixed
-	   locations in common memory */
-	u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
-	if (attr & IS_ATTR) {
-	    addr *= 2;
-	    flags = ICTRL0_AUTOINC;
-	}
+	mutex_lock(&s->ops_mutex);
+	if (attr & IS_INDIRECT) {
+		/* Indirect accesses use a bunch of special registers at fixed
+		   locations in common memory */
+		u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
+		if (attr & IS_ATTR) {
+			addr *= 2;
+			flags = ICTRL0_AUTOINC;
+		}
 
-	sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0));
-	if (!sys)
-		return; /* FIXME: Error */
+		sys = set_cis_map(s, 0, MAP_ACTIVE |
+				((cis_width) ? MAP_16BIT : 0));
+		if (!sys) {
+			dev_dbg(&s->dev, "could not map memory\n");
+			mutex_unlock(&s->ops_mutex);
+			return; /* FIXME: Error */
+		}
 
-	writeb(flags, sys+CISREG_ICTRL0);
-	writeb(addr & 0xff, sys+CISREG_IADDR0);
-	writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
-	writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
-	writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
-	for ( ; len > 0; len--, buf++)
-	    writeb(*buf, sys+CISREG_IDATA0);
-    } else {
-	u_int inc = 1, card_offset, flags;
+		writeb(flags, sys+CISREG_ICTRL0);
+		writeb(addr & 0xff, sys+CISREG_IADDR0);
+		writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
+		writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
+		writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
+		for ( ; len > 0; len--, buf++)
+			writeb(*buf, sys+CISREG_IDATA0);
+	} else {
+		u_int inc = 1, card_offset, flags;
 
-	flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
-	if (attr & IS_ATTR) {
-	    flags |= MAP_ATTRIB;
-	    inc++;
-	    addr *= 2;
-	}
+		flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
+		if (attr & IS_ATTR) {
+			flags |= MAP_ATTRIB;
+			inc++;
+			addr *= 2;
+		}
 
-	card_offset = addr & ~(s->map_size-1);
-	while (len) {
-	    sys = set_cis_map(s, card_offset, flags);
-	    if (!sys)
-		return; /* FIXME: error */
+		card_offset = addr & ~(s->map_size-1);
+		while (len) {
+			sys = set_cis_map(s, card_offset, flags);
+			if (!sys) {
+				dev_dbg(&s->dev, "could not map memory\n");
+				mutex_unlock(&s->ops_mutex);
+				return; /* FIXME: error */
+			}
 
-	    end = sys + s->map_size;
-	    sys = sys + (addr & (s->map_size-1));
-	    for ( ; len > 0; len--, buf++, sys += inc) {
-		if (sys == end)
-		    break;
-		writeb(*buf, sys);
-	    }
-	    card_offset += s->map_size;
-	    addr = 0;
+			end = sys + s->map_size;
+			sys = sys + (addr & (s->map_size-1));
+			for ( ; len > 0; len--, buf++, sys += inc) {
+				if (sys == end)
+					break;
+				writeb(*buf, sys);
+			}
+			card_offset += s->map_size;
+			addr = 0;
+		}
 	}
-    }
+	mutex_unlock(&s->ops_mutex);
 }
-EXPORT_SYMBOL(pcmcia_write_cis_mem);
-
-
-/*======================================================================
-
-    This is a wrapper around read_cis_mem, with the same interface,
-    but which caches information, for cards whose CIS may not be
-    readable all the time.
 
-======================================================================*/
 
-static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
-			   size_t len, void *ptr)
+/**
+ * read_cis_cache() - read CIS memory or its associated cache
+ *
+ * This is a wrapper around read_cis_mem, with the same interface,
+ * but which caches information, for cards whose CIS may not be
+ * readable all the time.
+ */
+static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
+			size_t len, void *ptr)
 {
-    struct cis_cache_entry *cis;
-    int ret;
+	struct cis_cache_entry *cis;
+	int ret = 0;
 
-    if (s->fake_cis) {
-	if (s->fake_cis_len >= addr+len)
-	    memcpy(ptr, s->fake_cis+addr, len);
-	else
-	    memset(ptr, 0xff, len);
-	return;
-    }
+	if (s->state & SOCKET_CARDBUS)
+		return -EINVAL;
 
-    list_for_each_entry(cis, &s->cis_cache, node) {
-	if (cis->addr == addr && cis->len == len && cis->attr == attr) {
-	    memcpy(ptr, cis->cache, len);
-	    return;
+	mutex_lock(&s->ops_mutex);
+	if (s->fake_cis) {
+		if (s->fake_cis_len >= addr+len)
+			memcpy(ptr, s->fake_cis+addr, len);
+		else {
+			memset(ptr, 0xff, len);
+			ret = -EINVAL;
+		}
+		mutex_unlock(&s->ops_mutex);
+		return ret;
 	}
-    }
 
-#ifdef CONFIG_CARDBUS
-    if (s->state & SOCKET_CARDBUS)
-	ret = read_cb_mem(s, attr, addr, len, ptr);
-    else
-#endif
+	list_for_each_entry(cis, &s->cis_cache, node) {
+		if (cis->addr == addr && cis->len == len && cis->attr == attr) {
+			memcpy(ptr, cis->cache, len);
+			mutex_unlock(&s->ops_mutex);
+			return 0;
+		}
+	}
+	mutex_unlock(&s->ops_mutex);
+
 	ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr);
 
 	if (ret == 0) {
@@ -301,9 +326,12 @@ static void read_cis_cache(struct pcmcia
 			cis->len = len;
 			cis->attr = attr;
 			memcpy(cis->cache, ptr, len);
+			mutex_lock(&s->ops_mutex);
 			list_add(&cis->node, &s->cis_cache);
+			mutex_unlock(&s->ops_mutex);
 		}
 	}
+	return ret;
 }
 
 static void
@@ -311,44 +339,46 @@ remove_cis_cache(struct pcmcia_socket *s
 {
 	struct cis_cache_entry *cis;
 
+	mutex_lock(&s->ops_mutex);
 	list_for_each_entry(cis, &s->cis_cache, node)
 		if (cis->addr == addr && cis->len == len && cis->attr == attr) {
 			list_del(&cis->node);
 			kfree(cis);
 			break;
 		}
+	mutex_unlock(&s->ops_mutex);
 }
 
+/**
+ * destroy_cis_cache() - destroy the CIS cache
+ * @s:		pcmcia_socket for which CIS cache shall be destroyed
+ *
+ * This destroys the CIS cache but keeps any fake CIS alive. Must be
+ * called with ops_mutex held.
+ */
 void destroy_cis_cache(struct pcmcia_socket *s)
 {
 	struct list_head *l, *n;
+	struct cis_cache_entry *cis;
 
 	list_for_each_safe(l, n, &s->cis_cache) {
-		struct cis_cache_entry *cis = list_entry(l, struct cis_cache_entry, node);
-
+		cis = list_entry(l, struct cis_cache_entry, node);
 		list_del(&cis->node);
 		kfree(cis);
 	}
-
-	/*
-	 * If there was a fake CIS, destroy that as well.
-	 */
-	kfree(s->fake_cis);
-	s->fake_cis = NULL;
 }
-EXPORT_SYMBOL(destroy_cis_cache);
-
-/*======================================================================
-
-    This verifies if the CIS of a card matches what is in the CIS
-    cache.
-
-======================================================================*/
 
+/**
+ * verify_cis_cache() - does the CIS match what is in the CIS cache?
+ */
 int verify_cis_cache(struct pcmcia_socket *s)
 {
 	struct cis_cache_entry *cis;
 	char *buf;
+	int ret;
+
+	if (s->state & SOCKET_CARDBUS)
+		return -EINVAL;
 
 	buf = kmalloc(256, GFP_KERNEL);
 	if (buf == NULL) {
@@ -361,14 +391,9 @@ int verify_cis_cache(struct pcmcia_socke
 
 		if (len > 256)
 			len = 256;
-#ifdef CONFIG_CARDBUS
-		if (s->state & SOCKET_CARDBUS)
-			read_cb_mem(s, cis->attr, cis->addr, len, buf);
-		else
-#endif
-			pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
 
-		if (memcmp(buf, cis->cache, len) != 0) {
+		ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
+		if (ret || memcmp(buf, cis->cache, len) != 0) {
 			kfree(buf);
 			return -1;
 		}
@@ -377,13 +402,12 @@ int verify_cis_cache(struct pcmcia_socke
 	return 0;
 }
 
-/*======================================================================
-
-    For really bad cards, we provide a facility for uploading a
-    replacement CIS.
-
-======================================================================*/
-
+/**
+ * pcmcia_replace_cis() - use a replacement CIS instead of the card's CIS
+ *
+ * For really bad cards, we provide a facility for uploading a
+ * replacement CIS.
+ */
 int pcmcia_replace_cis(struct pcmcia_socket *s,
 		       const u8 *data, const size_t len)
 {
@@ -391,29 +415,28 @@ int pcmcia_replace_cis(struct pcmcia_soc
 		dev_printk(KERN_WARNING, &s->dev, "replacement CIS too big\n");
 		return -EINVAL;
 	}
+	mutex_lock(&s->ops_mutex);
 	kfree(s->fake_cis);
 	s->fake_cis = kmalloc(len, GFP_KERNEL);
 	if (s->fake_cis == NULL) {
 		dev_printk(KERN_WARNING, &s->dev, "no memory to replace CIS\n");
+		mutex_unlock(&s->ops_mutex);
 		return -ENOMEM;
 	}
 	s->fake_cis_len = len;
 	memcpy(s->fake_cis, data, len);
+	dev_info(&s->dev, "Using replacement CIS\n");
+	mutex_unlock(&s->ops_mutex);
 	return 0;
 }
-EXPORT_SYMBOL(pcmcia_replace_cis);
 
-/*======================================================================
-
-    The high-level CIS tuple services
-
-======================================================================*/
+/* The high-level CIS tuple services */
 
 typedef struct tuple_flags {
-    u_int		link_space:4;
-    u_int		has_link:1;
-    u_int		mfc_fn:3;
-    u_int		space:4;
+	u_int		link_space:4;
+	u_int		has_link:1;
+	u_int		mfc_fn:3;
+	u_int		space:4;
 } tuple_flags;
 
 #define LINK_SPACE(f)	(((tuple_flags *)(&(f)))->link_space)
@@ -421,1099 +444,962 @@ typedef struct tuple_flags {
 #define MFC_FN(f)	(((tuple_flags *)(&(f)))->mfc_fn)
 #define SPACE(f)	(((tuple_flags *)(&(f)))->space)
 
-int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple)
+int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
+			tuple_t *tuple)
 {
-    if (!s)
-	return -EINVAL;
-    if (!(s->state & SOCKET_PRESENT))
-	return -ENODEV;
-    tuple->TupleLink = tuple->Flags = 0;
-#ifdef CONFIG_CARDBUS
-    if (s->state & SOCKET_CARDBUS) {
-	struct pci_dev *dev = s->cb_dev;
-	u_int ptr;
-	pci_bus_read_config_dword(dev->subordinate, 0, PCI_CARDBUS_CIS, &ptr);
-	tuple->CISOffset = ptr & ~7;
-	SPACE(tuple->Flags) = (ptr & 7);
-    } else
-#endif
-    {
+	if (!s)
+		return -EINVAL;
+
+	if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
+		return -ENODEV;
+	tuple->TupleLink = tuple->Flags = 0;
+
 	/* Assume presence of a LONGLINK_C to address 0 */
 	tuple->CISOffset = tuple->LinkOffset = 0;
 	SPACE(tuple->Flags) = HAS_LINK(tuple->Flags) = 1;
-    }
-    if (!(s->state & SOCKET_CARDBUS) && (s->functions > 1) &&
-	!(tuple->Attributes & TUPLE_RETURN_COMMON)) {
-	cisdata_t req = tuple->DesiredTuple;
-	tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
-	if (pccard_get_next_tuple(s, function, tuple) == 0) {
-	    tuple->DesiredTuple = CISTPL_LINKTARGET;
-	    if (pccard_get_next_tuple(s, function, tuple) != 0)
-		return -ENOSPC;
-	} else
-	    tuple->CISOffset = tuple->TupleLink = 0;
-	tuple->DesiredTuple = req;
-    }
-    return pccard_get_next_tuple(s, function, tuple);
+
+	if ((s->functions > 1) && !(tuple->Attributes & TUPLE_RETURN_COMMON)) {
+		cisdata_t req = tuple->DesiredTuple;
+		tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
+		if (pccard_get_next_tuple(s, function, tuple) == 0) {
+			tuple->DesiredTuple = CISTPL_LINKTARGET;
+			if (pccard_get_next_tuple(s, function, tuple) != 0)
+				return -ENOSPC;
+		} else
+			tuple->CISOffset = tuple->TupleLink = 0;
+		tuple->DesiredTuple = req;
+	}
+	return pccard_get_next_tuple(s, function, tuple);
 }
-EXPORT_SYMBOL(pccard_get_first_tuple);
 
 static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
 {
-    u_char link[5];
-    u_int ofs;
+	u_char link[5];
+	u_int ofs;
+	int ret;
 
-    if (MFC_FN(tuple->Flags)) {
-	/* Get indirect link from the MFC tuple */
-	read_cis_cache(s, LINK_SPACE(tuple->Flags),
-		       tuple->LinkOffset, 5, link);
-	ofs = get_unaligned_le32(link + 1);
-	SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
-	/* Move to the next indirect link */
-	tuple->LinkOffset += 5;
-	MFC_FN(tuple->Flags)--;
-    } else if (HAS_LINK(tuple->Flags)) {
-	ofs = tuple->LinkOffset;
-	SPACE(tuple->Flags) = LINK_SPACE(tuple->Flags);
-	HAS_LINK(tuple->Flags) = 0;
-    } else {
-	return -1;
-    }
-    if (!(s->state & SOCKET_CARDBUS) && SPACE(tuple->Flags)) {
-	/* This is ugly, but a common CIS error is to code the long
-	   link offset incorrectly, so we check the right spot... */
-	read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
+	if (MFC_FN(tuple->Flags)) {
+		/* Get indirect link from the MFC tuple */
+		ret = read_cis_cache(s, LINK_SPACE(tuple->Flags),
+				tuple->LinkOffset, 5, link);
+		if (ret)
+			return -1;
+		ofs = get_unaligned_le32(link + 1);
+		SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
+		/* Move to the next indirect link */
+		tuple->LinkOffset += 5;
+		MFC_FN(tuple->Flags)--;
+	} else if (HAS_LINK(tuple->Flags)) {
+		ofs = tuple->LinkOffset;
+		SPACE(tuple->Flags) = LINK_SPACE(tuple->Flags);
+		HAS_LINK(tuple->Flags) = 0;
+	} else
+		return -1;
+
+	if (SPACE(tuple->Flags)) {
+		/* This is ugly, but a common CIS error is to code the long
+		   link offset incorrectly, so we check the right spot... */
+		ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
+		if (ret)
+			return -1;
+		if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
+			(strncmp(link+2, "CIS", 3) == 0))
+			return ofs;
+		remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
+		/* Then, we try the wrong spot... */
+		ofs = ofs >> 1;
+	}
+	ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
+	if (ret)
+		return -1;
 	if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
-	    (strncmp(link+2, "CIS", 3) == 0))
-	    return ofs;
+		(strncmp(link+2, "CIS", 3) == 0))
+		return ofs;
 	remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
-	/* Then, we try the wrong spot... */
-	ofs = ofs >> 1;
-    }
-    read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
-    if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
-	(strncmp(link+2, "CIS", 3) == 0))
-	return ofs;
-    remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
-    return -1;
+	return -1;
 }
 
-int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple)
+int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
+			tuple_t *tuple)
 {
-    u_char link[2], tmp;
-    int ofs, i, attr;
-
-    if (!s)
-	return -EINVAL;
-    if (!(s->state & SOCKET_PRESENT))
-	return -ENODEV;
-
-    link[1] = tuple->TupleLink;
-    ofs = tuple->CISOffset + tuple->TupleLink;
-    attr = SPACE(tuple->Flags);
+	u_char link[2], tmp;
+	int ofs, i, attr;
+	int ret;
 
-    for (i = 0; i < MAX_TUPLES; i++) {
-	if (link[1] == 0xff) {
-	    link[0] = CISTPL_END;
-	} else {
-	    read_cis_cache(s, attr, ofs, 2, link);
-	    if (link[0] == CISTPL_NULL) {
-		ofs++; continue;
-	    }
-	}
+	if (!s)
+		return -EINVAL;
+	if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
+		return -ENODEV;
 
-	/* End of chain?  Follow long link if possible */
-	if (link[0] == CISTPL_END) {
-	    ofs = follow_link(s, tuple);
-	    if (ofs < 0)
-		return -ENOSPC;
-	    attr = SPACE(tuple->Flags);
-	    read_cis_cache(s, attr, ofs, 2, link);
-	}
+	link[1] = tuple->TupleLink;
+	ofs = tuple->CISOffset + tuple->TupleLink;
+	attr = SPACE(tuple->Flags);
 
-	/* Is this a link tuple?  Make a note of it */
-	if ((link[0] == CISTPL_LONGLINK_A) ||
-	    (link[0] == CISTPL_LONGLINK_C) ||
-	    (link[0] == CISTPL_LONGLINK_MFC) ||
-	    (link[0] == CISTPL_LINKTARGET) ||
-	    (link[0] == CISTPL_INDIRECT) ||
-	    (link[0] == CISTPL_NO_LINK)) {
-	    switch (link[0]) {
-	    case CISTPL_LONGLINK_A:
-		HAS_LINK(tuple->Flags) = 1;
-		LINK_SPACE(tuple->Flags) = attr | IS_ATTR;
-		read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset);
-		break;
-	    case CISTPL_LONGLINK_C:
-		HAS_LINK(tuple->Flags) = 1;
-		LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR;
-		read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset);
-		break;
-	    case CISTPL_INDIRECT:
-		HAS_LINK(tuple->Flags) = 1;
-		LINK_SPACE(tuple->Flags) = IS_ATTR | IS_INDIRECT;
-		tuple->LinkOffset = 0;
-		break;
-	    case CISTPL_LONGLINK_MFC:
-		tuple->LinkOffset = ofs + 3;
-		LINK_SPACE(tuple->Flags) = attr;
-		if (function == BIND_FN_ALL) {
-		    /* Follow all the MFC links */
-		    read_cis_cache(s, attr, ofs+2, 1, &tmp);
-		    MFC_FN(tuple->Flags) = tmp;
-		} else {
-		    /* Follow exactly one of the links */
-		    MFC_FN(tuple->Flags) = 1;
-		    tuple->LinkOffset += function * 5;
+	for (i = 0; i < MAX_TUPLES; i++) {
+		if (link[1] == 0xff)
+			link[0] = CISTPL_END;
+		else {
+			ret = read_cis_cache(s, attr, ofs, 2, link);
+			if (ret)
+				return -1;
+			if (link[0] == CISTPL_NULL) {
+				ofs++;
+				continue;
+			}
 		}
-		break;
-	    case CISTPL_NO_LINK:
-		HAS_LINK(tuple->Flags) = 0;
-		break;
-	    }
-	    if ((tuple->Attributes & TUPLE_RETURN_LINK) &&
-		(tuple->DesiredTuple == RETURN_FIRST_TUPLE))
-		break;
-	} else
-	    if (tuple->DesiredTuple == RETURN_FIRST_TUPLE)
-		break;
 
-	if (link[0] == tuple->DesiredTuple)
-	    break;
-	ofs += link[1] + 2;
-    }
-    if (i == MAX_TUPLES) {
-	dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n");
-	return -ENOSPC;
-    }
+		/* End of chain?  Follow long link if possible */
+		if (link[0] == CISTPL_END) {
+			ofs = follow_link(s, tuple);
+			if (ofs < 0)
+				return -ENOSPC;
+			attr = SPACE(tuple->Flags);
+			ret = read_cis_cache(s, attr, ofs, 2, link);
+			if (ret)
+				return -1;
+		}
 
-    tuple->TupleCode = link[0];
-    tuple->TupleLink = link[1];
-    tuple->CISOffset = ofs + 2;
-    return 0;
-}
-EXPORT_SYMBOL(pccard_get_next_tuple);
+		/* Is this a link tuple?  Make a note of it */
+		if ((link[0] == CISTPL_LONGLINK_A) ||
+			(link[0] == CISTPL_LONGLINK_C) ||
+			(link[0] == CISTPL_LONGLINK_MFC) ||
+			(link[0] == CISTPL_LINKTARGET) ||
+			(link[0] == CISTPL_INDIRECT) ||
+			(link[0] == CISTPL_NO_LINK)) {
+			switch (link[0]) {
+			case CISTPL_LONGLINK_A:
+				HAS_LINK(tuple->Flags) = 1;
+				LINK_SPACE(tuple->Flags) = attr | IS_ATTR;
+				ret = read_cis_cache(s, attr, ofs+2, 4,
+						&tuple->LinkOffset);
+				if (ret)
+					return -1;
+				break;
+			case CISTPL_LONGLINK_C:
+				HAS_LINK(tuple->Flags) = 1;
+				LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR;
+				ret = read_cis_cache(s, attr, ofs+2, 4,
+						&tuple->LinkOffset);
+				if (ret)
+					return -1;
+				break;
+			case CISTPL_INDIRECT:
+				HAS_LINK(tuple->Flags) = 1;
+				LINK_SPACE(tuple->Flags) = IS_ATTR |
+					IS_INDIRECT;
+				tuple->LinkOffset = 0;
+				break;
+			case CISTPL_LONGLINK_MFC:
+				tuple->LinkOffset = ofs + 3;
+				LINK_SPACE(tuple->Flags) = attr;
+				if (function == BIND_FN_ALL) {
+					/* Follow all the MFC links */
+					ret = read_cis_cache(s, attr, ofs+2,
+							1, &tmp);
+					if (ret)
+						return -1;
+					MFC_FN(tuple->Flags) = tmp;
+				} else {
+					/* Follow exactly one of the links */
+					MFC_FN(tuple->Flags) = 1;
+					tuple->LinkOffset += function * 5;
+				}
+				break;
+			case CISTPL_NO_LINK:
+				HAS_LINK(tuple->Flags) = 0;
+				break;
+			}
+			if ((tuple->Attributes & TUPLE_RETURN_LINK) &&
+				(tuple->DesiredTuple == RETURN_FIRST_TUPLE))
+				break;
+		} else
+			if (tuple->DesiredTuple == RETURN_FIRST_TUPLE)
+				break;
 
-/*====================================================================*/
+		if (link[0] == tuple->DesiredTuple)
+			break;
+		ofs += link[1] + 2;
+	}
+	if (i == MAX_TUPLES) {
+		dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n");
+		return -ENOSPC;
+	}
 
-#define _MIN(a, b)		(((a) < (b)) ? (a) : (b))
+	tuple->TupleCode = link[0];
+	tuple->TupleLink = link[1];
+	tuple->CISOffset = ofs + 2;
+	return 0;
+}
 
 int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
 {
-    u_int len;
+	u_int len;
+	int ret;
 
-    if (!s)
-	return -EINVAL;
+	if (!s)
+		return -EINVAL;
 
-    if (tuple->TupleLink < tuple->TupleOffset)
-	return -ENOSPC;
-    len = tuple->TupleLink - tuple->TupleOffset;
-    tuple->TupleDataLen = tuple->TupleLink;
-    if (len == 0)
+	if (tuple->TupleLink < tuple->TupleOffset)
+		return -ENOSPC;
+	len = tuple->TupleLink - tuple->TupleOffset;
+	tuple->TupleDataLen = tuple->TupleLink;
+	if (len == 0)
+		return 0;
+	ret = read_cis_cache(s, SPACE(tuple->Flags),
+			tuple->CISOffset + tuple->TupleOffset,
+			min(len, (u_int) tuple->TupleDataMax),
+			tuple->TupleData);
+	if (ret)
+		return -1;
 	return 0;
-    read_cis_cache(s, SPACE(tuple->Flags),
-		   tuple->CISOffset + tuple->TupleOffset,
-		   _MIN(len, tuple->TupleDataMax), tuple->TupleData);
-    return 0;
 }
-EXPORT_SYMBOL(pccard_get_tuple_data);
-
 
-/*======================================================================
-
-    Parsing routines for individual tuples
 
-======================================================================*/
+/* Parsing routines for individual tuples */
 
 static int parse_device(tuple_t *tuple, cistpl_device_t *device)
 {
-    int i;
-    u_char scale;
-    u_char *p, *q;
+	int i;
+	u_char scale;
+	u_char *p, *q;
 
-    p = (u_char *)tuple->TupleData;
-    q = p + tuple->TupleDataLen;
+	p = (u_char *)tuple->TupleData;
+	q = p + tuple->TupleDataLen;
 
-    device->ndev = 0;
-    for (i = 0; i < CISTPL_MAX_DEVICES; i++) {
+	device->ndev = 0;
+	for (i = 0; i < CISTPL_MAX_DEVICES; i++) {
 
-	if (*p == 0xff)
-		break;
-	device->dev[i].type = (*p >> 4);
-	device->dev[i].wp = (*p & 0x08) ? 1 : 0;
-	switch (*p & 0x07) {
-	case 0:
-		device->dev[i].speed = 0;
-		break;
-	case 1:
-		device->dev[i].speed = 250;
-		break;
-	case 2:
-		device->dev[i].speed = 200;
-		break;
-	case 3:
-		device->dev[i].speed = 150;
-		break;
-	case 4:
-		device->dev[i].speed = 100;
-		break;
-	case 7:
-		if (++p == q)
-			return -EINVAL;
-		device->dev[i].speed = SPEED_CVT(*p);
-		while (*p & 0x80)
+		if (*p == 0xff)
+			break;
+		device->dev[i].type = (*p >> 4);
+		device->dev[i].wp = (*p & 0x08) ? 1 : 0;
+		switch (*p & 0x07) {
+		case 0:
+			device->dev[i].speed = 0;
+			break;
+		case 1:
+			device->dev[i].speed = 250;
+			break;
+		case 2:
+			device->dev[i].speed = 200;
+			break;
+		case 3:
+			device->dev[i].speed = 150;
+			break;
+		case 4:
+			device->dev[i].speed = 100;
+			break;
+		case 7:
 			if (++p == q)
 				return -EINVAL;
-		break;
-	default:
-		return -EINVAL;
-	}
+			device->dev[i].speed = SPEED_CVT(*p);
+			while (*p & 0x80)
+				if (++p == q)
+					return -EINVAL;
+			break;
+		default:
+			return -EINVAL;
+		}
 
-	if (++p == q)
-		return -EINVAL;
-	if (*p == 0xff)
-		break;
-	scale = *p & 7;
-	if (scale == 7)
-		return -EINVAL;
-	device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2));
-	device->ndev++;
-	if (++p == q)
-		break;
-    }
+		if (++p == q)
+			return -EINVAL;
+		if (*p == 0xff)
+			break;
+		scale = *p & 7;
+		if (scale == 7)
+			return -EINVAL;
+		device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2));
+		device->ndev++;
+		if (++p == q)
+			break;
+	}
 
-    return 0;
+	return 0;
 }
 
-/*====================================================================*/
 
 static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
 {
-    u_char *p;
-    if (tuple->TupleDataLen < 5)
-	return -EINVAL;
-    p = (u_char *) tuple->TupleData;
-    csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2;
-    csum->len = get_unaligned_le16(p + 2);
-    csum->sum = *(p + 4);
-    return 0;
+	u_char *p;
+	if (tuple->TupleDataLen < 5)
+		return -EINVAL;
+	p = (u_char *) tuple->TupleData;
+	csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2;
+	csum->len = get_unaligned_le16(p + 2);
+	csum->sum = *(p + 4);
+	return 0;
 }
 
-/*====================================================================*/
 
 static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
 {
-    if (tuple->TupleDataLen < 4)
-	return -EINVAL;
-    link->addr = get_unaligned_le32(tuple->TupleData);
-    return 0;
+	if (tuple->TupleDataLen < 4)
+		return -EINVAL;
+	link->addr = get_unaligned_le32(tuple->TupleData);
+	return 0;
 }
 
-/*====================================================================*/
 
-static int parse_longlink_mfc(tuple_t *tuple,
-			      cistpl_longlink_mfc_t *link)
+static int parse_longlink_mfc(tuple_t *tuple, cistpl_longlink_mfc_t *link)
 {
-    u_char *p;
-    int i;
+	u_char *p;
+	int i;
 
-    p = (u_char *)tuple->TupleData;
+	p = (u_char *)tuple->TupleData;
 
-    link->nfn = *p; p++;
-    if (tuple->TupleDataLen <= link->nfn*5)
-	return -EINVAL;
-    for (i = 0; i < link->nfn; i++) {
-	link->fn[i].space = *p; p++;
-	link->fn[i].addr = get_unaligned_le32(p);
-	p += 4;
-    }
-    return 0;
+	link->nfn = *p; p++;
+	if (tuple->TupleDataLen <= link->nfn*5)
+		return -EINVAL;
+	for (i = 0; i < link->nfn; i++) {
+		link->fn[i].space = *p; p++;
+		link->fn[i].addr = get_unaligned_le32(p);
+		p += 4;
+	}
+	return 0;
 }
 
-/*====================================================================*/
 
 static int parse_strings(u_char *p, u_char *q, int max,
 			 char *s, u_char *ofs, u_char *found)
 {
-    int i, j, ns;
+	int i, j, ns;
 
-    if (p == q)
-	    return -EINVAL;
-    ns = 0; j = 0;
-    for (i = 0; i < max; i++) {
-	if (*p == 0xff)
-		break;
-	ofs[i] = j;
-	ns++;
-	for (;;) {
-	    s[j++] = (*p == 0xff) ? '\0' : *p;
-	    if ((*p == '\0') || (*p == 0xff))
-		    break;
-	    if (++p == q)
-		    return -EINVAL;
+	if (p == q)
+		return -EINVAL;
+	ns = 0; j = 0;
+	for (i = 0; i < max; i++) {
+		if (*p == 0xff)
+			break;
+		ofs[i] = j;
+		ns++;
+		for (;;) {
+			s[j++] = (*p == 0xff) ? '\0' : *p;
+			if ((*p == '\0') || (*p == 0xff))
+				break;
+			if (++p == q)
+				return -EINVAL;
+		}
+		if ((*p == 0xff) || (++p == q))
+			break;
 	}
-	if ((*p == 0xff) || (++p == q))
-		break;
-    }
-    if (found) {
-	*found = ns;
-	return 0;
-    } else {
+	if (found) {
+		*found = ns;
+		return 0;
+	}
+
 	return (ns == max) ? 0 : -EINVAL;
-    }
 }
 
-/*====================================================================*/
 
 static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1)
 {
-    u_char *p, *q;
+	u_char *p, *q;
 
-    p = (u_char *)tuple->TupleData;
-    q = p + tuple->TupleDataLen;
+	p = (u_char *)tuple->TupleData;
+	q = p + tuple->TupleDataLen;
 
-    vers_1->major = *p; p++;
-    vers_1->minor = *p; p++;
-    if (p >= q)
-	    return -EINVAL;
+	vers_1->major = *p; p++;
+	vers_1->minor = *p; p++;
+	if (p >= q)
+		return -EINVAL;
 
-    return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS,
-			 vers_1->str, vers_1->ofs, &vers_1->ns);
+	return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS,
+			vers_1->str, vers_1->ofs, &vers_1->ns);
 }
 
-/*====================================================================*/
 
 static int parse_altstr(tuple_t *tuple, cistpl_altstr_t *altstr)
 {
-    u_char *p, *q;
+	u_char *p, *q;
 
-    p = (u_char *)tuple->TupleData;
-    q = p + tuple->TupleDataLen;
+	p = (u_char *)tuple->TupleData;
+	q = p + tuple->TupleDataLen;
 
-    return parse_strings(p, q, CISTPL_MAX_ALTSTR_STRINGS,
-			 altstr->str, altstr->ofs, &altstr->ns);
+	return parse_strings(p, q, CISTPL_MAX_ALTSTR_STRINGS,
+			altstr->str, altstr->ofs, &altstr->ns);
 }
 
-/*====================================================================*/
 
 static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
 {
-    u_char *p, *q;
-    int nid;
+	u_char *p, *q;
+	int nid;
 
-    p = (u_char *)tuple->TupleData;
-    q = p + tuple->TupleDataLen;
+	p = (u_char *)tuple->TupleData;
+	q = p + tuple->TupleDataLen;
 
-    for (nid = 0; nid < CISTPL_MAX_DEVICES; nid++) {
-	if (p > q-2)
-		break;
-	jedec->id[nid].mfr = p[0];
-	jedec->id[nid].info = p[1];
-	p += 2;
-    }
-    jedec->nid = nid;
-    return 0;
+	for (nid = 0; nid < CISTPL_MAX_DEVICES; nid++) {
+		if (p > q-2)
+			break;
+		jedec->id[nid].mfr = p[0];
+		jedec->id[nid].info = p[1];
+		p += 2;
+	}
+	jedec->nid = nid;
+	return 0;
 }
 
-/*====================================================================*/
 
 static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
 {
-    if (tuple->TupleDataLen < 4)
-	return -EINVAL;
-    m->manf = get_unaligned_le16(tuple->TupleData);
-    m->card = get_unaligned_le16(tuple->TupleData + 2);
-    return 0;
+	if (tuple->TupleDataLen < 4)
+		return -EINVAL;
+	m->manf = get_unaligned_le16(tuple->TupleData);
+	m->card = get_unaligned_le16(tuple->TupleData + 2);
+	return 0;
 }
 
-/*====================================================================*/
 
 static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f)
 {
-    u_char *p;
-    if (tuple->TupleDataLen < 2)
-	return -EINVAL;
-    p = (u_char *)tuple->TupleData;
-    f->func = p[0];
-    f->sysinit = p[1];
-    return 0;
+	u_char *p;
+	if (tuple->TupleDataLen < 2)
+		return -EINVAL;
+	p = (u_char *)tuple->TupleData;
+	f->func = p[0];
+	f->sysinit = p[1];
+	return 0;
 }
 
-/*====================================================================*/
 
 static int parse_funce(tuple_t *tuple, cistpl_funce_t *f)
 {
-    u_char *p;
-    int i;
-    if (tuple->TupleDataLen < 1)
-	return -EINVAL;
-    p = (u_char *)tuple->TupleData;
-    f->type = p[0];
-    for (i = 1; i < tuple->TupleDataLen; i++)
-	f->data[i-1] = p[i];
-    return 0;
+	u_char *p;
+	int i;
+	if (tuple->TupleDataLen < 1)
+		return -EINVAL;
+	p = (u_char *)tuple->TupleData;
+	f->type = p[0];
+	for (i = 1; i < tuple->TupleDataLen; i++)
+		f->data[i-1] = p[i];
+	return 0;
 }
 
-/*====================================================================*/
 
 static int parse_config(tuple_t *tuple, cistpl_config_t *config)
 {
-    int rasz, rmsz, i;
-    u_char *p;
+	int rasz, rmsz, i;
+	u_char *p;
 
-    p = (u_char *)tuple->TupleData;
-    rasz = *p & 0x03;
-    rmsz = (*p & 0x3c) >> 2;
-    if (tuple->TupleDataLen < rasz+rmsz+4)
-	return -EINVAL;
-    config->last_idx = *(++p);
-    p++;
-    config->base = 0;
-    for (i = 0; i <= rasz; i++)
-	config->base += p[i] << (8*i);
-    p += rasz+1;
-    for (i = 0; i < 4; i++)
-	config->rmask[i] = 0;
-    for (i = 0; i <= rmsz; i++)
-	config->rmask[i>>2] += p[i] << (8*(i%4));
-    config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4);
-    return 0;
+	p = (u_char *)tuple->TupleData;
+	rasz = *p & 0x03;
+	rmsz = (*p & 0x3c) >> 2;
+	if (tuple->TupleDataLen < rasz+rmsz+4)
+		return -EINVAL;
+	config->last_idx = *(++p);
+	p++;
+	config->base = 0;
+	for (i = 0; i <= rasz; i++)
+		config->base += p[i] << (8*i);
+	p += rasz+1;
+	for (i = 0; i < 4; i++)
+		config->rmask[i] = 0;
+	for (i = 0; i <= rmsz; i++)
+		config->rmask[i>>2] += p[i] << (8*(i%4));
+	config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4);
+	return 0;
 }
 
-/*======================================================================
-
-    The following routines are all used to parse the nightmarish
-    config table entries.
-
-======================================================================*/
+/* The following routines are all used to parse the nightmarish
+ * config table entries.
+ */
 
-static u_char *parse_power(u_char *p, u_char *q,
-			   cistpl_power_t *pwr)
+static u_char *parse_power(u_char *p, u_char *q, cistpl_power_t *pwr)
 {
-    int i;
-    u_int scale;
+	int i;
+	u_int scale;
 
-    if (p == q)
-	    return NULL;
-    pwr->present = *p;
-    pwr->flags = 0;
-    p++;
-    for (i = 0; i < 7; i++)
-	if (pwr->present & (1<<i)) {
-	    if (p == q)
-		    return NULL;
-	    pwr->param[i] = POWER_CVT(*p);
-	    scale = POWER_SCALE(*p);
-	    while (*p & 0x80) {
-		if (++p == q)
-			return NULL;
-		if ((*p & 0x7f) < 100)
-		    pwr->param[i] += (*p & 0x7f) * scale / 100;
-		else if (*p == 0x7d)
-		    pwr->flags |= CISTPL_POWER_HIGHZ_OK;
-		else if (*p == 0x7e)
-		    pwr->param[i] = 0;
-		else if (*p == 0x7f)
-		    pwr->flags |= CISTPL_POWER_HIGHZ_REQ;
-		else
-		    return NULL;
-	    }
-	    p++;
-	}
-    return p;
+	if (p == q)
+		return NULL;
+	pwr->present = *p;
+	pwr->flags = 0;
+	p++;
+	for (i = 0; i < 7; i++)
+		if (pwr->present & (1<<i)) {
+			if (p == q)
+				return NULL;
+			pwr->param[i] = POWER_CVT(*p);
+			scale = POWER_SCALE(*p);
+			while (*p & 0x80) {
+				if (++p == q)
+					return NULL;
+				if ((*p & 0x7f) < 100)
+					pwr->param[i] +=
+						(*p & 0x7f) * scale / 100;
+				else if (*p == 0x7d)
+					pwr->flags |= CISTPL_POWER_HIGHZ_OK;
+				else if (*p == 0x7e)
+					pwr->param[i] = 0;
+				else if (*p == 0x7f)
+					pwr->flags |= CISTPL_POWER_HIGHZ_REQ;
+				else
+					return NULL;
+			}
+			p++;
+		}
+	return p;
 }
 
-/*====================================================================*/
 
-static u_char *parse_timing(u_char *p, u_char *q,
-			    cistpl_timing_t *timing)
+static u_char *parse_timing(u_char *p, u_char *q, cistpl_timing_t *timing)
 {
-    u_char scale;
+	u_char scale;
 
-    if (p == q)
-	    return NULL;
-    scale = *p;
-    if ((scale & 3) != 3) {
-	if (++p == q)
-		return NULL;
-	timing->wait = SPEED_CVT(*p);
-	timing->waitscale = exponent[scale & 3];
-    } else
-	timing->wait = 0;
-    scale >>= 2;
-    if ((scale & 7) != 7) {
-	if (++p == q)
-		return NULL;
-	timing->ready = SPEED_CVT(*p);
-	timing->rdyscale = exponent[scale & 7];
-    } else
-	timing->ready = 0;
-    scale >>= 3;
-    if (scale != 7) {
-	if (++p == q)
+	if (p == q)
 		return NULL;
-	timing->reserved = SPEED_CVT(*p);
-	timing->rsvscale = exponent[scale];
-    } else
-	timing->reserved = 0;
-    p++;
-    return p;
+	scale = *p;
+	if ((scale & 3) != 3) {
+		if (++p == q)
+			return NULL;
+		timing->wait = SPEED_CVT(*p);
+		timing->waitscale = exponent[scale & 3];
+	} else
+		timing->wait = 0;
+	scale >>= 2;
+	if ((scale & 7) != 7) {
+		if (++p == q)
+			return NULL;
+		timing->ready = SPEED_CVT(*p);
+		timing->rdyscale = exponent[scale & 7];
+	} else
+		timing->ready = 0;
+	scale >>= 3;
+	if (scale != 7) {
+		if (++p == q)
+			return NULL;
+		timing->reserved = SPEED_CVT(*p);
+		timing->rsvscale = exponent[scale];
+	} else
+		timing->reserved = 0;
+	p++;
+	return p;
 }
 
-/*====================================================================*/
 
 static u_char *parse_io(u_char *p, u_char *q, cistpl_io_t *io)
 {
-    int i, j, bsz, lsz;
+	int i, j, bsz, lsz;
 
-    if (p == q)
-	    return NULL;
-    io->flags = *p;
+	if (p == q)
+		return NULL;
+	io->flags = *p;
 
-    if (!(*p & 0x80)) {
-	io->nwin = 1;
-	io->win[0].base = 0;
-	io->win[0].len = (1 << (io->flags & CISTPL_IO_LINES_MASK));
-	return p+1;
-    }
+	if (!(*p & 0x80)) {
+		io->nwin = 1;
+		io->win[0].base = 0;
+		io->win[0].len = (1 << (io->flags & CISTPL_IO_LINES_MASK));
+		return p+1;
+	}
 
-    if (++p == q)
-	    return NULL;
-    io->nwin = (*p & 0x0f) + 1;
-    bsz = (*p & 0x30) >> 4;
-    if (bsz == 3)
-	    bsz++;
-    lsz = (*p & 0xc0) >> 6;
-    if (lsz == 3)
-	    lsz++;
-    p++;
+	if (++p == q)
+		return NULL;
+	io->nwin = (*p & 0x0f) + 1;
+	bsz = (*p & 0x30) >> 4;
+	if (bsz == 3)
+		bsz++;
+	lsz = (*p & 0xc0) >> 6;
+	if (lsz == 3)
+		lsz++;
+	p++;
 
-    for (i = 0; i < io->nwin; i++) {
-	io->win[i].base = 0;
-	io->win[i].len = 1;
-	for (j = 0; j < bsz; j++, p++) {
-	    if (p == q)
-		    return NULL;
-	    io->win[i].base += *p << (j*8);
-	}
-	for (j = 0; j < lsz; j++, p++) {
-	    if (p == q)
-		    return NULL;
-	    io->win[i].len += *p << (j*8);
+	for (i = 0; i < io->nwin; i++) {
+		io->win[i].base = 0;
+		io->win[i].len = 1;
+		for (j = 0; j < bsz; j++, p++) {
+			if (p == q)
+				return NULL;
+			io->win[i].base += *p << (j*8);
+		}
+		for (j = 0; j < lsz; j++, p++) {
+			if (p == q)
+				return NULL;
+			io->win[i].len += *p << (j*8);
+		}
 	}
-    }
-    return p;
+	return p;
 }
 
-/*====================================================================*/
 
 static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem)
 {
-    int i, j, asz, lsz, has_ha;
-    u_int len, ca, ha;
+	int i, j, asz, lsz, has_ha;
+	u_int len, ca, ha;
 
-    if (p == q)
-	    return NULL;
+	if (p == q)
+		return NULL;
 
-    mem->nwin = (*p & 0x07) + 1;
-    lsz = (*p & 0x18) >> 3;
-    asz = (*p & 0x60) >> 5;
-    has_ha = (*p & 0x80);
-    if (++p == q)
-	    return NULL;
+	mem->nwin = (*p & 0x07) + 1;
+	lsz = (*p & 0x18) >> 3;
+	asz = (*p & 0x60) >> 5;
+	has_ha = (*p & 0x80);
+	if (++p == q)
+		return NULL;
 
-    for (i = 0; i < mem->nwin; i++) {
-	len = ca = ha = 0;
-	for (j = 0; j < lsz; j++, p++) {
-	    if (p == q)
-		    return NULL;
-	    len += *p << (j*8);
-	}
-	for (j = 0; j < asz; j++, p++) {
-	    if (p == q)
-		    return NULL;
-	    ca += *p << (j*8);
+	for (i = 0; i < mem->nwin; i++) {
+		len = ca = ha = 0;
+		for (j = 0; j < lsz; j++, p++) {
+			if (p == q)
+				return NULL;
+			len += *p << (j*8);
+		}
+		for (j = 0; j < asz; j++, p++) {
+			if (p == q)
+				return NULL;
+			ca += *p << (j*8);
+		}
+		if (has_ha)
+			for (j = 0; j < asz; j++, p++) {
+				if (p == q)
+					return NULL;
+				ha += *p << (j*8);
+			}
+		mem->win[i].len = len << 8;
+		mem->win[i].card_addr = ca << 8;
+		mem->win[i].host_addr = ha << 8;
 	}
-	if (has_ha)
-	    for (j = 0; j < asz; j++, p++) {
-		if (p == q)
-			return NULL;
-		ha += *p << (j*8);
-	    }
-	mem->win[i].len = len << 8;
-	mem->win[i].card_addr = ca << 8;
-	mem->win[i].host_addr = ha << 8;
-    }
-    return p;
+	return p;
 }
 
-/*====================================================================*/
 
 static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq)
 {
-    if (p == q)
-	    return NULL;
-    irq->IRQInfo1 = *p; p++;
-    if (irq->IRQInfo1 & IRQ_INFO2_VALID) {
-	if (p+2 > q)
+	if (p == q)
 		return NULL;
-	irq->IRQInfo2 = (p[1]<<8) + p[0];
-	p += 2;
-    }
-    return p;
+	irq->IRQInfo1 = *p; p++;
+	if (irq->IRQInfo1 & IRQ_INFO2_VALID) {
+		if (p+2 > q)
+			return NULL;
+		irq->IRQInfo2 = (p[1]<<8) + p[0];
+		p += 2;
+	}
+	return p;
 }
 
-/*====================================================================*/
 
 static int parse_cftable_entry(tuple_t *tuple,
 			       cistpl_cftable_entry_t *entry)
 {
-    u_char *p, *q, features;
+	u_char *p, *q, features;
 
-    p = tuple->TupleData;
-    q = p + tuple->TupleDataLen;
-    entry->index = *p & 0x3f;
-    entry->flags = 0;
-    if (*p & 0x40)
-	entry->flags |= CISTPL_CFTABLE_DEFAULT;
-    if (*p & 0x80) {
-	if (++p == q)
-		return -EINVAL;
-	if (*p & 0x10)
-	    entry->flags |= CISTPL_CFTABLE_BVDS;
-	if (*p & 0x20)
-	    entry->flags |= CISTPL_CFTABLE_WP;
+	p = tuple->TupleData;
+	q = p + tuple->TupleDataLen;
+	entry->index = *p & 0x3f;
+	entry->flags = 0;
 	if (*p & 0x40)
-	    entry->flags |= CISTPL_CFTABLE_RDYBSY;
-	if (*p & 0x80)
-	    entry->flags |= CISTPL_CFTABLE_MWAIT;
-	entry->interface = *p & 0x0f;
-    } else
-	entry->interface = 0;
-
-    /* Process optional features */
-    if (++p == q)
-	    return -EINVAL;
-    features = *p; p++;
-
-    /* Power options */
-    if ((features & 3) > 0) {
-	p = parse_power(p, q, &entry->vcc);
-	if (p == NULL)
-		return -EINVAL;
-    } else
-	entry->vcc.present = 0;
-    if ((features & 3) > 1) {
-	p = parse_power(p, q, &entry->vpp1);
-	if (p == NULL)
-		return -EINVAL;
-    } else
-	entry->vpp1.present = 0;
-    if ((features & 3) > 2) {
-	p = parse_power(p, q, &entry->vpp2);
-	if (p == NULL)
-		return -EINVAL;
-    } else
-	entry->vpp2.present = 0;
-
-    /* Timing options */
-    if (features & 0x04) {
-	p = parse_timing(p, q, &entry->timing);
-	if (p == NULL)
-		return -EINVAL;
-    } else {
-	entry->timing.wait = 0;
-	entry->timing.ready = 0;
-	entry->timing.reserved = 0;
-    }
-
-    /* I/O window options */
-    if (features & 0x08) {
-	p = parse_io(p, q, &entry->io);
-	if (p == NULL)
-		return -EINVAL;
-    } else
-	entry->io.nwin = 0;
-
-    /* Interrupt options */
-    if (features & 0x10) {
-	p = parse_irq(p, q, &entry->irq);
-	if (p == NULL)
-		return -EINVAL;
-    } else
-	entry->irq.IRQInfo1 = 0;
-
-    switch (features & 0x60) {
-    case 0x00:
-	entry->mem.nwin = 0;
-	break;
-    case 0x20:
-	entry->mem.nwin = 1;
-	entry->mem.win[0].len = get_unaligned_le16(p) << 8;
-	entry->mem.win[0].card_addr = 0;
-	entry->mem.win[0].host_addr = 0;
-	p += 2;
-	if (p > q)
-		return -EINVAL;
-	break;
-    case 0x40:
-	entry->mem.nwin = 1;
-	entry->mem.win[0].len = get_unaligned_le16(p) << 8;
-	entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8;
-	entry->mem.win[0].host_addr = 0;
-	p += 4;
-	if (p > q)
-		return -EINVAL;
-	break;
-    case 0x60:
-	p = parse_mem(p, q, &entry->mem);
-	if (p == NULL)
-		return -EINVAL;
-	break;
-    }
+		entry->flags |= CISTPL_CFTABLE_DEFAULT;
+	if (*p & 0x80) {
+		if (++p == q)
+			return -EINVAL;
+		if (*p & 0x10)
+			entry->flags |= CISTPL_CFTABLE_BVDS;
+		if (*p & 0x20)
+			entry->flags |= CISTPL_CFTABLE_WP;
+		if (*p & 0x40)
+			entry->flags |= CISTPL_CFTABLE_RDYBSY;
+		if (*p & 0x80)
+			entry->flags |= CISTPL_CFTABLE_MWAIT;
+		entry->interface = *p & 0x0f;
+	} else
+		entry->interface = 0;
 
-    /* Misc features */
-    if (features & 0x80) {
-	if (p == q)
+	/* Process optional features */
+	if (++p == q)
 		return -EINVAL;
-	entry->flags |= (*p << 8);
-	while (*p & 0x80)
-	    if (++p == q)
-		    return -EINVAL;
-	p++;
-    }
-
-    entry->subtuples = q-p;
-
-    return 0;
-}
-
-/*====================================================================*/
-
-#ifdef CONFIG_CARDBUS
-
-static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar)
-{
-    u_char *p;
-    if (tuple->TupleDataLen < 6)
-	return -EINVAL;
-    p = (u_char *)tuple->TupleData;
-    bar->attr = *p;
-    p += 2;
-    bar->size = get_unaligned_le32(p);
-    return 0;
-}
-
-static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
-{
-    u_char *p;
-
-    p = (u_char *)tuple->TupleData;
-    if ((*p != 3) || (tuple->TupleDataLen < 6))
-	return -EINVAL;
-    config->last_idx = *(++p);
-    p++;
-    config->base = get_unaligned_le32(p);
-    config->subtuples = tuple->TupleDataLen - 6;
-    return 0;
-}
-
-static int parse_cftable_entry_cb(tuple_t *tuple,
-				  cistpl_cftable_entry_cb_t *entry)
-{
-    u_char *p, *q, features;
-
-    p = tuple->TupleData;
-    q = p + tuple->TupleDataLen;
-    entry->index = *p & 0x3f;
-    entry->flags = 0;
-    if (*p & 0x40)
-	entry->flags |= CISTPL_CFTABLE_DEFAULT;
+	features = *p; p++;
 
-    /* Process optional features */
-    if (++p == q)
-	    return -EINVAL;
-    features = *p; p++;
+	/* Power options */
+	if ((features & 3) > 0) {
+		p = parse_power(p, q, &entry->vcc);
+		if (p == NULL)
+			return -EINVAL;
+	} else
+		entry->vcc.present = 0;
+	if ((features & 3) > 1) {
+		p = parse_power(p, q, &entry->vpp1);
+		if (p == NULL)
+			return -EINVAL;
+	} else
+		entry->vpp1.present = 0;
+	if ((features & 3) > 2) {
+		p = parse_power(p, q, &entry->vpp2);
+		if (p == NULL)
+			return -EINVAL;
+	} else
+		entry->vpp2.present = 0;
 
-    /* Power options */
-    if ((features & 3) > 0) {
-	p = parse_power(p, q, &entry->vcc);
-	if (p == NULL)
-		return -EINVAL;
-    } else
-	entry->vcc.present = 0;
-    if ((features & 3) > 1) {
-	p = parse_power(p, q, &entry->vpp1);
-	if (p == NULL)
-		return -EINVAL;
-    } else
-	entry->vpp1.present = 0;
-    if ((features & 3) > 2) {
-	p = parse_power(p, q, &entry->vpp2);
-	if (p == NULL)
-		return -EINVAL;
-    } else
-	entry->vpp2.present = 0;
+	/* Timing options */
+	if (features & 0x04) {
+		p = parse_timing(p, q, &entry->timing);
+		if (p == NULL)
+			return -EINVAL;
+	} else {
+		entry->timing.wait = 0;
+		entry->timing.ready = 0;
+		entry->timing.reserved = 0;
+	}
 
-    /* I/O window options */
-    if (features & 0x08) {
-	if (p == q)
-		return -EINVAL;
-	entry->io = *p; p++;
-    } else
-	entry->io = 0;
+	/* I/O window options */
+	if (features & 0x08) {
+		p = parse_io(p, q, &entry->io);
+		if (p == NULL)
+			return -EINVAL;
+	} else
+		entry->io.nwin = 0;
 
-    /* Interrupt options */
-    if (features & 0x10) {
-	p = parse_irq(p, q, &entry->irq);
-	if (p == NULL)
-		return -EINVAL;
-    } else
-	entry->irq.IRQInfo1 = 0;
+	/* Interrupt options */
+	if (features & 0x10) {
+		p = parse_irq(p, q, &entry->irq);
+		if (p == NULL)
+			return -EINVAL;
+	} else
+		entry->irq.IRQInfo1 = 0;
 
-    if (features & 0x20) {
-	if (p == q)
-		return -EINVAL;
-	entry->mem = *p; p++;
-    } else
-	entry->mem = 0;
+	switch (features & 0x60) {
+	case 0x00:
+		entry->mem.nwin = 0;
+		break;
+	case 0x20:
+		entry->mem.nwin = 1;
+		entry->mem.win[0].len = get_unaligned_le16(p) << 8;
+		entry->mem.win[0].card_addr = 0;
+		entry->mem.win[0].host_addr = 0;
+		p += 2;
+		if (p > q)
+			return -EINVAL;
+		break;
+	case 0x40:
+		entry->mem.nwin = 1;
+		entry->mem.win[0].len = get_unaligned_le16(p) << 8;
+		entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8;
+		entry->mem.win[0].host_addr = 0;
+		p += 4;
+		if (p > q)
+			return -EINVAL;
+		break;
+	case 0x60:
+		p = parse_mem(p, q, &entry->mem);
+		if (p == NULL)
+			return -EINVAL;
+		break;
+	}
 
-    /* Misc features */
-    if (features & 0x80) {
-	if (p == q)
-		return -EINVAL;
-	entry->flags |= (*p << 8);
-	if (*p & 0x80) {
-	    if (++p == q)
-		    return -EINVAL;
-	    entry->flags |= (*p << 16);
+	/* Misc features */
+	if (features & 0x80) {
+		if (p == q)
+			return -EINVAL;
+		entry->flags |= (*p << 8);
+		while (*p & 0x80)
+			if (++p == q)
+				return -EINVAL;
+		p++;
 	}
-	while (*p & 0x80)
-	    if (++p == q)
-		    return -EINVAL;
-	p++;
-    }
 
-    entry->subtuples = q-p;
+	entry->subtuples = q-p;
 
-    return 0;
+	return 0;
 }
 
-#endif
-
-/*====================================================================*/
 
 static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo)
 {
-    u_char *p, *q;
-    int n;
+	u_char *p, *q;
+	int n;
 
-    p = (u_char *)tuple->TupleData;
-    q = p + tuple->TupleDataLen;
+	p = (u_char *)tuple->TupleData;
+	q = p + tuple->TupleDataLen;
 
-    for (n = 0; n < CISTPL_MAX_DEVICES; n++) {
-	if (p > q-6)
-		break;
-	geo->geo[n].buswidth = p[0];
-	geo->geo[n].erase_block = 1 << (p[1]-1);
-	geo->geo[n].read_block  = 1 << (p[2]-1);
-	geo->geo[n].write_block = 1 << (p[3]-1);
-	geo->geo[n].partition   = 1 << (p[4]-1);
-	geo->geo[n].interleave  = 1 << (p[5]-1);
-	p += 6;
-    }
-    geo->ngeo = n;
-    return 0;
+	for (n = 0; n < CISTPL_MAX_DEVICES; n++) {
+		if (p > q-6)
+			break;
+		geo->geo[n].buswidth = p[0];
+		geo->geo[n].erase_block = 1 << (p[1]-1);
+		geo->geo[n].read_block  = 1 << (p[2]-1);
+		geo->geo[n].write_block = 1 << (p[3]-1);
+		geo->geo[n].partition   = 1 << (p[4]-1);
+		geo->geo[n].interleave  = 1 << (p[5]-1);
+		p += 6;
+	}
+	geo->ngeo = n;
+	return 0;
 }
 
-/*====================================================================*/
 
 static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
 {
-    u_char *p, *q;
+	u_char *p, *q;
 
-    if (tuple->TupleDataLen < 10)
-	return -EINVAL;
+	if (tuple->TupleDataLen < 10)
+		return -EINVAL;
 
-    p = tuple->TupleData;
-    q = p + tuple->TupleDataLen;
+	p = tuple->TupleData;
+	q = p + tuple->TupleDataLen;
 
-    v2->vers = p[0];
-    v2->comply = p[1];
-    v2->dindex = get_unaligned_le16(p + 2);
-    v2->vspec8 = p[6];
-    v2->vspec9 = p[7];
-    v2->nhdr = p[8];
-    p += 9;
-    return parse_strings(p, q, 2, v2->str, &v2->vendor, NULL);
+	v2->vers = p[0];
+	v2->comply = p[1];
+	v2->dindex = get_unaligned_le16(p + 2);
+	v2->vspec8 = p[6];
+	v2->vspec9 = p[7];
+	v2->nhdr = p[8];
+	p += 9;
+	return parse_strings(p, q, 2, v2->str, &v2->vendor, NULL);
 }
 
-/*====================================================================*/
 
 static int parse_org(tuple_t *tuple, cistpl_org_t *org)
 {
-    u_char *p, *q;
-    int i;
+	u_char *p, *q;
+	int i;
 
-    p = tuple->TupleData;
-    q = p + tuple->TupleDataLen;
-    if (p == q)
-	    return -EINVAL;
-    org->data_org = *p;
-    if (++p == q)
-	    return -EINVAL;
-    for (i = 0; i < 30; i++) {
-	org->desc[i] = *p;
-	if (*p == '\0')
-		break;
+	p = tuple->TupleData;
+	q = p + tuple->TupleDataLen;
+	if (p == q)
+		return -EINVAL;
+	org->data_org = *p;
 	if (++p == q)
 		return -EINVAL;
-    }
-    return 0;
+	for (i = 0; i < 30; i++) {
+		org->desc[i] = *p;
+		if (*p == '\0')
+			break;
+		if (++p == q)
+			return -EINVAL;
+	}
+	return 0;
 }
 
-/*====================================================================*/
 
 static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
 {
-    u_char *p;
+	u_char *p;
 
-    if (tuple->TupleDataLen < 10)
-	return -EINVAL;
+	if (tuple->TupleDataLen < 10)
+		return -EINVAL;
 
-    p = tuple->TupleData;
+	p = tuple->TupleData;
 
-    fmt->type = p[0];
-    fmt->edc = p[1];
-    fmt->offset = get_unaligned_le32(p + 2);
-    fmt->length = get_unaligned_le32(p + 6);
+	fmt->type = p[0];
+	fmt->edc = p[1];
+	fmt->offset = get_unaligned_le32(p + 2);
+	fmt->length = get_unaligned_le32(p + 6);
 
-    return 0;
+	return 0;
 }
 
-/*====================================================================*/
 
 int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
 {
-    int ret = 0;
+	int ret = 0;
 
-    if (tuple->TupleDataLen > tuple->TupleDataMax)
-	return -EINVAL;
-    switch (tuple->TupleCode) {
-    case CISTPL_DEVICE:
-    case CISTPL_DEVICE_A:
-	ret = parse_device(tuple, &parse->device);
-	break;
-#ifdef CONFIG_CARDBUS
-    case CISTPL_BAR:
-	ret = parse_bar(tuple, &parse->bar);
-	break;
-    case CISTPL_CONFIG_CB:
-	ret = parse_config_cb(tuple, &parse->config);
-	break;
-    case CISTPL_CFTABLE_ENTRY_CB:
-	ret = parse_cftable_entry_cb(tuple, &parse->cftable_entry_cb);
-	break;
-#endif
-    case CISTPL_CHECKSUM:
-	ret = parse_checksum(tuple, &parse->checksum);
-	break;
-    case CISTPL_LONGLINK_A:
-    case CISTPL_LONGLINK_C:
-	ret = parse_longlink(tuple, &parse->longlink);
-	break;
-    case CISTPL_LONGLINK_MFC:
-	ret = parse_longlink_mfc(tuple, &parse->longlink_mfc);
-	break;
-    case CISTPL_VERS_1:
-	ret = parse_vers_1(tuple, &parse->version_1);
-	break;
-    case CISTPL_ALTSTR:
-	ret = parse_altstr(tuple, &parse->altstr);
-	break;
-    case CISTPL_JEDEC_A:
-    case CISTPL_JEDEC_C:
-	ret = parse_jedec(tuple, &parse->jedec);
-	break;
-    case CISTPL_MANFID:
-	ret = parse_manfid(tuple, &parse->manfid);
-	break;
-    case CISTPL_FUNCID:
-	ret = parse_funcid(tuple, &parse->funcid);
-	break;
-    case CISTPL_FUNCE:
-	ret = parse_funce(tuple, &parse->funce);
-	break;
-    case CISTPL_CONFIG:
-	ret = parse_config(tuple, &parse->config);
-	break;
-    case CISTPL_CFTABLE_ENTRY:
-	ret = parse_cftable_entry(tuple, &parse->cftable_entry);
-	break;
-    case CISTPL_DEVICE_GEO:
-    case CISTPL_DEVICE_GEO_A:
-	ret = parse_device_geo(tuple, &parse->device_geo);
-	break;
-    case CISTPL_VERS_2:
-	ret = parse_vers_2(tuple, &parse->vers_2);
-	break;
-    case CISTPL_ORG:
-	ret = parse_org(tuple, &parse->org);
-	break;
-    case CISTPL_FORMAT:
-    case CISTPL_FORMAT_A:
-	ret = parse_format(tuple, &parse->format);
-	break;
-    case CISTPL_NO_LINK:
-    case CISTPL_LINKTARGET:
-	ret = 0;
-	break;
-    default:
-	ret = -EINVAL;
-	break;
-    }
-    if (ret)
-	    pr_debug("parse_tuple failed %d\n", ret);
-    return ret;
+	if (tuple->TupleDataLen > tuple->TupleDataMax)
+		return -EINVAL;
+	switch (tuple->TupleCode) {
+	case CISTPL_DEVICE:
+	case CISTPL_DEVICE_A:
+		ret = parse_device(tuple, &parse->device);
+		break;
+	case CISTPL_CHECKSUM:
+		ret = parse_checksum(tuple, &parse->checksum);
+		break;
+	case CISTPL_LONGLINK_A:
+	case CISTPL_LONGLINK_C:
+		ret = parse_longlink(tuple, &parse->longlink);
+		break;
+	case CISTPL_LONGLINK_MFC:
+		ret = parse_longlink_mfc(tuple, &parse->longlink_mfc);
+		break;
+	case CISTPL_VERS_1:
+		ret = parse_vers_1(tuple, &parse->version_1);
+		break;
+	case CISTPL_ALTSTR:
+		ret = parse_altstr(tuple, &parse->altstr);
+		break;
+	case CISTPL_JEDEC_A:
+	case CISTPL_JEDEC_C:
+		ret = parse_jedec(tuple, &parse->jedec);
+		break;
+	case CISTPL_MANFID:
+		ret = parse_manfid(tuple, &parse->manfid);
+		break;
+	case CISTPL_FUNCID:
+		ret = parse_funcid(tuple, &parse->funcid);
+		break;
+	case CISTPL_FUNCE:
+		ret = parse_funce(tuple, &parse->funce);
+		break;
+	case CISTPL_CONFIG:
+		ret = parse_config(tuple, &parse->config);
+		break;
+	case CISTPL_CFTABLE_ENTRY:
+		ret = parse_cftable_entry(tuple, &parse->cftable_entry);
+		break;
+	case CISTPL_DEVICE_GEO:
+	case CISTPL_DEVICE_GEO_A:
+		ret = parse_device_geo(tuple, &parse->device_geo);
+		break;
+	case CISTPL_VERS_2:
+		ret = parse_vers_2(tuple, &parse->vers_2);
+		break;
+	case CISTPL_ORG:
+		ret = parse_org(tuple, &parse->org);
+		break;
+	case CISTPL_FORMAT:
+	case CISTPL_FORMAT_A:
+		ret = parse_format(tuple, &parse->format);
+		break;
+	case CISTPL_NO_LINK:
+	case CISTPL_LINKTARGET:
+		ret = 0;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	if (ret)
+		pr_debug("parse_tuple failed %d\n", ret);
+	return ret;
 }
 EXPORT_SYMBOL(pcmcia_parse_tuple);
 
-/*======================================================================
-
-    This is used internally by Card Services to look up CIS stuff.
-
-======================================================================*/
 
-int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse)
+/**
+ * pccard_read_tuple() - internal CIS tuple access
+ * @s:		the struct pcmcia_socket where the card is inserted
+ * @function:	the device function we loop for
+ * @code:	which CIS code shall we look for?
+ * @parse:	buffer where the tuple shall be parsed (or NULL, if no parse)
+ *
+ * pccard_read_tuple() reads out one tuple and attempts to parse it
+ */
+int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
+		cisdata_t code, void *parse)
 {
-    tuple_t tuple;
-    cisdata_t *buf;
-    int ret;
+	tuple_t tuple;
+	cisdata_t *buf;
+	int ret;
 
-    buf = kmalloc(256, GFP_KERNEL);
-    if (buf == NULL) {
-	    dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
-	    return -ENOMEM;
-    }
-    tuple.DesiredTuple = code;
-    tuple.Attributes = 0;
-    if (function == BIND_FN_ALL)
-	    tuple.Attributes = TUPLE_RETURN_COMMON;
-    ret = pccard_get_first_tuple(s, function, &tuple);
-    if (ret != 0)
-	    goto done;
-    tuple.TupleData = buf;
-    tuple.TupleOffset = 0;
-    tuple.TupleDataMax = 255;
-    ret = pccard_get_tuple_data(s, &tuple);
-    if (ret != 0)
-	    goto done;
-    ret = pcmcia_parse_tuple(&tuple, parse);
+	buf = kmalloc(256, GFP_KERNEL);
+	if (buf == NULL) {
+		dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
+		return -ENOMEM;
+	}
+	tuple.DesiredTuple = code;
+	tuple.Attributes = 0;
+	if (function == BIND_FN_ALL)
+		tuple.Attributes = TUPLE_RETURN_COMMON;
+	ret = pccard_get_first_tuple(s, function, &tuple);
+	if (ret != 0)
+		goto done;
+	tuple.TupleData = buf;
+	tuple.TupleOffset = 0;
+	tuple.TupleDataMax = 255;
+	ret = pccard_get_tuple_data(s, &tuple);
+	if (ret != 0)
+		goto done;
+	ret = pcmcia_parse_tuple(&tuple, parse);
 done:
-    kfree(buf);
-    return ret;
+	kfree(buf);
+	return ret;
 }
-EXPORT_SYMBOL(pccard_read_tuple);
 
 
 /**
@@ -1573,84 +1459,243 @@ next_entry:
 	kfree(buf);
 	return ret;
 }
-EXPORT_SYMBOL(pccard_loop_tuple);
 
 
-/*======================================================================
+/**
+ * pccard_validate_cis() - check whether card has a sensible CIS
+ * @s:		the struct pcmcia_socket we are to check
+ * @info:	returns the number of tuples in the (valid) CIS, or 0
+ *
+ * This tries to determine if a card has a sensible CIS.  In @info, it
+ * returns the number of tuples in the CIS, or 0 if the CIS looks bad. The
+ * checks include making sure several critical tuples are present and
+ * valid; seeing if the total number of tuples is reasonable; and
+ * looking for tuples that use reserved codes.
+ *
+ * The function returns 0 on success.
+ */
+int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
+{
+	tuple_t *tuple;
+	cisparse_t *p;
+	unsigned int count = 0;
+	int ret, reserved, dev_ok = 0, ident_ok = 0;
 
-    This tries to determine if a card has a sensible CIS.  It returns
-    the number of tuples in the CIS, or 0 if the CIS looks bad.  The
-    checks include making sure several critical tuples are present and
-    valid; seeing if the total number of tuples is reasonable; and
-    looking for tuples that use reserved codes.
+	if (!s)
+		return -EINVAL;
 
-======================================================================*/
+	if (s->functions) {
+		WARN_ON(1);
+		return -EINVAL;
+	}
 
-int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
-{
-    tuple_t *tuple;
-    cisparse_t *p;
-    unsigned int count = 0;
-    int ret, reserved, dev_ok = 0, ident_ok = 0;
+	/* We do not want to validate the CIS cache... */
+	mutex_lock(&s->ops_mutex);
+	destroy_cis_cache(s);
+	mutex_unlock(&s->ops_mutex);
 
-    if (!s)
-	return -EINVAL;
+	tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
+	if (tuple == NULL) {
+		dev_warn(&s->dev, "no memory to validate CIS\n");
+		return -ENOMEM;
+	}
+	p = kmalloc(sizeof(*p), GFP_KERNEL);
+	if (p == NULL) {
+		kfree(tuple);
+		dev_warn(&s->dev, "no memory to validate CIS\n");
+		return -ENOMEM;
+	}
 
-    tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
-    if (tuple == NULL) {
-	    dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
-	    return -ENOMEM;
-    }
-    p = kmalloc(sizeof(*p), GFP_KERNEL);
-    if (p == NULL) {
-	    kfree(tuple);
-	    dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
-	    return -ENOMEM;
-    }
+	count = reserved = 0;
+	tuple->DesiredTuple = RETURN_FIRST_TUPLE;
+	tuple->Attributes = TUPLE_RETURN_COMMON;
+	ret = pccard_get_first_tuple(s, BIND_FN_ALL, tuple);
+	if (ret != 0)
+		goto done;
 
-    count = reserved = 0;
-    tuple->DesiredTuple = RETURN_FIRST_TUPLE;
-    tuple->Attributes = TUPLE_RETURN_COMMON;
-    ret = pccard_get_first_tuple(s, BIND_FN_ALL, tuple);
-    if (ret != 0)
-	goto done;
+	/* First tuple should be DEVICE; we should really have either that
+	   or a CFTABLE_ENTRY of some sort */
+	if ((tuple->TupleCode == CISTPL_DEVICE) ||
+	    (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY, p)) ||
+	    (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY_CB, p)))
+		dev_ok++;
 
-    /* First tuple should be DEVICE; we should really have either that
-       or a CFTABLE_ENTRY of some sort */
-    if ((tuple->TupleCode == CISTPL_DEVICE) ||
-	(pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY, p) == 0) ||
-	(pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY_CB, p) == 0))
-	dev_ok++;
+	/* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
+	   tuple, for card identification.  Certain old D-Link and Linksys
+	   cards have only a broken VERS_2 tuple; hence the bogus test. */
+	if ((pccard_read_tuple(s, BIND_FN_ALL, CISTPL_MANFID, p) == 0) ||
+	    (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_1, p) == 0) ||
+	    (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_2, p) != -ENOSPC))
+		ident_ok++;
 
-    /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
-       tuple, for card identification.  Certain old D-Link and Linksys
-       cards have only a broken VERS_2 tuple; hence the bogus test. */
-    if ((pccard_read_tuple(s, BIND_FN_ALL, CISTPL_MANFID, p) == 0) ||
-	(pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_1, p) == 0) ||
-	(pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_2, p) != -ENOSPC))
-	ident_ok++;
+	if (!dev_ok && !ident_ok)
+		goto done;
 
-    if (!dev_ok && !ident_ok)
-	goto done;
+	for (count = 1; count < MAX_TUPLES; count++) {
+		ret = pccard_get_next_tuple(s, BIND_FN_ALL, tuple);
+		if (ret != 0)
+			break;
+		if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
+		    ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
+		    ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
+			reserved++;
+	}
+	if ((count == MAX_TUPLES) || (reserved > 5) ||
+		((!dev_ok || !ident_ok) && (count > 10)))
+		count = 0;
 
-    for (count = 1; count < MAX_TUPLES; count++) {
-	ret = pccard_get_next_tuple(s, BIND_FN_ALL, tuple);
-	if (ret != 0)
-		break;
-	if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
-	    ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
-	    ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
-	    reserved++;
-    }
-    if ((count == MAX_TUPLES) || (reserved > 5) ||
-	((!dev_ok || !ident_ok) && (count > 10)))
-	count = 0;
+	ret = 0;
 
 done:
-    if (info)
-	    *info = count;
-    kfree(tuple);
-    kfree(p);
-    return 0;
+	/* invalidate CIS cache on failure */
+	if (!dev_ok || !ident_ok || !count) {
+		mutex_lock(&s->ops_mutex);
+		destroy_cis_cache(s);
+		mutex_unlock(&s->ops_mutex);
+		ret = -EIO;
+	}
+
+	if (info)
+		*info = count;
+	kfree(tuple);
+	kfree(p);
+	return ret;
 }
-EXPORT_SYMBOL(pccard_validate_cis);
+
+
+#define to_socket(_dev) container_of(_dev, struct pcmcia_socket, dev)
+
+static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf,
+				  loff_t off, size_t count)
+{
+	tuple_t tuple;
+	int status, i;
+	loff_t pointer = 0;
+	ssize_t ret = 0;
+	u_char *tuplebuffer;
+	u_char *tempbuffer;
+
+	tuplebuffer = kmalloc(sizeof(u_char) * 256, GFP_KERNEL);
+	if (!tuplebuffer)
+		return -ENOMEM;
+
+	tempbuffer = kmalloc(sizeof(u_char) * 258, GFP_KERNEL);
+	if (!tempbuffer) {
+		ret = -ENOMEM;
+		goto free_tuple;
+	}
+
+	memset(&tuple, 0, sizeof(tuple_t));
+
+	tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON;
+	tuple.DesiredTuple = RETURN_FIRST_TUPLE;
+	tuple.TupleOffset = 0;
+
+	status = pccard_get_first_tuple(s, BIND_FN_ALL, &tuple);
+	while (!status) {
+		tuple.TupleData = tuplebuffer;
+		tuple.TupleDataMax = 255;
+		memset(tuplebuffer, 0, sizeof(u_char) * 255);
+
+		status = pccard_get_tuple_data(s, &tuple);
+		if (status)
+			break;
+
+		if (off < (pointer + 2 + tuple.TupleDataLen)) {
+			tempbuffer[0] = tuple.TupleCode & 0xff;
+			tempbuffer[1] = tuple.TupleLink & 0xff;
+			for (i = 0; i < tuple.TupleDataLen; i++)
+				tempbuffer[i + 2] = tuplebuffer[i] & 0xff;
+
+			for (i = 0; i < (2 + tuple.TupleDataLen); i++) {
+				if (((i + pointer) >= off) &&
+				    (i + pointer) < (off + count)) {
+					buf[ret] = tempbuffer[i];
+					ret++;
+				}
+			}
+		}
+
+		pointer += 2 + tuple.TupleDataLen;
+
+		if (pointer >= (off + count))
+			break;
+
+		if (tuple.TupleCode == CISTPL_END)
+			break;
+		status = pccard_get_next_tuple(s, BIND_FN_ALL, &tuple);
+	}
+
+	kfree(tempbuffer);
+ free_tuple:
+	kfree(tuplebuffer);
+
+	return ret;
+}
+
+
+static ssize_t pccard_show_cis(struct kobject *kobj,
+			       struct bin_attribute *bin_attr,
+			       char *buf, loff_t off, size_t count)
+{
+	unsigned int size = 0x200;
+
+	if (off >= size)
+		count = 0;
+	else {
+		struct pcmcia_socket *s;
+		unsigned int chains = 1;
+
+		if (off + count > size)
+			count = size - off;
+
+		s = to_socket(container_of(kobj, struct device, kobj));
+
+		if (!(s->state & SOCKET_PRESENT))
+			return -ENODEV;
+		if (!s->functions && pccard_validate_cis(s, &chains))
+			return -EIO;
+		if (!chains)
+			return -ENODATA;
+
+		count = pccard_extract_cis(s, buf, off, count);
+	}
+
+	return count;
+}
+
+
+static ssize_t pccard_store_cis(struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
+{
+	struct pcmcia_socket *s;
+	int error;
+
+	s = to_socket(container_of(kobj, struct device, kobj));
+
+	if (off)
+		return -EINVAL;
+
+	if (count >= CISTPL_MAX_CIS_SIZE)
+		return -EINVAL;
+
+	if (!(s->state & SOCKET_PRESENT))
+		return -ENODEV;
+
+	error = pcmcia_replace_cis(s, buf, count);
+	if (error)
+		return -EIO;
+
+	pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);
+
+	return count;
+}
+
+
+struct bin_attribute pccard_cis_attr = {
+	.attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR },
+	.size = 0x200,
+	.read = pccard_show_cis,
+	.write = pccard_store_cis,
+};
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/cs.c linux-libre-2.6.34-gnu1/drivers/pcmcia/cs.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -76,83 +76,18 @@ DECLARE_RWSEM(pcmcia_socket_list_rwsem);
 EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
 
 
-/*
- * Low-level PCMCIA socket drivers need to register with the PCCard
- * core using pcmcia_register_socket.
- *
- * socket drivers are expected to use the following callbacks in their
- * .drv struct:
- *  - pcmcia_socket_dev_suspend
- *  - pcmcia_socket_dev_resume
- * These functions check for the appropriate struct pcmcia_soket arrays,
- * and pass them to the low-level functions pcmcia_{suspend,resume}_socket
- */
-static int socket_early_resume(struct pcmcia_socket *skt);
-static int socket_late_resume(struct pcmcia_socket *skt);
-static int socket_resume(struct pcmcia_socket *skt);
-static int socket_suspend(struct pcmcia_socket *skt);
-
-static void pcmcia_socket_dev_run(struct device *dev,
-				  int (*cb)(struct pcmcia_socket *))
-{
-	struct pcmcia_socket *socket;
-
-	down_read(&pcmcia_socket_list_rwsem);
-	list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
-		if (socket->dev.parent != dev)
-			continue;
-		mutex_lock(&socket->skt_mutex);
-		cb(socket);
-		mutex_unlock(&socket->skt_mutex);
-	}
-	up_read(&pcmcia_socket_list_rwsem);
-}
-
-int pcmcia_socket_dev_suspend(struct device *dev)
-{
-	pcmcia_socket_dev_run(dev, socket_suspend);
-	return 0;
-}
-EXPORT_SYMBOL(pcmcia_socket_dev_suspend);
-
-void pcmcia_socket_dev_early_resume(struct device *dev)
-{
-	pcmcia_socket_dev_run(dev, socket_early_resume);
-}
-EXPORT_SYMBOL(pcmcia_socket_dev_early_resume);
-
-void pcmcia_socket_dev_late_resume(struct device *dev)
-{
-	pcmcia_socket_dev_run(dev, socket_late_resume);
-}
-EXPORT_SYMBOL(pcmcia_socket_dev_late_resume);
-
-int pcmcia_socket_dev_resume(struct device *dev)
-{
-	pcmcia_socket_dev_run(dev, socket_resume);
-	return 0;
-}
-EXPORT_SYMBOL(pcmcia_socket_dev_resume);
-
-
 struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt)
 {
 	struct device *dev = get_device(&skt->dev);
 	if (!dev)
 		return NULL;
-	skt = dev_get_drvdata(dev);
-	if (!try_module_get(skt->owner)) {
-		put_device(&skt->dev);
-		return NULL;
-	}
-	return skt;
+	return dev_get_drvdata(dev);
 }
 EXPORT_SYMBOL(pcmcia_get_socket);
 
 
 void pcmcia_put_socket(struct pcmcia_socket *skt)
 {
-	module_put(skt->owner);
 	put_device(&skt->dev);
 }
 EXPORT_SYMBOL(pcmcia_put_socket);
@@ -181,8 +116,6 @@ int pcmcia_register_socket(struct pcmcia
 
 	dev_dbg(&socket->dev, "pcmcia_register_socket(0x%p)\n", socket->ops);
 
-	spin_lock_init(&socket->lock);
-
 	/* try to obtain a socket number [yes, it gets ugly if we
 	 * register more than 2^sizeof(unsigned int) pcmcia
 	 * sockets... but the socket number is deprecated
@@ -228,10 +161,13 @@ int pcmcia_register_socket(struct pcmcia
 	init_completion(&socket->socket_released);
 	init_completion(&socket->thread_done);
 	mutex_init(&socket->skt_mutex);
+	mutex_init(&socket->ops_mutex);
 	spin_lock_init(&socket->thread_lock);
 
 	if (socket->resource_ops->init) {
+		mutex_lock(&socket->ops_mutex);
 		ret = socket->resource_ops->init(socket);
+		mutex_unlock(&socket->ops_mutex);
 		if (ret)
 			goto err;
 	}
@@ -283,15 +219,17 @@ void pcmcia_unregister_socket(struct pcm
 	if (socket->thread)
 		kthread_stop(socket->thread);
 
-	release_cis_mem(socket);
-
 	/* remove from our own list */
 	down_write(&pcmcia_socket_list_rwsem);
 	list_del(&socket->socket_list);
 	up_write(&pcmcia_socket_list_rwsem);
 
 	/* wait for sysfs to drop all references */
-	release_resource_db(socket);
+	if (socket->resource_ops->exit) {
+		mutex_lock(&socket->ops_mutex);
+		socket->resource_ops->exit(socket);
+		mutex_unlock(&socket->ops_mutex);
+	}
 	wait_for_completion(&socket->socket_released);
 } /* pcmcia_unregister_socket */
 EXPORT_SYMBOL(pcmcia_unregister_socket);
@@ -328,7 +266,7 @@ static int send_event(struct pcmcia_sock
 {
 	int ret;
 
-	if (s->state & SOCKET_CARDBUS)
+	if ((s->state & SOCKET_CARDBUS) && (event != CS_EVENT_CARD_REMOVAL))
 		return 0;
 
 	dev_dbg(&s->dev, "send_event(event %d, pri %d, callback 0x%p)\n",
@@ -346,13 +284,6 @@ static int send_event(struct pcmcia_sock
 	return ret;
 }
 
-static void socket_remove_drivers(struct pcmcia_socket *skt)
-{
-	dev_dbg(&skt->dev, "remove_drivers\n");
-
-	send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
-}
-
 static int socket_reset(struct pcmcia_socket *skt)
 {
 	int status, i;
@@ -395,7 +326,9 @@ static void socket_shutdown(struct pcmci
 
 	dev_dbg(&s->dev, "shutdown\n");
 
-	socket_remove_drivers(s);
+	send_event(s, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
+
+	mutex_lock(&s->ops_mutex);
 	s->state &= SOCKET_INUSE | SOCKET_PRESENT;
 	msleep(shutdown_delay * 10);
 	s->state &= SOCKET_INUSE;
@@ -406,11 +339,21 @@ static void socket_shutdown(struct pcmci
 	s->ops->set_socket(s, &s->socket);
 	s->irq.AssignedIRQ = s->irq.Config = 0;
 	s->lock_count = 0;
-	destroy_cis_cache(s);
+	kfree(s->fake_cis);
+	s->fake_cis = NULL;
+	s->functions = 0;
+
+	/* From here on we can be sure that only we (that is, the
+	 * pccardd thread) accesses this socket, and all (16-bit)
+	 * PCMCIA interactions are gone. Therefore, release
+	 * ops_mutex so that we don't get a sysfs-related lockdep
+	 * warning.
+	 */
+	mutex_unlock(&s->ops_mutex);
+
 #ifdef CONFIG_CARDBUS
 	cb_free(s);
 #endif
-	s->functions = 0;
 
 	/* give socket some time to power down */
 	msleep(100);
@@ -421,7 +364,7 @@ static void socket_shutdown(struct pcmci
 			   "*** DANGER *** unable to remove socket power\n");
 	}
 
-	cs_socket_put(s);
+	s->state &= ~SOCKET_INUSE;
 }
 
 static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
@@ -460,7 +403,8 @@ static int socket_setup(struct pcmcia_so
 			return -EINVAL;
 		}
 		skt->state |= SOCKET_CARDBUS;
-	}
+	} else
+		skt->state &= ~SOCKET_CARDBUS;
 
 	/*
 	 * Decode the card voltage requirements, and apply power to the card.
@@ -509,8 +453,12 @@ static int socket_insert(struct pcmcia_s
 
 	dev_dbg(&skt->dev, "insert\n");
 
-	if (!cs_socket_get(skt))
-		return -ENODEV;
+	mutex_lock(&skt->ops_mutex);
+	if (skt->state & SOCKET_INUSE) {
+		mutex_unlock(&skt->ops_mutex);
+		return -EINVAL;
+	}
+	skt->state |= SOCKET_INUSE;
 
 	ret = socket_setup(skt, setup_delay);
 	if (ret == 0) {
@@ -528,9 +476,11 @@ static int socket_insert(struct pcmcia_s
 		}
 #endif
 		dev_dbg(&skt->dev, "insert done\n");
+		mutex_unlock(&skt->ops_mutex);
 
 		send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
 	} else {
+		mutex_unlock(&skt->ops_mutex);
 		socket_shutdown(skt);
 	}
 
@@ -542,58 +492,72 @@ static int socket_suspend(struct pcmcia_
 	if (skt->state & SOCKET_SUSPEND)
 		return -EBUSY;
 
+	mutex_lock(&skt->ops_mutex);
+	skt->suspended_state = skt->state;
+
 	send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
 	skt->socket = dead_socket;
 	skt->ops->set_socket(skt, &skt->socket);
 	if (skt->ops->suspend)
 		skt->ops->suspend(skt);
 	skt->state |= SOCKET_SUSPEND;
-
+	mutex_unlock(&skt->ops_mutex);
 	return 0;
 }
 
 static int socket_early_resume(struct pcmcia_socket *skt)
 {
+	mutex_lock(&skt->ops_mutex);
 	skt->socket = dead_socket;
 	skt->ops->init(skt);
 	skt->ops->set_socket(skt, &skt->socket);
 	if (skt->state & SOCKET_PRESENT)
 		skt->resume_status = socket_setup(skt, resume_delay);
+	mutex_unlock(&skt->ops_mutex);
 	return 0;
 }
 
 static int socket_late_resume(struct pcmcia_socket *skt)
 {
+	int ret;
+
+	mutex_lock(&skt->ops_mutex);
+	skt->state &= ~SOCKET_SUSPEND;
+	mutex_unlock(&skt->ops_mutex);
+
 	if (!(skt->state & SOCKET_PRESENT)) {
-		skt->state &= ~SOCKET_SUSPEND;
-		return socket_insert(skt);
+		ret = socket_insert(skt);
+		if (ret == -ENODEV)
+			ret = 0;
+		return ret;
 	}
 
-	if (skt->resume_status == 0) {
-		/*
-		 * FIXME: need a better check here for cardbus cards.
-		 */
-		if (verify_cis_cache(skt) != 0) {
-			dev_dbg(&skt->dev, "cis mismatch - different card\n");
-			socket_remove_drivers(skt);
-			destroy_cis_cache(skt);
-			/*
-			 * Workaround: give DS time to schedule removal.
-			 * Remove me once the 100ms delay is eliminated
-			 * in ds.c
-			 */
-			msleep(200);
-			send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
-		} else {
-			dev_dbg(&skt->dev, "cis matches cache\n");
-			send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
-		}
-	} else {
+	if (skt->resume_status) {
 		socket_shutdown(skt);
+		return 0;
 	}
 
-	skt->state &= ~SOCKET_SUSPEND;
+	if (skt->suspended_state != skt->state) {
+		dev_dbg(&skt->dev,
+			"suspend state 0x%x != resume state 0x%x\n",
+			skt->suspended_state, skt->state);
+
+		socket_shutdown(skt);
+		return socket_insert(skt);
+	}
 
+#ifdef CONFIG_CARDBUS
+	if (skt->state & SOCKET_CARDBUS) {
+		/* We can't be sure the CardBus card is the same
+		 * as the one previously inserted. Therefore, remove
+		 * and re-add... */
+		cb_free(skt);
+		cb_alloc(skt);
+		return 0;
+	}
+#endif
+
+	send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
 	return 0;
 }
 
@@ -672,20 +636,26 @@ static int pccardd(void *__skt)
 
 	complete(&skt->thread_done);
 
+	/* wait for userspace to catch up */
+	msleep(250);
+
 	set_freezable();
 	for (;;) {
 		unsigned long flags;
 		unsigned int events;
+		unsigned int sysfs_events;
 
 		set_current_state(TASK_INTERRUPTIBLE);
 
 		spin_lock_irqsave(&skt->thread_lock, flags);
 		events = skt->thread_events;
 		skt->thread_events = 0;
+		sysfs_events = skt->sysfs_events;
+		skt->sysfs_events = 0;
 		spin_unlock_irqrestore(&skt->thread_lock, flags);
 
+		mutex_lock(&skt->skt_mutex);
 		if (events) {
-			mutex_lock(&skt->skt_mutex);
 			if (events & SS_DETECT)
 				socket_detect_change(skt);
 			if (events & SS_BATDEAD)
@@ -694,10 +664,41 @@ static int pccardd(void *__skt)
 				send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW);
 			if (events & SS_READY)
 				send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW);
-			mutex_unlock(&skt->skt_mutex);
-			continue;
 		}
 
+		if (sysfs_events) {
+			if (sysfs_events & PCMCIA_UEVENT_EJECT)
+				socket_remove(skt);
+			if (sysfs_events & PCMCIA_UEVENT_INSERT)
+				socket_insert(skt);
+			if ((sysfs_events & PCMCIA_UEVENT_SUSPEND) &&
+				!(skt->state & SOCKET_CARDBUS)) {
+				if (skt->callback)
+					ret = skt->callback->suspend(skt);
+				else
+					ret = 0;
+				if (!ret) {
+					socket_suspend(skt);
+					msleep(100);
+				}
+			}
+			if ((sysfs_events & PCMCIA_UEVENT_RESUME) &&
+				!(skt->state & SOCKET_CARDBUS)) {
+				ret = socket_resume(skt);
+				if (!ret && skt->callback)
+					skt->callback->resume(skt);
+			}
+			if ((sysfs_events & PCMCIA_UEVENT_REQUERY) &&
+				!(skt->state & SOCKET_CARDBUS)) {
+				if (!ret && skt->callback)
+					skt->callback->requery(skt);
+			}
+		}
+		mutex_unlock(&skt->skt_mutex);
+
+		if (events || sysfs_events)
+			continue;
+
 		if (kthread_should_stop())
 			break;
 
@@ -707,6 +708,13 @@ static int pccardd(void *__skt)
 	/* make sure we are running before we exit */
 	set_current_state(TASK_RUNNING);
 
+	/* shut down socket, if a device is still present */
+	if (skt->state & SOCKET_PRESENT) {
+		mutex_lock(&skt->skt_mutex);
+		socket_remove(skt);
+		mutex_unlock(&skt->skt_mutex);
+	}
+
 	/* remove from the device core */
 	pccard_sysfs_remove_socket(&skt->dev);
 	device_unregister(&skt->dev);
@@ -732,6 +740,31 @@ void pcmcia_parse_events(struct pcmcia_s
 } /* pcmcia_parse_events */
 EXPORT_SYMBOL(pcmcia_parse_events);
 
+/**
+ * pcmcia_parse_uevents() - tell pccardd to issue manual commands
+ * @s:		the PCMCIA socket we wan't to command
+ * @events:	events to pass to pccardd
+ *
+ * userspace-issued insert, eject, suspend and resume commands must be
+ * handled by pccardd to avoid any sysfs-related deadlocks. Valid events
+ * are PCMCIA_UEVENT_EJECT (for eject), PCMCIA_UEVENT__INSERT (for insert),
+ * PCMCIA_UEVENT_RESUME (for resume), PCMCIA_UEVENT_SUSPEND (for suspend)
+ * and PCMCIA_UEVENT_REQUERY (for re-querying the PCMCIA card).
+ */
+void pcmcia_parse_uevents(struct pcmcia_socket *s, u_int events)
+{
+	unsigned long flags;
+	dev_dbg(&s->dev, "parse_uevents: events %08x\n", events);
+	if (s->thread) {
+		spin_lock_irqsave(&s->thread_lock, flags);
+		s->sysfs_events |= events;
+		spin_unlock_irqrestore(&s->thread_lock, flags);
+
+		wake_up_process(s->thread);
+	}
+}
+EXPORT_SYMBOL(pcmcia_parse_uevents);
+
 
 /* register pcmcia_callback */
 int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
@@ -796,7 +829,10 @@ int pcmcia_reset_card(struct pcmcia_sock
 			send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
 			if (skt->callback)
 				skt->callback->suspend(skt);
-			if (socket_reset(skt) == 0) {
+			mutex_lock(&skt->ops_mutex);
+			ret = socket_reset(skt);
+			mutex_unlock(&skt->ops_mutex);
+			if (ret == 0) {
 				send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
 				if (skt->callback)
 					skt->callback->resume(skt);
@@ -812,146 +848,86 @@ int pcmcia_reset_card(struct pcmcia_sock
 EXPORT_SYMBOL(pcmcia_reset_card);
 
 
-/* These shut down or wake up a socket.  They are sort of user
- * initiated versions of the APM suspend and resume actions.
- */
-int pcmcia_suspend_card(struct pcmcia_socket *skt)
+static int pcmcia_socket_uevent(struct device *dev,
+				struct kobj_uevent_env *env)
 {
-	int ret;
+	struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
 
-	dev_dbg(&skt->dev, "suspending socket\n");
+	if (add_uevent_var(env, "SOCKET_NO=%u", s->sock))
+		return -ENOMEM;
 
-	mutex_lock(&skt->skt_mutex);
-	do {
-		if (!(skt->state & SOCKET_PRESENT)) {
-			ret = -ENODEV;
-			break;
-		}
-		if (skt->state & SOCKET_CARDBUS) {
-			ret = -EPERM;
-			break;
-		}
-		if (skt->callback) {
-			ret = skt->callback->suspend(skt);
-			if (ret)
-				break;
-		}
-		ret = socket_suspend(skt);
-	} while (0);
-	mutex_unlock(&skt->skt_mutex);
+	return 0;
+}
 
-	return ret;
-} /* suspend_card */
-EXPORT_SYMBOL(pcmcia_suspend_card);
 
+static struct completion pcmcia_unload;
 
-int pcmcia_resume_card(struct pcmcia_socket *skt)
+static void pcmcia_release_socket_class(struct class *data)
 {
-	int ret;
-
-	dev_dbg(&skt->dev, "waking up socket\n");
-
-	mutex_lock(&skt->skt_mutex);
-	do {
-		if (!(skt->state & SOCKET_PRESENT)) {
-			ret = -ENODEV;
-			break;
-		}
-		if (skt->state & SOCKET_CARDBUS) {
-			ret = -EPERM;
-			break;
-		}
-		ret = socket_resume(skt);
-		if (!ret && skt->callback)
-			skt->callback->resume(skt);
-	} while (0);
-	mutex_unlock(&skt->skt_mutex);
+	complete(&pcmcia_unload);
+}
 
-	return ret;
-} /* resume_card */
-EXPORT_SYMBOL(pcmcia_resume_card);
 
+#ifdef CONFIG_PM
 
-/* These handle user requests to eject or insert a card. */
-int pcmcia_eject_card(struct pcmcia_socket *skt)
+static int __pcmcia_pm_op(struct device *dev,
+			  int (*callback) (struct pcmcia_socket *skt))
 {
+	struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
 	int ret;
 
-	dev_dbg(&skt->dev, "user eject request\n");
-
-	mutex_lock(&skt->skt_mutex);
-	do {
-		if (!(skt->state & SOCKET_PRESENT)) {
-			ret = -ENODEV;
-			break;
-		}
-
-		ret = send_event(skt, CS_EVENT_EJECTION_REQUEST, CS_EVENT_PRI_LOW);
-		if (ret != 0) {
-			ret = -EINVAL;
-			break;
-		}
-
-		socket_remove(skt);
-		ret = 0;
-	} while (0);
-	mutex_unlock(&skt->skt_mutex);
+	mutex_lock(&s->skt_mutex);
+	ret = callback(s);
+	mutex_unlock(&s->skt_mutex);
 
 	return ret;
-} /* eject_card */
-EXPORT_SYMBOL(pcmcia_eject_card);
-
+}
 
-int pcmcia_insert_card(struct pcmcia_socket *skt)
+static int pcmcia_socket_dev_suspend_noirq(struct device *dev)
 {
-	int ret;
-
-	dev_dbg(&skt->dev, "user insert request\n");
-
-	mutex_lock(&skt->skt_mutex);
-	do {
-		if (skt->state & SOCKET_PRESENT) {
-			ret = -EBUSY;
-			break;
-		}
-		if (socket_insert(skt) == -ENODEV) {
-			ret = -ENODEV;
-			break;
-		}
-		ret = 0;
-	} while (0);
-	mutex_unlock(&skt->skt_mutex);
-
-	return ret;
-} /* insert_card */
-EXPORT_SYMBOL(pcmcia_insert_card);
+	return __pcmcia_pm_op(dev, socket_suspend);
+}
 
+static int pcmcia_socket_dev_resume_noirq(struct device *dev)
+{
+	return __pcmcia_pm_op(dev, socket_early_resume);
+}
 
-static int pcmcia_socket_uevent(struct device *dev,
-				struct kobj_uevent_env *env)
+static int pcmcia_socket_dev_resume(struct device *dev)
 {
-	struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
+	return __pcmcia_pm_op(dev, socket_late_resume);
+}
 
-	if (add_uevent_var(env, "SOCKET_NO=%u", s->sock))
-		return -ENOMEM;
+static const struct dev_pm_ops pcmcia_socket_pm_ops = {
+	/* dev_resume may be called with IRQs enabled */
+	SET_SYSTEM_SLEEP_PM_OPS(NULL,
+				pcmcia_socket_dev_resume)
 
-	return 0;
-}
+	/* late suspend must be called with IRQs disabled */
+	.suspend_noirq = pcmcia_socket_dev_suspend_noirq,
+	.freeze_noirq = pcmcia_socket_dev_suspend_noirq,
+	.poweroff_noirq = pcmcia_socket_dev_suspend_noirq,
+
+	/* early resume must be called with IRQs disabled */
+	.resume_noirq = pcmcia_socket_dev_resume_noirq,
+	.thaw_noirq = pcmcia_socket_dev_resume_noirq,
+	.restore_noirq = pcmcia_socket_dev_resume_noirq,
+};
 
+#define PCMCIA_SOCKET_CLASS_PM_OPS (&pcmcia_socket_pm_ops)
 
-static struct completion pcmcia_unload;
+#else /* CONFIG_PM */
 
-static void pcmcia_release_socket_class(struct class *data)
-{
-	complete(&pcmcia_unload);
-}
+#define PCMCIA_SOCKET_CLASS_PM_OPS NULL
 
+#endif /* CONFIG_PM */
 
 struct class pcmcia_socket_class = {
 	.name = "pcmcia_socket",
 	.dev_uevent = pcmcia_socket_uevent,
 	.dev_release = pcmcia_release_socket,
 	.class_release = pcmcia_release_socket_class,
+	.pm = PCMCIA_SOCKET_CLASS_PM_OPS,
 };
 EXPORT_SYMBOL(pcmcia_socket_class);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/cs_internal.h linux-libre-2.6.34-gnu1/drivers/pcmcia/cs_internal.h
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/cs_internal.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/cs_internal.h	2010-05-16 17:17:36.000000000 -0400
@@ -87,37 +87,11 @@ struct pccard_resource_ops {
 #define SOCKET_CARDBUS		0x8000
 #define SOCKET_CARDBUS_CONFIG	0x10000
 
-static inline int cs_socket_get(struct pcmcia_socket *skt)
-{
-	int ret;
-
-	WARN_ON(skt->state & SOCKET_INUSE);
-
-	ret = try_module_get(skt->owner);
-	if (ret)
-		skt->state |= SOCKET_INUSE;
-	return ret;
-}
-
-static inline void cs_socket_put(struct pcmcia_socket *skt)
-{
-	if (skt->state & SOCKET_INUSE) {
-		skt->state &= ~SOCKET_INUSE;
-		module_put(skt->owner);
-	}
-}
-
 
 /*
  * Stuff internal to module "pcmcia_core":
  */
 
-/* cistpl.c */
-int verify_cis_cache(struct pcmcia_socket *s);
-
-/* rsrc_mgr.c */
-void release_resource_db(struct pcmcia_socket *s);
-
 /* socket_sysfs.c */
 extern int pccard_sysfs_add_socket(struct device *dev);
 extern void pccard_sysfs_remove_socket(struct device *dev);
@@ -125,8 +99,6 @@ extern void pccard_sysfs_remove_socket(s
 /* cardbus.c */
 int cb_alloc(struct pcmcia_socket *s);
 void cb_free(struct pcmcia_socket *s);
-int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len,
-		void *ptr);
 
 
 
@@ -138,7 +110,8 @@ struct pcmcia_callback{
 	struct module	*owner;
 	int		(*event) (struct pcmcia_socket *s,
 				  event_t event, int priority);
-	void		(*requery) (struct pcmcia_socket *s, int new_cis);
+	void		(*requery) (struct pcmcia_socket *s);
+	int		(*validate) (struct pcmcia_socket *s, unsigned int *i);
 	int		(*suspend) (struct pcmcia_socket *s);
 	int		(*resume) (struct pcmcia_socket *s);
 };
@@ -151,16 +124,35 @@ extern struct class pcmcia_socket_class;
 int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
 struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr);
 
-int pcmcia_suspend_card(struct pcmcia_socket *skt);
-int pcmcia_resume_card(struct pcmcia_socket *skt);
-
-int pcmcia_eject_card(struct pcmcia_socket *skt);
-int pcmcia_insert_card(struct pcmcia_socket *skt);
+void pcmcia_parse_uevents(struct pcmcia_socket *socket, unsigned int events);
+#define PCMCIA_UEVENT_EJECT	0x0001
+#define PCMCIA_UEVENT_INSERT	0x0002
+#define PCMCIA_UEVENT_SUSPEND	0x0004
+#define PCMCIA_UEVENT_RESUME	0x0008
+#define PCMCIA_UEVENT_REQUERY	0x0010
 
 struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt);
 void pcmcia_put_socket(struct pcmcia_socket *skt);
 
+/*
+ * Stuff internal to module "pcmcia".
+ */
+/* ds.c */
+extern struct bus_type pcmcia_bus_type;
+
+/* pcmcia_resource.c */
+extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
+extern int pcmcia_validate_mem(struct pcmcia_socket *s);
+extern struct resource *pcmcia_find_mem_region(u_long base,
+					       u_long num,
+					       u_long align,
+					       int low,
+					       struct pcmcia_socket *s);
+
+
 /* cistpl.c */
+extern struct bin_attribute pccard_cis_attr;
+
 int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr,
 			u_int addr, u_int len, void *ptr);
 void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,
@@ -172,8 +164,8 @@ int pccard_read_tuple(struct pcmcia_sock
 int pcmcia_replace_cis(struct pcmcia_socket *s,
 		       const u8 *data, const size_t len);
 int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *count);
+int verify_cis_cache(struct pcmcia_socket *s);
 
-/* loop over CIS entries */
 int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
 		      cisdata_t code, cisparse_t *parse, void *priv_data,
 		      int (*loop_tuple) (tuple_t *tuple,
@@ -189,35 +181,8 @@ int pccard_get_next_tuple(struct pcmcia_
 int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
 
 
-/* rsrc_mgr.c */
-int pcmcia_validate_mem(struct pcmcia_socket *s);
-struct resource *pcmcia_find_io_region(unsigned long base,
-				       int num,
-				       unsigned long align,
-				       struct pcmcia_socket *s);
-int pcmcia_adjust_io_region(struct resource *res,
-			    unsigned long r_start,
-			    unsigned long r_end,
-			    struct pcmcia_socket *s);
-struct resource *pcmcia_find_mem_region(u_long base,
-					u_long num,
-					u_long align,
-					int low,
-					struct pcmcia_socket *s);
-
-/*
- * Stuff internal to module "pcmcia".
- */
-/* ds.c */
-extern struct bus_type pcmcia_bus_type;
-
-/* pcmcia_resource.c */
-extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
-
 #ifdef CONFIG_PCMCIA_IOCTL
 /* ds.c */
-extern spinlock_t pcmcia_dev_list_lock;
-
 extern struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev);
 extern void pcmcia_put_dev(struct pcmcia_device *p_dev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/db1xxx_ss.c linux-libre-2.6.34-gnu1/drivers/pcmcia/db1xxx_ss.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/db1xxx_ss.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/db1xxx_ss.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,580 @@
+/*
+ * PCMCIA socket code for the Alchemy Db1xxx/Pb1xxx boards.
+ *
+ * Copyright (c) 2009 Manuel Lauss <manuel.lauss@gmail.com>
+ *
+ */
+
+/* This is a fairly generic PCMCIA socket driver suitable for the
+ * following Alchemy Development boards:
+ *  Db1000, Db/Pb1500, Db/Pb1100, Db/Pb1550, Db/Pb1200.
+ *
+ * The Db1000 is used as a reference:  Per-socket card-, carddetect- and
+ *  statuschange IRQs connected to SoC GPIOs, control and status register
+ *  bits arranged in per-socket groups in an external PLD.  All boards
+ *  listed here use this layout, including bit positions and meanings.
+ *  Of course there are exceptions in later boards:
+ *
+ *	- Pb1100/Pb1500:  single socket only; voltage key bits VS are
+ *			  at STATUS[5:4] (instead of STATUS[1:0]).
+ *	- Au1200-based:	  additional card-eject irqs, irqs not gpios!
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/resource.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/ss.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+#define MEM_MAP_SIZE	0x400000
+#define IO_MAP_SIZE	0x1000
+
+struct db1x_pcmcia_sock {
+	struct pcmcia_socket	socket;
+	int		nr;		/* socket number */
+	void		*virt_io;
+
+	phys_addr_t	phys_io;
+	phys_addr_t	phys_attr;
+	phys_addr_t	phys_mem;
+
+	/* previous flags for set_socket() */
+	unsigned int old_flags;
+
+	/* interrupt sources: linux irq numbers! */
+	int	insert_irq;	/* default carddetect irq */
+	int	stschg_irq;	/* card-status-change irq */
+	int	card_irq;	/* card irq */
+	int	eject_irq;	/* db1200/pb1200 have these */
+
+#define BOARD_TYPE_DEFAULT	0	/* most boards */
+#define BOARD_TYPE_DB1200	1	/* IRQs aren't gpios */
+#define BOARD_TYPE_PB1100	2	/* VS bits slightly different */
+	int	board_type;
+};
+
+#define to_db1x_socket(x) container_of(x, struct db1x_pcmcia_sock, socket)
+
+/* DB/PB1200: check CPLD SIGSTATUS register bit 10/12 */
+static int db1200_card_inserted(struct db1x_pcmcia_sock *sock)
+{
+	unsigned short sigstat;
+
+	sigstat = bcsr_read(BCSR_SIGSTAT);
+	return sigstat & 1 << (8 + 2 * sock->nr);
+}
+
+/* carddetect gpio: low-active */
+static int db1000_card_inserted(struct db1x_pcmcia_sock *sock)
+{
+	return !gpio_get_value(irq_to_gpio(sock->insert_irq));
+}
+
+static int db1x_card_inserted(struct db1x_pcmcia_sock *sock)
+{
+	switch (sock->board_type) {
+	case BOARD_TYPE_DB1200:
+		return db1200_card_inserted(sock);
+	default:
+		return db1000_card_inserted(sock);
+	}
+}
+
+/* STSCHG tends to bounce heavily when cards are inserted/ejected.
+ * To avoid this, the interrupt is normally disabled and only enabled
+ * after reset to a card has been de-asserted.
+ */
+static inline void set_stschg(struct db1x_pcmcia_sock *sock, int en)
+{
+	if (sock->stschg_irq != -1) {
+		if (en)
+			enable_irq(sock->stschg_irq);
+		else
+			disable_irq(sock->stschg_irq);
+	}
+}
+
+static irqreturn_t db1000_pcmcia_cdirq(int irq, void *data)
+{
+	struct db1x_pcmcia_sock *sock = data;
+
+	pcmcia_parse_events(&sock->socket, SS_DETECT);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t db1000_pcmcia_stschgirq(int irq, void *data)
+{
+	struct db1x_pcmcia_sock *sock = data;
+
+	pcmcia_parse_events(&sock->socket, SS_STSCHG);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t db1200_pcmcia_cdirq(int irq, void *data)
+{
+	struct db1x_pcmcia_sock *sock = data;
+
+	/* Db/Pb1200 have separate per-socket insertion and ejection
+	 * interrupts which stay asserted as long as the card is
+	 * inserted/missing.  The one which caused us to be called
+	 * needs to be disabled and the other one enabled.
+	 */
+	if (irq == sock->insert_irq) {
+		disable_irq_nosync(sock->insert_irq);
+		enable_irq(sock->eject_irq);
+	} else {
+		disable_irq_nosync(sock->eject_irq);
+		enable_irq(sock->insert_irq);
+	}
+
+	pcmcia_parse_events(&sock->socket, SS_DETECT);
+
+	return IRQ_HANDLED;
+}
+
+static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
+{
+	int ret;
+
+	if (sock->stschg_irq != -1) {
+		ret = request_irq(sock->stschg_irq, db1000_pcmcia_stschgirq,
+				  0, "pcmcia_stschg", sock);
+		if (ret)
+			return ret;
+	}
+
+	/* Db/Pb1200 have separate per-socket insertion and ejection
+	 * interrupts, which should show edge behaviour but don't.
+	 * So interrupts are disabled until both insertion and
+	 * ejection handler have been registered and the currently
+	 * active one disabled.
+	 */
+	if (sock->board_type == BOARD_TYPE_DB1200) {
+		ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq,
+				  IRQF_DISABLED, "pcmcia_insert", sock);
+		if (ret)
+			goto out1;
+
+		ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq,
+				  IRQF_DISABLED, "pcmcia_eject", sock);
+		if (ret) {
+			free_irq(sock->insert_irq, sock);
+			goto out1;
+		}
+
+		/* enable the currently silent one */
+		if (db1200_card_inserted(sock))
+			enable_irq(sock->eject_irq);
+		else
+			enable_irq(sock->insert_irq);
+	} else {
+		/* all other (older) Db1x00 boards use a GPIO to show
+		 * card detection status:  use both-edge triggers.
+		 */
+		set_irq_type(sock->insert_irq, IRQ_TYPE_EDGE_BOTH);
+		ret = request_irq(sock->insert_irq, db1000_pcmcia_cdirq,
+				  0, "pcmcia_carddetect", sock);
+
+		if (ret)
+			goto out1;
+	}
+
+	return 0;	/* all done */
+
+out1:
+	if (sock->stschg_irq != -1)
+		free_irq(sock->stschg_irq, sock);
+
+	return ret;
+}
+
+static void db1x_pcmcia_free_irqs(struct db1x_pcmcia_sock *sock)
+{
+	if (sock->stschg_irq != -1)
+		free_irq(sock->stschg_irq, sock);
+
+	free_irq(sock->insert_irq, sock);
+	if (sock->eject_irq != -1)
+		free_irq(sock->eject_irq, sock);
+}
+
+/*
+ * configure a PCMCIA socket on the Db1x00 series of boards (and
+ * compatibles).
+ *
+ * 2 external registers are involved:
+ *   pcmcia_status (offset 0x04): bits [0:1/2:3]: read card voltage id
+ *   pcmcia_control(offset 0x10):
+ *	bits[0:1] set vcc for card
+ *	bits[2:3] set vpp for card
+ *	bit 4:	enable data buffers
+ *	bit 7:	reset# for card
+ *	add 8 for second socket.
+ */
+static int db1x_pcmcia_configure(struct pcmcia_socket *skt,
+				 struct socket_state_t *state)
+{
+	struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
+	unsigned short cr_clr, cr_set;
+	unsigned int changed;
+	int v, p, ret;
+
+	/* card voltage setup */
+	cr_clr = (0xf << (sock->nr * 8)); /* clear voltage settings */
+	cr_set = 0;
+	v = p = ret = 0;
+
+	switch (state->Vcc) {
+	case 50:
+		++v;
+	case 33:
+		++v;
+	case 0:
+		break;
+	default:
+		printk(KERN_INFO "pcmcia%d unsupported Vcc %d\n",
+			sock->nr, state->Vcc);
+	}
+
+	switch (state->Vpp) {
+	case 12:
+		++p;
+	case 33:
+	case 50:
+		++p;
+	case 0:
+		break;
+	default:
+		printk(KERN_INFO "pcmcia%d unsupported Vpp %d\n",
+			sock->nr, state->Vpp);
+	}
+
+	/* sanity check: Vpp must be 0, 12, or Vcc */
+	if (((state->Vcc == 33) && (state->Vpp == 50)) ||
+	    ((state->Vcc == 50) && (state->Vpp == 33))) {
+		printk(KERN_INFO "pcmcia%d bad Vcc/Vpp combo (%d %d)\n",
+			sock->nr, state->Vcc, state->Vpp);
+		v = p = 0;
+		ret = -EINVAL;
+	}
+
+	/* create new voltage code */
+	cr_set |= ((v << 2) | p) << (sock->nr * 8);
+
+	changed = state->flags ^ sock->old_flags;
+
+	if (changed & SS_RESET) {
+		if (state->flags & SS_RESET) {
+			set_stschg(sock, 0);
+			/* assert reset, disable io buffers */
+			cr_clr |= (1 << (7 + (sock->nr * 8)));
+			cr_clr |= (1 << (4 + (sock->nr * 8)));
+		} else {
+			/* de-assert reset, enable io buffers */
+			cr_set |= 1 << (7 + (sock->nr * 8));
+			cr_set |= 1 << (4 + (sock->nr * 8));
+		}
+	}
+
+	/* update PCMCIA configuration */
+	bcsr_mod(BCSR_PCMCIA, cr_clr, cr_set);
+
+	sock->old_flags = state->flags;
+
+	/* reset was taken away: give card time to initialize properly */
+	if ((changed & SS_RESET) && !(state->flags & SS_RESET)) {
+		msleep(500);
+		set_stschg(sock, 1);
+	}
+
+	return ret;
+}
+
+/* VCC bits at [3:2]/[11:10] */
+#define GET_VCC(cr, socknr)		\
+	((((cr) >> 2) >> ((socknr) * 8)) & 3)
+
+/* VS bits at [0:1]/[3:2] */
+#define GET_VS(sr, socknr)		\
+	(((sr) >> (2 * (socknr))) & 3)
+
+/* reset bits at [7]/[15] */
+#define GET_RESET(cr, socknr)		\
+	((cr) & (1 << (7 + (8 * (socknr)))))
+
+static int db1x_pcmcia_get_status(struct pcmcia_socket *skt,
+				  unsigned int *value)
+{
+	struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
+	unsigned short cr, sr;
+	unsigned int status;
+
+	status = db1x_card_inserted(sock) ? SS_DETECT : 0;
+
+	cr = bcsr_read(BCSR_PCMCIA);
+	sr = bcsr_read(BCSR_STATUS);
+
+	/* PB1100/PB1500: voltage key bits are at [5:4] */
+	if (sock->board_type == BOARD_TYPE_PB1100)
+		sr >>= 4;
+
+	/* determine card type */
+	switch (GET_VS(sr, sock->nr)) {
+	case 0:
+	case 2:
+		status |= SS_3VCARD;	/* 3V card */
+	case 3:
+		break;			/* 5V card: set nothing */
+	default:
+		status |= SS_XVCARD;	/* treated as unsupported in core */
+	}
+
+	/* if Vcc is not zero, we have applied power to a card */
+	status |= GET_VCC(cr, sock->nr) ? SS_POWERON : 0;
+
+	/* reset de-asserted? then we're ready */
+	status |= (GET_RESET(cr, sock->nr)) ? SS_READY : SS_RESET;
+
+	*value = status;
+
+	return 0;
+}
+
+static int db1x_pcmcia_sock_init(struct pcmcia_socket *skt)
+{
+	return 0;
+}
+
+static int db1x_pcmcia_sock_suspend(struct pcmcia_socket *skt)
+{
+	return 0;
+}
+
+static int au1x00_pcmcia_set_io_map(struct pcmcia_socket *skt,
+				    struct pccard_io_map *map)
+{
+	struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
+
+	map->start = (u32)sock->virt_io;
+	map->stop = map->start + IO_MAP_SIZE;
+
+	return 0;
+}
+
+static int au1x00_pcmcia_set_mem_map(struct pcmcia_socket *skt,
+				     struct pccard_mem_map *map)
+{
+	struct db1x_pcmcia_sock *sock = to_db1x_socket(skt);
+
+	if (map->flags & MAP_ATTRIB)
+		map->static_start = sock->phys_attr + map->card_start;
+	else
+		map->static_start = sock->phys_mem + map->card_start;
+
+	return 0;
+}
+
+static struct pccard_operations db1x_pcmcia_operations = {
+	.init			= db1x_pcmcia_sock_init,
+	.suspend		= db1x_pcmcia_sock_suspend,
+	.get_status		= db1x_pcmcia_get_status,
+	.set_socket		= db1x_pcmcia_configure,
+	.set_io_map		= au1x00_pcmcia_set_io_map,
+	.set_mem_map		= au1x00_pcmcia_set_mem_map,
+};
+
+static int __devinit db1x_pcmcia_socket_probe(struct platform_device *pdev)
+{
+	struct db1x_pcmcia_sock *sock;
+	struct resource *r;
+	int ret, bid;
+
+	sock = kzalloc(sizeof(struct db1x_pcmcia_sock), GFP_KERNEL);
+	if (!sock)
+		return -ENOMEM;
+
+	sock->nr = pdev->id;
+
+	bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
+	switch (bid) {
+	case BCSR_WHOAMI_PB1500:
+	case BCSR_WHOAMI_PB1500R2:
+	case BCSR_WHOAMI_PB1100:
+		sock->board_type = BOARD_TYPE_PB1100;
+		break;
+	case BCSR_WHOAMI_DB1000 ... BCSR_WHOAMI_PB1550_SDR:
+		sock->board_type = BOARD_TYPE_DEFAULT;
+		break;
+	case BCSR_WHOAMI_PB1200 ... BCSR_WHOAMI_DB1200:
+		sock->board_type = BOARD_TYPE_DB1200;
+		break;
+	default:
+		printk(KERN_INFO "db1xxx-ss: unknown board %d!\n", bid);
+		ret = -ENODEV;
+		goto out0;
+	};
+
+	/*
+	 * gather resources necessary and optional nice-to-haves to
+	 * operate a socket:
+	 * This includes IRQs for Carddetection/ejection, the card
+	 *  itself and optional status change detection.
+	 * Also, the memory areas covered by a socket.  For these
+	 *  we require the real 36bit addresses (see the au1000.h
+	 *  header for more information).
+	 */
+
+	/* card: irq assigned to the card itself. */
+	r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "card");
+	sock->card_irq = r ? r->start : 0;
+
+	/* insert: irq which triggers on card insertion/ejection */
+	r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "insert");
+	sock->insert_irq = r ? r->start : -1;
+
+	/* stschg: irq which trigger on card status change (optional) */
+	r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "stschg");
+	sock->stschg_irq = r ? r->start : -1;
+
+	/* eject: irq which triggers on ejection (DB1200/PB1200 only) */
+	r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "eject");
+	sock->eject_irq = r ? r->start : -1;
+
+	ret = -ENODEV;
+
+	/* 36bit PCMCIA Attribute area address */
+	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-attr");
+	if (!r) {
+		printk(KERN_ERR "pcmcia%d has no 'pseudo-attr' resource!\n",
+			sock->nr);
+		goto out0;
+	}
+	sock->phys_attr = r->start;
+
+	/* 36bit PCMCIA Memory area address */
+	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-mem");
+	if (!r) {
+		printk(KERN_ERR "pcmcia%d has no 'pseudo-mem' resource!\n",
+			sock->nr);
+		goto out0;
+	}
+	sock->phys_mem = r->start;
+
+	/* 36bit PCMCIA IO area address */
+	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-io");
+	if (!r) {
+		printk(KERN_ERR "pcmcia%d has no 'pseudo-io' resource!\n",
+			sock->nr);
+		goto out0;
+	}
+	sock->phys_io = r->start;
+
+	/*
+	 * PCMCIA client drivers use the inb/outb macros to access
+	 * the IO registers.  Since mips_io_port_base is added
+	 * to the access address of the mips implementation of
+	 * inb/outb, we need to subtract it here because we want
+	 * to access the I/O or MEM address directly, without
+	 * going through this "mips_io_port_base" mechanism.
+	 */
+	sock->virt_io = (void *)(ioremap(sock->phys_io, IO_MAP_SIZE) -
+				 mips_io_port_base);
+
+	if (!sock->virt_io) {
+		printk(KERN_ERR "pcmcia%d: cannot remap IO area\n",
+			sock->nr);
+		ret = -ENOMEM;
+		goto out0;
+	}
+
+	sock->socket.ops	= &db1x_pcmcia_operations;
+	sock->socket.owner	= THIS_MODULE;
+	sock->socket.pci_irq	= sock->card_irq;
+	sock->socket.features	= SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
+	sock->socket.map_size	= MEM_MAP_SIZE;
+	sock->socket.io_offset	= (unsigned long)sock->virt_io;
+	sock->socket.dev.parent	= &pdev->dev;
+	sock->socket.resource_ops = &pccard_static_ops;
+
+	platform_set_drvdata(pdev, sock);
+
+	ret = db1x_pcmcia_setup_irqs(sock);
+	if (ret) {
+		printk(KERN_ERR "pcmcia%d cannot setup interrupts\n",
+			sock->nr);
+		goto out1;
+	}
+
+	set_stschg(sock, 0);
+
+	ret = pcmcia_register_socket(&sock->socket);
+	if (ret) {
+		printk(KERN_ERR "pcmcia%d failed to register\n", sock->nr);
+		goto out2;
+	}
+
+	printk(KERN_INFO "Alchemy Db/Pb1xxx pcmcia%d @ io/attr/mem %09llx"
+		"(%p) %09llx %09llx  card/insert/stschg/eject irqs @ %d "
+		"%d %d %d\n", sock->nr, sock->phys_io, sock->virt_io,
+		sock->phys_attr, sock->phys_mem, sock->card_irq,
+		sock->insert_irq, sock->stschg_irq, sock->eject_irq);
+
+	return 0;
+
+out2:
+	db1x_pcmcia_free_irqs(sock);
+out1:
+	iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
+out0:
+	kfree(sock);
+	return ret;
+}
+
+static int __devexit db1x_pcmcia_socket_remove(struct platform_device *pdev)
+{
+	struct db1x_pcmcia_sock *sock = platform_get_drvdata(pdev);
+
+	db1x_pcmcia_free_irqs(sock);
+	pcmcia_unregister_socket(&sock->socket);
+	iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
+	kfree(sock);
+
+	return 0;
+}
+
+static struct platform_driver db1x_pcmcia_socket_driver = {
+	.driver	= {
+		.name	= "db1xxx_pcmcia",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= db1x_pcmcia_socket_probe,
+	.remove		= __devexit_p(db1x_pcmcia_socket_remove),
+};
+
+int __init db1x_pcmcia_socket_load(void)
+{
+	return platform_driver_register(&db1x_pcmcia_socket_driver);
+}
+
+void  __exit db1x_pcmcia_socket_unload(void)
+{
+	platform_driver_unregister(&db1x_pcmcia_socket_driver);
+}
+
+module_init(db1x_pcmcia_socket_load);
+module_exit(db1x_pcmcia_socket_unload);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PCMCIA Socket Services for Alchemy Db/Pb1x00 boards");
+MODULE_AUTHOR("Manuel Lauss");
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/ds.c linux-libre-2.6.34-gnu1/drivers/pcmcia/ds.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/ds.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/ds.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/firmware.h>
 #include <linux/kref.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
@@ -42,8 +43,6 @@ MODULE_DESCRIPTION("PCMCIA Driver Servic
 MODULE_LICENSE("GPL");
 
 
-spinlock_t pcmcia_dev_list_lock;
-
 /*====================================================================*/
 
 static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
@@ -126,9 +125,9 @@ pcmcia_store_new_id(struct device_driver
 	dynid->id.device_no = device_no;
 	memcpy(dynid->id.prod_id_hash, prod_id_hash, sizeof(__u32) * 4);
 
-	spin_lock(&pdrv->dynids.lock);
+	mutex_lock(&pdrv->dynids.lock);
 	list_add_tail(&dynid->node, &pdrv->dynids.list);
-	spin_unlock(&pdrv->dynids.lock);
+	mutex_unlock(&pdrv->dynids.lock);
 
 	if (get_driver(&pdrv->drv)) {
 		retval = driver_attach(&pdrv->drv);
@@ -146,12 +145,12 @@ pcmcia_free_dynids(struct pcmcia_driver
 {
 	struct pcmcia_dynid *dynid, *n;
 
-	spin_lock(&drv->dynids.lock);
+	mutex_lock(&drv->dynids.lock);
 	list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
 		list_del(&dynid->node);
 		kfree(dynid);
 	}
-	spin_unlock(&drv->dynids.lock);
+	mutex_unlock(&drv->dynids.lock);
 }
 
 static int
@@ -182,7 +181,7 @@ int pcmcia_register_driver(struct pcmcia
 	/* initialize common fields */
 	driver->drv.bus = &pcmcia_bus_type;
 	driver->drv.owner = driver->owner;
-	spin_lock_init(&driver->dynids.lock);
+	mutex_init(&driver->dynids.lock);
 	INIT_LIST_HEAD(&driver->dynids.list);
 
 	pr_debug("registering driver %s\n", driver->drv.name);
@@ -239,30 +238,21 @@ static void pcmcia_release_function(stru
 static void pcmcia_release_dev(struct device *dev)
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+	int i;
 	dev_dbg(dev, "releasing device\n");
 	pcmcia_put_socket(p_dev->socket);
+	for (i = 0; i < 4; i++)
+		kfree(p_dev->prod_id[i]);
 	kfree(p_dev->devname);
 	kref_put(&p_dev->function_config->ref, pcmcia_release_function);
 	kfree(p_dev);
 }
 
-static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc)
-{
-	if (!s->pcmcia_state.device_add_pending) {
-		dev_dbg(&s->dev, "scheduling to add %s secondary"
-		       " device to %d\n", mfc ? "mfc" : "pfc", s->sock);
-		s->pcmcia_state.device_add_pending = 1;
-		s->pcmcia_state.mfc_pfc = mfc;
-		schedule_work(&s->device_add);
-	}
-	return;
-}
 
 static int pcmcia_device_probe(struct device *dev)
 {
 	struct pcmcia_device *p_dev;
 	struct pcmcia_driver *p_drv;
-	struct pcmcia_device_id *did;
 	struct pcmcia_socket *s;
 	cistpl_config_t cis_config;
 	int ret = 0;
@@ -275,18 +265,6 @@ static int pcmcia_device_probe(struct de
 	p_drv = to_pcmcia_drv(dev->driver);
 	s = p_dev->socket;
 
-	/* The PCMCIA code passes the match data in via dev_set_drvdata(dev)
-	 * which is an ugly hack. Once the driver probe is called it may
-	 * and often will overwrite the match data so we must save it first
-	 *
-	 * handle pseudo multifunction devices:
-	 * there are at most two pseudo multifunction devices.
-	 * if we're matching against the first, schedule a
-	 * call which will then check whether there are two
-	 * pseudo devices, and if not, add the second one.
-	 */
-	did = dev_get_drvdata(&p_dev->dev);
-
 	dev_dbg(dev, "trying to bind to %s\n", p_drv->drv.name);
 
 	if ((!p_drv->probe) || (!p_dev->function_config) ||
@@ -315,9 +293,11 @@ static int pcmcia_device_probe(struct de
 		goto put_module;
 	}
 
-	if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
+	mutex_lock(&s->ops_mutex);
+	if ((s->pcmcia_state.has_pfc) &&
 	    (p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
-		pcmcia_add_device_later(p_dev->socket, 0);
+		pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);
+	mutex_unlock(&s->ops_mutex);
 
 put_module:
 	if (ret)
@@ -336,26 +316,26 @@ static void pcmcia_card_remove(struct pc
 {
 	struct pcmcia_device	*p_dev;
 	struct pcmcia_device	*tmp;
-	unsigned long		flags;
 
 	dev_dbg(leftover ? &leftover->dev : &s->dev,
 		   "pcmcia_card_remove(%d) %s\n", s->sock,
 		   leftover ? leftover->devname : "");
 
+	mutex_lock(&s->ops_mutex);
 	if (!leftover)
 		s->device_count = 0;
 	else
 		s->device_count = 1;
+	mutex_unlock(&s->ops_mutex);
 
 	/* unregister all pcmcia_devices registered with this socket, except leftover */
 	list_for_each_entry_safe(p_dev, tmp, &s->devices_list, socket_device_list) {
 		if (p_dev == leftover)
 			continue;
 
-		spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+		mutex_lock(&s->ops_mutex);
 		list_del(&p_dev->socket_device_list);
-		p_dev->_removed = 1;
-		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+		mutex_unlock(&s->ops_mutex);
 
 		dev_dbg(&p_dev->dev, "unregistering device\n");
 		device_unregister(&p_dev->dev);
@@ -368,7 +348,6 @@ static int pcmcia_device_remove(struct d
 {
 	struct pcmcia_device *p_dev;
 	struct pcmcia_driver *p_drv;
-	struct pcmcia_device_id *did;
 	int i;
 
 	p_dev = to_pcmcia_dev(dev);
@@ -380,9 +359,8 @@ static int pcmcia_device_remove(struct d
 	 * pseudo multi-function card, we need to unbind
 	 * all devices
 	 */
-	did = dev_get_drvdata(&p_dev->dev);
-	if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
-	    (p_dev->socket->device_count != 0) &&
+	if ((p_dev->socket->pcmcia_state.has_pfc) &&
+	    (p_dev->socket->device_count > 0) &&
 	    (p_dev->device_no == 0))
 		pcmcia_card_remove(p_dev->socket, p_dev);
 
@@ -431,16 +409,20 @@ static int pcmcia_device_query(struct pc
 
 	if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL,
 			       CISTPL_MANFID, &manf_id)) {
+		mutex_lock(&p_dev->socket->ops_mutex);
 		p_dev->manf_id = manf_id.manf;
 		p_dev->card_id = manf_id.card;
 		p_dev->has_manf_id = 1;
 		p_dev->has_card_id = 1;
+		mutex_unlock(&p_dev->socket->ops_mutex);
 	}
 
 	if (!pccard_read_tuple(p_dev->socket, p_dev->func,
 			       CISTPL_FUNCID, &func_id)) {
+		mutex_lock(&p_dev->socket->ops_mutex);
 		p_dev->func_id = func_id.func;
 		p_dev->has_func_id = 1;
+		mutex_unlock(&p_dev->socket->ops_mutex);
 	} else {
 		/* rule of thumb: cards with no FUNCID, but with
 		 * common memory device geometry information, are
@@ -457,17 +439,21 @@ static int pcmcia_device_query(struct pc
 			dev_dbg(&p_dev->dev,
 				   "mem device geometry probably means "
 				   "FUNCID_MEMORY\n");
+			mutex_lock(&p_dev->socket->ops_mutex);
 			p_dev->func_id = CISTPL_FUNCID_MEMORY;
 			p_dev->has_func_id = 1;
+			mutex_unlock(&p_dev->socket->ops_mutex);
 		}
 		kfree(devgeo);
 	}
 
 	if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL, CISTPL_VERS_1,
 			       vers1)) {
+		mutex_lock(&p_dev->socket->ops_mutex);
 		for (i = 0; i < min_t(unsigned int, 4, vers1->ns); i++) {
 			char *tmp;
 			unsigned int length;
+			char *new;
 
 			tmp = vers1->str + vers1->ofs[i];
 
@@ -475,14 +461,17 @@ static int pcmcia_device_query(struct pc
 			if ((length < 2) || (length > 255))
 				continue;
 
-			p_dev->prod_id[i] = kmalloc(sizeof(char) * length,
-						    GFP_KERNEL);
-			if (!p_dev->prod_id[i])
+			new = kmalloc(sizeof(char) * length, GFP_KERNEL);
+			if (!new)
 				continue;
 
-			p_dev->prod_id[i] = strncpy(p_dev->prod_id[i],
-						    tmp, length);
+			new = strncpy(new, tmp, length);
+
+			tmp = p_dev->prod_id[i];
+			p_dev->prod_id[i] = new;
+			kfree(tmp);
 		}
+		mutex_unlock(&p_dev->socket->ops_mutex);
 	}
 
 	kfree(vers1);
@@ -502,7 +491,7 @@ static DEFINE_MUTEX(device_add_lock);
 struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function)
 {
 	struct pcmcia_device *p_dev, *tmp_dev;
-	unsigned long flags;
+	int i;
 
 	s = pcmcia_get_socket(s);
 	if (!s)
@@ -512,16 +501,23 @@ struct pcmcia_device *pcmcia_device_add(
 
 	pr_debug("adding device to %d, function %d\n", s->sock, function);
 
-	/* max of 4 devices per card */
-	if (s->device_count == 4)
-		goto err_put;
-
 	p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL);
 	if (!p_dev)
 		goto err_put;
 
-	p_dev->socket = s;
+	mutex_lock(&s->ops_mutex);
 	p_dev->device_no = (s->device_count++);
+	mutex_unlock(&s->ops_mutex);
+
+	/* max of 2 PFC devices */
+	if ((p_dev->device_no >= 2) && (function == 0))
+		goto err_free;
+
+	/* max of 4 devices overall */
+	if (p_dev->device_no >= 4)
+		goto err_free;
+
+	p_dev->socket = s;
 	p_dev->func   = function;
 
 	p_dev->dev.bus = &pcmcia_bus_type;
@@ -538,7 +534,7 @@ struct pcmcia_device *pcmcia_device_add(
 		goto err_free;
 	dev_dbg(&p_dev->dev, "devname is %s\n", p_dev->devname);
 
-	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+	mutex_lock(&s->ops_mutex);
 
 	/*
 	 * p_dev->function_config must be the same for all card functions.
@@ -556,7 +552,7 @@ struct pcmcia_device *pcmcia_device_add(
 	/* Add to the list in pcmcia_bus_socket */
 	list_add(&p_dev->socket_device_list, &s->devices_list);
 
-	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+	mutex_unlock(&s->ops_mutex);
 
 	if (!p_dev->function_config) {
 		dev_dbg(&p_dev->dev, "creating config_t\n");
@@ -581,14 +577,19 @@ struct pcmcia_device *pcmcia_device_add(
 	return p_dev;
 
  err_unreg:
-	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+	mutex_lock(&s->ops_mutex);
 	list_del(&p_dev->socket_device_list);
-	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+	mutex_unlock(&s->ops_mutex);
 
  err_free:
+	mutex_lock(&s->ops_mutex);
+	s->device_count--;
+	mutex_unlock(&s->ops_mutex);
+
+	for (i = 0; i < 4; i++)
+		kfree(p_dev->prod_id[i]);
 	kfree(p_dev->devname);
 	kfree(p_dev);
-	s->device_count--;
  err_put:
 	mutex_unlock(&device_add_lock);
 	pcmcia_put_socket(s);
@@ -601,19 +602,23 @@ static int pcmcia_card_add(struct pcmcia
 {
 	cistpl_longlink_mfc_t mfc;
 	unsigned int no_funcs, i, no_chains;
-	int ret = 0;
+	int ret = -EAGAIN;
 
+	mutex_lock(&s->ops_mutex);
 	if (!(s->resource_setup_done)) {
 		dev_dbg(&s->dev,
 			   "no resources available, delaying card_add\n");
+		mutex_unlock(&s->ops_mutex);
 		return -EAGAIN; /* try again, but later... */
 	}
 
 	if (pcmcia_validate_mem(s)) {
 		dev_dbg(&s->dev, "validating mem resources failed, "
 		       "delaying card_add\n");
+		mutex_unlock(&s->ops_mutex);
 		return -EAGAIN; /* try again, but later... */
 	}
+	mutex_unlock(&s->ops_mutex);
 
 	ret = pccard_validate_cis(s, &no_chains);
 	if (ret || !no_chains) {
@@ -634,17 +639,7 @@ static int pcmcia_card_add(struct pcmcia
 }
 
 
-static void pcmcia_delayed_add_device(struct work_struct *work)
-{
-	struct pcmcia_socket *s =
-		container_of(work, struct pcmcia_socket, device_add);
-	dev_dbg(&s->dev, "adding additional device to %d\n", s->sock);
-	pcmcia_device_add(s, s->pcmcia_state.mfc_pfc);
-	s->pcmcia_state.device_add_pending = 0;
-	s->pcmcia_state.mfc_pfc = 0;
-}
-
-static int pcmcia_requery(struct device *dev, void * _data)
+static int pcmcia_requery_callback(struct device *dev, void * _data)
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
 	if (!p_dev->dev.driver) {
@@ -655,45 +650,58 @@ static int pcmcia_requery(struct device
 	return 0;
 }
 
-static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis)
-{
-	int no_devices = 0;
-	int ret = 0;
-	unsigned long flags;
-
-	/* must be called with skt_mutex held */
-	dev_dbg(&skt->dev, "re-scanning socket %d\n", skt->sock);
-
-	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
-	if (list_empty(&skt->devices_list))
-		no_devices = 1;
-	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 
-	/* If this is because of a CIS override, start over */
-	if (new_cis && !no_devices)
-		pcmcia_card_remove(skt, NULL);
+static void pcmcia_requery(struct pcmcia_socket *s)
+{
+	int has_pfc;
 
-	/* if no devices were added for this socket yet because of
-	 * missing resource information or other trouble, we need to
-	 * do this now. */
-	if (no_devices || new_cis) {
-		ret = pcmcia_card_add(skt);
-		if (ret)
-			return;
+	if (s->functions == 0) {
+		pcmcia_card_add(s);
+		return;
 	}
 
 	/* some device information might have changed because of a CIS
 	 * update or because we can finally read it correctly... so
 	 * determine it again, overwriting old values if necessary. */
-	bus_for_each_dev(&pcmcia_bus_type, NULL, NULL, pcmcia_requery);
+	bus_for_each_dev(&pcmcia_bus_type, NULL, NULL, pcmcia_requery_callback);
+
+	/* if the CIS changed, we need to check whether the number of
+	 * functions changed. */
+	if (s->fake_cis) {
+		int old_funcs, new_funcs;
+		cistpl_longlink_mfc_t mfc;
+
+		/* does this cis override add or remove functions? */
+		old_funcs = s->functions;
+
+		if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC,
+					&mfc))
+			new_funcs = mfc.nfn;
+		else
+			new_funcs = 1;
+		if (old_funcs != new_funcs) {
+			/* we need to re-start */
+			pcmcia_card_remove(s, NULL);
+			pcmcia_card_add(s);
+		}
+	}
+
+	/* If the PCMCIA device consists of two pseudo devices,
+	 * call pcmcia_device_add() -- which will fail if both
+	 * devices are already registered. */
+	mutex_lock(&s->ops_mutex);
+	has_pfc = s->pcmcia_state.has_pfc;
+	mutex_unlock(&s->ops_mutex);
+	if (has_pfc)
+		pcmcia_device_add(s, 0);
 
 	/* we re-scan all devices, not just the ones connected to this
 	 * socket. This does not matter, though. */
-	ret = bus_rescan_devices(&pcmcia_bus_type);
-	if (ret)
-		printk(KERN_INFO "pcmcia: bus_rescan_devices failed\n");
+	if (bus_rescan_devices(&pcmcia_bus_type))
+		dev_warn(&s->dev, "rescanning the bus failed\n");
 }
 
+
 #ifdef CONFIG_PCMCIA_LOAD_CIS
 
 /**
@@ -710,9 +718,8 @@ static int pcmcia_load_firmware(struct p
 	struct pcmcia_socket *s = dev->socket;
 	const struct firmware *fw;
 	int ret = -ENOMEM;
-	int no_funcs;
-	int old_funcs;
 	cistpl_longlink_mfc_t mfc;
+	int old_funcs, new_funcs = 1;
 
 	if (!filename)
 		return -EINVAL;
@@ -735,23 +742,20 @@ static int pcmcia_load_firmware(struct p
 			goto release;
 		}
 
+		/* we need to re-start if the number of functions changed */
+		old_funcs = s->functions;
+		if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC,
+					&mfc))
+			new_funcs = mfc.nfn;
+
+		if (old_funcs != new_funcs)
+			ret = -EBUSY;
 
 		/* update information */
 		pcmcia_device_query(dev);
 
-		/* does this cis override add or remove functions? */
-		old_funcs = s->functions;
-
-		if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, &mfc))
-			no_funcs = mfc.nfn;
-		else
-			no_funcs = 1;
-		s->functions = no_funcs;
-
-		if (old_funcs > no_funcs)
-			pcmcia_card_remove(s, dev);
-		else if (no_funcs > old_funcs)
-			pcmcia_add_device_later(s, 1);
+		/* requery (as number of functions might have changed) */
+		pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);
 	}
  release:
 	release_firmware(fw);
@@ -816,17 +820,23 @@ static inline int pcmcia_devmatch(struct
 	}
 
 	if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) {
+		dev_dbg(&dev->dev, "this is a pseudo-multi-function device\n");
+		mutex_lock(&dev->socket->ops_mutex);
+		dev->socket->pcmcia_state.has_pfc = 1;
+		mutex_unlock(&dev->socket->ops_mutex);
 		if (dev->device_no != did->device_no)
 			return 0;
 	}
 
 	if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) {
+		int ret;
+
 		if ((!dev->has_func_id) || (dev->func_id != did->func_id))
 			return 0;
 
 		/* if this is a pseudo-multi-function device,
 		 * we need explicit matches */
-		if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO)
+		if (dev->socket->pcmcia_state.has_pfc)
 			return 0;
 		if (dev->device_no)
 			return 0;
@@ -835,19 +845,22 @@ static inline int pcmcia_devmatch(struct
 		 * after it has re-checked that there is no possible module
 		 * with a prod_id/manf_id/card_id match.
 		 */
-		dev_dbg(&dev->dev,
-			"skipping FUNC_ID match until userspace interaction\n");
-		if (!dev->allow_func_id_match)
+		mutex_lock(&dev->socket->ops_mutex);
+		ret = dev->allow_func_id_match;
+		mutex_unlock(&dev->socket->ops_mutex);
+
+		if (!ret) {
+			dev_dbg(&dev->dev,
+				"skipping FUNC_ID match until userspace ACK\n");
 			return 0;
+		}
 	}
 
 	if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
 		dev_dbg(&dev->dev, "device needs a fake CIS\n");
 		if (!dev->socket->fake_cis)
-			pcmcia_load_firmware(dev, did->cisfile);
-
-		if (!dev->socket->fake_cis)
-			return 0;
+			if (pcmcia_load_firmware(dev, did->cisfile))
+				return 0;
 	}
 
 	if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) {
@@ -859,8 +872,6 @@ static inline int pcmcia_devmatch(struct
 			return 0;
 	}
 
-	dev_set_drvdata(&dev->dev, did);
-
 	return 1;
 }
 
@@ -873,16 +884,16 @@ static int pcmcia_bus_match(struct devic
 	struct pcmcia_dynid *dynid;
 
 	/* match dynamic devices first */
-	spin_lock(&p_drv->dynids.lock);
+	mutex_lock(&p_drv->dynids.lock);
 	list_for_each_entry(dynid, &p_drv->dynids.list, node) {
 		dev_dbg(dev, "trying to match to %s\n", drv->name);
 		if (pcmcia_devmatch(p_dev, &dynid->id)) {
 			dev_dbg(dev, "matched to %s\n", drv->name);
-			spin_unlock(&p_drv->dynids.lock);
+			mutex_unlock(&p_drv->dynids.lock);
 			return 1;
 		}
 	}
-	spin_unlock(&p_drv->dynids.lock);
+	mutex_unlock(&p_drv->dynids.lock);
 
 #ifdef CONFIG_PCMCIA_IOCTL
 	/* matching by cardmgr */
@@ -964,19 +975,20 @@ static int runtime_suspend(struct device
 {
 	int rc;
 
-	down(&dev->sem);
+	device_lock(dev);
 	rc = pcmcia_dev_suspend(dev, PMSG_SUSPEND);
-	up(&dev->sem);
+	device_unlock(dev);
 	return rc;
 }
 
-static void runtime_resume(struct device *dev)
+static int runtime_resume(struct device *dev)
 {
 	int rc;
 
-	down(&dev->sem);
+	device_lock(dev);
 	rc = pcmcia_dev_resume(dev);
-	up(&dev->sem);
+	device_unlock(dev);
+	return rc;
 }
 
 /************************ per-device sysfs output ***************************/
@@ -1027,7 +1039,7 @@ static ssize_t pcmcia_store_pm_state(str
 	if ((!p_dev->suspended) && !strncmp(buf, "off", 3))
 		ret = runtime_suspend(dev);
 	else if (p_dev->suspended && !strncmp(buf, "on", 2))
-		runtime_resume(dev);
+		ret = runtime_resume(dev);
 
 	return ret ? ret : count;
 }
@@ -1059,19 +1071,14 @@ static ssize_t pcmcia_store_allow_func_i
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
-	int ret;
 
 	if (!count)
 		return -EINVAL;
 
-	mutex_lock(&p_dev->socket->skt_mutex);
+	mutex_lock(&p_dev->socket->ops_mutex);
 	p_dev->allow_func_id_match = 1;
-	mutex_unlock(&p_dev->socket->skt_mutex);
-
-	ret = bus_rescan_devices(&pcmcia_bus_type);
-	if (ret)
-		printk(KERN_INFO "pcmcia: bus_rescan_devices failed after "
-		       "allowing func_id matches\n");
+	mutex_unlock(&p_dev->socket->ops_mutex);
+	pcmcia_parse_uevents(p_dev->socket, PCMCIA_UEVENT_REQUERY);
 
 	return count;
 }
@@ -1099,8 +1106,13 @@ static int pcmcia_dev_suspend(struct dev
 	struct pcmcia_driver *p_drv = NULL;
 	int ret = 0;
 
-	if (p_dev->suspended)
+	mutex_lock(&p_dev->socket->ops_mutex);
+	if (p_dev->suspended) {
+		mutex_unlock(&p_dev->socket->ops_mutex);
 		return 0;
+	}
+	p_dev->suspended = 1;
+	mutex_unlock(&p_dev->socket->ops_mutex);
 
 	dev_dbg(dev, "suspending\n");
 
@@ -1117,6 +1129,9 @@ static int pcmcia_dev_suspend(struct dev
 				   "pcmcia: device %s (driver %s) did "
 				   "not want to go to sleep (%d)\n",
 				   p_dev->devname, p_drv->drv.name, ret);
+			mutex_lock(&p_dev->socket->ops_mutex);
+			p_dev->suspended = 0;
+			mutex_unlock(&p_dev->socket->ops_mutex);
 			goto out;
 		}
 	}
@@ -1127,8 +1142,6 @@ static int pcmcia_dev_suspend(struct dev
 	}
 
  out:
-	if (!ret)
-		p_dev->suspended = 1;
 	return ret;
 }
 
@@ -1139,8 +1152,13 @@ static int pcmcia_dev_resume(struct devi
 	struct pcmcia_driver *p_drv = NULL;
 	int ret = 0;
 
-	if (!p_dev->suspended)
+	mutex_lock(&p_dev->socket->ops_mutex);
+	if (!p_dev->suspended) {
+		mutex_unlock(&p_dev->socket->ops_mutex);
 		return 0;
+	}
+	p_dev->suspended = 0;
+	mutex_unlock(&p_dev->socket->ops_mutex);
 
 	dev_dbg(dev, "resuming\n");
 
@@ -1161,8 +1179,6 @@ static int pcmcia_dev_resume(struct devi
 		ret = p_drv->resume(p_dev);
 
  out:
-	if (!ret)
-		p_dev->suspended = 0;
 	return ret;
 }
 
@@ -1237,13 +1253,20 @@ static int ds_event(struct pcmcia_socket
 
 	switch (event) {
 	case CS_EVENT_CARD_REMOVAL:
-		s->pcmcia_state.present = 0;
+		atomic_set(&skt->present, 0);
 		pcmcia_card_remove(skt, NULL);
 		handle_event(skt, event);
+		mutex_lock(&s->ops_mutex);
+		destroy_cis_cache(s);
+		mutex_unlock(&s->ops_mutex);
 		break;
 
 	case CS_EVENT_CARD_INSERTION:
-		s->pcmcia_state.present = 1;
+		atomic_set(&skt->present, 1);
+		mutex_lock(&s->ops_mutex);
+		s->pcmcia_state.has_pfc = 0;
+		destroy_cis_cache(s); /* to be on the safe side... */
+		mutex_unlock(&s->ops_mutex);
 		pcmcia_card_add(skt);
 		handle_event(skt, event);
 		break;
@@ -1251,8 +1274,25 @@ static int ds_event(struct pcmcia_socket
 	case CS_EVENT_EJECTION_REQUEST:
 		break;
 
-	case CS_EVENT_PM_SUSPEND:
 	case CS_EVENT_PM_RESUME:
+		if (verify_cis_cache(skt) != 0) {
+			dev_dbg(&skt->dev, "cis mismatch - different card\n");
+			/* first, remove the card */
+			ds_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
+			mutex_lock(&s->ops_mutex);
+			destroy_cis_cache(skt);
+			kfree(skt->fake_cis);
+			skt->fake_cis = NULL;
+			s->functions = 0;
+			mutex_unlock(&s->ops_mutex);
+			/* now, add the new card */
+			ds_event(skt, CS_EVENT_CARD_INSERTION,
+				 CS_EVENT_PRI_LOW);
+		}
+		handle_event(skt, event);
+		break;
+
+	case CS_EVENT_PM_SUSPEND:
 	case CS_EVENT_RESET_PHYSICAL:
 	case CS_EVENT_CARD_RESET:
 	default:
@@ -1265,7 +1305,13 @@ static int ds_event(struct pcmcia_socket
     return 0;
 } /* ds_event */
 
-
+/*
+ * NOTE: This is racy. There's no guarantee the card will still be
+ * physically present, even if the call to this function returns
+ * non-NULL. Furthermore, the device driver most likely is unbound
+ * almost immediately, so the timeframe where pcmcia_dev_present
+ * returns NULL is probably really really small.
+ */
 struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev)
 {
 	struct pcmcia_device *p_dev;
@@ -1275,17 +1321,9 @@ struct pcmcia_device *pcmcia_dev_present
 	if (!p_dev)
 		return NULL;
 
-	if (!p_dev->socket->pcmcia_state.present)
-		goto out;
-
-	if (p_dev->_removed)
-		goto out;
-
-	if (p_dev->suspended)
-		goto out;
+	if (atomic_read(&p_dev->socket->present) != 0)
+		ret = p_dev;
 
-	ret = p_dev;
- out:
 	pcmcia_put_dev(p_dev);
 	return ret;
 }
@@ -1295,7 +1333,8 @@ EXPORT_SYMBOL(pcmcia_dev_present);
 static struct pcmcia_callback pcmcia_bus_callback = {
 	.owner = THIS_MODULE,
 	.event = ds_event,
-	.requery = pcmcia_bus_rescan,
+	.requery = pcmcia_requery,
+	.validate = pccard_validate_cis,
 	.suspend = pcmcia_bus_suspend,
 	.resume = pcmcia_bus_resume,
 };
@@ -1313,17 +1352,17 @@ static int __devinit pcmcia_bus_add_sock
 		return -ENODEV;
 	}
 
-	/*
-	 * Ugly. But we want to wait for the socket threads to have started up.
-	 * We really should let the drivers themselves drive some of this..
-	 */
-	msleep(250);
+	ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr);
+	if (ret) {
+		dev_printk(KERN_ERR, dev, "PCMCIA registration failed\n");
+		pcmcia_put_socket(socket);
+		return ret;
+	}
 
 #ifdef CONFIG_PCMCIA_IOCTL
 	init_waitqueue_head(&socket->queue);
 #endif
 	INIT_LIST_HEAD(&socket->devices_list);
-	INIT_WORK(&socket->device_add, pcmcia_delayed_add_device);
 	memset(&socket->pcmcia_state, 0, sizeof(u8));
 	socket->device_count = 0;
 
@@ -1334,6 +1373,8 @@ static int __devinit pcmcia_bus_add_sock
 		return ret;
 	}
 
+	atomic_set(&socket->present, 0);
+
 	return 0;
 }
 
@@ -1345,14 +1386,16 @@ static void pcmcia_bus_remove_socket(str
 	if (!socket)
 		return;
 
-	socket->pcmcia_state.dead = 1;
 	pccard_register_pcmcia(socket, NULL);
 
 	/* unregister any unbound devices */
 	mutex_lock(&socket->skt_mutex);
 	pcmcia_card_remove(socket, NULL);
+	release_cis_mem(socket);
 	mutex_unlock(&socket->skt_mutex);
 
+	sysfs_remove_bin_file(&dev->kobj, &pccard_cis_attr);
+
 	pcmcia_put_socket(socket);
 
 	return;
@@ -1383,8 +1426,6 @@ static int __init init_pcmcia_bus(void)
 {
 	int ret;
 
-	spin_lock_init(&pcmcia_dev_list_lock);
-
 	ret = bus_register(&pcmcia_bus_type);
 	if (ret < 0) {
 		printk(KERN_WARNING "pcmcia: bus_register error: %d\n", ret);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/electra_cf.c linux-libre-2.6.34-gnu1/drivers/pcmcia/electra_cf.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/electra_cf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/electra_cf.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 
 #include <pcmcia/ss.h>
 
@@ -347,7 +348,7 @@ static int __devexit electra_cf_remove(s
 	return 0;
 }
 
-static struct of_device_id electra_cf_match[] = {
+static const struct of_device_id electra_cf_match[] = {
 	{
 		.compatible   = "electra-cf",
 	},
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/i82092.c linux-libre-2.6.34-gnu1/drivers/pcmcia/i82092.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/i82092.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/i82092.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,27 +39,11 @@ static struct pci_device_id i82092aa_pci
 };
 MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids);
 
-#ifdef CONFIG_PM
-static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state)
-{
-	return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int i82092aa_socket_resume (struct pci_dev *dev)
-{
-	return pcmcia_socket_dev_resume(&dev->dev);
-}
-#endif
-
 static struct pci_driver i82092aa_pci_driver = {
 	.name           = "i82092aa",
 	.id_table       = i82092aa_pci_ids,
 	.probe          = i82092aa_pci_probe,
 	.remove         = __devexit_p(i82092aa_pci_remove),
-#ifdef CONFIG_PM
-	.suspend        = i82092aa_socket_suspend,
-	.resume         = i82092aa_socket_resume,
-#endif
 };
 
 
@@ -133,6 +117,7 @@ static int __devinit i82092aa_pci_probe(
 		sockets[i].socket.map_size = 0x1000;
 		sockets[i].socket.irq_mask = 0;
 		sockets[i].socket.pci_irq  = dev->irq;
+		sockets[i].socket.cb_dev  = dev;
 		sockets[i].socket.owner = THIS_MODULE;
 
 		sockets[i].number = i;
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/i82365.c linux-libre-2.6.34-gnu1/drivers/pcmcia/i82365.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/i82365.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/i82365.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,7 +40,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/timer.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
@@ -1223,16 +1222,7 @@ 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);
-}
 
-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,8 +1238,6 @@ static struct platform_driver i82365_dri
 		.name = "i82365",
 		.owner		= THIS_MODULE,
 	},
-	.suspend 	= i82365_drv_pcmcia_suspend,
-	.resume 	= i82365_drv_pcmcia_resume,
 };
 
 static struct platform_device *i82365_device;
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/i82365.h linux-libre-2.6.34-gnu1/drivers/pcmcia/i82365.h
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/i82365.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/i82365.h	2010-05-16 17:17:36.000000000 -0400
@@ -77,8 +77,8 @@
 #define I365_VPP2_5V	0x04	/* Vpp2 = 5.0v */
 #define I365_VPP2_12V	0x08	/* Vpp2 = 12.0v */
 #define I365_VPP1_MASK	0x03	/* Mask for turning off Vpp1 */
-#define I365_VPP1_5V	0x01	/* Vpp2 = 5.0v */
-#define I365_VPP1_12V	0x02	/* Vpp2 = 12.0v */
+#define I365_VPP1_5V	0x01	/* Vpp1 = 5.0v */
+#define I365_VPP1_12V	0x02	/* Vpp1 = 12.0v */
 
 /* Flags for I365_INTCTL */
 #define I365_RING_ENA	0x80
@@ -95,6 +95,7 @@
 #define I365_CSC_DETECT	0x08
 #define I365_CSC_ANY	0x0F
 #define I365_CSC_GPI	0x10
+#define I365_CSC_IRQ_MASK	0xF0
 
 /* Flags for I365_ADDRWIN */
 #define I365_ENA_IO(map)	(0x40 << (map))
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/Kconfig linux-libre-2.6.34-gnu1/drivers/pcmcia/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -51,17 +51,23 @@ config PCMCIA_LOAD_CIS
 
 config PCMCIA_IOCTL
 	bool "PCMCIA control ioctl (obsolete)"
-	depends on PCMCIA
+	depends on PCMCIA && ARM && !SMP && !PREEMPT
 	default y
 	help
 	  If you say Y here, the deprecated ioctl interface to the PCMCIA
-	  subsystem will be built. It is needed by cardmgr and cardctl
-	  (pcmcia-cs) to function properly.
+	  subsystem will be built. It is needed by the deprecated pcmcia-cs
+	  tools (cardmgr, cardctl) to function properly.
 
 	  You should use the new pcmciautils package instead (see
 	  <file:Documentation/Changes> for location and details).
 
-	  If unsure, say Y.
+	  This config option will most likely be removed from kernel 2.6.35,
+	  the associated code from kernel 2.6.36.
+
+	  As the PCMCIA ioctl is not locking safe, it depends on !SMP and
+	  !PREEMPT.
+
+	  If unsure, say N.
 
 config CARDBUS
 	bool "32-bit CardBus support"
@@ -84,7 +90,7 @@ config YENTA
 	tristate "CardBus yenta-compatible bridge support"
 	depends on PCI
 	select CARDBUS if !EMBEDDED
-	select PCCARD_NONSTATIC
+	select PCCARD_NONSTATIC if PCMCIA != n
 	---help---
 	  This option enables support for CardBus host bridges.  Virtually
 	  all modern PCMCIA bridges are CardBus compatible.  A "bridge" is
@@ -161,9 +167,8 @@ config TCIC
 
 config PCMCIA_M8XX
 	tristate "MPC8xx PCMCIA support"
-	depends on PCMCIA && PPC && 8xx
-	select PCCARD_IODYN
-	select PCCARD_NONSTATIC
+	depends on PCCARD && PPC && 8xx
+	select PCCARD_IODYN if PCMCIA != n
 	help
 	  Say Y here to include support for PowerPC 8xx series PCMCIA
 	  controller.
@@ -174,6 +179,27 @@ config PCMCIA_AU1X00
 	tristate "Au1x00 pcmcia support"
 	depends on SOC_AU1X00 && PCMCIA
 
+config PCMCIA_ALCHEMY_DEVBOARD
+	tristate "Alchemy Db/Pb1xxx PCMCIA socket services"
+	depends on SOC_AU1X00 && PCMCIA
+	select 64BIT_PHYS_ADDR
+	help
+	  Enable this driver of you want PCMCIA support on your Alchemy
+	  Db1000, Db/Pb1100, Db/Pb1500, Db/Pb1550, Db/Pb1200 board.
+	  NOT suitable for the PB1000!
+
+	  This driver is also available as a module called db1xxx_ss.ko
+
+config PCMCIA_XXS1500
+	tristate "MyCable XXS1500 PCMCIA socket support"
+	depends on PCMCIA && MIPS_XXS1500
+	select 64BIT_PHYS_ADDR
+	help
+	  Support for the PCMCIA/CF socket interface on MyCable XXS1500
+	  systems.
+
+	  This driver is also available as a module called xxs1500_ss.ko
+
 config PCMCIA_BCM63XX
 	tristate "bcm63xx pcmcia support"
 	depends on BCM63XX && PCMCIA
@@ -238,14 +264,12 @@ config PCMCIA_PROBE
 config M32R_PCC
 	bool "M32R PCMCIA I/F"
 	depends on M32R && CHIP_M32700 && PCMCIA
-	select PCCARD_NONSTATIC
 	help
 	  Say Y here to use the M32R PCMCIA controller.
 
 config M32R_CFC
 	bool "M32R CF I/F Controller"
 	depends on M32R && (PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2 || PLAT_MAPPI3 || PLAT_OPSPUT)
-	select PCCARD_NONSTATIC
 	help
 	  Say Y here to use the M32R CompactFlash controller.
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/m32r_cfc.c linux-libre-2.6.34-gnu1/drivers/pcmcia/m32r_cfc.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/m32r_cfc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/m32r_cfc.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/timer.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
@@ -685,16 +684,7 @@ 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);
-}
 
-static int cfc_drv_pcmcia_resume(struct platform_device *dev)
-{
-	return pcmcia_socket_dev_resume(&dev->dev);
-}
 /*====================================================================*/
 
 static struct platform_driver pcc_driver = {
@@ -702,8 +692,6 @@ static struct platform_driver pcc_driver
 		.name		= "cfc",
 		.owner		= THIS_MODULE,
 	},
-	.suspend 	= cfc_drv_pcmcia_suspend,
-	.resume 	= cfc_drv_pcmcia_resume,
 };
 
 static struct platform_device pcc_device = {
@@ -764,7 +752,7 @@ static int __init init_m32r_pcc(void)
 	for (i = 0 ; i < pcc_sockets ; i++) {
 		socket[i].socket.dev.parent = &pcc_device.dev;
 		socket[i].socket.ops = &pcc_operations;
-		socket[i].socket.resource_ops = &pccard_nonstatic_ops;
+		socket[i].socket.resource_ops = &pccard_static_ops;
 		socket[i].socket.owner = THIS_MODULE;
 		socket[i].number = i;
 		ret = pcmcia_register_socket(&socket[i].socket);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/m32r_pcc.c linux-libre-2.6.34-gnu1/drivers/pcmcia/m32r_pcc.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/m32r_pcc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/m32r_pcc.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/timer.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
@@ -663,16 +662,6 @@ 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);
-}
-
-static int pcc_drv_pcmcia_resume(struct platform_device *dev)
-{
-	return pcmcia_socket_dev_resume(&dev->dev);
-}
 /*====================================================================*/
 
 static struct platform_driver pcc_driver = {
@@ -680,8 +669,6 @@ static struct platform_driver pcc_driver
 		.name		= "pcc",
 		.owner		= THIS_MODULE,
 	},
-	.suspend 	= pcc_drv_pcmcia_suspend,
-	.resume 	= pcc_drv_pcmcia_resume,
 };
 
 static struct platform_device pcc_device = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/m8xx_pcmcia.c linux-libre-2.6.34-gnu1/drivers/pcmcia/m8xx_pcmcia.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/m8xx_pcmcia.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/m8xx_pcmcia.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,7 +42,6 @@
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
@@ -1233,7 +1232,7 @@ static int __init m8xx_probe(struct of_d
 		socket[i].socket.io_offset = 0;
 		socket[i].socket.pci_irq = pcmcia_schlvl;
 		socket[i].socket.ops = &m8xx_services;
-		socket[i].socket.resource_ops = &pccard_nonstatic_ops;
+		socket[i].socket.resource_ops = &pccard_iodyn_ops;
 		socket[i].socket.cb_dev = NULL;
 		socket[i].socket.dev.parent = &ofdev->dev;
 		socket[i].pcmcia = pcmcia;
@@ -1288,22 +1287,7 @@ static int m8xx_remove(struct of_device
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int m8xx_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	return pcmcia_socket_dev_suspend(&pdev->dev);
-}
-
-static int m8xx_resume(struct platform_device *pdev)
-{
-	return pcmcia_socket_dev_resume(&pdev->dev);
-}
-#else
-#define m8xx_suspend NULL
-#define m8xx_resume NULL
-#endif
-
-static struct of_device_id m8xx_pcmcia_match[] = {
+static const struct of_device_id m8xx_pcmcia_match[] = {
 	{
 	 .type = "pcmcia",
 	 .compatible = "fsl,pq-pcmcia",
@@ -1318,8 +1302,6 @@ static struct of_platform_driver m8xx_pc
 	.match_table = m8xx_pcmcia_match,
 	.probe = m8xx_probe,
 	.remove = m8xx_remove,
-	.suspend = m8xx_suspend,
-	.resume = m8xx_resume,
 };
 
 static int __init m8xx_init(void)
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/Makefile linux-libre-2.6.34-gnu1/drivers/pcmcia/Makefile
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -2,11 +2,11 @@
 # Makefile for the kernel pcmcia subsystem (c/o David Hinds)
 #
 
-pcmcia_core-y					+= cs.o cistpl.o rsrc_mgr.o socket_sysfs.o
+pcmcia_core-y					+= cs.o rsrc_mgr.o socket_sysfs.o
 pcmcia_core-$(CONFIG_CARDBUS)			+= cardbus.o
 obj-$(CONFIG_PCCARD)				+= pcmcia_core.o
 
-pcmcia-y					+= ds.o pcmcia_resource.o
+pcmcia-y					+= ds.o pcmcia_resource.o cistpl.o
 pcmcia-$(CONFIG_PCMCIA_IOCTL)			+= pcmcia_ioctl.o
 obj-$(CONFIG_PCMCIA)				+= pcmcia.o
 
@@ -35,18 +35,10 @@ obj-$(CONFIG_OMAP_CF)				+= omap_cf.o
 obj-$(CONFIG_BFIN_CFPCMCIA)			+= bfin_cf_pcmcia.o
 obj-$(CONFIG_AT91_CF)				+= at91_cf.o
 obj-$(CONFIG_ELECTRA_CF)			+= electra_cf.o
+obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD)		+= db1xxx_ss.o
 
 au1x00_ss-y					+= au1000_generic.o
 au1x00_ss-$(CONFIG_MIPS_PB1000)			+= au1000_pb1x00.o
-au1x00_ss-$(CONFIG_MIPS_PB1100)			+= au1000_pb1x00.o
-au1x00_ss-$(CONFIG_MIPS_PB1200)			+= au1000_db1x00.o
-au1x00_ss-$(CONFIG_MIPS_PB1500)			+= au1000_pb1x00.o
-au1x00_ss-$(CONFIG_MIPS_DB1000)			+= au1000_db1x00.o
-au1x00_ss-$(CONFIG_MIPS_DB1100)			+= au1000_db1x00.o
-au1x00_ss-$(CONFIG_MIPS_DB1200)			+= au1000_db1x00.o
-au1x00_ss-$(CONFIG_MIPS_DB1500)			+= au1000_db1x00.o
-au1x00_ss-$(CONFIG_MIPS_DB1550)			+= au1000_db1x00.o
-au1x00_ss-$(CONFIG_MIPS_XXS1500)		+= au1000_xxs1500.o
 
 sa1111_cs-y					+= sa1111_generic.o
 sa1111_cs-$(CONFIG_ASSABET_NEPONSET)		+= sa1100_neponset.o
@@ -76,3 +68,5 @@ pxa2xx-obj-$(CONFIG_MACH_E740)			+= pxa2
 pxa2xx-obj-$(CONFIG_MACH_STARGATE2)		+= pxa2xx_stargate2.o
 
 obj-$(CONFIG_PCMCIA_PXA2XX)			+= pxa2xx_base.o $(pxa2xx-obj-y)
+
+obj-$(CONFIG_PCMCIA_XXS1500)			+= xxs1500_ss.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/o2micro.h linux-libre-2.6.34-gnu1/drivers/pcmcia/o2micro.h
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/o2micro.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/o2micro.h	2010-05-16 17:17:36.000000000 -0400
@@ -116,13 +116,12 @@ static int o2micro_override(struct yenta
 	 * from Eric Still, 02Micro.
 	 */
 	u8 a, b;
+	bool use_speedup;
 
 	if (PCI_FUNC(socket->dev->devfn) == 0) {
 		a = config_readb(socket, O2_RESERVED1);
 		b = config_readb(socket, O2_RESERVED2);
-
-		dev_printk(KERN_INFO, &socket->dev->dev,
-			   "O2: res at 0x94/0xD4: %02x/%02x\n", a, b);
+		dev_dbg(&socket->dev->dev, "O2: 0x94/0xD4: %02x/%02x\n", a, b);
 
 		switch (socket->dev->device) {
 		/*
@@ -135,23 +134,37 @@ static int o2micro_override(struct yenta
 		case PCI_DEVICE_ID_O2_6812:
 		case PCI_DEVICE_ID_O2_6832:
 		case PCI_DEVICE_ID_O2_6836:
- 		case PCI_DEVICE_ID_O2_6933:
-			dev_printk(KERN_INFO, &socket->dev->dev,
-				   "Yenta O2: old bridge, disabling read "
-				   "prefetch/write burst\n");
-			config_writeb(socket, O2_RESERVED1,
-			              a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
-			config_writeb(socket, O2_RESERVED2,
-			              b & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
+		case PCI_DEVICE_ID_O2_6933:
+			use_speedup = false;
 			break;
-
 		default:
-			dev_printk(KERN_INFO , &socket->dev->dev,
-				   "O2: enabling read prefetch/write burst\n");
+			use_speedup = true;
+			break;
+		}
+
+		/* the user may override our decision */
+		if (strcasecmp(o2_speedup, "on") == 0)
+			use_speedup = true;
+		else if (strcasecmp(o2_speedup, "off") == 0)
+			use_speedup = false;
+		else if (strcasecmp(o2_speedup, "default") != 0)
+			dev_warn(&socket->dev->dev,
+				"O2: Unknown parameter, using 'default'");
+
+		if (use_speedup) {
+			dev_info(&socket->dev->dev,
+				"O2: enabling read prefetch/write burst\n");
 			config_writeb(socket, O2_RESERVED1,
-			              a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
+				      a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
 			config_writeb(socket, O2_RESERVED2,
-			              b | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
+				      b | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
+		} else {
+			dev_info(&socket->dev->dev,
+				"O2: disabling read prefetch/write burst\n");
+			config_writeb(socket, O2_RESERVED1,
+				      a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
+			config_writeb(socket, O2_RESERVED2,
+				      b & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
 		}
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/omap_cf.c linux-libre-2.6.34-gnu1/drivers/pcmcia/omap_cf.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/omap_cf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/omap_cf.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include <pcmcia/ss.h>
 
@@ -71,8 +72,6 @@ struct omap_cf_socket {
 
 #define	POLL_INTERVAL		(2 * HZ)
 
-#define	SZ_2K			(2 * SZ_1K)
-
 /*--------------------------------------------------------------------------*/
 
 static int omap_cf_ss_init(struct pcmcia_socket *s)
@@ -332,24 +331,12 @@ static int __exit omap_cf_remove(struct
 	return 0;
 }
 
-static int omap_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
-	return pcmcia_socket_dev_suspend(&pdev->dev);
-}
-
-static int omap_cf_resume(struct platform_device *pdev)
-{
-	return pcmcia_socket_dev_resume(&pdev->dev);
-}
-
 static struct platform_driver omap_cf_driver = {
 	.driver = {
 		.name	= (char *) driver_name,
 		.owner	= THIS_MODULE,
 	},
 	.remove		= __exit_p(omap_cf_remove),
-	.suspend	= omap_cf_suspend,
-	.resume		= omap_cf_resume,
 };
 
 static int __init omap_cf_init(void)
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/pcmcia_ioctl.c linux-libre-2.6.34-gnu1/drivers/pcmcia/pcmcia_ioctl.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/pcmcia_ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/pcmcia_ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/proc_fs.h>
 #include <linux/poll.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/smp_lock.h>
 #include <linux/workqueue.h>
@@ -62,16 +63,15 @@ static struct pcmcia_device *get_pcmcia_
 						unsigned int function)
 {
 	struct pcmcia_device *p_dev = NULL;
-	unsigned long flags;
 
-	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+	mutex_lock(&s->ops_mutex);
 	list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
 		if (p_dev->func == function) {
-			spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+			mutex_unlock(&s->ops_mutex);
 			return pcmcia_get_dev(p_dev);
 		}
 	}
-	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+	mutex_unlock(&s->ops_mutex);
 	return NULL;
 }
 
@@ -169,7 +169,6 @@ static int pcmcia_adjust_resource_info(a
 {
 	struct pcmcia_socket *s;
 	int ret = -ENOSYS;
-	unsigned long flags;
 
 	down_read(&pcmcia_socket_list_rwsem);
 	list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
@@ -182,14 +181,13 @@ static int pcmcia_adjust_resource_info(a
 
 			/* you can't use the old interface if the new
 			 * one was used before */
-			spin_lock_irqsave(&s->lock, flags);
+			mutex_lock(&s->ops_mutex);
 			if ((s->resource_setup_new) &&
 			    !(s->resource_setup_old)) {
-				spin_unlock_irqrestore(&s->lock, flags);
+				mutex_unlock(&s->ops_mutex);
 				continue;
 			} else if (!(s->resource_setup_old))
 				s->resource_setup_old = 1;
-			spin_unlock_irqrestore(&s->lock, flags);
 
 			switch (adj->Resource) {
 			case RES_MEMORY_RANGE:
@@ -208,10 +206,9 @@ static int pcmcia_adjust_resource_info(a
 				 * last call to adjust_resource_info, we
 				 * always need to assume this is the latest
 				 * one... */
-				spin_lock_irqsave(&s->lock, flags);
 				s->resource_setup_done = 1;
-				spin_unlock_irqrestore(&s->lock, flags);
 			}
+			mutex_unlock(&s->ops_mutex);
 		}
 	}
 	up_read(&pcmcia_socket_list_rwsem);
@@ -470,7 +467,6 @@ static int bind_request(struct pcmcia_so
 	struct pcmcia_driver *p_drv;
 	struct pcmcia_device *p_dev;
 	int ret = 0;
-	unsigned long flags;
 
 	s = pcmcia_get_socket(s);
 	if (!s)
@@ -490,7 +486,7 @@ static int bind_request(struct pcmcia_so
 		goto err_put_driver;
 	}
 
-	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+	mutex_lock(&s->ops_mutex);
 	list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
 		if (p_dev->func == bind_info->function) {
 			if ((p_dev->dev.driver == &p_drv->drv)) {
@@ -499,7 +495,7 @@ static int bind_request(struct pcmcia_so
 					 * registered, and it was registered
 					 * by userspace before, we need to
 					 * return the "instance". */
-					spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+					mutex_unlock(&s->ops_mutex);
 					bind_info->instance = p_dev;
 					ret = -EBUSY;
 					goto err_put_module;
@@ -507,7 +503,7 @@ static int bind_request(struct pcmcia_so
 					/* the correct driver managed to bind
 					 * itself magically to the correct
 					 * device. */
-					spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+					mutex_unlock(&s->ops_mutex);
 					p_dev->cardmgr = p_drv;
 					ret = 0;
 					goto err_put_module;
@@ -516,12 +512,12 @@ static int bind_request(struct pcmcia_so
 				/* there's already a device available where
 				 * no device has been bound to yet. So we don't
 				 * need to register a device! */
-				spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+				mutex_unlock(&s->ops_mutex);
 				goto rescan;
 			}
 		}
 	}
-	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+	mutex_unlock(&s->ops_mutex);
 
 	p_dev = pcmcia_device_add(s, bind_info->function);
 	if (!p_dev) {
@@ -578,7 +574,6 @@ static int get_device_info(struct pcmcia
 	dev_node_t *node;
 	struct pcmcia_device *p_dev;
 	struct pcmcia_driver *p_drv;
-	unsigned long flags;
 	int ret = 0;
 
 #ifdef CONFIG_CARDBUS
@@ -617,7 +612,7 @@ static int get_device_info(struct pcmcia
 	}
 #endif
 
-	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+	mutex_lock(&s->ops_mutex);
 	list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
 		if (p_dev->func == bind_info->function) {
 			p_dev = pcmcia_get_dev(p_dev);
@@ -626,11 +621,11 @@ static int get_device_info(struct pcmcia
 			goto found;
 		}
 	}
-	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+	mutex_unlock(&s->ops_mutex);
 	return -ENODEV;
 
  found:
-	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+	mutex_unlock(&s->ops_mutex);
 
 	p_drv = to_pcmcia_drv(p_dev->dev.driver);
 	if (p_drv && !p_dev->_locked) {
@@ -716,7 +711,7 @@ static int ds_open(struct inode *inode,
 	    warning_printed = 1;
     }
 
-    if (s->pcmcia_state.present)
+    if (atomic_read(&s->present))
 	queue_event(user, CS_EVENT_CARD_INSERTION);
 out:
     unlock_kernel();
@@ -775,9 +770,6 @@ static ssize_t ds_read(struct file *file
 	return -EIO;
 
     s = user->socket;
-    if (s->pcmcia_state.dead)
-	return -EIO;
-
     ret = wait_event_interruptible(s->queue, !queue_empty(user));
     if (ret == 0)
 	ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
@@ -843,8 +835,6 @@ static int ds_ioctl(struct inode *inode,
 	return -EIO;
 
     s = user->socket;
-    if (s->pcmcia_state.dead)
-	return -EIO;
 
     size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
     if (size > sizeof(ds_ioctl_arg_t))
@@ -931,16 +921,16 @@ static int ds_ioctl(struct inode *inode,
 	ret = pccard_validate_cis(s, &buf->cisinfo.Chains);
 	break;
     case DS_SUSPEND_CARD:
-	ret = pcmcia_suspend_card(s);
+	pcmcia_parse_uevents(s, PCMCIA_UEVENT_SUSPEND);
 	break;
     case DS_RESUME_CARD:
-	ret = pcmcia_resume_card(s);
+	pcmcia_parse_uevents(s, PCMCIA_UEVENT_RESUME);
 	break;
     case DS_EJECT_CARD:
-	err = pcmcia_eject_card(s);
+	pcmcia_parse_uevents(s, PCMCIA_UEVENT_EJECT);
 	break;
     case DS_INSERT_CARD:
-	err = pcmcia_insert_card(s);
+	pcmcia_parse_uevents(s, PCMCIA_UEVENT_INSERT);
 	break;
     case DS_ACCESS_CONFIGURATION_REGISTER:
 	if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/pcmcia_resource.c linux-libre-2.6.34-gnu1/drivers/pcmcia/pcmcia_resource.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/pcmcia_resource.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/pcmcia_resource.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/pci.h>
 #include <linux/device.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
@@ -43,6 +44,39 @@ module_param(io_speed, int, 0444);
 static u8 pcmcia_used_irq[NR_IRQS];
 #endif
 
+static int pcmcia_adjust_io_region(struct resource *res, unsigned long start,
+				   unsigned long end, struct pcmcia_socket *s)
+{
+	if (s->resource_ops->adjust_io_region)
+		return s->resource_ops->adjust_io_region(res, start, end, s);
+	return -ENOMEM;
+}
+
+static struct resource *pcmcia_find_io_region(unsigned long base, int num,
+					      unsigned long align,
+					      struct pcmcia_socket *s)
+{
+	if (s->resource_ops->find_io)
+		return s->resource_ops->find_io(base, num, align, s);
+	return NULL;
+}
+
+int pcmcia_validate_mem(struct pcmcia_socket *s)
+{
+	if (s->resource_ops->validate_mem)
+		return s->resource_ops->validate_mem(s);
+	/* if there is no callback, we can assume that everything is OK */
+	return 0;
+}
+
+struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
+				 int low, struct pcmcia_socket *s)
+{
+	if (s->resource_ops->find_mem)
+		return s->resource_ops->find_mem(base, num, align, low, s);
+	return NULL;
+}
+
 
 /** alloc_io_space
  *
@@ -158,14 +192,18 @@ int pcmcia_access_configuration_register
 		return -EINVAL;
 
 	s = p_dev->socket;
+
+	mutex_lock(&s->ops_mutex);
 	c = p_dev->function_config;
 
 	if (!(c->state & CONFIG_LOCKED)) {
 		dev_dbg(&s->dev, "Configuration isnt't locked\n");
+		mutex_unlock(&s->ops_mutex);
 		return -EACCES;
 	}
 
 	addr = (c->ConfigBase + reg->Offset) >> 1;
+	mutex_unlock(&s->ops_mutex);
 
 	switch (reg->Action) {
 	case CS_READ:
@@ -190,6 +228,7 @@ int pcmcia_map_mem_page(struct pcmcia_de
 			memreq_t *req)
 {
 	struct pcmcia_socket *s = p_dev->socket;
+	int ret;
 
 	wh--;
 	if (wh >= MAX_WIN)
@@ -198,12 +237,13 @@ int pcmcia_map_mem_page(struct pcmcia_de
 		dev_dbg(&s->dev, "failure: requested page is zero\n");
 		return -EINVAL;
 	}
+	mutex_lock(&s->ops_mutex);
 	s->win[wh].card_start = req->CardOffset;
-	if (s->ops->set_mem_map(s, &s->win[wh]) != 0) {
-		dev_dbg(&s->dev, "failed to set_mem_map\n");
-		return -EIO;
-	}
-	return 0;
+	ret = s->ops->set_mem_map(s, &s->win[wh]);
+	if (ret)
+		dev_warn(&s->dev, "failed to set_mem_map\n");
+	mutex_unlock(&s->ops_mutex);
+	return ret;
 } /* pcmcia_map_mem_page */
 EXPORT_SYMBOL(pcmcia_map_mem_page);
 
@@ -217,17 +257,22 @@ int pcmcia_modify_configuration(struct p
 {
 	struct pcmcia_socket *s;
 	config_t *c;
+	int ret;
 
 	s = p_dev->socket;
+
+	mutex_lock(&s->ops_mutex);
 	c = p_dev->function_config;
 
 	if (!(s->state & SOCKET_PRESENT)) {
 		dev_dbg(&s->dev, "No card present\n");
-		return -ENODEV;
+		ret = -ENODEV;
+		goto unlock;
 	}
 	if (!(c->state & CONFIG_LOCKED)) {
 		dev_dbg(&s->dev, "Configuration isnt't locked\n");
-		return -EACCES;
+		ret = -EACCES;
+		goto unlock;
 	}
 
 	if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
@@ -243,7 +288,8 @@ int pcmcia_modify_configuration(struct p
 
 	if (mod->Attributes & CONF_VCC_CHANGE_VALID) {
 		dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto unlock;
 	}
 
 	/* We only allow changing Vpp1 and Vpp2 to the same value */
@@ -251,18 +297,21 @@ int pcmcia_modify_configuration(struct p
 	    (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
 		if (mod->Vpp1 != mod->Vpp2) {
 			dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n");
-			return -EINVAL;
+			ret = -EINVAL;
+			goto unlock;
 		}
 		s->socket.Vpp = mod->Vpp1;
 		if (s->ops->set_socket(s, &s->socket)) {
 			dev_printk(KERN_WARNING, &s->dev,
 				   "Unable to set VPP\n");
-			return -EIO;
+			ret = -EIO;
+			goto unlock;
 		}
 	} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
 		   (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
 		dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto unlock;
 	}
 
 	if (mod->Attributes & CONF_IO_CHANGE_WIDTH) {
@@ -286,8 +335,11 @@ int pcmcia_modify_configuration(struct p
 			s->ops->set_io_map(s, &io_on);
 		}
 	}
+	ret = 0;
+unlock:
+	mutex_unlock(&s->ops_mutex);
 
-	return 0;
+	return ret;
 } /* modify_configuration */
 EXPORT_SYMBOL(pcmcia_modify_configuration);
 
@@ -296,9 +348,11 @@ int pcmcia_release_configuration(struct
 {
 	pccard_io_map io = { 0, 0, 0, 0, 1 };
 	struct pcmcia_socket *s = p_dev->socket;
-	config_t *c = p_dev->function_config;
+	config_t *c;
 	int i;
 
+	mutex_lock(&s->ops_mutex);
+	c = p_dev->function_config;
 	if (p_dev->_locked) {
 		p_dev->_locked = 0;
 		if (--(s->lock_count) == 0) {
@@ -321,6 +375,7 @@ int pcmcia_release_configuration(struct
 				s->ops->set_io_map(s, &io);
 			}
 	}
+	mutex_unlock(&s->ops_mutex);
 
 	return 0;
 } /* pcmcia_release_configuration */
@@ -337,10 +392,14 @@ int pcmcia_release_configuration(struct
 static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
 {
 	struct pcmcia_socket *s = p_dev->socket;
-	config_t *c = p_dev->function_config;
+	int ret = -EINVAL;
+	config_t *c;
+
+	mutex_lock(&s->ops_mutex);
+	c = p_dev->function_config;
 
 	if (!p_dev->_io)
-		return -EINVAL;
+		goto out;
 
 	p_dev->_io = 0;
 
@@ -348,7 +407,7 @@ static int pcmcia_release_io(struct pcmc
 	    (c->io.NumPorts1 != req->NumPorts1) ||
 	    (c->io.BasePort2 != req->BasePort2) ||
 	    (c->io.NumPorts2 != req->NumPorts2))
-		return -EINVAL;
+		goto out;
 
 	c->state &= ~CONFIG_IO_REQ;
 
@@ -356,28 +415,38 @@ static int pcmcia_release_io(struct pcmc
 	if (req->NumPorts2)
 		release_io_space(s, req->BasePort2, req->NumPorts2);
 
-	return 0;
+out:
+	mutex_unlock(&s->ops_mutex);
+
+	return ret;
 } /* pcmcia_release_io */
 
 
 static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
 {
 	struct pcmcia_socket *s = p_dev->socket;
-	config_t *c = p_dev->function_config;
+	config_t *c;
+	int ret = -EINVAL;
+
+	mutex_lock(&s->ops_mutex);
+
+	c = p_dev->function_config;
 
 	if (!p_dev->_irq)
-		return -EINVAL;
+		goto out;
+
 	p_dev->_irq = 0;
 
 	if (c->state & CONFIG_LOCKED)
-		return -EACCES;
+		goto out;
+
 	if (c->irq.Attributes != req->Attributes) {
 		dev_dbg(&s->dev, "IRQ attributes must match assigned ones\n");
-		return -EINVAL;
+		goto out;
 	}
 	if (s->irq.AssignedIRQ != req->AssignedIRQ) {
 		dev_dbg(&s->dev, "IRQ must match assigned one\n");
-		return -EINVAL;
+		goto out;
 	}
 	if (--s->irq.Config == 0) {
 		c->state &= ~CONFIG_IRQ_REQ;
@@ -390,8 +459,12 @@ static int pcmcia_release_irq(struct pcm
 #ifdef CONFIG_PCMCIA_PROBE
 	pcmcia_used_irq[req->AssignedIRQ]--;
 #endif
+	ret = 0;
 
-	return 0;
+out:
+	mutex_unlock(&s->ops_mutex);
+
+	return ret;
 } /* pcmcia_release_irq */
 
 
@@ -404,10 +477,12 @@ int pcmcia_release_window(struct pcmcia_
 	if (wh >= MAX_WIN)
 		return -EINVAL;
 
+	mutex_lock(&s->ops_mutex);
 	win = &s->win[wh];
 
 	if (!(p_dev->_win & CLIENT_WIN_REQ(wh))) {
 		dev_dbg(&s->dev, "not releasing unknown window\n");
+		mutex_unlock(&s->ops_mutex);
 		return -EINVAL;
 	}
 
@@ -423,6 +498,7 @@ int pcmcia_release_window(struct pcmcia_
 		win->res = NULL;
 	}
 	p_dev->_win &= ~CLIENT_WIN_REQ(wh);
+	mutex_unlock(&s->ops_mutex);
 
 	return 0;
 } /* pcmcia_release_window */
@@ -445,8 +521,11 @@ int pcmcia_request_configuration(struct
 		dev_dbg(&s->dev, "IntType may not be INT_CARDBUS\n");
 		return -EINVAL;
 	}
+
+	mutex_lock(&s->ops_mutex);
 	c = p_dev->function_config;
 	if (c->state & CONFIG_LOCKED) {
+		mutex_unlock(&s->ops_mutex);
 		dev_dbg(&s->dev, "Configuration is locked\n");
 		return -EACCES;
 	}
@@ -454,6 +533,7 @@ int pcmcia_request_configuration(struct
 	/* Do power control.  We don't allow changes in Vcc. */
 	s->socket.Vpp = req->Vpp;
 	if (s->ops->set_socket(s, &s->socket)) {
+		mutex_unlock(&s->ops_mutex);
 		dev_printk(KERN_WARNING, &s->dev,
 			   "Unable to set socket state\n");
 		return -EINVAL;
@@ -476,6 +556,7 @@ int pcmcia_request_configuration(struct
 		s->socket.io_irq = 0;
 	s->ops->set_socket(s, &s->socket);
 	s->lock_count++;
+	mutex_unlock(&s->ops_mutex);
 
 	/* Set up CIS configuration registers */
 	base = c->ConfigBase = req->ConfigBase;
@@ -524,6 +605,7 @@ int pcmcia_request_configuration(struct
 
 	/* Configure I/O windows */
 	if (c->state & CONFIG_IO_REQ) {
+		mutex_lock(&s->ops_mutex);
 		iomap.speed = io_speed;
 		for (i = 0; i < MAX_IO_WIN; i++)
 			if (s->io[i].res) {
@@ -542,6 +624,7 @@ int pcmcia_request_configuration(struct
 				s->ops->set_io_map(s, &iomap);
 				s->io[i].Config++;
 			}
+		mutex_unlock(&s->ops_mutex);
 	}
 
 	c->state |= CONFIG_LOCKED;
@@ -560,54 +643,65 @@ int pcmcia_request_io(struct pcmcia_devi
 {
 	struct pcmcia_socket *s = p_dev->socket;
 	config_t *c;
+	int ret = -EINVAL;
+
+	mutex_lock(&s->ops_mutex);
 
 	if (!(s->state & SOCKET_PRESENT)) {
 		dev_dbg(&s->dev, "No card present\n");
-		return -ENODEV;
+		goto out;
 	}
 
 	if (!req)
-		return -EINVAL;
+		goto out;
+
 	c = p_dev->function_config;
 	if (c->state & CONFIG_LOCKED) {
 		dev_dbg(&s->dev, "Configuration is locked\n");
-		return -EACCES;
+		goto out;
 	}
 	if (c->state & CONFIG_IO_REQ) {
 		dev_dbg(&s->dev, "IO already configured\n");
-		return -EBUSY;
+		goto out;
 	}
 	if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) {
 		dev_dbg(&s->dev, "bad attribute setting for IO region 1\n");
-		return -EINVAL;
+		goto out;
 	}
 	if ((req->NumPorts2 > 0) &&
 	    (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) {
 		dev_dbg(&s->dev, "bad attribute setting for IO region 2\n");
-		return -EINVAL;
+		goto out;
 	}
 
 	dev_dbg(&s->dev, "trying to allocate resource 1\n");
-	if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
-			   req->NumPorts1, req->IOAddrLines)) {
+	ret = alloc_io_space(s, req->Attributes1, &req->BasePort1,
+			     req->NumPorts1, req->IOAddrLines);
+	if (ret) {
 		dev_dbg(&s->dev, "allocation of resource 1 failed\n");
-		return -EBUSY;
+		goto out;
 	}
 
 	if (req->NumPorts2) {
 		dev_dbg(&s->dev, "trying to allocate resource 2\n");
-		if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
-				   req->NumPorts2, req->IOAddrLines)) {
+		ret = alloc_io_space(s, req->Attributes2, &req->BasePort2,
+				     req->NumPorts2, req->IOAddrLines);
+		if (ret) {
 			dev_dbg(&s->dev, "allocation of resource 2 failed\n");
 			release_io_space(s, req->BasePort1, req->NumPorts1);
-			return -EBUSY;
+			goto out;
 		}
 	}
 
 	c->io = *req;
 	c->state |= CONFIG_IO_REQ;
 	p_dev->_io = 1;
-	return 0;
+	dev_dbg(&s->dev, "allocating resources succeeded: %d\n", ret);
+
+out:
+	mutex_unlock(&s->ops_mutex);
+
+	return ret;
 } /* pcmcia_request_io */
 EXPORT_SYMBOL(pcmcia_request_io);
 
@@ -636,18 +730,20 @@ int pcmcia_request_irq(struct pcmcia_dev
 	int ret = -EINVAL, irq = 0;
 	int type;
 
+	mutex_lock(&s->ops_mutex);
+
 	if (!(s->state & SOCKET_PRESENT)) {
 		dev_dbg(&s->dev, "No card present\n");
-		return -ENODEV;
+		goto out;
 	}
 	c = p_dev->function_config;
 	if (c->state & CONFIG_LOCKED) {
 		dev_dbg(&s->dev, "Configuration is locked\n");
-		return -EACCES;
+		goto out;
 	}
 	if (c->state & CONFIG_IRQ_REQ) {
 		dev_dbg(&s->dev, "IRQ already configured\n");
-		return -EBUSY;
+		goto out;
 	}
 
 	/* Decide what type of interrupt we are registering */
@@ -659,20 +755,12 @@ int pcmcia_request_irq(struct pcmcia_dev
 	else
 		printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n");
 
-#ifdef CONFIG_PCMCIA_PROBE
-
-#ifdef IRQ_NOAUTOEN
-	/* if the underlying IRQ infrastructure allows for it, only allocate
-	 * the IRQ, but do not enable it
-	 */
-	if (!(req->Handler))
-		type |= IRQ_NOAUTOEN;
-#endif /* IRQ_NOAUTOEN */
-
-	if (s->irq.AssignedIRQ != 0) {
-		/* If the interrupt is already assigned, it must be the same */
+	/* If the interrupt is already assigned, it must be the same */
+	if (s->irq.AssignedIRQ != 0)
 		irq = s->irq.AssignedIRQ;
-	} else {
+
+#ifdef CONFIG_PCMCIA_PROBE
+	if (!irq) {
 		int try;
 		u32 mask = s->irq_mask;
 		void *data = p_dev; /* something unique to this device */
@@ -708,7 +796,7 @@ int pcmcia_request_irq(struct pcmcia_dev
 	if (ret && !s->irq.AssignedIRQ) {
 		if (!s->pci_irq) {
 			dev_printk(KERN_INFO, &s->dev, "no IRQ found\n");
-			return ret;
+			goto out;
 		}
 		type = IRQF_SHARED;
 		irq = s->pci_irq;
@@ -720,7 +808,7 @@ int pcmcia_request_irq(struct pcmcia_dev
 		if (ret) {
 			dev_printk(KERN_INFO, &s->dev,
 				"request_irq() failed\n");
-			return ret;
+			goto out;
 		}
 	}
 
@@ -743,7 +831,10 @@ int pcmcia_request_irq(struct pcmcia_dev
 	pcmcia_used_irq[irq]++;
 #endif
 
-	return 0;
+	ret = 0;
+out:
+	mutex_unlock(&s->ops_mutex);
+	return ret;
 } /* pcmcia_request_irq */
 EXPORT_SYMBOL(pcmcia_request_irq);
 
@@ -796,6 +887,7 @@ int pcmcia_request_window(struct pcmcia_
 		return -EINVAL;
 	}
 
+	mutex_lock(&s->ops_mutex);
 	win = &s->win[w];
 
 	if (!(s->features & SS_CAP_STATIC_MAP)) {
@@ -803,6 +895,7 @@ int pcmcia_request_window(struct pcmcia_
 						      (req->Attributes & WIN_MAP_BELOW_1MB), s);
 		if (!win->res) {
 			dev_dbg(&s->dev, "allocating mem region failed\n");
+			mutex_unlock(&s->ops_mutex);
 			return -EINVAL;
 		}
 	}
@@ -821,8 +914,10 @@ int pcmcia_request_window(struct pcmcia_
 	if (req->Attributes & WIN_USE_WAIT)
 		win->flags |= MAP_USE_WAIT;
 	win->card_start = 0;
+
 	if (s->ops->set_mem_map(s, win) != 0) {
 		dev_dbg(&s->dev, "failed to set memory mapping\n");
+		mutex_unlock(&s->ops_mutex);
 		return -EIO;
 	}
 	s->state |= SOCKET_WIN_REQ(w);
@@ -833,6 +928,7 @@ int pcmcia_request_window(struct pcmcia_
 	else
 		req->Base = win->res->start;
 
+	mutex_unlock(&s->ops_mutex);
 	*wh = w + 1;
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/pd6729.c linux-libre-2.6.34-gnu1/drivers/pcmcia/pd6729.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/pd6729.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/pd6729.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,18 +9,19 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/device.h>
+#include <linux/io.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 
 #include <asm/system.h>
-#include <asm/io.h>
 
 #include "pd6729.h"
 #include "i82365.h"
@@ -48,23 +49,13 @@ MODULE_AUTHOR("Jun Komuro <komurojun-mbn
  *     Specifies the interrupt delivery mode.  The default (1) is to use PCI
  *     interrupts; a value of 0 selects ISA interrupts. This must be set for
  *     correct operation of PCI card readers.
- *
- *  irq_list=i,j,...
- *     This list limits the set of interrupts that can be used by PCMCIA
- *     cards.
- *     The default list is 3,4,5,7,9,10,11.
- *     (irq_list parameter is not used, if irq_mode = 1)
  */
 
 static int irq_mode = 1; /* 0 = ISA interrupt, 1 = PCI interrupt */
-static int irq_list[16];
-static unsigned int irq_list_count = 0;
 
 module_param(irq_mode, int, 0444);
-module_param_array(irq_list, int, &irq_list_count, 0444);
 MODULE_PARM_DESC(irq_mode,
 		"interrupt delivery mode. 0 = ISA, 1 = PCI. default is 1");
-MODULE_PARM_DESC(irq_list, "interrupts that can be used by PCMCIA cards");
 
 static DEFINE_SPINLOCK(port_lock);
 
@@ -232,9 +223,9 @@ static irqreturn_t pd6729_interrupt(int
 						? SS_READY : 0;
 			}
 
-			if (events) {
+			if (events)
 				pcmcia_parse_events(&socket[i].socket, events);
-			}
+
 			active |= events;
 		}
 
@@ -266,9 +257,8 @@ static int pd6729_get_status(struct pcmc
 	status = indirect_read(socket, I365_STATUS);
 	*value = 0;
 
-	if ((status & I365_CS_DETECT) == I365_CS_DETECT) {
+	if ((status & I365_CS_DETECT) == I365_CS_DETECT)
 		*value |= SS_DETECT;
-	}
 
 	/*
 	 * IO cards have a different meaning of bits 0,1
@@ -318,7 +308,7 @@ static int pd6729_set_socket(struct pcmc
 	socket->card_irq = state->io_irq;
 
 	reg = 0;
- 	/* The reset bit has "inverse" logic */
+	/* The reset bit has "inverse" logic */
 	if (!(state->flags & SS_RESET))
 		reg |= I365_PC_RESET;
 	if (state->flags & SS_IOCARD)
@@ -390,7 +380,7 @@ static int pd6729_set_socket(struct pcmc
 		indirect_write(socket, I365_POWER, reg);
 
 	if (irq_mode == 1) {
-		 /* all interrupts are to be done as PCI interrupts */
+		/* all interrupts are to be done as PCI interrupts */
 		data = PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ;
 	} else
 		data = 0;
@@ -401,9 +391,9 @@ static int pd6729_set_socket(struct pcmc
 	/* Enable specific interrupt events */
 
 	reg = 0x00;
-	if (state->csc_mask & SS_DETECT) {
+	if (state->csc_mask & SS_DETECT)
 		reg |= I365_CSC_DETECT;
-	}
+
 	if (state->flags & SS_IOCARD) {
 		if (state->csc_mask & SS_STSCHG)
 			reg |= I365_CSC_STSCHG;
@@ -460,9 +450,12 @@ static int pd6729_set_io_map(struct pcmc
 
 	ioctl = indirect_read(socket, I365_IOCTL) & ~I365_IOCTL_MASK(map);
 
-	if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
-	if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
-	if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
+	if (io->flags & MAP_0WS)
+		ioctl |= I365_IOCTL_0WS(map);
+	if (io->flags & MAP_16BIT)
+		ioctl |= I365_IOCTL_16BIT(map);
+	if (io->flags & MAP_AUTOSZ)
+		ioctl |= I365_IOCTL_IOCS16(map);
 
 	indirect_write(socket, I365_IOCTL, ioctl);
 
@@ -507,7 +500,7 @@ static int pd6729_set_mem_map(struct pcm
 
 	/* write the stop address */
 
-	i= (mem->res->end >> 12) & 0x0fff;
+	i = (mem->res->end >> 12) & 0x0fff;
 	switch (to_cycles(mem->speed)) {
 	case 0:
 		break;
@@ -573,7 +566,7 @@ static int pd6729_init(struct pcmcia_soc
 
 /* the pccard structure and its functions */
 static struct pccard_operations pd6729_operations = {
-	.init 			= pd6729_init,
+	.init			= pd6729_init,
 	.get_status		= pd6729_get_status,
 	.set_socket		= pd6729_set_socket,
 	.set_io_map		= pd6729_set_io_map,
@@ -588,8 +581,13 @@ static irqreturn_t pd6729_test(int irq,
 
 static int pd6729_check_irq(int irq)
 {
-	if (request_irq(irq, pd6729_test, IRQF_PROBE_SHARED, "x", pd6729_test)
-		!= 0) return -1;
+	int ret;
+
+	ret = request_irq(irq, pd6729_test, IRQF_PROBE_SHARED, "x",
+			  pd6729_test);
+	if (ret)
+		return -1;
+
 	free_irq(irq, pd6729_test);
 	return 0;
 }
@@ -601,17 +599,11 @@ static u_int __devinit pd6729_isa_scan(v
 
 	if (irq_mode == 1) {
 		printk(KERN_INFO "pd6729: PCI card interrupts, "
-						"PCI status changes\n");
+		       "PCI status changes\n");
 		return 0;
 	}
 
-	if (irq_list_count == 0)
-		mask0 = 0xffff;
-	else
-		for (i = mask0 = 0; i < irq_list_count; i++)
-			mask0 |= (1<<irq_list[i]);
-
-	mask0 &= PD67_MASK;
+	mask0 = PD67_MASK;
 
 	/* just find interrupts that aren't in use */
 	for (i = 0; i < 16; i++)
@@ -623,9 +615,10 @@ static u_int __devinit pd6729_isa_scan(v
 		if (mask & (1<<i))
 			printk("%s%d", ((mask & ((1<<i)-1)) ? "," : ""), i);
 
-	if (mask == 0) printk("none!");
-
-	printk("  polling status changes.\n");
+	if (mask == 0)
+		printk("none!");
+	else
+		printk("  polling status changes.\n");
 
 	return mask;
 }
@@ -640,11 +633,16 @@ static int __devinit pd6729_pci_probe(st
 
 	socket = kzalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS,
 			 GFP_KERNEL);
-	if (!socket)
+	if (!socket) {
+		dev_warn(&dev->dev, "failed to kzalloc socket.\n");
 		return -ENOMEM;
+	}
 
-	if ((ret = pci_enable_device(dev)))
+	ret = pci_enable_device(dev);
+	if (ret) {
+		dev_warn(&dev->dev, "failed to enable pci_device.\n");
 		goto err_out_free_mem;
+	}
 
 	if (!pci_resource_start(dev, 0)) {
 		dev_warn(&dev->dev, "refusing to load the driver as the "
@@ -655,7 +653,7 @@ static int __devinit pd6729_pci_probe(st
 	dev_info(&dev->dev, "Cirrus PD6729 PCI to PCMCIA Bridge at 0x%llx "
 		"on irq %d\n",
 		(unsigned long long)pci_resource_start(dev, 0), dev->irq);
- 	/*
+	/*
 	 * Since we have no memory BARs some firmware may not
 	 * have had PCI_COMMAND_MEMORY enabled, yet the device needs it.
 	 */
@@ -687,6 +685,7 @@ static int __devinit pd6729_pci_probe(st
 		socket[i].socket.map_size = 0x1000;
 		socket[i].socket.irq_mask = mask;
 		socket[i].socket.pci_irq  = dev->irq;
+		socket[i].socket.cb_dev = dev;
 		socket[i].socket.owner = THIS_MODULE;
 
 		socket[i].number = i;
@@ -700,8 +699,9 @@ static int __devinit pd6729_pci_probe(st
 	pci_set_drvdata(dev, socket);
 	if (irq_mode == 1) {
 		/* Register the interrupt handler */
-		if ((ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED,
-							"pd6729", socket))) {
+		ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED,
+				  "pd6729", socket);
+		if (ret) {
 			dev_err(&dev->dev, "Failed to register irq %d\n",
 				dev->irq);
 			goto err_out_free_res;
@@ -765,18 +765,6 @@ static void __devexit pd6729_pci_remove(
 	kfree(socket);
 }
 
-#ifdef CONFIG_PM
-static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state)
-{
-	return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int pd6729_socket_resume(struct pci_dev *dev)
-{
-	return pcmcia_socket_dev_resume(&dev->dev);
-}
-#endif
-
 static struct pci_device_id pd6729_pci_ids[] = {
 	{
 		.vendor		= PCI_VENDOR_ID_CIRRUS,
@@ -793,10 +781,6 @@ static struct pci_driver pd6729_pci_driv
 	.id_table	= pd6729_pci_ids,
 	.probe		= pd6729_pci_probe,
 	.remove		= __devexit_p(pd6729_pci_remove),
-#ifdef CONFIG_PM
-	.suspend	= pd6729_socket_suspend,
-	.resume		= pd6729_socket_resume,
-#endif
 };
 
 static int pd6729_module_init(void)
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_base.c linux-libre-2.6.34-gnu1/drivers/pcmcia/pxa2xx_base.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_base.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/pxa2xx_base.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
   ======================================================================*/
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/ioport.h>
@@ -325,19 +326,13 @@ static int pxa2xx_drv_pcmcia_remove(stru
 	return 0;
 }
 
-static int pxa2xx_drv_pcmcia_suspend(struct device *dev)
-{
-	return pcmcia_socket_dev_suspend(dev);
-}
-
 static int pxa2xx_drv_pcmcia_resume(struct device *dev)
 {
 	pxa2xx_configure_sockets(dev);
-	return pcmcia_socket_dev_resume(dev);
+	return 0;
 }
 
 static const struct dev_pm_ops pxa2xx_drv_pcmcia_pm_ops = {
-	.suspend	= pxa2xx_drv_pcmcia_suspend,
 	.resume		= pxa2xx_drv_pcmcia_resume,
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/rsrc_mgr.c linux-libre-2.6.34-gnu1/drivers/pcmcia/rsrc_mgr.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/rsrc_mgr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/rsrc_mgr.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
  * (C) 1999		David A. Hinds
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 
@@ -21,60 +22,12 @@
 #include <pcmcia/cistpl.h>
 #include "cs_internal.h"
 
-
-int pcmcia_validate_mem(struct pcmcia_socket *s)
-{
-	if (s->resource_ops->validate_mem)
-		return s->resource_ops->validate_mem(s);
-	/* if there is no callback, we can assume that everything is OK */
-	return 0;
-}
-EXPORT_SYMBOL(pcmcia_validate_mem);
-
-int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start,
-		     unsigned long r_end, struct pcmcia_socket *s)
-{
-	if (s->resource_ops->adjust_io_region)
-		return s->resource_ops->adjust_io_region(res, r_start, r_end, s);
-	return -ENOMEM;
-}
-EXPORT_SYMBOL(pcmcia_adjust_io_region);
-
-struct resource *pcmcia_find_io_region(unsigned long base, int num,
-		   unsigned long align, struct pcmcia_socket *s)
-{
-	if (s->resource_ops->find_io)
-		return s->resource_ops->find_io(base, num, align, s);
-	return NULL;
-}
-EXPORT_SYMBOL(pcmcia_find_io_region);
-
-struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
-				 int low, struct pcmcia_socket *s)
-{
-	if (s->resource_ops->find_mem)
-		return s->resource_ops->find_mem(base, num, align, low, s);
-	return NULL;
-}
-EXPORT_SYMBOL(pcmcia_find_mem_region);
-
-void release_resource_db(struct pcmcia_socket *s)
-{
-	if (s->resource_ops->exit)
-		s->resource_ops->exit(s);
-}
-
-
 static int static_init(struct pcmcia_socket *s)
 {
-	unsigned long flags;
-
 	/* the good thing about SS_CAP_STATIC_MAP sockets is
 	 * that they don't need a resource database */
 
-	spin_lock_irqsave(&s->lock, flags);
 	s->resource_setup_done = 1;
-	spin_unlock_irqrestore(&s->lock, flags);
 
 	return 0;
 }
@@ -114,32 +67,32 @@ struct pcmcia_align_data {
 	unsigned long	offset;
 };
 
-static void pcmcia_align(void *align_data, struct resource *res,
-			unsigned long size, unsigned long align)
+static resource_size_t pcmcia_align(void *align_data,
+				const struct resource *res,
+				resource_size_t size, resource_size_t align)
 {
 	struct pcmcia_align_data *data = align_data;
-	unsigned long start;
+	resource_size_t start;
 
 	start = (res->start & ~data->mask) + data->offset;
 	if (start < res->start)
 		start += data->mask + 1;
-	res->start = start;
 
 #ifdef CONFIG_X86
 	if (res->flags & IORESOURCE_IO) {
-		if (start & 0x300) {
+		if (start & 0x300)
 			start = (start + 0x3ff) & ~0x3ff;
-			res->start = start;
-		}
 	}
 #endif
 
 #ifdef CONFIG_M68K
 	if (res->flags & IORESOURCE_IO) {
 		if ((res->start + size - 1) >= 1024)
-			res->start = res->end;
+			start = res->end;
 	}
 #endif
+
+	return start;
 }
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/rsrc_nonstatic.c linux-libre-2.6.34-gnu1/drivers/pcmcia/rsrc_nonstatic.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/rsrc_nonstatic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/rsrc_nonstatic.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,11 +55,10 @@ struct resource_map {
 
 struct socket_data {
 	struct resource_map		mem_db;
+	struct resource_map		mem_db_valid;
 	struct resource_map		io_db;
-	unsigned int			rsrc_mem_probe;
 };
 
-static DEFINE_MUTEX(rsrc_mutex);
 #define MEM_PROBE_LOW	(1 << 0)
 #define MEM_PROBE_HIGH	(1 << 1)
 
@@ -125,8 +124,10 @@ static int add_interval(struct resource_
 	struct resource_map *p, *q;
 
 	for (p = map; ; p = p->next) {
-		if ((p != map) && (p->base+p->num-1 >= base))
-			return -1;
+		if ((p != map) && (p->base+p->num >= base)) {
+			p->num = max(num + base - p->base, p->num);
+			return 0;
+		}
 		if ((p->next == map) || (p->next->base > base+num-1))
 			break;
 	}
@@ -213,7 +214,7 @@ static void do_io_probe(struct pcmcia_so
 		return;
 	}
 	for (i = base, most = 0; i < base+num; i += 8) {
-		res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
+		res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
 		if (!res)
 			continue;
 		hole = inb(i);
@@ -230,9 +231,14 @@ static void do_io_probe(struct pcmcia_so
 
 	bad = any = 0;
 	for (i = base; i < base+num; i += 8) {
-		res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
-		if (!res)
+		res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
+		if (!res) {
+			if (!any)
+				printk(" excluding");
+			if (!bad)
+				bad = any = i;
 			continue;
+		}
 		for (j = 0; j < 8; j++)
 			if (inb(i+j) != most)
 				break;
@@ -252,6 +258,7 @@ static void do_io_probe(struct pcmcia_so
 	}
 	if (bad) {
 		if ((num > 16) && (bad == base) && (i == base+num)) {
+			sub_interval(&s_data->io_db, bad, i-bad);
 			printk(" nothing: probe failed.\n");
 			return;
 		} else {
@@ -264,36 +271,44 @@ static void do_io_probe(struct pcmcia_so
 }
 #endif
 
-/*======================================================================
-
-    This is tricky... when we set up CIS memory, we try to validate
-    the memory window space allocations.
-
-======================================================================*/
+/*======================================================================*/
 
-/* Validation function for cards with a valid CIS */
+/**
+ * readable() - iomem validation function for cards with a valid CIS
+ */
 static int readable(struct pcmcia_socket *s, struct resource *res,
 		    unsigned int *count)
 {
-	int ret = -1;
+	int ret = -EINVAL;
+
+	if (s->fake_cis) {
+		dev_dbg(&s->dev, "fake CIS is being used: can't validate mem\n");
+		return 0;
+	}
 
 	s->cis_mem.res = res;
 	s->cis_virt = ioremap(res->start, s->map_size);
 	if (s->cis_virt) {
-		ret = pccard_validate_cis(s, count);
-		/* invalidate mapping and CIS cache */
+		mutex_unlock(&s->ops_mutex);
+		/* as we're only called from pcmcia.c, we're safe */
+		if (s->callback->validate)
+			ret = s->callback->validate(s, count);
+		/* invalidate mapping */
+		mutex_lock(&s->ops_mutex);
 		iounmap(s->cis_virt);
 		s->cis_virt = NULL;
-		destroy_cis_cache(s);
 	}
 	s->cis_mem.res = NULL;
-	if ((ret != 0) || (*count == 0))
-		return 0;
-	return 1;
+	if ((ret) || (*count == 0))
+		return -EINVAL;
+	return 0;
 }
 
-/* Validation function for simple memory cards */
-static int checksum(struct pcmcia_socket *s, struct resource *res)
+/**
+ * checksum() - iomem validation function for simple memory cards
+ */
+static int checksum(struct pcmcia_socket *s, struct resource *res,
+		    unsigned int *value)
 {
 	pccard_mem_map map;
 	int i, a = 0, b = -1, d;
@@ -321,61 +336,90 @@ static int checksum(struct pcmcia_socket
 		iounmap(virt);
 	}
 
-	return (b == -1) ? -1 : (a>>1);
+	if (b == -1)
+		return -EINVAL;
+
+	*value = a;
+
+	return 0;
 }
 
-static int
-cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size)
+/**
+ * do_validate_mem() - low level validate a memory region for PCMCIA use
+ * @s:		PCMCIA socket to validate
+ * @base:	start address of resource to check
+ * @size:	size of resource to check
+ * @validate:	validation function to use
+ *
+ * do_validate_mem() splits up the memory region which is to be checked
+ * into two parts. Both are passed to the @validate() function. If
+ * @validate() returns non-zero, or the value parameter to @validate()
+ * is zero, or the value parameter is different between both calls,
+ * the check fails, and -EINVAL is returned. Else, 0 is returned.
+ */
+static int do_validate_mem(struct pcmcia_socket *s,
+			   unsigned long base, unsigned long size,
+			   int validate (struct pcmcia_socket *s,
+					 struct resource *res,
+					 unsigned int *value))
 {
+	struct socket_data *s_data = s->resource_data;
 	struct resource *res1, *res2;
-	unsigned int info1, info2;
-	int ret = 0;
+	unsigned int info1 = 1, info2 = 1;
+	int ret = -EINVAL;
 
 	res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe");
 	res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM,
 			"PCMCIA memprobe");
 
 	if (res1 && res2) {
-		ret = readable(s, res1, &info1);
-		ret += readable(s, res2, &info2);
+		ret = 0;
+		if (validate) {
+			ret = validate(s, res1, &info1);
+			ret += validate(s, res2, &info2);
+		}
 	}
 
 	free_region(res2);
 	free_region(res1);
 
-	return (ret == 2) && (info1 == info2);
-}
-
-static int
-checksum_match(struct pcmcia_socket *s, unsigned long base, unsigned long size)
-{
-	struct resource *res1, *res2;
-	int a = -1, b = -1;
+	dev_dbg(&s->dev, "cs: memory probe 0x%06lx-0x%06lx: %p %p %u %u %u",
+		base, base+size-1, res1, res2, ret, info1, info2);
 
-	res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe");
-	res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM,
-			"PCMCIA memprobe");
+	if ((ret) || (info1 != info2) || (info1 == 0))
+		return -EINVAL;
 
-	if (res1 && res2) {
-		a = checksum(s, res1);
-		b = checksum(s, res2);
+	if (validate && !s->fake_cis) {
+		/* move it to the validated data set */
+		add_interval(&s_data->mem_db_valid, base, size);
+		sub_interval(&s_data->mem_db, base, size);
 	}
 
-	free_region(res2);
-	free_region(res1);
-
-	return (a == b) && (a >= 0);
+	return 0;
 }
 
-/*======================================================================
-
-    The memory probe.  If the memory list includes a 64K-aligned block
-    below 1MB, we probe in 64K chunks, and as soon as we accumulate at
-    least mem_limit free space, we quit.
 
-======================================================================*/
-
-static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
+/**
+ * do_mem_probe() - validate a memory region for PCMCIA use
+ * @s:		PCMCIA socket to validate
+ * @base:	start address of resource to check
+ * @num:	size of resource to check
+ * @validate:	validation function to use
+ * @fallback:	validation function to use if validate fails
+ *
+ * do_mem_probe() checks a memory region for use by the PCMCIA subsystem.
+ * To do so, the area is split up into sensible parts, and then passed
+ * into the @validate() function. Only if @validate() and @fallback() fail,
+ * the area is marked as unavaibale for use by the PCMCIA subsystem. The
+ * function returns the size of the usable memory area.
+ */
+static int do_mem_probe(struct pcmcia_socket *s, u_long base, u_long num,
+			int validate (struct pcmcia_socket *s,
+				      struct resource *res,
+				      unsigned int *value),
+			int fallback (struct pcmcia_socket *s,
+				      struct resource *res,
+				      unsigned int *value))
 {
 	struct socket_data *s_data = s->resource_data;
 	u_long i, j, bad, fail, step;
@@ -393,15 +437,14 @@ static int do_mem_probe(u_long base, u_l
 	for (i = j = base; i < base+num; i = j + step) {
 		if (!fail) {
 			for (j = i; j < base+num; j += step) {
-				if (cis_readable(s, j, step))
+				if (!do_validate_mem(s, j, step, validate))
 					break;
 			}
 			fail = ((i == base) && (j == base+num));
 		}
-		if (fail) {
-			for (j = i; j < base+num; j += 2*step)
-				if (checksum_match(s, j, step) &&
-					checksum_match(s, j + step, step))
+		if ((fail) && (fallback)) {
+			for (j = i; j < base+num; j += step)
+				if (!do_validate_mem(s, j, step, fallback))
 					break;
 		}
 		if (i != j) {
@@ -416,8 +459,14 @@ static int do_mem_probe(u_long base, u_l
 	return num - bad;
 }
 
+
 #ifdef CONFIG_PCMCIA_PROBE
 
+/**
+ * inv_probe() - top-to-bottom search for one usuable high memory area
+ * @s:		PCMCIA socket to validate
+ * @m:		resource_map to check
+ */
 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
 {
 	struct socket_data *s_data = s->resource_data;
@@ -432,9 +481,18 @@ static u_long inv_probe(struct resource_
 	}
 	if (m->base < 0x100000)
 		return 0;
-	return do_mem_probe(m->base, m->num, s);
+	return do_mem_probe(s, m->base, m->num, readable, checksum);
 }
 
+/**
+ * validate_mem() - memory probe function
+ * @s:		PCMCIA socket to validate
+ * @probe_mask: MEM_PROBE_LOW | MEM_PROBE_HIGH
+ *
+ * The memory probe.  If the memory list includes a 64K-aligned block
+ * below 1MB, we probe in 64K chunks, and as soon as we accumulate at
+ * least mem_limit free space, we quit. Returns 0 on usuable ports.
+ */
 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
 {
 	struct resource_map *m, mm;
@@ -446,6 +504,8 @@ static int validate_mem(struct pcmcia_so
 	if (probe_mask & MEM_PROBE_HIGH) {
 		if (inv_probe(s_data->mem_db.next, s) > 0)
 			return 0;
+		if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
+			return 0;
 		dev_printk(KERN_NOTICE, &s->dev,
 			   "cs: warning: no high memory space available!\n");
 		return -ENODEV;
@@ -457,7 +517,8 @@ static int validate_mem(struct pcmcia_so
 		if (mm.base >= 0x100000)
 			continue;
 		if ((mm.base | mm.num) & 0xffff) {
-			ok += do_mem_probe(mm.base, mm.num, s);
+			ok += do_mem_probe(s, mm.base, mm.num, readable,
+					   checksum);
 			continue;
 		}
 		/* Special probe for 64K-aligned block */
@@ -467,7 +528,8 @@ static int validate_mem(struct pcmcia_so
 				if (ok >= mem_limit)
 					sub_interval(&s_data->mem_db, b, 0x10000);
 				else
-					ok += do_mem_probe(b, 0x10000, s);
+					ok += do_mem_probe(s, b, 0x10000,
+							   readable, checksum);
 			}
 		}
 	}
@@ -480,6 +542,13 @@ static int validate_mem(struct pcmcia_so
 
 #else /* CONFIG_PCMCIA_PROBE */
 
+/**
+ * validate_mem() - memory probe function
+ * @s:		PCMCIA socket to validate
+ * @probe_mask: ignored
+ *
+ * Returns 0 on usuable ports.
+ */
 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
 {
 	struct resource_map *m, mm;
@@ -488,7 +557,7 @@ static int validate_mem(struct pcmcia_so
 
 	for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
 		mm = *m;
-		ok += do_mem_probe(mm.base, mm.num, s);
+		ok += do_mem_probe(s, mm.base, mm.num, readable, checksum);
 	}
 	if (ok > 0)
 		return 0;
@@ -498,31 +567,31 @@ static int validate_mem(struct pcmcia_so
 #endif /* CONFIG_PCMCIA_PROBE */
 
 
-/*
+/**
+ * pcmcia_nonstatic_validate_mem() - try to validate iomem for PCMCIA use
+ * @s:		PCMCIA socket to validate
+ *
+ * This is tricky... when we set up CIS memory, we try to validate
+ * the memory window space allocations.
+ *
  * Locking note: Must be called with skt_mutex held!
  */
 static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
 {
 	struct socket_data *s_data = s->resource_data;
 	unsigned int probe_mask = MEM_PROBE_LOW;
-	int ret = 0;
+	int ret;
 
-	if (!probe_mem)
+	if (!probe_mem || !(s->state & SOCKET_PRESENT))
 		return 0;
 
-	mutex_lock(&rsrc_mutex);
-
 	if (s->features & SS_CAP_PAGE_REGS)
 		probe_mask = MEM_PROBE_HIGH;
 
-	if (probe_mask & ~s_data->rsrc_mem_probe) {
-		if (s->state & SOCKET_PRESENT)
-			ret = validate_mem(s, probe_mask);
-		if (!ret)
-			s_data->rsrc_mem_probe |= probe_mask;
-	}
+	ret = validate_mem(s, probe_mask);
 
-	mutex_unlock(&rsrc_mutex);
+	if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
+		return 0;
 
 	return ret;
 }
@@ -533,52 +602,49 @@ struct pcmcia_align_data {
 	struct resource_map	*map;
 };
 
-static void
-pcmcia_common_align(void *align_data, struct resource *res,
-			resource_size_t size, resource_size_t align)
+static resource_size_t pcmcia_common_align(struct pcmcia_align_data *align_data,
+					resource_size_t start)
 {
-	struct pcmcia_align_data *data = align_data;
-	resource_size_t start;
+	resource_size_t ret;
 	/*
 	 * Ensure that we have the correct start address
 	 */
-	start = (res->start & ~data->mask) + data->offset;
-	if (start < res->start)
-		start += data->mask + 1;
-	res->start = start;
+	ret = (start & ~align_data->mask) + align_data->offset;
+	if (ret < start)
+		ret += align_data->mask + 1;
+	return ret;
 }
 
-static void
-pcmcia_align(void *align_data, struct resource *res, resource_size_t size,
-		resource_size_t align)
+static resource_size_t
+pcmcia_align(void *align_data, const struct resource *res,
+	resource_size_t size, resource_size_t align)
 {
 	struct pcmcia_align_data *data = align_data;
 	struct resource_map *m;
+	resource_size_t start;
 
-	pcmcia_common_align(data, res, size, align);
+	start = pcmcia_common_align(data, res->start);
 
 	for (m = data->map->next; m != data->map; m = m->next) {
-		unsigned long start = m->base;
-		unsigned long end = m->base + m->num - 1;
+		unsigned long map_start = m->base;
+		unsigned long map_end = m->base + m->num - 1;
 
 		/*
 		 * If the lower resources are not available, try aligning
 		 * to this entry of the resource database to see if it'll
 		 * fit here.
 		 */
-		if (res->start < start) {
-			res->start = start;
-			pcmcia_common_align(data, res, size, align);
-		}
+		if (start < map_start)
+			start = pcmcia_common_align(data, map_start);
 
 		/*
 		 * If we're above the area which was passed in, there's
 		 * no point proceeding.
 		 */
-		if (res->start >= res->end)
+		if (start >= res->end)
 			break;
 
-		if ((res->start + size - 1) <= end)
+		if ((start + size - 1) <= map_end)
 			break;
 	}
 
@@ -586,7 +652,9 @@ pcmcia_align(void *align_data, struct re
 	 * If we failed to find something suitable, ensure we fail.
 	 */
 	if (m == data->map)
-		res->start = res->end;
+		start = res->end;
+
+	return start;
 }
 
 /*
@@ -600,7 +668,6 @@ static int nonstatic_adjust_io_region(st
 	struct socket_data *s_data = s->resource_data;
 	int ret = -ENOMEM;
 
-	mutex_lock(&rsrc_mutex);
 	for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
 		unsigned long start = m->base;
 		unsigned long end = m->base + m->num - 1;
@@ -611,7 +678,6 @@ static int nonstatic_adjust_io_region(st
 		ret = adjust_resource(res, r_start, r_end - r_start + 1);
 		break;
 	}
-	mutex_unlock(&rsrc_mutex);
 
 	return ret;
 }
@@ -645,7 +711,6 @@ static struct resource *nonstatic_find_i
 	data.offset = base & data.mask;
 	data.map = &s_data->io_db;
 
-	mutex_lock(&rsrc_mutex);
 #ifdef CONFIG_PCI
 	if (s->cb_dev) {
 		ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
@@ -654,7 +719,6 @@ static struct resource *nonstatic_find_i
 #endif
 		ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
 					1, pcmcia_align, &data);
-	mutex_unlock(&rsrc_mutex);
 
 	if (ret != 0) {
 		kfree(res);
@@ -670,15 +734,15 @@ static struct resource *nonstatic_find_m
 	struct socket_data *s_data = s->resource_data;
 	struct pcmcia_align_data data;
 	unsigned long min, max;
-	int ret, i;
+	int ret, i, j;
 
 	low = low || !(s->features & SS_CAP_PAGE_REGS);
 
 	data.mask = align - 1;
 	data.offset = base & data.mask;
-	data.map = &s_data->mem_db;
 
 	for (i = 0; i < 2; i++) {
+		data.map = &s_data->mem_db_valid;
 		if (low) {
 			max = 0x100000UL;
 			min = base < max ? base : 0;
@@ -687,17 +751,23 @@ static struct resource *nonstatic_find_m
 			min = 0x100000UL + base;
 		}
 
-		mutex_lock(&rsrc_mutex);
+		for (j = 0; j < 2; j++) {
 #ifdef CONFIG_PCI
-		if (s->cb_dev) {
-			ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
-						     1, min, 0,
-						     pcmcia_align, &data);
-		} else
+			if (s->cb_dev) {
+				ret = pci_bus_alloc_resource(s->cb_dev->bus,
+							res, num, 1, min, 0,
+							pcmcia_align, &data);
+			} else
 #endif
-			ret = allocate_resource(&iomem_resource, res, num, min,
-						max, 1, pcmcia_align, &data);
-		mutex_unlock(&rsrc_mutex);
+			{
+				ret = allocate_resource(&iomem_resource,
+							res, num, min, max, 1,
+							pcmcia_align, &data);
+			}
+			if (ret == 0)
+				break;
+			data.map = &s_data->mem_db;
+		}
 		if (ret == 0 || low)
 			break;
 		low = 1;
@@ -720,25 +790,18 @@ static int adjust_memory(struct pcmcia_s
 	if (end < start)
 		return -EINVAL;
 
-	mutex_lock(&rsrc_mutex);
 	switch (action) {
 	case ADD_MANAGED_RESOURCE:
 		ret = add_interval(&data->mem_db, start, size);
+		if (!ret)
+			do_mem_probe(s, start, size, NULL, NULL);
 		break;
 	case REMOVE_MANAGED_RESOURCE:
 		ret = sub_interval(&data->mem_db, start, size);
-		if (!ret) {
-			struct pcmcia_socket *socket;
-			down_read(&pcmcia_socket_list_rwsem);
-			list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
-				release_cis_mem(socket);
-			up_read(&pcmcia_socket_list_rwsem);
-		}
 		break;
 	default:
 		ret = -EINVAL;
 	}
-	mutex_unlock(&rsrc_mutex);
 
 	return ret;
 }
@@ -747,16 +810,24 @@ static int adjust_memory(struct pcmcia_s
 static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
 {
 	struct socket_data *data = s->resource_data;
-	unsigned long size = end - start + 1;
+	unsigned long size;
 	int ret = 0;
 
+#if defined(CONFIG_X86)
+	/* on x86, avoid anything < 0x100 for it is often used for
+	 * legacy platform devices */
+	if (start < 0x100)
+		start = 0x100;
+#endif
+
+	size = end - start + 1;
+
 	if (end < start)
 		return -EINVAL;
 
 	if (end > IO_SPACE_LIMIT)
 		return -EINVAL;
 
-	mutex_lock(&rsrc_mutex);
 	switch (action) {
 	case ADD_MANAGED_RESOURCE:
 		if (add_interval(&data->io_db, start, size) != 0) {
@@ -775,7 +846,6 @@ static int adjust_io(struct pcmcia_socke
 		ret = -EINVAL;
 		break;
 	}
-	mutex_unlock(&rsrc_mutex);
 
 	return ret;
 }
@@ -801,8 +871,7 @@ static int nonstatic_autoadd_resources(s
 		return -EINVAL;
 #endif
 
-	for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
-		res = s->cb_dev->bus->resource[i];
+	pci_bus_for_each_resource(s->cb_dev->bus, res, i) {
 		if (!res)
 			continue;
 
@@ -810,10 +879,8 @@ static int nonstatic_autoadd_resources(s
 			if (res == &ioport_resource)
 				continue;
 			dev_printk(KERN_INFO, &s->cb_dev->dev,
-				   "pcmcia: parent PCI bridge I/O "
-				   "window: 0x%llx - 0x%llx\n",
-				   (unsigned long long)res->start,
-				   (unsigned long long)res->end);
+				   "pcmcia: parent PCI bridge window: %pR\n",
+				   res);
 			if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
 				done |= IORESOURCE_IO;
 
@@ -823,10 +890,8 @@ static int nonstatic_autoadd_resources(s
 			if (res == &iomem_resource)
 				continue;
 			dev_printk(KERN_INFO, &s->cb_dev->dev,
-				   "pcmcia: parent PCI bridge Memory "
-				   "window: 0x%llx - 0x%llx\n",
-				   (unsigned long long)res->start,
-				   (unsigned long long)res->end);
+				   "pcmcia: parent PCI bridge window: %pR\n",
+				   res);
 			if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
 				done |= IORESOURCE_MEM;
 		}
@@ -859,6 +924,7 @@ static int nonstatic_init(struct pcmcia_
 		return -ENOMEM;
 
 	data->mem_db.next = &data->mem_db;
+	data->mem_db_valid.next = &data->mem_db_valid;
 	data->io_db.next = &data->io_db;
 
 	s->resource_data = (void *) data;
@@ -873,7 +939,10 @@ static void nonstatic_release_resource_d
 	struct socket_data *data = s->resource_data;
 	struct resource_map *p, *q;
 
-	mutex_lock(&rsrc_mutex);
+	for (p = data->mem_db_valid.next; p != &data->mem_db_valid; p = q) {
+		q = p->next;
+		kfree(p);
+	}
 	for (p = data->mem_db.next; p != &data->mem_db; p = q) {
 		q = p->next;
 		kfree(p);
@@ -882,7 +951,6 @@ static void nonstatic_release_resource_d
 		q = p->next;
 		kfree(p);
 	}
-	mutex_unlock(&rsrc_mutex);
 }
 
 
@@ -909,7 +977,7 @@ static ssize_t show_io_db(struct device
 	struct resource_map *p;
 	ssize_t ret = 0;
 
-	mutex_lock(&rsrc_mutex);
+	mutex_lock(&s->ops_mutex);
 	data = s->resource_data;
 
 	for (p = data->io_db.next; p != &data->io_db; p = p->next) {
@@ -921,7 +989,7 @@ static ssize_t show_io_db(struct device
 				((unsigned long) p->base + p->num - 1));
 	}
 
-	mutex_unlock(&rsrc_mutex);
+	mutex_unlock(&s->ops_mutex);
 	return ret;
 }
 
@@ -949,9 +1017,11 @@ static ssize_t store_io_db(struct device
 	if (end_addr < start_addr)
 		return -EINVAL;
 
+	mutex_lock(&s->ops_mutex);
 	ret = adjust_io(s, add, start_addr, end_addr);
 	if (!ret)
 		s->resource_setup_new = 1;
+	mutex_unlock(&s->ops_mutex);
 
 	return ret ? ret : count;
 }
@@ -965,9 +1035,19 @@ static ssize_t show_mem_db(struct device
 	struct resource_map *p;
 	ssize_t ret = 0;
 
-	mutex_lock(&rsrc_mutex);
+	mutex_lock(&s->ops_mutex);
 	data = s->resource_data;
 
+	for (p = data->mem_db_valid.next; p != &data->mem_db_valid;
+	     p = p->next) {
+		if (ret > (PAGE_SIZE - 10))
+			continue;
+		ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
+				"0x%08lx - 0x%08lx\n",
+				((unsigned long) p->base),
+				((unsigned long) p->base + p->num - 1));
+	}
+
 	for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
 		if (ret > (PAGE_SIZE - 10))
 			continue;
@@ -977,7 +1057,7 @@ static ssize_t show_mem_db(struct device
 				((unsigned long) p->base + p->num - 1));
 	}
 
-	mutex_unlock(&rsrc_mutex);
+	mutex_unlock(&s->ops_mutex);
 	return ret;
 }
 
@@ -1005,9 +1085,11 @@ static ssize_t store_mem_db(struct devic
 	if (end_addr < start_addr)
 		return -EINVAL;
 
+	mutex_lock(&s->ops_mutex);
 	ret = adjust_memory(s, add, start_addr, end_addr);
 	if (!ret)
 		s->resource_setup_new = 1;
+	mutex_unlock(&s->ops_mutex);
 
 	return ret ? ret : count;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_generic.c linux-libre-2.6.34-gnu1/drivers/pcmcia/sa1100_generic.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/sa1100_generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 
 #include <pcmcia/cs_types.h>
@@ -95,17 +96,6 @@ static int sa11x0_drv_pcmcia_remove(stru
 	return 0;
 }
 
-static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
-				     pm_message_t state)
-{
-	return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-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",
@@ -113,8 +103,6 @@ static struct platform_driver sa11x0_pcm
 	},
 	.probe		= sa11x0_drv_pcmcia_probe,
 	.remove		= sa11x0_drv_pcmcia_remove,
-	.suspend 	= sa11x0_drv_pcmcia_suspend,
-	.resume 	= sa11x0_drv_pcmcia_resume,
 };
 
 /* sa11x0_pcmcia_init()
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1111_generic.c linux-libre-2.6.34-gnu1/drivers/pcmcia/sa1111_generic.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1111_generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/sa1111_generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <pcmcia/ss.h>
 
@@ -21,11 +22,18 @@
 
 #include "sa1111_generic.h"
 
+#define IDX_IRQ_S0_READY_NINT	(0)
+#define IDX_IRQ_S0_CD_VALID	(1)
+#define IDX_IRQ_S0_BVD1_STSCHG	(2)
+#define IDX_IRQ_S1_READY_NINT	(3)
+#define IDX_IRQ_S1_CD_VALID	(4)
+#define IDX_IRQ_S1_BVD1_STSCHG	(5)
+
 static struct pcmcia_irqs irqs[] = {
-	{ 0, IRQ_S0_CD_VALID,    "SA1111 PCMCIA card detect" },
-	{ 0, IRQ_S0_BVD1_STSCHG, "SA1111 PCMCIA BVD1"        },
-	{ 1, IRQ_S1_CD_VALID,    "SA1111 CF card detect"     },
-	{ 1, IRQ_S1_BVD1_STSCHG, "SA1111 CF BVD1"            },
+	{ 0, NO_IRQ, "SA1111 PCMCIA card detect" },
+	{ 0, NO_IRQ, "SA1111 PCMCIA BVD1"        },
+	{ 1, NO_IRQ, "SA1111 CF card detect"     },
+	{ 1, NO_IRQ, "SA1111 CF BVD1"            },
 };
 
 static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
@@ -136,7 +144,9 @@ int sa1111_pcmcia_add(struct sa1111_dev
 		s->soc.ops = ops;
 		s->soc.socket.owner = ops->owner;
 		s->soc.socket.dev.parent = &dev->dev;
-		s->soc.socket.pci_irq = s->soc.nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT;
+		s->soc.socket.pci_irq = s->soc.nr ?
+				dev->irq[IDX_IRQ_S0_READY_NINT] :
+				dev->irq[IDX_IRQ_S1_READY_NINT];
 		s->dev = dev;
 
 		ret = add(&s->soc);
@@ -162,6 +172,12 @@ static int pcmcia_probe(struct sa1111_de
 
 	base = dev->mapbase;
 
+	/* Initialize PCMCIA IRQs */
+	irqs[0].irq = dev->irq[IDX_IRQ_S0_CD_VALID];
+	irqs[1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG];
+	irqs[2].irq = dev->irq[IDX_IRQ_S1_CD_VALID];
+	irqs[3].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG];
+
 	/*
 	 * Initialise the suspend state.
 	 */
@@ -198,16 +214,6 @@ static int __devexit pcmcia_remove(struc
 	return 0;
 }
 
-static int pcmcia_suspend(struct sa1111_dev *dev, pm_message_t state)
-{
-	return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int pcmcia_resume(struct sa1111_dev *dev)
-{
-	return pcmcia_socket_dev_resume(&dev->dev);
-}
-
 static struct sa1111_driver pcmcia_driver = {
 	.drv = {
 		.name	= "sa1111-pcmcia",
@@ -215,8 +221,6 @@ static struct sa1111_driver pcmcia_drive
 	.devid		= SA1111_DEVID_PCMCIA,
 	.probe		= pcmcia_probe,
 	.remove		= __devexit_p(pcmcia_remove),
-	.suspend	= pcmcia_suspend,
-	.resume		= pcmcia_resume,
 };
 
 static int __init sa1111_drv_pcmcia_init(void)
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/sa11xx_base.c linux-libre-2.6.34-gnu1/drivers/pcmcia/sa11xx_base.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/sa11xx_base.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/sa11xx_base.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/socket_sysfs.c linux-libre-2.6.34-gnu1/drivers/pcmcia/socket_sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/socket_sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/socket_sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/string.h>
 #include <linux/major.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/timer.h>
@@ -88,15 +87,14 @@ static DEVICE_ATTR(card_vcc, 0444, pccar
 static ssize_t pccard_store_insert(struct device *dev, struct device_attribute *attr,
 				   const char *buf, size_t count)
 {
-	ssize_t ret;
 	struct pcmcia_socket *s = to_socket(dev);
 
 	if (!count)
 		return -EINVAL;
 
-	ret = pcmcia_insert_card(s);
+	pcmcia_parse_uevents(s, PCMCIA_UEVENT_INSERT);
 
-	return ret ? ret : count;
+	return count;
 }
 static DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert);
 
@@ -113,18 +111,22 @@ static ssize_t pccard_store_card_pm_stat
 					  struct device_attribute *attr,
 					  const char *buf, size_t count)
 {
-	ssize_t ret = -EINVAL;
 	struct pcmcia_socket *s = to_socket(dev);
+	ssize_t ret = count;
 
 	if (!count)
 		return -EINVAL;
 
-	if (!(s->state & SOCKET_SUSPEND) && !strncmp(buf, "off", 3))
-		ret = pcmcia_suspend_card(s);
-	else if ((s->state & SOCKET_SUSPEND) && !strncmp(buf, "on", 2))
-		ret = pcmcia_resume_card(s);
+	if (!strncmp(buf, "off", 3))
+		pcmcia_parse_uevents(s, PCMCIA_UEVENT_SUSPEND);
+	else {
+		if (!strncmp(buf, "on", 2))
+			pcmcia_parse_uevents(s, PCMCIA_UEVENT_RESUME);
+		else
+			ret = -EINVAL;
+	}
 
-	return ret ? -ENODEV : count;
+	return ret;
 }
 static DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state);
 
@@ -132,15 +134,14 @@ static ssize_t pccard_store_eject(struct
 				  struct device_attribute *attr,
 				  const char *buf, size_t count)
 {
-	ssize_t ret;
 	struct pcmcia_socket *s = to_socket(dev);
 
 	if (!count)
 		return -EINVAL;
 
-	ret = pcmcia_eject_card(s);
+	pcmcia_parse_uevents(s, PCMCIA_UEVENT_EJECT);
 
-	return ret ? ret : count;
+	return count;
 }
 static DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject);
 
@@ -167,7 +168,9 @@ static ssize_t pccard_store_irq_mask(str
 	ret = sscanf(buf, "0x%x\n", &mask);
 
 	if (ret == 1) {
+		mutex_lock(&s->ops_mutex);
 		s->irq_mask &= mask;
+		mutex_unlock(&s->ops_mutex);
 		ret = 0;
 	}
 
@@ -187,164 +190,22 @@ static ssize_t pccard_store_resource(str
 				     struct device_attribute *attr,
 				     const char *buf, size_t count)
 {
-	unsigned long flags;
 	struct pcmcia_socket *s = to_socket(dev);
 
 	if (!count)
 		return -EINVAL;
 
-	spin_lock_irqsave(&s->lock, flags);
+	mutex_lock(&s->ops_mutex);
 	if (!s->resource_setup_done)
 		s->resource_setup_done = 1;
-	spin_unlock_irqrestore(&s->lock, flags);
+	mutex_unlock(&s->ops_mutex);
 
-	mutex_lock(&s->skt_mutex);
-	if ((s->callback) &&
-	    (s->state & SOCKET_PRESENT) &&
-	    !(s->state & SOCKET_CARDBUS)) {
-		if (try_module_get(s->callback->owner)) {
-			s->callback->requery(s, 0);
-			module_put(s->callback->owner);
-		}
-	}
-	mutex_unlock(&s->skt_mutex);
+	pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);
 
 	return count;
 }
 static DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource);
 
-
-static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf, loff_t off, size_t count)
-{
-	tuple_t tuple;
-	int status, i;
-	loff_t pointer = 0;
-	ssize_t ret = 0;
-	u_char *tuplebuffer;
-	u_char *tempbuffer;
-
-	tuplebuffer = kmalloc(sizeof(u_char) * 256, GFP_KERNEL);
-	if (!tuplebuffer)
-		return -ENOMEM;
-
-	tempbuffer = kmalloc(sizeof(u_char) * 258, GFP_KERNEL);
-	if (!tempbuffer) {
-		ret = -ENOMEM;
-		goto free_tuple;
-	}
-
-	memset(&tuple, 0, sizeof(tuple_t));
-
-	tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON;
-	tuple.DesiredTuple = RETURN_FIRST_TUPLE;
-	tuple.TupleOffset = 0;
-
-	status = pccard_get_first_tuple(s, BIND_FN_ALL, &tuple);
-	while (!status) {
-		tuple.TupleData = tuplebuffer;
-		tuple.TupleDataMax = 255;
-		memset(tuplebuffer, 0, sizeof(u_char) * 255);
-
-		status = pccard_get_tuple_data(s, &tuple);
-		if (status)
-			break;
-
-		if (off < (pointer + 2 + tuple.TupleDataLen)) {
-			tempbuffer[0] = tuple.TupleCode & 0xff;
-			tempbuffer[1] = tuple.TupleLink & 0xff;
-			for (i = 0; i < tuple.TupleDataLen; i++)
-				tempbuffer[i + 2] = tuplebuffer[i] & 0xff;
-
-			for (i = 0; i < (2 + tuple.TupleDataLen); i++) {
-				if (((i + pointer) >= off) &&
-				    (i + pointer) < (off + count)) {
-					buf[ret] = tempbuffer[i];
-					ret++;
-				}
-			}
-		}
-
-		pointer += 2 + tuple.TupleDataLen;
-
-		if (pointer >= (off + count))
-			break;
-
-		if (tuple.TupleCode == CISTPL_END)
-			break;
-		status = pccard_get_next_tuple(s, BIND_FN_ALL, &tuple);
-	}
-
-	kfree(tempbuffer);
- free_tuple:
-	kfree(tuplebuffer);
-
-	return ret;
-}
-
-static ssize_t pccard_show_cis(struct kobject *kobj,
-			       struct bin_attribute *bin_attr,
-			       char *buf, loff_t off, size_t count)
-{
-	unsigned int size = 0x200;
-
-	if (off >= size)
-		count = 0;
-	else {
-		struct pcmcia_socket *s;
-		unsigned int chains;
-
-		if (off + count > size)
-			count = size - off;
-
-		s = to_socket(container_of(kobj, struct device, kobj));
-
-		if (!(s->state & SOCKET_PRESENT))
-			return -ENODEV;
-		if (pccard_validate_cis(s, &chains))
-			return -EIO;
-		if (!chains)
-			return -ENODATA;
-
-		count = pccard_extract_cis(s, buf, off, count);
-	}
-
-	return count;
-}
-
-static ssize_t pccard_store_cis(struct kobject *kobj,
-				struct bin_attribute *bin_attr,
-				char *buf, loff_t off, size_t count)
-{
-	struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj));
-	int error;
-
-	if (off)
-		return -EINVAL;
-
-	if (count >= CISTPL_MAX_CIS_SIZE)
-		return -EINVAL;
-
-	if (!(s->state & SOCKET_PRESENT))
-		return -ENODEV;
-
-	error = pcmcia_replace_cis(s, buf, count);
-	if (error)
-		return -EIO;
-
-	mutex_lock(&s->skt_mutex);
-	if ((s->callback) && (s->state & SOCKET_PRESENT) &&
-	    !(s->state & SOCKET_CARDBUS)) {
-		if (try_module_get(s->callback->owner)) {
-			s->callback->requery(s, 1);
-			module_put(s->callback->owner);
-		}
-	}
-	mutex_unlock(&s->skt_mutex);
-
-	return count;
-}
-
-
 static struct attribute *pccard_socket_attributes[] = {
 	&dev_attr_card_type.attr,
 	&dev_attr_card_voltage.attr,
@@ -362,28 +223,12 @@ static const struct attribute_group sock
 	.attrs = pccard_socket_attributes,
 };
 
-static struct bin_attribute pccard_cis_attr = {
-	.attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR },
-	.size = 0x200,
-	.read = pccard_show_cis,
-	.write = pccard_store_cis,
-};
-
 int pccard_sysfs_add_socket(struct device *dev)
 {
-	int ret = 0;
-
-	ret = sysfs_create_group(&dev->kobj, &socket_attrs);
-	if (!ret) {
-		ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr);
-		if (ret)
-			sysfs_remove_group(&dev->kobj, &socket_attrs);
-	}
-	return ret;
+	return sysfs_create_group(&dev->kobj, &socket_attrs);
 }
 
 void pccard_sysfs_remove_socket(struct device *dev)
 {
-	sysfs_remove_bin_file(&dev->kobj, &pccard_cis_attr);
 	sysfs_remove_group(&dev->kobj, &socket_attrs);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/tcic.c linux-libre-2.6.34-gnu1/drivers/pcmcia/tcic.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/tcic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/tcic.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
@@ -348,16 +347,6 @@ 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);
-}
-
-static int tcic_drv_pcmcia_resume(struct platform_device *dev)
-{
-	return pcmcia_socket_dev_resume(&dev->dev);
-}
 /*====================================================================*/
 
 static struct platform_driver tcic_driver = {
@@ -365,8 +354,6 @@ static struct platform_driver tcic_drive
 		.name = "tcic-pcmcia",
 		.owner		= THIS_MODULE,
 	},
-	.suspend 	= tcic_drv_pcmcia_suspend,
-	.resume 	= tcic_drv_pcmcia_resume,
 };
 
 static struct platform_device tcic_device = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/ti113x.h linux-libre-2.6.34-gnu1/drivers/pcmcia/ti113x.h
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/ti113x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/ti113x.h	2010-05-16 17:17:36.000000000 -0400
@@ -296,7 +296,7 @@ static int ti_init(struct yenta_socket *
 	u8 new, reg = exca_readb(socket, I365_INTCTL);
 
 	new = reg & ~I365_INTR_ENA;
-	if (socket->cb_irq)
+	if (socket->dev->irq)
 		new |= I365_INTR_ENA;
 	if (new != reg)
 		exca_writeb(socket, I365_INTCTL, new);
@@ -316,14 +316,47 @@ static int ti_override(struct yenta_sock
 	return 0;
 }
 
+static void ti113x_use_isa_irq(struct yenta_socket *socket)
+{
+	int isa_irq = -1;
+	u8 intctl;
+	u32 isa_irq_mask = 0;
+
+	if (!isa_probe)
+		return;
+
+	/* get a free isa int */
+	isa_irq_mask = yenta_probe_irq(socket, isa_interrupts);
+	if (!isa_irq_mask)
+		return; /* no useable isa irq found */
+
+	/* choose highest available */
+	for (; isa_irq_mask; isa_irq++)
+		isa_irq_mask >>= 1;
+	socket->cb_irq = isa_irq;
+
+	exca_writeb(socket, I365_CSCINT, (isa_irq << 4));
+
+	intctl = exca_readb(socket, I365_INTCTL);
+	intctl &= ~(I365_INTR_ENA | I365_IRQ_MASK);     /* CSC Enable */
+	exca_writeb(socket, I365_INTCTL, intctl);
+
+	dev_info(&socket->dev->dev,
+		"Yenta TI113x: using isa irq %d for CardBus\n", isa_irq);
+}
+
+
 static int ti113x_override(struct yenta_socket *socket)
 {
 	u8 cardctl;
 
 	cardctl = config_readb(socket, TI113X_CARD_CONTROL);
 	cardctl &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC);
-	if (socket->cb_irq)
+	if (socket->dev->irq)
 		cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ;
+	else
+		ti113x_use_isa_irq(socket);
+
 	config_writeb(socket, TI113X_CARD_CONTROL, cardctl);
 
 	return ti_override(socket);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/vrc4171_card.c linux-libre-2.6.34-gnu1/drivers/pcmcia/vrc4171_card.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/vrc4171_card.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/vrc4171_card.c	2010-05-16 17:17:36.000000000 -0400
@@ -105,6 +105,7 @@ typedef struct vrc4171_socket {
 	char name[24];
 	int csc_irq;
 	int io_irq;
+	spinlock_t lock;
 } vrc4171_socket_t;
 
 static vrc4171_socket_t vrc4171_sockets[CARD_MAX_SLOTS];
@@ -327,7 +328,7 @@ static int pccard_set_socket(struct pcmc
 	slot = sock->sock;
 	socket = &vrc4171_sockets[slot];
 
-	spin_lock_irq(&sock->lock);
+	spin_lock_irq(&socket->lock);
 
 	voltage = set_Vcc_value(state->Vcc);
 	exca_write_byte(slot, CARD_VOLTAGE_SELECT, voltage);
@@ -370,7 +371,7 @@ static int pccard_set_socket(struct pcmc
 		cscint |= I365_CSC_DETECT;
         exca_write_byte(slot, I365_CSCINT, cscint);
 
-	spin_unlock_irq(&sock->lock);
+	spin_unlock_irq(&socket->lock);
 
 	return 0;
 }
@@ -704,24 +705,11 @@ static int __devinit vrc4171_card_setup(
 
 __setup("vrc4171_card=", vrc4171_card_setup);
 
-static int vrc4171_card_suspend(struct platform_device *dev,
-				     pm_message_t state)
-{
-	return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-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)
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/xxs1500_ss.c linux-libre-2.6.34-gnu1/drivers/pcmcia/xxs1500_ss.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/xxs1500_ss.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/xxs1500_ss.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,341 @@
+/*
+ * PCMCIA socket code for the MyCable XXS1500 system.
+ *
+ * Copyright (c) 2009 Manuel Lauss <manuel.lauss@gmail.com>
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/resource.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/cistpl.h>
+
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#define MEM_MAP_SIZE	0x400000
+#define IO_MAP_SIZE	0x1000
+
+
+/*
+ * 3.3V cards only; all interfacing is done via gpios:
+ *
+ * 0/1:  carddetect (00 = card present, xx = huh)
+ * 4:	 card irq
+ * 204:  reset (high-act)
+ * 205:  buffer enable (low-act)
+ * 208/209: card voltage key (00,01,10,11)
+ * 210:  battwarn
+ * 211:  batdead
+ * 214:  power (low-act)
+ */
+#define GPIO_CDA	0
+#define GPIO_CDB	1
+#define GPIO_CARDIRQ	4
+#define GPIO_RESET	204
+#define GPIO_OUTEN	205
+#define GPIO_VSL	208
+#define GPIO_VSH	209
+#define GPIO_BATTDEAD	210
+#define GPIO_BATTWARN	211
+#define GPIO_POWER	214
+
+struct xxs1500_pcmcia_sock {
+	struct pcmcia_socket	socket;
+	void		*virt_io;
+
+	phys_addr_t	phys_io;
+	phys_addr_t	phys_attr;
+	phys_addr_t	phys_mem;
+
+	/* previous flags for set_socket() */
+	unsigned int old_flags;
+};
+
+#define to_xxs_socket(x) container_of(x, struct xxs1500_pcmcia_sock, socket)
+
+static irqreturn_t cdirq(int irq, void *data)
+{
+	struct xxs1500_pcmcia_sock *sock = data;
+
+	pcmcia_parse_events(&sock->socket, SS_DETECT);
+
+	return IRQ_HANDLED;
+}
+
+static int xxs1500_pcmcia_configure(struct pcmcia_socket *skt,
+				    struct socket_state_t *state)
+{
+	struct xxs1500_pcmcia_sock *sock = to_xxs_socket(skt);
+	unsigned int changed;
+
+	/* power control */
+	switch (state->Vcc) {
+	case 0:
+		gpio_set_value(GPIO_POWER, 1);	/* power off */
+		break;
+	case 33:
+		gpio_set_value(GPIO_POWER, 0);	/* power on */
+		break;
+	case 50:
+	default:
+		return -EINVAL;
+	}
+
+	changed = state->flags ^ sock->old_flags;
+
+	if (changed & SS_RESET) {
+		if (state->flags & SS_RESET) {
+			gpio_set_value(GPIO_RESET, 1);	/* assert reset */
+			gpio_set_value(GPIO_OUTEN, 1);	/* buffers off */
+		} else {
+			gpio_set_value(GPIO_RESET, 0);	/* deassert reset */
+			gpio_set_value(GPIO_OUTEN, 0);	/* buffers on */
+			msleep(500);
+		}
+	}
+
+	sock->old_flags = state->flags;
+
+	return 0;
+}
+
+static int xxs1500_pcmcia_get_status(struct pcmcia_socket *skt,
+				     unsigned int *value)
+{
+	unsigned int status;
+	int i;
+
+	status = 0;
+
+	/* check carddetects: GPIO[0:1] must both be low */
+	if (!gpio_get_value(GPIO_CDA) && !gpio_get_value(GPIO_CDB))
+		status |= SS_DETECT;
+
+	/* determine card voltage: GPIO[208:209] binary value */
+	i = (!!gpio_get_value(GPIO_VSL)) | ((!!gpio_get_value(GPIO_VSH)) << 1);
+
+	switch (i) {
+	case 0:
+	case 1:
+	case 2:
+		status |= SS_3VCARD;	/* 3V card */
+		break;
+	case 3:				/* 5V card, unsupported */
+	default:
+		status |= SS_XVCARD;	/* treated as unsupported in core */
+	}
+
+	/* GPIO214: low active power switch */
+	status |= gpio_get_value(GPIO_POWER) ? 0 : SS_POWERON;
+
+	/* GPIO204: high-active reset line */
+	status |= gpio_get_value(GPIO_RESET) ? SS_RESET : SS_READY;
+
+	/* other stuff */
+	status |= gpio_get_value(GPIO_BATTDEAD) ? 0 : SS_BATDEAD;
+	status |= gpio_get_value(GPIO_BATTWARN) ? 0 : SS_BATWARN;
+
+	*value = status;
+
+	return 0;
+}
+
+static int xxs1500_pcmcia_sock_init(struct pcmcia_socket *skt)
+{
+	gpio_direction_input(GPIO_CDA);
+	gpio_direction_input(GPIO_CDB);
+	gpio_direction_input(GPIO_VSL);
+	gpio_direction_input(GPIO_VSH);
+	gpio_direction_input(GPIO_BATTDEAD);
+	gpio_direction_input(GPIO_BATTWARN);
+	gpio_direction_output(GPIO_RESET, 1);	/* assert reset */
+	gpio_direction_output(GPIO_OUTEN, 1);	/* disable buffers */
+	gpio_direction_output(GPIO_POWER, 1);	/* power off */
+
+	return 0;
+}
+
+static int xxs1500_pcmcia_sock_suspend(struct pcmcia_socket *skt)
+{
+	return 0;
+}
+
+static int au1x00_pcmcia_set_io_map(struct pcmcia_socket *skt,
+				    struct pccard_io_map *map)
+{
+	struct xxs1500_pcmcia_sock *sock = to_xxs_socket(skt);
+
+	map->start = (u32)sock->virt_io;
+	map->stop = map->start + IO_MAP_SIZE;
+
+	return 0;
+}
+
+static int au1x00_pcmcia_set_mem_map(struct pcmcia_socket *skt,
+				     struct pccard_mem_map *map)
+{
+	struct xxs1500_pcmcia_sock *sock = to_xxs_socket(skt);
+
+	if (map->flags & MAP_ATTRIB)
+		map->static_start = sock->phys_attr + map->card_start;
+	else
+		map->static_start = sock->phys_mem + map->card_start;
+
+	return 0;
+}
+
+static struct pccard_operations xxs1500_pcmcia_operations = {
+	.init			= xxs1500_pcmcia_sock_init,
+	.suspend		= xxs1500_pcmcia_sock_suspend,
+	.get_status		= xxs1500_pcmcia_get_status,
+	.set_socket		= xxs1500_pcmcia_configure,
+	.set_io_map		= au1x00_pcmcia_set_io_map,
+	.set_mem_map		= au1x00_pcmcia_set_mem_map,
+};
+
+static int __devinit xxs1500_pcmcia_probe(struct platform_device *pdev)
+{
+	struct xxs1500_pcmcia_sock *sock;
+	struct resource *r;
+	int ret, irq;
+
+	sock = kzalloc(sizeof(struct xxs1500_pcmcia_sock), GFP_KERNEL);
+	if (!sock)
+		return -ENOMEM;
+
+	ret = -ENODEV;
+
+	/* 36bit PCMCIA Attribute area address */
+	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-attr");
+	if (!r) {
+		dev_err(&pdev->dev, "missing 'pcmcia-attr' resource!\n");
+		goto out0;
+	}
+	sock->phys_attr = r->start;
+
+	/* 36bit PCMCIA Memory area address */
+	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-mem");
+	if (!r) {
+		dev_err(&pdev->dev, "missing 'pcmcia-mem' resource!\n");
+		goto out0;
+	}
+	sock->phys_mem = r->start;
+
+	/* 36bit PCMCIA IO area address */
+	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-io");
+	if (!r) {
+		dev_err(&pdev->dev, "missing 'pcmcia-io' resource!\n");
+		goto out0;
+	}
+	sock->phys_io = r->start;
+
+
+	/*
+	 * PCMCIA client drivers use the inb/outb macros to access
+	 * the IO registers.  Since mips_io_port_base is added
+	 * to the access address of the mips implementation of
+	 * inb/outb, we need to subtract it here because we want
+	 * to access the I/O or MEM address directly, without
+	 * going through this "mips_io_port_base" mechanism.
+	 */
+	sock->virt_io = (void *)(ioremap(sock->phys_io, IO_MAP_SIZE) -
+				 mips_io_port_base);
+
+	if (!sock->virt_io) {
+		dev_err(&pdev->dev, "cannot remap IO area\n");
+		ret = -ENOMEM;
+		goto out0;
+	}
+
+	sock->socket.ops	= &xxs1500_pcmcia_operations;
+	sock->socket.owner	= THIS_MODULE;
+	sock->socket.pci_irq	= gpio_to_irq(GPIO_CARDIRQ);
+	sock->socket.features	= SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
+	sock->socket.map_size	= MEM_MAP_SIZE;
+	sock->socket.io_offset	= (unsigned long)sock->virt_io;
+	sock->socket.dev.parent	= &pdev->dev;
+	sock->socket.resource_ops = &pccard_static_ops;
+
+	platform_set_drvdata(pdev, sock);
+
+	/* setup carddetect irq: use one of the 2 GPIOs as an
+	 * edge detector.
+	 */
+	irq = gpio_to_irq(GPIO_CDA);
+	set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
+	ret = request_irq(irq, cdirq, 0, "pcmcia_carddetect", sock);
+	if (ret) {
+		dev_err(&pdev->dev, "cannot setup cd irq\n");
+		goto out1;
+	}
+
+	ret = pcmcia_register_socket(&sock->socket);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register\n");
+		goto out2;
+	}
+
+	printk(KERN_INFO "MyCable XXS1500 PCMCIA socket services\n");
+
+	return 0;
+
+out2:
+	free_irq(gpio_to_irq(GPIO_CDA), sock);
+out1:
+	iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
+out0:
+	kfree(sock);
+	return ret;
+}
+
+static int __devexit xxs1500_pcmcia_remove(struct platform_device *pdev)
+{
+	struct xxs1500_pcmcia_sock *sock = platform_get_drvdata(pdev);
+
+	pcmcia_unregister_socket(&sock->socket);
+	free_irq(gpio_to_irq(GPIO_CDA), sock);
+	iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
+	kfree(sock);
+
+	return 0;
+}
+
+static struct platform_driver xxs1500_pcmcia_socket_driver = {
+	.driver	= {
+		.name	= "xxs1500_pcmcia",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= xxs1500_pcmcia_probe,
+	.remove		= __devexit_p(xxs1500_pcmcia_remove),
+};
+
+int __init xxs1500_pcmcia_socket_load(void)
+{
+	return platform_driver_register(&xxs1500_pcmcia_socket_driver);
+}
+
+void  __exit xxs1500_pcmcia_socket_unload(void)
+{
+	platform_driver_unregister(&xxs1500_pcmcia_socket_driver);
+}
+
+module_init(xxs1500_pcmcia_socket_load);
+module_exit(xxs1500_pcmcia_socket_unload);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PCMCIA Socket Services for MyCable XXS1500 systems");
+MODULE_AUTHOR("Manuel Lauss");
diff -druNp linux-libre-2.6.33-gnu1/drivers/pcmcia/yenta_socket.c linux-libre-2.6.34-gnu1/drivers/pcmcia/yenta_socket.c
--- linux-libre-2.6.33-gnu1/drivers/pcmcia/yenta_socket.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pcmcia/yenta_socket.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
@@ -37,6 +38,23 @@ static int pwr_irqs_off;
 module_param(pwr_irqs_off, bool, 0644);
 MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!");
 
+static char o2_speedup[] = "default";
+module_param_string(o2_speedup, o2_speedup, sizeof(o2_speedup), 0444);
+MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' "
+	"or 'default' (uses recommended behaviour for the detected bridge)");
+
+/*
+ * Only probe "regular" interrupts, don't
+ * touch dangerous spots like the mouse irq,
+ * because there are mice that apparently
+ * get really confused if they get fondled
+ * too intimately.
+ *
+ * Default to 11, 10, 9, 7, 6, 5, 4, 3.
+ */
+static u32 isa_interrupts = 0x0ef8;
+
+
 #define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args)
 
 /* Don't ask.. */
@@ -49,6 +67,8 @@ MODULE_PARM_DESC(pwr_irqs_off, "Force IR
  */
 #ifdef CONFIG_YENTA_TI
 static int yenta_probe_cb_irq(struct yenta_socket *socket);
+static unsigned int yenta_probe_irq(struct yenta_socket *socket,
+				u32 isa_irq_mask);
 #endif
 
 
@@ -324,8 +344,8 @@ static int yenta_set_socket(struct pcmci
 		/* ISA interrupt control? */
 		intr = exca_readb(socket, I365_INTCTL);
 		intr = (intr & ~0xf);
-		if (!socket->cb_irq) {
-			intr |= state->io_irq;
+		if (!socket->dev->irq) {
+			intr |= socket->cb_irq ? socket->cb_irq : state->io_irq;
 			bridge |= CB_BRIDGE_INTR;
 		}
 		exca_writeb(socket, I365_INTCTL, intr);
@@ -335,7 +355,7 @@ static int yenta_set_socket(struct pcmci
 		reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA);
 		reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
 		reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
-		if (state->io_irq != socket->cb_irq) {
+		if (state->io_irq != socket->dev->irq) {
 			reg |= state->io_irq;
 			bridge |= CB_BRIDGE_INTR;
 		}
@@ -351,7 +371,9 @@ static int yenta_set_socket(struct pcmci
 			exca_writeb(socket, I365_POWER, reg);
 
 		/* CSC interrupt: no ISA irq for CSC */
-		reg = I365_CSC_DETECT;
+		reg = exca_readb(socket, I365_CSCINT);
+		reg &= I365_CSC_IRQ_MASK;
+		reg |= I365_CSC_DETECT;
 		if (state->flags & SS_IOCARD) {
 			if (state->csc_mask & SS_STSCHG)
 				reg |= I365_CSC_STSCHG;
@@ -649,9 +671,10 @@ static int yenta_search_one_res(struct r
 static int yenta_search_res(struct yenta_socket *socket, struct resource *res,
 			    u32 min)
 {
+	struct resource *root;
 	int i;
-	for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
-		struct resource *root = socket->dev->bus->resource[i];
+
+	pci_bus_for_each_resource(socket->dev->bus, root, i) {
 		if (!root)
 			continue;
 
@@ -890,22 +913,12 @@ static struct cardbus_type cardbus_type[
 };
 
 
-/*
- * Only probe "regular" interrupts, don't
- * touch dangerous spots like the mouse irq,
- * because there are mice that apparently
- * get really confused if they get fondled
- * too intimately.
- *
- * Default to 11, 10, 9, 7, 6, 5, 4, 3.
- */
-static u32 isa_interrupts = 0x0ef8;
-
 static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask)
 {
 	int i;
 	unsigned long val;
 	u32 mask;
+	u8 reg;
 
 	/*
 	 * Probe for usable interrupts using the force
@@ -913,6 +926,7 @@ static unsigned int yenta_probe_irq(stru
 	 */
 	cb_writel(socket, CB_SOCKET_EVENT, -1);
 	cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
+	reg = exca_readb(socket, I365_CSCINT);
 	exca_writeb(socket, I365_CSCINT, 0);
 	val = probe_irq_on() & isa_irq_mask;
 	for (i = 1; i < 16; i++) {
@@ -924,7 +938,7 @@ static unsigned int yenta_probe_irq(stru
 		cb_writel(socket, CB_SOCKET_EVENT, -1);
 	}
 	cb_writel(socket, CB_SOCKET_MASK, 0);
-	exca_writeb(socket, I365_CSCINT, 0);
+	exca_writeb(socket, I365_CSCINT, reg);
 
 	mask = probe_irq_mask(val) & 0xffff;
 
@@ -961,6 +975,8 @@ static irqreturn_t yenta_probe_handler(i
 /* probes the PCI interrupt, use only on override functions */
 static int yenta_probe_cb_irq(struct yenta_socket *socket)
 {
+	u8 reg;
+
 	if (!socket->cb_irq)
 		return -1;
 
@@ -973,7 +989,8 @@ static int yenta_probe_cb_irq(struct yen
 	}
 
 	/* generate interrupt, wait */
-	exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG);
+	reg = exca_readb(socket, I365_CSCINT);
+	exca_writeb(socket, I365_CSCINT, reg | I365_CSC_STSCHG);
 	cb_writel(socket, CB_SOCKET_EVENT, -1);
 	cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
 	cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS);
@@ -982,7 +999,7 @@ static int yenta_probe_cb_irq(struct yen
 
 	/* disable interrupts */
 	cb_writel(socket, CB_SOCKET_MASK, 0);
-	exca_writeb(socket, I365_CSCINT, 0);
+	exca_writeb(socket, I365_CSCINT, reg);
 	cb_writel(socket, CB_SOCKET_EVENT, -1);
 	exca_readb(socket, I365_CSC);
 
@@ -1274,12 +1291,9 @@ static int yenta_dev_suspend_noirq(struc
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct yenta_socket *socket = pci_get_drvdata(pdev);
-	int ret;
-
-	ret = pcmcia_socket_dev_suspend(dev);
 
 	if (!socket)
-		return ret;
+		return 0;
 
 	if (socket->type && socket->type->save_state)
 		socket->type->save_state(socket);
@@ -1296,7 +1310,7 @@ static int yenta_dev_suspend_noirq(struc
 	 */
 	/* pci_set_power_state(dev, 3); */
 
-	return ret;
+	return 0;
 }
 
 static int yenta_dev_resume_noirq(struct device *dev)
@@ -1320,26 +1334,16 @@ static int yenta_dev_resume_noirq(struct
 	if (socket->type && socket->type->restore_state)
 		socket->type->restore_state(socket);
 
-	pcmcia_socket_dev_early_resume(dev);
-	return 0;
-}
-
-static int yenta_dev_resume(struct device *dev)
-{
-	pcmcia_socket_dev_late_resume(dev);
 	return 0;
 }
 
 static const struct dev_pm_ops yenta_pm_ops = {
 	.suspend_noirq = yenta_dev_suspend_noirq,
 	.resume_noirq = yenta_dev_resume_noirq,
-	.resume = yenta_dev_resume,
 	.freeze_noirq = yenta_dev_suspend_noirq,
 	.thaw_noirq = yenta_dev_resume_noirq,
-	.thaw = yenta_dev_resume,
 	.poweroff_noirq = yenta_dev_suspend_noirq,
 	.restore_noirq = yenta_dev_resume_noirq,
-	.restore = yenta_dev_resume,
 };
 
 #define YENTA_PM_OPS	(&yenta_pm_ops)
@@ -1402,10 +1406,10 @@ static struct pci_device_id yenta_table[
 	CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7510, TI12XX),
 	CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7610, TI12XX),
 
-	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_710, TI12XX),
-	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_712, TI12XX),
-	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_720, TI12XX),
-	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_722, TI12XX),
+	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_710, ENE),
+	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_712, ENE),
+	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_720, ENE),
+	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_722, ENE),
 	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1211, ENE),
 	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, ENE),
 	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, ENE),
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/acer-wmi.c linux-libre-2.6.34-gnu1/drivers/platform/x86/acer-wmi.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/acer-wmi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/acer-wmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/rfkill.h>
 #include <linux/workqueue.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 #include <acpi/acpi_drivers.h>
 
@@ -922,9 +923,13 @@ static struct backlight_ops acer_bl_ops
 
 static int __devinit acer_backlight_init(struct device *dev)
 {
+	struct backlight_properties props;
 	struct backlight_device *bd;
 
-	bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = max_brightness;
+	bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops,
+				       &props);
 	if (IS_ERR(bd)) {
 		printk(ACER_ERR "Could not register Acer backlight device\n");
 		acer_backlight_device = NULL;
@@ -935,7 +940,6 @@ static int __devinit acer_backlight_init
 
 	bd->props.power = FB_BLANK_UNBLANK;
 	bd->props.brightness = read_brightness(bd);
-	bd->props.max_brightness = max_brightness;
 	backlight_update_status(bd);
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/asus_acpi.c linux-libre-2.6.34-gnu1/drivers/platform/x86/asus_acpi.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/asus_acpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/asus_acpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
@@ -1225,9 +1226,8 @@ static int asus_model_match(char *model)
 	else if (strncmp(model, "M2N", 3) == 0 ||
 		 strncmp(model, "M3N", 3) == 0 ||
 		 strncmp(model, "M5N", 3) == 0 ||
-		 strncmp(model, "M6N", 3) == 0 ||
 		 strncmp(model, "S1N", 3) == 0 ||
-		 strncmp(model, "S5N", 3) == 0 || strncmp(model, "W1N", 3) == 0)
+		 strncmp(model, "S5N", 3) == 0)
 		return xxN;
 	else if (strncmp(model, "M1", 2) == 0)
 		return M1A;
@@ -1482,6 +1482,7 @@ static void asus_acpi_exit(void)
 
 static int __init asus_acpi_init(void)
 {
+	struct backlight_properties props;
 	int result;
 
 	result = acpi_bus_register_driver(&asus_hotk_driver);
@@ -1508,15 +1509,17 @@ static int __init asus_acpi_init(void)
 		return -ENODEV;
 	}
 
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = 15;
 	asus_backlight_device = backlight_device_register("asus", NULL, NULL,
-							  &asus_backlight_data);
+							  &asus_backlight_data,
+							  &props);
 	if (IS_ERR(asus_backlight_device)) {
 		printk(KERN_ERR "Could not register asus backlight device\n");
 		asus_backlight_device = NULL;
 		asus_acpi_exit();
 		return -ENODEV;
 	}
-	asus_backlight_device->props.max_brightness = 15;
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/asus-laptop.c linux-libre-2.6.34-gnu1/drivers/platform/x86/asus-laptop.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/asus-laptop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/asus-laptop.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,58 +45,24 @@
 #include <linux/fb.h>
 #include <linux/leds.h>
 #include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+#include <linux/rfkill.h>
+#include <linux/slab.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
-#include <asm/uaccess.h>
-#include <linux/input.h>
-
-#define ASUS_LAPTOP_VERSION "0.42"
-
-#define ASUS_HOTK_NAME          "Asus Laptop Support"
-#define ASUS_HOTK_CLASS         "hotkey"
-#define ASUS_HOTK_DEVICE_NAME   "Hotkey"
-#define ASUS_HOTK_FILE          KBUILD_MODNAME
-#define ASUS_HOTK_PREFIX        "\\_SB.ATKD."
-
-
-/*
- * Some events we use, same for all Asus
- */
-#define ATKD_BR_UP       0x10
-#define ATKD_BR_DOWN     0x20
-#define ATKD_LCD_ON      0x33
-#define ATKD_LCD_OFF     0x34
 
-/*
- * Known bits returned by \_SB.ATKD.HWRS
- */
-#define WL_HWRS     0x80
-#define BT_HWRS     0x100
-
-/*
- * Flags for hotk status
- * WL_ON and BT_ON are also used for wireless_status()
- */
-#define WL_ON       0x01	/* internal Wifi */
-#define BT_ON       0x02	/* internal Bluetooth */
-#define MLED_ON     0x04	/* mail LED */
-#define TLED_ON     0x08	/* touchpad LED */
-#define RLED_ON     0x10	/* Record LED */
-#define PLED_ON     0x20	/* Phone LED */
-#define GLED_ON     0x40	/* Gaming LED */
-#define LCD_ON      0x80	/* LCD backlight */
-#define GPS_ON      0x100	/* GPS */
-#define KEY_ON      0x200	/* Keyboard backlight */
+#define ASUS_LAPTOP_VERSION	"0.42"
 
-#define ASUS_LOG    ASUS_HOTK_FILE ": "
-#define ASUS_ERR    KERN_ERR    ASUS_LOG
-#define ASUS_WARNING    KERN_WARNING    ASUS_LOG
-#define ASUS_NOTICE KERN_NOTICE ASUS_LOG
-#define ASUS_INFO   KERN_INFO   ASUS_LOG
-#define ASUS_DEBUG  KERN_DEBUG  ASUS_LOG
+#define ASUS_LAPTOP_NAME	"Asus Laptop Support"
+#define ASUS_LAPTOP_CLASS	"hotkey"
+#define ASUS_LAPTOP_DEVICE_NAME	"Hotkey"
+#define ASUS_LAPTOP_FILE	KBUILD_MODNAME
+#define ASUS_LAPTOP_PREFIX	"\\_SB.ATKD."
 
 MODULE_AUTHOR("Julien Lerouge, Karol Kozimor, Corentin Chary");
-MODULE_DESCRIPTION(ASUS_HOTK_NAME);
+MODULE_DESCRIPTION(ASUS_LAPTOP_NAME);
 MODULE_LICENSE("GPL");
 
 /*
@@ -113,225 +79,209 @@ static uint wapf = 1;
 module_param(wapf, uint, 0644);
 MODULE_PARM_DESC(wapf, "WAPF value");
 
-#define ASUS_HANDLE(object, paths...)					\
-	static acpi_handle  object##_handle = NULL;			\
-	static char *object##_paths[] = { paths }
+static int wlan_status = 1;
+static int bluetooth_status = 1;
+
+module_param(wlan_status, int, 0644);
+MODULE_PARM_DESC(wlan_status, "Set the wireless status on boot "
+		 "(0 = disabled, 1 = enabled, -1 = don't do anything). "
+		 "default is 1");
+
+module_param(bluetooth_status, int, 0644);
+MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
+		 "(0 = disabled, 1 = enabled, -1 = don't do anything). "
+		 "default is 1");
+
+/*
+ * Some events we use, same for all Asus
+ */
+#define ATKD_BR_UP	0x10	/* (event & ~ATKD_BR_UP) = brightness level */
+#define ATKD_BR_DOWN	0x20	/* (event & ~ATKD_BR_DOWN) = britghness level */
+#define ATKD_BR_MIN	ATKD_BR_UP
+#define ATKD_BR_MAX	(ATKD_BR_DOWN | 0xF)	/* 0x2f */
+#define ATKD_LCD_ON	0x33
+#define ATKD_LCD_OFF	0x34
+
+/*
+ * Known bits returned by \_SB.ATKD.HWRS
+ */
+#define WL_HWRS		0x80
+#define BT_HWRS		0x100
+
+/*
+ * Flags for hotk status
+ * WL_ON and BT_ON are also used for wireless_status()
+ */
+#define WL_RSTS		0x01	/* internal Wifi */
+#define BT_RSTS		0x02	/* internal Bluetooth */
 
 /* LED */
-ASUS_HANDLE(mled_set, ASUS_HOTK_PREFIX "MLED");
-ASUS_HANDLE(tled_set, ASUS_HOTK_PREFIX "TLED");
-ASUS_HANDLE(rled_set, ASUS_HOTK_PREFIX "RLED");	/* W1JC */
-ASUS_HANDLE(pled_set, ASUS_HOTK_PREFIX "PLED");	/* A7J */
-ASUS_HANDLE(gled_set, ASUS_HOTK_PREFIX "GLED");	/* G1, G2 (probably) */
+#define METHOD_MLED		"MLED"
+#define METHOD_TLED		"TLED"
+#define METHOD_RLED		"RLED"	/* W1JC */
+#define METHOD_PLED		"PLED"	/* A7J */
+#define METHOD_GLED		"GLED"	/* G1, G2 (probably) */
 
 /* LEDD */
-ASUS_HANDLE(ledd_set, ASUS_HOTK_PREFIX "SLCM");
+#define METHOD_LEDD		"SLCM"
 
 /*
  * Bluetooth and WLAN
  * WLED and BLED are not handled like other XLED, because in some dsdt
  * they also control the WLAN/Bluetooth device.
  */
-ASUS_HANDLE(wl_switch, ASUS_HOTK_PREFIX "WLED");
-ASUS_HANDLE(bt_switch, ASUS_HOTK_PREFIX "BLED");
-ASUS_HANDLE(wireless_status, ASUS_HOTK_PREFIX "RSTS");	/* All new models */
+#define METHOD_WLAN		"WLED"
+#define METHOD_BLUETOOTH	"BLED"
+#define METHOD_WL_STATUS	"RSTS"
 
 /* Brightness */
-ASUS_HANDLE(brightness_set, ASUS_HOTK_PREFIX "SPLV");
-ASUS_HANDLE(brightness_get, ASUS_HOTK_PREFIX "GPLV");
+#define METHOD_BRIGHTNESS_SET	"SPLV"
+#define METHOD_BRIGHTNESS_GET	"GPLV"
 
 /* Backlight */
-ASUS_HANDLE(lcd_switch, "\\_SB.PCI0.SBRG.EC0._Q10",	/* All new models */
-	    "\\_SB.PCI0.ISA.EC0._Q10",	/* A1x */
-	    "\\_SB.PCI0.PX40.ECD0._Q10",	/* L3C */
-	    "\\_SB.PCI0.PX40.EC0.Q10",	/* M1A */
-	    "\\_SB.PCI0.LPCB.EC0._Q10",	/* P30 */
-	    "\\_SB.PCI0.LPCB.EC0._Q0E", /* P30/P35 */
-	    "\\_SB.PCI0.PX40.Q10",	/* S1x */
-	    "\\Q10");		/* A2x, L2D, L3D, M2E */
+static acpi_handle lcd_switch_handle;
+static char *lcd_switch_paths[] = {
+  "\\_SB.PCI0.SBRG.EC0._Q10",	/* All new models */
+  "\\_SB.PCI0.ISA.EC0._Q10",	/* A1x */
+  "\\_SB.PCI0.PX40.ECD0._Q10",	/* L3C */
+  "\\_SB.PCI0.PX40.EC0.Q10",	/* M1A */
+  "\\_SB.PCI0.LPCB.EC0._Q10",	/* P30 */
+  "\\_SB.PCI0.LPCB.EC0._Q0E", /* P30/P35 */
+  "\\_SB.PCI0.PX40.Q10",	/* S1x */
+  "\\Q10"};		/* A2x, L2D, L3D, M2E */
 
 /* Display */
-ASUS_HANDLE(display_set, ASUS_HOTK_PREFIX "SDSP");
-ASUS_HANDLE(display_get,
-	    /* A6B, A6K A6R A7D F3JM L4R M6R A3G M6A M6V VX-1 V6J V6V W3Z */
-	    "\\_SB.PCI0.P0P1.VGA.GETD",
-	    /* A3E A4K, A4D A4L A6J A7J A8J Z71V M9V S5A M5A z33A W1Jc W2V G1 */
-	    "\\_SB.PCI0.P0P2.VGA.GETD",
-	    /* A6V A6Q */
-	    "\\_SB.PCI0.P0P3.VGA.GETD",
-	    /* A6T, A6M */
-	    "\\_SB.PCI0.P0PA.VGA.GETD",
-	    /* L3C */
-	    "\\_SB.PCI0.PCI1.VGAC.NMAP",
-	    /* Z96F */
-	    "\\_SB.PCI0.VGA.GETD",
-	    /* A2D */
-	    "\\ACTD",
-	    /* A4G Z71A W1N W5A W5F M2N M3N M5N M6N S1N S5N */
-	    "\\ADVG",
-	    /* P30 */
-	    "\\DNXT",
-	    /* A2H D1 L2D L3D L3H L2E L5D L5C M1A M2E L4L W3V */
-	    "\\INFB",
-	    /* A3F A6F A3N A3L M6N W3N W6A */
-	    "\\SSTE");
+#define METHOD_SWITCH_DISPLAY	"SDSP"
 
-ASUS_HANDLE(ls_switch, ASUS_HOTK_PREFIX "ALSC"); /* Z71A Z71V */
-ASUS_HANDLE(ls_level, ASUS_HOTK_PREFIX "ALSL");	 /* Z71A Z71V */
+static acpi_handle display_get_handle;
+static char *display_get_paths[] = {
+  /* A6B, A6K A6R A7D F3JM L4R M6R A3G M6A M6V VX-1 V6J V6V W3Z */
+  "\\_SB.PCI0.P0P1.VGA.GETD",
+  /* A3E A4K, A4D A4L A6J A7J A8J Z71V M9V S5A M5A z33A W1Jc W2V G1 */
+  "\\_SB.PCI0.P0P2.VGA.GETD",
+  /* A6V A6Q */
+  "\\_SB.PCI0.P0P3.VGA.GETD",
+  /* A6T, A6M */
+  "\\_SB.PCI0.P0PA.VGA.GETD",
+  /* L3C */
+  "\\_SB.PCI0.PCI1.VGAC.NMAP",
+  /* Z96F */
+  "\\_SB.PCI0.VGA.GETD",
+  /* A2D */
+  "\\ACTD",
+  /* A4G Z71A W1N W5A W5F M2N M3N M5N M6N S1N S5N */
+  "\\ADVG",
+  /* P30 */
+  "\\DNXT",
+  /* A2H D1 L2D L3D L3H L2E L5D L5C M1A M2E L4L W3V */
+  "\\INFB",
+  /* A3F A6F A3N A3L M6N W3N W6A */
+  "\\SSTE"};
+
+#define METHOD_ALS_CONTROL	"ALSC" /* Z71A Z71V */
+#define METHOD_ALS_LEVEL	"ALSL" /* Z71A Z71V */
 
 /* GPS */
 /* R2H use different handle for GPS on/off */
-ASUS_HANDLE(gps_on, ASUS_HOTK_PREFIX "SDON");	/* R2H */
-ASUS_HANDLE(gps_off, ASUS_HOTK_PREFIX "SDOF");	/* R2H */
-ASUS_HANDLE(gps_status, ASUS_HOTK_PREFIX "GPST");
+#define METHOD_GPS_ON		"SDON"
+#define METHOD_GPS_OFF		"SDOF"
+#define METHOD_GPS_STATUS	"GPST"
 
 /* Keyboard light */
-ASUS_HANDLE(kled_set, ASUS_HOTK_PREFIX "SLKB");
-ASUS_HANDLE(kled_get, ASUS_HOTK_PREFIX "GLKB");
+#define METHOD_KBD_LIGHT_SET	"SLKB"
+#define METHOD_KBD_LIGHT_GET	"GLKB"
 
 /*
- * This is the main structure, we can use it to store anything interesting
- * about the hotk device
+ * Define a specific led structure to keep the main structure clean
  */
-struct asus_hotk {
-	char *name;		/* laptop name */
-	struct acpi_device *device;	/* the device we are in */
-	acpi_handle handle;	/* the handle of the hotk device */
-	char status;		/* status of the hotk, for LEDs, ... */
-	u32 ledd_status;	/* status of the LED display */
-	u8 light_level;		/* light sensor level */
-	u8 light_switch;	/* light sensor switch value */
-	u16 event_count[128];	/* count for each event TODO make this better */
-	struct input_dev *inputdev;
-	u16 *keycode_map;
+struct asus_led {
+	int wk;
+	struct work_struct work;
+	struct led_classdev led;
+	struct asus_laptop *asus;
+	const char *method;
 };
 
 /*
- * This header is made available to allow proper configuration given model,
- * revision number , ... this info cannot go in struct asus_hotk because it is
- * available before the hotk
- */
-static struct acpi_table_header *asus_info;
-
-/* The actual device the driver binds to */
-static struct asus_hotk *hotk;
-
-/*
- * The hotkey driver declaration
+ * This is the main structure, we can use it to store anything interesting
+ * about the hotk device
  */
-static const struct acpi_device_id asus_device_ids[] = {
-	{"ATK0100", 0},
-	{"ATK0101", 0},
-	{"", 0},
-};
-MODULE_DEVICE_TABLE(acpi, asus_device_ids);
-
-static int asus_hotk_add(struct acpi_device *device);
-static int asus_hotk_remove(struct acpi_device *device, int type);
-static void asus_hotk_notify(struct acpi_device *device, u32 event);
-
-static struct acpi_driver asus_hotk_driver = {
-	.name = ASUS_HOTK_NAME,
-	.class = ASUS_HOTK_CLASS,
-	.owner = THIS_MODULE,
-	.ids = asus_device_ids,
-	.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
-	.ops = {
-		.add = asus_hotk_add,
-		.remove = asus_hotk_remove,
-		.notify = asus_hotk_notify,
-		},
-};
+struct asus_laptop {
+	char *name;		/* laptop name */
 
-/* The backlight device /sys/class/backlight */
-static struct backlight_device *asus_backlight_device;
+	struct acpi_table_header *dsdt_info;
+	struct platform_device *platform_device;
+	struct acpi_device *device;		/* the device we are in */
+	struct backlight_device *backlight_device;
 
-/*
- * The backlight class declaration
- */
-static int read_brightness(struct backlight_device *bd);
-static int update_bl_status(struct backlight_device *bd);
-static struct backlight_ops asusbl_ops = {
-	.get_brightness = read_brightness,
-	.update_status = update_bl_status,
-};
+	struct input_dev *inputdev;
+	struct key_entry *keymap;
 
-/*
- * These functions actually update the LED's, and are called from a
- * workqueue. By doing this as separate work rather than when the LED
- * subsystem asks, we avoid messing with the Asus ACPI stuff during a
- * potentially bad time, such as a timer interrupt.
- */
-static struct workqueue_struct *led_workqueue;
+	struct asus_led mled;
+	struct asus_led tled;
+	struct asus_led rled;
+	struct asus_led pled;
+	struct asus_led gled;
+	struct asus_led kled;
+	struct workqueue_struct *led_workqueue;
 
-#define ASUS_LED(object, ledname, max)					\
-	static void object##_led_set(struct led_classdev *led_cdev,	\
-				     enum led_brightness value);	\
-	static enum led_brightness object##_led_get(			\
-		struct led_classdev *led_cdev);				\
-	static void object##_led_update(struct work_struct *ignored);	\
-	static int object##_led_wk;					\
-	static DECLARE_WORK(object##_led_work, object##_led_update);	\
-	static struct led_classdev object##_led = {			\
-		.name           = "asus::" ledname,			\
-		.brightness_set = object##_led_set,			\
-		.brightness_get = object##_led_get,			\
-		.max_brightness = max					\
-	}
+	int wireless_status;
+	bool have_rsts;
+	int lcd_state;
 
-ASUS_LED(mled, "mail", 1);
-ASUS_LED(tled, "touchpad", 1);
-ASUS_LED(rled, "record", 1);
-ASUS_LED(pled, "phone", 1);
-ASUS_LED(gled, "gaming", 1);
-ASUS_LED(kled, "kbd_backlight", 3);
+	struct rfkill *gps_rfkill;
 
-struct key_entry {
-	char type;
-	u8 code;
-	u16 keycode;
+	acpi_handle handle;	/* the handle of the hotk device */
+	u32 ledd_status;	/* status of the LED display */
+	u8 light_level;		/* light sensor level */
+	u8 light_switch;	/* light sensor switch value */
+	u16 event_count[128];	/* count for each event TODO make this better */
+	u16 *keycode_map;
 };
 
-enum { KE_KEY, KE_END };
-
-static struct key_entry asus_keymap[] = {
-	{KE_KEY, 0x02, KEY_SCREENLOCK},
-	{KE_KEY, 0x05, KEY_WLAN},
-	{KE_KEY, 0x08, KEY_F13},
-	{KE_KEY, 0x17, KEY_ZOOM},
-	{KE_KEY, 0x1f, KEY_BATTERY},
-	{KE_KEY, 0x30, KEY_VOLUMEUP},
-	{KE_KEY, 0x31, KEY_VOLUMEDOWN},
-	{KE_KEY, 0x32, KEY_MUTE},
-	{KE_KEY, 0x33, KEY_SWITCHVIDEOMODE},
-	{KE_KEY, 0x34, KEY_SWITCHVIDEOMODE},
-	{KE_KEY, 0x40, KEY_PREVIOUSSONG},
-	{KE_KEY, 0x41, KEY_NEXTSONG},
-	{KE_KEY, 0x43, KEY_STOPCD},
-	{KE_KEY, 0x45, KEY_PLAYPAUSE},
-	{KE_KEY, 0x4c, KEY_MEDIA},
-	{KE_KEY, 0x50, KEY_EMAIL},
-	{KE_KEY, 0x51, KEY_WWW},
-	{KE_KEY, 0x55, KEY_CALC},
-	{KE_KEY, 0x5C, KEY_SCREENLOCK},  /* Screenlock */
-	{KE_KEY, 0x5D, KEY_WLAN},
-	{KE_KEY, 0x5E, KEY_WLAN},
-	{KE_KEY, 0x5F, KEY_WLAN},
-	{KE_KEY, 0x60, KEY_SWITCHVIDEOMODE},
-	{KE_KEY, 0x61, KEY_SWITCHVIDEOMODE},
-	{KE_KEY, 0x62, KEY_SWITCHVIDEOMODE},
-	{KE_KEY, 0x63, KEY_SWITCHVIDEOMODE},
-	{KE_KEY, 0x6B, KEY_F13}, /* Lock Touchpad */
-	{KE_KEY, 0x82, KEY_CAMERA},
-	{KE_KEY, 0x88, KEY_WLAN },
-	{KE_KEY, 0x8A, KEY_PROG1},
-	{KE_KEY, 0x95, KEY_MEDIA},
-	{KE_KEY, 0x99, KEY_PHONE},
-	{KE_KEY, 0xc4, KEY_KBDILLUMUP},
-	{KE_KEY, 0xc5, KEY_KBDILLUMDOWN},
+static const struct key_entry asus_keymap[] = {
+	/* Lenovo SL Specific keycodes */
+	{KE_KEY, 0x02, { KEY_SCREENLOCK } },
+	{KE_KEY, 0x05, { KEY_WLAN } },
+	{KE_KEY, 0x08, { KEY_F13 } },
+	{KE_KEY, 0x17, { KEY_ZOOM } },
+	{KE_KEY, 0x1f, { KEY_BATTERY } },
+	/* End of Lenovo SL Specific keycodes */
+	{KE_KEY, 0x30, { KEY_VOLUMEUP } },
+	{KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
+	{KE_KEY, 0x32, { KEY_MUTE } },
+	{KE_KEY, 0x33, { KEY_SWITCHVIDEOMODE } },
+	{KE_KEY, 0x34, { KEY_SWITCHVIDEOMODE } },
+	{KE_KEY, 0x40, { KEY_PREVIOUSSONG } },
+	{KE_KEY, 0x41, { KEY_NEXTSONG } },
+	{KE_KEY, 0x43, { KEY_STOPCD } },
+	{KE_KEY, 0x45, { KEY_PLAYPAUSE } },
+	{KE_KEY, 0x4c, { KEY_MEDIA } },
+	{KE_KEY, 0x50, { KEY_EMAIL } },
+	{KE_KEY, 0x51, { KEY_WWW } },
+	{KE_KEY, 0x55, { KEY_CALC } },
+	{KE_KEY, 0x5C, { KEY_SCREENLOCK } },  /* Screenlock */
+	{KE_KEY, 0x5D, { KEY_WLAN } },
+	{KE_KEY, 0x5E, { KEY_WLAN } },
+	{KE_KEY, 0x5F, { KEY_WLAN } },
+	{KE_KEY, 0x60, { KEY_SWITCHVIDEOMODE } },
+	{KE_KEY, 0x61, { KEY_SWITCHVIDEOMODE } },
+	{KE_KEY, 0x62, { KEY_SWITCHVIDEOMODE } },
+	{KE_KEY, 0x63, { KEY_SWITCHVIDEOMODE } },
+	{KE_KEY, 0x6B, { KEY_F13 } }, /* Lock Touchpad */
+	{KE_KEY, 0x7E, { KEY_BLUETOOTH } },
+	{KE_KEY, 0x7D, { KEY_BLUETOOTH } },
+	{KE_KEY, 0x82, { KEY_CAMERA } },
+	{KE_KEY, 0x88, { KEY_WLAN  } },
+	{KE_KEY, 0x8A, { KEY_PROG1 } },
+	{KE_KEY, 0x95, { KEY_MEDIA } },
+	{KE_KEY, 0x99, { KEY_PHONE } },
+	{KE_KEY, 0xc4, { KEY_KBDILLUMUP } },
+	{KE_KEY, 0xc5, { KEY_KBDILLUMDOWN } },
 	{KE_END, 0},
 };
 
+
 /*
  * This function evaluates an ACPI method, given an int as parameter, the
  * method is searched within the scope of the handle, can be NULL. The output
@@ -339,8 +289,8 @@ static struct key_entry asus_keymap[] =
  *
  * returns 0 if write is successful, -1 else.
  */
-static int write_acpi_int(acpi_handle handle, const char *method, int val,
-			  struct acpi_buffer *output)
+static int write_acpi_int_ret(acpi_handle handle, const char *method, int val,
+			      struct acpi_buffer *output)
 {
 	struct acpi_object_list params;	/* list of input parameters (an int) */
 	union acpi_object in_obj;	/* the only param we use */
@@ -361,102 +311,82 @@ static int write_acpi_int(acpi_handle ha
 		return -1;
 }
 
-static int read_wireless_status(int mask)
+static int write_acpi_int(acpi_handle handle, const char *method, int val)
 {
-	unsigned long long status;
-	acpi_status rv = AE_OK;
+	return write_acpi_int_ret(handle, method, val, NULL);
+}
 
-	if (!wireless_status_handle)
-		return (hotk->status & mask) ? 1 : 0;
+static int acpi_check_handle(acpi_handle handle, const char *method,
+			     acpi_handle *ret)
+{
+	acpi_status status;
 
-	rv = acpi_evaluate_integer(wireless_status_handle, NULL, NULL, &status);
-	if (ACPI_FAILURE(rv))
-		pr_warning("Error reading Wireless status\n");
-	else
-		return (status & mask) ? 1 : 0;
+	if (method == NULL)
+		return -ENODEV;
 
-	return (hotk->status & mask) ? 1 : 0;
+	if (ret)
+		status = acpi_get_handle(handle, (char *)method,
+					 ret);
+	else {
+		acpi_handle dummy;
+
+		status = acpi_get_handle(handle, (char *)method,
+					 &dummy);
+	}
+
+	if (status != AE_OK) {
+		if (ret)
+			pr_warning("Error finding %s\n", method);
+		return -ENODEV;
+	}
+	return 0;
 }
 
-static int read_gps_status(void)
+/* Generic LED function */
+static int asus_led_set(struct asus_laptop *asus, const char *method,
+			 int value)
 {
-	unsigned long long status;
-	acpi_status rv = AE_OK;
-
-	rv = acpi_evaluate_integer(gps_status_handle, NULL, NULL, &status);
-	if (ACPI_FAILURE(rv))
-		pr_warning("Error reading GPS status\n");
+	if (!strcmp(method, METHOD_MLED))
+		value = !value;
+	else if (!strcmp(method, METHOD_GLED))
+		value = !value + 1;
 	else
-		return status ? 1 : 0;
+		value = !!value;
 
-	return (hotk->status & GPS_ON) ? 1 : 0;
+	return write_acpi_int(asus->handle, method, value);
 }
 
-/* Generic LED functions */
-static int read_status(int mask)
+/*
+ * LEDs
+ */
+/* /sys/class/led handlers */
+static void asus_led_cdev_set(struct led_classdev *led_cdev,
+			 enum led_brightness value)
 {
-	/* There is a special method for both wireless devices */
-	if (mask == BT_ON || mask == WL_ON)
-		return read_wireless_status(mask);
-	else if (mask == GPS_ON)
-		return read_gps_status();
+	struct asus_led *led = container_of(led_cdev, struct asus_led, led);
+	struct asus_laptop *asus = led->asus;
 
-	return (hotk->status & mask) ? 1 : 0;
+	led->wk = !!value;
+	queue_work(asus->led_workqueue, &led->work);
 }
 
-static void write_status(acpi_handle handle, int out, int mask)
+static void asus_led_cdev_update(struct work_struct *work)
 {
-	hotk->status = (out) ? (hotk->status | mask) : (hotk->status & ~mask);
-
-	switch (mask) {
-	case MLED_ON:
-		out = !(out & 0x1);
-		break;
-	case GLED_ON:
-		out = (out & 0x1) + 1;
-		break;
-	case GPS_ON:
-		handle = (out) ? gps_on_handle : gps_off_handle;
-		out = 0x02;
-		break;
-	default:
-		out &= 0x1;
-		break;
-	}
+	struct asus_led *led = container_of(work, struct asus_led, work);
+	struct asus_laptop *asus = led->asus;
 
-	if (write_acpi_int(handle, NULL, out, NULL))
-		pr_warning(" write failed %x\n", mask);
+	asus_led_set(asus, led->method, led->wk);
 }
 
-/* /sys/class/led handlers */
-#define ASUS_LED_HANDLER(object, mask)					\
-	static void object##_led_set(struct led_classdev *led_cdev,	\
-				     enum led_brightness value)		\
-	{								\
-		object##_led_wk = (value > 0) ? 1 : 0;			\
-		queue_work(led_workqueue, &object##_led_work);		\
-	}								\
-	static void object##_led_update(struct work_struct *ignored)	\
-	{								\
-		int value = object##_led_wk;				\
-		write_status(object##_set_handle, value, (mask));	\
-	}								\
-	static enum led_brightness object##_led_get(			\
-		struct led_classdev *led_cdev)				\
-	{								\
-		return led_cdev->brightness;				\
-	}
-
-ASUS_LED_HANDLER(mled, MLED_ON);
-ASUS_LED_HANDLER(pled, PLED_ON);
-ASUS_LED_HANDLER(rled, RLED_ON);
-ASUS_LED_HANDLER(tled, TLED_ON);
-ASUS_LED_HANDLER(gled, GLED_ON);
+static enum led_brightness asus_led_cdev_get(struct led_classdev *led_cdev)
+{
+	return led_cdev->brightness;
+}
 
 /*
- * Keyboard backlight
+ * Keyboard backlight (also a LED)
  */
-static int get_kled_lvl(void)
+static int asus_kled_lvl(struct asus_laptop *asus)
 {
 	unsigned long long kblv;
 	struct acpi_object_list params;
@@ -468,75 +398,183 @@ static int get_kled_lvl(void)
 	in_obj.type = ACPI_TYPE_INTEGER;
 	in_obj.integer.value = 2;
 
-	rv = acpi_evaluate_integer(kled_get_handle, NULL, &params, &kblv);
+	rv = acpi_evaluate_integer(asus->handle, METHOD_KBD_LIGHT_GET,
+				   &params, &kblv);
 	if (ACPI_FAILURE(rv)) {
 		pr_warning("Error reading kled level\n");
-		return 0;
+		return -ENODEV;
 	}
 	return kblv;
 }
 
-static int set_kled_lvl(int kblv)
+static int asus_kled_set(struct asus_laptop *asus, int kblv)
 {
 	if (kblv > 0)
 		kblv = (1 << 7) | (kblv & 0x7F);
 	else
 		kblv = 0;
 
-	if (write_acpi_int(kled_set_handle, NULL, kblv, NULL)) {
+	if (write_acpi_int(asus->handle, METHOD_KBD_LIGHT_SET, kblv)) {
 		pr_warning("Keyboard LED display write failed\n");
 		return -EINVAL;
 	}
 	return 0;
 }
 
-static void kled_led_set(struct led_classdev *led_cdev,
-			 enum led_brightness value)
+static void asus_kled_cdev_set(struct led_classdev *led_cdev,
+			      enum led_brightness value)
 {
-	kled_led_wk = value;
-	queue_work(led_workqueue, &kled_led_work);
+	struct asus_led *led = container_of(led_cdev, struct asus_led, led);
+	struct asus_laptop *asus = led->asus;
+
+	led->wk = value;
+	queue_work(asus->led_workqueue, &led->work);
 }
 
-static void kled_led_update(struct work_struct *ignored)
+static void asus_kled_cdev_update(struct work_struct *work)
 {
-	set_kled_lvl(kled_led_wk);
+	struct asus_led *led = container_of(work, struct asus_led, work);
+	struct asus_laptop *asus = led->asus;
+
+	asus_kled_set(asus, led->wk);
 }
 
-static enum led_brightness kled_led_get(struct led_classdev *led_cdev)
+static enum led_brightness asus_kled_cdev_get(struct led_classdev *led_cdev)
 {
-	return get_kled_lvl();
+	struct asus_led *led = container_of(led_cdev, struct asus_led, led);
+	struct asus_laptop *asus = led->asus;
+
+	return asus_kled_lvl(asus);
 }
 
-static int get_lcd_state(void)
+static void asus_led_exit(struct asus_laptop *asus)
 {
-	return read_status(LCD_ON);
+	if (asus->mled.led.dev)
+		led_classdev_unregister(&asus->mled.led);
+	if (asus->tled.led.dev)
+		led_classdev_unregister(&asus->tled.led);
+	if (asus->pled.led.dev)
+		led_classdev_unregister(&asus->pled.led);
+	if (asus->rled.led.dev)
+		led_classdev_unregister(&asus->rled.led);
+	if (asus->gled.led.dev)
+		led_classdev_unregister(&asus->gled.led);
+	if (asus->kled.led.dev)
+		led_classdev_unregister(&asus->kled.led);
+	if (asus->led_workqueue) {
+		destroy_workqueue(asus->led_workqueue);
+		asus->led_workqueue = NULL;
+	}
 }
 
-static int set_lcd_state(int value)
+/*  Ugly macro, need to fix that later */
+static int asus_led_register(struct asus_laptop *asus,
+			     struct asus_led *led,
+			     const char *name, const char *method)
+{
+	struct led_classdev *led_cdev = &led->led;
+
+	if (!method || acpi_check_handle(asus->handle, method, NULL))
+		return 0; /* Led not present */
+
+	led->asus = asus;
+	led->method = method;
+
+	INIT_WORK(&led->work, asus_led_cdev_update);
+	led_cdev->name = name;
+	led_cdev->brightness_set = asus_led_cdev_set;
+	led_cdev->brightness_get = asus_led_cdev_get;
+	led_cdev->max_brightness = 1;
+	return led_classdev_register(&asus->platform_device->dev, led_cdev);
+}
+
+static int asus_led_init(struct asus_laptop *asus)
+{
+	int r;
+
+	/*
+	 * Functions that actually update the LED's are called from a
+	 * workqueue. By doing this as separate work rather than when the LED
+	 * subsystem asks, we avoid messing with the Asus ACPI stuff during a
+	 * potentially bad time, such as a timer interrupt.
+	 */
+	asus->led_workqueue = create_singlethread_workqueue("led_workqueue");
+	if (!asus->led_workqueue)
+		return -ENOMEM;
+
+	r = asus_led_register(asus, &asus->mled, "asus::mail", METHOD_MLED);
+	if (r)
+		goto error;
+	r = asus_led_register(asus, &asus->tled, "asus::touchpad", METHOD_TLED);
+	if (r)
+		goto error;
+	r = asus_led_register(asus, &asus->rled, "asus::record", METHOD_RLED);
+	if (r)
+		goto error;
+	r = asus_led_register(asus, &asus->pled, "asus::phone", METHOD_PLED);
+	if (r)
+		goto error;
+	r = asus_led_register(asus, &asus->gled, "asus::gaming", METHOD_GLED);
+	if (r)
+		goto error;
+	if (!acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_SET, NULL) &&
+	    !acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_GET, NULL)) {
+		struct asus_led *led = &asus->kled;
+		struct led_classdev *cdev = &led->led;
+
+		led->asus = asus;
+
+		INIT_WORK(&led->work, asus_kled_cdev_update);
+		cdev->name = "asus::kbd_backlight";
+		cdev->brightness_set = asus_kled_cdev_set;
+		cdev->brightness_get = asus_kled_cdev_get;
+		cdev->max_brightness = 3;
+		r = led_classdev_register(&asus->platform_device->dev, cdev);
+	}
+error:
+	if (r)
+		asus_led_exit(asus);
+	return r;
+}
+
+/*
+ * Backlight device
+ */
+static int asus_lcd_status(struct asus_laptop *asus)
+{
+	return asus->lcd_state;
+}
+
+static int asus_lcd_set(struct asus_laptop *asus, int value)
 {
 	int lcd = 0;
 	acpi_status status = 0;
 
-	lcd = value ? 1 : 0;
+	lcd = !!value;
 
-	if (lcd == get_lcd_state())
+	if (lcd == asus_lcd_status(asus))
 		return 0;
 
-	if (lcd_switch_handle) {
-		status = acpi_evaluate_object(lcd_switch_handle,
-					      NULL, NULL, NULL);
+	if (!lcd_switch_handle)
+		return -ENODEV;
 
-		if (ACPI_FAILURE(status))
-			pr_warning("Error switching LCD\n");
+	status = acpi_evaluate_object(lcd_switch_handle,
+				      NULL, NULL, NULL);
+
+	if (ACPI_FAILURE(status)) {
+		pr_warning("Error switching LCD\n");
+		return -ENODEV;
 	}
 
-	write_status(NULL, lcd, LCD_ON);
+	asus->lcd_state = lcd;
 	return 0;
 }
 
-static void lcd_blank(int blank)
+static void lcd_blank(struct asus_laptop *asus, int blank)
 {
-	struct backlight_device *bd = asus_backlight_device;
+	struct backlight_device *bd = asus->backlight_device;
+
+	asus->lcd_state = (blank == FB_BLANK_UNBLANK);
 
 	if (bd) {
 		bd->props.power = blank;
@@ -544,44 +582,94 @@ static void lcd_blank(int blank)
 	}
 }
 
-static int read_brightness(struct backlight_device *bd)
+static int asus_read_brightness(struct backlight_device *bd)
 {
+	struct asus_laptop *asus = bl_get_data(bd);
 	unsigned long long value;
 	acpi_status rv = AE_OK;
 
-	rv = acpi_evaluate_integer(brightness_get_handle, NULL, NULL, &value);
+	rv = acpi_evaluate_integer(asus->handle, METHOD_BRIGHTNESS_GET,
+				   NULL, &value);
 	if (ACPI_FAILURE(rv))
 		pr_warning("Error reading brightness\n");
 
 	return value;
 }
 
-static int set_brightness(struct backlight_device *bd, int value)
+static int asus_set_brightness(struct backlight_device *bd, int value)
 {
-	int ret = 0;
-
-	value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
-	/* 0 <= value <= 15 */
+	struct asus_laptop *asus = bl_get_data(bd);
 
-	if (write_acpi_int(brightness_set_handle, NULL, value, NULL)) {
+	if (write_acpi_int(asus->handle, METHOD_BRIGHTNESS_SET, value)) {
 		pr_warning("Error changing brightness\n");
-		ret = -EIO;
+		return -EIO;
 	}
-
-	return ret;
+	return 0;
 }
 
 static int update_bl_status(struct backlight_device *bd)
 {
+	struct asus_laptop *asus = bl_get_data(bd);
 	int rv;
 	int value = bd->props.brightness;
 
-	rv = set_brightness(bd, value);
+	rv = asus_set_brightness(bd, value);
 	if (rv)
 		return rv;
 
 	value = (bd->props.power == FB_BLANK_UNBLANK) ? 1 : 0;
-	return set_lcd_state(value);
+	return asus_lcd_set(asus, value);
+}
+
+static struct backlight_ops asusbl_ops = {
+	.get_brightness = asus_read_brightness,
+	.update_status = update_bl_status,
+};
+
+static int asus_backlight_notify(struct asus_laptop *asus)
+{
+	struct backlight_device *bd = asus->backlight_device;
+	int old = bd->props.brightness;
+
+	backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
+
+	return old;
+}
+
+static int asus_backlight_init(struct asus_laptop *asus)
+{
+	struct backlight_device *bd;
+	struct device *dev = &asus->platform_device->dev;
+	struct backlight_properties props;
+
+	if (!acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_GET, NULL) &&
+	    !acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL) &&
+	    lcd_switch_handle) {
+		memset(&props, 0, sizeof(struct backlight_properties));
+		props.max_brightness = 15;
+
+		bd = backlight_device_register(ASUS_LAPTOP_FILE, dev,
+					       asus, &asusbl_ops, &props);
+		if (IS_ERR(bd)) {
+			pr_err("Could not register asus backlight device\n");
+			asus->backlight_device = NULL;
+			return PTR_ERR(bd);
+		}
+
+		asus->backlight_device = bd;
+
+		bd->props.power = FB_BLANK_UNBLANK;
+		bd->props.brightness = asus_read_brightness(bd);
+		backlight_update_status(bd);
+	}
+	return 0;
+}
+
+static void asus_backlight_exit(struct asus_laptop *asus)
+{
+	if (asus->backlight_device)
+		backlight_device_unregister(asus->backlight_device);
+	asus->backlight_device = NULL;
 }
 
 /*
@@ -596,25 +684,26 @@ static int update_bl_status(struct backl
 static ssize_t show_infos(struct device *dev,
 			  struct device_attribute *attr, char *page)
 {
+	struct asus_laptop *asus = dev_get_drvdata(dev);
 	int len = 0;
 	unsigned long long temp;
 	char buf[16];		/* enough for all info */
 	acpi_status rv = AE_OK;
 
 	/*
-	 * We use the easy way, we don't care of off and count, so we don't set eof
-	 * to 1
+	 * We use the easy way, we don't care of off and count,
+	 * so we don't set eof to 1
 	 */
 
-	len += sprintf(page, ASUS_HOTK_NAME " " ASUS_LAPTOP_VERSION "\n");
-	len += sprintf(page + len, "Model reference    : %s\n", hotk->name);
+	len += sprintf(page, ASUS_LAPTOP_NAME " " ASUS_LAPTOP_VERSION "\n");
+	len += sprintf(page + len, "Model reference    : %s\n", asus->name);
 	/*
 	 * The SFUN method probably allows the original driver to get the list
 	 * of features supported by a given model. For now, 0x0100 or 0x0800
 	 * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
 	 * The significance of others is yet to be found.
 	 */
-	rv = acpi_evaluate_integer(hotk->handle, "SFUN", NULL, &temp);
+	rv = acpi_evaluate_integer(asus->handle, "SFUN", NULL, &temp);
 	if (!ACPI_FAILURE(rv))
 		len += sprintf(page + len, "SFUN value         : %#x\n",
 			       (uint) temp);
@@ -624,7 +713,7 @@ static ssize_t show_infos(struct device
 	 * The significance of others is yet to be found.
 	 * If we don't find the method, we assume the device are present.
 	 */
-	rv = acpi_evaluate_integer(hotk->handle, "HRWS", NULL, &temp);
+	rv = acpi_evaluate_integer(asus->handle, "HRWS", NULL, &temp);
 	if (!ACPI_FAILURE(rv))
 		len += sprintf(page + len, "HRWS value         : %#x\n",
 			       (uint) temp);
@@ -635,26 +724,26 @@ static ssize_t show_infos(struct device
 	 * Note: since not all the laptops provide this method, errors are
 	 * silently ignored.
 	 */
-	rv = acpi_evaluate_integer(hotk->handle, "ASYM", NULL, &temp);
+	rv = acpi_evaluate_integer(asus->handle, "ASYM", NULL, &temp);
 	if (!ACPI_FAILURE(rv))
 		len += sprintf(page + len, "ASYM value         : %#x\n",
 			       (uint) temp);
-	if (asus_info) {
-		snprintf(buf, 16, "%d", asus_info->length);
+	if (asus->dsdt_info) {
+		snprintf(buf, 16, "%d", asus->dsdt_info->length);
 		len += sprintf(page + len, "DSDT length        : %s\n", buf);
-		snprintf(buf, 16, "%d", asus_info->checksum);
+		snprintf(buf, 16, "%d", asus->dsdt_info->checksum);
 		len += sprintf(page + len, "DSDT checksum      : %s\n", buf);
-		snprintf(buf, 16, "%d", asus_info->revision);
+		snprintf(buf, 16, "%d", asus->dsdt_info->revision);
 		len += sprintf(page + len, "DSDT revision      : %s\n", buf);
-		snprintf(buf, 7, "%s", asus_info->oem_id);
+		snprintf(buf, 7, "%s", asus->dsdt_info->oem_id);
 		len += sprintf(page + len, "OEM id             : %s\n", buf);
-		snprintf(buf, 9, "%s", asus_info->oem_table_id);
+		snprintf(buf, 9, "%s", asus->dsdt_info->oem_table_id);
 		len += sprintf(page + len, "OEM table id       : %s\n", buf);
-		snprintf(buf, 16, "%x", asus_info->oem_revision);
+		snprintf(buf, 16, "%x", asus->dsdt_info->oem_revision);
 		len += sprintf(page + len, "OEM revision       : 0x%s\n", buf);
-		snprintf(buf, 5, "%s", asus_info->asl_compiler_id);
+		snprintf(buf, 5, "%s", asus->dsdt_info->asl_compiler_id);
 		len += sprintf(page + len, "ASL comp vendor id : %s\n", buf);
-		snprintf(buf, 16, "%x", asus_info->asl_compiler_revision);
+		snprintf(buf, 16, "%x", asus->dsdt_info->asl_compiler_revision);
 		len += sprintf(page + len, "ASL comp revision  : 0x%s\n", buf);
 	}
 
@@ -672,8 +761,9 @@ static int parse_arg(const char *buf, un
 	return count;
 }
 
-static ssize_t store_status(const char *buf, size_t count,
-			    acpi_handle handle, int mask)
+static ssize_t sysfs_acpi_set(struct asus_laptop *asus,
+			      const char *buf, size_t count,
+			      const char *method)
 {
 	int rv, value;
 	int out = 0;
@@ -682,8 +772,8 @@ static ssize_t store_status(const char *
 	if (rv > 0)
 		out = value ? 1 : 0;
 
-	write_status(handle, out, mask);
-
+	if (write_acpi_int(asus->handle, method, value))
+		return -ENODEV;
 	return rv;
 }
 
@@ -693,67 +783,116 @@ static ssize_t store_status(const char *
 static ssize_t show_ledd(struct device *dev,
 			 struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "0x%08x\n", hotk->ledd_status);
+	struct asus_laptop *asus = dev_get_drvdata(dev);
+
+	return sprintf(buf, "0x%08x\n", asus->ledd_status);
 }
 
 static ssize_t store_ledd(struct device *dev, struct device_attribute *attr,
 			  const char *buf, size_t count)
 {
+	struct asus_laptop *asus = dev_get_drvdata(dev);
 	int rv, value;
 
 	rv = parse_arg(buf, count, &value);
 	if (rv > 0) {
-		if (write_acpi_int(ledd_set_handle, NULL, value, NULL))
+		if (write_acpi_int(asus->handle, METHOD_LEDD, value))
 			pr_warning("LED display write failed\n");
 		else
-			hotk->ledd_status = (u32) value;
+			asus->ledd_status = (u32) value;
 	}
 	return rv;
 }
 
 /*
+ * Wireless
+ */
+static int asus_wireless_status(struct asus_laptop *asus, int mask)
+{
+	unsigned long long status;
+	acpi_status rv = AE_OK;
+
+	if (!asus->have_rsts)
+		return (asus->wireless_status & mask) ? 1 : 0;
+
+	rv = acpi_evaluate_integer(asus->handle, METHOD_WL_STATUS,
+				   NULL, &status);
+	if (ACPI_FAILURE(rv)) {
+		pr_warning("Error reading Wireless status\n");
+		return -EINVAL;
+	}
+	return !!(status & mask);
+}
+
+/*
  * WLAN
  */
+static int asus_wlan_set(struct asus_laptop *asus, int status)
+{
+	if (write_acpi_int(asus->handle, METHOD_WLAN, !!status)) {
+		pr_warning("Error setting wlan status to %d", status);
+		return -EIO;
+	}
+	return 0;
+}
+
 static ssize_t show_wlan(struct device *dev,
 			 struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%d\n", read_status(WL_ON));
+	struct asus_laptop *asus = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", asus_wireless_status(asus, WL_RSTS));
 }
 
 static ssize_t store_wlan(struct device *dev, struct device_attribute *attr,
 			  const char *buf, size_t count)
 {
-	return store_status(buf, count, wl_switch_handle, WL_ON);
+	struct asus_laptop *asus = dev_get_drvdata(dev);
+
+	return sysfs_acpi_set(asus, buf, count, METHOD_WLAN);
 }
 
 /*
  * Bluetooth
  */
+static int asus_bluetooth_set(struct asus_laptop *asus, int status)
+{
+	if (write_acpi_int(asus->handle, METHOD_BLUETOOTH, !!status)) {
+		pr_warning("Error setting bluetooth status to %d", status);
+		return -EIO;
+	}
+	return 0;
+}
+
 static ssize_t show_bluetooth(struct device *dev,
 			      struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%d\n", read_status(BT_ON));
+	struct asus_laptop *asus = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", asus_wireless_status(asus, BT_RSTS));
 }
 
 static ssize_t store_bluetooth(struct device *dev,
 			       struct device_attribute *attr, const char *buf,
 			       size_t count)
 {
-	return store_status(buf, count, bt_switch_handle, BT_ON);
+	struct asus_laptop *asus = dev_get_drvdata(dev);
+
+	return sysfs_acpi_set(asus, buf, count, METHOD_BLUETOOTH);
 }
 
 /*
  * Display
  */
-static void set_display(int value)
+static void asus_set_display(struct asus_laptop *asus, int value)
 {
 	/* no sanity check needed for now */
-	if (write_acpi_int(display_set_handle, NULL, value, NULL))
+	if (write_acpi_int(asus->handle, METHOD_SWITCH_DISPLAY, value))
 		pr_warning("Error setting display\n");
 	return;
 }
 
-static int read_display(void)
+static int read_display(struct asus_laptop *asus)
 {
 	unsigned long long value = 0;
 	acpi_status rv = AE_OK;
@@ -769,7 +908,7 @@ static int read_display(void)
 			pr_warning("Error reading display status\n");
 	}
 
-	value &= 0x0F;		/* needed for some models, shouldn't hurt others */
+	value &= 0x0F; /* needed for some models, shouldn't hurt others */
 
 	return value;
 }
@@ -781,7 +920,11 @@ static int read_display(void)
 static ssize_t show_disp(struct device *dev,
 			 struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%d\n", read_display());
+	struct asus_laptop *asus = dev_get_drvdata(dev);
+
+	if (!display_get_handle)
+		return -ENODEV;
+	return sprintf(buf, "%d\n", read_display(asus));
 }
 
 /*
@@ -794,65 +937,72 @@ static ssize_t show_disp(struct device *
 static ssize_t store_disp(struct device *dev, struct device_attribute *attr,
 			  const char *buf, size_t count)
 {
+	struct asus_laptop *asus = dev_get_drvdata(dev);
 	int rv, value;
 
 	rv = parse_arg(buf, count, &value);
 	if (rv > 0)
-		set_display(value);
+		asus_set_display(asus, value);
 	return rv;
 }
 
 /*
  * Light Sens
  */
-static void set_light_sens_switch(int value)
+static void asus_als_switch(struct asus_laptop *asus, int value)
 {
-	if (write_acpi_int(ls_switch_handle, NULL, value, NULL))
+	if (write_acpi_int(asus->handle, METHOD_ALS_CONTROL, value))
 		pr_warning("Error setting light sensor switch\n");
-	hotk->light_switch = value;
+	asus->light_switch = value;
 }
 
 static ssize_t show_lssw(struct device *dev,
 			 struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%d\n", hotk->light_switch);
+	struct asus_laptop *asus = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", asus->light_switch);
 }
 
 static ssize_t store_lssw(struct device *dev, struct device_attribute *attr,
 			  const char *buf, size_t count)
 {
+	struct asus_laptop *asus = dev_get_drvdata(dev);
 	int rv, value;
 
 	rv = parse_arg(buf, count, &value);
 	if (rv > 0)
-		set_light_sens_switch(value ? 1 : 0);
+		asus_als_switch(asus, value ? 1 : 0);
 
 	return rv;
 }
 
-static void set_light_sens_level(int value)
+static void asus_als_level(struct asus_laptop *asus, int value)
 {
-	if (write_acpi_int(ls_level_handle, NULL, value, NULL))
+	if (write_acpi_int(asus->handle, METHOD_ALS_LEVEL, value))
 		pr_warning("Error setting light sensor level\n");
-	hotk->light_level = value;
+	asus->light_level = value;
 }
 
 static ssize_t show_lslvl(struct device *dev,
 			  struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%d\n", hotk->light_level);
+	struct asus_laptop *asus = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", asus->light_level);
 }
 
 static ssize_t store_lslvl(struct device *dev, struct device_attribute *attr,
 			   const char *buf, size_t count)
 {
+	struct asus_laptop *asus = dev_get_drvdata(dev);
 	int rv, value;
 
 	rv = parse_arg(buf, count, &value);
 	if (rv > 0) {
 		value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
 		/* 0 <= value <= 15 */
-		set_light_sens_level(value);
+		asus_als_level(asus, value);
 	}
 
 	return rv;
@@ -861,197 +1011,309 @@ static ssize_t store_lslvl(struct device
 /*
  * GPS
  */
+static int asus_gps_status(struct asus_laptop *asus)
+{
+	unsigned long long status;
+	acpi_status rv = AE_OK;
+
+	rv = acpi_evaluate_integer(asus->handle, METHOD_GPS_STATUS,
+				   NULL, &status);
+	if (ACPI_FAILURE(rv)) {
+		pr_warning("Error reading GPS status\n");
+		return -ENODEV;
+	}
+	return !!status;
+}
+
+static int asus_gps_switch(struct asus_laptop *asus, int status)
+{
+	const char *meth = status ? METHOD_GPS_ON : METHOD_GPS_OFF;
+
+	if (write_acpi_int(asus->handle, meth, 0x02))
+		return -ENODEV;
+	return 0;
+}
+
 static ssize_t show_gps(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%d\n", read_status(GPS_ON));
+	struct asus_laptop *asus = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", asus_gps_status(asus));
 }
 
 static ssize_t store_gps(struct device *dev, struct device_attribute *attr,
 			 const char *buf, size_t count)
 {
-	return store_status(buf, count, NULL, GPS_ON);
+	struct asus_laptop *asus = dev_get_drvdata(dev);
+	int rv, value;
+	int ret;
+
+	rv = parse_arg(buf, count, &value);
+	if (rv <= 0)
+		return -EINVAL;
+	ret = asus_gps_switch(asus, !!value);
+	if (ret)
+		return ret;
+	rfkill_set_sw_state(asus->gps_rfkill, !value);
+	return rv;
 }
 
 /*
- * Hotkey functions
+ * rfkill
  */
-static struct key_entry *asus_get_entry_by_scancode(int code)
+static int asus_gps_rfkill_set(void *data, bool blocked)
 {
-	struct key_entry *key;
-
-	for (key = asus_keymap; key->type != KE_END; key++)
-		if (code == key->code)
-			return key;
+	acpi_handle handle = data;
 
-	return NULL;
+	return asus_gps_switch(handle, !blocked);
 }
 
-static struct key_entry *asus_get_entry_by_keycode(int code)
-{
-	struct key_entry *key;
-
-	for (key = asus_keymap; key->type != KE_END; key++)
-		if (code == key->keycode && key->type == KE_KEY)
-			return key;
+static const struct rfkill_ops asus_gps_rfkill_ops = {
+	.set_block = asus_gps_rfkill_set,
+};
 
-	return NULL;
+static void asus_rfkill_exit(struct asus_laptop *asus)
+{
+	if (asus->gps_rfkill) {
+		rfkill_unregister(asus->gps_rfkill);
+		rfkill_destroy(asus->gps_rfkill);
+		asus->gps_rfkill = NULL;
+	}
 }
 
-static int asus_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static int asus_rfkill_init(struct asus_laptop *asus)
 {
-	struct key_entry *key = asus_get_entry_by_scancode(scancode);
+	int result;
 
-	if (key && key->type == KE_KEY) {
-		*keycode = key->keycode;
+	if (acpi_check_handle(asus->handle, METHOD_GPS_ON, NULL) ||
+	    acpi_check_handle(asus->handle, METHOD_GPS_OFF, NULL) ||
+	    acpi_check_handle(asus->handle, METHOD_GPS_STATUS, NULL))
 		return 0;
+
+	asus->gps_rfkill = rfkill_alloc("asus-gps", &asus->platform_device->dev,
+					RFKILL_TYPE_GPS,
+					&asus_gps_rfkill_ops, NULL);
+	if (!asus->gps_rfkill)
+		return -EINVAL;
+
+	result = rfkill_register(asus->gps_rfkill);
+	if (result) {
+		rfkill_destroy(asus->gps_rfkill);
+		asus->gps_rfkill = NULL;
 	}
 
-	return -EINVAL;
+	return result;
 }
 
-static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode)
+/*
+ * Input device (i.e. hotkeys)
+ */
+static void asus_input_notify(struct asus_laptop *asus, int event)
 {
-	struct key_entry *key;
-	int old_keycode;
+	if (asus->inputdev)
+		sparse_keymap_report_event(asus->inputdev, event, 1, true);
+}
 
-	if (keycode < 0 || keycode > KEY_MAX)
-		return -EINVAL;
+static int asus_input_init(struct asus_laptop *asus)
+{
+	struct input_dev *input;
+	int error;
 
-	key = asus_get_entry_by_scancode(scancode);
-	if (key && key->type == KE_KEY) {
-		old_keycode = key->keycode;
-		key->keycode = keycode;
-		set_bit(keycode, dev->keybit);
-		if (!asus_get_entry_by_keycode(old_keycode))
-			clear_bit(old_keycode, dev->keybit);
+	input = input_allocate_device();
+	if (!input) {
+		pr_info("Unable to allocate input device\n");
 		return 0;
 	}
+	input->name = "Asus Laptop extra buttons";
+	input->phys = ASUS_LAPTOP_FILE "/input0";
+	input->id.bustype = BUS_HOST;
+	input->dev.parent = &asus->platform_device->dev;
+	input_set_drvdata(input, asus);
 
-	return -EINVAL;
+	error = sparse_keymap_setup(input, asus_keymap, NULL);
+	if (error) {
+		pr_err("Unable to setup input device keymap\n");
+		goto err_keymap;
+	}
+	error = input_register_device(input);
+	if (error) {
+		pr_info("Unable to register input device\n");
+		goto err_device;
+	}
+
+	asus->inputdev = input;
+	return 0;
+
+err_keymap:
+	sparse_keymap_free(input);
+err_device:
+	input_free_device(input);
+	return error;
 }
 
-static void asus_hotk_notify(struct acpi_device *device, u32 event)
+static void asus_input_exit(struct asus_laptop *asus)
 {
-	static struct key_entry *key;
-	u16 count;
+	if (asus->inputdev) {
+		sparse_keymap_free(asus->inputdev);
+		input_unregister_device(asus->inputdev);
+	}
+}
 
-	/* TODO Find a better way to handle events count. */
-	if (!hotk)
-		return;
+/*
+ * ACPI driver
+ */
+static void asus_acpi_notify(struct acpi_device *device, u32 event)
+{
+	struct asus_laptop *asus = acpi_driver_data(device);
+	u16 count;
 
 	/*
 	 * We need to tell the backlight device when the backlight power is
 	 * switched
 	 */
-	if (event == ATKD_LCD_ON) {
-		write_status(NULL, 1, LCD_ON);
-		lcd_blank(FB_BLANK_UNBLANK);
-	} else if (event == ATKD_LCD_OFF) {
-		write_status(NULL, 0, LCD_ON);
-		lcd_blank(FB_BLANK_POWERDOWN);
-	}
+	if (event == ATKD_LCD_ON)
+		lcd_blank(asus, FB_BLANK_UNBLANK);
+	else if (event == ATKD_LCD_OFF)
+		lcd_blank(asus, FB_BLANK_POWERDOWN);
 
-	count = hotk->event_count[event % 128]++;
-	acpi_bus_generate_proc_event(hotk->device, event, count);
-	acpi_bus_generate_netlink_event(hotk->device->pnp.device_class,
-					dev_name(&hotk->device->dev), event,
+	/* TODO Find a better way to handle events count. */
+	count = asus->event_count[event % 128]++;
+	acpi_bus_generate_proc_event(asus->device, event, count);
+	acpi_bus_generate_netlink_event(asus->device->pnp.device_class,
+					dev_name(&asus->device->dev), event,
 					count);
 
-	if (hotk->inputdev) {
-		key = asus_get_entry_by_scancode(event);
-		if (!key)
-			return ;
+	/* Brightness events are special */
+	if (event >= ATKD_BR_MIN && event <= ATKD_BR_MAX) {
 
-		switch (key->type) {
-		case KE_KEY:
-			input_report_key(hotk->inputdev, key->keycode, 1);
-			input_sync(hotk->inputdev);
-			input_report_key(hotk->inputdev, key->keycode, 0);
-			input_sync(hotk->inputdev);
-			break;
+		/* Ignore them completely if the acpi video driver is used */
+		if (asus->backlight_device != NULL) {
+			/* Update the backlight device. */
+			asus_backlight_notify(asus);
 		}
+		return ;
 	}
+	asus_input_notify(asus, event);
 }
 
-#define ASUS_CREATE_DEVICE_ATTR(_name)					\
-	struct device_attribute dev_attr_##_name = {			\
-		.attr = {						\
-			.name = __stringify(_name),			\
-			.mode = 0 },					\
-		.show   = NULL,						\
-		.store  = NULL,						\
+static DEVICE_ATTR(infos, S_IRUGO, show_infos, NULL);
+static DEVICE_ATTR(wlan, S_IRUGO | S_IWUSR, show_wlan, store_wlan);
+static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR, show_bluetooth,
+		   store_bluetooth);
+static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp);
+static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd);
+static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl);
+static DEVICE_ATTR(ls_switch, S_IRUGO | S_IWUSR, show_lssw, store_lssw);
+static DEVICE_ATTR(gps, S_IRUGO | S_IWUSR, show_gps, store_gps);
+
+static void asus_sysfs_exit(struct asus_laptop *asus)
+{
+	struct platform_device *device = asus->platform_device;
+
+	device_remove_file(&device->dev, &dev_attr_infos);
+	device_remove_file(&device->dev, &dev_attr_wlan);
+	device_remove_file(&device->dev, &dev_attr_bluetooth);
+	device_remove_file(&device->dev, &dev_attr_display);
+	device_remove_file(&device->dev, &dev_attr_ledd);
+	device_remove_file(&device->dev, &dev_attr_ls_switch);
+	device_remove_file(&device->dev, &dev_attr_ls_level);
+	device_remove_file(&device->dev, &dev_attr_gps);
+}
+
+static int asus_sysfs_init(struct asus_laptop *asus)
+{
+	struct platform_device *device = asus->platform_device;
+	int err;
+
+	err = device_create_file(&device->dev, &dev_attr_infos);
+	if (err)
+		return err;
+
+	if (!acpi_check_handle(asus->handle, METHOD_WLAN, NULL)) {
+		err = device_create_file(&device->dev, &dev_attr_wlan);
+		if (err)
+			return err;
 	}
 
-#define ASUS_SET_DEVICE_ATTR(_name, _mode, _show, _store)		\
-	do {								\
-		dev_attr_##_name.attr.mode = _mode;			\
-		dev_attr_##_name.show = _show;				\
-		dev_attr_##_name.store = _store;			\
-	} while(0)
+	if (!acpi_check_handle(asus->handle, METHOD_BLUETOOTH, NULL)) {
+		err = device_create_file(&device->dev, &dev_attr_bluetooth);
+		if (err)
+			return err;
+	}
 
-static ASUS_CREATE_DEVICE_ATTR(infos);
-static ASUS_CREATE_DEVICE_ATTR(wlan);
-static ASUS_CREATE_DEVICE_ATTR(bluetooth);
-static ASUS_CREATE_DEVICE_ATTR(display);
-static ASUS_CREATE_DEVICE_ATTR(ledd);
-static ASUS_CREATE_DEVICE_ATTR(ls_switch);
-static ASUS_CREATE_DEVICE_ATTR(ls_level);
-static ASUS_CREATE_DEVICE_ATTR(gps);
+	if (!acpi_check_handle(asus->handle, METHOD_SWITCH_DISPLAY, NULL)) {
+		err = device_create_file(&device->dev, &dev_attr_display);
+		if (err)
+			return err;
+	}
 
-static struct attribute *asuspf_attributes[] = {
-	&dev_attr_infos.attr,
-	&dev_attr_wlan.attr,
-	&dev_attr_bluetooth.attr,
-	&dev_attr_display.attr,
-	&dev_attr_ledd.attr,
-	&dev_attr_ls_switch.attr,
-	&dev_attr_ls_level.attr,
-	&dev_attr_gps.attr,
-	NULL
-};
+	if (!acpi_check_handle(asus->handle, METHOD_LEDD, NULL)) {
+		err = device_create_file(&device->dev, &dev_attr_ledd);
+		if (err)
+			return err;
+	}
 
-static struct attribute_group asuspf_attribute_group = {
-	.attrs = asuspf_attributes
-};
+	if (!acpi_check_handle(asus->handle, METHOD_ALS_CONTROL, NULL) &&
+	    !acpi_check_handle(asus->handle, METHOD_ALS_LEVEL, NULL)) {
+		err = device_create_file(&device->dev, &dev_attr_ls_switch);
+		if (err)
+			return err;
+		err = device_create_file(&device->dev, &dev_attr_ls_level);
+		if (err)
+			return err;
+	}
 
-static struct platform_driver asuspf_driver = {
-	.driver = {
-		   .name = ASUS_HOTK_FILE,
-		   .owner = THIS_MODULE,
-		   }
-};
+	if (!acpi_check_handle(asus->handle, METHOD_GPS_ON, NULL) &&
+	    !acpi_check_handle(asus->handle, METHOD_GPS_OFF, NULL) &&
+	    !acpi_check_handle(asus->handle, METHOD_GPS_STATUS, NULL)) {
+		err = device_create_file(&device->dev, &dev_attr_gps);
+		if (err)
+			return err;
+	}
 
-static struct platform_device *asuspf_device;
+	return err;
+}
 
-static void asus_hotk_add_fs(void)
+static int asus_platform_init(struct asus_laptop *asus)
 {
-	ASUS_SET_DEVICE_ATTR(infos, 0444, show_infos, NULL);
-
-	if (wl_switch_handle)
-		ASUS_SET_DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan);
+	int err;
 
-	if (bt_switch_handle)
-		ASUS_SET_DEVICE_ATTR(bluetooth, 0644,
-				     show_bluetooth, store_bluetooth);
+	asus->platform_device = platform_device_alloc(ASUS_LAPTOP_FILE, -1);
+	if (!asus->platform_device)
+		return -ENOMEM;
+	platform_set_drvdata(asus->platform_device, asus);
 
-	if (display_set_handle && display_get_handle)
-		ASUS_SET_DEVICE_ATTR(display, 0644, show_disp, store_disp);
-	else if (display_set_handle)
-		ASUS_SET_DEVICE_ATTR(display, 0200, NULL, store_disp);
+	err = platform_device_add(asus->platform_device);
+	if (err)
+		goto fail_platform_device;
 
-	if (ledd_set_handle)
-		ASUS_SET_DEVICE_ATTR(ledd, 0644, show_ledd, store_ledd);
+	err = asus_sysfs_init(asus);
+	if (err)
+		goto fail_sysfs;
+	return 0;
 
-	if (ls_switch_handle && ls_level_handle) {
-		ASUS_SET_DEVICE_ATTR(ls_level, 0644, show_lslvl, store_lslvl);
-		ASUS_SET_DEVICE_ATTR(ls_switch, 0644, show_lssw, store_lssw);
-	}
+fail_sysfs:
+	asus_sysfs_exit(asus);
+	platform_device_del(asus->platform_device);
+fail_platform_device:
+	platform_device_put(asus->platform_device);
+	return err;
+}
 
-	if (gps_status_handle && gps_on_handle && gps_off_handle)
-		ASUS_SET_DEVICE_ATTR(gps, 0644, show_gps, store_gps);
+static void asus_platform_exit(struct asus_laptop *asus)
+{
+	asus_sysfs_exit(asus);
+	platform_device_unregister(asus->platform_device);
 }
 
+static struct platform_driver platform_driver = {
+	.driver = {
+		.name = ASUS_LAPTOP_FILE,
+		.owner = THIS_MODULE,
+	}
+};
+
 static int asus_handle_init(char *name, acpi_handle * handle,
 			    char **paths, int num_paths)
 {
@@ -1073,10 +1335,11 @@ static int asus_handle_init(char *name,
 			 ARRAY_SIZE(object##_paths))
 
 /*
- * This function is used to initialize the hotk with right values. In this
- * method, we can make all the detection we want, and modify the hotk struct
+ * This function is used to initialize the context with right values. In this
+ * method, we can make all the detection we want, and modify the asus_laptop
+ * struct
  */
-static int asus_hotk_get_info(void)
+static int asus_laptop_get_info(struct asus_laptop *asus)
 {
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 	union acpi_object *model = NULL;
@@ -1089,22 +1352,21 @@ static int asus_hotk_get_info(void)
 	 * models, but late enough to allow acpi_bus_register_driver() to fail
 	 * before doing anything ACPI-specific. Should we encounter a machine,
 	 * which needs special handling (i.e. its hotkey device has a different
-	 * HID), this bit will be moved. A global variable asus_info contains
-	 * the DSDT header.
+	 * HID), this bit will be moved.
 	 */
-	status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info);
+	status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus->dsdt_info);
 	if (ACPI_FAILURE(status))
 		pr_warning("Couldn't get the DSDT table header\n");
 
 	/* We have to write 0 on init this far for all ASUS models */
-	if (write_acpi_int(hotk->handle, "INIT", 0, &buffer)) {
+	if (write_acpi_int_ret(asus->handle, "INIT", 0, &buffer)) {
 		pr_err("Hotkey initialization failed\n");
 		return -ENODEV;
 	}
 
 	/* This needs to be called for some laptops to init properly */
 	status =
-	    acpi_evaluate_integer(hotk->handle, "BSTS", NULL, &bsts_result);
+	    acpi_evaluate_integer(asus->handle, "BSTS", NULL, &bsts_result);
 	if (ACPI_FAILURE(status))
 		pr_warning("Error calling BSTS\n");
 	else if (bsts_result)
@@ -1112,8 +1374,8 @@ static int asus_hotk_get_info(void)
 		       (uint) bsts_result);
 
 	/* This too ... */
-	write_acpi_int(hotk->handle, "CWAP", wapf, NULL);
-
+	if (write_acpi_int(asus->handle, "CWAP", wapf))
+		pr_err("Error calling CWAP(%d)\n", wapf);
 	/*
 	 * Try to match the object returned by INIT to the specific model.
 	 * Handle every possible object (or the lack of thereof) the DSDT
@@ -1134,397 +1396,210 @@ static int asus_hotk_get_info(void)
 			break;
 		}
 	}
-	hotk->name = kstrdup(string, GFP_KERNEL);
-	if (!hotk->name)
+	asus->name = kstrdup(string, GFP_KERNEL);
+	if (!asus->name)
 		return -ENOMEM;
 
 	if (*string)
 		pr_notice("  %s model detected\n", string);
 
-	ASUS_HANDLE_INIT(mled_set);
-	ASUS_HANDLE_INIT(tled_set);
-	ASUS_HANDLE_INIT(rled_set);
-	ASUS_HANDLE_INIT(pled_set);
-	ASUS_HANDLE_INIT(gled_set);
-
-	ASUS_HANDLE_INIT(ledd_set);
-
-	ASUS_HANDLE_INIT(kled_set);
-	ASUS_HANDLE_INIT(kled_get);
-
 	/*
 	 * The HWRS method return informations about the hardware.
 	 * 0x80 bit is for WLAN, 0x100 for Bluetooth.
 	 * The significance of others is yet to be found.
-	 * If we don't find the method, we assume the device are present.
 	 */
 	status =
-	    acpi_evaluate_integer(hotk->handle, "HRWS", NULL, &hwrs_result);
-	if (ACPI_FAILURE(status))
-		hwrs_result = WL_HWRS | BT_HWRS;
-
-	if (hwrs_result & WL_HWRS)
-		ASUS_HANDLE_INIT(wl_switch);
-	if (hwrs_result & BT_HWRS)
-		ASUS_HANDLE_INIT(bt_switch);
-
-	ASUS_HANDLE_INIT(wireless_status);
+	    acpi_evaluate_integer(asus->handle, "HRWS", NULL, &hwrs_result);
+	if (!ACPI_FAILURE(status))
+		pr_notice("  HRWS returned %x", (int)hwrs_result);
 
-	ASUS_HANDLE_INIT(brightness_set);
-	ASUS_HANDLE_INIT(brightness_get);
+	if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL))
+		asus->have_rsts = true;
 
+	/* Scheduled for removal */
 	ASUS_HANDLE_INIT(lcd_switch);
-
-	ASUS_HANDLE_INIT(display_set);
 	ASUS_HANDLE_INIT(display_get);
 
-	/*
-	 * There is a lot of models with "ALSL", but a few get
-	 * a real light sens, so we need to check it.
-	 */
-	if (!ASUS_HANDLE_INIT(ls_switch))
-		ASUS_HANDLE_INIT(ls_level);
-
-	ASUS_HANDLE_INIT(gps_on);
-	ASUS_HANDLE_INIT(gps_off);
-	ASUS_HANDLE_INIT(gps_status);
-
 	kfree(model);
 
 	return AE_OK;
 }
 
-static int asus_input_init(void)
-{
-	const struct key_entry *key;
-	int result;
-
-	hotk->inputdev = input_allocate_device();
-	if (!hotk->inputdev) {
-		pr_info("Unable to allocate input device\n");
-		return 0;
-	}
-	hotk->inputdev->name = "Asus Laptop extra buttons";
-	hotk->inputdev->phys = ASUS_HOTK_FILE "/input0";
-	hotk->inputdev->id.bustype = BUS_HOST;
-	hotk->inputdev->getkeycode = asus_getkeycode;
-	hotk->inputdev->setkeycode = asus_setkeycode;
-
-	for (key = asus_keymap; key->type != KE_END; key++) {
-		switch (key->type) {
-		case KE_KEY:
-			set_bit(EV_KEY, hotk->inputdev->evbit);
-			set_bit(key->keycode, hotk->inputdev->keybit);
-			break;
-		}
-	}
-	result = input_register_device(hotk->inputdev);
-	if (result) {
-		pr_info("Unable to register input device\n");
-		input_free_device(hotk->inputdev);
-	}
-	return result;
-}
+static bool asus_device_present;
 
-static int asus_hotk_check(void)
+static int __devinit asus_acpi_init(struct asus_laptop *asus)
 {
 	int result = 0;
 
-	result = acpi_bus_get_status(hotk->device);
+	result = acpi_bus_get_status(asus->device);
 	if (result)
 		return result;
-
-	if (hotk->device->status.present) {
-		result = asus_hotk_get_info();
-	} else {
+	if (!asus->device->status.present) {
 		pr_err("Hotkey device not present, aborting\n");
-		return -EINVAL;
+		return -ENODEV;
 	}
 
-	return result;
-}
-
-static int asus_hotk_found;
-
-static int asus_hotk_add(struct acpi_device *device)
-{
-	int result;
-
-	pr_notice("Asus Laptop Support version %s\n",
-	       ASUS_LAPTOP_VERSION);
-
-	hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL);
-	if (!hotk)
-		return -ENOMEM;
-
-	hotk->handle = device->handle;
-	strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME);
-	strcpy(acpi_device_class(device), ASUS_HOTK_CLASS);
-	device->driver_data = hotk;
-	hotk->device = device;
-
-	result = asus_hotk_check();
+	result = asus_laptop_get_info(asus);
 	if (result)
-		goto end;
-
-	asus_hotk_add_fs();
-
-	asus_hotk_found = 1;
+		return result;
 
 	/* WLED and BLED are on by default */
-	write_status(bt_switch_handle, 1, BT_ON);
-	write_status(wl_switch_handle, 1, WL_ON);
-
-	/* If the h/w switch is off, we need to check the real status */
-	write_status(NULL, read_status(BT_ON), BT_ON);
-	write_status(NULL, read_status(WL_ON), WL_ON);
+	if (bluetooth_status >= 0)
+		asus_bluetooth_set(asus, !!bluetooth_status);
 
-	/* LCD Backlight is on by default */
-	write_status(NULL, 1, LCD_ON);
+	if (wlan_status >= 0)
+		asus_wlan_set(asus, !!wlan_status);
 
 	/* Keyboard Backlight is on by default */
-	if (kled_set_handle)
-		set_kled_lvl(1);
+	if (!acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_SET, NULL))
+		asus_kled_set(asus, 1);
 
 	/* LED display is off by default */
-	hotk->ledd_status = 0xFFF;
+	asus->ledd_status = 0xFFF;
 
 	/* Set initial values of light sensor and level */
-	hotk->light_switch = 0;	/* Default to light sensor disabled */
-	hotk->light_level = 5;	/* level 5 for sensor sensitivity */
-
-	if (ls_switch_handle)
-		set_light_sens_switch(hotk->light_switch);
-
-	if (ls_level_handle)
-		set_light_sens_level(hotk->light_level);
-
-	/* GPS is on by default */
-	write_status(NULL, 1, GPS_ON);
+	asus->light_switch = 0;	/* Default to light sensor disabled */
+	asus->light_level = 5;	/* level 5 for sensor sensitivity */
 
-end:
-	if (result) {
-		kfree(hotk->name);
-		kfree(hotk);
+	if (!acpi_check_handle(asus->handle, METHOD_ALS_CONTROL, NULL) &&
+	    !acpi_check_handle(asus->handle, METHOD_ALS_LEVEL, NULL)) {
+		asus_als_switch(asus, asus->light_switch);
+		asus_als_level(asus, asus->light_level);
 	}
 
+	asus->lcd_state = 1; /* LCD should be on when the module load */
 	return result;
 }
 
-static int asus_hotk_remove(struct acpi_device *device, int type)
-{
-	kfree(hotk->name);
-	kfree(hotk);
-
-	return 0;
-}
-
-static void asus_backlight_exit(void)
+static int __devinit asus_acpi_add(struct acpi_device *device)
 {
-	if (asus_backlight_device)
-		backlight_device_unregister(asus_backlight_device);
-}
-
-#define  ASUS_LED_UNREGISTER(object)				\
-	if (object##_led.dev)					\
-		led_classdev_unregister(&object##_led)
+	struct asus_laptop *asus;
+	int result;
 
-static void asus_led_exit(void)
-{
-	destroy_workqueue(led_workqueue);
-	ASUS_LED_UNREGISTER(mled);
-	ASUS_LED_UNREGISTER(tled);
-	ASUS_LED_UNREGISTER(pled);
-	ASUS_LED_UNREGISTER(rled);
-	ASUS_LED_UNREGISTER(gled);
-	ASUS_LED_UNREGISTER(kled);
-}
+	pr_notice("Asus Laptop Support version %s\n",
+		  ASUS_LAPTOP_VERSION);
+	asus = kzalloc(sizeof(struct asus_laptop), GFP_KERNEL);
+	if (!asus)
+		return -ENOMEM;
+	asus->handle = device->handle;
+	strcpy(acpi_device_name(device), ASUS_LAPTOP_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ASUS_LAPTOP_CLASS);
+	device->driver_data = asus;
+	asus->device = device;
 
-static void asus_input_exit(void)
-{
-	if (hotk->inputdev)
-		input_unregister_device(hotk->inputdev);
-}
+	result = asus_acpi_init(asus);
+	if (result)
+		goto fail_platform;
 
-static void __exit asus_laptop_exit(void)
-{
-	asus_backlight_exit();
-	asus_led_exit();
-	asus_input_exit();
+	/*
+	 * Register the platform device first.  It is used as a parent for the
+	 * sub-devices below.
+	 */
+	result = asus_platform_init(asus);
+	if (result)
+		goto fail_platform;
 
-	acpi_bus_unregister_driver(&asus_hotk_driver);
-	sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group);
-	platform_device_unregister(asuspf_device);
-	platform_driver_unregister(&asuspf_driver);
-}
+	if (!acpi_video_backlight_support()) {
+		result = asus_backlight_init(asus);
+		if (result)
+			goto fail_backlight;
+	} else
+		pr_info("Backlight controlled by ACPI video driver\n");
 
-static int asus_backlight_init(struct device *dev)
-{
-	struct backlight_device *bd;
+	result = asus_input_init(asus);
+	if (result)
+		goto fail_input;
 
-	if (brightness_set_handle && lcd_switch_handle) {
-		bd = backlight_device_register(ASUS_HOTK_FILE, dev,
-					       NULL, &asusbl_ops);
-		if (IS_ERR(bd)) {
-			pr_err("Could not register asus backlight device\n");
-			asus_backlight_device = NULL;
-			return PTR_ERR(bd);
-		}
+	result = asus_led_init(asus);
+	if (result)
+		goto fail_led;
 
-		asus_backlight_device = bd;
+	result = asus_rfkill_init(asus);
+	if (result)
+		goto fail_rfkill;
 
-		bd->props.max_brightness = 15;
-		bd->props.brightness = read_brightness(NULL);
-		bd->props.power = FB_BLANK_UNBLANK;
-		backlight_update_status(bd);
-	}
+	asus_device_present = true;
 	return 0;
-}
 
-static int asus_led_register(acpi_handle handle,
-			     struct led_classdev *ldev, struct device *dev)
-{
-	if (!handle)
-		return 0;
+fail_rfkill:
+	asus_led_exit(asus);
+fail_led:
+	asus_input_exit(asus);
+fail_input:
+	asus_backlight_exit(asus);
+fail_backlight:
+	asus_platform_exit(asus);
+fail_platform:
+	kfree(asus->name);
+	kfree(asus);
 
-	return led_classdev_register(dev, ldev);
+	return result;
 }
 
-#define ASUS_LED_REGISTER(object, device)				\
-	asus_led_register(object##_set_handle, &object##_led, device)
-
-static int asus_led_init(struct device *dev)
+static int asus_acpi_remove(struct acpi_device *device, int type)
 {
-	int rv;
-
-	rv = ASUS_LED_REGISTER(mled, dev);
-	if (rv)
-		goto out;
-
-	rv = ASUS_LED_REGISTER(tled, dev);
-	if (rv)
-		goto out1;
-
-	rv = ASUS_LED_REGISTER(rled, dev);
-	if (rv)
-		goto out2;
-
-	rv = ASUS_LED_REGISTER(pled, dev);
-	if (rv)
-		goto out3;
-
-	rv = ASUS_LED_REGISTER(gled, dev);
-	if (rv)
-		goto out4;
-
-	if (kled_set_handle && kled_get_handle)
-		rv = ASUS_LED_REGISTER(kled, dev);
-	if (rv)
-		goto out5;
+	struct asus_laptop *asus = acpi_driver_data(device);
 
-	led_workqueue = create_singlethread_workqueue("led_workqueue");
-	if (!led_workqueue)
-		goto out6;
+	asus_backlight_exit(asus);
+	asus_rfkill_exit(asus);
+	asus_led_exit(asus);
+	asus_input_exit(asus);
+	asus_platform_exit(asus);
 
+	kfree(asus->name);
+	kfree(asus);
 	return 0;
-out6:
-	rv = -ENOMEM;
-	ASUS_LED_UNREGISTER(kled);
-out5:
-	ASUS_LED_UNREGISTER(gled);
-out4:
-	ASUS_LED_UNREGISTER(pled);
-out3:
-	ASUS_LED_UNREGISTER(rled);
-out2:
-	ASUS_LED_UNREGISTER(tled);
-out1:
-	ASUS_LED_UNREGISTER(mled);
-out:
-	return rv;
 }
 
+static const struct acpi_device_id asus_device_ids[] = {
+	{"ATK0100", 0},
+	{"ATK0101", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, asus_device_ids);
+
+static struct acpi_driver asus_acpi_driver = {
+	.name = ASUS_LAPTOP_NAME,
+	.class = ASUS_LAPTOP_CLASS,
+	.owner = THIS_MODULE,
+	.ids = asus_device_ids,
+	.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
+	.ops = {
+		.add = asus_acpi_add,
+		.remove = asus_acpi_remove,
+		.notify = asus_acpi_notify,
+		},
+};
+
 static int __init asus_laptop_init(void)
 {
 	int result;
 
-	result = acpi_bus_register_driver(&asus_hotk_driver);
+	result = platform_driver_register(&platform_driver);
 	if (result < 0)
 		return result;
 
-	/*
-	 * This is a bit of a kludge.  We only want this module loaded
-	 * for ASUS systems, but there's currently no way to probe the
-	 * ACPI namespace for ASUS HIDs.  So we just return failure if
-	 * we didn't find one, which will cause the module to be
-	 * unloaded.
-	 */
-	if (!asus_hotk_found) {
-		acpi_bus_unregister_driver(&asus_hotk_driver);
-		return -ENODEV;
-	}
-
-	result = asus_input_init();
-	if (result)
-		goto fail_input;
-
-	/* Register platform stuff */
-	result = platform_driver_register(&asuspf_driver);
-	if (result)
-		goto fail_platform_driver;
-
-	asuspf_device = platform_device_alloc(ASUS_HOTK_FILE, -1);
-	if (!asuspf_device) {
-		result = -ENOMEM;
-		goto fail_platform_device1;
+	result = acpi_bus_register_driver(&asus_acpi_driver);
+	if (result < 0)
+		goto fail_acpi_driver;
+	if (!asus_device_present) {
+		result = -ENODEV;
+		goto fail_no_device;
 	}
-
-	result = platform_device_add(asuspf_device);
-	if (result)
-		goto fail_platform_device2;
-
-	result = sysfs_create_group(&asuspf_device->dev.kobj,
-				    &asuspf_attribute_group);
-	if (result)
-		goto fail_sysfs;
-
-	result = asus_led_init(&asuspf_device->dev);
-	if (result)
-		goto fail_led;
-
-	if (!acpi_video_backlight_support()) {
-		result = asus_backlight_init(&asuspf_device->dev);
-		if (result)
-			goto fail_backlight;
-	} else
-		pr_info("Brightness ignored, must be controlled by "
-		       "ACPI video driver\n");
-
 	return 0;
 
-fail_backlight:
-       asus_led_exit();
-
-fail_led:
-       sysfs_remove_group(&asuspf_device->dev.kobj,
-			  &asuspf_attribute_group);
-
-fail_sysfs:
-	platform_device_del(asuspf_device);
-
-fail_platform_device2:
-	platform_device_put(asuspf_device);
-
-fail_platform_device1:
-	platform_driver_unregister(&asuspf_driver);
-
-fail_platform_driver:
-	asus_input_exit();
-
-fail_input:
-
+fail_no_device:
+	acpi_bus_unregister_driver(&asus_acpi_driver);
+fail_acpi_driver:
+	platform_driver_unregister(&platform_driver);
 	return result;
 }
 
+static void __exit asus_laptop_exit(void)
+{
+	acpi_bus_unregister_driver(&asus_acpi_driver);
+	platform_driver_unregister(&platform_driver);
+}
+
 module_init(asus_laptop_init);
 module_exit(asus_laptop_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/classmate-laptop.c linux-libre-2.6.34-gnu1/drivers/platform/x86/classmate-laptop.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/classmate-laptop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/classmate-laptop.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <acpi/acpi_drivers.h>
 #include <linux/backlight.h>
@@ -34,6 +35,11 @@ struct cmpc_accel {
 #define CMPC_ACCEL_SENSITIVITY_DEFAULT		5
 
 
+#define CMPC_ACCEL_HID		"ACCE0000"
+#define CMPC_TABLET_HID		"TBLT0000"
+#define CMPC_BL_HID		"IPML200"
+#define CMPC_KEYS_HID		"FnBT0000"
+
 /*
  * Generic input device code.
  */
@@ -282,10 +288,9 @@ static int cmpc_accel_remove(struct acpi
 }
 
 static const struct acpi_device_id cmpc_accel_device_ids[] = {
-	{"ACCE0000", 0},
+	{CMPC_ACCEL_HID, 0},
 	{"", 0}
 };
-MODULE_DEVICE_TABLE(acpi, cmpc_accel_device_ids);
 
 static struct acpi_driver cmpc_accel_acpi_driver = {
 	.owner = THIS_MODULE,
@@ -366,10 +371,9 @@ static int cmpc_tablet_resume(struct acp
 }
 
 static const struct acpi_device_id cmpc_tablet_device_ids[] = {
-	{"TBLT0000", 0},
+	{CMPC_TABLET_HID, 0},
 	{"", 0}
 };
-MODULE_DEVICE_TABLE(acpi, cmpc_tablet_device_ids);
 
 static struct acpi_driver cmpc_tablet_acpi_driver = {
 	.owner = THIS_MODULE,
@@ -452,18 +456,22 @@ static int cmpc_bl_update_status(struct
 		return -1;
 }
 
-static struct backlight_ops cmpc_bl_ops = {
+static const struct backlight_ops cmpc_bl_ops = {
 	.get_brightness = cmpc_bl_get_brightness,
 	.update_status = cmpc_bl_update_status
 };
 
 static int cmpc_bl_add(struct acpi_device *acpi)
 {
+	struct backlight_properties props;
 	struct backlight_device *bd;
 
-	bd = backlight_device_register("cmpc_bl", &acpi->dev,
-				       acpi->handle, &cmpc_bl_ops);
-	bd->props.max_brightness = 7;
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = 7;
+	bd = backlight_device_register("cmpc_bl", &acpi->dev, acpi->handle,
+				       &cmpc_bl_ops, &props);
+	if (IS_ERR(bd))
+		return PTR_ERR(bd);
 	dev_set_drvdata(&acpi->dev, bd);
 	return 0;
 }
@@ -477,17 +485,16 @@ static int cmpc_bl_remove(struct acpi_de
 	return 0;
 }
 
-static const struct acpi_device_id cmpc_device_ids[] = {
-	{"IPML200", 0},
+static const struct acpi_device_id cmpc_bl_device_ids[] = {
+	{CMPC_BL_HID, 0},
 	{"", 0}
 };
-MODULE_DEVICE_TABLE(acpi, cmpc_device_ids);
 
 static struct acpi_driver cmpc_bl_acpi_driver = {
 	.owner = THIS_MODULE,
 	.name = "cmpc",
 	.class = "cmpc",
-	.ids = cmpc_device_ids,
+	.ids = cmpc_bl_device_ids,
 	.ops = {
 		.add = cmpc_bl_add,
 		.remove = cmpc_bl_remove
@@ -505,6 +512,10 @@ static int cmpc_keys_codes[] = {
 	KEY_BRIGHTNESSDOWN,
 	KEY_BRIGHTNESSUP,
 	KEY_VENDOR,
+	KEY_UNKNOWN,
+	KEY_CAMERA,
+	KEY_BACK,
+	KEY_FORWARD,
 	KEY_MAX
 };
 
@@ -540,10 +551,9 @@ static int cmpc_keys_remove(struct acpi_
 }
 
 static const struct acpi_device_id cmpc_keys_device_ids[] = {
-	{"FnBT0000", 0},
+	{CMPC_KEYS_HID, 0},
 	{"", 0}
 };
-MODULE_DEVICE_TABLE(acpi, cmpc_keys_device_ids);
 
 static struct acpi_driver cmpc_keys_acpi_driver = {
 	.owner = THIS_MODULE,
@@ -607,3 +617,13 @@ static void cmpc_exit(void)
 
 module_init(cmpc_init);
 module_exit(cmpc_exit);
+
+static const struct acpi_device_id cmpc_device_ids[] = {
+	{CMPC_ACCEL_HID, 0},
+	{CMPC_TABLET_HID, 0},
+	{CMPC_BL_HID, 0},
+	{CMPC_KEYS_HID, 0},
+	{"", 0}
+};
+
+MODULE_DEVICE_TABLE(acpi, cmpc_device_ids);
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/compal-laptop.c linux-libre-2.6.34-gnu1/drivers/platform/x86/compal-laptop.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/compal-laptop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/compal-laptop.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,17 +26,8 @@
 /*
  * comapl-laptop.c - Compal laptop support.
  *
- * This driver exports a few files in /sys/devices/platform/compal-laptop/:
- *
- *   wlan - wlan subsystem state: contains 0 or 1 (rw)
- *
- *   bluetooth - Bluetooth subsystem state: contains 0 or 1 (rw)
- *
- *   raw - raw value taken from embedded controller register (ro)
- *
- * In addition to these platform device attributes the driver
- * registers itself in the Linux backlight control subsystem and is
- * available to userspace under /sys/class/backlight/compal-laptop/.
+ * The driver registers itself with the rfkill subsystem and
+ * the Linux backlight control subsystem.
  *
  * This driver might work on other laptops produced by Compal. If you
  * want to try it you can pass force=1 as argument to the module which
@@ -51,6 +42,7 @@
 #include <linux/dmi.h>
 #include <linux/backlight.h>
 #include <linux/platform_device.h>
+#include <linux/rfkill.h>
 
 #define COMPAL_DRIVER_VERSION "0.2.6"
 
@@ -63,6 +55,10 @@
 #define WLAN_MASK	0x01
 #define BT_MASK 	0x02
 
+static struct rfkill *wifi_rfkill;
+static struct rfkill *bt_rfkill;
+static struct platform_device *compal_device;
+
 static int force;
 module_param(force, bool, 0);
 MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
@@ -88,65 +84,75 @@ static int get_lcd_level(void)
 	return (int) result;
 }
 
-static int set_wlan_state(int state)
+static int compal_rfkill_set(void *data, bool blocked)
 {
+	unsigned long radio = (unsigned long) data;
 	u8 result, value;
 
 	ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
 
-	if ((result & KILLSWITCH_MASK) == 0)
-		return -EINVAL;
-	else {
-		if (state)
-			value = (u8) (result | WLAN_MASK);
-		else
-			value = (u8) (result & ~WLAN_MASK);
-		ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
-	}
+	if (!blocked)
+		value = (u8) (result | radio);
+	else
+		value = (u8) (result & ~radio);
+	ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
 
 	return 0;
 }
 
-static int set_bluetooth_state(int state)
+static void compal_rfkill_poll(struct rfkill *rfkill, void *data)
 {
-	u8 result, value;
+	u8 result;
+	bool hw_blocked;
 
 	ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
 
-	if ((result & KILLSWITCH_MASK) == 0)
-		return -EINVAL;
-	else {
-		if (state)
-			value = (u8) (result | BT_MASK);
-		else
-			value = (u8) (result & ~BT_MASK);
-		ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
-	}
-
-	return 0;
+	hw_blocked = !(result & KILLSWITCH_MASK);
+	rfkill_set_hw_state(rfkill, hw_blocked);
 }
 
-static int get_wireless_state(int *wlan, int *bluetooth)
+static const struct rfkill_ops compal_rfkill_ops = {
+	.poll = compal_rfkill_poll,
+	.set_block = compal_rfkill_set,
+};
+
+static int setup_rfkill(void)
 {
-	u8 result;
+	int ret;
 
-	ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
+	wifi_rfkill = rfkill_alloc("compal-wifi", &compal_device->dev,
+				RFKILL_TYPE_WLAN, &compal_rfkill_ops,
+				(void *) WLAN_MASK);
+	if (!wifi_rfkill)
+		return -ENOMEM;
 
-	if (wlan) {
-		if ((result & KILLSWITCH_MASK) == 0)
-			*wlan = 0;
-		else
-			*wlan = result & WLAN_MASK;
-	}
+	ret = rfkill_register(wifi_rfkill);
+	if (ret)
+		goto err_wifi;
 
-	if (bluetooth) {
-		if ((result & KILLSWITCH_MASK) == 0)
-			*bluetooth = 0;
-		else
-			*bluetooth = (result & BT_MASK) >> 1;
+	bt_rfkill = rfkill_alloc("compal-bluetooth", &compal_device->dev,
+				RFKILL_TYPE_BLUETOOTH, &compal_rfkill_ops,
+				(void *) BT_MASK);
+	if (!bt_rfkill) {
+		ret = -ENOMEM;
+		goto err_allocate_bt;
 	}
+	ret = rfkill_register(bt_rfkill);
+	if (ret)
+		goto err_register_bt;
 
 	return 0;
+
+err_register_bt:
+	rfkill_destroy(bt_rfkill);
+
+err_allocate_bt:
+	rfkill_unregister(wifi_rfkill);
+
+err_wifi:
+	rfkill_destroy(wifi_rfkill);
+
+	return ret;
 }
 
 /* Backlight device stuff */
@@ -169,86 +175,6 @@ static struct backlight_ops compalbl_ops
 
 static struct backlight_device *compalbl_device;
 
-/* Platform device */
-
-static ssize_t show_wlan(struct device *dev,
-	struct device_attribute *attr, char *buf)
-{
-	int ret, enabled;
-
-	ret = get_wireless_state(&enabled, NULL);
-	if (ret < 0)
-		return ret;
-
-	return sprintf(buf, "%i\n", enabled);
-}
-
-static ssize_t show_raw(struct device *dev,
-	struct device_attribute *attr, char *buf)
-{
-	u8 result;
-
-	ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
-
-	return sprintf(buf, "%i\n", result);
-}
-
-static ssize_t show_bluetooth(struct device *dev,
-	struct device_attribute *attr, char *buf)
-{
-	int ret, enabled;
-
-	ret = get_wireless_state(NULL, &enabled);
-	if (ret < 0)
-		return ret;
-
-	return sprintf(buf, "%i\n", enabled);
-}
-
-static ssize_t store_wlan_state(struct device *dev,
-	struct device_attribute *attr, const char *buf, size_t count)
-{
-	int state, ret;
-
-	if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1))
-		return -EINVAL;
-
-	ret = set_wlan_state(state);
-	if (ret < 0)
-		return ret;
-
-	return count;
-}
-
-static ssize_t store_bluetooth_state(struct device *dev,
-	struct device_attribute *attr, const char *buf, size_t count)
-{
-	int state, ret;
-
-	if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1))
-		return -EINVAL;
-
-	ret = set_bluetooth_state(state);
-	if (ret < 0)
-		return ret;
-
-	return count;
-}
-
-static DEVICE_ATTR(bluetooth, 0644, show_bluetooth, store_bluetooth_state);
-static DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan_state);
-static DEVICE_ATTR(raw, 0444, show_raw, NULL);
-
-static struct attribute *compal_attributes[] = {
-	&dev_attr_bluetooth.attr,
-	&dev_attr_wlan.attr,
-	&dev_attr_raw.attr,
-	NULL
-};
-
-static struct attribute_group compal_attribute_group = {
-	.attrs = compal_attributes
-};
 
 static struct platform_driver compal_driver = {
 	.driver = {
@@ -257,8 +183,6 @@ static struct platform_driver compal_dri
 	}
 };
 
-static struct platform_device *compal_device;
-
 /* Initialization */
 
 static int dmi_check_cb(const struct dmi_system_id *id)
@@ -310,6 +234,47 @@ static struct dmi_system_id __initdata c
 		},
 		.callback = dmi_check_cb
 	},
+	{
+		.ident = "Dell Mini 9",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 910"),
+		},
+		.callback = dmi_check_cb
+	},
+	{
+		.ident = "Dell Mini 10",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1010"),
+		},
+		.callback = dmi_check_cb
+	},
+	{
+		.ident = "Dell Mini 10v",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1011"),
+		},
+		.callback = dmi_check_cb
+	},
+	{
+		.ident = "Dell Inspiron 11z",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1110"),
+		},
+		.callback = dmi_check_cb
+	},
+	{
+		.ident = "Dell Mini 12",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1210"),
+		},
+		.callback = dmi_check_cb
+	},
+
 	{ }
 };
 
@@ -326,12 +291,15 @@ static int __init compal_init(void)
 	/* Register backlight stuff */
 
 	if (!acpi_video_backlight_support()) {
-		compalbl_device = backlight_device_register("compal-laptop", NULL, NULL,
-							    &compalbl_ops);
+		struct backlight_properties props;
+		memset(&props, 0, sizeof(struct backlight_properties));
+		props.max_brightness = COMPAL_LCD_LEVEL_MAX - 1;
+		compalbl_device = backlight_device_register("compal-laptop",
+							    NULL, NULL,
+							    &compalbl_ops,
+							    &props);
 		if (IS_ERR(compalbl_device))
 			return PTR_ERR(compalbl_device);
-
-		compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1;
 	}
 
 	ret = platform_driver_register(&compal_driver);
@@ -348,23 +316,21 @@ static int __init compal_init(void)
 
 	ret = platform_device_add(compal_device);
 	if (ret)
-		goto fail_platform_device1;
+		goto fail_platform_device;
 
-	ret = sysfs_create_group(&compal_device->dev.kobj,
-		&compal_attribute_group);
+	ret = setup_rfkill();
 	if (ret)
-		goto fail_platform_device2;
+		goto fail_rfkill;
 
 	printk(KERN_INFO "compal-laptop: driver "COMPAL_DRIVER_VERSION
 		" successfully loaded.\n");
 
 	return 0;
 
-fail_platform_device2:
-
+fail_rfkill:
 	platform_device_del(compal_device);
 
-fail_platform_device1:
+fail_platform_device:
 
 	platform_device_put(compal_device);
 
@@ -382,10 +348,13 @@ fail_backlight:
 static void __exit compal_cleanup(void)
 {
 
-	sysfs_remove_group(&compal_device->dev.kobj, &compal_attribute_group);
 	platform_device_unregister(compal_device);
 	platform_driver_unregister(&compal_driver);
 	backlight_device_unregister(compalbl_device);
+	rfkill_unregister(wifi_rfkill);
+	rfkill_destroy(wifi_rfkill);
+	rfkill_unregister(bt_rfkill);
+	rfkill_destroy(bt_rfkill);
 
 	printk(KERN_INFO "compal-laptop: driver unloaded.\n");
 }
@@ -403,3 +372,8 @@ MODULE_ALIAS("dmi:*:rnIFL90:rvrREFERENCE
 MODULE_ALIAS("dmi:*:rnIFL91:rvrIFT00:*");
 MODULE_ALIAS("dmi:*:rnJFL92:rvrIFT00:*");
 MODULE_ALIAS("dmi:*:rnIFT00:rvrIFT00:*");
+MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron910:*");
+MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1010:*");
+MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1011:*");
+MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1110:*");
+MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1210:*");
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/dell-laptop.c linux-libre-2.6.34-gnu1/drivers/platform/x86/dell-laptop.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/dell-laptop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/dell-laptop.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,9 @@
 #include <linux/rfkill.h>
 #include <linux/power_supply.h>
 #include <linux/acpi.h>
+#include <linux/mm.h>
+#include <linux/i8042.h>
+#include <linux/slab.h>
 #include "../../firmware/dcdbas.h"
 
 #define BRIGHTNESS_TOKEN 0x7d
@@ -79,9 +82,73 @@ static const struct dmi_system_id __init
 			DMI_MATCH(DMI_CHASSIS_TYPE, "8"),
 		},
 	},
+	{
+		.ident = "Dell Computer Corporation",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			DMI_MATCH(DMI_CHASSIS_TYPE, "8"),
+		},
+	},
 	{ }
 };
 
+static struct dmi_system_id __devinitdata dell_blacklist[] = {
+	/* Supported by compal-laptop */
+	{
+		.ident = "Dell Mini 9",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 910"),
+		},
+	},
+	{
+		.ident = "Dell Mini 10",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1010"),
+		},
+	},
+	{
+		.ident = "Dell Mini 10v",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1011"),
+		},
+	},
+	{
+		.ident = "Dell Inspiron 11z",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1110"),
+		},
+	},
+	{
+		.ident = "Dell Mini 12",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1210"),
+		},
+	},
+	{}
+};
+
+static struct calling_interface_buffer *buffer;
+static struct page *bufferpage;
+static DEFINE_MUTEX(buffer_mutex);
+
+static int hwswitch_state;
+
+static void get_buffer(void)
+{
+	mutex_lock(&buffer_mutex);
+	memset(buffer, 0, sizeof(struct calling_interface_buffer));
+}
+
+static void release_buffer(void)
+{
+	mutex_unlock(&buffer_mutex);
+}
+
 static void __init parse_da_table(const struct dmi_header *dm)
 {
 	/* Final token is a terminator, so we don't want to copy it */
@@ -160,6 +227,8 @@ dell_send_request(struct calling_interfa
 /* Derived from information in DellWirelessCtl.cpp:
    Class 17, select 11 is radio control. It returns an array of 32-bit values.
 
+   Input byte 0 = 0: Wireless information
+
    result[0]: return code
    result[1]:
      Bit 0:      Hardware switch supported
@@ -180,33 +249,62 @@ dell_send_request(struct calling_interfa
      Bits 20-31: Reserved
    result[2]: NVRAM size in bytes
    result[3]: NVRAM format version number
+
+   Input byte 0 = 2: Wireless switch configuration
+   result[0]: return code
+   result[1]:
+     Bit 0:      Wifi controlled by switch
+     Bit 1:      Bluetooth controlled by switch
+     Bit 2:      WWAN controlled by switch
+     Bits 3-6:   Reserved
+     Bit 7:      Wireless switch config locked
+     Bit 8:      Wifi locator enabled
+     Bits 9-14:  Reserved
+     Bit 15:     Wifi locator setting locked
+     Bits 16-31: Reserved
 */
 
 static int dell_rfkill_set(void *data, bool blocked)
 {
-	struct calling_interface_buffer buffer;
 	int disable = blocked ? 1 : 0;
 	unsigned long radio = (unsigned long)data;
+	int hwswitch_bit = (unsigned long)data - 1;
+	int ret = 0;
 
-	memset(&buffer, 0, sizeof(struct calling_interface_buffer));
-	buffer.input[0] = (1 | (radio<<8) | (disable << 16));
-	dell_send_request(&buffer, 17, 11);
+	get_buffer();
+	dell_send_request(buffer, 17, 11);
 
-	return 0;
+	/* If the hardware switch controls this radio, and the hardware
+	   switch is disabled, don't allow changing the software state */
+	if ((hwswitch_state & BIT(hwswitch_bit)) &&
+	    !(buffer->output[1] & BIT(16))) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	buffer->input[0] = (1 | (radio<<8) | (disable << 16));
+	dell_send_request(buffer, 17, 11);
+
+out:
+	release_buffer();
+	return ret;
 }
 
 static void dell_rfkill_query(struct rfkill *rfkill, void *data)
 {
-	struct calling_interface_buffer buffer;
 	int status;
 	int bit = (unsigned long)data + 16;
+	int hwswitch_bit = (unsigned long)data - 1;
 
-	memset(&buffer, 0, sizeof(struct calling_interface_buffer));
-	dell_send_request(&buffer, 17, 11);
-	status = buffer.output[1];
+	get_buffer();
+	dell_send_request(buffer, 17, 11);
+	status = buffer->output[1];
+	release_buffer();
 
 	rfkill_set_sw_state(rfkill, !!(status & BIT(bit)));
-	rfkill_set_hw_state(rfkill, !(status & BIT(16)));
+
+	if (hwswitch_state & (BIT(hwswitch_bit)))
+		rfkill_set_hw_state(rfkill, !(status & BIT(16)));
 }
 
 static const struct rfkill_ops dell_rfkill_ops = {
@@ -214,15 +312,36 @@ static const struct rfkill_ops dell_rfki
 	.query = dell_rfkill_query,
 };
 
+static void dell_update_rfkill(struct work_struct *ignored)
+{
+	if (wifi_rfkill)
+		dell_rfkill_query(wifi_rfkill, (void *)1);
+	if (bluetooth_rfkill)
+		dell_rfkill_query(bluetooth_rfkill, (void *)2);
+	if (wwan_rfkill)
+		dell_rfkill_query(wwan_rfkill, (void *)3);
+}
+static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill);
+
+
 static int __init dell_setup_rfkill(void)
 {
-	struct calling_interface_buffer buffer;
 	int status;
 	int ret;
 
-	memset(&buffer, 0, sizeof(struct calling_interface_buffer));
-	dell_send_request(&buffer, 17, 11);
-	status = buffer.output[1];
+	if (dmi_check_system(dell_blacklist)) {
+		printk(KERN_INFO "dell-laptop: Blacklisted hardware detected - "
+				"not enabling rfkill\n");
+		return 0;
+	}
+
+	get_buffer();
+	dell_send_request(buffer, 17, 11);
+	status = buffer->output[1];
+	buffer->input[0] = 0x2;
+	dell_send_request(buffer, 17, 11);
+	hwswitch_state = buffer->output[1];
+	release_buffer();
 
 	if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) {
 		wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev,
@@ -298,39 +417,49 @@ static void dell_cleanup_rfkill(void)
 
 static int dell_send_intensity(struct backlight_device *bd)
 {
-	struct calling_interface_buffer buffer;
+	int ret = 0;
 
-	memset(&buffer, 0, sizeof(struct calling_interface_buffer));
-	buffer.input[0] = find_token_location(BRIGHTNESS_TOKEN);
-	buffer.input[1] = bd->props.brightness;
+	get_buffer();
+	buffer->input[0] = find_token_location(BRIGHTNESS_TOKEN);
+	buffer->input[1] = bd->props.brightness;
 
-	if (buffer.input[0] == -1)
-		return -ENODEV;
+	if (buffer->input[0] == -1) {
+		ret = -ENODEV;
+		goto out;
+	}
 
 	if (power_supply_is_system_supplied() > 0)
-		dell_send_request(&buffer, 1, 2);
+		dell_send_request(buffer, 1, 2);
 	else
-		dell_send_request(&buffer, 1, 1);
+		dell_send_request(buffer, 1, 1);
 
+out:
+	release_buffer();
 	return 0;
 }
 
 static int dell_get_intensity(struct backlight_device *bd)
 {
-	struct calling_interface_buffer buffer;
+	int ret = 0;
 
-	memset(&buffer, 0, sizeof(struct calling_interface_buffer));
-	buffer.input[0] = find_token_location(BRIGHTNESS_TOKEN);
+	get_buffer();
+	buffer->input[0] = find_token_location(BRIGHTNESS_TOKEN);
 
-	if (buffer.input[0] == -1)
-		return -ENODEV;
+	if (buffer->input[0] == -1) {
+		ret = -ENODEV;
+		goto out;
+	}
 
 	if (power_supply_is_system_supplied() > 0)
-		dell_send_request(&buffer, 0, 2);
+		dell_send_request(buffer, 0, 2);
 	else
-		dell_send_request(&buffer, 0, 1);
+		dell_send_request(buffer, 0, 1);
 
-	return buffer.output[1];
+out:
+	release_buffer();
+	if (ret)
+		return ret;
+	return buffer->output[1];
 }
 
 static struct backlight_ops dell_ops = {
@@ -338,9 +467,32 @@ static struct backlight_ops dell_ops = {
 	.update_status  = dell_send_intensity,
 };
 
+bool dell_laptop_i8042_filter(unsigned char data, unsigned char str,
+			      struct serio *port)
+{
+	static bool extended;
+
+	if (str & 0x20)
+		return false;
+
+	if (unlikely(data == 0xe0)) {
+		extended = true;
+		return false;
+	} else if (unlikely(extended)) {
+		switch (data) {
+		case 0x8:
+			schedule_delayed_work(&dell_rfkill_work,
+					      round_jiffies_relative(HZ));
+			break;
+		}
+		extended = false;
+	}
+
+	return false;
+}
+
 static int __init dell_init(void)
 {
-	struct calling_interface_buffer buffer;
 	int max_intensity = 0;
 	int ret;
 
@@ -366,6 +518,17 @@ static int __init dell_init(void)
 	if (ret)
 		goto fail_platform_device2;
 
+	/*
+	 * Allocate buffer below 4GB for SMI data--only 32-bit physical addr
+	 * is passed to SMI handler.
+	 */
+	bufferpage = alloc_page(GFP_KERNEL | GFP_DMA32);
+
+	if (!bufferpage)
+		goto fail_buffer;
+	buffer = page_address(bufferpage);
+	mutex_init(&buffer_mutex);
+
 	ret = dell_setup_rfkill();
 
 	if (ret) {
@@ -373,6 +536,13 @@ static int __init dell_init(void)
 		goto fail_rfkill;
 	}
 
+	ret = i8042_install_filter(dell_laptop_i8042_filter);
+	if (ret) {
+		printk(KERN_WARNING
+		       "dell-laptop: Unable to install key filter\n");
+		goto fail_filter;
+	}
+
 #ifdef CONFIG_ACPI
 	/* In the event of an ACPI backlight being available, don't
 	 * register the platform controller.
@@ -381,19 +551,23 @@ static int __init dell_init(void)
 		return 0;
 #endif
 
-	memset(&buffer, 0, sizeof(struct calling_interface_buffer));
-	buffer.input[0] = find_token_location(BRIGHTNESS_TOKEN);
-
-	if (buffer.input[0] != -1) {
-		dell_send_request(&buffer, 0, 2);
-		max_intensity = buffer.output[3];
+	get_buffer();
+	buffer->input[0] = find_token_location(BRIGHTNESS_TOKEN);
+	if (buffer->input[0] != -1) {
+		dell_send_request(buffer, 0, 2);
+		max_intensity = buffer->output[3];
 	}
+	release_buffer();
 
 	if (max_intensity) {
-		dell_backlight_device = backlight_device_register(
-			"dell_backlight",
-			&platform_device->dev, NULL,
-			&dell_ops);
+		struct backlight_properties props;
+		memset(&props, 0, sizeof(struct backlight_properties));
+		props.max_brightness = max_intensity;
+		dell_backlight_device = backlight_device_register("dell_backlight",
+								  &platform_device->dev,
+								  NULL,
+								  &dell_ops,
+								  &props);
 
 		if (IS_ERR(dell_backlight_device)) {
 			ret = PTR_ERR(dell_backlight_device);
@@ -401,7 +575,6 @@ static int __init dell_init(void)
 			goto fail_backlight;
 		}
 
-		dell_backlight_device->props.max_brightness = max_intensity;
 		dell_backlight_device->props.brightness =
 			dell_get_intensity(dell_backlight_device);
 		backlight_update_status(dell_backlight_device);
@@ -410,8 +583,13 @@ static int __init dell_init(void)
 	return 0;
 
 fail_backlight:
+	i8042_remove_filter(dell_laptop_i8042_filter);
+	cancel_delayed_work_sync(&dell_rfkill_work);
+fail_filter:
 	dell_cleanup_rfkill();
 fail_rfkill:
+	free_page((unsigned long)bufferpage);
+fail_buffer:
 	platform_device_del(platform_device);
 fail_platform_device2:
 	platform_device_put(platform_device);
@@ -424,8 +602,16 @@ fail_platform_driver:
 
 static void __exit dell_exit(void)
 {
+	i8042_remove_filter(dell_laptop_i8042_filter);
+	cancel_delayed_work_sync(&dell_rfkill_work);
 	backlight_device_unregister(dell_backlight_device);
 	dell_cleanup_rfkill();
+	if (platform_device) {
+		platform_device_unregister(platform_device);
+		platform_driver_unregister(&platform_driver);
+	}
+	kfree(da_tokens);
+	free_page((unsigned long)buffer);
 }
 
 module_init(dell_init);
@@ -435,3 +621,4 @@ MODULE_AUTHOR("Matthew Garrett <mjg@redh
 MODULE_DESCRIPTION("Dell laptop driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("dmi:*svnDellInc.:*:ct8:*");
+MODULE_ALIAS("dmi:*svnDellComputerCorporation.:*:ct8:*");
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/dell-wmi.c linux-libre-2.6.34-gnu1/drivers/platform/x86/dell-wmi.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/dell-wmi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/dell-wmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/input.h>
 #include <acpi/acpi_drivers.h>
@@ -142,7 +143,7 @@ static struct key_entry *dell_wmi_keymap
 
 static struct input_dev *dell_wmi_input_dev;
 
-static struct key_entry *dell_wmi_get_entry_by_scancode(int code)
+static struct key_entry *dell_wmi_get_entry_by_scancode(unsigned int code)
 {
 	struct key_entry *key;
 
@@ -153,7 +154,7 @@ static struct key_entry *dell_wmi_get_en
 	return NULL;
 }
 
-static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode)
+static struct key_entry *dell_wmi_get_entry_by_keycode(unsigned int keycode)
 {
 	struct key_entry *key;
 
@@ -164,8 +165,8 @@ static struct key_entry *dell_wmi_get_en
 	return NULL;
 }
 
-static int dell_wmi_getkeycode(struct input_dev *dev, int scancode,
-			       int *keycode)
+static int dell_wmi_getkeycode(struct input_dev *dev,
+				unsigned int scancode, unsigned int *keycode)
 {
 	struct key_entry *key = dell_wmi_get_entry_by_scancode(scancode);
 
@@ -177,13 +178,11 @@ static int dell_wmi_getkeycode(struct in
 	return -EINVAL;
 }
 
-static int dell_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int dell_wmi_setkeycode(struct input_dev *dev,
+				unsigned int scancode, unsigned int keycode)
 {
 	struct key_entry *key;
-	int old_keycode;
-
-	if (keycode < 0 || keycode > KEY_MAX)
-		return -EINVAL;
+	unsigned int old_keycode;
 
 	key = dell_wmi_get_entry_by_scancode(scancode);
 	if (key && key->type == KE_KEY) {
@@ -218,6 +217,7 @@ static void dell_wmi_notify(u32 value, v
 		if (dell_new_hk_type && (buffer_entry[1] != 0x10)) {
 			printk(KERN_INFO "dell-wmi: Received unknown WMI event"
 					 " (0x%x)\n", buffer_entry[1]);
+			kfree(obj);
 			return;
 		}
 
@@ -235,7 +235,7 @@ static void dell_wmi_notify(u32 value, v
 			    key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) {
 			/* Don't report brightness notifications that will also
 			 * come via ACPI */
-			return;
+			;
 		} else {
 			input_report_key(dell_wmi_input_dev, key->keycode, 1);
 			input_sync(dell_wmi_input_dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/eeepc-laptop.c linux-libre-2.6.34-gnu1/drivers/platform/x86/eeepc-laptop.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/eeepc-laptop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/eeepc-laptop.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/fb.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/slab.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 #include <linux/uaccess.h>
@@ -168,7 +169,6 @@ struct eeepc_laptop {
 	struct backlight_device *backlight_device;
 
 	struct input_dev *inputdev;
-	struct key_entry *keymap;
 
 	struct rfkill *wlan_rfkill;
 	struct rfkill *bluetooth_rfkill;
@@ -578,6 +578,8 @@ static void eeepc_rfkill_hotplug(struct
 	struct pci_dev *dev;
 	struct pci_bus *bus;
 	bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
+	bool absent;
+	u32 l;
 
 	if (eeepc->wlan_rfkill)
 		rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
@@ -591,6 +593,22 @@ static void eeepc_rfkill_hotplug(struct
 			goto out_unlock;
 		}
 
+		if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
+			pr_err("Unable to read PCI config space?\n");
+			goto out_unlock;
+		}
+		absent = (l == 0xffffffff);
+
+		if (blocked != absent) {
+			pr_warning("BIOS says wireless lan is %s, "
+					"but the pci device is %s\n",
+				blocked ? "blocked" : "unblocked",
+				absent ? "absent" : "present");
+			pr_warning("skipped wireless hotplug as probably "
+					"inappropriate for this model\n");
+			goto out_unlock;
+		}
+
 		if (!blocked) {
 			dev = pci_get_slot(bus, 0);
 			if (dev) {
@@ -1113,18 +1131,20 @@ static int eeepc_backlight_notify(struct
 
 static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
 {
+	struct backlight_properties props;
 	struct backlight_device *bd;
 
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = 15;
 	bd = backlight_device_register(EEEPC_LAPTOP_FILE,
-				       &eeepc->platform_device->dev,
-				       eeepc, &eeepcbl_ops);
+				       &eeepc->platform_device->dev, eeepc,
+				       &eeepcbl_ops, &props);
 	if (IS_ERR(bd)) {
 		pr_err("Could not register eeepc backlight device\n");
 		eeepc->backlight_device = NULL;
 		return PTR_ERR(bd);
 	}
 	eeepc->backlight_device = bd;
-	bd->props.max_brightness = 15;
 	bd->props.brightness = read_brightness(bd);
 	bd->props.power = FB_BLANK_UNBLANK;
 	backlight_update_status(bd);
@@ -1183,8 +1203,8 @@ static int eeepc_input_init(struct eeepc
 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
 {
 	if (eeepc->inputdev) {
+		sparse_keymap_free(eeepc->inputdev);
 		input_unregister_device(eeepc->inputdev);
-		kfree(eeepc->keymap);
 	}
 }
 
@@ -1277,7 +1297,8 @@ static void eeepc_dmi_check(struct eeepc
 	 * hotplug code. In fact, current hotplug code seems to unplug another
 	 * device...
 	 */
-	if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0) {
+	if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0 ||
+	    strcmp(model, "1005PE") == 0) {
 		eeepc->hotplug_disabled = true;
 		pr_info("wlan hotplug disabled\n");
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/eeepc-wmi.c linux-libre-2.6.34-gnu1/drivers/platform/x86/eeepc-wmi.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/eeepc-wmi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/eeepc-wmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,413 @@
+/*
+ * Eee PC WMI hotkey driver
+ *
+ * Copyright(C) 2010 Intel Corporation.
+ *
+ * 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
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#define	EEEPC_WMI_FILE	"eeepc-wmi"
+
+MODULE_AUTHOR("Yong Wang <yong.y.wang@intel.com>");
+MODULE_DESCRIPTION("Eee PC WMI Hotkey Driver");
+MODULE_LICENSE("GPL");
+
+#define EEEPC_WMI_EVENT_GUID	"ABBC0F72-8EA1-11D1-00A0-C90629100000"
+#define EEEPC_WMI_MGMT_GUID	"97845ED0-4E6D-11DE-8A39-0800200C9A66"
+
+MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID);
+MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
+
+#define NOTIFY_BRNUP_MIN	0x11
+#define NOTIFY_BRNUP_MAX	0x1f
+#define NOTIFY_BRNDOWN_MIN	0x20
+#define NOTIFY_BRNDOWN_MAX	0x2e
+
+#define EEEPC_WMI_METHODID_DEVS	0x53564544
+#define EEEPC_WMI_METHODID_DSTS	0x53544344
+
+#define EEEPC_WMI_DEVID_BACKLIGHT	0x00050012
+
+static const struct key_entry eeepc_wmi_keymap[] = {
+	/* Sleep already handled via generic ACPI code */
+	{ KE_KEY, 0x5d, { KEY_WLAN } },
+	{ KE_KEY, 0x32, { KEY_MUTE } },
+	{ KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
+	{ KE_KEY, 0x30, { KEY_VOLUMEUP } },
+	{ KE_IGNORE, NOTIFY_BRNDOWN_MIN, { KEY_BRIGHTNESSDOWN } },
+	{ KE_IGNORE, NOTIFY_BRNUP_MIN, { KEY_BRIGHTNESSUP } },
+	{ KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } },
+	{ KE_END, 0},
+};
+
+struct bios_args {
+	u32	dev_id;
+	u32	ctrl_param;
+};
+
+struct eeepc_wmi {
+	struct input_dev *inputdev;
+	struct backlight_device *backlight_device;
+};
+
+static struct platform_device *platform_device;
+
+static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc)
+{
+	int err;
+
+	eeepc->inputdev = input_allocate_device();
+	if (!eeepc->inputdev)
+		return -ENOMEM;
+
+	eeepc->inputdev->name = "Eee PC WMI hotkeys";
+	eeepc->inputdev->phys = EEEPC_WMI_FILE "/input0";
+	eeepc->inputdev->id.bustype = BUS_HOST;
+	eeepc->inputdev->dev.parent = &platform_device->dev;
+
+	err = sparse_keymap_setup(eeepc->inputdev, eeepc_wmi_keymap, NULL);
+	if (err)
+		goto err_free_dev;
+
+	err = input_register_device(eeepc->inputdev);
+	if (err)
+		goto err_free_keymap;
+
+	return 0;
+
+err_free_keymap:
+	sparse_keymap_free(eeepc->inputdev);
+err_free_dev:
+	input_free_device(eeepc->inputdev);
+	return err;
+}
+
+static void eeepc_wmi_input_exit(struct eeepc_wmi *eeepc)
+{
+	if (eeepc->inputdev) {
+		sparse_keymap_free(eeepc->inputdev);
+		input_unregister_device(eeepc->inputdev);
+	}
+
+	eeepc->inputdev = NULL;
+}
+
+static acpi_status eeepc_wmi_get_devstate(u32 dev_id, u32 *ctrl_param)
+{
+	struct acpi_buffer input = { (acpi_size)sizeof(u32), &dev_id };
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *obj;
+	acpi_status status;
+	u32 tmp;
+
+	status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
+			1, EEEPC_WMI_METHODID_DSTS, &input, &output);
+
+	if (ACPI_FAILURE(status))
+		return status;
+
+	obj = (union acpi_object *)output.pointer;
+	if (obj && obj->type == ACPI_TYPE_INTEGER)
+		tmp = (u32)obj->integer.value;
+	else
+		tmp = 0;
+
+	if (ctrl_param)
+		*ctrl_param = tmp;
+
+	kfree(obj);
+
+	return status;
+
+}
+
+static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param)
+{
+	struct bios_args args = {
+		.dev_id = dev_id,
+		.ctrl_param = ctrl_param,
+	};
+	struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
+	acpi_status status;
+
+	status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
+			1, EEEPC_WMI_METHODID_DEVS, &input, NULL);
+
+	return status;
+}
+
+static int read_brightness(struct backlight_device *bd)
+{
+	static u32 ctrl_param;
+	acpi_status status;
+
+	status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &ctrl_param);
+
+	if (ACPI_FAILURE(status))
+		return -1;
+	else
+		return ctrl_param & 0xFF;
+}
+
+static int update_bl_status(struct backlight_device *bd)
+{
+
+	static u32 ctrl_param;
+	acpi_status status;
+
+	ctrl_param = bd->props.brightness;
+
+	status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT, ctrl_param);
+
+	if (ACPI_FAILURE(status))
+		return -1;
+	else
+		return 0;
+}
+
+static const struct backlight_ops eeepc_wmi_bl_ops = {
+	.get_brightness = read_brightness,
+	.update_status = update_bl_status,
+};
+
+static int eeepc_wmi_backlight_notify(struct eeepc_wmi *eeepc, int code)
+{
+	struct backlight_device *bd = eeepc->backlight_device;
+	int old = bd->props.brightness;
+	int new;
+
+	if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
+		new = code - NOTIFY_BRNUP_MIN + 1;
+	else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
+		new = code - NOTIFY_BRNDOWN_MIN;
+
+	bd->props.brightness = new;
+	backlight_update_status(bd);
+	backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
+
+	return old;
+}
+
+static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
+{
+	struct backlight_device *bd;
+	struct backlight_properties props;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = 15;
+	bd = backlight_device_register(EEEPC_WMI_FILE,
+				       &platform_device->dev, eeepc,
+				       &eeepc_wmi_bl_ops, &props);
+	if (IS_ERR(bd)) {
+		pr_err("Could not register backlight device\n");
+		return PTR_ERR(bd);
+	}
+
+	eeepc->backlight_device = bd;
+
+	bd->props.brightness = read_brightness(bd);
+	bd->props.power = FB_BLANK_UNBLANK;
+	backlight_update_status(bd);
+
+	return 0;
+}
+
+static void eeepc_wmi_backlight_exit(struct eeepc_wmi *eeepc)
+{
+	if (eeepc->backlight_device)
+		backlight_device_unregister(eeepc->backlight_device);
+
+	eeepc->backlight_device = NULL;
+}
+
+static void eeepc_wmi_notify(u32 value, void *context)
+{
+	struct eeepc_wmi *eeepc = context;
+	struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *obj;
+	acpi_status status;
+	int code;
+	int orig_code;
+
+	status = wmi_get_event_data(value, &response);
+	if (status != AE_OK) {
+		pr_err("bad event status 0x%x\n", status);
+		return;
+	}
+
+	obj = (union acpi_object *)response.pointer;
+
+	if (obj && obj->type == ACPI_TYPE_INTEGER) {
+		code = obj->integer.value;
+		orig_code = code;
+
+		if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
+			code = NOTIFY_BRNUP_MIN;
+		else if (code >= NOTIFY_BRNDOWN_MIN &&
+			 code <= NOTIFY_BRNDOWN_MAX)
+			code = NOTIFY_BRNDOWN_MIN;
+
+		if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) {
+			if (!acpi_video_backlight_support())
+				eeepc_wmi_backlight_notify(eeepc, orig_code);
+		}
+
+		if (!sparse_keymap_report_event(eeepc->inputdev,
+						code, 1, true))
+			pr_info("Unknown key %x pressed\n", code);
+	}
+
+	kfree(obj);
+}
+
+static int __devinit eeepc_wmi_platform_probe(struct platform_device *device)
+{
+	struct eeepc_wmi *eeepc;
+	int err;
+	acpi_status status;
+
+	eeepc = platform_get_drvdata(device);
+
+	err = eeepc_wmi_input_init(eeepc);
+	if (err)
+		goto error_input;
+
+	if (!acpi_video_backlight_support()) {
+		err = eeepc_wmi_backlight_init(eeepc);
+		if (err)
+			goto error_backlight;
+	} else
+		pr_info("Backlight controlled by ACPI video driver\n");
+
+	status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID,
+					eeepc_wmi_notify, eeepc);
+	if (ACPI_FAILURE(status)) {
+		pr_err("Unable to register notify handler - %d\n",
+			status);
+		err = -ENODEV;
+		goto error_wmi;
+	}
+
+	return 0;
+
+error_wmi:
+	eeepc_wmi_backlight_exit(eeepc);
+error_backlight:
+	eeepc_wmi_input_exit(eeepc);
+error_input:
+	return err;
+}
+
+static int __devexit eeepc_wmi_platform_remove(struct platform_device *device)
+{
+	struct eeepc_wmi *eeepc;
+
+	eeepc = platform_get_drvdata(device);
+	wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
+	eeepc_wmi_backlight_exit(eeepc);
+	eeepc_wmi_input_exit(eeepc);
+
+	return 0;
+}
+
+static struct platform_driver platform_driver = {
+	.driver = {
+		.name = EEEPC_WMI_FILE,
+		.owner = THIS_MODULE,
+	},
+	.probe = eeepc_wmi_platform_probe,
+	.remove = __devexit_p(eeepc_wmi_platform_remove),
+};
+
+static int __init eeepc_wmi_init(void)
+{
+	struct eeepc_wmi *eeepc;
+	int err;
+
+	if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID) ||
+	    !wmi_has_guid(EEEPC_WMI_MGMT_GUID)) {
+		pr_warning("No known WMI GUID found\n");
+		return -ENODEV;
+	}
+
+	eeepc = kzalloc(sizeof(struct eeepc_wmi), GFP_KERNEL);
+	if (!eeepc)
+		return -ENOMEM;
+
+	platform_device = platform_device_alloc(EEEPC_WMI_FILE, -1);
+	if (!platform_device) {
+		pr_warning("Unable to allocate platform device\n");
+		err = -ENOMEM;
+		goto fail_platform;
+	}
+
+	err = platform_device_add(platform_device);
+	if (err) {
+		pr_warning("Unable to add platform device\n");
+		goto put_dev;
+	}
+
+	platform_set_drvdata(platform_device, eeepc);
+
+	err = platform_driver_register(&platform_driver);
+	if (err) {
+		pr_warning("Unable to register platform driver\n");
+		goto del_dev;
+	}
+
+	return 0;
+
+del_dev:
+	platform_device_del(platform_device);
+put_dev:
+	platform_device_put(platform_device);
+fail_platform:
+	kfree(eeepc);
+
+	return err;
+}
+
+static void __exit eeepc_wmi_exit(void)
+{
+	struct eeepc_wmi *eeepc;
+
+	eeepc = platform_get_drvdata(platform_device);
+	platform_driver_unregister(&platform_driver);
+	platform_device_unregister(platform_device);
+	kfree(eeepc);
+}
+
+module_init(eeepc_wmi_init);
+module_exit(eeepc_wmi_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/fujitsu-laptop.c linux-libre-2.6.34-gnu1/drivers/platform/x86/fujitsu-laptop.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/fujitsu-laptop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/fujitsu-laptop.c	2010-05-16 17:17:36.000000000 -0400
@@ -66,6 +66,7 @@
 #include <linux/kfifo.h>
 #include <linux/video_output.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
 #include <linux/leds.h>
 #endif
@@ -1126,16 +1127,20 @@ static int __init fujitsu_init(void)
 	/* Register backlight stuff */
 
 	if (!acpi_video_backlight_support()) {
-		fujitsu->bl_device =
-			backlight_device_register("fujitsu-laptop", NULL, NULL,
-						  &fujitsubl_ops);
+		struct backlight_properties props;
+
+		memset(&props, 0, sizeof(struct backlight_properties));
+		max_brightness = fujitsu->max_brightness;
+		props.max_brightness = max_brightness - 1;
+		fujitsu->bl_device = backlight_device_register("fujitsu-laptop",
+							       NULL, NULL,
+							       &fujitsubl_ops,
+							       &props);
 		if (IS_ERR(fujitsu->bl_device)) {
 			ret = PTR_ERR(fujitsu->bl_device);
 			fujitsu->bl_device = NULL;
 			goto fail_sysfs_group;
 		}
-		max_brightness = fujitsu->max_brightness;
-		fujitsu->bl_device->props.max_brightness = max_brightness - 1;
 		fujitsu->bl_device->props.brightness = fujitsu->brightness_level;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/hp-wmi.c linux-libre-2.6.34-gnu1/drivers/platform/x86/hp-wmi.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/hp-wmi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/hp-wmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/input.h>
 #include <acpi/acpi_drivers.h>
@@ -57,7 +58,7 @@ enum hp_wmi_radio {
 	HPWMI_WWAN = 2,
 };
 
-static int __init hp_wmi_bios_setup(struct platform_device *device);
+static int __devinit hp_wmi_bios_setup(struct platform_device *device);
 static int __exit hp_wmi_bios_remove(struct platform_device *device);
 static int hp_wmi_resume_handler(struct device *device);
 
@@ -89,6 +90,7 @@ static struct key_entry hp_wmi_keymap[]
 	{KE_KEY, 0x20e6, KEY_PROG1},
 	{KE_KEY, 0x2142, KEY_MEDIA},
 	{KE_KEY, 0x213b, KEY_INFO},
+	{KE_KEY, 0x2169, KEY_DIRECTION},
 	{KE_KEY, 0x231b, KEY_HELP},
 	{KE_END, 0}
 };
@@ -277,7 +279,7 @@ static DEVICE_ATTR(als, S_IRUGO | S_IWUS
 static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL);
 static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL);
 
-static struct key_entry *hp_wmi_get_entry_by_scancode(int code)
+static struct key_entry *hp_wmi_get_entry_by_scancode(unsigned int code)
 {
 	struct key_entry *key;
 
@@ -288,7 +290,7 @@ static struct key_entry *hp_wmi_get_entr
 	return NULL;
 }
 
-static struct key_entry *hp_wmi_get_entry_by_keycode(int keycode)
+static struct key_entry *hp_wmi_get_entry_by_keycode(unsigned int keycode)
 {
 	struct key_entry *key;
 
@@ -299,7 +301,8 @@ static struct key_entry *hp_wmi_get_entr
 	return NULL;
 }
 
-static int hp_wmi_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static int hp_wmi_getkeycode(struct input_dev *dev,
+			     unsigned int scancode, unsigned int *keycode)
 {
 	struct key_entry *key = hp_wmi_get_entry_by_scancode(scancode);
 
@@ -311,13 +314,11 @@ static int hp_wmi_getkeycode(struct inpu
 	return -EINVAL;
 }
 
-static int hp_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int hp_wmi_setkeycode(struct input_dev *dev,
+			     unsigned int scancode, unsigned int keycode)
 {
 	struct key_entry *key;
-	int old_keycode;
-
-	if (keycode < 0 || keycode > KEY_MAX)
-		return -EINVAL;
+	unsigned int old_keycode;
 
 	key = hp_wmi_get_entry_by_scancode(scancode);
 	if (key && key->type == KE_KEY) {
@@ -446,7 +447,7 @@ static void cleanup_sysfs(struct platfor
 	device_remove_file(&device->dev, &dev_attr_tablet);
 }
 
-static int __init hp_wmi_bios_setup(struct platform_device *device)
+static int __devinit hp_wmi_bios_setup(struct platform_device *device)
 {
 	int err;
 	int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/intel_menlow.c linux-libre-2.6.34-gnu1/drivers/platform/x86/intel_menlow.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/intel_menlow.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/intel_menlow.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/pm.h>
@@ -396,6 +397,7 @@ static int intel_menlow_add_one_attribut
 	if (!attr)
 		return -ENOMEM;
 
+	sysfs_attr_init(&attr->attr.attr); /* That is consistent naming :D */
 	attr->attr.attr.name = name;
 	attr->attr.attr.mode = mode;
 	attr->attr.show = show;
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/Kconfig linux-libre-2.6.34-gnu1/drivers/platform/x86/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -59,6 +59,8 @@ config ASUS_LAPTOP
 	select NEW_LEDS
 	select BACKLIGHT_CLASS_DEVICE
 	depends on INPUT
+	depends on RFKILL || RFKILL = n
+	select INPUT_SPARSEKMAP
 	---help---
 	  This is the new Linux driver for Asus laptops. It may also support some
 	  MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate
@@ -79,6 +81,7 @@ config DELL_LAPTOP
 	depends on BACKLIGHT_CLASS_DEVICE
 	depends on RFKILL || RFKILL = n
 	depends on POWER_SUPPLY
+	depends on SERIO_I8042
 	default n
 	---help---
 	This driver adds support for rfkill and backlight control to Dell
@@ -147,6 +150,7 @@ config MSI_LAPTOP
 	tristate "MSI Laptop Extras"
 	depends on ACPI
 	depends on BACKLIGHT_CLASS_DEVICE
+	depends on RFKILL
 	---help---
 	  This is a driver for laptops built by MSI (MICRO-STAR
 	  INTERNATIONAL):
@@ -176,6 +180,7 @@ config COMPAL_LAPTOP
 	tristate "Compal Laptop Extras"
 	depends on ACPI
 	depends on BACKLIGHT_CLASS_DEVICE
+	depends on RFKILL
 	---help---
 	  This is a driver for laptops built by Compal:
 
@@ -319,9 +324,15 @@ config THINKPAD_ACPI_VIDEO
 	  server running, phase of the moon, and the current mood of
 	  Schroedinger's cat.  If you can use X.org's RandR to control
 	  your ThinkPad's video output ports instead of this feature,
-	  don't think twice: do it and say N here to save some memory.
+	  don't think twice: do it and say N here to save memory and avoid
+	  bad interactions with X.org.
 
-	  If you are not sure, say Y here.
+	  NOTE: access to this feature is limited to processes with the
+	  CAP_SYS_ADMIN capability, to avoid local DoS issues in platforms
+	  where it interacts badly with X.org.
+
+	  If you are not sure, say Y here but do try to check if you could
+	  be using X.org RandR instead.
 
 config THINKPAD_ACPI_HOTKEY_POLL
 	bool "Support NVRAM polling for hot keys"
@@ -374,6 +385,17 @@ config EEEPC_LAPTOP
 
 	  If you have an Eee PC laptop, say Y or M here.
 
+config EEEPC_WMI
+	tristate "Eee PC WMI Hotkey Driver (EXPERIMENTAL)"
+	depends on ACPI_WMI
+	depends on INPUT
+	depends on EXPERIMENTAL
+	select INPUT_SPARSEKMAP
+	---help---
+	  Say Y here if you want to support WMI-based hotkeys on Eee PC laptops.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called eeepc-wmi.
 
 config ACPI_WMI
 	tristate "WMI"
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/Makefile linux-libre-2.6.34-gnu1/drivers/platform/x86/Makefile
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
 #
 obj-$(CONFIG_ASUS_LAPTOP)	+= asus-laptop.o
 obj-$(CONFIG_EEEPC_LAPTOP)	+= eeepc-laptop.o
+obj-$(CONFIG_EEEPC_WMI)		+= eeepc-wmi.o
 obj-$(CONFIG_MSI_LAPTOP)	+= msi-laptop.o
 obj-$(CONFIG_ACPI_CMPC)		+= classmate-laptop.o
 obj-$(CONFIG_COMPAL_LAPTOP)	+= compal-laptop.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/msi-laptop.c linux-libre-2.6.34-gnu1/drivers/platform/x86/msi-laptop.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/msi-laptop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/msi-laptop.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,6 +58,7 @@
 #include <linux/dmi.h>
 #include <linux/backlight.h>
 #include <linux/platform_device.h>
+#include <linux/rfkill.h>
 
 #define MSI_DRIVER_VERSION "0.5"
 
@@ -66,6 +67,20 @@
 #define MSI_EC_COMMAND_WIRELESS 0x10
 #define MSI_EC_COMMAND_LCD_LEVEL 0x11
 
+#define MSI_STANDARD_EC_COMMAND_ADDRESS	0x2e
+#define MSI_STANDARD_EC_BLUETOOTH_MASK	(1 << 0)
+#define MSI_STANDARD_EC_WEBCAM_MASK	(1 << 1)
+#define MSI_STANDARD_EC_WLAN_MASK	(1 << 3)
+#define MSI_STANDARD_EC_3G_MASK		(1 << 4)
+
+/* For set SCM load flag to disable BIOS fn key */
+#define MSI_STANDARD_EC_SCM_LOAD_ADDRESS	0x2d
+#define MSI_STANDARD_EC_SCM_LOAD_MASK		(1 << 0)
+
+static int msi_laptop_resume(struct platform_device *device);
+
+#define MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS	0x2f
+
 static int force;
 module_param(force, bool, 0);
 MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
@@ -74,6 +89,23 @@ static int auto_brightness;
 module_param(auto_brightness, int, 0);
 MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)");
 
+static bool old_ec_model;
+static int wlan_s, bluetooth_s, threeg_s;
+static int threeg_exists;
+
+/* Some MSI 3G netbook only have one fn key to control Wlan/Bluetooth/3G,
+ * those netbook will load the SCM (windows app) to disable the original
+ * Wlan/Bluetooth control by BIOS when user press fn key, then control
+ * Wlan/Bluetooth/3G by SCM (software control by OS). Without SCM, user
+ * cann't on/off 3G module on those 3G netbook.
+ * On Linux, msi-laptop driver will do the same thing to disable the
+ * original BIOS control, then might need use HAL or other userland
+ * application to do the software control that simulate with SCM.
+ * e.g. MSI N034 netbook
+ */
+static bool load_scm_model;
+static struct rfkill *rfk_wlan, *rfk_bluetooth, *rfk_threeg;
+
 /* Hardware access */
 
 static int set_lcd_level(int level)
@@ -130,6 +162,35 @@ static int set_auto_brightness(int enabl
 	return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0, 1);
 }
 
+static ssize_t set_device_state(const char *buf, size_t count, u8 mask)
+{
+	int status;
+	u8 wdata = 0, rdata;
+	int result;
+
+	if (sscanf(buf, "%i", &status) != 1 || (status < 0 || status > 1))
+		return -EINVAL;
+
+	/* read current device state */
+	result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata);
+	if (result < 0)
+		return -EINVAL;
+
+	if (!!(rdata & mask) != status) {
+		/* reverse device bit */
+		if (rdata & mask)
+			wdata = rdata & ~mask;
+		else
+			wdata = rdata | mask;
+
+		result = ec_write(MSI_STANDARD_EC_COMMAND_ADDRESS, wdata);
+		if (result < 0)
+			return -EINVAL;
+	}
+
+	return count;
+}
+
 static int get_wireless_state(int *wlan, int *bluetooth)
 {
 	u8 wdata = 0, rdata;
@@ -148,6 +209,38 @@ static int get_wireless_state(int *wlan,
 	return 0;
 }
 
+static int get_wireless_state_ec_standard(void)
+{
+	u8 rdata;
+	int result;
+
+	result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata);
+	if (result < 0)
+		return -1;
+
+	wlan_s = !!(rdata & MSI_STANDARD_EC_WLAN_MASK);
+
+	bluetooth_s = !!(rdata & MSI_STANDARD_EC_BLUETOOTH_MASK);
+
+	threeg_s = !!(rdata & MSI_STANDARD_EC_3G_MASK);
+
+	return 0;
+}
+
+static int get_threeg_exists(void)
+{
+	u8 rdata;
+	int result;
+
+	result = ec_read(MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS, &rdata);
+	if (result < 0)
+		return -1;
+
+	threeg_exists = !!(rdata & MSI_STANDARD_EC_3G_MASK);
+
+	return 0;
+}
+
 /* Backlight device stuff */
 
 static int bl_get_brightness(struct backlight_device *b)
@@ -176,26 +269,71 @@ static ssize_t show_wlan(struct device *
 
 	int ret, enabled;
 
-	ret = get_wireless_state(&enabled, NULL);
+	if (old_ec_model) {
+		ret = get_wireless_state(&enabled, NULL);
+	} else {
+		ret = get_wireless_state_ec_standard();
+		enabled = wlan_s;
+	}
 	if (ret < 0)
 		return ret;
 
 	return sprintf(buf, "%i\n", enabled);
 }
 
+static ssize_t store_wlan(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	return set_device_state(buf, count, MSI_STANDARD_EC_WLAN_MASK);
+}
+
 static ssize_t show_bluetooth(struct device *dev,
 	struct device_attribute *attr, char *buf)
 {
 
 	int ret, enabled;
 
-	ret = get_wireless_state(NULL, &enabled);
+	if (old_ec_model) {
+		ret = get_wireless_state(NULL, &enabled);
+	} else {
+		ret = get_wireless_state_ec_standard();
+		enabled = bluetooth_s;
+	}
 	if (ret < 0)
 		return ret;
 
 	return sprintf(buf, "%i\n", enabled);
 }
 
+static ssize_t store_bluetooth(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	return set_device_state(buf, count, MSI_STANDARD_EC_BLUETOOTH_MASK);
+}
+
+static ssize_t show_threeg(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+
+	int ret;
+
+	/* old msi ec not support 3G */
+	if (old_ec_model)
+		return -1;
+
+	ret = get_wireless_state_ec_standard();
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "%i\n", threeg_s);
+}
+
+static ssize_t store_threeg(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	return set_device_state(buf, count, MSI_STANDARD_EC_3G_MASK);
+}
+
 static ssize_t show_lcd_level(struct device *dev,
 	struct device_attribute *attr, char *buf)
 {
@@ -258,6 +396,7 @@ static DEVICE_ATTR(lcd_level, 0644, show
 static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness);
 static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL);
 static DEVICE_ATTR(wlan, 0444, show_wlan, NULL);
+static DEVICE_ATTR(threeg, 0444, show_threeg, NULL);
 
 static struct attribute *msipf_attributes[] = {
 	&dev_attr_lcd_level.attr,
@@ -275,7 +414,8 @@ static struct platform_driver msipf_driv
 	.driver = {
 		.name = "msi-laptop-pf",
 		.owner = THIS_MODULE,
-	}
+	},
+	.resume = msi_laptop_resume,
 };
 
 static struct platform_device *msipf_device;
@@ -332,6 +472,192 @@ static struct dmi_system_id __initdata m
 	{ }
 };
 
+static struct dmi_system_id __initdata msi_load_scm_models_dmi_table[] = {
+	{
+		.ident = "MSI N034",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR,
+				"MICRO-STAR INTERNATIONAL CO., LTD"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MS-N034"),
+			DMI_MATCH(DMI_CHASSIS_VENDOR,
+			"MICRO-STAR INTERNATIONAL CO., LTD")
+		},
+		.callback = dmi_check_cb
+	},
+	{ }
+};
+
+static int rfkill_bluetooth_set(void *data, bool blocked)
+{
+	/* Do something with blocked...*/
+	/*
+	 * blocked == false is on
+	 * blocked == true is off
+	 */
+	if (blocked)
+		set_device_state("0", 0, MSI_STANDARD_EC_BLUETOOTH_MASK);
+	else
+		set_device_state("1", 0, MSI_STANDARD_EC_BLUETOOTH_MASK);
+
+	return 0;
+}
+
+static int rfkill_wlan_set(void *data, bool blocked)
+{
+	if (blocked)
+		set_device_state("0", 0, MSI_STANDARD_EC_WLAN_MASK);
+	else
+		set_device_state("1", 0, MSI_STANDARD_EC_WLAN_MASK);
+
+	return 0;
+}
+
+static int rfkill_threeg_set(void *data, bool blocked)
+{
+	if (blocked)
+		set_device_state("0", 0, MSI_STANDARD_EC_3G_MASK);
+	else
+		set_device_state("1", 0, MSI_STANDARD_EC_3G_MASK);
+
+	return 0;
+}
+
+static struct rfkill_ops rfkill_bluetooth_ops = {
+	.set_block = rfkill_bluetooth_set
+};
+
+static struct rfkill_ops rfkill_wlan_ops = {
+	.set_block = rfkill_wlan_set
+};
+
+static struct rfkill_ops rfkill_threeg_ops = {
+	.set_block = rfkill_threeg_set
+};
+
+static void rfkill_cleanup(void)
+{
+	if (rfk_bluetooth) {
+		rfkill_unregister(rfk_bluetooth);
+		rfkill_destroy(rfk_bluetooth);
+	}
+
+	if (rfk_threeg) {
+		rfkill_unregister(rfk_threeg);
+		rfkill_destroy(rfk_threeg);
+	}
+
+	if (rfk_wlan) {
+		rfkill_unregister(rfk_wlan);
+		rfkill_destroy(rfk_wlan);
+	}
+}
+
+static int rfkill_init(struct platform_device *sdev)
+{
+	/* add rfkill */
+	int retval;
+
+	rfk_bluetooth = rfkill_alloc("msi-bluetooth", &sdev->dev,
+				RFKILL_TYPE_BLUETOOTH,
+				&rfkill_bluetooth_ops, NULL);
+	if (!rfk_bluetooth) {
+		retval = -ENOMEM;
+		goto err_bluetooth;
+	}
+	retval = rfkill_register(rfk_bluetooth);
+	if (retval)
+		goto err_bluetooth;
+
+	rfk_wlan = rfkill_alloc("msi-wlan", &sdev->dev, RFKILL_TYPE_WLAN,
+				&rfkill_wlan_ops, NULL);
+	if (!rfk_wlan) {
+		retval = -ENOMEM;
+		goto err_wlan;
+	}
+	retval = rfkill_register(rfk_wlan);
+	if (retval)
+		goto err_wlan;
+
+	if (threeg_exists) {
+		rfk_threeg = rfkill_alloc("msi-threeg", &sdev->dev,
+				RFKILL_TYPE_WWAN, &rfkill_threeg_ops, NULL);
+		if (!rfk_threeg) {
+			retval = -ENOMEM;
+			goto err_threeg;
+		}
+		retval = rfkill_register(rfk_threeg);
+		if (retval)
+			goto err_threeg;
+	}
+
+	return 0;
+
+err_threeg:
+	rfkill_destroy(rfk_threeg);
+	if (rfk_wlan)
+		rfkill_unregister(rfk_wlan);
+err_wlan:
+	rfkill_destroy(rfk_wlan);
+	if (rfk_bluetooth)
+		rfkill_unregister(rfk_bluetooth);
+err_bluetooth:
+	rfkill_destroy(rfk_bluetooth);
+
+	return retval;
+}
+
+static int msi_laptop_resume(struct platform_device *device)
+{
+	u8 data;
+	int result;
+
+	if (!load_scm_model)
+		return 0;
+
+	/* set load SCM to disable hardware control by fn key */
+	result = ec_read(MSI_STANDARD_EC_SCM_LOAD_ADDRESS, &data);
+	if (result < 0)
+		return result;
+
+	result = ec_write(MSI_STANDARD_EC_SCM_LOAD_ADDRESS,
+		data | MSI_STANDARD_EC_SCM_LOAD_MASK);
+	if (result < 0)
+		return result;
+
+	return 0;
+}
+
+static int load_scm_model_init(struct platform_device *sdev)
+{
+	u8 data;
+	int result;
+
+	/* allow userland write sysfs file  */
+	dev_attr_bluetooth.store = store_bluetooth;
+	dev_attr_wlan.store = store_wlan;
+	dev_attr_threeg.store = store_threeg;
+	dev_attr_bluetooth.attr.mode |= S_IWUSR;
+	dev_attr_wlan.attr.mode |= S_IWUSR;
+	dev_attr_threeg.attr.mode |= S_IWUSR;
+
+	/* disable hardware control by fn key */
+	result = ec_read(MSI_STANDARD_EC_SCM_LOAD_ADDRESS, &data);
+	if (result < 0)
+		return result;
+
+	result = ec_write(MSI_STANDARD_EC_SCM_LOAD_ADDRESS,
+		data | MSI_STANDARD_EC_SCM_LOAD_MASK);
+	if (result < 0)
+		return result;
+
+	/* initial rfkill */
+	result = rfkill_init(sdev);
+	if (result < 0)
+		return result;
+
+	return 0;
+}
+
 static int __init msi_init(void)
 {
 	int ret;
@@ -339,8 +665,14 @@ static int __init msi_init(void)
 	if (acpi_disabled)
 		return -ENODEV;
 
-	if (!force && !dmi_check_system(msi_dmi_table))
-		return -ENODEV;
+	if (force || dmi_check_system(msi_dmi_table))
+		old_ec_model = 1;
+
+	if (!old_ec_model)
+		get_threeg_exists();
+
+	if (!old_ec_model && dmi_check_system(msi_load_scm_models_dmi_table))
+		load_scm_model = 1;
 
 	if (auto_brightness < 0 || auto_brightness > 2)
 		return -EINVAL;
@@ -351,11 +683,14 @@ static int __init msi_init(void)
 		printk(KERN_INFO "MSI: Brightness ignored, must be controlled "
 		       "by ACPI video driver\n");
 	} else {
+		struct backlight_properties props;
+		memset(&props, 0, sizeof(struct backlight_properties));
+		props.max_brightness = MSI_LCD_LEVEL_MAX - 1;
 		msibl_device = backlight_device_register("msi-laptop-bl", NULL,
-							 NULL, &msibl_ops);
+							 NULL, &msibl_ops,
+							 &props);
 		if (IS_ERR(msibl_device))
 			return PTR_ERR(msibl_device);
-		msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1;
 	}
 
 	ret = platform_driver_register(&msipf_driver);
@@ -374,10 +709,23 @@ static int __init msi_init(void)
 	if (ret)
 		goto fail_platform_device1;
 
+	if (load_scm_model && (load_scm_model_init(msipf_device) < 0)) {
+		ret = -EINVAL;
+		goto fail_platform_device1;
+	}
+
 	ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group);
 	if (ret)
 		goto fail_platform_device2;
 
+	if (!old_ec_model) {
+		if (threeg_exists)
+			ret = device_create_file(&msipf_device->dev,
+						&dev_attr_threeg);
+		if (ret)
+			goto fail_platform_device2;
+	}
+
 	/* Disable automatic brightness control by default because
 	 * this module was probably loaded to do brightness control in
 	 * software. */
@@ -412,10 +760,14 @@ static void __exit msi_cleanup(void)
 {
 
 	sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group);
+	if (!old_ec_model && threeg_exists)
+		device_remove_file(&msipf_device->dev, &dev_attr_threeg);
 	platform_device_unregister(msipf_device);
 	platform_driver_unregister(&msipf_driver);
 	backlight_device_unregister(msibl_device);
 
+	rfkill_cleanup();
+
 	/* Enable automatic brightness control again */
 	if (auto_brightness != 2)
 		set_auto_brightness(1);
@@ -435,3 +787,4 @@ MODULE_ALIAS("dmi:*:svnMICRO-STARINT'LCO
 MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1058:pvr0581:rvnMSI:rnMS-1058:*:ct10:*");
 MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1412:*:rvnMSI:rnMS-1412:*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
 MODULE_ALIAS("dmi:*:svnNOTEBOOK:pnSAM2000:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
+MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N034:*");
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/msi-wmi.c linux-libre-2.6.34-gnu1/drivers/platform/x86/msi-wmi.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/msi-wmi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/msi-wmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/input/sparse-keymap.h>
 #include <linux/acpi.h>
 #include <linux/backlight.h>
+#include <linux/slab.h>
 
 MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
 MODULE_DESCRIPTION("MSI laptop WMI hotkeys driver");
@@ -138,7 +139,7 @@ static int bl_set_status(struct backligh
 	return msi_wmi_set_block(0, backlight_map[bright]);
 }
 
-static struct backlight_ops msi_backlight_ops = {
+static const struct backlight_ops msi_backlight_ops = {
 	.get_brightness	= bl_get,
 	.update_status	= bl_set_status,
 };
@@ -249,12 +250,17 @@ static int __init msi_wmi_init(void)
 		goto err_uninstall_notifier;
 
 	if (!acpi_video_backlight_support()) {
-		backlight = backlight_device_register(DRV_NAME,
-				NULL, NULL, &msi_backlight_ops);
-		if (IS_ERR(backlight))
+		struct backlight_properties props;
+		memset(&props, 0, sizeof(struct backlight_properties));
+		props.max_brightness = ARRAY_SIZE(backlight_map) - 1;
+		backlight = backlight_device_register(DRV_NAME, NULL, NULL,
+						      &msi_backlight_ops,
+						      &props);
+		if (IS_ERR(backlight)) {
+			err = PTR_ERR(backlight);
 			goto err_free_input;
+		}
 
-		backlight->props.max_brightness = ARRAY_SIZE(backlight_map) - 1;
 		err = bl_get(NULL);
 		if (err < 0)
 			goto err_free_backlight;
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/panasonic-laptop.c linux-libre-2.6.34-gnu1/drivers/platform/x86/panasonic-laptop.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/panasonic-laptop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/panasonic-laptop.c	2010-05-16 17:17:36.000000000 -0400
@@ -124,6 +124,7 @@
 #include <linux/ctype.h>
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 #include <linux/input.h>
@@ -200,7 +201,7 @@ static struct acpi_driver acpi_pcc_drive
 };
 
 #define KEYMAP_SIZE		11
-static const int initial_keymap[KEYMAP_SIZE] = {
+static const unsigned int initial_keymap[KEYMAP_SIZE] = {
 	/*  0 */ KEY_RESERVED,
 	/*  1 */ KEY_BRIGHTNESSDOWN,
 	/*  2 */ KEY_BRIGHTNESSUP,
@@ -222,7 +223,7 @@ struct pcc_acpi {
 	struct acpi_device	*device;
 	struct input_dev	*input_dev;
 	struct backlight_device	*backlight;
-	int			keymap[KEYMAP_SIZE];
+	unsigned int		keymap[KEYMAP_SIZE];
 };
 
 struct pcc_keyinput {
@@ -352,7 +353,7 @@ static int bl_set_status(struct backligh
 	return acpi_pcc_write_sset(pcc, SINF_DC_CUR_BRIGHT, bright);
 }
 
-static struct backlight_ops pcc_backlight_ops = {
+static const struct backlight_ops pcc_backlight_ops = {
 	.get_brightness	= bl_get,
 	.update_status	= bl_set_status,
 };
@@ -445,7 +446,8 @@ static struct attribute_group pcc_attr_g
 
 /* hotkey input device driver */
 
-static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static int pcc_getkeycode(struct input_dev *dev,
+			  unsigned int scancode, unsigned int *keycode)
 {
 	struct pcc_acpi *pcc = input_get_drvdata(dev);
 
@@ -457,7 +459,7 @@ static int pcc_getkeycode(struct input_d
 	return 0;
 }
 
-static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode)
+static int keymap_get_by_keycode(struct pcc_acpi *pcc, unsigned int keycode)
 {
 	int i;
 
@@ -469,7 +471,8 @@ static int keymap_get_by_keycode(struct
 	return 0;
 }
 
-static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int pcc_setkeycode(struct input_dev *dev,
+			  unsigned int scancode, unsigned int keycode)
 {
 	struct pcc_acpi *pcc = input_get_drvdata(dev);
 	int oldkeycode;
@@ -477,9 +480,6 @@ static int pcc_setkeycode(struct input_d
 	if (scancode >= ARRAY_SIZE(pcc->keymap))
 		return -EINVAL;
 
-	if (keycode < 0 || keycode > KEY_MAX)
-		return -EINVAL;
-
 	oldkeycode = pcc->keymap[scancode];
 	pcc->keymap[scancode] = keycode;
 
@@ -601,6 +601,7 @@ static int acpi_pcc_hotkey_resume(struct
 
 static int acpi_pcc_hotkey_add(struct acpi_device *device)
 {
+	struct backlight_properties props;
 	struct pcc_acpi *pcc;
 	int num_sifr, result;
 
@@ -638,24 +639,25 @@ static int acpi_pcc_hotkey_add(struct ac
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 				  "Error installing keyinput handler\n"));
-		goto out_sinf;
+		goto out_hotkey;
 	}
 
-	/* initialize backlight */
-	pcc->backlight = backlight_device_register("panasonic", NULL, pcc,
-						   &pcc_backlight_ops);
-	if (IS_ERR(pcc->backlight))
-		goto out_input;
-
 	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 				 "Couldn't retrieve BIOS data\n"));
-		goto out_backlight;
+		goto out_input;
+	}
+	/* initialize backlight */
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = pcc->sinf[SINF_AC_MAX_BRIGHT];
+	pcc->backlight = backlight_device_register("panasonic", NULL, pcc,
+						   &pcc_backlight_ops, &props);
+	if (IS_ERR(pcc->backlight)) {
+		result = PTR_ERR(pcc->backlight);
+		goto out_sinf;
 	}
 
 	/* read the initial brightness setting from the hardware */
-	pcc->backlight->props.max_brightness =
-					pcc->sinf[SINF_AC_MAX_BRIGHT];
 	pcc->backlight->props.brightness = pcc->sinf[SINF_AC_CUR_BRIGHT];
 
 	/* read the initial sticky key mode from the hardware */
@@ -670,12 +672,12 @@ static int acpi_pcc_hotkey_add(struct ac
 
 out_backlight:
 	backlight_device_unregister(pcc->backlight);
+out_sinf:
+	kfree(pcc->sinf);
 out_input:
 	input_unregister_device(pcc->input_dev);
 	/* no need to input_free_device() since core input API refcount and
 	 * free()s the device */
-out_sinf:
-	kfree(pcc->sinf);
 out_hotkey:
 	kfree(pcc);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/sony-laptop.c linux-libre-2.6.34-gnu1/drivers/platform/x86/sony-laptop.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/sony-laptop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/sony-laptop.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,6 +58,7 @@
 #include <linux/kfifo.h>
 #include <linux/workqueue.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 #include <asm/uaccess.h>
@@ -145,7 +146,7 @@ struct sony_laptop_input_s {
 	struct input_dev	*key_dev;
 	struct kfifo		fifo;
 	spinlock_t		fifo_lock;
-	struct workqueue_struct	*wq;
+	struct timer_list	release_key_timer;
 };
 
 static struct sony_laptop_input_s sony_laptop_input = {
@@ -299,20 +300,26 @@ static int sony_laptop_input_keycode_map
 };
 
 /* release buttons after a short delay if pressed */
-static void do_sony_laptop_release_key(struct work_struct *work)
+static void do_sony_laptop_release_key(unsigned long unused)
 {
 	struct sony_laptop_keypress kp;
+	unsigned long flags;
 
-	while (kfifo_out_locked(&sony_laptop_input.fifo, (unsigned char *)&kp,
-			sizeof(kp), &sony_laptop_input.fifo_lock)
-			== sizeof(kp)) {
-		msleep(10);
+	spin_lock_irqsave(&sony_laptop_input.fifo_lock, flags);
+
+	if (kfifo_out(&sony_laptop_input.fifo,
+		      (unsigned char *)&kp, sizeof(kp)) == sizeof(kp)) {
 		input_report_key(kp.dev, kp.key, 0);
 		input_sync(kp.dev);
 	}
+
+	/* If there is something in the fifo schedule next release. */
+	if (kfifo_len(&sony_laptop_input.fifo) != 0)
+		mod_timer(&sony_laptop_input.release_key_timer,
+			  jiffies + msecs_to_jiffies(10));
+
+	spin_unlock_irqrestore(&sony_laptop_input.fifo_lock, flags);
 }
-static DECLARE_WORK(sony_laptop_release_key_work,
-		do_sony_laptop_release_key);
 
 /* forward event to the input subsystem */
 static void sony_laptop_report_input_event(u8 event)
@@ -366,13 +373,13 @@ static void sony_laptop_report_input_eve
 		/* we emit the scancode so we can always remap the key */
 		input_event(kp.dev, EV_MSC, MSC_SCAN, event);
 		input_sync(kp.dev);
-		kfifo_in_locked(&sony_laptop_input.fifo,
-			  (unsigned char *)&kp, sizeof(kp),
-			  &sony_laptop_input.fifo_lock);
 
-		if (!work_pending(&sony_laptop_release_key_work))
-			queue_work(sony_laptop_input.wq,
-					&sony_laptop_release_key_work);
+		/* schedule key release */
+		kfifo_in_locked(&sony_laptop_input.fifo,
+				(unsigned char *)&kp, sizeof(kp),
+				&sony_laptop_input.fifo_lock);
+		mod_timer(&sony_laptop_input.release_key_timer,
+			  jiffies + msecs_to_jiffies(10));
 	} else
 		dprintk("unknown input event %.2x\n", event);
 }
@@ -390,27 +397,21 @@ static int sony_laptop_setup_input(struc
 
 	/* kfifo */
 	spin_lock_init(&sony_laptop_input.fifo_lock);
-	error =
-	 kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
+	error = kfifo_alloc(&sony_laptop_input.fifo,
+			    SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
 	if (error) {
 		printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
 		goto err_dec_users;
 	}
 
-	/* init workqueue */
-	sony_laptop_input.wq = create_singlethread_workqueue("sony-laptop");
-	if (!sony_laptop_input.wq) {
-		printk(KERN_ERR DRV_PFX
-				"Unable to create workqueue.\n");
-		error = -ENXIO;
-		goto err_free_kfifo;
-	}
+	setup_timer(&sony_laptop_input.release_key_timer,
+		    do_sony_laptop_release_key, 0);
 
 	/* input keys */
 	key_dev = input_allocate_device();
 	if (!key_dev) {
 		error = -ENOMEM;
-		goto err_destroy_wq;
+		goto err_free_kfifo;
 	}
 
 	key_dev->name = "Sony Vaio Keys";
@@ -419,18 +420,15 @@ static int sony_laptop_setup_input(struc
 	key_dev->dev.parent = &acpi_device->dev;
 
 	/* Initialize the Input Drivers: special keys */
-	set_bit(EV_KEY, key_dev->evbit);
-	set_bit(EV_MSC, key_dev->evbit);
-	set_bit(MSC_SCAN, key_dev->mscbit);
+	input_set_capability(key_dev, EV_MSC, MSC_SCAN);
+
+	__set_bit(EV_KEY, key_dev->evbit);
 	key_dev->keycodesize = sizeof(sony_laptop_input_keycode_map[0]);
 	key_dev->keycodemax = ARRAY_SIZE(sony_laptop_input_keycode_map);
 	key_dev->keycode = &sony_laptop_input_keycode_map;
-	for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) {
-		if (sony_laptop_input_keycode_map[i] != KEY_RESERVED) {
-			set_bit(sony_laptop_input_keycode_map[i],
-				key_dev->keybit);
-		}
-	}
+	for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++)
+		__set_bit(sony_laptop_input_keycode_map[i], key_dev->keybit);
+	__clear_bit(KEY_RESERVED, key_dev->keybit);
 
 	error = input_register_device(key_dev);
 	if (error)
@@ -450,9 +448,8 @@ static int sony_laptop_setup_input(struc
 	jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
 	key_dev->dev.parent = &acpi_device->dev;
 
-	jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
-	jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE);
-	jog_dev->relbit[0] = BIT_MASK(REL_WHEEL);
+	input_set_capability(jog_dev, EV_KEY, BTN_MIDDLE);
+	input_set_capability(jog_dev, EV_REL, REL_WHEEL);
 
 	error = input_register_device(jog_dev);
 	if (error)
@@ -473,9 +470,6 @@ err_unregister_keydev:
 err_free_keydev:
 	input_free_device(key_dev);
 
-err_destroy_wq:
-	destroy_workqueue(sony_laptop_input.wq);
-
 err_free_kfifo:
 	kfifo_free(&sony_laptop_input.fifo);
 
@@ -486,12 +480,23 @@ err_dec_users:
 
 static void sony_laptop_remove_input(void)
 {
-	/* cleanup only after the last user has gone */
+	struct sony_laptop_keypress kp = { NULL };
+
+	/* Cleanup only after the last user has gone */
 	if (!atomic_dec_and_test(&sony_laptop_input.users))
 		return;
 
-	/* flush workqueue first */
-	flush_workqueue(sony_laptop_input.wq);
+	del_timer_sync(&sony_laptop_input.release_key_timer);
+
+	/*
+	 * Generate key-up events for remaining keys. Note that we don't
+	 * need locking since nobody is adding new events to the kfifo.
+	 */
+	while (kfifo_out(&sony_laptop_input.fifo,
+			 (unsigned char *)&kp, sizeof(kp)) == sizeof(kp)) {
+		input_report_key(kp.dev, kp.key, 0);
+		input_sync(kp.dev);
+	}
 
 	/* destroy input devs */
 	input_unregister_device(sony_laptop_input.key_dev);
@@ -502,7 +507,6 @@ static void sony_laptop_remove_input(voi
 		sony_laptop_input.jog_dev = NULL;
 	}
 
-	destroy_workqueue(sony_laptop_input.wq);
 	kfifo_free(&sony_laptop_input.fifo);
 }
 
@@ -1288,9 +1292,13 @@ static int sony_nc_add(struct acpi_devic
 		       "controlled by ACPI video driver\n");
 	} else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
 						&handle))) {
+							struct backlight_properties props;
+		memset(&props, 0, sizeof(struct backlight_properties));
+		props.max_brightness = SONY_MAX_BRIGHTNESS - 1;
 		sony_backlight_device = backlight_device_register("sony", NULL,
 								  NULL,
-								  &sony_backlight_ops);
+								  &sony_backlight_ops,
+								  &props);
 
 		if (IS_ERR(sony_backlight_device)) {
 			printk(KERN_WARNING DRV_PFX "unable to register backlight device\n");
@@ -1299,8 +1307,6 @@ static int sony_nc_add(struct acpi_devic
 			sony_backlight_device->props.brightness =
 			    sony_backlight_get_brightness
 			    (sony_backlight_device);
-			sony_backlight_device->props.max_brightness =
-			    SONY_MAX_BRIGHTNESS - 1;
 		}
 
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/tc1100-wmi.c linux-libre-2.6.34-gnu1/drivers/platform/x86/tc1100-wmi.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/tc1100-wmi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/tc1100-wmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <acpi/acpi.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/thinkpad_acpi.c linux-libre-2.6.34-gnu1/drivers/platform/x86/thinkpad_acpi.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/thinkpad_acpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/thinkpad_acpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,6 +58,7 @@
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <linux/nvram.h>
 #include <linux/proc_fs.h>
@@ -286,6 +287,7 @@ struct ibm_init_struct {
 	char param[32];
 
 	int (*init) (struct ibm_init_struct *);
+	mode_t base_procfs_mode;
 	struct ibm_struct *data;
 };
 
@@ -1667,7 +1669,7 @@ static void tpacpi_remove_driver_attribu
  * Table of recommended minimum BIOS versions
  *
  * Reasons for listing:
- *    1. Stable BIOS, listed because the unknown ammount of
+ *    1. Stable BIOS, listed because the unknown amount of
  *       bugs and bad ACPI behaviour on older versions
  *
  *    2. BIOS or EC fw with known bugs that trigger on Linux
@@ -2082,6 +2084,7 @@ static struct attribute_set *hotkey_dev_
 
 static void tpacpi_driver_event(const unsigned int hkey_event);
 static void hotkey_driver_event(const unsigned int scancode);
+static void hotkey_poll_setup(const bool may_warn);
 
 /* HKEY.MHKG() return bits */
 #define TP_HOTKEY_TABLET_MASK (1 << 3)
@@ -2264,6 +2267,8 @@ static int tpacpi_hotkey_driver_mask_set
 
 	rc = hotkey_mask_set((hotkey_acpi_mask | hotkey_driver_mask) &
 							~hotkey_source_mask);
+	hotkey_poll_setup(true);
+
 	mutex_unlock(&hotkey_mutex);
 
 	return rc;
@@ -2548,7 +2553,7 @@ static void hotkey_poll_stop_sync(void)
 }
 
 /* call with hotkey_mutex held */
-static void hotkey_poll_setup(bool may_warn)
+static void hotkey_poll_setup(const bool may_warn)
 {
 	const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask;
 	const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask;
@@ -2579,7 +2584,7 @@ static void hotkey_poll_setup(bool may_w
 	}
 }
 
-static void hotkey_poll_setup_safe(bool may_warn)
+static void hotkey_poll_setup_safe(const bool may_warn)
 {
 	mutex_lock(&hotkey_mutex);
 	hotkey_poll_setup(may_warn);
@@ -2597,7 +2602,11 @@ static void hotkey_poll_set_freq(unsigne
 
 #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
 
-static void hotkey_poll_setup_safe(bool __unused)
+static void hotkey_poll_setup(const bool __unused)
+{
+}
+
+static void hotkey_poll_setup_safe(const bool __unused)
 {
 }
 
@@ -2607,16 +2616,11 @@ static int hotkey_inputdev_open(struct i
 {
 	switch (tpacpi_lifecycle) {
 	case TPACPI_LIFE_INIT:
-		/*
-		 * hotkey_init will call hotkey_poll_setup_safe
-		 * at the appropriate moment
-		 */
-		return 0;
-	case TPACPI_LIFE_EXITING:
-		return -EBUSY;
 	case TPACPI_LIFE_RUNNING:
 		hotkey_poll_setup_safe(false);
 		return 0;
+	case TPACPI_LIFE_EXITING:
+		return -EBUSY;
 	}
 
 	/* Should only happen if tpacpi_lifecycle is corrupt */
@@ -2627,7 +2631,7 @@ static int hotkey_inputdev_open(struct i
 static void hotkey_inputdev_close(struct input_dev *dev)
 {
 	/* disable hotkey polling when possible */
-	if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING &&
+	if (tpacpi_lifecycle != TPACPI_LIFE_EXITING &&
 	    !(hotkey_source_mask & hotkey_driver_mask))
 		hotkey_poll_setup_safe(false);
 }
@@ -3655,13 +3659,19 @@ static void hotkey_notify(struct ibm_str
 			break;
 		case 3:
 			/* 0x3000-0x3FFF: bay-related wakeups */
-			if (hkey == TP_HKEY_EV_BAYEJ_ACK) {
+			switch (hkey) {
+			case TP_HKEY_EV_BAYEJ_ACK:
 				hotkey_autosleep_ack = 1;
 				printk(TPACPI_INFO
 				       "bay ejected\n");
 				hotkey_wakeup_hotunplug_complete_notify_change();
 				known_ev = true;
-			} else {
+				break;
+			case TP_HKEY_EV_OPTDRV_EJ:
+				/* FIXME: kick libata if SATA link offline */
+				known_ev = true;
+				break;
+			default:
 				known_ev = false;
 			}
 			break;
@@ -3870,7 +3880,7 @@ enum {
 	TP_ACPI_BLUETOOTH_HWPRESENT	= 0x01,	/* Bluetooth hw available */
 	TP_ACPI_BLUETOOTH_RADIOSSW	= 0x02,	/* Bluetooth radio enabled */
 	TP_ACPI_BLUETOOTH_RESUMECTRL	= 0x04,	/* Bluetooth state at resume:
-						   off / last state */
+						   0 = disable, 1 = enable */
 };
 
 enum {
@@ -3916,10 +3926,11 @@ static int bluetooth_set_status(enum tpa
 	}
 #endif
 
-	/* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
-	status = TP_ACPI_BLUETOOTH_RESUMECTRL;
 	if (state == TPACPI_RFK_RADIO_ON)
-		status |= TP_ACPI_BLUETOOTH_RADIOSSW;
+		status = TP_ACPI_BLUETOOTH_RADIOSSW
+			  | TP_ACPI_BLUETOOTH_RESUMECTRL;
+	else
+		status = 0;
 
 	if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
 		return -EIO;
@@ -4070,7 +4081,7 @@ enum {
 	TP_ACPI_WANCARD_HWPRESENT	= 0x01,	/* Wan hw available */
 	TP_ACPI_WANCARD_RADIOSSW	= 0x02,	/* Wan radio enabled */
 	TP_ACPI_WANCARD_RESUMECTRL	= 0x04,	/* Wan state at resume:
-						   off / last state */
+						   0 = disable, 1 = enable */
 };
 
 #define TPACPI_RFK_WWAN_SW_NAME		"tpacpi_wwan_sw"
@@ -4107,10 +4118,11 @@ static int wan_set_status(enum tpacpi_rf
 	}
 #endif
 
-	/* We make sure to set TP_ACPI_WANCARD_RESUMECTRL */
-	status = TP_ACPI_WANCARD_RESUMECTRL;
 	if (state == TPACPI_RFK_RADIO_ON)
-		status |= TP_ACPI_WANCARD_RADIOSSW;
+		status = TP_ACPI_WANCARD_RADIOSSW
+			 | TP_ACPI_WANCARD_RESUMECTRL;
+	else
+		status = 0;
 
 	if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
 		return -EIO;
@@ -4619,6 +4631,10 @@ static int video_read(struct seq_file *m
 		return 0;
 	}
 
+	/* Even reads can crash X.org, so... */
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
 	status = video_outputsw_get();
 	if (status < 0)
 		return status;
@@ -4652,6 +4668,10 @@ static int video_write(char *buf)
 	if (video_supported == TPACPI_VIDEO_NONE)
 		return -ENODEV;
 
+	/* Even reads can crash X.org, let alone writes... */
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
 	enable = 0;
 	disable = 0;
 
@@ -6133,13 +6153,13 @@ static const struct tpacpi_quirk brightn
 	TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC),	/* T43/p ATI */
 
 	/* Models with ATI GPUs that can use ECNVRAM */
-	TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC),
+	TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC),	/* R50,51 T40-42 */
 	TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
-	TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
+	TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_EC),	/* R52 */
 	TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
 
 	/* Models with Intel Extreme Graphics 2 */
-	TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC),
+	TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC),	/* X40 */
 	TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
 	TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
 
@@ -6151,6 +6171,7 @@ static const struct tpacpi_quirk brightn
 
 static int __init brightness_init(struct ibm_init_struct *iibm)
 {
+	struct backlight_properties props;
 	int b;
 	unsigned long quirks;
 
@@ -6240,9 +6261,12 @@ static int __init brightness_init(struct
 		printk(TPACPI_INFO
 		       "detected a 16-level brightness capable ThinkPad\n");
 
-	ibm_backlight_device = backlight_device_register(
-					TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
-					&ibm_backlight_data);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = (tp_features.bright_16levels) ? 15 : 7;
+	ibm_backlight_device = backlight_device_register(TPACPI_BACKLIGHT_DEV_NAME,
+							 NULL, NULL,
+							 &ibm_backlight_data,
+							 &props);
 	if (IS_ERR(ibm_backlight_device)) {
 		int rc = PTR_ERR(ibm_backlight_device);
 		ibm_backlight_device = NULL;
@@ -6261,8 +6285,6 @@ static int __init brightness_init(struct
 			"or not on your ThinkPad\n", TPACPI_MAIL);
 	}
 
-	ibm_backlight_device->props.max_brightness =
-				(tp_features.bright_16levels)? 15 : 7;
 	ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
 	backlight_update_status(ibm_backlight_device);
 
@@ -6522,7 +6544,8 @@ static int volume_set_status(const u8 st
 	return volume_set_status_ec(status);
 }
 
-static int volume_set_mute_ec(const bool mute)
+/* returns < 0 on error, 0 on no change, 1 on change */
+static int __volume_set_mute_ec(const bool mute)
 {
 	int rc;
 	u8 s, n;
@@ -6537,22 +6560,37 @@ static int volume_set_mute_ec(const bool
 	n = (mute) ? s | TP_EC_AUDIO_MUTESW_MSK :
 		     s & ~TP_EC_AUDIO_MUTESW_MSK;
 
-	if (n != s)
+	if (n != s) {
 		rc = volume_set_status_ec(n);
+		if (!rc)
+			rc = 1;
+	}
 
 unlock:
 	mutex_unlock(&volume_mutex);
 	return rc;
 }
 
+static int volume_alsa_set_mute(const bool mute)
+{
+	dbg_printk(TPACPI_DBG_MIXER, "ALSA: trying to %smute\n",
+		   (mute) ? "" : "un");
+	return __volume_set_mute_ec(mute);
+}
+
 static int volume_set_mute(const bool mute)
 {
+	int rc;
+
 	dbg_printk(TPACPI_DBG_MIXER, "trying to %smute\n",
 		   (mute) ? "" : "un");
-	return volume_set_mute_ec(mute);
+
+	rc = __volume_set_mute_ec(mute);
+	return (rc < 0) ? rc : 0;
 }
 
-static int volume_set_volume_ec(const u8 vol)
+/* returns < 0 on error, 0 on no change, 1 on change */
+static int __volume_set_volume_ec(const u8 vol)
 {
 	int rc;
 	u8 s, n;
@@ -6569,19 +6607,22 @@ static int volume_set_volume_ec(const u8
 
 	n = (s & ~TP_EC_AUDIO_LVL_MSK) | vol;
 
-	if (n != s)
+	if (n != s) {
 		rc = volume_set_status_ec(n);
+		if (!rc)
+			rc = 1;
+	}
 
 unlock:
 	mutex_unlock(&volume_mutex);
 	return rc;
 }
 
-static int volume_set_volume(const u8 vol)
+static int volume_alsa_set_volume(const u8 vol)
 {
 	dbg_printk(TPACPI_DBG_MIXER,
-		   "trying to set volume level to %hu\n", vol);
-	return volume_set_volume_ec(vol);
+		   "ALSA: trying to set volume level to %hu\n", vol);
+	return __volume_set_volume_ec(vol);
 }
 
 static void volume_alsa_notify_change(void)
@@ -6628,7 +6669,7 @@ static int volume_alsa_vol_get(struct sn
 static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	return volume_set_volume(ucontrol->value.integer.value[0]);
+	return volume_alsa_set_volume(ucontrol->value.integer.value[0]);
 }
 
 #define volume_alsa_mute_info snd_ctl_boolean_mono_info
@@ -6651,7 +6692,7 @@ static int volume_alsa_mute_get(struct s
 static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	return volume_set_mute(!ucontrol->value.integer.value[0]);
+	return volume_alsa_set_mute(!ucontrol->value.integer.value[0]);
 }
 
 static struct snd_kcontrol_new volume_alsa_control_vol __devinitdata = {
@@ -7070,7 +7111,7 @@ static struct ibm_struct volume_driver_d
  *
  * 	Fan speed changes of any sort (including those caused by the
  * 	disengaged mode) are usually done slowly by the firmware as the
- * 	maximum ammount of fan duty cycle change per second seems to be
+ * 	maximum amount of fan duty cycle change per second seems to be
  * 	limited.
  *
  * 	Reading is not available if GFAN exists.
@@ -8477,9 +8518,10 @@ static int __init ibm_init(struct ibm_in
 		"%s installed\n", ibm->name);
 
 	if (ibm->read) {
-		mode_t mode;
+		mode_t mode = iibm->base_procfs_mode;
 
-		mode = S_IRUGO;
+		if (!mode)
+			mode = S_IRUGO;
 		if (ibm->write)
 			mode |= S_IWUSR;
 		entry = proc_create_data(ibm->name, mode, proc_dir,
@@ -8670,6 +8712,7 @@ static struct ibm_init_struct ibms_init[
 #ifdef CONFIG_THINKPAD_ACPI_VIDEO
 	{
 		.init = video_init,
+		.base_procfs_mode = S_IRUSR,
 		.data = &video_driver_data,
 	},
 #endif
@@ -9032,6 +9075,9 @@ static int __init thinkpad_acpi_module_i
 			return ret;
 		}
 	}
+
+	tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
+
 	ret = input_register_device(tpacpi_inputdev);
 	if (ret < 0) {
 		printk(TPACPI_ERR "unable to register input device\n");
@@ -9041,7 +9087,6 @@ static int __init thinkpad_acpi_module_i
 		tp_features.input_device_registered = 1;
 	}
 
-	tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/topstar-laptop.c linux-libre-2.6.34-gnu1/drivers/platform/x86/topstar-laptop.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/topstar-laptop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/topstar-laptop.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/acpi.h>
 #include <linux/input.h>
 
@@ -46,7 +47,7 @@ static struct tps_key_entry topstar_keym
 	{ }
 };
 
-static struct tps_key_entry *tps_get_key_by_scancode(int code)
+static struct tps_key_entry *tps_get_key_by_scancode(unsigned int code)
 {
 	struct tps_key_entry *key;
 
@@ -57,7 +58,7 @@ static struct tps_key_entry *tps_get_key
 	return NULL;
 }
 
-static struct tps_key_entry *tps_get_key_by_keycode(int code)
+static struct tps_key_entry *tps_get_key_by_keycode(unsigned int code)
 {
 	struct tps_key_entry *key;
 
@@ -126,7 +127,8 @@ static int acpi_topstar_fncx_switch(stru
 	return 0;
 }
 
-static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static int topstar_getkeycode(struct input_dev *dev,
+				unsigned int scancode, unsigned int *keycode)
 {
 	struct tps_key_entry *key = tps_get_key_by_scancode(scancode);
 
@@ -137,14 +139,12 @@ static int topstar_getkeycode(struct inp
 	return 0;
 }
 
-static int topstar_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int topstar_setkeycode(struct input_dev *dev,
+				unsigned int scancode, unsigned int keycode)
 {
 	struct tps_key_entry *key;
 	int old_keycode;
 
-	if (keycode < 0 || keycode > KEY_MAX)
-		return -EINVAL;
-
 	key = tps_get_key_by_scancode(scancode);
 
 	if (!key)
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/toshiba_acpi.c linux-libre-2.6.34-gnu1/drivers/platform/x86/toshiba_acpi.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/toshiba_acpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/toshiba_acpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,8 @@
 #include <linux/backlight.h>
 #include <linux/platform_device.h>
 #include <linux/rfkill.h>
+#include <linux/input.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
@@ -62,9 +64,10 @@ MODULE_LICENSE("GPL");
 
 /* Toshiba ACPI method paths */
 #define METHOD_LCD_BRIGHTNESS	"\\_SB_.PCI0.VGA_.LCD_._BCM"
-#define METHOD_HCI_1		"\\_SB_.VALD.GHCI"
-#define METHOD_HCI_2		"\\_SB_.VALZ.GHCI"
+#define TOSH_INTERFACE_1	"\\_SB_.VALD"
+#define TOSH_INTERFACE_2	"\\_SB_.VALZ"
 #define METHOD_VIDEO_OUT	"\\_SB_.VALX.DSSX"
+#define GHCI_METHOD		".GHCI"
 
 /* Toshiba HCI interface definitions
  *
@@ -116,6 +119,36 @@ static const struct acpi_device_id toshi
 };
 MODULE_DEVICE_TABLE(acpi, toshiba_device_ids);
 
+struct key_entry {
+	char type;
+	u16 code;
+	u16 keycode;
+};
+
+enum {KE_KEY, KE_END};
+
+static struct key_entry toshiba_acpi_keymap[]  = {
+	{KE_KEY, 0x101, KEY_MUTE},
+	{KE_KEY, 0x13b, KEY_COFFEE},
+	{KE_KEY, 0x13c, KEY_BATTERY},
+	{KE_KEY, 0x13d, KEY_SLEEP},
+	{KE_KEY, 0x13e, KEY_SUSPEND},
+	{KE_KEY, 0x13f, KEY_SWITCHVIDEOMODE},
+	{KE_KEY, 0x140, KEY_BRIGHTNESSDOWN},
+	{KE_KEY, 0x141, KEY_BRIGHTNESSUP},
+	{KE_KEY, 0x142, KEY_WLAN},
+	{KE_KEY, 0x143, KEY_PROG1},
+	{KE_KEY, 0xb05, KEY_PROG2},
+	{KE_KEY, 0xb06, KEY_WWW},
+	{KE_KEY, 0xb07, KEY_MAIL},
+	{KE_KEY, 0xb30, KEY_STOP},
+	{KE_KEY, 0xb31, KEY_PREVIOUSSONG},
+	{KE_KEY, 0xb32, KEY_NEXTSONG},
+	{KE_KEY, 0xb33, KEY_PLAYPAUSE},
+	{KE_KEY, 0xb5a, KEY_MEDIA},
+	{KE_END, 0, 0},
+};
+
 /* utility
  */
 
@@ -251,6 +284,8 @@ static acpi_status hci_read2(u32 reg, u3
 struct toshiba_acpi_dev {
 	struct platform_device *p_dev;
 	struct rfkill *bt_rfk;
+	struct input_dev *hotkey_dev;
+	acpi_handle handle;
 
 	const char *bt_name;
 
@@ -711,8 +746,158 @@ static struct backlight_ops toshiba_back
         .update_status  = set_lcd_status,
 };
 
+static struct key_entry *toshiba_acpi_get_entry_by_scancode(unsigned int code)
+{
+	struct key_entry *key;
+
+	for (key = toshiba_acpi_keymap; key->type != KE_END; key++)
+		if (code == key->code)
+			return key;
+
+	return NULL;
+}
+
+static struct key_entry *toshiba_acpi_get_entry_by_keycode(unsigned int code)
+{
+	struct key_entry *key;
+
+	for (key = toshiba_acpi_keymap; key->type != KE_END; key++)
+		if (code == key->keycode && key->type == KE_KEY)
+			return key;
+
+	return NULL;
+}
+
+static int toshiba_acpi_getkeycode(struct input_dev *dev,
+				   unsigned int scancode, unsigned int *keycode)
+{
+	struct key_entry *key = toshiba_acpi_get_entry_by_scancode(scancode);
+
+	if (key && key->type == KE_KEY) {
+		*keycode = key->keycode;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int toshiba_acpi_setkeycode(struct input_dev *dev,
+				   unsigned int scancode, unsigned int keycode)
+{
+	struct key_entry *key;
+	unsigned int old_keycode;
+
+	key = toshiba_acpi_get_entry_by_scancode(scancode);
+	if (key && key->type == KE_KEY) {
+		old_keycode = key->keycode;
+		key->keycode = keycode;
+		set_bit(keycode, dev->keybit);
+		if (!toshiba_acpi_get_entry_by_keycode(old_keycode))
+			clear_bit(old_keycode, dev->keybit);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context)
+{
+	u32 hci_result, value;
+	struct key_entry *key;
+
+	if (event != 0x80)
+		return;
+	do {
+		hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result);
+		if (hci_result == HCI_SUCCESS) {
+			if (value == 0x100)
+				continue;
+			/* act on key press; ignore key release */
+			if (value & 0x80)
+				continue;
+
+			key = toshiba_acpi_get_entry_by_scancode
+				(value);
+			if (!key) {
+				printk(MY_INFO "Unknown key %x\n",
+				       value);
+				continue;
+			}
+			input_report_key(toshiba_acpi.hotkey_dev,
+					 key->keycode, 1);
+			input_sync(toshiba_acpi.hotkey_dev);
+			input_report_key(toshiba_acpi.hotkey_dev,
+					 key->keycode, 0);
+			input_sync(toshiba_acpi.hotkey_dev);
+		} else if (hci_result == HCI_NOT_SUPPORTED) {
+			/* This is a workaround for an unresolved issue on
+			 * some machines where system events sporadically
+			 * become disabled. */
+			hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result);
+			printk(MY_NOTICE "Re-enabled hotkeys\n");
+		}
+	} while (hci_result != HCI_EMPTY);
+}
+
+static int toshiba_acpi_setup_keyboard(char *device)
+{
+	acpi_status status;
+	acpi_handle handle;
+	int result;
+	const struct key_entry *key;
+
+	status = acpi_get_handle(NULL, device, &handle);
+	if (ACPI_FAILURE(status)) {
+		printk(MY_INFO "Unable to get notification device\n");
+		return -ENODEV;
+	}
+
+	toshiba_acpi.handle = handle;
+
+	status = acpi_evaluate_object(handle, "ENAB", NULL, NULL);
+	if (ACPI_FAILURE(status)) {
+		printk(MY_INFO "Unable to enable hotkeys\n");
+		return -ENODEV;
+	}
+
+	status = acpi_install_notify_handler(handle, ACPI_DEVICE_NOTIFY,
+					      toshiba_acpi_notify, NULL);
+	if (ACPI_FAILURE(status)) {
+		printk(MY_INFO "Unable to install hotkey notification\n");
+		return -ENODEV;
+	}
+
+	toshiba_acpi.hotkey_dev = input_allocate_device();
+	if (!toshiba_acpi.hotkey_dev) {
+		printk(MY_INFO "Unable to register input device\n");
+		return -ENOMEM;
+	}
+
+	toshiba_acpi.hotkey_dev->name = "Toshiba input device";
+	toshiba_acpi.hotkey_dev->phys = device;
+	toshiba_acpi.hotkey_dev->id.bustype = BUS_HOST;
+	toshiba_acpi.hotkey_dev->getkeycode = toshiba_acpi_getkeycode;
+	toshiba_acpi.hotkey_dev->setkeycode = toshiba_acpi_setkeycode;
+
+	for (key = toshiba_acpi_keymap; key->type != KE_END; key++) {
+		set_bit(EV_KEY, toshiba_acpi.hotkey_dev->evbit);
+		set_bit(key->keycode, toshiba_acpi.hotkey_dev->keybit);
+	}
+
+	result = input_register_device(toshiba_acpi.hotkey_dev);
+	if (result) {
+		printk(MY_INFO "Unable to register input device\n");
+		return result;
+	}
+
+	return 0;
+}
+
 static void toshiba_acpi_exit(void)
 {
+	if (toshiba_acpi.hotkey_dev)
+		input_unregister_device(toshiba_acpi.hotkey_dev);
+
 	if (toshiba_acpi.bt_rfk) {
 		rfkill_unregister(toshiba_acpi.bt_rfk);
 		rfkill_destroy(toshiba_acpi.bt_rfk);
@@ -726,6 +911,9 @@ static void toshiba_acpi_exit(void)
 	if (toshiba_proc_dir)
 		remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
 
+	acpi_remove_notify_handler(toshiba_acpi.handle, ACPI_DEVICE_NOTIFY,
+				   toshiba_acpi_notify);
+
 	platform_device_unregister(toshiba_acpi.p_dev);
 
 	return;
@@ -737,16 +925,21 @@ static int __init toshiba_acpi_init(void
 	u32 hci_result;
 	bool bt_present;
 	int ret = 0;
+	struct backlight_properties props;
 
 	if (acpi_disabled)
 		return -ENODEV;
 
 	/* simple device detection: look for HCI method */
-	if (is_valid_acpi_path(METHOD_HCI_1))
-		method_hci = METHOD_HCI_1;
-	else if (is_valid_acpi_path(METHOD_HCI_2))
-		method_hci = METHOD_HCI_2;
-	else
+	if (is_valid_acpi_path(TOSH_INTERFACE_1 GHCI_METHOD)) {
+		method_hci = TOSH_INTERFACE_1 GHCI_METHOD;
+		if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_1))
+			printk(MY_INFO "Unable to activate hotkeys\n");
+	} else if (is_valid_acpi_path(TOSH_INTERFACE_2 GHCI_METHOD)) {
+		method_hci = TOSH_INTERFACE_2 GHCI_METHOD;
+		if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_2))
+			printk(MY_INFO "Unable to activate hotkeys\n");
+	} else
 		return -ENODEV;
 
 	printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n",
@@ -783,10 +976,12 @@ static int __init toshiba_acpi_init(void
 		}
 	}
 
+	props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
 	toshiba_backlight_device = backlight_device_register("toshiba",
-						&toshiba_acpi.p_dev->dev,
-						NULL,
-						&toshiba_backlight_data);
+							     &toshiba_acpi.p_dev->dev,
+							     NULL,
+							     &toshiba_backlight_data,
+							     &props);
         if (IS_ERR(toshiba_backlight_device)) {
 		ret = PTR_ERR(toshiba_backlight_device);
 
@@ -795,7 +990,6 @@ static int __init toshiba_acpi_init(void
 		toshiba_acpi_exit();
 		return ret;
 	}
-        toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
 
 	/* Register rfkill switch for Bluetooth */
 	if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/toshiba_bluetooth.c linux-libre-2.6.34-gnu1/drivers/platform/x86/toshiba_bluetooth.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/toshiba_bluetooth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/toshiba_bluetooth.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,7 +57,7 @@ static struct acpi_driver toshiba_bt_rfk
 static int toshiba_bluetooth_enable(acpi_handle handle)
 {
 	acpi_status res1, res2;
-	acpi_integer result;
+	u64 result;
 
 	/*
 	 * Query ACPI to verify RFKill switch is set to 'on'.
@@ -95,7 +95,7 @@ static int toshiba_bt_resume(struct acpi
 static int toshiba_bt_rfkill_add(struct acpi_device *device)
 {
 	acpi_status status;
-	acpi_integer bt_present;
+	u64 bt_present;
 	int result = -ENODEV;
 
 	/*
diff -druNp linux-libre-2.6.33-gnu1/drivers/platform/x86/wmi.c linux-libre-2.6.34-gnu1/drivers/platform/x86/wmi.c
--- linux-libre-2.6.33-gnu1/drivers/platform/x86/wmi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/platform/x86/wmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/device.h>
 #include <linux/list.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -796,7 +797,7 @@ static __init acpi_status parse_wdg(acpi
  */
 static acpi_status
 acpi_wmi_ec_space_handler(u32 function, acpi_physical_address address,
-		      u32 bits, acpi_integer * value,
+		      u32 bits, u64 *value,
 		      void *handler_context, void *region_context)
 {
 	int result = 0, i = 0;
@@ -813,7 +814,7 @@ acpi_wmi_ec_space_handler(u32 function,
 
 	if (function == ACPI_READ) {
 		result = ec_read(address, &temp);
-		(*value) |= ((acpi_integer)temp) << i;
+		(*value) |= ((u64)temp) << i;
 	} else {
 		temp = 0xff & ((*value) >> i);
 		result = ec_write(address, temp);
diff -druNp linux-libre-2.6.33-gnu1/drivers/pnp/base.h linux-libre-2.6.34-gnu1/drivers/pnp/base.h
--- linux-libre-2.6.33-gnu1/drivers/pnp/base.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pnp/base.h	2010-05-16 17:17:36.000000000 -0400
@@ -166,6 +166,9 @@ struct pnp_resource *pnp_add_io_resource
 struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
 					  resource_size_t start,
 					  resource_size_t end, int flags);
+struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev,
+					  resource_size_t start,
+					  resource_size_t end);
 
 extern int pnp_debug;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pnp/interface.c linux-libre-2.6.34-gnu1/drivers/pnp/interface.c
--- linux-libre-2.6.33-gnu1/drivers/pnp/interface.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pnp/interface.c	2010-05-16 17:17:36.000000000 -0400
@@ -278,9 +278,12 @@ static ssize_t pnp_show_current_resource
 		switch (pnp_resource_type(res)) {
 		case IORESOURCE_IO:
 		case IORESOURCE_MEM:
-			pnp_printf(buffer, " %#llx-%#llx\n",
+		case IORESOURCE_BUS:
+			pnp_printf(buffer, " %#llx-%#llx%s\n",
 				   (unsigned long long) res->start,
-				   (unsigned long long) res->end);
+				   (unsigned long long) res->end,
+				   res->flags & IORESOURCE_WINDOW ?
+					" window" : "");
 			break;
 		case IORESOURCE_IRQ:
 		case IORESOURCE_DMA:
diff -druNp linux-libre-2.6.33-gnu1/drivers/pnp/isapnp/core.c linux-libre-2.6.34-gnu1/drivers/pnp/isapnp/core.c
--- linux-libre-2.6.33-gnu1/drivers/pnp/isapnp/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pnp/isapnp/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,7 +37,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/isapnp.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/pnp/manager.c linux-libre-2.6.34-gnu1/drivers/pnp/manager.c
--- linux-libre-2.6.33-gnu1/drivers/pnp/manager.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pnp/manager.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/pnp.h>
-#include <linux/slab.h>
 #include <linux/bitmap.h>
 #include <linux/mutex.h>
 #include "base.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/pnp/pnpacpi/core.c linux-libre-2.6.34-gnu1/drivers/pnp/pnpacpi/core.c
--- linux-libre-2.6.33-gnu1/drivers/pnp/pnpacpi/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pnp/pnpacpi/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 
 #include <linux/acpi.h>
 #include <linux/pnp.h>
+#include <linux/slab.h>
 #include <linux/mod_devicetable.h>
 #include <acpi/acpi_bus.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/pnp/pnpacpi/rsparser.c linux-libre-2.6.34-gnu1/drivers/pnp/pnpacpi/rsparser.c
--- linux-libre-2.6.33-gnu1/drivers/pnp/pnpacpi/rsparser.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pnp/pnpacpi/rsparser.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/acpi.h>
 #include <linux/pci.h>
 #include <linux/pnp.h>
+#include <linux/slab.h>
 #include "../base.h"
 #include "pnpacpi.h"
 
@@ -177,7 +178,8 @@ static int dma_flags(struct pnp_dev *dev
 }
 
 static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
-					       u64 len, int io_decode)
+					       u64 len, int io_decode,
+					       int window)
 {
 	int flags = 0;
 	u64 end = start + len - 1;
@@ -186,6 +188,8 @@ static void pnpacpi_parse_allocated_iore
 		flags |= IORESOURCE_IO_16BIT_ADDR;
 	if (len == 0 || end >= 0x10003)
 		flags |= IORESOURCE_DISABLED;
+	if (window)
+		flags |= IORESOURCE_WINDOW;
 
 	pnp_add_io_resource(dev, start, end, flags);
 }
@@ -247,7 +251,7 @@ static void pnpacpi_parse_allocated_vend
 
 static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
 						u64 start, u64 len,
-						int write_protect)
+						int write_protect, int window)
 {
 	int flags = 0;
 	u64 end = start + len - 1;
@@ -256,15 +260,27 @@ static void pnpacpi_parse_allocated_memr
 		flags |= IORESOURCE_DISABLED;
 	if (write_protect == ACPI_READ_WRITE_MEMORY)
 		flags |= IORESOURCE_MEM_WRITEABLE;
+	if (window)
+		flags |= IORESOURCE_WINDOW;
 
 	pnp_add_mem_resource(dev, start, end, flags);
 }
 
+static void pnpacpi_parse_allocated_busresource(struct pnp_dev *dev,
+						u64 start, u64 len)
+{
+	u64 end = start + len - 1;
+
+	pnp_add_bus_resource(dev, start, end);
+}
+
 static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
 						  struct acpi_resource *res)
 {
 	struct acpi_resource_address64 addr, *p = &addr;
 	acpi_status status;
+	int window;
+	u64 len;
 
 	status = acpi_resource_to_address64(res, p);
 	if (!ACPI_SUCCESS(status)) {
@@ -273,37 +289,41 @@ static void pnpacpi_parse_allocated_addr
 		return;
 	}
 
-	if (p->producer_consumer == ACPI_PRODUCER)
-		return;
+	/* Windows apparently computes length rather than using _LEN */
+	len = p->maximum - p->minimum + 1;
+	window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
 
 	if (p->resource_type == ACPI_MEMORY_RANGE)
-		pnpacpi_parse_allocated_memresource(dev,
-			p->minimum, p->address_length,
-			p->info.mem.write_protect);
+		pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
+			p->info.mem.write_protect, window);
 	else if (p->resource_type == ACPI_IO_RANGE)
-		pnpacpi_parse_allocated_ioresource(dev,
-			p->minimum, p->address_length,
+		pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
 			p->granularity == 0xfff ? ACPI_DECODE_10 :
-				ACPI_DECODE_16);
+				ACPI_DECODE_16, window);
+	else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
+		pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
 }
 
 static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
 						      struct acpi_resource *res)
 {
 	struct acpi_resource_extended_address64 *p = &res->data.ext_address64;
+	int window;
+	u64 len;
 
-	if (p->producer_consumer == ACPI_PRODUCER)
-		return;
+	/* Windows apparently computes length rather than using _LEN */
+	len = p->maximum - p->minimum + 1;
+	window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
 
 	if (p->resource_type == ACPI_MEMORY_RANGE)
-		pnpacpi_parse_allocated_memresource(dev,
-			p->minimum, p->address_length,
-			p->info.mem.write_protect);
+		pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
+			p->info.mem.write_protect, window);
 	else if (p->resource_type == ACPI_IO_RANGE)
-		pnpacpi_parse_allocated_ioresource(dev,
-			p->minimum, p->address_length,
+		pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
 			p->granularity == 0xfff ? ACPI_DECODE_10 :
-				ACPI_DECODE_16);
+				ACPI_DECODE_16, window);
+	else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
+		pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
 }
 
 static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
@@ -368,7 +388,7 @@ static acpi_status pnpacpi_allocated_res
 		pnpacpi_parse_allocated_ioresource(dev,
 			io->minimum,
 			io->address_length,
-			io->io_decode);
+			io->io_decode, 0);
 		break;
 
 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -380,7 +400,7 @@ static acpi_status pnpacpi_allocated_res
 		pnpacpi_parse_allocated_ioresource(dev,
 			fixed_io->address,
 			fixed_io->address_length,
-			ACPI_DECODE_10);
+			ACPI_DECODE_10, 0);
 		break;
 
 	case ACPI_RESOURCE_TYPE_VENDOR:
@@ -396,21 +416,21 @@ static acpi_status pnpacpi_allocated_res
 		pnpacpi_parse_allocated_memresource(dev,
 			memory24->minimum,
 			memory24->address_length,
-			memory24->write_protect);
+			memory24->write_protect, 0);
 		break;
 	case ACPI_RESOURCE_TYPE_MEMORY32:
 		memory32 = &res->data.memory32;
 		pnpacpi_parse_allocated_memresource(dev,
 			memory32->minimum,
 			memory32->address_length,
-			memory32->write_protect);
+			memory32->write_protect, 0);
 		break;
 	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
 		fixed_memory32 = &res->data.fixed_memory32;
 		pnpacpi_parse_allocated_memresource(dev,
 			fixed_memory32->address,
 			fixed_memory32->address_length,
-			fixed_memory32->write_protect);
+			fixed_memory32->write_protect, 0);
 		break;
 	case ACPI_RESOURCE_TYPE_ADDRESS16:
 	case ACPI_RESOURCE_TYPE_ADDRESS32:
diff -druNp linux-libre-2.6.33-gnu1/drivers/pnp/pnpbios/bioscalls.c linux-libre-2.6.34-gnu1/drivers/pnp/pnpbios/bioscalls.c
--- linux-libre-2.6.33-gnu1/drivers/pnp/pnpbios/bioscalls.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pnp/pnpbios/bioscalls.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,6 @@
 #include <linux/pnp.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/completion.h>
 #include <linux/spinlock.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/pnp/pnpbios/rsparser.c linux-libre-2.6.34-gnu1/drivers/pnp/pnpbios/rsparser.c
--- linux-libre-2.6.33-gnu1/drivers/pnp/pnpbios/rsparser.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pnp/pnpbios/rsparser.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,6 @@
 #include <linux/ctype.h>
 #include <linux/pnp.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 
 #ifdef CONFIG_PCI
 #include <linux/pci.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/pnp/resource.c linux-libre-2.6.34-gnu1/drivers/pnp/resource.c
--- linux-libre-2.6.33-gnu1/drivers/pnp/resource.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pnp/resource.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
@@ -210,6 +211,8 @@ int pnp_check_port(struct pnp_dev *dev,
 			if (tres->flags & IORESOURCE_IO) {
 				if (cannot_compare(tres->flags))
 					continue;
+				if (tres->flags & IORESOURCE_WINDOW)
+					continue;
 				tport = &tres->start;
 				tend = &tres->end;
 				if (ranged_conflict(port, end, tport, tend))
@@ -270,6 +273,8 @@ int pnp_check_mem(struct pnp_dev *dev, s
 			if (tres->flags & IORESOURCE_MEM) {
 				if (cannot_compare(tres->flags))
 					continue;
+				if (tres->flags & IORESOURCE_WINDOW)
+					continue;
 				taddr = &tres->start;
 				tend = &tres->end;
 				if (ranged_conflict(addr, end, taddr, tend))
@@ -470,7 +475,8 @@ int pnp_check_dma(struct pnp_dev *dev, s
 unsigned long pnp_resource_type(struct resource *res)
 {
 	return res->flags & (IORESOURCE_IO  | IORESOURCE_MEM |
-			     IORESOURCE_IRQ | IORESOURCE_DMA);
+			     IORESOURCE_IRQ | IORESOURCE_DMA |
+			     IORESOURCE_BUS);
 }
 
 struct resource *pnp_get_resource(struct pnp_dev *dev,
@@ -586,6 +592,30 @@ struct pnp_resource *pnp_add_mem_resourc
 	res->start = start;
 	res->end = end;
 
+	pnp_dbg(&dev->dev, "  add %pr\n", res);
+	return pnp_res;
+}
+
+struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev,
+					  resource_size_t start,
+					  resource_size_t end)
+{
+	struct pnp_resource *pnp_res;
+	struct resource *res;
+
+	pnp_res = pnp_new_resource(dev);
+	if (!pnp_res) {
+		dev_err(&dev->dev, "can't add resource for BUS %#llx-%#llx\n",
+			(unsigned long long) start,
+			(unsigned long long) end);
+		return NULL;
+	}
+
+	res = &pnp_res->res;
+	res->flags = IORESOURCE_BUS;
+	res->start = start;
+	res->end = end;
+
 	pnp_dbg(&dev->dev, "  add %pr\n", res);
 	return pnp_res;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/pnp/support.c linux-libre-2.6.34-gnu1/drivers/pnp/support.c
--- linux-libre-2.6.33-gnu1/drivers/pnp/support.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pnp/support.c	2010-05-16 17:17:36.000000000 -0400
@@ -69,8 +69,10 @@ char *pnp_resource_type_name(struct reso
 		return "irq";
 	case IORESOURCE_DMA:
 		return "dma";
+	case IORESOURCE_BUS:
+		return "bus";
 	}
-	return NULL;
+	return "unknown";
 }
 
 void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/bq27x00_battery.c linux-libre-2.6.34-gnu1/drivers/power/bq27x00_battery.c
--- linux-libre-2.6.33-gnu1/drivers/power/bq27x00_battery.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/bq27x00_battery.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,15 +24,25 @@
 #include <linux/power_supply.h>
 #include <linux/idr.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
-#define DRIVER_VERSION			"1.0.0"
+#define DRIVER_VERSION			"1.1.0"
 
 #define BQ27x00_REG_TEMP		0x06
 #define BQ27x00_REG_VOLT		0x08
-#define BQ27x00_REG_RSOC		0x0B /* Relative State-of-Charge */
 #define BQ27x00_REG_AI			0x14
 #define BQ27x00_REG_FLAGS		0x0A
+#define BQ27x00_REG_TTE			0x16
+#define BQ27x00_REG_TTF			0x18
+#define BQ27x00_REG_TTECP		0x26
+
+#define BQ27000_REG_RSOC		0x0B /* Relative State-of-Charge */
+#define BQ27000_FLAG_CHGS		BIT(7)
+
+#define BQ27500_REG_SOC			0x2c
+#define BQ27500_FLAG_DSC		BIT(0)
+#define BQ27500_FLAG_FC			BIT(9)
 
 /* If the system has several batteries we need a different name for each
  * of them...
@@ -46,25 +56,28 @@ struct bq27x00_access_methods {
 		struct bq27x00_device_info *di);
 };
 
+enum bq27x00_chip { BQ27000, BQ27500 };
+
 struct bq27x00_device_info {
 	struct device 		*dev;
 	int			id;
-	int			voltage_uV;
-	int			current_uA;
-	int			temp_C;
-	int			charge_rsoc;
 	struct bq27x00_access_methods	*bus;
 	struct power_supply	bat;
+	enum bq27x00_chip	chip;
 
 	struct i2c_client	*client;
 };
 
 static enum power_supply_property bq27x00_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
 	POWER_SUPPLY_PROP_CAPACITY,
 	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
+	POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
+	POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
 };
 
 /*
@@ -74,16 +87,11 @@ static enum power_supply_property bq27x0
 static int bq27x00_read(u8 reg, int *rt_value, int b_single,
 			struct bq27x00_device_info *di)
 {
-	int ret;
-
-	ret = di->bus->read(reg, rt_value, b_single, di);
-	*rt_value = be16_to_cpu(*rt_value);
-
-	return ret;
+	return di->bus->read(reg, rt_value, b_single, di);
 }
 
 /*
- * Return the battery temperature in Celsius degrees
+ * Return the battery temperature in tenths of degree Celsius
  * Or < 0 if something fails.
  */
 static int bq27x00_battery_temperature(struct bq27x00_device_info *di)
@@ -97,7 +105,10 @@ static int bq27x00_battery_temperature(s
 		return ret;
 	}
 
-	return (temp >> 2) - 273;
+	if (di->chip == BQ27500)
+		return temp - 2731;
+	else
+		return ((temp >> 2) - 273) * 10;
 }
 
 /*
@@ -115,7 +126,7 @@ static int bq27x00_battery_voltage(struc
 		return ret;
 	}
 
-	return volt;
+	return volt * 1000;
 }
 
 /*
@@ -134,16 +145,23 @@ static int bq27x00_battery_current(struc
 		dev_err(di->dev, "error reading current\n");
 		return 0;
 	}
-	ret = bq27x00_read(BQ27x00_REG_FLAGS, &flags, 0, di);
-	if (ret < 0) {
-		dev_err(di->dev, "error reading flags\n");
-		return 0;
-	}
-	if ((flags & (1 << 7)) != 0) {
-		dev_dbg(di->dev, "negative current!\n");
-		return -curr;
+
+	if (di->chip == BQ27500) {
+		/* bq27500 returns signed value */
+		curr = (int)(s16)curr;
+	} else {
+		ret = bq27x00_read(BQ27x00_REG_FLAGS, &flags, 0, di);
+		if (ret < 0) {
+			dev_err(di->dev, "error reading flags\n");
+			return 0;
+		}
+		if (flags & BQ27000_FLAG_CHGS) {
+			dev_dbg(di->dev, "negative current!\n");
+			curr = -curr;
+		}
 	}
-	return curr;
+
+	return curr * 1000;
 }
 
 /*
@@ -155,13 +173,70 @@ static int bq27x00_battery_rsoc(struct b
 	int ret;
 	int rsoc = 0;
 
-	ret = bq27x00_read(BQ27x00_REG_RSOC, &rsoc, 1, di);
+	if (di->chip == BQ27500)
+		ret = bq27x00_read(BQ27500_REG_SOC, &rsoc, 0, di);
+	else
+		ret = bq27x00_read(BQ27000_REG_RSOC, &rsoc, 1, di);
 	if (ret) {
 		dev_err(di->dev, "error reading relative State-of-Charge\n");
 		return ret;
 	}
 
-	return rsoc >> 8;
+	return rsoc;
+}
+
+static int bq27x00_battery_status(struct bq27x00_device_info *di,
+				  union power_supply_propval *val)
+{
+	int flags = 0;
+	int status;
+	int ret;
+
+	ret = bq27x00_read(BQ27x00_REG_FLAGS, &flags, 0, di);
+	if (ret < 0) {
+		dev_err(di->dev, "error reading flags\n");
+		return ret;
+	}
+
+	if (di->chip == BQ27500) {
+		if (flags & BQ27500_FLAG_FC)
+			status = POWER_SUPPLY_STATUS_FULL;
+		else if (flags & BQ27500_FLAG_DSC)
+			status = POWER_SUPPLY_STATUS_DISCHARGING;
+		else
+			status = POWER_SUPPLY_STATUS_CHARGING;
+	} else {
+		if (flags & BQ27000_FLAG_CHGS)
+			status = POWER_SUPPLY_STATUS_CHARGING;
+		else
+			status = POWER_SUPPLY_STATUS_DISCHARGING;
+	}
+
+	val->intval = status;
+	return 0;
+}
+
+/*
+ * Read a time register.
+ * Return < 0 if something fails.
+ */
+static int bq27x00_battery_time(struct bq27x00_device_info *di, int reg,
+				union power_supply_propval *val)
+{
+	int tval = 0;
+	int ret;
+
+	ret = bq27x00_read(reg, &tval, 0, di);
+	if (ret) {
+		dev_err(di->dev, "error reading register %02x\n", reg);
+		return ret;
+	}
+
+	if (tval == 65535)
+		return -ENODATA;
+
+	val->intval = tval * 60;
+	return 0;
 }
 
 #define to_bq27x00_device_info(x) container_of((x), \
@@ -171,9 +246,13 @@ static int bq27x00_battery_get_property(
 					enum power_supply_property psp,
 					union power_supply_propval *val)
 {
+	int ret = 0;
 	struct bq27x00_device_info *di = to_bq27x00_device_info(psy);
 
 	switch (psp) {
+	case POWER_SUPPLY_PROP_STATUS:
+		ret = bq27x00_battery_status(di, val);
+		break;
 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 	case POWER_SUPPLY_PROP_PRESENT:
 		val->intval = bq27x00_battery_voltage(di);
@@ -189,11 +268,20 @@ static int bq27x00_battery_get_property(
 	case POWER_SUPPLY_PROP_TEMP:
 		val->intval = bq27x00_battery_temperature(di);
 		break;
+	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
+		ret = bq27x00_battery_time(di, BQ27x00_REG_TTE, val);
+		break;
+	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
+		ret = bq27x00_battery_time(di, BQ27x00_REG_TTECP, val);
+		break;
+	case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
+		ret = bq27x00_battery_time(di, BQ27x00_REG_TTF, val);
+		break;
 	default:
 		return -EINVAL;
 	}
 
-	return 0;
+	return ret;
 }
 
 static void bq27x00_powersupply_init(struct bq27x00_device_info *di)
@@ -206,10 +294,10 @@ static void bq27x00_powersupply_init(str
 }
 
 /*
- * BQ27200 specific code
+ * i2c specific code
  */
 
-static int bq27200_read(u8 reg, int *rt_value, int b_single,
+static int bq27x00_read_i2c(u8 reg, int *rt_value, int b_single,
 			struct bq27x00_device_info *di)
 {
 	struct i2c_client *client = di->client;
@@ -238,7 +326,7 @@ static int bq27200_read(u8 reg, int *rt_
 		err = i2c_transfer(client->adapter, msg, 1);
 		if (err >= 0) {
 			if (!b_single)
-				*rt_value = get_unaligned_be16(data);
+				*rt_value = get_unaligned_le16(data);
 			else
 				*rt_value = data[0];
 
@@ -248,7 +336,7 @@ static int bq27200_read(u8 reg, int *rt_
 	return err;
 }
 
-static int bq27200_battery_probe(struct i2c_client *client,
+static int bq27x00_battery_probe(struct i2c_client *client,
 				 const struct i2c_device_id *id)
 {
 	char *name;
@@ -267,7 +355,7 @@ static int bq27200_battery_probe(struct
 	if (retval < 0)
 		return retval;
 
-	name = kasprintf(GFP_KERNEL, "bq27200-%d", num);
+	name = kasprintf(GFP_KERNEL, "%s-%d", id->name, num);
 	if (!name) {
 		dev_err(&client->dev, "failed to allocate device name\n");
 		retval = -ENOMEM;
@@ -281,6 +369,7 @@ static int bq27200_battery_probe(struct
 		goto batt_failed_2;
 	}
 	di->id = num;
+	di->chip = id->driver_data;
 
 	bus = kzalloc(sizeof(*bus), GFP_KERNEL);
 	if (!bus) {
@@ -293,7 +382,7 @@ static int bq27200_battery_probe(struct
 	i2c_set_clientdata(client, di);
 	di->dev = &client->dev;
 	di->bat.name = name;
-	bus->read = &bq27200_read;
+	bus->read = &bq27x00_read_i2c;
 	di->bus = bus;
 	di->client = client;
 
@@ -323,7 +412,7 @@ batt_failed_1:
 	return retval;
 }
 
-static int bq27200_battery_remove(struct i2c_client *client)
+static int bq27x00_battery_remove(struct i2c_client *client)
 {
 	struct bq27x00_device_info *di = i2c_get_clientdata(client);
 
@@ -344,27 +433,28 @@ static int bq27200_battery_remove(struct
  * Module stuff
  */
 
-static const struct i2c_device_id bq27200_id[] = {
-	{ "bq27200", 0 },
+static const struct i2c_device_id bq27x00_id[] = {
+	{ "bq27200", BQ27000 },	/* bq27200 is same as bq27000, but with i2c */
+	{ "bq27500", BQ27500 },
 	{},
 };
 
-static struct i2c_driver bq27200_battery_driver = {
+static struct i2c_driver bq27x00_battery_driver = {
 	.driver = {
-		.name = "bq27200-battery",
+		.name = "bq27x00-battery",
 	},
-	.probe = bq27200_battery_probe,
-	.remove = bq27200_battery_remove,
-	.id_table = bq27200_id,
+	.probe = bq27x00_battery_probe,
+	.remove = bq27x00_battery_remove,
+	.id_table = bq27x00_id,
 };
 
 static int __init bq27x00_battery_init(void)
 {
 	int ret;
 
-	ret = i2c_add_driver(&bq27200_battery_driver);
+	ret = i2c_add_driver(&bq27x00_battery_driver);
 	if (ret)
-		printk(KERN_ERR "Unable to register BQ27200 driver\n");
+		printk(KERN_ERR "Unable to register BQ27x00 driver\n");
 
 	return ret;
 }
@@ -372,7 +462,7 @@ module_init(bq27x00_battery_init);
 
 static void __exit bq27x00_battery_exit(void)
 {
-	i2c_del_driver(&bq27200_battery_driver);
+	i2c_del_driver(&bq27x00_battery_driver);
 }
 module_exit(bq27x00_battery_exit);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/da9030_battery.c linux-libre-2.6.34-gnu1/drivers/power/da9030_battery.c
--- linux-libre-2.6.33-gnu1/drivers/power/da9030_battery.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/da9030_battery.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/device.h>
@@ -509,7 +510,7 @@ static int da9030_battery_probe(struct p
 
 	charger->master = pdev->dev.parent;
 
-	/* 10 seconds between monotor runs unless platfrom defines other
+	/* 10 seconds between monitor runs unless platform defines other
 	   interval */
 	charger->interval = msecs_to_jiffies(
 		(pdata->batmon_interval ? : 10) * 1000);
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/ds2760_battery.c linux-libre-2.6.34-gnu1/drivers/power/ds2760_battery.c
--- linux-libre-2.6.33-gnu1/drivers/power/ds2760_battery.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/ds2760_battery.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/jiffies.h>
 #include <linux/workqueue.h>
 #include <linux/pm.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/ds2782_battery.c linux-libre-2.6.34-gnu1/drivers/power/ds2782_battery.c
--- linux-libre-2.6.33-gnu1/drivers/power/ds2782_battery.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/ds2782_battery.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/idr.h>
 #include <linux/power_supply.h>
+#include <linux/slab.h>
 
 #define DS2782_REG_RARC		0x06	/* Remaining active relative capacity */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/Kconfig linux-libre-2.6.34-gnu1/drivers/power/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/power/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,13 @@ config APM_POWER
 	  Say Y here to enable support APM status emulation using
 	  battery class devices.
 
+config MAX8925_POWER
+	tristate "MAX8925 battery charger support"
+	depends on MFD_MAX8925
+	help
+	  Say Y here to enable support for the battery charger in the Maxim
+	  MAX8925 PMIC.
+
 config WM831X_BACKUP
 	tristate "WM831X backup battery charger support"
 	depends on MFD_WM831X
@@ -98,10 +105,10 @@ config BATTERY_WM97XX
 	  Say Y to enable support for battery measured by WM97xx aux port.
 
 config BATTERY_BQ27x00
-	tristate "BQ27200 battery driver"
+	tristate "BQ27x00 battery driver"
 	depends on I2C
 	help
-	  Say Y here to enable support for batteries with BQ27200(I2C) chip.
+	  Say Y here to enable support for batteries with BQ27x00 (I2C) chips.
 
 config BATTERY_DA9030
 	tristate "DA9030 battery driver"
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/Makefile linux-libre-2.6.34-gnu1/drivers/power/Makefile
--- linux-libre-2.6.33-gnu1/drivers/power/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@ obj-$(CONFIG_POWER_SUPPLY)	+= power_supp
 
 obj-$(CONFIG_PDA_POWER)		+= pda_power.o
 obj-$(CONFIG_APM_POWER)		+= apm_power.o
+obj-$(CONFIG_MAX8925_POWER)	+= max8925_power.o
 obj-$(CONFIG_WM831X_BACKUP)	+= wm831x_backup.o
 obj-$(CONFIG_WM831X_POWER)	+= wm831x_power.o
 obj-$(CONFIG_WM8350_POWER)	+= wm8350_power.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/max17040_battery.c linux-libre-2.6.34-gnu1/drivers/power/max17040_battery.c
--- linux-libre-2.6.33-gnu1/drivers/power/max17040_battery.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/max17040_battery.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/power_supply.h>
 #include <linux/max17040_battery.h>
+#include <linux/slab.h>
 
 #define MAX17040_VCELL_MSB	0x02
 #define MAX17040_VCELL_LSB	0x03
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/max8925_power.c linux-libre-2.6.34-gnu1/drivers/power/max8925_power.c
--- linux-libre-2.6.33-gnu1/drivers/power/max8925_power.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/max8925_power.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,535 @@
+/*
+ * Battery driver for Maxim MAX8925
+ *
+ * Copyright (c) 2009-2010 Marvell International Ltd.
+ *	Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/mfd/max8925.h>
+
+/* registers in GPM */
+#define MAX8925_OUT5VEN			0x54
+#define MAX8925_OUT3VEN			0x58
+#define MAX8925_CHG_CNTL1		0x7c
+
+/* bits definition */
+#define MAX8925_CHG_STAT_VSYSLOW	(1 << 0)
+#define MAX8925_CHG_STAT_MODE_MASK	(3 << 2)
+#define MAX8925_CHG_STAT_EN_MASK	(1 << 4)
+#define MAX8925_CHG_MBDET		(1 << 1)
+#define MAX8925_CHG_AC_RANGE_MASK	(3 << 6)
+
+/* registers in ADC */
+#define MAX8925_ADC_RES_CNFG1		0x06
+#define MAX8925_ADC_AVG_CNFG1		0x07
+#define MAX8925_ADC_ACQ_CNFG1		0x08
+#define MAX8925_ADC_ACQ_CNFG2		0x09
+/* 2 bytes registers in below. MSB is 1st, LSB is 2nd. */
+#define MAX8925_ADC_AUX2		0x62
+#define MAX8925_ADC_VCHG		0x64
+#define MAX8925_ADC_VBBATT		0x66
+#define MAX8925_ADC_VMBATT		0x68
+#define MAX8925_ADC_ISNS		0x6a
+#define MAX8925_ADC_THM			0x6c
+#define MAX8925_ADC_TDIE		0x6e
+#define MAX8925_CMD_AUX2		0xc8
+#define MAX8925_CMD_VCHG		0xd0
+#define MAX8925_CMD_VBBATT		0xd8
+#define MAX8925_CMD_VMBATT		0xe0
+#define MAX8925_CMD_ISNS		0xe8
+#define MAX8925_CMD_THM			0xf0
+#define MAX8925_CMD_TDIE		0xf8
+
+enum {
+	MEASURE_AUX2,
+	MEASURE_VCHG,
+	MEASURE_VBBATT,
+	MEASURE_VMBATT,
+	MEASURE_ISNS,
+	MEASURE_THM,
+	MEASURE_TDIE,
+	MEASURE_MAX,
+};
+
+struct max8925_power_info {
+	struct max8925_chip	*chip;
+	struct i2c_client	*gpm;
+	struct i2c_client	*adc;
+
+	struct power_supply	ac;
+	struct power_supply	usb;
+	struct power_supply	battery;
+	int			irq_base;
+	unsigned		ac_online:1;
+	unsigned		usb_online:1;
+	unsigned		bat_online:1;
+	unsigned		chg_mode:2;
+	unsigned		batt_detect:1;	/* detecing MB by ID pin */
+	unsigned		topoff_threshold:2;
+	unsigned		fast_charge:3;
+
+	int (*set_charger) (int);
+};
+
+static int __set_charger(struct max8925_power_info *info, int enable)
+{
+	struct max8925_chip *chip = info->chip;
+	if (enable) {
+		/* enable charger in platform */
+		if (info->set_charger)
+			info->set_charger(1);
+		/* enable charger */
+		max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 0);
+	} else {
+		/* disable charge */
+		max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 1 << 7);
+		if (info->set_charger)
+			info->set_charger(0);
+	}
+	dev_dbg(chip->dev, "%s\n", (enable) ? "Enable charger"
+		: "Disable charger");
+	return 0;
+}
+
+static irqreturn_t max8925_charger_handler(int irq, void *data)
+{
+	struct max8925_power_info *info = (struct max8925_power_info *)data;
+	struct max8925_chip *chip = info->chip;
+
+	switch (irq - chip->irq_base) {
+	case MAX8925_IRQ_VCHG_DC_R:
+		info->ac_online = 1;
+		__set_charger(info, 1);
+		dev_dbg(chip->dev, "Adapter inserted\n");
+		break;
+	case MAX8925_IRQ_VCHG_DC_F:
+		info->ac_online = 0;
+		__set_charger(info, 0);
+		dev_dbg(chip->dev, "Adapter is removal\n");
+		break;
+	case MAX8925_IRQ_VCHG_USB_R:
+		info->usb_online = 1;
+		__set_charger(info, 1);
+		dev_dbg(chip->dev, "USB inserted\n");
+		break;
+	case MAX8925_IRQ_VCHG_USB_F:
+		info->usb_online = 0;
+		__set_charger(info, 0);
+		dev_dbg(chip->dev, "USB is removal\n");
+		break;
+	case MAX8925_IRQ_VCHG_THM_OK_F:
+		/* Battery is not ready yet */
+		dev_dbg(chip->dev, "Battery temperature is out of range\n");
+	case MAX8925_IRQ_VCHG_DC_OVP:
+		dev_dbg(chip->dev, "Error detection\n");
+		__set_charger(info, 0);
+		break;
+	case MAX8925_IRQ_VCHG_THM_OK_R:
+		/* Battery is ready now */
+		dev_dbg(chip->dev, "Battery temperature is in range\n");
+		break;
+	case MAX8925_IRQ_VCHG_SYSLOW_R:
+		/* VSYS is low */
+		dev_info(chip->dev, "Sys power is too low\n");
+		break;
+	case MAX8925_IRQ_VCHG_SYSLOW_F:
+		dev_dbg(chip->dev, "Sys power is above low threshold\n");
+		break;
+	case MAX8925_IRQ_VCHG_DONE:
+		__set_charger(info, 0);
+		dev_dbg(chip->dev, "Charging is done\n");
+		break;
+	case MAX8925_IRQ_VCHG_TOPOFF:
+		dev_dbg(chip->dev, "Charging in top-off mode\n");
+		break;
+	case MAX8925_IRQ_VCHG_TMR_FAULT:
+		__set_charger(info, 0);
+		dev_dbg(chip->dev, "Safe timer is expired\n");
+		break;
+	case MAX8925_IRQ_VCHG_RST:
+		__set_charger(info, 0);
+		dev_dbg(chip->dev, "Charger is reset\n");
+		break;
+	}
+	return IRQ_HANDLED;
+}
+
+static int start_measure(struct max8925_power_info *info, int type)
+{
+	unsigned char buf[2] = {0, 0};
+	int meas_reg = 0, ret;
+
+	switch (type) {
+	case MEASURE_VCHG:
+		meas_reg = MAX8925_ADC_VCHG;
+		break;
+	case MEASURE_VBBATT:
+		meas_reg = MAX8925_ADC_VBBATT;
+		break;
+	case MEASURE_VMBATT:
+		meas_reg = MAX8925_ADC_VMBATT;
+		break;
+	case MEASURE_ISNS:
+		meas_reg = MAX8925_ADC_ISNS;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	max8925_bulk_read(info->adc, meas_reg, 2, buf);
+	ret = (buf[0] << 4) | (buf[1] >> 4);
+
+	return ret;
+}
+
+static int max8925_ac_get_prop(struct power_supply *psy,
+			       enum power_supply_property psp,
+			       union power_supply_propval *val)
+{
+	struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
+	int ret = 0;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = info->ac_online;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		if (info->ac_online) {
+			ret = start_measure(info, MEASURE_VCHG);
+			if (ret >= 0) {
+				val->intval = ret << 1;	/* unit is mV */
+				goto out;
+			}
+		}
+		ret = -ENODATA;
+		break;
+	default:
+		ret = -ENODEV;
+		break;
+	}
+out:
+	return ret;
+}
+
+static enum power_supply_property max8925_ac_props[] = {
+	POWER_SUPPLY_PROP_ONLINE,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+};
+
+static int max8925_usb_get_prop(struct power_supply *psy,
+				enum power_supply_property psp,
+				union power_supply_propval *val)
+{
+	struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
+	int ret = 0;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = info->usb_online;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		if (info->usb_online) {
+			ret = start_measure(info, MEASURE_VCHG);
+			if (ret >= 0) {
+				val->intval = ret << 1;	/* unit is mV */
+				goto out;
+			}
+		}
+		ret = -ENODATA;
+		break;
+	default:
+		ret = -ENODEV;
+		break;
+	}
+out:
+	return ret;
+}
+
+static enum power_supply_property max8925_usb_props[] = {
+	POWER_SUPPLY_PROP_ONLINE,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+};
+
+static int max8925_bat_get_prop(struct power_supply *psy,
+				enum power_supply_property psp,
+				union power_supply_propval *val)
+{
+	struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
+	long long int tmp = 0;
+	int ret = 0;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = info->bat_online;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		if (info->bat_online) {
+			ret = start_measure(info, MEASURE_VMBATT);
+			if (ret >= 0) {
+				val->intval = ret << 1;	/* unit is mV */
+				ret = 0;
+				break;
+			}
+		}
+		ret = -ENODATA;
+		break;
+	case POWER_SUPPLY_PROP_CURRENT_NOW:
+		if (info->bat_online) {
+			ret = start_measure(info, MEASURE_ISNS);
+			if (ret >= 0) {
+				tmp = (long long int)ret * 6250 / 4096 - 3125;
+				ret = (int)tmp;
+				val->intval = 0;
+				if (ret > 0)
+					val->intval = ret; /* unit is mA */
+				ret = 0;
+				break;
+			}
+		}
+		ret = -ENODATA;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_TYPE:
+		if (!info->bat_online) {
+			ret = -ENODATA;
+			break;
+		}
+		ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
+		ret = (ret & MAX8925_CHG_STAT_MODE_MASK) >> 2;
+		switch (ret) {
+		case 1:
+			val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
+			break;
+		case 0:
+		case 2:
+			val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
+			break;
+		case 3:
+			val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
+			break;
+		}
+		ret = 0;
+		break;
+	case POWER_SUPPLY_PROP_STATUS:
+		if (!info->bat_online) {
+			ret = -ENODATA;
+			break;
+		}
+		ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
+		if (info->usb_online || info->ac_online) {
+			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+			if (ret & MAX8925_CHG_STAT_EN_MASK)
+				val->intval = POWER_SUPPLY_STATUS_CHARGING;
+		} else
+			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+		ret = 0;
+		break;
+	default:
+		ret = -ENODEV;
+		break;
+	}
+	return ret;
+}
+
+static enum power_supply_property max8925_battery_props[] = {
+	POWER_SUPPLY_PROP_ONLINE,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CHARGE_TYPE,
+	POWER_SUPPLY_PROP_STATUS,
+};
+
+#define REQUEST_IRQ(_irq, _name)					\
+do {									\
+	ret = request_threaded_irq(chip->irq_base + _irq, NULL,		\
+				    max8925_charger_handler,		\
+				    IRQF_ONESHOT, _name, info);		\
+	if (ret)							\
+		dev_err(chip->dev, "Failed to request IRQ #%d: %d\n",	\
+			_irq, ret);					\
+} while (0)
+
+static __devinit int max8925_init_charger(struct max8925_chip *chip,
+					  struct max8925_power_info *info)
+{
+	int ret;
+
+	REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_OVP, "ac-ovp");
+	REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_F, "ac-remove");
+	REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_R, "ac-insert");
+	REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_OVP, "usb-ovp");
+	REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_F, "usb-remove");
+	REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_R, "usb-insert");
+	REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_R, "batt-temp-in-range");
+	REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_F, "batt-temp-out-range");
+	REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_F, "vsys-high");
+	REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_R, "vsys-low");
+	REQUEST_IRQ(MAX8925_IRQ_VCHG_RST, "charger-reset");
+	REQUEST_IRQ(MAX8925_IRQ_VCHG_DONE, "charger-done");
+	REQUEST_IRQ(MAX8925_IRQ_VCHG_TOPOFF, "charger-topoff");
+	REQUEST_IRQ(MAX8925_IRQ_VCHG_TMR_FAULT, "charger-timer-expire");
+
+	info->ac_online = 0;
+	info->usb_online = 0;
+	info->bat_online = 0;
+	ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
+	if (ret >= 0) {
+		/*
+		 * If battery detection is enabled, ID pin of battery is
+		 * connected to MBDET pin of MAX8925. It could be used to
+		 * detect battery presence.
+		 * Otherwise, we have to assume that battery is always on.
+		 */
+		if (info->batt_detect)
+			info->bat_online = (ret & MAX8925_CHG_MBDET) ? 0 : 1;
+		else
+			info->bat_online = 1;
+		if (ret & MAX8925_CHG_AC_RANGE_MASK)
+			info->ac_online = 1;
+		else
+			info->ac_online = 0;
+	}
+	/* disable charge */
+	max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 1 << 7);
+	/* set charging current in charge topoff mode */
+	max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 3 << 5,
+			 info->topoff_threshold << 5);
+	/* set charing current in fast charge mode */
+	max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 7, info->fast_charge);
+
+	return 0;
+}
+
+static __devexit int max8925_deinit_charger(struct max8925_power_info *info)
+{
+	struct max8925_chip *chip = info->chip;
+	int irq;
+
+	irq = chip->irq_base + MAX8925_IRQ_VCHG_DC_OVP;
+	for (; irq <= chip->irq_base + MAX8925_IRQ_VCHG_TMR_FAULT; irq++)
+		free_irq(irq, info);
+
+	return 0;
+}
+
+static __devinit int max8925_power_probe(struct platform_device *pdev)
+{
+	struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct max8925_platform_data *max8925_pdata;
+	struct max8925_power_pdata *pdata = NULL;
+	struct max8925_power_info *info;
+	int ret;
+
+	if (pdev->dev.parent->platform_data) {
+		max8925_pdata = pdev->dev.parent->platform_data;
+		pdata = max8925_pdata->power;
+	}
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "platform data isn't assigned to "
+			"power supply\n");
+		return -EINVAL;
+	}
+
+	info = kzalloc(sizeof(struct max8925_power_info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+	info->chip = chip;
+	info->gpm = chip->i2c;
+	info->adc = chip->adc;
+
+	info->ac.name = "max8925-ac";
+	info->ac.type = POWER_SUPPLY_TYPE_MAINS;
+	info->ac.properties = max8925_ac_props;
+	info->ac.num_properties = ARRAY_SIZE(max8925_ac_props);
+	info->ac.get_property = max8925_ac_get_prop;
+	ret = power_supply_register(&pdev->dev, &info->ac);
+	if (ret)
+		goto out;
+	info->ac.dev->parent = &pdev->dev;
+
+	info->usb.name = "max8925-usb";
+	info->usb.type = POWER_SUPPLY_TYPE_USB;
+	info->usb.properties = max8925_usb_props;
+	info->usb.num_properties = ARRAY_SIZE(max8925_usb_props);
+	info->usb.get_property = max8925_usb_get_prop;
+	ret = power_supply_register(&pdev->dev, &info->usb);
+	if (ret)
+		goto out_usb;
+	info->usb.dev->parent = &pdev->dev;
+
+	info->battery.name = "max8925-battery";
+	info->battery.type = POWER_SUPPLY_TYPE_BATTERY;
+	info->battery.properties = max8925_battery_props;
+	info->battery.num_properties = ARRAY_SIZE(max8925_battery_props);
+	info->battery.get_property = max8925_bat_get_prop;
+	ret = power_supply_register(&pdev->dev, &info->battery);
+	if (ret)
+		goto out_battery;
+	info->battery.dev->parent = &pdev->dev;
+
+	info->batt_detect = pdata->batt_detect;
+	info->topoff_threshold = pdata->topoff_threshold;
+	info->fast_charge = pdata->fast_charge;
+	info->set_charger = pdata->set_charger;
+	dev_set_drvdata(&pdev->dev, info);
+	platform_set_drvdata(pdev, info);
+
+	max8925_init_charger(chip, info);
+	return 0;
+out_battery:
+	power_supply_unregister(&info->battery);
+out_usb:
+	power_supply_unregister(&info->ac);
+out:
+	kfree(info);
+	return ret;
+}
+
+static __devexit int max8925_power_remove(struct platform_device *pdev)
+{
+	struct max8925_power_info *info = platform_get_drvdata(pdev);
+
+	if (info) {
+		power_supply_unregister(&info->ac);
+		power_supply_unregister(&info->usb);
+		power_supply_unregister(&info->battery);
+		max8925_deinit_charger(info);
+		kfree(info);
+	}
+	return 0;
+}
+
+static struct platform_driver max8925_power_driver = {
+	.probe	= max8925_power_probe,
+	.remove	= __devexit_p(max8925_power_remove),
+	.driver	= {
+		.name	= "max8925-power",
+	},
+};
+
+static int __init max8925_power_init(void)
+{
+	return platform_driver_register(&max8925_power_driver);
+}
+module_init(max8925_power_init);
+
+static void __exit max8925_power_exit(void)
+{
+	platform_driver_unregister(&max8925_power_driver);
+}
+module_exit(max8925_power_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Power supply driver for MAX8925");
+MODULE_ALIAS("platform:max8925-power");
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/pcf50633-charger.c linux-libre-2.6.34-gnu1/drivers/power/pcf50633-charger.c
--- linux-libre-2.6.33-gnu1/drivers/power/pcf50633-charger.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/pcf50633-charger.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/pmu_battery.c linux-libre-2.6.34-gnu1/drivers/power/pmu_battery.c
--- linux-libre-2.6.33-gnu1/drivers/power/pmu_battery.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/pmu_battery.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/power_supply.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
+#include <linux/slab.h>
 
 static struct pmu_battery_dev {
 	struct power_supply bat;
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/power_supply_leds.c linux-libre-2.6.34-gnu1/drivers/power/power_supply_leds.c
--- linux-libre-2.6.33-gnu1/drivers/power/power_supply_leds.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/power_supply_leds.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 
 #include <linux/kernel.h>
 #include <linux/power_supply.h>
+#include <linux/slab.h>
 
 #include "power_supply.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/power_supply_sysfs.c linux-libre-2.6.34-gnu1/drivers/power/power_supply_sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/power/power_supply_sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/power_supply_sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 
 #include <linux/ctype.h>
 #include <linux/power_supply.h>
+#include <linux/slab.h>
 
 #include "power_supply.h"
 
@@ -99,6 +100,7 @@ static struct device_attribute power_sup
 	POWER_SUPPLY_ATTR(present),
 	POWER_SUPPLY_ATTR(online),
 	POWER_SUPPLY_ATTR(technology),
+	POWER_SUPPLY_ATTR(cycle_count),
 	POWER_SUPPLY_ATTR(voltage_max),
 	POWER_SUPPLY_ATTR(voltage_min),
 	POWER_SUPPLY_ATTR(voltage_max_design),
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/wm831x_backup.c linux-libre-2.6.34-gnu1/drivers/power/wm831x_backup.c
--- linux-libre-2.6.33-gnu1/drivers/power/wm831x_backup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/wm831x_backup.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/auxadc.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/wm831x_power.c linux-libre-2.6.34-gnu1/drivers/power/wm831x_power.c
--- linux-libre-2.6.33-gnu1/drivers/power/wm831x_power.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/wm831x_power.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/auxadc.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/wm8350_power.c linux-libre-2.6.34-gnu1/drivers/power/wm8350_power.c
--- linux-libre-2.6.33-gnu1/drivers/power/wm8350_power.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/wm8350_power.c	2010-05-16 17:17:36.000000000 -0400
@@ -190,7 +190,7 @@ static irqreturn_t wm8350_charger_handle
 	struct wm8350_power *power = &wm8350->power;
 	struct wm8350_charger_policy *policy = power->policy;
 
-	switch (irq) {
+	switch (irq - wm8350->irq_base) {
 	case WM8350_IRQ_CHG_BAT_FAIL:
 		dev_err(wm8350->dev, "battery failed\n");
 		break;
@@ -428,18 +428,18 @@ static void wm8350_init_charger(struct w
 
 static void free_charger_irq(struct wm8350 *wm8350)
 {
-	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT);
-	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD);
-	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL);
-	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO);
-	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END);
-	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START);
-	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9);
-	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1);
-	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85);
-	wm8350_free_irq(wm8350, WM8350_IRQ_EXT_USB_FB);
-	wm8350_free_irq(wm8350, WM8350_IRQ_EXT_WALL_FB);
-	wm8350_free_irq(wm8350, WM8350_IRQ_EXT_BAT_FB);
+	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT, wm8350);
+	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD, wm8350);
+	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL, wm8350);
+	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO, wm8350);
+	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END, wm8350);
+	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START, wm8350);
+	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9, wm8350);
+	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1, wm8350);
+	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85, wm8350);
+	wm8350_free_irq(wm8350, WM8350_IRQ_EXT_USB_FB, wm8350);
+	wm8350_free_irq(wm8350, WM8350_IRQ_EXT_WALL_FB, wm8350);
+	wm8350_free_irq(wm8350, WM8350_IRQ_EXT_BAT_FB, wm8350);
 }
 
 static __devinit int wm8350_power_probe(struct platform_device *pdev)
diff -druNp linux-libre-2.6.33-gnu1/drivers/power/wm97xx_battery.c linux-libre-2.6.34-gnu1/drivers/power/wm97xx_battery.c
--- linux-libre-2.6.33-gnu1/drivers/power/wm97xx_battery.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/power/wm97xx_battery.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,10 +23,11 @@
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 
 static DEFINE_MUTEX(bat_lock);
 static struct work_struct bat_work;
-struct mutex work_lock;
+static struct mutex work_lock;
 static int bat_status = POWER_SUPPLY_STATUS_UNKNOWN;
 static struct wm97xx_batt_info *gpdata;
 static enum power_supply_property *prop;
@@ -203,7 +204,7 @@ static int __devinit wm97xx_bat_probe(st
 			goto err2;
 		ret = request_irq(gpio_to_irq(pdata->charge_gpio),
 				wm97xx_chrg_irq, IRQF_DISABLED,
-				"AC Detect", 0);
+				"AC Detect", dev);
 		if (ret)
 			goto err2;
 		props++;	/* POWER_SUPPLY_PROP_STATUS */
diff -druNp linux-libre-2.6.33-gnu1/drivers/pps/clients/Kconfig linux-libre-2.6.34-gnu1/drivers/pps/clients/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/pps/clients/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pps/clients/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,25 @@
+#
+# PPS clients configuration
+#
+
+if PPS
+
+comment "PPS clients support"
+
+config PPS_CLIENT_KTIMER
+	tristate "Kernel timer client (Testing client, use for debug)"
+	help
+	  If you say yes here you get support for a PPS debugging client
+	  which uses a kernel timer to generate the PPS signal.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called pps-ktimer.
+
+config PPS_CLIENT_LDISC
+	tristate "PPS line discipline"
+	depends on PPS
+	help
+	  If you say yes here you get support for a PPS source connected
+	  with the CD (Carrier Detect) pin of your serial port.
+
+endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/pps/clients/Makefile linux-libre-2.6.34-gnu1/drivers/pps/clients/Makefile
--- linux-libre-2.6.33-gnu1/drivers/pps/clients/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pps/clients/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,10 @@
+#
+# Makefile for PPS clients.
+#
+
+obj-$(CONFIG_PPS_CLIENT_KTIMER)	+= pps-ktimer.o
+obj-$(CONFIG_PPS_CLIENT_LDISC)	+= pps-ldisc.o
+
+ifeq ($(CONFIG_PPS_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/pps/clients/pps-ktimer.c linux-libre-2.6.34-gnu1/drivers/pps/clients/pps-ktimer.c
--- linux-libre-2.6.33-gnu1/drivers/pps/clients/pps-ktimer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pps/clients/pps-ktimer.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,123 @@
+/*
+ * pps-ktimer.c -- kernel timer test client
+ *
+ *
+ * Copyright (C) 2005-2006   Rodolfo Giometti <giometti@linux.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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/pps_kernel.h>
+
+/*
+ * Global variables
+ */
+
+static int source;
+static struct timer_list ktimer;
+
+/*
+ * The kernel timer
+ */
+
+static void pps_ktimer_event(unsigned long ptr)
+{
+	struct timespec __ts;
+	struct pps_ktime ts;
+
+	/* First of all we get the time stamp... */
+	getnstimeofday(&__ts);
+
+	pr_info("PPS event at %lu\n", jiffies);
+
+	/* ... and translate it to PPS time data struct */
+	ts.sec = __ts.tv_sec;
+	ts.nsec = __ts.tv_nsec;
+
+	pps_event(source, &ts, PPS_CAPTUREASSERT, NULL);
+
+	mod_timer(&ktimer, jiffies + HZ);
+}
+
+/*
+ * The echo function
+ */
+
+static void pps_ktimer_echo(int source, int event, void *data)
+{
+	pr_info("echo %s %s for source %d\n",
+		event & PPS_CAPTUREASSERT ? "assert" : "",
+		event & PPS_CAPTURECLEAR ? "clear" : "",
+		source);
+}
+
+/*
+ * The PPS info struct
+ */
+
+static struct pps_source_info pps_ktimer_info = {
+	.name		= "ktimer",
+	.path		= "",
+	.mode		= PPS_CAPTUREASSERT | PPS_OFFSETASSERT |
+			  PPS_ECHOASSERT |
+			  PPS_CANWAIT | PPS_TSFMT_TSPEC,
+	.echo		= pps_ktimer_echo,
+	.owner		= THIS_MODULE,
+};
+
+/*
+ * Module staff
+ */
+
+static void __exit pps_ktimer_exit(void)
+{
+	del_timer_sync(&ktimer);
+	pps_unregister_source(source);
+
+	pr_info("ktimer PPS source unregistered\n");
+}
+
+static int __init pps_ktimer_init(void)
+{
+	int ret;
+
+	ret = pps_register_source(&pps_ktimer_info,
+				PPS_CAPTUREASSERT | PPS_OFFSETASSERT);
+	if (ret < 0) {
+		printk(KERN_ERR "cannot register ktimer source\n");
+		return ret;
+	}
+	source = ret;
+
+	setup_timer(&ktimer, pps_ktimer_event, 0);
+	mod_timer(&ktimer, jiffies + HZ);
+
+	pr_info("ktimer PPS source registered at %d\n", source);
+
+	return  0;
+}
+
+module_init(pps_ktimer_init);
+module_exit(pps_ktimer_exit);
+
+MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
+MODULE_DESCRIPTION("dummy PPS source by using a kernel timer (just for debug)");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/pps/clients/pps-ldisc.c linux-libre-2.6.34-gnu1/drivers/pps/clients/pps-ldisc.c
--- linux-libre-2.6.33-gnu1/drivers/pps/clients/pps-ldisc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pps/clients/pps-ldisc.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,154 @@
+/*
+ * pps-ldisc.c -- PPS line discipline
+ *
+ *
+ * Copyright (C) 2008	Rodolfo Giometti <giometti@linux.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/serial_core.h>
+#include <linux/tty.h>
+#include <linux/pps_kernel.h>
+
+#define PPS_TTY_MAGIC		0x0001
+
+static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status,
+				struct timespec *ts)
+{
+	int id = (long)tty->disc_data;
+	struct timespec __ts;
+	struct pps_ktime pps_ts;
+
+	/* First of all we get the time stamp... */
+	getnstimeofday(&__ts);
+
+	/* Does caller give us a timestamp? */
+	if (ts) {	/* Yes. Let's use it! */
+		pps_ts.sec = ts->tv_sec;
+		pps_ts.nsec = ts->tv_nsec;
+	} else {	/* No. Do it ourself! */
+		pps_ts.sec = __ts.tv_sec;
+		pps_ts.nsec = __ts.tv_nsec;
+	}
+
+	/* Now do the PPS event report */
+	pps_event(id, &pps_ts, status ? PPS_CAPTUREASSERT : PPS_CAPTURECLEAR,
+			NULL);
+
+	pr_debug("PPS %s at %lu on source #%d\n",
+			status ? "assert" : "clear", jiffies, id);
+}
+
+static int (*alias_n_tty_open)(struct tty_struct *tty);
+
+static int pps_tty_open(struct tty_struct *tty)
+{
+	struct pps_source_info info;
+	struct tty_driver *drv = tty->driver;
+	int index = tty->index + drv->name_base;
+	int ret;
+
+	info.owner = THIS_MODULE;
+	info.dev = NULL;
+	snprintf(info.name, PPS_MAX_NAME_LEN, "%s%d", drv->driver_name, index);
+	snprintf(info.path, PPS_MAX_NAME_LEN, "/dev/%s%d", drv->name, index);
+	info.mode = PPS_CAPTUREBOTH | \
+			PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \
+			PPS_CANWAIT | PPS_TSFMT_TSPEC;
+
+	ret = pps_register_source(&info, PPS_CAPTUREBOTH | \
+				PPS_OFFSETASSERT | PPS_OFFSETCLEAR);
+	if (ret < 0) {
+		pr_err("cannot register PPS source \"%s\"\n", info.path);
+		return ret;
+	}
+	tty->disc_data = (void *)(long)ret;
+
+	/* Should open N_TTY ldisc too */
+	ret = alias_n_tty_open(tty);
+	if (ret < 0)
+		pps_unregister_source((long)tty->disc_data);
+
+	pr_info("PPS source #%d \"%s\" added\n", ret, info.path);
+
+	return 0;
+}
+
+static void (*alias_n_tty_close)(struct tty_struct *tty);
+
+static void pps_tty_close(struct tty_struct *tty)
+{
+	int id = (long)tty->disc_data;
+
+	pps_unregister_source(id);
+	alias_n_tty_close(tty);
+
+	pr_info("PPS source #%d removed\n", id);
+}
+
+static struct tty_ldisc_ops pps_ldisc_ops;
+
+/*
+ * Module stuff
+ */
+
+static int __init pps_tty_init(void)
+{
+	int err;
+
+	/* Inherit the N_TTY's ops */
+	n_tty_inherit_ops(&pps_ldisc_ops);
+
+	/* Save N_TTY's open()/close() methods */
+	alias_n_tty_open = pps_ldisc_ops.open;
+	alias_n_tty_close = pps_ldisc_ops.close;
+
+	/* Init PPS_TTY data */
+	pps_ldisc_ops.owner = THIS_MODULE;
+	pps_ldisc_ops.magic = PPS_TTY_MAGIC;
+	pps_ldisc_ops.name = "pps_tty";
+	pps_ldisc_ops.dcd_change = pps_tty_dcd_change;
+	pps_ldisc_ops.open = pps_tty_open;
+	pps_ldisc_ops.close = pps_tty_close;
+
+	err = tty_register_ldisc(N_PPS, &pps_ldisc_ops);
+	if (err)
+		pr_err("can't register PPS line discipline\n");
+	else
+		pr_info("PPS line discipline registered\n");
+
+	return err;
+}
+
+static void __exit pps_tty_cleanup(void)
+{
+	int err;
+
+	err = tty_unregister_ldisc(N_PPS);
+	if (err)
+		pr_err("can't unregister PPS line discipline\n");
+	else
+		pr_info("PPS line discipline removed\n");
+}
+
+module_init(pps_tty_init);
+module_exit(pps_tty_cleanup);
+
+MODULE_ALIAS_LDISC(N_PPS);
+MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
+MODULE_DESCRIPTION("PPS TTY device driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/pps/kapi.c linux-libre-2.6.34-gnu1/drivers/pps/kapi.c
--- linux-libre-2.6.33-gnu1/drivers/pps/kapi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pps/kapi.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/idr.h>
 #include <linux/fs.h>
 #include <linux/pps_kernel.h>
+#include <linux/slab.h>
 
 /*
  * Global variables
diff -druNp linux-libre-2.6.33-gnu1/drivers/pps/Kconfig linux-libre-2.6.34-gnu1/drivers/pps/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/pps/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pps/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -30,4 +30,6 @@ config PPS_DEBUG
 	  messages to the system log.  Select this if you are having a
 	  problem with PPS support and want to see more of what is going on.
 
+source drivers/pps/clients/Kconfig
+
 endmenu
diff -druNp linux-libre-2.6.33-gnu1/drivers/pps/Makefile linux-libre-2.6.34-gnu1/drivers/pps/Makefile
--- linux-libre-2.6.33-gnu1/drivers/pps/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/pps/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -4,5 +4,6 @@
 
 pps_core-y			:= pps.o kapi.o sysfs.o
 obj-$(CONFIG_PPS)		:= pps_core.o
+obj-y				+= clients/
 
 ccflags-$(CONFIG_PPS_DEBUG) := -DDEBUG
diff -druNp linux-libre-2.6.33-gnu1/drivers/ps3/ps3av.c linux-libre-2.6.34-gnu1/drivers/ps3/ps3av.c
--- linux-libre-2.6.33-gnu1/drivers/ps3/ps3av.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ps3/ps3av.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/notifier.h>
 #include <linux/ioctl.h>
 #include <linux/fb.h>
+#include <linux/slab.h>
 
 #include <asm/firmware.h>
 #include <asm/ps3av.h>
@@ -532,7 +533,7 @@ static void ps3av_set_videomode_packet(u
 	res = ps3av_cmd_avb_param(&avb_param, len);
 	if (res == PS3AV_STATUS_NO_SYNC_HEAD)
 		printk(KERN_WARNING
-		       "%s: Command failed. Please try your request again. \n",
+		       "%s: Command failed. Please try your request again.\n",
 		       __func__);
 	else if (res)
 		dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n");
diff -druNp linux-libre-2.6.33-gnu1/drivers/ps3/ps3-lpm.c linux-libre-2.6.34-gnu1/drivers/ps3/ps3-lpm.c
--- linux-libre-2.6.33-gnu1/drivers/ps3/ps3-lpm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ps3/ps3-lpm.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ps3/ps3-vuart.c linux-libre-2.6.34-gnu1/drivers/ps3/ps3-vuart.c
--- linux-libre-2.6.33-gnu1/drivers/ps3/ps3-vuart.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ps3/ps3-vuart.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/88pm8607.c linux-libre-2.6.34-gnu1/drivers/regulator/88pm8607.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/88pm8607.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/88pm8607.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,15 +11,17 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
-#include <linux/mfd/88pm8607.h>
+#include <linux/mfd/88pm860x.h>
 
 struct pm8607_regulator_info {
 	struct regulator_desc	desc;
-	struct pm8607_chip	*chip;
+	struct pm860x_chip	*chip;
 	struct regulator_dev	*regulator;
+	struct i2c_client	*i2c;
 
 	int	min_uV;
 	int	max_uV;
@@ -46,7 +48,6 @@ static inline int check_range(struct pm8
 static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
 {
 	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
-	uint8_t chip_id = info->chip->chip_id;
 	int ret = -EINVAL;
 
 	switch (info->desc.id) {
@@ -88,79 +89,29 @@ static int pm8607_list_voltage(struct re
 	case PM8607_ID_LDO2:
 	case PM8607_ID_LDO3:
 	case PM8607_ID_LDO9:
-		switch (chip_id) {
-		case PM8607_CHIP_A0:
-		case PM8607_CHIP_A1:
-			ret = (index < 3) ? (index * 50000 + 1800000) :
-				((index < 8) ? (index * 50000 + 2550000) :
-				 -EINVAL);
-			break;
-		case PM8607_CHIP_B0:
-			ret = (index < 3) ? (index * 50000 + 1800000) :
-				((index < 7) ? (index * 50000 + 2550000) :
-				3300000);
-			break;
-		}
+		ret = (index < 3) ? (index * 50000 + 1800000) :
+			((index < 7) ? (index * 50000 + 2550000) :
+			3300000);
 		break;
 	case PM8607_ID_LDO4:
-		switch (chip_id) {
-		case PM8607_CHIP_A0:
-		case PM8607_CHIP_A1:
-			ret = (index < 3) ? (index * 50000 + 1800000) :
-				((index < 8) ? (index * 50000 + 2550000) :
-				 -EINVAL);
-			break;
-		case PM8607_CHIP_B0:
-			ret = (index < 3) ? (index * 50000 + 1800000) :
-				((index < 6) ? (index * 50000 + 2550000) :
-				((index == 6) ? 2900000 : 3300000));
-			break;
-		}
+		ret = (index < 3) ? (index * 50000 + 1800000) :
+			((index < 6) ? (index * 50000 + 2550000) :
+			((index == 6) ? 2900000 : 3300000));
 		break;
 	case PM8607_ID_LDO6:
-		switch (chip_id) {
-		case PM8607_CHIP_A0:
-		case PM8607_CHIP_A1:
-			ret = (index < 3) ? (index * 50000 + 1800000) :
-				((index < 8) ? (index * 50000 + 2450000) :
-				-EINVAL);
-			break;
-		case PM8607_CHIP_B0:
-			ret = (index < 2) ? (index * 50000 + 1800000) :
-				((index < 7) ? (index * 50000 + 2500000) :
-				3300000);
-			break;
-		}
+		ret = (index < 2) ? (index * 50000 + 1800000) :
+			((index < 7) ? (index * 50000 + 2500000) :
+			3300000);
 		break;
 	case PM8607_ID_LDO10:
-		switch (chip_id) {
-		case PM8607_CHIP_A0:
-		case PM8607_CHIP_A1:
-			ret = (index < 3) ? (index * 50000 + 1800000) :
-				((index < 8) ? (index * 50000 + 2550000) :
-				1200000);
-			break;
-		case PM8607_CHIP_B0:
-			ret = (index < 3) ? (index * 50000 + 1800000) :
-				((index < 7) ? (index * 50000 + 2550000) :
-				((index == 7) ? 3300000 : 1200000));
-			break;
-		}
+		ret = (index < 3) ? (index * 50000 + 1800000) :
+			((index < 7) ? (index * 50000 + 2550000) :
+			((index == 7) ? 3300000 : 1200000));
 		break;
 	case PM8607_ID_LDO14:
-		switch (chip_id) {
-		case PM8607_CHIP_A0:
-		case PM8607_CHIP_A1:
-			ret = (index < 3) ? (index * 50000 + 1800000) :
-				((index < 8) ? (index * 50000 + 2550000) :
-				 -EINVAL);
-			break;
-		case PM8607_CHIP_B0:
-			ret = (index < 2) ? (index * 50000 + 1800000) :
-				((index < 7) ? (index * 50000 + 2600000) :
-				3300000);
-			break;
-		}
+		ret = (index < 2) ? (index * 50000 + 1800000) :
+			((index < 7) ? (index * 50000 + 2600000) :
+			3300000);
 		break;
 	}
 	return ret;
@@ -169,7 +120,6 @@ static int pm8607_list_voltage(struct re
 static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
 {
 	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
-	uint8_t chip_id = info->chip->chip_id;
 	int val = -ENOENT;
 	int ret;
 
@@ -254,161 +204,77 @@ static int choose_voltage(struct regulat
 	case PM8607_ID_LDO2:
 	case PM8607_ID_LDO3:
 	case PM8607_ID_LDO9:
-		switch (chip_id) {
-		case PM8607_CHIP_A0:
-		case PM8607_CHIP_A1:
-			if (min_uV < 2700000)	/* 1800mV ~ 1900mV / 50mV */
-				if (min_uV <= 1800000)
-					val = 0;
-				else if (min_uV <= 1900000)
-					val = (min_uV - 1750001) / 50000;
-				else
-					val = 3;	/* 2700mV */
-			else {			/* 2700mV ~ 2900mV / 50mV */
-				if (min_uV <= 2900000) {
-					val = (min_uV - 2650001) / 50000;
-					val += 3;
-				} else
-					val = -EINVAL;
-			}
-			break;
-		case PM8607_CHIP_B0:
-			if (min_uV < 2700000) {	/* 1800mV ~ 1900mV / 50mV */
-				if (min_uV <= 1800000)
-					val = 0;
-				else if (min_uV <= 1900000)
-					val = (min_uV - 1750001) / 50000;
-				else
-					val = 3;	/* 2700mV */
-			} else {		 /* 2700mV ~ 2850mV / 50mV */
-				if (min_uV <= 2850000) {
-					val = (min_uV - 2650001) / 50000;
-					val += 3;
-				} else if (min_uV <= 3300000)
-					val = 7;
-				else
-					val = -EINVAL;
-			}
-			break;
+		if (min_uV < 2700000) {	/* 1800mV ~ 1900mV / 50mV */
+			if (min_uV <= 1800000)
+				val = 0;
+			else if (min_uV <= 1900000)
+				val = (min_uV - 1750001) / 50000;
+			else
+				val = 3;	/* 2700mV */
+		} else {		 /* 2700mV ~ 2850mV / 50mV */
+			if (min_uV <= 2850000) {
+				val = (min_uV - 2650001) / 50000;
+				val += 3;
+			} else if (min_uV <= 3300000)
+				val = 7;
+			else
+				val = -EINVAL;
 		}
 		break;
 	case PM8607_ID_LDO4:
-		switch (chip_id) {
-		case PM8607_CHIP_A0:
-		case PM8607_CHIP_A1:
-			if (min_uV < 2700000)	/* 1800mV ~ 1900mV / 50mV */
-				if (min_uV <= 1800000)
-					val = 0;
-				else if (min_uV <= 1900000)
-					val = (min_uV - 1750001) / 50000;
-				else
-					val = 3;	/* 2700mV */
-			else {			/* 2700mV ~ 2900mV / 50mV */
-				if (min_uV <= 2900000) {
-					val = (min_uV - 2650001) / 50000;
-					val += 3;
-				} else
-					val = -EINVAL;
-			}
-			break;
-		case PM8607_CHIP_B0:
-			if (min_uV < 2700000) {	/* 1800mV ~ 1900mV / 50mV */
-				if (min_uV <= 1800000)
-					val = 0;
-				else if (min_uV <= 1900000)
-					val = (min_uV - 1750001) / 50000;
-				else
-					val = 3;	/* 2700mV */
-			} else {		 /* 2700mV ~ 2800mV / 50mV */
-				if (min_uV <= 2850000) {
-					val = (min_uV - 2650001) / 50000;
-					val += 3;
-				} else if (min_uV <= 2900000)
-					val = 6;
-				else if (min_uV <= 3300000)
-					val = 7;
-				else
-					val = -EINVAL;
-			}
-			break;
+		if (min_uV < 2700000) {	/* 1800mV ~ 1900mV / 50mV */
+			if (min_uV <= 1800000)
+				val = 0;
+			else if (min_uV <= 1900000)
+				val = (min_uV - 1750001) / 50000;
+			else
+				val = 3;	/* 2700mV */
+		} else {		 /* 2700mV ~ 2800mV / 50mV */
+			if (min_uV <= 2850000) {
+				val = (min_uV - 2650001) / 50000;
+				val += 3;
+			} else if (min_uV <= 2900000)
+				val = 6;
+			else if (min_uV <= 3300000)
+				val = 7;
+			else
+				val = -EINVAL;
 		}
 		break;
 	case PM8607_ID_LDO6:
-		switch (chip_id) {
-		case PM8607_CHIP_A0:
-		case PM8607_CHIP_A1:
-			if (min_uV < 2600000) {	/* 1800mV ~ 1900mV / 50mV */
-				if (min_uV <= 1800000)
-					val = 0;
-				else if (min_uV <= 1900000)
-					val = (min_uV - 1750001) / 50000;
-				else
-					val = 3;	/* 2600mV */
-			} else {		/* 2600mV ~ 2800mV / 50mV */
-				if (min_uV <= 2800000) {
-					val = (min_uV - 2550001) / 50000;
-					val += 3;
-				} else
-					val = -EINVAL;
-			}
-			break;
-		case PM8607_CHIP_B0:
-			if (min_uV < 2600000) {	/* 1800mV ~ 1850mV / 50mV */
-				if (min_uV <= 1800000)
-					val = 0;
-				else if (min_uV <= 1850000)
-					val = (min_uV - 1750001) / 50000;
-				else
-					val = 2;	/* 2600mV */
-			} else {		/* 2600mV ~ 2800mV / 50mV */
-				if (min_uV <= 2800000) {
-					val = (min_uV - 2550001) / 50000;
-					val += 2;
-				} else if (min_uV <= 3300000)
-					val = 7;
-				else
-					val = -EINVAL;
-			}
-			break;
+		if (min_uV < 2600000) {	/* 1800mV ~ 1850mV / 50mV */
+			if (min_uV <= 1800000)
+				val = 0;
+			else if (min_uV <= 1850000)
+				val = (min_uV - 1750001) / 50000;
+			else
+				val = 2;	/* 2600mV */
+		} else {		/* 2600mV ~ 2800mV / 50mV */
+			if (min_uV <= 2800000) {
+				val = (min_uV - 2550001) / 50000;
+				val += 2;
+			} else if (min_uV <= 3300000)
+				val = 7;
+			else
+				val = -EINVAL;
 		}
 		break;
 	case PM8607_ID_LDO14:
-		switch (chip_id) {
-		case PM8607_CHIP_A0:
-		case PM8607_CHIP_A1:
-			if (min_uV < 2700000) {	/* 1800mV ~ 1900mV / 50mV */
-				if (min_uV <= 1800000)
-					val = 0;
-				else if (min_uV <= 1900000)
-					val = (min_uV - 1750001) / 50000;
-				else
-					val = 3;	/* 2700mV */
-			} else {		 /* 2700mV ~ 2900mV / 50mV */
-				if (min_uV <= 2900000) {
-					val = (min_uV - 2650001) / 50000;
-					val += 3;
-				} else
-					val = -EINVAL;
-			}
-			break;
-		case PM8607_CHIP_B0:
-			if (min_uV < 2700000) {	/* 1800mV ~ 1850mV / 50mV */
-				if (min_uV <= 1800000)
-					val = 0;
-				else if (min_uV <= 1850000)
-					val = (min_uV - 1750001) / 50000;
-				else
-					val = 2;	/* 2700mV */
-			} else {		 /* 2700mV ~ 2900mV / 50mV */
-				if (min_uV <= 2900000) {
-					val = (min_uV - 2650001) / 50000;
-					val += 2;
-				} else if (min_uV <= 3300000)
-					val = 7;
-				else
-					val = -EINVAL;
-			}
-			break;
+		if (min_uV < 2700000) {	/* 1800mV ~ 1850mV / 50mV */
+			if (min_uV <= 1800000)
+				val = 0;
+			else if (min_uV <= 1850000)
+				val = (min_uV - 1750001) / 50000;
+			else
+				val = 2;	/* 2700mV */
+		} else {		 /* 2700mV ~ 2900mV / 50mV */
+			if (min_uV <= 2900000) {
+				val = (min_uV - 2650001) / 50000;
+				val += 2;
+			} else if (min_uV <= 3300000)
+				val = 7;
+			else
+				val = -EINVAL;
 		}
 		break;
 	}
@@ -428,7 +294,6 @@ static int pm8607_set_voltage(struct reg
 			      int min_uV, int max_uV)
 {
 	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
-	struct pm8607_chip *chip = info->chip;
 	uint8_t val, mask;
 	int ret;
 
@@ -443,13 +308,13 @@ static int pm8607_set_voltage(struct reg
 	val = (uint8_t)(ret << info->vol_shift);
 	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
 
-	ret = pm8607_set_bits(chip, info->vol_reg, mask, val);
+	ret = pm860x_set_bits(info->i2c, info->vol_reg, mask, val);
 	if (ret)
 		return ret;
 	switch (info->desc.id) {
 	case PM8607_ID_BUCK1:
 	case PM8607_ID_BUCK3:
-		ret = pm8607_set_bits(chip, info->update_reg,
+		ret = pm860x_set_bits(info->i2c, info->update_reg,
 				      1 << info->update_bit,
 				      1 << info->update_bit);
 		break;
@@ -460,11 +325,10 @@ static int pm8607_set_voltage(struct reg
 static int pm8607_get_voltage(struct regulator_dev *rdev)
 {
 	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
-	struct pm8607_chip *chip = info->chip;
 	uint8_t val, mask;
 	int ret;
 
-	ret = pm8607_reg_read(chip, info->vol_reg);
+	ret = pm860x_reg_read(info->i2c, info->vol_reg);
 	if (ret < 0)
 		return ret;
 
@@ -477,9 +341,8 @@ static int pm8607_get_voltage(struct reg
 static int pm8607_enable(struct regulator_dev *rdev)
 {
 	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
-	struct pm8607_chip *chip = info->chip;
 
-	return pm8607_set_bits(chip, info->enable_reg,
+	return pm860x_set_bits(info->i2c, info->enable_reg,
 			       1 << info->enable_bit,
 			       1 << info->enable_bit);
 }
@@ -487,19 +350,17 @@ static int pm8607_enable(struct regulato
 static int pm8607_disable(struct regulator_dev *rdev)
 {
 	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
-	struct pm8607_chip *chip = info->chip;
 
-	return pm8607_set_bits(chip, info->enable_reg,
+	return pm860x_set_bits(info->i2c, info->enable_reg,
 			       1 << info->enable_bit, 0);
 }
 
 static int pm8607_is_enabled(struct regulator_dev *rdev)
 {
 	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
-	struct pm8607_chip *chip = info->chip;
 	int ret;
 
-	ret = pm8607_reg_read(chip, info->enable_reg);
+	ret = pm860x_reg_read(info->i2c, info->enable_reg);
 	if (ret < 0)
 		return ret;
 
@@ -589,8 +450,8 @@ static inline struct pm8607_regulator_in
 
 static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
 {
-	struct pm8607_chip *chip = dev_get_drvdata(pdev->dev.parent);
-	struct pm8607_platform_data *pdata = chip->dev->platform_data;
+	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct pm860x_platform_data *pdata = chip->dev->platform_data;
 	struct pm8607_regulator_info *info = NULL;
 
 	info = find_regulator_info(pdev->id);
@@ -599,6 +460,7 @@ static int __devinit pm8607_regulator_pr
 		return -EINVAL;
 	}
 
+	info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
 	info->chip = chip;
 
 	info->regulator = regulator_register(&info->desc, &pdev->dev,
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/ab3100.c linux-libre-2.6.34-gnu1/drivers/regulator/ab3100.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/ab3100.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/ab3100.c	2010-05-16 17:17:36.000000000 -0400
@@ -561,7 +561,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULAT
  * for all the different regulators.
  */
 
-static int __init ab3100_regulators_probe(struct platform_device *pdev)
+static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
 {
 	struct ab3100_platform_data *plfdata = pdev->dev.platform_data;
 	struct ab3100 *ab3100 = platform_get_drvdata(pdev);
@@ -641,7 +641,7 @@ static int __init ab3100_regulators_prob
 	return 0;
 }
 
-static int __exit ab3100_regulators_remove(struct platform_device *pdev)
+static int __devexit ab3100_regulators_remove(struct platform_device *pdev)
 {
 	int i;
 
@@ -659,7 +659,7 @@ static struct platform_driver ab3100_reg
 		.owner = THIS_MODULE,
 	},
 	.probe = ab3100_regulators_probe,
-	.remove = __exit_p(ab3100_regulators_remove),
+	.remove = __devexit_p(ab3100_regulators_remove),
 };
 
 static __init int ab3100_regulators_init(void)
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/core.c linux-libre-2.6.34-gnu1/drivers/regulator/core.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,13 +16,17 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/suspend.h>
+#include <linux/delay.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 
+#include "dummy.h"
+
 #define REGULATOR_VERSION "0.5"
 
 static DEFINE_MUTEX(regulator_list_mutex);
@@ -1035,6 +1039,7 @@ static struct regulator *create_regulato
 			goto overflow_err;
 
 		regulator->dev = dev;
+		sysfs_attr_init(&regulator->dev_attr.attr);
 		regulator->dev_attr.attr.name = kstrdup(buf, GFP_KERNEL);
 		if (regulator->dev_attr.attr.name == NULL)
 			goto attr_name_err;
@@ -1084,6 +1089,13 @@ overflow_err:
 	return NULL;
 }
 
+static int _regulator_get_enable_time(struct regulator_dev *rdev)
+{
+	if (!rdev->desc->ops->enable_time)
+		return 0;
+	return rdev->desc->ops->enable_time(rdev);
+}
+
 /* Internal regulator request function */
 static struct regulator *_regulator_get(struct device *dev, const char *id,
 					int exclusive)
@@ -1115,6 +1127,22 @@ static struct regulator *_regulator_get(
 			goto found;
 		}
 	}
+
+#ifdef CONFIG_REGULATOR_DUMMY
+	if (!devname)
+		devname = "deviceless";
+
+	/* If the board didn't flag that it was fully constrained then
+	 * substitute in a dummy regulator so consumers can continue.
+	 */
+	if (!has_full_constraints) {
+		pr_warning("%s supply %s not found, using dummy regulator\n",
+			   devname, id);
+		rdev = dummy_regulator_rdev;
+		goto found;
+	}
+#endif
+
 	mutex_unlock(&regulator_list_mutex);
 	return regulator;
 
@@ -1251,7 +1279,7 @@ static int _regulator_can_change_status(
 /* locks held by regulator_enable() */
 static int _regulator_enable(struct regulator_dev *rdev)
 {
-	int ret;
+	int ret, delay;
 
 	/* do we need to enable the supply regulator first */
 	if (rdev->supply) {
@@ -1275,13 +1303,34 @@ static int _regulator_enable(struct regu
 			if (!_regulator_can_change_status(rdev))
 				return -EPERM;
 
-			if (rdev->desc->ops->enable) {
-				ret = rdev->desc->ops->enable(rdev);
-				if (ret < 0)
-					return ret;
-			} else {
+			if (!rdev->desc->ops->enable)
 				return -EINVAL;
+
+			/* Query before enabling in case configuration
+			 * dependant.  */
+			ret = _regulator_get_enable_time(rdev);
+			if (ret >= 0) {
+				delay = ret;
+			} else {
+				printk(KERN_WARNING
+					"%s: enable_time() failed for %s: %d\n",
+					__func__, rdev_get_name(rdev),
+					ret);
+				delay = 0;
 			}
+
+			/* Allow the regulator to ramp; it would be useful
+			 * to extend this for bulk operations so that the
+			 * regulators can ramp together.  */
+			ret = rdev->desc->ops->enable(rdev);
+			if (ret < 0)
+				return ret;
+
+			if (delay >= 1000)
+				mdelay(delay / 1000);
+			else if (delay)
+				udelay(delay);
+
 		} else if (ret < 0) {
 			printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n",
 			       __func__, rdev_get_name(rdev), ret);
@@ -1341,6 +1390,9 @@ static int _regulator_disable(struct reg
 				       __func__, rdev_get_name(rdev));
 				return ret;
 			}
+
+			_notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
+					     NULL);
 		}
 
 		/* decrease our supplies ref count and disable if required */
@@ -1399,8 +1451,8 @@ static int _regulator_force_disable(stru
 			return ret;
 		}
 		/* notify other consumers that power has been forced off */
-		_notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE,
-			NULL);
+		_notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
+			REGULATOR_EVENT_DISABLE, NULL);
 	}
 
 	/* decrease our supplies ref count and disable if required */
@@ -1434,9 +1486,9 @@ EXPORT_SYMBOL_GPL(regulator_force_disabl
 
 static int _regulator_is_enabled(struct regulator_dev *rdev)
 {
-	/* sanity check */
+	/* If we don't know then assume that the regulator is always on */
 	if (!rdev->desc->ops->is_enabled)
-		return -EINVAL;
+		return 1;
 
 	return rdev->desc->ops->is_enabled(rdev);
 }
@@ -2451,8 +2503,15 @@ EXPORT_SYMBOL_GPL(regulator_get_init_drv
 
 static int __init regulator_init(void)
 {
+	int ret;
+
 	printk(KERN_INFO "regulator: core version %s\n", REGULATOR_VERSION);
-	return class_register(&regulator_class);
+
+	ret = class_register(&regulator_class);
+
+	regulator_dummy_init();
+
+	return ret;
 }
 
 /* init early to allow our consumers to complete system booting */
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/dummy.c linux-libre-2.6.34-gnu1/drivers/regulator/dummy.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/dummy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/dummy.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,66 @@
+/*
+ * dummy.c
+ *
+ * Copyright 2010 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This is useful for systems with mixed controllable and
+ * non-controllable regulators, as well as for allowing testing on
+ * systems with no controllable regulators.
+ */
+
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+
+#include "dummy.h"
+
+struct regulator_dev *dummy_regulator_rdev;
+
+static struct regulator_init_data dummy_initdata;
+
+static struct regulator_ops dummy_ops;
+
+static struct regulator_desc dummy_desc = {
+	.name = "dummy",
+	.id = -1,
+	.type = REGULATOR_VOLTAGE,
+	.owner = THIS_MODULE,
+	.ops = &dummy_ops,
+};
+
+static struct platform_device *dummy_pdev;
+
+void __init regulator_dummy_init(void)
+{
+	int ret;
+
+	dummy_pdev = platform_device_alloc("reg-dummy", -1);
+	if (!dummy_pdev) {
+		pr_err("Failed to allocate dummy regulator device\n");
+		return;
+	}
+
+	ret = platform_device_add(dummy_pdev);
+	if (ret != 0) {
+		pr_err("Failed to register dummy regulator device: %d\n", ret);
+		platform_device_put(dummy_pdev);
+		return;
+	}
+
+	dummy_regulator_rdev = regulator_register(&dummy_desc, NULL,
+						  &dummy_initdata, NULL);
+	if (IS_ERR(dummy_regulator_rdev)) {
+		ret = PTR_ERR(dummy_regulator_rdev);
+		pr_err("Failed to register regulator: %d\n", ret);
+		platform_device_unregister(dummy_pdev);
+		return;
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/dummy.h linux-libre-2.6.34-gnu1/drivers/regulator/dummy.h
--- linux-libre-2.6.33-gnu1/drivers/regulator/dummy.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/dummy.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,31 @@
+/*
+ * dummy.h
+ *
+ * Copyright 2010 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This is useful for systems with mixed controllable and
+ * non-controllable regulators, as well as for allowing testing on
+ * systems with no controllable regulators.
+ */
+
+#ifndef _DUMMY_H
+#define _DUMMY_H
+
+struct regulator_dev;
+
+extern struct regulator_dev *dummy_regulator_rdev;
+
+#ifdef CONFIG_REGULATOR_DUMMY
+void __init regulator_dummy_init(void);
+#else
+static inline void regulator_dummy_init(void) { }
+#endif
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/fixed.c linux-libre-2.6.34-gnu1/drivers/regulator/fixed.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/fixed.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/fixed.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,14 +24,17 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/fixed.h>
 #include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
 
 struct fixed_voltage_data {
 	struct regulator_desc desc;
 	struct regulator_dev *dev;
 	int microvolts;
 	int gpio;
-	unsigned enable_high:1;
-	unsigned is_enabled:1;
+	unsigned startup_delay;
+	bool enable_high;
+	bool is_enabled;
 };
 
 static int fixed_voltage_is_enabled(struct regulator_dev *dev)
@@ -47,7 +50,7 @@ static int fixed_voltage_enable(struct r
 
 	if (gpio_is_valid(data->gpio)) {
 		gpio_set_value_cansleep(data->gpio, data->enable_high);
-		data->is_enabled = 1;
+		data->is_enabled = true;
 	}
 
 	return 0;
@@ -59,12 +62,19 @@ static int fixed_voltage_disable(struct
 
 	if (gpio_is_valid(data->gpio)) {
 		gpio_set_value_cansleep(data->gpio, !data->enable_high);
-		data->is_enabled = 0;
+		data->is_enabled = false;
 	}
 
 	return 0;
 }
 
+static int fixed_voltage_enable_time(struct regulator_dev *dev)
+{
+	struct fixed_voltage_data *data = rdev_get_drvdata(dev);
+
+	return data->startup_delay;
+}
+
 static int fixed_voltage_get_voltage(struct regulator_dev *dev)
 {
 	struct fixed_voltage_data *data = rdev_get_drvdata(dev);
@@ -87,11 +97,12 @@ static struct regulator_ops fixed_voltag
 	.is_enabled = fixed_voltage_is_enabled,
 	.enable = fixed_voltage_enable,
 	.disable = fixed_voltage_disable,
+	.enable_time = fixed_voltage_enable_time,
 	.get_voltage = fixed_voltage_get_voltage,
 	.list_voltage = fixed_voltage_list_voltage,
 };
 
-static int regulator_fixed_voltage_probe(struct platform_device *pdev)
+static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
 {
 	struct fixed_voltage_config *config = pdev->dev.platform_data;
 	struct fixed_voltage_data *drvdata;
@@ -117,6 +128,7 @@ static int regulator_fixed_voltage_probe
 
 	drvdata->microvolts = config->microvolts;
 	drvdata->gpio = config->gpio;
+	drvdata->startup_delay = config->startup_delay;
 
 	if (gpio_is_valid(config->gpio)) {
 		drvdata->enable_high = config->enable_high;
@@ -163,7 +175,7 @@ static int regulator_fixed_voltage_probe
 		/* Regulator without GPIO control is considered
 		 * always enabled
 		 */
-		drvdata->is_enabled = 1;
+		drvdata->is_enabled = true;
 	}
 
 	drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
@@ -191,7 +203,7 @@ err:
 	return ret;
 }
 
-static int regulator_fixed_voltage_remove(struct platform_device *pdev)
+static int __devexit reg_fixed_voltage_remove(struct platform_device *pdev)
 {
 	struct fixed_voltage_data *drvdata = platform_get_drvdata(pdev);
 
@@ -205,10 +217,11 @@ static int regulator_fixed_voltage_remov
 }
 
 static struct platform_driver regulator_fixed_voltage_driver = {
-	.probe		= regulator_fixed_voltage_probe,
-	.remove		= regulator_fixed_voltage_remove,
+	.probe		= reg_fixed_voltage_probe,
+	.remove		= __devexit_p(reg_fixed_voltage_remove),
 	.driver		= {
 		.name		= "reg-fixed-voltage",
+		.owner		= THIS_MODULE,
 	},
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/Kconfig linux-libre-2.6.34-gnu1/drivers/regulator/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/regulator/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,17 @@ config REGULATOR_DEBUG
 	help
 	  Say yes here to enable debugging support.
 
+config REGULATOR_DUMMY
+	bool "Provide a dummy regulator if regulator lookups fail"
+	help
+	  If this option is enabled then when a regulator lookup fails
+	  and the board has not specified that it has provided full
+	  constraints then the regulator core will provide an always
+	  enabled dummy regulator will be provided, allowing consumer
+	  drivers to continue.
+
+	  A warning will be generated when this substitution is done.
+
 config REGULATOR_FIXED_VOLTAGE
 	tristate "Fixed voltage regulator support"
 	help
@@ -69,6 +80,13 @@ config REGULATOR_MAX1586
 	  regulator via I2C bus. The provided regulator is suitable
 	  for PXA27x chips to control VCC_CORE and VCC_USIM voltages.
 
+config REGULATOR_MAX8649
+	tristate "Maxim 8649 voltage regulator"
+	depends on I2C
+	help
+	  This driver controls a Maxim 8649 voltage output regulator via
+	  I2C bus.
+
 config REGULATOR_MAX8660
 	tristate "Maxim 8660/8661 voltage regulator"
 	depends on I2C
@@ -76,6 +94,12 @@ config REGULATOR_MAX8660
 	  This driver controls a Maxim 8660/8661 voltage output
 	  regulator via I2C bus.
 
+config REGULATOR_MAX8925
+	tristate "Maxim MAX8925 Power Management IC"
+	depends on MFD_MAX8925
+	help
+	  Say y here to support the voltage regulaltor of Maxim MAX8925 PMIC.
+
 config REGULATOR_TWL4030
 	bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC"
 	depends on TWL4030_CORE
@@ -91,19 +115,26 @@ config REGULATOR_WM831X
 	  of PMIC devices.
 
 config REGULATOR_WM8350
-	tristate "Wolfson Microelectroncis WM8350 AudioPlus PMIC"
+	tristate "Wolfson Microelectronics WM8350 AudioPlus PMIC"
 	depends on MFD_WM8350
 	help
 	  This driver provides support for the voltage and current regulators
           of the WM8350 AudioPlus PMIC.
 
 config REGULATOR_WM8400
-	tristate "Wolfson Microelectroncis WM8400 AudioPlus PMIC"
+	tristate "Wolfson Microelectronics WM8400 AudioPlus PMIC"
 	depends on MFD_WM8400
 	help
 	  This driver provides support for the voltage regulators of the
 	  WM8400 AudioPlus PMIC.
 
+config REGULATOR_WM8994
+	tristate "Wolfson Microelectronics WM8994 CODEC"
+	depends on MFD_WM8994
+	help
+	  This driver provides support for the voltage regulators on the
+	  WM8994 CODEC.
+
 config REGULATOR_DA903X
 	tristate "Support regulators on Dialog Semiconductor DA9030/DA9034 PMIC"
 	depends on PMIC_DA903X
@@ -166,7 +197,7 @@ config REGULATOR_TPS6507X
 
 config REGULATOR_88PM8607
 	bool "Marvell 88PM8607 Power regulators"
-	depends on MFD_88PM8607=y
+	depends on MFD_88PM860X=y
 	help
 	  This driver supports 88PM8607 voltage regulator chips.
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/lp3971.c linux-libre-2.6.34-gnu1/drivers/regulator/lp3971.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/lp3971.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/lp3971.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/lp3971.h>
+#include <linux/slab.h>
 
 struct lp3971 {
 	struct device *dev;
@@ -45,7 +46,7 @@ static int lp3971_set_bits(struct lp3971
 	LP3971_BUCK2 -> 4
 	LP3971_BUCK3 -> 6
 */
-#define BUCK_VOL_CHANGE_SHIFT(x) (((1 << x) & ~0x01) << 1)
+#define BUCK_VOL_CHANGE_SHIFT(x) (((!!x) << 2) | (x & ~0x01))
 #define BUCK_VOL_CHANGE_FLAG_GO 0x01
 #define BUCK_VOL_CHANGE_FLAG_TARGET 0x02
 #define BUCK_VOL_CHANGE_FLAG_MASK 0x03
@@ -54,7 +55,7 @@ static int lp3971_set_bits(struct lp3971
 #define LP3971_BUCK2_BASE 0x29
 #define LP3971_BUCK3_BASE 0x32
 
-const static int buck_base_addr[] = {
+static const int buck_base_addr[] = {
 	LP3971_BUCK1_BASE,
 	LP3971_BUCK2_BASE,
 	LP3971_BUCK3_BASE,
@@ -63,7 +64,7 @@ const static int buck_base_addr[] = {
 #define LP3971_BUCK_TARGET_VOL1_REG(x) (buck_base_addr[x])
 #define LP3971_BUCK_TARGET_VOL2_REG(x) (buck_base_addr[x]+1)
 
-const static int buck_voltage_map[] = {
+static const int buck_voltage_map[] = {
 	   0,  800,  850,  900,  950, 1000, 1050, 1100,
 	1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500,
 	1550, 1600, 1650, 1700, 1800, 1900, 2500, 2800,
@@ -96,17 +97,17 @@ const static int buck_voltage_map[] = {
 #define LDO_VOL_CONTR_SHIFT(x) ((x & 1) << 2)
 #define LDO_VOL_CONTR_MASK 0x0f
 
-const static int ldo45_voltage_map[] = {
+static const int ldo45_voltage_map[] = {
 	1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350,
 	1400, 1500, 1800, 1900, 2500, 2800, 3000, 3300,
 };
 
-const static int ldo123_voltage_map[] = {
+static const int ldo123_voltage_map[] = {
 	1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500,
 	2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300,
 };
 
-const static int *ldo_voltage_map[] = {
+static const int *ldo_voltage_map[] = {
 	ldo123_voltage_map, /* LDO1 */
 	ldo123_voltage_map, /* LDO2 */
 	ldo123_voltage_map, /* LDO3 */
@@ -187,7 +188,8 @@ static int lp3971_ldo_set_voltage(struct
 		return -EINVAL;
 
 	return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo),
-		LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo), val);
+			LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo),
+			val << LDO_VOL_CONTR_SHIFT(ldo));
 }
 
 static struct regulator_ops lp3971_ldo_ops = {
@@ -431,20 +433,24 @@ static int lp3971_set_bits(struct lp3971
 	return ret;
 }
 
-static int setup_regulators(struct lp3971 *lp3971,
-	struct lp3971_platform_data *pdata)
+static int __devinit setup_regulators(struct lp3971 *lp3971,
+				      struct lp3971_platform_data *pdata)
 {
 	int i, err;
-	int num_regulators = pdata->num_regulators;
-	lp3971->num_regulators = num_regulators;
-	lp3971->rdev = kzalloc(sizeof(struct regulator_dev *) * num_regulators,
-		GFP_KERNEL);
+
+	lp3971->num_regulators = pdata->num_regulators;
+	lp3971->rdev = kcalloc(pdata->num_regulators,
+				sizeof(struct regulator_dev *), GFP_KERNEL);
+	if (!lp3971->rdev) {
+		err = -ENOMEM;
+		goto err_nomem;
+	}
 
 	/* Instantiate the regulators */
-	for (i = 0; i < num_regulators; i++) {
-		int id = pdata->regulators[i].id;
-		lp3971->rdev[i] = regulator_register(&regulators[id],
-			lp3971->dev, pdata->regulators[i].initdata, lp3971);
+	for (i = 0; i < pdata->num_regulators; i++) {
+		struct lp3971_regulator_subdev *reg = &pdata->regulators[i];
+		lp3971->rdev[i] = regulator_register(&regulators[reg->id],
+					lp3971->dev, reg->initdata, lp3971);
 
 		if (IS_ERR(lp3971->rdev[i])) {
 			err = PTR_ERR(lp3971->rdev[i]);
@@ -455,12 +461,13 @@ static int setup_regulators(struct lp397
 	}
 
 	return 0;
+
 error:
-	for (i = 0; i < num_regulators; i++)
-		if (lp3971->rdev[i])
-			regulator_unregister(lp3971->rdev[i]);
+	while (--i >= 0)
+		regulator_unregister(lp3971->rdev[i]);
 	kfree(lp3971->rdev);
 	lp3971->rdev = NULL;
+err_nomem:
 	return err;
 }
 
@@ -472,15 +479,17 @@ static int __devinit lp3971_i2c_probe(st
 	int ret;
 	u16 val;
 
-	lp3971 = kzalloc(sizeof(struct lp3971), GFP_KERNEL);
-	if (lp3971 == NULL) {
-		ret = -ENOMEM;
-		goto err;
+	if (!pdata) {
+		dev_dbg(&i2c->dev, "No platform init data supplied\n");
+		return -ENODEV;
 	}
 
+	lp3971 = kzalloc(sizeof(struct lp3971), GFP_KERNEL);
+	if (lp3971 == NULL)
+		return -ENOMEM;
+
 	lp3971->i2c = i2c;
 	lp3971->dev = &i2c->dev;
-	i2c_set_clientdata(i2c, lp3971);
 
 	mutex_init(&lp3971->io_lock);
 
@@ -493,19 +502,15 @@ static int __devinit lp3971_i2c_probe(st
 		goto err_detect;
 	}
 
-	if (pdata) {
-		ret = setup_regulators(lp3971, pdata);
-		if (ret < 0)
-			goto err_detect;
-	} else
-		dev_warn(lp3971->dev, "No platform init data supplied\n");
+	ret = setup_regulators(lp3971, pdata);
+	if (ret < 0)
+		goto err_detect;
 
+	i2c_set_clientdata(i2c, lp3971);
 	return 0;
 
 err_detect:
-	i2c_set_clientdata(i2c, NULL);
 	kfree(lp3971);
-err:
 	return ret;
 }
 
@@ -513,11 +518,13 @@ static int __devexit lp3971_i2c_remove(s
 {
 	struct lp3971 *lp3971 = i2c_get_clientdata(i2c);
 	int i;
+
+	i2c_set_clientdata(i2c, NULL);
+
 	for (i = 0; i < lp3971->num_regulators; i++)
-		if (lp3971->rdev[i])
-			regulator_unregister(lp3971->rdev[i]);
+		regulator_unregister(lp3971->rdev[i]);
+
 	kfree(lp3971->rdev);
-	i2c_set_clientdata(i2c, NULL);
 	kfree(lp3971);
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/Makefile linux-libre-2.6.34-gnu1/drivers/regulator/Makefile
--- linux-libre-2.6.33-gnu1/drivers/regulator/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -9,15 +9,19 @@ obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER)
 obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
 
 obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
+obj-$(CONFIG_REGULATOR_DUMMY) += dummy.o
 obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
 obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
 obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
+obj-$(CONFIG_REGULATOR_MAX8649)	+= max8649.o
 obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
+obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
 obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
+obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
 obj-$(CONFIG_REGULATOR_DA903X)	+= da903x.o
 obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
 obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/max1586.c linux-libre-2.6.34-gnu1/drivers/regulator/max1586.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/max1586.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/max1586.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
+#include <linux/slab.h>
 #include <linux/regulator/max1586.h>
 
 #define MAX1586_V3_MAX_VSEL 31
@@ -179,8 +180,8 @@ static struct regulator_desc max1586_reg
 	},
 };
 
-static int max1586_pmic_probe(struct i2c_client *client,
-			      const struct i2c_device_id *i2c_id)
+static int __devinit max1586_pmic_probe(struct i2c_client *client,
+					const struct i2c_device_id *i2c_id)
 {
 	struct regulator_dev **rdev;
 	struct max1586_platform_data *pdata = client->dev.platform_data;
@@ -235,7 +236,7 @@ out:
 	return ret;
 }
 
-static int max1586_pmic_remove(struct i2c_client *client)
+static int __devexit max1586_pmic_remove(struct i2c_client *client)
 {
 	struct regulator_dev **rdev = i2c_get_clientdata(client);
 	int i;
@@ -243,8 +244,8 @@ static int max1586_pmic_remove(struct i2
 	for (i = 0; i <= MAX1586_V6; i++)
 		if (rdev[i])
 			regulator_unregister(rdev[i]);
-	kfree(rdev);
 	i2c_set_clientdata(client, NULL);
+	kfree(rdev);
 
 	return 0;
 }
@@ -257,9 +258,10 @@ MODULE_DEVICE_TABLE(i2c, max1586_id);
 
 static struct i2c_driver max1586_pmic_driver = {
 	.probe = max1586_pmic_probe,
-	.remove = max1586_pmic_remove,
+	.remove = __devexit_p(max1586_pmic_remove),
 	.driver		= {
 		.name	= "max1586",
+		.owner	= THIS_MODULE,
 	},
 	.id_table	= max1586_id,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/max8649.c linux-libre-2.6.34-gnu1/drivers/regulator/max8649.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/max8649.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/max8649.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,410 @@
+/*
+ * Regulators driver for Maxim max8649
+ *
+ * Copyright (C) 2009-2010 Marvell International Ltd.
+ *      Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/slab.h>
+#include <linux/regulator/max8649.h>
+
+#define MAX8649_DCDC_VMIN	750000		/* uV */
+#define MAX8649_DCDC_VMAX	1380000		/* uV */
+#define MAX8649_DCDC_STEP	10000		/* uV */
+#define MAX8649_VOL_MASK	0x3f
+
+/* Registers */
+#define MAX8649_MODE0		0x00
+#define MAX8649_MODE1		0x01
+#define MAX8649_MODE2		0x02
+#define MAX8649_MODE3		0x03
+#define MAX8649_CONTROL		0x04
+#define MAX8649_SYNC		0x05
+#define MAX8649_RAMP		0x06
+#define MAX8649_CHIP_ID1	0x08
+#define MAX8649_CHIP_ID2	0x09
+
+/* Bits */
+#define MAX8649_EN_PD		(1 << 7)
+#define MAX8649_VID0_PD		(1 << 6)
+#define MAX8649_VID1_PD		(1 << 5)
+#define MAX8649_VID_MASK	(3 << 5)
+
+#define MAX8649_FORCE_PWM	(1 << 7)
+#define MAX8649_SYNC_EXTCLK	(1 << 6)
+
+#define MAX8649_EXT_MASK	(3 << 6)
+
+#define MAX8649_RAMP_MASK	(7 << 5)
+#define MAX8649_RAMP_DOWN	(1 << 1)
+
+struct max8649_regulator_info {
+	struct regulator_dev	*regulator;
+	struct i2c_client	*i2c;
+	struct device		*dev;
+	struct mutex		io_lock;
+
+	int		vol_reg;
+	unsigned	mode:2;	/* bit[1:0] = VID1, VID0 */
+	unsigned	extclk_freq:2;
+	unsigned	extclk:1;
+	unsigned	ramp_timing:3;
+	unsigned	ramp_down:1;
+};
+
+/* I2C operations */
+
+static inline int max8649_read_device(struct i2c_client *i2c,
+				      int reg, int bytes, void *dest)
+{
+	unsigned char data;
+	int ret;
+
+	data = (unsigned char)reg;
+	ret = i2c_master_send(i2c, &data, 1);
+	if (ret < 0)
+		return ret;
+	ret = i2c_master_recv(i2c, dest, bytes);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static inline int max8649_write_device(struct i2c_client *i2c,
+				       int reg, int bytes, void *src)
+{
+	unsigned char buf[bytes + 1];
+	int ret;
+
+	buf[0] = (unsigned char)reg;
+	memcpy(&buf[1], src, bytes);
+
+	ret = i2c_master_send(i2c, buf, bytes + 1);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static int max8649_reg_read(struct i2c_client *i2c, int reg)
+{
+	struct max8649_regulator_info *info = i2c_get_clientdata(i2c);
+	unsigned char data;
+	int ret;
+
+	mutex_lock(&info->io_lock);
+	ret = max8649_read_device(i2c, reg, 1, &data);
+	mutex_unlock(&info->io_lock);
+
+	if (ret < 0)
+		return ret;
+	return (int)data;
+}
+
+static int max8649_set_bits(struct i2c_client *i2c, int reg,
+			    unsigned char mask, unsigned char data)
+{
+	struct max8649_regulator_info *info = i2c_get_clientdata(i2c);
+	unsigned char value;
+	int ret;
+
+	mutex_lock(&info->io_lock);
+	ret = max8649_read_device(i2c, reg, 1, &value);
+	if (ret < 0)
+		goto out;
+	value &= ~mask;
+	value |= data;
+	ret = max8649_write_device(i2c, reg, 1, &value);
+out:
+	mutex_unlock(&info->io_lock);
+	return ret;
+}
+
+static inline int check_range(int min_uV, int max_uV)
+{
+	if ((min_uV < MAX8649_DCDC_VMIN) || (max_uV > MAX8649_DCDC_VMAX)
+		|| (min_uV > max_uV))
+		return -EINVAL;
+	return 0;
+}
+
+static int max8649_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+	return (MAX8649_DCDC_VMIN + index * MAX8649_DCDC_STEP);
+}
+
+static int max8649_get_voltage(struct regulator_dev *rdev)
+{
+	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
+	unsigned char data;
+	int ret;
+
+	ret = max8649_reg_read(info->i2c, info->vol_reg);
+	if (ret < 0)
+		return ret;
+	data = (unsigned char)ret & MAX8649_VOL_MASK;
+	return max8649_list_voltage(rdev, data);
+}
+
+static int max8649_set_voltage(struct regulator_dev *rdev,
+			       int min_uV, int max_uV)
+{
+	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
+	unsigned char data, mask;
+
+	if (check_range(min_uV, max_uV)) {
+		dev_err(info->dev, "invalid voltage range (%d, %d) uV\n",
+			min_uV, max_uV);
+		return -EINVAL;
+	}
+	data = (min_uV - MAX8649_DCDC_VMIN + MAX8649_DCDC_STEP - 1)
+		/ MAX8649_DCDC_STEP;
+	mask = MAX8649_VOL_MASK;
+
+	return max8649_set_bits(info->i2c, info->vol_reg, mask, data);
+}
+
+/* EN_PD means pulldown on EN input */
+static int max8649_enable(struct regulator_dev *rdev)
+{
+	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
+	return max8649_set_bits(info->i2c, MAX8649_CONTROL, MAX8649_EN_PD, 0);
+}
+
+/*
+ * Applied internal pulldown resistor on EN input pin.
+ * If pulldown EN pin outside, it would be better.
+ */
+static int max8649_disable(struct regulator_dev *rdev)
+{
+	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
+	return max8649_set_bits(info->i2c, MAX8649_CONTROL, MAX8649_EN_PD,
+				MAX8649_EN_PD);
+}
+
+static int max8649_is_enabled(struct regulator_dev *rdev)
+{
+	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
+	int ret;
+
+	ret = max8649_reg_read(info->i2c, MAX8649_CONTROL);
+	if (ret < 0)
+		return ret;
+	return !((unsigned char)ret & MAX8649_EN_PD);
+}
+
+static int max8649_enable_time(struct regulator_dev *rdev)
+{
+	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
+	int voltage, rate, ret;
+
+	/* get voltage */
+	ret = max8649_reg_read(info->i2c, info->vol_reg);
+	if (ret < 0)
+		return ret;
+	ret &= MAX8649_VOL_MASK;
+	voltage = max8649_list_voltage(rdev, (unsigned char)ret); /* uV */
+
+	/* get rate */
+	ret = max8649_reg_read(info->i2c, MAX8649_RAMP);
+	if (ret < 0)
+		return ret;
+	ret = (ret & MAX8649_RAMP_MASK) >> 5;
+	rate = (32 * 1000) >> ret;	/* uV/uS */
+
+	return (voltage / rate);
+}
+
+static int max8649_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
+
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		max8649_set_bits(info->i2c, info->vol_reg, MAX8649_FORCE_PWM,
+				 MAX8649_FORCE_PWM);
+		break;
+	case REGULATOR_MODE_NORMAL:
+		max8649_set_bits(info->i2c, info->vol_reg,
+				 MAX8649_FORCE_PWM, 0);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static unsigned int max8649_get_mode(struct regulator_dev *rdev)
+{
+	struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
+	int ret;
+
+	ret = max8649_reg_read(info->i2c, info->vol_reg);
+	if (ret & MAX8649_FORCE_PWM)
+		return REGULATOR_MODE_FAST;
+	return REGULATOR_MODE_NORMAL;
+}
+
+static struct regulator_ops max8649_dcdc_ops = {
+	.set_voltage	= max8649_set_voltage,
+	.get_voltage	= max8649_get_voltage,
+	.list_voltage	= max8649_list_voltage,
+	.enable		= max8649_enable,
+	.disable	= max8649_disable,
+	.is_enabled	= max8649_is_enabled,
+	.enable_time	= max8649_enable_time,
+	.set_mode	= max8649_set_mode,
+	.get_mode	= max8649_get_mode,
+
+};
+
+static struct regulator_desc dcdc_desc = {
+	.name		= "max8649",
+	.ops		= &max8649_dcdc_ops,
+	.type		= REGULATOR_VOLTAGE,
+	.n_voltages	= 1 << 6,
+	.owner		= THIS_MODULE,
+};
+
+static int __devinit max8649_regulator_probe(struct i2c_client *client,
+					     const struct i2c_device_id *id)
+{
+	struct max8649_platform_data *pdata = client->dev.platform_data;
+	struct max8649_regulator_info *info = NULL;
+	unsigned char data;
+	int ret;
+
+	info = kzalloc(sizeof(struct max8649_regulator_info), GFP_KERNEL);
+	if (!info) {
+		dev_err(&client->dev, "No enough memory\n");
+		return -ENOMEM;
+	}
+
+	info->i2c = client;
+	info->dev = &client->dev;
+	mutex_init(&info->io_lock);
+	i2c_set_clientdata(client, info);
+
+	info->mode = pdata->mode;
+	switch (info->mode) {
+	case 0:
+		info->vol_reg = MAX8649_MODE0;
+		break;
+	case 1:
+		info->vol_reg = MAX8649_MODE1;
+		break;
+	case 2:
+		info->vol_reg = MAX8649_MODE2;
+		break;
+	case 3:
+		info->vol_reg = MAX8649_MODE3;
+		break;
+	default:
+		break;
+	}
+
+	ret = max8649_reg_read(info->i2c, MAX8649_CHIP_ID1);
+	if (ret < 0) {
+		dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n",
+			ret);
+		goto out;
+	}
+	dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", ret);
+
+	/* enable VID0 & VID1 */
+	max8649_set_bits(info->i2c, MAX8649_CONTROL, MAX8649_VID_MASK, 0);
+
+	/* enable/disable external clock synchronization */
+	info->extclk = pdata->extclk;
+	data = (info->extclk) ? MAX8649_SYNC_EXTCLK : 0;
+	max8649_set_bits(info->i2c, info->vol_reg, MAX8649_SYNC_EXTCLK, data);
+	if (info->extclk) {
+		/* set external clock frequency */
+		info->extclk_freq = pdata->extclk_freq;
+		max8649_set_bits(info->i2c, MAX8649_SYNC, MAX8649_EXT_MASK,
+				 info->extclk_freq);
+	}
+
+	if (pdata->ramp_timing) {
+		info->ramp_timing = pdata->ramp_timing;
+		max8649_set_bits(info->i2c, MAX8649_RAMP, MAX8649_RAMP_MASK,
+				 info->ramp_timing << 5);
+	}
+
+	info->ramp_down = pdata->ramp_down;
+	if (info->ramp_down) {
+		max8649_set_bits(info->i2c, MAX8649_RAMP, MAX8649_RAMP_DOWN,
+				 MAX8649_RAMP_DOWN);
+	}
+
+	info->regulator = regulator_register(&dcdc_desc, &client->dev,
+					     pdata->regulator, info);
+	if (IS_ERR(info->regulator)) {
+		dev_err(info->dev, "failed to register regulator %s\n",
+			dcdc_desc.name);
+		ret = PTR_ERR(info->regulator);
+		goto out;
+	}
+
+	dev_info(info->dev, "Max8649 regulator device is detected.\n");
+	return 0;
+out:
+	i2c_set_clientdata(client, NULL);
+	kfree(info);
+	return ret;
+}
+
+static int __devexit max8649_regulator_remove(struct i2c_client *client)
+{
+	struct max8649_regulator_info *info = i2c_get_clientdata(client);
+
+	if (info) {
+		if (info->regulator)
+			regulator_unregister(info->regulator);
+		i2c_set_clientdata(client, NULL);
+		kfree(info);
+	}
+
+	return 0;
+}
+
+static const struct i2c_device_id max8649_id[] = {
+	{ "max8649", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, max8649_id);
+
+static struct i2c_driver max8649_driver = {
+	.probe		= max8649_regulator_probe,
+	.remove		= __devexit_p(max8649_regulator_remove),
+	.driver		= {
+		.name	= "max8649",
+	},
+	.id_table	= max8649_id,
+};
+
+static int __init max8649_init(void)
+{
+	return i2c_add_driver(&max8649_driver);
+}
+subsys_initcall(max8649_init);
+
+static void __exit max8649_exit(void)
+{
+	i2c_del_driver(&max8649_driver);
+}
+module_exit(max8649_exit);
+
+/* Module information */
+MODULE_DESCRIPTION("MAXIM 8649 voltage regulator driver");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/max8660.c linux-libre-2.6.34-gnu1/drivers/regulator/max8660.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/max8660.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/max8660.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
+#include <linux/slab.h>
 #include <linux/regulator/max8660.h>
 
 #define MAX8660_DCDC_MIN_UV	 725000
@@ -345,8 +346,8 @@ static struct regulator_desc max8660_reg
 	},
 };
 
-static int max8660_probe(struct i2c_client *client,
-			      const struct i2c_device_id *i2c_id)
+static int __devinit max8660_probe(struct i2c_client *client,
+				   const struct i2c_device_id *i2c_id)
 {
 	struct regulator_dev **rdev;
 	struct max8660_platform_data *pdata = client->dev.platform_data;
@@ -354,7 +355,7 @@ static int max8660_probe(struct i2c_clie
 	int boot_on, i, id, ret = -EINVAL;
 
 	if (pdata->num_subdevs > MAX8660_V_END) {
-		dev_err(&client->dev, "Too much regulators found!\n");
+		dev_err(&client->dev, "Too many regulators found!\n");
 		goto out;
 	}
 
@@ -462,7 +463,7 @@ out:
 	return ret;
 }
 
-static int max8660_remove(struct i2c_client *client)
+static int __devexit max8660_remove(struct i2c_client *client)
 {
 	struct regulator_dev **rdev = i2c_get_clientdata(client);
 	int i;
@@ -470,8 +471,8 @@ static int max8660_remove(struct i2c_cli
 	for (i = 0; i < MAX8660_V_END; i++)
 		if (rdev[i])
 			regulator_unregister(rdev[i]);
-	kfree(rdev);
 	i2c_set_clientdata(client, NULL);
+	kfree(rdev);
 
 	return 0;
 }
@@ -485,9 +486,10 @@ MODULE_DEVICE_TABLE(i2c, max8660_id);
 
 static struct i2c_driver max8660_driver = {
 	.probe = max8660_probe,
-	.remove = max8660_remove,
+	.remove = __devexit_p(max8660_remove),
 	.driver		= {
 		.name	= "max8660",
+		.owner	= THIS_MODULE,
 	},
 	.id_table	= max8660_id,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/max8925-regulator.c linux-libre-2.6.34-gnu1/drivers/regulator/max8925-regulator.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/max8925-regulator.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/max8925-regulator.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,308 @@
+/*
+ * Regulators driver for Maxim max8925
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ *      Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/max8925.h>
+
+#define SD1_DVM_VMIN		850000
+#define SD1_DVM_VMAX		1000000
+#define SD1_DVM_STEP		50000
+#define SD1_DVM_SHIFT		5		/* SDCTL1 bit5 */
+#define SD1_DVM_EN		6		/* SDV1 bit 6 */
+
+struct max8925_regulator_info {
+	struct regulator_desc	desc;
+	struct regulator_dev	*regulator;
+	struct i2c_client	*i2c;
+	struct max8925_chip	*chip;
+
+	int	min_uV;
+	int	max_uV;
+	int	step_uV;
+	int	vol_reg;
+	int	vol_shift;
+	int	vol_nbits;
+	int	enable_bit;
+	int	enable_reg;
+};
+
+static inline int check_range(struct max8925_regulator_info *info,
+			      int min_uV, int max_uV)
+{
+	if (min_uV < info->min_uV || min_uV > info->max_uV)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int max8925_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+	struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+	return info->min_uV + index * info->step_uV;
+}
+
+static int max8925_set_voltage(struct regulator_dev *rdev,
+			       int min_uV, int max_uV)
+{
+	struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+	unsigned char data, mask;
+
+	if (check_range(info, min_uV, max_uV)) {
+		dev_err(info->chip->dev, "invalid voltage range (%d, %d) uV\n",
+			min_uV, max_uV);
+		return -EINVAL;
+	}
+	data = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV;
+	data <<= info->vol_shift;
+	mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
+
+	return max8925_set_bits(info->i2c, info->vol_reg, mask, data);
+}
+
+static int max8925_get_voltage(struct regulator_dev *rdev)
+{
+	struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+	unsigned char data, mask;
+	int ret;
+
+	ret = max8925_reg_read(info->i2c, info->vol_reg);
+	if (ret < 0)
+		return ret;
+	mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
+	data = (ret & mask) >> info->vol_shift;
+
+	return max8925_list_voltage(rdev, data);
+}
+
+static int max8925_enable(struct regulator_dev *rdev)
+{
+	struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+
+	return max8925_set_bits(info->i2c, info->enable_reg,
+				1 << info->enable_bit,
+				1 << info->enable_bit);
+}
+
+static int max8925_disable(struct regulator_dev *rdev)
+{
+	struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+
+	return max8925_set_bits(info->i2c, info->enable_reg,
+				1 << info->enable_bit, 0);
+}
+
+static int max8925_is_enabled(struct regulator_dev *rdev)
+{
+	struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+	int ret;
+
+	ret = max8925_reg_read(info->i2c, info->enable_reg);
+	if (ret < 0)
+		return ret;
+
+	return ret & (1 << info->enable_bit);
+}
+
+static int max8925_set_dvm_voltage(struct regulator_dev *rdev, int uV)
+{
+	struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+	unsigned char data, mask;
+
+	if (uV < SD1_DVM_VMIN || uV > SD1_DVM_VMAX)
+		return -EINVAL;
+
+	data = (uV - SD1_DVM_VMIN + SD1_DVM_STEP - 1) / SD1_DVM_STEP;
+	data <<= SD1_DVM_SHIFT;
+	mask = 3 << SD1_DVM_SHIFT;
+
+	return max8925_set_bits(info->i2c, info->enable_reg, mask, data);
+}
+
+static int max8925_set_dvm_enable(struct regulator_dev *rdev)
+{
+	struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+
+	return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN,
+				1 << SD1_DVM_EN);
+}
+
+static int max8925_set_dvm_disable(struct regulator_dev *rdev)
+{
+	struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+
+	return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN, 0);
+}
+
+static struct regulator_ops max8925_regulator_sdv_ops = {
+	.set_voltage		= max8925_set_voltage,
+	.get_voltage		= max8925_get_voltage,
+	.enable			= max8925_enable,
+	.disable		= max8925_disable,
+	.is_enabled		= max8925_is_enabled,
+	.set_suspend_voltage	= max8925_set_dvm_voltage,
+	.set_suspend_enable	= max8925_set_dvm_enable,
+	.set_suspend_disable	= max8925_set_dvm_disable,
+};
+
+static struct regulator_ops max8925_regulator_ldo_ops = {
+	.set_voltage		= max8925_set_voltage,
+	.get_voltage		= max8925_get_voltage,
+	.enable			= max8925_enable,
+	.disable		= max8925_disable,
+	.is_enabled		= max8925_is_enabled,
+};
+
+#define MAX8925_SDV(_id, min, max, step)			\
+{								\
+	.desc	= {						\
+		.name	= "SDV" #_id,				\
+		.ops	= &max8925_regulator_sdv_ops,		\
+		.type	= REGULATOR_VOLTAGE,			\
+		.id	= MAX8925_ID_SD##_id,			\
+		.owner	= THIS_MODULE,				\
+	},							\
+	.min_uV		= min * 1000,				\
+	.max_uV		= max * 1000,				\
+	.step_uV	= step * 1000,				\
+	.vol_reg	= MAX8925_SDV##_id,			\
+	.vol_shift	= 0,					\
+	.vol_nbits	= 6,					\
+	.enable_reg	= MAX8925_SDCTL##_id,			\
+	.enable_bit	= 0,					\
+}
+
+#define MAX8925_LDO(_id, min, max, step)			\
+{								\
+	.desc	= {						\
+		.name	= "LDO" #_id,				\
+		.ops	= &max8925_regulator_ldo_ops,		\
+		.type	= REGULATOR_VOLTAGE,			\
+		.id	= MAX8925_ID_LDO##_id,			\
+		.owner	= THIS_MODULE,				\
+	},							\
+	.min_uV		= min * 1000,				\
+	.max_uV		= max * 1000,				\
+	.step_uV	= step * 1000,				\
+	.vol_reg	= MAX8925_LDOVOUT##_id,			\
+	.vol_shift	= 0,					\
+	.vol_nbits	= 6,					\
+	.enable_reg	= MAX8925_LDOCTL##_id,			\
+	.enable_bit	= 0,					\
+}
+
+static struct max8925_regulator_info max8925_regulator_info[] = {
+	MAX8925_SDV(1, 637.5, 1425, 12.5),
+	MAX8925_SDV(2,   650, 2225,   25),
+	MAX8925_SDV(3,   750, 3900,   50),
+
+	MAX8925_LDO(1,  750, 3900, 50),
+	MAX8925_LDO(2,  650, 2250, 25),
+	MAX8925_LDO(3,  650, 2250, 25),
+	MAX8925_LDO(4,  750, 3900, 50),
+	MAX8925_LDO(5,  750, 3900, 50),
+	MAX8925_LDO(6,  750, 3900, 50),
+	MAX8925_LDO(7,  750, 3900, 50),
+	MAX8925_LDO(8,  750, 3900, 50),
+	MAX8925_LDO(9,  750, 3900, 50),
+	MAX8925_LDO(10, 750, 3900, 50),
+	MAX8925_LDO(11, 750, 3900, 50),
+	MAX8925_LDO(12, 750, 3900, 50),
+	MAX8925_LDO(13, 750, 3900, 50),
+	MAX8925_LDO(14, 750, 3900, 50),
+	MAX8925_LDO(15, 750, 3900, 50),
+	MAX8925_LDO(16, 750, 3900, 50),
+	MAX8925_LDO(17, 650, 2250, 25),
+	MAX8925_LDO(18, 650, 2250, 25),
+	MAX8925_LDO(19, 750, 3900, 50),
+	MAX8925_LDO(20, 750, 3900, 50),
+};
+
+static struct max8925_regulator_info * __devinit find_regulator_info(int id)
+{
+	struct max8925_regulator_info *ri;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) {
+		ri = &max8925_regulator_info[i];
+		if (ri->desc.id == id)
+			return ri;
+	}
+	return NULL;
+}
+
+static int __devinit max8925_regulator_probe(struct platform_device *pdev)
+{
+	struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct max8925_platform_data *pdata = chip->dev->platform_data;
+	struct max8925_regulator_info *ri;
+	struct regulator_dev *rdev;
+
+	ri = find_regulator_info(pdev->id);
+	if (ri == NULL) {
+		dev_err(&pdev->dev, "invalid regulator ID specified\n");
+		return -EINVAL;
+	}
+	ri->i2c = chip->i2c;
+	ri->chip = chip;
+
+	rdev = regulator_register(&ri->desc, &pdev->dev,
+				  pdata->regulator[pdev->id], ri);
+	if (IS_ERR(rdev)) {
+		dev_err(&pdev->dev, "failed to register regulator %s\n",
+				ri->desc.name);
+		return PTR_ERR(rdev);
+	}
+
+	platform_set_drvdata(pdev, rdev);
+	return 0;
+}
+
+static int __devexit max8925_regulator_remove(struct platform_device *pdev)
+{
+	struct regulator_dev *rdev = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	regulator_unregister(rdev);
+
+	return 0;
+}
+
+static struct platform_driver max8925_regulator_driver = {
+	.driver		= {
+		.name	= "max8925-regulator",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= max8925_regulator_probe,
+	.remove		= __devexit_p(max8925_regulator_remove),
+};
+
+static int __init max8925_regulator_init(void)
+{
+	return platform_driver_register(&max8925_regulator_driver);
+}
+subsys_initcall(max8925_regulator_init);
+
+static void __exit max8925_regulator_exit(void)
+{
+	platform_driver_unregister(&max8925_regulator_driver);
+}
+module_exit(max8925_regulator_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_DESCRIPTION("Regulator Driver for Maxim 8925 PMIC");
+MODULE_ALIAS("platform:max8925-regulator");
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/mc13783-regulator.c linux-libre-2.6.34-gnu1/drivers/regulator/mc13783-regulator.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/mc13783-regulator.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/mc13783-regulator.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
  * Regulator Driver for Freescale MC13783 PMIC
  *
  * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@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
@@ -13,14 +14,48 @@
 #include <linux/regulator/driver.h>
 #include <linux/platform_device.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/err.h>
 
-#define MC13783_REG_SWITCHERS4			28
-#define MC13783_REG_SWITCHERS4_PLLEN			(1 << 18)
-
 #define MC13783_REG_SWITCHERS5			29
 #define MC13783_REG_SWITCHERS5_SW3EN			(1 << 20)
+#define MC13783_REG_SWITCHERS5_SW3VSEL			18
+#define MC13783_REG_SWITCHERS5_SW3VSEL_M		(3 << 18)
+
+#define MC13783_REG_REGULATORSETTING0		30
+#define MC13783_REG_REGULATORSETTING0_VIOLOVSEL		2
+#define MC13783_REG_REGULATORSETTING0_VDIGVSEL		4
+#define MC13783_REG_REGULATORSETTING0_VGENVSEL		6
+#define MC13783_REG_REGULATORSETTING0_VRFDIGVSEL	9
+#define MC13783_REG_REGULATORSETTING0_VRFREFVSEL	11
+#define MC13783_REG_REGULATORSETTING0_VRFCPVSEL		13
+#define MC13783_REG_REGULATORSETTING0_VSIMVSEL		14
+#define MC13783_REG_REGULATORSETTING0_VESIMVSEL		15
+#define MC13783_REG_REGULATORSETTING0_VCAMVSEL		16
+
+#define MC13783_REG_REGULATORSETTING0_VIOLOVSEL_M	(3 << 2)
+#define MC13783_REG_REGULATORSETTING0_VDIGVSEL_M	(3 << 4)
+#define MC13783_REG_REGULATORSETTING0_VGENVSEL_M	(7 << 6)
+#define MC13783_REG_REGULATORSETTING0_VRFDIGVSEL_M	(3 << 9)
+#define MC13783_REG_REGULATORSETTING0_VRFREFVSEL_M	(3 << 11)
+#define MC13783_REG_REGULATORSETTING0_VRFCPVSEL_M	(1 << 13)
+#define MC13783_REG_REGULATORSETTING0_VSIMVSEL_M	(1 << 14)
+#define MC13783_REG_REGULATORSETTING0_VESIMVSEL_M	(1 << 15)
+#define MC13783_REG_REGULATORSETTING0_VCAMVSEL_M	(7 << 16)
+
+#define MC13783_REG_REGULATORSETTING1		31
+#define MC13783_REG_REGULATORSETTING1_VVIBVSEL		0
+#define MC13783_REG_REGULATORSETTING1_VRF1VSEL		2
+#define MC13783_REG_REGULATORSETTING1_VRF2VSEL		4
+#define MC13783_REG_REGULATORSETTING1_VMMC1VSEL		6
+#define MC13783_REG_REGULATORSETTING1_VMMC2VSEL		9
+
+#define MC13783_REG_REGULATORSETTING1_VVIBVSEL_M	(3 << 0)
+#define MC13783_REG_REGULATORSETTING1_VRF1VSEL_M	(3 << 2)
+#define MC13783_REG_REGULATORSETTING1_VRF2VSEL_M	(3 << 4)
+#define MC13783_REG_REGULATORSETTING1_VMMC1VSEL_M	(7 << 6)
+#define MC13783_REG_REGULATORSETTING1_VMMC2VSEL_M	(7 << 9)
 
 #define MC13783_REG_REGULATORMODE0		32
 #define MC13783_REG_REGULATORMODE0_VAUDIOEN		(1 << 0)
@@ -48,19 +83,107 @@
 #define MC13783_REG_POWERMISC_GPO2EN			(1 << 8)
 #define MC13783_REG_POWERMISC_GPO3EN			(1 << 10)
 #define MC13783_REG_POWERMISC_GPO4EN			(1 << 12)
+#define MC13783_REG_POWERMISC_PWGT1SPIEN		(1 << 15)
+#define MC13783_REG_POWERMISC_PWGT2SPIEN		(1 << 16)
+
+#define MC13783_REG_POWERMISC_PWGTSPI_M			(3 << 15)
+
 
 struct mc13783_regulator {
 	struct regulator_desc desc;
 	int reg;
 	int enable_bit;
+	int vsel_reg;
+	int vsel_shift;
+	int vsel_mask;
+	int const *voltages;
+};
+
+/* Voltage Values */
+static const int const mc13783_sw3_val[] = {
+	5000000, 5000000, 5000000, 5500000,
+};
+
+static const int const mc13783_vaudio_val[] = {
+	2775000,
+};
+
+static const int const mc13783_viohi_val[] = {
+	2775000,
+};
+
+static const int const mc13783_violo_val[] = {
+	1200000, 1300000, 1500000, 1800000,
+};
+
+static const int const mc13783_vdig_val[] = {
+	1200000, 1300000, 1500000, 1800000,
+};
+
+static const int const mc13783_vgen_val[] = {
+	1200000, 1300000, 1500000, 1800000,
+	1100000, 2000000, 2775000, 2400000,
+};
+
+static const int const mc13783_vrfdig_val[] = {
+	1200000, 1500000, 1800000, 1875000,
+};
+
+static const int const mc13783_vrfref_val[] = {
+	2475000, 2600000, 2700000, 2775000,
+};
+
+static const int const mc13783_vrfcp_val[] = {
+	2700000, 2775000,
+};
+
+static const int const mc13783_vsim_val[] = {
+	1800000, 2900000, 3000000,
+};
+
+static const int const mc13783_vesim_val[] = {
+	1800000, 2900000,
+};
+
+static const int const mc13783_vcam_val[] = {
+	1500000, 1800000, 2500000, 2550000,
+	2600000, 2750000, 2800000, 3000000,
+};
+
+static const int const mc13783_vrfbg_val[] = {
+	1250000,
+};
+
+static const int const mc13783_vvib_val[] = {
+	1300000, 1800000, 2000000, 3000000,
+};
+
+static const int const mc13783_vmmc_val[] = {
+	1600000, 1800000, 2000000, 2600000,
+	2700000, 2800000, 2900000, 3000000,
+};
+
+static const int const mc13783_vrf_val[] = {
+	1500000, 1875000, 2700000, 2775000,
+};
+
+static const int const mc13783_gpo_val[] = {
+	3100000,
+};
+
+static const int const mc13783_pwgtdrv_val[] = {
+	5500000,
 };
 
 static struct regulator_ops mc13783_regulator_ops;
+static struct regulator_ops mc13783_fixed_regulator_ops;
+static struct regulator_ops mc13783_gpo_regulator_ops;
 
-#define MC13783_DEFINE(prefix, _name, _reg)				\
+#define MC13783_DEFINE(prefix, _name, _reg, _vsel_reg, _voltages)	\
 	[MC13783_ ## prefix ## _ ## _name] = {				\
 		.desc = {						\
 			.name = #prefix "_" #_name,			\
+			.n_voltages = ARRAY_SIZE(_voltages),		\
 			.ops = &mc13783_regulator_ops,			\
 			.type = REGULATOR_VOLTAGE,			\
 			.id = MC13783_ ## prefix ## _ ## _name,		\
@@ -68,40 +191,92 @@ static struct regulator_ops mc13783_regu
 		},							\
 		.reg = MC13783_REG_ ## _reg,				\
 		.enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN,	\
+		.vsel_reg = MC13783_REG_ ## _vsel_reg,			\
+		.vsel_shift = MC13783_REG_ ## _vsel_reg ## _ ## _name ## VSEL,\
+		.vsel_mask = MC13783_REG_ ## _vsel_reg ## _ ## _name ## VSEL_M,\
+		.voltages =  _voltages,					\
 	}
 
-#define MC13783_DEFINE_SW(_name, _reg) MC13783_DEFINE(SW, _name, _reg)
-#define MC13783_DEFINE_REGU(_name, _reg) MC13783_DEFINE(REGU, _name, _reg)
+#define MC13783_FIXED_DEFINE(prefix, _name, _reg, _voltages)		\
+	[MC13783_ ## prefix ## _ ## _name] = {				\
+		.desc = {						\
+			.name = #prefix "_" #_name,			\
+			.n_voltages = ARRAY_SIZE(_voltages),		\
+			.ops = &mc13783_fixed_regulator_ops,		\
+			.type = REGULATOR_VOLTAGE,			\
+			.id = MC13783_ ## prefix ## _ ## _name,		\
+			.owner = THIS_MODULE,				\
+		},							\
+		.reg = MC13783_REG_ ## _reg,				\
+		.enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN,	\
+		.voltages =  _voltages,					\
+	}
+
+#define MC13783_GPO_DEFINE(prefix, _name, _reg,  _voltages)		\
+	[MC13783_ ## prefix ## _ ## _name] = {				\
+		.desc = {						\
+			.name = #prefix "_" #_name,			\
+			.n_voltages = ARRAY_SIZE(_voltages),		\
+			.ops = &mc13783_gpo_regulator_ops,		\
+			.type = REGULATOR_VOLTAGE,			\
+			.id = MC13783_ ## prefix ## _ ## _name,		\
+			.owner = THIS_MODULE,				\
+		},							\
+		.reg = MC13783_REG_ ## _reg,				\
+		.enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN,	\
+		.voltages =  _voltages,					\
+	}
+
+#define MC13783_DEFINE_SW(_name, _reg, _vsel_reg, _voltages)		\
+	MC13783_DEFINE(SW, _name, _reg, _vsel_reg, _voltages)
+#define MC13783_DEFINE_REGU(_name, _reg, _vsel_reg, _voltages)		\
+	MC13783_DEFINE(REGU, _name, _reg, _vsel_reg, _voltages)
 
 static struct mc13783_regulator mc13783_regulators[] = {
-	MC13783_DEFINE_SW(SW3, SWITCHERS5),
-	MC13783_DEFINE_SW(PLL, SWITCHERS4),
+	MC13783_DEFINE_SW(SW3, SWITCHERS5, SWITCHERS5, mc13783_sw3_val),
 
-	MC13783_DEFINE_REGU(VAUDIO, REGULATORMODE0),
-	MC13783_DEFINE_REGU(VIOHI, REGULATORMODE0),
-	MC13783_DEFINE_REGU(VIOLO, REGULATORMODE0),
-	MC13783_DEFINE_REGU(VDIG, REGULATORMODE0),
-	MC13783_DEFINE_REGU(VGEN, REGULATORMODE0),
-	MC13783_DEFINE_REGU(VRFDIG, REGULATORMODE0),
-	MC13783_DEFINE_REGU(VRFREF, REGULATORMODE0),
-	MC13783_DEFINE_REGU(VRFCP, REGULATORMODE0),
-	MC13783_DEFINE_REGU(VSIM, REGULATORMODE1),
-	MC13783_DEFINE_REGU(VESIM, REGULATORMODE1),
-	MC13783_DEFINE_REGU(VCAM, REGULATORMODE1),
-	MC13783_DEFINE_REGU(VRFBG, REGULATORMODE1),
-	MC13783_DEFINE_REGU(VVIB, REGULATORMODE1),
-	MC13783_DEFINE_REGU(VRF1, REGULATORMODE1),
-	MC13783_DEFINE_REGU(VRF2, REGULATORMODE1),
-	MC13783_DEFINE_REGU(VMMC1, REGULATORMODE1),
-	MC13783_DEFINE_REGU(VMMC2, REGULATORMODE1),
-	MC13783_DEFINE_REGU(GPO1, POWERMISC),
-	MC13783_DEFINE_REGU(GPO2, POWERMISC),
-	MC13783_DEFINE_REGU(GPO3, POWERMISC),
-	MC13783_DEFINE_REGU(GPO4, POWERMISC),
+	MC13783_FIXED_DEFINE(REGU, VAUDIO, REGULATORMODE0, mc13783_vaudio_val),
+	MC13783_FIXED_DEFINE(REGU, VIOHI, REGULATORMODE0, mc13783_viohi_val),
+	MC13783_DEFINE_REGU(VIOLO, REGULATORMODE0, REGULATORSETTING0,	\
+			    mc13783_violo_val),
+	MC13783_DEFINE_REGU(VDIG, REGULATORMODE0, REGULATORSETTING0,	\
+			    mc13783_vdig_val),
+	MC13783_DEFINE_REGU(VGEN, REGULATORMODE0, REGULATORSETTING0,	\
+			    mc13783_vgen_val),
+	MC13783_DEFINE_REGU(VRFDIG, REGULATORMODE0, REGULATORSETTING0,	\
+			    mc13783_vrfdig_val),
+	MC13783_DEFINE_REGU(VRFREF, REGULATORMODE0, REGULATORSETTING0,	\
+			    mc13783_vrfref_val),
+	MC13783_DEFINE_REGU(VRFCP, REGULATORMODE0, REGULATORSETTING0,	\
+			    mc13783_vrfcp_val),
+	MC13783_DEFINE_REGU(VSIM, REGULATORMODE1, REGULATORSETTING0,	\
+			    mc13783_vsim_val),
+	MC13783_DEFINE_REGU(VESIM, REGULATORMODE1, REGULATORSETTING0,	\
+			    mc13783_vesim_val),
+	MC13783_DEFINE_REGU(VCAM, REGULATORMODE1, REGULATORSETTING0,	\
+			    mc13783_vcam_val),
+	MC13783_FIXED_DEFINE(REGU, VRFBG, REGULATORMODE1, mc13783_vrfbg_val),
+	MC13783_DEFINE_REGU(VVIB, REGULATORMODE1, REGULATORSETTING1,	\
+			    mc13783_vvib_val),
+	MC13783_DEFINE_REGU(VRF1, REGULATORMODE1, REGULATORSETTING1,	\
+			    mc13783_vrf_val),
+	MC13783_DEFINE_REGU(VRF2, REGULATORMODE1, REGULATORSETTING1,	\
+			    mc13783_vrf_val),
+	MC13783_DEFINE_REGU(VMMC1, REGULATORMODE1, REGULATORSETTING1,	\
+			    mc13783_vmmc_val),
+	MC13783_DEFINE_REGU(VMMC2, REGULATORMODE1, REGULATORSETTING1,	\
+			    mc13783_vmmc_val),
+	MC13783_GPO_DEFINE(REGU, GPO1, POWERMISC, mc13783_gpo_val),
+	MC13783_GPO_DEFINE(REGU, GPO2, POWERMISC, mc13783_gpo_val),
+	MC13783_GPO_DEFINE(REGU, GPO3, POWERMISC, mc13783_gpo_val),
+	MC13783_GPO_DEFINE(REGU, GPO4, POWERMISC, mc13783_gpo_val),
+	MC13783_GPO_DEFINE(REGU, PWGT1SPI, POWERMISC, mc13783_pwgtdrv_val),
+	MC13783_GPO_DEFINE(REGU, PWGT2SPI, POWERMISC, mc13783_pwgtdrv_val),
 };
 
 struct mc13783_regulator_priv {
 	struct mc13783 *mc13783;
+	u32 powermisc_pwgt_state;
 	struct regulator_dev *regulators[];
 };
 
@@ -154,10 +329,241 @@ static int mc13783_regulator_is_enabled(
 	return (val & mc13783_regulators[id].enable_bit) != 0;
 }
 
+static int mc13783_regulator_list_voltage(struct regulator_dev *rdev,
+						unsigned selector)
+{
+	int id = rdev_get_id(rdev);
+
+	if (selector >= mc13783_regulators[id].desc.n_voltages)
+		return -EINVAL;
+
+	return mc13783_regulators[id].voltages[selector];
+}
+
+static int mc13783_get_best_voltage_index(struct regulator_dev *rdev,
+						int min_uV, int max_uV)
+{
+	int reg_id = rdev_get_id(rdev);
+	int i;
+	int bestmatch;
+	int bestindex;
+
+	/*
+	 * Locate the minimum voltage fitting the criteria on
+	 * this regulator. The switchable voltages are not
+	 * in strict falling order so we need to check them
+	 * all for the best match.
+	 */
+	bestmatch = INT_MAX;
+	bestindex = -1;
+	for (i = 0; i < mc13783_regulators[reg_id].desc.n_voltages; i++) {
+		if (mc13783_regulators[reg_id].voltages[i] >= min_uV &&
+		    mc13783_regulators[reg_id].voltages[i] < bestmatch) {
+			bestmatch = mc13783_regulators[reg_id].voltages[i];
+			bestindex = i;
+		}
+	}
+
+	if (bestindex < 0 || bestmatch > max_uV) {
+		dev_warn(&rdev->dev, "no possible value for %d<=x<=%d uV\n",
+				min_uV, max_uV);
+		return -EINVAL;
+	}
+	return bestindex;
+}
+
+static int mc13783_regulator_set_voltage(struct regulator_dev *rdev,
+						int min_uV, int max_uV)
+{
+	struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
+	int value, id = rdev_get_id(rdev);
+	int ret;
+
+	dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
+		__func__, id, min_uV, max_uV);
+
+	/* Find the best index */
+	value = mc13783_get_best_voltage_index(rdev, min_uV, max_uV);
+	dev_dbg(rdev_get_dev(rdev), "%s best value: %d \n", __func__, value);
+	if (value < 0)
+		return value;
+
+	mc13783_lock(priv->mc13783);
+	ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].vsel_reg,
+			mc13783_regulators[id].vsel_mask,
+			value << mc13783_regulators[id].vsel_shift);
+	mc13783_unlock(priv->mc13783);
+
+	return ret;
+}
+
+static int mc13783_regulator_get_voltage(struct regulator_dev *rdev)
+{
+	struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
+	int ret, id = rdev_get_id(rdev);
+	unsigned int val;
+
+	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+
+	mc13783_lock(priv->mc13783);
+	ret = mc13783_reg_read(priv->mc13783,
+				mc13783_regulators[id].vsel_reg, &val);
+	mc13783_unlock(priv->mc13783);
+
+	if (ret)
+		return ret;
+
+	val = (val & mc13783_regulators[id].vsel_mask)
+		>> mc13783_regulators[id].vsel_shift;
+
+	dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val);
+
+	BUG_ON(val < 0 || val > mc13783_regulators[id].desc.n_voltages);
+
+	return mc13783_regulators[id].voltages[val];
+}
+
 static struct regulator_ops mc13783_regulator_ops = {
 	.enable = mc13783_regulator_enable,
 	.disable = mc13783_regulator_disable,
 	.is_enabled = mc13783_regulator_is_enabled,
+	.list_voltage = mc13783_regulator_list_voltage,
+	.set_voltage = mc13783_regulator_set_voltage,
+	.get_voltage = mc13783_regulator_get_voltage,
+};
+
+static int mc13783_fixed_regulator_set_voltage(struct regulator_dev *rdev,
+						int min_uV, int max_uV)
+{
+	int id = rdev_get_id(rdev);
+
+	dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
+		__func__, id, min_uV, max_uV);
+
+	if (min_uV > mc13783_regulators[id].voltages[0] &&
+	    max_uV < mc13783_regulators[id].voltages[0])
+		return 0;
+	else
+		return -EINVAL;
+}
+
+static int mc13783_fixed_regulator_get_voltage(struct regulator_dev *rdev)
+{
+	int id = rdev_get_id(rdev);
+
+	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+
+	return mc13783_regulators[id].voltages[0];
+}
+
+static struct regulator_ops mc13783_fixed_regulator_ops = {
+	.enable = mc13783_regulator_enable,
+	.disable = mc13783_regulator_disable,
+	.is_enabled = mc13783_regulator_is_enabled,
+	.list_voltage = mc13783_regulator_list_voltage,
+	.set_voltage = mc13783_fixed_regulator_set_voltage,
+	.get_voltage = mc13783_fixed_regulator_get_voltage,
+};
+
+int mc13783_powermisc_rmw(struct mc13783_regulator_priv *priv, u32 mask,
+									u32 val)
+{
+	struct mc13783 *mc13783 = priv->mc13783;
+	int ret;
+	u32 valread;
+
+	BUG_ON(val & ~mask);
+
+	ret = mc13783_reg_read(mc13783, MC13783_REG_POWERMISC, &valread);
+	if (ret)
+		return ret;
+
+	/* Update the stored state for Power Gates. */
+	priv->powermisc_pwgt_state =
+				(priv->powermisc_pwgt_state & ~mask) | val;
+	priv->powermisc_pwgt_state &= MC13783_REG_POWERMISC_PWGTSPI_M;
+
+	/* Construct the new register value */
+	valread = (valread & ~mask) | val;
+	/* Overwrite the PWGTxEN with the stored version */
+	valread = (valread & ~MC13783_REG_POWERMISC_PWGTSPI_M) |
+						priv->powermisc_pwgt_state;
+
+	return mc13783_reg_write(mc13783, MC13783_REG_POWERMISC, valread);
+}
+
+static int mc13783_gpo_regulator_enable(struct regulator_dev *rdev)
+{
+	struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
+	int id = rdev_get_id(rdev);
+	int ret;
+	u32 en_val = mc13783_regulators[id].enable_bit;
+
+	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+
+	/* Power Gate enable value is 0 */
+	if (id == MC13783_REGU_PWGT1SPI ||
+	    id == MC13783_REGU_PWGT2SPI)
+		en_val = 0;
+
+	mc13783_lock(priv->mc13783);
+	ret = mc13783_powermisc_rmw(priv, mc13783_regulators[id].enable_bit,
+					en_val);
+	mc13783_unlock(priv->mc13783);
+
+	return ret;
+}
+
+static int mc13783_gpo_regulator_disable(struct regulator_dev *rdev)
+{
+	struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
+	int id = rdev_get_id(rdev);
+	int ret;
+	u32 dis_val = 0;
+
+	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+
+	/* Power Gate disable value is 1 */
+	if (id == MC13783_REGU_PWGT1SPI ||
+	    id == MC13783_REGU_PWGT2SPI)
+		dis_val = mc13783_regulators[id].enable_bit;
+
+	mc13783_lock(priv->mc13783);
+	ret = mc13783_powermisc_rmw(priv, mc13783_regulators[id].enable_bit,
+					dis_val);
+	mc13783_unlock(priv->mc13783);
+
+	return ret;
+}
+
+static int mc13783_gpo_regulator_is_enabled(struct regulator_dev *rdev)
+{
+	struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
+	int ret, id = rdev_get_id(rdev);
+	unsigned int val;
+
+	mc13783_lock(priv->mc13783);
+	ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val);
+	mc13783_unlock(priv->mc13783);
+
+	if (ret)
+		return ret;
+
+	/* Power Gates state is stored in powermisc_pwgt_state
+	 * where the meaning of bits is negated */
+	val = (val & ~MC13783_REG_POWERMISC_PWGTSPI_M) |
+	      (priv->powermisc_pwgt_state ^ MC13783_REG_POWERMISC_PWGTSPI_M);
+
+	return (val & mc13783_regulators[id].enable_bit) != 0;
+}
+
+static struct regulator_ops mc13783_gpo_regulator_ops = {
+	.enable = mc13783_gpo_regulator_enable,
+	.disable = mc13783_gpo_regulator_disable,
+	.is_enabled = mc13783_gpo_regulator_is_enabled,
+	.list_voltage = mc13783_regulator_list_voltage,
+	.set_voltage = mc13783_fixed_regulator_set_voltage,
+	.get_voltage = mc13783_fixed_regulator_get_voltage,
 };
 
 static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
@@ -212,9 +618,12 @@ static int __devexit mc13783_regulator_r
 		dev_get_platdata(&pdev->dev);
 	int i;
 
+	platform_set_drvdata(pdev, NULL);
+
 	for (i = 0; i < pdata->num_regulators; i++)
 		regulator_unregister(priv->regulators[i]);
 
+	kfree(priv);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/pcap-regulator.c linux-libre-2.6.34-gnu1/drivers/regulator/pcap-regulator.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/pcap-regulator.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/pcap-regulator.c	2010-05-16 17:17:36.000000000 -0400
@@ -288,16 +288,18 @@ static int __devexit pcap_regulator_remo
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
 	regulator_unregister(rdev);
+	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
 
 static struct platform_driver pcap_regulator_driver = {
 	.driver = {
-		.name = "pcap-regulator",
+		.name	= "pcap-regulator",
+		.owner	= THIS_MODULE,
 	},
-	.probe = pcap_regulator_probe,
-	.remove = __devexit_p(pcap_regulator_remove),
+	.probe	= pcap_regulator_probe,
+	.remove	= __devexit_p(pcap_regulator_remove),
 };
 
 static int __init pcap_regulator_init(void)
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/tps65023-regulator.c linux-libre-2.6.34-gnu1/drivers/regulator/tps65023-regulator.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/tps65023-regulator.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/tps65023-regulator.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 /* Register definitions */
 #define	TPS65023_REG_VERSION		0
@@ -457,8 +458,8 @@ static struct regulator_ops tps65023_ldo
 	.list_voltage = tps65023_ldo_list_voltage,
 };
 
-static
-int tps_65023_probe(struct i2c_client *client, const struct i2c_device_id *id)
+static int __devinit tps_65023_probe(struct i2c_client *client,
+				     const struct i2c_device_id *id)
 {
 	static int desc_id;
 	const struct tps_info *info = (void *)id->driver_data;
@@ -466,6 +467,7 @@ int tps_65023_probe(struct i2c_client *c
 	struct regulator_dev *rdev;
 	struct tps_pmic *tps;
 	int i;
+	int error;
 
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -EIO;
@@ -475,7 +477,6 @@ int tps_65023_probe(struct i2c_client *c
 	 * coming from the board-evm file.
 	 */
 	init_data = client->dev.platform_data;
-
 	if (!init_data)
 		return -EIO;
 
@@ -502,21 +503,12 @@ int tps_65023_probe(struct i2c_client *c
 
 		/* Register the regulators */
 		rdev = regulator_register(&tps->desc[i], &client->dev,
-								init_data, tps);
+					  init_data, tps);
 		if (IS_ERR(rdev)) {
 			dev_err(&client->dev, "failed to register %s\n",
 				id->name);
-
-			/* Unregister */
-			while (i)
-				regulator_unregister(tps->rdev[--i]);
-
-			tps->client = NULL;
-
-			/* clear the client data in i2c */
-			i2c_set_clientdata(client, NULL);
-			kfree(tps);
-			return PTR_ERR(rdev);
+			error = PTR_ERR(rdev);
+			goto fail;
 		}
 
 		/* Save regulator for cleanup */
@@ -526,6 +518,13 @@ int tps_65023_probe(struct i2c_client *c
 	i2c_set_clientdata(client, tps);
 
 	return 0;
+
+ fail:
+	while (--i >= 0)
+		regulator_unregister(tps->rdev[i]);
+
+	kfree(tps);
+	return error;
 }
 
 /**
@@ -539,13 +538,12 @@ static int __devexit tps_65023_remove(st
 	struct tps_pmic *tps = i2c_get_clientdata(client);
 	int i;
 
+	/* clear the client data in i2c */
+	i2c_set_clientdata(client, NULL);
+
 	for (i = 0; i < TPS65023_NUM_REGULATOR; i++)
 		regulator_unregister(tps->rdev[i]);
 
-	tps->client = NULL;
-
-	/* clear the client data in i2c */
-	i2c_set_clientdata(client, NULL);
 	kfree(tps);
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/tps6507x-regulator.c linux-libre-2.6.34-gnu1/drivers/regulator/tps6507x-regulator.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/tps6507x-regulator.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/tps6507x-regulator.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 /* Register definitions */
 #define	TPS6507X_REG_PPATH1				0X01
@@ -538,8 +539,8 @@ static struct regulator_ops tps6507x_ldo
 	.list_voltage = tps6507x_ldo_list_voltage,
 };
 
-static
-int tps_6507x_probe(struct i2c_client *client, const struct i2c_device_id *id)
+static int __devinit tps_6507x_probe(struct i2c_client *client,
+				     const struct i2c_device_id *id)
 {
 	static int desc_id;
 	const struct tps_info *info = (void *)id->driver_data;
@@ -547,6 +548,7 @@ int tps_6507x_probe(struct i2c_client *c
 	struct regulator_dev *rdev;
 	struct tps_pmic *tps;
 	int i;
+	int error;
 
 	if (!i2c_check_functionality(client->adapter,
 				I2C_FUNC_SMBUS_BYTE_DATA))
@@ -557,7 +559,6 @@ int tps_6507x_probe(struct i2c_client *c
 	 * coming from the board-evm file.
 	 */
 	init_data = client->dev.platform_data;
-
 	if (!init_data)
 		return -EIO;
 
@@ -586,18 +587,8 @@ int tps_6507x_probe(struct i2c_client *c
 		if (IS_ERR(rdev)) {
 			dev_err(&client->dev, "failed to register %s\n",
 				id->name);
-
-			/* Unregister */
-			while (i)
-				regulator_unregister(tps->rdev[--i]);
-
-			tps->client = NULL;
-
-			/* clear the client data in i2c */
-			i2c_set_clientdata(client, NULL);
-
-			kfree(tps);
-			return PTR_ERR(rdev);
+			error = PTR_ERR(rdev);
+			goto fail;
 		}
 
 		/* Save regulator for cleanup */
@@ -607,6 +598,13 @@ int tps_6507x_probe(struct i2c_client *c
 	i2c_set_clientdata(client, tps);
 
 	return 0;
+
+fail:
+	while (--i >= 0)
+		regulator_unregister(tps->rdev[i]);
+
+	kfree(tps);
+	return error;
 }
 
 /**
@@ -620,13 +618,12 @@ static int __devexit tps_6507x_remove(st
 	struct tps_pmic *tps = i2c_get_clientdata(client);
 	int i;
 
+	/* clear the client data in i2c */
+	i2c_set_clientdata(client, NULL);
+
 	for (i = 0; i < TPS6507X_NUM_REGULATOR; i++)
 		regulator_unregister(tps->rdev[i]);
 
-	tps->client = NULL;
-
-	/* clear the client data in i2c */
-	i2c_set_clientdata(client, NULL);
 	kfree(tps);
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/twl-regulator.c linux-libre-2.6.34-gnu1/drivers/regulator/twl-regulator.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/twl-regulator.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/twl-regulator.c	2010-05-16 17:17:36.000000000 -0400
@@ -519,19 +519,19 @@ static struct twlreg_info twl_regs[] = {
 	/* 6030 REG with base as PMC Slave Misc : 0x0030 */
 	/* Turnon-delay and remap configuration values for 6030 are not
 	   verified since the specification is not public */
-	TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1, 0, 0x08),
-	TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 2, 0, 0x08),
-	TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 3, 0, 0x08),
-	TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 4, 0, 0x08),
-	TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 5, 0, 0x08),
-	TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 7, 0, 0x08),
-	TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x08),
-	TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x08),
-	TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x08),
-	TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0, 0x08)
+	TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1, 0, 0x21),
+	TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 2, 0, 0x21),
+	TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 3, 0, 0x21),
+	TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 4, 0, 0x21),
+	TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 5, 0, 0x21),
+	TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 7, 0, 0x21),
+	TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x21),
+	TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x21),
+	TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x21),
+	TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0, 0x21)
 };
 
-static int twlreg_probe(struct platform_device *pdev)
+static int __devinit twlreg_probe(struct platform_device *pdev)
 {
 	int				i;
 	struct twlreg_info		*info;
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/userspace-consumer.c linux-libre-2.6.34-gnu1/drivers/regulator/userspace-consumer.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/userspace-consumer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/userspace-consumer.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/userspace-consumer.h>
+#include <linux/slab.h>
 
 struct userspace_consumer_data {
 	const char *name;
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/virtual.c linux-libre-2.6.34-gnu1/drivers/regulator/virtual.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/virtual.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/virtual.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,11 +15,12 @@
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 
 struct virtual_consumer_data {
 	struct mutex lock;
 	struct regulator *regulator;
-	int enabled;
+	bool enabled;
 	int min_uV;
 	int max_uV;
 	int min_uA;
@@ -49,7 +50,7 @@ static void update_voltage_constraints(s
 		dev_dbg(dev, "Enabling regulator\n");
 		ret = regulator_enable(data->regulator);
 		if (ret == 0)
-			data->enabled = 1;
+			data->enabled = true;
 		else
 			dev_err(dev, "regulator_enable() failed: %d\n",
 				ret);
@@ -59,7 +60,7 @@ static void update_voltage_constraints(s
 		dev_dbg(dev, "Disabling regulator\n");
 		ret = regulator_disable(data->regulator);
 		if (ret == 0)
-			data->enabled = 0;
+			data->enabled = false;
 		else
 			dev_err(dev, "regulator_disable() failed: %d\n",
 				ret);
@@ -89,7 +90,7 @@ static void update_current_limit_constra
 		dev_dbg(dev, "Enabling regulator\n");
 		ret = regulator_enable(data->regulator);
 		if (ret == 0)
-			data->enabled = 1;
+			data->enabled = true;
 		else
 			dev_err(dev, "regulator_enable() failed: %d\n",
 				ret);
@@ -99,7 +100,7 @@ static void update_current_limit_constra
 		dev_dbg(dev, "Disabling regulator\n");
 		ret = regulator_disable(data->regulator);
 		if (ret == 0)
-			data->enabled = 0;
+			data->enabled = false;
 		else
 			dev_err(dev, "regulator_disable() failed: %d\n",
 				ret);
@@ -270,24 +271,28 @@ 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);
 
-static struct device_attribute *attributes[] = {
-	&dev_attr_min_microvolts,
-	&dev_attr_max_microvolts,
-	&dev_attr_min_microamps,
-	&dev_attr_max_microamps,
-	&dev_attr_mode,
+static struct attribute *regulator_virtual_attributes[] = {
+	&dev_attr_min_microvolts.attr,
+	&dev_attr_max_microvolts.attr,
+	&dev_attr_min_microamps.attr,
+	&dev_attr_max_microamps.attr,
+	&dev_attr_mode.attr,
+	NULL
 };
 
-static int regulator_virtual_consumer_probe(struct platform_device *pdev)
+static const struct attribute_group regulator_virtual_attr_group = {
+	.attrs	= regulator_virtual_attributes,
+};
+
+static int __devinit regulator_virtual_probe(struct platform_device *pdev)
 {
 	char *reg_id = pdev->dev.platform_data;
 	struct virtual_consumer_data *drvdata;
-	int ret, i;
+	int ret;
 
 	drvdata = kzalloc(sizeof(struct virtual_consumer_data), GFP_KERNEL);
-	if (drvdata == NULL) {
+	if (drvdata == NULL)
 		return -ENOMEM;
-	}
 
 	mutex_init(&drvdata->lock);
 
@@ -299,13 +304,12 @@ static int regulator_virtual_consumer_pr
 		goto err;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(attributes); i++) {
-		ret = device_create_file(&pdev->dev, attributes[i]);
-		if (ret != 0) {
-			dev_err(&pdev->dev, "Failed to create attr %d: %d\n",
-				i, ret);
-			goto err_regulator;
-		}
+	ret = sysfs_create_group(&pdev->dev.kobj,
+				 &regulator_virtual_attr_group);
+	if (ret != 0) {
+		dev_err(&pdev->dev,
+			"Failed to create attribute group: %d\n", ret);
+		goto err_regulator;
 	}
 
 	drvdata->mode = regulator_get_mode(drvdata->regulator);
@@ -317,37 +321,36 @@ static int regulator_virtual_consumer_pr
 err_regulator:
 	regulator_put(drvdata->regulator);
 err:
-	for (i = 0; i < ARRAY_SIZE(attributes); i++)
-		device_remove_file(&pdev->dev, attributes[i]);
 	kfree(drvdata);
 	return ret;
 }
 
-static int regulator_virtual_consumer_remove(struct platform_device *pdev)
+static int __devexit regulator_virtual_remove(struct platform_device *pdev)
 {
 	struct virtual_consumer_data *drvdata = platform_get_drvdata(pdev);
-	int i;
 
-	for (i = 0; i < ARRAY_SIZE(attributes); i++)
-		device_remove_file(&pdev->dev, attributes[i]);
+	sysfs_remove_group(&pdev->dev.kobj, &regulator_virtual_attr_group);
+
 	if (drvdata->enabled)
 		regulator_disable(drvdata->regulator);
 	regulator_put(drvdata->regulator);
 
 	kfree(drvdata);
 
+	platform_set_drvdata(pdev, NULL);
+
 	return 0;
 }
 
 static struct platform_driver regulator_virtual_consumer_driver = {
-	.probe		= regulator_virtual_consumer_probe,
-	.remove		= regulator_virtual_consumer_remove,
+	.probe		= regulator_virtual_probe,
+	.remove		= __devexit_p(regulator_virtual_remove),
 	.driver		= {
 		.name		= "reg-virt-consumer",
+		.owner		= THIS_MODULE,
 	},
 };
 
-
 static int __init regulator_virtual_consumer_init(void)
 {
 	return platform_driver_register(&regulator_virtual_consumer_driver);
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/wm831x-dcdc.c linux-libre-2.6.34-gnu1/drivers/regulator/wm831x-dcdc.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/wm831x-dcdc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/wm831x-dcdc.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/regulator.h>
@@ -600,6 +601,8 @@ static __devexit int wm831x_buckv_remove
 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
 	struct wm831x *wm831x = dcdc->wm831x;
 
+	platform_set_drvdata(pdev, NULL);
+
 	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "HC"), dcdc);
 	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
 	regulator_unregister(dcdc->regulator);
@@ -615,6 +618,7 @@ static struct platform_driver wm831x_buc
 	.remove = __devexit_p(wm831x_buckv_remove),
 	.driver		= {
 		.name	= "wm831x-buckv",
+		.owner	= THIS_MODULE,
 	},
 };
 
@@ -769,6 +773,8 @@ static __devexit int wm831x_buckp_remove
 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
 	struct wm831x *wm831x = dcdc->wm831x;
 
+	platform_set_drvdata(pdev, NULL);
+
 	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
 	regulator_unregister(dcdc->regulator);
 	kfree(dcdc);
@@ -781,6 +787,7 @@ static struct platform_driver wm831x_buc
 	.remove = __devexit_p(wm831x_buckp_remove),
 	.driver		= {
 		.name	= "wm831x-buckp",
+		.owner	= THIS_MODULE,
 	},
 };
 
@@ -895,6 +902,8 @@ static __devexit int wm831x_boostp_remov
 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
 	struct wm831x *wm831x = dcdc->wm831x;
 
+	platform_set_drvdata(pdev, NULL);
+
 	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
 	regulator_unregister(dcdc->regulator);
 	kfree(dcdc);
@@ -907,6 +916,7 @@ static struct platform_driver wm831x_boo
 	.remove = __devexit_p(wm831x_boostp_remove),
 	.driver		= {
 		.name	= "wm831x-boostp",
+		.owner	= THIS_MODULE,
 	},
 };
 
@@ -979,6 +989,8 @@ static __devexit int wm831x_epe_remove(s
 {
 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
 
+	platform_set_drvdata(pdev, NULL);
+
 	regulator_unregister(dcdc->regulator);
 	kfree(dcdc);
 
@@ -990,6 +1002,7 @@ static struct platform_driver wm831x_epe
 	.remove = __devexit_p(wm831x_epe_remove),
 	.driver		= {
 		.name	= "wm831x-epe",
+		.owner	= THIS_MODULE,
 	},
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/wm831x-isink.c linux-libre-2.6.34-gnu1/drivers/regulator/wm831x-isink.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/wm831x-isink.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/wm831x-isink.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/regulator.h>
@@ -222,6 +223,8 @@ static __devexit int wm831x_isink_remove
 	struct wm831x_isink *isink = platform_get_drvdata(pdev);
 	struct wm831x *wm831x = isink->wm831x;
 
+	platform_set_drvdata(pdev, NULL);
+
 	wm831x_free_irq(wm831x, platform_get_irq(pdev, 0), isink);
 
 	regulator_unregister(isink->regulator);
@@ -235,6 +238,7 @@ static struct platform_driver wm831x_isi
 	.remove = __devexit_p(wm831x_isink_remove),
 	.driver		= {
 		.name	= "wm831x-isink",
+		.owner	= THIS_MODULE,
 	},
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/wm831x-ldo.c linux-libre-2.6.34-gnu1/drivers/regulator/wm831x-ldo.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/wm831x-ldo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/wm831x-ldo.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/regulator.h>
@@ -371,6 +372,8 @@ static __devexit int wm831x_gp_ldo_remov
 	struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
 	struct wm831x *wm831x = ldo->wm831x;
 
+	platform_set_drvdata(pdev, NULL);
+
 	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), ldo);
 	regulator_unregister(ldo->regulator);
 	kfree(ldo);
@@ -383,6 +386,7 @@ static struct platform_driver wm831x_gp_
 	.remove = __devexit_p(wm831x_gp_ldo_remove),
 	.driver		= {
 		.name	= "wm831x-ldo",
+		.owner	= THIS_MODULE,
 	},
 };
 
@@ -640,6 +644,7 @@ static struct platform_driver wm831x_ald
 	.remove = __devexit_p(wm831x_aldo_remove),
 	.driver		= {
 		.name	= "wm831x-aldo",
+		.owner	= THIS_MODULE,
 	},
 };
 
@@ -811,6 +816,7 @@ static struct platform_driver wm831x_ali
 	.remove = __devexit_p(wm831x_alive_ldo_remove),
 	.driver		= {
 		.name	= "wm831x-alive-ldo",
+		.owner	= THIS_MODULE,
 	},
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/wm8350-regulator.c linux-libre-2.6.34-gnu1/drivers/regulator/wm8350-regulator.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/wm8350-regulator.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/wm8350-regulator.c	2010-05-16 17:17:36.000000000 -0400
@@ -290,6 +290,51 @@ static int wm8350_isink_is_enabled(struc
 	return -EINVAL;
 }
 
+static int wm8350_isink_enable_time(struct regulator_dev *rdev)
+{
+	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
+	int isink = rdev_get_id(rdev);
+	int reg;
+
+	switch (isink) {
+	case WM8350_ISINK_A:
+		reg = wm8350_reg_read(wm8350, WM8350_CSA_FLASH_CONTROL);
+		break;
+	case WM8350_ISINK_B:
+		reg = wm8350_reg_read(wm8350, WM8350_CSB_FLASH_CONTROL);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (reg & WM8350_CS1_FLASH_MODE) {
+		switch (reg & WM8350_CS1_ON_RAMP_MASK) {
+		case 0:
+			return 0;
+		case 1:
+			return 1950;
+		case 2:
+			return 3910;
+		case 3:
+			return 7800;
+		}
+	} else {
+		switch (reg & WM8350_CS1_ON_RAMP_MASK) {
+		case 0:
+			return 0;
+		case 1:
+			return 250000;
+		case 2:
+			return 500000;
+		case 3:
+			return 1000000;
+		}
+	}
+
+	return -EINVAL;
+}
+
+
 int wm8350_isink_set_flash(struct wm8350 *wm8350, int isink, u16 mode,
 			   u16 trigger, u16 duration, u16 on_ramp, u16 off_ramp,
 			   u16 drive)
@@ -1221,6 +1266,7 @@ static struct regulator_ops wm8350_isink
 	.enable = wm8350_isink_enable,
 	.disable = wm8350_isink_disable,
 	.is_enabled = wm8350_isink_is_enabled,
+	.enable_time = wm8350_isink_enable_time,
 };
 
 static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
@@ -1407,7 +1453,7 @@ static int wm8350_regulator_remove(struc
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
 
-	wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq);
+	wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq, rdev);
 
 	regulator_unregister(rdev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/wm8400-regulator.c linux-libre-2.6.34-gnu1/drivers/regulator/wm8400-regulator.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/wm8400-regulator.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/wm8400-regulator.c	2010-05-16 17:17:36.000000000 -0400
@@ -317,14 +317,17 @@ static struct regulator_desc regulators[
 
 static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
 {
+	struct wm8400 *wm8400 = container_of(pdev, struct wm8400, regulators[pdev->id]);
 	struct regulator_dev *rdev;
 
 	rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
-		pdev->dev.platform_data, dev_get_drvdata(&pdev->dev));
+				  pdev->dev.platform_data, wm8400);
 
 	if (IS_ERR(rdev))
 		return PTR_ERR(rdev);
 
+	platform_set_drvdata(pdev, rdev);
+
 	return 0;
 }
 
@@ -332,6 +335,7 @@ static int __devexit wm8400_regulator_re
 {
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
+	platform_set_drvdata(pdev, NULL);
 	regulator_unregister(rdev);
 
 	return 0;
@@ -370,7 +374,6 @@ int wm8400_register_regulator(struct dev
 	wm8400->regulators[reg].id = reg;
 	wm8400->regulators[reg].dev.parent = dev;
 	wm8400->regulators[reg].dev.platform_data = initdata;
-	dev_set_drvdata(&wm8400->regulators[reg].dev, wm8400);
 
 	return platform_device_register(&wm8400->regulators[reg]);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/regulator/wm8994-regulator.c linux-libre-2.6.34-gnu1/drivers/regulator/wm8994-regulator.c
--- linux-libre-2.6.33-gnu1/drivers/regulator/wm8994-regulator.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/regulator/wm8994-regulator.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,308 @@
+/*
+ * wm8994-regulator.c  --  Regulator driver for the WM8994
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License 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/moduleparam.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+
+#include <linux/mfd/wm8994/core.h>
+#include <linux/mfd/wm8994/registers.h>
+#include <linux/mfd/wm8994/pdata.h>
+
+struct wm8994_ldo {
+	int enable;
+	bool is_enabled;
+	struct regulator_dev *regulator;
+	struct wm8994 *wm8994;
+};
+
+#define WM8994_LDO1_MAX_SELECTOR 0x7
+#define WM8994_LDO2_MAX_SELECTOR 0x3
+
+static int wm8994_ldo_enable(struct regulator_dev *rdev)
+{
+	struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
+
+	/* If we have no soft control assume that the LDO is always enabled. */
+	if (!ldo->enable)
+		return 0;
+
+	gpio_set_value(ldo->enable, 1);
+	ldo->is_enabled = true;
+
+	return 0;
+}
+
+static int wm8994_ldo_disable(struct regulator_dev *rdev)
+{
+	struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
+
+	/* If we have no soft control assume that the LDO is always enabled. */
+	if (!ldo->enable)
+		return -EINVAL;
+
+	gpio_set_value(ldo->enable, 0);
+	ldo->is_enabled = false;
+
+	return 0;
+}
+
+static int wm8994_ldo_is_enabled(struct regulator_dev *rdev)
+{
+	struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
+
+	return ldo->is_enabled;
+}
+
+static int wm8994_ldo_enable_time(struct regulator_dev *rdev)
+{
+	/* 3ms is fairly conservative but this shouldn't be too performance
+	 * critical; can be tweaked per-system if required. */
+	return 3000;
+}
+
+static int wm8994_ldo1_list_voltage(struct regulator_dev *rdev,
+				    unsigned int selector)
+{
+	if (selector > WM8994_LDO1_MAX_SELECTOR)
+		return -EINVAL;
+
+	return (selector * 100000) + 2400000;
+}
+
+static int wm8994_ldo1_get_voltage(struct regulator_dev *rdev)
+{
+	struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
+	int val;
+
+	val = wm8994_reg_read(ldo->wm8994, WM8994_LDO_1);
+	if (val < 0)
+		return val;
+
+	val = (val & WM8994_LDO1_VSEL_MASK) >> WM8994_LDO1_VSEL_SHIFT;
+
+	return wm8994_ldo1_list_voltage(rdev, val);
+}
+
+static int wm8994_ldo1_set_voltage(struct regulator_dev *rdev,
+				   int min_uV, int max_uV)
+{
+	struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
+	int selector, v;
+
+	selector = (min_uV - 2400000) / 100000;
+	v = wm8994_ldo1_list_voltage(rdev, selector);
+	if (v < 0 || v > max_uV)
+		return -EINVAL;
+
+	selector <<= WM8994_LDO1_VSEL_SHIFT;
+
+	return wm8994_set_bits(ldo->wm8994, WM8994_LDO_1,
+			       WM8994_LDO1_VSEL_MASK, selector);
+}
+
+static struct regulator_ops wm8994_ldo1_ops = {
+	.enable = wm8994_ldo_enable,
+	.disable = wm8994_ldo_disable,
+	.is_enabled = wm8994_ldo_is_enabled,
+	.enable_time = wm8994_ldo_enable_time,
+
+	.list_voltage = wm8994_ldo1_list_voltage,
+	.get_voltage = wm8994_ldo1_get_voltage,
+	.set_voltage = wm8994_ldo1_set_voltage,
+};
+
+static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev,
+				    unsigned int selector)
+{
+	if (selector > WM8994_LDO2_MAX_SELECTOR)
+		return -EINVAL;
+
+	return (selector * 100000) + 900000;
+}
+
+static int wm8994_ldo2_get_voltage(struct regulator_dev *rdev)
+{
+	struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
+	int val;
+
+	val = wm8994_reg_read(ldo->wm8994, WM8994_LDO_2);
+	if (val < 0)
+		return val;
+
+	val = (val & WM8994_LDO2_VSEL_MASK) >> WM8994_LDO2_VSEL_SHIFT;
+
+	return wm8994_ldo2_list_voltage(rdev, val);
+}
+
+static int wm8994_ldo2_set_voltage(struct regulator_dev *rdev,
+				   int min_uV, int max_uV)
+{
+	struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
+	int selector, v;
+
+	selector = (min_uV - 900000) / 100000;
+	v = wm8994_ldo2_list_voltage(rdev, selector);
+	if (v < 0 || v > max_uV)
+		return -EINVAL;
+
+	selector <<= WM8994_LDO2_VSEL_SHIFT;
+
+	return wm8994_set_bits(ldo->wm8994, WM8994_LDO_2,
+			       WM8994_LDO2_VSEL_MASK, selector);
+}
+
+static struct regulator_ops wm8994_ldo2_ops = {
+	.enable = wm8994_ldo_enable,
+	.disable = wm8994_ldo_disable,
+	.is_enabled = wm8994_ldo_is_enabled,
+	.enable_time = wm8994_ldo_enable_time,
+
+	.list_voltage = wm8994_ldo2_list_voltage,
+	.get_voltage = wm8994_ldo2_get_voltage,
+	.set_voltage = wm8994_ldo2_set_voltage,
+};
+
+static struct regulator_desc wm8994_ldo_desc[] = {
+	{
+		.name = "LDO1",
+		.id = 1,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8994_LDO1_MAX_SELECTOR + 1,
+		.ops = &wm8994_ldo1_ops,
+		.owner = THIS_MODULE,
+	},
+	{
+		.name = "LDO2",
+		.id = 2,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8994_LDO2_MAX_SELECTOR + 1,
+		.ops = &wm8994_ldo2_ops,
+		.owner = THIS_MODULE,
+	},
+};
+
+static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
+{
+	struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent);
+	struct wm8994_pdata *pdata = wm8994->dev->platform_data;
+	int id = pdev->id % ARRAY_SIZE(pdata->ldo);
+	struct wm8994_ldo *ldo;
+	int ret;
+
+	dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
+
+	if (!pdata)
+		return -ENODEV;
+
+	ldo = kzalloc(sizeof(struct wm8994_ldo), GFP_KERNEL);
+	if (ldo == NULL) {
+		dev_err(&pdev->dev, "Unable to allocate private data\n");
+		return -ENOMEM;
+	}
+
+	ldo->wm8994 = wm8994;
+
+	ldo->is_enabled = true;
+
+	if (pdata->ldo[id].enable && gpio_is_valid(pdata->ldo[id].enable)) {
+		ldo->enable = pdata->ldo[id].enable;
+
+		ret = gpio_request(ldo->enable, "WM8994 LDO enable");
+		if (ret < 0) {
+			dev_err(&pdev->dev, "Failed to get enable GPIO: %d\n",
+				ret);
+			goto err;
+		}
+
+		ret = gpio_direction_output(ldo->enable, ldo->is_enabled);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "Failed to set GPIO up: %d\n",
+				ret);
+			goto err_gpio;
+		}
+	}
+
+	ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &pdev->dev,
+					     pdata->ldo[id].init_data, ldo);
+	if (IS_ERR(ldo->regulator)) {
+		ret = PTR_ERR(ldo->regulator);
+		dev_err(wm8994->dev, "Failed to register LDO%d: %d\n",
+			id + 1, ret);
+		goto err_gpio;
+	}
+
+	platform_set_drvdata(pdev, ldo);
+
+	return 0;
+
+err_gpio:
+	if (gpio_is_valid(ldo->enable))
+		gpio_free(ldo->enable);
+err:
+	kfree(ldo);
+	return ret;
+}
+
+static __devexit int wm8994_ldo_remove(struct platform_device *pdev)
+{
+	struct wm8994_ldo *ldo = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+
+	regulator_unregister(ldo->regulator);
+	if (gpio_is_valid(ldo->enable))
+		gpio_free(ldo->enable);
+	kfree(ldo);
+
+	return 0;
+}
+
+static struct platform_driver wm8994_ldo_driver = {
+	.probe = wm8994_ldo_probe,
+	.remove = __devexit_p(wm8994_ldo_remove),
+	.driver		= {
+		.name	= "wm8994-ldo",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init wm8994_ldo_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&wm8994_ldo_driver);
+	if (ret != 0)
+		pr_err("Failed to register Wm8994 GP LDO driver: %d\n", ret);
+
+	return ret;
+}
+subsys_initcall(wm8994_ldo_init);
+
+static void __exit wm8994_ldo_exit(void)
+{
+	platform_driver_unregister(&wm8994_ldo_driver);
+}
+module_exit(wm8994_ldo_exit);
+
+/* Module information */
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("WM8994 LDO driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm8994-ldo");
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/class.c linux-libre-2.6.34-gnu1/drivers/rtc/class.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/class.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/class.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/rtc.h>
 #include <linux/kdev_t.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 
 #include "rtc-core.h"
 
@@ -226,6 +227,7 @@ static void __exit rtc_exit(void)
 {
 	rtc_dev_exit();
 	class_destroy(rtc_class);
+	idr_destroy(&rtc_idr);
 }
 
 subsys_initcall(rtc_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/hctosys.c linux-libre-2.6.34-gnu1/drivers/rtc/hctosys.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/hctosys.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/hctosys.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,48 +22,57 @@
  * the best guess is to add 0.5s.
  */
 
+int rtc_hctosys_ret = -ENODEV;
+
 static int __init rtc_hctosys(void)
 {
-	int err;
+	int err = -ENODEV;
 	struct rtc_time tm;
+	struct timespec tv = {
+		.tv_nsec = NSEC_PER_SEC >> 1,
+	};
 	struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
 
 	if (rtc == NULL) {
-		printk("%s: unable to open rtc device (%s)\n",
+		pr_err("%s: unable to open rtc device (%s)\n",
 			__FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
-		return -ENODEV;
+		goto err_open;
 	}
 
 	err = rtc_read_time(rtc, &tm);
-	if (err == 0) {
-		err = rtc_valid_tm(&tm);
-		if (err == 0) {
-			struct timespec tv;
+	if (err) {
+		dev_err(rtc->dev.parent,
+			"hctosys: unable to read the hardware clock\n");
+		goto err_read;
 
-			tv.tv_nsec = NSEC_PER_SEC >> 1;
+	}
 
-			rtc_tm_to_time(&tm, &tv.tv_sec);
+	err = rtc_valid_tm(&tm);
+	if (err) {
+		dev_err(rtc->dev.parent,
+			"hctosys: invalid date/time\n");
+		goto err_invalid;
+	}
 
-			do_settimeofday(&tv);
+	rtc_tm_to_time(&tm, &tv.tv_sec);
 
-			dev_info(rtc->dev.parent,
-				"setting system clock to "
-				"%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n",
-				tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
-				tm.tm_hour, tm.tm_min, tm.tm_sec,
-				(unsigned int) tv.tv_sec);
-		}
-		else
-			dev_err(rtc->dev.parent,
-				"hctosys: invalid date/time\n");
-	}
-	else
-		dev_err(rtc->dev.parent,
-			"hctosys: unable to read the hardware clock\n");
+	do_settimeofday(&tv);
 
+	dev_info(rtc->dev.parent,
+		"setting system clock to "
+		"%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n",
+		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+		tm.tm_hour, tm.tm_min, tm.tm_sec,
+		(unsigned int) tv.tv_sec);
+
+err_invalid:
+err_read:
 	rtc_class_close(rtc);
 
-	return 0;
+err_open:
+	rtc_hctosys_ret = err;
+
+	return err;
 }
 
 late_initcall(rtc_hctosys);
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/Kconfig linux-libre-2.6.34-gnu1/drivers/rtc/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/rtc/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -175,6 +175,16 @@ config RTC_DRV_MAX6900
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-max6900.
 
+config RTC_DRV_MAX8925
+	tristate "Maxim MAX8925"
+	depends on MFD_MAX8925
+	help
+	  If you say yes here you will get support for the
+	  RTC of Maxim MAX8925 PMIC.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-max8925.
+
 config RTC_DRV_RS5C372
 	tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A"
 	help
@@ -868,4 +878,14 @@ config RTC_DRV_MC13783
 	help
 	  This enables support for the Freescale MC13783 PMIC RTC
 
+config RTC_DRV_MPC5121
+	tristate "Freescale MPC5121 built-in RTC"
+	depends on PPC_MPC512x && RTC_CLASS
+	help
+	  If you say yes here you will get support for the
+	  built-in RTC MPC5121.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-mpc5121.
+
 endif # RTC_CLASS
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/Makefile linux-libre-2.6.34-gnu1/drivers/rtc/Makefile
--- linux-libre-2.6.33-gnu1/drivers/rtc/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -52,9 +52,11 @@ obj-$(CONFIG_RTC_DRV_M48T59)	+= rtc-m48t
 obj-$(CONFIG_RTC_DRV_M48T86)	+= rtc-m48t86.o
 obj-$(CONFIG_RTC_MXC)		+= rtc-mxc.o
 obj-$(CONFIG_RTC_DRV_MAX6900)	+= rtc-max6900.o
+obj-$(CONFIG_RTC_DRV_MAX8925)	+= rtc-max8925.o
 obj-$(CONFIG_RTC_DRV_MAX6902)	+= rtc-max6902.o
 obj-$(CONFIG_RTC_DRV_MC13783)	+= rtc-mc13783.o
 obj-$(CONFIG_RTC_DRV_MSM6242)	+= rtc-msm6242.o
+obj-$(CONFIG_RTC_DRV_MPC5121)	+= rtc-mpc5121.o
 obj-$(CONFIG_RTC_DRV_MV)	+= rtc-mv.o
 obj-$(CONFIG_RTC_DRV_NUC900)	+= rtc-nuc900.o
 obj-$(CONFIG_RTC_DRV_OMAP)	+= rtc-omap.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-at32ap700x.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-at32ap700x.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-at32ap700x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-at32ap700x.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/rtc.h>
 #include <linux/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-at91sam9.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-at91sam9.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-at91sam9.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-at91sam9.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/rtc.h>
 #include <linux/interrupt.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 
 #include <mach/board.h>
 #include <mach/at91_rtt.h>
@@ -161,7 +162,7 @@ static int at91_rtc_readalarm(struct dev
 	if (offset == 0)
 		return -EILSEQ;
 
-	memset(alrm, 0, sizeof(alrm));
+	memset(alrm, 0, sizeof(*alrm));
 	if (alarm != ALARM_DISABLED && offset != 0) {
 		rtc_time_to_tm(offset + alarm, tm);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-bfin.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-bfin.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-bfin.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-bfin.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,6 +51,7 @@
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <asm/blackfin.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-bq4802.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-bq4802.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-bq4802.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-bq4802.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 
 MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
 MODULE_DESCRIPTION("TI BQ4802 RTC driver");
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-coh901331.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-coh901331.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-coh901331.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-coh901331.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/pm.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 /*
  * Registers in the COH 901 331
@@ -271,12 +272,13 @@ static int coh901331_resume(struct platf
 {
 	struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev);
 
-	if (device_may_wakeup(&pdev->dev))
+	if (device_may_wakeup(&pdev->dev)) {
 		disable_irq_wake(rtap->irq);
-	else
+	} else {
 		clk_enable(rtap->clk);
 		writel(rtap->irqmaskstore, rtap->virtbase + COH901331_IRQ_MASK);
 		clk_disable(rtap->clk);
+	}
 	return 0;
 }
 #else
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1216.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1216.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1216.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1216.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 
 #define DRV_VERSION "0.2"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1286.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1286.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1286.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1286.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/bcd.h>
 #include <linux/ds1286.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #define DRV_VERSION		"1.0"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1305.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1305.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1305.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1305.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 #include <linux/rtc.h>
 #include <linux/workqueue.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1374.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1374.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1374.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1374.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/rtc.h>
 #include <linux/bcd.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 #define DS1374_REG_TOD0		0x00 /* Time of Day */
 #define DS1374_REG_TOD1		0x01
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1390.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1390.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1390.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1390.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/rtc.h>
 #include <linux/spi/spi.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 
 #define DS1390_REG_100THS		0x00
 #define DS1390_REG_SECONDS		0x01
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1511.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1511.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1511.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1511.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/bcd.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/rtc.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1553.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1553.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1553.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1553.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/bcd.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1742.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1742.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1742.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ds1742.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/bcd.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <linux/rtc.h>
@@ -184,6 +185,7 @@ static int __devinit ds1742_rtc_probe(st
 	pdata->size_nvram = pdata->size - RTC_SIZE;
 	pdata->ioaddr_rtc = ioaddr + pdata->size_nvram;
 
+	sysfs_bin_attr_init(&pdata->nvram_attr);
 	pdata->nvram_attr.attr.name = "nvram";
 	pdata->nvram_attr.attr.mode = S_IRUGO | S_IWUSR;
 	pdata->nvram_attr.read = ds1742_nvram_read;
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ep93xx.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ep93xx.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ep93xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-ep93xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 
 #define EP93XX_RTC_DATA			0x000
 #define EP93XX_RTC_MATCH		0x004
@@ -115,6 +116,15 @@ static ssize_t ep93xx_rtc_show_comp_dele
 }
 static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_rtc_show_comp_delete, NULL);
 
+static struct attribute *ep93xx_rtc_attrs[] = {
+	&dev_attr_comp_preload.attr,
+	&dev_attr_comp_delete.attr,
+	NULL
+};
+
+static const struct attribute_group ep93xx_rtc_sysfs_files = {
+	.attrs	= ep93xx_rtc_attrs,
+};
 
 static int __init ep93xx_rtc_probe(struct platform_device *pdev)
 {
@@ -123,27 +133,22 @@ static int __init ep93xx_rtc_probe(struc
 	struct rtc_device *rtc;
 	int err;
 
-	ep93xx_rtc = kzalloc(sizeof(struct ep93xx_rtc), GFP_KERNEL);
-	if (ep93xx_rtc == NULL)
+	ep93xx_rtc = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_rtc), GFP_KERNEL);
+	if (!ep93xx_rtc)
 		return -ENOMEM;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res == NULL) {
-		err = -ENXIO;
-		goto fail_free;
-	}
+	if (!res)
+		return -ENXIO;
 
-	res = request_mem_region(res->start, resource_size(res), pdev->name);
-	if (res == NULL) {
-		err = -EBUSY;
-		goto fail_free;
-	}
+	if (!devm_request_mem_region(&pdev->dev, res->start,
+				     resource_size(res), pdev->name))
+		return -EBUSY;
 
-	ep93xx_rtc->mmio_base = ioremap(res->start, resource_size(res));
-	if (ep93xx_rtc->mmio_base == NULL) {
-		err = -ENXIO;
-		goto fail;
-	}
+	ep93xx_rtc->mmio_base = devm_ioremap(&pdev->dev, res->start,
+					     resource_size(res));
+	if (!ep93xx_rtc->mmio_base)
+		return -ENXIO;
 
 	pdev->dev.platform_data = ep93xx_rtc;
 
@@ -151,53 +156,34 @@ static int __init ep93xx_rtc_probe(struc
 				&pdev->dev, &ep93xx_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc)) {
 		err = PTR_ERR(rtc);
-		goto fail;
+		goto exit;
 	}
 
 	platform_set_drvdata(pdev, rtc);
 
-	err = device_create_file(&pdev->dev, &dev_attr_comp_preload);
+	err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files);
 	if (err)
 		goto fail;
-	err = device_create_file(&pdev->dev, &dev_attr_comp_delete);
-	if (err) {
-		device_remove_file(&pdev->dev, &dev_attr_comp_preload);
-		goto fail;
-	}
 
 	return 0;
 
 fail:
-	if (ep93xx_rtc->mmio_base) {
-		iounmap(ep93xx_rtc->mmio_base);
-		pdev->dev.platform_data = NULL;
-	}
-	release_mem_region(res->start, resource_size(res));
-fail_free:
-	kfree(ep93xx_rtc);
+	platform_set_drvdata(pdev, NULL);
+	rtc_device_unregister(rtc);
+exit:
+	pdev->dev.platform_data = NULL;
 	return err;
 }
 
 static int __exit ep93xx_rtc_remove(struct platform_device *pdev)
 {
 	struct rtc_device *rtc = platform_get_drvdata(pdev);
-	struct ep93xx_rtc *ep93xx_rtc = pdev->dev.platform_data;
-	struct resource *res;
-
-	/* cleanup sysfs */
-	device_remove_file(&pdev->dev, &dev_attr_comp_delete);
-	device_remove_file(&pdev->dev, &dev_attr_comp_preload);
 
+	sysfs_remove_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files);
+	platform_set_drvdata(pdev, NULL);
 	rtc_device_unregister(rtc);
-
-	iounmap(ep93xx_rtc->mmio_base);
 	pdev->dev.platform_data = NULL;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(res->start, resource_size(res));
-
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-fm3130.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-fm3130.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-fm3130.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-fm3130.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/i2c.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 
 #define FM3130_RTC_CONTROL	(0x0)
 #define FM3130_CAL_CONTROL	(0x1)
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-m48t35.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-m48t35.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-m48t35.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-m48t35.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 
 #include <linux/module.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/bcd.h>
 #include <linux/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-m48t59.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-m48t59.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-m48t59.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-m48t59.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/rtc.h>
 #include <linux/rtc/m48t59.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 
 #ifndef NO_IRQ
 #define NO_IRQ	(-1)
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-max8925.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-max8925.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-max8925.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-max8925.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,315 @@
+/*
+ * RTC driver for Maxim MAX8925
+ *
+ * Copyright (C) 2009-2010 Marvell International Ltd.
+ *	Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/max8925.h>
+
+enum {
+	RTC_SEC = 0,
+	RTC_MIN,
+	RTC_HOUR,
+	RTC_WEEKDAY,
+	RTC_DATE,
+	RTC_MONTH,
+	RTC_YEAR1,
+	RTC_YEAR2,
+};
+
+#define MAX8925_RTC_SEC			0x00
+#define MAX8925_RTC_MIN			0x01
+#define MAX8925_RTC_HOUR		0x02
+#define MAX8925_RTC_WEEKDAY		0x03
+#define MAX8925_RTC_DATE		0x04
+#define MAX8925_RTC_MONTH		0x05
+#define MAX8925_RTC_YEAR1		0x06
+#define MAX8925_RTC_YEAR2		0x07
+#define MAX8925_ALARM0_SEC		0x08
+#define MAX8925_ALARM0_MIN		0x09
+#define MAX8925_ALARM0_HOUR		0x0a
+#define MAX8925_ALARM0_WEEKDAY		0x0b
+#define MAX8925_ALARM0_DATE		0x0c
+#define MAX8925_ALARM0_MON		0x0d
+#define MAX8925_ALARM0_YEAR1		0x0e
+#define MAX8925_ALARM0_YEAR2		0x0f
+#define MAX8925_ALARM1_SEC		0x10
+#define MAX8925_ALARM1_MIN		0x11
+#define MAX8925_ALARM1_HOUR		0x12
+#define MAX8925_ALARM1_WEEKDAY		0x13
+#define MAX8925_ALARM1_DATE		0x14
+#define MAX8925_ALARM1_MON		0x15
+#define MAX8925_ALARM1_YEAR1		0x16
+#define MAX8925_ALARM1_YEAR2		0x17
+#define MAX8925_RTC_CNTL		0x1b
+#define MAX8925_RTC_STATUS		0x20
+
+#define TIME_NUM			8
+#define ALARM_1SEC			(1 << 7)
+#define HOUR_12				(1 << 7)
+#define HOUR_AM_PM			(1 << 5)
+#define ALARM0_IRQ			(1 << 3)
+#define ALARM1_IRQ			(1 << 2)
+#define ALARM0_STATUS			(1 << 2)
+#define ALARM1_STATUS			(1 << 1)
+
+
+struct max8925_rtc_info {
+	struct rtc_device	*rtc_dev;
+	struct max8925_chip	*chip;
+	struct i2c_client	*rtc;
+	struct device		*dev;
+};
+
+static irqreturn_t rtc_update_handler(int irq, void *data)
+{
+	struct max8925_rtc_info *info = (struct max8925_rtc_info *)data;
+
+	/* disable ALARM0 except for 1SEC alarm */
+	max8925_set_bits(info->rtc, MAX8925_ALARM0_CNTL, 0x7f, 0);
+	rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF);
+	return IRQ_HANDLED;
+}
+
+static int tm_calc(struct rtc_time *tm, unsigned char *buf, int len)
+{
+	if (len < TIME_NUM)
+		return -EINVAL;
+	tm->tm_year = (buf[RTC_YEAR2] >> 4) * 1000
+			+ (buf[RTC_YEAR2] & 0xf) * 100
+			+ (buf[RTC_YEAR1] >> 4) * 10
+			+ (buf[RTC_YEAR1] & 0xf);
+	tm->tm_year -= 1900;
+	tm->tm_mon = ((buf[RTC_MONTH] >> 4) & 0x01) * 10
+			+ (buf[RTC_MONTH] & 0x0f);
+	tm->tm_mday = ((buf[RTC_DATE] >> 4) & 0x03) * 10
+			+ (buf[RTC_DATE] & 0x0f);
+	tm->tm_wday = buf[RTC_WEEKDAY] & 0x07;
+	if (buf[RTC_HOUR] & HOUR_12) {
+		tm->tm_hour = ((buf[RTC_HOUR] >> 4) & 0x1) * 10
+				+ (buf[RTC_HOUR] & 0x0f);
+		if (buf[RTC_HOUR] & HOUR_AM_PM)
+			tm->tm_hour += 12;
+	} else
+		tm->tm_hour = ((buf[RTC_HOUR] >> 4) & 0x03) * 10
+				+ (buf[RTC_HOUR] & 0x0f);
+	tm->tm_min = ((buf[RTC_MIN] >> 4) & 0x7) * 10
+			+ (buf[RTC_MIN] & 0x0f);
+	tm->tm_sec = ((buf[RTC_SEC] >> 4) & 0x7) * 10
+			+ (buf[RTC_SEC] & 0x0f);
+	return 0;
+}
+
+static int data_calc(unsigned char *buf, struct rtc_time *tm, int len)
+{
+	unsigned char high, low;
+
+	if (len < TIME_NUM)
+		return -EINVAL;
+
+	high = (tm->tm_year + 1900) / 1000;
+	low = (tm->tm_year + 1900) / 100;
+	low = low - high * 10;
+	buf[RTC_YEAR2] = (high << 4) + low;
+	high = (tm->tm_year + 1900) / 10;
+	low = tm->tm_year + 1900;
+	low = low - high * 10;
+	high = high - (high / 10) * 10;
+	buf[RTC_YEAR1] = (high << 4) + low;
+	high = tm->tm_mon / 10;
+	low = tm->tm_mon;
+	low = low - high * 10;
+	buf[RTC_MONTH] = (high << 4) + low;
+	high = tm->tm_mday / 10;
+	low = tm->tm_mday;
+	low = low - high * 10;
+	buf[RTC_DATE] = (high << 4) + low;
+	buf[RTC_WEEKDAY] = tm->tm_wday;
+	high = tm->tm_hour / 10;
+	low = tm->tm_hour;
+	low = low - high * 10;
+	buf[RTC_HOUR] = (high << 4) + low;
+	high = tm->tm_min / 10;
+	low = tm->tm_min;
+	low = low - high * 10;
+	buf[RTC_MIN] = (high << 4) + low;
+	high = tm->tm_sec / 10;
+	low = tm->tm_sec;
+	low = low - high * 10;
+	buf[RTC_SEC] = (high << 4) + low;
+	return 0;
+}
+
+static int max8925_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct max8925_rtc_info *info = dev_get_drvdata(dev);
+	unsigned char buf[TIME_NUM];
+	int ret;
+
+	ret = max8925_bulk_read(info->rtc, MAX8925_RTC_SEC, TIME_NUM, buf);
+	if (ret < 0)
+		goto out;
+	ret = tm_calc(tm, buf, TIME_NUM);
+out:
+	return ret;
+}
+
+static int max8925_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct max8925_rtc_info *info = dev_get_drvdata(dev);
+	unsigned char buf[TIME_NUM];
+	int ret;
+
+	ret = data_calc(buf, tm, TIME_NUM);
+	if (ret < 0)
+		goto out;
+	ret = max8925_bulk_write(info->rtc, MAX8925_RTC_SEC, TIME_NUM, buf);
+out:
+	return ret;
+}
+
+static int max8925_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct max8925_rtc_info *info = dev_get_drvdata(dev);
+	unsigned char buf[TIME_NUM];
+	int ret;
+
+	ret = max8925_bulk_read(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf);
+	if (ret < 0)
+		goto out;
+	ret = tm_calc(&alrm->time, buf, TIME_NUM);
+	if (ret < 0)
+		goto out;
+	ret = max8925_reg_read(info->rtc, MAX8925_RTC_IRQ_MASK);
+	if (ret < 0)
+		goto out;
+	if ((ret & ALARM0_IRQ) == 0)
+		alrm->enabled = 1;
+	else
+		alrm->enabled = 0;
+	ret = max8925_reg_read(info->rtc, MAX8925_RTC_STATUS);
+	if (ret < 0)
+		goto out;
+	if (ret & ALARM0_STATUS)
+		alrm->pending = 1;
+	else
+		alrm->pending = 0;
+out:
+	return ret;
+}
+
+static int max8925_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct max8925_rtc_info *info = dev_get_drvdata(dev);
+	unsigned char buf[TIME_NUM];
+	int ret;
+
+	ret = data_calc(buf, &alrm->time, TIME_NUM);
+	if (ret < 0)
+		goto out;
+	ret = max8925_bulk_write(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf);
+	if (ret < 0)
+		goto out;
+	/* only enable alarm on year/month/day/hour/min/sec */
+	ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77);
+	if (ret < 0)
+		goto out;
+out:
+	return ret;
+}
+
+static const struct rtc_class_ops max8925_rtc_ops = {
+	.read_time	= max8925_rtc_read_time,
+	.set_time	= max8925_rtc_set_time,
+	.read_alarm	= max8925_rtc_read_alarm,
+	.set_alarm	= max8925_rtc_set_alarm,
+};
+
+static int __devinit max8925_rtc_probe(struct platform_device *pdev)
+{
+	struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct max8925_rtc_info *info;
+	int irq, ret;
+
+	info = kzalloc(sizeof(struct max8925_rtc_info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+	info->chip = chip;
+	info->rtc = chip->rtc;
+	info->dev = &pdev->dev;
+	irq = chip->irq_base + MAX8925_IRQ_RTC_ALARM0;
+
+	ret = request_threaded_irq(irq, NULL, rtc_update_handler,
+				   IRQF_ONESHOT, "rtc-alarm0", info);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
+			irq, ret);
+		goto out_irq;
+	}
+
+	info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev,
+					&max8925_rtc_ops, THIS_MODULE);
+	ret = PTR_ERR(info->rtc_dev);
+	if (IS_ERR(info->rtc_dev)) {
+		dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
+		goto out_rtc;
+	}
+
+	dev_set_drvdata(&pdev->dev, info);
+	platform_set_drvdata(pdev, info);
+
+	return 0;
+out_rtc:
+	free_irq(chip->irq_base + MAX8925_IRQ_RTC_ALARM0, info);
+out_irq:
+	kfree(info);
+	return ret;
+}
+
+static int __devexit max8925_rtc_remove(struct platform_device *pdev)
+{
+	struct max8925_rtc_info *info = platform_get_drvdata(pdev);
+
+	if (info) {
+		free_irq(info->chip->irq_base + MAX8925_IRQ_RTC_ALARM0, info);
+		rtc_device_unregister(info->rtc_dev);
+		kfree(info);
+	}
+	return 0;
+}
+
+static struct platform_driver max8925_rtc_driver = {
+	.driver		= {
+		.name	= "max8925-rtc",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= max8925_rtc_probe,
+	.remove		= __devexit_p(max8925_rtc_remove),
+};
+
+static int __init max8925_rtc_init(void)
+{
+	return platform_driver_register(&max8925_rtc_driver);
+}
+module_init(max8925_rtc_init);
+
+static void __exit max8925_rtc_exit(void)
+{
+	platform_driver_unregister(&max8925_rtc_driver);
+}
+module_exit(max8925_rtc_exit);
+
+MODULE_DESCRIPTION("Maxim MAX8925 RTC driver");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-mc13783.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-mc13783.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-mc13783.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-mc13783.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/rtc.h>
 
 #define DRIVER_NAME "mc13783-rtc"
@@ -28,6 +29,34 @@ struct mc13783_rtc {
 	int valid;
 };
 
+static int mc13783_rtc_irq_enable_unlocked(struct device *dev,
+		unsigned int enabled, int irq)
+{
+	struct mc13783_rtc *priv = dev_get_drvdata(dev);
+	int (*func)(struct mc13783 *mc13783, int irq);
+
+	if (!priv->valid)
+		return -ENODATA;
+
+	func = enabled ? mc13783_irq_unmask : mc13783_irq_mask;
+	return func(priv->mc13783, irq);
+}
+
+static int mc13783_rtc_irq_enable(struct device *dev,
+		unsigned int enabled, int irq)
+{
+	struct mc13783_rtc *priv = dev_get_drvdata(dev);
+	int ret;
+
+	mc13783_lock(priv->mc13783);
+
+	ret = mc13783_rtc_irq_enable_unlocked(dev, enabled, irq);
+
+	mc13783_unlock(priv->mc13783);
+
+	return ret;
+}
+
 static int mc13783_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
 	struct mc13783_rtc *priv = dev_get_drvdata(dev);
@@ -78,6 +107,7 @@ static int mc13783_rtc_set_mmss(struct d
 {
 	struct mc13783_rtc *priv = dev_get_drvdata(dev);
 	unsigned int seconds, days;
+	unsigned int alarmseconds;
 	int ret;
 
 	seconds = secs % 86400;
@@ -86,7 +116,22 @@ static int mc13783_rtc_set_mmss(struct d
 	mc13783_lock(priv->mc13783);
 
 	/*
-	 * first write seconds=0 to prevent a day switch between writing days
+	 * temporarily invalidate alarm to prevent triggering it when the day is
+	 * already updated while the time isn't yet.
+	 */
+	ret = mc13783_reg_read(priv->mc13783, MC13783_RTCTODA, &alarmseconds);
+	if (unlikely(ret))
+		goto out;
+
+	if (alarmseconds < 86400) {
+		ret = mc13783_reg_write(priv->mc13783,
+				MC13783_RTCTODA, 0x1ffff);
+		if (unlikely(ret))
+			goto out;
+	}
+
+	/*
+	 * write seconds=0 to prevent a day switch between writing days
 	 * and seconds below
 	 */
 	ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTOD, 0);
@@ -101,11 +146,19 @@ static int mc13783_rtc_set_mmss(struct d
 	if (unlikely(ret))
 		goto out;
 
-	ret = mc13783_ackirq(priv->mc13783, MC13783_IRQ_RTCRST);
+	/* restore alarm */
+	if (alarmseconds < 86400) {
+		ret = mc13783_reg_write(priv->mc13783,
+				MC13783_RTCTODA, alarmseconds);
+		if (unlikely(ret))
+			goto out;
+	}
+
+	ret = mc13783_irq_ack(priv->mc13783, MC13783_IRQ_RTCRST);
 	if (unlikely(ret))
 		goto out;
 
-	ret = mc13783_unmask(priv->mc13783, MC13783_IRQ_RTCRST);
+	ret = mc13783_irq_unmask(priv->mc13783, MC13783_IRQ_RTCRST);
 out:
 	priv->valid = !ret;
 
@@ -114,41 +167,139 @@ out:
 	return ret;
 }
 
-static irqreturn_t mc13783_rtc_update_handler(int irq, void *dev)
+static int mc13783_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-	struct mc13783_rtc *priv = dev;
-	struct mc13783 *mc13783 = priv->mc13783;
+	struct mc13783_rtc *priv = dev_get_drvdata(dev);
+	unsigned seconds, days;
+	unsigned long s1970;
+	int enabled, pending;
+	int ret;
 
-	dev_dbg(&priv->rtc->dev, "1HZ\n");
+	mc13783_lock(priv->mc13783);
 
-	rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF);
+	ret = mc13783_reg_read(priv->mc13783, MC13783_RTCTODA, &seconds);
+	if (unlikely(ret))
+		goto out;
+	if (seconds >= 86400) {
+		ret = -ENODATA;
+		goto out;
+	}
 
-	mc13783_ackirq(mc13783, irq);
+	ret = mc13783_reg_read(priv->mc13783, MC13783_RTCDAY, &days);
+	if (unlikely(ret))
+		goto out;
 
-	return IRQ_HANDLED;
+	ret = mc13783_irq_status(priv->mc13783, MC13783_IRQ_TODA,
+			&enabled, &pending);
+
+out:
+	mc13783_unlock(priv->mc13783);
+
+	if (ret)
+		return ret;
+
+	alarm->enabled = enabled;
+	alarm->pending = pending;
+
+	s1970 = days * 86400 + seconds;
+
+	rtc_time_to_tm(s1970, &alarm->time);
+	dev_dbg(dev, "%s: %lu\n", __func__, s1970);
+
+	return 0;
 }
 
-static int mc13783_rtc_update_irq_enable(struct device *dev,
-		unsigned int enabled)
+static int mc13783_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	struct mc13783_rtc *priv = dev_get_drvdata(dev);
-	int ret = -ENODATA;
+	unsigned long s1970;
+	unsigned seconds, days;
+	int ret;
 
 	mc13783_lock(priv->mc13783);
-	if (!priv->valid)
+
+	/* disable alarm to prevent false triggering */
+	ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTODA, 0x1ffff);
+	if (unlikely(ret))
 		goto out;
 
-	ret = (enabled ? mc13783_unmask : mc13783_mask)(priv->mc13783,
-			MC13783_IRQ_1HZ);
+	ret = mc13783_irq_ack(priv->mc13783, MC13783_IRQ_TODA);
+	if (unlikely(ret))
+		goto out;
+
+	ret = rtc_tm_to_time(&alarm->time, &s1970);
+	if (unlikely(ret))
+		goto out;
+
+	dev_dbg(dev, "%s: o%2.s %lu\n", __func__, alarm->enabled ? "n" : "ff",
+			s1970);
+
+	ret = mc13783_rtc_irq_enable_unlocked(dev, alarm->enabled,
+			MC13783_IRQ_TODA);
+	if (unlikely(ret))
+		goto out;
+
+	seconds = s1970 % 86400;
+	days = s1970 / 86400;
+
+	ret = mc13783_reg_write(priv->mc13783, MC13783_RTCDAYA, days);
+	if (unlikely(ret))
+		goto out;
+
+	ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTODA, seconds);
+
 out:
 	mc13783_unlock(priv->mc13783);
 
 	return ret;
 }
 
+static irqreturn_t mc13783_rtc_alarm_handler(int irq, void *dev)
+{
+	struct mc13783_rtc *priv = dev;
+	struct mc13783 *mc13783 = priv->mc13783;
+
+	dev_dbg(&priv->rtc->dev, "Alarm\n");
+
+	rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_AF);
+
+	mc13783_irq_ack(mc13783, irq);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t mc13783_rtc_update_handler(int irq, void *dev)
+{
+	struct mc13783_rtc *priv = dev;
+	struct mc13783 *mc13783 = priv->mc13783;
+
+	dev_dbg(&priv->rtc->dev, "1HZ\n");
+
+	rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF);
+
+	mc13783_irq_ack(mc13783, irq);
+
+	return IRQ_HANDLED;
+}
+
+static int mc13783_rtc_update_irq_enable(struct device *dev,
+		unsigned int enabled)
+{
+	return mc13783_rtc_irq_enable(dev, enabled, MC13783_IRQ_1HZ);
+}
+
+static int mc13783_rtc_alarm_irq_enable(struct device *dev,
+		unsigned int enabled)
+{
+	return mc13783_rtc_irq_enable(dev, enabled, MC13783_IRQ_TODA);
+}
+
 static const struct rtc_class_ops mc13783_rtc_ops = {
 	.read_time = mc13783_rtc_read_time,
 	.set_mmss = mc13783_rtc_set_mmss,
+	.read_alarm = mc13783_rtc_read_alarm,
+	.set_alarm = mc13783_rtc_set_alarm,
+	.alarm_irq_enable = mc13783_rtc_alarm_irq_enable,
 	.update_irq_enable = mc13783_rtc_update_irq_enable,
 };
 
@@ -160,7 +311,7 @@ static irqreturn_t mc13783_rtc_reset_han
 	dev_dbg(&priv->rtc->dev, "RTCRST\n");
 	priv->valid = 0;
 
-	mc13783_mask(mc13783, irq);
+	mc13783_irq_mask(mc13783, irq);
 
 	return IRQ_HANDLED;
 }
@@ -169,50 +320,64 @@ static int __devinit mc13783_rtc_probe(s
 {
 	int ret;
 	struct mc13783_rtc *priv;
+	struct mc13783 *mc13783;
+	int rtcrst_pending;
 
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
-	priv->mc13783 = dev_get_drvdata(pdev->dev.parent);
-	platform_set_drvdata(pdev, priv);
+	mc13783 = dev_get_drvdata(pdev->dev.parent);
+	priv->mc13783 = mc13783;
 
-	priv->valid = 1;
+	platform_set_drvdata(pdev, priv);
 
-	mc13783_lock(priv->mc13783);
+	mc13783_lock(mc13783);
 
-	ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_RTCRST,
+	ret = mc13783_irq_request(mc13783, MC13783_IRQ_RTCRST,
 			mc13783_rtc_reset_handler, DRIVER_NAME, priv);
 	if (ret)
 		goto err_reset_irq_request;
 
-	ret = mc13783_irq_request_nounmask(priv->mc13783, MC13783_IRQ_1HZ,
+	ret = mc13783_irq_status(mc13783, MC13783_IRQ_RTCRST,
+			NULL, &rtcrst_pending);
+	if (ret)
+		goto err_reset_irq_status;
+
+	priv->valid = !rtcrst_pending;
+
+	ret = mc13783_irq_request_nounmask(mc13783, MC13783_IRQ_1HZ,
 			mc13783_rtc_update_handler, DRIVER_NAME, priv);
 	if (ret)
 		goto err_update_irq_request;
 
-	mc13783_unlock(priv->mc13783);
+	ret = mc13783_irq_request_nounmask(mc13783, MC13783_IRQ_TODA,
+			mc13783_rtc_alarm_handler, DRIVER_NAME, priv);
+	if (ret)
+		goto err_alarm_irq_request;
 
 	priv->rtc = rtc_device_register(pdev->name,
 			&pdev->dev, &mc13783_rtc_ops, THIS_MODULE);
-
 	if (IS_ERR(priv->rtc)) {
 		ret = PTR_ERR(priv->rtc);
 
-		mc13783_lock(priv->mc13783);
+		mc13783_irq_free(mc13783, MC13783_IRQ_TODA, priv);
+err_alarm_irq_request:
 
-		mc13783_irq_free(priv->mc13783, MC13783_IRQ_1HZ, priv);
+		mc13783_irq_free(mc13783, MC13783_IRQ_1HZ, priv);
 err_update_irq_request:
 
-		mc13783_irq_free(priv->mc13783, MC13783_IRQ_RTCRST, priv);
-err_reset_irq_request:
+err_reset_irq_status:
 
-		mc13783_unlock(priv->mc13783);
+		mc13783_irq_free(mc13783, MC13783_IRQ_RTCRST, priv);
+err_reset_irq_request:
 
 		platform_set_drvdata(pdev, NULL);
 		kfree(priv);
 	}
 
+	mc13783_unlock(mc13783);
+
 	return ret;
 }
 
@@ -220,10 +385,11 @@ static int __devexit mc13783_rtc_remove(
 {
 	struct mc13783_rtc *priv = platform_get_drvdata(pdev);
 
-	rtc_device_unregister(priv->rtc);
-
 	mc13783_lock(priv->mc13783);
 
+	rtc_device_unregister(priv->rtc);
+
+	mc13783_irq_free(priv->mc13783, MC13783_IRQ_TODA, priv);
 	mc13783_irq_free(priv->mc13783, MC13783_IRQ_1HZ, priv);
 	mc13783_irq_free(priv->mc13783, MC13783_IRQ_RTCRST, priv);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-mpc5121.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-mpc5121.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-mpc5121.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-mpc5121.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,388 @@
+/*
+ * Real-time clock driver for MPC5121
+ *
+ * Copyright 2007, Domen Puncer <domen.puncer@telargo.com>
+ * Copyright 2008, 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/rtc.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+struct mpc5121_rtc_regs {
+	u8 set_time;		/* RTC + 0x00 */
+	u8 hour_set;		/* RTC + 0x01 */
+	u8 minute_set;		/* RTC + 0x02 */
+	u8 second_set;		/* RTC + 0x03 */
+
+	u8 set_date;		/* RTC + 0x04 */
+	u8 month_set;		/* RTC + 0x05 */
+	u8 weekday_set;		/* RTC + 0x06 */
+	u8 date_set;		/* RTC + 0x07 */
+
+	u8 write_sw;		/* RTC + 0x08 */
+	u8 sw_set;		/* RTC + 0x09 */
+	u16 year_set;		/* RTC + 0x0a */
+
+	u8 alm_enable;		/* RTC + 0x0c */
+	u8 alm_hour_set;	/* RTC + 0x0d */
+	u8 alm_min_set;		/* RTC + 0x0e */
+	u8 int_enable;		/* RTC + 0x0f */
+
+	u8 reserved1;
+	u8 hour;		/* RTC + 0x11 */
+	u8 minute;		/* RTC + 0x12 */
+	u8 second;		/* RTC + 0x13 */
+
+	u8 month;		/* RTC + 0x14 */
+	u8 wday_mday;		/* RTC + 0x15 */
+	u16 year;		/* RTC + 0x16 */
+
+	u8 int_alm;		/* RTC + 0x18 */
+	u8 int_sw;		/* RTC + 0x19 */
+	u8 alm_status;		/* RTC + 0x1a */
+	u8 sw_minute;		/* RTC + 0x1b */
+
+	u8 bus_error_1;		/* RTC + 0x1c */
+	u8 int_day;		/* RTC + 0x1d */
+	u8 int_min;		/* RTC + 0x1e */
+	u8 int_sec;		/* RTC + 0x1f */
+
+	/*
+	 * target_time:
+	 *	intended to be used for hibernation but hibernation
+	 *	does not work on silicon rev 1.5 so use it for non-volatile
+	 *	storage of offset between the actual_time register and linux
+	 *	time
+	 */
+	u32 target_time;	/* RTC + 0x20 */
+	/*
+	 * actual_time:
+	 * 	readonly time since VBAT_RTC was last connected
+	 */
+	u32 actual_time;	/* RTC + 0x24 */
+	u32 keep_alive;		/* RTC + 0x28 */
+};
+
+struct mpc5121_rtc_data {
+	unsigned irq;
+	unsigned irq_periodic;
+	struct mpc5121_rtc_regs __iomem *regs;
+	struct rtc_device *rtc;
+	struct rtc_wkalrm wkalarm;
+};
+
+/*
+ * Update second/minute/hour registers.
+ *
+ * This is just so alarm will work.
+ */
+static void mpc5121_rtc_update_smh(struct mpc5121_rtc_regs __iomem *regs,
+				   struct rtc_time *tm)
+{
+	out_8(&regs->second_set, tm->tm_sec);
+	out_8(&regs->minute_set, tm->tm_min);
+	out_8(&regs->hour_set, tm->tm_hour);
+
+	/* set time sequence */
+	out_8(&regs->set_time, 0x1);
+	out_8(&regs->set_time, 0x3);
+	out_8(&regs->set_time, 0x1);
+	out_8(&regs->set_time, 0x0);
+}
+
+static int mpc5121_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
+	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+	unsigned long now;
+
+	/*
+	 * linux time is actual_time plus the offset saved in target_time
+	 */
+	now = in_be32(&regs->actual_time) + in_be32(&regs->target_time);
+
+	rtc_time_to_tm(now, tm);
+
+	/*
+	 * update second minute hour registers
+	 * so alarms will work
+	 */
+	mpc5121_rtc_update_smh(regs, tm);
+
+	return rtc_valid_tm(tm);
+}
+
+static int mpc5121_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
+	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+	int ret;
+	unsigned long now;
+
+	/*
+	 * The actual_time register is read only so we write the offset
+	 * between it and linux time to the target_time register.
+	 */
+	ret = rtc_tm_to_time(tm, &now);
+	if (ret == 0)
+		out_be32(&regs->target_time, now - in_be32(&regs->actual_time));
+
+	/*
+	 * update second minute hour registers
+	 * so alarms will work
+	 */
+	mpc5121_rtc_update_smh(regs, tm);
+
+	return 0;
+}
+
+static int mpc5121_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
+	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+
+	*alarm = rtc->wkalarm;
+
+	alarm->pending = in_8(&regs->alm_status);
+
+	return 0;
+}
+
+static int mpc5121_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
+	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+
+	/*
+	 * the alarm has no seconds so deal with it
+	 */
+	if (alarm->time.tm_sec) {
+		alarm->time.tm_sec = 0;
+		alarm->time.tm_min++;
+		if (alarm->time.tm_min >= 60) {
+			alarm->time.tm_min = 0;
+			alarm->time.tm_hour++;
+			if (alarm->time.tm_hour >= 24)
+				alarm->time.tm_hour = 0;
+		}
+	}
+
+	alarm->time.tm_mday = -1;
+	alarm->time.tm_mon = -1;
+	alarm->time.tm_year = -1;
+
+	out_8(&regs->alm_min_set, alarm->time.tm_min);
+	out_8(&regs->alm_hour_set, alarm->time.tm_hour);
+
+	out_8(&regs->alm_enable, alarm->enabled);
+
+	rtc->wkalarm = *alarm;
+	return 0;
+}
+
+static irqreturn_t mpc5121_rtc_handler(int irq, void *dev)
+{
+	struct mpc5121_rtc_data *rtc = dev_get_drvdata((struct device *)dev);
+	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+
+	if (in_8(&regs->int_alm)) {
+		/* acknowledge and clear status */
+		out_8(&regs->int_alm, 1);
+		out_8(&regs->alm_status, 1);
+
+		rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static irqreturn_t mpc5121_rtc_handler_upd(int irq, void *dev)
+{
+	struct mpc5121_rtc_data *rtc = dev_get_drvdata((struct device *)dev);
+	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+
+	if (in_8(&regs->int_sec) && (in_8(&regs->int_enable) & 0x1)) {
+		/* acknowledge */
+		out_8(&regs->int_sec, 1);
+
+		rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_UF);
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static int mpc5121_rtc_alarm_irq_enable(struct device *dev,
+					unsigned int enabled)
+{
+	struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
+	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+	int val;
+
+	if (enabled)
+		val = 1;
+	else
+		val = 0;
+
+	out_8(&regs->alm_enable, val);
+	rtc->wkalarm.enabled = val;
+
+	return 0;
+}
+
+static int mpc5121_rtc_update_irq_enable(struct device *dev,
+					 unsigned int enabled)
+{
+	struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
+	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+	int val;
+
+	val = in_8(&regs->int_enable);
+
+	if (enabled)
+		val = (val & ~0x8) | 0x1;
+	else
+		val &= ~0x1;
+
+	out_8(&regs->int_enable, val);
+
+	return 0;
+}
+
+static const struct rtc_class_ops mpc5121_rtc_ops = {
+	.read_time = mpc5121_rtc_read_time,
+	.set_time = mpc5121_rtc_set_time,
+	.read_alarm = mpc5121_rtc_read_alarm,
+	.set_alarm = mpc5121_rtc_set_alarm,
+	.alarm_irq_enable = mpc5121_rtc_alarm_irq_enable,
+	.update_irq_enable = mpc5121_rtc_update_irq_enable,
+};
+
+static int __devinit mpc5121_rtc_probe(struct of_device *op,
+					const struct of_device_id *match)
+{
+	struct mpc5121_rtc_data *rtc;
+	int err = 0;
+	u32 ka;
+
+	rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
+	if (!rtc)
+		return -ENOMEM;
+
+	rtc->regs = of_iomap(op->node, 0);
+	if (!rtc->regs) {
+		dev_err(&op->dev, "%s: couldn't map io space\n", __func__);
+		err = -ENOSYS;
+		goto out_free;
+	}
+
+	device_init_wakeup(&op->dev, 1);
+
+	dev_set_drvdata(&op->dev, rtc);
+
+	rtc->irq = irq_of_parse_and_map(op->node, 1);
+	err = request_irq(rtc->irq, mpc5121_rtc_handler, IRQF_DISABLED,
+						"mpc5121-rtc", &op->dev);
+	if (err) {
+		dev_err(&op->dev, "%s: could not request irq: %i\n",
+							__func__, rtc->irq);
+		goto out_dispose;
+	}
+
+	rtc->irq_periodic = irq_of_parse_and_map(op->node, 0);
+	err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd,
+				IRQF_DISABLED, "mpc5121-rtc_upd", &op->dev);
+	if (err) {
+		dev_err(&op->dev, "%s: could not request irq: %i\n",
+						__func__, rtc->irq_periodic);
+		goto out_dispose2;
+	}
+
+	ka = in_be32(&rtc->regs->keep_alive);
+	if (ka & 0x02) {
+		dev_warn(&op->dev,
+			"mpc5121-rtc: Battery or oscillator failure!\n");
+		out_be32(&rtc->regs->keep_alive, ka);
+	}
+
+	rtc->rtc = rtc_device_register("mpc5121-rtc", &op->dev,
+					&mpc5121_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc->rtc)) {
+		err = PTR_ERR(rtc->rtc);
+		goto out_free_irq;
+	}
+
+	return 0;
+
+out_free_irq:
+	free_irq(rtc->irq_periodic, &op->dev);
+out_dispose2:
+	irq_dispose_mapping(rtc->irq_periodic);
+	free_irq(rtc->irq, &op->dev);
+out_dispose:
+	irq_dispose_mapping(rtc->irq);
+	iounmap(rtc->regs);
+out_free:
+	kfree(rtc);
+
+	return err;
+}
+
+static int __devexit mpc5121_rtc_remove(struct of_device *op)
+{
+	struct mpc5121_rtc_data *rtc = dev_get_drvdata(&op->dev);
+	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+
+	/* disable interrupt, so there are no nasty surprises */
+	out_8(&regs->alm_enable, 0);
+	out_8(&regs->int_enable, in_8(&regs->int_enable) & ~0x1);
+
+	rtc_device_unregister(rtc->rtc);
+	iounmap(rtc->regs);
+	free_irq(rtc->irq, &op->dev);
+	free_irq(rtc->irq_periodic, &op->dev);
+	irq_dispose_mapping(rtc->irq);
+	irq_dispose_mapping(rtc->irq_periodic);
+	dev_set_drvdata(&op->dev, NULL);
+	kfree(rtc);
+
+	return 0;
+}
+
+static struct of_device_id mpc5121_rtc_match[] __devinitdata = {
+	{ .compatible = "fsl,mpc5121-rtc", },
+	{},
+};
+
+static struct of_platform_driver mpc5121_rtc_driver = {
+	.owner = THIS_MODULE,
+	.name = "mpc5121-rtc",
+	.match_table = mpc5121_rtc_match,
+	.probe = mpc5121_rtc_probe,
+	.remove = __devexit_p(mpc5121_rtc_remove),
+};
+
+static int __init mpc5121_rtc_init(void)
+{
+	return of_register_platform_driver(&mpc5121_rtc_driver);
+}
+module_init(mpc5121_rtc_init);
+
+static void __exit mpc5121_rtc_exit(void)
+{
+	of_unregister_platform_driver(&mpc5121_rtc_driver);
+}
+module_exit(mpc5121_rtc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Rigby <jcrigby@gmail.com>");
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-msm6242.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-msm6242.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-msm6242.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-msm6242.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 
 
 enum {
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-mv.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-mv.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-mv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-mv.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 
 #define RTC_TIME_REG_OFFS	0
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-mxc.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-mxc.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-mxc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-mxc.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/io.h>
 #include <linux/rtc.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
@@ -383,21 +384,29 @@ static int __init mxc_rtc_probe(struct p
 	struct rtc_device *rtc;
 	struct rtc_plat_data *pdata = NULL;
 	u32 reg;
-	int ret, rate;
+	unsigned long rate;
+	int ret;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
 		return -ENODEV;
 
-	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
 		return -ENOMEM;
 
-	pdata->ioaddr = ioremap(res->start, resource_size(res));
+	if (!devm_request_mem_region(&pdev->dev, res->start,
+				     resource_size(res), pdev->name))
+		return -EBUSY;
+
+	pdata->ioaddr = devm_ioremap(&pdev->dev, res->start,
+				     resource_size(res));
 
 	clk = clk_get(&pdev->dev, "ckil");
-	if (IS_ERR(clk))
-		return PTR_ERR(clk);
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		goto exit_free_pdata;
+	}
 
 	rate = clk_get_rate(clk);
 	clk_put(clk);
@@ -409,8 +418,7 @@ static int __init mxc_rtc_probe(struct p
 	else if (rate == 38400)
 		reg = RTC_INPUT_CLK_38400HZ;
 	else {
-		dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n",
-			clk_get_rate(clk));
+		dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate);
 		ret = -EINVAL;
 		goto exit_free_pdata;
 	}
@@ -446,8 +454,8 @@ static int __init mxc_rtc_probe(struct p
 	pdata->irq = platform_get_irq(pdev, 0);
 
 	if (pdata->irq >= 0 &&
-	    request_irq(pdata->irq, mxc_rtc_interrupt, IRQF_SHARED,
-			pdev->name, pdev) < 0) {
+	    devm_request_irq(&pdev->dev, pdata->irq, mxc_rtc_interrupt,
+			     IRQF_SHARED, pdev->name, pdev) < 0) {
 		dev_warn(&pdev->dev, "interrupt not available.\n");
 		pdata->irq = -1;
 	}
@@ -455,10 +463,10 @@ static int __init mxc_rtc_probe(struct p
 	return 0;
 
 exit_put_clk:
+	clk_disable(pdata->clk);
 	clk_put(pdata->clk);
 
 exit_free_pdata:
-	kfree(pdata);
 
 	return ret;
 }
@@ -469,12 +477,8 @@ static int __exit mxc_rtc_remove(struct
 
 	rtc_device_unregister(pdata->rtc);
 
-	if (pdata->irq >= 0)
-		free_irq(pdata->irq, pdev);
-
 	clk_disable(pdata->clk);
 	clk_put(pdata->clk);
-	kfree(pdata);
 	platform_set_drvdata(pdev, NULL);
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-nuc900.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-nuc900.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-nuc900.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-nuc900.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/rtc.h>
 #include <linux/delay.h>
 #include <linux/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pcap.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-pcap.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pcap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-pcap.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/mfd/ezx-pcap.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 
 struct pcap_rtc {
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pcf2123.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-pcf2123.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pcf2123.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-pcf2123.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/rtc.h>
 #include <linux/spi/spi.h>
 
@@ -315,7 +316,7 @@ kfree_exit:
 	return ret;
 }
 
-static int pcf2123_remove(struct spi_device *spi)
+static int __devexit pcf2123_remove(struct spi_device *spi)
 {
 	struct pcf2123_plat_data *pdata = spi->dev.platform_data;
 	int i;
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pcf50633.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-pcf50633.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pcf50633.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-pcf50633.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pcf8563.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-pcf8563.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pcf8563.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-pcf8563.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/i2c.h>
 #include <linux/bcd.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 
 #define DRV_VERSION "0.4.3"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pl030.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-pl030.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pl030.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-pl030.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/amba/bus.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #define RTC_DR		(0)
 #define RTC_MR		(4)
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pl031.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-pl031.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pl031.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-pl031.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,9 @@
  *
  * Copyright 2006 (c) MontaVista Software, Inc.
  *
+ * Author: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
+ * Copyright 2010 (c) ST-Ericsson AB
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
@@ -18,6 +21,10 @@
 #include <linux/interrupt.h>
 #include <linux/amba/bus.h>
 #include <linux/io.h>
+#include <linux/bcd.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+#include <linux/slab.h>
 
 /*
  * Register definitions
@@ -30,35 +37,207 @@
 #define	RTC_RIS		0x14	/* Raw interrupt status register */
 #define	RTC_MIS		0x18	/* Masked interrupt status register */
 #define	RTC_ICR		0x1c	/* Interrupt clear register */
+/* ST variants have additional timer functionality */
+#define RTC_TDR		0x20	/* Timer data read register */
+#define RTC_TLR		0x24	/* Timer data load register */
+#define RTC_TCR		0x28	/* Timer control register */
+#define RTC_YDR		0x30	/* Year data read register */
+#define RTC_YMR		0x34	/* Year match register */
+#define RTC_YLR		0x38	/* Year data load register */
+
+#define RTC_CR_CWEN	(1 << 26)	/* Clockwatch enable bit */
+
+#define RTC_TCR_EN	(1 << 1) /* Periodic timer enable bit */
+
+/* Common bit definitions for Interrupt status and control registers */
+#define RTC_BIT_AI	(1 << 0) /* Alarm interrupt bit */
+#define RTC_BIT_PI	(1 << 1) /* Periodic interrupt bit. ST variants only. */
+
+/* Common bit definations for ST v2 for reading/writing time */
+#define RTC_SEC_SHIFT 0
+#define RTC_SEC_MASK (0x3F << RTC_SEC_SHIFT) /* Second [0-59] */
+#define RTC_MIN_SHIFT 6
+#define RTC_MIN_MASK (0x3F << RTC_MIN_SHIFT) /* Minute [0-59] */
+#define RTC_HOUR_SHIFT 12
+#define RTC_HOUR_MASK (0x1F << RTC_HOUR_SHIFT) /* Hour [0-23] */
+#define RTC_WDAY_SHIFT 17
+#define RTC_WDAY_MASK (0x7 << RTC_WDAY_SHIFT) /* Day of Week [1-7] 1=Sunday */
+#define RTC_MDAY_SHIFT 20
+#define RTC_MDAY_MASK (0x1F << RTC_MDAY_SHIFT) /* Day of Month [1-31] */
+#define RTC_MON_SHIFT 25
+#define RTC_MON_MASK (0xF << RTC_MON_SHIFT) /* Month [1-12] 1=January */
+
+#define RTC_TIMER_FREQ 32768
 
 struct pl031_local {
 	struct rtc_device *rtc;
 	void __iomem *base;
+	u8 hw_designer;
+	u8 hw_revision:4;
 };
 
-static irqreturn_t pl031_interrupt(int irq, void *dev_id)
+static int pl031_alarm_irq_enable(struct device *dev,
+	unsigned int enabled)
 {
-	struct rtc_device *rtc = dev_id;
+	struct pl031_local *ldata = dev_get_drvdata(dev);
+	unsigned long imsc;
 
-	rtc_update_irq(rtc, 1, RTC_AF);
+	/* Clear any pending alarm interrupts. */
+	writel(RTC_BIT_AI, ldata->base + RTC_ICR);
 
-	return IRQ_HANDLED;
+	imsc = readl(ldata->base + RTC_IMSC);
+
+	if (enabled == 1)
+		writel(imsc | RTC_BIT_AI, ldata->base + RTC_IMSC);
+	else
+		writel(imsc & ~RTC_BIT_AI, ldata->base + RTC_IMSC);
+
+	return 0;
 }
 
-static int pl031_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+/*
+ * Convert Gregorian date to ST v2 RTC format.
+ */
+static int pl031_stv2_tm_to_time(struct device *dev,
+				 struct rtc_time *tm, unsigned long *st_time,
+	unsigned long *bcd_year)
+{
+	int year = tm->tm_year + 1900;
+	int wday = tm->tm_wday;
+
+	/* wday masking is not working in hardware so wday must be valid */
+	if (wday < -1 || wday > 6) {
+		dev_err(dev, "invalid wday value %d\n", tm->tm_wday);
+		return -EINVAL;
+	} else if (wday == -1) {
+		/* wday is not provided, calculate it here */
+		unsigned long time;
+		struct rtc_time calc_tm;
+
+		rtc_tm_to_time(tm, &time);
+		rtc_time_to_tm(time, &calc_tm);
+		wday = calc_tm.tm_wday;
+	}
+
+	*bcd_year = (bin2bcd(year % 100) | bin2bcd(year / 100) << 8);
+
+	*st_time = ((tm->tm_mon + 1) << RTC_MON_SHIFT)
+			|	(tm->tm_mday << RTC_MDAY_SHIFT)
+			|	((wday + 1) << RTC_WDAY_SHIFT)
+			|	(tm->tm_hour << RTC_HOUR_SHIFT)
+			|	(tm->tm_min << RTC_MIN_SHIFT)
+			|	(tm->tm_sec << RTC_SEC_SHIFT);
+
+	return 0;
+}
+
+/*
+ * Convert ST v2 RTC format to Gregorian date.
+ */
+static int pl031_stv2_time_to_tm(unsigned long st_time, unsigned long bcd_year,
+	struct rtc_time *tm)
+{
+	tm->tm_year = bcd2bin(bcd_year) + (bcd2bin(bcd_year >> 8) * 100);
+	tm->tm_mon  = ((st_time & RTC_MON_MASK) >> RTC_MON_SHIFT) - 1;
+	tm->tm_mday = ((st_time & RTC_MDAY_MASK) >> RTC_MDAY_SHIFT);
+	tm->tm_wday = ((st_time & RTC_WDAY_MASK) >> RTC_WDAY_SHIFT) - 1;
+	tm->tm_hour = ((st_time & RTC_HOUR_MASK) >> RTC_HOUR_SHIFT);
+	tm->tm_min  = ((st_time & RTC_MIN_MASK) >> RTC_MIN_SHIFT);
+	tm->tm_sec  = ((st_time & RTC_SEC_MASK) >> RTC_SEC_SHIFT);
+
+	tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
+	tm->tm_year -= 1900;
+
+	return 0;
+}
+
+static int pl031_stv2_read_time(struct device *dev, struct rtc_time *tm)
 {
 	struct pl031_local *ldata = dev_get_drvdata(dev);
 
-	switch (cmd) {
-	case RTC_AIE_OFF:
-		writel(1, ldata->base + RTC_MIS);
-		return 0;
-	case RTC_AIE_ON:
-		writel(0, ldata->base + RTC_MIS);
-		return 0;
+	pl031_stv2_time_to_tm(readl(ldata->base + RTC_DR),
+			readl(ldata->base + RTC_YDR), tm);
+
+	return 0;
+}
+
+static int pl031_stv2_set_time(struct device *dev, struct rtc_time *tm)
+{
+	unsigned long time;
+	unsigned long bcd_year;
+	struct pl031_local *ldata = dev_get_drvdata(dev);
+	int ret;
+
+	ret = pl031_stv2_tm_to_time(dev, tm, &time, &bcd_year);
+	if (ret == 0) {
+		writel(bcd_year, ldata->base + RTC_YLR);
+		writel(time, ldata->base + RTC_LR);
 	}
 
-	return -ENOIOCTLCMD;
+	return ret;
+}
+
+static int pl031_stv2_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct pl031_local *ldata = dev_get_drvdata(dev);
+	int ret;
+
+	ret = pl031_stv2_time_to_tm(readl(ldata->base + RTC_MR),
+			readl(ldata->base + RTC_YMR), &alarm->time);
+
+	alarm->pending = readl(ldata->base + RTC_RIS) & RTC_BIT_AI;
+	alarm->enabled = readl(ldata->base + RTC_IMSC) & RTC_BIT_AI;
+
+	return ret;
+}
+
+static int pl031_stv2_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct pl031_local *ldata = dev_get_drvdata(dev);
+	unsigned long time;
+	unsigned long bcd_year;
+	int ret;
+
+	/* At the moment, we can only deal with non-wildcarded alarm times. */
+	ret = rtc_valid_tm(&alarm->time);
+	if (ret == 0) {
+		ret = pl031_stv2_tm_to_time(dev, &alarm->time,
+					    &time, &bcd_year);
+		if (ret == 0) {
+			writel(bcd_year, ldata->base + RTC_YMR);
+			writel(time, ldata->base + RTC_MR);
+
+			pl031_alarm_irq_enable(dev, alarm->enabled);
+		}
+	}
+
+	return ret;
+}
+
+static irqreturn_t pl031_interrupt(int irq, void *dev_id)
+{
+	struct pl031_local *ldata = dev_id;
+	unsigned long rtcmis;
+	unsigned long events = 0;
+
+	rtcmis = readl(ldata->base + RTC_MIS);
+	if (rtcmis) {
+		writel(rtcmis, ldata->base + RTC_ICR);
+
+		if (rtcmis & RTC_BIT_AI)
+			events |= (RTC_AF | RTC_IRQF);
+
+		/* Timer interrupt is only available in ST variants */
+		if ((rtcmis & RTC_BIT_PI) &&
+			(ldata->hw_designer == AMBA_VENDOR_ST))
+			events |= (RTC_PF | RTC_IRQF);
+
+		rtc_update_irq(ldata->rtc, 1, events);
+
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
 }
 
 static int pl031_read_time(struct device *dev, struct rtc_time *tm)
@@ -74,11 +253,14 @@ static int pl031_set_time(struct device
 {
 	unsigned long time;
 	struct pl031_local *ldata = dev_get_drvdata(dev);
+	int ret;
 
-	rtc_tm_to_time(tm, &time);
-	writel(time, ldata->base + RTC_LR);
+	ret = rtc_tm_to_time(tm, &time);
 
-	return 0;
+	if (ret == 0)
+		writel(time, ldata->base + RTC_LR);
+
+	return ret;
 }
 
 static int pl031_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
@@ -86,8 +268,9 @@ static int pl031_read_alarm(struct devic
 	struct pl031_local *ldata = dev_get_drvdata(dev);
 
 	rtc_time_to_tm(readl(ldata->base + RTC_MR), &alarm->time);
-	alarm->pending = readl(ldata->base + RTC_RIS);
-	alarm->enabled = readl(ldata->base + RTC_IMSC);
+
+	alarm->pending = readl(ldata->base + RTC_RIS) & RTC_BIT_AI;
+	alarm->enabled = readl(ldata->base + RTC_IMSC) & RTC_BIT_AI;
 
 	return 0;
 }
@@ -96,22 +279,71 @@ static int pl031_set_alarm(struct device
 {
 	struct pl031_local *ldata = dev_get_drvdata(dev);
 	unsigned long time;
+	int ret;
 
-	rtc_tm_to_time(&alarm->time, &time);
+	/* At the moment, we can only deal with non-wildcarded alarm times. */
+	ret = rtc_valid_tm(&alarm->time);
+	if (ret == 0) {
+		ret = rtc_tm_to_time(&alarm->time, &time);
+		if (ret == 0) {
+			writel(time, ldata->base + RTC_MR);
+			pl031_alarm_irq_enable(dev, alarm->enabled);
+		}
+	}
 
-	writel(time, ldata->base + RTC_MR);
-	writel(!alarm->enabled, ldata->base + RTC_MIS);
+	return ret;
+}
+
+/* Periodic interrupt is only available in ST variants. */
+static int pl031_irq_set_state(struct device *dev, int enabled)
+{
+	struct pl031_local *ldata = dev_get_drvdata(dev);
+
+	if (enabled == 1) {
+		/* Clear any pending timer interrupt. */
+		writel(RTC_BIT_PI, ldata->base + RTC_ICR);
+
+		writel(readl(ldata->base + RTC_IMSC) | RTC_BIT_PI,
+			ldata->base + RTC_IMSC);
+
+		/* Now start the timer */
+		writel(readl(ldata->base + RTC_TCR) | RTC_TCR_EN,
+			ldata->base + RTC_TCR);
+
+	} else {
+		writel(readl(ldata->base + RTC_IMSC) & (~RTC_BIT_PI),
+			ldata->base + RTC_IMSC);
+
+		/* Also stop the timer */
+		writel(readl(ldata->base + RTC_TCR) & (~RTC_TCR_EN),
+			ldata->base + RTC_TCR);
+	}
+	/* Wait at least 1 RTC32 clock cycle to ensure next access
+	 * to RTC_TCR will succeed.
+	 */
+	udelay(40);
 
 	return 0;
 }
 
-static const struct rtc_class_ops pl031_ops = {
-	.ioctl = pl031_ioctl,
-	.read_time = pl031_read_time,
-	.set_time = pl031_set_time,
-	.read_alarm = pl031_read_alarm,
-	.set_alarm = pl031_set_alarm,
-};
+static int pl031_irq_set_freq(struct device *dev, int freq)
+{
+	struct pl031_local *ldata = dev_get_drvdata(dev);
+
+	/* Cant set timer if it is already enabled */
+	if (readl(ldata->base + RTC_TCR) & RTC_TCR_EN) {
+		dev_err(dev, "can't change frequency while timer enabled\n");
+		return -EINVAL;
+	}
+
+	/* If self start bit in RTC_TCR is set timer will start here,
+	 * but we never set that bit. Instead we start the timer when
+	 * set_state is called with enabled == 1.
+	 */
+	writel(RTC_TIMER_FREQ / freq, ldata->base + RTC_TLR);
+
+	return 0;
+}
 
 static int pl031_remove(struct amba_device *adev)
 {
@@ -131,18 +363,20 @@ static int pl031_probe(struct amba_devic
 {
 	int ret;
 	struct pl031_local *ldata;
+	struct rtc_class_ops *ops = id->data;
 
 	ret = amba_request_regions(adev, NULL);
 	if (ret)
 		goto err_req;
 
-	ldata = kmalloc(sizeof(struct pl031_local), GFP_KERNEL);
+	ldata = kzalloc(sizeof(struct pl031_local), GFP_KERNEL);
 	if (!ldata) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
 	ldata->base = ioremap(adev->res.start, resource_size(&adev->res));
+
 	if (!ldata->base) {
 		ret = -ENOMEM;
 		goto out_no_remap;
@@ -150,24 +384,36 @@ static int pl031_probe(struct amba_devic
 
 	amba_set_drvdata(adev, ldata);
 
-	if (request_irq(adev->irq[0], pl031_interrupt, IRQF_DISABLED,
-			"rtc-pl031", ldata->rtc)) {
-		ret = -EIO;
-		goto out_no_irq;
-	}
+	ldata->hw_designer = amba_manf(adev);
+	ldata->hw_revision = amba_rev(adev);
 
-	ldata->rtc = rtc_device_register("pl031", &adev->dev, &pl031_ops,
-					 THIS_MODULE);
+	dev_dbg(&adev->dev, "designer ID = 0x%02x\n", ldata->hw_designer);
+	dev_dbg(&adev->dev, "revision = 0x%01x\n", ldata->hw_revision);
+
+	/* Enable the clockwatch on ST Variants */
+	if ((ldata->hw_designer == AMBA_VENDOR_ST) &&
+	    (ldata->hw_revision > 1))
+		writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN,
+		       ldata->base + RTC_CR);
+
+	ldata->rtc = rtc_device_register("pl031", &adev->dev, ops,
+					THIS_MODULE);
 	if (IS_ERR(ldata->rtc)) {
 		ret = PTR_ERR(ldata->rtc);
 		goto out_no_rtc;
 	}
 
+	if (request_irq(adev->irq[0], pl031_interrupt,
+			IRQF_DISABLED | IRQF_SHARED, "rtc-pl031", ldata)) {
+		ret = -EIO;
+		goto out_no_irq;
+	}
+
 	return 0;
 
-out_no_rtc:
-	free_irq(adev->irq[0], ldata->rtc);
 out_no_irq:
+	rtc_device_unregister(ldata->rtc);
+out_no_rtc:
 	iounmap(ldata->base);
 	amba_set_drvdata(adev, NULL);
 out_no_remap:
@@ -175,13 +421,57 @@ out_no_remap:
 out:
 	amba_release_regions(adev);
 err_req:
+
 	return ret;
 }
 
+/* Operations for the original ARM version */
+static struct rtc_class_ops arm_pl031_ops = {
+	.read_time = pl031_read_time,
+	.set_time = pl031_set_time,
+	.read_alarm = pl031_read_alarm,
+	.set_alarm = pl031_set_alarm,
+	.alarm_irq_enable = pl031_alarm_irq_enable,
+};
+
+/* The First ST derivative */
+static struct rtc_class_ops stv1_pl031_ops = {
+	.read_time = pl031_read_time,
+	.set_time = pl031_set_time,
+	.read_alarm = pl031_read_alarm,
+	.set_alarm = pl031_set_alarm,
+	.alarm_irq_enable = pl031_alarm_irq_enable,
+	.irq_set_state = pl031_irq_set_state,
+	.irq_set_freq = pl031_irq_set_freq,
+};
+
+/* And the second ST derivative */
+static struct rtc_class_ops stv2_pl031_ops = {
+	.read_time = pl031_stv2_read_time,
+	.set_time = pl031_stv2_set_time,
+	.read_alarm = pl031_stv2_read_alarm,
+	.set_alarm = pl031_stv2_set_alarm,
+	.alarm_irq_enable = pl031_alarm_irq_enable,
+	.irq_set_state = pl031_irq_set_state,
+	.irq_set_freq = pl031_irq_set_freq,
+};
+
 static struct amba_id pl031_ids[] __initdata = {
 	{
 		.id = 0x00041031,
 		.mask = 0x000fffff,
+		.data = &arm_pl031_ops,
+	},
+	/* ST Micro variants */
+	{
+		.id = 0x00180031,
+		.mask = 0x00ffffff,
+		.data = &stv1_pl031_ops,
+	},
+	{
+		.id = 0x00280031,
+		.mask = 0x00ffffff,
+		.data = &stv2_pl031_ops,
 	},
 	{0, 0},
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pxa.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-pxa.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pxa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-pxa.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-rp5c01.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-rp5c01.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-rp5c01.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-rp5c01.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 
 
 enum {
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-rs5c348.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-rs5c348.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-rs5c348.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-rs5c348.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/rtc.h>
 #include <linux/workqueue.h>
 #include <linux/spi/spi.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-rs5c372.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-rs5c372.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-rs5c372.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-rs5c372.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/i2c.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 
 #define DRV_VERSION "0.6"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-rx8025.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-rx8025.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-rx8025.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-rx8025.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/bcd.h>
 #include <linux/i2c.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-s3c.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-s3c.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-s3c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-s3c.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/bcd.h>
 #include <linux/clk.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-sh.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-sh.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-sh.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-sh.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/io.h>
 #include <linux/log2.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 #include <asm/rtc.h>
 
 #define DRV_NAME	"sh-rtc"
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-stk17ta8.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-stk17ta8.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-stk17ta8.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-stk17ta8.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/bcd.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-stmp3xxx.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-stmp3xxx.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-stmp3xxx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-stmp3xxx.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 
 #include <mach/platform.h>
 #include <mach/stmp3xxx.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-sysfs.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -107,8 +107,9 @@ rtc_sysfs_show_hctosys(struct device *de
 		char *buf)
 {
 #ifdef CONFIG_RTC_HCTOSYS_DEVICE
-	if (strcmp(dev_name(&to_rtc_device(dev)->dev),
-		   CONFIG_RTC_HCTOSYS_DEVICE) == 0)
+	if (rtc_hctosys_ret == 0 &&
+			strcmp(dev_name(&to_rtc_device(dev)->dev),
+				CONFIG_RTC_HCTOSYS_DEVICE) == 0)
 		return sprintf(buf, "1\n");
 	else
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-twl.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-twl.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-twl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-twl.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,7 +57,7 @@ enum {
 	REG_RTC_COMP_LSB_REG,
 	REG_RTC_COMP_MSB_REG,
 };
-const static u8 twl4030_rtc_reg_map[] = {
+static const u8 twl4030_rtc_reg_map[] = {
 	[REG_SECONDS_REG] = 0x00,
 	[REG_MINUTES_REG] = 0x01,
 	[REG_HOURS_REG] = 0x02,
@@ -80,7 +80,7 @@ const static u8 twl4030_rtc_reg_map[] =
 	[REG_RTC_COMP_LSB_REG] = 0x10,
 	[REG_RTC_COMP_MSB_REG] = 0x11,
 };
-const static u8 twl6030_rtc_reg_map[] = {
+static const u8 twl6030_rtc_reg_map[] = {
 	[REG_SECONDS_REG] = 0x00,
 	[REG_MINUTES_REG] = 0x01,
 	[REG_HOURS_REG] = 0x02,
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-tx4939.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-tx4939.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-tx4939.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-tx4939.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 #include <asm/txx9/tx4939.h>
 
 struct tx4939rtc_plat_data {
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-v3020.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-v3020.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-v3020.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-v3020.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/rtc-v3020.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <linux/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-wm831x.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-wm831x.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-wm831x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-wm831x.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/time.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 #include <linux/bcd.h>
 #include <linux/interrupt.h>
 #include <linux/ioctl.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/rtc/rtc-wm8350.c linux-libre-2.6.34-gnu1/drivers/rtc/rtc-wm8350.c
--- linux-libre-2.6.33-gnu1/drivers/rtc/rtc-wm8350.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/rtc/rtc-wm8350.c	2010-05-16 17:17:36.000000000 -0400
@@ -307,11 +307,18 @@ static int wm8350_rtc_update_irq_enable(
 {
 	struct wm8350 *wm8350 = dev_get_drvdata(dev);
 
+	/* Suppress duplicate changes since genirq nests enable and
+	 * disable calls. */
+	if (enabled == wm8350->rtc.update_enabled)
+		return 0;
+
 	if (enabled)
 		wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC);
 	else
 		wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
 
+	wm8350->rtc.update_enabled = enabled;
+
 	return 0;
 }
 
@@ -478,8 +485,8 @@ static int __devexit wm8350_rtc_remove(s
 	struct wm8350 *wm8350 = platform_get_drvdata(pdev);
 	struct wm8350_rtc *wm_rtc = &wm8350->rtc;
 
-	wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC);
-	wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM);
+	wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350);
+	wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM, wm8350);
 
 	rtc_device_unregister(wm_rtc->rtc);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_3990_erp.c linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_3990_erp.c
--- linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_3990_erp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_3990_erp.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
 #define KMSG_COMPONENT "dasd-eckd"
 
 #include <linux/timer.h>
-#include <linux/slab.h>
 #include <asm/idals.h>
 
 #define PRINTK_HEADER "dasd_erp(3990): "
@@ -1045,6 +1044,10 @@ dasd_3990_erp_com_rej(struct dasd_ccw_re
 
 		erp->retries = 5;
 
+	} else if (sense[1] & SNS1_WRITE_INHIBITED) {
+		dev_err(&device->cdev->dev, "An I/O request was rejected"
+			" because writing is inhibited\n");
+		erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
 	} else {
 		/* fatal error -  set status to FAILED
 		   internal error 09 - Command Reject */
@@ -2283,7 +2286,8 @@ static struct dasd_ccw_req *dasd_3990_er
 
 	if (cqr->cpmode == 1) {
 		cplength = 0;
-		datasize = sizeof(struct tcw) + sizeof(struct tsb);
+		/* TCW needs to be 64 byte aligned, so leave enough room */
+		datasize = 64 + sizeof(struct tcw) + sizeof(struct tsb);
 	} else {
 		cplength = 2;
 		datasize = 0;
@@ -2305,15 +2309,15 @@ static struct dasd_ccw_req *dasd_3990_er
                                      cqr->retries);
 			dasd_block_set_timer(device->block, (HZ << 3));
                 }
-		return cqr;
+		return erp;
 	}
 
 	ccw = 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;
+		erp->cpaddr = PTR_ALIGN(erp->data, 64);
+		tcw = erp->cpaddr;
 		tsb = (struct tsb *) &tcw[1];
 		*tcw = *((struct tcw *)cqr->cpaddr);
 		tcw->tsb = (long)tsb;
@@ -2368,6 +2372,9 @@ dasd_3990_erp_additional_erp(struct dasd
 	/* add erp and initialize with default TIC */
 	erp = dasd_3990_erp_add_erp(cqr);
 
+	if (IS_ERR(erp))
+		return erp;
+
 	/* inspect sense, determine specific ERP if possible */
 	if (erp != cqr) {
 
@@ -2707,6 +2714,8 @@ dasd_3990_erp_action(struct dasd_ccw_req
 	if (erp == NULL) {
 		/* no matching erp found - set up erp */
 		erp = dasd_3990_erp_additional_erp(cqr);
+		if (IS_ERR(erp))
+			return erp;
 	} else {
 		/* matching erp found - set all leading erp's to DONE */
 		erp = dasd_3990_erp_handle_match_erp(cqr, erp);
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_alias.c linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_alias.c
--- linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_alias.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_alias.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 #define KMSG_COMPONENT "dasd-eckd"
 
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <asm/ebcdic.h>
 #include "dasd_int.h"
 #include "dasd_eckd.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/block/dasd.c linux-libre-2.6.34-gnu1/drivers/s390/block/dasd.c
--- linux-libre-2.6.33-gnu1/drivers/s390/block/dasd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/block/dasd.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,11 +20,13 @@
 #include <linux/buffer_head.h>
 #include <linux/hdreg.h>
 #include <linux/async.h>
+#include <linux/mutex.h>
 
 #include <asm/ccwdev.h>
 #include <asm/ebcdic.h>
 #include <asm/idals.h>
 #include <asm/itcw.h>
+#include <asm/diag.h>
 
 /* This is ugly... */
 #define PRINTK_HEADER "dasd:"
@@ -35,6 +37,9 @@
  */
 #define DASD_CHANQ_MAX_SIZE 4
 
+#define DASD_SLEEPON_START_TAG	(void *) 1
+#define DASD_SLEEPON_END_TAG	(void *) 2
+
 /*
  * SECTION: exported variables of dasd.c
  */
@@ -112,6 +117,7 @@ struct dasd_device *dasd_alloc_device(vo
 	INIT_WORK(&device->restore_device, do_restore_device);
 	device->state = DASD_STATE_NEW;
 	device->target = DASD_STATE_NEW;
+	mutex_init(&device->state_mutex);
 
 	return device;
 }
@@ -321,8 +327,8 @@ static int dasd_state_ready_to_basic(str
 			device->state = DASD_STATE_READY;
 			return rc;
 		}
-		dasd_destroy_partitions(block);
 		dasd_flush_request_queue(block);
+		dasd_destroy_partitions(block);
 		block->blocks = 0;
 		block->bp_block = 0;
 		block->s2b_shift = 0;
@@ -484,10 +490,8 @@ static void dasd_change_state(struct das
 	if (rc)
 		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);
@@ -502,7 +506,9 @@ static void dasd_change_state(struct das
 static void do_kick_device(struct work_struct *work)
 {
 	struct dasd_device *device = container_of(work, struct dasd_device, kick_work);
+	mutex_lock(&device->state_mutex);
 	dasd_change_state(device);
+	mutex_unlock(&device->state_mutex);
 	dasd_schedule_device_bh(device);
 	dasd_put_device(device);
 }
@@ -539,18 +545,19 @@ void dasd_restore_device(struct dasd_dev
 void dasd_set_target_state(struct dasd_device *device, int target)
 {
 	dasd_get_device(device);
+	mutex_lock(&device->state_mutex);
 	/* 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)
 		dasd_change_state(device);
+	mutex_unlock(&device->state_mutex);
+	dasd_put_device(device);
 }
 
 /*
@@ -1000,12 +1007,20 @@ static void dasd_handle_killed_request(s
 		return;
 	}
 
-	device = (struct dasd_device *) cqr->startdev;
-	if (device == NULL ||
-	    device != dasd_device_from_cdev_locked(cdev) ||
-	    strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
+	device = dasd_device_from_cdev_locked(cdev);
+	if (IS_ERR(device)) {
+		DBF_EVENT_DEVID(DBF_DEBUG, cdev, "%s",
+				"unable to get device from cdev");
+		return;
+	}
+
+	if (!cqr->startdev ||
+	    device != cqr->startdev ||
+	    strncmp(cqr->startdev->discipline->ebcname,
+		    (char *) &cqr->magic, 4)) {
 		DBF_EVENT_DEVID(DBF_DEBUG, cdev, "%s",
 				"invalid device in request");
+		dasd_put_device(device);
 		return;
 	}
 
@@ -1460,7 +1475,10 @@ void dasd_add_request_tail(struct dasd_c
  */
 static void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data)
 {
-	wake_up((wait_queue_head_t *) data);
+	spin_lock_irq(get_ccwdev_lock(cqr->startdev->cdev));
+	cqr->callback_data = DASD_SLEEPON_END_TAG;
+	spin_unlock_irq(get_ccwdev_lock(cqr->startdev->cdev));
+	wake_up(&generic_waitq);
 }
 
 static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr)
@@ -1470,10 +1488,7 @@ static inline int _wait_for_wakeup(struc
 
 	device = cqr->startdev;
 	spin_lock_irq(get_ccwdev_lock(device->cdev));
-	rc = ((cqr->status == DASD_CQR_DONE ||
-	       cqr->status == DASD_CQR_NEED_ERP ||
-	       cqr->status == DASD_CQR_TERMINATED) &&
-	      list_empty(&cqr->devlist));
+	rc = (cqr->callback_data == DASD_SLEEPON_END_TAG);
 	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 	return rc;
 }
@@ -1561,7 +1576,7 @@ static int _dasd_sleep_on(struct dasd_cc
 			wait_event(generic_waitq, !(device->stopped));
 
 		cqr->callback = dasd_wakeup_cb;
-		cqr->callback_data = (void *) &generic_waitq;
+		cqr->callback_data = DASD_SLEEPON_START_TAG;
 		dasd_add_request_tail(cqr);
 		if (interruptible) {
 			rc = wait_event_interruptible(
@@ -1640,7 +1655,7 @@ int dasd_sleep_on_immediatly(struct dasd
 	}
 
 	cqr->callback = dasd_wakeup_cb;
-	cqr->callback_data = (void *) &generic_waitq;
+	cqr->callback_data = DASD_SLEEPON_START_TAG;
 	cqr->status = DASD_CQR_QUEUED;
 	list_add(&cqr->devlist, &device->ccw_queue);
 
@@ -1692,7 +1707,6 @@ int dasd_cancel_req(struct dasd_ccw_req
 				cqr, rc);
 		} else {
 			cqr->stopclk = get_clock();
-			rc = 1;
 		}
 		break;
 	default: /* already finished or clear pending - do nothing */
@@ -1888,7 +1902,8 @@ restart:
 		/*  Process requests that may be recovered */
 		if (cqr->status == DASD_CQR_NEED_ERP) {
 			erp_fn = base->discipline->erp_action(cqr);
-			erp_fn(cqr);
+			if (IS_ERR(erp_fn(cqr)))
+				continue;
 			goto restart;
 		}
 
@@ -2129,9 +2144,8 @@ static void dasd_setup_queue(struct dasd
 
 	blk_queue_logical_block_size(block->request_queue, block->bp_block);
 	max = block->base->discipline->max_blocks << block->s2b_shift;
-	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_hw_sectors(block->request_queue, max);
+	blk_queue_max_segments(block->request_queue, -1L);
 	/* with page sized segments we can translate each segement into
 	 * one idaw/tidaw
 	 */
@@ -2170,9 +2184,13 @@ static void dasd_flush_request_queue(str
 static int dasd_open(struct block_device *bdev, fmode_t mode)
 {
 	struct dasd_block *block = bdev->bd_disk->private_data;
-	struct dasd_device *base = block->base;
+	struct dasd_device *base;
 	int rc;
 
+	if (!block)
+		return -ENODEV;
+
+	base = block->base;
 	atomic_inc(&block->open_count);
 	if (test_bit(DASD_FLAG_OFFLINE, &base->flags)) {
 		rc = -ENODEV;
@@ -2199,6 +2217,13 @@ static int dasd_open(struct block_device
 		goto out;
 	}
 
+	if ((mode & FMODE_WRITE) &&
+	    (test_bit(DASD_FLAG_DEVICE_RO, &base->flags) ||
+	     (base->features & DASD_FEATURE_READONLY))) {
+		rc = -EROFS;
+		goto out;
+	}
+
 	return 0;
 
 out:
@@ -2276,6 +2301,34 @@ dasd_exit(void)
  * SECTION: common functions for ccw_driver use
  */
 
+/*
+ * Is the device read-only?
+ * Note that this function does not report the setting of the
+ * readonly device attribute, but how it is configured in z/VM.
+ */
+int dasd_device_is_ro(struct dasd_device *device)
+{
+	struct ccw_dev_id dev_id;
+	struct diag210 diag_data;
+	int rc;
+
+	if (!MACHINE_IS_VM)
+		return 0;
+	ccw_device_get_id(device->cdev, &dev_id);
+	memset(&diag_data, 0, sizeof(diag_data));
+	diag_data.vrdcdvno = dev_id.devno;
+	diag_data.vrdclen = sizeof(diag_data);
+	rc = diag210(&diag_data);
+	if (rc == 0 || rc == 2) {
+		return diag_data.vrdcvfla & 0x80;
+	} else {
+		DBF_EVENT(DBF_WARNING, "diag210 failed for dev=%04x with rc=%d",
+			  dev_id.devno, rc);
+		return 0;
+	}
+}
+EXPORT_SYMBOL_GPL(dasd_device_is_ro);
+
 static void dasd_generic_auto_online(void *data, async_cookie_t cookie)
 {
 	struct ccw_device *cdev = data;
@@ -2285,11 +2338,6 @@ static void dasd_generic_auto_online(voi
 	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);
-	}
 }
 
 /*
@@ -2424,6 +2472,9 @@ int dasd_generic_set_online(struct ccw_d
 	} else
 		pr_debug("dasd_generic device %s found\n",
 				dev_name(&cdev->dev));
+
+	wait_event(dasd_init_waitq, _wait_for_device(device));
+
 	dasd_put_device(device);
 	return rc;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_devmap.c linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_devmap.c
--- linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_devmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_devmap.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <asm/debug.h>
 #include <asm/uaccess.h>
@@ -742,6 +743,7 @@ dasd_ro_store(struct device *dev, struct
 	      const char *buf, size_t count)
 {
 	struct dasd_devmap *devmap;
+	struct dasd_device *device;
 	int val;
 	char *endp;
 
@@ -758,12 +760,14 @@ dasd_ro_store(struct device *dev, struct
 		devmap->features |= DASD_FEATURE_READONLY;
 	else
 		devmap->features &= ~DASD_FEATURE_READONLY;
-	if (devmap->device)
-		devmap->device->features = devmap->features;
-	if (devmap->device && devmap->device->block
-	    && devmap->device->block->gdp)
-		set_disk_ro(devmap->device->block->gdp, val);
+	device = devmap->device;
+	if (device) {
+		device->features = devmap->features;
+		val = val || test_bit(DASD_FLAG_DEVICE_RO, &device->flags);
+	}
 	spin_unlock(&dasd_devmap_lock);
+	if (device && device->block && device->block->gdp)
+		set_disk_ro(device->block->gdp, val);
 	return count;
 }
 
@@ -874,12 +878,19 @@ dasd_discipline_show(struct device *dev,
 	ssize_t len;
 
 	device = dasd_device_from_cdev(to_ccwdev(dev));
-	if (!IS_ERR(device) && device->discipline) {
+	if (IS_ERR(device))
+		goto out;
+	else if (!device->discipline) {
+		dasd_put_device(device);
+		goto out;
+	} else {
 		len = snprintf(buf, PAGE_SIZE, "%s\n",
 			       device->discipline->name);
 		dasd_put_device(device);
-	} else
-		len = snprintf(buf, PAGE_SIZE, "none\n");
+		return len;
+	}
+out:
+	len = snprintf(buf, PAGE_SIZE, "none\n");
 	return len;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_diag.c linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_diag.c
--- linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_diag.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_diag.c	2010-05-16 17:17:36.000000000 -0400
@@ -145,12 +145,10 @@ dasd_diag_erp(struct dasd_device *device
 	mdsk_term_io(device);
 	rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
 	if (rc == 4) {
-		if (!(device->features & DASD_FEATURE_READONLY)) {
+		if (!(test_and_set_bit(DASD_FLAG_DEVICE_RO, &device->flags)))
 			pr_warning("%s: The access mode of a DIAG device "
 				   "changed to read-only\n",
 				   dev_name(&device->cdev->dev));
-			device->features |= DASD_FEATURE_READONLY;
-		}
 		rc = 0;
 	}
 	if (rc)
@@ -449,7 +447,7 @@ dasd_diag_check_device(struct dasd_devic
 		rc = -EIO;
 	} else {
 		if (rc == 4)
-			device->features |= DASD_FEATURE_READONLY;
+			set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
 		pr_info("%s: New DASD with %ld byte/block, total size %ld "
 			"KB%s\n", dev_name(&device->cdev->dev),
 			(unsigned long) block->bp_block,
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_eckd.c linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_eckd.c
--- linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_eckd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_eckd.c	2010-05-16 17:17:36.000000000 -0400
@@ -1089,6 +1089,7 @@ dasd_eckd_check_characteristics(struct d
 	struct dasd_eckd_private *private;
 	struct dasd_block *block;
 	int is_known, rc;
+	int readonly;
 
 	if (!ccw_device_is_pathgroup(device->cdev)) {
 		dev_warn(&device->cdev->dev,
@@ -1182,15 +1183,20 @@ dasd_eckd_check_characteristics(struct d
 	else
 		private->real_cyl = private->rdc_data.no_cyl;
 
+	readonly = dasd_device_is_ro(device);
+	if (readonly)
+		set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
+
 	dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) "
-		 "with %d cylinders, %d heads, %d sectors\n",
+		 "with %d cylinders, %d heads, %d sectors%s\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);
+		 private->rdc_data.sec_per_trk,
+		 readonly ? ", read-only device" : "");
 	return 0;
 
 out_err3:
@@ -2839,8 +2845,13 @@ static int dasd_symm_io(struct dasd_devi
 	char *psf_data, *rssd_result;
 	struct dasd_ccw_req *cqr;
 	struct ccw1 *ccw;
+	char psf0, psf1;
 	int rc;
 
+	if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
+		return -EACCES;
+	psf0 = psf1 = 0;
+
 	/* Copy parms from caller */
 	rc = -EFAULT;
 	if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
@@ -2869,12 +2880,8 @@ static int dasd_symm_io(struct dasd_devi
 			   (void __user *)(unsigned long) usrparm.psf_data,
 			   usrparm.psf_data_len))
 		goto out_free;
-
-	/* sanity check on syscall header */
-	if (psf_data[0] != 0x17 && psf_data[1] != 0xce) {
-		rc = -EINVAL;
-		goto out_free;
-	}
+	psf0 = psf_data[0];
+	psf1 = psf_data[1];
 
 	/* setup CCWs for PSF + RSSD */
 	cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 , 0, device);
@@ -2925,7 +2932,9 @@ out_free:
 	kfree(rssd_result);
 	kfree(psf_data);
 out:
-	DBF_DEV_EVENT(DBF_WARNING, device, "Symmetrix ioctl: rc=%d", rc);
+	DBF_DEV_EVENT(DBF_WARNING, device,
+		      "Symmetrix ioctl (0x%02x 0x%02x): rc=%d",
+		      (int) psf0, (int) psf1, rc);
 	return rc;
 }
 
@@ -3146,11 +3155,11 @@ static void dasd_eckd_dump_sense_tcw(str
 
 	tsb = NULL;
 	sense = NULL;
-	if (irb->scsw.tm.tcw)
+	if (irb->scsw.tm.tcw && (irb->scsw.tm.fcxs == 0x01))
 		tsb = tcw_get_tsb(
 			(struct tcw *)(unsigned long)irb->scsw.tm.tcw);
 
-	if (tsb && (irb->scsw.tm.fcxs == 0x01)) {
+	if (tsb) {
 		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
 			       " tsb->length %d\n", tsb->length);
 		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_eer.c linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_eer.c
--- linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_eer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_eer.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/mutex.h>
 #include <linux/smp_lock.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_fba.c linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_fba.c
--- linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_fba.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_fba.c	2010-05-16 17:17:36.000000000 -0400
@@ -124,6 +124,7 @@ dasd_fba_check_characteristics(struct da
 	struct dasd_fba_private *private;
 	struct ccw_device *cdev = device->cdev;
 	int rc;
+	int readonly;
 
 	private = (struct dasd_fba_private *) device->private;
 	if (!private) {
@@ -162,16 +163,21 @@ dasd_fba_check_characteristics(struct da
 		return rc;
 	}
 
+	readonly = dasd_device_is_ro(device);
+	if (readonly)
+		set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
+
 	dev_info(&device->cdev->dev,
 		 "New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB "
-		 "and %d B/blk\n",
+		 "and %d B/blk%s\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);
+		 private->rdc_data.blk_size,
+		 readonly ? ", read-only device" : "");
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_genhd.c linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_genhd.c
--- linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_genhd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_genhd.c	2010-05-16 17:17:36.000000000 -0400
@@ -70,7 +70,8 @@ int dasd_gendisk_alloc(struct dasd_block
 	}
 	len += sprintf(gdp->disk_name + len, "%c", 'a'+(base->devindex%26));
 
-	if (block->base->features & DASD_FEATURE_READONLY)
+	if (base->features & DASD_FEATURE_READONLY ||
+	    test_bit(DASD_FLAG_DEVICE_RO, &base->flags))
 		set_disk_ro(gdp, 1);
 	gdp->private_data = block;
 	gdp->queue = block->request_queue;
@@ -88,6 +89,7 @@ void dasd_gendisk_free(struct dasd_block
 	if (block->gdp) {
 		del_gendisk(block->gdp);
 		block->gdp->queue = NULL;
+		block->gdp->private_data = NULL;
 		put_disk(block->gdp);
 		block->gdp = NULL;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_int.h linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_int.h
--- linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_int.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_int.h	2010-05-16 17:17:36.000000000 -0400
@@ -368,6 +368,7 @@ struct dasd_device {
 
 	/* Device state and target state. */
 	int state, target;
+	struct mutex state_mutex;
 	int stopped;		/* device (ccw_device_start) was stopped */
 
 	/* reference count. */
@@ -435,6 +436,10 @@ struct dasd_block {
 #define DASD_FLAG_OFFLINE	3	/* device is in offline processing */
 #define DASD_FLAG_EER_SNSS	4	/* A SNSS is required */
 #define DASD_FLAG_EER_IN_USE	5	/* A SNSS request is running */
+#define DASD_FLAG_DEVICE_RO	6	/* The device itself is read-only. Don't
+					 * confuse this with the user specified
+					 * read-only feature.
+					 */
 
 void dasd_put_device_wake(struct dasd_device *);
 
@@ -608,6 +613,9 @@ char *dasd_get_sense(struct irb *);
 void dasd_device_set_stop_bits(struct dasd_device *, int);
 void dasd_device_remove_stop_bits(struct dasd_device *, int);
 
+int dasd_device_is_ro(struct dasd_device *);
+
+
 /* externals in dasd_devmap.c */
 extern int dasd_max_devindex;
 extern int dasd_probeonly;
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_ioctl.c linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_ioctl.c
--- linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/fs.h>
 #include <linux/blkpg.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <asm/compat.h>
 #include <asm/ccwdev.h>
 #include <asm/cmb.h>
@@ -199,7 +200,8 @@ dasd_ioctl_format(struct block_device *b
 	if (!argp)
 		return -EINVAL;
 
-	if (block->base->features & DASD_FEATURE_READONLY)
+	if (block->base->features & DASD_FEATURE_READONLY ||
+	    test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags))
 		return -EROFS;
 	if (copy_from_user(&fdata, argp, sizeof(struct format_data_t)))
 		return -EFAULT;
@@ -349,7 +351,8 @@ dasd_ioctl_set_ro(struct block_device *b
 		return -EINVAL;
 	if (get_user(intval, (int __user *)argp))
 		return -EFAULT;
-
+	if (!intval && test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags))
+		return -EROFS;
 	set_disk_ro(bdev->bd_disk, intval);
 	return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_proc.c linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_proc.c
--- linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/block/dasd_proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #define KMSG_COMPONENT "dasd"
 
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/seq_file.h>
 #include <linux/vmalloc.h>
@@ -165,51 +166,32 @@ static const struct file_operations dasd
 	.release	= seq_release,
 };
 
-static int
-dasd_calc_metrics(char *page, char **start, off_t off,
-		  int count, int *eof, int len)
-{
-	len = (len > off) ? len - off : 0;
-	if (len > count)
-		len = count;
-	if (len < count)
-		*eof = 1;
-	*start = page + off;
-	return len;
-}
-
 #ifdef CONFIG_DASD_PROFILE
-static char *
-dasd_statistics_array(char *str, unsigned int *array, int factor)
+static void dasd_statistics_array(struct seq_file *m, unsigned int *array, int factor)
 {
 	int i;
 
 	for (i = 0; i < 32; i++) {
-		str += sprintf(str, "%7d ", array[i] / factor);
+		seq_printf(m, "%7d ", array[i] / factor);
 		if (i == 15)
-			str += sprintf(str, "\n");
+			seq_putc(m, '\n');
 	}
-	str += sprintf(str,"\n");
-	return str;
+	seq_putc(m, '\n');
 }
 #endif /* CONFIG_DASD_PROFILE */
 
-static int
-dasd_statistics_read(char *page, char **start, off_t off,
-		     int count, int *eof, void *data)
+static int dasd_stats_proc_show(struct seq_file *m, void *v)
 {
-	unsigned long len;
 #ifdef CONFIG_DASD_PROFILE
 	struct dasd_profile_info_t *prof;
-	char *str;
 	int factor;
 
 	/* check for active profiling */
 	if (dasd_profile_level == DASD_PROFILE_OFF) {
-		len = sprintf(page, "Statistics are off - they might be "
+		seq_printf(m, "Statistics are off - they might be "
 				    "switched on using 'echo set on > "
 				    "/proc/dasd/statistics'\n");
-		return dasd_calc_metrics(page, start, off, count, eof, len);
+		return 0;
 	}
 
 	prof = &dasd_global_profile;
@@ -217,47 +199,49 @@ dasd_statistics_read(char *page, char **
 	for (factor = 1; (prof->dasd_io_reqs / factor) > 9999999;
 	     factor *= 10);
 
-	str = page;
-	str += sprintf(str, "%d dasd I/O requests\n", prof->dasd_io_reqs);
-	str += sprintf(str, "with %u sectors(512B each)\n",
+	seq_printf(m, "%d dasd I/O requests\n", prof->dasd_io_reqs);
+	seq_printf(m, "with %u sectors(512B each)\n",
 		       prof->dasd_io_sects);
-	str += sprintf(str, "Scale Factor is  %d\n", factor);
-	str += sprintf(str,
+	seq_printf(m, "Scale Factor is  %d\n", factor);
+	seq_printf(m,
 		       "   __<4	   ___8	   __16	   __32	   __64	   _128	"
 		       "   _256	   _512	   __1k	   __2k	   __4k	   __8k	"
 		       "   _16k	   _32k	   _64k	   128k\n");
-	str += sprintf(str,
+	seq_printf(m,
 		       "   _256	   _512	   __1M	   __2M	   __4M	   __8M	"
 		       "   _16M	   _32M	   _64M	   128M	   256M	   512M	"
 		       "   __1G	   __2G	   __4G " "   _>4G\n");
 
-	str += sprintf(str, "Histogram of sizes (512B secs)\n");
-	str = dasd_statistics_array(str, prof->dasd_io_secs, factor);
-	str += sprintf(str, "Histogram of I/O times (microseconds)\n");
-	str = dasd_statistics_array(str, prof->dasd_io_times, factor);
-	str += sprintf(str, "Histogram of I/O times per sector\n");
-	str = dasd_statistics_array(str, prof->dasd_io_timps, factor);
-	str += sprintf(str, "Histogram of I/O time till ssch\n");
-	str = dasd_statistics_array(str, prof->dasd_io_time1, factor);
-	str += sprintf(str, "Histogram of I/O time between ssch and irq\n");
-	str = dasd_statistics_array(str, prof->dasd_io_time2, factor);
-	str += sprintf(str, "Histogram of I/O time between ssch "
+	seq_printf(m, "Histogram of sizes (512B secs)\n");
+	dasd_statistics_array(m, prof->dasd_io_secs, factor);
+	seq_printf(m, "Histogram of I/O times (microseconds)\n");
+	dasd_statistics_array(m, prof->dasd_io_times, factor);
+	seq_printf(m, "Histogram of I/O times per sector\n");
+	dasd_statistics_array(m, prof->dasd_io_timps, factor);
+	seq_printf(m, "Histogram of I/O time till ssch\n");
+	dasd_statistics_array(m, prof->dasd_io_time1, factor);
+	seq_printf(m, "Histogram of I/O time between ssch and irq\n");
+	dasd_statistics_array(m, prof->dasd_io_time2, factor);
+	seq_printf(m, "Histogram of I/O time between ssch "
 			    "and irq per sector\n");
-	str = dasd_statistics_array(str, prof->dasd_io_time2ps, factor);
-	str += sprintf(str, "Histogram of I/O time between irq and end\n");
-	str = dasd_statistics_array(str, prof->dasd_io_time3, factor);
-	str += sprintf(str, "# of req in chanq at enqueuing (1..32) \n");
-	str = dasd_statistics_array(str, prof->dasd_io_nr_req, factor);
-	len = str - page;
+	dasd_statistics_array(m, prof->dasd_io_time2ps, factor);
+	seq_printf(m, "Histogram of I/O time between irq and end\n");
+	dasd_statistics_array(m, prof->dasd_io_time3, factor);
+	seq_printf(m, "# of req in chanq at enqueuing (1..32) \n");
+	dasd_statistics_array(m, prof->dasd_io_nr_req, factor);
 #else
-	len = sprintf(page, "Statistics are not activated in this kernel\n");
+	seq_printf(m, "Statistics are not activated in this kernel\n");
 #endif
-	return dasd_calc_metrics(page, start, off, count, eof, len);
+	return 0;
 }
 
-static int
-dasd_statistics_write(struct file *file, const char __user *user_buf,
-		      unsigned long user_len, void *data)
+static int dasd_stats_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, dasd_stats_proc_show, NULL);
+}
+
+static ssize_t dasd_stats_proc_write(struct file *file,
+		const char __user *user_buf, size_t user_len, loff_t *pos)
 {
 #ifdef CONFIG_DASD_PROFILE
 	char *buffer, *str;
@@ -308,6 +292,15 @@ out_error:
 #endif				/* CONFIG_DASD_PROFILE */
 }
 
+static const struct file_operations dasd_stats_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= dasd_stats_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= dasd_stats_proc_write,
+};
+
 /*
  * Create dasd proc-fs entries.
  * In case creation failed, cleanup and return -ENOENT.
@@ -324,13 +317,12 @@ dasd_proc_init(void)
 					 &dasd_devices_file_ops);
 	if (!dasd_devices_entry)
 		goto out_nodevices;
-	dasd_statistics_entry = create_proc_entry("statistics",
-						  S_IFREG | S_IRUGO | S_IWUSR,
-						  dasd_proc_root_entry);
+	dasd_statistics_entry = proc_create("statistics",
+					    S_IFREG | S_IRUGO | S_IWUSR,
+					    dasd_proc_root_entry,
+					    &dasd_stats_proc_fops);
 	if (!dasd_statistics_entry)
 		goto out_nostatistics;
-	dasd_statistics_entry->read_proc = dasd_statistics_read;
-	dasd_statistics_entry->write_proc = dasd_statistics_write;
 	return 0;
 
  out_nostatistics:
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/block/xpram.c linux-libre-2.6.34-gnu1/drivers/s390/block/xpram.c
--- linux-libre-2.6.33-gnu1/drivers/s390/block/xpram.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/block/xpram.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,6 @@
 #include <linux/ctype.h>  /* isdigit, isxdigit */
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/blkpg.h>
 #include <linux/hdreg.h>  /* HDIO_GETGEO */
@@ -41,6 +40,7 @@
 #include <linux/bio.h>
 #include <linux/suspend.h>
 #include <linux/platform_device.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 
 #define XPRAM_NAME	"xpram"
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/con3270.c linux-libre-2.6.34-gnu1/drivers/s390/char/con3270.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/con3270.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/con3270.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/reboot.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/fs3270.c linux-libre-2.6.34-gnu1/drivers/s390/char/fs3270.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/fs3270.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/fs3270.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/smp_lock.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/keyboard.c linux-libre-2.6.34-gnu1/drivers/s390/char/keyboard.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/keyboard.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/keyboard.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/sysrq.h>
 
 #include <linux/consolemap.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/monreader.c linux-libre-2.6.34-gnu1/drivers/s390/char/monreader.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/monreader.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/monreader.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/poll.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <net/iucv/iucv.h>
 #include <asm/uaccess.h>
 #include <asm/ebcdic.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/monwriter.c linux-libre-2.6.34-gnu1/drivers/s390/char/monwriter.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/monwriter.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/monwriter.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/poll.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/ebcdic.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/raw3270.c linux-libre-2.6.34-gnu1/drivers/s390/char/raw3270.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/raw3270.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/raw3270.c	2010-05-16 17:17:36.000000000 -0400
@@ -373,7 +373,7 @@ raw3270_irq (struct ccw_device *cdev, un
 		rq->rc = ccw_device_start(rp->cdev, &rq->ccw,
 					  (unsigned long) rq, 0, 0);
 		if (rq->rc == 0)
-			return;	/* Sucessfully restarted. */
+			return;	/* Successfully restarted. */
 		break;
 	case RAW3270_IO_STOP:
 		if (!rq)
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_async.c linux-libre-2.6.34-gnu1/drivers/s390/char/sclp_async.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_async.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/sclp_async.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/device.h>
 #include <linux/stat.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/kmod.h>
 #include <linux/err.h>
@@ -84,6 +85,7 @@ static int proc_handler_callhome(struct
 		rc = copy_from_user(buf, buffer, sizeof(buf));
 		if (rc != 0)
 			return -EFAULT;
+		buf[sizeof(buf) - 1] = '\0';
 		if (strict_strtoul(buf, 0, &val) != 0)
 			return -EINVAL;
 		if (val != 0 && val != 1)
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/sclp.c linux-libre-2.6.34-gnu1/drivers/s390/char/sclp.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/sclp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/sclp.c	2010-05-16 17:17:36.000000000 -0400
@@ -196,7 +196,7 @@ __sclp_start_request(struct sclp_req *re
 	req->start_count++;
 
 	if (rc == 0) {
-		/* Sucessfully started request */
+		/* Successfully started request */
 		req->status = SCLP_REQ_RUNNING;
 		sclp_running_state = sclp_running_state_running;
 		__sclp_set_request_timer(SCLP_RETRY_INTERVAL * HZ,
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_cmd.c linux-libre-2.6.34-gnu1/drivers/s390/char/sclp_cmd.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_cmd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/sclp_cmd.c	2010-05-16 17:17:36.000000000 -0400
@@ -308,6 +308,13 @@ struct assign_storage_sccb {
 	u16 rn;
 } __packed;
 
+int arch_get_memory_phys_device(unsigned long start_pfn)
+{
+	if (!rzm)
+		return 0;
+	return PFN_PHYS(start_pfn) >> ilog2(rzm);
+}
+
 static unsigned long long rn2addr(u16 rn)
 {
 	return (unsigned long long) (rn - 1) * rzm;
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_con.c linux-libre-2.6.34-gnu1/drivers/s390/char/sclp_con.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_con.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/sclp_con.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/termios.h>
 #include <linux/err.h>
 #include <linux/reboot.h>
+#include <linux/gfp.h>
 
 #include "sclp.h"
 #include "sclp_rw.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_tty.c linux-libre-2.6.34-gnu1/drivers/s390/char/sclp_tty.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_tty.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/sclp_tty.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,10 +13,10 @@
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
-#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 
 #include "ctrlchar.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_vt220.c linux-libre-2.6.34-gnu1/drivers/s390/char/sclp_vt220.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_vt220.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/sclp_vt220.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/reboot.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include "sclp.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/tape_34xx.c linux-libre-2.6.34-gnu1/drivers/s390/char/tape_34xx.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/tape_34xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/tape_34xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/bio.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 #define TAPE_DBF_AREA	tape_34xx_dbf
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/tape_3590.c linux-libre-2.6.34-gnu1/drivers/s390/char/tape_3590.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/tape_3590.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/tape_3590.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/bio.h>
 #include <asm/ebcdic.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/tape_block.c linux-libre-2.6.34-gnu1/drivers/s390/char/tape_block.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/tape_block.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/tape_block.c	2010-05-16 17:17:36.000000000 -0400
@@ -222,9 +222,8 @@ tapeblock_setup_device(struct tape_devic
 		goto cleanup_queue;
 
 	blk_queue_logical_block_size(blkdat->request_queue, TAPEBLOCK_HSEC_SIZE);
-	blk_queue_max_sectors(blkdat->request_queue, TAPEBLOCK_MAX_SEC);
-	blk_queue_max_phys_segments(blkdat->request_queue, -1L);
-	blk_queue_max_hw_segments(blkdat->request_queue, -1L);
+	blk_queue_max_hw_sectors(blkdat->request_queue, TAPEBLOCK_MAX_SEC);
+	blk_queue_max_segments(blkdat->request_queue, -1L);
 	blk_queue_max_segment_size(blkdat->request_queue, -1L);
 	blk_queue_segment_boundary(blkdat->request_queue, -1L);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/tape_class.c linux-libre-2.6.34-gnu1/drivers/s390/char/tape_class.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/tape_class.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/tape_class.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,8 @@
 #define KMSG_COMPONENT "tape"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/slab.h>
+
 #include "tape_class.h"
 
 MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>");
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/tape_core.c linux-libre-2.6.34-gnu1/drivers/s390/char/tape_core.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/tape_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/tape_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/spinlock.h>  // for locks
 #include <linux/vmalloc.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 
 #include <asm/types.h>	     // for variable types
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/vmcp.c linux-libre-2.6.34-gnu1/drivers/s390/char/vmcp.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/vmcp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/vmcp.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/compat.h>
 #include <asm/cpcmd.h>
 #include <asm/debug.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/vmlogrdr.c linux-libre-2.6.34-gnu1/drivers/s390/char/vmlogrdr.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/vmlogrdr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/vmlogrdr.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/vmur.c linux-libre-2.6.34-gnu1/drivers/s390/char/vmur.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/vmur.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/vmur.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/cdev.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/vmwatchdog.c linux-libre-2.6.34-gnu1/drivers/s390/char/vmwatchdog.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/vmwatchdog.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/vmwatchdog.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <linux/suspend.h>
 #include <linux/watchdog.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/char/zcore.c linux-libre-2.6.34-gnu1/drivers/s390/char/zcore.c
--- linux-libre-2.6.33-gnu1/drivers/s390/char/zcore.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/char/zcore.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,8 +13,10 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/miscdevice.h>
 #include <linux/debugfs.h>
+#include <asm/asm-offsets.h>
 #include <asm/ipl.h>
 #include <asm/sclp.h>
 #include <asm/setup.h>
@@ -40,12 +42,12 @@ enum arch_id {
 /* dump system info */
 
 struct sys_info {
-	enum arch_id	arch;
-	unsigned long	sa_base;
-	u32		sa_size;
-	int		cpu_map[NR_CPUS];
-	unsigned long	mem_size;
-	union save_area	lc_mask;
+	enum arch_id	 arch;
+	unsigned long	 sa_base;
+	u32		 sa_size;
+	int		 cpu_map[NR_CPUS];
+	unsigned long	 mem_size;
+	struct save_area lc_mask;
 };
 
 struct ipib_info {
@@ -140,33 +142,6 @@ static int memcpy_hsa_kernel(void *dest,
 	return memcpy_hsa(dest, src, count, TO_KERNEL);
 }
 
-static int memcpy_real(void *dest, unsigned long src, size_t count)
-{
-	unsigned long flags;
-	int rc = -EFAULT;
-	register unsigned long _dest asm("2") = (unsigned long) dest;
-	register unsigned long _len1 asm("3") = (unsigned long) count;
-	register unsigned long _src  asm("4") = src;
-	register unsigned long _len2 asm("5") = (unsigned long) count;
-
-	if (count == 0)
-		return 0;
-	flags = __raw_local_irq_stnsm(0xf8UL); /* switch to real mode */
-	asm volatile (
-		"0:	mvcle	%1,%2,0x0\n"
-		"1:	jo	0b\n"
-		"	lhi	%0,0x0\n"
-		"2:\n"
-		EX_TABLE(1b,2b)
-		: "+d" (rc), "+d" (_dest), "+d" (_src), "+d" (_len1),
-		  "+d" (_len2), "=m" (*((long*)dest))
-		: "m" (*((long*)src))
-		: "cc", "memory");
-	__raw_local_irq_ssm(flags);
-
-	return rc;
-}
-
 static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
 {
 	static char buf[4096];
@@ -174,7 +149,7 @@ static int memcpy_real_user(void __user
 
 	while (offs < count) {
 		size = min(sizeof(buf), count - offs);
-		if (memcpy_real(buf, src + offs, size))
+		if (memcpy_real(buf, (void *) src + offs, size))
 			return -EFAULT;
 		if (copy_to_user(dest + offs, buf, size))
 			return -EFAULT;
@@ -183,52 +158,9 @@ static int memcpy_real_user(void __user
 	return 0;
 }
 
-#ifdef __s390x__
-/*
- * Convert s390x (64 bit) cpu info to s390 (32 bit) cpu info
- */
-static void __init s390x_to_s390_regs(union save_area *out, union save_area *in,
-				      int cpu)
-{
-	int i;
-
-	for (i = 0; i < 16; i++) {
-		out->s390.gp_regs[i] = in->s390x.gp_regs[i] & 0x00000000ffffffff;
-		out->s390.acc_regs[i] = in->s390x.acc_regs[i];
-		out->s390.ctrl_regs[i] =
-			in->s390x.ctrl_regs[i] & 0x00000000ffffffff;
-	}
-	/* locore for 31 bit has only space for fpregs 0,2,4,6 */
-	out->s390.fp_regs[0] = in->s390x.fp_regs[0];
-	out->s390.fp_regs[1] = in->s390x.fp_regs[2];
-	out->s390.fp_regs[2] = in->s390x.fp_regs[4];
-	out->s390.fp_regs[3] = in->s390x.fp_regs[6];
-	memcpy(&(out->s390.psw[0]), &(in->s390x.psw[0]), 4);
-	out->s390.psw[1] |= 0x8; /* set bit 12 */
-	memcpy(&(out->s390.psw[4]),&(in->s390x.psw[12]), 4);
-	out->s390.psw[4] |= 0x80; /* set (31bit) addressing bit */
-	out->s390.pref_reg = in->s390x.pref_reg;
-	out->s390.timer = in->s390x.timer;
-	out->s390.clk_cmp = in->s390x.clk_cmp;
-}
-
-static void __init s390x_to_s390_save_areas(void)
-{
-	int i = 1;
-	static union save_area tmp;
-
-	while (zfcpdump_save_areas[i]) {
-		s390x_to_s390_regs(&tmp, zfcpdump_save_areas[i], i);
-		memcpy(zfcpdump_save_areas[i], &tmp, sizeof(tmp));
-		i++;
-	}
-}
-
-#endif /* __s390x__ */
-
 static int __init init_cpu_info(enum arch_id arch)
 {
-	union save_area *sa;
+	struct save_area *sa;
 
 	/* get info for boot cpu from lowcore, stored in the HSA */
 
@@ -241,20 +173,12 @@ static int __init init_cpu_info(enum arc
 		return -EIO;
 	}
 	zfcpdump_save_areas[0] = sa;
-
-#ifdef __s390x__
-	/* convert s390x regs to s390, if we are dumping an s390 Linux */
-
-	if (arch == ARCH_S390)
-		s390x_to_s390_save_areas();
-#endif
-
 	return 0;
 }
 
 static DEFINE_MUTEX(zcore_mutex);
 
-#define DUMP_VERSION	0x3
+#define DUMP_VERSION	0x5
 #define DUMP_MAGIC	0xa8190173618f23fdULL
 #define DUMP_ARCH_S390X	2
 #define DUMP_ARCH_S390	1
@@ -279,7 +203,14 @@ struct zcore_header {
 	u32 volnr;
 	u32 build_arch;
 	u64 rmem_size;
-	char pad2[4016];
+	u8 mvdump;
+	u16 cpu_cnt;
+	u16 real_cpu_cnt;
+	u8 end_pad1[0x200-0x061];
+	u64 mvdump_sign;
+	u64 mvdump_zipl_time;
+	u8 end_pad2[0x800-0x210];
+	u32 lc_vec[512];
 } __attribute__((packed,__aligned__(16)));
 
 static struct zcore_header zcore_header = {
@@ -289,7 +220,7 @@ static struct zcore_header zcore_header
 	.dump_level	= 0,
 	.page_size	= PAGE_SIZE,
 	.mem_start	= 0,
-#ifdef __s390x__
+#ifdef CONFIG_64BIT
 	.build_arch	= DUMP_ARCH_S390X,
 #else
 	.build_arch	= DUMP_ARCH_S390,
@@ -340,11 +271,7 @@ static int zcore_add_lc(char __user *buf
 		unsigned long prefix;
 		unsigned long sa_off, len, buf_off;
 
-		if (sys_info.arch == ARCH_S390)
-			prefix = zfcpdump_save_areas[i]->s390.pref_reg;
-		else
-			prefix = zfcpdump_save_areas[i]->s390x.pref_reg;
-
+		prefix = zfcpdump_save_areas[i]->pref_reg;
 		sa_start = prefix + sys_info.sa_base;
 		sa_end = prefix + sys_info.sa_base + sys_info.sa_size;
 
@@ -561,34 +488,39 @@ static const struct file_operations zcor
 	.release	= zcore_reipl_release,
 };
 
+#ifdef CONFIG_32BIT
 
-static void __init set_s390_lc_mask(union save_area *map)
+static void __init set_lc_mask(struct save_area *map)
 {
-	memset(&map->s390.ext_save, 0xff, sizeof(map->s390.ext_save));
-	memset(&map->s390.timer, 0xff, sizeof(map->s390.timer));
-	memset(&map->s390.clk_cmp, 0xff, sizeof(map->s390.clk_cmp));
-	memset(&map->s390.psw, 0xff, sizeof(map->s390.psw));
-	memset(&map->s390.pref_reg, 0xff, sizeof(map->s390.pref_reg));
-	memset(&map->s390.acc_regs, 0xff, sizeof(map->s390.acc_regs));
-	memset(&map->s390.fp_regs, 0xff, sizeof(map->s390.fp_regs));
-	memset(&map->s390.gp_regs, 0xff, sizeof(map->s390.gp_regs));
-	memset(&map->s390.ctrl_regs, 0xff, sizeof(map->s390.ctrl_regs));
+	memset(&map->ext_save, 0xff, sizeof(map->ext_save));
+	memset(&map->timer, 0xff, sizeof(map->timer));
+	memset(&map->clk_cmp, 0xff, sizeof(map->clk_cmp));
+	memset(&map->psw, 0xff, sizeof(map->psw));
+	memset(&map->pref_reg, 0xff, sizeof(map->pref_reg));
+	memset(&map->acc_regs, 0xff, sizeof(map->acc_regs));
+	memset(&map->fp_regs, 0xff, sizeof(map->fp_regs));
+	memset(&map->gp_regs, 0xff, sizeof(map->gp_regs));
+	memset(&map->ctrl_regs, 0xff, sizeof(map->ctrl_regs));
 }
 
-static void __init set_s390x_lc_mask(union save_area *map)
+#else /* CONFIG_32BIT */
+
+static void __init set_lc_mask(struct save_area *map)
 {
-	memset(&map->s390x.fp_regs, 0xff, sizeof(map->s390x.fp_regs));
-	memset(&map->s390x.gp_regs, 0xff, sizeof(map->s390x.gp_regs));
-	memset(&map->s390x.psw, 0xff, sizeof(map->s390x.psw));
-	memset(&map->s390x.pref_reg, 0xff, sizeof(map->s390x.pref_reg));
-	memset(&map->s390x.fp_ctrl_reg, 0xff, sizeof(map->s390x.fp_ctrl_reg));
-	memset(&map->s390x.tod_reg, 0xff, sizeof(map->s390x.tod_reg));
-	memset(&map->s390x.timer, 0xff, sizeof(map->s390x.timer));
-	memset(&map->s390x.clk_cmp, 0xff, sizeof(map->s390x.clk_cmp));
-	memset(&map->s390x.acc_regs, 0xff, sizeof(map->s390x.acc_regs));
-	memset(&map->s390x.ctrl_regs, 0xff, sizeof(map->s390x.ctrl_regs));
+	memset(&map->fp_regs, 0xff, sizeof(map->fp_regs));
+	memset(&map->gp_regs, 0xff, sizeof(map->gp_regs));
+	memset(&map->psw, 0xff, sizeof(map->psw));
+	memset(&map->pref_reg, 0xff, sizeof(map->pref_reg));
+	memset(&map->fp_ctrl_reg, 0xff, sizeof(map->fp_ctrl_reg));
+	memset(&map->tod_reg, 0xff, sizeof(map->tod_reg));
+	memset(&map->timer, 0xff, sizeof(map->timer));
+	memset(&map->clk_cmp, 0xff, sizeof(map->clk_cmp));
+	memset(&map->acc_regs, 0xff, sizeof(map->acc_regs));
+	memset(&map->ctrl_regs, 0xff, sizeof(map->ctrl_regs));
 }
 
+#endif /* CONFIG_32BIT */
+
 /*
  * Initialize dump globals for a given architecture
  */
@@ -599,21 +531,18 @@ static int __init sys_info_init(enum arc
 	switch (arch) {
 	case ARCH_S390X:
 		pr_alert("DETECTED 'S390X (64 bit) OS'\n");
-		sys_info.sa_base = SAVE_AREA_BASE_S390X;
-		sys_info.sa_size = sizeof(struct save_area_s390x);
-		set_s390x_lc_mask(&sys_info.lc_mask);
 		break;
 	case ARCH_S390:
 		pr_alert("DETECTED 'S390 (32 bit) OS'\n");
-		sys_info.sa_base = SAVE_AREA_BASE_S390;
-		sys_info.sa_size = sizeof(struct save_area_s390);
-		set_s390_lc_mask(&sys_info.lc_mask);
 		break;
 	default:
 		pr_alert("0x%x is an unknown architecture.\n",arch);
 		return -EINVAL;
 	}
+	sys_info.sa_base = SAVE_AREA_BASE;
+	sys_info.sa_size = sizeof(struct save_area);
 	sys_info.arch = arch;
+	set_lc_mask(&sys_info.lc_mask);
 	rc = init_cpu_info(arch);
 	if (rc)
 		return rc;
@@ -660,8 +589,9 @@ static int __init get_mem_size(unsigned
 
 static int __init zcore_header_init(int arch, struct zcore_header *hdr)
 {
-	int rc;
+	int rc, i;
 	unsigned long memory = 0;
+	u32 prefix;
 
 	if (arch == ARCH_S390X)
 		hdr->arch_id = DUMP_ARCH_S390X;
@@ -676,6 +606,14 @@ static int __init zcore_header_init(int
 	hdr->num_pages = memory / PAGE_SIZE;
 	hdr->tod = get_clock();
 	get_cpu_id(&hdr->cpu_id);
+	for (i = 0; zfcpdump_save_areas[i]; i++) {
+		prefix = zfcpdump_save_areas[i]->pref_reg;
+		hdr->real_cpu_cnt++;
+		if (!prefix)
+			continue;
+		hdr->lc_vec[hdr->cpu_cnt] = prefix;
+		hdr->cpu_cnt++;
+	}
 	return 0;
 }
 
@@ -699,12 +637,8 @@ static int __init zcore_reipl_init(void)
 	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) !=
+		rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE);
+	if (rc || csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
 	    ipib_info.checksum) {
 		TRACE("Checksum does not match\n");
 		free_page((unsigned long) ipl_block);
@@ -741,14 +675,21 @@ static int __init zcore_init(void)
 	if (rc)
 		goto fail;
 
-#ifndef __s390x__
+#ifdef CONFIG_64BIT
+	if (arch == ARCH_S390) {
+		pr_alert("The 64-bit dump tool cannot be used for a "
+			 "32-bit system\n");
+		rc = -EINVAL;
+		goto fail;
+	}
+#else /* CONFIG_64BIT */
 	if (arch == ARCH_S390X) {
 		pr_alert("The 32-bit dump tool cannot be used for a "
 			 "64-bit system\n");
 		rc = -EINVAL;
 		goto fail;
 	}
-#endif
+#endif /* CONFIG_64BIT */
 
 	rc = sys_info_init(arch);
 	if (rc)
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/blacklist.c linux-libre-2.6.34-gnu1/drivers/s390/cio/blacklist.c
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/blacklist.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/blacklist.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
 
 #include <linux/init.h>
 #include <linux/vmalloc.h>
-#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/ctype.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/ccwreq.c linux-libre-2.6.34-gnu1/drivers/s390/cio/ccwreq.c
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/ccwreq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/ccwreq.c	2010-05-16 17:17:36.000000000 -0400
@@ -224,8 +224,8 @@ static void ccwreq_log_status(struct ccw
  */
 void ccw_request_handler(struct ccw_device *cdev)
 {
+	struct irb *irb = (struct irb *)&S390_lowcore.irb;
 	struct ccw_request *req = &cdev->private->req;
-	struct irb *irb = (struct irb *) __LC_IRB;
 	enum io_status status;
 	int rc = -EOPNOTSUPP;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/chp.c linux-libre-2.6.34-gnu1/drivers/s390/cio/chp.c
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/chp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/chp.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/wait.h>
 #include <linux/mutex.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <asm/chpid.h>
 #include <asm/sclp.h>
 #include <asm/crw.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/chsc.c linux-libre-2.6.34-gnu1/drivers/s390/cio/chsc.c
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/chsc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/chsc.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include "chsc.h"
 
 static void *sei_page;
+static DEFINE_SPINLOCK(sda_lock);
 
 /**
  * chsc_error_from_response() - convert a chsc response to an error
@@ -574,7 +575,7 @@ int __chsc_do_secm(struct channel_subsys
 	secm_area->request.length = 0x0050;
 	secm_area->request.code = 0x0016;
 
-	secm_area->key = PAGE_DEFAULT_KEY;
+	secm_area->key = PAGE_DEFAULT_KEY >> 4;
 	secm_area->cub_addr1 = (u64)(unsigned long)css->cub_addr1;
 	secm_area->cub_addr2 = (u64)(unsigned long)css->cub_addr2;
 
@@ -832,11 +833,10 @@ void __init chsc_free_sei_area(void)
 	kfree(sei_page);
 }
 
-int __init
-chsc_enable_facility(int operation_code)
+int chsc_enable_facility(int operation_code)
 {
 	int ret;
-	struct {
+	static struct {
 		struct chsc_header request;
 		u8 reserved1:4;
 		u8 format:4;
@@ -849,33 +849,32 @@ chsc_enable_facility(int operation_code)
 		u32 reserved5:4;
 		u32 format2:4;
 		u32 reserved6:24;
-	} __attribute__ ((packed)) *sda_area;
+	} __attribute__ ((packed, aligned(4096))) sda_area;
 
-	sda_area = (void *)get_zeroed_page(GFP_KERNEL|GFP_DMA);
-	if (!sda_area)
-		return -ENOMEM;
-	sda_area->request.length = 0x0400;
-	sda_area->request.code = 0x0031;
-	sda_area->operation_code = operation_code;
+	spin_lock(&sda_lock);
+	memset(&sda_area, 0, sizeof(sda_area));
+	sda_area.request.length = 0x0400;
+	sda_area.request.code = 0x0031;
+	sda_area.operation_code = operation_code;
 
-	ret = chsc(sda_area);
+	ret = chsc(&sda_area);
 	if (ret > 0) {
 		ret = (ret == 3) ? -ENODEV : -EBUSY;
 		goto out;
 	}
 
-	switch (sda_area->response.code) {
+	switch (sda_area.response.code) {
 	case 0x0101:
 		ret = -EOPNOTSUPP;
 		break;
 	default:
-		ret = chsc_error_from_response(sda_area->response.code);
+		ret = chsc_error_from_response(sda_area.response.code);
 	}
 	if (ret != 0)
 		CIO_CRW_EVENT(2, "chsc: sda (oc=%x) failed (rc=%04x)\n",
-			      operation_code, sda_area->response.code);
+			      operation_code, sda_area.response.code);
  out:
-	free_page((unsigned long)sda_area);
+	spin_unlock(&sda_lock);
 	return ret;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/chsc_sch.c linux-libre-2.6.34-gnu1/drivers/s390/cio/chsc_sch.c
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/chsc_sch.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/chsc_sch.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/uaccess.h>
@@ -51,7 +52,7 @@ static void chsc_subchannel_irq(struct s
 {
 	struct chsc_private *private = sch->private;
 	struct chsc_request *request = private->request;
-	struct irb *irb = (struct irb *)__LC_IRB;
+	struct irb *irb = (struct irb *)&S390_lowcore.irb;
 
 	CHSC_LOG(4, "irb");
 	CHSC_LOG_HEX(4, irb, sizeof(*irb));
@@ -123,7 +124,7 @@ static int chsc_subchannel_prepare(struc
 	 * since we don't have a way to clear the subchannel and
 	 * cannot disable it with a request running.
 	 */
-	cc = stsch(sch->schid, &schib);
+	cc = stsch_err(sch->schid, &schib);
 	if (!cc && scsw_stctl(&schib.scsw))
 		return -EAGAIN;
 	return 0;
@@ -237,7 +238,7 @@ static int chsc_async(struct chsc_async_
 	int ret = -ENODEV;
 	char dbf[10];
 
-	chsc_area->header.key = PAGE_DEFAULT_KEY;
+	chsc_area->header.key = PAGE_DEFAULT_KEY >> 4;
 	while ((sch = chsc_get_next_subchannel(sch))) {
 		spin_lock(sch->lock);
 		private = sch->private;
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/cio.c linux-libre-2.6.34-gnu1/drivers/s390/cio/cio.c
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/cio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/cio.c	2010-05-16 17:17:36.000000000 -0400
@@ -361,7 +361,7 @@ int cio_commit_config(struct subchannel
 	struct schib schib;
 	int ccode, retry, ret = 0;
 
-	if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib))
+	if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib))
 		return -ENODEV;
 
 	for (retry = 0; retry < 5; retry++) {
@@ -372,7 +372,7 @@ int cio_commit_config(struct subchannel
 			return ccode;
 		switch (ccode) {
 		case 0: /* successful */
-			if (stsch(sch->schid, &schib) ||
+			if (stsch_err(sch->schid, &schib) ||
 			    !css_sch_is_valid(&schib))
 				return -ENODEV;
 			if (cio_check_config(sch, &schib)) {
@@ -404,7 +404,7 @@ int cio_update_schib(struct subchannel *
 {
 	struct schib schib;
 
-	if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib))
+	if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib))
 		return -ENODEV;
 
 	memcpy(&sch->schib, &schib, sizeof(schib));
@@ -625,8 +625,8 @@ void __irq_entry do_IRQ(struct pt_regs *
 	/*
 	 * Get interrupt information from lowcore
 	 */
-	tpi_info = (struct tpi_info *) __LC_SUBCHANNEL_ID;
-	irb = (struct irb *) __LC_IRB;
+	tpi_info = (struct tpi_info *)&S390_lowcore.subchannel_id;
+	irb = (struct irb *)&S390_lowcore.irb;
 	do {
 		kstat_cpu(smp_processor_id()).irqs[IO_INTERRUPT]++;
 		/*
@@ -661,7 +661,7 @@ void __irq_entry do_IRQ(struct pt_regs *
 		 * We don't do this for VM because a tpi drops the cpu
 		 * out of the sie which costs more cycles than it saves.
 		 */
-	} while (!MACHINE_IS_VM && tpi (NULL) != 0);
+	} while (MACHINE_IS_LPAR && tpi(NULL) != 0);
 	irq_exit();
 	set_irq_regs(old_regs);
 }
@@ -682,10 +682,10 @@ static int cio_tpi(void)
 	struct irb *irb;
 	int irq_context;
 
-	tpi_info = (struct tpi_info *) __LC_SUBCHANNEL_ID;
+	tpi_info = (struct tpi_info *)&S390_lowcore.subchannel_id;
 	if (tpi(NULL) != 1)
 		return 0;
-	irb = (struct irb *) __LC_IRB;
+	irb = (struct irb *)&S390_lowcore.irb;
 	/* Store interrupt response block to lowcore. */
 	if (tsch(tpi_info->schid, irb) != 0)
 		/* Not status pending or not operational. */
@@ -771,7 +771,7 @@ cio_get_console_sch_no(void)
 	if (console_irq != -1) {
 		/* VM provided us with the irq number of the console. */
 		schid.sch_no = console_irq;
-		if (stsch(schid, &console_subchannel.schib) != 0 ||
+		if (stsch_err(schid, &console_subchannel.schib) != 0 ||
 		    (console_subchannel.schib.pmcw.st != SUBCHANNEL_TYPE_IO) ||
 		    !console_subchannel.schib.pmcw.dnv)
 			return -1;
@@ -863,10 +863,10 @@ __disable_subchannel_easy(struct subchan
 	cc = 0;
 	for (retry=0;retry<3;retry++) {
 		schib->pmcw.ena = 0;
-		cc = msch(schid, schib);
+		cc = msch_err(schid, schib);
 		if (cc)
 			return (cc==3?-ENODEV:-EBUSY);
-		if (stsch(schid, schib) || !css_sch_is_valid(schib))
+		if (stsch_err(schid, schib) || !css_sch_is_valid(schib))
 			return -ENODEV;
 		if (!schib->pmcw.ena)
 			return 0;
@@ -885,7 +885,7 @@ __clear_io_subchannel_easy(struct subcha
 		struct tpi_info ti;
 
 		if (tpi(&ti)) {
-			tsch(ti.schid, (struct irb *)__LC_IRB);
+			tsch(ti.schid, (struct irb *)&S390_lowcore.irb);
 			if (schid_equal(&ti.schid, &schid))
 				return 0;
 		}
@@ -913,7 +913,7 @@ static int stsch_reset(struct subchannel
 
 	pgm_check_occured = 0;
 	s390_base_pgm_handler_fn = cio_reset_pgm_check_handler;
-	rc = stsch(schid, addr);
+	rc = stsch_err(schid, addr);
 	s390_base_pgm_handler_fn = NULL;
 
 	/* The program check handler could have changed pgm_check_occured. */
@@ -950,7 +950,7 @@ static int __shutdown_subchannel_easy(st
 			/* No default clear strategy */
 			break;
 		}
-		stsch(schid, &schib);
+		stsch_err(schid, &schib);
 		__disable_subchannel_easy(schid, &schib);
 	}
 out:
@@ -1083,10 +1083,10 @@ int __init cio_get_iplinfo(struct cio_ip
 	struct subchannel_id schid;
 	struct schib schib;
 
-	schid = *(struct subchannel_id *)__LC_SUBCHANNEL_ID;
+	schid = *(struct subchannel_id *)&S390_lowcore.subchannel_id;
 	if (!schid.one)
 		return -ENODEV;
-	if (stsch(schid, &schib))
+	if (stsch_err(schid, &schib))
 		return -ENODEV;
 	if (schib.pmcw.st != SUBCHANNEL_TYPE_IO)
 		return -ENODEV;
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/crw.c linux-libre-2.6.34-gnu1/drivers/s390/cio/crw.c
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/crw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/crw.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,15 +8,16 @@
  *		 Heiko Carstens <heiko.carstens@de.ibm.com>,
  */
 
-#include <linux/semaphore.h>
 #include <linux/mutex.h>
 #include <linux/kthread.h>
 #include <linux/init.h>
+#include <linux/wait.h>
 #include <asm/crw.h>
 
-static struct semaphore crw_semaphore;
 static DEFINE_MUTEX(crw_handler_mutex);
 static crw_handler_t crw_handlers[NR_RSCS];
+static atomic_t crw_nr_req = ATOMIC_INIT(0);
+static DECLARE_WAIT_QUEUE_HEAD(crw_handler_wait_q);
 
 /**
  * crw_register_handler() - register a channel report word handler
@@ -59,12 +60,14 @@ void crw_unregister_handler(int rsc)
 static int crw_collect_info(void *unused)
 {
 	struct crw crw[2];
-	int ccode;
+	int ccode, signal;
 	unsigned int chain;
-	int ignore;
 
 repeat:
-	ignore = down_interruptible(&crw_semaphore);
+	signal = wait_event_interruptible(crw_handler_wait_q,
+					  atomic_read(&crw_nr_req) > 0);
+	if (unlikely(signal))
+		atomic_inc(&crw_nr_req);
 	chain = 0;
 	while (1) {
 		crw_handler_t handler;
@@ -122,25 +125,23 @@ repeat:
 		/* chain is always 0 or 1 here. */
 		chain = crw[chain].chn ? chain + 1 : 0;
 	}
+	if (atomic_dec_and_test(&crw_nr_req))
+		wake_up(&crw_handler_wait_q);
 	goto repeat;
 	return 0;
 }
 
 void crw_handle_channel_report(void)
 {
-	up(&crw_semaphore);
+	atomic_inc(&crw_nr_req);
+	wake_up(&crw_handler_wait_q);
 }
 
-/*
- * 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)
+void crw_wait_for_channel_report(void)
 {
-	init_MUTEX_LOCKED(&crw_semaphore);
-	return 0;
+	crw_handle_channel_report();
+	wait_event(crw_handler_wait_q, atomic_read(&crw_nr_req) == 0);
 }
-pure_initcall(crw_init_semaphore);
 
 /*
  * Machine checks for the channel subsystem must be enabled
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/css.c linux-libre-2.6.34-gnu1/drivers/s390/cio/css.c
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/css.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/css.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/list.h>
 #include <linux/reboot.h>
 #include <linux/suspend.h>
+#include <linux/proc_fs.h>
 #include <asm/isc.h>
 #include <asm/crw.h>
 
@@ -232,7 +233,7 @@ void css_sched_sch_todo(struct subchanne
 	if (!get_device(&sch->dev))
 		return;
 	sch->todo = todo;
-	if (!queue_work(slow_path_wq, &sch->todo_work)) {
+	if (!queue_work(cio_work_q, &sch->todo_work)) {
 		/* Already queued, release workqueue ref. */
 		put_device(&sch->dev);
 	}
@@ -543,7 +544,7 @@ static void css_slow_path_func(struct wo
 }
 
 static DECLARE_WORK(slow_path_work, css_slow_path_func);
-struct workqueue_struct *slow_path_wq;
+struct workqueue_struct *cio_work_q;
 
 void css_schedule_eval(struct subchannel_id schid)
 {
@@ -552,7 +553,7 @@ void css_schedule_eval(struct subchannel
 	spin_lock_irqsave(&slow_subchannel_lock, flags);
 	idset_sch_add(slow_subchannel_set, schid);
 	atomic_set(&css_eval_scheduled, 1);
-	queue_work(slow_path_wq, &slow_path_work);
+	queue_work(cio_work_q, &slow_path_work);
 	spin_unlock_irqrestore(&slow_subchannel_lock, flags);
 }
 
@@ -563,7 +564,7 @@ void css_schedule_eval_all(void)
 	spin_lock_irqsave(&slow_subchannel_lock, flags);
 	idset_fill(slow_subchannel_set);
 	atomic_set(&css_eval_scheduled, 1);
-	queue_work(slow_path_wq, &slow_path_work);
+	queue_work(cio_work_q, &slow_path_work);
 	spin_unlock_irqrestore(&slow_subchannel_lock, flags);
 }
 
@@ -594,14 +595,14 @@ void css_schedule_eval_all_unreg(void)
 	spin_lock_irqsave(&slow_subchannel_lock, flags);
 	idset_add_set(slow_subchannel_set, unreg_set);
 	atomic_set(&css_eval_scheduled, 1);
-	queue_work(slow_path_wq, &slow_path_work);
+	queue_work(cio_work_q, &slow_path_work);
 	spin_unlock_irqrestore(&slow_subchannel_lock, flags);
 	idset_free(unreg_set);
 }
 
 void css_wait_for_slow_path(void)
 {
-	flush_workqueue(slow_path_wq);
+	flush_workqueue(cio_work_q);
 }
 
 /* Schedule reprobing of all unregistered subchannels. */
@@ -869,15 +870,10 @@ static int __init css_bus_init(void)
 
 	/* Try to enable MSS. */
 	ret = chsc_enable_facility(CHSC_SDA_OC_MSS);
-	switch (ret) {
-	case 0: /* Success. */
-		max_ssid = __MAX_SSID;
-		break;
-	case -ENOMEM:
-		goto out;
-	default:
+	if (ret)
 		max_ssid = 0;
-	}
+	else /* Success. */
+		max_ssid = __MAX_SSID;
 
 	ret = slow_subchannel_init();
 	if (ret)
@@ -992,12 +988,21 @@ static int __init channel_subsystem_init
 	ret = css_bus_init();
 	if (ret)
 		return ret;
-
+	cio_work_q = create_singlethread_workqueue("cio");
+	if (!cio_work_q) {
+		ret = -ENOMEM;
+		goto out_bus;
+	}
 	ret = io_subchannel_init();
 	if (ret)
-		css_bus_cleanup();
+		goto out_wq;
 
 	return ret;
+out_wq:
+	destroy_workqueue(cio_work_q);
+out_bus:
+	css_bus_cleanup();
+	return ret;
 }
 subsys_initcall(channel_subsystem_init);
 
@@ -1006,10 +1011,25 @@ static int css_settle(struct device_driv
 	struct css_driver *cssdrv = to_cssdriver(drv);
 
 	if (cssdrv->settle)
-		cssdrv->settle();
+		return cssdrv->settle();
 	return 0;
 }
 
+int css_complete_work(void)
+{
+	int ret;
+
+	/* Wait for the evaluation of subchannels to finish. */
+	ret = wait_event_interruptible(css_eval_wq,
+				       atomic_read(&css_eval_scheduled) == 0);
+	if (ret)
+		return -EINTR;
+	flush_workqueue(cio_work_q);
+	/* Wait for the subchannel type specific initialization to finish */
+	return bus_for_each_drv(&css_bus_type, NULL, NULL, css_settle);
+}
+
+
 /*
  * Wait for the initialization of devices to finish, to make sure we are
  * done with our setup if the search for the root device starts.
@@ -1018,13 +1038,46 @@ static int __init channel_subsystem_init
 {
 	/* Start initial subchannel evaluation. */
 	css_schedule_eval_all();
-	/* Wait for the evaluation of subchannels to finish. */
-	wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0);
-	/* Wait for the subchannel type specific initialization to finish */
-	return bus_for_each_drv(&css_bus_type, NULL, NULL, css_settle);
+	css_complete_work();
+	return 0;
 }
 subsys_initcall_sync(channel_subsystem_init_sync);
 
+void channel_subsystem_reinit(void)
+{
+	chsc_enable_facility(CHSC_SDA_OC_MSS);
+}
+
+#ifdef CONFIG_PROC_FS
+static ssize_t cio_settle_write(struct file *file, const char __user *buf,
+				size_t count, loff_t *ppos)
+{
+	int ret;
+
+	/* Handle pending CRW's. */
+	crw_wait_for_channel_report();
+	ret = css_complete_work();
+
+	return ret ? ret : count;
+}
+
+static const struct file_operations cio_settle_proc_fops = {
+	.write = cio_settle_write,
+};
+
+static int __init cio_settle_init(void)
+{
+	struct proc_dir_entry *entry;
+
+	entry = proc_create("cio_settle", S_IWUSR, NULL,
+			    &cio_settle_proc_fops);
+	if (!entry)
+		return -ENOMEM;
+	return 0;
+}
+device_initcall(cio_settle_init);
+#endif /*CONFIG_PROC_FS*/
+
 int sch_is_pseudo_sch(struct subchannel *sch)
 {
 	return sch == to_css(sch->dev.parent)->pseudo_subchannel;
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/css.h linux-libre-2.6.34-gnu1/drivers/s390/cio/css.h
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/css.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/css.h	2010-05-16 17:17:36.000000000 -0400
@@ -95,7 +95,7 @@ struct css_driver {
 	int (*freeze)(struct subchannel *);
 	int (*thaw) (struct subchannel *);
 	int (*restore)(struct subchannel *);
-	void (*settle)(void);
+	int (*settle)(void);
 	const char *name;
 };
 
@@ -146,12 +146,13 @@ extern struct channel_subsystem *channel
 /* Helper functions to build lists for the slow path. */
 void css_schedule_eval(struct subchannel_id schid);
 void css_schedule_eval_all(void);
+int css_complete_work(void);
 
 int sch_is_pseudo_sch(struct subchannel *);
 struct schib;
 int css_sch_is_valid(struct schib *);
 
-extern struct workqueue_struct *slow_path_wq;
+extern struct workqueue_struct *cio_work_q;
 void css_wait_for_slow_path(void);
 void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo);
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/device.c linux-libre-2.6.34-gnu1/drivers/s390/cio/device.c
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/device.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/device.c	2010-05-16 17:17:36.000000000 -0400
@@ -136,7 +136,6 @@ static int io_subchannel_sch_event(struc
 static int io_subchannel_chp_event(struct subchannel *, struct chp_link *,
 				   int);
 static void recovery_func(unsigned long data);
-struct workqueue_struct *ccw_device_work;
 wait_queue_head_t ccw_device_init_wq;
 atomic_t ccw_device_init_count;
 
@@ -159,11 +158,16 @@ static int io_subchannel_prepare(struct
 	return 0;
 }
 
-static void io_subchannel_settle(void)
+static int io_subchannel_settle(void)
 {
-	wait_event(ccw_device_init_wq,
-		   atomic_read(&ccw_device_init_count) == 0);
-	flush_workqueue(ccw_device_work);
+	int ret;
+
+	ret = wait_event_interruptible(ccw_device_init_wq,
+				atomic_read(&ccw_device_init_count) == 0);
+	if (ret)
+		return -EINTR;
+	flush_workqueue(cio_work_q);
+	return 0;
 }
 
 static struct css_driver io_subchannel_driver = {
@@ -188,27 +192,13 @@ int __init io_subchannel_init(void)
 	atomic_set(&ccw_device_init_count, 0);
 	setup_timer(&recovery_timer, recovery_func, 0);
 
-	ccw_device_work = create_singlethread_workqueue("cio");
-	if (!ccw_device_work)
-		return -ENOMEM;
-	slow_path_wq = create_singlethread_workqueue("kslowcrw");
-	if (!slow_path_wq) {
-		ret = -ENOMEM;
-		goto out_err;
-	}
-	if ((ret = bus_register (&ccw_bus_type)))
-		goto out_err;
-
+	ret = bus_register(&ccw_bus_type);
+	if (ret)
+		return ret;
 	ret = css_driver_register(&io_subchannel_driver);
 	if (ret)
-		goto out_err;
+		bus_unregister(&ccw_bus_type);
 
-	return 0;
-out_err:
-	if (ccw_device_work)
-		destroy_workqueue(ccw_device_work);
-	if (slow_path_wq)
-		destroy_workqueue(slow_path_wq);
 	return ret;
 }
 
@@ -774,7 +764,7 @@ static void sch_create_and_recog_new_dev
 static void io_subchannel_register(struct ccw_device *cdev)
 {
 	struct subchannel *sch;
-	int ret;
+	int ret, adjust_init_count = 1;
 	unsigned long flags;
 
 	sch = to_subchannel(cdev->dev.parent);
@@ -803,6 +793,7 @@ static void io_subchannel_register(struc
 					      cdev->private->dev_id.ssid,
 					      cdev->private->dev_id.devno);
 		}
+		adjust_init_count = 0;
 		goto out;
 	}
 	/*
@@ -828,7 +819,7 @@ out:
 	cdev->private->flags.recog_done = 1;
 	wake_up(&cdev->private->wait_q);
 out_err:
-	if (atomic_dec_and_test(&ccw_device_init_count))
+	if (adjust_init_count && atomic_dec_and_test(&ccw_device_init_count))
 		wake_up(&ccw_device_init_wq);
 }
 
@@ -1348,7 +1339,7 @@ static enum io_sch_action sch_get_action
 		/* Not operational. */
 		if (!cdev)
 			return IO_SCH_UNREG;
-		if (!ccw_device_notify(cdev, CIO_GONE))
+		if (ccw_device_notify(cdev, CIO_GONE) != NOTIFY_OK)
 			return IO_SCH_UNREG;
 		return IO_SCH_ORPH_UNREG;
 	}
@@ -1356,12 +1347,12 @@ static enum io_sch_action sch_get_action
 	if (!cdev)
 		return IO_SCH_ATTACH;
 	if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) {
-		if (!ccw_device_notify(cdev, CIO_GONE))
+		if (ccw_device_notify(cdev, CIO_GONE) != NOTIFY_OK)
 			return IO_SCH_UNREG_ATTACH;
 		return IO_SCH_ORPH_ATTACH;
 	}
 	if ((sch->schib.pmcw.pam & sch->opm) == 0) {
-		if (!ccw_device_notify(cdev, CIO_NO_PATH))
+		if (ccw_device_notify(cdev, CIO_NO_PATH) != NOTIFY_OK)
 			return IO_SCH_UNREG;
 		return IO_SCH_DISC;
 	}
@@ -1410,6 +1401,12 @@ static int io_subchannel_sch_event(struc
 		rc = 0;
 		goto out_unlock;
 	case IO_SCH_VERIFY:
+		if (cdev->private->flags.resuming == 1) {
+			if (cio_enable_subchannel(sch, (u32)(addr_t)sch)) {
+				ccw_device_set_notoper(cdev);
+				break;
+			}
+		}
 		/* Trigger path verification. */
 		io_subchannel_verify(sch);
 		rc = 0;
@@ -1448,7 +1445,8 @@ static int io_subchannel_sch_event(struc
 		break;
 	case IO_SCH_UNREG_ATTACH:
 		/* Unregister ccw device. */
-		ccw_device_unregister(cdev);
+		if (!cdev->private->flags.resuming)
+			ccw_device_unregister(cdev);
 		break;
 	default:
 		break;
@@ -1457,7 +1455,8 @@ static int io_subchannel_sch_event(struc
 	switch (action) {
 	case IO_SCH_ORPH_UNREG:
 	case IO_SCH_UNREG:
-		css_sch_device_unregister(sch);
+		if (!cdev || !cdev->private->flags.resuming)
+			css_sch_device_unregister(sch);
 		break;
 	case IO_SCH_ORPH_ATTACH:
 	case IO_SCH_UNREG_ATTACH:
@@ -1779,26 +1778,42 @@ static void __ccw_device_pm_restore(stru
 {
 	struct subchannel *sch = to_subchannel(cdev->dev.parent);
 
-	if (cio_is_console(sch->schid))
-		goto out;
+	spin_lock_irq(sch->lock);
+	if (cio_is_console(sch->schid)) {
+		cio_enable_subchannel(sch, (u32)(addr_t)sch);
+		goto out_unlock;
+	}
 	/*
 	 * While we were sleeping, devices may have gone or become
 	 * available again. Kick re-detection.
 	 */
-	spin_lock_irq(sch->lock);
 	cdev->private->flags.resuming = 1;
+	css_schedule_eval(sch->schid);
+	spin_unlock_irq(sch->lock);
+	css_complete_work();
+
+	/* cdev may have been moved to a different subchannel. */
+	sch = to_subchannel(cdev->dev.parent);
+	spin_lock_irq(sch->lock);
+	if (cdev->private->state != DEV_STATE_ONLINE &&
+	    cdev->private->state != DEV_STATE_OFFLINE)
+		goto out_unlock;
+
 	ccw_device_recognition(cdev);
 	spin_unlock_irq(sch->lock);
 	wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev) ||
 		   cdev->private->state == DEV_STATE_DISCONNECTED);
-out:
+	spin_lock_irq(sch->lock);
+
+out_unlock:
 	cdev->private->flags.resuming = 0;
+	spin_unlock_irq(sch->lock);
 }
 
 static int resume_handle_boxed(struct ccw_device *cdev)
 {
 	cdev->private->state = DEV_STATE_BOXED;
-	if (ccw_device_notify(cdev, CIO_BOXED))
+	if (ccw_device_notify(cdev, CIO_BOXED) == NOTIFY_OK)
 		return 0;
 	ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 	return -ENODEV;
@@ -1807,7 +1822,7 @@ static int resume_handle_boxed(struct cc
 static int resume_handle_disc(struct ccw_device *cdev)
 {
 	cdev->private->state = DEV_STATE_DISCONNECTED;
-	if (ccw_device_notify(cdev, CIO_GONE))
+	if (ccw_device_notify(cdev, CIO_GONE) == NOTIFY_OK)
 		return 0;
 	ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 	return -ENODEV;
@@ -1816,40 +1831,31 @@ static int resume_handle_disc(struct ccw
 static int ccw_device_pm_restore(struct device *dev)
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
-	struct subchannel *sch = to_subchannel(cdev->dev.parent);
-	int ret = 0, cm_enabled;
+	struct subchannel *sch;
+	int ret = 0;
 
 	__ccw_device_pm_restore(cdev);
+	sch = to_subchannel(cdev->dev.parent);
 	spin_lock_irq(sch->lock);
-	if (cio_is_console(sch->schid)) {
-		cio_enable_subchannel(sch, (u32)(addr_t)sch);
-		spin_unlock_irq(sch->lock);
+	if (cio_is_console(sch->schid))
 		goto out_restore;
-	}
-	cdev->private->flags.donotify = 0;
+
 	/* check recognition results */
 	switch (cdev->private->state) {
 	case DEV_STATE_OFFLINE:
+	case DEV_STATE_ONLINE:
+		cdev->private->flags.donotify = 0;
 		break;
 	case DEV_STATE_BOXED:
 		ret = resume_handle_boxed(cdev);
-		spin_unlock_irq(sch->lock);
 		if (ret)
-			goto out;
+			goto out_unlock;
 		goto out_restore;
-	case DEV_STATE_DISCONNECTED:
-		goto out_disc_unlock;
 	default:
-		goto out_unreg_unlock;
-	}
-	/* check if the device id has changed */
-	if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) {
-		CIO_MSG_EVENT(0, "resume: sch 0.%x.%04x: failed (devno "
-			      "changed from %04x to %04x)\n",
-			      sch->schid.ssid, sch->schid.sch_no,
-			      cdev->private->dev_id.devno,
-			      sch->schib.pmcw.dev);
-		goto out_unreg_unlock;
+		ret = resume_handle_disc(cdev);
+		if (ret)
+			goto out_unlock;
+		goto out_restore;
 	}
 	/* check if the device type has changed */
 	if (!ccw_device_test_sense_data(cdev)) {
@@ -1858,24 +1864,30 @@ static int ccw_device_pm_restore(struct
 		ret = -ENODEV;
 		goto out_unlock;
 	}
-	if (!cdev->online) {
-		ret = 0;
+	if (!cdev->online)
 		goto out_unlock;
-	}
-	ret = ccw_device_online(cdev);
-	if (ret)
-		goto out_disc_unlock;
 
-	cm_enabled = cdev->private->cmb != NULL;
+	if (ccw_device_online(cdev)) {
+		ret = resume_handle_disc(cdev);
+		if (ret)
+			goto out_unlock;
+		goto out_restore;
+	}
 	spin_unlock_irq(sch->lock);
-
 	wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
-	if (cdev->private->state != DEV_STATE_ONLINE) {
-		spin_lock_irq(sch->lock);
-		goto out_disc_unlock;
+	spin_lock_irq(sch->lock);
+
+	if (ccw_device_notify(cdev, CIO_OPER) == NOTIFY_BAD) {
+		ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
+		ret = -ENODEV;
+		goto out_unlock;
 	}
-	if (cm_enabled) {
+
+	/* reenable cmf, if needed */
+	if (cdev->private->cmb) {
+		spin_unlock_irq(sch->lock);
 		ret = ccw_set_cmf(cdev, 1);
+		spin_lock_irq(sch->lock);
 		if (ret) {
 			CIO_MSG_EVENT(2, "resume: cdev 0.%x.%04x: cmf failed "
 				      "(rc=%d)\n", cdev->private->dev_id.ssid,
@@ -1885,21 +1897,11 @@ static int ccw_device_pm_restore(struct
 	}
 
 out_restore:
+	spin_unlock_irq(sch->lock);
 	if (cdev->online && cdev->drv && cdev->drv->restore)
 		ret = cdev->drv->restore(cdev);
-out:
 	return ret;
 
-out_disc_unlock:
-	ret = resume_handle_disc(cdev);
-	spin_unlock_irq(sch->lock);
-	if (ret)
-		return ret;
-	goto out_restore;
-
-out_unreg_unlock:
-	ccw_device_sched_todo(cdev, CDEV_TODO_UNREG_EVAL);
-	ret = -ENODEV;
 out_unlock:
 	spin_unlock_irq(sch->lock);
 	return ret;
@@ -2028,7 +2030,7 @@ void ccw_device_sched_todo(struct ccw_de
 	/* Get workqueue ref. */
 	if (!get_device(&cdev->dev))
 		return;
-	if (!queue_work(slow_path_wq, &cdev->private->todo_work)) {
+	if (!queue_work(cio_work_q, &cdev->private->todo_work)) {
 		/* Already queued, release workqueue ref. */
 		put_device(&cdev->dev);
 	}
@@ -2041,5 +2043,4 @@ EXPORT_SYMBOL(ccw_driver_register);
 EXPORT_SYMBOL(ccw_driver_unregister);
 EXPORT_SYMBOL(get_ccwdev_by_busid);
 EXPORT_SYMBOL(ccw_bus_type);
-EXPORT_SYMBOL(ccw_device_work);
 EXPORT_SYMBOL_GPL(ccw_device_get_subchannel_id);
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/device_fsm.c linux-libre-2.6.34-gnu1/drivers/s390/cio/device_fsm.c
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/device_fsm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/device_fsm.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,7 +45,7 @@ static void ccw_timeout_log(struct ccw_d
 	sch = to_subchannel(cdev->dev.parent);
 	private = to_io_private(sch);
 	orb = &private->orb;
-	cc = stsch(sch->schid, &schib);
+	cc = stsch_err(sch->schid, &schib);
 
 	printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, "
 	       "device information:\n", get_clock());
@@ -313,21 +313,43 @@ ccw_device_sense_id_done(struct ccw_devi
 	}
 }
 
+/**
+  * ccw_device_notify() - inform the device's driver about an event
+  * @cdev: device for which an event occured
+  * @event: event that occurred
+  *
+  * Returns:
+  *   -%EINVAL if the device is offline or has no driver.
+  *   -%EOPNOTSUPP if the device's driver has no notifier registered.
+  *   %NOTIFY_OK if the driver wants to keep the device.
+  *   %NOTIFY_BAD if the driver doesn't want to keep the device.
+  */
 int ccw_device_notify(struct ccw_device *cdev, int event)
 {
+	int ret = -EINVAL;
+
 	if (!cdev->drv)
-		return 0;
+		goto out;
 	if (!cdev->online)
-		return 0;
+		goto out;
 	CIO_MSG_EVENT(2, "notify called for 0.%x.%04x, event=%d\n",
 		      cdev->private->dev_id.ssid, cdev->private->dev_id.devno,
 		      event);
-	return cdev->drv->notify ? cdev->drv->notify(cdev, event) : 0;
+	if (!cdev->drv->notify) {
+		ret = -EOPNOTSUPP;
+		goto out;
+	}
+	if (cdev->drv->notify(cdev, event))
+		ret = NOTIFY_OK;
+	else
+		ret = NOTIFY_BAD;
+out:
+	return ret;
 }
 
 static void ccw_device_oper_notify(struct ccw_device *cdev)
 {
-	if (ccw_device_notify(cdev, CIO_OPER)) {
+	if (ccw_device_notify(cdev, CIO_OPER) == NOTIFY_OK) {
 		/* Reenable channel measurements, if needed. */
 		ccw_device_sched_todo(cdev, CDEV_TODO_ENABLE_CMF);
 		return;
@@ -361,14 +383,15 @@ ccw_device_done(struct ccw_device *cdev,
 	case 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))
+		if (cdev->online &&
+		    ccw_device_notify(cdev, CIO_BOXED) != NOTIFY_OK)
 			ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 		cdev->private->flags.donotify = 0;
 		break;
 	case DEV_STATE_NOT_OPER:
 		CIO_MSG_EVENT(0, "Device %04x gone on subchannel %04x\n",
 			      cdev->private->dev_id.devno, sch->schid.sch_no);
-		if (!ccw_device_notify(cdev, CIO_GONE))
+		if (ccw_device_notify(cdev, CIO_GONE) != NOTIFY_OK)
 			ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 		else
 			ccw_device_set_disconnected(cdev);
@@ -378,7 +401,7 @@ ccw_device_done(struct ccw_device *cdev,
 		CIO_MSG_EVENT(0, "Disconnected device %04x on subchannel "
 			      "%04x\n", cdev->private->dev_id.devno,
 			      sch->schid.sch_no);
-		if (!ccw_device_notify(cdev, CIO_NO_PATH))
+		if (ccw_device_notify(cdev, CIO_NO_PATH) != NOTIFY_OK)
 			ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 		else
 			ccw_device_set_disconnected(cdev);
@@ -586,7 +609,7 @@ ccw_device_offline(struct ccw_device *cd
 static void ccw_device_generic_notoper(struct ccw_device *cdev,
 				       enum dev_event dev_event)
 {
-	if (!ccw_device_notify(cdev, CIO_GONE))
+	if (ccw_device_notify(cdev, CIO_GONE) != NOTIFY_OK)
 		ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 	else
 		ccw_device_set_disconnected(cdev);
@@ -667,7 +690,7 @@ ccw_device_irq(struct ccw_device *cdev,
 	struct irb *irb;
 	int is_cmd;
 
-	irb = (struct irb *) __LC_IRB;
+	irb = (struct irb *)&S390_lowcore.irb;
 	is_cmd = !scsw_is_tm(&irb->scsw);
 	/* Check for unsolicited interrupt. */
 	if (!scsw_is_solicited(&irb->scsw)) {
@@ -732,7 +755,7 @@ ccw_device_w4sense(struct ccw_device *cd
 {
 	struct irb *irb;
 
-	irb = (struct irb *) __LC_IRB;
+	irb = (struct irb *)&S390_lowcore.irb;
 	/* Check for unsolicited interrupt. */
 	if (scsw_stctl(&irb->scsw) ==
 	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/device.h linux-libre-2.6.34-gnu1/drivers/s390/cio/device.h
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/device.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/device.h	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
 #include <asm/ccwdev.h>
 #include <asm/atomic.h>
 #include <linux/wait.h>
-
+#include <linux/notifier.h>
 #include "io_sch.h"
 
 /*
@@ -71,7 +71,6 @@ dev_fsm_final_state(struct ccw_device *c
 		cdev->private->state == DEV_STATE_BOXED);
 }
 
-extern struct workqueue_struct *ccw_device_work;
 extern wait_queue_head_t ccw_device_init_wq;
 extern atomic_t ccw_device_init_count;
 int __init io_subchannel_init(void);
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_debug.c linux-libre-2.6.34-gnu1/drivers/s390/cio/qdio_debug.c
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_debug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/qdio_debug.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,6 @@ void qdio_allocate_dbf(struct qdio_initi
 	DBF_HEX(&init_data->input_handler, sizeof(void *));
 	DBF_HEX(&init_data->output_handler, sizeof(void *));
 	DBF_HEX(&init_data->int_parm, sizeof(long));
-	DBF_HEX(&init_data->flags, sizeof(long));
 	DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *));
 	DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *));
 	DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
@@ -60,7 +59,7 @@ static int qstat_show(struct seq_file *m
 	seq_printf(m, "ftc: %d  last_move: %d\n", q->first_to_check, q->last_move);
 	seq_printf(m, "polling: %d  ack start: %d  ack count: %d\n",
 		   q->u.in.polling, q->u.in.ack_start, q->u.in.ack_count);
-	seq_printf(m, "slsb buffer states:\n");
+	seq_printf(m, "SBAL states:\n");
 	seq_printf(m, "|0      |8      |16     |24     |32     |40     |48     |56  63|\n");
 
 	for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {
@@ -97,6 +96,20 @@ static int qstat_show(struct seq_file *m
 	}
 	seq_printf(m, "\n");
 	seq_printf(m, "|64     |72     |80     |88     |96     |104    |112    |   127|\n");
+
+	seq_printf(m, "\nSBAL statistics:");
+	if (!q->irq_ptr->perf_stat_enabled) {
+		seq_printf(m, " disabled\n");
+		return 0;
+	}
+
+	seq_printf(m, "\n1          2..        4..        8..        "
+		   "16..       32..       64..       127\n");
+	for (i = 0; i < ARRAY_SIZE(q->q_stats.nr_sbals); i++)
+		seq_printf(m, "%-10u ", q->q_stats.nr_sbals[i]);
+	seq_printf(m, "\nError      NOP        Total\n%-10u %-10u %-10u\n\n",
+		   q->q_stats.nr_sbal_error, q->q_stats.nr_sbal_nop,
+		   q->q_stats.nr_sbal_total);
 	return 0;
 }
 
@@ -181,9 +194,10 @@ static ssize_t qperf_seq_write(struct fi
 {
 	struct seq_file *seq = file->private_data;
 	struct qdio_irq *irq_ptr = seq->private;
+	struct qdio_q *q;
 	unsigned long val;
 	char buf[8];
-	int ret;
+	int ret, i;
 
 	if (!irq_ptr)
 		return 0;
@@ -201,6 +215,10 @@ static ssize_t qperf_seq_write(struct fi
 	case 0:
 		irq_ptr->perf_stat_enabled = 0;
 		memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat));
+		for_each_input_queue(irq_ptr, q, i)
+			memset(&q->q_stats, 0, sizeof(q->q_stats));
+		for_each_output_queue(irq_ptr, q, i)
+			memset(&q->q_stats, 0, sizeof(q->q_stats));
 		break;
 	case 1:
 		irq_ptr->perf_stat_enabled = 1;
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio.h linux-libre-2.6.34-gnu1/drivers/s390/cio/qdio.h
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/qdio.h	2010-05-16 17:17:36.000000000 -0400
@@ -208,18 +208,27 @@ struct qdio_dev_perf_stat {
 	unsigned int eqbs_partial;
 	unsigned int sqbs;
 	unsigned int sqbs_partial;
+} ____cacheline_aligned;
+
+struct qdio_queue_perf_stat {
+	/*
+	 * Sorted into order-2 buckets: 1, 2-3, 4-7, ... 64-127, 128.
+	 * Since max. 127 SBALs are scanned reuse entry for 128 as queue full
+	 * aka 127 SBALs found.
+	 */
+	unsigned int nr_sbals[8];
+	unsigned int nr_sbal_error;
+	unsigned int nr_sbal_nop;
+	unsigned int nr_sbal_total;
 };
 
 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;
-
 	/* last time of noticing incoming data */
 	u64 timestamp;
 };
@@ -227,40 +236,27 @@ struct qdio_input_q {
 struct qdio_output_q {
 	/* PCIs are enabled for the queue */
 	int pci_out_enabled;
-
 	/* IQDIO: output multiple buffers (enhanced SIGA) */
 	int use_enh_siga;
-
 	/* timer to check for more outbound work */
 	struct timer_list timer;
 };
 
+/*
+ * Note on cache alignment: grouped slsb and write mostly data at the beginning
+ * sbal[] is read-only and starts on a new cacheline followed by read mostly.
+ */
 struct qdio_q {
 	struct slsb slsb;
+
 	union {
 		struct qdio_input_q in;
 		struct qdio_output_q out;
 	} u;
 
-	/* queue number */
-	int nr;
-
-	/* bitmask of queue number */
-	int mask;
-
-	/* input or output queue */
-	int is_input_q;
-
-	/* list of thinint input queues */
-	struct list_head entry;
-
-	/* upper-layer program handler */
-	qdio_handler_t (*handler);
-
 	/*
 	 * inbound: next buffer the program should check for
-	 * outbound: next buffer to check for having been processed
-	 * by the card
+	 * outbound: next buffer to check if adapter processed it
 	 */
 	int first_to_check;
 
@@ -273,16 +269,32 @@ struct qdio_q {
 	/* number of buffers in use by the adapter */
 	atomic_t nr_buf_used;
 
-	struct qdio_irq *irq_ptr;
-	struct dentry *debugfs_q;
-	struct tasklet_struct tasklet;
-
 	/* error condition during a data transfer */
 	unsigned int qdio_error;
 
-	struct sl *sl;
-	struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q];
+	struct tasklet_struct tasklet;
+	struct qdio_queue_perf_stat q_stats;
+
+	struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q] ____cacheline_aligned;
+
+	/* queue number */
+	int nr;
+
+	/* bitmask of queue number */
+	int mask;
 
+	/* input or output queue */
+	int is_input_q;
+
+	/* list of thinint input queues */
+	struct list_head entry;
+
+	/* upper-layer program handler */
+	qdio_handler_t (*handler);
+
+	struct dentry *debugfs_q;
+	struct qdio_irq *irq_ptr;
+	struct sl *sl;
 	/*
 	 * Warning: Leave this member at the end so it won't be cleared in
 	 * qdio_fill_qs. A page is allocated under this pointer and used for
@@ -317,12 +329,8 @@ struct qdio_irq {
 	struct qdio_ssqd_desc ssqd_desc;
 	void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *);
 
-	struct qdio_dev_perf_stat perf_stat;
 	int perf_stat_enabled;
-	/*
-	 * Warning: Leave these members together at the end so they won't be
-	 * cleared in qdio_setup_irq.
-	 */
+
 	struct qdr *qdr;
 	unsigned long chsc_page;
 
@@ -331,6 +339,7 @@ struct qdio_irq {
 
 	debug_info_t *debug_area;
 	struct mutex setup_mutex;
+	struct qdio_dev_perf_stat perf_stat;
 };
 
 /* helper functions */
@@ -341,9 +350,20 @@ struct qdio_irq {
 	(irq->qib.qfmt == QDIO_IQDIO_QFMT || \
 	 css_general_characteristics.aif_osa)
 
-#define qperf(qdev,attr)	qdev->perf_stat.attr
-#define qperf_inc(q,attr)	if (q->irq_ptr->perf_stat_enabled) \
-					q->irq_ptr->perf_stat.attr++
+#define qperf(__qdev, __attr)	((__qdev)->perf_stat.(__attr))
+
+#define qperf_inc(__q, __attr)						\
+({									\
+	struct qdio_irq *qdev = (__q)->irq_ptr;				\
+	if (qdev->perf_stat_enabled)					\
+		(qdev->perf_stat.__attr)++;				\
+})
+
+static inline void account_sbals_error(struct qdio_q *q, int count)
+{
+	q->q_stats.nr_sbal_error += count;
+	q->q_stats.nr_sbal_total += count;
+}
 
 /* the highest iqdio queue is used for multicast */
 static inline int multicast_outbound(struct qdio_q *q)
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_main.c linux-libre-2.6.34-gnu1/drivers/s390/cio/qdio_main.c
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/qdio_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <asm/atomic.h>
 #include <asm/debug.h>
 #include <asm/qdio.h>
@@ -392,6 +393,20 @@ static inline void qdio_stop_polling(str
 		set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
 }
 
+static inline void account_sbals(struct qdio_q *q, int count)
+{
+	int pos = 0;
+
+	q->q_stats.nr_sbal_total += count;
+	if (count == QDIO_MAX_BUFFERS_MASK) {
+		q->q_stats.nr_sbals[7]++;
+		return;
+	}
+	while (count >>= 1)
+		pos++;
+	q->q_stats.nr_sbals[pos]++;
+}
+
 static void announce_buffer_error(struct qdio_q *q, int count)
 {
 	q->qdio_error |= QDIO_ERROR_SLSB_STATE;
@@ -487,16 +502,22 @@ static int get_inbound_buffer_frontier(s
 		q->first_to_check = add_buf(q->first_to_check, count);
 		if (atomic_sub(count, &q->nr_buf_used) == 0)
 			qperf_inc(q, inbound_queue_full);
+		if (q->irq_ptr->perf_stat_enabled)
+			account_sbals(q, count);
 		break;
 	case SLSB_P_INPUT_ERROR:
 		announce_buffer_error(q, count);
 		/* process the buffer, the upper layer will take care of it */
 		q->first_to_check = add_buf(q->first_to_check, count);
 		atomic_sub(count, &q->nr_buf_used);
+		if (q->irq_ptr->perf_stat_enabled)
+			account_sbals_error(q, count);
 		break;
 	case SLSB_CU_INPUT_EMPTY:
 	case SLSB_P_INPUT_NOT_INIT:
 	case SLSB_P_INPUT_ACK:
+		if (q->irq_ptr->perf_stat_enabled)
+			q->q_stats.nr_sbal_nop++;
 		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in nop");
 		break;
 	default:
@@ -514,7 +535,7 @@ static int qdio_inbound_q_moved(struct q
 
 	if ((bufnr != q->last_move) || q->qdio_error) {
 		q->last_move = bufnr;
-		if (!is_thinint_irq(q->irq_ptr) && !MACHINE_IS_VM)
+		if (!is_thinint_irq(q->irq_ptr) && MACHINE_IS_LPAR)
 			q->u.in.timestamp = get_usecs();
 		return 1;
 	} else
@@ -568,10 +589,11 @@ static void qdio_kick_handler(struct qdi
 	if (q->is_input_q) {
 		qperf_inc(q, inbound_handler);
 		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count);
-	} else
+	} else {
 		qperf_inc(q, outbound_handler);
 		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x",
 			      start, count);
+	}
 
 	q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
 		   q->irq_ptr->int_parm);
@@ -643,15 +665,21 @@ static int get_outbound_buffer_frontier(
 
 		atomic_sub(count, &q->nr_buf_used);
 		q->first_to_check = add_buf(q->first_to_check, count);
+		if (q->irq_ptr->perf_stat_enabled)
+			account_sbals(q, count);
 		break;
 	case SLSB_P_OUTPUT_ERROR:
 		announce_buffer_error(q, count);
 		/* process the buffer, the upper layer will take care of it */
 		q->first_to_check = add_buf(q->first_to_check, count);
 		atomic_sub(count, &q->nr_buf_used);
+		if (q->irq_ptr->perf_stat_enabled)
+			account_sbals_error(q, count);
 		break;
 	case SLSB_CU_OUTPUT_PRIMED:
 		/* the adapter has not fetched the output yet */
+		if (q->irq_ptr->perf_stat_enabled)
+			q->q_stats.nr_sbal_nop++;
 		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out primed:%1d", q->nr);
 		break;
 	case SLSB_P_OUTPUT_NOT_INIT:
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_setup.c linux-libre-2.6.34-gnu1/drivers/s390/cio/qdio_setup.c
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/qdio_setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -333,10 +333,10 @@ static void __qdio_allocate_fill_qdr(str
 	irq_ptr->qdr->qdf0[i + nr].slsba =
 		(unsigned long)&irq_ptr_qs[i]->slsb.val[0];
 
-	irq_ptr->qdr->qdf0[i + nr].akey = PAGE_DEFAULT_KEY;
-	irq_ptr->qdr->qdf0[i + nr].bkey = PAGE_DEFAULT_KEY;
-	irq_ptr->qdr->qdf0[i + nr].ckey = PAGE_DEFAULT_KEY;
-	irq_ptr->qdr->qdf0[i + nr].dkey = PAGE_DEFAULT_KEY;
+	irq_ptr->qdr->qdf0[i + nr].akey = PAGE_DEFAULT_KEY >> 4;
+	irq_ptr->qdr->qdf0[i + nr].bkey = PAGE_DEFAULT_KEY >> 4;
+	irq_ptr->qdr->qdf0[i + nr].ckey = PAGE_DEFAULT_KEY >> 4;
+	irq_ptr->qdr->qdf0[i + nr].dkey = PAGE_DEFAULT_KEY >> 4;
 }
 
 static void setup_qdr(struct qdio_irq *irq_ptr,
@@ -350,7 +350,7 @@ static void setup_qdr(struct qdio_irq *i
 	irq_ptr->qdr->iqdsz = sizeof(struct qdesfmt0) / 4; /* size in words */
 	irq_ptr->qdr->oqdsz = sizeof(struct qdesfmt0) / 4;
 	irq_ptr->qdr->qiba = (unsigned long)&irq_ptr->qib;
-	irq_ptr->qdr->qkey = PAGE_DEFAULT_KEY;
+	irq_ptr->qdr->qkey = PAGE_DEFAULT_KEY >> 4;
 
 	for (i = 0; i < qdio_init->no_input_qs; i++)
 		__qdio_allocate_fill_qdr(irq_ptr, irq_ptr->input_qs, i, 0);
@@ -382,7 +382,15 @@ int qdio_setup_irq(struct qdio_initializ
 	struct qdio_irq *irq_ptr = init_data->cdev->private->qdio_data;
 	int rc;
 
-	memset(irq_ptr, 0, ((char *)&irq_ptr->qdr) - ((char *)irq_ptr));
+	memset(&irq_ptr->qib, 0, sizeof(irq_ptr->qib));
+	memset(&irq_ptr->siga_flag, 0, sizeof(irq_ptr->siga_flag));
+	memset(&irq_ptr->ccw, 0, sizeof(irq_ptr->ccw));
+	memset(&irq_ptr->ssqd_desc, 0, sizeof(irq_ptr->ssqd_desc));
+	memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat));
+
+	irq_ptr->debugfs_dev = irq_ptr->debugfs_perf = NULL;
+	irq_ptr->sch_token = irq_ptr->state = irq_ptr->perf_stat_enabled = 0;
+
 	/* wipes qib.ac, required by ar7063 */
 	memset(irq_ptr->qdr, 0, sizeof(struct qdr));
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_thinint.c linux-libre-2.6.34-gnu1/drivers/s390/cio/qdio_thinint.c
--- linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_thinint.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/cio/qdio_thinint.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
  *	      Jan Glauber <jang@linux.vnet.ibm.com>
  */
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/debug.h>
 #include <asm/qdio.h>
@@ -198,8 +199,8 @@ static int set_subchannel_ind(struct qdi
 		.code	= 0x0021,
 	};
 	scssc_area->operation_code = 0;
-	scssc_area->ks = PAGE_DEFAULT_KEY;
-	scssc_area->kc = PAGE_DEFAULT_KEY;
+	scssc_area->ks = PAGE_DEFAULT_KEY >> 4;
+	scssc_area->kc = PAGE_DEFAULT_KEY >> 4;
 	scssc_area->isc = QDIO_AIRQ_ISC;
 	scssc_area->schid = irq_ptr->schid;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/crypto/ap_bus.c linux-libre-2.6.34-gnu1/drivers/s390/crypto/ap_bus.c
--- linux-libre-2.6.33-gnu1/drivers/s390/crypto/ap_bus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/crypto/ap_bus.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 #include <linux/notifier.h>
 #include <linux/kthread.h>
 #include <linux/mutex.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_api.c linux-libre-2.6.34-gnu1/drivers/s390/crypto/zcrypt_api.c
--- linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_api.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/crypto/zcrypt_api.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,8 +33,10 @@
 #include <linux/miscdevice.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/compat.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
 #include <linux/hw_random.h>
@@ -912,126 +914,105 @@ static struct miscdevice zcrypt_misc_dev
  */
 static struct proc_dir_entry *zcrypt_entry;
 
-static int sprintcl(unsigned char *outaddr, unsigned char *addr,
-		    unsigned int len)
+static void sprintcl(struct seq_file *m, unsigned char *addr, unsigned int len)
 {
-	int hl, i;
+	int i;
 
-	hl = 0;
 	for (i = 0; i < len; i++)
-		hl += sprintf(outaddr+hl, "%01x", (unsigned int) addr[i]);
-	hl += sprintf(outaddr+hl, " ");
-	return hl;
+		seq_printf(m, "%01x", (unsigned int) addr[i]);
+	seq_putc(m, ' ');
 }
 
-static int sprintrw(unsigned char *outaddr, unsigned char *addr,
-		    unsigned int len)
+static void sprintrw(struct seq_file *m, unsigned char *addr, unsigned int len)
 {
-	int hl, inl, c, cx;
+	int inl, c, cx;
 
-	hl = sprintf(outaddr, "	   ");
+	seq_printf(m, "	   ");
 	inl = 0;
 	for (c = 0; c < (len / 16); c++) {
-		hl += sprintcl(outaddr+hl, addr+inl, 16);
+		sprintcl(m, addr+inl, 16);
 		inl += 16;
 	}
 	cx = len%16;
 	if (cx) {
-		hl += sprintcl(outaddr+hl, addr+inl, cx);
+		sprintcl(m, addr+inl, cx);
 		inl += cx;
 	}
-	hl += sprintf(outaddr+hl, "\n");
-	return hl;
+	seq_putc(m, '\n');
 }
 
-static int sprinthx(unsigned char *title, unsigned char *outaddr,
-		    unsigned char *addr, unsigned int len)
+static void sprinthx(unsigned char *title, struct seq_file *m,
+		     unsigned char *addr, unsigned int len)
 {
-	int hl, inl, r, rx;
+	int inl, r, rx;
 
-	hl = sprintf(outaddr, "\n%s\n", title);
+	seq_printf(m, "\n%s\n", title);
 	inl = 0;
 	for (r = 0; r < (len / 64); r++) {
-		hl += sprintrw(outaddr+hl, addr+inl, 64);
+		sprintrw(m, addr+inl, 64);
 		inl += 64;
 	}
 	rx = len % 64;
 	if (rx) {
-		hl += sprintrw(outaddr+hl, addr+inl, rx);
+		sprintrw(m, addr+inl, rx);
 		inl += rx;
 	}
-	hl += sprintf(outaddr+hl, "\n");
-	return hl;
+	seq_putc(m, '\n');
 }
 
-static int sprinthx4(unsigned char *title, unsigned char *outaddr,
-		     unsigned int *array, unsigned int len)
+static void sprinthx4(unsigned char *title, struct seq_file *m,
+		      unsigned int *array, unsigned int len)
 {
-	int hl, r;
+	int r;
 
-	hl = sprintf(outaddr, "\n%s\n", title);
+	seq_printf(m, "\n%s\n", title);
 	for (r = 0; r < len; r++) {
 		if ((r % 8) == 0)
-			hl += sprintf(outaddr+hl, "    ");
-		hl += sprintf(outaddr+hl, "%08X ", array[r]);
+			seq_printf(m, "    ");
+		seq_printf(m, "%08X ", array[r]);
 		if ((r % 8) == 7)
-			hl += sprintf(outaddr+hl, "\n");
+			seq_putc(m, '\n');
 	}
-	hl += sprintf(outaddr+hl, "\n");
-	return hl;
+	seq_putc(m, '\n');
 }
 
-static int zcrypt_status_read(char *resp_buff, char **start, off_t offset,
-			      int count, int *eof, void *data)
+static int zcrypt_proc_show(struct seq_file *m, void *v)
 {
-	unsigned char *workarea;
-	int len;
-
-	len = 0;
+	char workarea[sizeof(int) * AP_DEVICES];
 
-	/* resp_buff is a page. Use the right half for a work area */
-	workarea = resp_buff + 2000;
-	len += sprintf(resp_buff + len, "\nzcrypt version: %d.%d.%d\n",
-		ZCRYPT_VERSION, ZCRYPT_RELEASE, ZCRYPT_VARIANT);
-	len += sprintf(resp_buff + len, "Cryptographic domain: %d\n",
-		       ap_domain_index);
-	len += sprintf(resp_buff + len, "Total device count: %d\n",
-		       zcrypt_device_count);
-	len += sprintf(resp_buff + len, "PCICA count: %d\n",
-		       zcrypt_count_type(ZCRYPT_PCICA));
-	len += sprintf(resp_buff + len, "PCICC count: %d\n",
-		       zcrypt_count_type(ZCRYPT_PCICC));
-	len += sprintf(resp_buff + len, "PCIXCC MCL2 count: %d\n",
-		       zcrypt_count_type(ZCRYPT_PCIXCC_MCL2));
-	len += sprintf(resp_buff + len, "PCIXCC MCL3 count: %d\n",
-		       zcrypt_count_type(ZCRYPT_PCIXCC_MCL3));
-	len += sprintf(resp_buff + len, "CEX2C count: %d\n",
-		       zcrypt_count_type(ZCRYPT_CEX2C));
-	len += sprintf(resp_buff + len, "CEX2A count: %d\n",
-		       zcrypt_count_type(ZCRYPT_CEX2A));
-	len += sprintf(resp_buff + len, "CEX3C count: %d\n",
-		       zcrypt_count_type(ZCRYPT_CEX3C));
-	len += sprintf(resp_buff + len, "CEX3A count: %d\n",
-		       zcrypt_count_type(ZCRYPT_CEX3A));
-	len += sprintf(resp_buff + len, "requestq count: %d\n",
-		       zcrypt_requestq_count());
-	len += sprintf(resp_buff + len, "pendingq count: %d\n",
-		       zcrypt_pendingq_count());
-	len += sprintf(resp_buff + len, "Total open handles: %d\n\n",
-		       atomic_read(&zcrypt_open_count));
+	seq_printf(m, "\nzcrypt version: %d.%d.%d\n",
+		   ZCRYPT_VERSION, ZCRYPT_RELEASE, ZCRYPT_VARIANT);
+	seq_printf(m, "Cryptographic domain: %d\n", ap_domain_index);
+	seq_printf(m, "Total device count: %d\n", zcrypt_device_count);
+	seq_printf(m, "PCICA count: %d\n", zcrypt_count_type(ZCRYPT_PCICA));
+	seq_printf(m, "PCICC count: %d\n", zcrypt_count_type(ZCRYPT_PCICC));
+	seq_printf(m, "PCIXCC MCL2 count: %d\n",
+		   zcrypt_count_type(ZCRYPT_PCIXCC_MCL2));
+	seq_printf(m, "PCIXCC MCL3 count: %d\n",
+		   zcrypt_count_type(ZCRYPT_PCIXCC_MCL3));
+	seq_printf(m, "CEX2C count: %d\n", zcrypt_count_type(ZCRYPT_CEX2C));
+	seq_printf(m, "CEX2A count: %d\n", zcrypt_count_type(ZCRYPT_CEX2A));
+	seq_printf(m, "CEX3C count: %d\n", zcrypt_count_type(ZCRYPT_CEX3C));
+	seq_printf(m, "CEX3A count: %d\n", zcrypt_count_type(ZCRYPT_CEX3A));
+	seq_printf(m, "requestq count: %d\n", zcrypt_requestq_count());
+	seq_printf(m, "pendingq count: %d\n", zcrypt_pendingq_count());
+	seq_printf(m, "Total open handles: %d\n\n",
+		   atomic_read(&zcrypt_open_count));
 	zcrypt_status_mask(workarea);
-	len += sprinthx("Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) "
-			"4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A 7=CEX3C 8=CEX3A",
-			resp_buff+len, workarea, AP_DEVICES);
+	sprinthx("Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) "
+		 "4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A 7=CEX3C 8=CEX3A",
+		 m, workarea, AP_DEVICES);
 	zcrypt_qdepth_mask(workarea);
-	len += sprinthx("Waiting work element counts",
-			resp_buff+len, workarea, AP_DEVICES);
+	sprinthx("Waiting work element counts", m, workarea, AP_DEVICES);
 	zcrypt_perdev_reqcnt((int *) workarea);
-	len += sprinthx4("Per-device successfully completed request counts",
-			 resp_buff+len,(unsigned int *) workarea, AP_DEVICES);
-	*eof = 1;
-	memset((void *) workarea, 0x00, AP_DEVICES * sizeof(unsigned int));
-	return len;
+	sprinthx4("Per-device successfully completed request counts",
+		  m, (unsigned int *) workarea, AP_DEVICES);
+	return 0;
+}
+
+static int zcrypt_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, zcrypt_proc_show, NULL);
 }
 
 static void zcrypt_disable_card(int index)
@@ -1061,11 +1042,11 @@ static void zcrypt_enable_card(int index
 	spin_unlock_bh(&zcrypt_device_lock);
 }
 
-static int zcrypt_status_write(struct file *file, const char __user *buffer,
-			       unsigned long count, void *data)
+static ssize_t zcrypt_proc_write(struct file *file, const char __user *buffer,
+				 size_t count, loff_t *pos)
 {
 	unsigned char *lbuf, *ptr;
-	unsigned long local_count;
+	size_t local_count;
 	int j;
 
 	if (count <= 0)
@@ -1115,6 +1096,15 @@ out:
 	return count;
 }
 
+static const struct file_operations zcrypt_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= zcrypt_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= zcrypt_proc_write,
+};
+
 static int zcrypt_rng_device_count;
 static u32 *zcrypt_rng_buffer;
 static int zcrypt_rng_buffer_index;
@@ -1197,14 +1187,11 @@ int __init zcrypt_api_init(void)
 		goto out;
 
 	/* Set up the proc file system */
-	zcrypt_entry = create_proc_entry("driver/z90crypt", 0644, NULL);
+	zcrypt_entry = proc_create("driver/z90crypt", 0644, NULL, &zcrypt_proc_fops);
 	if (!zcrypt_entry) {
 		rc = -ENOMEM;
 		goto out_misc;
 	}
-	zcrypt_entry->data = NULL;
-	zcrypt_entry->read_proc = zcrypt_status_read;
-	zcrypt_entry->write_proc = zcrypt_status_write;
 
 	return 0;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_cex2a.c linux-libre-2.6.34-gnu1/drivers/s390/crypto/zcrypt_cex2a.c
--- linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_cex2a.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/crypto/zcrypt_cex2a.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/err.h>
 #include <asm/atomic.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_pcica.c linux-libre-2.6.34-gnu1/drivers/s390/crypto/zcrypt_pcica.c
--- linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_pcica.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/crypto/zcrypt_pcica.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/err.h>
 #include <asm/atomic.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_pcicc.c linux-libre-2.6.34-gnu1/drivers/s390/crypto/zcrypt_pcicc.c
--- linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_pcicc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/crypto/zcrypt_pcicc.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/err.h>
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_pcixcc.c linux-libre-2.6.34-gnu1/drivers/s390/crypto/zcrypt_pcixcc.c
--- linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_pcixcc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/crypto/zcrypt_pcixcc.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/kvm/kvm_virtio.c linux-libre-2.6.34-gnu1/drivers/s390/kvm/kvm_virtio.c
--- linux-libre-2.6.33-gnu1/drivers/s390/kvm/kvm_virtio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/kvm/kvm_virtio.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/err.h>
 #include <linux/virtio.h>
 #include <linux/virtio_config.h>
+#include <linux/slab.h>
 #include <linux/virtio_console.h>
 #include <linux/interrupt.h>
 #include <linux/virtio_ring.h>
@@ -340,11 +341,11 @@ static void kvm_extint_handler(u16 code)
 		return;
 
 	/* The LSB might be overloaded, we have to mask it */
-	vq = (struct virtqueue *) ((*(long *) __LC_PFAULT_INTPARM) & ~1UL);
+	vq = (struct virtqueue *)(S390_lowcore.ext_params2 & ~1UL);
 
 	/* We use the LSB of extparam, to decide, if this interrupt is a config
 	 * change or a "standard" interrupt */
-	config_changed =  (*(int *)  __LC_EXT_PARAMS & 1);
+	config_changed = S390_lowcore.ext_params & 1;
 
 	if (config_changed) {
 		struct virtio_driver *drv;
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_dbug.c linux-libre-2.6.34-gnu1/drivers/s390/net/ctcm_dbug.c
--- linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_dbug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/ctcm_dbug.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/sysctl.h>
 #include <linux/module.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_sysfs.c linux-libre-2.6.34-gnu1/drivers/s390/net/ctcm_sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/ctcm_sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 #include "ctcm_main.h"
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/fsm.c linux-libre-2.6.34-gnu1/drivers/s390/net/fsm.c
--- linux-libre-2.6.33-gnu1/drivers/s390/net/fsm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/fsm.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
 
 #include "fsm.h"
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 
 MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)");
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/Kconfig linux-libre-2.6.34-gnu1/drivers/s390/net/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/s390/net/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,16 @@ config SMSGIUCV
 	  Select this option if you want to be able to receive SMSG messages
 	  from other VM guest systems.
 
+config SMSGIUCV_EVENT
+	tristate "Deliver IUCV special messages as uevents (VM only)"
+	depends on SMSGIUCV
+	help
+	  Select this option to deliver CP special messages (SMSGs) as
+	  uevents.  The driver handles only those special messages that
+	  start with "APP".
+
+	  To compile as a module, choose M. The module name is "smsgiucv_app".
+
 config CLAW
 	tristate "CLAW device support"
 	depends on CCW && NETDEVICES
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/lcs.c linux-libre-2.6.34-gnu1/drivers/s390/net/lcs.c
--- linux-libre-2.6.33-gnu1/drivers/s390/net/lcs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/lcs.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/igmp.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 #include <net/ip.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/Makefile linux-libre-2.6.34-gnu1/drivers/s390/net/Makefile
--- linux-libre-2.6.33-gnu1/drivers/s390/net/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@ ctcm-y += ctcm_main.o ctcm_fsms.o ctcm_m
 obj-$(CONFIG_CTCM) += ctcm.o fsm.o
 obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
 obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
+obj-$(CONFIG_SMSGIUCV_EVENT) += smsgiucv_app.o
 obj-$(CONFIG_LCS) += lcs.o
 obj-$(CONFIG_CLAW) += claw.o
 qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core.h linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_core.h
--- linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_core.h	2010-05-16 17:17:36.000000000 -0400
@@ -649,6 +649,7 @@ struct qeth_card_options {
 	int performance_stats;
 	int rx_sg_cb;
 	enum qeth_ipa_isolation_modes isolation;
+	int sniffer;
 };
 
 /*
@@ -737,6 +738,7 @@ struct qeth_card {
 	struct qeth_discipline discipline;
 	atomic_t force_alloc_skb;
 	struct service_level qeth_service_level;
+	struct qdio_ssqd_desc ssqd;
 };
 
 struct qeth_card_list_struct {
@@ -761,7 +763,8 @@ static inline int qeth_get_micros(void)
 
 static inline int qeth_get_ip_version(struct sk_buff *skb)
 {
-	switch (skb->protocol) {
+	struct ethhdr *ehdr = (struct ethhdr *)skb->data;
+	switch (ehdr->h_proto) {
 	case ETH_P_IPV6:
 		return 6;
 	case ETH_P_IP:
@@ -811,7 +814,8 @@ int qeth_send_ipa_cmd(struct qeth_card *
 struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *,
 			enum qeth_ipa_cmds, enum qeth_prot_versions);
 int qeth_query_setadapterparms(struct qeth_card *);
-int qeth_check_qdio_errors(struct qdio_buffer *, unsigned int, const char *);
+int qeth_check_qdio_errors(struct qeth_card *, struct qdio_buffer *,
+		unsigned int, const char *);
 void qeth_queue_input_buffer(struct qeth_card *, int);
 struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
 		struct qdio_buffer *, struct qdio_buffer_element **, int *,
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core_main.c linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_core_main.c
--- linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_core_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/tcp.h>
 #include <linux/mii.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 #include <asm/ebcdic.h>
 #include <asm/io.h>
@@ -269,6 +270,7 @@ int qeth_realloc_buffer_pool(struct qeth
 	card->qdio.init_pool.buf_count = bufcnt;
 	return qeth_alloc_buffer_pool(card);
 }
+EXPORT_SYMBOL_GPL(qeth_realloc_buffer_pool);
 
 static int qeth_issue_next_read(struct qeth_card *card)
 {
@@ -350,8 +352,10 @@ static struct qeth_ipa_cmd *qeth_check_i
 	if (IS_IPA(iob->data)) {
 		cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
 		if (IS_IPA_REPLY(cmd)) {
-			if (cmd->hdr.command < IPA_CMD_SETCCID ||
-			    cmd->hdr.command > IPA_CMD_MODCCID)
+			if (cmd->hdr.command != IPA_CMD_SETCCID &&
+			    cmd->hdr.command != IPA_CMD_DELCCID &&
+			    cmd->hdr.command != IPA_CMD_MODCCID &&
+			    cmd->hdr.command != IPA_CMD_SET_DIAG_ASS)
 				qeth_issue_ipa_msg(cmd,
 						cmd->hdr.return_code, card);
 			return cmd;
@@ -534,7 +538,8 @@ static void qeth_send_control_data_cb(st
 			dev_err(&card->gdev->dev,
 				"The qeth device is not configured "
 				"for the OSI layer required by z/VM\n");
-		qeth_schedule_recovery(card);
+		else
+			qeth_schedule_recovery(card);
 		goto out;
 	}
 
@@ -1100,11 +1105,6 @@ static int qeth_setup_card(struct qeth_c
 	card->thread_running_mask = 0;
 	INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread);
 	INIT_LIST_HEAD(&card->ip_list);
-	card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL);
-	if (!card->ip_tbd_list) {
-		QETH_DBF_TEXT(SETUP, 0, "iptbdnom");
-		return -ENOMEM;
-	}
 	INIT_LIST_HEAD(card->ip_tbd_list);
 	INIT_LIST_HEAD(&card->cmd_waiter_list);
 	init_waitqueue_head(&card->wait_q);
@@ -1115,8 +1115,6 @@ static int qeth_setup_card(struct qeth_c
 	card->ipato.enabled = 0;
 	card->ipato.invert4 = 0;
 	card->ipato.invert6 = 0;
-	if (card->info.type == QETH_CARD_TYPE_IQD)
-		card->options.checksum_type = NO_CHECKSUMMING;
 	/* init QDIO stuff */
 	qeth_init_qdio_info(card);
 	return 0;
@@ -1138,21 +1136,30 @@ static struct qeth_card *qeth_alloc_card
 	QETH_DBF_TEXT(SETUP, 2, "alloccrd");
 	card = kzalloc(sizeof(struct qeth_card), GFP_DMA|GFP_KERNEL);
 	if (!card)
-		return NULL;
+		goto out;
 	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
-	if (qeth_setup_channel(&card->read)) {
-		kfree(card);
-		return NULL;
-	}
-	if (qeth_setup_channel(&card->write)) {
-		qeth_clean_channel(&card->read);
-		kfree(card);
-		return NULL;
+	card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL);
+	if (!card->ip_tbd_list) {
+		QETH_DBF_TEXT(SETUP, 0, "iptbdnom");
+		goto out_card;
 	}
+	if (qeth_setup_channel(&card->read))
+		goto out_ip;
+	if (qeth_setup_channel(&card->write))
+		goto out_channel;
 	card->options.layer2 = -1;
 	card->qeth_service_level.seq_print = qeth_core_sl_print;
 	register_service_level(&card->qeth_service_level);
 	return card;
+
+out_channel:
+	qeth_clean_channel(&card->read);
+out_ip:
+	kfree(card->ip_tbd_list);
+out_card:
+	kfree(card);
+out:
+	return NULL;
 }
 
 static int qeth_determine_card_type(struct qeth_card *card)
@@ -1355,26 +1362,29 @@ static int qeth_read_conf_data(struct qe
 	return ret;
 }
 
-static int qeth_get_unitaddr(struct qeth_card *card)
+static void qeth_configure_unitaddr(struct qeth_card *card, char *prcd)
 {
-	int length;
-	char *prcd;
-	int rc;
-
-	QETH_DBF_TEXT(SETUP, 2, "getunit");
-	rc = qeth_read_conf_data(card, (void **) &prcd, &length);
-	if (rc) {
-		QETH_DBF_MESSAGE(2, "%s qeth_read_conf_data returned %i\n",
-			dev_name(&card->gdev->dev), rc);
-		return rc;
-	}
+	QETH_DBF_TEXT(SETUP, 2, "cfgunit");
 	card->info.chpid = prcd[30];
 	card->info.unit_addr2 = prcd[31];
 	card->info.cula = prcd[63];
 	card->info.guestlan = ((prcd[0x10] == _ascebc['V']) &&
 			       (prcd[0x11] == _ascebc['M']));
-	kfree(prcd);
-	return 0;
+}
+
+static void qeth_configure_blkt_default(struct qeth_card *card, char *prcd)
+{
+	QETH_DBF_TEXT(SETUP, 2, "cfgblkt");
+
+	if (prcd[74] == 0xF0 && prcd[75] == 0xF0 && prcd[76] == 0xF5) {
+		card->info.blkt.time_total = 250;
+		card->info.blkt.inter_packet = 5;
+		card->info.blkt.inter_packet_jumbo = 15;
+	} else {
+		card->info.blkt.time_total = 0;
+		card->info.blkt.inter_packet = 0;
+		card->info.blkt.inter_packet_jumbo = 0;
+	}
 }
 
 static void qeth_init_tokens(struct qeth_card *card)
@@ -2573,8 +2583,8 @@ int qeth_query_setadapterparms(struct qe
 }
 EXPORT_SYMBOL_GPL(qeth_query_setadapterparms);
 
-int qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error,
-		const char *dbftext)
+int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf,
+		unsigned int qdio_error, const char *dbftext)
 {
 	if (qdio_error) {
 		QETH_DBF_TEXT(TRACE, 2, dbftext);
@@ -2584,7 +2594,11 @@ int qeth_check_qdio_errors(struct qdio_b
 		QETH_DBF_TEXT_(QERR, 2, " F14=%02X",
 			       buf->element[14].flags & 0xff);
 		QETH_DBF_TEXT_(QERR, 2, " qerr=%X", qdio_error);
-		return 1;
+		if ((buf->element[15].flags & 0xff) == 0x12) {
+			card->stats.rx_dropped++;
+			return 0;
+		} else
+			return 1;
 	}
 	return 0;
 }
@@ -2667,7 +2681,7 @@ static int qeth_handle_send_error(struct
 			qdio_err = 1;
 		}
 	}
-	qeth_check_qdio_errors(buffer->buffer, qdio_err, "qouterr");
+	qeth_check_qdio_errors(card, buffer->buffer, qdio_err, "qouterr");
 
 	if (!qdio_err)
 		return QETH_SEND_ERROR_NONE;
@@ -3509,6 +3523,7 @@ void qeth_tx_timeout(struct net_device *
 {
 	struct qeth_card *card;
 
+	QETH_DBF_TEXT(TRACE, 4, "txtimeo");
 	card = dev->ml_priv;
 	card->stats.tx_errors++;
 	qeth_schedule_recovery(card);
@@ -3790,9 +3805,6 @@ static int qeth_qdio_establish(struct qe
 	init_data.input_handler          = card->discipline.input_handler;
 	init_data.output_handler         = card->discipline.output_handler;
 	init_data.int_parm               = (unsigned long) card;
-	init_data.flags                  = QDIO_INBOUND_0COPY_SBALS |
-					   QDIO_OUTBOUND_0COPY_SBALS |
-					   QDIO_USE_OUTBOUND_PCIS;
 	init_data.input_sbal_addr_array  = (void **) in_sbal_ptrs;
 	init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
 
@@ -3847,9 +3859,7 @@ static int qeth_core_driver_group(const
 
 int qeth_core_hardsetup_card(struct qeth_card *card)
 {
-	struct qdio_ssqd_desc *ssqd;
 	int retries = 0;
-	int mpno = 0;
 	int rc;
 
 	QETH_DBF_TEXT(SETUP, 2, "hrdsetup");
@@ -3882,31 +3892,6 @@ retriable:
 		else
 			goto retry;
 	}
-
-	rc = qeth_get_unitaddr(card);
-	if (rc) {
-		QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
-		return rc;
-	}
-
-	ssqd = kmalloc(sizeof(struct qdio_ssqd_desc), GFP_KERNEL);
-	if (!ssqd) {
-		rc = -ENOMEM;
-		goto out;
-	}
-	rc = qdio_get_ssqd_desc(CARD_DDEV(card), ssqd);
-	if (rc == 0)
-		mpno = ssqd->pcnt;
-	kfree(ssqd);
-
-	if (mpno)
-		mpno = min(mpno - 1, QETH_MAX_PORTNO);
-	if (card->info.portno > mpno) {
-		QETH_DBF_MESSAGE(2, "Device %s does not offer port number %d"
-			"\n.", CARD_BUS_ID(card), card->info.portno);
-		rc = -ENODEV;
-		goto out;
-	}
 	qeth_init_tokens(card);
 	qeth_init_func_level(card);
 	rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb);
@@ -3990,7 +3975,7 @@ struct sk_buff *qeth_core_get_next_skb(s
 	struct qdio_buffer_element *element = *__element;
 	int offset = *__offset;
 	struct sk_buff *skb = NULL;
-	int skb_len;
+	int skb_len = 0;
 	void *data_ptr;
 	int data_len;
 	int headroom = 0;
@@ -4009,20 +3994,24 @@ struct sk_buff *qeth_core_get_next_skb(s
 	*hdr = element->addr + offset;
 
 	offset += sizeof(struct qeth_hdr);
-	if (card->options.layer2) {
-		if (card->info.type == QETH_CARD_TYPE_OSN) {
-			skb_len = (*hdr)->hdr.osn.pdu_length;
-			headroom = sizeof(struct qeth_hdr);
-		} else {
-			skb_len = (*hdr)->hdr.l2.pkt_length;
-		}
-	} else {
+	switch ((*hdr)->hdr.l2.id) {
+	case QETH_HEADER_TYPE_LAYER2:
+		skb_len = (*hdr)->hdr.l2.pkt_length;
+		break;
+	case QETH_HEADER_TYPE_LAYER3:
 		skb_len = (*hdr)->hdr.l3.length;
 		if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) ||
 		    (card->info.link_type == QETH_LINK_TYPE_HSTR))
 			headroom = TR_HLEN;
 		else
 			headroom = ETH_HLEN;
+		break;
+	case QETH_HEADER_TYPE_OSN:
+		skb_len = (*hdr)->hdr.osn.pdu_length;
+		headroom = sizeof(struct qeth_hdr);
+		break;
+	default:
+		break;
 	}
 
 	if (!skb_len)
@@ -4177,6 +4166,41 @@ void qeth_core_free_discipline(struct qe
 	card->discipline.ccwgdriver = NULL;
 }
 
+static void qeth_determine_capabilities(struct qeth_card *card)
+{
+	int rc;
+	int length;
+	char *prcd;
+
+	QETH_DBF_TEXT(SETUP, 2, "detcapab");
+	rc = ccw_device_set_online(CARD_DDEV(card));
+	if (rc) {
+		QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
+		goto out;
+	}
+
+
+	rc = qeth_read_conf_data(card, (void **) &prcd, &length);
+	if (rc) {
+		QETH_DBF_MESSAGE(2, "%s qeth_read_conf_data returned %i\n",
+			dev_name(&card->gdev->dev), rc);
+		QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
+		goto out_offline;
+	}
+	qeth_configure_unitaddr(card, prcd);
+	qeth_configure_blkt_default(card, prcd);
+	kfree(prcd);
+
+	rc = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
+	if (rc)
+		QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
+
+out_offline:
+	ccw_device_set_offline(CARD_DDEV(card));
+out:
+	return;
+}
+
 static int qeth_core_probe_device(struct ccwgroup_device *gdev)
 {
 	struct qeth_card *card;
@@ -4242,6 +4266,8 @@ static int qeth_core_probe_device(struct
 	write_lock_irqsave(&qeth_core_card_list.rwlock, flags);
 	list_add_tail(&card->list, &qeth_core_card_list.list);
 	write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
+
+	qeth_determine_capabilities(card);
 	return 0;
 
 err_card:
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core_mpc.h linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_core_mpc.h
--- linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core_mpc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_core_mpc.h	2010-05-16 17:17:36.000000000 -0400
@@ -156,6 +156,8 @@ enum qeth_ipa_return_codes {
 	IPA_RC_IP_TABLE_FULL		= 0x0002,
 	IPA_RC_UNKNOWN_ERROR		= 0x0003,
 	IPA_RC_UNSUPPORTED_COMMAND	= 0x0004,
+	IPA_RC_TRACE_ALREADY_ACTIVE	= 0x0005,
+	IPA_RC_INVALID_FORMAT		= 0x0006,
 	IPA_RC_DUP_IPV6_REMOTE		= 0x0008,
 	IPA_RC_DUP_IPV6_HOME		= 0x0010,
 	IPA_RC_UNREGISTERED_ADDR	= 0x0011,
@@ -196,6 +198,11 @@ enum qeth_ipa_return_codes {
 	IPA_RC_INVALID_IP_VERSION2	= 0xf001,
 	IPA_RC_FFFF			= 0xffff
 };
+/* for DELIP */
+#define IPA_RC_IP_ADDRESS_NOT_DEFINED	IPA_RC_PRIMARY_ALREADY_DEFINED
+/* for SET_DIAGNOSTIC_ASSIST */
+#define IPA_RC_INVALID_SUBCMD		IPA_RC_IP_TABLE_FULL
+#define IPA_RC_HARDWARE_AUTH_ERROR	IPA_RC_UNKNOWN_ERROR
 
 /* IPA function flags; each flag marks availability of respective function */
 enum qeth_ipa_funcs {
@@ -246,6 +253,7 @@ enum qeth_ipa_setadp_cmd {
 	IPA_SETADP_SET_SNMP_CONTROL		= 0x00000200L,
 	IPA_SETADP_QUERY_CARD_INFO		= 0x00000400L,
 	IPA_SETADP_SET_PROMISC_MODE		= 0x00000800L,
+	IPA_SETADP_SET_DIAG_ASSIST		= 0x00002000L,
 	IPA_SETADP_SET_ACCESS_CONTROL		= 0x00010000L,
 };
 enum qeth_ipa_mac_ops {
@@ -424,6 +432,40 @@ struct qeth_create_destroy_address {
 	__u8 unique_id[8];
 } __attribute__ ((packed));
 
+/* SET DIAGNOSTIC ASSIST IPA Command:	 *************************************/
+
+enum qeth_diags_cmds {
+	QETH_DIAGS_CMD_QUERY	= 0x0001,
+	QETH_DIAGS_CMD_TRAP	= 0x0002,
+	QETH_DIAGS_CMD_TRACE	= 0x0004,
+	QETH_DIAGS_CMD_NOLOG	= 0x0008,
+	QETH_DIAGS_CMD_DUMP	= 0x0010,
+};
+
+enum qeth_diags_trace_types {
+	QETH_DIAGS_TYPE_HIPERSOCKET	= 0x02,
+};
+
+enum qeth_diags_trace_cmds {
+	QETH_DIAGS_CMD_TRACE_ENABLE	= 0x0001,
+	QETH_DIAGS_CMD_TRACE_DISABLE	= 0x0002,
+	QETH_DIAGS_CMD_TRACE_MODIFY	= 0x0004,
+	QETH_DIAGS_CMD_TRACE_REPLACE	= 0x0008,
+	QETH_DIAGS_CMD_TRACE_QUERY	= 0x0010,
+};
+
+struct qeth_ipacmd_diagass {
+	__u32  host_tod2;
+	__u32:32;
+	__u16  subcmd_len;
+	__u16:16;
+	__u32  subcmd;
+	__u8   type;
+	__u8   action;
+	__u16  options;
+	__u32:32;
+} __attribute__ ((packed));
+
 /* Header for each IPA command */
 struct qeth_ipacmd_hdr {
 	__u8   command;
@@ -452,6 +494,7 @@ struct qeth_ipa_cmd {
 		struct qeth_create_destroy_address	create_destroy_addr;
 		struct qeth_ipacmd_setadpparms		setadapterparms;
 		struct qeth_set_routing			setrtg;
+		struct qeth_ipacmd_diagass		diagass;
 	} data;
 } __attribute__ ((packed));
 
@@ -469,7 +512,6 @@ enum qeth_ipa_arp_return_codes {
 	QETH_IPA_ARP_RC_Q_NO_DATA    = 0x0008,
 };
 
-
 extern char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc);
 extern char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core_sys.c linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_core_sys.c
--- linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core_sys.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_core_sys.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,9 @@
  *		 Frank Blaschka <frank.blaschka@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "qeth"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/list.h>
 #include <linux/rwsem.h>
 #include <asm/ebcdic.h>
@@ -118,7 +121,7 @@ static ssize_t qeth_dev_portno_store(str
 {
 	struct qeth_card *card = dev_get_drvdata(dev);
 	char *tmp;
-	unsigned int portno;
+	unsigned int portno, limit;
 
 	if (!card)
 		return -EINVAL;
@@ -128,9 +131,11 @@ static ssize_t qeth_dev_portno_store(str
 		return -EPERM;
 
 	portno = simple_strtoul(buf, &tmp, 16);
-	if (portno > QETH_MAX_PORTNO) {
+	if (portno > QETH_MAX_PORTNO)
+		return -EINVAL;
+	limit = (card->ssqd.pcnt ? card->ssqd.pcnt - 1 : card->ssqd.pcnt);
+	if (portno > limit)
 		return -EINVAL;
-	}
 
 	card->info.portno = portno;
 	return count;
@@ -537,7 +542,7 @@ static ssize_t qeth_dev_blkt_total_store
 	struct qeth_card *card = dev_get_drvdata(dev);
 
 	return qeth_dev_blkt_store(card, buf, count,
-				   &card->info.blkt.time_total, 1000);
+				   &card->info.blkt.time_total, 5000);
 }
 
 
@@ -559,7 +564,7 @@ static ssize_t qeth_dev_blkt_inter_store
 	struct qeth_card *card = dev_get_drvdata(dev);
 
 	return qeth_dev_blkt_store(card, buf, count,
-				   &card->info.blkt.inter_packet, 100);
+				   &card->info.blkt.inter_packet, 1000);
 }
 
 static DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show,
@@ -580,7 +585,7 @@ static ssize_t qeth_dev_blkt_inter_jumbo
 	struct qeth_card *card = dev_get_drvdata(dev);
 
 	return qeth_dev_blkt_store(card, buf, count,
-				   &card->info.blkt.inter_packet_jumbo, 100);
+				   &card->info.blkt.inter_packet_jumbo, 1000);
 }
 
 static DEVICE_ATTR(inter_jumbo, 0644, qeth_dev_blkt_inter_jumbo_show,
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l2_main.c linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_l2_main.c
--- linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l2_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_l2_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/etherdevice.h>
 #include <linux/mii.h>
 #include <linux/ip.h>
@@ -486,22 +487,14 @@ static int qeth_l2_send_setmac_cb(struct
 		case IPA_RC_L2_DUP_MAC:
 		case IPA_RC_L2_DUP_LAYER3_MAC:
 			dev_warn(&card->gdev->dev,
-				"MAC address "
-				"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
-				"already exists\n",
-				card->dev->dev_addr[0], card->dev->dev_addr[1],
-				card->dev->dev_addr[2], card->dev->dev_addr[3],
-				card->dev->dev_addr[4], card->dev->dev_addr[5]);
+				"MAC address %pM already exists\n",
+				card->dev->dev_addr);
 			break;
 		case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP:
 		case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP:
 			dev_warn(&card->gdev->dev,
-				"MAC address "
-				"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
-				"is not authorized\n",
-				card->dev->dev_addr[0], card->dev->dev_addr[1],
-				card->dev->dev_addr[2], card->dev->dev_addr[3],
-				card->dev->dev_addr[4], card->dev->dev_addr[5]);
+				"MAC address %pM is not authorized\n",
+				card->dev->dev_addr);
 			break;
 		default:
 			break;
@@ -512,12 +505,8 @@ static int qeth_l2_send_setmac_cb(struct
 		memcpy(card->dev->dev_addr, cmd->data.setdelmac.mac,
 		       OSA_ADDR_LEN);
 		dev_info(&card->gdev->dev,
-			"MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
-			"successfully registered on device %s\n",
-			card->dev->dev_addr[0], card->dev->dev_addr[1],
-			card->dev->dev_addr[2], card->dev->dev_addr[3],
-			card->dev->dev_addr[4], card->dev->dev_addr[5],
-			card->dev->name);
+			"MAC address %pM successfully registered on device %s\n",
+			card->dev->dev_addr, card->dev->name);
 	}
 	return 0;
 }
@@ -634,7 +623,7 @@ static void qeth_l2_set_multicast_list(s
 	for (dm = dev->mc_list; dm; dm = dm->next)
 		qeth_l2_add_mc(card, dm->da_addr, 0);
 
-	list_for_each_entry(ha, &dev->uc.list, list)
+	netdev_for_each_uc_addr(ha, dev)
 		qeth_l2_add_mc(card, ha->addr, 1);
 
 	spin_unlock_bh(&card->mclock);
@@ -781,7 +770,8 @@ static void qeth_l2_qdio_input_handler(s
 		index = i % QDIO_MAX_BUFFERS_PER_Q;
 		buffer = &card->qdio.in_q->bufs[index];
 		if (!(qdio_err &&
-		      qeth_check_qdio_errors(buffer->buffer, qdio_err, "qinerr")))
+		      qeth_check_qdio_errors(card, buffer->buffer, qdio_err,
+					     "qinerr")))
 			qeth_l2_process_inbound_buffer(card, buffer, index);
 		/* clear buffer and give back to hardware */
 		qeth_put_buffer_pool_entry(card, buffer->pool_entry);
@@ -938,7 +928,6 @@ static int __qeth_l2_set_online(struct c
 	QETH_DBF_TEXT(SETUP, 2, "setonlin");
 	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
 
-	qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1);
 	recover_flag = card->state;
 	rc = qeth_core_hardsetup_card(card);
 	if (rc) {
@@ -1083,11 +1072,9 @@ static int qeth_l2_recover(void *ptr)
 		dev_info(&card->gdev->dev,
 			"Device successfully recovered!\n");
 	else {
-		if (card->dev) {
-			rtnl_lock();
-			dev_close(card->dev);
-			rtnl_unlock();
-		}
+		rtnl_lock();
+		dev_close(card->dev);
+		rtnl_unlock();
 		dev_warn(&card->gdev->dev, "The qeth device driver "
 			"failed to recover an error on the device\n");
 	}
@@ -1141,11 +1128,9 @@ static int qeth_l2_pm_resume(struct ccwg
 	if (card->state == CARD_STATE_RECOVER) {
 		rc = __qeth_l2_set_online(card->gdev, 1);
 		if (rc) {
-			if (card->dev) {
-				rtnl_lock();
-				dev_close(card->dev);
-				rtnl_unlock();
-			}
+			rtnl_lock();
+			dev_close(card->dev);
+			rtnl_unlock();
 		}
 	} else
 		rc = __qeth_l2_set_online(card->gdev, 0);
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l3.h linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_l3.h
--- linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l3.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_l3.h	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,8 @@
 
 #include "qeth_core.h"
 
+#define QETH_SNIFF_AVAIL	0x0008
+
 struct qeth_ipaddr {
 	struct list_head entry;
 	enum qeth_ip_types type;
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l3_main.c linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_l3_main.c
--- linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l3_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_l3_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/ipv6.h>
 #include <linux/inetdevice.h>
 #include <linux/igmp.h>
+#include <linux/slab.h>
 
 #include <net/ip.h>
 #include <net/arp.h>
@@ -242,6 +243,8 @@ static int __qeth_l3_insert_ip_todo(stru
 	struct qeth_ipaddr *tmp, *t;
 	int found = 0;
 
+	if (card->options.sniffer)
+		return 0;
 	list_for_each_entry_safe(tmp, t, card->ip_tbd_list, entry) {
 		if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) &&
 		    (tmp->type == QETH_IP_TYPE_DEL_ALL_MC))
@@ -457,6 +460,8 @@ static void qeth_l3_set_ip_addr_list(str
 	QETH_DBF_TEXT(TRACE, 2, "sdiplist");
 	QETH_DBF_HEX(TRACE, 2, &card, sizeof(void *));
 
+	if (card->options.sniffer)
+		return;
 	spin_lock_irqsave(&card->ip_lock, flags);
 	tbd_list = card->ip_tbd_list;
 	card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC);
@@ -495,7 +500,7 @@ static void qeth_l3_set_ip_addr_list(str
 			spin_unlock_irqrestore(&card->ip_lock, flags);
 			rc = qeth_l3_deregister_addr_entry(card, addr);
 			spin_lock_irqsave(&card->ip_lock, flags);
-			if (!rc || (rc == IPA_RC_PRIMARY_ALREADY_DEFINED))
+			if (!rc || (rc == IPA_RC_IP_ADDRESS_NOT_DEFINED))
 				kfree(addr);
 			else
 				list_add_tail(&addr->entry, &card->ip_list);
@@ -513,6 +518,8 @@ static void qeth_l3_clear_ip_list(struct
 	unsigned long flags;
 
 	QETH_DBF_TEXT(TRACE, 4, "clearip");
+	if (recover && card->options.sniffer)
+		return;
 	spin_lock_irqsave(&card->ip_lock, flags);
 	/* clear todo list */
 	list_for_each_entry_safe(addr, tmp, card->ip_tbd_list, entry) {
@@ -1674,6 +1681,80 @@ static int qeth_l3_get_unique_id(struct
 	return rc;
 }
 
+static int
+qeth_diags_trace_cb(struct qeth_card *card, struct qeth_reply *reply,
+			    unsigned long data)
+{
+	struct qeth_ipa_cmd	   *cmd;
+	__u16 rc;
+
+	QETH_DBF_TEXT(SETUP, 2, "diastrcb");
+
+	cmd = (struct qeth_ipa_cmd *)data;
+	rc = cmd->hdr.return_code;
+	if (rc)
+		QETH_DBF_TEXT_(TRACE, 2, "dxter%x", rc);
+	switch (cmd->data.diagass.action) {
+	case QETH_DIAGS_CMD_TRACE_QUERY:
+		break;
+	case QETH_DIAGS_CMD_TRACE_DISABLE:
+		switch (rc) {
+		case 0:
+		case IPA_RC_INVALID_SUBCMD:
+			card->info.promisc_mode = SET_PROMISC_MODE_OFF;
+			dev_info(&card->gdev->dev, "The HiperSockets network "
+				"traffic analyzer is deactivated\n");
+			break;
+		default:
+			break;
+		}
+		break;
+	case QETH_DIAGS_CMD_TRACE_ENABLE:
+		switch (rc) {
+		case 0:
+			card->info.promisc_mode = SET_PROMISC_MODE_ON;
+			dev_info(&card->gdev->dev, "The HiperSockets network "
+				"traffic analyzer is activated\n");
+			break;
+		case IPA_RC_HARDWARE_AUTH_ERROR:
+			dev_warn(&card->gdev->dev, "The device is not "
+				"authorized to run as a HiperSockets network "
+				"traffic analyzer\n");
+			break;
+		case IPA_RC_TRACE_ALREADY_ACTIVE:
+			dev_warn(&card->gdev->dev, "A HiperSockets "
+				"network traffic analyzer is already "
+				"active in the HiperSockets LAN\n");
+			break;
+		default:
+			break;
+		}
+		break;
+	default:
+		QETH_DBF_MESSAGE(2, "Unknown sniffer action (0x%04x) on %s\n",
+			cmd->data.diagass.action, QETH_CARD_IFNAME(card));
+	}
+
+	return 0;
+}
+
+static int
+qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd)
+{
+	struct qeth_cmd_buffer *iob;
+	struct qeth_ipa_cmd    *cmd;
+
+	QETH_DBF_TEXT(SETUP, 2, "diagtrac");
+
+	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
+	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
+	cmd->data.diagass.subcmd_len = 16;
+	cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE;
+	cmd->data.diagass.type = QETH_DIAGS_TYPE_HIPERSOCKET;
+	cmd->data.diagass.action = diags_cmd;
+	return qeth_send_ipa_cmd(card, iob, qeth_diags_trace_cb, NULL);
+}
+
 static void qeth_l3_get_mac_for_ipm(__u32 ipm, char *mac,
 				struct net_device *dev)
 {
@@ -1951,7 +2032,10 @@ static inline __u16 qeth_l3_rebuild_skb(
 		case QETH_CAST_ANYCAST:
 		case QETH_CAST_NOCAST:
 		default:
-			skb->pkt_type = PACKET_HOST;
+			if (card->options.sniffer)
+				skb->pkt_type = PACKET_OTHERHOST;
+			else
+				skb->pkt_type = PACKET_HOST;
 			memcpy(tg_addr, card->dev->dev_addr,
 				card->dev->addr_len);
 		}
@@ -2007,7 +2091,6 @@ static void qeth_l3_process_inbound_buff
 	int offset;
 	__u16 vlan_tag = 0;
 	unsigned int len;
-
 	/* get first element of current buffer */
 	element = (struct qdio_buffer_element *)&buf->buffer->element[0];
 	offset = 0;
@@ -2026,7 +2109,7 @@ static void qeth_l3_process_inbound_buff
 		case QETH_HEADER_TYPE_LAYER3:
 			vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr);
 			len = skb->len;
-			if (vlan_tag)
+			if (vlan_tag && !card->options.sniffer)
 				if (card->vlangrp)
 					vlan_hwaccel_rx(skb, card->vlangrp,
 						vlan_tag);
@@ -2037,6 +2120,16 @@ static void qeth_l3_process_inbound_buff
 			else
 				netif_rx(skb);
 			break;
+		case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */
+			skb->pkt_type = PACKET_HOST;
+			skb->protocol = eth_type_trans(skb, skb->dev);
+			if (card->options.checksum_type == NO_CHECKSUMMING)
+				skb->ip_summed = CHECKSUM_UNNECESSARY;
+			else
+				skb->ip_summed = CHECKSUM_NONE;
+			len = skb->len;
+			netif_receive_skb(skb);
+			break;
 		default:
 			dev_kfree_skb_any(skb);
 			QETH_DBF_TEXT(TRACE, 3, "inbunkno");
@@ -2118,17 +2211,18 @@ static int qeth_l3_stop_card(struct qeth
 	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
 
 	qeth_set_allowed_threads(card, 0, 1);
+	if (card->options.sniffer &&
+	    (card->info.promisc_mode == SET_PROMISC_MODE_ON))
+		qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_DISABLE);
 	if (card->read.state == CH_STATE_UP &&
 	    card->write.state == CH_STATE_UP &&
 	    (card->state == CARD_STATE_UP)) {
 		if (recovery_mode)
 			qeth_l3_stop(card->dev);
 		else {
-			if (card->dev) {
-				rtnl_lock();
-				dev_close(card->dev);
-				rtnl_unlock();
-			}
+			rtnl_lock();
+			dev_close(card->dev);
+			rtnl_unlock();
 		}
 		if (!card->use_hard_stop) {
 			rc = qeth_send_stoplan(card);
@@ -2162,6 +2256,36 @@ static int qeth_l3_stop_card(struct qeth
 	return rc;
 }
 
+/*
+ * test for and Switch promiscuous mode (on or off)
+ *  either for guestlan or HiperSocket Sniffer
+ */
+static void
+qeth_l3_handle_promisc_mode(struct qeth_card *card)
+{
+	struct net_device *dev = card->dev;
+
+	if (((dev->flags & IFF_PROMISC) &&
+	     (card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
+	    (!(dev->flags & IFF_PROMISC) &&
+	     (card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
+		return;
+
+	if (card->info.guestlan) {		/* Guestlan trace */
+		if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
+			qeth_setadp_promisc_mode(card);
+	} else if (card->options.sniffer &&	/* HiperSockets trace */
+		   qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) {
+		if (dev->flags & IFF_PROMISC) {
+			QETH_DBF_TEXT(TRACE, 3, "+promisc");
+			qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_ENABLE);
+		} else {
+			QETH_DBF_TEXT(TRACE, 3, "-promisc");
+			qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_DISABLE);
+		}
+	}
+}
+
 static void qeth_l3_set_multicast_list(struct net_device *dev)
 {
 	struct qeth_card *card = dev->ml_priv;
@@ -2170,15 +2294,17 @@ static void qeth_l3_set_multicast_list(s
 	if (qeth_threads_running(card, QETH_RECOVER_THREAD) &&
 	    (card->state != CARD_STATE_UP))
 		return;
-	qeth_l3_delete_mc_addresses(card);
-	qeth_l3_add_multicast_ipv4(card);
+	if (!card->options.sniffer) {
+		qeth_l3_delete_mc_addresses(card);
+		qeth_l3_add_multicast_ipv4(card);
 #ifdef CONFIG_QETH_IPV6
-	qeth_l3_add_multicast_ipv6(card);
+		qeth_l3_add_multicast_ipv6(card);
 #endif
-	qeth_l3_set_ip_addr_list(card);
-	if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
-		return;
-	qeth_setadp_promisc_mode(card);
+		qeth_l3_set_ip_addr_list(card);
+		if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
+			return;
+	}
+	qeth_l3_handle_promisc_mode(card);
 }
 
 static const char *qeth_l3_arp_get_error_cause(int *rc)
@@ -2777,9 +2903,8 @@ static int qeth_l3_hard_start_xmit(struc
 	int data_offset = -1;
 	int nr_frags;
 
-	if ((card->info.type == QETH_CARD_TYPE_IQD) &&
-	    (skb->protocol != htons(ETH_P_IPV6)) &&
-	    (skb->protocol != htons(ETH_P_IP)))
+	if (((card->info.type == QETH_CARD_TYPE_IQD) && (!ipv)) ||
+	     card->options.sniffer)
 			goto tx_drop;
 
 	if ((card->state != CARD_STATE_UP) || !card->lan_online) {
@@ -2825,14 +2950,14 @@ static int qeth_l3_hard_start_xmit(struc
 		if (data_offset < 0)
 			skb_pull(new_skb, ETH_HLEN);
 	} else {
-		if (new_skb->protocol == htons(ETH_P_IP)) {
+		if (ipv == 4) {
 			if (card->dev->type == ARPHRD_IEEE802_TR)
 				skb_pull(new_skb, TR_HLEN);
 			else
 				skb_pull(new_skb, ETH_HLEN);
 		}
 
-		if (new_skb->protocol == ETH_P_IPV6 && card->vlangrp &&
+		if (ipv == 6 && card->vlangrp &&
 				vlan_tx_tag_present(new_skb)) {
 			skb_push(new_skb, VLAN_HLEN);
 			skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4);
@@ -3155,7 +3280,7 @@ static void qeth_l3_qdio_input_handler(s
 		index = i % QDIO_MAX_BUFFERS_PER_Q;
 		buffer = &card->qdio.in_q->bufs[index];
 		if (!(qdio_err &&
-		      qeth_check_qdio_errors(buffer->buffer,
+		      qeth_check_qdio_errors(card, buffer->buffer,
 					     qdio_err, "qinerr")))
 			qeth_l3_process_inbound_buffer(card, buffer, index);
 		/* clear buffer and give back to hardware */
@@ -3214,8 +3339,6 @@ static int __qeth_l3_set_online(struct c
 	QETH_DBF_TEXT(SETUP, 2, "setonlin");
 	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
 
-	qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1);
-
 	recover_flag = card->state;
 	rc = qeth_core_hardsetup_card(card);
 	if (rc) {
@@ -3250,20 +3373,22 @@ static int __qeth_l3_set_online(struct c
 		goto out_remove;
 	} else
 		card->lan_online = 1;
-	qeth_l3_set_large_send(card, card->options.large_send);
 
 	rc = qeth_l3_setadapter_parms(card);
 	if (rc)
 		QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
-	rc = qeth_l3_start_ipassists(card);
-	if (rc)
-		QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
-	rc = qeth_l3_setrouting_v4(card);
-	if (rc)
-		QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc);
-	rc = qeth_l3_setrouting_v6(card);
-	if (rc)
-		QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
+	if (!card->options.sniffer) {
+		rc = qeth_l3_start_ipassists(card);
+		if (rc)
+			QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
+		qeth_l3_set_large_send(card, card->options.large_send);
+		rc = qeth_l3_setrouting_v4(card);
+		if (rc)
+			QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc);
+		rc = qeth_l3_setrouting_v6(card);
+		if (rc)
+			QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
+	}
 	netif_tx_disable(card->dev);
 
 	rc = qeth_init_qdio_queues(card);
@@ -3410,11 +3535,9 @@ static int qeth_l3_pm_resume(struct ccwg
 	if (card->state == CARD_STATE_RECOVER) {
 		rc = __qeth_l3_set_online(card->gdev, 1);
 		if (rc) {
-			if (card->dev) {
-				rtnl_lock();
-				dev_close(card->dev);
-				rtnl_unlock();
-			}
+			rtnl_lock();
+			dev_close(card->dev);
+			rtnl_unlock();
 		}
 	} else
 		rc = __qeth_l3_set_online(card->gdev, 0);
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l3_sys.c linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_l3_sys.c
--- linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l3_sys.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/qeth_l3_sys.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,8 @@
  *		 Frank Blaschka <frank.blaschka@de.ibm.com>
  */
 
+#include <linux/slab.h>
+
 #include "qeth_l3.h"
 
 #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
@@ -319,6 +321,61 @@ static ssize_t qeth_l3_dev_checksum_stor
 static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
 		qeth_l3_dev_checksum_store);
 
+static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct qeth_card *card = dev_get_drvdata(dev);
+
+	if (!card)
+		return -EINVAL;
+
+	return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0);
+}
+
+static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct qeth_card *card = dev_get_drvdata(dev);
+	int ret;
+	unsigned long i;
+
+	if (!card)
+		return -EINVAL;
+
+	if (card->info.type != QETH_CARD_TYPE_IQD)
+		return -EPERM;
+
+	if ((card->state != CARD_STATE_DOWN) &&
+	    (card->state != CARD_STATE_RECOVER))
+		return -EPERM;
+
+	ret = strict_strtoul(buf, 16, &i);
+	if (ret)
+		return -EINVAL;
+	switch (i) {
+	case 0:
+		card->options.sniffer = i;
+		break;
+	case 1:
+		ret = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
+		if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) {
+			card->options.sniffer = i;
+			if (card->qdio.init_pool.buf_count !=
+					QETH_IN_BUF_COUNT_MAX)
+				qeth_realloc_buffer_pool(card,
+					QETH_IN_BUF_COUNT_MAX);
+			break;
+		} else
+			return -EPERM;
+	default:   /* fall through */
+		return -EINVAL;
+	}
+	return count;
+}
+
+static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
+		qeth_l3_dev_sniffer_store);
+
 static ssize_t qeth_l3_dev_large_send_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
@@ -373,6 +430,7 @@ static struct attribute *qeth_l3_device_
 	&dev_attr_broadcast_mode.attr,
 	&dev_attr_canonical_macaddr.attr,
 	&dev_attr_checksumming.attr,
+	&dev_attr_sniffer.attr,
 	&dev_attr_large_send.attr,
 	NULL,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/smsgiucv_app.c linux-libre-2.6.34-gnu1/drivers/s390/net/smsgiucv_app.c
--- linux-libre-2.6.33-gnu1/drivers/s390/net/smsgiucv_app.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/smsgiucv_app.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,212 @@
+/*
+ * Deliver z/VM CP special messages (SMSG) as uevents.
+ *
+ * The driver registers for z/VM CP special messages with the
+ * "APP" prefix. Incoming messages are delivered to user space
+ * as uevents.
+ *
+ * Copyright IBM Corp. 2010
+ * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+ *
+ */
+#define KMSG_COMPONENT		"smsgiucv_app"
+#define pr_fmt(fmt)		KMSG_COMPONENT ": " fmt
+
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/kobject.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <net/iucv/iucv.h>
+#include "smsgiucv.h"
+
+/* prefix used for SMSG registration */
+#define SMSG_PREFIX		"APP"
+
+/* SMSG related uevent environment variables */
+#define ENV_SENDER_STR		"SMSG_SENDER="
+#define ENV_SENDER_LEN		(strlen(ENV_SENDER_STR) + 8 + 1)
+#define ENV_PREFIX_STR		"SMSG_ID="
+#define ENV_PREFIX_LEN		(strlen(ENV_PREFIX_STR) + \
+				 strlen(SMSG_PREFIX) + 1)
+#define ENV_TEXT_STR		"SMSG_TEXT="
+#define ENV_TEXT_LEN(msg)	(strlen(ENV_TEXT_STR) + strlen((msg)) + 1)
+
+/* z/VM user ID which is permitted to send SMSGs
+ * If the value is undefined or empty (""), special messages are
+ * accepted from any z/VM user ID. */
+static char *sender;
+module_param(sender, charp, 0400);
+MODULE_PARM_DESC(sender, "z/VM user ID from which CP SMSGs are accepted");
+
+/* SMSG device representation */
+static struct device *smsg_app_dev;
+
+/* list element for queuing received messages for delivery */
+struct smsg_app_event {
+	struct list_head list;
+	char *buf;
+	char *envp[4];
+};
+
+/* queue for outgoing uevents */
+static LIST_HEAD(smsg_event_queue);
+static DEFINE_SPINLOCK(smsg_event_queue_lock);
+
+static void smsg_app_event_free(struct smsg_app_event *ev)
+{
+	kfree(ev->buf);
+	kfree(ev);
+}
+
+static struct smsg_app_event *smsg_app_event_alloc(const char *from,
+						   const char *msg)
+{
+	struct smsg_app_event *ev;
+
+	ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
+	if (!ev)
+		return NULL;
+
+	ev->buf = kzalloc(ENV_SENDER_LEN + ENV_PREFIX_LEN +
+			  ENV_TEXT_LEN(msg), GFP_ATOMIC);
+	if (!ev->buf) {
+		kfree(ev);
+		return NULL;
+	}
+
+	/* setting up environment pointers into buf */
+	ev->envp[0] = ev->buf;
+	ev->envp[1] = ev->envp[0] + ENV_SENDER_LEN;
+	ev->envp[2] = ev->envp[1] + ENV_PREFIX_LEN;
+	ev->envp[3] = NULL;
+
+	/* setting up environment: sender, prefix name, and message text */
+	snprintf(ev->envp[0], ENV_SENDER_LEN, ENV_SENDER_STR "%s", from);
+	snprintf(ev->envp[1], ENV_PREFIX_LEN, ENV_PREFIX_STR "%s", SMSG_PREFIX);
+	snprintf(ev->envp[2], ENV_TEXT_LEN(msg), ENV_TEXT_STR "%s", msg);
+
+	return ev;
+}
+
+static void smsg_event_work_fn(struct work_struct *work)
+{
+	LIST_HEAD(event_queue);
+	struct smsg_app_event *p, *n;
+	struct device *dev;
+
+	dev = get_device(smsg_app_dev);
+	if (!dev)
+		return;
+
+	spin_lock_bh(&smsg_event_queue_lock);
+	list_splice_init(&smsg_event_queue, &event_queue);
+	spin_unlock_bh(&smsg_event_queue_lock);
+
+	list_for_each_entry_safe(p, n, &event_queue, list) {
+		list_del(&p->list);
+		kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, p->envp);
+		smsg_app_event_free(p);
+	}
+
+	put_device(dev);
+}
+static DECLARE_WORK(smsg_event_work, smsg_event_work_fn);
+
+static void smsg_app_callback(const char *from, char *msg)
+{
+	struct smsg_app_event *se;
+
+	/* check if the originating z/VM user ID matches
+	 * the configured sender. */
+	if (sender && strlen(sender) > 0 && strcmp(from, sender) != 0)
+		return;
+
+	/* get start of message text (skip prefix and leading blanks) */
+	msg += strlen(SMSG_PREFIX);
+	while (*msg && isspace(*msg))
+		msg++;
+	if (*msg == '\0')
+		return;
+
+	/* allocate event list element and its environment */
+	se = smsg_app_event_alloc(from, msg);
+	if (!se)
+		return;
+
+	/* queue event and schedule work function */
+	spin_lock(&smsg_event_queue_lock);
+	list_add_tail(&se->list, &smsg_event_queue);
+	spin_unlock(&smsg_event_queue_lock);
+
+	schedule_work(&smsg_event_work);
+	return;
+}
+
+static int __init smsgiucv_app_init(void)
+{
+	struct device_driver *smsgiucv_drv;
+	int rc;
+
+	if (!MACHINE_IS_VM)
+		return -ENODEV;
+
+	smsg_app_dev = kzalloc(sizeof(*smsg_app_dev), GFP_KERNEL);
+	if (!smsg_app_dev)
+		return -ENOMEM;
+
+	smsgiucv_drv = driver_find(SMSGIUCV_DRV_NAME, &iucv_bus);
+	if (!smsgiucv_drv) {
+		kfree(smsg_app_dev);
+		return -ENODEV;
+	}
+
+	rc = dev_set_name(smsg_app_dev, KMSG_COMPONENT);
+	if (rc) {
+		kfree(smsg_app_dev);
+		goto fail_put_driver;
+	}
+	smsg_app_dev->bus = &iucv_bus;
+	smsg_app_dev->parent = iucv_root;
+	smsg_app_dev->release = (void (*)(struct device *)) kfree;
+	smsg_app_dev->driver = smsgiucv_drv;
+	rc = device_register(smsg_app_dev);
+	if (rc) {
+		put_device(smsg_app_dev);
+		goto fail_put_driver;
+	}
+
+	/* register with the smsgiucv device driver */
+	rc = smsg_register_callback(SMSG_PREFIX, smsg_app_callback);
+	if (rc) {
+		device_unregister(smsg_app_dev);
+		goto fail_put_driver;
+	}
+
+	rc = 0;
+fail_put_driver:
+	put_driver(smsgiucv_drv);
+	return rc;
+}
+module_init(smsgiucv_app_init);
+
+static void __exit smsgiucv_app_exit(void)
+{
+	/* unregister callback */
+	smsg_unregister_callback(SMSG_PREFIX, smsg_app_callback);
+
+	/* cancel pending work and flush any queued event work */
+	cancel_work_sync(&smsg_event_work);
+	smsg_event_work_fn(&smsg_event_work);
+
+	device_unregister(smsg_app_dev);
+}
+module_exit(smsgiucv_app_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Deliver z/VM CP SMSG as uevents");
+MODULE_AUTHOR("Hendrik Brueckner <brueckner@linux.vnet.ibm.com>");
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/smsgiucv.c linux-libre-2.6.34-gnu1/drivers/s390/net/smsgiucv.c
--- linux-libre-2.6.33-gnu1/drivers/s390/net/smsgiucv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/smsgiucv.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <net/iucv/iucv.h>
 #include <asm/cpcmd.h>
 #include <asm/ebcdic.h>
@@ -31,9 +32,9 @@
 
 struct smsg_callback {
 	struct list_head list;
-	char *prefix;
+	const char *prefix;
 	int len;
-	void (*callback)(char *from, char *str);
+	void (*callback)(const char *from, char *str);
 };
 
 MODULE_AUTHOR
@@ -100,8 +101,8 @@ static void smsg_message_pending(struct
 	kfree(buffer);
 }
 
-int smsg_register_callback(char *prefix,
-			   void (*callback)(char *from, char *str))
+int smsg_register_callback(const char *prefix,
+			   void (*callback)(const char *from, char *str))
 {
 	struct smsg_callback *cb;
 
@@ -117,8 +118,9 @@ int smsg_register_callback(char *prefix,
 	return 0;
 }
 
-void smsg_unregister_callback(char *prefix,
-			      void (*callback)(char *from, char *str))
+void smsg_unregister_callback(const char *prefix,
+			      void (*callback)(const char *from,
+					       char *str))
 {
 	struct smsg_callback *cb, *tmp;
 
@@ -176,7 +178,7 @@ static const struct dev_pm_ops smsg_pm_o
 
 static struct device_driver smsg_driver = {
 	.owner = THIS_MODULE,
-	.name = "SMSGIUCV",
+	.name = SMSGIUCV_DRV_NAME,
 	.bus  = &iucv_bus,
 	.pm = &smsg_pm_ops,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/net/smsgiucv.h linux-libre-2.6.34-gnu1/drivers/s390/net/smsgiucv.h
--- linux-libre-2.6.33-gnu1/drivers/s390/net/smsgiucv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/net/smsgiucv.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,10 @@
  * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
  */
 
-int  smsg_register_callback(char *, void (*)(char *, char *));
-void smsg_unregister_callback(char *, void (*)(char *, char *));
+#define SMSGIUCV_DRV_NAME     "SMSGIUCV"
+
+int  smsg_register_callback(const char *,
+			    void (*)(const char *, char *));
+void smsg_unregister_callback(const char *,
+			      void (*)(const char *, char *));
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_aux.c linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_aux.c
--- linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_aux.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_aux.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,7 @@
  *
  * Module interface and handling of zfcp data structures.
  *
- * Copyright IBM Corporation 2002, 2009
+ * Copyright IBM Corporation 2002, 2010
  */
 
 /*
@@ -30,8 +30,10 @@
 
 #include <linux/miscdevice.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "zfcp_ext.h"
 #include "zfcp_fc.h"
+#include "zfcp_reqlist.h"
 
 #define ZFCP_BUS_ID_SIZE	20
 
@@ -49,36 +51,6 @@ static struct kmem_cache *zfcp_cache_hw_
 	return kmem_cache_create(name, size, roundup_pow_of_two(size), 0, NULL);
 }
 
-static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter)
-{
-	int idx;
-
-	adapter->req_list = kcalloc(REQUEST_LIST_SIZE, sizeof(struct list_head),
-				    GFP_KERNEL);
-	if (!adapter->req_list)
-		return -ENOMEM;
-
-	for (idx = 0; idx < REQUEST_LIST_SIZE; idx++)
-		INIT_LIST_HEAD(&adapter->req_list[idx]);
-	return 0;
-}
-
-/**
- * zfcp_reqlist_isempty - is the request list empty
- * @adapter: pointer to struct zfcp_adapter
- *
- * Returns: true if list is empty, false otherwise
- */
-int zfcp_reqlist_isempty(struct zfcp_adapter *adapter)
-{
-	unsigned int idx;
-
-	for (idx = 0; idx < REQUEST_LIST_SIZE; idx++)
-		if (!list_empty(&adapter->req_list[idx]))
-			return 0;
-	return 1;
-}
-
 static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
 {
 	struct ccw_device *cdev;
@@ -110,7 +82,7 @@ static void __init zfcp_init_device_conf
 	flush_work(&unit->scsi_work);
 
 out_unit:
-	put_device(&port->sysfs_device);
+	put_device(&port->dev);
 out_port:
 	zfcp_ccw_adapter_put(adapter);
 out_ccw_device:
@@ -255,7 +227,7 @@ struct zfcp_unit *zfcp_get_unit_by_lun(s
 	read_lock_irqsave(&port->unit_list_lock, flags);
 	list_for_each_entry(unit, &port->unit_list, list)
 		if (unit->fcp_lun == fcp_lun) {
-			if (!get_device(&unit->sysfs_device))
+			if (!get_device(&unit->dev))
 				unit = NULL;
 			read_unlock_irqrestore(&port->unit_list_lock, flags);
 			return unit;
@@ -280,7 +252,7 @@ struct zfcp_port *zfcp_get_port_by_wwpn(
 	read_lock_irqsave(&adapter->port_list_lock, flags);
 	list_for_each_entry(port, &adapter->port_list, list)
 		if (port->wwpn == wwpn) {
-			if (!get_device(&port->sysfs_device))
+			if (!get_device(&port->dev))
 				port = NULL;
 			read_unlock_irqrestore(&adapter->port_list_lock, flags);
 			return port;
@@ -298,10 +270,9 @@ struct zfcp_port *zfcp_get_port_by_wwpn(
  */
 static void zfcp_unit_release(struct device *dev)
 {
-	struct zfcp_unit *unit = container_of(dev, struct zfcp_unit,
-					      sysfs_device);
+	struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev);
 
-	put_device(&unit->port->sysfs_device);
+	put_device(&unit->port->dev);
 	kfree(unit);
 }
 
@@ -318,11 +289,11 @@ struct zfcp_unit *zfcp_unit_enqueue(stru
 	struct zfcp_unit *unit;
 	int retval = -ENOMEM;
 
-	get_device(&port->sysfs_device);
+	get_device(&port->dev);
 
 	unit = zfcp_get_unit_by_lun(port, fcp_lun);
 	if (unit) {
-		put_device(&unit->sysfs_device);
+		put_device(&unit->dev);
 		retval = -EEXIST;
 		goto err_out;
 	}
@@ -333,10 +304,10 @@ struct zfcp_unit *zfcp_unit_enqueue(stru
 
 	unit->port = port;
 	unit->fcp_lun = fcp_lun;
-	unit->sysfs_device.parent = &port->sysfs_device;
-	unit->sysfs_device.release = zfcp_unit_release;
+	unit->dev.parent = &port->dev;
+	unit->dev.release = zfcp_unit_release;
 
-	if (dev_set_name(&unit->sysfs_device, "0x%016llx",
+	if (dev_set_name(&unit->dev, "0x%016llx",
 			 (unsigned long long) fcp_lun)) {
 		kfree(unit);
 		goto err_out;
@@ -353,13 +324,12 @@ struct zfcp_unit *zfcp_unit_enqueue(stru
 	unit->latencies.cmd.channel.min = 0xFFFFFFFF;
 	unit->latencies.cmd.fabric.min = 0xFFFFFFFF;
 
-	if (device_register(&unit->sysfs_device)) {
-		put_device(&unit->sysfs_device);
+	if (device_register(&unit->dev)) {
+		put_device(&unit->dev);
 		goto err_out;
 	}
 
-	if (sysfs_create_group(&unit->sysfs_device.kobj,
-			       &zfcp_sysfs_unit_attrs))
+	if (sysfs_create_group(&unit->dev.kobj, &zfcp_sysfs_unit_attrs))
 		goto err_out_put;
 
 	write_lock_irq(&port->unit_list_lock);
@@ -371,9 +341,9 @@ struct zfcp_unit *zfcp_unit_enqueue(stru
 	return unit;
 
 err_out_put:
-	device_unregister(&unit->sysfs_device);
+	device_unregister(&unit->dev);
 err_out:
-	put_device(&port->sysfs_device);
+	put_device(&port->dev);
 	return ERR_PTR(retval);
 }
 
@@ -539,7 +509,8 @@ struct zfcp_adapter *zfcp_adapter_enqueu
 	if (zfcp_allocate_low_mem_buffers(adapter))
 		goto failed;
 
-	if (zfcp_reqlist_alloc(adapter))
+	adapter->req_list = zfcp_reqlist_alloc();
+	if (!adapter->req_list)
 		goto failed;
 
 	if (zfcp_dbf_adapter_register(adapter))
@@ -560,8 +531,6 @@ struct zfcp_adapter *zfcp_adapter_enqueu
 	INIT_LIST_HEAD(&adapter->erp_ready_head);
 	INIT_LIST_HEAD(&adapter->erp_running_head);
 
-	spin_lock_init(&adapter->req_list_lock);
-
 	rwlock_init(&adapter->erp_lock);
 	rwlock_init(&adapter->abort_lock);
 
@@ -640,8 +609,7 @@ void zfcp_device_unregister(struct devic
 
 static void zfcp_port_release(struct device *dev)
 {
-	struct zfcp_port *port = container_of(dev, struct zfcp_port,
-					      sysfs_device);
+	struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
 
 	zfcp_ccw_adapter_put(port->adapter);
 	kfree(port);
@@ -669,7 +637,7 @@ struct zfcp_port *zfcp_port_enqueue(stru
 
 	port = zfcp_get_port_by_wwpn(adapter, wwpn);
 	if (port) {
-		put_device(&port->sysfs_device);
+		put_device(&port->dev);
 		retval = -EEXIST;
 		goto err_out;
 	}
@@ -689,22 +657,21 @@ struct zfcp_port *zfcp_port_enqueue(stru
 	port->d_id = d_id;
 	port->wwpn = wwpn;
 	port->rport_task = RPORT_NONE;
-	port->sysfs_device.parent = &adapter->ccw_device->dev;
-	port->sysfs_device.release = zfcp_port_release;
+	port->dev.parent = &adapter->ccw_device->dev;
+	port->dev.release = zfcp_port_release;
 
-	if (dev_set_name(&port->sysfs_device, "0x%016llx",
-			 (unsigned long long)wwpn)) {
+	if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) {
 		kfree(port);
 		goto err_out;
 	}
 	retval = -EINVAL;
 
-	if (device_register(&port->sysfs_device)) {
-		put_device(&port->sysfs_device);
+	if (device_register(&port->dev)) {
+		put_device(&port->dev);
 		goto err_out;
 	}
 
-	if (sysfs_create_group(&port->sysfs_device.kobj,
+	if (sysfs_create_group(&port->dev.kobj,
 			       &zfcp_sysfs_port_attrs))
 		goto err_out_put;
 
@@ -717,7 +684,7 @@ struct zfcp_port *zfcp_port_enqueue(stru
 	return port;
 
 err_out_put:
-	device_unregister(&port->sysfs_device);
+	device_unregister(&port->dev);
 err_out:
 	zfcp_ccw_adapter_put(adapter);
 	return ERR_PTR(retval);
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_ccw.c linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_ccw.c
--- linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_ccw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_ccw.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,13 +3,14 @@
  *
  * Registration and callback for the s390 common I/O layer.
  *
- * Copyright IBM Corporation 2002, 2009
+ * Copyright IBM Corporation 2002, 2010
  */
 
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include "zfcp_ext.h"
+#include "zfcp_reqlist.h"
 
 #define ZFCP_MODEL_PRIV 0x4
 
@@ -122,12 +123,10 @@ static void zfcp_ccw_remove(struct ccw_d
 	zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */
 
 	list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
-		zfcp_device_unregister(&unit->sysfs_device,
-				       &zfcp_sysfs_unit_attrs);
+		zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs);
 
 	list_for_each_entry_safe(port, p, &port_remove_lh, list)
-		zfcp_device_unregister(&port->sysfs_device,
-				       &zfcp_sysfs_port_attrs);
+		zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs);
 
 	zfcp_adapter_unregister(adapter);
 }
@@ -162,7 +161,7 @@ static int zfcp_ccw_set_online(struct cc
 	}
 
 	/* initialize request counter */
-	BUG_ON(!zfcp_reqlist_isempty(adapter));
+	BUG_ON(!zfcp_reqlist_isempty(adapter->req_list));
 	adapter->req_no = 0;
 
 	zfcp_erp_modify_adapter_status(adapter, "ccsonl1", NULL,
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_cfdc.c linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_cfdc.c
--- linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_cfdc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_cfdc.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/miscdevice.h>
 #include <asm/compat.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_dbf.c linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_dbf.c
--- linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_dbf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_dbf.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <asm/debug.h>
 #include "zfcp_dbf.h"
 #include "zfcp_ext.h"
@@ -140,9 +141,9 @@ void _zfcp_dbf_hba_fsf_response(const ch
 	memcpy(response->fsf_status_qual,
 	       fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE);
 	response->fsf_req_status = fsf_req->status;
-	response->sbal_first = fsf_req->queue_req.sbal_first;
-	response->sbal_last = fsf_req->queue_req.sbal_last;
-	response->sbal_response = fsf_req->queue_req.sbal_response;
+	response->sbal_first = fsf_req->qdio_req.sbal_first;
+	response->sbal_last = fsf_req->qdio_req.sbal_last;
+	response->sbal_response = fsf_req->qdio_req.sbal_response;
 	response->pool = fsf_req->pool != NULL;
 	response->erp_action = (unsigned long)fsf_req->erp_action;
 
@@ -576,7 +577,8 @@ void zfcp_dbf_rec_adapter(char *id, void
 	struct zfcp_adapter *adapter = dbf->adapter;
 
 	zfcp_dbf_rec_target(id, ref, dbf, &adapter->status,
-				  &adapter->erp_counter, 0, 0, 0);
+			    &adapter->erp_counter, 0, 0,
+			    ZFCP_DBF_INVALID_LUN);
 }
 
 /**
@@ -590,8 +592,8 @@ void zfcp_dbf_rec_port(char *id, void *r
 	struct zfcp_dbf *dbf = port->adapter->dbf;
 
 	zfcp_dbf_rec_target(id, ref, dbf, &port->status,
-				  &port->erp_counter, port->wwpn, port->d_id,
-				  0);
+			    &port->erp_counter, port->wwpn, port->d_id,
+			    ZFCP_DBF_INVALID_LUN);
 }
 
 /**
@@ -642,10 +644,9 @@ void zfcp_dbf_rec_trigger(char *id2, voi
 		r->u.trigger.ps = atomic_read(&port->status);
 		r->u.trigger.wwpn = port->wwpn;
 	}
-	if (unit) {
+	if (unit)
 		r->u.trigger.us = atomic_read(&unit->status);
-		r->u.trigger.fcp_lun = unit->fcp_lun;
-	}
+	r->u.trigger.fcp_lun = unit ? unit->fcp_lun : ZFCP_DBF_INVALID_LUN;
 	debug_event(dbf->rec, action ? 1 : 4, r, sizeof(*r));
 	spin_unlock_irqrestore(&dbf->rec_lock, flags);
 }
@@ -668,7 +669,7 @@ void zfcp_dbf_rec_action(char *id2, stru
 	r->u.action.action = (unsigned long)erp_action;
 	r->u.action.status = erp_action->status;
 	r->u.action.step = erp_action->step;
-	r->u.action.fsf_req = (unsigned long)erp_action->fsf_req;
+	r->u.action.fsf_req = erp_action->fsf_req_id;
 	debug_event(dbf->rec, 5, r, sizeof(*r));
 	spin_unlock_irqrestore(&dbf->rec_lock, flags);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_dbf.h linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_dbf.h
--- linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_dbf.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_dbf.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,8 @@
 #define ZFCP_DBF_TAG_SIZE      4
 #define ZFCP_DBF_ID_SIZE       7
 
+#define ZFCP_DBF_INVALID_LUN	0xFFFFFFFFFFFFFFFFull
+
 struct zfcp_dbf_dump {
 	u8 tag[ZFCP_DBF_TAG_SIZE];
 	u32 total_size;		/* size of total dump data */
@@ -192,10 +194,10 @@ struct zfcp_dbf_san_record {
 		struct zfcp_dbf_san_record_ct_response ct_resp;
 		struct zfcp_dbf_san_record_els els;
 	} u;
-#define ZFCP_DBF_SAN_MAX_PAYLOAD 1024
-	u8 payload[32];
 } __attribute__ ((packed));
 
+#define ZFCP_DBF_SAN_MAX_PAYLOAD 1024
+
 struct zfcp_dbf_scsi_record {
 	u8 tag[ZFCP_DBF_TAG_SIZE];
 	u8 tag2[ZFCP_DBF_TAG_SIZE];
@@ -301,17 +303,31 @@ void zfcp_dbf_scsi(const char *tag, cons
 
 /**
  * zfcp_dbf_scsi_result - trace event for SCSI command completion
- * @tag: tag indicating success or failure of SCSI command
- * @level: trace level applicable for this event
- * @adapter: adapter that has been used to issue the SCSI command
+ * @dbf: adapter dbf trace
  * @scmd: SCSI command pointer
- * @fsf_req: request used to issue SCSI command (might be NULL)
+ * @req: FSF request used to issue SCSI command
  */
 static inline
-void zfcp_dbf_scsi_result(const char *tag, int level, struct zfcp_dbf *dbf,
-			  struct scsi_cmnd *scmd, struct zfcp_fsf_req *fsf_req)
+void zfcp_dbf_scsi_result(struct zfcp_dbf *dbf, struct scsi_cmnd *scmd,
+			  struct zfcp_fsf_req *req)
 {
-	zfcp_dbf_scsi("rslt", tag, level, dbf, scmd, fsf_req, 0);
+	if (scmd->result != 0)
+		zfcp_dbf_scsi("rslt", "erro", 3, dbf, scmd, req, 0);
+	else if (scmd->retries > 0)
+		zfcp_dbf_scsi("rslt", "retr", 4, dbf, scmd, req, 0);
+	else
+		zfcp_dbf_scsi("rslt", "norm", 6, dbf, scmd, req, 0);
+}
+
+/**
+ * zfcp_dbf_scsi_fail_send - trace event for failure to send SCSI command
+ * @dbf: adapter dbf trace
+ * @scmd: SCSI command pointer
+ */
+static inline
+void zfcp_dbf_scsi_fail_send(struct zfcp_dbf *dbf, struct scsi_cmnd *scmd)
+{
+	zfcp_dbf_scsi("rslt", "fail", 4, dbf, scmd, NULL, 0);
 }
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_def.h linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_def.h
--- linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_def.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_def.h	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,7 @@
  *
  * Global definitions for the zfcp device driver.
  *
- * Copyright IBM Corporation 2002, 2009
+ * Copyright IBM Corporation 2002, 2010
  */
 
 #ifndef ZFCP_DEF_H
@@ -33,15 +33,13 @@
 #include <scsi/scsi_transport_fc.h>
 #include <scsi/scsi_bsg_fc.h>
 #include <asm/ccwdev.h>
-#include <asm/qdio.h>
 #include <asm/debug.h>
 #include <asm/ebcdic.h>
 #include <asm/sysinfo.h>
 #include "zfcp_fsf.h"
+#include "zfcp_qdio.h"
 
-/********************* GENERAL DEFINES *********************************/
-
-#define REQUEST_LIST_SIZE 128
+struct zfcp_reqlist;
 
 /********************* SCSI SPECIFIC DEFINES *********************************/
 #define ZFCP_SCSI_ER_TIMEOUT                    (10*HZ)
@@ -129,12 +127,6 @@ struct zfcp_adapter_mempool {
 	mempool_t *qtcb_pool;
 };
 
-struct zfcp_qdio_queue {
-	struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q];
-	u8		   first;	/* index of next free bfr in queue */
-	atomic_t           count;	/* number of free buffers in queue */
-};
-
 struct zfcp_erp_action {
 	struct list_head list;
 	int action;	              /* requested action code */
@@ -143,8 +135,7 @@ struct zfcp_erp_action {
 	struct zfcp_unit *unit;
 	u32		status;	      /* recovery status */
 	u32 step;	              /* active step of this erp action */
-	struct zfcp_fsf_req *fsf_req; /* fsf request currently pending
-					 for this action */
+	unsigned long		fsf_req_id;
 	struct timer_list timer;
 };
 
@@ -167,29 +158,6 @@ struct zfcp_latencies {
 	spinlock_t lock;
 };
 
-/** struct zfcp_qdio - basic QDIO data structure
- * @resp_q: response queue
- * @req_q: request queue
- * @stat_lock: lock to protect req_q_util and req_q_time
- * @req_q_lock; lock to serialize access to request queue
- * @req_q_time: time of last fill level change
- * @req_q_util: used for accounting
- * @req_q_full: queue full incidents
- * @req_q_wq: used to wait for SBAL availability
- * @adapter: adapter used in conjunction with this QDIO structure
- */
-struct zfcp_qdio {
-	struct zfcp_qdio_queue	resp_q;
-	struct zfcp_qdio_queue	req_q;
-	spinlock_t		stat_lock;
-	spinlock_t		req_q_lock;
-	unsigned long long	req_q_time;
-	u64			req_q_util;
-	atomic_t		req_q_full;
-	wait_queue_head_t	req_q_wq;
-	struct zfcp_adapter	*adapter;
-};
-
 struct zfcp_adapter {
 	struct kref		ref;
 	u64			peer_wwnn;	   /* P2P peer WWNN */
@@ -207,8 +175,7 @@ struct zfcp_adapter {
 	struct list_head	port_list;	   /* remote port list */
 	rwlock_t		port_list_lock;    /* port list lock */
 	unsigned long		req_no;		   /* unique FSF req number */
-	struct list_head	*req_list;	   /* list of pending reqs */
-	spinlock_t		req_list_lock;	   /* request list lock */
+	struct zfcp_reqlist	*req_list;
 	u32			fsf_req_seq_no;	   /* FSF cmnd seq number */
 	rwlock_t		abort_lock;        /* Protects against SCSI
 						      stack abort/command
@@ -241,7 +208,7 @@ struct zfcp_adapter {
 };
 
 struct zfcp_port {
-	struct device          sysfs_device;   /* sysfs device */
+	struct device          dev;
 	struct fc_rport        *rport;         /* rport of fc transport class */
 	struct list_head       list;	       /* list of remote ports */
 	struct zfcp_adapter    *adapter;       /* adapter used to access port */
@@ -263,7 +230,7 @@ struct zfcp_port {
 };
 
 struct zfcp_unit {
-	struct device          sysfs_device;   /* sysfs device */
+	struct device          dev;
 	struct list_head       list;	       /* list of logical units */
 	struct zfcp_port       *port;	       /* remote port of unit */
 	atomic_t	       status;	       /* status of this logical unit */
@@ -277,33 +244,11 @@ struct zfcp_unit {
 };
 
 /**
- * struct zfcp_queue_req - queue related values for a request
- * @sbal_number: number of free SBALs
- * @sbal_first: first SBAL for this request
- * @sbal_last: last SBAL for this request
- * @sbal_limit: last possible SBAL for this request
- * @sbale_curr: current SBALE at creation of this request
- * @sbal_response: SBAL used in interrupt
- * @qdio_outb_usage: usage of outbound queue
- * @qdio_inb_usage: usage of inbound queue
- */
-struct zfcp_queue_req {
-	u8		       sbal_number;
-	u8		       sbal_first;
-	u8		       sbal_last;
-	u8		       sbal_limit;
-	u8		       sbale_curr;
-	u8		       sbal_response;
-	u16		       qdio_outb_usage;
-	u16		       qdio_inb_usage;
-};
-
-/**
  * struct zfcp_fsf_req - basic FSF request structure
  * @list: list of FSF requests
  * @req_id: unique request ID
  * @adapter: adapter this request belongs to
- * @queue_req: queue related values
+ * @qdio_req: qdio queue related values
  * @completion: used to signal the completion of the request
  * @status: status of the request
  * @fsf_command: FSF command issued
@@ -321,7 +266,7 @@ struct zfcp_fsf_req {
 	struct list_head	list;
 	unsigned long		req_id;
 	struct zfcp_adapter	*adapter;
-	struct zfcp_queue_req	queue_req;
+	struct zfcp_qdio_req	qdio_req;
 	struct completion	completion;
 	u32			status;
 	u32			fsf_command;
@@ -352,45 +297,4 @@ struct zfcp_data {
 #define ZFCP_SET                0x00000100
 #define ZFCP_CLEAR              0x00000200
 
-/*
- * Helper functions for request ID management.
- */
-static inline int zfcp_reqlist_hash(unsigned long req_id)
-{
-	return req_id % REQUEST_LIST_SIZE;
-}
-
-static inline void zfcp_reqlist_remove(struct zfcp_adapter *adapter,
-				       struct zfcp_fsf_req *fsf_req)
-{
-	list_del(&fsf_req->list);
-}
-
-static inline struct zfcp_fsf_req *
-zfcp_reqlist_find(struct zfcp_adapter *adapter, unsigned long req_id)
-{
-	struct zfcp_fsf_req *request;
-	unsigned int idx;
-
-	idx = zfcp_reqlist_hash(req_id);
-	list_for_each_entry(request, &adapter->req_list[idx], list)
-		if (request->req_id == req_id)
-			return request;
-	return NULL;
-}
-
-static inline struct zfcp_fsf_req *
-zfcp_reqlist_find_safe(struct zfcp_adapter *adapter, struct zfcp_fsf_req *req)
-{
-	struct zfcp_fsf_req *request;
-	unsigned int idx;
-
-	for (idx = 0; idx < REQUEST_LIST_SIZE; idx++) {
-		list_for_each_entry(request, &adapter->req_list[idx], list)
-			if (request == req)
-				return request;
-	}
-	return NULL;
-}
-
 #endif /* ZFCP_DEF_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_erp.c linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_erp.c
--- linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_erp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_erp.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,7 @@
  *
  * Error Recovery Procedures (ERP).
  *
- * Copyright IBM Corporation 2002, 2009
+ * Copyright IBM Corporation 2002, 2010
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -11,6 +11,7 @@
 
 #include <linux/kthread.h>
 #include "zfcp_ext.h"
+#include "zfcp_reqlist.h"
 
 #define ZFCP_MAX_ERPS                   3
 
@@ -174,7 +175,7 @@ static struct zfcp_erp_action *zfcp_erp_
 
 	switch (need) {
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
-		if (!get_device(&unit->sysfs_device))
+		if (!get_device(&unit->dev))
 			return NULL;
 		atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status);
 		erp_action = &unit->erp_action;
@@ -184,7 +185,7 @@ static struct zfcp_erp_action *zfcp_erp_
 
 	case ZFCP_ERP_ACTION_REOPEN_PORT:
 	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
-		if (!get_device(&port->sysfs_device))
+		if (!get_device(&port->dev))
 			return NULL;
 		zfcp_erp_action_dismiss_port(port);
 		atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
@@ -478,26 +479,27 @@ static void zfcp_erp_action_to_running(s
 static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act)
 {
 	struct zfcp_adapter *adapter = act->adapter;
+	struct zfcp_fsf_req *req;
 
-	if (!act->fsf_req)
+	if (!act->fsf_req_id)
 		return;
 
-	spin_lock(&adapter->req_list_lock);
-	if (zfcp_reqlist_find_safe(adapter, act->fsf_req) &&
-	    act->fsf_req->erp_action == act) {
+	spin_lock(&adapter->req_list->lock);
+	req = _zfcp_reqlist_find(adapter->req_list, act->fsf_req_id);
+	if (req && req->erp_action == act) {
 		if (act->status & (ZFCP_STATUS_ERP_DISMISSED |
 				   ZFCP_STATUS_ERP_TIMEDOUT)) {
-			act->fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
+			req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
 			zfcp_dbf_rec_action("erscf_1", act);
-			act->fsf_req->erp_action = NULL;
+			req->erp_action = NULL;
 		}
 		if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
 			zfcp_dbf_rec_action("erscf_2", act);
-		if (act->fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED)
-			act->fsf_req = NULL;
+		if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED)
+			act->fsf_req_id = 0;
 	} else
-		act->fsf_req = NULL;
-	spin_unlock(&adapter->req_list_lock);
+		act->fsf_req_id = 0;
+	spin_unlock(&adapter->req_list->lock);
 }
 
 /**
@@ -1179,19 +1181,19 @@ static void zfcp_erp_action_cleanup(stru
 	switch (act->action) {
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
 		if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) {
-			get_device(&unit->sysfs_device);
+			get_device(&unit->dev);
 			if (scsi_queue_work(unit->port->adapter->scsi_host,
 					    &unit->scsi_work) <= 0)
-				put_device(&unit->sysfs_device);
+				put_device(&unit->dev);
 		}
-		put_device(&unit->sysfs_device);
+		put_device(&unit->dev);
 		break;
 
 	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
 	case ZFCP_ERP_ACTION_REOPEN_PORT:
 		if (result == ZFCP_ERP_SUCCEEDED)
 			zfcp_scsi_schedule_rport_register(port);
-		put_device(&port->sysfs_device);
+		put_device(&port->dev);
 		break;
 
 	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_ext.h linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_ext.h
--- linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_ext.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_ext.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@ extern struct zfcp_adapter *zfcp_adapter
 extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32,
 					   u32);
 extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, u64);
-extern int zfcp_reqlist_isempty(struct zfcp_adapter *);
 extern void zfcp_sg_free_table(struct scatterlist *, int);
 extern int zfcp_sg_setup_table(struct scatterlist *, int);
 extern void zfcp_device_unregister(struct device *,
@@ -144,13 +143,9 @@ extern void zfcp_fsf_reqid_check(struct
 /* zfcp_qdio.c */
 extern int zfcp_qdio_setup(struct zfcp_adapter *);
 extern void zfcp_qdio_destroy(struct zfcp_qdio *);
-extern int zfcp_qdio_send(struct zfcp_qdio *, struct zfcp_queue_req *);
-extern struct qdio_buffer_element
-	*zfcp_qdio_sbale_req(struct zfcp_qdio *, struct zfcp_queue_req *);
-extern struct qdio_buffer_element
-	*zfcp_qdio_sbale_curr(struct zfcp_qdio *, struct zfcp_queue_req *);
+extern int zfcp_qdio_send(struct zfcp_qdio *, struct zfcp_qdio_req *);
 extern int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *,
-				   struct zfcp_queue_req *, unsigned long,
+				   struct zfcp_qdio_req *, unsigned long,
 				   struct scatterlist *, int);
 extern int zfcp_qdio_open(struct zfcp_qdio *);
 extern void zfcp_qdio_close(struct zfcp_qdio *);
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_fc.c linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_fc.c
--- linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_fc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_fc.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,13 +3,14 @@
  *
  * Fibre Channel related functions for the zfcp device driver.
  *
- * Copyright IBM Corporation 2008, 2009
+ * Copyright IBM Corporation 2008, 2010
  */
 
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <scsi/fc/fc_els.h>
 #include <scsi/libfc.h>
 #include "zfcp_ext.h"
@@ -316,7 +317,7 @@ void zfcp_fc_port_did_lookup(struct work
 
 	zfcp_erp_port_reopen(port, 0, "fcgpn_3", NULL);
 out:
-	put_device(&port->sysfs_device);
+	put_device(&port->dev);
 }
 
 /**
@@ -325,9 +326,9 @@ out:
  */
 void zfcp_fc_trigger_did_lookup(struct zfcp_port *port)
 {
-	get_device(&port->sysfs_device);
+	get_device(&port->dev);
 	if (!queue_work(port->adapter->work_queue, &port->gid_pn_work))
-		put_device(&port->sysfs_device);
+		put_device(&port->dev);
 }
 
 /**
@@ -389,7 +390,7 @@ static void zfcp_fc_adisc_handler(void *
 	zfcp_scsi_schedule_rport_register(port);
  out:
 	atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
-	put_device(&port->sysfs_device);
+	put_device(&port->dev);
 	kmem_cache_free(zfcp_data.adisc_cache, adisc);
 }
 
@@ -436,7 +437,7 @@ void zfcp_fc_link_test_work(struct work_
 		container_of(work, struct zfcp_port, test_link_work);
 	int retval;
 
-	get_device(&port->sysfs_device);
+	get_device(&port->dev);
 	port->rport_task = RPORT_DEL;
 	zfcp_scsi_rport_work(&port->rport_work);
 
@@ -455,7 +456,7 @@ void zfcp_fc_link_test_work(struct work_
 	zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL);
 
 out:
-	put_device(&port->sysfs_device);
+	put_device(&port->dev);
 }
 
 /**
@@ -468,9 +469,9 @@ out:
  */
 void zfcp_fc_test_link(struct zfcp_port *port)
 {
-	get_device(&port->sysfs_device);
+	get_device(&port->dev);
 	if (!queue_work(port->adapter->work_queue, &port->test_link_work))
-		put_device(&port->sysfs_device);
+		put_device(&port->dev);
 }
 
 static void zfcp_free_sg_env(struct zfcp_fc_gpn_ft *gpn_ft, int buf_num)
@@ -617,8 +618,7 @@ static int zfcp_fc_eval_gpn_ft(struct zf
 
 	list_for_each_entry_safe(port, tmp, &remove_lh, list) {
 		zfcp_erp_port_shutdown(port, 0, "fcegpf2", NULL);
-		zfcp_device_unregister(&port->sysfs_device,
-				       &zfcp_sysfs_port_attrs);
+		zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs);
 	}
 
 	return ret;
@@ -731,7 +731,7 @@ static int zfcp_fc_exec_els_job(struct f
 			return -EINVAL;
 
 		d_id = port->d_id;
-		put_device(&port->sysfs_device);
+		put_device(&port->dev);
 	} else
 		d_id = ntoh24(job->request->rqst_data.h_els.port_id);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_fsf.c linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_fsf.c
--- linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_fsf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_fsf.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,17 +3,20 @@
  *
  * Implementation of FSF commands.
  *
- * Copyright IBM Corporation 2002, 2009
+ * Copyright IBM Corporation 2002, 2010
  */
 
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/blktrace_api.h>
+#include <linux/slab.h>
 #include <scsi/fc/fc_els.h>
 #include "zfcp_ext.h"
 #include "zfcp_fc.h"
 #include "zfcp_dbf.h"
+#include "zfcp_qdio.h"
+#include "zfcp_reqlist.h"
 
 static void zfcp_fsf_request_timeout_handler(unsigned long data)
 {
@@ -393,7 +396,7 @@ static void zfcp_fsf_protstatus_eval(str
 	case FSF_PROT_LINK_DOWN:
 		zfcp_fsf_link_down_info_eval(req, "fspse_5",
 					     &psq->link_down_info);
-		/* FIXME: reopening adapter now? better wait for link up */
+		/* go through reopen to flush pending requests */
 		zfcp_erp_adapter_reopen(adapter, 0, "fspse_6", req);
 		break;
 	case FSF_PROT_REEST_QUEUE:
@@ -457,15 +460,10 @@ static void zfcp_fsf_req_complete(struct
 void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
 {
 	struct zfcp_fsf_req *req, *tmp;
-	unsigned long flags;
 	LIST_HEAD(remove_queue);
-	unsigned int i;
 
 	BUG_ON(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP);
-	spin_lock_irqsave(&adapter->req_list_lock, flags);
-	for (i = 0; i < REQUEST_LIST_SIZE; i++)
-		list_splice_init(&adapter->req_list[i], &remove_queue);
-	spin_unlock_irqrestore(&adapter->req_list_lock, flags);
+	zfcp_reqlist_move(adapter->req_list, &remove_queue);
 
 	list_for_each_entry_safe(req, tmp, &remove_queue, list) {
 		list_del(&req->list);
@@ -495,8 +493,6 @@ static int zfcp_fsf_exchange_config_eval
 	fc_host_port_id(shost) = ntoh24(bottom->s_id);
 	fc_host_speed(shost) = bottom->fc_link_speed;
 	fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
-	fc_host_supported_fc4s(shost)[2] = 1; /* FCP */
-	fc_host_active_fc4s(shost)[2] = 1; /* FCP */
 
 	adapter->hydra_version = bottom->adapter_type;
 	adapter->timer_ticks = bottom->timer_interval;
@@ -619,6 +615,10 @@ static void zfcp_fsf_exchange_port_evalu
 		fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
 	fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
 	fc_host_supported_speeds(shost) = bottom->supported_speed;
+	memcpy(fc_host_supported_fc4s(shost), bottom->supported_fc4_types,
+	       FC_FC4_LIST_SIZE);
+	memcpy(fc_host_active_fc4s(shost), bottom->active_fc4_types,
+	       FC_FC4_LIST_SIZE);
 }
 
 static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req)
@@ -725,12 +725,12 @@ static struct zfcp_fsf_req *zfcp_fsf_req
 	req->adapter = adapter;
 	req->fsf_command = fsf_cmd;
 	req->req_id = adapter->req_no;
-	req->queue_req.sbal_number = 1;
-	req->queue_req.sbal_first = req_q->first;
-	req->queue_req.sbal_last = req_q->first;
-	req->queue_req.sbale_curr = 1;
+	req->qdio_req.sbal_number = 1;
+	req->qdio_req.sbal_first = req_q->first;
+	req->qdio_req.sbal_last = req_q->first;
+	req->qdio_req.sbale_curr = 1;
 
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
 	sbale[0].addr = (void *) req->req_id;
 	sbale[0].flags |= SBAL_FLAGS0_COMMAND;
 
@@ -745,6 +745,7 @@ static struct zfcp_fsf_req *zfcp_fsf_req
 			return ERR_PTR(-ENOMEM);
 		}
 
+		req->seq_no = adapter->fsf_req_seq_no;
 		req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no;
 		req->qtcb->prefix.req_id = req->req_id;
 		req->qtcb->prefix.ulp_info = 26;
@@ -752,8 +753,6 @@ static struct zfcp_fsf_req *zfcp_fsf_req
 		req->qtcb->prefix.qtcb_version = FSF_QTCB_CURRENT_VERSION;
 		req->qtcb->header.req_handle = req->req_id;
 		req->qtcb->header.fsf_command = req->fsf_command;
-		req->seq_no = adapter->fsf_req_seq_no;
-		req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no;
 		sbale[1].addr = (void *) req->qtcb;
 		sbale[1].length = sizeof(struct fsf_qtcb);
 	}
@@ -770,25 +769,17 @@ static int zfcp_fsf_req_send(struct zfcp
 {
 	struct zfcp_adapter *adapter = req->adapter;
 	struct zfcp_qdio *qdio = adapter->qdio;
-	unsigned long	     flags;
-	int		     idx;
-	int		     with_qtcb = (req->qtcb != NULL);
+	int with_qtcb = (req->qtcb != NULL);
+	int req_id = req->req_id;
 
-	/* put allocated FSF request into hash table */
-	spin_lock_irqsave(&adapter->req_list_lock, flags);
-	idx = zfcp_reqlist_hash(req->req_id);
-	list_add_tail(&req->list, &adapter->req_list[idx]);
-	spin_unlock_irqrestore(&adapter->req_list_lock, flags);
+	zfcp_reqlist_add(adapter->req_list, req);
 
-	req->queue_req.qdio_outb_usage = atomic_read(&qdio->req_q.count);
+	req->qdio_req.qdio_outb_usage = atomic_read(&qdio->req_q.count);
 	req->issued = get_clock();
-	if (zfcp_qdio_send(qdio, &req->queue_req)) {
+	if (zfcp_qdio_send(qdio, &req->qdio_req)) {
 		del_timer(&req->timer);
-		spin_lock_irqsave(&adapter->req_list_lock, flags);
 		/* lookup request again, list might have changed */
-		if (zfcp_reqlist_find_safe(adapter, req))
-			zfcp_reqlist_remove(adapter, req);
-		spin_unlock_irqrestore(&adapter->req_list_lock, flags);
+		zfcp_reqlist_find_rm(adapter->req_list, req_id);
 		zfcp_erp_adapter_reopen(adapter, 0, "fsrs__1", req);
 		return -EIO;
 	}
@@ -826,9 +817,9 @@ int zfcp_fsf_status_read(struct zfcp_qdi
 		goto out;
 	}
 
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
 	sbale[2].flags |= SBAL_FLAGS_LAST_ENTRY;
-	req->queue_req.sbale_curr = 2;
+	req->qdio_req.sbale_curr = 2;
 
 	sr_buf = mempool_alloc(adapter->pool.status_read_data, GFP_ATOMIC);
 	if (!sr_buf) {
@@ -837,7 +828,7 @@ int zfcp_fsf_status_read(struct zfcp_qdi
 	}
 	memset(sr_buf, 0, sizeof(*sr_buf));
 	req->data = sr_buf;
-	sbale = zfcp_qdio_sbale_curr(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_curr(qdio, &req->qdio_req);
 	sbale->addr = (void *) sr_buf;
 	sbale->length = sizeof(*sr_buf);
 
@@ -934,7 +925,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_
 		       ZFCP_STATUS_COMMON_UNBLOCKED)))
 		goto out_error_free;
 
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1029,7 +1020,7 @@ static int zfcp_fsf_setup_ct_els_sbals(s
 {
 	struct zfcp_adapter *adapter = req->adapter;
 	struct qdio_buffer_element *sbale = zfcp_qdio_sbale_req(adapter->qdio,
-							       &req->queue_req);
+							       &req->qdio_req);
 	u32 feat = adapter->adapter_features;
 	int bytes;
 
@@ -1047,15 +1038,15 @@ static int zfcp_fsf_setup_ct_els_sbals(s
 		return 0;
 	}
 
-	bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->queue_req,
+	bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->qdio_req,
 					SBAL_FLAGS0_TYPE_WRITE_READ,
 					sg_req, max_sbals);
 	if (bytes <= 0)
 		return -EIO;
 	req->qtcb->bottom.support.req_buf_length = bytes;
-	req->queue_req.sbale_curr = ZFCP_LAST_SBALE_PER_SBAL;
+	req->qdio_req.sbale_curr = ZFCP_LAST_SBALE_PER_SBAL;
 
-	bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->queue_req,
+	bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->qdio_req,
 					SBAL_FLAGS0_TYPE_WRITE_READ,
 					sg_resp, max_sbals);
 	req->qtcb->bottom.support.resp_buf_length = bytes;
@@ -1251,7 +1242,7 @@ int zfcp_fsf_exchange_config_data(struct
 	}
 
 	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1262,13 +1253,13 @@ int zfcp_fsf_exchange_config_data(struct
 			FSF_FEATURE_UPDATE_ALERT;
 	req->erp_action = erp_action;
 	req->handler = zfcp_fsf_exchange_config_data_handler;
-	erp_action->fsf_req = req;
+	erp_action->fsf_req_id = req->req_id;
 
 	zfcp_fsf_start_erp_timer(req);
 	retval = zfcp_fsf_req_send(req);
 	if (retval) {
 		zfcp_fsf_req_free(req);
-		erp_action->fsf_req = NULL;
+		erp_action->fsf_req_id = 0;
 	}
 out:
 	spin_unlock_bh(&qdio->req_q_lock);
@@ -1293,7 +1284,7 @@ int zfcp_fsf_exchange_config_data_sync(s
 		goto out_unlock;
 	}
 
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 	req->handler = zfcp_fsf_exchange_config_data_handler;
@@ -1349,19 +1340,19 @@ int zfcp_fsf_exchange_port_data(struct z
 	}
 
 	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
 	req->handler = zfcp_fsf_exchange_port_data_handler;
 	req->erp_action = erp_action;
-	erp_action->fsf_req = req;
+	erp_action->fsf_req_id = req->req_id;
 
 	zfcp_fsf_start_erp_timer(req);
 	retval = zfcp_fsf_req_send(req);
 	if (retval) {
 		zfcp_fsf_req_free(req);
-		erp_action->fsf_req = NULL;
+		erp_action->fsf_req_id = 0;
 	}
 out:
 	spin_unlock_bh(&qdio->req_q_lock);
@@ -1398,7 +1389,7 @@ int zfcp_fsf_exchange_port_data_sync(str
 	if (data)
 		req->data = data;
 
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1484,7 +1475,7 @@ static void zfcp_fsf_open_port_handler(s
 	}
 
 out:
-	put_device(&port->sysfs_device);
+	put_device(&port->dev);
 }
 
 /**
@@ -1513,7 +1504,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_a
 	}
 
 	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
         sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
         sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1521,15 +1512,15 @@ int zfcp_fsf_open_port(struct zfcp_erp_a
 	hton24(req->qtcb->bottom.support.d_id, port->d_id);
 	req->data = port;
 	req->erp_action = erp_action;
-	erp_action->fsf_req = req;
-	get_device(&port->sysfs_device);
+	erp_action->fsf_req_id = req->req_id;
+	get_device(&port->dev);
 
 	zfcp_fsf_start_erp_timer(req);
 	retval = zfcp_fsf_req_send(req);
 	if (retval) {
 		zfcp_fsf_req_free(req);
-		erp_action->fsf_req = NULL;
-		put_device(&port->sysfs_device);
+		erp_action->fsf_req_id = 0;
+		put_device(&port->dev);
 	}
 out:
 	spin_unlock_bh(&qdio->req_q_lock);
@@ -1583,7 +1574,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_
 	}
 
 	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1591,13 +1582,13 @@ int zfcp_fsf_close_port(struct zfcp_erp_
 	req->data = erp_action->port;
 	req->erp_action = erp_action;
 	req->qtcb->header.port_handle = erp_action->port->handle;
-	erp_action->fsf_req = req;
+	erp_action->fsf_req_id = req->req_id;
 
 	zfcp_fsf_start_erp_timer(req);
 	retval = zfcp_fsf_req_send(req);
 	if (retval) {
 		zfcp_fsf_req_free(req);
-		erp_action->fsf_req = NULL;
+		erp_action->fsf_req_id = 0;
 	}
 out:
 	spin_unlock_bh(&qdio->req_q_lock);
@@ -1660,7 +1651,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_f
 	}
 
 	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1715,7 +1706,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_
 	}
 
 	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1809,7 +1800,7 @@ int zfcp_fsf_close_physical_port(struct
 	}
 
 	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1817,13 +1808,13 @@ int zfcp_fsf_close_physical_port(struct
 	req->qtcb->header.port_handle = erp_action->port->handle;
 	req->erp_action = erp_action;
 	req->handler = zfcp_fsf_close_physical_port_handler;
-	erp_action->fsf_req = req;
+	erp_action->fsf_req_id = req->req_id;
 
 	zfcp_fsf_start_erp_timer(req);
 	retval = zfcp_fsf_req_send(req);
 	if (retval) {
 		zfcp_fsf_req_free(req);
-		erp_action->fsf_req = NULL;
+		erp_action->fsf_req_id = 0;
 	}
 out:
 	spin_unlock_bh(&qdio->req_q_lock);
@@ -1982,7 +1973,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_a
 	}
 
 	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
         sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
         sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1991,7 +1982,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_a
 	req->handler = zfcp_fsf_open_unit_handler;
 	req->data = erp_action->unit;
 	req->erp_action = erp_action;
-	erp_action->fsf_req = req;
+	erp_action->fsf_req_id = req->req_id;
 
 	if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE))
 		req->qtcb->bottom.support.option = FSF_OPEN_LUN_SUPPRESS_BOXING;
@@ -2000,7 +1991,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_a
 	retval = zfcp_fsf_req_send(req);
 	if (retval) {
 		zfcp_fsf_req_free(req);
-		erp_action->fsf_req = NULL;
+		erp_action->fsf_req_id = 0;
 	}
 out:
 	spin_unlock_bh(&qdio->req_q_lock);
@@ -2068,7 +2059,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_
 	}
 
 	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -2077,13 +2068,13 @@ int zfcp_fsf_close_unit(struct zfcp_erp_
 	req->handler = zfcp_fsf_close_unit_handler;
 	req->data = erp_action->unit;
 	req->erp_action = erp_action;
-	erp_action->fsf_req = req;
+	erp_action->fsf_req_id = req->req_id;
 
 	zfcp_fsf_start_erp_timer(req);
 	retval = zfcp_fsf_req_send(req);
 	if (retval) {
 		zfcp_fsf_req_free(req);
-		erp_action->fsf_req = NULL;
+		erp_action->fsf_req_id = 0;
 	}
 out:
 	spin_unlock_bh(&qdio->req_q_lock);
@@ -2111,10 +2102,11 @@ static void zfcp_fsf_req_trace(struct zf
 	blktrc.magic = ZFCP_BLK_DRV_DATA_MAGIC;
 	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
 		blktrc.flags |= ZFCP_BLK_REQ_ERROR;
-	blktrc.inb_usage = req->queue_req.qdio_inb_usage;
-	blktrc.outb_usage = req->queue_req.qdio_outb_usage;
+	blktrc.inb_usage = req->qdio_req.qdio_inb_usage;
+	blktrc.outb_usage = req->qdio_req.qdio_outb_usage;
 
-	if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) {
+	if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA &&
+	    !(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
 		blktrc.flags |= ZFCP_BLK_LAT_VALID;
 		blktrc.channel_lat = lat_in->channel_lat * ticks;
 		blktrc.fabric_lat = lat_in->fabric_lat * ticks;
@@ -2166,15 +2158,9 @@ static void zfcp_fsf_send_fcp_command_ta
 	fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
 	zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt);
 
-	zfcp_fsf_req_trace(req, scpnt);
-
 skip_fsfstatus:
-	if (scpnt->result != 0)
-		zfcp_dbf_scsi_result("erro", 3, req->adapter->dbf, scpnt, req);
-	else if (scpnt->retries > 0)
-		zfcp_dbf_scsi_result("retr", 4, req->adapter->dbf, scpnt, req);
-	else
-		zfcp_dbf_scsi_result("norm", 6, req->adapter->dbf, scpnt, req);
+	zfcp_fsf_req_trace(req, scpnt);
+	zfcp_dbf_scsi_result(req->adapter->dbf, scpnt, req);
 
 	scpnt->host_scribble = NULL;
 	(scpnt->scsi_done) (scpnt);
@@ -2274,7 +2260,7 @@ skip_fsfstatus:
 	else {
 		zfcp_fsf_send_fcp_command_task_handler(req);
 		req->unit = NULL;
-		put_device(&unit->sysfs_device);
+		put_device(&unit->dev);
 	}
 }
 
@@ -2312,7 +2298,7 @@ int zfcp_fsf_send_fcp_command_task(struc
 	}
 
 	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-	get_device(&unit->sysfs_device);
+	get_device(&unit->dev);
 	req->unit = unit;
 	req->data = scsi_cmnd;
 	req->handler = zfcp_fsf_send_fcp_command_handler;
@@ -2346,11 +2332,11 @@ int zfcp_fsf_send_fcp_command_task(struc
 	fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd;
 	zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd);
 
-	real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->queue_req, sbtype,
+	real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sbtype,
 					     scsi_sglist(scsi_cmnd),
 					     FSF_MAX_SBALS_PER_REQ);
 	if (unlikely(real_bytes < 0)) {
-		if (req->queue_req.sbal_number >= FSF_MAX_SBALS_PER_REQ) {
+		if (req->qdio_req.sbal_number >= FSF_MAX_SBALS_PER_REQ) {
 			dev_err(&adapter->ccw_device->dev,
 				"Oversize data package, unit 0x%016Lx "
 				"on port 0x%016Lx closed\n",
@@ -2369,7 +2355,7 @@ int zfcp_fsf_send_fcp_command_task(struc
 	goto out;
 
 failed_scsi_cmnd:
-	put_device(&unit->sysfs_device);
+	put_device(&unit->dev);
 	zfcp_fsf_req_free(req);
 	scsi_cmnd->host_scribble = NULL;
 out:
@@ -2415,7 +2401,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_c
 	req->qtcb->bottom.io.service_class = FSF_CLASS_3;
 	req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN;
 
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -2478,14 +2464,14 @@ struct zfcp_fsf_req *zfcp_fsf_control_fi
 
 	req->handler = zfcp_fsf_control_file_handler;
 
-	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req);
 	sbale[0].flags |= direction;
 
 	bottom = &req->qtcb->bottom.support;
 	bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE;
 	bottom->option = fsf_cfdc->option;
 
-	bytes = zfcp_qdio_sbals_from_sg(qdio, &req->queue_req,
+	bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req,
 					direction, fsf_cfdc->sg,
 					FSF_MAX_SBALS_PER_REQ);
 	if (bytes != ZFCP_CFDC_MAX_SIZE) {
@@ -2516,15 +2502,14 @@ void zfcp_fsf_reqid_check(struct zfcp_qd
 	struct qdio_buffer *sbal = qdio->resp_q.sbal[sbal_idx];
 	struct qdio_buffer_element *sbale;
 	struct zfcp_fsf_req *fsf_req;
-	unsigned long flags, req_id;
+	unsigned long req_id;
 	int idx;
 
 	for (idx = 0; idx < QDIO_MAX_ELEMENTS_PER_BUFFER; idx++) {
 
 		sbale = &sbal->element[idx];
 		req_id = (unsigned long) sbale->addr;
-		spin_lock_irqsave(&adapter->req_list_lock, flags);
-		fsf_req = zfcp_reqlist_find(adapter, req_id);
+		fsf_req = zfcp_reqlist_find_rm(adapter->req_list, req_id);
 
 		if (!fsf_req)
 			/*
@@ -2534,11 +2519,8 @@ void zfcp_fsf_reqid_check(struct zfcp_qd
 			panic("error: unknown req_id (%lx) on adapter %s.\n",
 			      req_id, dev_name(&adapter->ccw_device->dev));
 
-		list_del(&fsf_req->list);
-		spin_unlock_irqrestore(&adapter->req_list_lock, flags);
-
-		fsf_req->queue_req.sbal_response = sbal_idx;
-		fsf_req->queue_req.qdio_inb_usage =
+		fsf_req->qdio_req.sbal_response = sbal_idx;
+		fsf_req->qdio_req.qdio_inb_usage =
 			atomic_read(&qdio->resp_q.count);
 		zfcp_fsf_req_complete(fsf_req);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_qdio.c linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_qdio.c
--- linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_qdio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_qdio.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,9 @@
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/slab.h>
 #include "zfcp_ext.h"
+#include "zfcp_qdio.h"
 
 #define QBUFF_PER_PAGE		(PAGE_SIZE / sizeof(struct qdio_buffer))
 
@@ -28,12 +30,6 @@ static int zfcp_qdio_buffers_enqueue(str
 	return 0;
 }
 
-static struct qdio_buffer_element *
-zfcp_qdio_sbale(struct zfcp_qdio_queue *q, int sbal_idx, int sbale_idx)
-{
-	return &q->sbal[sbal_idx]->element[sbale_idx];
-}
-
 static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id)
 {
 	struct zfcp_adapter *adapter = qdio->adapter;
@@ -106,7 +102,7 @@ static void zfcp_qdio_resp_put_back(stru
 
 	if (unlikely(retval)) {
 		atomic_set(&queue->count, count);
-		/* FIXME: Recover this with an adapter reopen? */
+		zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdrpb_1", NULL);
 	} else {
 		queue->first += count;
 		queue->first %= QDIO_MAX_BUFFERS_PER_Q;
@@ -145,32 +141,8 @@ static void zfcp_qdio_int_resp(struct cc
 	zfcp_qdio_resp_put_back(qdio, count);
 }
 
-/**
- * zfcp_qdio_sbale_req - return ptr to SBALE of req_q for a struct zfcp_fsf_req
- * @qdio: pointer to struct zfcp_qdio
- * @q_rec: pointer to struct zfcp_queue_rec
- * Returns: pointer to qdio_buffer_element (SBALE) structure
- */
-struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_qdio *qdio,
-						struct zfcp_queue_req *q_req)
-{
-	return zfcp_qdio_sbale(&qdio->req_q, q_req->sbal_last, 0);
-}
-
-/**
- * zfcp_qdio_sbale_curr - return curr SBALE on req_q for a struct zfcp_fsf_req
- * @fsf_req: pointer to struct fsf_req
- * Returns: pointer to qdio_buffer_element (SBALE) structure
- */
-struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_qdio *qdio,
-						 struct zfcp_queue_req *q_req)
-{
-	return zfcp_qdio_sbale(&qdio->req_q, q_req->sbal_last,
-			       q_req->sbale_curr);
-}
-
 static void zfcp_qdio_sbal_limit(struct zfcp_qdio *qdio,
-				 struct zfcp_queue_req *q_req, int max_sbals)
+				 struct zfcp_qdio_req *q_req, int max_sbals)
 {
 	int count = atomic_read(&qdio->req_q.count);
 	count = min(count, max_sbals);
@@ -179,7 +151,7 @@ static void zfcp_qdio_sbal_limit(struct
 }
 
 static struct qdio_buffer_element *
-zfcp_qdio_sbal_chain(struct zfcp_qdio *qdio, struct zfcp_queue_req *q_req,
+zfcp_qdio_sbal_chain(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
 		     unsigned long sbtype)
 {
 	struct qdio_buffer_element *sbale;
@@ -214,7 +186,7 @@ zfcp_qdio_sbal_chain(struct zfcp_qdio *q
 }
 
 static struct qdio_buffer_element *
-zfcp_qdio_sbale_next(struct zfcp_qdio *qdio, struct zfcp_queue_req *q_req,
+zfcp_qdio_sbale_next(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
 		     unsigned int sbtype)
 {
 	if (q_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL)
@@ -224,7 +196,7 @@ zfcp_qdio_sbale_next(struct zfcp_qdio *q
 }
 
 static void zfcp_qdio_undo_sbals(struct zfcp_qdio *qdio,
-				 struct zfcp_queue_req *q_req)
+				 struct zfcp_qdio_req *q_req)
 {
 	struct qdio_buffer **sbal = qdio->req_q.sbal;
 	int first = q_req->sbal_first;
@@ -235,7 +207,7 @@ static void zfcp_qdio_undo_sbals(struct
 }
 
 static int zfcp_qdio_fill_sbals(struct zfcp_qdio *qdio,
-				struct zfcp_queue_req *q_req,
+				struct zfcp_qdio_req *q_req,
 				unsigned int sbtype, void *start_addr,
 				unsigned int total_length)
 {
@@ -271,8 +243,7 @@ static int zfcp_qdio_fill_sbals(struct z
  * @max_sbals: upper bound for number of SBALs to be used
  * Returns: number of bytes, or error (negativ)
  */
-int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio,
-			    struct zfcp_queue_req *q_req,
+int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
 			    unsigned long sbtype, struct scatterlist *sg,
 			    int max_sbals)
 {
@@ -304,10 +275,10 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_
 /**
  * zfcp_qdio_send - set PCI flag in first SBALE and send req to QDIO
  * @qdio: pointer to struct zfcp_qdio
- * @q_req: pointer to struct zfcp_queue_req
+ * @q_req: pointer to struct zfcp_qdio_req
  * Returns: 0 on success, error otherwise
  */
-int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_queue_req *q_req)
+int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
 {
 	struct zfcp_qdio_queue *req_q = &qdio->req_q;
 	int first = q_req->sbal_first;
@@ -349,8 +320,6 @@ static void zfcp_qdio_setup_init_data(st
 	id->input_handler = zfcp_qdio_int_resp;
 	id->output_handler = zfcp_qdio_int_req;
 	id->int_parm = (unsigned long) qdio;
-	id->flags = QDIO_INBOUND_0COPY_SBALS |
-		    QDIO_OUTBOUND_0COPY_SBALS | QDIO_USE_OUTBOUND_PCIS;
 	id->input_sbal_addr_array = (void **) (qdio->resp_q.sbal);
 	id->output_sbal_addr_array = (void **) (qdio->req_q.sbal);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_qdio.h linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_qdio.h
--- linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_qdio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_qdio.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,109 @@
+/*
+ * zfcp device driver
+ *
+ * Header file for zfcp qdio interface
+ *
+ * Copyright IBM Corporation 2010
+ */
+
+#ifndef ZFCP_QDIO_H
+#define ZFCP_QDIO_H
+
+#include <asm/qdio.h>
+
+/**
+ * struct zfcp_qdio_queue - qdio queue buffer, zfcp index and free count
+ * @sbal: qdio buffers
+ * @first: index of next free buffer in queue
+ * @count: number of free buffers in queue
+ */
+struct zfcp_qdio_queue {
+	struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q];
+	u8		   first;
+	atomic_t           count;
+};
+
+/**
+ * struct zfcp_qdio - basic qdio data structure
+ * @resp_q: response queue
+ * @req_q: request queue
+ * @stat_lock: lock to protect req_q_util and req_q_time
+ * @req_q_lock: lock to serialize access to request queue
+ * @req_q_time: time of last fill level change
+ * @req_q_util: used for accounting
+ * @req_q_full: queue full incidents
+ * @req_q_wq: used to wait for SBAL availability
+ * @adapter: adapter used in conjunction with this qdio structure
+ */
+struct zfcp_qdio {
+	struct zfcp_qdio_queue	resp_q;
+	struct zfcp_qdio_queue	req_q;
+	spinlock_t		stat_lock;
+	spinlock_t		req_q_lock;
+	unsigned long long	req_q_time;
+	u64			req_q_util;
+	atomic_t		req_q_full;
+	wait_queue_head_t	req_q_wq;
+	struct zfcp_adapter	*adapter;
+};
+
+/**
+ * struct zfcp_qdio_req - qdio queue related values for a request
+ * @sbal_number: number of free sbals
+ * @sbal_first: first sbal for this request
+ * @sbal_last: last sbal for this request
+ * @sbal_limit: last possible sbal for this request
+ * @sbale_curr: current sbale at creation of this request
+ * @sbal_response: sbal used in interrupt
+ * @qdio_outb_usage: usage of outbound queue
+ * @qdio_inb_usage: usage of inbound queue
+ */
+struct zfcp_qdio_req {
+	u8	sbal_number;
+	u8	sbal_first;
+	u8	sbal_last;
+	u8	sbal_limit;
+	u8	sbale_curr;
+	u8	sbal_response;
+	u16	qdio_outb_usage;
+	u16	qdio_inb_usage;
+};
+
+/**
+ * zfcp_qdio_sbale - return pointer to sbale in qdio queue
+ * @q: queue where to find sbal
+ * @sbal_idx: sbal index in queue
+ * @sbale_idx: sbale index in sbal
+ */
+static inline struct qdio_buffer_element *
+zfcp_qdio_sbale(struct zfcp_qdio_queue *q, int sbal_idx, int sbale_idx)
+{
+	return &q->sbal[sbal_idx]->element[sbale_idx];
+}
+
+/**
+ * zfcp_qdio_sbale_req - return pointer to sbale on req_q for a request
+ * @qdio: pointer to struct zfcp_qdio
+ * @q_rec: pointer to struct zfcp_qdio_req
+ * Returns: pointer to qdio_buffer_element (sbale) structure
+ */
+static inline struct qdio_buffer_element *
+zfcp_qdio_sbale_req(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
+{
+	return zfcp_qdio_sbale(&qdio->req_q, q_req->sbal_last, 0);
+}
+
+/**
+ * zfcp_qdio_sbale_curr - return current sbale on req_q for a request
+ * @qdio: pointer to struct zfcp_qdio
+ * @fsf_req: pointer to struct zfcp_fsf_req
+ * Returns: pointer to qdio_buffer_element (sbale) structure
+ */
+static inline struct qdio_buffer_element *
+zfcp_qdio_sbale_curr(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
+{
+	return zfcp_qdio_sbale(&qdio->req_q, q_req->sbal_last,
+			       q_req->sbale_curr);
+}
+
+#endif /* ZFCP_QDIO_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_reqlist.h linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_reqlist.h
--- linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_reqlist.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_reqlist.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,183 @@
+/*
+ * zfcp device driver
+ *
+ * Data structure and helper functions for tracking pending FSF
+ * requests.
+ *
+ * Copyright IBM Corporation 2009
+ */
+
+#ifndef ZFCP_REQLIST_H
+#define ZFCP_REQLIST_H
+
+/* number of hash buckets */
+#define ZFCP_REQ_LIST_BUCKETS 128
+
+/**
+ * struct zfcp_reqlist - Container for request list (reqlist)
+ * @lock: Spinlock for protecting the hash list
+ * @list: Array of hashbuckets, each is a list of requests in this bucket
+ */
+struct zfcp_reqlist {
+	spinlock_t lock;
+	struct list_head buckets[ZFCP_REQ_LIST_BUCKETS];
+};
+
+static inline int zfcp_reqlist_hash(unsigned long req_id)
+{
+	return req_id % ZFCP_REQ_LIST_BUCKETS;
+}
+
+/**
+ * zfcp_reqlist_alloc - Allocate and initialize reqlist
+ *
+ * Returns pointer to allocated reqlist on success, or NULL on
+ * allocation failure.
+ */
+static inline struct zfcp_reqlist *zfcp_reqlist_alloc(void)
+{
+	unsigned int i;
+	struct zfcp_reqlist *rl;
+
+	rl = kzalloc(sizeof(struct zfcp_reqlist), GFP_KERNEL);
+	if (!rl)
+		return NULL;
+
+	spin_lock_init(&rl->lock);
+
+	for (i = 0; i < ZFCP_REQ_LIST_BUCKETS; i++)
+		INIT_LIST_HEAD(&rl->buckets[i]);
+
+	return rl;
+}
+
+/**
+ * zfcp_reqlist_isempty - Check whether the request list empty
+ * @rl: pointer to reqlist
+ *
+ * Returns: 1 if list is empty, 0 if not
+ */
+static inline int zfcp_reqlist_isempty(struct zfcp_reqlist *rl)
+{
+	unsigned int i;
+
+	for (i = 0; i < ZFCP_REQ_LIST_BUCKETS; i++)
+		if (!list_empty(&rl->buckets[i]))
+			return 0;
+	return 1;
+}
+
+/**
+ * zfcp_reqlist_free - Free allocated memory for reqlist
+ * @rl: The reqlist where to free memory
+ */
+static inline void zfcp_reqlist_free(struct zfcp_reqlist *rl)
+{
+	/* sanity check */
+	BUG_ON(!zfcp_reqlist_isempty(rl));
+
+	kfree(rl);
+}
+
+static inline struct zfcp_fsf_req *
+_zfcp_reqlist_find(struct zfcp_reqlist *rl, unsigned long req_id)
+{
+	struct zfcp_fsf_req *req;
+	unsigned int i;
+
+	i = zfcp_reqlist_hash(req_id);
+	list_for_each_entry(req, &rl->buckets[i], list)
+		if (req->req_id == req_id)
+			return req;
+	return NULL;
+}
+
+/**
+ * zfcp_reqlist_find - Lookup FSF request by its request id
+ * @rl: The reqlist where to lookup the FSF request
+ * @req_id: The request id to look for
+ *
+ * Returns a pointer to the FSF request with the specified request id
+ * or NULL if there is no known FSF request with this id.
+ */
+static inline struct zfcp_fsf_req *
+zfcp_reqlist_find(struct zfcp_reqlist *rl, unsigned long req_id)
+{
+	unsigned long flags;
+	struct zfcp_fsf_req *req;
+
+	spin_lock_irqsave(&rl->lock, flags);
+	req = _zfcp_reqlist_find(rl, req_id);
+	spin_unlock_irqrestore(&rl->lock, flags);
+
+	return req;
+}
+
+/**
+ * zfcp_reqlist_find_rm - Lookup request by id and remove it from reqlist
+ * @rl: reqlist where to search and remove entry
+ * @req_id: The request id of the request to look for
+ *
+ * This functions tries to find the FSF request with the specified
+ * id and then removes it from the reqlist. The reqlist lock is held
+ * during both steps of the operation.
+ *
+ * Returns: Pointer to the FSF request if the request has been found,
+ * NULL if it has not been found.
+ */
+static inline struct zfcp_fsf_req *
+zfcp_reqlist_find_rm(struct zfcp_reqlist *rl, unsigned long req_id)
+{
+	unsigned long flags;
+	struct zfcp_fsf_req *req;
+
+	spin_lock_irqsave(&rl->lock, flags);
+	req = _zfcp_reqlist_find(rl, req_id);
+	if (req)
+		list_del(&req->list);
+	spin_unlock_irqrestore(&rl->lock, flags);
+
+	return req;
+}
+
+/**
+ * zfcp_reqlist_add - Add entry to reqlist
+ * @rl: reqlist where to add the entry
+ * @req: The entry to add
+ *
+ * The request id always increases. As an optimization new requests
+ * are added here with list_add_tail at the end of the bucket lists
+ * while old requests are looked up starting at the beginning of the
+ * lists.
+ */
+static inline void zfcp_reqlist_add(struct zfcp_reqlist *rl,
+				    struct zfcp_fsf_req *req)
+{
+	unsigned int i;
+	unsigned long flags;
+
+	i = zfcp_reqlist_hash(req->req_id);
+
+	spin_lock_irqsave(&rl->lock, flags);
+	list_add_tail(&req->list, &rl->buckets[i]);
+	spin_unlock_irqrestore(&rl->lock, flags);
+}
+
+/**
+ * zfcp_reqlist_move - Move all entries from reqlist to simple list
+ * @rl: The zfcp_reqlist where to remove all entries
+ * @list: The list where to move all entries
+ */
+static inline void zfcp_reqlist_move(struct zfcp_reqlist *rl,
+				     struct list_head *list)
+{
+	unsigned int i;
+	unsigned long flags;
+
+	spin_lock_irqsave(&rl->lock, flags);
+	for (i = 0; i < ZFCP_REQ_LIST_BUCKETS; i++)
+		list_splice_init(&rl->buckets[i], list);
+	spin_unlock_irqrestore(&rl->lock, flags);
+}
+
+#endif /* ZFCP_REQLIST_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_scsi.c linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_scsi.c
--- linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_scsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_scsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,18 +3,20 @@
  *
  * Interface to Linux SCSI midlayer.
  *
- * Copyright IBM Corporation 2002, 2009
+ * Copyright IBM Corporation 2002, 2010
  */
 
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <scsi/fc/fc_fcp.h>
 #include <asm/atomic.h>
 #include "zfcp_ext.h"
 #include "zfcp_dbf.h"
 #include "zfcp_fc.h"
+#include "zfcp_reqlist.h"
 
 static unsigned int default_depth = 32;
 module_param_named(queue_depth, default_depth, uint, 0600);
@@ -43,7 +45,7 @@ static void zfcp_scsi_slave_destroy(stru
 {
 	struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
 	unit->device = NULL;
-	put_device(&unit->sysfs_device);
+	put_device(&unit->dev);
 }
 
 static int zfcp_scsi_slave_configure(struct scsi_device *sdp)
@@ -59,10 +61,9 @@ static void zfcp_scsi_command_fail(struc
 {
 	struct zfcp_adapter *adapter =
 		(struct zfcp_adapter *) scpnt->device->host->hostdata[0];
+
 	set_host_byte(scpnt, result);
-	if ((scpnt->device != NULL) && (scpnt->device->host != NULL))
-		zfcp_dbf_scsi_result("fail", 4, adapter->dbf, scpnt, NULL);
-	/* return directly */
+	zfcp_dbf_scsi_fail_send(adapter->dbf, scpnt);
 	scpnt->scsi_done(scpnt);
 }
 
@@ -86,18 +87,10 @@ static int zfcp_scsi_queuecommand(struct
 	adapter = (struct zfcp_adapter *) scpnt->device->host->hostdata[0];
 	unit = scpnt->device->hostdata;
 
-	BUG_ON(!adapter || (adapter != unit->port->adapter));
-	BUG_ON(!scpnt->scsi_done);
-
-	if (unlikely(!unit)) {
-		zfcp_scsi_command_fail(scpnt, DID_NO_CONNECT);
-		return 0;
-	}
-
 	scsi_result = fc_remote_port_chkready(rport);
 	if (unlikely(scsi_result)) {
 		scpnt->result = scsi_result;
-		zfcp_dbf_scsi_result("fail", 4, adapter->dbf, scpnt, NULL);
+		zfcp_dbf_scsi_fail_send(adapter->dbf, scpnt);
 		scpnt->scsi_done(scpnt);
 		return 0;
 	}
@@ -189,9 +182,7 @@ static int zfcp_scsi_eh_abort_handler(st
 	/* avoid race condition between late normal completion and abort */
 	write_lock_irqsave(&adapter->abort_lock, flags);
 
-	spin_lock(&adapter->req_list_lock);
-	old_req = zfcp_reqlist_find(adapter, old_reqid);
-	spin_unlock(&adapter->req_list_lock);
+	old_req = zfcp_reqlist_find(adapter->req_list, old_reqid);
 	if (!old_req) {
 		write_unlock_irqrestore(&adapter->abort_lock, flags);
 		zfcp_dbf_scsi_abort("lte1", adapter->dbf, scpnt, NULL,
@@ -521,7 +512,7 @@ static void zfcp_scsi_terminate_rport_io
 
 	if (port) {
 		zfcp_erp_port_reopen(port, 0, "sctrpi1", NULL);
-		put_device(&port->sysfs_device);
+		put_device(&port->dev);
 	}
 }
 
@@ -563,23 +554,23 @@ static void zfcp_scsi_rport_block(struct
 
 void zfcp_scsi_schedule_rport_register(struct zfcp_port *port)
 {
-	get_device(&port->sysfs_device);
+	get_device(&port->dev);
 	port->rport_task = RPORT_ADD;
 
 	if (!queue_work(port->adapter->work_queue, &port->rport_work))
-		put_device(&port->sysfs_device);
+		put_device(&port->dev);
 }
 
 void zfcp_scsi_schedule_rport_block(struct zfcp_port *port)
 {
-	get_device(&port->sysfs_device);
+	get_device(&port->dev);
 	port->rport_task = RPORT_DEL;
 
 	if (port->rport && queue_work(port->adapter->work_queue,
 				      &port->rport_work))
 		return;
 
-	put_device(&port->sysfs_device);
+	put_device(&port->dev);
 }
 
 void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *adapter)
@@ -608,7 +599,7 @@ void zfcp_scsi_rport_work(struct work_st
 		}
 	}
 
-	put_device(&port->sysfs_device);
+	put_device(&port->dev);
 }
 
 
@@ -626,7 +617,7 @@ void zfcp_scsi_scan(struct work_struct *
 				 scsilun_to_int((struct scsi_lun *)
 						&unit->fcp_lun), 0);
 
-	put_device(&unit->sysfs_device);
+	put_device(&unit->dev);
 }
 
 struct fc_function_template zfcp_transport_functions = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_sysfs.c linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/s390/scsi/zfcp_sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,12 +3,13 @@
  *
  * sysfs attributes.
  *
- * Copyright IBM Corporation 2008, 2009
+ * Copyright IBM Corporation 2008, 2010
  */
 
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/slab.h>
 #include "zfcp_ext.h"
 
 #define ZFCP_DEV_ATTR(_feat, _name, _mode, _show, _store) \
@@ -19,8 +20,7 @@ static ssize_t zfcp_sysfs_##_feat##_##_n
 						   struct device_attribute *at,\
 						   char *buf)		       \
 {									       \
-	struct _feat_def *_feat = container_of(dev, struct _feat_def,	       \
-					       sysfs_device);		       \
+	struct _feat_def *_feat = container_of(dev, struct _feat_def, dev);    \
 									       \
 	return sprintf(buf, _format, _value);				       \
 }									       \
@@ -87,8 +87,7 @@ static ssize_t zfcp_sysfs_##_feat##_fail
 						struct device_attribute *attr, \
 						char *buf)		       \
 {									       \
-	struct _feat_def *_feat = container_of(dev, struct _feat_def,	       \
-					       sysfs_device);		       \
+	struct _feat_def *_feat = container_of(dev, struct _feat_def, dev);    \
 									       \
 	if (atomic_read(&_feat->status) & ZFCP_STATUS_COMMON_ERP_FAILED)       \
 		return sprintf(buf, "1\n");				       \
@@ -99,12 +98,11 @@ static ssize_t zfcp_sysfs_##_feat##_fail
 						 struct device_attribute *attr,\
 						 const char *buf, size_t count)\
 {									       \
-	struct _feat_def *_feat = container_of(dev, struct _feat_def,	       \
-					       sysfs_device);		       \
+	struct _feat_def *_feat = container_of(dev, struct _feat_def, dev);    \
 	unsigned long val;						       \
 	int retval = 0;							       \
 									       \
-	if (!(_feat && get_device(&_feat->sysfs_device)))		       \
+	if (!(_feat && get_device(&_feat->dev)))			       \
 		return -EBUSY;						       \
 									       \
 	if (strict_strtoul(buf, 0, &val) || val != 0) {			       \
@@ -118,7 +116,7 @@ static ssize_t zfcp_sysfs_##_feat##_fail
 				  _reopen_id, NULL);			       \
 	zfcp_erp_wait(_adapter);					       \
 out:									       \
-	put_device(&_feat->sysfs_device);				       \
+	put_device(&_feat->dev);					       \
 	return retval ? retval : (ssize_t) count;			       \
 }									       \
 static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO,			       \
@@ -224,10 +222,10 @@ static ssize_t zfcp_sysfs_port_remove_st
 	list_del(&port->list);
 	write_unlock_irq(&adapter->port_list_lock);
 
-	put_device(&port->sysfs_device);
+	put_device(&port->dev);
 
 	zfcp_erp_port_shutdown(port, 0, "syprs_1", NULL);
-	zfcp_device_unregister(&port->sysfs_device, &zfcp_sysfs_port_attrs);
+	zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs);
  out:
 	zfcp_ccw_adapter_put(adapter);
 	return retval ? retval : (ssize_t) count;
@@ -258,13 +256,12 @@ static ssize_t zfcp_sysfs_unit_add_store
 					 struct device_attribute *attr,
 					 const char *buf, size_t count)
 {
-	struct zfcp_port *port = container_of(dev, struct zfcp_port,
-					      sysfs_device);
+	struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
 	struct zfcp_unit *unit;
 	u64 fcp_lun;
 	int retval = -EINVAL;
 
-	if (!(port && get_device(&port->sysfs_device)))
+	if (!(port && get_device(&port->dev)))
 		return -EBUSY;
 
 	if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
@@ -280,7 +277,7 @@ static ssize_t zfcp_sysfs_unit_add_store
 	zfcp_erp_wait(unit->port->adapter);
 	flush_work(&unit->scsi_work);
 out:
-	put_device(&port->sysfs_device);
+	put_device(&port->dev);
 	return retval ? retval : (ssize_t) count;
 }
 static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store);
@@ -289,13 +286,12 @@ static ssize_t zfcp_sysfs_unit_remove_st
 					    struct device_attribute *attr,
 					    const char *buf, size_t count)
 {
-	struct zfcp_port *port = container_of(dev, struct zfcp_port,
-					      sysfs_device);
+	struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
 	struct zfcp_unit *unit;
 	u64 fcp_lun;
 	int retval = -EINVAL;
 
-	if (!(port && get_device(&port->sysfs_device)))
+	if (!(port && get_device(&port->dev)))
 		return -EBUSY;
 
 	if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
@@ -314,12 +310,12 @@ static ssize_t zfcp_sysfs_unit_remove_st
 	list_del(&unit->list);
 	write_unlock_irq(&port->unit_list_lock);
 
-	put_device(&unit->sysfs_device);
+	put_device(&unit->dev);
 
 	zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL);
-	zfcp_device_unregister(&unit->sysfs_device, &zfcp_sysfs_unit_attrs);
+	zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs);
 out:
-	put_device(&port->sysfs_device);
+	put_device(&port->dev);
 	return retval ? retval : (ssize_t) count;
 }
 static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store);
diff -druNp linux-libre-2.6.33-gnu1/drivers/sbus/char/bbc_envctrl.c linux-libre-2.6.34-gnu1/drivers/sbus/char/bbc_envctrl.c
--- linux-libre-2.6.33-gnu1/drivers/sbus/char/bbc_envctrl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/sbus/char/bbc_envctrl.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 #include <linux/kmod.h>
 #include <linux/reboot.h>
 #include <linux/of.h>
+#include <linux/slab.h>
 #include <linux/of_device.h>
 #include <asm/oplib.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/sbus/char/display7seg.c linux-libre-2.6.34-gnu1/drivers/sbus/char/display7seg.c
--- linux-libre-2.6.33-gnu1/drivers/sbus/char/display7seg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/sbus/char/display7seg.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/ioport.h>		/* request_region */
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/sbus/char/envctrl.c linux-libre-2.6.34-gnu1/drivers/sbus/char/envctrl.c
--- linux-libre-2.6.33-gnu1/drivers/sbus/char/envctrl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/sbus/char/envctrl.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/miscdevice.h>
 #include <linux/kmod.h>
 #include <linux/reboot.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/sbus/char/flash.c linux-libre-2.6.34-gnu1/drivers/sbus/char/flash.c
--- linux-libre-2.6.33-gnu1/drivers/sbus/char/flash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/sbus/char/flash.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
-#include <linux/slab.h>
 #include <linux/fcntl.h>
 #include <linux/poll.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/sbus/char/jsflash.c linux-libre-2.6.34-gnu1/drivers/sbus/char/jsflash.c
--- linux-libre-2.6.33-gnu1/drivers/sbus/char/jsflash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/sbus/char/jsflash.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
-#include <linux/slab.h>
 #include <linux/fcntl.h>
 #include <linux/poll.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/sbus/char/openprom.c linux-libre-2.6.34-gnu1/drivers/sbus/char/openprom.c
--- linux-libre-2.6.33-gnu1/drivers/sbus/char/openprom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/sbus/char/openprom.c	2010-05-16 17:17:36.000000000 -0400
@@ -233,7 +233,7 @@ static int opromnext(void __user *argp,
 
 	ph = 0;
 	if (dp)
-		ph = dp->node;
+		ph = dp->phandle;
 
 	data->current_node = dp;
 	*((int *) op->oprom_array) = ph;
@@ -256,7 +256,7 @@ static int oprompci2node(void __user *ar
 
 		dp = pci_device_to_OF_node(pdev);
 		data->current_node = dp;
-		*((int *)op->oprom_array) = dp->node;
+		*((int *)op->oprom_array) = dp->phandle;
 		op->oprom_size = sizeof(int);
 		err = copyout(argp, op, bufsize + sizeof(int));
 
@@ -273,7 +273,7 @@ static int oprompath2node(void __user *a
 
 	dp = of_find_node_by_path(op->oprom_array);
 	if (dp)
-		ph = dp->node;
+		ph = dp->phandle;
 	data->current_node = dp;
 	*((int *)op->oprom_array) = ph;
 	op->oprom_size = sizeof(int);
@@ -540,7 +540,7 @@ static int opiocgetnext(unsigned int cmd
 		}
 	}
 	if (dp)
-		nd = dp->node;
+		nd = dp->phandle;
 	if (copy_to_user(argp, &nd, sizeof(phandle)))
 		return -EFAULT;
 
@@ -570,7 +570,7 @@ static int openprom_bsd_ioctl(struct ino
 	case OPIOCGETOPTNODE:
 		BUILD_BUG_ON(sizeof(phandle) != sizeof(int));
 
-		if (copy_to_user(argp, &options_node->node, sizeof(phandle)))
+		if (copy_to_user(argp, &options_node->phandle, sizeof(phandle)))
 			return -EFAULT;
 
 		return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/3w-9xxx.c linux-libre-2.6.34-gnu1/drivers/scsi/3w-9xxx.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/3w-9xxx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/3w-9xxx.c	2010-05-16 17:17:36.000000000 -0400
@@ -91,6 +91,7 @@
 #include <linux/time.h>
 #include <linux/mutex.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/3w-sas.c linux-libre-2.6.34-gnu1/drivers/scsi/3w-sas.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/3w-sas.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/3w-sas.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,6 +65,7 @@
 #include <linux/time.h>
 #include <linux/mutex.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/3w-xxxx.c linux-libre-2.6.34-gnu1/drivers/scsi/3w-xxxx.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/3w-xxxx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/3w-xxxx.c	2010-05-16 17:17:36.000000000 -0400
@@ -205,6 +205,7 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/time.h>
 #include <linux/mutex.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/53c700.c linux-libre-2.6.34-gnu1/drivers/scsi/53c700.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/53c700.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/53c700.c	2010-05-16 17:17:36.000000000 -0400
@@ -117,6 +117,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/a100u2w.c linux-libre-2.6.34-gnu1/drivers/scsi/a100u2w.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/a100u2w.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/a100u2w.c	2010-05-16 17:17:36.000000000 -0400
@@ -69,7 +69,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/dma-mapping.h>
 
 #include <asm/io.h>
@@ -492,7 +491,7 @@ static void init_alloc_map(struct orc_ho
  *	init_orchid		-	initialise the host adapter
  *	@host:host adapter to initialise
  *
- *	Initialise the controller and if neccessary load the firmware.
+ *	Initialise the controller and if necessary load the firmware.
  *
  *	Returns -1 if the initialisation fails.
  */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/a2091.c linux-libre-2.6.34-gnu1/drivers/scsi/a2091.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/a2091.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/a2091.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,6 @@
 #include <linux/types.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/a3000.c linux-libre-2.6.34-gnu1/drivers/scsi/a3000.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/a3000.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/a3000.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,6 @@
 #include <linux/types.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/a4000t.c linux-libre-2.6.34-gnu1/drivers/scsi/a4000t.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/a4000t.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/a4000t.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/amigahw.h>
 #include <asm/amigaints.h>
 #include <scsi/scsi_host.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/rx.c linux-libre-2.6.34-gnu1/drivers/scsi/aacraid/rx.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/aacraid/rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,6 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
-#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/completion.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/sa.c linux-libre-2.6.34-gnu1/drivers/scsi/aacraid/sa.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/sa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/aacraid/sa.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,6 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
-#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/completion.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/advansys.c linux-libre-2.6.34-gnu1/drivers/scsi/advansys.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/advansys.c	2013-05-03 12:12:36.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/scsi/advansys.c	2013-05-03 09:52:08.000000000 -0400
@@ -4724,6 +4724,10 @@ static ushort AscInitMicroCodeVar(ASC_DV
 	BUG_ON((unsigned long)asc_dvc->overrun_buf & 7);
 	asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf,
 					ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
+	if (dma_mapping_error(board->dev, asc_dvc->overrun_dma)) {
+		warn_code = -ENOMEM;
+		goto err_dma_map;
+	}
 	phy_addr = cpu_to_le32(asc_dvc->overrun_dma);
 	AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
 				 (uchar *)&phy_addr, 1);
@@ -4739,14 +4743,23 @@ static ushort AscInitMicroCodeVar(ASC_DV
 	AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
 	if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
 		asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
-		return warn_code;
+		warn_code = UW_ERR;
+		goto err_mcode_start;
 	}
 	if (AscStartChip(iop_base) != 1) {
 		asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
-		return warn_code;
+		warn_code = UW_ERR;
+		goto err_mcode_start;
 	}
 
 	return warn_code;
+
+err_mcode_start:
+	dma_unmap_single(board->dev, asc_dvc->overrun_dma,
+			 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
+err_dma_map:
+	asc_dvc->overrun_dma = 0;
+	return warn_code;
 }
 
 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
@@ -4781,12 +4794,14 @@ static ushort AscInitAsc1000Driver(ASC_D
 	if (err) {
 		printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
 		       fwname, err);
+		asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
 		return err;
 	}
 	if (fw->size < 4) {
 		printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
 		       fw->size, fwname);
 		release_firmware(fw);
+		asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
 		return -EINVAL;
 	}
 	chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
@@ -4800,6 +4815,8 @@ static ushort AscInitAsc1000Driver(ASC_D
 	}
 	release_firmware(fw);
 	warn_code |= AscInitMicroCodeVar(asc_dvc);
+	if (!asc_dvc->overrun_dma)
+		return warn_code;
 	asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
 	AscEnableInterrupt(iop_base);
 	return warn_code;
@@ -5110,12 +5127,14 @@ static int AdvInitAsc3550Driver(ADV_DVC_
 	if (err) {
 		printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
 		       fwname, err);
+		asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
 		return err;
 	}
 	if (fw->size < 4) {
 		printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
 		       fw->size, fwname);
 		release_firmware(fw);
+		asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
 		return -EINVAL;
 	}
 	chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
@@ -5624,12 +5643,14 @@ static int AdvInitAsc38C0800Driver(ADV_D
 	if (err) {
 		printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
 		       fwname, err);
+		asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
 		return err;
 	}
 	if (fw->size < 4) {
 		printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
 		       fw->size, fwname);
 		release_firmware(fw);
+		asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
 		return -EINVAL;
 	}
 	chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
@@ -6124,12 +6145,14 @@ static int AdvInitAsc38C1600Driver(ADV_D
 	if (err) {
 		printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
 		       fwname, err);
+		asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
 		return err;
 	}
 	if (fw->size < 4) {
 		printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
 		       fw->size, fwname);
 		release_firmware(fw);
+		asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
 		return -EINVAL;
 	}
 	chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
@@ -7970,9 +7993,10 @@ static int advansys_reset(struct scsi_cm
 		status = AscInitAsc1000Driver(asc_dvc);
 
 		/* Refer to ASC_IERR_* definitions for meaning of 'err_code'. */
-		if (asc_dvc->err_code) {
+		if (asc_dvc->err_code || !asc_dvc->overrun_dma) {
 			scmd_printk(KERN_INFO, scp, "SCSI bus reset error: "
-				    "0x%x\n", asc_dvc->err_code);
+				    "0x%x, status: 0x%x\n", asc_dvc->err_code,
+				    status);
 			ret = FAILED;
 		} else if (status) {
 			scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: "
@@ -12303,7 +12327,7 @@ static int __devinit advansys_board_foun
 		asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL);
 		if (!asc_dvc_varp->overrun_buf) {
 			ret = -ENOMEM;
-			goto err_free_wide_mem;
+			goto err_free_irq;
 		}
 		warn_code = AscInitAsc1000Driver(asc_dvc_varp);
 
@@ -12312,30 +12336,36 @@ static int __devinit advansys_board_foun
 					"warn 0x%x, error 0x%x\n",
 					asc_dvc_varp->init_state, warn_code,
 					asc_dvc_varp->err_code);
-			if (asc_dvc_varp->err_code) {
+			if (!asc_dvc_varp->overrun_dma) {
 				ret = -ENODEV;
-				kfree(asc_dvc_varp->overrun_buf);
+				goto err_free_mem;
 			}
 		}
 	} else {
-		if (advansys_wide_init_chip(shost))
+		if (advansys_wide_init_chip(shost)) {
 			ret = -ENODEV;
+			goto err_free_mem;
+		}
 	}
 
-	if (ret)
-		goto err_free_wide_mem;
-
 	ASC_DBG_PRT_SCSI_HOST(2, shost);
 
 	ret = scsi_add_host(shost, boardp->dev);
 	if (ret)
-		goto err_free_wide_mem;
+		goto err_free_mem;
 
 	scsi_scan_host(shost);
 	return 0;
 
- err_free_wide_mem:
-	advansys_wide_free_mem(boardp);
+ err_free_mem:
+	if (ASC_NARROW_BOARD(boardp)) {
+		if (asc_dvc_varp->overrun_dma)
+			dma_unmap_single(boardp->dev, asc_dvc_varp->overrun_dma,
+					 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
+		kfree(asc_dvc_varp->overrun_buf);
+	} else
+		advansys_wide_free_mem(boardp);
+ err_free_irq:
 	free_irq(boardp->irq, shost);
  err_free_dma:
 #ifdef CONFIG_ISA
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/aha152x.c linux-libre-2.6.34-gnu1/drivers/scsi/aha152x.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/aha152x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/aha152x.c	2010-05-16 17:17:36.000000000 -0400
@@ -254,6 +254,7 @@
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <scsi/scsicam.h>
 
 #include "scsi.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/aha1542.c linux-libre-2.6.34-gnu1/drivers/scsi/aha1542.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/aha1542.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/aha1542.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/blkdev.h>
 #include <linux/mca.h>
 #include <linux/mca-legacy.h>
+#include <linux/slab.h>
 
 #include <asm/dma.h>
 #include <asm/system.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/aha1740.c linux-libre-2.6.34-gnu1/drivers/scsi/aha1740.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/aha1740.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/aha1740.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,6 +50,7 @@
 #include <linux/device.h>
 #include <linux/eisa.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <asm/dma.h>
 #include <asm/system.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic79xx_osm.c linux-libre-2.6.34-gnu1/drivers/scsi/aic7xxx/aic79xx_osm.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic79xx_osm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/aic7xxx/aic79xx_osm.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,6 +53,7 @@ static struct scsi_transport_template *a
 #include <linux/blkdev.h>		/* For block_size() */
 #include <linux/delay.h>	/* For ssleep/msleep */
 #include <linux/device.h>
+#include <linux/slab.h>
 
 /*
  * Bucket size for counting good commands in between bad ones.
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic7xxx_osm.c linux-libre-2.6.34-gnu1/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic7xxx_osm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/aic7xxx/aic7xxx_osm.c	2010-05-16 17:17:36.000000000 -0400
@@ -129,6 +129,7 @@ static struct scsi_transport_template *a
 #include <linux/mm.h>		/* For fetching system memory size */
 #include <linux/blkdev.h>		/* For block_size() */
 #include <linux/delay.h>	/* For ssleep/msleep */
+#include <linux/slab.h>
 
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/aic94xx/aic94xx_hwi.c linux-libre-2.6.34-gnu1/drivers/scsi/aic94xx/aic94xx_hwi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/aic94xx/aic94xx_hwi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/aic94xx/aic94xx_hwi.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/firmware.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/aic94xx/aic94xx_init.c linux-libre-2.6.34-gnu1/drivers/scsi/aic94xx/aic94xx_init.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/aic94xx/aic94xx_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/aic94xx/aic94xx_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi_host.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/aic94xx/aic94xx_scb.c linux-libre-2.6.34-gnu1/drivers/scsi/aic94xx/aic94xx_scb.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/aic94xx/aic94xx_scb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/aic94xx/aic94xx_scb.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
  *
  */
 
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 
 #include "aic94xx.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/aic94xx/aic94xx_sds.c linux-libre-2.6.34-gnu1/drivers/scsi/aic94xx/aic94xx_sds.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/aic94xx/aic94xx_sds.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/aic94xx/aic94xx_sds.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include "aic94xx.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/aic94xx/aic94xx_seq.c linux-libre-2.6.34-gnu1/drivers/scsi/aic94xx/aic94xx_seq.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/aic94xx/aic94xx_seq.c	2013-05-03 12:12:42.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/scsi/aic94xx/aic94xx_seq.c	2013-05-03 09:52:14.000000000 -0400
@@ -27,6 +27,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/firmware.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/aic94xx/aic94xx_tmf.c linux-libre-2.6.34-gnu1/drivers/scsi/aic94xx/aic94xx_tmf.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/aic94xx/aic94xx_tmf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/aic94xx/aic94xx_tmf.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
  */
 
 #include <linux/spinlock.h>
+#include <linux/gfp.h>
 #include "aic94xx.h"
 #include "aic94xx_sas.h"
 #include "aic94xx_hwi.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/arcmsr/arcmsr_hba.c linux-libre-2.6.34-gnu1/drivers/scsi/arcmsr/arcmsr_hba.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/arcmsr/arcmsr_hba.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/arcmsr/arcmsr_hba.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,6 +58,7 @@
 #include <linux/timer.h>
 #include <linux/pci.h>
 #include <linux/aer.h>
+#include <linux/slab.h>
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/system.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/atari_NCR5380.c linux-libre-2.6.34-gnu1/drivers/scsi/atari_NCR5380.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/atari_NCR5380.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/atari_NCR5380.c	2010-05-16 17:17:36.000000000 -0400
@@ -651,6 +651,7 @@ static inline void NCR5380_print_phase(s
  * interrupt or bottom half.
  */
 
+#include <linux/gfp.h>
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/atp870u.c linux-libre-2.6.34-gnu1/drivers/scsi/atp870u.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/atp870u.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/atp870u.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/pci.h>
 #include <linux/blkdev.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <asm/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_cmds.c linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_cmds.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_cmds.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_cmds.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -19,7 +19,7 @@
 #include "be_mgmt.h"
 #include "be_main.h"
 
-static void be_mcc_notify(struct beiscsi_hba *phba)
+void be_mcc_notify(struct beiscsi_hba *phba)
 {
 	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
 	u32 val = 0;
@@ -29,6 +29,45 @@ static void be_mcc_notify(struct beiscsi
 	iowrite32(val, phba->db_va + DB_MCCQ_OFFSET);
 }
 
+unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
+{
+	unsigned int tag = 0;
+
+	if (phba->ctrl.mcc_tag_available) {
+		tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
+		phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
+		phba->ctrl.mcc_numtag[tag] = 0;
+	}
+	if (tag) {
+		phba->ctrl.mcc_tag_available--;
+		if (phba->ctrl.mcc_alloc_index == (MAX_MCC_CMD - 1))
+			phba->ctrl.mcc_alloc_index = 0;
+		else
+			phba->ctrl.mcc_alloc_index++;
+	}
+	return tag;
+}
+
+void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
+{
+	spin_lock(&ctrl->mbox_lock);
+	tag = tag & 0x000000FF;
+	ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
+	if (ctrl->mcc_free_index == (MAX_MCC_CMD - 1))
+		ctrl->mcc_free_index = 0;
+	else
+		ctrl->mcc_free_index++;
+	ctrl->mcc_tag_available++;
+	spin_unlock(&ctrl->mbox_lock);
+}
+
+bool is_link_state_evt(u32 trailer)
+{
+	return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
+		  ASYNC_TRAILER_EVENT_CODE_MASK) ==
+		  ASYNC_EVENT_CODE_LINK_STATE);
+}
+
 static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
 {
 	if (compl->flags != 0) {
@@ -64,12 +103,30 @@ static int be_mcc_compl_process(struct b
 	return 0;
 }
 
-
-static inline bool is_link_state_evt(u32 trailer)
+int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
+				    struct be_mcc_compl *compl)
 {
-	return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
-		  ASYNC_TRAILER_EVENT_CODE_MASK) ==
-		  ASYNC_EVENT_CODE_LINK_STATE);
+	u16 compl_status, extd_status;
+	unsigned short tag;
+
+	be_dws_le_to_cpu(compl, 4);
+
+	compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
+					CQE_STATUS_COMPL_MASK;
+	/* The ctrl.mcc_numtag[tag] is filled with
+	 * [31] = valid, [30:24] = Rsvd, [23:16] = wrb, [15:8] = extd_status,
+	 * [7:0] = compl_status
+	 */
+	tag = (compl->tag0 & 0x000000FF);
+	extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
+					CQE_STATUS_EXTD_MASK;
+
+	ctrl->mcc_numtag[tag]  = 0x80000000;
+	ctrl->mcc_numtag[tag] |= (compl->tag0 & 0x00FF0000);
+	ctrl->mcc_numtag[tag] |= (extd_status & 0x000000FF) << 8;
+	ctrl->mcc_numtag[tag] |= (compl_status & 0x000000FF);
+	wake_up_interruptible(&ctrl->mcc_wait[tag]);
+	return 0;
 }
 
 static struct be_mcc_compl *be_mcc_compl_get(struct beiscsi_hba *phba)
@@ -89,7 +146,7 @@ static void be2iscsi_fail_session(struct
 	iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
 }
 
-static void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
+void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
 		struct be_async_event_link_state *evt)
 {
 	switch (evt->port_link_status) {
@@ -97,13 +154,13 @@ static void beiscsi_async_link_state_pro
 		SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d \n",
 						evt->physical_port);
 		phba->state |= BE_ADAPTER_LINK_DOWN;
+		iscsi_host_for_each_session(phba->shost,
+					    be2iscsi_fail_session);
 		break;
 	case ASYNC_EVENT_LINK_UP:
 		phba->state = BE_ADAPTER_UP;
 		SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d \n",
 						evt->physical_port);
-		iscsi_host_for_each_session(phba->shost,
-					    be2iscsi_fail_session);
 		break;
 	default:
 		SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on"
@@ -162,7 +219,6 @@ int beiscsi_process_mcc(struct beiscsi_h
 /* Wait till no more pending mcc requests are present */
 static int be_mcc_wait_compl(struct beiscsi_hba *phba)
 {
-#define mcc_timeout		120000 /* 5s timeout */
 	int i, status;
 	for (i = 0; i < mcc_timeout; i++) {
 		status = beiscsi_process_mcc(phba);
@@ -372,9 +428,10 @@ struct be_mcc_wrb *wrb_from_mccq(struct
 
 	BUG_ON(atomic_read(&mccq->used) >= mccq->len);
 	wrb = queue_head_node(mccq);
+	memset(wrb, 0, sizeof(*wrb));
+	wrb->tag0 = (mccq->head & 0x000000FF) << 16;
 	queue_head_inc(mccq);
 	atomic_inc(&mccq->used);
-	memset(wrb, 0, sizeof(*wrb));
 	return wrb;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_cmds.h linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_cmds.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_cmds.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_cmds.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -425,14 +425,20 @@ int beiscsi_cmd_mccq_create(struct beisc
 int be_poll_mcc(struct be_ctrl_info *ctrl);
 unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
 				      struct beiscsi_hba *phba);
-int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr);
-
+unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba);
+void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);
 /*ISCSI Functuions */
 int be_cmd_fw_initialize(struct be_ctrl_info *ctrl);
 
 struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem);
 struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba);
 int be_mcc_notify_wait(struct beiscsi_hba *phba);
+void be_mcc_notify(struct beiscsi_hba *phba);
+unsigned int alloc_mcc_tag(struct beiscsi_hba *phba);
+void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
+		struct be_async_event_link_state *evt);
+int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
+				    struct be_mcc_compl *compl);
 
 int be_mbox_notify(struct be_ctrl_info *ctrl);
 
@@ -448,6 +454,8 @@ int be_cmd_iscsi_post_sgl_pages(struct b
 int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem,
 		       struct be_queue_info *wrbq);
 
+bool is_link_state_evt(u32 trailer);
+
 struct be_default_pdu_context {
 	u32 dw[4];
 } __packed;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be.h linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -24,6 +24,10 @@
 #define FW_VER_LEN	32
 #define MCC_Q_LEN	128
 #define MCC_CQ_LEN	256
+#define MAX_MCC_CMD	16
+/* BladeEngine Generation numbers */
+#define BE_GEN2 2
+#define BE_GEN3 3
 
 struct be_dma_mem {
 	void *va;
@@ -57,6 +61,11 @@ static inline void *queue_head_node(stru
 	return q->dma_mem.va + q->head * q->entry_size;
 }
 
+static inline void *queue_get_wrb(struct be_queue_info *q, unsigned int wrb_num)
+{
+	return q->dma_mem.va + wrb_num * q->entry_size;
+}
+
 static inline void *queue_tail_node(struct be_queue_info *q)
 {
 	return q->dma_mem.va + q->tail * q->entry_size;
@@ -104,15 +113,19 @@ struct be_ctrl_info {
 	spinlock_t mcc_lock;	/* For serializing mcc cmds to BE card */
 	spinlock_t mcc_cq_lock;
 
-	/* MCC Async callback */
-	void (*async_cb) (void *adapter, bool link_up);
-	void *adapter_ctxt;
+	wait_queue_head_t mcc_wait[MAX_MCC_CMD + 1];
+	unsigned int mcc_tag[MAX_MCC_CMD];
+	unsigned int mcc_numtag[MAX_MCC_CMD + 1];
+	unsigned short mcc_alloc_index;
+	unsigned short mcc_free_index;
+	unsigned int mcc_tag_available;
 };
 
 #include "be_cmds.h"
 
 #define PAGE_SHIFT_4K 12
 #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
+#define mcc_timeout		120000 /* 5s timeout */
 
 /* Returns number of pages spanned by the data starting at the given addr */
 #define PAGES_4K_SPANNED(_address, size) 				\
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_iscsi.c linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_iscsi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_iscsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_iscsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -101,6 +101,7 @@ void beiscsi_session_destroy(struct iscs
 	struct iscsi_session *sess = cls_session->dd_data;
 	struct beiscsi_session *beiscsi_sess = sess->dd_data;
 
+	SE_DEBUG(DBG_LVL_8, "In beiscsi_session_destroy\n");
 	pci_pool_destroy(beiscsi_sess->bhs_pool);
 	iscsi_session_teardown(cls_session);
 }
@@ -224,6 +225,7 @@ int beiscsi_conn_get_param(struct iscsi_
 	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
 	int len = 0;
 
+	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_get_param, param= %d\n", param);
 	beiscsi_ep = beiscsi_conn->ep;
 	if (!beiscsi_ep) {
 		SE_DEBUG(DBG_LVL_1,
@@ -254,6 +256,7 @@ int beiscsi_set_param(struct iscsi_cls_c
 	struct iscsi_session *session = conn->session;
 	int ret;
 
+	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_set_param, param= %d\n", param);
 	ret = iscsi_set_param(cls_conn, param, buf, buflen);
 	if (ret)
 		return ret;
@@ -271,8 +274,8 @@ int beiscsi_set_param(struct iscsi_cls_c
 			conn->max_recv_dlength = 65536;
 		break;
 	case ISCSI_PARAM_MAX_BURST:
-		if (session->first_burst > 262144)
-			session->first_burst = 262144;
+		if (session->max_burst > 262144)
+			session->max_burst = 262144;
 		break;
 	default:
 		return 0;
@@ -293,12 +296,41 @@ int beiscsi_get_host_param(struct Scsi_H
 			   enum iscsi_host_param param, char *buf)
 {
 	struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost);
+	struct be_cmd_resp_get_mac_addr *resp;
+	struct be_mcc_wrb *wrb;
+	unsigned int tag, wrb_num;
 	int len = 0;
+	unsigned short status, extd_status;
+	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
 
+	SE_DEBUG(DBG_LVL_8, "In beiscsi_get_host_param, param= %d\n", param);
 	switch (param) {
 	case ISCSI_HOST_PARAM_HWADDRESS:
-		be_cmd_get_mac_addr(phba, phba->mac_address);
-		len = sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
+		tag = be_cmd_get_mac_addr(phba);
+		if (!tag) {
+			SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed \n");
+			return -1;
+		} else
+			wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+						 phba->ctrl.mcc_numtag[tag]);
+
+		wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
+		extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
+		status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
+		if (status || extd_status) {
+			SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed"
+					    " status = %d extd_status = %d \n",
+					    status, extd_status);
+			free_mcc_tag(&phba->ctrl, tag);
+			return -1;
+		} else {
+			wrb = queue_get_wrb(mccq, wrb_num);
+			free_mcc_tag(&phba->ctrl, tag);
+			resp = embedded_payload(wrb);
+			memcpy(phba->mac_address, resp->mac_address, ETH_ALEN);
+			len = sysfs_format_mac(buf, phba->mac_address,
+					       ETH_ALEN);
+		}
 		break;
 	default:
 		return iscsi_host_get_param(shost, param, buf);
@@ -378,6 +410,7 @@ int beiscsi_conn_start(struct iscsi_cls_
 	struct beiscsi_endpoint *beiscsi_ep;
 	struct beiscsi_offload_params params;
 
+	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_start\n");
 	memset(&params, 0, sizeof(struct beiscsi_offload_params));
 	beiscsi_ep = beiscsi_conn->ep;
 	if (!beiscsi_ep)
@@ -422,8 +455,14 @@ static int beiscsi_open_conn(struct iscs
 {
 	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
 	struct beiscsi_hba *phba = beiscsi_ep->phba;
+	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
+	struct be_mcc_wrb *wrb;
+	struct tcp_connect_and_offload_out *ptcpcnct_out;
+	unsigned short status, extd_status;
+	unsigned int tag, wrb_num;
 	int ret = -1;
 
+	SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn\n");
 	beiscsi_ep->ep_cid = beiscsi_get_cid(phba);
 	if (beiscsi_ep->ep_cid == 0xFFFF) {
 		SE_DEBUG(DBG_LVL_1, "No free cid available\n");
@@ -431,15 +470,44 @@ static int beiscsi_open_conn(struct iscs
 	}
 	SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn, ep_cid=%d ",
 		 beiscsi_ep->ep_cid);
-	phba->ep_array[beiscsi_ep->ep_cid] = ep;
-	if (beiscsi_ep->ep_cid >
-	    (phba->fw_config.iscsi_cid_start + phba->params.cxns_per_ctrl)) {
+	phba->ep_array[beiscsi_ep->ep_cid -
+		       phba->fw_config.iscsi_cid_start] = ep;
+	if (beiscsi_ep->ep_cid > (phba->fw_config.iscsi_cid_start +
+				  phba->params.cxns_per_ctrl * 2)) {
 		SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n");
 		return ret;
 	}
 
 	beiscsi_ep->cid_vld = 0;
-	return mgmt_open_connection(phba, dst_addr, beiscsi_ep);
+	tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep);
+	if (!tag) {
+		SE_DEBUG(DBG_LVL_1,
+			 "mgmt_open_connection Failed for cid=%d \n",
+			 beiscsi_ep->ep_cid);
+	} else {
+		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+					 phba->ctrl.mcc_numtag[tag]);
+	}
+	wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
+	extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
+	status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
+	if (status || extd_status) {
+		SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed"
+				    " status = %d extd_status = %d \n",
+				    status, extd_status);
+		free_mcc_tag(&phba->ctrl, tag);
+		return -1;
+	} else {
+		wrb = queue_get_wrb(mccq, wrb_num);
+		free_mcc_tag(&phba->ctrl, tag);
+
+		ptcpcnct_out = 	embedded_payload(wrb);
+		beiscsi_ep = ep->dd_data;
+		beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
+		beiscsi_ep->cid_vld = 1;
+		SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n");
+	}
+	return 0;
 }
 
 /**
@@ -459,14 +527,12 @@ static void beiscsi_put_cid(struct beisc
  * beiscsi_free_ep - free endpoint
  * @ep:	pointer to iscsi endpoint structure
  */
-static void beiscsi_free_ep(struct iscsi_endpoint *ep)
+static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep)
 {
-	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
 	struct beiscsi_hba *phba = beiscsi_ep->phba;
 
 	beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
 	beiscsi_ep->phba = NULL;
-	iscsi_destroy_endpoint(ep);
 }
 
 /**
@@ -495,9 +561,9 @@ beiscsi_ep_connect(struct Scsi_Host *sho
 		return ERR_PTR(ret);
 	}
 
-	if (phba->state) {
+	if (phba->state != BE_ADAPTER_UP) {
 		ret = -EBUSY;
-		SE_DEBUG(DBG_LVL_1, "The Adapet state is Not UP \n");
+		SE_DEBUG(DBG_LVL_1, "The Adapter state is Not UP \n");
 		return ERR_PTR(ret);
 	}
 
@@ -509,9 +575,9 @@ beiscsi_ep_connect(struct Scsi_Host *sho
 
 	beiscsi_ep = ep->dd_data;
 	beiscsi_ep->phba = phba;
-
+	beiscsi_ep->openiscsi_ep = ep;
 	if (beiscsi_open_conn(ep, NULL, dst_addr, non_blocking)) {
-		SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n");
+		SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn \n");
 		ret = -ENOMEM;
 		goto free_ep;
 	}
@@ -519,7 +585,7 @@ beiscsi_ep_connect(struct Scsi_Host *sho
 	return ep;
 
 free_ep:
-	beiscsi_free_ep(ep);
+	beiscsi_free_ep(beiscsi_ep);
 	return ERR_PTR(ret);
 }
 
@@ -546,20 +612,22 @@ int beiscsi_ep_poll(struct iscsi_endpoin
  * @ep: The iscsi endpoint
  * @flag: The type of connection closure
  */
-static int beiscsi_close_conn(struct iscsi_endpoint *ep, int flag)
+static int beiscsi_close_conn(struct  beiscsi_endpoint *beiscsi_ep, int flag)
 {
 	int ret = 0;
-	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
+	unsigned int tag;
 	struct beiscsi_hba *phba = beiscsi_ep->phba;
 
-	if (MGMT_STATUS_SUCCESS !=
-	    mgmt_upload_connection(phba, beiscsi_ep->ep_cid,
-		CONNECTION_UPLOAD_GRACEFUL)) {
+	tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag);
+	if (!tag) {
 		SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x",
 			 beiscsi_ep->ep_cid);
 		ret = -1;
+	} else {
+		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+					 phba->ctrl.mcc_numtag[tag]);
+		free_mcc_tag(&phba->ctrl, tag);
 	}
-
 	return ret;
 }
 
@@ -574,19 +642,17 @@ void beiscsi_ep_disconnect(struct iscsi_
 	struct beiscsi_conn *beiscsi_conn;
 	struct beiscsi_endpoint *beiscsi_ep;
 	struct beiscsi_hba *phba;
-	int flag = 0;
 
 	beiscsi_ep = ep->dd_data;
 	phba = beiscsi_ep->phba;
-	SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect\n");
+	SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect for ep_cid = %d\n",
+			     beiscsi_ep->ep_cid);
 
 	if (beiscsi_ep->conn) {
 		beiscsi_conn = beiscsi_ep->conn;
 		iscsi_suspend_queue(beiscsi_conn->conn);
-		beiscsi_close_conn(ep, flag);
 	}
 
-	beiscsi_free_ep(ep);
 }
 
 /**
@@ -619,23 +685,31 @@ void beiscsi_conn_stop(struct iscsi_cls_
 	struct iscsi_session *session = conn->session;
 	struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session);
 	struct beiscsi_hba *phba = iscsi_host_priv(shost);
-	unsigned int status;
+	unsigned int tag;
 	unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH;
 
-	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop\n");
 	beiscsi_ep = beiscsi_conn->ep;
 	if (!beiscsi_ep) {
 		SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop , no beiscsi_ep\n");
 		return;
 	}
-	status = mgmt_invalidate_connection(phba, beiscsi_ep,
+	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop  ep_cid = %d\n",
+			     beiscsi_ep->ep_cid);
+	tag = mgmt_invalidate_connection(phba, beiscsi_ep,
 					    beiscsi_ep->ep_cid, 1,
 					    savecfg_flag);
-	if (status != MGMT_STATUS_SUCCESS) {
+	if (!tag) {
 		SE_DEBUG(DBG_LVL_1,
 			 "mgmt_invalidate_connection Failed for cid=%d \n",
-			 beiscsi_ep->ep_cid);
+			  beiscsi_ep->ep_cid);
+	} else {
+		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+					 phba->ctrl.mcc_numtag[tag]);
+		free_mcc_tag(&phba->ctrl, tag);
 	}
+	beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL);
+	beiscsi_free_ep(beiscsi_ep);
+	iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep);
 	beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid);
 	iscsi_conn_stop(cls_conn, flag);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_iscsi.h linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_iscsi.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_iscsi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_iscsi.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_main.c linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_main.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -19,6 +19,7 @@
  */
 #include <linux/reboot.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/blkdev.h>
 #include <linux/pci.h>
@@ -40,7 +41,6 @@
 static unsigned int be_iopoll_budget = 10;
 static unsigned int be_max_phys_size = 64;
 static unsigned int enable_msix = 1;
-static unsigned int ring_mode;
 
 MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
 MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR);
@@ -59,13 +59,130 @@ static int beiscsi_slave_configure(struc
 	return 0;
 }
 
+static int beiscsi_eh_abort(struct scsi_cmnd *sc)
+{
+	struct iscsi_cls_session *cls_session;
+	struct iscsi_task *aborted_task = (struct iscsi_task *)sc->SCp.ptr;
+	struct beiscsi_io_task *aborted_io_task;
+	struct iscsi_conn *conn;
+	struct beiscsi_conn *beiscsi_conn;
+	struct beiscsi_hba *phba;
+	struct iscsi_session *session;
+	struct invalidate_command_table *inv_tbl;
+	unsigned int cid, tag, num_invalidate;
+
+	cls_session = starget_to_session(scsi_target(sc->device));
+	session = cls_session->dd_data;
+
+	spin_lock_bh(&session->lock);
+	if (!aborted_task || !aborted_task->sc) {
+		/* we raced */
+		spin_unlock_bh(&session->lock);
+		return SUCCESS;
+	}
+
+	aborted_io_task = aborted_task->dd_data;
+	if (!aborted_io_task->scsi_cmnd) {
+		/* raced or invalid command */
+		spin_unlock_bh(&session->lock);
+		return SUCCESS;
+	}
+	spin_unlock_bh(&session->lock);
+	conn = aborted_task->conn;
+	beiscsi_conn = conn->dd_data;
+	phba = beiscsi_conn->phba;
+
+	/* invalidate iocb */
+	cid = beiscsi_conn->beiscsi_conn_cid;
+	inv_tbl = phba->inv_tbl;
+	memset(inv_tbl, 0x0, sizeof(*inv_tbl));
+	inv_tbl->cid = cid;
+	inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index;
+	num_invalidate = 1;
+	tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
+	if (!tag) {
+		shost_printk(KERN_WARNING, phba->shost,
+			     "mgmt_invalidate_icds could not be"
+			     " submitted\n");
+		return FAILED;
+	} else {
+		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+					 phba->ctrl.mcc_numtag[tag]);
+		free_mcc_tag(&phba->ctrl, tag);
+	}
+
+	return iscsi_eh_abort(sc);
+}
+
+static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
+{
+	struct iscsi_task *abrt_task;
+	struct beiscsi_io_task *abrt_io_task;
+	struct iscsi_conn *conn;
+	struct beiscsi_conn *beiscsi_conn;
+	struct beiscsi_hba *phba;
+	struct iscsi_session *session;
+	struct iscsi_cls_session *cls_session;
+	struct invalidate_command_table *inv_tbl;
+	unsigned int cid, tag, i, num_invalidate;
+	int rc = FAILED;
+
+	/* invalidate iocbs */
+	cls_session = starget_to_session(scsi_target(sc->device));
+	session = cls_session->dd_data;
+	spin_lock_bh(&session->lock);
+	if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN)
+		goto unlock;
+
+	conn = session->leadconn;
+	beiscsi_conn = conn->dd_data;
+	phba = beiscsi_conn->phba;
+	cid = beiscsi_conn->beiscsi_conn_cid;
+	inv_tbl = phba->inv_tbl;
+	memset(inv_tbl, 0x0, sizeof(*inv_tbl) * BE2_CMDS_PER_CXN);
+	num_invalidate = 0;
+	for (i = 0; i < conn->session->cmds_max; i++) {
+		abrt_task = conn->session->cmds[i];
+		abrt_io_task = abrt_task->dd_data;
+		if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE)
+			continue;
+
+		if (abrt_task->sc->device->lun != abrt_task->sc->device->lun)
+			continue;
+
+		inv_tbl->cid = cid;
+		inv_tbl->icd = abrt_io_task->psgl_handle->sgl_index;
+		num_invalidate++;
+		inv_tbl++;
+	}
+	spin_unlock_bh(&session->lock);
+	inv_tbl = phba->inv_tbl;
+
+	tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
+	if (!tag) {
+		shost_printk(KERN_WARNING, phba->shost,
+			     "mgmt_invalidate_icds could not be"
+			     " submitted\n");
+		return FAILED;
+	} else {
+		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+					 phba->ctrl.mcc_numtag[tag]);
+		free_mcc_tag(&phba->ctrl, tag);
+	}
+
+	return iscsi_eh_device_reset(sc);
+unlock:
+	spin_unlock_bh(&session->lock);
+	return rc;
+}
+
 /*------------------- PCI Driver operations and data ----------------- */
 static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
 	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
+	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) },
 	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
 	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
 	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID3) },
-	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID4) },
 	{ 0 }
 };
 MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
@@ -75,12 +192,12 @@ static struct scsi_host_template beiscsi
 	.name = "ServerEngines 10Gbe open-iscsi Initiator Driver",
 	.proc_name = DRV_NAME,
 	.queuecommand = iscsi_queuecommand,
-	.eh_abort_handler = iscsi_eh_abort,
 	.change_queue_depth = iscsi_change_queue_depth,
 	.slave_configure = beiscsi_slave_configure,
 	.target_alloc = iscsi_target_alloc,
-	.eh_device_reset_handler = iscsi_eh_device_reset,
-	.eh_target_reset_handler = iscsi_eh_target_reset,
+	.eh_abort_handler = beiscsi_eh_abort,
+	.eh_device_reset_handler = beiscsi_eh_device_reset,
+	.eh_target_reset_handler = iscsi_eh_session_reset,
 	.sg_tablesize = BEISCSI_SGLIST_ELEMENTS,
 	.can_queue = BE2_IO_DEPTH,
 	.this_id = -1,
@@ -112,6 +229,7 @@ static struct beiscsi_hba *beiscsi_hba_a
 	memset(phba, 0, sizeof(*phba));
 	phba->shost = shost;
 	phba->pcidev = pci_dev_get(pcidev);
+	pci_set_drvdata(pcidev, phba);
 
 	if (iscsi_host_add(shost, &phba->pcidev->dev))
 		goto free_devices;
@@ -143,6 +261,7 @@ static int beiscsi_map_pci_bars(struct b
 				struct pci_dev *pcidev)
 {
 	u8 __iomem *addr;
+	int pcicfg_reg;
 
 	addr = ioremap_nocache(pci_resource_start(pcidev, 2),
 			       pci_resource_len(pcidev, 2));
@@ -159,13 +278,19 @@ static int beiscsi_map_pci_bars(struct b
 	phba->db_va = addr;
 	phba->db_pa.u.a64.address =  pci_resource_start(pcidev, 4);
 
-	addr = ioremap_nocache(pci_resource_start(pcidev, 1),
-			       pci_resource_len(pcidev, 1));
+	if (phba->generation == BE_GEN2)
+		pcicfg_reg = 1;
+	else
+		pcicfg_reg = 0;
+
+	addr = ioremap_nocache(pci_resource_start(pcidev, pcicfg_reg),
+			       pci_resource_len(pcidev, pcicfg_reg));
+
 	if (addr == NULL)
 		goto pci_map_err;
 	phba->ctrl.pcicfg = addr;
 	phba->pci_va = addr;
-	phba->pci_pa.u.a64.address = pci_resource_start(pcidev, 1);
+	phba->pci_pa.u.a64.address = pci_resource_start(pcidev, pcicfg_reg);
 	return 0;
 
 pci_map_err:
@@ -230,29 +355,27 @@ static int be_ctrl_init(struct beiscsi_h
 
 static void beiscsi_get_params(struct beiscsi_hba *phba)
 {
-	phba->params.ios_per_ctrl = BE2_IO_DEPTH;
-	phba->params.cxns_per_ctrl = BE2_MAX_SESSIONS;
-	phba->params.asyncpdus_per_ctrl = BE2_ASYNCPDUS;
-	phba->params.icds_per_ctrl = BE2_MAX_ICDS / 2;
+	phba->params.ios_per_ctrl = (phba->fw_config.iscsi_icd_count
+				    - (phba->fw_config.iscsi_cid_count
+				    + BE2_TMFS
+				    + BE2_NOPOUT_REQ));
+	phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count;
+	phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count * 2;
+	phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;;
 	phba->params.num_sge_per_io = BE2_SGE;
 	phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ;
 	phba->params.defpdu_data_sz = BE2_DEFPDU_DATA_SZ;
 	phba->params.eq_timer = 64;
 	phba->params.num_eq_entries =
-	    (((BE2_CMDS_PER_CXN * 2 + BE2_LOGOUTS + BE2_TMFS + BE2_ASYNCPDUS) /
-								512) + 1) * 512;
+	    (((BE2_CMDS_PER_CXN * 2 + phba->fw_config.iscsi_cid_count * 2
+				    + BE2_TMFS) / 512) + 1) * 512;
 	phba->params.num_eq_entries = (phba->params.num_eq_entries < 1024)
 				? 1024 : phba->params.num_eq_entries;
 	SE_DEBUG(DBG_LVL_8, "phba->params.num_eq_entries=%d \n",
-		 phba->params.num_eq_entries);
+			     phba->params.num_eq_entries);
 	phba->params.num_cq_entries =
-	    (((BE2_CMDS_PER_CXN * 2 + BE2_LOGOUTS + BE2_TMFS + BE2_ASYNCPDUS) /
-								512) + 1) * 512;
-	SE_DEBUG(DBG_LVL_8,
-		"phba->params.num_cq_entries=%d BE2_CMDS_PER_CXN=%d"
-		"BE2_LOGOUTS=%d BE2_TMFS=%d BE2_ASYNCPDUS=%d \n",
-		phba->params.num_cq_entries, BE2_CMDS_PER_CXN,
-		BE2_LOGOUTS, BE2_TMFS, BE2_ASYNCPDUS);
+	    (((BE2_CMDS_PER_CXN * 2 +  phba->fw_config.iscsi_cid_count * 2
+				    + BE2_TMFS) / 512) + 1) * 512;
 	phba->params.wrbs_per_cxn = 256;
 }
 
@@ -443,7 +566,7 @@ static irqreturn_t be_isr(int irq, void
 			if (phba->todo_mcc_cq)
 				queue_work(phba->wq, &phba->work_cqs);
 
-		if ((num_mcceq_processed) && (!num_ioeq_processed))
+			if ((num_mcceq_processed) && (!num_ioeq_processed))
 				hwi_ring_eq_db(phba, eq->id, 0,
 					      (num_ioeq_processed +
 					       num_mcceq_processed) , 1, 1);
@@ -561,6 +684,7 @@ beiscsi_process_async_pdu(struct beiscsi
 		SE_DEBUG(DBG_LVL_1, "In ISCSI_OP_REJECT\n");
 		break;
 	case ISCSI_OP_LOGIN_RSP:
+	case ISCSI_OP_TEXT_RSP:
 		task = conn->login_task;
 		io_task = task->dd_data;
 		login_hdr = (struct iscsi_hdr *)ppdu;
@@ -631,29 +755,29 @@ free_io_sgl_handle(struct beiscsi_hba *p
  * alloc_wrb_handle - To allocate a wrb handle
  * @phba: The hba pointer
  * @cid: The cid to use for allocation
- * @index: index allocation and wrb index
  *
  * This happens under session_lock until submission to chip
  */
-struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid,
-				    int index)
+struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid)
 {
 	struct hwi_wrb_context *pwrb_context;
 	struct hwi_controller *phwi_ctrlr;
-	struct wrb_handle *pwrb_handle;
+	struct wrb_handle *pwrb_handle, *pwrb_handle_tmp;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
 	pwrb_context = &phwi_ctrlr->wrb_context[cid];
-	if (pwrb_context->wrb_handles_available) {
+	if (pwrb_context->wrb_handles_available >= 2) {
 		pwrb_handle = pwrb_context->pwrb_handle_base[
 					    pwrb_context->alloc_index];
 		pwrb_context->wrb_handles_available--;
-		pwrb_handle->nxt_wrb_index = pwrb_handle->wrb_index;
 		if (pwrb_context->alloc_index ==
 						(phba->params.wrbs_per_cxn - 1))
 			pwrb_context->alloc_index = 0;
 		else
 			pwrb_context->alloc_index++;
+		pwrb_handle_tmp = pwrb_context->pwrb_handle_base[
+						pwrb_context->alloc_index];
+		pwrb_handle->nxt_wrb_index = pwrb_handle_tmp->wrb_index;
 	} else
 		pwrb_handle = NULL;
 	return pwrb_handle;
@@ -671,9 +795,7 @@ static void
 free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context,
 		struct wrb_handle *pwrb_handle)
 {
-	if (!ring_mode)
-		pwrb_context->pwrb_handle_base[pwrb_context->free_index] =
-					       pwrb_handle;
+	pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle;
 	pwrb_context->wrb_handles_available++;
 	if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1))
 		pwrb_context->free_index = 0;
@@ -790,6 +912,7 @@ be_complete_io(struct beiscsi_conn *beis
 		memcpy(task->sc->sense_buffer, sense,
 		       min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE));
 	}
+
 	if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) {
 		if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
 							& SOL_RES_CNT_MASK)
@@ -811,6 +934,7 @@ be_complete_logout(struct beiscsi_conn *
 	struct iscsi_conn *conn = beiscsi_conn->conn;
 
 	hdr = (struct iscsi_logout_rsp *)task->hdr;
+	hdr->opcode = ISCSI_OP_LOGOUT_RSP;
 	hdr->t2wait = 5;
 	hdr->t2retain = 0;
 	hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
@@ -825,6 +949,9 @@ be_complete_logout(struct beiscsi_conn *
 					& SOL_EXP_CMD_SN_MASK) +
 			((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
 					/ 32] & SOL_CMD_WND_MASK) >> 24) - 1);
+	hdr->dlength[0] = 0;
+	hdr->dlength[1] = 0;
+	hdr->dlength[2] = 0;
 	hdr->hlength = 0;
 	hdr->itt = io_task->libiscsi_itt;
 	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
@@ -839,6 +966,7 @@ be_complete_tmf(struct beiscsi_conn *bei
 	struct beiscsi_io_task *io_task = task->dd_data;
 
 	hdr = (struct iscsi_tm_rsp *)task->hdr;
+	hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP;
 	hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
 					& SOL_FLAGS_MASK) >> 24) | 0x80;
 	hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) /
@@ -859,7 +987,6 @@ hwi_complete_drvr_msgs(struct beiscsi_co
 {
 	struct hwi_wrb_context *pwrb_context;
 	struct wrb_handle *pwrb_handle = NULL;
-	struct sgl_handle *psgl_handle = NULL;
 	struct hwi_controller *phwi_ctrlr;
 	struct iscsi_task *task;
 	struct beiscsi_io_task *io_task;
@@ -867,22 +994,14 @@ hwi_complete_drvr_msgs(struct beiscsi_co
 	struct iscsi_session *session = conn->session;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
-	if (ring_mode) {
-		psgl_handle = phba->sgl_hndl_array[((psol->
-			      dw[offsetof(struct amap_sol_cqe_ring, icd_index) /
-				32] & SOL_ICD_INDEX_MASK) >> 6)];
-		pwrb_context = &phwi_ctrlr->wrb_context[psgl_handle->cid];
-		task = psgl_handle->task;
-		pwrb_handle = NULL;
-	} else {
-		pwrb_context = &phwi_ctrlr->wrb_context[((psol->
+	pwrb_context = &phwi_ctrlr->wrb_context[((psol->
 				dw[offsetof(struct amap_sol_cqe, cid) / 32] &
-				SOL_CID_MASK) >> 6)];
-		pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
+				SOL_CID_MASK) >> 6) -
+				phba->fw_config.iscsi_cid_start];
+	pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
 				dw[offsetof(struct amap_sol_cqe, wrb_index) /
 				32] & SOL_WRB_INDEX_MASK) >> 16)];
-		task = pwrb_handle->pio_handle;
-	}
+	task = pwrb_handle->pio_handle;
 
 	io_task = task->dd_data;
 	spin_lock(&phba->mgmt_sgl_lock);
@@ -923,44 +1042,40 @@ static void hwi_complete_cmd(struct beis
 	struct iscsi_wrb *pwrb = NULL;
 	struct hwi_controller *phwi_ctrlr;
 	struct iscsi_task *task;
-	struct sgl_handle *psgl_handle = NULL;
 	unsigned int type;
 	struct iscsi_conn *conn = beiscsi_conn->conn;
 	struct iscsi_session *session = conn->session;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
-	if (ring_mode) {
-		psgl_handle = phba->sgl_hndl_array[((psol->
-			      dw[offsetof(struct amap_sol_cqe_ring, icd_index) /
-			      32] & SOL_ICD_INDEX_MASK) >> 6)];
-		task = psgl_handle->task;
-		type = psgl_handle->type;
-	} else {
-		pwrb_context = &phwi_ctrlr->
-				wrb_context[((psol->dw[offsetof
+	pwrb_context = &phwi_ctrlr->wrb_context[((psol->dw[offsetof
 				(struct amap_sol_cqe, cid) / 32]
-				& SOL_CID_MASK) >> 6)];
-		pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
+				& SOL_CID_MASK) >> 6) -
+				phba->fw_config.iscsi_cid_start];
+	pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
 				dw[offsetof(struct amap_sol_cqe, wrb_index) /
 				32] & SOL_WRB_INDEX_MASK) >> 16)];
-		task = pwrb_handle->pio_handle;
-		pwrb = pwrb_handle->pwrb;
-		type = (pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] &
-			 WRB_TYPE_MASK) >> 28;
-	}
+	task = pwrb_handle->pio_handle;
+	pwrb = pwrb_handle->pwrb;
+	type = (pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] &
+				 WRB_TYPE_MASK) >> 28;
+
 	spin_lock_bh(&session->lock);
 	switch (type) {
 	case HWH_TYPE_IO:
 	case HWH_TYPE_IO_RD:
 		if ((task->hdr->opcode & ISCSI_OPCODE_MASK) ==
-		    ISCSI_OP_NOOP_OUT) {
+		     ISCSI_OP_NOOP_OUT)
 			be_complete_nopin_resp(beiscsi_conn, task, psol);
-		} else
+		else
 			be_complete_io(beiscsi_conn, task, psol);
 		break;
 
 	case HWH_TYPE_LOGOUT:
-		be_complete_logout(beiscsi_conn, task, psol);
+		if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
+			be_complete_logout(beiscsi_conn, task, psol);
+		else
+			be_complete_tmf(beiscsi_conn, task, psol);
+
 		break;
 
 	case HWH_TYPE_LOGIN:
@@ -969,24 +1084,12 @@ static void hwi_complete_cmd(struct beis
 			 "- Solicited path \n");
 		break;
 
-	case HWH_TYPE_TMF:
-		be_complete_tmf(beiscsi_conn, task, psol);
-		break;
-
 	case HWH_TYPE_NOP:
 		be_complete_nopin_resp(beiscsi_conn, task, psol);
 		break;
 
 	default:
-		if (ring_mode)
-			shost_printk(KERN_WARNING, phba->shost,
-				"In hwi_complete_cmd, unknown type = %d"
-				"icd_index 0x%x CID 0x%x\n", type,
-				((psol->dw[offsetof(struct amap_sol_cqe_ring,
-				icd_index) / 32] & SOL_ICD_INDEX_MASK) >> 6),
-				psgl_handle->cid);
-		else
-			shost_printk(KERN_WARNING, phba->shost,
+		shost_printk(KERN_WARNING, phba->shost,
 				"In hwi_complete_cmd, unknown type = %d"
 				"wrb_index 0x%x CID 0x%x\n", type,
 				((psol->dw[offsetof(struct amap_iscsi_wrb,
@@ -1077,7 +1180,8 @@ hwi_get_async_handle(struct beiscsi_hba
 
 	WARN_ON(!pasync_handle);
 
-	pasync_handle->cri = (unsigned short)beiscsi_conn->beiscsi_conn_cid;
+	pasync_handle->cri = (unsigned short)beiscsi_conn->beiscsi_conn_cid -
+					     phba->fw_config.iscsi_cid_start;
 	pasync_handle->is_header = is_header;
 	pasync_handle->buffer_len = ((pdpdu_cqe->
 			dw[offsetof(struct amap_i_t_dpdu_cqe, dpl) / 32]
@@ -1327,9 +1431,10 @@ hwi_fwd_async_msg(struct beiscsi_conn *b
 	}
 
 	status = beiscsi_process_async_pdu(beiscsi_conn, phba,
-					   beiscsi_conn->beiscsi_conn_cid,
-					   phdr, hdr_len, pfirst_buffer,
-					   buf_len);
+					   (beiscsi_conn->beiscsi_conn_cid -
+					    phba->fw_config.iscsi_cid_start),
+					    phdr, hdr_len, pfirst_buffer,
+					    buf_len);
 
 	if (status == 0)
 		hwi_free_async_msg(phba, cri);
@@ -1422,6 +1527,48 @@ static void hwi_process_default_pdu_ring
 	hwi_post_async_buffers(phba, pasync_handle->is_header);
 }
 
+static void  beiscsi_process_mcc_isr(struct beiscsi_hba *phba)
+{
+	struct be_queue_info *mcc_cq;
+	struct  be_mcc_compl *mcc_compl;
+	unsigned int num_processed = 0;
+
+	mcc_cq = &phba->ctrl.mcc_obj.cq;
+	mcc_compl = queue_tail_node(mcc_cq);
+	mcc_compl->flags = le32_to_cpu(mcc_compl->flags);
+	while (mcc_compl->flags & CQE_FLAGS_VALID_MASK) {
+
+		if (num_processed >= 32) {
+			hwi_ring_cq_db(phba, mcc_cq->id,
+					num_processed, 0, 0);
+			num_processed = 0;
+		}
+		if (mcc_compl->flags & CQE_FLAGS_ASYNC_MASK) {
+			/* Interpret flags as an async trailer */
+			if (is_link_state_evt(mcc_compl->flags))
+				/* Interpret compl as a async link evt */
+				beiscsi_async_link_state_process(phba,
+				(struct be_async_event_link_state *) mcc_compl);
+			else
+				SE_DEBUG(DBG_LVL_1,
+					" Unsupported Async Event, flags"
+					" = 0x%08x \n", mcc_compl->flags);
+		} else if (mcc_compl->flags & CQE_FLAGS_COMPLETED_MASK) {
+			be_mcc_compl_process_isr(&phba->ctrl, mcc_compl);
+			atomic_dec(&phba->ctrl.mcc_obj.q.used);
+		}
+
+		mcc_compl->flags = 0;
+		queue_tail_inc(mcc_cq);
+		mcc_compl = queue_tail_node(mcc_cq);
+		mcc_compl->flags = le32_to_cpu(mcc_compl->flags);
+		num_processed++;
+	}
+
+	if (num_processed > 0)
+		hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1, 0);
+
+}
 
 static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
 {
@@ -1431,7 +1578,8 @@ static unsigned int beiscsi_process_cq(s
 	unsigned int num_processed = 0;
 	unsigned int tot_nump = 0;
 	struct beiscsi_conn *beiscsi_conn;
-	struct sgl_handle *psgl_handle = NULL;
+	struct beiscsi_endpoint *beiscsi_ep;
+	struct iscsi_endpoint *ep;
 	struct beiscsi_hba *phba;
 
 	cq = pbe_eq->cq;
@@ -1442,32 +1590,13 @@ static unsigned int beiscsi_process_cq(s
 	       CQE_VALID_MASK) {
 		be_dws_le_to_cpu(sol, sizeof(struct sol_cqe));
 
-		if (ring_mode) {
-			psgl_handle = phba->sgl_hndl_array[((sol->
-				      dw[offsetof(struct amap_sol_cqe_ring,
-				      icd_index) / 32] & SOL_ICD_INDEX_MASK)
-				      >> 6)];
-			beiscsi_conn = phba->conn_table[psgl_handle->cid];
-			if (!beiscsi_conn || !beiscsi_conn->ep) {
-				shost_printk(KERN_WARNING, phba->shost,
-				     "Connection table empty for cid = %d\n",
-				      psgl_handle->cid);
-				return 0;
-			}
-
-		} else {
-			beiscsi_conn = phba->conn_table[(u32) (sol->
-				 dw[offsetof(struct amap_sol_cqe, cid) / 32] &
-				 SOL_CID_MASK) >> 6];
+		ep = phba->ep_array[(u32) ((sol->
+				   dw[offsetof(struct amap_sol_cqe, cid) / 32] &
+				   SOL_CID_MASK) >> 6) -
+				   phba->fw_config.iscsi_cid_start];
 
-			if (!beiscsi_conn || !beiscsi_conn->ep) {
-				shost_printk(KERN_WARNING, phba->shost,
-				     "Connection table empty for cid = %d\n",
-				     (u32)(sol->dw[offsetof(struct amap_sol_cqe,
-				     cid) / 32] & SOL_CID_MASK) >> 6);
-				return 0;
-			}
-		}
+		beiscsi_ep = ep->dd_data;
+		beiscsi_conn = beiscsi_ep->conn;
 
 		if (num_processed >= 32) {
 			hwi_ring_cq_db(phba, cq->id,
@@ -1511,21 +1640,13 @@ static unsigned int beiscsi_process_cq(s
 		case CMD_CXN_KILLED_ITT_INVALID:
 		case CMD_CXN_KILLED_SEQ_OUTOFORDER:
 		case CMD_CXN_KILLED_INVALID_DATASN_RCVD:
-			if (ring_mode) {
-				SE_DEBUG(DBG_LVL_1,
-				 "CQ Error notification for cmd.. "
-				 "code %d cid 0x%x\n",
-				 sol->dw[offsetof(struct amap_sol_cqe, code) /
-				 32] & CQE_CODE_MASK, psgl_handle->cid);
-			} else {
-				SE_DEBUG(DBG_LVL_1,
+			SE_DEBUG(DBG_LVL_1,
 				 "CQ Error notification for cmd.. "
 				 "code %d cid 0x%x\n",
 				 sol->dw[offsetof(struct amap_sol_cqe, code) /
 				 32] & CQE_CODE_MASK,
 				 (sol->dw[offsetof(struct amap_sol_cqe, cid) /
 				 32] & SOL_CID_MASK));
-			}
 			break;
 		case UNSOL_DATA_DIGEST_ERROR_NOTIFY:
 			SE_DEBUG(DBG_LVL_1,
@@ -1547,37 +1668,23 @@ static unsigned int beiscsi_process_cq(s
 		case CXN_KILLED_OVER_RUN_RESIDUAL:
 		case CXN_KILLED_UNDER_RUN_RESIDUAL:
 		case CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN:
-			if (ring_mode) {
-				SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID "
-				 "0x%x...\n",
-				 sol->dw[offsetof(struct amap_sol_cqe, code) /
-				 32] & CQE_CODE_MASK, psgl_handle->cid);
-			} else {
-				SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID "
+			SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID "
 				 "0x%x...\n",
 				 sol->dw[offsetof(struct amap_sol_cqe, code) /
 				 32] & CQE_CODE_MASK,
-				 sol->dw[offsetof(struct amap_sol_cqe, cid) /
-				 32] & CQE_CID_MASK);
-			}
+				 (sol->dw[offsetof(struct amap_sol_cqe, cid) /
+				 32] & CQE_CID_MASK));
 			iscsi_conn_failure(beiscsi_conn->conn,
 					   ISCSI_ERR_CONN_FAILED);
 			break;
 		case CXN_KILLED_RST_SENT:
 		case CXN_KILLED_RST_RCVD:
-			if (ring_mode) {
-				SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset"
-				"received/sent on CID 0x%x...\n",
-				 sol->dw[offsetof(struct amap_sol_cqe, code) /
-				 32] & CQE_CODE_MASK, psgl_handle->cid);
-			} else {
-				SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset"
+			SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset"
 				"received/sent on CID 0x%x...\n",
 				 sol->dw[offsetof(struct amap_sol_cqe, code) /
 				 32] & CQE_CODE_MASK,
-				 sol->dw[offsetof(struct amap_sol_cqe, cid) /
-				 32] & CQE_CID_MASK);
-			}
+				 (sol->dw[offsetof(struct amap_sol_cqe, cid) /
+				 32] & CQE_CID_MASK));
 			iscsi_conn_failure(beiscsi_conn->conn,
 					   ISCSI_ERR_CONN_FAILED);
 			break;
@@ -1586,8 +1693,8 @@ static unsigned int beiscsi_process_cq(s
 				 "received on CID 0x%x...\n",
 				 sol->dw[offsetof(struct amap_sol_cqe, code) /
 				 32] & CQE_CODE_MASK,
-				 sol->dw[offsetof(struct amap_sol_cqe, cid) /
-				 32] & CQE_CID_MASK);
+				 (sol->dw[offsetof(struct amap_sol_cqe, cid) /
+				 32] & CQE_CID_MASK));
 			break;
 		}
 
@@ -1604,7 +1711,7 @@ static unsigned int beiscsi_process_cq(s
 	return tot_nump;
 }
 
-static void beiscsi_process_all_cqs(struct work_struct *work)
+void beiscsi_process_all_cqs(struct work_struct *work)
 {
 	unsigned long flags;
 	struct hwi_controller *phwi_ctrlr;
@@ -1624,6 +1731,7 @@ static void beiscsi_process_all_cqs(stru
 		spin_lock_irqsave(&phba->isr_lock, flags);
 		phba->todo_mcc_cq = 0;
 		spin_unlock_irqrestore(&phba->isr_lock, flags);
+		beiscsi_process_mcc_isr(phba);
 	}
 
 	if (phba->todo_cq) {
@@ -1668,7 +1776,8 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, st
 				      io_task->bhs_pa.u.a32.address_hi);
 
 	l_sg = sg;
-	for (index = 0; (index < num_sg) && (index < 2); index++, sg_next(sg)) {
+	for (index = 0; (index < num_sg) && (index < 2); index++,
+							 sg = sg_next(sg)) {
 		if (index == 0) {
 			sg_len = sg_dma_len(sg);
 			addr = (u64) sg_dma_address(sg);
@@ -1679,11 +1788,7 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, st
 			AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb,
 							sg_len);
 			sge_len = sg_len;
-			AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
-							1);
 		} else {
-			AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
-							0);
 			AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_r2t_offset,
 							pwrb, sge_len);
 			sg_len = sg_dma_len(sg);
@@ -1706,13 +1811,27 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, st
 	AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl,
 			io_task->bhs_pa.u.a32.address_lo);
 
-	if (num_sg == 2)
-		AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb, 1);
+	if (num_sg == 1) {
+		AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
+								1);
+		AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb,
+								0);
+	} else if (num_sg == 2) {
+		AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
+								0);
+		AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb,
+								1);
+	} else {
+		AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
+								0);
+		AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb,
+								0);
+	}
 	sg = l_sg;
 	psgl++;
 	psgl++;
 	offset = 0;
-	for (index = 0; index < num_sg; index++, sg_next(sg), psgl++) {
+	for (index = 0; index < num_sg; index++, sg = sg_next(sg), psgl++) {
 		sg_len = sg_dma_len(sg);
 		addr = (u64) sg_dma_address(sg);
 		AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl,
@@ -2048,11 +2167,10 @@ static void beiscsi_init_wrb_handle(stru
 	}
 	idx = 0;
 	pwrb = mem_descr_wrb->mem_array[idx].virtual_address;
-	num_cxn_wrb =
-	    ((mem_descr_wrb->mem_array[idx].size) / (sizeof(struct iscsi_wrb)) *
-	     phba->params.wrbs_per_cxn);
-
-	for (index = 0; index < phba->params.cxns_per_ctrl; index += 2) {
+	num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) /
+		      ((sizeof(struct iscsi_wrb) *
+			phba->params.wrbs_per_cxn));
+	for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) {
 		pwrb_context = &phwi_ctrlr->wrb_context[index];
 		if (num_cxn_wrb) {
 			for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
@@ -2064,9 +2182,9 @@ static void beiscsi_init_wrb_handle(stru
 		} else {
 			idx++;
 			pwrb = mem_descr_wrb->mem_array[idx].virtual_address;
-			num_cxn_wrb = ((mem_descr_wrb->mem_array[idx].size) /
-					(sizeof(struct iscsi_wrb)) *
-					phba->params.wrbs_per_cxn);
+			num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) /
+				      ((sizeof(struct iscsi_wrb) *
+					phba->params.wrbs_per_cxn));
 			for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
 				pwrb_handle = pwrb_context->pwrb_handle_base[j];
 				pwrb_handle->pwrb = pwrb;
@@ -2383,7 +2501,7 @@ static int beiscsi_create_cqs(struct bei
 						     &paddr);
 		if (!cq_vaddress)
 			goto create_cq_error;
-		ret = be_fill_queue(cq, phba->params.icds_per_ctrl / 2,
+		ret = be_fill_queue(cq, phba->params.num_cq_entries,
 				    sizeof(struct sol_cqe), cq_vaddress);
 		if (ret) {
 			shost_printk(KERN_ERR, phba->shost,
@@ -2634,7 +2752,8 @@ beiscsi_create_wrb_rings(struct beiscsi_
 				     "wrbq create failed.");
 			return status;
 		}
-		phwi_ctrlr->wrb_context[i].cid = phwi_context->be_wrbq[i].id;
+		phwi_ctrlr->wrb_context[i * 2].cid = phwi_context->be_wrbq[i].
+								   id;
 	}
 	kfree(pwrb_arr);
 	return 0;
@@ -2803,17 +2922,6 @@ static int hwi_init_port(struct beiscsi_
 		goto error;
 	}
 
-	if (phba->fw_config.iscsi_features == 0x1)
-		ring_mode = 1;
-	else
-		ring_mode = 0;
-	status = mgmt_get_fw_config(ctrl, phba);
-	if (status != 0) {
-		shost_printk(KERN_ERR, phba->shost,
-			     "Error getting fw config\n");
-		goto error;
-	}
-
 	status = beiscsi_create_cqs(phba, phwi_context);
 	if (status != 0) {
 		shost_printk(KERN_ERR, phba->shost, "CQ not created\n");
@@ -2941,17 +3049,6 @@ static int beiscsi_init_sgl_handle(struc
 	phba->io_sgl_hndl_avbl = 0;
 	phba->eh_sgl_hndl_avbl = 0;
 
-	if (ring_mode) {
-		phba->sgl_hndl_array = kzalloc(sizeof(struct sgl_handle *) *
-					      phba->params.icds_per_ctrl,
-						 GFP_KERNEL);
-		if (!phba->sgl_hndl_array) {
-			shost_printk(KERN_ERR, phba->shost,
-			     "Mem Alloc Failed. Failing to load\n");
-			return -ENOMEM;
-		}
-	}
-
 	mem_descr_sglh = phba->init_mem;
 	mem_descr_sglh += HWI_MEM_SGLH;
 	if (1 == mem_descr_sglh->num_elements) {
@@ -2959,8 +3056,6 @@ static int beiscsi_init_sgl_handle(struc
 						 phba->params.ios_per_ctrl,
 						 GFP_KERNEL);
 		if (!phba->io_sgl_hndl_base) {
-			if (ring_mode)
-				kfree(phba->sgl_hndl_array);
 			shost_printk(KERN_ERR, phba->shost,
 				     "Mem Alloc Failed. Failing to load\n");
 			return -ENOMEM;
@@ -3032,7 +3127,7 @@ static int beiscsi_init_sgl_handle(struc
 			AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, pfrag, 0);
 			pfrag += phba->params.num_sge_per_io;
 			psgl_handle->sgl_index =
-				phba->fw_config.iscsi_cid_start + arr_index++;
+				phba->fw_config.iscsi_icd_start + arr_index++;
 		}
 		idx++;
 	}
@@ -3047,7 +3142,7 @@ static int hba_setup_cid_tbls(struct bei
 {
 	int i, new_cid;
 
-	phba->cid_array = kmalloc(sizeof(void *) * phba->params.cxns_per_ctrl,
+	phba->cid_array = kzalloc(sizeof(void *) * phba->params.cxns_per_ctrl,
 				  GFP_KERNEL);
 	if (!phba->cid_array) {
 		shost_printk(KERN_ERR, phba->shost,
@@ -3055,7 +3150,7 @@ static int hba_setup_cid_tbls(struct bei
 			     "hba_setup_cid_tbls\n");
 		return -ENOMEM;
 	}
-	phba->ep_array = kmalloc(sizeof(struct iscsi_endpoint *) *
+	phba->ep_array = kzalloc(sizeof(struct iscsi_endpoint *) *
 				 phba->params.cxns_per_ctrl * 2, GFP_KERNEL);
 	if (!phba->ep_array) {
 		shost_printk(KERN_ERR, phba->shost,
@@ -3064,7 +3159,7 @@ static int hba_setup_cid_tbls(struct bei
 		kfree(phba->cid_array);
 		return -ENOMEM;
 	}
-	new_cid = phba->fw_config.iscsi_icd_start;
+	new_cid = phba->fw_config.iscsi_cid_start;
 	for (i = 0; i < phba->params.cxns_per_ctrl; i++) {
 		phba->cid_array[i] = new_cid;
 		new_cid += 2;
@@ -3096,14 +3191,18 @@ static unsigned char hwi_enable_intr(str
 		reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
 		SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr);
 		iowrite32(reg, addr);
-		for (i = 0; i <= phba->num_cpus; i++) {
-			eq = &phwi_context->be_eq[i].q;
+		if (!phba->msix_enabled) {
+			eq = &phwi_context->be_eq[0].q;
 			SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
 			hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
+		} else {
+			for (i = 0; i <= phba->num_cpus; i++) {
+				eq = &phwi_context->be_eq[i].q;
+				SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
+				hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
+			}
 		}
-	} else
-		shost_printk(KERN_WARNING, phba->shost,
-			     "In hwi_enable_intr, Not Enabled \n");
+	}
 	return true;
 }
 
@@ -3145,8 +3244,6 @@ static int beiscsi_init_port(struct beis
 	if (hba_setup_cid_tbls(phba)) {
 		shost_printk(KERN_ERR, phba->shost,
 			     "Failed in hba_setup_cid_tbls\n");
-		if (ring_mode)
-			kfree(phba->sgl_hndl_array);
 		kfree(phba->io_sgl_hndl_base);
 		kfree(phba->eh_sgl_hndl_base);
 		goto do_cleanup_ctrlr;
@@ -3166,6 +3263,7 @@ static void hwi_purge_eq(struct beiscsi_
 	struct be_queue_info *eq;
 	struct be_eq_entry *eqe = NULL;
 	int i, eq_msix;
+	unsigned int num_processed;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
 	phwi_context = phwi_ctrlr->phwi_ctxt;
@@ -3177,13 +3275,17 @@ static void hwi_purge_eq(struct beiscsi_
 	for (i = 0; i < (phba->num_cpus + eq_msix); i++) {
 		eq = &phwi_context->be_eq[i].q;
 		eqe = queue_tail_node(eq);
-
+		num_processed = 0;
 		while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
 					& EQE_VALID_MASK) {
 			AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
 			queue_tail_inc(eq);
 			eqe = queue_tail_node(eq);
+			num_processed++;
 		}
+
+		if (num_processed)
+			hwi_ring_eq_db(phba, eq->id, 1,	num_processed, 1, 1);
 	}
 }
 
@@ -3195,10 +3297,9 @@ static void beiscsi_clean_port(struct be
 	if (mgmt_status)
 		shost_printk(KERN_WARNING, phba->shost,
 			     "mgmt_epfw_cleanup FAILED \n");
-	hwi_cleanup(phba);
+
 	hwi_purge_eq(phba);
-	if (ring_mode)
-		kfree(phba->sgl_hndl_array);
+	hwi_cleanup(phba);
 	kfree(phba->io_sgl_hndl_base);
 	kfree(phba->eh_sgl_hndl_base);
 	kfree(phba->cid_array);
@@ -3219,7 +3320,8 @@ beiscsi_offload_connection(struct beiscs
 	 * We can always use 0 here because it is reserved by libiscsi for
 	 * login/startup related tasks.
 	 */
-	pwrb_handle = alloc_wrb_handle(phba, beiscsi_conn->beiscsi_conn_cid, 0);
+	pwrb_handle = alloc_wrb_handle(phba, (beiscsi_conn->beiscsi_conn_cid -
+				       phba->fw_config.iscsi_cid_start));
 	pwrb = (struct iscsi_target_context_update_wrb *)pwrb_handle->pwrb;
 	memset(pwrb, 0, sizeof(*pwrb));
 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
@@ -3283,8 +3385,7 @@ beiscsi_offload_connection(struct beiscs
 	be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_target_context_update_wrb));
 
 	doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
-	if (!ring_mode)
-		doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK)
+	doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK)
 			     << DB_DEF_PDU_WRB_INDEX_SHIFT;
 	doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
 
@@ -3328,8 +3429,9 @@ static int beiscsi_alloc_pdu(struct iscs
 	io_task->bhs_pa.u.a64.address = paddr;
 	io_task->libiscsi_itt = (itt_t)task->itt;
 	io_task->pwrb_handle = alloc_wrb_handle(phba,
-						beiscsi_conn->beiscsi_conn_cid,
-						task->itt);
+						beiscsi_conn->beiscsi_conn_cid -
+						phba->fw_config.iscsi_cid_start
+						);
 	io_task->conn = beiscsi_conn;
 
 	task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr;
@@ -3343,7 +3445,7 @@ static int beiscsi_alloc_pdu(struct iscs
 			goto free_hndls;
 	} else {
 		io_task->scsi_cmnd = NULL;
-		if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) {
+		if ((opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) {
 			if (!beiscsi_conn->login_in_progress) {
 				spin_lock(&phba->mgmt_sgl_lock);
 				io_task->psgl_handle = (struct sgl_handle *)
@@ -3370,21 +3472,16 @@ static int beiscsi_alloc_pdu(struct iscs
 	itt = (itt_t) cpu_to_be32(((unsigned int)io_task->pwrb_handle->
 				 wrb_index << 16) | (unsigned int)
 				(io_task->psgl_handle->sgl_index));
-	if (ring_mode) {
-		phba->sgl_hndl_array[io_task->psgl_handle->sgl_index -
-				     phba->fw_config.iscsi_cid_start] =
-				     io_task->psgl_handle;
-		io_task->psgl_handle->task = task;
-		io_task->psgl_handle->cid = beiscsi_conn->beiscsi_conn_cid;
-	} else
-		io_task->pwrb_handle->pio_handle = task;
+	io_task->pwrb_handle->pio_handle = task;
 
 	io_task->cmd_bhs->iscsi_hdr.itt = itt;
 	return 0;
 
 free_hndls:
 	phwi_ctrlr = phba->phwi_ctrlr;
-	pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid];
+	pwrb_context = &phwi_ctrlr->wrb_context[
+			beiscsi_conn->beiscsi_conn_cid -
+			phba->fw_config.iscsi_cid_start];
 	free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle);
 	io_task->pwrb_handle = NULL;
 	pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs,
@@ -3404,7 +3501,8 @@ static void beiscsi_cleanup_task(struct
 	struct hwi_controller *phwi_ctrlr;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
-	pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid];
+	pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid
+			- phba->fw_config.iscsi_cid_start];
 	if (io_task->pwrb_handle) {
 		free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle);
 		io_task->pwrb_handle = NULL;
@@ -3460,18 +3558,12 @@ static int beiscsi_iotask(struct iscsi_t
 			      ISCSI_OPCODE_SCSI_DATA_OUT);
 		AMAP_SET_BITS(struct amap_pdu_data_out, final_bit,
 			      &io_task->cmd_bhs->iscsi_data_pdu, 1);
-		if (ring_mode)
-			io_task->psgl_handle->type = INI_WR_CMD;
-		else
-			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
-				      INI_WR_CMD);
+		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+			      INI_WR_CMD);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1);
 	} else {
-		if (ring_mode)
-			io_task->psgl_handle->type = INI_RD_CMD;
-		else
-			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
-				      INI_RD_CMD);
+		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+			      INI_RD_CMD);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0);
 	}
 	memcpy(&io_task->cmd_bhs->iscsi_data_pdu.
@@ -3496,8 +3588,7 @@ static int beiscsi_iotask(struct iscsi_t
 	be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
 
 	doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
-	if (!ring_mode)
-		doorbell |= (io_task->pwrb_handle->wrb_index &
+	doorbell |= (io_task->pwrb_handle->wrb_index &
 		     DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT;
 	doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
 
@@ -3507,21 +3598,17 @@ static int beiscsi_iotask(struct iscsi_t
 
 static int beiscsi_mtask(struct iscsi_task *task)
 {
-	struct beiscsi_io_task *aborted_io_task, *io_task = task->dd_data;
+	struct beiscsi_io_task *io_task = task->dd_data;
 	struct iscsi_conn *conn = task->conn;
 	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
 	struct beiscsi_hba *phba = beiscsi_conn->phba;
-	struct iscsi_session *session;
 	struct iscsi_wrb *pwrb = NULL;
-	struct hwi_controller *phwi_ctrlr;
-	struct hwi_wrb_context *pwrb_context;
-	struct wrb_handle *pwrb_handle;
 	unsigned int doorbell = 0;
-	unsigned int i, cid;
-	struct iscsi_task *aborted_task;
+	unsigned int cid;
 
 	cid = beiscsi_conn->beiscsi_conn_cid;
 	pwrb = io_task->pwrb_handle->pwrb;
+	memset(pwrb, 0, sizeof(*pwrb));
 	AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb,
 		      be32_to_cpu(task->cmdsn));
 	AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb,
@@ -3531,65 +3618,37 @@ static int beiscsi_mtask(struct iscsi_ta
 
 	switch (task->hdr->opcode & ISCSI_OPCODE_MASK) {
 	case ISCSI_OP_LOGIN:
-		if (ring_mode)
-			io_task->psgl_handle->type = TGT_DM_CMD;
-		else
-			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
-				      TGT_DM_CMD);
+		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+			      TGT_DM_CMD);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1);
 		hwi_write_buffer(pwrb, task);
 		break;
 	case ISCSI_OP_NOOP_OUT:
-		if (ring_mode)
-			io_task->psgl_handle->type = INI_RD_CMD;
+		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+			      INI_RD_CMD);
+		if (task->hdr->ttt == ISCSI_RESERVED_TAG)
+			AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
 		else
-			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
-				      INI_RD_CMD);
+			AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 1);
 		hwi_write_buffer(pwrb, task);
 		break;
 	case ISCSI_OP_TEXT:
-		if (ring_mode)
-			io_task->psgl_handle->type = INI_WR_CMD;
-		else
-			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
-				      INI_WR_CMD);
-		AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1);
+		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+			      TGT_DM_CMD);
+		AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
 		hwi_write_buffer(pwrb, task);
 		break;
 	case ISCSI_OP_SCSI_TMFUNC:
-		session = conn->session;
-		i = ((struct iscsi_tm *)task->hdr)->rtt;
-		phwi_ctrlr = phba->phwi_ctrlr;
-		pwrb_context = &phwi_ctrlr->wrb_context[cid];
-		pwrb_handle = pwrb_context->pwrb_handle_basestd[be32_to_cpu(i)
-								>> 16];
-		aborted_task = pwrb_handle->pio_handle;
-		 if (!aborted_task)
-			return 0;
-
-		aborted_io_task = aborted_task->dd_data;
-		if (!aborted_io_task->scsi_cmnd)
-			return 0;
-
-		mgmt_invalidate_icds(phba,
-				     aborted_io_task->psgl_handle->sgl_index,
-				     cid);
-		if (ring_mode)
-			io_task->psgl_handle->type = INI_TMF_CMD;
-		else
-			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
-				      INI_TMF_CMD);
+		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+			      INI_TMF_CMD);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
 		hwi_write_buffer(pwrb, task);
 		break;
 	case ISCSI_OP_LOGOUT:
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
-		if (ring_mode)
-			io_task->psgl_handle->type = HWH_TYPE_LOGOUT;
-		else
 		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
-				HWH_TYPE_LOGOUT);
+			      HWH_TYPE_LOGOUT);
 		hwi_write_buffer(pwrb, task);
 		break;
 
@@ -3600,14 +3659,13 @@ static int beiscsi_mtask(struct iscsi_ta
 	}
 
 	AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb,
-		      be32_to_cpu(task->data_count));
+		      task->data_count);
 	AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb,
 		      io_task->pwrb_handle->nxt_wrb_index);
 	be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
 
 	doorbell |= cid & DB_WRB_POST_CID_MASK;
-	if (!ring_mode)
-		doorbell |= (io_task->pwrb_handle->wrb_index &
+	doorbell |= (io_task->pwrb_handle->wrb_index &
 		     DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT;
 	doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
 	iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET);
@@ -3616,17 +3674,12 @@ static int beiscsi_mtask(struct iscsi_ta
 
 static int beiscsi_task_xmit(struct iscsi_task *task)
 {
-	struct iscsi_conn *conn = task->conn;
 	struct beiscsi_io_task *io_task = task->dd_data;
 	struct scsi_cmnd *sc = task->sc;
-	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
 	struct scatterlist *sg;
 	int num_sg;
 	unsigned int  writedir = 0, xferlen = 0;
 
-	SE_DEBUG(DBG_LVL_4, "\n cid=%d In beiscsi_task_xmit task=%p conn=%p \t"
-		 "beiscsi_conn=%p \n", beiscsi_conn->beiscsi_conn_cid,
-		 task, conn, beiscsi_conn);
 	if (!sc)
 		return beiscsi_mtask(task);
 
@@ -3649,7 +3702,6 @@ static int beiscsi_task_xmit(struct iscs
 	return beiscsi_iotask(task, sg, num_sg, xferlen, writedir);
 }
 
-
 static void beiscsi_remove(struct pci_dev *pcidev)
 {
 	struct beiscsi_hba *phba = NULL;
@@ -3732,9 +3784,21 @@ static int __devinit beiscsi_dev_probe(s
 			" Failed in beiscsi_hba_alloc \n");
 		goto disable_pci;
 	}
-	SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba);
 
-	pci_set_drvdata(pcidev, phba);
+	switch (pcidev->device) {
+	case BE_DEVICE_ID1:
+	case OC_DEVICE_ID1:
+	case OC_DEVICE_ID2:
+		phba->generation = BE_GEN2;
+		break;
+	case BE_DEVICE_ID2:
+	case OC_DEVICE_ID3:
+		phba->generation = BE_GEN3;
+		break;
+	default:
+		phba->generation = 0;
+	}
+
 	if (enable_msix)
 		num_cpus = find_num_cpus();
 	else
@@ -3754,7 +3818,15 @@ static int __devinit beiscsi_dev_probe(s
 	spin_lock_init(&phba->io_sgl_lock);
 	spin_lock_init(&phba->mgmt_sgl_lock);
 	spin_lock_init(&phba->isr_lock);
+	ret = mgmt_get_fw_config(&phba->ctrl, phba);
+	if (ret != 0) {
+		shost_printk(KERN_ERR, phba->shost,
+			     "Error getting fw config\n");
+		goto free_port;
+	}
+	phba->shost->max_id = phba->fw_config.iscsi_cid_count;
 	beiscsi_get_params(phba);
+	phba->shost->can_queue = phba->params.ios_per_ctrl;
 	ret = beiscsi_init_port(phba);
 	if (ret < 0) {
 		shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
@@ -3762,6 +3834,15 @@ static int __devinit beiscsi_dev_probe(s
 		goto free_port;
 	}
 
+	for (i = 0; i < MAX_MCC_CMD ; i++) {
+		init_waitqueue_head(&phba->ctrl.mcc_wait[i + 1]);
+		phba->ctrl.mcc_tag[i] = i + 1;
+		phba->ctrl.mcc_numtag[i + 1] = 0;
+		phba->ctrl.mcc_tag_available++;
+	}
+
+	phba->ctrl.mcc_alloc_index = phba->ctrl.mcc_free_index = 0;
+
 	snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u",
 		 phba->shost->host_no);
 	phba->wq = create_workqueue(phba->wq_name);
@@ -3836,7 +3917,7 @@ disable_pci:
 struct iscsi_transport beiscsi_iscsi_transport = {
 	.owner = THIS_MODULE,
 	.name = DRV_NAME,
-	.caps = CAP_RECOVERY_L0 | CAP_HDRDGST |
+	.caps = CAP_RECOVERY_L0 | CAP_HDRDGST | CAP_TEXT_NEGO |
 		CAP_MULTI_R2T | CAP_DATADGST | CAP_DATA_PATH_OFFLOAD,
 	.param_mask = ISCSI_MAX_RECV_DLENGTH |
 		ISCSI_MAX_XMIT_DLENGTH |
@@ -3859,7 +3940,7 @@ struct iscsi_transport beiscsi_iscsi_tra
 		ISCSI_USERNAME | ISCSI_PASSWORD |
 		ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
 		ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
-		ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
+		ISCSI_LU_RESET_TMO |
 		ISCSI_PING_TMO | ISCSI_RECV_TMO |
 		ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
 	.host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
@@ -3905,7 +3986,7 @@ static int __init beiscsi_module_init(vo
 		SE_DEBUG(DBG_LVL_1,
 			 "beiscsi_module_init - Unable to  register beiscsi"
 			 "transport.\n");
-		ret = -ENOMEM;
+		return -ENOMEM;
 	}
 	SE_DEBUG(DBG_LVL_8, "In beiscsi_module_init, tt=%p \n",
 		 &beiscsi_iscsi_transport);
@@ -3917,7 +3998,6 @@ static int __init beiscsi_module_init(vo
 			 "beiscsi pci driver.\n");
 		goto unregister_iscsi_transport;
 	}
-	ring_mode = 0;
 	return 0;
 
 unregister_iscsi_transport:
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_main.h linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_main.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_main.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_main.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -40,31 +40,29 @@
 #define DRV_DESC		BE_NAME " " "Driver"
 
 #define BE_VENDOR_ID 		0x19A2
+/* DEVICE ID's for BE2 */
 #define BE_DEVICE_ID1		0x212
 #define OC_DEVICE_ID1		0x702
 #define OC_DEVICE_ID2		0x703
+
+/* DEVICE ID's for BE3 */
+#define BE_DEVICE_ID2		0x222
 #define OC_DEVICE_ID3		0x712
-#define OC_DEVICE_ID4		0x222
 
-#define BE2_MAX_SESSIONS	64
+#define BE2_IO_DEPTH		1024
+#define BE2_MAX_SESSIONS	256
 #define BE2_CMDS_PER_CXN	128
-#define BE2_LOGOUTS		BE2_MAX_SESSIONS
 #define BE2_TMFS		16
 #define BE2_NOPOUT_REQ		16
-#define BE2_ASYNCPDUS		BE2_MAX_SESSIONS
-#define BE2_MAX_ICDS		2048
 #define BE2_SGE			32
 #define BE2_DEFPDU_HDR_SZ	64
 #define BE2_DEFPDU_DATA_SZ	8192
-#define BE2_IO_DEPTH \
-	(BE2_MAX_ICDS / 2 - (BE2_LOGOUTS + BE2_TMFS + BE2_NOPOUT_REQ))
 
 #define MAX_CPUS		31
-#define BEISCSI_SGLIST_ELEMENTS	BE2_SGE
+#define BEISCSI_SGLIST_ELEMENTS	30
 
-#define BEISCSI_MAX_CMNDS	1024	/* Max IO's per Ctrlr sht->can_queue */
 #define BEISCSI_CMD_PER_LUN	128	/* scsi_host->cmd_per_lun */
-#define BEISCSI_MAX_SECTORS	2048	/* scsi_host->max_sectors */
+#define BEISCSI_MAX_SECTORS	256	/* scsi_host->max_sectors */
 
 #define BEISCSI_MAX_CMD_LEN	16	/* scsi_host->max_cmd_len */
 #define BEISCSI_NUM_MAX_LUN	256	/* scsi_host->max_lun */
@@ -259,6 +257,11 @@ struct hba_parameters {
 	unsigned int num_sge;
 };
 
+struct invalidate_command_table {
+	unsigned short icd;
+	unsigned short cid;
+} __packed;
+
 struct beiscsi_hba {
 	struct hba_parameters params;
 	struct hwi_controller *phwi_ctrlr;
@@ -330,6 +333,9 @@ struct beiscsi_hba {
 	struct workqueue_struct *wq;	/* The actuak work queue */
 	struct work_struct work_cqs;	/* The work being queued */
 	struct be_ctrl_info ctrl;
+	unsigned int generation;
+	struct invalidate_command_table inv_tbl[128];
+
 };
 
 struct beiscsi_session {
@@ -492,8 +498,6 @@ struct hwi_async_entry {
 	struct list_head data_busy_list;
 };
 
-#define BE_MIN_ASYNC_ENTRIES 128
-
 struct hwi_async_pdu_context {
 	struct {
 		struct be_bus_address pa_base;
@@ -534,7 +538,7 @@ struct hwi_async_pdu_context {
 	 * This is a varying size list! Do not add anything
 	 * after this entry!!
 	 */
-	struct hwi_async_entry async_entry[BE_MIN_ASYNC_ENTRIES];
+	struct hwi_async_entry async_entry[BE2_MAX_SESSIONS * 2];
 };
 
 #define PDUCQE_CODE_MASK	0x0000003F
@@ -656,11 +660,12 @@ struct amap_iscsi_wrb {
 
 } __packed;
 
-struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid,
-				    int index);
+struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid);
 void
 free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle);
 
+void beiscsi_process_all_cqs(struct work_struct *work);
+
 struct pdu_nop_out {
 	u32 dw[12];
 };
@@ -802,7 +807,6 @@ struct hwi_controller {
 	struct be_ring default_pdu_hdr;
 	struct be_ring default_pdu_data;
 	struct hwi_context_memory *phwi_ctxt;
-	unsigned short cq_errors[CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN];
 };
 
 enum hwh_type_enum {
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_mgmt.c linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_mgmt.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_mgmt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_mgmt.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -48,6 +48,14 @@ unsigned char mgmt_get_fw_config(struct
 					pfw_cfg->ulp[0].sq_base;
 		phba->fw_config.iscsi_cid_count =
 					pfw_cfg->ulp[0].sq_count;
+		if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) {
+			SE_DEBUG(DBG_LVL_8,
+				"FW reported MAX CXNS as %d \t"
+				"Max Supported = %d.\n",
+				phba->fw_config.iscsi_cid_count,
+				BE2_MAX_SESSIONS);
+			phba->fw_config.iscsi_cid_count = BE2_MAX_SESSIONS / 2;
+		}
 	} else {
 		shost_printk(KERN_WARNING, phba->shost,
 			     "Failed in mgmt_get_fw_config \n");
@@ -77,6 +85,7 @@ unsigned char mgmt_check_supported_fw(st
 	}
 	nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
 	req = nonemb_cmd.va;
+	memset(req, 0, sizeof(*req));
 	spin_lock(&ctrl->mbox_lock);
 	memset(wrb, 0, sizeof(*wrb));
 	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
@@ -136,14 +145,22 @@ unsigned char mgmt_epfw_cleanup(struct b
 }
 
 unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
-				   unsigned int icd, unsigned int cid)
+				struct invalidate_command_table *inv_tbl,
+				unsigned int num_invalidate, unsigned int cid)
 {
 	struct be_dma_mem nonemb_cmd;
 	struct be_ctrl_info *ctrl = &phba->ctrl;
-	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
-	struct be_sge *sge = nonembedded_sgl(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_sge *sge;
 	struct invalidate_commands_params_in *req;
-	int status = 0;
+	unsigned int i, tag = 0;
+
+	spin_lock(&ctrl->mbox_lock);
+	tag = alloc_mcc_tag(phba);
+	if (!tag) {
+		spin_unlock(&ctrl->mbox_lock);
+		return tag;
+	}
 
 	nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
 				sizeof(struct invalidate_commands_params_in),
@@ -152,12 +169,15 @@ unsigned char mgmt_invalidate_icds(struc
 		SE_DEBUG(DBG_LVL_1,
 			 "Failed to allocate memory for"
 			 "mgmt_invalidate_icds \n");
+		spin_unlock(&ctrl->mbox_lock);
 		return -1;
 	}
 	nonemb_cmd.size = sizeof(struct invalidate_commands_params_in);
 	req = nonemb_cmd.va;
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	memset(req, 0, sizeof(*req));
+	wrb = wrb_from_mccq(phba);
+	sge = nonembedded_sgl(wrb);
+	wrb->tag0 |= tag;
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
@@ -165,21 +185,22 @@ unsigned char mgmt_invalidate_icds(struc
 			sizeof(*req));
 	req->ref_handle = 0;
 	req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
-	req->icd_count = 0;
-	req->table[req->icd_count].icd = icd;
-	req->table[req->icd_count].cid = cid;
+	for (i = 0; i < num_invalidate; i++) {
+		req->table[i].icd = inv_tbl->icd;
+		req->table[i].cid = inv_tbl->cid;
+		req->icd_count++;
+		inv_tbl++;
+	}
 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
 	sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
 	sge->len = cpu_to_le32(nonemb_cmd.size);
 
-	status = be_mcc_notify_wait(phba);
-	if (status)
-		SE_DEBUG(DBG_LVL_1, "ICDS Invalidation Failed\n");
+	be_mcc_notify(phba);
 	spin_unlock(&ctrl->mbox_lock);
 	if (nonemb_cmd.va)
 		pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
 				    nonemb_cmd.va, nonemb_cmd.dma);
-	return status;
+	return tag;
 }
 
 unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
@@ -189,13 +210,19 @@ unsigned char mgmt_invalidate_connection
 					 unsigned short savecfg_flag)
 {
 	struct be_ctrl_info *ctrl = &phba->ctrl;
-	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
-	struct iscsi_invalidate_connection_params_in *req =
-						embedded_payload(wrb);
-	int status = 0;
+	struct be_mcc_wrb *wrb;
+	struct iscsi_invalidate_connection_params_in *req;
+	unsigned int tag = 0;
 
 	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	tag = alloc_mcc_tag(phba);
+	if (!tag) {
+		spin_unlock(&ctrl->mbox_lock);
+		return tag;
+	}
+	wrb = wrb_from_mccq(phba);
+	wrb->tag0 |= tag;
+	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
@@ -208,35 +235,37 @@ unsigned char mgmt_invalidate_connection
 	else
 		req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
 	req->save_cfg = savecfg_flag;
-	status =  be_mcc_notify_wait(phba);
-	if (status)
-		SE_DEBUG(DBG_LVL_1, "Invalidation Failed\n");
-
+	be_mcc_notify(phba);
 	spin_unlock(&ctrl->mbox_lock);
-	return status;
+	return tag;
 }
 
 unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
 				unsigned short cid, unsigned int upload_flag)
 {
 	struct be_ctrl_info *ctrl = &phba->ctrl;
-	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
-	struct tcp_upload_params_in *req = embedded_payload(wrb);
-	int status = 0;
+	struct be_mcc_wrb *wrb;
+	struct tcp_upload_params_in *req;
+	unsigned int tag = 0;
 
 	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	tag = alloc_mcc_tag(phba);
+	if (!tag) {
+		spin_unlock(&ctrl->mbox_lock);
+		return tag;
+	}
+	wrb = wrb_from_mccq(phba);
+	req = embedded_payload(wrb);
+	wrb->tag0 |= tag;
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 	be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
 			   OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
 	req->id = (unsigned short)cid;
 	req->upload_type = (unsigned char)upload_flag;
-	status = be_mcc_notify_wait(phba);
-	if (status)
-		SE_DEBUG(DBG_LVL_1, "mgmt_upload_connection Failed\n");
+	be_mcc_notify(phba);
 	spin_unlock(&ctrl->mbox_lock);
-	return status;
+	return tag;
 }
 
 int mgmt_open_connection(struct beiscsi_hba *phba,
@@ -248,13 +277,13 @@ int mgmt_open_connection(struct beiscsi_
 	struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
 	struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
 	struct be_ctrl_info *ctrl = &phba->ctrl;
-	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
-	struct tcp_connect_and_offload_in *req = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct tcp_connect_and_offload_in *req;
 	unsigned short def_hdr_id;
 	unsigned short def_data_id;
 	struct phys_addr template_address = { 0, 0 };
 	struct phys_addr *ptemplate_address;
-	int status = 0;
+	unsigned int tag = 0;
 	unsigned int i;
 	unsigned short cid = beiscsi_ep->ep_cid;
 
@@ -266,7 +295,14 @@ int mgmt_open_connection(struct beiscsi_
 	ptemplate_address = &template_address;
 	ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
 	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	tag = alloc_mcc_tag(phba);
+	if (!tag) {
+		spin_unlock(&ctrl->mbox_lock);
+		return tag;
+	}
+	wrb = wrb_from_mccq(phba);
+	req = embedded_payload(wrb);
+	wrb->tag0 |= tag;
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
@@ -311,46 +347,36 @@ int mgmt_open_connection(struct beiscsi_
 	req->do_offload = 1;
 	req->dataout_template_pa.lo = ptemplate_address->lo;
 	req->dataout_template_pa.hi = ptemplate_address->hi;
-	status = be_mcc_notify_wait(phba);
-	if (!status) {
-		struct iscsi_endpoint *ep;
-		struct tcp_connect_and_offload_out *ptcpcnct_out =
-							embedded_payload(wrb);
-
-		ep = phba->ep_array[ptcpcnct_out->cid];
-		beiscsi_ep = ep->dd_data;
-		beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
-		beiscsi_ep->cid_vld = 1;
-		SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n");
-	} else
-		SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed\n");
+	be_mcc_notify(phba);
 	spin_unlock(&ctrl->mbox_lock);
-	return status;
+	return tag;
 }
 
-int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr)
+unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba)
 {
 	struct be_ctrl_info *ctrl = &phba->ctrl;
-	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
-	struct be_cmd_req_get_mac_addr *req = embedded_payload(wrb);
-	int status;
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_get_mac_addr *req;
+	unsigned int tag = 0;
 
 	SE_DEBUG(DBG_LVL_8, "In be_cmd_get_mac_addr\n");
 	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	tag = alloc_mcc_tag(phba);
+	if (!tag) {
+		spin_unlock(&ctrl->mbox_lock);
+		return tag;
+	}
+
+	wrb = wrb_from_mccq(phba);
+	req = embedded_payload(wrb);
+	wrb->tag0 |= tag;
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
 			   OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
 			   sizeof(*req));
 
-	status = be_mcc_notify_wait(phba);
-	if (!status) {
-		struct be_cmd_resp_get_mac_addr *resp = embedded_payload(wrb);
-
-		memcpy(mac_addr, resp->mac_address, ETH_ALEN);
-	}
-
+	be_mcc_notify(phba);
 	spin_unlock(&ctrl->mbox_lock);
-	return status;
+	return tag;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_mgmt.h linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_mgmt.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_mgmt.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/be2iscsi/be_mgmt.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2009 ServerEngines
+ * Copyright (C) 2005 - 2010 ServerEngines
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -94,7 +94,8 @@ unsigned char mgmt_upload_connection(str
 				     unsigned short cid,
 				     unsigned int upload_flag);
 unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
-				   unsigned int icd, unsigned int cid);
+				struct invalidate_command_table *inv_tbl,
+				unsigned int num_invalidate, unsigned int cid);
 
 struct iscsi_invalidate_connection_params_in {
 	struct be_cmd_req_hdr hdr;
@@ -116,11 +117,6 @@ union iscsi_invalidate_connection_params
 	struct iscsi_invalidate_connection_params_out response;
 } __packed;
 
-struct invalidate_command_table {
-	unsigned short icd;
-	unsigned short cid;
-} __packed;
-
 struct invalidate_commands_params_in {
 	struct be_cmd_req_hdr hdr;
 	unsigned int ref_handle;
@@ -231,6 +227,7 @@ struct beiscsi_endpoint {
 	struct beiscsi_hba *phba;
 	struct beiscsi_sess *sess;
 	struct beiscsi_conn *conn;
+	struct iscsi_endpoint *openiscsi_ep;
 	unsigned short ip_type;
 	char dst6_addr[ISCSI_ADDRESS_BUF_LEN];
 	unsigned long dst_addr;
@@ -249,7 +246,4 @@ unsigned char mgmt_invalidate_connection
 					 unsigned short issue_reset,
 					 unsigned short savecfg_flag);
 
-unsigned char mgmt_fw_cmd(struct be_ctrl_info *ctrl,
-			  struct beiscsi_hba *phba,
-			  char *buf, unsigned int len);
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_core.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_core.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -385,6 +385,15 @@ bfa_debug_fwsave(struct bfa_s *bfa, void
 }
 
 /**
+ * Clear the saved firmware trace information of an IOC.
+ */
+void
+bfa_debug_fwsave_clear(struct bfa_s *bfa)
+{
+	bfa_ioc_debug_fwsave_clear(&bfa->ioc);
+}
+
+/**
  * 		Fetch firmware trace data.
  *
  * @param[in]		bfa			BFA instance
@@ -399,4 +408,14 @@ bfa_debug_fwtrc(struct bfa_s *bfa, void
 {
 	return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
 }
+
+/**
+ * Reset hw semaphore & usage cnt regs and initialize.
+ */
+void
+bfa_chip_reset(struct bfa_s *bfa)
+{
+	bfa_ioc_ownership_reset(&bfa->ioc);
+	bfa_ioc_pll_init(&bfa->ioc);
+}
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_attr.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfad_attr.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_attr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfad_attr.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  *  bfa_attr.c Linux driver configuration interface module.
  */
 
+#include <linux/slab.h>
 #include "bfad_drv.h"
 #include "bfad_im.h"
 #include "bfad_trcmod.h"
@@ -141,7 +142,7 @@ bfad_im_get_host_port_type(struct Scsi_H
 	struct bfad_s         *bfad = im_port->bfad;
 	struct bfa_pport_attr_s attr;
 
-	bfa_pport_get_attr(&bfad->bfa, &attr);
+	bfa_fcport_get_attr(&bfad->bfa, &attr);
 
 	switch (attr.port_type) {
 	case BFA_PPORT_TYPE_NPORT:
@@ -173,7 +174,7 @@ bfad_im_get_host_port_state(struct Scsi_
 	struct bfad_s         *bfad = im_port->bfad;
 	struct bfa_pport_attr_s attr;
 
-	bfa_pport_get_attr(&bfad->bfa, &attr);
+	bfa_fcport_get_attr(&bfad->bfa, &attr);
 
 	switch (attr.port_state) {
 	case BFA_PPORT_ST_LINKDOWN:
@@ -229,8 +230,10 @@ bfad_im_get_host_speed(struct Scsi_Host
 			(struct bfad_im_port_s *) shost->hostdata[0];
 	struct bfad_s         *bfad = im_port->bfad;
 	struct bfa_pport_attr_s attr;
+	unsigned long   flags;
 
-	bfa_pport_get_attr(&bfad->bfa, &attr);
+	spin_lock_irqsave(shost->host_lock, flags);
+	bfa_fcport_get_attr(&bfad->bfa, &attr);
 	switch (attr.speed) {
 	case BFA_PPORT_SPEED_8GBPS:
 		fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
@@ -248,6 +251,7 @@ bfad_im_get_host_speed(struct Scsi_Host
 		fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
 		break;
 	}
+	spin_unlock_irqrestore(shost->host_lock, flags);
 }
 
 /**
@@ -285,7 +289,7 @@ bfad_im_get_stats(struct Scsi_Host *shos
 	init_completion(&fcomp.comp);
 	spin_lock_irqsave(&bfad->bfad_lock, flags);
 	memset(hstats, 0, sizeof(struct fc_host_statistics));
-	rc = bfa_pport_get_stats(&bfad->bfa,
+	rc =  bfa_port_get_stats(BFA_FCPORT(&bfad->bfa),
 				     (union bfa_pport_stats_u *) hstats,
 				     bfad_hcb_comp, &fcomp);
 	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -312,7 +316,8 @@ bfad_im_reset_stats(struct Scsi_Host *sh
 
 	init_completion(&fcomp.comp);
 	spin_lock_irqsave(&bfad->bfad_lock, flags);
-	rc = bfa_pport_clear_stats(&bfad->bfa, bfad_hcb_comp, &fcomp);
+	rc = bfa_port_clear_stats(BFA_FCPORT(&bfad->bfa), bfad_hcb_comp,
+		&fcomp);
 	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
 	if (rc != BFA_STATUS_OK)
@@ -421,12 +426,10 @@ bfad_im_serial_num_show(struct device *d
 	struct bfad_im_port_s *im_port =
 			(struct bfad_im_port_s *) shost->hostdata[0];
 	struct bfad_s         *bfad = im_port->bfad;
-	struct bfa_ioc_attr_s  ioc_attr;
+	char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
 
-	memset(&ioc_attr, 0, sizeof(ioc_attr));
-	bfa_get_attr(&bfad->bfa, &ioc_attr);
-	return snprintf(buf, PAGE_SIZE, "%s\n",
-			ioc_attr.adapter_attr.serial_num);
+	bfa_get_adapter_serial_num(&bfad->bfa, serial_num);
+	return snprintf(buf, PAGE_SIZE, "%s\n", serial_num);
 }
 
 static ssize_t
@@ -437,11 +440,10 @@ bfad_im_model_show(struct device *dev, s
 	struct bfad_im_port_s *im_port =
 			(struct bfad_im_port_s *) shost->hostdata[0];
 	struct bfad_s         *bfad = im_port->bfad;
-	struct bfa_ioc_attr_s  ioc_attr;
+	char model[BFA_ADAPTER_MODEL_NAME_LEN];
 
-	memset(&ioc_attr, 0, sizeof(ioc_attr));
-	bfa_get_attr(&bfad->bfa, &ioc_attr);
-	return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.model);
+	bfa_get_adapter_model(&bfad->bfa, model);
+	return snprintf(buf, PAGE_SIZE, "%s\n", model);
 }
 
 static ssize_t
@@ -452,12 +454,10 @@ bfad_im_model_desc_show(struct device *d
 	struct bfad_im_port_s *im_port =
 			(struct bfad_im_port_s *) shost->hostdata[0];
 	struct bfad_s         *bfad = im_port->bfad;
-	struct bfa_ioc_attr_s  ioc_attr;
+	char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN];
 
-	memset(&ioc_attr, 0, sizeof(ioc_attr));
-	bfa_get_attr(&bfad->bfa, &ioc_attr);
-	return snprintf(buf, PAGE_SIZE, "%s\n",
-			ioc_attr.adapter_attr.model_descr);
+	bfa_get_adapter_model(&bfad->bfa, model_descr);
+	return snprintf(buf, PAGE_SIZE, "%s\n", model_descr);
 }
 
 static ssize_t
@@ -482,14 +482,13 @@ bfad_im_symbolic_name_show(struct device
 	struct bfad_im_port_s *im_port =
 			(struct bfad_im_port_s *) shost->hostdata[0];
 	struct bfad_s         *bfad = im_port->bfad;
-	struct bfa_ioc_attr_s  ioc_attr;
-
-	memset(&ioc_attr, 0, sizeof(ioc_attr));
-	bfa_get_attr(&bfad->bfa, &ioc_attr);
+	char model[BFA_ADAPTER_MODEL_NAME_LEN];
+	char fw_ver[BFA_VERSION_LEN];
 
+	bfa_get_adapter_model(&bfad->bfa, model);
+	bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
 	return snprintf(buf, PAGE_SIZE, "Brocade %s FV%s DV%s\n",
-			ioc_attr.adapter_attr.model,
-			ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION);
+		model, fw_ver, BFAD_DRIVER_VERSION);
 }
 
 static ssize_t
@@ -500,11 +499,10 @@ bfad_im_hw_version_show(struct device *d
 	struct bfad_im_port_s *im_port =
 			(struct bfad_im_port_s *) shost->hostdata[0];
 	struct bfad_s         *bfad = im_port->bfad;
-	struct bfa_ioc_attr_s  ioc_attr;
+	char hw_ver[BFA_VERSION_LEN];
 
-	memset(&ioc_attr, 0, sizeof(ioc_attr));
-	bfa_get_attr(&bfad->bfa, &ioc_attr);
-	return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.hw_ver);
+	bfa_get_pci_chip_rev(&bfad->bfa, hw_ver);
+	return snprintf(buf, PAGE_SIZE, "%s\n", hw_ver);
 }
 
 static ssize_t
@@ -522,12 +520,10 @@ bfad_im_optionrom_version_show(struct de
 	struct bfad_im_port_s *im_port =
 			(struct bfad_im_port_s *) shost->hostdata[0];
 	struct bfad_s         *bfad = im_port->bfad;
-	struct bfa_ioc_attr_s  ioc_attr;
+	char optrom_ver[BFA_VERSION_LEN];
 
-	memset(&ioc_attr, 0, sizeof(ioc_attr));
-	bfa_get_attr(&bfad->bfa, &ioc_attr);
-	return snprintf(buf, PAGE_SIZE, "%s\n",
-			ioc_attr.adapter_attr.optrom_ver);
+	bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver);
+	return snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver);
 }
 
 static ssize_t
@@ -538,11 +534,10 @@ bfad_im_fw_version_show(struct device *d
 	struct bfad_im_port_s *im_port =
 			(struct bfad_im_port_s *) shost->hostdata[0];
 	struct bfad_s         *bfad = im_port->bfad;
-	struct bfa_ioc_attr_s  ioc_attr;
+	char fw_ver[BFA_VERSION_LEN];
 
-	memset(&ioc_attr, 0, sizeof(ioc_attr));
-	bfa_get_attr(&bfad->bfa, &ioc_attr);
-	return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.fw_ver);
+	bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
+	return snprintf(buf, PAGE_SIZE, "%s\n", fw_ver);
 }
 
 static ssize_t
@@ -553,11 +548,9 @@ bfad_im_num_of_ports_show(struct device
 	struct bfad_im_port_s *im_port =
 			(struct bfad_im_port_s *) shost->hostdata[0];
 	struct bfad_s         *bfad = im_port->bfad;
-	struct bfa_ioc_attr_s  ioc_attr;
 
-	memset(&ioc_attr, 0, sizeof(ioc_attr));
-	bfa_get_attr(&bfad->bfa, &ioc_attr);
-	return snprintf(buf, PAGE_SIZE, "%d\n", ioc_attr.adapter_attr.nports);
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+		bfa_get_nports(&bfad->bfa));
 }
 
 static ssize_t
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_attr.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfad_attr.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_attr.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfad_attr.h	2010-05-16 17:17:36.000000000 -0400
@@ -17,9 +17,6 @@
 
 #ifndef __BFAD_ATTR_H__
 #define __BFAD_ATTR_H__
-/**
- *  bfad_attr.h VMware driver configuration interface module.
- */
 
 /**
  *  FC_transport_template FC transport template
@@ -52,12 +49,6 @@ bfad_im_get_starget_port_name(struct scs
 void
 bfad_im_get_host_port_id(struct Scsi_Host *shost);
 
-/**
- * FC transport template entry, issue a LIP.
- */
-int
-bfad_im_issue_fc_host_lip(struct Scsi_Host *shost);
-
 struct Scsi_Host*
 bfad_os_starget_to_shost(struct scsi_target *starget);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfad.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfad.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,9 @@
  *  bfad.c Linux driver PCI interface module.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/kthread.h>
 #include "bfad_drv.h"
 #include "bfad_im.h"
 #include "bfad_tm.h"
@@ -53,6 +55,7 @@ static int      log_level = BFA_LOG_WARN
 static int      ioc_auto_recover = BFA_TRUE;
 static int      ipfc_enable = BFA_FALSE;
 static int      ipfc_mtu = -1;
+static int	fdmi_enable = BFA_TRUE;
 int 		bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
 int      	bfa_linkup_delay = -1;
 
@@ -74,6 +77,7 @@ module_param(log_level, int, S_IRUGO | S
 module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
 module_param(ipfc_enable, int, S_IRUGO | S_IWUSR);
 module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR);
+module_param(fdmi_enable, int, S_IRUGO | S_IWUSR);
 module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
 
 /*
@@ -95,6 +99,8 @@ bfad_fc4_probe(struct bfad_s *bfad)
 
 	if (ipfc_enable)
 		bfad_ipfc_probe(bfad);
+
+	bfad->bfad_flags |= BFAD_FC4_PROBE_DONE;
 ext:
 	return rc;
 }
@@ -106,6 +112,7 @@ bfad_fc4_probe_undo(struct bfad_s *bfad)
 	bfad_tm_probe_undo(bfad);
 	if (ipfc_enable)
 		bfad_ipfc_probe_undo(bfad);
+	bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
 }
 
 static void
@@ -173,9 +180,19 @@ bfa_cb_init(void *drv, bfa_status_t init
 {
 	struct bfad_s  *bfad = drv;
 
-	if (init_status == BFA_STATUS_OK)
+	if (init_status == BFA_STATUS_OK) {
 		bfad->bfad_flags |= BFAD_HAL_INIT_DONE;
 
+		/* If BFAD_HAL_INIT_FAIL flag is set:
+		 * Wake up the kernel thread to start
+		 * the bfad operations after HAL init done
+		 */
+		if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) {
+			bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL;
+			wake_up_process(bfad->bfad_tsk);
+		}
+	}
+
 	complete(&bfad->comp);
 }
 
@@ -648,7 +665,7 @@ bfad_fcs_port_cfg(struct bfad_s *bfad)
 
 	sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no);
 	memcpy(port_cfg.sym_name.symname, symname, strlen(symname));
-	bfa_pport_get_attr(&bfad->bfa, &attr);
+	bfa_fcport_get_attr(&bfad->bfa, &attr);
 	port_cfg.nwwn = attr.nwwn;
 	port_cfg.pwwn = attr.pwwn;
 
@@ -661,7 +678,6 @@ bfad_drv_init(struct bfad_s *bfad)
 	bfa_status_t    rc;
 	unsigned long   flags;
 	struct bfa_fcs_driver_info_s driver_info;
-	int             i;
 
 	bfad->cfg_data.rport_del_timeout = rport_del_timeout;
 	bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth;
@@ -681,12 +697,7 @@ bfad_drv_init(struct bfad_s *bfad)
 	bfa_init_log(&bfad->bfa, bfad->logmod);
 	bfa_init_trc(&bfad->bfa, bfad->trcmod);
 	bfa_init_aen(&bfad->bfa, bfad->aen);
-	INIT_LIST_HEAD(&bfad->file_q);
-	INIT_LIST_HEAD(&bfad->file_free_q);
-	for (i = 0; i < BFAD_AEN_MAX_APPS; i++) {
-		bfa_q_qe_init(&bfad->file_buf[i].qe);
-		list_add_tail(&bfad->file_buf[i].qe, &bfad->file_free_q);
-	}
+	memset(bfad->file_map, 0, sizeof(bfad->file_map));
 	bfa_init_plog(&bfad->bfa, &bfad->plog_buf);
 	bfa_plog_init(&bfad->plog_buf);
 	bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
@@ -746,8 +757,16 @@ bfad_drv_init(struct bfad_s *bfad)
 	bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod);
 	bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod);
 	bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen);
-	bfa_fcs_init(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
+	bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
+
+	/* Do FCS init only when HAL init is done */
+	if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
+		bfa_fcs_init(&bfad->bfa_fcs);
+		bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
+	}
+
 	bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info);
+	bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable);
 	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
 	bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
@@ -763,12 +782,21 @@ out_hal_mem_alloc_failure:
 void
 bfad_drv_uninit(struct bfad_s *bfad)
 {
+	unsigned long   flags;
+
+	spin_lock_irqsave(&bfad->bfad_lock, flags);
+	init_completion(&bfad->comp);
+	bfa_stop(&bfad->bfa);
+	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+	wait_for_completion(&bfad->comp);
+
 	del_timer_sync(&bfad->hal_tmo);
 	bfa_isr_disable(&bfad->bfa);
 	bfa_detach(&bfad->bfa);
 	bfad_remove_intr(bfad);
-	bfa_assert(list_empty(&bfad->file_q));
 	bfad_hal_mem_release(bfad);
+
+	bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE;
 }
 
 void
@@ -859,6 +887,86 @@ bfad_drv_log_level_set(struct bfad_s *bf
 		bfa_log_set_level_all(&bfad->log_data, log_level);
 }
 
+bfa_status_t
+bfad_start_ops(struct bfad_s *bfad)
+{
+	int retval;
+
+	/* PPORT FCS config */
+	bfad_fcs_port_cfg(bfad);
+
+	retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
+	if (retval != BFA_STATUS_OK)
+		goto out_cfg_pport_failure;
+
+	/* BFAD level FC4 (IM/TM/IPFC) specific resource allocation */
+	retval = bfad_fc4_probe(bfad);
+	if (retval != BFA_STATUS_OK) {
+		printk(KERN_WARNING "bfad_fc4_probe failed\n");
+		goto out_fc4_probe_failure;
+	}
+
+	bfad_drv_start(bfad);
+
+	/*
+	 * If bfa_linkup_delay is set to -1 default; try to retrive the
+	 * value using the bfad_os_get_linkup_delay(); else use the
+	 * passed in module param value as the bfa_linkup_delay.
+	 */
+	if (bfa_linkup_delay < 0) {
+
+		bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
+		bfad_os_rport_online_wait(bfad);
+		bfa_linkup_delay = -1;
+
+	} else {
+		bfad_os_rport_online_wait(bfad);
+	}
+
+	bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
+
+	return BFA_STATUS_OK;
+
+out_fc4_probe_failure:
+	bfad_fc4_probe_undo(bfad);
+	bfad_uncfg_pport(bfad);
+out_cfg_pport_failure:
+	return BFA_STATUS_FAILED;
+}
+
+int
+bfad_worker (void *ptr)
+{
+	struct bfad_s *bfad;
+	unsigned long   flags;
+
+	bfad = (struct bfad_s *)ptr;
+
+	while (!kthread_should_stop()) {
+
+		/* Check if the FCS init is done from bfad_drv_init;
+		 * if not done do FCS init and set the flag.
+		 */
+		if (!(bfad->bfad_flags & BFAD_FCS_INIT_DONE)) {
+			spin_lock_irqsave(&bfad->bfad_lock, flags);
+			bfa_fcs_init(&bfad->bfa_fcs);
+			bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
+			spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+		}
+
+		/* Start the bfad operations after HAL init done */
+		bfad_start_ops(bfad);
+
+		spin_lock_irqsave(&bfad->bfad_lock, flags);
+		bfad->bfad_tsk = NULL;
+		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+		break;
+	}
+
+	return 0;
+}
+
  /*
   *  PCI_entry PCI driver entries * {
   */
@@ -871,7 +979,6 @@ bfad_pci_probe(struct pci_dev *pdev, con
 {
 	struct bfad_s  *bfad;
 	int             error = -ENODEV, retval;
-	char            buf[16];
 
 	/*
 	 * For single port cards - only claim function 0
@@ -902,8 +1009,7 @@ bfad_pci_probe(struct pci_dev *pdev, con
 	bfa_trc(bfad, bfad_inst);
 
 	bfad->logmod = &bfad->log_data;
-	sprintf(buf, "%d", bfad_inst);
-	bfa_log_init(bfad->logmod, buf, bfa_os_printf);
+	bfa_log_init(bfad->logmod, (char *)pci_name(pdev), bfa_os_printf);
 
 	bfad_drv_log_level_set(bfad);
 
@@ -933,57 +1039,39 @@ bfad_pci_probe(struct pci_dev *pdev, con
 	bfad->ref_count = 0;
 	bfad->pport.bfad = bfad;
 
+	bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s",
+					"bfad_worker");
+	if (IS_ERR(bfad->bfad_tsk)) {
+		printk(KERN_INFO "bfad[%d]: Kernel thread"
+			" creation failed!\n",
+			bfad->inst_no);
+		goto out_kthread_create_failure;
+	}
+
 	retval = bfad_drv_init(bfad);
 	if (retval != BFA_STATUS_OK)
 		goto out_drv_init_failure;
 	if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
+		bfad->bfad_flags |= BFAD_HAL_INIT_FAIL;
 		printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no);
 		goto ok;
 	}
 
-	/*
-	 * PPORT FCS config
-	 */
-	bfad_fcs_port_cfg(bfad);
-
-	retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
+	retval = bfad_start_ops(bfad);
 	if (retval != BFA_STATUS_OK)
-		goto out_cfg_pport_failure;
-
-	/*
-	 * BFAD level FC4 (IM/TM/IPFC) specific resource allocation
-	 */
-	retval = bfad_fc4_probe(bfad);
-	if (retval != BFA_STATUS_OK) {
-		printk(KERN_WARNING "bfad_fc4_probe failed\n");
-		goto out_fc4_probe_failure;
-	}
-
-	bfad_drv_start(bfad);
+		goto out_start_ops_failure;
 
-	/*
-	 * If bfa_linkup_delay is set to -1 default; try to retrive the
-	 * value using the bfad_os_get_linkup_delay(); else use the
-	 * passed in module param value as the bfa_linkup_delay.
-	 */
-	if (bfa_linkup_delay < 0) {
-		bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
-		bfad_os_rport_online_wait(bfad);
-		bfa_linkup_delay = -1;
-	} else {
-		bfad_os_rport_online_wait(bfad);
-	}
+	kthread_stop(bfad->bfad_tsk);
+	bfad->bfad_tsk = NULL;
 
-	bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
 ok:
 	return 0;
 
-out_fc4_probe_failure:
-	bfad_fc4_probe_undo(bfad);
-	bfad_uncfg_pport(bfad);
-out_cfg_pport_failure:
+out_start_ops_failure:
 	bfad_drv_uninit(bfad);
 out_drv_init_failure:
+	kthread_stop(bfad->bfad_tsk);
+out_kthread_create_failure:
 	mutex_lock(&bfad_mutex);
 	bfad_inst--;
 	list_del(&bfad->list_entry);
@@ -1008,6 +1096,11 @@ bfad_pci_remove(struct pci_dev *pdev)
 
 	bfa_trc(bfad, bfad->inst_no);
 
+	spin_lock_irqsave(&bfad->bfad_lock, flags);
+	if (bfad->bfad_tsk != NULL)
+		kthread_stop(bfad->bfad_tsk);
+	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
 	if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE)
 	    && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
 
@@ -1024,13 +1117,25 @@ bfad_pci_remove(struct pci_dev *pdev)
 		goto remove_sysfs;
 	}
 
-	if (bfad->bfad_flags & BFAD_HAL_START_DONE)
+	if (bfad->bfad_flags & BFAD_HAL_START_DONE) {
 		bfad_drv_stop(bfad);
+	} else if (bfad->bfad_flags & BFAD_DRV_INIT_DONE) {
+		/* Invoking bfa_stop() before bfa_detach
+		 * when HAL and DRV init are success
+		 * but HAL start did not occur.
+		 */
+		spin_lock_irqsave(&bfad->bfad_lock, flags);
+		init_completion(&bfad->comp);
+		bfa_stop(&bfad->bfa);
+		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+		wait_for_completion(&bfad->comp);
+	}
 
 	bfad_remove_intr(bfad);
-
 	del_timer_sync(&bfad->hal_tmo);
-	bfad_fc4_probe_undo(bfad);
+
+	if (bfad->bfad_flags & BFAD_FC4_PROBE_DONE)
+		bfad_fc4_probe_undo(bfad);
 
 	if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE)
 		bfad_uncfg_pport(bfad);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_drv.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfad_drv.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_drv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfad_drv.h	2010-05-16 17:17:36.000000000 -0400
@@ -46,7 +46,7 @@
 #ifdef BFA_DRIVER_VERSION
 #define BFAD_DRIVER_VERSION    BFA_DRIVER_VERSION
 #else
-#define BFAD_DRIVER_VERSION    "2.0.0.0"
+#define BFAD_DRIVER_VERSION    "2.1.2.1"
 #endif
 
 
@@ -62,7 +62,9 @@
 #define BFAD_HAL_START_DONE			0x00000010
 #define BFAD_PORT_ONLINE			0x00000020
 #define BFAD_RPORT_ONLINE			0x00000040
-
+#define BFAD_FCS_INIT_DONE                      0x00000080
+#define BFAD_HAL_INIT_FAIL                      0x00000100
+#define BFAD_FC4_PROBE_DONE                     0x00000200
 #define BFAD_PORT_DELETE			0x00000001
 
 /*
@@ -137,12 +139,16 @@ struct bfad_cfg_param_s {
 	u32        binding_method;
 };
 
-#define BFAD_AEN_MAX_APPS 8
-struct bfad_aen_file_s {
-	struct list_head  qe;
-	struct bfad_s *bfad;
-	s32 ri;
-	s32 app_id;
+union bfad_tmp_buf {
+	/* From struct bfa_adapter_attr_s */
+	char            manufacturer[BFA_ADAPTER_MFG_NAME_LEN];
+	char            serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
+	char            model[BFA_ADAPTER_MODEL_NAME_LEN];
+	char            fw_ver[BFA_VERSION_LEN];
+	char            optrom_ver[BFA_VERSION_LEN];
+
+	/* From struct bfa_ioc_pci_attr_s */
+	u8         chip_rev[BFA_IOC_CHIP_REV_LEN];  /*  chip revision */
 };
 
 /*
@@ -168,6 +174,7 @@ struct bfad_s {
 	u32        inst_no;	/* BFAD instance number */
 	u32        bfad_flags;
 	spinlock_t      bfad_lock;
+	struct task_struct *bfad_tsk;
 	struct bfad_cfg_param_s cfg_data;
 	struct bfad_msix_s msix_tab[MAX_MSIX_ENTRY];
 	int             nvec;
@@ -183,18 +190,12 @@ struct bfad_s {
 	struct bfa_log_mod_s  *logmod;
 	struct bfa_aen_s      *aen;
 	struct bfa_aen_s       aen_buf;
-	struct bfad_aen_file_s file_buf[BFAD_AEN_MAX_APPS];
-	struct list_head         file_q;
-	struct list_head         file_free_q;
+	void		*file_map[BFA_AEN_MAX_APP];
 	struct bfa_plog_s      plog_buf;
 	int             ref_count;
 	bfa_boolean_t	ipfc_enabled;
+	union bfad_tmp_buf tmp_buf;
 	struct fc_host_statistics link_stats;
-
-	struct kobject *bfa_kobj;
-	struct kobject *ioc_kobj;
-	struct kobject *pport_kobj;
-	struct kobject *lport_kobj;
 };
 
 /*
@@ -258,6 +259,7 @@ bfa_status_t    bfad_vf_create(struct bf
 			       struct bfa_port_cfg_s *port_cfg);
 bfa_status_t    bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role);
 bfa_status_t    bfad_drv_init(struct bfad_s *bfad);
+bfa_status_t	bfad_start_ops(struct bfad_s *bfad);
 void            bfad_drv_start(struct bfad_s *bfad);
 void            bfad_uncfg_pport(struct bfad_s *bfad);
 void            bfad_drv_stop(struct bfad_s *bfad);
@@ -279,6 +281,7 @@ void		bfad_drv_uninit(struct bfad_s *bfa
 void		bfad_drv_log_level_set(struct bfad_s *bfad);
 bfa_status_t	bfad_fc4_module_init(void);
 void		bfad_fc4_module_exit(void);
+int		bfad_worker (void *ptr);
 
 void bfad_pci_remove(struct pci_dev *pdev);
 int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_im.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfad_im.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_im.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfad_im.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  *  bfad_im.c Linux driver IM module.
  */
 
+#include <linux/slab.h>
 #include "bfad_drv.h"
 #include "bfad_im.h"
 #include "bfad_trcmod.h"
@@ -43,11 +44,11 @@ bfa_cb_ioim_done(void *drv, struct bfad_
 	struct bfad_s         *bfad = drv;
 	struct bfad_itnim_data_s *itnim_data;
 	struct bfad_itnim_s *itnim;
+	u8         host_status = DID_OK;
 
 	switch (io_status) {
 	case BFI_IOIM_STS_OK:
 		bfa_trc(bfad, scsi_status);
-		cmnd->result = ScsiResult(DID_OK, scsi_status);
 		scsi_set_resid(cmnd, 0);
 
 		if (sns_len > 0) {
@@ -56,8 +57,18 @@ bfa_cb_ioim_done(void *drv, struct bfad_
 				sns_len = SCSI_SENSE_BUFFERSIZE;
 			memcpy(cmnd->sense_buffer, sns_info, sns_len);
 		}
-		if (residue > 0)
+		if (residue > 0) {
+			bfa_trc(bfad, residue);
 			scsi_set_resid(cmnd, residue);
+			if (!sns_len && (scsi_status == SAM_STAT_GOOD) &&
+				(scsi_bufflen(cmnd) - residue) <
+					cmnd->underflow) {
+				bfa_trc(bfad, 0);
+				host_status = DID_ERROR;
+			}
+		}
+		cmnd->result = ScsiResult(host_status, scsi_status);
+
 		break;
 
 	case BFI_IOIM_STS_ABORTED:
@@ -167,17 +178,15 @@ bfad_im_info(struct Scsi_Host *shost)
 	static char     bfa_buf[256];
 	struct bfad_im_port_s *im_port =
 			(struct bfad_im_port_s *) shost->hostdata[0];
-	struct bfa_ioc_attr_s  ioc_attr;
 	struct bfad_s         *bfad = im_port->bfad;
+	char model[BFA_ADAPTER_MODEL_NAME_LEN];
 
-	memset(&ioc_attr, 0, sizeof(ioc_attr));
-	bfa_get_attr(&bfad->bfa, &ioc_attr);
+	bfa_get_adapter_model(&bfad->bfa, model);
 
 	memset(bfa_buf, 0, sizeof(bfa_buf));
 	snprintf(bfa_buf, sizeof(bfa_buf),
-		 "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s",
-		 ioc_attr.adapter_attr.model, bfad->pci_name,
-		 BFAD_DRIVER_VERSION);
+		"Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s",
+		model, bfad->pci_name, BFAD_DRIVER_VERSION);
 	return bfa_buf;
 }
 
@@ -501,16 +510,6 @@ void bfa_fcb_itnim_tov(struct bfad_itnim
 }
 
 /**
- * Path TOV processing begin notification -- dummy for linux
- */
-void
-bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim)
-{
-}
-
-
-
-/**
  * Allocate a Scsi_Host for a port.
  */
 int
@@ -931,10 +930,9 @@ bfad_os_fc_host_init(struct bfad_im_port
 	struct Scsi_Host *host = im_port->shost;
 	struct bfad_s         *bfad = im_port->bfad;
 	struct bfad_port_s    *port = im_port->port;
-	union attr {
-		struct bfa_pport_attr_s pattr;
-		struct bfa_ioc_attr_s  ioc_attr;
-	} attr;
+	struct bfa_pport_attr_s pattr;
+	char model[BFA_ADAPTER_MODEL_NAME_LEN];
+	char fw_ver[BFA_VERSION_LEN];
 
 	fc_host_node_name(host) =
 		bfa_os_htonll((bfa_fcs_port_get_nwwn(port->fcs_port)));
@@ -954,20 +952,18 @@ bfad_os_fc_host_init(struct bfad_im_port
 	/* For fibre channel services type 0x20 */
 	fc_host_supported_fc4s(host)[7] = 1;
 
-	memset(&attr.ioc_attr, 0, sizeof(attr.ioc_attr));
-	bfa_get_attr(&bfad->bfa, &attr.ioc_attr);
+	bfa_get_adapter_model(&bfad->bfa, model);
+	bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
 	sprintf(fc_host_symbolic_name(host), "Brocade %s FV%s DV%s",
-		attr.ioc_attr.adapter_attr.model,
-		attr.ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION);
+		model, fw_ver, BFAD_DRIVER_VERSION);
 
 	fc_host_supported_speeds(host) = 0;
 	fc_host_supported_speeds(host) |=
 		FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT |
 		FC_PORTSPEED_1GBIT;
 
-	memset(&attr.pattr, 0, sizeof(attr.pattr));
-	bfa_pport_get_attr(&bfad->bfa, &attr.pattr);
-	fc_host_maxframe_size(host) = attr.pattr.pport_cfg.maxfrsize;
+	bfa_fcport_get_attr(&bfad->bfa, &pattr);
+	fc_host_maxframe_size(host) = pattr.pport_cfg.maxfrsize;
 }
 
 static void
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_im.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfad_im.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_im.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfad_im.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 
 #define FCPI_NAME " fcpim"
 
-void bfad_flags_set(struct bfad_s *bfad, u32 flags);
 bfa_status_t bfad_im_module_init(void);
 void bfad_im_module_exit(void);
 bfa_status_t bfad_im_probe(struct bfad_s *bfad);
@@ -126,7 +125,6 @@ bfa_status_t bfad_os_thread_workq(struct
 void bfad_os_destroy_workq(struct bfad_im_s *im);
 void bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv);
 void bfad_os_fc_host_init(struct bfad_im_port_s *im_port);
-void bfad_os_init_work(struct bfad_im_port_s *im_port);
 void bfad_os_scsi_host_free(struct bfad_s *bfad,
 				 struct bfad_im_port_s *im_port);
 void bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim,
@@ -136,9 +134,6 @@ struct bfad_itnim_s *bfad_os_get_itnim(s
 int bfad_os_scsi_add_host(struct Scsi_Host *shost,
 		struct bfad_im_port_s *im_port, struct bfad_s *bfad);
 
-/*
- * scsi_host_template entries
- */
 void bfad_im_itnim_unmap(struct bfad_im_port_s  *im_port,
 			 struct bfad_itnim_s *itnim);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_intr.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfad_intr.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_intr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfad_intr.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,8 +23,10 @@ BFA_TRC_FILE(LDRV, INTR);
 /**
  *  bfa_isr BFA driver interrupt functions
  */
-static int msix_disable;
-module_param(msix_disable, int, S_IRUGO | S_IWUSR);
+static int msix_disable_cb;
+static int msix_disable_ct;
+module_param(msix_disable_cb, int, S_IRUGO | S_IWUSR);
+module_param(msix_disable_ct, int, S_IRUGO | S_IWUSR);
 /**
  * Line based interrupt handler.
  */
@@ -141,6 +143,7 @@ bfad_setup_intr(struct bfad_s *bfad)
 	int error = 0;
 	u32 mask = 0, i, num_bit = 0, max_bit = 0;
 	struct msix_entry msix_entries[MAX_MSIX_ENTRY];
+	struct pci_dev *pdev = bfad->pcidev;
 
 	/* Call BFA to get the msix map for this PCI function.  */
 	bfa_msix_getvecs(&bfad->bfa, &mask, &num_bit, &max_bit);
@@ -148,7 +151,9 @@ bfad_setup_intr(struct bfad_s *bfad)
 	/* Set up the msix entry table */
 	bfad_init_msix_entry(bfad, msix_entries, mask, max_bit);
 
-	if (!msix_disable) {
+	if ((pdev->device == BFA_PCI_DEVICE_ID_CT && !msix_disable_ct) ||
+	    (pdev->device != BFA_PCI_DEVICE_ID_CT && !msix_disable_cb)) {
+
 		error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec);
 		if (error) {
 			/*
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcport.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_fcport.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_fcport.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,40 +23,33 @@
 #include <cs/bfa_plog.h>
 #include <aen/bfa_aen_port.h>
 
-BFA_TRC_FILE(HAL, PPORT);
-BFA_MODULE(pport);
-
-#define bfa_pport_callback(__pport, __event) do {			\
-	if ((__pport)->bfa->fcs) {      \
-		(__pport)->event_cbfn((__pport)->event_cbarg, (__event));      \
-	} else {							\
-		(__pport)->hcb_event = (__event);      \
-		bfa_cb_queue((__pport)->bfa, &(__pport)->hcb_qe,	\
-		__bfa_cb_port_event, (__pport));      \
-	}								\
-} while (0)
+BFA_TRC_FILE(HAL, FCPORT);
+BFA_MODULE(fcport);
 
 /*
  * The port is considered disabled if corresponding physical port or IOC are
  * disabled explicitly
  */
 #define BFA_PORT_IS_DISABLED(bfa) \
-	((bfa_pport_is_disabled(bfa) == BFA_TRUE) || \
+	((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \
 	(bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
 
 /*
  * forward declarations
  */
-static bfa_boolean_t bfa_pport_send_enable(struct bfa_pport_s *port);
-static bfa_boolean_t bfa_pport_send_disable(struct bfa_pport_s *port);
-static void     bfa_pport_update_linkinfo(struct bfa_pport_s *pport);
-static void     bfa_pport_reset_linkinfo(struct bfa_pport_s *pport);
-static void     bfa_pport_set_wwns(struct bfa_pport_s *port);
-static void     __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete);
-static void     __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete);
-static void     __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete);
-static void     bfa_port_stats_timeout(void *cbarg);
-static void     bfa_port_stats_clr_timeout(void *cbarg);
+static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport);
+static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport);
+static void     bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport);
+static void     bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport);
+static void     bfa_fcport_set_wwns(struct bfa_fcport_s *fcport);
+static void     __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete);
+static void     bfa_fcport_callback(struct bfa_fcport_s *fcport,
+				enum bfa_pport_linkstate event);
+static void     bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln,
+				enum bfa_pport_linkstate event);
+static void     __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete);
+static void     bfa_fcport_stats_get_timeout(void *cbarg);
+static void     bfa_fcport_stats_clr_timeout(void *cbarg);
 
 /**
  *  bfa_pport_private
@@ -65,111 +58,114 @@ static void     bfa_port_stats_clr_timeo
 /**
  * BFA port state machine events
  */
-enum bfa_pport_sm_event {
-	BFA_PPORT_SM_START = 1,	/*  start port state machine */
-	BFA_PPORT_SM_STOP = 2,	/*  stop port state machine */
-	BFA_PPORT_SM_ENABLE = 3,	/*  enable port */
-	BFA_PPORT_SM_DISABLE = 4,	/*  disable port state machine */
-	BFA_PPORT_SM_FWRSP = 5,	/*  firmware enable/disable rsp */
-	BFA_PPORT_SM_LINKUP = 6,	/*  firmware linkup event */
-	BFA_PPORT_SM_LINKDOWN = 7,	/*  firmware linkup down */
-	BFA_PPORT_SM_QRESUME = 8,	/*  CQ space available */
-	BFA_PPORT_SM_HWFAIL = 9,	/*  IOC h/w failure */
+enum bfa_fcport_sm_event {
+	BFA_FCPORT_SM_START = 1,	/*  start port state machine */
+	BFA_FCPORT_SM_STOP = 2,	/*  stop port state machine */
+	BFA_FCPORT_SM_ENABLE = 3,	/*  enable port */
+	BFA_FCPORT_SM_DISABLE = 4,	/*  disable port state machine */
+	BFA_FCPORT_SM_FWRSP = 5,	/*  firmware enable/disable rsp */
+	BFA_FCPORT_SM_LINKUP = 6,	/*  firmware linkup event */
+	BFA_FCPORT_SM_LINKDOWN = 7,	/*  firmware linkup down */
+	BFA_FCPORT_SM_QRESUME = 8,	/*  CQ space available */
+	BFA_FCPORT_SM_HWFAIL = 9,	/*  IOC h/w failure */
 };
 
-static void     bfa_pport_sm_uninit(struct bfa_pport_s *pport,
-				    enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
-					    enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_enabling(struct bfa_pport_s *pport,
-				      enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_linkdown(struct bfa_pport_s *pport,
-				      enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_linkup(struct bfa_pport_s *pport,
-				    enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_disabling(struct bfa_pport_s *pport,
-				       enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport,
-					     enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_disabled(struct bfa_pport_s *pport,
-				      enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_stopped(struct bfa_pport_s *pport,
-				     enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_iocdown(struct bfa_pport_s *pport,
-				     enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_iocfail(struct bfa_pport_s *pport,
-				     enum bfa_pport_sm_event event);
+/**
+ * BFA port link notification state machine events
+ */
+
+enum bfa_fcport_ln_sm_event {
+	BFA_FCPORT_LN_SM_LINKUP         = 1,    /*  linkup event */
+	BFA_FCPORT_LN_SM_LINKDOWN       = 2,    /*  linkdown event */
+	BFA_FCPORT_LN_SM_NOTIFICATION   = 3     /*  done notification */
+};
+
+static void     bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
+					enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
+						enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
+						enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
+						enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
+						enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
+						enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
+						enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
+						enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
+					 enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
+					 enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
+					 enum bfa_fcport_sm_event event);
+
+static void     bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
+					 enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
+					 enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
+					 enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
+					 enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
+					 enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
+					 enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
+					 enum bfa_fcport_ln_sm_event event);
 
 static struct bfa_sm_table_s hal_pport_sm_table[] = {
-	{BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT},
-	{BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
-	{BFA_SM(bfa_pport_sm_enabling), BFA_PPORT_ST_ENABLING},
-	{BFA_SM(bfa_pport_sm_linkdown), BFA_PPORT_ST_LINKDOWN},
-	{BFA_SM(bfa_pport_sm_linkup), BFA_PPORT_ST_LINKUP},
-	{BFA_SM(bfa_pport_sm_disabling_qwait),
-	 BFA_PPORT_ST_DISABLING_QWAIT},
-	{BFA_SM(bfa_pport_sm_disabling), BFA_PPORT_ST_DISABLING},
-	{BFA_SM(bfa_pport_sm_disabled), BFA_PPORT_ST_DISABLED},
-	{BFA_SM(bfa_pport_sm_stopped), BFA_PPORT_ST_STOPPED},
-	{BFA_SM(bfa_pport_sm_iocdown), BFA_PPORT_ST_IOCDOWN},
-	{BFA_SM(bfa_pport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
+	{BFA_SM(bfa_fcport_sm_uninit), BFA_PPORT_ST_UNINIT},
+	{BFA_SM(bfa_fcport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
+	{BFA_SM(bfa_fcport_sm_enabling), BFA_PPORT_ST_ENABLING},
+	{BFA_SM(bfa_fcport_sm_linkdown), BFA_PPORT_ST_LINKDOWN},
+	{BFA_SM(bfa_fcport_sm_linkup), BFA_PPORT_ST_LINKUP},
+	{BFA_SM(bfa_fcport_sm_disabling_qwait), BFA_PPORT_ST_DISABLING_QWAIT},
+	{BFA_SM(bfa_fcport_sm_disabling), BFA_PPORT_ST_DISABLING},
+	{BFA_SM(bfa_fcport_sm_disabled), BFA_PPORT_ST_DISABLED},
+	{BFA_SM(bfa_fcport_sm_stopped), BFA_PPORT_ST_STOPPED},
+	{BFA_SM(bfa_fcport_sm_iocdown), BFA_PPORT_ST_IOCDOWN},
+	{BFA_SM(bfa_fcport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
 };
 
 static void
-bfa_pport_aen_post(struct bfa_pport_s *pport, enum bfa_port_aen_event event)
+bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event)
 {
 	union bfa_aen_data_u aen_data;
-	struct bfa_log_mod_s *logmod = pport->bfa->logm;
-	wwn_t           pwwn = pport->pwwn;
+	struct bfa_log_mod_s *logmod = fcport->bfa->logm;
+	wwn_t           pwwn = fcport->pwwn;
 	char            pwwn_ptr[BFA_STRING_32];
-	struct bfa_ioc_attr_s ioc_attr;
 
+	memset(&aen_data, 0, sizeof(aen_data));
 	wwn2str(pwwn_ptr, pwwn);
-	switch (event) {
-	case BFA_PORT_AEN_ONLINE:
-		bfa_log(logmod, BFA_AEN_PORT_ONLINE, pwwn_ptr);
-		break;
-	case BFA_PORT_AEN_OFFLINE:
-		bfa_log(logmod, BFA_AEN_PORT_OFFLINE, pwwn_ptr);
-		break;
-	case BFA_PORT_AEN_ENABLE:
-		bfa_log(logmod, BFA_AEN_PORT_ENABLE, pwwn_ptr);
-		break;
-	case BFA_PORT_AEN_DISABLE:
-		bfa_log(logmod, BFA_AEN_PORT_DISABLE, pwwn_ptr);
-		break;
-	case BFA_PORT_AEN_DISCONNECT:
-		bfa_log(logmod, BFA_AEN_PORT_DISCONNECT, pwwn_ptr);
-		break;
-	case BFA_PORT_AEN_QOS_NEG:
-		bfa_log(logmod, BFA_AEN_PORT_QOS_NEG, pwwn_ptr);
-		break;
-	default:
-		break;
-	}
+	bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event), pwwn_ptr);
 
-	bfa_ioc_get_attr(&pport->bfa->ioc, &ioc_attr);
-	aen_data.port.ioc_type = ioc_attr.ioc_type;
+	aen_data.port.ioc_type = bfa_get_type(fcport->bfa);
 	aen_data.port.pwwn = pwwn;
 }
 
 static void
-bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
+			enum bfa_fcport_sm_event event)
 {
-	bfa_trc(pport->bfa, event);
+	bfa_trc(fcport->bfa, event);
 
 	switch (event) {
-	case BFA_PPORT_SM_START:
+	case BFA_FCPORT_SM_START:
 		/**
 		 * Start event after IOC is configured and BFA is started.
 		 */
-		if (bfa_pport_send_enable(pport))
-			bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+		if (bfa_fcport_send_enable(fcport))
+			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
 		else
-			bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
 		break;
 
-	case BFA_PPORT_SM_ENABLE:
+	case BFA_FCPORT_SM_ENABLE:
 		/**
 		 * Port is persistently configured to be in enabled state. Do
 		 * not change state. Port enabling is done when START event is
@@ -177,389 +173,412 @@ bfa_pport_sm_uninit(struct bfa_pport_s *
 		 */
 		break;
 
-	case BFA_PPORT_SM_DISABLE:
+	case BFA_FCPORT_SM_DISABLE:
 		/**
 		 * If a port is persistently configured to be disabled, the
 		 * first event will a port disable request.
 		 */
-		bfa_sm_set_state(pport, bfa_pport_sm_disabled);
+		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
 		break;
 
-	case BFA_PPORT_SM_HWFAIL:
-		bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+	case BFA_FCPORT_SM_HWFAIL:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
 		break;
 
 	default:
-		bfa_sm_fault(pport->bfa, event);
+		bfa_sm_fault(fcport->bfa, event);
 	}
 }
 
 static void
-bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
-			    enum bfa_pport_sm_event event)
+bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
+			    enum bfa_fcport_sm_event event)
 {
-	bfa_trc(pport->bfa, event);
+	bfa_trc(fcport->bfa, event);
 
 	switch (event) {
-	case BFA_PPORT_SM_QRESUME:
-		bfa_sm_set_state(pport, bfa_pport_sm_enabling);
-		bfa_pport_send_enable(pport);
+	case BFA_FCPORT_SM_QRESUME:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
+		bfa_fcport_send_enable(fcport);
 		break;
 
-	case BFA_PPORT_SM_STOP:
-		bfa_reqq_wcancel(&pport->reqq_wait);
-		bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+	case BFA_FCPORT_SM_STOP:
+		bfa_reqq_wcancel(&fcport->reqq_wait);
+		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
 		break;
 
-	case BFA_PPORT_SM_ENABLE:
+	case BFA_FCPORT_SM_ENABLE:
 		/**
 		 * Already enable is in progress.
 		 */
 		break;
 
-	case BFA_PPORT_SM_DISABLE:
+	case BFA_FCPORT_SM_DISABLE:
 		/**
 		 * Just send disable request to firmware when room becomes
 		 * available in request queue.
 		 */
-		bfa_sm_set_state(pport, bfa_pport_sm_disabled);
-		bfa_reqq_wcancel(&pport->reqq_wait);
-		bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
+		bfa_reqq_wcancel(&fcport->reqq_wait);
+		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
 			     BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
-		bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
 		break;
 
-	case BFA_PPORT_SM_LINKUP:
-	case BFA_PPORT_SM_LINKDOWN:
+	case BFA_FCPORT_SM_LINKUP:
+	case BFA_FCPORT_SM_LINKDOWN:
 		/**
 		 * Possible to get link events when doing back-to-back
 		 * enable/disables.
 		 */
 		break;
 
-	case BFA_PPORT_SM_HWFAIL:
-		bfa_reqq_wcancel(&pport->reqq_wait);
-		bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+	case BFA_FCPORT_SM_HWFAIL:
+		bfa_reqq_wcancel(&fcport->reqq_wait);
+		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
 		break;
 
 	default:
-		bfa_sm_fault(pport->bfa, event);
+		bfa_sm_fault(fcport->bfa, event);
 	}
 }
 
 static void
-bfa_pport_sm_enabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
+		enum bfa_fcport_sm_event event)
 {
-	bfa_trc(pport->bfa, event);
+	bfa_trc(fcport->bfa, event);
 
 	switch (event) {
-	case BFA_PPORT_SM_FWRSP:
-	case BFA_PPORT_SM_LINKDOWN:
-		bfa_sm_set_state(pport, bfa_pport_sm_linkdown);
+	case BFA_FCPORT_SM_FWRSP:
+	case BFA_FCPORT_SM_LINKDOWN:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
 		break;
 
-	case BFA_PPORT_SM_LINKUP:
-		bfa_pport_update_linkinfo(pport);
-		bfa_sm_set_state(pport, bfa_pport_sm_linkup);
+	case BFA_FCPORT_SM_LINKUP:
+		bfa_fcport_update_linkinfo(fcport);
+		bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
 
-		bfa_assert(pport->event_cbfn);
-		bfa_pport_callback(pport, BFA_PPORT_LINKUP);
+		bfa_assert(fcport->event_cbfn);
+		bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
 		break;
 
-	case BFA_PPORT_SM_ENABLE:
+	case BFA_FCPORT_SM_ENABLE:
 		/**
 		 * Already being enabled.
 		 */
 		break;
 
-	case BFA_PPORT_SM_DISABLE:
-		if (bfa_pport_send_disable(pport))
-			bfa_sm_set_state(pport, bfa_pport_sm_disabling);
+	case BFA_FCPORT_SM_DISABLE:
+		if (bfa_fcport_send_disable(fcport))
+			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
 		else
-			bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
+			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
 
-		bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
 			     BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
-		bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
 		break;
 
-	case BFA_PPORT_SM_STOP:
-		bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+	case BFA_FCPORT_SM_STOP:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
 		break;
 
-	case BFA_PPORT_SM_HWFAIL:
-		bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+	case BFA_FCPORT_SM_HWFAIL:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
 		break;
 
 	default:
-		bfa_sm_fault(pport->bfa, event);
+		bfa_sm_fault(fcport->bfa, event);
 	}
 }
 
 static void
-bfa_pport_sm_linkdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
+			enum bfa_fcport_sm_event event)
 {
-	bfa_trc(pport->bfa, event);
+	struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
+	bfa_trc(fcport->bfa, event);
 
 	switch (event) {
-	case BFA_PPORT_SM_LINKUP:
-		bfa_pport_update_linkinfo(pport);
-		bfa_sm_set_state(pport, bfa_pport_sm_linkup);
-		bfa_assert(pport->event_cbfn);
-		bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+	case BFA_FCPORT_SM_LINKUP:
+		bfa_fcport_update_linkinfo(fcport);
+		bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
+		bfa_assert(fcport->event_cbfn);
+		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
 			     BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup");
-		bfa_pport_callback(pport, BFA_PPORT_LINKUP);
-		bfa_pport_aen_post(pport, BFA_PORT_AEN_ONLINE);
+
+		if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
+
+			bfa_trc(fcport->bfa, pevent->link_state.fcf.fipenabled);
+			bfa_trc(fcport->bfa, pevent->link_state.fcf.fipfailed);
+
+			if (pevent->link_state.fcf.fipfailed)
+				bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
+					BFA_PL_EID_FIP_FCF_DISC, 0,
+					"FIP FCF Discovery Failed");
+			else
+				bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
+					BFA_PL_EID_FIP_FCF_DISC, 0,
+					"FIP FCF Discovered");
+		}
+
+		bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
+		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE);
 		/**
 		 * If QoS is enabled and it is not online,
 		 * Send a separate event.
 		 */
-		if ((pport->cfg.qos_enabled)
-		    && (bfa_os_ntohl(pport->qos_attr.state) != BFA_QOS_ONLINE))
-			bfa_pport_aen_post(pport, BFA_PORT_AEN_QOS_NEG);
+		if ((fcport->cfg.qos_enabled)
+		    && (bfa_os_ntohl(fcport->qos_attr.state) != BFA_QOS_ONLINE))
+			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG);
 
 		break;
 
-	case BFA_PPORT_SM_LINKDOWN:
+	case BFA_FCPORT_SM_LINKDOWN:
 		/**
 		 * Possible to get link down event.
 		 */
 		break;
 
-	case BFA_PPORT_SM_ENABLE:
+	case BFA_FCPORT_SM_ENABLE:
 		/**
 		 * Already enabled.
 		 */
 		break;
 
-	case BFA_PPORT_SM_DISABLE:
-		if (bfa_pport_send_disable(pport))
-			bfa_sm_set_state(pport, bfa_pport_sm_disabling);
+	case BFA_FCPORT_SM_DISABLE:
+		if (bfa_fcport_send_disable(fcport))
+			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
 		else
-			bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
+			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
 
-		bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
 			     BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
-		bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
 		break;
 
-	case BFA_PPORT_SM_STOP:
-		bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+	case BFA_FCPORT_SM_STOP:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
 		break;
 
-	case BFA_PPORT_SM_HWFAIL:
-		bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+	case BFA_FCPORT_SM_HWFAIL:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
 		break;
 
 	default:
-		bfa_sm_fault(pport->bfa, event);
+		bfa_sm_fault(fcport->bfa, event);
 	}
 }
 
 static void
-bfa_pport_sm_linkup(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
+			enum bfa_fcport_sm_event event)
 {
-	bfa_trc(pport->bfa, event);
+	bfa_trc(fcport->bfa, event);
 
 	switch (event) {
-	case BFA_PPORT_SM_ENABLE:
+	case BFA_FCPORT_SM_ENABLE:
 		/**
 		 * Already enabled.
 		 */
 		break;
 
-	case BFA_PPORT_SM_DISABLE:
-		if (bfa_pport_send_disable(pport))
-			bfa_sm_set_state(pport, bfa_pport_sm_disabling);
+	case BFA_FCPORT_SM_DISABLE:
+		if (bfa_fcport_send_disable(fcport))
+			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
 		else
-			bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
+			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
 
-		bfa_pport_reset_linkinfo(pport);
-		bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
-		bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+		bfa_fcport_reset_linkinfo(fcport);
+		bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
+		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
 			     BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
-		bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
-		bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
+		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
 		break;
 
-	case BFA_PPORT_SM_LINKDOWN:
-		bfa_sm_set_state(pport, bfa_pport_sm_linkdown);
-		bfa_pport_reset_linkinfo(pport);
-		bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
-		bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+	case BFA_FCPORT_SM_LINKDOWN:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
+		bfa_fcport_reset_linkinfo(fcport);
+		bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
+		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
 			     BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
-		if (BFA_PORT_IS_DISABLED(pport->bfa))
-			bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
+		if (BFA_PORT_IS_DISABLED(fcport->bfa))
+			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
 		else
-			bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
+			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
 		break;
 
-	case BFA_PPORT_SM_STOP:
-		bfa_sm_set_state(pport, bfa_pport_sm_stopped);
-		bfa_pport_reset_linkinfo(pport);
-		if (BFA_PORT_IS_DISABLED(pport->bfa))
-			bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
+	case BFA_FCPORT_SM_STOP:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
+		bfa_fcport_reset_linkinfo(fcport);
+		if (BFA_PORT_IS_DISABLED(fcport->bfa))
+			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
 		else
-			bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
+			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
 		break;
 
-	case BFA_PPORT_SM_HWFAIL:
-		bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
-		bfa_pport_reset_linkinfo(pport);
-		bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
-		if (BFA_PORT_IS_DISABLED(pport->bfa))
-			bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
+	case BFA_FCPORT_SM_HWFAIL:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
+		bfa_fcport_reset_linkinfo(fcport);
+		bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
+		if (BFA_PORT_IS_DISABLED(fcport->bfa))
+			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
 		else
-			bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
+			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
 		break;
 
 	default:
-		bfa_sm_fault(pport->bfa, event);
+		bfa_sm_fault(fcport->bfa, event);
 	}
 }
 
 static void
-bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport,
-			     enum bfa_pport_sm_event event)
+bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
+			     enum bfa_fcport_sm_event event)
 {
-	bfa_trc(pport->bfa, event);
+	bfa_trc(fcport->bfa, event);
 
 	switch (event) {
-	case BFA_PPORT_SM_QRESUME:
-		bfa_sm_set_state(pport, bfa_pport_sm_disabling);
-		bfa_pport_send_disable(pport);
+	case BFA_FCPORT_SM_QRESUME:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
+		bfa_fcport_send_disable(fcport);
 		break;
 
-	case BFA_PPORT_SM_STOP:
-		bfa_sm_set_state(pport, bfa_pport_sm_stopped);
-		bfa_reqq_wcancel(&pport->reqq_wait);
+	case BFA_FCPORT_SM_STOP:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
+		bfa_reqq_wcancel(&fcport->reqq_wait);
 		break;
 
-	case BFA_PPORT_SM_DISABLE:
+	case BFA_FCPORT_SM_DISABLE:
 		/**
 		 * Already being disabled.
 		 */
 		break;
 
-	case BFA_PPORT_SM_LINKUP:
-	case BFA_PPORT_SM_LINKDOWN:
+	case BFA_FCPORT_SM_LINKUP:
+	case BFA_FCPORT_SM_LINKDOWN:
 		/**
 		 * Possible to get link events when doing back-to-back
 		 * enable/disables.
 		 */
 		break;
 
-	case BFA_PPORT_SM_HWFAIL:
-		bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
-		bfa_reqq_wcancel(&pport->reqq_wait);
+	case BFA_FCPORT_SM_HWFAIL:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
+		bfa_reqq_wcancel(&fcport->reqq_wait);
 		break;
 
 	default:
-		bfa_sm_fault(pport->bfa, event);
+		bfa_sm_fault(fcport->bfa, event);
 	}
 }
 
 static void
-bfa_pport_sm_disabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
+			enum bfa_fcport_sm_event event)
 {
-	bfa_trc(pport->bfa, event);
+	bfa_trc(fcport->bfa, event);
 
 	switch (event) {
-	case BFA_PPORT_SM_FWRSP:
-		bfa_sm_set_state(pport, bfa_pport_sm_disabled);
+	case BFA_FCPORT_SM_FWRSP:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
 		break;
 
-	case BFA_PPORT_SM_DISABLE:
+	case BFA_FCPORT_SM_DISABLE:
 		/**
 		 * Already being disabled.
 		 */
 		break;
 
-	case BFA_PPORT_SM_ENABLE:
-		if (bfa_pport_send_enable(pport))
-			bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+	case BFA_FCPORT_SM_ENABLE:
+		if (bfa_fcport_send_enable(fcport))
+			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
 		else
-			bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
 
-		bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
 			     BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
-		bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE);
+		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
 		break;
 
-	case BFA_PPORT_SM_STOP:
-		bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+	case BFA_FCPORT_SM_STOP:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
 		break;
 
-	case BFA_PPORT_SM_LINKUP:
-	case BFA_PPORT_SM_LINKDOWN:
+	case BFA_FCPORT_SM_LINKUP:
+	case BFA_FCPORT_SM_LINKDOWN:
 		/**
 		 * Possible to get link events when doing back-to-back
 		 * enable/disables.
 		 */
 		break;
 
-	case BFA_PPORT_SM_HWFAIL:
-		bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
+	case BFA_FCPORT_SM_HWFAIL:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
 		break;
 
 	default:
-		bfa_sm_fault(pport->bfa, event);
+		bfa_sm_fault(fcport->bfa, event);
 	}
 }
 
 static void
-bfa_pport_sm_disabled(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
+			enum bfa_fcport_sm_event event)
 {
-	bfa_trc(pport->bfa, event);
+	bfa_trc(fcport->bfa, event);
 
 	switch (event) {
-	case BFA_PPORT_SM_START:
+	case BFA_FCPORT_SM_START:
 		/**
 		 * Ignore start event for a port that is disabled.
 		 */
 		break;
 
-	case BFA_PPORT_SM_STOP:
-		bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+	case BFA_FCPORT_SM_STOP:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
 		break;
 
-	case BFA_PPORT_SM_ENABLE:
-		if (bfa_pport_send_enable(pport))
-			bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+	case BFA_FCPORT_SM_ENABLE:
+		if (bfa_fcport_send_enable(fcport))
+			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
 		else
-			bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
 
-		bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
 			     BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
-		bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE);
+		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
 		break;
 
-	case BFA_PPORT_SM_DISABLE:
+	case BFA_FCPORT_SM_DISABLE:
 		/**
 		 * Already disabled.
 		 */
 		break;
 
-	case BFA_PPORT_SM_HWFAIL:
-		bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
+	case BFA_FCPORT_SM_HWFAIL:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
 		break;
 
 	default:
-		bfa_sm_fault(pport->bfa, event);
+		bfa_sm_fault(fcport->bfa, event);
 	}
 }
 
 static void
-bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
+			enum bfa_fcport_sm_event event)
 {
-	bfa_trc(pport->bfa, event);
+	bfa_trc(fcport->bfa, event);
 
 	switch (event) {
-	case BFA_PPORT_SM_START:
-		if (bfa_pport_send_enable(pport))
-			bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+	case BFA_FCPORT_SM_START:
+		if (bfa_fcport_send_enable(fcport))
+			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
 		else
-			bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
 		break;
 
 	default:
@@ -574,16 +593,17 @@ bfa_pport_sm_stopped(struct bfa_pport_s
  * Port is enabled. IOC is down/failed.
  */
 static void
-bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
+			enum bfa_fcport_sm_event event)
 {
-	bfa_trc(pport->bfa, event);
+	bfa_trc(fcport->bfa, event);
 
 	switch (event) {
-	case BFA_PPORT_SM_START:
-		if (bfa_pport_send_enable(pport))
-			bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+	case BFA_FCPORT_SM_START:
+		if (bfa_fcport_send_enable(fcport))
+			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
 		else
-			bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
 		break;
 
 	default:
@@ -598,17 +618,18 @@ bfa_pport_sm_iocdown(struct bfa_pport_s
  * Port is disabled. IOC is down/failed.
  */
 static void
-bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
+			enum bfa_fcport_sm_event event)
 {
-	bfa_trc(pport->bfa, event);
+	bfa_trc(fcport->bfa, event);
 
 	switch (event) {
-	case BFA_PPORT_SM_START:
-		bfa_sm_set_state(pport, bfa_pport_sm_disabled);
+	case BFA_FCPORT_SM_START:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
 		break;
 
-	case BFA_PPORT_SM_ENABLE:
-		bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+	case BFA_FCPORT_SM_ENABLE:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
 		break;
 
 	default:
@@ -619,41 +640,226 @@ bfa_pport_sm_iocfail(struct bfa_pport_s
 	}
 }
 
+/**
+ * Link state is down
+ */
+static void
+bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
+		enum bfa_fcport_ln_sm_event event)
+{
+	bfa_trc(ln->fcport->bfa, event);
 
+	switch (event) {
+	case BFA_FCPORT_LN_SM_LINKUP:
+		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
+		bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
+		break;
+
+	default:
+		bfa_sm_fault(ln->fcport->bfa, event);
+	}
+}
+
+/**
+ * Link state is waiting for down notification
+ */
+static void
+bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
+		enum bfa_fcport_ln_sm_event event)
+{
+	bfa_trc(ln->fcport->bfa, event);
+
+	switch (event) {
+	case BFA_FCPORT_LN_SM_LINKUP:
+		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
+		break;
+
+	case BFA_FCPORT_LN_SM_NOTIFICATION:
+		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
+		break;
+
+	default:
+		bfa_sm_fault(ln->fcport->bfa, event);
+	}
+}
+
+/**
+ * Link state is waiting for down notification and there is a pending up
+ */
+static void
+bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
+		enum bfa_fcport_ln_sm_event event)
+{
+	bfa_trc(ln->fcport->bfa, event);
+
+	switch (event) {
+	case BFA_FCPORT_LN_SM_LINKDOWN:
+		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
+		break;
+
+	case BFA_FCPORT_LN_SM_NOTIFICATION:
+		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
+		bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
+		break;
+
+	default:
+		bfa_sm_fault(ln->fcport->bfa, event);
+	}
+}
+
+/**
+ * Link state is up
+ */
+static void
+bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
+		enum bfa_fcport_ln_sm_event event)
+{
+	bfa_trc(ln->fcport->bfa, event);
+
+	switch (event) {
+	case BFA_FCPORT_LN_SM_LINKDOWN:
+		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
+		bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
+		break;
+
+	default:
+		bfa_sm_fault(ln->fcport->bfa, event);
+	}
+}
+
+/**
+ * Link state is waiting for up notification
+ */
+static void
+bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
+		enum bfa_fcport_ln_sm_event event)
+{
+	bfa_trc(ln->fcport->bfa, event);
+
+	switch (event) {
+	case BFA_FCPORT_LN_SM_LINKDOWN:
+		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
+		break;
+
+	case BFA_FCPORT_LN_SM_NOTIFICATION:
+		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up);
+		break;
+
+	default:
+		bfa_sm_fault(ln->fcport->bfa, event);
+	}
+}
+
+/**
+ * Link state is waiting for up notification and there is a pending down
+ */
+static void
+bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
+		enum bfa_fcport_ln_sm_event event)
+{
+	bfa_trc(ln->fcport->bfa, event);
+
+	switch (event) {
+	case BFA_FCPORT_LN_SM_LINKUP:
+		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf);
+		break;
+
+	case BFA_FCPORT_LN_SM_NOTIFICATION:
+		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
+		bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
+		break;
+
+	default:
+		bfa_sm_fault(ln->fcport->bfa, event);
+	}
+}
+
+/**
+ * Link state is waiting for up notification and there are pending down and up
+ */
+static void
+bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
+			enum bfa_fcport_ln_sm_event event)
+{
+	bfa_trc(ln->fcport->bfa, event);
+
+	switch (event) {
+	case BFA_FCPORT_LN_SM_LINKDOWN:
+		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
+		break;
+
+	case BFA_FCPORT_LN_SM_NOTIFICATION:
+		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
+		bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
+		break;
+
+	default:
+		bfa_sm_fault(ln->fcport->bfa, event);
+	}
+}
 
 /**
  *  bfa_pport_private
  */
 
 static void
-__bfa_cb_port_event(void *cbarg, bfa_boolean_t complete)
+__bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete)
 {
-	struct bfa_pport_s *pport = cbarg;
+	struct bfa_fcport_ln_s *ln = cbarg;
 
 	if (complete)
-		pport->event_cbfn(pport->event_cbarg, pport->hcb_event);
+		ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event);
+	else
+		bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION);
 }
 
-#define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \
+static void
+bfa_fcport_callback(struct bfa_fcport_s *fcport, enum bfa_pport_linkstate event)
+{
+	if (fcport->bfa->fcs) {
+		fcport->event_cbfn(fcport->event_cbarg, event);
+		return;
+	}
+
+	switch (event) {
+	case BFA_PPORT_LINKUP:
+		bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP);
+		break;
+	case BFA_PPORT_LINKDOWN:
+		bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN);
+		break;
+	default:
+		bfa_assert(0);
+	}
+}
+
+static void
+bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_pport_linkstate event)
+{
+	ln->ln_event = event;
+	bfa_cb_queue(ln->fcport->bfa, &ln->ln_qe, __bfa_cb_fcport_event, ln);
+}
+
+#define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \
 							BFA_CACHELINE_SZ))
 
 static void
-bfa_pport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
+bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
 		  u32 *dm_len)
 {
-	*dm_len += PPORT_STATS_DMA_SZ;
+	*dm_len += FCPORT_STATS_DMA_SZ;
 }
 
 static void
-bfa_pport_qresume(void *cbarg)
+bfa_fcport_qresume(void *cbarg)
 {
-	struct bfa_pport_s *port = cbarg;
+	struct bfa_fcport_s *fcport = cbarg;
 
-	bfa_sm_send_event(port, BFA_PPORT_SM_QRESUME);
+	bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME);
 }
 
 static void
-bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo)
+bfa_fcport_mem_claim(struct bfa_fcport_s *fcport, struct bfa_meminfo_s *meminfo)
 {
 	u8        *dm_kva;
 	u64        dm_pa;
@@ -661,12 +867,12 @@ bfa_pport_mem_claim(struct bfa_pport_s *
 	dm_kva = bfa_meminfo_dma_virt(meminfo);
 	dm_pa = bfa_meminfo_dma_phys(meminfo);
 
-	pport->stats_kva = dm_kva;
-	pport->stats_pa = dm_pa;
-	pport->stats = (union bfa_pport_stats_u *)dm_kva;
+	fcport->stats_kva = dm_kva;
+	fcport->stats_pa = dm_pa;
+	fcport->stats = (union bfa_fcport_stats_u *)dm_kva;
 
-	dm_kva += PPORT_STATS_DMA_SZ;
-	dm_pa += PPORT_STATS_DMA_SZ;
+	dm_kva += FCPORT_STATS_DMA_SZ;
+	dm_pa += FCPORT_STATS_DMA_SZ;
 
 	bfa_meminfo_dma_virt(meminfo) = dm_kva;
 	bfa_meminfo_dma_phys(meminfo) = dm_pa;
@@ -676,18 +882,21 @@ bfa_pport_mem_claim(struct bfa_pport_s *
  * Memory initialization.
  */
 static void
-bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
+bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
 		 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
-	struct bfa_pport_cfg_s *port_cfg = &pport->cfg;
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+	struct bfa_pport_cfg_s *port_cfg = &fcport->cfg;
+	struct bfa_fcport_ln_s *ln = &fcport->ln;
 
-	bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s));
-	pport->bfa = bfa;
+	bfa_os_memset(fcport, 0, sizeof(struct bfa_fcport_s));
+	fcport->bfa = bfa;
+	ln->fcport = fcport;
 
-	bfa_pport_mem_claim(pport, meminfo);
+	bfa_fcport_mem_claim(fcport, meminfo);
 
-	bfa_sm_set_state(pport, bfa_pport_sm_uninit);
+	bfa_sm_set_state(fcport, bfa_fcport_sm_uninit);
+	bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
 
 	/**
 	 * initialize and set default configuration
@@ -699,30 +908,30 @@ bfa_pport_attach(struct bfa_s *bfa, void
 
 	port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS;
 
-	bfa_reqq_winit(&pport->reqq_wait, bfa_pport_qresume, pport);
+	bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport);
 }
 
 static void
-bfa_pport_initdone(struct bfa_s *bfa)
+bfa_fcport_initdone(struct bfa_s *bfa)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
 	/**
 	 * Initialize port attributes from IOC hardware data.
 	 */
-	bfa_pport_set_wwns(pport);
-	if (pport->cfg.maxfrsize == 0)
-		pport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
-	pport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
-	pport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
+	bfa_fcport_set_wwns(fcport);
+	if (fcport->cfg.maxfrsize == 0)
+		fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
+	fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
+	fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
 
-	bfa_assert(pport->cfg.maxfrsize);
-	bfa_assert(pport->cfg.rx_bbcredit);
-	bfa_assert(pport->speed_sup);
+	bfa_assert(fcport->cfg.maxfrsize);
+	bfa_assert(fcport->cfg.rx_bbcredit);
+	bfa_assert(fcport->speed_sup);
 }
 
 static void
-bfa_pport_detach(struct bfa_s *bfa)
+bfa_fcport_detach(struct bfa_s *bfa)
 {
 }
 
@@ -730,95 +939,97 @@ bfa_pport_detach(struct bfa_s *bfa)
  * Called when IOC is ready.
  */
 static void
-bfa_pport_start(struct bfa_s *bfa)
+bfa_fcport_start(struct bfa_s *bfa)
 {
-	bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_START);
+	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START);
 }
 
 /**
  * Called before IOC is stopped.
  */
 static void
-bfa_pport_stop(struct bfa_s *bfa)
+bfa_fcport_stop(struct bfa_s *bfa)
 {
-	bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_STOP);
+	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_STOP);
 }
 
 /**
  * Called when IOC failure is detected.
  */
 static void
-bfa_pport_iocdisable(struct bfa_s *bfa)
+bfa_fcport_iocdisable(struct bfa_s *bfa)
 {
-	bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_HWFAIL);
+	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_HWFAIL);
 }
 
 static void
-bfa_pport_update_linkinfo(struct bfa_pport_s *pport)
+bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
 {
-	struct bfi_pport_event_s *pevent = pport->event_arg.i2hmsg.event;
+	struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
 
-	pport->speed = pevent->link_state.speed;
-	pport->topology = pevent->link_state.topology;
+	fcport->speed = pevent->link_state.speed;
+	fcport->topology = pevent->link_state.topology;
 
-	if (pport->topology == BFA_PPORT_TOPOLOGY_LOOP)
-		pport->myalpa = pevent->link_state.tl.loop_info.myalpa;
+	if (fcport->topology == BFA_PPORT_TOPOLOGY_LOOP)
+		fcport->myalpa =
+			pevent->link_state.tl.loop_info.myalpa;
 
 	/*
 	 * QoS Details
 	 */
-	bfa_os_assign(pport->qos_attr, pevent->link_state.qos_attr);
-	bfa_os_assign(pport->qos_vc_attr, pevent->link_state.qos_vc_attr);
+	bfa_os_assign(fcport->qos_attr, pevent->link_state.qos_attr);
+	bfa_os_assign(fcport->qos_vc_attr, pevent->link_state.qos_vc_attr);
 
-	bfa_trc(pport->bfa, pport->speed);
-	bfa_trc(pport->bfa, pport->topology);
+	bfa_trc(fcport->bfa, fcport->speed);
+	bfa_trc(fcport->bfa, fcport->topology);
 }
 
 static void
-bfa_pport_reset_linkinfo(struct bfa_pport_s *pport)
+bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport)
 {
-	pport->speed = BFA_PPORT_SPEED_UNKNOWN;
-	pport->topology = BFA_PPORT_TOPOLOGY_NONE;
+	fcport->speed = BFA_PPORT_SPEED_UNKNOWN;
+	fcport->topology = BFA_PPORT_TOPOLOGY_NONE;
 }
 
 /**
  * Send port enable message to firmware.
  */
 static          bfa_boolean_t
-bfa_pport_send_enable(struct bfa_pport_s *port)
+bfa_fcport_send_enable(struct bfa_fcport_s *fcport)
 {
-	struct bfi_pport_enable_req_s *m;
+	struct bfi_fcport_enable_req_s *m;
 
 	/**
 	 * Increment message tag before queue check, so that responses to old
 	 * requests are discarded.
 	 */
-	port->msgtag++;
+	fcport->msgtag++;
 
 	/**
 	 * check for room in queue to send request now
 	 */
-	m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+	m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
 	if (!m) {
-		bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait);
+		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+							&fcport->reqq_wait);
 		return BFA_FALSE;
 	}
 
-	bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_ENABLE_REQ,
-		    bfa_lpuid(port->bfa));
-	m->nwwn = port->nwwn;
-	m->pwwn = port->pwwn;
-	m->port_cfg = port->cfg;
-	m->msgtag = port->msgtag;
-	m->port_cfg.maxfrsize = bfa_os_htons(port->cfg.maxfrsize);
-	bfa_dma_be_addr_set(m->stats_dma_addr, port->stats_pa);
-	bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_lo);
-	bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_hi);
+	bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ,
+				bfa_lpuid(fcport->bfa));
+	m->nwwn = fcport->nwwn;
+	m->pwwn = fcport->pwwn;
+	m->port_cfg = fcport->cfg;
+	m->msgtag = fcport->msgtag;
+	m->port_cfg.maxfrsize = bfa_os_htons(fcport->cfg.maxfrsize);
+	bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa);
+	bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo);
+	bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi);
 
 	/**
 	 * queue I/O message to firmware
 	 */
-	bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
+	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
 	return BFA_TRUE;
 }
 
@@ -826,74 +1037,226 @@ bfa_pport_send_enable(struct bfa_pport_s
  * Send port disable message to firmware.
  */
 static          bfa_boolean_t
-bfa_pport_send_disable(struct bfa_pport_s *port)
+bfa_fcport_send_disable(struct bfa_fcport_s *fcport)
 {
-	bfi_pport_disable_req_t *m;
+	struct bfi_fcport_req_s *m;
 
 	/**
 	 * Increment message tag before queue check, so that responses to old
 	 * requests are discarded.
 	 */
-	port->msgtag++;
+	fcport->msgtag++;
 
 	/**
 	 * check for room in queue to send request now
 	 */
-	m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+	m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
 	if (!m) {
-		bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait);
+		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+							&fcport->reqq_wait);
 		return BFA_FALSE;
 	}
 
-	bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_DISABLE_REQ,
-		    bfa_lpuid(port->bfa));
-	m->msgtag = port->msgtag;
+	bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ,
+			bfa_lpuid(fcport->bfa));
+	m->msgtag = fcport->msgtag;
 
 	/**
 	 * queue I/O message to firmware
 	 */
-	bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
+	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
 
 	return BFA_TRUE;
 }
 
 static void
-bfa_pport_set_wwns(struct bfa_pport_s *port)
+bfa_fcport_set_wwns(struct bfa_fcport_s *fcport)
 {
-	port->pwwn = bfa_ioc_get_pwwn(&port->bfa->ioc);
-	port->nwwn = bfa_ioc_get_nwwn(&port->bfa->ioc);
+	fcport->pwwn = bfa_ioc_get_pwwn(&fcport->bfa->ioc);
+	fcport->nwwn = bfa_ioc_get_nwwn(&fcport->bfa->ioc);
 
-	bfa_trc(port->bfa, port->pwwn);
-	bfa_trc(port->bfa, port->nwwn);
+	bfa_trc(fcport->bfa, fcport->pwwn);
+	bfa_trc(fcport->bfa, fcport->nwwn);
 }
 
 static void
-bfa_port_send_txcredit(void *port_cbarg)
+bfa_fcport_send_txcredit(void *port_cbarg)
 {
 
-	struct bfa_pport_s *port = port_cbarg;
-	struct bfi_pport_set_svc_params_req_s *m;
+	struct bfa_fcport_s *fcport = port_cbarg;
+	struct bfi_fcport_set_svc_params_req_s *m;
 
 	/**
 	 * check for room in queue to send request now
 	 */
-	m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+	m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
 	if (!m) {
-		bfa_trc(port->bfa, port->cfg.tx_bbcredit);
+		bfa_trc(fcport->bfa, fcport->cfg.tx_bbcredit);
 		return;
 	}
 
-	bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_SET_SVC_PARAMS_REQ,
-		    bfa_lpuid(port->bfa));
-	m->tx_bbcredit = bfa_os_htons((u16) port->cfg.tx_bbcredit);
+	bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ,
+			bfa_lpuid(fcport->bfa));
+	m->tx_bbcredit = bfa_os_htons((u16) fcport->cfg.tx_bbcredit);
 
 	/**
 	 * queue I/O message to firmware
 	 */
-	bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
+	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
+}
+
+static void
+bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d,
+	struct bfa_qos_stats_s *s)
+{
+	u32     *dip = (u32 *) d;
+	u32     *sip = (u32 *) s;
+	int             i;
+
+	/* Now swap the 32 bit fields */
+	for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i)
+		dip[i] = bfa_os_ntohl(sip[i]);
+}
+
+static void
+bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d,
+	struct bfa_fcoe_stats_s *s)
+{
+	u32     *dip = (u32 *) d;
+	u32     *sip = (u32 *) s;
+	int             i;
+
+	for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32));
+		i = i + 2) {
+#ifdef __BIGENDIAN
+		dip[i] = bfa_os_ntohl(sip[i]);
+		dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
+#else
+		dip[i] = bfa_os_ntohl(sip[i + 1]);
+		dip[i + 1] = bfa_os_ntohl(sip[i]);
+#endif
+	}
+}
+
+static void
+__bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
+{
+	struct bfa_fcport_s *fcport = cbarg;
+
+	if (complete) {
+		if (fcport->stats_status == BFA_STATUS_OK) {
+
+			/* Swap FC QoS or FCoE stats */
+			if (bfa_ioc_get_fcmode(&fcport->bfa->ioc))
+				bfa_fcport_qos_stats_swap(
+					&fcport->stats_ret->fcqos,
+					&fcport->stats->fcqos);
+			else
+				bfa_fcport_fcoe_stats_swap(
+					&fcport->stats_ret->fcoe,
+					&fcport->stats->fcoe);
+		}
+		fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
+	} else {
+		fcport->stats_busy = BFA_FALSE;
+		fcport->stats_status = BFA_STATUS_OK;
+	}
 }
 
+static void
+bfa_fcport_stats_get_timeout(void *cbarg)
+{
+	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
 
+	bfa_trc(fcport->bfa, fcport->stats_qfull);
+
+	if (fcport->stats_qfull) {
+		bfa_reqq_wcancel(&fcport->stats_reqq_wait);
+		fcport->stats_qfull = BFA_FALSE;
+	}
+
+	fcport->stats_status = BFA_STATUS_ETIMER;
+	bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_get,
+		fcport);
+}
+
+static void
+bfa_fcport_send_stats_get(void *cbarg)
+{
+	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
+	struct bfi_fcport_req_s *msg;
+
+	msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
+
+	if (!msg) {
+		fcport->stats_qfull = BFA_TRUE;
+		bfa_reqq_winit(&fcport->stats_reqq_wait,
+				bfa_fcport_send_stats_get, fcport);
+		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+				&fcport->stats_reqq_wait);
+		return;
+	}
+	fcport->stats_qfull = BFA_FALSE;
+
+	bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
+	bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ,
+		bfa_lpuid(fcport->bfa));
+	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
+}
+
+static void
+__bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
+{
+	struct bfa_fcport_s *fcport = cbarg;
+
+	if (complete) {
+		fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
+	} else {
+		fcport->stats_busy = BFA_FALSE;
+		fcport->stats_status = BFA_STATUS_OK;
+	}
+}
+
+static void
+bfa_fcport_stats_clr_timeout(void *cbarg)
+{
+	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
+
+	bfa_trc(fcport->bfa, fcport->stats_qfull);
+
+	if (fcport->stats_qfull) {
+		bfa_reqq_wcancel(&fcport->stats_reqq_wait);
+		fcport->stats_qfull = BFA_FALSE;
+	}
+
+	fcport->stats_status = BFA_STATUS_ETIMER;
+	bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
+			__bfa_cb_fcport_stats_clr, fcport);
+}
+
+static void
+bfa_fcport_send_stats_clear(void *cbarg)
+{
+	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
+	struct bfi_fcport_req_s *msg;
+
+	msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
+
+	if (!msg) {
+		fcport->stats_qfull = BFA_TRUE;
+		bfa_reqq_winit(&fcport->stats_reqq_wait,
+				bfa_fcport_send_stats_clear, fcport);
+		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+				&fcport->stats_reqq_wait);
+		return;
+	}
+	fcport->stats_qfull = BFA_FALSE;
+
+	bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
+	bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ,
+			bfa_lpuid(fcport->bfa));
+	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
+}
 
 /**
  *  bfa_pport_public
@@ -903,32 +1266,32 @@ bfa_port_send_txcredit(void *port_cbarg)
  * Firmware message handler.
  */
 void
-bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
+bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
-	union bfi_pport_i2h_msg_u i2hmsg;
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+	union bfi_fcport_i2h_msg_u i2hmsg;
 
 	i2hmsg.msg = msg;
-	pport->event_arg.i2hmsg = i2hmsg;
+	fcport->event_arg.i2hmsg = i2hmsg;
 
 	switch (msg->mhdr.msg_id) {
-	case BFI_PPORT_I2H_ENABLE_RSP:
-		if (pport->msgtag == i2hmsg.enable_rsp->msgtag)
-			bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP);
+	case BFI_FCPORT_I2H_ENABLE_RSP:
+		if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
+			bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
 		break;
 
-	case BFI_PPORT_I2H_DISABLE_RSP:
-		if (pport->msgtag == i2hmsg.enable_rsp->msgtag)
-			bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP);
+	case BFI_FCPORT_I2H_DISABLE_RSP:
+		if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
+			bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
 		break;
 
-	case BFI_PPORT_I2H_EVENT:
+	case BFI_FCPORT_I2H_EVENT:
 		switch (i2hmsg.event->link_state.linkstate) {
 		case BFA_PPORT_LINKUP:
-			bfa_sm_send_event(pport, BFA_PPORT_SM_LINKUP);
+			bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP);
 			break;
 		case BFA_PPORT_LINKDOWN:
-			bfa_sm_send_event(pport, BFA_PPORT_SM_LINKDOWN);
+			bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN);
 			break;
 		case BFA_PPORT_TRUNK_LINKDOWN:
 			/** todo: event notification */
@@ -936,42 +1299,40 @@ bfa_pport_isr(struct bfa_s *bfa, struct
 		}
 		break;
 
-	case BFI_PPORT_I2H_GET_STATS_RSP:
-	case BFI_PPORT_I2H_GET_QOS_STATS_RSP:
+	case BFI_FCPORT_I2H_STATS_GET_RSP:
 		/*
 		 * check for timer pop before processing the rsp
 		 */
-		if (pport->stats_busy == BFA_FALSE
-		    || pport->stats_status == BFA_STATUS_ETIMER)
+		if (fcport->stats_busy == BFA_FALSE ||
+			fcport->stats_status == BFA_STATUS_ETIMER)
 			break;
 
-		bfa_timer_stop(&pport->timer);
-		pport->stats_status = i2hmsg.getstats_rsp->status;
-		bfa_cb_queue(pport->bfa, &pport->hcb_qe, __bfa_cb_port_stats,
-			     pport);
+		bfa_timer_stop(&fcport->timer);
+		fcport->stats_status = i2hmsg.pstatsget_rsp->status;
+		bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
+				__bfa_cb_fcport_stats_get, fcport);
 		break;
-	case BFI_PPORT_I2H_CLEAR_STATS_RSP:
-	case BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP:
+
+	case BFI_FCPORT_I2H_STATS_CLEAR_RSP:
 		/*
 		 * check for timer pop before processing the rsp
 		 */
-		if (pport->stats_busy == BFA_FALSE
-		    || pport->stats_status == BFA_STATUS_ETIMER)
+		if (fcport->stats_busy == BFA_FALSE ||
+			fcport->stats_status == BFA_STATUS_ETIMER)
 			break;
 
-		bfa_timer_stop(&pport->timer);
-		pport->stats_status = BFA_STATUS_OK;
-		bfa_cb_queue(pport->bfa, &pport->hcb_qe,
-			     __bfa_cb_port_stats_clr, pport);
+		bfa_timer_stop(&fcport->timer);
+		fcport->stats_status = BFA_STATUS_OK;
+		bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
+				__bfa_cb_fcport_stats_clr, fcport);
 		break;
 
 	default:
 		bfa_assert(0);
+	break;
 	}
 }
 
-
-
 /**
  *  bfa_pport_api
  */
@@ -980,35 +1341,35 @@ bfa_pport_isr(struct bfa_s *bfa, struct
  * Registered callback for port events.
  */
 void
-bfa_pport_event_register(struct bfa_s *bfa,
+bfa_fcport_event_register(struct bfa_s *bfa,
 			 void (*cbfn) (void *cbarg, bfa_pport_event_t event),
 			 void *cbarg)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	pport->event_cbfn = cbfn;
-	pport->event_cbarg = cbarg;
+	fcport->event_cbfn = cbfn;
+	fcport->event_cbarg = cbarg;
 }
 
 bfa_status_t
-bfa_pport_enable(struct bfa_s *bfa)
+bfa_fcport_enable(struct bfa_s *bfa)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	if (pport->diag_busy)
+	if (fcport->diag_busy)
 		return BFA_STATUS_DIAG_BUSY;
 	else if (bfa_sm_cmp_state
-		 (BFA_PORT_MOD(bfa), bfa_pport_sm_disabling_qwait))
+		 (BFA_FCPORT_MOD(bfa), bfa_fcport_sm_disabling_qwait))
 		return BFA_STATUS_DEVBUSY;
 
-	bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_ENABLE);
+	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE);
 	return BFA_STATUS_OK;
 }
 
 bfa_status_t
-bfa_pport_disable(struct bfa_s *bfa)
+bfa_fcport_disable(struct bfa_s *bfa)
 {
-	bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_DISABLE);
+	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE);
 	return BFA_STATUS_OK;
 }
 
@@ -1016,18 +1377,18 @@ bfa_pport_disable(struct bfa_s *bfa)
  * Configure port speed.
  */
 bfa_status_t
-bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
+bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
 	bfa_trc(bfa, speed);
 
-	if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > pport->speed_sup)) {
-		bfa_trc(bfa, pport->speed_sup);
+	if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > fcport->speed_sup)) {
+		bfa_trc(bfa, fcport->speed_sup);
 		return BFA_STATUS_UNSUPP_SPEED;
 	}
 
-	pport->cfg.speed = speed;
+	fcport->cfg.speed = speed;
 
 	return BFA_STATUS_OK;
 }
@@ -1036,23 +1397,23 @@ bfa_pport_cfg_speed(struct bfa_s *bfa, e
  * Get current speed.
  */
 enum bfa_pport_speed
-bfa_pport_get_speed(struct bfa_s *bfa)
+bfa_fcport_get_speed(struct bfa_s *bfa)
 {
-	struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	return port->speed;
+	return fcport->speed;
 }
 
 /**
  * Configure port topology.
  */
 bfa_status_t
-bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
+bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
 	bfa_trc(bfa, topology);
-	bfa_trc(bfa, pport->cfg.topology);
+	bfa_trc(bfa, fcport->cfg.topology);
 
 	switch (topology) {
 	case BFA_PPORT_TOPOLOGY_P2P:
@@ -1064,7 +1425,7 @@ bfa_pport_cfg_topology(struct bfa_s *bfa
 		return BFA_STATUS_EINVAL;
 	}
 
-	pport->cfg.topology = topology;
+	fcport->cfg.topology = topology;
 	return BFA_STATUS_OK;
 }
 
@@ -1072,64 +1433,64 @@ bfa_pport_cfg_topology(struct bfa_s *bfa
  * Get current topology.
  */
 enum bfa_pport_topology
-bfa_pport_get_topology(struct bfa_s *bfa)
+bfa_fcport_get_topology(struct bfa_s *bfa)
 {
-	struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	return port->topology;
+	return fcport->topology;
 }
 
 bfa_status_t
-bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
+bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
 	bfa_trc(bfa, alpa);
-	bfa_trc(bfa, pport->cfg.cfg_hardalpa);
-	bfa_trc(bfa, pport->cfg.hardalpa);
+	bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
+	bfa_trc(bfa, fcport->cfg.hardalpa);
 
-	pport->cfg.cfg_hardalpa = BFA_TRUE;
-	pport->cfg.hardalpa = alpa;
+	fcport->cfg.cfg_hardalpa = BFA_TRUE;
+	fcport->cfg.hardalpa = alpa;
 
 	return BFA_STATUS_OK;
 }
 
 bfa_status_t
-bfa_pport_clr_hardalpa(struct bfa_s *bfa)
+bfa_fcport_clr_hardalpa(struct bfa_s *bfa)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	bfa_trc(bfa, pport->cfg.cfg_hardalpa);
-	bfa_trc(bfa, pport->cfg.hardalpa);
+	bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
+	bfa_trc(bfa, fcport->cfg.hardalpa);
 
-	pport->cfg.cfg_hardalpa = BFA_FALSE;
+	fcport->cfg.cfg_hardalpa = BFA_FALSE;
 	return BFA_STATUS_OK;
 }
 
 bfa_boolean_t
-bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
+bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
 {
-	struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	*alpa = port->cfg.hardalpa;
-	return port->cfg.cfg_hardalpa;
+	*alpa = fcport->cfg.hardalpa;
+	return fcport->cfg.cfg_hardalpa;
 }
 
 u8
-bfa_pport_get_myalpa(struct bfa_s *bfa)
+bfa_fcport_get_myalpa(struct bfa_s *bfa)
 {
-	struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	return port->myalpa;
+	return fcport->myalpa;
 }
 
 bfa_status_t
-bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
+bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
 	bfa_trc(bfa, maxfrsize);
-	bfa_trc(bfa, pport->cfg.maxfrsize);
+	bfa_trc(bfa, fcport->cfg.maxfrsize);
 
 	/*
 	 * with in range
@@ -1143,41 +1504,41 @@ bfa_pport_cfg_maxfrsize(struct bfa_s *bf
 	if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1)))
 		return BFA_STATUS_INVLD_DFSZ;
 
-	pport->cfg.maxfrsize = maxfrsize;
+	fcport->cfg.maxfrsize = maxfrsize;
 	return BFA_STATUS_OK;
 }
 
 u16
-bfa_pport_get_maxfrsize(struct bfa_s *bfa)
+bfa_fcport_get_maxfrsize(struct bfa_s *bfa)
 {
-	struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	return port->cfg.maxfrsize;
+	return fcport->cfg.maxfrsize;
 }
 
 u32
-bfa_pport_mypid(struct bfa_s *bfa)
+bfa_fcport_mypid(struct bfa_s *bfa)
 {
-	struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	return port->mypid;
+	return fcport->mypid;
 }
 
 u8
-bfa_pport_get_rx_bbcredit(struct bfa_s *bfa)
+bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa)
 {
-	struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	return port->cfg.rx_bbcredit;
+	return fcport->cfg.rx_bbcredit;
 }
 
 void
-bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
+bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
 {
-	struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	port->cfg.tx_bbcredit = (u8) tx_bbcredit;
-	bfa_port_send_txcredit(port);
+	fcport->cfg.tx_bbcredit = (u8) tx_bbcredit;
+	bfa_fcport_send_txcredit(fcport);
 }
 
 /**
@@ -1185,302 +1546,192 @@ bfa_pport_set_tx_bbcredit(struct bfa_s *
  */
 
 wwn_t
-bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
+bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 	if (node)
-		return pport->nwwn;
+		return fcport->nwwn;
 	else
-		return pport->pwwn;
+		return fcport->pwwn;
 }
 
 void
-bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
+bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
 	bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s));
 
-	attr->nwwn = pport->nwwn;
-	attr->pwwn = pport->pwwn;
+	attr->nwwn = fcport->nwwn;
+	attr->pwwn = fcport->pwwn;
 
-	bfa_os_memcpy(&attr->pport_cfg, &pport->cfg,
+	bfa_os_memcpy(&attr->pport_cfg, &fcport->cfg,
 		      sizeof(struct bfa_pport_cfg_s));
 	/*
 	 * speed attributes
 	 */
-	attr->pport_cfg.speed = pport->cfg.speed;
-	attr->speed_supported = pport->speed_sup;
-	attr->speed = pport->speed;
+	attr->pport_cfg.speed = fcport->cfg.speed;
+	attr->speed_supported = fcport->speed_sup;
+	attr->speed = fcport->speed;
 	attr->cos_supported = FC_CLASS_3;
 
 	/*
 	 * topology attributes
 	 */
-	attr->pport_cfg.topology = pport->cfg.topology;
-	attr->topology = pport->topology;
+	attr->pport_cfg.topology = fcport->cfg.topology;
+	attr->topology = fcport->topology;
 
 	/*
 	 * beacon attributes
 	 */
-	attr->beacon = pport->beacon;
-	attr->link_e2e_beacon = pport->link_e2e_beacon;
-	attr->plog_enabled = bfa_plog_get_setting(pport->bfa->plog);
+	attr->beacon = fcport->beacon;
+	attr->link_e2e_beacon = fcport->link_e2e_beacon;
+	attr->plog_enabled = bfa_plog_get_setting(fcport->bfa->plog);
 
 	attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa);
 	attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa);
-	attr->port_state = bfa_sm_to_state(hal_pport_sm_table, pport->sm);
-	if (bfa_ioc_is_disabled(&pport->bfa->ioc))
+	attr->port_state = bfa_sm_to_state(hal_pport_sm_table, fcport->sm);
+	if (bfa_ioc_is_disabled(&fcport->bfa->ioc))
 		attr->port_state = BFA_PPORT_ST_IOCDIS;
-	else if (bfa_ioc_fw_mismatch(&pport->bfa->ioc))
+	else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
 		attr->port_state = BFA_PPORT_ST_FWMISMATCH;
 }
 
-static void
-bfa_port_stats_query(void *cbarg)
-{
-	struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
-	bfi_pport_get_stats_req_t *msg;
-
-	msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
-
-	if (!msg) {
-		port->stats_qfull = BFA_TRUE;
-		bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_query,
-			       port);
-		bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
-		return;
-	}
-	port->stats_qfull = BFA_FALSE;
-
-	bfa_os_memset(msg, 0, sizeof(bfi_pport_get_stats_req_t));
-	bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_GET_STATS_REQ,
-		    bfa_lpuid(port->bfa));
-	bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
-
-	return;
-}
-
-static void
-bfa_port_stats_clear(void *cbarg)
-{
-	struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
-	bfi_pport_clear_stats_req_t *msg;
-
-	msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
-
-	if (!msg) {
-		port->stats_qfull = BFA_TRUE;
-		bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_clear,
-			       port);
-		bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
-		return;
-	}
-	port->stats_qfull = BFA_FALSE;
-
-	bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_stats_req_t));
-	bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_STATS_REQ,
-		    bfa_lpuid(port->bfa));
-	bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
-	return;
-}
+#define BFA_FCPORT_STATS_TOV	1000
 
-static void
-bfa_port_qos_stats_clear(void *cbarg)
+/**
+ * Fetch port attributes (FCQoS or FCoE).
+ */
+bfa_status_t
+bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
+		    bfa_cb_pport_t cbfn, void *cbarg)
 {
-	struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
-	bfi_pport_clear_qos_stats_req_t *msg;
-
-	msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	if (!msg) {
-		port->stats_qfull = BFA_TRUE;
-		bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_qos_stats_clear,
-			       port);
-		bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
-		return;
+	if (fcport->stats_busy) {
+		bfa_trc(bfa, fcport->stats_busy);
+		return BFA_STATUS_DEVBUSY;
 	}
-	port->stats_qfull = BFA_FALSE;
-
-	bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_qos_stats_req_t));
-	bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ,
-		    bfa_lpuid(port->bfa));
-	bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
-	return;
-}
 
-static void
-bfa_pport_stats_swap(union bfa_pport_stats_u *d, union bfa_pport_stats_u *s)
-{
-	u32       *dip = (u32 *) d;
-	u32       *sip = (u32 *) s;
-	int             i;
+	fcport->stats_busy  = BFA_TRUE;
+	fcport->stats_ret   = stats;
+	fcport->stats_cbfn  = cbfn;
+	fcport->stats_cbarg = cbarg;
 
-	/*
-	 * Do 64 bit fields swap first
-	 */
-	for (i = 0;
-	     i <
-	     ((sizeof(union bfa_pport_stats_u) -
-	       sizeof(struct bfa_qos_stats_s)) / sizeof(u32)); i = i + 2) {
-#ifdef __BIGENDIAN
-		dip[i] = bfa_os_ntohl(sip[i]);
-		dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
-#else
-		dip[i] = bfa_os_ntohl(sip[i + 1]);
-		dip[i + 1] = bfa_os_ntohl(sip[i]);
-#endif
-	}
+	bfa_fcport_send_stats_get(fcport);
 
-	/*
-	 * Now swap the 32 bit fields
-	 */
-	for (; i < (sizeof(union bfa_pport_stats_u) / sizeof(u32)); ++i)
-		dip[i] = bfa_os_ntohl(sip[i]);
+	bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_get_timeout,
+		fcport, BFA_FCPORT_STATS_TOV);
+	return BFA_STATUS_OK;
 }
 
-static void
-__bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete)
+/**
+ * Reset port statistics (FCQoS or FCoE).
+ */
+bfa_status_t
+bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
 {
-	struct bfa_pport_s *port = cbarg;
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	if (complete) {
-		port->stats_cbfn(port->stats_cbarg, port->stats_status);
-	} else {
-		port->stats_busy = BFA_FALSE;
-		port->stats_status = BFA_STATUS_OK;
+	if (fcport->stats_busy) {
+		bfa_trc(bfa, fcport->stats_busy);
+		return BFA_STATUS_DEVBUSY;
 	}
-}
-
-static void
-bfa_port_stats_clr_timeout(void *cbarg)
-{
-	struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
 
-	bfa_trc(port->bfa, port->stats_qfull);
+	fcport->stats_busy = BFA_TRUE;
+	fcport->stats_cbfn = cbfn;
+	fcport->stats_cbarg = cbarg;
 
-	if (port->stats_qfull) {
-		bfa_reqq_wcancel(&port->stats_reqq_wait);
-		port->stats_qfull = BFA_FALSE;
-	}
+	bfa_fcport_send_stats_clear(fcport);
 
-	port->stats_status = BFA_STATUS_ETIMER;
-	bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats_clr, port);
+	bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout,
+			fcport, BFA_FCPORT_STATS_TOV);
+	return BFA_STATUS_OK;
 }
 
-static void
-__bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete)
+/**
+ * Fetch FCQoS port statistics
+ */
+bfa_status_t
+bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
+	bfa_cb_pport_t cbfn, void *cbarg)
 {
-	struct bfa_pport_s *port = cbarg;
+	/* Meaningful only for FC mode */
+	bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
 
-	if (complete) {
-		if (port->stats_status == BFA_STATUS_OK)
-			bfa_pport_stats_swap(port->stats_ret, port->stats);
-		port->stats_cbfn(port->stats_cbarg, port->stats_status);
-	} else {
-		port->stats_busy = BFA_FALSE;
-		port->stats_status = BFA_STATUS_OK;
-	}
+	return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
 }
 
-static void
-bfa_port_stats_timeout(void *cbarg)
+/**
+ * Reset FCoE port statistics
+ */
+bfa_status_t
+bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
 {
-	struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
-
-	bfa_trc(port->bfa, port->stats_qfull);
-
-	if (port->stats_qfull) {
-		bfa_reqq_wcancel(&port->stats_reqq_wait);
-		port->stats_qfull = BFA_FALSE;
-	}
+	/* Meaningful only for FC mode */
+	bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
 
-	port->stats_status = BFA_STATUS_ETIMER;
-	bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats, port);
+	return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
 }
 
-#define BFA_PORT_STATS_TOV	1000
-
 /**
- * Fetch port attributes.
+ * Fetch FCQoS port statistics
  */
 bfa_status_t
-bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats,
-		    bfa_cb_pport_t cbfn, void *cbarg)
+bfa_fcport_get_fcoe_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
+	bfa_cb_pport_t cbfn, void *cbarg)
 {
-	struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
-
-	if (port->stats_busy) {
-		bfa_trc(bfa, port->stats_busy);
-		return BFA_STATUS_DEVBUSY;
-	}
-
-	port->stats_busy = BFA_TRUE;
-	port->stats_ret = stats;
-	port->stats_cbfn = cbfn;
-	port->stats_cbarg = cbarg;
-
-	bfa_port_stats_query(port);
+	/* Meaningful only for FCoE mode */
+	bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
 
-	bfa_timer_start(bfa, &port->timer, bfa_port_stats_timeout, port,
-			BFA_PORT_STATS_TOV);
-	return BFA_STATUS_OK;
+	return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
 }
 
+/**
+ * Reset FCoE port statistics
+ */
 bfa_status_t
-bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
+bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
 {
-	struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
-
-	if (port->stats_busy) {
-		bfa_trc(bfa, port->stats_busy);
-		return BFA_STATUS_DEVBUSY;
-	}
-
-	port->stats_busy = BFA_TRUE;
-	port->stats_cbfn = cbfn;
-	port->stats_cbarg = cbarg;
-
-	bfa_port_stats_clear(port);
+	/* Meaningful only for FCoE mode */
+	bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
 
-	bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
-			BFA_PORT_STATS_TOV);
-	return BFA_STATUS_OK;
+	return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
 }
 
 bfa_status_t
-bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap)
+bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
 	bfa_trc(bfa, bitmap);
-	bfa_trc(bfa, pport->cfg.trunked);
-	bfa_trc(bfa, pport->cfg.trunk_ports);
+	bfa_trc(bfa, fcport->cfg.trunked);
+	bfa_trc(bfa, fcport->cfg.trunk_ports);
 
 	if (!bitmap || (bitmap & (bitmap - 1)))
 		return BFA_STATUS_EINVAL;
 
-	pport->cfg.trunked = BFA_TRUE;
-	pport->cfg.trunk_ports = bitmap;
+	fcport->cfg.trunked = BFA_TRUE;
+	fcport->cfg.trunk_ports = bitmap;
 
 	return BFA_STATUS_OK;
 }
 
 void
-bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
+bfa_fcport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	qos_attr->state = bfa_os_ntohl(pport->qos_attr.state);
-	qos_attr->total_bb_cr = bfa_os_ntohl(pport->qos_attr.total_bb_cr);
+	qos_attr->state = bfa_os_ntohl(fcport->qos_attr.state);
+	qos_attr->total_bb_cr = bfa_os_ntohl(fcport->qos_attr.total_bb_cr);
 }
 
 void
-bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
+bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
 			  struct bfa_qos_vc_attr_s *qos_vc_attr)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
-	struct bfa_qos_vc_attr_s *bfa_vc_attr = &pport->qos_vc_attr;
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+	struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr;
 	u32        i = 0;
 
 	qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count);
@@ -1503,119 +1754,89 @@ bfa_pport_qos_get_vc_attr(struct bfa_s *
 }
 
 /**
- * Fetch QoS Stats.
- */
-bfa_status_t
-bfa_pport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats,
-			bfa_cb_pport_t cbfn, void *cbarg)
-{
-	/*
-	 * QoS stats is embedded in port stats
-	 */
-	return bfa_pport_get_stats(bfa, stats, cbfn, cbarg);
-}
-
-bfa_status_t
-bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
-{
-	struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
-
-	if (port->stats_busy) {
-		bfa_trc(bfa, port->stats_busy);
-		return BFA_STATUS_DEVBUSY;
-	}
-
-	port->stats_busy = BFA_TRUE;
-	port->stats_cbfn = cbfn;
-	port->stats_cbarg = cbarg;
-
-	bfa_port_qos_stats_clear(port);
-
-	bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
-			BFA_PORT_STATS_TOV);
-	return BFA_STATUS_OK;
-}
-
-/**
  * Fetch port attributes.
  */
 bfa_status_t
-bfa_pport_trunk_disable(struct bfa_s *bfa)
+bfa_fcport_trunk_disable(struct bfa_s *bfa)
 {
 	return BFA_STATUS_OK;
 }
 
 bfa_boolean_t
-bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap)
+bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap)
 {
-	struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	*bitmap = port->cfg.trunk_ports;
-	return port->cfg.trunked;
+	*bitmap = fcport->cfg.trunk_ports;
+	return fcport->cfg.trunked;
 }
 
 bfa_boolean_t
-bfa_pport_is_disabled(struct bfa_s *bfa)
+bfa_fcport_is_disabled(struct bfa_s *bfa)
 {
-	struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	return bfa_sm_to_state(hal_pport_sm_table, port->sm) ==
+	return bfa_sm_to_state(hal_pport_sm_table, fcport->sm) ==
 		BFA_PPORT_ST_DISABLED;
 
 }
 
 bfa_boolean_t
-bfa_pport_is_ratelim(struct bfa_s *bfa)
+bfa_fcport_is_ratelim(struct bfa_s *bfa)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	return pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
+	return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
 
 }
 
 void
-bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
+bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+	enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa);
 
 	bfa_trc(bfa, on_off);
-	bfa_trc(bfa, pport->cfg.qos_enabled);
+	bfa_trc(bfa, fcport->cfg.qos_enabled);
 
-	pport->cfg.qos_enabled = on_off;
+	bfa_trc(bfa, ioc_type);
+
+	if (ioc_type == BFA_IOC_TYPE_FC)
+		fcport->cfg.qos_enabled = on_off;
 }
 
 void
-bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
+bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
 	bfa_trc(bfa, on_off);
-	bfa_trc(bfa, pport->cfg.ratelimit);
+	bfa_trc(bfa, fcport->cfg.ratelimit);
 
-	pport->cfg.ratelimit = on_off;
-	if (pport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN)
-		pport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS;
+	fcport->cfg.ratelimit = on_off;
+	if (fcport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN)
+		fcport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS;
 }
 
 /**
  * Configure default minimum ratelim speed
  */
 bfa_status_t
-bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
+bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
 	bfa_trc(bfa, speed);
 
 	/*
 	 * Auto and speeds greater than the supported speed, are invalid
 	 */
-	if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > pport->speed_sup)) {
-		bfa_trc(bfa, pport->speed_sup);
+	if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > fcport->speed_sup)) {
+		bfa_trc(bfa, fcport->speed_sup);
 		return BFA_STATUS_UNSUPP_SPEED;
 	}
 
-	pport->cfg.trl_def_speed = speed;
+	fcport->cfg.trl_def_speed = speed;
 
 	return BFA_STATUS_OK;
 }
@@ -1624,45 +1845,45 @@ bfa_pport_cfg_ratelim_speed(struct bfa_s
  * Get default minimum ratelim speed
  */
 enum bfa_pport_speed
-bfa_pport_get_ratelim_speed(struct bfa_s *bfa)
+bfa_fcport_get_ratelim_speed(struct bfa_s *bfa)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-	bfa_trc(bfa, pport->cfg.trl_def_speed);
-	return pport->cfg.trl_def_speed;
+	bfa_trc(bfa, fcport->cfg.trl_def_speed);
+	return fcport->cfg.trl_def_speed;
 
 }
 
 void
-bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status)
+bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
 	bfa_trc(bfa, status);
-	bfa_trc(bfa, pport->diag_busy);
+	bfa_trc(bfa, fcport->diag_busy);
 
-	pport->diag_busy = status;
+	fcport->diag_busy = status;
 }
 
 void
-bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
+bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
 		 bfa_boolean_t link_e2e_beacon)
 {
-	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
 	bfa_trc(bfa, beacon);
 	bfa_trc(bfa, link_e2e_beacon);
-	bfa_trc(bfa, pport->beacon);
-	bfa_trc(bfa, pport->link_e2e_beacon);
+	bfa_trc(bfa, fcport->beacon);
+	bfa_trc(bfa, fcport->link_e2e_beacon);
 
-	pport->beacon = beacon;
-	pport->link_e2e_beacon = link_e2e_beacon;
+	fcport->beacon = beacon;
+	fcport->link_e2e_beacon = link_e2e_beacon;
 }
 
 bfa_boolean_t
-bfa_pport_is_linkup(struct bfa_s *bfa)
+bfa_fcport_is_linkup(struct bfa_s *bfa)
 {
-	return bfa_sm_cmp_state(BFA_PORT_MOD(bfa), bfa_pport_sm_linkup);
+	return bfa_sm_cmp_state(BFA_FCPORT_MOD(bfa), bfa_fcport_sm_linkup);
 }
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcs.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_fcs.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_fcs.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
  * FCS sub-modules
  */
 struct bfa_fcs_mod_s {
+	void		(*attach) (struct bfa_fcs_s *fcs);
 	void            (*modinit) (struct bfa_fcs_s *fcs);
 	void            (*modexit) (struct bfa_fcs_s *fcs);
 };
@@ -43,12 +44,10 @@ struct bfa_fcs_mod_s {
 #define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }
 
 static struct bfa_fcs_mod_s fcs_modules[] = {
-	BFA_FCS_MODULE(bfa_fcs_pport),
-	BFA_FCS_MODULE(bfa_fcs_uf),
-	BFA_FCS_MODULE(bfa_fcs_fabric),
-	BFA_FCS_MODULE(bfa_fcs_vport),
-	BFA_FCS_MODULE(bfa_fcs_rport),
-	BFA_FCS_MODULE(bfa_fcs_fcpim),
+	{ bfa_fcs_pport_attach, NULL, NULL },
+	{ bfa_fcs_uf_attach, NULL, NULL },
+	{ bfa_fcs_fabric_attach, bfa_fcs_fabric_modinit,
+	 bfa_fcs_fabric_modexit },
 };
 
 /**
@@ -71,16 +70,10 @@ bfa_fcs_exit_comp(void *fcs_cbarg)
  */
 
 /**
- * 		FCS instance initialization.
- *
- * 	param[in]		fcs		FCS instance
- * 	param[in]		bfa		BFA instance
- * 	param[in]		bfad		BFA driver instance
- *
- * 	return None
+ * fcs attach -- called once to initialize data structures at driver attach time
  */
 void
-bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
+bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
 			bfa_boolean_t min_cfg)
 {
 	int             i;
@@ -95,7 +88,24 @@ bfa_fcs_init(struct bfa_fcs_s *fcs, stru
 
 	for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
 		mod = &fcs_modules[i];
-		mod->modinit(fcs);
+		if (mod->attach)
+			mod->attach(fcs);
+	}
+}
+
+/**
+ * fcs initialization, called once after bfa initialization is complete
+ */
+void
+bfa_fcs_init(struct bfa_fcs_s *fcs)
+{
+	int             i;
+	struct bfa_fcs_mod_s  *mod;
+
+	for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
+		mod = &fcs_modules[i];
+		if (mod->modinit)
+			mod->modinit(fcs);
 	}
 }
 
@@ -127,6 +137,23 @@ bfa_fcs_driver_info_init(struct bfa_fcs_
 }
 
 /**
+ *      @brief
+ *              FCS FDMI Driver Parameter Initialization
+ *
+ *      @param[in]              fcs             FCS instance
+ *      @param[in]              fdmi_enable     TRUE/FALSE
+ *
+ *      @return None
+ */
+void
+bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable)
+{
+
+	fcs->fdmi_enabled = fdmi_enable;
+
+}
+
+/**
  * 		FCS instance cleanup and exit.
  *
  * 	param[in]		fcs			FCS instance
@@ -143,10 +170,12 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs)
 	nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]);
 
 	for (i = 0; i < nmods; i++) {
-		bfa_wc_up(&fcs->wc);
 
 		mod = &fcs_modules[i];
-		mod->modexit(fcs);
+		if (mod->modexit) {
+			bfa_wc_up(&fcs->wc);
+			mod->modexit(fcs);
+		}
 	}
 
 	bfa_wc_wait(&fcs->wc);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcs_lport.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_fcs_lport.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcs_lport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_fcs_lport.c	2010-05-16 17:17:36.000000000 -0400
@@ -114,7 +114,7 @@ bfa_fcs_port_sm_uninit(struct bfa_fcs_po
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
@@ -136,7 +136,7 @@ bfa_fcs_port_sm_init(struct bfa_fcs_port
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
@@ -176,7 +176,7 @@ bfa_fcs_port_sm_online(struct bfa_fcs_po
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
@@ -214,7 +214,7 @@ bfa_fcs_port_sm_offline(struct bfa_fcs_p
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
@@ -234,7 +234,7 @@ bfa_fcs_port_sm_deleting(struct bfa_fcs_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
@@ -263,30 +263,8 @@ bfa_fcs_port_aen_post(struct bfa_fcs_por
 
 	bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
 
-	switch (event) {
-	case BFA_LPORT_AEN_ONLINE:
-		bfa_log(logmod, BFA_AEN_LPORT_ONLINE, lpwwn_ptr,
-			role_str[role / 2]);
-		break;
-	case BFA_LPORT_AEN_OFFLINE:
-		bfa_log(logmod, BFA_AEN_LPORT_OFFLINE, lpwwn_ptr,
-			role_str[role / 2]);
-		break;
-	case BFA_LPORT_AEN_NEW:
-		bfa_log(logmod, BFA_AEN_LPORT_NEW, lpwwn_ptr,
-			role_str[role / 2]);
-		break;
-	case BFA_LPORT_AEN_DELETE:
-		bfa_log(logmod, BFA_AEN_LPORT_DELETE, lpwwn_ptr,
-			role_str[role / 2]);
-		break;
-	case BFA_LPORT_AEN_DISCONNECT:
-		bfa_log(logmod, BFA_AEN_LPORT_DISCONNECT, lpwwn_ptr,
-			role_str[role / 2]);
-		break;
-	default:
-		break;
-	}
+	bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr,
+		role_str[role/2]);
 
 	aen_data.lport.vf_id = port->fabric->vf_id;
 	aen_data.lport.roles = role;
@@ -873,36 +851,46 @@ bfa_fcs_port_is_online(struct bfa_fcs_po
 }
 
 /**
- * Logical port initialization of base or virtual port.
- * Called by fabric for base port or by vport for virtual ports.
+ * Attach time initialization of logical ports.
  */
 void
-bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
-		   u16 vf_id, struct bfa_port_cfg_s *port_cfg,
-		   struct bfa_fcs_vport_s *vport)
+bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
+		uint16_t vf_id, struct bfa_fcs_vport_s *vport)
 {
 	lport->fcs = fcs;
 	lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
-	bfa_os_assign(lport->port_cfg, *port_cfg);
 	lport->vport = vport;
 	lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) :
 			 bfa_lps_get_tag(lport->fabric->lps);
 
 	INIT_LIST_HEAD(&lport->rport_q);
 	lport->num_rports = 0;
+}
 
-	lport->bfad_port =
-		bfa_fcb_port_new(fcs->bfad, lport, lport->port_cfg.roles,
+/**
+ * Logical port initialization of base or virtual port.
+ * Called by fabric for base port or by vport for virtual ports.
+ */
+
+void
+bfa_fcs_lport_init(struct bfa_fcs_port_s *lport,
+		struct bfa_port_cfg_s *port_cfg)
+{
+	struct bfa_fcs_vport_s *vport = lport->vport;
+
+	bfa_os_assign(lport->port_cfg, *port_cfg);
+
+	lport->bfad_port = bfa_fcb_port_new(lport->fcs->bfad, lport,
+				lport->port_cfg.roles,
 				lport->fabric->vf_drv,
 				vport ? vport->vport_drv : NULL);
+
 	bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW);
 
 	bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit);
 	bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
 }
 
-
-
 /**
  *  fcs_lport_api
  */
@@ -921,13 +909,20 @@ bfa_fcs_port_get_attr(struct bfa_fcs_por
 	if (port->fabric) {
 		port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric);
 		port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric);
+		port_attr->authfail =
+				bfa_fcs_fabric_is_auth_failed(port->fabric);
 		port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port);
 		memcpy(port_attr->fabric_ip_addr,
 		       bfa_fcs_port_get_fabric_ipaddr(port),
 		       BFA_FCS_FABRIC_IPADDR_SZ);
 
-		if (port->vport != NULL)
+		if (port->vport != NULL) {
 			port_attr->port_type = BFA_PPORT_TYPE_VPORT;
+			port_attr->fpma_mac =
+				bfa_lps_get_lp_mac(port->vport->lps);
+		} else
+			port_attr->fpma_mac =
+				bfa_lps_get_lp_mac(port->fabric->lps);
 
 	} else {
 		port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcs_port.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_fcs_port.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcs_port.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_fcs_port.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,14 +55,7 @@ bfa_fcs_pport_event_handler(void *cbarg,
 }
 
 void
-bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs)
-{
-	bfa_pport_event_register(fcs->bfa, bfa_fcs_pport_event_handler,
-				     fcs);
-}
-
-void
-bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs)
+bfa_fcs_pport_attach(struct bfa_fcs_s *fcs)
 {
-	bfa_fcs_modexit_comp(fcs);
+	bfa_fcport_event_register(fcs->bfa, bfa_fcs_pport_event_handler, fcs);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcs_uf.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_fcs_uf.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcs_uf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_fcs_uf.c	2010-05-16 17:17:36.000000000 -0400
@@ -93,13 +93,7 @@ bfa_fcs_uf_recv(void *cbarg, struct bfa_
 }
 
 void
-bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs)
+bfa_fcs_uf_attach(struct bfa_fcs_s *fcs)
 {
 	bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs);
 }
-
-void
-bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs)
-{
-	bfa_fcs_modexit_comp(fcs);
-}
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_hw_cb.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_hw_cb.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_hw_cb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_hw_cb.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,6 +53,18 @@ bfa_hwcb_reginit(struct bfa_s *bfa)
 }
 
 void
+bfa_hwcb_reqq_ack(struct bfa_s *bfa, int reqq)
+{
+}
+
+static void
+bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq)
+{
+	bfa_reg_write(bfa->iocfc.bfa_regs.intr_status,
+		__HFN_INT_CPE_Q0 << CPE_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), reqq));
+}
+
+void
 bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq)
 {
 }
@@ -136,6 +148,7 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bf
 void
 bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
 {
+	bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix;
 	bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_hw_ct.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_hw_ct.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_hw_ct.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_hw_ct.c	2010-05-16 17:17:36.000000000 -0400
@@ -85,6 +85,15 @@ bfa_hwct_reginit(struct bfa_s *bfa)
 }
 
 void
+bfa_hwct_reqq_ack(struct bfa_s *bfa, int reqq)
+{
+	u32 r32;
+
+	r32 = bfa_reg_read(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]);
+	bfa_reg_write(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq], r32);
+}
+
+void
 bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq)
 {
 	u32	r32;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_intr.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_intr.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_intr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_intr.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,7 @@
  * General Public License for more details.
  */
 #include <bfa.h>
-#include <bfi/bfi_cbreg.h>
+#include <bfi/bfi_ctreg.h>
 #include <bfa_port_priv.h>
 #include <bfa_intr_priv.h>
 #include <cs/bfa_debug.h>
@@ -34,6 +34,26 @@ bfa_msix_lpu(struct bfa_s *bfa)
 	bfa_ioc_mbox_isr(&bfa->ioc);
 }
 
+static void
+bfa_reqq_resume(struct bfa_s *bfa, int qid)
+{
+	struct list_head *waitq, *qe, *qen;
+	struct bfa_reqq_wait_s *wqe;
+
+	waitq = bfa_reqq(bfa, qid);
+	list_for_each_safe(qe, qen, waitq) {
+		/**
+		 * Callback only as long as there is room in request queue
+		 */
+		if (bfa_reqq_full(bfa, qid))
+			break;
+
+		list_del(qe);
+		wqe = (struct bfa_reqq_wait_s *) qe;
+		wqe->qresume(wqe->cbarg);
+	}
+}
+
 void
 bfa_msix_all(struct bfa_s *bfa, int vec)
 {
@@ -96,7 +116,8 @@ bfa_isr_enable(struct bfa_s *bfa)
 
 	bfa_msix_install(bfa);
 	intr_unmask = (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
-		       __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS);
+		       __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS |
+		       __HFN_INT_LL_HALT);
 
 	if (pci_func == 0)
 		intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 |
@@ -127,23 +148,18 @@ bfa_isr_disable(struct bfa_s *bfa)
 void
 bfa_msix_reqq(struct bfa_s *bfa, int qid)
 {
-	struct list_head 		*waitq, *qe, *qen;
-	struct bfa_reqq_wait_s	*wqe;
+	struct list_head *waitq;
 
 	qid &= (BFI_IOC_MAX_CQS - 1);
 
-	waitq = bfa_reqq(bfa, qid);
-	list_for_each_safe(qe, qen, waitq) {
-		/**
-		 * Callback only as long as there is room in request queue
-		 */
-		if (bfa_reqq_full(bfa, qid))
-			break;
+	bfa->iocfc.hwif.hw_reqq_ack(bfa, qid);
 
-		list_del(qe);
-		wqe = (struct bfa_reqq_wait_s *) qe;
-		wqe->qresume(wqe->cbarg);
-	}
+	/**
+	 * Resume any pending requests in the corresponding reqq.
+	 */
+	waitq = bfa_reqq(bfa, qid);
+	if (!list_empty(waitq))
+		bfa_reqq_resume(bfa, qid);
 }
 
 void
@@ -157,26 +173,27 @@ bfa_isr_unhandled(struct bfa_s *bfa, str
 }
 
 void
-bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid)
+bfa_msix_rspq(struct bfa_s *bfa, int qid)
 {
-	struct bfi_msg_s      *m;
-	u32        pi, ci;
+	struct bfi_msg_s *m;
+	u32 pi, ci;
+	struct list_head *waitq;
 
-	bfa_trc_fp(bfa, rsp_qid);
+	bfa_trc_fp(bfa, qid);
 
-	rsp_qid &= (BFI_IOC_MAX_CQS - 1);
+	qid &= (BFI_IOC_MAX_CQS - 1);
 
-	bfa->iocfc.hwif.hw_rspq_ack(bfa, rsp_qid);
+	bfa->iocfc.hwif.hw_rspq_ack(bfa, qid);
 
-	ci = bfa_rspq_ci(bfa, rsp_qid);
-	pi = bfa_rspq_pi(bfa, rsp_qid);
+	ci = bfa_rspq_ci(bfa, qid);
+	pi = bfa_rspq_pi(bfa, qid);
 
 	bfa_trc_fp(bfa, ci);
 	bfa_trc_fp(bfa, pi);
 
 	if (bfa->rme_process) {
 		while (ci != pi) {
-			m = bfa_rspq_elem(bfa, rsp_qid, ci);
+			m = bfa_rspq_elem(bfa, qid, ci);
 			bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX);
 
 			bfa_isrs[m->mhdr.msg_class] (bfa, m);
@@ -188,25 +205,59 @@ bfa_msix_rspq(struct bfa_s *bfa, int rsp
 	/**
 	 * update CI
 	 */
-	bfa_rspq_ci(bfa, rsp_qid) = pi;
-	bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[rsp_qid], pi);
+	bfa_rspq_ci(bfa, qid) = pi;
+	bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[qid], pi);
 	bfa_os_mmiowb();
+
+	/**
+	 * Resume any pending requests in the corresponding reqq.
+	 */
+	waitq = bfa_reqq(bfa, qid);
+	if (!list_empty(waitq))
+		bfa_reqq_resume(bfa, qid);
 }
 
 void
 bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
 {
-	u32 intr;
+	u32 intr, curr_value;
 
 	intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status);
 
 	if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1))
 		bfa_msix_lpu(bfa);
 
-	if (intr & (__HFN_INT_ERR_EMC |
-		    __HFN_INT_ERR_LPU0 | __HFN_INT_ERR_LPU1 |
-		    __HFN_INT_ERR_PSS))
+	intr &= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
+		__HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT);
+
+	if (intr) {
+		if (intr & __HFN_INT_LL_HALT) {
+			/**
+			 * If LL_HALT bit is set then FW Init Halt LL Port
+			 * Register needs to be cleared as well so Interrupt
+			 * Status Register will be cleared.
+			 */
+			curr_value = bfa_reg_read(bfa->ioc.ioc_regs.ll_halt);
+			curr_value &= ~__FW_INIT_HALT_P;
+			bfa_reg_write(bfa->ioc.ioc_regs.ll_halt, curr_value);
+		}
+
+		if (intr & __HFN_INT_ERR_PSS) {
+			/**
+			 * ERR_PSS bit needs to be cleared as well in case
+			 * interrups are shared so driver's interrupt handler is
+			 * still called eventhough it is already masked out.
+			 */
+			curr_value = bfa_reg_read(
+				bfa->ioc.ioc_regs.pss_err_status_reg);
+			curr_value &= __PSS_ERR_STATUS_SET;
+			bfa_reg_write(bfa->ioc.ioc_regs.pss_err_status_reg,
+				curr_value);
+		}
+
+		bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr);
 		bfa_msix_errint(bfa, intr);
+	}
 }
 
 void
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioc.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_ioc.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_ioc.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,7 @@
 #include <bfa.h>
 #include <bfa_ioc.h>
 #include <bfa_fwimg_priv.h>
-#include <bfa_trcmod_priv.h>
+#include <cna/bfa_cna_trcmod.h>
 #include <cs/bfa_debug.h>
 #include <bfi/bfi_ioc.h>
 #include <bfi/bfi_ctreg.h>
@@ -27,18 +27,17 @@
 #include <log/bfa_log_hal.h>
 #include <defs/bfa_defs_pci.h>
 
-BFA_TRC_FILE(HAL, IOC);
+BFA_TRC_FILE(CNA, IOC);
 
 /**
  * IOC local definitions
  */
 #define BFA_IOC_TOV		2000	/* msecs */
-#define BFA_IOC_HB_TOV		1000	/* msecs */
-#define BFA_IOC_HB_FAIL_MAX	4
-#define BFA_IOC_HWINIT_MAX	2
+#define BFA_IOC_HWSEM_TOV       500     /* msecs */
+#define BFA_IOC_HB_TOV          500     /* msecs */
+#define BFA_IOC_HWINIT_MAX      2
 #define BFA_IOC_FWIMG_MINSZ     (16 * 1024)
-#define BFA_IOC_TOV_RECOVER	(BFA_IOC_HB_FAIL_MAX * BFA_IOC_HB_TOV \
-				+ BFA_IOC_TOV)
+#define BFA_IOC_TOV_RECOVER      BFA_IOC_HB_TOV
 
 #define bfa_ioc_timer_start(__ioc)					\
 	bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer,	\
@@ -51,12 +50,25 @@ BFA_TRC_FILE(HAL, IOC);
 	 (sizeof(struct bfa_trc_mod_s) -			\
 	  BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
 #define BFA_DBG_FWTRC_OFF(_fn)	(BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
-#define bfa_ioc_stats(_ioc, _stats)	((_ioc)->stats._stats++)
 
-#define BFA_FLASH_CHUNK_NO(off)         (off / BFI_FLASH_CHUNK_SZ_WORDS)
-#define BFA_FLASH_OFFSET_IN_CHUNK(off)  (off % BFI_FLASH_CHUNK_SZ_WORDS)
-#define BFA_FLASH_CHUNK_ADDR(chunkno)   (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
-bfa_boolean_t   bfa_auto_recover = BFA_FALSE;
+/**
+ * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details.
+ */
+
+#define bfa_ioc_firmware_lock(__ioc)                    \
+			((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc))
+#define bfa_ioc_firmware_unlock(__ioc)                  \
+			((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc))
+#define bfa_ioc_fwimg_get_chunk(__ioc, __off)           \
+			((__ioc)->ioc_hwif->ioc_fwimg_get_chunk(__ioc, __off))
+#define bfa_ioc_fwimg_get_size(__ioc)                   \
+			((__ioc)->ioc_hwif->ioc_fwimg_get_size(__ioc))
+#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc))
+#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
+#define bfa_ioc_notify_hbfail(__ioc)                    \
+			((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc))
+
+bfa_boolean_t   bfa_auto_recover = BFA_TRUE;
 
 /*
  * forward declarations
@@ -64,7 +76,6 @@ bfa_boolean_t   bfa_auto_recover = BFA_F
 static void     bfa_ioc_aen_post(struct bfa_ioc_s *bfa,
 				 enum bfa_ioc_aen_event event);
 static void     bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
-static void     bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
 static void     bfa_ioc_timeout(void *ioc);
@@ -77,8 +88,6 @@ static void     bfa_ioc_reset(struct bfa
 static void     bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_recover(struct bfa_ioc_s *ioc);
-static bfa_boolean_t bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc);
-static void     bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
 
@@ -508,14 +517,19 @@ bfa_ioc_sm_disabling(struct bfa_ioc_s *i
 	bfa_trc(ioc, event);
 
 	switch (event) {
-	case IOC_E_HWERROR:
 	case IOC_E_FWRSP_DISABLE:
 		bfa_ioc_timer_stop(ioc);
+		bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+		break;
+
+	case IOC_E_HWERROR:
+		bfa_ioc_timer_stop(ioc);
 		/*
 		 * !!! fall through !!!
 		 */
 
 	case IOC_E_TIMEOUT:
+		bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL);
 		bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
 		break;
 
@@ -608,15 +622,12 @@ bfa_ioc_sm_hbfail_entry(struct bfa_ioc_s
 	 * Mark IOC as failed in hardware and stop firmware.
 	 */
 	bfa_ioc_lpu_stop(ioc);
-	bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_HBFAIL);
+	bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL);
 
-	if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
-		bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
-		/*
-		 * Wait for halt to take effect
-		 */
-		bfa_reg_read(ioc->ioc_regs.ll_halt);
-	}
+	/**
+	 * Notify other functions on HB failure.
+	 */
+	bfa_ioc_notify_hbfail(ioc);
 
 	/**
 	 * Notify driver and common modules registered for notification.
@@ -672,6 +683,12 @@ bfa_ioc_sm_hbfail(struct bfa_ioc_s *ioc,
 		 */
 		break;
 
+	case IOC_E_HWERROR:
+		/*
+		 * HB failure notification, ignore.
+		 */
+		break;
+
 	default:
 		bfa_sm_fault(ioc, event);
 	}
@@ -700,7 +717,7 @@ bfa_ioc_disable_comp(struct bfa_ioc_s *i
 	}
 }
 
-static void
+void
 bfa_ioc_sem_timeout(void *ioc_arg)
 {
 	struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg;
@@ -708,26 +725,32 @@ bfa_ioc_sem_timeout(void *ioc_arg)
 	bfa_ioc_hw_sem_get(ioc);
 }
 
-static void
-bfa_ioc_usage_sem_get(struct bfa_ioc_s *ioc)
+bfa_boolean_t
+bfa_ioc_sem_get(bfa_os_addr_t sem_reg)
 {
-	u32        r32;
-	int             cnt = 0;
-#define BFA_SEM_SPINCNT	1000
+	u32 r32;
+	int cnt = 0;
+#define BFA_SEM_SPINCNT 3000
 
-	do {
-		r32 = bfa_reg_read(ioc->ioc_regs.ioc_usage_sem_reg);
+	r32 = bfa_reg_read(sem_reg);
+
+	while (r32 && (cnt < BFA_SEM_SPINCNT)) {
 		cnt++;
-		if (cnt > BFA_SEM_SPINCNT)
-			break;
-	} while (r32 != 0);
+		bfa_os_udelay(2);
+		r32 = bfa_reg_read(sem_reg);
+	}
+
+	if (r32 == 0)
+		return BFA_TRUE;
+
 	bfa_assert(cnt < BFA_SEM_SPINCNT);
+	return BFA_FALSE;
 }
 
-static void
-bfa_ioc_usage_sem_release(struct bfa_ioc_s *ioc)
+void
+bfa_ioc_sem_release(bfa_os_addr_t sem_reg)
 {
-	bfa_reg_write(ioc->ioc_regs.ioc_usage_sem_reg, 1);
+	bfa_reg_write(sem_reg, 1);
 }
 
 static void
@@ -737,7 +760,7 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc
 
 	/**
 	 * First read to the semaphore register will return 0, subsequent reads
-	 * will return 1. Semaphore is released by writing 0 to the register
+	 * will return 1. Semaphore is released by writing 1 to the register
 	 */
 	r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
 	if (r32 == 0) {
@@ -746,10 +769,10 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc
 	}
 
 	bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout,
-			ioc, BFA_IOC_TOV);
+			ioc, BFA_IOC_HWSEM_TOV);
 }
 
-static void
+void
 bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc)
 {
 	bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1);
@@ -828,7 +851,7 @@ bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc)
 /**
  * Get driver and firmware versions.
  */
-static void
+void
 bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
 {
 	u32        pgnum, pgoff;
@@ -847,24 +870,10 @@ bfa_ioc_fwver_get(struct bfa_ioc_s *ioc,
 	}
 }
 
-static u32 *
-bfa_ioc_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
-{
-	if (ioc->ctdev)
-		return bfi_image_ct_get_chunk(off);
-	return bfi_image_cb_get_chunk(off);
-}
-
-static          u32
-bfa_ioc_fwimg_get_size(struct bfa_ioc_s *ioc)
-{
-return (ioc->ctdev) ? bfi_image_ct_size : bfi_image_cb_size;
-}
-
 /**
  * Returns TRUE if same.
  */
-static          bfa_boolean_t
+bfa_boolean_t
 bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
 {
 	struct bfi_ioc_image_hdr_s *drv_fwhdr;
@@ -921,95 +930,6 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *io
 }
 
 /**
- * Return true if firmware of current driver matches the running firmware.
- */
-static          bfa_boolean_t
-bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc)
-{
-	enum bfi_ioc_state ioc_fwstate;
-	u32        usecnt;
-	struct bfi_ioc_image_hdr_s fwhdr;
-
-	/**
-	 * Firmware match check is relevant only for CNA.
-	 */
-	if (!ioc->cna)
-		return BFA_TRUE;
-
-	/**
-	 * If bios boot (flash based) -- do not increment usage count
-	 */
-	if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
-		return BFA_TRUE;
-
-	bfa_ioc_usage_sem_get(ioc);
-	usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
-
-	/**
-	 * If usage count is 0, always return TRUE.
-	 */
-	if (usecnt == 0) {
-		bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
-		bfa_ioc_usage_sem_release(ioc);
-		bfa_trc(ioc, usecnt);
-		return BFA_TRUE;
-	}
-
-	ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
-	bfa_trc(ioc, ioc_fwstate);
-
-	/**
-	 * Use count cannot be non-zero and chip in uninitialized state.
-	 */
-	bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
-
-	/**
-	 * Check if another driver with a different firmware is active
-	 */
-	bfa_ioc_fwver_get(ioc, &fwhdr);
-	if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
-		bfa_ioc_usage_sem_release(ioc);
-		bfa_trc(ioc, usecnt);
-		return BFA_FALSE;
-	}
-
-	/**
-	 * Same firmware version. Increment the reference count.
-	 */
-	usecnt++;
-	bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
-	bfa_ioc_usage_sem_release(ioc);
-	bfa_trc(ioc, usecnt);
-	return BFA_TRUE;
-}
-
-static void
-bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc)
-{
-	u32        usecnt;
-
-	/**
-	 * Firmware lock is relevant only for CNA.
-	 * If bios boot (flash based) -- do not decrement usage count
-	 */
-	if (!ioc->cna || (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ))
-		return;
-
-	/**
-	 * decrement usage count
-	 */
-	bfa_ioc_usage_sem_get(ioc);
-	usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
-	bfa_assert(usecnt > 0);
-
-	usecnt--;
-	bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
-	bfa_trc(ioc, usecnt);
-
-	bfa_ioc_usage_sem_release(ioc);
-}
-
-/**
  * Conditionally flush any pending message from firmware at start.
  */
 static void
@@ -1152,33 +1072,27 @@ bfa_ioc_send_getattr(struct bfa_ioc_s *i
 static void
 bfa_ioc_hb_check(void *cbarg)
 {
-	struct bfa_ioc_s *ioc = cbarg;
-	u32        hb_count;
+	struct bfa_ioc_s  *ioc = cbarg;
+	u32     hb_count;
 
 	hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
 	if (ioc->hb_count == hb_count) {
-		ioc->hb_fail++;
-	} else {
-		ioc->hb_count = hb_count;
-		ioc->hb_fail = 0;
-	}
-
-	if (ioc->hb_fail >= BFA_IOC_HB_FAIL_MAX) {
-		bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE, hb_count);
-		ioc->hb_fail = 0;
+		bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE,
+			hb_count);
 		bfa_ioc_recover(ioc);
 		return;
+	} else {
+		ioc->hb_count = hb_count;
 	}
 
 	bfa_ioc_mbox_poll(ioc);
-	bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
-			BFA_IOC_HB_TOV);
+	bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check,
+			ioc, BFA_IOC_HB_TOV);
 }
 
 static void
 bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
 {
-	ioc->hb_fail = 0;
 	ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
 	bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
 			BFA_IOC_HB_TOV);
@@ -1191,112 +1105,6 @@ bfa_ioc_hb_stop(struct bfa_ioc_s *ioc)
 }
 
 /**
- * Host to LPU mailbox message addresses
- */
-static struct {
-	u32        hfn_mbox, lpu_mbox, hfn_pgn;
-} iocreg_fnreg[] = {
-	{
-	HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0}, {
-	HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1}, {
-	HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2}, {
-	HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3}
-};
-
-/**
- * Host <-> LPU mailbox command/status registers - port 0
- */
-static struct {
-	u32        hfn, lpu;
-} iocreg_mbcmd_p0[] = {
-	{
-	HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT}, {
-	HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT}, {
-	HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT}, {
-	HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT}
-};
-
-/**
- * Host <-> LPU mailbox command/status registers - port 1
- */
-static struct {
-	u32        hfn, lpu;
-} iocreg_mbcmd_p1[] = {
-	{
-	HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT}, {
-	HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT}, {
-	HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT}, {
-	HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT}
-};
-
-/**
- * Shared IRQ handling in INTX mode
- */
-static struct {
-	u32        isr, msk;
-} iocreg_shirq_next[] = {
-	{
-	HOSTFN1_INT_STATUS, HOSTFN1_INT_MSK}, {
-	HOSTFN2_INT_STATUS, HOSTFN2_INT_MSK}, {
-	HOSTFN3_INT_STATUS, HOSTFN3_INT_MSK}, {
-HOSTFN0_INT_STATUS, HOSTFN0_INT_MSK},};
-
-static void
-bfa_ioc_reg_init(struct bfa_ioc_s *ioc)
-{
-	bfa_os_addr_t   rb;
-	int             pcifn = bfa_ioc_pcifn(ioc);
-
-	rb = bfa_ioc_bar0(ioc);
-
-	ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
-	ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
-	ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
-
-	if (ioc->port_id == 0) {
-		ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
-		ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
-		ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
-		ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
-		ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
-	} else {
-		ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
-		ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
-		ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
-		ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
-		ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
-	}
-
-	/**
-	 * Shared IRQ handling in INTX mode
-	 */
-	ioc->ioc_regs.shirq_isr_next = rb + iocreg_shirq_next[pcifn].isr;
-	ioc->ioc_regs.shirq_msk_next = rb + iocreg_shirq_next[pcifn].msk;
-
-	/*
-	 * PSS control registers
-	 */
-	ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
-	ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
-	ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
-
-	/*
-	 * IOC semaphore registers and serialization
-	 */
-	ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
-	ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
-	ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
-
-	/**
-	 * sram memory access
-	 */
-	ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
-	ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
-	if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT)
-		ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
-}
-
-/**
  *      Initiate a full firmware download.
  */
 static void
@@ -1321,9 +1129,6 @@ bfa_ioc_download_fw(struct bfa_ioc_s *io
 	if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
 		boot_type = BFI_BOOT_TYPE_FLASH;
 	fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno);
-	fwimg[BFI_BOOT_TYPE_OFF / sizeof(u32)] = bfa_os_swap32(boot_type);
-	fwimg[BFI_BOOT_PARAM_OFF / sizeof(u32)] =
-		bfa_os_swap32(boot_param);
 
 	pgnum = bfa_ioc_smem_pgnum(ioc, loff);
 	pgoff = bfa_ioc_smem_pgoff(ioc, loff);
@@ -1332,17 +1137,17 @@ bfa_ioc_download_fw(struct bfa_ioc_s *io
 
 	for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) {
 
-		if (BFA_FLASH_CHUNK_NO(i) != chunkno) {
-			chunkno = BFA_FLASH_CHUNK_NO(i);
+		if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
+			chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
 			fwimg = bfa_ioc_fwimg_get_chunk(ioc,
-					BFA_FLASH_CHUNK_ADDR(chunkno));
+					BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
 		}
 
 		/**
 		 * write smem
 		 */
 		bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
-			      fwimg[BFA_FLASH_OFFSET_IN_CHUNK(i)]);
+			      fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]);
 
 		loff += sizeof(u32);
 
@@ -1358,6 +1163,14 @@ bfa_ioc_download_fw(struct bfa_ioc_s *io
 
 	bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
 		      bfa_ioc_smem_pgnum(ioc, 0));
+
+	/*
+	 * Set boot type and boot param at the end.
+	 */
+	bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_TYPE_OFF,
+			bfa_os_swap32(boot_type));
+	bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_PARAM_OFF,
+			bfa_os_swap32(boot_param));
 }
 
 static void
@@ -1440,168 +1253,10 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc_s *io
 }
 
 /**
- * Initialize IOC to port mapping.
- */
-
-#define FNC_PERS_FN_SHIFT(__fn)	((__fn) * 8)
-static void
-bfa_ioc_map_port(struct bfa_ioc_s *ioc)
-{
-	bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
-	u32        r32;
-
-	/**
-	 * For crossbow, port id is same as pci function.
-	 */
-	if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT) {
-		ioc->port_id = bfa_ioc_pcifn(ioc);
-		return;
-	}
-
-	/**
-	 * For catapult, base port id on personality register and IOC type
-	 */
-	r32 = bfa_reg_read(rb + FNC_PERS_REG);
-	r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
-	ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
-
-	bfa_trc(ioc, bfa_ioc_pcifn(ioc));
-	bfa_trc(ioc, ioc->port_id);
-}
-
-
-
-/**
  *  bfa_ioc_public
  */
 
 /**
-* Set interrupt mode for a function: INTX or MSIX
- */
-void
-bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
-{
-	bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
-	u32        r32, mode;
-
-	r32 = bfa_reg_read(rb + FNC_PERS_REG);
-	bfa_trc(ioc, r32);
-
-	mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
-		__F0_INTX_STATUS;
-
-	/**
-	 * If already in desired mode, do not change anything
-	 */
-	if (!msix && mode)
-		return;
-
-	if (msix)
-		mode = __F0_INTX_STATUS_MSIX;
-	else
-		mode = __F0_INTX_STATUS_INTA;
-
-	r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
-	r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
-	bfa_trc(ioc, r32);
-
-	bfa_reg_write(rb + FNC_PERS_REG, r32);
-}
-
-bfa_status_t
-bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
-{
-	bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
-	u32        pll_sclk, pll_fclk, r32;
-
-	if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
-		pll_sclk =
-			__APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
-			__APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) |
-			__APP_PLL_312_JITLMT0_1(3U) |
-			__APP_PLL_312_CNTLMT0_1(1U);
-		pll_fclk =
-			__APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
-			__APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) |
-			__APP_PLL_425_JITLMT0_1(3U) |
-			__APP_PLL_425_CNTLMT0_1(1U);
-
-		/**
-		 * 	For catapult, choose operational mode FC/FCoE
-		 */
-		if (ioc->fcmode) {
-			bfa_reg_write((rb + OP_MODE), 0);
-			bfa_reg_write((rb + ETH_MAC_SER_REG),
-				      __APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2
-				      | __APP_EMS_CHANNEL_SEL);
-		} else {
-			ioc->pllinit = BFA_TRUE;
-			bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
-			bfa_reg_write((rb + ETH_MAC_SER_REG),
-				      __APP_EMS_REFCKBUFEN1);
-		}
-	} else {
-		pll_sclk =
-			__APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
-			__APP_PLL_312_P0_1(3U) | __APP_PLL_312_JITLMT0_1(3U) |
-			__APP_PLL_312_CNTLMT0_1(3U);
-		pll_fclk =
-			__APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
-			__APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
-			__APP_PLL_425_JITLMT0_1(3U) |
-			__APP_PLL_425_CNTLMT0_1(3U);
-	}
-
-	bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
-	bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
-
-	bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
-	bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
-	bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
-	bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
-	bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
-	bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
-
-	bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
-		      __APP_PLL_312_LOGIC_SOFT_RESET);
-	bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
-		      __APP_PLL_312_BYPASS | __APP_PLL_312_LOGIC_SOFT_RESET);
-	bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
-		      __APP_PLL_425_LOGIC_SOFT_RESET);
-	bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
-		      __APP_PLL_425_BYPASS | __APP_PLL_425_LOGIC_SOFT_RESET);
-	bfa_os_udelay(2);
-	bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
-		      __APP_PLL_312_LOGIC_SOFT_RESET);
-	bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
-		      __APP_PLL_425_LOGIC_SOFT_RESET);
-
-	bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
-		      pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET);
-	bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
-		      pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET);
-
-	/**
-	 * Wait for PLLs to lock.
-	 */
-	bfa_os_udelay(2000);
-	bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
-	bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
-
-	bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
-	bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
-
-	if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
-		bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
-		bfa_os_udelay(1000);
-		r32 = bfa_reg_read((rb + MBIST_STAT_REG));
-		bfa_trc(ioc, r32);
-	}
-
-	return BFA_STATUS_OK;
-}
-
-/**
  * Interface used by diag module to do firmware boot with memory test
  * as the entry vector.
  */
@@ -1642,7 +1297,7 @@ bfa_ioc_boot(struct bfa_ioc_s *ioc, u32
 void
 bfa_ioc_auto_recover(bfa_boolean_t auto_recover)
 {
-	bfa_auto_recover = BFA_FALSE;
+	bfa_auto_recover = auto_recover;
 }
 
 
@@ -1764,6 +1419,14 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc,
 	ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT);
 	ioc->cna = ioc->ctdev && !ioc->fcmode;
 
+	/**
+	 * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c
+	 */
+	if (ioc->ctdev)
+		bfa_ioc_set_ct_hwif(ioc);
+	else
+		bfa_ioc_set_cb_hwif(ioc);
+
 	bfa_ioc_map_port(ioc);
 	bfa_ioc_reg_init(ioc);
 }
@@ -1830,7 +1493,6 @@ return (auto_recover) ? BFA_DBG_FWTRC_LE
 void
 bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
 {
-	bfa_assert(ioc->auto_recover);
 	ioc->dbg_fwsave = dbg_fwsave;
 	ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->auto_recover);
 }
@@ -1973,7 +1635,7 @@ bfa_ioc_fw_mismatch(struct bfa_ioc_s *io
 	 ((__sm) == BFI_IOC_INITING) ||		\
 	 ((__sm) == BFI_IOC_HWINIT) ||		\
 	 ((__sm) == BFI_IOC_DISABLED) ||	\
-	 ((__sm) == BFI_IOC_HBFAIL) ||		\
+	 ((__sm) == BFI_IOC_FAIL) ||		\
 	 ((__sm) == BFI_IOC_CFG_DISABLED))
 
 /**
@@ -2017,46 +1679,28 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_
 			 struct bfa_adapter_attr_s *ad_attr)
 {
 	struct bfi_ioc_attr_s *ioc_attr;
-	char            model[BFA_ADAPTER_MODEL_NAME_LEN];
 
 	ioc_attr = ioc->attr;
-	bfa_os_memcpy((void *)&ad_attr->serial_num,
-		      (void *)ioc_attr->brcd_serialnum,
-		      BFA_ADAPTER_SERIAL_NUM_LEN);
 
-	bfa_os_memcpy(&ad_attr->fw_ver, ioc_attr->fw_version, BFA_VERSION_LEN);
-	bfa_os_memcpy(&ad_attr->optrom_ver, ioc_attr->optrom_version,
-		      BFA_VERSION_LEN);
-	bfa_os_memcpy(&ad_attr->manufacturer, BFA_MFG_NAME,
-		      BFA_ADAPTER_MFG_NAME_LEN);
+	bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num);
+	bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver);
+	bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver);
+	bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer);
 	bfa_os_memcpy(&ad_attr->vpd, &ioc_attr->vpd,
 		      sizeof(struct bfa_mfg_vpd_s));
 
-	ad_attr->nports = BFI_ADAPTER_GETP(NPORTS, ioc_attr->adapter_prop);
-	ad_attr->max_speed = BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
+	ad_attr->nports = bfa_ioc_get_nports(ioc);
+	ad_attr->max_speed = bfa_ioc_speed_sup(ioc);
 
-	/**
-	 * model name
-	 */
-	if (BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop) == 10) {
-		strcpy(model, "BR-10?0");
-		model[5] = '0' + ad_attr->nports;
-	} else {
-		strcpy(model, "Brocade-??5");
-		model[8] =
-			'0' + BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
-		model[9] = '0' + ad_attr->nports;
-	}
+	bfa_ioc_get_adapter_model(ioc, ad_attr->model);
+	/* For now, model descr uses same model string */
+	bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr);
 
 	if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
 		ad_attr->prototype = 1;
 	else
 		ad_attr->prototype = 0;
 
-	bfa_os_memcpy(&ad_attr->model, model, BFA_ADAPTER_MODEL_NAME_LEN);
-	bfa_os_memcpy(&ad_attr->model_descr, &ad_attr->model,
-		      BFA_ADAPTER_MODEL_NAME_LEN);
-
 	ad_attr->pwwn = bfa_ioc_get_pwwn(ioc);
 	ad_attr->mac = bfa_ioc_get_mac(ioc);
 
@@ -2064,41 +1708,122 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_
 	ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
 	ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
 	ad_attr->asic_rev = ioc_attr->asic_rev;
-	ad_attr->hw_ver[0] = 'R';
-	ad_attr->hw_ver[1] = 'e';
-	ad_attr->hw_ver[2] = 'v';
-	ad_attr->hw_ver[3] = '-';
-	ad_attr->hw_ver[4] = ioc_attr->asic_rev;
-	ad_attr->hw_ver[5] = '\0';
+
+	bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
 
 	ad_attr->cna_capable = ioc->cna;
 }
 
+enum bfa_ioc_type_e
+bfa_ioc_get_type(struct bfa_ioc_s *ioc)
+{
+	if (!ioc->ctdev || ioc->fcmode)
+		return BFA_IOC_TYPE_FC;
+	else if (ioc->ioc_mc == BFI_MC_IOCFC)
+		return BFA_IOC_TYPE_FCoE;
+	else if (ioc->ioc_mc == BFI_MC_LL)
+		return BFA_IOC_TYPE_LL;
+	else {
+		bfa_assert(ioc->ioc_mc == BFI_MC_LL);
+		return BFA_IOC_TYPE_LL;
+	}
+}
+
+void
+bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num)
+{
+	bfa_os_memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN);
+	bfa_os_memcpy((void *)serial_num,
+			(void *)ioc->attr->brcd_serialnum,
+			BFA_ADAPTER_SERIAL_NUM_LEN);
+}
+
+void
+bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver)
+{
+	bfa_os_memset((void *)fw_ver, 0, BFA_VERSION_LEN);
+	bfa_os_memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN);
+}
+
+void
+bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev)
+{
+	bfa_assert(chip_rev);
+
+	bfa_os_memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN);
+
+	chip_rev[0] = 'R';
+	chip_rev[1] = 'e';
+	chip_rev[2] = 'v';
+	chip_rev[3] = '-';
+	chip_rev[4] = ioc->attr->asic_rev;
+	chip_rev[5] = '\0';
+}
+
+void
+bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver)
+{
+	bfa_os_memset((void *)optrom_ver, 0, BFA_VERSION_LEN);
+	bfa_os_memcpy(optrom_ver, ioc->attr->optrom_version,
+		BFA_VERSION_LEN);
+}
+
+void
+bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer)
+{
+	bfa_os_memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN);
+	bfa_os_memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
+}
+
+void
+bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model)
+{
+	struct bfi_ioc_attr_s   *ioc_attr;
+	u8              nports;
+	u8              max_speed;
+
+	bfa_assert(model);
+	bfa_os_memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
+
+	ioc_attr = ioc->attr;
+
+	nports = bfa_ioc_get_nports(ioc);
+	max_speed = bfa_ioc_speed_sup(ioc);
+
+	/**
+	 * model name
+	 */
+	if (max_speed == 10) {
+		strcpy(model, "BR-10?0");
+		model[5] = '0' + nports;
+	} else {
+		strcpy(model, "Brocade-??5");
+		model[8] = '0' + max_speed;
+		model[9] = '0' + nports;
+	}
+}
+
+enum bfa_ioc_state
+bfa_ioc_get_state(struct bfa_ioc_s *ioc)
+{
+	return bfa_sm_to_state(ioc_sm_table, ioc->fsm);
+}
+
 void
 bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
 {
 	bfa_os_memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
 
-	ioc_attr->state = bfa_sm_to_state(ioc_sm_table, ioc->fsm);
+	ioc_attr->state = bfa_ioc_get_state(ioc);
 	ioc_attr->port_id = ioc->port_id;
 
-	if (!ioc->ctdev)
-		ioc_attr->ioc_type = BFA_IOC_TYPE_FC;
-	else if (ioc->ioc_mc == BFI_MC_IOCFC)
-		ioc_attr->ioc_type = BFA_IOC_TYPE_FCoE;
-	else if (ioc->ioc_mc == BFI_MC_LL)
-		ioc_attr->ioc_type = BFA_IOC_TYPE_LL;
+	ioc_attr->ioc_type = bfa_ioc_get_type(ioc);
 
 	bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
 
 	ioc_attr->pci_attr.device_id = ioc->pcidev.device_id;
 	ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func;
-	ioc_attr->pci_attr.chip_rev[0] = 'R';
-	ioc_attr->pci_attr.chip_rev[1] = 'e';
-	ioc_attr->pci_attr.chip_rev[2] = 'v';
-	ioc_attr->pci_attr.chip_rev[3] = '-';
-	ioc_attr->pci_attr.chip_rev[4] = ioc_attr->adapter_attr.asic_rev;
-	ioc_attr->pci_attr.chip_rev[5] = '\0';
+	bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
 }
 
 /**
@@ -2195,29 +1920,6 @@ bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc
 }
 
 /**
- * Return true if interrupt should be claimed.
- */
-bfa_boolean_t
-bfa_ioc_intx_claim(struct bfa_ioc_s *ioc)
-{
-	u32        isr, msk;
-
-	/**
-	 * Always claim if not catapult.
-	 */
-	if (!ioc->ctdev)
-		return BFA_TRUE;
-
-	/**
-	 * FALSE if next device is claiming interrupt.
-	 * TRUE if next device is not interrupting or not present.
-	 */
-	msk = bfa_reg_read(ioc->ioc_regs.shirq_msk_next);
-	isr = bfa_reg_read(ioc->ioc_regs.shirq_isr_next);
-	return !(isr & ~msk);
-}
-
-/**
  * Send AEN notification
  */
 static void
@@ -2226,32 +1928,14 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc,
 	union bfa_aen_data_u aen_data;
 	struct bfa_log_mod_s *logmod = ioc->logm;
 	s32         inst_num = 0;
-	struct bfa_ioc_attr_s ioc_attr;
+	enum bfa_ioc_type_e ioc_type;
 
-	switch (event) {
-	case BFA_IOC_AEN_HBGOOD:
-		bfa_log(logmod, BFA_AEN_IOC_HBGOOD, inst_num);
-		break;
-	case BFA_IOC_AEN_HBFAIL:
-		bfa_log(logmod, BFA_AEN_IOC_HBFAIL, inst_num);
-		break;
-	case BFA_IOC_AEN_ENABLE:
-		bfa_log(logmod, BFA_AEN_IOC_ENABLE, inst_num);
-		break;
-	case BFA_IOC_AEN_DISABLE:
-		bfa_log(logmod, BFA_AEN_IOC_DISABLE, inst_num);
-		break;
-	case BFA_IOC_AEN_FWMISMATCH:
-		bfa_log(logmod, BFA_AEN_IOC_FWMISMATCH, inst_num);
-		break;
-	default:
-		break;
-	}
+	bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, event), inst_num);
 
 	memset(&aen_data.ioc.pwwn, 0, sizeof(aen_data.ioc.pwwn));
 	memset(&aen_data.ioc.mac, 0, sizeof(aen_data.ioc.mac));
-	bfa_ioc_get_attr(ioc, &ioc_attr);
-	switch (ioc_attr.ioc_type) {
+	ioc_type = bfa_ioc_get_type(ioc);
+	switch (ioc_type) {
 	case BFA_IOC_TYPE_FC:
 		aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc);
 		break;
@@ -2263,10 +1947,10 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc,
 		aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
 		break;
 	default:
-		bfa_assert(ioc_attr.ioc_type == BFA_IOC_TYPE_FC);
+		bfa_assert(ioc_type == BFA_IOC_TYPE_FC);
 		break;
 	}
-	aen_data.ioc.ioc_type = ioc_attr.ioc_type;
+	aen_data.ioc.ioc_type = ioc_type;
 }
 
 /**
@@ -2290,6 +1974,15 @@ bfa_ioc_debug_fwsave(struct bfa_ioc_s *i
 }
 
 /**
+ * Clear saved firmware trace
+ */
+void
+bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc)
+{
+	ioc->dbg_fwsave_once = BFA_TRUE;
+}
+
+/**
  * Retrieve saved firmware trace from a prior IOC failure.
  */
 bfa_status_t
@@ -2304,6 +1997,13 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *io
 
 	pgnum = bfa_ioc_smem_pgnum(ioc, loff);
 	loff = bfa_ioc_smem_pgoff(ioc, loff);
+
+	/*
+	 *  Hold semaphore to serialize pll init and fwtrc.
+	 */
+	if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg))
+		return BFA_STATUS_FAILED;
+
 	bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
 
 	tlen = *trclen;
@@ -2329,6 +2029,12 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *io
 	}
 	bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
 		      bfa_ioc_smem_pgnum(ioc, 0));
+
+	/*
+	 *  release semaphore.
+	 */
+	bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+
 	bfa_trc(ioc, pgnum);
 
 	*trclen = tlen * sizeof(u32);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioc_cb.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_ioc_cb.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioc_cb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_ioc_cb.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux driver for Brocade Fibre Channel Host Bus Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <bfa.h>
+#include <bfa_ioc.h>
+#include <bfa_fwimg_priv.h>
+#include <cna/bfa_cna_trcmod.h>
+#include <cs/bfa_debug.h>
+#include <bfi/bfi_ioc.h>
+#include <bfi/bfi_cbreg.h>
+#include <log/bfa_log_hal.h>
+#include <defs/bfa_defs_pci.h>
+
+BFA_TRC_FILE(CNA, IOC_CB);
+
+/*
+ * forward declarations
+ */
+static bfa_status_t bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc);
+static bfa_boolean_t bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc);
+static u32  *bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off);
+static u32 bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
+static void bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc);
+
+struct bfa_ioc_hwif_s hwif_cb = {
+	bfa_ioc_cb_pll_init,
+	bfa_ioc_cb_firmware_lock,
+	bfa_ioc_cb_firmware_unlock,
+	bfa_ioc_cb_fwimg_get_chunk,
+	bfa_ioc_cb_fwimg_get_size,
+	bfa_ioc_cb_reg_init,
+	bfa_ioc_cb_map_port,
+	bfa_ioc_cb_isr_mode_set,
+	bfa_ioc_cb_notify_hbfail,
+	bfa_ioc_cb_ownership_reset,
+};
+
+/**
+ * Called from bfa_ioc_attach() to map asic specific calls.
+ */
+void
+bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
+{
+	ioc->ioc_hwif = &hwif_cb;
+}
+
+static u32 *
+bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
+{
+	return bfi_image_cb_get_chunk(off);
+}
+
+static u32
+bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc)
+{
+	return bfi_image_cb_size;
+}
+
+/**
+ * Return true if firmware of current driver matches the running firmware.
+ */
+static bfa_boolean_t
+bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc)
+{
+	return BFA_TRUE;
+}
+
+static void
+bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc)
+{
+}
+
+/**
+ * Notify other functions on HB failure.
+ */
+static void
+bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc)
+{
+	bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
+	bfa_reg_read(ioc->ioc_regs.err_set);
+}
+
+/**
+ * Host to LPU mailbox message addresses
+ */
+static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
+	{ HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
+	{ HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd[] = {
+	{ HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT },
+	{ HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT }
+};
+
+static void
+bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc)
+{
+	bfa_os_addr_t	rb;
+	int		pcifn = bfa_ioc_pcifn(ioc);
+
+	rb = bfa_ioc_bar0(ioc);
+
+	ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
+	ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
+	ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
+
+	if (ioc->port_id == 0) {
+		ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
+		ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
+	} else {
+		ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
+		ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+	}
+
+	/**
+	 * Host <-> LPU mailbox command/status registers
+	 */
+	ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd[pcifn].hfn;
+	ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd[pcifn].lpu;
+
+	/*
+	 * PSS control registers
+	 */
+	ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
+	ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
+	ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_400_CTL_REG);
+	ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_212_CTL_REG);
+
+	/*
+	 * IOC semaphore registers and serialization
+	 */
+	ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
+	ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
+
+	/**
+	 * sram memory access
+	 */
+	ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
+	ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
+
+	/*
+	 * err set reg : for notification of hb failure
+	 */
+	ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
+}
+
+/**
+ * Initialize IOC to port mapping.
+ */
+static void
+bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc)
+{
+	/**
+	 * For crossbow, port id is same as pci function.
+	 */
+	ioc->port_id = bfa_ioc_pcifn(ioc);
+	bfa_trc(ioc, ioc->port_id);
+}
+
+/**
+ * Set interrupt mode for a function: INTX or MSIX
+ */
+static void
+bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
+{
+}
+
+static bfa_status_t
+bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc)
+{
+	bfa_os_addr_t	rb = ioc->pcidev.pci_bar_kva;
+	u32	pll_sclk, pll_fclk;
+
+	/*
+	 *  Hold semaphore so that nobody can access the chip during init.
+	 */
+	bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
+
+	pll_sclk = __APP_PLL_212_ENABLE | __APP_PLL_212_LRESETN |
+			__APP_PLL_212_P0_1(3U) |
+			__APP_PLL_212_JITLMT0_1(3U) |
+			__APP_PLL_212_CNTLMT0_1(3U);
+	pll_fclk = __APP_PLL_400_ENABLE | __APP_PLL_400_LRESETN |
+			__APP_PLL_400_RSEL200500 | __APP_PLL_400_P0_1(3U) |
+			__APP_PLL_400_JITLMT0_1(3U) |
+			__APP_PLL_400_CNTLMT0_1(3U);
+
+	bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
+	bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
+
+	bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+	bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+	bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+	bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+	bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+	bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+
+	bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+			__APP_PLL_212_LOGIC_SOFT_RESET);
+	bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+			__APP_PLL_212_BYPASS |
+			__APP_PLL_212_LOGIC_SOFT_RESET);
+	bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+			__APP_PLL_400_LOGIC_SOFT_RESET);
+	bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+			__APP_PLL_400_BYPASS |
+			__APP_PLL_400_LOGIC_SOFT_RESET);
+	bfa_os_udelay(2);
+	bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+			__APP_PLL_212_LOGIC_SOFT_RESET);
+	bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+			__APP_PLL_400_LOGIC_SOFT_RESET);
+
+	bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+			pll_sclk | __APP_PLL_212_LOGIC_SOFT_RESET);
+	bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+			pll_fclk | __APP_PLL_400_LOGIC_SOFT_RESET);
+
+	/**
+	 * Wait for PLLs to lock.
+	 */
+	bfa_os_udelay(2000);
+	bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+	bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+
+	bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
+	bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
+
+	/*
+	 *  release semaphore.
+	 */
+	bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+
+	return BFA_STATUS_OK;
+}
+
+/**
+ * Cleanup hw semaphore and usecnt registers
+ */
+static void
+bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc)
+{
+
+	/*
+	 * Read the hw sem reg to make sure that it is locked
+	 * before we clear it. If it is not locked, writing 1
+	 * will lock it instead of clearing it.
+	 */
+	bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
+	bfa_ioc_hw_sem_release(ioc);
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioc_ct.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_ioc_ct.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioc_ct.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_ioc_ct.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux driver for Brocade Fibre Channel Host Bus Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <bfa.h>
+#include <bfa_ioc.h>
+#include <bfa_fwimg_priv.h>
+#include <cna/bfa_cna_trcmod.h>
+#include <cs/bfa_debug.h>
+#include <bfi/bfi_ioc.h>
+#include <bfi/bfi_ctreg.h>
+#include <log/bfa_log_hal.h>
+#include <defs/bfa_defs_pci.h>
+
+BFA_TRC_FILE(CNA, IOC_CT);
+
+/*
+ * forward declarations
+ */
+static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc);
+static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc);
+static u32* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc,
+					u32 off);
+static u32 bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
+static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc);
+
+struct bfa_ioc_hwif_s hwif_ct = {
+	bfa_ioc_ct_pll_init,
+	bfa_ioc_ct_firmware_lock,
+	bfa_ioc_ct_firmware_unlock,
+	bfa_ioc_ct_fwimg_get_chunk,
+	bfa_ioc_ct_fwimg_get_size,
+	bfa_ioc_ct_reg_init,
+	bfa_ioc_ct_map_port,
+	bfa_ioc_ct_isr_mode_set,
+	bfa_ioc_ct_notify_hbfail,
+	bfa_ioc_ct_ownership_reset,
+};
+
+/**
+ * Called from bfa_ioc_attach() to map asic specific calls.
+ */
+void
+bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc)
+{
+	ioc->ioc_hwif = &hwif_ct;
+}
+
+static u32*
+bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
+{
+	return bfi_image_ct_get_chunk(off);
+}
+
+static u32
+bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc)
+{
+	return bfi_image_ct_size;
+}
+
+/**
+ * Return true if firmware of current driver matches the running firmware.
+ */
+static bfa_boolean_t
+bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
+{
+	enum bfi_ioc_state ioc_fwstate;
+	u32 usecnt;
+	struct bfi_ioc_image_hdr_s fwhdr;
+
+	/**
+	 * Firmware match check is relevant only for CNA.
+	 */
+	if (!ioc->cna)
+		return BFA_TRUE;
+
+	/**
+	 * If bios boot (flash based) -- do not increment usage count
+	 */
+	if (bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+		return BFA_TRUE;
+
+	bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+	usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
+
+	/**
+	 * If usage count is 0, always return TRUE.
+	 */
+	if (usecnt == 0) {
+		bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
+		bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+		bfa_trc(ioc, usecnt);
+		return BFA_TRUE;
+	}
+
+	ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
+	bfa_trc(ioc, ioc_fwstate);
+
+	/**
+	 * Use count cannot be non-zero and chip in uninitialized state.
+	 */
+	bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
+
+	/**
+	 * Check if another driver with a different firmware is active
+	 */
+	bfa_ioc_fwver_get(ioc, &fwhdr);
+	if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
+		bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+		bfa_trc(ioc, usecnt);
+		return BFA_FALSE;
+	}
+
+	/**
+	 * Same firmware version. Increment the reference count.
+	 */
+	usecnt++;
+	bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
+	bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+	bfa_trc(ioc, usecnt);
+	return BFA_TRUE;
+}
+
+static void
+bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
+{
+	u32 usecnt;
+
+	/**
+	 * Firmware lock is relevant only for CNA.
+	 * If bios boot (flash based) -- do not decrement usage count
+	 */
+	if (!ioc->cna || bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+		return;
+
+	/**
+	 * decrement usage count
+	 */
+	bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+	usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
+	bfa_assert(usecnt > 0);
+
+	usecnt--;
+	bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
+	bfa_trc(ioc, usecnt);
+
+	bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+}
+
+/**
+ * Notify other functions on HB failure.
+ */
+static void
+bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc)
+{
+	if (ioc->cna) {
+		bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
+		/* Wait for halt to take effect */
+		bfa_reg_read(ioc->ioc_regs.ll_halt);
+	} else {
+		bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
+		bfa_reg_read(ioc->ioc_regs.err_set);
+	}
+}
+
+/**
+ * Host to LPU mailbox message addresses
+ */
+static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
+	{ HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
+	{ HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
+	{ HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 },
+	{ HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers - port 0
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = {
+	{ HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT },
+	{ HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT },
+	{ HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT },
+	{ HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers - port 1
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = {
+	{ HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT },
+	{ HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT },
+	{ HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT },
+	{ HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT }
+};
+
+static void
+bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
+{
+	bfa_os_addr_t	rb;
+	int		pcifn = bfa_ioc_pcifn(ioc);
+
+	rb = bfa_ioc_bar0(ioc);
+
+	ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
+	ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
+	ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
+
+	if (ioc->port_id == 0) {
+		ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
+		ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
+		ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
+		ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
+		ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
+	} else {
+		ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
+		ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+		ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
+		ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
+		ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
+	}
+
+	/*
+	 * PSS control registers
+	 */
+	ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
+	ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
+	ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
+	ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
+
+	/*
+	 * IOC semaphore registers and serialization
+	 */
+	ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
+	ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
+	ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
+	ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
+
+	/**
+	 * sram memory access
+	 */
+	ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
+	ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
+
+	/*
+	 * err set reg : for notification of hb failure in fcmode
+	 */
+	ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
+}
+
+/**
+ * Initialize IOC to port mapping.
+ */
+
+#define FNC_PERS_FN_SHIFT(__fn)	((__fn) * 8)
+static void
+bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc)
+{
+	bfa_os_addr_t	rb = ioc->pcidev.pci_bar_kva;
+	u32	r32;
+
+	/**
+	 * For catapult, base port id on personality register and IOC type
+	 */
+	r32 = bfa_reg_read(rb + FNC_PERS_REG);
+	r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
+	ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
+
+	bfa_trc(ioc, bfa_ioc_pcifn(ioc));
+	bfa_trc(ioc, ioc->port_id);
+}
+
+/**
+ * Set interrupt mode for a function: INTX or MSIX
+ */
+static void
+bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
+{
+	bfa_os_addr_t	rb = ioc->pcidev.pci_bar_kva;
+	u32	r32, mode;
+
+	r32 = bfa_reg_read(rb + FNC_PERS_REG);
+	bfa_trc(ioc, r32);
+
+	mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
+		__F0_INTX_STATUS;
+
+	/**
+	 * If already in desired mode, do not change anything
+	 */
+	if (!msix && mode)
+		return;
+
+	if (msix)
+		mode = __F0_INTX_STATUS_MSIX;
+	else
+		mode = __F0_INTX_STATUS_INTA;
+
+	r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
+	r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
+	bfa_trc(ioc, r32);
+
+	bfa_reg_write(rb + FNC_PERS_REG, r32);
+}
+
+static bfa_status_t
+bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc)
+{
+	bfa_os_addr_t	rb = ioc->pcidev.pci_bar_kva;
+	u32	pll_sclk, pll_fclk, r32;
+
+	/*
+	 *  Hold semaphore so that nobody can access the chip during init.
+	 */
+	bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
+
+	pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST |
+		__APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) |
+		__APP_PLL_312_JITLMT0_1(3U) |
+		__APP_PLL_312_CNTLMT0_1(1U);
+	pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST |
+		__APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
+		__APP_PLL_425_JITLMT0_1(3U) |
+		__APP_PLL_425_CNTLMT0_1(1U);
+
+	/**
+	 *	For catapult, choose operational mode FC/FCoE
+	 */
+	if (ioc->fcmode) {
+		bfa_reg_write((rb + OP_MODE), 0);
+		bfa_reg_write((rb + ETH_MAC_SER_REG),
+				__APP_EMS_CMLCKSEL |
+				__APP_EMS_REFCKBUFEN2 |
+				__APP_EMS_CHANNEL_SEL);
+	} else {
+		ioc->pllinit = BFA_TRUE;
+		bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
+		bfa_reg_write((rb + ETH_MAC_SER_REG),
+				 __APP_EMS_REFCKBUFEN1);
+	}
+
+	bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
+	bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
+
+	bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+	bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+	bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+	bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+	bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+	bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+
+	bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
+		__APP_PLL_312_LOGIC_SOFT_RESET);
+	bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
+		__APP_PLL_425_LOGIC_SOFT_RESET);
+	bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
+		__APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE);
+	bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
+		__APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE);
+
+	/**
+	 * Wait for PLLs to lock.
+	 */
+	bfa_reg_read(rb + HOSTFN0_INT_MSK);
+	bfa_os_udelay(2000);
+	bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+	bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+
+	bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
+		__APP_PLL_312_ENABLE);
+	bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
+		__APP_PLL_425_ENABLE);
+
+	bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
+	bfa_os_udelay(1000);
+	r32 = bfa_reg_read((rb + MBIST_STAT_REG));
+	bfa_trc(ioc, r32);
+	/*
+	 *  release semaphore.
+	 */
+	bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+
+	return BFA_STATUS_OK;
+}
+
+/**
+ * Cleanup hw semaphore and usecnt registers
+ */
+static void
+bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
+{
+
+	if (ioc->cna) {
+		bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+		bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 0);
+		bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+	}
+
+	/*
+	 * Read the hw sem reg to make sure that it is locked
+	 * before we clear it. If it is not locked, writing 1
+	 * will lock it instead of clearing it.
+	 */
+	bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
+	bfa_ioc_hw_sem_release(ioc);
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_iocfc.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_iocfc.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_iocfc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_iocfc.c	2010-05-16 17:17:36.000000000 -0400
@@ -172,6 +172,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, vo
 	 */
 	if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) {
 		iocfc->hwif.hw_reginit = bfa_hwct_reginit;
+		iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack;
 		iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack;
 		iocfc->hwif.hw_msix_init = bfa_hwct_msix_init;
 		iocfc->hwif.hw_msix_install = bfa_hwct_msix_install;
@@ -180,6 +181,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, vo
 		iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
 	} else {
 		iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
+		iocfc->hwif.hw_reqq_ack = bfa_hwcb_reqq_ack;
 		iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
 		iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
 		iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install;
@@ -336,8 +338,10 @@ bfa_iocfc_init_cb(void *bfa_arg, bfa_boo
 			bfa_cb_init(bfa->bfad, BFA_STATUS_OK);
 		else
 			bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED);
-	} else
-		bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
+	} else {
+		if (bfa->iocfc.cfgdone)
+			bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
+	}
 }
 
 static void
@@ -619,8 +623,6 @@ bfa_iocfc_attach(struct bfa_s *bfa, void
 
 	bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod,
 		bfa->trcmod, bfa->aen, bfa->logm);
-	bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
-	bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
 
 	/**
 	 * Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode.
@@ -628,6 +630,9 @@ bfa_iocfc_attach(struct bfa_s *bfa, void
 	if (0)
 		bfa_ioc_set_fcmode(&bfa->ioc);
 
+	bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
+	bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
+
 	bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev);
 	bfa_iocfc_mem_claim(bfa, cfg, meminfo);
 	bfa_timer_init(&bfa->timer_mod);
@@ -654,7 +659,6 @@ bfa_iocfc_init(struct bfa_s *bfa)
 {
 	bfa->iocfc.action = BFA_IOCFC_ACT_INIT;
 	bfa_ioc_enable(&bfa->ioc);
-	bfa_msix_install(bfa);
 }
 
 /**
@@ -797,6 +801,11 @@ bfa_iocfc_get_stats(struct bfa_s *bfa, s
 		return BFA_STATUS_DEVBUSY;
 	}
 
+	if (!bfa_iocfc_is_operational(bfa)) {
+		bfa_trc(bfa, 0);
+		return BFA_STATUS_IOC_NON_OP;
+	}
+
 	iocfc->stats_busy = BFA_TRUE;
 	iocfc->stats_ret = stats;
 	iocfc->stats_cbfn = cbfn;
@@ -817,6 +826,11 @@ bfa_iocfc_clear_stats(struct bfa_s *bfa,
 		return BFA_STATUS_DEVBUSY;
 	}
 
+	if (!bfa_iocfc_is_operational(bfa)) {
+		bfa_trc(bfa, 0);
+		return BFA_STATUS_IOC_NON_OP;
+	}
+
 	iocfc->stats_busy = BFA_TRUE;
 	iocfc->stats_cbfn = cbfn;
 	iocfc->stats_cbarg = cbarg;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_iocfc.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_iocfc.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_iocfc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_iocfc.h	2010-05-16 17:17:36.000000000 -0400
@@ -54,6 +54,7 @@ struct bfa_msix_s {
  */
 struct bfa_hwif_s {
 	void (*hw_reginit)(struct bfa_s *bfa);
+	void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq);
 	void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq);
 	void (*hw_msix_init)(struct bfa_s *bfa, int nvecs);
 	void (*hw_msix_install)(struct bfa_s *bfa);
@@ -143,6 +144,7 @@ void bfa_msix_rspq(struct bfa_s *bfa, in
 void bfa_msix_lpu_err(struct bfa_s *bfa, int vec);
 
 void bfa_hwcb_reginit(struct bfa_s *bfa);
+void bfa_hwcb_reqq_ack(struct bfa_s *bfa, int rspq);
 void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq);
 void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs);
 void bfa_hwcb_msix_install(struct bfa_s *bfa);
@@ -151,6 +153,7 @@ void bfa_hwcb_isr_mode_set(struct bfa_s
 void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap,
 			u32 *nvecs, u32 *maxvec);
 void bfa_hwct_reginit(struct bfa_s *bfa);
+void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq);
 void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq);
 void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs);
 void bfa_hwct_msix_install(struct bfa_s *bfa);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioc.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_ioc.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_ioc.h	2010-05-16 17:17:36.000000000 -0400
@@ -74,15 +74,18 @@ struct bfa_ioc_regs_s {
 	bfa_os_addr_t   lpu_mbox_cmd;
 	bfa_os_addr_t   lpu_mbox;
 	bfa_os_addr_t   pss_ctl_reg;
+	bfa_os_addr_t   pss_err_status_reg;
 	bfa_os_addr_t   app_pll_fast_ctl_reg;
 	bfa_os_addr_t   app_pll_slow_ctl_reg;
 	bfa_os_addr_t   ioc_sem_reg;
 	bfa_os_addr_t   ioc_usage_sem_reg;
+	bfa_os_addr_t   ioc_init_sem_reg;
 	bfa_os_addr_t   ioc_usage_reg;
 	bfa_os_addr_t   host_page_num_fn;
 	bfa_os_addr_t   heartbeat;
 	bfa_os_addr_t   ioc_fwstate;
 	bfa_os_addr_t   ll_halt;
+	bfa_os_addr_t   err_set;
 	bfa_os_addr_t   shirq_isr_next;
 	bfa_os_addr_t   shirq_msk_next;
 	bfa_os_addr_t   smem_page_start;
@@ -154,7 +157,6 @@ struct bfa_ioc_s {
 	struct bfa_timer_s 	ioc_timer;
 	struct bfa_timer_s 	sem_timer;
 	u32		hb_count;
-	u32		hb_fail;
 	u32		retry_count;
 	struct list_head		hb_notify_q;
 	void			*dbg_fwsave;
@@ -177,6 +179,22 @@ struct bfa_ioc_s {
 	struct bfi_ioc_attr_s	*attr;
 	struct bfa_ioc_cbfn_s	*cbfn;
 	struct bfa_ioc_mbox_mod_s mbox_mod;
+	struct bfa_ioc_hwif_s   *ioc_hwif;
+};
+
+struct bfa_ioc_hwif_s {
+	bfa_status_t    (*ioc_pll_init) (struct bfa_ioc_s *ioc);
+	bfa_boolean_t   (*ioc_firmware_lock)    (struct bfa_ioc_s *ioc);
+	void            (*ioc_firmware_unlock)  (struct bfa_ioc_s *ioc);
+	u32 *   	(*ioc_fwimg_get_chunk)  (struct bfa_ioc_s *ioc,
+						u32 off);
+	u32		(*ioc_fwimg_get_size)   (struct bfa_ioc_s *ioc);
+	void		(*ioc_reg_init) (struct bfa_ioc_s *ioc);
+	void		(*ioc_map_port) (struct bfa_ioc_s *ioc);
+	void		(*ioc_isr_mode_set)     (struct bfa_ioc_s *ioc,
+						bfa_boolean_t msix);
+	void            (*ioc_notify_hbfail)    (struct bfa_ioc_s *ioc);
+	void            (*ioc_ownership_reset)  (struct bfa_ioc_s *ioc);
 };
 
 #define bfa_ioc_pcifn(__ioc)		((__ioc)->pcidev.pci_func)
@@ -191,6 +209,15 @@ struct bfa_ioc_s {
 #define bfa_ioc_rx_bbcredit(__ioc)	((__ioc)->attr->rx_bbcredit)
 #define bfa_ioc_speed_sup(__ioc)	\
 	BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)
+#define bfa_ioc_get_nports(__ioc)       \
+	BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop)
+
+#define bfa_ioc_stats(_ioc, _stats)     ((_ioc)->stats._stats++)
+#define BFA_IOC_FWIMG_MINSZ     (16 * 1024)
+
+#define BFA_IOC_FLASH_CHUNK_NO(off)             (off / BFI_FLASH_CHUNK_SZ_WORDS)
+#define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off)      (off % BFI_FLASH_CHUNK_SZ_WORDS)
+#define BFA_IOC_FLASH_CHUNK_ADDR(chunkno)  (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
 
 /**
  * IOC mailbox interface
@@ -207,6 +234,14 @@ void bfa_ioc_mbox_regisr(struct bfa_ioc_
 /**
  * IOC interfaces
  */
+#define bfa_ioc_pll_init(__ioc) ((__ioc)->ioc_hwif->ioc_pll_init(__ioc))
+#define bfa_ioc_isr_mode_set(__ioc, __msix)                     \
+			((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix))
+#define bfa_ioc_ownership_reset(__ioc)                          \
+			((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc))
+
+void bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc);
+void bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc);
 void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa,
 		struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod,
 		struct bfa_trc_mod_s *trcmod,
@@ -223,13 +258,21 @@ bfa_boolean_t bfa_ioc_intx_claim(struct
 void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param);
 void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg);
 void bfa_ioc_error_isr(struct bfa_ioc_s *ioc);
-void bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t intx);
-bfa_status_t bfa_ioc_pll_init(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc);
 void bfa_ioc_cfg_complete(struct bfa_ioc_s *ioc);
+enum bfa_ioc_type_e bfa_ioc_get_type(struct bfa_ioc_s *ioc);
+void bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num);
+void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver);
+void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver);
+void bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model);
+void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc,
+	char *manufacturer);
+void bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev);
+enum bfa_ioc_state bfa_ioc_get_state(struct bfa_ioc_s *ioc);
+
 void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr);
 void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
 		struct bfa_adapter_attr_s *ad_attr);
@@ -237,6 +280,7 @@ int bfa_ioc_debug_trcsz(bfa_boolean_t au
 void bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave);
 bfa_status_t bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata,
 		int *trclen);
+void bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc);
 bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata,
 				 int *trclen);
 u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr);
@@ -245,6 +289,13 @@ void bfa_ioc_set_fcmode(struct bfa_ioc_s
 bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc);
 void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
 	struct bfa_ioc_hbfail_notify_s *notify);
+bfa_boolean_t bfa_ioc_sem_get(bfa_os_addr_t sem_reg);
+void bfa_ioc_sem_release(bfa_os_addr_t sem_reg);
+void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
+void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc,
+			struct bfi_ioc_image_hdr_s *fwhdr);
+bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
+			struct bfi_ioc_image_hdr_s *fwhdr);
 
 /*
  * bfa mfg wwn API functions
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioim.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_ioim.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioim.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_ioim.c	2010-05-16 17:17:36.000000000 -0400
@@ -149,7 +149,7 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *io
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ioim->bfa, event);
 	}
 }
 
@@ -194,7 +194,7 @@ bfa_ioim_sm_sgalloc(struct bfa_ioim_s *i
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ioim->bfa, event);
 	}
 }
 
@@ -259,7 +259,7 @@ bfa_ioim_sm_active(struct bfa_ioim_s *io
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ioim->bfa, event);
 	}
 }
 
@@ -317,7 +317,7 @@ bfa_ioim_sm_abort(struct bfa_ioim_s *ioi
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ioim->bfa, event);
 	}
 }
 
@@ -377,7 +377,7 @@ bfa_ioim_sm_cleanup(struct bfa_ioim_s *i
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ioim->bfa, event);
 	}
 }
 
@@ -419,7 +419,7 @@ bfa_ioim_sm_qfull(struct bfa_ioim_s *ioi
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ioim->bfa, event);
 	}
 }
 
@@ -467,7 +467,7 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ioim->bfa, event);
 	}
 }
 
@@ -516,7 +516,7 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioi
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ioim->bfa, event);
 	}
 }
 
@@ -544,7 +544,7 @@ bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim,
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ioim->bfa, event);
 	}
 }
 
@@ -577,7 +577,7 @@ bfa_ioim_sm_hcb_free(struct bfa_ioim_s *
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ioim->bfa, event);
 	}
 }
 
@@ -605,7 +605,7 @@ bfa_ioim_sm_resfree(struct bfa_ioim_s *i
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ioim->bfa, event);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_itnim.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_itnim.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_itnim.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_itnim.c	2010-05-16 17:17:36.000000000 -0400
@@ -144,7 +144,7 @@ bfa_itnim_sm_uninit(struct bfa_itnim_s *
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->bfa, event);
 	}
 }
 
@@ -175,7 +175,7 @@ bfa_itnim_sm_created(struct bfa_itnim_s
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->bfa, event);
 	}
 }
 
@@ -212,7 +212,7 @@ bfa_itnim_sm_fwcreate(struct bfa_itnim_s
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->bfa, event);
 	}
 }
 
@@ -247,7 +247,7 @@ bfa_itnim_sm_fwcreate_qfull(struct bfa_i
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->bfa, event);
 	}
 }
 
@@ -275,7 +275,7 @@ bfa_itnim_sm_delete_pending(struct bfa_i
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->bfa, event);
 	}
 }
 
@@ -317,7 +317,7 @@ bfa_itnim_sm_online(struct bfa_itnim_s *
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->bfa, event);
 	}
 }
 
@@ -348,7 +348,7 @@ bfa_itnim_sm_sler(struct bfa_itnim_s *it
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->bfa, event);
 	}
 }
 
@@ -385,7 +385,7 @@ bfa_itnim_sm_cleanup_offline(struct bfa_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->bfa, event);
 	}
 }
 
@@ -413,7 +413,7 @@ bfa_itnim_sm_cleanup_delete(struct bfa_i
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->bfa, event);
 	}
 }
 
@@ -442,7 +442,7 @@ bfa_itnim_sm_fwdelete(struct bfa_itnim_s
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->bfa, event);
 	}
 }
 
@@ -470,7 +470,7 @@ bfa_itnim_sm_fwdelete_qfull(struct bfa_i
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->bfa, event);
 	}
 }
 
@@ -502,7 +502,7 @@ bfa_itnim_sm_offline(struct bfa_itnim_s
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->bfa, event);
 	}
 }
 
@@ -538,7 +538,7 @@ bfa_itnim_sm_iocdisable(struct bfa_itnim
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->bfa, event);
 	}
 }
 
@@ -559,7 +559,7 @@ bfa_itnim_sm_deleting(struct bfa_itnim_s
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->bfa, event);
 	}
 }
 
@@ -583,7 +583,7 @@ bfa_itnim_sm_deleting_qfull(struct bfa_i
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->bfa, event);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_lps.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_lps.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_lps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_lps.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <bfa.h>
 #include <bfi/bfi_lps.h>
 #include <cs/bfa_debug.h>
+#include <defs/bfa_defs_pci.h>
 
 BFA_TRC_FILE(HAL, LPS);
 BFA_MODULE(lps);
@@ -25,6 +26,12 @@ BFA_MODULE(lps);
 #define BFA_LPS_MIN_LPORTS	(1)
 #define BFA_LPS_MAX_LPORTS	(256)
 
+/*
+ * Maximum Vports supported per physical port or vf.
+ */
+#define BFA_LPS_MAX_VPORTS_SUPP_CB  255
+#define BFA_LPS_MAX_VPORTS_SUPP_CT  190
+
 /**
  * forward declarations
  */
@@ -49,7 +56,7 @@ static void bfa_lps_send_login(struct bf
 static void bfa_lps_send_logout(struct bfa_lps_s *lps);
 static void bfa_lps_login_comp(struct bfa_lps_s *lps);
 static void bfa_lps_logout_comp(struct bfa_lps_s *lps);
-
+static void bfa_lps_cvl_event(struct bfa_lps_s *lps);
 
 /**
  *  lps_pvt BFA LPS private functions
@@ -62,6 +69,7 @@ enum bfa_lps_event {
 	BFA_LPS_SM_RESUME	= 4,	/* space present in reqq queue	*/
 	BFA_LPS_SM_DELETE	= 5,	/* lps delete from user		*/
 	BFA_LPS_SM_OFFLINE	= 6,	/* Link is offline		*/
+	BFA_LPS_SM_RX_CVL       = 7,	/* Rx clear virtual link        */
 };
 
 static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event);
@@ -91,6 +99,12 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, e
 			bfa_sm_set_state(lps, bfa_lps_sm_login);
 			bfa_lps_send_login(lps);
 		}
+		if (lps->fdisc)
+			bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+			BFA_PL_EID_LOGIN, 0, "FDISC Request");
+		else
+			bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+			BFA_PL_EID_LOGIN, 0, "FLOGI Request");
 		break;
 
 	case BFA_LPS_SM_LOGOUT:
@@ -101,6 +115,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, e
 		bfa_lps_free(lps);
 		break;
 
+	case BFA_LPS_SM_RX_CVL:
 	case BFA_LPS_SM_OFFLINE:
 		break;
 
@@ -112,7 +127,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, e
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(lps->bfa, event);
 	}
 }
 
@@ -127,10 +142,25 @@ bfa_lps_sm_login(struct bfa_lps_s *lps,
 
 	switch (event) {
 	case BFA_LPS_SM_FWRSP:
-		if (lps->status == BFA_STATUS_OK)
+		if (lps->status == BFA_STATUS_OK) {
 			bfa_sm_set_state(lps, bfa_lps_sm_online);
-		else
+			if (lps->fdisc)
+				bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+				BFA_PL_EID_LOGIN, 0, "FDISC Accept");
+			else
+				bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+				BFA_PL_EID_LOGIN, 0, "FLOGI Accept");
+		} else {
 			bfa_sm_set_state(lps, bfa_lps_sm_init);
+			if (lps->fdisc)
+				bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+				BFA_PL_EID_LOGIN, 0,
+				"FDISC Fail (RJT or timeout)");
+			else
+				bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+				BFA_PL_EID_LOGIN, 0,
+				"FLOGI Fail (RJT or timeout)");
+		}
 		bfa_lps_login_comp(lps);
 		break;
 
@@ -139,7 +169,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps,
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(lps->bfa, event);
 	}
 }
 
@@ -162,8 +192,16 @@ bfa_lps_sm_loginwait(struct bfa_lps_s *l
 		bfa_reqq_wcancel(&lps->wqe);
 		break;
 
+	case BFA_LPS_SM_RX_CVL:
+		/*
+		 * Login was not even sent out; so when getting out
+		 * of this state, it will appear like a login retry
+		 * after Clear virtual link
+		 */
+		break;
+
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(lps->bfa, event);
 	}
 }
 
@@ -185,6 +223,17 @@ bfa_lps_sm_online(struct bfa_lps_s *lps,
 			bfa_sm_set_state(lps, bfa_lps_sm_logout);
 			bfa_lps_send_logout(lps);
 		}
+		bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+			BFA_PL_EID_LOGO, 0, "Logout");
+		break;
+
+	case BFA_LPS_SM_RX_CVL:
+		bfa_sm_set_state(lps, bfa_lps_sm_init);
+
+		/* Let the vport module know about this event */
+		bfa_lps_cvl_event(lps);
+		bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+			BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
 		break;
 
 	case BFA_LPS_SM_OFFLINE:
@@ -193,7 +242,7 @@ bfa_lps_sm_online(struct bfa_lps_s *lps,
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(lps->bfa, event);
 	}
 }
 
@@ -217,7 +266,7 @@ bfa_lps_sm_logout(struct bfa_lps_s *lps,
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(lps->bfa, event);
 	}
 }
 
@@ -242,7 +291,7 @@ bfa_lps_sm_logowait(struct bfa_lps_s *lp
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(lps->bfa, event);
 	}
 }
 
@@ -396,6 +445,20 @@ bfa_lps_logout_rsp(struct bfa_s *bfa, st
 }
 
 /**
+ * Firmware received a Clear virtual link request (for FCoE)
+ */
+static void
+bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl)
+{
+	struct bfa_lps_mod_s    *mod = BFA_LPS_MOD(bfa);
+	struct bfa_lps_s        *lps;
+
+	lps = BFA_LPS_FROM_TAG(mod, cvl->lp_tag);
+
+	bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL);
+}
+
+/**
  * Space is available in request queue, resume queueing request to firmware.
  */
 static void
@@ -531,7 +594,48 @@ bfa_lps_logout_comp(struct bfa_lps_s *lp
 		bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg);
 }
 
+/**
+ * Clear virtual link completion handler for non-fcs
+ */
+static void
+bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete)
+{
+	struct bfa_lps_s *lps   = arg;
+
+	if (!complete)
+		return;
 
+	/* Clear virtual link to base port will result in link down */
+	if (lps->fdisc)
+		bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
+}
+
+/**
+ * Received Clear virtual link event --direct call for fcs,
+ * queue for others
+ */
+static void
+bfa_lps_cvl_event(struct bfa_lps_s *lps)
+{
+	if (!lps->bfa->fcs) {
+		bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb,
+				lps);
+		return;
+	}
+
+	/* Clear virtual link to base port will result in link down */
+	if (lps->fdisc)
+		bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
+}
+
+u32
+bfa_lps_get_max_vport(struct bfa_s *bfa)
+{
+	if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT)
+		return BFA_LPS_MAX_VPORTS_SUPP_CT;
+	else
+		return BFA_LPS_MAX_VPORTS_SUPP_CB;
+}
 
 /**
  *  lps_public BFA LPS public functions
@@ -752,6 +856,14 @@ bfa_lps_get_lsrjt_expl(struct bfa_lps_s
 	return lps->lsrjt_expl;
 }
 
+/**
+ * Return fpma/spma MAC for lport
+ */
+struct mac_s
+bfa_lps_get_lp_mac(struct bfa_lps_s *lps)
+{
+	return lps->lp_mac;
+}
 
 /**
  * LPS firmware message class handler.
@@ -773,6 +885,10 @@ bfa_lps_isr(struct bfa_s *bfa, struct bf
 		bfa_lps_logout_rsp(bfa, msg.logout_rsp);
 		break;
 
+	case BFI_LPS_H2I_CVL_EVENT:
+		bfa_lps_rx_cvl_event(bfa, msg.cvl_event);
+		break;
+
 	default:
 		bfa_trc(bfa, m->mhdr.msg_id);
 		bfa_assert(0);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_module.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_module.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_module.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_module.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,7 @@
  */
 struct bfa_module_s *hal_mods[] = {
 	&hal_mod_sgpg,
-	&hal_mod_pport,
+	&hal_mod_fcport,
 	&hal_mod_fcxp,
 	&hal_mod_lps,
 	&hal_mod_uf,
@@ -45,7 +45,7 @@ bfa_isr_func_t  bfa_isrs[BFI_MC_MAX] = {
 	bfa_isr_unhandled,	/* BFI_MC_DIAG */
 	bfa_isr_unhandled,	/* BFI_MC_FLASH */
 	bfa_isr_unhandled,	/* BFI_MC_CEE */
-	bfa_pport_isr,		/* BFI_MC_PORT */
+	bfa_fcport_isr,		/* BFI_MC_FCPORT */
 	bfa_isr_unhandled,	/* BFI_MC_IOCFC */
 	bfa_isr_unhandled,	/* BFI_MC_LL */
 	bfa_uf_isr,		/* BFI_MC_UF */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_modules_priv.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_modules_priv.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_modules_priv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_modules_priv.h	2010-05-16 17:17:36.000000000 -0400
@@ -29,7 +29,7 @@
 
 
 struct bfa_modules_s {
-	struct bfa_pport_s	pport;	/*  physical port module	*/
+	struct bfa_fcport_s	fcport;	/*  fc port module	*/
 	struct bfa_fcxp_mod_s fcxp_mod; /*  fcxp module		*/
 	struct bfa_lps_mod_s lps_mod;   /*  fcxp module		*/
 	struct bfa_uf_mod_s uf_mod;	/*  unsolicited frame module	*/
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_port_priv.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_port_priv.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_port_priv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_port_priv.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,9 +23,19 @@
 #include "bfa_intr_priv.h"
 
 /**
- * BFA physical port data structure
+ * Link notification data structure
  */
-struct bfa_pport_s {
+struct bfa_fcport_ln_s {
+	struct bfa_fcport_s     *fcport;
+	bfa_sm_t                sm;
+	struct bfa_cb_qe_s      ln_qe;  /*  BFA callback queue elem for ln */
+	enum bfa_pport_linkstate ln_event; /*  ln event for callback */
+};
+
+/**
+ * BFA FC port data structure
+ */
+struct bfa_fcport_s {
 	struct bfa_s 		*bfa;	/*  parent BFA instance */
 	bfa_sm_t		sm;	/*  port state machine */
 	wwn_t			nwwn;	/*  node wwn of physical port */
@@ -36,6 +46,8 @@ struct bfa_pport_s {
 	enum bfa_pport_topology topology;	/*  current topology */
 	u8			myalpa;	/*  my ALPA in LOOP topology */
 	u8			rsvd[3];
+	u32             mypid:24;
+	u32             rsvd_b:8;
 	struct bfa_pport_cfg_s	cfg;	/*  current port configuration */
 	struct bfa_qos_attr_s  qos_attr;   /* QoS Attributes */
 	struct bfa_qos_vc_attr_s qos_vc_attr;  /*  VC info from ELP */
@@ -49,42 +61,31 @@ struct bfa_pport_s {
 	void			(*event_cbfn) (void *cbarg,
 						bfa_pport_event_t event);
 	union {
-		union bfi_pport_i2h_msg_u i2hmsg;
+		union bfi_fcport_i2h_msg_u i2hmsg;
 	} event_arg;
 	void			*bfad;	/*  BFA driver handle */
+	struct bfa_fcport_ln_s   ln; /* Link Notification */
 	struct bfa_cb_qe_s		hcb_qe;	/*  BFA callback queue elem */
-	enum bfa_pport_linkstate	hcb_event;
-					/*  link event for callback */
+	struct bfa_timer_s      timer;  /*  timer */
 	u32		msgtag;	/*  fimrware msg tag for reply */
 	u8			*stats_kva;
 	u64		stats_pa;
-	union bfa_pport_stats_u *stats;	/*  pport stats */
-	u32		mypid:24;
-	u32		rsvd_b:8;
-	struct bfa_timer_s 	timer;	/*  timer */
-	union bfa_pport_stats_u 	*stats_ret;
-					/*  driver stats location */
-	bfa_status_t		stats_status;
-					/*  stats/statsclr status */
-	bfa_boolean_t   	stats_busy;
-					/*  outstanding stats/statsclr */
-	bfa_boolean_t   	stats_qfull;
-	bfa_boolean_t   	diag_busy;
-					/*  diag busy status */
-	bfa_boolean_t   	beacon;
-					/*  port beacon status */
-	bfa_boolean_t   	link_e2e_beacon;
-					/*  link beacon status */
-	bfa_cb_pport_t		stats_cbfn;
-					/*  driver callback function */
-	void			*stats_cbarg;
-					/* *!< user callback arg */
+	union bfa_fcport_stats_u *stats;
+	union bfa_fcport_stats_u *stats_ret; /*  driver stats location */
+	bfa_status_t            stats_status; /*  stats/statsclr status */
+	bfa_boolean_t           stats_busy; /*  outstanding stats/statsclr */
+	bfa_boolean_t           stats_qfull;
+	bfa_cb_pport_t          stats_cbfn; /*  driver callback function */
+	void                    *stats_cbarg; /* *!< user callback arg */
+	bfa_boolean_t           diag_busy; /*  diag busy status */
+	bfa_boolean_t           beacon; /*  port beacon status */
+	bfa_boolean_t           link_e2e_beacon; /*  link beacon status */
 };
 
-#define BFA_PORT_MOD(__bfa)	(&(__bfa)->modules.pport)
+#define BFA_FCPORT_MOD(__bfa)	(&(__bfa)->modules.fcport)
 
 /*
  * public functions
  */
-void	bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
+void	bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
 #endif /* __BFA_PORT_PRIV_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_priv.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_priv.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_priv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_priv.h	2010-05-16 17:17:36.000000000 -0400
@@ -101,7 +101,7 @@ extern bfa_boolean_t bfa_auto_recover;
 extern struct bfa_module_s hal_mod_flash;
 extern struct bfa_module_s hal_mod_fcdiag;
 extern struct bfa_module_s hal_mod_sgpg;
-extern struct bfa_module_s hal_mod_pport;
+extern struct bfa_module_s hal_mod_fcport;
 extern struct bfa_module_s hal_mod_fcxp;
 extern struct bfa_module_s hal_mod_lps;
 extern struct bfa_module_s hal_mod_uf;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_rport.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_rport.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_rport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_rport.c	2010-05-16 17:17:36.000000000 -0400
@@ -114,7 +114,7 @@ bfa_rport_sm_uninit(struct bfa_rport_s *
 
 	default:
 		bfa_stats(rp, sm_un_unexp);
-		bfa_assert(0);
+		bfa_sm_fault(rp->bfa, event);
 	}
 }
 
@@ -146,7 +146,7 @@ bfa_rport_sm_created(struct bfa_rport_s
 
 	default:
 		bfa_stats(rp, sm_cr_unexp);
-		bfa_assert(0);
+		bfa_sm_fault(rp->bfa, event);
 	}
 }
 
@@ -183,7 +183,7 @@ bfa_rport_sm_fwcreate(struct bfa_rport_s
 
 	default:
 		bfa_stats(rp, sm_fwc_unexp);
-		bfa_assert(0);
+		bfa_sm_fault(rp->bfa, event);
 	}
 }
 
@@ -224,7 +224,7 @@ bfa_rport_sm_fwcreate_qfull(struct bfa_r
 
 	default:
 		bfa_stats(rp, sm_fwc_unexp);
-		bfa_assert(0);
+		bfa_sm_fault(rp->bfa, event);
 	}
 }
 
@@ -296,7 +296,7 @@ bfa_rport_sm_online(struct bfa_rport_s *
 
 	default:
 		bfa_stats(rp, sm_on_unexp);
-		bfa_assert(0);
+		bfa_sm_fault(rp->bfa, event);
 	}
 }
 
@@ -329,7 +329,7 @@ bfa_rport_sm_fwdelete(struct bfa_rport_s
 
 	default:
 		bfa_stats(rp, sm_fwd_unexp);
-		bfa_assert(0);
+		bfa_sm_fault(rp->bfa, event);
 	}
 }
 
@@ -359,7 +359,7 @@ bfa_rport_sm_fwdelete_qfull(struct bfa_r
 
 	default:
 		bfa_stats(rp, sm_fwd_unexp);
-		bfa_assert(0);
+		bfa_sm_fault(rp->bfa, event);
 	}
 }
 
@@ -394,7 +394,7 @@ bfa_rport_sm_offline(struct bfa_rport_s
 
 	default:
 		bfa_stats(rp, sm_off_unexp);
-		bfa_assert(0);
+		bfa_sm_fault(rp->bfa, event);
 	}
 }
 
@@ -421,7 +421,7 @@ bfa_rport_sm_deleting(struct bfa_rport_s
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rp->bfa, event);
 	}
 }
 
@@ -446,7 +446,7 @@ bfa_rport_sm_deleting_qfull(struct bfa_r
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rp->bfa, event);
 	}
 }
 
@@ -477,7 +477,7 @@ bfa_rport_sm_delete_pending(struct bfa_r
 
 	default:
 		bfa_stats(rp, sm_delp_unexp);
-		bfa_assert(0);
+		bfa_sm_fault(rp->bfa, event);
 	}
 }
 
@@ -512,7 +512,7 @@ bfa_rport_sm_offline_pending(struct bfa_
 
 	default:
 		bfa_stats(rp, sm_offp_unexp);
-		bfa_assert(0);
+		bfa_sm_fault(rp->bfa, event);
 	}
 }
 
@@ -550,7 +550,7 @@ bfa_rport_sm_iocdisable(struct bfa_rport
 
 	default:
 		bfa_stats(rp, sm_iocd_unexp);
-		bfa_assert(0);
+		bfa_sm_fault(rp->bfa, event);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_trcmod_priv.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_trcmod_priv.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_trcmod_priv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_trcmod_priv.h	2010-05-16 17:17:36.000000000 -0400
@@ -29,38 +29,36 @@
  * !!! needed between trace utility and driver version
  */
 enum {
-	BFA_TRC_HAL_IOC		= 1,
-	BFA_TRC_HAL_INTR	= 2,
-	BFA_TRC_HAL_FCXP	= 3,
-	BFA_TRC_HAL_UF		= 4,
-	BFA_TRC_HAL_DIAG	= 5,
-	BFA_TRC_HAL_RPORT	= 6,
-	BFA_TRC_HAL_FCPIM	= 7,
-	BFA_TRC_HAL_IOIM	= 8,
-	BFA_TRC_HAL_TSKIM	= 9,
-	BFA_TRC_HAL_ITNIM	= 10,
-	BFA_TRC_HAL_PPORT	= 11,
-	BFA_TRC_HAL_SGPG	= 12,
-	BFA_TRC_HAL_FLASH	= 13,
-	BFA_TRC_HAL_DEBUG	= 14,
-	BFA_TRC_HAL_WWN		= 15,
-	BFA_TRC_HAL_FLASH_RAW	= 16,
-	BFA_TRC_HAL_SBOOT	= 17,
-	BFA_TRC_HAL_SBOOT_IO	= 18,
-	BFA_TRC_HAL_SBOOT_INTR	= 19,
-	BFA_TRC_HAL_SBTEST	= 20,
-	BFA_TRC_HAL_IPFC	= 21,
-	BFA_TRC_HAL_IOCFC	= 22,
-	BFA_TRC_HAL_FCPTM	= 23,
-	BFA_TRC_HAL_IOTM	= 24,
-	BFA_TRC_HAL_TSKTM	= 25,
-	BFA_TRC_HAL_TIN		= 26,
-	BFA_TRC_HAL_LPS		= 27,
-	BFA_TRC_HAL_FCDIAG	= 28,
-	BFA_TRC_HAL_PBIND	= 29,
-	BFA_TRC_HAL_IOCFC_CT	= 30,
-	BFA_TRC_HAL_IOCFC_CB	= 31,
-	BFA_TRC_HAL_IOCFC_Q	= 32,
+	BFA_TRC_HAL_INTR	= 1,
+	BFA_TRC_HAL_FCXP	= 2,
+	BFA_TRC_HAL_UF		= 3,
+	BFA_TRC_HAL_RPORT	= 4,
+	BFA_TRC_HAL_FCPIM	= 5,
+	BFA_TRC_HAL_IOIM	= 6,
+	BFA_TRC_HAL_TSKIM	= 7,
+	BFA_TRC_HAL_ITNIM	= 8,
+	BFA_TRC_HAL_FCPORT	= 9,
+	BFA_TRC_HAL_SGPG	= 10,
+	BFA_TRC_HAL_FLASH	= 11,
+	BFA_TRC_HAL_DEBUG	= 12,
+	BFA_TRC_HAL_WWN		= 13,
+	BFA_TRC_HAL_FLASH_RAW	= 14,
+	BFA_TRC_HAL_SBOOT	= 15,
+	BFA_TRC_HAL_SBOOT_IO	= 16,
+	BFA_TRC_HAL_SBOOT_INTR	= 17,
+	BFA_TRC_HAL_SBTEST	= 18,
+	BFA_TRC_HAL_IPFC	= 19,
+	BFA_TRC_HAL_IOCFC	= 20,
+	BFA_TRC_HAL_FCPTM	= 21,
+	BFA_TRC_HAL_IOTM	= 22,
+	BFA_TRC_HAL_TSKTM	= 23,
+	BFA_TRC_HAL_TIN		= 24,
+	BFA_TRC_HAL_LPS		= 25,
+	BFA_TRC_HAL_FCDIAG	= 26,
+	BFA_TRC_HAL_PBIND	= 27,
+	BFA_TRC_HAL_IOCFC_CT	= 28,
+	BFA_TRC_HAL_IOCFC_CB	= 29,
+	BFA_TRC_HAL_IOCFC_Q	= 30,
 };
 
 #endif /* __BFA_TRCMOD_PRIV_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_tskim.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_tskim.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_tskim.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/bfa_tskim.c	2010-05-16 17:17:36.000000000 -0400
@@ -110,7 +110,7 @@ bfa_tskim_sm_uninit(struct bfa_tskim_s *
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(tskim->bfa, event);
 	}
 }
 
@@ -146,7 +146,7 @@ bfa_tskim_sm_active(struct bfa_tskim_s *
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(tskim->bfa, event);
 	}
 }
 
@@ -178,7 +178,7 @@ bfa_tskim_sm_cleanup(struct bfa_tskim_s
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(tskim->bfa, event);
 	}
 }
 
@@ -207,7 +207,7 @@ bfa_tskim_sm_iocleanup(struct bfa_tskim_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(tskim->bfa, event);
 	}
 }
 
@@ -242,7 +242,7 @@ bfa_tskim_sm_qfull(struct bfa_tskim_s *t
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(tskim->bfa, event);
 	}
 }
 
@@ -277,7 +277,7 @@ bfa_tskim_sm_cleanup_qfull(struct bfa_ts
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(tskim->bfa, event);
 	}
 }
 
@@ -303,7 +303,7 @@ bfa_tskim_sm_hcb(struct bfa_tskim_s *tsk
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(tskim->bfa, event);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fabric.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fabric.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fabric.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fabric.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,7 +37,7 @@ BFA_TRC_FILE(FCS, FABRIC);
 #define BFA_FCS_FABRIC_CLEANUP_DELAY	(10000)	/* Milliseconds */
 
 #define bfa_fcs_fabric_set_opertype(__fabric) do {             \
-	if (bfa_pport_get_topology((__fabric)->fcs->bfa)       \
+	if (bfa_fcport_get_topology((__fabric)->fcs->bfa)       \
 				== BFA_PPORT_TOPOLOGY_P2P)     \
 		(__fabric)->oper_type = BFA_PPORT_TYPE_NPORT;  \
 	else                                                   \
@@ -136,8 +136,7 @@ bfa_fcs_fabric_sm_uninit(struct bfa_fcs_
 	case BFA_FCS_FABRIC_SM_CREATE:
 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
 		bfa_fcs_fabric_init(fabric);
-		bfa_fcs_lport_init(&fabric->bport, fabric->fcs, FC_VF_ID_NULL,
-				   &fabric->bport.port_cfg, NULL);
+		bfa_fcs_lport_init(&fabric->bport, &fabric->bport.port_cfg);
 		break;
 
 	case BFA_FCS_FABRIC_SM_LINK_UP:
@@ -161,7 +160,7 @@ bfa_fcs_fabric_sm_created(struct bfa_fcs
 
 	switch (event) {
 	case BFA_FCS_FABRIC_SM_START:
-		if (bfa_pport_is_linkup(fabric->fcs->bfa)) {
+		if (bfa_fcport_is_linkup(fabric->fcs->bfa)) {
 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
 			bfa_fcs_fabric_login(fabric);
 		} else
@@ -225,7 +224,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_f
 	switch (event) {
 	case BFA_FCS_FABRIC_SM_CONT_OP:
 
-		bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
+		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
 		fabric->fab_type = BFA_FCS_FABRIC_SWITCHED;
 
 		if (fabric->auth_reqd && fabric->is_auth) {
@@ -252,7 +251,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_f
 
 	case BFA_FCS_FABRIC_SM_NO_FABRIC:
 		fabric->fab_type = BFA_FCS_FABRIC_N2N;
-		bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
+		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
 		bfa_fcs_fabric_notify_online(fabric);
 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric);
 		break;
@@ -419,7 +418,7 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fc
 
 	case BFA_FCS_FABRIC_SM_NO_FABRIC:
 		bfa_trc(fabric->fcs, fabric->bb_credit);
-		bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
+		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
 		break;
 
 	default:
@@ -563,17 +562,15 @@ void
 bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
 {
 	struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg;
-	struct bfa_adapter_attr_s adapter_attr;
+	char            model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
 	struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
 
-	bfa_os_memset((void *)&adapter_attr, 0,
-		      sizeof(struct bfa_adapter_attr_s));
-	bfa_ioc_get_adapter_attr(&fabric->fcs->bfa->ioc, &adapter_attr);
+	bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
 
 	/*
 	 * Model name/number
 	 */
-	strncpy((char *)&port_cfg->sym_name, adapter_attr.model,
+	strncpy((char *)&port_cfg->sym_name, model,
 		BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
 	strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
 		sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
@@ -719,10 +716,10 @@ bfa_fcs_fabric_login(struct bfa_fcs_fabr
 	struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg;
 	u8         alpa = 0;
 
-	if (bfa_pport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP)
-		alpa = bfa_pport_get_myalpa(bfa);
+	if (bfa_fcport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP)
+		alpa = bfa_fcport_get_myalpa(bfa);
 
-	bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_pport_get_maxfrsize(bfa),
+	bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa),
 		      pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd);
 
 	fabric->stats.flogi_sent++;
@@ -814,10 +811,10 @@ bfa_fcs_fabric_delete_comp(void *cbarg)
  */
 
 /**
- *   Module initialization
+ *   Attach time initialization
  */
 void
-bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
+bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs)
 {
 	struct bfa_fcs_fabric_s *fabric;
 
@@ -841,7 +838,13 @@ bfa_fcs_fabric_modinit(struct bfa_fcs_s
 	bfa_wc_up(&fabric->wc);	/* For the base port */
 
 	bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
-	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CREATE);
+	bfa_fcs_lport_attach(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, NULL);
+}
+
+void
+bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
+{
+	bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_CREATE);
 	bfa_trc(fcs, 0);
 }
 
@@ -890,6 +893,12 @@ bfa_fcs_fabric_is_loopback(struct bfa_fc
 	return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback);
 }
 
+bfa_boolean_t
+bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric)
+{
+	return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_auth_failed);
+}
+
 enum bfa_pport_type
 bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric)
 {
@@ -1165,8 +1174,8 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa
 	reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
 				    bfa_os_hton3b(FC_FABRIC_PORT),
 				    n2n_port->reply_oxid, pcfg->pwwn,
-				    pcfg->nwwn, bfa_pport_get_maxfrsize(bfa),
-				    bfa_pport_get_rx_bbcredit(bfa));
+				    pcfg->nwwn, bfa_fcport_get_maxfrsize(bfa),
+				    bfa_fcport_get_rx_bbcredit(bfa));
 
 	bfa_fcxp_send(fcxp, NULL, fabric->vf_id, bfa_lps_get_tag(fabric->lps),
 			BFA_FALSE, FC_CLASS_3, reqlen, &fchs,
@@ -1224,14 +1233,8 @@ bfa_fcs_fabric_aen_post(struct bfa_fcs_p
 	wwn2str(pwwn_ptr, pwwn);
 	wwn2str(fwwn_ptr, fwwn);
 
-	switch (event) {
-	case BFA_PORT_AEN_FABRIC_NAME_CHANGE:
-		bfa_log(logmod, BFA_AEN_PORT_FABRIC_NAME_CHANGE, pwwn_ptr,
-			fwwn_ptr);
-		break;
-	default:
-		break;
-	}
+	bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event),
+		pwwn_ptr, fwwn_ptr);
 
 	aen_data.port.pwwn = pwwn;
 	aen_data.port.fwwn = fwwn;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcbuild.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcbuild.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcbuild.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcbuild.h	2010-05-16 17:17:36.000000000 -0400
@@ -72,6 +72,9 @@ fc_rpsc_operspeed_to_bfa_speed(enum fc_r
 	case RPSC_OP_SPEED_8G:
 		return BFA_PPORT_SPEED_8GBPS;
 
+	case RPSC_OP_SPEED_10G:
+		return BFA_PPORT_SPEED_10GBPS;
+
 	default:
 		return BFA_PPORT_SPEED_UNKNOWN;
 	}
@@ -97,6 +100,9 @@ fc_bfa_speed_to_rpsc_operspeed(enum bfa_
 	case BFA_PPORT_SPEED_8GBPS:
 		return RPSC_OP_SPEED_8G;
 
+	case BFA_PPORT_SPEED_10GBPS:
+		return RPSC_OP_SPEED_10G;
+
 	default:
 		return RPSC_OP_SPEED_NOT_EST;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcpim.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcpim.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcpim.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcpim.c	2010-05-16 17:17:36.000000000 -0400
@@ -126,7 +126,7 @@ bfa_fcs_itnim_sm_offline(struct bfa_fcs_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->fcs, event);
 	}
 
 }
@@ -161,7 +161,7 @@ bfa_fcs_itnim_sm_prli_send(struct bfa_fc
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->fcs, event);
 	}
 }
 
@@ -205,7 +205,7 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itn
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->fcs, event);
 	}
 }
 
@@ -240,7 +240,7 @@ bfa_fcs_itnim_sm_prli_retry(struct bfa_f
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->fcs, event);
 	}
 }
 
@@ -270,7 +270,7 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_f
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->fcs, event);
 	}
 }
 
@@ -298,7 +298,7 @@ bfa_fcs_itnim_sm_online(struct bfa_fcs_i
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->fcs, event);
 	}
 }
 
@@ -321,7 +321,7 @@ bfa_fcs_itnim_sm_hcb_offline(struct bfa_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->fcs, event);
 	}
 }
 
@@ -354,7 +354,7 @@ bfa_fcs_itnim_sm_initiator(struct bfa_fc
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(itnim->fcs, event);
 	}
 }
 
@@ -385,19 +385,8 @@ bfa_fcs_itnim_aen_post(struct bfa_fcs_it
 	wwn2str(lpwwn_ptr, lpwwn);
 	wwn2str(rpwwn_ptr, rpwwn);
 
-	switch (event) {
-	case BFA_ITNIM_AEN_ONLINE:
-		bfa_log(logmod, BFA_AEN_ITNIM_ONLINE, rpwwn_ptr, lpwwn_ptr);
-		break;
-	case BFA_ITNIM_AEN_OFFLINE:
-		bfa_log(logmod, BFA_AEN_ITNIM_OFFLINE, rpwwn_ptr, lpwwn_ptr);
-		break;
-	case BFA_ITNIM_AEN_DISCONNECT:
-		bfa_log(logmod, BFA_AEN_ITNIM_DISCONNECT, rpwwn_ptr, lpwwn_ptr);
-		break;
-	default:
-		break;
-	}
+	bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_ITNIM, event),
+		rpwwn_ptr, lpwwn_ptr);
 
 	aen_data.itnim.vf_id = rport->port->fabric->vf_id;
 	aen_data.itnim.ppwwn =
@@ -689,7 +678,6 @@ bfa_cb_itnim_tov_begin(void *cb_arg)
 	struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg;
 
 	bfa_trc(itnim->fcs, itnim->rport->pwwn);
-	bfa_fcb_itnim_tov_begin(itnim->itnim_drv);
 }
 
 /**
@@ -822,22 +810,3 @@ void
 bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim)
 {
 }
-
-/**
- *   Module initialization
- */
-void
-bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs)
-{
-}
-
-/**
- *   Module cleanup
- */
-void
-bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs)
-{
-	bfa_fcs_modexit_comp(fcs);
-}
-
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs_fabric.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcs_fabric.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs_fabric.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcs_fabric.h	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 /*
 * fcs friend functions: only between fcs modules
  */
+void		bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs);
 void            bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs);
 void            bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs);
 void            bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs);
@@ -46,6 +47,7 @@ void            bfa_fcs_fabric_uf_recv(s
 			struct fchs_s *fchs, u16 len);
 u16        bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric);
 bfa_boolean_t   bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric);
+bfa_boolean_t	bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric);
 enum bfa_pport_type bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric);
 void     	bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric);
 void bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs_fcpim.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcs_fcpim.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs_fcpim.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcs_fcpim.h	2010-05-16 17:17:36.000000000 -0400
@@ -34,11 +34,6 @@ void bfa_fcs_itnim_is_initiator(struct b
 void bfa_fcs_itnim_pause(struct bfa_fcs_itnim_s *itnim);
 void bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim);
 
-/*
- * Modudle init/cleanup routines.
- */
-void bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs);
 void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs,
 			u16 len);
 #endif /* __FCS_FCPIM_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs_lport.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcs_lport.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs_lport.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcs_lport.h	2010-05-16 17:17:36.000000000 -0400
@@ -84,9 +84,10 @@ void bfa_fcs_port_uf_recv(struct bfa_fcs
  * Following routines will be called by Fabric to indicate port
  * online/offline to vport.
  */
-void bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
-			u16 vf_id, struct bfa_port_cfg_s *port_cfg,
-			struct bfa_fcs_vport_s *vport);
+void bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
+			uint16_t vf_id, struct bfa_fcs_vport_s *vport);
+void bfa_fcs_lport_init(struct bfa_fcs_port_s *lport,
+			struct bfa_port_cfg_s *port_cfg);
 void bfa_fcs_port_online(struct bfa_fcs_port_s *port);
 void bfa_fcs_port_offline(struct bfa_fcs_port_s *port);
 void bfa_fcs_port_delete(struct bfa_fcs_port_s *port);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs_port.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcs_port.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs_port.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcs_port.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 /*
  * fcs friend functions: only between fcs modules
  */
-void bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs);
+void bfa_fcs_pport_attach(struct bfa_fcs_s *fcs);
 
 #endif /* __FCS_PPORT_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs_rport.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcs_rport.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs_rport.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcs_rport.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,9 +24,6 @@
 
 #include <fcs/bfa_fcs_rport.h>
 
-void bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs);
-
 void bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs,
 			u16 len);
 void bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs_uf.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcs_uf.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs_uf.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcs_uf.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 /*
  * fcs friend functions: only between fcs modules
  */
-void bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs);
+void bfa_fcs_uf_attach(struct bfa_fcs_s *fcs);
 
 #endif /* __FCS_UF_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs_vport.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcs_vport.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs_vport.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fcs_vport.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,18 +22,10 @@
 #include <fcs/bfa_fcs_vport.h>
 #include <defs/bfa_defs_pci.h>
 
-/*
- * Modudle init/cleanup routines.
- */
-
-void bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs);
-
 void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport);
 void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport);
 void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport);
 void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport);
-u32 bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs);
 
 #endif /* __FCS_VPORT_H__ */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fdmi.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fdmi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fdmi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/fdmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -116,6 +116,9 @@ static void     bfa_fcs_port_fdmi_sm_rpa
 			enum port_fdmi_event event);
 static void     bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
 			enum port_fdmi_event event);
+static void	bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi,
+			enum port_fdmi_event event);
+
 /**
  * 		Start in offline state - awaiting MS to send start.
  */
@@ -155,7 +158,7 @@ bfa_fcs_port_fdmi_sm_offline(struct bfa_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
@@ -180,7 +183,7 @@ bfa_fcs_port_fdmi_sm_sending_rhba(struct
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
@@ -227,7 +230,7 @@ bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
@@ -255,7 +258,7 @@ bfa_fcs_port_fdmi_sm_rhba_retry(struct b
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
@@ -283,7 +286,7 @@ bfa_fcs_port_fdmi_sm_sending_rprt(struct
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
@@ -328,7 +331,7 @@ bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
@@ -356,7 +359,7 @@ bfa_fcs_port_fdmi_sm_rprt_retry(struct b
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
@@ -384,7 +387,7 @@ bfa_fcs_port_fdmi_sm_sending_rpa(struct
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
@@ -428,7 +431,7 @@ bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
@@ -456,7 +459,7 @@ bfa_fcs_port_fdmi_sm_rpa_retry(struct bf
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
@@ -475,10 +478,24 @@ bfa_fcs_port_fdmi_sm_online(struct bfa_f
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(port->fcs, event);
 	}
 }
 
+/**
+ *  FDMI is disabled state.
+ */
+static void
+bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi,
+				enum port_fdmi_event event)
+{
+	struct bfa_fcs_port_s *port = fdmi->ms->port;
+
+	bfa_trc(port->fcs, port->port_cfg.pwwn);
+	bfa_trc(port->fcs, event);
+
+	/* No op State. It can only be enabled at Driver Init. */
+}
 
 /**
 *   RHBA : Register HBA Attributes.
@@ -1097,36 +1114,23 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_
 {
 	struct bfa_fcs_port_s *port = fdmi->ms->port;
 	struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
-	struct bfa_adapter_attr_s adapter_attr;
 
 	bfa_os_memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
-	bfa_os_memset(&adapter_attr, 0, sizeof(struct bfa_adapter_attr_s));
-
-	bfa_ioc_get_adapter_attr(&port->fcs->bfa->ioc, &adapter_attr);
-
-	strncpy(hba_attr->manufacturer, adapter_attr.manufacturer,
-		sizeof(adapter_attr.manufacturer));
-
-	strncpy(hba_attr->serial_num, adapter_attr.serial_num,
-		sizeof(adapter_attr.serial_num));
-
-	strncpy(hba_attr->model, adapter_attr.model, sizeof(hba_attr->model));
 
-	strncpy(hba_attr->model_desc, adapter_attr.model_descr,
-		sizeof(hba_attr->model_desc));
-
-	strncpy(hba_attr->hw_version, adapter_attr.hw_ver,
-		sizeof(hba_attr->hw_version));
+	bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc,
+		hba_attr->manufacturer);
+	bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc,
+						hba_attr->serial_num);
+	bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, hba_attr->model);
+	bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, hba_attr->model_desc);
+	bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc, hba_attr->hw_version);
+	bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc,
+		hba_attr->option_rom_ver);
+	bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc, hba_attr->fw_version);
 
 	strncpy(hba_attr->driver_version, (char *)driver_info->version,
 		sizeof(hba_attr->driver_version));
 
-	strncpy(hba_attr->option_rom_ver, adapter_attr.optrom_ver,
-		sizeof(hba_attr->option_rom_ver));
-
-	strncpy(hba_attr->fw_version, adapter_attr.fw_ver,
-		sizeof(hba_attr->fw_version));
-
 	strncpy(hba_attr->os_name, driver_info->host_os_name,
 		sizeof(hba_attr->os_name));
 
@@ -1158,7 +1162,7 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs
 	/*
 	 * get pport attributes from hal
 	 */
-	bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
+	bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
 
 	/*
 	 * get FC4 type Bitmask
@@ -1201,7 +1205,10 @@ bfa_fcs_port_fdmi_init(struct bfa_fcs_po
 	struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
 
 	fdmi->ms = ms;
-	bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
+	if (ms->port->fcs->fdmi_enabled)
+		bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
+	else
+		bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_disabled);
 }
 
 void
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/aen/bfa_aen.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/aen/bfa_aen.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/aen/bfa_aen.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/aen/bfa_aen.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,21 +18,24 @@
 #define __BFA_AEN_H__
 
 #include "defs/bfa_defs_aen.h"
+#include "defs/bfa_defs_status.h"
+#include "cs/bfa_debug.h"
 
-#define BFA_AEN_MAX_ENTRY   512
+#define BFA_AEN_MAX_ENTRY	512
 
-extern s32 bfa_aen_max_cfg_entry;
+extern int bfa_aen_max_cfg_entry;
 struct bfa_aen_s {
 	void		*bfad;
-	s32		max_entry;
-	s32		write_index;
-	s32		read_index;
-	u32	bfad_num;
-	u32	seq_num;
+	int		max_entry;
+	int		write_index;
+	int		read_index;
+	int		bfad_num;
+	int		seq_num;
 	void		(*aen_cb_notify)(void *bfad);
 	void		(*gettimeofday)(struct bfa_timeval_s *tv);
-	struct bfa_trc_mod_s 	*trcmod;
-	struct bfa_aen_entry_s	list[BFA_AEN_MAX_ENTRY]; /* Must be the last */
+	struct bfa_trc_mod_s *trcmod;
+	int		app_ri[BFA_AEN_MAX_APP]; /* For multiclient support */
+	struct bfa_aen_entry_s list[BFA_AEN_MAX_ENTRY]; /* Must be the last */
 };
 
 
@@ -45,48 +48,49 @@ bfa_aen_set_max_cfg_entry(int max_entry)
 	bfa_aen_max_cfg_entry = max_entry;
 }
 
-static inline s32
+static inline int
 bfa_aen_get_max_cfg_entry(void)
 {
 	return bfa_aen_max_cfg_entry;
 }
 
-static inline s32
+static inline int
 bfa_aen_get_meminfo(void)
 {
 	return sizeof(struct bfa_aen_entry_s) * bfa_aen_get_max_cfg_entry();
 }
 
-static inline s32
+static inline int
 bfa_aen_get_wi(struct bfa_aen_s *aen)
 {
 	return aen->write_index;
 }
 
-static inline s32
+static inline int
 bfa_aen_get_ri(struct bfa_aen_s *aen)
 {
 	return aen->read_index;
 }
 
-static inline s32
-bfa_aen_fetch_count(struct bfa_aen_s *aen, s32 read_index)
+static inline int
+bfa_aen_fetch_count(struct bfa_aen_s *aen, enum bfa_aen_app  app_id)
 {
-	return ((aen->write_index + aen->max_entry) - read_index)
+	bfa_assert((app_id < BFA_AEN_MAX_APP) && (app_id >= bfa_aen_app_bcu));
+	return ((aen->write_index + aen->max_entry) - aen->app_ri[app_id])
 		% aen->max_entry;
 }
 
-s32 bfa_aen_init(struct bfa_aen_s *aen, struct bfa_trc_mod_s *trcmod,
-		void *bfad, u32 inst_id, void (*aen_cb_notify)(void *),
+int bfa_aen_init(struct bfa_aen_s *aen, struct bfa_trc_mod_s *trcmod,
+		void *bfad, int bfad_num, void (*aen_cb_notify)(void *),
 		void (*gettimeofday)(struct bfa_timeval_s *));
 
-s32 bfa_aen_post(struct bfa_aen_s *aen, enum bfa_aen_category aen_category,
+void bfa_aen_post(struct bfa_aen_s *aen, enum bfa_aen_category aen_category,
 		     int aen_type, union bfa_aen_data_u *aen_data);
 
-s32 bfa_aen_fetch(struct bfa_aen_s *aen, struct bfa_aen_entry_s *aen_entry,
-		      s32 entry_space, s32 rii, s32 *ri_arr,
-		      s32 ri_arr_cnt);
+bfa_status_t bfa_aen_fetch(struct bfa_aen_s *aen,
+			struct bfa_aen_entry_s *aen_entry,
+			int entry_req, enum bfa_aen_app app_id, int *entry_ret);
 
-s32 bfa_aen_get_inst(struct bfa_aen_s *aen);
+int bfa_aen_get_inst(struct bfa_aen_s *aen);
 
 #endif /* __BFA_AEN_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfa.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfa.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfa.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfa.h	2010-05-16 17:17:36.000000000 -0400
@@ -106,6 +106,26 @@ struct bfa_sge_s {
 	bfa_ioc_fetch_stats(&(__bfa)->ioc, __ioc_stats)
 #define bfa_ioc_clear_stats(__bfa)	\
 	bfa_ioc_clr_stats(&(__bfa)->ioc)
+#define bfa_get_nports(__bfa)   \
+	bfa_ioc_get_nports(&(__bfa)->ioc)
+#define bfa_get_adapter_manufacturer(__bfa, __manufacturer) \
+	bfa_ioc_get_adapter_manufacturer(&(__bfa)->ioc, __manufacturer)
+#define bfa_get_adapter_model(__bfa, __model)   \
+	bfa_ioc_get_adapter_model(&(__bfa)->ioc, __model)
+#define bfa_get_adapter_serial_num(__bfa, __serial_num) \
+	bfa_ioc_get_adapter_serial_num(&(__bfa)->ioc, __serial_num)
+#define bfa_get_adapter_fw_ver(__bfa, __fw_ver) \
+	bfa_ioc_get_adapter_fw_ver(&(__bfa)->ioc, __fw_ver)
+#define bfa_get_adapter_optrom_ver(__bfa, __optrom_ver) \
+	bfa_ioc_get_adapter_optrom_ver(&(__bfa)->ioc, __optrom_ver)
+#define bfa_get_pci_chip_rev(__bfa, __chip_rev) \
+	bfa_ioc_get_pci_chip_rev(&(__bfa)->ioc, __chip_rev)
+#define bfa_get_ioc_state(__bfa)    \
+	bfa_ioc_get_state(&(__bfa)->ioc)
+#define bfa_get_type(__bfa) \
+	bfa_ioc_get_type(&(__bfa)->ioc)
+#define bfa_get_mac(__bfa)  \
+	bfa_ioc_get_mac(&(__bfa)->ioc)
 
 /*
  * bfa API functions
@@ -161,6 +181,7 @@ bfa_status_t bfa_iocfc_israttr_set(struc
 void bfa_iocfc_enable(struct bfa_s *bfa);
 void bfa_iocfc_disable(struct bfa_s *bfa);
 void bfa_ioc_auto_recover(bfa_boolean_t auto_recover);
+void bfa_chip_reset(struct bfa_s *bfa);
 void bfa_cb_ioc_disable(void *bfad);
 void bfa_timer_tick(struct bfa_s *bfa);
 #define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout)	\
@@ -171,6 +192,7 @@ void bfa_timer_tick(struct bfa_s *bfa);
  */
 bfa_status_t bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen);
 bfa_status_t bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen);
+void bfa_debug_fwsave_clear(struct bfa_s *bfa);
 
 #include "bfa_priv.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfa_svc.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfa_svc.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfa_svc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfa_svc.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@ struct bfa_fcxp_s;
 #include <defs/bfa_defs_pport.h>
 #include <defs/bfa_defs_rport.h>
 #include <defs/bfa_defs_qos.h>
+#include <defs/bfa_defs_fcport.h>
 #include <cs/bfa_sm.h>
 #include <bfa.h>
 
@@ -35,7 +36,7 @@ struct bfa_fcxp_s;
 struct bfa_rport_info_s {
 	u16        max_frmsz;	/*  max rcv pdu size               */
 	u32        pid:24,		/*  remote port ID                 */
-			lp_tag:8;
+			lp_tag:8;	/*  tag                     */
 	u32        local_pid:24,	/*  local port ID		    */
 			cisc:8;		/*  CIRO supported		    */
 	u8         fc_class;	/*  supported FC classes. enum fc_cos */
@@ -54,7 +55,7 @@ struct bfa_rport_s {
 	void                  *rport_drv; /*  fcs/driver rport object */
 	u16              fw_handle; /*  firmware rport handle */
 	u16              rport_tag; /*  BFA rport tag */
-	struct bfa_rport_info_s rport_info; /*  rport info from *fcs/driver */
+	struct bfa_rport_info_s rport_info; /*  rport info from fcs/driver */
 	struct bfa_reqq_wait_s reqq_wait; /*  to wait for room in reqq */
 	struct bfa_cb_qe_s    hcb_qe;	 /*  BFA callback qelem */
 	struct bfa_rport_hal_stats_s stats; /*  BFA rport statistics  */
@@ -101,7 +102,7 @@ struct bfa_uf_buf_s {
 struct bfa_uf_s {
 	struct list_head	qe;		/*  queue element	  */
 	struct bfa_s	*bfa;		/*  bfa instance	  */
-	u16        uf_tag;		/*  identifying tag f/w messages */
+	u16        uf_tag;		/*  identifying tag fw msgs     */
 	u16        vf_id;
 	u16        src_rport_handle;
 	u16        rsvd;
@@ -127,7 +128,7 @@ struct bfa_lps_s {
 	u8		reqq;		/*  lport request queue	*/
 	u8		alpa;		/*  ALPA for loop topologies	*/
 	u32	lp_pid;		/*  lport port ID		*/
-	bfa_boolean_t	fdisc;		/*  send FDISC instead of FLOGI*/
+	bfa_boolean_t	fdisc;		/*  send FDISC instead of FLOGI  */
 	bfa_boolean_t	auth_en;	/*  enable authentication	*/
 	bfa_boolean_t	auth_req;	/*  authentication required	*/
 	bfa_boolean_t	npiv_en;	/*  NPIV is allowed by peer	*/
@@ -151,60 +152,69 @@ struct bfa_lps_s {
 	bfa_eproto_status_t	ext_status;
 };
 
+#define BFA_FCPORT(_bfa)        (&((_bfa)->modules.port))
+
 /*
  * bfa pport API functions
  */
-bfa_status_t bfa_pport_enable(struct bfa_s *bfa);
-bfa_status_t bfa_pport_disable(struct bfa_s *bfa);
-bfa_status_t bfa_pport_cfg_speed(struct bfa_s *bfa,
+bfa_status_t bfa_fcport_enable(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_disable(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_cfg_speed(struct bfa_s *bfa,
 			enum bfa_pport_speed speed);
-enum bfa_pport_speed bfa_pport_get_speed(struct bfa_s *bfa);
-bfa_status_t bfa_pport_cfg_topology(struct bfa_s *bfa,
+enum bfa_pport_speed bfa_fcport_get_speed(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_cfg_topology(struct bfa_s *bfa,
 			enum bfa_pport_topology topo);
-enum bfa_pport_topology bfa_pport_get_topology(struct bfa_s *bfa);
-bfa_status_t bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa);
-bfa_boolean_t bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa);
-u8 bfa_pport_get_myalpa(struct bfa_s *bfa);
-bfa_status_t bfa_pport_clr_hardalpa(struct bfa_s *bfa);
-bfa_status_t bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxsize);
-u16 bfa_pport_get_maxfrsize(struct bfa_s *bfa);
-u32 bfa_pport_mypid(struct bfa_s *bfa);
-u8 bfa_pport_get_rx_bbcredit(struct bfa_s *bfa);
-bfa_status_t bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap);
-bfa_status_t bfa_pport_trunk_disable(struct bfa_s *bfa);
-bfa_boolean_t bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap);
-void bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr);
-wwn_t bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node);
-bfa_status_t bfa_pport_get_stats(struct bfa_s *bfa,
-			union bfa_pport_stats_u *stats,
-			bfa_cb_pport_t cbfn, void *cbarg);
-bfa_status_t bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
-			void *cbarg);
-void bfa_pport_event_register(struct bfa_s *bfa,
+enum bfa_pport_topology bfa_fcport_get_topology(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa);
+bfa_boolean_t bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa);
+u8 bfa_fcport_get_myalpa(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_clr_hardalpa(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxsize);
+u16 bfa_fcport_get_maxfrsize(struct bfa_s *bfa);
+u32 bfa_fcport_mypid(struct bfa_s *bfa);
+u8 bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap);
+bfa_status_t bfa_fcport_trunk_disable(struct bfa_s *bfa);
+bfa_boolean_t bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap);
+void bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr);
+wwn_t bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node);
+void bfa_fcport_event_register(struct bfa_s *bfa,
 			void (*event_cbfn) (void *cbarg,
 			bfa_pport_event_t event), void *event_cbarg);
-bfa_boolean_t bfa_pport_is_disabled(struct bfa_s *bfa);
-void bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off);
-void bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off);
-bfa_status_t bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa,
+bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa);
+void bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off);
+void bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off);
+bfa_status_t bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa,
 			enum bfa_pport_speed speed);
-enum bfa_pport_speed bfa_pport_get_ratelim_speed(struct bfa_s *bfa);
+enum bfa_pport_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa);
 
-void bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit);
-void bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status);
-void bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
+void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit);
+void bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status);
+void bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
 			bfa_boolean_t link_e2e_beacon);
 void bfa_cb_pport_event(void *cbarg, bfa_pport_event_t event);
-void bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr);
-void bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
+void bfa_fcport_qos_get_attr(struct bfa_s *bfa,
+			struct bfa_qos_attr_s *qos_attr);
+void bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
 			struct bfa_qos_vc_attr_s *qos_vc_attr);
-bfa_status_t bfa_pport_get_qos_stats(struct bfa_s *bfa,
-			union bfa_pport_stats_u *stats,
+bfa_status_t bfa_fcport_get_qos_stats(struct bfa_s *bfa,
+			union bfa_fcport_stats_u *stats,
 			bfa_cb_pport_t cbfn, void *cbarg);
-bfa_status_t bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
+bfa_status_t bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
 			void *cbarg);
-bfa_boolean_t     bfa_pport_is_ratelim(struct bfa_s *bfa);
-bfa_boolean_t	bfa_pport_is_linkup(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_get_fcoe_stats(struct bfa_s *bfa,
+			union bfa_fcport_stats_u *stats,
+			bfa_cb_pport_t cbfn, void *cbarg);
+bfa_status_t bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
+			void *cbarg);
+
+bfa_boolean_t     bfa_fcport_is_ratelim(struct bfa_s *bfa);
+bfa_boolean_t	bfa_fcport_is_linkup(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_get_stats(struct bfa_s *bfa,
+		union bfa_fcport_stats_u *stats,
+		bfa_cb_pport_t cbfn, void *cbarg);
+bfa_status_t bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
+		void *cbarg);
 
 /*
  * bfa rport API functions
@@ -293,6 +303,7 @@ void bfa_uf_free(struct bfa_uf_s *uf);
  * bfa lport service api
  */
 
+u32	bfa_lps_get_max_vport(struct bfa_s *bfa);
 struct bfa_lps_s *bfa_lps_alloc(struct bfa_s *bfa);
 void bfa_lps_delete(struct bfa_lps_s *lps);
 void bfa_lps_discard(struct bfa_lps_s *lps);
@@ -315,10 +326,12 @@ wwn_t bfa_lps_get_peer_pwwn(struct bfa_l
 wwn_t bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps);
 u8 bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps);
 u8 bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps);
+mac_t bfa_lps_get_lp_mac(struct bfa_lps_s *lps);
 void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status);
 void bfa_cb_lps_flogo_comp(void *bfad, void *uarg);
 void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status);
 void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg);
+void bfa_cb_lps_cvl_event(void *bfad, void *uarg);
 
 #endif /* __BFA_SVC_H__ */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfa_timer.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfa_timer.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfa_timer.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfa_timer.h	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,7 @@ struct bfa_timer_mod_s {
 	struct list_head timer_q;
 };
 
-#define BFA_TIMER_FREQ 500 /**< specified in millisecs */
+#define BFA_TIMER_FREQ 200 /**< specified in millisecs */
 
 void bfa_timer_beat(struct bfa_timer_mod_s *mod);
 void bfa_timer_init(struct bfa_timer_mod_s *mod);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_cbreg.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfi/bfi_cbreg.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_cbreg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfi/bfi_cbreg.h	2010-05-16 17:17:36.000000000 -0400
@@ -177,7 +177,21 @@
 #define __PSS_LMEM_INIT_EN               0x00000100
 #define __PSS_LPU1_RESET                 0x00000002
 #define __PSS_LPU0_RESET                 0x00000001
-
+#define PSS_ERR_STATUS_REG		 0x00018810
+#define __PSS_LMEM1_CORR_ERR		 0x00000800
+#define __PSS_LMEM0_CORR_ERR             0x00000400
+#define __PSS_LMEM1_UNCORR_ERR           0x00000200
+#define __PSS_LMEM0_UNCORR_ERR           0x00000100
+#define __PSS_BAL_PERR                   0x00000080
+#define __PSS_DIP_IF_ERR                 0x00000040
+#define __PSS_IOH_IF_ERR                 0x00000020
+#define __PSS_TDS_IF_ERR                 0x00000010
+#define __PSS_RDS_IF_ERR                 0x00000008
+#define __PSS_SGM_IF_ERR                 0x00000004
+#define __PSS_LPU1_RAM_ERR               0x00000002
+#define __PSS_LPU0_RAM_ERR               0x00000001
+#define ERR_SET_REG			 0x00018818
+#define __PSS_ERR_STATUS_SET		 0x00000fff
 
 /*
  * These definitions are either in error/missing in spec. Its auto-generated
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_ctreg.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_ctreg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfi/bfi_ctreg.h	2010-05-16 17:17:36.000000000 -0400
@@ -430,6 +430,31 @@ enum {
 #define __PSS_LMEM_INIT_EN               0x00000100
 #define __PSS_LPU1_RESET                 0x00000002
 #define __PSS_LPU0_RESET                 0x00000001
+#define PSS_ERR_STATUS_REG               0x00018810
+#define __PSS_LPU1_TCM_READ_ERR          0x00200000
+#define __PSS_LPU0_TCM_READ_ERR          0x00100000
+#define __PSS_LMEM5_CORR_ERR             0x00080000
+#define __PSS_LMEM4_CORR_ERR             0x00040000
+#define __PSS_LMEM3_CORR_ERR             0x00020000
+#define __PSS_LMEM2_CORR_ERR             0x00010000
+#define __PSS_LMEM1_CORR_ERR             0x00008000
+#define __PSS_LMEM0_CORR_ERR             0x00004000
+#define __PSS_LMEM5_UNCORR_ERR           0x00002000
+#define __PSS_LMEM4_UNCORR_ERR           0x00001000
+#define __PSS_LMEM3_UNCORR_ERR           0x00000800
+#define __PSS_LMEM2_UNCORR_ERR           0x00000400
+#define __PSS_LMEM1_UNCORR_ERR           0x00000200
+#define __PSS_LMEM0_UNCORR_ERR           0x00000100
+#define __PSS_BAL_PERR                   0x00000080
+#define __PSS_DIP_IF_ERR                 0x00000040
+#define __PSS_IOH_IF_ERR                 0x00000020
+#define __PSS_TDS_IF_ERR                 0x00000010
+#define __PSS_RDS_IF_ERR                 0x00000008
+#define __PSS_SGM_IF_ERR                 0x00000004
+#define __PSS_LPU1_RAM_ERR               0x00000002
+#define __PSS_LPU0_RAM_ERR               0x00000001
+#define ERR_SET_REG			 0x00018818
+#define __PSS_ERR_STATUS_SET		 0x003fffff
 #define HQM_QSET0_RXQ_DRBL_P0            0x00038000
 #define __RXQ0_ADD_VECTORS_P             0x80000000
 #define __RXQ0_STOP_P                    0x40000000
@@ -589,6 +614,7 @@ enum {
 #define __HFN_INT_MBOX_LPU1                0x00200000U
 #define __HFN_INT_MBOX1_LPU0               0x00400000U
 #define __HFN_INT_MBOX1_LPU1               0x00800000U
+#define __HFN_INT_LL_HALT		   0x01000000U
 #define __HFN_INT_CPE_MASK                 0x000000ffU
 #define __HFN_INT_RME_MASK                 0x0000ff00U
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfi/bfi.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfi/bfi.h	2010-05-16 17:17:36.000000000 -0400
@@ -143,8 +143,8 @@ enum bfi_mclass {
 	BFI_MC_IOC		= 1,	/*  IO Controller (IOC)	    */
 	BFI_MC_DIAG		= 2,	/*  Diagnostic Msgs		    */
 	BFI_MC_FLASH		= 3,	/*  Flash message class	    */
-	BFI_MC_CEE		= 4,
-	BFI_MC_FC_PORT		= 5,	/*  FC port		   	    */
+	BFI_MC_CEE		= 4,	/*  CEE                     */
+	BFI_MC_FCPORT		= 5,	/*  FC port		   	    */
 	BFI_MC_IOCFC		= 6,	/*  FC - IO Controller (IOC)	    */
 	BFI_MC_LL		= 7,	/*  Link Layer		 	    */
 	BFI_MC_UF		= 8,	/*  Unsolicited frame receive	    */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_ioc.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfi/bfi_ioc.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_ioc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfi/bfi_ioc.h	2010-05-16 17:17:36.000000000 -0400
@@ -123,7 +123,7 @@ enum bfi_ioc_state {
 	BFI_IOC_DISABLING 	 = 5,	/*  IOC is being disabled           */
 	BFI_IOC_DISABLED 	 = 6,	/*  IOC is disabled                 */
 	BFI_IOC_CFG_DISABLED = 7,	/*  IOC is being disabled;transient */
-	BFI_IOC_HBFAIL       = 8,	/*  IOC heart-beat failure          */
+	BFI_IOC_FAIL       = 8,		/*  IOC heart-beat failure          */
 	BFI_IOC_MEMTEST      = 9,	/*  IOC is doing memtest            */
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_lps.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfi/bfi_lps.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_lps.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfi/bfi_lps.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@ enum bfi_lps_h2i_msgs {
 enum bfi_lps_i2h_msgs {
 	BFI_LPS_H2I_LOGIN_RSP	= BFA_I2HM(1),
 	BFI_LPS_H2I_LOGOUT_RSP	= BFA_I2HM(2),
+	BFI_LPS_H2I_CVL_EVENT   = BFA_I2HM(3),
 };
 
 struct bfi_lps_login_req_s {
@@ -77,6 +78,12 @@ struct bfi_lps_logout_rsp_s {
 	u8		rsvd[2];
 };
 
+struct bfi_lps_cvl_event_s {
+	struct bfi_mhdr_s  mh;      /* common msg header      */
+	u8		lp_tag;
+	u8		rsvd[3];
+};
+
 union bfi_lps_h2i_msg_u {
 	struct bfi_mhdr_s		*msg;
 	struct bfi_lps_login_req_s	*login_req;
@@ -87,6 +94,7 @@ union bfi_lps_i2h_msg_u {
 	struct bfi_msg_s		*msg;
 	struct bfi_lps_login_rsp_s	*login_rsp;
 	struct bfi_lps_logout_rsp_s	*logout_rsp;
+	struct bfi_lps_cvl_event_s	*cvl_event;
 };
 
 #pragma pack()
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_pport.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfi/bfi_pport.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_pport.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/bfi/bfi_pport.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,163 +22,97 @@
 
 #pragma pack(1)
 
-enum bfi_pport_h2i {
-	BFI_PPORT_H2I_ENABLE_REQ		= (1),
-	BFI_PPORT_H2I_DISABLE_REQ		= (2),
-	BFI_PPORT_H2I_GET_STATS_REQ		= (3),
-	BFI_PPORT_H2I_CLEAR_STATS_REQ	= (4),
-	BFI_PPORT_H2I_SET_SVC_PARAMS_REQ	= (5),
-	BFI_PPORT_H2I_ENABLE_RX_VF_TAG_REQ	= (6),
-	BFI_PPORT_H2I_ENABLE_TX_VF_TAG_REQ	= (7),
-	BFI_PPORT_H2I_GET_QOS_STATS_REQ		= (8),
-	BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ	= (9),
+enum bfi_fcport_h2i {
+	BFI_FCPORT_H2I_ENABLE_REQ		= (1),
+	BFI_FCPORT_H2I_DISABLE_REQ		= (2),
+	BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ	= (3),
+	BFI_FCPORT_H2I_STATS_GET_REQ		= (4),
+	BFI_FCPORT_H2I_STATS_CLEAR_REQ		= (5),
 };
 
-enum bfi_pport_i2h {
-	BFI_PPORT_I2H_ENABLE_RSP		= BFA_I2HM(1),
-	BFI_PPORT_I2H_DISABLE_RSP		= BFA_I2HM(2),
-	BFI_PPORT_I2H_GET_STATS_RSP		= BFA_I2HM(3),
-	BFI_PPORT_I2H_CLEAR_STATS_RSP	= BFA_I2HM(4),
-	BFI_PPORT_I2H_SET_SVC_PARAMS_RSP	= BFA_I2HM(5),
-	BFI_PPORT_I2H_ENABLE_RX_VF_TAG_RSP	= BFA_I2HM(6),
-	BFI_PPORT_I2H_ENABLE_TX_VF_TAG_RSP	= BFA_I2HM(7),
-	BFI_PPORT_I2H_EVENT			= BFA_I2HM(8),
-	BFI_PPORT_I2H_GET_QOS_STATS_RSP		= BFA_I2HM(9),
-	BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP	= BFA_I2HM(10),
+enum bfi_fcport_i2h {
+	BFI_FCPORT_I2H_ENABLE_RSP		= BFA_I2HM(1),
+	BFI_FCPORT_I2H_DISABLE_RSP		= BFA_I2HM(2),
+	BFI_FCPORT_I2H_SET_SVC_PARAMS_RSP	= BFA_I2HM(3),
+	BFI_FCPORT_I2H_STATS_GET_RSP		= BFA_I2HM(4),
+	BFI_FCPORT_I2H_STATS_CLEAR_RSP		= BFA_I2HM(5),
+	BFI_FCPORT_I2H_EVENT			= BFA_I2HM(6),
 };
 
 /**
  * Generic REQ type
  */
-struct bfi_pport_generic_req_s {
+struct bfi_fcport_req_s {
 	struct bfi_mhdr_s  mh;		/*  msg header			    */
-	u32        msgtag;		/*  msgtag for reply		    */
+	u32	   msgtag;	/*  msgtag for reply		    */
 };
 
 /**
  * Generic RSP type
  */
-struct bfi_pport_generic_rsp_s {
+struct bfi_fcport_rsp_s {
 	struct bfi_mhdr_s  mh;		/*  common msg header		    */
-	u8         status;		/*  port enable status		    */
-	u8         rsvd[3];
-	u32        msgtag;		/*  msgtag for reply		    */
+	u8		   status;	/*  port enable status		    */
+	u8		   rsvd[3];
+	u32	   msgtag;	/*  msgtag for reply		    */
 };
 
 /**
- * BFI_PPORT_H2I_ENABLE_REQ
+ * BFI_FCPORT_H2I_ENABLE_REQ
  */
-struct bfi_pport_enable_req_s {
+struct bfi_fcport_enable_req_s {
 	struct bfi_mhdr_s  mh;		/*  msg header			    */
-	u32        rsvd1;
-	wwn_t           nwwn;		/*  node wwn of physical port	    */
-	wwn_t           pwwn;		/*  port wwn of physical port	    */
-	struct bfa_pport_cfg_s port_cfg;	/*  port configuration	    */
-	union bfi_addr_u  stats_dma_addr;	/*  DMA address for stats  */
-	u32        msgtag;		/*  msgtag for reply		    */
-	u32        rsvd2;
+	u32	   rsvd1;
+	wwn_t		   nwwn;	/*  node wwn of physical port	    */
+	wwn_t		   pwwn;	/*  port wwn of physical port	    */
+	struct bfa_pport_cfg_s port_cfg; /*  port configuration	    */
+	union bfi_addr_u   stats_dma_addr; /*  DMA address for stats	    */
+	u32	   msgtag;	/*  msgtag for reply		    */
+	u32	   rsvd2;
 };
 
 /**
- * BFI_PPORT_I2H_ENABLE_RSP
- */
-#define bfi_pport_enable_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_DISABLE_REQ
- */
-#define bfi_pport_disable_req_t struct bfi_pport_generic_req_s
-
-/**
- * BFI_PPORT_I2H_DISABLE_RSP
- */
-#define bfi_pport_disable_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_GET_STATS_REQ
- */
-#define bfi_pport_get_stats_req_t struct bfi_pport_generic_req_s
-
-/**
- * BFI_PPORT_I2H_GET_STATS_RSP
- */
-#define bfi_pport_get_stats_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_CLEAR_STATS_REQ
- */
-#define bfi_pport_clear_stats_req_t struct bfi_pport_generic_req_s
-
-/**
- * BFI_PPORT_I2H_CLEAR_STATS_RSP
- */
-#define bfi_pport_clear_stats_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_GET_QOS_STATS_REQ
- */
-#define bfi_pport_get_qos_stats_req_t struct bfi_pport_generic_req_s
-
-/**
- * BFI_PPORT_H2I_GET_QOS_STATS_RSP
- */
-#define bfi_pport_get_qos_stats_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ
- */
-#define bfi_pport_clear_qos_stats_req_t struct bfi_pport_generic_req_s
-
-/**
- * BFI_PPORT_H2I_CLEAR_QOS_STATS_RSP
- */
-#define bfi_pport_clear_qos_stats_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_SET_SVC_PARAMS_REQ
+ * BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ
  */
-struct bfi_pport_set_svc_params_req_s {
+struct bfi_fcport_set_svc_params_req_s {
 	struct bfi_mhdr_s  mh;		/*  msg header */
-	u16        tx_bbcredit;	/*  Tx credits */
-	u16        rsvd;
+	u16	   tx_bbcredit;	/*  Tx credits */
+	u16	   rsvd;
 };
 
 /**
- * BFI_PPORT_I2H_SET_SVC_PARAMS_RSP
- */
-
-/**
- * BFI_PPORT_I2H_EVENT
+ * BFI_FCPORT_I2H_EVENT
  */
-struct bfi_pport_event_s {
+struct bfi_fcport_event_s {
 	struct bfi_mhdr_s 	mh;	/*  common msg header */
 	struct bfa_pport_link_s	link_state;
 };
 
-union bfi_pport_h2i_msg_u {
+/**
+ * fcport H2I message
+ */
+union bfi_fcport_h2i_msg_u {
 	struct bfi_mhdr_s			*mhdr;
-	struct bfi_pport_enable_req_s		*penable;
-	struct bfi_pport_generic_req_s		*pdisable;
-	struct bfi_pport_generic_req_s		*pgetstats;
-	struct bfi_pport_generic_req_s		*pclearstats;
-	struct bfi_pport_set_svc_params_req_s	*psetsvcparams;
-	struct bfi_pport_get_qos_stats_req_s	*pgetqosstats;
-	struct bfi_pport_generic_req_s		*pclearqosstats;
+	struct bfi_fcport_enable_req_s		*penable;
+	struct bfi_fcport_req_s			*pdisable;
+	struct bfi_fcport_set_svc_params_req_s	*psetsvcparams;
+	struct bfi_fcport_req_s			*pstatsget;
+	struct bfi_fcport_req_s			*pstatsclear;
 };
 
-union bfi_pport_i2h_msg_u {
+/**
+ * fcport I2H message
+ */
+union bfi_fcport_i2h_msg_u {
 	struct bfi_msg_s			*msg;
-	struct bfi_pport_generic_rsp_s		*enable_rsp;
-	struct bfi_pport_disable_rsp_s		*disable_rsp;
-	struct bfi_pport_generic_rsp_s		*getstats_rsp;
-	struct bfi_pport_clear_stats_rsp_s	*clearstats_rsp;
-	struct bfi_pport_set_svc_params_rsp_s	*setsvcparasm_rsp;
-	struct bfi_pport_get_qos_stats_rsp_s	*getqosstats_rsp;
-	struct bfi_pport_clear_qos_stats_rsp_s	*clearqosstats_rsp;
-	struct bfi_pport_event_s		*event;
+	struct bfi_fcport_rsp_s			*penable_rsp;
+	struct bfi_fcport_rsp_s			*pdisable_rsp;
+	struct bfi_fcport_rsp_s			*psetsvcparams_rsp;
+	struct bfi_fcport_rsp_s			*pstatsget_rsp;
+	struct bfi_fcport_rsp_s			*pstatsclear_rsp;
+	struct bfi_fcport_event_s		*event;
 };
 
 #pragma pack()
 
 #endif /* __BFI_PPORT_H__ */
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,10 @@
 enum {
 	BFA_TRC_CNA_CEE		= 1,
 	BFA_TRC_CNA_PORT	= 2,
+	BFA_TRC_CNA_IOC     = 3,
+	BFA_TRC_CNA_DIAG    = 4,
+	BFA_TRC_CNA_IOC_CB  = 5,
+	BFA_TRC_CNA_IOC_CT  = 6,
 };
 
 #endif /* __BFA_CNA_TRCMOD_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/cs/bfa_log.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/cs/bfa_log.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/cs/bfa_log.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/cs/bfa_log.h	2010-05-16 17:17:36.000000000 -0400
@@ -157,7 +157,7 @@ typedef void (*bfa_log_cb_t)(struct bfa_
 
 
 struct bfa_log_mod_s {
-	char		instance_info[16];	/*  instance info */
+	char		instance_info[BFA_STRING_32];	/*  instance info */
 	int		log_level[BFA_LOG_MODULE_ID_MAX + 1];
 						/*  log level for modules */
 	bfa_log_cb_t	cbfn; 			/*  callback function */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/cs/bfa_plog.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/cs/bfa_plog.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/cs/bfa_plog.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/cs/bfa_plog.h	2010-05-16 17:17:36.000000000 -0400
@@ -80,7 +80,8 @@ enum bfa_plog_mid {
 	BFA_PL_MID_HAL_FCXP 	= 4,
 	BFA_PL_MID_HAL_UF 	= 5,
 	BFA_PL_MID_FCS 		= 6,
-	BFA_PL_MID_MAX 		= 7
+	BFA_PL_MID_LPS		= 7,
+	BFA_PL_MID_MAX 		= 8
 };
 
 #define BFA_PL_MID_STRLEN    8
@@ -118,7 +119,11 @@ enum bfa_plog_eid {
 	BFA_PL_EID_RSCN 		= 17,
 	BFA_PL_EID_DEBUG 		= 18,
 	BFA_PL_EID_MISC 		= 19,
-	BFA_PL_EID_MAX 			= 20
+	BFA_PL_EID_FIP_FCF_DISC		= 20,
+	BFA_PL_EID_FIP_FCF_CVL		= 21,
+	BFA_PL_EID_LOGIN		= 22,
+	BFA_PL_EID_LOGO			= 23,
+	BFA_PL_EID_MAX			= 24
 };
 
 #define BFA_PL_ENAME_STRLEN    	8
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/cs/bfa_sm.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/cs/bfa_sm.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/cs/bfa_sm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/cs/bfa_sm.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,14 @@
 #define __BFA_SM_H__
 
 typedef void (*bfa_sm_t)(void *sm, int event);
+/**
+ * oc - object class eg. bfa_ioc
+ * st - state, eg. reset
+ * otype - object type, eg. struct bfa_ioc_s
+ * etype - object type, eg. enum ioc_event
+ */
+#define bfa_sm_state_decl(oc, st, otype, etype)         \
+	static void oc ## _sm_ ## st(otype * fsm, etype event)
 
 #define bfa_sm_set_state(_sm, _state)	((_sm)->sm = (bfa_sm_t)(_state))
 #define bfa_sm_send_event(_sm, _event)	((_sm)->sm((_sm), (_event)))
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_aen.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_aen.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_aen.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_aen.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,16 @@
 #include <defs/bfa_defs_audit.h>
 #include <defs/bfa_defs_ethport.h>
 
+#define BFA_AEN_MAX_APP         5
+
+enum bfa_aen_app {
+	bfa_aen_app_bcu = 0,    /* No thread for bcu */
+	bfa_aen_app_hcm = 1,
+	bfa_aen_app_cim = 2,
+	bfa_aen_app_snia = 3,
+	bfa_aen_app_test = 4,   /* To be removed after unit test */
+};
+
 enum bfa_aen_category {
 	BFA_AEN_CAT_ADAPTER 	= 1,
 	BFA_AEN_CAT_PORT 	= 2,
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_auth.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_auth.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_auth.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_auth.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #define PRIVATE_KEY			19009
 #define KEY_LEN				32399
 #define BFA_AUTH_SECRET_STRING_LEN	256
+#define BFA_AUTH_FAIL_NO_PASSWORD	0xFE
 #define BFA_AUTH_FAIL_TIMEOUT		0xFF
 
 /**
@@ -41,6 +42,27 @@ enum bfa_auth_status {
 	BFA_AUTH_STATUS_UNKNOWN = 9,	/*  authentication status unknown */
 };
 
+enum bfa_auth_rej_code {
+	BFA_AUTH_RJT_CODE_AUTH_FAILURE   = 1, /* auth failure */
+	BFA_AUTH_RJT_CODE_LOGICAL_ERR    = 2, /* logical error */
+};
+
+/**
+ * Authentication reject codes
+ */
+enum bfa_auth_rej_code_exp {
+	BFA_AUTH_MECH_NOT_USABLE        = 1, /* auth. mechanism not usable */
+	BFA_AUTH_DH_GROUP_NOT_USABLE    = 2, /* DH Group not usable */
+	BFA_AUTH_HASH_FUNC_NOT_USABLE   = 3, /* hash Function not usable */
+	BFA_AUTH_AUTH_XACT_STARTED      = 4, /* auth xact started */
+	BFA_AUTH_AUTH_FAILED            = 5, /* auth failed */
+	BFA_AUTH_INCORRECT_PLD          = 6, /* incorrect payload */
+	BFA_AUTH_INCORRECT_PROTO_MSG    = 7, /* incorrect proto msg */
+	BFA_AUTH_RESTART_AUTH_PROTO     = 8, /* restart auth protocol */
+	BFA_AUTH_AUTH_CONCAT_NOT_SUPP   = 9, /* auth concat not supported */
+	BFA_AUTH_PROTO_VER_NOT_SUPP     = 10,/* proto version not supported */
+};
+
 struct auth_proto_stats_s {
 	u32        auth_rjts;
 	u32        auth_negs;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_cee.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_cee.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_cee.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_cee.h	2010-05-16 17:17:36.000000000 -0400
@@ -28,10 +28,6 @@
 
 #define BFA_CEE_LLDP_MAX_STRING_LEN (128)
 
-
-/* FIXME: this is coming from the protocol spec. Can the host & apps share the
-   protocol .h files ?
- */
 #define BFA_CEE_LLDP_SYS_CAP_OTHER       0x0001
 #define BFA_CEE_LLDP_SYS_CAP_REPEATER    0x0002
 #define BFA_CEE_LLDP_SYS_CAP_MAC_BRIDGE  0x0004
@@ -94,9 +90,10 @@ struct bfa_cee_dcbx_cfg_s {
 /* CEE status */
 /* Making this to tri-state for the benefit of port list command */
 enum bfa_cee_status_e {
-    CEE_PHY_DOWN = 0,
-    CEE_PHY_UP = 1,
-    CEE_UP = 2,
+	CEE_UP = 0,
+	CEE_PHY_UP = 1,
+	CEE_LOOPBACK = 2,
+	CEE_PHY_DOWN = 3,
 };
 
 /* CEE Query */
@@ -107,7 +104,8 @@ struct bfa_cee_attr_s {
 	struct bfa_cee_dcbx_cfg_s dcbx_remote;
 	mac_t src_mac;
 	u8 link_speed;
-	u8 filler[3];
+	u8 nw_priority;
+	u8 filler[2];
 };
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_driver.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_driver.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_driver.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_driver.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 /**
  * Driver statistics
  */
+struct bfa_driver_stats_s {
 	u16    tm_io_abort;
     u16    tm_io_abort_comp;
     u16    tm_lun_reset;
@@ -34,7 +35,7 @@
     u64    output_req;
     u64    input_words;
     u64    output_words;
-} bfa_driver_stats_t;
+};
 
 
 #endif /* __BFA_DEFS_DRIVER_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #define __BFA_DEFS_ETHPORT_H__
 
 #include <defs/bfa_defs_status.h>
+#include <defs/bfa_defs_port.h>
 #include <protocol/types.h>
 #include <cna/pstats/phyport_defs.h>
 #include <cna/pstats/ethport_defs.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ *  bfa_defs_fcport.h
+ *
+ * Linux driver for Brocade Fibre Channel Host Bus Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+#ifndef __BFA_DEFS_FCPORT_H__
+#define __BFA_DEFS_FCPORT_H__
+
+#include <defs/bfa_defs_types.h>
+#include <protocol/types.h>
+
+#pragma pack(1)
+
+/**
+ * FCoE statistics
+ */
+struct bfa_fcoe_stats_s {
+	u64	secs_reset;	/*  Seconds since stats reset	     */
+	u64	cee_linkups;	/*  CEE link up		     */
+	u64	cee_linkdns;	/*  CEE link down		     */
+	u64	fip_linkups;	/*  FIP link up		     */
+	u64	fip_linkdns;	/*  FIP link down		     */
+	u64	fip_fails;	/*  FIP failures		     */
+	u64	mac_invalids;	/*  Invalid mac assignments	     */
+	u64	vlan_req;	/*  Vlan requests		     */
+	u64	vlan_notify;	/*  Vlan notifications		     */
+	u64	vlan_err;	/*  Vlan notification errors	     */
+	u64	vlan_timeouts;	/*  Vlan request timeouts	     */
+	u64	vlan_invalids;	/*  Vlan invalids		     */
+	u64	disc_req;	/*  Discovery requests		     */
+	u64	disc_rsp;	/*  Discovery responses	     */
+	u64	disc_err;	/*  Discovery error frames	     */
+	u64	disc_unsol;	/*  Discovery unsolicited	     */
+	u64	disc_timeouts;	/*  Discovery timeouts		     */
+	u64	disc_fcf_unavail; /*  Discovery FCF not avail	     */
+	u64	linksvc_unsupp;	/*  FIP link service req unsupp.    */
+	u64	linksvc_err;	/*  FIP link service req errors     */
+	u64	logo_req;	/*  FIP logo			     */
+	u64	clrvlink_req;	/*  Clear virtual link requests     */
+	u64	op_unsupp;	/*  FIP operation unsupp.	     */
+	u64	untagged;	/*  FIP untagged frames	     */
+	u64	txf_ucast;	/*  Tx FCoE unicast frames	     */
+	u64	txf_ucast_vlan;	/*  Tx FCoE unicast vlan frames     */
+	u64	txf_ucast_octets; /*  Tx FCoE unicast octets	     */
+	u64	txf_mcast;	/*  Tx FCoE mutlicast frames	     */
+	u64	txf_mcast_vlan;	/*  Tx FCoE mutlicast vlan frames   */
+	u64	txf_mcast_octets; /*  Tx FCoE multicast octets	     */
+	u64	txf_bcast;	/*  Tx FCoE broadcast frames	     */
+	u64	txf_bcast_vlan;	/*  Tx FCoE broadcast vlan frames   */
+	u64	txf_bcast_octets; /*  Tx FCoE broadcast octets	     */
+	u64	txf_timeout;	/*  Tx timeouts		     */
+	u64	txf_parity_errors; /*  Transmit parity err	     */
+	u64	txf_fid_parity_errors; /*  Transmit FID parity err  */
+	u64	tx_pause;	/*  Tx pause frames		     */
+	u64	tx_zero_pause;	/*  Tx zero pause frames	     */
+	u64	tx_first_pause;	/*  Tx first pause frames	     */
+	u64	rx_pause;	/*  Rx pause frames		     */
+	u64	rx_zero_pause;	/*  Rx zero pause frames	     */
+	u64	rx_first_pause;	/*  Rx first pause frames	     */
+	u64	rxf_ucast_octets; /*  Rx unicast octets	     */
+	u64	rxf_ucast;	/*  Rx unicast frames		     */
+	u64	rxf_ucast_vlan;	/*  Rx unicast vlan frames	     */
+	u64	rxf_mcast_octets; /*  Rx multicast octets	     */
+	u64	rxf_mcast;	/*  Rx multicast frames	     */
+	u64	rxf_mcast_vlan;	/*  Rx multicast vlan frames	     */
+	u64	rxf_bcast_octets; /*  Rx broadcast octests	     */
+	u64	rxf_bcast;	/*  Rx broadcast frames	     */
+	u64	rxf_bcast_vlan;	/*  Rx broadcast vlan frames	     */
+};
+
+/**
+ * QoS or FCoE stats (fcport stats excluding physical FC port stats)
+ */
+union bfa_fcport_stats_u {
+	struct bfa_qos_stats_s	fcqos;
+	struct bfa_fcoe_stats_s	fcoe;
+};
+
+#pragma pack()
+
+#endif  /* __BFA_DEFS_FCPORT_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- *
- * Linux driver for Brocade Fibre Channel Host Bus Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) Version 2 as
- * published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- */
-
-#ifndef __BFA_DEFS_IM_COMMON_H__
-#define __BFA_DEFS_IM_COMMON_H__
-
-#define	BFA_ADAPTER_NAME_LEN	256
-#define BFA_ADAPTER_GUID_LEN    256
-#define RESERVED_VLAN_NAME      L"PORT VLAN"
-#define PASSTHRU_VLAN_NAME      L"PASSTHRU VLAN"
-
-	u64	tx_pkt_cnt;
-	u64	rx_pkt_cnt;
-	u32	duration;
-	u8		status;
-} bfa_im_stats_t, *pbfa_im_stats_t;
-
-#endif /* __BFA_DEFS_IM_COMMON_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- *
- * Linux driver for Brocade Fibre Channel Host Bus Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) Version 2 as
- * published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- */
-
-#ifndef __BFA_DEFS_IM_TEAM_H__
-#define __BFA_DEFS_IM_TEAM_H__
-
-#include <protocol/types.h>
-
-#define	BFA_TEAM_MAX_PORTS	8
-#define	BFA_TEAM_NAME_LEN	256
-#define BFA_MAX_NUM_TEAMS	16
-#define BFA_TEAM_INVALID_DELAY -1
-
-	BFA_LACP_RATE_SLOW = 1,
-	BFA_LACP_RATE_FAST
-} bfa_im_lacp_rate_t;
-
-	BFA_TEAM_MODE_FAIL_OVER = 1,
-	BFA_TEAM_MODE_FAIL_BACK,
-	BFA_TEAM_MODE_LACP,
-	BFA_TEAM_MODE_NONE
-} bfa_im_team_mode_t;
-
-	BFA_XMIT_POLICY_L2 = 1,
-	BFA_XMIT_POLICY_L3_L4
-} bfa_im_xmit_policy_t;
-
-	bfa_im_team_mode_t     team_mode;
-	bfa_im_lacp_rate_t     lacp_rate;
-	bfa_im_xmit_policy_t   xmit_policy;
-	int   	          delay;
-	wchar_t    	  primary[BFA_ADAPTER_NAME_LEN];
-	wchar_t        	  preferred_primary[BFA_ADAPTER_NAME_LEN];
-	mac_t	          mac;
-	u16       	  num_ports;
-	u16          num_vlans;
-	u16 vlan_list[BFA_MAX_VLANS_PER_PORT];
-	wchar_t	 team_guid_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_GUID_LEN];
-	wchar_t	 ioc_name_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_NAME_LEN];
-} bfa_im_team_attr_t;
-
-	wchar_t		             team_name[BFA_TEAM_NAME_LEN];
-	bfa_im_xmit_policy_t	 xmit_policy;
-	int                 	 delay;
-	wchar_t                	 primary[BFA_ADAPTER_NAME_LEN];
-	wchar_t               	 preferred_primary[BFA_ADAPTER_NAME_LEN];
-} bfa_im_team_edit_t, *pbfa_im_team_edit_t;
-
-	wchar_t					team_name[BFA_TEAM_NAME_LEN];
-	bfa_im_team_mode_t      team_mode;
-	mac_t	               	mac;
-} bfa_im_team_info_t;
-
-	bfa_im_team_info_t 		team_info[BFA_MAX_NUM_TEAMS];
-	u16 				num_teams;
-} bfa_im_team_list_t, *pbfa_im_team_list_t;
-
-#endif /* __BFA_DEFS_IM_TEAM_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,8 @@
 
 #define BFA_IOCFC_INTR_DELAY	1125
 #define BFA_IOCFC_INTR_LATENCY	225
+#define BFA_IOCFCOE_INTR_DELAY  25
+#define BFA_IOCFCOE_INTR_LATENCY 5
 
 /**
  * Interrupt coalescing configuration.
@@ -50,7 +52,7 @@ struct bfa_iocfc_fwcfg_s {
 	u16        num_fcxp_reqs;	/*  unassisted FC exchanges	*/
 	u16        num_uf_bufs;	/*  unsolicited recv buffers	*/
 	u8		num_cqs;
-	u8		rsvd;
+	u8		rsvd[5];
 };
 
 struct bfa_iocfc_drvcfg_s {
@@ -224,18 +226,24 @@ struct bfa_fw_port_physm_stats_s {
 
 
 struct bfa_fw_fip_stats_s {
+    u32    vlan_req;           /*  vlan discovery requests             */
+    u32    vlan_notify;        /*  vlan notifications                  */
+    u32    vlan_err;           /*  vlan response error                 */
+    u32    vlan_timeouts;      /*  vlan disvoery timeouts              */
+    u32    vlan_invalids;      /*  invalid vlan in discovery advert.   */
     u32    disc_req;           /*  Discovery solicit requests          */
     u32    disc_rsp;           /*  Discovery solicit response          */
     u32    disc_err;           /*  Discovery advt. parse errors        */
     u32    disc_unsol;         /*  Discovery unsolicited               */
     u32    disc_timeouts;      /*  Discovery timeouts                  */
+    u32    disc_fcf_unavail;   /*  Discovery FCF Not Avail.            */
     u32    linksvc_unsupp;     /*  Unsupported link service req        */
     u32    linksvc_err;        /*  Parse error in link service req     */
     u32    logo_req;           /*  Number of FIP logos received        */
     u32    clrvlink_req;       /*  Clear virtual link req              */
     u32    op_unsupp;          /*  Unsupported FIP operation           */
     u32    untagged;           /*  Untagged frames (ignored)           */
-    u32    rsvd;
+    u32	   invalid_version;    /*!< Invalid FIP version           */
 };
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h	2010-05-16 17:17:36.000000000 -0400
@@ -126,6 +126,7 @@ struct bfa_ioc_attr_s {
 	struct bfa_ioc_driver_attr_s 	driver_attr;	/*  driver attr    */
 	struct bfa_ioc_pci_attr_s	pci_attr;
 	u8				port_id;	/*  port number    */
+	u8				rsvd[7];	/*!< 64bit align    */
 };
 
 /**
@@ -143,8 +144,8 @@ enum bfa_ioc_aen_event {
  * BFA IOC level event data, now just a place holder
  */
 struct bfa_ioc_aen_data_s {
-	enum bfa_ioc_type_e ioc_type;
 	wwn_t	pwwn;
+	s16 ioc_type;
 	mac_t	mac;
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_lport.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_lport.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_lport.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_lport.h	2010-05-16 17:17:36.000000000 -0400
@@ -59,8 +59,8 @@ enum bfa_lport_aen_event {
  */
 struct bfa_lport_aen_data_s {
 	u16        vf_id;	/*  vf_id of this logical port */
-	u16        rsvd;
-	enum bfa_port_role roles;	/*  Logical port mode,IM/TM/IP etc */
+	s16         roles;  /*  Logical port mode,IM/TM/IP etc */
+	u32        rsvd;
 	wwn_t           ppwwn;	/*  WWN of its physical port */
 	wwn_t           lpwwn;	/*  WWN of this logical port */
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,47 @@
 /**
  * Manufacturing block version
  */
-#define BFA_MFG_VERSION				1
+#define BFA_MFG_VERSION				2
+
+/**
+ * Manufacturing block encrypted version
+ */
+#define BFA_MFG_ENC_VER				2
+
+/**
+ * Manufacturing block version 1 length
+ */
+#define BFA_MFG_VER1_LEN			128
+
+/**
+ * Manufacturing block header length
+ */
+#define BFA_MFG_HDR_LEN				4
+
+/**
+ * Checksum size
+ */
+#define BFA_MFG_CHKSUM_SIZE			16
+
+/**
+ * Manufacturing block encrypted version
+ */
+#define BFA_MFG_ENC_VER				2
+
+/**
+ * Manufacturing block version 1 length
+ */
+#define BFA_MFG_VER1_LEN			128
+
+/**
+ * Manufacturing block header length
+ */
+#define BFA_MFG_HDR_LEN				4
+
+/**
+ * Checksum size
+ */
+#define BFA_MFG_CHKSUM_SIZE			16
 
 /**
  * Manufacturing block format
@@ -30,29 +70,74 @@
 #define BFA_MFG_SERIALNUM_SIZE			11
 #define BFA_MFG_PARTNUM_SIZE			14
 #define BFA_MFG_SUPPLIER_ID_SIZE		10
-#define BFA_MFG_SUPPLIER_PARTNUM_SIZE	20
-#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE	20
-#define BFA_MFG_SUPPLIER_REVISION_SIZE	4
+#define BFA_MFG_SUPPLIER_PARTNUM_SIZE		20
+#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE		20
+#define BFA_MFG_SUPPLIER_REVISION_SIZE		4
 #define STRSZ(_n)	(((_n) + 4) & ~3)
 
 /**
+ * Manufacturing card type
+ */
+enum {
+	BFA_MFG_TYPE_CB_MAX  = 825,      /*  Crossbow card type max	*/
+	BFA_MFG_TYPE_FC8P2   = 825,      /*  8G 2port FC card		*/
+	BFA_MFG_TYPE_FC8P1   = 815,      /*  8G 1port FC card		*/
+	BFA_MFG_TYPE_FC4P2   = 425,      /*  4G 2port FC card		*/
+	BFA_MFG_TYPE_FC4P1   = 415,      /*  4G 1port FC card		*/
+	BFA_MFG_TYPE_CNA10P2 = 1020,     /*  10G 2port CNA card	*/
+	BFA_MFG_TYPE_CNA10P1 = 1010,     /*  10G 1port CNA card	*/
+};
+
+#pragma pack(1)
+
+/**
+ * Card type to port number conversion
+ */
+#define bfa_mfg_type2port_num(card_type) (((card_type) / 10) % 10)
+
+
+/**
+ * All numerical fields are in big-endian format.
+ */
+struct bfa_mfg_block_s {
+};
+
+/**
  * VPD data length
  */
-#define BFA_MFG_VPD_LEN     256
+#define BFA_MFG_VPD_LEN		512
+
+#define BFA_MFG_VPD_PCI_HDR_OFF		137
+#define BFA_MFG_VPD_PCI_VER_MASK	0x07	/*  version mask 3 bits */
+#define BFA_MFG_VPD_PCI_VDR_MASK	0xf8	/*  vendor mask 5 bits */
+
+/**
+ * VPD vendor tag
+ */
+enum {
+	BFA_MFG_VPD_UNKNOWN	= 0,     /*  vendor unknown 		*/
+	BFA_MFG_VPD_IBM 	= 1,     /*  vendor IBM 		*/
+	BFA_MFG_VPD_HP  	= 2,     /*  vendor HP  		*/
+	BFA_MFG_VPD_DELL        = 3,	 /*  vendor DELL                */
+	BFA_MFG_VPD_PCI_IBM 	= 0x08,  /*  PCI VPD IBM     		*/
+	BFA_MFG_VPD_PCI_HP  	= 0x10,  /*  PCI VPD HP			*/
+	BFA_MFG_VPD_PCI_DELL    = 0x20,  /*  PCI VPD DELL           	*/
+	BFA_MFG_VPD_PCI_BRCD 	= 0xf8,  /*  PCI VPD Brocade 		*/
+};
 
 /**
  * All numerical fields are in big-endian format.
  */
 struct bfa_mfg_vpd_s {
-    u8     version;    /*  vpd data version */
-    u8     vpd_sig[3]; /*  characters 'V', 'P', 'D' */
-    u8     chksum;     /*  u8 checksum */
-    u8     vendor;     /*  vendor */
-    u8     len;        /*  vpd data length excluding header */
-    u8     rsv;
-    u8     data[BFA_MFG_VPD_LEN];  /*  vpd data */
+	u8		version;	/*  vpd data version */
+	u8		vpd_sig[3];	/*  characters 'V', 'P', 'D' */
+	u8		chksum;		/*  u8 checksum */
+	u8		vendor;		/*  vendor */
+	u8 	len;		/*  vpd data length excluding header */
+	u8 	rsv;
+	u8		data[BFA_MFG_VPD_LEN];	/*  vpd data */
 };
 
-#pragma pack(1)
+#pragma pack()
 
 #endif /* __BFA_DEFS_MFG_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_port.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_port.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_port.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_port.h	2010-05-16 17:17:36.000000000 -0400
@@ -185,6 +185,8 @@ struct bfa_port_attr_s {
 	wwn_t		fabric_name; /*  attached switch's nwwn */
 	u8		fabric_ip_addr[BFA_FCS_FABRIC_IPADDR_SZ]; /*  attached
 							* fabric's ip addr */
+	struct mac_s    fpma_mac;	/*  Lport's FPMA Mac address */
+	u16     authfail;		/*  auth failed state */
 };
 
 /**
@@ -232,14 +234,15 @@ enum bfa_port_aen_sfp_pom {
 };
 
 struct bfa_port_aen_data_s {
-	enum bfa_ioc_type_e ioc_type;
-	wwn_t           pwwn;	      /*  WWN of the physical port */
-	wwn_t           fwwn;	      /*  WWN of the fabric port */
-	mac_t           mac;	      /*  MAC addres of the ethernet port,
-				       * applicable to CNA port only */
-	int             phy_port_num; /*! For SFP related events */
-	enum bfa_port_aen_sfp_pom level; /*  Only transitions will
-					  * be informed */
+	wwn_t           pwwn;         /*  WWN of the physical port */
+	wwn_t           fwwn;         /*  WWN of the fabric port */
+	s32         phy_port_num; /*! For SFP related events */
+	s16         ioc_type;
+	s16         level;        /*  Only transitions will
+					* be informed */
+	struct mac_s    mac;          /*  MAC address of the ethernet port,
+					* applicable to CNA port only */
+	s16         rsvd;
 };
 
 #endif /* __BFA_DEFS_PORT_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_pport.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_pport.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_pport.h	2010-05-16 17:17:36.000000000 -0400
@@ -232,7 +232,7 @@ struct bfa_pport_attr_s {
 	u32        	pid;		/*  port ID */
 	enum bfa_pport_type 	port_type;	/*  current topology */
 	u32        	loopback;	/*  external loopback */
-	u32		rsvd1;
+	u32		authfail;	/* auth fail state */
 	u32		rsvd2;		/*  padding for 64 bit */
 };
 
@@ -240,73 +240,79 @@ struct bfa_pport_attr_s {
  * 		FC Port statistics.
  */
 struct bfa_pport_fc_stats_s {
-	u64        secs_reset;	/*  seconds since stats is reset */
-	u64        tx_frames;	/*  transmitted frames */
-	u64        tx_words;	/*  transmitted words */
-	u64        rx_frames;	/*  received frames */
-	u64        rx_words;	/*  received words */
-	u64        lip_count;	/*  LIPs seen */
-	u64        nos_count;	/*  NOS count */
-	u64        error_frames;	/*  errored frames (sent?) */
-	u64        dropped_frames;	/*  dropped frames */
-	u64        link_failures;	/*  link failure count */
-	u64        loss_of_syncs;	/*  loss of sync count */
-	u64        loss_of_signals;/*  loss of signal count */
-	u64        primseq_errs;	/*  primitive sequence protocol */
-	u64        bad_os_count;	/*  invalid ordered set */
-	u64        err_enc_out;	/*  Encoding error outside frame */
-	u64        invalid_crcs;	/*  frames received with invalid CRC*/
-	u64	undersized_frm; /*  undersized frames */
-	u64	oversized_frm;	/*  oversized frames */
-	u64	bad_eof_frm;	/*  frames with bad EOF */
-	struct bfa_qos_stats_s	qos_stats;	/*  QoS statistics */
+	u64    secs_reset; /* Seconds since stats is reset     */
+	u64    tx_frames;  /* Tx frames                */
+	u64    tx_words;   /* Tx words                 */
+	u64    tx_lip;     /* TX LIP               */
+	u64    tx_nos;     /* Tx NOS               */
+	u64    tx_ols;     /* Tx OLS               */
+	u64    tx_lr;      /* Tx LR                */
+	u64    tx_lrr;     /* Tx LRR               */
+	u64    rx_frames;  /* Rx frames                */
+	u64    rx_words;   /* Rx words                 */
+	u64    lip_count;  /* Rx LIP                   */
+	u64    nos_count;  /* Rx NOS               */
+	u64    ols_count;  /* Rx OLS               */
+	u64    lr_count;   /* Rx LR                */
+	u64    lrr_count;  /* Rx LRR               */
+	u64    invalid_crcs;   /* Rx CRC err frames            */
+	u64    invalid_crc_gd_eof; /* Rx CRC err good EOF frames   */
+	u64    undersized_frm; /* Rx undersized frames         */
+	u64    oversized_frm;  /* Rx oversized frames          */
+	u64    bad_eof_frm;    /* Rx frames with bad EOF       */
+	u64    error_frames;   /* Errored frames           */
+	u64    dropped_frames; /* Dropped frames           */
+	u64    link_failures;  /* Link Failure (LF) count          */
+	u64    loss_of_syncs;  /* Loss of sync count           */
+	u64    loss_of_signals;/* Loss of signal count         */
+	u64    primseq_errs;   /* Primitive sequence protocol err. */
+	u64    bad_os_count;   /* Invalid ordered sets         */
+	u64    err_enc_out;    /* Encoding err nonframe_8b10b      */
+	u64    err_enc;    /* Encoding err frame_8b10b         */
 };
 
 /**
  * 		Eth Port statistics.
  */
 struct bfa_pport_eth_stats_s {
-	u64	secs_reset;	/*  seconds since stats is reset */
-	u64	frame_64;      /*  both rx and tx counter */
-	u64	frame_65_127;      /* both rx and tx counter */
-	u64	frame_128_255;     /* both rx and tx counter */
-	u64	frame_256_511;     /* both rx and tx counter */
-	u64	frame_512_1023;    /* both rx and tx counter */
-	u64	frame_1024_1518;   /* both rx and tx counter */
-	u64	frame_1519_1522;   /* both rx and tx counter */
-
-	u64	tx_bytes;
-	u64	tx_packets;
-	u64	tx_mcast_packets;
-	u64	tx_bcast_packets;
-	u64	tx_control_frame;
-	u64	tx_drop;
-	u64	tx_jabber;
-	u64	tx_fcs_error;
-	u64	tx_fragments;
-
-	u64	rx_bytes;
-	u64	rx_packets;
-	u64	rx_mcast_packets;
-	u64	rx_bcast_packets;
-	u64	rx_control_frames;
-	u64	rx_unknown_opcode;
-	u64	rx_drop;
-	u64	rx_jabber;
-	u64	rx_fcs_error;
-	u64	rx_alignment_error;
-	u64	rx_frame_length_error;
-	u64	rx_code_error;
-	u64	rx_fragments;
-
-	u64	rx_pause; /* BPC */
-	u64	rx_zero_pause; /*  BPC Pause cancellation */
-	u64	tx_pause;      /* BPC */
-	u64	tx_zero_pause; /*  BPC Pause cancellation */
-	u64	rx_fcoe_pause; /* BPC */
-	u64	rx_fcoe_zero_pause; /*  BPC Pause cancellation */
-	u64	tx_fcoe_pause;      /* BPC */
-	u64	tx_fcoe_zero_pause; /*  BPC Pause cancellation */
+	u64    secs_reset;   /* Seconds since stats is reset   */
+	u64    frame_64;     /* Frames 64 bytes            */
+	u64    frame_65_127;     /* Frames 65-127 bytes        */
+	u64    frame_128_255;    /* Frames 128-255 bytes       */
+	u64    frame_256_511;    /* Frames 256-511 bytes       */
+	u64    frame_512_1023;   /* Frames 512-1023 bytes          */
+	u64    frame_1024_1518;  /* Frames 1024-1518 bytes         */
+	u64    frame_1519_1522;  /* Frames 1519-1522 bytes         */
+	u64    tx_bytes;     /* Tx bytes               */
+	u64    tx_packets;   /* Tx packets             */
+	u64    tx_mcast_packets; /* Tx multicast packets       */
+	u64    tx_bcast_packets; /* Tx broadcast packets       */
+	u64    tx_control_frame; /* Tx control frame           */
+	u64    tx_drop;      /* Tx drops               */
+	u64    tx_jabber;    /* Tx jabber              */
+	u64    tx_fcs_error;     /* Tx FCS error           */
+	u64    tx_fragments;     /* Tx fragments           */
+	u64    rx_bytes;     /* Rx bytes               */
+	u64    rx_packets;   /* Rx packets             */
+	u64    rx_mcast_packets; /* Rx multicast packets       */
+	u64    rx_bcast_packets; /* Rx broadcast packets       */
+	u64    rx_control_frames; /* Rx control frames         */
+	u64    rx_unknown_opcode; /* Rx unknown opcode         */
+	u64    rx_drop;      /* Rx drops               */
+	u64    rx_jabber;    /* Rx jabber              */
+	u64    rx_fcs_error;     /* Rx FCS errors              */
+	u64    rx_alignment_error; /* Rx alignment errors          */
+	u64    rx_frame_length_error; /* Rx frame len errors       */
+	u64    rx_code_error;    /* Rx code errors             */
+	u64    rx_fragments;     /* Rx fragments           */
+	u64    rx_pause;     /* Rx pause               */
+	u64    rx_zero_pause;    /* Rx zero pause              */
+	u64    tx_pause;     /* Tx pause               */
+	u64    tx_zero_pause;    /* Tx zero pause              */
+	u64    rx_fcoe_pause;    /* Rx fcoe pause              */
+	u64    rx_fcoe_zero_pause; /* Rx FCoE zero pause       */
+	u64    tx_fcoe_pause;    /* Tx FCoE pause              */
+	u64    tx_fcoe_zero_pause; /* Tx FCoE zero pause       */
 };
 
 /**
@@ -333,8 +339,7 @@ struct bfa_pport_fcpmap_s {
 };
 
 /**
- *              Port RNID info.
- */
+ *              Port RNI	 */
 struct bfa_pport_rnid_s {
 	wwn_t             wwn;
 	u32          unittype;
@@ -347,6 +352,23 @@ struct bfa_pport_rnid_s {
 	u16          topologydiscoveryflags;
 };
 
+struct bfa_fcport_fcf_s {
+	wwn_t           name;           /* FCF name                 */
+	wwn_t           fabric_name;    /* Fabric Name              */
+	u8		fipenabled;     /* FIP enabled or not       */
+	u8		fipfailed;      /* FIP failed or not        */
+	u8         	resv[2];
+	u8         	pri;            /* FCF priority             */
+	u8         	version;        /* FIP version used         */
+	u8         	available;      /* Available  for  login    */
+	u8         	fka_disabled;   /* FKA is disabled          */
+	u8         	maxsz_verified; /* FCoE max size verified   */
+	u8         	fc_map[3];      /* FC map                   */
+	u16		vlan;           /* FCoE vlan tag/priority   */
+	u32        	fka_adv_per;    /* FIP  ka advert. period   */
+	struct mac_s	mac;            /* FCF mac                  */
+};
+
 /**
  * 		Link state information
  */
@@ -378,6 +400,7 @@ struct bfa_pport_link_s {
 			struct fc_alpabm_s     alpabm;	   /*  alpa bitmap */
 		} loop_info;
 	} tl;
+	struct bfa_fcport_fcf_s fcf;    /*!< FCF information (for FCoE) */
 };
 
 #endif /* __BFA_DEFS_PPORT_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_status.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_status.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_status.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_status.h	2010-05-16 17:17:36.000000000 -0400
@@ -180,8 +180,8 @@ enum bfa_status {
 	BFA_STATUS_IM_ADAPT_ALREADY_IN_TEAM = 114, /*  Given adapter is part
 						    * of another team */
 	BFA_STATUS_IM_ADAPT_HAS_VLANS = 115, /*  Adapter has VLANs configured.
-					      * Delete all VLANs before
-					      * creating team */
+					      * Delete all VLANs to become
+					      * part of the team */
 	BFA_STATUS_IM_PVID_MISMATCH = 116, /*  Mismatching PVIDs configured
 					    * for adapters */
 	BFA_STATUS_IM_LINK_SPEED_MISMATCH = 117, /*  Mismatching link speeds
@@ -213,7 +213,7 @@ enum bfa_status {
 					     * loaded */
 	BFA_STATUS_CARD_TYPE_MISMATCH = 131, /*  Card type mismatch */
 	BFA_STATUS_BAD_ASICBLK = 132, /*  Bad ASIC block */
-	BFA_STATUS_NO_DRIVER = 133, /*  Storage/Ethernet driver not loaded */
+	BFA_STATUS_NO_DRIVER = 133, /*  Brocade adapter/driver not installed or loaded */
 	BFA_STATUS_INVALID_MAC = 134, /*  Invalid mac address */
 	BFA_STATUS_IM_NO_VLAN = 135, /*  No VLANs configured on the adapter */
 	BFA_STATUS_IM_ETH_LB_FAILED = 136, /*  Ethernet loopback test failed */
@@ -228,8 +228,7 @@ enum bfa_status {
 	BFA_STATUS_IM_GET_INETCFG_FAILED = 142, /*  Acquiring Network Subsytem
 						 * handle Failed. Please try
 						 * after some time */
-	BFA_STATUS_IM_NOT_BOUND = 143, /*  Brocade 10G Ethernet Service is not
-					* Enabled on this port */
+	BFA_STATUS_IM_NOT_BOUND = 143, /*  IM driver is not active */
 	BFA_STATUS_INSUFFICIENT_PERMS = 144, /*  User doesn't have sufficient
 					      * permissions to execute the BCU
 					      * application */
@@ -242,6 +241,14 @@ enum bfa_status {
 					  * failed */
 	BFA_STATUS_IM_UNBIND_FAILED = 149, /* ! < IM Driver unbind operation
 					    * failed */
+	BFA_STATUS_IM_PORT_IN_TEAM = 150, /*  Port is already part of the
+					   * team */
+	BFA_STATUS_IM_VLAN_NOT_FOUND = 151, /*  VLAN ID doesn't exists */
+	BFA_STATUS_IM_TEAM_NOT_FOUND = 152, /*  Teaming configuration doesn't
+					     * exists */
+	BFA_STATUS_IM_TEAM_CFG_NOT_ALLOWED = 153, /*  Given settings are not
+						* allowed for the current
+						* Teaming mode */
 	BFA_STATUS_MAX_VAL		/*  Unknown error code */
 };
 #define bfa_status_t enum bfa_status
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h	2010-05-16 17:17:36.000000000 -0400
@@ -70,7 +70,6 @@ void            bfa_fcb_itnim_online(str
  */
 void            bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv);
 
-void            bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim_drv);
 void            bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim_drv);
 
 #endif /* __BFAD_FCB_FCPIM_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs.h	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,7 @@ struct bfa_fcs_s {
 	struct bfa_trc_mod_s  *trcmod;	/*  tracing module */
 	struct bfa_aen_s      *aen;	/*  aen component */
 	bfa_boolean_t   vf_enabled;	/*  VF mode is enabled */
+	bfa_boolean_t   fdmi_enabled;   /*!< FDMI is enabled */
 	bfa_boolean_t min_cfg;		/* min cfg enabled/disabled */
 	u16        port_vfid;	/*  port default VF ID */
 	struct bfa_fcs_driver_info_s driver_info;
@@ -60,10 +61,12 @@ struct bfa_fcs_s {
 /*
  * bfa fcs API functions
  */
-void bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
+void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
 			bfa_boolean_t min_cfg);
+void bfa_fcs_init(struct bfa_fcs_s *fcs);
 void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
 			struct bfa_fcs_driver_info_s *driver_info);
+void bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable);
 void bfa_fcs_exit(struct bfa_fcs_s *fcs);
 void bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod);
 void bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h	2010-05-16 17:17:36.000000000 -0400
@@ -34,14 +34,6 @@ struct bfa_fcs_s;
 struct bfa_fcs_fabric_s;
 
 /*
-* @todo : need to move to a global config file.
- * Maximum Vports supported per physical port or vf.
- */
-#define BFA_FCS_MAX_VPORTS_SUPP_CB  255
-#define BFA_FCS_MAX_VPORTS_SUPP_CT  191
-
-/*
-* @todo : need to move to a global config file.
  * Maximum Rports supported per port (physical/logical).
  */
 #define BFA_FCS_MAX_RPORTS_SUPP  256	/* @todo : tentative value */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/log/bfa_log_hal.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/log/bfa_log_hal.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/log/bfa_log_hal.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/log/bfa_log_hal.h	2010-05-16 17:17:36.000000000 -0400
@@ -27,4 +27,10 @@
 	(((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 3)
 #define BFA_LOG_HAL_SM_ASSERT \
 	(((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 4)
+#define BFA_LOG_HAL_DRIVER_ERROR \
+	(((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 5)
+#define BFA_LOG_HAL_DRIVER_CONFIG_ERROR \
+	(((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 6)
+#define BFA_LOG_HAL_MBOX_ERROR \
+	(((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 7)
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/log/bfa_log_linux.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/log/bfa_log_linux.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/log/bfa_log_linux.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/log/bfa_log_linux.h	2010-05-16 17:17:36.000000000 -0400
@@ -41,4 +41,20 @@
 		(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 10)
 #define BFA_LOG_LINUX_SCSI_ABORT_COMP \
 		(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 11)
+#define BFA_LOG_LINUX_DRIVER_CONFIG_ERROR \
+		(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 12)
+#define BFA_LOG_LINUX_BNA_STATE_MACHINE \
+		(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 13)
+#define BFA_LOG_LINUX_IOC_ERROR \
+	(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 14)
+#define BFA_LOG_LINUX_RESOURCE_ALLOC_ERROR \
+	(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 15)
+#define BFA_LOG_LINUX_RING_BUFFER_ERROR \
+	(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 16)
+#define BFA_LOG_LINUX_DRIVER_ERROR \
+	(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 17)
+#define BFA_LOG_LINUX_DRIVER_DIAG \
+	(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 18)
+#define BFA_LOG_LINUX_DRIVER_AEN \
+	(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 19)
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/protocol/fc.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/protocol/fc.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/protocol/fc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/protocol/fc.h	2010-05-16 17:17:36.000000000 -0400
@@ -50,6 +50,11 @@ struct fchs_s {
 
 	u32        ro;		/* relative offset */
 };
+
+#define FC_SOF_LEN      4
+#define FC_EOF_LEN      4
+#define FC_CRC_LEN      4
+
 /*
  * Fibre Channel BB_E Header Structure
  */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/protocol/pcifw.h linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/protocol/pcifw.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/protocol/pcifw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/include/protocol/pcifw.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- *
- * Linux driver for Brocade Fibre Channel Host Bus Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) 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.
- */
-
-/**
- *  pcifw.h PCI FW related headers
- */
-
-#ifndef __PCIFW_H__
-#define __PCIFW_H__
-
-#pragma pack(1)
-
-struct pnp_hdr_s{
-  u32	signature;	/* "$PnP" */
-  u8	rev;		/* Struct revision */
-  u8 	len;		/* Header structure len in multiples
-				 * of 16 bytes */
-  u16  off;		/* Offset to next header 00 if none */
-  u8	rsvd;		/* Reserved byte */
-  u8	cksum;		/* 8-bit checksum for this header */
-  u32	pnp_dev_id;	/* PnP Device Id */
-  u16  mfstr;		/* Pointer to manufacturer string */
-  u16	prstr;		/* Pointer to product string */
-  u8	devtype[3];	/* Device Type Code */
-  u8	devind;		/* Device Indicator */
-  u16	bcventr;	/* Bootstrap entry vector */
-  u16	rsvd2;		/* Reserved */
-  u16  sriv;		/* Static resource information vector */
-};
-
-struct pci_3_0_ds_s{
- u32	sig;   		/* Signature "PCIR" */
- u16	vendid;		/* Vendor ID */
- u16	devid;		/* Device ID */
- u16	devlistoff;	/* Device List Offset */
- u16	len;		/* PCI Data Structure Length */
- u8	rev;		/* PCI Data Structure Revision */
- u8	clcode[3];	/* Class Code */
- u16	imglen;		/* Code image length in multiples of
-				 * 512 bytes */
- u16	coderev;	/* Revision level of code/data */
- u8	codetype;	/* Code type 0x00 - BIOS */
- u8	indr;		/* Last image indicator */
- u16	mrtimglen;	/* Max Run Time Image Length */
- u16	cuoff;		/* Config Utility Code Header Offset */
- u16	dmtfclp;	/* DMTF CLP entry point offset */
-};
-
-struct pci_optrom_hdr_s{
- u16	sig;		/* Signature 0x55AA */
- u8	len;		/* Option ROM length in units of 512 bytes */
- u8	inivec[3];	/* Initialization vector */
- u8	rsvd[16];	/* Reserved field */
- u16	verptr;		/* Pointer to version string - private */
- u16	pcids;		/* Pointer to PCI data structure */
- u16	pnphdr;		/* Pointer to PnP expansion header */
-};
-
-#pragma pack()
-
-#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/loop.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/loop.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/loop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/loop.c	2010-05-16 17:17:36.000000000 -0400
@@ -162,7 +162,7 @@ bfa_fcs_port_loop_send_plogi(struct bfa_
 	len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
 			     bfa_fcs_port_get_fcid(port), 0,
 			     port->port_cfg.pwwn, port->port_cfg.nwwn,
-				 bfa_pport_get_maxfrsize(port->fcs->bfa));
+				 bfa_fcport_get_maxfrsize(port->fcs->bfa));
 
 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
 			  FC_CLASS_3, len, &fchs,
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/lport_api.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/lport_api.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/lport_api.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/lport_api.c	2010-05-16 17:17:36.000000000 -0400
@@ -156,7 +156,7 @@ bfa_fcs_port_get_rport_max_speed(struct
 	/*
 	 * Get Physical port's current speed
 	 */
-	bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
+	bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
 	pport_speed = pport_attr.speed;
 	bfa_trc(fcs, pport_speed);
 
@@ -235,7 +235,8 @@ bfa_fcs_port_get_info(struct bfa_fcs_por
 		port_info->port_wwn = bfa_fcs_port_get_pwwn(port);
 		port_info->node_wwn = bfa_fcs_port_get_nwwn(port);
 
-		port_info->max_vports_supp = bfa_fcs_vport_get_max(port->fcs);
+		port_info->max_vports_supp =
+			bfa_lps_get_max_vport(port->fcs->bfa);
 		port_info->num_vports_inuse =
 			bfa_fcs_fabric_vport_count(port->fabric);
 		port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/Makefile linux-libre-2.6.34-gnu1/drivers/scsi/bfa/Makefile
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -2,14 +2,14 @@ obj-$(CONFIG_SCSI_BFA_FC) := bfa.o
 
 bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o
 
-bfa-y += bfa_core.o bfa_ioc.o bfa_iocfc.o bfa_fcxp.o bfa_lps.o
-bfa-y += bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o 
+bfa-y += bfa_core.o bfa_ioc.o bfa_ioc_ct.o bfa_ioc_cb.o bfa_iocfc.o bfa_fcxp.o
+bfa-y += bfa_lps.o bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o
 bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o
 bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o
 bfa-y += bfa_csdebug.o bfa_sm.o plog.o
 
-bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o 
+bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o
 bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o
 bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o
 
-ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna
+ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna -DBFA_PERF_BUILD
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/ms.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/ms.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/ms.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/ms.c	2010-05-16 17:17:36.000000000 -0400
@@ -118,7 +118,7 @@ bfa_fcs_port_ms_sm_offline(struct bfa_fc
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ms->port->fcs, event);
 	}
 }
 
@@ -141,7 +141,7 @@ bfa_fcs_port_ms_sm_plogi_sending(struct
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ms->port->fcs, event);
 	}
 }
 
@@ -190,7 +190,7 @@ bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ms->port->fcs, event);
 	}
 }
 
@@ -216,7 +216,7 @@ bfa_fcs_port_ms_sm_plogi_retry(struct bf
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ms->port->fcs, event);
 	}
 }
 
@@ -230,10 +230,6 @@ bfa_fcs_port_ms_sm_online(struct bfa_fcs
 	switch (event) {
 	case MSSM_EVENT_PORT_OFFLINE:
 		bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
-		/*
-		 * now invoke MS related sub-modules
-		 */
-		bfa_fcs_port_fdmi_offline(ms);
 		break;
 
 	case MSSM_EVENT_PORT_FABRIC_RSCN:
@@ -243,7 +239,7 @@ bfa_fcs_port_ms_sm_online(struct bfa_fcs
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ms->port->fcs, event);
 	}
 }
 
@@ -266,7 +262,7 @@ bfa_fcs_port_ms_sm_gmal_sending(struct b
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ms->port->fcs, event);
 	}
 }
 
@@ -304,7 +300,7 @@ bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_p
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ms->port->fcs, event);
 	}
 }
 
@@ -330,7 +326,7 @@ bfa_fcs_port_ms_sm_gmal_retry(struct bfa
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ms->port->fcs, event);
 	}
 }
 
@@ -466,7 +462,7 @@ bfa_fcs_port_ms_sm_gfn_sending(struct bf
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ms->port->fcs, event);
 	}
 }
 
@@ -502,7 +498,7 @@ bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_po
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ms->port->fcs, event);
 	}
 }
 
@@ -528,7 +524,7 @@ bfa_fcs_port_ms_sm_gfn_retry(struct bfa_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ms->port->fcs, event);
 	}
 }
 
@@ -637,7 +633,7 @@ bfa_fcs_port_ms_send_plogi(void *ms_cbar
 			     bfa_os_hton3b(FC_MGMT_SERVER),
 			     bfa_fcs_port_get_fcid(port), 0,
 			     port->port_cfg.pwwn, port->port_cfg.nwwn,
-			     bfa_pport_get_maxfrsize(port->fcs->bfa));
+			     bfa_fcport_get_maxfrsize(port->fcs->bfa));
 
 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
 		      FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_plogi_response,
@@ -735,6 +731,7 @@ bfa_fcs_port_ms_offline(struct bfa_fcs_p
 
 	ms->port = port;
 	bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE);
+	bfa_fcs_port_fdmi_offline(ms);
 }
 
 void
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/ns.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/ns.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/ns.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/ns.c	2010-05-16 17:17:36.000000000 -0400
@@ -164,7 +164,7 @@ bfa_fcs_port_ns_sm_offline(struct bfa_fc
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -187,7 +187,7 @@ bfa_fcs_port_ns_sm_plogi_sending(struct
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -221,7 +221,7 @@ bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -247,7 +247,7 @@ bfa_fcs_port_ns_sm_plogi_retry(struct bf
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -270,7 +270,7 @@ bfa_fcs_port_ns_sm_sending_rspn_id(struc
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -304,7 +304,7 @@ bfa_fcs_port_ns_sm_rspn_id(struct bfa_fc
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -330,7 +330,7 @@ bfa_fcs_port_ns_sm_rspn_id_retry(struct
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -353,7 +353,7 @@ bfa_fcs_port_ns_sm_sending_rft_id(struct
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -390,7 +390,7 @@ bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -413,7 +413,7 @@ bfa_fcs_port_ns_sm_rft_id_retry(struct b
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -436,7 +436,7 @@ bfa_fcs_port_ns_sm_sending_rff_id(struct
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -494,7 +494,7 @@ bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -517,7 +517,7 @@ bfa_fcs_port_ns_sm_rff_id_retry(struct b
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 static void
@@ -539,7 +539,7 @@ bfa_fcs_port_ns_sm_sending_gid_ft(struct
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -575,7 +575,7 @@ bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -598,7 +598,7 @@ bfa_fcs_port_ns_sm_gid_ft_retry(struct b
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -626,7 +626,7 @@ bfa_fcs_port_ns_sm_online(struct bfa_fcs
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(ns->port->fcs, event);
 	}
 }
 
@@ -660,7 +660,7 @@ bfa_fcs_port_ns_send_plogi(void *ns_cbar
 			     bfa_os_hton3b(FC_NAME_SERVER),
 			     bfa_fcs_port_get_fcid(port), 0,
 			     port->port_cfg.pwwn, port->port_cfg.nwwn,
-			     bfa_pport_get_maxfrsize(port->fcs->bfa));
+			     bfa_fcport_get_maxfrsize(port->fcs->bfa));
 
 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
 		      FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_plogi_response,
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/rport_api.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/rport_api.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/rport_api.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/rport_api.c	2010-05-16 17:17:36.000000000 -0400
@@ -102,7 +102,7 @@ bfa_fcs_rport_get_attr(struct bfa_fcs_rp
 	rport_attr->qos_attr = qos_attr;
 
 	rport_attr->trl_enforced = BFA_FALSE;
-	if (bfa_pport_is_ratelim(port->fcs->bfa)) {
+	if (bfa_fcport_is_ratelim(port->fcs->bfa)) {
 		if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN) ||
 			(rport->rpf.rpsc_speed <
 			bfa_fcs_port_get_rport_max_speed(port)))
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/rport.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/rport.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/rport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/rport.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  *  rport.c Remote port implementation.
  */
 
+#include <linux/slab.h>
 #include <bfa.h>
 #include <bfa_svc.h>
 #include "fcbuild.h"
@@ -224,7 +225,7 @@ bfa_fcs_rport_sm_uninit(struct bfa_fcs_r
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -276,7 +277,7 @@ bfa_fcs_rport_sm_plogi_sending(struct bf
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -332,7 +333,7 @@ bfa_fcs_rport_sm_plogiacc_sending(struct
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -406,7 +407,7 @@ bfa_fcs_rport_sm_plogi_retry(struct bfa_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -481,7 +482,7 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rp
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -534,7 +535,7 @@ bfa_fcs_rport_sm_hal_online(struct bfa_f
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -589,7 +590,7 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_r
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -646,7 +647,7 @@ bfa_fcs_rport_sm_nsquery_sending(struct
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -704,7 +705,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -754,7 +755,7 @@ bfa_fcs_rport_sm_adisc_sending(struct bf
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -816,7 +817,7 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rp
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -846,7 +847,7 @@ bfa_fcs_rport_sm_fc4_logorcv(struct bfa_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -869,7 +870,7 @@ bfa_fcs_rport_sm_fc4_logosend(struct bfa
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -905,7 +906,7 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -925,10 +926,17 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_
 	case RPSM_EVENT_HCB_OFFLINE:
 	case RPSM_EVENT_ADDRESS_CHANGE:
 		if (bfa_fcs_port_is_online(rport->port)) {
-			bfa_sm_set_state(rport,
-					 bfa_fcs_rport_sm_nsdisc_sending);
-			rport->ns_retries = 0;
-			bfa_fcs_rport_send_gidpn(rport, NULL);
+			if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
+				bfa_sm_set_state(rport,
+					bfa_fcs_rport_sm_nsdisc_sending);
+				rport->ns_retries = 0;
+				bfa_fcs_rport_send_gidpn(rport, NULL);
+			} else {
+				bfa_sm_set_state(rport,
+					bfa_fcs_rport_sm_plogi_sending);
+				rport->plogi_retries = 0;
+				bfa_fcs_rport_send_plogi(rport, NULL);
+			}
 		} else {
 			rport->pid = 0;
 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
@@ -951,7 +959,7 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -1011,7 +1019,7 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -1038,7 +1046,7 @@ bfa_fcs_rport_sm_hcb_logosend(struct bfa
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -1073,7 +1081,7 @@ bfa_fcs_rport_sm_logo_sending(struct bfa
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -1132,7 +1140,7 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -1188,7 +1196,7 @@ bfa_fcs_rport_sm_nsdisc_sending(struct b
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -1249,7 +1257,7 @@ bfa_fcs_rport_sm_nsdisc_retry(struct bfa
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -1334,7 +1342,7 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -1366,7 +1374,7 @@ bfa_fcs_rport_send_plogi(void *rport_cba
 	len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
 			     bfa_fcs_port_get_fcid(port), 0,
 			     port->port_cfg.pwwn, port->port_cfg.nwwn,
-			     bfa_pport_get_maxfrsize(port->fcs->bfa));
+			     bfa_fcport_get_maxfrsize(port->fcs->bfa));
 
 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
 		      FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
@@ -1478,7 +1486,7 @@ bfa_fcs_rport_send_plogiacc(void *rport_
 	len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
 				 bfa_fcs_port_get_fcid(port), rport->reply_oxid,
 				 port->port_cfg.pwwn, port->port_cfg.nwwn,
-				 bfa_pport_get_maxfrsize(port->fcs->bfa));
+				 bfa_fcport_get_maxfrsize(port->fcs->bfa));
 
 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
 		      FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
@@ -1813,7 +1821,7 @@ bfa_fcs_rport_process_rpsc(struct bfa_fc
 	/*
 	 * get curent speed from pport attributes from BFA
 	 */
-	bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
+	bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
 
 	speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
 
@@ -2032,13 +2040,10 @@ bfa_fcs_rport_aen_post(struct bfa_fcs_rp
 
 	switch (event) {
 	case BFA_RPORT_AEN_ONLINE:
-		bfa_log(logmod, BFA_AEN_RPORT_ONLINE, rpwwn_ptr, lpwwn_ptr);
-		break;
 	case BFA_RPORT_AEN_OFFLINE:
-		bfa_log(logmod, BFA_AEN_RPORT_OFFLINE, rpwwn_ptr, lpwwn_ptr);
-		break;
 	case BFA_RPORT_AEN_DISCONNECT:
-		bfa_log(logmod, BFA_AEN_RPORT_DISCONNECT, rpwwn_ptr, lpwwn_ptr);
+		bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, event),
+			rpwwn_ptr, lpwwn_ptr);
 		break;
 	case BFA_RPORT_AEN_QOS_PRIO:
 		aen_data.rport.priv.qos = data->priv.qos;
@@ -2164,7 +2169,7 @@ bfa_fcs_rport_update(struct bfa_fcs_rpor
 		bfa_trc(port->fcs, port->fabric->bb_credit);
 
 		port->fabric->bb_credit = bfa_os_ntohs(plogi->csp.bbcred);
-		bfa_pport_set_tx_bbcredit(port->fcs->bfa,
+		bfa_fcport_set_tx_bbcredit(port->fcs->bfa,
 					  port->fabric->bb_credit);
 	}
 
@@ -2575,23 +2580,6 @@ bfa_fcs_rport_send_ls_rjt(struct bfa_fcs
 }
 
 /**
- *   Module initialization
- */
-void
-bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs)
-{
-}
-
-/**
- *   Module cleanup
- */
-void
-bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs)
-{
-	bfa_fcs_modexit_comp(fcs);
-}
-
-/**
  * Return state of rport.
  */
 int
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/rport_ftrs.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/rport_ftrs.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/rport_ftrs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/rport_ftrs.c	2010-05-16 17:17:36.000000000 -0400
@@ -91,7 +91,7 @@ bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -114,7 +114,7 @@ bfa_fcs_rpf_sm_rpsc_sending(struct bfa_f
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -160,7 +160,7 @@ bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -186,7 +186,7 @@ bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -206,7 +206,7 @@ bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 
@@ -229,7 +229,7 @@ bfa_fcs_rpf_sm_offline(struct bfa_fcs_rp
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(rport->fcs, event);
 	}
 }
 /**
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/scn.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/scn.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/scn.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/scn.c	2010-05-16 17:17:36.000000000 -0400
@@ -90,7 +90,7 @@ bfa_fcs_port_scn_sm_offline(struct bfa_f
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(scn->port->fcs, event);
 	}
 }
 
@@ -109,7 +109,7 @@ bfa_fcs_port_scn_sm_sending_scr(struct b
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(scn->port->fcs, event);
 	}
 }
 
@@ -137,7 +137,7 @@ bfa_fcs_port_scn_sm_scr(struct bfa_fcs_p
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(scn->port->fcs, event);
 	}
 }
 
@@ -157,7 +157,7 @@ bfa_fcs_port_scn_sm_scr_retry(struct bfa
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(scn->port->fcs, event);
 	}
 }
 
@@ -171,7 +171,7 @@ bfa_fcs_port_scn_sm_online(struct bfa_fc
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(scn->port->fcs, event);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bfa/vport.c linux-libre-2.6.34-gnu1/drivers/scsi/bfa/vport.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bfa/vport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bfa/vport.c	2010-05-16 17:17:36.000000000 -0400
@@ -122,7 +122,7 @@ bfa_fcs_vport_sm_uninit(struct bfa_fcs_v
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(__vport_fcs(vport), event);
 	}
 }
 
@@ -165,7 +165,7 @@ bfa_fcs_vport_sm_created(struct bfa_fcs_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(__vport_fcs(vport), event);
 	}
 }
 
@@ -202,7 +202,7 @@ bfa_fcs_vport_sm_offline(struct bfa_fcs_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(__vport_fcs(vport), event);
 	}
 }
 
@@ -249,7 +249,7 @@ bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vp
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(__vport_fcs(vport), event);
 	}
 }
 
@@ -283,7 +283,7 @@ bfa_fcs_vport_sm_fdisc_retry(struct bfa_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(__vport_fcs(vport), event);
 	}
 }
 
@@ -310,7 +310,7 @@ bfa_fcs_vport_sm_online(struct bfa_fcs_v
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(__vport_fcs(vport), event);
 	}
 }
 
@@ -339,7 +339,7 @@ bfa_fcs_vport_sm_deleting(struct bfa_fcs
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(__vport_fcs(vport), event);
 	}
 }
 
@@ -387,7 +387,7 @@ bfa_fcs_vport_sm_cleanup(struct bfa_fcs_
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(__vport_fcs(vport), event);
 	}
 }
 
@@ -419,7 +419,7 @@ bfa_fcs_vport_sm_logo(struct bfa_fcs_vpo
 		break;
 
 	default:
-		bfa_assert(0);
+		bfa_sm_fault(__vport_fcs(vport), event);
 	}
 }
 
@@ -447,22 +447,8 @@ bfa_fcs_vport_aen_post(bfa_fcs_lport_t *
 
 	bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
 
-	switch (event) {
-	case BFA_LPORT_AEN_NPIV_DUP_WWN:
-		bfa_log(logmod, BFA_AEN_LPORT_NPIV_DUP_WWN, lpwwn_ptr,
-			role_str[role / 2]);
-		break;
-	case BFA_LPORT_AEN_NPIV_FABRIC_MAX:
-		bfa_log(logmod, BFA_AEN_LPORT_NPIV_FABRIC_MAX, lpwwn_ptr,
-			role_str[role / 2]);
-		break;
-	case BFA_LPORT_AEN_NPIV_UNKNOWN:
-		bfa_log(logmod, BFA_AEN_LPORT_NPIV_UNKNOWN, lpwwn_ptr,
-			role_str[role / 2]);
-		break;
-	default:
-		break;
-	}
+	bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr,
+			role_str[role/2]);
 
 	aen_data.lport.vf_id = port->fabric->vf_id;
 	aen_data.lport.roles = role;
@@ -478,7 +464,7 @@ static void
 bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport)
 {
 	bfa_lps_fdisc(vport->lps, vport,
-		      bfa_pport_get_maxfrsize(__vport_bfa(vport)),
+		      bfa_fcport_get_maxfrsize(__vport_bfa(vport)),
 		      __vport_pwwn(vport), __vport_nwwn(vport));
 	vport->vport_stats.fdisc_sent++;
 }
@@ -617,38 +603,6 @@ bfa_fcs_vport_delete_comp(struct bfa_fcs
 }
 
 /**
- *   Module initialization
- */
-void
-bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs)
-{
-}
-
-/**
- *   Module cleanup
- */
-void
-bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs)
-{
-	bfa_fcs_modexit_comp(fcs);
-}
-
-u32
-bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs)
-{
-	struct bfa_ioc_attr_s ioc_attr;
-
-	bfa_get_attr(fcs->bfa, &ioc_attr);
-
-	if (ioc_attr.pci_attr.device_id == BFA_PCI_DEVICE_ID_CT)
-		return BFA_FCS_MAX_VPORTS_SUPP_CT;
-	else
-		return BFA_FCS_MAX_VPORTS_SUPP_CB;
-}
-
-
-
-/**
  *  fcs_vport_api Virtual port API
  */
 
@@ -684,7 +638,7 @@ bfa_fcs_vport_create(struct bfa_fcs_vpor
 		return BFA_STATUS_VPORT_EXISTS;
 
 	if (bfa_fcs_fabric_vport_count(&fcs->fabric) ==
-	    bfa_fcs_vport_get_max(fcs))
+		bfa_lps_get_max_vport(fcs->bfa))
 		return BFA_STATUS_VPORT_MAX;
 
 	vport->lps = bfa_lps_alloc(fcs->bfa);
@@ -694,7 +648,8 @@ bfa_fcs_vport_create(struct bfa_fcs_vpor
 	vport->vport_drv = vport_drv;
 	bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
 
-	bfa_fcs_lport_init(&vport->lport, fcs, vf_id, vport_cfg, vport);
+	bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport);
+	bfa_fcs_lport_init(&vport->lport, vport_cfg);
 
 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE);
 
@@ -888,4 +843,15 @@ bfa_cb_lps_fdisclogo_comp(void *bfad, vo
 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
 }
 
+/**
+ * Received clear virtual link
+ */
+void
+bfa_cb_lps_cvl_event(void *bfad, void *uarg)
+{
+	struct bfa_fcs_vport_s *vport = uarg;
 
+	/* Send an Offline followed by an ONLINE */
+	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
+	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i.h linux-libre-2.6.34-gnu1/drivers/scsi/bnx2i/bnx2i.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bnx2i/bnx2i.h	2010-05-16 17:17:36.000000000 -0400
@@ -362,6 +362,7 @@ struct bnx2i_hba {
 	u32 num_ccell;
 
 	int ofld_conns_active;
+	wait_queue_head_t eh_wait;
 
 	int max_active_conns;
 	struct iscsi_cid_queue cid_que;
@@ -381,6 +382,7 @@ struct bnx2i_hba {
 	spinlock_t lock;	/* protects hba structure access */
 	struct mutex net_dev_lock;/* sync net device access */
 
+	int hba_shutdown_tmo;
 	/*
 	 * PCI related info.
 	 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i_hwi.c linux-libre-2.6.34-gnu1/drivers/scsi/bnx2i/bnx2i_hwi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i_hwi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bnx2i/bnx2i_hwi.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
  * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
  */
 
+#include <linux/gfp.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/libiscsi.h>
 #include "bnx2i.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i_init.c linux-libre-2.6.34-gnu1/drivers/scsi/bnx2i/bnx2i_init.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bnx2i/bnx2i_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -177,11 +177,22 @@ void bnx2i_stop(void *handle)
 	struct bnx2i_hba *hba = handle;
 
 	/* check if cleanup happened in GOING_DOWN context */
-	clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
 	if (!test_and_clear_bit(ADAPTER_STATE_GOING_DOWN,
 				&hba->adapter_state))
 		iscsi_host_for_each_session(hba->shost,
 					    bnx2i_drop_session);
+
+	/* Wait for all endpoints to be torn down, Chip will be reset once
+	 *  control returns to network driver. So it is required to cleanup and
+	 * release all connection resources before returning from this routine.
+	 */
+	wait_event_interruptible_timeout(hba->eh_wait,
+					 (hba->ofld_conns_active == 0),
+					 hba->hba_shutdown_tmo);
+	/* This flag should be cleared last so that ep_disconnect() gracefully
+	 * cleans up connection context
+	 */
+	clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
 }
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i_iscsi.c linux-libre-2.6.34-gnu1/drivers/scsi/bnx2i/bnx2i_iscsi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i_iscsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bnx2i/bnx2i_iscsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
  * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
  */
 
+#include <linux/slab.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/libiscsi.h>
 #include "bnx2i.h"
@@ -819,6 +820,11 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct
 
 	spin_lock_init(&hba->lock);
 	mutex_init(&hba->net_dev_lock);
+	init_waitqueue_head(&hba->eh_wait);
+	if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type))
+		hba->hba_shutdown_tmo = 240 * HZ;
+	else	/* 5706/5708/5709 */
+		hba->hba_shutdown_tmo = 30 * HZ;
 
 	if (iscsi_host_add(shost, &hba->pcidev->dev))
 		goto free_dump_mem;
@@ -1426,8 +1432,8 @@ static int bnx2i_conn_get_param(struct i
 		break;
 	case ISCSI_PARAM_CONN_ADDRESS:
 		if (bnx2i_conn->ep)
-			len = sprintf(buf, NIPQUAD_FMT "\n",
-				      NIPQUAD(bnx2i_conn->ep->cm_sk->dst_ip));
+			len = sprintf(buf, "%pI4\n",
+				      &bnx2i_conn->ep->cm_sk->dst_ip);
 		break;
 	default:
 		return iscsi_conn_get_param(cls_conn, param, buf);
@@ -1657,8 +1663,8 @@ static struct iscsi_endpoint *bnx2i_ep_c
 		 */
 		hba = bnx2i_check_route(dst_addr);
 
-	if (!hba) {
-		rc = -ENOMEM;
+	if (!hba || test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state)) {
+		rc = -EINVAL;
 		goto check_busy;
 	}
 
@@ -1803,7 +1809,7 @@ static int bnx2i_ep_poll(struct iscsi_en
 					       (bnx2i_ep->state ==
 						EP_STATE_CONNECT_COMPL)),
 					      msecs_to_jiffies(timeout_ms));
-	if (!rc || (bnx2i_ep->state == EP_STATE_OFLD_FAILED))
+	if (bnx2i_ep->state == EP_STATE_OFLD_FAILED)
 		rc = -1;
 
 	if (rc > 0)
@@ -1956,6 +1962,8 @@ return_bnx2i_ep:
 
 	if (!hba->ofld_conns_active)
 		bnx2i_unreg_dev_all();
+
+	wake_up_interruptible(&hba->eh_wait);
 }
 
 
@@ -1989,7 +1997,8 @@ static struct scsi_host_template bnx2i_h
 	.queuecommand		= iscsi_queuecommand,
 	.eh_abort_handler	= iscsi_eh_abort,
 	.eh_device_reset_handler = iscsi_eh_device_reset,
-	.eh_target_reset_handler = iscsi_eh_target_reset,
+	.eh_target_reset_handler = iscsi_eh_recover_target,
+	.change_queue_depth	= iscsi_change_queue_depth,
 	.can_queue		= 1024,
 	.max_sectors		= 127,
 	.cmd_per_lun		= 32,
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/BusLogic.c linux-libre-2.6.34-gnu1/drivers/scsi/BusLogic.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/BusLogic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/BusLogic.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/spinlock.h>
 #include <linux/jiffies.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <scsi/scsicam.h>
 
 #include <asm/dma.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/bvme6000_scsi.c linux-libre-2.6.34-gnu1/drivers/scsi/bvme6000_scsi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/bvme6000_scsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/bvme6000_scsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/bvme6000hw.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/ch.c linux-libre-2.6.34-gnu1/drivers/scsi/ch.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/ch.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/ch.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/mutex.h>
 #include <linux/idr.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/constants.c linux-libre-2.6.34-gnu1/drivers/scsi/constants.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/constants.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/constants.c	2010-05-16 17:17:36.000000000 -0400
@@ -219,18 +219,15 @@ static void print_opcode_name(unsigned c
 			break;
 		}
 		sa = (cdbp[8] << 8) + cdbp[9];
-		name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa);
-		if (name) {
+		name = get_sa_name(variable_length_arr, VARIABLE_LENGTH_SZ, sa);
+		if (name)
 			printk("%s", name);
-			if ((cdb_len > 0) && (len != cdb_len))
-				printk(", in_cdb_len=%d, ext_len=%d",
-				       len, cdb_len);
-		} else {
+		else
 			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
-			if ((cdb_len > 0) && (len != cdb_len))
-				printk(", in_cdb_len=%d, ext_len=%d",
-				       len, cdb_len);
-		}
+
+		if ((cdb_len > 0) && (len != cdb_len))
+			printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len);
+
 		break;
 	case MAINTENANCE_IN:
 		sa = cdbp[1] & 0x1f;
@@ -349,6 +346,9 @@ void scsi_print_command(struct scsi_cmnd
 {
 	int k;
 
+	if (cmd->cmnd == NULL)
+		return;
+
 	scmd_printk(KERN_INFO, cmd, "CDB: ");
 	print_opcode_name(cmd->cmnd, cmd->cmd_len);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_ddp.c linux-libre-2.6.34-gnu1/drivers/scsi/cxgb3i/cxgb3i_ddp.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_ddp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/cxgb3i/cxgb3i_ddp.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  * Written by: Karen Xie (kxie@chelsio.com)
  */
 
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/scatterlist.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_ddp.h linux-libre-2.6.34-gnu1/drivers/scsi/cxgb3i/cxgb3i_ddp.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_ddp.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/cxgb3i/cxgb3i_ddp.h	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #ifndef __CXGB3I_ULP2_DDP_H__
 #define __CXGB3I_ULP2_DDP_H__
 
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_iscsi.c linux-libre-2.6.34-gnu1/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_iscsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/cxgb3i/cxgb3i_iscsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
  */
 
 #include <linux/inet.h>
+#include <linux/slab.h>
 #include <linux/crypto.h>
 #include <linux/if_vlan.h>
 #include <net/dst.h>
@@ -591,8 +592,7 @@ static int cxgb3i_conn_bind(struct iscsi
 	cxgb3i_conn_max_recv_dlength(conn);
 
 	spin_lock_bh(&conn->session->lock);
-	sprintf(conn->portal_address, NIPQUAD_FMT,
-		NIPQUAD(c3cn->daddr.sin_addr.s_addr));
+	sprintf(conn->portal_address, "%pI4", &c3cn->daddr.sin_addr.s_addr);
 	conn->portal_port = ntohs(c3cn->daddr.sin_port);
 	spin_unlock_bh(&conn->session->lock);
 
@@ -709,6 +709,12 @@ static int cxgb3i_host_set_param(struct
 {
 	struct cxgb3i_hba *hba = iscsi_host_priv(shost);
 
+	if (!hba->ndev) {
+		shost_printk(KERN_ERR, shost, "Could not set host param. "
+			     "Netdev for host not set.\n");
+		return -ENODEV;
+	}
+
 	cxgb3i_api_debug("param %d, buf %s.\n", param, buf);
 
 	switch (param) {
@@ -739,6 +745,12 @@ static int cxgb3i_host_get_param(struct
 	struct cxgb3i_hba *hba = iscsi_host_priv(shost);
 	int len = 0;
 
+	if (!hba->ndev) {
+		shost_printk(KERN_ERR, shost, "Could not set host param. "
+			     "Netdev for host not set.\n");
+		return -ENODEV;
+	}
+
 	cxgb3i_api_debug("hba %s, param %d.\n", hba->ndev->name, param);
 
 	switch (param) {
@@ -753,7 +765,7 @@ static int cxgb3i_host_get_param(struct
 		__be32 addr;
 
 		addr = cxgb3i_get_private_ipv4addr(hba->ndev);
-		len = sprintf(buf, NIPQUAD_FMT, NIPQUAD(addr));
+		len = sprintf(buf, "%pI4", &addr);
 		break;
 	}
 	default:
@@ -904,7 +916,7 @@ static struct scsi_host_template cxgb3i_
 	.cmd_per_lun		= ISCSI_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,
+	.eh_target_reset_handler = iscsi_eh_recover_target,
 	.target_alloc		= iscsi_target_alloc,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.this_id		= -1,
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_offload.c linux-libre-2.6.34-gnu1/drivers/scsi/cxgb3i/cxgb3i_offload.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_offload.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/cxgb3i/cxgb3i_offload.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
  */
 
 #include <linux/if_vlan.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 
 #include "cxgb3_defs.h"
@@ -1675,10 +1676,11 @@ int cxgb3i_c3cn_connect(struct net_devic
 	} else
 		c3cn->saddr.sin_addr.s_addr = sipv4;
 
-	c3cn_conn_debug("c3cn 0x%p, %u.%u.%u.%u,%u-%u.%u.%u.%u,%u SYN_SENT.\n",
-			c3cn, NIPQUAD(c3cn->saddr.sin_addr.s_addr),
+	c3cn_conn_debug("c3cn 0x%p, %pI4,%u-%pI4,%u SYN_SENT.\n",
+			c3cn,
+			&c3cn->saddr.sin_addr.s_addr,
 			ntohs(c3cn->saddr.sin_port),
-			NIPQUAD(c3cn->daddr.sin_addr.s_addr),
+			&c3cn->daddr.sin_addr.s_addr,
 			ntohs(c3cn->daddr.sin_port));
 
 	c3cn_set_state(c3cn, C3CN_STATE_CONNECTING);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_pdu.c linux-libre-2.6.34-gnu1/drivers/scsi/cxgb3i/cxgb3i_pdu.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_pdu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/cxgb3i/cxgb3i_pdu.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
  * Written by: Karen Xie (kxie@chelsio.com)
  */
 
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/crypto.h>
 #include <scsi/scsi_cmnd.h>
@@ -461,10 +462,8 @@ void cxgb3i_conn_pdu_ready(struct s3_con
 		skb = skb_peek(&c3cn->receive_queue);
 	}
 	read_unlock(&c3cn->callback_lock);
-	if (c3cn) {
-		c3cn->copied_seq += read;
-		cxgb3i_c3cn_rx_credits(c3cn, read);
-	}
+	c3cn->copied_seq += read;
+	cxgb3i_c3cn_rx_credits(c3cn, read);
 	conn->rxdata_octets += read;
 
 	if (err) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/dc395x.c linux-libre-2.6.34-gnu1/drivers/scsi/dc395x.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/dc395x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/dc395x.c	2010-05-16 17:17:36.000000000 -0400
@@ -57,6 +57,7 @@
 #include <linux/pci.h>
 #include <linux/list.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #include <scsi/scsi.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_alua.c linux-libre-2.6.34-gnu1/drivers/scsi/device_handler/scsi_dh_alua.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_alua.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/device_handler/scsi_dh_alua.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
  */
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_dh.h>
@@ -717,6 +718,8 @@ static const struct scsi_dh_devlist alua
 	{"IBM", "2145" },
 	{"Pillar", "Axiom" },
 	{"Intel", "Multi-Flex"},
+	{"NETAPP", "LUN"},
+	{"AIX", "NVDISK"},
 	{NULL, NULL}
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh.c linux-libre-2.6.34-gnu1/drivers/scsi/device_handler/scsi_dh.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/device_handler/scsi_dh.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
  *               Mike Anderson <andmike@linux.vnet.ibm.com>
  */
 
+#include <linux/slab.h>
 #include <scsi/scsi_dh.h>
 #include "../scsi_priv.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_emc.c linux-libre-2.6.34-gnu1/drivers/scsi/device_handler/scsi_dh_emc.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_emc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/device_handler/scsi_dh_emc.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  * along with this program; see the file COPYING.  If not, write to
  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  */
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_dh.h>
@@ -272,7 +273,7 @@ static struct request *get_req(struct sc
 	int len = 0;
 
 	rq = blk_get_request(sdev->request_queue,
-			(cmd == MODE_SELECT) ? WRITE : READ, GFP_NOIO);
+			(cmd != INQUIRY) ? WRITE : READ, GFP_NOIO);
 	if (!rq) {
 		sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed");
 		return NULL;
@@ -286,14 +287,17 @@ static struct request *get_req(struct sc
 		len = sizeof(short_trespass);
 		rq->cmd_flags |= REQ_RW;
 		rq->cmd[1] = 0x10;
+		rq->cmd[4] = len;
 		break;
 	case MODE_SELECT_10:
 		len = sizeof(long_trespass);
 		rq->cmd_flags |= REQ_RW;
 		rq->cmd[1] = 0x10;
+		rq->cmd[8] = len;
 		break;
 	case INQUIRY:
 		len = CLARIION_BUFFER_SIZE;
+		rq->cmd[4] = len;
 		memset(buffer, 0, len);
 		break;
 	default:
@@ -301,7 +305,6 @@ static struct request *get_req(struct sc
 		break;
 	}
 
-	rq->cmd[4] = len;
 	rq->cmd_type = REQ_TYPE_BLOCK_PC;
 	rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
 			 REQ_FAILFAST_DRIVER;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_hp_sw.c linux-libre-2.6.34-gnu1/drivers/scsi/device_handler/scsi_dh_hp_sw.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_hp_sw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/device_handler/scsi_dh_hp_sw.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_eh.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_rdac.c linux-libre-2.6.34-gnu1/drivers/scsi/device_handler/scsi_dh_rdac.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_rdac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/device_handler/scsi_dh_rdac.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_dh.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 #define RDAC_NAME "rdac"
 #define RDAC_RETRY_COUNT 5
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/dpt_i2o.c linux-libre-2.6.34-gnu1/drivers/scsi/dpt_i2o.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/dpt_i2o.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/dpt_i2o.c	2010-05-16 17:17:36.000000000 -0400
@@ -188,7 +188,8 @@ MODULE_DEVICE_TABLE(pci,dptids);
 static int adpt_detect(struct scsi_host_template* sht)
 {
 	struct pci_dev *pDev = NULL;
-	adpt_hba* pHba;
+	adpt_hba *pHba;
+	adpt_hba *next;
 
 	PINFO("Detecting Adaptec I2O RAID controllers...\n");
 
@@ -206,7 +207,8 @@ static int adpt_detect(struct scsi_host_
 	}
 
 	/* In INIT state, Activate IOPs */
-	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+	for (pHba = hba_chain; pHba; pHba = next) {
+		next = pHba->next;
 		// Activate does get status , init outbound, and get hrt
 		if (adpt_i2o_activate_hba(pHba) < 0) {
 			adpt_i2o_delete_hba(pHba);
@@ -243,7 +245,8 @@ rebuild_sys_tab:
 	PDEBUG("HBA's in OPERATIONAL state\n");
 
 	printk("dpti: If you have a lot of devices this could take a few minutes.\n");
-	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+	for (pHba = hba_chain; pHba; pHba = next) {
+		next = pHba->next;
 		printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
 		if (adpt_i2o_lct_get(pHba) < 0){
 			adpt_i2o_delete_hba(pHba);
@@ -263,7 +266,8 @@ rebuild_sys_tab:
 		adpt_sysfs_class = NULL;
 	}
 
-	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+	for (pHba = hba_chain; pHba; pHba = next) {
+		next = pHba->next;
 		if (adpt_scsi_host_alloc(pHba, sht) < 0){
 			adpt_i2o_delete_hba(pHba);
 			continue;
@@ -1229,11 +1233,10 @@ static void adpt_i2o_delete_hba(adpt_hba
 		}
 	}
 	pci_dev_put(pHba->pDev);
-	kfree(pHba);
-
 	if (adpt_sysfs_class)
 		device_destroy(adpt_sysfs_class,
 				MKDEV(DPTI_I2O_MAJOR, pHba->unit));
+	kfree(pHba);
 
 	if(hba_count <= 0){
 		unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);   
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/eata.c linux-libre-2.6.34-gnu1/drivers/scsi/eata.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/eata.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/eata.c	2010-05-16 17:17:36.000000000 -0400
@@ -490,6 +490,7 @@
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 #include <asm/dma.h>
 #include <asm/io.h>
@@ -1509,7 +1510,7 @@ static int option_setup(char *str)
 	char *cur = str;
 	int i = 1;
 
-	while (cur && isdigit(*cur) && i <= MAX_INT_PARAM) {
+	while (cur && isdigit(*cur) && i < MAX_INT_PARAM) {
 		ints[i++] = simple_strtoul(cur, NULL, 0);
 
 		if ((cur = strchr(cur, ',')) != NULL)
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/eata_pio.c linux-libre-2.6.34-gnu1/drivers/scsi/eata_pio.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/eata_pio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/eata_pio.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,7 +50,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/in.h>
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/esp_scsi.c linux-libre-2.6.34-gnu1/drivers/scsi/esp_scsi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/esp_scsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/esp_scsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -1449,9 +1449,6 @@ static void esp_msgin_sdtr(struct esp *e
 	if (offset > 15)
 		goto do_reject;
 
-	if (esp->flags & ESP_FLAG_DISABLE_SYNC)
-		offset = 0;
-
 	if (offset) {
 		int one_clock;
 
@@ -2405,12 +2402,6 @@ static int esp_slave_configure(struct sc
 	struct esp_target_data *tp = &esp->target[dev->id];
 	int goal_tags, queue_depth;
 
-	if (esp->flags & ESP_FLAG_DISABLE_SYNC) {
-		/* Bypass async domain validation */
-		dev->ppr  = 0;
-		dev->sdtr = 0;
-	}
-
 	goal_tags = 0;
 
 	if (dev->tagged_supported) {
@@ -2660,7 +2651,10 @@ static void esp_set_offset(struct scsi_t
 	struct esp *esp = shost_priv(host);
 	struct esp_target_data *tp = &esp->target[target->id];
 
-	tp->nego_goal_offset = offset;
+	if (esp->flags & ESP_FLAG_DISABLE_SYNC)
+		tp->nego_goal_offset = 0;
+	else
+		tp->nego_goal_offset = offset;
 	tp->flags |= ESP_TGT_CHECK_NEGO;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/fcoe/fcoe.c linux-libre-2.6.34-gnu1/drivers/scsi/fcoe/fcoe.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/fcoe/fcoe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/fcoe/fcoe.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/crc32.h>
+#include <linux/slab.h>
 #include <linux/cpu.h>
 #include <linux/fs.h>
 #include <linux/sysfs.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/fcoe/libfcoe.c linux-libre-2.6.34-gnu1/drivers/scsi/fcoe/libfcoe.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/fcoe/libfcoe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/fcoe/libfcoe.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/if_vlan.h>
 #include <linux/errno.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include <net/rtnetlink.h>
 
 #include <scsi/fc/fc_els.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/fd_mcs.c linux-libre-2.6.34-gnu1/drivers/scsi/fd_mcs.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/fd_mcs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/fd_mcs.c	2010-05-16 17:17:36.000000000 -0400
@@ -88,6 +88,7 @@
 #include <linux/delay.h>
 #include <linux/mca.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <scsi/scsicam.h>
 #include <linux/mca-legacy.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/fdomain.c linux-libre-2.6.34-gnu1/drivers/scsi/fdomain.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/fdomain.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/fdomain.c	2010-05-16 17:17:36.000000000 -0400
@@ -279,6 +279,7 @@
 #include <linux/stat.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <scsi/scsicam.h>
 
 #include <asm/system.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/FlashPoint.c linux-libre-2.6.34-gnu1/drivers/scsi/FlashPoint.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/FlashPoint.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/FlashPoint.c	2010-05-16 17:17:36.000000000 -0400
@@ -3924,7 +3924,7 @@ static void FPT_sinits(struct sccb *p_sc
 {
 	struct sccb_mgr_tar_info *currTar_Info;
 
-	if ((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN)) {
+	if ((p_sccb->TargID >= MAX_SCSI_TAR) || (p_sccb->Lun >= MAX_LUN)) {
 		return;
 	}
 	currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_fcs.c linux-libre-2.6.34-gnu1/drivers/scsi/fnic/fnic_fcs.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_fcs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/fnic/fnic_fcs.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 #include <linux/errno.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic.h linux-libre-2.6.34-gnu1/drivers/scsi/fnic/fnic.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/fnic/fnic.h	2010-05-16 17:17:36.000000000 -0400
@@ -36,7 +36,7 @@
 
 #define DRV_NAME		"fnic"
 #define DRV_DESCRIPTION		"Cisco FCoE HBA Driver"
-#define DRV_VERSION		"1.0.0.1121"
+#define DRV_VERSION		"1.4.0.98"
 #define PFX			DRV_NAME ": "
 #define DFX                     DRV_NAME "%d: "
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_main.c linux-libre-2.6.34-gnu1/drivers/scsi/fnic/fnic_main.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/fnic/fnic_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/mempool.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/pci.h>
@@ -620,6 +621,8 @@ static int __devinit fnic_probe(struct p
 	if (fnic->config.flags & VFCF_FIP_CAPABLE) {
 		shost_printk(KERN_INFO, fnic->lport->host,
 			     "firmware supports FIP\n");
+		/* enable directed and multicast */
+		vnic_dev_packet_filter(fnic->vdev, 1, 1, 0, 0, 0);
 		vnic_dev_add_addr(fnic->vdev, FIP_ALL_ENODE_MACS);
 		vnic_dev_add_addr(fnic->vdev, fnic->ctlr.ctl_src_addr);
 	} else {
@@ -698,6 +701,8 @@ static int __devinit fnic_probe(struct p
 		goto err_out_remove_scsi_host;
 	}
 
+	fc_lport_init_stats(lp);
+
 	fc_lport_config(lp);
 
 	if (fc_set_mfs(lp, fnic->config.maxdatafieldsize +
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_scsi.c linux-libre-2.6.34-gnu1/drivers/scsi/fnic/fnic_scsi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_scsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/fnic/fnic_scsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/fnic/vnic_dev.c linux-libre-2.6.34-gnu1/drivers/scsi/fnic/vnic_dev.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/fnic/vnic_dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/fnic/vnic_dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/if_ether.h>
+#include <linux/slab.h>
 #include "vnic_resource.h"
 #include "vnic_devcmd.h"
 #include "vnic_dev.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/fnic/vnic_devcmd.h linux-libre-2.6.34-gnu1/drivers/scsi/fnic/vnic_devcmd.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/fnic/vnic_devcmd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/fnic/vnic_devcmd.h	2010-05-16 17:17:36.000000000 -0400
@@ -94,7 +94,7 @@ enum vnic_devcmd_cmd {
 	CMD_STATS_DUMP          = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 4),
 
 	/* set Rx packet filter: (u32)a0=filters (see CMD_PFILTER_*) */
-	CMD_PACKET_FILTER	= _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 7),
+	CMD_PACKET_FILTER       = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 7),
 
 	/* hang detection notification */
 	CMD_HANG_NOTIFY         = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 8),
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/fnic/vnic_rq.c linux-libre-2.6.34-gnu1/drivers/scsi/fnic/vnic_rq.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/fnic/vnic_rq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/fnic/vnic_rq.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include "vnic_dev.h"
 #include "vnic_rq.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/fnic/vnic_wq.c linux-libre-2.6.34-gnu1/drivers/scsi/fnic/vnic_wq.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/fnic/vnic_wq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/fnic/vnic_wq.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include "vnic_dev.h"
 #include "vnic_wq.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/gdth.c linux-libre-2.6.34-gnu1/drivers/scsi/gdth.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/gdth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/gdth.c	2010-05-16 17:17:36.000000000 -0400
@@ -121,6 +121,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/list.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 
 #ifdef GDTH_RTC
 #include <linux/mc146818rtc.h>
@@ -140,40 +141,40 @@
 #include "gdth.h"
 
 static void gdth_delay(int milliseconds);
-static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs);
+static void gdth_eval_mapping(u32 size, u32 *cyls, int *heads, int *secs);
 static irqreturn_t gdth_interrupt(int irq, void *dev_id);
 static irqreturn_t __gdth_interrupt(gdth_ha_str *ha,
                                     int gdth_from_wait, int* pIndex);
-static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index,
+static int gdth_sync_event(gdth_ha_str *ha, int service, u8 index,
                                                                Scsi_Cmnd *scp);
 static int gdth_async_event(gdth_ha_str *ha);
 static void gdth_log_event(gdth_evt_data *dvr, char *buffer);
 
-static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority);
+static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, u8 priority);
 static void gdth_next(gdth_ha_str *ha);
-static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b);
+static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, u8 b);
 static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp);
-static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, ushort source,
-                                      ushort idx, gdth_evt_data *evt);
+static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, u16 source,
+                                      u16 idx, gdth_evt_data *evt);
 static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr);
-static void gdth_readapp_event(gdth_ha_str *ha, unchar application, 
+static void gdth_readapp_event(gdth_ha_str *ha, u8 application, 
                                gdth_evt_str *estr);
 static void gdth_clear_events(void);
 
 static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
-                                    char *buffer, ushort count);
+                                    char *buffer, u16 count);
 static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp);
-static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive);
+static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, u16 hdrive);
 
 static void gdth_enable_int(gdth_ha_str *ha);
 static int gdth_test_busy(gdth_ha_str *ha);
 static int gdth_get_cmd_index(gdth_ha_str *ha);
 static void gdth_release_event(gdth_ha_str *ha);
-static int gdth_wait(gdth_ha_str *ha, int index,ulong32 time);
-static int gdth_internal_cmd(gdth_ha_str *ha, unchar service, ushort opcode,
-                                             ulong32 p1, ulong64 p2,ulong64 p3);
+static int gdth_wait(gdth_ha_str *ha, int index,u32 time);
+static int gdth_internal_cmd(gdth_ha_str *ha, u8 service, u16 opcode,
+                                             u32 p1, u64 p2,u64 p3);
 static int gdth_search_drives(gdth_ha_str *ha);
-static int gdth_analyse_hdrive(gdth_ha_str *ha, ushort hdrive);
+static int gdth_analyse_hdrive(gdth_ha_str *ha, u16 hdrive);
 
 static const char *gdth_ctr_name(gdth_ha_str *ha);
 
@@ -189,7 +190,7 @@ static int __gdth_queuecommand(gdth_ha_s
 static void gdth_scsi_done(struct scsi_cmnd *scp);
 
 #ifdef DEBUG_GDTH
-static unchar   DebugState = DEBUG_GDTH;
+static u8   DebugState = DEBUG_GDTH;
 
 #ifdef __SERIAL__
 #define MAX_SERBUF 160
@@ -270,30 +271,30 @@ static int ser_printk(const char *fmt, .
 #endif
 
 #ifdef GDTH_STATISTICS
-static ulong32 max_rq=0, max_index=0, max_sg=0;
+static u32 max_rq=0, max_index=0, max_sg=0;
 #ifdef INT_COAL
-static ulong32 max_int_coal=0;
+static u32 max_int_coal=0;
 #endif
-static ulong32 act_ints=0, act_ios=0, act_stats=0, act_rq=0;
+static u32 act_ints=0, act_ios=0, act_stats=0, act_rq=0;
 static struct timer_list gdth_timer;
 #endif
 
-#define PTR2USHORT(a)   (ushort)(ulong)(a)
+#define PTR2USHORT(a)   (u16)(unsigned long)(a)
 #define GDTOFFSOF(a,b)  (size_t)&(((a*)0)->b)
 #define INDEX_OK(i,t)   ((i)<ARRAY_SIZE(t))
 
 #define BUS_L2P(a,b)    ((b)>(a)->virt_bus ? (b-1):(b))
 
 #ifdef CONFIG_ISA
-static unchar   gdth_drq_tab[4] = {5,6,7,7};            /* DRQ table */
+static u8   gdth_drq_tab[4] = {5,6,7,7};            /* DRQ table */
 #endif
 #if defined(CONFIG_EISA) || defined(CONFIG_ISA)
-static unchar   gdth_irq_tab[6] = {0,10,11,12,14,0};    /* IRQ table */
+static u8   gdth_irq_tab[6] = {0,10,11,12,14,0};    /* IRQ table */
 #endif
-static unchar   gdth_polling;                           /* polling if TRUE */
+static u8   gdth_polling;                           /* polling if TRUE */
 static int      gdth_ctr_count  = 0;                    /* controller count */
 static LIST_HEAD(gdth_instances);                       /* controller list */
-static unchar   gdth_write_through = FALSE;             /* write through */
+static u8   gdth_write_through = FALSE;             /* write through */
 static gdth_evt_str ebuffer[MAX_EVENTS];                /* event buffer */
 static int elastidx;
 static int eoldidx;
@@ -303,7 +304,7 @@ static int major;
 #define DOU     2                               /* OUT data direction */
 #define DNO     DIN                             /* no data transfer */
 #define DUN     DIN                             /* unknown data direction */
-static unchar gdth_direction_tab[0x100] = {
+static u8 gdth_direction_tab[0x100] = {
     DNO,DNO,DIN,DIN,DOU,DIN,DIN,DOU,DIN,DUN,DOU,DOU,DUN,DUN,DUN,DIN,
     DNO,DIN,DIN,DOU,DIN,DOU,DNO,DNO,DOU,DNO,DIN,DNO,DIN,DOU,DNO,DUN,
     DIN,DUN,DIN,DUN,DOU,DIN,DUN,DUN,DIN,DIN,DOU,DNO,DUN,DIN,DOU,DOU,
@@ -390,7 +391,7 @@ static gdth_ha_str *gdth_find_ha(int han
 static struct gdth_cmndinfo *gdth_get_cmndinfo(gdth_ha_str *ha)
 {
 	struct gdth_cmndinfo *priv = NULL;
-	ulong flags;
+	unsigned long flags;
 	int i;
 
 	spin_lock_irqsave(&ha->smp_lock, flags);
@@ -493,7 +494,7 @@ int gdth_execute(struct Scsi_Host *shost
     return rval;
 }
 
-static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs)
+static void gdth_eval_mapping(u32 size, u32 *cyls, int *heads, int *secs)
 {
     *cyls = size /HEADS/SECS;
     if (*cyls <= MAXCYLS) {
@@ -514,9 +515,9 @@ static void gdth_eval_mapping(ulong32 si
 
 /* controller search and initialization functions */
 #ifdef CONFIG_EISA
-static int __init gdth_search_eisa(ushort eisa_adr)
+static int __init gdth_search_eisa(u16 eisa_adr)
 {
-    ulong32 id;
+    u32 id;
     
     TRACE(("gdth_search_eisa() adr. %x\n",eisa_adr));
     id = inl(eisa_adr+ID0REG);
@@ -533,13 +534,13 @@ static int __init gdth_search_eisa(ushor
 #endif /* CONFIG_EISA */
 
 #ifdef CONFIG_ISA
-static int __init gdth_search_isa(ulong32 bios_adr)
+static int __init gdth_search_isa(u32 bios_adr)
 {
     void __iomem *addr;
-    ulong32 id;
+    u32 id;
 
     TRACE(("gdth_search_isa() bios adr. %x\n",bios_adr));
-    if ((addr = ioremap(bios_adr+BIOS_ID_OFFS, sizeof(ulong32))) != NULL) {
+    if ((addr = ioremap(bios_adr+BIOS_ID_OFFS, sizeof(u32))) != NULL) {
         id = readl(addr);
         iounmap(addr);
         if (id == GDT2_ID)                          /* GDT2000 */
@@ -551,7 +552,7 @@ static int __init gdth_search_isa(ulong3
 
 #ifdef CONFIG_PCI
 
-static bool gdth_search_vortex(ushort device)
+static bool gdth_search_vortex(u16 device)
 {
 	if (device <= PCI_DEVICE_ID_VORTEX_GDT6555)
 		return true;
@@ -603,9 +604,9 @@ static void __devexit gdth_pci_remove_on
 static int __devinit gdth_pci_init_one(struct pci_dev *pdev,
 				       const struct pci_device_id *ent)
 {
-	ushort vendor = pdev->vendor;
-	ushort device = pdev->device;
-	ulong base0, base1, base2;
+	u16 vendor = pdev->vendor;
+	u16 device = pdev->device;
+	unsigned long base0, base1, base2;
 	int rc;
 	gdth_pci_str gdth_pcistr;
 	gdth_ha_str *ha = NULL;
@@ -658,10 +659,10 @@ static int __devinit gdth_pci_init_one(s
 #endif /* CONFIG_PCI */
 
 #ifdef CONFIG_EISA
-static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha)
+static int __init gdth_init_eisa(u16 eisa_adr,gdth_ha_str *ha)
 {
-    ulong32 retries,id;
-    unchar prot_ver,eisacf,i,irq_found;
+    u32 retries,id;
+    u8 prot_ver,eisacf,i,irq_found;
 
     TRACE(("gdth_init_eisa() adr. %x\n",eisa_adr));
     
@@ -688,7 +689,7 @@ static int __init gdth_init_eisa(ushort
         return 0;
     }
     ha->bmic = eisa_adr;
-    ha->brd_phys = (ulong32)eisa_adr >> 12;
+    ha->brd_phys = (u32)eisa_adr >> 12;
 
     outl(0,eisa_adr+MAILBOXREG);
     outl(0,eisa_adr+MAILBOXREG+4);
@@ -752,12 +753,12 @@ static int __init gdth_init_eisa(ushort
 #endif /* CONFIG_EISA */
 
 #ifdef CONFIG_ISA
-static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha)
+static int __init gdth_init_isa(u32 bios_adr,gdth_ha_str *ha)
 {
     register gdt2_dpram_str __iomem *dp2_ptr;
     int i;
-    unchar irq_drq,prot_ver;
-    ulong32 retries;
+    u8 irq_drq,prot_ver;
+    u32 retries;
 
     TRACE(("gdth_init_isa() bios adr. %x\n",bios_adr));
 
@@ -812,7 +813,7 @@ static int __init gdth_init_isa(ulong32
         }
         gdth_delay(1);
     }
-    prot_ver = (unchar)readl(&dp2_ptr->u.ic.S_Info[0]);
+    prot_ver = (u8)readl(&dp2_ptr->u.ic.S_Info[0]);
     writeb(0, &dp2_ptr->u.ic.Status);
     writeb(0xff, &dp2_ptr->io.irqdel);
     if (prot_ver != PROTOCOL_VERSION) {
@@ -859,9 +860,9 @@ static int __devinit gdth_init_pci(struc
     register gdt6_dpram_str __iomem *dp6_ptr;
     register gdt6c_dpram_str __iomem *dp6c_ptr;
     register gdt6m_dpram_str __iomem *dp6m_ptr;
-    ulong32 retries;
-    unchar prot_ver;
-    ushort command;
+    u32 retries;
+    u8 prot_ver;
+    u16 command;
     int i, found = FALSE;
 
     TRACE(("gdth_init_pci()\n"));
@@ -871,7 +872,7 @@ static int __devinit gdth_init_pci(struc
     else
         ha->oem_id = OEM_ID_ICP;
     ha->brd_phys = (pdev->bus->number << 8) | (pdev->devfn & 0xf8);
-    ha->stype = (ulong32)pdev->device;
+    ha->stype = (u32)pdev->device;
     ha->irq = pdev->irq;
     ha->pdev = pdev;
     
@@ -891,7 +892,7 @@ static int __devinit gdth_init_pci(struc
             found = FALSE;
             for (i = 0xC8000; i < 0xE8000; i += 0x4000) {
                 iounmap(ha->brd);
-                ha->brd = ioremap(i, sizeof(ushort)); 
+                ha->brd = ioremap(i, sizeof(u16)); 
                 if (ha->brd == NULL) {
                     printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
                     return 0;
@@ -947,7 +948,7 @@ static int __devinit gdth_init_pci(struc
             }
             gdth_delay(1);
         }
-        prot_ver = (unchar)readl(&dp6_ptr->u.ic.S_Info[0]);
+        prot_ver = (u8)readl(&dp6_ptr->u.ic.S_Info[0]);
         writeb(0, &dp6_ptr->u.ic.S_Status);
         writeb(0xff, &dp6_ptr->io.irqdel);
         if (prot_ver != PROTOCOL_VERSION) {
@@ -1000,7 +1001,7 @@ static int __devinit gdth_init_pci(struc
             found = FALSE;
             for (i = 0xC8000; i < 0xE8000; i += 0x4000) {
                 iounmap(ha->brd);
-                ha->brd = ioremap(i, sizeof(ushort)); 
+                ha->brd = ioremap(i, sizeof(u16)); 
                 if (ha->brd == NULL) {
                     printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
                     return 0;
@@ -1059,7 +1060,7 @@ static int __devinit gdth_init_pci(struc
             }
             gdth_delay(1);
         }
-        prot_ver = (unchar)readl(&dp6c_ptr->u.ic.S_Info[0]);
+        prot_ver = (u8)readl(&dp6c_ptr->u.ic.S_Info[0]);
         writeb(0, &dp6c_ptr->u.ic.Status);
         if (prot_ver != PROTOCOL_VERSION) {
             printk("GDT-PCI: Illegal protocol version\n");
@@ -1128,7 +1129,7 @@ static int __devinit gdth_init_pci(struc
             found = FALSE;
             for (i = 0xC8000; i < 0xE8000; i += 0x4000) {
                 iounmap(ha->brd);
-                ha->brd = ioremap(i, sizeof(ushort)); 
+                ha->brd = ioremap(i, sizeof(u16)); 
                 if (ha->brd == NULL) {
                     printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
                     return 0;
@@ -1180,7 +1181,7 @@ static int __devinit gdth_init_pci(struc
             }
             gdth_delay(1);
         }
-        prot_ver = (unchar)readl(&dp6m_ptr->u.ic.S_Info[0]);
+        prot_ver = (u8)readl(&dp6m_ptr->u.ic.S_Info[0]);
         writeb(0, &dp6m_ptr->u.ic.S_Status);
         if (prot_ver != PROTOCOL_VERSION) {
             printk("GDT-PCI: Illegal protocol version\n");
@@ -1223,7 +1224,7 @@ static int __devinit gdth_init_pci(struc
             }
             gdth_delay(1);
         }
-        prot_ver = (unchar)(readl(&dp6m_ptr->u.ic.S_Info[0]) >> 16);
+        prot_ver = (u8)(readl(&dp6m_ptr->u.ic.S_Info[0]) >> 16);
         writeb(0, &dp6m_ptr->u.ic.S_Status);
         if (prot_ver < 0x2b)      /* FW < x.43: no 64-bit DMA support */
             ha->dma64_support = 0;
@@ -1239,7 +1240,7 @@ static int __devinit gdth_init_pci(struc
 
 static void __devinit gdth_enable_int(gdth_ha_str *ha)
 {
-    ulong flags;
+    unsigned long flags;
     gdt2_dpram_str __iomem *dp2_ptr;
     gdt6_dpram_str __iomem *dp6_ptr;
     gdt6m_dpram_str __iomem *dp6m_ptr;
@@ -1274,14 +1275,14 @@ static void __devinit gdth_enable_int(gd
 }
 
 /* return IStatus if interrupt was from this card else 0 */
-static unchar gdth_get_status(gdth_ha_str *ha)
+static u8 gdth_get_status(gdth_ha_str *ha)
 {
-    unchar IStatus = 0;
+    u8 IStatus = 0;
 
     TRACE(("gdth_get_status() irq %d ctr_count %d\n", ha->irq, gdth_ctr_count));
 
         if (ha->type == GDT_EISA)
-            IStatus = inb((ushort)ha->bmic + EDOORREG);
+            IStatus = inb((u16)ha->bmic + EDOORREG);
         else if (ha->type == GDT_ISA)
             IStatus =
                 readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index);
@@ -1329,7 +1330,7 @@ static int gdth_get_cmd_index(gdth_ha_st
         if (ha->cmd_tab[i].cmnd == UNUSED_CMND) {
             ha->cmd_tab[i].cmnd = ha->pccb->RequestBuffer;
             ha->cmd_tab[i].service = ha->pccb->Service;
-            ha->pccb->CommandIndex = (ulong32)i+2;
+            ha->pccb->CommandIndex = (u32)i+2;
             return (i+2);
         }
     }
@@ -1362,7 +1363,7 @@ static void gdth_copy_command(gdth_ha_st
     register gdt6c_dpram_str __iomem *dp6c_ptr;
     gdt6_dpram_str __iomem *dp6_ptr;
     gdt2_dpram_str __iomem *dp2_ptr;
-    ushort cp_count,dp_offset,cmd_no;
+    u16 cp_count,dp_offset,cmd_no;
     
     TRACE(("gdth_copy_command() hanum %d\n", ha->hanum));
 
@@ -1386,28 +1387,28 @@ static void gdth_copy_command(gdth_ha_st
         dp2_ptr = ha->brd;
         writew(dp_offset + DPMEM_COMMAND_OFFSET,
                     &dp2_ptr->u.ic.comm_queue[cmd_no].offset);
-        writew((ushort)cmd_ptr->Service,
+        writew((u16)cmd_ptr->Service,
                     &dp2_ptr->u.ic.comm_queue[cmd_no].serv_id);
         memcpy_toio(&dp2_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count);
     } else if (ha->type == GDT_PCI) {
         dp6_ptr = ha->brd;
         writew(dp_offset + DPMEM_COMMAND_OFFSET,
                     &dp6_ptr->u.ic.comm_queue[cmd_no].offset);
-        writew((ushort)cmd_ptr->Service,
+        writew((u16)cmd_ptr->Service,
                     &dp6_ptr->u.ic.comm_queue[cmd_no].serv_id);
         memcpy_toio(&dp6_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count);
     } else if (ha->type == GDT_PCINEW) {
         dp6c_ptr = ha->brd;
         writew(dp_offset + DPMEM_COMMAND_OFFSET,
                     &dp6c_ptr->u.ic.comm_queue[cmd_no].offset);
-        writew((ushort)cmd_ptr->Service,
+        writew((u16)cmd_ptr->Service,
                     &dp6c_ptr->u.ic.comm_queue[cmd_no].serv_id);
         memcpy_toio(&dp6c_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count);
     } else if (ha->type == GDT_PCIMPR) {
         dp6m_ptr = ha->brd;
         writew(dp_offset + DPMEM_COMMAND_OFFSET,
                     &dp6m_ptr->u.ic.comm_queue[cmd_no].offset);
-        writew((ushort)cmd_ptr->Service,
+        writew((u16)cmd_ptr->Service,
                     &dp6m_ptr->u.ic.comm_queue[cmd_no].serv_id);
         memcpy_toio(&dp6m_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count);
     }
@@ -1420,14 +1421,14 @@ static void gdth_release_event(gdth_ha_s
 
 #ifdef GDTH_STATISTICS
     {
-        ulong32 i,j;
+        u32 i,j;
         for (i=0,j=0; j<GDTH_MAXCMDS; ++j) {
             if (ha->cmd_tab[j].cmnd != UNUSED_CMND)
                 ++i;
         }
         if (max_index < i) {
             max_index = i;
-            TRACE3(("GDT: max_index = %d\n",(ushort)i));
+            TRACE3(("GDT: max_index = %d\n",(u16)i));
         }
     }
 #endif
@@ -1450,7 +1451,7 @@ static void gdth_release_event(gdth_ha_s
     }
 }
 
-static int gdth_wait(gdth_ha_str *ha, int index, ulong32 time)
+static int gdth_wait(gdth_ha_str *ha, int index, u32 time)
 {
     int answer_found = FALSE;
     int wait_index = 0;
@@ -1476,8 +1477,8 @@ static int gdth_wait(gdth_ha_str *ha, in
 }
 
 
-static int gdth_internal_cmd(gdth_ha_str *ha, unchar service, ushort opcode,
-                                            ulong32 p1, ulong64 p2, ulong64 p3)
+static int gdth_internal_cmd(gdth_ha_str *ha, u8 service, u16 opcode,
+                                            u32 p1, u64 p2, u64 p3)
 {
     register gdth_cmd_str *cmd_ptr;
     int retries,index;
@@ -1501,35 +1502,35 @@ static int gdth_internal_cmd(gdth_ha_str
         if (service == CACHESERVICE) {
             if (opcode == GDT_IOCTL) {
                 cmd_ptr->u.ioctl.subfunc = p1;
-                cmd_ptr->u.ioctl.channel = (ulong32)p2;
-                cmd_ptr->u.ioctl.param_size = (ushort)p3;
+                cmd_ptr->u.ioctl.channel = (u32)p2;
+                cmd_ptr->u.ioctl.param_size = (u16)p3;
                 cmd_ptr->u.ioctl.p_param = ha->scratch_phys;
             } else {
                 if (ha->cache_feat & GDT_64BIT) {
-                    cmd_ptr->u.cache64.DeviceNo = (ushort)p1;
+                    cmd_ptr->u.cache64.DeviceNo = (u16)p1;
                     cmd_ptr->u.cache64.BlockNo  = p2;
                 } else {
-                    cmd_ptr->u.cache.DeviceNo = (ushort)p1;
-                    cmd_ptr->u.cache.BlockNo  = (ulong32)p2;
+                    cmd_ptr->u.cache.DeviceNo = (u16)p1;
+                    cmd_ptr->u.cache.BlockNo  = (u32)p2;
                 }
             }
         } else if (service == SCSIRAWSERVICE) {
             if (ha->raw_feat & GDT_64BIT) {
                 cmd_ptr->u.raw64.direction  = p1;
-                cmd_ptr->u.raw64.bus        = (unchar)p2;
-                cmd_ptr->u.raw64.target     = (unchar)p3;
-                cmd_ptr->u.raw64.lun        = (unchar)(p3 >> 8);
+                cmd_ptr->u.raw64.bus        = (u8)p2;
+                cmd_ptr->u.raw64.target     = (u8)p3;
+                cmd_ptr->u.raw64.lun        = (u8)(p3 >> 8);
             } else {
                 cmd_ptr->u.raw.direction  = p1;
-                cmd_ptr->u.raw.bus        = (unchar)p2;
-                cmd_ptr->u.raw.target     = (unchar)p3;
-                cmd_ptr->u.raw.lun        = (unchar)(p3 >> 8);
+                cmd_ptr->u.raw.bus        = (u8)p2;
+                cmd_ptr->u.raw.target     = (u8)p3;
+                cmd_ptr->u.raw.lun        = (u8)(p3 >> 8);
             }
         } else if (service == SCREENSERVICE) {
             if (opcode == GDT_REALTIME) {
-                *(ulong32 *)&cmd_ptr->u.screen.su.data[0] = p1;
-                *(ulong32 *)&cmd_ptr->u.screen.su.data[4] = (ulong32)p2;
-                *(ulong32 *)&cmd_ptr->u.screen.su.data[8] = (ulong32)p3;
+                *(u32 *)&cmd_ptr->u.screen.su.data[0] = p1;
+                *(u32 *)&cmd_ptr->u.screen.su.data[4] = (u32)p2;
+                *(u32 *)&cmd_ptr->u.screen.su.data[8] = (u32)p3;
             }
         }
         ha->cmd_len          = sizeof(gdth_cmd_str);
@@ -1555,9 +1556,9 @@ static int gdth_internal_cmd(gdth_ha_str
 
 static int __devinit gdth_search_drives(gdth_ha_str *ha)
 {
-    ushort cdev_cnt, i;
+    u16 cdev_cnt, i;
     int ok;
-    ulong32 bus_no, drv_cnt, drv_no, j;
+    u32 bus_no, drv_cnt, drv_no, j;
     gdth_getch_str *chn;
     gdth_drlist_str *drl;
     gdth_iochan_str *ioc;
@@ -1570,8 +1571,8 @@ static int __devinit gdth_search_drives(
 #endif
 
 #ifdef GDTH_RTC
-    unchar rtc[12];
-    ulong flags;
+    u8 rtc[12];
+    unsigned long flags;
 #endif     
    
     TRACE(("gdth_search_drives() hanum %d\n", ha->hanum));
@@ -1584,7 +1585,7 @@ static int __devinit gdth_search_drives(
         if (ok)
             ha->screen_feat = GDT_64BIT;
     }
-    if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC))
+    if (force_dma32 || (!ok && ha->status == (u16)S_NOFUNC))
         ok = gdth_internal_cmd(ha, SCREENSERVICE, GDT_INIT, 0, 0, 0);
     if (!ok) {
         printk("GDT-HA %d: Initialization error screen service (code %d)\n",
@@ -1609,11 +1610,11 @@ static int __devinit gdth_search_drives(
             rtc[j] = CMOS_READ(j);
     } while (rtc[0] != CMOS_READ(0));
     spin_unlock_irqrestore(&rtc_lock, flags);
-    TRACE2(("gdth_search_drives(): RTC: %x/%x/%x\n",*(ulong32 *)&rtc[0],
-            *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]));
+    TRACE2(("gdth_search_drives(): RTC: %x/%x/%x\n",*(u32 *)&rtc[0],
+            *(u32 *)&rtc[4], *(u32 *)&rtc[8]));
     /* 3. send to controller firmware */
-    gdth_internal_cmd(ha, SCREENSERVICE, GDT_REALTIME, *(ulong32 *)&rtc[0],
-                      *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]);
+    gdth_internal_cmd(ha, SCREENSERVICE, GDT_REALTIME, *(u32 *)&rtc[0],
+                      *(u32 *)&rtc[4], *(u32 *)&rtc[8]);
 #endif  
  
     /* unfreeze all IOs */
@@ -1627,7 +1628,7 @@ static int __devinit gdth_search_drives(
         if (ok)
             ha->cache_feat = GDT_64BIT;
     }
-    if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC))
+    if (force_dma32 || (!ok && ha->status == (u16)S_NOFUNC))
         ok = gdth_internal_cmd(ha, CACHESERVICE, GDT_INIT, LINUX_OS, 0, 0);
     if (!ok) {
         printk("GDT-HA %d: Initialization error cache service (code %d)\n",
@@ -1635,7 +1636,7 @@ static int __devinit gdth_search_drives(
         return 0;
     }
     TRACE2(("gdth_search_drives(): CACHESERVICE initialized\n"));
-    cdev_cnt = (ushort)ha->info;
+    cdev_cnt = (u16)ha->info;
     ha->fw_vers = ha->service;
 
 #ifdef INT_COAL
@@ -1644,7 +1645,7 @@ static int __devinit gdth_search_drives(
         pmod = (gdth_perf_modes *)ha->pscratch;
         pmod->version          = 1;
         pmod->st_mode          = 1;    /* enable one status buffer */
-        *((ulong64 *)&pmod->st_buff_addr1) = ha->coal_stat_phys;
+        *((u64 *)&pmod->st_buff_addr1) = ha->coal_stat_phys;
         pmod->st_buff_indx1    = COALINDEX;
         pmod->st_buff_addr2    = 0;
         pmod->st_buff_u_addr2  = 0;
@@ -1705,7 +1706,7 @@ static int __devinit gdth_search_drives(
             else
                 ha->bus_id[bus_no] = 0xff;
         }       
-        ha->bus_cnt = (unchar)bus_no;
+        ha->bus_cnt = (u8)bus_no;
     }
     TRACE2(("gdth_search_drives() %d channels\n",ha->bus_cnt));
 
@@ -1789,12 +1790,12 @@ static int __devinit gdth_search_drives(
 
         /* logical drives */
         if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_DRV_CNT,
-                              INVALID_CHANNEL,sizeof(ulong32))) {
-            drv_cnt = *(ulong32 *)ha->pscratch;
+                              INVALID_CHANNEL,sizeof(u32))) {
+            drv_cnt = *(u32 *)ha->pscratch;
             if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_DRV_LIST,
-                                  INVALID_CHANNEL,drv_cnt * sizeof(ulong32))) {
+                                  INVALID_CHANNEL,drv_cnt * sizeof(u32))) {
                 for (j = 0; j < drv_cnt; ++j) {
-                    drv_no = ((ulong32 *)ha->pscratch)[j];
+                    drv_no = ((u32 *)ha->pscratch)[j];
                     if (drv_no < MAX_LDRIVES) {
                         ha->hdr[drv_no].is_logdrv = TRUE;
                         TRACE2(("Drive %d is log. drive\n",drv_no));
@@ -1838,7 +1839,7 @@ static int __devinit gdth_search_drives(
         if (ok)
             ha->raw_feat = GDT_64BIT;
     }
-    if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC))
+    if (force_dma32 || (!ok && ha->status == (u16)S_NOFUNC))
         ok = gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_INIT, 0, 0, 0);
     if (!ok) {
         printk("GDT-HA %d: Initialization error raw service (code %d)\n",
@@ -1854,7 +1855,7 @@ static int __devinit gdth_search_drives(
         if (gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_GET_FEAT, 0, 0, 0)) {
             TRACE2(("gdth_search_dr(): get feat RAWSERVICE %d\n",
                     ha->info));
-            ha->raw_feat |= (ushort)ha->info;
+            ha->raw_feat |= (u16)ha->info;
         }
     } 
 
@@ -1865,7 +1866,7 @@ static int __devinit gdth_search_drives(
         if (gdth_internal_cmd(ha, CACHESERVICE, GDT_GET_FEAT, 0, 0, 0)) {
             TRACE2(("gdth_search_dr(): get feat CACHESERV. %d\n",
                     ha->info));
-            ha->cache_feat |= (ushort)ha->info;
+            ha->cache_feat |= (u16)ha->info;
         }
     }
 
@@ -1923,9 +1924,9 @@ static int __devinit gdth_search_drives(
     return 1;
 }
 
-static int gdth_analyse_hdrive(gdth_ha_str *ha, ushort hdrive)
+static int gdth_analyse_hdrive(gdth_ha_str *ha, u16 hdrive)
 {
-    ulong32 drv_cyls;
+    u32 drv_cyls;
     int drv_hds, drv_secs;
 
     TRACE(("gdth_analyse_hdrive() hanum %d drive %d\n", ha->hanum, hdrive));
@@ -1944,17 +1945,17 @@ static int gdth_analyse_hdrive(gdth_ha_s
     } else {
         drv_hds = ha->info2 & 0xff;
         drv_secs = (ha->info2 >> 8) & 0xff;
-        drv_cyls = (ulong32)ha->hdr[hdrive].size / drv_hds / drv_secs;
+        drv_cyls = (u32)ha->hdr[hdrive].size / drv_hds / drv_secs;
     }
-    ha->hdr[hdrive].heads = (unchar)drv_hds;
-    ha->hdr[hdrive].secs  = (unchar)drv_secs;
+    ha->hdr[hdrive].heads = (u8)drv_hds;
+    ha->hdr[hdrive].secs  = (u8)drv_secs;
     /* round size */
     ha->hdr[hdrive].size  = drv_cyls * drv_hds * drv_secs;
     
     if (ha->cache_feat & GDT_64BIT) {
         if (gdth_internal_cmd(ha, CACHESERVICE, GDT_X_INFO, hdrive, 0, 0)
             && ha->info2 != 0) {
-            ha->hdr[hdrive].size = ((ulong64)ha->info2 << 32) | ha->info;
+            ha->hdr[hdrive].size = ((u64)ha->info2 << 32) | ha->info;
         }
     }
     TRACE2(("gdth_search_dr() cdr. %d size %d hds %d scs %d\n",
@@ -1964,7 +1965,7 @@ static int gdth_analyse_hdrive(gdth_ha_s
     if (gdth_internal_cmd(ha, CACHESERVICE, GDT_DEVTYPE, hdrive, 0, 0)) {
         TRACE2(("gdth_search_dr() cache drive %d devtype %d\n",
                 hdrive,ha->info));
-        ha->hdr[hdrive].devtype = (ushort)ha->info;
+        ha->hdr[hdrive].devtype = (u16)ha->info;
     }
 
     /* cluster info */
@@ -1972,14 +1973,14 @@ static int gdth_analyse_hdrive(gdth_ha_s
         TRACE2(("gdth_search_dr() cache drive %d cluster info %d\n",
                 hdrive,ha->info));
         if (!shared_access)
-            ha->hdr[hdrive].cluster_type = (unchar)ha->info;
+            ha->hdr[hdrive].cluster_type = (u8)ha->info;
     }
 
     /* R/W attributes */
     if (gdth_internal_cmd(ha, CACHESERVICE, GDT_RW_ATTRIBS, hdrive, 0, 0)) {
         TRACE2(("gdth_search_dr() cache drive %d r/w attrib. %d\n",
                 hdrive,ha->info));
-        ha->hdr[hdrive].rw_attribs = (unchar)ha->info;
+        ha->hdr[hdrive].rw_attribs = (u8)ha->info;
     }
 
     return 1;
@@ -1988,12 +1989,12 @@ static int gdth_analyse_hdrive(gdth_ha_s
 
 /* command queueing/sending functions */
 
-static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority)
+static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, u8 priority)
 {
     struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
     register Scsi_Cmnd *pscp;
     register Scsi_Cmnd *nscp;
-    ulong flags;
+    unsigned long flags;
 
     TRACE(("gdth_putq() priority %d\n",priority));
     spin_lock_irqsave(&ha->smp_lock, flags);
@@ -2023,7 +2024,7 @@ static void gdth_putq(gdth_ha_str *ha, S
         ++flags;
     if (max_rq < flags) {
         max_rq = flags;
-        TRACE3(("GDT: max_rq = %d\n",(ushort)max_rq));
+        TRACE3(("GDT: max_rq = %d\n",(u16)max_rq));
     }
 #endif
 }
@@ -2032,9 +2033,9 @@ static void gdth_next(gdth_ha_str *ha)
 {
     register Scsi_Cmnd *pscp;
     register Scsi_Cmnd *nscp;
-    unchar b, t, l, firsttime;
-    unchar this_cmd, next_cmd;
-    ulong flags = 0;
+    u8 b, t, l, firsttime;
+    u8 this_cmd, next_cmd;
+    unsigned long flags = 0;
     int cmd_index;
 
     TRACE(("gdth_next() hanum %d\n", ha->hanum));
@@ -2282,20 +2283,20 @@ static void gdth_next(gdth_ha_str *ha)
  * buffers, kmap_atomic() as needed.
  */
 static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
-                                    char *buffer, ushort count)
+                                    char *buffer, u16 count)
 {
-    ushort cpcount,i, max_sg = scsi_sg_count(scp);
-    ushort cpsum,cpnow;
+    u16 cpcount,i, max_sg = scsi_sg_count(scp);
+    u16 cpsum,cpnow;
     struct scatterlist *sl;
     char *address;
 
-    cpcount = min_t(ushort, count, scsi_bufflen(scp));
+    cpcount = min_t(u16, count, scsi_bufflen(scp));
 
     if (cpcount) {
         cpsum=0;
         scsi_for_each_sg(scp, sl, max_sg, i) {
             unsigned long flags;
-            cpnow = (ushort)sl->length;
+            cpnow = (u16)sl->length;
             TRACE(("copy_internal() now %d sum %d count %d %d\n",
                           cpnow, cpsum, cpcount, scsi_bufflen(scp)));
             if (cpsum+cpnow > cpcount) 
@@ -2325,7 +2326,7 @@ static void gdth_copy_internal_data(gdth
 
 static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
 {
-    unchar t;
+    u8 t;
     gdth_inq_data inq;
     gdth_rdcap_data rdc;
     gdth_sense_data sd;
@@ -2389,7 +2390,7 @@ static int gdth_internal_cache_cmd(gdth_
 
       case READ_CAPACITY:
         TRACE2(("Read capacity hdrive %d\n",t));
-        if (ha->hdr[t].size > (ulong64)0xffffffff)
+        if (ha->hdr[t].size > (u64)0xffffffff)
             rdc.last_block_no = 0xffffffff;
         else
             rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1);
@@ -2425,12 +2426,12 @@ static int gdth_internal_cache_cmd(gdth_
     return 0;
 }
 
-static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive)
+static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, u16 hdrive)
 {
     register gdth_cmd_str *cmdp;
     struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
-    ulong32 cnt, blockcnt;
-    ulong64 no, blockno;
+    u32 cnt, blockcnt;
+    u64 no, blockno;
     int i, cmd_index, read_write, sgcnt, mode64;
 
     cmdp = ha->pccb;
@@ -2498,17 +2499,17 @@ static int gdth_fill_cache_cmd(gdth_ha_s
 
     if (read_write) {
         if (scp->cmd_len == 16) {
-            memcpy(&no, &scp->cmnd[2], sizeof(ulong64));
+            memcpy(&no, &scp->cmnd[2], sizeof(u64));
             blockno = be64_to_cpu(no);
-            memcpy(&cnt, &scp->cmnd[10], sizeof(ulong32));
+            memcpy(&cnt, &scp->cmnd[10], sizeof(u32));
             blockcnt = be32_to_cpu(cnt);
         } else if (scp->cmd_len == 10) {
-            memcpy(&no, &scp->cmnd[2], sizeof(ulong32));
+            memcpy(&no, &scp->cmnd[2], sizeof(u32));
             blockno = be32_to_cpu(no);
-            memcpy(&cnt, &scp->cmnd[7], sizeof(ushort));
+            memcpy(&cnt, &scp->cmnd[7], sizeof(u16));
             blockcnt = be16_to_cpu(cnt);
         } else {
-            memcpy(&no, &scp->cmnd[0], sizeof(ulong32));
+            memcpy(&no, &scp->cmnd[0], sizeof(u32));
             blockno = be32_to_cpu(no) & 0x001fffffUL;
             blockcnt= scp->cmnd[4]==0 ? 0x100 : scp->cmnd[4];
         }
@@ -2516,7 +2517,7 @@ static int gdth_fill_cache_cmd(gdth_ha_s
             cmdp->u.cache64.BlockNo = blockno;
             cmdp->u.cache64.BlockCnt = blockcnt;
         } else {
-            cmdp->u.cache.BlockNo = (ulong32)blockno;
+            cmdp->u.cache.BlockNo = (u32)blockno;
             cmdp->u.cache.BlockCnt = blockcnt;
         }
 
@@ -2528,12 +2529,12 @@ static int gdth_fill_cache_cmd(gdth_ha_s
             if (mode64) {
                 struct scatterlist *sl;
 
-                cmdp->u.cache64.DestAddr= (ulong64)-1;
+                cmdp->u.cache64.DestAddr= (u64)-1;
                 cmdp->u.cache64.sg_canz = sgcnt;
                 scsi_for_each_sg(scp, sl, sgcnt, i) {
                     cmdp->u.cache64.sg_lst[i].sg_ptr = sg_dma_address(sl);
 #ifdef GDTH_DMA_STATISTICS
-                    if (cmdp->u.cache64.sg_lst[i].sg_ptr > (ulong64)0xffffffff)
+                    if (cmdp->u.cache64.sg_lst[i].sg_ptr > (u64)0xffffffff)
                         ha->dma64_cnt++;
                     else
                         ha->dma32_cnt++;
@@ -2555,8 +2556,8 @@ static int gdth_fill_cache_cmd(gdth_ha_s
             }
 
 #ifdef GDTH_STATISTICS
-            if (max_sg < (ulong32)sgcnt) {
-                max_sg = (ulong32)sgcnt;
+            if (max_sg < (u32)sgcnt) {
+                max_sg = (u32)sgcnt;
                 TRACE3(("GDT: max_sg = %d\n",max_sg));
             }
 #endif
@@ -2572,7 +2573,7 @@ static int gdth_fill_cache_cmd(gdth_ha_s
         TRACE(("cache cmd: cmd %d blockno. %d, blockcnt %d\n",
                cmdp->OpCode,cmdp->u.cache64.BlockNo,cmdp->u.cache64.BlockCnt));
         ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.cache64.sg_lst) +
-            (ushort)cmdp->u.cache64.sg_canz * sizeof(gdth_sg64_str);
+            (u16)cmdp->u.cache64.sg_canz * sizeof(gdth_sg64_str);
     } else {
         TRACE(("cache cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n",
                cmdp->u.cache.DestAddr,cmdp->u.cache.sg_canz,
@@ -2581,7 +2582,7 @@ static int gdth_fill_cache_cmd(gdth_ha_s
         TRACE(("cache cmd: cmd %d blockno. %d, blockcnt %d\n",
                cmdp->OpCode,cmdp->u.cache.BlockNo,cmdp->u.cache.BlockCnt));
         ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.cache.sg_lst) +
-            (ushort)cmdp->u.cache.sg_canz * sizeof(gdth_sg_str);
+            (u16)cmdp->u.cache.sg_canz * sizeof(gdth_sg_str);
     }
     if (ha->cmd_len & 3)
         ha->cmd_len += (4 - (ha->cmd_len & 3));
@@ -2600,15 +2601,15 @@ static int gdth_fill_cache_cmd(gdth_ha_s
     return cmd_index;
 }
 
-static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b)
+static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, u8 b)
 {
     register gdth_cmd_str *cmdp;
-    ushort i;
+    u16 i;
     dma_addr_t sense_paddr;
     int cmd_index, sgcnt, mode64;
-    unchar t,l;
+    u8 t,l;
     struct page *page;
-    ulong offset;
+    unsigned long offset;
     struct gdth_cmndinfo *cmndinfo;
 
     t = scp->device->id;
@@ -2654,7 +2655,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str
 
     } else {
         page = virt_to_page(scp->sense_buffer);
-        offset = (ulong)scp->sense_buffer & ~PAGE_MASK;
+        offset = (unsigned long)scp->sense_buffer & ~PAGE_MASK;
         sense_paddr = pci_map_page(ha->pdev,page,offset,
                                    16,PCI_DMA_FROMDEVICE);
 
@@ -2703,12 +2704,12 @@ static int gdth_fill_raw_cmd(gdth_ha_str
             if (mode64) {
                 struct scatterlist *sl;
 
-                cmdp->u.raw64.sdata = (ulong64)-1;
+                cmdp->u.raw64.sdata = (u64)-1;
                 cmdp->u.raw64.sg_ranz = sgcnt;
                 scsi_for_each_sg(scp, sl, sgcnt, i) {
                     cmdp->u.raw64.sg_lst[i].sg_ptr = sg_dma_address(sl);
 #ifdef GDTH_DMA_STATISTICS
-                    if (cmdp->u.raw64.sg_lst[i].sg_ptr > (ulong64)0xffffffff)
+                    if (cmdp->u.raw64.sg_lst[i].sg_ptr > (u64)0xffffffff)
                         ha->dma64_cnt++;
                     else
                         ha->dma32_cnt++;
@@ -2744,7 +2745,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str
                    cmdp->u.raw64.sg_lst[0].sg_len));
             /* evaluate command size */
             ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw64.sg_lst) +
-                (ushort)cmdp->u.raw64.sg_ranz * sizeof(gdth_sg64_str);
+                (u16)cmdp->u.raw64.sg_ranz * sizeof(gdth_sg64_str);
         } else {
             TRACE(("raw cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n",
                    cmdp->u.raw.sdata,cmdp->u.raw.sg_ranz,
@@ -2752,7 +2753,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str
                    cmdp->u.raw.sg_lst[0].sg_len));
             /* evaluate command size */
             ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst) +
-                (ushort)cmdp->u.raw.sg_ranz * sizeof(gdth_sg_str);
+                (u16)cmdp->u.raw.sg_ranz * sizeof(gdth_sg_str);
         }
     }
     /* check space */
@@ -2802,7 +2803,7 @@ static int gdth_special_cmd(gdth_ha_str
     if (cmdp->OpCode == GDT_IOCTL) {
         TRACE2(("IOCTL\n"));
         ha->cmd_len = 
-            GDTOFFSOF(gdth_cmd_str,u.ioctl.p_param) + sizeof(ulong64);
+            GDTOFFSOF(gdth_cmd_str,u.ioctl.p_param) + sizeof(u64);
     } else if (cmdp->Service == CACHESERVICE) {
         TRACE2(("cache command %d\n",cmdp->OpCode));
         if (ha->cache_feat & GDT_64BIT)
@@ -2840,8 +2841,8 @@ static int gdth_special_cmd(gdth_ha_str
 
 
 /* Controller event handling functions */
-static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, ushort source, 
-                                      ushort idx, gdth_evt_data *evt)
+static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, u16 source, 
+                                      u16 idx, gdth_evt_data *evt)
 {
     gdth_evt_str *e;
     struct timeval tv;
@@ -2890,7 +2891,7 @@ static int gdth_read_event(gdth_ha_str *
 {
     gdth_evt_str *e;
     int eindex;
-    ulong flags;
+    unsigned long flags;
 
     TRACE2(("gdth_read_event() handle %d\n", handle));
     spin_lock_irqsave(&ha->smp_lock, flags);
@@ -2919,12 +2920,12 @@ static int gdth_read_event(gdth_ha_str *
 }
 
 static void gdth_readapp_event(gdth_ha_str *ha,
-                               unchar application, gdth_evt_str *estr)
+                               u8 application, gdth_evt_str *estr)
 {
     gdth_evt_str *e;
     int eindex;
-    ulong flags;
-    unchar found = FALSE;
+    unsigned long flags;
+    u8 found = FALSE;
 
     TRACE2(("gdth_readapp_event() app. %d\n", application));
     spin_lock_irqsave(&ha->smp_lock, flags);
@@ -2969,9 +2970,9 @@ static irqreturn_t __gdth_interrupt(gdth
     gdt2_dpram_str __iomem *dp2_ptr;
     Scsi_Cmnd *scp;
     int rval, i;
-    unchar IStatus;
-    ushort Service;
-    ulong flags = 0;
+    u8 IStatus;
+    u16 Service;
+    unsigned long flags = 0;
 #ifdef INT_COAL
     int coalesced = FALSE;
     int next = FALSE;
@@ -3018,7 +3019,7 @@ static irqreturn_t __gdth_interrupt(gdth
         if (coalesced) {
             /* For coalesced requests all status
                information is found in the status buffer */
-            IStatus = (unchar)(pcs->status & 0xff);
+            IStatus = (u8)(pcs->status & 0xff);
         }
 #endif
     
@@ -3197,7 +3198,7 @@ static irqreturn_t __gdth_interrupt(gdth
             ++act_int_coal;
             if (act_int_coal > max_int_coal) {
                 max_int_coal = act_int_coal;
-                printk("GDT: max_int_coal = %d\n",(ushort)max_int_coal);
+                printk("GDT: max_int_coal = %d\n",(u16)max_int_coal);
             }
 #endif      
             /* see if there is another status */
@@ -3225,12 +3226,12 @@ static irqreturn_t gdth_interrupt(int ir
 	return __gdth_interrupt(ha, false, NULL);
 }
 
-static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index,
+static int gdth_sync_event(gdth_ha_str *ha, int service, u8 index,
                                                               Scsi_Cmnd *scp)
 {
     gdth_msg_str *msg;
     gdth_cmd_str *cmdp;
-    unchar b, t;
+    u8 b, t;
     struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
 
     cmdp = ha->pccb;
@@ -3263,7 +3264,7 @@ static int gdth_sync_event(gdth_ha_str *
             cmdp->u.screen.su.msg.msg_addr  = ha->msg_phys;
             ha->cmd_offs_dpmem = 0;
             ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) 
-                + sizeof(ulong64);
+                + sizeof(u64);
             ha->cmd_cnt = 0;
             gdth_copy_command(ha);
             gdth_release_event(ha);
@@ -3297,7 +3298,7 @@ static int gdth_sync_event(gdth_ha_str *
             cmdp->u.screen.su.msg.msg_addr  = ha->msg_phys;
             ha->cmd_offs_dpmem = 0;
             ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) 
-                + sizeof(ulong64);
+                + sizeof(u64);
             ha->cmd_cnt = 0;
             gdth_copy_command(ha);
             gdth_release_event(ha);
@@ -3335,7 +3336,7 @@ static int gdth_sync_event(gdth_ha_str *
                         cmndinfo->OpCode));
                 /* special commands GDT_CLUST_INFO/GDT_MOUNT ? */
                 if (cmndinfo->OpCode == GDT_CLUST_INFO) {
-                    ha->hdr[t].cluster_type = (unchar)ha->info;
+                    ha->hdr[t].cluster_type = (u8)ha->info;
                     if (!(ha->hdr[t].cluster_type & 
                         CLUSTER_MOUNTED)) {
                         /* NOT MOUNTED -> MOUNT */
@@ -3397,7 +3398,7 @@ static int gdth_sync_event(gdth_ha_str *
                     ha->hdr[t].cluster_type &= ~CLUSTER_RESERVED;
                 }
                 memset((char*)scp->sense_buffer,0,16);
-                if (ha->status == (ushort)S_CACHE_RESERV) {
+                if (ha->status == (u16)S_CACHE_RESERV) {
                     scp->result = (DID_OK << 16) | (RESERVATION_CONFLICT << 1);
                 } else {
                     scp->sense_buffer[0] = 0x70;
@@ -3614,16 +3615,16 @@ static int gdth_async_event(gdth_ha_str
             cmdp->u.screen.su.msg.msg_addr  = ha->msg_phys;
             ha->cmd_offs_dpmem = 0;
             ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) 
-                + sizeof(ulong64);
+                + sizeof(u64);
             ha->cmd_cnt = 0;
             gdth_copy_command(ha);
             if (ha->type == GDT_EISA)
-                printk("[EISA slot %d] ",(ushort)ha->brd_phys);
+                printk("[EISA slot %d] ",(u16)ha->brd_phys);
             else if (ha->type == GDT_ISA)
-                printk("[DPMEM 0x%4X] ",(ushort)ha->brd_phys);
+                printk("[DPMEM 0x%4X] ",(u16)ha->brd_phys);
             else 
-                printk("[PCI %d/%d] ",(ushort)(ha->brd_phys>>8),
-                       (ushort)((ha->brd_phys>>3)&0x1f));
+                printk("[PCI %d/%d] ",(u16)(ha->brd_phys>>8),
+                       (u16)((ha->brd_phys>>3)&0x1f));
             gdth_release_event(ha);
         }
 
@@ -3640,7 +3641,7 @@ static int gdth_async_event(gdth_ha_str
             ha->dvr.eu.async.service = ha->service;
             ha->dvr.eu.async.status  = ha->status;
             ha->dvr.eu.async.info    = ha->info;
-            *(ulong32 *)ha->dvr.eu.async.scsi_coord  = ha->info2;
+            *(u32 *)ha->dvr.eu.async.scsi_coord  = ha->info2;
         }
         gdth_store_event( ha, ES_ASYNC, ha->service, &ha->dvr );
         gdth_log_event( &ha->dvr, NULL );
@@ -3648,8 +3649,8 @@ static int gdth_async_event(gdth_ha_str
         /* new host drive from expand? */
         if (ha->service == CACHESERVICE && ha->status == 56) {
             TRACE2(("gdth_async_event(): new host drive %d created\n",
-                    (ushort)ha->info));
-            /* gdth_analyse_hdrive(hanum, (ushort)ha->info); */
+                    (u16)ha->info));
+            /* gdth_analyse_hdrive(hanum, (u16)ha->info); */
         }   
     }
     return 1;
@@ -3680,13 +3681,13 @@ static void gdth_log_event(gdth_evt_data
         for (j=0,i=1; i < f[0]; i+=2) {
             switch (f[i+1]) {
               case 4:
-                stack.b[j++] = *(ulong32*)&dvr->eu.stream[(int)f[i]];
+                stack.b[j++] = *(u32*)&dvr->eu.stream[(int)f[i]];
                 break;
               case 2:
-                stack.b[j++] = *(ushort*)&dvr->eu.stream[(int)f[i]];
+                stack.b[j++] = *(u16*)&dvr->eu.stream[(int)f[i]];
                 break;
               case 1:
-                stack.b[j++] = *(unchar*)&dvr->eu.stream[(int)f[i]];
+                stack.b[j++] = *(u8*)&dvr->eu.stream[(int)f[i]];
                 break;
               default:
                 break;
@@ -3712,14 +3713,14 @@ static void gdth_log_event(gdth_evt_data
 }
 
 #ifdef GDTH_STATISTICS
-static unchar	gdth_timer_running;
+static u8	gdth_timer_running;
 
-static void gdth_timeout(ulong data)
+static void gdth_timeout(unsigned long data)
 {
-    ulong32 i;
+    u32 i;
     Scsi_Cmnd *nscp;
     gdth_ha_str *ha;
-    ulong flags;
+    unsigned long flags;
 
     if(unlikely(list_empty(&gdth_instances))) {
 	    gdth_timer_running = 0;
@@ -3891,8 +3892,8 @@ static enum blk_eh_timer_return gdth_tim
 {
 	gdth_ha_str *ha = shost_priv(scp->device->host);
 	struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
-	unchar b, t;
-	ulong flags;
+	u8 b, t;
+	unsigned long flags;
 	enum blk_eh_timer_return retval = BLK_EH_NOT_HANDLED;
 
 	TRACE(("%s() cmd 0x%x\n", scp->cmnd[0], __func__));
@@ -3924,9 +3925,9 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *
 {
     gdth_ha_str *ha = shost_priv(scp->device->host);
     int i;
-    ulong flags;
+    unsigned long flags;
     Scsi_Cmnd *cmnd;
-    unchar b;
+    u8 b;
 
     TRACE2(("gdth_eh_bus_reset()\n"));
 
@@ -3974,7 +3975,7 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *
 
 static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,sector_t cap,int *ip)
 {
-    unchar b, t;
+    u8 b, t;
     gdth_ha_str *ha = shost_priv(sdev->host);
     struct scsi_device *sd;
     unsigned capacity;
@@ -4062,7 +4063,7 @@ static int ioc_event(void __user *arg)
 {
     gdth_ioctl_event evt;
     gdth_ha_str *ha;
-    ulong flags;
+    unsigned long flags;
 
     if (copy_from_user(&evt, arg, sizeof(gdth_ioctl_event)))
         return -EFAULT;
@@ -4098,8 +4099,8 @@ static int ioc_event(void __user *arg)
 static int ioc_lockdrv(void __user *arg)
 {
     gdth_ioctl_lockdrv ldrv;
-    unchar i, j;
-    ulong flags;
+    u8 i, j;
+    unsigned long flags;
     gdth_ha_str *ha;
 
     if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv)))
@@ -4165,7 +4166,7 @@ static int ioc_general(void __user *arg,
 {
     gdth_ioctl_general gen;
     char *buf = NULL;
-    ulong64 paddr; 
+    u64 paddr; 
     gdth_ha_str *ha;
     int rval;
 
@@ -4194,7 +4195,7 @@ static int ioc_general(void __user *arg,
                 gen.command.u.cache64.DeviceNo = gen.command.u.cache.DeviceNo;
                 /* addresses */
                 if (ha->cache_feat & SCATTER_GATHER) {
-                    gen.command.u.cache64.DestAddr = (ulong64)-1;
+                    gen.command.u.cache64.DestAddr = (u64)-1;
                     gen.command.u.cache64.sg_canz = 1;
                     gen.command.u.cache64.sg_lst[0].sg_ptr = paddr;
                     gen.command.u.cache64.sg_lst[0].sg_len = gen.data_len;
@@ -4207,7 +4208,7 @@ static int ioc_general(void __user *arg,
                 if (ha->cache_feat & SCATTER_GATHER) {
                     gen.command.u.cache.DestAddr = 0xffffffff;
                     gen.command.u.cache.sg_canz = 1;
-                    gen.command.u.cache.sg_lst[0].sg_ptr = (ulong32)paddr;
+                    gen.command.u.cache.sg_lst[0].sg_ptr = (u32)paddr;
                     gen.command.u.cache.sg_lst[0].sg_len = gen.data_len;
                     gen.command.u.cache.sg_lst[1].sg_len = 0;
                 } else {
@@ -4230,7 +4231,7 @@ static int ioc_general(void __user *arg,
                 gen.command.u.raw64.direction = gen.command.u.raw.direction;
                 /* addresses */
                 if (ha->raw_feat & SCATTER_GATHER) {
-                    gen.command.u.raw64.sdata = (ulong64)-1;
+                    gen.command.u.raw64.sdata = (u64)-1;
                     gen.command.u.raw64.sg_ranz = 1;
                     gen.command.u.raw64.sg_lst[0].sg_ptr = paddr;
                     gen.command.u.raw64.sg_lst[0].sg_len = gen.data_len;
@@ -4244,14 +4245,14 @@ static int ioc_general(void __user *arg,
                 if (ha->raw_feat & SCATTER_GATHER) {
                     gen.command.u.raw.sdata = 0xffffffff;
                     gen.command.u.raw.sg_ranz = 1;
-                    gen.command.u.raw.sg_lst[0].sg_ptr = (ulong32)paddr;
+                    gen.command.u.raw.sg_lst[0].sg_ptr = (u32)paddr;
                     gen.command.u.raw.sg_lst[0].sg_len = gen.data_len;
                     gen.command.u.raw.sg_lst[1].sg_len = 0;
                 } else {
                     gen.command.u.raw.sdata = paddr;
                     gen.command.u.raw.sg_ranz = 0;
                 }
-                gen.command.u.raw.sense_data = (ulong32)paddr + gen.data_len;
+                gen.command.u.raw.sense_data = (u32)paddr + gen.data_len;
             }
         } else {
             gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr);
@@ -4283,7 +4284,7 @@ static int ioc_hdrlist(void __user *arg,
     gdth_ioctl_rescan *rsc;
     gdth_cmd_str *cmd;
     gdth_ha_str *ha;
-    unchar i;
+    u8 i;
     int rc = -ENOMEM;
     u32 cluster_type = 0;
 
@@ -4335,11 +4336,11 @@ static int ioc_rescan(void __user *arg,
 {
     gdth_ioctl_rescan *rsc;
     gdth_cmd_str *cmd;
-    ushort i, status, hdr_cnt;
-    ulong32 info;
+    u16 i, status, hdr_cnt;
+    u32 info;
     int cyls, hds, secs;
     int rc = -ENOMEM;
-    ulong flags;
+    unsigned long flags;
     gdth_ha_str *ha; 
 
     rsc = kmalloc(sizeof(*rsc), GFP_KERNEL);
@@ -4367,7 +4368,7 @@ static int ioc_rescan(void __user *arg,
 
         status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info);
         i = 0;
-        hdr_cnt = (status == S_OK ? (ushort)info : 0);
+        hdr_cnt = (status == S_OK ? (u16)info : 0);
     } else {
         i = rsc->hdr_no;
         hdr_cnt = i + 1;
@@ -4418,7 +4419,7 @@ static int ioc_rescan(void __user *arg,
         status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info);
 
         spin_lock_irqsave(&ha->smp_lock, flags);
-        ha->hdr[i].devtype = (status == S_OK ? (ushort)info : 0);
+        ha->hdr[i].devtype = (status == S_OK ? (u16)info : 0);
         spin_unlock_irqrestore(&ha->smp_lock, flags);
 
         cmd->Service = CACHESERVICE;
@@ -4432,7 +4433,7 @@ static int ioc_rescan(void __user *arg,
 
         spin_lock_irqsave(&ha->smp_lock, flags);
         ha->hdr[i].cluster_type = 
-            ((status == S_OK && !shared_access) ? (ushort)info : 0);
+            ((status == S_OK && !shared_access) ? (u16)info : 0);
         spin_unlock_irqrestore(&ha->smp_lock, flags);
         rsc->hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
 
@@ -4446,7 +4447,7 @@ static int ioc_rescan(void __user *arg,
         status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info);
 
         spin_lock_irqsave(&ha->smp_lock, flags);
-        ha->hdr[i].rw_attribs = (status == S_OK ? (ushort)info : 0);
+        ha->hdr[i].rw_attribs = (status == S_OK ? (u16)info : 0);
         spin_unlock_irqrestore(&ha->smp_lock, flags);
     }
  
@@ -4466,7 +4467,7 @@ static int gdth_ioctl(struct inode *inod
 {
     gdth_ha_str *ha; 
     Scsi_Cmnd *scp;
-    ulong flags;
+    unsigned long flags;
     char cmnd[MAX_COMMAND_SIZE];   
     void __user *argp = (void __user *)arg;
 
@@ -4495,9 +4496,9 @@ static int gdth_ioctl(struct inode *inod
       { 
         gdth_ioctl_osvers osv; 
 
-        osv.version = (unchar)(LINUX_VERSION_CODE >> 16);
-        osv.subversion = (unchar)(LINUX_VERSION_CODE >> 8);
-        osv.revision = (ushort)(LINUX_VERSION_CODE & 0xff);
+        osv.version = (u8)(LINUX_VERSION_CODE >> 16);
+        osv.subversion = (u8)(LINUX_VERSION_CODE >> 8);
+        osv.revision = (u16)(LINUX_VERSION_CODE & 0xff);
         if (copy_to_user(argp, &osv, sizeof(gdth_ioctl_osvers)))
                 return -EFAULT;
         break;
@@ -4512,10 +4513,10 @@ static int gdth_ioctl(struct inode *inod
             return -EFAULT;
 
         if (ha->type == GDT_ISA || ha->type == GDT_EISA) {
-            ctrt.type = (unchar)((ha->stype>>20) - 0x10);
+            ctrt.type = (u8)((ha->stype>>20) - 0x10);
         } else {
             if (ha->type != GDT_PCIMPR) {
-                ctrt.type = (unchar)((ha->stype<<4) + 6);
+                ctrt.type = (u8)((ha->stype<<4) + 6);
             } else {
                 ctrt.type = 
                     (ha->oem_id == OEM_ID_INTEL ? 0xfd : 0xfe);
@@ -4546,7 +4547,7 @@ static int gdth_ioctl(struct inode *inod
       case GDTIOCTL_LOCKCHN:
       {
         gdth_ioctl_lockchn lchn;
-        unchar i, j;
+        u8 i, j;
 
         if (copy_from_user(&lchn, argp, sizeof(gdth_ioctl_lockchn)) ||
             (NULL == (ha = gdth_find_ha(lchn.ionode))))
@@ -4670,7 +4671,7 @@ static struct scsi_host_template gdth_te
 };
 
 #ifdef CONFIG_ISA
-static int __init gdth_isa_probe_one(ulong32 isa_bios)
+static int __init gdth_isa_probe_one(u32 isa_bios)
 {
 	struct Scsi_Host *shp;
 	gdth_ha_str *ha;
@@ -4802,7 +4803,7 @@ static int __init gdth_isa_probe_one(ulo
 #endif /* CONFIG_ISA */
 
 #ifdef CONFIG_EISA
-static int __init gdth_eisa_probe_one(ushort eisa_slot)
+static int __init gdth_eisa_probe_one(u16 eisa_slot)
 {
 	struct Scsi_Host *shp;
 	gdth_ha_str *ha;
@@ -5120,7 +5121,7 @@ static void gdth_remove_one(gdth_ha_str
 	scsi_host_put(shp);
 }
 
-static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
+static int gdth_halt(struct notifier_block *nb, unsigned long event, void *buf)
 {
 	gdth_ha_str *ha;
 
@@ -5158,14 +5159,14 @@ static int __init gdth_init(void)
 	if (probe_eisa_isa) {
 		/* scanning for controllers, at first: ISA controller */
 #ifdef CONFIG_ISA
-		ulong32 isa_bios;
+		u32 isa_bios;
 		for (isa_bios = 0xc8000UL; isa_bios <= 0xd8000UL;
 		                isa_bios += 0x8000UL)
 			gdth_isa_probe_one(isa_bios);
 #endif
 #ifdef CONFIG_EISA
 		{
-			ushort eisa_slot;
+			u16 eisa_slot;
 			for (eisa_slot = 0x1000; eisa_slot <= 0x8000;
 			                         eisa_slot += 0x1000)
 				gdth_eisa_probe_one(eisa_slot);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/gdth.h linux-libre-2.6.34-gnu1/drivers/scsi/gdth.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/gdth.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/gdth.h	2010-05-16 17:17:36.000000000 -0400
@@ -321,524 +321,524 @@
 
 /* screenservice message */
 typedef struct {                               
-    ulong32     msg_handle;                     /* message handle */
-    ulong32     msg_len;                        /* size of message */
-    ulong32     msg_alen;                       /* answer length */
-    unchar      msg_answer;                     /* answer flag */
-    unchar      msg_ext;                        /* more messages */
-    unchar      msg_reserved[2];
+    u32     msg_handle;                     /* message handle */
+    u32     msg_len;                        /* size of message */
+    u32     msg_alen;                       /* answer length */
+    u8      msg_answer;                     /* answer flag */
+    u8      msg_ext;                        /* more messages */
+    u8      msg_reserved[2];
     char        msg_text[MSGLEN+2];             /* the message text */
-} PACKED gdth_msg_str;
+} __attribute__((packed)) gdth_msg_str;
 
 
 /* IOCTL data structures */
 
 /* Status coalescing buffer for returning multiple requests per interrupt */
 typedef struct {
-    ulong32     status;
-    ulong32     ext_status;
-    ulong32     info0;
-    ulong32     info1;
-} PACKED gdth_coal_status;
+    u32     status;
+    u32     ext_status;
+    u32     info0;
+    u32     info1;
+} __attribute__((packed)) gdth_coal_status;
 
 /* performance mode data structure */
 typedef struct {
-    ulong32     version;            /* The version of this IOCTL structure. */
-    ulong32     st_mode;            /* 0=dis., 1=st_buf_addr1 valid, 2=both  */
-    ulong32     st_buff_addr1;      /* physical address of status buffer 1 */
-    ulong32     st_buff_u_addr1;    /* reserved for 64 bit addressing */
-    ulong32     st_buff_indx1;      /* reserved command idx. for this buffer */
-    ulong32     st_buff_addr2;      /* physical address of status buffer 1 */
-    ulong32     st_buff_u_addr2;    /* reserved for 64 bit addressing */
-    ulong32     st_buff_indx2;      /* reserved command idx. for this buffer */
-    ulong32     st_buff_size;       /* size of each buffer in bytes */
-    ulong32     cmd_mode;           /* 0 = mode disabled, 1 = cmd_buff_addr1 */ 
-    ulong32     cmd_buff_addr1;     /* physical address of cmd buffer 1 */   
-    ulong32     cmd_buff_u_addr1;   /* reserved for 64 bit addressing */
-    ulong32     cmd_buff_indx1;     /* cmd buf addr1 unique identifier */
-    ulong32     cmd_buff_addr2;     /* physical address of cmd buffer 1 */   
-    ulong32     cmd_buff_u_addr2;   /* reserved for 64 bit addressing */
-    ulong32     cmd_buff_indx2;     /* cmd buf addr1 unique identifier */
-    ulong32     cmd_buff_size;      /* size of each cmd bufer in bytes */
-    ulong32     reserved1;
-    ulong32     reserved2;
-} PACKED gdth_perf_modes;
+    u32     version;            /* The version of this IOCTL structure. */
+    u32     st_mode;            /* 0=dis., 1=st_buf_addr1 valid, 2=both  */
+    u32     st_buff_addr1;      /* physical address of status buffer 1 */
+    u32     st_buff_u_addr1;    /* reserved for 64 bit addressing */
+    u32     st_buff_indx1;      /* reserved command idx. for this buffer */
+    u32     st_buff_addr2;      /* physical address of status buffer 1 */
+    u32     st_buff_u_addr2;    /* reserved for 64 bit addressing */
+    u32     st_buff_indx2;      /* reserved command idx. for this buffer */
+    u32     st_buff_size;       /* size of each buffer in bytes */
+    u32     cmd_mode;           /* 0 = mode disabled, 1 = cmd_buff_addr1 */ 
+    u32     cmd_buff_addr1;     /* physical address of cmd buffer 1 */   
+    u32     cmd_buff_u_addr1;   /* reserved for 64 bit addressing */
+    u32     cmd_buff_indx1;     /* cmd buf addr1 unique identifier */
+    u32     cmd_buff_addr2;     /* physical address of cmd buffer 1 */   
+    u32     cmd_buff_u_addr2;   /* reserved for 64 bit addressing */
+    u32     cmd_buff_indx2;     /* cmd buf addr1 unique identifier */
+    u32     cmd_buff_size;      /* size of each cmd bufer in bytes */
+    u32     reserved1;
+    u32     reserved2;
+} __attribute__((packed)) gdth_perf_modes;
 
 /* SCSI drive info */
 typedef struct {
-    unchar      vendor[8];                      /* vendor string */
-    unchar      product[16];                    /* product string */
-    unchar      revision[4];                    /* revision */
-    ulong32     sy_rate;                        /* current rate for sync. tr. */
-    ulong32     sy_max_rate;                    /* max. rate for sync. tr. */
-    ulong32     no_ldrive;                      /* belongs to this log. drv.*/
-    ulong32     blkcnt;                         /* number of blocks */
-    ushort      blksize;                        /* size of block in bytes */
-    unchar      available;                      /* flag: access is available */
-    unchar      init;                           /* medium is initialized */
-    unchar      devtype;                        /* SCSI devicetype */
-    unchar      rm_medium;                      /* medium is removable */
-    unchar      wp_medium;                      /* medium is write protected */
-    unchar      ansi;                           /* SCSI I/II or III? */
-    unchar      protocol;                       /* same as ansi */
-    unchar      sync;                           /* flag: sync. transfer enab. */
-    unchar      disc;                           /* flag: disconnect enabled */
-    unchar      queueing;                       /* flag: command queing enab. */
-    unchar      cached;                         /* flag: caching enabled */
-    unchar      target_id;                      /* target ID of device */
-    unchar      lun;                            /* LUN id of device */
-    unchar      orphan;                         /* flag: drive fragment */
-    ulong32     last_error;                     /* sense key or drive state */
-    ulong32     last_result;                    /* result of last command */
-    ulong32     check_errors;                   /* err. in last surface check */
-    unchar      percent;                        /* progress for surface check */
-    unchar      last_check;                     /* IOCTRL operation */
-    unchar      res[2];
-    ulong32     flags;                          /* from 1.19/2.19: raw reserv.*/
-    unchar      multi_bus;                      /* multi bus dev? (fibre ch.) */
-    unchar      mb_status;                      /* status: available? */
-    unchar      res2[2];
-    unchar      mb_alt_status;                  /* status on second bus */
-    unchar      mb_alt_bid;                     /* number of second bus */
-    unchar      mb_alt_tid;                     /* target id on second bus */
-    unchar      res3;
-    unchar      fc_flag;                        /* from 1.22/2.22: info valid?*/
-    unchar      res4;
-    ushort      fc_frame_size;                  /* frame size (bytes) */
+    u8      vendor[8];                      /* vendor string */
+    u8      product[16];                    /* product string */
+    u8      revision[4];                    /* revision */
+    u32     sy_rate;                        /* current rate for sync. tr. */
+    u32     sy_max_rate;                    /* max. rate for sync. tr. */
+    u32     no_ldrive;                      /* belongs to this log. drv.*/
+    u32     blkcnt;                         /* number of blocks */
+    u16      blksize;                        /* size of block in bytes */
+    u8      available;                      /* flag: access is available */
+    u8      init;                           /* medium is initialized */
+    u8      devtype;                        /* SCSI devicetype */
+    u8      rm_medium;                      /* medium is removable */
+    u8      wp_medium;                      /* medium is write protected */
+    u8      ansi;                           /* SCSI I/II or III? */
+    u8      protocol;                       /* same as ansi */
+    u8      sync;                           /* flag: sync. transfer enab. */
+    u8      disc;                           /* flag: disconnect enabled */
+    u8      queueing;                       /* flag: command queing enab. */
+    u8      cached;                         /* flag: caching enabled */
+    u8      target_id;                      /* target ID of device */
+    u8      lun;                            /* LUN id of device */
+    u8      orphan;                         /* flag: drive fragment */
+    u32     last_error;                     /* sense key or drive state */
+    u32     last_result;                    /* result of last command */
+    u32     check_errors;                   /* err. in last surface check */
+    u8      percent;                        /* progress for surface check */
+    u8      last_check;                     /* IOCTRL operation */
+    u8      res[2];
+    u32     flags;                          /* from 1.19/2.19: raw reserv.*/
+    u8      multi_bus;                      /* multi bus dev? (fibre ch.) */
+    u8      mb_status;                      /* status: available? */
+    u8      res2[2];
+    u8      mb_alt_status;                  /* status on second bus */
+    u8      mb_alt_bid;                     /* number of second bus */
+    u8      mb_alt_tid;                     /* target id on second bus */
+    u8      res3;
+    u8      fc_flag;                        /* from 1.22/2.22: info valid?*/
+    u8      res4;
+    u16      fc_frame_size;                  /* frame size (bytes) */
     char        wwn[8];                         /* world wide name */
-} PACKED gdth_diskinfo_str;
+} __attribute__((packed)) gdth_diskinfo_str;
 
 /* get SCSI channel count  */
 typedef struct {
-    ulong32     channel_no;                     /* number of channel */
-    ulong32     drive_cnt;                      /* drive count */
-    unchar      siop_id;                        /* SCSI processor ID */
-    unchar      siop_state;                     /* SCSI processor state */ 
-} PACKED gdth_getch_str;
+    u32     channel_no;                     /* number of channel */
+    u32     drive_cnt;                      /* drive count */
+    u8      siop_id;                        /* SCSI processor ID */
+    u8      siop_state;                     /* SCSI processor state */ 
+} __attribute__((packed)) gdth_getch_str;
 
 /* get SCSI drive numbers */
 typedef struct {
-    ulong32     sc_no;                          /* SCSI channel */
-    ulong32     sc_cnt;                         /* sc_list[] elements */
-    ulong32     sc_list[MAXID];                 /* minor device numbers */
-} PACKED gdth_drlist_str;
+    u32     sc_no;                          /* SCSI channel */
+    u32     sc_cnt;                         /* sc_list[] elements */
+    u32     sc_list[MAXID];                 /* minor device numbers */
+} __attribute__((packed)) gdth_drlist_str;
 
 /* get grown/primary defect count */
 typedef struct {
-    unchar      sddc_type;                      /* 0x08: grown, 0x10: prim. */
-    unchar      sddc_format;                    /* list entry format */
-    unchar      sddc_len;                       /* list entry length */
-    unchar      sddc_res;
-    ulong32     sddc_cnt;                       /* entry count */
-} PACKED gdth_defcnt_str;
+    u8      sddc_type;                      /* 0x08: grown, 0x10: prim. */
+    u8      sddc_format;                    /* list entry format */
+    u8      sddc_len;                       /* list entry length */
+    u8      sddc_res;
+    u32     sddc_cnt;                       /* entry count */
+} __attribute__((packed)) gdth_defcnt_str;
 
 /* disk statistics */
 typedef struct {
-    ulong32     bid;                            /* SCSI channel */
-    ulong32     first;                          /* first SCSI disk */
-    ulong32     entries;                        /* number of elements */
-    ulong32     count;                          /* (R) number of init. el. */
-    ulong32     mon_time;                       /* time stamp */
+    u32     bid;                            /* SCSI channel */
+    u32     first;                          /* first SCSI disk */
+    u32     entries;                        /* number of elements */
+    u32     count;                          /* (R) number of init. el. */
+    u32     mon_time;                       /* time stamp */
     struct {
-        unchar  tid;                            /* target ID */
-        unchar  lun;                            /* LUN */
-        unchar  res[2];
-        ulong32 blk_size;                       /* block size in bytes */
-        ulong32 rd_count;                       /* bytes read */
-        ulong32 wr_count;                       /* bytes written */
-        ulong32 rd_blk_count;                   /* blocks read */
-        ulong32 wr_blk_count;                   /* blocks written */
-        ulong32 retries;                        /* retries */
-        ulong32 reassigns;                      /* reassigns */
-    } PACKED list[1];
-} PACKED gdth_dskstat_str;
+        u8  tid;                            /* target ID */
+        u8  lun;                            /* LUN */
+        u8  res[2];
+        u32 blk_size;                       /* block size in bytes */
+        u32 rd_count;                       /* bytes read */
+        u32 wr_count;                       /* bytes written */
+        u32 rd_blk_count;                   /* blocks read */
+        u32 wr_blk_count;                   /* blocks written */
+        u32 retries;                        /* retries */
+        u32 reassigns;                      /* reassigns */
+    } __attribute__((packed)) list[1];
+} __attribute__((packed)) gdth_dskstat_str;
 
 /* IO channel header */
 typedef struct {
-    ulong32     version;                        /* version (-1UL: newest) */
-    unchar      list_entries;                   /* list entry count */
-    unchar      first_chan;                     /* first channel number */
-    unchar      last_chan;                      /* last channel number */
-    unchar      chan_count;                     /* (R) channel count */
-    ulong32     list_offset;                    /* offset of list[0] */
-} PACKED gdth_iochan_header;
+    u32     version;                        /* version (-1UL: newest) */
+    u8      list_entries;                   /* list entry count */
+    u8      first_chan;                     /* first channel number */
+    u8      last_chan;                      /* last channel number */
+    u8      chan_count;                     /* (R) channel count */
+    u32     list_offset;                    /* offset of list[0] */
+} __attribute__((packed)) gdth_iochan_header;
 
 /* get IO channel description */
 typedef struct {
     gdth_iochan_header  hdr;
     struct {
-        ulong32         address;                /* channel address */
-        unchar          type;                   /* type (SCSI, FCAL) */
-        unchar          local_no;               /* local number */
-        ushort          features;               /* channel features */
-    } PACKED list[MAXBUS];
-} PACKED gdth_iochan_str;
+        u32         address;                /* channel address */
+        u8          type;                   /* type (SCSI, FCAL) */
+        u8          local_no;               /* local number */
+        u16          features;               /* channel features */
+    } __attribute__((packed)) list[MAXBUS];
+} __attribute__((packed)) gdth_iochan_str;
 
 /* get raw IO channel description */
 typedef struct {
     gdth_iochan_header  hdr;
     struct {
-        unchar      proc_id;                    /* processor id */
-        unchar      proc_defect;                /* defect ? */
-        unchar      reserved[2];
-    } PACKED list[MAXBUS];
-} PACKED gdth_raw_iochan_str;
+        u8      proc_id;                    /* processor id */
+        u8      proc_defect;                /* defect ? */
+        u8      reserved[2];
+    } __attribute__((packed)) list[MAXBUS];
+} __attribute__((packed)) gdth_raw_iochan_str;
 
 /* array drive component */
 typedef struct {
-    ulong32     al_controller;                  /* controller ID */
-    unchar      al_cache_drive;                 /* cache drive number */
-    unchar      al_status;                      /* cache drive state */
-    unchar      al_res[2];     
-} PACKED gdth_arraycomp_str;
+    u32     al_controller;                  /* controller ID */
+    u8      al_cache_drive;                 /* cache drive number */
+    u8      al_status;                      /* cache drive state */
+    u8      al_res[2];     
+} __attribute__((packed)) gdth_arraycomp_str;
 
 /* array drive information */
 typedef struct {
-    unchar      ai_type;                        /* array type (RAID0,4,5) */
-    unchar      ai_cache_drive_cnt;             /* active cachedrives */
-    unchar      ai_state;                       /* array drive state */
-    unchar      ai_master_cd;                   /* master cachedrive */
-    ulong32     ai_master_controller;           /* ID of master controller */
-    ulong32     ai_size;                        /* user capacity [sectors] */
-    ulong32     ai_striping_size;               /* striping size [sectors] */
-    ulong32     ai_secsize;                     /* sector size [bytes] */
-    ulong32     ai_err_info;                    /* failed cache drive */
-    unchar      ai_name[8];                     /* name of the array drive */
-    unchar      ai_controller_cnt;              /* number of controllers */
-    unchar      ai_removable;                   /* flag: removable */
-    unchar      ai_write_protected;             /* flag: write protected */
-    unchar      ai_devtype;                     /* type: always direct access */
+    u8      ai_type;                        /* array type (RAID0,4,5) */
+    u8      ai_cache_drive_cnt;             /* active cachedrives */
+    u8      ai_state;                       /* array drive state */
+    u8      ai_master_cd;                   /* master cachedrive */
+    u32     ai_master_controller;           /* ID of master controller */
+    u32     ai_size;                        /* user capacity [sectors] */
+    u32     ai_striping_size;               /* striping size [sectors] */
+    u32     ai_secsize;                     /* sector size [bytes] */
+    u32     ai_err_info;                    /* failed cache drive */
+    u8      ai_name[8];                     /* name of the array drive */
+    u8      ai_controller_cnt;              /* number of controllers */
+    u8      ai_removable;                   /* flag: removable */
+    u8      ai_write_protected;             /* flag: write protected */
+    u8      ai_devtype;                     /* type: always direct access */
     gdth_arraycomp_str  ai_drives[35];          /* drive components: */
-    unchar      ai_drive_entries;               /* number of drive components */
-    unchar      ai_protected;                   /* protection flag */
-    unchar      ai_verify_state;                /* state of a parity verify */
-    unchar      ai_ext_state;                   /* extended array drive state */
-    unchar      ai_expand_state;                /* array expand state (>=2.18)*/
-    unchar      ai_reserved[3];
-} PACKED gdth_arrayinf_str;
+    u8      ai_drive_entries;               /* number of drive components */
+    u8      ai_protected;                   /* protection flag */
+    u8      ai_verify_state;                /* state of a parity verify */
+    u8      ai_ext_state;                   /* extended array drive state */
+    u8      ai_expand_state;                /* array expand state (>=2.18)*/
+    u8      ai_reserved[3];
+} __attribute__((packed)) gdth_arrayinf_str;
 
 /* get array drive list */
 typedef struct {
-    ulong32     controller_no;                  /* controller no. */
-    unchar      cd_handle;                      /* master cachedrive */
-    unchar      is_arrayd;                      /* Flag: is array drive? */
-    unchar      is_master;                      /* Flag: is array master? */
-    unchar      is_parity;                      /* Flag: is parity drive? */
-    unchar      is_hotfix;                      /* Flag: is hotfix drive? */
-    unchar      res[3];
-} PACKED gdth_alist_str;
+    u32     controller_no;                  /* controller no. */
+    u8      cd_handle;                      /* master cachedrive */
+    u8      is_arrayd;                      /* Flag: is array drive? */
+    u8      is_master;                      /* Flag: is array master? */
+    u8      is_parity;                      /* Flag: is parity drive? */
+    u8      is_hotfix;                      /* Flag: is hotfix drive? */
+    u8      res[3];
+} __attribute__((packed)) gdth_alist_str;
 
 typedef struct {
-    ulong32     entries_avail;                  /* allocated entries */
-    ulong32     entries_init;                   /* returned entries */
-    ulong32     first_entry;                    /* first entry number */
-    ulong32     list_offset;                    /* offset of following list */
+    u32     entries_avail;                  /* allocated entries */
+    u32     entries_init;                   /* returned entries */
+    u32     first_entry;                    /* first entry number */
+    u32     list_offset;                    /* offset of following list */
     gdth_alist_str list[1];                     /* list */
-} PACKED gdth_arcdl_str;
+} __attribute__((packed)) gdth_arcdl_str;
 
 /* cache info/config IOCTL */
 typedef struct {
-    ulong32     version;                        /* firmware version */
-    ushort      state;                          /* cache state (on/off) */
-    ushort      strategy;                       /* cache strategy */
-    ushort      write_back;                     /* write back state (on/off) */
-    ushort      block_size;                     /* cache block size */
-} PACKED gdth_cpar_str;
+    u32     version;                        /* firmware version */
+    u16      state;                          /* cache state (on/off) */
+    u16      strategy;                       /* cache strategy */
+    u16      write_back;                     /* write back state (on/off) */
+    u16      block_size;                     /* cache block size */
+} __attribute__((packed)) gdth_cpar_str;
 
 typedef struct {
-    ulong32     csize;                          /* cache size */
-    ulong32     read_cnt;                       /* read/write counter */
-    ulong32     write_cnt;
-    ulong32     tr_hits;                        /* hits */
-    ulong32     sec_hits;
-    ulong32     sec_miss;                       /* misses */
-} PACKED gdth_cstat_str;
+    u32     csize;                          /* cache size */
+    u32     read_cnt;                       /* read/write counter */
+    u32     write_cnt;
+    u32     tr_hits;                        /* hits */
+    u32     sec_hits;
+    u32     sec_miss;                       /* misses */
+} __attribute__((packed)) gdth_cstat_str;
 
 typedef struct {
     gdth_cpar_str   cpar;
     gdth_cstat_str  cstat;
-} PACKED gdth_cinfo_str;
+} __attribute__((packed)) gdth_cinfo_str;
 
 /* cache drive info */
 typedef struct {
-    unchar      cd_name[8];                     /* cache drive name */
-    ulong32     cd_devtype;                     /* SCSI devicetype */
-    ulong32     cd_ldcnt;                       /* number of log. drives */
-    ulong32     cd_last_error;                  /* last error */
-    unchar      cd_initialized;                 /* drive is initialized */
-    unchar      cd_removable;                   /* media is removable */
-    unchar      cd_write_protected;             /* write protected */
-    unchar      cd_flags;                       /* Pool Hot Fix? */
-    ulong32     ld_blkcnt;                      /* number of blocks */
-    ulong32     ld_blksize;                     /* blocksize */
-    ulong32     ld_dcnt;                        /* number of disks */
-    ulong32     ld_slave;                       /* log. drive index */
-    ulong32     ld_dtype;                       /* type of logical drive */
-    ulong32     ld_last_error;                  /* last error */
-    unchar      ld_name[8];                     /* log. drive name */
-    unchar      ld_error;                       /* error */
-} PACKED gdth_cdrinfo_str;
+    u8      cd_name[8];                     /* cache drive name */
+    u32     cd_devtype;                     /* SCSI devicetype */
+    u32     cd_ldcnt;                       /* number of log. drives */
+    u32     cd_last_error;                  /* last error */
+    u8      cd_initialized;                 /* drive is initialized */
+    u8      cd_removable;                   /* media is removable */
+    u8      cd_write_protected;             /* write protected */
+    u8      cd_flags;                       /* Pool Hot Fix? */
+    u32     ld_blkcnt;                      /* number of blocks */
+    u32     ld_blksize;                     /* blocksize */
+    u32     ld_dcnt;                        /* number of disks */
+    u32     ld_slave;                       /* log. drive index */
+    u32     ld_dtype;                       /* type of logical drive */
+    u32     ld_last_error;                  /* last error */
+    u8      ld_name[8];                     /* log. drive name */
+    u8      ld_error;                       /* error */
+} __attribute__((packed)) gdth_cdrinfo_str;
 
 /* OEM string */
 typedef struct {
-    ulong32     ctl_version;
-    ulong32     file_major_version;
-    ulong32     file_minor_version;
-    ulong32     buffer_size;
-    ulong32     cpy_count;
-    ulong32     ext_error;
-    ulong32     oem_id;
-    ulong32     board_id;
-} PACKED gdth_oem_str_params;
+    u32     ctl_version;
+    u32     file_major_version;
+    u32     file_minor_version;
+    u32     buffer_size;
+    u32     cpy_count;
+    u32     ext_error;
+    u32     oem_id;
+    u32     board_id;
+} __attribute__((packed)) gdth_oem_str_params;
 
 typedef struct {
-    unchar      product_0_1_name[16];
-    unchar      product_4_5_name[16];
-    unchar      product_cluster_name[16];
-    unchar      product_reserved[16];
-    unchar      scsi_cluster_target_vendor_id[16];
-    unchar      cluster_raid_fw_name[16];
-    unchar      oem_brand_name[16];
-    unchar      oem_raid_type[16];
-    unchar      bios_type[13];
-    unchar      bios_title[50];
-    unchar      oem_company_name[37];
-    ulong32     pci_id_1;
-    ulong32     pci_id_2;
-    unchar      validation_status[80];
-    unchar      reserved_1[4];
-    unchar      scsi_host_drive_inquiry_vendor_id[16];
-    unchar      library_file_template[16];
-    unchar      reserved_2[16];
-    unchar      tool_name_1[32];
-    unchar      tool_name_2[32];
-    unchar      tool_name_3[32];
-    unchar      oem_contact_1[84];
-    unchar      oem_contact_2[84];
-    unchar      oem_contact_3[84];
-} PACKED gdth_oem_str;
+    u8      product_0_1_name[16];
+    u8      product_4_5_name[16];
+    u8      product_cluster_name[16];
+    u8      product_reserved[16];
+    u8      scsi_cluster_target_vendor_id[16];
+    u8      cluster_raid_fw_name[16];
+    u8      oem_brand_name[16];
+    u8      oem_raid_type[16];
+    u8      bios_type[13];
+    u8      bios_title[50];
+    u8      oem_company_name[37];
+    u32     pci_id_1;
+    u32     pci_id_2;
+    u8      validation_status[80];
+    u8      reserved_1[4];
+    u8      scsi_host_drive_inquiry_vendor_id[16];
+    u8      library_file_template[16];
+    u8      reserved_2[16];
+    u8      tool_name_1[32];
+    u8      tool_name_2[32];
+    u8      tool_name_3[32];
+    u8      oem_contact_1[84];
+    u8      oem_contact_2[84];
+    u8      oem_contact_3[84];
+} __attribute__((packed)) gdth_oem_str;
 
 typedef struct {
     gdth_oem_str_params params;
     gdth_oem_str        text;
-} PACKED gdth_oem_str_ioctl;
+} __attribute__((packed)) gdth_oem_str_ioctl;
 
 /* board features */
 typedef struct {
-    unchar      chaining;                       /* Chaining supported */
-    unchar      striping;                       /* Striping (RAID-0) supp. */
-    unchar      mirroring;                      /* Mirroring (RAID-1) supp. */
-    unchar      raid;                           /* RAID-4/5/10 supported */
-} PACKED gdth_bfeat_str;
+    u8      chaining;                       /* Chaining supported */
+    u8      striping;                       /* Striping (RAID-0) supp. */
+    u8      mirroring;                      /* Mirroring (RAID-1) supp. */
+    u8      raid;                           /* RAID-4/5/10 supported */
+} __attribute__((packed)) gdth_bfeat_str;
 
 /* board info IOCTL */
 typedef struct {
-    ulong32     ser_no;                         /* serial no. */
-    unchar      oem_id[2];                      /* OEM ID */
-    ushort      ep_flags;                       /* eprom flags */
-    ulong32     proc_id;                        /* processor ID */
-    ulong32     memsize;                        /* memory size (bytes) */
-    unchar      mem_banks;                      /* memory banks */
-    unchar      chan_type;                      /* channel type */
-    unchar      chan_count;                     /* channel count */
-    unchar      rdongle_pres;                   /* dongle present? */
-    ulong32     epr_fw_ver;                     /* (eprom) firmware version */
-    ulong32     upd_fw_ver;                     /* (update) firmware version */
-    ulong32     upd_revision;                   /* update revision */
+    u32     ser_no;                         /* serial no. */
+    u8      oem_id[2];                      /* OEM ID */
+    u16      ep_flags;                       /* eprom flags */
+    u32     proc_id;                        /* processor ID */
+    u32     memsize;                        /* memory size (bytes) */
+    u8      mem_banks;                      /* memory banks */
+    u8      chan_type;                      /* channel type */
+    u8      chan_count;                     /* channel count */
+    u8      rdongle_pres;                   /* dongle present? */
+    u32     epr_fw_ver;                     /* (eprom) firmware version */
+    u32     upd_fw_ver;                     /* (update) firmware version */
+    u32     upd_revision;                   /* update revision */
     char        type_string[16];                /* controller name */
     char        raid_string[16];                /* RAID firmware name */
-    unchar      update_pres;                    /* update present? */
-    unchar      xor_pres;                       /* XOR engine present? */
-    unchar      prom_type;                      /* ROM type (eprom/flash) */
-    unchar      prom_count;                     /* number of ROM devices */
-    ulong32     dup_pres;                       /* duplexing module present? */
-    ulong32     chan_pres;                      /* number of expansion chn. */
-    ulong32     mem_pres;                       /* memory expansion inst. ? */
-    unchar      ft_bus_system;                  /* fault bus supported? */
-    unchar      subtype_valid;                  /* board_subtype valid? */
-    unchar      board_subtype;                  /* subtype/hardware level */
-    unchar      ramparity_pres;                 /* RAM parity check hardware? */
-} PACKED gdth_binfo_str; 
+    u8      update_pres;                    /* update present? */
+    u8      xor_pres;                       /* XOR engine present? */
+    u8      prom_type;                      /* ROM type (eprom/flash) */
+    u8      prom_count;                     /* number of ROM devices */
+    u32     dup_pres;                       /* duplexing module present? */
+    u32     chan_pres;                      /* number of expansion chn. */
+    u32     mem_pres;                       /* memory expansion inst. ? */
+    u8      ft_bus_system;                  /* fault bus supported? */
+    u8      subtype_valid;                  /* board_subtype valid? */
+    u8      board_subtype;                  /* subtype/hardware level */
+    u8      ramparity_pres;                 /* RAM parity check hardware? */
+} __attribute__((packed)) gdth_binfo_str; 
 
 /* get host drive info */
 typedef struct {
     char        name[8];                        /* host drive name */
-    ulong32     size;                           /* size (sectors) */
-    unchar      host_drive;                     /* host drive number */
-    unchar      log_drive;                      /* log. drive (master) */
-    unchar      reserved;
-    unchar      rw_attribs;                     /* r/w attribs */
-    ulong32     start_sec;                      /* start sector */
-} PACKED gdth_hentry_str;
+    u32     size;                           /* size (sectors) */
+    u8      host_drive;                     /* host drive number */
+    u8      log_drive;                      /* log. drive (master) */
+    u8      reserved;
+    u8      rw_attribs;                     /* r/w attribs */
+    u32     start_sec;                      /* start sector */
+} __attribute__((packed)) gdth_hentry_str;
 
 typedef struct {
-    ulong32     entries;                        /* entry count */
-    ulong32     offset;                         /* offset of entries */
-    unchar      secs_p_head;                    /* sectors/head */
-    unchar      heads_p_cyl;                    /* heads/cylinder */
-    unchar      reserved;
-    unchar      clust_drvtype;                  /* cluster drive type */
-    ulong32     location;                       /* controller number */
+    u32     entries;                        /* entry count */
+    u32     offset;                         /* offset of entries */
+    u8      secs_p_head;                    /* sectors/head */
+    u8      heads_p_cyl;                    /* heads/cylinder */
+    u8      reserved;
+    u8      clust_drvtype;                  /* cluster drive type */
+    u32     location;                       /* controller number */
     gdth_hentry_str entry[MAX_HDRIVES];         /* entries */
-} PACKED gdth_hget_str;    
+} __attribute__((packed)) gdth_hget_str;    
 
 
 /* DPRAM structures */
 
 /* interface area ISA/PCI */
 typedef struct {
-    unchar              S_Cmd_Indx;             /* special command */
-    unchar volatile     S_Status;               /* status special command */
-    ushort              reserved1;
-    ulong32             S_Info[4];              /* add. info special command */
-    unchar volatile     Sema0;                  /* command semaphore */
-    unchar              reserved2[3];
-    unchar              Cmd_Index;              /* command number */
-    unchar              reserved3[3];
-    ushort volatile     Status;                 /* command status */
-    ushort              Service;                /* service(for async.events) */
-    ulong32             Info[2];                /* additional info */
+    u8              S_Cmd_Indx;             /* special command */
+    u8 volatile     S_Status;               /* status special command */
+    u16              reserved1;
+    u32             S_Info[4];              /* add. info special command */
+    u8 volatile     Sema0;                  /* command semaphore */
+    u8              reserved2[3];
+    u8              Cmd_Index;              /* command number */
+    u8              reserved3[3];
+    u16 volatile     Status;                 /* command status */
+    u16              Service;                /* service(for async.events) */
+    u32             Info[2];                /* additional info */
     struct {
-        ushort          offset;                 /* command offs. in the DPRAM*/
-        ushort          serv_id;                /* service */
-    } PACKED comm_queue[MAXOFFSETS];            /* command queue */
-    ulong32             bios_reserved[2];
-    unchar              gdt_dpr_cmd[1];         /* commands */
-} PACKED gdt_dpr_if;
+        u16          offset;                 /* command offs. in the DPRAM*/
+        u16          serv_id;                /* service */
+    } __attribute__((packed)) comm_queue[MAXOFFSETS];            /* command queue */
+    u32             bios_reserved[2];
+    u8              gdt_dpr_cmd[1];         /* commands */
+} __attribute__((packed)) gdt_dpr_if;
 
 /* SRAM structure PCI controllers */
 typedef struct {
-    ulong32     magic;                          /* controller ID from BIOS */
-    ushort      need_deinit;                    /* switch betw. BIOS/driver */
-    unchar      switch_support;                 /* see need_deinit */
-    unchar      padding[9];
-    unchar      os_used[16];                    /* OS code per service */
-    unchar      unused[28];
-    unchar      fw_magic;                       /* contr. ID from firmware */
-} PACKED gdt_pci_sram;
+    u32     magic;                          /* controller ID from BIOS */
+    u16      need_deinit;                    /* switch betw. BIOS/driver */
+    u8      switch_support;                 /* see need_deinit */
+    u8      padding[9];
+    u8      os_used[16];                    /* OS code per service */
+    u8      unused[28];
+    u8      fw_magic;                       /* contr. ID from firmware */
+} __attribute__((packed)) gdt_pci_sram;
 
 /* SRAM structure EISA controllers (but NOT GDT3000/3020) */
 typedef struct {
-    unchar      os_used[16];                    /* OS code per service */
-    ushort      need_deinit;                    /* switch betw. BIOS/driver */
-    unchar      switch_support;                 /* see need_deinit */
-    unchar      padding;
-} PACKED gdt_eisa_sram;
+    u8      os_used[16];                    /* OS code per service */
+    u16      need_deinit;                    /* switch betw. BIOS/driver */
+    u8      switch_support;                 /* see need_deinit */
+    u8      padding;
+} __attribute__((packed)) gdt_eisa_sram;
 
 
 /* DPRAM ISA controllers */
 typedef struct {
     union {
         struct {
-            unchar      bios_used[0x3c00-32];   /* 15KB - 32Bytes BIOS */
-            ulong32     magic;                  /* controller (EISA) ID */
-            ushort      need_deinit;            /* switch betw. BIOS/driver */
-            unchar      switch_support;         /* see need_deinit */
-            unchar      padding[9];
-            unchar      os_used[16];            /* OS code per service */
-        } PACKED dp_sram;
-        unchar          bios_area[0x4000];      /* 16KB reserved for BIOS */
+            u8      bios_used[0x3c00-32];   /* 15KB - 32Bytes BIOS */
+            u32     magic;                  /* controller (EISA) ID */
+            u16      need_deinit;            /* switch betw. BIOS/driver */
+            u8      switch_support;         /* see need_deinit */
+            u8      padding[9];
+            u8      os_used[16];            /* OS code per service */
+        } __attribute__((packed)) dp_sram;
+        u8          bios_area[0x4000];      /* 16KB reserved for BIOS */
     } bu;
     union {
         gdt_dpr_if      ic;                     /* interface area */
-        unchar          if_area[0x3000];        /* 12KB for interface */
+        u8          if_area[0x3000];        /* 12KB for interface */
     } u;
     struct {
-        unchar          memlock;                /* write protection DPRAM */
-        unchar          event;                  /* release event */
-        unchar          irqen;                  /* board interrupts enable */
-        unchar          irqdel;                 /* acknowledge board int. */
-        unchar volatile Sema1;                  /* status semaphore */
-        unchar          rq;                     /* IRQ/DRQ configuration */
-    } PACKED io;
-} PACKED gdt2_dpram_str;
+        u8          memlock;                /* write protection DPRAM */
+        u8          event;                  /* release event */
+        u8          irqen;                  /* board interrupts enable */
+        u8          irqdel;                 /* acknowledge board int. */
+        u8 volatile Sema1;                  /* status semaphore */
+        u8          rq;                     /* IRQ/DRQ configuration */
+    } __attribute__((packed)) io;
+} __attribute__((packed)) gdt2_dpram_str;
 
 /* DPRAM PCI controllers */
 typedef struct {
     union {
         gdt_dpr_if      ic;                     /* interface area */
-        unchar          if_area[0xff0-sizeof(gdt_pci_sram)];
+        u8          if_area[0xff0-sizeof(gdt_pci_sram)];
     } u;
     gdt_pci_sram        gdt6sr;                 /* SRAM structure */
     struct {
-        unchar          unused0[1];
-        unchar volatile Sema1;                  /* command semaphore */
-        unchar          unused1[3];
-        unchar          irqen;                  /* board interrupts enable */
-        unchar          unused2[2];
-        unchar          event;                  /* release event */
-        unchar          unused3[3];
-        unchar          irqdel;                 /* acknowledge board int. */
-        unchar          unused4[3];
-    } PACKED io;
-} PACKED gdt6_dpram_str;
+        u8          unused0[1];
+        u8 volatile Sema1;                  /* command semaphore */
+        u8          unused1[3];
+        u8          irqen;                  /* board interrupts enable */
+        u8          unused2[2];
+        u8          event;                  /* release event */
+        u8          unused3[3];
+        u8          irqdel;                 /* acknowledge board int. */
+        u8          unused4[3];
+    } __attribute__((packed)) io;
+} __attribute__((packed)) gdt6_dpram_str;
 
 /* PLX register structure (new PCI controllers) */
 typedef struct {
-    unchar              cfg_reg;        /* DPRAM cfg.(2:below 1MB,0:anywhere)*/
-    unchar              unused1[0x3f];
-    unchar volatile     sema0_reg;              /* command semaphore */
-    unchar volatile     sema1_reg;              /* status semaphore */
-    unchar              unused2[2];
-    ushort volatile     status;                 /* command status */
-    ushort              service;                /* service */
-    ulong32             info[2];                /* additional info */
-    unchar              unused3[0x10];
-    unchar              ldoor_reg;              /* PCI to local doorbell */
-    unchar              unused4[3];
-    unchar volatile     edoor_reg;              /* local to PCI doorbell */
-    unchar              unused5[3];
-    unchar              control0;               /* control0 register(unused) */
-    unchar              control1;               /* board interrupts enable */
-    unchar              unused6[0x16];
-} PACKED gdt6c_plx_regs;
+    u8              cfg_reg;        /* DPRAM cfg.(2:below 1MB,0:anywhere)*/
+    u8              unused1[0x3f];
+    u8 volatile     sema0_reg;              /* command semaphore */
+    u8 volatile     sema1_reg;              /* status semaphore */
+    u8              unused2[2];
+    u16 volatile     status;                 /* command status */
+    u16              service;                /* service */
+    u32             info[2];                /* additional info */
+    u8              unused3[0x10];
+    u8              ldoor_reg;              /* PCI to local doorbell */
+    u8              unused4[3];
+    u8 volatile     edoor_reg;              /* local to PCI doorbell */
+    u8              unused5[3];
+    u8              control0;               /* control0 register(unused) */
+    u8              control1;               /* board interrupts enable */
+    u8              unused6[0x16];
+} __attribute__((packed)) gdt6c_plx_regs;
 
 /* DPRAM new PCI controllers */
 typedef struct {
     union {
         gdt_dpr_if      ic;                     /* interface area */
-        unchar          if_area[0x4000-sizeof(gdt_pci_sram)];
+        u8          if_area[0x4000-sizeof(gdt_pci_sram)];
     } u;
     gdt_pci_sram        gdt6sr;                 /* SRAM structure */
-} PACKED gdt6c_dpram_str;
+} __attribute__((packed)) gdt6c_dpram_str;
 
 /* i960 register structure (PCI MPR controllers) */
 typedef struct {
-    unchar              unused1[16];
-    unchar volatile     sema0_reg;              /* command semaphore */
-    unchar              unused2;
-    unchar volatile     sema1_reg;              /* status semaphore */
-    unchar              unused3;
-    ushort volatile     status;                 /* command status */
-    ushort              service;                /* service */
-    ulong32             info[2];                /* additional info */
-    unchar              ldoor_reg;              /* PCI to local doorbell */
-    unchar              unused4[11];
-    unchar volatile     edoor_reg;              /* local to PCI doorbell */
-    unchar              unused5[7];
-    unchar              edoor_en_reg;           /* board interrupts enable */
-    unchar              unused6[27];
-    ulong32             unused7[939];         
-    ulong32             severity;       
+    u8              unused1[16];
+    u8 volatile     sema0_reg;              /* command semaphore */
+    u8              unused2;
+    u8 volatile     sema1_reg;              /* status semaphore */
+    u8              unused3;
+    u16 volatile     status;                 /* command status */
+    u16              service;                /* service */
+    u32             info[2];                /* additional info */
+    u8              ldoor_reg;              /* PCI to local doorbell */
+    u8              unused4[11];
+    u8 volatile     edoor_reg;              /* local to PCI doorbell */
+    u8              unused5[7];
+    u8              edoor_en_reg;           /* board interrupts enable */
+    u8              unused6[27];
+    u32             unused7[939];         
+    u32             severity;       
     char                evt_str[256];           /* event string */
-} PACKED gdt6m_i960_regs;
+} __attribute__((packed)) gdt6m_i960_regs;
 
 /* DPRAM PCI MPR controllers */
 typedef struct {
     gdt6m_i960_regs     i960r;                  /* 4KB i960 registers */
     union {
         gdt_dpr_if      ic;                     /* interface area */
-        unchar          if_area[0x3000-sizeof(gdt_pci_sram)];
+        u8          if_area[0x3000-sizeof(gdt_pci_sram)];
     } u;
     gdt_pci_sram        gdt6sr;                 /* SRAM structure */
-} PACKED gdt6m_dpram_str;
+} __attribute__((packed)) gdt6m_dpram_str;
 
 
 /* PCI resources */
 typedef struct {
     struct pci_dev      *pdev;
-    ulong               dpmem;                  /* DPRAM address */
-    ulong               io;                     /* IO address */
+    unsigned long               dpmem;                  /* DPRAM address */
+    unsigned long               io;                     /* IO address */
 } gdth_pci_str;
 
 
@@ -846,93 +846,93 @@ typedef struct {
 typedef struct {
     struct Scsi_Host    *shost;
     struct list_head    list;
-    ushort      	hanum;
-    ushort              oem_id;                 /* OEM */
-    ushort              type;                   /* controller class */
-    ulong32             stype;                  /* subtype (PCI: device ID) */
-    ushort              fw_vers;                /* firmware version */
-    ushort              cache_feat;             /* feat. cache serv. (s/g,..)*/
-    ushort              raw_feat;               /* feat. raw service (s/g,..)*/
-    ushort              screen_feat;            /* feat. raw service (s/g,..)*/
-    ushort              bmic;                   /* BMIC address (EISA) */
+    u16      	hanum;
+    u16              oem_id;                 /* OEM */
+    u16              type;                   /* controller class */
+    u32             stype;                  /* subtype (PCI: device ID) */
+    u16              fw_vers;                /* firmware version */
+    u16              cache_feat;             /* feat. cache serv. (s/g,..)*/
+    u16              raw_feat;               /* feat. raw service (s/g,..)*/
+    u16              screen_feat;            /* feat. raw service (s/g,..)*/
+    u16              bmic;                   /* BMIC address (EISA) */
     void __iomem        *brd;                   /* DPRAM address */
-    ulong32             brd_phys;               /* slot number/BIOS address */
+    u32             brd_phys;               /* slot number/BIOS address */
     gdt6c_plx_regs      *plx;                   /* PLX regs (new PCI contr.) */
     gdth_cmd_str        cmdext;
     gdth_cmd_str        *pccb;                  /* address command structure */
-    ulong32             ccb_phys;               /* phys. address */
+    u32             ccb_phys;               /* phys. address */
 #ifdef INT_COAL
     gdth_coal_status    *coal_stat;             /* buffer for coalescing int.*/
-    ulong64             coal_stat_phys;         /* phys. address */
+    u64             coal_stat_phys;         /* phys. address */
 #endif
     char                *pscratch;              /* scratch (DMA) buffer */
-    ulong64             scratch_phys;           /* phys. address */
-    unchar              scratch_busy;           /* in use? */
-    unchar              dma64_support;          /* 64-bit DMA supported? */
+    u64             scratch_phys;           /* phys. address */
+    u8              scratch_busy;           /* in use? */
+    u8              dma64_support;          /* 64-bit DMA supported? */
     gdth_msg_str        *pmsg;                  /* message buffer */
-    ulong64             msg_phys;               /* phys. address */
-    unchar              scan_mode;              /* current scan mode */
-    unchar              irq;                    /* IRQ */
-    unchar              drq;                    /* DRQ (ISA controllers) */
-    ushort              status;                 /* command status */
-    ushort              service;                /* service/firmware ver./.. */
-    ulong32             info;
-    ulong32             info2;                  /* additional info */
+    u64             msg_phys;               /* phys. address */
+    u8              scan_mode;              /* current scan mode */
+    u8              irq;                    /* IRQ */
+    u8              drq;                    /* DRQ (ISA controllers) */
+    u16              status;                 /* command status */
+    u16              service;                /* service/firmware ver./.. */
+    u32             info;
+    u32             info2;                  /* additional info */
     Scsi_Cmnd           *req_first;             /* top of request queue */
     struct {
-        unchar          present;                /* Flag: host drive present? */
-        unchar          is_logdrv;              /* Flag: log. drive (master)? */
-        unchar          is_arraydrv;            /* Flag: array drive? */
-        unchar          is_master;              /* Flag: array drive master? */
-        unchar          is_parity;              /* Flag: parity drive? */
-        unchar          is_hotfix;              /* Flag: hotfix drive? */
-        unchar          master_no;              /* number of master drive */
-        unchar          lock;                   /* drive locked? (hot plug) */
-        unchar          heads;                  /* mapping */
-        unchar          secs;
-        ushort          devtype;                /* further information */
-        ulong64         size;                   /* capacity */
-        unchar          ldr_no;                 /* log. drive no. */
-        unchar          rw_attribs;             /* r/w attributes */
-        unchar          cluster_type;           /* cluster properties */
-        unchar          media_changed;          /* Flag:MOUNT/UNMOUNT occured */
-        ulong32         start_sec;              /* start sector */
+        u8          present;                /* Flag: host drive present? */
+        u8          is_logdrv;              /* Flag: log. drive (master)? */
+        u8          is_arraydrv;            /* Flag: array drive? */
+        u8          is_master;              /* Flag: array drive master? */
+        u8          is_parity;              /* Flag: parity drive? */
+        u8          is_hotfix;              /* Flag: hotfix drive? */
+        u8          master_no;              /* number of master drive */
+        u8          lock;                   /* drive locked? (hot plug) */
+        u8          heads;                  /* mapping */
+        u8          secs;
+        u16          devtype;                /* further information */
+        u64         size;                   /* capacity */
+        u8          ldr_no;                 /* log. drive no. */
+        u8          rw_attribs;             /* r/w attributes */
+        u8          cluster_type;           /* cluster properties */
+        u8          media_changed;          /* Flag:MOUNT/UNMOUNT occured */
+        u32         start_sec;              /* start sector */
     } hdr[MAX_LDRIVES];                         /* host drives */
     struct {
-        unchar          lock;                   /* channel locked? (hot plug) */
-        unchar          pdev_cnt;               /* physical device count */
-        unchar          local_no;               /* local channel number */
-        unchar          io_cnt[MAXID];          /* current IO count */
-        ulong32         address;                /* channel address */
-        ulong32         id_list[MAXID];         /* IDs of the phys. devices */
+        u8          lock;                   /* channel locked? (hot plug) */
+        u8          pdev_cnt;               /* physical device count */
+        u8          local_no;               /* local channel number */
+        u8          io_cnt[MAXID];          /* current IO count */
+        u32         address;                /* channel address */
+        u32         id_list[MAXID];         /* IDs of the phys. devices */
     } raw[MAXBUS];                              /* SCSI channels */
     struct {
         Scsi_Cmnd       *cmnd;                  /* pending request */
-        ushort          service;                /* service */
+        u16          service;                /* service */
     } cmd_tab[GDTH_MAXCMDS];                    /* table of pend. requests */
     struct gdth_cmndinfo {                      /* per-command private info */
         int index;
         int internal_command;                   /* don't call scsi_done */
         gdth_cmd_str *internal_cmd_str;         /* crier for internal messages*/
         dma_addr_t sense_paddr;                 /* sense dma-addr */
-        unchar priority;
+        u8 priority;
 	int timeout_count;			/* # of timeout calls */
         volatile int wait_for_completion;
-        ushort status;
-        ulong32 info;
+        u16 status;
+        u32 info;
         enum dma_data_direction dma_dir;
         int phase;                              /* ???? */
         int OpCode;
     } cmndinfo[GDTH_MAXCMDS];                   /* index==0 is free */
-    unchar              bus_cnt;                /* SCSI bus count */
-    unchar              tid_cnt;                /* Target ID count */
-    unchar              bus_id[MAXBUS];         /* IOP IDs */
-    unchar              virt_bus;               /* number of virtual bus */
-    unchar              more_proc;              /* more /proc info supported */
-    ushort              cmd_cnt;                /* command count in DPRAM */
-    ushort              cmd_len;                /* length of actual command */
-    ushort              cmd_offs_dpmem;         /* actual offset in DPRAM */
-    ushort              ic_all_size;            /* sizeof DPRAM interf. area */
+    u8              bus_cnt;                /* SCSI bus count */
+    u8              tid_cnt;                /* Target ID count */
+    u8              bus_id[MAXBUS];         /* IOP IDs */
+    u8              virt_bus;               /* number of virtual bus */
+    u8              more_proc;              /* more /proc info supported */
+    u16              cmd_cnt;                /* command count in DPRAM */
+    u16              cmd_len;                /* length of actual command */
+    u16              cmd_offs_dpmem;         /* actual offset in DPRAM */
+    u16              ic_all_size;            /* sizeof DPRAM interf. area */
     gdth_cpar_str       cpar;                   /* controller cache par. */
     gdth_bfeat_str      bfeat;                  /* controller features */
     gdth_binfo_str      binfo;                  /* controller info */
@@ -941,7 +941,7 @@ typedef struct {
     struct pci_dev      *pdev;
     char                oem_name[8];
 #ifdef GDTH_DMA_STATISTICS
-    ulong               dma32_cnt, dma64_cnt;   /* statistics: DMA buffer */
+    unsigned long               dma32_cnt, dma64_cnt;   /* statistics: DMA buffer */
 #endif
     struct scsi_device         *sdev;
 } gdth_ha_str;
@@ -953,65 +953,65 @@ static inline struct gdth_cmndinfo *gdth
 
 /* INQUIRY data format */
 typedef struct {
-    unchar      type_qual;
-    unchar      modif_rmb;
-    unchar      version;
-    unchar      resp_aenc;
-    unchar      add_length;
-    unchar      reserved1;
-    unchar      reserved2;
-    unchar      misc;
-    unchar      vendor[8];
-    unchar      product[16];
-    unchar      revision[4];
-} PACKED gdth_inq_data;
+    u8      type_qual;
+    u8      modif_rmb;
+    u8      version;
+    u8      resp_aenc;
+    u8      add_length;
+    u8      reserved1;
+    u8      reserved2;
+    u8      misc;
+    u8      vendor[8];
+    u8      product[16];
+    u8      revision[4];
+} __attribute__((packed)) gdth_inq_data;
 
 /* READ_CAPACITY data format */
 typedef struct {
-    ulong32     last_block_no;
-    ulong32     block_length;
-} PACKED gdth_rdcap_data;
+    u32     last_block_no;
+    u32     block_length;
+} __attribute__((packed)) gdth_rdcap_data;
 
 /* READ_CAPACITY (16) data format */
 typedef struct {
-    ulong64     last_block_no;
-    ulong32     block_length;
-} PACKED gdth_rdcap16_data;
+    u64     last_block_no;
+    u32     block_length;
+} __attribute__((packed)) gdth_rdcap16_data;
 
 /* REQUEST_SENSE data format */
 typedef struct {
-    unchar      errorcode;
-    unchar      segno;
-    unchar      key;
-    ulong32     info;
-    unchar      add_length;
-    ulong32     cmd_info;
-    unchar      adsc;
-    unchar      adsq;
-    unchar      fruc;
-    unchar      key_spec[3];
-} PACKED gdth_sense_data;
+    u8      errorcode;
+    u8      segno;
+    u8      key;
+    u32     info;
+    u8      add_length;
+    u32     cmd_info;
+    u8      adsc;
+    u8      adsq;
+    u8      fruc;
+    u8      key_spec[3];
+} __attribute__((packed)) gdth_sense_data;
 
 /* MODE_SENSE data format */
 typedef struct {
     struct {
-        unchar  data_length;
-        unchar  med_type;
-        unchar  dev_par;
-        unchar  bd_length;
-    } PACKED hd;
+        u8  data_length;
+        u8  med_type;
+        u8  dev_par;
+        u8  bd_length;
+    } __attribute__((packed)) hd;
     struct {
-        unchar  dens_code;
-        unchar  block_count[3];
-        unchar  reserved;
-        unchar  block_length[3];
-    } PACKED bd;
-} PACKED gdth_modep_data;
+        u8  dens_code;
+        u8  block_count[3];
+        u8  reserved;
+        u8  block_length[3];
+    } __attribute__((packed)) bd;
+} __attribute__((packed)) gdth_modep_data;
 
 /* stack frame */
 typedef struct {
-    ulong       b[10];                          /* 32/64 bit compiler ! */
-} PACKED gdth_stackframe;
+    unsigned long       b[10];                          /* 32/64 bit compiler ! */
+} __attribute__((packed)) gdth_stackframe;
 
 
 /* function prototyping */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/gdth_ioctl.h linux-libre-2.6.34-gnu1/drivers/scsi/gdth_ioctl.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/gdth_ioctl.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/gdth_ioctl.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,109 +32,101 @@
 #define MAX_HDRIVES     MAX_LDRIVES             /* max. host drive count */
 #endif
 
-/* typedefs */
-#ifdef __KERNEL__
-typedef u32     ulong32;
-typedef u64     ulong64;
-#endif
-
-#define PACKED  __attribute__((packed))
-
 /* scatter/gather element */
 typedef struct {
-    ulong32     sg_ptr;                         /* address */
-    ulong32     sg_len;                         /* length */
-} PACKED gdth_sg_str;
+    u32     sg_ptr;                         /* address */
+    u32     sg_len;                         /* length */
+} __attribute__((packed)) gdth_sg_str;
 
 /* scatter/gather element - 64bit addresses */
 typedef struct {
-    ulong64     sg_ptr;                         /* address */
-    ulong32     sg_len;                         /* length */
-} PACKED gdth_sg64_str;
+    u64     sg_ptr;                         /* address */
+    u32     sg_len;                         /* length */
+} __attribute__((packed)) gdth_sg64_str;
 
 /* command structure */
 typedef struct {
-    ulong32     BoardNode;                      /* board node (always 0) */
-    ulong32     CommandIndex;                   /* command number */
-    ushort      OpCode;                         /* the command (READ,..) */
+    u32     BoardNode;                      /* board node (always 0) */
+    u32     CommandIndex;                   /* command number */
+    u16      OpCode;                         /* the command (READ,..) */
     union {
         struct {
-            ushort      DeviceNo;               /* number of cache drive */
-            ulong32     BlockNo;                /* block number */
-            ulong32     BlockCnt;               /* block count */
-            ulong32     DestAddr;               /* dest. addr. (if s/g: -1) */
-            ulong32     sg_canz;                /* s/g element count */
+            u16      DeviceNo;               /* number of cache drive */
+            u32     BlockNo;                /* block number */
+            u32     BlockCnt;               /* block count */
+            u32     DestAddr;               /* dest. addr. (if s/g: -1) */
+            u32     sg_canz;                /* s/g element count */
             gdth_sg_str sg_lst[GDTH_MAXSG];     /* s/g list */
-        } PACKED cache;                         /* cache service cmd. str. */
+        } __attribute__((packed)) cache;                         /* cache service cmd. str. */
         struct {
-            ushort      DeviceNo;               /* number of cache drive */
-            ulong64     BlockNo;                /* block number */
-            ulong32     BlockCnt;               /* block count */
-            ulong64     DestAddr;               /* dest. addr. (if s/g: -1) */
-            ulong32     sg_canz;                /* s/g element count */
+            u16      DeviceNo;               /* number of cache drive */
+            u64     BlockNo;                /* block number */
+            u32     BlockCnt;               /* block count */
+            u64     DestAddr;               /* dest. addr. (if s/g: -1) */
+            u32     sg_canz;                /* s/g element count */
             gdth_sg64_str sg_lst[GDTH_MAXSG];   /* s/g list */
-        } PACKED cache64;                       /* cache service cmd. str. */
+        } __attribute__((packed)) cache64;                       /* cache service cmd. str. */
         struct {
-            ushort      param_size;             /* size of p_param buffer */
-            ulong32     subfunc;                /* IOCTL function */
-            ulong32     channel;                /* device */
-            ulong64     p_param;                /* buffer */
-        } PACKED ioctl;                         /* IOCTL command structure */
+            u16      param_size;             /* size of p_param buffer */
+            u32     subfunc;                /* IOCTL function */
+            u32     channel;                /* device */
+            u64     p_param;                /* buffer */
+        } __attribute__((packed)) ioctl;                         /* IOCTL command structure */
         struct {
-            ushort      reserved;
+            u16      reserved;
             union {
                 struct {
-                    ulong32  msg_handle;        /* message handle */
-                    ulong64  msg_addr;          /* message buffer address */
-                } PACKED msg;
-                unchar       data[12];          /* buffer for rtc data, ... */
+                    u32  msg_handle;        /* message handle */
+                    u64  msg_addr;          /* message buffer address */
+                } __attribute__((packed)) msg;
+                u8       data[12];          /* buffer for rtc data, ... */
             } su;
-        } PACKED screen;                        /* screen service cmd. str. */
+        } __attribute__((packed)) screen;                        /* screen service cmd. str. */
         struct {
-            ushort      reserved;
-            ulong32     direction;              /* data direction */
-            ulong32     mdisc_time;             /* disc. time (0: no timeout)*/
-            ulong32     mcon_time;              /* connect time(0: no to.) */
-            ulong32     sdata;                  /* dest. addr. (if s/g: -1) */
-            ulong32     sdlen;                  /* data length (bytes) */
-            ulong32     clen;                   /* SCSI cmd. length(6,10,12) */
-            unchar      cmd[12];                /* SCSI command */
-            unchar      target;                 /* target ID */
-            unchar      lun;                    /* LUN */
-            unchar      bus;                    /* SCSI bus number */
-            unchar      priority;               /* only 0 used */
-            ulong32     sense_len;              /* sense data length */
-            ulong32     sense_data;             /* sense data addr. */
-            ulong32     link_p;                 /* linked cmds (not supp.) */
-            ulong32     sg_ranz;                /* s/g element count */
+            u16      reserved;
+            u32     direction;              /* data direction */
+            u32     mdisc_time;             /* disc. time (0: no timeout)*/
+            u32     mcon_time;              /* connect time(0: no to.) */
+            u32     sdata;                  /* dest. addr. (if s/g: -1) */
+            u32     sdlen;                  /* data length (bytes) */
+            u32     clen;                   /* SCSI cmd. length(6,10,12) */
+            u8      cmd[12];                /* SCSI command */
+            u8      target;                 /* target ID */
+            u8      lun;                    /* LUN */
+            u8      bus;                    /* SCSI bus number */
+            u8      priority;               /* only 0 used */
+            u32     sense_len;              /* sense data length */
+            u32     sense_data;             /* sense data addr. */
+            u32     link_p;                 /* linked cmds (not supp.) */
+            u32     sg_ranz;                /* s/g element count */
             gdth_sg_str sg_lst[GDTH_MAXSG];     /* s/g list */
-        } PACKED raw;                           /* raw service cmd. struct. */
+        } __attribute__((packed)) raw;                           /* raw service cmd. struct. */
         struct {
-            ushort      reserved;
-            ulong32     direction;              /* data direction */
-            ulong32     mdisc_time;             /* disc. time (0: no timeout)*/
-            ulong32     mcon_time;              /* connect time(0: no to.) */
-            ulong64     sdata;                  /* dest. addr. (if s/g: -1) */
-            ulong32     sdlen;                  /* data length (bytes) */
-            ulong32     clen;                   /* SCSI cmd. length(6,..,16) */
-            unchar      cmd[16];                /* SCSI command */
-            unchar      target;                 /* target ID */
-            unchar      lun;                    /* LUN */
-            unchar      bus;                    /* SCSI bus number */
-            unchar      priority;               /* only 0 used */
-            ulong32     sense_len;              /* sense data length */
-            ulong64     sense_data;             /* sense data addr. */
-            ulong32     sg_ranz;                /* s/g element count */
+            u16      reserved;
+            u32     direction;              /* data direction */
+            u32     mdisc_time;             /* disc. time (0: no timeout)*/
+            u32     mcon_time;              /* connect time(0: no to.) */
+            u64     sdata;                  /* dest. addr. (if s/g: -1) */
+            u32     sdlen;                  /* data length (bytes) */
+            u32     clen;                   /* SCSI cmd. length(6,..,16) */
+            u8      cmd[16];                /* SCSI command */
+            u8      target;                 /* target ID */
+            u8      lun;                    /* LUN */
+            u8      bus;                    /* SCSI bus number */
+            u8      priority;               /* only 0 used */
+            u32     sense_len;              /* sense data length */
+            u64     sense_data;             /* sense data addr. */
+            u32     sg_ranz;                /* s/g element count */
             gdth_sg64_str sg_lst[GDTH_MAXSG];   /* s/g list */
-        } PACKED raw64;                         /* raw service cmd. struct. */
+        } __attribute__((packed)) raw64;                         /* raw service cmd. struct. */
     } u;
     /* additional variables */
-    unchar      Service;                        /* controller service */
-    unchar      reserved;
-    ushort      Status;                         /* command result */
-    ulong32     Info;                           /* additional information */
+    u8      Service;                        /* controller service */
+    u8      reserved;
+    u16      Status;                         /* command result */
+    u32     Info;                           /* additional information */
     void        *RequestBuffer;                 /* request buffer */
-} PACKED gdth_cmd_str;
+} __attribute__((packed)) gdth_cmd_str;
 
 /* controller event structure */
 #define ES_ASYNC    1
@@ -142,129 +134,129 @@ typedef struct {
 #define ES_TEST     3
 #define ES_SYNC     4
 typedef struct {
-    ushort                  size;               /* size of structure */
+    u16                  size;               /* size of structure */
     union {
         char                stream[16];
         struct {
-            ushort          ionode;
-            ushort          service;
-            ulong32         index;
-        } PACKED driver;
+            u16          ionode;
+            u16          service;
+            u32         index;
+        } __attribute__((packed)) driver;
         struct {
-            ushort          ionode;
-            ushort          service;
-            ushort          status;
-            ulong32         info;
-            unchar          scsi_coord[3];
-        } PACKED async;
+            u16          ionode;
+            u16          service;
+            u16          status;
+            u32         info;
+            u8          scsi_coord[3];
+        } __attribute__((packed)) async;
         struct {
-            ushort          ionode;
-            ushort          service;
-            ushort          status;
-            ulong32         info;
-            ushort          hostdrive;
-            unchar          scsi_coord[3];
-            unchar          sense_key;
-        } PACKED sync;
+            u16          ionode;
+            u16          service;
+            u16          status;
+            u32         info;
+            u16          hostdrive;
+            u8          scsi_coord[3];
+            u8          sense_key;
+        } __attribute__((packed)) sync;
         struct {
-            ulong32         l1, l2, l3, l4;
-        } PACKED test;
+            u32         l1, l2, l3, l4;
+        } __attribute__((packed)) test;
     } eu;
-    ulong32                 severity;
-    unchar                  event_string[256];          
-} PACKED gdth_evt_data;
+    u32                 severity;
+    u8                  event_string[256];          
+} __attribute__((packed)) gdth_evt_data;
 
 typedef struct {
-    ulong32         first_stamp;
-    ulong32         last_stamp;
-    ushort          same_count;
-    ushort          event_source;
-    ushort          event_idx;
-    unchar          application;
-    unchar          reserved;
+    u32         first_stamp;
+    u32         last_stamp;
+    u16          same_count;
+    u16          event_source;
+    u16          event_idx;
+    u8          application;
+    u8          reserved;
     gdth_evt_data   event_data;
-} PACKED gdth_evt_str;
+} __attribute__((packed)) gdth_evt_str;
 
 
 #ifdef GDTH_IOCTL_PROC
 /* IOCTL structure (write) */
 typedef struct {
-    ulong32                 magic;              /* IOCTL magic */
-    ushort                  ioctl;              /* IOCTL */
-    ushort                  ionode;             /* controller number */
-    ushort                  service;            /* controller service */
-    ushort                  timeout;            /* timeout */
+    u32                 magic;              /* IOCTL magic */
+    u16                  ioctl;              /* IOCTL */
+    u16                  ionode;             /* controller number */
+    u16                  service;            /* controller service */
+    u16                  timeout;            /* timeout */
     union {
         struct {
-            unchar          command[512];       /* controller command */
-            unchar          data[1];            /* add. data */
+            u8          command[512];       /* controller command */
+            u8          data[1];            /* add. data */
         } general;
         struct {
-            unchar          lock;               /* lock/unlock */
-            unchar          drive_cnt;          /* drive count */
-            ushort          drives[MAX_HDRIVES];/* drives */
+            u8          lock;               /* lock/unlock */
+            u8          drive_cnt;          /* drive count */
+            u16          drives[MAX_HDRIVES];/* drives */
         } lockdrv;
         struct {
-            unchar          lock;               /* lock/unlock */
-            unchar          channel;            /* channel */
+            u8          lock;               /* lock/unlock */
+            u8          channel;            /* channel */
         } lockchn;
         struct {
             int             erase;              /* erase event ? */
             int             handle;
-            unchar          evt[EVENT_SIZE];    /* event structure */
+            u8          evt[EVENT_SIZE];    /* event structure */
         } event;
         struct {
-            unchar          bus;                /* SCSI bus */
-            unchar          target;             /* target ID */
-            unchar          lun;                /* LUN */
-            unchar          cmd_len;            /* command length */
-            unchar          cmd[12];            /* SCSI command */
+            u8          bus;                /* SCSI bus */
+            u8          target;             /* target ID */
+            u8          lun;                /* LUN */
+            u8          cmd_len;            /* command length */
+            u8          cmd[12];            /* SCSI command */
         } scsi;
         struct {
-            ushort          hdr_no;             /* host drive number */
-            unchar          flag;               /* old meth./add/remove */
+            u16          hdr_no;             /* host drive number */
+            u8          flag;               /* old meth./add/remove */
         } rescan;
     } iu;
 } gdth_iowr_str;
 
 /* IOCTL structure (read) */
 typedef struct {
-    ulong32                 size;               /* buffer size */
-    ulong32                 status;             /* IOCTL error code */
+    u32                 size;               /* buffer size */
+    u32                 status;             /* IOCTL error code */
     union {
         struct {
-            unchar          data[1];            /* data */
+            u8          data[1];            /* data */
         } general;
         struct {
-            ushort          version;            /* driver version */
+            u16          version;            /* driver version */
         } drvers;
         struct {
-            unchar          type;               /* controller type */
-            ushort          info;               /* slot etc. */
-            ushort          oem_id;             /* OEM ID */
-            ushort          bios_ver;           /* not used */
-            ushort          access;             /* not used */
-            ushort          ext_type;           /* extended type */
-            ushort          device_id;          /* device ID */
-            ushort          sub_device_id;      /* sub device ID */
+            u8          type;               /* controller type */
+            u16          info;               /* slot etc. */
+            u16          oem_id;             /* OEM ID */
+            u16          bios_ver;           /* not used */
+            u16          access;             /* not used */
+            u16          ext_type;           /* extended type */
+            u16          device_id;          /* device ID */
+            u16          sub_device_id;      /* sub device ID */
         } ctrtype;
         struct {
-            unchar          version;            /* OS version */
-            unchar          subversion;         /* OS subversion */
-            ushort          revision;           /* revision */
+            u8          version;            /* OS version */
+            u8          subversion;         /* OS subversion */
+            u16          revision;           /* revision */
         } osvers;
         struct {
-            ushort          count;              /* controller count */
+            u16          count;              /* controller count */
         } ctrcnt;
         struct {
             int             handle;
-            unchar          evt[EVENT_SIZE];    /* event structure */
+            u8          evt[EVENT_SIZE];    /* event structure */
         } event;
         struct {
-            unchar          bus;                /* SCSI bus, 0xff: invalid */
-            unchar          target;             /* target ID */
-            unchar          lun;                /* LUN */
-            unchar          cluster_type;       /* cluster properties */
+            u8          bus;                /* SCSI bus, 0xff: invalid */
+            u8          target;             /* target ID */
+            u8          lun;                /* LUN */
+            u8          cluster_type;       /* cluster properties */
         } hdr_list[MAX_HDRIVES];                /* index is host drive number */
     } iu;
 } gdth_iord_str;
@@ -272,53 +264,53 @@ typedef struct {
 
 /* GDTIOCTL_GENERAL */
 typedef struct {
-    ushort ionode;                              /* controller number */
-    ushort timeout;                             /* timeout */
-    ulong32 info;                               /* error info */ 
-    ushort status;                              /* status */
-    ulong data_len;                             /* data buffer size */
-    ulong sense_len;                            /* sense buffer size */
+    u16 ionode;                              /* controller number */
+    u16 timeout;                             /* timeout */
+    u32 info;                               /* error info */ 
+    u16 status;                              /* status */
+    unsigned long data_len;                             /* data buffer size */
+    unsigned long sense_len;                            /* sense buffer size */
     gdth_cmd_str command;                       /* command */                   
 } gdth_ioctl_general;
 
 /* GDTIOCTL_LOCKDRV */
 typedef struct {
-    ushort ionode;                              /* controller number */
-    unchar lock;                                /* lock/unlock */
-    unchar drive_cnt;                           /* drive count */
-    ushort drives[MAX_HDRIVES];                 /* drives */
+    u16 ionode;                              /* controller number */
+    u8 lock;                                /* lock/unlock */
+    u8 drive_cnt;                           /* drive count */
+    u16 drives[MAX_HDRIVES];                 /* drives */
 } gdth_ioctl_lockdrv;
 
 /* GDTIOCTL_LOCKCHN */
 typedef struct {
-    ushort ionode;                              /* controller number */
-    unchar lock;                                /* lock/unlock */
-    unchar channel;                             /* channel */
+    u16 ionode;                              /* controller number */
+    u8 lock;                                /* lock/unlock */
+    u8 channel;                             /* channel */
 } gdth_ioctl_lockchn;
 
 /* GDTIOCTL_OSVERS */
 typedef struct {
-    unchar version;                             /* OS version */
-    unchar subversion;                          /* OS subversion */
-    ushort revision;                            /* revision */
+    u8 version;                             /* OS version */
+    u8 subversion;                          /* OS subversion */
+    u16 revision;                            /* revision */
 } gdth_ioctl_osvers;
 
 /* GDTIOCTL_CTRTYPE */
 typedef struct {
-    ushort ionode;                              /* controller number */
-    unchar type;                                /* controller type */
-    ushort info;                                /* slot etc. */
-    ushort oem_id;                              /* OEM ID */
-    ushort bios_ver;                            /* not used */
-    ushort access;                              /* not used */
-    ushort ext_type;                            /* extended type */
-    ushort device_id;                           /* device ID */
-    ushort sub_device_id;                       /* sub device ID */
+    u16 ionode;                              /* controller number */
+    u8 type;                                /* controller type */
+    u16 info;                                /* slot etc. */
+    u16 oem_id;                              /* OEM ID */
+    u16 bios_ver;                            /* not used */
+    u16 access;                              /* not used */
+    u16 ext_type;                            /* extended type */
+    u16 device_id;                           /* device ID */
+    u16 sub_device_id;                       /* sub device ID */
 } gdth_ioctl_ctrtype;
 
 /* GDTIOCTL_EVENT */
 typedef struct {
-    ushort ionode;
+    u16 ionode;
     int erase;                                  /* erase event? */
     int handle;                                 /* event handle */
     gdth_evt_str event;
@@ -326,22 +318,22 @@ typedef struct {
 
 /* GDTIOCTL_RESCAN/GDTIOCTL_HDRLIST */
 typedef struct {
-    ushort ionode;                              /* controller number */
-    unchar flag;                                /* add/remove */
-    ushort hdr_no;                              /* drive no. */
+    u16 ionode;                              /* controller number */
+    u8 flag;                                /* add/remove */
+    u16 hdr_no;                              /* drive no. */
     struct {
-        unchar bus;                             /* SCSI bus */
-        unchar target;                          /* target ID */
-        unchar lun;                             /* LUN */
-        unchar cluster_type;                    /* cluster properties */
+        u8 bus;                             /* SCSI bus */
+        u8 target;                          /* target ID */
+        u8 lun;                             /* LUN */
+        u8 cluster_type;                    /* cluster properties */
     } hdr_list[MAX_HDRIVES];                    /* index is host drive number */
 } gdth_ioctl_rescan;
 
 /* GDTIOCTL_RESET_BUS/GDTIOCTL_RESET_DRV */
 typedef struct {
-    ushort ionode;                              /* controller number */
-    ushort number;                              /* bus/host drive number */
-    ushort status;                              /* status */
+    u16 ionode;                              /* controller number */
+    u16 number;                              /* bus/host drive number */
+    u16 status;                              /* status */
 } gdth_ioctl_reset;
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/gdth_proc.c linux-libre-2.6.34-gnu1/drivers/scsi/gdth_proc.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/gdth_proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/gdth_proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
  */
 
 #include <linux/completion.h>
+#include <linux/slab.h>
 
 int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length,   
                    int inout)
@@ -43,7 +44,7 @@ static int gdth_set_asc_info(struct Scsi
     int i, found;
     gdth_cmd_str    gdtcmd;
     gdth_cpar_str   *pcpar;
-    ulong64         paddr;
+    u64         paddr;
 
     char            cmnd[MAX_COMMAND_SIZE];
     memset(cmnd, 0xff, 12);
@@ -156,8 +157,8 @@ static int gdth_get_info(char *buffer,ch
     off_t begin = 0,pos = 0;
     int id, i, j, k, sec, flag;
     int no_mdrv = 0, drv_no, is_mirr;
-    ulong32 cnt;
-    ulong64 paddr;
+    u32 cnt;
+    u64 paddr;
     int rc = -ENOMEM;
 
     gdth_cmd_str *gdtcmd;
@@ -220,14 +221,14 @@ static int gdth_get_info(char *buffer,ch
 
     if (ha->more_proc)
         sprintf(hrec, "%d.%02d.%02d-%c%03X", 
-                (unchar)(ha->binfo.upd_fw_ver>>24),
-                (unchar)(ha->binfo.upd_fw_ver>>16),
-                (unchar)(ha->binfo.upd_fw_ver),
+                (u8)(ha->binfo.upd_fw_ver>>24),
+                (u8)(ha->binfo.upd_fw_ver>>16),
+                (u8)(ha->binfo.upd_fw_ver),
                 ha->bfeat.raid ? 'R':'N',
                 ha->binfo.upd_revision);
     else
-        sprintf(hrec, "%d.%02d", (unchar)(ha->cpar.version>>8),
-                (unchar)(ha->cpar.version));
+        sprintf(hrec, "%d.%02d", (u8)(ha->cpar.version>>8),
+                (u8)(ha->cpar.version));
 
     size = sprintf(buffer+len,
                    " Driver Ver.:  \t%-10s\tFirmware Ver.: \t%s\n",
@@ -281,7 +282,7 @@ static int gdth_get_info(char *buffer,ch
             pds->bid = ha->raw[i].local_no;
             pds->first = 0;
             pds->entries = ha->raw[i].pdev_cnt;
-            cnt = (3*GDTH_SCRATCH/4 - 5 * sizeof(ulong32)) /
+            cnt = (3*GDTH_SCRATCH/4 - 5 * sizeof(u32)) /
                 sizeof(pds->list[0]);
             if (pds->entries > cnt)
                 pds->entries = cnt;
@@ -604,7 +605,7 @@ static int gdth_get_info(char *buffer,ch
 
             size = sprintf(buffer+len,
                            " Capacity [MB]:\t%-6d    \tStart Sector:  \t%d\n",
-                           (ulong32)(ha->hdr[i].size/2048), ha->hdr[i].start_sec);
+                           (u32)(ha->hdr[i].size/2048), ha->hdr[i].start_sec);
             len += size;  pos = begin + len;
             if (pos < offset) {
                 len = 0;
@@ -664,9 +665,9 @@ free_fail:
 }
 
 static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch,
-                              ulong64 *paddr)
+                              u64 *paddr)
 {
-    ulong flags;
+    unsigned long flags;
     char *ret_val;
 
     if (size == 0)
@@ -691,9 +692,9 @@ static char *gdth_ioctl_alloc(gdth_ha_st
     return ret_val;
 }
 
-static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, ulong64 paddr)
+static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, u64 paddr)
 {
-    ulong flags;
+    unsigned long flags;
 
     if (buf == ha->pscratch) {
 	spin_lock_irqsave(&ha->smp_lock, flags);
@@ -705,16 +706,16 @@ static void gdth_ioctl_free(gdth_ha_str
 }
 
 #ifdef GDTH_IOCTL_PROC
-static int gdth_ioctl_check_bin(gdth_ha_str *ha, ushort size)
+static int gdth_ioctl_check_bin(gdth_ha_str *ha, u16 size)
 {
-    ulong flags;
+    unsigned long flags;
     int ret_val;
 
     spin_lock_irqsave(&ha->smp_lock, flags);
 
     ret_val = FALSE;
     if (ha->scratch_busy) {
-        if (((gdth_iord_str *)ha->pscratch)->size == (ulong32)size)
+        if (((gdth_iord_str *)ha->pscratch)->size == (u32)size)
             ret_val = TRUE;
     }
     spin_unlock_irqrestore(&ha->smp_lock, flags);
@@ -724,11 +725,11 @@ static int gdth_ioctl_check_bin(gdth_ha_
 
 static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id)
 {
-    ulong flags;
+    unsigned long flags;
     int i;
     Scsi_Cmnd *scp;
     struct gdth_cmndinfo *cmndinfo;
-    unchar b, t;
+    u8 b, t;
 
     spin_lock_irqsave(&ha->smp_lock, flags);
 
@@ -738,8 +739,8 @@ static void gdth_wait_completion(gdth_ha
 
         b = scp->device->channel;
         t = scp->device->id;
-        if (!SPECIAL_SCP(scp) && t == (unchar)id && 
-            b == (unchar)busnum) {
+        if (!SPECIAL_SCP(scp) && t == (u8)id && 
+            b == (u8)busnum) {
             cmndinfo->wait_for_completion = 0;
             spin_unlock_irqrestore(&ha->smp_lock, flags);
             while (!cmndinfo->wait_for_completion)
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/gdth_proc.h linux-libre-2.6.34-gnu1/drivers/scsi/gdth_proc.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/gdth_proc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/gdth_proc.h	2010-05-16 17:17:36.000000000 -0400
@@ -17,8 +17,8 @@ static int gdth_set_asc_info(struct Scsi
                              int length, gdth_ha_str *ha);
 
 static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch,
-                              ulong64 *paddr);
-static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, ulong64 paddr);
+                              u64 *paddr);
+static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, u64 paddr);
 static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id);
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/gvp11.c linux-libre-2.6.34-gnu1/drivers/scsi/gvp11.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/gvp11.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/gvp11.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,6 @@
 #include <linux/types.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/hosts.c linux-libre-2.6.34-gnu1/drivers/scsi/hosts.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/hosts.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/hosts.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/blkdev.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/kthread.h>
 #include <linux/string.h>
 #include <linux/mm.h>
@@ -215,6 +216,8 @@ int scsi_add_host_with_dma(struct Scsi_H
 		shost->shost_gendev.parent = dev ? dev : &platform_bus;
 	shost->dma_dev = dma_dev;
 
+	device_enable_async_suspend(&shost->shost_gendev);
+
 	error = device_add(&shost->shost_gendev);
 	if (error)
 		goto out;
@@ -222,6 +225,8 @@ int scsi_add_host_with_dma(struct Scsi_H
 	scsi_host_set_state(shost, SHOST_RUNNING);
 	get_device(shost->shost_gendev.parent);
 
+	device_enable_async_suspend(&shost->shost_dev);
+
 	error = device_add(&shost->shost_dev);
 	if (error)
 		goto out_del_gendev;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/hpsa.c linux-libre-2.6.34-gnu1/drivers/scsi/hpsa.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/hpsa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/hpsa.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,7 @@
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
 #include <linux/cciss_ioctl.h>
 #include <linux/string.h>
 #include <linux/bitmap.h>
@@ -52,7 +53,7 @@
 #include "hpsa.h"
 
 /* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */
-#define HPSA_DRIVER_VERSION "1.0.0"
+#define HPSA_DRIVER_VERSION "2.0.2-1"
 #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
 
 /* How long to wait (in milliseconds) for board to go into simple mode */
@@ -77,9 +78,6 @@ MODULE_PARM_DESC(hpsa_allow_any,
 
 /* define the PCI info for the cards we can control */
 static const struct pci_device_id hpsa_pci_device_id[] = {
-	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSC,     0x103C, 0x3223},
-	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSC,     0x103C, 0x3234},
-	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSC,     0x103C, 0x323D},
 	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3241},
 	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3243},
 	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3245},
@@ -87,6 +85,9 @@ static const struct pci_device_id hpsa_p
 	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3249},
 	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x324a},
 	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x324b},
+	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3233},
+#define PCI_DEVICE_ID_HP_CISSF 0x333f
+	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x333F},
 	{PCI_VENDOR_ID_HP,     PCI_ANY_ID,             PCI_ANY_ID, PCI_ANY_ID,
 		PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
 	{0,}
@@ -99,9 +100,6 @@ MODULE_DEVICE_TABLE(pci, hpsa_pci_device
  *  access = Address of the struct of function pointers
  */
 static struct board_type products[] = {
-	{0x3223103C, "Smart Array P800", &SA5_access},
-	{0x3234103C, "Smart Array P400", &SA5_access},
-	{0x323d103c, "Smart Array P700M", &SA5_access},
 	{0x3241103C, "Smart Array P212", &SA5_access},
 	{0x3243103C, "Smart Array P410", &SA5_access},
 	{0x3245103C, "Smart Array P410i", &SA5_access},
@@ -109,6 +107,8 @@ static struct board_type products[] = {
 	{0x3249103C, "Smart Array P812", &SA5_access},
 	{0x324a103C, "Smart Array P712m", &SA5_access},
 	{0x324b103C, "Smart Array P711m", &SA5_access},
+	{0x3233103C, "StorageWorks P1210m", &SA5_access},
+	{0x333F103C, "StorageWorks P1210m", &SA5_access},
 	{0xFFFF103C, "Unknown Smart Array", &SA5_access},
 };
 
@@ -126,12 +126,17 @@ static void cmd_free(struct ctlr_info *h
 static void cmd_special_free(struct ctlr_info *h, struct CommandList *c);
 static struct CommandList *cmd_alloc(struct ctlr_info *h);
 static struct CommandList *cmd_special_alloc(struct ctlr_info *h);
-static void fill_cmd(struct CommandList *c, __u8 cmd, struct ctlr_info *h,
-	void *buff, size_t size, __u8 page_code, unsigned char *scsi3addr,
+static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
+	void *buff, size_t size, u8 page_code, unsigned char *scsi3addr,
 	int cmd_type);
 
 static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
 		void (*done)(struct scsi_cmnd *));
+static void hpsa_scan_start(struct Scsi_Host *);
+static int hpsa_scan_finished(struct Scsi_Host *sh,
+	unsigned long elapsed_time);
+static int hpsa_change_queue_depth(struct scsi_device *sdev,
+	int qdepth, int reason);
 
 static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd);
 static int hpsa_slave_alloc(struct scsi_device *sdev);
@@ -150,6 +155,11 @@ static int check_for_unit_attention(stru
 	struct CommandList *c);
 static void check_ioctl_unit_attention(struct ctlr_info *h,
 	struct CommandList *c);
+/* performant mode helper functions */
+static void calc_bucket_map(int *bucket, int num_buckets,
+	int nsgs, int *bucket_map);
+static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h);
+static inline u32 next_command(struct ctlr_info *h);
 
 static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL);
 static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL);
@@ -173,10 +183,10 @@ static struct scsi_host_template hpsa_dr
 	.name			= "hpsa",
 	.proc_name		= "hpsa",
 	.queuecommand		= hpsa_scsi_queue_command,
-	.can_queue		= 512,
+	.scan_start		= hpsa_scan_start,
+	.scan_finished		= hpsa_scan_finished,
+	.change_queue_depth	= hpsa_change_queue_depth,
 	.this_id		= -1,
-	.sg_tablesize		= MAXSGENTRIES,
-	.cmd_per_lun		= 512,
 	.use_clustering		= ENABLE_CLUSTERING,
 	.eh_device_reset_handler = hpsa_eh_device_reset_handler,
 	.ioctl			= hpsa_ioctl,
@@ -195,131 +205,10 @@ static inline struct ctlr_info *sdev_to_
 	return (struct ctlr_info *) *priv;
 }
 
-static struct task_struct *hpsa_scan_thread;
-static DEFINE_MUTEX(hpsa_scan_mutex);
-static LIST_HEAD(hpsa_scan_q);
-static int hpsa_scan_func(void *data);
-
-/**
- * add_to_scan_list() - add controller to rescan queue
- * @h:		      Pointer to the controller.
- *
- * Adds the controller to the rescan queue if not already on the queue.
- *
- * returns 1 if added to the queue, 0 if skipped (could be on the
- * queue already, or the controller could be initializing or shutting
- * down).
- **/
-static int add_to_scan_list(struct ctlr_info *h)
-{
-	struct ctlr_info *test_h;
-	int found = 0;
-	int ret = 0;
-
-	if (h->busy_initializing)
-		return 0;
-
-	/*
-	 * If we don't get the lock, it means the driver is unloading
-	 * and there's no point in scheduling a new scan.
-	 */
-	if (!mutex_trylock(&h->busy_shutting_down))
-		return 0;
-
-	mutex_lock(&hpsa_scan_mutex);
-	list_for_each_entry(test_h, &hpsa_scan_q, scan_list) {
-		if (test_h == h) {
-			found = 1;
-			break;
-		}
-	}
-	if (!found && !h->busy_scanning) {
-		INIT_COMPLETION(h->scan_wait);
-		list_add_tail(&h->scan_list, &hpsa_scan_q);
-		ret = 1;
-	}
-	mutex_unlock(&hpsa_scan_mutex);
-	mutex_unlock(&h->busy_shutting_down);
-
-	return ret;
-}
-
-/**
- * remove_from_scan_list() - remove controller from rescan queue
- * @h:			   Pointer to the controller.
- *
- * Removes the controller from the rescan queue if present. Blocks if
- * the controller is currently conducting a rescan.  The controller
- * can be in one of three states:
- * 1. Doesn't need a scan
- * 2. On the scan list, but not scanning yet (we remove it)
- * 3. Busy scanning (and not on the list). In this case we want to wait for
- *    the scan to complete to make sure the scanning thread for this
- *    controller is completely idle.
- **/
-static void remove_from_scan_list(struct ctlr_info *h)
-{
-	struct ctlr_info *test_h, *tmp_h;
-
-	mutex_lock(&hpsa_scan_mutex);
-	list_for_each_entry_safe(test_h, tmp_h, &hpsa_scan_q, scan_list) {
-		if (test_h == h) { /* state 2. */
-			list_del(&h->scan_list);
-			complete_all(&h->scan_wait);
-			mutex_unlock(&hpsa_scan_mutex);
-			return;
-		}
-	}
-	if (h->busy_scanning) { /* state 3. */
-		mutex_unlock(&hpsa_scan_mutex);
-		wait_for_completion(&h->scan_wait);
-	} else { /* state 1, nothing to do. */
-		mutex_unlock(&hpsa_scan_mutex);
-	}
-}
-
-/* hpsa_scan_func() - kernel thread used to rescan controllers
- * @data:	 Ignored.
- *
- * A kernel thread used scan for drive topology changes on
- * controllers. The thread processes only one controller at a time
- * using a queue.  Controllers are added to the queue using
- * add_to_scan_list() and removed from the queue either after done
- * processing or using remove_from_scan_list().
- *
- * returns 0.
- **/
-static int hpsa_scan_func(__attribute__((unused)) void *data)
+static inline struct ctlr_info *shost_to_hba(struct Scsi_Host *sh)
 {
-	struct ctlr_info *h;
-	int host_no;
-
-	while (1) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule();
-		if (kthread_should_stop())
-			break;
-
-		while (1) {
-			mutex_lock(&hpsa_scan_mutex);
-			if (list_empty(&hpsa_scan_q)) {
-				mutex_unlock(&hpsa_scan_mutex);
-				break;
-			}
-			h = list_entry(hpsa_scan_q.next, struct ctlr_info,
-					scan_list);
-			list_del(&h->scan_list);
-			h->busy_scanning = 1;
-			mutex_unlock(&hpsa_scan_mutex);
-			host_no = h->scsi_host ?  h->scsi_host->host_no : -1;
-			hpsa_update_scsi_devices(h, host_no);
-			complete_all(&h->scan_wait);
-			mutex_lock(&hpsa_scan_mutex);
-			h->busy_scanning = 0;
-			mutex_unlock(&hpsa_scan_mutex);
-		}
-	}
-	return 0;
+	unsigned long *priv = shost_priv(sh);
+	return (struct ctlr_info *) *priv;
 }
 
 static int check_for_unit_attention(struct ctlr_info *h,
@@ -339,21 +228,8 @@ static int check_for_unit_attention(stru
 		break;
 	case REPORT_LUNS_CHANGED:
 		dev_warn(&h->pdev->dev, "hpsa%d: report LUN data "
-			"changed\n", h->ctlr);
+			"changed, action required\n", h->ctlr);
 	/*
-	 * Here, we could call add_to_scan_list and wake up the scan thread,
-	 * except that it's quite likely that we will get more than one
-	 * REPORT_LUNS_CHANGED condition in quick succession, which means
-	 * that those which occur after the first one will likely happen
-	 * *during* the hpsa_scan_thread's rescan.  And the rescan code is not
-	 * robust enough to restart in the middle, undoing what it has already
-	 * done, and it's not clear that it's even possible to do this, since
-	 * part of what it does is notify the SCSI mid layer, which starts
-	 * doing it's own i/o to read partition tables and so on, and the
-	 * driver doesn't have visibility to know what might need undoing.
-	 * In any event, if possible, it is horribly complicated to get right
-	 * so we just don't do it for now.
-	 *
 	 * Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012.
 	 */
 		break;
@@ -379,12 +255,8 @@ static ssize_t host_store_rescan(struct
 {
 	struct ctlr_info *h;
 	struct Scsi_Host *shost = class_to_shost(dev);
-	unsigned long *priv = shost_priv(shost);
-	h = (struct ctlr_info *) *priv;
-	if (add_to_scan_list(h)) {
-		wake_up_process(hpsa_scan_thread);
-		wait_for_completion_interruptible(&h->scan_wait);
-	}
+	h = shost_to_hba(shost);
+	hpsa_scan_start(h->scsi_host);
 	return count;
 }
 
@@ -394,10 +266,44 @@ static inline void addQ(struct hlist_hea
 	hlist_add_head(&c->list, list);
 }
 
+static inline u32 next_command(struct ctlr_info *h)
+{
+	u32 a;
+
+	if (unlikely(h->transMethod != CFGTBL_Trans_Performant))
+		return h->access.command_completed(h);
+
+	if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) {
+		a = *(h->reply_pool_head); /* Next cmd in ring buffer */
+		(h->reply_pool_head)++;
+		h->commands_outstanding--;
+	} else {
+		a = FIFO_EMPTY;
+	}
+	/* Check for wraparound */
+	if (h->reply_pool_head == (h->reply_pool + h->max_commands)) {
+		h->reply_pool_head = h->reply_pool;
+		h->reply_pool_wraparound ^= 1;
+	}
+	return a;
+}
+
+/* set_performant_mode: Modify the tag for cciss performant
+ * set bit 0 for pull model, bits 3-1 for block fetch
+ * register number
+ */
+static void set_performant_mode(struct ctlr_info *h, struct CommandList *c)
+{
+	if (likely(h->transMethod == CFGTBL_Trans_Performant))
+		c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1);
+}
+
 static void enqueue_cmd_and_start_io(struct ctlr_info *h,
 	struct CommandList *c)
 {
 	unsigned long flags;
+
+	set_performant_mode(h, c);
 	spin_lock_irqsave(&h->lock, flags);
 	addQ(&h->reqQ, c);
 	h->Qdepth++;
@@ -422,6 +328,15 @@ static inline int is_logical_dev_addr_mo
 	return (scsi3addr[3] & 0xC0) == 0x40;
 }
 
+static inline int is_scsi_rev_5(struct ctlr_info *h)
+{
+	if (!h->hba_inquiry_data)
+		return 0;
+	if ((h->hba_inquiry_data[2] & 0x07) == 5)
+		return 1;
+	return 0;
+}
+
 static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
 	"UNKNOWN"
 };
@@ -431,7 +346,7 @@ static ssize_t raid_level_show(struct de
 	     struct device_attribute *attr, char *buf)
 {
 	ssize_t l = 0;
-	int rlevel;
+	unsigned char rlevel;
 	struct ctlr_info *h;
 	struct scsi_device *sdev;
 	struct hpsa_scsi_dev_t *hdev;
@@ -455,7 +370,7 @@ static ssize_t raid_level_show(struct de
 
 	rlevel = hdev->raid_level;
 	spin_unlock_irqrestore(&h->lock, flags);
-	if (rlevel < 0 || rlevel > RAID_UNKNOWN)
+	if (rlevel > RAID_UNKNOWN)
 		rlevel = RAID_UNKNOWN;
 	l = snprintf(buf, PAGE_SIZE, "RAID %s\n", raid_label[rlevel]);
 	return l;
@@ -620,6 +535,24 @@ lun_assigned:
 	return 0;
 }
 
+/* Replace an entry from h->dev[] array. */
+static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno,
+	int entry, struct hpsa_scsi_dev_t *new_entry,
+	struct hpsa_scsi_dev_t *added[], int *nadded,
+	struct hpsa_scsi_dev_t *removed[], int *nremoved)
+{
+	/* assumes h->devlock is held */
+	BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA);
+	removed[*nremoved] = h->dev[entry];
+	(*nremoved)++;
+	h->dev[entry] = new_entry;
+	added[*nadded] = new_entry;
+	(*nadded)++;
+	dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d changed.\n",
+		scsi_device_type(new_entry->devtype), hostno, new_entry->bus,
+			new_entry->target, new_entry->lun);
+}
+
 /* Remove an entry from h->dev[] array. */
 static void hpsa_scsi_remove_entry(struct ctlr_info *h, int hostno, int entry,
 	struct hpsa_scsi_dev_t *removed[], int *nremoved)
@@ -628,8 +561,7 @@ static void hpsa_scsi_remove_entry(struc
 	int i;
 	struct hpsa_scsi_dev_t *sd;
 
-	if (entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA)
-		BUG();
+	BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA);
 
 	sd = h->dev[entry];
 	removed[*nremoved] = h->dev[entry];
@@ -722,6 +654,8 @@ static int hpsa_scsi_find_entry(struct h
 #define DEVICE_CHANGED 1
 #define DEVICE_SAME 2
 	for (i = 0; i < haystack_size; i++) {
+		if (haystack[i] == NULL) /* previously removed. */
+			continue;
 		if (SCSI3ADDR_EQ(needle->scsi3addr, haystack[i]->scsi3addr)) {
 			*index = i;
 			if (device_is_the_same(needle, haystack[i]))
@@ -734,7 +668,7 @@ static int hpsa_scsi_find_entry(struct h
 	return DEVICE_NOT_FOUND;
 }
 
-static int adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
+static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
 	struct hpsa_scsi_dev_t *sd[], int nsds)
 {
 	/* sd contains scsi3 addresses and devtypes, and inquiry
@@ -779,12 +713,12 @@ static int adjust_hpsa_scsi_table(struct
 			continue; /* remove ^^^, hence i not incremented */
 		} else if (device_change == DEVICE_CHANGED) {
 			changes++;
-			hpsa_scsi_remove_entry(h, hostno, i,
-				removed, &nremoved);
-			(void) hpsa_scsi_add_entry(h, hostno, sd[entry],
-				added, &nadded);
-			/* add can't fail, we just removed one. */
-			sd[entry] = NULL; /* prevent it from being freed */
+			hpsa_scsi_replace_entry(h, hostno, i, sd[entry],
+				added, &nadded, removed, &nremoved);
+			/* Set it to NULL to prevent it from being freed
+			 * at the bottom of hpsa_update_scsi_devices()
+			 */
+			sd[entry] = NULL;
 		}
 		i++;
 	}
@@ -860,7 +794,6 @@ static int adjust_hpsa_scsi_table(struct
 free_and_out:
 	kfree(added);
 	kfree(removed);
-	return 0;
 }
 
 /*
@@ -900,7 +833,7 @@ static int hpsa_slave_alloc(struct scsi_
 
 static void hpsa_slave_destroy(struct scsi_device *sdev)
 {
-	return; /* nothing to do. */
+	/* nothing to do. */
 }
 
 static void hpsa_scsi_setup(struct ctlr_info *h)
@@ -908,11 +841,80 @@ static void hpsa_scsi_setup(struct ctlr_
 	h->ndevices = 0;
 	h->scsi_host = NULL;
 	spin_lock_init(&h->devlock);
-	return;
+}
+
+static void hpsa_free_sg_chain_blocks(struct ctlr_info *h)
+{
+	int i;
+
+	if (!h->cmd_sg_list)
+		return;
+	for (i = 0; i < h->nr_cmds; i++) {
+		kfree(h->cmd_sg_list[i]);
+		h->cmd_sg_list[i] = NULL;
+	}
+	kfree(h->cmd_sg_list);
+	h->cmd_sg_list = NULL;
+}
+
+static int hpsa_allocate_sg_chain_blocks(struct ctlr_info *h)
+{
+	int i;
+
+	if (h->chainsize <= 0)
+		return 0;
+
+	h->cmd_sg_list = kzalloc(sizeof(*h->cmd_sg_list) * h->nr_cmds,
+				GFP_KERNEL);
+	if (!h->cmd_sg_list)
+		return -ENOMEM;
+	for (i = 0; i < h->nr_cmds; i++) {
+		h->cmd_sg_list[i] = kmalloc(sizeof(*h->cmd_sg_list[i]) *
+						h->chainsize, GFP_KERNEL);
+		if (!h->cmd_sg_list[i])
+			goto clean;
+	}
+	return 0;
+
+clean:
+	hpsa_free_sg_chain_blocks(h);
+	return -ENOMEM;
+}
+
+static void hpsa_map_sg_chain_block(struct ctlr_info *h,
+	struct CommandList *c)
+{
+	struct SGDescriptor *chain_sg, *chain_block;
+	u64 temp64;
+
+	chain_sg = &c->SG[h->max_cmd_sg_entries - 1];
+	chain_block = h->cmd_sg_list[c->cmdindex];
+	chain_sg->Ext = HPSA_SG_CHAIN;
+	chain_sg->Len = sizeof(*chain_sg) *
+		(c->Header.SGTotal - h->max_cmd_sg_entries);
+	temp64 = pci_map_single(h->pdev, chain_block, chain_sg->Len,
+				PCI_DMA_TODEVICE);
+	chain_sg->Addr.lower = (u32) (temp64 & 0x0FFFFFFFFULL);
+	chain_sg->Addr.upper = (u32) ((temp64 >> 32) & 0x0FFFFFFFFULL);
+}
+
+static void hpsa_unmap_sg_chain_block(struct ctlr_info *h,
+	struct CommandList *c)
+{
+	struct SGDescriptor *chain_sg;
+	union u64bit temp64;
+
+	if (c->Header.SGTotal <= h->max_cmd_sg_entries)
+		return;
+
+	chain_sg = &c->SG[h->max_cmd_sg_entries - 1];
+	temp64.val32.lower = chain_sg->Addr.lower;
+	temp64.val32.upper = chain_sg->Addr.upper;
+	pci_unmap_single(h->pdev, temp64.val, chain_sg->Len, PCI_DMA_TODEVICE);
 }
 
 static void complete_scsi_command(struct CommandList *cp,
-	int timeout, __u32 tag)
+	int timeout, u32 tag)
 {
 	struct scsi_cmnd *cmd;
 	struct ctlr_info *h;
@@ -927,10 +929,12 @@ static void complete_scsi_command(struct
 	h = cp->h;
 
 	scsi_dma_unmap(cmd); /* undo the DMA mappings */
+	if (cp->Header.SGTotal > h->max_cmd_sg_entries)
+		hpsa_unmap_sg_chain_block(h, cp);
 
 	cmd->result = (DID_OK << 16); 		/* host byte */
 	cmd->result |= (COMMAND_COMPLETE << 8);	/* msg byte */
-	cmd->result |= (ei->ScsiStatus << 1);
+	cmd->result |= ei->ScsiStatus;
 
 	/* copy the sense data whether we need to or not. */
 	memcpy(cmd->sense_buffer, ei->SenseInfo,
@@ -987,7 +991,6 @@ static void complete_scsi_command(struct
 				 * required
 				 */
 				if ((asc == 0x04) && (ascq == 0x03)) {
-					cmd->result = DID_NO_CONNECT << 16;
 					dev_warn(&h->pdev->dev, "cp %p "
 						"has check condition: unit "
 						"not ready, manual "
@@ -995,14 +998,22 @@ static void complete_scsi_command(struct
 					break;
 				}
 			}
-
-
+			if (sense_key == ABORTED_COMMAND) {
+				/* Aborted command is retryable */
+				dev_warn(&h->pdev->dev, "cp %p "
+					"has check condition: aborted command: "
+					"ASC: 0x%x, ASCQ: 0x%x\n",
+					cp, asc, ascq);
+				cmd->result = DID_SOFT_ERROR << 16;
+				break;
+			}
 			/* Must be some other type of check condition */
 			dev_warn(&h->pdev->dev, "cp %p has check condition: "
 					"unknown type: "
 					"Sense: 0x%x, ASC: 0x%x, ASCQ: 0x%x, "
 					"Returning result: 0x%x, "
 					"cmd=[%02x %02x %02x %02x %02x "
+					"%02x %02x %02x %02x %02x %02x "
 					"%02x %02x %02x %02x %02x]\n",
 					cp, sense_key, asc, ascq,
 					cmd->result,
@@ -1010,7 +1021,10 @@ static void complete_scsi_command(struct
 					cmd->cmnd[2], cmd->cmnd[3],
 					cmd->cmnd[4], cmd->cmnd[5],
 					cmd->cmnd[6], cmd->cmnd[7],
-					cmd->cmnd[8], cmd->cmnd[9]);
+					cmd->cmnd[8], cmd->cmnd[9],
+					cmd->cmnd[10], cmd->cmnd[11],
+					cmd->cmnd[12], cmd->cmnd[13],
+					cmd->cmnd[14], cmd->cmnd[15]);
 			break;
 		}
 
@@ -1086,7 +1100,7 @@ static void complete_scsi_command(struct
 		dev_warn(&h->pdev->dev, "cp %p reports abort failed\n", cp);
 		break;
 	case CMD_UNSOLICITED_ABORT:
-		cmd->result = DID_ABORT << 16;
+		cmd->result = DID_RESET << 16;
 		dev_warn(&h->pdev->dev, "cp %p aborted do to an unsolicited "
 			"abort\n", cp);
 		break;
@@ -1119,9 +1133,12 @@ static int hpsa_scsi_detect(struct ctlr_
 	sh->max_cmd_len = MAX_COMMAND_SIZE;
 	sh->max_lun = HPSA_MAX_LUN;
 	sh->max_id = HPSA_MAX_LUN;
+	sh->can_queue = h->nr_cmds;
+	sh->cmd_per_lun = h->nr_cmds;
+	sh->sg_tablesize = h->maxsgentries;
 	h->scsi_host = sh;
 	sh->hostdata[0] = (unsigned long) h;
-	sh->irq = h->intr[SIMPLE_MODE_INT];
+	sh->irq = h->intr[PERF_MODE_INT];
 	sh->unique_id = sh->irq;
 	error = scsi_add_host(sh, &h->pdev->dev);
 	if (error)
@@ -1133,11 +1150,11 @@ static int hpsa_scsi_detect(struct ctlr_
 	dev_err(&h->pdev->dev, "hpsa_scsi_detect: scsi_add_host"
 		" failed for controller %d\n", h->ctlr);
 	scsi_host_put(sh);
-	return -1;
+	return error;
  fail:
 	dev_err(&h->pdev->dev, "hpsa_scsi_detect: scsi_host_alloc"
 		" failed for controller %d\n", h->ctlr);
-	return -1;
+	return -ENOMEM;
 }
 
 static void hpsa_pci_unmap(struct pci_dev *pdev,
@@ -1160,7 +1177,7 @@ static void hpsa_map_one(struct pci_dev
 		size_t buflen,
 		int data_direction)
 {
-	__u64 addr64;
+	u64 addr64;
 
 	if (buflen == 0 || data_direction == PCI_DMA_NONE) {
 		cp->Header.SGList = 0;
@@ -1168,14 +1185,14 @@ static void hpsa_map_one(struct pci_dev
 		return;
 	}
 
-	addr64 = (__u64) pci_map_single(pdev, buf, buflen, data_direction);
+	addr64 = (u64) pci_map_single(pdev, buf, buflen, data_direction);
 	cp->SG[0].Addr.lower =
-	  (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
+	  (u32) (addr64 & (u64) 0x00000000FFFFFFFF);
 	cp->SG[0].Addr.upper =
-	  (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
+	  (u32) ((addr64 >> 32) & (u64) 0x00000000FFFFFFFF);
 	cp->SG[0].Len = buflen;
-	cp->Header.SGList = (__u8) 1;   /* no. SGs contig in this cmd */
-	cp->Header.SGTotal = (__u16) 1; /* total sgs in this cmd list */
+	cp->Header.SGList = (u8) 1;   /* no. SGs contig in this cmd */
+	cp->Header.SGTotal = (u16) 1; /* total sgs in this cmd list */
 }
 
 static inline void hpsa_scsi_do_simple_cmd_core(struct ctlr_info *h,
@@ -1274,7 +1291,7 @@ static int hpsa_scsi_do_inquiry(struct c
 
 	if (c == NULL) {			/* trouble... */
 		dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n");
-		return -1;
+		return -ENOMEM;
 	}
 
 	fill_cmd(c, HPSA_INQUIRY, h, buf, bufsize, page, scsi3addr, TYPE_CMD);
@@ -1298,7 +1315,7 @@ static int hpsa_send_reset(struct ctlr_i
 
 	if (c == NULL) {			/* trouble... */
 		dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n");
-		return -1;
+		return -ENOMEM;
 	}
 
 	fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, scsi3addr, TYPE_MSG);
@@ -1366,9 +1383,8 @@ static int hpsa_scsi_do_report_luns(stru
 		dev_err(&h->pdev->dev, "cmd_special_alloc returned NULL!\n");
 		return -1;
 	}
-
-	memset(&scsi3addr[0], 0, 8); /* address the controller */
-
+	/* address the controller */
+	memset(scsi3addr, 0, sizeof(scsi3addr));
 	fill_cmd(c, logical ? HPSA_REPORT_LOG : HPSA_REPORT_PHYS, h,
 		buf, bufsize, 0, scsi3addr, TYPE_CMD);
 	if (extended_response)
@@ -1409,13 +1425,12 @@ static int hpsa_update_device_info(struc
 	unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device)
 {
 #define OBDR_TAPE_INQ_SIZE 49
-	unsigned char *inq_buff = NULL;
+	unsigned char *inq_buff;
 
-	inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
+	inq_buff = kzalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
 	if (!inq_buff)
 		goto bail_out;
 
-	memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE);
 	/* Do an inquiry to the device to see what it is. */
 	if (hpsa_scsi_do_inquiry(h, scsi3addr, 0, inq_buff,
 		(unsigned char) OBDR_TAPE_INQ_SIZE) != 0) {
@@ -1485,32 +1500,51 @@ static int is_msa2xxx(struct ctlr_info *
  * in hpsa_find_target_lun, called by hpsa_scsi_add_entry.)
  */
 static void figure_bus_target_lun(struct ctlr_info *h,
-	__u8 *lunaddrbytes, int *bus, int *target, int *lun,
+	u8 *lunaddrbytes, int *bus, int *target, int *lun,
 	struct hpsa_scsi_dev_t *device)
 {
-
-	__u32 lunid;
+	u32 lunid;
 
 	if (is_logical_dev_addr_mode(lunaddrbytes)) {
 		/* logical device */
-		memcpy(&lunid, lunaddrbytes, sizeof(lunid));
-		lunid = le32_to_cpu(lunid);
-
-		if (is_msa2xxx(h, device)) {
-			*bus = 1;
-			*target = (lunid >> 16) & 0x3fff;
-			*lun = lunid & 0x00ff;
-		} else {
+		if (unlikely(is_scsi_rev_5(h))) {
+			/* p1210m, logical drives lun assignments
+			 * match SCSI REPORT LUNS data.
+			 */
+			lunid = le32_to_cpu(*((__le32 *) lunaddrbytes));
 			*bus = 0;
-			*lun = 0;
-			*target = lunid & 0x3fff;
+			*target = 0;
+			*lun = (lunid & 0x3fff) + 1;
+		} else {
+			/* not p1210m... */
+			lunid = le32_to_cpu(*((__le32 *) lunaddrbytes));
+			if (is_msa2xxx(h, device)) {
+				/* msa2xxx way, put logicals on bus 1
+				 * and match target/lun numbers box
+				 * reports.
+				 */
+				*bus = 1;
+				*target = (lunid >> 16) & 0x3fff;
+				*lun = lunid & 0x00ff;
+			} else {
+				/* Traditional smart array way. */
+				*bus = 0;
+				*lun = 0;
+				*target = lunid & 0x3fff;
+			}
 		}
 	} else {
 		/* physical device */
 		if (is_hba_lunid(lunaddrbytes))
-			*bus = 3;
+			if (unlikely(is_scsi_rev_5(h))) {
+				*bus = 0; /* put p1210m ctlr at 0,0,0 */
+				*target = 0;
+				*lun = 0;
+				return;
+			} else
+				*bus = 3; /* traditional smartarray */
 		else
-			*bus = 2;
+			*bus = 2; /* physical disk */
 		*target = -1;
 		*lun = -1; /* we will fill these in later. */
 	}
@@ -1529,7 +1563,7 @@ static void figure_bus_target_lun(struct
  */
 static int add_msa2xxx_enclosure_device(struct ctlr_info *h,
 	struct hpsa_scsi_dev_t *tmpdevice,
-	struct hpsa_scsi_dev_t *this_device, __u8 *lunaddrbytes,
+	struct hpsa_scsi_dev_t *this_device, u8 *lunaddrbytes,
 	int bus, int target, int lun, unsigned long lunzerobits[],
 	int *nmsa2xxx_enclosures)
 {
@@ -1550,6 +1584,9 @@ static int add_msa2xxx_enclosure_device(
 	if (is_hba_lunid(scsi3addr))
 		return 0; /* Don't add the RAID controller here. */
 
+	if (is_scsi_rev_5(h))
+		return 0; /* p1210m doesn't need to do this. */
+
 #define MAX_MSA2XXX_ENCLOSURES 32
 	if (*nmsa2xxx_enclosures >= MAX_MSA2XXX_ENCLOSURES) {
 		dev_warn(&h->pdev->dev, "Maximum number of MSA2XXX "
@@ -1576,18 +1613,14 @@ static int add_msa2xxx_enclosure_device(
  */
 static int hpsa_gather_lun_info(struct ctlr_info *h,
 	int reportlunsize,
-	struct ReportLUNdata *physdev, __u32 *nphysicals,
-	struct ReportLUNdata *logdev, __u32 *nlogicals)
+	struct ReportLUNdata *physdev, u32 *nphysicals,
+	struct ReportLUNdata *logdev, u32 *nlogicals)
 {
 	if (hpsa_scsi_do_report_phys_luns(h, physdev, reportlunsize, 0)) {
 		dev_err(&h->pdev->dev, "report physical LUNs failed.\n");
 		return -1;
 	}
-	memcpy(nphysicals, &physdev->LUNListLength[0], sizeof(*nphysicals));
-	*nphysicals = be32_to_cpu(*nphysicals) / 8;
-#ifdef DEBUG
-	dev_info(&h->pdev->dev, "number of physical luns is %d\n", *nphysicals);
-#endif
+	*nphysicals = be32_to_cpu(*((__be32 *)physdev->LUNListLength)) / 8;
 	if (*nphysicals > HPSA_MAX_PHYS_LUN) {
 		dev_warn(&h->pdev->dev, "maximum physical LUNs (%d) exceeded."
 			"  %d LUNs ignored.\n", HPSA_MAX_PHYS_LUN,
@@ -1598,11 +1631,7 @@ static int hpsa_gather_lun_info(struct c
 		dev_err(&h->pdev->dev, "report logical LUNs failed.\n");
 		return -1;
 	}
-	memcpy(nlogicals, &logdev->LUNListLength[0], sizeof(*nlogicals));
-	*nlogicals = be32_to_cpu(*nlogicals) / 8;
-#ifdef DEBUG
-	dev_info(&h->pdev->dev, "number of logical luns is %d\n", *nlogicals);
-#endif
+	*nlogicals = be32_to_cpu(*((__be32 *) logdev->LUNListLength)) / 8;
 	/* Reject Logicals in excess of our max capability. */
 	if (*nlogicals > HPSA_MAX_LUN) {
 		dev_warn(&h->pdev->dev,
@@ -1621,6 +1650,31 @@ static int hpsa_gather_lun_info(struct c
 	return 0;
 }
 
+u8 *figure_lunaddrbytes(struct ctlr_info *h, int raid_ctlr_position, int i,
+	int nphysicals, int nlogicals, struct ReportLUNdata *physdev_list,
+	struct ReportLUNdata *logdev_list)
+{
+	/* Helper function, figure out where the LUN ID info is coming from
+	 * given index i, lists of physical and logical devices, where in
+	 * the list the raid controller is supposed to appear (first or last)
+	 */
+
+	int logicals_start = nphysicals + (raid_ctlr_position == 0);
+	int last_device = nphysicals + nlogicals + (raid_ctlr_position == 0);
+
+	if (i == raid_ctlr_position)
+		return RAID_CTLR_LUNID;
+
+	if (i < logicals_start)
+		return &physdev_list->LUN[i - (raid_ctlr_position == 0)][0];
+
+	if (i < last_device)
+		return &logdev_list->LUN[i - nphysicals -
+			(raid_ctlr_position == 0)][0];
+	BUG();
+	return NULL;
+}
+
 static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
 {
 	/* the idea here is we could get notified
@@ -1636,14 +1690,15 @@ static void hpsa_update_scsi_devices(str
 	struct ReportLUNdata *physdev_list = NULL;
 	struct ReportLUNdata *logdev_list = NULL;
 	unsigned char *inq_buff = NULL;
-	__u32 nphysicals = 0;
-	__u32 nlogicals = 0;
-	__u32 ndev_allocated = 0;
+	u32 nphysicals = 0;
+	u32 nlogicals = 0;
+	u32 ndev_allocated = 0;
 	struct hpsa_scsi_dev_t **currentsd, *this_device, *tmpdevice;
 	int ncurrent = 0;
 	int reportlunsize = sizeof(*physdev_list) + HPSA_MAX_PHYS_LUN * 8;
 	int i, nmsa2xxx_enclosures, ndevs_to_allocate;
 	int bus, target, lun;
+	int raid_ctlr_position;
 	DECLARE_BITMAP(lunzerobits, HPSA_MAX_TARGETS_PER_CTLR);
 
 	currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_SCSI_DEVS_PER_HBA,
@@ -1681,23 +1736,22 @@ static void hpsa_update_scsi_devices(str
 		ndev_allocated++;
 	}
 
+	if (unlikely(is_scsi_rev_5(h)))
+		raid_ctlr_position = 0;
+	else
+		raid_ctlr_position = nphysicals + nlogicals;
+
 	/* adjust our table of devices */
 	nmsa2xxx_enclosures = 0;
 	for (i = 0; i < nphysicals + nlogicals + 1; i++) {
-		__u8 *lunaddrbytes;
+		u8 *lunaddrbytes;
 
 		/* Figure out where the LUN ID info is coming from */
-		if (i < nphysicals)
-			lunaddrbytes = &physdev_list->LUN[i][0];
-		else
-			if (i < nphysicals + nlogicals)
-				lunaddrbytes =
-					&logdev_list->LUN[i-nphysicals][0];
-			else /* jam in the RAID controller at the end */
-				lunaddrbytes = RAID_CTLR_LUNID;
-
+		lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position,
+			i, nphysicals, nlogicals, physdev_list, logdev_list);
 		/* skip masked physical devices. */
-		if (lunaddrbytes[3] & 0xC0 && i < nphysicals)
+		if (lunaddrbytes[3] & 0xC0 &&
+			i < nphysicals + (raid_ctlr_position == 0))
 			continue;
 
 		/* Get device type, vendor, model, device id */
@@ -1777,23 +1831,23 @@ out:
 	kfree(inq_buff);
 	kfree(physdev_list);
 	kfree(logdev_list);
-	return;
 }
 
 /* hpsa_scatter_gather takes a struct scsi_cmnd, (cmd), and does the pci
  * dma mapping  and fills in the scatter gather entries of the
  * hpsa command, cp.
  */
-static int hpsa_scatter_gather(struct pci_dev *pdev,
+static int hpsa_scatter_gather(struct ctlr_info *h,
 		struct CommandList *cp,
 		struct scsi_cmnd *cmd)
 {
 	unsigned int len;
 	struct scatterlist *sg;
-	__u64 addr64;
-	int use_sg, i;
+	u64 addr64;
+	int use_sg, i, sg_index, chained;
+	struct SGDescriptor *curr_sg;
 
-	BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES);
+	BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);
 
 	use_sg = scsi_dma_map(cmd);
 	if (use_sg < 0)
@@ -1802,21 +1856,39 @@ static int hpsa_scatter_gather(struct pc
 	if (!use_sg)
 		goto sglist_finished;
 
+	curr_sg = cp->SG;
+	chained = 0;
+	sg_index = 0;
 	scsi_for_each_sg(cmd, sg, use_sg, i) {
-		addr64 = (__u64) sg_dma_address(sg);
+		if (i == h->max_cmd_sg_entries - 1 &&
+			use_sg > h->max_cmd_sg_entries) {
+			chained = 1;
+			curr_sg = h->cmd_sg_list[cp->cmdindex];
+			sg_index = 0;
+		}
+		addr64 = (u64) sg_dma_address(sg);
 		len  = sg_dma_len(sg);
-		cp->SG[i].Addr.lower =
-			(__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
-		cp->SG[i].Addr.upper =
-			(__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
-		cp->SG[i].Len = len;
-		cp->SG[i].Ext = 0;  /* we are not chaining */
+		curr_sg->Addr.lower = (u32) (addr64 & 0x0FFFFFFFFULL);
+		curr_sg->Addr.upper = (u32) ((addr64 >> 32) & 0x0FFFFFFFFULL);
+		curr_sg->Len = len;
+		curr_sg->Ext = 0;  /* we are not chaining */
+		curr_sg++;
+	}
+
+	if (use_sg + chained > h->maxSG)
+		h->maxSG = use_sg + chained;
+
+	if (chained) {
+		cp->Header.SGList = h->max_cmd_sg_entries;
+		cp->Header.SGTotal = (u16) (use_sg + 1);
+		hpsa_map_sg_chain_block(h, cp);
+		return 0;
 	}
 
 sglist_finished:
 
-	cp->Header.SGList = (__u8) use_sg;   /* no. SGs contig in this cmd */
-	cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */
+	cp->Header.SGList = (u8) use_sg;   /* no. SGs contig in this cmd */
+	cp->Header.SGTotal = (u16) use_sg; /* total sgs in this cmd list */
 	return 0;
 }
 
@@ -1860,7 +1932,8 @@ static int hpsa_scsi_queue_command(struc
 	c->scsi_cmd = cmd;
 	c->Header.ReplyQueue = 0;  /* unused in simple mode */
 	memcpy(&c->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8);
-	c->Header.Tag.lower = c->busaddr;  /* Use k. address of cmd as tag */
+	c->Header.Tag.lower = (c->cmdindex << DIRECT_LOOKUP_SHIFT);
+	c->Header.Tag.lower |= DIRECT_LOOKUP_BIT;
 
 	/* Fill in the request block... */
 
@@ -1905,7 +1978,7 @@ static int hpsa_scsi_queue_command(struc
 		break;
 	}
 
-	if (hpsa_scatter_gather(h->pdev, c, cmd) < 0) { /* Fill SG list */
+	if (hpsa_scatter_gather(h, c, cmd) < 0) { /* Fill SG list */
 		cmd_free(h, c);
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
@@ -1914,6 +1987,65 @@ static int hpsa_scsi_queue_command(struc
 	return 0;
 }
 
+static void hpsa_scan_start(struct Scsi_Host *sh)
+{
+	struct ctlr_info *h = shost_to_hba(sh);
+	unsigned long flags;
+
+	/* wait until any scan already in progress is finished. */
+	while (1) {
+		spin_lock_irqsave(&h->scan_lock, flags);
+		if (h->scan_finished)
+			break;
+		spin_unlock_irqrestore(&h->scan_lock, flags);
+		wait_event(h->scan_wait_queue, h->scan_finished);
+		/* Note: We don't need to worry about a race between this
+		 * thread and driver unload because the midlayer will
+		 * have incremented the reference count, so unload won't
+		 * happen if we're in here.
+		 */
+	}
+	h->scan_finished = 0; /* mark scan as in progress */
+	spin_unlock_irqrestore(&h->scan_lock, flags);
+
+	hpsa_update_scsi_devices(h, h->scsi_host->host_no);
+
+	spin_lock_irqsave(&h->scan_lock, flags);
+	h->scan_finished = 1; /* mark scan as finished. */
+	wake_up_all(&h->scan_wait_queue);
+	spin_unlock_irqrestore(&h->scan_lock, flags);
+}
+
+static int hpsa_scan_finished(struct Scsi_Host *sh,
+	unsigned long elapsed_time)
+{
+	struct ctlr_info *h = shost_to_hba(sh);
+	unsigned long flags;
+	int finished;
+
+	spin_lock_irqsave(&h->scan_lock, flags);
+	finished = h->scan_finished;
+	spin_unlock_irqrestore(&h->scan_lock, flags);
+	return finished;
+}
+
+static int hpsa_change_queue_depth(struct scsi_device *sdev,
+	int qdepth, int reason)
+{
+	struct ctlr_info *h = sdev_to_hba(sdev);
+
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -ENOTSUPP;
+
+	if (qdepth < 1)
+		qdepth = 1;
+	else
+		if (qdepth > h->nr_cmds)
+			qdepth = h->nr_cmds;
+	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+	return sdev->queue_depth;
+}
+
 static void hpsa_unregister_scsi(struct ctlr_info *h)
 {
 	/* we are being forcibly unloaded, and may not refuse. */
@@ -1926,7 +2058,6 @@ static int hpsa_register_scsi(struct ctl
 {
 	int rc;
 
-	hpsa_update_scsi_devices(h, -1);
 	rc = hpsa_scsi_detect(h);
 	if (rc != 0)
 		dev_err(&h->pdev->dev, "hpsa_register_scsi: failed"
@@ -2003,14 +2134,14 @@ static int hpsa_eh_device_reset_handler(
 	h = sdev_to_hba(scsicmd->device);
 	if (h == NULL) /* paranoia */
 		return FAILED;
-	dev_warn(&h->pdev->dev, "resetting drive\n");
-
 	dev = scsicmd->device->hostdata;
 	if (!dev) {
 		dev_err(&h->pdev->dev, "hpsa_eh_device_reset_handler: "
 			"device lookup failed.\n");
 		return FAILED;
 	}
+	dev_warn(&h->pdev->dev, "resetting device %d:%d:%d:%d\n",
+		h->scsi_host->host_no, dev->bus, dev->target, dev->lun);
 	/* send a reset to the SCSI LUN which the command was sent to */
 	rc = hpsa_send_reset(h, dev->scsi3addr);
 	if (rc == 0 && wait_for_device_to_become_ready(h, dev->scsi3addr) == 0)
@@ -2053,8 +2184,8 @@ static struct CommandList *cmd_alloc(str
 	c->cmdindex = i;
 
 	INIT_HLIST_NODE(&c->list);
-	c->busaddr = (__u32) cmd_dma_handle;
-	temp64.val = (__u64) err_dma_handle;
+	c->busaddr = (u32) cmd_dma_handle;
+	temp64.val = (u64) err_dma_handle;
 	c->ErrDesc.Addr.lower = temp64.val32.lower;
 	c->ErrDesc.Addr.upper = temp64.val32.upper;
 	c->ErrDesc.Len = sizeof(*c->err_info);
@@ -2091,8 +2222,8 @@ static struct CommandList *cmd_special_a
 	memset(c->err_info, 0, sizeof(*c->err_info));
 
 	INIT_HLIST_NODE(&c->list);
-	c->busaddr = (__u32) cmd_dma_handle;
-	temp64.val = (__u64) err_dma_handle;
+	c->busaddr = (u32) cmd_dma_handle;
+	temp64.val = (u64) err_dma_handle;
 	c->ErrDesc.Addr.lower = temp64.val32.lower;
 	c->ErrDesc.Addr.upper = temp64.val32.upper;
 	c->ErrDesc.Len = sizeof(*c->err_info);
@@ -2125,50 +2256,6 @@ static void cmd_special_free(struct ctlr
 
 #ifdef CONFIG_COMPAT
 
-static int do_ioctl(struct scsi_device *dev, int cmd, void *arg)
-{
-	int ret;
-
-	lock_kernel();
-	ret = hpsa_ioctl(dev, cmd, arg);
-	unlock_kernel();
-	return ret;
-}
-
-static int hpsa_ioctl32_passthru(struct scsi_device *dev, int cmd, void *arg);
-static int hpsa_ioctl32_big_passthru(struct scsi_device *dev,
-	int cmd, void *arg);
-
-static int hpsa_compat_ioctl(struct scsi_device *dev, int cmd, void *arg)
-{
-	switch (cmd) {
-	case CCISS_GETPCIINFO:
-	case CCISS_GETINTINFO:
-	case CCISS_SETINTINFO:
-	case CCISS_GETNODENAME:
-	case CCISS_SETNODENAME:
-	case CCISS_GETHEARTBEAT:
-	case CCISS_GETBUSTYPES:
-	case CCISS_GETFIRMVER:
-	case CCISS_GETDRIVVER:
-	case CCISS_REVALIDVOLS:
-	case CCISS_DEREGDISK:
-	case CCISS_REGNEWDISK:
-	case CCISS_REGNEWD:
-	case CCISS_RESCANDISK:
-	case CCISS_GETLUNINFO:
-		return do_ioctl(dev, cmd, arg);
-
-	case CCISS_PASSTHRU32:
-		return hpsa_ioctl32_passthru(dev, cmd, arg);
-	case CCISS_BIG_PASSTHRU32:
-		return hpsa_ioctl32_big_passthru(dev, cmd, arg);
-
-	default:
-		return -ENOIOCTLCMD;
-	}
-}
-
 static int hpsa_ioctl32_passthru(struct scsi_device *dev, int cmd, void *arg)
 {
 	IOCTL32_Command_struct __user *arg32 =
@@ -2193,7 +2280,7 @@ static int hpsa_ioctl32_passthru(struct
 	if (err)
 		return -EFAULT;
 
-	err = do_ioctl(dev, CCISS_PASSTHRU, (void *)p);
+	err = hpsa_ioctl(dev, CCISS_PASSTHRU, (void *)p);
 	if (err)
 		return err;
 	err |= copy_in_user(&arg32->error_info, &p->error_info,
@@ -2230,7 +2317,7 @@ static int hpsa_ioctl32_big_passthru(str
 	if (err)
 		return -EFAULT;
 
-	err = do_ioctl(dev, CCISS_BIG_PASSTHRU, (void *)p);
+	err = hpsa_ioctl(dev, CCISS_BIG_PASSTHRU, (void *)p);
 	if (err)
 		return err;
 	err |= copy_in_user(&arg32->error_info, &p->error_info,
@@ -2239,6 +2326,36 @@ static int hpsa_ioctl32_big_passthru(str
 		return -EFAULT;
 	return err;
 }
+
+static int hpsa_compat_ioctl(struct scsi_device *dev, int cmd, void *arg)
+{
+	switch (cmd) {
+	case CCISS_GETPCIINFO:
+	case CCISS_GETINTINFO:
+	case CCISS_SETINTINFO:
+	case CCISS_GETNODENAME:
+	case CCISS_SETNODENAME:
+	case CCISS_GETHEARTBEAT:
+	case CCISS_GETBUSTYPES:
+	case CCISS_GETFIRMVER:
+	case CCISS_GETDRIVVER:
+	case CCISS_REVALIDVOLS:
+	case CCISS_DEREGDISK:
+	case CCISS_REGNEWDISK:
+	case CCISS_REGNEWD:
+	case CCISS_RESCANDISK:
+	case CCISS_GETLUNINFO:
+		return hpsa_ioctl(dev, cmd, arg);
+
+	case CCISS_PASSTHRU32:
+		return hpsa_ioctl32_passthru(dev, cmd, arg);
+	case CCISS_BIG_PASSTHRU32:
+		return hpsa_ioctl32_big_passthru(dev, cmd, arg);
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
 #endif
 
 static int hpsa_getpciinfo_ioctl(struct ctlr_info *h, void __user *argp)
@@ -2378,8 +2495,8 @@ static int hpsa_big_passthru_ioctl(struc
 	BYTE sg_used = 0;
 	int status = 0;
 	int i;
-	__u32 left;
-	__u32 sz;
+	u32 left;
+	u32 sz;
 	BYTE __user *data_ptr;
 
 	if (!argp)
@@ -2527,7 +2644,7 @@ static int hpsa_ioctl(struct scsi_device
 	case CCISS_DEREGDISK:
 	case CCISS_REGNEWDISK:
 	case CCISS_REGNEWD:
-		hpsa_update_scsi_devices(h, dev->host->host_no);
+		hpsa_scan_start(h->scsi_host);
 		return 0;
 	case CCISS_GETPCIINFO:
 		return hpsa_getpciinfo_ioctl(h, argp);
@@ -2542,8 +2659,8 @@ static int hpsa_ioctl(struct scsi_device
 	}
 }
 
-static void fill_cmd(struct CommandList *c, __u8 cmd, struct ctlr_info *h,
-	void *buff, size_t size, __u8 page_code, unsigned char *scsi3addr,
+static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
+	void *buff, size_t size, u8 page_code, unsigned char *scsi3addr,
 	int cmd_type)
 {
 	int pci_dir = XFER_NONE;
@@ -2710,19 +2827,20 @@ static inline unsigned long get_next_com
 	return h->access.command_completed(h);
 }
 
-static inline int interrupt_pending(struct ctlr_info *h)
+static inline bool interrupt_pending(struct ctlr_info *h)
 {
 	return h->access.intr_pending(h);
 }
 
 static inline long interrupt_not_for_us(struct ctlr_info *h)
 {
-	return ((h->access.intr_pending(h) == 0) ||
-		 (h->interrupts_enabled == 0));
+	return !(h->msi_vector || h->msix_vector) &&
+		((h->access.intr_pending(h) == 0) ||
+		(h->interrupts_enabled == 0));
 }
 
-static inline int bad_tag(struct ctlr_info *h, __u32 tag_index,
-	__u32 raw_tag)
+static inline int bad_tag(struct ctlr_info *h, u32 tag_index,
+	u32 raw_tag)
 {
 	if (unlikely(tag_index >= h->nr_cmds)) {
 		dev_warn(&h->pdev->dev, "bad tag 0x%08x ignored.\n", raw_tag);
@@ -2731,7 +2849,7 @@ static inline int bad_tag(struct ctlr_in
 	return 0;
 }
 
-static inline void finish_cmd(struct CommandList *c, __u32 raw_tag)
+static inline void finish_cmd(struct CommandList *c, u32 raw_tag)
 {
 	removeQ(c);
 	if (likely(c->cmd_type == CMD_SCSI))
@@ -2740,36 +2858,73 @@ static inline void finish_cmd(struct Com
 		complete(c->waiting);
 }
 
+static inline u32 hpsa_tag_contains_index(u32 tag)
+{
+#define DIRECT_LOOKUP_BIT 0x10
+	return tag & DIRECT_LOOKUP_BIT;
+}
+
+static inline u32 hpsa_tag_to_index(u32 tag)
+{
+#define DIRECT_LOOKUP_SHIFT 5
+	return tag >> DIRECT_LOOKUP_SHIFT;
+}
+
+static inline u32 hpsa_tag_discard_error_bits(u32 tag)
+{
+#define HPSA_ERROR_BITS 0x03
+	return tag & ~HPSA_ERROR_BITS;
+}
+
+/* process completion of an indexed ("direct lookup") command */
+static inline u32 process_indexed_cmd(struct ctlr_info *h,
+	u32 raw_tag)
+{
+	u32 tag_index;
+	struct CommandList *c;
+
+	tag_index = hpsa_tag_to_index(raw_tag);
+	if (bad_tag(h, tag_index, raw_tag))
+		return next_command(h);
+	c = h->cmd_pool + tag_index;
+	finish_cmd(c, raw_tag);
+	return next_command(h);
+}
+
+/* process completion of a non-indexed command */
+static inline u32 process_nonindexed_cmd(struct ctlr_info *h,
+	u32 raw_tag)
+{
+	u32 tag;
+	struct CommandList *c = NULL;
+	struct hlist_node *tmp;
+
+	tag = hpsa_tag_discard_error_bits(raw_tag);
+	hlist_for_each_entry(c, tmp, &h->cmpQ, list) {
+		if ((c->busaddr & 0xFFFFFFE0) == (tag & 0xFFFFFFE0)) {
+			finish_cmd(c, raw_tag);
+			return next_command(h);
+		}
+	}
+	bad_tag(h, h->nr_cmds + 1, raw_tag);
+	return next_command(h);
+}
+
 static irqreturn_t do_hpsa_intr(int irq, void *dev_id)
 {
 	struct ctlr_info *h = dev_id;
-	struct CommandList *c;
 	unsigned long flags;
-	__u32 raw_tag, tag, tag_index;
-	struct hlist_node *tmp;
+	u32 raw_tag;
 
 	if (interrupt_not_for_us(h))
 		return IRQ_NONE;
 	spin_lock_irqsave(&h->lock, flags);
-	while (interrupt_pending(h)) {
-		while ((raw_tag = get_next_completion(h)) != FIFO_EMPTY) {
-			if (likely(HPSA_TAG_CONTAINS_INDEX(raw_tag))) {
-				tag_index = HPSA_TAG_TO_INDEX(raw_tag);
-				if (bad_tag(h, tag_index, raw_tag))
-					return IRQ_HANDLED;
-				c = h->cmd_pool + tag_index;
-				finish_cmd(c, raw_tag);
-				continue;
-			}
-			tag = HPSA_TAG_DISCARD_ERROR_BITS(raw_tag);
-			c = NULL;
-			hlist_for_each_entry(c, tmp, &h->cmpQ, list) {
-				if (c->busaddr == tag) {
-					finish_cmd(c, raw_tag);
-					break;
-				}
-			}
-		}
+	raw_tag = get_next_completion(h);
+	while (raw_tag != FIFO_EMPTY) {
+		if (hpsa_tag_contains_index(raw_tag))
+			raw_tag = process_indexed_cmd(h, raw_tag);
+		else
+			raw_tag = process_nonindexed_cmd(h, raw_tag);
 	}
 	spin_unlock_irqrestore(&h->lock, flags);
 	return IRQ_HANDLED;
@@ -2841,7 +2996,7 @@ static __devinit int hpsa_message(struct
 
 	for (i = 0; i < HPSA_MSG_SEND_RETRY_LIMIT; i++) {
 		tag = readl(vaddr + SA5_REPLY_PORT_OFFSET);
-		if (HPSA_TAG_DISCARD_ERROR_BITS(tag) == paddr32)
+		if (hpsa_tag_discard_error_bits(tag) == paddr32)
 			break;
 		msleep(HPSA_MSG_SEND_RETRY_INTERVAL_MSECS);
 	}
@@ -3063,7 +3218,7 @@ static int find_PCI_BAR_index(struct pci
  */
 
 static void __devinit hpsa_interrupt_mode(struct ctlr_info *h,
-					   struct pci_dev *pdev, __u32 board_id)
+					   struct pci_dev *pdev, u32 board_id)
 {
 #ifdef CONFIG_PCI_MSI
 	int err;
@@ -3107,22 +3262,22 @@ static void __devinit hpsa_interrupt_mod
 default_int_mode:
 #endif				/* CONFIG_PCI_MSI */
 	/* if we get here we're going to use the default interrupt mode */
-	h->intr[SIMPLE_MODE_INT] = pdev->irq;
-	return;
+	h->intr[PERF_MODE_INT] = pdev->irq;
 }
 
-static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
+static int __devinit hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
 {
 	ushort subsystem_vendor_id, subsystem_device_id, command;
-	__u32 board_id, scratchpad = 0;
-	__u64 cfg_offset;
-	__u32 cfg_base_addr;
-	__u64 cfg_base_addr_index;
+	u32 board_id, scratchpad = 0;
+	u64 cfg_offset;
+	u32 cfg_base_addr;
+	u64 cfg_base_addr_index;
+	u32 trans_offset;
 	int i, prod_index, err;
 
 	subsystem_vendor_id = pdev->subsystem_vendor;
 	subsystem_device_id = pdev->subsystem_device;
-	board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) |
+	board_id = (((u32) (subsystem_device_id << 16) & 0xffff0000) |
 		    subsystem_vendor_id);
 
 	for (i = 0; i < ARRAY_SIZE(products); i++)
@@ -3199,7 +3354,7 @@ static int hpsa_pci_init(struct ctlr_inf
 
 	/* get the address index number */
 	cfg_base_addr = readl(h->vaddr + SA5_CTCFG_OFFSET);
-	cfg_base_addr &= (__u32) 0x0000ffff;
+	cfg_base_addr &= (u32) 0x0000ffff;
 	cfg_base_addr_index = find_PCI_BAR_index(pdev, cfg_base_addr);
 	if (cfg_base_addr_index == -1) {
 		dev_warn(&pdev->dev, "cannot find cfg_base_addr_index\n");
@@ -3211,10 +3366,30 @@ static int hpsa_pci_init(struct ctlr_inf
 	h->cfgtable = remap_pci_mem(pci_resource_start(pdev,
 			       cfg_base_addr_index) + cfg_offset,
 				sizeof(h->cfgtable));
+	/* Find performant mode table. */
+	trans_offset = readl(&(h->cfgtable->TransMethodOffset));
+	h->transtable = remap_pci_mem(pci_resource_start(pdev,
+				cfg_base_addr_index)+cfg_offset+trans_offset,
+				sizeof(*h->transtable));
+
 	h->board_id = board_id;
+	h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
+	h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements));
 
-	/* Query controller for max supported commands: */
-	h->max_commands = readl(&(h->cfgtable->CmdsOutMax));
+	/*
+	 * Limit in-command s/g elements to 32 save dma'able memory.
+	 * Howvever spec says if 0, use 31
+	 */
+
+	h->max_cmd_sg_entries = 31;
+	if (h->maxsgentries > 512) {
+		h->max_cmd_sg_entries = 32;
+		h->chainsize = h->maxsgentries - h->max_cmd_sg_entries + 1;
+		h->maxsgentries--; /* save one for chain pointer */
+	} else {
+		h->maxsgentries = 31; /* default to traditional values */
+		h->chainsize = 0;
+	}
 
 	h->product_name = products[prod_index].product_name;
 	h->access = *(products[prod_index].access);
@@ -3232,7 +3407,7 @@ static int hpsa_pci_init(struct ctlr_inf
 #ifdef CONFIG_X86
 	{
 		/* Need to enable prefetch in the SCSI core for 6400 in x86 */
-		__u32 prefetch;
+		u32 prefetch;
 		prefetch = readl(&(h->cfgtable->SCSI_Prefetch));
 		prefetch |= 0x100;
 		writel(prefetch, &(h->cfgtable->SCSI_Prefetch));
@@ -3244,7 +3419,7 @@ static int hpsa_pci_init(struct ctlr_inf
 	 * physical memory.
 	 */
 	if (board_id == 0x3225103C) {
-		__u32 dma_prefetch;
+		u32 dma_prefetch;
 		dma_prefetch = readl(h->vaddr + I2O_DMA1_CFG);
 		dma_prefetch |= 0x8000;
 		writel(dma_prefetch, h->vaddr + I2O_DMA1_CFG);
@@ -3286,10 +3461,26 @@ err_out_free_res:
 	return err;
 }
 
+static void __devinit hpsa_hba_inquiry(struct ctlr_info *h)
+{
+	int rc;
+
+#define HBA_INQUIRY_BYTE_COUNT 64
+	h->hba_inquiry_data = kmalloc(HBA_INQUIRY_BYTE_COUNT, GFP_KERNEL);
+	if (!h->hba_inquiry_data)
+		return;
+	rc = hpsa_scsi_do_inquiry(h, RAID_CTLR_LUNID, 0,
+		h->hba_inquiry_data, HBA_INQUIRY_BYTE_COUNT);
+	if (rc != 0) {
+		kfree(h->hba_inquiry_data);
+		h->hba_inquiry_data = NULL;
+	}
+}
+
 static int __devinit hpsa_init_one(struct pci_dev *pdev,
 				    const struct pci_device_id *ent)
 {
-	int i;
+	int i, rc;
 	int dac;
 	struct ctlr_info *h;
 
@@ -3314,17 +3505,21 @@ static int __devinit hpsa_init_one(struc
 		}
 	}
 
-	BUILD_BUG_ON(sizeof(struct CommandList) % 8);
+	/* Command structures must be aligned on a 32-byte boundary because
+	 * the 5 lower bits of the address are used by the hardware. and by
+	 * the driver.  See comments in hpsa.h for more info.
+	 */
+#define COMMANDLIST_ALIGNMENT 32
+	BUILD_BUG_ON(sizeof(struct CommandList) % COMMANDLIST_ALIGNMENT);
 	h = kzalloc(sizeof(*h), GFP_KERNEL);
 	if (!h)
-		return -1;
+		return -ENOMEM;
 
 	h->busy_initializing = 1;
 	INIT_HLIST_HEAD(&h->cmpQ);
 	INIT_HLIST_HEAD(&h->reqQ);
-	mutex_init(&h->busy_shutting_down);
-	init_completion(&h->scan_wait);
-	if (hpsa_pci_init(h, pdev) != 0)
+	rc = hpsa_pci_init(h, pdev);
+	if (rc != 0)
 		goto clean1;
 
 	sprintf(h->devname, "hpsa%d", number_of_controllers);
@@ -3333,27 +3528,32 @@ static int __devinit hpsa_init_one(struc
 	h->pdev = pdev;
 
 	/* configure PCI DMA stuff */
-	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
+	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+	if (rc == 0) {
 		dac = 1;
-	else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
-		dac = 0;
-	else {
-		dev_err(&pdev->dev, "no suitable DMA available\n");
-		goto clean1;
+	} else {
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+		if (rc == 0) {
+			dac = 0;
+		} else {
+			dev_err(&pdev->dev, "no suitable DMA available\n");
+			goto clean1;
+		}
 	}
 
 	/* make sure the board interrupts are off */
 	h->access.set_intr_mask(h, HPSA_INTR_OFF);
-	if (request_irq(h->intr[SIMPLE_MODE_INT], do_hpsa_intr,
-			IRQF_DISABLED | IRQF_SHARED, h->devname, h)) {
+	rc = request_irq(h->intr[PERF_MODE_INT], do_hpsa_intr,
+			IRQF_DISABLED, h->devname, h);
+	if (rc) {
 		dev_err(&pdev->dev, "unable to get irq %d for %s\n",
-		       h->intr[SIMPLE_MODE_INT], h->devname);
+		       h->intr[PERF_MODE_INT], h->devname);
 		goto clean2;
 	}
 
-	dev_info(&pdev->dev, "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n",
-	       h->devname, pdev->device, pci_name(pdev),
-	       h->intr[SIMPLE_MODE_INT], dac ? "" : " not");
+	dev_info(&pdev->dev, "%s: <0x%x> at IRQ %d%s using DAC\n",
+	       h->devname, pdev->device,
+	       h->intr[PERF_MODE_INT], dac ? "" : " not");
 
 	h->cmd_pool_bits =
 	    kmalloc(((h->nr_cmds + BITS_PER_LONG -
@@ -3368,9 +3568,15 @@ static int __devinit hpsa_init_one(struc
 	    || (h->cmd_pool == NULL)
 	    || (h->errinfo_pool == NULL)) {
 		dev_err(&pdev->dev, "out of memory");
+		rc = -ENOMEM;
 		goto clean4;
 	}
+	if (hpsa_allocate_sg_chain_blocks(h))
+		goto clean4;
 	spin_lock_init(&h->lock);
+	spin_lock_init(&h->scan_lock);
+	init_waitqueue_head(&h->scan_wait_queue);
+	h->scan_finished = 1; /* no scan currently in progress */
 
 	pci_set_drvdata(pdev, h);
 	memset(h->cmd_pool_bits, 0,
@@ -3382,11 +3588,14 @@ static int __devinit hpsa_init_one(struc
 	/* Turn the interrupts on so we can service requests */
 	h->access.set_intr_mask(h, HPSA_INTR_ON);
 
+	hpsa_put_ctlr_into_performant_mode(h);
+	hpsa_hba_inquiry(h);
 	hpsa_register_scsi(h);	/* hook ourselves into SCSI subsystem */
 	h->busy_initializing = 0;
 	return 1;
 
 clean4:
+	hpsa_free_sg_chain_blocks(h);
 	kfree(h->cmd_pool_bits);
 	if (h->cmd_pool)
 		pci_free_consistent(h->pdev,
@@ -3397,12 +3606,12 @@ clean4:
 			    h->nr_cmds * sizeof(struct ErrorInfo),
 			    h->errinfo_pool,
 			    h->errinfo_pool_dhandle);
-	free_irq(h->intr[SIMPLE_MODE_INT], h);
+	free_irq(h->intr[PERF_MODE_INT], h);
 clean2:
 clean1:
 	h->busy_initializing = 0;
 	kfree(h);
-	return -1;
+	return rc;
 }
 
 static void hpsa_flush_cache(struct ctlr_info *h)
@@ -3441,7 +3650,7 @@ static void hpsa_shutdown(struct pci_dev
 	 */
 	hpsa_flush_cache(h);
 	h->access.set_intr_mask(h, HPSA_INTR_OFF);
-	free_irq(h->intr[2], h);
+	free_irq(h->intr[PERF_MODE_INT], h);
 #ifdef CONFIG_PCI_MSI
 	if (h->msix_vector)
 		pci_disable_msix(h->pdev);
@@ -3459,25 +3668,27 @@ static void __devexit hpsa_remove_one(st
 		return;
 	}
 	h = pci_get_drvdata(pdev);
-	mutex_lock(&h->busy_shutting_down);
-	remove_from_scan_list(h);
 	hpsa_unregister_scsi(h);	/* unhook from SCSI subsystem */
 	hpsa_shutdown(pdev);
 	iounmap(h->vaddr);
+	hpsa_free_sg_chain_blocks(h);
 	pci_free_consistent(h->pdev,
 		h->nr_cmds * sizeof(struct CommandList),
 		h->cmd_pool, h->cmd_pool_dhandle);
 	pci_free_consistent(h->pdev,
 		h->nr_cmds * sizeof(struct ErrorInfo),
 		h->errinfo_pool, h->errinfo_pool_dhandle);
+	pci_free_consistent(h->pdev, h->reply_pool_size,
+		h->reply_pool, h->reply_pool_dhandle);
 	kfree(h->cmd_pool_bits);
+	kfree(h->blockFetchTable);
+	kfree(h->hba_inquiry_data);
 	/*
 	 * Deliberately omit pci_disable_device(): it does something nasty to
 	 * Smart Array controllers that pci_enable_device does not undo
 	 */
 	pci_release_regions(pdev);
 	pci_set_drvdata(pdev, NULL);
-	mutex_unlock(&h->busy_shutting_down);
 	kfree(h);
 }
 
@@ -3502,29 +3713,141 @@ static struct pci_driver hpsa_pci_driver
 	.resume = hpsa_resume,
 };
 
+/* Fill in bucket_map[], given nsgs (the max number of
+ * scatter gather elements supported) and bucket[],
+ * which is an array of 8 integers.  The bucket[] array
+ * contains 8 different DMA transfer sizes (in 16
+ * byte increments) which the controller uses to fetch
+ * commands.  This function fills in bucket_map[], which
+ * maps a given number of scatter gather elements to one of
+ * the 8 DMA transfer sizes.  The point of it is to allow the
+ * controller to only do as much DMA as needed to fetch the
+ * command, with the DMA transfer size encoded in the lower
+ * bits of the command address.
+ */
+static void  calc_bucket_map(int bucket[], int num_buckets,
+	int nsgs, int *bucket_map)
+{
+	int i, j, b, size;
+
+	/* even a command with 0 SGs requires 4 blocks */
+#define MINIMUM_TRANSFER_BLOCKS 4
+#define NUM_BUCKETS 8
+	/* Note, bucket_map must have nsgs+1 entries. */
+	for (i = 0; i <= nsgs; i++) {
+		/* Compute size of a command with i SG entries */
+		size = i + MINIMUM_TRANSFER_BLOCKS;
+		b = num_buckets; /* Assume the biggest bucket */
+		/* Find the bucket that is just big enough */
+		for (j = 0; j < 8; j++) {
+			if (bucket[j] >= size) {
+				b = j;
+				break;
+			}
+		}
+		/* for a command with i SG entries, use bucket b. */
+		bucket_map[i] = b;
+	}
+}
+
+static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h)
+{
+	u32 trans_support;
+	u64 trans_offset;
+	/*  5 = 1 s/g entry or 4k
+	 *  6 = 2 s/g entry or 8k
+	 *  8 = 4 s/g entry or 16k
+	 * 10 = 6 s/g entry or 24k
+	 */
+	int bft[8] = {5, 6, 8, 10, 12, 20, 28, 35}; /* for scatter/gathers */
+	int i = 0;
+	int l = 0;
+	unsigned long register_value;
+
+	trans_support = readl(&(h->cfgtable->TransportSupport));
+	if (!(trans_support & PERFORMANT_MODE))
+		return;
+
+	h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
+	h->max_sg_entries = 32;
+	/* Performant mode ring buffer and supporting data structures */
+	h->reply_pool_size = h->max_commands * sizeof(u64);
+	h->reply_pool = pci_alloc_consistent(h->pdev, h->reply_pool_size,
+				&(h->reply_pool_dhandle));
+
+	/* Need a block fetch table for performant mode */
+	h->blockFetchTable = kmalloc(((h->max_sg_entries+1) *
+				sizeof(u32)), GFP_KERNEL);
+
+	if ((h->reply_pool == NULL)
+		|| (h->blockFetchTable == NULL))
+		goto clean_up;
+
+	h->reply_pool_wraparound = 1; /* spec: init to 1 */
+
+	/* Controller spec: zero out this buffer. */
+	memset(h->reply_pool, 0, h->reply_pool_size);
+	h->reply_pool_head = h->reply_pool;
+
+	trans_offset = readl(&(h->cfgtable->TransMethodOffset));
+	bft[7] = h->max_sg_entries + 4;
+	calc_bucket_map(bft, ARRAY_SIZE(bft), 32, h->blockFetchTable);
+	for (i = 0; i < 8; i++)
+		writel(bft[i], &h->transtable->BlockFetch[i]);
+
+	/* size of controller ring buffer */
+	writel(h->max_commands, &h->transtable->RepQSize);
+	writel(1, &h->transtable->RepQCount);
+	writel(0, &h->transtable->RepQCtrAddrLow32);
+	writel(0, &h->transtable->RepQCtrAddrHigh32);
+	writel(h->reply_pool_dhandle, &h->transtable->RepQAddr0Low32);
+	writel(0, &h->transtable->RepQAddr0High32);
+	writel(CFGTBL_Trans_Performant,
+		&(h->cfgtable->HostWrite.TransportRequest));
+	writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
+	/* under certain very rare conditions, this can take awhile.
+	 * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right
+	 * as we enter this code.) */
+	for (l = 0; l < MAX_CONFIG_WAIT; l++) {
+		register_value = readl(h->vaddr + SA5_DOORBELL);
+		if (!(register_value & CFGTBL_ChangeReq))
+			break;
+		/* delay and try again */
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(10);
+	}
+	register_value = readl(&(h->cfgtable->TransportActive));
+	if (!(register_value & CFGTBL_Trans_Performant)) {
+		dev_warn(&h->pdev->dev, "unable to get board into"
+					" performant mode\n");
+		return;
+	}
+
+	/* Change the access methods to the performant access methods */
+	h->access = SA5_performant_access;
+	h->transMethod = CFGTBL_Trans_Performant;
+
+	return;
+
+clean_up:
+	if (h->reply_pool)
+		pci_free_consistent(h->pdev, h->reply_pool_size,
+			h->reply_pool, h->reply_pool_dhandle);
+	kfree(h->blockFetchTable);
+}
+
 /*
  *  This is it.  Register the PCI driver information for the cards we control
  *  the OS will call our registered routines when it finds one of our cards.
  */
 static int __init hpsa_init(void)
 {
-	int err;
-	/* Start the scan thread */
-	hpsa_scan_thread = kthread_run(hpsa_scan_func, NULL, "hpsa_scan");
-	if (IS_ERR(hpsa_scan_thread)) {
-		err = PTR_ERR(hpsa_scan_thread);
-		return -ENODEV;
-	}
-	err = pci_register_driver(&hpsa_pci_driver);
-	if (err)
-		kthread_stop(hpsa_scan_thread);
-	return err;
+	return pci_register_driver(&hpsa_pci_driver);
 }
 
 static void __exit hpsa_cleanup(void)
 {
 	pci_unregister_driver(&hpsa_pci_driver);
-	kthread_stop(hpsa_scan_thread);
 }
 
 module_init(hpsa_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/hpsa_cmd.h linux-libre-2.6.34-gnu1/drivers/scsi/hpsa_cmd.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/hpsa_cmd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/hpsa_cmd.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,8 @@
 
 /* general boundary defintions */
 #define SENSEINFOBYTES          32 /* may vary between hbas */
-#define MAXSGENTRIES            31
+#define MAXSGENTRIES            32
+#define HPSA_SG_CHAIN		0x80000000
 #define MAXREPLYQS              256
 
 /* Command Status value */
@@ -101,19 +102,20 @@
 #define CFGTBL_AccCmds          0x00000001l
 
 #define CFGTBL_Trans_Simple     0x00000002l
+#define CFGTBL_Trans_Performant 0x00000004l
 
 #define CFGTBL_BusType_Ultra2   0x00000001l
 #define CFGTBL_BusType_Ultra3   0x00000002l
 #define CFGTBL_BusType_Fibre1G  0x00000100l
 #define CFGTBL_BusType_Fibre2G  0x00000200l
 struct vals32 {
-	__u32   lower;
-	__u32   upper;
+	u32   lower;
+	u32   upper;
 };
 
 union u64bit {
 	struct vals32 val32;
-	__u64 val;
+	u64 val;
 };
 
 /* FIXME this is a per controller value (barf!) */
@@ -126,34 +128,34 @@ union u64bit {
 
 #define HPSA_INQUIRY 0x12
 struct InquiryData {
-	__u8 data_byte[36];
+	u8 data_byte[36];
 };
 
 #define HPSA_REPORT_LOG 0xc2    /* Report Logical LUNs */
 #define HPSA_REPORT_PHYS 0xc3   /* Report Physical LUNs */
 struct ReportLUNdata {
-	__u8 LUNListLength[4];
-	__u32 reserved;
-	__u8 LUN[HPSA_MAX_LUN][8];
+	u8 LUNListLength[4];
+	u32 reserved;
+	u8 LUN[HPSA_MAX_LUN][8];
 };
 
 struct ReportExtendedLUNdata {
-	__u8 LUNListLength[4];
-	__u8 extended_response_flag;
-	__u8 reserved[3];
-	__u8 LUN[HPSA_MAX_LUN][24];
+	u8 LUNListLength[4];
+	u8 extended_response_flag;
+	u8 reserved[3];
+	u8 LUN[HPSA_MAX_LUN][24];
 };
 
 struct SenseSubsystem_info {
-	__u8 reserved[36];
-	__u8 portname[8];
-	__u8 reserved1[1108];
+	u8 reserved[36];
+	u8 portname[8];
+	u8 reserved1[1108];
 };
 
 #define HPSA_READ_CAPACITY 0x25 /* Read Capacity */
 struct ReadCapdata {
-	__u8 total_size[4];	/* Total size in blocks */
-	__u8 block_size[4];	/* Size of blocks in bytes */
+	u8 total_size[4];	/* Total size in blocks */
+	u8 block_size[4];	/* Size of blocks in bytes */
 };
 
 #if 0
@@ -174,152 +176,202 @@ struct ReadCapdata {
 /* Command List Structure */
 union SCSI3Addr {
 	struct {
-		__u8 Dev;
-		__u8 Bus:6;
-		__u8 Mode:2;        /* b00 */
+		u8 Dev;
+		u8 Bus:6;
+		u8 Mode:2;        /* b00 */
 	} PeripDev;
 	struct {
-		__u8 DevLSB;
-		__u8 DevMSB:6;
-		__u8 Mode:2;        /* b01 */
+		u8 DevLSB;
+		u8 DevMSB:6;
+		u8 Mode:2;        /* b01 */
 	} LogDev;
 	struct {
-		__u8 Dev:5;
-		__u8 Bus:3;
-		__u8 Targ:6;
-		__u8 Mode:2;        /* b10 */
+		u8 Dev:5;
+		u8 Bus:3;
+		u8 Targ:6;
+		u8 Mode:2;        /* b10 */
 	} LogUnit;
 };
 
 struct PhysDevAddr {
-	__u32             TargetId:24;
-	__u32             Bus:6;
-	__u32             Mode:2;
+	u32             TargetId:24;
+	u32             Bus:6;
+	u32             Mode:2;
 	/* 2 level target device addr */
 	union SCSI3Addr  Target[2];
 };
 
 struct LogDevAddr {
-	__u32            VolId:30;
-	__u32            Mode:2;
-	__u8             reserved[4];
+	u32            VolId:30;
+	u32            Mode:2;
+	u8             reserved[4];
 };
 
 union LUNAddr {
-	__u8               LunAddrBytes[8];
+	u8               LunAddrBytes[8];
 	union SCSI3Addr    SCSI3Lun[4];
 	struct PhysDevAddr PhysDev;
 	struct LogDevAddr  LogDev;
 };
 
 struct CommandListHeader {
-	__u8              ReplyQueue;
-	__u8              SGList;
-	__u16             SGTotal;
+	u8              ReplyQueue;
+	u8              SGList;
+	u16             SGTotal;
 	struct vals32     Tag;
 	union LUNAddr     LUN;
 };
 
 struct RequestBlock {
-	__u8   CDBLen;
+	u8   CDBLen;
 	struct {
-		__u8 Type:3;
-		__u8 Attribute:3;
-		__u8 Direction:2;
+		u8 Type:3;
+		u8 Attribute:3;
+		u8 Direction:2;
 	} Type;
-	__u16  Timeout;
-	__u8   CDB[16];
+	u16  Timeout;
+	u8   CDB[16];
 };
 
 struct ErrDescriptor {
 	struct vals32 Addr;
-	__u32  Len;
+	u32  Len;
 };
 
 struct SGDescriptor {
 	struct vals32 Addr;
-	__u32  Len;
-	__u32  Ext;
+	u32  Len;
+	u32  Ext;
 };
 
 union MoreErrInfo {
 	struct {
-		__u8  Reserved[3];
-		__u8  Type;
-		__u32 ErrorInfo;
+		u8  Reserved[3];
+		u8  Type;
+		u32 ErrorInfo;
 	} Common_Info;
 	struct {
-		__u8  Reserved[2];
-		__u8  offense_size; /* size of offending entry */
-		__u8  offense_num;  /* byte # of offense 0-base */
-		__u32 offense_value;
+		u8  Reserved[2];
+		u8  offense_size; /* size of offending entry */
+		u8  offense_num;  /* byte # of offense 0-base */
+		u32 offense_value;
 	} Invalid_Cmd;
 };
 struct ErrorInfo {
-	__u8               ScsiStatus;
-	__u8               SenseLen;
-	__u16              CommandStatus;
-	__u32              ResidualCnt;
+	u8               ScsiStatus;
+	u8               SenseLen;
+	u16              CommandStatus;
+	u32              ResidualCnt;
 	union MoreErrInfo  MoreErrInfo;
-	__u8               SenseInfo[SENSEINFOBYTES];
+	u8               SenseInfo[SENSEINFOBYTES];
 };
 /* Command types */
 #define CMD_IOCTL_PEND  0x01
 #define CMD_SCSI	0x03
 
+/* This structure needs to be divisible by 32 for new
+ * indexing method and performant mode.
+ */
+#define PAD32 32
+#define PAD64DIFF 0
+#define USEEXTRA ((sizeof(void *) - 4)/4)
+#define PADSIZE (PAD32 + PAD64DIFF * USEEXTRA)
+
+#define DIRECT_LOOKUP_SHIFT 5
+#define DIRECT_LOOKUP_BIT 0x10
+
+#define HPSA_ERROR_BIT          0x02
 struct ctlr_info; /* defined in hpsa.h */
-/* The size of this structure needs to be divisible by 8
- * od on all architectures, because the controller uses 2
- * lower bits of the address, and the driver uses 1 lower
- * bit (3 bits total.)
+/* The size of this structure needs to be divisible by 32
+ * on all architectures because low 5 bits of the addresses
+ * are used as follows:
+ *
+ * bit 0: to device, used to indicate "performant mode" command
+ *        from device, indidcates error status.
+ * bit 1-3: to device, indicates block fetch table entry for
+ *          reducing DMA in fetching commands from host memory.
+ * bit 4: used to indicate whether tag is "direct lookup" (index),
+ *        or a bus address.
  */
+
 struct CommandList {
 	struct CommandListHeader Header;
 	struct RequestBlock      Request;
 	struct ErrDescriptor     ErrDesc;
 	struct SGDescriptor      SG[MAXSGENTRIES];
 	/* information associated with the command */
-	__u32			   busaddr; /* physical addr of this record */
+	u32			   busaddr; /* physical addr of this record */
 	struct ErrorInfo *err_info; /* pointer to the allocated mem */
 	struct ctlr_info	   *h;
 	int			   cmd_type;
 	long			   cmdindex;
 	struct hlist_node list;
-	struct CommandList *prev;
-	struct CommandList *next;
 	struct request *rq;
 	struct completion *waiting;
-	int	 retry_count;
 	void   *scsi_cmd;
+
+/* on 64 bit architectures, to get this to be 32-byte-aligned
+ * it so happens we need PAD_64 bytes of padding, on 32 bit systems,
+ * we need PAD_32 bytes of padding (see below).   This does that.
+ * If it happens that 64 bit and 32 bit systems need different
+ * padding, PAD_32 and PAD_64 can be set independently, and.
+ * the code below will do the right thing.
+ */
+#define IS_32_BIT ((8 - sizeof(long))/4)
+#define IS_64_BIT (!IS_32_BIT)
+#define PAD_32 (4)
+#define PAD_64 (4)
+#define COMMANDLIST_PAD (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64)
+	u8 pad[COMMANDLIST_PAD];
 };
 
 /* Configuration Table Structure */
 struct HostWrite {
-	__u32 TransportRequest;
-	__u32 Reserved;
-	__u32 CoalIntDelay;
-	__u32 CoalIntCount;
+	u32 TransportRequest;
+	u32 Reserved;
+	u32 CoalIntDelay;
+	u32 CoalIntCount;
 };
 
+#define SIMPLE_MODE     0x02
+#define PERFORMANT_MODE 0x04
+#define MEMQ_MODE       0x08
+
 struct CfgTable {
-	__u8             Signature[4];
-	__u32            SpecValence;
-	__u32            TransportSupport;
-	__u32            TransportActive;
-	struct HostWrite HostWrite;
-	__u32            CmdsOutMax;
-	__u32            BusTypes;
-	__u32            Reserved;
-	__u8             ServerName[16];
-	__u32            HeartBeat;
-	__u32            SCSI_Prefetch;
+	u8            Signature[4];
+	u32		SpecValence;
+	u32           TransportSupport;
+	u32           TransportActive;
+	struct 		HostWrite HostWrite;
+	u32           CmdsOutMax;
+	u32           BusTypes;
+	u32           TransMethodOffset;
+	u8            ServerName[16];
+	u32           HeartBeat;
+	u32           SCSI_Prefetch;
+	u32	 	MaxScatterGatherElements;
+	u32		MaxLogicalUnits;
+	u32		MaxPhysicalDevices;
+	u32		MaxPhysicalDrivesPerLogicalUnit;
+	u32		MaxPerformantModeCommands;
+};
+
+#define NUM_BLOCKFETCH_ENTRIES 8
+struct TransTable_struct {
+	u32            BlockFetch[NUM_BLOCKFETCH_ENTRIES];
+	u32            RepQSize;
+	u32            RepQCount;
+	u32            RepQCtrAddrLow32;
+	u32            RepQCtrAddrHigh32;
+	u32            RepQAddr0Low32;
+	u32            RepQAddr0High32;
 };
 
 struct hpsa_pci_info {
 	unsigned char	bus;
 	unsigned char	dev_fn;
 	unsigned short	domain;
-	__u32		board_id;
+	u32		board_id;
 };
 
 #pragma pack()
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/hpsa.h linux-libre-2.6.34-gnu1/drivers/scsi/hpsa.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/hpsa.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/hpsa.h	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,7 @@ struct access_method {
 		struct CommandList *c);
 	void (*set_intr_mask)(struct ctlr_info *h, unsigned long val);
 	unsigned long (*fifo_full)(struct ctlr_info *h);
-	unsigned long (*intr_pending)(struct ctlr_info *h);
+	bool (*intr_pending)(struct ctlr_info *h);
 	unsigned long (*command_completed)(struct ctlr_info *h);
 };
 
@@ -55,19 +55,20 @@ struct ctlr_info {
 	char    *product_name;
 	char	firm_ver[4]; /* Firmware version */
 	struct pci_dev *pdev;
-	__u32	board_id;
+	u32	board_id;
 	void __iomem *vaddr;
 	unsigned long paddr;
 	int 	nr_cmds; /* Number of commands allowed on this controller */
 	struct CfgTable __iomem *cfgtable;
+	int     max_sg_entries;
 	int	interrupts_enabled;
 	int	major;
 	int 	max_commands;
 	int	commands_outstanding;
 	int 	max_outstanding; /* Debug */
 	int	usage_count;  /* number of opens all all minor devices */
-#	define DOORBELL_INT	0
-#	define PERF_MODE_INT	1
+#	define PERF_MODE_INT	0
+#	define DOORBELL_INT	1
 #	define SIMPLE_MODE_INT	2
 #	define MEMQ_MODE_INT	3
 	unsigned int intr[4];
@@ -82,6 +83,10 @@ struct ctlr_info {
 	unsigned int maxQsinceinit;
 	unsigned int maxSG;
 	spinlock_t lock;
+	int maxsgentries;
+	u8 max_cmd_sg_entries;
+	int chainsize;
+	struct SGDescriptor **cmd_sg_list;
 
 	/* pointers to command and error info pool */
 	struct CommandList 	*cmd_pool;
@@ -93,15 +98,33 @@ struct ctlr_info {
 	int			nr_frees;
 	int			busy_initializing;
 	int			busy_scanning;
-	struct mutex		busy_shutting_down;
-	struct list_head	scan_list;
-	struct completion	scan_wait;
+	int			scan_finished;
+	spinlock_t		scan_lock;
+	wait_queue_head_t	scan_wait_queue;
 
 	struct Scsi_Host *scsi_host;
 	spinlock_t devlock; /* to protect hba[ctlr]->dev[];  */
 	int ndevices; /* number of used elements in .dev[] array. */
 #define HPSA_MAX_SCSI_DEVS_PER_HBA 256
 	struct hpsa_scsi_dev_t *dev[HPSA_MAX_SCSI_DEVS_PER_HBA];
+	/*
+	 * Performant mode tables.
+	 */
+	u32 trans_support;
+	u32 trans_offset;
+	struct TransTable_struct *transtable;
+	unsigned long transMethod;
+
+	/*
+	 * Performant mode completion buffer
+	 */
+	u64 *reply_pool;
+	dma_addr_t reply_pool_dhandle;
+	u64 *reply_pool_head;
+	size_t reply_pool_size;
+	unsigned char reply_pool_wraparound;
+	u32 *blockFetchTable;
+	unsigned char *hba_inquiry_data;
 };
 #define HPSA_ABORT_MSG 0
 #define HPSA_DEVICE_RESET_MSG 1
@@ -164,9 +187,16 @@ struct ctlr_info {
 #define HPSA_FIRMWARE_READY	0xffff0000 /* value in scratchpad register */
 
 #define HPSA_ERROR_BIT		0x02
-#define HPSA_TAG_CONTAINS_INDEX(tag) ((tag) & 0x04)
-#define HPSA_TAG_TO_INDEX(tag) ((tag) >> 3)
-#define HPSA_TAG_DISCARD_ERROR_BITS(tag) ((tag) & ~3)
+
+/* Performant mode flags */
+#define SA5_PERF_INTR_PENDING   0x04
+#define SA5_PERF_INTR_OFF       0x05
+#define SA5_OUTDB_STATUS_PERF_BIT       0x01
+#define SA5_OUTDB_CLEAR_PERF_BIT        0x01
+#define SA5_OUTDB_CLEAR         0xA0
+#define SA5_OUTDB_CLEAR_PERF_BIT        0x01
+#define SA5_OUTDB_STATUS        0x9C
+
 
 #define HPSA_INTR_ON 	1
 #define HPSA_INTR_OFF	0
@@ -176,10 +206,8 @@ struct ctlr_info {
 static void SA5_submit_command(struct ctlr_info *h,
 	struct CommandList *c)
 {
-#ifdef HPSA_DEBUG
-	 printk(KERN_WARNING "hpsa: Sending %x - down to controller\n",
-		c->busaddr);
-#endif /* HPSA_DEBUG */
+	dev_dbg(&h->pdev->dev, "Sending %x, tag = %x\n", c->busaddr,
+		c->Header.Tag.lower);
 	writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
 	h->commands_outstanding++;
 	if (h->commands_outstanding > h->max_outstanding)
@@ -202,6 +230,52 @@ static void SA5_intr_mask(struct ctlr_in
 			h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 	}
 }
+
+static void SA5_performant_intr_mask(struct ctlr_info *h, unsigned long val)
+{
+	if (val) { /* turn on interrupts */
+		h->interrupts_enabled = 1;
+		writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+	} else {
+		h->interrupts_enabled = 0;
+		writel(SA5_PERF_INTR_OFF,
+			h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+	}
+}
+
+static unsigned long SA5_performant_completed(struct ctlr_info *h)
+{
+	unsigned long register_value = FIFO_EMPTY;
+
+	/* flush the controller write of the reply queue by reading
+	 * outbound doorbell status register.
+	 */
+	register_value = readl(h->vaddr + SA5_OUTDB_STATUS);
+	/* msi auto clears the interrupt pending bit. */
+	if (!(h->msi_vector || h->msix_vector)) {
+		writel(SA5_OUTDB_CLEAR_PERF_BIT, h->vaddr + SA5_OUTDB_CLEAR);
+		/* Do a read in order to flush the write to the controller
+		 * (as per spec.)
+		 */
+		register_value = readl(h->vaddr + SA5_OUTDB_STATUS);
+	}
+
+	if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) {
+		register_value = *(h->reply_pool_head);
+		(h->reply_pool_head)++;
+		h->commands_outstanding--;
+	} else {
+		register_value = FIFO_EMPTY;
+	}
+	/* Check for wraparound */
+	if (h->reply_pool_head == (h->reply_pool + h->max_commands)) {
+		h->reply_pool_head = h->reply_pool;
+		h->reply_pool_wraparound ^= 1;
+	}
+
+	return register_value;
+}
+
 /*
  *  Returns true if fifo is full.
  *
@@ -228,10 +302,10 @@ static unsigned long SA5_completed(struc
 
 #ifdef HPSA_DEBUG
 	if (register_value != FIFO_EMPTY)
-		printk(KERN_INFO "hpsa:  Read %lx back from board\n",
+		dev_dbg(&h->pdev->dev, "Read %lx back from board\n",
 			register_value);
 	else
-		printk(KERN_INFO "hpsa:  FIFO Empty read\n");
+		dev_dbg(&h->pdev->dev, "hpsa: FIFO Empty read\n");
 #endif
 
 	return register_value;
@@ -239,18 +313,28 @@ static unsigned long SA5_completed(struc
 /*
  *	Returns true if an interrupt is pending..
  */
-static unsigned long SA5_intr_pending(struct ctlr_info *h)
+static bool SA5_intr_pending(struct ctlr_info *h)
 {
 	unsigned long register_value  =
 		readl(h->vaddr + SA5_INTR_STATUS);
-#ifdef HPSA_DEBUG
-	printk(KERN_INFO "hpsa: intr_pending %lx\n", register_value);
-#endif  /* HPSA_DEBUG */
-	if (register_value &  SA5_INTR_PENDING)
-		return  1;
-	return 0 ;
+	dev_dbg(&h->pdev->dev, "intr_pending %lx\n", register_value);
+	return register_value & SA5_INTR_PENDING;
 }
 
+static bool SA5_performant_intr_pending(struct ctlr_info *h)
+{
+	unsigned long register_value = readl(h->vaddr + SA5_INTR_STATUS);
+
+	if (!register_value)
+		return false;
+
+	if (h->msi_vector || h->msix_vector)
+		return true;
+
+	/* Read outbound doorbell to flush */
+	register_value = readl(h->vaddr + SA5_OUTDB_STATUS);
+	return register_value & SA5_OUTDB_STATUS_PERF_BIT;
+}
 
 static struct access_method SA5_access = {
 	SA5_submit_command,
@@ -260,14 +344,19 @@ static struct access_method SA5_access =
 	SA5_completed,
 };
 
+static struct access_method SA5_performant_access = {
+	SA5_submit_command,
+	SA5_performant_intr_mask,
+	SA5_fifo_full,
+	SA5_performant_intr_pending,
+	SA5_performant_completed,
+};
+
 struct board_type {
-	__u32	board_id;
+	u32	board_id;
 	char	*product_name;
 	struct access_method *access;
 };
 
-
-/* end of old hpsa_scsi.h file */
-
 #endif /* HPSA_H */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/hptiop.c linux-libre-2.6.34-gnu1/drivers/scsi/hptiop.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/hptiop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/hptiop.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/timer.h>
 #include <linux/spinlock.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/div64.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/ibmmca.c linux-libre-2.6.34-gnu1/drivers/scsi/ibmmca.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/ibmmca.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/ibmmca.c	2010-05-16 17:17:36.000000000 -0400
@@ -2336,7 +2336,7 @@ static int option_setup(char *str)
 	char *cur = str;
 	int i = 1;
 
-	while (cur && isdigit(*cur) && i <= IM_MAX_HOSTS) {
+	while (cur && isdigit(*cur) && i < IM_MAX_HOSTS) {
 		ints[i++] = simple_strtoul(cur, NULL, 0);
 		if ((cur = strchr(cur, ',')) != NULL)
 			cur++;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/ibmvfc.c linux-libre-2.6.34-gnu1/drivers/scsi/ibmvscsi/ibmvfc.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/ibmvfc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/ibmvscsi/ibmvfc.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,9 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/pm.h>
 #include <linux/stringify.h>
 #include <asm/firmware.h>
 #include <asm/irq.h>
@@ -4195,7 +4197,7 @@ static void ibmvfc_tgt_add_rport(struct
 		if (tgt->service_parms.class3_parms[0] & 0x80000000)
 			rport->supported_classes |= FC_COS_CLASS3;
 		if (rport->rqst_q)
-			blk_queue_max_hw_segments(rport->rqst_q, 1);
+			blk_queue_max_segments(rport->rqst_q, 1);
 	} else
 		tgt_dbg(tgt, "rport add failed\n");
 	spin_unlock_irqrestore(vhost->host->host_lock, flags);
@@ -4669,7 +4671,7 @@ static int ibmvfc_probe(struct vio_dev *
 	}
 
 	if (shost_to_fc_host(shost)->rqst_q)
-		blk_queue_max_hw_segments(shost_to_fc_host(shost)->rqst_q, 1);
+		blk_queue_max_segments(shost_to_fc_host(shost)->rqst_q, 1);
 	dev_set_drvdata(dev, vhost);
 	spin_lock(&ibmvfc_driver_lock);
 	list_add_tail(&vhost->queue, &ibmvfc_head);
@@ -4736,6 +4738,27 @@ static int ibmvfc_remove(struct vio_dev
 }
 
 /**
+ * ibmvfc_resume - Resume from suspend
+ * @dev:	device struct
+ *
+ * We may have lost an interrupt across suspend/resume, so kick the
+ * interrupt handler
+ *
+ */
+static int ibmvfc_resume(struct device *dev)
+{
+	unsigned long flags;
+	struct ibmvfc_host *vhost = dev_get_drvdata(dev);
+	struct vio_dev *vdev = to_vio_dev(dev);
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	vio_disable_interrupts(vdev);
+	tasklet_schedule(&vhost->tasklet);
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+	return 0;
+}
+
+/**
  * ibmvfc_get_desired_dma - Calculate DMA resources needed by the driver
  * @vdev:	vio device struct
  *
@@ -4755,6 +4778,10 @@ static struct vio_device_id ibmvfc_devic
 };
 MODULE_DEVICE_TABLE(vio, ibmvfc_device_table);
 
+static struct dev_pm_ops ibmvfc_pm_ops = {
+	.resume = ibmvfc_resume
+};
+
 static struct vio_driver ibmvfc_driver = {
 	.id_table = ibmvfc_device_table,
 	.probe = ibmvfc_probe,
@@ -4763,6 +4790,7 @@ static struct vio_driver ibmvfc_driver =
 	.driver = {
 		.name = IBMVFC_NAME,
 		.owner = THIS_MODULE,
+		.pm = &ibmvfc_pm_ops,
 	}
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/ibmvscsi.c linux-libre-2.6.34-gnu1/drivers/scsi/ibmvscsi/ibmvscsi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/ibmvscsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/ibmvscsi/ibmvscsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,7 +40,7 @@
  * (CRQ), which is just a buffer of 16 byte entries in the receiver's 
  * Senders cannot access the buffer directly, but send messages by
  * making a hypervisor call and passing in the 16 bytes.  The hypervisor
- * puts the message in the next 16 byte space in round-robbin fashion,
+ * puts the message in the next 16 byte space in round-robin fashion,
  * turns on the high order bit of the message (the valid bit), and 
  * generates an interrupt to the receiver (if interrupts are turned on.) 
  * The receiver just turns off the valid bit when they have copied out
@@ -70,7 +70,9 @@
 #include <linux/moduleparam.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/pm.h>
 #include <asm/firmware.h>
 #include <asm/vio.h>
 #include <scsi/scsi.h>
@@ -321,16 +323,6 @@ static void set_srp_direction(struct scs
 		srp_cmd->buf_fmt = fmt;
 }
 
-static void unmap_sg_list(int num_entries,
-		struct device *dev,
-		struct srp_direct_buf *md)
-{
-	int i;
-
-	for (i = 0; i < num_entries; ++i)
-		dma_unmap_single(dev, md[i].va, md[i].len, DMA_BIDIRECTIONAL);
-}
-
 /**
  * unmap_cmd_data: - Unmap data pointed in srp_cmd based on the format
  * @cmd:	srp_cmd whose additional_data member will be unmapped
@@ -348,24 +340,9 @@ static void unmap_cmd_data(struct srp_cm
 
 	if (out_fmt == SRP_NO_DATA_DESC && in_fmt == SRP_NO_DATA_DESC)
 		return;
-	else if (out_fmt == SRP_DATA_DESC_DIRECT ||
-		 in_fmt == SRP_DATA_DESC_DIRECT) {
-		struct srp_direct_buf *data =
-			(struct srp_direct_buf *) cmd->add_data;
-		dma_unmap_single(dev, data->va, data->len, DMA_BIDIRECTIONAL);
-	} else {
-		struct srp_indirect_buf *indirect =
-			(struct srp_indirect_buf *) cmd->add_data;
-		int num_mapped = indirect->table_desc.len /
-			sizeof(struct srp_direct_buf);
 
-		if (num_mapped <= MAX_INDIRECT_BUFS) {
-			unmap_sg_list(num_mapped, dev, &indirect->desc_list[0]);
-			return;
-		}
-
-		unmap_sg_list(num_mapped, dev, evt_struct->ext_list);
-	}
+	if (evt_struct->cmnd)
+		scsi_dma_unmap(evt_struct->cmnd);
 }
 
 static int map_sg_list(struct scsi_cmnd *cmd, int nseg,
@@ -1991,6 +1968,19 @@ static int ibmvscsi_remove(struct vio_de
 }
 
 /**
+ * ibmvscsi_resume: Resume from suspend
+ * @dev:	device struct
+ *
+ * We may have lost an interrupt across suspend/resume, so kick the
+ * interrupt handler
+ */
+static int ibmvscsi_resume(struct device *dev)
+{
+	struct ibmvscsi_host_data *hostdata = dev_get_drvdata(dev);
+	return ibmvscsi_ops->resume(hostdata);
+}
+
+/**
  * ibmvscsi_device_table: Used by vio.c to match devices in the device tree we 
  * support.
  */
@@ -2000,6 +1990,10 @@ static struct vio_device_id ibmvscsi_dev
 };
 MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table);
 
+static struct dev_pm_ops ibmvscsi_pm_ops = {
+	.resume = ibmvscsi_resume
+};
+
 static struct vio_driver ibmvscsi_driver = {
 	.id_table = ibmvscsi_device_table,
 	.probe = ibmvscsi_probe,
@@ -2008,6 +2002,7 @@ static struct vio_driver ibmvscsi_driver
 	.driver = {
 		.name = "ibmvscsi",
 		.owner = THIS_MODULE,
+		.pm = &ibmvscsi_pm_ops,
 	}
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/ibmvscsi.h linux-libre-2.6.34-gnu1/drivers/scsi/ibmvscsi/ibmvscsi.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/ibmvscsi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/ibmvscsi/ibmvscsi.h	2010-05-16 17:17:36.000000000 -0400
@@ -120,6 +120,7 @@ struct ibmvscsi_ops {
 				  struct ibmvscsi_host_data *hostdata);
 	int (*send_crq)(struct ibmvscsi_host_data *hostdata,
 		       u64 word1, u64 word2);
+	int (*resume) (struct ibmvscsi_host_data *hostdata);
 };
 
 extern struct ibmvscsi_ops iseriesvscsi_ops;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/ibmvstgt.c linux-libre-2.6.34-gnu1/drivers/scsi/ibmvscsi/ibmvstgt.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/ibmvstgt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/ibmvscsi/ibmvstgt.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
  */
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport_srp.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/iseries_vscsi.c linux-libre-2.6.34-gnu1/drivers/scsi/ibmvscsi/iseries_vscsi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/iseries_vscsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/ibmvscsi/iseries_vscsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -158,10 +158,16 @@ static int iseriesvscsi_send_crq(struct
 					     0);
 }
 
+static int iseriesvscsi_resume(struct ibmvscsi_host_data *hostdata)
+{
+	return 0;
+}
+
 struct ibmvscsi_ops iseriesvscsi_ops = {
 	.init_crq_queue = iseriesvscsi_init_crq_queue,
 	.release_crq_queue = iseriesvscsi_release_crq_queue,
 	.reset_crq_queue = iseriesvscsi_reset_crq_queue,
 	.reenable_crq_queue = iseriesvscsi_reenable_crq_queue,
 	.send_crq = iseriesvscsi_send_crq,
+	.resume = iseriesvscsi_resume,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/rpa_vscsi.c linux-libre-2.6.34-gnu1/drivers/scsi/ibmvscsi/rpa_vscsi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/rpa_vscsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/ibmvscsi/rpa_vscsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <asm/iommu.h>
 #include <asm/hvcall.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 #include <linux/interrupt.h>
 #include "ibmvscsi.h"
 
@@ -334,10 +335,23 @@ static int rpavscsi_reenable_crq_queue(s
 	return rc;
 }
 
+/**
+ * rpavscsi_resume: - resume after suspend
+ * @hostdata:	ibmvscsi_host_data of host
+ *
+ */
+static int rpavscsi_resume(struct ibmvscsi_host_data *hostdata)
+{
+	vio_disable_interrupts(to_vio_dev(hostdata->dev));
+	tasklet_schedule(&hostdata->srp_task);
+	return 0;
+}
+
 struct ibmvscsi_ops rpavscsi_ops = {
 	.init_crq_queue = rpavscsi_init_crq_queue,
 	.release_crq_queue = rpavscsi_release_crq_queue,
 	.reset_crq_queue = rpavscsi_reset_crq_queue,
 	.reenable_crq_queue = rpavscsi_reenable_crq_queue,
 	.send_crq = rpavscsi_send_crq,
+	.resume = rpavscsi_resume,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/imm.c linux-libre-2.6.34-gnu1/drivers/scsi/imm.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/imm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/imm.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/parport.h>
 #include <linux/workqueue.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #include <scsi/scsi.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/initio.c linux-libre-2.6.34-gnu1/drivers/scsi/initio.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/initio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/initio.c	2010-05-16 17:17:36.000000000 -0400
@@ -531,7 +531,7 @@ static void initio_read_eeprom(unsigned
  *	initio_stop_bm		-	stop bus master
  *	@host: InitIO we are stopping
  *
- *	Stop any pending DMA operation, aborting the DMA if neccessary
+ *	Stop any pending DMA operation, aborting the DMA if necessary
  */
 
 static void initio_stop_bm(struct initio_host * host)
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/ipr.c linux-libre-2.6.34-gnu1/drivers/scsi/ipr.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/ipr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/ipr.c	2010-05-16 17:17:36.000000000 -0400
@@ -59,6 +59,7 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
@@ -72,6 +73,8 @@
 #include <linux/moduleparam.h>
 #include <linux/libata.h>
 #include <linux/hdreg.h>
+#include <linux/reboot.h>
+#include <linux/stringify.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/processor.h>
@@ -91,8 +94,8 @@ static unsigned int ipr_max_speed = 1;
 static int ipr_testmode = 0;
 static unsigned int ipr_fastfail = 0;
 static unsigned int ipr_transop_timeout = 0;
-static unsigned int ipr_enable_cache = 1;
 static unsigned int ipr_debug = 0;
+static unsigned int ipr_max_devs = IPR_DEFAULT_SIS64_DEVS;
 static unsigned int ipr_dual_ioa_raid = 1;
 static DEFINE_SPINLOCK(ipr_driver_lock);
 
@@ -104,13 +107,20 @@ static const struct ipr_chip_cfg_t ipr_c
 		{
 			.set_interrupt_mask_reg = 0x0022C,
 			.clr_interrupt_mask_reg = 0x00230,
+			.clr_interrupt_mask_reg32 = 0x00230,
 			.sense_interrupt_mask_reg = 0x0022C,
+			.sense_interrupt_mask_reg32 = 0x0022C,
 			.clr_interrupt_reg = 0x00228,
+			.clr_interrupt_reg32 = 0x00228,
 			.sense_interrupt_reg = 0x00224,
+			.sense_interrupt_reg32 = 0x00224,
 			.ioarrin_reg = 0x00404,
 			.sense_uproc_interrupt_reg = 0x00214,
+			.sense_uproc_interrupt_reg32 = 0x00214,
 			.set_uproc_interrupt_reg = 0x00214,
-			.clr_uproc_interrupt_reg = 0x00218
+			.set_uproc_interrupt_reg32 = 0x00214,
+			.clr_uproc_interrupt_reg = 0x00218,
+			.clr_uproc_interrupt_reg32 = 0x00218
 		}
 	},
 	{ /* Snipe and Scamp */
@@ -119,25 +129,59 @@ static const struct ipr_chip_cfg_t ipr_c
 		{
 			.set_interrupt_mask_reg = 0x00288,
 			.clr_interrupt_mask_reg = 0x0028C,
+			.clr_interrupt_mask_reg32 = 0x0028C,
 			.sense_interrupt_mask_reg = 0x00288,
+			.sense_interrupt_mask_reg32 = 0x00288,
 			.clr_interrupt_reg = 0x00284,
+			.clr_interrupt_reg32 = 0x00284,
 			.sense_interrupt_reg = 0x00280,
+			.sense_interrupt_reg32 = 0x00280,
 			.ioarrin_reg = 0x00504,
 			.sense_uproc_interrupt_reg = 0x00290,
+			.sense_uproc_interrupt_reg32 = 0x00290,
 			.set_uproc_interrupt_reg = 0x00290,
-			.clr_uproc_interrupt_reg = 0x00294
+			.set_uproc_interrupt_reg32 = 0x00290,
+			.clr_uproc_interrupt_reg = 0x00294,
+			.clr_uproc_interrupt_reg32 = 0x00294
+		}
+	},
+	{ /* CRoC */
+		.mailbox = 0x00040,
+		.cache_line_size = 0x20,
+		{
+			.set_interrupt_mask_reg = 0x00010,
+			.clr_interrupt_mask_reg = 0x00018,
+			.clr_interrupt_mask_reg32 = 0x0001C,
+			.sense_interrupt_mask_reg = 0x00010,
+			.sense_interrupt_mask_reg32 = 0x00014,
+			.clr_interrupt_reg = 0x00008,
+			.clr_interrupt_reg32 = 0x0000C,
+			.sense_interrupt_reg = 0x00000,
+			.sense_interrupt_reg32 = 0x00004,
+			.ioarrin_reg = 0x00070,
+			.sense_uproc_interrupt_reg = 0x00020,
+			.sense_uproc_interrupt_reg32 = 0x00024,
+			.set_uproc_interrupt_reg = 0x00020,
+			.set_uproc_interrupt_reg32 = 0x00024,
+			.clr_uproc_interrupt_reg = 0x00028,
+			.clr_uproc_interrupt_reg32 = 0x0002C,
+			.init_feedback_reg = 0x0005C,
+			.dump_addr_reg = 0x00064,
+			.dump_data_reg = 0x00068
 		}
 	},
 };
 
 static const struct ipr_chip_t ipr_chip[] = {
-	{ PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, &ipr_chip_cfg[0] },
-	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, &ipr_chip_cfg[0] },
-	{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] },
-	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] },
-	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, &ipr_chip_cfg[0] },
-	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, &ipr_chip_cfg[1] },
-	{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, &ipr_chip_cfg[1] }
+	{ PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
+	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
+	{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
+	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
+	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, IPR_SIS32, &ipr_chip_cfg[0] },
+	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] },
+	{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] },
+	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, IPR_USE_MSI, IPR_SIS64, &ipr_chip_cfg[2] },
+	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, IPR_USE_MSI, IPR_SIS64, &ipr_chip_cfg[2] }
 };
 
 static int ipr_max_bus_speeds [] = {
@@ -156,12 +200,13 @@ module_param_named(fastfail, ipr_fastfai
 MODULE_PARM_DESC(fastfail, "Reduce timeouts and retries");
 module_param_named(transop_timeout, ipr_transop_timeout, int, 0);
 MODULE_PARM_DESC(transop_timeout, "Time in seconds to wait for adapter to come operational (default: 300)");
-module_param_named(enable_cache, ipr_enable_cache, int, 0);
-MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)");
 module_param_named(debug, ipr_debug, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)");
 module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0);
 MODULE_PARM_DESC(dual_ioa_raid, "Enable dual adapter RAID support. Set to 1 to enable. (default: 1)");
+module_param_named(max_devs, ipr_max_devs, int, 0);
+MODULE_PARM_DESC(max_devs, "Specify the maximum number of physical devices. "
+		 "[Default=" __stringify(IPR_DEFAULT_SIS64_DEVS) "]");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(IPR_DRIVER_VERSION);
 
@@ -180,6 +225,20 @@ struct ipr_error_table_t ipr_error_table
 	"FFFE: Soft device bus error recovered by the IOA"},
 	{0x01088100, 0, IPR_DEFAULT_LOG_LEVEL,
 	"4101: Soft device bus fabric error"},
+	{0x01100100, 0, IPR_DEFAULT_LOG_LEVEL,
+	"FFFC: Logical block guard error recovered by the device"},
+	{0x01100300, 0, IPR_DEFAULT_LOG_LEVEL,
+	"FFFC: Logical block reference tag error recovered by the device"},
+	{0x01108300, 0, IPR_DEFAULT_LOG_LEVEL,
+	"4171: Recovered scatter list tag / sequence number error"},
+	{0x01109000, 0, IPR_DEFAULT_LOG_LEVEL,
+	"FF3D: Recovered logical block CRC error on IOA to Host transfer"},
+	{0x01109200, 0, IPR_DEFAULT_LOG_LEVEL,
+	"4171: Recovered logical block sequence number error on IOA to Host transfer"},
+	{0x0110A000, 0, IPR_DEFAULT_LOG_LEVEL,
+	"FFFD: Recovered logical block reference tag error detected by the IOA"},
+	{0x0110A100, 0, IPR_DEFAULT_LOG_LEVEL,
+	"FFFD: Logical block guard error recovered by the IOA"},
 	{0x01170600, 0, IPR_DEFAULT_LOG_LEVEL,
 	"FFF9: Device sector reassign successful"},
 	{0x01170900, 0, IPR_DEFAULT_LOG_LEVEL,
@@ -236,12 +295,28 @@ struct ipr_error_table_t ipr_error_table
 	"3120: SCSI bus is not operational"},
 	{0x04088100, 0, IPR_DEFAULT_LOG_LEVEL,
 	"4100: Hard device bus fabric error"},
+	{0x04100100, 0, IPR_DEFAULT_LOG_LEVEL,
+	"310C: Logical block guard error detected by the device"},
+	{0x04100300, 0, IPR_DEFAULT_LOG_LEVEL,
+	"310C: Logical block reference tag error detected by the device"},
+	{0x04108300, 1, IPR_DEFAULT_LOG_LEVEL,
+	"4170: Scatter list tag / sequence number error"},
+	{0x04109000, 1, IPR_DEFAULT_LOG_LEVEL,
+	"8150: Logical block CRC error on IOA to Host transfer"},
+	{0x04109200, 1, IPR_DEFAULT_LOG_LEVEL,
+	"4170: Logical block sequence number error on IOA to Host transfer"},
+	{0x0410A000, 0, IPR_DEFAULT_LOG_LEVEL,
+	"310D: Logical block reference tag error detected by the IOA"},
+	{0x0410A100, 0, IPR_DEFAULT_LOG_LEVEL,
+	"310D: Logical block guard error detected by the IOA"},
 	{0x04118000, 0, IPR_DEFAULT_LOG_LEVEL,
 	"9000: IOA reserved area data check"},
 	{0x04118100, 0, IPR_DEFAULT_LOG_LEVEL,
 	"9001: IOA reserved area invalid data pattern"},
 	{0x04118200, 0, IPR_DEFAULT_LOG_LEVEL,
 	"9002: IOA reserved area LRC error"},
+	{0x04118300, 1, IPR_DEFAULT_LOG_LEVEL,
+	"Hardware Error, IOA metadata access error"},
 	{0x04320000, 0, IPR_DEFAULT_LOG_LEVEL,
 	"102E: Out of alternate sectors for disk storage"},
 	{0x04330000, 1, IPR_DEFAULT_LOG_LEVEL,
@@ -306,6 +381,8 @@ struct ipr_error_table_t ipr_error_table
 	"Illegal request, commands not allowed to this device"},
 	{0x05258100, 0, 0,
 	"Illegal request, command not allowed to a secondary adapter"},
+	{0x05258200, 0, 0,
+	"Illegal request, command not allowed to a non-optimized resource"},
 	{0x05260000, 0, 0,
 	"Illegal request, invalid field in parameter list"},
 	{0x05260100, 0, 0,
@@ -468,7 +545,10 @@ static void ipr_trc_hook(struct ipr_cmnd
 	trace_entry->time = jiffies;
 	trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0];
 	trace_entry->type = type;
-	trace_entry->ata_op_code = ipr_cmd->ioarcb.add_data.u.regs.command;
+	if (ipr_cmd->ioa_cfg->sis64)
+		trace_entry->ata_op_code = ipr_cmd->i.ata_ioadl.regs.command;
+	else
+		trace_entry->ata_op_code = ipr_cmd->ioarcb.u.add_data.u.regs.command;
 	trace_entry->cmd_index = ipr_cmd->cmd_index & 0xff;
 	trace_entry->res_handle = ipr_cmd->ioarcb.res_handle;
 	trace_entry->u.add_data = add_data;
@@ -488,16 +568,23 @@ static void ipr_reinit_ipr_cmnd(struct i
 {
 	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
 	struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
-	dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr);
+	dma_addr_t dma_addr = ipr_cmd->dma_addr;
 
 	memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt));
-	ioarcb->write_data_transfer_length = 0;
+	ioarcb->data_transfer_length = 0;
 	ioarcb->read_data_transfer_length = 0;
-	ioarcb->write_ioadl_len = 0;
+	ioarcb->ioadl_len = 0;
 	ioarcb->read_ioadl_len = 0;
-	ioarcb->write_ioadl_addr =
-		cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl));
-	ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+
+	if (ipr_cmd->ioa_cfg->sis64)
+		ioarcb->u.sis64_addr_data.data_ioadl_addr =
+			cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64));
+	else {
+		ioarcb->write_ioadl_addr =
+			cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl));
+		ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+	}
+
 	ioasa->ioasc = 0;
 	ioasa->residual_data_len = 0;
 	ioasa->u.gata.status = 0;
@@ -562,10 +649,15 @@ static void ipr_mask_and_clear_interrupt
 	ioa_cfg->allow_interrupts = 0;
 
 	/* Set interrupt mask to stop all new interrupts */
-	writel(~0, ioa_cfg->regs.set_interrupt_mask_reg);
+	if (ioa_cfg->sis64)
+		writeq(~0, ioa_cfg->regs.set_interrupt_mask_reg);
+	else
+		writel(~0, ioa_cfg->regs.set_interrupt_mask_reg);
 
 	/* Clear any pending interrupts */
-	writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg);
+	if (ioa_cfg->sis64)
+		writel(~0, ioa_cfg->regs.clr_interrupt_reg);
+	writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg32);
 	int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
 }
 
@@ -693,6 +785,35 @@ static void ipr_fail_all_ops(struct ipr_
 }
 
 /**
+ * ipr_send_command -  Send driver initiated requests.
+ * @ipr_cmd:		ipr command struct
+ *
+ * This function sends a command to the adapter using the correct write call.
+ * In the case of sis64, calculate the ioarcb size required. Then or in the
+ * appropriate bits.
+ *
+ * Return value:
+ * 	none
+ **/
+static void ipr_send_command(struct ipr_cmnd *ipr_cmd)
+{
+	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+	dma_addr_t send_dma_addr = ipr_cmd->dma_addr;
+
+	if (ioa_cfg->sis64) {
+		/* The default size is 256 bytes */
+		send_dma_addr |= 0x1;
+
+		/* If the number of ioadls * size of ioadl > 128 bytes,
+		   then use a 512 byte ioarcb */
+		if (ipr_cmd->dma_use_sg * sizeof(struct ipr_ioadl64_desc) > 128 )
+			send_dma_addr |= 0x4;
+		writeq(send_dma_addr, ioa_cfg->regs.ioarrin_reg);
+	} else
+		writel(send_dma_addr, ioa_cfg->regs.ioarrin_reg);
+}
+
+/**
  * ipr_do_req -  Send driver initiated requests.
  * @ipr_cmd:		ipr command struct
  * @done:			done function
@@ -724,8 +845,8 @@ static void ipr_do_req(struct ipr_cmnd *
 	ipr_trc_hook(ipr_cmd, IPR_TRACE_START, 0);
 
 	mb();
-	writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr),
-	       ioa_cfg->regs.ioarrin_reg);
+
+	ipr_send_command(ipr_cmd);
 }
 
 /**
@@ -747,6 +868,51 @@ static void ipr_internal_cmd_done(struct
 }
 
 /**
+ * ipr_init_ioadl - initialize the ioadl for the correct SIS type
+ * @ipr_cmd:	ipr command struct
+ * @dma_addr:	dma address
+ * @len:	transfer length
+ * @flags:	ioadl flag value
+ *
+ * This function initializes an ioadl in the case where there is only a single
+ * descriptor.
+ *
+ * Return value:
+ * 	nothing
+ **/
+static void ipr_init_ioadl(struct ipr_cmnd *ipr_cmd, dma_addr_t dma_addr,
+			   u32 len, int flags)
+{
+	struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
+	struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
+
+	ipr_cmd->dma_use_sg = 1;
+
+	if (ipr_cmd->ioa_cfg->sis64) {
+		ioadl64->flags = cpu_to_be32(flags);
+		ioadl64->data_len = cpu_to_be32(len);
+		ioadl64->address = cpu_to_be64(dma_addr);
+
+		ipr_cmd->ioarcb.ioadl_len =
+		       	cpu_to_be32(sizeof(struct ipr_ioadl64_desc));
+		ipr_cmd->ioarcb.data_transfer_length = cpu_to_be32(len);
+	} else {
+		ioadl->flags_and_data_len = cpu_to_be32(flags | len);
+		ioadl->address = cpu_to_be32(dma_addr);
+
+		if (flags == IPR_IOADL_FLAGS_READ_LAST) {
+			ipr_cmd->ioarcb.read_ioadl_len =
+				cpu_to_be32(sizeof(struct ipr_ioadl_desc));
+			ipr_cmd->ioarcb.read_data_transfer_length = cpu_to_be32(len);
+		} else {
+			ipr_cmd->ioarcb.ioadl_len =
+			       	cpu_to_be32(sizeof(struct ipr_ioadl_desc));
+			ipr_cmd->ioarcb.data_transfer_length = cpu_to_be32(len);
+		}
+	}
+}
+
+/**
  * ipr_send_blocking_cmd - Send command and sleep on its completion.
  * @ipr_cmd:	ipr command struct
  * @timeout_func:	function to invoke if command times out
@@ -803,11 +969,8 @@ static void ipr_send_hcam(struct ipr_ioa
 		ioarcb->cmd_pkt.cdb[7] = (sizeof(hostrcb->hcam) >> 8) & 0xff;
 		ioarcb->cmd_pkt.cdb[8] = sizeof(hostrcb->hcam) & 0xff;
 
-		ioarcb->read_data_transfer_length = cpu_to_be32(sizeof(hostrcb->hcam));
-		ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-		ipr_cmd->ioadl[0].flags_and_data_len =
-			cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | sizeof(hostrcb->hcam));
-		ipr_cmd->ioadl[0].address = cpu_to_be32(hostrcb->hostrcb_dma);
+		ipr_init_ioadl(ipr_cmd, hostrcb->hostrcb_dma,
+			       sizeof(hostrcb->hcam), IPR_IOADL_FLAGS_READ_LAST);
 
 		if (type == IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE)
 			ipr_cmd->done = ipr_process_ccn;
@@ -817,22 +980,54 @@ static void ipr_send_hcam(struct ipr_ioa
 		ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_IOA_RES_ADDR);
 
 		mb();
-		writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr),
-		       ioa_cfg->regs.ioarrin_reg);
+
+		ipr_send_command(ipr_cmd);
 	} else {
 		list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q);
 	}
 }
 
 /**
+ * ipr_update_ata_class - Update the ata class in the resource entry
+ * @res:	resource entry struct
+ * @proto:	cfgte device bus protocol value
+ *
+ * Return value:
+ * 	none
+ **/
+static void ipr_update_ata_class(struct ipr_resource_entry *res, unsigned int proto)
+{
+	switch(proto) {
+	case IPR_PROTO_SATA:
+	case IPR_PROTO_SAS_STP:
+		res->ata_class = ATA_DEV_ATA;
+		break;
+	case IPR_PROTO_SATA_ATAPI:
+	case IPR_PROTO_SAS_STP_ATAPI:
+		res->ata_class = ATA_DEV_ATAPI;
+		break;
+	default:
+		res->ata_class = ATA_DEV_UNKNOWN;
+		break;
+	};
+}
+
+/**
  * ipr_init_res_entry - Initialize a resource entry struct.
  * @res:	resource entry struct
+ * @cfgtew:	config table entry wrapper struct
  *
  * Return value:
  * 	none
  **/
-static void ipr_init_res_entry(struct ipr_resource_entry *res)
+static void ipr_init_res_entry(struct ipr_resource_entry *res,
+			       struct ipr_config_table_entry_wrapper *cfgtew)
 {
+	int found = 0;
+	unsigned int proto;
+	struct ipr_ioa_cfg *ioa_cfg = res->ioa_cfg;
+	struct ipr_resource_entry *gscsi_res = NULL;
+
 	res->needs_sync_complete = 0;
 	res->in_erp = 0;
 	res->add_to_ml = 0;
@@ -840,6 +1035,205 @@ static void ipr_init_res_entry(struct ip
 	res->resetting_device = 0;
 	res->sdev = NULL;
 	res->sata_port = NULL;
+
+	if (ioa_cfg->sis64) {
+		proto = cfgtew->u.cfgte64->proto;
+		res->res_flags = cfgtew->u.cfgte64->res_flags;
+		res->qmodel = IPR_QUEUEING_MODEL64(res);
+		res->type = cfgtew->u.cfgte64->res_type & 0x0f;
+
+		memcpy(res->res_path, &cfgtew->u.cfgte64->res_path,
+			sizeof(res->res_path));
+
+		res->bus = 0;
+		res->lun = scsilun_to_int(&res->dev_lun);
+
+		if (res->type == IPR_RES_TYPE_GENERIC_SCSI) {
+			list_for_each_entry(gscsi_res, &ioa_cfg->used_res_q, queue) {
+				if (gscsi_res->dev_id == cfgtew->u.cfgte64->dev_id) {
+					found = 1;
+					res->target = gscsi_res->target;
+					break;
+				}
+			}
+			if (!found) {
+				res->target = find_first_zero_bit(ioa_cfg->target_ids,
+								  ioa_cfg->max_devs_supported);
+				set_bit(res->target, ioa_cfg->target_ids);
+			}
+
+			memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun,
+				sizeof(res->dev_lun.scsi_lun));
+		} else if (res->type == IPR_RES_TYPE_IOAFP) {
+			res->bus = IPR_IOAFP_VIRTUAL_BUS;
+			res->target = 0;
+		} else if (res->type == IPR_RES_TYPE_ARRAY) {
+			res->bus = IPR_ARRAY_VIRTUAL_BUS;
+			res->target = find_first_zero_bit(ioa_cfg->array_ids,
+							  ioa_cfg->max_devs_supported);
+			set_bit(res->target, ioa_cfg->array_ids);
+		} else if (res->type == IPR_RES_TYPE_VOLUME_SET) {
+			res->bus = IPR_VSET_VIRTUAL_BUS;
+			res->target = find_first_zero_bit(ioa_cfg->vset_ids,
+							  ioa_cfg->max_devs_supported);
+			set_bit(res->target, ioa_cfg->vset_ids);
+		} else {
+			res->target = find_first_zero_bit(ioa_cfg->target_ids,
+							  ioa_cfg->max_devs_supported);
+			set_bit(res->target, ioa_cfg->target_ids);
+		}
+	} else {
+		proto = cfgtew->u.cfgte->proto;
+		res->qmodel = IPR_QUEUEING_MODEL(res);
+		res->flags = cfgtew->u.cfgte->flags;
+		if (res->flags & IPR_IS_IOA_RESOURCE)
+			res->type = IPR_RES_TYPE_IOAFP;
+		else
+			res->type = cfgtew->u.cfgte->rsvd_subtype & 0x0f;
+
+		res->bus = cfgtew->u.cfgte->res_addr.bus;
+		res->target = cfgtew->u.cfgte->res_addr.target;
+		res->lun = cfgtew->u.cfgte->res_addr.lun;
+	}
+
+	ipr_update_ata_class(res, proto);
+}
+
+/**
+ * ipr_is_same_device - Determine if two devices are the same.
+ * @res:	resource entry struct
+ * @cfgtew:	config table entry wrapper struct
+ *
+ * Return value:
+ * 	1 if the devices are the same / 0 otherwise
+ **/
+static int ipr_is_same_device(struct ipr_resource_entry *res,
+			      struct ipr_config_table_entry_wrapper *cfgtew)
+{
+	if (res->ioa_cfg->sis64) {
+		if (!memcmp(&res->dev_id, &cfgtew->u.cfgte64->dev_id,
+					sizeof(cfgtew->u.cfgte64->dev_id)) &&
+			!memcmp(&res->lun, &cfgtew->u.cfgte64->lun,
+					sizeof(cfgtew->u.cfgte64->lun))) {
+			return 1;
+		}
+	} else {
+		if (res->bus == cfgtew->u.cfgte->res_addr.bus &&
+		    res->target == cfgtew->u.cfgte->res_addr.target &&
+		    res->lun == cfgtew->u.cfgte->res_addr.lun)
+			return 1;
+	}
+
+	return 0;
+}
+
+/**
+ * ipr_format_resource_path - Format the resource path for printing.
+ * @res_path:	resource path
+ * @buf:	buffer
+ *
+ * Return value:
+ * 	pointer to buffer
+ **/
+static char *ipr_format_resource_path(u8 *res_path, char *buffer)
+{
+	int i;
+
+	sprintf(buffer, "%02X", res_path[0]);
+	for (i=1; res_path[i] != 0xff; i++)
+		sprintf(buffer, "%s-%02X", buffer, res_path[i]);
+
+	return buffer;
+}
+
+/**
+ * ipr_update_res_entry - Update the resource entry.
+ * @res:	resource entry struct
+ * @cfgtew:	config table entry wrapper struct
+ *
+ * Return value:
+ *      none
+ **/
+static void ipr_update_res_entry(struct ipr_resource_entry *res,
+				 struct ipr_config_table_entry_wrapper *cfgtew)
+{
+	char buffer[IPR_MAX_RES_PATH_LENGTH];
+	unsigned int proto;
+	int new_path = 0;
+
+	if (res->ioa_cfg->sis64) {
+		res->flags = cfgtew->u.cfgte64->flags;
+		res->res_flags = cfgtew->u.cfgte64->res_flags;
+		res->type = cfgtew->u.cfgte64->res_type & 0x0f;
+
+		memcpy(&res->std_inq_data, &cfgtew->u.cfgte64->std_inq_data,
+			sizeof(struct ipr_std_inq_data));
+
+		res->qmodel = IPR_QUEUEING_MODEL64(res);
+		proto = cfgtew->u.cfgte64->proto;
+		res->res_handle = cfgtew->u.cfgte64->res_handle;
+		res->dev_id = cfgtew->u.cfgte64->dev_id;
+
+		memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun,
+			sizeof(res->dev_lun.scsi_lun));
+
+		if (memcmp(res->res_path, &cfgtew->u.cfgte64->res_path,
+					sizeof(res->res_path))) {
+			memcpy(res->res_path, &cfgtew->u.cfgte64->res_path,
+				sizeof(res->res_path));
+			new_path = 1;
+		}
+
+		if (res->sdev && new_path)
+			sdev_printk(KERN_INFO, res->sdev, "Resource path: %s\n",
+				    ipr_format_resource_path(&res->res_path[0], &buffer[0]));
+	} else {
+		res->flags = cfgtew->u.cfgte->flags;
+		if (res->flags & IPR_IS_IOA_RESOURCE)
+			res->type = IPR_RES_TYPE_IOAFP;
+		else
+			res->type = cfgtew->u.cfgte->rsvd_subtype & 0x0f;
+
+		memcpy(&res->std_inq_data, &cfgtew->u.cfgte->std_inq_data,
+			sizeof(struct ipr_std_inq_data));
+
+		res->qmodel = IPR_QUEUEING_MODEL(res);
+		proto = cfgtew->u.cfgte->proto;
+		res->res_handle = cfgtew->u.cfgte->res_handle;
+	}
+
+	ipr_update_ata_class(res, proto);
+}
+
+/**
+ * ipr_clear_res_target - Clear the bit in the bit map representing the target
+ * 			  for the resource.
+ * @res:	resource entry struct
+ * @cfgtew:	config table entry wrapper struct
+ *
+ * Return value:
+ *      none
+ **/
+static void ipr_clear_res_target(struct ipr_resource_entry *res)
+{
+	struct ipr_resource_entry *gscsi_res = NULL;
+	struct ipr_ioa_cfg *ioa_cfg = res->ioa_cfg;
+
+	if (!ioa_cfg->sis64)
+		return;
+
+	if (res->bus == IPR_ARRAY_VIRTUAL_BUS)
+		clear_bit(res->target, ioa_cfg->array_ids);
+	else if (res->bus == IPR_VSET_VIRTUAL_BUS)
+		clear_bit(res->target, ioa_cfg->vset_ids);
+	else if (res->bus == 0 && res->type == IPR_RES_TYPE_GENERIC_SCSI) {
+		list_for_each_entry(gscsi_res, &ioa_cfg->used_res_q, queue)
+			if (gscsi_res->dev_id == res->dev_id && gscsi_res != res)
+				return;
+		clear_bit(res->target, ioa_cfg->target_ids);
+
+	} else if (res->bus == 0)
+		clear_bit(res->target, ioa_cfg->target_ids);
 }
 
 /**
@@ -851,17 +1245,24 @@ static void ipr_init_res_entry(struct ip
  * 	none
  **/
 static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg,
-			      struct ipr_hostrcb *hostrcb)
+				     struct ipr_hostrcb *hostrcb)
 {
 	struct ipr_resource_entry *res = NULL;
-	struct ipr_config_table_entry *cfgte;
+	struct ipr_config_table_entry_wrapper cfgtew;
+	__be32 cc_res_handle;
+
 	u32 is_ndn = 1;
 
-	cfgte = &hostrcb->hcam.u.ccn.cfgte;
+	if (ioa_cfg->sis64) {
+		cfgtew.u.cfgte64 = &hostrcb->hcam.u.ccn.u.cfgte64;
+		cc_res_handle = cfgtew.u.cfgte64->res_handle;
+	} else {
+		cfgtew.u.cfgte = &hostrcb->hcam.u.ccn.u.cfgte;
+		cc_res_handle = cfgtew.u.cfgte->res_handle;
+	}
 
 	list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-		if (!memcmp(&res->cfgte.res_addr, &cfgte->res_addr,
-			    sizeof(cfgte->res_addr))) {
+		if (res->res_handle == cc_res_handle) {
 			is_ndn = 0;
 			break;
 		}
@@ -879,20 +1280,22 @@ static void ipr_handle_config_change(str
 				 struct ipr_resource_entry, queue);
 
 		list_del(&res->queue);
-		ipr_init_res_entry(res);
+		ipr_init_res_entry(res, &cfgtew);
 		list_add_tail(&res->queue, &ioa_cfg->used_res_q);
 	}
 
-	memcpy(&res->cfgte, cfgte, sizeof(struct ipr_config_table_entry));
+	ipr_update_res_entry(res, &cfgtew);
 
 	if (hostrcb->hcam.notify_type == IPR_HOST_RCB_NOTIF_TYPE_REM_ENTRY) {
 		if (res->sdev) {
 			res->del_from_ml = 1;
-			res->cfgte.res_handle = IPR_INVALID_RES_HANDLE;
+			res->res_handle = IPR_INVALID_RES_HANDLE;
 			if (ioa_cfg->allow_ml_add_del)
 				schedule_work(&ioa_cfg->work_q);
-		} else
+		} else {
+			ipr_clear_res_target(res);
 			list_move_tail(&res->queue, &ioa_cfg->free_res_q);
+		}
 	} else if (!res->sdev) {
 		res->add_to_ml = 1;
 		if (ioa_cfg->allow_ml_add_del)
@@ -1044,8 +1447,12 @@ static void ipr_log_ext_vpd(struct ipr_e
 static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg,
 					 struct ipr_hostrcb *hostrcb)
 {
-	struct ipr_hostrcb_type_12_error *error =
-		&hostrcb->hcam.u.error.u.type_12_error;
+	struct ipr_hostrcb_type_12_error *error;
+
+	if (ioa_cfg->sis64)
+		error = &hostrcb->hcam.u.error64.u.type_12_error;
+	else
+		error = &hostrcb->hcam.u.error.u.type_12_error;
 
 	ipr_err("-----Current Configuration-----\n");
 	ipr_err("Cache Directory Card Information:\n");
@@ -1138,6 +1545,48 @@ static void ipr_log_enhanced_config_erro
 }
 
 /**
+ * ipr_log_sis64_config_error - Log a device error.
+ * @ioa_cfg:	ioa config struct
+ * @hostrcb:	hostrcb struct
+ *
+ * Return value:
+ * 	none
+ **/
+static void ipr_log_sis64_config_error(struct ipr_ioa_cfg *ioa_cfg,
+				       struct ipr_hostrcb *hostrcb)
+{
+	int errors_logged, i;
+	struct ipr_hostrcb64_device_data_entry_enhanced *dev_entry;
+	struct ipr_hostrcb_type_23_error *error;
+	char buffer[IPR_MAX_RES_PATH_LENGTH];
+
+	error = &hostrcb->hcam.u.error64.u.type_23_error;
+	errors_logged = be32_to_cpu(error->errors_logged);
+
+	ipr_err("Device Errors Detected/Logged: %d/%d\n",
+		be32_to_cpu(error->errors_detected), errors_logged);
+
+	dev_entry = error->dev;
+
+	for (i = 0; i < errors_logged; i++, dev_entry++) {
+		ipr_err_separator;
+
+		ipr_err("Device %d : %s", i + 1,
+			 ipr_format_resource_path(&dev_entry->res_path[0], &buffer[0]));
+		ipr_log_ext_vpd(&dev_entry->vpd);
+
+		ipr_err("-----New Device Information-----\n");
+		ipr_log_ext_vpd(&dev_entry->new_vpd);
+
+		ipr_err("Cache Directory Card Information:\n");
+		ipr_log_ext_vpd(&dev_entry->ioa_last_with_dev_vpd);
+
+		ipr_err("Adapter Card Information:\n");
+		ipr_log_ext_vpd(&dev_entry->cfc_last_with_dev_vpd);
+	}
+}
+
+/**
  * ipr_log_config_error - Log a configuration error.
  * @ioa_cfg:	ioa config struct
  * @hostrcb:	hostrcb struct
@@ -1331,7 +1780,11 @@ static void ipr_log_enhanced_dual_ioa_er
 {
 	struct ipr_hostrcb_type_17_error *error;
 
-	error = &hostrcb->hcam.u.error.u.type_17_error;
+	if (ioa_cfg->sis64)
+		error = &hostrcb->hcam.u.error64.u.type_17_error;
+	else
+		error = &hostrcb->hcam.u.error.u.type_17_error;
+
 	error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
 	strim(error->failure_reason);
 
@@ -1438,6 +1891,42 @@ static void ipr_log_fabric_path(struct i
 		fabric->ioa_port, fabric->cascaded_expander, fabric->phy);
 }
 
+/**
+ * ipr_log64_fabric_path - Log a fabric path error
+ * @hostrcb:	hostrcb struct
+ * @fabric:		fabric descriptor
+ *
+ * Return value:
+ * 	none
+ **/
+static void ipr_log64_fabric_path(struct ipr_hostrcb *hostrcb,
+				  struct ipr_hostrcb64_fabric_desc *fabric)
+{
+	int i, j;
+	u8 path_state = fabric->path_state;
+	u8 active = path_state & IPR_PATH_ACTIVE_MASK;
+	u8 state = path_state & IPR_PATH_STATE_MASK;
+	char buffer[IPR_MAX_RES_PATH_LENGTH];
+
+	for (i = 0; i < ARRAY_SIZE(path_active_desc); i++) {
+		if (path_active_desc[i].active != active)
+			continue;
+
+		for (j = 0; j < ARRAY_SIZE(path_state_desc); j++) {
+			if (path_state_desc[j].state != state)
+				continue;
+
+			ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s\n",
+				     path_active_desc[i].desc, path_state_desc[j].desc,
+				     ipr_format_resource_path(&fabric->res_path[0], &buffer[0]));
+			return;
+		}
+	}
+
+	ipr_err("Path state=%02X Resource Path=%s\n", path_state,
+		ipr_format_resource_path(&fabric->res_path[0], &buffer[0]));
+}
+
 static const struct {
 	u8 type;
 	char *desc;
@@ -1547,6 +2036,49 @@ static void ipr_log_path_elem(struct ipr
 }
 
 /**
+ * ipr_log64_path_elem - Log a fabric path element.
+ * @hostrcb:	hostrcb struct
+ * @cfg:		fabric path element struct
+ *
+ * Return value:
+ * 	none
+ **/
+static void ipr_log64_path_elem(struct ipr_hostrcb *hostrcb,
+				struct ipr_hostrcb64_config_element *cfg)
+{
+	int i, j;
+	u8 desc_id = cfg->descriptor_id & IPR_DESCRIPTOR_MASK;
+	u8 type = cfg->type_status & IPR_PATH_CFG_TYPE_MASK;
+	u8 status = cfg->type_status & IPR_PATH_CFG_STATUS_MASK;
+	char buffer[IPR_MAX_RES_PATH_LENGTH];
+
+	if (type == IPR_PATH_CFG_NOT_EXIST || desc_id != IPR_DESCRIPTOR_SIS64)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(path_type_desc); i++) {
+		if (path_type_desc[i].type != type)
+			continue;
+
+		for (j = 0; j < ARRAY_SIZE(path_status_desc); j++) {
+			if (path_status_desc[j].status != status)
+				continue;
+
+			ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s, Link rate=%s, WWN=%08X%08X\n",
+				     path_status_desc[j].desc, path_type_desc[i].desc,
+				     ipr_format_resource_path(&cfg->res_path[0], &buffer[0]),
+				     link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
+				     be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
+			return;
+		}
+	}
+	ipr_hcam_err(hostrcb, "Path element=%02X: Resource Path=%s, Link rate=%s "
+		     "WWN=%08X%08X\n", cfg->type_status,
+		     ipr_format_resource_path(&cfg->res_path[0], &buffer[0]),
+		     link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
+		     be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
+}
+
+/**
  * ipr_log_fabric_error - Log a fabric error.
  * @ioa_cfg:	ioa config struct
  * @hostrcb:	hostrcb struct
@@ -1584,6 +2116,96 @@ static void ipr_log_fabric_error(struct
 }
 
 /**
+ * ipr_log_sis64_array_error - Log a sis64 array error.
+ * @ioa_cfg:	ioa config struct
+ * @hostrcb:	hostrcb struct
+ *
+ * Return value:
+ * 	none
+ **/
+static void ipr_log_sis64_array_error(struct ipr_ioa_cfg *ioa_cfg,
+				      struct ipr_hostrcb *hostrcb)
+{
+	int i, num_entries;
+	struct ipr_hostrcb_type_24_error *error;
+	struct ipr_hostrcb64_array_data_entry *array_entry;
+	char buffer[IPR_MAX_RES_PATH_LENGTH];
+	const u8 zero_sn[IPR_SERIAL_NUM_LEN] = { [0 ... IPR_SERIAL_NUM_LEN-1] = '0' };
+
+	error = &hostrcb->hcam.u.error64.u.type_24_error;
+
+	ipr_err_separator;
+
+	ipr_err("RAID %s Array Configuration: %s\n",
+		error->protection_level,
+		ipr_format_resource_path(&error->last_res_path[0], &buffer[0]));
+
+	ipr_err_separator;
+
+	array_entry = error->array_member;
+	num_entries = min_t(u32, be32_to_cpu(error->num_entries),
+			    sizeof(error->array_member));
+
+	for (i = 0; i < num_entries; i++, array_entry++) {
+
+		if (!memcmp(array_entry->vpd.vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN))
+			continue;
+
+		if (error->exposed_mode_adn == i)
+			ipr_err("Exposed Array Member %d:\n", i);
+		else
+			ipr_err("Array Member %d:\n", i);
+
+		ipr_err("Array Member %d:\n", i);
+		ipr_log_ext_vpd(&array_entry->vpd);
+		ipr_err("Current Location: %s",
+			 ipr_format_resource_path(&array_entry->res_path[0], &buffer[0]));
+		ipr_err("Expected Location: %s",
+			 ipr_format_resource_path(&array_entry->expected_res_path[0], &buffer[0]));
+
+		ipr_err_separator;
+	}
+}
+
+/**
+ * ipr_log_sis64_fabric_error - Log a sis64 fabric error.
+ * @ioa_cfg:	ioa config struct
+ * @hostrcb:	hostrcb struct
+ *
+ * Return value:
+ * 	none
+ **/
+static void ipr_log_sis64_fabric_error(struct ipr_ioa_cfg *ioa_cfg,
+				       struct ipr_hostrcb *hostrcb)
+{
+	struct ipr_hostrcb_type_30_error *error;
+	struct ipr_hostrcb64_fabric_desc *fabric;
+	struct ipr_hostrcb64_config_element *cfg;
+	int i, add_len;
+
+	error = &hostrcb->hcam.u.error64.u.type_30_error;
+
+	error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
+	ipr_hcam_err(hostrcb, "%s\n", error->failure_reason);
+
+	add_len = be32_to_cpu(hostrcb->hcam.length) -
+		(offsetof(struct ipr_hostrcb64_error, u) +
+		 offsetof(struct ipr_hostrcb_type_30_error, desc));
+
+	for (i = 0, fabric = error->desc; i < error->num_entries; i++) {
+		ipr_log64_fabric_path(hostrcb, fabric);
+		for_each_fabric_cfg(fabric, cfg)
+			ipr_log64_path_elem(hostrcb, cfg);
+
+		add_len -= be16_to_cpu(fabric->length);
+		fabric = (struct ipr_hostrcb64_fabric_desc *)
+			((unsigned long)fabric + be16_to_cpu(fabric->length));
+	}
+
+	ipr_log_hex_data(ioa_cfg, (u32 *)fabric, add_len);
+}
+
+/**
  * ipr_log_generic_error - Log an adapter error.
  * @ioa_cfg:	ioa config struct
  * @hostrcb:	hostrcb struct
@@ -1642,13 +2264,16 @@ static void ipr_handle_log_data(struct i
 	if (hostrcb->hcam.notifications_lost == IPR_HOST_RCB_NOTIFICATIONS_LOST)
 		dev_err(&ioa_cfg->pdev->dev, "Error notifications lost\n");
 
-	ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc);
+	if (ioa_cfg->sis64)
+		ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc);
+	else
+		ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc);
 
-	if (ioasc == IPR_IOASC_BUS_WAS_RESET ||
-	    ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER) {
+	if (!ioa_cfg->sis64 && (ioasc == IPR_IOASC_BUS_WAS_RESET ||
+	    ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER)) {
 		/* Tell the midlayer we had a bus reset so it will handle the UA properly */
 		scsi_report_bus_reset(ioa_cfg->host,
-				      hostrcb->hcam.u.error.failing_dev_res_addr.bus);
+				      hostrcb->hcam.u.error.fd_res_addr.bus);
 	}
 
 	error_index = ipr_get_error(ioasc);
@@ -1696,6 +2321,16 @@ static void ipr_handle_log_data(struct i
 	case IPR_HOST_RCB_OVERLAY_ID_20:
 		ipr_log_fabric_error(ioa_cfg, hostrcb);
 		break;
+	case IPR_HOST_RCB_OVERLAY_ID_23:
+		ipr_log_sis64_config_error(ioa_cfg, hostrcb);
+		break;
+	case IPR_HOST_RCB_OVERLAY_ID_24:
+	case IPR_HOST_RCB_OVERLAY_ID_26:
+		ipr_log_sis64_array_error(ioa_cfg, hostrcb);
+		break;
+	case IPR_HOST_RCB_OVERLAY_ID_30:
+		ipr_log_sis64_fabric_error(ioa_cfg, hostrcb);
+		break;
 	case IPR_HOST_RCB_OVERLAY_ID_1:
 	case IPR_HOST_RCB_OVERLAY_ID_DEFAULT:
 	default:
@@ -1720,7 +2355,12 @@ static void ipr_process_error(struct ipr
 	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
 	struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb;
 	u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
-	u32 fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc);
+	u32 fd_ioasc;
+
+	if (ioa_cfg->sis64)
+		fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc);
+	else
+		fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc);
 
 	list_del(&hostrcb->queue);
 	list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
@@ -1845,12 +2485,14 @@ static const struct ipr_ses_table_entry
 ipr_find_ses_entry(struct ipr_resource_entry *res)
 {
 	int i, j, matches;
+	struct ipr_std_inq_vpids *vpids;
 	const struct ipr_ses_table_entry *ste = ipr_ses_table;
 
 	for (i = 0; i < ARRAY_SIZE(ipr_ses_table); i++, ste++) {
 		for (j = 0, matches = 0; j < IPR_PROD_ID_LEN; j++) {
 			if (ste->compare_product_id_byte[j] == 'X') {
-				if (res->cfgte.std_inq_data.vpids.product_id[j] == ste->product_id[j])
+				vpids = &res->std_inq_data.vpids;
+				if (vpids->product_id[j] == ste->product_id[j])
 					matches++;
 				else
 					break;
@@ -1885,10 +2527,10 @@ static u32 ipr_get_max_scsi_speed(struct
 
 	/* Loop through each config table entry in the config table buffer */
 	list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-		if (!(IPR_IS_SES_DEVICE(res->cfgte.std_inq_data)))
+		if (!(IPR_IS_SES_DEVICE(res->std_inq_data)))
 			continue;
 
-		if (bus != res->cfgte.res_addr.bus)
+		if (bus != res->bus)
 			continue;
 
 		if (!(ste = ipr_find_ses_entry(res)))
@@ -1934,6 +2576,31 @@ static int ipr_wait_iodbg_ack(struct ipr
 }
 
 /**
+ * ipr_get_sis64_dump_data_section - Dump IOA memory
+ * @ioa_cfg:			ioa config struct
+ * @start_addr:			adapter address to dump
+ * @dest:			destination kernel buffer
+ * @length_in_words:		length to dump in 4 byte words
+ *
+ * Return value:
+ * 	0 on success
+ **/
+static int ipr_get_sis64_dump_data_section(struct ipr_ioa_cfg *ioa_cfg,
+					   u32 start_addr,
+					   __be32 *dest, u32 length_in_words)
+{
+	int i;
+
+	for (i = 0; i < length_in_words; i++) {
+		writel(start_addr+(i*4), ioa_cfg->regs.dump_addr_reg);
+		*dest = cpu_to_be32(readl(ioa_cfg->regs.dump_data_reg));
+		dest++;
+	}
+
+	return 0;
+}
+
+/**
  * ipr_get_ldump_data_section - Dump IOA memory
  * @ioa_cfg:			ioa config struct
  * @start_addr:			adapter address to dump
@@ -1950,9 +2617,13 @@ static int ipr_get_ldump_data_section(st
 	volatile u32 temp_pcii_reg;
 	int i, delay = 0;
 
+	if (ioa_cfg->sis64)
+		return ipr_get_sis64_dump_data_section(ioa_cfg, start_addr,
+						       dest, length_in_words);
+
 	/* Write IOA interrupt reg starting LDUMP state  */
 	writel((IPR_UPROCI_RESET_ALERT | IPR_UPROCI_IO_DEBUG_ALERT),
-	       ioa_cfg->regs.set_uproc_interrupt_reg);
+	       ioa_cfg->regs.set_uproc_interrupt_reg32);
 
 	/* Wait for IO debug acknowledge */
 	if (ipr_wait_iodbg_ack(ioa_cfg,
@@ -1971,7 +2642,7 @@ static int ipr_get_ldump_data_section(st
 
 	/* Signal address valid - clear IOA Reset alert */
 	writel(IPR_UPROCI_RESET_ALERT,
-	       ioa_cfg->regs.clr_uproc_interrupt_reg);
+	       ioa_cfg->regs.clr_uproc_interrupt_reg32);
 
 	for (i = 0; i < length_in_words; i++) {
 		/* Wait for IO debug acknowledge */
@@ -1996,10 +2667,10 @@ static int ipr_get_ldump_data_section(st
 
 	/* Signal end of block transfer. Set reset alert then clear IO debug ack */
 	writel(IPR_UPROCI_RESET_ALERT,
-	       ioa_cfg->regs.set_uproc_interrupt_reg);
+	       ioa_cfg->regs.set_uproc_interrupt_reg32);
 
 	writel(IPR_UPROCI_IO_DEBUG_ALERT,
-	       ioa_cfg->regs.clr_uproc_interrupt_reg);
+	       ioa_cfg->regs.clr_uproc_interrupt_reg32);
 
 	/* Signal dump data received - Clear IO debug Ack */
 	writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE,
@@ -2008,7 +2679,7 @@ static int ipr_get_ldump_data_section(st
 	/* Wait for IOA to signal LDUMP exit - IOA reset alert will be cleared */
 	while (delay < IPR_LDUMP_MAX_SHORT_ACK_DELAY_IN_USEC) {
 		temp_pcii_reg =
-		    readl(ioa_cfg->regs.sense_uproc_interrupt_reg);
+		    readl(ioa_cfg->regs.sense_uproc_interrupt_reg32);
 
 		if (!(temp_pcii_reg & IPR_UPROCI_RESET_ALERT))
 			return 0;
@@ -2207,6 +2878,7 @@ static void ipr_get_ioa_dump(struct ipr_
 	u32 num_entries, start_off, end_off;
 	u32 bytes_to_copy, bytes_copied, rc;
 	struct ipr_sdt *sdt;
+	int valid = 1;
 	int i;
 
 	ENTER;
@@ -2220,7 +2892,7 @@ static void ipr_get_ioa_dump(struct ipr_
 
 	start_addr = readl(ioa_cfg->ioa_mailbox);
 
-	if (!ipr_sdt_is_fmt2(start_addr)) {
+	if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(start_addr)) {
 		dev_err(&ioa_cfg->pdev->dev,
 			"Invalid dump table format: %lx\n", start_addr);
 		spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -2249,7 +2921,6 @@ static void ipr_get_ioa_dump(struct ipr_
 
 	/* IOA Dump entry */
 	ipr_init_dump_entry_hdr(&ioa_dump->hdr);
-	ioa_dump->format = IPR_SDT_FMT2;
 	ioa_dump->hdr.len = 0;
 	ioa_dump->hdr.data_type = IPR_DUMP_DATA_TYPE_BINARY;
 	ioa_dump->hdr.id = IPR_DUMP_IOA_DUMP_ID;
@@ -2264,7 +2935,8 @@ static void ipr_get_ioa_dump(struct ipr_
 					sizeof(struct ipr_sdt) / sizeof(__be32));
 
 	/* Smart Dump table is ready to use and the first entry is valid */
-	if (rc || (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE)) {
+	if (rc || ((be32_to_cpu(sdt->hdr.state) != IPR_FMT3_SDT_READY_TO_USE) &&
+	    (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) {
 		dev_err(&ioa_cfg->pdev->dev,
 			"Dump of IOA failed. Dump table not valid: %d, %X.\n",
 			rc, be32_to_cpu(sdt->hdr.state));
@@ -2288,12 +2960,19 @@ static void ipr_get_ioa_dump(struct ipr_
 		}
 
 		if (sdt->entry[i].flags & IPR_SDT_VALID_ENTRY) {
-			sdt_word = be32_to_cpu(sdt->entry[i].bar_str_offset);
-			start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK;
-			end_off = be32_to_cpu(sdt->entry[i].end_offset);
+			sdt_word = be32_to_cpu(sdt->entry[i].start_token);
+			if (ioa_cfg->sis64)
+				bytes_to_copy = be32_to_cpu(sdt->entry[i].end_token);
+			else {
+				start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK;
+				end_off = be32_to_cpu(sdt->entry[i].end_token);
 
-			if (ipr_sdt_is_fmt2(sdt_word) && sdt_word) {
-				bytes_to_copy = end_off - start_off;
+				if (ipr_sdt_is_fmt2(sdt_word) && sdt_word)
+					bytes_to_copy = end_off - start_off;
+				else
+					valid = 0;
+			}
+			if (valid) {
 				if (bytes_to_copy > IPR_MAX_IOA_DUMP_SIZE) {
 					sdt->entry[i].flags &= ~IPR_SDT_VALID_ENTRY;
 					continue;
@@ -2422,9 +3101,9 @@ restart:
 
 	list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
 		if (res->add_to_ml) {
-			bus = res->cfgte.res_addr.bus;
-			target = res->cfgte.res_addr.target;
-			lun = res->cfgte.res_addr.lun;
+			bus = res->bus;
+			target = res->target;
+			lun = res->lun;
 			res->add_to_ml = 0;
 			spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
 			scsi_add_device(ioa_cfg->host, bus, target, lun);
@@ -2478,105 +3157,6 @@ static struct bin_attribute ipr_trace_at
 };
 #endif
 
-static const struct {
-	enum ipr_cache_state state;
-	char *name;
-} cache_state [] = {
-	{ CACHE_NONE, "none" },
-	{ CACHE_DISABLED, "disabled" },
-	{ CACHE_ENABLED, "enabled" }
-};
-
-/**
- * ipr_show_write_caching - Show the write caching attribute
- * @dev:	device struct
- * @buf:	buffer
- *
- * Return value:
- *	number of bytes printed to buffer
- **/
-static ssize_t ipr_show_write_caching(struct device *dev,
-				      struct device_attribute *attr, char *buf)
-{
-	struct Scsi_Host *shost = class_to_shost(dev);
-	struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata;
-	unsigned long lock_flags = 0;
-	int i, len = 0;
-
-	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
-	for (i = 0; i < ARRAY_SIZE(cache_state); i++) {
-		if (cache_state[i].state == ioa_cfg->cache_state) {
-			len = snprintf(buf, PAGE_SIZE, "%s\n", cache_state[i].name);
-			break;
-		}
-	}
-	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-	return len;
-}
-
-
-/**
- * ipr_store_write_caching - Enable/disable adapter write cache
- * @dev:	device struct
- * @buf:	buffer
- * @count:	buffer size
- *
- * This function will enable/disable adapter write cache.
- *
- * Return value:
- * 	count on success / other on failure
- **/
-static ssize_t ipr_store_write_caching(struct device *dev,
-				       struct device_attribute *attr,
-				       const char *buf, size_t count)
-{
-	struct Scsi_Host *shost = class_to_shost(dev);
-	struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata;
-	unsigned long lock_flags = 0;
-	enum ipr_cache_state new_state = CACHE_INVALID;
-	int i;
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EACCES;
-	if (ioa_cfg->cache_state == CACHE_NONE)
-		return -EINVAL;
-
-	for (i = 0; i < ARRAY_SIZE(cache_state); i++) {
-		if (!strncmp(cache_state[i].name, buf, strlen(cache_state[i].name))) {
-			new_state = cache_state[i].state;
-			break;
-		}
-	}
-
-	if (new_state != CACHE_DISABLED && new_state != CACHE_ENABLED)
-		return -EINVAL;
-
-	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
-	if (ioa_cfg->cache_state == new_state) {
-		spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-		return count;
-	}
-
-	ioa_cfg->cache_state = new_state;
-	dev_info(&ioa_cfg->pdev->dev, "%s adapter write cache.\n",
-		 new_state == CACHE_ENABLED ? "Enabling" : "Disabling");
-	if (!ioa_cfg->in_reset_reload)
-		ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL);
-	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-	wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
-
-	return count;
-}
-
-static struct device_attribute ipr_ioa_cache_attr = {
-	.attr = {
-		.name =		"write_cache",
-		.mode =		S_IRUGO | S_IWUSR,
-	},
-	.show = ipr_show_write_caching,
-	.store = ipr_store_write_caching
-};
-
 /**
  * ipr_show_fw_version - Show the firmware version
  * @dev:	class device struct
@@ -2976,6 +3556,37 @@ static int ipr_copy_ucode_buffer(struct
 }
 
 /**
+ * ipr_build_ucode_ioadl64 - Build a microcode download IOADL
+ * @ipr_cmd:		ipr command struct
+ * @sglist:		scatter/gather list
+ *
+ * Builds a microcode download IOA data list (IOADL).
+ *
+ **/
+static void ipr_build_ucode_ioadl64(struct ipr_cmnd *ipr_cmd,
+				    struct ipr_sglist *sglist)
+{
+	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
+	struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
+	struct scatterlist *scatterlist = sglist->scatterlist;
+	int i;
+
+	ipr_cmd->dma_use_sg = sglist->num_dma_sg;
+	ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
+	ioarcb->data_transfer_length = cpu_to_be32(sglist->buffer_len);
+
+	ioarcb->ioadl_len =
+		cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg);
+	for (i = 0; i < ipr_cmd->dma_use_sg; i++) {
+		ioadl64[i].flags = cpu_to_be32(IPR_IOADL_FLAGS_WRITE);
+		ioadl64[i].data_len = cpu_to_be32(sg_dma_len(&scatterlist[i]));
+		ioadl64[i].address = cpu_to_be64(sg_dma_address(&scatterlist[i]));
+	}
+
+	ioadl64[i-1].flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
+}
+
+/**
  * ipr_build_ucode_ioadl - Build a microcode download IOADL
  * @ipr_cmd:	ipr command struct
  * @sglist:		scatter/gather list
@@ -2987,14 +3598,15 @@ static void ipr_build_ucode_ioadl(struct
 				  struct ipr_sglist *sglist)
 {
 	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
-	struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+	struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
 	struct scatterlist *scatterlist = sglist->scatterlist;
 	int i;
 
 	ipr_cmd->dma_use_sg = sglist->num_dma_sg;
 	ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
-	ioarcb->write_data_transfer_length = cpu_to_be32(sglist->buffer_len);
-	ioarcb->write_ioadl_len =
+	ioarcb->data_transfer_length = cpu_to_be32(sglist->buffer_len);
+
+	ioarcb->ioadl_len =
 		cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
 
 	for (i = 0; i < ipr_cmd->dma_use_sg; i++) {
@@ -3146,7 +3758,6 @@ static struct device_attribute *ipr_ioa_
 	&ipr_ioa_state_attr,
 	&ipr_ioa_reset_attr,
 	&ipr_update_fw_attr,
-	&ipr_ioa_cache_attr,
 	NULL,
 };
 
@@ -3450,7 +4061,7 @@ static ssize_t ipr_show_adapter_handle(s
 	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
 	res = (struct ipr_resource_entry *)sdev->hostdata;
 	if (res)
-		len = snprintf(buf, PAGE_SIZE, "%08X\n", res->cfgte.res_handle);
+		len = snprintf(buf, PAGE_SIZE, "%08X\n", res->res_handle);
 	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
 	return len;
 }
@@ -3463,8 +4074,43 @@ static struct device_attribute ipr_adapt
 	.show = ipr_show_adapter_handle
 };
 
+/**
+ * ipr_show_resource_path - Show the resource path for this device.
+ * @dev:	device struct
+ * @buf:	buffer
+ *
+ * Return value:
+ * 	number of bytes printed to buffer
+ **/
+static ssize_t ipr_show_resource_path(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
+	struct ipr_resource_entry *res;
+	unsigned long lock_flags = 0;
+	ssize_t len = -ENXIO;
+	char buffer[IPR_MAX_RES_PATH_LENGTH];
+
+	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+	res = (struct ipr_resource_entry *)sdev->hostdata;
+	if (res)
+		len = snprintf(buf, PAGE_SIZE, "%s\n",
+			       ipr_format_resource_path(&res->res_path[0], &buffer[0]));
+	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+	return len;
+}
+
+static struct device_attribute ipr_resource_path_attr = {
+	.attr = {
+		.name = 	"resource_path",
+		.mode =		S_IRUSR,
+	},
+	.show = ipr_show_resource_path
+};
+
 static struct device_attribute *ipr_dev_attrs[] = {
 	&ipr_adapter_handle_attr,
+	&ipr_resource_path_attr,
 	NULL,
 };
 
@@ -3517,9 +4163,9 @@ static struct ipr_resource_entry *ipr_fi
 	struct ipr_resource_entry *res;
 
 	list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-		if ((res->cfgte.res_addr.bus == starget->channel) &&
-		    (res->cfgte.res_addr.target == starget->id) &&
-		    (res->cfgte.res_addr.lun == 0)) {
+		if ((res->bus == starget->channel) &&
+		    (res->target == starget->id) &&
+		    (res->lun == 0)) {
 			return res;
 		}
 	}
@@ -3589,6 +4235,17 @@ static int ipr_target_alloc(struct scsi_
 static void ipr_target_destroy(struct scsi_target *starget)
 {
 	struct ipr_sata_port *sata_port = starget->hostdata;
+	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+	struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata;
+
+	if (ioa_cfg->sis64) {
+		if (starget->channel == IPR_ARRAY_VIRTUAL_BUS)
+			clear_bit(starget->id, ioa_cfg->array_ids);
+		else if (starget->channel == IPR_VSET_VIRTUAL_BUS)
+			clear_bit(starget->id, ioa_cfg->vset_ids);
+		else if (starget->channel == 0)
+			clear_bit(starget->id, ioa_cfg->target_ids);
+	}
 
 	if (sata_port) {
 		starget->hostdata = NULL;
@@ -3610,9 +4267,9 @@ static struct ipr_resource_entry *ipr_fi
 	struct ipr_resource_entry *res;
 
 	list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-		if ((res->cfgte.res_addr.bus == sdev->channel) &&
-		    (res->cfgte.res_addr.target == sdev->id) &&
-		    (res->cfgte.res_addr.lun == sdev->lun))
+		if ((res->bus == sdev->channel) &&
+		    (res->target == sdev->id) &&
+		    (res->lun == sdev->lun))
 			return res;
 	}
 
@@ -3661,6 +4318,7 @@ static int ipr_slave_configure(struct sc
 	struct ipr_resource_entry *res;
 	struct ata_port *ap = NULL;
 	unsigned long lock_flags = 0;
+	char buffer[IPR_MAX_RES_PATH_LENGTH];
 
 	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
 	res = sdev->hostdata;
@@ -3674,7 +4332,7 @@ static int ipr_slave_configure(struct sc
 		if (ipr_is_vset_device(res)) {
 			blk_queue_rq_timeout(sdev->request_queue,
 					     IPR_VSET_RW_TIMEOUT);
-			blk_queue_max_sectors(sdev->request_queue, IPR_VSET_MAX_SECTORS);
+			blk_queue_max_hw_sectors(sdev->request_queue, IPR_VSET_MAX_SECTORS);
 		}
 		if (ipr_is_vset_device(res) || ipr_is_scsi_disk(res))
 			sdev->allow_restart = 1;
@@ -3687,6 +4345,9 @@ static int ipr_slave_configure(struct sc
 			ata_sas_slave_configure(sdev, ap);
 		} else
 			scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
+		if (ioa_cfg->sis64)
+			sdev_printk(KERN_INFO, sdev, "Resource path: %s\n",
+			            ipr_format_resource_path(&res->res_path[0], &buffer[0]));
 		return 0;
 	}
 	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -3828,14 +4489,19 @@ static int ipr_device_reset(struct ipr_i
 	ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
 	ioarcb = &ipr_cmd->ioarcb;
 	cmd_pkt = &ioarcb->cmd_pkt;
-	regs = &ioarcb->add_data.u.regs;
 
-	ioarcb->res_handle = res->cfgte.res_handle;
+	if (ipr_cmd->ioa_cfg->sis64) {
+		regs = &ipr_cmd->i.ata_ioadl.regs;
+		ioarcb->add_cmd_parms_offset = cpu_to_be16(sizeof(*ioarcb));
+	} else
+		regs = &ioarcb->u.add_data.u.regs;
+
+	ioarcb->res_handle = res->res_handle;
 	cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
 	cmd_pkt->cdb[0] = IPR_RESET_DEVICE;
 	if (ipr_is_gata(res)) {
 		cmd_pkt->cdb[2] = IPR_ATA_PHY_RESET;
-		ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(regs->flags));
+		ioarcb->add_cmd_parms_len = cpu_to_be16(sizeof(regs->flags));
 		regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;
 	}
 
@@ -3880,19 +4546,7 @@ static int ipr_sata_reset(struct ata_lin
 	res = sata_port->res;
 	if (res) {
 		rc = ipr_device_reset(ioa_cfg, res);
-		switch(res->cfgte.proto) {
-		case IPR_PROTO_SATA:
-		case IPR_PROTO_SAS_STP:
-			*classes = ATA_DEV_ATA;
-			break;
-		case IPR_PROTO_SATA_ATAPI:
-		case IPR_PROTO_SAS_STP_ATAPI:
-			*classes = ATA_DEV_ATAPI;
-			break;
-		default:
-			*classes = ATA_DEV_UNKNOWN;
-			break;
-		};
+		*classes = res->ata_class;
 	}
 
 	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -3937,7 +4591,7 @@ static int __ipr_eh_dev_reset(struct scs
 		return FAILED;
 
 	list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
-		if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) {
+		if (ipr_cmd->ioarcb.res_handle == res->res_handle) {
 			if (ipr_cmd->scsi_cmd)
 				ipr_cmd->done = ipr_scsi_eh_done;
 			if (ipr_cmd->qc)
@@ -3959,7 +4613,7 @@ static int __ipr_eh_dev_reset(struct scs
 		spin_lock_irq(scsi_cmd->device->host->host_lock);
 
 		list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
-			if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) {
+			if (ipr_cmd->ioarcb.res_handle == res->res_handle) {
 				rc = -EIO;
 				break;
 			}
@@ -3998,13 +4652,13 @@ static void ipr_bus_reset_done(struct ip
 	struct ipr_resource_entry *res;
 
 	ENTER;
-	list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-		if (!memcmp(&res->cfgte.res_handle, &ipr_cmd->ioarcb.res_handle,
-			    sizeof(res->cfgte.res_handle))) {
-			scsi_report_bus_reset(ioa_cfg->host, res->cfgte.res_addr.bus);
-			break;
+	if (!ioa_cfg->sis64)
+		list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
+			if (res->res_handle == ipr_cmd->ioarcb.res_handle) {
+				scsi_report_bus_reset(ioa_cfg->host, res->bus);
+				break;
+			}
 		}
-	}
 
 	/*
 	 * If abort has not completed, indicate the reset has, else call the
@@ -4102,7 +4756,7 @@ static int ipr_cancel_op(struct scsi_cmn
 		return SUCCESS;
 
 	ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
-	ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle;
+	ipr_cmd->ioarcb.res_handle = res->res_handle;
 	cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt;
 	cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
 	cmd_pkt->cdb[0] = IPR_CANCEL_ALL_REQUESTS;
@@ -4239,11 +4893,29 @@ static irqreturn_t ipr_isr(int irq, void
 		return IRQ_NONE;
 	}
 
-	int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
-	int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+	int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32);
+	int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg;
 
-	/* If an interrupt on the adapter did not occur, ignore it */
+	/* If an interrupt on the adapter did not occur, ignore it.
+	 * Or in the case of SIS 64, check for a stage change interrupt.
+	 */
 	if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) {
+		if (ioa_cfg->sis64) {
+			int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+			int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+			if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) {
+
+				/* clear stage change */
+				writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg);
+				int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+				list_del(&ioa_cfg->reset_cmd->queue);
+				del_timer(&ioa_cfg->reset_cmd->timer);
+				ipr_reset_ioa_job(ioa_cfg->reset_cmd);
+				spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+				return IRQ_HANDLED;
+			}
+		}
+
 		spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
 		return IRQ_NONE;
 	}
@@ -4286,8 +4958,8 @@ static irqreturn_t ipr_isr(int irq, void
 		if (ipr_cmd != NULL) {
 			/* Clear the PCI interrupt */
 			do {
-				writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg);
-				int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+				writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32);
+				int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg;
 			} while (int_reg & IPR_PCII_HRRQ_UPDATED &&
 					num_hrrq++ < IPR_MAX_HRRQ_RETRIES);
 
@@ -4309,6 +4981,53 @@ static irqreturn_t ipr_isr(int irq, void
 }
 
 /**
+ * ipr_build_ioadl64 - Build a scatter/gather list and map the buffer
+ * @ioa_cfg:	ioa config struct
+ * @ipr_cmd:	ipr command struct
+ *
+ * Return value:
+ * 	0 on success / -1 on failure
+ **/
+static int ipr_build_ioadl64(struct ipr_ioa_cfg *ioa_cfg,
+			     struct ipr_cmnd *ipr_cmd)
+{
+	int i, nseg;
+	struct scatterlist *sg;
+	u32 length;
+	u32 ioadl_flags = 0;
+	struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
+	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
+	struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
+
+	length = scsi_bufflen(scsi_cmd);
+	if (!length)
+		return 0;
+
+	nseg = scsi_dma_map(scsi_cmd);
+	if (nseg < 0) {
+		dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");
+		return -1;
+	}
+
+	ipr_cmd->dma_use_sg = nseg;
+
+	if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) {
+		ioadl_flags = IPR_IOADL_FLAGS_WRITE;
+		ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
+	} else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE)
+		ioadl_flags = IPR_IOADL_FLAGS_READ;
+
+	scsi_for_each_sg(scsi_cmd, sg, ipr_cmd->dma_use_sg, i) {
+		ioadl64[i].flags = cpu_to_be32(ioadl_flags);
+		ioadl64[i].data_len = cpu_to_be32(sg_dma_len(sg));
+		ioadl64[i].address = cpu_to_be64(sg_dma_address(sg));
+	}
+
+	ioadl64[i-1].flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
+	return 0;
+}
+
+/**
  * ipr_build_ioadl - Build a scatter/gather list and map the buffer
  * @ioa_cfg:	ioa config struct
  * @ipr_cmd:	ipr command struct
@@ -4325,7 +5044,7 @@ static int ipr_build_ioadl(struct ipr_io
 	u32 ioadl_flags = 0;
 	struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
 	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
-	struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+	struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
 
 	length = scsi_bufflen(scsi_cmd);
 	if (!length)
@@ -4342,8 +5061,8 @@ static int ipr_build_ioadl(struct ipr_io
 	if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) {
 		ioadl_flags = IPR_IOADL_FLAGS_WRITE;
 		ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
-		ioarcb->write_data_transfer_length = cpu_to_be32(length);
-		ioarcb->write_ioadl_len =
+		ioarcb->data_transfer_length = cpu_to_be32(length);
+		ioarcb->ioadl_len =
 			cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
 	} else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) {
 		ioadl_flags = IPR_IOADL_FLAGS_READ;
@@ -4352,11 +5071,10 @@ static int ipr_build_ioadl(struct ipr_io
 			cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
 	}
 
-	if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->add_data.u.ioadl)) {
-		ioadl = ioarcb->add_data.u.ioadl;
-		ioarcb->write_ioadl_addr =
-			cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) +
-				    offsetof(struct ipr_ioarcb, add_data));
+	if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->u.add_data.u.ioadl)) {
+		ioadl = ioarcb->u.add_data.u.ioadl;
+		ioarcb->write_ioadl_addr = cpu_to_be32((ipr_cmd->dma_addr) +
+				    offsetof(struct ipr_ioarcb, u.add_data));
 		ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
 	}
 
@@ -4446,18 +5164,24 @@ static void ipr_reinit_ipr_cmnd_for_erp(
 {
 	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
 	struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
-	dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr);
+	dma_addr_t dma_addr = ipr_cmd->dma_addr;
 
 	memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt));
-	ioarcb->write_data_transfer_length = 0;
+	ioarcb->data_transfer_length = 0;
 	ioarcb->read_data_transfer_length = 0;
-	ioarcb->write_ioadl_len = 0;
+	ioarcb->ioadl_len = 0;
 	ioarcb->read_ioadl_len = 0;
 	ioasa->ioasc = 0;
 	ioasa->residual_data_len = 0;
-	ioarcb->write_ioadl_addr =
-		cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl));
-	ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+
+	if (ipr_cmd->ioa_cfg->sis64)
+		ioarcb->u.sis64_addr_data.data_ioadl_addr =
+			cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64));
+	else {
+		ioarcb->write_ioadl_addr =
+			cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl));
+		ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+	}
 }
 
 /**
@@ -4489,15 +5213,8 @@ static void ipr_erp_request_sense(struct
 	cmd_pkt->flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
 	cmd_pkt->timeout = cpu_to_be16(IPR_REQUEST_SENSE_TIMEOUT / HZ);
 
-	ipr_cmd->ioadl[0].flags_and_data_len =
-		cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | SCSI_SENSE_BUFFERSIZE);
-	ipr_cmd->ioadl[0].address =
-		cpu_to_be32(ipr_cmd->sense_buffer_dma);
-
-	ipr_cmd->ioarcb.read_ioadl_len =
-		cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-	ipr_cmd->ioarcb.read_data_transfer_length =
-		cpu_to_be32(SCSI_SENSE_BUFFERSIZE);
+	ipr_init_ioadl(ipr_cmd, ipr_cmd->sense_buffer_dma,
+		       SCSI_SENSE_BUFFERSIZE, IPR_IOADL_FLAGS_READ_LAST);
 
 	ipr_do_req(ipr_cmd, ipr_erp_done, ipr_timeout,
 		   IPR_REQUEST_SENSE_TIMEOUT * 2);
@@ -4893,9 +5610,9 @@ static int ipr_queuecommand(struct scsi_
 
 	memcpy(ioarcb->cmd_pkt.cdb, scsi_cmd->cmnd, scsi_cmd->cmd_len);
 	ipr_cmd->scsi_cmd = scsi_cmd;
-	ioarcb->res_handle = res->cfgte.res_handle;
+	ioarcb->res_handle = res->res_handle;
 	ipr_cmd->done = ipr_scsi_done;
-	ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr));
+	ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res));
 
 	if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) {
 		if (scsi_cmd->underflow == 0)
@@ -4916,13 +5633,16 @@ static int ipr_queuecommand(struct scsi_
 	    (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE))
 		ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
 
-	if (likely(rc == 0))
-		rc = ipr_build_ioadl(ioa_cfg, ipr_cmd);
+	if (likely(rc == 0)) {
+		if (ioa_cfg->sis64)
+			rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd);
+		else
+			rc = ipr_build_ioadl(ioa_cfg, ipr_cmd);
+	}
 
 	if (likely(rc == 0)) {
 		mb();
-		writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr),
-		       ioa_cfg->regs.ioarrin_reg);
+		ipr_send_command(ipr_cmd);
 	} else {
 		 list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
 		 return SCSI_MLQUEUE_HOST_BUSY;
@@ -5035,20 +5755,9 @@ static void ipr_ata_phy_reset(struct ata
 		goto out_unlock;
 	}
 
-	switch(res->cfgte.proto) {
-	case IPR_PROTO_SATA:
-	case IPR_PROTO_SAS_STP:
-		ap->link.device[0].class = ATA_DEV_ATA;
-		break;
-	case IPR_PROTO_SATA_ATAPI:
-	case IPR_PROTO_SAS_STP_ATAPI:
-		ap->link.device[0].class = ATA_DEV_ATAPI;
-		break;
-	default:
-		ap->link.device[0].class = ATA_DEV_UNKNOWN;
+	ap->link.device[0].class = res->ata_class;
+	if (ap->link.device[0].class == ATA_DEV_UNKNOWN)
 		ata_port_disable(ap);
-		break;
-	};
 
 out_unlock:
 	spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
@@ -5134,8 +5843,7 @@ static void ipr_sata_done(struct ipr_cmn
 	ipr_dump_ioasa(ioa_cfg, ipr_cmd, res);
 
 	if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET)
-		scsi_report_device_reset(ioa_cfg->host, res->cfgte.res_addr.bus,
-					 res->cfgte.res_addr.target);
+		scsi_report_device_reset(ioa_cfg->host, res->bus, res->target);
 
 	if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR)
 		qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status);
@@ -5146,6 +5854,52 @@ static void ipr_sata_done(struct ipr_cmn
 }
 
 /**
+ * ipr_build_ata_ioadl64 - Build an ATA scatter/gather list
+ * @ipr_cmd:	ipr command struct
+ * @qc:		ATA queued command
+ *
+ **/
+static void ipr_build_ata_ioadl64(struct ipr_cmnd *ipr_cmd,
+				  struct ata_queued_cmd *qc)
+{
+	u32 ioadl_flags = 0;
+	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
+	struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
+	struct ipr_ioadl64_desc *last_ioadl64 = NULL;
+	int len = qc->nbytes;
+	struct scatterlist *sg;
+	unsigned int si;
+	dma_addr_t dma_addr = ipr_cmd->dma_addr;
+
+	if (len == 0)
+		return;
+
+	if (qc->dma_dir == DMA_TO_DEVICE) {
+		ioadl_flags = IPR_IOADL_FLAGS_WRITE;
+		ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
+	} else if (qc->dma_dir == DMA_FROM_DEVICE)
+		ioadl_flags = IPR_IOADL_FLAGS_READ;
+
+	ioarcb->data_transfer_length = cpu_to_be32(len);
+	ioarcb->ioadl_len =
+		cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg);
+	ioarcb->u.sis64_addr_data.data_ioadl_addr =
+		cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ata_ioadl));
+
+	for_each_sg(qc->sg, sg, qc->n_elem, si) {
+		ioadl64->flags = cpu_to_be32(ioadl_flags);
+		ioadl64->data_len = cpu_to_be32(sg_dma_len(sg));
+		ioadl64->address = cpu_to_be64(sg_dma_address(sg));
+
+		last_ioadl64 = ioadl64;
+		ioadl64++;
+	}
+
+	if (likely(last_ioadl64))
+		last_ioadl64->flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
+}
+
+/**
  * ipr_build_ata_ioadl - Build an ATA scatter/gather list
  * @ipr_cmd:	ipr command struct
  * @qc:		ATA queued command
@@ -5156,7 +5910,7 @@ static void ipr_build_ata_ioadl(struct i
 {
 	u32 ioadl_flags = 0;
 	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
-	struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+	struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
 	struct ipr_ioadl_desc *last_ioadl = NULL;
 	int len = qc->nbytes;
 	struct scatterlist *sg;
@@ -5168,8 +5922,8 @@ static void ipr_build_ata_ioadl(struct i
 	if (qc->dma_dir == DMA_TO_DEVICE) {
 		ioadl_flags = IPR_IOADL_FLAGS_WRITE;
 		ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
-		ioarcb->write_data_transfer_length = cpu_to_be32(len);
-		ioarcb->write_ioadl_len =
+		ioarcb->data_transfer_length = cpu_to_be32(len);
+		ioarcb->ioadl_len =
 			cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
 	} else if (qc->dma_dir == DMA_FROM_DEVICE) {
 		ioadl_flags = IPR_IOADL_FLAGS_READ;
@@ -5212,25 +5966,34 @@ static unsigned int ipr_qc_issue(struct
 
 	ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
 	ioarcb = &ipr_cmd->ioarcb;
-	regs = &ioarcb->add_data.u.regs;
 
-	memset(&ioarcb->add_data, 0, sizeof(ioarcb->add_data));
-	ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(ioarcb->add_data.u.regs));
+	if (ioa_cfg->sis64) {
+		regs = &ipr_cmd->i.ata_ioadl.regs;
+		ioarcb->add_cmd_parms_offset = cpu_to_be16(sizeof(*ioarcb));
+	} else
+		regs = &ioarcb->u.add_data.u.regs;
+
+	memset(regs, 0, sizeof(*regs));
+	ioarcb->add_cmd_parms_len = cpu_to_be16(sizeof(*regs));
 
 	list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
 	ipr_cmd->qc = qc;
 	ipr_cmd->done = ipr_sata_done;
-	ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle;
+	ipr_cmd->ioarcb.res_handle = res->res_handle;
 	ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU;
 	ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;
 	ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
 	ipr_cmd->dma_use_sg = qc->n_elem;
 
-	ipr_build_ata_ioadl(ipr_cmd, qc);
+	if (ioa_cfg->sis64)
+		ipr_build_ata_ioadl64(ipr_cmd, qc);
+	else
+		ipr_build_ata_ioadl(ipr_cmd, qc);
+
 	regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;
 	ipr_copy_sata_tf(regs, &qc->tf);
 	memcpy(ioarcb->cmd_pkt.cdb, qc->cdb, IPR_MAX_CDB_LEN);
-	ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr));
+	ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res));
 
 	switch (qc->tf.protocol) {
 	case ATA_PROT_NODATA:
@@ -5257,8 +6020,9 @@ static unsigned int ipr_qc_issue(struct
 	}
 
 	mb();
-	writel(be32_to_cpu(ioarcb->ioarcb_host_pci_addr),
-	       ioa_cfg->regs.ioarrin_reg);
+
+	ipr_send_command(ipr_cmd);
+
 	return 0;
 }
 
@@ -5459,7 +6223,7 @@ static void ipr_set_sup_dev_dflt(struct
  * ipr_set_supported_devs - Send Set Supported Devices for a device
  * @ipr_cmd:	ipr command struct
  *
- * This function send a Set Supported Devices to the adapter
+ * This function sends a Set Supported Devices to the adapter
  *
  * Return value:
  * 	IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
@@ -5468,7 +6232,6 @@ static int ipr_set_supported_devs(struct
 {
 	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
 	struct ipr_supported_device *supp_dev = &ioa_cfg->vpd_cbs->supp_dev;
-	struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
 	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
 	struct ipr_resource_entry *res = ipr_cmd->u.res;
 
@@ -5479,28 +6242,28 @@ static int ipr_set_supported_devs(struct
 			continue;
 
 		ipr_cmd->u.res = res;
-		ipr_set_sup_dev_dflt(supp_dev, &res->cfgte.std_inq_data.vpids);
+		ipr_set_sup_dev_dflt(supp_dev, &res->std_inq_data.vpids);
 
 		ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
 		ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
 		ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
 
 		ioarcb->cmd_pkt.cdb[0] = IPR_SET_SUPPORTED_DEVICES;
+		ioarcb->cmd_pkt.cdb[1] = IPR_SET_ALL_SUPPORTED_DEVICES;
 		ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_supported_device) >> 8) & 0xff;
 		ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_supported_device) & 0xff;
 
-		ioadl->flags_and_data_len = cpu_to_be32(IPR_IOADL_FLAGS_WRITE_LAST |
-							sizeof(struct ipr_supported_device));
-		ioadl->address = cpu_to_be32(ioa_cfg->vpd_cbs_dma +
-					     offsetof(struct ipr_misc_cbs, supp_dev));
-		ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-		ioarcb->write_data_transfer_length =
-			cpu_to_be32(sizeof(struct ipr_supported_device));
+		ipr_init_ioadl(ipr_cmd,
+			       ioa_cfg->vpd_cbs_dma +
+				 offsetof(struct ipr_misc_cbs, supp_dev),
+			       sizeof(struct ipr_supported_device),
+			       IPR_IOADL_FLAGS_WRITE_LAST);
 
 		ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout,
 			   IPR_SET_SUP_DEVICE_TIMEOUT);
 
-		ipr_cmd->job_step = ipr_set_supported_devs;
+		if (!ioa_cfg->sis64)
+			ipr_cmd->job_step = ipr_set_supported_devs;
 		return IPR_RC_JOB_RETURN;
 	}
 
@@ -5508,36 +6271,6 @@ static int ipr_set_supported_devs(struct
 }
 
 /**
- * ipr_setup_write_cache - Disable write cache if needed
- * @ipr_cmd:	ipr command struct
- *
- * This function sets up adapters write cache to desired setting
- *
- * Return value:
- * 	IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
- **/
-static int ipr_setup_write_cache(struct ipr_cmnd *ipr_cmd)
-{
-	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
-
-	ipr_cmd->job_step = ipr_set_supported_devs;
-	ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next,
-				    struct ipr_resource_entry, queue);
-
-	if (ioa_cfg->cache_state != CACHE_DISABLED)
-		return IPR_RC_JOB_CONTINUE;
-
-	ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
-	ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
-	ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN;
-	ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL;
-
-	ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
-
-	return IPR_RC_JOB_RETURN;
-}
-
-/**
  * ipr_get_mode_page - Locate specified mode page
  * @mode_pages:	mode page buffer
  * @page_code:	page code to find
@@ -5695,10 +6428,9 @@ static void ipr_modify_ioafp_mode_page_2
  * 	none
  **/
 static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd,
-				  __be32 res_handle, u8 parm, u32 dma_addr,
-				  u8 xfer_len)
+				  __be32 res_handle, u8 parm,
+				  dma_addr_t dma_addr, u8 xfer_len)
 {
-	struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
 	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
 
 	ioarcb->res_handle = res_handle;
@@ -5708,11 +6440,7 @@ static void ipr_build_mode_select(struct
 	ioarcb->cmd_pkt.cdb[1] = parm;
 	ioarcb->cmd_pkt.cdb[4] = xfer_len;
 
-	ioadl->flags_and_data_len =
-		cpu_to_be32(IPR_IOADL_FLAGS_WRITE_LAST | xfer_len);
-	ioadl->address = cpu_to_be32(dma_addr);
-	ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-	ioarcb->write_data_transfer_length = cpu_to_be32(xfer_len);
+	ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_WRITE_LAST);
 }
 
 /**
@@ -5742,7 +6470,9 @@ static int ipr_ioafp_mode_select_page28(
 			      ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages),
 			      length);
 
-	ipr_cmd->job_step = ipr_setup_write_cache;
+	ipr_cmd->job_step = ipr_set_supported_devs;
+	ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next,
+				    struct ipr_resource_entry, queue);
 	ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
 
 	LEAVE;
@@ -5762,9 +6492,8 @@ static int ipr_ioafp_mode_select_page28(
  **/
 static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd,
 				 __be32 res_handle,
-				 u8 parm, u32 dma_addr, u8 xfer_len)
+				 u8 parm, dma_addr_t dma_addr, u8 xfer_len)
 {
-	struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
 	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
 
 	ioarcb->res_handle = res_handle;
@@ -5773,11 +6502,7 @@ static void ipr_build_mode_sense(struct
 	ioarcb->cmd_pkt.cdb[4] = xfer_len;
 	ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB;
 
-	ioadl->flags_and_data_len =
-		cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | xfer_len);
-	ioadl->address = cpu_to_be32(dma_addr);
-	ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-	ioarcb->read_data_transfer_length = cpu_to_be32(xfer_len);
+	ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_READ_LAST);
 }
 
 /**
@@ -5815,10 +6540,13 @@ static int ipr_reset_cmd_failed(struct i
  **/
 static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd)
 {
+	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
 	u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
 
 	if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) {
-		ipr_cmd->job_step = ipr_setup_write_cache;
+		ipr_cmd->job_step = ipr_set_supported_devs;
+		ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next,
+					    struct ipr_resource_entry, queue);
 		return IPR_RC_JOB_CONTINUE;
 	}
 
@@ -5958,24 +6686,36 @@ static int ipr_init_res_table(struct ipr
 {
 	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
 	struct ipr_resource_entry *res, *temp;
-	struct ipr_config_table_entry *cfgte;
-	int found, i;
+	struct ipr_config_table_entry_wrapper cfgtew;
+	int entries, found, flag, i;
 	LIST_HEAD(old_res);
 
 	ENTER;
-	if (ioa_cfg->cfg_table->hdr.flags & IPR_UCODE_DOWNLOAD_REQ)
+	if (ioa_cfg->sis64)
+		flag = ioa_cfg->u.cfg_table64->hdr64.flags;
+	else
+		flag = ioa_cfg->u.cfg_table->hdr.flags;
+
+	if (flag & IPR_UCODE_DOWNLOAD_REQ)
 		dev_err(&ioa_cfg->pdev->dev, "Microcode download required\n");
 
 	list_for_each_entry_safe(res, temp, &ioa_cfg->used_res_q, queue)
 		list_move_tail(&res->queue, &old_res);
 
-	for (i = 0; i < ioa_cfg->cfg_table->hdr.num_entries; i++) {
-		cfgte = &ioa_cfg->cfg_table->dev[i];
+	if (ioa_cfg->sis64)
+		entries = ioa_cfg->u.cfg_table64->hdr64.num_entries;
+	else
+		entries = ioa_cfg->u.cfg_table->hdr.num_entries;
+
+	for (i = 0; i < entries; i++) {
+		if (ioa_cfg->sis64)
+			cfgtew.u.cfgte64 = &ioa_cfg->u.cfg_table64->dev[i];
+		else
+			cfgtew.u.cfgte = &ioa_cfg->u.cfg_table->dev[i];
 		found = 0;
 
 		list_for_each_entry_safe(res, temp, &old_res, queue) {
-			if (!memcmp(&res->cfgte.res_addr,
-				    &cfgte->res_addr, sizeof(cfgte->res_addr))) {
+			if (ipr_is_same_device(res, &cfgtew)) {
 				list_move_tail(&res->queue, &ioa_cfg->used_res_q);
 				found = 1;
 				break;
@@ -5992,24 +6732,27 @@ static int ipr_init_res_table(struct ipr
 			res = list_entry(ioa_cfg->free_res_q.next,
 					 struct ipr_resource_entry, queue);
 			list_move_tail(&res->queue, &ioa_cfg->used_res_q);
-			ipr_init_res_entry(res);
+			ipr_init_res_entry(res, &cfgtew);
 			res->add_to_ml = 1;
 		}
 
 		if (found)
-			memcpy(&res->cfgte, cfgte, sizeof(struct ipr_config_table_entry));
+			ipr_update_res_entry(res, &cfgtew);
 	}
 
 	list_for_each_entry_safe(res, temp, &old_res, queue) {
 		if (res->sdev) {
 			res->del_from_ml = 1;
-			res->cfgte.res_handle = IPR_INVALID_RES_HANDLE;
+			res->res_handle = IPR_INVALID_RES_HANDLE;
 			list_move_tail(&res->queue, &ioa_cfg->used_res_q);
-		} else {
-			list_move_tail(&res->queue, &ioa_cfg->free_res_q);
 		}
 	}
 
+	list_for_each_entry_safe(res, temp, &old_res, queue) {
+		ipr_clear_res_target(res);
+		list_move_tail(&res->queue, &ioa_cfg->free_res_q);
+	}
+
 	if (ioa_cfg->dual_raid && ipr_dual_ioa_raid)
 		ipr_cmd->job_step = ipr_ioafp_mode_sense_page24;
 	else
@@ -6033,7 +6776,6 @@ static int ipr_ioafp_query_ioa_cfg(struc
 {
 	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
 	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
-	struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
 	struct ipr_inquiry_page3 *ucode_vpd = &ioa_cfg->vpd_cbs->page3_data;
 	struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap;
 
@@ -6047,16 +6789,11 @@ static int ipr_ioafp_query_ioa_cfg(struc
 	ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
 
 	ioarcb->cmd_pkt.cdb[0] = IPR_QUERY_IOA_CONFIG;
-	ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_config_table) >> 8) & 0xff;
-	ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_config_table) & 0xff;
-
-	ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-	ioarcb->read_data_transfer_length =
-		cpu_to_be32(sizeof(struct ipr_config_table));
+	ioarcb->cmd_pkt.cdb[7] = (ioa_cfg->cfg_table_size >> 8) & 0xff;
+	ioarcb->cmd_pkt.cdb[8] = ioa_cfg->cfg_table_size & 0xff;
 
-	ioadl->address = cpu_to_be32(ioa_cfg->cfg_table_dma);
-	ioadl->flags_and_data_len =
-		cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | sizeof(struct ipr_config_table));
+	ipr_init_ioadl(ipr_cmd, ioa_cfg->cfg_table_dma, ioa_cfg->cfg_table_size,
+		       IPR_IOADL_FLAGS_READ_LAST);
 
 	ipr_cmd->job_step = ipr_init_res_table;
 
@@ -6076,10 +6813,9 @@ static int ipr_ioafp_query_ioa_cfg(struc
  * 	none
  **/
 static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page,
-			      u32 dma_addr, u8 xfer_len)
+			      dma_addr_t dma_addr, u8 xfer_len)
 {
 	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
-	struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
 
 	ENTER;
 	ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB;
@@ -6090,12 +6826,7 @@ static void ipr_ioafp_inquiry(struct ipr
 	ioarcb->cmd_pkt.cdb[2] = page;
 	ioarcb->cmd_pkt.cdb[4] = xfer_len;
 
-	ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-	ioarcb->read_data_transfer_length = cpu_to_be32(xfer_len);
-
-	ioadl->address = cpu_to_be32(dma_addr);
-	ioadl->flags_and_data_len =
-		cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | xfer_len);
+	ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_READ_LAST);
 
 	ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
 	LEAVE;
@@ -6166,13 +6897,9 @@ static int ipr_ioafp_cap_inquiry(struct
 static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd)
 {
 	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
-	struct ipr_inquiry_page0 *page0 = &ioa_cfg->vpd_cbs->page0_data;
 
 	ENTER;
 
-	if (!ipr_inquiry_page_supported(page0, 1))
-		ioa_cfg->cache_state = CACHE_NONE;
-
 	ipr_cmd->job_step = ipr_ioafp_cap_inquiry;
 
 	ipr_ioafp_inquiry(ipr_cmd, 1, 3,
@@ -6240,7 +6967,7 @@ static int ipr_ioafp_std_inquiry(struct
 }
 
 /**
- * ipr_ioafp_indentify_hrrq - Send Identify Host RRQ.
+ * ipr_ioafp_identify_hrrq - Send Identify Host RRQ.
  * @ipr_cmd:	ipr command struct
  *
  * This function send an Identify Host Request Response Queue
@@ -6249,7 +6976,7 @@ static int ipr_ioafp_std_inquiry(struct
  * Return value:
  * 	IPR_RC_JOB_RETURN
  **/
-static int ipr_ioafp_indentify_hrrq(struct ipr_cmnd *ipr_cmd)
+static int ipr_ioafp_identify_hrrq(struct ipr_cmnd *ipr_cmd)
 {
 	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
 	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
@@ -6261,19 +6988,32 @@ static int ipr_ioafp_indentify_hrrq(stru
 	ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
 
 	ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
+	if (ioa_cfg->sis64)
+		ioarcb->cmd_pkt.cdb[1] = 0x1;
 	ioarcb->cmd_pkt.cdb[2] =
-		((u32) ioa_cfg->host_rrq_dma >> 24) & 0xff;
+		((u64) ioa_cfg->host_rrq_dma >> 24) & 0xff;
 	ioarcb->cmd_pkt.cdb[3] =
-		((u32) ioa_cfg->host_rrq_dma >> 16) & 0xff;
+		((u64) ioa_cfg->host_rrq_dma >> 16) & 0xff;
 	ioarcb->cmd_pkt.cdb[4] =
-		((u32) ioa_cfg->host_rrq_dma >> 8) & 0xff;
+		((u64) ioa_cfg->host_rrq_dma >> 8) & 0xff;
 	ioarcb->cmd_pkt.cdb[5] =
-		((u32) ioa_cfg->host_rrq_dma) & 0xff;
+		((u64) ioa_cfg->host_rrq_dma) & 0xff;
 	ioarcb->cmd_pkt.cdb[7] =
 		((sizeof(u32) * IPR_NUM_CMD_BLKS) >> 8) & 0xff;
 	ioarcb->cmd_pkt.cdb[8] =
 		(sizeof(u32) * IPR_NUM_CMD_BLKS) & 0xff;
 
+	if (ioa_cfg->sis64) {
+		ioarcb->cmd_pkt.cdb[10] =
+			((u64) ioa_cfg->host_rrq_dma >> 56) & 0xff;
+		ioarcb->cmd_pkt.cdb[11] =
+			((u64) ioa_cfg->host_rrq_dma >> 48) & 0xff;
+		ioarcb->cmd_pkt.cdb[12] =
+			((u64) ioa_cfg->host_rrq_dma >> 40) & 0xff;
+		ioarcb->cmd_pkt.cdb[13] =
+			((u64) ioa_cfg->host_rrq_dma >> 32) & 0xff;
+	}
+
 	ipr_cmd->job_step = ipr_ioafp_std_inquiry;
 
 	ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
@@ -6354,7 +7094,58 @@ static void ipr_init_ioa_mem(struct ipr_
 	ioa_cfg->toggle_bit = 1;
 
 	/* Zero out config table */
-	memset(ioa_cfg->cfg_table, 0, sizeof(struct ipr_config_table));
+	memset(ioa_cfg->u.cfg_table, 0, ioa_cfg->cfg_table_size);
+}
+
+/**
+ * ipr_reset_next_stage - Process IPL stage change based on feedback register.
+ * @ipr_cmd:	ipr command struct
+ *
+ * Return value:
+ * 	IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
+ **/
+static int ipr_reset_next_stage(struct ipr_cmnd *ipr_cmd)
+{
+	unsigned long stage, stage_time;
+	u32 feedback;
+	volatile u32 int_reg;
+	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+	u64 maskval = 0;
+
+	feedback = readl(ioa_cfg->regs.init_feedback_reg);
+	stage = feedback & IPR_IPL_INIT_STAGE_MASK;
+	stage_time = feedback & IPR_IPL_INIT_STAGE_TIME_MASK;
+
+	ipr_dbg("IPL stage = 0x%lx, IPL stage time = %ld\n", stage, stage_time);
+
+	/* sanity check the stage_time value */
+	if (stage_time < IPR_IPL_INIT_MIN_STAGE_TIME)
+		stage_time = IPR_IPL_INIT_MIN_STAGE_TIME;
+	else if (stage_time > IPR_LONG_OPERATIONAL_TIMEOUT)
+		stage_time = IPR_LONG_OPERATIONAL_TIMEOUT;
+
+	if (stage == IPR_IPL_INIT_STAGE_UNKNOWN) {
+		writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.set_interrupt_mask_reg);
+		int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+		stage_time = ioa_cfg->transop_timeout;
+		ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
+	} else if (stage == IPR_IPL_INIT_STAGE_TRANSOP) {
+		ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
+		maskval = IPR_PCII_IPL_STAGE_CHANGE;
+		maskval = (maskval << 32) | IPR_PCII_IOA_TRANS_TO_OPER;
+		writeq(maskval, ioa_cfg->regs.set_interrupt_mask_reg);
+		int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+		return IPR_RC_JOB_CONTINUE;
+	}
+
+	ipr_cmd->timer.data = (unsigned long) ipr_cmd;
+	ipr_cmd->timer.expires = jiffies + stage_time * HZ;
+	ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout;
+	ipr_cmd->done = ipr_reset_ioa_job;
+	add_timer(&ipr_cmd->timer);
+	list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
+
+	return IPR_RC_JOB_RETURN;
 }
 
 /**
@@ -6373,7 +7164,7 @@ static int ipr_reset_enable_ioa(struct i
 	volatile u32 int_reg;
 
 	ENTER;
-	ipr_cmd->job_step = ipr_ioafp_indentify_hrrq;
+	ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
 	ipr_init_ioa_mem(ioa_cfg);
 
 	ioa_cfg->allow_interrupts = 1;
@@ -6381,19 +7172,27 @@ static int ipr_reset_enable_ioa(struct i
 
 	if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) {
 		writel((IPR_PCII_ERROR_INTERRUPTS | IPR_PCII_HRRQ_UPDATED),
-		       ioa_cfg->regs.clr_interrupt_mask_reg);
+		       ioa_cfg->regs.clr_interrupt_mask_reg32);
 		int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
 		return IPR_RC_JOB_CONTINUE;
 	}
 
 	/* Enable destructive diagnostics on IOA */
-	writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg);
+	writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg32);
+
+	writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg32);
+	if (ioa_cfg->sis64)
+		writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_mask_reg);
 
-	writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg);
 	int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
 
 	dev_info(&ioa_cfg->pdev->dev, "Initializing IOA.\n");
 
+	if (ioa_cfg->sis64) {
+		ipr_cmd->job_step = ipr_reset_next_stage;
+		return IPR_RC_JOB_CONTINUE;
+	}
+
 	ipr_cmd->timer.data = (unsigned long) ipr_cmd;
 	ipr_cmd->timer.expires = jiffies + (ioa_cfg->transop_timeout * HZ);
 	ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout;
@@ -6463,7 +7262,7 @@ static void ipr_get_unit_check_buffer(st
 
 	mailbox = readl(ioa_cfg->ioa_mailbox);
 
-	if (!ipr_sdt_is_fmt2(mailbox)) {
+	if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(mailbox)) {
 		ipr_unit_check_no_data(ioa_cfg);
 		return;
 	}
@@ -6472,15 +7271,20 @@ static void ipr_get_unit_check_buffer(st
 	rc = ipr_get_ldump_data_section(ioa_cfg, mailbox, (__be32 *) &sdt,
 					(sizeof(struct ipr_uc_sdt)) / sizeof(__be32));
 
-	if (rc || (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE) ||
-	    !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY)) {
+	if (rc || !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY) ||
+	    ((be32_to_cpu(sdt.hdr.state) != IPR_FMT3_SDT_READY_TO_USE) &&
+	    (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) {
 		ipr_unit_check_no_data(ioa_cfg);
 		return;
 	}
 
 	/* Find length of the first sdt entry (UC buffer) */
-	length = (be32_to_cpu(sdt.entry[0].end_offset) -
-		  be32_to_cpu(sdt.entry[0].bar_str_offset)) & IPR_FMT2_MBX_ADDR_MASK;
+	if (be32_to_cpu(sdt.hdr.state) == IPR_FMT3_SDT_READY_TO_USE)
+		length = be32_to_cpu(sdt.entry[0].end_token);
+	else
+		length = (be32_to_cpu(sdt.entry[0].end_token) -
+			  be32_to_cpu(sdt.entry[0].start_token)) &
+			  IPR_FMT2_MBX_ADDR_MASK;
 
 	hostrcb = list_entry(ioa_cfg->hostrcb_free_q.next,
 			     struct ipr_hostrcb, queue);
@@ -6488,13 +7292,13 @@ static void ipr_get_unit_check_buffer(st
 	memset(&hostrcb->hcam, 0, sizeof(hostrcb->hcam));
 
 	rc = ipr_get_ldump_data_section(ioa_cfg,
-					be32_to_cpu(sdt.entry[0].bar_str_offset),
+					be32_to_cpu(sdt.entry[0].start_token),
 					(__be32 *)&hostrcb->hcam,
 					min(length, (int)sizeof(hostrcb->hcam)) / sizeof(__be32));
 
 	if (!rc) {
 		ipr_handle_log_data(ioa_cfg, hostrcb);
-		ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc);
+		ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc);
 		if (ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED &&
 		    ioa_cfg->sdt_state == GET_DUMP)
 			ioa_cfg->sdt_state = WAIT_FOR_DUMP;
@@ -6722,7 +7526,7 @@ static int ipr_reset_alert(struct ipr_cm
 
 	if ((rc == PCIBIOS_SUCCESSFUL) && (cmd_reg & PCI_COMMAND_MEMORY)) {
 		ipr_mask_and_clear_interrupts(ioa_cfg, ~0);
-		writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg);
+		writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg32);
 		ipr_cmd->job_step = ipr_reset_wait_to_start_bist;
 	} else {
 		ipr_cmd->job_step = ioa_cfg->reset;
@@ -6785,7 +7589,10 @@ static int ipr_reset_ucode_download(stru
 	ipr_cmd->ioarcb.cmd_pkt.cdb[7] = (sglist->buffer_len & 0x00ff00) >> 8;
 	ipr_cmd->ioarcb.cmd_pkt.cdb[8] = sglist->buffer_len & 0x0000ff;
 
-	ipr_build_ucode_ioadl(ipr_cmd, sglist);
+	if (ioa_cfg->sis64)
+		ipr_build_ucode_ioadl64(ipr_cmd, sglist);
+	else
+		ipr_build_ucode_ioadl(ipr_cmd, sglist);
 	ipr_cmd->job_step = ipr_reset_ucode_download_done;
 
 	ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout,
@@ -7154,8 +7961,8 @@ static void ipr_free_mem(struct ipr_ioa_
 	ipr_free_cmd_blks(ioa_cfg);
 	pci_free_consistent(ioa_cfg->pdev, sizeof(u32) * IPR_NUM_CMD_BLKS,
 			    ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma);
-	pci_free_consistent(ioa_cfg->pdev, sizeof(struct ipr_config_table),
-			    ioa_cfg->cfg_table,
+	pci_free_consistent(ioa_cfg->pdev, ioa_cfg->cfg_table_size,
+			    ioa_cfg->u.cfg_table,
 			    ioa_cfg->cfg_table_dma);
 
 	for (i = 0; i < IPR_NUM_HCAMS; i++) {
@@ -7209,7 +8016,7 @@ static int __devinit ipr_alloc_cmd_blks(
 	int i;
 
 	ioa_cfg->ipr_cmd_pool = pci_pool_create (IPR_NAME, ioa_cfg->pdev,
-						 sizeof(struct ipr_cmnd), 8, 0);
+						 sizeof(struct ipr_cmnd), 16, 0);
 
 	if (!ioa_cfg->ipr_cmd_pool)
 		return -ENOMEM;
@@ -7227,13 +8034,25 @@ static int __devinit ipr_alloc_cmd_blks(
 		ioa_cfg->ipr_cmnd_list_dma[i] = dma_addr;
 
 		ioarcb = &ipr_cmd->ioarcb;
-		ioarcb->ioarcb_host_pci_addr = cpu_to_be32(dma_addr);
+		ipr_cmd->dma_addr = dma_addr;
+		if (ioa_cfg->sis64)
+			ioarcb->a.ioarcb_host_pci_addr64 = cpu_to_be64(dma_addr);
+		else
+			ioarcb->a.ioarcb_host_pci_addr = cpu_to_be32(dma_addr);
+
 		ioarcb->host_response_handle = cpu_to_be32(i << 2);
-		ioarcb->write_ioadl_addr =
-			cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl));
-		ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
-		ioarcb->ioasa_host_pci_addr =
-			cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa));
+		if (ioa_cfg->sis64) {
+			ioarcb->u.sis64_addr_data.data_ioadl_addr =
+				cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64));
+			ioarcb->u.sis64_addr_data.ioasa_host_pci_addr =
+				cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, ioasa));
+		} else {
+			ioarcb->write_ioadl_addr =
+				cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl));
+			ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+			ioarcb->ioasa_host_pci_addr =
+				cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa));
+		}
 		ioarcb->ioasa_len = cpu_to_be16(sizeof(struct ipr_ioasa));
 		ipr_cmd->cmd_index = i;
 		ipr_cmd->ioa_cfg = ioa_cfg;
@@ -7260,13 +8079,24 @@ static int __devinit ipr_alloc_mem(struc
 
 	ENTER;
 	ioa_cfg->res_entries = kzalloc(sizeof(struct ipr_resource_entry) *
-				       IPR_MAX_PHYSICAL_DEVS, GFP_KERNEL);
+				       ioa_cfg->max_devs_supported, GFP_KERNEL);
 
 	if (!ioa_cfg->res_entries)
 		goto out;
 
-	for (i = 0; i < IPR_MAX_PHYSICAL_DEVS; i++)
+	if (ioa_cfg->sis64) {
+		ioa_cfg->target_ids = kzalloc(sizeof(unsigned long) *
+					      BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
+		ioa_cfg->array_ids = kzalloc(sizeof(unsigned long) *
+					     BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
+		ioa_cfg->vset_ids = kzalloc(sizeof(unsigned long) *
+					    BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
+	}
+
+	for (i = 0; i < ioa_cfg->max_devs_supported; i++) {
 		list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q);
+		ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg;
+	}
 
 	ioa_cfg->vpd_cbs = pci_alloc_consistent(ioa_cfg->pdev,
 						sizeof(struct ipr_misc_cbs),
@@ -7285,11 +8115,11 @@ static int __devinit ipr_alloc_mem(struc
 	if (!ioa_cfg->host_rrq)
 		goto out_ipr_free_cmd_blocks;
 
-	ioa_cfg->cfg_table = pci_alloc_consistent(ioa_cfg->pdev,
-						  sizeof(struct ipr_config_table),
-						  &ioa_cfg->cfg_table_dma);
+	ioa_cfg->u.cfg_table = pci_alloc_consistent(ioa_cfg->pdev,
+						    ioa_cfg->cfg_table_size,
+						    &ioa_cfg->cfg_table_dma);
 
-	if (!ioa_cfg->cfg_table)
+	if (!ioa_cfg->u.cfg_table)
 		goto out_free_host_rrq;
 
 	for (i = 0; i < IPR_NUM_HCAMS; i++) {
@@ -7323,8 +8153,9 @@ out_free_hostrcb_dma:
 				    ioa_cfg->hostrcb[i],
 				    ioa_cfg->hostrcb_dma[i]);
 	}
-	pci_free_consistent(pdev, sizeof(struct ipr_config_table),
-			    ioa_cfg->cfg_table, ioa_cfg->cfg_table_dma);
+	pci_free_consistent(pdev, ioa_cfg->cfg_table_size,
+			    ioa_cfg->u.cfg_table,
+			    ioa_cfg->cfg_table_dma);
 out_free_host_rrq:
 	pci_free_consistent(pdev, sizeof(u32) * IPR_NUM_CMD_BLKS,
 			    ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma);
@@ -7399,15 +8230,21 @@ static void __devinit ipr_init_ioa_cfg(s
 	init_waitqueue_head(&ioa_cfg->reset_wait_q);
 	init_waitqueue_head(&ioa_cfg->msi_wait_q);
 	ioa_cfg->sdt_state = INACTIVE;
-	if (ipr_enable_cache)
-		ioa_cfg->cache_state = CACHE_ENABLED;
-	else
-		ioa_cfg->cache_state = CACHE_DISABLED;
 
 	ipr_initialize_bus_attr(ioa_cfg);
+	ioa_cfg->max_devs_supported = ipr_max_devs;
 
-	host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS;
-	host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET;
+	if (ioa_cfg->sis64) {
+		host->max_id = IPR_MAX_SIS64_TARGETS_PER_BUS;
+		host->max_lun = IPR_MAX_SIS64_LUNS_PER_TARGET;
+		if (ipr_max_devs > IPR_MAX_SIS64_DEVS)
+			ioa_cfg->max_devs_supported = IPR_MAX_SIS64_DEVS;
+	} else {
+		host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS;
+		host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET;
+		if (ipr_max_devs > IPR_MAX_PHYSICAL_DEVS)
+			ioa_cfg->max_devs_supported = IPR_MAX_PHYSICAL_DEVS;
+	}
 	host->max_channel = IPR_MAX_BUS_TO_SCAN;
 	host->unique_id = host->host_no;
 	host->max_cmd_len = IPR_MAX_CDB_LEN;
@@ -7419,13 +8256,26 @@ static void __devinit ipr_init_ioa_cfg(s
 
 	t->set_interrupt_mask_reg = base + p->set_interrupt_mask_reg;
 	t->clr_interrupt_mask_reg = base + p->clr_interrupt_mask_reg;
+	t->clr_interrupt_mask_reg32 = base + p->clr_interrupt_mask_reg32;
 	t->sense_interrupt_mask_reg = base + p->sense_interrupt_mask_reg;
+	t->sense_interrupt_mask_reg32 = base + p->sense_interrupt_mask_reg32;
 	t->clr_interrupt_reg = base + p->clr_interrupt_reg;
+	t->clr_interrupt_reg32 = base + p->clr_interrupt_reg32;
 	t->sense_interrupt_reg = base + p->sense_interrupt_reg;
+	t->sense_interrupt_reg32 = base + p->sense_interrupt_reg32;
 	t->ioarrin_reg = base + p->ioarrin_reg;
 	t->sense_uproc_interrupt_reg = base + p->sense_uproc_interrupt_reg;
+	t->sense_uproc_interrupt_reg32 = base + p->sense_uproc_interrupt_reg32;
 	t->set_uproc_interrupt_reg = base + p->set_uproc_interrupt_reg;
+	t->set_uproc_interrupt_reg32 = base + p->set_uproc_interrupt_reg32;
 	t->clr_uproc_interrupt_reg = base + p->clr_uproc_interrupt_reg;
+	t->clr_uproc_interrupt_reg32 = base + p->clr_uproc_interrupt_reg32;
+
+	if (ioa_cfg->sis64) {
+		t->init_feedback_reg = base + p->init_feedback_reg;
+		t->dump_addr_reg = base + p->dump_addr_reg;
+		t->dump_data_reg = base + p->dump_data_reg;
+	}
 }
 
 /**
@@ -7497,7 +8347,7 @@ static int __devinit ipr_test_msi(struct
 	init_waitqueue_head(&ioa_cfg->msi_wait_q);
 	ioa_cfg->msi_received = 0;
 	ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
-	writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg);
+	writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg32);
 	int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
 	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
 
@@ -7508,7 +8358,7 @@ static int __devinit ipr_test_msi(struct
 	} else if (ipr_debug)
 		dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq);
 
-	writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg);
+	writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg32);
 	int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
 	wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ);
 	ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
@@ -7578,6 +8428,8 @@ static int __devinit ipr_probe_ioa(struc
 		goto out_scsi_host_put;
 	}
 
+	/* set SIS 32 or SIS 64 */
+	ioa_cfg->sis64 = ioa_cfg->ipr_chip->sis_type == IPR_SIS64 ? 1 : 0;
 	ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg;
 
 	if (ipr_transop_timeout)
@@ -7615,7 +8467,16 @@ static int __devinit ipr_probe_ioa(struc
 
 	pci_set_master(pdev);
 
-	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+	if (ioa_cfg->sis64) {
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+		if (rc < 0) {
+			dev_dbg(&pdev->dev, "Failed to set 64 bit PCI DMA mask\n");
+			rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+		}
+
+	} else
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+
 	if (rc < 0) {
 		dev_err(&pdev->dev, "Failed to set PCI DMA mask\n");
 		goto cleanup_nomem;
@@ -7657,6 +8518,15 @@ static int __devinit ipr_probe_ioa(struc
 	if ((rc = ipr_set_pcix_cmd_reg(ioa_cfg)))
 		goto cleanup_nomem;
 
+	if (ioa_cfg->sis64)
+		ioa_cfg->cfg_table_size = (sizeof(struct ipr_config_table_hdr64)
+				+ ((sizeof(struct ipr_config_table_entry64)
+				* ioa_cfg->max_devs_supported)));
+	else
+		ioa_cfg->cfg_table_size = (sizeof(struct ipr_config_table_hdr)
+				+ ((sizeof(struct ipr_config_table_entry)
+				* ioa_cfg->max_devs_supported)));
+
 	rc = ipr_alloc_mem(ioa_cfg);
 	if (rc < 0) {
 		dev_err(&pdev->dev,
@@ -7668,9 +8538,9 @@ static int __devinit ipr_probe_ioa(struc
 	 * If HRRQ updated interrupt is not masked, or reset alert is set,
 	 * the card is in an unknown state and needs a hard reset
 	 */
-	mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
-	interrupts = readl(ioa_cfg->regs.sense_interrupt_reg);
-	uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg);
+	mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg32);
+	interrupts = readl(ioa_cfg->regs.sense_interrupt_reg32);
+	uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg32);
 	if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT))
 		ioa_cfg->needs_hard_reset = 1;
 	if (interrupts & IPR_PCII_ERROR_INTERRUPTS)
@@ -7958,9 +8828,6 @@ static struct pci_device_id ipr_pci_tabl
 	      PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574E, 0, 0,
 	      IPR_USE_LONG_TRANSOP_TIMEOUT },
 	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
-	      PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0,
-	      IPR_USE_LONG_TRANSOP_TIMEOUT },
-	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
 	      PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B3, 0, 0, 0 },
 	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
 	      PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0,
@@ -7975,9 +8842,22 @@ static struct pci_device_id ipr_pci_tabl
 	{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP,
 		PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0,
 		IPR_USE_LONG_TRANSOP_TIMEOUT },
-	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SCAMP_E,
-		PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0,
-		IPR_USE_LONG_TRANSOP_TIMEOUT },
+	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
+		PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B5, 0, 0, 0 },
+	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
+		PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0, 0 },
+	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
+		PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B2, 0, 0, 0 },
+	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
+		PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B4, 0, 0, 0 },
+	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
+		PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B1, 0, 0, 0 },
+	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
+		PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57C6, 0, 0, 0 },
+	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
+		PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0, 0 },
+	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
+		PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57CE, 0, 0, 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, ipr_pci_table);
@@ -7997,6 +8877,61 @@ static struct pci_driver ipr_driver = {
 };
 
 /**
+ * ipr_halt_done - Shutdown prepare completion
+ *
+ * Return value:
+ * 	none
+ **/
+static void ipr_halt_done(struct ipr_cmnd *ipr_cmd)
+{
+	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+
+	list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
+}
+
+/**
+ * ipr_halt - Issue shutdown prepare to all adapters
+ *
+ * Return value:
+ * 	NOTIFY_OK on success / NOTIFY_DONE on failure
+ **/
+static int ipr_halt(struct notifier_block *nb, ulong event, void *buf)
+{
+	struct ipr_cmnd *ipr_cmd;
+	struct ipr_ioa_cfg *ioa_cfg;
+	unsigned long flags = 0;
+
+	if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
+		return NOTIFY_DONE;
+
+	spin_lock(&ipr_driver_lock);
+
+	list_for_each_entry(ioa_cfg, &ipr_ioa_head, queue) {
+		spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
+		if (!ioa_cfg->allow_cmds) {
+			spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
+			continue;
+		}
+
+		ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
+		ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
+		ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
+		ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN;
+		ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL;
+
+		ipr_do_req(ipr_cmd, ipr_halt_done, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT);
+		spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
+	}
+	spin_unlock(&ipr_driver_lock);
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block ipr_notifier = {
+	ipr_halt, NULL, 0
+};
+
+/**
  * ipr_init - Module entry point
  *
  * Return value:
@@ -8007,6 +8942,7 @@ static int __init ipr_init(void)
 	ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n",
 		 IPR_DRIVER_VERSION, IPR_DRIVER_DATE);
 
+	register_reboot_notifier(&ipr_notifier);
 	return pci_register_driver(&ipr_driver);
 }
 
@@ -8020,6 +8956,7 @@ static int __init ipr_init(void)
  **/
 static void __exit ipr_exit(void)
 {
+	unregister_reboot_notifier(&ipr_notifier);
 	pci_unregister_driver(&ipr_driver);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/ipr.h linux-libre-2.6.34-gnu1/drivers/scsi/ipr.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/ipr.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/ipr.h	2010-05-16 17:17:36.000000000 -0400
@@ -37,8 +37,8 @@
 /*
  * Literals
  */
-#define IPR_DRIVER_VERSION "2.4.3"
-#define IPR_DRIVER_DATE "(June 10, 2009)"
+#define IPR_DRIVER_VERSION "2.5.0"
+#define IPR_DRIVER_DATE "(February 11, 2010)"
 
 /*
  * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -55,7 +55,9 @@
 #define IPR_NUM_BASE_CMD_BLKS				100
 
 #define PCI_DEVICE_ID_IBM_OBSIDIAN_E	0x0339
-#define PCI_DEVICE_ID_IBM_SCAMP_E		0x034A
+
+#define PCI_DEVICE_ID_IBM_CROC_FPGA_E2          0x033D
+#define PCI_DEVICE_ID_IBM_CROC_ASIC_E2          0x034A
 
 #define IPR_SUBS_DEV_ID_2780	0x0264
 #define IPR_SUBS_DEV_ID_5702	0x0266
@@ -70,15 +72,24 @@
 #define IPR_SUBS_DEV_ID_572A	0x02C1
 #define IPR_SUBS_DEV_ID_572B	0x02C2
 #define IPR_SUBS_DEV_ID_572F	0x02C3
-#define IPR_SUBS_DEV_ID_574D	0x030B
 #define IPR_SUBS_DEV_ID_574E	0x030A
 #define IPR_SUBS_DEV_ID_575B	0x030D
 #define IPR_SUBS_DEV_ID_575C	0x0338
-#define IPR_SUBS_DEV_ID_575D	0x033E
 #define IPR_SUBS_DEV_ID_57B3	0x033A
 #define IPR_SUBS_DEV_ID_57B7	0x0360
 #define IPR_SUBS_DEV_ID_57B8	0x02C2
 
+#define IPR_SUBS_DEV_ID_57B4    0x033B
+#define IPR_SUBS_DEV_ID_57B2    0x035F
+#define IPR_SUBS_DEV_ID_57C6    0x0357
+
+#define IPR_SUBS_DEV_ID_57B5    0x033C
+#define IPR_SUBS_DEV_ID_57CE    0x035E
+#define IPR_SUBS_DEV_ID_57B1    0x0355
+
+#define IPR_SUBS_DEV_ID_574D    0x0356
+#define IPR_SUBS_DEV_ID_575D    0x035D
+
 #define IPR_NAME				"ipr"
 
 /*
@@ -118,6 +129,10 @@
 #define IPR_NUM_LOG_HCAMS				2
 #define IPR_NUM_CFG_CHG_HCAMS				2
 #define IPR_NUM_HCAMS	(IPR_NUM_LOG_HCAMS + IPR_NUM_CFG_CHG_HCAMS)
+
+#define IPR_MAX_SIS64_TARGETS_PER_BUS			1024
+#define IPR_MAX_SIS64_LUNS_PER_TARGET			0xffffffff
+
 #define IPR_MAX_NUM_TARGETS_PER_BUS			256
 #define IPR_MAX_NUM_LUNS_PER_TARGET			256
 #define IPR_MAX_NUM_VSET_LUNS_PER_TARGET	8
@@ -132,13 +147,15 @@
 
 /* We need resources for HCAMS, IOA reset, IOA bringdown, and ERP */
 #define IPR_NUM_INTERNAL_CMD_BLKS	(IPR_NUM_HCAMS + \
-                                     ((IPR_NUM_RESET_RELOAD_RETRIES + 1) * 2) + 3)
+                                     ((IPR_NUM_RESET_RELOAD_RETRIES + 1) * 2) + 4)
 
 #define IPR_MAX_COMMANDS		IPR_NUM_BASE_CMD_BLKS
 #define IPR_NUM_CMD_BLKS		(IPR_NUM_BASE_CMD_BLKS + \
 						IPR_NUM_INTERNAL_CMD_BLKS)
 
 #define IPR_MAX_PHYSICAL_DEVS				192
+#define IPR_DEFAULT_SIS64_DEVS				1024
+#define IPR_MAX_SIS64_DEVS				4096
 
 #define IPR_MAX_SGLIST					64
 #define IPR_IOA_MAX_SECTORS				32767
@@ -173,6 +190,7 @@
 #define	IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE	0x01
 #define	IPR_HCAM_CDB_OP_CODE_LOG_DATA		0x02
 #define IPR_SET_SUPPORTED_DEVICES			0xFB
+#define IPR_SET_ALL_SUPPORTED_DEVICES			0x80
 #define IPR_IOA_SHUTDOWN				0xF7
 #define	IPR_WR_BUF_DOWNLOAD_AND_SAVE			0x05
 
@@ -221,9 +239,17 @@
 #define IPR_SDT_FMT2_BAR5_SEL				0x5
 #define IPR_SDT_FMT2_EXP_ROM_SEL			0x8
 #define IPR_FMT2_SDT_READY_TO_USE			0xC4D4E3F2
+#define IPR_FMT3_SDT_READY_TO_USE			0xC4D4E3F3
 #define IPR_DOORBELL					0x82800000
 #define IPR_RUNTIME_RESET				0x40000000
 
+#define IPR_IPL_INIT_MIN_STAGE_TIME			5
+#define IPR_IPL_INIT_STAGE_UNKNOWN			0x0
+#define IPR_IPL_INIT_STAGE_TRANSOP			0xB0000000
+#define IPR_IPL_INIT_STAGE_MASK				0xff000000
+#define IPR_IPL_INIT_STAGE_TIME_MASK			0x0000ffff
+#define IPR_PCII_IPL_STAGE_CHANGE			(0x80000000 >> 0)
+
 #define IPR_PCII_IOA_TRANS_TO_OPER			(0x80000000 >> 0)
 #define IPR_PCII_IOARCB_XFER_FAILED			(0x80000000 >> 3)
 #define IPR_PCII_IOA_UNIT_CHECKED			(0x80000000 >> 4)
@@ -318,27 +344,27 @@ struct ipr_std_inq_data {
 	u8 serial_num[IPR_SERIAL_NUM_LEN];
 }__attribute__ ((packed));
 
+#define IPR_RES_TYPE_AF_DASD		0x00
+#define IPR_RES_TYPE_GENERIC_SCSI	0x01
+#define IPR_RES_TYPE_VOLUME_SET		0x02
+#define IPR_RES_TYPE_REMOTE_AF_DASD	0x03
+#define IPR_RES_TYPE_GENERIC_ATA	0x04
+#define IPR_RES_TYPE_ARRAY		0x05
+#define IPR_RES_TYPE_IOAFP		0xff
+
 struct ipr_config_table_entry {
 	u8 proto;
 #define IPR_PROTO_SATA			0x02
 #define IPR_PROTO_SATA_ATAPI		0x03
 #define IPR_PROTO_SAS_STP		0x06
-#define IPR_PROTO_SAS_STP_ATAPI	0x07
+#define IPR_PROTO_SAS_STP_ATAPI		0x07
 	u8 array_id;
 	u8 flags;
-#define IPR_IS_IOA_RESOURCE	0x80
-#define IPR_IS_ARRAY_MEMBER 0x20
-#define IPR_IS_HOT_SPARE	0x10
-
+#define IPR_IS_IOA_RESOURCE		0x80
 	u8 rsvd_subtype;
-#define IPR_RES_SUBTYPE(res) (((res)->cfgte.rsvd_subtype) & 0x0f)
-#define IPR_SUBTYPE_AF_DASD			0
-#define IPR_SUBTYPE_GENERIC_SCSI	1
-#define IPR_SUBTYPE_VOLUME_SET		2
-#define IPR_SUBTYPE_GENERIC_ATA	4
 
-#define IPR_QUEUEING_MODEL(res)	((((res)->cfgte.flags) & 0x70) >> 4)
-#define IPR_QUEUE_FROZEN_MODEL	0
+#define IPR_QUEUEING_MODEL(res)	((((res)->flags) & 0x70) >> 4)
+#define IPR_QUEUE_FROZEN_MODEL		0
 #define IPR_QUEUE_NACA_MODEL		1
 
 	struct ipr_res_addr res_addr;
@@ -347,6 +373,28 @@ struct ipr_config_table_entry {
 	struct ipr_std_inq_data std_inq_data;
 }__attribute__ ((packed, aligned (4)));
 
+struct ipr_config_table_entry64 {
+	u8 res_type;
+	u8 proto;
+	u8 vset_num;
+	u8 array_id;
+	__be16 flags;
+	__be16 res_flags;
+#define IPR_QUEUEING_MODEL64(res) ((((res)->res_flags) & 0x7000) >> 12)
+	__be32 res_handle;
+	u8 dev_id_type;
+	u8 reserved[3];
+	__be64 dev_id;
+	__be64 lun;
+	__be64 lun_wwn[2];
+#define IPR_MAX_RES_PATH_LENGTH		24
+	__be64 res_path;
+	struct ipr_std_inq_data std_inq_data;
+	u8 reserved2[4];
+	__be64 reserved3[2]; // description text
+	u8 reserved4[8];
+}__attribute__ ((packed, aligned (8)));
+
 struct ipr_config_table_hdr {
 	u8 num_entries;
 	u8 flags;
@@ -354,13 +402,35 @@ struct ipr_config_table_hdr {
 	__be16 reserved;
 }__attribute__((packed, aligned (4)));
 
+struct ipr_config_table_hdr64 {
+	__be16 num_entries;
+	__be16 reserved;
+	u8 flags;
+	u8 reserved2[11];
+}__attribute__((packed, aligned (4)));
+
 struct ipr_config_table {
 	struct ipr_config_table_hdr hdr;
-	struct ipr_config_table_entry dev[IPR_MAX_PHYSICAL_DEVS];
+	struct ipr_config_table_entry dev[0];
 }__attribute__((packed, aligned (4)));
 
+struct ipr_config_table64 {
+	struct ipr_config_table_hdr64 hdr64;
+	struct ipr_config_table_entry64 dev[0];
+}__attribute__((packed, aligned (8)));
+
+struct ipr_config_table_entry_wrapper {
+	union {
+		struct ipr_config_table_entry *cfgte;
+		struct ipr_config_table_entry64 *cfgte64;
+	} u;
+};
+
 struct ipr_hostrcb_cfg_ch_not {
-	struct ipr_config_table_entry cfgte;
+	union {
+		struct ipr_config_table_entry cfgte;
+		struct ipr_config_table_entry64 cfgte64;
+	} u;
 	u8 reserved[936];
 }__attribute__((packed, aligned (4)));
 
@@ -381,7 +451,7 @@ struct ipr_cmd_pkt {
 #define IPR_RQTYPE_HCAM			0x02
 #define IPR_RQTYPE_ATA_PASSTHRU	0x04
 
-	u8 luntar_luntrn;
+	u8 reserved2;
 
 	u8 flags_hi;
 #define IPR_FLAGS_HI_WRITE_NOT_READ		0x80
@@ -403,7 +473,7 @@ struct ipr_cmd_pkt {
 	__be16 timeout;
 }__attribute__ ((packed, aligned(4)));
 
-struct ipr_ioarcb_ata_regs {
+struct ipr_ioarcb_ata_regs {	/* 22 bytes */
 	u8 flags;
 #define IPR_ATA_FLAG_PACKET_CMD			0x80
 #define IPR_ATA_FLAG_XFER_TYPE_DMA			0x40
@@ -442,28 +512,49 @@ struct ipr_ioadl_desc {
 	__be32 address;
 }__attribute__((packed, aligned (8)));
 
+struct ipr_ioadl64_desc {
+	__be32 flags;
+	__be32 data_len;
+	__be64 address;
+}__attribute__((packed, aligned (16)));
+
+struct ipr_ata64_ioadl {
+	struct ipr_ioarcb_ata_regs regs;
+	u16 reserved[5];
+	struct ipr_ioadl64_desc ioadl64[IPR_NUM_IOADL_ENTRIES];
+}__attribute__((packed, aligned (16)));
+
 struct ipr_ioarcb_add_data {
 	union {
 		struct ipr_ioarcb_ata_regs regs;
 		struct ipr_ioadl_desc ioadl[5];
 		__be32 add_cmd_parms[10];
-	}u;
-}__attribute__ ((packed, aligned(4)));
+	} u;
+}__attribute__ ((packed, aligned (4)));
+
+struct ipr_ioarcb_sis64_add_addr_ecb {
+	__be64 ioasa_host_pci_addr;
+	__be64 data_ioadl_addr;
+	__be64 reserved;
+	__be32 ext_control_buf[4];
+}__attribute__((packed, aligned (8)));
 
 /* IOA Request Control Block    128 bytes  */
 struct ipr_ioarcb {
-	__be32 ioarcb_host_pci_addr;
-	__be32 reserved;
+	union {
+		__be32 ioarcb_host_pci_addr;
+		__be64 ioarcb_host_pci_addr64;
+	} a;
 	__be32 res_handle;
 	__be32 host_response_handle;
 	__be32 reserved1;
 	__be32 reserved2;
 	__be32 reserved3;
 
-	__be32 write_data_transfer_length;
+	__be32 data_transfer_length;
 	__be32 read_data_transfer_length;
 	__be32 write_ioadl_addr;
-	__be32 write_ioadl_len;
+	__be32 ioadl_len;
 	__be32 read_ioadl_addr;
 	__be32 read_ioadl_len;
 
@@ -473,8 +564,14 @@ struct ipr_ioarcb {
 
 	struct ipr_cmd_pkt cmd_pkt;
 
-	__be32 add_cmd_parms_len;
-	struct ipr_ioarcb_add_data add_data;
+	__be16 add_cmd_parms_offset;
+	__be16 add_cmd_parms_len;
+
+	union {
+		struct ipr_ioarcb_add_data add_data;
+		struct ipr_ioarcb_sis64_add_addr_ecb sis64_addr_data;
+	} u;
+
 }__attribute__((packed, aligned (4)));
 
 struct ipr_ioasa_vset {
@@ -676,12 +773,29 @@ struct ipr_hostrcb_device_data_entry_enh
 	struct ipr_ext_vpd cfc_last_with_dev_vpd;
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb64_device_data_entry_enhanced {
+	struct ipr_ext_vpd vpd;
+	u8 ccin[4];
+	u8 res_path[8];
+	struct ipr_ext_vpd new_vpd;
+	u8 new_ccin[4];
+	struct ipr_ext_vpd ioa_last_with_dev_vpd;
+	struct ipr_ext_vpd cfc_last_with_dev_vpd;
+}__attribute__((packed, aligned (4)));
+
 struct ipr_hostrcb_array_data_entry {
 	struct ipr_vpd vpd;
 	struct ipr_res_addr expected_dev_res_addr;
 	struct ipr_res_addr dev_res_addr;
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb64_array_data_entry {
+	struct ipr_ext_vpd vpd;
+	u8 ccin[4];
+	u8 expected_res_path[8];
+	u8 res_path[8];
+}__attribute__((packed, aligned (4)));
+
 struct ipr_hostrcb_array_data_entry_enhanced {
 	struct ipr_ext_vpd vpd;
 	u8 ccin[4];
@@ -733,6 +847,14 @@ struct ipr_hostrcb_type_13_error {
 	struct ipr_hostrcb_device_data_entry_enhanced dev[3];
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb_type_23_error {
+	struct ipr_ext_vpd ioa_vpd;
+	struct ipr_ext_vpd cfc_vpd;
+	__be32 errors_detected;
+	__be32 errors_logged;
+	struct ipr_hostrcb64_device_data_entry_enhanced dev[3];
+}__attribute__((packed, aligned (4)));
+
 struct ipr_hostrcb_type_04_error {
 	struct ipr_vpd ioa_vpd;
 	struct ipr_vpd cfc_vpd;
@@ -760,6 +882,22 @@ struct ipr_hostrcb_type_14_error {
 	struct ipr_hostrcb_array_data_entry_enhanced array_member[18];
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb_type_24_error {
+	struct ipr_ext_vpd ioa_vpd;
+	struct ipr_ext_vpd cfc_vpd;
+	u8 reserved[2];
+	u8 exposed_mode_adn;
+#define IPR_INVALID_ARRAY_DEV_NUM		0xff
+	u8 array_id;
+	u8 last_res_path[8];
+	u8 protection_level[8];
+	struct ipr_ext_vpd array_vpd;
+	u8 description[16];
+	u8 reserved2[3];
+	u8 num_entries;
+	struct ipr_hostrcb64_array_data_entry array_member[32];
+}__attribute__((packed, aligned (4)));
+
 struct ipr_hostrcb_type_07_error {
 	u8 failure_reason[64];
 	struct ipr_vpd vpd;
@@ -797,6 +935,22 @@ struct ipr_hostrcb_config_element {
 	__be32 wwid[2];
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb64_config_element {
+	__be16 length;
+	u8 descriptor_id;
+#define IPR_DESCRIPTOR_MASK		0xC0
+#define IPR_DESCRIPTOR_SIS64		0x00
+
+	u8 reserved;
+	u8 type_status;
+
+	u8 reserved2[2];
+	u8 link_rate;
+
+	u8 res_path[8];
+	__be32 wwid[2];
+}__attribute__((packed, aligned (8)));
+
 struct ipr_hostrcb_fabric_desc {
 	__be16 length;
 	u8 ioa_port;
@@ -818,6 +972,20 @@ struct ipr_hostrcb_fabric_desc {
 	struct ipr_hostrcb_config_element elem[1];
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb64_fabric_desc {
+	__be16 length;
+	u8 descriptor_id;
+
+	u8 reserved;
+	u8 path_state;
+
+	u8 reserved2[2];
+	u8 res_path[8];
+	u8 reserved3[6];
+	__be16 num_entries;
+	struct ipr_hostrcb64_config_element elem[1];
+}__attribute__((packed, aligned (8)));
+
 #define for_each_fabric_cfg(fabric, cfg) \
 		for (cfg = (fabric)->elem; \
 			cfg < ((fabric)->elem + be16_to_cpu((fabric)->num_entries)); \
@@ -830,10 +998,17 @@ struct ipr_hostrcb_type_20_error {
 	struct ipr_hostrcb_fabric_desc desc[1];
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb_type_30_error {
+	u8 failure_reason[64];
+	u8 reserved[3];
+	u8 num_entries;
+	struct ipr_hostrcb64_fabric_desc desc[1];
+}__attribute__((packed, aligned (4)));
+
 struct ipr_hostrcb_error {
-	__be32 failing_dev_ioasc;
-	struct ipr_res_addr failing_dev_res_addr;
-	__be32 failing_dev_res_handle;
+	__be32 fd_ioasc;
+	struct ipr_res_addr fd_res_addr;
+	__be32 fd_res_handle;
 	__be32 prc;
 	union {
 		struct ipr_hostrcb_type_ff_error type_ff_error;
@@ -850,6 +1025,26 @@ struct ipr_hostrcb_error {
 	} u;
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb64_error {
+	__be32 fd_ioasc;
+	__be32 ioa_fw_level;
+	__be32 fd_res_handle;
+	__be32 prc;
+	__be64 fd_dev_id;
+	__be64 fd_lun;
+	u8 fd_res_path[8];
+	__be64 time_stamp;
+	u8 reserved[2];
+	union {
+		struct ipr_hostrcb_type_ff_error type_ff_error;
+		struct ipr_hostrcb_type_12_error type_12_error;
+		struct ipr_hostrcb_type_17_error type_17_error;
+		struct ipr_hostrcb_type_23_error type_23_error;
+		struct ipr_hostrcb_type_24_error type_24_error;
+		struct ipr_hostrcb_type_30_error type_30_error;
+	} u;
+}__attribute__((packed, aligned (8)));
+
 struct ipr_hostrcb_raw {
 	__be32 data[sizeof(struct ipr_hostrcb_error)/sizeof(__be32)];
 }__attribute__((packed, aligned (4)));
@@ -887,7 +1082,11 @@ struct ipr_hcam {
 #define IPR_HOST_RCB_OVERLAY_ID_16				0x16
 #define IPR_HOST_RCB_OVERLAY_ID_17				0x17
 #define IPR_HOST_RCB_OVERLAY_ID_20				0x20
-#define IPR_HOST_RCB_OVERLAY_ID_DEFAULT			0xFF
+#define IPR_HOST_RCB_OVERLAY_ID_23				0x23
+#define IPR_HOST_RCB_OVERLAY_ID_24				0x24
+#define IPR_HOST_RCB_OVERLAY_ID_26				0x26
+#define IPR_HOST_RCB_OVERLAY_ID_30				0x30
+#define IPR_HOST_RCB_OVERLAY_ID_DEFAULT				0xFF
 
 	u8 reserved1[3];
 	__be32 ilid;
@@ -897,6 +1096,7 @@ struct ipr_hcam {
 
 	union {
 		struct ipr_hostrcb_error error;
+		struct ipr_hostrcb64_error error64;
 		struct ipr_hostrcb_cfg_ch_not ccn;
 		struct ipr_hostrcb_raw raw;
 	} u;
@@ -907,14 +1107,14 @@ struct ipr_hostrcb {
 	dma_addr_t hostrcb_dma;
 	struct list_head queue;
 	struct ipr_ioa_cfg *ioa_cfg;
+	char rp_buffer[IPR_MAX_RES_PATH_LENGTH];
 };
 
 /* IPR smart dump table structures */
 struct ipr_sdt_entry {
-	__be32 bar_str_offset;
-	__be32 end_offset;
-	u8 entry_byte;
-	u8 reserved[3];
+	__be32 start_token;
+	__be32 end_token;
+	u8 reserved[4];
 
 	u8 flags;
 #define IPR_SDT_ENDIAN		0x80
@@ -960,28 +1160,48 @@ struct ipr_sata_port {
 };
 
 struct ipr_resource_entry {
-	struct ipr_config_table_entry cfgte;
 	u8 needs_sync_complete:1;
 	u8 in_erp:1;
 	u8 add_to_ml:1;
 	u8 del_from_ml:1;
 	u8 resetting_device:1;
 
+	u32 bus;		/* AKA channel */
+	u32 target;		/* AKA id */
+	u32 lun;
+#define IPR_ARRAY_VIRTUAL_BUS			0x1
+#define IPR_VSET_VIRTUAL_BUS			0x2
+#define IPR_IOAFP_VIRTUAL_BUS			0x3
+
+#define IPR_GET_RES_PHYS_LOC(res) \
+	(((res)->bus << 24) | ((res)->target << 8) | (res)->lun)
+
+	u8 ata_class;
+
+	u8 flags;
+	__be16 res_flags;
+
+	__be32 type;
+
+	u8 qmodel;
+	struct ipr_std_inq_data std_inq_data;
+
+	__be32 res_handle;
+	__be64 dev_id;
+	struct scsi_lun dev_lun;
+	u8 res_path[8];
+
+	struct ipr_ioa_cfg *ioa_cfg;
 	struct scsi_device *sdev;
 	struct ipr_sata_port *sata_port;
 	struct list_head queue;
-};
+}; /* struct ipr_resource_entry */
 
 struct ipr_resource_hdr {
 	u16 num_entries;
 	u16 reserved;
 };
 
-struct ipr_resource_table {
-	struct ipr_resource_hdr hdr;
-	struct ipr_resource_entry dev[IPR_MAX_PHYSICAL_DEVS];
-};
-
 struct ipr_misc_cbs {
 	struct ipr_ioa_vpd ioa_vpd;
 	struct ipr_inquiry_page0 page0_data;
@@ -994,27 +1214,51 @@ struct ipr_misc_cbs {
 struct ipr_interrupt_offsets {
 	unsigned long set_interrupt_mask_reg;
 	unsigned long clr_interrupt_mask_reg;
+	unsigned long clr_interrupt_mask_reg32;
 	unsigned long sense_interrupt_mask_reg;
+	unsigned long sense_interrupt_mask_reg32;
 	unsigned long clr_interrupt_reg;
+	unsigned long clr_interrupt_reg32;
 
 	unsigned long sense_interrupt_reg;
+	unsigned long sense_interrupt_reg32;
 	unsigned long ioarrin_reg;
 	unsigned long sense_uproc_interrupt_reg;
+	unsigned long sense_uproc_interrupt_reg32;
 	unsigned long set_uproc_interrupt_reg;
+	unsigned long set_uproc_interrupt_reg32;
 	unsigned long clr_uproc_interrupt_reg;
+	unsigned long clr_uproc_interrupt_reg32;
+
+	unsigned long init_feedback_reg;
+
+	unsigned long dump_addr_reg;
+	unsigned long dump_data_reg;
 };
 
 struct ipr_interrupts {
 	void __iomem *set_interrupt_mask_reg;
 	void __iomem *clr_interrupt_mask_reg;
+	void __iomem *clr_interrupt_mask_reg32;
 	void __iomem *sense_interrupt_mask_reg;
+	void __iomem *sense_interrupt_mask_reg32;
 	void __iomem *clr_interrupt_reg;
+	void __iomem *clr_interrupt_reg32;
 
 	void __iomem *sense_interrupt_reg;
+	void __iomem *sense_interrupt_reg32;
 	void __iomem *ioarrin_reg;
 	void __iomem *sense_uproc_interrupt_reg;
+	void __iomem *sense_uproc_interrupt_reg32;
 	void __iomem *set_uproc_interrupt_reg;
+	void __iomem *set_uproc_interrupt_reg32;
 	void __iomem *clr_uproc_interrupt_reg;
+	void __iomem *clr_uproc_interrupt_reg32;
+
+	void __iomem *init_feedback_reg;
+
+	void __iomem *dump_addr_reg;
+	void __iomem *dump_data_reg;
 };
 
 struct ipr_chip_cfg_t {
@@ -1029,6 +1273,9 @@ struct ipr_chip_t {
 	u16 intr_type;
 #define IPR_USE_LSI			0x00
 #define IPR_USE_MSI			0x01
+	u16 sis_type;
+#define IPR_SIS32			0x00
+#define IPR_SIS64			0x01
 	const struct ipr_chip_cfg_t *cfg;
 };
 
@@ -1073,13 +1320,6 @@ enum ipr_sdt_state {
 	DUMP_OBTAINED
 };
 
-enum ipr_cache_state {
-	CACHE_NONE,
-	CACHE_DISABLED,
-	CACHE_ENABLED,
-	CACHE_INVALID
-};
-
 /* Per-controller data */
 struct ipr_ioa_cfg {
 	char eye_catcher[8];
@@ -1099,10 +1339,17 @@ struct ipr_ioa_cfg {
 	u8 dual_raid:1;
 	u8 needs_warm_reset:1;
 	u8 msi_received:1;
+	u8 sis64:1;
 
 	u8 revid;
 
-	enum ipr_cache_state cache_state;
+	/*
+	 * Bitmaps for SIS64 generated target values
+	 */
+	unsigned long *target_ids;
+	unsigned long *array_ids;
+	unsigned long *vset_ids;
+
 	u16 type; /* CCIN of the card */
 
 	u8 log_level;
@@ -1133,8 +1380,13 @@ struct ipr_ioa_cfg {
 
 	char cfg_table_start[8];
 #define IPR_CFG_TBL_START		"cfg"
-	struct ipr_config_table *cfg_table;
+	union {
+		struct ipr_config_table *cfg_table;
+		struct ipr_config_table64 *cfg_table64;
+	} u;
 	dma_addr_t cfg_table_dma;
+	u32 cfg_table_size;
+	u32 max_devs_supported;
 
 	char resource_table_label[8];
 #define IPR_RES_TABLE_LABEL		"res_tbl"
@@ -1202,13 +1454,17 @@ struct ipr_ioa_cfg {
 	char ipr_cmd_label[8];
 #define IPR_CMD_LABEL		"ipr_cmd"
 	struct ipr_cmnd *ipr_cmnd_list[IPR_NUM_CMD_BLKS];
-	u32 ipr_cmnd_list_dma[IPR_NUM_CMD_BLKS];
-};
+	dma_addr_t ipr_cmnd_list_dma[IPR_NUM_CMD_BLKS];
+}; /* struct ipr_ioa_cfg */
 
 struct ipr_cmnd {
 	struct ipr_ioarcb ioarcb;
+	union {
+		struct ipr_ioadl_desc ioadl[IPR_NUM_IOADL_ENTRIES];
+		struct ipr_ioadl64_desc ioadl64[IPR_NUM_IOADL_ENTRIES];
+		struct ipr_ata64_ioadl ata_ioadl;
+	} i;
 	struct ipr_ioasa ioasa;
-	struct ipr_ioadl_desc ioadl[IPR_NUM_IOADL_ENTRIES];
 	struct list_head queue;
 	struct scsi_cmnd *scsi_cmd;
 	struct ata_queued_cmd *qc;
@@ -1221,7 +1477,7 @@ struct ipr_cmnd {
 	u8 sense_buffer[SCSI_SENSE_BUFFERSIZE];
 	dma_addr_t sense_buffer_dma;
 	unsigned short dma_use_sg;
-	dma_addr_t dma_handle;
+	dma_addr_t dma_addr;
 	struct ipr_cmnd *sibling;
 	union {
 		enum ipr_shutdown_type shutdown_type;
@@ -1314,8 +1570,6 @@ struct ipr_ioa_dump {
 	u32 next_page_index;
 	u32 page_offset;
 	u32 format;
-#define IPR_SDT_FMT2		2
-#define IPR_SDT_UNKNOWN		3
 }__attribute__((packed, aligned (4)));
 
 struct ipr_dump {
@@ -1377,6 +1631,13 @@ struct ipr_ucode_image_header {
 #define ipr_info(...) printk(KERN_INFO IPR_NAME ": "__VA_ARGS__)
 #define ipr_dbg(...) IPR_DBG_CMD(printk(KERN_INFO IPR_NAME ": "__VA_ARGS__))
 
+#define ipr_res_printk(level, ioa_cfg, bus, target, lun, fmt, ...) \
+	printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, (ioa_cfg)->host->host_no, \
+		bus, target, lun, ##__VA_ARGS__)
+
+#define ipr_res_err(ioa_cfg, res, fmt, ...) \
+	ipr_res_printk(KERN_ERR, ioa_cfg, (res)->bus, (res)->target, (res)->lun, fmt, ##__VA_ARGS__)
+
 #define ipr_ra_printk(level, ioa_cfg, ra, fmt, ...) \
 	printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, (ioa_cfg)->host->host_no, \
 		(ra).bus, (ra).target, (ra).lun, ##__VA_ARGS__)
@@ -1384,9 +1645,6 @@ struct ipr_ucode_image_header {
 #define ipr_ra_err(ioa_cfg, ra, fmt, ...) \
 	ipr_ra_printk(KERN_ERR, ioa_cfg, ra, fmt, ##__VA_ARGS__)
 
-#define ipr_res_err(ioa_cfg, res, fmt, ...) \
-	ipr_ra_err(ioa_cfg, (res)->cfgte.res_addr, fmt, ##__VA_ARGS__)
-
 #define ipr_phys_res_err(ioa_cfg, res, fmt, ...)			\
 {									\
 	if ((res).bus >= IPR_MAX_NUM_BUSES) {				\
@@ -1399,14 +1657,21 @@ struct ipr_ucode_image_header {
 }
 
 #define ipr_hcam_err(hostrcb, fmt, ...)					\
-{													\
-	if (ipr_is_device(&(hostrcb)->hcam.u.error.failing_dev_res_addr)) {		\
-		ipr_ra_err((hostrcb)->ioa_cfg,							\
-				(hostrcb)->hcam.u.error.failing_dev_res_addr,			\
-				fmt, ##__VA_ARGS__);							\
-	} else {											\
-		dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, ##__VA_ARGS__);		\
-	}												\
+{									\
+	if (ipr_is_device(hostrcb)) {					\
+		if ((hostrcb)->ioa_cfg->sis64) {			\
+			printk(KERN_ERR IPR_NAME ": %s: " fmt, 		\
+				ipr_format_resource_path(&hostrcb->hcam.u.error64.fd_res_path[0], \
+					&hostrcb->rp_buffer[0]),	\
+				__VA_ARGS__);				\
+		} else {						\
+			ipr_ra_err((hostrcb)->ioa_cfg,			\
+				(hostrcb)->hcam.u.error.fd_res_addr,	\
+				fmt, __VA_ARGS__);			\
+		}							\
+	} else {							\
+		dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, __VA_ARGS__); \
+	}								\
 }
 
 #define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\
@@ -1432,7 +1697,7 @@ ipr_err("-------------------------------
  **/
 static inline int ipr_is_ioa_resource(struct ipr_resource_entry *res)
 {
-	return (res->cfgte.flags & IPR_IS_IOA_RESOURCE) ? 1 : 0;
+	return res->type == IPR_RES_TYPE_IOAFP;
 }
 
 /**
@@ -1444,12 +1709,8 @@ static inline int ipr_is_ioa_resource(st
  **/
 static inline int ipr_is_af_dasd_device(struct ipr_resource_entry *res)
 {
-	if (IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data) &&
-	    !ipr_is_ioa_resource(res) &&
-	    IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_AF_DASD)
-		return 1;
-	else
-		return 0;
+	return res->type == IPR_RES_TYPE_AF_DASD ||
+		res->type == IPR_RES_TYPE_REMOTE_AF_DASD;
 }
 
 /**
@@ -1461,12 +1722,7 @@ static inline int ipr_is_af_dasd_device(
  **/
 static inline int ipr_is_vset_device(struct ipr_resource_entry *res)
 {
-	if (IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data) &&
-	    !ipr_is_ioa_resource(res) &&
-	    IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_VOLUME_SET)
-		return 1;
-	else
-		return 0;
+	return res->type == IPR_RES_TYPE_VOLUME_SET;
 }
 
 /**
@@ -1478,11 +1734,7 @@ static inline int ipr_is_vset_device(str
  **/
 static inline int ipr_is_gscsi(struct ipr_resource_entry *res)
 {
-	if (!ipr_is_ioa_resource(res) &&
-	    IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_GENERIC_SCSI)
-		return 1;
-	else
-		return 0;
+	return res->type == IPR_RES_TYPE_GENERIC_SCSI;
 }
 
 /**
@@ -1495,7 +1747,7 @@ static inline int ipr_is_gscsi(struct ip
 static inline int ipr_is_scsi_disk(struct ipr_resource_entry *res)
 {
 	if (ipr_is_af_dasd_device(res) ||
-	    (ipr_is_gscsi(res) && IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data)))
+	    (ipr_is_gscsi(res) && IPR_IS_DASD_DEVICE(res->std_inq_data)))
 		return 1;
 	else
 		return 0;
@@ -1510,11 +1762,7 @@ static inline int ipr_is_scsi_disk(struc
  **/
 static inline int ipr_is_gata(struct ipr_resource_entry *res)
 {
-	if (!ipr_is_ioa_resource(res) &&
-	    IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_GENERIC_ATA)
-		return 1;
-	else
-		return 0;
+	return res->type == IPR_RES_TYPE_GENERIC_ATA;
 }
 
 /**
@@ -1526,24 +1774,35 @@ static inline int ipr_is_gata(struct ipr
  **/
 static inline int ipr_is_naca_model(struct ipr_resource_entry *res)
 {
-	if (ipr_is_gscsi(res) && IPR_QUEUEING_MODEL(res) == IPR_QUEUE_NACA_MODEL)
+	if (ipr_is_gscsi(res) && res->qmodel == IPR_QUEUE_NACA_MODEL)
 		return 1;
 	return 0;
 }
 
 /**
- * ipr_is_device - Determine if resource address is that of a device
- * @res_addr:	resource address struct
+ * ipr_is_device - Determine if the hostrcb structure is related to a device
+ * @hostrcb:	host resource control blocks struct
  *
  * Return value:
  * 	1 if AF / 0 if not AF
  **/
-static inline int ipr_is_device(struct ipr_res_addr *res_addr)
+static inline int ipr_is_device(struct ipr_hostrcb *hostrcb)
 {
-	if ((res_addr->bus < IPR_MAX_NUM_BUSES) &&
-	    (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1)))
-		return 1;
+	struct ipr_res_addr *res_addr;
+	u8 *res_path;
+
+	if (hostrcb->ioa_cfg->sis64) {
+		res_path = &hostrcb->hcam.u.error64.fd_res_path[0];
+		if ((res_path[0] == 0x00 || res_path[0] == 0x80 ||
+		    res_path[0] == 0x81) && res_path[2] != 0xFF)
+			return 1;
+	} else {
+		res_addr = &hostrcb->hcam.u.error.fd_res_addr;
 
+		if ((res_addr->bus < IPR_MAX_NUM_BUSES) &&
+		    (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1)))
+			return 1;
+	}
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/iscsi_tcp.c linux-libre-2.6.34-gnu1/drivers/scsi/iscsi_tcp.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/iscsi_tcp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/iscsi_tcp.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 
 #include <linux/types.h>
 #include <linux/inet.h>
+#include <linux/slab.h>
 #include <linux/file.h>
 #include <linux/blkdev.h>
 #include <linux/crypto.h>
@@ -584,9 +585,10 @@ static void iscsi_sw_tcp_conn_stop(struc
 	struct iscsi_conn *conn = cls_conn->dd_data;
 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
 	struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
+	struct socket *sock = tcp_sw_conn->sock;
 
 	/* userspace may have goofed up and not bound us */
-	if (!tcp_sw_conn->sock)
+	if (!sock)
 		return;
 	/*
 	 * Make sure our recv side is stopped.
@@ -597,6 +599,11 @@ static void iscsi_sw_tcp_conn_stop(struc
 	set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
 	write_unlock_bh(&tcp_sw_conn->sock->sk->sk_callback_lock);
 
+	if (sock->sk->sk_sleep) {
+		sock->sk->sk_err = EIO;
+		wake_up_interruptible(sock->sk->sk_sleep);
+	}
+
 	iscsi_conn_stop(cls_conn, flag);
 	iscsi_sw_tcp_release_conn(conn);
 }
@@ -868,7 +875,7 @@ static struct scsi_host_template iscsi_s
 	.cmd_per_lun		= ISCSI_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,
+	.eh_target_reset_handler = iscsi_eh_recover_target,
 	.use_clustering         = DISABLE_CLUSTERING,
 	.slave_alloc            = iscsi_sw_tcp_slave_alloc,
 	.slave_configure        = iscsi_sw_tcp_slave_configure,
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/jazz_esp.c linux-libre-2.6.34-gnu1/drivers/scsi/jazz_esp.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/jazz_esp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/jazz_esp.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/Kconfig linux-libre-2.6.34-gnu1/drivers/scsi/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/scsi/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,9 +1,15 @@
 menu "SCSI device support"
 
+config SCSI_MOD
+       tristate
+       default y if SCSI=n || SCSI=y
+       default m if SCSI=m
+
 config RAID_ATTRS
 	tristate "RAID Transport Class"
 	default n
 	depends on BLOCK
+	depends on SCSI_MOD
 	---help---
 	  Provides RAID
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lasi700.c linux-libre-2.6.34-gnu1/drivers/scsi/lasi700.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/lasi700.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lasi700.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/blkdev.h>
 #include <linux/ioport.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_disc.c linux-libre-2.6.34-gnu1/drivers/scsi/libfc/fc_disc.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_disc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/libfc/fc_disc.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
  */
 
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <asm/unaligned.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_exch.c linux-libre-2.6.34-gnu1/drivers/scsi/libfc/fc_exch.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_exch.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/libfc/fc_exch.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,7 @@
  */
 
 #include <linux/timer.h>
-#include <linux/gfp.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 
 #include <scsi/fc/fc_fc2.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_fcp.c linux-libre-2.6.34-gnu1/drivers/scsi/libfc/fc_fcp.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_fcp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/libfc/fc_fcp.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/scatterlist.h>
 #include <linux/err.h>
 #include <linux/crc32.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi.h>
@@ -48,7 +49,7 @@ struct kmem_cache *scsi_pkt_cachep;
 #define FC_SRB_CMD_SENT		(1 << 0)	/* cmd has been sent */
 #define FC_SRB_RCV_STATUS	(1 << 1)	/* response has arrived */
 #define FC_SRB_ABORT_PENDING	(1 << 2)	/* cmd abort sent to device */
-#define FC_SRB_ABORTED		(1 << 3)	/* abort acknowleged */
+#define FC_SRB_ABORTED		(1 << 3)	/* abort acknowledged */
 #define FC_SRB_DISCONTIG	(1 << 4)	/* non-sequential data recvd */
 #define FC_SRB_COMPL		(1 << 5)	/* fc_io_compl has been run */
 #define FC_SRB_FCP_PROCESSING_TMO (1 << 6)	/* timer function processing */
@@ -519,7 +520,7 @@ crc_err:
  *
  * Called after receiving a Transfer Ready data descriptor.
  * If the LLD is capable of sequence offload then send down the
- * seq_blen ammount of data in single frame, otherwise send
+ * seq_blen amount of data in single frame, otherwise send
  * multiple frames of the maximum frame payload supported by
  * the target port.
  */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_frame.c linux-libre-2.6.34-gnu1/drivers/scsi/libfc/fc_frame.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_frame.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/libfc/fc_frame.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/crc32.h>
+#include <linux/gfp.h>
 
 #include <scsi/fc_frame.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_lport.c linux-libre-2.6.34-gnu1/drivers/scsi/libfc/fc_lport.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_lport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/libfc/fc_lport.c	2010-05-16 17:17:36.000000000 -0400
@@ -88,6 +88,7 @@
  */
 
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #include <scsi/fc/fc_gs.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_rport.c linux-libre-2.6.34-gnu1/drivers/scsi/libfc/fc_rport.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_rport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/libfc/fc_rport.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,7 @@
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/rcupdate.h>
 #include <linux/timer.h>
 #include <linux/workqueue.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/libiscsi.c linux-libre-2.6.34-gnu1/drivers/scsi/libiscsi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/libiscsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/libiscsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/kfifo.h>
 #include <linux/delay.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include <net/tcp.h>
 #include <scsi/scsi_cmnd.h>
@@ -470,12 +471,12 @@ static int iscsi_prep_scsi_cmd_pdu(struc
 
 	WARN_ON(hdrlength >= 256);
 	hdr->hlength = hdrlength & 0xFF;
+	hdr->cmdsn = task->cmdsn = cpu_to_be32(session->cmdsn);
 
 	if (session->tt->init_task && session->tt->init_task(task))
 		return -EIO;
 
 	task->state = ISCSI_TASK_RUNNING;
-	hdr->cmdsn = task->cmdsn = cpu_to_be32(session->cmdsn);
 	session->cmdsn++;
 
 	conn->scsicmd_pdus_cnt++;
@@ -1919,10 +1920,11 @@ static int iscsi_has_ping_timed_out(stru
 static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
 {
 	enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED;
-	struct iscsi_task *task = NULL;
+	struct iscsi_task *task = NULL, *running_task;
 	struct iscsi_cls_session *cls_session;
 	struct iscsi_session *session;
 	struct iscsi_conn *conn;
+	int i;
 
 	cls_session = starget_to_session(scsi_target(sc->device));
 	session = cls_session->dd_data;
@@ -1947,8 +1949,15 @@ static enum blk_eh_timer_return iscsi_eh
 	}
 
 	task = (struct iscsi_task *)sc->SCp.ptr;
-	if (!task)
+	if (!task) {
+		/*
+		 * Raced with completion. Just reset timer, and let it
+		 * complete normally
+		 */
+		rc = BLK_EH_RESET_TIMER;
 		goto done;
+	}
+
 	/*
 	 * If we have sent (at least queued to the network layer) a pdu or
 	 * recvd one for the task since the last timeout ask for
@@ -1956,10 +1965,10 @@ static enum blk_eh_timer_return iscsi_eh
 	 * we can check if it is the task or connection when we send the
 	 * nop as a ping.
 	 */
-	if (time_after_eq(task->last_xfer, task->last_timeout)) {
+	if (time_after(task->last_xfer, task->last_timeout)) {
 		ISCSI_DBG_EH(session, "Command making progress. Asking "
 			     "scsi-ml for more time to complete. "
-			     "Last data recv at %lu. Last timeout was at "
+			     "Last data xfer at %lu. Last timeout was at "
 			     "%lu\n.", task->last_xfer, task->last_timeout);
 		task->have_checked_conn = false;
 		rc = BLK_EH_RESET_TIMER;
@@ -1977,6 +1986,43 @@ static enum blk_eh_timer_return iscsi_eh
 		goto done;
 	}
 
+	for (i = 0; i < conn->session->cmds_max; i++) {
+		running_task = conn->session->cmds[i];
+		if (!running_task->sc || running_task == task ||
+		     running_task->state != ISCSI_TASK_RUNNING)
+			continue;
+
+		/*
+		 * Only check if cmds started before this one have made
+		 * progress, or this could never fail
+		 */
+		if (time_after(running_task->sc->jiffies_at_alloc,
+			       task->sc->jiffies_at_alloc))
+			continue;
+
+		if (time_after(running_task->last_xfer, task->last_timeout)) {
+			/*
+			 * This task has not made progress, but a task
+			 * started before us has transferred data since
+			 * we started/last-checked. We could be queueing
+			 * too many tasks or the LU is bad.
+			 *
+			 * If the device is bad the cmds ahead of us on
+			 * other devs will complete, and this loop will
+			 * eventually fail starting the scsi eh.
+			 */
+			ISCSI_DBG_EH(session, "Command has not made progress "
+				     "but commands ahead of it have. "
+				     "Asking scsi-ml for more time to "
+				     "complete. Our last xfer vs running task "
+				     "last xfer %lu/%lu. Last check %lu.\n",
+				     task->last_xfer, running_task->last_xfer,
+				     task->last_timeout);
+			rc = BLK_EH_RESET_TIMER;
+			goto done;
+		}
+	}
+
 	/* Assumes nop timeout is shorter than scsi cmd timeout */
 	if (task->have_checked_conn)
 		goto done;
@@ -2293,7 +2339,7 @@ EXPORT_SYMBOL_GPL(iscsi_session_recovery
  * This function will wait for a relogin, session termination from
  * userspace, or a recovery/replacement timeout.
  */
-static int iscsi_eh_session_reset(struct scsi_cmnd *sc)
+int iscsi_eh_session_reset(struct scsi_cmnd *sc)
 {
 	struct iscsi_cls_session *cls_session;
 	struct iscsi_session *session;
@@ -2344,6 +2390,7 @@ failed:
 	mutex_unlock(&session->eh_mutex);
 	return SUCCESS;
 }
+EXPORT_SYMBOL_GPL(iscsi_eh_session_reset);
 
 static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr)
 {
@@ -2358,8 +2405,7 @@ static void iscsi_prep_tgt_reset_pdu(str
  * iscsi_eh_target_reset - reset target
  * @sc: scsi command
  *
- * This will attempt to send a warm target reset. If that fails
- * then we will drop the session and attempt ERL0 recovery.
+ * This will attempt to send a warm target reset.
  */
 int iscsi_eh_target_reset(struct scsi_cmnd *sc)
 {
@@ -2431,12 +2477,27 @@ done:
 	ISCSI_DBG_EH(session, "tgt %s reset result = %s\n", session->targetname,
 		     rc == SUCCESS ? "SUCCESS" : "FAILED");
 	mutex_unlock(&session->eh_mutex);
+	return rc;
+}
+EXPORT_SYMBOL_GPL(iscsi_eh_target_reset);
 
+/**
+ * iscsi_eh_recover_target - reset target and possibly the session
+ * @sc: scsi command
+ *
+ * This will attempt to send a warm target reset. If that fails,
+ * we will escalate to ERL0 session recovery.
+ */
+int iscsi_eh_recover_target(struct scsi_cmnd *sc)
+{
+	int rc;
+
+	rc = iscsi_eh_target_reset(sc);
 	if (rc == FAILED)
 		rc = iscsi_eh_session_reset(sc);
 	return rc;
 }
-EXPORT_SYMBOL_GPL(iscsi_eh_target_reset);
+EXPORT_SYMBOL_GPL(iscsi_eh_recover_target);
 
 /*
  * Pre-allocate a pool of @max items of @item_size. By default, the pool
@@ -3027,14 +3088,15 @@ static void iscsi_start_session_recovery
 		session->state = ISCSI_STATE_TERMINATE;
 	else if (conn->stop_stage != STOP_CONN_RECOVER)
 		session->state = ISCSI_STATE_IN_RECOVERY;
+
+	old_stop_stage = conn->stop_stage;
+	conn->stop_stage = flag;
 	spin_unlock_bh(&session->lock);
 
 	del_timer_sync(&conn->transport_timer);
 	iscsi_suspend_tx(conn);
 
 	spin_lock_bh(&session->lock);
-	old_stop_stage = conn->stop_stage;
-	conn->stop_stage = flag;
 	conn->c_stage = ISCSI_CONN_STOPPED;
 	spin_unlock_bh(&session->lock);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/libiscsi_tcp.c linux-libre-2.6.34-gnu1/drivers/scsi/libiscsi_tcp.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/libiscsi_tcp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/libiscsi_tcp.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/inet.h>
+#include <linux/slab.h>
 #include <linux/file.h>
 #include <linux/blkdev.h>
 #include <linux/crypto.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/libsas/sas_ata.c linux-libre-2.6.34-gnu1/drivers/scsi/libsas/sas_ata.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/libsas/sas_ata.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/libsas/sas_ata.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  */
 
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 #include <scsi/sas_ata.h>
 #include "sas_internal.h"
@@ -394,11 +395,15 @@ int sas_ata_init_host_and_port(struct do
 void sas_ata_task_abort(struct sas_task *task)
 {
 	struct ata_queued_cmd *qc = task->uldd_task;
+	struct request_queue *q = qc->scsicmd->device->request_queue;
 	struct completion *waiting;
+	unsigned long flags;
 
 	/* Bounce SCSI-initiated commands to the SCSI EH */
 	if (qc->scsicmd) {
+		spin_lock_irqsave(q->queue_lock, flags);
 		blk_abort_request(qc->scsicmd->request);
+		spin_unlock_irqrestore(q->queue_lock, flags);
 		scsi_schedule_eh(qc->scsicmd->device->host);
 		return;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/libsas/sas_discover.c linux-libre-2.6.34-gnu1/drivers/scsi/libsas/sas_discover.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/libsas/sas_discover.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/libsas/sas_discover.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
  */
 
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_eh.h>
 #include "sas_internal.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/libsas/sas_expander.c linux-libre-2.6.34-gnu1/drivers/scsi/libsas/sas_expander.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/libsas/sas_expander.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/libsas/sas_expander.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 
 #include <linux/scatterlist.h>
 #include <linux/blkdev.h>
+#include <linux/slab.h>
 
 #include "sas_internal.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/libsas/sas_host_smp.c linux-libre-2.6.34-gnu1/drivers/scsi/libsas/sas_host_smp.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/libsas/sas_host_smp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/libsas/sas_host_smp.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 #include <linux/scatterlist.h>
 #include <linux/blkdev.h>
+#include <linux/slab.h>
 
 #include "sas_internal.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/libsas/sas_init.c linux-libre-2.6.34-gnu1/drivers/scsi/libsas/sas_init.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/libsas/sas_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/libsas/sas_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/spinlock.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/libsas/sas_scsi_host.c linux-libre-2.6.34-gnu1/drivers/scsi/libsas/sas_scsi_host.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/libsas/sas_scsi_host.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/libsas/sas_scsi_host.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,7 @@
 #include <linux/err.h>
 #include <linux/blkdev.h>
 #include <linux/freezer.h>
+#include <linux/gfp.h>
 #include <linux/scatterlist.h>
 #include <linux/libata.h>
 
@@ -1029,6 +1030,8 @@ int __sas_task_abort(struct sas_task *ta
 void sas_task_abort(struct sas_task *task)
 {
 	struct scsi_cmnd *sc = task->uldd_task;
+	struct request_queue *q = sc->device->request_queue;
+	unsigned long flags;
 
 	/* Escape for libsas internal commands */
 	if (!sc) {
@@ -1043,7 +1046,9 @@ void sas_task_abort(struct sas_task *tas
 		return;
 	}
 
+	spin_lock_irqsave(q->queue_lock, flags);
 	blk_abort_request(sc->request);
+	spin_unlock_irqrestore(q->queue_lock, flags);
 	scsi_schedule_eh(sc->device->host);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/libsrp.c linux-libre-2.6.34-gnu1/drivers/scsi/libsrp.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/libsrp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/libsrp.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * SCSI RDAM Protocol lib functions
+ * SCSI RDMA Protocol lib functions
  *
  * Copyright (C) 2006 FUJITA Tomonori <tomof@acm.org>
  *
@@ -19,6 +19,7 @@
  * 02110-1301 USA
  */
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/kfifo.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
@@ -328,7 +329,7 @@ int srp_transfer_data(struct scsi_cmnd *
 	int offset, err = 0;
 	u8 format;
 
-	offset = cmd->add_cdb_len * 4;
+	offset = cmd->add_cdb_len & ~3;
 
 	dir = srp_cmd_direction(cmd);
 	if (dir == DMA_FROM_DEVICE)
@@ -366,7 +367,7 @@ static int vscsis_data_length(struct srp
 {
 	struct srp_direct_buf *md;
 	struct srp_indirect_buf *id;
-	int len = 0, offset = cmd->add_cdb_len * 4;
+	int len = 0, offset = cmd->add_cdb_len & ~3;
 	u8 fmt;
 
 	if (dir == DMA_TO_DEVICE)
@@ -440,6 +441,6 @@ int srp_cmd_queue(struct Scsi_Host *shos
 }
 EXPORT_SYMBOL_GPL(srp_cmd_queue);
 
-MODULE_DESCRIPTION("SCSI RDAM Protocol lib functions");
+MODULE_DESCRIPTION("SCSI RDMA Protocol lib functions");
 MODULE_AUTHOR("FUJITA Tomonori");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_attr.c linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_attr.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_attr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_attr.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/aer.h>
+#include <linux/gfp.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
@@ -482,6 +483,41 @@ lpfc_link_state_show(struct device *dev,
 }
 
 /**
+ * lpfc_link_state_store - Transition the link_state on an HBA port
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: one or more lpfc_polling_flags values.
+ * @count: not used.
+ *
+ * Returns:
+ * -EINVAL if the buffer is not "up" or "down"
+ * return from link state change function if non-zero
+ * length of the buf on success
+ **/
+static ssize_t
+lpfc_link_state_store(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct Scsi_Host  *shost = class_to_shost(dev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+
+	int status = -EINVAL;
+
+	if ((strncmp(buf, "up", sizeof("up") - 1) == 0) &&
+			(phba->link_state == LPFC_LINK_DOWN))
+		status = phba->lpfc_hba_init_link(phba);
+	else if ((strncmp(buf, "down", sizeof("down") - 1) == 0) &&
+			(phba->link_state >= LPFC_LINK_UP))
+		status = phba->lpfc_hba_down_link(phba);
+
+	if (status == 0)
+		return strlen(buf);
+	else
+		return status;
+}
+
+/**
  * lpfc_num_discovered_ports_show - Return sum of mapped and unmapped vports
  * @dev: class device that is converted into a Scsi_host.
  * @attr: device attribute, not used.
@@ -1219,7 +1255,7 @@ lpfc_##attr##_show(struct device *dev, s
 	struct Scsi_Host  *shost = class_to_shost(dev);\
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
 	struct lpfc_hba   *phba = vport->phba;\
-	int val = 0;\
+	uint val = 0;\
 	val = phba->cfg_##attr;\
 	return snprintf(buf, PAGE_SIZE, "%d\n",\
 			phba->cfg_##attr);\
@@ -1247,7 +1283,7 @@ lpfc_##attr##_show(struct device *dev, s
 	struct Scsi_Host  *shost = class_to_shost(dev);\
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
 	struct lpfc_hba   *phba = vport->phba;\
-	int val = 0;\
+	uint val = 0;\
 	val = phba->cfg_##attr;\
 	return snprintf(buf, PAGE_SIZE, "%#x\n",\
 			phba->cfg_##attr);\
@@ -1274,7 +1310,7 @@ lpfc_##attr##_show(struct device *dev, s
  **/
 #define lpfc_param_init(attr, default, minval, maxval)	\
 static int \
-lpfc_##attr##_init(struct lpfc_hba *phba, int val) \
+lpfc_##attr##_init(struct lpfc_hba *phba, uint val) \
 { \
 	if (val >= minval && val <= maxval) {\
 		phba->cfg_##attr = val;\
@@ -1309,7 +1345,7 @@ lpfc_##attr##_init(struct lpfc_hba *phba
  **/
 #define lpfc_param_set(attr, default, minval, maxval)	\
 static int \
-lpfc_##attr##_set(struct lpfc_hba *phba, int val) \
+lpfc_##attr##_set(struct lpfc_hba *phba, uint val) \
 { \
 	if (val >= minval && val <= maxval) {\
 		phba->cfg_##attr = val;\
@@ -1350,7 +1386,7 @@ lpfc_##attr##_store(struct device *dev,
 	struct Scsi_Host  *shost = class_to_shost(dev);\
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
 	struct lpfc_hba   *phba = vport->phba;\
-	int val=0;\
+	uint val = 0;\
 	if (!isdigit(buf[0]))\
 		return -EINVAL;\
 	if (sscanf(buf, "%i", &val) != 1)\
@@ -1382,7 +1418,7 @@ lpfc_##attr##_show(struct device *dev, s
 { \
 	struct Scsi_Host  *shost = class_to_shost(dev);\
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
-	int val = 0;\
+	uint val = 0;\
 	val = vport->cfg_##attr;\
 	return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_##attr);\
 }
@@ -1409,7 +1445,7 @@ lpfc_##attr##_show(struct device *dev, s
 { \
 	struct Scsi_Host  *shost = class_to_shost(dev);\
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
-	int val = 0;\
+	uint val = 0;\
 	val = vport->cfg_##attr;\
 	return snprintf(buf, PAGE_SIZE, "%#x\n", vport->cfg_##attr);\
 }
@@ -1434,7 +1470,7 @@ lpfc_##attr##_show(struct device *dev, s
  **/
 #define lpfc_vport_param_init(attr, default, minval, maxval)	\
 static int \
-lpfc_##attr##_init(struct lpfc_vport *vport, int val) \
+lpfc_##attr##_init(struct lpfc_vport *vport, uint val) \
 { \
 	if (val >= minval && val <= maxval) {\
 		vport->cfg_##attr = val;\
@@ -1466,7 +1502,7 @@ lpfc_##attr##_init(struct lpfc_vport *vp
  **/
 #define lpfc_vport_param_set(attr, default, minval, maxval)	\
 static int \
-lpfc_##attr##_set(struct lpfc_vport *vport, int val) \
+lpfc_##attr##_set(struct lpfc_vport *vport, uint val) \
 { \
 	if (val >= minval && val <= maxval) {\
 		vport->cfg_##attr = val;\
@@ -1502,7 +1538,7 @@ lpfc_##attr##_store(struct device *dev,
 { \
 	struct Scsi_Host  *shost = class_to_shost(dev);\
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
-	int val=0;\
+	uint val = 0;\
 	if (!isdigit(buf[0]))\
 		return -EINVAL;\
 	if (sscanf(buf, "%i", &val) != 1)\
@@ -1515,22 +1551,22 @@ lpfc_##attr##_store(struct device *dev,
 
 
 #define LPFC_ATTR(name, defval, minval, maxval, desc) \
-static int lpfc_##name = defval;\
-module_param(lpfc_##name, int, 0);\
+static uint lpfc_##name = defval;\
+module_param(lpfc_##name, uint, 0);\
 MODULE_PARM_DESC(lpfc_##name, desc);\
 lpfc_param_init(name, defval, minval, maxval)
 
 #define LPFC_ATTR_R(name, defval, minval, maxval, desc) \
-static int lpfc_##name = defval;\
-module_param(lpfc_##name, int, 0);\
+static uint lpfc_##name = defval;\
+module_param(lpfc_##name, uint, 0);\
 MODULE_PARM_DESC(lpfc_##name, desc);\
 lpfc_param_show(name)\
 lpfc_param_init(name, defval, minval, maxval)\
 static DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
 
 #define LPFC_ATTR_RW(name, defval, minval, maxval, desc) \
-static int lpfc_##name = defval;\
-module_param(lpfc_##name, int, 0);\
+static uint lpfc_##name = defval;\
+module_param(lpfc_##name, uint, 0);\
 MODULE_PARM_DESC(lpfc_##name, desc);\
 lpfc_param_show(name)\
 lpfc_param_init(name, defval, minval, maxval)\
@@ -1540,16 +1576,16 @@ static DEVICE_ATTR(lpfc_##name, S_IRUGO
 		   lpfc_##name##_show, lpfc_##name##_store)
 
 #define LPFC_ATTR_HEX_R(name, defval, minval, maxval, desc) \
-static int lpfc_##name = defval;\
-module_param(lpfc_##name, int, 0);\
+static uint lpfc_##name = defval;\
+module_param(lpfc_##name, uint, 0);\
 MODULE_PARM_DESC(lpfc_##name, desc);\
 lpfc_param_hex_show(name)\
 lpfc_param_init(name, defval, minval, maxval)\
 static DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
 
 #define LPFC_ATTR_HEX_RW(name, defval, minval, maxval, desc) \
-static int lpfc_##name = defval;\
-module_param(lpfc_##name, int, 0);\
+static uint lpfc_##name = defval;\
+module_param(lpfc_##name, uint, 0);\
 MODULE_PARM_DESC(lpfc_##name, desc);\
 lpfc_param_hex_show(name)\
 lpfc_param_init(name, defval, minval, maxval)\
@@ -1559,22 +1595,22 @@ static DEVICE_ATTR(lpfc_##name, S_IRUGO
 		   lpfc_##name##_show, lpfc_##name##_store)
 
 #define LPFC_VPORT_ATTR(name, defval, minval, maxval, desc) \
-static int lpfc_##name = defval;\
-module_param(lpfc_##name, int, 0);\
+static uint lpfc_##name = defval;\
+module_param(lpfc_##name, uint, 0);\
 MODULE_PARM_DESC(lpfc_##name, desc);\
 lpfc_vport_param_init(name, defval, minval, maxval)
 
 #define LPFC_VPORT_ATTR_R(name, defval, minval, maxval, desc) \
-static int lpfc_##name = defval;\
-module_param(lpfc_##name, int, 0);\
+static uint lpfc_##name = defval;\
+module_param(lpfc_##name, uint, 0);\
 MODULE_PARM_DESC(lpfc_##name, desc);\
 lpfc_vport_param_show(name)\
 lpfc_vport_param_init(name, defval, minval, maxval)\
 static DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
 
 #define LPFC_VPORT_ATTR_RW(name, defval, minval, maxval, desc) \
-static int lpfc_##name = defval;\
-module_param(lpfc_##name, int, 0);\
+static uint lpfc_##name = defval;\
+module_param(lpfc_##name, uint, 0);\
 MODULE_PARM_DESC(lpfc_##name, desc);\
 lpfc_vport_param_show(name)\
 lpfc_vport_param_init(name, defval, minval, maxval)\
@@ -1584,16 +1620,16 @@ static DEVICE_ATTR(lpfc_##name, S_IRUGO
 		   lpfc_##name##_show, lpfc_##name##_store)
 
 #define LPFC_VPORT_ATTR_HEX_R(name, defval, minval, maxval, desc) \
-static int lpfc_##name = defval;\
-module_param(lpfc_##name, int, 0);\
+static uint lpfc_##name = defval;\
+module_param(lpfc_##name, uint, 0);\
 MODULE_PARM_DESC(lpfc_##name, desc);\
 lpfc_vport_param_hex_show(name)\
 lpfc_vport_param_init(name, defval, minval, maxval)\
 static DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
 
 #define LPFC_VPORT_ATTR_HEX_RW(name, defval, minval, maxval, desc) \
-static int lpfc_##name = defval;\
-module_param(lpfc_##name, int, 0);\
+static uint lpfc_##name = defval;\
+module_param(lpfc_##name, uint, 0);\
 MODULE_PARM_DESC(lpfc_##name, desc);\
 lpfc_vport_param_hex_show(name)\
 lpfc_vport_param_init(name, defval, minval, maxval)\
@@ -1614,7 +1650,8 @@ static DEVICE_ATTR(programtype, S_IRUGO,
 static DEVICE_ATTR(portnum, S_IRUGO, lpfc_vportnum_show, NULL);
 static DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL);
 static DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL);
-static DEVICE_ATTR(link_state, S_IRUGO, lpfc_link_state_show, NULL);
+static DEVICE_ATTR(link_state, S_IRUGO | S_IWUSR, lpfc_link_state_show,
+		lpfc_link_state_store);
 static DEVICE_ATTR(option_rom_version, S_IRUGO,
 		   lpfc_option_rom_version_show, NULL);
 static DEVICE_ATTR(num_discovered_ports, S_IRUGO,
@@ -1897,6 +1934,17 @@ static DEVICE_ATTR(lpfc_enable_npiv, S_I
 			 lpfc_enable_npiv_show, NULL);
 
 /*
+# lpfc_suppress_link_up:  Bring link up at initialization
+#            0x0  = bring link up (issue MBX_INIT_LINK)
+#            0x1  = do NOT bring link up at initialization(MBX_INIT_LINK)
+#            0x2  = never bring up link
+# Default value is 0.
+*/
+LPFC_ATTR_R(suppress_link_up, LPFC_INITIALIZE_LINK, LPFC_INITIALIZE_LINK,
+		LPFC_DELAY_INIT_LINK_INDEFINITELY,
+		"Suppress Link Up at initialization");
+
+/*
 # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
 # until the timer expires. Value range is [0,255]. Default value is 30.
 */
@@ -1921,8 +1969,7 @@ lpfc_nodev_tmo_show(struct device *dev,
 {
 	struct Scsi_Host  *shost = class_to_shost(dev);
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
-	int val = 0;
-	val = vport->cfg_devloss_tmo;
+
 	return snprintf(buf, PAGE_SIZE, "%d\n",	vport->cfg_devloss_tmo);
 }
 
@@ -3114,12 +3161,12 @@ LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
 /*
 # lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that
 #		support this feature
-#       0  = MSI disabled (default)
+#       0  = MSI disabled
 #       1  = MSI enabled
-#       2  = MSI-X enabled
-# Value range is [0,2]. Default value is 0.
+#       2  = MSI-X enabled (default)
+# Value range is [0,2]. Default value is 2.
 */
-LPFC_ATTR_R(use_msi, 0, 0, 2, "Use Message Signaled Interrupts (1) or "
+LPFC_ATTR_R(use_msi, 2, 0, 2, "Use Message Signaled Interrupts (1) or "
 	    "MSI-X (2), if possible");
 
 /*
@@ -3278,6 +3325,7 @@ struct device_attribute *lpfc_hba_attrs[
 	&dev_attr_lpfc_prot_sg_seg_cnt,
 	&dev_attr_lpfc_aer_support,
 	&dev_attr_lpfc_aer_state_cleanup,
+	&dev_attr_lpfc_suppress_link_up,
 	NULL,
 };
 
@@ -4456,7 +4504,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
 	lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
 	lpfc_hba_log_verbose_init(phba, lpfc_log_verbose);
 	lpfc_aer_support_init(phba, lpfc_aer_support);
-
+	lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up);
 	return;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_bsg.c linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_bsg.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_bsg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_bsg.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2009 Emulex.  All rights reserved.                *
+ * Copyright (C) 2009-2010 Emulex.  All rights reserved.                *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
@@ -21,6 +21,8 @@
 #include <linux/interrupt.h>
 #include <linux/mempool.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
@@ -33,6 +35,7 @@
 #include "lpfc_sli.h"
 #include "lpfc_sli4.h"
 #include "lpfc_nl.h"
+#include "lpfc_bsg.h"
 #include "lpfc_disc.h"
 #include "lpfc_scsi.h"
 #include "lpfc.h"
@@ -41,14 +44,196 @@
 #include "lpfc_vport.h"
 #include "lpfc_version.h"
 
+struct lpfc_bsg_event {
+	struct list_head node;
+	struct kref kref;
+	wait_queue_head_t wq;
+
+	/* Event type and waiter identifiers */
+	uint32_t type_mask;
+	uint32_t req_id;
+	uint32_t reg_id;
+
+	/* next two flags are here for the auto-delete logic */
+	unsigned long wait_time_stamp;
+	int waiting;
+
+	/* seen and not seen events */
+	struct list_head events_to_get;
+	struct list_head events_to_see;
+
+	/* job waiting for this event to finish */
+	struct fc_bsg_job *set_job;
+};
+
+struct lpfc_bsg_iocb {
+	struct lpfc_iocbq *cmdiocbq;
+	struct lpfc_iocbq *rspiocbq;
+	struct lpfc_dmabuf *bmp;
+	struct lpfc_nodelist *ndlp;
+
+	/* job waiting for this iocb to finish */
+	struct fc_bsg_job *set_job;
+};
+
+struct lpfc_bsg_mbox {
+	LPFC_MBOXQ_t *pmboxq;
+	MAILBOX_t *mb;
+
+	/* job waiting for this mbox command to finish */
+	struct fc_bsg_job *set_job;
+};
+
+#define MENLO_DID 0x0000FC0E
+
+struct lpfc_bsg_menlo {
+	struct lpfc_iocbq *cmdiocbq;
+	struct lpfc_iocbq *rspiocbq;
+	struct lpfc_dmabuf *bmp;
+
+	/* job waiting for this iocb to finish */
+	struct fc_bsg_job *set_job;
+};
+
+#define TYPE_EVT 	1
+#define TYPE_IOCB	2
+#define TYPE_MBOX	3
+#define TYPE_MENLO	4
+struct bsg_job_data {
+	uint32_t type;
+	union {
+		struct lpfc_bsg_event *evt;
+		struct lpfc_bsg_iocb iocb;
+		struct lpfc_bsg_mbox mbox;
+		struct lpfc_bsg_menlo menlo;
+	} context_un;
+};
+
+struct event_data {
+	struct list_head node;
+	uint32_t type;
+	uint32_t immed_dat;
+	void *data;
+	uint32_t len;
+};
+
+#define BUF_SZ_4K 4096
+#define SLI_CT_ELX_LOOPBACK 0x10
+
+enum ELX_LOOPBACK_CMD {
+	ELX_LOOPBACK_XRI_SETUP,
+	ELX_LOOPBACK_DATA,
+};
+
+#define ELX_LOOPBACK_HEADER_SZ \
+	(size_t)(&((struct lpfc_sli_ct_request *)NULL)->un)
+
+struct lpfc_dmabufext {
+	struct lpfc_dmabuf dma;
+	uint32_t size;
+	uint32_t flag;
+};
+
 /**
- * lpfc_bsg_rport_ct - send a CT command from a bsg request
+ * lpfc_bsg_send_mgmt_cmd_cmp - lpfc_bsg_send_mgmt_cmd's completion handler
+ * @phba: Pointer to HBA context object.
+ * @cmdiocbq: Pointer to command iocb.
+ * @rspiocbq: Pointer to response iocb.
+ *
+ * This function is the completion handler for iocbs issued using
+ * lpfc_bsg_send_mgmt_cmd function. This function is called by the
+ * ring event handler function without any lock held. This function
+ * can be called from both worker thread context and interrupt
+ * context. This function also can be called from another thread which
+ * cleans up the SLI layer objects.
+ * This function copies the contents of the response iocb to the
+ * response iocb memory object provided by the caller of
+ * lpfc_sli_issue_iocb_wait and then wakes up the thread which
+ * sleeps for the iocb completion.
+ **/
+static void
+lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
+			struct lpfc_iocbq *cmdiocbq,
+			struct lpfc_iocbq *rspiocbq)
+{
+	unsigned long iflags;
+	struct bsg_job_data *dd_data;
+	struct fc_bsg_job *job;
+	IOCB_t *rsp;
+	struct lpfc_dmabuf *bmp;
+	struct lpfc_nodelist *ndlp;
+	struct lpfc_bsg_iocb *iocb;
+	unsigned long flags;
+	int rc = 0;
+
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
+	dd_data = cmdiocbq->context1;
+	if (!dd_data) {
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+		return;
+	}
+
+	iocb = &dd_data->context_un.iocb;
+	job = iocb->set_job;
+	job->dd_data = NULL; /* so timeout handler does not reply */
+
+	spin_lock_irqsave(&phba->hbalock, iflags);
+	cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
+	if (cmdiocbq->context2 && rspiocbq)
+		memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
+		       &rspiocbq->iocb, sizeof(IOCB_t));
+	spin_unlock_irqrestore(&phba->hbalock, iflags);
+
+	bmp = iocb->bmp;
+	rspiocbq = iocb->rspiocbq;
+	rsp = &rspiocbq->iocb;
+	ndlp = iocb->ndlp;
+
+	pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
+		     job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
+		     job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+
+	if (rsp->ulpStatus) {
+		if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
+			switch (rsp->un.ulpWord[4] & 0xff) {
+			case IOERR_SEQUENCE_TIMEOUT:
+				rc = -ETIMEDOUT;
+				break;
+			case IOERR_INVALID_RPI:
+				rc = -EFAULT;
+				break;
+			default:
+				rc = -EACCES;
+				break;
+			}
+		} else
+			rc = -EACCES;
+	} else
+		job->reply->reply_payload_rcv_len =
+			rsp->un.genreq64.bdl.bdeSize;
+
+	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
+	lpfc_sli_release_iocbq(phba, rspiocbq);
+	lpfc_sli_release_iocbq(phba, cmdiocbq);
+	lpfc_nlp_put(ndlp);
+	kfree(bmp);
+	kfree(dd_data);
+	/* make error code available to userspace */
+	job->reply->result = rc;
+	/* complete the job back to userspace */
+	job->job_done(job);
+	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+	return;
+}
+
+/**
+ * lpfc_bsg_send_mgmt_cmd - send a CT command from a bsg request
  * @job: fc_bsg_job to handle
- */
+ **/
 static int
-lpfc_bsg_rport_ct(struct fc_bsg_job *job)
+lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
 {
-	struct Scsi_Host *shost = job->shost;
 	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
 	struct lpfc_hba *phba = vport->phba;
 	struct lpfc_rport_data *rdata = job->rport->dd_data;
@@ -65,57 +250,60 @@ lpfc_bsg_rport_ct(struct fc_bsg_job *job
 	struct scatterlist *sgel = NULL;
 	int numbde;
 	dma_addr_t busaddr;
+	struct bsg_job_data *dd_data;
+	uint32_t creg_val;
 	int rc = 0;
 
 	/* in case no data is transferred */
 	job->reply->reply_payload_rcv_len = 0;
 
+	/* allocate our bsg tracking structure */
+	dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
+	if (!dd_data) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2733 Failed allocation of dd_data\n");
+		rc = -ENOMEM;
+		goto no_dd_data;
+	}
+
 	if (!lpfc_nlp_get(ndlp)) {
-		job->reply->result = -ENODEV;
-		return 0;
+		rc = -ENODEV;
+		goto no_ndlp;
+	}
+
+	bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+	if (!bmp) {
+		rc = -ENOMEM;
+		goto free_ndlp;
 	}
 
 	if (ndlp->nlp_flag & NLP_ELS_SND_MASK) {
 		rc = -ENODEV;
-		goto free_ndlp_exit;
+		goto free_bmp;
 	}
 
-	spin_lock_irq(shost->host_lock);
 	cmdiocbq = lpfc_sli_get_iocbq(phba);
 	if (!cmdiocbq) {
 		rc = -ENOMEM;
-		spin_unlock_irq(shost->host_lock);
-		goto free_ndlp_exit;
+		goto free_bmp;
 	}
-	cmd = &cmdiocbq->iocb;
 
+	cmd = &cmdiocbq->iocb;
 	rspiocbq = lpfc_sli_get_iocbq(phba);
 	if (!rspiocbq) {
 		rc = -ENOMEM;
 		goto free_cmdiocbq;
 	}
-	spin_unlock_irq(shost->host_lock);
 
 	rsp = &rspiocbq->iocb;
-
-	bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
-	if (!bmp) {
-		rc = -ENOMEM;
-		spin_lock_irq(shost->host_lock);
-		goto free_rspiocbq;
-	}
-
-	spin_lock_irq(shost->host_lock);
 	bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys);
 	if (!bmp->virt) {
 		rc = -ENOMEM;
-		goto free_bmp;
+		goto free_rspiocbq;
 	}
-	spin_unlock_irq(shost->host_lock);
 
 	INIT_LIST_HEAD(&bmp->list);
 	bpl = (struct ulp_bde64 *) bmp->virt;
-
 	request_nseg = pci_map_sg(phba->pcidev, job->request_payload.sg_list,
 				  job->request_payload.sg_cnt, DMA_TO_DEVICE);
 	for_each_sg(job->request_payload.sg_list, sgel, request_nseg, numbde) {
@@ -157,78 +345,152 @@ lpfc_bsg_rport_ct(struct fc_bsg_job *job
 	cmd->ulpContext = ndlp->nlp_rpi;
 	cmd->ulpOwner = OWN_CHIP;
 	cmdiocbq->vport = phba->pport;
-	cmdiocbq->context1 = NULL;
-	cmdiocbq->context2 = NULL;
+	cmdiocbq->context3 = bmp;
 	cmdiocbq->iocb_flag |= LPFC_IO_LIBDFC;
-
 	timeout = phba->fc_ratov * 2;
-	job->dd_data = cmdiocbq;
+	cmd->ulpTimeout = timeout;
 
-	rc = lpfc_sli_issue_iocb_wait(phba, LPFC_ELS_RING, cmdiocbq, rspiocbq,
-					timeout + LPFC_DRVR_TIMEOUT);
+	cmdiocbq->iocb_cmpl = lpfc_bsg_send_mgmt_cmd_cmp;
+	cmdiocbq->context1 = dd_data;
+	cmdiocbq->context2 = rspiocbq;
+	dd_data->type = TYPE_IOCB;
+	dd_data->context_un.iocb.cmdiocbq = cmdiocbq;
+	dd_data->context_un.iocb.rspiocbq = rspiocbq;
+	dd_data->context_un.iocb.set_job = job;
+	dd_data->context_un.iocb.bmp = bmp;
+	dd_data->context_un.iocb.ndlp = ndlp;
 
-	if (rc != IOCB_TIMEDOUT) {
-		pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
-			     job->request_payload.sg_cnt, DMA_TO_DEVICE);
-		pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
-			     job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+	if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+		creg_val = readl(phba->HCregaddr);
+		creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
+		writel(creg_val, phba->HCregaddr);
+		readl(phba->HCregaddr); /* flush */
 	}
 
-	if (rc == IOCB_TIMEDOUT) {
-		lpfc_sli_release_iocbq(phba, rspiocbq);
-		rc = -EACCES;
-		goto free_ndlp_exit;
-	}
+	rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0);
 
-	if (rc != IOCB_SUCCESS) {
-		rc = -EACCES;
-		goto free_outdmp;
-	}
+	if (rc == IOCB_SUCCESS)
+		return 0; /* done for now */
 
-	if (rsp->ulpStatus) {
-		if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
-			switch (rsp->un.ulpWord[4] & 0xff) {
-			case IOERR_SEQUENCE_TIMEOUT:
-				rc = -ETIMEDOUT;
-				break;
-			case IOERR_INVALID_RPI:
-				rc = -EFAULT;
-				break;
-			default:
-				rc = -EACCES;
-				break;
-			}
-			goto free_outdmp;
-		}
-	} else
-		job->reply->reply_payload_rcv_len =
-			rsp->un.genreq64.bdl.bdeSize;
+	/* iocb failed so cleanup */
+	pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
+		     job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
+		     job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
 
-free_outdmp:
-	spin_lock_irq(shost->host_lock);
 	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
-free_bmp:
-	kfree(bmp);
+
 free_rspiocbq:
 	lpfc_sli_release_iocbq(phba, rspiocbq);
 free_cmdiocbq:
 	lpfc_sli_release_iocbq(phba, cmdiocbq);
-	spin_unlock_irq(shost->host_lock);
-free_ndlp_exit:
+free_bmp:
+	kfree(bmp);
+free_ndlp:
 	lpfc_nlp_put(ndlp);
+no_ndlp:
+	kfree(dd_data);
+no_dd_data:
+	/* make error code available to userspace */
+	job->reply->result = rc;
+	job->dd_data = NULL;
+	return rc;
+}
+
+/**
+ * lpfc_bsg_rport_els_cmp - lpfc_bsg_rport_els's completion handler
+ * @phba: Pointer to HBA context object.
+ * @cmdiocbq: Pointer to command iocb.
+ * @rspiocbq: Pointer to response iocb.
+ *
+ * This function is the completion handler for iocbs issued using
+ * lpfc_bsg_rport_els_cmp function. This function is called by the
+ * ring event handler function without any lock held. This function
+ * can be called from both worker thread context and interrupt
+ * context. This function also can be called from other thread which
+ * cleans up the SLI layer objects.
+ * This function copies the contents of the response iocb to the
+ * response iocb memory object provided by the caller of
+ * lpfc_sli_issue_iocb_wait and then wakes up the thread which
+ * sleeps for the iocb completion.
+ **/
+static void
+lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
+			struct lpfc_iocbq *cmdiocbq,
+			struct lpfc_iocbq *rspiocbq)
+{
+	struct bsg_job_data *dd_data;
+	struct fc_bsg_job *job;
+	IOCB_t *rsp;
+	struct lpfc_nodelist *ndlp;
+	struct lpfc_dmabuf *pbuflist = NULL;
+	struct fc_bsg_ctels_reply *els_reply;
+	uint8_t *rjt_data;
+	unsigned long flags;
+	int rc = 0;
 
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
+	dd_data = cmdiocbq->context1;
+	/* normal completion and timeout crossed paths, already done */
+	if (!dd_data) {
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+		return;
+	}
+
+	cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
+	if (cmdiocbq->context2 && rspiocbq)
+		memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
+		       &rspiocbq->iocb, sizeof(IOCB_t));
+
+	job = dd_data->context_un.iocb.set_job;
+	cmdiocbq = dd_data->context_un.iocb.cmdiocbq;
+	rspiocbq = dd_data->context_un.iocb.rspiocbq;
+	rsp = &rspiocbq->iocb;
+	ndlp = dd_data->context_un.iocb.ndlp;
+
+	pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
+		     job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
+		     job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+
+	if (job->reply->result == -EAGAIN)
+		rc = -EAGAIN;
+	else if (rsp->ulpStatus == IOSTAT_SUCCESS)
+		job->reply->reply_payload_rcv_len =
+			rsp->un.elsreq64.bdl.bdeSize;
+	else if (rsp->ulpStatus == IOSTAT_LS_RJT) {
+		job->reply->reply_payload_rcv_len =
+			sizeof(struct fc_bsg_ctels_reply);
+		/* LS_RJT data returned in word 4 */
+		rjt_data = (uint8_t *)&rsp->un.ulpWord[4];
+		els_reply = &job->reply->reply_data.ctels_reply;
+		els_reply->status = FC_CTELS_STATUS_REJECT;
+		els_reply->rjt_data.action = rjt_data[3];
+		els_reply->rjt_data.reason_code = rjt_data[2];
+		els_reply->rjt_data.reason_explanation = rjt_data[1];
+		els_reply->rjt_data.vendor_unique = rjt_data[0];
+	} else
+		rc = -EIO;
+
+	pbuflist = (struct lpfc_dmabuf *) cmdiocbq->context3;
+	lpfc_mbuf_free(phba, pbuflist->virt, pbuflist->phys);
+	lpfc_sli_release_iocbq(phba, rspiocbq);
+	lpfc_sli_release_iocbq(phba, cmdiocbq);
+	lpfc_nlp_put(ndlp);
+	kfree(dd_data);
 	/* make error code available to userspace */
 	job->reply->result = rc;
+	job->dd_data = NULL;
 	/* complete the job back to userspace */
 	job->job_done(job);
-
-	return 0;
+	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+	return;
 }
 
 /**
  * lpfc_bsg_rport_els - send an ELS command from a bsg request
  * @job: fc_bsg_job to handle
- */
+ **/
 static int
 lpfc_bsg_rport_els(struct fc_bsg_job *job)
 {
@@ -236,7 +498,6 @@ lpfc_bsg_rport_els(struct fc_bsg_job *jo
 	struct lpfc_hba *phba = vport->phba;
 	struct lpfc_rport_data *rdata = job->rport->dd_data;
 	struct lpfc_nodelist *ndlp = rdata->pnode;
-
 	uint32_t elscmd;
 	uint32_t cmdsize;
 	uint32_t rspsize;
@@ -248,20 +509,30 @@ lpfc_bsg_rport_els(struct fc_bsg_job *jo
 	struct lpfc_dmabuf *prsp;
 	struct lpfc_dmabuf *pbuflist = NULL;
 	struct ulp_bde64 *bpl;
-	int iocb_status;
 	int request_nseg;
 	int reply_nseg;
 	struct scatterlist *sgel = NULL;
 	int numbde;
 	dma_addr_t busaddr;
+	struct bsg_job_data *dd_data;
+	uint32_t creg_val;
 	int rc = 0;
 
 	/* in case no data is transferred */
 	job->reply->reply_payload_rcv_len = 0;
 
+	/* allocate our bsg tracking structure */
+	dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
+	if (!dd_data) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2735 Failed allocation of dd_data\n");
+		rc = -ENOMEM;
+		goto no_dd_data;
+	}
+
 	if (!lpfc_nlp_get(ndlp)) {
 		rc = -ENODEV;
-		goto out;
+		goto free_dd_data;
 	}
 
 	elscmd = job->request->rqst_data.r_els.els_code;
@@ -271,24 +542,24 @@ lpfc_bsg_rport_els(struct fc_bsg_job *jo
 	if (!rspiocbq) {
 		lpfc_nlp_put(ndlp);
 		rc = -ENOMEM;
-		goto out;
+		goto free_dd_data;
 	}
 
 	rsp = &rspiocbq->iocb;
 	rpi = ndlp->nlp_rpi;
 
-	cmdiocbq = lpfc_prep_els_iocb(phba->pport, 1, cmdsize, 0, ndlp,
+	cmdiocbq = lpfc_prep_els_iocb(vport, 1, cmdsize, 0, ndlp,
 				      ndlp->nlp_DID, elscmd);
-
 	if (!cmdiocbq) {
-		lpfc_sli_release_iocbq(phba, rspiocbq);
-		return -EIO;
+		rc = -EIO;
+		goto free_rspiocbq;
 	}
 
-	job->dd_data = cmdiocbq;
+	/* prep els iocb set context1 to the ndlp, context2 to the command
+	 * dmabuf, context3 holds the data dmabuf
+	 */
 	pcmd = (struct lpfc_dmabuf *) cmdiocbq->context2;
 	prsp = (struct lpfc_dmabuf *) pcmd->list.next;
-
 	lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
 	kfree(pcmd);
 	lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
@@ -300,7 +571,6 @@ lpfc_bsg_rport_els(struct fc_bsg_job *jo
 
 	request_nseg = pci_map_sg(phba->pcidev, job->request_payload.sg_list,
 				  job->request_payload.sg_cnt, DMA_TO_DEVICE);
-
 	for_each_sg(job->request_payload.sg_list, sgel, request_nseg, numbde) {
 		busaddr = sg_dma_address(sgel);
 		bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
@@ -322,7 +592,6 @@ lpfc_bsg_rport_els(struct fc_bsg_job *jo
 		bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr));
 		bpl++;
 	}
-
 	cmdiocbq->iocb.un.elsreq64.bdl.bdeSize =
 		(request_nseg + reply_nseg) * sizeof(struct ulp_bde64);
 	cmdiocbq->iocb.ulpContext = rpi;
@@ -330,102 +599,62 @@ lpfc_bsg_rport_els(struct fc_bsg_job *jo
 	cmdiocbq->context1 = NULL;
 	cmdiocbq->context2 = NULL;
 
-	iocb_status = lpfc_sli_issue_iocb_wait(phba, LPFC_ELS_RING, cmdiocbq,
-					rspiocbq, (phba->fc_ratov * 2)
-					       + LPFC_DRVR_TIMEOUT);
+	cmdiocbq->iocb_cmpl = lpfc_bsg_rport_els_cmp;
+	cmdiocbq->context1 = dd_data;
+	cmdiocbq->context2 = rspiocbq;
+	dd_data->type = TYPE_IOCB;
+	dd_data->context_un.iocb.cmdiocbq = cmdiocbq;
+	dd_data->context_un.iocb.rspiocbq = rspiocbq;
+	dd_data->context_un.iocb.set_job = job;
+	dd_data->context_un.iocb.bmp = NULL;;
+	dd_data->context_un.iocb.ndlp = ndlp;
 
-	/* release the new ndlp once the iocb completes */
-	lpfc_nlp_put(ndlp);
-	if (iocb_status != IOCB_TIMEDOUT) {
-		pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
-			     job->request_payload.sg_cnt, DMA_TO_DEVICE);
-		pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
-			     job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+	if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+		creg_val = readl(phba->HCregaddr);
+		creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
+		writel(creg_val, phba->HCregaddr);
+		readl(phba->HCregaddr); /* flush */
 	}
+	rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0);
+	lpfc_nlp_put(ndlp);
+	if (rc == IOCB_SUCCESS)
+		return 0; /* done for now */
 
-	if (iocb_status == IOCB_SUCCESS) {
-		if (rsp->ulpStatus == IOSTAT_SUCCESS) {
-			job->reply->reply_payload_rcv_len =
-				rsp->un.elsreq64.bdl.bdeSize;
-			rc = 0;
-		} else if (rsp->ulpStatus == IOSTAT_LS_RJT) {
-			struct fc_bsg_ctels_reply *els_reply;
-			/* LS_RJT data returned in word 4 */
-			uint8_t *rjt_data = (uint8_t *)&rsp->un.ulpWord[4];
+	pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
+		     job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
+		     job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
 
-			els_reply = &job->reply->reply_data.ctels_reply;
-			job->reply->result = 0;
-			els_reply->status = FC_CTELS_STATUS_REJECT;
-			els_reply->rjt_data.action = rjt_data[0];
-			els_reply->rjt_data.reason_code = rjt_data[1];
-			els_reply->rjt_data.reason_explanation = rjt_data[2];
-			els_reply->rjt_data.vendor_unique = rjt_data[3];
-		} else
-			rc = -EIO;
-	} else
-		rc = -EIO;
+	lpfc_mbuf_free(phba, pbuflist->virt, pbuflist->phys);
 
-	if (iocb_status != IOCB_TIMEDOUT)
-		lpfc_els_free_iocb(phba, cmdiocbq);
+	lpfc_sli_release_iocbq(phba, cmdiocbq);
 
+free_rspiocbq:
 	lpfc_sli_release_iocbq(phba, rspiocbq);
 
-out:
+free_dd_data:
+	kfree(dd_data);
+
+no_dd_data:
 	/* make error code available to userspace */
 	job->reply->result = rc;
-	/* complete the job back to userspace */
-	job->job_done(job);
-
-	return 0;
-}
-
-struct lpfc_ct_event {
-	struct list_head node;
-	int ref;
-	wait_queue_head_t wq;
-
-	/* Event type and waiter identifiers */
-	uint32_t type_mask;
-	uint32_t req_id;
-	uint32_t reg_id;
-
-	/* next two flags are here for the auto-delete logic */
-	unsigned long wait_time_stamp;
-	int waiting;
-
-	/* seen and not seen events */
-	struct list_head events_to_get;
-	struct list_head events_to_see;
-};
-
-struct event_data {
-	struct list_head node;
-	uint32_t type;
-	uint32_t immed_dat;
-	void *data;
-	uint32_t len;
-};
-
-static struct lpfc_ct_event *
-lpfc_ct_event_new(int ev_reg_id, uint32_t ev_req_id)
-{
-	struct lpfc_ct_event *evt = kzalloc(sizeof(*evt), GFP_KERNEL);
-	if (!evt)
-		return NULL;
-
-	INIT_LIST_HEAD(&evt->events_to_get);
-	INIT_LIST_HEAD(&evt->events_to_see);
-	evt->req_id = ev_req_id;
-	evt->reg_id = ev_reg_id;
-	evt->wait_time_stamp = jiffies;
-	init_waitqueue_head(&evt->wq);
-
-	return evt;
+	job->dd_data = NULL;
+	return rc;
 }
 
+/**
+ * lpfc_bsg_event_free - frees an allocated event structure
+ * @kref: Pointer to a kref.
+ *
+ * Called from kref_put. Back cast the kref into an event structure address.
+ * Free any events to get, delete associated nodes, free any events to see,
+ * free any data then free the event itself.
+ **/
 static void
-lpfc_ct_event_free(struct lpfc_ct_event *evt)
+lpfc_bsg_event_free(struct kref *kref)
 {
+	struct lpfc_bsg_event *evt = container_of(kref, struct lpfc_bsg_event,
+						  kref);
 	struct event_data *ed;
 
 	list_del(&evt->node);
@@ -447,25 +676,82 @@ lpfc_ct_event_free(struct lpfc_ct_event
 	kfree(evt);
 }
 
+/**
+ * lpfc_bsg_event_ref - increments the kref for an event
+ * @evt: Pointer to an event structure.
+ **/
 static inline void
-lpfc_ct_event_ref(struct lpfc_ct_event *evt)
+lpfc_bsg_event_ref(struct lpfc_bsg_event *evt)
 {
-	evt->ref++;
+	kref_get(&evt->kref);
 }
 
+/**
+ * lpfc_bsg_event_unref - Uses kref_put to free an event structure
+ * @evt: Pointer to an event structure.
+ **/
 static inline void
-lpfc_ct_event_unref(struct lpfc_ct_event *evt)
+lpfc_bsg_event_unref(struct lpfc_bsg_event *evt)
 {
-	if (--evt->ref < 0)
-		lpfc_ct_event_free(evt);
+	kref_put(&evt->kref, lpfc_bsg_event_free);
 }
 
-#define SLI_CT_ELX_LOOPBACK 0x10
+/**
+ * lpfc_bsg_event_new - allocate and initialize a event structure
+ * @ev_mask: Mask of events.
+ * @ev_reg_id: Event reg id.
+ * @ev_req_id: Event request id.
+ **/
+static struct lpfc_bsg_event *
+lpfc_bsg_event_new(uint32_t ev_mask, int ev_reg_id, uint32_t ev_req_id)
+{
+	struct lpfc_bsg_event *evt = kzalloc(sizeof(*evt), GFP_KERNEL);
 
-enum ELX_LOOPBACK_CMD {
-	ELX_LOOPBACK_XRI_SETUP,
-	ELX_LOOPBACK_DATA,
-};
+	if (!evt)
+		return NULL;
+
+	INIT_LIST_HEAD(&evt->events_to_get);
+	INIT_LIST_HEAD(&evt->events_to_see);
+	evt->type_mask = ev_mask;
+	evt->req_id = ev_req_id;
+	evt->reg_id = ev_reg_id;
+	evt->wait_time_stamp = jiffies;
+	init_waitqueue_head(&evt->wq);
+	kref_init(&evt->kref);
+	return evt;
+}
+
+/**
+ * diag_cmd_data_free - Frees an lpfc dma buffer extension
+ * @phba: Pointer to HBA context object.
+ * @mlist: Pointer to an lpfc dma buffer extension.
+ **/
+static int
+diag_cmd_data_free(struct lpfc_hba *phba, struct lpfc_dmabufext *mlist)
+{
+	struct lpfc_dmabufext *mlast;
+	struct pci_dev *pcidev;
+	struct list_head head, *curr, *next;
+
+	if ((!mlist) || (!lpfc_is_link_up(phba) &&
+		(phba->link_flag & LS_LOOPBACK_MODE))) {
+		return 0;
+	}
+
+	pcidev = phba->pcidev;
+	list_add_tail(&head, &mlist->dma.list);
+
+	list_for_each_safe(curr, next, &head) {
+		mlast = list_entry(curr, struct lpfc_dmabufext , dma.list);
+		if (mlast->dma.virt)
+			dma_free_coherent(&pcidev->dev,
+					  mlast->size,
+					  mlast->dma.virt,
+					  mlast->dma.phys);
+		kfree(mlast);
+	}
+	return 0;
+}
 
 /**
  * lpfc_bsg_ct_unsol_event - process an unsolicited CT command
@@ -474,9 +760,9 @@ enum ELX_LOOPBACK_CMD {
  * @piocbq:
  *
  * This function is called when an unsolicited CT command is received.  It
- * forwards the event to any processes registerd to receive CT events.
- */
-void
+ * forwards the event to any processes registered to receive CT events.
+ **/
+int
 lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 			struct lpfc_iocbq *piocbq)
 {
@@ -484,7 +770,7 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba
 	uint32_t cmd;
 	uint32_t len;
 	struct lpfc_dmabuf *dmabuf = NULL;
-	struct lpfc_ct_event *evt;
+	struct lpfc_bsg_event *evt;
 	struct event_data *evt_dat = NULL;
 	struct lpfc_iocbq *iocbq;
 	size_t offset = 0;
@@ -496,6 +782,9 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba
 	struct lpfc_dmabuf *bdeBuf2 = piocbq->context3;
 	struct lpfc_hbq_entry *hbqe;
 	struct lpfc_sli_ct_request *ct_req;
+	struct fc_bsg_job *job = NULL;
+	unsigned long flags;
+	int size = 0;
 
 	INIT_LIST_HEAD(&head);
 	list_add_tail(&head, &piocbq->list);
@@ -504,6 +793,10 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba
 	    piocbq->iocb.un.cont64[0].tus.f.bdeSize == 0)
 		goto error_ct_unsol_exit;
 
+	if (phba->link_state == LPFC_HBA_ERROR ||
+		(!(phba->sli.sli_flag & LPFC_SLI_ACTIVE)))
+		goto error_ct_unsol_exit;
+
 	if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)
 		dmabuf = bdeBuf1;
 	else {
@@ -511,7 +804,8 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba
 				    piocbq->iocb.un.cont64[0].addrLow);
 		dmabuf = lpfc_sli_ringpostbuf_get(phba, pring, dma_addr);
 	}
-
+	if (dmabuf == NULL)
+		goto error_ct_unsol_exit;
 	ct_req = (struct lpfc_sli_ct_request *)dmabuf->virt;
 	evt_req_id = ct_req->FsType;
 	cmd = ct_req->CommandResponse.bits.CmdRsp;
@@ -519,24 +813,24 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba
 	if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
 		lpfc_sli_ringpostbuf_put(phba, pring, dmabuf);
 
-	mutex_lock(&phba->ct_event_mutex);
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
 	list_for_each_entry(evt, &phba->ct_ev_waiters, node) {
-		if (evt->req_id != evt_req_id)
+		if (!(evt->type_mask & FC_REG_CT_EVENT) ||
+			evt->req_id != evt_req_id)
 			continue;
 
-		lpfc_ct_event_ref(evt);
-
+		lpfc_bsg_event_ref(evt);
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
 		evt_dat = kzalloc(sizeof(*evt_dat), GFP_KERNEL);
-		if (!evt_dat) {
-			lpfc_ct_event_unref(evt);
+		if (evt_dat == NULL) {
+			spin_lock_irqsave(&phba->ct_ev_lock, flags);
+			lpfc_bsg_event_unref(evt);
 			lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
 					"2614 Memory allocation failed for "
 					"CT event\n");
 			break;
 		}
 
-		mutex_unlock(&phba->ct_event_mutex);
-
 		if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
 			/* take accumulated byte count from the last iocbq */
 			iocbq = list_entry(head.prev, typeof(*iocbq), list);
@@ -550,25 +844,25 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba
 		}
 
 		evt_dat->data = kzalloc(evt_dat->len, GFP_KERNEL);
-		if (!evt_dat->data) {
+		if (evt_dat->data == NULL) {
 			lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
 					"2615 Memory allocation failed for "
 					"CT event data, size %d\n",
 					evt_dat->len);
 			kfree(evt_dat);
-			mutex_lock(&phba->ct_event_mutex);
-			lpfc_ct_event_unref(evt);
-			mutex_unlock(&phba->ct_event_mutex);
+			spin_lock_irqsave(&phba->ct_ev_lock, flags);
+			lpfc_bsg_event_unref(evt);
+			spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
 			goto error_ct_unsol_exit;
 		}
 
 		list_for_each_entry(iocbq, &head, list) {
+			size = 0;
 			if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
 				bdeBuf1 = iocbq->context2;
 				bdeBuf2 = iocbq->context3;
 			}
 			for (i = 0; i < iocbq->iocb.ulpBdeCount; i++) {
-				int size = 0;
 				if (phba->sli3_options &
 				    LPFC_SLI3_HBQ_ENABLED) {
 					if (i == 0) {
@@ -601,9 +895,11 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba
 						iocbq);
 					kfree(evt_dat->data);
 					kfree(evt_dat);
-					mutex_lock(&phba->ct_event_mutex);
-					lpfc_ct_event_unref(evt);
-					mutex_unlock(&phba->ct_event_mutex);
+					spin_lock_irqsave(&phba->ct_ev_lock,
+						flags);
+					lpfc_bsg_event_unref(evt);
+					spin_unlock_irqrestore(
+						&phba->ct_ev_lock, flags);
 					goto error_ct_unsol_exit;
 				}
 				memcpy((char *)(evt_dat->data) + offset,
@@ -616,15 +912,24 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba
 								 dmabuf);
 				} else {
 					switch (cmd) {
+					case ELX_LOOPBACK_DATA:
+						diag_cmd_data_free(phba,
+						(struct lpfc_dmabufext *)
+							dmabuf);
+						break;
 					case ELX_LOOPBACK_XRI_SETUP:
-						if (!(phba->sli3_options &
-						      LPFC_SLI3_HBQ_ENABLED))
+						if ((phba->sli_rev ==
+							LPFC_SLI_REV2) ||
+							(phba->sli3_options &
+							LPFC_SLI3_HBQ_ENABLED
+							)) {
+							lpfc_in_buf_free(phba,
+									dmabuf);
+						} else {
 							lpfc_post_buffer(phba,
 									 pring,
 									 1);
-						else
-							lpfc_in_buf_free(phba,
-									dmabuf);
+						}
 						break;
 					default:
 						if (!(phba->sli3_options &
@@ -638,7 +943,7 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba
 			}
 		}
 
-		mutex_lock(&phba->ct_event_mutex);
+		spin_lock_irqsave(&phba->ct_ev_lock, flags);
 		if (phba->sli_rev == LPFC_SLI_REV4) {
 			evt_dat->immed_dat = phba->ctx_idx;
 			phba->ctx_idx = (phba->ctx_idx + 1) % 64;
@@ -651,122 +956,144 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba
 
 		evt_dat->type = FC_REG_CT_EVENT;
 		list_add(&evt_dat->node, &evt->events_to_see);
-		wake_up_interruptible(&evt->wq);
-		lpfc_ct_event_unref(evt);
-		if (evt_req_id == SLI_CT_ELX_LOOPBACK)
+		if (evt_req_id == SLI_CT_ELX_LOOPBACK) {
+			wake_up_interruptible(&evt->wq);
+			lpfc_bsg_event_unref(evt);
 			break;
+		}
+
+		list_move(evt->events_to_see.prev, &evt->events_to_get);
+		lpfc_bsg_event_unref(evt);
+
+		job = evt->set_job;
+		evt->set_job = NULL;
+		if (job) {
+			job->reply->reply_payload_rcv_len = size;
+			/* make error code available to userspace */
+			job->reply->result = 0;
+			job->dd_data = NULL;
+			/* complete the job back to userspace */
+			spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+			job->job_done(job);
+			spin_lock_irqsave(&phba->ct_ev_lock, flags);
+		}
 	}
-	mutex_unlock(&phba->ct_event_mutex);
+	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
 
 error_ct_unsol_exit:
 	if (!list_empty(&head))
 		list_del(&head);
-
-	return;
+	if (evt_req_id == SLI_CT_ELX_LOOPBACK)
+		return 0;
+	return 1;
 }
 
 /**
- * lpfc_bsg_set_event - process a SET_EVENT bsg vendor command
+ * lpfc_bsg_hba_set_event - process a SET_EVENT bsg vendor command
  * @job: SET_EVENT fc_bsg_job
- */
+ **/
 static int
-lpfc_bsg_set_event(struct fc_bsg_job *job)
+lpfc_bsg_hba_set_event(struct fc_bsg_job *job)
 {
 	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
 	struct lpfc_hba *phba = vport->phba;
 	struct set_ct_event *event_req;
-	struct lpfc_ct_event *evt;
+	struct lpfc_bsg_event *evt;
 	int rc = 0;
+	struct bsg_job_data *dd_data = NULL;
+	uint32_t ev_mask;
+	unsigned long flags;
 
 	if (job->request_len <
 	    sizeof(struct fc_bsg_request) + sizeof(struct set_ct_event)) {
 		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
 				"2612 Received SET_CT_EVENT below minimum "
 				"size\n");
-		return -EINVAL;
+		rc = -EINVAL;
+		goto job_error;
+	}
+
+	dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
+	if (dd_data == NULL) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2734 Failed allocation of dd_data\n");
+		rc = -ENOMEM;
+		goto job_error;
 	}
 
 	event_req = (struct set_ct_event *)
 		job->request->rqst_data.h_vendor.vendor_cmd;
-
-	mutex_lock(&phba->ct_event_mutex);
+	ev_mask = ((uint32_t)(unsigned long)event_req->type_mask &
+				FC_REG_EVENT_MASK);
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
 	list_for_each_entry(evt, &phba->ct_ev_waiters, node) {
 		if (evt->reg_id == event_req->ev_reg_id) {
-			lpfc_ct_event_ref(evt);
+			lpfc_bsg_event_ref(evt);
 			evt->wait_time_stamp = jiffies;
 			break;
 		}
 	}
-	mutex_unlock(&phba->ct_event_mutex);
+	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
 
 	if (&evt->node == &phba->ct_ev_waiters) {
 		/* no event waiting struct yet - first call */
-		evt = lpfc_ct_event_new(event_req->ev_reg_id,
+		evt = lpfc_bsg_event_new(ev_mask, event_req->ev_reg_id,
 					event_req->ev_req_id);
 		if (!evt) {
 			lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
 					"2617 Failed allocation of event "
 					"waiter\n");
-			return -ENOMEM;
+			rc = -ENOMEM;
+			goto job_error;
 		}
 
-		mutex_lock(&phba->ct_event_mutex);
+		spin_lock_irqsave(&phba->ct_ev_lock, flags);
 		list_add(&evt->node, &phba->ct_ev_waiters);
-		lpfc_ct_event_ref(evt);
-		mutex_unlock(&phba->ct_event_mutex);
+		lpfc_bsg_event_ref(evt);
+		evt->wait_time_stamp = jiffies;
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
 	}
 
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
 	evt->waiting = 1;
-	if (wait_event_interruptible(evt->wq,
-				     !list_empty(&evt->events_to_see))) {
-		mutex_lock(&phba->ct_event_mutex);
-		lpfc_ct_event_unref(evt); /* release ref */
-		lpfc_ct_event_unref(evt); /* delete */
-		mutex_unlock(&phba->ct_event_mutex);
-		rc = -EINTR;
-		goto set_event_out;
-	}
-
-	evt->wait_time_stamp = jiffies;
-	evt->waiting = 0;
-
-	mutex_lock(&phba->ct_event_mutex);
-	list_move(evt->events_to_see.prev, &evt->events_to_get);
-	lpfc_ct_event_unref(evt); /* release ref */
-	mutex_unlock(&phba->ct_event_mutex);
+	dd_data->type = TYPE_EVT;
+	dd_data->context_un.evt = evt;
+	evt->set_job = job; /* for unsolicited command */
+	job->dd_data = dd_data; /* for fc transport timeout callback*/
+	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+	return 0; /* call job done later */
 
-set_event_out:
-	/* set_event carries no reply payload */
-	job->reply->reply_payload_rcv_len = 0;
-	/* make error code available to userspace */
-	job->reply->result = rc;
-	/* complete the job back to userspace */
-	job->job_done(job);
+job_error:
+	if (dd_data != NULL)
+		kfree(dd_data);
 
-	return 0;
+	job->dd_data = NULL;
+	return rc;
 }
 
 /**
- * lpfc_bsg_get_event - process a GET_EVENT bsg vendor command
+ * lpfc_bsg_hba_get_event - process a GET_EVENT bsg vendor command
  * @job: GET_EVENT fc_bsg_job
- */
+ **/
 static int
-lpfc_bsg_get_event(struct fc_bsg_job *job)
+lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
 {
 	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
 	struct lpfc_hba *phba = vport->phba;
 	struct get_ct_event *event_req;
 	struct get_ct_event_reply *event_reply;
-	struct lpfc_ct_event *evt;
+	struct lpfc_bsg_event *evt;
 	struct event_data *evt_dat = NULL;
-	int rc = 0;
+	unsigned long flags;
+	uint32_t rc = 0;
 
 	if (job->request_len <
 	    sizeof(struct fc_bsg_request) + sizeof(struct get_ct_event)) {
 		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
 				"2613 Received GET_CT_EVENT request below "
 				"minimum size\n");
-		return -EINVAL;
+		rc = -EINVAL;
+		goto job_error;
 	}
 
 	event_req = (struct get_ct_event *)
@@ -774,13 +1101,12 @@ lpfc_bsg_get_event(struct fc_bsg_job *jo
 
 	event_reply = (struct get_ct_event_reply *)
 		job->reply->reply_data.vendor_reply.vendor_rsp;
-
-	mutex_lock(&phba->ct_event_mutex);
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
 	list_for_each_entry(evt, &phba->ct_ev_waiters, node) {
 		if (evt->reg_id == event_req->ev_reg_id) {
 			if (list_empty(&evt->events_to_get))
 				break;
-			lpfc_ct_event_ref(evt);
+			lpfc_bsg_event_ref(evt);
 			evt->wait_time_stamp = jiffies;
 			evt_dat = list_entry(evt->events_to_get.prev,
 					     struct event_data, node);
@@ -788,84 +1114,1904 @@ lpfc_bsg_get_event(struct fc_bsg_job *jo
 			break;
 		}
 	}
-	mutex_unlock(&phba->ct_event_mutex);
+	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
 
-	if (!evt_dat) {
+	/* The app may continue to ask for event data until it gets
+	 * an error indicating that there isn't anymore
+	 */
+	if (evt_dat == NULL) {
 		job->reply->reply_payload_rcv_len = 0;
 		rc = -ENOENT;
-		goto error_get_event_exit;
+		goto job_error;
 	}
 
-	if (evt_dat->len > job->reply_payload.payload_len) {
-		evt_dat->len = job->reply_payload.payload_len;
-			lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
-					"2618 Truncated event data at %d "
-					"bytes\n",
-					job->reply_payload.payload_len);
+	if (evt_dat->len > job->request_payload.payload_len) {
+		evt_dat->len = job->request_payload.payload_len;
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2618 Truncated event data at %d "
+				"bytes\n",
+				job->request_payload.payload_len);
 	}
 
+	event_reply->type = evt_dat->type;
 	event_reply->immed_data = evt_dat->immed_dat;
-
 	if (evt_dat->len > 0)
 		job->reply->reply_payload_rcv_len =
-			sg_copy_from_buffer(job->reply_payload.sg_list,
-					    job->reply_payload.sg_cnt,
+			sg_copy_from_buffer(job->request_payload.sg_list,
+					    job->request_payload.sg_cnt,
 					    evt_dat->data, evt_dat->len);
 	else
 		job->reply->reply_payload_rcv_len = 0;
-	rc = 0;
 
-	if (evt_dat)
+	if (evt_dat) {
 		kfree(evt_dat->data);
-	kfree(evt_dat);
-	mutex_lock(&phba->ct_event_mutex);
-	lpfc_ct_event_unref(evt);
-	mutex_unlock(&phba->ct_event_mutex);
+		kfree(evt_dat);
+	}
 
-error_get_event_exit:
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
+	lpfc_bsg_event_unref(evt);
+	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+	job->dd_data = NULL;
+	job->reply->result = 0;
+	job->job_done(job);
+	return 0;
+
+job_error:
+	job->dd_data = NULL;
+	job->reply->result = rc;
+	return rc;
+}
+
+/**
+ * lpfc_issue_ct_rsp_cmp - lpfc_issue_ct_rsp's completion handler
+ * @phba: Pointer to HBA context object.
+ * @cmdiocbq: Pointer to command iocb.
+ * @rspiocbq: Pointer to response iocb.
+ *
+ * This function is the completion handler for iocbs issued using
+ * lpfc_issue_ct_rsp_cmp function. This function is called by the
+ * ring event handler function without any lock held. This function
+ * can be called from both worker thread context and interrupt
+ * context. This function also can be called from other thread which
+ * cleans up the SLI layer objects.
+ * This function copy the contents of the response iocb to the
+ * response iocb memory object provided by the caller of
+ * lpfc_sli_issue_iocb_wait and then wakes up the thread which
+ * sleeps for the iocb completion.
+ **/
+static void
+lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
+			struct lpfc_iocbq *cmdiocbq,
+			struct lpfc_iocbq *rspiocbq)
+{
+	struct bsg_job_data *dd_data;
+	struct fc_bsg_job *job;
+	IOCB_t *rsp;
+	struct lpfc_dmabuf *bmp;
+	struct lpfc_nodelist *ndlp;
+	unsigned long flags;
+	int rc = 0;
+
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
+	dd_data = cmdiocbq->context1;
+	/* normal completion and timeout crossed paths, already done */
+	if (!dd_data) {
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+		return;
+	}
+
+	job = dd_data->context_un.iocb.set_job;
+	bmp = dd_data->context_un.iocb.bmp;
+	rsp = &rspiocbq->iocb;
+	ndlp = dd_data->context_un.iocb.ndlp;
+
+	pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
+		     job->request_payload.sg_cnt, DMA_TO_DEVICE);
+
+	if (rsp->ulpStatus) {
+		if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
+			switch (rsp->un.ulpWord[4] & 0xff) {
+			case IOERR_SEQUENCE_TIMEOUT:
+				rc = -ETIMEDOUT;
+				break;
+			case IOERR_INVALID_RPI:
+				rc = -EFAULT;
+				break;
+			default:
+				rc = -EACCES;
+				break;
+			}
+		} else
+			rc = -EACCES;
+	} else
+		job->reply->reply_payload_rcv_len =
+			rsp->un.genreq64.bdl.bdeSize;
+
+	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
+	lpfc_sli_release_iocbq(phba, cmdiocbq);
+	lpfc_nlp_put(ndlp);
+	kfree(bmp);
+	kfree(dd_data);
 	/* make error code available to userspace */
 	job->reply->result = rc;
+	job->dd_data = NULL;
 	/* complete the job back to userspace */
 	job->job_done(job);
+	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+	return;
+}
+
+/**
+ * lpfc_issue_ct_rsp - issue a ct response
+ * @phba: Pointer to HBA context object.
+ * @job: Pointer to the job object.
+ * @tag: tag index value into the ports context exchange array.
+ * @bmp: Pointer to a dma buffer descriptor.
+ * @num_entry: Number of enties in the bde.
+ **/
+static int
+lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag,
+		  struct lpfc_dmabuf *bmp, int num_entry)
+{
+	IOCB_t *icmd;
+	struct lpfc_iocbq *ctiocb = NULL;
+	int rc = 0;
+	struct lpfc_nodelist *ndlp = NULL;
+	struct bsg_job_data *dd_data;
+	uint32_t creg_val;
+
+	/* allocate our bsg tracking structure */
+	dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
+	if (!dd_data) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2736 Failed allocation of dd_data\n");
+		rc = -ENOMEM;
+		goto no_dd_data;
+	}
+
+	/* Allocate buffer for  command iocb */
+	ctiocb = lpfc_sli_get_iocbq(phba);
+	if (!ctiocb) {
+		rc = ENOMEM;
+		goto no_ctiocb;
+	}
+
+	icmd = &ctiocb->iocb;
+	icmd->un.xseq64.bdl.ulpIoTag32 = 0;
+	icmd->un.xseq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
+	icmd->un.xseq64.bdl.addrLow = putPaddrLow(bmp->phys);
+	icmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
+	icmd->un.xseq64.bdl.bdeSize = (num_entry * sizeof(struct ulp_bde64));
+	icmd->un.xseq64.w5.hcsw.Fctl = (LS | LA);
+	icmd->un.xseq64.w5.hcsw.Dfctl = 0;
+	icmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_DD_SOL_CTL;
+	icmd->un.xseq64.w5.hcsw.Type = FC_TYPE_CT;
+
+	/* Fill in rest of iocb */
+	icmd->ulpCommand = CMD_XMIT_SEQUENCE64_CX;
+	icmd->ulpBdeCount = 1;
+	icmd->ulpLe = 1;
+	icmd->ulpClass = CLASS3;
+	if (phba->sli_rev == LPFC_SLI_REV4) {
+		/* Do not issue unsol response if oxid not marked as valid */
+		if (!(phba->ct_ctx[tag].flags & UNSOL_VALID)) {
+			rc = IOCB_ERROR;
+			goto issue_ct_rsp_exit;
+		}
+		icmd->ulpContext = phba->ct_ctx[tag].oxid;
+		ndlp = lpfc_findnode_did(phba->pport, phba->ct_ctx[tag].SID);
+		if (!ndlp) {
+			lpfc_printf_log(phba, KERN_WARNING, LOG_ELS,
+				 "2721 ndlp null for oxid %x SID %x\n",
+					icmd->ulpContext,
+					phba->ct_ctx[tag].SID);
+			rc = IOCB_ERROR;
+			goto issue_ct_rsp_exit;
+		}
+		icmd->un.ulpWord[3] = ndlp->nlp_rpi;
+		/* The exchange is done, mark the entry as invalid */
+		phba->ct_ctx[tag].flags &= ~UNSOL_VALID;
+	} else
+		icmd->ulpContext = (ushort) tag;
+
+	icmd->ulpTimeout = phba->fc_ratov * 2;
+
+	/* Xmit CT response on exchange <xid> */
+	lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
+			"2722 Xmit CT response on exchange x%x Data: x%x x%x\n",
+			icmd->ulpContext, icmd->ulpIoTag, phba->link_state);
+
+	ctiocb->iocb_cmpl = NULL;
+	ctiocb->iocb_flag |= LPFC_IO_LIBDFC;
+	ctiocb->vport = phba->pport;
+	ctiocb->context3 = bmp;
+
+	ctiocb->iocb_cmpl = lpfc_issue_ct_rsp_cmp;
+	ctiocb->context1 = dd_data;
+	ctiocb->context2 = NULL;
+	dd_data->type = TYPE_IOCB;
+	dd_data->context_un.iocb.cmdiocbq = ctiocb;
+	dd_data->context_un.iocb.rspiocbq = NULL;
+	dd_data->context_un.iocb.set_job = job;
+	dd_data->context_un.iocb.bmp = bmp;
+	dd_data->context_un.iocb.ndlp = ndlp;
+
+	if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+		creg_val = readl(phba->HCregaddr);
+		creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
+		writel(creg_val, phba->HCregaddr);
+		readl(phba->HCregaddr); /* flush */
+	}
+
+	rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, ctiocb, 0);
+
+	if (rc == IOCB_SUCCESS)
+		return 0; /* done for now */
+
+issue_ct_rsp_exit:
+	lpfc_sli_release_iocbq(phba, ctiocb);
+no_ctiocb:
+	kfree(dd_data);
+no_dd_data:
+	return rc;
+}
+
+/**
+ * lpfc_bsg_send_mgmt_rsp - process a SEND_MGMT_RESP bsg vendor command
+ * @job: SEND_MGMT_RESP fc_bsg_job
+ **/
+static int
+lpfc_bsg_send_mgmt_rsp(struct fc_bsg_job *job)
+{
+	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	struct send_mgmt_resp *mgmt_resp = (struct send_mgmt_resp *)
+		job->request->rqst_data.h_vendor.vendor_cmd;
+	struct ulp_bde64 *bpl;
+	struct lpfc_dmabuf *bmp = NULL;
+	struct scatterlist *sgel = NULL;
+	int request_nseg;
+	int numbde;
+	dma_addr_t busaddr;
+	uint32_t tag = mgmt_resp->tag;
+	unsigned long reqbfrcnt =
+			(unsigned long)job->request_payload.payload_len;
+	int rc = 0;
+
+	/* in case no data is transferred */
+	job->reply->reply_payload_rcv_len = 0;
+
+	if (!reqbfrcnt || (reqbfrcnt > (80 * BUF_SZ_4K))) {
+		rc = -ERANGE;
+		goto send_mgmt_rsp_exit;
+	}
+
+	bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+	if (!bmp) {
+		rc = -ENOMEM;
+		goto send_mgmt_rsp_exit;
+	}
+
+	bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys);
+	if (!bmp->virt) {
+		rc = -ENOMEM;
+		goto send_mgmt_rsp_free_bmp;
+	}
+
+	INIT_LIST_HEAD(&bmp->list);
+	bpl = (struct ulp_bde64 *) bmp->virt;
+	request_nseg = pci_map_sg(phba->pcidev, job->request_payload.sg_list,
+				  job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	for_each_sg(job->request_payload.sg_list, sgel, request_nseg, numbde) {
+		busaddr = sg_dma_address(sgel);
+		bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+		bpl->tus.f.bdeSize = sg_dma_len(sgel);
+		bpl->tus.w = cpu_to_le32(bpl->tus.w);
+		bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr));
+		bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr));
+		bpl++;
+	}
+
+	rc = lpfc_issue_ct_rsp(phba, job, tag, bmp, request_nseg);
+
+	if (rc == IOCB_SUCCESS)
+		return 0; /* done for now */
+
+	/* TBD need to handle a timeout */
+	pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
+			  job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	rc = -EACCES;
+	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
+
+send_mgmt_rsp_free_bmp:
+	kfree(bmp);
+send_mgmt_rsp_exit:
+	/* make error code available to userspace */
+	job->reply->result = rc;
+	job->dd_data = NULL;
+	return rc;
+}
+
+/**
+ * lpfc_bsg_diag_mode - process a LPFC_BSG_VENDOR_DIAG_MODE bsg vendor command
+ * @job: LPFC_BSG_VENDOR_DIAG_MODE
+ *
+ * This function is responsible for placing a port into diagnostic loopback
+ * mode in order to perform a diagnostic loopback test.
+ * All new scsi requests are blocked, a small delay is used to allow the
+ * scsi requests to complete then the link is brought down. If the link is
+ * is placed in loopback mode then scsi requests are again allowed
+ * so the scsi mid-layer doesn't give up on the port.
+ * All of this is done in-line.
+ */
+static int
+lpfc_bsg_diag_mode(struct fc_bsg_job *job)
+{
+	struct Scsi_Host *shost = job->shost;
+	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	struct diag_mode_set *loopback_mode;
+	struct lpfc_sli *psli = &phba->sli;
+	struct lpfc_sli_ring *pring = &psli->ring[LPFC_FCP_RING];
+	uint32_t link_flags;
+	uint32_t timeout;
+	struct lpfc_vport **vports;
+	LPFC_MBOXQ_t *pmboxq;
+	int mbxstatus;
+	int i = 0;
+	int rc = 0;
+
+	/* no data to return just the return code */
+	job->reply->reply_payload_rcv_len = 0;
+
+	if (job->request_len <
+	    sizeof(struct fc_bsg_request) + sizeof(struct diag_mode_set)) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2738 Received DIAG MODE request below minimum "
+				"size\n");
+		rc = -EINVAL;
+		goto job_error;
+	}
+
+	loopback_mode = (struct diag_mode_set *)
+		job->request->rqst_data.h_vendor.vendor_cmd;
+	link_flags = loopback_mode->type;
+	timeout = loopback_mode->timeout;
+
+	if ((phba->link_state == LPFC_HBA_ERROR) ||
+	    (psli->sli_flag & LPFC_BLOCK_MGMT_IO) ||
+	    (!(psli->sli_flag & LPFC_SLI_ACTIVE))) {
+		rc = -EACCES;
+		goto job_error;
+	}
+
+	pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!pmboxq) {
+		rc = -ENOMEM;
+		goto job_error;
+	}
+
+	vports = lpfc_create_vport_work_array(phba);
+	if (vports) {
+		for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
+			shost = lpfc_shost_from_vport(vports[i]);
+			scsi_block_requests(shost);
+		}
+
+		lpfc_destroy_vport_work_array(phba, vports);
+	} else {
+		shost = lpfc_shost_from_vport(phba->pport);
+		scsi_block_requests(shost);
+	}
+
+	while (pring->txcmplq_cnt) {
+		if (i++ > 500)	/* wait up to 5 seconds */
+			break;
+
+		msleep(10);
+	}
+
+	memset((void *)pmboxq, 0, sizeof(LPFC_MBOXQ_t));
+	pmboxq->u.mb.mbxCommand = MBX_DOWN_LINK;
+	pmboxq->u.mb.mbxOwner = OWN_HOST;
+
+	mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO);
+
+	if ((mbxstatus == MBX_SUCCESS) && (pmboxq->u.mb.mbxStatus == 0)) {
+		/* wait for link down before proceeding */
+		i = 0;
+		while (phba->link_state != LPFC_LINK_DOWN) {
+			if (i++ > timeout) {
+				rc = -ETIMEDOUT;
+				goto loopback_mode_exit;
+			}
+
+			msleep(10);
+		}
+
+		memset((void *)pmboxq, 0, sizeof(LPFC_MBOXQ_t));
+		if (link_flags == INTERNAL_LOOP_BACK)
+			pmboxq->u.mb.un.varInitLnk.link_flags = FLAGS_LOCAL_LB;
+		else
+			pmboxq->u.mb.un.varInitLnk.link_flags =
+				FLAGS_TOPOLOGY_MODE_LOOP;
+
+		pmboxq->u.mb.mbxCommand = MBX_INIT_LINK;
+		pmboxq->u.mb.mbxOwner = OWN_HOST;
+
+		mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq,
+						     LPFC_MBOX_TMO);
+
+		if ((mbxstatus != MBX_SUCCESS) || (pmboxq->u.mb.mbxStatus))
+			rc = -ENODEV;
+		else {
+			phba->link_flag |= LS_LOOPBACK_MODE;
+			/* wait for the link attention interrupt */
+			msleep(100);
+
+			i = 0;
+			while (phba->link_state != LPFC_HBA_READY) {
+				if (i++ > timeout) {
+					rc = -ETIMEDOUT;
+					break;
+				}
+
+				msleep(10);
+			}
+		}
+
+	} else
+		rc = -ENODEV;
+
+loopback_mode_exit:
+	vports = lpfc_create_vport_work_array(phba);
+	if (vports) {
+		for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
+			shost = lpfc_shost_from_vport(vports[i]);
+			scsi_unblock_requests(shost);
+		}
+		lpfc_destroy_vport_work_array(phba, vports);
+	} else {
+		shost = lpfc_shost_from_vport(phba->pport);
+		scsi_unblock_requests(shost);
+	}
+
+	/*
+	 * Let SLI layer release mboxq if mbox command completed after timeout.
+	 */
+	if (mbxstatus != MBX_TIMEOUT)
+		mempool_free(pmboxq, phba->mbox_mem_pool);
+
+job_error:
+	/* make error code available to userspace */
+	job->reply->result = rc;
+	/* complete the job back to userspace if no error */
+	if (rc == 0)
+		job->job_done(job);
+	return rc;
+}
+
+/**
+ * lpfcdiag_loop_self_reg - obtains a remote port login id
+ * @phba: Pointer to HBA context object
+ * @rpi: Pointer to a remote port login id
+ *
+ * This function obtains a remote port login id so the diag loopback test
+ * can send and receive its own unsolicited CT command.
+ **/
+static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t * rpi)
+{
+	LPFC_MBOXQ_t *mbox;
+	struct lpfc_dmabuf *dmabuff;
+	int status;
+
+	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!mbox)
+		return ENOMEM;
+
+	status = lpfc_reg_rpi(phba, 0, phba->pport->fc_myDID,
+				(uint8_t *)&phba->pport->fc_sparam, mbox, 0);
+	if (status) {
+		mempool_free(mbox, phba->mbox_mem_pool);
+		return ENOMEM;
+	}
+
+	dmabuff = (struct lpfc_dmabuf *) mbox->context1;
+	mbox->context1 = NULL;
+	status = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO);
+
+	if ((status != MBX_SUCCESS) || (mbox->u.mb.mbxStatus)) {
+		lpfc_mbuf_free(phba, dmabuff->virt, dmabuff->phys);
+		kfree(dmabuff);
+		if (status != MBX_TIMEOUT)
+			mempool_free(mbox, phba->mbox_mem_pool);
+		return ENODEV;
+	}
+
+	*rpi = mbox->u.mb.un.varWords[0];
+
+	lpfc_mbuf_free(phba, dmabuff->virt, dmabuff->phys);
+	kfree(dmabuff);
+	mempool_free(mbox, phba->mbox_mem_pool);
+	return 0;
+}
+
+/**
+ * lpfcdiag_loop_self_unreg - unregs from the rpi
+ * @phba: Pointer to HBA context object
+ * @rpi: Remote port login id
+ *
+ * This function unregisters the rpi obtained in lpfcdiag_loop_self_reg
+ **/
+static int lpfcdiag_loop_self_unreg(struct lpfc_hba *phba, uint16_t rpi)
+{
+	LPFC_MBOXQ_t *mbox;
+	int status;
+
+	/* Allocate mboxq structure */
+	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (mbox == NULL)
+		return ENOMEM;
+
+	lpfc_unreg_login(phba, 0, rpi, mbox);
+	status = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO);
+
+	if ((status != MBX_SUCCESS) || (mbox->u.mb.mbxStatus)) {
+		if (status != MBX_TIMEOUT)
+			mempool_free(mbox, phba->mbox_mem_pool);
+		return EIO;
+	}
+
+	mempool_free(mbox, phba->mbox_mem_pool);
+	return 0;
+}
+
+/**
+ * lpfcdiag_loop_get_xri - obtains the transmit and receive ids
+ * @phba: Pointer to HBA context object
+ * @rpi: Remote port login id
+ * @txxri: Pointer to transmit exchange id
+ * @rxxri: Pointer to response exchabge id
+ *
+ * This function obtains the transmit and receive ids required to send
+ * an unsolicited ct command with a payload. A special lpfc FsType and CmdRsp
+ * flags are used to the unsolicted response handler is able to process
+ * the ct command sent on the same port.
+ **/
+static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi,
+			 uint16_t *txxri, uint16_t * rxxri)
+{
+	struct lpfc_bsg_event *evt;
+	struct lpfc_iocbq *cmdiocbq, *rspiocbq;
+	IOCB_t *cmd, *rsp;
+	struct lpfc_dmabuf *dmabuf;
+	struct ulp_bde64 *bpl = NULL;
+	struct lpfc_sli_ct_request *ctreq = NULL;
+	int ret_val = 0;
+	unsigned long flags;
+
+	*txxri = 0;
+	*rxxri = 0;
+	evt = lpfc_bsg_event_new(FC_REG_CT_EVENT, current->pid,
+				SLI_CT_ELX_LOOPBACK);
+	if (!evt)
+		return ENOMEM;
+
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
+	list_add(&evt->node, &phba->ct_ev_waiters);
+	lpfc_bsg_event_ref(evt);
+	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+
+	cmdiocbq = lpfc_sli_get_iocbq(phba);
+	rspiocbq = lpfc_sli_get_iocbq(phba);
+
+	dmabuf = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+	if (dmabuf) {
+		dmabuf->virt = lpfc_mbuf_alloc(phba, 0, &dmabuf->phys);
+		INIT_LIST_HEAD(&dmabuf->list);
+		bpl = (struct ulp_bde64 *) dmabuf->virt;
+		memset(bpl, 0, sizeof(*bpl));
+		ctreq = (struct lpfc_sli_ct_request *)(bpl + 1);
+		bpl->addrHigh =
+			le32_to_cpu(putPaddrHigh(dmabuf->phys + sizeof(*bpl)));
+		bpl->addrLow =
+			le32_to_cpu(putPaddrLow(dmabuf->phys + sizeof(*bpl)));
+		bpl->tus.f.bdeFlags = 0;
+		bpl->tus.f.bdeSize = ELX_LOOPBACK_HEADER_SZ;
+		bpl->tus.w = le32_to_cpu(bpl->tus.w);
+	}
+
+	if (cmdiocbq == NULL || rspiocbq == NULL ||
+	    dmabuf == NULL || bpl == NULL || ctreq == NULL) {
+		ret_val = ENOMEM;
+		goto err_get_xri_exit;
+	}
+
+	cmd = &cmdiocbq->iocb;
+	rsp = &rspiocbq->iocb;
+
+	memset(ctreq, 0, ELX_LOOPBACK_HEADER_SZ);
+
+	ctreq->RevisionId.bits.Revision = SLI_CT_REVISION;
+	ctreq->RevisionId.bits.InId = 0;
+	ctreq->FsType = SLI_CT_ELX_LOOPBACK;
+	ctreq->FsSubType = 0;
+	ctreq->CommandResponse.bits.CmdRsp = ELX_LOOPBACK_XRI_SETUP;
+	ctreq->CommandResponse.bits.Size = 0;
+
+
+	cmd->un.xseq64.bdl.addrHigh = putPaddrHigh(dmabuf->phys);
+	cmd->un.xseq64.bdl.addrLow = putPaddrLow(dmabuf->phys);
+	cmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
+	cmd->un.xseq64.bdl.bdeSize = sizeof(*bpl);
+
+	cmd->un.xseq64.w5.hcsw.Fctl = LA;
+	cmd->un.xseq64.w5.hcsw.Dfctl = 0;
+	cmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
+	cmd->un.xseq64.w5.hcsw.Type = FC_TYPE_CT;
+
+	cmd->ulpCommand = CMD_XMIT_SEQUENCE64_CR;
+	cmd->ulpBdeCount = 1;
+	cmd->ulpLe = 1;
+	cmd->ulpClass = CLASS3;
+	cmd->ulpContext = rpi;
+
+	cmdiocbq->iocb_flag |= LPFC_IO_LIBDFC;
+	cmdiocbq->vport = phba->pport;
+
+	ret_val = lpfc_sli_issue_iocb_wait(phba, LPFC_ELS_RING, cmdiocbq,
+				rspiocbq,
+				(phba->fc_ratov * 2)
+				+ LPFC_DRVR_TIMEOUT);
+	if (ret_val)
+		goto err_get_xri_exit;
+
+	*txxri =  rsp->ulpContext;
+
+	evt->waiting = 1;
+	evt->wait_time_stamp = jiffies;
+	ret_val = wait_event_interruptible_timeout(
+		evt->wq, !list_empty(&evt->events_to_see),
+		((phba->fc_ratov * 2) + LPFC_DRVR_TIMEOUT) * HZ);
+	if (list_empty(&evt->events_to_see))
+		ret_val = (ret_val) ? EINTR : ETIMEDOUT;
+	else {
+		ret_val = IOCB_SUCCESS;
+		spin_lock_irqsave(&phba->ct_ev_lock, flags);
+		list_move(evt->events_to_see.prev, &evt->events_to_get);
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+		*rxxri = (list_entry(evt->events_to_get.prev,
+				     typeof(struct event_data),
+				     node))->immed_dat;
+	}
+	evt->waiting = 0;
+
+err_get_xri_exit:
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
+	lpfc_bsg_event_unref(evt); /* release ref */
+	lpfc_bsg_event_unref(evt); /* delete */
+	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+
+	if (dmabuf) {
+		if (dmabuf->virt)
+			lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys);
+		kfree(dmabuf);
+	}
+
+	if (cmdiocbq && (ret_val != IOCB_TIMEDOUT))
+		lpfc_sli_release_iocbq(phba, cmdiocbq);
+	if (rspiocbq)
+		lpfc_sli_release_iocbq(phba, rspiocbq);
+	return ret_val;
+}
+
+/**
+ * diag_cmd_data_alloc - fills in a bde struct with dma buffers
+ * @phba: Pointer to HBA context object
+ * @bpl: Pointer to 64 bit bde structure
+ * @size: Number of bytes to process
+ * @nocopydata: Flag to copy user data into the allocated buffer
+ *
+ * This function allocates page size buffers and populates an lpfc_dmabufext.
+ * If allowed the user data pointed to with indataptr is copied into the kernel
+ * memory. The chained list of page size buffers is returned.
+ **/
+static struct lpfc_dmabufext *
+diag_cmd_data_alloc(struct lpfc_hba *phba,
+		   struct ulp_bde64 *bpl, uint32_t size,
+		   int nocopydata)
+{
+	struct lpfc_dmabufext *mlist = NULL;
+	struct lpfc_dmabufext *dmp;
+	int cnt, offset = 0, i = 0;
+	struct pci_dev *pcidev;
+
+	pcidev = phba->pcidev;
+
+	while (size) {
+		/* We get chunks of 4K */
+		if (size > BUF_SZ_4K)
+			cnt = BUF_SZ_4K;
+		else
+			cnt = size;
+
+		/* allocate struct lpfc_dmabufext buffer header */
+		dmp = kmalloc(sizeof(struct lpfc_dmabufext), GFP_KERNEL);
+		if (!dmp)
+			goto out;
+
+		INIT_LIST_HEAD(&dmp->dma.list);
+
+		/* Queue it to a linked list */
+		if (mlist)
+			list_add_tail(&dmp->dma.list, &mlist->dma.list);
+		else
+			mlist = dmp;
+
+		/* allocate buffer */
+		dmp->dma.virt = dma_alloc_coherent(&pcidev->dev,
+						   cnt,
+						   &(dmp->dma.phys),
+						   GFP_KERNEL);
+
+		if (!dmp->dma.virt)
+			goto out;
+
+		dmp->size = cnt;
+
+		if (nocopydata) {
+			bpl->tus.f.bdeFlags = 0;
+			pci_dma_sync_single_for_device(phba->pcidev,
+				dmp->dma.phys, LPFC_BPL_SIZE, PCI_DMA_TODEVICE);
+
+		} else {
+			memset((uint8_t *)dmp->dma.virt, 0, cnt);
+			bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;
+		}
+
+		/* build buffer ptr list for IOCB */
+		bpl->addrLow = le32_to_cpu(putPaddrLow(dmp->dma.phys));
+		bpl->addrHigh = le32_to_cpu(putPaddrHigh(dmp->dma.phys));
+		bpl->tus.f.bdeSize = (ushort) cnt;
+		bpl->tus.w = le32_to_cpu(bpl->tus.w);
+		bpl++;
+
+		i++;
+		offset += cnt;
+		size -= cnt;
+	}
+
+	mlist->flag = i;
+	return mlist;
+out:
+	diag_cmd_data_free(phba, mlist);
+	return NULL;
+}
+
+/**
+ * lpfcdiag_loop_post_rxbufs - post the receive buffers for an unsol CT cmd
+ * @phba: Pointer to HBA context object
+ * @rxxri: Receive exchange id
+ * @len: Number of data bytes
+ *
+ * This function allocates and posts a data buffer of sufficient size to recieve
+ * an unsolicted CT command.
+ **/
+static int lpfcdiag_loop_post_rxbufs(struct lpfc_hba *phba, uint16_t rxxri,
+			     size_t len)
+{
+	struct lpfc_sli *psli = &phba->sli;
+	struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
+	struct lpfc_iocbq *cmdiocbq;
+	IOCB_t *cmd = NULL;
+	struct list_head head, *curr, *next;
+	struct lpfc_dmabuf *rxbmp;
+	struct lpfc_dmabuf *dmp;
+	struct lpfc_dmabuf *mp[2] = {NULL, NULL};
+	struct ulp_bde64 *rxbpl = NULL;
+	uint32_t num_bde;
+	struct lpfc_dmabufext *rxbuffer = NULL;
+	int ret_val = 0;
+	int i = 0;
+
+	cmdiocbq = lpfc_sli_get_iocbq(phba);
+	rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+	if (rxbmp != NULL) {
+		rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys);
+		INIT_LIST_HEAD(&rxbmp->list);
+		rxbpl = (struct ulp_bde64 *) rxbmp->virt;
+		rxbuffer = diag_cmd_data_alloc(phba, rxbpl, len, 0);
+	}
+
+	if (!cmdiocbq || !rxbmp || !rxbpl || !rxbuffer) {
+		ret_val = ENOMEM;
+		goto err_post_rxbufs_exit;
+	}
+
+	/* Queue buffers for the receive exchange */
+	num_bde = (uint32_t)rxbuffer->flag;
+	dmp = &rxbuffer->dma;
+
+	cmd = &cmdiocbq->iocb;
+	i = 0;
+
+	INIT_LIST_HEAD(&head);
+	list_add_tail(&head, &dmp->list);
+	list_for_each_safe(curr, next, &head) {
+		mp[i] = list_entry(curr, struct lpfc_dmabuf, list);
+		list_del(curr);
+
+		if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
+			mp[i]->buffer_tag = lpfc_sli_get_buffer_tag(phba);
+			cmd->un.quexri64cx.buff.bde.addrHigh =
+				putPaddrHigh(mp[i]->phys);
+			cmd->un.quexri64cx.buff.bde.addrLow =
+				putPaddrLow(mp[i]->phys);
+			cmd->un.quexri64cx.buff.bde.tus.f.bdeSize =
+				((struct lpfc_dmabufext *)mp[i])->size;
+			cmd->un.quexri64cx.buff.buffer_tag = mp[i]->buffer_tag;
+			cmd->ulpCommand = CMD_QUE_XRI64_CX;
+			cmd->ulpPU = 0;
+			cmd->ulpLe = 1;
+			cmd->ulpBdeCount = 1;
+			cmd->unsli3.que_xri64cx_ext_words.ebde_count = 0;
+
+		} else {
+			cmd->un.cont64[i].addrHigh = putPaddrHigh(mp[i]->phys);
+			cmd->un.cont64[i].addrLow = putPaddrLow(mp[i]->phys);
+			cmd->un.cont64[i].tus.f.bdeSize =
+				((struct lpfc_dmabufext *)mp[i])->size;
+					cmd->ulpBdeCount = ++i;
+
+			if ((--num_bde > 0) && (i < 2))
+				continue;
+
+			cmd->ulpCommand = CMD_QUE_XRI_BUF64_CX;
+			cmd->ulpLe = 1;
+		}
+
+		cmd->ulpClass = CLASS3;
+		cmd->ulpContext = rxxri;
+
+		ret_val = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0);
+
+		if (ret_val == IOCB_ERROR) {
+			diag_cmd_data_free(phba,
+				(struct lpfc_dmabufext *)mp[0]);
+			if (mp[1])
+				diag_cmd_data_free(phba,
+					  (struct lpfc_dmabufext *)mp[1]);
+			dmp = list_entry(next, struct lpfc_dmabuf, list);
+			ret_val = EIO;
+			goto err_post_rxbufs_exit;
+		}
+
+		lpfc_sli_ringpostbuf_put(phba, pring, mp[0]);
+		if (mp[1]) {
+			lpfc_sli_ringpostbuf_put(phba, pring, mp[1]);
+			mp[1] = NULL;
+		}
+
+		/* The iocb was freed by lpfc_sli_issue_iocb */
+		cmdiocbq = lpfc_sli_get_iocbq(phba);
+		if (!cmdiocbq) {
+			dmp = list_entry(next, struct lpfc_dmabuf, list);
+			ret_val = EIO;
+			goto err_post_rxbufs_exit;
+		}
+
+		cmd = &cmdiocbq->iocb;
+		i = 0;
+	}
+	list_del(&head);
+
+err_post_rxbufs_exit:
+
+	if (rxbmp) {
+		if (rxbmp->virt)
+			lpfc_mbuf_free(phba, rxbmp->virt, rxbmp->phys);
+		kfree(rxbmp);
+	}
+
+	if (cmdiocbq)
+		lpfc_sli_release_iocbq(phba, cmdiocbq);
+	return ret_val;
+}
+
+/**
+ * lpfc_bsg_diag_test - with a port in loopback issues a Ct cmd to itself
+ * @job: LPFC_BSG_VENDOR_DIAG_TEST fc_bsg_job
+ *
+ * This function receives a user data buffer to be transmitted and received on
+ * the same port, the link must be up and in loopback mode prior
+ * to being called.
+ * 1. A kernel buffer is allocated to copy the user data into.
+ * 2. The port registers with "itself".
+ * 3. The transmit and receive exchange ids are obtained.
+ * 4. The receive exchange id is posted.
+ * 5. A new els loopback event is created.
+ * 6. The command and response iocbs are allocated.
+ * 7. The cmd iocb FsType is set to elx loopback and the CmdRsp to looppback.
+ *
+ * This function is meant to be called n times while the port is in loopback
+ * so it is the apps responsibility to issue a reset to take the port out
+ * of loopback mode.
+ **/
+static int
+lpfc_bsg_diag_test(struct fc_bsg_job *job)
+{
+	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	struct diag_mode_test *diag_mode;
+	struct lpfc_bsg_event *evt;
+	struct event_data *evdat;
+	struct lpfc_sli *psli = &phba->sli;
+	uint32_t size;
+	uint32_t full_size;
+	size_t segment_len = 0, segment_offset = 0, current_offset = 0;
+	uint16_t rpi;
+	struct lpfc_iocbq *cmdiocbq, *rspiocbq;
+	IOCB_t *cmd, *rsp;
+	struct lpfc_sli_ct_request *ctreq;
+	struct lpfc_dmabuf *txbmp;
+	struct ulp_bde64 *txbpl = NULL;
+	struct lpfc_dmabufext *txbuffer = NULL;
+	struct list_head head;
+	struct lpfc_dmabuf  *curr;
+	uint16_t txxri, rxxri;
+	uint32_t num_bde;
+	uint8_t *ptr = NULL, *rx_databuf = NULL;
+	int rc = 0;
+	unsigned long flags;
+	void *dataout = NULL;
+	uint32_t total_mem;
+
+	/* in case no data is returned return just the return code */
+	job->reply->reply_payload_rcv_len = 0;
+
+	if (job->request_len <
+	    sizeof(struct fc_bsg_request) + sizeof(struct diag_mode_test)) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2739 Received DIAG TEST request below minimum "
+				"size\n");
+		rc = -EINVAL;
+		goto loopback_test_exit;
+	}
+
+	if (job->request_payload.payload_len !=
+		job->reply_payload.payload_len) {
+		rc = -EINVAL;
+		goto loopback_test_exit;
+	}
+
+	diag_mode = (struct diag_mode_test *)
+		job->request->rqst_data.h_vendor.vendor_cmd;
+
+	if ((phba->link_state == LPFC_HBA_ERROR) ||
+	    (psli->sli_flag & LPFC_BLOCK_MGMT_IO) ||
+	    (!(psli->sli_flag & LPFC_SLI_ACTIVE))) {
+		rc = -EACCES;
+		goto loopback_test_exit;
+	}
+
+	if (!lpfc_is_link_up(phba) || !(phba->link_flag & LS_LOOPBACK_MODE)) {
+		rc = -EACCES;
+		goto loopback_test_exit;
+	}
+
+	size = job->request_payload.payload_len;
+	full_size = size + ELX_LOOPBACK_HEADER_SZ; /* plus the header */
+
+	if ((size == 0) || (size > 80 * BUF_SZ_4K)) {
+		rc = -ERANGE;
+		goto loopback_test_exit;
+	}
+
+	if (size >= BUF_SZ_4K) {
+		/*
+		 * Allocate memory for ioctl data. If buffer is bigger than 64k,
+		 * then we allocate 64k and re-use that buffer over and over to
+		 * xfer the whole block. This is because Linux kernel has a
+		 * problem allocating more than 120k of kernel space memory. Saw
+		 * problem with GET_FCPTARGETMAPPING...
+		 */
+		if (size <= (64 * 1024))
+			total_mem = size;
+		else
+			total_mem = 64 * 1024;
+	} else
+		/* Allocate memory for ioctl data */
+		total_mem = BUF_SZ_4K;
+
+	dataout = kmalloc(total_mem, GFP_KERNEL);
+	if (dataout == NULL) {
+		rc = -ENOMEM;
+		goto loopback_test_exit;
+	}
+
+	ptr = dataout;
+	ptr += ELX_LOOPBACK_HEADER_SZ;
+	sg_copy_to_buffer(job->request_payload.sg_list,
+				job->request_payload.sg_cnt,
+				ptr, size);
+
+	rc = lpfcdiag_loop_self_reg(phba, &rpi);
+	if (rc) {
+		rc = -ENOMEM;
+		goto loopback_test_exit;
+	}
+
+	rc = lpfcdiag_loop_get_xri(phba, rpi, &txxri, &rxxri);
+	if (rc) {
+		lpfcdiag_loop_self_unreg(phba, rpi);
+		rc = -ENOMEM;
+		goto loopback_test_exit;
+	}
+
+	rc = lpfcdiag_loop_post_rxbufs(phba, rxxri, full_size);
+	if (rc) {
+		lpfcdiag_loop_self_unreg(phba, rpi);
+		rc = -ENOMEM;
+		goto loopback_test_exit;
+	}
+
+	evt = lpfc_bsg_event_new(FC_REG_CT_EVENT, current->pid,
+				SLI_CT_ELX_LOOPBACK);
+	if (!evt) {
+		lpfcdiag_loop_self_unreg(phba, rpi);
+		rc = -ENOMEM;
+		goto loopback_test_exit;
+	}
+
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
+	list_add(&evt->node, &phba->ct_ev_waiters);
+	lpfc_bsg_event_ref(evt);
+	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+
+	cmdiocbq = lpfc_sli_get_iocbq(phba);
+	rspiocbq = lpfc_sli_get_iocbq(phba);
+	txbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+
+	if (txbmp) {
+		txbmp->virt = lpfc_mbuf_alloc(phba, 0, &txbmp->phys);
+		INIT_LIST_HEAD(&txbmp->list);
+		txbpl = (struct ulp_bde64 *) txbmp->virt;
+		if (txbpl)
+			txbuffer = diag_cmd_data_alloc(phba,
+							txbpl, full_size, 0);
+	}
+
+	if (!cmdiocbq || !rspiocbq || !txbmp || !txbpl || !txbuffer) {
+		rc = -ENOMEM;
+		goto err_loopback_test_exit;
+	}
+
+	cmd = &cmdiocbq->iocb;
+	rsp = &rspiocbq->iocb;
+
+	INIT_LIST_HEAD(&head);
+	list_add_tail(&head, &txbuffer->dma.list);
+	list_for_each_entry(curr, &head, list) {
+		segment_len = ((struct lpfc_dmabufext *)curr)->size;
+		if (current_offset == 0) {
+			ctreq = curr->virt;
+			memset(ctreq, 0, ELX_LOOPBACK_HEADER_SZ);
+			ctreq->RevisionId.bits.Revision = SLI_CT_REVISION;
+			ctreq->RevisionId.bits.InId = 0;
+			ctreq->FsType = SLI_CT_ELX_LOOPBACK;
+			ctreq->FsSubType = 0;
+			ctreq->CommandResponse.bits.CmdRsp = ELX_LOOPBACK_DATA;
+			ctreq->CommandResponse.bits.Size   = size;
+			segment_offset = ELX_LOOPBACK_HEADER_SZ;
+		} else
+			segment_offset = 0;
+
+		BUG_ON(segment_offset >= segment_len);
+		memcpy(curr->virt + segment_offset,
+			ptr + current_offset,
+			segment_len - segment_offset);
+
+		current_offset += segment_len - segment_offset;
+		BUG_ON(current_offset > size);
+	}
+	list_del(&head);
+
+	/* Build the XMIT_SEQUENCE iocb */
+
+	num_bde = (uint32_t)txbuffer->flag;
+
+	cmd->un.xseq64.bdl.addrHigh = putPaddrHigh(txbmp->phys);
+	cmd->un.xseq64.bdl.addrLow = putPaddrLow(txbmp->phys);
+	cmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
+	cmd->un.xseq64.bdl.bdeSize = (num_bde * sizeof(struct ulp_bde64));
+
+	cmd->un.xseq64.w5.hcsw.Fctl = (LS | LA);
+	cmd->un.xseq64.w5.hcsw.Dfctl = 0;
+	cmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
+	cmd->un.xseq64.w5.hcsw.Type = FC_TYPE_CT;
+
+	cmd->ulpCommand = CMD_XMIT_SEQUENCE64_CX;
+	cmd->ulpBdeCount = 1;
+	cmd->ulpLe = 1;
+	cmd->ulpClass = CLASS3;
+	cmd->ulpContext = txxri;
+
+	cmdiocbq->iocb_flag |= LPFC_IO_LIBDFC;
+	cmdiocbq->vport = phba->pport;
+
+	rc = lpfc_sli_issue_iocb_wait(phba, LPFC_ELS_RING, cmdiocbq, rspiocbq,
+				      (phba->fc_ratov * 2) + LPFC_DRVR_TIMEOUT);
+
+	if ((rc != IOCB_SUCCESS) || (rsp->ulpStatus != IOCB_SUCCESS)) {
+		rc = -EIO;
+		goto err_loopback_test_exit;
+	}
+
+	evt->waiting = 1;
+	rc = wait_event_interruptible_timeout(
+		evt->wq, !list_empty(&evt->events_to_see),
+		((phba->fc_ratov * 2) + LPFC_DRVR_TIMEOUT) * HZ);
+	evt->waiting = 0;
+	if (list_empty(&evt->events_to_see))
+		rc = (rc) ? -EINTR : -ETIMEDOUT;
+	else {
+		spin_lock_irqsave(&phba->ct_ev_lock, flags);
+		list_move(evt->events_to_see.prev, &evt->events_to_get);
+		evdat = list_entry(evt->events_to_get.prev,
+				   typeof(*evdat), node);
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+		rx_databuf = evdat->data;
+		if (evdat->len != full_size) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+				"1603 Loopback test did not receive expected "
+				"data length. actual length 0x%x expected "
+				"length 0x%x\n",
+				evdat->len, full_size);
+			rc = -EIO;
+		} else if (rx_databuf == NULL)
+			rc = -EIO;
+		else {
+			rc = IOCB_SUCCESS;
+			/* skip over elx loopback header */
+			rx_databuf += ELX_LOOPBACK_HEADER_SZ;
+			job->reply->reply_payload_rcv_len =
+				sg_copy_from_buffer(job->reply_payload.sg_list,
+						    job->reply_payload.sg_cnt,
+						    rx_databuf, size);
+			job->reply->reply_payload_rcv_len = size;
+		}
+	}
+
+err_loopback_test_exit:
+	lpfcdiag_loop_self_unreg(phba, rpi);
+
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
+	lpfc_bsg_event_unref(evt); /* release ref */
+	lpfc_bsg_event_unref(evt); /* delete */
+	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+
+	if (cmdiocbq != NULL)
+		lpfc_sli_release_iocbq(phba, cmdiocbq);
+
+	if (rspiocbq != NULL)
+		lpfc_sli_release_iocbq(phba, rspiocbq);
+
+	if (txbmp != NULL) {
+		if (txbpl != NULL) {
+			if (txbuffer != NULL)
+				diag_cmd_data_free(phba, txbuffer);
+			lpfc_mbuf_free(phba, txbmp->virt, txbmp->phys);
+		}
+		kfree(txbmp);
+	}
+
+loopback_test_exit:
+	kfree(dataout);
+	/* make error code available to userspace */
+	job->reply->result = rc;
+	job->dd_data = NULL;
+	/* complete the job back to userspace if no error */
+	if (rc == 0)
+		job->job_done(job);
+	return rc;
+}
+
+/**
+ * lpfc_bsg_get_dfc_rev - process a GET_DFC_REV bsg vendor command
+ * @job: GET_DFC_REV fc_bsg_job
+ **/
+static int
+lpfc_bsg_get_dfc_rev(struct fc_bsg_job *job)
+{
+	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	struct get_mgmt_rev *event_req;
+	struct get_mgmt_rev_reply *event_reply;
+	int rc = 0;
+
+	if (job->request_len <
+	    sizeof(struct fc_bsg_request) + sizeof(struct get_mgmt_rev)) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2740 Received GET_DFC_REV request below "
+				"minimum size\n");
+		rc = -EINVAL;
+		goto job_error;
+	}
+
+	event_req = (struct get_mgmt_rev *)
+		job->request->rqst_data.h_vendor.vendor_cmd;
+
+	event_reply = (struct get_mgmt_rev_reply *)
+		job->reply->reply_data.vendor_reply.vendor_rsp;
+
+	if (job->reply_len <
+	    sizeof(struct fc_bsg_request) + sizeof(struct get_mgmt_rev_reply)) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2741 Received GET_DFC_REV reply below "
+				"minimum size\n");
+		rc = -EINVAL;
+		goto job_error;
+	}
+
+	event_reply->info.a_Major = MANAGEMENT_MAJOR_REV;
+	event_reply->info.a_Minor = MANAGEMENT_MINOR_REV;
+job_error:
+	job->reply->result = rc;
+	if (rc == 0)
+		job->job_done(job);
+	return rc;
+}
+
+/**
+ * lpfc_bsg_wake_mbox_wait - lpfc_bsg_issue_mbox mbox completion handler
+ * @phba: Pointer to HBA context object.
+ * @pmboxq: Pointer to mailbox command.
+ *
+ * This is completion handler function for mailbox commands issued from
+ * lpfc_bsg_issue_mbox function. This function is called by the
+ * mailbox event handler function with no lock held. This function
+ * will wake up thread waiting on the wait queue pointed by context1
+ * of the mailbox.
+ **/
+void
+lpfc_bsg_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
+{
+	struct bsg_job_data *dd_data;
+	MAILBOX_t *pmb;
+	MAILBOX_t *mb;
+	struct fc_bsg_job *job;
+	uint32_t size;
+	unsigned long flags;
+
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
+	dd_data = pmboxq->context1;
+	if (!dd_data) {
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+		return;
+	}
+
+	pmb = &dd_data->context_un.mbox.pmboxq->u.mb;
+	mb = dd_data->context_un.mbox.mb;
+	job = dd_data->context_un.mbox.set_job;
+	memcpy(mb, pmb, sizeof(*pmb));
+	size = job->request_payload.payload_len;
+	job->reply->reply_payload_rcv_len =
+		sg_copy_from_buffer(job->reply_payload.sg_list,
+				job->reply_payload.sg_cnt,
+				mb, size);
+	job->reply->result = 0;
+	dd_data->context_un.mbox.set_job = NULL;
+	job->dd_data = NULL;
+	job->job_done(job);
+	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+	mempool_free(dd_data->context_un.mbox.pmboxq, phba->mbox_mem_pool);
+	kfree(mb);
+	kfree(dd_data);
+	return;
+}
+
+/**
+ * lpfc_bsg_check_cmd_access - test for a supported mailbox command
+ * @phba: Pointer to HBA context object.
+ * @mb: Pointer to a mailbox object.
+ * @vport: Pointer to a vport object.
+ *
+ * Some commands require the port to be offline, some may not be called from
+ * the application.
+ **/
+static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba,
+	MAILBOX_t *mb, struct lpfc_vport *vport)
+{
+	/* return negative error values for bsg job */
+	switch (mb->mbxCommand) {
+	/* Offline only */
+	case MBX_INIT_LINK:
+	case MBX_DOWN_LINK:
+	case MBX_CONFIG_LINK:
+	case MBX_CONFIG_RING:
+	case MBX_RESET_RING:
+	case MBX_UNREG_LOGIN:
+	case MBX_CLEAR_LA:
+	case MBX_DUMP_CONTEXT:
+	case MBX_RUN_DIAGS:
+	case MBX_RESTART:
+	case MBX_SET_MASK:
+		if (!(vport->fc_flag & FC_OFFLINE_MODE)) {
+			lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2743 Command 0x%x is illegal in on-line "
+				"state\n",
+				mb->mbxCommand);
+			return -EPERM;
+		}
+	case MBX_WRITE_NV:
+	case MBX_WRITE_VPARMS:
+	case MBX_LOAD_SM:
+	case MBX_READ_NV:
+	case MBX_READ_CONFIG:
+	case MBX_READ_RCONFIG:
+	case MBX_READ_STATUS:
+	case MBX_READ_XRI:
+	case MBX_READ_REV:
+	case MBX_READ_LNK_STAT:
+	case MBX_DUMP_MEMORY:
+	case MBX_DOWN_LOAD:
+	case MBX_UPDATE_CFG:
+	case MBX_KILL_BOARD:
+	case MBX_LOAD_AREA:
+	case MBX_LOAD_EXP_ROM:
+	case MBX_BEACON:
+	case MBX_DEL_LD_ENTRY:
+	case MBX_SET_DEBUG:
+	case MBX_WRITE_WWN:
+	case MBX_SLI4_CONFIG:
+	case MBX_READ_EVENT_LOG_STATUS:
+	case MBX_WRITE_EVENT_LOG:
+	case MBX_PORT_CAPABILITIES:
+	case MBX_PORT_IOV_CONTROL:
+		break;
+	case MBX_SET_VARIABLE:
+		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+			"1226 mbox: set_variable 0x%x, 0x%x\n",
+			mb->un.varWords[0],
+			mb->un.varWords[1]);
+		if ((mb->un.varWords[0] == SETVAR_MLOMNT)
+			&& (mb->un.varWords[1] == 1)) {
+			phba->wait_4_mlo_maint_flg = 1;
+		} else if (mb->un.varWords[0] == SETVAR_MLORST) {
+			phba->link_flag &= ~LS_LOOPBACK_MODE;
+			phba->fc_topology = TOPOLOGY_PT_PT;
+		}
+		break;
+	case MBX_RUN_BIU_DIAG64:
+	case MBX_READ_EVENT_LOG:
+	case MBX_READ_SPARM64:
+	case MBX_READ_LA:
+	case MBX_READ_LA64:
+	case MBX_REG_LOGIN:
+	case MBX_REG_LOGIN64:
+	case MBX_CONFIG_PORT:
+	case MBX_RUN_BIU_DIAG:
+	default:
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+			"2742 Unknown Command 0x%x\n",
+			mb->mbxCommand);
+		return -EPERM;
+	}
+
+	return 0; /* ok */
+}
+
+/**
+ * lpfc_bsg_issue_mbox - issues a mailbox command on behalf of an app
+ * @phba: Pointer to HBA context object.
+ * @mb: Pointer to a mailbox object.
+ * @vport: Pointer to a vport object.
+ *
+ * Allocate a tracking object, mailbox command memory, get a mailbox
+ * from the mailbox pool, copy the caller mailbox command.
+ *
+ * If offline and the sli is active we need to poll for the command (port is
+ * being reset) and com-plete the job, otherwise issue the mailbox command and
+ * let our completion handler finish the command.
+ **/
+static uint32_t
+lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
+	struct lpfc_vport *vport)
+{
+	LPFC_MBOXQ_t *pmboxq;
+	MAILBOX_t *pmb;
+	MAILBOX_t *mb;
+	struct bsg_job_data *dd_data;
+	uint32_t size;
+	int rc = 0;
+
+	/* allocate our bsg tracking structure */
+	dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
+	if (!dd_data) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2727 Failed allocation of dd_data\n");
+		return -ENOMEM;
+	}
+
+	mb = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!mb) {
+		kfree(dd_data);
+		return -ENOMEM;
+	}
+
+	pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!pmboxq) {
+		kfree(dd_data);
+		kfree(mb);
+		return -ENOMEM;
+	}
+
+	size = job->request_payload.payload_len;
+	job->reply->reply_payload_rcv_len =
+		sg_copy_to_buffer(job->request_payload.sg_list,
+				job->request_payload.sg_cnt,
+				mb, size);
+
+	rc = lpfc_bsg_check_cmd_access(phba, mb, vport);
+	if (rc != 0) {
+		kfree(dd_data);
+		kfree(mb);
+		mempool_free(pmboxq, phba->mbox_mem_pool);
+		return rc; /* must be negative */
+	}
+
+	memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
+	pmb = &pmboxq->u.mb;
+	memcpy(pmb, mb, sizeof(*pmb));
+	pmb->mbxOwner = OWN_HOST;
+	pmboxq->context1 = NULL;
+	pmboxq->vport = vport;
+
+	if ((vport->fc_flag & FC_OFFLINE_MODE) ||
+	    (!(phba->sli.sli_flag & LPFC_SLI_ACTIVE))) {
+		rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
+		if (rc != MBX_SUCCESS) {
+			if (rc != MBX_TIMEOUT) {
+				kfree(dd_data);
+				kfree(mb);
+				mempool_free(pmboxq, phba->mbox_mem_pool);
+			}
+			return  (rc == MBX_TIMEOUT) ? -ETIME : -ENODEV;
+		}
+
+		memcpy(mb, pmb, sizeof(*pmb));
+		job->reply->reply_payload_rcv_len =
+			sg_copy_from_buffer(job->reply_payload.sg_list,
+					job->reply_payload.sg_cnt,
+					mb, size);
+		kfree(dd_data);
+		kfree(mb);
+		mempool_free(pmboxq, phba->mbox_mem_pool);
+		/* not waiting mbox already done */
+		return 0;
+	}
+
+	/* setup wake call as IOCB callback */
+	pmboxq->mbox_cmpl = lpfc_bsg_wake_mbox_wait;
+	/* setup context field to pass wait_queue pointer to wake function */
+	pmboxq->context1 = dd_data;
+	dd_data->type = TYPE_MBOX;
+	dd_data->context_un.mbox.pmboxq = pmboxq;
+	dd_data->context_un.mbox.mb = mb;
+	dd_data->context_un.mbox.set_job = job;
+	job->dd_data = dd_data;
+	rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT);
+	if ((rc != MBX_SUCCESS) && (rc != MBX_BUSY)) {
+		kfree(dd_data);
+		kfree(mb);
+		mempool_free(pmboxq, phba->mbox_mem_pool);
+		return -EIO;
+	}
+
+	return 1;
+}
+
+/**
+ * lpfc_bsg_mbox_cmd - process an fc bsg LPFC_BSG_VENDOR_MBOX command
+ * @job: MBOX fc_bsg_job for LPFC_BSG_VENDOR_MBOX.
+ **/
+static int
+lpfc_bsg_mbox_cmd(struct fc_bsg_job *job)
+{
+	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	int rc = 0;
+
+	/* in case no data is transferred */
+	job->reply->reply_payload_rcv_len = 0;
+	if (job->request_len <
+	    sizeof(struct fc_bsg_request) + sizeof(struct dfc_mbox_req)) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2737 Received MBOX_REQ request below "
+				"minimum size\n");
+		rc = -EINVAL;
+		goto job_error;
+	}
+
+	if (job->request_payload.payload_len != PAGE_SIZE) {
+		rc = -EINVAL;
+		goto job_error;
+	}
+
+	if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) {
+		rc = -EAGAIN;
+		goto job_error;
+	}
+
+	rc = lpfc_bsg_issue_mbox(phba, job, vport);
+
+job_error:
+	if (rc == 0) {
+		/* job done */
+		job->reply->result = 0;
+		job->dd_data = NULL;
+		job->job_done(job);
+	} else if (rc == 1)
+		/* job submitted, will complete later*/
+		rc = 0; /* return zero, no error */
+	else {
+		/* some error occurred */
+		job->reply->result = rc;
+		job->dd_data = NULL;
+	}
 
 	return rc;
 }
 
 /**
+ * lpfc_bsg_menlo_cmd_cmp - lpfc_menlo_cmd completion handler
+ * @phba: Pointer to HBA context object.
+ * @cmdiocbq: Pointer to command iocb.
+ * @rspiocbq: Pointer to response iocb.
+ *
+ * This function is the completion handler for iocbs issued using
+ * lpfc_menlo_cmd function. This function is called by the
+ * ring event handler function without any lock held. This function
+ * can be called from both worker thread context and interrupt
+ * context. This function also can be called from another thread which
+ * cleans up the SLI layer objects.
+ * This function copies the contents of the response iocb to the
+ * response iocb memory object provided by the caller of
+ * lpfc_sli_issue_iocb_wait and then wakes up the thread which
+ * sleeps for the iocb completion.
+ **/
+static void
+lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
+			struct lpfc_iocbq *cmdiocbq,
+			struct lpfc_iocbq *rspiocbq)
+{
+	struct bsg_job_data *dd_data;
+	struct fc_bsg_job *job;
+	IOCB_t *rsp;
+	struct lpfc_dmabuf *bmp;
+	struct lpfc_bsg_menlo *menlo;
+	unsigned long flags;
+	struct menlo_response *menlo_resp;
+	int rc = 0;
+
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
+	dd_data = cmdiocbq->context1;
+	if (!dd_data) {
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+		return;
+	}
+
+	menlo = &dd_data->context_un.menlo;
+	job = menlo->set_job;
+	job->dd_data = NULL; /* so timeout handler does not reply */
+
+	spin_lock_irqsave(&phba->hbalock, flags);
+	cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
+	if (cmdiocbq->context2 && rspiocbq)
+		memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
+		       &rspiocbq->iocb, sizeof(IOCB_t));
+	spin_unlock_irqrestore(&phba->hbalock, flags);
+
+	bmp = menlo->bmp;
+	rspiocbq = menlo->rspiocbq;
+	rsp = &rspiocbq->iocb;
+
+	pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
+		     job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
+		     job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+
+	/* always return the xri, this would be used in the case
+	 * of a menlo download to allow the data to be sent as a continuation
+	 * of the exchange.
+	 */
+	menlo_resp = (struct menlo_response *)
+		job->reply->reply_data.vendor_reply.vendor_rsp;
+	menlo_resp->xri = rsp->ulpContext;
+	if (rsp->ulpStatus) {
+		if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
+			switch (rsp->un.ulpWord[4] & 0xff) {
+			case IOERR_SEQUENCE_TIMEOUT:
+				rc = -ETIMEDOUT;
+				break;
+			case IOERR_INVALID_RPI:
+				rc = -EFAULT;
+				break;
+			default:
+				rc = -EACCES;
+				break;
+			}
+		} else
+			rc = -EACCES;
+	} else
+		job->reply->reply_payload_rcv_len =
+			rsp->un.genreq64.bdl.bdeSize;
+
+	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
+	lpfc_sli_release_iocbq(phba, rspiocbq);
+	lpfc_sli_release_iocbq(phba, cmdiocbq);
+	kfree(bmp);
+	kfree(dd_data);
+	/* make error code available to userspace */
+	job->reply->result = rc;
+	/* complete the job back to userspace */
+	job->job_done(job);
+	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+	return;
+}
+
+/**
+ * lpfc_menlo_cmd - send an ioctl for menlo hardware
+ * @job: fc_bsg_job to handle
+ *
+ * This function issues a gen request 64 CR ioctl for all menlo cmd requests,
+ * all the command completions will return the xri for the command.
+ * For menlo data requests a gen request 64 CX is used to continue the exchange
+ * supplied in the menlo request header xri field.
+ **/
+static int
+lpfc_menlo_cmd(struct fc_bsg_job *job)
+{
+	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_iocbq *cmdiocbq, *rspiocbq;
+	IOCB_t *cmd, *rsp;
+	int rc = 0;
+	struct menlo_command *menlo_cmd;
+	struct menlo_response *menlo_resp;
+	struct lpfc_dmabuf *bmp = NULL;
+	int request_nseg;
+	int reply_nseg;
+	struct scatterlist *sgel = NULL;
+	int numbde;
+	dma_addr_t busaddr;
+	struct bsg_job_data *dd_data;
+	struct ulp_bde64 *bpl = NULL;
+
+	/* in case no data is returned return just the return code */
+	job->reply->reply_payload_rcv_len = 0;
+
+	if (job->request_len <
+	    sizeof(struct fc_bsg_request) +
+		sizeof(struct menlo_command)) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2784 Received MENLO_CMD request below "
+				"minimum size\n");
+		rc = -ERANGE;
+		goto no_dd_data;
+	}
+
+	if (job->reply_len <
+	    sizeof(struct fc_bsg_request) + sizeof(struct menlo_response)) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2785 Received MENLO_CMD reply below "
+				"minimum size\n");
+		rc = -ERANGE;
+		goto no_dd_data;
+	}
+
+	if (!(phba->menlo_flag & HBA_MENLO_SUPPORT)) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2786 Adapter does not support menlo "
+				"commands\n");
+		rc = -EPERM;
+		goto no_dd_data;
+	}
+
+	menlo_cmd = (struct menlo_command *)
+		job->request->rqst_data.h_vendor.vendor_cmd;
+
+	menlo_resp = (struct menlo_response *)
+		job->reply->reply_data.vendor_reply.vendor_rsp;
+
+	/* allocate our bsg tracking structure */
+	dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
+	if (!dd_data) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2787 Failed allocation of dd_data\n");
+		rc = -ENOMEM;
+		goto no_dd_data;
+	}
+
+	bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+	if (!bmp) {
+		rc = -ENOMEM;
+		goto free_dd;
+	}
+
+	cmdiocbq = lpfc_sli_get_iocbq(phba);
+	if (!cmdiocbq) {
+		rc = -ENOMEM;
+		goto free_bmp;
+	}
+
+	rspiocbq = lpfc_sli_get_iocbq(phba);
+	if (!rspiocbq) {
+		rc = -ENOMEM;
+		goto free_cmdiocbq;
+	}
+
+	rsp = &rspiocbq->iocb;
+
+	bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys);
+	if (!bmp->virt) {
+		rc = -ENOMEM;
+		goto free_rspiocbq;
+	}
+
+	INIT_LIST_HEAD(&bmp->list);
+	bpl = (struct ulp_bde64 *) bmp->virt;
+	request_nseg = pci_map_sg(phba->pcidev, job->request_payload.sg_list,
+				  job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	for_each_sg(job->request_payload.sg_list, sgel, request_nseg, numbde) {
+		busaddr = sg_dma_address(sgel);
+		bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+		bpl->tus.f.bdeSize = sg_dma_len(sgel);
+		bpl->tus.w = cpu_to_le32(bpl->tus.w);
+		bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr));
+		bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr));
+		bpl++;
+	}
+
+	reply_nseg = pci_map_sg(phba->pcidev, job->reply_payload.sg_list,
+				job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+	for_each_sg(job->reply_payload.sg_list, sgel, reply_nseg, numbde) {
+		busaddr = sg_dma_address(sgel);
+		bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;
+		bpl->tus.f.bdeSize = sg_dma_len(sgel);
+		bpl->tus.w = cpu_to_le32(bpl->tus.w);
+		bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr));
+		bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr));
+		bpl++;
+	}
+
+	cmd = &cmdiocbq->iocb;
+	cmd->un.genreq64.bdl.ulpIoTag32 = 0;
+	cmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
+	cmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
+	cmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
+	cmd->un.genreq64.bdl.bdeSize =
+	    (request_nseg + reply_nseg) * sizeof(struct ulp_bde64);
+	cmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
+	cmd->un.genreq64.w5.hcsw.Dfctl = 0;
+	cmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CMD;
+	cmd->un.genreq64.w5.hcsw.Type = MENLO_TRANSPORT_TYPE; /* 0xfe */
+	cmd->ulpBdeCount = 1;
+	cmd->ulpClass = CLASS3;
+	cmd->ulpOwner = OWN_CHIP;
+	cmd->ulpLe = 1; /* Limited Edition */
+	cmdiocbq->iocb_flag |= LPFC_IO_LIBDFC;
+	cmdiocbq->vport = phba->pport;
+	/* We want the firmware to timeout before we do */
+	cmd->ulpTimeout = MENLO_TIMEOUT - 5;
+	cmdiocbq->context3 = bmp;
+	cmdiocbq->context2 = rspiocbq;
+	cmdiocbq->iocb_cmpl = lpfc_bsg_menlo_cmd_cmp;
+	cmdiocbq->context1 = dd_data;
+	cmdiocbq->context2 = rspiocbq;
+	if (menlo_cmd->cmd == LPFC_BSG_VENDOR_MENLO_CMD) {
+		cmd->ulpCommand = CMD_GEN_REQUEST64_CR;
+		cmd->ulpPU = MENLO_PU; /* 3 */
+		cmd->un.ulpWord[4] = MENLO_DID; /* 0x0000FC0E */
+		cmd->ulpContext = MENLO_CONTEXT; /* 0 */
+	} else {
+		cmd->ulpCommand = CMD_GEN_REQUEST64_CX;
+		cmd->ulpPU = 1;
+		cmd->un.ulpWord[4] = 0;
+		cmd->ulpContext = menlo_cmd->xri;
+	}
+
+	dd_data->type = TYPE_MENLO;
+	dd_data->context_un.menlo.cmdiocbq = cmdiocbq;
+	dd_data->context_un.menlo.rspiocbq = rspiocbq;
+	dd_data->context_un.menlo.set_job = job;
+	dd_data->context_un.menlo.bmp = bmp;
+
+	rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq,
+		MENLO_TIMEOUT - 5);
+	if (rc == IOCB_SUCCESS)
+		return 0; /* done for now */
+
+	/* iocb failed so cleanup */
+	pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
+		     job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
+		     job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+
+	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
+
+free_rspiocbq:
+	lpfc_sli_release_iocbq(phba, rspiocbq);
+free_cmdiocbq:
+	lpfc_sli_release_iocbq(phba, cmdiocbq);
+free_bmp:
+	kfree(bmp);
+free_dd:
+	kfree(dd_data);
+no_dd_data:
+	/* make error code available to userspace */
+	job->reply->result = rc;
+	job->dd_data = NULL;
+	return rc;
+}
+/**
  * lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job
  * @job: fc_bsg_job to handle
- */
+ **/
 static int
 lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
 {
 	int command = job->request->rqst_data.h_vendor.vendor_cmd[0];
+	int rc;
 
 	switch (command) {
 	case LPFC_BSG_VENDOR_SET_CT_EVENT:
-		return lpfc_bsg_set_event(job);
+		rc = lpfc_bsg_hba_set_event(job);
 		break;
-
 	case LPFC_BSG_VENDOR_GET_CT_EVENT:
-		return lpfc_bsg_get_event(job);
+		rc = lpfc_bsg_hba_get_event(job);
+		break;
+	case LPFC_BSG_VENDOR_SEND_MGMT_RESP:
+		rc = lpfc_bsg_send_mgmt_rsp(job);
+		break;
+	case LPFC_BSG_VENDOR_DIAG_MODE:
+		rc = lpfc_bsg_diag_mode(job);
+		break;
+	case LPFC_BSG_VENDOR_DIAG_TEST:
+		rc = lpfc_bsg_diag_test(job);
+		break;
+	case LPFC_BSG_VENDOR_GET_MGMT_REV:
+		rc = lpfc_bsg_get_dfc_rev(job);
+		break;
+	case LPFC_BSG_VENDOR_MBOX:
+		rc = lpfc_bsg_mbox_cmd(job);
+		break;
+	case LPFC_BSG_VENDOR_MENLO_CMD:
+	case LPFC_BSG_VENDOR_MENLO_DATA:
+		rc = lpfc_menlo_cmd(job);
 		break;
-
 	default:
-		return -EINVAL;
+		rc = -EINVAL;
+		job->reply->reply_payload_rcv_len = 0;
+		/* make error code available to userspace */
+		job->reply->result = rc;
+		break;
 	}
+
+	return rc;
 }
 
 /**
  * lpfc_bsg_request - handle a bsg request from the FC transport
  * @job: fc_bsg_job to handle
- */
+ **/
 int
 lpfc_bsg_request(struct fc_bsg_job *job)
 {
 	uint32_t msgcode;
-	int rc = -EINVAL;
+	int rc;
 
 	msgcode = job->request->msgcode;
-
 	switch (msgcode) {
 	case FC_BSG_HST_VENDOR:
 		rc = lpfc_bsg_hst_vendor(job);
@@ -874,9 +3020,13 @@ lpfc_bsg_request(struct fc_bsg_job *job)
 		rc = lpfc_bsg_rport_els(job);
 		break;
 	case FC_BSG_RPT_CT:
-		rc = lpfc_bsg_rport_ct(job);
+		rc = lpfc_bsg_send_mgmt_cmd(job);
 		break;
 	default:
+		rc = -EINVAL;
+		job->reply->reply_payload_rcv_len = 0;
+		/* make error code available to userspace */
+		job->reply->result = rc;
 		break;
 	}
 
@@ -889,17 +3039,83 @@ lpfc_bsg_request(struct fc_bsg_job *job)
  *
  * This function just aborts the job's IOCB.  The aborted IOCB will return to
  * the waiting function which will handle passing the error back to userspace
- */
+ **/
 int
 lpfc_bsg_timeout(struct fc_bsg_job *job)
 {
 	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
 	struct lpfc_hba *phba = vport->phba;
-	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)job->dd_data;
+	struct lpfc_iocbq *cmdiocb;
+	struct lpfc_bsg_event *evt;
+	struct lpfc_bsg_iocb *iocb;
+	struct lpfc_bsg_mbox *mbox;
+	struct lpfc_bsg_menlo *menlo;
 	struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
+	struct bsg_job_data *dd_data;
+	unsigned long flags;
 
-	if (cmdiocb)
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
+	dd_data = (struct bsg_job_data *)job->dd_data;
+	/* timeout and completion crossed paths if no dd_data */
+	if (!dd_data) {
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+		return 0;
+	}
+
+	switch (dd_data->type) {
+	case TYPE_IOCB:
+		iocb = &dd_data->context_un.iocb;
+		cmdiocb = iocb->cmdiocbq;
+		/* hint to completion handler that the job timed out */
+		job->reply->result = -EAGAIN;
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+		/* this will call our completion handler */
+		spin_lock_irq(&phba->hbalock);
 		lpfc_sli_issue_abort_iotag(phba, pring, cmdiocb);
+		spin_unlock_irq(&phba->hbalock);
+		break;
+	case TYPE_EVT:
+		evt = dd_data->context_un.evt;
+		/* this event has no job anymore */
+		evt->set_job = NULL;
+		job->dd_data = NULL;
+		job->reply->reply_payload_rcv_len = 0;
+		/* Return -EAGAIN which is our way of signallying the
+		 * app to retry.
+		 */
+		job->reply->result = -EAGAIN;
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+		job->job_done(job);
+		break;
+	case TYPE_MBOX:
+		mbox = &dd_data->context_un.mbox;
+		/* this mbox has no job anymore */
+		mbox->set_job = NULL;
+		job->dd_data = NULL;
+		job->reply->reply_payload_rcv_len = 0;
+		job->reply->result = -EAGAIN;
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+		job->job_done(job);
+		break;
+	case TYPE_MENLO:
+		menlo = &dd_data->context_un.menlo;
+		cmdiocb = menlo->cmdiocbq;
+		/* hint to completion handler that the job timed out */
+		job->reply->result = -EAGAIN;
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+		/* this will call our completion handler */
+		spin_lock_irq(&phba->hbalock);
+		lpfc_sli_issue_abort_iotag(phba, pring, cmdiocb);
+		spin_unlock_irq(&phba->hbalock);
+		break;
+	default:
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+		break;
+	}
 
+	/* scsi transport fc fc_bsg_job_timeout expects a zero return code,
+	 * otherwise an error message will be displayed on the console
+	 * so always return success (zero)
+	 */
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_bsg.h linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_bsg.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_bsg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_bsg.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,110 @@
+/*******************************************************************
+ * This file is part of the Emulex Linux Device Driver for         *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2010 Emulex.  All rights reserved.                *
+ * EMULEX and SLI are trademarks of Emulex.                        *
+ * www.emulex.com                                                  *
+ *                                                                 *
+ * 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. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
+ *******************************************************************/
+/* bsg definitions
+ * No pointers to user data are allowed, all application buffers and sizes will
+ * derived through the bsg interface.
+ *
+ * These are the vendor unique structures passed in using the bsg
+ * FC_BSG_HST_VENDOR message code type.
+ */
+#define LPFC_BSG_VENDOR_SET_CT_EVENT	1
+#define LPFC_BSG_VENDOR_GET_CT_EVENT	2
+#define LPFC_BSG_VENDOR_SEND_MGMT_RESP	3
+#define LPFC_BSG_VENDOR_DIAG_MODE	4
+#define LPFC_BSG_VENDOR_DIAG_TEST	5
+#define LPFC_BSG_VENDOR_GET_MGMT_REV	6
+#define LPFC_BSG_VENDOR_MBOX		7
+#define LPFC_BSG_VENDOR_MENLO_CMD	8
+#define LPFC_BSG_VENDOR_MENLO_DATA	9
+
+struct set_ct_event {
+	uint32_t command;
+	uint32_t type_mask;
+	uint32_t ev_req_id;
+	uint32_t ev_reg_id;
+};
+
+struct get_ct_event {
+	uint32_t command;
+	uint32_t ev_reg_id;
+	uint32_t ev_req_id;
+};
+
+struct get_ct_event_reply {
+	uint32_t immed_data;
+	uint32_t type;
+};
+
+struct send_mgmt_resp {
+	uint32_t command;
+	uint32_t tag;
+};
+
+
+#define INTERNAL_LOOP_BACK 0x1 /* adapter short cuts the loop internally */
+#define EXTERNAL_LOOP_BACK 0x2 /* requires an external loopback plug */
+
+struct diag_mode_set {
+	uint32_t command;
+	uint32_t type;
+	uint32_t timeout;
+};
+
+struct diag_mode_test {
+	uint32_t command;
+};
+
+#define LPFC_WWNN_TYPE		0
+#define LPFC_WWPN_TYPE		1
+
+struct get_mgmt_rev {
+	uint32_t command;
+};
+
+#define MANAGEMENT_MAJOR_REV   1
+#define MANAGEMENT_MINOR_REV   0
+
+/* the MgmtRevInfo structure */
+struct MgmtRevInfo {
+	uint32_t a_Major;
+	uint32_t a_Minor;
+};
+
+struct get_mgmt_rev_reply {
+	struct MgmtRevInfo info;
+};
+
+struct dfc_mbox_req {
+	uint32_t command;
+	uint32_t inExtWLen;
+	uint32_t outExtWLen;
+	uint8_t mbOffset;
+};
+
+/* Used for menlo command or menlo data. The xri is only used for menlo data */
+struct menlo_command {
+	uint32_t cmd;
+	uint32_t xri;
+};
+
+struct menlo_response {
+	uint32_t xri; /* return the xri of the iocb exchange */
+};
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_crtn.h linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_crtn.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_crtn.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_crtn.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2008 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2010 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
@@ -44,18 +44,27 @@ int lpfc_reg_rpi(struct lpfc_hba *, uint
 void lpfc_unreg_login(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
 void lpfc_unreg_did(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
 void lpfc_reg_vpi(struct lpfc_vport *, LPFC_MBOXQ_t *);
+void lpfc_register_new_vport(struct lpfc_hba *, struct lpfc_vport *,
+			struct lpfc_nodelist *);
 void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *);
 void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
 void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *);
+void lpfc_supported_pages(struct lpfcMboxq *);
+void lpfc_sli4_params(struct lpfcMboxq *);
+int lpfc_pc_sli4_params_get(struct lpfc_hba *, LPFC_MBOXQ_t *);
 
 struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t);
 void lpfc_cleanup_rcv_buffers(struct lpfc_vport *);
 void lpfc_rcv_seq_check_edtov(struct lpfc_vport *);
 void lpfc_cleanup_rpis(struct lpfc_vport *, int);
+void lpfc_cleanup_pending_mbox(struct lpfc_vport *);
 int lpfc_linkdown(struct lpfc_hba *);
 void lpfc_linkdown_port(struct lpfc_vport *);
 void lpfc_port_link_failure(struct lpfc_vport *);
 void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *);
+void lpfc_retry_pport_discovery(struct lpfc_hba *);
 
 void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -73,6 +82,7 @@ void lpfc_set_disctmo(struct lpfc_vport
 int  lpfc_can_disctmo(struct lpfc_vport *);
 int  lpfc_unreg_rpi(struct lpfc_vport *, struct lpfc_nodelist *);
 void lpfc_unreg_all_rpis(struct lpfc_vport *);
+void lpfc_unreg_hba_rpis(struct lpfc_hba *);
 void lpfc_unreg_default_rpis(struct lpfc_vport *);
 void lpfc_issue_reg_vpi(struct lpfc_hba *, struct lpfc_vport *);
 
@@ -99,7 +109,7 @@ int lpfc_disc_state_machine(struct lpfc_
 
 void lpfc_do_scr_ns_plogi(struct lpfc_hba *, struct lpfc_vport *);
 int lpfc_check_sparm(struct lpfc_vport *, struct lpfc_nodelist *,
-		     struct serv_parm *, uint32_t);
+		     struct serv_parm *, uint32_t, int);
 int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist *);
 void lpfc_more_plogi(struct lpfc_vport *);
 void lpfc_more_adisc(struct lpfc_vport *);
@@ -197,6 +207,7 @@ void lpfc_reg_fcfi(struct lpfc_hba *, st
 void lpfc_unreg_fcfi(struct lpfcMboxq *, uint16_t);
 void lpfc_resume_rpi(struct lpfcMboxq *, struct lpfc_nodelist *);
 int lpfc_check_pending_fcoe_event(struct lpfc_hba *, uint8_t);
+void lpfc_issue_init_vpi(struct lpfc_vport *);
 
 void lpfc_config_hbq(struct lpfc_hba *, uint32_t, struct lpfc_hbq_init *,
 	uint32_t , LPFC_MBOXQ_t *);
@@ -206,7 +217,15 @@ struct hbq_dmabuf *lpfc_sli4_rb_alloc(st
 void lpfc_sli4_rb_free(struct lpfc_hba *, struct hbq_dmabuf *);
 void lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *, struct fcf_record *,
 			uint16_t);
+void lpfc_unregister_fcf(struct lpfc_hba *);
+void lpfc_unregister_fcf_rescan(struct lpfc_hba *);
 void lpfc_unregister_unused_fcf(struct lpfc_hba *);
+int lpfc_sli4_redisc_fcf_table(struct lpfc_hba *);
+void lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *);
+void lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *);
+uint16_t lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *);
+int lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *, uint16_t);
+void lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *, uint16_t);
 
 int lpfc_mem_alloc(struct lpfc_hba *, int align);
 void lpfc_mem_free(struct lpfc_hba *);
@@ -365,11 +384,13 @@ void lpfc_free_fast_evt(struct lpfc_hba
 void lpfc_create_static_vport(struct lpfc_hba *);
 void lpfc_stop_hba_timers(struct lpfc_hba *);
 void lpfc_stop_port(struct lpfc_hba *);
+void __lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *);
+void lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *);
 void lpfc_parse_fcoe_conf(struct lpfc_hba *, uint8_t *, uint32_t);
 int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int);
 void lpfc_start_fdiscs(struct lpfc_hba *phba);
 struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t);
-
+struct lpfc_sglq *__lpfc_get_active_sglq(struct lpfc_hba *, uint16_t);
 #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code)
 #define HBA_EVENT_RSCN                   5
 #define HBA_EVENT_LINK_UP                2
@@ -378,5 +399,5 @@ struct lpfc_vport *lpfc_find_vport_by_vp
 /* functions to support SGIOv4/bsg interface */
 int lpfc_bsg_request(struct fc_bsg_job *);
 int lpfc_bsg_timeout(struct fc_bsg_job *);
-void lpfc_bsg_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
+int lpfc_bsg_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
 			     struct lpfc_iocbq *);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_ct.c linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_ct.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_ct.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_ct.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2009 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2010 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
@@ -25,6 +25,7 @@
 #include <linux/blkdev.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/utsname.h>
 
 #include <scsi/scsi.h>
@@ -97,7 +98,8 @@ lpfc_ct_unsol_event(struct lpfc_hba *phb
 	struct list_head head;
 	struct lpfc_dmabuf *bdeBuf;
 
-	lpfc_bsg_ct_unsol_event(phba, pring, piocbq);
+	if (lpfc_bsg_ct_unsol_event(phba, pring, piocbq) == 0)
+		return;
 
 	if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) {
 		lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
@@ -181,7 +183,8 @@ lpfc_sli4_ct_abort_unsol_event(struct lp
 	uint32_t size;
 
 	/* Forward abort event to any process registered to receive ct event */
-	lpfc_bsg_ct_unsol_event(phba, pring, piocbq);
+	if (lpfc_bsg_ct_unsol_event(phba, pring, piocbq) == 0)
+		return;
 
 	/* If there is no BDE associated with IOCB, there is nothing to do */
 	if (icmd->ulpBdeCount == 0)
@@ -1843,12 +1846,7 @@ lpfc_decode_firmware_rev(struct lpfc_hba
 		c  = (rev & 0x0000ff00) >> 8;
 		b4 = (rev & 0x000000ff);
 
-		if (flag)
-			sprintf(fwrevision, "%d.%d%d%c%d ", b1,
-				b2, b3, c, b4);
-		else
-			sprintf(fwrevision, "%d.%d%d%c%d ", b1,
-				b2, b3, c, b4);
+		sprintf(fwrevision, "%d.%d%d%c%d", b1, b2, b3, c, b4);
 	}
 	return;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_debugfs.c linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_debugfs.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_debugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_debugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/idr.h>
 #include <linux/interrupt.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/ctype.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_els.c linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_els.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_els.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_els.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 /* See Fibre Channel protocol T11 FC-LS for details */
 #include <linux/blkdev.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 
 #include <scsi/scsi.h>
@@ -50,9 +51,6 @@ static int lpfc_issue_els_fdisc(struct l
 				struct lpfc_nodelist *ndlp, uint8_t retry);
 static int lpfc_issue_fabric_iocb(struct lpfc_hba *phba,
 				  struct lpfc_iocbq *iocb);
-static void lpfc_register_new_vport(struct lpfc_hba *phba,
-				    struct lpfc_vport *vport,
-				    struct lpfc_nodelist *ndlp);
 
 static int lpfc_max_els_tries = 3;
 
@@ -592,6 +590,15 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_v
 			vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
 			spin_unlock_irq(shost->host_lock);
 		}
+		/*
+		 * If VPI is unreged, driver need to do INIT_VPI
+		 * before re-registering
+		 */
+		if (phba->sli_rev == LPFC_SLI_REV4) {
+			spin_lock_irq(shost->host_lock);
+			vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
+			spin_unlock_irq(shost->host_lock);
+		}
 	}
 
 	if (phba->sli_rev < LPFC_SLI_REV4) {
@@ -604,10 +611,13 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_v
 	} else {
 		ndlp->nlp_type |= NLP_FABRIC;
 		lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
-		if (vport->vpi_state & LPFC_VPI_REGISTERED) {
+		if ((!(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) &&
+			(vport->vpi_state & LPFC_VPI_REGISTERED)) {
 			lpfc_start_fdiscs(phba);
 			lpfc_do_scr_ns_plogi(phba, vport);
-		} else
+		} else if (vport->fc_flag & FC_VFI_REGISTERED)
+			lpfc_issue_init_vpi(vport);
+		else
 			lpfc_issue_reg_vfi(vport);
 	}
 	return 0;
@@ -762,6 +772,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phb
 	struct lpfc_nodelist *ndlp = cmdiocb->context1;
 	struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp;
 	struct serv_parm *sp;
+	uint16_t fcf_index;
 	int rc;
 
 	/* Check to see if link went down during discovery */
@@ -779,6 +790,54 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phb
 		vport->port_state);
 
 	if (irsp->ulpStatus) {
+		/*
+		 * In case of FIP mode, perform round robin FCF failover
+		 * due to new FCF discovery
+		 */
+		if ((phba->hba_flag & HBA_FIP_SUPPORT) &&
+		    (phba->fcf.fcf_flag & FCF_DISCOVERY)) {
+			lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS,
+					"2611 FLOGI failed on registered "
+					"FCF record fcf_index:%d, trying "
+					"to perform round robin failover\n",
+					phba->fcf.current_rec.fcf_indx);
+			fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba);
+			if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) {
+				/*
+				 * Exhausted the eligible FCF record list,
+				 * fail through to retry FLOGI on current
+				 * FCF record.
+				 */
+				lpfc_printf_log(phba, KERN_WARNING,
+						LOG_FIP | LOG_ELS,
+						"2760 FLOGI exhausted FCF "
+						"round robin failover list, "
+						"retry FLOGI on the current "
+						"registered FCF index:%d\n",
+						phba->fcf.current_rec.fcf_indx);
+				spin_lock_irq(&phba->hbalock);
+				phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+				spin_unlock_irq(&phba->hbalock);
+			} else {
+				rc = lpfc_sli4_fcf_rr_read_fcf_rec(phba,
+								   fcf_index);
+				if (rc) {
+					lpfc_printf_log(phba, KERN_WARNING,
+							LOG_FIP | LOG_ELS,
+							"2761 FLOGI round "
+							"robin FCF failover "
+							"read FCF failed "
+							"rc:x%x, fcf_index:"
+							"%d\n", rc,
+						phba->fcf.current_rec.fcf_indx);
+					spin_lock_irq(&phba->hbalock);
+					phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+					spin_unlock_irq(&phba->hbalock);
+				} else
+					goto out;
+			}
+		}
+
 		/* Check for retry */
 		if (lpfc_els_retry(phba, cmdiocb, rspiocb))
 			goto out;
@@ -797,13 +856,15 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phb
 		}
 
 		/* FLOGI failure */
-		lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
-				 "0100 FLOGI failure Data: x%x x%x "
-				 "x%x\n",
+		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+				 "0100 FLOGI failure Status:x%x/x%x TMO:x%x\n",
 				 irsp->ulpStatus, irsp->un.ulpWord[4],
 				 irsp->ulpTimeout);
 		goto flogifail;
 	}
+	spin_lock_irq(shost->host_lock);
+	vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
+	spin_unlock_irq(shost->host_lock);
 
 	/*
 	 * The FLogI succeeded.  Sync the data for the CPU before
@@ -830,8 +891,18 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phb
 		else
 			rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp);
 
-		if (!rc)
+		if (!rc) {
+			/* Mark the FCF discovery process done */
+			lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP | LOG_ELS,
+					 "2769 FLOGI successful on FCF record: "
+					 "current_fcf_index:x%x, terminate FCF "
+					 "round robin failover process\n",
+					 phba->fcf.current_rec.fcf_indx);
+			spin_lock_irq(&phba->hbalock);
+			phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+			spin_unlock_irq(&phba->hbalock);
 			goto out;
+		}
 	}
 
 flogifail:
@@ -969,7 +1040,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *
  * function returns, it does not guarantee all the IOCBs are actually aborted.
  *
  * Return code
- *   0 - Sucessfully issued abort iocb on all outstanding flogis (Always 0)
+ *   0 - Successfully issued abort iocb on all outstanding flogis (Always 0)
  **/
 int
 lpfc_els_abort_flogi(struct lpfc_hba *phba)
@@ -1397,6 +1468,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phb
 			goto out;
 		}
 		/* PLOGI failed */
+		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+				 "2753 PLOGI failure DID:%06X Status:x%x/x%x\n",
+				 ndlp->nlp_DID, irsp->ulpStatus,
+				 irsp->un.ulpWord[4]);
 		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
 		if (lpfc_error_lost_link(irsp))
 			rc = NLP_STE_FREED_NODE;
@@ -1565,6 +1640,10 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba
 			goto out;
 		}
 		/* PRLI failed */
+		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+				 "2754 PRLI failure DID:%06X Status:x%x/x%x\n",
+				 ndlp->nlp_DID, irsp->ulpStatus,
+				 irsp->un.ulpWord[4]);
 		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
 		if (lpfc_error_lost_link(irsp))
 			goto out;
@@ -1848,6 +1927,10 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phb
 			goto out;
 		}
 		/* ADISC failed */
+		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+				 "2755 ADISC failure DID:%06X Status:x%x/x%x\n",
+				 ndlp->nlp_DID, irsp->ulpStatus,
+				 irsp->un.ulpWord[4]);
 		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
 		if (!lpfc_error_lost_link(irsp))
 			lpfc_disc_state_machine(vport, ndlp, cmdiocb,
@@ -1997,6 +2080,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba
 			/* ELS command is being retried */
 			goto out;
 		/* LOGO failed */
+		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+				 "2756 LOGO failure DID:%06X Status:x%x/x%x\n",
+				 ndlp->nlp_DID, irsp->ulpStatus,
+				 irsp->un.ulpWord[4]);
 		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
 		if (lpfc_error_lost_link(irsp))
 			goto out;
@@ -2720,7 +2807,7 @@ lpfc_els_retry(struct lpfc_hba *phba, st
 	if (did == FDMI_DID)
 		retry = 1;
 
-	if ((cmd == ELS_CMD_FLOGI) &&
+	if (((cmd == ELS_CMD_FLOGI) || (cmd == ELS_CMD_FDISC)) &&
 	    (phba->fc_topology != TOPOLOGY_LOOP) &&
 	    !lpfc_error_lost_link(irsp)) {
 		/* FLOGI retry policy */
@@ -3117,7 +3204,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba,
 	if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
 	    (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) {
 		/* A LS_RJT associated with Default RPI cleanup has its own
-		 * seperate code path.
+		 * separate code path.
 		 */
 		if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI))
 			ls_rjt = 1;
@@ -4385,7 +4472,7 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vp
 
 	did = Fabric_DID;
 
-	if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3))) {
+	if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1))) {
 		/* For a FLOGI we accept, then if our portname is greater
 		 * then the remote portname we initiate Nport login.
 		 */
@@ -5915,6 +6002,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba
 	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
 	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
 	MAILBOX_t *mb = &pmb->u.mb;
+	int rc;
 
 	spin_lock_irq(shost->host_lock);
 	vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
@@ -5936,6 +6024,26 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba
 			spin_unlock_irq(shost->host_lock);
 			lpfc_can_disctmo(vport);
 			break;
+		/* If reg_vpi fail with invalid VPI status, re-init VPI */
+		case 0x20:
+			spin_lock_irq(shost->host_lock);
+			vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
+			spin_unlock_irq(shost->host_lock);
+			lpfc_init_vpi(phba, pmb, vport->vpi);
+			pmb->vport = vport;
+			pmb->mbox_cmpl = lpfc_init_vpi_cmpl;
+			rc = lpfc_sli_issue_mbox(phba, pmb,
+				MBX_NOWAIT);
+			if (rc == MBX_NOT_FINISHED) {
+				lpfc_printf_vlog(vport,
+					KERN_ERR, LOG_MBOX,
+					"2732 Failed to issue INIT_VPI"
+					" mailbox command\n");
+			} else {
+				lpfc_nlp_put(ndlp);
+				return;
+			}
+
 		default:
 			/* Try to recover from this error */
 			lpfc_mbx_unreg_vpi(vport);
@@ -5949,13 +6057,22 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba
 			break;
 		}
 	} else {
+		spin_lock_irq(shost->host_lock);
 		vport->vpi_state |= LPFC_VPI_REGISTERED;
-		if (vport == phba->pport)
+		spin_unlock_irq(shost->host_lock);
+		if (vport == phba->pport) {
 			if (phba->sli_rev < LPFC_SLI_REV4)
 				lpfc_issue_fabric_reglogin(vport);
-			else
-				lpfc_issue_reg_vfi(vport);
-		else
+			else {
+				/*
+				 * If the physical port is instantiated using
+				 * FDISC, do not start vport discovery.
+				 */
+				if (vport->port_state != LPFC_FDISC)
+					lpfc_start_fdiscs(phba);
+				lpfc_do_scr_ns_plogi(phba, vport);
+			}
+		} else
 			lpfc_do_scr_ns_plogi(phba, vport);
 	}
 
@@ -5977,7 +6094,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba
  * This routine registers the @vport as a new virtual port with a HBA.
  * It is done through a registering vpi mailbox command.
  **/
-static void
+void
 lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
 			struct lpfc_nodelist *ndlp)
 {
@@ -6018,6 +6135,92 @@ mbox_err_exit:
 }
 
 /**
+ * lpfc_cancel_all_vport_retry_delay_timer - Cancel all vport retry delay timer
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine cancels the retry delay timers to all the vports.
+ **/
+void
+lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *phba)
+{
+	struct lpfc_vport **vports;
+	struct lpfc_nodelist *ndlp;
+	uint32_t link_state;
+	int i;
+
+	/* Treat this failure as linkdown for all vports */
+	link_state = phba->link_state;
+	lpfc_linkdown(phba);
+	phba->link_state = link_state;
+
+	vports = lpfc_create_vport_work_array(phba);
+
+	if (vports) {
+		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
+			ndlp = lpfc_findnode_did(vports[i], Fabric_DID);
+			if (ndlp)
+				lpfc_cancel_retry_delay_tmo(vports[i], ndlp);
+			lpfc_els_flush_cmd(vports[i]);
+		}
+		lpfc_destroy_vport_work_array(phba, vports);
+	}
+}
+
+/**
+ * lpfc_retry_pport_discovery - Start timer to retry FLOGI.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine abort all pending discovery commands and
+ * start a timer to retry FLOGI for the physical port
+ * discovery.
+ **/
+void
+lpfc_retry_pport_discovery(struct lpfc_hba *phba)
+{
+	struct lpfc_nodelist *ndlp;
+	struct Scsi_Host  *shost;
+
+	/* Cancel the all vports retry delay retry timers */
+	lpfc_cancel_all_vport_retry_delay_timer(phba);
+
+	/* If fabric require FLOGI, then re-instantiate physical login */
+	ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
+	if (!ndlp)
+		return;
+
+	shost = lpfc_shost_from_vport(phba->pport);
+	mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
+	spin_lock_irq(shost->host_lock);
+	ndlp->nlp_flag |= NLP_DELAY_TMO;
+	spin_unlock_irq(shost->host_lock);
+	ndlp->nlp_last_elscmd = ELS_CMD_FLOGI;
+	phba->pport->port_state = LPFC_FLOGI;
+	return;
+}
+
+/**
+ * lpfc_fabric_login_reqd - Check if FLOGI required.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmdiocb: pointer to FDISC command iocb.
+ * @rspiocb: pointer to FDISC response iocb.
+ *
+ * This routine checks if a FLOGI is reguired for FDISC
+ * to succeed.
+ **/
+static int
+lpfc_fabric_login_reqd(struct lpfc_hba *phba,
+		struct lpfc_iocbq *cmdiocb,
+		struct lpfc_iocbq *rspiocb)
+{
+
+	if ((rspiocb->iocb.ulpStatus != IOSTAT_FABRIC_RJT) ||
+		(rspiocb->iocb.un.ulpWord[4] != RJT_LOGIN_REQUIRED))
+		return 0;
+	else
+		return 1;
+}
+
+/**
  * lpfc_cmpl_els_fdisc - Completion function for fdisc iocb command
  * @phba: pointer to lpfc hba data structure.
  * @cmdiocb: pointer to lpfc command iocb data structure.
@@ -6066,6 +6269,12 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phb
 		irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_prevDID);
 
 	if (irsp->ulpStatus) {
+
+		if (lpfc_fabric_login_reqd(phba, cmdiocb, rspiocb)) {
+			lpfc_retry_pport_discovery(phba);
+			goto out;
+		}
+
 		/* Check for retry */
 		if (lpfc_els_retry(phba, cmdiocb, rspiocb))
 			goto out;
@@ -6076,6 +6285,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phb
 		goto fdisc_failed;
 	}
 	spin_lock_irq(shost->host_lock);
+	vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
 	vport->fc_flag |= FC_FABRIC;
 	if (vport->phba->fc_topology == TOPOLOGY_LOOP)
 		vport->fc_flag |=  FC_PUBLIC_LOOP;
@@ -6103,10 +6313,14 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phb
 		lpfc_mbx_unreg_vpi(vport);
 		spin_lock_irq(shost->host_lock);
 		vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
+		if (phba->sli_rev == LPFC_SLI_REV4)
+			vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
 		spin_unlock_irq(shost->host_lock);
 	}
 
-	if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)
+	if (vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI)
+		lpfc_issue_init_vpi(vport);
+	else if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)
 		lpfc_register_new_vport(phba, vport, ndlp);
 	else
 		lpfc_do_scr_ns_plogi(phba, vport);
@@ -6678,21 +6892,27 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hb
 	struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
 	unsigned long iflag = 0;
 
-	spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, iflag);
+	spin_lock_irqsave(&phba->hbalock, iflag);
+	spin_lock(&phba->sli4_hba.abts_sgl_list_lock);
 	list_for_each_entry_safe(sglq_entry, sglq_next,
 			&phba->sli4_hba.lpfc_abts_els_sgl_list, list) {
 		if (sglq_entry->sli4_xritag == xri) {
 			list_del(&sglq_entry->list);
-			spin_unlock_irqrestore(
-					&phba->sli4_hba.abts_sgl_list_lock,
-					 iflag);
-			spin_lock_irqsave(&phba->hbalock, iflag);
-
 			list_add_tail(&sglq_entry->list,
 				&phba->sli4_hba.lpfc_sgl_list);
+			sglq_entry->state = SGL_FREED;
+			spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
 			spin_unlock_irqrestore(&phba->hbalock, iflag);
 			return;
 		}
 	}
-	spin_unlock_irqrestore(&phba->sli4_hba.abts_sgl_list_lock, iflag);
+	spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
+	sglq_entry = __lpfc_get_active_sglq(phba, xri);
+	if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) {
+		spin_unlock_irqrestore(&phba->hbalock, iflag);
+		return;
+	}
+	sglq_entry->state = SGL_XRI_ABORTED;
+	spin_unlock_irqrestore(&phba->hbalock, iflag);
+	return;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc.h linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2009 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2010 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
@@ -37,6 +37,9 @@ struct lpfc_sli2_slim;
 					   the NameServer  before giving up. */
 #define LPFC_CMD_PER_LUN	3	/* max outstanding cmds per lun */
 #define LPFC_DEFAULT_SG_SEG_CNT 64	/* sg element count per scsi cmnd */
+#define LPFC_DEFAULT_MENLO_SG_SEG_CNT 128	/* sg element count per scsi
+		cmnd for menlo needs nearly twice as for firmware
+		downloads using bsg */
 #define LPFC_DEFAULT_PROT_SG_SEG_CNT 4096 /* sg protection elements count */
 #define LPFC_MAX_SG_SEG_CNT	4096	/* sg element count per scsi cmnd */
 #define LPFC_MAX_PROT_SG_SEG_CNT 4096	/* prot sg element count per scsi cmd*/
@@ -315,6 +318,9 @@ struct lpfc_vport {
 #define FC_VPORT_NEEDS_REG_VPI	0x80000  /* Needs to have its vpi registered */
 #define FC_RSCN_DEFERRED	0x100000 /* A deferred RSCN being processed */
 #define FC_VPORT_NEEDS_INIT_VPI 0x200000 /* Need to INIT_VPI before FDISC */
+#define FC_VPORT_CVL_RCVD	0x400000 /* VLink failed due to CVL	 */
+#define FC_VFI_REGISTERED	0x800000 /* VFI is registered */
+#define FC_FDISC_COMPLETED	0x1000000/* FDISC completed */
 
 	uint32_t ct_flags;
 #define FC_CT_RFF_ID		0x1	 /* RFF_ID accepted by switch */
@@ -448,6 +454,8 @@ struct unsol_rcv_ct_ctx {
 	uint32_t ctxt_id;
 	uint32_t SID;
 	uint32_t oxid;
+	uint32_t flags;
+#define UNSOL_VALID	0x00000001
 };
 
 struct lpfc_hba {
@@ -499,7 +507,10 @@ struct lpfc_hba {
 		(struct lpfc_hba *);
 	void (*lpfc_stop_port)
 		(struct lpfc_hba *);
-
+	int (*lpfc_hba_init_link)
+		(struct lpfc_hba *);
+	int (*lpfc_hba_down_link)
+		(struct lpfc_hba *);
 
 	/* SLI4 specific HBA data structure */
 	struct lpfc_sli4_hba sli4_hba;
@@ -613,6 +624,10 @@ struct lpfc_hba {
 	uint32_t cfg_enable_bg;
 	uint32_t cfg_log_verbose;
 	uint32_t cfg_aer_support;
+	uint32_t cfg_suppress_link_up;
+#define LPFC_INITIALIZE_LINK              0	/* do normal init_link mbox */
+#define LPFC_DELAY_INIT_LINK              1	/* layered driver hold off */
+#define LPFC_DELAY_INIT_LINK_INDEFINITELY 2	/* wait, manual intervention */
 
 	lpfc_vpd_t vpd;		/* vital product data */
 
@@ -790,10 +805,13 @@ struct lpfc_hba {
 	uint16_t vlan_id;
 	struct list_head fcf_conn_rec_list;
 
-	struct mutex ct_event_mutex; /* synchronize access to ct_ev_waiters */
+	spinlock_t ct_ev_lock; /* synchronize access to ct_ev_waiters */
 	struct list_head ct_ev_waiters;
 	struct unsol_rcv_ct_ctx ct_ctx[64];
 	uint32_t ctx_idx;
+
+	uint8_t menlo_flag;	/* menlo generic flags */
+#define HBA_MENLO_SUPPORT	0x1 /* HBA supports menlo commands */
 };
 
 static inline struct Scsi_Host *
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_hbadisc.c linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_hbadisc.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_hbadisc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_hbadisc.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  *******************************************************************/
 
 #include <linux/blkdev.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/kthread.h>
 #include <linux/interrupt.h>
@@ -525,6 +526,8 @@ lpfc_work_done(struct lpfc_hba *phba)
 			spin_unlock_irq(&phba->hbalock);
 			lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
 		}
+		if (phba->fcf.fcf_flag & FCF_REDISC_EVT)
+			lpfc_sli4_fcf_redisc_event_proc(phba);
 	}
 
 	vports = lpfc_create_vport_work_array(phba);
@@ -706,6 +709,8 @@ lpfc_cleanup_rpis(struct lpfc_vport *vpo
 void
 lpfc_port_link_failure(struct lpfc_vport *vport)
 {
+	lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN);
+
 	/* Cleanup any outstanding received buffers */
 	lpfc_cleanup_rcv_buffers(vport);
 
@@ -752,12 +757,14 @@ lpfc_linkdown(struct lpfc_hba *phba)
 	lpfc_scsi_dev_block(phba);
 
 	spin_lock_irq(&phba->hbalock);
-	phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED);
+	phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_SCAN_DONE);
+	spin_unlock_irq(&phba->hbalock);
 	if (phba->link_state > LPFC_LINK_DOWN) {
 		phba->link_state = LPFC_LINK_DOWN;
+		spin_lock_irq(shost->host_lock);
 		phba->pport->fc_flag &= ~FC_LBIT;
+		spin_unlock_irq(shost->host_lock);
 	}
-	spin_unlock_irq(&phba->hbalock);
 	vports = lpfc_create_vport_work_array(phba);
 	if (vports != NULL)
 		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
@@ -1023,7 +1030,7 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *
 		return;
 	}
 	spin_lock_irqsave(&phba->hbalock, flags);
-	phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE);
+	phba->fcf.fcf_flag |= (FCF_SCAN_DONE | FCF_IN_USE);
 	phba->hba_flag &= ~FCF_DISC_INPROGRESS;
 	spin_unlock_irqrestore(&phba->hbalock, flags);
 	if (vport->port_state != LPFC_FLOGI)
@@ -1045,25 +1052,23 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *
 static uint32_t
 lpfc_fab_name_match(uint8_t *fab_name, struct fcf_record *new_fcf_record)
 {
-	if ((fab_name[0] ==
-		bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record)) &&
-	    (fab_name[1] ==
-		bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record)) &&
-	    (fab_name[2] ==
-		bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record)) &&
-	    (fab_name[3] ==
-		bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record)) &&
-	    (fab_name[4] ==
-		bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record)) &&
-	    (fab_name[5] ==
-		bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record)) &&
-	    (fab_name[6] ==
-		bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record)) &&
-	    (fab_name[7] ==
-		bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record)))
-		return 1;
-	else
+	if (fab_name[0] != bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record))
+		return 0;
+	if (fab_name[1] != bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record))
+		return 0;
+	if (fab_name[2] != bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record))
+		return 0;
+	if (fab_name[3] != bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record))
 		return 0;
+	if (fab_name[4] != bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record))
+		return 0;
+	if (fab_name[5] != bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record))
+		return 0;
+	if (fab_name[6] != bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record))
+		return 0;
+	if (fab_name[7] != bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record))
+		return 0;
+	return 1;
 }
 
 /**
@@ -1078,30 +1083,28 @@ lpfc_fab_name_match(uint8_t *fab_name, s
 static uint32_t
 lpfc_sw_name_match(uint8_t *sw_name, struct fcf_record *new_fcf_record)
 {
-	if ((sw_name[0] ==
-		bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record)) &&
-	    (sw_name[1] ==
-		bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record)) &&
-	    (sw_name[2] ==
-		bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record)) &&
-	    (sw_name[3] ==
-		bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record)) &&
-	    (sw_name[4] ==
-		bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record)) &&
-	    (sw_name[5] ==
-		bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record)) &&
-	    (sw_name[6] ==
-		bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record)) &&
-	    (sw_name[7] ==
-		bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record)))
-		return 1;
-	else
+	if (sw_name[0] != bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record))
+		return 0;
+	if (sw_name[1] != bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record))
+		return 0;
+	if (sw_name[2] != bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record))
+		return 0;
+	if (sw_name[3] != bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record))
+		return 0;
+	if (sw_name[4] != bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record))
+		return 0;
+	if (sw_name[5] != bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record))
+		return 0;
+	if (sw_name[6] != bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record))
+		return 0;
+	if (sw_name[7] != bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record))
 		return 0;
+	return 1;
 }
 
 /**
  * lpfc_mac_addr_match - Check if the fcf mac address match.
- * @phba: pointer to lpfc hba data structure.
+ * @mac_addr: pointer to mac address.
  * @new_fcf_record: pointer to fcf record.
  *
  * This routine compare the fcf record's mac address with HBA's
@@ -1109,85 +1112,115 @@ lpfc_sw_name_match(uint8_t *sw_name, str
  * returns 1 else return 0.
  **/
 static uint32_t
-lpfc_mac_addr_match(struct lpfc_hba *phba, struct fcf_record *new_fcf_record)
+lpfc_mac_addr_match(uint8_t *mac_addr, struct fcf_record *new_fcf_record)
 {
-	if ((phba->fcf.mac_addr[0] ==
-		bf_get(lpfc_fcf_record_mac_0, new_fcf_record)) &&
-	    (phba->fcf.mac_addr[1] ==
-		bf_get(lpfc_fcf_record_mac_1, new_fcf_record)) &&
-	    (phba->fcf.mac_addr[2] ==
-		bf_get(lpfc_fcf_record_mac_2, new_fcf_record)) &&
-	    (phba->fcf.mac_addr[3] ==
-		bf_get(lpfc_fcf_record_mac_3, new_fcf_record)) &&
-	    (phba->fcf.mac_addr[4] ==
-		bf_get(lpfc_fcf_record_mac_4, new_fcf_record)) &&
-	    (phba->fcf.mac_addr[5] ==
-		bf_get(lpfc_fcf_record_mac_5, new_fcf_record)))
-		return 1;
-	else
+	if (mac_addr[0] != bf_get(lpfc_fcf_record_mac_0, new_fcf_record))
+		return 0;
+	if (mac_addr[1] != bf_get(lpfc_fcf_record_mac_1, new_fcf_record))
+		return 0;
+	if (mac_addr[2] != bf_get(lpfc_fcf_record_mac_2, new_fcf_record))
 		return 0;
+	if (mac_addr[3] != bf_get(lpfc_fcf_record_mac_3, new_fcf_record))
+		return 0;
+	if (mac_addr[4] != bf_get(lpfc_fcf_record_mac_4, new_fcf_record))
+		return 0;
+	if (mac_addr[5] != bf_get(lpfc_fcf_record_mac_5, new_fcf_record))
+		return 0;
+	return 1;
+}
+
+static bool
+lpfc_vlan_id_match(uint16_t curr_vlan_id, uint16_t new_vlan_id)
+{
+	return (curr_vlan_id == new_vlan_id);
 }
 
 /**
  * lpfc_copy_fcf_record - Copy fcf information to lpfc_hba.
- * @phba: pointer to lpfc hba data structure.
+ * @fcf: pointer to driver fcf record.
  * @new_fcf_record: pointer to fcf record.
  *
  * This routine copies the FCF information from the FCF
  * record to lpfc_hba data structure.
  **/
 static void
-lpfc_copy_fcf_record(struct lpfc_hba *phba, struct fcf_record *new_fcf_record)
+lpfc_copy_fcf_record(struct lpfc_fcf_rec *fcf_rec,
+		     struct fcf_record *new_fcf_record)
 {
-	phba->fcf.fabric_name[0] =
+	/* Fabric name */
+	fcf_rec->fabric_name[0] =
 		bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record);
-	phba->fcf.fabric_name[1] =
+	fcf_rec->fabric_name[1] =
 		bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record);
-	phba->fcf.fabric_name[2] =
+	fcf_rec->fabric_name[2] =
 		bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record);
-	phba->fcf.fabric_name[3] =
+	fcf_rec->fabric_name[3] =
 		bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record);
-	phba->fcf.fabric_name[4] =
+	fcf_rec->fabric_name[4] =
 		bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record);
-	phba->fcf.fabric_name[5] =
+	fcf_rec->fabric_name[5] =
 		bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record);
-	phba->fcf.fabric_name[6] =
+	fcf_rec->fabric_name[6] =
 		bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record);
-	phba->fcf.fabric_name[7] =
+	fcf_rec->fabric_name[7] =
 		bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record);
-	phba->fcf.mac_addr[0] =
-		bf_get(lpfc_fcf_record_mac_0, new_fcf_record);
-	phba->fcf.mac_addr[1] =
-		bf_get(lpfc_fcf_record_mac_1, new_fcf_record);
-	phba->fcf.mac_addr[2] =
-		bf_get(lpfc_fcf_record_mac_2, new_fcf_record);
-	phba->fcf.mac_addr[3] =
-		bf_get(lpfc_fcf_record_mac_3, new_fcf_record);
-	phba->fcf.mac_addr[4] =
-		bf_get(lpfc_fcf_record_mac_4, new_fcf_record);
-	phba->fcf.mac_addr[5] =
-		bf_get(lpfc_fcf_record_mac_5, new_fcf_record);
-	phba->fcf.fcf_indx = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record);
-	phba->fcf.priority = new_fcf_record->fip_priority;
-	phba->fcf.switch_name[0] =
+	/* Mac address */
+	fcf_rec->mac_addr[0] = bf_get(lpfc_fcf_record_mac_0, new_fcf_record);
+	fcf_rec->mac_addr[1] = bf_get(lpfc_fcf_record_mac_1, new_fcf_record);
+	fcf_rec->mac_addr[2] = bf_get(lpfc_fcf_record_mac_2, new_fcf_record);
+	fcf_rec->mac_addr[3] = bf_get(lpfc_fcf_record_mac_3, new_fcf_record);
+	fcf_rec->mac_addr[4] = bf_get(lpfc_fcf_record_mac_4, new_fcf_record);
+	fcf_rec->mac_addr[5] = bf_get(lpfc_fcf_record_mac_5, new_fcf_record);
+	/* FCF record index */
+	fcf_rec->fcf_indx = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record);
+	/* FCF record priority */
+	fcf_rec->priority = new_fcf_record->fip_priority;
+	/* Switch name */
+	fcf_rec->switch_name[0] =
 		bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record);
-	phba->fcf.switch_name[1] =
+	fcf_rec->switch_name[1] =
 		bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record);
-	phba->fcf.switch_name[2] =
+	fcf_rec->switch_name[2] =
 		bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record);
-	phba->fcf.switch_name[3] =
+	fcf_rec->switch_name[3] =
 		bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record);
-	phba->fcf.switch_name[4] =
+	fcf_rec->switch_name[4] =
 		bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record);
-	phba->fcf.switch_name[5] =
+	fcf_rec->switch_name[5] =
 		bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record);
-	phba->fcf.switch_name[6] =
+	fcf_rec->switch_name[6] =
 		bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record);
-	phba->fcf.switch_name[7] =
+	fcf_rec->switch_name[7] =
 		bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record);
 }
 
 /**
+ * lpfc_update_fcf_record - Update driver fcf record
+ * @phba: pointer to lpfc hba data structure.
+ * @fcf_rec: pointer to driver fcf record.
+ * @new_fcf_record: pointer to hba fcf record.
+ * @addr_mode: address mode to be set to the driver fcf record.
+ * @vlan_id: vlan tag to be set to the driver fcf record.
+ * @flag: flag bits to be set to the driver fcf record.
+ *
+ * This routine updates the driver FCF record from the new HBA FCF record
+ * together with the address mode, vlan_id, and other informations. This
+ * routine is called with the host lock held.
+ **/
+static void
+__lpfc_update_fcf_record(struct lpfc_hba *phba, struct lpfc_fcf_rec *fcf_rec,
+		       struct fcf_record *new_fcf_record, uint32_t addr_mode,
+		       uint16_t vlan_id, uint32_t flag)
+{
+	/* Copy the fields from the HBA's FCF record */
+	lpfc_copy_fcf_record(fcf_rec, new_fcf_record);
+	/* Update other fields of driver FCF record */
+	fcf_rec->addr_mode = addr_mode;
+	fcf_rec->vlan_id = vlan_id;
+	fcf_rec->flag |= (flag | RECORD_VALID);
+}
+
+/**
  * lpfc_register_fcf - Register the FCF with hba.
  * @phba: pointer to lpfc hba data structure.
  *
@@ -1212,7 +1245,7 @@ lpfc_register_fcf(struct lpfc_hba *phba)
 
 	/* The FCF is already registered, start discovery */
 	if (phba->fcf.fcf_flag & FCF_REGISTERED) {
-		phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE);
+		phba->fcf.fcf_flag |= (FCF_SCAN_DONE | FCF_IN_USE);
 		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
 		spin_unlock_irqrestore(&phba->hbalock, flags);
 		if (phba->pport->port_state != LPFC_FLOGI)
@@ -1250,6 +1283,7 @@ lpfc_register_fcf(struct lpfc_hba *phba)
  * @new_fcf_record: pointer to fcf record.
  * @boot_flag: Indicates if this record used by boot bios.
  * @addr_mode: The address mode to be used by this FCF
+ * @vlan_id: The vlan id to be used as vlan tagging by this FCF.
  *
  * This routine compare the fcf record with connect list obtained from the
  * config region to decide if this FCF can be used for SAN discovery. It returns
@@ -1323,7 +1357,8 @@ lpfc_match_fcf_conn_list(struct lpfc_hba
 		return 1;
 	}
 
-	list_for_each_entry(conn_entry, &phba->fcf_conn_rec_list, list) {
+	list_for_each_entry(conn_entry,
+			    &phba->fcf_conn_rec_list, list) {
 		if (!(conn_entry->conn_rec.flags & FCFCNCT_VALID))
 			continue;
 
@@ -1447,8 +1482,6 @@ lpfc_match_fcf_conn_list(struct lpfc_hba
 int
 lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf)
 {
-	LPFC_MBOXQ_t *mbox;
-	int rc;
 	/*
 	 * If the Link is up and no FCoE events while in the
 	 * FCF discovery, no need to restart FCF discovery.
@@ -1457,84 +1490,70 @@ lpfc_check_pending_fcoe_event(struct lpf
 		(phba->fcoe_eventtag == phba->fcoe_eventtag_at_fcf_scan))
 		return 0;
 
+	lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+			"2768 Pending link or FCF event during current "
+			"handling of the previous event: link_state:x%x, "
+			"evt_tag_at_scan:x%x, evt_tag_current:x%x\n",
+			phba->link_state, phba->fcoe_eventtag_at_fcf_scan,
+			phba->fcoe_eventtag);
+
 	spin_lock_irq(&phba->hbalock);
 	phba->fcf.fcf_flag &= ~FCF_AVAILABLE;
 	spin_unlock_irq(&phba->hbalock);
 
-	if (phba->link_state >= LPFC_LINK_UP)
-		lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
-	else {
+	if (phba->link_state >= LPFC_LINK_UP) {
+		lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+				"2780 Restart FCF table scan due to "
+				"pending FCF event:evt_tag_at_scan:x%x, "
+				"evt_tag_current:x%x\n",
+				phba->fcoe_eventtag_at_fcf_scan,
+				phba->fcoe_eventtag);
+		lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
+	} else {
 		/*
 		 * Do not continue FCF discovery and clear FCF_DISC_INPROGRESS
 		 * flag
 		 */
 		spin_lock_irq(&phba->hbalock);
 		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+		phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | FCF_DISCOVERY);
 		spin_unlock_irq(&phba->hbalock);
 	}
 
+	/* Unregister the currently registered FCF if required */
 	if (unreg_fcf) {
 		spin_lock_irq(&phba->hbalock);
 		phba->fcf.fcf_flag &= ~FCF_REGISTERED;
 		spin_unlock_irq(&phba->hbalock);
-		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-		if (!mbox) {
-			lpfc_printf_log(phba, KERN_ERR,
-				LOG_DISCOVERY|LOG_MBOX,
-				"2610 UNREG_FCFI mbox allocation failed\n");
-			return 1;
-		}
-		lpfc_unreg_fcfi(mbox, phba->fcf.fcfi);
-		mbox->vport = phba->pport;
-		mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl;
-		rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
-		if (rc == MBX_NOT_FINISHED) {
-			lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
-				"2611 UNREG_FCFI issue mbox failed\n");
-			mempool_free(mbox, phba->mbox_mem_pool);
-		}
+		lpfc_sli4_unregister_fcf(phba);
 	}
-
 	return 1;
 }
 
 /**
- * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox.
+ * lpfc_sli4_fcf_rec_mbox_parse - parse non-embedded fcf record mailbox command
  * @phba: pointer to lpfc hba data structure.
  * @mboxq: pointer to mailbox object.
+ * @next_fcf_index: pointer to holder of next fcf index.
  *
- * This function iterate through all the fcf records available in
- * HBA and choose the optimal FCF record for discovery. After finding
- * the FCF for discovery it register the FCF record and kick start
- * discovery.
- * If FCF_IN_USE flag is set in currently used FCF, the routine try to
- * use a FCF record which match fabric name and mac address of the
- * currently used FCF record.
- * If the driver support only one FCF, it will try to use the FCF record
- * used by BOOT_BIOS.
+ * This routine parses the non-embedded fcf mailbox command by performing the
+ * necessarily error checking, non-embedded read FCF record mailbox command
+ * SGE parsing, and endianness swapping.
+ *
+ * Returns the pointer to the new FCF record in the non-embedded mailbox
+ * command DMA memory if successfully, other NULL.
  */
-void
-lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+static struct fcf_record *
+lpfc_sli4_fcf_rec_mbox_parse(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq,
+			     uint16_t *next_fcf_index)
 {
 	void *virt_addr;
 	dma_addr_t phys_addr;
-	uint8_t *bytep;
 	struct lpfc_mbx_sge sge;
 	struct lpfc_mbx_read_fcf_tbl *read_fcf;
 	uint32_t shdr_status, shdr_add_status;
 	union lpfc_sli4_cfg_shdr *shdr;
 	struct fcf_record *new_fcf_record;
-	int rc;
-	uint32_t boot_flag, addr_mode;
-	uint32_t next_fcf_index;
-	unsigned long flags;
-	uint16_t vlan_id;
-
-	/* If there is pending FCoE event restart FCF table scan */
-	if (lpfc_check_pending_fcoe_event(phba, 0)) {
-		lpfc_sli4_mbox_cmd_free(phba, mboxq);
-		return;
-	}
 
 	/* Get the first SGE entry from the non-embedded DMA memory. This
 	 * routine only uses a single SGE.
@@ -1545,140 +1564,359 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpf
 		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
 				"2524 Failed to get the non-embedded SGE "
 				"virtual address\n");
-		goto out;
+		return NULL;
 	}
 	virt_addr = mboxq->sge_array->addr[0];
 
 	shdr = (union lpfc_sli4_cfg_shdr *)virt_addr;
 	shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
-	shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
-				 &shdr->response);
-	/*
-	 * The FCF Record was read and there is no reason for the driver
-	 * to maintain the FCF record data or memory. Instead, just need
-	 * to book keeping the FCFIs can be used.
-	 */
+	shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
 	if (shdr_status || shdr_add_status) {
-		if (shdr_status == STATUS_FCF_TABLE_EMPTY) {
-			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+		if (shdr_status == STATUS_FCF_TABLE_EMPTY)
+			lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
 					"2726 READ_FCF_RECORD Indicates empty "
 					"FCF table.\n");
-		} else {
-			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+		else
+			lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
 					"2521 READ_FCF_RECORD mailbox failed "
-					"with status x%x add_status x%x, mbx\n",
-					shdr_status, shdr_add_status);
-		}
-		goto out;
+					"with status x%x add_status x%x, "
+					"mbx\n", shdr_status, shdr_add_status);
+		return NULL;
 	}
-	/* Interpreting the returned information of FCF records */
+
+	/* Interpreting the returned information of the FCF record */
 	read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr;
 	lpfc_sli_pcimem_bcopy(read_fcf, read_fcf,
 			      sizeof(struct lpfc_mbx_read_fcf_tbl));
-	next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf);
-
+	*next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf);
 	new_fcf_record = (struct fcf_record *)(virt_addr +
 			  sizeof(struct lpfc_mbx_read_fcf_tbl));
 	lpfc_sli_pcimem_bcopy(new_fcf_record, new_fcf_record,
 			      sizeof(struct fcf_record));
-	bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr);
 
-	rc = lpfc_match_fcf_conn_list(phba, new_fcf_record,
-				      &boot_flag, &addr_mode,
-					&vlan_id);
+	return new_fcf_record;
+}
+
+/**
+ * lpfc_sli4_log_fcf_record_info - Log the information of a fcf record
+ * @phba: pointer to lpfc hba data structure.
+ * @fcf_record: pointer to the fcf record.
+ * @vlan_id: the lowest vlan identifier associated to this fcf record.
+ * @next_fcf_index: the index to the next fcf record in hba's fcf table.
+ *
+ * This routine logs the detailed FCF record if the LOG_FIP loggin is
+ * enabled.
+ **/
+static void
+lpfc_sli4_log_fcf_record_info(struct lpfc_hba *phba,
+			      struct fcf_record *fcf_record,
+			      uint16_t vlan_id,
+			      uint16_t next_fcf_index)
+{
+	lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+			"2764 READ_FCF_RECORD:\n"
+			"\tFCF_Index     : x%x\n"
+			"\tFCF_Avail     : x%x\n"
+			"\tFCF_Valid     : x%x\n"
+			"\tFIP_Priority  : x%x\n"
+			"\tMAC_Provider  : x%x\n"
+			"\tLowest VLANID : x%x\n"
+			"\tFCF_MAC Addr  : x%x:%x:%x:%x:%x:%x\n"
+			"\tFabric_Name   : x%x:%x:%x:%x:%x:%x:%x:%x\n"
+			"\tSwitch_Name   : x%x:%x:%x:%x:%x:%x:%x:%x\n"
+			"\tNext_FCF_Index: x%x\n",
+			bf_get(lpfc_fcf_record_fcf_index, fcf_record),
+			bf_get(lpfc_fcf_record_fcf_avail, fcf_record),
+			bf_get(lpfc_fcf_record_fcf_valid, fcf_record),
+			fcf_record->fip_priority,
+			bf_get(lpfc_fcf_record_mac_addr_prov, fcf_record),
+			vlan_id,
+			bf_get(lpfc_fcf_record_mac_0, fcf_record),
+			bf_get(lpfc_fcf_record_mac_1, fcf_record),
+			bf_get(lpfc_fcf_record_mac_2, fcf_record),
+			bf_get(lpfc_fcf_record_mac_3, fcf_record),
+			bf_get(lpfc_fcf_record_mac_4, fcf_record),
+			bf_get(lpfc_fcf_record_mac_5, fcf_record),
+			bf_get(lpfc_fcf_record_fab_name_0, fcf_record),
+			bf_get(lpfc_fcf_record_fab_name_1, fcf_record),
+			bf_get(lpfc_fcf_record_fab_name_2, fcf_record),
+			bf_get(lpfc_fcf_record_fab_name_3, fcf_record),
+			bf_get(lpfc_fcf_record_fab_name_4, fcf_record),
+			bf_get(lpfc_fcf_record_fab_name_5, fcf_record),
+			bf_get(lpfc_fcf_record_fab_name_6, fcf_record),
+			bf_get(lpfc_fcf_record_fab_name_7, fcf_record),
+			bf_get(lpfc_fcf_record_switch_name_0, fcf_record),
+			bf_get(lpfc_fcf_record_switch_name_1, fcf_record),
+			bf_get(lpfc_fcf_record_switch_name_2, fcf_record),
+			bf_get(lpfc_fcf_record_switch_name_3, fcf_record),
+			bf_get(lpfc_fcf_record_switch_name_4, fcf_record),
+			bf_get(lpfc_fcf_record_switch_name_5, fcf_record),
+			bf_get(lpfc_fcf_record_switch_name_6, fcf_record),
+			bf_get(lpfc_fcf_record_switch_name_7, fcf_record),
+			next_fcf_index);
+}
+
+/**
+ * lpfc_mbx_cmpl_fcf_scan_read_fcf_rec - fcf scan read_fcf mbox cmpl handler.
+ * @phba: pointer to lpfc hba data structure.
+ * @mboxq: pointer to mailbox object.
+ *
+ * This function iterates through all the fcf records available in
+ * HBA and chooses the optimal FCF record for discovery. After finding
+ * the FCF for discovery it registers the FCF record and kicks start
+ * discovery.
+ * If FCF_IN_USE flag is set in currently used FCF, the routine tries to
+ * use an FCF record which matches fabric name and mac address of the
+ * currently used FCF record.
+ * If the driver supports only one FCF, it will try to use the FCF record
+ * used by BOOT_BIOS.
+ */
+void
+lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+	struct fcf_record *new_fcf_record;
+	uint32_t boot_flag, addr_mode;
+	uint16_t fcf_index, next_fcf_index;
+	struct lpfc_fcf_rec *fcf_rec = NULL;
+	uint16_t vlan_id;
+	int rc;
+
+	/* If there is pending FCoE event restart FCF table scan */
+	if (lpfc_check_pending_fcoe_event(phba, 0)) {
+		lpfc_sli4_mbox_cmd_free(phba, mboxq);
+		return;
+	}
+
+	/* Parse the FCF record from the non-embedded mailbox command */
+	new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq,
+						      &next_fcf_index);
+	if (!new_fcf_record) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
+				"2765 Mailbox command READ_FCF_RECORD "
+				"failed to retrieve a FCF record.\n");
+		/* Let next new FCF event trigger fast failover */
+		spin_lock_irq(&phba->hbalock);
+		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+		spin_unlock_irq(&phba->hbalock);
+		lpfc_sli4_mbox_cmd_free(phba, mboxq);
+		return;
+	}
+
+	/* Check the FCF record against the connection list */
+	rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag,
+				      &addr_mode, &vlan_id);
+
+	/* Log the FCF record information if turned on */
+	lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id,
+				      next_fcf_index);
+
 	/*
 	 * If the fcf record does not match with connect list entries
-	 * read the next entry.
+	 * read the next entry; otherwise, this is an eligible FCF
+	 * record for round robin FCF failover.
 	 */
-	if (!rc)
+	if (!rc) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
+				"2781 FCF record fcf_index:x%x failed FCF "
+				"connection list check, fcf_avail:x%x, "
+				"fcf_valid:x%x\n",
+				bf_get(lpfc_fcf_record_fcf_index,
+				       new_fcf_record),
+				bf_get(lpfc_fcf_record_fcf_avail,
+				       new_fcf_record),
+				bf_get(lpfc_fcf_record_fcf_valid,
+				       new_fcf_record));
 		goto read_next_fcf;
+	} else {
+		fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record);
+		rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index);
+		if (rc)
+			goto read_next_fcf;
+	}
+
 	/*
 	 * If this is not the first FCF discovery of the HBA, use last
-	 * FCF record for the discovery.
+	 * FCF record for the discovery. The condition that a rescan
+	 * matches the in-use FCF record: fabric name, switch name, mac
+	 * address, and vlan_id.
 	 */
-	spin_lock_irqsave(&phba->hbalock, flags);
+	spin_lock_irq(&phba->hbalock);
 	if (phba->fcf.fcf_flag & FCF_IN_USE) {
-		if (lpfc_fab_name_match(phba->fcf.fabric_name,
+		if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name,
 					new_fcf_record) &&
-		    lpfc_sw_name_match(phba->fcf.switch_name,
+		    lpfc_sw_name_match(phba->fcf.current_rec.switch_name,
 					new_fcf_record) &&
-		    lpfc_mac_addr_match(phba, new_fcf_record)) {
+		    lpfc_mac_addr_match(phba->fcf.current_rec.mac_addr,
+					new_fcf_record) &&
+		    lpfc_vlan_id_match(phba->fcf.current_rec.vlan_id,
+					vlan_id)) {
 			phba->fcf.fcf_flag |= FCF_AVAILABLE;
-			spin_unlock_irqrestore(&phba->hbalock, flags);
+			if (phba->fcf.fcf_flag & FCF_REDISC_PEND)
+				/* Stop FCF redisc wait timer if pending */
+				__lpfc_sli4_stop_fcf_redisc_wait_timer(phba);
+			else if (phba->fcf.fcf_flag & FCF_REDISC_FOV)
+				/* If in fast failover, mark it's completed */
+				phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV |
+							FCF_DISCOVERY);
+			spin_unlock_irq(&phba->hbalock);
 			goto out;
 		}
-		spin_unlock_irqrestore(&phba->hbalock, flags);
-		goto read_next_fcf;
+		/*
+		 * Read next FCF record from HBA searching for the matching
+		 * with in-use record only if not during the fast failover
+		 * period. In case of fast failover period, it shall try to
+		 * determine whether the FCF record just read should be the
+		 * next candidate.
+		 */
+		if (!(phba->fcf.fcf_flag & FCF_REDISC_FOV)) {
+			spin_unlock_irq(&phba->hbalock);
+			goto read_next_fcf;
+		}
 	}
+	/*
+	 * Update on failover FCF record only if it's in FCF fast-failover
+	 * period; otherwise, update on current FCF record.
+	 */
+	if (phba->fcf.fcf_flag & FCF_REDISC_FOV)
+		fcf_rec = &phba->fcf.failover_rec;
+	else
+		fcf_rec = &phba->fcf.current_rec;
+
 	if (phba->fcf.fcf_flag & FCF_AVAILABLE) {
 		/*
-		 * If the current FCF record does not have boot flag
-		 * set and new fcf record has boot flag set, use the
-		 * new fcf record.
+		 * If the driver FCF record does not have boot flag
+		 * set and new hba fcf record has boot flag set, use
+		 * the new hba fcf record.
 		 */
-		if (boot_flag && !(phba->fcf.fcf_flag & FCF_BOOT_ENABLE)) {
-			/* Use this FCF record */
-			lpfc_copy_fcf_record(phba, new_fcf_record);
-			phba->fcf.addr_mode = addr_mode;
-			phba->fcf.fcf_flag |= FCF_BOOT_ENABLE;
-			if (vlan_id != 0xFFFF) {
-				phba->fcf.fcf_flag |= FCF_VALID_VLAN;
-				phba->fcf.vlan_id = vlan_id;
-			}
-			spin_unlock_irqrestore(&phba->hbalock, flags);
+		if (boot_flag && !(fcf_rec->flag & BOOT_ENABLE)) {
+			/* Choose this FCF record */
+			__lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record,
+					addr_mode, vlan_id, BOOT_ENABLE);
+			spin_unlock_irq(&phba->hbalock);
 			goto read_next_fcf;
 		}
 		/*
-		 * If the current FCF record has boot flag set and the
-		 * new FCF record does not have boot flag, read the next
-		 * FCF record.
+		 * If the driver FCF record has boot flag set and the
+		 * new hba FCF record does not have boot flag, read
+		 * the next FCF record.
 		 */
-		if (!boot_flag && (phba->fcf.fcf_flag & FCF_BOOT_ENABLE)) {
-			spin_unlock_irqrestore(&phba->hbalock, flags);
+		if (!boot_flag && (fcf_rec->flag & BOOT_ENABLE)) {
+			spin_unlock_irq(&phba->hbalock);
 			goto read_next_fcf;
 		}
 		/*
-		 * If there is a record with lower priority value for
-		 * the current FCF, use that record.
+		 * If the new hba FCF record has lower priority value
+		 * than the driver FCF record, use the new record.
 		 */
-		if (lpfc_fab_name_match(phba->fcf.fabric_name,
-					new_fcf_record) &&
-		    (new_fcf_record->fip_priority < phba->fcf.priority)) {
-			/* Use this FCF record */
-			lpfc_copy_fcf_record(phba, new_fcf_record);
-			phba->fcf.addr_mode = addr_mode;
-			if (vlan_id != 0xFFFF) {
-				phba->fcf.fcf_flag |= FCF_VALID_VLAN;
-				phba->fcf.vlan_id = vlan_id;
-			}
-			spin_unlock_irqrestore(&phba->hbalock, flags);
-			goto read_next_fcf;
+		if (new_fcf_record->fip_priority < fcf_rec->priority) {
+			/* Choose this FCF record */
+			__lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record,
+					addr_mode, vlan_id, 0);
 		}
-		spin_unlock_irqrestore(&phba->hbalock, flags);
+		spin_unlock_irq(&phba->hbalock);
 		goto read_next_fcf;
 	}
 	/*
-	 * This is the first available FCF record, use this
-	 * record.
+	 * This is the first suitable FCF record, choose this record for
+	 * initial best-fit FCF.
 	 */
-	lpfc_copy_fcf_record(phba, new_fcf_record);
-	phba->fcf.addr_mode = addr_mode;
-	if (boot_flag)
-		phba->fcf.fcf_flag |= FCF_BOOT_ENABLE;
-	phba->fcf.fcf_flag |= FCF_AVAILABLE;
-	if (vlan_id != 0xFFFF) {
-		phba->fcf.fcf_flag |= FCF_VALID_VLAN;
-		phba->fcf.vlan_id = vlan_id;
+	if (fcf_rec) {
+		__lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record,
+					 addr_mode, vlan_id, (boot_flag ?
+					 BOOT_ENABLE : 0));
+		phba->fcf.fcf_flag |= FCF_AVAILABLE;
 	}
-	spin_unlock_irqrestore(&phba->hbalock, flags);
+	spin_unlock_irq(&phba->hbalock);
 	goto read_next_fcf;
 
 read_next_fcf:
 	lpfc_sli4_mbox_cmd_free(phba, mboxq);
-	if (next_fcf_index == LPFC_FCOE_FCF_NEXT_NONE || next_fcf_index == 0)
-		lpfc_register_fcf(phba);
-	else
-		lpfc_sli4_read_fcf_record(phba, next_fcf_index);
+	if (next_fcf_index == LPFC_FCOE_FCF_NEXT_NONE || next_fcf_index == 0) {
+		if (phba->fcf.fcf_flag & FCF_REDISC_FOV) {
+			/*
+			 * Case of FCF fast failover scan
+			 */
+
+			/*
+			 * It has not found any suitable FCF record, cancel
+			 * FCF scan inprogress, and do nothing
+			 */
+			if (!(phba->fcf.failover_rec.flag & RECORD_VALID)) {
+				lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
+					       "2782 No suitable FCF record "
+					       "found during this round of "
+					       "post FCF rediscovery scan: "
+					       "fcf_evt_tag:x%x, fcf_index: "
+					       "x%x\n",
+					       phba->fcoe_eventtag_at_fcf_scan,
+					       bf_get(lpfc_fcf_record_fcf_index,
+						      new_fcf_record));
+				/*
+				 * Let next new FCF event trigger fast
+				 * failover
+				 */
+				spin_lock_irq(&phba->hbalock);
+				phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+				spin_unlock_irq(&phba->hbalock);
+				return;
+			}
+			/*
+			 * It has found a suitable FCF record that is not
+			 * the same as in-use FCF record, unregister the
+			 * in-use FCF record, replace the in-use FCF record
+			 * with the new FCF record, mark FCF fast failover
+			 * completed, and then start register the new FCF
+			 * record.
+			 */
+
+			/* Unregister the current in-use FCF record */
+			lpfc_unregister_fcf(phba);
+
+			/* Replace in-use record with the new record */
+			memcpy(&phba->fcf.current_rec,
+			       &phba->fcf.failover_rec,
+			       sizeof(struct lpfc_fcf_rec));
+			/* mark the FCF fast failover completed */
+			spin_lock_irq(&phba->hbalock);
+			phba->fcf.fcf_flag &= ~FCF_REDISC_FOV;
+			spin_unlock_irq(&phba->hbalock);
+			/*
+			 * Set up the initial registered FCF index for FLOGI
+			 * round robin FCF failover.
+			 */
+			phba->fcf.fcf_rr_init_indx =
+					phba->fcf.failover_rec.fcf_indx;
+			/* Register to the new FCF record */
+			lpfc_register_fcf(phba);
+		} else {
+			/*
+			 * In case of transaction period to fast FCF failover,
+			 * do nothing when search to the end of the FCF table.
+			 */
+			if ((phba->fcf.fcf_flag & FCF_REDISC_EVT) ||
+			    (phba->fcf.fcf_flag & FCF_REDISC_PEND))
+				return;
+			/*
+			 * Otherwise, initial scan or post linkdown rescan,
+			 * register with the best FCF record found so far
+			 * through the FCF scanning process.
+			 */
+
+			/* mark the initial FCF discovery completed */
+			spin_lock_irq(&phba->hbalock);
+			phba->fcf.fcf_flag &= ~FCF_INIT_DISC;
+			spin_unlock_irq(&phba->hbalock);
+			/*
+			 * Set up the initial registered FCF index for FLOGI
+			 * round robin FCF failover
+			 */
+			phba->fcf.fcf_rr_init_indx =
+					phba->fcf.current_rec.fcf_indx;
+			/* Register to the new FCF record */
+			lpfc_register_fcf(phba);
+		}
+	} else
+		lpfc_sli4_fcf_scan_read_fcf_rec(phba, next_fcf_index);
 	return;
 
 out:
@@ -1689,16 +1927,154 @@ out:
 }
 
 /**
+ * lpfc_mbx_cmpl_fcf_rr_read_fcf_rec - fcf round robin read_fcf mbox cmpl hdler
+ * @phba: pointer to lpfc hba data structure.
+ * @mboxq: pointer to mailbox object.
+ *
+ * This is the callback function for FLOGI failure round robin FCF failover
+ * read FCF record mailbox command from the eligible FCF record bmask for
+ * performing the failover. If the FCF read back is not valid/available, it
+ * fails through to retrying FLOGI to the currently registered FCF again.
+ * Otherwise, if the FCF read back is valid and available, it will set the
+ * newly read FCF record to the failover FCF record, unregister currently
+ * registered FCF record, copy the failover FCF record to the current
+ * FCF record, and then register the current FCF record before proceeding
+ * to trying FLOGI on the new failover FCF.
+ */
+void
+lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+	struct fcf_record *new_fcf_record;
+	uint32_t boot_flag, addr_mode;
+	uint16_t next_fcf_index;
+	uint16_t current_fcf_index;
+	uint16_t vlan_id;
+
+	/* If link state is not up, stop the round robin failover process */
+	if (phba->link_state < LPFC_LINK_UP) {
+		spin_lock_irq(&phba->hbalock);
+		phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+		spin_unlock_irq(&phba->hbalock);
+		lpfc_sli4_mbox_cmd_free(phba, mboxq);
+		return;
+	}
+
+	/* Parse the FCF record from the non-embedded mailbox command */
+	new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq,
+						      &next_fcf_index);
+	if (!new_fcf_record) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
+				"2766 Mailbox command READ_FCF_RECORD "
+				"failed to retrieve a FCF record.\n");
+		goto out;
+	}
+
+	/* Get the needed parameters from FCF record */
+	lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag,
+				 &addr_mode, &vlan_id);
+
+	/* Log the FCF record information if turned on */
+	lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id,
+				      next_fcf_index);
+
+	/* Upload new FCF record to the failover FCF record */
+	spin_lock_irq(&phba->hbalock);
+	__lpfc_update_fcf_record(phba, &phba->fcf.failover_rec,
+				 new_fcf_record, addr_mode, vlan_id,
+				 (boot_flag ? BOOT_ENABLE : 0));
+	spin_unlock_irq(&phba->hbalock);
+
+	current_fcf_index = phba->fcf.current_rec.fcf_indx;
+
+	/* Unregister the current in-use FCF record */
+	lpfc_unregister_fcf(phba);
+
+	/* Replace in-use record with the new record */
+	memcpy(&phba->fcf.current_rec, &phba->fcf.failover_rec,
+	       sizeof(struct lpfc_fcf_rec));
+
+	lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+			"2783 FLOGI round robin FCF failover from FCF "
+			"(index:x%x) to FCF (index:x%x).\n",
+			current_fcf_index,
+			bf_get(lpfc_fcf_record_fcf_index, new_fcf_record));
+
+out:
+	lpfc_sli4_mbox_cmd_free(phba, mboxq);
+	lpfc_register_fcf(phba);
+}
+
+/**
+ * lpfc_mbx_cmpl_read_fcf_rec - read fcf completion handler.
+ * @phba: pointer to lpfc hba data structure.
+ * @mboxq: pointer to mailbox object.
+ *
+ * This is the callback function of read FCF record mailbox command for
+ * updating the eligible FCF bmask for FLOGI failure round robin FCF
+ * failover when a new FCF event happened. If the FCF read back is
+ * valid/available and it passes the connection list check, it updates
+ * the bmask for the eligible FCF record for round robin failover.
+ */
+void
+lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+	struct fcf_record *new_fcf_record;
+	uint32_t boot_flag, addr_mode;
+	uint16_t fcf_index, next_fcf_index;
+	uint16_t vlan_id;
+	int rc;
+
+	/* If link state is not up, no need to proceed */
+	if (phba->link_state < LPFC_LINK_UP)
+		goto out;
+
+	/* If FCF discovery period is over, no need to proceed */
+	if (phba->fcf.fcf_flag & FCF_DISCOVERY)
+		goto out;
+
+	/* Parse the FCF record from the non-embedded mailbox command */
+	new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq,
+						      &next_fcf_index);
+	if (!new_fcf_record) {
+		lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+				"2767 Mailbox command READ_FCF_RECORD "
+				"failed to retrieve a FCF record.\n");
+		goto out;
+	}
+
+	/* Check the connection list for eligibility */
+	rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag,
+				      &addr_mode, &vlan_id);
+
+	/* Log the FCF record information if turned on */
+	lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id,
+				      next_fcf_index);
+
+	if (!rc)
+		goto out;
+
+	/* Update the eligible FCF record index bmask */
+	fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record);
+	rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index);
+
+out:
+	lpfc_sli4_mbox_cmd_free(phba, mboxq);
+}
+
+/**
  * lpfc_init_vpi_cmpl - Completion handler for init_vpi mbox command.
  * @phba: pointer to lpfc hba data structure.
  * @mboxq: pointer to mailbox data structure.
  *
  * This function handles completion of init vpi mailbox command.
  */
-static void
+void
 lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
 {
 	struct lpfc_vport *vport = mboxq->vport;
+	struct lpfc_nodelist *ndlp;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
 	if (mboxq->u.mb.mbxStatus) {
 		lpfc_printf_vlog(vport, KERN_ERR,
 				LOG_MBOX,
@@ -1708,9 +2084,23 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba
 		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
 		return;
 	}
-	spin_lock_irq(&phba->hbalock);
+	spin_lock_irq(shost->host_lock);
 	vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI;
-	spin_unlock_irq(&phba->hbalock);
+	spin_unlock_irq(shost->host_lock);
+
+	/* If this port is physical port or FDISC is done, do reg_vpi */
+	if ((phba->pport == vport) || (vport->port_state == LPFC_FDISC)) {
+			ndlp = lpfc_findnode_did(vport, Fabric_DID);
+			if (!ndlp)
+				lpfc_printf_vlog(vport, KERN_ERR,
+					LOG_DISCOVERY,
+					"2731 Cannot find fabric "
+					"controller node\n");
+			else
+				lpfc_register_new_vport(phba, vport, ndlp);
+			mempool_free(mboxq, phba->mbox_mem_pool);
+			return;
+	}
 
 	if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
 		lpfc_initial_fdisc(vport);
@@ -1719,10 +2109,42 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
 				 "2606 No NPIV Fabric support\n");
 	}
+	mempool_free(mboxq, phba->mbox_mem_pool);
 	return;
 }
 
 /**
+ * lpfc_issue_init_vpi - Issue init_vpi mailbox command.
+ * @vport: pointer to lpfc_vport data structure.
+ *
+ * This function issue a init_vpi mailbox command to initialize
+ * VPI for the vport.
+ */
+void
+lpfc_issue_init_vpi(struct lpfc_vport *vport)
+{
+	LPFC_MBOXQ_t *mboxq;
+	int rc;
+
+	mboxq = mempool_alloc(vport->phba->mbox_mem_pool, GFP_KERNEL);
+	if (!mboxq) {
+		lpfc_printf_vlog(vport, KERN_ERR,
+			LOG_MBOX, "2607 Failed to allocate "
+			"init_vpi mailbox\n");
+		return;
+	}
+	lpfc_init_vpi(vport->phba, mboxq, vport->vpi);
+	mboxq->vport = vport;
+	mboxq->mbox_cmpl = lpfc_init_vpi_cmpl;
+	rc = lpfc_sli_issue_mbox(vport->phba, mboxq, MBX_NOWAIT);
+	if (rc == MBX_NOT_FINISHED) {
+		lpfc_printf_vlog(vport, KERN_ERR,
+			LOG_MBOX, "2608 Failed to issue init_vpi mailbox\n");
+		mempool_free(mboxq, vport->phba->mbox_mem_pool);
+	}
+}
+
+/**
  * lpfc_start_fdiscs - send fdiscs for each vports on this port.
  * @phba: pointer to lpfc hba data structure.
  *
@@ -1734,8 +2156,6 @@ lpfc_start_fdiscs(struct lpfc_hba *phba)
 {
 	struct lpfc_vport **vports;
 	int i;
-	LPFC_MBOXQ_t *mboxq;
-	int rc;
 
 	vports = lpfc_create_vport_work_array(phba);
 	if (vports != NULL) {
@@ -1754,26 +2174,7 @@ lpfc_start_fdiscs(struct lpfc_hba *phba)
 				continue;
 			}
 			if (vports[i]->fc_flag & FC_VPORT_NEEDS_INIT_VPI) {
-				mboxq = mempool_alloc(phba->mbox_mem_pool,
-					GFP_KERNEL);
-				if (!mboxq) {
-					lpfc_printf_vlog(vports[i], KERN_ERR,
-					LOG_MBOX, "2607 Failed to allocate "
-					"init_vpi mailbox\n");
-					continue;
-				}
-				lpfc_init_vpi(phba, mboxq, vports[i]->vpi);
-				mboxq->vport = vports[i];
-				mboxq->mbox_cmpl = lpfc_init_vpi_cmpl;
-				rc = lpfc_sli_issue_mbox(phba, mboxq,
-					MBX_NOWAIT);
-				if (rc == MBX_NOT_FINISHED) {
-					lpfc_printf_vlog(vports[i], KERN_ERR,
-					LOG_MBOX, "2608 Failed to issue "
-					"init_vpi mailbox\n");
-					mempool_free(mboxq,
-						phba->mbox_mem_pool);
-				}
+				lpfc_issue_init_vpi(vports[i]);
 				continue;
 			}
 			if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
@@ -1796,6 +2197,7 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *p
 {
 	struct lpfc_dmabuf *dmabuf = mboxq->context1;
 	struct lpfc_vport *vport = mboxq->vport;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 
 	if (mboxq->u.mb.mbxStatus) {
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
@@ -1813,7 +2215,11 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *p
 		goto fail_free_mem;
 	}
 	/* The VPI is implicitly registered when the VFI is registered */
+	spin_lock_irq(shost->host_lock);
 	vport->vpi_state |= LPFC_VPI_REGISTERED;
+	vport->fc_flag |= FC_VFI_REGISTERED;
+	vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
+	spin_unlock_irq(shost->host_lock);
 
 	if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
 		lpfc_start_fdiscs(phba);
@@ -1887,8 +2293,6 @@ lpfc_mbx_process_link_up(struct lpfc_hba
 	int rc;
 	struct fcf_record *fcf_record;
 
-	sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-
 	spin_lock_irq(&phba->hbalock);
 	switch (la->UlnkSpeed) {
 	case LA_1GHZ_LINK:
@@ -1980,18 +2384,24 @@ lpfc_mbx_process_link_up(struct lpfc_hba
 	spin_unlock_irq(&phba->hbalock);
 
 	lpfc_linkup(phba);
-	if (sparam_mbox) {
-		lpfc_read_sparam(phba, sparam_mbox, 0);
-		sparam_mbox->vport = vport;
-		sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
-		rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT);
-		if (rc == MBX_NOT_FINISHED) {
-			mp = (struct lpfc_dmabuf *) sparam_mbox->context1;
-			lpfc_mbuf_free(phba, mp->virt, mp->phys);
-			kfree(mp);
-			mempool_free(sparam_mbox, phba->mbox_mem_pool);
-			goto out;
-		}
+	sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!sparam_mbox)
+		goto out;
+
+	rc = lpfc_read_sparam(phba, sparam_mbox, 0);
+	if (rc) {
+		mempool_free(sparam_mbox, phba->mbox_mem_pool);
+		goto out;
+	}
+	sparam_mbox->vport = vport;
+	sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
+	rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT);
+	if (rc == MBX_NOT_FINISHED) {
+		mp = (struct lpfc_dmabuf *) sparam_mbox->context1;
+		lpfc_mbuf_free(phba, mp->virt, mp->phys);
+		kfree(mp);
+		mempool_free(sparam_mbox, phba->mbox_mem_pool);
+		goto out;
 	}
 
 	if (!(phba->hba_flag & HBA_FCOE_SUPPORT)) {
@@ -2049,11 +2459,20 @@ lpfc_mbx_process_link_up(struct lpfc_hba
 			spin_unlock_irq(&phba->hbalock);
 			return;
 		}
+		/* This is the initial FCF discovery scan */
+		phba->fcf.fcf_flag |= FCF_INIT_DISC;
 		spin_unlock_irq(&phba->hbalock);
-		rc = lpfc_sli4_read_fcf_record(phba,
-					LPFC_FCOE_FCF_GET_FIRST);
-		if (rc)
+		lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+				"2778 Start FCF table scan at linkup\n");
+
+		rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba,
+						     LPFC_FCOE_FCF_GET_FIRST);
+		if (rc) {
+			spin_lock_irq(&phba->hbalock);
+			phba->fcf.fcf_flag &= ~FCF_INIT_DISC;
+			spin_unlock_irq(&phba->hbalock);
 			goto out;
+		}
 	}
 
 	return;
@@ -2139,10 +2558,12 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *p
 	}
 
 	phba->fc_eventTag = la->eventTag;
+	spin_lock_irq(&phba->hbalock);
 	if (la->mm)
 		phba->sli.sli_flag |= LPFC_MENLO_MAINT;
 	else
 		phba->sli.sli_flag &= ~LPFC_MENLO_MAINT;
+	spin_unlock_irq(&phba->hbalock);
 
 	phba->link_events++;
 	if (la->attType == AT_LINK_UP && (!la->mm)) {
@@ -2271,10 +2692,10 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba
 				 mb->mbxStatus);
 		break;
 	}
-	spin_lock_irq(&phba->hbalock);
+	spin_lock_irq(shost->host_lock);
 	vport->vpi_state &= ~LPFC_VPI_REGISTERED;
 	vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
-	spin_unlock_irq(&phba->hbalock);
+	spin_unlock_irq(shost->host_lock);
 	vport->unreg_vpi_cmpl = VPORT_OK;
 	mempool_free(pmb, phba->mbox_mem_pool);
 	/*
@@ -2332,7 +2753,10 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *p
 		goto out;
 	}
 
+	spin_lock_irq(shost->host_lock);
 	vport->vpi_state |= LPFC_VPI_REGISTERED;
+	vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
+	spin_unlock_irq(shost->host_lock);
 	vport->num_disc_nodes = 0;
 	/* go thru NPR list and issue ELS PLOGIs */
 	if (vport->fc_npr_cnt)
@@ -3218,6 +3642,38 @@ lpfc_unreg_rpi(struct lpfc_vport *vport,
 	return 0;
 }
 
+/**
+ * lpfc_unreg_hba_rpis - Unregister rpis registered to the hba.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked to unregister all the currently registered RPIs
+ * to the HBA.
+ **/
+void
+lpfc_unreg_hba_rpis(struct lpfc_hba *phba)
+{
+	struct lpfc_vport **vports;
+	struct lpfc_nodelist *ndlp;
+	struct Scsi_Host *shost;
+	int i;
+
+	vports = lpfc_create_vport_work_array(phba);
+	for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
+		shost = lpfc_shost_from_vport(vports[i]);
+		spin_lock_irq(shost->host_lock);
+		list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) {
+			if (ndlp->nlp_flag & NLP_RPI_VALID) {
+				/* The mempool_alloc might sleep */
+				spin_unlock_irq(shost->host_lock);
+				lpfc_unreg_rpi(vports[i], ndlp);
+				spin_lock_irq(shost->host_lock);
+			}
+		}
+		spin_unlock_irq(shost->host_lock);
+	}
+	lpfc_destroy_vport_work_array(phba, vports);
+}
+
 void
 lpfc_unreg_all_rpis(struct lpfc_vport *vport)
 {
@@ -4448,63 +4904,56 @@ lpfc_unregister_fcfi_cmpl(struct lpfc_hb
 }
 
 /**
- * lpfc_unregister_unused_fcf - Unregister FCF if all devices are disconnected.
+ * lpfc_unregister_fcf_prep - Unregister fcf record preparation
  * @phba: Pointer to hba context object.
  *
- * This function check if there are any connected remote port for the FCF and
- * if all the devices are disconnected, this function unregister FCFI.
- * This function also tries to use another FCF for discovery.
+ * This function prepare the HBA for unregistering the currently registered
+ * FCF from the HBA. It performs unregistering, in order, RPIs, VPIs, and
+ * VFIs.
  */
-void
-lpfc_unregister_unused_fcf(struct lpfc_hba *phba)
+int
+lpfc_unregister_fcf_prep(struct lpfc_hba *phba)
 {
 	LPFC_MBOXQ_t *mbox;
-	int rc;
 	struct lpfc_vport **vports;
-	int i;
-
-	spin_lock_irq(&phba->hbalock);
-	/*
-	 * If HBA is not running in FIP mode or
-	 * If HBA does not support FCoE or
-	 * If FCF is not registered.
-	 * do nothing.
-	 */
-	if (!(phba->hba_flag & HBA_FCOE_SUPPORT) ||
-		!(phba->fcf.fcf_flag & FCF_REGISTERED) ||
-		(!(phba->hba_flag & HBA_FIP_SUPPORT))) {
-		spin_unlock_irq(&phba->hbalock);
-		return;
-	}
-	spin_unlock_irq(&phba->hbalock);
+	struct lpfc_nodelist *ndlp;
+	struct Scsi_Host *shost;
+	int i, rc;
 
+	/* Unregister RPIs */
 	if (lpfc_fcf_inuse(phba))
-		return;
+		lpfc_unreg_hba_rpis(phba);
 
 	/* At this point, all discovery is aborted */
 	phba->pport->port_state = LPFC_VPORT_UNKNOWN;
 
 	/* Unregister VPIs */
 	vports = lpfc_create_vport_work_array(phba);
-	if (vports &&
-		(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED))
+	if (vports && (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED))
 		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
+			/* Stop FLOGI/FDISC retries */
+			ndlp = lpfc_findnode_did(vports[i], Fabric_DID);
+			if (ndlp)
+				lpfc_cancel_retry_delay_tmo(vports[i], ndlp);
 			lpfc_mbx_unreg_vpi(vports[i]);
-			spin_lock_irq(&phba->hbalock);
+			shost = lpfc_shost_from_vport(vports[i]);
+			spin_lock_irq(shost->host_lock);
 			vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
 			vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED;
-			spin_unlock_irq(&phba->hbalock);
+			spin_unlock_irq(shost->host_lock);
 		}
 	lpfc_destroy_vport_work_array(phba, vports);
 
+	/* Cleanup any outstanding ELS commands */
+	lpfc_els_flush_all_cmd(phba);
+
 	/* Unregister VFI */
 	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!mbox) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
-			"2556 UNREG_VFI mbox allocation failed"
-			"HBA state x%x\n",
-			phba->pport->port_state);
-		return;
+				"2556 UNREG_VFI mbox allocation failed"
+				"HBA state x%x\n", phba->pport->port_state);
+		return -ENOMEM;
 	}
 
 	lpfc_unreg_vfi(mbox, phba->pport);
@@ -4514,58 +4963,172 @@ lpfc_unregister_unused_fcf(struct lpfc_h
 	rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
 	if (rc == MBX_NOT_FINISHED) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
-			"2557 UNREG_VFI issue mbox failed rc x%x "
-			"HBA state x%x\n",
-			rc, phba->pport->port_state);
+				"2557 UNREG_VFI issue mbox failed rc x%x "
+				"HBA state x%x\n",
+				rc, phba->pport->port_state);
 		mempool_free(mbox, phba->mbox_mem_pool);
-		return;
+		return -EIO;
 	}
 
-	/* Unregister FCF */
+	shost = lpfc_shost_from_vport(phba->pport);
+	spin_lock_irq(shost->host_lock);
+	phba->pport->fc_flag &= ~FC_VFI_REGISTERED;
+	spin_unlock_irq(shost->host_lock);
+
+	return 0;
+}
+
+/**
+ * lpfc_sli4_unregister_fcf - Unregister currently registered FCF record
+ * @phba: Pointer to hba context object.
+ *
+ * This function issues synchronous unregister FCF mailbox command to HBA to
+ * unregister the currently registered FCF record. The driver does not reset
+ * the driver FCF usage state flags.
+ *
+ * Return 0 if successfully issued, none-zero otherwise.
+ */
+int
+lpfc_sli4_unregister_fcf(struct lpfc_hba *phba)
+{
+	LPFC_MBOXQ_t *mbox;
+	int rc;
+
 	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!mbox) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
-			"2551 UNREG_FCFI mbox allocation failed"
-			"HBA state x%x\n",
-			phba->pport->port_state);
-		return;
+				"2551 UNREG_FCFI mbox allocation failed"
+				"HBA state x%x\n", phba->pport->port_state);
+		return -ENOMEM;
 	}
-
 	lpfc_unreg_fcfi(mbox, phba->fcf.fcfi);
 	mbox->vport = phba->pport;
 	mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl;
 	rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
 
 	if (rc == MBX_NOT_FINISHED) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
-			"2552 UNREG_FCFI issue mbox failed rc x%x "
-			"HBA state x%x\n",
-			rc, phba->pport->port_state);
-		mempool_free(mbox, phba->mbox_mem_pool);
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+				"2552 Unregister FCFI command failed rc x%x "
+				"HBA state x%x\n",
+				rc, phba->pport->port_state);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ * lpfc_unregister_fcf_rescan - Unregister currently registered fcf and rescan
+ * @phba: Pointer to hba context object.
+ *
+ * This function unregisters the currently reigstered FCF. This function
+ * also tries to find another FCF for discovery by rescan the HBA FCF table.
+ */
+void
+lpfc_unregister_fcf_rescan(struct lpfc_hba *phba)
+{
+	int rc;
+
+	/* Preparation for unregistering fcf */
+	rc = lpfc_unregister_fcf_prep(phba);
+	if (rc) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
+				"2748 Failed to prepare for unregistering "
+				"HBA's FCF record: rc=%d\n", rc);
 		return;
 	}
 
-	spin_lock_irq(&phba->hbalock);
-	phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_REGISTERED |
-		FCF_DISCOVERED | FCF_BOOT_ENABLE | FCF_IN_USE |
-		FCF_VALID_VLAN);
-	spin_unlock_irq(&phba->hbalock);
+	/* Now, unregister FCF record and reset HBA FCF state */
+	rc = lpfc_sli4_unregister_fcf(phba);
+	if (rc)
+		return;
+	/* Reset HBA FCF states after successful unregister FCF */
+	phba->fcf.fcf_flag = 0;
+	phba->fcf.current_rec.flag = 0;
 
 	/*
 	 * If driver is not unloading, check if there is any other
 	 * FCF record that can be used for discovery.
 	 */
 	if ((phba->pport->load_flag & FC_UNLOADING) ||
-		(phba->link_state < LPFC_LINK_UP))
+	    (phba->link_state < LPFC_LINK_UP))
 		return;
 
-	rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
+	/* This is considered as the initial FCF discovery scan */
+	spin_lock_irq(&phba->hbalock);
+	phba->fcf.fcf_flag |= FCF_INIT_DISC;
+	spin_unlock_irq(&phba->hbalock);
+	rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
 
-	if (rc)
+	if (rc) {
+		spin_lock_irq(&phba->hbalock);
+		phba->fcf.fcf_flag &= ~FCF_INIT_DISC;
+		spin_unlock_irq(&phba->hbalock);
 		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
-			"2553 lpfc_unregister_unused_fcf failed to read FCF"
-			" record HBA state x%x\n",
-			phba->pport->port_state);
+				"2553 lpfc_unregister_unused_fcf failed "
+				"to read FCF record HBA state x%x\n",
+				phba->pport->port_state);
+	}
+}
+
+/**
+ * lpfc_unregister_fcf - Unregister the currently registered fcf record
+ * @phba: Pointer to hba context object.
+ *
+ * This function just unregisters the currently reigstered FCF. It does not
+ * try to find another FCF for discovery.
+ */
+void
+lpfc_unregister_fcf(struct lpfc_hba *phba)
+{
+	int rc;
+
+	/* Preparation for unregistering fcf */
+	rc = lpfc_unregister_fcf_prep(phba);
+	if (rc) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
+				"2749 Failed to prepare for unregistering "
+				"HBA's FCF record: rc=%d\n", rc);
+		return;
+	}
+
+	/* Now, unregister FCF record and reset HBA FCF state */
+	rc = lpfc_sli4_unregister_fcf(phba);
+	if (rc)
+		return;
+	/* Set proper HBA FCF states after successful unregister FCF */
+	spin_lock_irq(&phba->hbalock);
+	phba->fcf.fcf_flag &= ~FCF_REGISTERED;
+	spin_unlock_irq(&phba->hbalock);
+}
+
+/**
+ * lpfc_unregister_unused_fcf - Unregister FCF if all devices are disconnected.
+ * @phba: Pointer to hba context object.
+ *
+ * This function check if there are any connected remote port for the FCF and
+ * if all the devices are disconnected, this function unregister FCFI.
+ * This function also tries to use another FCF for discovery.
+ */
+void
+lpfc_unregister_unused_fcf(struct lpfc_hba *phba)
+{
+	/*
+	 * If HBA is not running in FIP mode or if HBA does not support
+	 * FCoE or if FCF is not registered, do nothing.
+	 */
+	spin_lock_irq(&phba->hbalock);
+	if (!(phba->hba_flag & HBA_FCOE_SUPPORT) ||
+	    !(phba->fcf.fcf_flag & FCF_REGISTERED) ||
+	    !(phba->hba_flag & HBA_FIP_SUPPORT)) {
+		spin_unlock_irq(&phba->hbalock);
+		return;
+	}
+	spin_unlock_irq(&phba->hbalock);
+
+	if (lpfc_fcf_inuse(phba))
+		return;
+
+	lpfc_unregister_fcf_rescan(phba);
 }
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_hw4.h linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_hw4.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_hw4.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_hw4.h	2010-05-16 17:17:36.000000000 -0400
@@ -52,35 +52,37 @@ struct dma_address {
 	uint32_t addr_hi;
 };
 
-#define LPFC_SLIREV_CONF_WORD	0x58
 struct lpfc_sli_intf {
 	uint32_t word0;
-#define lpfc_sli_intf_iftype_MASK 	0x00000007
-#define lpfc_sli_intf_iftype_SHIFT	0
-#define lpfc_sli_intf_iftype_WORD	word0
-#define lpfc_sli_intf_rev_MASK 		0x0000000f
-#define lpfc_sli_intf_rev_SHIFT		4
-#define lpfc_sli_intf_rev_WORD		word0
-#define LPFC_SLIREV_CONF_SLI4	4
-#define lpfc_sli_intf_family_MASK 	0x000000ff
-#define lpfc_sli_intf_family_SHIFT	8
-#define lpfc_sli_intf_family_WORD	word0
-#define lpfc_sli_intf_feat1_MASK 	0x000000ff
-#define lpfc_sli_intf_feat1_SHIFT	16
-#define lpfc_sli_intf_feat1_WORD	word0
-#define lpfc_sli_intf_feat2_MASK 	0x0000001f
-#define lpfc_sli_intf_feat2_SHIFT	24
-#define lpfc_sli_intf_feat2_WORD	word0
-#define lpfc_sli_intf_valid_MASK 	0x00000007
-#define lpfc_sli_intf_valid_SHIFT	29
-#define lpfc_sli_intf_valid_WORD	word0
+#define lpfc_sli_intf_valid_SHIFT		29
+#define lpfc_sli_intf_valid_MASK		0x00000007
+#define lpfc_sli_intf_valid_WORD		word0
 #define LPFC_SLI_INTF_VALID		6
+#define lpfc_sli_intf_featurelevel2_SHIFT	24
+#define lpfc_sli_intf_featurelevel2_MASK	0x0000001F
+#define lpfc_sli_intf_featurelevel2_WORD	word0
+#define lpfc_sli_intf_featurelevel1_SHIFT	16
+#define lpfc_sli_intf_featurelevel1_MASK	0x000000FF
+#define lpfc_sli_intf_featurelevel1_WORD	word0
+#define LPFC_SLI_INTF_FEATURELEVEL1_1	1
+#define LPFC_SLI_INTF_FEATURELEVEL1_2	2
+#define lpfc_sli_intf_sli_family_SHIFT		8
+#define lpfc_sli_intf_sli_family_MASK		0x000000FF
+#define lpfc_sli_intf_sli_family_WORD		word0
+#define LPFC_SLI_INTF_FAMILY_BE2	0
+#define LPFC_SLI_INTF_FAMILY_BE3	1
+#define lpfc_sli_intf_slirev_SHIFT		4
+#define lpfc_sli_intf_slirev_MASK		0x0000000F
+#define lpfc_sli_intf_slirev_WORD		word0
+#define LPFC_SLI_INTF_REV_SLI3		3
+#define LPFC_SLI_INTF_REV_SLI4		4
+#define lpfc_sli_intf_if_type_SHIFT		0
+#define lpfc_sli_intf_if_type_MASK		0x00000007
+#define lpfc_sli_intf_if_type_WORD		word0
+#define LPFC_SLI_INTF_IF_TYPE_0		0
+#define LPFC_SLI_INTF_IF_TYPE_1		1
 };
 
-#define LPFC_SLI4_BAR0		1
-#define LPFC_SLI4_BAR1		2
-#define LPFC_SLI4_BAR2		4
-
 #define LPFC_SLI4_MBX_EMBED	true
 #define LPFC_SLI4_MBX_NEMBED	false
 
@@ -161,6 +163,9 @@ struct lpfc_sli_intf {
 #define LPFC_FP_DEF_IMAX       10000
 #define LPFC_SP_DEF_IMAX       10000
 
+/* PORT_CAPABILITIES constants. */
+#define LPFC_MAX_SUPPORTED_PAGES	8
+
 struct ulp_bde64 {
 	union ULP_BDE_TUS {
 		uint32_t w;
@@ -516,7 +521,7 @@ struct lpfc_register {
 #define LPFC_UERR_STATUS_LO		0x00A0
 #define LPFC_UE_MASK_HI			0x00AC
 #define LPFC_UE_MASK_LO			0x00A8
-#define LPFC_SCRATCHPAD			0x0058
+#define LPFC_SLI_INTF			0x0058
 
 /* BAR0 Registers */
 #define LPFC_HST_STATE			0x00AC
@@ -576,19 +581,6 @@ struct lpfc_register {
 #define LPFC_POST_STAGE_ARMFW_READY			0xC000
 #define LPFC_POST_STAGE_ARMFW_UE 			0xF000
 
-#define lpfc_scratchpad_slirev_SHIFT			4
-#define lpfc_scratchpad_slirev_MASK			0xF
-#define lpfc_scratchpad_slirev_WORD			word0
-#define lpfc_scratchpad_chiptype_SHIFT			8
-#define lpfc_scratchpad_chiptype_MASK			0xFF
-#define lpfc_scratchpad_chiptype_WORD			word0
-#define lpfc_scratchpad_featurelevel1_SHIFT		16
-#define lpfc_scratchpad_featurelevel1_MASK		0xFF
-#define lpfc_scratchpad_featurelevel1_WORD		word0
-#define lpfc_scratchpad_featurelevel2_SHIFT		24
-#define lpfc_scratchpad_featurelevel2_MASK		0xFF
-#define lpfc_scratchpad_featurelevel2_WORD		word0
-
 /* BAR1 Registers */
 #define LPFC_IMR_MASK_ALL	0xFFFFFFFF
 #define LPFC_ISCR_CLEAR_ALL	0xFFFFFFFF
@@ -801,6 +793,7 @@ struct mbox_header {
 #define LPFC_MBOX_OPCODE_FCOE_ADD_FCF			0x09
 #define LPFC_MBOX_OPCODE_FCOE_DELETE_FCF		0x0A
 #define LPFC_MBOX_OPCODE_FCOE_POST_HDR_TEMPLATE		0x0B
+#define LPFC_MBOX_OPCODE_FCOE_REDISCOVER_FCF		0x10
 
 /* Mailbox command structures */
 struct eq_context {
@@ -1149,10 +1142,7 @@ struct sli4_sge {	/* SLI-4 */
 						this  flag !! */
 #define lpfc_sli4_sge_last_MASK		0x00000001
 #define lpfc_sli4_sge_last_WORD		word2
-	uint32_t word3;
-#define lpfc_sli4_sge_len_SHIFT		0
-#define lpfc_sli4_sge_len_MASK		0x0001FFFF
-#define lpfc_sli4_sge_len_WORD		word3
+	uint32_t sge_len;
 };
 
 struct fcf_record {
@@ -1301,6 +1291,19 @@ struct lpfc_mbx_del_fcf_tbl_entry {
 #define lpfc_mbx_del_fcf_tbl_index_WORD		word10
 };
 
+struct lpfc_mbx_redisc_fcf_tbl {
+	struct mbox_header header;
+	uint32_t word10;
+#define lpfc_mbx_redisc_fcf_count_SHIFT		0
+#define lpfc_mbx_redisc_fcf_count_MASK		0x0000FFFF
+#define lpfc_mbx_redisc_fcf_count_WORD		word10
+	uint32_t resvd;
+	uint32_t word12;
+#define lpfc_mbx_redisc_fcf_index_SHIFT		0
+#define lpfc_mbx_redisc_fcf_index_MASK		0x0000FFFF
+#define lpfc_mbx_redisc_fcf_index_WORD		word12
+};
+
 struct lpfc_mbx_query_fw_cfg {
 	struct mbox_header header;
 	uint32_t config_number;
@@ -1834,6 +1837,177 @@ struct lpfc_mbx_request_features {
 #define lpfc_mbx_rq_ftr_rsp_ifip_WORD		word3
 };
 
+struct lpfc_mbx_supp_pages {
+	uint32_t word1;
+#define qs_SHIFT 				0
+#define qs_MASK					0x00000001
+#define qs_WORD					word1
+#define wr_SHIFT				1
+#define wr_MASK 				0x00000001
+#define wr_WORD					word1
+#define pf_SHIFT				8
+#define pf_MASK					0x000000ff
+#define pf_WORD					word1
+#define cpn_SHIFT				16
+#define cpn_MASK				0x000000ff
+#define cpn_WORD				word1
+	uint32_t word2;
+#define list_offset_SHIFT 			0
+#define list_offset_MASK			0x000000ff
+#define list_offset_WORD			word2
+#define next_offset_SHIFT			8
+#define next_offset_MASK			0x000000ff
+#define next_offset_WORD			word2
+#define elem_cnt_SHIFT				16
+#define elem_cnt_MASK				0x000000ff
+#define elem_cnt_WORD				word2
+	uint32_t word3;
+#define pn_0_SHIFT				24
+#define pn_0_MASK  				0x000000ff
+#define pn_0_WORD				word3
+#define pn_1_SHIFT				16
+#define pn_1_MASK				0x000000ff
+#define pn_1_WORD				word3
+#define pn_2_SHIFT				8
+#define pn_2_MASK				0x000000ff
+#define pn_2_WORD				word3
+#define pn_3_SHIFT				0
+#define pn_3_MASK				0x000000ff
+#define pn_3_WORD				word3
+	uint32_t word4;
+#define pn_4_SHIFT				24
+#define pn_4_MASK				0x000000ff
+#define pn_4_WORD				word4
+#define pn_5_SHIFT				16
+#define pn_5_MASK				0x000000ff
+#define pn_5_WORD				word4
+#define pn_6_SHIFT				8
+#define pn_6_MASK				0x000000ff
+#define pn_6_WORD				word4
+#define pn_7_SHIFT				0
+#define pn_7_MASK				0x000000ff
+#define pn_7_WORD				word4
+	uint32_t rsvd[27];
+#define LPFC_SUPP_PAGES			0
+#define LPFC_BLOCK_GUARD_PROFILES	1
+#define LPFC_SLI4_PARAMETERS		2
+};
+
+struct lpfc_mbx_sli4_params {
+	uint32_t word1;
+#define qs_SHIFT				0
+#define qs_MASK					0x00000001
+#define qs_WORD					word1
+#define wr_SHIFT				1
+#define wr_MASK					0x00000001
+#define wr_WORD					word1
+#define pf_SHIFT				8
+#define pf_MASK					0x000000ff
+#define pf_WORD					word1
+#define cpn_SHIFT				16
+#define cpn_MASK				0x000000ff
+#define cpn_WORD				word1
+	uint32_t word2;
+#define if_type_SHIFT				0
+#define if_type_MASK				0x00000007
+#define if_type_WORD				word2
+#define sli_rev_SHIFT				4
+#define sli_rev_MASK				0x0000000f
+#define sli_rev_WORD				word2
+#define sli_family_SHIFT			8
+#define sli_family_MASK				0x000000ff
+#define sli_family_WORD				word2
+#define featurelevel_1_SHIFT			16
+#define featurelevel_1_MASK			0x000000ff
+#define featurelevel_1_WORD			word2
+#define featurelevel_2_SHIFT			24
+#define featurelevel_2_MASK			0x0000001f
+#define featurelevel_2_WORD			word2
+	uint32_t word3;
+#define fcoe_SHIFT 				0
+#define fcoe_MASK				0x00000001
+#define fcoe_WORD				word3
+#define fc_SHIFT				1
+#define fc_MASK					0x00000001
+#define fc_WORD					word3
+#define nic_SHIFT				2
+#define nic_MASK				0x00000001
+#define nic_WORD				word3
+#define iscsi_SHIFT				3
+#define iscsi_MASK				0x00000001
+#define iscsi_WORD				word3
+#define rdma_SHIFT				4
+#define rdma_MASK				0x00000001
+#define rdma_WORD				word3
+	uint32_t sge_supp_len;
+	uint32_t word5;
+#define if_page_sz_SHIFT			0
+#define if_page_sz_MASK				0x0000ffff
+#define if_page_sz_WORD				word5
+#define loopbk_scope_SHIFT			24
+#define loopbk_scope_MASK			0x0000000f
+#define loopbk_scope_WORD			word5
+#define rq_db_window_SHIFT			28
+#define rq_db_window_MASK			0x0000000f
+#define rq_db_window_WORD			word5
+	uint32_t word6;
+#define eq_pages_SHIFT				0
+#define eq_pages_MASK				0x0000000f
+#define eq_pages_WORD				word6
+#define eqe_size_SHIFT				8
+#define eqe_size_MASK				0x000000ff
+#define eqe_size_WORD				word6
+	uint32_t word7;
+#define cq_pages_SHIFT				0
+#define cq_pages_MASK				0x0000000f
+#define cq_pages_WORD				word7
+#define cqe_size_SHIFT				8
+#define cqe_size_MASK				0x000000ff
+#define cqe_size_WORD				word7
+	uint32_t word8;
+#define mq_pages_SHIFT				0
+#define mq_pages_MASK				0x0000000f
+#define mq_pages_WORD				word8
+#define mqe_size_SHIFT				8
+#define mqe_size_MASK				0x000000ff
+#define mqe_size_WORD				word8
+#define mq_elem_cnt_SHIFT			16
+#define mq_elem_cnt_MASK			0x000000ff
+#define mq_elem_cnt_WORD			word8
+	uint32_t word9;
+#define wq_pages_SHIFT				0
+#define wq_pages_MASK				0x0000ffff
+#define wq_pages_WORD				word9
+#define wqe_size_SHIFT				8
+#define wqe_size_MASK				0x000000ff
+#define wqe_size_WORD				word9
+	uint32_t word10;
+#define rq_pages_SHIFT				0
+#define rq_pages_MASK				0x0000ffff
+#define rq_pages_WORD				word10
+#define rqe_size_SHIFT				8
+#define rqe_size_MASK				0x000000ff
+#define rqe_size_WORD				word10
+	uint32_t word11;
+#define hdr_pages_SHIFT				0
+#define hdr_pages_MASK				0x0000000f
+#define hdr_pages_WORD				word11
+#define hdr_size_SHIFT				8
+#define hdr_size_MASK				0x0000000f
+#define hdr_size_WORD				word11
+#define hdr_pp_align_SHIFT			16
+#define hdr_pp_align_MASK			0x0000ffff
+#define hdr_pp_align_WORD			word11
+	uint32_t word12;
+#define sgl_pages_SHIFT				0
+#define sgl_pages_MASK				0x0000000f
+#define sgl_pages_WORD				word12
+#define sgl_pp_align_SHIFT			16
+#define sgl_pp_align_MASK			0x0000ffff
+#define sgl_pp_align_WORD			word12
+	uint32_t rsvd_13_63[51];
+};
+
 /* Mailbox Completion Queue Error Messages */
 #define MB_CQE_STATUS_SUCCESS 			0x0
 #define MB_CQE_STATUS_INSUFFICIENT_PRIVILEGES	0x1
@@ -1863,6 +2037,7 @@ struct lpfc_mqe {
 		struct lpfc_mbx_read_fcf_tbl read_fcf_tbl;
 		struct lpfc_mbx_add_fcf_tbl_entry add_fcf_entry;
 		struct lpfc_mbx_del_fcf_tbl_entry del_fcf_entry;
+		struct lpfc_mbx_redisc_fcf_tbl redisc_fcf_tbl;
 		struct lpfc_mbx_reg_fcfi reg_fcfi;
 		struct lpfc_mbx_unreg_fcfi unreg_fcfi;
 		struct lpfc_mbx_mq_create mq_create;
@@ -1883,6 +2058,8 @@ struct lpfc_mqe {
 		struct lpfc_mbx_request_features req_ftrs;
 		struct lpfc_mbx_post_hdr_tmpl hdr_tmpl;
 		struct lpfc_mbx_query_fw_cfg query_fw_cfg;
+		struct lpfc_mbx_supp_pages supp_pages;
+		struct lpfc_mbx_sli4_params sli4_params;
 		struct lpfc_mbx_nop nop;
 	} un;
 };
@@ -1959,6 +2136,9 @@ struct lpfc_acqe_link {
 #define LPFC_ASYNC_LINK_FAULT_NONE	0x0
 #define LPFC_ASYNC_LINK_FAULT_LOCAL	0x1
 #define LPFC_ASYNC_LINK_FAULT_REMOTE	0x2
+#define lpfc_acqe_qos_link_speed_SHIFT	16
+#define lpfc_acqe_qos_link_speed_MASK	0x0000FFFF
+#define lpfc_acqe_qos_link_speed_WORD	word1
 	uint32_t event_tag;
 	uint32_t trailer;
 };
@@ -1976,6 +2156,7 @@ struct lpfc_acqe_fcoe {
 #define LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL	0x2
 #define LPFC_FCOE_EVENT_TYPE_FCF_DEAD		0x3
 #define LPFC_FCOE_EVENT_TYPE_CVL		0x4
+#define LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD	0x5
 	uint32_t event_tag;
 	uint32_t trailer;
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_hw.h linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_hw.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2009 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2010 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
@@ -1346,6 +1346,9 @@ typedef struct {		/* FireFly BIU registe
 #define MBX_HEARTBEAT       0x31
 #define MBX_WRITE_VPARMS    0x32
 #define MBX_ASYNCEVT_ENABLE 0x33
+#define MBX_READ_EVENT_LOG_STATUS 0x37
+#define MBX_READ_EVENT_LOG  0x38
+#define MBX_WRITE_EVENT_LOG 0x39
 
 #define MBX_PORT_CAPABILITIES 0x3B
 #define MBX_PORT_IOV_CONTROL 0x3C
@@ -1465,17 +1468,13 @@ typedef struct {		/* FireFly BIU registe
 #define CMD_IOCB_LOGENTRY_CN		0x94
 #define CMD_IOCB_LOGENTRY_ASYNC_CN	0x96
 
-/* Unhandled Data Security SLI Commands */
-#define DSSCMD_IWRITE64_CR 		0xD8
-#define DSSCMD_IWRITE64_CX		0xD9
-#define DSSCMD_IREAD64_CR		0xDA
-#define DSSCMD_IREAD64_CX		0xDB
-#define DSSCMD_INVALIDATE_DEK		0xDC
-#define DSSCMD_SET_KEK			0xDD
-#define DSSCMD_GET_KEK_ID		0xDE
-#define DSSCMD_GEN_XFER			0xDF
+/* Data Security SLI Commands */
+#define DSSCMD_IWRITE64_CR		0xF8
+#define DSSCMD_IWRITE64_CX		0xF9
+#define DSSCMD_IREAD64_CR		0xFA
+#define DSSCMD_IREAD64_CX		0xFB
 
-#define CMD_MAX_IOCB_CMD        0xE6
+#define CMD_MAX_IOCB_CMD        0xFB
 #define CMD_IOCB_MASK           0xff
 
 #define MAX_MSG_DATA            28	/* max msg data in CMD_ADAPTER_MSG
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_init.c linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_init.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2009 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2010 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
@@ -29,6 +29,7 @@
 #include <linux/spinlock.h>
 #include <linux/ctype.h>
 #include <linux/aer.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
@@ -350,7 +351,12 @@ lpfc_config_port_post(struct lpfc_hba *p
 	mb = &pmb->u.mb;
 
 	/* Get login parameters for NID.  */
-	lpfc_read_sparam(phba, pmb, 0);
+	rc = lpfc_read_sparam(phba, pmb, 0);
+	if (rc) {
+		mempool_free(pmb, phba->mbox_mem_pool);
+		return -ENOMEM;
+	}
+
 	pmb->vport = vport;
 	if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -359,7 +365,7 @@ lpfc_config_port_post(struct lpfc_hba *p
 				mb->mbxCommand, mb->mbxStatus);
 		phba->link_state = LPFC_HBA_ERROR;
 		mp = (struct lpfc_dmabuf *) pmb->context1;
-		mempool_free( pmb, phba->mbox_mem_pool);
+		mempool_free(pmb, phba->mbox_mem_pool);
 		lpfc_mbuf_free(phba, mp->virt, mp->phys);
 		kfree(mp);
 		return -EIO;
@@ -544,7 +550,7 @@ lpfc_config_port_post(struct lpfc_hba *p
 			mempool_free(pmb, phba->mbox_mem_pool);
 			return -EIO;
 		}
-	} else {
+	} else if (phba->cfg_suppress_link_up == LPFC_INITIALIZE_LINK) {
 		lpfc_init_link(phba, pmb, phba->cfg_topology,
 			phba->cfg_link_speed);
 		pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
@@ -571,6 +577,11 @@ lpfc_config_port_post(struct lpfc_hba *p
 	}
 	/* MBOX buffer will be freed in mbox compl */
 	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!pmb) {
+		phba->link_state = LPFC_HBA_ERROR;
+		return -ENOMEM;
+	}
+
 	lpfc_config_async(phba, pmb, LPFC_ELS_RING);
 	pmb->mbox_cmpl = lpfc_config_async_cmpl;
 	pmb->vport = phba->pport;
@@ -588,6 +599,11 @@ lpfc_config_port_post(struct lpfc_hba *p
 
 	/* Get Option rom version */
 	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!pmb) {
+		phba->link_state = LPFC_HBA_ERROR;
+		return -ENOMEM;
+	}
+
 	lpfc_dump_wakeup_param(phba, pmb);
 	pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl;
 	pmb->vport = phba->pport;
@@ -603,6 +619,102 @@ lpfc_config_port_post(struct lpfc_hba *p
 }
 
 /**
+ * lpfc_hba_init_link - Initialize the FC link
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine will issue the INIT_LINK mailbox command call.
+ * It is available to other drivers through the lpfc_hba data
+ * structure for use as a delayed link up mechanism with the
+ * module parameter lpfc_suppress_link_up.
+ *
+ * Return code
+ *		0 - success
+ *		Any other value - error
+ **/
+int
+lpfc_hba_init_link(struct lpfc_hba *phba)
+{
+	struct lpfc_vport *vport = phba->pport;
+	LPFC_MBOXQ_t *pmb;
+	MAILBOX_t *mb;
+	int rc;
+
+	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!pmb) {
+		phba->link_state = LPFC_HBA_ERROR;
+		return -ENOMEM;
+	}
+	mb = &pmb->u.mb;
+	pmb->vport = vport;
+
+	lpfc_init_link(phba, pmb, phba->cfg_topology,
+		phba->cfg_link_speed);
+	pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+	lpfc_set_loopback_flag(phba);
+	rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
+	if (rc != MBX_SUCCESS) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"0498 Adapter failed to init, mbxCmd x%x "
+			"INIT_LINK, mbxStatus x%x\n",
+			mb->mbxCommand, mb->mbxStatus);
+		/* Clear all interrupt enable conditions */
+		writel(0, phba->HCregaddr);
+		readl(phba->HCregaddr); /* flush */
+		/* Clear all pending interrupts */
+		writel(0xffffffff, phba->HAregaddr);
+		readl(phba->HAregaddr); /* flush */
+		phba->link_state = LPFC_HBA_ERROR;
+		if (rc != MBX_BUSY)
+			mempool_free(pmb, phba->mbox_mem_pool);
+		return -EIO;
+	}
+	phba->cfg_suppress_link_up = LPFC_INITIALIZE_LINK;
+
+	return 0;
+}
+
+/**
+ * lpfc_hba_down_link - this routine downs the FC link
+ *
+ * This routine will issue the DOWN_LINK mailbox command call.
+ * It is available to other drivers through the lpfc_hba data
+ * structure for use to stop the link.
+ *
+ * Return code
+ *		0 - success
+ *		Any other value - error
+ **/
+int
+lpfc_hba_down_link(struct lpfc_hba *phba)
+{
+	LPFC_MBOXQ_t *pmb;
+	int rc;
+
+	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!pmb) {
+		phba->link_state = LPFC_HBA_ERROR;
+		return -ENOMEM;
+	}
+
+	lpfc_printf_log(phba,
+		KERN_ERR, LOG_INIT,
+		"0491 Adapter Link is disabled.\n");
+	lpfc_down_link(phba, pmb);
+	pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+	rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
+	if ((rc != MBX_SUCCESS) && (rc != MBX_BUSY)) {
+		lpfc_printf_log(phba,
+		KERN_ERR, LOG_INIT,
+		"2522 Adapter failed to issue DOWN_LINK"
+		" mbox command rc 0x%x\n", rc);
+
+		mempool_free(pmb, phba->mbox_mem_pool);
+		return -EIO;
+	}
+	return 0;
+}
+
+/**
  * lpfc_hba_down_prep - Perform lpfc uninitialization prior to HBA reset
  * @phba: pointer to lpfc HBA data structure.
  *
@@ -711,6 +823,8 @@ lpfc_hba_down_post_s4(struct lpfc_hba *p
 	LIST_HEAD(aborts);
 	int ret;
 	unsigned long iflag = 0;
+	struct lpfc_sglq *sglq_entry = NULL;
+
 	ret = lpfc_hba_down_post_s3(phba);
 	if (ret)
 		return ret;
@@ -726,6 +840,10 @@ lpfc_hba_down_post_s4(struct lpfc_hba *p
 	 * list.
 	 */
 	spin_lock(&phba->sli4_hba.abts_sgl_list_lock);
+	list_for_each_entry(sglq_entry,
+		&phba->sli4_hba.lpfc_abts_els_sgl_list, list)
+		sglq_entry->state = SGL_FREED;
+
 	list_splice_init(&phba->sli4_hba.lpfc_abts_els_sgl_list,
 			&phba->sli4_hba.lpfc_sgl_list);
 	spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
@@ -2073,6 +2191,46 @@ lpfc_stop_vport_timers(struct lpfc_vport
 }
 
 /**
+ * __lpfc_sli4_stop_fcf_redisc_wait_timer - Stop FCF rediscovery wait timer
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine stops the SLI4 FCF rediscover wait timer if it's on. The
+ * caller of this routine should already hold the host lock.
+ **/
+void
+__lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba)
+{
+	/* Clear pending FCF rediscovery wait and failover in progress flags */
+	phba->fcf.fcf_flag &= ~(FCF_REDISC_PEND |
+				FCF_DEAD_DISC |
+				FCF_ACVL_DISC);
+	/* Now, try to stop the timer */
+	del_timer(&phba->fcf.redisc_wait);
+}
+
+/**
+ * lpfc_sli4_stop_fcf_redisc_wait_timer - Stop FCF rediscovery wait timer
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine stops the SLI4 FCF rediscover wait timer if it's on. It
+ * checks whether the FCF rediscovery wait timer is pending with the host
+ * lock held before proceeding with disabling the timer and clearing the
+ * wait timer pendig flag.
+ **/
+void
+lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba)
+{
+	spin_lock_irq(&phba->hbalock);
+	if (!(phba->fcf.fcf_flag & FCF_REDISC_PEND)) {
+		/* FCF rediscovery timer already fired or stopped */
+		spin_unlock_irq(&phba->hbalock);
+		return;
+	}
+	__lpfc_sli4_stop_fcf_redisc_wait_timer(phba);
+	spin_unlock_irq(&phba->hbalock);
+}
+
+/**
  * lpfc_stop_hba_timers - Stop all the timers associated with an HBA
  * @phba: pointer to lpfc hba data structure.
  *
@@ -2096,6 +2254,7 @@ lpfc_stop_hba_timers(struct lpfc_hba *ph
 		break;
 	case LPFC_PCI_DEV_OC:
 		/* Stop any OneConnect device sepcific driver timers */
+		lpfc_sli4_stop_fcf_redisc_wait_timer(phba);
 		break;
 	default:
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -2228,6 +2387,7 @@ lpfc_offline_prep(struct lpfc_hba * phba
 	struct lpfc_vport *vport = phba->pport;
 	struct lpfc_nodelist  *ndlp, *next_ndlp;
 	struct lpfc_vport **vports;
+	struct Scsi_Host *shost;
 	int i;
 
 	if (vport->fc_flag & FC_OFFLINE_MODE)
@@ -2241,11 +2401,15 @@ lpfc_offline_prep(struct lpfc_hba * phba
 	vports = lpfc_create_vport_work_array(phba);
 	if (vports != NULL) {
 		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
-			struct Scsi_Host *shost;
-
 			if (vports[i]->load_flag & FC_UNLOADING)
 				continue;
+			shost = lpfc_shost_from_vport(vports[i]);
+			spin_lock_irq(shost->host_lock);
 			vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED;
+			vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
+			vports[i]->fc_flag &= ~FC_VFI_REGISTERED;
+			spin_unlock_irq(shost->host_lock);
+
 			shost =	lpfc_shost_from_vport(vports[i]);
 			list_for_each_entry_safe(ndlp, next_ndlp,
 						 &vports[i]->fc_nodes,
@@ -2401,7 +2565,8 @@ lpfc_create_port(struct lpfc_hba *phba,
 	shost->this_id = -1;
 	shost->max_cmd_len = 16;
 	if (phba->sli_rev == LPFC_SLI_REV4) {
-		shost->dma_boundary = LPFC_SLI4_MAX_SEGMENT_SIZE;
+		shost->dma_boundary =
+			phba->sli4_hba.pc_sli4_params.sge_supp_len;
 		shost->sg_tablesize = phba->cfg_sg_seg_cnt;
 	}
 
@@ -2435,6 +2600,14 @@ lpfc_create_port(struct lpfc_hba *phba,
 	init_timer(&vport->els_tmofunc);
 	vport->els_tmofunc.function = lpfc_els_timeout;
 	vport->els_tmofunc.data = (unsigned long)vport;
+	if (phba->pcidev->device == PCI_DEVICE_ID_HORNET) {
+		phba->menlo_flag |= HBA_MENLO_SUPPORT;
+		/* check for menlo minimum sg count */
+		if (phba->cfg_sg_seg_cnt < LPFC_DEFAULT_MENLO_SG_SEG_CNT) {
+			phba->cfg_sg_seg_cnt = LPFC_DEFAULT_MENLO_SG_SEG_CNT;
+			shost->sg_tablesize = phba->cfg_sg_seg_cnt;
+		}
+	}
 
 	error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev);
 	if (error)
@@ -2650,8 +2823,6 @@ lpfc_stop_port_s4(struct lpfc_hba *phba)
 	lpfc_stop_hba_timers(phba);
 	phba->pport->work_port_events = 0;
 	phba->sli4_hba.intr_enable = 0;
-	/* Hard clear it for now, shall have more graceful way to wait later */
-	phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
 }
 
 /**
@@ -2703,7 +2874,7 @@ lpfc_sli_remove_dflt_fcf(struct lpfc_hba
 	del_fcf_record = &mboxq->u.mqe.un.del_fcf_entry;
 	bf_set(lpfc_mbx_del_fcf_tbl_count, del_fcf_record, 1);
 	bf_set(lpfc_mbx_del_fcf_tbl_index, del_fcf_record,
-	       phba->fcf.fcf_indx);
+	       phba->fcf.current_rec.fcf_indx);
 
 	if (!phba->sli4_hba.intr_enable)
 		rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
@@ -2727,6 +2898,60 @@ lpfc_sli_remove_dflt_fcf(struct lpfc_hba
 }
 
 /**
+ * lpfc_fcf_redisc_wait_start_timer - Start fcf rediscover wait timer
+ * @phba: Pointer to hba for which this call is being executed.
+ *
+ * This routine starts the timer waiting for the FCF rediscovery to complete.
+ **/
+void
+lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *phba)
+{
+	unsigned long fcf_redisc_wait_tmo =
+		(jiffies + msecs_to_jiffies(LPFC_FCF_REDISCOVER_WAIT_TMO));
+	/* Start fcf rediscovery wait period timer */
+	mod_timer(&phba->fcf.redisc_wait, fcf_redisc_wait_tmo);
+	spin_lock_irq(&phba->hbalock);
+	/* Allow action to new fcf asynchronous event */
+	phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_SCAN_DONE);
+	/* Mark the FCF rediscovery pending state */
+	phba->fcf.fcf_flag |= FCF_REDISC_PEND;
+	spin_unlock_irq(&phba->hbalock);
+}
+
+/**
+ * lpfc_sli4_fcf_redisc_wait_tmo - FCF table rediscover wait timeout
+ * @ptr: Map to lpfc_hba data structure pointer.
+ *
+ * This routine is invoked when waiting for FCF table rediscover has been
+ * timed out. If new FCF record(s) has (have) been discovered during the
+ * wait period, a new FCF event shall be added to the FCOE async event
+ * list, and then worker thread shall be waked up for processing from the
+ * worker thread context.
+ **/
+void
+lpfc_sli4_fcf_redisc_wait_tmo(unsigned long ptr)
+{
+	struct lpfc_hba *phba = (struct lpfc_hba *)ptr;
+
+	/* Don't send FCF rediscovery event if timer cancelled */
+	spin_lock_irq(&phba->hbalock);
+	if (!(phba->fcf.fcf_flag & FCF_REDISC_PEND)) {
+		spin_unlock_irq(&phba->hbalock);
+		return;
+	}
+	/* Clear FCF rediscovery timer pending flag */
+	phba->fcf.fcf_flag &= ~FCF_REDISC_PEND;
+	/* FCF rediscovery event to worker thread */
+	phba->fcf.fcf_flag |= FCF_REDISC_EVT;
+	spin_unlock_irq(&phba->hbalock);
+	lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+			"2776 FCF rediscover wait timer expired, post "
+			"a worker thread event for FCF table scan\n");
+	/* wake up worker thread */
+	lpfc_worker_wake_up(phba);
+}
+
+/**
  * lpfc_sli4_fw_cfg_check - Read the firmware config and verify FCoE support
  * @phba: pointer to lpfc hba data structure.
  *
@@ -2978,6 +3203,8 @@ lpfc_sli4_async_link_evt(struct lpfc_hba
 				bf_get(lpfc_acqe_link_physical, acqe_link);
 	phba->sli4_hba.link_state.fault =
 				bf_get(lpfc_acqe_link_fault, acqe_link);
+	phba->sli4_hba.link_state.logical_speed =
+				bf_get(lpfc_acqe_qos_link_speed, acqe_link);
 
 	/* Invoke the lpfc_handle_latt mailbox command callback function */
 	lpfc_mbx_cmpl_read_la(phba, pmb);
@@ -2991,6 +3218,68 @@ out_free_pmb:
 }
 
 /**
+ * lpfc_sli4_perform_vport_cvl - Perform clear virtual link on a vport
+ * @vport: pointer to vport data structure.
+ *
+ * This routine is to perform Clear Virtual Link (CVL) on a vport in
+ * response to a CVL event.
+ *
+ * Return the pointer to the ndlp with the vport if successful, otherwise
+ * return NULL.
+ **/
+static struct lpfc_nodelist *
+lpfc_sli4_perform_vport_cvl(struct lpfc_vport *vport)
+{
+	struct lpfc_nodelist *ndlp;
+	struct Scsi_Host *shost;
+	struct lpfc_hba *phba;
+
+	if (!vport)
+		return NULL;
+	ndlp = lpfc_findnode_did(vport, Fabric_DID);
+	if (!ndlp)
+		return NULL;
+	phba = vport->phba;
+	if (!phba)
+		return NULL;
+	if (phba->pport->port_state <= LPFC_FLOGI)
+		return NULL;
+	/* If virtual link is not yet instantiated ignore CVL */
+	if (vport->port_state <= LPFC_FDISC)
+		return NULL;
+	shost = lpfc_shost_from_vport(vport);
+	if (!shost)
+		return NULL;
+	lpfc_linkdown_port(vport);
+	lpfc_cleanup_pending_mbox(vport);
+	spin_lock_irq(shost->host_lock);
+	vport->fc_flag |= FC_VPORT_CVL_RCVD;
+	spin_unlock_irq(shost->host_lock);
+
+	return ndlp;
+}
+
+/**
+ * lpfc_sli4_perform_all_vport_cvl - Perform clear virtual link on all vports
+ * @vport: pointer to lpfc hba data structure.
+ *
+ * This routine is to perform Clear Virtual Link (CVL) on all vports in
+ * response to a FCF dead event.
+ **/
+static void
+lpfc_sli4_perform_all_vport_cvl(struct lpfc_hba *phba)
+{
+	struct lpfc_vport **vports;
+	int i;
+
+	vports = lpfc_create_vport_work_array(phba);
+	if (vports)
+		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++)
+			lpfc_sli4_perform_vport_cvl(vports[i]);
+	lpfc_destroy_vport_work_array(phba, vports);
+}
+
+/**
  * lpfc_sli4_async_fcoe_evt - Process the asynchronous fcoe event
  * @phba: pointer to lpfc hba data structure.
  * @acqe_link: pointer to the async fcoe completion queue entry.
@@ -3006,34 +3295,68 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba
 	struct lpfc_vport *vport;
 	struct lpfc_nodelist *ndlp;
 	struct Scsi_Host  *shost;
-	uint32_t link_state;
+	int active_vlink_present;
+	struct lpfc_vport **vports;
+	int i;
 
 	phba->fc_eventTag = acqe_fcoe->event_tag;
 	phba->fcoe_eventtag = acqe_fcoe->event_tag;
 	switch (event_type) {
 	case LPFC_FCOE_EVENT_TYPE_NEW_FCF:
-		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
-			"2546 New FCF found index 0x%x tag 0x%x\n",
-			acqe_fcoe->index,
-			acqe_fcoe->event_tag);
-		/*
-		 * If the current FCF is in discovered state, or
-		 * FCF discovery is in progress do nothing.
-		 */
+	case LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD:
+		lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
+			"2546 New FCF found/FCF parameter modified event: "
+			"evt_tag:x%x, fcf_index:x%x\n",
+			acqe_fcoe->event_tag, acqe_fcoe->index);
+
 		spin_lock_irq(&phba->hbalock);
-		if ((phba->fcf.fcf_flag & FCF_DISCOVERED) ||
-		   (phba->hba_flag & FCF_DISC_INPROGRESS)) {
+		if ((phba->fcf.fcf_flag & FCF_SCAN_DONE) ||
+		    (phba->hba_flag & FCF_DISC_INPROGRESS)) {
+			/*
+			 * If the current FCF is in discovered state or
+			 * FCF discovery is in progress, do nothing.
+			 */
+			spin_unlock_irq(&phba->hbalock);
+			break;
+		}
+
+		if (phba->fcf.fcf_flag & FCF_REDISC_EVT) {
+			/*
+			 * If fast FCF failover rescan event is pending,
+			 * do nothing.
+			 */
 			spin_unlock_irq(&phba->hbalock);
 			break;
 		}
 		spin_unlock_irq(&phba->hbalock);
 
-		/* Read the FCF table and re-discover SAN. */
-		rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
+		if ((phba->fcf.fcf_flag & FCF_DISCOVERY) &&
+		    !(phba->fcf.fcf_flag & FCF_REDISC_FOV)) {
+			/*
+			 * During period of FCF discovery, read the FCF
+			 * table record indexed by the event to update
+			 * FCF round robin failover eligible FCF bmask.
+			 */
+			lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
+					LOG_DISCOVERY,
+					"2779 Read new FCF record with "
+					"fcf_index:x%x for updating FCF "
+					"round robin failover bmask\n",
+					acqe_fcoe->index);
+			rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index);
+		}
+
+		/* Otherwise, scan the entire FCF table and re-discover SAN */
+		lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+				"2770 Start FCF table scan due to new FCF "
+				"event: evt_tag:x%x, fcf_index:x%x\n",
+				acqe_fcoe->event_tag, acqe_fcoe->index);
+		rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba,
+						     LPFC_FCOE_FCF_GET_FIRST);
 		if (rc)
-			lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
-					"2547 Read FCF record failed 0x%x\n",
-					rc);
+			lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
+					"2547 Issue FCF scan read FCF mailbox "
+					"command failed 0x%x\n", rc);
 		break;
 
 	case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL:
@@ -3044,44 +3367,128 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba
 		break;
 
 	case LPFC_FCOE_EVENT_TYPE_FCF_DEAD:
-		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
+		lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
 			"2549 FCF disconnected from network index 0x%x"
 			" tag 0x%x\n", acqe_fcoe->index,
 			acqe_fcoe->event_tag);
 		/* If the event is not for currently used fcf do nothing */
-		if (phba->fcf.fcf_indx != acqe_fcoe->index)
+		if (phba->fcf.current_rec.fcf_indx != acqe_fcoe->index)
 			break;
-		/*
-		 * Currently, driver support only one FCF - so treat this as
-		 * a link down, but save the link state because we don't want
-		 * it to be changed to Link Down unless it is already down.
+		/* We request port to rediscover the entire FCF table for
+		 * a fast recovery from case that the current FCF record
+		 * is no longer valid if we are not in the middle of FCF
+		 * failover process already.
 		 */
-		link_state = phba->link_state;
-		lpfc_linkdown(phba);
-		phba->link_state = link_state;
-		/* Unregister FCF if no devices connected to it */
-		lpfc_unregister_unused_fcf(phba);
+		spin_lock_irq(&phba->hbalock);
+		if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
+			spin_unlock_irq(&phba->hbalock);
+			/* Update FLOGI FCF failover eligible FCF bmask */
+			lpfc_sli4_fcf_rr_index_clear(phba, acqe_fcoe->index);
+			break;
+		}
+		/* Mark the fast failover process in progress */
+		phba->fcf.fcf_flag |= FCF_DEAD_DISC;
+		spin_unlock_irq(&phba->hbalock);
+		lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+				"2771 Start FCF fast failover process due to "
+				"FCF DEAD event: evt_tag:x%x, fcf_index:x%x "
+				"\n", acqe_fcoe->event_tag, acqe_fcoe->index);
+		rc = lpfc_sli4_redisc_fcf_table(phba);
+		if (rc) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
+					LOG_DISCOVERY,
+					"2772 Issue FCF rediscover mabilbox "
+					"command failed, fail through to FCF "
+					"dead event\n");
+			spin_lock_irq(&phba->hbalock);
+			phba->fcf.fcf_flag &= ~FCF_DEAD_DISC;
+			spin_unlock_irq(&phba->hbalock);
+			/*
+			 * Last resort will fail over by treating this
+			 * as a link down to FCF registration.
+			 */
+			lpfc_sli4_fcf_dead_failthrough(phba);
+		} else
+			/* Handling fast FCF failover to a DEAD FCF event
+			 * is considered equalivant to receiving CVL to all
+			 * vports.
+			 */
+			lpfc_sli4_perform_all_vport_cvl(phba);
 		break;
 	case LPFC_FCOE_EVENT_TYPE_CVL:
-		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
+		lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
 			"2718 Clear Virtual Link Received for VPI 0x%x"
 			" tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag);
 		vport = lpfc_find_vport_by_vpid(phba,
 				acqe_fcoe->index - phba->vpi_base);
-		if (!vport)
-			break;
-		ndlp = lpfc_findnode_did(vport, Fabric_DID);
+		ndlp = lpfc_sli4_perform_vport_cvl(vport);
 		if (!ndlp)
 			break;
-		shost = lpfc_shost_from_vport(vport);
-		lpfc_linkdown_port(vport);
-		if (vport->port_type != LPFC_NPIV_PORT) {
+		active_vlink_present = 0;
+
+		vports = lpfc_create_vport_work_array(phba);
+		if (vports) {
+			for (i = 0; i <= phba->max_vports && vports[i] != NULL;
+					i++) {
+				if ((!(vports[i]->fc_flag &
+					FC_VPORT_CVL_RCVD)) &&
+					(vports[i]->port_state > LPFC_FDISC)) {
+					active_vlink_present = 1;
+					break;
+				}
+			}
+			lpfc_destroy_vport_work_array(phba, vports);
+		}
+
+		if (active_vlink_present) {
+			/*
+			 * If there are other active VLinks present,
+			 * re-instantiate the Vlink using FDISC.
+			 */
 			mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
+			shost = lpfc_shost_from_vport(vport);
 			spin_lock_irq(shost->host_lock);
 			ndlp->nlp_flag |= NLP_DELAY_TMO;
 			spin_unlock_irq(shost->host_lock);
-			ndlp->nlp_last_elscmd = ELS_CMD_FLOGI;
-			vport->port_state = LPFC_FLOGI;
+			ndlp->nlp_last_elscmd = ELS_CMD_FDISC;
+			vport->port_state = LPFC_FDISC;
+		} else {
+			/*
+			 * Otherwise, we request port to rediscover
+			 * the entire FCF table for a fast recovery
+			 * from possible case that the current FCF
+			 * is no longer valid if we are not already
+			 * in the FCF failover process.
+			 */
+			spin_lock_irq(&phba->hbalock);
+			if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
+				spin_unlock_irq(&phba->hbalock);
+				break;
+			}
+			/* Mark the fast failover process in progress */
+			phba->fcf.fcf_flag |= FCF_ACVL_DISC;
+			spin_unlock_irq(&phba->hbalock);
+			lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
+					LOG_DISCOVERY,
+					"2773 Start FCF fast failover due "
+					"to CVL event: evt_tag:x%x\n",
+					acqe_fcoe->event_tag);
+			rc = lpfc_sli4_redisc_fcf_table(phba);
+			if (rc) {
+				lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
+						LOG_DISCOVERY,
+						"2774 Issue FCF rediscover "
+						"mabilbox command failed, "
+						"through to CVL event\n");
+				spin_lock_irq(&phba->hbalock);
+				phba->fcf.fcf_flag &= ~FCF_ACVL_DISC;
+				spin_unlock_irq(&phba->hbalock);
+				/*
+				 * Last resort will be re-try on the
+				 * the current registered FCF entry.
+				 */
+				lpfc_retry_pport_discovery(phba);
+			}
 		}
 		break;
 	default:
@@ -3158,6 +3565,37 @@ void lpfc_sli4_async_event_proc(struct l
 }
 
 /**
+ * lpfc_sli4_fcf_redisc_event_proc - Process fcf table rediscovery event
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked by the worker thread to process FCF table
+ * rediscovery pending completion event.
+ **/
+void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *phba)
+{
+	int rc;
+
+	spin_lock_irq(&phba->hbalock);
+	/* Clear FCF rediscovery timeout event */
+	phba->fcf.fcf_flag &= ~FCF_REDISC_EVT;
+	/* Clear driver fast failover FCF record flag */
+	phba->fcf.failover_rec.flag = 0;
+	/* Set state for FCF fast failover */
+	phba->fcf.fcf_flag |= FCF_REDISC_FOV;
+	spin_unlock_irq(&phba->hbalock);
+
+	/* Scan FCF table from the first entry to re-discover SAN */
+	lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+			"2777 Start FCF table scan after FCF "
+			"rediscovery quiescent period over\n");
+	rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
+	if (rc)
+		lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
+				"2747 Issue FCF scan read FCF mailbox "
+				"command failed 0x%x\n", rc);
+}
+
+/**
  * lpfc_api_table_setup - Set up per hba pci-device group func api jump table
  * @phba: pointer to lpfc hba data structure.
  * @dev_grp: The HBA PCI-Device group number.
@@ -3442,8 +3880,11 @@ static int
 lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
 {
 	struct lpfc_sli *psli;
-	int rc;
-	int i, hbq_count;
+	LPFC_MBOXQ_t *mboxq;
+	int rc, i, hbq_count, buf_size, dma_buf_size, max_buf_size;
+	uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0};
+	struct lpfc_mqe *mqe;
+	int longs;
 
 	/* Before proceed, wait for POST done and device ready */
 	rc = lpfc_sli4_post_status_check(phba);
@@ -3472,6 +3913,11 @@ lpfc_sli4_driver_resource_setup(struct l
 	init_timer(&phba->eratt_poll);
 	phba->eratt_poll.function = lpfc_poll_eratt;
 	phba->eratt_poll.data = (unsigned long) phba;
+	/* FCF rediscover timer */
+	init_timer(&phba->fcf.redisc_wait);
+	phba->fcf.redisc_wait.function = lpfc_sli4_fcf_redisc_wait_tmo;
+	phba->fcf.redisc_wait.data = (unsigned long)phba;
+
 	/*
 	 * We need to do a READ_CONFIG mailbox command here before
 	 * calling lpfc_get_cfgparam. For VFs this will report the
@@ -3496,31 +3942,26 @@ lpfc_sli4_driver_resource_setup(struct l
 	 * used to create the sg_dma_buf_pool must be dynamically calculated.
 	 * 2 segments are added since the IOCB needs a command and response bde.
 	 * To insure that the scsi sgl does not cross a 4k page boundary only
-	 * sgl sizes of 1k, 2k, 4k, and 8k are supported.
-	 * Table of sgl sizes and seg_cnt:
-	 * sgl size, 	sg_seg_cnt	total seg
-	 * 1k		50		52
-	 * 2k		114		116
-	 * 4k		242		244
-	 * 8k		498		500
-	 * cmd(32) + rsp(160) + (52 * sizeof(sli4_sge)) = 1024
-	 * cmd(32) + rsp(160) + (116 * sizeof(sli4_sge)) = 2048
-	 * cmd(32) + rsp(160) + (244 * sizeof(sli4_sge)) = 4096
-	 * cmd(32) + rsp(160) + (500 * sizeof(sli4_sge)) = 8192
+	 * sgl sizes of must be a power of 2.
 	 */
-	if (phba->cfg_sg_seg_cnt <= LPFC_DEFAULT_SG_SEG_CNT)
-		phba->cfg_sg_seg_cnt = 50;
-	else if (phba->cfg_sg_seg_cnt <= 114)
-		phba->cfg_sg_seg_cnt = 114;
-	else if (phba->cfg_sg_seg_cnt <= 242)
-		phba->cfg_sg_seg_cnt = 242;
+	buf_size = (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp) +
+		    ((phba->cfg_sg_seg_cnt + 2) * sizeof(struct sli4_sge)));
+	/* Feature Level 1 hardware is limited to 2 pages */
+	if ((bf_get(lpfc_sli_intf_featurelevel1, &phba->sli4_hba.sli_intf) ==
+	     LPFC_SLI_INTF_FEATURELEVEL1_1))
+		max_buf_size = LPFC_SLI4_FL1_MAX_BUF_SIZE;
 	else
-		phba->cfg_sg_seg_cnt = 498;
-
-	phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd)
-					+ sizeof(struct fcp_rsp);
-	phba->cfg_sg_dma_buf_size +=
-		((phba->cfg_sg_seg_cnt + 2) * sizeof(struct sli4_sge));
+		max_buf_size = LPFC_SLI4_MAX_BUF_SIZE;
+	for (dma_buf_size = LPFC_SLI4_MIN_BUF_SIZE;
+	     dma_buf_size < max_buf_size && buf_size > dma_buf_size;
+	     dma_buf_size = dma_buf_size << 1)
+		;
+	if (dma_buf_size == max_buf_size)
+		phba->cfg_sg_seg_cnt = (dma_buf_size -
+			sizeof(struct fcp_cmnd) - sizeof(struct fcp_rsp) -
+			(2 * sizeof(struct sli4_sge))) /
+				sizeof(struct sli4_sge);
+	phba->cfg_sg_dma_buf_size = dma_buf_size;
 
 	/* Initialize buffer queue management fields */
 	hbq_count = lpfc_sli_hbq_count();
@@ -3620,13 +4061,24 @@ lpfc_sli4_driver_resource_setup(struct l
 		goto out_free_active_sgl;
 	}
 
+	/* Allocate eligible FCF bmask memory for FCF round robin failover */
+	longs = (LPFC_SLI4_FCF_TBL_INDX_MAX + BITS_PER_LONG - 1)/BITS_PER_LONG;
+	phba->fcf.fcf_rr_bmask = kzalloc(longs * sizeof(unsigned long),
+					 GFP_KERNEL);
+	if (!phba->fcf.fcf_rr_bmask) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"2759 Failed allocate memory for FCF round "
+				"robin failover bmask\n");
+		goto out_remove_rpi_hdrs;
+	}
+
 	phba->sli4_hba.fcp_eq_hdl = kzalloc((sizeof(struct lpfc_fcp_eq_hdl) *
 				    phba->cfg_fcp_eq_count), GFP_KERNEL);
 	if (!phba->sli4_hba.fcp_eq_hdl) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 				"2572 Failed allocate memory for fast-path "
 				"per-EQ handle array\n");
-		goto out_remove_rpi_hdrs;
+		goto out_free_fcf_rr_bmask;
 	}
 
 	phba->sli4_hba.msix_entries = kzalloc((sizeof(struct msix_entry) *
@@ -3638,10 +4090,49 @@ lpfc_sli4_driver_resource_setup(struct l
 		goto out_free_fcp_eq_hdl;
 	}
 
+	mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
+						       GFP_KERNEL);
+	if (!mboxq) {
+		rc = -ENOMEM;
+		goto out_free_fcp_eq_hdl;
+	}
+
+	/* Get the Supported Pages. It is always available. */
+	lpfc_supported_pages(mboxq);
+	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+	if (unlikely(rc)) {
+		rc = -EIO;
+		mempool_free(mboxq, phba->mbox_mem_pool);
+		goto out_free_fcp_eq_hdl;
+	}
+
+	mqe = &mboxq->u.mqe;
+	memcpy(&pn_page[0], ((uint8_t *)&mqe->un.supp_pages.word3),
+	       LPFC_MAX_SUPPORTED_PAGES);
+	for (i = 0; i < LPFC_MAX_SUPPORTED_PAGES; i++) {
+		switch (pn_page[i]) {
+		case LPFC_SLI4_PARAMETERS:
+			phba->sli4_hba.pc_sli4_params.supported = 1;
+			break;
+		default:
+			break;
+		}
+	}
+
+	/* Read the port's SLI4 Parameters capabilities if supported. */
+	if (phba->sli4_hba.pc_sli4_params.supported)
+		rc = lpfc_pc_sli4_params_get(phba, mboxq);
+	mempool_free(mboxq, phba->mbox_mem_pool);
+	if (rc) {
+		rc = -EIO;
+		goto out_free_fcp_eq_hdl;
+	}
 	return rc;
 
 out_free_fcp_eq_hdl:
 	kfree(phba->sli4_hba.fcp_eq_hdl);
+out_free_fcf_rr_bmask:
+	kfree(phba->fcf.fcf_rr_bmask);
 out_remove_rpi_hdrs:
 	lpfc_sli4_remove_rpi_hdrs(phba);
 out_free_active_sgl:
@@ -3687,6 +4178,9 @@ lpfc_sli4_driver_resource_unset(struct l
 	lpfc_sli4_remove_rpi_hdrs(phba);
 	lpfc_sli4_remove_rpis(phba);
 
+	/* Free eligible FCF index bmask */
+	kfree(phba->fcf.fcf_rr_bmask);
+
 	/* Free the ELS sgl list */
 	lpfc_free_active_sgl(phba);
 	lpfc_free_sgl_list(phba);
@@ -3733,6 +4227,8 @@ lpfc_sli4_driver_resource_unset(struct l
 int
 lpfc_init_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp)
 {
+	phba->lpfc_hba_init_link = lpfc_hba_init_link;
+	phba->lpfc_hba_down_link = lpfc_hba_down_link;
 	switch (dev_grp) {
 	case LPFC_PCI_DEV_LP:
 		phba->lpfc_hba_down_post = lpfc_hba_down_post_s3;
@@ -4080,6 +4576,7 @@ lpfc_init_sgl_list(struct lpfc_hba *phba
 
 		/* The list order is used by later block SGL registraton */
 		spin_lock_irq(&phba->hbalock);
+		sglq_entry->state = SGL_FREED;
 		list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_sgl_list);
 		phba->sli4_hba.lpfc_els_sgl_array[i] = sglq_entry;
 		phba->sli4_hba.total_sglq_bufs++;
@@ -4291,7 +4788,7 @@ lpfc_hba_alloc(struct pci_dev *pdev)
 		return NULL;
 	}
 
-	mutex_init(&phba->ct_event_mutex);
+	spin_lock_init(&phba->ct_ev_lock);
 	INIT_LIST_HEAD(&phba->ct_ev_waiters);
 
 	return phba;
@@ -4641,7 +5138,7 @@ lpfc_sli_pci_mem_unset(struct lpfc_hba *
 int
 lpfc_sli4_post_status_check(struct lpfc_hba *phba)
 {
-	struct lpfc_register sta_reg, uerrlo_reg, uerrhi_reg, scratchpad;
+	struct lpfc_register sta_reg, uerrlo_reg, uerrhi_reg;
 	int i, port_error = -ENODEV;
 
 	if (!phba->sli4_hba.STAregaddr)
@@ -4677,14 +5174,21 @@ lpfc_sli4_post_status_check(struct lpfc_
 			bf_get(lpfc_hst_state_port_status, &sta_reg));
 
 	/* Log device information */
-	scratchpad.word0 =  readl(phba->sli4_hba.SCRATCHPADregaddr);
-	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-			"2534 Device Info: ChipType=0x%x, SliRev=0x%x, "
-			"FeatureL1=0x%x, FeatureL2=0x%x\n",
-			bf_get(lpfc_scratchpad_chiptype, &scratchpad),
-			bf_get(lpfc_scratchpad_slirev, &scratchpad),
-			bf_get(lpfc_scratchpad_featurelevel1, &scratchpad),
-			bf_get(lpfc_scratchpad_featurelevel2, &scratchpad));
+	phba->sli4_hba.sli_intf.word0 = readl(phba->sli4_hba.SLIINTFregaddr);
+	if (bf_get(lpfc_sli_intf_valid,
+		   &phba->sli4_hba.sli_intf) == LPFC_SLI_INTF_VALID) {
+		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+				"2534 Device Info: ChipType=0x%x, SliRev=0x%x, "
+				"FeatureL1=0x%x, FeatureL2=0x%x\n",
+				bf_get(lpfc_sli_intf_sli_family,
+				       &phba->sli4_hba.sli_intf),
+				bf_get(lpfc_sli_intf_slirev,
+				       &phba->sli4_hba.sli_intf),
+				bf_get(lpfc_sli_intf_featurelevel1,
+				       &phba->sli4_hba.sli_intf),
+				bf_get(lpfc_sli_intf_featurelevel2,
+				       &phba->sli4_hba.sli_intf));
+	}
 	phba->sli4_hba.ue_mask_lo = readl(phba->sli4_hba.UEMASKLOregaddr);
 	phba->sli4_hba.ue_mask_hi = readl(phba->sli4_hba.UEMASKHIregaddr);
 	/* With uncoverable error, log the error message and return error */
@@ -4723,8 +5227,8 @@ lpfc_sli4_bar0_register_memmap(struct lp
 					LPFC_UE_MASK_LO;
 	phba->sli4_hba.UEMASKHIregaddr = phba->sli4_hba.conf_regs_memmap_p +
 					LPFC_UE_MASK_HI;
-	phba->sli4_hba.SCRATCHPADregaddr = phba->sli4_hba.conf_regs_memmap_p +
-					LPFC_SCRATCHPAD;
+	phba->sli4_hba.SLIINTFregaddr = phba->sli4_hba.conf_regs_memmap_p +
+					LPFC_SLI_INTF;
 }
 
 /**
@@ -5999,7 +6503,7 @@ lpfc_sli4_fcfi_unreg(struct lpfc_hba *ph
 		spin_lock_irqsave(&phba->hbalock, flags);
 		/* Mark the FCFI is no longer registered */
 		phba->fcf.fcf_flag &=
-			~(FCF_AVAILABLE | FCF_REGISTERED | FCF_DISCOVERED);
+			~(FCF_AVAILABLE | FCF_REGISTERED | FCF_SCAN_DONE);
 		spin_unlock_irqrestore(&phba->hbalock, flags);
 	}
 }
@@ -6039,16 +6543,20 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba
 
 	/* Get the bus address of SLI4 device Bar0, Bar1, and Bar2 and the
 	 * number of bytes required by each mapping. They are actually
-	 * mapping to the PCI BAR regions 1, 2, and 4 by the SLI4 device.
+	 * mapping to the PCI BAR regions 0 or 1, 2, and 4 by the SLI4 device.
 	 */
-	phba->pci_bar0_map = pci_resource_start(pdev, LPFC_SLI4_BAR0);
-	bar0map_len = pci_resource_len(pdev, LPFC_SLI4_BAR0);
-
-	phba->pci_bar1_map = pci_resource_start(pdev, LPFC_SLI4_BAR1);
-	bar1map_len = pci_resource_len(pdev, LPFC_SLI4_BAR1);
+	if (pci_resource_start(pdev, 0)) {
+		phba->pci_bar0_map = pci_resource_start(pdev, 0);
+		bar0map_len = pci_resource_len(pdev, 0);
+	} else {
+		phba->pci_bar0_map = pci_resource_start(pdev, 1);
+		bar0map_len = pci_resource_len(pdev, 1);
+	}
+	phba->pci_bar1_map = pci_resource_start(pdev, 2);
+	bar1map_len = pci_resource_len(pdev, 2);
 
-	phba->pci_bar2_map = pci_resource_start(pdev, LPFC_SLI4_BAR2);
-	bar2map_len = pci_resource_len(pdev, LPFC_SLI4_BAR2);
+	phba->pci_bar2_map = pci_resource_start(pdev, 4);
+	bar2map_len = pci_resource_len(pdev, 4);
 
 	/* Map SLI4 PCI Config Space Register base to a kernel virtual addr */
 	phba->sli4_hba.conf_regs_memmap_p =
@@ -6793,6 +7301,73 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phb
 	phba->pport->work_port_events = 0;
 }
 
+ /**
+ * lpfc_pc_sli4_params_get - Get the SLI4_PARAMS port capabilities.
+ * @phba: Pointer to HBA context object.
+ * @mboxq: Pointer to the mailboxq memory for the mailbox command response.
+ *
+ * This function is called in the SLI4 code path to read the port's
+ * sli4 capabilities.
+ *
+ * This function may be be called from any context that can block-wait
+ * for the completion.  The expectation is that this routine is called
+ * typically from probe_one or from the online routine.
+ **/
+int
+lpfc_pc_sli4_params_get(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+	int rc;
+	struct lpfc_mqe *mqe;
+	struct lpfc_pc_sli4_params *sli4_params;
+	uint32_t mbox_tmo;
+
+	rc = 0;
+	mqe = &mboxq->u.mqe;
+
+	/* Read the port's SLI4 Parameters port capabilities */
+	lpfc_sli4_params(mboxq);
+	if (!phba->sli4_hba.intr_enable)
+		rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+	else {
+		mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_PORT_CAPABILITIES);
+		rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo);
+	}
+
+	if (unlikely(rc))
+		return 1;
+
+	sli4_params = &phba->sli4_hba.pc_sli4_params;
+	sli4_params->if_type = bf_get(if_type, &mqe->un.sli4_params);
+	sli4_params->sli_rev = bf_get(sli_rev, &mqe->un.sli4_params);
+	sli4_params->sli_family = bf_get(sli_family, &mqe->un.sli4_params);
+	sli4_params->featurelevel_1 = bf_get(featurelevel_1,
+					     &mqe->un.sli4_params);
+	sli4_params->featurelevel_2 = bf_get(featurelevel_2,
+					     &mqe->un.sli4_params);
+	sli4_params->proto_types = mqe->un.sli4_params.word3;
+	sli4_params->sge_supp_len = mqe->un.sli4_params.sge_supp_len;
+	sli4_params->if_page_sz = bf_get(if_page_sz, &mqe->un.sli4_params);
+	sli4_params->rq_db_window = bf_get(rq_db_window, &mqe->un.sli4_params);
+	sli4_params->loopbk_scope = bf_get(loopbk_scope, &mqe->un.sli4_params);
+	sli4_params->eq_pages_max = bf_get(eq_pages, &mqe->un.sli4_params);
+	sli4_params->eqe_size = bf_get(eqe_size, &mqe->un.sli4_params);
+	sli4_params->cq_pages_max = bf_get(cq_pages, &mqe->un.sli4_params);
+	sli4_params->cqe_size = bf_get(cqe_size, &mqe->un.sli4_params);
+	sli4_params->mq_pages_max = bf_get(mq_pages, &mqe->un.sli4_params);
+	sli4_params->mqe_size = bf_get(mqe_size, &mqe->un.sli4_params);
+	sli4_params->mq_elem_cnt = bf_get(mq_elem_cnt, &mqe->un.sli4_params);
+	sli4_params->wq_pages_max = bf_get(wq_pages, &mqe->un.sli4_params);
+	sli4_params->wqe_size = bf_get(wqe_size, &mqe->un.sli4_params);
+	sli4_params->rq_pages_max = bf_get(rq_pages, &mqe->un.sli4_params);
+	sli4_params->rqe_size = bf_get(rqe_size, &mqe->un.sli4_params);
+	sli4_params->hdr_pages_max = bf_get(hdr_pages, &mqe->un.sli4_params);
+	sli4_params->hdr_size = bf_get(hdr_size, &mqe->un.sli4_params);
+	sli4_params->hdr_pp_align = bf_get(hdr_pp_align, &mqe->un.sli4_params);
+	sli4_params->sgl_pages_max = bf_get(sgl_pages, &mqe->un.sli4_params);
+	sli4_params->sgl_pp_align = bf_get(sgl_pp_align, &mqe->un.sli4_params);
+	return rc;
+}
+
 /**
  * lpfc_pci_probe_one_s3 - PCI probe func to reg SLI-3 device to PCI subsystem.
  * @pdev: pointer to PCI device
@@ -7134,6 +7709,12 @@ lpfc_pci_resume_one_s3(struct pci_dev *p
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 
+	/*
+	 * As the new kernel behavior of pci_restore_state() API call clears
+	 * device saved_state flag, need to save the restored state again.
+	 */
+	pci_save_state(pdev);
+
 	if (pdev->is_busmaster)
 		pci_set_master(pdev);
 
@@ -7317,6 +7898,13 @@ lpfc_io_slot_reset_s3(struct pci_dev *pd
 	}
 
 	pci_restore_state(pdev);
+
+	/*
+	 * As the new kernel behavior of pci_restore_state() API call clears
+	 * device saved_state flag, need to save the restored state again.
+	 */
+	pci_save_state(pdev);
+
 	if (pdev->is_busmaster)
 		pci_set_master(pdev);
 
@@ -7726,6 +8314,13 @@ lpfc_pci_resume_one_s4(struct pci_dev *p
 	/* Restore device state from PCI config space */
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
+
+	/*
+	 * As the new kernel behavior of pci_restore_state() API call clears
+	 * device saved_state flag, need to save the restored state again.
+	 */
+	pci_save_state(pdev);
+
 	if (pdev->is_busmaster)
 		pci_set_master(pdev);
 
@@ -7845,11 +8440,11 @@ lpfc_pci_probe_one(struct pci_dev *pdev,
 	int rc;
 	struct lpfc_sli_intf intf;
 
-	if (pci_read_config_dword(pdev, LPFC_SLIREV_CONF_WORD, &intf.word0))
+	if (pci_read_config_dword(pdev, LPFC_SLI_INTF, &intf.word0))
 		return -ENODEV;
 
 	if ((bf_get(lpfc_sli_intf_valid, &intf) == LPFC_SLI_INTF_VALID) &&
-		(bf_get(lpfc_sli_intf_rev, &intf) == LPFC_SLIREV_CONF_SLI4))
+	    (bf_get(lpfc_sli_intf_slirev, &intf) == LPFC_SLI_INTF_REV_SLI4))
 		rc = lpfc_pci_probe_one_s4(pdev, pid);
 	else
 		rc = lpfc_pci_probe_one_s3(pdev, pid);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_logmsg.h linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_logmsg.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_logmsg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_logmsg.h	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #define LOG_VPORT	0x00004000	/* NPIV events */
 #define LOF_SECURITY	0x00008000	/* Security events */
 #define LOG_EVENT	0x00010000	/* CT,TEMP,DUMP, logging */
+#define LOG_FIP		0x00020000	/* FIP events */
 #define LOG_ALL_MSG	0xffffffff	/* LOG all messages */
 
 #define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_mbox.c linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_mbox.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_mbox.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_mbox.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 
 #include <linux/blkdev.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 
 #include <scsi/scsi_device.h>
@@ -1707,7 +1708,8 @@ lpfc_sli4_config(struct lpfc_hba *phba,
 				alloc_len - sizeof(union  lpfc_sli4_cfg_shdr);
 	}
 	/* The sub-header is in DMA memory, which needs endian converstion */
-	lpfc_sli_pcimem_bcopy(cfg_shdr, cfg_shdr,
+	if (cfg_shdr)
+		lpfc_sli_pcimem_bcopy(cfg_shdr, cfg_shdr,
 			      sizeof(union  lpfc_sli4_cfg_shdr));
 
 	return alloc_len;
@@ -1747,6 +1749,65 @@ lpfc_sli4_mbox_opcode_get(struct lpfc_hb
 }
 
 /**
+ * lpfc_sli4_mbx_read_fcf_rec - Allocate and construct read fcf mbox cmd
+ * @phba: pointer to lpfc hba data structure.
+ * @fcf_index: index to fcf table.
+ *
+ * This routine routine allocates and constructs non-embedded mailbox command
+ * for reading a FCF table entry refered by @fcf_index.
+ *
+ * Return: pointer to the mailbox command constructed if successful, otherwise
+ * NULL.
+ **/
+int
+lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *phba,
+			   struct lpfcMboxq *mboxq,
+			   uint16_t fcf_index)
+{
+	void *virt_addr;
+	dma_addr_t phys_addr;
+	uint8_t *bytep;
+	struct lpfc_mbx_sge sge;
+	uint32_t alloc_len, req_len;
+	struct lpfc_mbx_read_fcf_tbl *read_fcf;
+
+	if (!mboxq)
+		return -ENOMEM;
+
+	req_len = sizeof(struct fcf_record) +
+		  sizeof(union lpfc_sli4_cfg_shdr) + 2 * sizeof(uint32_t);
+
+	/* Set up READ_FCF SLI4_CONFIG mailbox-ioctl command */
+	alloc_len = lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_FCOE,
+			LPFC_MBOX_OPCODE_FCOE_READ_FCF_TABLE, req_len,
+			LPFC_SLI4_MBX_NEMBED);
+
+	if (alloc_len < req_len) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
+				"0291 Allocated DMA memory size (x%x) is "
+				"less than the requested DMA memory "
+				"size (x%x)\n", alloc_len, req_len);
+		return -ENOMEM;
+	}
+
+	/* Get the first SGE entry from the non-embedded DMA memory. This
+	 * routine only uses a single SGE.
+	 */
+	lpfc_sli4_mbx_sge_get(mboxq, 0, &sge);
+	phys_addr = getPaddr(sge.pa_hi, sge.pa_lo);
+	virt_addr = mboxq->sge_array->addr[0];
+	read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr;
+
+	/* Set up command fields */
+	bf_set(lpfc_mbx_read_fcf_tbl_indx, &read_fcf->u.request, fcf_index);
+	/* Perform necessary endian conversion */
+	bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr);
+	lpfc_sli_pcimem_bcopy(bytep, bytep, sizeof(uint32_t));
+
+	return 0;
+}
+
+/**
  * lpfc_request_features: Configure SLI4 REQUEST_FEATURES mailbox
  * @mboxq: pointer to lpfc mbox command.
  *
@@ -1946,13 +2007,14 @@ lpfc_reg_fcfi(struct lpfc_hba *phba, str
 	bf_set(lpfc_reg_fcfi_rq_id1, reg_fcfi, REG_FCF_INVALID_QID);
 	bf_set(lpfc_reg_fcfi_rq_id2, reg_fcfi, REG_FCF_INVALID_QID);
 	bf_set(lpfc_reg_fcfi_rq_id3, reg_fcfi, REG_FCF_INVALID_QID);
-	bf_set(lpfc_reg_fcfi_info_index, reg_fcfi, phba->fcf.fcf_indx);
+	bf_set(lpfc_reg_fcfi_info_index, reg_fcfi,
+	       phba->fcf.current_rec.fcf_indx);
 	/* reg_fcf addr mode is bit wise inverted value of fcf addr_mode */
-	bf_set(lpfc_reg_fcfi_mam, reg_fcfi,
-		(~phba->fcf.addr_mode) & 0x3);
-	if (phba->fcf.fcf_flag & FCF_VALID_VLAN) {
+	bf_set(lpfc_reg_fcfi_mam, reg_fcfi, (~phba->fcf.addr_mode) & 0x3);
+	if (phba->fcf.current_rec.vlan_id != 0xFFFF) {
 		bf_set(lpfc_reg_fcfi_vv, reg_fcfi, 1);
-		bf_set(lpfc_reg_fcfi_vlan_tag, reg_fcfi, phba->fcf.vlan_id);
+		bf_set(lpfc_reg_fcfi_vlan_tag, reg_fcfi,
+		       phba->fcf.current_rec.vlan_id);
 	}
 }
 
@@ -1992,3 +2054,41 @@ lpfc_resume_rpi(struct lpfcMboxq *mbox,
 	bf_set(lpfc_resume_rpi_ii, resume_rpi, RESUME_INDEX_RPI);
 	resume_rpi->event_tag = ndlp->phba->fc_eventTag;
 }
+
+/**
+ * lpfc_supported_pages - Initialize the PORT_CAPABILITIES supported pages
+ *                        mailbox command.
+ * @mbox: pointer to lpfc mbox command to initialize.
+ *
+ * The PORT_CAPABILITIES supported pages mailbox command is issued to
+ * retrieve the particular feature pages supported by the port.
+ **/
+void
+lpfc_supported_pages(struct lpfcMboxq *mbox)
+{
+	struct lpfc_mbx_supp_pages *supp_pages;
+
+	memset(mbox, 0, sizeof(*mbox));
+	supp_pages = &mbox->u.mqe.un.supp_pages;
+	bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES);
+	bf_set(cpn, supp_pages, LPFC_SUPP_PAGES);
+}
+
+/**
+ * lpfc_sli4_params - Initialize the PORT_CAPABILITIES SLI4 Params
+ *                    mailbox command.
+ * @mbox: pointer to lpfc mbox command to initialize.
+ *
+ * The PORT_CAPABILITIES SLI4 parameters mailbox command is issued to
+ * retrieve the particular SLI4 features supported by the port.
+ **/
+void
+lpfc_sli4_params(struct lpfcMboxq *mbox)
+{
+	struct lpfc_mbx_sli4_params *sli4_params;
+
+	memset(mbox, 0, sizeof(*mbox));
+	sli4_params = &mbox->u.mqe.un.sli4_params;
+	bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES);
+	bf_set(cpn, sli4_params, LPFC_SLI4_PARAMETERS);
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_mem.c linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_mem.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_mem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_mem.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  *******************************************************************/
 
 #include <linux/mempool.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_nl.h linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_nl.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_nl.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_nl.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2008 Emulex.  All rights reserved.                *
+ * Copyright (C) 2010 Emulex.  All rights reserved.                *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
@@ -177,23 +177,3 @@ struct temp_event {
 	uint32_t data;
 };
 
-/* bsg definitions */
-#define LPFC_BSG_VENDOR_SET_CT_EVENT	1
-#define LPFC_BSG_VENDOR_GET_CT_EVENT	2
-
-struct set_ct_event {
-	uint32_t command;
-	uint32_t ev_req_id;
-	uint32_t ev_reg_id;
-};
-
-struct get_ct_event {
-	uint32_t command;
-	uint32_t ev_reg_id;
-	uint32_t ev_req_id;
-};
-
-struct get_ct_event_reply {
-	uint32_t immed_data;
-	uint32_t type;
-};
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_nportdisc.c linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_nportdisc.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_nportdisc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_nportdisc.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 
 #include <linux/blkdev.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 
 #include <scsi/scsi.h>
@@ -62,7 +63,7 @@ lpfc_check_adisc(struct lpfc_vport *vpor
 
 int
 lpfc_check_sparm(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
-		 struct serv_parm * sp, uint32_t class)
+		 struct serv_parm *sp, uint32_t class, int flogi)
 {
 	volatile struct serv_parm *hsp = &vport->fc_sparam;
 	uint16_t hsp_value, ssp_value = 0;
@@ -75,49 +76,56 @@ lpfc_check_sparm(struct lpfc_vport *vpor
 	 * correcting the byte values.
 	 */
 	if (sp->cls1.classValid) {
-		hsp_value = (hsp->cls1.rcvDataSizeMsb << 8) |
-				hsp->cls1.rcvDataSizeLsb;
-		ssp_value = (sp->cls1.rcvDataSizeMsb << 8) |
-				sp->cls1.rcvDataSizeLsb;
-		if (!ssp_value)
-			goto bad_service_param;
-		if (ssp_value > hsp_value) {
-			sp->cls1.rcvDataSizeLsb = hsp->cls1.rcvDataSizeLsb;
-			sp->cls1.rcvDataSizeMsb = hsp->cls1.rcvDataSizeMsb;
+		if (!flogi) {
+			hsp_value = ((hsp->cls1.rcvDataSizeMsb << 8) |
+				     hsp->cls1.rcvDataSizeLsb);
+			ssp_value = ((sp->cls1.rcvDataSizeMsb << 8) |
+				     sp->cls1.rcvDataSizeLsb);
+			if (!ssp_value)
+				goto bad_service_param;
+			if (ssp_value > hsp_value) {
+				sp->cls1.rcvDataSizeLsb =
+					hsp->cls1.rcvDataSizeLsb;
+				sp->cls1.rcvDataSizeMsb =
+					hsp->cls1.rcvDataSizeMsb;
+			}
 		}
-	} else if (class == CLASS1) {
+	} else if (class == CLASS1)
 		goto bad_service_param;
-	}
-
 	if (sp->cls2.classValid) {
-		hsp_value = (hsp->cls2.rcvDataSizeMsb << 8) |
-				hsp->cls2.rcvDataSizeLsb;
-		ssp_value = (sp->cls2.rcvDataSizeMsb << 8) |
-				sp->cls2.rcvDataSizeLsb;
-		if (!ssp_value)
-			goto bad_service_param;
-		if (ssp_value > hsp_value) {
-			sp->cls2.rcvDataSizeLsb = hsp->cls2.rcvDataSizeLsb;
-			sp->cls2.rcvDataSizeMsb = hsp->cls2.rcvDataSizeMsb;
+		if (!flogi) {
+			hsp_value = ((hsp->cls2.rcvDataSizeMsb << 8) |
+				     hsp->cls2.rcvDataSizeLsb);
+			ssp_value = ((sp->cls2.rcvDataSizeMsb << 8) |
+				     sp->cls2.rcvDataSizeLsb);
+			if (!ssp_value)
+				goto bad_service_param;
+			if (ssp_value > hsp_value) {
+				sp->cls2.rcvDataSizeLsb =
+					hsp->cls2.rcvDataSizeLsb;
+				sp->cls2.rcvDataSizeMsb =
+					hsp->cls2.rcvDataSizeMsb;
+			}
 		}
-	} else if (class == CLASS2) {
+	} else if (class == CLASS2)
 		goto bad_service_param;
-	}
-
 	if (sp->cls3.classValid) {
-		hsp_value = (hsp->cls3.rcvDataSizeMsb << 8) |
-				hsp->cls3.rcvDataSizeLsb;
-		ssp_value = (sp->cls3.rcvDataSizeMsb << 8) |
-				sp->cls3.rcvDataSizeLsb;
-		if (!ssp_value)
-			goto bad_service_param;
-		if (ssp_value > hsp_value) {
-			sp->cls3.rcvDataSizeLsb = hsp->cls3.rcvDataSizeLsb;
-			sp->cls3.rcvDataSizeMsb = hsp->cls3.rcvDataSizeMsb;
+		if (!flogi) {
+			hsp_value = ((hsp->cls3.rcvDataSizeMsb << 8) |
+				     hsp->cls3.rcvDataSizeLsb);
+			ssp_value = ((sp->cls3.rcvDataSizeMsb << 8) |
+				     sp->cls3.rcvDataSizeLsb);
+			if (!ssp_value)
+				goto bad_service_param;
+			if (ssp_value > hsp_value) {
+				sp->cls3.rcvDataSizeLsb =
+					hsp->cls3.rcvDataSizeLsb;
+				sp->cls3.rcvDataSizeMsb =
+					hsp->cls3.rcvDataSizeMsb;
+			}
 		}
-	} else if (class == CLASS3) {
+	} else if (class == CLASS3)
 		goto bad_service_param;
-	}
 
 	/*
 	 * Preserve the upper four bits of the MSB from the PLOGI response.
@@ -247,7 +255,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport,
 	int rc;
 
 	memset(&stat, 0, sizeof (struct ls_rjt));
-	if (vport->port_state <= LPFC_FLOGI) {
+	if (vport->port_state <= LPFC_FDISC) {
 		/* Before responding to PLOGI, check for pt2pt mode.
 		 * If we are pt2pt, with an outstanding FLOGI, abort
 		 * the FLOGI and resend it first.
@@ -295,7 +303,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport,
 			NULL);
 		return 0;
 	}
-	if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3) == 0)) {
+	if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 0) == 0)) {
 		/* Reject this request because invalid parameters */
 		stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
 		stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
@@ -831,7 +839,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_
 				 "0142 PLOGI RSP: Invalid WWN.\n");
 		goto out;
 	}
-	if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3))
+	if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3, 0))
 		goto out;
 	/* PLOGI chkparm OK */
 	lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_scsi.c linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_scsi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_scsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_scsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  * included with this package.                                     *
  *******************************************************************/
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <asm/unaligned.h>
@@ -620,22 +621,40 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hb
 	uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri);
 	struct lpfc_scsi_buf *psb, *next_psb;
 	unsigned long iflag = 0;
+	struct lpfc_iocbq *iocbq;
+	int i;
 
-	spin_lock_irqsave(&phba->sli4_hba.abts_scsi_buf_list_lock, iflag);
+	spin_lock_irqsave(&phba->hbalock, iflag);
+	spin_lock(&phba->sli4_hba.abts_scsi_buf_list_lock);
 	list_for_each_entry_safe(psb, next_psb,
 		&phba->sli4_hba.lpfc_abts_scsi_buf_list, list) {
 		if (psb->cur_iocbq.sli4_xritag == xri) {
 			list_del(&psb->list);
+			psb->exch_busy = 0;
 			psb->status = IOSTAT_SUCCESS;
-			spin_unlock_irqrestore(
-				&phba->sli4_hba.abts_scsi_buf_list_lock,
-				iflag);
+			spin_unlock(
+				&phba->sli4_hba.abts_scsi_buf_list_lock);
+			spin_unlock_irqrestore(&phba->hbalock, iflag);
 			lpfc_release_scsi_buf_s4(phba, psb);
 			return;
 		}
 	}
-	spin_unlock_irqrestore(&phba->sli4_hba.abts_scsi_buf_list_lock,
-				iflag);
+	spin_unlock(&phba->sli4_hba.abts_scsi_buf_list_lock);
+	for (i = 1; i <= phba->sli.last_iotag; i++) {
+		iocbq = phba->sli.iocbq_lookup[i];
+
+		if (!(iocbq->iocb_flag &  LPFC_IO_FCP) ||
+			(iocbq->iocb_flag & LPFC_IO_LIBDFC))
+			continue;
+		if (iocbq->sli4_xritag != xri)
+			continue;
+		psb = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq);
+		psb->exch_busy = 0;
+		spin_unlock_irqrestore(&phba->hbalock, iflag);
+		return;
+
+	}
+	spin_unlock_irqrestore(&phba->hbalock, iflag);
 }
 
 /**
@@ -688,11 +707,12 @@ lpfc_sli4_repost_scsi_sgl_list(struct lp
 					 list);
 			if (status) {
 				/* Put this back on the abort scsi list */
-				psb->status = IOSTAT_LOCAL_REJECT;
-				psb->result = IOERR_ABORT_REQUESTED;
+				psb->exch_busy = 1;
 				rc++;
-			} else
+			} else {
+				psb->exch_busy = 0;
 				psb->status = IOSTAT_SUCCESS;
+			}
 			/* Put it back into the SCSI buffer list */
 			lpfc_release_scsi_buf_s4(phba, psb);
 		}
@@ -796,19 +816,17 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *
 		 */
 		sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_cmd));
 		sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_cmd));
-		bf_set(lpfc_sli4_sge_len, sgl, sizeof(struct fcp_cmnd));
 		bf_set(lpfc_sli4_sge_last, sgl, 0);
 		sgl->word2 = cpu_to_le32(sgl->word2);
-		sgl->word3 = cpu_to_le32(sgl->word3);
+		sgl->sge_len = cpu_to_le32(sizeof(struct fcp_cmnd));
 		sgl++;
 
 		/* Setup the physical region for the FCP RSP */
 		sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_rsp));
 		sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_rsp));
-		bf_set(lpfc_sli4_sge_len, sgl, sizeof(struct fcp_rsp));
 		bf_set(lpfc_sli4_sge_last, sgl, 1);
 		sgl->word2 = cpu_to_le32(sgl->word2);
-		sgl->word3 = cpu_to_le32(sgl->word3);
+		sgl->sge_len = cpu_to_le32(sizeof(struct fcp_rsp));
 
 		/*
 		 * Since the IOCB for the FCP I/O is built into this
@@ -839,11 +857,12 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *
 						psb->cur_iocbq.sli4_xritag);
 			if (status) {
 				/* Put this back on the abort scsi list */
-				psb->status = IOSTAT_LOCAL_REJECT;
-				psb->result = IOERR_ABORT_REQUESTED;
+				psb->exch_busy = 1;
 				rc++;
-			} else
+			} else {
+				psb->exch_busy = 0;
 				psb->status = IOSTAT_SUCCESS;
+			}
 			/* Put it back into the SCSI buffer list */
 			lpfc_release_scsi_buf_s4(phba, psb);
 			break;
@@ -857,11 +876,12 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *
 				 list);
 			if (status) {
 				/* Put this back on the abort scsi list */
-				psb->status = IOSTAT_LOCAL_REJECT;
-				psb->result = IOERR_ABORT_REQUESTED;
+				psb->exch_busy = 1;
 				rc++;
-			} else
+			} else {
+				psb->exch_busy = 0;
 				psb->status = IOSTAT_SUCCESS;
+			}
 			/* Put it back into the SCSI buffer list */
 			lpfc_release_scsi_buf_s4(phba, psb);
 		}
@@ -951,8 +971,7 @@ lpfc_release_scsi_buf_s4(struct lpfc_hba
 {
 	unsigned long iflag = 0;
 
-	if (psb->status == IOSTAT_LOCAL_REJECT
-		&& psb->result == IOERR_ABORT_REQUESTED) {
+	if (psb->exch_busy) {
 		spin_lock_irqsave(&phba->sli4_hba.abts_scsi_buf_list_lock,
 					iflag);
 		psb->pCmd = NULL;
@@ -1005,6 +1024,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hb
 	struct scatterlist *sgel = NULL;
 	struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
 	struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl;
+	struct lpfc_iocbq *iocbq = &lpfc_cmd->cur_iocbq;
 	IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
 	struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde;
 	dma_addr_t physaddr;
@@ -1055,6 +1075,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hb
 			physaddr = sg_dma_address(sgel);
 			if (phba->sli_rev == 3 &&
 			    !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
+			    !(iocbq->iocb_flag & DSS_SECURITY_OP) &&
 			    nseg <= LPFC_EXT_DATA_BDE_COUNT) {
 				data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
 				data_bde->tus.f.bdeSize = sg_dma_len(sgel);
@@ -1081,7 +1102,8 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hb
 	 * explicitly reinitialized since all iocb memory resources are reused.
 	 */
 	if (phba->sli_rev == 3 &&
-	    !(phba->sli3_options & LPFC_SLI3_BG_ENABLED)) {
+	    !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
+	    !(iocbq->iocb_flag & DSS_SECURITY_OP)) {
 		if (num_bde > LPFC_EXT_DATA_BDE_COUNT) {
 			/*
 			 * The extended IOCB format can only fit 3 BDE or a BPL.
@@ -1106,6 +1128,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hb
 	} else {
 		iocb_cmd->un.fcpi64.bdl.bdeSize =
 			((num_bde + 2) * sizeof(struct ulp_bde64));
+		iocb_cmd->unsli3.fcp_ext.ebde_count = (num_bde + 1);
 	}
 	fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd));
 
@@ -1574,7 +1597,7 @@ lpfc_bg_scsi_prep_dma_buf(struct lpfc_hb
 		case LPFC_PG_TYPE_NO_DIF:
 			num_bde = lpfc_bg_setup_bpl(phba, scsi_cmnd, bpl,
 					datasegcnt);
-			/* we shoud have 2 or more entries in buffer list */
+			/* we should have 2 or more entries in buffer list */
 			if (num_bde < 2)
 				goto err;
 			break;
@@ -1611,7 +1634,7 @@ lpfc_bg_scsi_prep_dma_buf(struct lpfc_hb
 
 			num_bde = lpfc_bg_setup_bpl_prot(phba, scsi_cmnd, bpl,
 					datasegcnt, protsegcnt);
-			/* we shoud have 3 or more entries in buffer list */
+			/* we should have 3 or more entries in buffer list */
 			if (num_bde < 3)
 				goto err;
 			break;
@@ -1869,7 +1892,6 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hb
 		scsi_for_each_sg(scsi_cmnd, sgel, nseg, num_bde) {
 			physaddr = sg_dma_address(sgel);
 			dma_len = sg_dma_len(sgel);
-			bf_set(lpfc_sli4_sge_len, sgl, sg_dma_len(sgel));
 			sgl->addr_lo = cpu_to_le32(putPaddrLow(physaddr));
 			sgl->addr_hi = cpu_to_le32(putPaddrHigh(physaddr));
 			if ((num_bde + 1) == nseg)
@@ -1878,7 +1900,7 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hb
 				bf_set(lpfc_sli4_sge_last, sgl, 0);
 			bf_set(lpfc_sli4_sge_offset, sgl, dma_offset);
 			sgl->word2 = cpu_to_le32(sgl->word2);
-			sgl->word3 = cpu_to_le32(sgl->word3);
+			sgl->sge_len = cpu_to_le32(dma_len);
 			dma_offset += dma_len;
 			sgl++;
 		}
@@ -2079,8 +2101,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *v
 
 	if (resp_info & RSP_LEN_VALID) {
 		rsplen = be32_to_cpu(fcprsp->rspRspLen);
-		if ((rsplen != 0 && rsplen != 4 && rsplen != 8) ||
-		    (fcprsp->rspInfo3 != RSP_NO_FAILURE)) {
+		if (rsplen != 0 && rsplen != 4 && rsplen != 8) {
 			lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
 				 "2719 Invalid response length: "
 				 "tgt x%x lun x%x cmnd x%x rsplen x%x\n",
@@ -2090,6 +2111,17 @@ lpfc_handle_fcp_err(struct lpfc_vport *v
 			host_status = DID_ERROR;
 			goto out;
 		}
+		if (fcprsp->rspInfo3 != RSP_NO_FAILURE) {
+			lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+				 "2757 Protocol failure detected during "
+				 "processing of FCP I/O op: "
+				 "tgt x%x lun x%x cmnd x%x rspInfo3 x%x\n",
+				 cmnd->device->id,
+				 cmnd->device->lun, cmnd->cmnd[0],
+				 fcprsp->rspInfo3);
+			host_status = DID_ERROR;
+			goto out;
+		}
 	}
 
 	if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) {
@@ -2221,6 +2253,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba
 
 	lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4];
 	lpfc_cmd->status = pIocbOut->iocb.ulpStatus;
+	/* pick up SLI4 exhange busy status from HBA */
+	lpfc_cmd->exch_busy = pIocbOut->iocb_flag & LPFC_EXCHANGE_BUSY;
+
 	if (pnode && NLP_CHK_NODE_ACT(pnode))
 		atomic_dec(&pnode->cmd_pending);
 
@@ -2637,6 +2672,7 @@ lpfc_scsi_api_table_setup(struct lpfc_hb
 	}
 	phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf;
 	phba->lpfc_rampdown_queue_depth = lpfc_rampdown_queue_depth;
+	phba->lpfc_scsi_cmd_iocb_cmpl = lpfc_scsi_cmd_iocb_cmpl;
 	return 0;
 }
 
@@ -2695,6 +2731,13 @@ lpfc_info(struct Scsi_Host *host)
 				 " port %s",
 				 phba->Port);
 		}
+		len = strlen(lpfcinfobuf);
+		if (phba->sli4_hba.link_state.logical_speed) {
+			snprintf(lpfcinfobuf + len,
+				 384-len,
+				 " Logical Link Speed: %d Mbps",
+				 phba->sli4_hba.link_state.logical_speed * 10);
+		}
 	}
 	return lpfcinfobuf;
 }
@@ -2990,6 +3033,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmn
 
 	/* ABTS WQE must go to the same WQ as the WQE to be aborted */
 	abtsiocb->fcp_wqidx = iocb->fcp_wqidx;
+	abtsiocb->iocb_flag |= LPFC_USE_FCPWQIDX;
 
 	if (lpfc_is_link_up(phba))
 		icmd->ulpCommand = CMD_ABORT_XRI_CN;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_scsi.h linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_scsi.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_scsi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_scsi.h	2010-05-16 17:17:36.000000000 -0400
@@ -118,6 +118,7 @@ struct lpfc_scsi_buf {
 
 	uint32_t timeout;
 
+	uint16_t exch_busy;     /* SLI4 hba reported XB on complete WCQE */
 	uint16_t status;	/* From IOCB Word 7- ulpStatus */
 	uint32_t result;	/* From IOCB Word 4. */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_sli4.h linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_sli4.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_sli4.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_sli4.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,10 @@
 #define LPFC_RELEASE_NOTIFICATION_INTERVAL	32
 #define LPFC_GET_QE_REL_INT			32
 #define LPFC_RPI_LOW_WATER_MARK			10
+
+/* Amount of time in seconds for waiting FCF rediscovery to complete */
+#define LPFC_FCF_REDISCOVER_WAIT_TMO		2000 /* msec */
+
 /* Number of SGL entries can be posted in a 4KB nonembedded mbox command */
 #define LPFC_NEMBED_MBOX_SGL_CNT		254
 
@@ -126,26 +130,50 @@ struct lpfc_sli4_link {
 	uint8_t status;
 	uint8_t physical;
 	uint8_t fault;
+	uint16_t logical_speed;
 };
 
-struct lpfc_fcf {
-	uint8_t	 fabric_name[8];
-	uint8_t	 switch_name[8];
+struct lpfc_fcf_rec {
+	uint8_t  fabric_name[8];
+	uint8_t  switch_name[8];
 	uint8_t  mac_addr[6];
 	uint16_t fcf_indx;
+	uint32_t priority;
+	uint16_t vlan_id;
+	uint32_t addr_mode;
+	uint32_t flag;
+#define BOOT_ENABLE	0x01
+#define RECORD_VALID	0x02
+};
+
+struct lpfc_fcf {
 	uint16_t fcfi;
 	uint32_t fcf_flag;
 #define FCF_AVAILABLE	0x01 /* FCF available for discovery */
 #define FCF_REGISTERED	0x02 /* FCF registered with FW */
-#define FCF_DISCOVERED	0x04 /* FCF discovery started  */
-#define FCF_BOOT_ENABLE 0x08 /* Boot bios use this FCF */
-#define FCF_IN_USE	0x10 /* Atleast one discovery completed */
-#define FCF_VALID_VLAN	0x20 /* Use the vlan id specified */
-	uint32_t priority;
+#define FCF_SCAN_DONE	0x04 /* FCF table scan done */
+#define FCF_IN_USE	0x08 /* Atleast one discovery completed */
+#define FCF_INIT_DISC	0x10 /* Initial FCF discovery */
+#define FCF_DEAD_DISC	0x20 /* FCF DEAD fast FCF failover discovery */
+#define FCF_ACVL_DISC	0x40 /* All CVL fast FCF failover discovery */
+#define FCF_DISCOVERY	(FCF_INIT_DISC | FCF_DEAD_DISC | FCF_ACVL_DISC)
+#define FCF_REDISC_PEND	0x80 /* FCF rediscovery pending */
+#define FCF_REDISC_EVT	0x100 /* FCF rediscovery event to worker thread */
+#define FCF_REDISC_FOV	0x200 /* Post FCF rediscovery fast failover */
 	uint32_t addr_mode;
-	uint16_t vlan_id;
+	uint16_t fcf_rr_init_indx;
+	struct lpfc_fcf_rec current_rec;
+	struct lpfc_fcf_rec failover_rec;
+	struct timer_list redisc_wait;
+	unsigned long *fcf_rr_bmask; /* Eligible FCF indexes for RR failover */
 };
 
+/*
+ * Maximum FCF table index, it is for driver internal book keeping, it
+ * just needs to be no less than the supported HBA's FCF table size.
+ */
+#define LPFC_SLI4_FCF_TBL_INDX_MAX	32
+
 #define LPFC_REGION23_SIGNATURE "RG23"
 #define LPFC_REGION23_VERSION	1
 #define LPFC_REGION23_LAST_REC  0xff
@@ -248,7 +276,10 @@ struct lpfc_bmbx {
 #define SLI4_CT_VFI 2
 #define SLI4_CT_FCFI 3
 
-#define LPFC_SLI4_MAX_SEGMENT_SIZE 0x10000
+#define LPFC_SLI4_FL1_MAX_SEGMENT_SIZE	0x10000
+#define LPFC_SLI4_FL1_MAX_BUF_SIZE	0X2000
+#define LPFC_SLI4_MIN_BUF_SIZE		0x400
+#define LPFC_SLI4_MAX_BUF_SIZE		0x20000
 
 /*
  * SLI4 specific data structures
@@ -282,6 +313,42 @@ struct lpfc_fcp_eq_hdl {
 	struct lpfc_hba *phba;
 };
 
+/* Port Capabilities for SLI4 Parameters */
+struct lpfc_pc_sli4_params {
+	uint32_t supported;
+	uint32_t if_type;
+	uint32_t sli_rev;
+	uint32_t sli_family;
+	uint32_t featurelevel_1;
+	uint32_t featurelevel_2;
+	uint32_t proto_types;
+#define LPFC_SLI4_PROTO_FCOE	0x0000001
+#define LPFC_SLI4_PROTO_FC	0x0000002
+#define LPFC_SLI4_PROTO_NIC	0x0000004
+#define LPFC_SLI4_PROTO_ISCSI	0x0000008
+#define LPFC_SLI4_PROTO_RDMA	0x0000010
+	uint32_t sge_supp_len;
+	uint32_t if_page_sz;
+	uint32_t rq_db_window;
+	uint32_t loopbk_scope;
+	uint32_t eq_pages_max;
+	uint32_t eqe_size;
+	uint32_t cq_pages_max;
+	uint32_t cqe_size;
+	uint32_t mq_pages_max;
+	uint32_t mqe_size;
+	uint32_t mq_elem_cnt;
+	uint32_t wq_pages_max;
+	uint32_t wqe_size;
+	uint32_t rq_pages_max;
+	uint32_t rqe_size;
+	uint32_t hdr_pages_max;
+	uint32_t hdr_size;
+	uint32_t hdr_pp_align;
+	uint32_t sgl_pages_max;
+	uint32_t sgl_pp_align;
+};
+
 /* SLI4 HBA data structure entries */
 struct lpfc_sli4_hba {
 	void __iomem *conf_regs_memmap_p; /* Kernel memory mapped address for
@@ -295,7 +362,7 @@ struct lpfc_sli4_hba {
 	void __iomem *UERRHIregaddr; /* Address to UERR_STATUS_HI register */
 	void __iomem *UEMASKLOregaddr; /* Address to UE_MASK_LO register */
 	void __iomem *UEMASKHIregaddr; /* Address to UE_MASK_HI register */
-	void __iomem *SCRATCHPADregaddr; /* Address to scratchpad register */
+	void __iomem *SLIINTFregaddr; /* Address to SLI_INTF register */
 	/* BAR1 FCoE function CSR register memory map */
 	void __iomem *STAregaddr;    /* Address to HST_STATE register */
 	void __iomem *ISRregaddr;    /* Address to HST_ISR register */
@@ -310,6 +377,8 @@ struct lpfc_sli4_hba {
 
 	uint32_t ue_mask_lo;
 	uint32_t ue_mask_hi;
+	struct lpfc_register sli_intf;
+	struct lpfc_pc_sli4_params pc_sli4_params;
 	struct msix_entry *msix_entries;
 	uint32_t cfg_eqn;
 	struct lpfc_fcp_eq_hdl *fcp_eq_hdl; /* FCP per-WQ handle */
@@ -374,11 +443,18 @@ enum lpfc_sge_type {
 	SCSI_BUFF_TYPE
 };
 
+enum lpfc_sgl_state {
+	SGL_FREED,
+	SGL_ALLOCATED,
+	SGL_XRI_ABORTED
+};
+
 struct lpfc_sglq {
 	/* lpfc_sglqs are used in double linked lists */
 	struct list_head list;
 	struct list_head clist;
 	enum lpfc_sge_type buff_type; /* is this a scsi sgl */
+	enum lpfc_sgl_state state;
 	uint16_t iotag;         /* pre-assigned IO tag */
 	uint16_t sli4_xritag;   /* pre-assigned XRI, (OXID) tag. */
 	struct sli4_sge *sgl;	/* pre-assigned SGL */
@@ -406,6 +482,8 @@ void lpfc_sli4_mbox_cmd_free(struct lpfc
 void lpfc_sli4_mbx_sge_set(struct lpfcMboxq *, uint32_t, dma_addr_t, uint32_t);
 void lpfc_sli4_mbx_sge_get(struct lpfcMboxq *, uint32_t,
 			   struct lpfc_mbx_sge *);
+int lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *, struct lpfcMboxq *,
+			       uint16_t);
 
 void lpfc_sli4_hba_reset(struct lpfc_hba *);
 struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t,
@@ -448,6 +526,7 @@ int lpfc_sli4_alloc_rpi(struct lpfc_hba
 void lpfc_sli4_free_rpi(struct lpfc_hba *, int);
 void lpfc_sli4_remove_rpis(struct lpfc_hba *);
 void lpfc_sli4_async_event_proc(struct lpfc_hba *);
+void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *);
 int lpfc_sli4_resume_rpi(struct lpfc_nodelist *);
 void lpfc_sli4_fcp_xri_abort_event_proc(struct lpfc_hba *);
 void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *);
@@ -463,8 +542,13 @@ int lpfc_sli4_init_vpi(struct lpfc_hba *
 uint32_t lpfc_sli4_cq_release(struct lpfc_queue *, bool);
 uint32_t lpfc_sli4_eq_release(struct lpfc_queue *, bool);
 void lpfc_sli4_fcfi_unreg(struct lpfc_hba *, uint16_t);
-int lpfc_sli4_read_fcf_record(struct lpfc_hba *, uint16_t);
-void lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *, LPFC_MBOXQ_t *);
+int lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *, uint16_t);
+int lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *, uint16_t);
+int lpfc_sli4_read_fcf_rec(struct lpfc_hba *, uint16_t);
+void lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *);
+int lpfc_sli4_unregister_fcf(struct lpfc_hba *);
 int lpfc_sli4_post_status_check(struct lpfc_hba *);
 uint8_t lpfc_sli4_mbox_opcode_get(struct lpfc_hba *, struct lpfcMboxq *);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_sli.c linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_sli.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_sli.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_sli.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -494,7 +495,7 @@ __lpfc_clear_active_sglq(struct lpfc_hba
  *
  * Returns sglq ponter = success, NULL = Failure.
  **/
-static struct lpfc_sglq *
+struct lpfc_sglq *
 __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag)
 {
 	uint16_t adj_xri;
@@ -526,6 +527,7 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phb
 		return NULL;
 	adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base;
 	phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq;
+	sglq->state = SGL_ALLOCATED;
 	return sglq;
 }
 
@@ -580,18 +582,18 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_
 	else
 		sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag);
 	if (sglq)  {
-		if (iocbq->iocb_flag & LPFC_DRIVER_ABORTED
-			&& ((iocbq->iocb.ulpStatus == IOSTAT_LOCAL_REJECT)
-			&& (iocbq->iocb.un.ulpWord[4]
-				== IOERR_ABORT_REQUESTED))) {
+		if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) &&
+			(sglq->state != SGL_XRI_ABORTED)) {
 			spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock,
 					iflag);
 			list_add(&sglq->list,
 				&phba->sli4_hba.lpfc_abts_els_sgl_list);
 			spin_unlock_irqrestore(
 				&phba->sli4_hba.abts_sgl_list_lock, iflag);
-		} else
+		} else {
+			sglq->state = SGL_FREED;
 			list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list);
+		}
 	}
 
 
@@ -764,10 +766,6 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd
 	case DSSCMD_IWRITE64_CX:
 	case DSSCMD_IREAD64_CR:
 	case DSSCMD_IREAD64_CX:
-	case DSSCMD_INVALIDATE_DEK:
-	case DSSCMD_SET_KEK:
-	case DSSCMD_GET_KEK_ID:
-	case DSSCMD_GEN_XFER:
 		type = LPFC_SOL_IOCB;
 		break;
 	case CMD_ABORT_XRI_CN:
@@ -1717,6 +1715,7 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *
 	struct lpfc_dmabuf *mp;
 	uint16_t rpi, vpi;
 	int rc;
+	struct lpfc_vport  *vport = pmb->vport;
 
 	mp = (struct lpfc_dmabuf *) (pmb->context1);
 
@@ -1745,6 +1744,18 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *
 			return;
 	}
 
+	/* Unreg VPI, if the REG_VPI succeed after VLink failure */
+	if ((pmb->u.mb.mbxCommand == MBX_REG_VPI) &&
+		!(phba->pport->load_flag & FC_UNLOADING) &&
+		!pmb->u.mb.mbxStatus) {
+		lpfc_unreg_vpi(phba, pmb->u.mb.un.varRegVpi.vpi, pmb);
+		pmb->vport = vport;
+		pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
+		if (rc != MBX_NOT_FINISHED)
+			return;
+	}
+
 	if (bf_get(lpfc_mqe_command, &pmb->u.mqe) == MBX_SLI4_CONFIG)
 		lpfc_sli4_mbox_cmd_free(phba, pmb);
 	else
@@ -2228,9 +2239,15 @@ lpfc_sli_process_sol_iocb(struct lpfc_hb
 			 * All other are passed to the completion callback.
 			 */
 			if (pring->ringno == LPFC_ELS_RING) {
-				if (cmdiocbp->iocb_flag & LPFC_DRIVER_ABORTED) {
+				if ((phba->sli_rev < LPFC_SLI_REV4) &&
+				    (cmdiocbp->iocb_flag &
+							LPFC_DRIVER_ABORTED)) {
+					spin_lock_irqsave(&phba->hbalock,
+							  iflag);
 					cmdiocbp->iocb_flag &=
 						~LPFC_DRIVER_ABORTED;
+					spin_unlock_irqrestore(&phba->hbalock,
+							       iflag);
 					saveq->iocb.ulpStatus =
 						IOSTAT_LOCAL_REJECT;
 					saveq->iocb.un.ulpWord[4] =
@@ -2240,7 +2257,62 @@ lpfc_sli_process_sol_iocb(struct lpfc_hb
 					 * of DMAing payload, so don't free data
 					 * buffer till after a hbeat.
 					 */
+					spin_lock_irqsave(&phba->hbalock,
+							  iflag);
 					saveq->iocb_flag |= LPFC_DELAY_MEM_FREE;
+					spin_unlock_irqrestore(&phba->hbalock,
+							       iflag);
+				}
+				if (phba->sli_rev == LPFC_SLI_REV4) {
+					if (saveq->iocb_flag &
+					    LPFC_EXCHANGE_BUSY) {
+						/* Set cmdiocb flag for the
+						 * exchange busy so sgl (xri)
+						 * will not be released until
+						 * the abort xri is received
+						 * from hba.
+						 */
+						spin_lock_irqsave(
+							&phba->hbalock, iflag);
+						cmdiocbp->iocb_flag |=
+							LPFC_EXCHANGE_BUSY;
+						spin_unlock_irqrestore(
+							&phba->hbalock, iflag);
+					}
+					if (cmdiocbp->iocb_flag &
+					    LPFC_DRIVER_ABORTED) {
+						/*
+						 * Clear LPFC_DRIVER_ABORTED
+						 * bit in case it was driver
+						 * initiated abort.
+						 */
+						spin_lock_irqsave(
+							&phba->hbalock, iflag);
+						cmdiocbp->iocb_flag &=
+							~LPFC_DRIVER_ABORTED;
+						spin_unlock_irqrestore(
+							&phba->hbalock, iflag);
+						cmdiocbp->iocb.ulpStatus =
+							IOSTAT_LOCAL_REJECT;
+						cmdiocbp->iocb.un.ulpWord[4] =
+							IOERR_ABORT_REQUESTED;
+						/*
+						 * For SLI4, irsiocb contains
+						 * NO_XRI in sli_xritag, it
+						 * shall not affect releasing
+						 * sgl (xri) process.
+						 */
+						saveq->iocb.ulpStatus =
+							IOSTAT_LOCAL_REJECT;
+						saveq->iocb.un.ulpWord[4] =
+							IOERR_SLI_ABORTED;
+						spin_lock_irqsave(
+							&phba->hbalock, iflag);
+						saveq->iocb_flag |=
+							LPFC_DELAY_MEM_FREE;
+						spin_unlock_irqrestore(
+							&phba->hbalock, iflag);
+					}
 				}
 			}
 			(cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq);
@@ -2463,14 +2535,16 @@ lpfc_sli_handle_fast_ring_event(struct l
 
 			cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
 							 &rspiocbq);
-			if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
-					spin_unlock_irqrestore(&phba->hbalock,
-							       iflag);
-					(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
-							      &rspiocbq);
-					spin_lock_irqsave(&phba->hbalock,
-							  iflag);
-				}
+			if (unlikely(!cmdiocbq))
+				break;
+			if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED)
+				cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED;
+			if (cmdiocbq->iocb_cmpl) {
+				spin_unlock_irqrestore(&phba->hbalock, iflag);
+				(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
+						      &rspiocbq);
+				spin_lock_irqsave(&phba->hbalock, iflag);
+			}
 			break;
 		case LPFC_UNSOL_IOCB:
 			spin_unlock_irqrestore(&phba->hbalock, iflag);
@@ -3039,6 +3113,12 @@ lpfc_sli_brdready_s3(struct lpfc_hba *ph
 
 	/* Check to see if any errors occurred during init */
 	if ((status & HS_FFERM) || (i >= 20)) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"2751 Adapter failed to restart, "
+				"status reg x%x, FW Data: A8 x%x AC x%x\n",
+				status,
+				readl(phba->MBslimaddr + 0xa8),
+				readl(phba->MBslimaddr + 0xac));
 		phba->link_state = LPFC_HBA_ERROR;
 		retval = 1;
 	}
@@ -3226,6 +3306,9 @@ lpfc_sli_brdkill(struct lpfc_hba *phba)
 	if (retval != MBX_SUCCESS) {
 		if (retval != MBX_BUSY)
 			mempool_free(pmb, phba->mbox_mem_pool);
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+				"2752 KILL_BOARD command failed retval %d\n",
+				retval);
 		spin_lock_irq(&phba->hbalock);
 		phba->link_flag &= ~LS_IGNORE_ERATT;
 		spin_unlock_irq(&phba->hbalock);
@@ -3983,7 +4066,7 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba
 
 lpfc_sli_hba_setup_error:
 	phba->link_state = LPFC_HBA_ERROR;
-	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 			"0445 Firmware initialization failed\n");
 	return rc;
 }
@@ -4336,7 +4419,13 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phb
 	spin_unlock_irq(&phba->hbalock);
 
 	/* Read the port's service parameters. */
-	lpfc_read_sparam(phba, mboxq, vport->vpi);
+	rc = lpfc_read_sparam(phba, mboxq, vport->vpi);
+	if (rc) {
+		phba->link_state = LPFC_HBA_ERROR;
+		rc = -ENOMEM;
+		goto out_free_vpd;
+	}
+
 	mboxq->vport = vport;
 	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
 	mp = (struct lpfc_dmabuf *) mboxq->context1;
@@ -4431,6 +4520,10 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phb
 	/* Post receive buffers to the device */
 	lpfc_sli4_rb_setup(phba);
 
+	/* Reset HBA FCF states after HBA reset */
+	phba->fcf.fcf_flag = 0;
+	phba->fcf.current_rec.flag = 0;
+
 	/* Start the ELS watchdog timer */
 	mod_timer(&vport->els_tmofunc,
 		  jiffies + HZ * (phba->fc_ratov * 2));
@@ -5687,19 +5780,19 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba,
 
 		for (i = 0; i < numBdes; i++) {
 			/* Should already be byte swapped. */
-			sgl->addr_hi =  bpl->addrHigh;
-			sgl->addr_lo =  bpl->addrLow;
-			/* swap the size field back to the cpu so we
-			 * can assign it to the sgl.
-			 */
-			bde.tus.w  = le32_to_cpu(bpl->tus.w);
-			bf_set(lpfc_sli4_sge_len, sgl, bde.tus.f.bdeSize);
+			sgl->addr_hi = bpl->addrHigh;
+			sgl->addr_lo = bpl->addrLow;
+
 			if ((i+1) == numBdes)
 				bf_set(lpfc_sli4_sge_last, sgl, 1);
 			else
 				bf_set(lpfc_sli4_sge_last, sgl, 0);
 			sgl->word2 = cpu_to_le32(sgl->word2);
-			sgl->word3 = cpu_to_le32(sgl->word3);
+			/* swap the size field back to the cpu so we
+			 * can assign it to the sgl.
+			 */
+			bde.tus.w = le32_to_cpu(bpl->tus.w);
+			sgl->sge_len = cpu_to_le32(bde.tus.f.bdeSize);
 			bpl++;
 			sgl++;
 		}
@@ -5712,11 +5805,10 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba,
 				cpu_to_le32(icmd->un.genreq64.bdl.addrHigh);
 			sgl->addr_lo =
 				cpu_to_le32(icmd->un.genreq64.bdl.addrLow);
-			bf_set(lpfc_sli4_sge_len, sgl,
-				icmd->un.genreq64.bdl.bdeSize);
 			bf_set(lpfc_sli4_sge_last, sgl, 1);
 			sgl->word2 = cpu_to_le32(sgl->word2);
-			sgl->word3 = cpu_to_le32(sgl->word3);
+			sgl->sge_len =
+				cpu_to_le32(icmd->un.genreq64.bdl.bdeSize);
 	}
 	return sglq->sli4_xritag;
 }
@@ -5987,12 +6079,10 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
 		else
 			bf_set(abort_cmd_ia, &wqe->abort_cmd, 0);
 		bf_set(abort_cmd_criteria, &wqe->abort_cmd, T_XRI_TAG);
-		abort_tag = iocbq->iocb.un.acxri.abortIoTag;
 		wqe->words[5] = 0;
 		bf_set(lpfc_wqe_gen_ct, &wqe->generic,
 			((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l));
 		abort_tag = iocbq->iocb.un.acxri.abortIoTag;
-		wqe->generic.abort_tag = abort_tag;
 		/*
 		 * The abort handler will send us CMD_ABORT_XRI_CN or
 		 * CMD_CLOSE_XRI_CN and the fw only accepts CMD_ABORT_XRI_CX
@@ -6121,15 +6211,15 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba
 	if (lpfc_sli4_iocb2wqe(phba, piocb, &wqe))
 		return IOCB_ERROR;
 
-	if (piocb->iocb_flag &  LPFC_IO_FCP) {
+	if ((piocb->iocb_flag & LPFC_IO_FCP) ||
+		(piocb->iocb_flag & LPFC_USE_FCPWQIDX)) {
 		/*
 		 * For FCP command IOCB, get a new WQ index to distribute
 		 * WQE across the WQsr. On the other hand, for abort IOCB,
 		 * it carries the same WQ index to the original command
 		 * IOCB.
 		 */
-		if ((piocb->iocb.ulpCommand != CMD_ABORT_XRI_CN) &&
-		    (piocb->iocb.ulpCommand != CMD_CLOSE_XRI_CN))
+		if (piocb->iocb_flag & LPFC_IO_FCP)
 			piocb->fcp_wqidx = lpfc_sli4_scmd_to_wqidx_distr(phba);
 		if (lpfc_sli4_wq_put(phba->sli4_hba.fcp_wq[piocb->fcp_wqidx],
 				     &wqe))
@@ -7004,7 +7094,14 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba
 		    abort_iocb->iocb.ulpContext != abort_context ||
 		    (abort_iocb->iocb_flag & LPFC_DRIVER_ABORTED) == 0)
 			spin_unlock_irq(&phba->hbalock);
-		else {
+		else if (phba->sli_rev < LPFC_SLI_REV4) {
+			/*
+			 * leave the SLI4 aborted command on the txcmplq
+			 * list and the command complete WCQE's XB bit
+			 * will tell whether the SGL (XRI) can be released
+			 * immediately or to the aborted SGL list for the
+			 * following abort XRI from the HBA.
+			 */
 			list_del_init(&abort_iocb->list);
 			pring->txcmplq_cnt--;
 			spin_unlock_irq(&phba->hbalock);
@@ -7013,11 +7110,13 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba
 			 * payload, so don't free data buffer till after
 			 * a hbeat.
 			 */
+			spin_lock_irq(&phba->hbalock);
 			abort_iocb->iocb_flag |= LPFC_DELAY_MEM_FREE;
-
 			abort_iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED;
+			spin_unlock_irq(&phba->hbalock);
+
 			abort_iocb->iocb.ulpStatus = IOSTAT_LOCAL_REJECT;
-			abort_iocb->iocb.un.ulpWord[4] = IOERR_SLI_ABORTED;
+			abort_iocb->iocb.un.ulpWord[4] = IOERR_ABORT_REQUESTED;
 			(abort_iocb->iocb_cmpl)(phba, abort_iocb, abort_iocb);
 		}
 	}
@@ -7106,7 +7205,7 @@ lpfc_sli_issue_abort_iotag(struct lpfc_h
 		return 0;
 
 	/* This signals the response to set the correct status
-	 * before calling the completion handler.
+	 * before calling the completion handler
 	 */
 	cmdiocb->iocb_flag |= LPFC_DRIVER_ABORTED;
 
@@ -7124,6 +7223,8 @@ lpfc_sli_issue_abort_iotag(struct lpfc_h
 
 	/* ABTS WQE must go to the same WQ as the WQE to be aborted */
 	abtsiocbp->fcp_wqidx = cmdiocb->fcp_wqidx;
+	if (cmdiocb->iocb_flag & LPFC_IO_FCP)
+		abtsiocbp->iocb_flag |= LPFC_USE_FCPWQIDX;
 
 	if (phba->link_state >= LPFC_LINK_UP)
 		iabt->ulpCommand = CMD_ABORT_XRI_CN;
@@ -7330,6 +7431,8 @@ lpfc_sli_abort_iocb(struct lpfc_vport *v
 
 		/* ABTS WQE must go to the same WQ as the WQE to be aborted */
 		abtsiocb->fcp_wqidx = iocbq->fcp_wqidx;
+		if (iocbq->iocb_flag & LPFC_IO_FCP)
+			abtsiocb->iocb_flag |= LPFC_USE_FCPWQIDX;
 
 		if (lpfc_is_link_up(phba))
 			abtsiocb->iocb.ulpCommand = CMD_ABORT_XRI_CN;
@@ -7374,6 +7477,7 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba
 {
 	wait_queue_head_t *pdone_q;
 	unsigned long iflags;
+	struct lpfc_scsi_buf *lpfc_cmd;
 
 	spin_lock_irqsave(&phba->hbalock, iflags);
 	cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
@@ -7381,6 +7485,14 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba
 		memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
 		       &rspiocbq->iocb, sizeof(IOCB_t));
 
+	/* Set the exchange busy flag for task management commands */
+	if ((cmdiocbq->iocb_flag & LPFC_IO_FCP) &&
+		!(cmdiocbq->iocb_flag & LPFC_IO_LIBDFC)) {
+		lpfc_cmd = container_of(cmdiocbq, struct lpfc_scsi_buf,
+			cur_iocbq);
+		lpfc_cmd->exch_busy = rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY;
+	}
+
 	pdone_q = cmdiocbq->context_un.wait_queue;
 	if (pdone_q)
 		wake_up(pdone_q);
@@ -8359,11 +8471,24 @@ void lpfc_sli4_els_xri_abort_event_proc(
 	}
 }
 
+/**
+ * lpfc_sli4_iocb_param_transfer - Transfer pIocbOut and cmpl status to pIocbIn
+ * @phba: pointer to lpfc hba data structure
+ * @pIocbIn: pointer to the rspiocbq
+ * @pIocbOut: pointer to the cmdiocbq
+ * @wcqe: pointer to the complete wcqe
+ *
+ * This routine transfers the fields of a command iocbq to a response iocbq
+ * by copying all the IOCB fields from command iocbq and transferring the
+ * completion status information from the complete wcqe.
+ **/
 static void
-lpfc_sli4_iocb_param_transfer(struct lpfc_iocbq *pIocbIn,
+lpfc_sli4_iocb_param_transfer(struct lpfc_hba *phba,
+			      struct lpfc_iocbq *pIocbIn,
 			      struct lpfc_iocbq *pIocbOut,
 			      struct lpfc_wcqe_complete *wcqe)
 {
+	unsigned long iflags;
 	size_t offset = offsetof(struct lpfc_iocbq, iocb);
 
 	memcpy((char *)pIocbIn + offset, (char *)pIocbOut + offset,
@@ -8377,8 +8502,17 @@ lpfc_sli4_iocb_param_transfer(struct lpf
 					wcqe->total_data_placed;
 		else
 			pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter;
-	else
+	else {
 		pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter;
+		pIocbIn->iocb.un.genreq64.bdl.bdeSize = wcqe->total_data_placed;
+	}
+
+	/* Pick up HBA exchange busy condition */
+	if (bf_get(lpfc_wcqe_c_xb, wcqe)) {
+		spin_lock_irqsave(&phba->hbalock, iflags);
+		pIocbIn->iocb_flag |= LPFC_EXCHANGE_BUSY;
+		spin_unlock_irqrestore(&phba->hbalock, iflags);
+	}
 }
 
 /**
@@ -8419,7 +8553,7 @@ lpfc_sli4_els_wcqe_to_rspiocbq(struct lp
 	}
 
 	/* Fake the irspiocbq and copy necessary response information */
-	lpfc_sli4_iocb_param_transfer(irspiocbq, cmdiocbq, wcqe);
+	lpfc_sli4_iocb_param_transfer(phba, irspiocbq, cmdiocbq, wcqe);
 
 	return irspiocbq;
 }
@@ -8849,8 +8983,7 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba
 	int ecount = 0;
 	uint16_t cqid;
 
-	if (bf_get(lpfc_eqe_major_code, eqe) != 0 ||
-	    bf_get(lpfc_eqe_minor_code, eqe) != 0) {
+	if (bf_get(lpfc_eqe_major_code, eqe) != 0) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 				"0359 Not a valid slow-path completion "
 				"event: majorcode=x%x, minorcode=x%x\n",
@@ -8976,7 +9109,13 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc
 	}
 
 	/* Fake the irspiocb and copy necessary response information */
-	lpfc_sli4_iocb_param_transfer(&irspiocbq, cmdiocbq, wcqe);
+	lpfc_sli4_iocb_param_transfer(phba, &irspiocbq, cmdiocbq, wcqe);
+
+	if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED) {
+		spin_lock_irqsave(&phba->hbalock, iflags);
+		cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED;
+		spin_unlock_irqrestore(&phba->hbalock, iflags);
+	}
 
 	/* Pass the cmd_iocb and the rsp state to the upper layer */
 	(cmdiocbq->iocb_cmpl)(phba, cmdiocbq, &irspiocbq);
@@ -9082,8 +9221,7 @@ lpfc_sli4_fp_handle_eqe(struct lpfc_hba
 	uint16_t cqid;
 	int ecount = 0;
 
-	if (unlikely(bf_get(lpfc_eqe_major_code, eqe) != 0) ||
-	    unlikely(bf_get(lpfc_eqe_minor_code, eqe) != 0)) {
+	if (unlikely(bf_get(lpfc_eqe_major_code, eqe) != 0)) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 				"0366 Not a valid fast-path completion "
 				"event: majorcode=x%x, minorcode=x%x\n",
@@ -11859,24 +11997,22 @@ lpfc_sli4_build_dflt_fcf_record(struct l
 }
 
 /**
- * lpfc_sli4_read_fcf_record - Read the driver's default FCF Record.
+ * lpfc_sli4_fcf_scan_read_fcf_rec - Read hba fcf record for fcf scan.
  * @phba: pointer to lpfc hba data structure.
  * @fcf_index: FCF table entry offset.
  *
- * This routine is invoked to read up to @fcf_num of FCF record from the
- * device starting with the given @fcf_index.
+ * This routine is invoked to scan the entire FCF table by reading FCF
+ * record and processing it one at a time starting from the @fcf_index
+ * for initial FCF discovery or fast FCF failover rediscovery.
+ *
+ * Return 0 if the mailbox command is submitted sucessfully, none 0
+ * otherwise.
  **/
 int
-lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index)
+lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
 {
 	int rc = 0, error;
 	LPFC_MBOXQ_t *mboxq;
-	void *virt_addr;
-	dma_addr_t phys_addr;
-	uint8_t *bytep;
-	struct lpfc_mbx_sge sge;
-	uint32_t alloc_len, req_len;
-	struct lpfc_mbx_read_fcf_tbl *read_fcf;
 
 	phba->fcoe_eventtag_at_fcf_scan = phba->fcoe_eventtag;
 	mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
@@ -11885,51 +12021,31 @@ lpfc_sli4_read_fcf_record(struct lpfc_hb
 				"2000 Failed to allocate mbox for "
 				"READ_FCF cmd\n");
 		error = -ENOMEM;
-		goto fail_fcfscan;
+		goto fail_fcf_scan;
 	}
-
-	req_len = sizeof(struct fcf_record) +
-		  sizeof(union lpfc_sli4_cfg_shdr) + 2 * sizeof(uint32_t);
-
-	/* Set up READ_FCF SLI4_CONFIG mailbox-ioctl command */
-	alloc_len = lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_FCOE,
-			 LPFC_MBOX_OPCODE_FCOE_READ_FCF_TABLE, req_len,
-			 LPFC_SLI4_MBX_NEMBED);
-
-	if (alloc_len < req_len) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-				"0291 Allocated DMA memory size (x%x) is "
-				"less than the requested DMA memory "
-				"size (x%x)\n", alloc_len, req_len);
-		error = -ENOMEM;
-		goto fail_fcfscan;
+	/* Construct the read FCF record mailbox command */
+	rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index);
+	if (rc) {
+		error = -EINVAL;
+		goto fail_fcf_scan;
 	}
-
-	/* Get the first SGE entry from the non-embedded DMA memory. This
-	 * routine only uses a single SGE.
-	 */
-	lpfc_sli4_mbx_sge_get(mboxq, 0, &sge);
-	phys_addr = getPaddr(sge.pa_hi, sge.pa_lo);
-	virt_addr = mboxq->sge_array->addr[0];
-	read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr;
-
-	/* Set up command fields */
-	bf_set(lpfc_mbx_read_fcf_tbl_indx, &read_fcf->u.request, fcf_index);
-	/* Perform necessary endian conversion */
-	bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr);
-	lpfc_sli_pcimem_bcopy(bytep, bytep, sizeof(uint32_t));
+	/* Issue the mailbox command asynchronously */
 	mboxq->vport = phba->pport;
-	mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_record;
+	mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_scan_read_fcf_rec;
 	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
-	if (rc == MBX_NOT_FINISHED) {
+	if (rc == MBX_NOT_FINISHED)
 		error = -EIO;
-	} else {
+	else {
 		spin_lock_irq(&phba->hbalock);
 		phba->hba_flag |= FCF_DISC_INPROGRESS;
 		spin_unlock_irq(&phba->hbalock);
+		/* Reset FCF round robin index bmask for new scan */
+		if (fcf_index == LPFC_FCOE_FCF_GET_FIRST)
+			memset(phba->fcf.fcf_rr_bmask, 0,
+			       sizeof(*phba->fcf.fcf_rr_bmask));
 		error = 0;
 	}
-fail_fcfscan:
+fail_fcf_scan:
 	if (error) {
 		if (mboxq)
 			lpfc_sli4_mbox_cmd_free(phba, mboxq);
@@ -11942,6 +12058,312 @@ fail_fcfscan:
 }
 
 /**
+ * lpfc_sli4_fcf_rr_read_fcf_rec - Read hba fcf record for round robin fcf.
+ * @phba: pointer to lpfc hba data structure.
+ * @fcf_index: FCF table entry offset.
+ *
+ * This routine is invoked to read an FCF record indicated by @fcf_index
+ * and to use it for FLOGI round robin FCF failover.
+ *
+ * Return 0 if the mailbox command is submitted sucessfully, none 0
+ * otherwise.
+ **/
+int
+lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
+{
+	int rc = 0, error;
+	LPFC_MBOXQ_t *mboxq;
+
+	mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!mboxq) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_INIT,
+				"2763 Failed to allocate mbox for "
+				"READ_FCF cmd\n");
+		error = -ENOMEM;
+		goto fail_fcf_read;
+	}
+	/* Construct the read FCF record mailbox command */
+	rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index);
+	if (rc) {
+		error = -EINVAL;
+		goto fail_fcf_read;
+	}
+	/* Issue the mailbox command asynchronously */
+	mboxq->vport = phba->pport;
+	mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_rr_read_fcf_rec;
+	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
+	if (rc == MBX_NOT_FINISHED)
+		error = -EIO;
+	else
+		error = 0;
+
+fail_fcf_read:
+	if (error && mboxq)
+		lpfc_sli4_mbox_cmd_free(phba, mboxq);
+	return error;
+}
+
+/**
+ * lpfc_sli4_read_fcf_rec - Read hba fcf record for update eligible fcf bmask.
+ * @phba: pointer to lpfc hba data structure.
+ * @fcf_index: FCF table entry offset.
+ *
+ * This routine is invoked to read an FCF record indicated by @fcf_index to
+ * determine whether it's eligible for FLOGI round robin failover list.
+ *
+ * Return 0 if the mailbox command is submitted sucessfully, none 0
+ * otherwise.
+ **/
+int
+lpfc_sli4_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
+{
+	int rc = 0, error;
+	LPFC_MBOXQ_t *mboxq;
+
+	mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!mboxq) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_INIT,
+				"2758 Failed to allocate mbox for "
+				"READ_FCF cmd\n");
+				error = -ENOMEM;
+				goto fail_fcf_read;
+	}
+	/* Construct the read FCF record mailbox command */
+	rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index);
+	if (rc) {
+		error = -EINVAL;
+		goto fail_fcf_read;
+	}
+	/* Issue the mailbox command asynchronously */
+	mboxq->vport = phba->pport;
+	mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_rec;
+	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
+	if (rc == MBX_NOT_FINISHED)
+		error = -EIO;
+	else
+		error = 0;
+
+fail_fcf_read:
+	if (error && mboxq)
+		lpfc_sli4_mbox_cmd_free(phba, mboxq);
+	return error;
+}
+
+/**
+ * lpfc_sli4_fcf_rr_next_index_get - Get next eligible fcf record index
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is to get the next eligible FCF record index in a round
+ * robin fashion. If the next eligible FCF record index equals to the
+ * initial round robin FCF record index, LPFC_FCOE_FCF_NEXT_NONE (0xFFFF)
+ * shall be returned, otherwise, the next eligible FCF record's index
+ * shall be returned.
+ **/
+uint16_t
+lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *phba)
+{
+	uint16_t next_fcf_index;
+
+	/* Search from the currently registered FCF index */
+	next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask,
+				       LPFC_SLI4_FCF_TBL_INDX_MAX,
+				       phba->fcf.current_rec.fcf_indx);
+	/* Wrap around condition on phba->fcf.fcf_rr_bmask */
+	if (next_fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX)
+		next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask,
+					       LPFC_SLI4_FCF_TBL_INDX_MAX, 0);
+	/* Round robin failover stop condition */
+	if (next_fcf_index == phba->fcf.fcf_rr_init_indx)
+		return LPFC_FCOE_FCF_NEXT_NONE;
+
+	return next_fcf_index;
+}
+
+/**
+ * lpfc_sli4_fcf_rr_index_set - Set bmask with eligible fcf record index
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine sets the FCF record index in to the eligible bmask for
+ * round robin failover search. It checks to make sure that the index
+ * does not go beyond the range of the driver allocated bmask dimension
+ * before setting the bit.
+ *
+ * Returns 0 if the index bit successfully set, otherwise, it returns
+ * -EINVAL.
+ **/
+int
+lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *phba, uint16_t fcf_index)
+{
+	if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
+				"2610 HBA FCF index reached driver's "
+				"book keeping dimension: fcf_index:%d, "
+				"driver_bmask_max:%d\n",
+				fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX);
+		return -EINVAL;
+	}
+	/* Set the eligible FCF record index bmask */
+	set_bit(fcf_index, phba->fcf.fcf_rr_bmask);
+
+	return 0;
+}
+
+/**
+ * lpfc_sli4_fcf_rr_index_set - Clear bmask from eligible fcf record index
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine clears the FCF record index from the eligible bmask for
+ * round robin failover search. It checks to make sure that the index
+ * does not go beyond the range of the driver allocated bmask dimension
+ * before clearing the bit.
+ **/
+void
+lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *phba, uint16_t fcf_index)
+{
+	if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
+				"2762 HBA FCF index goes beyond driver's "
+				"book keeping dimension: fcf_index:%d, "
+				"driver_bmask_max:%d\n",
+				fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX);
+		return;
+	}
+	/* Clear the eligible FCF record index bmask */
+	clear_bit(fcf_index, phba->fcf.fcf_rr_bmask);
+}
+
+/**
+ * lpfc_mbx_cmpl_redisc_fcf_table - completion routine for rediscover FCF table
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is the completion routine for the rediscover FCF table mailbox
+ * command. If the mailbox command returned failure, it will try to stop the
+ * FCF rediscover wait timer.
+ **/
+void
+lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
+{
+	struct lpfc_mbx_redisc_fcf_tbl *redisc_fcf;
+	uint32_t shdr_status, shdr_add_status;
+
+	redisc_fcf = &mbox->u.mqe.un.redisc_fcf_tbl;
+
+	shdr_status = bf_get(lpfc_mbox_hdr_status,
+			     &redisc_fcf->header.cfg_shdr.response);
+	shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
+			     &redisc_fcf->header.cfg_shdr.response);
+	if (shdr_status || shdr_add_status) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
+				"2746 Requesting for FCF rediscovery failed "
+				"status x%x add_status x%x\n",
+				shdr_status, shdr_add_status);
+		if (phba->fcf.fcf_flag & FCF_ACVL_DISC) {
+			spin_lock_irq(&phba->hbalock);
+			phba->fcf.fcf_flag &= ~FCF_ACVL_DISC;
+			spin_unlock_irq(&phba->hbalock);
+			/*
+			 * CVL event triggered FCF rediscover request failed,
+			 * last resort to re-try current registered FCF entry.
+			 */
+			lpfc_retry_pport_discovery(phba);
+		} else {
+			spin_lock_irq(&phba->hbalock);
+			phba->fcf.fcf_flag &= ~FCF_DEAD_DISC;
+			spin_unlock_irq(&phba->hbalock);
+			/*
+			 * DEAD FCF event triggered FCF rediscover request
+			 * failed, last resort to fail over as a link down
+			 * to FCF registration.
+			 */
+			lpfc_sli4_fcf_dead_failthrough(phba);
+		}
+	} else {
+		lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+				"2775 Start FCF rediscovery quiescent period "
+				"wait timer before scaning FCF table\n");
+		/*
+		 * Start FCF rediscovery wait timer for pending FCF
+		 * before rescan FCF record table.
+		 */
+		lpfc_fcf_redisc_wait_start_timer(phba);
+	}
+
+	mempool_free(mbox, phba->mbox_mem_pool);
+}
+
+/**
+ * lpfc_sli4_redisc_all_fcf - Request to rediscover entire FCF table by port.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked to request for rediscovery of the entire FCF table
+ * by the port.
+ **/
+int
+lpfc_sli4_redisc_fcf_table(struct lpfc_hba *phba)
+{
+	LPFC_MBOXQ_t *mbox;
+	struct lpfc_mbx_redisc_fcf_tbl *redisc_fcf;
+	int rc, length;
+
+	/* Cancel retry delay timers to all vports before FCF rediscover */
+	lpfc_cancel_all_vport_retry_delay_timer(phba);
+
+	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!mbox) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+				"2745 Failed to allocate mbox for "
+				"requesting FCF rediscover.\n");
+		return -ENOMEM;
+	}
+
+	length = (sizeof(struct lpfc_mbx_redisc_fcf_tbl) -
+		  sizeof(struct lpfc_sli4_cfg_mhdr));
+	lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE,
+			 LPFC_MBOX_OPCODE_FCOE_REDISCOVER_FCF,
+			 length, LPFC_SLI4_MBX_EMBED);
+
+	redisc_fcf = &mbox->u.mqe.un.redisc_fcf_tbl;
+	/* Set count to 0 for invalidating the entire FCF database */
+	bf_set(lpfc_mbx_redisc_fcf_count, redisc_fcf, 0);
+
+	/* Issue the mailbox command asynchronously */
+	mbox->vport = phba->pport;
+	mbox->mbox_cmpl = lpfc_mbx_cmpl_redisc_fcf_table;
+	rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
+
+	if (rc == MBX_NOT_FINISHED) {
+		mempool_free(mbox, phba->mbox_mem_pool);
+		return -EIO;
+	}
+	return 0;
+}
+
+/**
+ * lpfc_sli4_fcf_dead_failthrough - Failthrough routine to fcf dead event
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This function is the failover routine as a last resort to the FCF DEAD
+ * event when driver failed to perform fast FCF failover.
+ **/
+void
+lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *phba)
+{
+	uint32_t link_state;
+
+	/*
+	 * Last resort as FCF DEAD event failover will treat this as
+	 * a link down, but save the link state because we don't want
+	 * it to be changed to Link Down unless it is already down.
+	 */
+	link_state = phba->link_state;
+	lpfc_linkdown(phba);
+	phba->link_state = link_state;
+
+	/* Unregister FCF if no devices connected to it */
+	lpfc_unregister_unused_fcf(phba);
+}
+
+/**
  * lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled.
  * @phba: pointer to lpfc hba data structure.
  *
@@ -12069,3 +12491,48 @@ out:
 	kfree(rgn23_data);
 	return;
 }
+
+/**
+ * lpfc_cleanup_pending_mbox - Free up vport discovery mailbox commands.
+ * @vport: pointer to vport data structure.
+ *
+ * This function iterate through the mailboxq and clean up all REG_LOGIN
+ * and REG_VPI mailbox commands associated with the vport. This function
+ * is called when driver want to restart discovery of the vport due to
+ * a Clear Virtual Link event.
+ **/
+void
+lpfc_cleanup_pending_mbox(struct lpfc_vport *vport)
+{
+	struct lpfc_hba *phba = vport->phba;
+	LPFC_MBOXQ_t *mb, *nextmb;
+	struct lpfc_dmabuf *mp;
+
+	spin_lock_irq(&phba->hbalock);
+	list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
+		if (mb->vport != vport)
+			continue;
+
+		if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) &&
+			(mb->u.mb.mbxCommand != MBX_REG_VPI))
+			continue;
+
+		if (mb->u.mb.mbxCommand == MBX_REG_LOGIN64) {
+			mp = (struct lpfc_dmabuf *) (mb->context1);
+			if (mp) {
+				__lpfc_mbuf_free(phba, mp->virt, mp->phys);
+				kfree(mp);
+			}
+		}
+		list_del(&mb->list);
+		mempool_free(mb, phba->mbox_mem_pool);
+	}
+	mb = phba->sli.mbox_active;
+	if (mb && (mb->vport == vport)) {
+		if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) ||
+			(mb->u.mb.mbxCommand == MBX_REG_VPI))
+			mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+	}
+	spin_unlock_irq(&phba->hbalock);
+}
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_sli.h linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_sli.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_sli.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_sli.h	2010-05-16 17:17:36.000000000 -0400
@@ -53,17 +53,20 @@ struct lpfc_iocbq {
 
 	IOCB_t iocb;		/* IOCB cmd */
 	uint8_t retry;		/* retry counter for IOCB cmd - if needed */
-	uint8_t iocb_flag;
+	uint16_t iocb_flag;
 #define LPFC_IO_LIBDFC		1	/* libdfc iocb */
 #define LPFC_IO_WAKE		2	/* High Priority Queue signal flag */
 #define LPFC_IO_FCP		4	/* FCP command -- iocbq in scsi_buf */
 #define LPFC_DRIVER_ABORTED	8	/* driver aborted this request */
 #define LPFC_IO_FABRIC		0x10	/* Iocb send using fabric scheduler */
 #define LPFC_DELAY_MEM_FREE	0x20    /* Defer free'ing of FC data */
-#define LPFC_FIP_ELS_ID_MASK	0xc0	/* ELS_ID range 0-3 */
-#define LPFC_FIP_ELS_ID_SHIFT	6
+#define LPFC_EXCHANGE_BUSY	0x40    /* SLI4 hba reported XB in response */
+#define LPFC_USE_FCPWQIDX	0x80    /* Submit to specified FCPWQ index */
+#define DSS_SECURITY_OP		0x100	/* security IO */
+
+#define LPFC_FIP_ELS_ID_MASK	0xc000	/* ELS_ID range 0-3, non-shifted mask */
+#define LPFC_FIP_ELS_ID_SHIFT	14
 
-	uint8_t abort_count;
 	uint8_t rsvd2;
 	uint32_t drvrTimeout;	/* driver timeout in seconds */
 	uint32_t fcp_wqidx;	/* index to FCP work queue */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_version.h linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_version.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_version.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_version.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2009 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2010 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.3.7"
+#define LPFC_DRIVER_VERSION "8.3.10"
 #define LPFC_DRIVER_NAME		"lpfc"
 #define LPFC_SP_DRIVER_HANDLER_NAME	"lpfc:sp"
 #define LPFC_FP_DRIVER_HANDLER_NAME	"lpfc:fp"
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_vport.c linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_vport.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_vport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/lpfc/lpfc_vport.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/interrupt.h>
 #include <linux/kthread.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 
 #include <scsi/scsi.h>
@@ -123,7 +124,12 @@ lpfc_vport_sparm(struct lpfc_hba *phba,
 	}
 	mb = &pmb->u.mb;
 
-	lpfc_read_sparam(phba, pmb, vport->vpi);
+	rc = lpfc_read_sparam(phba, pmb, vport->vpi);
+	if (rc) {
+		mempool_free(pmb, phba->mbox_mem_pool);
+		return -ENOMEM;
+	}
+
 	/*
 	 * Grab buffer pointer and clear context1 so we can use
 	 * lpfc_sli_issue_box_wait
@@ -389,7 +395,7 @@ lpfc_vport_create(struct fc_vport *fc_vp
 	 * by the port.
 	 */
 	if ((phba->sli_rev == LPFC_SLI_REV4) &&
-	    (pport->vpi_state & LPFC_VPI_REGISTERED)) {
+		(pport->fc_flag & FC_VFI_REGISTERED)) {
 		rc = lpfc_sli4_init_vpi(phba, vpi);
 		if (rc) {
 			lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
@@ -505,6 +511,7 @@ enable_vport(struct fc_vport *fc_vport)
 	struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
 	struct lpfc_hba   *phba = vport->phba;
 	struct lpfc_nodelist *ndlp = NULL;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 
 	if ((phba->link_state < LPFC_LINK_UP) ||
 	    (phba->fc_topology == TOPOLOGY_LOOP)) {
@@ -512,10 +519,10 @@ enable_vport(struct fc_vport *fc_vport)
 		return VPORT_OK;
 	}
 
-	spin_lock_irq(&phba->hbalock);
+	spin_lock_irq(shost->host_lock);
 	vport->load_flag |= FC_LOADING;
 	vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
-	spin_unlock_irq(&phba->hbalock);
+	spin_unlock_irq(shost->host_lock);
 
 	/* Use the Physical nodes Fabric NDLP to determine if the link is
 	 * up and ready to FDISC.
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mac_esp.c linux-libre-2.6.34-gnu1/drivers/scsi/mac_esp.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/mac_esp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mac_esp.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,10 +19,10 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/nubus.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 #include <asm/dma.h>
-
 #include <asm/macints.h>
 #include <asm/macintosh.h>
 
@@ -53,7 +53,6 @@ struct mac_esp_priv {
 	void __iomem *pdma_io;
 	int error;
 };
-static struct platform_device *internal_pdev, *external_pdev;
 static struct esp *esp_chips[2];
 
 #define MAC_ESP_GET_PRIV(esp) ((struct mac_esp_priv *) \
@@ -279,24 +278,27 @@ static void mac_esp_send_pdma_cmd(struct
  * Programmed IO routines follow.
  */
 
-static inline int mac_esp_wait_for_fifo(struct esp *esp)
+static inline unsigned int mac_esp_wait_for_fifo(struct esp *esp)
 {
 	int i = 500000;
 
 	do {
-		if (esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES)
-			return 0;
+		unsigned int fbytes = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES;
+
+		if (fbytes)
+			return fbytes;
 
 		udelay(2);
 	} while (--i);
 
 	printk(KERN_ERR PFX "FIFO is empty (sreg %02x)\n",
 	       esp_read8(ESP_STATUS));
-	return 1;
+	return 0;
 }
 
 static inline int mac_esp_wait_for_intr(struct esp *esp)
 {
+	struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp);
 	int i = 500000;
 
 	do {
@@ -308,6 +310,7 @@ static inline int mac_esp_wait_for_intr(
 	} while (--i);
 
 	printk(KERN_ERR PFX "IRQ timeout (sreg %02x)\n", esp->sreg);
+	mep->error = 1;
 	return 1;
 }
 
@@ -347,11 +350,10 @@ static inline int mac_esp_wait_for_intr(
 static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,
 				 u32 dma_count, int write, u8 cmd)
 {
-	unsigned long flags;
 	struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp);
 	u8 *fifo = esp->regs + ESP_FDATA * 16;
 
-	local_irq_save(flags);
+	disable_irq(esp->host->irq);
 
 	cmd &= ~ESP_CMD_DMA;
 	mep->error = 0;
@@ -359,11 +361,35 @@ static void mac_esp_send_pio_cmd(struct
 	if (write) {
 		scsi_esp_cmd(esp, cmd);
 
-		if (!mac_esp_wait_for_intr(esp)) {
-			if (mac_esp_wait_for_fifo(esp))
-				esp_count = 0;
-		} else {
-			esp_count = 0;
+		while (1) {
+			unsigned int n;
+
+			n = mac_esp_wait_for_fifo(esp);
+			if (!n)
+				break;
+
+			if (n > esp_count)
+				n = esp_count;
+			esp_count -= n;
+
+			MAC_ESP_PIO_LOOP("%2@,%0@+", n);
+
+			if (!esp_count)
+				break;
+
+			if (mac_esp_wait_for_intr(esp))
+				break;
+
+			if (((esp->sreg & ESP_STAT_PMASK) != ESP_DIP) &&
+			    ((esp->sreg & ESP_STAT_PMASK) != ESP_MIP))
+				break;
+
+			esp->ireg = esp_read8(ESP_INTRPT);
+			if ((esp->ireg & (ESP_INTR_DC | ESP_INTR_BSERV)) !=
+			    ESP_INTR_BSERV)
+				break;
+
+			scsi_esp_cmd(esp, ESP_CMD_TI);
 		}
 	} else {
 		scsi_esp_cmd(esp, ESP_CMD_FLUSH);
@@ -374,47 +400,24 @@ static void mac_esp_send_pio_cmd(struct
 			MAC_ESP_PIO_LOOP("%0@+,%2@", esp_count);
 
 		scsi_esp_cmd(esp, cmd);
-	}
-
-	while (esp_count) {
-		unsigned int n;
-
-		if (mac_esp_wait_for_intr(esp)) {
-			mep->error = 1;
-			break;
-		}
-
-		if (esp->sreg & ESP_STAT_SPAM) {
-			printk(KERN_ERR PFX "gross error\n");
-			mep->error = 1;
-			break;
-		}
 
-		n = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES;
-
-		if (write) {
-			if (n > esp_count)
-				n = esp_count;
-			esp_count -= n;
-
-			MAC_ESP_PIO_LOOP("%2@,%0@+", n);
+		while (esp_count) {
+			unsigned int n;
 
-			if ((esp->sreg & ESP_STAT_PMASK) == ESP_STATP)
+			if (mac_esp_wait_for_intr(esp))
 				break;
 
-			if (esp_count) {
-				esp->ireg = esp_read8(ESP_INTRPT);
-				if (esp->ireg & ESP_INTR_DC)
-					break;
+			if (((esp->sreg & ESP_STAT_PMASK) != ESP_DOP) &&
+			    ((esp->sreg & ESP_STAT_PMASK) != ESP_MOP))
+				break;
 
-				scsi_esp_cmd(esp, ESP_CMD_TI);
-			}
-		} else {
 			esp->ireg = esp_read8(ESP_INTRPT);
-			if (esp->ireg & ESP_INTR_DC)
+			if ((esp->ireg & (ESP_INTR_DC | ESP_INTR_BSERV)) !=
+			    ESP_INTR_BSERV)
 				break;
 
-			n = MAC_ESP_FIFO_SIZE - n;
+			n = MAC_ESP_FIFO_SIZE -
+			    (esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES);
 			if (n > esp_count)
 				n = esp_count;
 
@@ -429,7 +432,7 @@ static void mac_esp_send_pio_cmd(struct
 		}
 	}
 
-	local_irq_restore(flags);
+	enable_irq(esp->host->irq);
 }
 
 static int mac_esp_irq_pending(struct esp *esp)
@@ -492,29 +495,12 @@ static int __devinit esp_mac_probe(struc
 	struct Scsi_Host *host;
 	struct esp *esp;
 	int err;
-	int chips_present;
 	struct mac_esp_priv *mep;
 
 	if (!MACH_IS_MAC)
 		return -ENODEV;
 
-	switch (macintosh_config->scsi_type) {
-	case MAC_SCSI_QUADRA:
-	case MAC_SCSI_QUADRA3:
-		chips_present = 1;
-		break;
-	case MAC_SCSI_QUADRA2:
-		if ((macintosh_config->ident == MAC_MODEL_Q900) ||
-		    (macintosh_config->ident == MAC_MODEL_Q950))
-			chips_present = 2;
-		else
-			chips_present = 1;
-		break;
-	default:
-		chips_present = 0;
-	}
-
-	if (dev->id + 1 > chips_present)
+	if (dev->id > 1)
 		return -ENODEV;
 
 	host = scsi_host_alloc(tpnt, sizeof(struct esp));
@@ -639,55 +625,26 @@ static struct platform_driver esp_mac_dr
 	.probe    = esp_mac_probe,
 	.remove   = __devexit_p(esp_mac_remove),
 	.driver   = {
-		.name     = DRV_MODULE_NAME,
+		.name	= DRV_MODULE_NAME,
+		.owner	= THIS_MODULE,
 	},
 };
 
 static int __init mac_esp_init(void)
 {
-	int err;
-
-	err = platform_driver_register(&esp_mac_driver);
-	if (err)
-		return err;
-
-	internal_pdev = platform_device_alloc(DRV_MODULE_NAME, 0);
-	if (internal_pdev && platform_device_add(internal_pdev)) {
-		platform_device_put(internal_pdev);
-		internal_pdev = NULL;
-	}
-	external_pdev = platform_device_alloc(DRV_MODULE_NAME, 1);
-	if (external_pdev && platform_device_add(external_pdev)) {
-		platform_device_put(external_pdev);
-		external_pdev = NULL;
-	}
-
-	if (internal_pdev || external_pdev) {
-		return 0;
-	} else {
-		platform_driver_unregister(&esp_mac_driver);
-		return -ENOMEM;
-	}
+	return platform_driver_register(&esp_mac_driver);
 }
 
 static void __exit mac_esp_exit(void)
 {
 	platform_driver_unregister(&esp_mac_driver);
-
-	if (internal_pdev) {
-		platform_device_unregister(internal_pdev);
-		internal_pdev = NULL;
-	}
-	if (external_pdev) {
-		platform_device_unregister(external_pdev);
-		external_pdev = NULL;
-	}
 }
 
 MODULE_DESCRIPTION("Mac ESP SCSI driver");
 MODULE_AUTHOR("Finn Thain <fthain@telegraphics.com.au>");
 MODULE_LICENSE("GPL v2");
 MODULE_VERSION(DRV_VERSION);
+MODULE_ALIAS("platform:" DRV_MODULE_NAME);
 
 module_init(mac_esp_init);
 module_exit(mac_esp_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/megaraid_mbox.c linux-libre-2.6.34-gnu1/drivers/scsi/megaraid/megaraid_mbox.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/megaraid_mbox.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/megaraid/megaraid_mbox.c	2010-05-16 17:17:36.000000000 -0400
@@ -70,6 +70,7 @@
  * For history of changes, see Documentation/ChangeLog.megaraid
  */
 
+#include <linux/slab.h>
 #include "megaraid_mbox.h"
 
 static int megaraid_init(void);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/megaraid_mm.c linux-libre-2.6.34-gnu1/drivers/scsi/megaraid/megaraid_mm.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/megaraid_mm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/megaraid/megaraid_mm.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
  * Common management module
  */
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include "megaraid_mm.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/megaraid_sas.c linux-libre-2.6.34-gnu1/drivers/scsi/megaraid/megaraid_sas.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/megaraid_sas.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/megaraid/megaraid_sas.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,7 @@
  *	   2 of the License, or (at your option) any later version.
  *
  * FILE		: megaraid_sas.c
- * Version     : v00.00.04.12-rc1
+ * Version     : v00.00.04.17.1-rc1
  *
  * Authors:
  *	(email-id : megaraidlinux@lsi.com)
@@ -35,6 +35,7 @@
 #include <linux/delay.h>
 #include <linux/smp_lock.h>
 #include <linux/uio.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/fs.h>
 #include <linux/compat.h>
@@ -843,6 +844,7 @@ megasas_build_dcdb(struct megasas_instan
 	pthru->lun = scp->device->lun;
 	pthru->cdb_len = scp->cmd_len;
 	pthru->timeout = 0;
+	pthru->pad_0 = 0;
 	pthru->flags = flags;
 	pthru->data_xfer_len = scsi_bufflen(scp);
 
@@ -874,6 +876,12 @@ megasas_build_dcdb(struct megasas_instan
 		pthru->sge_count = megasas_make_sgl32(instance, scp,
 						      &pthru->sgl);
 
+	if (pthru->sge_count > instance->max_num_sge) {
+		printk(KERN_ERR "megasas: DCDB two many SGE NUM=%x\n",
+			pthru->sge_count);
+		return 0;
+	}
+
 	/*
 	 * Sense info specific
 	 */
@@ -1000,6 +1008,12 @@ megasas_build_ldio(struct megasas_instan
 	} else
 		ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl);
 
+	if (ldio->sge_count > instance->max_num_sge) {
+		printk(KERN_ERR "megasas: build_ld_io: sge_count = %x\n",
+			ldio->sge_count);
+		return 0;
+	}
+
 	/*
 	 * Sense info specific
 	 */
@@ -2250,6 +2264,7 @@ megasas_get_pd_list(struct megasas_insta
 	dcmd->sge_count = 1;
 	dcmd->flags = MFI_FRAME_DIR_READ;
 	dcmd->timeout = 0;
+	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
 	dcmd->opcode = MR_DCMD_PD_LIST_QUERY;
 	dcmd->sgl.sge32[0].phys_addr = ci_h;
@@ -2294,6 +2309,86 @@ megasas_get_pd_list(struct megasas_insta
 	return ret;
 }
 
+/*
+ * megasas_get_ld_list_info -	Returns FW's ld_list structure
+ * @instance:				Adapter soft state
+ * @ld_list:				ld_list structure
+ *
+ * Issues an internal command (DCMD) to get the FW's controller PD
+ * list structure.  This information is mainly used to find out SYSTEM
+ * supported by the FW.
+ */
+static int
+megasas_get_ld_list(struct megasas_instance *instance)
+{
+	int ret = 0, ld_index = 0, ids = 0;
+	struct megasas_cmd *cmd;
+	struct megasas_dcmd_frame *dcmd;
+	struct MR_LD_LIST *ci;
+	dma_addr_t ci_h = 0;
+
+	cmd = megasas_get_cmd(instance);
+
+	if (!cmd) {
+		printk(KERN_DEBUG "megasas_get_ld_list: Failed to get cmd\n");
+		return -ENOMEM;
+	}
+
+	dcmd = &cmd->frame->dcmd;
+
+	ci = pci_alloc_consistent(instance->pdev,
+				sizeof(struct MR_LD_LIST),
+				&ci_h);
+
+	if (!ci) {
+		printk(KERN_DEBUG "Failed to alloc mem in get_ld_list\n");
+		megasas_return_cmd(instance, cmd);
+		return -ENOMEM;
+	}
+
+	memset(ci, 0, sizeof(*ci));
+	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+	dcmd->cmd = MFI_CMD_DCMD;
+	dcmd->cmd_status = 0xFF;
+	dcmd->sge_count = 1;
+	dcmd->flags = MFI_FRAME_DIR_READ;
+	dcmd->timeout = 0;
+	dcmd->data_xfer_len = sizeof(struct MR_LD_LIST);
+	dcmd->opcode = MR_DCMD_LD_GET_LIST;
+	dcmd->sgl.sge32[0].phys_addr = ci_h;
+	dcmd->sgl.sge32[0].length = sizeof(struct MR_LD_LIST);
+	dcmd->pad_0  = 0;
+
+	if (!megasas_issue_polled(instance, cmd)) {
+		ret = 0;
+	} else {
+		ret = -1;
+	}
+
+	/* the following function will get the instance PD LIST */
+
+	if ((ret == 0) && (ci->ldCount < MAX_LOGICAL_DRIVES)) {
+		memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
+
+		for (ld_index = 0; ld_index < ci->ldCount; ld_index++) {
+			if (ci->ldList[ld_index].state != 0) {
+				ids = ci->ldList[ld_index].ref.targetId;
+				instance->ld_ids[ids] =
+					ci->ldList[ld_index].ref.targetId;
+			}
+		}
+	}
+
+	pci_free_consistent(instance->pdev,
+				sizeof(struct MR_LD_LIST),
+				ci,
+				ci_h);
+
+	megasas_return_cmd(instance, cmd);
+	return ret;
+}
+
 /**
  * megasas_get_controller_info -	Returns FW's controller structure
  * @instance:				Adapter soft state
@@ -2339,6 +2434,7 @@ megasas_get_ctrl_info(struct megasas_ins
 	dcmd->sge_count = 1;
 	dcmd->flags = MFI_FRAME_DIR_READ;
 	dcmd->timeout = 0;
+	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = sizeof(struct megasas_ctrl_info);
 	dcmd->opcode = MR_DCMD_CTRL_GET_INFO;
 	dcmd->sgl.sge32[0].phys_addr = ci_h;
@@ -2590,6 +2686,9 @@ static int megasas_init_mfi(struct megas
 		(MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
 	megasas_get_pd_list(instance);
 
+	memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
+	megasas_get_ld_list(instance);
+
 	ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
 
 	/*
@@ -2714,6 +2813,7 @@ megasas_get_seq_num(struct megasas_insta
 	dcmd->sge_count = 1;
 	dcmd->flags = MFI_FRAME_DIR_READ;
 	dcmd->timeout = 0;
+	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = sizeof(struct megasas_evt_log_info);
 	dcmd->opcode = MR_DCMD_CTRL_EVENT_GET_INFO;
 	dcmd->sgl.sge32[0].phys_addr = el_info_h;
@@ -2828,6 +2928,7 @@ megasas_register_aen(struct megasas_inst
 	dcmd->sge_count = 1;
 	dcmd->flags = MFI_FRAME_DIR_READ;
 	dcmd->timeout = 0;
+	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = sizeof(struct megasas_evt_detail);
 	dcmd->opcode = MR_DCMD_CTRL_EVENT_WAIT;
 	dcmd->mbox.w[0] = seq_num;
@@ -3166,6 +3267,7 @@ static void megasas_flush_cache(struct m
 	dcmd->sge_count = 0;
 	dcmd->flags = MFI_FRAME_DIR_NONE;
 	dcmd->timeout = 0;
+	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = 0;
 	dcmd->opcode = MR_DCMD_CTRL_CACHE_FLUSH;
 	dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
@@ -3205,6 +3307,7 @@ static void megasas_shutdown_controller(
 	dcmd->sge_count = 0;
 	dcmd->flags = MFI_FRAME_DIR_NONE;
 	dcmd->timeout = 0;
+	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = 0;
 	dcmd->opcode = opcode;
 
@@ -3984,6 +4087,7 @@ megasas_aen_polling(struct work_struct *
 	struct  Scsi_Host *host;
 	struct  scsi_device *sdev1;
 	u16     pd_index = 0;
+	u16	ld_index = 0;
 	int     i, j, doscan = 0;
 	u32 seq_num;
 	int error;
@@ -3999,8 +4103,124 @@ megasas_aen_polling(struct work_struct *
 
 		switch (instance->evt_detail->code) {
 		case MR_EVT_PD_INSERTED:
+			if (megasas_get_pd_list(instance) == 0) {
+			for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
+				for (j = 0;
+				j < MEGASAS_MAX_DEV_PER_CHANNEL;
+				j++) {
+
+				pd_index =
+				(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
+
+				sdev1 =
+				scsi_device_lookup(host, i, j, 0);
+
+				if (instance->pd_list[pd_index].driveState
+						== MR_PD_STATE_SYSTEM) {
+						if (!sdev1) {
+						scsi_add_device(host, i, j, 0);
+						}
+
+					if (sdev1)
+						scsi_device_put(sdev1);
+					}
+				}
+			}
+			}
+			doscan = 0;
+			break;
+
 		case MR_EVT_PD_REMOVED:
+			if (megasas_get_pd_list(instance) == 0) {
+			megasas_get_pd_list(instance);
+			for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
+				for (j = 0;
+				j < MEGASAS_MAX_DEV_PER_CHANNEL;
+				j++) {
+
+				pd_index =
+				(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
+
+				sdev1 =
+				scsi_device_lookup(host, i, j, 0);
+
+				if (instance->pd_list[pd_index].driveState
+					== MR_PD_STATE_SYSTEM) {
+					if (sdev1) {
+						scsi_device_put(sdev1);
+					}
+				} else {
+					if (sdev1) {
+						scsi_remove_device(sdev1);
+						scsi_device_put(sdev1);
+					}
+				}
+				}
+			}
+			}
+			doscan = 0;
+			break;
+
+		case MR_EVT_LD_OFFLINE:
+		case MR_EVT_LD_DELETED:
+			megasas_get_ld_list(instance);
+			for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
+				for (j = 0;
+				j < MEGASAS_MAX_DEV_PER_CHANNEL;
+				j++) {
+
+				ld_index =
+				(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
+
+				sdev1 = scsi_device_lookup(host,
+					i + MEGASAS_MAX_LD_CHANNELS,
+					j,
+					0);
+
+				if (instance->ld_ids[ld_index] != 0xff) {
+					if (sdev1) {
+						scsi_device_put(sdev1);
+					}
+				} else {
+					if (sdev1) {
+						scsi_remove_device(sdev1);
+						scsi_device_put(sdev1);
+					}
+				}
+				}
+			}
+			doscan = 0;
+			break;
+		case MR_EVT_LD_CREATED:
+			megasas_get_ld_list(instance);
+			for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
+				for (j = 0;
+					j < MEGASAS_MAX_DEV_PER_CHANNEL;
+					j++) {
+					ld_index =
+					(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
+
+					sdev1 = scsi_device_lookup(host,
+						i+MEGASAS_MAX_LD_CHANNELS,
+						j, 0);
+
+					if (instance->ld_ids[ld_index] !=
+								0xff) {
+						if (!sdev1) {
+							scsi_add_device(host,
+								i + 2,
+								j, 0);
+						}
+					}
+					if (sdev1) {
+						scsi_device_put(sdev1);
+					}
+				}
+			}
+			doscan = 0;
+			break;
 		case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
+		case MR_EVT_FOREIGN_CFG_IMPORTED:
 			doscan = 1;
 			break;
 		default:
@@ -4030,6 +4250,31 @@ megasas_aen_polling(struct work_struct *
 				} else {
 					if (sdev1) {
 						scsi_remove_device(sdev1);
+						scsi_device_put(sdev1);
+					}
+				}
+			}
+		}
+
+		megasas_get_ld_list(instance);
+		for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
+			for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
+				ld_index =
+				(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
+
+				sdev1 = scsi_device_lookup(host,
+					i+MEGASAS_MAX_LD_CHANNELS, j, 0);
+				if (instance->ld_ids[ld_index] != 0xff) {
+					if (!sdev1) {
+						scsi_add_device(host,
+								i+2,
+								j, 0);
+					} else {
+						scsi_device_put(sdev1);
+					}
+				} else {
+					if (sdev1) {
+						scsi_remove_device(sdev1);
 						scsi_device_put(sdev1);
 					}
 				}
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/megaraid_sas.h linux-libre-2.6.34-gnu1/drivers/scsi/megaraid/megaraid_sas.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/megaraid_sas.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/megaraid/megaraid_sas.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,9 +18,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION				"00.00.04.12-rc1"
-#define MEGASAS_RELDATE				"Sep. 17, 2009"
-#define MEGASAS_EXT_VERSION			"Thu Sep. 17 11:41:51 PST 2009"
+#define MEGASAS_VERSION			"00.00.04.17.1-rc1"
+#define MEGASAS_RELDATE			"Oct. 29, 2009"
+#define MEGASAS_EXT_VERSION		"Thu. Oct. 29, 11:41:51 PST 2009"
 
 /*
  * Device IDs
@@ -117,6 +117,7 @@
 #define MFI_CMD_STP				0x08
 
 #define MR_DCMD_CTRL_GET_INFO			0x01010000
+#define MR_DCMD_LD_GET_LIST			0x03010000
 
 #define MR_DCMD_CTRL_CACHE_FLUSH		0x01101000
 #define MR_FLUSH_CTRL_CACHE			0x01
@@ -349,6 +350,32 @@ struct megasas_pd_list {
 	u8             driveState;
 } __packed;
 
+ /*
+ * defines the logical drive reference structure
+ */
+union  MR_LD_REF {
+	struct {
+		u8      targetId;
+		u8      reserved;
+		u16     seqNum;
+	};
+	u32     ref;
+} __packed;
+
+/*
+ * defines the logical drive list structure
+ */
+struct MR_LD_LIST {
+	u32     ldCount;
+	u32     reserved;
+	struct {
+		union MR_LD_REF   ref;
+		u8          state;
+		u8          reserved[3];
+		u64         size;
+	} ldList[MAX_LOGICAL_DRIVES];
+} __packed;
+
 /*
  * SAS controller properties
  */
@@ -637,6 +664,8 @@ struct megasas_ctrl_info {
 #define MEGASAS_MAX_LD				64
 #define MEGASAS_MAX_PD                          (MEGASAS_MAX_PD_CHANNELS * \
 						MEGASAS_MAX_DEV_PER_CHANNEL)
+#define MEGASAS_MAX_LD_IDS			(MEGASAS_MAX_LD_CHANNELS * \
+						MEGASAS_MAX_DEV_PER_CHANNEL)
 
 #define MEGASAS_DBG_LVL				1
 
@@ -1187,6 +1216,7 @@ struct megasas_instance {
 	struct megasas_register_set __iomem *reg_set;
 
 	struct megasas_pd_list          pd_list[MEGASAS_MAX_PD];
+	u8     ld_ids[MEGASAS_MAX_LD_IDS];
 	s8 init_id;
 
 	u16 max_num_sge;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/megaraid.c linux-libre-2.6.34-gnu1/drivers/scsi/megaraid.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/megaraid.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/megaraid.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,7 @@
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <scsi/scsicam.h>
 
 #include "scsi.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mesh.c linux-libre-2.6.34-gnu1/drivers/scsi/mesh.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/mesh.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mesh.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/delay.h>
 #include <linux/types.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/Kconfig linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,7 @@ config SCSI_MPT2SAS
 	tristate "LSI MPT Fusion SAS 2.0 Device Driver"
 	depends on PCI && SCSI
 	select SCSI_SAS_ATTRS
+	select RAID_ATTRS
 	---help---
 	This driver supports PCI-Express SAS 6Gb/s Host Adapters.
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *          Title:  MPI Configuration messages and pages
  *  Creation Date:  November 10, 2006
  *
- *    mpi2_cnfg.h Version:  02.00.12
+ *    mpi2_cnfg.h Version:  02.00.13
  *
  *  Version History
  *  ---------------
@@ -107,6 +107,8 @@
  *                      to SAS Device Page 0 Flags field.
  *                      Added PhyInfo defines for power condition.
  *                      Added Ethernet configuration pages.
+ *  10-28-09  02.00.13  Added MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY.
+ *                      Added SAS PHY Page 4 structure and defines.
  *  --------------------------------------------------------------------------
  */
 
@@ -712,6 +714,7 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT
 #define MPI2_IOUNITPAGE1_PAGEVERSION                    (0x04)
 
 /* IO Unit Page 1 Flags defines */
+#define MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY    (0x00000800)
 #define MPI2_IOUNITPAGE1_MASK_SATA_WRITE_CACHE          (0x00000600)
 #define MPI2_IOUNITPAGE1_ENABLE_SATA_WRITE_CACHE        (0x00000000)
 #define MPI2_IOUNITPAGE1_DISABLE_SATA_WRITE_CACHE       (0x00000200)
@@ -2291,6 +2294,26 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_PHY
 #define MPI2_SASPHY3_PAGEVERSION            (0x00)
 
 
+/* SAS PHY Page 4 */
+
+typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_4 {
+    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                     /* 0x00 */
+    U16                                 Reserved1;                  /* 0x08 */
+    U8                                  Reserved2;                  /* 0x0A */
+    U8                                  Flags;                      /* 0x0B */
+    U8                                  InitialFrame[28];           /* 0x0C */
+} MPI2_CONFIG_PAGE_SAS_PHY_4, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PHY_4,
+  Mpi2SasPhyPage4_t, MPI2_POINTER pMpi2SasPhyPage4_t;
+
+#define MPI2_SASPHY4_PAGEVERSION            (0x00)
+
+/* values for the Flags field */
+#define MPI2_SASPHY4_FLAGS_FRAME_VALID        (0x02)
+#define MPI2_SASPHY4_FLAGS_SATA_FRAME         (0x01)
+
+
+
+
 /****************************************************************************
 *   SAS Port Config Pages
 ****************************************************************************/
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2.h linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpi/mpi2.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpi/mpi2.h	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,7 @@
  *                  scatter/gather formats.
  *  Creation Date:  June 21, 2006
  *
- *  mpi2.h Version:  02.00.13
+ *  mpi2.h Version:  02.00.14
  *
  *  Version History
  *  ---------------
@@ -53,6 +53,10 @@
  *                      bytes reserved.
  *                      Added RAID Accelerator functionality.
  *  07-30-09  02.00.13  Bumped MPI2_HEADER_VERSION_UNIT.
+ *  10-28-09  02.00.14  Bumped MPI2_HEADER_VERSION_UNIT.
+ *                      Added MSI-x index mask and shift for Reply Post Host
+ *                      Index register.
+ *                      Added function code for Host Based Discovery Action.
  *  --------------------------------------------------------------------------
  */
 
@@ -78,7 +82,7 @@
 #define MPI2_VERSION_02_00                  (0x0200)
 
 /* versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT            (0x0D)
+#define MPI2_HEADER_VERSION_UNIT            (0x0E)
 #define MPI2_HEADER_VERSION_DEV             (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK       (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT      (8)
@@ -232,9 +236,12 @@ typedef volatile struct _MPI2_SYSTEM_INT
 #define MPI2_REPLY_FREE_HOST_INDEX_OFFSET       (0x00000048)
 
 /*
- * Offset for the Reply Descriptor Post Queue
+ * Defines for the Reply Descriptor Post Queue
  */
 #define MPI2_REPLY_POST_HOST_INDEX_OFFSET       (0x0000006C)
+#define MPI2_REPLY_POST_HOST_INDEX_MASK         (0x00FFFFFF)
+#define MPI2_RPHI_MSIX_INDEX_MASK               (0xFF000000)
+#define MPI2_RPHI_MSIX_INDEX_SHIFT              (24)
 
 /*
  * Defines for the HCBSize and address
@@ -497,12 +504,13 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UN
 #define MPI2_FUNCTION_TARGET_CMD_BUF_BASE_POST      (0x24) /* Target Command Buffer Post Base */
 #define MPI2_FUNCTION_TARGET_CMD_BUF_LIST_POST      (0x25) /* Target Command Buffer Post List */
 #define MPI2_FUNCTION_RAID_ACCELERATOR              (0x2C) /* RAID Accelerator*/
+/* Host Based Discovery Action */
+#define MPI2_FUNCTION_HOST_BASED_DISCOVERY_ACTION   (0x2F)
 
 
 
 /* Doorbell functions */
 #define MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET        (0x40)
-/* #define MPI2_FUNCTION_IO_UNIT_RESET                 (0x41) */
 #define MPI2_FUNCTION_HANDSHAKE                     (0x42)
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_history.txt linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_history.txt
--- linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_history.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_history.txt	2010-05-16 17:17:36.000000000 -0400
@@ -5,23 +5,24 @@
  Copyright (c) 2000-2009 LSI Corporation.
 
  ---------------------------------------
- Header Set Release Version:    02.00.12
- Header Set Release Date:       05-06-09
+ Header Set Release Version:    02.00.14
+ Header Set Release Date:       10-28-09
  ---------------------------------------
 
  Filename               Current version     Prior version
  ----------             ---------------     -------------
- mpi2.h                 02.00.12            02.00.11
- mpi2_cnfg.h            02.00.11            02.00.10
- mpi2_init.h            02.00.07            02.00.06
- mpi2_ioc.h             02.00.11            02.00.10
- mpi2_raid.h            02.00.03            02.00.03
- mpi2_sas.h             02.00.02            02.00.02
+ mpi2.h                 02.00.14            02.00.13
+ mpi2_cnfg.h            02.00.13            02.00.12
+ mpi2_init.h            02.00.08            02.00.07
+ mpi2_ioc.h             02.00.13            02.00.12
+ mpi2_raid.h            02.00.04            02.00.04
+ mpi2_sas.h             02.00.03            02.00.02
  mpi2_targ.h            02.00.03            02.00.03
- mpi2_tool.h            02.00.03            02.00.02
+ mpi2_tool.h            02.00.04            02.00.04
  mpi2_type.h            02.00.00            02.00.00
- mpi2_ra.h              02.00.00
- mpi2_history.txt       02.00.11            02.00.12
+ mpi2_ra.h              02.00.00            02.00.00
+ mpi2_hbd.h             02.00.00
+ mpi2_history.txt       02.00.14            02.00.13
 
 
  *  Date      Version   Description
@@ -65,6 +66,11 @@ mpi2.h
  *                      MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those
  *                      bytes reserved.
  *                      Added RAID Accelerator functionality.
+ *  07-30-09  02.00.13  Bumped MPI2_HEADER_VERSION_UNIT.
+ *  10-28-09  02.00.14  Bumped MPI2_HEADER_VERSION_UNIT.
+ *                      Added MSI-x index mask and shift for Reply Post Host
+ *                      Index register.
+ *                      Added function code for Host Based Discovery Action.
  *  --------------------------------------------------------------------------
 
 mpi2_cnfg.h
@@ -155,6 +161,15 @@ mpi2_cnfg.h
  *                      Added expander reduced functionality data to SAS
  *                      Expander Page 0.
  *                      Added SAS PHY Page 2 and SAS PHY Page 3.
+ *  07-30-09  02.00.12  Added IO Unit Page 7.
+ *                      Added new device ids.
+ *                      Added SAS IO Unit Page 5.
+ *                      Added partial and slumber power management capable flags
+ *                      to SAS Device Page 0 Flags field.
+ *                      Added PhyInfo defines for power condition.
+ *                      Added Ethernet configuration pages.
+ *  10-28-09  02.00.13  Added MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY.
+ *                      Added SAS PHY Page 4 structure and defines.
  *  --------------------------------------------------------------------------
 
 mpi2_init.h
@@ -172,6 +187,10 @@ mpi2_init.h
  *                      Query Asynchronous Event.
  *                      Defined two new bits in the SlotStatus field of the SCSI
  *                      Enclosure Processor Request and Reply.
+ *  10-28-09  02.00.08  Added defines for decoding the ResponseInfo bytes for
+ *                      both SCSI IO Error Reply and SCSI Task Management Reply.
+ *                      Added ResponseInfo field to MPI2_SCSI_TASK_MANAGE_REPLY.
+ *                      Added MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG define.
  *  --------------------------------------------------------------------------
 
 mpi2_ioc.h
@@ -246,6 +265,20 @@ mpi2_ioc.h
  *                      Added two new reason codes for SAS Device Status Change
  *                      Event.
  *                      Added new event: SAS PHY Counter.
+ *  07-30-09  02.00.12  Added GPIO Interrupt event define and structure.
+ *                      Added MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define.
+ *                      Added new product id family for 2208.
+ *  10-28-09  02.00.13  Added HostMSIxVectors field to MPI2_IOC_INIT_REQUEST.
+ *                      Added MaxMSIxVectors field to MPI2_IOC_FACTS_REPLY.
+ *                      Added MinDevHandle field to MPI2_IOC_FACTS_REPLY.
+ *                      Added MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY.
+ *                      Added MPI2_EVENT_HOST_BASED_DISCOVERY_PHY define.
+ *                      Added MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER define.
+ *                      Added Host Based Discovery Phy Event data.
+ *                      Added defines for ProductID Product field
+ *                      (MPI2_FW_HEADER_PID_).
+ *                      Modified values for SAS ProductID Family
+ *                      (MPI2_FW_HEADER_PID_FAMILY_).
  *  --------------------------------------------------------------------------
 
 mpi2_raid.h
@@ -256,6 +289,8 @@ mpi2_raid.h
  *  05-21-08  02.00.03  Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that
  *                      the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT
  *                      can be sized by the build environment.
+ *  07-30-09  02.00.04  Added proper define for the Use Default Settings bit of
+ *                      VolumeCreationFlags and marked the old one as obsolete.
  *  --------------------------------------------------------------------------
 
 mpi2_sas.h
@@ -264,6 +299,8 @@ mpi2_sas.h
  *                      Control Request.
  *  10-02-08  02.00.02  Added Set IOC Parameter Operation to SAS IO Unit Control
  *                      Request.
+ *  10-28-09  02.00.03  Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST
+ *                      to MPI2_SGE_IO_UNION since it supports chained SGLs.
  *  --------------------------------------------------------------------------
 
 mpi2_targ.h
@@ -283,6 +320,10 @@ mpi2_tool.h
  *                      structures and defines.
  *  02-29-08  02.00.02  Modified various names to make them 32-character unique.
  *  05-06-09  02.00.03  Added ISTWI Read Write Tool and Diagnostic CLI Tool.
+ *  07-30-09  02.00.04  Added ExtendedType field to DiagnosticBufferPost request
+ *                      and reply messages.
+ *                      Added MPI2_DIAG_BUF_TYPE_EXTENDED.
+ *                      Incremented MPI2_DIAG_BUF_TYPE_COUNT.
  *  --------------------------------------------------------------------------
 
 mpi2_type.h
@@ -293,20 +334,26 @@ mpi2_ra.h
  *  05-06-09  02.00.00  Initial version.
  *  --------------------------------------------------------------------------
 
+mpi2_hbd.h
+ *  10-28-09  02.00.00  Initial version.
+ *  --------------------------------------------------------------------------
+
+
 mpi2_history.txt         Parts list history
 
-Filename     02.00.12
-----------   --------
-mpi2.h       02.00.12
-mpi2_cnfg.h  02.00.11
-mpi2_init.h  02.00.07
-mpi2_ioc.h   02.00.11
-mpi2_raid.h  02.00.03
-mpi2_sas.h   02.00.02
-mpi2_targ.h  02.00.03
-mpi2_tool.h  02.00.03
-mpi2_type.h  02.00.00
-mpi2_ra.h    02.00.00
+Filename     02.00.14  02.00.13  02.00.12
+----------   --------  --------  --------
+mpi2.h       02.00.14  02.00.13  02.00.12
+mpi2_cnfg.h  02.00.13  02.00.12  02.00.11
+mpi2_init.h  02.00.08  02.00.07  02.00.07
+mpi2_ioc.h   02.00.13  02.00.12  02.00.11
+mpi2_raid.h  02.00.04  02.00.04  02.00.03
+mpi2_sas.h   02.00.03  02.00.02  02.00.02
+mpi2_targ.h  02.00.03  02.00.03  02.00.03
+mpi2_tool.h  02.00.04  02.00.04  02.00.03
+mpi2_type.h  02.00.00  02.00.00  02.00.00
+mpi2_ra.h    02.00.00  02.00.00  02.00.00
+mpi2_hbd.h   02.00.00
 
 Filename     02.00.11  02.00.10  02.00.09  02.00.08  02.00.07  02.00.06
 ----------   --------  --------  --------  --------  --------  --------
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_init.h linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_init.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_init.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_init.h	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *          Title:  MPI SCSI initiator mode messages and structures
  *  Creation Date:  June 23, 2006
  *
- *    mpi2_init.h Version:  02.00.07
+ *    mpi2_init.h Version:  02.00.08
  *
  *  Version History
  *  ---------------
@@ -27,6 +27,10 @@
  *                      Query Asynchronous Event.
  *                      Defined two new bits in the SlotStatus field of the SCSI
  *                      Enclosure Processor Request and Reply.
+ *  10-28-09  02.00.08  Added defines for decoding the ResponseInfo bytes for
+ *                      both SCSI IO Error Reply and SCSI Task Management Reply.
+ *                      Added ResponseInfo field to MPI2_SCSI_TASK_MANAGE_REPLY.
+ *                      Added MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG define.
  *  --------------------------------------------------------------------------
  */
 
@@ -254,6 +258,11 @@ typedef struct _MPI2_SCSI_IO_REPLY
 #define MPI2_SCSI_STATE_AUTOSENSE_FAILED        (0x02)
 #define MPI2_SCSI_STATE_AUTOSENSE_VALID         (0x01)
 
+/* masks and shifts for the ResponseInfo field */
+
+#define MPI2_SCSI_RI_MASK_REASONCODE            (0x000000FF)
+#define MPI2_SCSI_RI_SHIFT_REASONCODE           (0)
+
 #define MPI2_SCSI_TASKTAG_UNKNOWN               (0xFFFF)
 
 
@@ -327,6 +336,7 @@ typedef struct _MPI2_SCSI_TASK_MANAGE_RE
     U16                     IOCStatus;                      /* 0x0E */
     U32                     IOCLogInfo;                     /* 0x10 */
     U32                     TerminationCount;               /* 0x14 */
+    U32                     ResponseInfo;                   /* 0x18 */
 } MPI2_SCSI_TASK_MANAGE_REPLY,
   MPI2_POINTER PTR_MPI2_SCSI_TASK_MANAGE_REPLY,
   Mpi2SCSITaskManagementReply_t, MPI2_POINTER pMpi2SCSIManagementReply_t;
@@ -339,8 +349,20 @@ typedef struct _MPI2_SCSI_TASK_MANAGE_RE
 #define MPI2_SCSITASKMGMT_RSP_TM_FAILED                 (0x05)
 #define MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED              (0x08)
 #define MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN            (0x09)
+#define MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG         (0x0A)
 #define MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC          (0x80)
 
+/* masks and shifts for the ResponseInfo field */
+
+#define MPI2_SCSITASKMGMT_RI_MASK_REASONCODE            (0x000000FF)
+#define MPI2_SCSITASKMGMT_RI_SHIFT_REASONCODE           (0)
+#define MPI2_SCSITASKMGMT_RI_MASK_ARI2                  (0x0000FF00)
+#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI2                 (8)
+#define MPI2_SCSITASKMGMT_RI_MASK_ARI1                  (0x00FF0000)
+#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI1                 (16)
+#define MPI2_SCSITASKMGMT_RI_MASK_ARI0                  (0xFF000000)
+#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI0                 (24)
+
 
 /****************************************************************************
 *  SCSI Enclosure Processor messages
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *          Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  *  Creation Date:  October 11, 2006
  *
- *  mpi2_ioc.h Version:  02.00.12
+ *  mpi2_ioc.h Version:  02.00.13
  *
  *  Version History
  *  ---------------
@@ -87,6 +87,17 @@
  *  07-30-09  02.00.12  Added GPIO Interrupt event define and structure.
  *                      Added MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define.
  *                      Added new product id family for 2208.
+ *  10-28-09  02.00.13  Added HostMSIxVectors field to MPI2_IOC_INIT_REQUEST.
+ *                      Added MaxMSIxVectors field to MPI2_IOC_FACTS_REPLY.
+ *                      Added MinDevHandle field to MPI2_IOC_FACTS_REPLY.
+ *                      Added MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY.
+ *                      Added MPI2_EVENT_HOST_BASED_DISCOVERY_PHY define.
+ *                      Added MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER define.
+ *                      Added Host Based Discovery Phy Event data.
+ *                      Added defines for ProductID Product field
+ *                      (MPI2_FW_HEADER_PID_).
+ *                      Modified values for SAS ProductID Family
+ *                      (MPI2_FW_HEADER_PID_FAMILY_).
  *  --------------------------------------------------------------------------
  */
 
@@ -119,8 +130,10 @@ typedef struct _MPI2_IOC_INIT_REQUEST
     U16                     MsgVersion;                     /* 0x0C */
     U16                     HeaderVersion;                  /* 0x0E */
     U32                     Reserved5;                      /* 0x10 */
-    U32                     Reserved6;                      /* 0x14 */
-    U16                     Reserved7;                      /* 0x18 */
+    U16                     Reserved6;                      /* 0x14 */
+    U8                      Reserved7;                      /* 0x16 */
+    U8                      HostMSIxVectors;                /* 0x17 */
+    U16                     Reserved8;                      /* 0x18 */
     U16                     SystemRequestFrameSize;         /* 0x1A */
     U16                     ReplyDescriptorPostQueueDepth;  /* 0x1C */
     U16                     ReplyFreeQueueDepth;            /* 0x1E */
@@ -215,7 +228,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY
     U8                      MaxChainDepth;                  /* 0x14 */
     U8                      WhoInit;                        /* 0x15 */
     U8                      NumberOfPorts;                  /* 0x16 */
-    U8                      Reserved2;                      /* 0x17 */
+    U8                      MaxMSIxVectors;                 /* 0x17 */
     U16                     RequestCredit;                  /* 0x18 */
     U16                     ProductID;                      /* 0x1A */
     U32                     IOCCapabilities;                /* 0x1C */
@@ -233,7 +246,8 @@ typedef struct _MPI2_IOC_FACTS_REPLY
     U8                      MaxVolumes;                     /* 0x37 */
     U16                     MaxDevHandle;                   /* 0x38 */
     U16                     MaxPersistentEntries;           /* 0x3A */
-    U32                     Reserved4;                      /* 0x3C */
+    U16                     MinDevHandle;                   /* 0x3C */
+    U16                     Reserved4;                      /* 0x3E */
 } MPI2_IOC_FACTS_REPLY, MPI2_POINTER PTR_MPI2_IOC_FACTS_REPLY,
   Mpi2IOCFactsReply_t, MPI2_POINTER pMpi2IOCFactsReply_t;
 
@@ -269,6 +283,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY
 /* ProductID field uses MPI2_FW_HEADER_PID_ */
 
 /* IOCCapabilities */
+#define MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY   (0x00010000)
 #define MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX            (0x00008000)
 #define MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR       (0x00004000)
 #define MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY           (0x00002000)
@@ -453,6 +468,7 @@ typedef struct _MPI2_EVENT_NOTIFICATION_
 #define MPI2_EVENT_LOG_ENTRY_ADDED                  (0x0021)
 #define MPI2_EVENT_SAS_PHY_COUNTER                  (0x0022)
 #define MPI2_EVENT_GPIO_INTERRUPT                   (0x0023)
+#define MPI2_EVENT_HOST_BASED_DISCOVERY_PHY         (0x0024)
 
 
 /* Log Entry Added Event data */
@@ -793,6 +809,7 @@ typedef struct _MPI2_EVENT_DATA_SAS_TOPO
   MPI2_POINTER pMpi2EventDataSasTopologyChangeList_t;
 
 /* values for the ExpStatus field */
+#define MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER                  (0x00)
 #define MPI2_EVENT_SAS_TOPO_ES_ADDED                        (0x01)
 #define MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING               (0x02)
 #define MPI2_EVENT_SAS_TOPO_ES_RESPONDING                   (0x03)
@@ -878,6 +895,44 @@ typedef struct _MPI2_EVENT_DATA_SAS_PHY_
  * */
 
 
+/* Host Based Discovery Phy Event data */
+
+typedef struct _MPI2_EVENT_HBD_PHY_SAS {
+    U8          Flags;                      /* 0x00 */
+    U8          NegotiatedLinkRate;         /* 0x01 */
+    U8          PhyNum;                     /* 0x02 */
+    U8          PhysicalPort;               /* 0x03 */
+    U32         Reserved1;                  /* 0x04 */
+    U8          InitialFrame[28];           /* 0x08 */
+} MPI2_EVENT_HBD_PHY_SAS, MPI2_POINTER PTR_MPI2_EVENT_HBD_PHY_SAS,
+  Mpi2EventHbdPhySas_t, MPI2_POINTER pMpi2EventHbdPhySas_t;
+
+/* values for the Flags field */
+#define MPI2_EVENT_HBD_SAS_FLAGS_FRAME_VALID        (0x02)
+#define MPI2_EVENT_HBD_SAS_FLAGS_SATA_FRAME         (0x01)
+
+/* use MPI2_SAS_NEG_LINK_RATE_ defines from mpi2_cnfg.h for
+ * the NegotiatedLinkRate field */
+
+typedef union _MPI2_EVENT_HBD_DESCRIPTOR {
+    MPI2_EVENT_HBD_PHY_SAS      Sas;
+} MPI2_EVENT_HBD_DESCRIPTOR, MPI2_POINTER PTR_MPI2_EVENT_HBD_DESCRIPTOR,
+  Mpi2EventHbdDescriptor_t, MPI2_POINTER pMpi2EventHbdDescriptor_t;
+
+typedef struct _MPI2_EVENT_DATA_HBD_PHY {
+    U8                          DescriptorType;     /* 0x00 */
+    U8                          Reserved1;          /* 0x01 */
+    U16                         Reserved2;          /* 0x02 */
+    U32                         Reserved3;          /* 0x04 */
+    MPI2_EVENT_HBD_DESCRIPTOR   Descriptor;         /* 0x08 */
+} MPI2_EVENT_DATA_HBD_PHY, MPI2_POINTER PTR_MPI2_EVENT_DATA_HBD_PHY,
+  Mpi2EventDataHbdPhy_t, MPI2_POINTER pMpi2EventDataMpi2EventDataHbdPhy_t;
+
+/* values for the DescriptorType field */
+#define MPI2_EVENT_HBD_DT_SAS               (0x01)
+
+
+
 /****************************************************************************
 *  EventAck message
 ****************************************************************************/
@@ -1126,13 +1181,17 @@ typedef struct _MPI2_FW_IMAGE_HEADER
 #define MPI2_FW_HEADER_PID_TYPE_MASK            (0xF000)
 #define MPI2_FW_HEADER_PID_TYPE_SAS             (0x2000)
 
-#define MPI2_FW_HEADER_PID_PROD_MASK            (0x0F00)
-#define MPI2_FW_HEADER_PID_PROD_A               (0x0000)
+#define MPI2_FW_HEADER_PID_PROD_MASK                    (0x0F00)
+#define MPI2_FW_HEADER_PID_PROD_A                       (0x0000)
+#define MPI2_FW_HEADER_PID_PROD_MASK                    (0x0F00)
+#define MPI2_FW_HEADER_PID_PROD_TARGET_INITIATOR_SCSI   (0x0200)
+#define MPI2_FW_HEADER_PID_PROD_IR_SCSI                 (0x0700)
+
 
 #define MPI2_FW_HEADER_PID_FAMILY_MASK          (0x00FF)
 /* SAS */
-#define MPI2_FW_HEADER_PID_FAMILY_2108_SAS      (0x0010)
-#define MPI2_FW_HEADER_PID_FAMILY_2208_SAS      (0x0011)
+#define MPI2_FW_HEADER_PID_FAMILY_2108_SAS      (0x0013)
+#define MPI2_FW_HEADER_PID_FAMILY_2208_SAS      (0x0014)
 
 /* use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_sas.h linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_sas.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_sas.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_sas.h	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *          Title:  MPI Serial Attached SCSI structures and definitions
  *  Creation Date:  February 9, 2007
  *
- *  mpi2.h Version:  02.00.02
+ *  mpi2.h Version:  02.00.03
  *
  *  Version History
  *  ---------------
@@ -18,6 +18,8 @@
  *                      Control Request.
  *  10-02-08  02.00.02  Added Set IOC Parameter Operation to SAS IO Unit Control
  *                      Request.
+ *  10-28-09  02.00.03  Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST
+ *                      to MPI2_SGE_IO_UNION since it supports chained SGLs.
  *  --------------------------------------------------------------------------
  */
 
@@ -160,7 +162,7 @@ typedef struct _MPI2_SATA_PASSTHROUGH_RE
     U32                     Reserved4;          /* 0x14 */
     U32                     DataLength;         /* 0x18 */
     U8                      CommandFIS[20];     /* 0x1C */
-    MPI2_SIMPLE_SGE_UNION   SGL;                /* 0x20 */
+    MPI2_SGE_IO_UNION       SGL;                /* 0x20 */
 } MPI2_SATA_PASSTHROUGH_REQUEST, MPI2_POINTER PTR_MPI2_SATA_PASSTHROUGH_REQUEST,
   Mpi2SataPassthroughRequest_t, MPI2_POINTER pMpi2SataPassthroughRequest_t;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.c linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.c	2010-05-16 17:17:36.000000000 -0400
@@ -107,8 +107,7 @@ _scsih_set_fwfault_debug(const char *val
 	if (ret)
 		return ret;
 
-	printk(KERN_INFO "setting logging_level(0x%08x)\n",
-				mpt2sas_fwfault_debug);
+	printk(KERN_INFO "setting fwfault_debug(%d)\n", mpt2sas_fwfault_debug);
 	list_for_each_entry(ioc, &mpt2sas_ioc_list, list)
 		ioc->fwfault_debug = mpt2sas_fwfault_debug;
 	return 0;
@@ -1222,6 +1221,8 @@ mpt2sas_base_map_resources(struct MPT2SA
 	u32 memap_sz;
 	u32 pio_sz;
 	int i, r = 0;
+	u64 pio_chip = 0;
+	u64 chip_phys = 0;
 
 	dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n",
 	    ioc->name, __func__));
@@ -1255,12 +1256,13 @@ mpt2sas_base_map_resources(struct MPT2SA
 		if (pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO) {
 			if (pio_sz)
 				continue;
-			ioc->pio_chip = pci_resource_start(pdev, i);
+			pio_chip = (u64)pci_resource_start(pdev, i);
 			pio_sz = pci_resource_len(pdev, i);
 		} else {
 			if (memap_sz)
 				continue;
 			ioc->chip_phys = pci_resource_start(pdev, i);
+			chip_phys = (u64)ioc->chip_phys;
 			memap_sz = pci_resource_len(pdev, i);
 			ioc->chip = ioremap(ioc->chip_phys, memap_sz);
 			if (ioc->chip == NULL) {
@@ -1280,10 +1282,10 @@ mpt2sas_base_map_resources(struct MPT2SA
 	printk(MPT2SAS_INFO_FMT "%s: IRQ %d\n",
 	    ioc->name,  ((ioc->msix_enable) ? "PCI-MSI-X enabled" :
 	    "IO-APIC enabled"), ioc->pci_irq);
-	printk(MPT2SAS_INFO_FMT "iomem(0x%lx), mapped(0x%p), size(%d)\n",
-	    ioc->name, ioc->chip_phys, ioc->chip, memap_sz);
-	printk(MPT2SAS_INFO_FMT "ioport(0x%lx), size(%d)\n",
-	    ioc->name, ioc->pio_chip, pio_sz);
+	printk(MPT2SAS_INFO_FMT "iomem(0x%016llx), mapped(0x%p), size(%d)\n",
+	    ioc->name, (unsigned long long)chip_phys, ioc->chip, memap_sz);
+	printk(MPT2SAS_INFO_FMT "ioport(0x%016llx), size(%d)\n",
+	    ioc->name, (unsigned long long)pio_chip, pio_sz);
 
 	return 0;
 
@@ -3573,6 +3575,8 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPT
 
 	init_waitqueue_head(&ioc->reset_wq);
 
+	ioc->fwfault_debug = mpt2sas_fwfault_debug;
+
 	/* base internal command bits */
 	mutex_init(&ioc->base_cmds.mutex);
 	ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.h linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.h	2010-05-16 17:17:36.000000000 -0400
@@ -69,10 +69,10 @@
 #define MPT2SAS_DRIVER_NAME		"mpt2sas"
 #define MPT2SAS_AUTHOR	"LSI Corporation <DL-MPTFusionLinux@lsi.com>"
 #define MPT2SAS_DESCRIPTION	"LSI MPT Fusion SAS 2.0 Device Driver"
-#define MPT2SAS_DRIVER_VERSION		"03.100.03.00"
-#define MPT2SAS_MAJOR_VERSION		03
+#define MPT2SAS_DRIVER_VERSION		"04.100.01.00"
+#define MPT2SAS_MAJOR_VERSION		04
 #define MPT2SAS_MINOR_VERSION		100
-#define MPT2SAS_BUILD_VERSION		03
+#define MPT2SAS_BUILD_VERSION		01
 #define MPT2SAS_RELEASE_VERSION		00
 
 /*
@@ -323,6 +323,7 @@ struct _sas_device {
  * @device_info: bitfield provides detailed info about the hidden components
  * @num_pds: number of hidden raid components
  * @responding: used in _scsih_raid_device_mark_responding
+ * @percent_complete: resync percent complete
  */
 struct _raid_device {
 	struct list_head list;
@@ -336,6 +337,7 @@ struct _raid_device {
 	u32	device_info;
 	u8	num_pds;
 	u8	responding;
+	u8	percent_complete;
 };
 
 /**
@@ -464,7 +466,6 @@ typedef void (*MPT_ADD_SGE)(void *paddr,
  * @pdev: pci pdev object
  * @chip: memory mapped register space
  * @chip_phys: physical addrss prior to mapping
- * @pio_chip: I/O mapped register space
  * @logging_level: see mpt2sas_debug.h
  * @fwfault_debug: debuging FW timeouts
  * @ir_firmware: IR firmware present
@@ -587,8 +588,7 @@ struct MPT2SAS_ADAPTER {
 	char		tmp_string[MPT_STRING_LENGTH];
 	struct pci_dev	*pdev;
 	Mpi2SystemInterfaceRegs_t __iomem *chip;
-	unsigned long	chip_phys;
-	unsigned long	pio_chip;
+	resource_size_t	chip_phys;
 	int		logging_level;
 	int		fwfault_debug;
 	u8		ir_firmware;
@@ -853,6 +853,8 @@ int mpt2sas_config_set_iounit_pg1(struct
     *mpi_reply, Mpi2IOUnitPage1_t *config_page);
 int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
     *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz);
+int mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
+    Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz);
 int mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
     *mpi_reply, Mpi2IOCPage8_t *config_page);
 int mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_config.c linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpt2sas_config.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_config.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpt2sas_config.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,6 +51,7 @@
 #include <linux/workqueue.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "mpt2sas_base.h"
 
@@ -324,7 +325,9 @@ _config_request(struct MPT2SAS_ADAPTER *
 		if (r != 0)
 			goto out;
 		if (mpi_request->Action ==
-		    MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT) {
+		    MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT ||
+		    mpi_request->Action ==
+		    MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
 			ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
 			    MPT2_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz,
 			    mem.page_dma);
@@ -882,7 +885,7 @@ mpt2sas_config_get_sas_iounit_pg0(struct
 }
 
 /**
- * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 0
+ * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1
  * @ioc: per adapter object
  * @mpi_reply: reply mf payload returned from firmware
  * @config_page: contents of the config page
@@ -907,7 +910,7 @@ mpt2sas_config_get_sas_iounit_pg1(struct
 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
 	mpi_request.Header.PageNumber = 1;
-	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
+	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
 	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
@@ -918,6 +921,49 @@ mpt2sas_config_get_sas_iounit_pg1(struct
 	r = _config_request(ioc, &mpi_request, mpi_reply,
 	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
  out:
+	return r;
+}
+
+/**
+ * mpt2sas_config_set_sas_iounit_pg1 - send sas iounit page 1
+ * @ioc: per adapter object
+ * @mpi_reply: reply mf payload returned from firmware
+ * @config_page: contents of the config page
+ * @sz: size of buffer passed in config_page
+ * Context: sleep.
+ *
+ * Calling function should call config_get_number_hba_phys prior to
+ * this function, so enough memory is allocated for config_page.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+int
+mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
+    *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz)
+{
+	Mpi2ConfigRequest_t mpi_request;
+	int r;
+
+	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
+	mpi_request.Function = MPI2_FUNCTION_CONFIG;
+	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
+	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
+	mpi_request.Header.PageNumber = 1;
+	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
+	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
+	r = _config_request(ioc, &mpi_request, mpi_reply,
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
+	if (r)
+		goto out;
+
+	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
+	_config_request(ioc, &mpi_request, mpi_reply,
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
+	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
+	r = _config_request(ioc, &mpi_request, mpi_reply,
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
+ out:
 	return r;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_ctl.c linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpt2sas_ctl.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_ctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpt2sas_ctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -891,6 +891,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPT
 
  issue_host_reset:
 	if (issue_reset) {
+		ret = -ENODATA;
 		if ((mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
 		    mpi_request->Function ==
 		    MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
@@ -2202,14 +2203,10 @@ _ctl_compat_mpt_command(struct file *fil
 	karg.data_out_size = karg32.data_out_size;
 	karg.max_sense_bytes = karg32.max_sense_bytes;
 	karg.data_sge_offset = karg32.data_sge_offset;
-	memcpy(&karg.reply_frame_buf_ptr, &karg32.reply_frame_buf_ptr,
-	    sizeof(uint32_t));
-	memcpy(&karg.data_in_buf_ptr, &karg32.data_in_buf_ptr,
-	    sizeof(uint32_t));
-	memcpy(&karg.data_out_buf_ptr, &karg32.data_out_buf_ptr,
-	    sizeof(uint32_t));
-	memcpy(&karg.sense_data_ptr, &karg32.sense_data_ptr,
-	    sizeof(uint32_t));
+	karg.reply_frame_buf_ptr = compat_ptr(karg32.reply_frame_buf_ptr);
+	karg.data_in_buf_ptr = compat_ptr(karg32.data_in_buf_ptr);
+	karg.data_out_buf_ptr = compat_ptr(karg32.data_out_buf_ptr);
+	karg.sense_data_ptr = compat_ptr(karg32.sense_data_ptr);
 	state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING;
 	return _ctl_do_mpt_command(ioc, karg, &uarg->mf, state);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_scsih.c linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpt2sas_scsih.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_scsih.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpt2sas_scsih.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,6 +52,8 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
+#include <linux/raid_class.h>
+#include <linux/slab.h>
 
 #include "mpt2sas_base.h"
 
@@ -133,6 +135,9 @@ struct fw_event_work {
 	void			*event_data;
 };
 
+/* raid transport support */
+static struct raid_template *mpt2sas_raid_template;
+
 /**
  * struct _scsi_io_transfer - scsi io transfer
  * @handle: sas device handle (assigned by firmware)
@@ -1305,7 +1310,6 @@ _scsih_slave_alloc(struct scsi_device *s
 	struct MPT2SAS_DEVICE *sas_device_priv_data;
 	struct scsi_target *starget;
 	struct _raid_device *raid_device;
-	struct _sas_device *sas_device;
 	unsigned long flags;
 
 	sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL);
@@ -1332,21 +1336,8 @@ _scsih_slave_alloc(struct scsi_device *s
 		if (raid_device)
 			raid_device->sdev = sdev; /* raid is single lun */
 		spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-	} else {
-		/* set TLR bit for SSP devices */
-		if (!(ioc->facts.IOCCapabilities &
-		     MPI2_IOCFACTS_CAPABILITY_TLR))
-			goto out;
-		spin_lock_irqsave(&ioc->sas_device_lock, flags);
-		sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
-		   sas_device_priv_data->sas_target->sas_address);
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		if (sas_device && sas_device->device_info &
-		    MPI2_SAS_DEVICE_INFO_SSP_TARGET)
-			sas_device_priv_data->flags |= MPT_DEVICE_TLR_ON;
 	}
 
- out:
 	return 0;
 }
 
@@ -1419,6 +1410,140 @@ _scsih_display_sata_capabilities(struct
 }
 
 /**
+ * _scsih_is_raid - return boolean indicating device is raid volume
+ * @dev the device struct object
+ */
+static int
+_scsih_is_raid(struct device *dev)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+
+	return (sdev->channel == RAID_CHANNEL) ? 1 : 0;
+}
+
+/**
+ * _scsih_get_resync - get raid volume resync percent complete
+ * @dev the device struct object
+ */
+static void
+_scsih_get_resync(struct device *dev)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
+	static struct _raid_device *raid_device;
+	unsigned long flags;
+	Mpi2RaidVolPage0_t vol_pg0;
+	Mpi2ConfigReply_t mpi_reply;
+	u32 volume_status_flags;
+	u8 percent_complete = 0;
+
+	spin_lock_irqsave(&ioc->raid_device_lock, flags);
+	raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
+	    sdev->channel);
+	spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
+
+	if (!raid_device)
+		goto out;
+
+	if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
+	     MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle,
+	     sizeof(Mpi2RaidVolPage0_t))) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		goto out;
+	}
+
+	volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags);
+	if (volume_status_flags & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS)
+		percent_complete = raid_device->percent_complete;
+ out:
+	raid_set_resync(mpt2sas_raid_template, dev, percent_complete);
+}
+
+/**
+ * _scsih_get_state - get raid volume level
+ * @dev the device struct object
+ */
+static void
+_scsih_get_state(struct device *dev)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
+	static struct _raid_device *raid_device;
+	unsigned long flags;
+	Mpi2RaidVolPage0_t vol_pg0;
+	Mpi2ConfigReply_t mpi_reply;
+	u32 volstate;
+	enum raid_state state = RAID_STATE_UNKNOWN;
+
+	spin_lock_irqsave(&ioc->raid_device_lock, flags);
+	raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
+	    sdev->channel);
+	spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
+
+	if (!raid_device)
+		goto out;
+
+	if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
+	     MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle,
+	     sizeof(Mpi2RaidVolPage0_t))) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		goto out;
+	}
+
+	volstate = le32_to_cpu(vol_pg0.VolumeStatusFlags);
+	if (volstate & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) {
+		state = RAID_STATE_RESYNCING;
+		goto out;
+	}
+
+	switch (vol_pg0.VolumeState) {
+	case MPI2_RAID_VOL_STATE_OPTIMAL:
+	case MPI2_RAID_VOL_STATE_ONLINE:
+		state = RAID_STATE_ACTIVE;
+		break;
+	case  MPI2_RAID_VOL_STATE_DEGRADED:
+		state = RAID_STATE_DEGRADED;
+		break;
+	case MPI2_RAID_VOL_STATE_FAILED:
+	case MPI2_RAID_VOL_STATE_MISSING:
+		state = RAID_STATE_OFFLINE;
+		break;
+	}
+ out:
+	raid_set_state(mpt2sas_raid_template, dev, state);
+}
+
+/**
+ * _scsih_set_level - set raid level
+ * @sdev: scsi device struct
+ * @raid_device: raid_device object
+ */
+static void
+_scsih_set_level(struct scsi_device *sdev, struct _raid_device *raid_device)
+{
+	enum raid_level level = RAID_LEVEL_UNKNOWN;
+
+	switch (raid_device->volume_type) {
+	case MPI2_RAID_VOL_TYPE_RAID0:
+		level = RAID_LEVEL_0;
+		break;
+	case MPI2_RAID_VOL_TYPE_RAID10:
+		level = RAID_LEVEL_10;
+		break;
+	case MPI2_RAID_VOL_TYPE_RAID1E:
+		level = RAID_LEVEL_1E;
+		break;
+	case MPI2_RAID_VOL_TYPE_RAID1:
+		level = RAID_LEVEL_1;
+		break;
+	}
+
+	raid_set_level(mpt2sas_raid_template, &sdev->sdev_gendev, level);
+}
+
+/**
  * _scsih_get_volume_capabilities - volume capabilities
  * @ioc: per adapter object
  * @sas_device: the raid_device object
@@ -1479,6 +1604,32 @@ _scsih_get_volume_capabilities(struct MP
 }
 
 /**
+ * _scsih_enable_tlr - setting TLR flags
+ * @ioc: per adapter object
+ * @sdev: scsi device struct
+ *
+ * Enabling Transaction Layer Retries for tape devices when
+ * vpd page 0x90 is present
+ *
+ */
+static void
+_scsih_enable_tlr(struct MPT2SAS_ADAPTER *ioc, struct scsi_device *sdev)
+{
+	/* only for TAPE */
+	if (sdev->type != TYPE_TAPE)
+		return;
+
+	if (!(ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR))
+		return;
+
+	sas_enable_tlr(sdev);
+	sdev_printk(KERN_INFO, sdev, "TLR %s\n",
+	    sas_is_tlr_enabled(sdev) ? "Enabled" : "Disabled");
+	return;
+
+}
+
+/**
  * _scsih_slave_configure - device configure routine.
  * @sdev: scsi device struct
  *
@@ -1574,6 +1725,8 @@ _scsih_slave_configure(struct scsi_devic
 		    (unsigned long long)raid_device->wwid,
 		    raid_device->num_pds, ds);
 		_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
+		/* raid transport support */
+		_scsih_set_level(sdev, raid_device);
 		return 0;
 	}
 
@@ -1621,8 +1774,10 @@ _scsih_slave_configure(struct scsi_devic
 
 	_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
 
-	if (ssp_target)
+	if (ssp_target) {
 		sas_read_port_mode_page(sdev);
+		_scsih_enable_tlr(ioc, sdev);
+	}
 	return 0;
 }
 
@@ -2908,8 +3063,9 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void
 
 	} else
 		mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
-
-	if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON))
+	/* Make sure Device is not raid volume */
+	if (!_scsih_is_raid(&scmd->device->sdev_gendev) &&
+	    sas_is_tlr_enabled(scmd->device))
 		mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
 
 	smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd);
@@ -3298,10 +3454,12 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *i
 		    le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
 	if (!sas_device_priv_data->tlr_snoop_check) {
 		sas_device_priv_data->tlr_snoop_check++;
-		if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) &&
-		    response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME)
-			sas_device_priv_data->flags &=
-			    ~MPT_DEVICE_TLR_ON;
+	if (!_scsih_is_raid(&scmd->device->sdev_gendev) &&
+		sas_is_tlr_enabled(scmd->device) &&
+		    response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
+			sas_disable_tlr(scmd->device);
+			sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n");
+		}
 	}
 
 	xfer_cnt = le32_to_cpu(mpi_reply->TransferCount);
@@ -5170,11 +5328,33 @@ static void
 _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,
     struct fw_event_work *fw_event)
 {
+	Mpi2EventDataIrOperationStatus_t *event_data = fw_event->event_data;
+	static struct _raid_device *raid_device;
+	unsigned long flags;
+	u16 handle;
+
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 	if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
 		_scsih_sas_ir_operation_status_event_debug(ioc,
-		     fw_event->event_data);
+		     event_data);
 #endif
+
+	/* code added for raid transport support */
+	if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) {
+
+		handle = le16_to_cpu(event_data->VolDevHandle);
+
+		spin_lock_irqsave(&ioc->raid_device_lock, flags);
+		raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
+		spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
+
+		if (!raid_device)
+			return;
+
+		if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC)
+			raid_device->percent_complete =
+			    event_data->PercentComplete;
+	}
 }
 
 /**
@@ -5998,6 +6178,8 @@ _scsih_remove(struct pci_dev *pdev)
 	struct _sas_port *mpt2sas_port;
 	struct _sas_device *sas_device;
 	struct _sas_node *expander_sibling;
+	struct _raid_device *raid_device, *next;
+	struct MPT2SAS_TARGET *sas_target_priv_data;
 	struct workqueue_struct	*wq;
 	unsigned long flags;
 
@@ -6011,6 +6193,21 @@ _scsih_remove(struct pci_dev *pdev)
 	if (wq)
 		destroy_workqueue(wq);
 
+	/* release all the volumes */
+	list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list,
+	    list) {
+		if (raid_device->starget) {
+			sas_target_priv_data =
+			    raid_device->starget->hostdata;
+			sas_target_priv_data->deleted = 1;
+			scsi_remove_target(&raid_device->starget->dev);
+		}
+		printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid"
+		    "(0x%016llx)\n", ioc->name,  raid_device->handle,
+		    (unsigned long long) raid_device->wwid);
+		_scsih_raid_device_remove(ioc, raid_device);
+	}
+
 	/* free ports attached to the sas_host */
  retry_again:
 	list_for_each_entry(mpt2sas_port,
@@ -6373,6 +6570,13 @@ static struct pci_driver scsih_driver =
 #endif
 };
 
+/* raid transport support */
+static struct raid_function_template mpt2sas_raid_functions = {
+	.cookie		= &scsih_driver_template,
+	.is_raid	= _scsih_is_raid,
+	.get_resync	= _scsih_get_resync,
+	.get_state	= _scsih_get_state,
+};
 
 /**
  * _scsih_init - main entry point for this driver.
@@ -6392,6 +6596,12 @@ _scsih_init(void)
 	    sas_attach_transport(&mpt2sas_transport_functions);
 	if (!mpt2sas_transport_template)
 		return -ENODEV;
+	/* raid transport support */
+	mpt2sas_raid_template = raid_class_attach(&mpt2sas_raid_functions);
+	if (!mpt2sas_raid_template) {
+		sas_release_transport(mpt2sas_transport_template);
+		return -ENODEV;
+	}
 
 	mpt2sas_base_initialize_callback_handler();
 
@@ -6426,8 +6636,11 @@ _scsih_init(void)
 	mpt2sas_ctl_init();
 
 	error = pci_register_driver(&scsih_driver);
-	if (error)
+	if (error) {
+		/* raid transport support */
+		raid_class_release(mpt2sas_raid_template);
 		sas_release_transport(mpt2sas_transport_template);
+	}
 
 	return error;
 }
@@ -6445,7 +6658,8 @@ _scsih_exit(void)
 
 	pci_unregister_driver(&scsih_driver);
 
-	sas_release_transport(mpt2sas_transport_template);
+	mpt2sas_ctl_exit();
+
 	mpt2sas_base_release_callback_handler(scsi_io_cb_idx);
 	mpt2sas_base_release_callback_handler(tm_cb_idx);
 	mpt2sas_base_release_callback_handler(base_cb_idx);
@@ -6457,7 +6671,10 @@ _scsih_exit(void)
 	mpt2sas_base_release_callback_handler(tm_tr_cb_idx);
 	mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx);
 
-	mpt2sas_ctl_exit();
+	/* raid transport support */
+	raid_class_release(mpt2sas_raid_template);
+	sas_release_transport(mpt2sas_transport_template);
+
 }
 
 module_init(_scsih_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_transport.c linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpt2sas_transport.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_transport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mpt2sas/mpt2sas_transport.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,7 @@
 #include <linux/workqueue.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -855,6 +856,17 @@ rphy_to_ioc(struct sas_rphy *rphy)
 	return shost_priv(shost);
 }
 
+static struct _sas_phy *
+_transport_find_local_phy(struct MPT2SAS_ADAPTER *ioc, struct sas_phy *phy)
+{
+	int i;
+
+	for (i = 0; i < ioc->sas_hba.num_phys; i++)
+		if (ioc->sas_hba.phy[i].phy == phy)
+			return(&ioc->sas_hba.phy[i]);
+	return NULL;
+}
+
 /**
  * _transport_get_linkerrors -
  * @phy: The sas phy object
@@ -870,14 +882,8 @@ _transport_get_linkerrors(struct sas_phy
 	struct _sas_phy *mpt2sas_phy;
 	Mpi2ConfigReply_t mpi_reply;
 	Mpi2SasPhyPage1_t phy_pg1;
-	int i;
 
-	for (i = 0, mpt2sas_phy = NULL; i < ioc->sas_hba.num_phys &&
-	    !mpt2sas_phy; i++) {
-		if (ioc->sas_hba.phy[i].phy != phy)
-			continue;
-		mpt2sas_phy = &ioc->sas_hba.phy[i];
-	}
+	mpt2sas_phy = _transport_find_local_phy(ioc, phy);
 
 	if (!mpt2sas_phy) /* this phy not on sas_host */
 		return -EINVAL;
@@ -971,14 +977,8 @@ _transport_phy_reset(struct sas_phy *phy
 	struct _sas_phy *mpt2sas_phy;
 	Mpi2SasIoUnitControlReply_t mpi_reply;
 	Mpi2SasIoUnitControlRequest_t mpi_request;
-	int i;
 
-	for (i = 0, mpt2sas_phy = NULL; i < ioc->sas_hba.num_phys &&
-	    !mpt2sas_phy; i++) {
-		if (ioc->sas_hba.phy[i].phy != phy)
-			continue;
-		mpt2sas_phy = &ioc->sas_hba.phy[i];
-	}
+	mpt2sas_phy = _transport_find_local_phy(ioc, phy);
 
 	if (!mpt2sas_phy) /* this phy not on sas_host */
 		return -EINVAL;
@@ -1006,6 +1006,173 @@ _transport_phy_reset(struct sas_phy *phy
 }
 
 /**
+ * _transport_phy_enable - enable/disable phys
+ * @phy: The sas phy object
+ * @enable: enable phy when true
+ *
+ * Only support sas_host direct attached phys.
+ * Returns 0 for success, non-zero for failure.
+ */
+static int
+_transport_phy_enable(struct sas_phy *phy, int enable)
+{
+	struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
+	struct _sas_phy *mpt2sas_phy;
+	Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
+	Mpi2ConfigReply_t mpi_reply;
+	u16 ioc_status;
+	u16 sz;
+	int rc = 0;
+
+	mpt2sas_phy = _transport_find_local_phy(ioc, phy);
+
+	if (!mpt2sas_phy) /* this phy not on sas_host */
+		return -EINVAL;
+
+	/* sas_iounit page 1 */
+	sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
+	    sizeof(Mpi2SasIOUnit1PhyData_t));
+	sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
+	if (!sas_iounit_pg1) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		rc = -ENOMEM;
+		goto out;
+	}
+	if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
+	    sas_iounit_pg1, sz))) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		rc = -ENXIO;
+		goto out;
+	}
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+	    MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		rc = -EIO;
+		goto out;
+	}
+
+	if (enable)
+		sas_iounit_pg1->PhyData[mpt2sas_phy->phy_id].PhyFlags
+		    &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
+	else
+		sas_iounit_pg1->PhyData[mpt2sas_phy->phy_id].PhyFlags
+		    |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
+
+	mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz);
+
+ out:
+	kfree(sas_iounit_pg1);
+	return rc;
+}
+
+/**
+ * _transport_phy_speed - set phy min/max link rates
+ * @phy: The sas phy object
+ * @rates: rates defined in sas_phy_linkrates
+ *
+ * Only support sas_host direct attached phys.
+ * Returns 0 for success, non-zero for failure.
+ */
+static int
+_transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates)
+{
+	struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
+	struct _sas_phy *mpt2sas_phy;
+	Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
+	Mpi2SasPhyPage0_t phy_pg0;
+	Mpi2ConfigReply_t mpi_reply;
+	u16 ioc_status;
+	u16 sz;
+	int i;
+	int rc = 0;
+
+	mpt2sas_phy = _transport_find_local_phy(ioc, phy);
+
+	if (!mpt2sas_phy) /* this phy not on sas_host */
+		return -EINVAL;
+
+	if (!rates->minimum_linkrate)
+		rates->minimum_linkrate = phy->minimum_linkrate;
+	else if (rates->minimum_linkrate < phy->minimum_linkrate_hw)
+		rates->minimum_linkrate = phy->minimum_linkrate_hw;
+
+	if (!rates->maximum_linkrate)
+		rates->maximum_linkrate = phy->maximum_linkrate;
+	else if (rates->maximum_linkrate > phy->maximum_linkrate_hw)
+		rates->maximum_linkrate = phy->maximum_linkrate_hw;
+
+	/* sas_iounit page 1 */
+	sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
+	    sizeof(Mpi2SasIOUnit1PhyData_t));
+	sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
+	if (!sas_iounit_pg1) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		rc = -ENOMEM;
+		goto out;
+	}
+	if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
+	    sas_iounit_pg1, sz))) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		rc = -ENXIO;
+		goto out;
+	}
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+	    MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		rc = -EIO;
+		goto out;
+	}
+
+	for (i = 0; i < ioc->sas_hba.num_phys; i++) {
+		if (mpt2sas_phy->phy_id != i) {
+			sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
+			    (ioc->sas_hba.phy[i].phy->minimum_linkrate +
+			    (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4));
+		} else {
+			sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
+			    (rates->minimum_linkrate +
+			    (rates->maximum_linkrate << 4));
+		}
+	}
+
+	if (mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1,
+	    sz)) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		rc = -ENXIO;
+		goto out;
+	}
+
+	/* link reset */
+	_transport_phy_reset(phy, 0);
+
+	/* read phy page 0, then update the rates in the sas transport phy */
+	if (!mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
+	    mpt2sas_phy->phy_id)) {
+		phy->minimum_linkrate = _transport_convert_phy_link_rate(
+		    phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
+		phy->maximum_linkrate = _transport_convert_phy_link_rate(
+		    phy_pg0.ProgrammedLinkRate >> 4);
+		phy->negotiated_linkrate = _transport_convert_phy_link_rate(
+		    phy_pg0.NegotiatedLinkRate &
+		    MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
+	}
+
+ out:
+	kfree(sas_iounit_pg1);
+	return rc;
+}
+
+
+/**
  * _transport_smp_handler - transport portal for smp passthru
  * @shost: shost object
  * @rphy: sas transport rphy object
@@ -1207,6 +1374,8 @@ struct sas_function_template mpt2sas_tra
 	.get_enclosure_identifier = _transport_get_enclosure_identifier,
 	.get_bay_identifier	= _transport_get_bay_identifier,
 	.phy_reset		= _transport_phy_reset,
+	.phy_enable		= _transport_phy_enable,
+	.set_phy_speed		= _transport_phy_speed,
 	.smp_handler		= _transport_smp_handler,
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mvme16x_scsi.c linux-libre-2.6.34-gnu1/drivers/scsi/mvme16x_scsi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/mvme16x_scsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mvme16x_scsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/mvme16xhw.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/mvsas/mv_sas.h linux-libre-2.6.34-gnu1/drivers/scsi/mvsas/mv_sas.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/mvsas/mv_sas.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/mvsas/mv_sas.h	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <scsi/libsas.h>
 #include <scsi/scsi_tcq.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/ncr53c8xx.c linux-libre-2.6.34-gnu1/drivers/scsi/ncr53c8xx.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/ncr53c8xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/ncr53c8xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -98,6 +98,7 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/NCR_D700.c linux-libre-2.6.34-gnu1/drivers/scsi/NCR_D700.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/NCR_D700.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/NCR_D700.c	2010-05-16 17:17:36.000000000 -0400
@@ -97,6 +97,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mca.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/NCR_Q720.c linux-libre-2.6.34-gnu1/drivers/scsi/NCR_Q720.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/NCR_Q720.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/NCR_Q720.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mca.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/nsp32.c linux-libre-2.6.34-gnu1/drivers/scsi/nsp32.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/nsp32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/nsp32.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/ioport.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/osd/osd_initiator.c linux-libre-2.6.34-gnu1/drivers/scsi/osd/osd_initiator.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/osd/osd_initiator.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/osd/osd_initiator.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include <scsi/osd_initiator.h>
 #include <scsi/osd_sec.h>
 #include <scsi/osd_attributes.h>
@@ -1433,6 +1435,10 @@ int osd_finalize_request(struct osd_requ
 	cdbh->command_specific_options |= or->attributes_mode;
 	if (or->attributes_mode == OSD_CDB_GET_ATTR_PAGE_SET_ONE) {
 		ret = _osd_req_finalize_attr_page(or);
+		if (ret) {
+			OSD_DEBUG("_osd_req_finalize_attr_page failed\n");
+			return ret;
+		}
 	} else {
 		/* TODO: I think that for the GET_ATTR command these 2 should
 		 * be reversed to keep them in execution order (for embeded
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/osd/osd_uld.c linux-libre-2.6.34-gnu1/drivers/scsi/osd/osd_uld.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/osd/osd_uld.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/osd/osd_uld.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,6 +50,7 @@
 #include <linux/idr.h>
 #include <linux/major.h>
 #include <linux/file.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_driver.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/osst.c linux-libre-2.6.34-gnu1/drivers/scsi/osst.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/osst.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/osst.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@ static const char * osst_version = "0.99
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/errno.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/pcmcia/nsp_cs.c linux-libre-2.6.34-gnu1/drivers/scsi/pcmcia/nsp_cs.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/pcmcia/nsp_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/pcmcia/nsp_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -1717,6 +1717,7 @@ static int nsp_cs_config(struct pcmcia_d
 	cfg_mem->data = data;
 
 	ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem);
+	if (ret)
 		goto cs_failed;
 
 	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/pcmcia/nsp_cs.h linux-libre-2.6.34-gnu1/drivers/scsi/pcmcia/nsp_cs.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/pcmcia/nsp_cs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/pcmcia/nsp_cs.h	2010-05-16 17:17:36.000000000 -0400
@@ -187,7 +187,7 @@
 #define S_IO		BIT(1)    /* Input/Output line from SCSI bus */
 #define S_CD		BIT(2)    /* Command/Data line from SCSI bus */
 #define S_BUSY		BIT(3)    /* Busy line from SCSI bus         */
-#define S_ACK		BIT(4)    /* Acknowlege line from SCSI bus   */
+#define S_ACK		BIT(4)    /* Acknowledge line from SCSI bus  */
 #define S_REQUEST	BIT(5)    /* Request line from SCSI bus      */
 #define S_SELECT	BIT(6)	  /*                                 */
 #define S_ATN		BIT(7)	  /*                                 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_ctl.c linux-libre-2.6.34-gnu1/drivers/scsi/pm8001/pm8001_ctl.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_ctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/pm8001/pm8001_ctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
  *
  */
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include "pm8001_sas.h"
 #include "pm8001_ctl.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_hwi.c linux-libre-2.6.34-gnu1/drivers/scsi/pm8001/pm8001_hwi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_hwi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/pm8001/pm8001_hwi.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  *
  */
+ #include <linux/slab.h>
  #include "pm8001_sas.h"
  #include "pm8001_hwi.h"
  #include "pm8001_chips.h"
@@ -2924,7 +2925,7 @@ hw_event_sas_phy_up(struct pm8001_hba_in
 		break;
 	default:
 		PM8001_MSG_DBG(pm8001_ha,
-			pm8001_printk("unkown device type(%x)\n", deviceType));
+			pm8001_printk("unknown device type(%x)\n", deviceType));
 		break;
 	}
 	phy->phy_type |= PORT_TYPE_SAS;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_init.c linux-libre-2.6.34-gnu1/drivers/scsi/pm8001/pm8001_init.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/pm8001/pm8001_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include "pm8001_sas.h"
 #include "pm8001_chips.h"
 
@@ -654,7 +655,7 @@ static int __devinit pm8001_pci_probe(st
 	}
 	chip = &pm8001_chips[ent->driver_data];
 	SHOST_TO_SAS_HA(shost) =
-		kcalloc(1, sizeof(struct sas_ha_struct), GFP_KERNEL);
+		kzalloc(sizeof(struct sas_ha_struct), GFP_KERNEL);
 	if (!SHOST_TO_SAS_HA(shost)) {
 		rc = -ENOMEM;
 		goto err_out_free_host;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_sas.c linux-libre-2.6.34-gnu1/drivers/scsi/pm8001/pm8001_sas.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_sas.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/pm8001/pm8001_sas.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include "pm8001_sas.h"
 
 /**
@@ -600,7 +601,7 @@ static void pm8001_free_dev(struct pm800
   * by the command "OPC_INB_REG_DEV", after that the HBA will assign a
   * device ID(according to device's sas address) and returned it to LLDD. From
   * now on, we communicate with HBA FW with the device ID which HBA assigned
-  * rather than sas address. it is the neccessary step for our HBA but it is
+  * rather than sas address. it is the necessary step for our HBA but it is
   * the optional for other HBA driver.
   */
 static int pm8001_dev_found_notify(struct domain_device *dev)
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/pmcraid.c linux-libre-2.6.34-gnu1/drivers/scsi/pmcraid.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/pmcraid.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/pmcraid.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@
 #include <linux/hdreg.h>
 #include <linux/version.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <asm/irq.h>
 #include <asm/processor.h>
 #include <linux/libata.h>
@@ -235,7 +236,7 @@ static int pmcraid_slave_configure(struc
 		scsi_dev->allow_restart = 1;
 		blk_queue_rq_timeout(scsi_dev->request_queue,
 				     PMCRAID_VSET_IO_TIMEOUT);
-		blk_queue_max_sectors(scsi_dev->request_queue,
+		blk_queue_max_hw_sectors(scsi_dev->request_queue,
 				      PMCRAID_VSET_MAX_SECTORS);
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/pmcraid.h linux-libre-2.6.34-gnu1/drivers/scsi/pmcraid.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/pmcraid.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/pmcraid.h	2010-05-16 17:17:36.000000000 -0400
@@ -938,7 +938,7 @@ static struct pmcraid_ioasc_error pmcrai
 
 /*
  * pmcraid_ioctl_header - definition of header structure that preceeds all the
- * buffers given as ioctl arguements.
+ * buffers given as ioctl arguments.
  *
  * .signature           : always ASCII string, "PMCRAID"
  * .reserved            : not used
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/ppa.c linux-libre-2.6.34-gnu1/drivers/scsi/ppa.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/ppa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/ppa.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/blkdev.h>
 #include <linux/parport.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/ps3rom.c linux-libre-2.6.34-gnu1/drivers/scsi/ps3rom.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/ps3rom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/ps3rom.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 
 #include <linux/cdrom.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla1280.c linux-libre-2.6.34-gnu1/drivers/scsi/qla1280.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla1280.c	2013-05-03 12:12:40.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla1280.c	2013-05-03 09:52:12.000000000 -0400
@@ -17,9 +17,11 @@
 * General Public License for more details.
 *
 ******************************************************************************/
-#define QLA1280_VERSION      "3.27"
+#define QLA1280_VERSION      "3.27.1"
 /*****************************************************************************
     Revision History:
+    Rev  3.27.1, February 8, 2010, Michael Reed
+	- Retain firmware image for error recovery.
     Rev  3.27, February 10, 2009, Michael Reed
 	- General code cleanup.
 	- Improve error recovery.
@@ -346,7 +348,6 @@
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
-#include <linux/slab.h>
 #include <linux/pci_ids.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -538,9 +539,9 @@ __setup("qla1280=", qla1280_setup);
 /*****************************************/
 
 struct qla_boards {
-	unsigned char name[9];	/* Board ID String */
+	char *name;		/* Board ID String */
 	int numPorts;		/* Number of SCSI ports */
-	char *fwname;		/* firmware name        */
+	int fw_index;		/* index into qla1280_fw_tbl for firmware */
 };
 
 /* NOTE: the last argument in each entry is used to index ql1280_board_tbl */
@@ -561,15 +562,30 @@ static struct pci_device_id qla1280_pci_
 };
 MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl);
 
+DEFINE_MUTEX(qla1280_firmware_mutex);
+
+struct qla_fw {
+	char *fwname;
+	const struct firmware *fw;
+};
+
+#define QL_NUM_FW_IMAGES 3
+
+struct qla_fw qla1280_fw_tbl[QL_NUM_FW_IMAGES] = {
+	{"/*(DEBLOBBED)*/",  NULL},	/* image 0 */
+	{"/*(DEBLOBBED)*/",  NULL},	/* image 1 */
+	{"/*(DEBLOBBED)*/", NULL},	/* image 2 */
+};
+
+/* NOTE: Order of boards in this table must match order in qla1280_pci_tbl */
 static struct qla_boards ql1280_board_tbl[] = {
-	/* Name ,  Number of ports, FW details */
-	{"QLA12160",	2, "/*(DEBLOBBED)*/"},
-	{"QLA1040",	1, "/*(DEBLOBBED)*/"},
-	{"QLA1080",	1, "/*(DEBLOBBED)*/"},
-	{"QLA1240",	2, "/*(DEBLOBBED)*/"},
-	{"QLA1280",	2, "/*(DEBLOBBED)*/"},
-	{"QLA10160",	1, "/*(DEBLOBBED)*/"},
-	{"        ",	0, "   "},
+	{.name = "QLA12160", .numPorts = 2, .fw_index = 2},
+	{.name = "QLA1040" , .numPorts = 1, .fw_index = 0},
+	{.name = "QLA1080" , .numPorts = 1, .fw_index = 1},
+	{.name = "QLA1240" , .numPorts = 2, .fw_index = 1},
+	{.name = "QLA1280" , .numPorts = 2, .fw_index = 1},
+	{.name = "QLA10160", .numPorts = 1, .fw_index = 2},
+	{.name = "        ", .numPorts = 0, .fw_index = -1},
 };
 
 static int qla1280_verbose = 1;
@@ -1512,6 +1528,63 @@ qla1280_initialize_adapter(struct scsi_q
 }
 
 /*
+ * qla1280_reject_firmware
+ *      Acquire firmware for chip.  Retain in memory
+ *      for error recovery.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ *
+ * Returns:
+ *      Pointer to firmware image or an error code
+ *      cast to pointer via ERR_PTR().
+ */
+static const struct firmware *
+qla1280_reject_firmware(struct scsi_qla_host *ha)
+{
+	const struct firmware *fw;
+	int err;
+	int index;
+	char *fwname;
+
+	spin_unlock_irq(ha->host->host_lock);
+	mutex_lock(&qla1280_firmware_mutex);
+
+	index = ql1280_board_tbl[ha->devnum].fw_index;
+	fw = qla1280_fw_tbl[index].fw;
+	if (fw)
+		goto out;
+
+	fwname = qla1280_fw_tbl[index].fwname;
+	err = reject_firmware(&fw, fwname, &ha->pdev->dev);
+
+	if (err) {
+		printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+		       fwname, err);
+		fw = ERR_PTR(err);
+		goto unlock;
+	}
+	if ((fw->size % 2) || (fw->size < 6)) {
+		printk(KERN_ERR "Invalid firmware length %zu in image \"%s\"\n",
+		       fw->size, fwname);
+		release_firmware(fw);
+		fw = ERR_PTR(-EINVAL);
+		goto unlock;
+	}
+
+	qla1280_fw_tbl[index].fw = fw;
+
+ out:
+	ha->fwver1 = fw->data[0];
+	ha->fwver2 = fw->data[1];
+	ha->fwver3 = fw->data[2];
+ unlock:
+	mutex_unlock(&qla1280_firmware_mutex);
+	spin_lock_irq(ha->host->host_lock);
+	return fw;
+}
+
+/*
  * Chip diagnostics
  *      Test chip for proper operation.
  *
@@ -1634,28 +1707,18 @@ qla1280_chip_diag(struct scsi_qla_host *
 static int
 qla1280_load_firmware_pio(struct scsi_qla_host *ha)
 {
+	/* enter with host_lock acquired */
+
 	const struct firmware *fw;
 	const __le16 *fw_data;
 	uint16_t risc_address, risc_code_size;
 	uint16_t mb[MAILBOX_REGISTER_COUNT], i;
-	int err;
+	int err = 0;
+
+	fw = qla1280_reject_firmware(ha);
+	if (IS_ERR(fw))
+		return PTR_ERR(fw);
 
-	err = reject_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
-			       &ha->pdev->dev);
-	if (err) {
-		printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
-		       ql1280_board_tbl[ha->devnum].fwname, err);
-		return err;
-	}
-	if ((fw->size % 2) || (fw->size < 6)) {
-		printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
-		       fw->size, ql1280_board_tbl[ha->devnum].fwname);
-		err = -EINVAL;
-		goto out;
-	}
-	ha->fwver1 = fw->data[0];
-	ha->fwver2 = fw->data[1];
-	ha->fwver3 = fw->data[2];
 	fw_data = (const __le16 *)&fw->data[0];
 	ha->fwstart = __le16_to_cpu(fw_data[2]);
 
@@ -1673,11 +1736,10 @@ qla1280_load_firmware_pio(struct scsi_ql
 		if (err) {
 			printk(KERN_ERR "scsi(%li): Failed to load firmware\n",
 					ha->host_no);
-			goto out;
+			break;
 		}
 	}
-out:
-	release_firmware(fw);
+
 	return err;
 }
 
@@ -1685,6 +1747,7 @@ out:
 static int
 qla1280_load_firmware_dma(struct scsi_qla_host *ha)
 {
+	/* enter with host_lock acquired */
 	const struct firmware *fw;
 	const __le16 *fw_data;
 	uint16_t risc_address, risc_code_size;
@@ -1699,22 +1762,10 @@ qla1280_load_firmware_dma(struct scsi_ql
 		return -ENOMEM;
 #endif
 
-	err = reject_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
-			       &ha->pdev->dev);
-	if (err) {
-		printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
-		       ql1280_board_tbl[ha->devnum].fwname, err);
-		return err;
-	}
-	if ((fw->size % 2) || (fw->size < 6)) {
-		printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
-		       fw->size, ql1280_board_tbl[ha->devnum].fwname);
-		err = -EINVAL;
-		goto out;
-	}
-	ha->fwver1 = fw->data[0];
-	ha->fwver2 = fw->data[1];
-	ha->fwver3 = fw->data[2];
+	fw = qla1280_reject_firmware(ha);
+	if (IS_ERR(fw))
+		return PTR_ERR(fw);
+
 	fw_data = (const __le16 *)&fw->data[0];
 	ha->fwstart = __le16_to_cpu(fw_data[2]);
 
@@ -1799,7 +1850,6 @@ qla1280_load_firmware_dma(struct scsi_ql
 #if DUMP_IT_BACK
 	pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf);
 #endif
-	release_firmware(fw);
 	return err;
 }
 
@@ -1838,6 +1888,7 @@ qla1280_start_firmware(struct scsi_qla_h
 static int
 qla1280_load_firmware(struct scsi_qla_host *ha)
 {
+	/* enter with host_lock taken */
 	int err;
 
 	err = qla1280_chip_diag(ha);
@@ -4416,7 +4467,16 @@ qla1280_init(void)
 static void __exit
 qla1280_exit(void)
 {
+	int i;
+
 	pci_unregister_driver(&qla1280_pci_driver);
+	/* release any allocated firmware images */
+	for (i = 0; i < QL_NUM_FW_IMAGES; i++) {
+		if (qla1280_fw_tbl[i].fw) {
+			release_firmware(qla1280_fw_tbl[i].fw);
+			qla1280_fw_tbl[i].fw = NULL;
+		}
+	}
 }
 
 module_init(qla1280_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_attr.c linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_attr.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_attr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_attr.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,10 +8,13 @@
 
 #include <linux/kthread.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 
 static int qla24xx_vport_disable(struct fc_vport *, bool);
-
+static int qla84xx_reset(scsi_qla_host_t *, struct msg_echo_lb *, struct fc_bsg_job *);
+int qla84xx_reset_chip(scsi_qla_host_t *, uint16_t, uint16_t *);
+static int qla84xx_mgmt_cmd(scsi_qla_host_t *, struct msg_echo_lb *, struct fc_bsg_job *);
 /* SYSFS attributes --------------------------------------------------------- */
 
 static ssize_t
@@ -1168,6 +1171,28 @@ qla2x00_total_isp_aborts_show(struct dev
 }
 
 static ssize_t
+qla24xx_84xx_fw_version_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	int rval = QLA_SUCCESS;
+	uint16_t status[2] = {0, 0};
+	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+	struct qla_hw_data *ha = vha->hw;
+
+	if (IS_QLA84XX(ha) && ha->cs84xx) {
+		if (ha->cs84xx->op_fw_version == 0) {
+			rval = qla84xx_verify_chip(vha, status);
+	}
+
+	if ((rval == QLA_SUCCESS) && (status[0] == 0))
+		return snprintf(buf, PAGE_SIZE, "%u\n",
+			(uint32_t)ha->cs84xx->op_fw_version);
+	}
+
+	return snprintf(buf, PAGE_SIZE, "\n");
+}
+
+static ssize_t
 qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr,
     char *buf)
 {
@@ -1250,7 +1275,11 @@ qla2x00_fw_state_show(struct device *dev
 	int rval = QLA_FUNCTION_FAILED;
 	uint16_t state[5];
 
-	if (!vha->hw->flags.eeh_busy)
+	if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
+		test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
+		DEBUG2_3_11(printk("%s(%ld): isp reset in progress.\n",
+			__func__, vha->host_no));
+	else if (!vha->hw->flags.eeh_busy)
 		rval = qla2x00_get_firmware_state(vha, state);
 	if (rval != QLA_SUCCESS)
 		memset(state, -1, sizeof(state));
@@ -1281,6 +1310,8 @@ static DEVICE_ATTR(optrom_fcode_version,
 		   qla2x00_optrom_fcode_version_show, NULL);
 static DEVICE_ATTR(optrom_fw_version, S_IRUGO, qla2x00_optrom_fw_version_show,
 		   NULL);
+static DEVICE_ATTR(84xx_fw_version, S_IRUGO, qla24xx_84xx_fw_version_show,
+		   NULL);
 static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show,
 		   NULL);
 static DEVICE_ATTR(mpi_version, S_IRUGO, qla2x00_mpi_version_show, NULL);
@@ -1310,6 +1341,7 @@ struct device_attribute *qla2x00_host_at
 	&dev_attr_optrom_efi_version,
 	&dev_attr_optrom_fcode_version,
 	&dev_attr_optrom_fw_version,
+	&dev_attr_84xx_fw_version,
 	&dev_attr_total_isp_aborts,
 	&dev_attr_mpi_version,
 	&dev_attr_phy_version,
@@ -1504,8 +1536,6 @@ qla2x00_terminate_rport_io(struct fc_rpo
 		fcport->vha->hw->isp_ops->fabric_logout(fcport->vha,
 			fcport->loop_id, fcport->d_id.b.domain,
 			fcport->d_id.b.area, fcport->d_id.b.al_pa);
-
-	qla2x00_abort_fcport_cmds(fcport);
 }
 
 static int
@@ -1795,6 +1825,582 @@ qla24xx_vport_disable(struct fc_vport *f
 	return 0;
 }
 
+/* BSG support for ELS/CT pass through */
+inline srb_t *
+qla2x00_get_ctx_bsg_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size)
+{
+	srb_t *sp;
+	struct qla_hw_data *ha = vha->hw;
+	struct srb_bsg_ctx *ctx;
+
+	sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL);
+	if (!sp)
+		goto done;
+	ctx = kzalloc(size, GFP_KERNEL);
+	if (!ctx) {
+		mempool_free(sp, ha->srb_mempool);
+		goto done;
+	}
+
+	memset(sp, 0, sizeof(*sp));
+	sp->fcport = fcport;
+	sp->ctx = ctx;
+done:
+	return sp;
+}
+
+static int
+qla2x00_process_els(struct fc_bsg_job *bsg_job)
+{
+	struct fc_rport *rport;
+	fc_port_t *fcport;
+	struct Scsi_Host *host;
+	scsi_qla_host_t *vha;
+	struct qla_hw_data *ha;
+	srb_t *sp;
+	const char *type;
+	int req_sg_cnt, rsp_sg_cnt;
+	int rval =  (DRIVER_ERROR << 16);
+	uint16_t nextlid = 0;
+	struct srb_bsg *els;
+
+	/*  Multiple SG's are not supported for ELS requests */
+        if (bsg_job->request_payload.sg_cnt > 1 ||
+		bsg_job->reply_payload.sg_cnt > 1) {
+		DEBUG2(printk(KERN_INFO
+		    "multiple SG's are not supported for ELS requests"
+		    " [request_sg_cnt: %x reply_sg_cnt: %x]\n",
+		    bsg_job->request_payload.sg_cnt,
+		    bsg_job->reply_payload.sg_cnt));
+		rval = -EPERM;
+		goto done;
+        }
+
+	/* ELS request for rport */
+	if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
+		rport = bsg_job->rport;
+		fcport = *(fc_port_t **) rport->dd_data;
+		host = rport_to_shost(rport);
+		vha = shost_priv(host);
+		ha = vha->hw;
+		type = "FC_BSG_RPT_ELS";
+
+		/* make sure the rport is logged in,
+		 * if not perform fabric login
+		 */
+		if (qla2x00_fabric_login(vha, fcport, &nextlid)) {
+			DEBUG2(qla_printk(KERN_WARNING, ha,
+			    "failed to login port %06X for ELS passthru\n",
+			    fcport->d_id.b24));
+			rval = -EIO;
+			goto done;
+		}
+	} else {
+		host = bsg_job->shost;
+		vha = shost_priv(host);
+		ha = vha->hw;
+		type = "FC_BSG_HST_ELS_NOLOGIN";
+
+		/* Allocate a dummy fcport structure, since functions
+		 * preparing the IOCB and mailbox command retrieves port
+		 * specific information from fcport structure. For Host based
+		 * ELS commands there will be no fcport structure allocated
+		 */
+		fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
+		if (!fcport) {
+			rval = -ENOMEM;
+			goto done;
+		}
+
+		/* Initialize all required  fields of fcport */
+		fcport->vha = vha;
+		fcport->vp_idx = vha->vp_idx;
+		fcport->d_id.b.al_pa =
+		    bsg_job->request->rqst_data.h_els.port_id[0];
+		fcport->d_id.b.area =
+		    bsg_job->request->rqst_data.h_els.port_id[1];
+		fcport->d_id.b.domain =
+		    bsg_job->request->rqst_data.h_els.port_id[2];
+		fcport->loop_id =
+		    (fcport->d_id.b.al_pa == 0xFD) ?
+		    NPH_FABRIC_CONTROLLER : NPH_F_PORT;
+	}
+
+	if (!vha->flags.online) {
+		DEBUG2(qla_printk(KERN_WARNING, ha,
+		    "host not online\n"));
+		rval = -EIO;
+		goto done;
+	}
+
+        req_sg_cnt =
+	    dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
+	    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
+        if (!req_sg_cnt) {
+		rval = -ENOMEM;
+		goto done_free_fcport;
+	}
+        rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
+	    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+        if (!rsp_sg_cnt) {
+		rval = -ENOMEM;
+                goto done_free_fcport;
+	}
+
+	if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
+	    (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt))
+	{
+		DEBUG2(printk(KERN_INFO
+		    "dma mapping resulted in different sg counts \
+		    [request_sg_cnt: %x dma_request_sg_cnt: %x\
+		    reply_sg_cnt: %x dma_reply_sg_cnt: %x]\n",
+		    bsg_job->request_payload.sg_cnt, req_sg_cnt,
+		    bsg_job->reply_payload.sg_cnt, rsp_sg_cnt));
+		rval = -EAGAIN;
+                goto done_unmap_sg;
+	}
+
+	/* Alloc SRB structure */
+	sp = qla2x00_get_ctx_bsg_sp(vha, fcport, sizeof(struct srb_bsg));
+	if (!sp) {
+		rval = -ENOMEM;
+                goto done_unmap_sg;
+	}
+
+	els = sp->ctx;
+	els->ctx.type =
+	    (bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
+	    SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
+	els->bsg_job = bsg_job;
+
+	DEBUG2(qla_printk(KERN_INFO, ha,
+	    "scsi(%ld:%x): bsg rqst type: %s els type: %x - loop-id=%x "
+	    "portid=%02x%02x%02x.\n", vha->host_no, sp->handle, type,
+	    bsg_job->request->rqst_data.h_els.command_code,
+	    fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
+	    fcport->d_id.b.al_pa));
+
+	rval = qla2x00_start_sp(sp);
+	if (rval != QLA_SUCCESS) {
+		kfree(sp->ctx);
+		mempool_free(sp, ha->srb_mempool);
+		rval = -EIO;
+		goto done_unmap_sg;
+	}
+	return rval;
+
+done_unmap_sg:
+	dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
+		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
+		bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+	goto done_free_fcport;
+
+done_free_fcport:
+	if (bsg_job->request->msgcode == FC_BSG_HST_ELS_NOLOGIN)
+		kfree(fcport);
+done:
+	return rval;
+}
+
+static int
+qla2x00_process_ct(struct fc_bsg_job *bsg_job)
+{
+	srb_t *sp;
+	struct Scsi_Host *host = bsg_job->shost;
+	scsi_qla_host_t *vha = shost_priv(host);
+	struct qla_hw_data *ha = vha->hw;
+	int rval = (DRIVER_ERROR << 16);
+	int req_sg_cnt, rsp_sg_cnt;
+	uint16_t loop_id;
+	struct fc_port *fcport;
+	char  *type = "FC_BSG_HST_CT";
+	struct srb_bsg *ct;
+
+	/* pass through is supported only for ISP 4Gb or higher */
+        if (!IS_FWI2_CAPABLE(ha)) {
+		DEBUG2(qla_printk(KERN_INFO, ha,
+		    "scsi(%ld):Firmware is not capable to support FC "
+		    "CT pass thru\n", vha->host_no));
+		rval = -EPERM;
+                goto done;
+	}
+
+        req_sg_cnt =
+	    dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
+	    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
+        if (!req_sg_cnt) {
+		rval = -ENOMEM;
+		goto done;
+	}
+
+        rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
+            bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+        if (!rsp_sg_cnt) {
+		rval = -ENOMEM;
+                goto done;
+	}
+
+	if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
+		(rsp_sg_cnt != bsg_job->reply_payload.sg_cnt))
+	{
+		DEBUG2(qla_printk(KERN_WARNING, ha,
+		    "dma mapping resulted in different sg counts \
+		    [request_sg_cnt: %x dma_request_sg_cnt: %x\
+		    reply_sg_cnt: %x dma_reply_sg_cnt: %x]\n",
+		    bsg_job->request_payload.sg_cnt, req_sg_cnt,
+		    bsg_job->reply_payload.sg_cnt, rsp_sg_cnt));
+		rval = -EAGAIN;
+                goto done_unmap_sg;
+	}
+
+	if (!vha->flags.online) {
+		DEBUG2(qla_printk(KERN_WARNING, ha,
+		    "host not online\n"));
+		rval = -EIO;
+                goto done_unmap_sg;
+	}
+
+	loop_id =
+	    (bsg_job->request->rqst_data.h_ct.preamble_word1 & 0xFF000000)
+	    >> 24;
+	switch (loop_id) {
+		case 0xFC:
+			loop_id = cpu_to_le16(NPH_SNS);
+			break;
+		case 0xFA:
+			loop_id = vha->mgmt_svr_loop_id;
+			break;
+		default:
+			DEBUG2(qla_printk(KERN_INFO, ha,
+			    "Unknown loop id: %x\n", loop_id));
+			rval = -EINVAL;
+			goto done_unmap_sg;
+	}
+
+	/* Allocate a dummy fcport structure, since functions preparing the
+	 * IOCB and mailbox command retrieves port specific information
+	 * from fcport structure. For Host based ELS commands there will be
+	 * no fcport structure allocated
+	 */
+	fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
+	if (!fcport)
+	{
+		rval = -ENOMEM;
+		goto  done_unmap_sg;
+	}
+
+	/* Initialize all required  fields of fcport */
+	fcport->vha = vha;
+	fcport->vp_idx = vha->vp_idx;
+	fcport->d_id.b.al_pa = bsg_job->request->rqst_data.h_ct.port_id[0];
+	fcport->d_id.b.area = bsg_job->request->rqst_data.h_ct.port_id[1];
+	fcport->d_id.b.domain = bsg_job->request->rqst_data.h_ct.port_id[2];
+	fcport->loop_id = loop_id;
+
+	/* Alloc SRB structure */
+	sp = qla2x00_get_ctx_bsg_sp(vha, fcport, sizeof(struct srb_bsg));
+	if (!sp) {
+		rval = -ENOMEM;
+		goto done_free_fcport;
+	}
+
+	ct = sp->ctx;
+	ct->ctx.type = SRB_CT_CMD;
+	ct->bsg_job = bsg_job;
+
+	DEBUG2(qla_printk(KERN_INFO, ha,
+	    "scsi(%ld:%x): bsg rqst type: %s els type: %x - loop-id=%x "
+	    "portid=%02x%02x%02x.\n", vha->host_no, sp->handle, type,
+	    (bsg_job->request->rqst_data.h_ct.preamble_word2 >> 16),
+	    fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
+	    fcport->d_id.b.al_pa));
+
+	rval = qla2x00_start_sp(sp);
+	if (rval != QLA_SUCCESS) {
+		kfree(sp->ctx);
+		mempool_free(sp, ha->srb_mempool);
+		rval = -EIO;
+		goto done_free_fcport;
+	}
+	return rval;
+
+done_free_fcport:
+	kfree(fcport);
+done_unmap_sg:
+	dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
+	    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
+	    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+done:
+	return rval;
+}
+
+static int
+qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
+{
+	struct Scsi_Host *host = bsg_job->shost;
+	scsi_qla_host_t *vha = shost_priv(host);
+	struct qla_hw_data *ha = vha->hw;
+	int rval;
+	uint8_t command_sent;
+	uint32_t vendor_cmd;
+	char *type;
+	struct msg_echo_lb elreq;
+	uint16_t response[MAILBOX_REGISTER_COUNT];
+	uint8_t* fw_sts_ptr;
+	uint8_t *req_data;
+	dma_addr_t req_data_dma;
+	uint32_t req_data_len;
+	uint8_t *rsp_data;
+	dma_addr_t rsp_data_dma;
+	uint32_t rsp_data_len;
+
+	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
+	    test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
+	    test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
+		rval = -EBUSY;
+		goto done;
+	}
+
+	if (!vha->flags.online) {
+		DEBUG2(qla_printk(KERN_WARNING, ha,
+		    "host not online\n"));
+		rval = -EIO;
+                goto done;
+	}
+
+        elreq.req_sg_cnt =
+	    dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
+	    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
+        if (!elreq.req_sg_cnt) {
+		rval = -ENOMEM;
+		goto done;
+	}
+        elreq.rsp_sg_cnt =
+	    dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
+	    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+        if (!elreq.rsp_sg_cnt) {
+		rval = -ENOMEM;
+                goto done;
+	}
+
+	if ((elreq.req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
+	    (elreq.rsp_sg_cnt != bsg_job->reply_payload.sg_cnt))
+	{
+		DEBUG2(printk(KERN_INFO
+		    "dma mapping resulted in different sg counts \
+		    [request_sg_cnt: %x dma_request_sg_cnt: %x\
+		    reply_sg_cnt: %x dma_reply_sg_cnt: %x]\n",
+		    bsg_job->request_payload.sg_cnt, elreq.req_sg_cnt,
+		    bsg_job->reply_payload.sg_cnt, elreq.rsp_sg_cnt));
+		rval = -EAGAIN;
+                goto done_unmap_sg;
+	}
+	req_data_len = rsp_data_len = bsg_job->request_payload.payload_len;
+	req_data = dma_alloc_coherent(&ha->pdev->dev, req_data_len,
+	    &req_data_dma, GFP_KERNEL);
+
+	rsp_data = dma_alloc_coherent(&ha->pdev->dev, rsp_data_len,
+	    &rsp_data_dma, GFP_KERNEL);
+
+	/* Copy the request buffer in req_data now */
+	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
+	    bsg_job->request_payload.sg_cnt, req_data,
+	    req_data_len);
+
+	elreq.send_dma = req_data_dma;
+	elreq.rcv_dma = rsp_data_dma;
+	elreq.transfer_size = req_data_len;
+
+	/* Vendor cmd : loopback or ECHO diagnostic
+	 * Options:
+	 * 	Loopback : Either internal or external loopback
+	 * 	ECHO: ECHO ELS or Vendor specific FC4  link data
+	 */
+	vendor_cmd = bsg_job->request->rqst_data.h_vendor.vendor_cmd[0];
+	elreq.options =
+	    *(((uint32_t *)bsg_job->request->rqst_data.h_vendor.vendor_cmd)
+	    + 1);
+
+	switch (bsg_job->request->rqst_data.h_vendor.vendor_cmd[0]) {
+	case QL_VND_LOOPBACK:
+		if (ha->current_topology != ISP_CFG_F) {
+			type = "FC_BSG_HST_VENDOR_LOOPBACK";
+
+			DEBUG2(qla_printk(KERN_INFO, ha,
+				"scsi(%ld) bsg rqst type: %s vendor rqst type: %x options: %x.\n",
+				vha->host_no, type, vendor_cmd, elreq.options));
+
+			command_sent = INT_DEF_LB_LOOPBACK_CMD;
+			rval = qla2x00_loopback_test(vha, &elreq, response);
+			if (IS_QLA81XX(ha)) {
+				if (response[0] == MBS_COMMAND_ERROR && response[1] == MBS_LB_RESET) {
+					DEBUG2(printk(KERN_ERR "%s(%ld): ABORTing "
+						"ISP\n", __func__, vha->host_no));
+					set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+					qla2xxx_wake_dpc(vha);
+				 }
+			}
+		} else {
+			type = "FC_BSG_HST_VENDOR_ECHO_DIAG";
+			DEBUG2(qla_printk(KERN_INFO, ha,
+				"scsi(%ld) bsg rqst type: %s vendor rqst type: %x options: %x.\n",
+				vha->host_no, type, vendor_cmd, elreq.options));
+
+			command_sent = INT_DEF_LB_ECHO_CMD;
+			rval = qla2x00_echo_test(vha, &elreq, response);
+		}
+		break;
+	case QLA84_RESET:
+		if (!IS_QLA84XX(vha->hw)) {
+			rval = -EINVAL;
+			DEBUG16(printk(
+				"%s(%ld): 8xxx exiting.\n",
+				__func__, vha->host_no));
+			return rval;
+		}
+		rval = qla84xx_reset(vha, &elreq, bsg_job);
+		break;
+	case QLA84_MGMT_CMD:
+		if (!IS_QLA84XX(vha->hw)) {
+			rval = -EINVAL;
+			DEBUG16(printk(
+				"%s(%ld): 8xxx exiting.\n",
+				__func__, vha->host_no));
+			return rval;
+		}
+		rval = qla84xx_mgmt_cmd(vha, &elreq, bsg_job);
+		break;
+	default:
+		rval = -ENOSYS;
+	}
+
+	if (rval != QLA_SUCCESS) {
+		DEBUG2(qla_printk(KERN_WARNING, ha,
+			"scsi(%ld) Vendor request %s failed\n", vha->host_no, type));
+		rval = 0;
+		bsg_job->reply->result = (DID_ERROR << 16);
+		bsg_job->reply->reply_payload_rcv_len = 0;
+		fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
+		memcpy( fw_sts_ptr, response, sizeof(response));
+		fw_sts_ptr += sizeof(response);
+                *fw_sts_ptr = command_sent;
+	} else {
+		DEBUG2(qla_printk(KERN_WARNING, ha,
+			"scsi(%ld) Vendor request %s completed\n", vha->host_no, type));
+		rval = bsg_job->reply->result = 0;
+		bsg_job->reply_len = sizeof(struct fc_bsg_reply) + sizeof(response) + sizeof(uint8_t);
+		bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
+		fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
+		memcpy(fw_sts_ptr, response, sizeof(response));
+		fw_sts_ptr += sizeof(response);
+		*fw_sts_ptr = command_sent;
+		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
+		bsg_job->reply_payload.sg_cnt, rsp_data,
+		rsp_data_len);
+	}
+	bsg_job->job_done(bsg_job);
+
+done_unmap_sg:
+
+	if(req_data)
+		dma_free_coherent(&ha->pdev->dev, req_data_len,
+			req_data, req_data_dma);
+	dma_unmap_sg(&ha->pdev->dev,
+	    bsg_job->request_payload.sg_list,
+	    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	dma_unmap_sg(&ha->pdev->dev,
+	    bsg_job->reply_payload.sg_list,
+	    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+
+done:
+        return rval;
+}
+
+static int
+qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
+{
+        int ret = -EINVAL;
+
+        switch (bsg_job->request->msgcode) {
+		case FC_BSG_RPT_ELS:
+		case FC_BSG_HST_ELS_NOLOGIN:
+			ret = qla2x00_process_els(bsg_job);
+			break;
+		case FC_BSG_HST_CT:
+			ret = qla2x00_process_ct(bsg_job);
+			break;
+		case FC_BSG_HST_VENDOR:
+			ret = qla2x00_process_vendor_specific(bsg_job);
+			break;
+		case FC_BSG_HST_ADD_RPORT:
+		case FC_BSG_HST_DEL_RPORT:
+		case FC_BSG_RPT_CT:
+		default:
+			DEBUG2(printk("qla2xxx: unsupported BSG request\n"));
+			break;
+        }
+	return ret;
+}
+
+static int
+qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
+{
+        scsi_qla_host_t *vha = shost_priv(bsg_job->shost);
+        struct qla_hw_data *ha = vha->hw;
+        srb_t *sp;
+        int cnt, que;
+        unsigned long flags;
+        struct req_que *req;
+	struct srb_bsg *sp_bsg;
+
+	/* find the bsg job from the active list of commands */
+        spin_lock_irqsave(&ha->hardware_lock, flags);
+	for (que = 0; que < ha->max_req_queues; que++) {
+		req = ha->req_q_map[que];
+		if (!req)
+			continue;
+
+		for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++ ) {
+			sp = req->outstanding_cmds[cnt];
+
+			if (sp) {
+				sp_bsg = (struct srb_bsg*)sp->ctx;
+
+				if (((sp_bsg->ctx.type == SRB_CT_CMD) ||
+				    (sp_bsg->ctx.type == SRB_ELS_CMD_RPT)
+				    || ( sp_bsg->ctx.type == SRB_ELS_CMD_HST)) &&
+				    (sp_bsg->bsg_job == bsg_job)) {
+					if (ha->isp_ops->abort_command(sp)) {
+						DEBUG2(qla_printk(KERN_INFO, ha,
+						"scsi(%ld): mbx abort_command failed\n", vha->host_no));
+						bsg_job->req->errors = bsg_job->reply->result = -EIO;
+					} else {
+						DEBUG2(qla_printk(KERN_INFO, ha,
+						"scsi(%ld): mbx abort_command success\n", vha->host_no));
+						bsg_job->req->errors = bsg_job->reply->result = 0;
+					}
+					goto done;
+				}
+			}
+		}
+	}
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	DEBUG2(qla_printk(KERN_INFO, ha,
+		"scsi(%ld) SRB not found to abort\n", vha->host_no));
+	bsg_job->req->errors = bsg_job->reply->result = -ENXIO;
+	return 0;
+
+done:
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	if (bsg_job->request->msgcode == FC_BSG_HST_CT)
+		kfree(sp->fcport);
+	kfree(sp->ctx);
+	mempool_free(sp, ha->srb_mempool);
+	return 0;
+}
+
 struct fc_function_template qla2xxx_transport_functions = {
 
 	.show_host_node_name = 1,
@@ -1838,6 +2444,8 @@ struct fc_function_template qla2xxx_tran
 	.vport_create = qla24xx_vport_create,
 	.vport_disable = qla24xx_vport_disable,
 	.vport_delete = qla24xx_vport_delete,
+	.bsg_request = qla24xx_bsg_request,
+	.bsg_timeout = qla24xx_bsg_timeout,
 };
 
 struct fc_function_template qla2xxx_transport_vport_functions = {
@@ -1878,6 +2486,8 @@ struct fc_function_template qla2xxx_tran
 	.dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk,
 	.terminate_rport_io = qla2x00_terminate_rport_io,
 	.get_fc_host_stats = qla2x00_get_fc_host_stats,
+	.bsg_request = qla24xx_bsg_request,
+	.bsg_timeout = qla24xx_bsg_timeout,
 };
 
 void
@@ -1906,3 +2516,125 @@ qla2x00_init_host_attr(scsi_qla_host_t *
 		speed = FC_PORTSPEED_1GBIT;
 	fc_host_supported_speeds(vha->host) = speed;
 }
+static int
+qla84xx_reset(scsi_qla_host_t *ha, struct msg_echo_lb *mreq, struct fc_bsg_job *bsg_job)
+{
+	int             ret = 0;
+	int             cmd;
+	uint16_t        cmd_status;
+
+	DEBUG16(printk("%s(%ld): entered.\n", __func__, ha->host_no));
+
+	cmd = (*((bsg_job->request->rqst_data.h_vendor.vendor_cmd) + 2))
+			== A84_RESET_FLAG_ENABLE_DIAG_FW ?
+				A84_ISSUE_RESET_DIAG_FW : A84_ISSUE_RESET_OP_FW;
+	ret = qla84xx_reset_chip(ha, cmd == A84_ISSUE_RESET_DIAG_FW,
+	&cmd_status);
+	return ret;
+}
+
+static int
+qla84xx_mgmt_cmd(scsi_qla_host_t *ha, struct msg_echo_lb *mreq, struct fc_bsg_job *bsg_job)
+{
+	struct access_chip_84xx *mn;
+	dma_addr_t mn_dma, mgmt_dma;
+	void *mgmt_b = NULL;
+	int ret = 0;
+	int rsp_hdr_len, len = 0;
+	struct qla84_msg_mgmt *ql84_mgmt;
+
+	ql84_mgmt = (struct qla84_msg_mgmt *) vmalloc(sizeof(struct qla84_msg_mgmt));
+	ql84_mgmt->cmd =
+		*((uint16_t *)(bsg_job->request->rqst_data.h_vendor.vendor_cmd + 2));
+	ql84_mgmt->mgmtp.u.mem.start_addr =
+		*((uint32_t *)(bsg_job->request->rqst_data.h_vendor.vendor_cmd + 3));
+	ql84_mgmt->len =
+		*((uint32_t *)(bsg_job->request->rqst_data.h_vendor.vendor_cmd + 4));
+	ql84_mgmt->mgmtp.u.config.id =
+		*((uint32_t *)(bsg_job->request->rqst_data.h_vendor.vendor_cmd + 5));
+	ql84_mgmt->mgmtp.u.config.param0 =
+		*((uint32_t *)(bsg_job->request->rqst_data.h_vendor.vendor_cmd + 6));
+	ql84_mgmt->mgmtp.u.config.param1 =
+		*((uint32_t *)(bsg_job->request->rqst_data.h_vendor.vendor_cmd + 7));
+	ql84_mgmt->mgmtp.u.info.type =
+		*((uint32_t *)(bsg_job->request->rqst_data.h_vendor.vendor_cmd + 8));
+	ql84_mgmt->mgmtp.u.info.context =
+		*((uint32_t *)(bsg_job->request->rqst_data.h_vendor.vendor_cmd + 9));
+
+	rsp_hdr_len = bsg_job->request_payload.payload_len;
+
+	mn = dma_pool_alloc(ha->hw->s_dma_pool, GFP_KERNEL, &mn_dma);
+	if (mn == NULL) {
+		DEBUG2(printk(KERN_ERR "%s: dma alloc for fw buffer "
+		"failed%lu\n", __func__, ha->host_no));
+		return -ENOMEM;
+	}
+
+	memset(mn, 0, sizeof (struct access_chip_84xx));
+
+	mn->entry_type = ACCESS_CHIP_IOCB_TYPE;
+	mn->entry_count = 1;
+
+	switch (ql84_mgmt->cmd) {
+	case QLA84_MGMT_READ_MEM:
+		mn->options = cpu_to_le16(ACO_DUMP_MEMORY);
+		mn->parameter1 = cpu_to_le32(ql84_mgmt->mgmtp.u.mem.start_addr);
+		break;
+	case QLA84_MGMT_WRITE_MEM:
+		mn->options = cpu_to_le16(ACO_LOAD_MEMORY);
+		mn->parameter1 = cpu_to_le32(ql84_mgmt->mgmtp.u.mem.start_addr);
+		break;
+	case QLA84_MGMT_CHNG_CONFIG:
+		mn->options = cpu_to_le16(ACO_CHANGE_CONFIG_PARAM);
+		mn->parameter1 = cpu_to_le32(ql84_mgmt->mgmtp.u.config.id);
+		mn->parameter2 = cpu_to_le32(ql84_mgmt->mgmtp.u.config.param0);
+		mn->parameter3 = cpu_to_le32(ql84_mgmt->mgmtp.u.config.param1);
+		break;
+	case QLA84_MGMT_GET_INFO:
+		mn->options = cpu_to_le16(ACO_REQUEST_INFO);
+		mn->parameter1 = cpu_to_le32(ql84_mgmt->mgmtp.u.info.type);
+		mn->parameter2 = cpu_to_le32(ql84_mgmt->mgmtp.u.info.context);
+		break;
+	default:
+		ret = -EIO;
+		goto exit_mgmt0;
+	}
+
+	if ((len == ql84_mgmt->len) &&
+		ql84_mgmt->cmd != QLA84_MGMT_CHNG_CONFIG) {
+		mgmt_b = dma_alloc_coherent(&ha->hw->pdev->dev, len,
+				&mgmt_dma, GFP_KERNEL);
+		if (mgmt_b == NULL) {
+			DEBUG2(printk(KERN_ERR "%s: dma alloc mgmt_b "
+			"failed%lu\n", __func__, ha->host_no));
+			ret = -ENOMEM;
+			goto exit_mgmt0;
+		}
+		mn->total_byte_cnt = cpu_to_le32(ql84_mgmt->len);
+		mn->dseg_count = cpu_to_le16(1);
+		mn->dseg_address[0] = cpu_to_le32(LSD(mgmt_dma));
+		mn->dseg_address[1] = cpu_to_le32(MSD(mgmt_dma));
+		mn->dseg_length = cpu_to_le32(len);
+
+		if (ql84_mgmt->cmd == QLA84_MGMT_WRITE_MEM) {
+			memcpy(mgmt_b, ql84_mgmt->payload, len);
+		}
+	}
+
+	ret = qla2x00_issue_iocb(ha, mn, mn_dma, 0);
+	if ((ret != QLA_SUCCESS) || (ql84_mgmt->cmd == QLA84_MGMT_WRITE_MEM)
+		|| (ql84_mgmt->cmd == QLA84_MGMT_CHNG_CONFIG)) {
+			if (ret != QLA_SUCCESS)
+				DEBUG2(printk(KERN_ERR "%s(%lu): failed\n",
+					__func__, ha->host_no));
+	} else if ((ql84_mgmt->cmd == QLA84_MGMT_READ_MEM) ||
+			(ql84_mgmt->cmd == QLA84_MGMT_GET_INFO)) {
+	}
+
+	if (mgmt_b)
+		dma_free_coherent(&ha->hw->pdev->dev, len, mgmt_b, mgmt_dma);
+
+exit_mgmt0:
+	dma_pool_free(ha->hw->s_dma_pool, mn, mn_dma);
+	return ret;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_def.h linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_def.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_def.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_def.h	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_transport_fc.h>
+#include <scsi/scsi_bsg_fc.h>
 
 #define QLA2XXX_DRIVER_NAME  "qla2xxx"
 
@@ -228,6 +229,27 @@ struct srb_logio {
 	uint16_t flags;
 };
 
+struct srb_bsg_ctx {
+#define SRB_ELS_CMD_RPT 3
+#define SRB_ELS_CMD_HST 4
+#define SRB_CT_CMD 5
+	uint16_t type;
+};
+
+struct srb_bsg {
+	struct srb_bsg_ctx ctx;
+	struct fc_bsg_job *bsg_job;
+};
+
+struct msg_echo_lb {
+	dma_addr_t send_dma;
+	dma_addr_t rcv_dma;
+	uint16_t req_sg_cnt;
+	uint16_t rsp_sg_cnt;
+	uint16_t options;
+	uint32_t transfer_size;
+};
+
 /*
  * ISP I/O Register Set structure definitions.
  */
@@ -522,6 +544,8 @@ typedef struct {
 #define MBA_DISCARD_RND_FRAME	0x8048	/* discard RND frame due to error. */
 #define MBA_REJECTED_FCP_CMD	0x8049	/* rejected FCP_CMD. */
 
+/* ISP mailbox loopback echo diagnostic error code */
+#define MBS_LB_RESET	0x17
 /*
  * Firmware options 1, 2, 3.
  */
@@ -2230,6 +2254,13 @@ struct req_que {
 	int max_q_depth;
 };
 
+/* Place holder for FW buffer parameters */
+struct qlfc_fw {
+	void *fw_buf;
+	dma_addr_t fw_dma;
+	uint32_t len;
+};
+
 /*
  * Qlogic host adapter specific data structure.
 */
@@ -2594,6 +2625,7 @@ struct qla_hw_data {
 	struct qla_statistics qla_stats;
 	struct isp_operations *isp_ops;
 	struct workqueue_struct *wq;
+	struct qlfc_fw fw_buf;
 };
 
 /*
@@ -2766,4 +2798,127 @@ typedef struct scsi_qla_host {
 
 #define CMD_SP(Cmnd)		((Cmnd)->SCp.ptr)
 
+/*
+ * BSG Vendor specific commands
+ */
+
+#define QL_VND_LOOPBACK		0x01
+#define QLA84_RESET		0x02
+#define QLA84_UPDATE_FW		0x03
+#define QLA84_MGMT_CMD		0x04
+
+/* BSG definations for interpreting CommandSent field */
+#define INT_DEF_LB_LOOPBACK_CMD         0
+#define INT_DEF_LB_ECHO_CMD             1
+
+/* BSG Vendor specific definations */
+typedef struct _A84_RESET {
+	uint16_t Flags;
+	uint16_t Reserved;
+#define A84_RESET_FLAG_ENABLE_DIAG_FW   1
+} __attribute__((packed)) A84_RESET, *PA84_RESET;
+
+#define A84_ISSUE_WRITE_TYPE_CMD        0
+#define A84_ISSUE_READ_TYPE_CMD         1
+#define A84_CLEANUP_CMD                 2
+#define A84_ISSUE_RESET_OP_FW           3
+#define A84_ISSUE_RESET_DIAG_FW         4
+#define A84_ISSUE_UPDATE_OPFW_CMD       5
+#define A84_ISSUE_UPDATE_DIAGFW_CMD     6
+
+struct qla84_mgmt_param {
+	union {
+		struct {
+			uint32_t start_addr;
+		} mem; /* for QLA84_MGMT_READ/WRITE_MEM */
+		struct {
+			uint32_t id;
+#define QLA84_MGMT_CONFIG_ID_UIF        1
+#define QLA84_MGMT_CONFIG_ID_FCOE_COS   2
+#define QLA84_MGMT_CONFIG_ID_PAUSE      3
+#define QLA84_MGMT_CONFIG_ID_TIMEOUTS   4
+
+		uint32_t param0;
+		uint32_t param1;
+	} config; /* for QLA84_MGMT_CHNG_CONFIG */
+
+	struct {
+		uint32_t type;
+#define QLA84_MGMT_INFO_CONFIG_LOG_DATA         1 /* Get Config Log Data */
+#define QLA84_MGMT_INFO_LOG_DATA                2 /* Get Log Data */
+#define QLA84_MGMT_INFO_PORT_STAT               3 /* Get Port Statistics */
+#define QLA84_MGMT_INFO_LIF_STAT                4 /* Get LIF Statistics  */
+#define QLA84_MGMT_INFO_ASIC_STAT               5 /* Get ASIC Statistics */
+#define QLA84_MGMT_INFO_CONFIG_PARAMS           6 /* Get Config Parameters */
+#define QLA84_MGMT_INFO_PANIC_LOG               7 /* Get Panic Log */
+
+		uint32_t context;
+/*
+* context definitions for QLA84_MGMT_INFO_CONFIG_LOG_DATA
+*/
+#define IC_LOG_DATA_LOG_ID_DEBUG_LOG                    0
+#define IC_LOG_DATA_LOG_ID_LEARN_LOG                    1
+#define IC_LOG_DATA_LOG_ID_FC_ACL_INGRESS_LOG           2
+#define IC_LOG_DATA_LOG_ID_FC_ACL_EGRESS_LOG            3
+#define IC_LOG_DATA_LOG_ID_ETHERNET_ACL_INGRESS_LOG     4
+#define IC_LOG_DATA_LOG_ID_ETHERNET_ACL_EGRESS_LOG      5
+#define IC_LOG_DATA_LOG_ID_MESSAGE_TRANSMIT_LOG         6
+#define IC_LOG_DATA_LOG_ID_MESSAGE_RECEIVE_LOG          7
+#define IC_LOG_DATA_LOG_ID_LINK_EVENT_LOG               8
+#define IC_LOG_DATA_LOG_ID_DCX_LOG                      9
+
+/*
+* context definitions for QLA84_MGMT_INFO_PORT_STAT
+*/
+#define IC_PORT_STATISTICS_PORT_NUMBER_ETHERNET_PORT0   0
+#define IC_PORT_STATISTICS_PORT_NUMBER_ETHERNET_PORT1   1
+#define IC_PORT_STATISTICS_PORT_NUMBER_NSL_PORT0        2
+#define IC_PORT_STATISTICS_PORT_NUMBER_NSL_PORT1        3
+#define IC_PORT_STATISTICS_PORT_NUMBER_FC_PORT0         4
+#define IC_PORT_STATISTICS_PORT_NUMBER_FC_PORT1         5
+
+
+/*
+* context definitions for QLA84_MGMT_INFO_LIF_STAT
+*/
+#define IC_LIF_STATISTICS_LIF_NUMBER_ETHERNET_PORT0     0
+#define IC_LIF_STATISTICS_LIF_NUMBER_ETHERNET_PORT1     1
+#define IC_LIF_STATISTICS_LIF_NUMBER_FC_PORT0           2
+#define IC_LIF_STATISTICS_LIF_NUMBER_FC_PORT1           3
+#define IC_LIF_STATISTICS_LIF_NUMBER_CPU                6
+
+		} info; /* for QLA84_MGMT_GET_INFO */
+	} u;
+};
+
+struct qla84_msg_mgmt {
+	uint16_t cmd;
+#define QLA84_MGMT_READ_MEM     0x00
+#define QLA84_MGMT_WRITE_MEM    0x01
+#define QLA84_MGMT_CHNG_CONFIG  0x02
+#define QLA84_MGMT_GET_INFO     0x03
+	uint16_t rsrvd;
+	struct qla84_mgmt_param mgmtp;/* parameters for cmd */
+	uint32_t len; /* bytes in payload following this struct */
+	uint8_t payload[0]; /* payload for cmd */
+};
+
+struct msg_update_fw {
+	/*
+	* diag_fw = 0  operational fw
+	*      otherwise diagnostic fw
+	* offset, len, fw_len are present to overcome the current limitation
+	* of 128Kb xfer size. The fw is sent in smaller chunks. Each chunk
+	* specifies the byte "offset" where it fits in the fw buffer. The
+	* number of bytes in each chunk is specified in "len". "fw_len"
+	* is the total size of fw. The first chunk should start at offset = 0.
+	* When offset+len == fw_len, the fw is written to the HBA.
+	*/
+	uint32_t diag_fw;
+	uint32_t offset;/* start offset */
+	uint32_t len;   /* num bytes in cur xfer */
+	uint32_t fw_len; /* size of fw in bytes */
+	uint8_t fw_bytes[0];
+};
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_fw.h linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_fw.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_fw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_fw.h	2010-05-16 17:17:36.000000000 -0400
@@ -627,6 +627,39 @@ struct els_entry_24xx {
 	uint32_t rx_len;		/* Data segment 1 length. */
 };
 
+struct els_sts_entry_24xx {
+	uint8_t entry_type;		/* Entry type. */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t sys_define;		/* System Defined. */
+	uint8_t entry_status;		/* Entry Status. */
+
+	uint32_t handle;		/* System handle. */
+
+	uint16_t comp_status;
+
+	uint16_t nport_handle;		/* N_PORT handle. */
+
+	uint16_t reserved_1;
+
+	uint8_t vp_index;
+	uint8_t sof_type;
+
+	uint32_t rx_xchg_address;	/* Receive exchange address. */
+	uint16_t reserved_2;
+
+	uint8_t opcode;
+	uint8_t reserved_3;
+
+	uint8_t port_id[3];
+	uint8_t reserved_4;
+
+	uint16_t reserved_5;
+
+	uint16_t control_flags;		/* Control flags. */
+	uint32_t total_byte_count;
+	uint32_t error_subcode_1;
+	uint32_t error_subcode_2;
+};
 /*
  * ISP queue - Mailbox Command entry structure definition.
  */
@@ -1559,10 +1592,22 @@ struct nvram_81xx {
 
 	/* Offset 384. */
 	uint8_t reserved_21[16];
-	uint16_t reserved_22[8];
+	uint16_t reserved_22[3];
+
+	/*
+	 * BIT 0 = Extended BB credits for LR
+	 * BIT 1 = Virtual Fabric Enable
+	 * BIT 2 = Enhanced Features Unused
+	 * BIT 3-7 = Enhanced Features Reserved
+	 */
+	/* Enhanced Features */
+	uint8_t enhanced_features;
+
+	uint8_t reserved_23;
+	uint16_t reserved_24[4];
 
 	/* Offset 416. */
-	uint16_t reserved_23[32];
+	uint16_t reserved_25[32];
 
 	/* Offset 480. */
 	uint8_t model_name[16];
@@ -1570,7 +1615,7 @@ struct nvram_81xx {
 	/* Offset 496. */
 	uint16_t feature_mask_l;
 	uint16_t feature_mask_h;
-	uint16_t reserved_24[2];
+	uint16_t reserved_26[2];
 
 	uint16_t subsystem_vendor_id;
 	uint16_t subsystem_device_id;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_gbl.h linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_gbl.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_gbl.h	2013-05-03 12:12:46.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_gbl.h	2013-05-03 09:52:18.000000000 -0400
@@ -60,6 +60,8 @@ extern int qla2x00_async_login_done(stru
 extern int qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *,
     uint16_t *);
 
+extern fc_port_t *
+qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t );
 /*
  * Global Data in qla_os.c source file.
  */
@@ -76,6 +78,7 @@ extern int ql2xiidmaenable;
 extern int ql2xmaxqueues;
 extern int ql2xmultique_tag;
 extern int ql2xfwloadbin;
+extern int ql2xetsenable;
 
 extern int qla2x00_loop_reset(scsi_qla_host_t *);
 extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
@@ -94,7 +97,6 @@ extern int qla2x00_post_uevent_work(stru
 
 extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
 
-extern void qla2x00_abort_fcport_cmds(fc_port_t *);
 extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *,
 	struct qla_hw_data *);
 extern void qla2x00_free_host(struct scsi_qla_host *);
@@ -154,6 +156,7 @@ int qla2x00_marker(struct scsi_qla_host
 int __qla2x00_marker(struct scsi_qla_host *, struct req_que *, struct rsp_que *,
 						uint16_t, uint16_t, uint8_t);
 extern int qla2x00_start_sp(srb_t *);
+extern void qla2x00_ctx_sp_free(srb_t *);
 
 /*
  * Global Function Prototypes in qla_mbx.c source file.
@@ -426,6 +429,8 @@ extern void qla2x00_free_sysfs_attr(scsi
 extern void qla2x00_init_host_attr(scsi_qla_host_t *);
 extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);
 extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *);
+extern int qla2x00_loopback_test(scsi_qla_host_t *, struct msg_echo_lb *, uint16_t *);
+extern int qla2x00_echo_test(scsi_qla_host_t *, struct msg_echo_lb *, uint16_t *);
 
 /*
  * Global Function Prototypes in qla_dfs.c source file.
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_init.c linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_init.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_init.c	2013-05-03 12:12:46.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_init.c	2013-05-03 09:52:18.000000000 -0400
@@ -8,6 +8,7 @@
 #include "qla_gbl.h"
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "qla_devtbl.h"
@@ -62,7 +63,7 @@ qla2x00_ctx_sp_timeout(unsigned long __d
 	ctx->free(sp);
 }
 
-static void
+void
 qla2x00_ctx_sp_free(srb_t *sp)
 {
 	struct srb_ctx *ctx = sp->ctx;
@@ -338,6 +339,16 @@ qla2x00_initialize_adapter(scsi_qla_host
 	rval = qla2x00_init_rings(vha);
 	ha->flags.chip_reset_done = 1;
 
+	if (rval == QLA_SUCCESS && IS_QLA84XX(ha)) {
+	/* Issue verify 84xx FW IOCB to complete 84xx initialization */
+		rval = qla84xx_init_chip(vha);
+		if (rval != QLA_SUCCESS) {
+			qla_printk(KERN_ERR, ha,
+				"Unable to initialize ISP84XX.\n");
+		qla84xx_put_chip(vha);
+		}
+	}
+
 	return (rval);
 }
 
@@ -2216,7 +2227,7 @@ qla2x00_rport_del(void *data)
  *
  * Returns a pointer to the allocated fcport, or NULL, if none available.
  */
-static fc_port_t *
+fc_port_t *
 qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
 {
 	fc_port_t *fcport;
@@ -2900,8 +2911,13 @@ qla2x00_find_all_fabric_devs(scsi_qla_ho
 		if (qla2x00_is_reserved_id(vha, loop_id))
 			continue;
 
-		if (atomic_read(&vha->loop_down_timer) || LOOP_TRANSITION(vha))
+		if (atomic_read(&vha->loop_down_timer) ||
+		    LOOP_TRANSITION(vha)) {
+			atomic_set(&vha->loop_down_timer, 0);
+			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+			set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
 			break;
+		}
 
 		if (swl != NULL) {
 			if (last_dev) {
@@ -4877,6 +4893,15 @@ qla81xx_nvram_config(scsi_qla_host_t *vh
 }
 
 void
-qla81xx_update_fw_options(scsi_qla_host_t *ha)
+qla81xx_update_fw_options(scsi_qla_host_t *vha)
 {
+	struct qla_hw_data *ha = vha->hw;
+
+	if (!ql2xetsenable)
+		return;
+
+	/* Enable ETS Burst. */
+	memset(ha->fw_options, 0, sizeof(ha->fw_options));
+	ha->fw_options[2] |= BIT_9;
+	qla2x00_set_fw_options(vha, ha->fw_options);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_iocb.c linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_iocb.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_iocb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_iocb.c	2010-05-16 17:17:36.000000000 -0400
@@ -1025,6 +1025,119 @@ qla2x00_logout_iocb(srb_t *sp, struct mb
 	/* Implicit: mbx->mbx10 = 0. */
 }
 
+static void
+qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
+{
+	struct fc_bsg_job *bsg_job = ((struct srb_bsg*)sp->ctx)->bsg_job;
+
+        els_iocb->entry_type = ELS_IOCB_TYPE;
+        els_iocb->entry_count = 1;
+        els_iocb->sys_define = 0;
+        els_iocb->entry_status = 0;
+        els_iocb->handle = sp->handle;
+        els_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
+        els_iocb->tx_dsd_count = __constant_cpu_to_le16(bsg_job->request_payload.sg_cnt);
+        els_iocb->vp_index = sp->fcport->vp_idx;
+        els_iocb->sof_type = EST_SOFI3;
+        els_iocb->rx_dsd_count = __constant_cpu_to_le16(bsg_job->reply_payload.sg_cnt);
+
+        els_iocb->opcode =(((struct srb_bsg*)sp->ctx)->ctx.type == SRB_ELS_CMD_RPT) ?
+	    bsg_job->request->rqst_data.r_els.els_code : bsg_job->request->rqst_data.h_els.command_code;
+        els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
+        els_iocb->port_id[1] = sp->fcport->d_id.b.area;
+        els_iocb->port_id[2] = sp->fcport->d_id.b.domain;
+        els_iocb->control_flags = 0;
+        els_iocb->rx_byte_count =
+            cpu_to_le32(bsg_job->reply_payload.payload_len);
+        els_iocb->tx_byte_count =
+            cpu_to_le32(bsg_job->request_payload.payload_len);
+
+        els_iocb->tx_address[0] = cpu_to_le32(LSD(sg_dma_address
+            (bsg_job->request_payload.sg_list)));
+        els_iocb->tx_address[1] = cpu_to_le32(MSD(sg_dma_address
+            (bsg_job->request_payload.sg_list)));
+        els_iocb->tx_len = cpu_to_le32(sg_dma_len
+            (bsg_job->request_payload.sg_list));
+
+        els_iocb->rx_address[0] = cpu_to_le32(LSD(sg_dma_address
+            (bsg_job->reply_payload.sg_list)));
+        els_iocb->rx_address[1] = cpu_to_le32(MSD(sg_dma_address
+            (bsg_job->reply_payload.sg_list)));
+        els_iocb->rx_len = cpu_to_le32(sg_dma_len
+            (bsg_job->reply_payload.sg_list));
+}
+
+static void
+qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb)
+{
+	uint16_t        avail_dsds;
+	uint32_t        *cur_dsd;
+	struct scatterlist *sg;
+	int index;
+	uint16_t tot_dsds;
+        scsi_qla_host_t *vha = sp->fcport->vha;
+	struct fc_bsg_job *bsg_job = ((struct srb_bsg*)sp->ctx)->bsg_job;
+	int loop_iterartion = 0;
+	int cont_iocb_prsnt = 0;
+	int entry_count = 1;
+
+	ct_iocb->entry_type = CT_IOCB_TYPE;
+        ct_iocb->entry_status = 0;
+        ct_iocb->sys_define = 0;
+        ct_iocb->handle = sp->handle;
+
+	ct_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
+	ct_iocb->vp_index = sp->fcport->vp_idx;
+        ct_iocb->comp_status = __constant_cpu_to_le16(0);
+
+	ct_iocb->cmd_dsd_count =
+            __constant_cpu_to_le16(bsg_job->request_payload.sg_cnt);
+        ct_iocb->timeout = 0;
+        ct_iocb->rsp_dsd_count =
+            __constant_cpu_to_le16(bsg_job->reply_payload.sg_cnt);
+        ct_iocb->rsp_byte_count =
+            cpu_to_le32(bsg_job->reply_payload.payload_len);
+        ct_iocb->cmd_byte_count =
+            cpu_to_le32(bsg_job->request_payload.payload_len);
+        ct_iocb->dseg_0_address[0] = cpu_to_le32(LSD(sg_dma_address
+            (bsg_job->request_payload.sg_list)));
+        ct_iocb->dseg_0_address[1] = cpu_to_le32(MSD(sg_dma_address
+           (bsg_job->request_payload.sg_list)));
+        ct_iocb->dseg_0_len = cpu_to_le32(sg_dma_len
+            (bsg_job->request_payload.sg_list));
+
+	avail_dsds = 1;
+	cur_dsd = (uint32_t *)ct_iocb->dseg_1_address;
+	index = 0;
+	tot_dsds = bsg_job->reply_payload.sg_cnt;
+
+	for_each_sg(bsg_job->reply_payload.sg_list, sg, tot_dsds, index) {
+		dma_addr_t       sle_dma;
+		cont_a64_entry_t *cont_pkt;
+
+		/* Allocate additional continuation packets? */
+		if (avail_dsds == 0) {
+			/*
+			* Five DSDs are available in the Cont.
+			* Type 1 IOCB.
+			       */
+			cont_pkt = qla2x00_prep_cont_type1_iocb(vha);
+			cur_dsd = (uint32_t *) cont_pkt->dseg_0_address;
+			avail_dsds = 5;
+			cont_iocb_prsnt = 1;
+			entry_count++;
+		}
+
+		sle_dma = sg_dma_address(sg);
+		*cur_dsd++   = cpu_to_le32(LSD(sle_dma));
+		*cur_dsd++   = cpu_to_le32(MSD(sle_dma));
+		*cur_dsd++   = cpu_to_le32(sg_dma_len(sg));
+		loop_iterartion++;
+		avail_dsds--;
+	}
+        ct_iocb->entry_count = entry_count;
+}
+
 int
 qla2x00_start_sp(srb_t *sp)
 {
@@ -1052,6 +1165,13 @@ qla2x00_start_sp(srb_t *sp)
 		    qla24xx_logout_iocb(sp, pkt):
 		    qla2x00_logout_iocb(sp, pkt);
 		break;
+	case SRB_ELS_CMD_RPT:
+	case SRB_ELS_CMD_HST:
+		qla24xx_els_iocb(sp, pkt);
+		break;
+	case SRB_CT_CMD:
+		qla24xx_ct_iocb(sp, pkt);
+		break;
 	default:
 		break;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_isr.c linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_isr.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_isr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_isr.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,7 +7,9 @@
 #include "qla_def.h"
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <scsi/scsi_tcq.h>
+#include <scsi/scsi_bsg_fc.h>
 
 static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
 static void qla2x00_process_completed_request(struct scsi_qla_host *,
@@ -619,11 +621,10 @@ skip_rio:
 		 *           vp_idx does not match
 		 *       Event is not global, vp_idx does not match
 		 */
-		if ((mb[1] == 0xffff && (mb[3] & 0xff) != 0xff)
-			|| (mb[1] != 0xffff)) {
-			if (vha->vp_idx != (mb[3] & 0xff))
-				break;
-		}
+		if (IS_QLA2XXX_MIDTYPE(ha) &&
+		    ((mb[1] == 0xffff && (mb[3] & 0xff) != 0xff) ||
+			(mb[1] != 0xffff)) && vha->vp_idx != (mb[3] & 0xff))
+			break;
 
 		/* Global event -- port logout or port unavailable. */
 		if (mb[1] == 0xffff && mb[2] == 0x7) {
@@ -881,7 +882,9 @@ qla2x00_get_sp_from_handle(scsi_qla_host
 		    index);
 		return NULL;
 	}
+
 	req->outstanding_cmds[index] = NULL;
+
 done:
 	return sp;
 }
@@ -982,6 +985,100 @@ done_post_logio_done_work:
 }
 
 static void
+qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
+    struct sts_entry_24xx *pkt, int iocb_type)
+{
+	const char func[] = "ELS_CT_IOCB";
+	const char *type;
+	struct qla_hw_data *ha = vha->hw;
+	srb_t *sp;
+	struct srb_bsg *sp_bsg;
+	struct fc_bsg_job *bsg_job;
+	uint16_t comp_status;
+	uint32_t fw_status[3];
+	uint8_t* fw_sts_ptr;
+
+	sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
+	if (!sp)
+		return;
+	sp_bsg = (struct srb_bsg*)sp->ctx;
+	bsg_job = sp_bsg->bsg_job;
+
+	type = NULL;
+	switch (sp_bsg->ctx.type) {
+	case SRB_ELS_CMD_RPT:
+	case SRB_ELS_CMD_HST:
+		type = "els";
+		break;
+	case SRB_CT_CMD:
+		type = "ct pass-through";
+		break;
+	default:
+		qla_printk(KERN_WARNING, ha,
+		    "%s: Unrecognized SRB: (%p) type=%d.\n", func, sp,
+		    sp_bsg->ctx.type);
+		return;
+	}
+
+	comp_status = fw_status[0] = le16_to_cpu(pkt->comp_status);
+	fw_status[1] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_1);
+	fw_status[2] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_2);
+
+	/* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT
+	 * fc payload  to the caller
+	 */
+	bsg_job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
+	bsg_job->reply_len = sizeof(struct fc_bsg_reply) + sizeof(fw_status);
+
+	if (comp_status != CS_COMPLETE) {
+		if (comp_status == CS_DATA_UNDERRUN) {
+			bsg_job->reply->result = DID_OK << 16;
+			bsg_job->reply->reply_payload_rcv_len =
+				le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->total_byte_count);
+
+			DEBUG2(qla_printk(KERN_WARNING, ha,
+			    "scsi(%ld:0x%x): ELS-CT pass-through-%s error comp_status-status=0x%x "
+			    "error subcode 1=0x%x error subcode 2=0x%x total_byte = 0x%x.\n",
+				vha->host_no, sp->handle, type, comp_status, fw_status[1], fw_status[2],
+				le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->total_byte_count)));
+			fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
+			memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
+		}
+		else {
+			DEBUG2(qla_printk(KERN_WARNING, ha,
+			    "scsi(%ld:0x%x): ELS-CT pass-through-%s error comp_status-status=0x%x "
+			    "error subcode 1=0x%x error subcode 2=0x%x.\n",
+				vha->host_no, sp->handle, type, comp_status,
+				le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_1),
+				le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_2)));
+			bsg_job->reply->result = DID_ERROR << 16;
+			bsg_job->reply->reply_payload_rcv_len = 0;
+			fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
+			memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
+		}
+		DEBUG2(qla2x00_dump_buffer((uint8_t *)pkt, sizeof(*pkt)));
+	}
+	else {
+		bsg_job->reply->result =  DID_OK << 16;;
+		bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
+		bsg_job->reply_len = 0;
+	}
+
+	dma_unmap_sg(&ha->pdev->dev,
+	    bsg_job->request_payload.sg_list,
+	    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	dma_unmap_sg(&ha->pdev->dev,
+	    bsg_job->reply_payload.sg_list,
+	    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+	if ((sp_bsg->ctx.type == SRB_ELS_CMD_HST) ||
+	    (sp_bsg->ctx.type == SRB_CT_CMD))
+		kfree(sp->fcport);
+	kfree(sp->ctx);
+	mempool_free(sp, ha->srb_mempool);
+	bsg_job->job_done(bsg_job);
+}
+
+static void
 qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
     struct logio_entry_24xx *logio)
 {
@@ -1749,6 +1846,13 @@ void qla24xx_process_response_queue(stru
 			qla24xx_logio_entry(vha, rsp->req,
 			    (struct logio_entry_24xx *)pkt);
 			break;
+                case CT_IOCB_TYPE:
+			qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE);
+			clear_bit(MBX_INTERRUPT, &vha->hw->mbx_cmd_flags);
+			break;
+                case ELS_IOCB_TYPE:
+			qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE);
+			break;
 		default:
 			/* Type Not Supported. */
 			DEBUG4(printk(KERN_WARNING
@@ -2049,7 +2153,6 @@ qla24xx_msix_default(int irq, void *dev_
 		set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
 		complete(&ha->mbx_intr_comp);
 	}
-
 	return IRQ_HANDLED;
 }
 
@@ -2169,30 +2272,28 @@ qla2x00_request_irqs(struct qla_hw_data
 
 	/* If possible, enable MSI-X. */
 	if (!IS_QLA2432(ha) && !IS_QLA2532(ha) &&
-	    !IS_QLA8432(ha) && !IS_QLA8001(ha))
-		goto skip_msix;
+		!IS_QLA8432(ha) && !IS_QLA8001(ha))
+		goto skip_msi;
+
+	if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
+		(ha->pdev->subsystem_device == 0x7040 ||
+		ha->pdev->subsystem_device == 0x7041 ||
+		ha->pdev->subsystem_device == 0x1705)) {
+		DEBUG2(qla_printk(KERN_WARNING, ha,
+			"MSI-X: Unsupported ISP2432 SSVID/SSDID (0x%X,0x%X).\n",
+			ha->pdev->subsystem_vendor,
+			ha->pdev->subsystem_device));
+		goto skip_msi;
+	}
 
 	if (IS_QLA2432(ha) && (ha->pdev->revision < QLA_MSIX_CHIP_REV_24XX ||
 		!QLA_MSIX_FW_MODE_1(ha->fw_attributes))) {
 		DEBUG2(qla_printk(KERN_WARNING, ha,
 		"MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n",
 			ha->pdev->revision, ha->fw_attributes));
-
 		goto skip_msix;
 	}
 
-	if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
-	    (ha->pdev->subsystem_device == 0x7040 ||
-		ha->pdev->subsystem_device == 0x7041 ||
-		ha->pdev->subsystem_device == 0x1705)) {
-		DEBUG2(qla_printk(KERN_WARNING, ha,
-		    "MSI-X: Unsupported ISP2432 SSVID/SSDID (0x%X, 0x%X).\n",
-		    ha->pdev->subsystem_vendor,
-		    ha->pdev->subsystem_device));
-
-		goto skip_msi;
-	}
-
 	ret = qla24xx_enable_msix(ha, rsp);
 	if (!ret) {
 		DEBUG2(qla_printk(KERN_INFO, ha,
@@ -2255,10 +2356,11 @@ qla2x00_free_irqs(scsi_qla_host_t *vha)
 
 	if (ha->flags.msix_enabled)
 		qla24xx_disable_msix(ha);
-	else if (ha->flags.inta_enabled) {
+	else if (ha->flags.msi_enabled) {
 		free_irq(ha->pdev->irq, rsp);
 		pci_disable_msi(ha->pdev);
-	}
+	} else
+		free_irq(ha->pdev->irq, rsp);
 }
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_mbx.c linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_mbx.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_mbx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_mbx.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
 #include "qla_def.h"
 
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 
 /*
@@ -339,6 +340,7 @@ qla2x00_load_ram(scsi_qla_host_t *vha, d
 	return rval;
 }
 
+#define	EXTENDED_BB_CREDITS	BIT_0
 /*
  * qla2x00_execute_fw
  *     Start adapter firmware.
@@ -371,7 +373,12 @@ qla2x00_execute_fw(scsi_qla_host_t *vha,
 		mcp->mb[1] = MSW(risc_addr);
 		mcp->mb[2] = LSW(risc_addr);
 		mcp->mb[3] = 0;
-		mcp->mb[4] = 0;
+		if (IS_QLA81XX(ha)) {
+			struct nvram_81xx *nv = ha->nvram;
+			mcp->mb[4] = (nv->enhanced_features &
+			    EXTENDED_BB_CREDITS);
+		} else
+			mcp->mb[4] = 0;
 		mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
 		mcp->in_mb |= MBX_1;
 	} else {
@@ -3634,6 +3641,157 @@ qla2x00_read_ram_word(scsi_qla_host_t *v
 
 	return rval;
 }
+
+int
+qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t *mresp)
+{
+	int rval;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+	uint32_t iter_cnt = 0x1;
+
+	DEBUG11(printk("scsi(%ld): entered.\n", vha->host_no));
+
+	memset(mcp->mb, 0 , sizeof(mcp->mb));
+	mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
+	mcp->mb[1] = mreq->options | BIT_6;	// BIT_6 specifies 64 bit addressing
+
+	/* transfer count */
+	mcp->mb[10] = LSW(mreq->transfer_size);
+	mcp->mb[11] = MSW(mreq->transfer_size);
+
+	/* send data address */
+	mcp->mb[14] = LSW(mreq->send_dma);
+	mcp->mb[15] = MSW(mreq->send_dma);
+	mcp->mb[20] = LSW(MSD(mreq->send_dma));
+	mcp->mb[21] = MSW(MSD(mreq->send_dma));
+
+	/* recieve data address */
+	mcp->mb[16] = LSW(mreq->rcv_dma);
+	mcp->mb[17] = MSW(mreq->rcv_dma);
+	mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
+	mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
+
+	/* Iteration count */
+	mcp->mb[18] = LSW(iter_cnt);
+	mcp->mb[19] = MSW(iter_cnt);
+
+	mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
+	    MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
+	if (IS_QLA81XX(vha->hw))
+		mcp->out_mb |= MBX_2;
+	mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
+
+	mcp->buf_size = mreq->transfer_size;
+	mcp->tov = MBX_TOV_SECONDS;
+	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
+
+	rval = qla2x00_mailbox_command(vha, mcp);
+
+	if (rval != QLA_SUCCESS) {
+		DEBUG2(printk(KERN_WARNING
+		    "(%ld): failed=%x mb[0]=0x%x "
+			"mb[1]=0x%x mb[2]=0x%x mb[3]=0x%x mb[18]=0x%x mb[19]=0x%x. \n", vha->host_no, rval,
+			mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[18], mcp->mb[19]));
+	} else {
+		DEBUG2(printk(KERN_WARNING
+		    "scsi(%ld): done.\n", vha->host_no));
+	}
+
+	/* Copy mailbox information */
+	memcpy( mresp, mcp->mb, 64);
+	mresp[3] = mcp->mb[18];
+	mresp[4] = mcp->mb[19];
+	return rval;
+}
+
+int
+qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t *mresp)
+{
+	int rval;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+	struct qla_hw_data *ha = vha->hw;
+
+	DEBUG11(printk("scsi(%ld): entered.\n", vha->host_no));
+
+	memset(mcp->mb, 0 , sizeof(mcp->mb));
+	mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
+	mcp->mb[1] = mreq->options | BIT_6;	/* BIT_6 specifies 64bit address */
+	if (IS_QLA81XX(ha))
+		mcp->mb[1] |= BIT_15;
+	mcp->mb[2] = IS_QLA81XX(ha) ? vha->fcoe_fcf_idx : 0;
+	mcp->mb[16] = LSW(mreq->rcv_dma);
+	mcp->mb[17] = MSW(mreq->rcv_dma);
+	mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
+	mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
+
+	mcp->mb[10] = LSW(mreq->transfer_size);
+
+	mcp->mb[14] = LSW(mreq->send_dma);
+	mcp->mb[15] = MSW(mreq->send_dma);
+	mcp->mb[20] = LSW(MSD(mreq->send_dma));
+	mcp->mb[21] = MSW(MSD(mreq->send_dma));
+
+	mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
+	    MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
+	if (IS_QLA81XX(ha))
+		mcp->out_mb |= MBX_2;
+
+	mcp->in_mb = MBX_0;
+	if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha))
+		mcp->in_mb |= MBX_1;
+	if (IS_QLA81XX(ha))
+		mcp->in_mb |= MBX_3;
+
+	mcp->tov = MBX_TOV_SECONDS;
+	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
+	mcp->buf_size = mreq->transfer_size;
+
+	rval = qla2x00_mailbox_command(vha, mcp);
+
+	if (rval != QLA_SUCCESS) {
+		DEBUG2(printk(KERN_WARNING
+		    "(%ld): failed=%x mb[0]=0x%x mb[1]=0x%x.\n",
+		    vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
+	} else {
+		DEBUG2(printk(KERN_WARNING
+		    "scsi(%ld): done.\n", vha->host_no));
+	}
+
+	/* Copy mailbox information */
+	memcpy( mresp, mcp->mb, 32);
+	return rval;
+}
+int
+qla84xx_reset_chip(scsi_qla_host_t *ha, uint16_t enable_diagnostic,
+    uint16_t *cmd_status)
+{
+	int rval;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+
+	DEBUG16(printk("%s(%ld): enable_diag=%d entered.\n", __func__,
+		ha->host_no, enable_diagnostic));
+
+	mcp->mb[0] = MBC_ISP84XX_RESET;
+	mcp->mb[1] = enable_diagnostic;
+	mcp->out_mb = MBX_1|MBX_0;
+	mcp->in_mb = MBX_1|MBX_0;
+	mcp->tov = MBX_TOV_SECONDS;
+	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
+	rval = qla2x00_mailbox_command(ha, mcp);
+
+	/* Return mailbox statuses. */
+	*cmd_status = mcp->mb[0];
+	if (rval != QLA_SUCCESS)
+		DEBUG16(printk("%s(%ld): failed=%x.\n", __func__, ha->host_no,
+			rval));
+	else
+		DEBUG16(printk("%s(%ld): done.\n", __func__, ha->host_no));
+
+	return rval;
+}
 
 int
 qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_mid.c linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_mid.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_mid.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_mid.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 
 #include <linux/moduleparam.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 
 #include <scsi/scsi_tcq.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_os.c linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_os.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_os.c	2013-05-03 12:12:49.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_os.c	2013-05-03 09:52:21.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/kthread.h>
 #include <linux/mutex.h>
 #include <linux/kobject.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsicam.h>
@@ -107,6 +108,12 @@ MODULE_PARM_DESC(ql2xfwloadbin,
 		" 1 -- load firmware from flash.\n"
 		" 0 -- use default semantics.\n");
 
+int ql2xetsenable;
+module_param(ql2xetsenable, int, S_IRUGO|S_IRUSR);
+MODULE_PARM_DESC(ql2xetsenable,
+		"Enables firmware ETS burst."
+		"Default is 0 - skip ETS enablement.");
+
 /*
  * SCSI host template entry points
  */
@@ -682,44 +689,6 @@ qla2x00_wait_for_loop_ready(scsi_qla_hos
 	return (return_status);
 }
 
-void
-qla2x00_abort_fcport_cmds(fc_port_t *fcport)
-{
-	int cnt;
-	unsigned long flags;
-	srb_t *sp;
-	scsi_qla_host_t *vha = fcport->vha;
-	struct qla_hw_data *ha = vha->hw;
-	struct req_que *req;
-
-	spin_lock_irqsave(&ha->hardware_lock, flags);
-	req = vha->req;
-	for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
-		sp = req->outstanding_cmds[cnt];
-		if (!sp)
-			continue;
-		if (sp->fcport != fcport)
-			continue;
-		if (sp->ctx)
-			continue;
-
-		spin_unlock_irqrestore(&ha->hardware_lock, flags);
-		if (ha->isp_ops->abort_command(sp)) {
-			DEBUG2(qla_printk(KERN_WARNING, ha,
-			"Abort failed --  %lx\n",
-			sp->cmd->serial_number));
-		} else {
-			if (qla2x00_eh_wait_on_command(sp->cmd) !=
-				QLA_SUCCESS)
-				DEBUG2(qla_printk(KERN_WARNING, ha,
-				"Abort failed while waiting --  %lx\n",
-				sp->cmd->serial_number));
-		}
-		spin_lock_irqsave(&ha->hardware_lock, flags);
-	}
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
-}
-
 /**************************************************************************
 * qla2xxx_eh_abort
 *
@@ -1095,6 +1064,20 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
 	struct fc_port *fcport;
 	struct qla_hw_data *ha = vha->hw;
 
+	if (ha->flags.enable_target_reset) {
+		list_for_each_entry(fcport, &vha->vp_fcports, list) {
+			if (fcport->port_type != FCT_TARGET)
+				continue;
+
+			ret = ha->isp_ops->target_reset(fcport, 0, 0);
+			if (ret != QLA_SUCCESS) {
+				DEBUG2_3(printk("%s(%ld): bus_reset failed: "
+				    "target_reset=%d d_id=%x.\n", __func__,
+				    vha->host_no, ret, fcport->d_id.b24));
+			}
+		}
+	}
+
 	if (ha->flags.enable_lip_full_login && !IS_QLA81XX(ha)) {
 		ret = qla2x00_full_login_lip(vha);
 		if (ret != QLA_SUCCESS) {
@@ -1117,19 +1100,6 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
 			qla2x00_wait_for_loop_ready(vha);
 	}
 
-	if (ha->flags.enable_target_reset) {
-		list_for_each_entry(fcport, &vha->vp_fcports, list) {
-			if (fcport->port_type != FCT_TARGET)
-				continue;
-
-			ret = ha->isp_ops->target_reset(fcport, 0, 0);
-			if (ret != QLA_SUCCESS) {
-				DEBUG2_3(printk("%s(%ld): bus_reset failed: "
-				    "target_reset=%d d_id=%x.\n", __func__,
-				    vha->host_no, ret, fcport->d_id.b24));
-			}
-		}
-	}
 	/* Issue marker command only when we are going to start the I/O */
 	vha->marker_needed = 1;
 
@@ -1160,8 +1130,19 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *
 					qla2x00_sp_compl(ha, sp);
 				} else {
 					ctx = sp->ctx;
-					del_timer_sync(&ctx->timer);
-					ctx->free(sp);
+					if (ctx->type == SRB_LOGIN_CMD || ctx->type == SRB_LOGOUT_CMD) {
+						del_timer_sync(&ctx->timer);
+						ctx->free(sp);
+					} else {
+						struct srb_bsg* sp_bsg = (struct srb_bsg*)sp->ctx;
+						if (sp_bsg->bsg_job->request->msgcode == FC_BSG_HST_CT)
+							kfree(sp->fcport);
+						sp_bsg->bsg_job->req->errors = 0;
+						sp_bsg->bsg_job->reply->result = res;
+						sp_bsg->bsg_job->job_done(sp_bsg->bsg_job);
+						kfree(sp->ctx);
+						mempool_free(sp, ha->srb_mempool);
+					}
 				}
 			}
 		}
@@ -1258,7 +1239,7 @@ qla2x00_change_queue_depth(struct scsi_d
 		qla2x00_adjust_sdev_qdepth_up(sdev, qdepth);
 		break;
 	default:
-		return EOPNOTSUPP;
+		return -EOPNOTSUPP;
 	}
 
 	return sdev->queue_depth;
@@ -1696,9 +1677,11 @@ skip_pio:
 
 	/* Determine queue resources */
 	ha->max_req_queues = ha->max_rsp_queues = 1;
-	if ((ql2xmaxqueues <= 1 || ql2xmultique_tag < 1) &&
+	if ((ql2xmaxqueues <= 1 && !ql2xmultique_tag) ||
+		(ql2xmaxqueues > 1 && ql2xmultique_tag) ||
 		(!IS_QLA25XX(ha) && !IS_QLA81XX(ha)))
 		goto mqiobase_exit;
+
 	ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3),
 			pci_resource_len(ha->pdev, 3));
 	if (ha->mqiobase) {
@@ -1818,7 +1801,6 @@ qla2x00_probe_one(struct pci_dev *pdev,
 	/* Set EEH reset type to fundamental if required by hba */
 	if ( IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha)) {
 		pdev->needs_freset = 1;
-		pci_save_state(pdev);
 	}
 
 	/* Configure PCI I/O space */
@@ -1970,11 +1952,15 @@ qla2x00_probe_one(struct pci_dev *pdev,
 	host->max_channel = MAX_BUSES - 1;
 	host->max_lun = MAX_LUNS;
 	host->transportt = qla2xxx_transport_template;
+	sht->vendor_id = (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_QLOGIC);
 
 	/* Set up the irqs */
 	ret = qla2x00_request_irqs(ha, rsp);
 	if (ret)
 		goto probe_init_failed;
+
+	pci_save_state(pdev);
+
 	/* Alloc arrays of request and response ring ptrs */
 que_init:
 	if (!qla2x00_alloc_queues(ha)) {
@@ -2176,6 +2162,8 @@ qla2x00_remove_one(struct pci_dev *pdev)
 	kfree(ha);
 	ha = NULL;
 
+	pci_disable_pcie_error_reporting(pdev);
+
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
 }
@@ -3310,6 +3298,7 @@ qla2xxx_pci_error_detected(struct pci_de
 		return PCI_ERS_RESULT_CAN_RECOVER;
 	case pci_channel_io_frozen:
 		ha->flags.eeh_busy = 1;
+		qla2x00_free_irqs(vha);
 		pci_disable_device(pdev);
 		return PCI_ERS_RESULT_NEED_RESET;
 	case pci_channel_io_perm_failure:
@@ -3363,10 +3352,24 @@ qla2xxx_pci_slot_reset(struct pci_dev *p
 	pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT;
 	scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
 	struct qla_hw_data *ha = base_vha->hw;
-	int rc;
+	struct rsp_que *rsp;
+	int rc, retries = 10;
 
 	DEBUG17(qla_printk(KERN_WARNING, ha, "slot_reset\n"));
 
+	/* Workaround: qla2xxx driver which access hardware earlier
+	 * needs error state to be pci_channel_io_online.
+	 * Otherwise mailbox command timesout.
+	 */
+	pdev->error_state = pci_channel_io_normal;
+
+	pci_restore_state(pdev);
+
+	/* pci_restore_state() clears the saved_state flag of the device
+	 * save restored state which resets saved_state flag
+	 */
+	pci_save_state(pdev);
+
 	if (ha->mem_only)
 		rc = pci_enable_device_mem(pdev);
 	else
@@ -3378,27 +3381,23 @@ qla2xxx_pci_slot_reset(struct pci_dev *p
 		return ret;
 	}
 
+	rsp = ha->rsp_q_map[0];
+	if (qla2x00_request_irqs(ha, rsp))
+		return ret;
+
 	if (ha->isp_ops->pci_config(base_vha))
 		return ret;
 
-#ifdef QL_DEBUG_LEVEL_17
-	{
-		uint8_t b;
-		uint32_t i;
+	while (ha->flags.mbox_busy && retries--)
+		msleep(1000);
 
-		printk("slot_reset_1: ");
-		for (i = 0; i < 256; i++) {
-			pci_read_config_byte(ha->pdev, i, &b);
-			printk("%s%02x", (i%16) ? " " : "\n", b);
-		}
-		printk("\n");
-	}
-#endif
 	set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
 	if (qla2x00_abort_isp(base_vha) == QLA_SUCCESS)
 		ret =  PCI_ERS_RESULT_RECOVERED;
 	clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
 
+	pci_cleanup_aer_uncorrect_error_status(pdev);
+
 	DEBUG17(qla_printk(KERN_WARNING, ha,
 	    "slot_reset-return:ret=%x\n", ret));
 
@@ -3422,8 +3421,6 @@ qla2xxx_pci_resume(struct pci_dev *pdev)
 	}
 
 	ha->flags.eeh_busy = 0;
-
-	pci_cleanup_aer_uncorrect_error_status(pdev);
 }
 
 static struct pci_error_handlers qla2xxx_err_handler = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_sup.c linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_sup.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_sup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_sup.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
 #include "qla_def.h"
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <asm/uaccess.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_version.h linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_version.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla2xxx/qla_version.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla2xxx/qla_version.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,9 +7,9 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.03.01-k10"
+#define QLA2XXX_VERSION      "8.03.02-k2"
 
 #define QLA_DRIVER_MAJOR_VER	8
 #define QLA_DRIVER_MINOR_VER	3
-#define QLA_DRIVER_PATCH_VER	1
-#define QLA_DRIVER_BETA_VER	0
+#define QLA_DRIVER_PATCH_VER	2
+#define QLA_DRIVER_BETA_VER	2
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla4xxx/ql4_init.c linux-libre-2.6.34-gnu1/drivers/scsi/qla4xxx/ql4_init.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla4xxx/ql4_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla4xxx/ql4_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -844,10 +844,10 @@ static int qla4xxx_config_nvram(struct s
 	DEBUG2(printk("scsi%ld: %s: Get EEProm parameters \n", ha->host_no,
 		      __func__));
 	if (ql4xxx_lock_flash(ha) != QLA_SUCCESS)
-		return (QLA_ERROR);
+		return QLA_ERROR;
 	if (ql4xxx_lock_nvram(ha) != QLA_SUCCESS) {
 		ql4xxx_unlock_flash(ha);
-		return (QLA_ERROR);
+		return QLA_ERROR;
 	}
 
 	/* Get EEPRom Parameters from NVRAM and validate */
@@ -858,20 +858,18 @@ static int qla4xxx_config_nvram(struct s
 			rd_nvram_word(ha, eeprom_ext_hw_conf_offset(ha));
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	} else {
-		/*
-		 * QLogic adapters should always have a valid NVRAM.
-		 * If not valid, do not load.
-		 */
 		dev_warn(&ha->pdev->dev,
 			   "scsi%ld: %s: EEProm checksum invalid.  "
 			   "Please update your EEPROM\n", ha->host_no,
 			   __func__);
 
-		/* set defaults */
+		/* Attempt to set defaults */
 		if (is_qla4010(ha))
 			extHwConfig.Asuint32_t = 0x1912;
 		else if (is_qla4022(ha) | is_qla4032(ha))
 			extHwConfig.Asuint32_t = 0x0023;
+		else
+			return QLA_ERROR;
 	}
 	DEBUG(printk("scsi%ld: %s: Setting extHwConfig to 0xFFFF%04x\n",
 		     ha->host_no, __func__, extHwConfig.Asuint32_t));
@@ -884,7 +882,7 @@ static int qla4xxx_config_nvram(struct s
 	ql4xxx_unlock_nvram(ha);
 	ql4xxx_unlock_flash(ha);
 
-	return (QLA_SUCCESS);
+	return QLA_SUCCESS;
 }
 
 static void qla4x00_pci_config(struct scsi_qla_host *ha)
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla4xxx/ql4_mbx.c linux-libre-2.6.34-gnu1/drivers/scsi/qla4xxx/ql4_mbx.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla4xxx/ql4_mbx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla4xxx/ql4_mbx.c	2010-05-16 17:17:36.000000000 -0400
@@ -467,7 +467,7 @@ int qla4xxx_get_fwddb_entry(struct scsi_
 	if (conn_err_detail)
 		*conn_err_detail = mbox_sts[5];
 	if (tcp_source_port_num)
-		*tcp_source_port_num = (uint16_t) mbox_sts[6] >> 16;
+		*tcp_source_port_num = (uint16_t) (mbox_sts[6] >> 16);
 	if (connection_id)
 		*connection_id = (uint16_t) mbox_sts[6] & 0x00FF;
 	status = QLA_SUCCESS;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qla4xxx/ql4_os.c linux-libre-2.6.34-gnu1/drivers/scsi/qla4xxx/ql4_os.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/qla4xxx/ql4_os.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qla4xxx/ql4_os.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,6 +5,7 @@
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsicam.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/qlogicpti.c linux-libre-2.6.34-gnu1/drivers/scsi/qlogicpti.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/qlogicpti.c	2013-05-03 12:12:29.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/scsi/qlogicpti.c	2013-05-03 09:52:01.000000000 -0400
@@ -16,7 +16,7 @@
 #include <linux/delay.h>
 #include <linux/types.h>
 #include <linux/string.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/blkdev.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
@@ -738,7 +738,7 @@ static int __devinit qpti_register_irq(s
 	 * sanely maintain.
 	 */
 	if (request_irq(qpti->irq, qpti_intr,
-			IRQF_SHARED, "Qlogic/PTI", qpti))
+			IRQF_SHARED, "QlogicPTI", qpti))
 		goto fail;
 
 	printk("qlogicpti%d: IRQ %d ", qpti->qpti_id, qpti->irq);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/raid_class.c linux-libre-2.6.34-gnu1/drivers/scsi/raid_class.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/raid_class.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/raid_class.c	2010-05-16 17:17:36.000000000 -0400
@@ -63,6 +63,7 @@ static int raid_match(struct attribute_c
 	 * emulated RAID devices, so start with SCSI */
 	struct raid_internal *i = ac_to_raid_internal(cont);
 
+#if defined(CONFIG_SCSI) || defined(CONFIG_SCSI_MODULE)
 	if (scsi_is_sdev_device(dev)) {
 		struct scsi_device *sdev = to_scsi_device(dev);
 
@@ -71,6 +72,7 @@ static int raid_match(struct attribute_c
 
 		return i->f->is_raid(dev);
 	}
+#endif
 	/* FIXME: look at other subsystems too */
 	return 0;
 }
@@ -149,6 +151,7 @@ static struct {
 	{ RAID_LEVEL_0, "raid0" },
 	{ RAID_LEVEL_1, "raid1" },
 	{ RAID_LEVEL_10, "raid10" },
+	{ RAID_LEVEL_1E, "raid1e" },
 	{ RAID_LEVEL_3, "raid3" },
 	{ RAID_LEVEL_4, "raid4" },
 	{ RAID_LEVEL_5, "raid5" },
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi.c linux-libre-2.6.34-gnu1/drivers/scsi/scsi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -1018,6 +1018,8 @@ static int scsi_vpd_inquiry(struct scsi_
  * scsi_get_vpd_page - Get Vital Product Data from a SCSI device
  * @sdev: The device to ask
  * @page: Which Vital Product Data to return
+ * @buf: where to store the VPD
+ * @buf_len: number of bytes in the VPD buffer area
  *
  * SCSI devices may optionally supply Vital Product Data.  Each 'page'
  * of VPD is defined in the appropriate SCSI document (eg SPC, SBC).
@@ -1026,55 +1028,39 @@ static int scsi_vpd_inquiry(struct scsi_
  * responsible for calling kfree() on this pointer when it is no longer
  * needed.  If we cannot retrieve the VPD page this routine returns %NULL.
  */
-unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
+int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf,
+		      int buf_len)
 {
 	int i, result;
-	unsigned int len;
-	const unsigned int init_vpd_len = 255;
-	unsigned char *buf = kmalloc(init_vpd_len, GFP_KERNEL);
-
-	if (!buf)
-		return NULL;
 
 	/* Ask for all the pages supported by this device */
-	result = scsi_vpd_inquiry(sdev, buf, 0, init_vpd_len);
+	result = scsi_vpd_inquiry(sdev, buf, 0, buf_len);
 	if (result)
 		goto fail;
 
 	/* If the user actually wanted this page, we can skip the rest */
 	if (page == 0)
-		return buf;
+		return -EINVAL;
 
-	for (i = 0; i < buf[3]; i++)
+	for (i = 0; i < min((int)buf[3], buf_len - 4); i++)
 		if (buf[i + 4] == page)
 			goto found;
+
+	if (i < buf[3] && i > buf_len)
+		/* ran off the end of the buffer, give us benefit of doubt */
+		goto found;
 	/* The device claims it doesn't support the requested page */
 	goto fail;
 
  found:
-	result = scsi_vpd_inquiry(sdev, buf, page, 255);
-	if (result)
-		goto fail;
-
-	/*
-	 * Some pages are longer than 255 bytes.  The actual length of
-	 * the page is returned in the header.
-	 */
-	len = ((buf[2] << 8) | buf[3]) + 4;
-	if (len <= init_vpd_len)
-		return buf;
-
-	kfree(buf);
-	buf = kmalloc(len, GFP_KERNEL);
-	result = scsi_vpd_inquiry(sdev, buf, page, len);
+	result = scsi_vpd_inquiry(sdev, buf, page, buf_len);
 	if (result)
 		goto fail;
 
-	return buf;
+	return 0;
 
  fail:
-	kfree(buf);
-	return NULL;
+	return -EINVAL;
 }
 EXPORT_SYMBOL_GPL(scsi_get_vpd_page);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsicam.c linux-libre-2.6.34-gnu1/drivers/scsi/scsicam.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsicam.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsicam.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/genhd.h>
 #include <linux/kernel.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi_debug.c linux-libre-2.6.34-gnu1/drivers/scsi/scsi_debug.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi_debug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi_debug.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/genhd.h>
@@ -956,7 +957,8 @@ static int resp_start_stop(struct scsi_c
 static sector_t get_sdebug_capacity(void)
 {
 	if (scsi_debug_virtual_gb > 0)
-		return 2048 * 1024 * (sector_t)scsi_debug_virtual_gb;
+		return (sector_t)scsi_debug_virtual_gb *
+			(1073741824 / scsi_debug_sector_size);
 	else
 		return sdebug_store_sectors;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi_devinfo.c linux-libre-2.6.34-gnu1/drivers/scsi/scsi_devinfo.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi_devinfo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi_devinfo.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
 #include <linux/moduleparam.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_devinfo.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi_error.c linux-libre-2.6.34-gnu1/drivers/scsi/scsi_error.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi_error.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi_error.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/gfp.h>
 #include <linux/timer.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
@@ -301,7 +302,20 @@ static int scsi_check_sense(struct scsi_
 		if (scmd->device->allow_restart &&
 		    (sshdr.asc == 0x04) && (sshdr.ascq == 0x02))
 			return FAILED;
-		return SUCCESS;
+
+		if (blk_barrier_rq(scmd->request))
+			/*
+			 * barrier requests should always retry on UA
+			 * otherwise block will get a spurious error
+			 */
+			return NEEDS_RETRY;
+		else
+			/*
+			 * for normal (non barrier) commands, pass the
+			 * UA upwards for a determination in the
+			 * completion functions
+			 */
+			return SUCCESS;
 
 		/* these three are not supported */
 	case COPY_ABORTED:
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi_lib.c linux-libre-2.6.34-gnu1/drivers/scsi/scsi_lib.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi_lib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi_lib.c	2010-05-16 17:17:36.000000000 -0400
@@ -773,8 +773,14 @@ void scsi_io_completion(struct scsi_cmnd
 	 * we already took a copy of the original into rq->errors which
 	 * is what gets returned to the user
 	 */
-	if (sense_valid && sshdr.sense_key == RECOVERED_ERROR) {
-		if (!(req->cmd_flags & REQ_QUIET))
+	if (sense_valid && (sshdr.sense_key == RECOVERED_ERROR)) {
+		/* if ATA PASS-THROUGH INFORMATION AVAILABLE skip
+		 * print since caller wants ATA registers. Only occurs on
+		 * SCSI ATA PASS_THROUGH commands when CK_COND=1
+		 */
+		if ((sshdr.asc == 0x0) && (sshdr.ascq == 0x1d))
+			;
+		else if (!(req->cmd_flags & REQ_QUIET))
 			scsi_print_sense("", cmd);
 		result = 0;
 		/* BLOCK_PC may have set error */
@@ -1624,10 +1630,10 @@ struct request_queue *__scsi_alloc_queue
 	/*
 	 * this limit is imposed by hardware restrictions
 	 */
-	blk_queue_max_hw_segments(q, shost->sg_tablesize);
-	blk_queue_max_phys_segments(q, SCSI_MAX_SG_CHAIN_SEGMENTS);
+	blk_queue_max_segments(q, min_t(unsigned short, shost->sg_tablesize,
+					SCSI_MAX_SG_CHAIN_SEGMENTS));
 
-	blk_queue_max_sectors(q, shost->max_sectors);
+	blk_queue_max_hw_sectors(q, shost->max_sectors);
 	blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost));
 	blk_queue_segment_boundary(q, shost->dma_boundary);
 	dma_set_seg_boundary(dev, shost->dma_boundary);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi_netlink.c linux-libre-2.6.34-gnu1/drivers/scsi/scsi_netlink.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi_netlink.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi_netlink.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/jiffies.h>
 #include <linux/security.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/netlink.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi_proc.c linux-libre-2.6.34-gnu1/drivers/scsi/scsi_proc.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi_proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi_proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,12 +20,12 @@
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/errno.h>
 #include <linux/blkdev.h>
 #include <linux/seq_file.h>
 #include <linux/mutex.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 
 #include <scsi/scsi.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi_sas_internal.h linux-libre-2.6.34-gnu1/drivers/scsi/scsi_sas_internal.h
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi_sas_internal.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi_sas_internal.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
 #define SAS_PHY_ATTRS		17
 #define SAS_PORT_ATTRS		1
 #define SAS_RPORT_ATTRS		7
-#define SAS_END_DEV_ATTRS	3
+#define SAS_END_DEV_ATTRS	5
 #define SAS_EXPANDER_ATTRS	7
 
 struct sas_internal {
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi_scan.c linux-libre-2.6.34-gnu1/drivers/scsi/scsi_scan.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi_scan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi_scan.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/kthread.h>
 #include <linux/spinlock.h>
 #include <linux/async.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -879,7 +880,7 @@ static int scsi_add_lun(struct scsi_devi
 	 * broken RA4x00 Compaq Disk Array
 	 */
 	if (*bflags & BLIST_MAX_512)
-		blk_queue_max_sectors(sdev->request_queue, 512);
+		blk_queue_max_hw_sectors(sdev->request_queue, 512);
 
 	/*
 	 * Some devices may not want to have a start command automatically
@@ -1339,8 +1340,10 @@ static int scsi_report_lun_scan(struct s
 		sdev = scsi_alloc_sdev(starget, 0, NULL);
 		if (!sdev)
 			return 0;
-		if (scsi_device_get(sdev))
+		if (scsi_device_get(sdev)) {
+			__scsi_remove_device(sdev);
 			return 0;
+		}
 	}
 
 	sprintf(devname, "host %d channel %d id %d",
@@ -1907,10 +1910,9 @@ struct scsi_device *scsi_get_host_dev(st
 		goto out;
 
 	sdev = scsi_alloc_sdev(starget, 0, NULL);
-	if (sdev) {
-		sdev->sdev_gendev.parent = get_device(&starget->dev);
+	if (sdev)
 		sdev->borken = 0;
-	} else
+	else
 		scsi_target_reap(starget);
 	put_device(&starget->dev);
  out:
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi_sysfs.c linux-libre-2.6.34-gnu1/drivers/scsi/scsi_sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi_sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi_sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/device.h>
@@ -847,6 +848,8 @@ static int scsi_target_add(struct scsi_t
 	if (starget->state != STARGET_CREATED)
 		return 0;
 
+	device_enable_async_suspend(&starget->dev);
+
 	error = device_add(&starget->dev);
 	if (error) {
 		dev_err(&starget->dev, "target device_add failed, error %d\n", error);
@@ -878,7 +881,8 @@ int scsi_sysfs_add_sdev(struct scsi_devi
 	struct request_queue *rq = sdev->request_queue;
 	struct scsi_target *starget = sdev->sdev_target;
 
-	if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0)
+	error = scsi_device_set_state(sdev, SDEV_RUNNING);
+	if (error)
 		return error;
 
 	error = scsi_target_add(starget);
@@ -886,16 +890,18 @@ int scsi_sysfs_add_sdev(struct scsi_devi
 		return error;
 
 	transport_configure_device(&starget->dev);
+	device_enable_async_suspend(&sdev->sdev_gendev);
 	error = device_add(&sdev->sdev_gendev);
 	if (error) {
 		printk(KERN_INFO "error 1\n");
-		goto out_remove;
+		return error;
 	}
+	device_enable_async_suspend(&sdev->sdev_dev);
 	error = device_add(&sdev->sdev_dev);
 	if (error) {
 		printk(KERN_INFO "error 2\n");
 		device_del(&sdev->sdev_gendev);
-		goto out_remove;
+		return error;
 	}
 	transport_add_device(&sdev->sdev_gendev);
 	sdev->is_visible = 1;
@@ -910,14 +916,14 @@ int scsi_sysfs_add_sdev(struct scsi_devi
 	else
 		error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth);
 	if (error)
-		goto out_remove;
+		return error;
 
 	if (sdev->host->hostt->change_queue_type)
 		error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_type_rw);
 	else
 		error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_type);
 	if (error)
-		goto out_remove;
+		return error;
 
 	error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL, NULL);
 
@@ -933,16 +939,11 @@ int scsi_sysfs_add_sdev(struct scsi_devi
 			error = device_create_file(&sdev->sdev_gendev,
 					sdev->host->hostt->sdev_attrs[i]);
 			if (error)
-				goto out_remove;
+				return error;
 		}
 	}
 
-	return 0;
-
- out_remove:
-	__scsi_remove_device(sdev);
 	return error;
-
 }
 
 void __scsi_remove_device(struct scsi_device *sdev)
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi_tgt_if.c linux-libre-2.6.34-gnu1/drivers/scsi/scsi_tgt_if.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi_tgt_if.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi_tgt_if.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  * 02110-1301 USA
  */
 #include <linux/miscdevice.h>
+#include <linux/gfp.h>
 #include <linux/file.h>
 #include <linux/smp_lock.h>
 #include <net/tcp.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi_tgt_lib.c linux-libre-2.6.34-gnu1/drivers/scsi/scsi_tgt_lib.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi_tgt_lib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi_tgt_lib.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/hash.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi_transport_fc.c linux-libre-2.6.34-gnu1/drivers/scsi/scsi_transport_fc.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi_transport_fc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi_transport_fc.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
  */
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
@@ -475,7 +476,8 @@ MODULE_PARM_DESC(dev_loss_tmo,
 		 "Maximum number of seconds that the FC transport should"
 		 " insulate the loss of a remote port. Once this value is"
 		 " exceeded, the scsi target is removed. Value should be"
-		 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT.");
+		 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT if"
+		 " fast_io_fail_tmo is not set.");
 
 /*
  * Netlink Infrastructure
@@ -842,9 +844,17 @@ store_fc_rport_dev_loss_tmo(struct devic
 	    (rport->port_state == FC_PORTSTATE_NOTPRESENT))
 		return -EBUSY;
 	val = simple_strtoul(buf, &cp, 0);
-	if ((*cp && (*cp != '\n')) ||
-	    (val < 0) || (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT))
+	if ((*cp && (*cp != '\n')) || (val < 0))
+		return -EINVAL;
+
+	/*
+	 * If fast_io_fail is off we have to cap
+	 * dev_loss_tmo at SCSI_DEVICE_BLOCK_MAX_TIMEOUT
+	 */
+	if (rport->fast_io_fail_tmo == -1 &&
+	    val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)
 		return -EINVAL;
+
 	i->f->set_rport_dev_loss_tmo(rport, val);
 	return count;
 }
@@ -925,9 +935,16 @@ store_fc_rport_fast_io_fail_tmo(struct d
 		rport->fast_io_fail_tmo = -1;
 	else {
 		val = simple_strtoul(buf, &cp, 0);
-		if ((*cp && (*cp != '\n')) ||
-		    (val < 0) || (val >= rport->dev_loss_tmo))
+		if ((*cp && (*cp != '\n')) || (val < 0))
+			return -EINVAL;
+		/*
+		 * Cap fast_io_fail by dev_loss_tmo or
+		 * SCSI_DEVICE_BLOCK_MAX_TIMEOUT.
+		 */
+		if ((val >= rport->dev_loss_tmo) ||
+		    (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT))
 			return -EINVAL;
+
 		rport->fast_io_fail_tmo = val;
 	}
 	return count;
@@ -1216,6 +1233,15 @@ store_fc_vport_delete(struct device *dev
 {
 	struct fc_vport *vport = transport_class_to_vport(dev);
 	struct Scsi_Host *shost = vport_to_shost(vport);
+	unsigned long flags;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) {
+		spin_unlock_irqrestore(shost->host_lock, flags);
+		return -EBUSY;
+	}
+	vport->flags |= FC_VPORT_DELETING;
+	spin_unlock_irqrestore(shost->host_lock, flags);
 
 	fc_queue_work(shost, &vport->vport_delete_work);
 	return count;
@@ -1805,6 +1831,9 @@ store_fc_host_vport_delete(struct device
 	list_for_each_entry(vport, &fc_host->vports, peers) {
 		if ((vport->channel == 0) &&
 		    (vport->port_name == wwpn) && (vport->node_name == wwnn)) {
+			if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))
+				break;
+			vport->flags |= FC_VPORT_DELETING;
 			match = 1;
 			break;
 		}
@@ -3354,18 +3383,6 @@ fc_vport_terminate(struct fc_vport *vpor
 	unsigned long flags;
 	int stat;
 
-	spin_lock_irqsave(shost->host_lock, flags);
-	if (vport->flags & FC_VPORT_CREATING) {
-		spin_unlock_irqrestore(shost->host_lock, flags);
-		return -EBUSY;
-	}
-	if (vport->flags & (FC_VPORT_DEL)) {
-		spin_unlock_irqrestore(shost->host_lock, flags);
-		return -EALREADY;
-	}
-	vport->flags |= FC_VPORT_DELETING;
-	spin_unlock_irqrestore(shost->host_lock, flags);
-
 	if (i->f->vport_delete)
 		stat = i->f->vport_delete(vport);
 	else
@@ -3836,7 +3853,7 @@ fc_bsg_request_handler(struct request_qu
 		if (rport && (rport->port_state != FC_PORTSTATE_ONLINE)) {
 			req->errors = -ENXIO;
 			spin_unlock_irq(q->queue_lock);
-			blk_end_request(req, -ENXIO, blk_rq_bytes(req));
+			blk_end_request_all(req, -ENXIO);
 			spin_lock_irq(q->queue_lock);
 			continue;
 		}
@@ -3846,7 +3863,7 @@ fc_bsg_request_handler(struct request_qu
 		ret = fc_req_to_bsgjob(shost, rport, req);
 		if (ret) {
 			req->errors = ret;
-			blk_end_request(req, ret, blk_rq_bytes(req));
+			blk_end_request_all(req, ret);
 			spin_lock_irq(q->queue_lock);
 			continue;
 		}
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi_transport_iscsi.c linux-libre-2.6.34-gnu1/drivers/scsi/scsi_transport_iscsi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi_transport_iscsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi_transport_iscsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  */
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <net/tcp.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi_transport_sas.c linux-libre-2.6.34-gnu1/drivers/scsi/scsi_transport_sas.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi_transport_sas.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi_transport_sas.c	2010-05-16 17:17:36.000000000 -0400
@@ -155,6 +155,17 @@ static struct {
 sas_bitfield_name_search(linkspeed, sas_linkspeed_names)
 sas_bitfield_name_set(linkspeed, sas_linkspeed_names)
 
+static struct sas_end_device *sas_sdev_to_rdev(struct scsi_device *sdev)
+{
+	struct sas_rphy *rphy = target_to_rphy(sdev->sdev_target);
+	struct sas_end_device *rdev;
+
+	BUG_ON(rphy->identify.device_type != SAS_END_DEVICE);
+
+	rdev = rphy_to_end_device(rphy);
+	return rdev;
+}
+
 static void sas_smp_request(struct request_queue *q, struct Scsi_Host *shost,
 			    struct sas_rphy *rphy)
 {
@@ -358,6 +369,85 @@ void sas_remove_host(struct Scsi_Host *s
 }
 EXPORT_SYMBOL(sas_remove_host);
 
+/**
+ * sas_tlr_supported - checking TLR bit in vpd 0x90
+ * @sdev: scsi device struct
+ *
+ * Check Transport Layer Retries are supported or not.
+ * If vpd page 0x90 is present, TRL is supported.
+ *
+ */
+unsigned int
+sas_tlr_supported(struct scsi_device *sdev)
+{
+	const int vpd_len = 32;
+	struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
+	char *buffer = kzalloc(vpd_len, GFP_KERNEL);
+	int ret = 0;
+
+	if (scsi_get_vpd_page(sdev, 0x90, buffer, vpd_len))
+		goto out;
+
+	/*
+	 * Magic numbers: the VPD Protocol page (0x90)
+	 * has a 4 byte header and then one entry per device port
+	 * the TLR bit is at offset 8 on each port entry
+	 * if we take the first port, that's at total offset 12
+	 */
+	ret = buffer[12] & 0x01;
+
+ out:
+	kfree(buffer);
+	rdev->tlr_supported = ret;
+	return ret;
+
+}
+EXPORT_SYMBOL_GPL(sas_tlr_supported);
+
+/**
+ * sas_disable_tlr - setting TLR flags
+ * @sdev: scsi device struct
+ *
+ * Seting tlr_enabled flag to 0.
+ *
+ */
+void
+sas_disable_tlr(struct scsi_device *sdev)
+{
+	struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
+
+	rdev->tlr_enabled = 0;
+}
+EXPORT_SYMBOL_GPL(sas_disable_tlr);
+
+/**
+ * sas_enable_tlr - setting TLR flags
+ * @sdev: scsi device struct
+ *
+ * Seting tlr_enabled flag 1.
+ *
+ */
+void sas_enable_tlr(struct scsi_device *sdev)
+{
+	unsigned int tlr_supported = 0;
+	tlr_supported  = sas_tlr_supported(sdev);
+
+	if (tlr_supported) {
+		struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
+
+		rdev->tlr_enabled = 1;
+	}
+
+	return;
+}
+EXPORT_SYMBOL_GPL(sas_enable_tlr);
+
+unsigned int sas_is_tlr_enabled(struct scsi_device *sdev)
+{
+	struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
+	return rdev->tlr_enabled;
+}
+EXPORT_SYMBOL_GPL(sas_is_tlr_enabled);
 
 /*
  * SAS Phy attributes
@@ -1146,15 +1236,10 @@ sas_rphy_simple_attr(identify.phy_identi
 int sas_read_port_mode_page(struct scsi_device *sdev)
 {
 	char *buffer = kzalloc(BUF_SIZE, GFP_KERNEL), *msdata;
-	struct sas_rphy *rphy = target_to_rphy(sdev->sdev_target);
-	struct sas_end_device *rdev;
+	struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
 	struct scsi_mode_data mode_data;
 	int res, error;
 
-	BUG_ON(rphy->identify.device_type != SAS_END_DEVICE);
-
-	rdev = rphy_to_end_device(rphy);
-
 	if (!buffer)
 		return -ENOMEM;
 
@@ -1207,6 +1292,10 @@ sas_end_dev_simple_attr(I_T_nexus_loss_t
 			"%d\n", int);
 sas_end_dev_simple_attr(initiator_response_timeout, initiator_response_timeout,
 			"%d\n", int);
+sas_end_dev_simple_attr(tlr_supported, tlr_supported,
+			"%d\n", int);
+sas_end_dev_simple_attr(tlr_enabled, tlr_enabled,
+			"%d\n", int);
 
 static DECLARE_TRANSPORT_CLASS(sas_expander_class,
 			       "sas_expander", NULL, NULL, NULL);
@@ -1733,6 +1822,8 @@ sas_attach_transport(struct sas_function
 	SETUP_END_DEV_ATTRIBUTE(end_dev_ready_led_meaning);
 	SETUP_END_DEV_ATTRIBUTE(end_dev_I_T_nexus_loss_timeout);
 	SETUP_END_DEV_ATTRIBUTE(end_dev_initiator_response_timeout);
+	SETUP_END_DEV_ATTRIBUTE(end_dev_tlr_supported);
+	SETUP_END_DEV_ATTRIBUTE(end_dev_tlr_enabled);
 	i->end_dev_attrs[count] = NULL;
 
 	count = 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/scsi_transport_spi.c linux-libre-2.6.34-gnu1/drivers/scsi/scsi_transport_spi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/scsi_transport_spi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/scsi_transport_spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/blkdev.h>
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include "scsi_priv.h"
 #include <scsi/scsi_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/sd.c linux-libre-2.6.34-gnu1/drivers/scsi/sd.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/sd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/sd.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,7 @@
 #include <linux/mutex.h>
 #include <linux/string_helpers.h>
 #include <linux/async.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 
@@ -1039,6 +1040,7 @@ static void sd_prepare_flush(struct requ
 {
 	rq->cmd_type = REQ_TYPE_BLOCK_PC;
 	rq->timeout = SD_TIMEOUT;
+	rq->retries = SD_MAX_RETRIES;
 	rq->cmd[0] = SYNCHRONIZE_CACHE;
 	rq->cmd_len = 10;
 }
@@ -1196,19 +1198,10 @@ static int sd_done(struct scsi_cmnd *SCp
 		SCpnt->result = 0;
 		memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
 		break;
-	case ABORTED_COMMAND:
-		if (sshdr.asc == 0x10) { /* DIF: Disk detected corruption */
-			scsi_print_result(SCpnt);
-			scsi_print_sense("sd", SCpnt);
-			good_bytes = sd_completed_bytes(SCpnt);
-		}
-		break;
-	case ILLEGAL_REQUEST:
-		if (sshdr.asc == 0x10) { /* DIX: HBA detected corruption */
-			scsi_print_result(SCpnt);
-			scsi_print_sense("sd", SCpnt);
+	case ABORTED_COMMAND: /* DIF: Target detected corruption */
+	case ILLEGAL_REQUEST: /* DIX: Host detected corruption */
+		if (sshdr.asc == 0x10)
 			good_bytes = sd_completed_bytes(SCpnt);
-		}
 		break;
 	default:
 		break;
@@ -1218,8 +1211,19 @@ static int sd_done(struct scsi_cmnd *SCp
 		sd_dif_complete(SCpnt, good_bytes);
 
 	if (scsi_host_dif_capable(sdkp->device->host, sdkp->protection_type)
-	    == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd)
+	    == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd) {
+
+		/* We have to print a failed command here as the
+		 * extended CDB gets freed before scsi_io_completion()
+		 * is called.
+		 */
+		if (result)
+			scsi_print_command(SCpnt);
+
 		mempool_free(SCpnt->cmnd, sd_cdb_pool);
+		SCpnt->cmnd = NULL;
+		SCpnt->cmd_len = 0;
+	}
 
 	return good_bytes;
 }
@@ -1946,13 +1950,13 @@ static void sd_read_block_limits(struct
 {
 	struct request_queue *q = sdkp->disk->queue;
 	unsigned int sector_sz = sdkp->device->sector_size;
-	char *buffer;
-
-	/* Block Limits VPD */
-	buffer = scsi_get_vpd_page(sdkp->device, 0xb0);
+	const int vpd_len = 64;
+	unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL);
 
-	if (buffer == NULL)
-		return;
+	if (!buffer ||
+	    /* Block Limits VPD */
+	    scsi_get_vpd_page(sdkp->device, 0xb0, buffer, vpd_len))
+		goto out;
 
 	blk_queue_io_min(sdkp->disk->queue,
 			 get_unaligned_be16(&buffer[6]) * sector_sz);
@@ -1984,6 +1988,7 @@ static void sd_read_block_limits(struct
 				get_unaligned_be32(&buffer[32]) & ~(1 << 31);
 	}
 
+ out:
 	kfree(buffer);
 }
 
@@ -1993,20 +1998,23 @@ static void sd_read_block_limits(struct
  */
 static void sd_read_block_characteristics(struct scsi_disk *sdkp)
 {
-	char *buffer;
+	unsigned char *buffer;
 	u16 rot;
+	const int vpd_len = 64;
 
-	/* Block Device Characteristics VPD */
-	buffer = scsi_get_vpd_page(sdkp->device, 0xb1);
+	buffer = kmalloc(vpd_len, GFP_KERNEL);
 
-	if (buffer == NULL)
-		return;
+	if (!buffer ||
+	    /* Block Device Characteristics VPD */
+	    scsi_get_vpd_page(sdkp->device, 0xb1, buffer, vpd_len))
+		goto out;
 
 	rot = get_unaligned_be16(&buffer[4]);
 
 	if (rot == 1)
 		queue_flag_set_unlocked(QUEUE_FLAG_NONROT, sdkp->disk->queue);
 
+ out:
 	kfree(buffer);
 }
 
@@ -2105,7 +2113,7 @@ static int sd_revalidate_disk(struct gen
  *	which is followed by sdaaa.
  *
  *	This is basically 26 base counting with one extra 'nil' entry
- *	at the beggining from the second digit on and can be
+ *	at the beginning from the second digit on and can be
  *	determined using similar method as 26 base conversion with the
  *	index shifted -1 after each digit is computed.
  *
@@ -2179,7 +2187,7 @@ static void sd_probe_async(void *data, a
 	blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
 
 	gd->driverfs_dev = &sdp->sdev_gendev;
-	gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS;
+	gd->flags = GENHD_FL_EXT_DEVT;
 	if (sdp->removable)
 		gd->flags |= GENHD_FL_REMOVABLE;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/ses.c linux-libre-2.6.34-gnu1/drivers/scsi/ses.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/ses.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/ses.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 **-----------------------------------------------------------------------------
 */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/enclosure.h>
@@ -448,13 +449,17 @@ static void ses_match_to_enclosure(struc
 		.addr = 0,
 	};
 
-	buf = scsi_get_vpd_page(sdev, 0x83);
-	if (!buf)
-		return;
+	buf = kmalloc(INIT_ALLOC_SIZE, GFP_KERNEL);
+	if (!buf || scsi_get_vpd_page(sdev, 0x83, buf, INIT_ALLOC_SIZE))
+		goto free;
 
 	ses_enclosure_data_process(edev, to_scsi_device(edev->edev.parent), 0);
 
 	vpd_len = ((buf[2] << 8) | buf[3]) + 4;
+	kfree(buf);
+	buf = kmalloc(vpd_len, GFP_KERNEL);
+	if (!buf ||scsi_get_vpd_page(sdev, 0x83, buf, vpd_len))
+		goto free;
 
 	desc = buf + 4;
 	while (desc < buf + vpd_len) {
@@ -591,8 +596,6 @@ static int ses_intf_add(struct device *c
 		ses_dev->page10_len = len;
 		buf = NULL;
 	}
-	kfree(hdr_buf);
-
 	scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL);
 	if (!scomp)
 		goto err_free;
@@ -604,6 +607,8 @@ static int ses_intf_add(struct device *c
 		goto err_free;
 	}
 
+	kfree(hdr_buf);
+
 	edev->scratch = ses_dev;
 	for (i = 0; i < components; i++)
 		edev->component[i].scratch = scomp + i;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/sg.c linux-libre-2.6.34-gnu1/drivers/scsi/sg.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/sg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/sg.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@ static int sg_version_num = 30534;	/* 2
 #include <linux/errno.h>
 #include <linux/mtio.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
 #include <linux/poll.h>
@@ -287,8 +288,7 @@ sg_open(struct inode *inode, struct file
 	if (list_empty(&sdp->sfds)) {	/* no existing opens on this device */
 		sdp->sgdebug = 0;
 		q = sdp->device->request_queue;
-		sdp->sg_tablesize = min(queue_max_hw_segments(q),
-					queue_max_phys_segments(q));
+		sdp->sg_tablesize = queue_max_segments(q);
 	}
 	if ((sfp = sg_add_sfp(sdp, dev)))
 		filp->private_data = sfp;
@@ -1376,8 +1376,7 @@ static Sg_device *sg_alloc(struct gendis
 	sdp->device = scsidp;
 	INIT_LIST_HEAD(&sdp->sfds);
 	init_waitqueue_head(&sdp->o_excl_wait);
-	sdp->sg_tablesize = min(queue_max_hw_segments(q),
-				queue_max_phys_segments(q));
+	sdp->sg_tablesize = queue_max_segments(q);
 	sdp->index = k;
 	kref_init(&sdp->d_ref);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/sgiwd93.c linux-libre-2.6.34-gnu1/drivers/scsi/sgiwd93.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/sgiwd93.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/sgiwd93.c	2010-05-16 17:17:36.000000000 -0400
@@ -226,7 +226,7 @@ static struct scsi_host_template sgiwd93
 	.use_clustering		= DISABLE_CLUSTERING,
 };
 
-static int __init sgiwd93_probe(struct platform_device *pdev)
+static int __devinit sgiwd93_probe(struct platform_device *pdev)
 {
 	struct sgiwd93_platform_data *pd = pdev->dev.platform_data;
 	unsigned char *wdregs = pd->wdregs;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/sim710.c linux-libre-2.6.34-gnu1/drivers/scsi/sim710.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/sim710.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/sim710.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/blkdev.h>
 #include <linux/device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/sni_53c710.c linux-libre-2.6.34-gnu1/drivers/scsi/sni_53c710.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/sni_53c710.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/sni_53c710.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/mm.h>
 #include <linux/blkdev.h>
@@ -64,7 +65,7 @@ static struct scsi_host_template snirm71
 	.module		= THIS_MODULE,
 };
 
-static int __init snirm710_probe(struct platform_device *dev)
+static int __devinit snirm710_probe(struct platform_device *dev)
 {
 	unsigned long base;
 	struct NCR_700_Host_Parameters *hostdata;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/sr.c linux-libre-2.6.34-gnu1/drivers/scsi/sr.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/sr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/sr.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,7 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 #include <scsi/scsi.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/sr_ioctl.c linux-libre-2.6.34-gnu1/drivers/scsi/sr_ioctl.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/sr_ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/sr_ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
 #include <linux/blkpg.h>
 #include <linux/cdrom.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/sr_vendor.c linux-libre-2.6.34-gnu1/drivers/scsi/sr_vendor.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/sr_vendor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/sr_vendor.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/string.h>
 #include <linux/bcd.h>
 #include <linux/blkdev.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/st.c linux-libre-2.6.34-gnu1/drivers/scsi/st.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/st.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/st.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@ static const char *verstr = "20081215";
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/mtio.h>
 #include <linux/cdrom.h>
@@ -3983,8 +3984,7 @@ static int st_probe(struct device *dev)
 		return -ENODEV;
 	}
 
-	i = min(queue_max_hw_segments(SDp->request_queue),
-		queue_max_phys_segments(SDp->request_queue));
+	i = queue_max_segments(SDp->request_queue);
 	if (st_max_sg_segs < i)
 		i = st_max_sg_segs;
 	buffer = new_tape_buffer((SDp->host)->unchecked_isa_dma, i);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/stex.c linux-libre-2.6.34-gnu1/drivers/scsi/stex.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/stex.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/stex.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/pci.h>
 #include <linux/blkdev.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/sun3_NCR5380.c linux-libre-2.6.34-gnu1/drivers/scsi/sun3_NCR5380.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/sun3_NCR5380.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/sun3_NCR5380.c	2010-05-16 17:17:36.000000000 -0400
@@ -645,6 +645,7 @@ __inline__ void NCR5380_print_phase(stru
  * interrupt or bottom half.
  */
 
+#include <linux/gfp.h>
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/sun3x_esp.c linux-libre-2.6.34-gnu1/drivers/scsi/sun3x_esp.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/sun3x_esp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/sun3x_esp.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/types.h>
 #include <linux/delay.h>
 #include <linux/module.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/sun_esp.c linux-libre-2.6.34-gnu1/drivers/scsi/sun_esp.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/sun_esp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/sun_esp.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/gfp.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/tmscsim.c linux-libre-2.6.34-gnu1/drivers/scsi/tmscsim.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/tmscsim.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/tmscsim.c	2010-05-16 17:17:36.000000000 -0400
@@ -233,6 +233,7 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #include <scsi/scsi.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/u14-34f.c linux-libre-2.6.34-gnu1/drivers/scsi/u14-34f.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/u14-34f.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/u14-34f.c	2010-05-16 17:17:36.000000000 -0400
@@ -420,6 +420,7 @@
 #include <linux/init.h>
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <asm/dma.h>
 #include <asm/irq.h>
 
@@ -1070,7 +1071,7 @@ static int option_setup(char *str) {
    char *cur = str;
    int i = 1;
 
-   while (cur && isdigit(*cur) && i <= MAX_INT_PARAM) {
+   while (cur && isdigit(*cur) && i < MAX_INT_PARAM) {
       ints[i++] = simple_strtoul(cur, NULL, 0);
 
       if ((cur = strchr(cur, ',')) != NULL) cur++;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/vmw_pvscsi.c linux-libre-2.6.34-gnu1/drivers/scsi/vmw_pvscsi.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/vmw_pvscsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/vmw_pvscsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/pci.h>
 
@@ -1069,7 +1070,8 @@ static void pvscsi_free_sgls(const struc
 		free_pages((unsigned long)ctx->sgl, get_order(SGL_SIZE));
 }
 
-static int pvscsi_setup_msix(const struct pvscsi_adapter *adapter, int *irq)
+static int pvscsi_setup_msix(const struct pvscsi_adapter *adapter,
+			     unsigned int *irq)
 {
 	struct msix_entry entry = { 0, PVSCSI_VECTOR_COMPLETION };
 	int ret;
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/wd7000.c linux-libre-2.6.34-gnu1/drivers/scsi/wd7000.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/wd7000.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/wd7000.c	2010-05-16 17:17:36.000000000 -0400
@@ -171,7 +171,6 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/ioport.h>
 #include <linux/proc_fs.h>
@@ -1588,7 +1587,7 @@ static int wd7000_host_reset(struct scsi
 {
 	Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
 
-	spin_unlock_irq(SCpnt->device->host->host_lock);
+	spin_lock_irq(SCpnt->device->host->host_lock);
 
 	if (wd7000_adapter_reset(host) < 0) {
 		spin_unlock_irq(SCpnt->device->host->host_lock);
diff -druNp linux-libre-2.6.33-gnu1/drivers/scsi/zorro7xx.c linux-libre-2.6.34-gnu1/drivers/scsi/zorro7xx.c
--- linux-libre-2.6.33-gnu1/drivers/scsi/zorro7xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/scsi/zorro7xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/zorro.h>
+#include <linux/slab.h>
 
 #include <asm/amigahw.h>
 #include <asm/amigaints.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/68328serial.c linux-libre-2.6.34-gnu1/drivers/serial/68328serial.c
--- linux-libre-2.6.33-gnu1/drivers/serial/68328serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/68328serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/pm.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -153,8 +154,6 @@ static int baud_table[] = {
 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
 	9600, 19200, 38400, 57600, 115200, 0 };
 
-#define BAUD_TABLE_SIZE (sizeof(baud_table)/sizeof(baud_table[0]))
-
 /* Sets or clears DTR/RTS on the requested line */
 static inline void m68k_rtsdtr(struct m68k_serial *ss, int set)
 {
@@ -1406,10 +1405,10 @@ static void m68328_set_baud(void)
 	USTCNT = ustcnt & ~USTCNT_TXEN;
 
 again:
-	for (i = 0; i < sizeof(baud_table) / sizeof(baud_table[0]); i++)
+	for (i = 0; i < ARRAY_SIZE(baud_table); i++)
 		if (baud_table[i] == m68328_console_baud)
 			break;
-	if (i >= sizeof(baud_table) / sizeof(baud_table[0])) {
+	if (i >= ARRAY_SIZE(baud_table)) {
 		m68328_console_baud = 9600;
 		goto again;
 	}
@@ -1435,7 +1434,7 @@ int m68328_console_setup(struct console
 	if (arg)
 		n = simple_strtoul(arg,NULL,0);
 
-	for (i = 0; i < BAUD_TABLE_SIZE; i++)
+	for (i = 0; i < ARRAY_SIZE(baud_table); i++)
 		if (baud_table[i] == n)
 			break;
 	if (i < BAUD_TABLE_SIZE) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/8250.c linux-libre-2.6.34-gnu1/drivers/serial/8250.c
--- linux-libre-2.6.33-gnu1/drivers/serial/8250.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/8250.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/serial_8250.h>
 #include <linux/nmi.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -1217,12 +1218,6 @@ static void autoconfig(struct uart_8250_
 	}
 #endif
 
-#ifdef CONFIG_SERIAL_8250_AU1X00
-	/* if access method is AU, it is a 16550 with a quirk */
-	if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU)
-		up->bugs |= UART_BUG_NOMSR;
-#endif
-
 	serial_outp(up, UART_LCR, save_lcr);
 
 	if (up->capabilities != uart_config[up->port.type].flags) {
@@ -2414,6 +2409,21 @@ serial8250_set_termios(struct uart_port
 }
 
 static void
+serial8250_set_ldisc(struct uart_port *port)
+{
+	int line = port->line;
+
+	if (line >= port->state->port.tty->driver->num)
+		return;
+
+	if (port->state->port.tty->ldisc->ops->num == N_PPS) {
+		port->flags |= UPF_HARDPPS_CD;
+		serial8250_enable_ms(port);
+	} else
+		port->flags &= ~UPF_HARDPPS_CD;
+}
+
+static void
 serial8250_pm(struct uart_port *port, unsigned int state,
 	      unsigned int oldstate)
 {
@@ -2428,7 +2438,7 @@ serial8250_pm(struct uart_port *port, un
 static unsigned int serial8250_port_size(struct uart_8250_port *pt)
 {
 	if (pt->port.iotype == UPIO_AU)
-		return 0x100000;
+		return 0x1000;
 #ifdef CONFIG_ARCH_OMAP
 	if (is_omap_port(pt))
 		return 0x16 << pt->port.regshift;
@@ -2585,6 +2595,13 @@ static void serial8250_config_port(struc
 
 	if (flags & UART_CONFIG_TYPE)
 		autoconfig(up, probeflags);
+
+#ifdef CONFIG_SERIAL_8250_AU1X00
+	/* if access method is AU, it is a 16550 with a quirk */
+	if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU)
+		up->bugs |= UART_BUG_NOMSR;
+#endif
+
 	if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
 		autoconfig_irq(up);
 
@@ -2627,6 +2644,7 @@ static struct uart_ops serial8250_pops =
 	.startup	= serial8250_startup,
 	.shutdown	= serial8250_shutdown,
 	.set_termios	= serial8250_set_termios,
+	.set_ldisc	= serial8250_set_ldisc,
 	.pm		= serial8250_pm,
 	.type		= serial8250_type,
 	.release_port	= serial8250_release_port,
@@ -2689,6 +2707,15 @@ static void __init serial8250_isa_init_p
 	}
 }
 
+static void
+serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type)
+{
+	up->port.type = type;
+	up->port.fifosize = uart_config[type].fifo_size;
+	up->capabilities = uart_config[type].flags;
+	up->tx_loadsz = uart_config[type].tx_loadsz;
+}
+
 static void __init
 serial8250_register_ports(struct uart_driver *drv, struct device *dev)
 {
@@ -2705,6 +2732,10 @@ serial8250_register_ports(struct uart_dr
 		struct uart_8250_port *up = &serial8250_ports[i];
 
 		up->port.dev = dev;
+
+		if (up->port.flags & UPF_FIXED_TYPE)
+			serial8250_init_fixed_type_port(up, up->port.type);
+
 		uart_add_one_port(drv, &up->port);
 	}
 }
@@ -3117,12 +3148,8 @@ int serial8250_register_port(struct uart
 		if (port->dev)
 			uart->port.dev = port->dev;
 
-		if (port->flags & UPF_FIXED_TYPE) {
-			uart->port.type = port->type;
-			uart->port.fifosize = uart_config[port->type].fifo_size;
-			uart->capabilities = uart_config[port->type].flags;
-			uart->tx_loadsz = uart_config[port->type].tx_loadsz;
-		}
+		if (port->flags & UPF_FIXED_TYPE)
+			serial8250_init_fixed_type_port(uart, port->type);
 
 		set_io_from_upio(&uart->port);
 		/* Possibly override default I/O functions.  */
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/8250_gsc.c linux-libre-2.6.34-gnu1/drivers/serial/8250_gsc.c
--- linux-libre-2.6.33-gnu1/drivers/serial/8250_gsc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/8250_gsc.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/module.h>
 #include <linux/serial_core.h>
 #include <linux/signal.h>
-#include <linux/slab.h>
 #include <linux/types.h>
 
 #include <asm/hardware.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/8250_hp300.c linux-libre-2.6.34-gnu1/drivers/serial/8250_hp300.c
--- linux-libre-2.6.33-gnu1/drivers/serial/8250_hp300.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/8250_hp300.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 #include <linux/dio.h>
 #include <linux/console.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #include "8250.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/8250_pci.c linux-libre-2.6.34-gnu1/drivers/serial/8250_pci.c
--- linux-libre-2.6.33-gnu1/drivers/serial/8250_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/8250_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -760,7 +760,8 @@ static int pci_netmos_init(struct pci_de
 	/* subdevice 0x00PS means <P> parallel, <S> serial */
 	unsigned int num_serial = dev->subsystem_device & 0xf;
 
-	if (dev->device == PCI_DEVICE_ID_NETMOS_9901)
+	if ((dev->device == PCI_DEVICE_ID_NETMOS_9901) ||
+		(dev->device == PCI_DEVICE_ID_NETMOS_9865))
 		return 0;
 	if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM &&
 			dev->subsystem_device == 0x0299)
@@ -1479,6 +1480,7 @@ enum pci_board_num_t {
 
 	pbn_b0_bt_1_115200,
 	pbn_b0_bt_2_115200,
+	pbn_b0_bt_4_115200,
 	pbn_b0_bt_8_115200,
 
 	pbn_b0_bt_1_460800,
@@ -1703,6 +1705,12 @@ static struct pciserial_board pci_boards
 		.base_baud	= 115200,
 		.uart_offset	= 8,
 	},
+	[pbn_b0_bt_4_115200] = {
+		.flags		= FL_BASE0|FL_BASE_BARS,
+		.num_ports	= 4,
+		.base_baud	= 115200,
+		.uart_offset	= 8,
+	},
 	[pbn_b0_bt_8_115200] = {
 		.flags		= FL_BASE0|FL_BASE_BARS,
 		.num_ports	= 8,
@@ -3191,6 +3199,15 @@ static struct pci_device_id serial_pci_t
 		0x1208, 0x0004, 0, 0,
 		pbn_b0_4_921600 },
 
+	{	PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2,
+		0x1204, 0x0004, 0, 0,
+		pbn_b0_4_921600 },
+	{	PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2,
+		0x1208, 0x0004, 0, 0,
+		pbn_b0_4_921600 },
+	{	PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF3,
+		0x1208, 0x0004, 0, 0,
+		pbn_b0_4_921600 },
 	/*
 	 * Dell Remote Access Card 4 - Tim_T_Murphy@Dell.com
 	 */
@@ -3649,6 +3666,18 @@ static struct pci_device_id serial_pci_t
 		0, 0, pbn_b0_1_115200 },
 
 	/*
+	 * Best Connectivity PCI Multi I/O cards
+	 */
+
+	{	PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
+		0xA000, 0x1000,
+		0, 0, pbn_b0_1_115200 },
+
+	{	PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
+		0xA000, 0x3004,
+		0, 0, pbn_b0_bt_4_115200 },
+
+	/*
 	 * These entries match devices with class COMMUNICATION_SERIAL,
 	 * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
 	 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/8250_pnp.c linux-libre-2.6.34-gnu1/drivers/serial/8250_pnp.c
--- linux-libre-2.6.33-gnu1/drivers/serial/8250_pnp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/8250_pnp.c	2010-05-16 17:17:36.000000000 -0400
@@ -348,6 +348,8 @@ static const struct pnp_device_id pnp_de
 	{	"FUJ02E6",		0	},
 	/* Fujitsu Wacom 2FGT Tablet PC device */
 	{	"FUJ02E7",		0	},
+	/* Fujitsu Wacom 1FGT Tablet PC device */
+	{	"FUJ02E9",		0	},
 	/*
 	 * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in
 	 * disguise)
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/amba-pl010.c linux-libre-2.6.34-gnu1/drivers/serial/amba-pl010.c
--- linux-libre-2.6.33-gnu1/drivers/serial/amba-pl010.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/amba-pl010.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/serial.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
@@ -471,6 +472,20 @@ pl010_set_termios(struct uart_port *port
 	spin_unlock_irqrestore(&uap->port.lock, flags);
 }
 
+static void pl010_set_ldisc(struct uart_port *port)
+{
+	int line = port->line;
+
+	if (line >= port->state->port.tty->driver->num)
+		return;
+
+	if (port->state->port.tty->ldisc->ops->num == N_PPS) {
+		port->flags |= UPF_HARDPPS_CD;
+		pl010_enable_ms(port);
+	} else
+		port->flags &= ~UPF_HARDPPS_CD;
+}
+
 static const char *pl010_type(struct uart_port *port)
 {
 	return port->type == PORT_AMBA ? "AMBA" : NULL;
@@ -531,6 +546,7 @@ static struct uart_ops amba_pl010_pops =
 	.startup	= pl010_startup,
 	.shutdown	= pl010_shutdown,
 	.set_termios	= pl010_set_termios,
+	.set_ldisc	= pl010_set_ldisc,
 	.type		= pl010_type,
 	.release_port	= pl010_release_port,
 	.request_port	= pl010_request_port,
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/amba-pl011.c linux-libre-2.6.34-gnu1/drivers/serial/amba-pl011.c
--- linux-libre-2.6.33-gnu1/drivers/serial/amba-pl011.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/amba-pl011.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/serial.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/sizes.h>
@@ -71,6 +72,7 @@ struct uart_amba_port {
 	unsigned int		im;	/* interrupt mask */
 	unsigned int		old_status;
 	unsigned int		ifls;	/* vendor-specific */
+	bool			autorts;
 };
 
 /* There is by now at least one vendor with differing details, so handle it */
@@ -308,6 +310,11 @@ static void pl011_set_mctrl(struct uart_
 	TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1);
 	TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2);
 	TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE);
+
+	if (uap->autorts) {
+		/* We need to disable auto-RTS if we want to turn RTS off */
+		TIOCMBIT(TIOCM_RTS, UART011_CR_RTSEN);
+	}
 #undef TIOCMBIT
 
 	writew(cr, uap->port.membase + UART011_CR);
@@ -437,6 +444,7 @@ static void pl011_shutdown(struct uart_p
 	/*
 	 * disable the port
 	 */
+	uap->autorts = false;
 	writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR);
 
 	/*
@@ -456,6 +464,7 @@ static void
 pl011_set_termios(struct uart_port *port, struct ktermios *termios,
 		     struct ktermios *old)
 {
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
 	unsigned int lcr_h, old_cr;
 	unsigned long flags;
 	unsigned int baud, quot;
@@ -532,6 +541,17 @@ pl011_set_termios(struct uart_port *port
 	old_cr = readw(port->membase + UART011_CR);
 	writew(0, port->membase + UART011_CR);
 
+	if (termios->c_cflag & CRTSCTS) {
+		if (old_cr & UART011_CR_RTS)
+			old_cr |= UART011_CR_RTSEN;
+
+		old_cr |= UART011_CR_CTSEN;
+		uap->autorts = true;
+	} else {
+		old_cr &= ~(UART011_CR_CTSEN | UART011_CR_RTSEN);
+		uap->autorts = false;
+	}
+
 	/* Set baud rate */
 	writew(quot & 0x3f, port->membase + UART011_FBRD);
 	writew(quot >> 6, port->membase + UART011_IBRD);
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/atmel_serial.c linux-libre-2.6.34-gnu1/drivers/serial/atmel_serial.c
--- linux-libre-2.6.33-gnu1/drivers/serial/atmel_serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/atmel_serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -1213,6 +1213,24 @@ static int atmel_verify_port(struct uart
 	return ret;
 }
 
+#ifdef CONFIG_CONSOLE_POLL
+static int atmel_poll_get_char(struct uart_port *port)
+{
+	while (!(UART_GET_CSR(port) & ATMEL_US_RXRDY))
+		cpu_relax();
+
+	return UART_GET_CHAR(port);
+}
+
+static void atmel_poll_put_char(struct uart_port *port, unsigned char ch)
+{
+	while (!(UART_GET_CSR(port) & ATMEL_US_TXRDY))
+		cpu_relax();
+
+	UART_PUT_CHAR(port, ch);
+}
+#endif
+
 static struct uart_ops atmel_pops = {
 	.tx_empty	= atmel_tx_empty,
 	.set_mctrl	= atmel_set_mctrl,
@@ -1232,6 +1250,10 @@ static struct uart_ops atmel_pops = {
 	.config_port	= atmel_config_port,
 	.verify_port	= atmel_verify_port,
 	.pm		= atmel_serial_pm,
+#ifdef CONFIG_CONSOLE_POLL
+	.poll_get_char	= atmel_poll_get_char,
+	.poll_put_char	= atmel_poll_put_char,
+#endif
 };
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/bcm63xx_uart.c linux-libre-2.6.34-gnu1/drivers/serial/bcm63xx_uart.c
--- linux-libre-2.6.33-gnu1/drivers/serial/bcm63xx_uart.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/bcm63xx_uart.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,7 +35,7 @@
 #include <bcm63xx_regs.h>
 #include <bcm63xx_io.h>
 
-#define BCM63XX_NR_UARTS	1
+#define BCM63XX_NR_UARTS	2
 
 static struct uart_port ports[BCM63XX_NR_UARTS];
 
@@ -784,7 +784,7 @@ static struct uart_driver bcm_uart_drive
 	.dev_name	= "ttyS",
 	.major		= TTY_MAJOR,
 	.minor		= 64,
-	.nr		= 1,
+	.nr		= BCM63XX_NR_UARTS,
 	.cons		= BCM63XX_CONSOLE,
 };
 
@@ -826,11 +826,12 @@ static int __devinit bcm_uart_probe(stru
 	port->dev = &pdev->dev;
 	port->fifosize = 16;
 	port->uartclk = clk_get_rate(clk) / 2;
+	port->line = pdev->id;
 	clk_put(clk);
 
 	ret = uart_add_one_port(&bcm_uart_driver, port);
 	if (ret) {
-		kfree(port);
+		ports[pdev->id].membase = 0;
 		return ret;
 	}
 	platform_set_drvdata(pdev, port);
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/bfin_5xx.c linux-libre-2.6.34-gnu1/drivers/serial/bfin_5xx.c
--- linux-libre-2.6.33-gnu1/drivers/serial/bfin_5xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/bfin_5xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,8 @@
 
 #include <linux/module.h>
 #include <linux/ioport.h>
+#include <linux/gfp.h>
+#include <linux/io.h>
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/sysrq.h>
@@ -237,7 +239,8 @@ static void bfin_serial_rx_chars(struct
 
 #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
 	defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
-	if (kgdb_connected && kgdboc_port_line == uart->port.line)
+	if (kgdb_connected && kgdboc_port_line == uart->port.line
+		&& kgdboc_break_enabled)
 		if (ch == 0x3) {/* Ctrl + C */
 			kgdb_breakpoint();
 			return;
@@ -488,6 +491,7 @@ void bfin_serial_rx_dma_timeout(struct b
 {
 	int x_pos, pos;
 
+	dma_disable_irq(uart->tx_dma_channel);
 	dma_disable_irq(uart->rx_dma_channel);
 	spin_lock_bh(&uart->port.lock);
 
@@ -521,6 +525,7 @@ void bfin_serial_rx_dma_timeout(struct b
 	}
 
 	spin_unlock_bh(&uart->port.lock);
+	dma_enable_irq(uart->tx_dma_channel);
 	dma_enable_irq(uart->rx_dma_channel);
 
 	mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES);
@@ -746,15 +751,6 @@ static int bfin_serial_startup(struct ua
 			Status interrupt.\n");
 	}
 
-	if (uart->cts_pin >= 0) {
-		gpio_request(uart->cts_pin, DRIVER_NAME);
-		gpio_direction_output(uart->cts_pin, 1);
-	}
-	if (uart->rts_pin >= 0) {
-		gpio_request(uart->rts_pin, DRIVER_NAME);
-		gpio_direction_output(uart->rts_pin, 0);
-	}
-
 	/* CTS RTS PINs are negative assertive. */
 	UART_PUT_MCR(uart, ACTS);
 	UART_SET_IER(uart, EDSSI);
@@ -801,10 +797,6 @@ static void bfin_serial_shutdown(struct
 		gpio_free(uart->rts_pin);
 #endif
 #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
-	if (uart->cts_pin >= 0)
-		gpio_free(uart->cts_pin);
-	if (uart->rts_pin >= 0)
-		gpio_free(uart->rts_pin);
 	if (UART_GET_IER(uart) && EDSSI)
 		free_irq(uart->status_irq, uart);
 #endif
@@ -1409,8 +1401,7 @@ static int bfin_serial_remove(struct pla
 			continue;
 		uart_remove_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port);
 		bfin_serial_ports[i].port.dev = NULL;
-#if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \
-	defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS)
+#if defined(CONFIG_SERIAL_BFIN_CTSRTS)
 		gpio_free(bfin_serial_ports[i].cts_pin);
 		gpio_free(bfin_serial_ports[i].rts_pin);
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/bfin_sport_uart.c linux-libre-2.6.34-gnu1/drivers/serial/bfin_sport_uart.c
--- linux-libre-2.6.33-gnu1/drivers/serial/bfin_sport_uart.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/bfin_sport_uart.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,27 +1,11 @@
 /*
- * File:	linux/drivers/serial/bfin_sport_uart.c
- *
- * Based on:	drivers/serial/bfin_5xx.c by Aubrey Li.
- * Author:	Roy Huang <roy.huang@analog.com>
- *
- * Created:	Nov 22, 2006
- * Copyright:	(c) 2006-2007 Analog Devices Inc.
- * Description: this driver enable SPORTs on Blackfin emulate UART.
+ * Blackfin On-Chip Sport Emulated UART 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.
+ * Copyright 2006-2009 Analog Devices Inc.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Enter bugs at http://blackfin.uclinux.org/
  *
- * 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
+ * Licensed under the GPL-2 or later.
  */
 
 /*
@@ -29,42 +13,22 @@
  * http://www.analog.com/UploadedFiles/Application_Notes/399447663EE191.pdf
  * This application note describe how to implement a UART on a Sharc DSP,
  * but this driver is implemented on Blackfin Processor.
+ * Transmit Frame Sync is not used by this driver to transfer data out.
  */
 
-/* After reset, there is a prelude of low level pulse when transmit data first
- * time. No addtional pulse in following transmit.
- * According to document:
- * The SPORTs are ready to start transmitting or receiving data no later than
- * three serial clock cycles after they are enabled in the SPORTx_TCR1 or
- * SPORTx_RCR1 register. No serial clock cycles are lost from this point on.
- * The first internal frame sync will occur one frame sync delay after the
- * SPORTs are ready. External frame syncs can occur as soon as the SPORT is
- * ready.
- */
-
-/* Thanks to Axel Alatalo <axel@rubico.se> for fixing sport rx bug. Sometimes
- * sport receives data incorrectly. The following is Axel's words.
- * As EE-191, sport rx samples 3 times of the UART baudrate and takes the
- * middle smaple of every 3 samples as the data bit. For a 8-N-1 UART setting,
- * 30 samples will be required for a byte. If transmitter sends a 1/3 bit short
- * byte due to buadrate drift, then the 30th sample of a byte, this sample is
- * also the third sample of the stop bit, will happens on the immediately
- * following start bit which will be thrown away and missed. Thus since parts
- * of the startbit will be missed and the receiver will begin to drift, the
- * effect accumulates over time until synchronization is lost.
- * If only require 2 samples of the stopbit (by sampling in total 29 samples),
- * then a to short byte as in the case above will be tolerated. Then the 1/3
- * early startbit will trigger a framesync since the last read is complete
- * after only 2/3 stopbit and framesync is active during the last 1/3 looking
- * for a possible early startbit. */
+/* #define DEBUG */
 
-//#define DEBUG
+#define DRV_NAME "bfin-sport-uart"
+#define DEVICE_NAME	"ttySS"
+#define pr_fmt(fmt) DRV_NAME ": " fmt
 
 #include <linux/module.h>
 #include <linux/ioport.h>
+#include <linux/io.h>
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/sysrq.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
@@ -75,23 +39,36 @@
 
 #include "bfin_sport_uart.h"
 
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
 unsigned short bfin_uart_pin_req_sport0[] =
 	{P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \
 	 P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0};
-
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
 unsigned short bfin_uart_pin_req_sport1[] =
 	{P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \
 	P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0};
-
-#define DRV_NAME "bfin-sport-uart"
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+unsigned short bfin_uart_pin_req_sport2[] =
+	{P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS, \
+	P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+unsigned short bfin_uart_pin_req_sport3[] =
+	{P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS, \
+	P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0};
+#endif
 
 struct sport_uart_port {
 	struct uart_port	port;
-	char			*name;
-
-	int			tx_irq;
-	int			rx_irq;
 	int			err_irq;
+	unsigned short		csize;
+	unsigned short		rxmask;
+	unsigned short		txmask1;
+	unsigned short		txmask2;
+	unsigned char		stopb;
+/*	unsigned char		parib; */
 };
 
 static void sport_uart_tx_chars(struct sport_uart_port *up);
@@ -99,36 +76,42 @@ static void sport_stop_tx(struct uart_po
 
 static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value)
 {
-	pr_debug("%s value:%x\n", __func__, value);
-	/* Place a Start and Stop bit */
+	pr_debug("%s value:%x, mask1=0x%x, mask2=0x%x\n", __func__, value,
+		up->txmask1, up->txmask2);
+
+	/* Place Start and Stop bits */
 	__asm__ __volatile__ (
-		"R2 = b#01111111100;"
-		"R3 = b#10000000001;"
-		"%0 <<= 2;"
-		"%0 = %0 & R2;"
-		"%0 = %0 | R3;"
-		: "=d"(value)
-		: "d"(value)
-		: "ASTAT", "R2", "R3"
+		"%[val] <<= 1;"
+		"%[val] = %[val] & %[mask1];"
+		"%[val] = %[val] | %[mask2];"
+		: [val]"+d"(value)
+		: [mask1]"d"(up->txmask1), [mask2]"d"(up->txmask2)
+		: "ASTAT"
 	);
 	pr_debug("%s value:%x\n", __func__, value);
 
 	SPORT_PUT_TX(up, value);
 }
 
-static inline unsigned int rx_one_byte(struct sport_uart_port *up)
+static inline unsigned char rx_one_byte(struct sport_uart_port *up)
 {
-	unsigned int value, extract;
+	unsigned int value;
+	unsigned char extract;
 	u32 tmp_mask1, tmp_mask2, tmp_shift, tmp;
 
-	value = SPORT_GET_RX32(up);
-	pr_debug("%s value:%x\n", __func__, value);
+	if ((up->csize + up->stopb) > 7)
+		value = SPORT_GET_RX32(up);
+	else
+		value = SPORT_GET_RX(up);
 
-	/* Extract 8 bits data */
+	pr_debug("%s value:%x, cs=%d, mask=0x%x\n", __func__, value,
+		up->csize, up->rxmask);
+
+	/* Extract data */
 	__asm__ __volatile__ (
 		"%[extr] = 0;"
-		"%[mask1] = 0x1801(Z);"
-		"%[mask2] = 0x0300(Z);"
+		"%[mask1] = %[rxmask];"
+		"%[mask2] = 0x0200(Z);"
 		"%[shift] = 0;"
 		"LSETUP(.Lloop_s, .Lloop_e) LC0 = %[lc];"
 		".Lloop_s:"
@@ -138,9 +121,9 @@ static inline unsigned int rx_one_byte(s
 		"%[mask1] = %[mask1] - %[mask2];"
 		".Lloop_e:"
 		"%[shift] += 1;"
-		: [val]"=d"(value), [extr]"=d"(extract), [shift]"=d"(tmp_shift), [tmp]"=d"(tmp),
-		  [mask1]"=d"(tmp_mask1), [mask2]"=d"(tmp_mask2)
-		: "d"(value), [lc]"a"(8)
+		: [extr]"=&d"(extract), [shift]"=&d"(tmp_shift), [tmp]"=&d"(tmp),
+		  [mask1]"=&d"(tmp_mask1), [mask2]"=&d"(tmp_mask2)
+		: [val]"d"(value), [rxmask]"d"(up->rxmask), [lc]"a"(up->csize)
 		: "ASTAT", "LB0", "LC0", "LT0"
 	);
 
@@ -148,29 +131,28 @@ static inline unsigned int rx_one_byte(s
 	return extract;
 }
 
-static int sport_uart_setup(struct sport_uart_port *up, int sclk, int baud_rate)
+static int sport_uart_setup(struct sport_uart_port *up, int size, int baud_rate)
 {
-	int tclkdiv, tfsdiv, rclkdiv;
+	int tclkdiv, rclkdiv;
+	unsigned int sclk = get_sclk();
 
-	/* Set TCR1 and TCR2 */
-	SPORT_PUT_TCR1(up, (LATFS | ITFS | TFSR | TLSBIT | ITCLK));
-	SPORT_PUT_TCR2(up, 10);
+	/* Set TCR1 and TCR2, TFSR is not enabled for uart */
+	SPORT_PUT_TCR1(up, (ITFS | TLSBIT | ITCLK));
+	SPORT_PUT_TCR2(up, size + 1);
 	pr_debug("%s TCR1:%x, TCR2:%x\n", __func__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up));
 
 	/* Set RCR1 and RCR2 */
 	SPORT_PUT_RCR1(up, (RCKFE | LARFS | LRFS | RFSR | IRCLK));
-	SPORT_PUT_RCR2(up, 28);
+	SPORT_PUT_RCR2(up, (size + 1) * 2 - 1);
 	pr_debug("%s RCR1:%x, RCR2:%x\n", __func__, SPORT_GET_RCR1(up), SPORT_GET_RCR2(up));
 
-	tclkdiv = sclk/(2 * baud_rate) - 1;
-	tfsdiv = 12;
-	rclkdiv = sclk/(2 * baud_rate * 3) - 1;
+	tclkdiv = sclk / (2 * baud_rate) - 1;
+	rclkdiv = sclk / (2 * baud_rate * 2) - 1;
 	SPORT_PUT_TCLKDIV(up, tclkdiv);
-	SPORT_PUT_TFSDIV(up, tfsdiv);
 	SPORT_PUT_RCLKDIV(up, rclkdiv);
 	SSYNC();
-	pr_debug("%s sclk:%d, baud_rate:%d, tclkdiv:%d, tfsdiv:%d, rclkdiv:%d\n",
-			__func__, sclk, baud_rate, tclkdiv, tfsdiv, rclkdiv);
+	pr_debug("%s sclk:%d, baud_rate:%d, tclkdiv:%d, rclkdiv:%d\n",
+			__func__, sclk, baud_rate, tclkdiv, rclkdiv);
 
 	return 0;
 }
@@ -181,23 +163,29 @@ static irqreturn_t sport_uart_rx_irq(int
 	struct tty_struct *tty = up->port.state->port.tty;
 	unsigned int ch;
 
-	do {
+	spin_lock(&up->port.lock);
+
+	while (SPORT_GET_STAT(up) & RXNE) {
 		ch = rx_one_byte(up);
 		up->port.icount.rx++;
 
-		if (uart_handle_sysrq_char(&up->port, ch))
-			;
-		else
+		if (!uart_handle_sysrq_char(&up->port, ch))
 			tty_insert_flip_char(tty, ch, TTY_NORMAL);
-	} while (SPORT_GET_STAT(up) & RXNE);
+	}
 	tty_flip_buffer_push(tty);
 
+	spin_unlock(&up->port.lock);
+
 	return IRQ_HANDLED;
 }
 
 static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id)
 {
-	sport_uart_tx_chars(dev_id);
+	struct sport_uart_port *up = dev_id;
+
+	spin_lock(&up->port.lock);
+	sport_uart_tx_chars(up);
+	spin_unlock(&up->port.lock);
 
 	return IRQ_HANDLED;
 }
@@ -208,6 +196,8 @@ static irqreturn_t sport_uart_err_irq(in
 	struct tty_struct *tty = up->port.state->port.tty;
 	unsigned int stat = SPORT_GET_STAT(up);
 
+	spin_lock(&up->port.lock);
+
 	/* Overflow in RX FIFO */
 	if (stat & ROVF) {
 		up->port.icount.overrun++;
@@ -216,15 +206,16 @@ static irqreturn_t sport_uart_err_irq(in
 	}
 	/* These should not happen */
 	if (stat & (TOVF | TUVF | RUVF)) {
-		printk(KERN_ERR "SPORT Error:%s %s %s\n",
-				(stat & TOVF)?"TX overflow":"",
-				(stat & TUVF)?"TX underflow":"",
-				(stat & RUVF)?"RX underflow":"");
+		pr_err("SPORT Error:%s %s %s\n",
+		       (stat & TOVF) ? "TX overflow" : "",
+		       (stat & TUVF) ? "TX underflow" : "",
+		       (stat & RUVF) ? "RX underflow" : "");
 		SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN);
 		SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN);
 	}
 	SSYNC();
 
+	spin_unlock(&up->port.lock);
 	return IRQ_HANDLED;
 }
 
@@ -232,60 +223,37 @@ static irqreturn_t sport_uart_err_irq(in
 static int sport_startup(struct uart_port *port)
 {
 	struct sport_uart_port *up = (struct sport_uart_port *)port;
-	char buffer[20];
-	int retval;
+	int ret;
 
 	pr_debug("%s enter\n", __func__);
-	snprintf(buffer, 20, "%s rx", up->name);
-	retval = request_irq(up->rx_irq, sport_uart_rx_irq, IRQF_SAMPLE_RANDOM, buffer, up);
-	if (retval) {
-		printk(KERN_ERR "Unable to request interrupt %s\n", buffer);
-		return retval;
+	ret = request_irq(up->port.irq, sport_uart_rx_irq, 0,
+		"SPORT_UART_RX", up);
+	if (ret) {
+		dev_err(port->dev, "unable to request SPORT RX interrupt\n");
+		return ret;
 	}
 
-	snprintf(buffer, 20, "%s tx", up->name);
-	retval = request_irq(up->tx_irq, sport_uart_tx_irq, IRQF_SAMPLE_RANDOM, buffer, up);
-	if (retval) {
-		printk(KERN_ERR "Unable to request interrupt %s\n", buffer);
+	ret = request_irq(up->port.irq+1, sport_uart_tx_irq, 0,
+		"SPORT_UART_TX", up);
+	if (ret) {
+		dev_err(port->dev, "unable to request SPORT TX interrupt\n");
 		goto fail1;
 	}
 
-	snprintf(buffer, 20, "%s err", up->name);
-	retval = request_irq(up->err_irq, sport_uart_err_irq, IRQF_SAMPLE_RANDOM, buffer, up);
-	if (retval) {
-		printk(KERN_ERR "Unable to request interrupt %s\n", buffer);
+	ret = request_irq(up->err_irq, sport_uart_err_irq, 0,
+		"SPORT_UART_STATUS", up);
+	if (ret) {
+		dev_err(port->dev, "unable to request SPORT status interrupt\n");
 		goto fail2;
 	}
 
-	if (port->line) {
-		if (peripheral_request_list(bfin_uart_pin_req_sport1, DRV_NAME))
-			goto fail3;
-	} else {
-		if (peripheral_request_list(bfin_uart_pin_req_sport0, DRV_NAME))
-			goto fail3;
-	}
-
-	sport_uart_setup(up, get_sclk(), port->uartclk);
-
-	/* Enable receive interrupt */
-	SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) | RSPEN));
-	SSYNC();
-
 	return 0;
+ fail2:
+	free_irq(up->port.irq+1, up);
+ fail1:
+	free_irq(up->port.irq, up);
 
-
-fail3:
-	printk(KERN_ERR DRV_NAME
-		": Requesting Peripherals failed\n");
-
-	free_irq(up->err_irq, up);
-fail2:
-	free_irq(up->tx_irq, up);
-fail1:
-	free_irq(up->rx_irq, up);
-
-	return retval;
-
+	return ret;
 }
 
 static void sport_uart_tx_chars(struct sport_uart_port *up)
@@ -344,20 +312,17 @@ static void sport_set_mctrl(struct uart_
 static void sport_stop_tx(struct uart_port *port)
 {
 	struct sport_uart_port *up = (struct sport_uart_port *)port;
-	unsigned int stat;
 
 	pr_debug("%s enter\n", __func__);
 
-	stat = SPORT_GET_STAT(up);
-	while(!(stat & TXHRE)) {
-		udelay(1);
-		stat = SPORT_GET_STAT(up);
-	}
 	/* Although the hold register is empty, last byte is still in shift
-	 * register and not sent out yet. If baud rate is lower than default,
-	 * delay should be longer. For example, if the baud rate is 9600,
-	 * the delay must be at least 2ms by experience */
-	udelay(500);
+	 * register and not sent out yet. So, put a dummy data into TX FIFO.
+	 * Then, sport tx stops when last byte is shift out and the dummy
+	 * data is moved into the shift register.
+	 */
+	SPORT_PUT_TX(up, 0xffff);
+	while (!(SPORT_GET_STAT(up) & TXHRE))
+		cpu_relax();
 
 	SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN));
 	SSYNC();
@@ -370,6 +335,7 @@ static void sport_start_tx(struct uart_p
 	struct sport_uart_port *up = (struct sport_uart_port *)port;
 
 	pr_debug("%s enter\n", __func__);
+
 	/* Write data into SPORT FIFO before enable SPROT to transmit */
 	sport_uart_tx_chars(up);
 
@@ -403,37 +369,24 @@ static void sport_shutdown(struct uart_p
 {
 	struct sport_uart_port *up = (struct sport_uart_port *)port;
 
-	pr_debug("%s enter\n", __func__);
+	dev_dbg(port->dev, "%s enter\n", __func__);
 
 	/* Disable sport */
 	SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN));
 	SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) & ~RSPEN));
 	SSYNC();
 
-	if (port->line) {
-		peripheral_free_list(bfin_uart_pin_req_sport1);
-	} else {
-		peripheral_free_list(bfin_uart_pin_req_sport0);
-	}
-
-	free_irq(up->rx_irq, up);
-	free_irq(up->tx_irq, up);
+	free_irq(up->port.irq, up);
+	free_irq(up->port.irq+1, up);
 	free_irq(up->err_irq, up);
 }
 
-static void sport_set_termios(struct uart_port *port,
-		struct ktermios *termios, struct ktermios *old)
-{
-	pr_debug("%s enter, c_cflag:%08x\n", __func__, termios->c_cflag);
-	uart_update_timeout(port, CS8 ,port->uartclk);
-}
-
 static const char *sport_type(struct uart_port *port)
 {
 	struct sport_uart_port *up = (struct sport_uart_port *)port;
 
 	pr_debug("%s enter\n", __func__);
-	return up->name;
+	return up->port.type == PORT_BFIN_SPORT ? "BFIN-SPORT-UART" : NULL;
 }
 
 static void sport_release_port(struct uart_port *port)
@@ -461,6 +414,110 @@ static int sport_verify_port(struct uart
 	return 0;
 }
 
+static void sport_set_termios(struct uart_port *port,
+		struct ktermios *termios, struct ktermios *old)
+{
+	struct sport_uart_port *up = (struct sport_uart_port *)port;
+	unsigned long flags;
+	int i;
+
+	pr_debug("%s enter, c_cflag:%08x\n", __func__, termios->c_cflag);
+
+	switch (termios->c_cflag & CSIZE) {
+	case CS8:
+		up->csize = 8;
+		break;
+	case CS7:
+		up->csize = 7;
+		break;
+	case CS6:
+		up->csize = 6;
+		break;
+	case CS5:
+		up->csize = 5;
+		break;
+	default:
+		pr_warning("requested word length not supported\n");
+	}
+
+	if (termios->c_cflag & CSTOPB) {
+		up->stopb = 1;
+	}
+	if (termios->c_cflag & PARENB) {
+		pr_warning("PAREN bits is not supported yet\n");
+		/* up->parib = 1; */
+	}
+
+	port->read_status_mask = OE;
+	if (termios->c_iflag & INPCK)
+		port->read_status_mask |= (FE | PE);
+	if (termios->c_iflag & (BRKINT | PARMRK))
+		port->read_status_mask |= BI;
+
+	/*
+	 * Characters to ignore
+	 */
+	port->ignore_status_mask = 0;
+	if (termios->c_iflag & IGNPAR)
+		port->ignore_status_mask |= FE | PE;
+	if (termios->c_iflag & IGNBRK) {
+		port->ignore_status_mask |= BI;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (termios->c_iflag & IGNPAR)
+			port->ignore_status_mask |= OE;
+	}
+
+	/* RX extract mask */
+	up->rxmask = 0x01 | (((up->csize + up->stopb) * 2 - 1) << 0x8);
+	/* TX masks, 8 bit data and 1 bit stop for example:
+	 * mask1 = b#0111111110
+	 * mask2 = b#1000000000
+	 */
+	for (i = 0, up->txmask1 = 0; i < up->csize; i++)
+		up->txmask1 |= (1<<i);
+	up->txmask2 = (1<<i);
+	if (up->stopb) {
+		++i;
+		up->txmask2 |= (1<<i);
+	}
+	up->txmask1 <<= 1;
+	up->txmask2 <<= 1;
+	/* uart baud rate */
+	port->uartclk = uart_get_baud_rate(port, termios, old, 0, get_sclk()/16);
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	/* Disable UART */
+	SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN);
+	SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN);
+
+	sport_uart_setup(up, up->csize + up->stopb, port->uartclk);
+
+	/* driver TX line high after config, one dummy data is
+	 * necessary to stop sport after shift one byte
+	 */
+	SPORT_PUT_TX(up, 0xffff);
+	SPORT_PUT_TX(up, 0xffff);
+	SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN));
+	SSYNC();
+	while (!(SPORT_GET_STAT(up) & TXHRE))
+		cpu_relax();
+	SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN);
+	SSYNC();
+
+	/* Port speed changed, update the per-port timeout. */
+	uart_update_timeout(port, termios->c_cflag, port->uartclk);
+
+	/* Enable sport rx */
+	SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) | RSPEN);
+	SSYNC();
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
 struct uart_ops sport_uart_ops = {
 	.tx_empty	= sport_tx_empty,
 	.set_mctrl	= sport_set_mctrl,
@@ -480,138 +537,319 @@ struct uart_ops sport_uart_ops = {
 	.verify_port	= sport_verify_port,
 };
 
-static struct sport_uart_port sport_uart_ports[] = {
-	{ /* SPORT 0 */
-		.name	= "SPORT0",
-		.tx_irq = IRQ_SPORT0_TX,
-		.rx_irq = IRQ_SPORT0_RX,
-		.err_irq= IRQ_SPORT0_ERROR,
-		.port	= {
-			.type		= PORT_BFIN_SPORT,
-			.iotype		= UPIO_MEM,
-			.membase	= (void __iomem *)SPORT0_TCR1,
-			.mapbase	= SPORT0_TCR1,
-			.irq		= IRQ_SPORT0_RX,
-			.uartclk	= CONFIG_SPORT_BAUD_RATE,
-			.fifosize	= 8,
-			.ops		= &sport_uart_ops,
-			.line		= 0,
-		},
-	}, { /* SPORT 1 */
-		.name	= "SPORT1",
-		.tx_irq = IRQ_SPORT1_TX,
-		.rx_irq = IRQ_SPORT1_RX,
-		.err_irq= IRQ_SPORT1_ERROR,
-		.port	= {
-			.type		= PORT_BFIN_SPORT,
-			.iotype		= UPIO_MEM,
-			.membase	= (void __iomem *)SPORT1_TCR1,
-			.mapbase	= SPORT1_TCR1,
-			.irq		= IRQ_SPORT1_RX,
-			.uartclk	= CONFIG_SPORT_BAUD_RATE,
-			.fifosize	= 8,
-			.ops		= &sport_uart_ops,
-			.line		= 1,
-		},
+#define BFIN_SPORT_UART_MAX_PORTS 4
+
+static struct sport_uart_port *bfin_sport_uart_ports[BFIN_SPORT_UART_MAX_PORTS];
+
+#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE
+static int __init
+sport_uart_console_setup(struct console *co, char *options)
+{
+	struct sport_uart_port *up;
+	int baud = 57600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/* Check whether an invalid uart number has been specified */
+	if (co->index < 0 || co->index >= BFIN_SPORT_UART_MAX_PORTS)
+		return -ENODEV;
+
+	up = bfin_sport_uart_ports[co->index];
+	if (!up)
+		return -ENODEV;
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	return uart_set_options(&up->port, co, baud, parity, bits, flow);
+}
+
+static void sport_uart_console_putchar(struct uart_port *port, int ch)
+{
+	struct sport_uart_port *up = (struct sport_uart_port *)port;
+
+	while (SPORT_GET_STAT(up) & TXF)
+		barrier();
+
+	tx_one_byte(up, ch);
+}
+
+/*
+ * Interrupts are disabled on entering
+ */
+static void
+sport_uart_console_write(struct console *co, const char *s, unsigned int count)
+{
+	struct sport_uart_port *up = bfin_sport_uart_ports[co->index];
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	if (SPORT_GET_TCR1(up) & TSPEN)
+		uart_console_write(&up->port, s, count, sport_uart_console_putchar);
+	else {
+		/* dummy data to start sport */
+		while (SPORT_GET_STAT(up) & TXF)
+			barrier();
+		SPORT_PUT_TX(up, 0xffff);
+		/* Enable transmit, then an interrupt will generated */
+		SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN));
+		SSYNC();
+
+		uart_console_write(&up->port, s, count, sport_uart_console_putchar);
+
+		/* Although the hold register is empty, last byte is still in shift
+		 * register and not sent out yet. So, put a dummy data into TX FIFO.
+		 * Then, sport tx stops when last byte is shift out and the dummy
+		 * data is moved into the shift register.
+		 */
+		while (SPORT_GET_STAT(up) & TXF)
+			barrier();
+		SPORT_PUT_TX(up, 0xffff);
+		while (!(SPORT_GET_STAT(up) & TXHRE))
+			barrier();
+
+		/* Stop sport tx transfer */
+		SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN));
+		SSYNC();
 	}
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static struct uart_driver sport_uart_reg;
+
+static struct console sport_uart_console = {
+	.name		= DEVICE_NAME,
+	.write		= sport_uart_console_write,
+	.device		= uart_console_device,
+	.setup		= sport_uart_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+	.data		= &sport_uart_reg,
 };
 
+#define SPORT_UART_CONSOLE	(&sport_uart_console)
+#else
+#define SPORT_UART_CONSOLE	NULL
+#endif /* CONFIG_SERIAL_BFIN_SPORT_CONSOLE */
+
+
 static struct uart_driver sport_uart_reg = {
 	.owner		= THIS_MODULE,
-	.driver_name	= "SPORT-UART",
-	.dev_name	= "ttySS",
+	.driver_name	= DRV_NAME,
+	.dev_name	= DEVICE_NAME,
 	.major		= 204,
 	.minor		= 84,
-	.nr		= ARRAY_SIZE(sport_uart_ports),
-	.cons		= NULL,
+	.nr		= BFIN_SPORT_UART_MAX_PORTS,
+	.cons		= SPORT_UART_CONSOLE,
 };
 
-static int sport_uart_suspend(struct platform_device *dev, pm_message_t state)
+#ifdef CONFIG_PM
+static int sport_uart_suspend(struct device *dev)
 {
-	struct sport_uart_port *sport = platform_get_drvdata(dev);
+	struct sport_uart_port *sport = dev_get_drvdata(dev);
 
-	pr_debug("%s enter\n", __func__);
+	dev_dbg(dev, "%s enter\n", __func__);
 	if (sport)
 		uart_suspend_port(&sport_uart_reg, &sport->port);
 
 	return 0;
 }
 
-static int sport_uart_resume(struct platform_device *dev)
+static int sport_uart_resume(struct device *dev)
 {
-	struct sport_uart_port *sport = platform_get_drvdata(dev);
+	struct sport_uart_port *sport = dev_get_drvdata(dev);
 
-	pr_debug("%s enter\n", __func__);
+	dev_dbg(dev, "%s enter\n", __func__);
 	if (sport)
 		uart_resume_port(&sport_uart_reg, &sport->port);
 
 	return 0;
 }
 
-static int sport_uart_probe(struct platform_device *dev)
+static struct dev_pm_ops bfin_sport_uart_dev_pm_ops = {
+	.suspend	= sport_uart_suspend,
+	.resume		= sport_uart_resume,
+};
+#endif
+
+static int __devinit sport_uart_probe(struct platform_device *pdev)
 {
-	pr_debug("%s enter\n", __func__);
-	sport_uart_ports[dev->id].port.dev = &dev->dev;
-	uart_add_one_port(&sport_uart_reg, &sport_uart_ports[dev->id].port);
-	platform_set_drvdata(dev, &sport_uart_ports[dev->id]);
+	struct resource *res;
+	struct sport_uart_port *sport;
+	int ret = 0;
 
-	return 0;
+	dev_dbg(&pdev->dev, "%s enter\n", __func__);
+
+	if (pdev->id < 0 || pdev->id >= BFIN_SPORT_UART_MAX_PORTS) {
+		dev_err(&pdev->dev, "Wrong sport uart platform device id.\n");
+		return -ENOENT;
+	}
+
+	if (bfin_sport_uart_ports[pdev->id] == NULL) {
+		bfin_sport_uart_ports[pdev->id] =
+			kmalloc(sizeof(struct sport_uart_port), GFP_KERNEL);
+		sport = bfin_sport_uart_ports[pdev->id];
+		if (!sport) {
+			dev_err(&pdev->dev,
+				"Fail to kmalloc sport_uart_port\n");
+			return -ENOMEM;
+		}
+
+		ret = peripheral_request_list(
+			(unsigned short *)pdev->dev.platform_data, DRV_NAME);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"Fail to request SPORT peripherals\n");
+			goto out_error_free_mem;
+		}
+
+		spin_lock_init(&sport->port.lock);
+		sport->port.fifosize  = SPORT_TX_FIFO_SIZE,
+		sport->port.ops       = &sport_uart_ops;
+		sport->port.line      = pdev->id;
+		sport->port.iotype    = UPIO_MEM;
+		sport->port.flags     = UPF_BOOT_AUTOCONF;
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		if (res == NULL) {
+			dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
+			ret = -ENOENT;
+			goto out_error_free_peripherals;
+		}
+
+		sport->port.membase = ioremap(res->start,
+			res->end - res->start);
+		if (!sport->port.membase) {
+			dev_err(&pdev->dev, "Cannot map sport IO\n");
+			ret = -ENXIO;
+			goto out_error_free_peripherals;
+		}
+
+		sport->port.irq = platform_get_irq(pdev, 0);
+		if (sport->port.irq < 0) {
+			dev_err(&pdev->dev, "No sport RX/TX IRQ specified\n");
+			ret = -ENOENT;
+			goto out_error_unmap;
+		}
+
+		sport->err_irq = platform_get_irq(pdev, 1);
+		if (sport->err_irq < 0) {
+			dev_err(&pdev->dev, "No sport status IRQ specified\n");
+			ret = -ENOENT;
+			goto out_error_unmap;
+		}
+	}
+
+#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE
+	if (!is_early_platform_device(pdev)) {
+#endif
+		sport = bfin_sport_uart_ports[pdev->id];
+		sport->port.dev = &pdev->dev;
+		dev_set_drvdata(&pdev->dev, sport);
+		ret = uart_add_one_port(&sport_uart_reg, &sport->port);
+#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE
+	}
+#endif
+	if (!ret)
+		return 0;
+
+	if (sport) {
+out_error_unmap:
+		iounmap(sport->port.membase);
+out_error_free_peripherals:
+		peripheral_free_list(
+			(unsigned short *)pdev->dev.platform_data);
+out_error_free_mem:
+		kfree(sport);
+		bfin_sport_uart_ports[pdev->id] = NULL;
+	}
+
+	return ret;
 }
 
-static int sport_uart_remove(struct platform_device *dev)
+static int __devexit sport_uart_remove(struct platform_device *pdev)
 {
-	struct sport_uart_port *sport = platform_get_drvdata(dev);
+	struct sport_uart_port *sport = platform_get_drvdata(pdev);
 
-	pr_debug("%s enter\n", __func__);
-	platform_set_drvdata(dev, NULL);
+	dev_dbg(&pdev->dev, "%s enter\n", __func__);
+	dev_set_drvdata(&pdev->dev, NULL);
 
-	if (sport)
+	if (sport) {
 		uart_remove_one_port(&sport_uart_reg, &sport->port);
+		iounmap(sport->port.membase);
+		peripheral_free_list(
+			(unsigned short *)pdev->dev.platform_data);
+		kfree(sport);
+		bfin_sport_uart_ports[pdev->id] = NULL;
+	}
 
 	return 0;
 }
 
 static struct platform_driver sport_uart_driver = {
 	.probe		= sport_uart_probe,
-	.remove		= sport_uart_remove,
-	.suspend	= sport_uart_suspend,
-	.resume		= sport_uart_resume,
+	.remove		= __devexit_p(sport_uart_remove),
 	.driver		= {
 		.name	= DRV_NAME,
+#ifdef CONFIG_PM
+		.pm	= &bfin_sport_uart_dev_pm_ops,
+#endif
 	},
 };
 
+#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE
+static __initdata struct early_platform_driver early_sport_uart_driver = {
+	.class_str = DRV_NAME,
+	.pdrv = &sport_uart_driver,
+	.requested_id = EARLY_PLATFORM_ID_UNSET,
+};
+
+static int __init sport_uart_rs_console_init(void)
+{
+	early_platform_driver_register(&early_sport_uart_driver, DRV_NAME);
+
+	early_platform_driver_probe(DRV_NAME, BFIN_SPORT_UART_MAX_PORTS, 0);
+
+	register_console(&sport_uart_console);
+
+	return 0;
+}
+console_initcall(sport_uart_rs_console_init);
+#endif
+
 static int __init sport_uart_init(void)
 {
 	int ret;
 
-	pr_debug("%s enter\n", __func__);
+	pr_info("Serial: Blackfin uart over sport driver\n");
+
 	ret = uart_register_driver(&sport_uart_reg);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register %s:%d\n",
+	if (ret) {
+		pr_err("failed to register %s:%d\n",
 				sport_uart_reg.driver_name, ret);
 		return ret;
 	}
 
 	ret = platform_driver_register(&sport_uart_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register sport uart driver:%d\n", ret);
+	if (ret) {
+		pr_err("failed to register sport uart driver:%d\n", ret);
 		uart_unregister_driver(&sport_uart_reg);
 	}
 
-
-	pr_debug("%s exit\n", __func__);
 	return ret;
 }
+module_init(sport_uart_init);
 
 static void __exit sport_uart_exit(void)
 {
-	pr_debug("%s enter\n", __func__);
 	platform_driver_unregister(&sport_uart_driver);
 	uart_unregister_driver(&sport_uart_reg);
 }
-
-module_init(sport_uart_init);
 module_exit(sport_uart_exit);
 
+MODULE_AUTHOR("Sonic Zhang, Roy Huang");
+MODULE_DESCRIPTION("Blackfin serial over SPORT driver");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/bfin_sport_uart.h linux-libre-2.6.34-gnu1/drivers/serial/bfin_sport_uart.h
--- linux-libre-2.6.33-gnu1/drivers/serial/bfin_sport_uart.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/bfin_sport_uart.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,29 +1,23 @@
 /*
- * File:	linux/drivers/serial/bfin_sport_uart.h
- *
- * Based on:	include/asm-blackfin/mach-533/bfin_serial_5xx.h
- * Author:	Roy Huang <roy.huang>analog.com>
- *
- * Created:	Nov 22, 2006
- * Copyright:	(C) Analog Device Inc.
- * Description: this driver enable SPORTs on Blackfin emulate UART.
+ * Blackfin On-Chip Sport Emulated UART 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.
+ * Copyright 2006-2008 Analog Devices Inc.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Enter bugs at http://blackfin.uclinux.org/
  *
- * 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
+ * Licensed under the GPL-2 or later.
  */
 
+/*
+ * This driver and the hardware supported are in term of EE-191 of ADI.
+ * http://www.analog.com/UploadedFiles/Application_Notes/399447663EE191.pdf
+ * This application note describe how to implement a UART on a Sharc DSP,
+ * but this driver is implemented on Blackfin Processor.
+ * Transmit Frame Sync is not used by this driver to transfer data out.
+ */
+
+#ifndef _BFIN_SPORT_UART_H
+#define _BFIN_SPORT_UART_H
 
 #define OFFSET_TCR1		0x00	/* Transmit Configuration 1 Register */
 #define OFFSET_TCR2		0x04	/* Transmit Configuration 2 Register */
@@ -61,3 +55,7 @@
 #define SPORT_PUT_RCLKDIV(sport, v)	bfin_write16(((sport)->port.membase + OFFSET_RCLKDIV), v)
 #define SPORT_PUT_RFSDIV(sport, v)	bfin_write16(((sport)->port.membase + OFFSET_RFSDIV), v)
 #define SPORT_PUT_STAT(sport, v)	bfin_write16(((sport)->port.membase + OFFSET_STAT), v)
+
+#define SPORT_TX_FIFO_SIZE	8
+
+#endif /* _BFIN_SPORT_UART_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/cpm_uart/cpm_uart_cpm1.c linux-libre-2.6.34-gnu1/drivers/serial/cpm_uart/cpm_uart_cpm1.c
--- linux-libre-2.6.33-gnu1/drivers/serial/cpm_uart/cpm_uart_cpm1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/cpm_uart/cpm_uart_cpm1.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 
 #include <linux/module.h>
 #include <linux/tty.h>
+#include <linux/gfp.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/serial.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/cpm_uart/cpm_uart_cpm2.c linux-libre-2.6.34-gnu1/drivers/serial/cpm_uart/cpm_uart_cpm2.c
--- linux-libre-2.6.33-gnu1/drivers/serial/cpm_uart/cpm_uart_cpm2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/cpm_uart/cpm_uart_cpm2.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/tty.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/serial.h>
 #include <linux/console.h>
@@ -61,7 +62,7 @@ void __iomem *cpm_uart_map_pram(struct u
 	void __iomem *pram;
 	unsigned long offset;
 	struct resource res;
-	unsigned long len;
+	resource_size_t len;
 
 	/* Don't remap parameter RAM if it has already been initialized
 	 * during console setup.
@@ -74,7 +75,7 @@ void __iomem *cpm_uart_map_pram(struct u
 	if (of_address_to_resource(np, 1, &res))
 		return NULL;
 
-	len = 1 + res.end - res.start;
+	len = resource_size(&res);
 	pram = ioremap(res.start, len);
 	if (!pram)
 		return NULL;
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/icom.c linux-libre-2.6.34-gnu1/drivers/serial/icom.c
--- linux-libre-2.6.33-gnu1/drivers/serial/icom.c	2013-05-03 12:12:16.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/serial/icom.c	2013-05-03 09:51:49.000000000 -0400
@@ -751,7 +751,6 @@ static void recv_interrupt(u16 port_int_
 		trace(icom_port, "FID_STATUS", status);
 		count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
 
-                count = tty_buffer_request_room(tty, count);
 		trace(icom_port, "RCV_COUNT", count);
 
 		trace(icom_port, "REAL_COUNT", count);
@@ -1654,4 +1653,4 @@ MODULE_DESCRIPTION("IBM iSeries Serial I
 MODULE_SUPPORTED_DEVICE
     ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
 MODULE_LICENSE("GPL");
-
+/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/imx.c linux-libre-2.6.34-gnu1/drivers/serial/imx.c
--- linux-libre-2.6.33-gnu1/drivers/serial/imx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/imx.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/rational.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -119,7 +120,8 @@
 #define  MX2_UCR3_RXDMUXSEL	 (1<<2)  /* RXD Muxed Input Select, on mx2/mx3 */
 #define  UCR3_INVT  	 (1<<1)  /* Inverted Infrared transmission */
 #define  UCR3_BPEN  	 (1<<0)  /* Preset registers enable */
-#define  UCR4_CTSTL_32   (32<<10) /* CTS trigger level (32 chars) */
+#define  UCR4_CTSTL_SHF  10      /* CTS trigger level shift */
+#define  UCR4_CTSTL_MASK 0x3F    /* CTS trigger is 6 bits wide */
 #define  UCR4_INVR  	 (1<<9)  /* Inverted infrared reception */
 #define  UCR4_ENIRI 	 (1<<8)  /* Serial infrared interrupt enable */
 #define  UCR4_WKEN  	 (1<<7)  /* Wake interrupt enable */
@@ -440,7 +442,7 @@ static irqreturn_t imx_rxint(int irq, vo
 
 		temp = readl(sport->port.membase + USR2);
 		if (temp & USR2_BRCD) {
-			writel(temp | USR2_BRCD, sport->port.membase + USR2);
+			writel(USR2_BRCD, sport->port.membase + USR2);
 			if (uart_handle_break(&sport->port))
 				continue;
 		}
@@ -590,6 +592,9 @@ static int imx_setup_ufcr(struct imx_por
 	return 0;
 }
 
+/* half the RX buffer size */
+#define CTSTL 16
+
 static int imx_startup(struct uart_port *port)
 {
 	struct imx_port *sport = (struct imx_port *)port;
@@ -606,6 +611,10 @@ static int imx_startup(struct uart_port
 	if (USE_IRDA(sport))
 		temp |= UCR4_IRSC;
 
+	/* set the trigger level for CTS */
+	temp &= ~(UCR4_CTSTL_MASK<<  UCR4_CTSTL_SHF);
+	temp |= CTSTL<<  UCR4_CTSTL_SHF;
+
 	writel(temp & ~UCR4_DREN, sport->port.membase + UCR4);
 
 	if (USE_IRDA(sport)) {
@@ -1279,7 +1288,7 @@ static int serial_imx_probe(struct platf
 		sport->use_irda = 1;
 #endif
 
-	if (pdata->init) {
+	if (pdata && pdata->init) {
 		ret = pdata->init(pdev);
 		if (ret)
 			goto clkput;
@@ -1292,7 +1301,7 @@ static int serial_imx_probe(struct platf
 
 	return 0;
 deinit:
-	if (pdata->exit)
+	if (pdata && pdata->exit)
 		pdata->exit(pdev);
 clkput:
 	clk_put(sport->clk);
@@ -1321,7 +1330,7 @@ static int serial_imx_remove(struct plat
 
 	clk_disable(sport->clk);
 
-	if (pdata->exit)
+	if (pdata && pdata->exit)
 		pdata->exit(pdev);
 
 	iounmap(sport->port.membase);
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/ioc3_serial.c linux-libre-2.6.34-gnu1/drivers/serial/ioc3_serial.c
--- linux-libre-2.6.33-gnu1/drivers/serial/ioc3_serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/ioc3_serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/pci.h>
 #include <linux/serial_core.h>
 #include <linux/ioc3.h>
+#include <linux/slab.h>
 
 /*
  * Interesting things about the ioc3
@@ -1411,8 +1412,7 @@ static int receive_chars(struct uart_por
 	read_count = do_read(the_port, ch, MAX_CHARS);
 	if (read_count > 0) {
 		flip = 1;
-		read_room = tty_buffer_request_room(tty, read_count);
-		tty_insert_flip_string(tty, ch, read_room);
+		read_room = tty_insert_flip_string(tty, ch, read_count);
 		the_port->icount.rx += read_count;
 	}
 	spin_unlock_irqrestore(&the_port->lock, pflags);
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/ioc4_serial.c linux-libre-2.6.34-gnu1/drivers/serial/ioc4_serial.c
--- linux-libre-2.6.33-gnu1/drivers/serial/ioc4_serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/ioc4_serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/pci.h>
 #include <linux/ioc4.h>
 #include <linux/serial_core.h>
+#include <linux/slab.h>
 
 /*
  * interesting things about the ioc4
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/jsm/jsm_driver.c linux-libre-2.6.34-gnu1/drivers/serial/jsm/jsm_driver.c
--- linux-libre-2.6.33-gnu1/drivers/serial/jsm/jsm_driver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/jsm/jsm_driver.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
  ***********************************************************************/
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "jsm.h"
 
@@ -179,6 +180,7 @@ static int __devinit jsm_probe_one(struc
 
 	return 0;
  out_free_irq:
+	jsm_remove_uart_port(brd);
 	free_irq(brd->irq, brd);
  out_iounmap:
 	iounmap(brd->re_map_membase);
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/jsm/jsm_tty.c linux-libre-2.6.34-gnu1/drivers/serial/jsm/jsm_tty.c
--- linux-libre-2.6.33-gnu1/drivers/serial/jsm/jsm_tty.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/jsm/jsm_tty.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/serial_reg.h>
 #include <linux/delay.h>	/* For udelay */
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "jsm.h"
 
@@ -432,7 +433,7 @@ int __devinit jsm_tty_init(struct jsm_bo
 
 int jsm_uart_port_init(struct jsm_board *brd)
 {
-	int i;
+	int i, rc;
 	unsigned int line;
 	struct jsm_channel *ch;
 
@@ -467,8 +468,11 @@ int jsm_uart_port_init(struct jsm_board
 		} else
 			set_bit(line, linemap);
 		brd->channels[i]->uart_port.line = line;
-		if (uart_add_one_port (&jsm_uart_driver, &brd->channels[i]->uart_port))
-			printk(KERN_INFO "jsm: add device failed\n");
+		rc = uart_add_one_port (&jsm_uart_driver, &brd->channels[i]->uart_port);
+		if (rc){
+			printk(KERN_INFO "jsm: Port %d failed. Aborting...\n", i);
+			return rc;
+		}
 		else
 			printk(KERN_INFO "jsm: Port %d added\n", i);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/Kconfig linux-libre-2.6.34-gnu1/drivers/serial/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/serial/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -447,7 +447,7 @@ config SERIAL_CLPS711X_CONSOLE
 
 config SERIAL_SAMSUNG
 	tristate "Samsung SoC serial support"
-	depends on ARM && PLAT_S3C
+	depends on ARM && PLAT_SAMSUNG
 	select SERIAL_CORE
 	help
 	  Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
@@ -455,11 +455,18 @@ config SERIAL_SAMSUNG
 	  provide all of these ports, depending on how the serial port
 	  pins are configured.
 
+config SERIAL_SAMSUNG_UARTS_4
+	bool
+	depends on ARM && PLAT_SAMSUNG
+	default y if CPU_S3C2443
+	help
+	  Internal node for the common case of 4 Samsung compatible UARTs
+
 config SERIAL_SAMSUNG_UARTS
 	int
-	depends on ARM && PLAT_S3C
+	depends on ARM && PLAT_SAMSUNG
 	default 2 if ARCH_S3C2400
-	default 4 if ARCH_S5PC1XX || ARCH_S3C64XX || CPU_S3C2443
+	default 4 if SERIAL_SAMSUNG_UARTS_4
 	default 3
 	help
 	  Select the number of available UART ports for the Samsung S3C
@@ -526,20 +533,30 @@ config SERIAL_S3C24A0
 	  Serial port support for the Samsung S3C24A0 SoC
 
 config SERIAL_S3C6400
-	tristate "Samsung S3C6400/S3C6410 Serial port support"
-	depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410)
+	tristate "Samsung S3C6400/S3C6410/S5P6440 Seria port support"
+	depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440)
+	select SERIAL_SAMSUNG_UARTS_4
 	default y
 	help
-	  Serial port support for the Samsung S3C6400 and S3C6410
+	  Serial port support for the Samsung S3C6400, S3C6410 and S5P6440
 	  SoCs
 
 config SERIAL_S5PC100
 	tristate "Samsung S5PC100 Serial port support"
 	depends on SERIAL_SAMSUNG && CPU_S5PC100
+	select SERIAL_SAMSUNG_UARTS_4
 	default y
 	help
 	  Serial port support for the Samsung S5PC100 SoCs
 
+config SERIAL_S5PV210
+	tristate "Samsung S5PV210 Serial port support"
+	depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_S5P6442)
+	select SERIAL_SAMSUNG_UARTS_4 if CPU_S5PV210
+	default y
+	help
+	  Serial port support for Samsung's S5P Family of SoC's
+
 config SERIAL_MAX3100
 	tristate "MAX3100 support"
 	depends on SPI
@@ -996,7 +1013,7 @@ config SERIAL_IP22_ZILOG_CONSOLE
 
 config SERIAL_SH_SCI
 	tristate "SuperH SCI(F) serial port support"
-	depends on HAVE_CLK && (SUPERH || H8300)
+	depends on HAVE_CLK && (SUPERH || H8300 || ARCH_SHMOBILE)
 	select SERIAL_CORE
 
 config SERIAL_SH_SCI_NR_UARTS
@@ -1009,6 +1026,10 @@ config SERIAL_SH_SCI_CONSOLE
 	depends on SERIAL_SH_SCI=y
 	select SERIAL_CORE_CONSOLE
 
+config SERIAL_SH_SCI_DMA
+	bool "DMA support"
+	depends on SERIAL_SH_SCI && SH_DMAE && EXPERIMENTAL
+
 config SERIAL_PNX8XXX
 	bool "Enable PNX8XXX SoCs' UART Support"
 	depends on MIPS && (SOC_PNX8550 || SOC_PNX833X)
@@ -1086,12 +1107,12 @@ config SERIAL_68360
 	default y
 
 config SERIAL_PMACZILOG
-	tristate "PowerMac z85c30 ESCC support"
-	depends on PPC_OF && PPC_PMAC
+	tristate "Mac or PowerMac z85c30 ESCC support"
+	depends on (M68K && MAC) || (PPC_OF && PPC_PMAC)
 	select SERIAL_CORE
 	help
 	  This driver supports the Zilog z85C30 serial ports found on
-	  PowerMac machines.
+	  (Power)Mac machines.
 	  Say Y or M if you want to be able to these serial ports.
 
 config SERIAL_PMACZILOG_TTYS
@@ -1116,16 +1137,16 @@ config SERIAL_PMACZILOG_TTYS
 	  unable to use the 8250 module for PCMCIA or other 16C550-style
 	  UARTs.
 
-	  Say N unless you need the z85c30 ports on your powermac
+	  Say N unless you need the z85c30 ports on your (Power)Mac
 	  to appear as /dev/ttySn.
 
 config SERIAL_PMACZILOG_CONSOLE
-	bool "Console on PowerMac z85c30 serial port"
+	bool "Console on Mac or PowerMac z85c30 serial port"
 	depends on SERIAL_PMACZILOG=y
 	select SERIAL_CORE_CONSOLE
 	help
 	  If you would like to be able to use the z85c30 serial port
-	  on your PowerMac as the console, you can do so by answering
+	  on your (Power)Mac as the console, you can do so by answering
 	  Y to this option.
 
 config SERIAL_LH7A40X
@@ -1418,42 +1439,37 @@ config SERIAL_BFIN_SPORT
 	  To compile this driver as a module, choose M here: the
 	  module will be called bfin_sport_uart.
 
-choice
-	prompt "Baud rate for Blackfin SPORT UART"
-	depends on SERIAL_BFIN_SPORT
-	default SERIAL_SPORT_BAUD_RATE_57600
-	help
-	  Choose a baud rate for the SPORT UART, other uart settings are
-	  8 bit, 1 stop bit, no parity, no flow control.
-
-config SERIAL_SPORT_BAUD_RATE_115200
-	bool "115200"
-
-config SERIAL_SPORT_BAUD_RATE_57600
-	bool "57600"
+config SERIAL_BFIN_SPORT_CONSOLE
+	bool "Console on Blackfin sport emulated uart"
+	depends on SERIAL_BFIN_SPORT=y
+	select SERIAL_CORE_CONSOLE
 
-config SERIAL_SPORT_BAUD_RATE_38400
-	bool "38400"
+config SERIAL_BFIN_SPORT0_UART
+	bool "Enable UART over SPORT0"
+	depends on SERIAL_BFIN_SPORT && !(BF542 || BF542M || BF544 || BF544M)
+	help
+	  Enable UART over SPORT0
 
-config SERIAL_SPORT_BAUD_RATE_19200
-	bool "19200"
+config SERIAL_BFIN_SPORT1_UART
+	bool "Enable UART over SPORT1"
+	depends on SERIAL_BFIN_SPORT
+	help
+	  Enable UART over SPORT1
 
-config SERIAL_SPORT_BAUD_RATE_9600
-	bool "9600"
-endchoice
+config SERIAL_BFIN_SPORT2_UART
+	bool "Enable UART over SPORT2"
+	depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539)
+	help
+	  Enable UART over SPORT2
 
-config SPORT_BAUD_RATE
-	int
-	depends on SERIAL_BFIN_SPORT
-	default 115200 if (SERIAL_SPORT_BAUD_RATE_115200)
-	default 57600 if (SERIAL_SPORT_BAUD_RATE_57600)
-	default 38400 if (SERIAL_SPORT_BAUD_RATE_38400)
-	default 19200 if (SERIAL_SPORT_BAUD_RATE_19200)
-	default 9600 if (SERIAL_SPORT_BAUD_RATE_9600)
+config SERIAL_BFIN_SPORT3_UART
+	bool "Enable UART over SPORT3"
+	depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539)
+	help
+	  Enable UART over SPORT3
 
 config SERIAL_TIMBERDALE
 	tristate "Support for timberdale UART"
-	depends on MFD_TIMBERDALE
 	select SERIAL_CORE
 	---help---
 	Add support for UART controller on timberdale.
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/Makefile linux-libre-2.6.34-gnu1/drivers/serial/Makefile
--- linux-libre-2.6.33-gnu1/drivers/serial/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -45,6 +45,7 @@ obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.
 obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o
 obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o
 obj-$(CONFIG_SERIAL_S5PC100) += s3c6400.o
+obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o
 obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
 obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
 obj-$(CONFIG_SERIAL_MUX) += mux.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/max3100.c linux-libre-2.6.34-gnu1/drivers/serial/max3100.c
--- linux-libre-2.6.33-gnu1/drivers/serial/max3100.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/max3100.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@
 #define MAX_MAX3100 4
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/serial_core.h>
 #include <linux/serial.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/mcf.c linux-libre-2.6.34-gnu1/drivers/serial/mcf.c
--- linux-libre-2.6.33-gnu1/drivers/serial/mcf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/mcf.c	2010-05-16 17:17:36.000000000 -0400
@@ -263,6 +263,7 @@ static void mcf_set_termios(struct uart_
 	}
 
 	spin_lock_irqsave(&port->lock, flags);
+	uart_update_timeout(port, termios->c_cflag, baud);
 	writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
 	writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
 	writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR);
@@ -379,6 +380,7 @@ static irqreturn_t mcf_interrupt(int irq
 static void mcf_config_port(struct uart_port *port, int flags)
 {
 	port->type = PORT_MCF;
+	port->fifosize = MCFUART_TXFIFOSIZE;
 
 	/* Clear mask, so no surprise interrupts. */
 	writeb(0, port->membase + MCFUART_UIMR);
@@ -424,7 +426,7 @@ static int mcf_verify_port(struct uart_p
 /*
  *	Define the basic serial functions we support.
  */
-static struct uart_ops mcf_uart_ops = {
+static const struct uart_ops mcf_uart_ops = {
 	.tx_empty	= mcf_tx_empty,
 	.get_mctrl	= mcf_get_mctrl,
 	.set_mctrl	= mcf_set_mctrl,
@@ -443,7 +445,7 @@ static struct uart_ops mcf_uart_ops = {
 	.verify_port	= mcf_verify_port,
 };
 
-static struct mcf_uart mcf_ports[3];
+static struct mcf_uart mcf_ports[4];
 
 #define	MCF_MAXPORTS	ARRAY_SIZE(mcf_ports)
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/mpc52xx_uart.c linux-libre-2.6.34-gnu1/drivers/serial/mpc52xx_uart.c
--- linux-libre-2.6.33-gnu1/drivers/serial/mpc52xx_uart.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/mpc52xx_uart.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,39 +29,6 @@
  * kind, whether express or implied.
  */
 
-/* Platform device Usage :
- *
- * Since PSCs can have multiple function, the correct driver for each one
- * is selected by calling mpc52xx_match_psc_function(...). The function
- * handled by this driver is "uart".
- *
- * The driver init all necessary registers to place the PSC in uart mode without
- * DCD. However, the pin multiplexing aren't changed and should be set either
- * by the bootloader or in the platform init code.
- *
- * The idx field must be equal to the PSC index (e.g. 0 for PSC1, 1 for PSC2,
- * and so on). So the PSC1 is mapped to /dev/ttyPSC0, PSC2 to /dev/ttyPSC1 and
- * so on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly
- * fpr the console code : without this 1:1 mapping, at early boot time, when we
- * are parsing the kernel args console=ttyPSC?, we wouldn't know which PSC it
- * will be mapped to.
- */
-
-/* OF Platform device Usage :
- *
- * This driver is only used for PSCs configured in uart mode.  The device
- * tree will have a node for each PSC with "mpc52xx-psc-uart" in the compatible
- * list.
- *
- * By default, PSC devices are enumerated in the order they are found.  However
- * a particular PSC number can be forces by adding 'device_no = <port#>'
- * to the device node.
- *
- * The driver init all necessary registers to place the PSC in uart mode without
- * DCD. However, the pin multiplexing aren't changed and should be set either
- * by the bootloader or in the platform init code.
- */
-
 #undef DEBUG
 
 #include <linux/device.h>
@@ -74,6 +41,7 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/clk.h>
 
 #include <asm/mpc52xx.h>
 #include <asm/mpc52xx_psc.h>
@@ -113,6 +81,7 @@ static void mpc52xx_uart_of_enumerate(vo
 
 /* Forward declaration of the interruption handling routine */
 static irqreturn_t mpc52xx_uart_int(int irq, void *dev_id);
+static irqreturn_t mpc5xxx_uart_process_int(struct uart_port *port);
 
 
 /* Simple macro to test if a port is console or not. This one is taken
@@ -145,6 +114,11 @@ struct psc_ops {
 	void		(*cw_disable_ints)(struct uart_port *port);
 	void		(*cw_restore_ints)(struct uart_port *port);
 	unsigned long	(*getuartclk)(void *p);
+	int		(*clock)(struct uart_port *port, int enable);
+	int		(*fifoc_init)(void);
+	void		(*fifoc_uninit)(void);
+	void		(*get_irq)(struct uart_port *, struct device_node *);
+	irqreturn_t	(*handle_irq)(struct uart_port *port);
 };
 
 #ifdef CONFIG_PPC_MPC52xx
@@ -256,6 +230,18 @@ static unsigned long mpc52xx_getuartclk(
 	return mpc5xxx_get_bus_frequency(p) / 2;
 }
 
+static void mpc52xx_psc_get_irq(struct uart_port *port, struct device_node *np)
+{
+	port->irqflags = IRQF_DISABLED;
+	port->irq = irq_of_parse_and_map(np, 0);
+}
+
+/* 52xx specific interrupt handler. The caller holds the port lock */
+static irqreturn_t mpc52xx_psc_handle_irq(struct uart_port *port)
+{
+	return mpc5xxx_uart_process_int(port);
+}
+
 static struct psc_ops mpc52xx_psc_ops = {
 	.fifo_init = mpc52xx_psc_fifo_init,
 	.raw_rx_rdy = mpc52xx_psc_raw_rx_rdy,
@@ -273,14 +259,32 @@ static struct psc_ops mpc52xx_psc_ops =
 	.cw_disable_ints = mpc52xx_psc_cw_disable_ints,
 	.cw_restore_ints = mpc52xx_psc_cw_restore_ints,
 	.getuartclk = mpc52xx_getuartclk,
+	.get_irq = mpc52xx_psc_get_irq,
+	.handle_irq = mpc52xx_psc_handle_irq,
 };
 
 #endif /* CONFIG_MPC52xx */
 
 #ifdef CONFIG_PPC_MPC512x
 #define FIFO_512x(port) ((struct mpc512x_psc_fifo __iomem *)(PSC(port)+1))
+
+/* PSC FIFO Controller for mpc512x */
+struct psc_fifoc {
+	u32 fifoc_cmd;
+	u32 fifoc_int;
+	u32 fifoc_dma;
+	u32 fifoc_axe;
+	u32 fifoc_debug;
+};
+
+static struct psc_fifoc __iomem *psc_fifoc;
+static unsigned int psc_fifoc_irq;
+
 static void mpc512x_psc_fifo_init(struct uart_port *port)
 {
+	/* /32 prescaler */
+	out_be16(&PSC(port)->mpc52xx_psc_clock_select, 0xdd00);
+
 	out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_RESET_SLICE);
 	out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_ENABLE_SLICE);
 	out_be32(&FIFO_512x(port)->txalarm, 1);
@@ -393,6 +397,160 @@ static unsigned long mpc512x_getuartclk(
 	return mpc5xxx_get_bus_frequency(p);
 }
 
+#define DEFAULT_FIFO_SIZE 16
+
+static unsigned int __init get_fifo_size(struct device_node *np,
+					 char *fifo_name)
+{
+	const unsigned int *fp;
+
+	fp = of_get_property(np, fifo_name, NULL);
+	if (fp)
+		return *fp;
+
+	pr_warning("no %s property in %s node, defaulting to %d\n",
+		   fifo_name, np->full_name, DEFAULT_FIFO_SIZE);
+
+	return DEFAULT_FIFO_SIZE;
+}
+
+#define FIFOC(_base) ((struct mpc512x_psc_fifo __iomem *) \
+		    ((u32)(_base) + sizeof(struct mpc52xx_psc)))
+
+/* Init PSC FIFO Controller */
+static int __init mpc512x_psc_fifoc_init(void)
+{
+	struct device_node *np;
+	void __iomem *psc;
+	unsigned int tx_fifo_size;
+	unsigned int rx_fifo_size;
+	int fifobase = 0; /* current fifo address in 32 bit words */
+
+	np = of_find_compatible_node(NULL, NULL,
+				     "fsl,mpc5121-psc-fifo");
+	if (!np) {
+		pr_err("%s: Can't find FIFOC node\n", __func__);
+		return -ENODEV;
+	}
+
+	psc_fifoc = of_iomap(np, 0);
+	if (!psc_fifoc) {
+		pr_err("%s: Can't map FIFOC\n", __func__);
+		return -ENODEV;
+	}
+
+	psc_fifoc_irq = irq_of_parse_and_map(np, 0);
+	of_node_put(np);
+	if (psc_fifoc_irq == NO_IRQ) {
+		pr_err("%s: Can't get FIFOC irq\n", __func__);
+		iounmap(psc_fifoc);
+		return -ENODEV;
+	}
+
+	for_each_compatible_node(np, NULL, "fsl,mpc5121-psc-uart") {
+		tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size");
+		rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size");
+
+		/* size in register is in 4 byte units */
+		tx_fifo_size /= 4;
+		rx_fifo_size /= 4;
+		if (!tx_fifo_size)
+			tx_fifo_size = 1;
+		if (!rx_fifo_size)
+			rx_fifo_size = 1;
+
+		psc = of_iomap(np, 0);
+		if (!psc) {
+			pr_err("%s: Can't map %s device\n",
+				__func__, np->full_name);
+			continue;
+		}
+
+		/* FIFO space is 4KiB, check if requested size is available */
+		if ((fifobase + tx_fifo_size + rx_fifo_size) > 0x1000) {
+			pr_err("%s: no fifo space available for %s\n",
+				__func__, np->full_name);
+			iounmap(psc);
+			/*
+			 * chances are that another device requests less
+			 * fifo space, so we continue.
+			 */
+			continue;
+		}
+		/* set tx and rx fifo size registers */
+		out_be32(&FIFOC(psc)->txsz, (fifobase << 16) | tx_fifo_size);
+		fifobase += tx_fifo_size;
+		out_be32(&FIFOC(psc)->rxsz, (fifobase << 16) | rx_fifo_size);
+		fifobase += rx_fifo_size;
+
+		/* reset and enable the slices */
+		out_be32(&FIFOC(psc)->txcmd, 0x80);
+		out_be32(&FIFOC(psc)->txcmd, 0x01);
+		out_be32(&FIFOC(psc)->rxcmd, 0x80);
+		out_be32(&FIFOC(psc)->rxcmd, 0x01);
+
+		iounmap(psc);
+	}
+
+	return 0;
+}
+
+static void __exit mpc512x_psc_fifoc_uninit(void)
+{
+	iounmap(psc_fifoc);
+}
+
+/* 512x specific interrupt handler. The caller holds the port lock */
+static irqreturn_t mpc512x_psc_handle_irq(struct uart_port *port)
+{
+	unsigned long fifoc_int;
+	int psc_num;
+
+	/* Read pending PSC FIFOC interrupts */
+	fifoc_int = in_be32(&psc_fifoc->fifoc_int);
+
+	/* Check if it is an interrupt for this port */
+	psc_num = (port->mapbase & 0xf00) >> 8;
+	if (test_bit(psc_num, &fifoc_int) ||
+	    test_bit(psc_num + 16, &fifoc_int))
+		return mpc5xxx_uart_process_int(port);
+
+	return IRQ_NONE;
+}
+
+static int mpc512x_psc_clock(struct uart_port *port, int enable)
+{
+	struct clk *psc_clk;
+	int psc_num;
+	char clk_name[10];
+
+	if (uart_console(port))
+		return 0;
+
+	psc_num = (port->mapbase & 0xf00) >> 8;
+	snprintf(clk_name, sizeof(clk_name), "psc%d_clk", psc_num);
+	psc_clk = clk_get(port->dev, clk_name);
+	if (IS_ERR(psc_clk)) {
+		dev_err(port->dev, "Failed to get PSC clock entry!\n");
+		return -ENODEV;
+	}
+
+	dev_dbg(port->dev, "%s %sable\n", clk_name, enable ? "en" : "dis");
+
+	if (enable)
+		clk_enable(psc_clk);
+	else
+		clk_disable(psc_clk);
+
+	return 0;
+}
+
+static void mpc512x_psc_get_irq(struct uart_port *port, struct device_node *np)
+{
+	port->irqflags = IRQF_SHARED;
+	port->irq = psc_fifoc_irq;
+}
+
 static struct psc_ops mpc512x_psc_ops = {
 	.fifo_init = mpc512x_psc_fifo_init,
 	.raw_rx_rdy = mpc512x_psc_raw_rx_rdy,
@@ -410,6 +568,11 @@ static struct psc_ops mpc512x_psc_ops =
 	.cw_disable_ints = mpc512x_psc_cw_disable_ints,
 	.cw_restore_ints = mpc512x_psc_cw_restore_ints,
 	.getuartclk = mpc512x_getuartclk,
+	.clock = mpc512x_psc_clock,
+	.fifoc_init = mpc512x_psc_fifoc_init,
+	.fifoc_uninit = mpc512x_psc_fifoc_uninit,
+	.get_irq = mpc512x_psc_get_irq,
+	.handle_irq = mpc512x_psc_handle_irq,
 };
 #endif
 
@@ -519,10 +682,15 @@ mpc52xx_uart_startup(struct uart_port *p
 	struct mpc52xx_psc __iomem *psc = PSC(port);
 	int ret;
 
+	if (psc_ops->clock) {
+		ret = psc_ops->clock(port, 1);
+		if (ret)
+			return ret;
+	}
+
 	/* Request IRQ */
 	ret = request_irq(port->irq, mpc52xx_uart_int,
-		IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
-		"mpc52xx_psc_uart", port);
+			  port->irqflags, "mpc52xx_psc_uart", port);
 	if (ret)
 		return ret;
 
@@ -553,6 +721,9 @@ mpc52xx_uart_shutdown(struct uart_port *
 	port->read_status_mask = 0;
 	out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
 
+	if (psc_ops->clock)
+		psc_ops->clock(port, 0);
+
 	/* Release interrupt */
 	free_irq(port->irq, port);
 }
@@ -851,15 +1022,12 @@ mpc52xx_uart_int_tx_chars(struct uart_po
 }
 
 static irqreturn_t
-mpc52xx_uart_int(int irq, void *dev_id)
+mpc5xxx_uart_process_int(struct uart_port *port)
 {
-	struct uart_port *port = dev_id;
 	unsigned long pass = ISR_PASS_LIMIT;
 	unsigned int keepgoing;
 	u8 status;
 
-	spin_lock(&port->lock);
-
 	/* While we have stuff to do, we continue */
 	do {
 		/* If we don't find anything to do, we stop */
@@ -886,11 +1054,23 @@ mpc52xx_uart_int(int irq, void *dev_id)
 
 	} while (keepgoing);
 
-	spin_unlock(&port->lock);
-
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t
+mpc52xx_uart_int(int irq, void *dev_id)
+{
+	struct uart_port *port = dev_id;
+	irqreturn_t ret;
+
+	spin_lock(&port->lock);
+
+	ret = psc_ops->handle_irq(port);
+
+	spin_unlock(&port->lock);
+
+	return ret;
+}
 
 /* ======================================================================== */
 /* Console ( if applicable )                                                */
@@ -1152,7 +1332,7 @@ mpc52xx_uart_of_probe(struct of_device *
 		return -EINVAL;
 	}
 
-	port->irq = irq_of_parse_and_map(op->node, 0);
+	psc_ops->get_irq(port, op->node);
 	if (port->irq == NO_IRQ) {
 		dev_dbg(&op->dev, "Could not get irq\n");
 		return -EINVAL;
@@ -1163,10 +1343,8 @@ mpc52xx_uart_of_probe(struct of_device *
 
 	/* Add the port to the uart sub-system */
 	ret = uart_add_one_port(&mpc52xx_uart_driver, port);
-	if (ret) {
-		irq_dispose_mapping(port->irq);
+	if (ret)
 		return ret;
-	}
 
 	dev_set_drvdata(&op->dev, (void *)port);
 	return 0;
@@ -1178,10 +1356,8 @@ mpc52xx_uart_of_remove(struct of_device
 	struct uart_port *port = dev_get_drvdata(&op->dev);
 	dev_set_drvdata(&op->dev, NULL);
 
-	if (port) {
+	if (port)
 		uart_remove_one_port(&mpc52xx_uart_driver, port);
-		irq_dispose_mapping(port->irq);
-	}
 
 	return 0;
 }
@@ -1288,6 +1464,15 @@ mpc52xx_uart_init(void)
 
 	mpc52xx_uart_of_enumerate();
 
+	/*
+	 * Map the PSC FIFO Controller and init if on MPC512x.
+	 */
+	if (psc_ops && psc_ops->fifoc_init) {
+		ret = psc_ops->fifoc_init();
+		if (ret)
+			return ret;
+	}
+
 	ret = of_register_platform_driver(&mpc52xx_uart_of_driver);
 	if (ret) {
 		printk(KERN_ERR "%s: of_register_platform_driver failed (%i)\n",
@@ -1302,6 +1487,9 @@ mpc52xx_uart_init(void)
 static void __exit
 mpc52xx_uart_exit(void)
 {
+	if (psc_ops->fifoc_uninit)
+		psc_ops->fifoc_uninit();
+
 	of_unregister_platform_driver(&mpc52xx_uart_of_driver);
 	uart_unregister_driver(&mpc52xx_uart_driver);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/mpsc.c linux-libre-2.6.34-gnu1/drivers/serial/mpsc.c
--- linux-libre-2.6.33-gnu1/drivers/serial/mpsc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/mpsc.c	2010-05-16 17:17:36.000000000 -0400
@@ -70,6 +70,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/mv643xx.h>
 #include <linux/platform_device.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/msm_serial.c linux-libre-2.6.34-gnu1/drivers/serial/msm_serial.c
--- linux-libre-2.6.33-gnu1/drivers/serial/msm_serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/msm_serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -691,6 +691,7 @@ static int __init msm_serial_probe(struc
 	struct msm_port *msm_port;
 	struct resource *resource;
 	struct uart_port *port;
+	int irq;
 
 	if (unlikely(pdev->id < 0 || pdev->id >= UART_NR))
 		return -ENXIO;
@@ -711,9 +712,10 @@ static int __init msm_serial_probe(struc
 		return -ENXIO;
 	port->mapbase = resource->start;
 
-	port->irq = platform_get_irq(pdev, 0);
-	if (unlikely(port->irq < 0))
+	irq = platform_get_irq(pdev, 0);
+	if (unlikely(irq < 0))
 		return -ENXIO;
+	port->irq = irq;
 
 	platform_set_drvdata(pdev, port);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/mux.c linux-libre-2.6.34-gnu1/drivers/serial/mux.c
--- linux-libre-2.6.33-gnu1/drivers/serial/mux.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/mux.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/init.h>
 #include <linux/serial.h>
 #include <linux/console.h>
-#include <linux/slab.h>
 #include <linux/delay.h> /* for udelay */
 #include <linux/device.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/of_serial.c linux-libre-2.6.34-gnu1/drivers/serial/of_serial.c
--- linux-libre-2.6.33-gnu1/drivers/serial/of_serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/of_serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 #include <linux/of_platform.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/pmac_zilog.c linux-libre-2.6.34-gnu1/drivers/serial/pmac_zilog.c
--- linux-libre-2.6.33-gnu1/drivers/serial/pmac_zilog.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/pmac_zilog.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,7 +54,6 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/console.h>
-#include <linux/slab.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
 #include <linux/bitops.h>
@@ -63,11 +62,17 @@
 #include <asm/sections.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+
+#ifdef CONFIG_PPC_PMAC
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
 #include <asm/dbdma.h>
 #include <asm/macio.h>
+#else
+#include <linux/platform_device.h>
+#define of_machine_is_compatible(x) (0)
+#endif
 
 #if defined (CONFIG_SERIAL_PMACZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 #define SUPPORT_SYSRQ
@@ -83,11 +88,9 @@
 
 static char version[] __initdata = "pmac_zilog: 0.6 (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
 MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
-MODULE_DESCRIPTION("Driver for the PowerMac serial ports.");
+MODULE_DESCRIPTION("Driver for the Mac and PowerMac serial ports.");
 MODULE_LICENSE("GPL");
 
-#define PWRDBG(fmt, arg...)	printk(KERN_DEBUG fmt , ## arg)
-
 #ifdef CONFIG_SERIAL_PMACZILOG_TTYS
 #define PMACZILOG_MAJOR		TTY_MAJOR
 #define PMACZILOG_MINOR		64
@@ -153,8 +156,8 @@ static void pmz_load_zsregs(struct uart_
 	write_zsreg(uap, R10, regs[R10]);
 
 	/* Set TX/RX controls sans the enable bits.  */
-       	write_zsreg(uap, R3, regs[R3] & ~RxENABLE);
-       	write_zsreg(uap, R5, regs[R5] & ~TxENABLE);
+	write_zsreg(uap, R3, regs[R3] & ~RxENABLE);
+	write_zsreg(uap, R5, regs[R5] & ~TxENABLE);
 
 	/* now set R7 "prime" on ESCC */
 	write_zsreg(uap, R15, regs[R15] | EN85C30);
@@ -205,7 +208,7 @@ static void pmz_load_zsregs(struct uart_
  */
 static void pmz_maybe_update_regs(struct uart_pmac_port *uap)
 {
-       	if (!ZS_REGS_HELD(uap)) {
+	if (!ZS_REGS_HELD(uap)) {
 		if (ZS_TX_ACTIVE(uap)) {
 			uap->flags |= PMACZILOG_FLAG_REGS_HELD;
 		} else {
@@ -281,7 +284,7 @@ static struct tty_struct *pmz_receive_ch
 			spin_lock(&uap->port.lock);
 			if (swallow)
 				goto next_char;
- 		}
+		}
 #endif /* CONFIG_MAGIC_SYSRQ && CONFIG_SERIAL_CORE_CONSOLE */
 
 		/* A real serial line, record the character and status.  */
@@ -317,7 +320,7 @@ static struct tty_struct *pmz_receive_ch
 
 		if (uap->port.ignore_status_mask == 0xff ||
 		    (r1 & uap->port.ignore_status_mask) == 0) {
-		    	tty_insert_flip_char(tty, ch, flag);
+			tty_insert_flip_char(tty, ch, flag);
 		}
 		if (r1 & Rx_OVR)
 			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
@@ -341,7 +344,7 @@ static struct tty_struct *pmz_receive_ch
 	uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
 	write_zsreg(uap, R1, uap->curregs[R1]);
 	zssync(uap);
-	dev_err(&uap->dev->ofdev.dev, "pmz: rx irq flood !\n");
+	pmz_error("pmz: rx irq flood !\n");
 	return tty;
 }
 
@@ -470,47 +473,47 @@ static irqreturn_t pmz_interrupt(int irq
 
 	uap_a = pmz_get_port_A(uap);
 	uap_b = uap_a->mate;
-       
-       	spin_lock(&uap_a->port.lock);
+
+	spin_lock(&uap_a->port.lock);
 	r3 = read_zsreg(uap_a, R3);
 
 #ifdef DEBUG_HARD
 	pmz_debug("irq, r3: %x\n", r3);
 #endif
-       	/* Channel A */
+	/* Channel A */
 	tty = NULL;
-       	if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
+	if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
 		write_zsreg(uap_a, R0, RES_H_IUS);
 		zssync(uap_a);		
-       		if (r3 & CHAEXT)
-       			pmz_status_handle(uap_a);
+		if (r3 & CHAEXT)
+			pmz_status_handle(uap_a);
 		if (r3 & CHARxIP)
 			tty = pmz_receive_chars(uap_a);
-       		if (r3 & CHATxIP)
-       			pmz_transmit_chars(uap_a);
-	        rc = IRQ_HANDLED;
-       	}
-       	spin_unlock(&uap_a->port.lock);
+		if (r3 & CHATxIP)
+			pmz_transmit_chars(uap_a);
+		rc = IRQ_HANDLED;
+	}
+	spin_unlock(&uap_a->port.lock);
 	if (tty != NULL)
 		tty_flip_buffer_push(tty);
 
 	if (uap_b->node == NULL)
 		goto out;
 
-       	spin_lock(&uap_b->port.lock);
+	spin_lock(&uap_b->port.lock);
 	tty = NULL;
 	if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
 		write_zsreg(uap_b, R0, RES_H_IUS);
 		zssync(uap_b);
-       		if (r3 & CHBEXT)
-       			pmz_status_handle(uap_b);
-       	       	if (r3 & CHBRxIP)
-       			tty = pmz_receive_chars(uap_b);
-       		if (r3 & CHBTxIP)
-       			pmz_transmit_chars(uap_b);
-	       	rc = IRQ_HANDLED;
-       	}
-       	spin_unlock(&uap_b->port.lock);
+		if (r3 & CHBEXT)
+			pmz_status_handle(uap_b);
+		if (r3 & CHBRxIP)
+			tty = pmz_receive_chars(uap_b);
+		if (r3 & CHBTxIP)
+			pmz_transmit_chars(uap_b);
+		rc = IRQ_HANDLED;
+	}
+	spin_unlock(&uap_b->port.lock);
 	if (tty != NULL)
 		tty_flip_buffer_push(tty);
 
@@ -718,7 +721,7 @@ static void pmz_enable_ms(struct uart_po
 
 		if (ZS_IS_ASLEEP(uap))
 			return;
-		/* NOTE: Not subject to 'transmitter active' rule.  */ 
+		/* NOTE: Not subject to 'transmitter active' rule. */
 		write_zsreg(uap, R15, uap->curregs[R15]);
 	}
 }
@@ -748,15 +751,19 @@ static void pmz_break_ctl(struct uart_po
 	if (new_reg != uap->curregs[R5]) {
 		uap->curregs[R5] = new_reg;
 
-		/* NOTE: Not subject to 'transmitter active' rule.  */ 
-		if (ZS_IS_ASLEEP(uap))
+		/* NOTE: Not subject to 'transmitter active' rule. */
+		if (ZS_IS_ASLEEP(uap)) {
+			spin_unlock_irqrestore(&port->lock, flags);
 			return;
+		}
 		write_zsreg(uap, R5, uap->curregs[R5]);
 	}
 
 	spin_unlock_irqrestore(&port->lock, flags);
 }
 
+#ifdef CONFIG_PPC_PMAC
+
 /*
  * Turn power on or off to the SCC and associated stuff
  * (port drivers, modem, IR port, etc.)
@@ -792,6 +799,15 @@ static int pmz_set_scc_power(struct uart
 	return delay;
 }
 
+#else
+
+static int pmz_set_scc_power(struct uart_pmac_port *uap, int state)
+{
+	return 0;
+}
+
+#endif /* !CONFIG_PPC_PMAC */
+
 /*
  * FixZeroBug....Works around a bug in the SCC receving channel.
  * Inspired from Darwin code, 15 Sept. 2000  -DanM
@@ -908,7 +924,6 @@ static int __pmz_startup(struct uart_pma
 	/* Remember status for DCD/CTS changes */
 	uap->prev_status = read_zsreg(uap, R0);
 
-
 	return pwr_delay;
 }
 
@@ -955,9 +970,9 @@ static int pmz_startup(struct uart_port
 	}	
 
 	pmz_get_port_A(uap)->flags |= PMACZILOG_FLAG_IS_IRQ_ON;
-	if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED, "PowerMac Zilog", uap)) {
-		dev_err(&uap->dev->ofdev.dev,
-			"Unable to register zs interrupt handler.\n");
+	if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED,
+			"SCC", uap)) {
+		pmz_error("Unable to register zs interrupt handler.\n");
 		pmz_set_scc_power(uap, 0);
 		mutex_unlock(&pmz_irq_mutex);
 		return -ENXIO;
@@ -983,7 +998,7 @@ static int pmz_startup(struct uart_port
 	if (!ZS_IS_EXTCLK(uap))
 		uap->curregs[R1] |= EXT_INT_ENAB;
 	write_zsreg(uap, R1, uap->curregs[R1]);
-       	spin_unlock_irqrestore(&port->lock, flags);
+	spin_unlock_irqrestore(&port->lock, flags);
 
 	pmz_debug("pmz: startup() done.\n");
 
@@ -1003,7 +1018,7 @@ static void pmz_shutdown(struct uart_por
 	mutex_lock(&pmz_irq_mutex);
 
 	/* Release interrupt handler */
-       	free_irq(uap->port.irq, uap);
+	free_irq(uap->port.irq, uap);
 
 	spin_lock_irqsave(&port->lock, flags);
 
@@ -1051,7 +1066,6 @@ static void pmz_convert_to_zs(struct uar
 {
 	int brg;
 
-
 	/* Switch to external clocking for IrDA high clock rates. That
 	 * code could be re-used for Midi interfaces with different
 	 * multipliers
@@ -1198,7 +1212,7 @@ static void pmz_irda_setup(struct uart_p
 	while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0
 	       || (read_zsreg(uap, R1) & ALL_SNT) == 0) {
 		if (--t <= 0) {
-			dev_err(&uap->dev->ofdev.dev, "transmitter didn't drain\n");
+			pmz_error("transmitter didn't drain\n");
 			return;
 		}
 		udelay(10);
@@ -1214,7 +1228,7 @@ static void pmz_irda_setup(struct uart_p
 		read_zsdata(uap);
 		mdelay(10);
 		if (--t <= 0) {
-			dev_err(&uap->dev->ofdev.dev, "receiver didn't drain\n");
+			pmz_error("receiver didn't drain\n");
 			return;
 		}
 	}
@@ -1223,20 +1237,19 @@ static void pmz_irda_setup(struct uart_p
 	uap->curregs[R5] |= DTR;
 	write_zsreg(uap, R5, uap->curregs[R5]);
 	zssync(uap);
-       	mdelay(1);
+	mdelay(1);
 
 	/* Switch SCC to 19200 */
 	pmz_convert_to_zs(uap, CS8, 0, 19200);		
 	pmz_load_zsregs(uap, uap->curregs);
-       	mdelay(1);
+	mdelay(1);
 
 	/* Write get_version command byte */
 	write_zsdata(uap, 1);
 	t = 5000;
 	while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) {
 		if (--t <= 0) {
-			dev_err(&uap->dev->ofdev.dev,
-				"irda_setup timed out on get_version byte\n");
+			pmz_error("irda_setup timed out on get_version byte\n");
 			goto out;
 		}
 		udelay(10);
@@ -1244,8 +1257,7 @@ static void pmz_irda_setup(struct uart_p
 	version = read_zsdata(uap);
 
 	if (version < 4) {
-		dev_info(&uap->dev->ofdev.dev, "IrDA: dongle version %d not supported\n",
-			 version);
+		pmz_info("IrDA: dongle version %d not supported\n", version);
 		goto out;
 	}
 
@@ -1254,18 +1266,16 @@ static void pmz_irda_setup(struct uart_p
 	t = 5000;
 	while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) {
 		if (--t <= 0) {
-			dev_err(&uap->dev->ofdev.dev,
-				"irda_setup timed out on speed mode byte\n");
+			pmz_error("irda_setup timed out on speed mode byte\n");
 			goto out;
 		}
 		udelay(10);
 	}
 	t = read_zsdata(uap);
 	if (t != cmdbyte)
-		dev_err(&uap->dev->ofdev.dev,
-			"irda_setup speed mode byte = %x (%x)\n", t, cmdbyte);
+		pmz_error("irda_setup speed mode byte = %x (%x)\n", t, cmdbyte);
 
-	dev_info(&uap->dev->ofdev.dev, "IrDA setup for %ld bps, dongle version: %d\n",
+	pmz_info("IrDA setup for %ld bps, dongle version: %d\n",
 		 *baud, version);
 
 	(void)read_zsdata(uap);
@@ -1415,7 +1425,7 @@ static void pmz_poll_put_char(struct uar
 	write_zsdata(uap, c);
 }
 
-#endif
+#endif /* CONFIG_CONSOLE_POLL */
 
 static struct uart_ops pmz_pops = {
 	.tx_empty	=	pmz_tx_empty,
@@ -1440,6 +1450,8 @@ static struct uart_ops pmz_pops = {
 #endif
 };
 
+#ifdef CONFIG_PPC_PMAC
+
 /*
  * Setup one port structure after probing, HW is down at this point,
  * Unlike sunzilog, we don't need to pre-init the spinlock as we don't
@@ -1463,7 +1475,7 @@ static int __init pmz_init_port(struct u
 		return -ENODEV;
 	uap->port.mapbase = r_ports.start;
 	uap->port.membase = ioremap(uap->port.mapbase, 0x1000);
-      
+
 	uap->control_reg = uap->port.membase;
 	uap->data_reg = uap->control_reg + 0x10;
 	
@@ -1590,7 +1602,7 @@ static void pmz_dispose_port(struct uart
 }
 
 /*
- * Called upon match with an escc node in the devive-tree.
+ * Called upon match with an escc node in the device-tree.
  */
 static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match)
 {
@@ -1812,7 +1824,7 @@ static int __init pmz_probe(void)
 		pmz_ports[count].node		= node_a;
 		pmz_ports[count+1].node		= node_b;
 		pmz_ports[count].port.line	= count;
-		pmz_ports[count+1].port.line   	= count+1;
+		pmz_ports[count+1].port.line	= count+1;
 
 		/*
 		 * Setup the ports for real
@@ -1836,6 +1848,88 @@ next:
 	return 0;
 }
 
+#else
+
+extern struct platform_device scc_a_pdev, scc_b_pdev;
+
+static int __init pmz_init_port(struct uart_pmac_port *uap)
+{
+	struct resource *r_ports;
+	int irq;
+
+	r_ports = platform_get_resource(uap->node, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(uap->node, 0);
+	if (!r_ports || !irq)
+		return -ENODEV;
+
+	uap->port.mapbase  = r_ports->start;
+	uap->port.membase  = (unsigned char __iomem *) r_ports->start;
+	uap->port.iotype   = UPIO_MEM;
+	uap->port.irq      = irq;
+	uap->port.uartclk  = ZS_CLOCK;
+	uap->port.fifosize = 1;
+	uap->port.ops      = &pmz_pops;
+	uap->port.type     = PORT_PMAC_ZILOG;
+	uap->port.flags    = 0;
+
+	uap->control_reg   = uap->port.membase;
+	uap->data_reg      = uap->control_reg + 4;
+	uap->port_type     = 0;
+
+	pmz_convert_to_zs(uap, CS8, 0, 9600);
+
+	return 0;
+}
+
+static int __init pmz_probe(void)
+{
+	int err;
+
+	pmz_ports_count = 0;
+
+	pmz_ports[0].mate      = &pmz_ports[1];
+	pmz_ports[0].port.line = 0;
+	pmz_ports[0].flags     = PMACZILOG_FLAG_IS_CHANNEL_A;
+	pmz_ports[0].node      = &scc_a_pdev;
+	err = pmz_init_port(&pmz_ports[0]);
+	if (err)
+		return err;
+	pmz_ports_count++;
+
+	pmz_ports[1].mate      = &pmz_ports[0];
+	pmz_ports[1].port.line = 1;
+	pmz_ports[1].flags     = 0;
+	pmz_ports[1].node      = &scc_b_pdev;
+	err = pmz_init_port(&pmz_ports[1]);
+	if (err)
+		return err;
+	pmz_ports_count++;
+
+	return 0;
+}
+
+static void pmz_dispose_port(struct uart_pmac_port *uap)
+{
+	memset(uap, 0, sizeof(struct uart_pmac_port));
+}
+
+static int __init pmz_attach(struct platform_device *pdev)
+{
+	int i;
+
+	for (i = 0; i < pmz_ports_count; i++)
+		if (pmz_ports[i].node == pdev)
+			return 0;
+	return -ENODEV;
+}
+
+static int __exit pmz_detach(struct platform_device *pdev)
+{
+	return 0;
+}
+
+#endif /* !CONFIG_PPC_PMAC */
+
 #ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
 
 static void pmz_console_write(struct console *con, const char *s, unsigned int count);
@@ -1896,28 +1990,41 @@ err_out:
 	return rc;
 }
 
+#ifdef CONFIG_PPC_PMAC
+
 static struct of_device_id pmz_match[] = 
 {
 	{
-	.name 		= "ch-a",
+	.name		= "ch-a",
 	},
 	{
-	.name 		= "ch-b",
+	.name		= "ch-b",
 	},
 	{},
 };
 MODULE_DEVICE_TABLE (of, pmz_match);
 
-static struct macio_driver pmz_driver = 
-{
+static struct macio_driver pmz_driver = {
 	.name 		= "pmac_zilog",
 	.match_table	= pmz_match,
 	.probe		= pmz_attach,
 	.remove		= pmz_detach,
 	.suspend	= pmz_suspend,
-       	.resume		= pmz_resume,
+	.resume		= pmz_resume,
+};
+
+#else
+
+static struct platform_driver pmz_driver = {
+	.remove		= __exit_p(pmz_detach),
+	.driver		= {
+		.name		= "scc",
+		.owner		= THIS_MODULE,
+	},
 };
 
+#endif /* !CONFIG_PPC_PMAC */
+
 static int __init init_pmz(void)
 {
 	int rc, i;
@@ -1952,19 +2059,27 @@ static int __init init_pmz(void)
 			pmz_dispose_port(&pmz_ports[i]);
 		return rc;
 	}
-	
+
 	/*
 	 * Then we register the macio driver itself
 	 */
+#ifdef CONFIG_PPC_PMAC
 	return macio_register_driver(&pmz_driver);
+#else
+	return platform_driver_probe(&pmz_driver, pmz_attach);
+#endif
 }
 
 static void __exit exit_pmz(void)
 {
 	int i;
 
+#ifdef CONFIG_PPC_PMAC
 	/* Get rid of macio-driver (detach from macio) */
 	macio_unregister_driver(&pmz_driver);
+#else
+	platform_driver_unregister(&pmz_driver);
+#endif
 
 	for (i = 0; i < pmz_ports_count; i++) {
 		struct uart_pmac_port *uport = &pmz_ports[i];
@@ -2031,10 +2146,10 @@ static int __init pmz_console_setup(stru
 	/*
 	 * XServe's default to 57600 bps
 	 */
-	if (machine_is_compatible("RackMac1,1")
-	    || machine_is_compatible("RackMac1,2")
-	    || machine_is_compatible("MacRISC4"))
-	 	baud = 57600;
+	if (of_machine_is_compatible("RackMac1,1")
+	    || of_machine_is_compatible("RackMac1,2")
+	    || of_machine_is_compatible("MacRISC4"))
+		baud = 57600;
 
 	/*
 	 * Check whether an invalid uart number has been specified, and
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/pmac_zilog.h linux-libre-2.6.34-gnu1/drivers/serial/pmac_zilog.h
--- linux-libre-2.6.33-gnu1/drivers/serial/pmac_zilog.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/pmac_zilog.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,15 @@
 #ifndef __PMAC_ZILOG_H__
 #define __PMAC_ZILOG_H__
 
-#define pmz_debug(fmt,arg...)	dev_dbg(&uap->dev->ofdev.dev, fmt, ## arg)
+#ifdef CONFIG_PPC_PMAC
+#define pmz_debug(fmt, arg...)	dev_dbg(&uap->dev->ofdev.dev, fmt, ## arg)
+#define pmz_error(fmt, arg...)	dev_err(&uap->dev->ofdev.dev, fmt, ## arg)
+#define pmz_info(fmt, arg...)	dev_info(&uap->dev->ofdev.dev, fmt, ## arg)
+#else
+#define pmz_debug(fmt, arg...)	dev_dbg(&uap->node->dev, fmt, ## arg)
+#define pmz_error(fmt, arg...)	dev_err(&uap->node->dev, fmt, ## arg)
+#define pmz_info(fmt, arg...)	dev_info(&uap->node->dev, fmt, ## arg)
+#endif
 
 /*
  * At most 2 ESCCs with 2 ports each
@@ -17,6 +25,7 @@ struct uart_pmac_port {
 	struct uart_port		port;
 	struct uart_pmac_port		*mate;
 
+#ifdef CONFIG_PPC_PMAC
 	/* macio_dev for the escc holding this port (maybe be null on
 	 * early inited port)
 	 */
@@ -25,6 +34,9 @@ struct uart_pmac_port {
 	 * of "escc" node (ie. ch-a or ch-b)
 	 */
 	struct device_node		*node;
+#else
+	struct platform_device		*node;
+#endif
 
 	/* Port type as obtained from device tree (IRDA, modem, ...) */
 	int				port_type;
@@ -55,10 +67,12 @@ struct uart_pmac_port {
 	volatile u8			__iomem *control_reg;
 	volatile u8			__iomem *data_reg;
 
+#ifdef CONFIG_PPC_PMAC
 	unsigned int			tx_dma_irq;
 	unsigned int			rx_dma_irq;
 	volatile struct dbdma_regs	__iomem *tx_dma_regs;
 	volatile struct dbdma_regs	__iomem *rx_dma_regs;
+#endif
 
 	struct ktermios			termios_cache;
 };
@@ -113,7 +127,7 @@ static inline void zssync(struct uart_pm
 #define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2))
 #define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2)
 
-#define ZS_CLOCK         3686400 	/* Z8530 RTxC input clock rate */
+#define ZS_CLOCK         3686400	/* Z8530 RTxC input clock rate */
 
 /* The Zilog register set */
 
@@ -171,7 +185,7 @@ static inline void zssync(struct uart_pm
 
 /* Write Register 3 */
 
-#define	RxENABLE       	0x1	/* Rx Enable */
+#define	RxENABLE	0x1	/* Rx Enable */
 #define	SYNC_L_INH	0x2	/* Sync Character Load Inhibit */
 #define	ADD_SM		0x4	/* Address Search Mode (SDLC) */
 #define	RxCRC_ENAB	0x8	/* Rx CRC Enable */
@@ -185,7 +199,7 @@ static inline void zssync(struct uart_pm
 
 /* Write Register 4 */
 
-#define	PAR_ENAB       	0x1	/* Parity Enable */
+#define	PAR_ENAB	0x1	/* Parity Enable */
 #define	PAR_EVEN	0x2	/* Parity Even/Odd* */
 
 #define	SYNC_ENAB	0	/* Sync Modes Enable */
@@ -210,7 +224,7 @@ static inline void zssync(struct uart_pm
 #define	TxCRC_ENAB	0x1	/* Tx CRC Enable */
 #define	RTS		0x2	/* RTS */
 #define	SDLC_CRC	0x4	/* SDLC/CRC-16 */
-#define	TxENABLE       	0x8	/* Tx Enable */
+#define	TxENABLE	0x8	/* Tx Enable */
 #define	SND_BRK		0x10	/* Send Break */
 #define	Tx5		0x0	/* Tx 5 bits (or less)/character */
 #define	Tx7		0x20	/* Tx 7 bits/character */
@@ -372,11 +386,11 @@ static inline void zssync(struct uart_pm
 #define ZS_TX_ACTIVE(UP)		((UP)->flags & PMACZILOG_FLAG_TX_ACTIVE)
 #define ZS_WANTS_MODEM_STATUS(UP)	((UP)->flags & PMACZILOG_FLAG_MODEM_STATUS)
 #define ZS_IS_IRDA(UP)			((UP)->flags & PMACZILOG_FLAG_IS_IRDA)
-#define ZS_IS_INTMODEM(UP)	       	((UP)->flags & PMACZILOG_FLAG_IS_INTMODEM)
+#define ZS_IS_INTMODEM(UP)		((UP)->flags & PMACZILOG_FLAG_IS_INTMODEM)
 #define ZS_HAS_DMA(UP)			((UP)->flags & PMACZILOG_FLAG_HAS_DMA)
-#define ZS_IS_ASLEEP(UP)       		((UP)->flags & PMACZILOG_FLAG_IS_ASLEEP)
-#define ZS_IS_OPEN(UP)       		((UP)->flags & PMACZILOG_FLAG_IS_OPEN)
-#define ZS_IS_IRQ_ON(UP)       		((UP)->flags & PMACZILOG_FLAG_IS_IRQ_ON)
-#define ZS_IS_EXTCLK(UP)       		((UP)->flags & PMACZILOG_FLAG_IS_EXTCLK)
+#define ZS_IS_ASLEEP(UP)		((UP)->flags & PMACZILOG_FLAG_IS_ASLEEP)
+#define ZS_IS_OPEN(UP)			((UP)->flags & PMACZILOG_FLAG_IS_OPEN)
+#define ZS_IS_IRQ_ON(UP)		((UP)->flags & PMACZILOG_FLAG_IS_IRQ_ON)
+#define ZS_IS_EXTCLK(UP)		((UP)->flags & PMACZILOG_FLAG_IS_EXTCLK)
 
 #endif /* __PMAC_ZILOG_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/pxa.c linux-libre-2.6.34-gnu1/drivers/serial/pxa.c
--- linux-libre-2.6.33-gnu1/drivers/serial/pxa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/pxa.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,7 @@
 #include <linux/serial_core.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 struct uart_pxa_port {
 	struct uart_port        port;
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/s3c2412.c linux-libre-2.6.34-gnu1/drivers/serial/s3c2412.c
--- linux-libre-2.6.33-gnu1/drivers/serial/s3c2412.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/s3c2412.c	2010-05-16 17:17:36.000000000 -0400
@@ -102,6 +102,7 @@ static struct s3c24xx_uart_info s3c2412_
 	.name		= "Samsung S3C2412 UART",
 	.type		= PORT_S3C2412,
 	.fifosize	= 64,
+	.has_divslot	= 1,
 	.rx_fifomask	= S3C2440_UFSTAT_RXMASK,
 	.rx_fifoshift	= S3C2440_UFSTAT_RXSHIFT,
 	.rx_fifofull	= S3C2440_UFSTAT_RXFULL,
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/s5pv210.c linux-libre-2.6.34-gnu1/drivers/serial/s5pv210.c
--- linux-libre-2.6.33-gnu1/drivers/serial/s5pv210.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/s5pv210.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,154 @@
+/* linux/drivers/serial/s5pv210.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Based on drivers/serial/s3c6400.c
+ *
+ * Driver for Samsung S5PV210 SoC UARTs.
+ *
+ * This program is free software; you can 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/ioport.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <plat/regs-serial.h>
+#include "samsung.h"
+
+static int s5pv210_serial_setsource(struct uart_port *port,
+					struct s3c24xx_uart_clksrc *clk)
+{
+	unsigned long ucon = rd_regl(port, S3C2410_UCON);
+
+	if (strcmp(clk->name, "pclk") == 0)
+		ucon &= ~S5PV210_UCON_CLKMASK;
+	else if (strcmp(clk->name, "uclk1") == 0)
+		ucon |= S5PV210_UCON_CLKMASK;
+	else {
+		printk(KERN_ERR "unknown clock source %s\n", clk->name);
+		return -EINVAL;
+	}
+
+	wr_regl(port, S3C2410_UCON, ucon);
+	return 0;
+}
+
+
+static int s5pv210_serial_getsource(struct uart_port *port,
+					struct s3c24xx_uart_clksrc *clk)
+{
+	u32 ucon = rd_regl(port, S3C2410_UCON);
+
+	clk->divisor = 1;
+
+	switch (ucon & S5PV210_UCON_CLKMASK) {
+	case S5PV210_UCON_PCLK:
+		clk->name = "pclk";
+		break;
+	case S5PV210_UCON_UCLK:
+		clk->name = "uclk1";
+		break;
+	}
+
+	return 0;
+}
+
+static int s5pv210_serial_resetport(struct uart_port *port,
+					struct s3c2410_uartcfg *cfg)
+{
+	unsigned long ucon = rd_regl(port, S3C2410_UCON);
+
+	ucon &= S5PV210_UCON_CLKMASK;
+	wr_regl(port, S3C2410_UCON,  ucon | cfg->ucon);
+	wr_regl(port, S3C2410_ULCON, cfg->ulcon);
+
+	/* reset both fifos */
+	wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
+	wr_regl(port, S3C2410_UFCON, cfg->ufcon);
+
+	return 0;
+}
+
+#define S5PV210_UART_DEFAULT_INFO(fifo_size)			\
+		.name		= "Samsung S5PV210 UART0",	\
+		.type		= PORT_S3C6400,			\
+		.fifosize	= fifo_size,			\
+		.has_divslot	= 1,				\
+		.rx_fifomask	= S5PV210_UFSTAT_RXMASK,	\
+		.rx_fifoshift	= S5PV210_UFSTAT_RXSHIFT,	\
+		.rx_fifofull	= S5PV210_UFSTAT_RXFULL,	\
+		.tx_fifofull	= S5PV210_UFSTAT_TXFULL,	\
+		.tx_fifomask	= S5PV210_UFSTAT_TXMASK,	\
+		.tx_fifoshift	= S5PV210_UFSTAT_TXSHIFT,	\
+		.get_clksrc	= s5pv210_serial_getsource,	\
+		.set_clksrc	= s5pv210_serial_setsource,	\
+		.reset_port	= s5pv210_serial_resetport
+
+static struct s3c24xx_uart_info s5p_port_fifo256 = {
+	S5PV210_UART_DEFAULT_INFO(256),
+};
+
+static struct s3c24xx_uart_info s5p_port_fifo64 = {
+	S5PV210_UART_DEFAULT_INFO(64),
+};
+
+static struct s3c24xx_uart_info s5p_port_fifo16 = {
+	S5PV210_UART_DEFAULT_INFO(16),
+};
+
+static struct s3c24xx_uart_info *s5p_uart_inf[] = {
+	[0] = &s5p_port_fifo256,
+	[1] = &s5p_port_fifo64,
+	[2] = &s5p_port_fifo16,
+	[3] = &s5p_port_fifo16,
+};
+
+/* device management */
+static int s5p_serial_probe(struct platform_device *pdev)
+{
+	return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]);
+}
+
+static struct platform_driver s5p_serial_drv = {
+	.probe		= s5p_serial_probe,
+	.remove		= __devexit_p(s3c24xx_serial_remove),
+	.driver		= {
+		.name	= "s5pv210-uart",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init s5pv210_serial_console_init(void)
+{
+	return s3c24xx_serial_initconsole(&s5p_serial_drv, s5p_uart_inf);
+}
+
+console_initcall(s5pv210_serial_console_init);
+
+static int __init s5p_serial_init(void)
+{
+	return s3c24xx_serial_init(&s5p_serial_drv, *s5p_uart_inf);
+}
+
+static void __exit s5p_serial_exit(void)
+{
+	platform_driver_unregister(&s5p_serial_drv);
+}
+
+module_init(s5p_serial_init);
+module_exit(s5p_serial_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:s5pv210-uart");
+MODULE_DESCRIPTION("Samsung S5PV210 UART Driver support");
+MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/samsung.c linux-libre-2.6.34-gnu1/drivers/serial/samsung.c
--- linux-libre-2.6.33-gnu1/drivers/serial/samsung.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/samsung.c	2010-05-16 17:17:36.000000000 -0400
@@ -1271,7 +1271,7 @@ s3c24xx_serial_console_txrdy(struct uart
 	unsigned long ufstat, utrstat;
 
 	if (ufcon & S3C2410_UFCON_FIFOMODE) {
-		/* fifo mode - check ammount of data in fifo registers... */
+		/* fifo mode - check amount of data in fifo registers... */
 
 		ufstat = rd_regl(port, S3C2410_UFSTAT);
 		return (ufstat & info->tx_fifofull) ? 0 : 1;
@@ -1374,7 +1374,7 @@ s3c24xx_serial_get_options(struct uart_p
  * data.
 */
 
-static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info *info)
+static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info **info)
 {
 	struct s3c24xx_uart_port *ptr = s3c24xx_serial_ports;
 	struct platform_device **platdev_ptr;
@@ -1385,7 +1385,7 @@ static int s3c24xx_serial_init_ports(str
 	platdev_ptr = s3c24xx_uart_devs;
 
 	for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++, ptr++, platdev_ptr++) {
-		s3c24xx_serial_init_port(ptr, info, *platdev_ptr);
+		s3c24xx_serial_init_port(ptr, info[i], *platdev_ptr);
 	}
 
 	return 0;
@@ -1451,7 +1451,7 @@ static struct console s3c24xx_serial_con
 };
 
 int s3c24xx_serial_initconsole(struct platform_driver *drv,
-			       struct s3c24xx_uart_info *info)
+			       struct s3c24xx_uart_info **info)
 
 {
 	struct platform_device *dev = s3c24xx_uart_devs[0];
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/samsung.h linux-libre-2.6.34-gnu1/drivers/serial/samsung.h
--- linux-libre-2.6.33-gnu1/drivers/serial/samsung.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/samsung.h	2010-05-16 17:17:36.000000000 -0400
@@ -75,19 +75,24 @@ extern int s3c24xx_serial_probe(struct p
 extern int __devexit s3c24xx_serial_remove(struct platform_device *dev);
 
 extern int s3c24xx_serial_initconsole(struct platform_driver *drv,
-				      struct s3c24xx_uart_info *uart);
+				      struct s3c24xx_uart_info **uart);
 
 extern int s3c24xx_serial_init(struct platform_driver *drv,
 			       struct s3c24xx_uart_info *info);
 
 #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
 
-#define s3c24xx_console_init(__drv, __inf)			\
-static int __init s3c_serial_console_init(void)			\
-{								\
-	return s3c24xx_serial_initconsole(__drv, __inf);	\
-}								\
-								\
+#define s3c24xx_console_init(__drv, __inf)				\
+static int __init s3c_serial_console_init(void)				\
+{									\
+	struct s3c24xx_uart_info *uinfo[CONFIG_SERIAL_SAMSUNG_UARTS];	\
+	int i;								\
+									\
+	for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)		\
+		uinfo[i] = __inf;					\
+	return s3c24xx_serial_initconsole(__drv, uinfo);		\
+}									\
+									\
 console_initcall(s3c_serial_console_init)
 
 #else
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/serial_cs.c linux-libre-2.6.34-gnu1/drivers/serial/serial_cs.c
--- linux-libre-2.6.33-gnu1/drivers/serial/serial_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/serial_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -105,6 +105,10 @@ struct serial_cfg_mem {
  * manfid 0x0160, 0x0104
  * This card appears to have a 14.7456MHz clock.
  */
+/* Generic Modem: MD55x (GPRS/EDGE) have
+ * Elan VPU16551 UART with 14.7456MHz oscillator
+ * manfid 0x015D, 0x4C45
+ */
 static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
 {
 	port->uartclk = 14745600;
@@ -196,6 +200,11 @@ static const struct serial_quirk quirks[
 		.multi	= -1,
 		.setup	= quirk_setup_brainboxes_0104,
 	}, {
+		.manfid	= 0x015D,
+		.prodid	= 0x4C45,
+		.multi	= -1,
+		.setup	= quirk_setup_brainboxes_0104,
+	}, {
 		.manfid	= MANFID_IBM,
 		.prodid	= ~0,
 		.multi	= -1,
@@ -696,11 +705,11 @@ static int serial_config(struct pcmcia_d
 		info->multi = info->quirk->multi;
 
 	if (info->multi > 1)
-		multi_config(link);
+		i = multi_config(link);
 	else
-		simple_config(link);
+		i = simple_config(link);
 
-	if (info->ndev == 0)
+	if (i || info->ndev == 0)
 		goto failed;
 
 	/*
@@ -715,6 +724,7 @@ static int serial_config(struct pcmcia_d
 	return 0;
 
 failed:
+	dev_warn(&link->dev, "serial_cs: failed to initialize\n");
 	serial_remove(link);
 	return -ENODEV;
 }
@@ -744,6 +754,7 @@ static struct pcmcia_device_id serial_id
 	PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29),
 	PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719),
 	PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4),
+	PCMCIA_PFC_DEVICE_PROD_ID12(1, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e),
 	PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
 	PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c),
 	PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/serial_ks8695.c linux-libre-2.6.34-gnu1/drivers/serial/serial_ks8695.c
--- linux-libre-2.6.33-gnu1/drivers/serial/serial_ks8695.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/serial_ks8695.c	2010-05-16 17:17:36.000000000 -0400
@@ -650,6 +650,7 @@ static struct console ks8695_console = {
 
 static int __init ks8695_console_init(void)
 {
+	add_preferred_console(SERIAL_KS8695_DEVNAME, 0, NULL);
 	register_console(&ks8695_console);
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/sh-sci.c linux-libre-2.6.34-gnu1/drivers/serial/sh-sci.c
--- linux-libre-2.6.33-gnu1/drivers/serial/sh-sci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/sh-sci.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,6 +48,9 @@
 #include <linux/ctype.h>
 #include <linux/err.h>
 #include <linux/list.h>
+#include <linux/dmaengine.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_SUPERH
 #include <asm/sh_bios.h>
@@ -84,6 +87,27 @@ struct sci_port {
 	struct clk		*dclk;
 
 	struct list_head	node;
+	struct dma_chan			*chan_tx;
+	struct dma_chan			*chan_rx;
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+	struct device			*dma_dev;
+	enum sh_dmae_slave_chan_id	slave_tx;
+	enum sh_dmae_slave_chan_id	slave_rx;
+	struct dma_async_tx_descriptor	*desc_tx;
+	struct dma_async_tx_descriptor	*desc_rx[2];
+	dma_cookie_t			cookie_tx;
+	dma_cookie_t			cookie_rx[2];
+	dma_cookie_t			active_rx;
+	struct scatterlist		sg_tx;
+	unsigned int			sg_len_tx;
+	struct scatterlist		sg_rx[2];
+	size_t				buf_len_rx;
+	struct sh_dmae_slave		param_tx;
+	struct sh_dmae_slave		param_rx;
+	struct work_struct		work_tx;
+	struct work_struct		work_rx;
+	struct timer_list		rx_timer;
+#endif
 };
 
 struct sh_sci_priv {
@@ -269,29 +293,44 @@ static inline void sci_init_pins(struct
     defined(CONFIG_CPU_SUBTYPE_SH7780) || \
     defined(CONFIG_CPU_SUBTYPE_SH7785) || \
     defined(CONFIG_CPU_SUBTYPE_SH7786)
-static inline int scif_txroom(struct uart_port *port)
+static int scif_txfill(struct uart_port *port)
 {
-	return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff);
+	return sci_in(port, SCTFDR) & 0xff;
 }
 
-static inline int scif_rxroom(struct uart_port *port)
+static int scif_txroom(struct uart_port *port)
+{
+	return SCIF_TXROOM_MAX - scif_txfill(port);
+}
+
+static int scif_rxfill(struct uart_port *port)
 {
 	return sci_in(port, SCRFDR) & 0xff;
 }
 #elif defined(CONFIG_CPU_SUBTYPE_SH7763)
-static inline int scif_txroom(struct uart_port *port)
+static int scif_txfill(struct uart_port *port)
 {
-	if ((port->mapbase == 0xffe00000) ||
-	    (port->mapbase == 0xffe08000)) {
+	if (port->mapbase == 0xffe00000 ||
+	    port->mapbase == 0xffe08000)
 		/* SCIF0/1*/
-		return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff);
-	} else {
+		return sci_in(port, SCTFDR) & 0xff;
+	else
 		/* SCIF2 */
-		return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8);
-	}
+		return sci_in(port, SCFDR) >> 8;
 }
 
-static inline int scif_rxroom(struct uart_port *port)
+static int scif_txroom(struct uart_port *port)
+{
+	if (port->mapbase == 0xffe00000 ||
+	    port->mapbase == 0xffe08000)
+		/* SCIF0/1*/
+		return SCIF_TXROOM_MAX - scif_txfill(port);
+	else
+		/* SCIF2 */
+		return SCIF2_TXROOM_MAX - scif_txfill(port);
+}
+
+static int scif_rxfill(struct uart_port *port)
 {
 	if ((port->mapbase == 0xffe00000) ||
 	    (port->mapbase == 0xffe08000)) {
@@ -303,23 +342,33 @@ static inline int scif_rxroom(struct uar
 	}
 }
 #else
-static inline int scif_txroom(struct uart_port *port)
+static int scif_txfill(struct uart_port *port)
 {
-	return SCIF_TXROOM_MAX - (sci_in(port, SCFDR) >> 8);
+	return sci_in(port, SCFDR) >> 8;
 }
 
-static inline int scif_rxroom(struct uart_port *port)
+static int scif_txroom(struct uart_port *port)
+{
+	return SCIF_TXROOM_MAX - scif_txfill(port);
+}
+
+static int scif_rxfill(struct uart_port *port)
 {
 	return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
 }
 #endif
 
-static inline int sci_txroom(struct uart_port *port)
+static int sci_txfill(struct uart_port *port)
 {
-	return (sci_in(port, SCxSR) & SCI_TDRE) != 0;
+	return !(sci_in(port, SCxSR) & SCI_TDRE);
 }
 
-static inline int sci_rxroom(struct uart_port *port)
+static int sci_txroom(struct uart_port *port)
+{
+	return !sci_txfill(port);
+}
+
+static int sci_rxfill(struct uart_port *port)
 {
 	return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0;
 }
@@ -406,9 +455,9 @@ static inline void sci_receive_chars(str
 
 	while (1) {
 		if (port->type == PORT_SCI)
-			count = sci_rxroom(port);
+			count = sci_rxfill(port);
 		else
-			count = scif_rxroom(port);
+			count = scif_rxfill(port);
 
 		/* Don't copy more bytes than there is room for in the buffer */
 		count = tty_buffer_request_room(tty, count);
@@ -453,10 +502,10 @@ static inline void sci_receive_chars(str
 				}
 
 				/* Store data and status */
-				if (status&SCxSR_FER(port)) {
+				if (status & SCxSR_FER(port)) {
 					flag = TTY_FRAME;
 					dev_notice(port->dev, "frame error\n");
-				} else if (status&SCxSR_PER(port)) {
+				} else if (status & SCxSR_PER(port)) {
 					flag = TTY_PARITY;
 					dev_notice(port->dev, "parity error\n");
 				} else
@@ -618,13 +667,39 @@ static inline int sci_handle_breaks(stru
 	return copied;
 }
 
-static irqreturn_t sci_rx_interrupt(int irq, void *port)
+static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
 {
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+	struct uart_port *port = ptr;
+	struct sci_port *s = to_sci_port(port);
+
+	if (s->chan_rx) {
+		unsigned long tout;
+		u16 scr = sci_in(port, SCSCR);
+		u16 ssr = sci_in(port, SCxSR);
+
+		/* Disable future Rx interrupts */
+		sci_out(port, SCSCR, scr & ~SCI_CTRL_FLAGS_RIE);
+		/* Clear current interrupt */
+		sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port)));
+		/* Calculate delay for 1.5 DMA buffers */
+		tout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 /
+			port->fifosize / 2;
+		dev_dbg(port->dev, "Rx IRQ: setup timeout in %lu ms\n",
+			tout * 1000 / HZ);
+		if (tout < 2)
+			tout = 2;
+		mod_timer(&s->rx_timer, jiffies + tout);
+
+		return IRQ_HANDLED;
+	}
+#endif
+
 	/* I think sci_receive_chars has to be called irrespective
 	 * of whether the I_IXOFF is set, otherwise, how is the interrupt
 	 * to be disabled?
 	 */
-	sci_receive_chars(port);
+	sci_receive_chars(ptr);
 
 	return IRQ_HANDLED;
 }
@@ -680,6 +755,7 @@ static irqreturn_t sci_mpxed_interrupt(i
 {
 	unsigned short ssr_status, scr_status, err_enabled;
 	struct uart_port *port = ptr;
+	struct sci_port *s = to_sci_port(port);
 	irqreturn_t ret = IRQ_NONE;
 
 	ssr_status = sci_in(port, SCxSR);
@@ -687,10 +763,15 @@ static irqreturn_t sci_mpxed_interrupt(i
 	err_enabled = scr_status & (SCI_CTRL_FLAGS_REIE | SCI_CTRL_FLAGS_RIE);
 
 	/* Tx Interrupt */
-	if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCI_CTRL_FLAGS_TIE))
+	if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCI_CTRL_FLAGS_TIE) &&
+	    !s->chan_tx)
 		ret = sci_tx_interrupt(irq, ptr);
-	/* Rx Interrupt */
-	if ((ssr_status & SCxSR_RDxF(port)) && (scr_status & SCI_CTRL_FLAGS_RIE))
+	/*
+	 * Rx Interrupt: if we're using DMA, the DMA controller clears RDF /
+	 * DR flags
+	 */
+	if (((ssr_status & SCxSR_RDxF(port)) || s->chan_rx) &&
+	    (scr_status & SCI_CTRL_FLAGS_RIE))
 		ret = sci_rx_interrupt(irq, ptr);
 	/* Error Interrupt */
 	if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled)
@@ -800,7 +881,9 @@ static void sci_free_irq(struct sci_port
 static unsigned int sci_tx_empty(struct uart_port *port)
 {
 	unsigned short status = sci_in(port, SCxSR);
-	return status & SCxSR_TEND(port) ? TIOCSER_TEMT : 0;
+	unsigned short in_tx_fifo = scif_txfill(port);
+
+	return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0;
 }
 
 static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
@@ -812,16 +895,297 @@ static void sci_set_mctrl(struct uart_po
 
 static unsigned int sci_get_mctrl(struct uart_port *port)
 {
-	/* This routine is used for geting signals of: DTR, DCD, DSR, RI,
+	/* This routine is used for getting signals of: DTR, DCD, DSR, RI,
 	   and CTS/RTS */
 
 	return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR;
 }
 
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+static void sci_dma_tx_complete(void *arg)
+{
+	struct sci_port *s = arg;
+	struct uart_port *port = &s->port;
+	struct circ_buf *xmit = &port->state->xmit;
+	unsigned long flags;
+
+	dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	xmit->tail += s->sg_tx.length;
+	xmit->tail &= UART_XMIT_SIZE - 1;
+
+	port->icount.tx += s->sg_tx.length;
+
+	async_tx_ack(s->desc_tx);
+	s->cookie_tx = -EINVAL;
+	s->desc_tx = NULL;
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+
+	if (uart_circ_chars_pending(xmit))
+		schedule_work(&s->work_tx);
+}
+
+/* Locking: called with port lock held */
+static int sci_dma_rx_push(struct sci_port *s, struct tty_struct *tty,
+			   size_t count)
+{
+	struct uart_port *port = &s->port;
+	int i, active, room;
+
+	room = tty_buffer_request_room(tty, count);
+
+	if (s->active_rx == s->cookie_rx[0]) {
+		active = 0;
+	} else if (s->active_rx == s->cookie_rx[1]) {
+		active = 1;
+	} else {
+		dev_err(port->dev, "cookie %d not found!\n", s->active_rx);
+		return 0;
+	}
+
+	if (room < count)
+		dev_warn(port->dev, "Rx overrun: dropping %u bytes\n",
+			 count - room);
+	if (!room)
+		return room;
+
+	for (i = 0; i < room; i++)
+		tty_insert_flip_char(tty, ((u8 *)sg_virt(&s->sg_rx[active]))[i],
+				     TTY_NORMAL);
+
+	port->icount.rx += room;
+
+	return room;
+}
+
+static void sci_dma_rx_complete(void *arg)
+{
+	struct sci_port *s = arg;
+	struct uart_port *port = &s->port;
+	struct tty_struct *tty = port->state->port.tty;
+	unsigned long flags;
+	int count;
+
+	dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	count = sci_dma_rx_push(s, tty, s->buf_len_rx);
+
+	mod_timer(&s->rx_timer, jiffies + msecs_to_jiffies(5));
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	if (count)
+		tty_flip_buffer_push(tty);
+
+	schedule_work(&s->work_rx);
+}
+
+static void sci_start_rx(struct uart_port *port);
+static void sci_start_tx(struct uart_port *port);
+
+static void sci_rx_dma_release(struct sci_port *s, bool enable_pio)
+{
+	struct dma_chan *chan = s->chan_rx;
+	struct uart_port *port = &s->port;
+
+	s->chan_rx = NULL;
+	s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL;
+	dma_release_channel(chan);
+	dma_free_coherent(port->dev, s->buf_len_rx * 2,
+			  sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0]));
+	if (enable_pio)
+		sci_start_rx(port);
+}
+
+static void sci_tx_dma_release(struct sci_port *s, bool enable_pio)
+{
+	struct dma_chan *chan = s->chan_tx;
+	struct uart_port *port = &s->port;
+
+	s->chan_tx = NULL;
+	s->cookie_tx = -EINVAL;
+	dma_release_channel(chan);
+	if (enable_pio)
+		sci_start_tx(port);
+}
+
+static void sci_submit_rx(struct sci_port *s)
+{
+	struct dma_chan *chan = s->chan_rx;
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		struct scatterlist *sg = &s->sg_rx[i];
+		struct dma_async_tx_descriptor *desc;
+
+		desc = chan->device->device_prep_slave_sg(chan,
+			sg, 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT);
+
+		if (desc) {
+			s->desc_rx[i] = desc;
+			desc->callback = sci_dma_rx_complete;
+			desc->callback_param = s;
+			s->cookie_rx[i] = desc->tx_submit(desc);
+		}
+
+		if (!desc || s->cookie_rx[i] < 0) {
+			if (i) {
+				async_tx_ack(s->desc_rx[0]);
+				s->cookie_rx[0] = -EINVAL;
+			}
+			if (desc) {
+				async_tx_ack(desc);
+				s->cookie_rx[i] = -EINVAL;
+			}
+			dev_warn(s->port.dev,
+				 "failed to re-start DMA, using PIO\n");
+			sci_rx_dma_release(s, true);
+			return;
+		}
+	}
+
+	s->active_rx = s->cookie_rx[0];
+
+	dma_async_issue_pending(chan);
+}
+
+static void work_fn_rx(struct work_struct *work)
+{
+	struct sci_port *s = container_of(work, struct sci_port, work_rx);
+	struct uart_port *port = &s->port;
+	struct dma_async_tx_descriptor *desc;
+	int new;
+
+	if (s->active_rx == s->cookie_rx[0]) {
+		new = 0;
+	} else if (s->active_rx == s->cookie_rx[1]) {
+		new = 1;
+	} else {
+		dev_err(port->dev, "cookie %d not found!\n", s->active_rx);
+		return;
+	}
+	desc = s->desc_rx[new];
+
+	if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) !=
+	    DMA_SUCCESS) {
+		/* Handle incomplete DMA receive */
+		struct tty_struct *tty = port->state->port.tty;
+		struct dma_chan *chan = s->chan_rx;
+		struct sh_desc *sh_desc = container_of(desc, struct sh_desc,
+						       async_tx);
+		unsigned long flags;
+		int count;
+
+		chan->device->device_terminate_all(chan);
+		dev_dbg(port->dev, "Read %u bytes with cookie %d\n",
+			sh_desc->partial, sh_desc->cookie);
+
+		spin_lock_irqsave(&port->lock, flags);
+		count = sci_dma_rx_push(s, tty, sh_desc->partial);
+		spin_unlock_irqrestore(&port->lock, flags);
+
+		if (count)
+			tty_flip_buffer_push(tty);
+
+		sci_submit_rx(s);
+
+		return;
+	}
+
+	s->cookie_rx[new] = desc->tx_submit(desc);
+	if (s->cookie_rx[new] < 0) {
+		dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
+		sci_rx_dma_release(s, true);
+		return;
+	}
+
+	dev_dbg(port->dev, "%s: cookie %d #%d\n", __func__,
+		s->cookie_rx[new], new);
+
+	s->active_rx = s->cookie_rx[!new];
+}
+
+static void work_fn_tx(struct work_struct *work)
+{
+	struct sci_port *s = container_of(work, struct sci_port, work_tx);
+	struct dma_async_tx_descriptor *desc;
+	struct dma_chan *chan = s->chan_tx;
+	struct uart_port *port = &s->port;
+	struct circ_buf *xmit = &port->state->xmit;
+	struct scatterlist *sg = &s->sg_tx;
+
+	/*
+	 * DMA is idle now.
+	 * Port xmit buffer is already mapped, and it is one page... Just adjust
+	 * offsets and lengths. Since it is a circular buffer, we have to
+	 * transmit till the end, and then the rest. Take the port lock to get a
+	 * consistent xmit buffer state.
+	 */
+	spin_lock_irq(&port->lock);
+	sg->offset = xmit->tail & (UART_XMIT_SIZE - 1);
+	sg->dma_address = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) +
+		sg->offset;
+	sg->length = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE),
+		CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE));
+	sg->dma_length = sg->length;
+	spin_unlock_irq(&port->lock);
+
+	BUG_ON(!sg->length);
+
+	desc = chan->device->device_prep_slave_sg(chan,
+			sg, s->sg_len_tx, DMA_TO_DEVICE,
+			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc) {
+		/* switch to PIO */
+		sci_tx_dma_release(s, true);
+		return;
+	}
+
+	dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE);
+
+	spin_lock_irq(&port->lock);
+	s->desc_tx = desc;
+	desc->callback = sci_dma_tx_complete;
+	desc->callback_param = s;
+	spin_unlock_irq(&port->lock);
+	s->cookie_tx = desc->tx_submit(desc);
+	if (s->cookie_tx < 0) {
+		dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n");
+		/* switch to PIO */
+		sci_tx_dma_release(s, true);
+		return;
+	}
+
+	dev_dbg(port->dev, "%s: %p: %d...%d, cookie %d\n", __func__,
+		xmit->buf, xmit->tail, xmit->head, s->cookie_tx);
+
+	dma_async_issue_pending(chan);
+}
+#endif
+
 static void sci_start_tx(struct uart_port *port)
 {
 	unsigned short ctrl;
 
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+	struct sci_port *s = to_sci_port(port);
+
+	if (s->chan_tx) {
+		if (!uart_circ_empty(&s->port.state->xmit) && s->cookie_tx < 0)
+			schedule_work(&s->work_tx);
+
+		return;
+	}
+#endif
+
 	/* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
 	ctrl = sci_in(port, SCSCR);
 	ctrl |= SCI_CTRL_FLAGS_TIE;
@@ -838,13 +1202,12 @@ static void sci_stop_tx(struct uart_port
 	sci_out(port, SCSCR, ctrl);
 }
 
-static void sci_start_rx(struct uart_port *port, unsigned int tty_start)
+static void sci_start_rx(struct uart_port *port)
 {
-	unsigned short ctrl;
+	unsigned short ctrl = SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE;
 
 	/* Set RIE (Receive Interrupt Enable) bit in SCSCR */
-	ctrl = sci_in(port, SCSCR);
-	ctrl |= SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE;
+	ctrl |= sci_in(port, SCSCR);
 	sci_out(port, SCSCR, ctrl);
 }
 
@@ -868,16 +1231,154 @@ static void sci_break_ctl(struct uart_po
 	/* Nothing here yet .. */
 }
 
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+static bool filter(struct dma_chan *chan, void *slave)
+{
+	struct sh_dmae_slave *param = slave;
+
+	dev_dbg(chan->device->dev, "%s: slave ID %d\n", __func__,
+		param->slave_id);
+
+	if (param->dma_dev == chan->device->dev) {
+		chan->private = param;
+		return true;
+	} else {
+		return false;
+	}
+}
+
+static void rx_timer_fn(unsigned long arg)
+{
+	struct sci_port *s = (struct sci_port *)arg;
+	struct uart_port *port = &s->port;
+
+	u16 scr = sci_in(port, SCSCR);
+	sci_out(port, SCSCR, scr | SCI_CTRL_FLAGS_RIE);
+	dev_dbg(port->dev, "DMA Rx timed out\n");
+	schedule_work(&s->work_rx);
+}
+
+static void sci_request_dma(struct uart_port *port)
+{
+	struct sci_port *s = to_sci_port(port);
+	struct sh_dmae_slave *param;
+	struct dma_chan *chan;
+	dma_cap_mask_t mask;
+	int nent;
+
+	dev_dbg(port->dev, "%s: port %d DMA %p\n", __func__,
+		port->line, s->dma_dev);
+
+	if (!s->dma_dev)
+		return;
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+
+	param = &s->param_tx;
+
+	/* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */
+	param->slave_id = s->slave_tx;
+	param->dma_dev = s->dma_dev;
+
+	s->cookie_tx = -EINVAL;
+	chan = dma_request_channel(mask, filter, param);
+	dev_dbg(port->dev, "%s: TX: got channel %p\n", __func__, chan);
+	if (chan) {
+		s->chan_tx = chan;
+		sg_init_table(&s->sg_tx, 1);
+		/* UART circular tx buffer is an aligned page. */
+		BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK);
+		sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf),
+			    UART_XMIT_SIZE, (int)port->state->xmit.buf & ~PAGE_MASK);
+		nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE);
+		if (!nent)
+			sci_tx_dma_release(s, false);
+		else
+			dev_dbg(port->dev, "%s: mapped %d@%p to %x\n", __func__,
+				sg_dma_len(&s->sg_tx),
+				port->state->xmit.buf, sg_dma_address(&s->sg_tx));
+
+		s->sg_len_tx = nent;
+
+		INIT_WORK(&s->work_tx, work_fn_tx);
+	}
+
+	param = &s->param_rx;
+
+	/* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */
+	param->slave_id = s->slave_rx;
+	param->dma_dev = s->dma_dev;
+
+	chan = dma_request_channel(mask, filter, param);
+	dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan);
+	if (chan) {
+		dma_addr_t dma[2];
+		void *buf[2];
+		int i;
+
+		s->chan_rx = chan;
+
+		s->buf_len_rx = 2 * max(16, (int)port->fifosize);
+		buf[0] = dma_alloc_coherent(port->dev, s->buf_len_rx * 2,
+					    &dma[0], GFP_KERNEL);
+
+		if (!buf[0]) {
+			dev_warn(port->dev,
+				 "failed to allocate dma buffer, using PIO\n");
+			sci_rx_dma_release(s, true);
+			return;
+		}
+
+		buf[1] = buf[0] + s->buf_len_rx;
+		dma[1] = dma[0] + s->buf_len_rx;
+
+		for (i = 0; i < 2; i++) {
+			struct scatterlist *sg = &s->sg_rx[i];
+
+			sg_init_table(sg, 1);
+			sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx,
+				    (int)buf[i] & ~PAGE_MASK);
+			sg->dma_address = dma[i];
+			sg->dma_length = sg->length;
+		}
+
+		INIT_WORK(&s->work_rx, work_fn_rx);
+		setup_timer(&s->rx_timer, rx_timer_fn, (unsigned long)s);
+
+		sci_submit_rx(s);
+	}
+}
+
+static void sci_free_dma(struct uart_port *port)
+{
+	struct sci_port *s = to_sci_port(port);
+
+	if (!s->dma_dev)
+		return;
+
+	if (s->chan_tx)
+		sci_tx_dma_release(s, false);
+	if (s->chan_rx)
+		sci_rx_dma_release(s, false);
+}
+#endif
+
 static int sci_startup(struct uart_port *port)
 {
 	struct sci_port *s = to_sci_port(port);
 
+	dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
+
 	if (s->enable)
 		s->enable(port);
 
 	sci_request_irq(s);
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+	sci_request_dma(port);
+#endif
 	sci_start_tx(port);
-	sci_start_rx(port, 1);
+	sci_start_rx(port);
 
 	return 0;
 }
@@ -886,8 +1387,13 @@ static void sci_shutdown(struct uart_por
 {
 	struct sci_port *s = to_sci_port(port);
 
+	dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
+
 	sci_stop_rx(port);
 	sci_stop_tx(port);
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+	sci_free_dma(port);
+#endif
 	sci_free_irq(s);
 
 	if (s->disable)
@@ -937,6 +1443,9 @@ static void sci_set_termios(struct uart_
 
 	sci_out(port, SCSMR, smr_val);
 
+	dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t,
+		SCSCR_INIT(port));
+
 	if (t > 0) {
 		if (t >= 256) {
 			sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1);
@@ -954,7 +1463,7 @@ static void sci_set_termios(struct uart_
 	sci_out(port, SCSCR, SCSCR_INIT(port));
 
 	if ((termios->c_cflag & CREAD) != 0)
-		sci_start_rx(port, 0);
+		sci_start_rx(port);
 }
 
 static const char *sci_type(struct uart_port *port)
@@ -1049,19 +1558,21 @@ static void __devinit sci_init_single(st
 				      unsigned int index,
 				      struct plat_sci_port *p)
 {
-	sci_port->port.ops	= &sci_uart_ops;
-	sci_port->port.iotype	= UPIO_MEM;
-	sci_port->port.line	= index;
+	struct uart_port *port = &sci_port->port;
+
+	port->ops	= &sci_uart_ops;
+	port->iotype	= UPIO_MEM;
+	port->line	= index;
 
 	switch (p->type) {
 	case PORT_SCIFA:
-		sci_port->port.fifosize = 64;
+		port->fifosize = 64;
 		break;
 	case PORT_SCIF:
-		sci_port->port.fifosize = 16;
+		port->fifosize = 16;
 		break;
 	default:
-		sci_port->port.fifosize = 1;
+		port->fifosize = 1;
 		break;
 	}
 
@@ -1070,19 +1581,28 @@ static void __devinit sci_init_single(st
 		sci_port->dclk = clk_get(&dev->dev, "peripheral_clk");
 		sci_port->enable = sci_clk_enable;
 		sci_port->disable = sci_clk_disable;
-		sci_port->port.dev = &dev->dev;
+		port->dev = &dev->dev;
 	}
 
 	sci_port->break_timer.data = (unsigned long)sci_port;
 	sci_port->break_timer.function = sci_break_timer;
 	init_timer(&sci_port->break_timer);
 
-	sci_port->port.mapbase	= p->mapbase;
-	sci_port->port.membase	= p->membase;
+	port->mapbase	= p->mapbase;
+	port->membase	= p->membase;
 
-	sci_port->port.irq	= p->irqs[SCIx_TXI_IRQ];
-	sci_port->port.flags	= p->flags;
-	sci_port->type		= sci_port->port.type = p->type;
+	port->irq	= p->irqs[SCIx_TXI_IRQ];
+	port->flags	= p->flags;
+	sci_port->type	= port->type = p->type;
+
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+	sci_port->dma_dev	= p->dma_dev;
+	sci_port->slave_tx	= p->dma_slave_tx;
+	sci_port->slave_rx	= p->dma_slave_rx;
+
+	dev_dbg(port->dev, "%s: DMA device %p, tx %d, rx %d\n", __func__,
+		p->dma_dev, p->dma_slave_tx, p->dma_slave_rx);
+#endif
 
 	memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs));
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/sh-sci.h linux-libre-2.6.34-gnu1/drivers/serial/sh-sci.h
--- linux-libre-2.6.33-gnu1/drivers/serial/sh-sci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/sh-sci.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,10 @@
  */
 # define SCSCR_INIT(port) (port->mapbase == SCIF2) ? 0xF3 : 0xF0
 #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7721)
+      defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+      defined(CONFIG_ARCH_SH7367) || \
+      defined(CONFIG_ARCH_SH7377) || \
+      defined(CONFIG_ARCH_SH7372)
 # define SCSCR_INIT(port)  0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */
 # define PORT_PTCR	   0xA405011EUL
 # define PORT_PVCR	   0xA4050122UL
@@ -93,7 +96,9 @@
 # define SCSCR_INIT(port)       0x0038  /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
 #elif defined(CONFIG_CPU_SUBTYPE_SH7724)
 # define SCIF_ORER              0x0001  /* overrun error bit */
-# define SCSCR_INIT(port)       0x0038  /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+# define SCSCR_INIT(port) ((port)->type == PORT_SCIFA ? \
+	0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ : \
+	0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ )
 #elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
 # define SCSPTR2 0xffe80020 /* 16 bit SCIF */
 # define SCIF_ORER 0x0001   /* overrun error bit */
@@ -196,6 +201,8 @@
     defined(CONFIG_CPU_SUBTYPE_SH7786)  || \
     defined(CONFIG_CPU_SUBTYPE_SHX3)
 #define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */
+#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define SCI_CTRL_FLAGS_REIE ((port)->type == PORT_SCIFA ? 0 : 8)
 #else
 #define SCI_CTRL_FLAGS_REIE 0
 #endif
@@ -228,7 +235,10 @@
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
     defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721)
+    defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+    defined(CONFIG_ARCH_SH7367) || \
+    defined(CONFIG_ARCH_SH7377) || \
+    defined(CONFIG_ARCH_SH7372)
 # define SCIF_ORER    0x0200
 # define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
 # define SCIF_RFDC_MASK 0x007f
@@ -261,7 +271,10 @@
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
     defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721)
+    defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+    defined(CONFIG_ARCH_SH7367) || \
+    defined(CONFIG_ARCH_SH7377) || \
+    defined(CONFIG_ARCH_SH7372)
 # define SCxSR_RDxF_CLEAR(port)	 (sci_in(port, SCxSR) & 0xfffc)
 # define SCxSR_ERROR_CLEAR(port) (sci_in(port, SCxSR) & 0xfd73)
 # define SCxSR_TDxE_CLEAR(port)	 (sci_in(port, SCxSR) & 0xffdf)
@@ -356,7 +369,10 @@
     SCI_OUT(sci_size, sci_offset, value);				\
   }
 
-#ifdef CONFIG_CPU_SH3
+#if defined(CONFIG_CPU_SH3) || \
+    defined(CONFIG_ARCH_SH7367) || \
+    defined(CONFIG_ARCH_SH7377) || \
+    defined(CONFIG_ARCH_SH7372)
 #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
 #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
 		                sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \
@@ -366,7 +382,10 @@
 	  CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
 #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
       defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7721)
+      defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+      defined(CONFIG_ARCH_SH7367) || \
+      defined(CONFIG_ARCH_SH7377) || \
+      defined(CONFIG_ARCH_SH7372)
 #define SCIF_FNS(name, scif_offset, scif_size) \
   CPU_SCIF_FNS(name, scif_offset, scif_size)
 #else
@@ -401,7 +420,10 @@
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
     defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721)
+    defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+    defined(CONFIG_ARCH_SH7367) || \
+    defined(CONFIG_ARCH_SH7377) || \
+    defined(CONFIG_ARCH_SH7372)
 
 SCIF_FNS(SCSMR,  0x00, 16)
 SCIF_FNS(SCBRR,  0x04,  8)
@@ -413,7 +435,7 @@ SCIF_FNS(SCFCR,  0x18, 16)
 SCIF_FNS(SCFDR,  0x1c, 16)
 SCIF_FNS(SCxTDR, 0x20,  8)
 SCIF_FNS(SCxRDR, 0x24,  8)
-SCIF_FNS(SCLSR,  0x24, 16)
+SCIF_FNS(SCLSR,  0x00,  0)
 #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
       defined(CONFIG_CPU_SUBTYPE_SH7724)
 SCIx_FNS(SCSMR,  0x00, 16, 0x00, 16)
@@ -518,34 +540,6 @@ static inline int sci_rxd_in(struct uart
 {
 	if (port->mapbase == 0xfffffe80)
 		return __raw_readb(SCPDR)&0x01 ? 1 : 0; /* SCI */
-	if (port->mapbase == 0xa4000150)
-		return __raw_readb(SCPDR)&0x10 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xa4000140)
-		return __raw_readb(SCPDR)&0x04 ? 1 : 0; /* IRDA */
-	return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7705)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	if (port->mapbase == SCIF0)
-		return __raw_readb(SCPDR)&0x04 ? 1 : 0; /* IRDA */
-	if (port->mapbase == SCIF2)
-		return __raw_readb(SCPDR)&0x10 ? 1 : 0; /* SCIF */
-	return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	  return sci_in(port,SCxSR)&0x0010 ? 1 : 0;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7721)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	if (port->mapbase == 0xa4430000)
-		return sci_in(port, SCxSR) & 0x0003 ? 1 : 0;
-	else if (port->mapbase == 0xa4438000)
-		return sci_in(port, SCxSR) & 0x0003 ? 1 : 0;
 	return 1;
 }
 #elif defined(CONFIG_CPU_SUBTYPE_SH7750)  || \
@@ -558,207 +552,17 @@ static inline int sci_rxd_in(struct uart
 {
 	if (port->mapbase == 0xffe00000)
 		return __raw_readb(SCSPTR1)&0x01 ? 1 : 0; /* SCI */
-	if (port->mapbase == 0xffe80000)
-		return __raw_readw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */
-	return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	if (port->mapbase == 0xffe80000)
-		return __raw_readw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */
-	return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	if (port->mapbase == 0xfe4b0000)
-		return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0;
-	if (port->mapbase == 0xfe4c0000)
-		return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0;
-	if (port->mapbase == 0xfe4d0000)
-		return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	if (port->mapbase == 0xfe600000)
-		return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xfe610000)
-		return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xfe620000)
-		return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
-	return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7343)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	if (port->mapbase == 0xffe00000)
-		return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xffe10000)
-		return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xffe20000)
-		return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xffe30000)
-		return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
-	return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7366)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	if (port->mapbase == 0xffe00000)
-		return __raw_readb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */
 	return 1;
 }
-#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	if (port->mapbase == 0xffe00000)
-		return __raw_readb(PSDR) & 0x02 ? 1 : 0; /* SCIF0 */
-	if (port->mapbase == 0xffe10000)
-		return __raw_readb(PADR) & 0x40 ? 1 : 0; /* SCIF1 */
-	if (port->mapbase == 0xffe20000)
-		return __raw_readb(PWDR) & 0x04 ? 1 : 0; /* SCIF2 */
-
-	return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-        if (port->mapbase == 0xffe00000)
-                return __raw_readb(SCSPTR0) & 0x0008 ? 1 : 0; /* SCIF0 */
-        if (port->mapbase == 0xffe10000)
-                return __raw_readb(SCSPTR1) & 0x0020 ? 1 : 0; /* SCIF1 */
-        if (port->mapbase == 0xffe20000)
-                return __raw_readb(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF2 */
-        if (port->mapbase == 0xa4e30000)
-                return __raw_readb(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF3 */
-        if (port->mapbase == 0xa4e40000)
-                return __raw_readb(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF4 */
-        if (port->mapbase == 0xa4e50000)
-                return __raw_readb(SCSPTR5) & 0x0008 ? 1 : 0; /* SCIF5 */
-        return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
-#  define SCFSR    0x0010
-#  define SCASSR   0x0014
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	if (port->type == PORT_SCIF)
-		return __raw_readw((port->mapbase + SCFSR))  & SCIF_BRK ? 1 : 0;
-	if (port->type == PORT_SCIFA)
-		return __raw_readw((port->mapbase + SCASSR)) & SCIF_BRK ? 1 : 0;
-	return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-         return sci_in(port, SCSPTR)&0x0001 ? 1 : 0; /* SCIF */
-}
 #elif defined(__H8300H__) || defined(__H8300S__)
 static inline int sci_rxd_in(struct uart_port *port)
 {
 	int ch = (port->mapbase - SMR0) >> 3;
 	return (H8300_SCI_DR(ch) & h8300_sci_pins[ch].rx) ? 1 : 0;
 }
-#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	if (port->mapbase == 0xffe00000)
-		return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xffe08000)
-		return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xffe10000)
-		return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF/IRDA */
-
-	return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	if (port->mapbase == 0xff923000)
-		return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xff924000)
-		return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xff925000)
-		return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
-	return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	if (port->mapbase == 0xffe00000)
-		return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xffe10000)
-		return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
-	return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7786)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	if (port->mapbase == 0xffea0000)
-		return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xffeb0000)
-		return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xffec0000)
-		return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xffed0000)
-		return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xffee0000)
-		return __raw_readw(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xffef0000)
-		return __raw_readw(SCSPTR5) & 0x0001 ? 1 : 0; /* SCIF */
-	return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7203) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7206) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7263)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	if (port->mapbase == 0xfffe8000)
-		return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xfffe8800)
-		return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xfffe9000)
-		return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xfffe9800)
-		return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
-#if defined(CONFIG_CPU_SUBTYPE_SH7201)
-	if (port->mapbase == 0xfffeA000)
-		return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xfffeA800)
-		return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xfffeB000)
-		return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xfffeB800)
-		return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
-#endif
-	return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
-static inline int sci_rxd_in(struct uart_port *port)
-{
-	if (port->mapbase == 0xf8400000)
-		return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xf8410000)
-		return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xf8420000)
-		return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
-	return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SHX3)
+#else /* default case for non-SCI processors */
 static inline int sci_rxd_in(struct uart_port *port)
 {
-	if (port->mapbase == 0xffc30000)
-		return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xffc40000)
-		return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xffc50000)
-		return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
-	if (port->mapbase == 0xffc60000)
-		return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
 	return 1;
 }
 #endif
@@ -801,7 +605,10 @@ static inline int sci_rxd_in(struct uart
 #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1)
 #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
       defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7721)
+      defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+      defined(CONFIG_ARCH_SH7367) || \
+      defined(CONFIG_ARCH_SH7377) || \
+      defined(CONFIG_ARCH_SH7372)
 #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1)
 #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
       defined(CONFIG_CPU_SUBTYPE_SH7724)
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/sunsab.c linux-libre-2.6.34-gnu1/drivers/serial/sunsab.c
--- linux-libre-2.6.33-gnu1/drivers/serial/sunsab.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/sunsab.c	2010-05-16 17:17:36.000000000 -0400
@@ -474,7 +474,7 @@ static void sunsab_stop_rx(struct uart_p
 {
 	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
 
-	up->interrupt_mask0 |= SAB82532_ISR0_TCD;
+	up->interrupt_mask0 |= SAB82532_IMR0_TCD;
 	writeb(up->interrupt_mask1, &up->regs->w.imr0);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/sunsu.c linux-libre-2.6.34-gnu1/drivers/serial/sunsu.c
--- linux-libre-2.6.33-gnu1/drivers/serial/sunsu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/sunsu.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/serial.h>
 #include <linux/sysrq.h>
 #include <linux/console.h>
+#include <linux/slab.h>
 #ifdef CONFIG_SERIO
 #include <linux/serio.h>
 #endif
@@ -1453,8 +1454,10 @@ static int __devinit su_probe(struct of_
 	if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) {
 		err = sunsu_kbd_ms_init(up);
 		if (err) {
+			of_iounmap(&op->resource[0],
+				   up->port.membase, up->reg_size);
 			kfree(up);
-			goto out_unmap;
+			return err;
 		}
 		dev_set_drvdata(&op->dev, up);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/timbuart.c linux-libre-2.6.34-gnu1/drivers/serial/timbuart.c
--- linux-libre-2.6.33-gnu1/drivers/serial/timbuart.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/timbuart.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
 
 #include "timbuart.h"
 
@@ -421,7 +422,7 @@ static struct uart_driver timbuart_drive
 
 static int timbuart_probe(struct platform_device *dev)
 {
-	int err;
+	int err, irq;
 	struct timbuart_port *uart;
 	struct resource *iomem;
 
@@ -453,11 +454,12 @@ static int timbuart_probe(struct platfor
 	uart->port.mapbase = iomem->start;
 	uart->port.membase = NULL;
 
-	uart->port.irq = platform_get_irq(dev, 0);
-	if (uart->port.irq < 0) {
+	irq = platform_get_irq(dev, 0);
+	if (irq < 0) {
 		err = -EINVAL;
 		goto err_register;
 	}
+	uart->port.irq = irq;
 
 	tasklet_init(&uart->tasklet, timbuart_tasklet, (unsigned long)uart);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/uartlite.c linux-libre-2.6.34-gnu1/drivers/serial/uartlite.c
--- linux-libre-2.6.33-gnu1/drivers/serial/uartlite.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/serial/uartlite.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,7 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <asm/io.h>
-#if defined(CONFIG_OF)
+#if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE))
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
@@ -581,7 +581,7 @@ static struct platform_driver ulite_plat
 /* ---------------------------------------------------------------------
  * OF bus bindings
  */
-#if defined(CONFIG_OF)
+#if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE))
 static int __devinit
 ulite_of_probe(struct of_device *op, const struct of_device_id *match)
 {
@@ -631,11 +631,11 @@ static inline void __exit ulite_of_unreg
 {
 	of_unregister_platform_driver(&ulite_of_driver);
 }
-#else /* CONFIG_OF */
-/* CONFIG_OF not enabled; do nothing helpers */
+#else /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */
+/* Appropriate config not enabled; do nothing helpers */
 static inline int __init ulite_of_register(void) { return 0; }
 static inline void __exit ulite_of_unregister(void) { }
-#endif /* CONFIG_OF */
+#endif /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */
 
 /* ---------------------------------------------------------------------
  * Module setup/teardown
diff -druNp linux-libre-2.6.33-gnu1/drivers/serial/ucc_uart.c linux-libre-2.6.34-gnu1/drivers/serial/ucc_uart.c
--- linux-libre-2.6.33-gnu1/drivers/serial/ucc_uart.c	2013-05-03 12:12:19.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/serial/ucc_uart.c	2013-05-03 09:51:51.000000000 -0400
@@ -20,6 +20,7 @@
 
 #include <linux/module.h>
 #include <linux/serial.h>
+#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/io.h>
 #include <linux/of_platform.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/sh/intc.c linux-libre-2.6.34-gnu1/drivers/sh/intc.c
--- linux-libre-2.6.33-gnu1/drivers/sh/intc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/sh/intc.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  * Shared interrupt handling code for IPR and INTC2 types of IRQs.
  *
  * Copyright (C) 2007, 2008 Magnus Damm
- * Copyright (C) 2009 Paul Mundt
+ * Copyright (C) 2009, 2010 Paul Mundt
  *
  * Based on intc2.c and ipr.c
  *
@@ -20,12 +20,14 @@
 #include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/sh_intc.h>
 #include <linux/sysdev.h>
 #include <linux/list.h>
 #include <linux/topology.h>
 #include <linux/bitmap.h>
+#include <linux/cpumask.h>
 
 #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
 	((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
@@ -234,6 +236,10 @@ static inline void _intc_enable(unsigned
 	unsigned int cpu;
 
 	for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) {
+#ifdef CONFIG_SMP
+		if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity))
+			continue;
+#endif
 		addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu);
 		intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\
 						    [_INTC_FN(handle)], irq);
@@ -253,17 +259,75 @@ static void intc_disable(unsigned int ir
 	unsigned int cpu;
 
 	for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) {
+#ifdef CONFIG_SMP
+		if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity))
+			continue;
+#endif
 		addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu);
 		intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\
 						     [_INTC_FN(handle)], irq);
 	}
 }
 
+static void (*intc_enable_noprio_fns[])(unsigned long addr,
+					unsigned long handle,
+					void (*fn)(unsigned long,
+						   unsigned long,
+						   unsigned long),
+					unsigned int irq) = {
+	[MODE_ENABLE_REG] = intc_mode_field,
+	[MODE_MASK_REG] = intc_mode_zero,
+	[MODE_DUAL_REG] = intc_mode_field,
+	[MODE_PRIO_REG] = intc_mode_field,
+	[MODE_PCLR_REG] = intc_mode_field,
+};
+
+static void intc_enable_disable(struct intc_desc_int *d,
+				unsigned long handle, int do_enable)
+{
+	unsigned long addr;
+	unsigned int cpu;
+	void (*fn)(unsigned long, unsigned long,
+		   void (*)(unsigned long, unsigned long, unsigned long),
+		   unsigned int);
+
+	if (do_enable) {
+		for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) {
+			addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu);
+			fn = intc_enable_noprio_fns[_INTC_MODE(handle)];
+			fn(addr, handle, intc_reg_fns[_INTC_FN(handle)], 0);
+		}
+	} else {
+		for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) {
+			addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu);
+			fn = intc_disable_fns[_INTC_MODE(handle)];
+			fn(addr, handle, intc_reg_fns[_INTC_FN(handle)], 0);
+		}
+	}
+}
+
 static int intc_set_wake(unsigned int irq, unsigned int on)
 {
 	return 0; /* allow wakeup, but setup hardware in intc_suspend() */
 }
 
+#ifdef CONFIG_SMP
+/*
+ * This is held with the irq desc lock held, so we don't require any
+ * additional locking here at the intc desc level. The affinity mask is
+ * later tested in the enable/disable paths.
+ */
+static int intc_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+{
+	if (!cpumask_intersects(cpumask, cpu_online_mask))
+		return -1;
+
+	cpumask_copy(irq_to_desc(irq)->affinity, cpumask);
+
+	return 0;
+}
+#endif
+
 static void intc_mask_ack(unsigned int irq)
 {
 	struct intc_desc_int *d = get_intc_desc(irq);
@@ -400,11 +464,11 @@ static unsigned int __init intc_get_reg(
 static intc_enum __init intc_grp_id(struct intc_desc *desc,
 				    intc_enum enum_id)
 {
-	struct intc_group *g = desc->groups;
+	struct intc_group *g = desc->hw.groups;
 	unsigned int i, j;
 
-	for (i = 0; g && enum_id && i < desc->nr_groups; i++) {
-		g = desc->groups + i;
+	for (i = 0; g && enum_id && i < desc->hw.nr_groups; i++) {
+		g = desc->hw.groups + i;
 
 		for (j = 0; g->enum_ids[j]; j++) {
 			if (g->enum_ids[j] != enum_id)
@@ -417,19 +481,21 @@ static intc_enum __init intc_grp_id(stru
 	return 0;
 }
 
-static unsigned int __init intc_mask_data(struct intc_desc *desc,
-					  struct intc_desc_int *d,
-					  intc_enum enum_id, int do_grps)
+static unsigned int __init _intc_mask_data(struct intc_desc *desc,
+					   struct intc_desc_int *d,
+					   intc_enum enum_id,
+					   unsigned int *reg_idx,
+					   unsigned int *fld_idx)
 {
-	struct intc_mask_reg *mr = desc->mask_regs;
-	unsigned int i, j, fn, mode;
+	struct intc_mask_reg *mr = desc->hw.mask_regs;
+	unsigned int fn, mode;
 	unsigned long reg_e, reg_d;
 
-	for (i = 0; mr && enum_id && i < desc->nr_mask_regs; i++) {
-		mr = desc->mask_regs + i;
+	while (mr && enum_id && *reg_idx < desc->hw.nr_mask_regs) {
+		mr = desc->hw.mask_regs + *reg_idx;
 
-		for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) {
-			if (mr->enum_ids[j] != enum_id)
+		for (; *fld_idx < ARRAY_SIZE(mr->enum_ids); (*fld_idx)++) {
+			if (mr->enum_ids[*fld_idx] != enum_id)
 				continue;
 
 			if (mr->set_reg && mr->clr_reg) {
@@ -455,29 +521,49 @@ static unsigned int __init intc_mask_dat
 					intc_get_reg(d, reg_e),
 					intc_get_reg(d, reg_d),
 					1,
-					(mr->reg_width - 1) - j);
+					(mr->reg_width - 1) - *fld_idx);
 		}
+
+		*fld_idx = 0;
+		(*reg_idx)++;
 	}
 
+	return 0;
+}
+
+static unsigned int __init intc_mask_data(struct intc_desc *desc,
+					  struct intc_desc_int *d,
+					  intc_enum enum_id, int do_grps)
+{
+	unsigned int i = 0;
+	unsigned int j = 0;
+	unsigned int ret;
+
+	ret = _intc_mask_data(desc, d, enum_id, &i, &j);
+	if (ret)
+		return ret;
+
 	if (do_grps)
 		return intc_mask_data(desc, d, intc_grp_id(desc, enum_id), 0);
 
 	return 0;
 }
 
-static unsigned int __init intc_prio_data(struct intc_desc *desc,
-					  struct intc_desc_int *d,
-					  intc_enum enum_id, int do_grps)
+static unsigned int __init _intc_prio_data(struct intc_desc *desc,
+					   struct intc_desc_int *d,
+					   intc_enum enum_id,
+					   unsigned int *reg_idx,
+					   unsigned int *fld_idx)
 {
-	struct intc_prio_reg *pr = desc->prio_regs;
-	unsigned int i, j, fn, mode, bit;
+	struct intc_prio_reg *pr = desc->hw.prio_regs;
+	unsigned int fn, n, mode, bit;
 	unsigned long reg_e, reg_d;
 
-	for (i = 0; pr && enum_id && i < desc->nr_prio_regs; i++) {
-		pr = desc->prio_regs + i;
+	while (pr && enum_id && *reg_idx < desc->hw.nr_prio_regs) {
+		pr = desc->hw.prio_regs + *reg_idx;
 
-		for (j = 0; j < ARRAY_SIZE(pr->enum_ids); j++) {
-			if (pr->enum_ids[j] != enum_id)
+		for (; *fld_idx < ARRAY_SIZE(pr->enum_ids); (*fld_idx)++) {
+			if (pr->enum_ids[*fld_idx] != enum_id)
 				continue;
 
 			if (pr->set_reg && pr->clr_reg) {
@@ -495,34 +581,79 @@ static unsigned int __init intc_prio_dat
 			}
 
 			fn += (pr->reg_width >> 3) - 1;
+			n = *fld_idx + 1;
 
-			BUG_ON((j + 1) * pr->field_width > pr->reg_width);
+			BUG_ON(n * pr->field_width > pr->reg_width);
 
-			bit = pr->reg_width - ((j + 1) * pr->field_width);
+			bit = pr->reg_width - (n * pr->field_width);
 
 			return _INTC_MK(fn, mode,
 					intc_get_reg(d, reg_e),
 					intc_get_reg(d, reg_d),
 					pr->field_width, bit);
 		}
+
+		*fld_idx = 0;
+		(*reg_idx)++;
 	}
 
+	return 0;
+}
+
+static unsigned int __init intc_prio_data(struct intc_desc *desc,
+					  struct intc_desc_int *d,
+					  intc_enum enum_id, int do_grps)
+{
+	unsigned int i = 0;
+	unsigned int j = 0;
+	unsigned int ret;
+
+	ret = _intc_prio_data(desc, d, enum_id, &i, &j);
+	if (ret)
+		return ret;
+
 	if (do_grps)
 		return intc_prio_data(desc, d, intc_grp_id(desc, enum_id), 0);
 
 	return 0;
 }
 
+static void __init intc_enable_disable_enum(struct intc_desc *desc,
+					    struct intc_desc_int *d,
+					    intc_enum enum_id, int enable)
+{
+	unsigned int i, j, data;
+
+	/* go through and enable/disable all mask bits */
+	i = j = 0;
+	do {
+		data = _intc_mask_data(desc, d, enum_id, &i, &j);
+		if (data)
+			intc_enable_disable(d, data, enable);
+		j++;
+	} while (data);
+
+	/* go through and enable/disable all priority fields */
+	i = j = 0;
+	do {
+		data = _intc_prio_data(desc, d, enum_id, &i, &j);
+		if (data)
+			intc_enable_disable(d, data, enable);
+
+		j++;
+	} while (data);
+}
+
 static unsigned int __init intc_ack_data(struct intc_desc *desc,
 					  struct intc_desc_int *d,
 					  intc_enum enum_id)
 {
-	struct intc_mask_reg *mr = desc->ack_regs;
+	struct intc_mask_reg *mr = desc->hw.ack_regs;
 	unsigned int i, j, fn, mode;
 	unsigned long reg_e, reg_d;
 
-	for (i = 0; mr && enum_id && i < desc->nr_ack_regs; i++) {
-		mr = desc->ack_regs + i;
+	for (i = 0; mr && enum_id && i < desc->hw.nr_ack_regs; i++) {
+		mr = desc->hw.ack_regs + i;
 
 		for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) {
 			if (mr->enum_ids[j] != enum_id)
@@ -549,11 +680,11 @@ static unsigned int __init intc_sense_da
 					   struct intc_desc_int *d,
 					   intc_enum enum_id)
 {
-	struct intc_sense_reg *sr = desc->sense_regs;
+	struct intc_sense_reg *sr = desc->hw.sense_regs;
 	unsigned int i, j, fn, bit;
 
-	for (i = 0; sr && enum_id && i < desc->nr_sense_regs; i++) {
-		sr = desc->sense_regs + i;
+	for (i = 0; sr && enum_id && i < desc->hw.nr_sense_regs; i++) {
+		sr = desc->hw.sense_regs + i;
 
 		for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) {
 			if (sr->enum_ids[j] != enum_id)
@@ -656,8 +787,12 @@ static void __init intc_register_irq(str
 	/* irq should be disabled by default */
 	d->chip.mask(irq);
 
-	if (desc->ack_regs)
+	if (desc->hw.ack_regs)
 		ack_handle[irq] = intc_ack_data(desc, d, enum_id);
+
+#ifdef CONFIG_ARM
+	set_irq_flags(irq, IRQF_VALID); /* Enable IRQ on ARM systems */
+#endif
 }
 
 static unsigned int __init save_reg(struct intc_desc_int *d,
@@ -684,6 +819,7 @@ static void intc_redirect_irq(unsigned i
 void __init register_intc_controller(struct intc_desc *desc)
 {
 	unsigned int i, k, smp;
+	struct intc_hw_desc *hw = &desc->hw;
 	struct intc_desc_int *d;
 
 	d = kzalloc(sizeof(*d), GFP_NOWAIT);
@@ -691,10 +827,10 @@ void __init register_intc_controller(str
 	INIT_LIST_HEAD(&d->list);
 	list_add(&d->list, &intc_list);
 
-	d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0;
-	d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;
-	d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;
-	d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0;
+	d->nr_reg = hw->mask_regs ? hw->nr_mask_regs * 2 : 0;
+	d->nr_reg += hw->prio_regs ? hw->nr_prio_regs * 2 : 0;
+	d->nr_reg += hw->sense_regs ? hw->nr_sense_regs : 0;
+	d->nr_reg += hw->ack_regs ? hw->nr_ack_regs : 0;
 
 	d->reg = kzalloc(d->nr_reg * sizeof(*d->reg), GFP_NOWAIT);
 #ifdef CONFIG_SMP
@@ -702,30 +838,31 @@ void __init register_intc_controller(str
 #endif
 	k = 0;
 
-	if (desc->mask_regs) {
-		for (i = 0; i < desc->nr_mask_regs; i++) {
-			smp = IS_SMP(desc->mask_regs[i]);
-			k += save_reg(d, k, desc->mask_regs[i].set_reg, smp);
-			k += save_reg(d, k, desc->mask_regs[i].clr_reg, smp);
+	if (hw->mask_regs) {
+		for (i = 0; i < hw->nr_mask_regs; i++) {
+			smp = IS_SMP(hw->mask_regs[i]);
+			k += save_reg(d, k, hw->mask_regs[i].set_reg, smp);
+			k += save_reg(d, k, hw->mask_regs[i].clr_reg, smp);
 		}
 	}
 
-	if (desc->prio_regs) {
-		d->prio = kzalloc(desc->nr_vectors * sizeof(*d->prio), GFP_NOWAIT);
+	if (hw->prio_regs) {
+		d->prio = kzalloc(hw->nr_vectors * sizeof(*d->prio),
+				  GFP_NOWAIT);
 
-		for (i = 0; i < desc->nr_prio_regs; i++) {
-			smp = IS_SMP(desc->prio_regs[i]);
-			k += save_reg(d, k, desc->prio_regs[i].set_reg, smp);
-			k += save_reg(d, k, desc->prio_regs[i].clr_reg, smp);
+		for (i = 0; i < hw->nr_prio_regs; i++) {
+			smp = IS_SMP(hw->prio_regs[i]);
+			k += save_reg(d, k, hw->prio_regs[i].set_reg, smp);
+			k += save_reg(d, k, hw->prio_regs[i].clr_reg, smp);
 		}
 	}
 
-	if (desc->sense_regs) {
-		d->sense = kzalloc(desc->nr_vectors * sizeof(*d->sense), GFP_NOWAIT);
+	if (hw->sense_regs) {
+		d->sense = kzalloc(hw->nr_vectors * sizeof(*d->sense),
+				   GFP_NOWAIT);
 
-		for (i = 0; i < desc->nr_sense_regs; i++) {
-			k += save_reg(d, k, desc->sense_regs[i].reg, 0);
-		}
+		for (i = 0; i < hw->nr_sense_regs; i++)
+			k += save_reg(d, k, hw->sense_regs[i].reg, 0);
 	}
 
 	d->chip.name = desc->name;
@@ -737,19 +874,30 @@ void __init register_intc_controller(str
 	d->chip.shutdown = intc_disable;
 	d->chip.set_type = intc_set_sense;
 	d->chip.set_wake = intc_set_wake;
+#ifdef CONFIG_SMP
+	d->chip.set_affinity = intc_set_affinity;
+#endif
 
-	if (desc->ack_regs) {
-		for (i = 0; i < desc->nr_ack_regs; i++)
-			k += save_reg(d, k, desc->ack_regs[i].set_reg, 0);
+	if (hw->ack_regs) {
+		for (i = 0; i < hw->nr_ack_regs; i++)
+			k += save_reg(d, k, hw->ack_regs[i].set_reg, 0);
 
 		d->chip.mask_ack = intc_mask_ack;
 	}
 
+	/* disable bits matching force_disable before registering irqs */
+	if (desc->force_disable)
+		intc_enable_disable_enum(desc, d, desc->force_disable, 0);
+
+	/* disable bits matching force_enable before registering irqs */
+	if (desc->force_enable)
+		intc_enable_disable_enum(desc, d, desc->force_enable, 0);
+
 	BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
 
 	/* register the vectors one by one */
-	for (i = 0; i < desc->nr_vectors; i++) {
-		struct intc_vect *vect = desc->vectors + i;
+	for (i = 0; i < hw->nr_vectors; i++) {
+		struct intc_vect *vect = hw->vectors + i;
 		unsigned int irq = evt2irq(vect->vect);
 		struct irq_desc *irq_desc;
 
@@ -764,8 +912,8 @@ void __init register_intc_controller(str
 
 		intc_register_irq(desc, d, vect->enum_id, irq);
 
-		for (k = i + 1; k < desc->nr_vectors; k++) {
-			struct intc_vect *vect2 = desc->vectors + k;
+		for (k = i + 1; k < hw->nr_vectors; k++) {
+			struct intc_vect *vect2 = hw->vectors + k;
 			unsigned int irq2 = evt2irq(vect2->vect);
 
 			if (vect->enum_id != vect2->enum_id)
@@ -785,11 +933,15 @@ void __init register_intc_controller(str
 			vect2->enum_id = 0;
 
 			/* redirect this interrupts to the first one */
-			set_irq_chip_and_handler_name(irq2, &d->chip,
-					intc_redirect_irq, "redirect");
+			set_irq_chip(irq2, &dummy_irq_chip);
+			set_irq_chained_handler(irq2, intc_redirect_irq);
 			set_irq_data(irq2, (void *)irq);
 		}
 	}
+
+	/* enable bits matching force_enable after registering irqs */
+	if (desc->force_enable)
+		intc_enable_disable_enum(desc, d, desc->force_enable, 1);
 }
 
 static int intc_suspend(struct sys_device *dev, pm_message_t state)
@@ -872,7 +1024,7 @@ device_initcall(register_intc_sysdevs);
 /*
  * Dynamic IRQ allocation and deallocation
  */
-static unsigned int create_irq_on_node(unsigned int irq_want, int node)
+unsigned int create_irq_nr(unsigned int irq_want, int node)
 {
 	unsigned int irq = 0, new;
 	unsigned long flags;
@@ -881,29 +1033,37 @@ static unsigned int create_irq_on_node(u
 	spin_lock_irqsave(&vector_lock, flags);
 
 	/*
-	 * First try the wanted IRQ, then scan.
+	 * First try the wanted IRQ
 	 */
-	if (test_and_set_bit(irq_want, intc_irq_map)) {
+	if (test_and_set_bit(irq_want, intc_irq_map) == 0) {
+		new = irq_want;
+	} else {
+		/* .. then fall back to scanning. */
 		new = find_first_zero_bit(intc_irq_map, nr_irqs);
 		if (unlikely(new == nr_irqs))
 			goto out_unlock;
 
-		desc = irq_to_desc_alloc_node(new, node);
-		if (unlikely(!desc)) {
-			pr_info("can't get irq_desc for %d\n", new);
-			goto out_unlock;
-		}
-
-		desc = move_irq_desc(desc, node);
 		__set_bit(new, intc_irq_map);
-		irq = new;
 	}
 
+	desc = irq_to_desc_alloc_node(new, node);
+	if (unlikely(!desc)) {
+		pr_info("can't get irq_desc for %d\n", new);
+		goto out_unlock;
+	}
+
+	desc = move_irq_desc(desc, node);
+	irq = new;
+
 out_unlock:
 	spin_unlock_irqrestore(&vector_lock, flags);
 
-	if (irq > 0)
+	if (irq > 0) {
 		dynamic_irq_init(irq);
+#ifdef CONFIG_ARM
+		set_irq_flags(irq, IRQF_VALID); /* Enable IRQ on ARM systems */
+#endif
+	}
 
 	return irq;
 }
@@ -913,7 +1073,7 @@ int create_irq(void)
 	int nid = cpu_to_node(smp_processor_id());
 	int irq;
 
-	irq = create_irq_on_node(NR_IRQS_LEGACY, nid);
+	irq = create_irq_nr(NR_IRQS_LEGACY, nid);
 	if (irq == 0)
 		irq = -1;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/sh/pfc.c linux-libre-2.6.34-gnu1/drivers/sh/pfc.c
--- linux-libre-2.6.33-gnu1/drivers/sh/pfc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/sh/pfc.c	2010-05-16 17:17:36.000000000 -0400
@@ -337,12 +337,39 @@ static int pinmux_config_gpio(struct pin
 		if (!enum_id)
 			break;
 
+		/* first check if this is a function enum */
 		in_range = enum_in_range(enum_id, &gpioc->function);
-		if (!in_range && range) {
-			in_range = enum_in_range(enum_id, range);
+		if (!in_range) {
+			/* not a function enum */
+			if (range) {
+				/*
+				 * other range exists, so this pin is
+				 * a regular GPIO pin that now is being
+				 * bound to a specific direction.
+				 *
+				 * for this case we only allow function enums
+				 * and the enums that match the other range.
+				 */
+				in_range = enum_in_range(enum_id, range);
 
-			if (in_range && enum_id == range->force)
-				continue;
+				/*
+				 * special case pass through for fixed
+				 * input-only or output-only pins without
+				 * function enum register association.
+				 */
+				if (in_range && enum_id == range->force)
+					continue;
+			} else {
+				/*
+				 * no other range exists, so this pin
+				 * must then be of the function type.
+				 *
+				 * allow function type pins to select
+				 * any combination of function/in/out
+				 * in their MARK lists.
+				 */
+				in_range = 1;
+			}
 		}
 
 		if (!in_range)
diff -druNp linux-libre-2.6.33-gnu1/drivers/sn/ioc3.c linux-libre-2.6.34-gnu1/drivers/sn/ioc3.c
--- linux-libre-2.6.33-gnu1/drivers/sn/ioc3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/sn/ioc3.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/ioc3.h>
 #include <linux/rwsem.h>
+#include <linux/slab.h>
 
 #define IOC3_PCI_SIZE 0x100000
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/amba-pl022.c linux-libre-2.6.34-gnu1/drivers/spi/amba-pl022.c
--- linux-libre-2.6.33-gnu1/drivers/spi/amba-pl022.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/amba-pl022.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/pl022.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 /*
  * This macro is used to define some register default values.
@@ -363,6 +364,7 @@ struct pl022 {
 	void				*rx_end;
 	enum ssp_reading		read;
 	enum ssp_writing		write;
+	u32				exp_fifo_level;
 };
 
 /**
@@ -501,6 +503,9 @@ static int flush(struct pl022 *pl022)
 		while (readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_RNE)
 			readw(SSP_DR(pl022->virtbase));
 	} while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_BSY) && limit--);
+
+	pl022->exp_fifo_level = 0;
+
 	return limit;
 }
 
@@ -583,10 +588,9 @@ static void readwriter(struct pl022 *pl0
 	 * errons in 8bit wide transfers on ARM variants (just 8 words
 	 * FIFO, means only 8x8 = 64 bits in FIFO) at least.
 	 *
-	 * FIXME: currently we have no logic to account for this.
-	 * perhaps there is even something broken in HW regarding
-	 * 8bit transfers (it doesn't fail on 16bit) so this needs
-	 * more investigation...
+	 * To prevent this issue, the TX FIFO is only filled to the
+	 * unused RX FIFO fill length, regardless of what the TX
+	 * FIFO status flag indicates.
 	 */
 	dev_dbg(&pl022->adev->dev,
 		"%s, rx: %p, rxend: %p, tx: %p, txend: %p\n",
@@ -613,11 +617,12 @@ static void readwriter(struct pl022 *pl0
 			break;
 		}
 		pl022->rx += (pl022->cur_chip->n_bytes);
+		pl022->exp_fifo_level--;
 	}
 	/*
-	 * Write as much as you can, while keeping an eye on the RX FIFO!
+	 * Write as much as possible up to the RX FIFO size
 	 */
-	while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_TNF)
+	while ((pl022->exp_fifo_level < pl022->vendor->fifodepth)
 	       && (pl022->tx < pl022->tx_end)) {
 		switch (pl022->write) {
 		case WRITING_NULL:
@@ -634,6 +639,7 @@ static void readwriter(struct pl022 *pl0
 			break;
 		}
 		pl022->tx += (pl022->cur_chip->n_bytes);
+		pl022->exp_fifo_level++;
 		/*
 		 * This inner reader takes care of things appearing in the RX
 		 * FIFO as we're transmitting. This will happen a lot since the
@@ -660,6 +666,7 @@ static void readwriter(struct pl022 *pl0
 				break;
 			}
 			pl022->rx += (pl022->cur_chip->n_bytes);
+			pl022->exp_fifo_level--;
 		}
 	}
 	/*
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/atmel_spi.c linux-libre-2.6.34-gnu1/drivers/spi/atmel_spi.c
--- linux-libre-2.6.33-gnu1/drivers/spi/atmel_spi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/atmel_spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <mach/board.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/au1550_spi.c linux-libre-2.6.34-gnu1/drivers/spi/au1550_spi.c
--- linux-libre-2.6.33-gnu1/drivers/spi/au1550_spi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/au1550_spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
@@ -412,11 +413,13 @@ static int au1550_spi_dma_txrxb(struct s
 	}
 
 	/* put buffers on the ring */
-	res = au1xxx_dbdma_put_dest(hw->dma_rx_ch, hw->rx, t->len);
+	res = au1xxx_dbdma_put_dest(hw->dma_rx_ch, virt_to_phys(hw->rx),
+				    t->len, DDMA_FLAGS_IE);
 	if (!res)
 		dev_err(hw->dev, "rx dma put dest error\n");
 
-	res = au1xxx_dbdma_put_source(hw->dma_tx_ch, (void *)hw->tx, t->len);
+	res = au1xxx_dbdma_put_source(hw->dma_tx_ch, virt_to_phys(hw->tx),
+				      t->len, DDMA_FLAGS_IE);
 	if (!res)
 		dev_err(hw->dev, "tx dma put source error\n");
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/coldfire_qspi.c linux-libre-2.6.34-gnu1/drivers/spi/coldfire_qspi.c
--- linux-libre-2.6.33-gnu1/drivers/spi/coldfire_qspi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/coldfire_qspi.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,640 @@
+/*
+ * Freescale/Motorola Coldfire Queued SPI driver
+ *
+ * Copyright 2010 Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/spi/spi.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfqspi.h>
+
+#define	DRIVER_NAME "mcfqspi"
+
+#define	MCFQSPI_BUSCLK			(MCF_BUSCLK / 2)
+
+#define	MCFQSPI_QMR			0x00
+#define		MCFQSPI_QMR_MSTR	0x8000
+#define		MCFQSPI_QMR_CPOL	0x0200
+#define		MCFQSPI_QMR_CPHA	0x0100
+#define	MCFQSPI_QDLYR			0x04
+#define		MCFQSPI_QDLYR_SPE	0x8000
+#define	MCFQSPI_QWR			0x08
+#define		MCFQSPI_QWR_HALT	0x8000
+#define		MCFQSPI_QWR_WREN	0x4000
+#define		MCFQSPI_QWR_CSIV	0x1000
+#define	MCFQSPI_QIR			0x0C
+#define		MCFQSPI_QIR_WCEFB	0x8000
+#define		MCFQSPI_QIR_ABRTB	0x4000
+#define		MCFQSPI_QIR_ABRTL	0x1000
+#define		MCFQSPI_QIR_WCEFE	0x0800
+#define		MCFQSPI_QIR_ABRTE	0x0400
+#define		MCFQSPI_QIR_SPIFE	0x0100
+#define		MCFQSPI_QIR_WCEF	0x0008
+#define		MCFQSPI_QIR_ABRT	0x0004
+#define		MCFQSPI_QIR_SPIF	0x0001
+#define	MCFQSPI_QAR			0x010
+#define		MCFQSPI_QAR_TXBUF	0x00
+#define		MCFQSPI_QAR_RXBUF	0x10
+#define		MCFQSPI_QAR_CMDBUF	0x20
+#define	MCFQSPI_QDR			0x014
+#define	MCFQSPI_QCR			0x014
+#define		MCFQSPI_QCR_CONT	0x8000
+#define		MCFQSPI_QCR_BITSE	0x4000
+#define		MCFQSPI_QCR_DT		0x2000
+
+struct mcfqspi {
+	void __iomem *iobase;
+	int irq;
+	struct clk *clk;
+	struct mcfqspi_cs_control *cs_control;
+
+	wait_queue_head_t waitq;
+
+	struct work_struct work;
+	struct workqueue_struct *workq;
+	spinlock_t lock;
+	struct list_head msgq;
+};
+
+static void mcfqspi_wr_qmr(struct mcfqspi *mcfqspi, u16 val)
+{
+	writew(val, mcfqspi->iobase + MCFQSPI_QMR);
+}
+
+static void mcfqspi_wr_qdlyr(struct mcfqspi *mcfqspi, u16 val)
+{
+	writew(val, mcfqspi->iobase + MCFQSPI_QDLYR);
+}
+
+static u16 mcfqspi_rd_qdlyr(struct mcfqspi *mcfqspi)
+{
+	return readw(mcfqspi->iobase + MCFQSPI_QDLYR);
+}
+
+static void mcfqspi_wr_qwr(struct mcfqspi *mcfqspi, u16 val)
+{
+	writew(val, mcfqspi->iobase + MCFQSPI_QWR);
+}
+
+static void mcfqspi_wr_qir(struct mcfqspi *mcfqspi, u16 val)
+{
+	writew(val, mcfqspi->iobase + MCFQSPI_QIR);
+}
+
+static void mcfqspi_wr_qar(struct mcfqspi *mcfqspi, u16 val)
+{
+	writew(val, mcfqspi->iobase + MCFQSPI_QAR);
+}
+
+static void mcfqspi_wr_qdr(struct mcfqspi *mcfqspi, u16 val)
+{
+	writew(val, mcfqspi->iobase + MCFQSPI_QDR);
+}
+
+static u16 mcfqspi_rd_qdr(struct mcfqspi *mcfqspi)
+{
+	return readw(mcfqspi->iobase + MCFQSPI_QDR);
+}
+
+static void mcfqspi_cs_select(struct mcfqspi *mcfqspi, u8 chip_select,
+			    bool cs_high)
+{
+	mcfqspi->cs_control->select(mcfqspi->cs_control, chip_select, cs_high);
+}
+
+static void mcfqspi_cs_deselect(struct mcfqspi *mcfqspi, u8 chip_select,
+				bool cs_high)
+{
+	mcfqspi->cs_control->deselect(mcfqspi->cs_control, chip_select, cs_high);
+}
+
+static int mcfqspi_cs_setup(struct mcfqspi *mcfqspi)
+{
+	return (mcfqspi->cs_control && mcfqspi->cs_control->setup) ?
+		mcfqspi->cs_control->setup(mcfqspi->cs_control) : 0;
+}
+
+static void mcfqspi_cs_teardown(struct mcfqspi *mcfqspi)
+{
+	if (mcfqspi->cs_control && mcfqspi->cs_control->teardown)
+		mcfqspi->cs_control->teardown(mcfqspi->cs_control);
+}
+
+static u8 mcfqspi_qmr_baud(u32 speed_hz)
+{
+	return clamp((MCFQSPI_BUSCLK + speed_hz - 1) / speed_hz, 2u, 255u);
+}
+
+static bool mcfqspi_qdlyr_spe(struct mcfqspi *mcfqspi)
+{
+	return mcfqspi_rd_qdlyr(mcfqspi) & MCFQSPI_QDLYR_SPE;
+}
+
+static irqreturn_t mcfqspi_irq_handler(int this_irq, void *dev_id)
+{
+	struct mcfqspi *mcfqspi = dev_id;
+
+	/* clear interrupt */
+	mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE | MCFQSPI_QIR_SPIF);
+	wake_up(&mcfqspi->waitq);
+
+	return IRQ_HANDLED;
+}
+
+static void mcfqspi_transfer_msg8(struct mcfqspi *mcfqspi, unsigned count,
+				  const u8 *txbuf, u8 *rxbuf)
+{
+	unsigned i, n, offset = 0;
+
+	n = min(count, 16u);
+
+	mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_CMDBUF);
+	for (i = 0; i < n; ++i)
+		mcfqspi_wr_qdr(mcfqspi, MCFQSPI_QCR_BITSE);
+
+	mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_TXBUF);
+	if (txbuf)
+		for (i = 0; i < n; ++i)
+			mcfqspi_wr_qdr(mcfqspi, *txbuf++);
+	else
+		for (i = 0; i < count; ++i)
+			mcfqspi_wr_qdr(mcfqspi, 0);
+
+	count -= n;
+	if (count) {
+		u16 qwr = 0xf08;
+		mcfqspi_wr_qwr(mcfqspi, 0x700);
+		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
+
+		do {
+			wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
+			mcfqspi_wr_qwr(mcfqspi, qwr);
+			mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
+			if (rxbuf) {
+				mcfqspi_wr_qar(mcfqspi,
+					       MCFQSPI_QAR_RXBUF + offset);
+				for (i = 0; i < 8; ++i)
+					*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
+			}
+			n = min(count, 8u);
+			if (txbuf) {
+				mcfqspi_wr_qar(mcfqspi,
+					       MCFQSPI_QAR_TXBUF + offset);
+				for (i = 0; i < n; ++i)
+					mcfqspi_wr_qdr(mcfqspi, *txbuf++);
+			}
+			qwr = (offset ? 0x808 : 0) + ((n - 1) << 8);
+			offset ^= 8;
+			count -= n;
+		} while (count);
+		wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
+		mcfqspi_wr_qwr(mcfqspi, qwr);
+		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
+		if (rxbuf) {
+			mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
+			for (i = 0; i < 8; ++i)
+				*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
+			offset ^= 8;
+		}
+	} else {
+		mcfqspi_wr_qwr(mcfqspi, (n - 1) << 8);
+		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
+	}
+	wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
+	if (rxbuf) {
+		mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
+		for (i = 0; i < n; ++i)
+			*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
+	}
+}
+
+static void mcfqspi_transfer_msg16(struct mcfqspi *mcfqspi, unsigned count,
+				   const u16 *txbuf, u16 *rxbuf)
+{
+	unsigned i, n, offset = 0;
+
+	n = min(count, 16u);
+
+	mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_CMDBUF);
+	for (i = 0; i < n; ++i)
+		mcfqspi_wr_qdr(mcfqspi, MCFQSPI_QCR_BITSE);
+
+	mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_TXBUF);
+	if (txbuf)
+		for (i = 0; i < n; ++i)
+			mcfqspi_wr_qdr(mcfqspi, *txbuf++);
+	else
+		for (i = 0; i < count; ++i)
+			mcfqspi_wr_qdr(mcfqspi, 0);
+
+	count -= n;
+	if (count) {
+		u16 qwr = 0xf08;
+		mcfqspi_wr_qwr(mcfqspi, 0x700);
+		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
+
+		do {
+			wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
+			mcfqspi_wr_qwr(mcfqspi, qwr);
+			mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
+			if (rxbuf) {
+				mcfqspi_wr_qar(mcfqspi,
+					       MCFQSPI_QAR_RXBUF + offset);
+				for (i = 0; i < 8; ++i)
+					*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
+			}
+			n = min(count, 8u);
+			if (txbuf) {
+				mcfqspi_wr_qar(mcfqspi,
+					       MCFQSPI_QAR_TXBUF + offset);
+				for (i = 0; i < n; ++i)
+					mcfqspi_wr_qdr(mcfqspi, *txbuf++);
+			}
+			qwr = (offset ? 0x808 : 0x000) + ((n - 1) << 8);
+			offset ^= 8;
+			count -= n;
+		} while (count);
+		wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
+		mcfqspi_wr_qwr(mcfqspi, qwr);
+		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
+		if (rxbuf) {
+			mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
+			for (i = 0; i < 8; ++i)
+				*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
+			offset ^= 8;
+		}
+	} else {
+		mcfqspi_wr_qwr(mcfqspi, (n - 1) << 8);
+		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
+	}
+	wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
+	if (rxbuf) {
+		mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
+		for (i = 0; i < n; ++i)
+			*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
+	}
+}
+
+static void mcfqspi_work(struct work_struct *work)
+{
+	struct mcfqspi *mcfqspi = container_of(work, struct mcfqspi, work);
+	unsigned long flags;
+
+	spin_lock_irqsave(&mcfqspi->lock, flags);
+	while (!list_empty(&mcfqspi->msgq)) {
+		struct spi_message *msg;
+		struct spi_device *spi;
+		struct spi_transfer *xfer;
+		int status = 0;
+
+		msg = container_of(mcfqspi->msgq.next, struct spi_message,
+				   queue);
+
+		list_del_init(&mcfqspi->msgq);
+		spin_unlock_irqrestore(&mcfqspi->lock, flags);
+
+		spi = msg->spi;
+
+		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+			bool cs_high = spi->mode & SPI_CS_HIGH;
+			u16 qmr = MCFQSPI_QMR_MSTR;
+
+			if (xfer->bits_per_word)
+				qmr |= xfer->bits_per_word << 10;
+			else
+				qmr |= spi->bits_per_word << 10;
+			if (spi->mode & SPI_CPHA)
+				qmr |= MCFQSPI_QMR_CPHA;
+			if (spi->mode & SPI_CPOL)
+				qmr |= MCFQSPI_QMR_CPOL;
+			if (xfer->speed_hz)
+				qmr |= mcfqspi_qmr_baud(xfer->speed_hz);
+			else
+				qmr |= mcfqspi_qmr_baud(spi->max_speed_hz);
+			mcfqspi_wr_qmr(mcfqspi, qmr);
+
+			mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high);
+
+			mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE);
+			if ((xfer->bits_per_word ? xfer->bits_per_word :
+						spi->bits_per_word) == 8)
+				mcfqspi_transfer_msg8(mcfqspi, xfer->len,
+						      xfer->tx_buf,
+						      xfer->rx_buf);
+			else
+				mcfqspi_transfer_msg16(mcfqspi, xfer->len / 2,
+						       xfer->tx_buf,
+						       xfer->rx_buf);
+			mcfqspi_wr_qir(mcfqspi, 0);
+
+			if (xfer->delay_usecs)
+				udelay(xfer->delay_usecs);
+			if (xfer->cs_change) {
+				if (!list_is_last(&xfer->transfer_list,
+						  &msg->transfers))
+					mcfqspi_cs_deselect(mcfqspi,
+							    spi->chip_select,
+							    cs_high);
+			} else {
+				if (list_is_last(&xfer->transfer_list,
+						 &msg->transfers))
+					mcfqspi_cs_deselect(mcfqspi,
+							    spi->chip_select,
+							    cs_high);
+			}
+			msg->actual_length += xfer->len;
+		}
+		msg->status = status;
+		msg->complete(msg->context);
+
+		spin_lock_irqsave(&mcfqspi->lock, flags);
+	}
+	spin_unlock_irqrestore(&mcfqspi->lock, flags);
+}
+
+static int mcfqspi_transfer(struct spi_device *spi, struct spi_message *msg)
+{
+	struct mcfqspi *mcfqspi;
+	struct spi_transfer *xfer;
+	unsigned long flags;
+
+	mcfqspi = spi_master_get_devdata(spi->master);
+
+	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+		if (xfer->bits_per_word && ((xfer->bits_per_word < 8)
+					|| (xfer->bits_per_word > 16))) {
+			dev_dbg(&spi->dev,
+				"%d bits per word is not supported\n",
+				xfer->bits_per_word);
+			goto fail;
+		}
+		if (xfer->speed_hz) {
+			u32 real_speed = MCFQSPI_BUSCLK /
+				mcfqspi_qmr_baud(xfer->speed_hz);
+			if (real_speed != xfer->speed_hz)
+				dev_dbg(&spi->dev,
+					"using speed %d instead of %d\n",
+					real_speed, xfer->speed_hz);
+		}
+	}
+	msg->status = -EINPROGRESS;
+	msg->actual_length = 0;
+
+	spin_lock_irqsave(&mcfqspi->lock, flags);
+	list_add_tail(&msg->queue, &mcfqspi->msgq);
+	queue_work(mcfqspi->workq, &mcfqspi->work);
+	spin_unlock_irqrestore(&mcfqspi->lock, flags);
+
+	return 0;
+fail:
+	msg->status = -EINVAL;
+	return -EINVAL;
+}
+
+static int mcfqspi_setup(struct spi_device *spi)
+{
+	if ((spi->bits_per_word < 8) || (spi->bits_per_word > 16)) {
+		dev_dbg(&spi->dev, "%d bits per word is not supported\n",
+			spi->bits_per_word);
+		return -EINVAL;
+	}
+	if (spi->chip_select >= spi->master->num_chipselect) {
+		dev_dbg(&spi->dev, "%d chip select is out of range\n",
+			spi->chip_select);
+		return -EINVAL;
+	}
+
+	mcfqspi_cs_deselect(spi_master_get_devdata(spi->master),
+			    spi->chip_select, spi->mode & SPI_CS_HIGH);
+
+	dev_dbg(&spi->dev,
+			"bits per word %d, chip select %d, speed %d KHz\n",
+			spi->bits_per_word, spi->chip_select,
+			(MCFQSPI_BUSCLK / mcfqspi_qmr_baud(spi->max_speed_hz))
+			/ 1000);
+
+	return 0;
+}
+
+static int __devinit mcfqspi_probe(struct platform_device *pdev)
+{
+	struct spi_master *master;
+	struct mcfqspi *mcfqspi;
+	struct resource *res;
+	struct mcfqspi_platform_data *pdata;
+	int status;
+
+	master = spi_alloc_master(&pdev->dev, sizeof(*mcfqspi));
+	if (master == NULL) {
+		dev_dbg(&pdev->dev, "spi_alloc_master failed\n");
+		return -ENOMEM;
+	}
+
+	mcfqspi = spi_master_get_devdata(master);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_dbg(&pdev->dev, "platform_get_resource failed\n");
+		status = -ENXIO;
+		goto fail0;
+	}
+
+	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
+		dev_dbg(&pdev->dev, "request_mem_region failed\n");
+		status = -EBUSY;
+		goto fail0;
+	}
+
+	mcfqspi->iobase = ioremap(res->start, resource_size(res));
+	if (!mcfqspi->iobase) {
+		dev_dbg(&pdev->dev, "ioremap failed\n");
+		status = -ENOMEM;
+		goto fail1;
+	}
+
+	mcfqspi->irq = platform_get_irq(pdev, 0);
+	if (mcfqspi->irq < 0) {
+		dev_dbg(&pdev->dev, "platform_get_irq failed\n");
+		status = -ENXIO;
+		goto fail2;
+	}
+
+	status = request_irq(mcfqspi->irq, mcfqspi_irq_handler, IRQF_DISABLED,
+			     pdev->name, mcfqspi);
+	if (status) {
+		dev_dbg(&pdev->dev, "request_irq failed\n");
+		goto fail2;
+	}
+
+	mcfqspi->clk = clk_get(&pdev->dev, "qspi_clk");
+	if (IS_ERR(mcfqspi->clk)) {
+		dev_dbg(&pdev->dev, "clk_get failed\n");
+		status = PTR_ERR(mcfqspi->clk);
+		goto fail3;
+	}
+	clk_enable(mcfqspi->clk);
+
+	mcfqspi->workq = create_singlethread_workqueue(dev_name(master->dev.parent));
+	if (!mcfqspi->workq) {
+		dev_dbg(&pdev->dev, "create_workqueue failed\n");
+		status = -ENOMEM;
+		goto fail4;
+	}
+	INIT_WORK(&mcfqspi->work, mcfqspi_work);
+	spin_lock_init(&mcfqspi->lock);
+	INIT_LIST_HEAD(&mcfqspi->msgq);
+	init_waitqueue_head(&mcfqspi->waitq);
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_dbg(&pdev->dev, "platform data is missing\n");
+		goto fail5;
+	}
+	master->bus_num = pdata->bus_num;
+	master->num_chipselect = pdata->num_chipselect;
+
+	mcfqspi->cs_control = pdata->cs_control;
+	status = mcfqspi_cs_setup(mcfqspi);
+	if (status) {
+		dev_dbg(&pdev->dev, "error initializing cs_control\n");
+		goto fail5;
+	}
+
+	master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA;
+	master->setup = mcfqspi_setup;
+	master->transfer = mcfqspi_transfer;
+
+	platform_set_drvdata(pdev, master);
+
+	status = spi_register_master(master);
+	if (status) {
+		dev_dbg(&pdev->dev, "spi_register_master failed\n");
+		goto fail6;
+	}
+	dev_info(&pdev->dev, "Coldfire QSPI bus driver\n");
+
+	return 0;
+
+fail6:
+	mcfqspi_cs_teardown(mcfqspi);
+fail5:
+	destroy_workqueue(mcfqspi->workq);
+fail4:
+	clk_disable(mcfqspi->clk);
+	clk_put(mcfqspi->clk);
+fail3:
+	free_irq(mcfqspi->irq, mcfqspi);
+fail2:
+	iounmap(mcfqspi->iobase);
+fail1:
+	release_mem_region(res->start, resource_size(res));
+fail0:
+	spi_master_put(master);
+
+	dev_dbg(&pdev->dev, "Coldfire QSPI probe failed\n");
+
+	return status;
+}
+
+static int __devexit mcfqspi_remove(struct platform_device *pdev)
+{
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	/* disable the hardware (set the baud rate to 0) */
+	mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR);
+
+	platform_set_drvdata(pdev, NULL);
+	mcfqspi_cs_teardown(mcfqspi);
+	destroy_workqueue(mcfqspi->workq);
+	clk_disable(mcfqspi->clk);
+	clk_put(mcfqspi->clk);
+	free_irq(mcfqspi->irq, mcfqspi);
+	iounmap(mcfqspi->iobase);
+	release_mem_region(res->start, resource_size(res));
+	spi_unregister_master(master);
+	spi_master_put(master);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int mcfqspi_suspend(struct device *dev)
+{
+	struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));
+
+	clk_disable(mcfqspi->clk);
+
+	return 0;
+}
+
+static int mcfqspi_resume(struct device *dev)
+{
+	struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));
+
+	clk_enable(mcfqspi->clk);
+
+	return 0;
+}
+
+static struct dev_pm_ops mcfqspi_dev_pm_ops = {
+	.suspend	= mcfqspi_suspend,
+	.resume		= mcfqspi_resume,
+};
+
+#define	MCFQSPI_DEV_PM_OPS	(&mcfqspi_dev_pm_ops)
+#else
+#define	MCFQSPI_DEV_PM_OPS	NULL
+#endif
+
+static struct platform_driver mcfqspi_driver = {
+	.driver.name	= DRIVER_NAME,
+	.driver.owner	= THIS_MODULE,
+	.driver.pm	= MCFQSPI_DEV_PM_OPS,
+	.remove		= __devexit_p(mcfqspi_remove),
+};
+
+static int __init mcfqspi_init(void)
+{
+	return platform_driver_probe(&mcfqspi_driver, mcfqspi_probe);
+}
+module_init(mcfqspi_init);
+
+static void __exit mcfqspi_exit(void)
+{
+	platform_driver_unregister(&mcfqspi_driver);
+}
+module_exit(mcfqspi_exit);
+
+MODULE_AUTHOR("Steven King <sfking@fdwdc.com>");
+MODULE_DESCRIPTION("Coldfire QSPI Controller Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/davinci_spi.c linux-libre-2.6.34-gnu1/drivers/spi/davinci_spi.c
--- linux-libre-2.6.33-gnu1/drivers/spi/davinci_spi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/davinci_spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1256 @@
+/*
+ * Copyright (C) 2009 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <linux/slab.h>
+
+#include <mach/spi.h>
+#include <mach/edma.h>
+
+#define SPI_NO_RESOURCE		((resource_size_t)-1)
+
+#define SPI_MAX_CHIPSELECT	2
+
+#define CS_DEFAULT	0xFF
+
+#define SPI_BUFSIZ	(SMP_CACHE_BYTES + 1)
+#define DAVINCI_DMA_DATA_TYPE_S8	0x01
+#define DAVINCI_DMA_DATA_TYPE_S16	0x02
+#define DAVINCI_DMA_DATA_TYPE_S32	0x04
+
+#define SPIFMT_PHASE_MASK	BIT(16)
+#define SPIFMT_POLARITY_MASK	BIT(17)
+#define SPIFMT_DISTIMER_MASK	BIT(18)
+#define SPIFMT_SHIFTDIR_MASK	BIT(20)
+#define SPIFMT_WAITENA_MASK	BIT(21)
+#define SPIFMT_PARITYENA_MASK	BIT(22)
+#define SPIFMT_ODD_PARITY_MASK	BIT(23)
+#define SPIFMT_WDELAY_MASK	0x3f000000u
+#define SPIFMT_WDELAY_SHIFT	24
+#define SPIFMT_CHARLEN_MASK	0x0000001Fu
+
+/* SPIGCR1 */
+#define SPIGCR1_SPIENA_MASK	0x01000000u
+
+/* SPIPC0 */
+#define SPIPC0_DIFUN_MASK	BIT(11)		/* MISO */
+#define SPIPC0_DOFUN_MASK	BIT(10)		/* MOSI */
+#define SPIPC0_CLKFUN_MASK	BIT(9)		/* CLK */
+#define SPIPC0_SPIENA_MASK	BIT(8)		/* nREADY */
+#define SPIPC0_EN1FUN_MASK	BIT(1)
+#define SPIPC0_EN0FUN_MASK	BIT(0)
+
+#define SPIINT_MASKALL		0x0101035F
+#define SPI_INTLVL_1		0x000001FFu
+#define SPI_INTLVL_0		0x00000000u
+
+/* SPIDAT1 */
+#define SPIDAT1_CSHOLD_SHIFT	28
+#define SPIDAT1_CSNR_SHIFT	16
+#define SPIGCR1_CLKMOD_MASK	BIT(1)
+#define SPIGCR1_MASTER_MASK     BIT(0)
+#define SPIGCR1_LOOPBACK_MASK	BIT(16)
+
+/* SPIBUF */
+#define SPIBUF_TXFULL_MASK	BIT(29)
+#define SPIBUF_RXEMPTY_MASK	BIT(31)
+
+/* Error Masks */
+#define SPIFLG_DLEN_ERR_MASK		BIT(0)
+#define SPIFLG_TIMEOUT_MASK		BIT(1)
+#define SPIFLG_PARERR_MASK		BIT(2)
+#define SPIFLG_DESYNC_MASK		BIT(3)
+#define SPIFLG_BITERR_MASK		BIT(4)
+#define SPIFLG_OVRRUN_MASK		BIT(6)
+#define SPIFLG_RX_INTR_MASK		BIT(8)
+#define SPIFLG_TX_INTR_MASK		BIT(9)
+#define SPIFLG_BUF_INIT_ACTIVE_MASK	BIT(24)
+#define SPIFLG_MASK			(SPIFLG_DLEN_ERR_MASK \
+				| SPIFLG_TIMEOUT_MASK | SPIFLG_PARERR_MASK \
+				| SPIFLG_DESYNC_MASK | SPIFLG_BITERR_MASK \
+				| SPIFLG_OVRRUN_MASK | SPIFLG_RX_INTR_MASK \
+				| SPIFLG_TX_INTR_MASK \
+				| SPIFLG_BUF_INIT_ACTIVE_MASK)
+
+#define SPIINT_DLEN_ERR_INTR	BIT(0)
+#define SPIINT_TIMEOUT_INTR	BIT(1)
+#define SPIINT_PARERR_INTR	BIT(2)
+#define SPIINT_DESYNC_INTR	BIT(3)
+#define SPIINT_BITERR_INTR	BIT(4)
+#define SPIINT_OVRRUN_INTR	BIT(6)
+#define SPIINT_RX_INTR		BIT(8)
+#define SPIINT_TX_INTR		BIT(9)
+#define SPIINT_DMA_REQ_EN	BIT(16)
+#define SPIINT_ENABLE_HIGHZ	BIT(24)
+
+#define SPI_T2CDELAY_SHIFT	16
+#define SPI_C2TDELAY_SHIFT	24
+
+/* SPI Controller registers */
+#define SPIGCR0		0x00
+#define SPIGCR1		0x04
+#define SPIINT		0x08
+#define SPILVL		0x0c
+#define SPIFLG		0x10
+#define SPIPC0		0x14
+#define SPIPC1		0x18
+#define SPIPC2		0x1c
+#define SPIPC3		0x20
+#define SPIPC4		0x24
+#define SPIPC5		0x28
+#define SPIPC6		0x2c
+#define SPIPC7		0x30
+#define SPIPC8		0x34
+#define SPIDAT0		0x38
+#define SPIDAT1		0x3c
+#define SPIBUF		0x40
+#define SPIEMU		0x44
+#define SPIDELAY	0x48
+#define SPIDEF		0x4c
+#define SPIFMT0		0x50
+#define SPIFMT1		0x54
+#define SPIFMT2		0x58
+#define SPIFMT3		0x5c
+#define TGINTVEC0	0x60
+#define TGINTVEC1	0x64
+
+struct davinci_spi_slave {
+	u32	cmd_to_write;
+	u32	clk_ctrl_to_write;
+	u32	bytes_per_word;
+	u8	active_cs;
+};
+
+/* We have 2 DMA channels per CS, one for RX and one for TX */
+struct davinci_spi_dma {
+	int			dma_tx_channel;
+	int			dma_rx_channel;
+	int			dma_tx_sync_dev;
+	int			dma_rx_sync_dev;
+	enum dma_event_q	eventq;
+
+	struct completion	dma_tx_completion;
+	struct completion	dma_rx_completion;
+};
+
+/* SPI Controller driver's private data. */
+struct davinci_spi {
+	struct spi_bitbang	bitbang;
+	struct clk		*clk;
+
+	u8			version;
+	resource_size_t		pbase;
+	void __iomem		*base;
+	size_t			region_size;
+	u32			irq;
+	struct completion	done;
+
+	const void		*tx;
+	void			*rx;
+	u8			*tmp_buf;
+	int			count;
+	struct davinci_spi_dma	*dma_channels;
+	struct			davinci_spi_platform_data *pdata;
+
+	void			(*get_rx)(u32 rx_data, struct davinci_spi *);
+	u32			(*get_tx)(struct davinci_spi *);
+
+	struct davinci_spi_slave slave[SPI_MAX_CHIPSELECT];
+};
+
+static unsigned use_dma;
+
+static void davinci_spi_rx_buf_u8(u32 data, struct davinci_spi *davinci_spi)
+{
+	u8 *rx = davinci_spi->rx;
+
+	*rx++ = (u8)data;
+	davinci_spi->rx = rx;
+}
+
+static void davinci_spi_rx_buf_u16(u32 data, struct davinci_spi *davinci_spi)
+{
+	u16 *rx = davinci_spi->rx;
+
+	*rx++ = (u16)data;
+	davinci_spi->rx = rx;
+}
+
+static u32 davinci_spi_tx_buf_u8(struct davinci_spi *davinci_spi)
+{
+	u32 data;
+	const u8 *tx = davinci_spi->tx;
+
+	data = *tx++;
+	davinci_spi->tx = tx;
+	return data;
+}
+
+static u32 davinci_spi_tx_buf_u16(struct davinci_spi *davinci_spi)
+{
+	u32 data;
+	const u16 *tx = davinci_spi->tx;
+
+	data = *tx++;
+	davinci_spi->tx = tx;
+	return data;
+}
+
+static inline void set_io_bits(void __iomem *addr, u32 bits)
+{
+	u32 v = ioread32(addr);
+
+	v |= bits;
+	iowrite32(v, addr);
+}
+
+static inline void clear_io_bits(void __iomem *addr, u32 bits)
+{
+	u32 v = ioread32(addr);
+
+	v &= ~bits;
+	iowrite32(v, addr);
+}
+
+static inline void set_fmt_bits(void __iomem *addr, u32 bits, int cs_num)
+{
+	set_io_bits(addr + SPIFMT0 + (0x4 * cs_num), bits);
+}
+
+static inline void clear_fmt_bits(void __iomem *addr, u32 bits, int cs_num)
+{
+	clear_io_bits(addr + SPIFMT0 + (0x4 * cs_num), bits);
+}
+
+static void davinci_spi_set_dma_req(const struct spi_device *spi, int enable)
+{
+	struct davinci_spi *davinci_spi = spi_master_get_devdata(spi->master);
+
+	if (enable)
+		set_io_bits(davinci_spi->base + SPIINT, SPIINT_DMA_REQ_EN);
+	else
+		clear_io_bits(davinci_spi->base + SPIINT, SPIINT_DMA_REQ_EN);
+}
+
+/*
+ * Interface to control the chip select signal
+ */
+static void davinci_spi_chipselect(struct spi_device *spi, int value)
+{
+	struct davinci_spi *davinci_spi;
+	struct davinci_spi_platform_data *pdata;
+	u32 data1_reg_val = 0;
+
+	davinci_spi = spi_master_get_devdata(spi->master);
+	pdata = davinci_spi->pdata;
+
+	/*
+	 * Board specific chip select logic decides the polarity and cs
+	 * line for the controller
+	 */
+	if (value == BITBANG_CS_INACTIVE) {
+		set_io_bits(davinci_spi->base + SPIDEF, CS_DEFAULT);
+
+		data1_reg_val |= CS_DEFAULT << SPIDAT1_CSNR_SHIFT;
+		iowrite32(data1_reg_val, davinci_spi->base + SPIDAT1);
+
+		while ((ioread32(davinci_spi->base + SPIBUF)
+					& SPIBUF_RXEMPTY_MASK) == 0)
+			cpu_relax();
+	}
+}
+
+/**
+ * davinci_spi_setup_transfer - This functions will determine transfer method
+ * @spi: spi device on which data transfer to be done
+ * @t: spi transfer in which transfer info is filled
+ *
+ * This function determines data transfer method (8/16/32 bit transfer).
+ * It will also set the SPI Clock Control register according to
+ * SPI slave device freq.
+ */
+static int davinci_spi_setup_transfer(struct spi_device *spi,
+		struct spi_transfer *t)
+{
+
+	struct davinci_spi *davinci_spi;
+	struct davinci_spi_platform_data *pdata;
+	u8 bits_per_word = 0;
+	u32 hz = 0, prescale;
+
+	davinci_spi = spi_master_get_devdata(spi->master);
+	pdata = davinci_spi->pdata;
+
+	if (t) {
+		bits_per_word = t->bits_per_word;
+		hz = t->speed_hz;
+	}
+
+	/* if bits_per_word is not set then set it default */
+	if (!bits_per_word)
+		bits_per_word = spi->bits_per_word;
+
+	/*
+	 * Assign function pointer to appropriate transfer method
+	 * 8bit, 16bit or 32bit transfer
+	 */
+	if (bits_per_word <= 8 && bits_per_word >= 2) {
+		davinci_spi->get_rx = davinci_spi_rx_buf_u8;
+		davinci_spi->get_tx = davinci_spi_tx_buf_u8;
+		davinci_spi->slave[spi->chip_select].bytes_per_word = 1;
+	} else if (bits_per_word <= 16 && bits_per_word >= 2) {
+		davinci_spi->get_rx = davinci_spi_rx_buf_u16;
+		davinci_spi->get_tx = davinci_spi_tx_buf_u16;
+		davinci_spi->slave[spi->chip_select].bytes_per_word = 2;
+	} else
+		return -EINVAL;
+
+	if (!hz)
+		hz = spi->max_speed_hz;
+
+	clear_fmt_bits(davinci_spi->base, SPIFMT_CHARLEN_MASK,
+			spi->chip_select);
+	set_fmt_bits(davinci_spi->base, bits_per_word & 0x1f,
+			spi->chip_select);
+
+	prescale = ((clk_get_rate(davinci_spi->clk) / hz) - 1) & 0xff;
+
+	clear_fmt_bits(davinci_spi->base, 0x0000ff00, spi->chip_select);
+	set_fmt_bits(davinci_spi->base, prescale << 8, spi->chip_select);
+
+	return 0;
+}
+
+static void davinci_spi_dma_rx_callback(unsigned lch, u16 ch_status, void *data)
+{
+	struct spi_device *spi = (struct spi_device *)data;
+	struct davinci_spi *davinci_spi;
+	struct davinci_spi_dma *davinci_spi_dma;
+	struct davinci_spi_platform_data *pdata;
+
+	davinci_spi = spi_master_get_devdata(spi->master);
+	davinci_spi_dma = &(davinci_spi->dma_channels[spi->chip_select]);
+	pdata = davinci_spi->pdata;
+
+	if (ch_status == DMA_COMPLETE)
+		edma_stop(davinci_spi_dma->dma_rx_channel);
+	else
+		edma_clean_channel(davinci_spi_dma->dma_rx_channel);
+
+	complete(&davinci_spi_dma->dma_rx_completion);
+	/* We must disable the DMA RX request */
+	davinci_spi_set_dma_req(spi, 0);
+}
+
+static void davinci_spi_dma_tx_callback(unsigned lch, u16 ch_status, void *data)
+{
+	struct spi_device *spi = (struct spi_device *)data;
+	struct davinci_spi *davinci_spi;
+	struct davinci_spi_dma *davinci_spi_dma;
+	struct davinci_spi_platform_data *pdata;
+
+	davinci_spi = spi_master_get_devdata(spi->master);
+	davinci_spi_dma = &(davinci_spi->dma_channels[spi->chip_select]);
+	pdata = davinci_spi->pdata;
+
+	if (ch_status == DMA_COMPLETE)
+		edma_stop(davinci_spi_dma->dma_tx_channel);
+	else
+		edma_clean_channel(davinci_spi_dma->dma_tx_channel);
+
+	complete(&davinci_spi_dma->dma_tx_completion);
+	/* We must disable the DMA TX request */
+	davinci_spi_set_dma_req(spi, 0);
+}
+
+static int davinci_spi_request_dma(struct spi_device *spi)
+{
+	struct davinci_spi *davinci_spi;
+	struct davinci_spi_dma *davinci_spi_dma;
+	struct davinci_spi_platform_data *pdata;
+	struct device *sdev;
+	int r;
+
+	davinci_spi = spi_master_get_devdata(spi->master);
+	davinci_spi_dma = &davinci_spi->dma_channels[spi->chip_select];
+	pdata = davinci_spi->pdata;
+	sdev = davinci_spi->bitbang.master->dev.parent;
+
+	r = edma_alloc_channel(davinci_spi_dma->dma_rx_sync_dev,
+				davinci_spi_dma_rx_callback, spi,
+				davinci_spi_dma->eventq);
+	if (r < 0) {
+		dev_dbg(sdev, "Unable to request DMA channel for SPI RX\n");
+		return -EAGAIN;
+	}
+	davinci_spi_dma->dma_rx_channel = r;
+	r = edma_alloc_channel(davinci_spi_dma->dma_tx_sync_dev,
+				davinci_spi_dma_tx_callback, spi,
+				davinci_spi_dma->eventq);
+	if (r < 0) {
+		edma_free_channel(davinci_spi_dma->dma_rx_channel);
+		davinci_spi_dma->dma_rx_channel = -1;
+		dev_dbg(sdev, "Unable to request DMA channel for SPI TX\n");
+		return -EAGAIN;
+	}
+	davinci_spi_dma->dma_tx_channel = r;
+
+	return 0;
+}
+
+/**
+ * davinci_spi_setup - This functions will set default transfer method
+ * @spi: spi device on which data transfer to be done
+ *
+ * This functions sets the default transfer method.
+ */
+
+static int davinci_spi_setup(struct spi_device *spi)
+{
+	int retval;
+	struct davinci_spi *davinci_spi;
+	struct davinci_spi_dma *davinci_spi_dma;
+	struct device *sdev;
+
+	davinci_spi = spi_master_get_devdata(spi->master);
+	sdev = davinci_spi->bitbang.master->dev.parent;
+
+	/* if bits per word length is zero then set it default 8 */
+	if (!spi->bits_per_word)
+		spi->bits_per_word = 8;
+
+	davinci_spi->slave[spi->chip_select].cmd_to_write = 0;
+
+	if (use_dma && davinci_spi->dma_channels) {
+		davinci_spi_dma = &davinci_spi->dma_channels[spi->chip_select];
+
+		if ((davinci_spi_dma->dma_rx_channel == -1)
+				|| (davinci_spi_dma->dma_tx_channel == -1)) {
+			retval = davinci_spi_request_dma(spi);
+			if (retval < 0)
+				return retval;
+		}
+	}
+
+	/*
+	 * SPI in DaVinci and DA8xx operate between
+	 * 600 KHz and 50 MHz
+	 */
+	if (spi->max_speed_hz < 600000 || spi->max_speed_hz > 50000000) {
+		dev_dbg(sdev, "Operating frequency is not in acceptable "
+				"range\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Set up SPIFMTn register, unique to this chipselect.
+	 *
+	 * NOTE: we could do all of these with one write.  Also, some
+	 * of the "version 2" features are found in chips that don't
+	 * support all of them...
+	 */
+	if (spi->mode & SPI_LSB_FIRST)
+		set_fmt_bits(davinci_spi->base, SPIFMT_SHIFTDIR_MASK,
+				spi->chip_select);
+	else
+		clear_fmt_bits(davinci_spi->base, SPIFMT_SHIFTDIR_MASK,
+				spi->chip_select);
+
+	if (spi->mode & SPI_CPOL)
+		set_fmt_bits(davinci_spi->base, SPIFMT_POLARITY_MASK,
+				spi->chip_select);
+	else
+		clear_fmt_bits(davinci_spi->base, SPIFMT_POLARITY_MASK,
+				spi->chip_select);
+
+	if (!(spi->mode & SPI_CPHA))
+		set_fmt_bits(davinci_spi->base, SPIFMT_PHASE_MASK,
+				spi->chip_select);
+	else
+		clear_fmt_bits(davinci_spi->base, SPIFMT_PHASE_MASK,
+				spi->chip_select);
+
+	/*
+	 * Version 1 hardware supports two basic SPI modes:
+	 *  - Standard SPI mode uses 4 pins, with chipselect
+	 *  - 3 pin SPI is a 4 pin variant without CS (SPI_NO_CS)
+	 *	(distinct from SPI_3WIRE, with just one data wire;
+	 *	or similar variants without MOSI or without MISO)
+	 *
+	 * Version 2 hardware supports an optional handshaking signal,
+	 * so it can support two more modes:
+	 *  - 5 pin SPI variant is standard SPI plus SPI_READY
+	 *  - 4 pin with enable is (SPI_READY | SPI_NO_CS)
+	 */
+
+	if (davinci_spi->version == SPI_VERSION_2) {
+		clear_fmt_bits(davinci_spi->base, SPIFMT_WDELAY_MASK,
+				spi->chip_select);
+		set_fmt_bits(davinci_spi->base,
+				(davinci_spi->pdata->wdelay
+						<< SPIFMT_WDELAY_SHIFT)
+					& SPIFMT_WDELAY_MASK,
+				spi->chip_select);
+
+		if (davinci_spi->pdata->odd_parity)
+			set_fmt_bits(davinci_spi->base,
+					SPIFMT_ODD_PARITY_MASK,
+					spi->chip_select);
+		else
+			clear_fmt_bits(davinci_spi->base,
+					SPIFMT_ODD_PARITY_MASK,
+					spi->chip_select);
+
+		if (davinci_spi->pdata->parity_enable)
+			set_fmt_bits(davinci_spi->base,
+					SPIFMT_PARITYENA_MASK,
+					spi->chip_select);
+		else
+			clear_fmt_bits(davinci_spi->base,
+					SPIFMT_PARITYENA_MASK,
+					spi->chip_select);
+
+		if (davinci_spi->pdata->wait_enable)
+			set_fmt_bits(davinci_spi->base,
+					SPIFMT_WAITENA_MASK,
+					spi->chip_select);
+		else
+			clear_fmt_bits(davinci_spi->base,
+					SPIFMT_WAITENA_MASK,
+					spi->chip_select);
+
+		if (davinci_spi->pdata->timer_disable)
+			set_fmt_bits(davinci_spi->base,
+					SPIFMT_DISTIMER_MASK,
+					spi->chip_select);
+		else
+			clear_fmt_bits(davinci_spi->base,
+					SPIFMT_DISTIMER_MASK,
+					spi->chip_select);
+	}
+
+	retval = davinci_spi_setup_transfer(spi, NULL);
+
+	return retval;
+}
+
+static void davinci_spi_cleanup(struct spi_device *spi)
+{
+	struct davinci_spi *davinci_spi = spi_master_get_devdata(spi->master);
+	struct davinci_spi_dma *davinci_spi_dma;
+
+	davinci_spi_dma = &davinci_spi->dma_channels[spi->chip_select];
+
+	if (use_dma && davinci_spi->dma_channels) {
+		davinci_spi_dma = &davinci_spi->dma_channels[spi->chip_select];
+
+		if ((davinci_spi_dma->dma_rx_channel != -1)
+				&& (davinci_spi_dma->dma_tx_channel != -1)) {
+			edma_free_channel(davinci_spi_dma->dma_tx_channel);
+			edma_free_channel(davinci_spi_dma->dma_rx_channel);
+		}
+	}
+}
+
+static int davinci_spi_bufs_prep(struct spi_device *spi,
+				 struct davinci_spi *davinci_spi)
+{
+	int op_mode = 0;
+
+	/*
+	 * REVISIT  unless devices disagree about SPI_LOOP or
+	 * SPI_READY (SPI_NO_CS only allows one device!), this
+	 * should not need to be done before each message...
+	 * optimize for both flags staying cleared.
+	 */
+
+	op_mode = SPIPC0_DIFUN_MASK
+		| SPIPC0_DOFUN_MASK
+		| SPIPC0_CLKFUN_MASK;
+	if (!(spi->mode & SPI_NO_CS))
+		op_mode |= 1 << spi->chip_select;
+	if (spi->mode & SPI_READY)
+		op_mode |= SPIPC0_SPIENA_MASK;
+
+	iowrite32(op_mode, davinci_spi->base + SPIPC0);
+
+	if (spi->mode & SPI_LOOP)
+		set_io_bits(davinci_spi->base + SPIGCR1,
+				SPIGCR1_LOOPBACK_MASK);
+	else
+		clear_io_bits(davinci_spi->base + SPIGCR1,
+				SPIGCR1_LOOPBACK_MASK);
+
+	return 0;
+}
+
+static int davinci_spi_check_error(struct davinci_spi *davinci_spi,
+				   int int_status)
+{
+	struct device *sdev = davinci_spi->bitbang.master->dev.parent;
+
+	if (int_status & SPIFLG_TIMEOUT_MASK) {
+		dev_dbg(sdev, "SPI Time-out Error\n");
+		return -ETIMEDOUT;
+	}
+	if (int_status & SPIFLG_DESYNC_MASK) {
+		dev_dbg(sdev, "SPI Desynchronization Error\n");
+		return -EIO;
+	}
+	if (int_status & SPIFLG_BITERR_MASK) {
+		dev_dbg(sdev, "SPI Bit error\n");
+		return -EIO;
+	}
+
+	if (davinci_spi->version == SPI_VERSION_2) {
+		if (int_status & SPIFLG_DLEN_ERR_MASK) {
+			dev_dbg(sdev, "SPI Data Length Error\n");
+			return -EIO;
+		}
+		if (int_status & SPIFLG_PARERR_MASK) {
+			dev_dbg(sdev, "SPI Parity Error\n");
+			return -EIO;
+		}
+		if (int_status & SPIFLG_OVRRUN_MASK) {
+			dev_dbg(sdev, "SPI Data Overrun error\n");
+			return -EIO;
+		}
+		if (int_status & SPIFLG_TX_INTR_MASK) {
+			dev_dbg(sdev, "SPI TX intr bit set\n");
+			return -EIO;
+		}
+		if (int_status & SPIFLG_BUF_INIT_ACTIVE_MASK) {
+			dev_dbg(sdev, "SPI Buffer Init Active\n");
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * davinci_spi_bufs - functions which will handle transfer data
+ * @spi: spi device on which data transfer to be done
+ * @t: spi transfer in which transfer info is filled
+ *
+ * This function will put data to be transferred into data register
+ * of SPI controller and then wait until the completion will be marked
+ * by the IRQ Handler.
+ */
+static int davinci_spi_bufs_pio(struct spi_device *spi, struct spi_transfer *t)
+{
+	struct davinci_spi *davinci_spi;
+	int int_status, count, ret;
+	u8 conv, tmp;
+	u32 tx_data, data1_reg_val;
+	u32 buf_val, flg_val;
+	struct davinci_spi_platform_data *pdata;
+
+	davinci_spi = spi_master_get_devdata(spi->master);
+	pdata = davinci_spi->pdata;
+
+	davinci_spi->tx = t->tx_buf;
+	davinci_spi->rx = t->rx_buf;
+
+	/* convert len to words based on bits_per_word */
+	conv = davinci_spi->slave[spi->chip_select].bytes_per_word;
+	davinci_spi->count = t->len / conv;
+
+	INIT_COMPLETION(davinci_spi->done);
+
+	ret = davinci_spi_bufs_prep(spi, davinci_spi);
+	if (ret)
+		return ret;
+
+	/* Enable SPI */
+	set_io_bits(davinci_spi->base + SPIGCR1, SPIGCR1_SPIENA_MASK);
+
+	iowrite32(0 | (pdata->c2tdelay << SPI_C2TDELAY_SHIFT) |
+			(pdata->t2cdelay << SPI_T2CDELAY_SHIFT),
+			davinci_spi->base + SPIDELAY);
+
+	count = davinci_spi->count;
+	data1_reg_val = pdata->cs_hold << SPIDAT1_CSHOLD_SHIFT;
+	tmp = ~(0x1 << spi->chip_select);
+
+	clear_io_bits(davinci_spi->base + SPIDEF, ~tmp);
+
+	data1_reg_val |= tmp << SPIDAT1_CSNR_SHIFT;
+
+	while ((ioread32(davinci_spi->base + SPIBUF)
+				& SPIBUF_RXEMPTY_MASK) == 0)
+		cpu_relax();
+
+	/* Determine the command to execute READ or WRITE */
+	if (t->tx_buf) {
+		clear_io_bits(davinci_spi->base + SPIINT, SPIINT_MASKALL);
+
+		while (1) {
+			tx_data = davinci_spi->get_tx(davinci_spi);
+
+			data1_reg_val &= ~(0xFFFF);
+			data1_reg_val |= (0xFFFF & tx_data);
+
+			buf_val = ioread32(davinci_spi->base + SPIBUF);
+			if ((buf_val & SPIBUF_TXFULL_MASK) == 0) {
+				iowrite32(data1_reg_val,
+						davinci_spi->base + SPIDAT1);
+
+				count--;
+			}
+			while (ioread32(davinci_spi->base + SPIBUF)
+					& SPIBUF_RXEMPTY_MASK)
+				cpu_relax();
+
+			/* getting the returned byte */
+			if (t->rx_buf) {
+				buf_val = ioread32(davinci_spi->base + SPIBUF);
+				davinci_spi->get_rx(buf_val, davinci_spi);
+			}
+			if (count <= 0)
+				break;
+		}
+	} else {
+		if (pdata->poll_mode) {
+			while (1) {
+				/* keeps the serial clock going */
+				if ((ioread32(davinci_spi->base + SPIBUF)
+						& SPIBUF_TXFULL_MASK) == 0)
+					iowrite32(data1_reg_val,
+						davinci_spi->base + SPIDAT1);
+
+				while (ioread32(davinci_spi->base + SPIBUF) &
+						SPIBUF_RXEMPTY_MASK)
+					cpu_relax();
+
+				flg_val = ioread32(davinci_spi->base + SPIFLG);
+				buf_val = ioread32(davinci_spi->base + SPIBUF);
+
+				davinci_spi->get_rx(buf_val, davinci_spi);
+
+				count--;
+				if (count <= 0)
+					break;
+			}
+		} else {	/* Receive in Interrupt mode */
+			int i;
+
+			for (i = 0; i < davinci_spi->count; i++) {
+				set_io_bits(davinci_spi->base + SPIINT,
+						SPIINT_BITERR_INTR
+						| SPIINT_OVRRUN_INTR
+						| SPIINT_RX_INTR);
+
+				iowrite32(data1_reg_val,
+						davinci_spi->base + SPIDAT1);
+
+				while (ioread32(davinci_spi->base + SPIINT) &
+						SPIINT_RX_INTR)
+					cpu_relax();
+			}
+			iowrite32((data1_reg_val & 0x0ffcffff),
+					davinci_spi->base + SPIDAT1);
+		}
+	}
+
+	/*
+	 * Check for bit error, desync error,parity error,timeout error and
+	 * receive overflow errors
+	 */
+	int_status = ioread32(davinci_spi->base + SPIFLG);
+
+	ret = davinci_spi_check_error(davinci_spi, int_status);
+	if (ret != 0)
+		return ret;
+
+	/* SPI Framework maintains the count only in bytes so convert back */
+	davinci_spi->count *= conv;
+
+	return t->len;
+}
+
+#define DAVINCI_DMA_DATA_TYPE_S8	0x01
+#define DAVINCI_DMA_DATA_TYPE_S16	0x02
+#define DAVINCI_DMA_DATA_TYPE_S32	0x04
+
+static int davinci_spi_bufs_dma(struct spi_device *spi, struct spi_transfer *t)
+{
+	struct davinci_spi *davinci_spi;
+	int int_status = 0;
+	int count, temp_count;
+	u8 conv = 1;
+	u8 tmp;
+	u32 data1_reg_val;
+	struct davinci_spi_dma *davinci_spi_dma;
+	int word_len, data_type, ret;
+	unsigned long tx_reg, rx_reg;
+	struct davinci_spi_platform_data *pdata;
+	struct device *sdev;
+
+	davinci_spi = spi_master_get_devdata(spi->master);
+	pdata = davinci_spi->pdata;
+	sdev = davinci_spi->bitbang.master->dev.parent;
+
+	davinci_spi_dma = &davinci_spi->dma_channels[spi->chip_select];
+
+	tx_reg = (unsigned long)davinci_spi->pbase + SPIDAT1;
+	rx_reg = (unsigned long)davinci_spi->pbase + SPIBUF;
+
+	davinci_spi->tx = t->tx_buf;
+	davinci_spi->rx = t->rx_buf;
+
+	/* convert len to words based on bits_per_word */
+	conv = davinci_spi->slave[spi->chip_select].bytes_per_word;
+	davinci_spi->count = t->len / conv;
+
+	INIT_COMPLETION(davinci_spi->done);
+
+	init_completion(&davinci_spi_dma->dma_rx_completion);
+	init_completion(&davinci_spi_dma->dma_tx_completion);
+
+	word_len = conv * 8;
+
+	if (word_len <= 8)
+		data_type = DAVINCI_DMA_DATA_TYPE_S8;
+	else if (word_len <= 16)
+		data_type = DAVINCI_DMA_DATA_TYPE_S16;
+	else if (word_len <= 32)
+		data_type = DAVINCI_DMA_DATA_TYPE_S32;
+	else
+		return -EINVAL;
+
+	ret = davinci_spi_bufs_prep(spi, davinci_spi);
+	if (ret)
+		return ret;
+
+	/* Put delay val if required */
+	iowrite32(0 | (pdata->c2tdelay << SPI_C2TDELAY_SHIFT) |
+			(pdata->t2cdelay << SPI_T2CDELAY_SHIFT),
+			davinci_spi->base + SPIDELAY);
+
+	count = davinci_spi->count;	/* the number of elements */
+	data1_reg_val = pdata->cs_hold << SPIDAT1_CSHOLD_SHIFT;
+
+	/* CS default = 0xFF */
+	tmp = ~(0x1 << spi->chip_select);
+
+	clear_io_bits(davinci_spi->base + SPIDEF, ~tmp);
+
+	data1_reg_val |= tmp << SPIDAT1_CSNR_SHIFT;
+
+	/* disable all interrupts for dma transfers */
+	clear_io_bits(davinci_spi->base + SPIINT, SPIINT_MASKALL);
+	/* Disable SPI to write configuration bits in SPIDAT */
+	clear_io_bits(davinci_spi->base + SPIGCR1, SPIGCR1_SPIENA_MASK);
+	iowrite32(data1_reg_val, davinci_spi->base + SPIDAT1);
+	/* Enable SPI */
+	set_io_bits(davinci_spi->base + SPIGCR1, SPIGCR1_SPIENA_MASK);
+
+	while ((ioread32(davinci_spi->base + SPIBUF)
+				& SPIBUF_RXEMPTY_MASK) == 0)
+		cpu_relax();
+
+
+	if (t->tx_buf) {
+		t->tx_dma = dma_map_single(&spi->dev, (void *)t->tx_buf, count,
+				DMA_TO_DEVICE);
+		if (dma_mapping_error(&spi->dev, t->tx_dma)) {
+			dev_dbg(sdev, "Unable to DMA map a %d bytes"
+				" TX buffer\n", count);
+			return -ENOMEM;
+		}
+		temp_count = count;
+	} else {
+		/* We need TX clocking for RX transaction */
+		t->tx_dma = dma_map_single(&spi->dev,
+				(void *)davinci_spi->tmp_buf, count + 1,
+				DMA_TO_DEVICE);
+		if (dma_mapping_error(&spi->dev, t->tx_dma)) {
+			dev_dbg(sdev, "Unable to DMA map a %d bytes"
+				" TX tmp buffer\n", count);
+			return -ENOMEM;
+		}
+		temp_count = count + 1;
+	}
+
+	edma_set_transfer_params(davinci_spi_dma->dma_tx_channel,
+					data_type, temp_count, 1, 0, ASYNC);
+	edma_set_dest(davinci_spi_dma->dma_tx_channel, tx_reg, INCR, W8BIT);
+	edma_set_src(davinci_spi_dma->dma_tx_channel, t->tx_dma, INCR, W8BIT);
+	edma_set_src_index(davinci_spi_dma->dma_tx_channel, data_type, 0);
+	edma_set_dest_index(davinci_spi_dma->dma_tx_channel, 0, 0);
+
+	if (t->rx_buf) {
+		/* initiate transaction */
+		iowrite32(data1_reg_val, davinci_spi->base + SPIDAT1);
+
+		t->rx_dma = dma_map_single(&spi->dev, (void *)t->rx_buf, count,
+				DMA_FROM_DEVICE);
+		if (dma_mapping_error(&spi->dev, t->rx_dma)) {
+			dev_dbg(sdev, "Couldn't DMA map a %d bytes RX buffer\n",
+					count);
+			if (t->tx_buf != NULL)
+				dma_unmap_single(NULL, t->tx_dma,
+						 count, DMA_TO_DEVICE);
+			return -ENOMEM;
+		}
+		edma_set_transfer_params(davinci_spi_dma->dma_rx_channel,
+				data_type, count, 1, 0, ASYNC);
+		edma_set_src(davinci_spi_dma->dma_rx_channel,
+				rx_reg, INCR, W8BIT);
+		edma_set_dest(davinci_spi_dma->dma_rx_channel,
+				t->rx_dma, INCR, W8BIT);
+		edma_set_src_index(davinci_spi_dma->dma_rx_channel, 0, 0);
+		edma_set_dest_index(davinci_spi_dma->dma_rx_channel,
+				data_type, 0);
+	}
+
+	if ((t->tx_buf) || (t->rx_buf))
+		edma_start(davinci_spi_dma->dma_tx_channel);
+
+	if (t->rx_buf)
+		edma_start(davinci_spi_dma->dma_rx_channel);
+
+	if ((t->rx_buf) || (t->tx_buf))
+		davinci_spi_set_dma_req(spi, 1);
+
+	if (t->tx_buf)
+		wait_for_completion_interruptible(
+				&davinci_spi_dma->dma_tx_completion);
+
+	if (t->rx_buf)
+		wait_for_completion_interruptible(
+				&davinci_spi_dma->dma_rx_completion);
+
+	dma_unmap_single(NULL, t->tx_dma, temp_count, DMA_TO_DEVICE);
+
+	if (t->rx_buf)
+		dma_unmap_single(NULL, t->rx_dma, count, DMA_FROM_DEVICE);
+
+	/*
+	 * Check for bit error, desync error,parity error,timeout error and
+	 * receive overflow errors
+	 */
+	int_status = ioread32(davinci_spi->base + SPIFLG);
+
+	ret = davinci_spi_check_error(davinci_spi, int_status);
+	if (ret != 0)
+		return ret;
+
+	/* SPI Framework maintains the count only in bytes so convert back */
+	davinci_spi->count *= conv;
+
+	return t->len;
+}
+
+/**
+ * davinci_spi_irq - IRQ handler for DaVinci SPI
+ * @irq: IRQ number for this SPI Master
+ * @context_data: structure for SPI Master controller davinci_spi
+ */
+static irqreturn_t davinci_spi_irq(s32 irq, void *context_data)
+{
+	struct davinci_spi *davinci_spi = context_data;
+	u32 int_status, rx_data = 0;
+	irqreturn_t ret = IRQ_NONE;
+
+	int_status = ioread32(davinci_spi->base + SPIFLG);
+
+	while ((int_status & SPIFLG_RX_INTR_MASK)) {
+		if (likely(int_status & SPIFLG_RX_INTR_MASK)) {
+			ret = IRQ_HANDLED;
+
+			rx_data = ioread32(davinci_spi->base + SPIBUF);
+			davinci_spi->get_rx(rx_data, davinci_spi);
+
+			/* Disable Receive Interrupt */
+			iowrite32(~(SPIINT_RX_INTR | SPIINT_TX_INTR),
+					davinci_spi->base + SPIINT);
+		} else
+			(void)davinci_spi_check_error(davinci_spi, int_status);
+
+		int_status = ioread32(davinci_spi->base + SPIFLG);
+	}
+
+	return ret;
+}
+
+/**
+ * davinci_spi_probe - probe function for SPI Master Controller
+ * @pdev: platform_device structure which contains plateform specific data
+ */
+static int davinci_spi_probe(struct platform_device *pdev)
+{
+	struct spi_master *master;
+	struct davinci_spi *davinci_spi;
+	struct davinci_spi_platform_data *pdata;
+	struct resource *r, *mem;
+	resource_size_t dma_rx_chan = SPI_NO_RESOURCE;
+	resource_size_t	dma_tx_chan = SPI_NO_RESOURCE;
+	resource_size_t	dma_eventq = SPI_NO_RESOURCE;
+	int i = 0, ret = 0;
+
+	pdata = pdev->dev.platform_data;
+	if (pdata == NULL) {
+		ret = -ENODEV;
+		goto err;
+	}
+
+	master = spi_alloc_master(&pdev->dev, sizeof(struct davinci_spi));
+	if (master == NULL) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	dev_set_drvdata(&pdev->dev, master);
+
+	davinci_spi = spi_master_get_devdata(master);
+	if (davinci_spi == NULL) {
+		ret = -ENOENT;
+		goto free_master;
+	}
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (r == NULL) {
+		ret = -ENOENT;
+		goto free_master;
+	}
+
+	davinci_spi->pbase = r->start;
+	davinci_spi->region_size = resource_size(r);
+	davinci_spi->pdata = pdata;
+
+	mem = request_mem_region(r->start, davinci_spi->region_size,
+					pdev->name);
+	if (mem == NULL) {
+		ret = -EBUSY;
+		goto free_master;
+	}
+
+	davinci_spi->base = (struct davinci_spi_reg __iomem *)
+			ioremap(r->start, davinci_spi->region_size);
+	if (davinci_spi->base == NULL) {
+		ret = -ENOMEM;
+		goto release_region;
+	}
+
+	davinci_spi->irq = platform_get_irq(pdev, 0);
+	if (davinci_spi->irq <= 0) {
+		ret = -EINVAL;
+		goto unmap_io;
+	}
+
+	ret = request_irq(davinci_spi->irq, davinci_spi_irq, IRQF_DISABLED,
+			  dev_name(&pdev->dev), davinci_spi);
+	if (ret)
+		goto unmap_io;
+
+	/* Allocate tmp_buf for tx_buf */
+	davinci_spi->tmp_buf = kzalloc(SPI_BUFSIZ, GFP_KERNEL);
+	if (davinci_spi->tmp_buf == NULL) {
+		ret = -ENOMEM;
+		goto irq_free;
+	}
+
+	davinci_spi->bitbang.master = spi_master_get(master);
+	if (davinci_spi->bitbang.master == NULL) {
+		ret = -ENODEV;
+		goto free_tmp_buf;
+	}
+
+	davinci_spi->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(davinci_spi->clk)) {
+		ret = -ENODEV;
+		goto put_master;
+	}
+	clk_enable(davinci_spi->clk);
+
+
+	master->bus_num = pdev->id;
+	master->num_chipselect = pdata->num_chipselect;
+	master->setup = davinci_spi_setup;
+	master->cleanup = davinci_spi_cleanup;
+
+	davinci_spi->bitbang.chipselect = davinci_spi_chipselect;
+	davinci_spi->bitbang.setup_transfer = davinci_spi_setup_transfer;
+
+	davinci_spi->version = pdata->version;
+	use_dma = pdata->use_dma;
+
+	davinci_spi->bitbang.flags = SPI_NO_CS | SPI_LSB_FIRST | SPI_LOOP;
+	if (davinci_spi->version == SPI_VERSION_2)
+		davinci_spi->bitbang.flags |= SPI_READY;
+
+	if (use_dma) {
+			r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+			if (r)
+				dma_rx_chan = r->start;
+			r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+			if (r)
+				dma_tx_chan = r->start;
+			r = platform_get_resource(pdev, IORESOURCE_DMA, 2);
+			if (r)
+				dma_eventq = r->start;
+	}
+
+	if (!use_dma ||
+	    dma_rx_chan == SPI_NO_RESOURCE ||
+	    dma_tx_chan == SPI_NO_RESOURCE ||
+	    dma_eventq	== SPI_NO_RESOURCE) {
+		davinci_spi->bitbang.txrx_bufs = davinci_spi_bufs_pio;
+		use_dma = 0;
+	} else {
+		davinci_spi->bitbang.txrx_bufs = davinci_spi_bufs_dma;
+		davinci_spi->dma_channels = kzalloc(master->num_chipselect
+				* sizeof(struct davinci_spi_dma), GFP_KERNEL);
+		if (davinci_spi->dma_channels == NULL) {
+			ret = -ENOMEM;
+			goto free_clk;
+		}
+
+		for (i = 0; i < master->num_chipselect; i++) {
+			davinci_spi->dma_channels[i].dma_rx_channel = -1;
+			davinci_spi->dma_channels[i].dma_rx_sync_dev =
+				dma_rx_chan;
+			davinci_spi->dma_channels[i].dma_tx_channel = -1;
+			davinci_spi->dma_channels[i].dma_tx_sync_dev =
+				dma_tx_chan;
+			davinci_spi->dma_channels[i].eventq = dma_eventq;
+		}
+		dev_info(&pdev->dev, "DaVinci SPI driver in EDMA mode\n"
+				"Using RX channel = %d , TX channel = %d and "
+				"event queue = %d", dma_rx_chan, dma_tx_chan,
+				dma_eventq);
+	}
+
+	davinci_spi->get_rx = davinci_spi_rx_buf_u8;
+	davinci_spi->get_tx = davinci_spi_tx_buf_u8;
+
+	init_completion(&davinci_spi->done);
+
+	/* Reset In/OUT SPI module */
+	iowrite32(0, davinci_spi->base + SPIGCR0);
+	udelay(100);
+	iowrite32(1, davinci_spi->base + SPIGCR0);
+
+	/* Clock internal */
+	if (davinci_spi->pdata->clk_internal)
+		set_io_bits(davinci_spi->base + SPIGCR1,
+				SPIGCR1_CLKMOD_MASK);
+	else
+		clear_io_bits(davinci_spi->base + SPIGCR1,
+				SPIGCR1_CLKMOD_MASK);
+
+	/* master mode default */
+	set_io_bits(davinci_spi->base + SPIGCR1, SPIGCR1_MASTER_MASK);
+
+	if (davinci_spi->pdata->intr_level)
+		iowrite32(SPI_INTLVL_1, davinci_spi->base + SPILVL);
+	else
+		iowrite32(SPI_INTLVL_0, davinci_spi->base + SPILVL);
+
+	ret = spi_bitbang_start(&davinci_spi->bitbang);
+	if (ret)
+		goto free_clk;
+
+	dev_info(&pdev->dev, "Controller at 0x%p \n", davinci_spi->base);
+
+	if (!pdata->poll_mode)
+		dev_info(&pdev->dev, "Operating in interrupt mode"
+			" using IRQ %d\n", davinci_spi->irq);
+
+	return ret;
+
+free_clk:
+	clk_disable(davinci_spi->clk);
+	clk_put(davinci_spi->clk);
+put_master:
+	spi_master_put(master);
+free_tmp_buf:
+	kfree(davinci_spi->tmp_buf);
+irq_free:
+	free_irq(davinci_spi->irq, davinci_spi);
+unmap_io:
+	iounmap(davinci_spi->base);
+release_region:
+	release_mem_region(davinci_spi->pbase, davinci_spi->region_size);
+free_master:
+	kfree(master);
+err:
+	return ret;
+}
+
+/**
+ * davinci_spi_remove - remove function for SPI Master Controller
+ * @pdev: platform_device structure which contains plateform specific data
+ *
+ * This function will do the reverse action of davinci_spi_probe function
+ * It will free the IRQ and SPI controller's memory region.
+ * It will also call spi_bitbang_stop to destroy the work queue which was
+ * created by spi_bitbang_start.
+ */
+static int __exit davinci_spi_remove(struct platform_device *pdev)
+{
+	struct davinci_spi *davinci_spi;
+	struct spi_master *master;
+
+	master = dev_get_drvdata(&pdev->dev);
+	davinci_spi = spi_master_get_devdata(master);
+
+	spi_bitbang_stop(&davinci_spi->bitbang);
+
+	clk_disable(davinci_spi->clk);
+	clk_put(davinci_spi->clk);
+	spi_master_put(master);
+	kfree(davinci_spi->tmp_buf);
+	free_irq(davinci_spi->irq, davinci_spi);
+	iounmap(davinci_spi->base);
+	release_mem_region(davinci_spi->pbase, davinci_spi->region_size);
+
+	return 0;
+}
+
+static struct platform_driver davinci_spi_driver = {
+	.driver.name = "spi_davinci",
+	.remove = __exit_p(davinci_spi_remove),
+};
+
+static int __init davinci_spi_init(void)
+{
+	return platform_driver_probe(&davinci_spi_driver, davinci_spi_probe);
+}
+module_init(davinci_spi_init);
+
+static void __exit davinci_spi_exit(void)
+{
+	platform_driver_unregister(&davinci_spi_driver);
+}
+module_exit(davinci_spi_exit);
+
+MODULE_DESCRIPTION("TI DaVinci SPI Master Controller Driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/dw_spi.c linux-libre-2.6.34-gnu1/drivers/spi/dw_spi.c
--- linux-libre-2.6.33-gnu1/drivers/spi/dw_spi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/dw_spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/highmem.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <linux/spi/dw_spi.h>
 #include <linux/spi/spi.h>
@@ -152,6 +153,7 @@ static void mrst_spi_debugfs_remove(stru
 #else
 static inline int mrst_spi_debugfs_init(struct dw_spi *dws)
 {
+	return 0;
 }
 
 static inline void mrst_spi_debugfs_remove(struct dw_spi *dws)
@@ -161,14 +163,14 @@ static inline void mrst_spi_debugfs_remo
 
 static void wait_till_not_busy(struct dw_spi *dws)
 {
-	unsigned long end = jiffies + usecs_to_jiffies(1000);
+	unsigned long end = jiffies + 1 + usecs_to_jiffies(1000);
 
 	while (time_before(jiffies, end)) {
 		if (!(dw_readw(dws, sr) & SR_BUSY))
 			return;
 	}
 	dev_err(&dws->master->dev,
-		"DW SPI: Stutus keeps busy for 1000us after a read/write!\n");
+		"DW SPI: Status keeps busy for 1000us after a read/write!\n");
 }
 
 static void flush(struct dw_spi *dws)
@@ -358,6 +360,8 @@ static void transfer_complete(struct dw_
 static irqreturn_t interrupt_transfer(struct dw_spi *dws)
 {
 	u16 irq_status, irq_mask = 0x3f;
+	u32 int_level = dws->fifo_len / 2;
+	u32 left;
 
 	irq_status = dw_readw(dws, isr) & irq_mask;
 	/* Error handling */
@@ -369,22 +373,23 @@ static irqreturn_t interrupt_transfer(st
 		return IRQ_HANDLED;
 	}
 
-	/* INT comes from tx */
-	if (dws->tx && (irq_status & SPI_INT_TXEI)) {
-		while (dws->tx < dws->tx_end)
+	if (irq_status & SPI_INT_TXEI) {
+		spi_mask_intr(dws, SPI_INT_TXEI);
+
+		left = (dws->tx_end - dws->tx) / dws->n_bytes;
+		left = (left > int_level) ? int_level : left;
+
+		while (left--)
 			dws->write(dws);
+		dws->read(dws);
 
-		if (dws->tx == dws->tx_end) {
-			spi_mask_intr(dws, SPI_INT_TXEI);
+		/* Re-enable the IRQ if there is still data left to tx */
+		if (dws->tx_end > dws->tx)
+			spi_umask_intr(dws, SPI_INT_TXEI);
+		else
 			transfer_complete(dws);
-		}
 	}
 
-	/* INT comes from rx */
-	if (dws->rx && (irq_status & SPI_INT_RXFI)) {
-		if (dws->read(dws))
-			transfer_complete(dws);
-	}
 	return IRQ_HANDLED;
 }
 
@@ -404,12 +409,9 @@ static irqreturn_t dw_spi_irq(int irq, v
 /* Must be called inside pump_transfers() */
 static void poll_transfer(struct dw_spi *dws)
 {
-	if (dws->tx) {
-		while (dws->write(dws))
-			dws->read(dws);
-	}
+	while (dws->write(dws))
+		dws->read(dws);
 
-	dws->read(dws);
 	transfer_complete(dws);
 }
 
@@ -428,6 +430,7 @@ static void pump_transfers(unsigned long
 	u8 bits = 0;
 	u8 imask = 0;
 	u8 cs_change = 0;
+	u16 txint_level = 0;
 	u16 clk_div = 0;
 	u32 speed = 0;
 	u32 cr0 = 0;
@@ -438,6 +441,9 @@ static void pump_transfers(unsigned long
 	chip = dws->cur_chip;
 	spi = message->spi;
 
+	if (unlikely(!chip->clk_div))
+		chip->clk_div = dws->max_freq / chip->speed_hz;
+
 	if (message->state == ERROR_STATE) {
 		message->status = -EIO;
 		goto early_exit;
@@ -492,7 +498,7 @@ static void pump_transfers(unsigned long
 
 			/* clk_div doesn't support odd number */
 			clk_div = dws->max_freq / speed;
-			clk_div = (clk_div >> 1) << 1;
+			clk_div = (clk_div + 1) & 0xfffe;
 
 			chip->speed_hz = speed;
 			chip->clk_div = clk_div;
@@ -532,14 +538,35 @@ static void pump_transfers(unsigned long
 	}
 	message->state = RUNNING_STATE;
 
+	/*
+	 * Adjust transfer mode if necessary. Requires platform dependent
+	 * chipselect mechanism.
+	 */
+	if (dws->cs_control) {
+		if (dws->rx && dws->tx)
+			chip->tmode = 0x00;
+		else if (dws->rx)
+			chip->tmode = 0x02;
+		else
+			chip->tmode = 0x01;
+
+		cr0 &= ~(0x3 << SPI_MODE_OFFSET);
+		cr0 |= (chip->tmode << SPI_TMOD_OFFSET);
+	}
+
 	/* Check if current transfer is a DMA transaction */
 	dws->dma_mapped = map_dma_buffers(dws);
 
+	/*
+	 * Interrupt mode
+	 * we only need set the TXEI IRQ, as TX/RX always happen syncronizely
+	 */
 	if (!dws->dma_mapped && !chip->poll_mode) {
-		if (dws->rx)
-			imask |= SPI_INT_RXFI;
-		if (dws->tx)
-			imask |= SPI_INT_TXEI;
+		int templen = dws->len / dws->n_bytes;
+		txint_level = dws->fifo_len / 2;
+		txint_level = (templen > txint_level) ? txint_level : templen;
+
+		imask |= SPI_INT_TXEI;
 		dws->transfer_handler = interrupt_transfer;
 	}
 
@@ -549,21 +576,23 @@ static void pump_transfers(unsigned long
 	 *	2. clk_div is changed
 	 *	3. control value changes
 	 */
-	if (dw_readw(dws, ctrl0) != cr0 || cs_change || clk_div) {
+	if (dw_readw(dws, ctrl0) != cr0 || cs_change || clk_div || imask) {
 		spi_enable_chip(dws, 0);
 
 		if (dw_readw(dws, ctrl0) != cr0)
 			dw_writew(dws, ctrl0, cr0);
 
+		spi_set_clk(dws, clk_div ? clk_div : chip->clk_div);
+		spi_chip_sel(dws, spi->chip_select);
+
 		/* Set the interrupt mask, for poll mode just diable all int */
 		spi_mask_intr(dws, 0xff);
-		if (!chip->poll_mode)
+		if (imask)
 			spi_umask_intr(dws, imask);
+		if (txint_level)
+			dw_writew(dws, txfltr, txint_level);
 
-		spi_set_clk(dws, clk_div ? clk_div : chip->clk_div);
-		spi_chip_sel(dws, spi->chip_select);
 		spi_enable_chip(dws, 1);
-
 		if (cs_change)
 			dws->prev_chip = chip;
 	}
@@ -712,11 +741,11 @@ static int dw_spi_setup(struct spi_devic
 	}
 	chip->bits_per_word = spi->bits_per_word;
 
+	if (!spi->max_speed_hz) {
+		dev_err(&spi->dev, "No max speed HZ parameter\n");
+		return -EINVAL;
+	}
 	chip->speed_hz = spi->max_speed_hz;
-	if (chip->speed_hz)
-		chip->clk_div = 25000000 / chip->speed_hz;
-	else
-		chip->clk_div = 8;	/* default value */
 
 	chip->tmode = 0; /* Tx & Rx */
 	/* Default SPI mode is SCPOL = 0, SCPH = 0 */
@@ -735,7 +764,7 @@ static void dw_spi_cleanup(struct spi_de
 	kfree(chip);
 }
 
-static int __init init_queue(struct dw_spi *dws)
+static int __devinit init_queue(struct dw_spi *dws)
 {
 	INIT_LIST_HEAD(&dws->queue);
 	spin_lock_init(&dws->lock);
@@ -817,6 +846,22 @@ static void spi_hw_init(struct dw_spi *d
 	spi_mask_intr(dws, 0xff);
 	spi_enable_chip(dws, 1);
 	flush(dws);
+
+	/*
+	 * Try to detect the FIFO depth if not set by interface driver,
+	 * the depth could be from 2 to 256 from HW spec
+	 */
+	if (!dws->fifo_len) {
+		u32 fifo;
+		for (fifo = 2; fifo <= 257; fifo++) {
+			dw_writew(dws, txfltr, fifo);
+			if (fifo != dw_readw(dws, txfltr))
+				break;
+		}
+
+		dws->fifo_len = (fifo == 257) ? 0 : fifo;
+		dw_writew(dws, txfltr, 0);
+	}
 }
 
 int __devinit dw_spi_add_host(struct dw_spi *dws)
@@ -913,6 +958,7 @@ void __devexit dw_spi_remove_host(struct
 	/* Disconnect from the SPI framework */
 	spi_unregister_master(dws->master);
 }
+EXPORT_SYMBOL(dw_spi_remove_host);
 
 int dw_spi_suspend_host(struct dw_spi *dws)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/dw_spi_mmio.c linux-libre-2.6.34-gnu1/drivers/spi/dw_spi_mmio.c
--- linux-libre-2.6.33-gnu1/drivers/spi/dw_spi_mmio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/dw_spi_mmio.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,148 @@
+/*
+ * dw_spi_mmio.c - Memory-mapped interface driver for DW SPI Core
+ *
+ * Copyright (c) 2010, Octasic semiconductor.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spi/dw_spi.h>
+#include <linux/spi/spi.h>
+
+#define DRIVER_NAME "dw_spi_mmio"
+
+struct dw_spi_mmio {
+	struct dw_spi  dws;
+	struct clk     *clk;
+};
+
+static int __devinit dw_spi_mmio_probe(struct platform_device *pdev)
+{
+	struct dw_spi_mmio *dwsmmio;
+	struct dw_spi *dws;
+	struct resource *mem, *ioarea;
+	int ret;
+
+	dwsmmio = kzalloc(sizeof(struct dw_spi_mmio), GFP_KERNEL);
+	if (!dwsmmio) {
+		ret = -ENOMEM;
+		goto err_end;
+	}
+
+	dws = &dwsmmio->dws;
+
+	/* Get basic io resource and map it */
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		dev_err(&pdev->dev, "no mem resource?\n");
+		ret = -EINVAL;
+		goto err_kfree;
+	}
+
+	ioarea = request_mem_region(mem->start, resource_size(mem),
+			pdev->name);
+	if (!ioarea) {
+		dev_err(&pdev->dev, "SPI region already claimed\n");
+		ret = -EBUSY;
+		goto err_kfree;
+	}
+
+	dws->regs = ioremap_nocache(mem->start, resource_size(mem));
+	if (!dws->regs) {
+		dev_err(&pdev->dev, "SPI region already mapped\n");
+		ret = -ENOMEM;
+		goto err_release_reg;
+	}
+
+	dws->irq = platform_get_irq(pdev, 0);
+	if (dws->irq < 0) {
+		dev_err(&pdev->dev, "no irq resource?\n");
+		ret = dws->irq; /* -ENXIO */
+		goto err_unmap;
+	}
+
+	dwsmmio->clk = clk_get(&pdev->dev, NULL);
+	if (!dwsmmio->clk) {
+		ret = -ENODEV;
+		goto err_irq;
+	}
+	clk_enable(dwsmmio->clk);
+
+	dws->parent_dev = &pdev->dev;
+	dws->bus_num = 0;
+	dws->num_cs = 4;
+	dws->max_freq = clk_get_rate(dwsmmio->clk);
+
+	ret = dw_spi_add_host(dws);
+	if (ret)
+		goto err_clk;
+
+	platform_set_drvdata(pdev, dwsmmio);
+	return 0;
+
+err_clk:
+	clk_disable(dwsmmio->clk);
+	clk_put(dwsmmio->clk);
+	dwsmmio->clk = NULL;
+err_irq:
+	free_irq(dws->irq, dws);
+err_unmap:
+	iounmap(dws->regs);
+err_release_reg:
+	release_mem_region(mem->start, resource_size(mem));
+err_kfree:
+	kfree(dwsmmio);
+err_end:
+	return ret;
+}
+
+static int __devexit dw_spi_mmio_remove(struct platform_device *pdev)
+{
+	struct dw_spi_mmio *dwsmmio = platform_get_drvdata(pdev);
+	struct resource *mem;
+
+	platform_set_drvdata(pdev, NULL);
+
+	clk_disable(dwsmmio->clk);
+	clk_put(dwsmmio->clk);
+	dwsmmio->clk = NULL;
+
+	free_irq(dwsmmio->dws.irq, &dwsmmio->dws);
+	dw_spi_remove_host(&dwsmmio->dws);
+	iounmap(dwsmmio->dws.regs);
+	kfree(dwsmmio);
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(mem->start, resource_size(mem));
+	return 0;
+}
+
+static struct platform_driver dw_spi_mmio_driver = {
+	.remove		= __devexit_p(dw_spi_mmio_remove),
+	.driver		= {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init dw_spi_mmio_init(void)
+{
+	return platform_driver_probe(&dw_spi_mmio_driver, dw_spi_mmio_probe);
+}
+module_init(dw_spi_mmio_init);
+
+static void __exit dw_spi_mmio_exit(void)
+{
+	platform_driver_unregister(&dw_spi_mmio_driver);
+}
+module_exit(dw_spi_mmio_exit);
+
+MODULE_AUTHOR("Jean-Hugues Deschenes <jean-hugues.deschenes@octasic.com>");
+MODULE_DESCRIPTION("Memory-mapped I/O interface driver for DW SPI Core");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/dw_spi_pci.c linux-libre-2.6.34-gnu1/drivers/spi/dw_spi_pci.c
--- linux-libre-2.6.33-gnu1/drivers/spi/dw_spi_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/dw_spi_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/spi/dw_spi.h>
 #include <linux/spi/spi.h>
 
@@ -73,6 +74,7 @@ static int __devinit spi_pci_probe(struc
 	dws->num_cs = 4;
 	dws->max_freq = 25000000;	/* for Moorestwon */
 	dws->irq = pdev->irq;
+	dws->fifo_len = 40;		/* FIFO has 40 words buffer */
 
 	ret = dw_spi_add_host(dws);
 	if (ret)
@@ -98,6 +100,7 @@ static void __devexit spi_pci_remove(str
 	struct dw_spi_pci *dwpci = pci_get_drvdata(pdev);
 
 	pci_set_drvdata(pdev, NULL);
+	dw_spi_remove_host(&dwpci->dws);
 	iounmap(dwpci->dws.regs);
 	pci_release_region(pdev, 0);
 	kfree(dwpci);
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/Kconfig linux-libre-2.6.34-gnu1/drivers/spi/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/spi/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -100,6 +100,23 @@ config SPI_BUTTERFLY
 	  inexpensive battery powered microcontroller evaluation board.
 	  This same cable can be used to flash new firmware.
 
+config SPI_COLDFIRE_QSPI
+	tristate "Freescale Coldfire QSPI controller"
+	depends on (M520x || M523x || M5249 || M527x || M528x || M532x)
+	help
+	  This enables support for the Coldfire QSPI controller in master
+	  mode.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called coldfire_qspi.
+
+config SPI_DAVINCI
+	tristate "SPI controller driver for DaVinci/DA8xx SoC's"
+	depends on SPI_MASTER && ARCH_DAVINCI
+	select SPI_BITBANG
+	help
+	  SPI master controller for DaVinci and DA8xx SPI modules.
+
 config SPI_GPIO
 	tristate "GPIO-based bitbanging SPI Master"
 	depends on GENERIC_GPIO
@@ -164,7 +181,7 @@ config SPI_OMAP_UWIRE
 
 config SPI_OMAP24XX
 	tristate "McSPI driver for OMAP24xx/OMAP34xx"
-	depends on ARCH_OMAP24XX || ARCH_OMAP34XX
+	depends on ARCH_OMAP2 || ARCH_OMAP3
 	help
 	  SPI master controller for OMAP24xx/OMAP34xx Multichannel SPI
 	  (McSPI) modules.
@@ -308,7 +325,7 @@ config SPI_NUC900
 #
 
 config SPI_DESIGNWARE
-	bool "DesignWare SPI controller core support"
+	tristate "DesignWare SPI controller core support"
 	depends on SPI_MASTER
 	help
 	  general driver for SPI controller core from DesignWare
@@ -317,6 +334,10 @@ config SPI_DW_PCI
 	tristate "PCI interface driver for DW SPI core"
 	depends on SPI_DESIGNWARE && PCI
 
+config SPI_DW_MMIO
+	tristate "Memory-mapped io interface driver for DW SPI core"
+	depends on SPI_DESIGNWARE && HAVE_CLK
+
 #
 # There are lots of SPI device types, with sensors and memory
 # being probably the most widely used ones.
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/Makefile linux-libre-2.6.34-gnu1/drivers/spi/Makefile
--- linux-libre-2.6.33-gnu1/drivers/spi/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -16,8 +16,11 @@ obj-$(CONFIG_SPI_BFIN)			+= spi_bfin5xx.
 obj-$(CONFIG_SPI_BITBANG)		+= spi_bitbang.o
 obj-$(CONFIG_SPI_AU1550)		+= au1550_spi.o
 obj-$(CONFIG_SPI_BUTTERFLY)		+= spi_butterfly.o
+obj-$(CONFIG_SPI_COLDFIRE_QSPI)		+= coldfire_qspi.o
+obj-$(CONFIG_SPI_DAVINCI)		+= davinci_spi.o
 obj-$(CONFIG_SPI_DESIGNWARE)		+= dw_spi.o
 obj-$(CONFIG_SPI_DW_PCI)		+= dw_spi_pci.o
+obj-$(CONFIG_SPI_DW_MMIO)		+= dw_spi_mmio.o
 obj-$(CONFIG_SPI_GPIO)			+= spi_gpio.o
 obj-$(CONFIG_SPI_IMX)			+= spi_imx.o
 obj-$(CONFIG_SPI_LM70_LLP)		+= spi_lm70llp.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/mpc52xx_psc_spi.c linux-libre-2.6.34-gnu1/drivers/spi/mpc52xx_psc_spi.c
--- linux-libre-2.6.33-gnu1/drivers/spi/mpc52xx_psc_spi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/mpc52xx_psc_spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/spi/spi.h>
 #include <linux/fsl_devices.h>
+#include <linux/slab.h>
 
 #include <asm/mpc52xx.h>
 #include <asm/mpc52xx_psc.h>
@@ -503,7 +504,7 @@ static int __exit mpc52xx_psc_spi_of_rem
 	return mpc52xx_psc_spi_do_remove(&op->dev);
 }
 
-static struct of_device_id mpc52xx_psc_spi_of_match[] = {
+static const struct of_device_id mpc52xx_psc_spi_of_match[] = {
 	{ .compatible = "fsl,mpc5200-psc-spi", },
 	{ .compatible = "mpc5200-psc-spi", }, /* old */
 	{}
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/mpc52xx_spi.c linux-libre-2.6.34-gnu1/drivers/spi/mpc52xx_spi.c
--- linux-libre-2.6.33-gnu1/drivers/spi/mpc52xx_spi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/mpc52xx_spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/of_spi.h>
 #include <linux/io.h>
 #include <linux/of_gpio.h>
+#include <linux/slab.h>
 #include <asm/time.h>
 #include <asm/mpc52xx.h>
 
@@ -550,7 +551,7 @@ static int __devexit mpc52xx_spi_remove(
 	return 0;
 }
 
-static struct of_device_id mpc52xx_spi_match[] __devinitdata = {
+static const struct of_device_id mpc52xx_spi_match[] __devinitconst = {
 	{ .compatible = "fsl,mpc5200-spi", },
 	{}
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/omap2_mcspi.c linux-libre-2.6.34-gnu1/drivers/spi/omap2_mcspi.c
--- linux-libre-2.6.33-gnu1/drivers/spi/omap2_mcspi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/omap2_mcspi.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 
@@ -203,6 +204,7 @@ static inline void mcspi_write_chconf0(c
 
 	cs->chconf0 = val;
 	mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, val);
+	mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0);
 }
 
 static void omap2_mcspi_set_dma_req(const struct spi_device *spi,
@@ -531,7 +533,7 @@ omap2_mcspi_txrx_pio(struct spi_device *
 					goto out;
 				}
 #ifdef VERBOSE
-				dev_dbg(&spi->dev, "write-%d %04x\n",
+				dev_dbg(&spi->dev, "write-%d %08x\n",
 						word_len, *tx);
 #endif
 				__raw_writel(*tx++, tx_reg);
@@ -549,7 +551,7 @@ omap2_mcspi_txrx_pio(struct spi_device *
 					mcspi_write_chconf0(spi, l);
 				*rx++ = __raw_readl(rx_reg);
 #ifdef VERBOSE
-				dev_dbg(&spi->dev, "read-%d %04x\n",
+				dev_dbg(&spi->dev, "read-%d %08x\n",
 						word_len, *(rx - 1));
 #endif
 			}
@@ -578,6 +580,7 @@ static int omap2_mcspi_setup_transfer(st
 	struct spi_master *spi_cntrl;
 	u32 l = 0, div = 0;
 	u8 word_len = spi->bits_per_word;
+	u32 speed_hz = spi->max_speed_hz;
 
 	mcspi = spi_master_get_devdata(spi->master);
 	spi_cntrl = mcspi->master;
@@ -587,9 +590,12 @@ static int omap2_mcspi_setup_transfer(st
 
 	cs->word_len = word_len;
 
-	if (spi->max_speed_hz) {
+	if (t && t->speed_hz)
+		speed_hz = t->speed_hz;
+
+	if (speed_hz) {
 		while (div <= 15 && (OMAP2_MCSPI_MAX_FREQ / (1 << div))
-					> spi->max_speed_hz)
+					> speed_hz)
 			div++;
 	} else
 		div = 15;
@@ -751,11 +757,13 @@ static void omap2_mcspi_cleanup(struct s
 	mcspi = spi_master_get_devdata(spi->master);
 	mcspi_dma = &mcspi->dma_channels[spi->chip_select];
 
-	/* Unlink controller state from context save list */
-	cs = spi->controller_state;
-	list_del(&cs->node);
+	if (spi->controller_state) {
+		/* Unlink controller state from context save list */
+		cs = spi->controller_state;
+		list_del(&cs->node);
 
-	kfree(spi->controller_state);
+		kfree(spi->controller_state);
+	}
 
 	if (mcspi_dma->dma_rx_channel != -1) {
 		omap_free_dma(mcspi_dma->dma_rx_channel);
@@ -1014,7 +1022,7 @@ static u8 __initdata spi2_txdma_id[] = {
 	OMAP24XX_DMA_SPI2_TX1,
 };
 
-#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) \
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) \
 	|| defined(CONFIG_ARCH_OMAP4)
 static u8 __initdata spi3_rxdma_id[] = {
 	OMAP24XX_DMA_SPI3_RX0,
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/omap_spi_100k.c linux-libre-2.6.34-gnu1/drivers/spi/omap_spi_100k.c
--- linux-libre-2.6.33-gnu1/drivers/spi/omap_spi_100k.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/omap_spi_100k.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/omap_uwire.c linux-libre-2.6.34-gnu1/drivers/spi/omap_uwire.c
--- linux-libre-2.6.33-gnu1/drivers/spi/omap_uwire.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/omap_uwire.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@
 #include <linux/interrupt.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/pxa2xx_spi.c linux-libre-2.6.34-gnu1/drivers/spi/pxa2xx_spi.c
--- linux-libre-2.6.33-gnu1/drivers/spi/pxa2xx_spi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/pxa2xx_spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/spi_bfin5xx.c linux-libre-2.6.34-gnu1/drivers/spi/spi_bfin5xx.c
--- linux-libre-2.6.33-gnu1/drivers/spi/spi_bfin5xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/spi_bfin5xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/spi_bitbang.c linux-libre-2.6.34-gnu1/drivers/spi/spi_bitbang.c
--- linux-libre-2.6.33-gnu1/drivers/spi/spi_bitbang.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/spi_bitbang.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/spi.c linux-libre-2.6.34-gnu1/drivers/spi/spi.c
--- linux-libre-2.6.33-gnu1/drivers/spi/spi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/cache.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/mod_devicetable.h>
 #include <linux/spi/spi.h>
 
@@ -40,7 +41,7 @@ static void spidev_release(struct device
 		spi->master->cleanup(spi);
 
 	spi_master_put(spi->master);
-	kfree(dev);
+	kfree(spi);
 }
 
 static ssize_t
@@ -256,6 +257,7 @@ int spi_add_device(struct spi_device *sp
 {
 	static DEFINE_MUTEX(spi_add_lock);
 	struct device *dev = spi->master->dev.parent;
+	struct device *d;
 	int status;
 
 	/* Chipselects are numbered 0..max; validate. */
@@ -277,10 +279,11 @@ int spi_add_device(struct spi_device *sp
 	 */
 	mutex_lock(&spi_add_lock);
 
-	if (bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev))
-			!= NULL) {
+	d = bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev));
+	if (d != NULL) {
 		dev_err(dev, "chipselect %d already in use\n",
 				spi->chip_select);
+		put_device(d);
 		status = -EBUSY;
 		goto done;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/spi_imx.c linux-libre-2.6.34-gnu1/drivers/spi/spi_imx.c
--- linux-libre-2.6.33-gnu1/drivers/spi/spi_imx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/spi_imx.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
 #include <linux/types.h>
@@ -469,7 +470,7 @@ static int spi_imx_setup(struct spi_devi
 	struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
 	int gpio = spi_imx->chipselect[spi->chip_select];
 
-	pr_debug("%s: mode %d, %u bpw, %d hz\n", __func__,
+	dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", __func__,
 		 spi->mode, spi->bits_per_word, spi->max_speed_hz);
 
 	if (gpio >= 0)
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/spi_mpc8xxx.c linux-libre-2.6.34-gnu1/drivers/spi/spi_mpc8xxx.c
--- linux-libre-2.6.33-gnu1/drivers/spi/spi_mpc8xxx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/spi_mpc8xxx.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
 #include <linux/of_spi.h>
+#include <linux/slab.h>
 
 #include <sysdev/fsl_soc.h>
 #include <asm/cpm.h>
@@ -365,7 +366,7 @@ int mpc8xxx_spi_setup_transfer(struct sp
 
 	if ((mpc8xxx_spi->spibrg / hz) > 64) {
 		cs->hw_mode |= SPMODE_DIV16;
-		pm = mpc8xxx_spi->spibrg / (hz * 64);
+		pm = (mpc8xxx_spi->spibrg - 1) / (hz * 64) + 1;
 
 		WARN_ONCE(pm > 16, "%s: Requested speed is too low: %d Hz. "
 			  "Will use %d Hz instead.\n", dev_name(&spi->dev),
@@ -373,7 +374,7 @@ int mpc8xxx_spi_setup_transfer(struct sp
 		if (pm > 16)
 			pm = 16;
 	} else
-		pm = mpc8xxx_spi->spibrg / (hz * 4);
+		pm = (mpc8xxx_spi->spibrg - 1) / (hz * 4) + 1;
 	if (pm)
 		pm--;
 
@@ -1328,7 +1329,7 @@ static struct of_platform_driver of_mpc8
 static int __devinit plat_mpc8xxx_spi_probe(struct platform_device *pdev)
 {
 	struct resource *mem;
-	unsigned int irq;
+	int irq;
 	struct spi_master *master;
 
 	if (!pdev->dev.platform_data)
@@ -1339,7 +1340,7 @@ static int __devinit plat_mpc8xxx_spi_pr
 		return -EINVAL;
 
 	irq = platform_get_irq(pdev, 0);
-	if (!irq)
+	if (irq <= 0)
 		return -EINVAL;
 
 	master = mpc8xxx_spi_probe(&pdev->dev, mem, irq);
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/spi_nuc900.c linux-libre-2.6.34-gnu1/drivers/spi/spi_nuc900.c
--- linux-libre-2.6.33-gnu1/drivers/spi/spi_nuc900.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/spi_nuc900.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/spi_ppc4xx.c linux-libre-2.6.34-gnu1/drivers/spi/spi_ppc4xx.c
--- linux-libre-2.6.33-gnu1/drivers/spi/spi_ppc4xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/spi_ppc4xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/wait.h>
 #include <linux/of_platform.h>
@@ -578,7 +579,7 @@ static int __exit spi_ppc4xx_of_remove(s
 	return 0;
 }
 
-static struct of_device_id spi_ppc4xx_of_match[] = {
+static const struct of_device_id spi_ppc4xx_of_match[] = {
 	{ .compatible = "ibm,ppc4xx-spi", },
 	{},
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/spi_s3c24xx.c linux-libre-2.6.34-gnu1/drivers/spi/spi_s3c24xx.c
--- linux-libre-2.6.33-gnu1/drivers/spi/spi_s3c24xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/spi_s3c24xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
@@ -275,7 +276,7 @@ static inline u32 ack_bit(unsigned int i
  * Claim the FIQ handler (only one can be active at any one time) and
  * then setup the correct transfer code for this transfer.
  *
- * This call updates all the necessary state information if sucessful,
+ * This call updates all the necessary state information if successful,
  * so the caller does not need to do anything more than start the transfer
  * as normal, since the IRQ will have been re-routed to the FIQ handler.
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/spi_s3c64xx.c linux-libre-2.6.34-gnu1/drivers/spi/spi_s3c64xx.c
--- linux-libre-2.6.33-gnu1/drivers/spi/spi_s3c64xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/spi_s3c64xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,7 @@
 #include <linux/spi/spi.h>
 
 #include <mach/dma.h>
-#include <plat/spi.h>
+#include <plat/s3c64xx-spi.h>
 
 /* Registers and bit-fields */
 
@@ -137,6 +137,7 @@
 /**
  * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver.
  * @clk: Pointer to the spi clock.
+ * @src_clk: Pointer to the clock used to generate SPI signals.
  * @master: Pointer to the SPI Protocol master.
  * @workqueue: Work queue for the SPI xfer requests.
  * @cntrlr_info: Platform specific data for the controller this driver manages.
@@ -157,10 +158,11 @@
 struct s3c64xx_spi_driver_data {
 	void __iomem                    *regs;
 	struct clk                      *clk;
+	struct clk                      *src_clk;
 	struct platform_device          *pdev;
 	struct spi_master               *master;
 	struct workqueue_struct	        *workqueue;
-	struct s3c64xx_spi_cntrlr_info  *cntrlr_info;
+	struct s3c64xx_spi_info  *cntrlr_info;
 	struct spi_device               *tgl_spi;
 	struct work_struct              work;
 	struct list_head                queue;
@@ -180,7 +182,7 @@ static struct s3c2410_dma_client s3c64xx
 
 static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
 {
-	struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
+	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
 	void __iomem *regs = sdd->regs;
 	unsigned long loops;
 	u32 val;
@@ -225,7 +227,7 @@ static void enable_datapath(struct s3c64
 				struct spi_device *spi,
 				struct spi_transfer *xfer, int dma_mode)
 {
-	struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
+	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
 	void __iomem *regs = sdd->regs;
 	u32 modecfg, chcfg;
 
@@ -298,19 +300,20 @@ static inline void enable_cs(struct s3c6
 		if (sdd->tgl_spi != spi) { /* if last mssg on diff device */
 			/* Deselect the last toggled device */
 			cs = sdd->tgl_spi->controller_data;
-			cs->set_level(spi->mode & SPI_CS_HIGH ? 0 : 1);
+			cs->set_level(cs->line,
+					spi->mode & SPI_CS_HIGH ? 0 : 1);
 		}
 		sdd->tgl_spi = NULL;
 	}
 
 	cs = spi->controller_data;
-	cs->set_level(spi->mode & SPI_CS_HIGH ? 1 : 0);
+	cs->set_level(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0);
 }
 
 static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
 				struct spi_transfer *xfer, int dma_mode)
 {
-	struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
+	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
 	void __iomem *regs = sdd->regs;
 	unsigned long val;
 	int ms;
@@ -384,12 +387,11 @@ static inline void disable_cs(struct s3c
 	if (sdd->tgl_spi == spi)
 		sdd->tgl_spi = NULL;
 
-	cs->set_level(spi->mode & SPI_CS_HIGH ? 0 : 1);
+	cs->set_level(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1);
 }
 
 static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
 {
-	struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
 	void __iomem *regs = sdd->regs;
 	u32 val;
 
@@ -435,7 +437,7 @@ static void s3c64xx_spi_config(struct s3
 	/* Configure Clock */
 	val = readl(regs + S3C64XX_SPI_CLK_CFG);
 	val &= ~S3C64XX_SPI_PSR_MASK;
-	val |= ((clk_get_rate(sci->src_clk) / sdd->cur_speed / 2 - 1)
+	val |= ((clk_get_rate(sdd->src_clk) / sdd->cur_speed / 2 - 1)
 			& S3C64XX_SPI_PSR_MASK);
 	writel(val, regs + S3C64XX_SPI_CLK_CFG);
 
@@ -558,7 +560,7 @@ static void s3c64xx_spi_unmap_mssg(struc
 static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
 					struct spi_message *msg)
 {
-	struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
+	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
 	struct spi_device *spi = msg->spi;
 	struct s3c64xx_spi_csinfo *cs = spi->controller_data;
 	struct spi_transfer *xfer;
@@ -632,8 +634,8 @@ static void handle_msg(struct s3c64xx_sp
 		S3C64XX_SPI_DEACT(sdd);
 
 		if (status) {
-			dev_err(&spi->dev, "I/O Error: \
-				rx-%d tx-%d res:rx-%c tx-%c len-%d\n",
+			dev_err(&spi->dev, "I/O Error: "
+				"rx-%d tx-%d res:rx-%c tx-%c len-%d\n",
 				xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0,
 				(sdd->state & RXBUSY) ? 'f' : 'p',
 				(sdd->state & TXBUSY) ? 'f' : 'p',
@@ -786,7 +788,7 @@ static int s3c64xx_spi_setup(struct spi_
 {
 	struct s3c64xx_spi_csinfo *cs = spi->controller_data;
 	struct s3c64xx_spi_driver_data *sdd;
-	struct s3c64xx_spi_cntrlr_info *sci;
+	struct s3c64xx_spi_info *sci;
 	struct spi_message *msg;
 	u32 psr, speed;
 	unsigned long flags;
@@ -831,17 +833,17 @@ static int s3c64xx_spi_setup(struct spi_
 	}
 
 	/* Check if we can provide the requested rate */
-	speed = clk_get_rate(sci->src_clk) / 2 / (0 + 1); /* Max possible */
+	speed = clk_get_rate(sdd->src_clk) / 2 / (0 + 1); /* Max possible */
 
 	if (spi->max_speed_hz > speed)
 		spi->max_speed_hz = speed;
 
-	psr = clk_get_rate(sci->src_clk) / 2 / spi->max_speed_hz - 1;
+	psr = clk_get_rate(sdd->src_clk) / 2 / spi->max_speed_hz - 1;
 	psr &= S3C64XX_SPI_PSR_MASK;
 	if (psr == S3C64XX_SPI_PSR_MASK)
 		psr--;
 
-	speed = clk_get_rate(sci->src_clk) / 2 / (psr + 1);
+	speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1);
 	if (spi->max_speed_hz < speed) {
 		if (psr+1 < S3C64XX_SPI_PSR_MASK) {
 			psr++;
@@ -851,7 +853,7 @@ static int s3c64xx_spi_setup(struct spi_
 		}
 	}
 
-	speed = clk_get_rate(sci->src_clk) / 2 / (psr + 1);
+	speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1);
 	if (spi->max_speed_hz >= speed)
 		spi->max_speed_hz = speed;
 	else
@@ -867,7 +869,7 @@ setup_exit:
 
 static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
 {
-	struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
+	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
 	void __iomem *regs = sdd->regs;
 	unsigned int val;
 
@@ -902,7 +904,7 @@ static int __init s3c64xx_spi_probe(stru
 {
 	struct resource	*mem_res, *dmatx_res, *dmarx_res;
 	struct s3c64xx_spi_driver_data *sdd;
-	struct s3c64xx_spi_cntrlr_info *sci;
+	struct s3c64xx_spi_info *sci;
 	struct spi_master *master;
 	int ret;
 
@@ -1000,18 +1002,15 @@ static int __init s3c64xx_spi_probe(stru
 		goto err4;
 	}
 
-	if (sci->src_clk_nr == S3C64XX_SPI_SRCCLK_PCLK)
-		sci->src_clk = sdd->clk;
-	else
-		sci->src_clk = clk_get(&pdev->dev, sci->src_clk_name);
-	if (IS_ERR(sci->src_clk)) {
+	sdd->src_clk = clk_get(&pdev->dev, sci->src_clk_name);
+	if (IS_ERR(sdd->src_clk)) {
 		dev_err(&pdev->dev,
 			"Unable to acquire clock '%s'\n", sci->src_clk_name);
-		ret = PTR_ERR(sci->src_clk);
+		ret = PTR_ERR(sdd->src_clk);
 		goto err5;
 	}
 
-	if (sci->src_clk != sdd->clk && clk_enable(sci->src_clk)) {
+	if (clk_enable(sdd->src_clk)) {
 		dev_err(&pdev->dev, "Couldn't enable clock '%s'\n",
 							sci->src_clk_name);
 		ret = -EBUSY;
@@ -1040,11 +1039,10 @@ static int __init s3c64xx_spi_probe(stru
 		goto err8;
 	}
 
-	dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d \
-					with %d Slaves attached\n",
+	dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d "
+					"with %d Slaves attached\n",
 					pdev->id, master->num_chipselect);
-	dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\
-					\tDMA=[Rx-%d, Tx-%d]\n",
+	dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n",
 					mem_res->end, mem_res->start,
 					sdd->rx_dmach, sdd->tx_dmach);
 
@@ -1053,11 +1051,9 @@ static int __init s3c64xx_spi_probe(stru
 err8:
 	destroy_workqueue(sdd->workqueue);
 err7:
-	if (sci->src_clk != sdd->clk)
-		clk_disable(sci->src_clk);
+	clk_disable(sdd->src_clk);
 err6:
-	if (sci->src_clk != sdd->clk)
-		clk_put(sci->src_clk);
+	clk_put(sdd->src_clk);
 err5:
 	clk_disable(sdd->clk);
 err4:
@@ -1078,7 +1074,6 @@ static int s3c64xx_spi_remove(struct pla
 {
 	struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
-	struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
 	struct resource	*mem_res;
 	unsigned long flags;
 
@@ -1093,11 +1088,8 @@ static int s3c64xx_spi_remove(struct pla
 
 	destroy_workqueue(sdd->workqueue);
 
-	if (sci->src_clk != sdd->clk)
-		clk_disable(sci->src_clk);
-
-	if (sci->src_clk != sdd->clk)
-		clk_put(sci->src_clk);
+	clk_disable(sdd->src_clk);
+	clk_put(sdd->src_clk);
 
 	clk_disable(sdd->clk);
 	clk_put(sdd->clk);
@@ -1105,7 +1097,8 @@ static int s3c64xx_spi_remove(struct pla
 	iounmap((void *) sdd->regs);
 
 	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(mem_res->start, resource_size(mem_res));
+	if (mem_res != NULL)
+		release_mem_region(mem_res->start, resource_size(mem_res));
 
 	platform_set_drvdata(pdev, NULL);
 	spi_master_put(master);
@@ -1118,8 +1111,6 @@ static int s3c64xx_spi_suspend(struct pl
 {
 	struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
-	struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
-	struct s3c64xx_spi_csinfo *cs;
 	unsigned long flags;
 
 	spin_lock_irqsave(&sdd->lock, flags);
@@ -1130,9 +1121,7 @@ static int s3c64xx_spi_suspend(struct pl
 		msleep(10);
 
 	/* Disable the clock */
-	if (sci->src_clk != sdd->clk)
-		clk_disable(sci->src_clk);
-
+	clk_disable(sdd->src_clk);
 	clk_disable(sdd->clk);
 
 	sdd->cur_speed = 0; /* Output Clock is stopped */
@@ -1144,15 +1133,13 @@ static int s3c64xx_spi_resume(struct pla
 {
 	struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
-	struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
+	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
 	unsigned long flags;
 
 	sci->cfg_gpio(pdev);
 
 	/* Enable the clock */
-	if (sci->src_clk != sdd->clk)
-		clk_enable(sci->src_clk);
-
+	clk_enable(sdd->src_clk);
 	clk_enable(sdd->clk);
 
 	s3c64xx_spi_hwinit(sdd, pdev->id);
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/spi_sh_msiof.c linux-libre-2.6.34-gnu1/drivers/spi/spi_sh_msiof.c
--- linux-libre-2.6.33-gnu1/drivers/spi/spi_sh_msiof.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/spi_sh_msiof.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,12 +20,12 @@
 #include <linux/bitmap.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/err.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
 #include <linux/spi/sh_msiof.h>
 
-#include <asm/spi.h>
 #include <asm/unaligned.h>
 
 struct sh_msiof_spi_priv {
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/spi_stmp.c linux-libre-2.6.34-gnu1/drivers/spi/spi_stmp.c
--- linux-libre-2.6.33-gnu1/drivers/spi/spi_stmp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/spi_stmp.c	2010-05-16 17:17:36.000000000 -0400
@@ -76,7 +76,7 @@ struct stmp_spi {
 			break;						\
 		}							\
 		cpu_relax();						\
-	} while (time_before(end_jiffies, jiffies));			\
+	} while (time_before(jiffies, end_jiffies));			\
 	succeeded;							\
 	})
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/tle62x0.c linux-libre-2.6.34-gnu1/drivers/spi/tle62x0.c
--- linux-libre-2.6.33-gnu1/drivers/spi/tle62x0.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/tle62x0.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <linux/device.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/tle62x0.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/xilinx_spi.c linux-libre-2.6.34-gnu1/drivers/spi/xilinx_spi.c
--- linux-libre-2.6.33-gnu1/drivers/spi/xilinx_spi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/xilinx_spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -93,6 +93,26 @@ struct xilinx_spi {
 	void (*rx_fn) (struct xilinx_spi *);
 };
 
+static void xspi_write32(u32 val, void __iomem *addr)
+{
+	iowrite32(val, addr);
+}
+
+static unsigned int xspi_read32(void __iomem *addr)
+{
+	return ioread32(addr);
+}
+
+static void xspi_write32_be(u32 val, void __iomem *addr)
+{
+	iowrite32be(val, addr);
+}
+
+static unsigned int xspi_read32_be(void __iomem *addr)
+{
+	return ioread32be(addr);
+}
+
 static void xspi_tx8(struct xilinx_spi *xspi)
 {
 	xspi->write_fn(*xspi->tx_ptr, xspi->regs + XSPI_TXD_OFFSET);
@@ -374,11 +394,11 @@ struct spi_master *xilinx_spi_init(struc
 	xspi->mem = *mem;
 	xspi->irq = irq;
 	if (pdata->little_endian) {
-		xspi->read_fn = ioread32;
-		xspi->write_fn = iowrite32;
+		xspi->read_fn = xspi_read32;
+		xspi->write_fn = xspi_write32;
 	} else {
-		xspi->read_fn = ioread32be;
-		xspi->write_fn = iowrite32be;
+		xspi->read_fn = xspi_read32_be;
+		xspi->write_fn = xspi_write32_be;
 	}
 	xspi->bits_per_word = pdata->bits_per_word;
 	if (xspi->bits_per_word == 8) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/spi/xilinx_spi_of.c linux-libre-2.6.34-gnu1/drivers/spi/xilinx_spi_of.c
--- linux-libre-2.6.33-gnu1/drivers/spi/xilinx_spi_of.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/spi/xilinx_spi_of.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/of_platform.h>
 #include <linux/of_device.h>
@@ -99,7 +100,7 @@ static int __exit xilinx_spi_of_remove(s
 	return xilinx_spi_remove(op);
 }
 
-static struct of_device_id xilinx_spi_of_match[] = {
+static const struct of_device_id xilinx_spi_of_match[] = {
 	{ .compatible = "xlnx,xps-spi-2.00.a", },
 	{ .compatible = "xlnx,xps-spi-2.00.b", },
 	{}
diff -druNp linux-libre-2.6.33-gnu1/drivers/ssb/driver_chipcommon_pmu.c linux-libre-2.6.34-gnu1/drivers/ssb/driver_chipcommon_pmu.c
--- linux-libre-2.6.33-gnu1/drivers/ssb/driver_chipcommon_pmu.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ssb/driver_chipcommon_pmu.c	2010-05-16 17:17:36.000000000 -0400
@@ -332,6 +332,12 @@ static void ssb_pmu_pll_init(struct ssb_
 	case 0x5354:
 		ssb_pmu0_pllinit_r0(cc, crystalfreq);
 		break;
+	case 0x4322:
+		if (cc->pmu.rev == 2) {
+			chipco_write32(cc, SSB_CHIPCO_PLLCTL_ADDR, 0x0000000A);
+			chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, 0x380005C0);
+		}
+		break;
 	default:
 		ssb_printk(KERN_ERR PFX
 			   "ERROR: PLL init unknown for device %04X\n",
@@ -417,6 +423,7 @@ static void ssb_pmu_resources_init(struc
 
 	switch (bus->chip_id) {
 	case 0x4312:
+	case 0x4322:
 		/* We keep the default settings:
 		 * min_msk = 0xCBB
 		 * max_msk = 0x7FFFF
diff -druNp linux-libre-2.6.33-gnu1/drivers/ssb/driver_gige.c linux-libre-2.6.34-gnu1/drivers/ssb/driver_gige.c
--- linux-libre-2.6.33-gnu1/drivers/ssb/driver_gige.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ssb/driver_gige.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/ssb/ssb_driver_gige.h>
 #include <linux/pci.h>
 #include <linux/pci_regs.h>
+#include <linux/slab.h>
 
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/ssb/driver_mipscore.c linux-libre-2.6.34-gnu1/drivers/ssb/driver_mipscore.c
--- linux-libre-2.6.33-gnu1/drivers/ssb/driver_mipscore.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ssb/driver_mipscore.c	2010-05-16 17:17:36.000000000 -0400
@@ -270,7 +270,6 @@ void ssb_mipscore_init(struct ssb_mipsco
 				set_irq(dev, irq++);
 			}
 			break;
-			/* fallthrough */
 		case SSB_DEV_PCI:
 		case SSB_DEV_ETHERNET:
 		case SSB_DEV_ETHERNET_GBIT:
@@ -281,6 +280,10 @@ void ssb_mipscore_init(struct ssb_mipsco
 				set_irq(dev, irq++);
 				break;
 			}
+			/* fallthrough */
+		case SSB_DEV_EXTIF:
+			set_irq(dev, 0);
+			break;
 		}
 	}
 	ssb_dprintk(KERN_INFO PFX "after irq reconfiguration\n");
diff -druNp linux-libre-2.6.33-gnu1/drivers/ssb/driver_pcicore.c linux-libre-2.6.34-gnu1/drivers/ssb/driver_pcicore.c
--- linux-libre-2.6.33-gnu1/drivers/ssb/driver_pcicore.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ssb/driver_pcicore.c	2010-05-16 17:17:36.000000000 -0400
@@ -246,20 +246,12 @@ static struct pci_controller ssb_pcicore
 	.pci_ops	= &ssb_pcicore_pciops,
 	.io_resource	= &ssb_pcicore_io_resource,
 	.mem_resource	= &ssb_pcicore_mem_resource,
-	.mem_offset	= 0x24000000,
 };
 
-static u32 ssb_pcicore_pcibus_iobase = 0x100;
-static u32 ssb_pcicore_pcibus_membase = SSB_PCI_DMA;
-
 /* This function is called when doing a pci_enable_device().
  * We must first check if the device is a device on the PCI-core bridge. */
 int ssb_pcicore_plat_dev_init(struct pci_dev *d)
 {
-	struct resource *res;
-	int pos, size;
-	u32 *base;
-
 	if (d->bus->ops != &ssb_pcicore_pciops) {
 		/* This is not a device on the PCI-core bridge. */
 		return -ENODEV;
@@ -268,27 +260,6 @@ int ssb_pcicore_plat_dev_init(struct pci
 	ssb_printk(KERN_INFO "PCI: Fixing up device %s\n",
 		   pci_name(d));
 
-	/* Fix up resource bases */
-	for (pos = 0; pos < 6; pos++) {
-		res = &d->resource[pos];
-		if (res->flags & IORESOURCE_IO)
-			base = &ssb_pcicore_pcibus_iobase;
-		else
-			base = &ssb_pcicore_pcibus_membase;
-		res->flags |= IORESOURCE_PCI_FIXED;
-		if (res->end) {
-			size = res->end - res->start + 1;
-			if (*base & (size - 1))
-				*base = (*base + size) & ~(size - 1);
-			res->start = *base;
-			res->end = res->start + size - 1;
-			*base += size;
-			pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
-		}
-		/* Fix up PCI bridge BAR0 only */
-		if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0)
-			break;
-	}
 	/* Fix up interrupt lines */
 	d->irq = ssb_mips_irq(extpci_core->dev) + 2;
 	pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
diff -druNp linux-libre-2.6.33-gnu1/drivers/ssb/main.c linux-libre-2.6.34-gnu1/drivers/ssb/main.c
--- linux-libre-2.6.33-gnu1/drivers/ssb/main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ssb/main.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/pci.h>
 #include <linux/mmc/sdio_func.h>
+#include <linux/slab.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/ssb/pci.c linux-libre-2.6.34-gnu1/drivers/ssb/pci.c
--- linux-libre-2.6.33-gnu1/drivers/ssb/pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ssb/pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_regs.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ssb/pcihost_wrapper.c linux-libre-2.6.34-gnu1/drivers/ssb/pcihost_wrapper.c
--- linux-libre-2.6.33-gnu1/drivers/ssb/pcihost_wrapper.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ssb/pcihost_wrapper.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/ssb/ssb.h>
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/ssb/sprom.c linux-libre-2.6.34-gnu1/drivers/ssb/sprom.c
--- linux-libre-2.6.33-gnu1/drivers/ssb/sprom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ssb/sprom.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include "ssb_private.h"
 
 #include <linux/ctype.h>
+#include <linux/slab.h>
 
 
 static const struct ssb_sprom *fallback_sprom;
diff -druNp linux-libre-2.6.33-gnu1/drivers/ssb/ssb_private.h linux-libre-2.6.34-gnu1/drivers/ssb/ssb_private.h
--- linux-libre-2.6.33-gnu1/drivers/ssb/ssb_private.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/ssb/ssb_private.h	2010-05-16 17:17:36.000000000 -0400
@@ -196,7 +196,7 @@ extern int ssb_devices_thaw(struct ssb_f
 #ifdef CONFIG_SSB_B43_PCI_BRIDGE
 extern int __init b43_pci_ssb_bridge_init(void);
 extern void __exit b43_pci_ssb_bridge_exit(void);
-#else /* CONFIG_SSB_B43_PCI_BRIDGR */
+#else /* CONFIG_SSB_B43_PCI_BRIDGE */
 static inline int b43_pci_ssb_bridge_init(void)
 {
 	return 0;
@@ -204,6 +204,6 @@ static inline int b43_pci_ssb_bridge_ini
 static inline void b43_pci_ssb_bridge_exit(void)
 {
 }
-#endif /* CONFIG_SSB_PCIHOST */
+#endif /* CONFIG_SSB_B43_PCI_BRIDGE */
 
 #endif /* LINUX_SSB_PRIVATE_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/altpciechdma/altpciechdma.c linux-libre-2.6.34-gnu1/drivers/staging/altpciechdma/altpciechdma.c
--- linux-libre-2.6.33-gnu1/drivers/staging/altpciechdma/altpciechdma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/altpciechdma/altpciechdma.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1182 +0,0 @@
-/**
- * Driver for Altera PCIe core chaining DMA reference design.
- *
- * Copyright (C) 2008 Leon Woestenberg  <leon.woestenberg@axon.tv>
- * Copyright (C) 2008 Nickolas Heppermann  <heppermannwdt@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.
- *
- *
- * Rationale: This driver exercises the chaining DMA read and write engine
- * in the reference design. It is meant as a complementary reference
- * driver that can be used for testing early designs as well as a basis to
- * write your custom driver.
- *
- * Status: Test results from Leon Woestenberg  <leon.woestenberg@axon.tv>:
- *
- * Sendero Board w/ Cyclone II EP2C35F672C6N, PX1011A PCIe x1 PHY on a
- * Dell Precision 370 PC, x86, kernel 2.6.20 from Ubuntu 7.04.
- *
- * Sendero Board w/ Cyclone II EP2C35F672C6N, PX1011A PCIe x1 PHY on a
- * Freescale MPC8313E-RDB board, PowerPC, 2.6.24 w/ Freescale patches.
- *
- * Driver tests passed with PCIe Compiler 8.1. With PCIe 8.0 the DMA
- * loopback test had reproducable compare errors. I assume a change
- * in the compiler or reference design, but could not find evidence nor
- * documentation on a change or fix in that direction.
- *
- * The reference design does not have readable locations and thus a
- * dummy read, used to flush PCI posted writes, cannot be performed.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/cdev.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/jiffies.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-
-
-/* by default do not build the character device interface */
-/* XXX It is non-functional yet */
-#ifndef ALTPCIECHDMA_CDEV
-#  define ALTPCIECHDMA_CDEV 0
-#endif
-
-/* build the character device interface? */
-#if ALTPCIECHDMA_CDEV
-#  define MAX_CHDMA_SIZE (8 * 1024 * 1024)
-#  include "mapper_user_to_sg.h"
-#endif
-
-/** driver name, mimicks Altera naming of the reference design */
-#define DRV_NAME "altpciechdma"
-/** number of BARs on the device */
-#define APE_BAR_NUM (6)
-/** BAR number where the RCSLAVE memory sits */
-#define APE_BAR_RCSLAVE (0)
-/** BAR number where the Descriptor Header sits */
-#define APE_BAR_HEADER (2)
-
-/** maximum size in bytes of the descriptor table, chdma logic limit */
-#define APE_CHDMA_TABLE_SIZE (4096)
-/* single transfer must not exceed 255 table entries. worst case this can be
- * achieved by 255 scattered pages, with only a single byte in the head and
- * tail pages. 253 * PAGE_SIZE is a safe upper bound for the transfer size.
- */
-#define APE_CHDMA_MAX_TRANSFER_LEN (253 * PAGE_SIZE)
-
-/**
- * Specifies those BARs to be mapped and the length of each mapping.
- *
- * Zero (0) means do not map, otherwise specifies the BAR lengths to be mapped.
- * If the actual BAR length is less, this is considered an error; then
- * reconfigure your PCIe core.
- *
- * @see ug_pci_express 8.0, table 7-2 at page 7-13.
- */
-static const unsigned long bar_min_len[APE_BAR_NUM] =
-	{ 32768, 0, 256, 0, 32768, 0 };
-
-/**
- * Descriptor Header, controls the DMA read engine or write engine.
- *
- * The descriptor header is the main data structure for starting DMA transfers.
- *
- * It sits in End Point (FPGA) memory BAR[2] for 32-bit or BAR[3:2] for 64-bit.
- * It references a descriptor table which exists in Root Complex (PC) memory.
- * Writing the rclast field starts the DMA operation, thus all other structures
- * and fields must be setup before doing so.
- *
- * @see ug_pci_express 8.0, tables 7-3, 7-4 and 7-5 at page 7-14.
- * @note This header must be written in four 32-bit (PCI DWORD) writes.
- */
-struct ape_chdma_header {
-	/**
-	 * w0 consists of two 16-bit fields:
-	 * lsb u16 number; number of descriptors in ape_chdma_table
-	 * msb u16 control; global control flags
-	 */
-	u32 w0;
-	/* bus address to ape_chdma_table in Root Complex memory */
-	u32 bdt_addr_h;
-	u32 bdt_addr_l;
-	/**
-	 * w3 consists of two 16-bit fields:
-	 * - lsb u16 rclast; last descriptor number available in Root Complex
-	 *    - zero (0) means the first descriptor is ready,
-	 *    - one (1) means two descriptors are ready, etc.
-	 * - msb u16 reserved;
-	 *
-	 * @note writing to this memory location starts the DMA operation!
-	 */
-	u32 w3;
-} __attribute__ ((packed));
-
-/**
- * Descriptor Entry, describing a (non-scattered) single memory block transfer.
- *
- * There is one descriptor for each memory block involved in the transfer, a
- * block being a contiguous address range on the bus.
- *
- * Multiple descriptors are chained by means of the ape_chdma_table data
- * structure.
- *
- * @see ug_pci_express 8.0, tables 7-6, 7-7 and 7-8 at page 7-14 and page 7-15.
- */
-struct ape_chdma_desc {
-	/**
-	 * w0 consists of two 16-bit fields:
-	 * number of DWORDS to transfer
-	 * - lsb u16 length;
-	 * global control
-	 * - msb u16 control;
-	 */
-	u32 w0;
-	/* address of memory in the End Point */
-	u32 ep_addr;
-	/* bus address of source or destination memory in the Root Complex */
-	u32 rc_addr_h;
-	u32 rc_addr_l;
-} __attribute__ ((packed));
-
-/**
- * Descriptor Table, an array of descriptors describing a chained transfer.
- *
- * An array of descriptors, preceded by workspace for the End Point.
- * It exists in Root Complex memory.
- *
- * The End Point can update its last completed descriptor number in the
- * eplast field if requested by setting the EPLAST_ENA bit either
- * globally in the header's or locally in any descriptor's control field.
- *
- * @note this structure may not exceed 4096 bytes. This results in a
- * maximum of 4096 / (4 * 4) - 1 = 255 descriptors per chained transfer.
- *
- * @see ug_pci_express 8.0, tables 7-9, 7-10 and 7-11 at page 7-17 and page 7-18.
- */
-struct ape_chdma_table {
-	/* workspace 0x00-0x0b, reserved */
-	u32 reserved1[3];
-	/* workspace 0x0c-0x0f, last descriptor handled by End Point */
-	u32 w3;
-	/* the actual array of descriptors
-    * 0x10-0x1f, 0x20-0x2f, ... 0xff0-0xfff (255 entries)
-    */
-	struct ape_chdma_desc desc[255];
-} __attribute__ ((packed));
-
-/**
- * Altera PCI Express ('ape') board specific book keeping data
- *
- * Keeps state of the PCIe core and the Chaining DMA controller
- * application.
- */
-struct ape_dev {
-	/** the kernel pci device data structure provided by probe() */
-	struct pci_dev *pci_dev;
-	/**
-	 * kernel virtual address of the mapped BAR memory and IO regions of
-	 * the End Point. Used by map_bars()/unmap_bars().
-	 */
-	void * __iomem bar[APE_BAR_NUM];
-	/** kernel virtual address for Descriptor Table in Root Complex memory */
-	struct ape_chdma_table *table_virt;
-	/**
-	 * bus address for the Descriptor Table in Root Complex memory, in
-	 * CPU-native endianess
-	 */
-	dma_addr_t table_bus;
-	/* if the device regions could not be allocated, assume and remember it
-	 * is in use by another driver; this driver must not disable the device.
-	 */
-	int in_use;
-	/* whether this driver enabled msi for the device */
-	int msi_enabled;
-	/* whether this driver could obtain the regions */
-	int got_regions;
-	/* irq line successfully requested by this driver, -1 otherwise */
-	int irq_line;
-	/* board revision */
-	u8 revision;
-	/* interrupt count, incremented by the interrupt handler */
-	int irq_count;
-#if ALTPCIECHDMA_CDEV
-	/* character device */
-	dev_t cdevno;
-	struct cdev cdev;
-	/* user space scatter gather mapper */
-	struct sg_mapping_t *sgm;
-#endif
-};
-
-/**
- * Using the subsystem vendor id and subsystem id, it is possible to
- * distinguish between different cards bases around the same
- * (third-party) logic core.
- *
- * Default Altera vendor and device ID's, and some (non-reserved)
- * ID's are now used here that are used amongst the testers/developers.
- */
-static const struct pci_device_id ids[] = {
-	{ PCI_DEVICE(0x1172, 0xE001), },
-	{ PCI_DEVICE(0x2071, 0x2071), },
-	{ 0, }
-};
-MODULE_DEVICE_TABLE(pci, ids);
-
-#if ALTPCIECHDMA_CDEV
-/* prototypes for character device */
-static int sg_init(struct ape_dev *ape);
-static void sg_exit(struct ape_dev *ape);
-#endif
-
-/**
- * altpciechdma_isr() - Interrupt handler
- *
- */
-static irqreturn_t altpciechdma_isr(int irq, void *dev_id)
-{
-	struct ape_dev *ape = (struct ape_dev *)dev_id;
-	if (!ape)
-		return IRQ_NONE;
-	ape->irq_count++;
-	return IRQ_HANDLED;
-}
-
-static int __devinit scan_bars(struct ape_dev *ape, struct pci_dev *dev)
-{
-	int i;
-	for (i = 0; i < APE_BAR_NUM; i++) {
-		unsigned long bar_start = pci_resource_start(dev, i);
-		if (bar_start) {
-			unsigned long bar_end = pci_resource_end(dev, i);
-			unsigned long bar_flags = pci_resource_flags(dev, i);
-			printk(KERN_DEBUG "BAR%d 0x%08lx-0x%08lx flags 0x%08lx\n",
-			  i, bar_start, bar_end, bar_flags);
-		}
-	}
-	return 0;
-}
-
-/**
- * Unmap the BAR regions that had been mapped earlier using map_bars()
- */
-static void unmap_bars(struct ape_dev *ape, struct pci_dev *dev)
-{
-	int i;
-	for (i = 0; i < APE_BAR_NUM; i++) {
-	  /* is this BAR mapped? */
-		if (ape->bar[i]) {
-			/* unmap BAR */
-			pci_iounmap(dev, ape->bar[i]);
-			ape->bar[i] = NULL;
-		}
-	}
-}
-
-/**
- * Map the device memory regions into kernel virtual address space after
- * verifying their sizes respect the minimum sizes needed, given by the
- * bar_min_len[] array.
- */
-static int __devinit map_bars(struct ape_dev *ape, struct pci_dev *dev)
-{
-	int rc;
-	int i;
-	/* iterate through all the BARs */
-	for (i = 0; i < APE_BAR_NUM; i++) {
-		unsigned long bar_start = pci_resource_start(dev, i);
-		unsigned long bar_end = pci_resource_end(dev, i);
-		unsigned long bar_length = bar_end - bar_start + 1;
-		ape->bar[i] = NULL;
-		/* do not map, and skip, BARs with length 0 */
-		if (!bar_min_len[i])
-			continue;
-		/* do not map BARs with address 0 */
-		if (!bar_start || !bar_end) {
-			printk(KERN_DEBUG "BAR #%d is not present?!\n", i);
-			rc = -1;
-			goto fail;
-		}
-		bar_length = bar_end - bar_start + 1;
-		/* BAR length is less than driver requires? */
-		if (bar_length < bar_min_len[i]) {
-			printk(KERN_DEBUG "BAR #%d length = %lu bytes but driver "
-			"requires at least %lu bytes\n",
-			i, bar_length, bar_min_len[i]);
-			rc = -1;
-			goto fail;
-		}
-		/* map the device memory or IO region into kernel virtual
-		 * address space */
-		ape->bar[i] = pci_iomap(dev, i, bar_min_len[i]);
-		if (!ape->bar[i]) {
-			printk(KERN_DEBUG "Could not map BAR #%d.\n", i);
-			rc = -1;
-			goto fail;
-		}
-		printk(KERN_DEBUG "BAR[%d] mapped at 0x%p with length %lu(/%lu).\n", i,
-		ape->bar[i], bar_min_len[i], bar_length);
-	}
-	/* successfully mapped all required BAR regions */
-	rc = 0;
-	goto success;
-fail:
-	/* unmap any BARs that we did map */
-	unmap_bars(ape, dev);
-success:
-	return rc;
-}
-
-#if 0 /* not yet implemented fully FIXME add opcode */
-static void __devinit rcslave_test(struct ape_dev *ape, struct pci_dev *dev)
-{
-	u32 *rcslave_mem = (u32 *)ape->bar[APE_BAR_RCSLAVE];
-	u32 result = 0;
-	/** this number is assumed to be different each time this test runs */
-	u32 seed = (u32)jiffies;
-	u32 value = seed;
-	int i;
-
-	/* write loop */
-	value = seed;
-	for (i = 1024; i < 32768 / 4 ; i++) {
-		printk(KERN_DEBUG "Writing 0x%08x to 0x%p.\n",
-			(u32)value, (void *)rcslave_mem + i);
-		iowrite32(value, rcslave_mem + i);
-		value++;
-	}
-	/* read-back loop */
-	value = seed;
-	for (i = 1024; i < 32768 / 4; i++) {
-		result = ioread32(rcslave_mem + i);
-		if (result != value) {
-			printk(KERN_DEBUG "Wrote 0x%08x to 0x%p, but read back 0x%08x.\n",
-				(u32)value, (void *)rcslave_mem + i, (u32)result);
-			break;
-		}
-		value++;
-	}
-}
-#endif
-
-/* obtain the 32 most significant (high) bits of a 32-bit or 64-bit address */
-#define pci_dma_h(addr) ((addr >> 16) >> 16)
-/* obtain the 32 least significant (low) bits of a 32-bit or 64-bit address */
-#define pci_dma_l(addr) (addr & 0xffffffffUL)
-
-/* ape_fill_chdma_desc() - Fill a Altera PCI Express Chaining DMA descriptor
- *
- * @desc pointer to descriptor to be filled
- * @addr root complex address
- * @ep_addr end point address
- * @len number of bytes, must be a multiple of 4.
- */
-static inline void ape_chdma_desc_set(struct ape_chdma_desc *desc, dma_addr_t addr, u32 ep_addr, int len)
-{
-  BUG_ON(len & 3);
-	desc->w0 = cpu_to_le32(len / 4);
-	desc->ep_addr = cpu_to_le32(ep_addr);
-	desc->rc_addr_h = cpu_to_le32(pci_dma_h(addr));
-	desc->rc_addr_l = cpu_to_le32(pci_dma_l(addr));
-}
-
-#if ALTPCIECHDMA_CDEV
-/*
- * ape_sg_to_chdma_table() - Create a device descriptor table from a scatterlist.
- *
- * The scatterlist must have been mapped by pci_map_sg(sgm->sgl).
- *
- * @sgl scatterlist.
- * @nents Number of entries in the scatterlist.
- * @first Start index in the scatterlist sgm->sgl.
- * @ep_addr End Point address for the scatter/gather transfer.
- * @desc pointer to first descriptor
- *
- * Returns Number of entries in the table on success, -1 on error.
- */
-static int ape_sg_to_chdma_table(struct scatterlist *sgl, int nents, int first, struct ape_chdma_desc *desc, u32 ep_addr)
-{
-	int i = first, j = 0;
-	/* inspect first entry */
-	dma_addr_t addr = sg_dma_address(&sgl[i]);
-	unsigned int len = sg_dma_len(&sgl[i]);
-	/* contiguous block */
-	dma_addr_t cont_addr = addr;
-	unsigned int cont_len = len;
-	/* iterate over remaining entries */
-	for (; j < 25 && i < nents - 1; i++) {
-		/* bus address of next entry i + 1 */
-		dma_addr_t next = sg_dma_address(&sgl[i + 1]);
-		/* length of this entry i */
-		len = sg_dma_len(&sgl[i]);
-		printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i,
-			(unsigned long long)addr, len);
-		/* entry i + 1 is non-contiguous with entry i? */
-		if (next != addr + len) {
-			/* TODO create entry here (we could overwrite i) */
-			printk(KERN_DEBUG "%4d: cont_addr=0x%Lx cont_len=0x%08x\n", j,
-				(unsigned long long)cont_addr, cont_len);
-			/* set descriptor for contiguous transfer */
-			ape_chdma_desc_set(&desc[j], cont_addr, ep_addr, cont_len);
-			/* next end point memory address */
-			ep_addr += cont_len;
-			/* start new contiguous block */
-			cont_addr = next;
-			cont_len = 0;
-			j++;
-		}
-		/* add entry i + 1 to current contiguous block */
-		cont_len += len;
-		/* goto entry i + 1 */
-		addr = next;
-	}
-	/* TODO create entry here  (we could overwrite i) */
-	printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i,
-		(unsigned long long)addr, len);
-	printk(KERN_DEBUG "%4d: cont_addr=0x%Lx length=0x%08x\n", j,
-		(unsigned long long)cont_addr, cont_len);
-	j++;
-	return j;
-}
-#endif
-
-/* compare buffers */
-static inline int compare(u32 *p, u32 *q, int len)
-{
-	int result = -1;
-	int fail = 0;
-	int i;
-	for (i = 0; i < len / 4; i++) {
-		if (*p == *q) {
-			/* every so many u32 words, show equals */
-			if ((i & 255) == 0)
-				printk(KERN_DEBUG "[%p] = 0x%08x    [%p] = 0x%08x\n", p, *p, q, *q);
-		} else {
-			fail++;
-			/* show the first few miscompares */
-			if (fail < 10)
-				printk(KERN_DEBUG "[%p] = 0x%08x != [%p] = 0x%08x ?!\n", p, *p, q, *q);
-				/* but stop after a while */
-			else if (fail == 10)
-				printk(KERN_DEBUG "---more errors follow! not printed---\n");
-			else
-				/* stop compare after this many errors */
-			break;
-		}
-		p++;
-		q++;
-	}
-	if (!fail)
-		result = 0;
-	return result;
-}
-
-/* dma_test() - Perform DMA loop back test to end point and back to root complex.
- *
- * Allocate a cache-coherent buffer in host memory, consisting of four pages.
- *
- * Fill the four memory pages such that each 32-bit word contains its own address.
- *
- * Now perform a loop back test, have the end point device copy the first buffer
- * half to end point memory, then have it copy back into the second half.
- *
- *   Create a descriptor table to copy the first buffer half into End Point
- *   memory. Instruct the End Point to do a DMA read using that table.
- *
- *   Create a descriptor table to copy End Point memory to the second buffer
- *   half. Instruct the End Point to do a DMA write using that table.
- *
- * Compare results, fail or pass.
- *
- */
-static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
-{
-	/* test result; guilty until proven innocent */
-	int result = -1;
-	/* the DMA read header sits at address 0x00 of the DMA engine BAR */
-	struct ape_chdma_header *write_header = (struct ape_chdma_header *)ape->bar[APE_BAR_HEADER];
-	/* the write DMA header sits after the read header at address 0x10 */
-	struct ape_chdma_header *read_header = write_header + 1;
-	/* virtual address of the allocated buffer */
-	u8 *buffer_virt = 0;
-	/* bus address of the allocated buffer */
-	dma_addr_t buffer_bus = 0;
-	int i, n = 0, irq_count;
-
-	/* temporary value used to construct 32-bit data words */
-	u32 w;
-
-	printk(KERN_DEBUG "bar_tests(), PAGE_SIZE = 0x%0x\n", (int)PAGE_SIZE);
-	printk(KERN_DEBUG "write_header = 0x%p.\n", write_header);
-	printk(KERN_DEBUG "read_header = 0x%p.\n", read_header);
-	printk(KERN_DEBUG "&write_header->w3 = 0x%p\n", &write_header->w3);
-	printk(KERN_DEBUG "&read_header->w3 = 0x%p\n", &read_header->w3);
-	printk(KERN_DEBUG "ape->table_virt = 0x%p.\n", ape->table_virt);
-
-	if (!write_header || !read_header || !ape->table_virt)
-		goto fail;
-
-	/* allocate and map coherently-cached memory for a DMA-able buffer */
-	/* @see Documentation/PCI/PCI-DMA-mapping.txt, near line 318 */
-	buffer_virt = (u8 *)pci_alloc_consistent(dev, PAGE_SIZE * 4, &buffer_bus);
-	if (!buffer_virt) {
-		printk(KERN_DEBUG "Could not allocate coherent DMA buffer.\n");
-		goto fail;
-	}
-	printk(KERN_DEBUG "Allocated cache-coherent DMA buffer (virtual address = %p, bus address = 0x%016llx).\n",
-	       buffer_virt, (u64)buffer_bus);
-
-	/* fill first half of buffer with its virtual address as data */
-	for (i = 0; i < 4 * PAGE_SIZE; i += 4)
-#if 0
-		*(u32 *)(buffer_virt + i) = i / PAGE_SIZE + 1;
-#else
-		*(u32 *)(buffer_virt + i) = (u32)(unsigned long)(buffer_virt + i);
-#endif
-#if 0
-  compare((u32 *)buffer_virt, (u32 *)(buffer_virt + 2 * PAGE_SIZE), 8192);
-#endif
-
-#if 0
-	/* fill second half of buffer with zeroes */
-	for (i = 2 * PAGE_SIZE; i < 4 * PAGE_SIZE; i += 4)
-		*(u32 *)(buffer_virt + i) = 0;
-#endif
-
-	/* invalidate EPLAST, outside 0-255, 0xFADE is from the testbench */
-	ape->table_virt->w3 = cpu_to_le32(0x0000FADE);
-
-	/* fill in first descriptor */
-	n = 0;
-	/* read 8192 bytes from RC buffer to EP address 4096 */
-	ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus, 4096, 2 * PAGE_SIZE);
-#if 1
-	for (i = 0; i < 255; i++)
-		ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus, 4096, 2 * PAGE_SIZE);
-	/* index of last descriptor */
-	n = i - 1;
-#endif
-#if 0
-	/* fill in next descriptor */
-	n++;
-	/* read 1024 bytes from RC buffer to EP address 4096 + 1024 */
-	ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus + 1024, 4096 + 1024, 1024);
-#endif
-
-#if 1
-	/* enable MSI after the last descriptor is completed */
-	if (ape->msi_enabled)
-		ape->table_virt->desc[n].w0 |= cpu_to_le32(1UL << 16)/*local MSI*/;
-#endif
-#if 0
-	/* dump descriptor table for debugging */
-	printk(KERN_DEBUG "Descriptor Table (Read, in Root Complex Memory, # = %d)\n", n + 1);
-	for (i = 0; i < 4 + (n + 1) * 4; i += 4) {
-		u32 *p = (u32 *)ape->table_virt;
-		p += i;
-		printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (LEN=0x%x)\n", (u32)p, (u32)p & 15, *p, 4 * le32_to_cpu(*p));
-		p++;
-		printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (EPA=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
-		p++;
-		printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCH=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
-		p++;
-		printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCL=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
-	}
-#endif
-	/* set available number of descriptors in table */
-	w = (u32)(n + 1);
-	w |= (1UL << 18)/*global EPLAST_EN*/;
-#if 0
-	if (ape->msi_enabled)
-		w |= (1UL << 17)/*global MSI*/;
-#endif
-	printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", w, (void *)&read_header->w0);
-	iowrite32(w, &read_header->w0);
-
-	/* write table address (higher 32-bits) */
-	printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", (u32)((ape->table_bus >> 16) >> 16), (void *)&read_header->bdt_addr_h);
-	iowrite32(pci_dma_h(ape->table_bus), &read_header->bdt_addr_h);
-
-	/* write table address (lower 32-bits) */
-	printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", (u32)(ape->table_bus & 0xffffffffUL), (void *)&read_header->bdt_addr_l);
-	iowrite32(pci_dma_l(ape->table_bus), &read_header->bdt_addr_l);
-
-	/* memory write barrier */
-	wmb();
-	printk(KERN_DEBUG "Flush posted writes\n");
-	/** FIXME Add dummy read to flush posted writes but need a readable location! */
-#if 0
-	(void)ioread32();
-#endif
-
-	/* remember IRQ count before the transfer */
-	irq_count = ape->irq_count;
-	/* write number of descriptors - this starts the DMA */
-	printk(KERN_DEBUG "\nStart DMA read\n");
-	printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", (u32)n, (void *)&read_header->w3);
-	iowrite32(n, &read_header->w3);
-	printk(KERN_DEBUG "EPLAST = %lu\n", le32_to_cpu(*(u32 *)&ape->table_virt->w3) & 0xffffUL);
-
-	/** memory write barrier */
-	wmb();
-	/* dummy read to flush posted writes */
-	/* FIXME Need a readable location! */
-#if 0
-	(void)ioread32();
-#endif
-	printk(KERN_DEBUG "POLL FOR READ:\n");
-	/* poll for chain completion, 1000 times 1 millisecond */
-	for (i = 0; i < 100; i++) {
-		volatile u32 *p = &ape->table_virt->w3;
-		u32 eplast = le32_to_cpu(*p) & 0xffffUL;
-		printk(KERN_DEBUG "EPLAST = %u, n = %d\n", eplast, n);
-		if (eplast == n) {
-			printk(KERN_DEBUG "DONE\n");
-			/* print IRQ count before the transfer */
-			printk(KERN_DEBUG "#IRQs during transfer: %d\n", ape->irq_count - irq_count);
-			break;
-		}
-		udelay(100);
-	}
-
-	/* invalidate EPLAST, outside 0-255, 0xFADE is from the testbench */
-	ape->table_virt->w3 = cpu_to_le32(0x0000FADE);
-
-	/* setup first descriptor */
-	n = 0;
-	ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus + 8192, 4096, 2 * PAGE_SIZE);
-#if 1
-	for (i = 0; i < 255; i++)
-		ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus + 8192, 4096, 2 * PAGE_SIZE);
-
-	/* index of last descriptor */
-	n = i - 1;
-#endif
-#if 1 /* test variable, make a module option later */
-	if (ape->msi_enabled)
-		ape->table_virt->desc[n].w0 |= cpu_to_le32(1UL << 16)/*local MSI*/;
-#endif
-#if 0
-	/* dump descriptor table for debugging */
-	printk(KERN_DEBUG "Descriptor Table (Write, in Root Complex Memory, # = %d)\n", n + 1);
-	for (i = 0; i < 4 + (n + 1) * 4; i += 4) {
-		u32 *p = (u32 *)ape->table_virt;
-		p += i;
-		printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (LEN=0x%x)\n", (u32)p, (u32)p & 15, *p, 4 * le32_to_cpu(*p));
-		p++;
-		printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (EPA=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
-		p++;
-		printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCH=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
-		p++;
-		printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCL=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
-	}
-#endif
-
-	/* set number of available descriptors in the table */
-	w = (u32)(n + 1);
-	/* enable updates of eplast for each descriptor completion */
-	w |= (u32)(1UL << 18)/*global EPLAST_EN*/;
-#if 0   /* test variable, make a module option later */
-	/* enable MSI for each descriptor completion */
-	if (ape->msi_enabled)
-		w |= (1UL << 17)/*global MSI*/;
-#endif
-	iowrite32(w, &write_header->w0);
-	iowrite32(pci_dma_h(ape->table_bus), &write_header->bdt_addr_h);
-	iowrite32(pci_dma_l(ape->table_bus), &write_header->bdt_addr_l);
-
-	/** memory write barrier and flush posted writes */
-	wmb();
-	/* dummy read to flush posted writes */
-	/* FIXME Need a readable location! */
-#if 0
-	(void)ioread32();
-#endif
-	irq_count = ape->irq_count;
-
-	printk(KERN_DEBUG "\nStart DMA write\n");
-	iowrite32(n, &write_header->w3);
-
-	/** memory write barrier */
-	wmb();
-	/** dummy read to flush posted writes */
-	/* (void) ioread32(); */
-
-	printk(KERN_DEBUG "POLL FOR WRITE:\n");
-	/* poll for completion, 1000 times 1 millisecond */
-	for (i = 0; i < 100; i++) {
-		volatile u32 *p = &ape->table_virt->w3;
-		u32 eplast = le32_to_cpu(*p) & 0xffffUL;
-		printk(KERN_DEBUG "EPLAST = %u, n = %d\n", eplast, n);
-		if (eplast == n) {
-			printk(KERN_DEBUG "DONE\n");
-			/* print IRQ count before the transfer */
-			printk(KERN_DEBUG "#IRQs during transfer: %d\n", ape->irq_count - irq_count);
-			break;
-		}
-		udelay(100);
-	}
-	/* soft-reset DMA write engine */
-	iowrite32(0x0000ffffUL, &write_header->w0);
-	/* soft-reset DMA read engine */
-	iowrite32(0x0000ffffUL, &read_header->w0);
-
-	/** memory write barrier */
-	wmb();
-	/* dummy read to flush posted writes */
-	/* FIXME Need a readable location! */
-#if 0
-	(void)ioread32();
-#endif
-	/* compare first half of buffer with second half, should be identical */
-	result = compare((u32 *)buffer_virt, (u32 *)(buffer_virt + 2 * PAGE_SIZE), 8192);
-	printk(KERN_DEBUG "DMA loop back test %s.\n", result ? "FAILED" : "PASSED");
-
-	pci_free_consistent(dev, 4 * PAGE_SIZE, buffer_virt, buffer_bus);
-fail:
-	printk(KERN_DEBUG "bar_tests() end, result %d\n", result);
-	return result;
-}
-
-/* Called when the PCI sub system thinks we can control the given device.
- * Inspect if we can support the device and if so take control of it.
- *
- * Return 0 when we have taken control of the given device.
- *
- * - allocate board specific bookkeeping
- * - allocate coherently-mapped memory for the descriptor table
- * - enable the board
- * - verify board revision
- * - request regions
- * - query DMA mask
- * - obtain and request irq
- * - map regions into kernel address space
- */
-static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
-	int rc = 0;
-	struct ape_dev *ape = NULL;
-	u8 irq_pin, irq_line;
-	printk(KERN_DEBUG "probe(dev = 0x%p, pciid = 0x%p)\n", dev, id);
-
-	/* allocate memory for per-board book keeping */
-	ape = kzalloc(sizeof(struct ape_dev), GFP_KERNEL);
-	if (!ape) {
-		printk(KERN_DEBUG "Could not kzalloc()ate memory.\n");
-		goto err_ape;
-	}
-	ape->pci_dev = dev;
-	dev_set_drvdata(&dev->dev, ape);
-	printk(KERN_DEBUG "probe() ape = 0x%p\n", ape);
-
-	printk(KERN_DEBUG "sizeof(struct ape_chdma_table) = %d.\n",
-		(int)sizeof(struct ape_chdma_table));
-	/* the reference design has a size restriction on the table size */
-	BUG_ON(sizeof(struct ape_chdma_table) > APE_CHDMA_TABLE_SIZE);
-
-	/* allocate and map coherently-cached memory for a descriptor table */
-	/* @see LDD3 page 446 */
-	ape->table_virt = (struct ape_chdma_table *)pci_alloc_consistent(dev,
-		APE_CHDMA_TABLE_SIZE, &ape->table_bus);
-	/* could not allocate table? */
-	if (!ape->table_virt) {
-		printk(KERN_DEBUG "Could not dma_alloc()ate_coherent memory.\n");
-		goto err_table;
-	}
-
-	printk(KERN_DEBUG "table_virt = %p, table_bus = 0x%16llx.\n",
-		ape->table_virt, (u64)ape->table_bus);
-
-	/* enable device */
-	rc = pci_enable_device(dev);
-	if (rc) {
-		printk(KERN_DEBUG "pci_enable_device() failed\n");
-		goto err_enable;
-	}
-
-	/* enable bus master capability on device */
-	pci_set_master(dev);
-	/* enable message signaled interrupts */
-	rc = pci_enable_msi(dev);
-	/* could not use MSI? */
-	if (rc) {
-		/* resort to legacy interrupts */
-		printk(KERN_DEBUG "Could not enable MSI interrupting.\n");
-		ape->msi_enabled = 0;
-	/* MSI enabled, remember for cleanup */
-	} else {
-		printk(KERN_DEBUG "Enabled MSI interrupting.\n");
-		ape->msi_enabled = 1;
-	}
-
-	pci_read_config_byte(dev, PCI_REVISION_ID, &ape->revision);
-#if 0 /* example */
-	/* (for example) this driver does not support revision 0x42 */
-    if (ape->revision == 0x42) {
-		printk(KERN_DEBUG "Revision 0x42 is not supported by this driver.\n");
-		rc = -ENODEV;
-		goto err_rev;
-	}
-#endif
-	/** XXX check for native or legacy PCIe endpoint? */
-
-	rc = pci_request_regions(dev, DRV_NAME);
-	/* could not request all regions? */
-	if (rc) {
-		/* assume device is in use (and do not disable it later!) */
-		ape->in_use = 1;
-		goto err_regions;
-	}
-	ape->got_regions = 1;
-
-#if 1   /* @todo For now, disable 64-bit, because I do not understand the implications (DAC!) */
-	/* query for DMA transfer */
-	/* @see Documentation/PCI/PCI-DMA-mapping.txt */
-	if (!pci_set_dma_mask(dev, DMA_BIT_MASK(64))) {
-		pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(64));
-		/* use 64-bit DMA */
-		printk(KERN_DEBUG "Using a 64-bit DMA mask.\n");
-	} else
-#endif
-	if (!pci_set_dma_mask(dev, DMA_BIT_MASK(32))) {
-		printk(KERN_DEBUG "Could not set 64-bit DMA mask.\n");
-		pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(32));
-		/* use 32-bit DMA */
-		printk(KERN_DEBUG "Using a 32-bit DMA mask.\n");
-	} else {
-		printk(KERN_DEBUG "No suitable DMA possible.\n");
-		/** @todo Choose proper error return code */
-		rc = -1;
-		goto err_mask;
-	}
-
-	rc = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
-	/* could not read? */
-	if (rc)
-		goto err_irq;
-	printk(KERN_DEBUG "IRQ pin #%d (0=none, 1=INTA#...4=INTD#).\n", irq_pin);
-
-	/* @see LDD3, page 318 */
-	rc = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq_line);
-	/* could not read? */
-	if (rc) {
-		printk(KERN_DEBUG "Could not query PCI_INTERRUPT_LINE, error %d\n", rc);
-		goto err_irq;
-	}
-	printk(KERN_DEBUG "IRQ line #%d.\n", irq_line);
-#if 1
-	irq_line = dev->irq;
-	/* @see LDD3, page 259 */
-	rc = request_irq(irq_line, altpciechdma_isr, IRQF_SHARED, DRV_NAME, (void *)ape);
-	if (rc) {
-		printk(KERN_DEBUG "Could not request IRQ #%d, error %d\n", irq_line, rc);
-		ape->irq_line = -1;
-		goto err_irq;
-	}
-	/* remember which irq we allocated */
-	ape->irq_line = (int)irq_line;
-	printk(KERN_DEBUG "Succesfully requested IRQ #%d with dev_id 0x%p\n", irq_line, ape);
-#endif
-	/* show BARs */
-	scan_bars(ape, dev);
-	/* map BARs */
-	rc = map_bars(ape, dev);
-	if (rc)
-		goto err_map;
-#if ALTPCIECHDMA_CDEV
-	/* initialize character device */
-	rc = sg_init(ape);
-	if (rc)
-		goto err_cdev;
-#endif
-	/* perform DMA engines loop back test */
-	rc = dma_test(ape, dev);
-	(void)rc;
-	/* successfully took the device */
-	rc = 0;
-	printk(KERN_DEBUG "probe() successful.\n");
-	goto end;
-#if ALTPCIECHDMA_CDEV
-err_cdev:
-	/* unmap the BARs */
-	unmap_bars(ape, dev);
-#endif
-err_map:
-	/* free allocated irq */
-	if (ape->irq_line >= 0)
-		free_irq(ape->irq_line, (void *)ape);
-err_irq:
-	if (ape->msi_enabled)
-		pci_disable_msi(dev);
-	/* disable the device iff it is not in use */
-	if (!ape->in_use)
-		pci_disable_device(dev);
-	if (ape->got_regions)
-		pci_release_regions(dev);
-err_mask:
-err_regions:
-/*err_rev:*/
-/* clean up everything before device enable() */
-err_enable:
-	if (ape->table_virt)
-		pci_free_consistent(dev, APE_CHDMA_TABLE_SIZE, ape->table_virt, ape->table_bus);
-/* clean up everything before allocating descriptor table */
-err_table:
-	if (ape)
-		kfree(ape);
-err_ape:
-end:
-	return rc;
-}
-
-static void __devexit remove(struct pci_dev *dev)
-{
-	struct ape_dev *ape = dev_get_drvdata(&dev->dev);
-
-	printk(KERN_DEBUG "remove(0x%p)\n", dev);
-	printk(KERN_DEBUG "remove(dev = 0x%p) where ape = 0x%p\n", dev, ape);
-
-	/* remove character device */
-#if ALTPCIECHDMA_CDEV
-	sg_exit(ape);
-#endif
-
-	if (ape->table_virt)
-		pci_free_consistent(dev, APE_CHDMA_TABLE_SIZE, ape->table_virt, ape->table_bus);
-
-	/* free IRQ
-	 * @see LDD3 page 279
-	 */
-	if (ape->irq_line >= 0) {
-		printk(KERN_DEBUG "Freeing IRQ #%d for dev_id 0x%08lx.\n",
-		ape->irq_line, (unsigned long)ape);
-		free_irq(ape->irq_line, (void *)ape);
-	}
-	/* MSI was enabled? */
-	if (ape->msi_enabled) {
-		/* Disable MSI @see Documentation/MSI-HOWTO.txt */
-		pci_disable_msi(dev);
-		ape->msi_enabled = 0;
-	}
-	/* unmap the BARs */
-	unmap_bars(ape, dev);
-	if (!ape->in_use)
-		pci_disable_device(dev);
-	if (ape->got_regions)
-		/* to be called after device disable */
-		pci_release_regions(dev);
-}
-
-#if ALTPCIECHDMA_CDEV
-
-/*
- * Called when the device goes from unused to used.
- */
-static int sg_open(struct inode *inode, struct file *file)
-{
-	struct ape_dev *ape;
-	printk(KERN_DEBUG DRV_NAME "_open()\n");
-	/* pointer to containing data structure of the character device inode */
-	ape = container_of(inode->i_cdev, struct ape_dev, cdev);
-	/* create a reference to our device state in the opened file */
-	file->private_data = ape;
-	/* create virtual memory mapper */
-	ape->sgm = sg_create_mapper(MAX_CHDMA_SIZE);
-	return 0;
-}
-
-/*
- * Called when the device goes from used to unused.
- */
-static int sg_close(struct inode *inode, struct file *file)
-{
-	/* fetch device specific data stored earlier during open */
-	struct ape_dev *ape = (struct ape_dev *)file->private_data;
-	printk(KERN_DEBUG DRV_NAME "_close()\n");
-	/* destroy virtual memory mapper */
-	sg_destroy_mapper(ape->sgm);
-	return 0;
-}
-
-static ssize_t sg_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
-{
-	/* fetch device specific data stored earlier during open */
-	struct ape_dev *ape = (struct ape_dev *)file->private_data;
-	(void)ape;
-	printk(KERN_DEBUG DRV_NAME "_read(buf=0x%p, count=%lld, pos=%llu)\n", buf, (s64)count, (u64)*pos);
-	return count;
-}
-
-/* sg_write() - Write to the device
- *
- * @buf userspace buffer
- * @count number of bytes in the userspace buffer
- *
- * Iterate over the userspace buffer, taking at most 255 * PAGE_SIZE bytes for
- * each DMA transfer.
- *   For each transfer, get the user pages, build a sglist, map, build a
- *   descriptor table. submit the transfer. wait for the interrupt handler
- *   to wake us on completion.
- */
-static ssize_t sg_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
-{
-	int hwnents, tents;
-	size_t transfer_len, remaining = count, done = 0;
-	u64 transfer_addr = (u64)buf;
-	/* fetch device specific data stored earlier during open */
-	struct ape_dev *ape = (struct ape_dev *)file->private_data;
-	printk(KERN_DEBUG DRV_NAME "_write(buf=0x%p, count=%lld, pos=%llu)\n",
-		buf, (s64)count, (u64)*pos);
-	/* TODO transfer boundaries at PAGE_SIZE granularity */
-	while (remaining > 0) {
-		/* limit DMA transfer size */
-		transfer_len = (remaining < APE_CHDMA_MAX_TRANSFER_LEN) ? remaining :
-			APE_CHDMA_MAX_TRANSFER_LEN;
-		/* get all user space buffer pages and create a scattergather list */
-		sgm_map_user_pages(ape->sgm, transfer_addr, transfer_len, 0/*read from userspace*/);
-		printk(KERN_DEBUG DRV_NAME "mapped_pages=%d\n", ape->sgm->mapped_pages);
-		/* map all entries in the scattergather list */
-		hwnents = pci_map_sg(ape->pci_dev, ape->sgm->sgl, ape->sgm->mapped_pages, DMA_TO_DEVICE);
-		printk(KERN_DEBUG DRV_NAME "hwnents=%d\n", hwnents);
-		/* build device descriptor tables and submit them to the DMA engine */
-		tents = ape_sg_to_chdma_table(ape->sgm->sgl, hwnents, 0, &ape->table_virt->desc[0], 4096);
-		printk(KERN_DEBUG DRV_NAME "tents=%d\n", hwnents);
-#if 0
-		while (tables) {
-			/* TODO build table */
-			/* TODO submit table to the device */
-			/* if engine stopped and unfinished work then start engine */
-		}
-		put ourselves on wait queue
-#endif
-
-		dma_unmap_sg(NULL, ape->sgm->sgl, ape->sgm->mapped_pages, DMA_TO_DEVICE);
-		/* dirty and free the pages */
-		sgm_unmap_user_pages(ape->sgm, 1/*dirtied*/);
-		/* book keeping */
-		transfer_addr += transfer_len;
-		remaining -= transfer_len;
-		done += transfer_len;
-	}
-	return done;
-}
-
-/*
- * character device file operations
- */
-static const struct file_operations sg_fops = {
-	.owner = THIS_MODULE,
-	.open = sg_open,
-	.release = sg_close,
-	.read = sg_read,
-	.write = sg_write,
-};
-
-/* sg_init() - Initialize character device
- *
- * XXX Should ideally be tied to the device, on device probe, not module init.
- */
-static int sg_init(struct ape_dev *ape)
-{
-	int rc;
-	printk(KERN_DEBUG DRV_NAME " sg_init()\n");
-	/* allocate a dynamically allocated character device node */
-	rc = alloc_chrdev_region(&ape->cdevno, 0/*requested minor*/, 1/*count*/, DRV_NAME);
-	/* allocation failed? */
-	if (rc < 0) {
-		printk("alloc_chrdev_region() = %d\n", rc);
-		goto fail_alloc;
-	}
-	/* couple the device file operations to the character device */
-	cdev_init(&ape->cdev, &sg_fops);
-	ape->cdev.owner = THIS_MODULE;
-	/* bring character device live */
-	rc = cdev_add(&ape->cdev, ape->cdevno, 1/*count*/);
-	if (rc < 0) {
-		printk("cdev_add() = %d\n", rc);
-		goto fail_add;
-	}
-	printk(KERN_DEBUG "altpciechdma = %d:%d\n", MAJOR(ape->cdevno), MINOR(ape->cdevno));
-	return 0;
-fail_add:
-	/* free the dynamically allocated character device node */
-    unregister_chrdev_region(ape->cdevno, 1/*count*/);
-fail_alloc:
-	return -1;
-}
-
-/* sg_exit() - Cleanup character device
- *
- * XXX Should ideally be tied to the device, on device remove, not module exit.
- */
-
-static void sg_exit(struct ape_dev *ape)
-{
-	printk(KERN_DEBUG DRV_NAME " sg_exit()\n");
-	/* remove the character device */
-	cdev_del(&ape->cdev);
-	/* free the dynamically allocated character device node */
-	unregister_chrdev_region(ape->cdevno, 1/*count*/);
-}
-
-#endif /* ALTPCIECHDMA_CDEV */
-
-/* used to register the driver with the PCI kernel sub system
- * @see LDD3 page 311
- */
-static struct pci_driver pci_driver = {
-	.name = DRV_NAME,
-	.id_table = ids,
-	.probe = probe,
-	.remove = __devexit_p(remove),
-	/* resume, suspend are optional */
-};
-
-/**
- * alterapciechdma_init() - Module initialization, registers devices.
- */
-static int __init alterapciechdma_init(void)
-{
-	int rc = 0;
-	printk(KERN_DEBUG DRV_NAME " init(), built at " __DATE__ " " __TIME__ "\n");
-	/* register this driver with the PCI bus driver */
-	rc = pci_register_driver(&pci_driver);
-	if (rc < 0)
-		return rc;
-	return 0;
-}
-
-/**
- * alterapciechdma_init() - Module cleanup, unregisters devices.
- */
-static void __exit alterapciechdma_exit(void)
-{
-	printk(KERN_DEBUG DRV_NAME " exit(), built at " __DATE__ " " __TIME__ "\n");
-	/* unregister this driver from the PCI bus driver */
-	pci_unregister_driver(&pci_driver);
-}
-
-MODULE_LICENSE("GPL");
-
-module_init(alterapciechdma_init);
-module_exit(alterapciechdma_exit);
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/altpciechdma/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/altpciechdma/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/altpciechdma/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/altpciechdma/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,10 +0,0 @@
-config ALTERA_PCIE_CHDMA
-	tristate "Altera PCI Express Chaining DMA driver"
-	depends on PCI
-	default N
-	---help---
-	  A reference driver that exercises the Chaining DMA logic reference
-	  design generated along the Altera FPGA PCI Express soft or hard core,
-	  only if instantiated using the MegaWizard, not the SOPC builder, of
-	  Quartus 8.1.
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/altpciechdma/Makefile linux-libre-2.6.34-gnu1/drivers/staging/altpciechdma/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/altpciechdma/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/altpciechdma/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,2 +0,0 @@
-obj-$(CONFIG_ALTERA_PCIE_CHDMA)	+= altpciechdma.o
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/altpciechdma/TODO linux-libre-2.6.34-gnu1/drivers/staging/altpciechdma/TODO
--- linux-libre-2.6.33-gnu1/drivers/staging/altpciechdma/TODO	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/altpciechdma/TODO	1969-12-31 19:00:00.000000000 -0500
@@ -1,15 +0,0 @@
-DONE:
-    - functionality similar to logic testbench
-
-TODO:
-	- checkpatch.pl cleanups.
-	- keep state of DMA engines.
-	- keep data structure that keeps state of each transfer.
-	- interrupt handler should iterate over outstanding descriptor tables.
-	- complete userspace cdev to read/write using the DMA engines.
-	- split off the DMA support functions in a module, re-usable by custom
-	  drivers.
-
-Please coordinate work with, and send patches to
-Leon Woestenberg <leon@sidebranch.com>
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/arlan/arlan.h linux-libre-2.6.34-gnu1/drivers/staging/arlan/arlan.h
--- linux-libre-2.6.33-gnu1/drivers/staging/arlan/arlan.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/arlan/arlan.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1997 Cullen Jennings
- *  Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500	
+ *  Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500
  *  GNU General Public License applies
  */
 
@@ -20,14 +20,14 @@
 #include <linux/init.h>
 #include <linux/bitops.h>
 #include <asm/system.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 
 
-//#define ARLAN_DEBUGGING 1
+/* #define ARLAN_DEBUGGING 1 */
 
 #define ARLAN_PROC_INTERFACE
 #define MAX_ARLANS 4 /* not more than 4 ! */
@@ -51,8 +51,8 @@ extern int	arlan_debug;
 extern int	arlan_entry_debug;
 extern int	arlan_exit_debug;
 extern int	testMemory;
-extern int     arlan_command(struct net_device * dev, int command);
- 
+extern int     arlan_command(struct net_device *dev, int command);
+
 #define SIDUNKNOWN -1
 #define radioNodeIdUNKNOWN -1
 #define irqUNKNOWN 0
@@ -65,22 +65,21 @@ extern int     arlan_command(struct net_
 #define registrationModeUNKNOWN -1
 
 
-#define IFDEBUG( L ) if ( (L) & arlan_debug ) 
-#define ARLAN_FAKE_HDR_LEN 12 
+#define IFDEBUG(L) if ((L) & arlan_debug)
+#define ARLAN_FAKE_HDR_LEN 12
 
 #ifdef ARLAN_DEBUGGING
 	#define DEBUG 1
 	#define ARLAN_ENTRY_EXIT_DEBUGGING 1
-	#define ARLAN_DEBUG(a,b) printk(KERN_DEBUG a, b)
+	#define ARLAN_DEBUG(a, b) printk(KERN_DEBUG a, b)
 #else
-	#define ARLAN_DEBUG(a,b) 
+	#define ARLAN_DEBUG(a, b)
 #endif
 
 #define ARLAN_SHMEM_SIZE	0x2000
 
-struct arlan_shmem
-{
-      /* Header Signature */ 
+struct arlan_shmem {
+      /* Header Signature */
       volatile	char textRegion[48];
       volatile	u_char resetFlag;
       volatile	u_char  diagnosticInfo;
@@ -91,10 +90,10 @@ struct arlan_shmem
       volatile	u_char hardwareType;
       volatile	u_char majorHardwareVersion;
       volatile	u_char minorHardwareVersion;
-      volatile	u_char radioModule;// shows EEPROM, can be overridden at 0x111
-      volatile	u_char defaultChannelSet; // shows EEProm, can be overriiden at 0x10A
+      volatile	u_char radioModule;/* shows EEPROM, can be overridden at 0x111 */
+      volatile	u_char defaultChannelSet; /* shows EEProm, can be overriiden at 0x10A */
       volatile	u_char _2[47];
-      
+
       /* Control/Status Block - 0x0080 */
       volatile	u_char interruptInProgress; /* not used by lancpu */
       volatile	u_char cntrlRegImage; /* not used by lancpu */
@@ -113,7 +112,7 @@ struct arlan_shmem
       volatile	u_char rxQuality;
       volatile	u_char scrambled;
       volatile	u_char _4[1];
-      
+
       /* Transmit Status - 0x00b0 */
       volatile	u_char txStatus;
       volatile	u_char txAckQuality;
@@ -151,7 +150,7 @@ struct arlan_shmem
       volatile	u_short routerId;
       volatile	u_char _10[9];
       volatile	u_char txAttenuation;
-      volatile	u_char systemId[4]; 
+      volatile	u_char systemId[4];
       volatile	u_short globalChecksum;
       volatile	u_char _11[4];
       volatile	u_short maxDatagramSize;
@@ -207,19 +206,19 @@ struct arlan_shmem
       volatile	u_char hostcpuLock;
       volatile	u_char lancpuLock;
       volatile	u_char resetTime[18];
-      
+
       volatile	u_char numDatagramsTransmitted[4];
       volatile	u_char numReTransmissions[4];
       volatile	u_char numFramesDiscarded[4];
       volatile	u_char numDatagramsReceived[4];
       volatile	u_char numDuplicateReceivedFrames[4];
       volatile	u_char numDatagramsDiscarded[4];
-      
+
       volatile	u_short maxNumReTransmitDatagram;
       volatile	u_short maxNumReTransmitFrames;
       volatile	u_short maxNumConsecutiveDuplicateFrames;
       /* misaligned here so we have to go to characters */
-     
+
       volatile	u_char numBytesTransmitted[4];
       volatile	u_char numBytesReceived[4];
       volatile	u_char numCRCErrors[4];
@@ -259,7 +258,7 @@ struct arlan_conf_stru {
       int channelNumber;
       int scramblingDisable;
       int txAttenuation;
-      int systemId; 
+      int systemId;
       int maxDatagramSize;
       int maxFrameSize;
       int maxRetries;
@@ -316,8 +315,7 @@ struct arlan_conf_stru {
 
 extern struct arlan_conf_stru arlan_conf[MAX_ARLANS];
 
-struct TxParam
-{
+struct TxParam {
       volatile	short 		offset;
       volatile 	short 		length;
       volatile	u_char 		dest[6];
@@ -330,12 +328,12 @@ struct TxParam
 #define TX_RING_SIZE 2
 /* Information that need to be kept for each board. */
 struct arlan_private {
-      struct arlan_shmem __iomem * card;
-      struct arlan_shmem * conf;
+      struct arlan_shmem __iomem *card;
+      struct arlan_shmem *conf;
 
-      struct arlan_conf_stru * Conf;	     
+      struct arlan_conf_stru *Conf;
       int	bad;
-      int 	reset;
+      int	reset;
       unsigned long lastReset;
       struct timer_list timer;
       struct timer_list tx_delay_timer;
@@ -407,38 +405,38 @@ struct arlan_private {
 
 #define TXBuffStart(dev) offsetof(struct arlan_shmem, txBuffer)
 #define TXBuffEnd(dev) offsetof(struct arlan_shmem, xxBuffer)
- 
-#define READSHM(to,from,atype) {\
+
+#define READSHM(to, from, atype) {\
 	atype tmp;\
-	memcpy_fromio(&(tmp),&(from),sizeof(atype));\
+	memcpy_fromio(&(tmp), &(from), sizeof(atype));\
 	to = tmp;\
 	}
 
-#define READSHMEM(from,atype)\
+#define READSHMEM(from, atype)\
 	atype from; \
 	READSHM(from, arlan->from, atype);
 
-#define WRITESHM(to,from,atype) \
+#define WRITESHM(to, from, atype) \
 	{ atype tmpSHM = from;\
-	memcpy_toio(&(to),&tmpSHM,sizeof(atype));\
+	memcpy_toio(&(to), &tmpSHM, sizeof(atype));\
 	}
 
-#define DEBUGSHM(levelSHM,stringSHM,stuff,atype) \
+#define DEBUGSHM(levelSHM, stringSHM, stuff, atype) \
 	{	atype tmpSHM; \
-		memcpy_fromio(&tmpSHM,&(stuff),sizeof(atype));\
-		IFDEBUG(levelSHM) printk(stringSHM,tmpSHM);\
+		memcpy_fromio(&tmpSHM, &(stuff), sizeof(atype));\
+		IFDEBUG(levelSHM) printk(stringSHM, tmpSHM);\
 	}
 
 #define WRITESHMB(to, val) \
-	writeb(val,&(to))
+	writeb(val, &(to))
 #define READSHMB(to) \
 	readb(&(to))
 #define WRITESHMS(to, val) \
-	writew(val,&(to))
+	writew(val, &(to))
 #define READSHMS(to) \
 	readw(&(to))
 #define WRITESHMI(to, val) \
-	writel(val,&(to))
+	writel(val, &(to))
 #define READSHMI(to) \
 	readl(&(to))
 
@@ -447,51 +445,51 @@ struct arlan_private {
 
 
 #define registrationBad(dev)\
-   ( (   READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode)    > 0) && \
-     (   READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0)    )
+    ((   READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode)    > 0) && \
+     (   READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0))
 
 
 #define readControlRegister(dev)\
- 	READSHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage)
+	READSHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage)
 
-#define writeControlRegister(dev, v){\
-   WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage	,((v) &0xF) );\
-   WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister	,(v) 	);}
+#define writeControlRegister(dev, v) {\
+   WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage, ((v) & 0xF));\
+   WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister, (v)); }
 
 
 #define arlan_interrupt_lancpu(dev) {\
    int cr;   \
    \
    cr = readControlRegister(dev);\
-   if (cr & ARLAN_CHANNEL_ATTENTION){ \
+   if (cr & ARLAN_CHANNEL_ATTENTION) { \
       writeControlRegister(dev, (cr & ~ARLAN_CHANNEL_ATTENTION));\
-   }else  \
+   } else  \
       writeControlRegister(dev, (cr | ARLAN_CHANNEL_ATTENTION));\
 }
 
-#define clearChannelAttention(dev){ \
-   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION);}
+#define clearChannelAttention(dev) { \
+   writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION); }
 #define setHardwareReset(dev) {\
-   writeControlRegister(dev,readControlRegister(dev) | ARLAN_RESET);}
+   writeControlRegister(dev, readControlRegister(dev) | ARLAN_RESET); }
 #define clearHardwareReset(dev) {\
-   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_RESET);}
-#define setInterruptEnable(dev){\
-   writeControlRegister(dev,readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE)  ;}
-#define clearInterruptEnable(dev){\
-   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE)  ;}
-#define setClearInterrupt(dev){\
-   writeControlRegister(dev,readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT)   ;}
-#define clearClearInterrupt(dev){\
-   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT);}
-#define setPowerOff(dev){\
-   writeControlRegister(dev,readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\
-   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);}
-#define setPowerOn(dev){\
-   writeControlRegister(dev,readControlRegister(dev) & ~(ARLAN_POWER));   }
-#define arlan_lock_card_access(dev){\
-   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);}
-#define arlan_unlock_card_access(dev){\
-   writeControlRegister(dev,readControlRegister(dev) | ARLAN_ACCESS ); }  
+   writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_RESET); }
+#define setInterruptEnable(dev) {\
+   writeControlRegister(dev, readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE)  ; }
+#define clearInterruptEnable(dev) {\
+   writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE)  ; }
+#define setClearInterrupt(dev) {\
+   writeControlRegister(dev, readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT)   ; }
+#define clearClearInterrupt(dev) {\
+   writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT); }
+#define setPowerOff(dev) {\
+   writeControlRegister(dev, readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\
+   writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_ACCESS); }
+#define setPowerOn(dev) {\
+   writeControlRegister(dev, readControlRegister(dev) & ~(ARLAN_POWER)); }
+#define arlan_lock_card_access(dev) {\
+   writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_ACCESS); }
+#define arlan_unlock_card_access(dev) {\
+   writeControlRegister(dev, readControlRegister(dev) | ARLAN_ACCESS); }
 
 
 
@@ -525,7 +523,6 @@ struct arlan_private {
 					| ARLAN_COMMAND_RESET)
 
 
- 
 #define ARLAN_DEBUG_CHAIN_LOCKS		0x00001
 #define ARLAN_DEBUG_RESET		0x00002
 #define ARLAN_DEBUG_TIMING		0x00004
@@ -536,4 +533,3 @@ struct arlan_private {
 #define ARLAN_DEBUG_INTERRUPT		0x00080
 #define ARLAN_DEBUG_STARTUP		0x00100
 #define ARLAN_DEBUG_SHUTDOWN		0x00200
- 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/arlan/arlan-main.c linux-libre-2.6.34-gnu1/drivers/staging/arlan/arlan-main.c
--- linux-libre-2.6.33-gnu1/drivers/staging/arlan/arlan-main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/arlan/arlan-main.c	2010-05-16 17:17:36.000000000 -0400
@@ -1455,10 +1455,10 @@ static void arlan_rx_interrupt(struct ne
 #ifdef ARLAN_MULTICAST
 			if (!(dev->flags & IFF_ALLMULTI) &&
 				!(dev->flags & IFF_PROMISC) &&
-				dev->mc_list)
+				!netdev_mc_empty(dev))
 			{
 				char hw_dst_addr[6];
-				struct dev_mc_list *dmi = dev->mc_list;
+				struct dev_mc_list *dmi;
 				int i;
 
 				memcpy_fromio(hw_dst_addr, arlan->ultimateDestAddress, 6);
@@ -1469,20 +1469,15 @@ static void arlan_rx_interrupt(struct ne
 							printk(KERN_ERR "%s mcast 0x0100 \n", dev->name);
 						else if (hw_dst_addr[1] == 0x40)
 							printk(KERN_ERR "%s m/bcast 0x0140 \n", dev->name);
-					while (dmi)
-					{
-						if (dmi->dmi_addrlen == 6) {
-							if (arlan_debug & ARLAN_DEBUG_HEADER_DUMP)
-								printk(KERN_ERR "%s mcl %pM\n",
-								       dev->name, dmi->dmi_addr);
-							for (i = 0; i < 6; i++)
-								if (dmi->dmi_addr[i] != hw_dst_addr[i])
-									break;
-							if (i == 6)
+					netdev_for_each_mc_entry(dmi, dev) {
+						if (arlan_debug & ARLAN_DEBUG_HEADER_DUMP)
+							printk(KERN_ERR "%s mcl %pM\n",
+							       dev->name, dmi->dmi_addr);
+						for (i = 0; i < 6; i++)
+							if (dmi->dmi_addr[i] != hw_dst_addr[i])
 								break;
-						} else
-							printk(KERN_ERR "%s: invalid multicast address length given.\n", dev->name);
-						dmi = dmi->next;
+						if (i == 6)
+							break;
 					}
 					/* we reach here if multicast filtering is on and packet 
 					 * is multicast and not for receive */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/arlan/Makefile linux-libre-2.6.34-gnu1/drivers/staging/arlan/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/arlan/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/arlan/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,3 +1,3 @@
-obj-$(CONFIG_ARLAN) += arlan.o 
+obj-$(CONFIG_ARLAN) += arlan.o
 
 arlan-objs := arlan-main.o arlan-proc.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/asus_oled/asus_oled.c linux-libre-2.6.34-gnu1/drivers/staging/asus_oled/asus_oled.c
--- linux-libre-2.6.33-gnu1/drivers/staging/asus_oled/asus_oled.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/asus_oled/asus_oled.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,6 +52,10 @@
 #define ASUS_OLED_DISP_HEIGHT		32
 #define ASUS_OLED_PACKET_BUF_SIZE	256
 
+#define USB_VENDOR_ID_ASUS      0x0b05
+#define USB_DEVICE_ID_ASUS_LCM      0x1726
+#define USB_DEVICE_ID_ASUS_LCM2     0x175b
+
 MODULE_AUTHOR("Jakub Schmidtke, sjakub@gmail.com");
 MODULE_DESCRIPTION("Asus OLED Driver v" ASUS_OLED_VERSION);
 MODULE_LICENSE("GPL");
@@ -83,18 +87,20 @@ struct oled_dev_desc_str {
 };
 
 /* table of devices that work with this driver */
-static struct usb_device_id id_table[] = {
+static const struct usb_device_id id_table[] = {
 	/* Asus G1/G2 (and variants)*/
-	{ USB_DEVICE(0x0b05, 0x1726) },
+	{ USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM) },
 	/* Asus G50V (and possibly others - G70? G71?)*/
-	{ USB_DEVICE(0x0b05, 0x175b) },
+	{ USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2) },
 	{ },
 };
 
 /* parameters of specific devices */
 static struct oled_dev_desc_str oled_dev_desc_table[] = {
-	{ 0x0b05, 0x1726, 128, PACK_MODE_G1, "G1/G2" },
-	{ 0x0b05, 0x175b, 256, PACK_MODE_G50, "G50" },
+	{ USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, 128, PACK_MODE_G1,
+		"G1/G2" },
+	{ USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2, 256, PACK_MODE_G50,
+		"G50" },
 	{ },
 };
 
@@ -424,6 +430,11 @@ static ssize_t odev_set_picture(struct a
 
 		kfree(odev->buf);
 		odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
+		if (odev->buf == NULL) {
+			odev->buf_size = 0;
+			printk(ASUS_OLED_ERROR "Out of memory!\n");
+			return -ENOMEM;
+		}
 
 		memset(odev->buf, 0xff, odev->buf_size);
 
@@ -759,13 +770,8 @@ static struct usb_driver oled_driver = {
 	.id_table =	id_table,
 };
 
-static ssize_t version_show(struct class *dev, char *buf)
-{
-	return sprintf(buf, ASUS_OLED_UNDERSCORE_NAME " %s\n",
-		       ASUS_OLED_VERSION);
-}
-
-static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
+static CLASS_ATTR_STRING(version, S_IRUGO,
+		 	ASUS_OLED_UNDERSCORE_NAME " " ASUS_OLED_VERSION);
 
 static int __init asus_oled_init(void)
 {
@@ -777,7 +783,7 @@ static int __init asus_oled_init(void)
 		return PTR_ERR(oled_class);
 	}
 
-	retval = class_create_file(oled_class, &class_attr_version);
+	retval = class_create_file(oled_class, &class_attr_version.attr);
 	if (retval) {
 		err("Error creating class version file");
 		goto error;
@@ -799,7 +805,7 @@ error:
 
 static void __exit asus_oled_exit(void)
 {
-	class_remove_file(oled_class, &class_attr_version);
+	class_remove_file(oled_class, &class_attr_version.attr);
 	class_destroy(oled_class);
 
 	usb_deregister(&oled_driver);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/b3dfg/b3dfg.c linux-libre-2.6.34-gnu1/drivers/staging/b3dfg/b3dfg.c
--- linux-libre-2.6.33-gnu1/drivers/staging/b3dfg/b3dfg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/b3dfg/b3dfg.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1100 +0,0 @@
- /*
- * Brontes PCI frame grabber driver
- *
- * Copyright (C) 2008 3M Company
- * Contact: Justin Bronder <jsbronder@brontes3d.com>
- * Original Authors: Daniel Drake <ddrake@brontes3d.com>
- *                   Duane Griffin <duaneg@dghda.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You 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/device.h>
-#include <linux/fs.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/ioctl.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/types.h>
-#include <linux/cdev.h>
-#include <linux/list.h>
-#include <linux/poll.h>
-#include <linux/wait.h>
-#include <linux/mm.h>
-#include <linux/uaccess.h>
-#include <linux/sched.h>
-
-static unsigned int b3dfg_nbuf = 2;
-
-module_param_named(buffer_count, b3dfg_nbuf, uint, 0444);
-
-MODULE_PARM_DESC(buffer_count, "Number of buffers (min 2, default 2)");
-
-MODULE_AUTHOR("Daniel Drake <ddrake@brontes3d.com>");
-MODULE_DESCRIPTION("Brontes frame grabber driver");
-MODULE_LICENSE("GPL");
-
-#define DRIVER_NAME "b3dfg"
-#define B3DFG_MAX_DEVS 4
-#define B3DFG_FRAMES_PER_BUFFER 3
-
-#define B3DFG_BAR_REGS	0
-#define B3DFG_REGS_LENGTH 0x10000
-
-#define B3DFG_IOC_MAGIC		0xb3 /* dfg :-) */
-#define B3DFG_IOCGFRMSZ		_IOR(B3DFG_IOC_MAGIC, 1, int)
-#define B3DFG_IOCTNUMBUFS	_IO(B3DFG_IOC_MAGIC, 2)
-#define B3DFG_IOCTTRANS		_IO(B3DFG_IOC_MAGIC, 3)
-#define B3DFG_IOCTQUEUEBUF	_IO(B3DFG_IOC_MAGIC, 4)
-#define B3DFG_IOCTPOLLBUF	_IOWR(B3DFG_IOC_MAGIC, 5, struct b3dfg_poll)
-#define B3DFG_IOCTWAITBUF	_IOWR(B3DFG_IOC_MAGIC, 6, struct b3dfg_wait)
-#define B3DFG_IOCGWANDSTAT	_IOR(B3DFG_IOC_MAGIC, 7, int)
-
-enum {
-	/* number of 4kb pages per frame */
-	B3D_REG_FRM_SIZE = 0x0,
-
-	/* bit 0: set to enable interrupts
-	 * bit 1: set to enable cable status change interrupts */
-	B3D_REG_HW_CTRL = 0x4,
-
-	/* bit 0-1 - 1-based ID of next pending frame transfer (0 = none)
-	 * bit 2 indicates the previous DMA transfer has completed
-	 * bit 3 indicates wand cable status change
-	 * bit 8:15 - counter of number of discarded triplets */
-	B3D_REG_DMA_STS = 0x8,
-
-	/* bit 0: wand status (1 = present, 0 = disconnected) */
-	B3D_REG_WAND_STS = 0xc,
-
-	/* bus address for DMA transfers. lower 2 bits must be zero because DMA
-	 * works with 32 bit word size. */
-	B3D_REG_EC220_DMA_ADDR = 0x8000,
-
-	/* bit 20:0 - number of 32 bit words to be transferred
-	 * bit 21:31 - reserved */
-	B3D_REG_EC220_TRF_SIZE = 0x8004,
-
-	/* bit 0 - error bit
-	 * bit 1 - interrupt bit (set to generate interrupt at end of transfer)
-	 * bit 2 - start bit (set to start transfer)
-	 * bit 3 - direction (0 = DMA_TO_DEVICE, 1 = DMA_FROM_DEVICE
-	 * bit 4:31 - reserved */
-	B3D_REG_EC220_DMA_STS = 0x8008,
-};
-
-enum b3dfg_buffer_state {
-	B3DFG_BUFFER_POLLED = 0,
-	B3DFG_BUFFER_PENDING,
-	B3DFG_BUFFER_POPULATED,
-};
-
-struct b3dfg_buffer {
-	unsigned char *frame[B3DFG_FRAMES_PER_BUFFER];
-	struct list_head list;
-	u8 state;
-};
-
-struct b3dfg_dev {
-
-	/* no protection needed: all finalized at initialization time */
-	struct pci_dev *pdev;
-	struct cdev chardev;
-	struct device *dev;
-	void __iomem *regs;
-	unsigned int frame_size;
-
-	/*
-	 * Protects buffer state, including buffer_queue, triplet_ready,
-	 * cur_dma_frame_idx & cur_dma_frame_addr.
-	 */
-	spinlock_t buffer_lock;
-	struct b3dfg_buffer *buffers;
-	struct list_head buffer_queue;
-
-	/* Last frame in triplet transferred (-1 if none). */
-	int cur_dma_frame_idx;
-
-	/* Current frame's address for DMA. */
-	dma_addr_t cur_dma_frame_addr;
-
-	/*
-	 * Protects cstate_tstamp.
-	 * Nests inside buffer_lock.
-	 */
-	spinlock_t cstate_lock;
-	unsigned long cstate_tstamp;
-
-	/*
-	 * Protects triplets_dropped.
-	 * Nests inside buffers_lock.
-	 */
-	spinlock_t triplets_dropped_lock;
-	unsigned int triplets_dropped;
-
-	wait_queue_head_t buffer_waitqueue;
-
-	unsigned int transmission_enabled:1;
-	unsigned int triplet_ready:1;
-};
-
-static u8 b3dfg_devices[B3DFG_MAX_DEVS];
-
-static struct class *b3dfg_class;
-static dev_t b3dfg_devt;
-
-static const struct pci_device_id b3dfg_ids[] __devinitdata = {
-	{ PCI_DEVICE(0x0b3d, 0x0001) },
-	{ },
-};
-
-MODULE_DEVICE_TABLE(pci, b3dfg_ids);
-
-/***** user-visible types *****/
-
-struct b3dfg_poll {
-	int buffer_idx;
-	unsigned int triplets_dropped;
-};
-
-struct b3dfg_wait {
-	int buffer_idx;
-	unsigned int timeout;
-	unsigned int triplets_dropped;
-};
-
-/**** register I/O ****/
-
-static u32 b3dfg_read32(struct b3dfg_dev *fgdev, u16 reg)
-{
-	return ioread32(fgdev->regs + reg);
-}
-
-static void b3dfg_write32(struct b3dfg_dev *fgdev, u16 reg, u32 value)
-{
-	iowrite32(value, fgdev->regs + reg);
-}
-
-/**** buffer management ****/
-
-/*
- * Program EC220 for transfer of a specific frame.
- * Called with buffer_lock held.
- */
-static int setup_frame_transfer(struct b3dfg_dev *fgdev,
-	struct b3dfg_buffer *buf, int frame)
-{
-	unsigned char *frm_addr;
-	dma_addr_t frm_addr_dma;
-	unsigned int frm_size = fgdev->frame_size;
-
-	frm_addr = buf->frame[frame];
-	frm_addr_dma = pci_map_single(fgdev->pdev, frm_addr,
-					  frm_size, PCI_DMA_FROMDEVICE);
-	if (pci_dma_mapping_error(fgdev->pdev, frm_addr_dma))
-		return -ENOMEM;
-
-	fgdev->cur_dma_frame_addr = frm_addr_dma;
-	fgdev->cur_dma_frame_idx = frame;
-
-	b3dfg_write32(fgdev, B3D_REG_EC220_DMA_ADDR,
-					cpu_to_le32(frm_addr_dma));
-	b3dfg_write32(fgdev, B3D_REG_EC220_TRF_SIZE,
-					cpu_to_le32(frm_size >> 2));
-	b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0xf);
-
-	return 0;
-}
-
-/* Caller should hold buffer lock */
-static void dequeue_all_buffers(struct b3dfg_dev *fgdev)
-{
-	int i;
-	for (i = 0; i < b3dfg_nbuf; i++) {
-		struct b3dfg_buffer *buf = &fgdev->buffers[i];
-		buf->state = B3DFG_BUFFER_POLLED;
-		list_del_init(&buf->list);
-	}
-}
-
-/* queue a buffer to receive data */
-static int queue_buffer(struct b3dfg_dev *fgdev, int bufidx)
-{
-	struct device *dev = &fgdev->pdev->dev;
-	struct b3dfg_buffer *buf;
-	unsigned long flags;
-	int r = 0;
-
-	spin_lock_irqsave(&fgdev->buffer_lock, flags);
-	if (bufidx < 0 || bufidx >= b3dfg_nbuf) {
-		dev_dbg(dev, "Invalid buffer index, %d\n", bufidx);
-		r = -ENOENT;
-		goto out;
-	}
-	buf = &fgdev->buffers[bufidx];
-
-	if (unlikely(buf->state == B3DFG_BUFFER_PENDING)) {
-		dev_dbg(dev, "buffer %d is already queued\n", bufidx);
-		r = -EINVAL;
-		goto out;
-	}
-
-	buf->state = B3DFG_BUFFER_PENDING;
-	list_add_tail(&buf->list, &fgdev->buffer_queue);
-
-	if (fgdev->transmission_enabled && fgdev->triplet_ready) {
-		dev_dbg(dev, "triplet is ready, pushing immediately\n");
-		fgdev->triplet_ready = 0;
-		r = setup_frame_transfer(fgdev, buf, 0);
-		if (r)
-			dev_err(dev, "unable to map DMA buffer\n");
-	}
-
-out:
-	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
-	return r;
-}
-
-/* non-blocking buffer poll. returns 1 if data is present in the buffer,
- * 0 otherwise */
-static int poll_buffer(struct b3dfg_dev *fgdev, void __user *arg)
-{
-	struct device *dev = &fgdev->pdev->dev;
-	struct b3dfg_poll p;
-	struct b3dfg_buffer *buf;
-	unsigned long flags;
-	int r = 1;
-	int arg_out = 0;
-
-	if (copy_from_user(&p, arg, sizeof(p)))
-		return -EFAULT;
-
-	if (unlikely(!fgdev->transmission_enabled)) {
-		dev_dbg(dev, "cannot poll, transmission disabled\n");
-		return -EINVAL;
-	}
-
-	if (p.buffer_idx < 0 || p.buffer_idx >= b3dfg_nbuf)
-		return -ENOENT;
-
-	buf = &fgdev->buffers[p.buffer_idx];
-
-	spin_lock_irqsave(&fgdev->buffer_lock, flags);
-
-	if (likely(buf->state == B3DFG_BUFFER_POPULATED)) {
-		arg_out = 1;
-		buf->state = B3DFG_BUFFER_POLLED;
-
-		/* IRQs already disabled by spin_lock_irqsave above. */
-		spin_lock(&fgdev->triplets_dropped_lock);
-		p.triplets_dropped = fgdev->triplets_dropped;
-		fgdev->triplets_dropped = 0;
-		spin_unlock(&fgdev->triplets_dropped_lock);
-	} else {
-		r = 0;
-	}
-
-	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
-
-	if (arg_out && copy_to_user(arg, &p, sizeof(p)))
-		r = -EFAULT;
-
-	return r;
-}
-
-static unsigned long get_cstate_change(struct b3dfg_dev *fgdev)
-{
-	unsigned long flags, when;
-
-	spin_lock_irqsave(&fgdev->cstate_lock, flags);
-	when = fgdev->cstate_tstamp;
-	spin_unlock_irqrestore(&fgdev->cstate_lock, flags);
-	return when;
-}
-
-static int is_event_ready(struct b3dfg_dev *fgdev, struct b3dfg_buffer *buf,
-			  unsigned long when)
-{
-	int result;
-	unsigned long flags;
-
-	spin_lock_irqsave(&fgdev->buffer_lock, flags);
-	spin_lock(&fgdev->cstate_lock);
-	result = (!fgdev->transmission_enabled ||
-		  buf->state == B3DFG_BUFFER_POPULATED ||
-		  when != fgdev->cstate_tstamp);
-	spin_unlock(&fgdev->cstate_lock);
-	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
-
-	return result;
-}
-
-/* sleep until a specific buffer becomes populated */
-static int wait_buffer(struct b3dfg_dev *fgdev, void __user *arg)
-{
-	struct device *dev = &fgdev->pdev->dev;
-	struct b3dfg_wait w;
-	struct b3dfg_buffer *buf;
-	unsigned long flags, when;
-	int r;
-
-	if (copy_from_user(&w, arg, sizeof(w)))
-		return -EFAULT;
-
-	if (!fgdev->transmission_enabled) {
-		dev_dbg(dev, "cannot wait, transmission disabled\n");
-		return -EINVAL;
-	}
-
-	if (w.buffer_idx < 0 || w.buffer_idx >= b3dfg_nbuf)
-		return -ENOENT;
-
-	buf = &fgdev->buffers[w.buffer_idx];
-
-	spin_lock_irqsave(&fgdev->buffer_lock, flags);
-
-	if (buf->state == B3DFG_BUFFER_POPULATED) {
-		r = w.timeout;
-		goto out_triplets_dropped;
-	}
-
-	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
-
-	when = get_cstate_change(fgdev);
-	if (w.timeout > 0) {
-		r = wait_event_interruptible_timeout(fgdev->buffer_waitqueue,
-			is_event_ready(fgdev, buf, when),
-			(w.timeout * HZ) / 1000);
-
-		if (unlikely(r < 0))
-			goto out;
-
-		w.timeout = r * 1000 / HZ;
-	} else {
-		r = wait_event_interruptible(fgdev->buffer_waitqueue,
-			is_event_ready(fgdev, buf, when));
-
-		if (unlikely(r)) {
-			r = -ERESTARTSYS;
-			goto out;
-		}
-	}
-
-	/* TODO: Inform the user via field(s) in w? */
-	if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev)) {
-		r = -EINVAL;
-		goto out;
-	}
-
-	spin_lock_irqsave(&fgdev->buffer_lock, flags);
-
-	if (buf->state != B3DFG_BUFFER_POPULATED) {
-		r = -ETIMEDOUT;
-		goto out_unlock;
-	}
-
-	buf->state = B3DFG_BUFFER_POLLED;
-
-out_triplets_dropped:
-
-	/* IRQs already disabled by spin_lock_irqsave above. */
-	spin_lock(&fgdev->triplets_dropped_lock);
-	w.triplets_dropped = fgdev->triplets_dropped;
-	fgdev->triplets_dropped = 0;
-	spin_unlock(&fgdev->triplets_dropped_lock);
-
-out_unlock:
-	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
-	if (copy_to_user(arg, &w, sizeof(w)))
-		r = -EFAULT;
-out:
-	return r;
-}
-
-/* mmap page fault handler */
-static int b3dfg_vma_fault(struct vm_area_struct *vma,
-	struct vm_fault *vmf)
-{
-	struct b3dfg_dev *fgdev = vma->vm_file->private_data;
-	unsigned long off = vmf->pgoff << PAGE_SHIFT;
-	unsigned int frame_size = fgdev->frame_size;
-	unsigned int buf_size = frame_size * B3DFG_FRAMES_PER_BUFFER;
-	unsigned char *addr;
-
-	/* determine which buffer the offset lies within */
-	unsigned int buf_idx = off / buf_size;
-	/* and the offset into the buffer */
-	unsigned int buf_off = off % buf_size;
-
-	/* determine which frame inside the buffer the offset lies in */
-	unsigned int frm_idx = buf_off / frame_size;
-	/* and the offset into the frame */
-	unsigned int frm_off = buf_off % frame_size;
-
-	if (unlikely(buf_idx >= b3dfg_nbuf))
-		return VM_FAULT_SIGBUS;
-
-	addr = fgdev->buffers[buf_idx].frame[frm_idx] + frm_off;
-	vm_insert_pfn(vma, (unsigned long)vmf->virtual_address,
-			  virt_to_phys(addr) >> PAGE_SHIFT);
-
-	return VM_FAULT_NOPAGE;
-}
-
-static struct vm_operations_struct b3dfg_vm_ops = {
-	.fault = b3dfg_vma_fault,
-};
-
-static int get_wand_status(struct b3dfg_dev *fgdev, int __user *arg)
-{
-	u32 wndstat = b3dfg_read32(fgdev, B3D_REG_WAND_STS);
-	dev_dbg(&fgdev->pdev->dev, "wand status %x\n", wndstat);
-	return __put_user(wndstat & 0x1, arg);
-}
-
-static int enable_transmission(struct b3dfg_dev *fgdev)
-{
-	unsigned long flags;
-	struct device *dev = &fgdev->pdev->dev;
-
-	dev_dbg(dev, "enable transmission\n");
-
-	/* check the cable is plugged in. */
-	if (!b3dfg_read32(fgdev, B3D_REG_WAND_STS)) {
-		dev_dbg(dev, "cannot start transmission without wand\n");
-		return -EINVAL;
-	}
-
-	spin_lock_irqsave(&fgdev->buffer_lock, flags);
-
-	/* Handle racing enable_transmission calls. */
-	if (fgdev->transmission_enabled) {
-		spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
-		goto out;
-	}
-
-	spin_lock(&fgdev->triplets_dropped_lock);
-	fgdev->triplets_dropped = 0;
-	spin_unlock(&fgdev->triplets_dropped_lock);
-
-	fgdev->triplet_ready = 0;
-	fgdev->cur_dma_frame_idx = -1;
-	fgdev->transmission_enabled = 1;
-
-	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
-
-	/* Enable DMA and cable status interrupts. */
-	b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0x03);
-
-out:
-	return 0;
-}
-
-static void disable_transmission(struct b3dfg_dev *fgdev)
-{
-	struct device *dev = &fgdev->pdev->dev;
-	unsigned long flags;
-	u32 tmp;
-
-	dev_dbg(dev, "disable transmission\n");
-
-	/* guarantee that no more interrupts will be serviced */
-	spin_lock_irqsave(&fgdev->buffer_lock, flags);
-	fgdev->transmission_enabled = 0;
-
-	b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
-
-	/* FIXME: temporary debugging only. if the board stops transmitting,
-	 * hitting ctrl+c and seeing this message is useful for determining
-	 * the state of the board. */
-	tmp = b3dfg_read32(fgdev, B3D_REG_DMA_STS);
-	dev_dbg(dev, "DMA_STS reads %x after TX stopped\n", tmp);
-
-	dequeue_all_buffers(fgdev);
-	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
-
-	wake_up_interruptible(&fgdev->buffer_waitqueue);
-}
-
-static int set_transmission(struct b3dfg_dev *fgdev, int enabled)
-{
-	int res = 0;
-
-	if (enabled && !fgdev->transmission_enabled)
-		res = enable_transmission(fgdev);
-	else if (!enabled && fgdev->transmission_enabled)
-		disable_transmission(fgdev);
-
-	return res;
-}
-
-/* Called in interrupt context. */
-static void handle_cstate_unplug(struct b3dfg_dev *fgdev)
-{
-	/* Disable all interrupts. */
-	b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
-
-	/* Stop transmission. */
-	spin_lock(&fgdev->buffer_lock);
-	fgdev->transmission_enabled = 0;
-
-	fgdev->cur_dma_frame_idx = -1;
-	fgdev->triplet_ready = 0;
-	if (fgdev->cur_dma_frame_addr) {
-		pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr,
-				 fgdev->frame_size, PCI_DMA_FROMDEVICE);
-		fgdev->cur_dma_frame_addr = 0;
-	}
-	dequeue_all_buffers(fgdev);
-	spin_unlock(&fgdev->buffer_lock);
-}
-
-/* Called in interrupt context. */
-static void handle_cstate_change(struct b3dfg_dev *fgdev)
-{
-	u32 cstate = b3dfg_read32(fgdev, B3D_REG_WAND_STS);
-	unsigned long when;
-	struct device *dev = &fgdev->pdev->dev;
-
-	dev_dbg(dev, "cable state change: %u\n", cstate);
-
-	/*
-	 * When the wand is unplugged we reset our state. The hardware will
-	 * have done the same internally.
-	 *
-	 * Note we should never see a cable *plugged* event, as interrupts
-	 * should only be enabled when transmitting, which requires the cable
-	 * to be plugged. If we do see one it probably means the cable has been
-	 * unplugged and re-plugged very rapidly. Possibly because it has a
-	 * broken wire and is momentarily losing contact.
-	 *
-	 * TODO: At the moment if you plug in the cable then enable transmission
-	 * the hardware will raise a couple of spurious interrupts, so
-	 * just ignore them for now.
-	 *
-	 * Once the hardware is fixed we should complain and treat it as an
-	 * unplug. Or at least track how frequently it is happening and do
-	 * so if too many come in.
-	 */
-	if (cstate) {
-		dev_warn(dev, "ignoring unexpected plug event\n");
-		return;
-	}
-	handle_cstate_unplug(fgdev);
-
-	/*
-	 * Record cable state change timestamp & wake anyone waiting
-	 * on a cable state change. Be paranoid about ensuring events
-	 * are not missed if we somehow get two interrupts in a jiffy.
-	 */
-	spin_lock(&fgdev->cstate_lock);
-	when = jiffies_64;
-	if (when <= fgdev->cstate_tstamp)
-		when = fgdev->cstate_tstamp + 1;
-	fgdev->cstate_tstamp = when;
-	wake_up_interruptible(&fgdev->buffer_waitqueue);
-	spin_unlock(&fgdev->cstate_lock);
-}
-
-/* Called with buffer_lock held. */
-static void transfer_complete(struct b3dfg_dev *fgdev)
-{
-	struct b3dfg_buffer *buf;
-	struct device *dev = &fgdev->pdev->dev;
-
-	pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr,
-			 fgdev->frame_size, PCI_DMA_FROMDEVICE);
-	fgdev->cur_dma_frame_addr = 0;
-
-	buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
-
-	dev_dbg(dev, "handle frame completion\n");
-	if (fgdev->cur_dma_frame_idx == B3DFG_FRAMES_PER_BUFFER - 1) {
-
-		/* last frame of that triplet completed */
-		dev_dbg(dev, "triplet completed\n");
-		buf->state = B3DFG_BUFFER_POPULATED;
-		list_del_init(&buf->list);
-		wake_up_interruptible(&fgdev->buffer_waitqueue);
-	}
-}
-
-/*
- * Called with buffer_lock held.
- *
- * Note that idx is the (1-based) *next* frame to be transferred, while
- * cur_dma_frame_idx is the (0-based) *last* frame to have been transferred (or
- * -1 if none). Thus there should be a difference of 2 between them.
- */
-static bool setup_next_frame_transfer(struct b3dfg_dev *fgdev, int idx)
-{
-	struct b3dfg_buffer *buf;
-	struct device *dev = &fgdev->pdev->dev;
-	bool need_ack = 1;
-
-	dev_dbg(dev, "program DMA transfer for next frame: %d\n", idx);
-
-	buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
-	if (idx == fgdev->cur_dma_frame_idx + 2) {
-		if (setup_frame_transfer(fgdev, buf, idx - 1))
-			dev_err(dev, "unable to map DMA buffer\n");
-		need_ack = 0;
-	} else {
-		dev_err(dev, "frame mismatch, got %d, expected %d\n",
-			idx, fgdev->cur_dma_frame_idx + 2);
-
-		/* FIXME: handle dropped triplets here */
-	}
-
-	return need_ack;
-}
-
-static irqreturn_t b3dfg_intr(int irq, void *dev_id)
-{
-	struct b3dfg_dev *fgdev = dev_id;
-	struct device *dev = &fgdev->pdev->dev;
-	u32 sts;
-	u8 dropped;
-	bool need_ack = 1;
-	irqreturn_t res = IRQ_HANDLED;
-
-	sts = b3dfg_read32(fgdev, B3D_REG_DMA_STS);
-	if (unlikely(sts == 0)) {
-		dev_warn(dev, "ignore interrupt, DMA status is 0\n");
-		res = IRQ_NONE;
-		goto out;
-	}
-
-	if (unlikely(!fgdev->transmission_enabled)) {
-		dev_warn(dev, "ignore interrupt, TX disabled\n");
-		res = IRQ_HANDLED;
-		goto out;
-	}
-
-	/* Handle dropped frames, as reported by the hardware. */
-	dropped = (sts >> 8) & 0xff;
-	dev_dbg(dev, "intr: DMA_STS=%08x (drop=%d comp=%d next=%d)\n",
-		sts, dropped, !!(sts & 0x4), sts & 0x3);
-	if (unlikely(dropped > 0)) {
-		spin_lock(&fgdev->triplets_dropped_lock);
-		fgdev->triplets_dropped += dropped;
-		spin_unlock(&fgdev->triplets_dropped_lock);
-	}
-
-	/* Handle a cable state change (i.e. the wand being unplugged). */
-	if (sts & 0x08) {
-		handle_cstate_change(fgdev);
-		goto out;
-	}
-
-	spin_lock(&fgdev->buffer_lock);
-	if (unlikely(list_empty(&fgdev->buffer_queue))) {
-
-		/* FIXME need more sanity checking here */
-		dev_info(dev, "buffer not ready for next transfer\n");
-		fgdev->triplet_ready = 1;
-		goto out_unlock;
-	}
-
-	/* Has a frame transfer been completed? */
-	if (sts & 0x4) {
-		u32 dma_status = b3dfg_read32(fgdev, B3D_REG_EC220_DMA_STS);
-
-		/* Check for DMA errors reported by the hardware. */
-		if (unlikely(dma_status & 0x1)) {
-			dev_err(dev, "EC220 error: %08x\n", dma_status);
-
-			/* FIXME flesh out error handling */
-			goto out_unlock;
-		}
-
-		/* Sanity check, we should have a frame index at this point. */
-		if (unlikely(fgdev->cur_dma_frame_idx == -1)) {
-			dev_err(dev, "completed but no last idx?\n");
-
-			/* FIXME flesh out error handling */
-			goto out_unlock;
-		}
-
-		transfer_complete(fgdev);
-	}
-
-	/* Is there another frame transfer pending? */
-	if (sts & 0x3)
-		need_ack = setup_next_frame_transfer(fgdev, sts & 0x3);
-	else
-		fgdev->cur_dma_frame_idx = -1;
-
-out_unlock:
-	spin_unlock(&fgdev->buffer_lock);
-out:
-	if (need_ack) {
-		dev_dbg(dev, "acknowledging interrupt\n");
-		b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0x0b);
-	}
-	return res;
-}
-
-static int b3dfg_open(struct inode *inode, struct file *filp)
-{
-	struct b3dfg_dev *fgdev =
-		container_of(inode->i_cdev, struct b3dfg_dev, chardev);
-
-	dev_dbg(&fgdev->pdev->dev, "open\n");
-	filp->private_data = fgdev;
-	return 0;
-}
-
-static int b3dfg_release(struct inode *inode, struct file *filp)
-{
-	struct b3dfg_dev *fgdev = filp->private_data;
-	dev_dbg(&fgdev->pdev->dev, "release\n");
-	disable_transmission(fgdev);
-	return 0;
-}
-
-static long b3dfg_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
-	struct b3dfg_dev *fgdev = filp->private_data;
-
-	switch (cmd) {
-	case B3DFG_IOCGFRMSZ:
-		return __put_user(fgdev->frame_size, (int __user *) arg);
-	case B3DFG_IOCGWANDSTAT:
-		return get_wand_status(fgdev, (int __user *) arg);
-	case B3DFG_IOCTTRANS:
-		return set_transmission(fgdev, (int) arg);
-	case B3DFG_IOCTQUEUEBUF:
-		return queue_buffer(fgdev, (int) arg);
-	case B3DFG_IOCTPOLLBUF:
-		return poll_buffer(fgdev, (void __user *) arg);
-	case B3DFG_IOCTWAITBUF:
-		return wait_buffer(fgdev, (void __user *) arg);
-	default:
-		dev_dbg(&fgdev->pdev->dev, "unrecognised ioctl %x\n", cmd);
-		return -EINVAL;
-	}
-}
-
-static unsigned int b3dfg_poll(struct file *filp, poll_table *poll_table)
-{
-	struct b3dfg_dev *fgdev = filp->private_data;
-	unsigned long flags, when;
-	int i;
-	int r = 0;
-
-	when = get_cstate_change(fgdev);
-	poll_wait(filp, &fgdev->buffer_waitqueue, poll_table);
-
-	spin_lock_irqsave(&fgdev->buffer_lock, flags);
-	for (i = 0; i < b3dfg_nbuf; i++) {
-		if (fgdev->buffers[i].state == B3DFG_BUFFER_POPULATED) {
-			r = POLLIN | POLLRDNORM;
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
-
-	/* TODO: Confirm this is how we want to communicate the change. */
-	if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev))
-		r = POLLERR;
-
-	return r;
-}
-
-static int b3dfg_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-	struct b3dfg_dev *fgdev = filp->private_data;
-	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-	unsigned long vsize = vma->vm_end - vma->vm_start;
-	unsigned long bufdatalen = b3dfg_nbuf * fgdev->frame_size * 3;
-	unsigned long psize = bufdatalen - offset;
-	int r = 0;
-
-	if (vsize <= psize) {
-		vma->vm_flags |= VM_IO | VM_RESERVED | VM_CAN_NONLINEAR |
-				 VM_PFNMAP;
-		vma->vm_ops = &b3dfg_vm_ops;
-	} else {
-		r = -EINVAL;
-	}
-
-	return r;
-}
-
-static struct file_operations b3dfg_fops = {
-	.owner = THIS_MODULE,
-	.open = b3dfg_open,
-	.release = b3dfg_release,
-	.unlocked_ioctl = b3dfg_ioctl,
-	.poll = b3dfg_poll,
-	.mmap = b3dfg_mmap,
-};
-
-static void free_all_frame_buffers(struct b3dfg_dev *fgdev)
-{
-	int i, j;
-	for (i = 0; i < b3dfg_nbuf; i++)
-		for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++)
-			kfree(fgdev->buffers[i].frame[j]);
-	kfree(fgdev->buffers);
-}
-
-/* initialize device and any data structures. called before any interrupts
- * are enabled. */
-static int b3dfg_init_dev(struct b3dfg_dev *fgdev)
-{
-	int i, j;
-	u32 frm_size = b3dfg_read32(fgdev, B3D_REG_FRM_SIZE);
-
-	/* Disable interrupts. In abnormal circumstances (e.g. after a crash)
-	 * the board may still be transmitting from the previous session. If we
-	 * ensure that interrupts are disabled before we later enable them, we
-	 * are sure to capture a triplet from the start, rather than starting
-	 * from frame 2 or 3. Disabling interrupts causes the FG to throw away
-	 * all buffered data and stop buffering more until interrupts are
-	 * enabled again.
-	 */
-	b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
-
-	fgdev->frame_size = frm_size * 4096;
-	fgdev->buffers = kzalloc(sizeof(struct b3dfg_buffer) * b3dfg_nbuf,
-				 GFP_KERNEL);
-	if (!fgdev->buffers)
-		goto err_no_buf;
-	for (i = 0; i < b3dfg_nbuf; i++) {
-		struct b3dfg_buffer *buf = &fgdev->buffers[i];
-		for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++) {
-			buf->frame[j] = kmalloc(fgdev->frame_size, GFP_KERNEL);
-			if (!buf->frame[j])
-				goto err_no_mem;
-		}
-		INIT_LIST_HEAD(&buf->list);
-	}
-
-	INIT_LIST_HEAD(&fgdev->buffer_queue);
-	init_waitqueue_head(&fgdev->buffer_waitqueue);
-	spin_lock_init(&fgdev->buffer_lock);
-	spin_lock_init(&fgdev->cstate_lock);
-	spin_lock_init(&fgdev->triplets_dropped_lock);
-	return 0;
-
-err_no_mem:
-	free_all_frame_buffers(fgdev);
-err_no_buf:
-	return -ENOMEM;
-}
-
-/* find next free minor number, returns -1 if none are availabile */
-static int get_free_minor(void)
-{
-	int i;
-	for (i = 0; i < B3DFG_MAX_DEVS; i++) {
-		if (b3dfg_devices[i] == 0)
-			return i;
-	}
-	return -1;
-}
-
-static int __devinit b3dfg_probe(struct pci_dev *pdev,
-	const struct pci_device_id *id)
-{
-	struct b3dfg_dev *fgdev = kzalloc(sizeof(*fgdev), GFP_KERNEL);
-	int r = 0;
-	int minor = get_free_minor();
-	dev_t devno = MKDEV(MAJOR(b3dfg_devt), minor);
-	unsigned long res_len;
-	resource_size_t res_base;
-
-	if (fgdev == NULL)
-		return -ENOMEM;
-
-	if (minor < 0) {
-		dev_err(&pdev->dev, "too many devices found!\n");
-		r = -EIO;
-		goto err_free;
-	}
-
-	b3dfg_devices[minor] = 1;
-	dev_info(&pdev->dev, "probe device with IRQ %d\n", pdev->irq);
-
-	cdev_init(&fgdev->chardev, &b3dfg_fops);
-	fgdev->chardev.owner = THIS_MODULE;
-
-	r = cdev_add(&fgdev->chardev, devno, 1);
-	if (r) {
-		dev_err(&pdev->dev, "cannot add char device\n");
-		goto err_release_minor;
-	}
-
-	fgdev->dev = device_create(
-		b3dfg_class,
-		&pdev->dev,
-		devno,
-		dev_get_drvdata(&pdev->dev),
-		DRIVER_NAME "%d", minor);
-
-	if (IS_ERR(fgdev->dev)) {
-		dev_err(&pdev->dev, "cannot create device\n");
-		r = PTR_ERR(fgdev->dev);
-		goto err_del_cdev;
-	}
-
-	r = pci_enable_device(pdev);
-	if (r) {
-		dev_err(&pdev->dev, "cannot enable PCI device\n");
-		goto err_dev_unreg;
-	}
-
-	res_len = pci_resource_len(pdev, B3DFG_BAR_REGS);
-	if (res_len != B3DFG_REGS_LENGTH) {
-		dev_err(&pdev->dev, "invalid register resource size\n");
-		r = -EIO;
-		goto err_disable;
-	}
-
-	if (pci_resource_flags(pdev, B3DFG_BAR_REGS)
-				!= (IORESOURCE_MEM | IORESOURCE_SIZEALIGN)) {
-		dev_err(&pdev->dev, "invalid resource flags\n");
-		r = -EIO;
-		goto err_disable;
-	}
-	r = pci_request_regions(pdev, DRIVER_NAME);
-	if (r) {
-		dev_err(&pdev->dev, "cannot obtain PCI resources\n");
-		goto err_disable;
-	}
-
-	pci_set_master(pdev);
-
-	r = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-	if (r) {
-		dev_err(&pdev->dev, "no usable DMA configuration\n");
-		goto err_free_res;
-	}
-
-	res_base = pci_resource_start(pdev, B3DFG_BAR_REGS);
-	fgdev->regs = ioremap_nocache(res_base, res_len);
-	if (!fgdev->regs) {
-		dev_err(&pdev->dev, "regs ioremap failed\n");
-		r = -EIO;
-		goto err_free_res;
-	}
-
-	fgdev->pdev = pdev;
-	pci_set_drvdata(pdev, fgdev);
-	r = b3dfg_init_dev(fgdev);
-	if (r < 0) {
-		dev_err(&pdev->dev, "failed to initalize device\n");
-		goto err_unmap;
-	}
-
-	r = request_irq(pdev->irq, b3dfg_intr, IRQF_SHARED, DRIVER_NAME, fgdev);
-	if (r) {
-		dev_err(&pdev->dev, "couldn't request irq %d\n", pdev->irq);
-		goto err_free_bufs;
-	}
-
-	return 0;
-
-err_free_bufs:
-	free_all_frame_buffers(fgdev);
-err_unmap:
-	iounmap(fgdev->regs);
-err_free_res:
-	pci_release_regions(pdev);
-err_disable:
-	pci_disable_device(pdev);
-err_dev_unreg:
-	device_destroy(b3dfg_class, devno);
-err_del_cdev:
-	cdev_del(&fgdev->chardev);
-err_release_minor:
-	b3dfg_devices[minor] = 0;
-err_free:
-	kfree(fgdev);
-	return r;
-}
-
-static void __devexit b3dfg_remove(struct pci_dev *pdev)
-{
-	struct b3dfg_dev *fgdev = pci_get_drvdata(pdev);
-	unsigned int minor = MINOR(fgdev->chardev.dev);
-
-	dev_dbg(&pdev->dev, "remove\n");
-
-	free_irq(pdev->irq, fgdev);
-	iounmap(fgdev->regs);
-	pci_release_regions(pdev);
-	pci_disable_device(pdev);
-	device_destroy(b3dfg_class, MKDEV(MAJOR(b3dfg_devt), minor));
-	cdev_del(&fgdev->chardev);
-	free_all_frame_buffers(fgdev);
-	kfree(fgdev);
-	b3dfg_devices[minor] = 0;
-}
-
-static struct pci_driver b3dfg_driver = {
-	.name = DRIVER_NAME,
-	.id_table = b3dfg_ids,
-	.probe = b3dfg_probe,
-	.remove = __devexit_p(b3dfg_remove),
-};
-
-static int __init b3dfg_module_init(void)
-{
-	int r;
-
-	if (b3dfg_nbuf < 2) {
-		printk(KERN_ERR DRIVER_NAME
-			   ": buffer_count is out of range (must be >= 2)");
-		return -EINVAL;
-	}
-
-	printk(KERN_INFO DRIVER_NAME ": loaded\n");
-
-	b3dfg_class = class_create(THIS_MODULE, DRIVER_NAME);
-	if (IS_ERR(b3dfg_class))
-		return PTR_ERR(b3dfg_class);
-
-	r = alloc_chrdev_region(&b3dfg_devt, 0, B3DFG_MAX_DEVS, DRIVER_NAME);
-	if (r)
-		goto err1;
-
-	r = pci_register_driver(&b3dfg_driver);
-	if (r)
-		goto err2;
-
-	return r;
-
-err2:
-	unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS);
-err1:
-	class_destroy(b3dfg_class);
-	return r;
-}
-
-static void __exit b3dfg_module_exit(void)
-{
-	printk(KERN_INFO DRIVER_NAME ": unloaded\n");
-	pci_unregister_driver(&b3dfg_driver);
-	unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS);
-	class_destroy(b3dfg_class);
-}
-
-module_init(b3dfg_module_init);
-module_exit(b3dfg_module_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/b3dfg/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/b3dfg/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/b3dfg/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/b3dfg/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,10 +0,0 @@
-config B3DFG
-       tristate "Brontes 3d Frame Framegrabber"
-       depends on PCI
-       default n
-       ---help---
-         This driver provides support for the Brontes 3d Framegrabber
-         PCI card.
-
-         To compile this driver as a module, choose M here. The module
-         will be called b3dfg.
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/b3dfg/Makefile linux-libre-2.6.34-gnu1/drivers/staging/b3dfg/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/b3dfg/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/b3dfg/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-obj-$(CONFIG_B3DFG) += b3dfg.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/b3dfg/TODO linux-libre-2.6.34-gnu1/drivers/staging/b3dfg/TODO
--- linux-libre-2.6.33-gnu1/drivers/staging/b3dfg/TODO	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/b3dfg/TODO	1969-12-31 19:00:00.000000000 -0500
@@ -1,4 +0,0 @@
-
- - queue/wait buffer presents filltime results for each frame?
- - counting of dropped frames
- - review endianness
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/aggregation.c linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/aggregation.c
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/aggregation.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/aggregation.c	2010-05-16 17:17:36.000000000 -0400
@@ -96,6 +96,7 @@ static void new_aggregated_packet(unsign
 			   int own_packet)
 {
 	struct forw_packet *forw_packet_aggr;
+	unsigned long flags;
 
 	forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
 	if (!forw_packet_aggr)
@@ -115,6 +116,7 @@ static void new_aggregated_packet(unsign
 	       packet_buff,
 	       forw_packet_aggr->packet_len);
 
+	forw_packet_aggr->skb = NULL;
 	forw_packet_aggr->own = own_packet;
 	forw_packet_aggr->if_incoming = if_incoming;
 	forw_packet_aggr->num_packets = 0;
@@ -126,9 +128,9 @@ static void new_aggregated_packet(unsign
 		forw_packet_aggr->direct_link_flags |= 1;
 
 	/* add new packet to packet list */
-	spin_lock(&forw_bat_list_lock);
+	spin_lock_irqsave(&forw_bat_list_lock, flags);
 	hlist_add_head(&forw_packet_aggr->list, &forw_bat_list);
-	spin_unlock(&forw_bat_list_lock);
+	spin_unlock_irqrestore(&forw_bat_list_lock, flags);
 
 	/* start timer for this packet */
 	INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
@@ -168,9 +170,10 @@ void add_bat_packet_to_list(unsigned cha
 	struct batman_packet *batman_packet =
 		(struct batman_packet *)packet_buff;
 	bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0;
+	unsigned long flags;
 
 	/* find position for the packet in the forward queue */
-	spin_lock(&forw_bat_list_lock);
+	spin_lock_irqsave(&forw_bat_list_lock, flags);
 	/* own packets are not to be aggregated */
 	if ((atomic_read(&aggregation_enabled)) && (!own_packet)) {
 		hlist_for_each_entry(forw_packet_pos, tmp_node, &forw_bat_list,
@@ -191,7 +194,7 @@ void add_bat_packet_to_list(unsigned cha
 	 * suitable aggregation packet found */
 	if (forw_packet_aggr == NULL) {
 		/* the following section can run without the lock */
-		spin_unlock(&forw_bat_list_lock);
+		spin_unlock_irqrestore(&forw_bat_list_lock, flags);
 		new_aggregated_packet(packet_buff, packet_len,
 				      send_time, direct_link,
 				      if_incoming, own_packet);
@@ -199,7 +202,7 @@ void add_bat_packet_to_list(unsigned cha
 		aggregate(forw_packet_aggr,
 			  packet_buff, packet_len,
 			  direct_link);
-		spin_unlock(&forw_bat_list_lock);
+		spin_unlock_irqrestore(&forw_bat_list_lock, flags);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/bitarray.c linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/bitarray.c
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/bitarray.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/bitarray.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@
 
 #include "main.h"
 #include "bitarray.h"
-#include "log.h"
 
 /* returns true if the corresponding bit in the given seq_bits indicates true
  * and curr_seqno is within range of last_seqno */
@@ -80,8 +79,8 @@ void bit_shift(TYPE_OF_WORD *seq_bits, i
 		 * from.
 		 *
 		 * left is high, right is low: FEDC BA98 7654 3210
-		 *	                                  ^^ ^^
-		 *                             vvvv
+		 *					  ^^ ^^
+		 *			       vvvv
 		 * ^^^^ = from, vvvvv =to, we'd have word_num==1 and
 		 * word_offset==WORD_BIT_SIZE/2 ????? in this example.
 		 * (=24 bits)
@@ -133,13 +132,13 @@ char bit_get_packet(TYPE_OF_WORD *seq_bi
 	    (seq_num_diff < -TQ_LOCAL_WINDOW_SIZE)) {
 
 		if (seq_num_diff > TQ_LOCAL_WINDOW_SIZE)
-			debug_log(LOG_TYPE_BATMAN,
-				  "We missed a lot of packets (%i) !\n",
-				  seq_num_diff-1);
+			bat_dbg(DBG_BATMAN,
+				"We missed a lot of packets (%i) !\n",
+				seq_num_diff-1);
 
 		if (-seq_num_diff > TQ_LOCAL_WINDOW_SIZE)
-			debug_log(LOG_TYPE_BATMAN,
-				  "Other host probably restarted !\n");
+			bat_dbg(DBG_BATMAN,
+				"Other host probably restarted !\n");
 
 		for (i = 0; i < NUM_WORDS; i++)
 			seq_bits[i] = 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/compat.h linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/compat.h
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/compat.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/compat.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner, Simon Wunderlich
- *
- * 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-1301, USA
- *
- *
- * This file contains macros for maintaining compatibility with older versions
- * of the Linux kernel.
- */
-
-#include <linux/version.h>	/* LINUX_VERSION_CODE */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
-
-#define skb_set_network_header(_skb, _offset) \
-	do { (_skb)->nh.raw = (_skb)->data + (_offset); } while (0)
-
-#define skb_reset_mac_header(_skb) \
-	do { (_skb)->mac.raw = (_skb)->data; } while (0)
-
-#define list_first_entry(ptr, type, member) \
-	list_entry((ptr)->next, type, member)
-
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) */
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
-
-#define device_create(_cls, _parent, _devt, _device, _fmt) \
-	class_device_create(_cls, _parent, _devt, _device, _fmt)
-
-#define device_destroy(_cls, _device) \
-	class_device_destroy(_cls, _device)
-
-#else
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
-
-#define device_create(_cls, _parent, _devt, _device, _fmt) \
-	device_create_drvdata(_cls, _parent, _devt, _device, _fmt)
-
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) */
-
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
-
-#define cancel_delayed_work_sync(wq) cancel_rearming_delayed_work(wq)
-
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
-#define strict_strtoul(cp, base, res) \
-	({ \
-	int ret = 0; \
-	char *endp; \
-	*res = simple_strtoul(cp, &endp, base); \
-	if (cp == endp) \
-		ret = -EINVAL; \
-	ret; \
-})
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/device.c linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/device.c
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/device.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/device.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,14 +19,14 @@
  *
  */
 
+#include <linux/device.h>
+#include <linux/slab.h>
 #include "main.h"
 #include "device.h"
-#include "log.h"
 #include "send.h"
 #include "types.h"
 #include "hash.h"
-
-#include "compat.h"
+#include "hard-interface.h"
 
 static struct class *batman_class;
 
@@ -60,7 +60,7 @@ int bat_device_setup(void)
 	/* register our device - kernel assigns a free major number */
 	tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops);
 	if (tmp_major < 0) {
-		debug_log(LOG_TYPE_WARN, "Registering the character device failed with %d\n",
+		printk(KERN_ERR "batman-adv:Registering the character device failed with %d\n",
 			  tmp_major);
 		return 0;
 	}
@@ -68,7 +68,7 @@ int bat_device_setup(void)
 	batman_class = class_create(THIS_MODULE, "batman-adv");
 
 	if (IS_ERR(batman_class)) {
-		debug_log(LOG_TYPE_WARN, "Could not register class 'batman-adv' \n");
+		printk(KERN_ERR "batman-adv:Could not register class 'batman-adv' \n");
 		return 0;
 	}
 
@@ -111,7 +111,7 @@ int bat_device_open(struct inode *inode,
 	}
 
 	if (device_client_hash[i] != device_client) {
-		debug_log(LOG_TYPE_WARN, "Error - can't add another packet client: maximum number of clients reached \n");
+		printk(KERN_ERR "batman-adv:Error - can't add another packet client: maximum number of clients reached \n");
 		kfree(device_client);
 		return -EXFULL;
 	}
@@ -119,7 +119,7 @@ int bat_device_open(struct inode *inode,
 	INIT_LIST_HEAD(&device_client->queue_list);
 	device_client->queue_len = 0;
 	device_client->index = i;
-	device_client->lock = __SPIN_LOCK_UNLOCKED(device_client->lock);
+	spin_lock_init(&device_client->lock);
 	init_waitqueue_head(&device_client->queue_wait);
 
 	file->private_data = device_client;
@@ -134,8 +134,9 @@ int bat_device_release(struct inode *ino
 		(struct device_client *)file->private_data;
 	struct device_packet *device_packet;
 	struct list_head *list_pos, *list_pos_tmp;
+	unsigned long flags;
 
-	spin_lock(&device_client->lock);
+	spin_lock_irqsave(&device_client->lock, flags);
 
 	/* for all packets in the queue ... */
 	list_for_each_safe(list_pos, list_pos_tmp, &device_client->queue_list) {
@@ -147,7 +148,7 @@ int bat_device_release(struct inode *ino
 	}
 
 	device_client_hash[device_client->index] = NULL;
-	spin_unlock(&device_client->lock);
+	spin_unlock_irqrestore(&device_client->lock, flags);
 
 	kfree(device_client);
 	dec_module_count();
@@ -162,6 +163,7 @@ ssize_t bat_device_read(struct file *fil
 		(struct device_client *)file->private_data;
 	struct device_packet *device_packet;
 	int error;
+	unsigned long flags;
 
 	if ((file->f_flags & O_NONBLOCK) && (device_client->queue_len == 0))
 		return -EAGAIN;
@@ -178,14 +180,14 @@ ssize_t bat_device_read(struct file *fil
 	if (error)
 		return error;
 
-	spin_lock(&device_client->lock);
+	spin_lock_irqsave(&device_client->lock, flags);
 
 	device_packet = list_first_entry(&device_client->queue_list,
 					 struct device_packet, list);
 	list_del(&device_packet->list);
 	device_client->queue_len--;
 
-	spin_unlock(&device_client->lock);
+	spin_unlock_irqrestore(&device_client->lock, flags);
 
 	error = __copy_to_user(buf, &device_packet->icmp_packet,
 			       sizeof(struct icmp_packet));
@@ -206,9 +208,11 @@ ssize_t bat_device_write(struct file *fi
 	struct icmp_packet icmp_packet;
 	struct orig_node *orig_node;
 	struct batman_if *batman_if;
+	uint8_t dstaddr[ETH_ALEN];
+	unsigned long flags;
 
 	if (len < sizeof(struct icmp_packet)) {
-		debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: invalid packet size\n");
+		bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: invalid packet size\n");
 		return -EINVAL;
 	}
 
@@ -219,12 +223,12 @@ ssize_t bat_device_write(struct file *fi
 		return -EFAULT;
 
 	if (icmp_packet.packet_type != BAT_ICMP) {
-		debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
+		bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
 		return -EINVAL;
 	}
 
 	if (icmp_packet.msg_type != ECHO_REQUEST) {
-		debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n");
+		bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n");
 		return -EINVAL;
 	}
 
@@ -240,7 +244,7 @@ ssize_t bat_device_write(struct file *fi
 	if (atomic_read(&module_state) != MODULE_ACTIVE)
 		goto dst_unreach;
 
-	spin_lock(&orig_hash_lock);
+	spin_lock_irqsave(&orig_hash_lock, flags);
 	orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst));
 
 	if (!orig_node)
@@ -250,9 +254,15 @@ ssize_t bat_device_write(struct file *fi
 		goto unlock;
 
 	batman_if = orig_node->batman_if;
+	memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
 
 	if (!batman_if)
-		goto unlock;
+		goto dst_unreach;
+
+	if (batman_if->if_active != IF_ACTIVE)
+		goto dst_unreach;
 
 	memcpy(icmp_packet.orig,
 	       batman_if->net_dev->dev_addr,
@@ -260,13 +270,12 @@ ssize_t bat_device_write(struct file *fi
 
 	send_raw_packet((unsigned char *)&icmp_packet,
 			sizeof(struct icmp_packet),
-			batman_if, orig_node->router->addr);
+			batman_if, dstaddr);
 
-	spin_unlock(&orig_hash_lock);
 	goto out;
 
 unlock:
-	spin_unlock(&orig_hash_lock);
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
 dst_unreach:
 	icmp_packet.msg_type = DESTINATION_UNREACHABLE;
 	bat_device_add_packet(device_client, &icmp_packet);
@@ -291,6 +300,7 @@ void bat_device_add_packet(struct device
 			   struct icmp_packet *icmp_packet)
 {
 	struct device_packet *device_packet;
+	unsigned long flags;
 
 	device_packet = kmalloc(sizeof(struct device_packet), GFP_KERNEL);
 
@@ -301,12 +311,12 @@ void bat_device_add_packet(struct device
 	memcpy(&device_packet->icmp_packet, icmp_packet,
 	       sizeof(struct icmp_packet));
 
-	spin_lock(&device_client->lock);
+	spin_lock_irqsave(&device_client->lock, flags);
 
 	/* while waiting for the lock the device_client could have been
 	 * deleted */
 	if (!device_client_hash[icmp_packet->uid]) {
-		spin_unlock(&device_client->lock);
+		spin_unlock_irqrestore(&device_client->lock, flags);
 		kfree(device_packet);
 		return;
 	}
@@ -323,7 +333,7 @@ void bat_device_add_packet(struct device
 		device_client->queue_len--;
 	}
 
-	spin_unlock(&device_client->lock);
+	spin_unlock_irqrestore(&device_client->lock, flags);
 
 	wake_up(&device_client->queue_wait);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/hard-interface.c linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/hard-interface.c
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/hard-interface.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/hard-interface.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,13 +21,11 @@
 
 #include "main.h"
 #include "hard-interface.h"
-#include "log.h"
 #include "soft-interface.h"
 #include "send.h"
 #include "translation-table.h"
 #include "routing.h"
 #include "hash.h"
-#include "compat.h"
 
 #define MIN(x, y) ((x) < (y) ? (x) : (y))
 
@@ -75,7 +73,6 @@ int hardif_min_mtu(void)
 static void check_known_mac_addr(uint8_t *addr)
 {
 	struct batman_if *batman_if;
-	char mac_string[ETH_STR_LEN];
 
 	rcu_read_lock();
 	list_for_each_entry_rcu(batman_if, &if_list, list) {
@@ -86,10 +83,9 @@ static void check_known_mac_addr(uint8_t
 		if (!compare_orig(batman_if->net_dev->dev_addr, addr))
 			continue;
 
-		addr_to_string(mac_string, addr);
-		debug_log(LOG_TYPE_WARN, "The newly added mac address (%s) already exists on: %s\n",
-		          mac_string, batman_if->dev);
-		debug_log(LOG_TYPE_WARN, "It is strongly recommended to keep mac addresses unique to avoid problems!\n");
+		printk(KERN_WARNING "batman-adv:The newly added mac address (%pM) already exists on: %s\n",
+		       addr, batman_if->dev);
+		printk(KERN_WARNING "batman-adv:It is strongly recommended to keep mac addresses unique to avoid problems!\n");
 	}
 	rcu_read_unlock();
 }
@@ -154,9 +150,6 @@ void hardif_deactivate_interface(struct
 	if (batman_if->if_active != IF_ACTIVE)
 		return;
 
-	if (batman_if->raw_sock)
-		sock_release(batman_if->raw_sock);
-
 	/**
 	 * batman_if->net_dev has been acquired by dev_get_by_name() in
 	 * proc_interfaces_write() and has to be unreferenced.
@@ -165,22 +158,16 @@ void hardif_deactivate_interface(struct
 	if (batman_if->net_dev)
 		dev_put(batman_if->net_dev);
 
-	batman_if->raw_sock = NULL;
-	batman_if->net_dev = NULL;
-
 	batman_if->if_active = IF_INACTIVE;
 	active_ifs--;
 
-	debug_log(LOG_TYPE_NOTICE, "Interface deactivated: %s\n",
-	          batman_if->dev);
+	printk(KERN_INFO "batman-adv:Interface deactivated: %s\n",
+		  batman_if->dev);
 }
 
 /* (re)activate given interface. */
 static void hardif_activate_interface(struct batman_if *batman_if)
 {
-	struct sockaddr_ll bind_addr;
-	int retval;
-
 	if (batman_if->if_active != IF_INACTIVE)
 		return;
 
@@ -192,35 +179,8 @@ static void hardif_activate_interface(st
 	if (!batman_if->net_dev)
 		goto dev_err;
 
-	retval = sock_create_kern(PF_PACKET, SOCK_RAW,
-				  __constant_htons(ETH_P_BATMAN),
-				  &batman_if->raw_sock);
-
-	if (retval < 0) {
-		debug_log(LOG_TYPE_WARN, "Can't create raw socket: %i\n",
-			  retval);
-		goto sock_err;
-	}
-
-	bind_addr.sll_family = AF_PACKET;
-	bind_addr.sll_ifindex = batman_if->net_dev->ifindex;
-	bind_addr.sll_protocol = 0;	/* is set by the kernel */
-
-	retval = kernel_bind(batman_if->raw_sock,
-			     (struct sockaddr *)&bind_addr, sizeof(bind_addr));
-
-	if (retval < 0) {
-		debug_log(LOG_TYPE_WARN, "Can't create bind raw socket: %i\n",
-			  retval);
-		goto bind_err;
-	}
-
 	check_known_mac_addr(batman_if->net_dev->dev_addr);
 
-	batman_if->raw_sock->sk->sk_user_data =
-		batman_if->raw_sock->sk->sk_data_ready;
-	batman_if->raw_sock->sk->sk_data_ready = batman_data_ready;
-
 	addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr);
 
 	memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig,
@@ -235,17 +195,12 @@ static void hardif_activate_interface(st
 	if (batman_if->if_num == 0)
 		set_main_if_addr(batman_if->net_dev->dev_addr);
 
-	debug_log(LOG_TYPE_NOTICE, "Interface activated: %s\n",
-	          batman_if->dev);
+	printk(KERN_INFO "batman-adv:Interface activated: %s\n",
+		  batman_if->dev);
 
 	return;
 
-bind_err:
-	sock_release(batman_if->raw_sock);
-sock_err:
-	dev_put(batman_if->net_dev);
 dev_err:
-	batman_if->raw_sock = NULL;
 	batman_if->net_dev = NULL;
 }
 
@@ -290,7 +245,7 @@ static int resize_orig(struct orig_node
 	data_ptr = kmalloc((if_num + 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS,
 			   GFP_ATOMIC);
 	if (!data_ptr) {
-		debug_log(LOG_TYPE_WARN, "Can't resize orig: out of memory\n");
+		printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n");
 		return -1;
 	}
 
@@ -301,7 +256,7 @@ static int resize_orig(struct orig_node
 
 	data_ptr = kmalloc((if_num + 1) * sizeof(uint8_t), GFP_ATOMIC);
 	if (!data_ptr) {
-		debug_log(LOG_TYPE_WARN, "Can't resize orig: out of memory\n");
+		printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n");
 		return -1;
 	}
 
@@ -319,16 +274,16 @@ int hardif_add_interface(char *dev, int
 	struct batman_if *batman_if;
 	struct batman_packet *batman_packet;
 	struct orig_node *orig_node;
-	struct hash_it_t *hashit = NULL;
+	unsigned long flags;
+	HASHIT(hashit);
 
 	batman_if = kmalloc(sizeof(struct batman_if), GFP_KERNEL);
 
 	if (!batman_if) {
-		debug_log(LOG_TYPE_WARN, "Can't add interface (%s): out of memory\n", dev);
+		printk(KERN_ERR "batman-adv:Can't add interface (%s): out of memory\n", dev);
 		return -1;
 	}
 
-	batman_if->raw_sock = NULL;
 	batman_if->net_dev = NULL;
 
 	if ((if_num == 0) && (num_hna > 0))
@@ -339,7 +294,7 @@ int hardif_add_interface(char *dev, int
 	batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_KERNEL);
 
 	if (!batman_if->packet_buff) {
-		debug_log(LOG_TYPE_WARN, "Can't add interface packet (%s): out of memory\n", dev);
+		printk(KERN_ERR "batman-adv:Can't add interface packet (%s): out of memory\n", dev);
 		goto out;
 	}
 
@@ -348,7 +303,7 @@ int hardif_add_interface(char *dev, int
 	batman_if->if_active = IF_INACTIVE;
 	INIT_RCU_HEAD(&batman_if->rcu);
 
-	debug_log(LOG_TYPE_NOTICE, "Adding interface: %s\n", dev);
+	printk(KERN_INFO "batman-adv:Adding interface: %s\n", dev);
 	avail_ifs++;
 
 	INIT_LIST_HEAD(&batman_if->list);
@@ -376,20 +331,20 @@ int hardif_add_interface(char *dev, int
 
 	/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
 	 * if_num */
-	spin_lock(&orig_hash_lock);
+	spin_lock_irqsave(&orig_hash_lock, flags);
 
-	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
-		orig_node = hashit->bucket->data;
+	while (hash_iterate(orig_hash, &hashit)) {
+		orig_node = hashit.bucket->data;
 		if (resize_orig(orig_node, if_num) == -1) {
-			spin_unlock(&orig_hash_lock);
+			spin_unlock_irqrestore(&orig_hash_lock, flags);
 			goto out;
 		}
 	}
 
-	spin_unlock(&orig_hash_lock);
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
 
 	if (!hardif_is_interface_up(batman_if->dev))
-		debug_log(LOG_TYPE_WARN, "Not using interface %s (retrying later): interface not active\n", batman_if->dev);
+		printk(KERN_ERR "batman-adv:Not using interface %s (retrying later): interface not active\n", batman_if->dev);
 	else
 		hardif_activate_interface(batman_if);
 
@@ -400,8 +355,7 @@ int hardif_add_interface(char *dev, int
 	return 1;
 
 out:
-	if (batman_if->packet_buff)
-		kfree(batman_if->packet_buff);
+	kfree(batman_if->packet_buff);
 	kfree(batman_if);
 	kfree(dev);
 	return -1;
@@ -413,7 +367,7 @@ char hardif_get_active_if_num(void)
 }
 
 static int hard_if_event(struct notifier_block *this,
-                            unsigned long event, void *ptr)
+			    unsigned long event, void *ptr)
 {
 	struct net_device *dev = (struct net_device *)ptr;
 	struct batman_if *batman_if = get_batman_if_by_name(dev->name);
@@ -436,7 +390,6 @@ static int hard_if_event(struct notifier
 		break;
 	/* NETDEV_CHANGEADDR - mac address change - what are we doing here ? */
 	default:
-		/* debug_log(LOG_TYPE_CRIT, "hard_if_event: %s %i\n", dev->name, event); */
 		break;
 	};
 
@@ -446,6 +399,122 @@ out:
 	return NOTIFY_DONE;
 }
 
+/* find batman interface by netdev. assumes rcu_read_lock on */
+static struct batman_if *find_batman_if(struct net_device *dev)
+{
+	struct batman_if *batman_if;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(batman_if, &if_list, list) {
+		if (batman_if->net_dev == dev) {
+			rcu_read_unlock();
+			return batman_if;
+		}
+	}
+	rcu_read_unlock();
+	return NULL;
+}
+
+
+/* receive a packet with the batman ethertype coming on a hard
+ * interface */
+int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
+	struct packet_type *ptype, struct net_device *orig_dev)
+{
+	struct batman_packet *batman_packet;
+	struct batman_if *batman_if;
+	struct net_device_stats *stats;
+	int ret;
+
+	skb = skb_share_check(skb, GFP_ATOMIC);
+
+	/* skb was released by skb_share_check() */
+	if (!skb)
+		goto err_out;
+
+	if (atomic_read(&module_state) != MODULE_ACTIVE)
+		goto err_free;
+
+	/* packet should hold at least type and version */
+	if (unlikely(skb_headlen(skb) < 2))
+		goto err_free;
+
+	/* expect a valid ethernet header here. */
+	if (unlikely(skb->mac_len != sizeof(struct ethhdr)
+				|| !skb_mac_header(skb)))
+		goto err_free;
+
+	batman_if = find_batman_if(skb->dev);
+	if (!batman_if)
+		goto err_free;
+
+	/* discard frames on not active interfaces */
+	if (batman_if->if_active != IF_ACTIVE)
+		goto err_free;
+
+	stats = (struct net_device_stats *)dev_get_stats(skb->dev);
+	if (stats) {
+		stats->rx_packets++;
+		stats->rx_bytes += skb->len;
+	}
+
+	batman_packet = (struct batman_packet *)skb->data;
+
+	if (batman_packet->version != COMPAT_VERSION) {
+		bat_dbg(DBG_BATMAN,
+			"Drop packet: incompatible batman version (%i)\n",
+			batman_packet->version);
+		goto err_free;
+	}
+
+	/* all receive handlers return whether they received or reused
+	 * the supplied skb. if not, we have to free the skb. */
+
+	switch (batman_packet->packet_type) {
+		/* batman originator packet */
+	case BAT_PACKET:
+		ret = recv_bat_packet(skb, batman_if);
+		break;
+
+		/* batman icmp packet */
+	case BAT_ICMP:
+		ret = recv_icmp_packet(skb);
+		break;
+
+		/* unicast packet */
+	case BAT_UNICAST:
+		ret = recv_unicast_packet(skb);
+		break;
+
+		/* broadcast packet */
+	case BAT_BCAST:
+		ret = recv_bcast_packet(skb);
+		break;
+
+		/* vis packet */
+	case BAT_VIS:
+		ret = recv_vis_packet(skb);
+		break;
+	default:
+		ret = NET_RX_DROP;
+	}
+
+	if (ret == NET_RX_DROP)
+		kfree_skb(skb);
+
+	/* return NET_RX_SUCCESS in any case as we
+	 * most probably dropped the packet for
+	 * routing-logical reasons. */
+
+	return NET_RX_SUCCESS;
+
+err_free:
+	kfree_skb(skb);
+err_out:
+	return NET_RX_DROP;
+}
+
+
 struct notifier_block hard_if_notifier = {
-        .notifier_call = hard_if_event,
+	.notifier_call = hard_if_event,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/hard-interface.h linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/hard-interface.h
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/hard-interface.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/hard-interface.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,5 +32,9 @@ void hardif_deactivate_interface(struct
 char hardif_get_active_if_num(void);
 void hardif_check_interfaces_status(void);
 void hardif_check_interfaces_status_wq(struct work_struct *work);
+int batman_skb_recv(struct sk_buff *skb,
+				struct net_device *dev,
+				struct packet_type *ptype,
+				struct net_device *orig_dev);
 int hardif_min_mtu(void);
 void update_min_mtu(void);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/hash.c linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/hash.c
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/hash.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/hash.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,24 +64,18 @@ void hash_destroy(struct hashtable_t *ha
 	kfree(hash);
 }
 
-/* iterate though the hash. first element is selected with iter_in NULL.  use
- * the returned iterator to access the elements until hash_it_t returns NULL. */
+/* iterate though the hash. First element is selected if an iterator
+ * initialized with HASHIT() is supplied as iter. Use the returned
+ * (or supplied) iterator to access the elements until hash_iterate returns
+ * NULL. */
+
 struct hash_it_t *hash_iterate(struct hashtable_t *hash,
-			       struct hash_it_t *iter_in)
+			       struct hash_it_t *iter)
 {
-	struct hash_it_t *iter;
-
 	if (!hash)
 		return NULL;
-
-	if (iter_in == NULL) {
-		iter = kmalloc(sizeof(struct hash_it_t), GFP_ATOMIC);
-		iter->index = -1;
-		iter->bucket = NULL;
-		iter->prev_bucket = NULL;
-	} else {
-		iter = iter_in;
-	}
+	if (!iter)
+		return NULL;
 
 	/* sanity checks first (if our bucket got deleted in the last
 	 * iteration): */
@@ -139,7 +133,6 @@ struct hash_it_t *hash_iterate(struct ha
 	}
 
 	/* nothing to iterate over anymore */
-	kfree(iter);
 	return NULL;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/hash.h linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/hash.h
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/hash.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/hash.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,11 @@
 
 #ifndef _BATMAN_HASH_H
 #define _BATMAN_HASH_H
+#define HASHIT(name) struct hash_it_t name = { \
+		.index = -1, .bucket = NULL, \
+		.prev_bucket = NULL, \
+		.first_bucket = NULL }
+
 
 typedef int (*hashdata_compare_cb)(void *, void *);
 typedef int (*hashdata_choose_cb)(void *, int);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
 
 config BATMAN_ADV
 	tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
-	depends on PROC_FS && PACKET
+	depends on PROC_FS && NET
         default n
 	---help---
 
@@ -14,10 +14,10 @@ config BATMAN_ADV
         http://www.open-mesh.org/ for more information and user space
         tools.
 
-config BATMAN_DEBUG
+config BATMAN_ADV_DEBUG
 	bool "B.A.T.M.A.N. debugging"
 	depends on BATMAN_ADV != n
-	help
+	---help---
 
 	  This is an option for use by developers; most people should
 	  say N here. This enables compilation of support for
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/log.c linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/log.c
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/log.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/log.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner, Simon Wunderlich
- *
- * 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-1301, USA
- *
- */
-
-#include "main.h"
-#include "log.h"
-
-#define LOG_BUF_MASK (log_buf_len-1)
-#define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK])
-
-static char log_buf[LOG_BUF_LEN];
-static int log_buf_len = LOG_BUF_LEN;
-static unsigned long log_start;
-static unsigned long log_end;
-uint8_t log_level;
-
-static DEFINE_SPINLOCK(logbuf_lock);
-
-const struct file_operations proc_log_operations = {
-	.open           = log_open,
-	.release        = log_release,
-	.read           = log_read,
-	.write          = log_write,
-	.poll           = log_poll,
-};
-
-static DECLARE_WAIT_QUEUE_HEAD(log_wait);
-
-static void emit_log_char(char c)
-{
-	LOG_BUF(log_end) = c;
-	log_end++;
-
-	if (log_end - log_start > log_buf_len)
-		log_start = log_end - log_buf_len;
-}
-
-static int fdebug_log(char *fmt, ...)
-{
-	int printed_len;
-	char *p;
-	va_list args;
-	static char debug_log_buf[256];
-	unsigned long flags;
-
-	spin_lock_irqsave(&logbuf_lock, flags);
-	va_start(args, fmt);
-	printed_len = vscnprintf(debug_log_buf, sizeof(debug_log_buf), fmt,
-				 args);
-	va_end(args);
-
-	for (p = debug_log_buf; *p != 0; p++)
-		emit_log_char(*p);
-
-	spin_unlock_irqrestore(&logbuf_lock, flags);
-
-	wake_up(&log_wait);
-
-	return 0;
-}
-
-int debug_log(int type, char *fmt, ...)
-{
-	va_list args;
-	int retval = 0;
-	char tmp_log_buf[256];
-
-	/* only critical information get into the official kernel log */
-	if (type == LOG_TYPE_CRIT) {
-		va_start(args, fmt);
-		vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
-		printk(KERN_ERR "batman-adv: %s", tmp_log_buf);
-		va_end(args);
-	}
-
-	if ((type == LOG_TYPE_CRIT) || (log_level & type)) {
-		va_start(args, fmt);
-		vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
-		fdebug_log("[%10u] %s", (jiffies / HZ), tmp_log_buf);
-		va_end(args);
-	}
-
-	return retval;
-}
-
-int log_open(struct inode *inode, struct file *file)
-{
-	inc_module_count();
-	return 0;
-}
-
-int log_release(struct inode *inode, struct file *file)
-{
-	dec_module_count();
-	return 0;
-}
-
-ssize_t log_read(struct file *file, char __user *buf, size_t count,
-		 loff_t *ppos)
-{
-	int error, i = 0;
-	char c;
-	unsigned long flags;
-
-	if ((file->f_flags & O_NONBLOCK) && !(log_end - log_start))
-		return -EAGAIN;
-
-	if ((!buf) || (count < 0))
-		return -EINVAL;
-
-	if (count == 0)
-		return 0;
-
-	if (!access_ok(VERIFY_WRITE, buf, count))
-		return -EFAULT;
-
-	error = wait_event_interruptible(log_wait, (log_start - log_end));
-
-	if (error)
-		return error;
-
-	spin_lock_irqsave(&logbuf_lock, flags);
-
-	while ((!error) && (log_start != log_end) && (i < count)) {
-		c = LOG_BUF(log_start);
-
-		log_start++;
-
-		spin_unlock_irqrestore(&logbuf_lock, flags);
-
-		error = __put_user(c, buf);
-
-		spin_lock_irqsave(&logbuf_lock, flags);
-
-		buf++;
-		i++;
-
-	}
-
-	spin_unlock_irqrestore(&logbuf_lock, flags);
-
-	if (!error)
-		return i;
-
-	return error;
-}
-
-ssize_t log_write(struct file *file, const char __user *buf, size_t count,
-		  loff_t *ppos)
-{
-	return count;
-}
-
-unsigned int log_poll(struct file *file, poll_table *wait)
-{
-	poll_wait(file, &log_wait, wait);
-
-	if (log_end - log_start)
-		return POLLIN | POLLRDNORM;
-
-	return 0;
-}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/log.h linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/log.h
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/log.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/log.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner, Simon Wunderlich
- *
- * 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-1301, USA
- *
- */
-
-extern const struct file_operations proc_log_operations;
-extern uint8_t log_level;
-
-int debug_log(int type, char *fmt, ...);
-int log_open(struct inode *inode, struct file *file);
-int log_release(struct inode *inode, struct file *file);
-ssize_t log_read(struct file *file, char __user *buf, size_t count,
-		 loff_t *ppos);
-ssize_t log_write(struct file *file, const char __user *buf, size_t count,
-		  loff_t *ppos);
-unsigned int log_poll(struct file *file, poll_table *wait);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/main.c linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/main.c
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/main.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,9 +21,9 @@
 
 #include "main.h"
 #include "proc.h"
-#include "log.h"
 #include "routing.h"
 #include "send.h"
+#include "originator.h"
 #include "soft-interface.h"
 #include "device.h"
 #include "translation-table.h"
@@ -31,7 +31,6 @@
 #include "types.h"
 #include "vis.h"
 #include "hash.h"
-#include "compat.h"
 
 struct list_head if_list;
 struct hlist_head forw_bat_list;
@@ -44,19 +43,34 @@ DEFINE_SPINLOCK(forw_bcast_list_lock);
 
 atomic_t originator_interval;
 atomic_t vis_interval;
+atomic_t vis_mode;
 atomic_t aggregation_enabled;
 int16_t num_hna;
 int16_t num_ifs;
 
 struct net_device *soft_device;
 
-static struct task_struct *kthread_task;
-
 unsigned char broadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 atomic_t module_state;
 
+static struct packet_type batman_adv_packet_type __read_mostly = {
+	.type = __constant_htons(ETH_P_BATMAN),
+	.func = batman_skb_recv,
+};
+
 struct workqueue_struct *bat_event_workqueue;
 
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+int debug;
+
+module_param(debug, int, 0644);
+
+int bat_debug_type(int type)
+{
+	return debug & type;
+}
+#endif
+
 int init_module(void)
 {
 	int retval;
@@ -70,6 +84,7 @@ int init_module(void)
 	atomic_set(&originator_interval, 1000);
 	atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
 					 * for debugging now. */
+	atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE);
 	atomic_set(&aggregation_enabled, 1);
 
 	/* the name should not be longer than 10 chars - see
@@ -90,21 +105,22 @@ int init_module(void)
 				   interface_setup);
 
 	if (!soft_device) {
-		debug_log(LOG_TYPE_CRIT, "Unable to allocate the batman interface\n");
+		printk(KERN_ERR "batman-adv:Unable to allocate the batman interface\n");
 		goto end;
 	}
 
 	retval = register_netdev(soft_device);
 
 	if (retval < 0) {
-		debug_log(LOG_TYPE_CRIT, "Unable to register the batman interface: %i\n", retval);
+		printk(KERN_ERR "batman-adv:Unable to register the batman interface: %i\n", retval);
 		goto free_soft_device;
 	}
 
 	register_netdevice_notifier(&hard_if_notifier);
+	dev_add_pack(&batman_adv_packet_type);
 
-	debug_log(LOG_TYPE_CRIT, "B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded \n",
-	          SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION);
+	printk(KERN_INFO "batman-adv:B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded \n",
+		  SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION);
 
 	return 0;
 
@@ -124,6 +140,8 @@ void cleanup_module(void)
 		soft_device = NULL;
 	}
 
+	dev_remove_pack(&batman_adv_packet_type);
+
 	unregister_netdevice_notifier(&hard_if_notifier);
 	cleanup_procfs();
 
@@ -151,22 +169,12 @@ void activate_module(void)
 	if (vis_init() < 1)
 		goto err;
 
-	/* (re)start kernel thread for packet processing */
-	if (!kthread_task) {
-		kthread_task = kthread_run(packet_recv_thread, NULL, "batman-adv");
-
-		if (IS_ERR(kthread_task)) {
-			debug_log(LOG_TYPE_CRIT, "Unable to start packet receive thread\n");
-			kthread_task = NULL;
-		}
-	}
-
 	update_min_mtu();
 	atomic_set(&module_state, MODULE_ACTIVE);
 	goto end;
 
 err:
-	debug_log(LOG_TYPE_CRIT, "Unable to allocate memory for mesh information structures: out of mem ?\n");
+	printk(KERN_ERR "batman-adv:Unable to allocate memory for mesh information structures: out of mem ?\n");
 	shutdown_module();
 end:
 	return;
@@ -182,14 +190,7 @@ void shutdown_module(void)
 
 	vis_quit();
 
-	/* deactivate kernel thread for packet processing (if running) */
-	if (kthread_task) {
-		atomic_set(&exit_cond, 1);
-		wake_up_interruptible(&thread_wait);
-		kthread_stop(kthread_task);
-
-		kthread_task = NULL;
-	}
+	/* TODO: unregister BATMAN pack */
 
 	originator_free();
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/main.h linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/main.h
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/main.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/main.h	2010-05-16 17:17:36.000000000 -0400
@@ -33,16 +33,16 @@
 
 #define TQ_MAX_VALUE 255
 #define JITTER 20
-#define TTL 50		          /* Time To Live of broadcast messages */
-#define MAX_ADDR 16	          /* number of interfaces which can be added to
+#define TTL 50			  /* Time To Live of broadcast messages */
+#define MAX_ADDR 16		  /* number of interfaces which can be added to
 				   * batman. */
 
-#define PURGE_TIMEOUT 200000      /* purge originators after time in ms if no
+#define PURGE_TIMEOUT 200000	  /* purge originators after time in ms if no
 				   * valid packet comes in -> TODO: check
 				   * influence on TQ_LOCAL_WINDOW_SIZE */
 #define LOCAL_HNA_TIMEOUT 3600000
 
-#define TQ_LOCAL_WINDOW_SIZE 64   /* sliding packet range of received originator
+#define TQ_LOCAL_WINDOW_SIZE 64	  /* sliding packet range of received originator
 				   * messages in squence numbers (should be a
 				   * multiple of our word size) */
 #define TQ_GLOBAL_WINDOW_SIZE 5
@@ -69,24 +69,27 @@
 
 
 /*
- * Logging
+ * Debug Messages
  */
 
-#define LOG_TYPE_CRIT 0		/* highest priority for fatal errors such as
-				 * blocked sockets / failed packet delivery /
-				 * programming errors */
-#define LOG_TYPE_WARN 1		/* warnings for small errors like wrong user
-				 * input / damaged packets / etc */
-#define LOG_TYPE_NOTICE 2	/* notice information for new interfaces /
-				 * changed settings / new originators / etc */
-#define LOG_TYPE_BATMAN 4	/* all messages related to routing / flooding /
-				 * broadcasting / etc */
-#define LOG_TYPE_ROUTES 8	/* route or hna added / changed / deleted */
-#define LOG_TYPE_CRIT_NAME	"critical"
-#define LOG_TYPE_WARN_NAME	"warnings"
-#define LOG_TYPE_NOTICE_NAME	"notices"
-#define LOG_TYPE_BATMAN_NAME	"batman"
-#define LOG_TYPE_ROUTES_NAME	"routes"
+#define DBG_BATMAN 1	/* all messages related to routing / flooding /
+			 * broadcasting / etc */
+#define DBG_ROUTES 2	/* route or hna added / changed / deleted */
+
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+extern int debug;
+
+extern int bat_debug_type(int type);
+#define bat_dbg(type, fmt, arg...) do {					\
+		if (bat_debug_type(type))				\
+			printk(KERN_DEBUG "batman-adv:" fmt, ## arg);	\
+	}								\
+	while (0)
+#else /* !CONFIG_BATMAN_ADV_DEBUG */
+#define bat_dbg(type, fmt, arg...) do {		\
+	}					\
+	while (0)
+#endif
 
 /*
  *  Vis
@@ -106,6 +109,7 @@
 #include <linux/kthread.h>	/* kernel threads */
 #include <linux/pkt_sched.h>	/* schedule types */
 #include <linux/workqueue.h>	/* workqueue */
+#include <linux/slab.h>
 #include <net/sock.h>		/* struct sock */
 #include <linux/jiffies.h>
 #include "types.h"
@@ -127,6 +131,7 @@ extern spinlock_t forw_bcast_list_lock;
 
 extern atomic_t originator_interval;
 extern atomic_t vis_interval;
+extern atomic_t vis_mode;
 extern atomic_t aggregation_enabled;
 extern int16_t num_hna;
 extern int16_t num_ifs;
@@ -147,5 +152,3 @@ int choose_orig(void *data, int32_t size
 int is_my_mac(uint8_t *addr);
 int is_bcast(uint8_t *addr);
 int is_mcast(uint8_t *addr);
-
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/Makefile linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -19,4 +19,4 @@
 #
 
 obj-m += batman-adv.o
-batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o log.o
+batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/originator.c linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/originator.c
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/originator.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/originator.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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-1301, USA
+ *
+ */
+
+/* increase the reference counter for this originator */
+
+#include "main.h"
+#include "originator.h"
+#include "hash.h"
+#include "translation-table.h"
+#include "routing.h"
+
+static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig);
+
+static void start_purge_timer(void)
+{
+	queue_delayed_work(bat_event_workqueue, &purge_orig_wq, 1 * HZ);
+}
+
+int originator_init(void)
+{
+	unsigned long flags;
+	if (orig_hash)
+		return 1;
+
+	spin_lock_irqsave(&orig_hash_lock, flags);
+	orig_hash = hash_new(128, compare_orig, choose_orig);
+
+	if (!orig_hash)
+		goto err;
+
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
+	start_purge_timer();
+	return 1;
+
+err:
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
+	return 0;
+}
+
+void originator_free(void)
+{
+	unsigned long flags;
+
+	if (!orig_hash)
+		return;
+
+	cancel_delayed_work_sync(&purge_orig_wq);
+
+	spin_lock_irqsave(&orig_hash_lock, flags);
+	hash_delete(orig_hash, free_orig_node);
+	orig_hash = NULL;
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
+}
+
+struct neigh_node *
+create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
+		uint8_t *neigh, struct batman_if *if_incoming)
+{
+	struct neigh_node *neigh_node;
+
+	bat_dbg(DBG_BATMAN, "Creating new last-hop neighbor of originator\n");
+
+	neigh_node = kzalloc(sizeof(struct neigh_node), GFP_ATOMIC);
+	if (!neigh_node)
+		return NULL;
+
+	INIT_LIST_HEAD(&neigh_node->list);
+
+	memcpy(neigh_node->addr, neigh, ETH_ALEN);
+	neigh_node->orig_node = orig_neigh_node;
+	neigh_node->if_incoming = if_incoming;
+
+	list_add_tail(&neigh_node->list, &orig_node->neigh_list);
+	return neigh_node;
+}
+
+void free_orig_node(void *data)
+{
+	struct list_head *list_pos, *list_pos_tmp;
+	struct neigh_node *neigh_node;
+	struct orig_node *orig_node = (struct orig_node *)data;
+
+	/* for all neighbors towards this originator ... */
+	list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
+		neigh_node = list_entry(list_pos, struct neigh_node, list);
+
+		list_del(list_pos);
+		kfree(neigh_node);
+	}
+
+	hna_global_del_orig(orig_node, "originator timed out");
+
+	kfree(orig_node->bcast_own);
+	kfree(orig_node->bcast_own_sum);
+	kfree(orig_node);
+}
+
+/* this function finds or creates an originator entry for the given
+ * address if it does not exits */
+struct orig_node *get_orig_node(uint8_t *addr)
+{
+	struct orig_node *orig_node;
+	struct hashtable_t *swaphash;
+	int size;
+
+	orig_node = ((struct orig_node *)hash_find(orig_hash, addr));
+
+	if (orig_node != NULL)
+		return orig_node;
+
+	bat_dbg(DBG_BATMAN, "Creating new originator: %pM \n", addr);
+
+	orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC);
+	if (!orig_node)
+		return NULL;
+
+	INIT_LIST_HEAD(&orig_node->neigh_list);
+
+	memcpy(orig_node->orig, addr, ETH_ALEN);
+	orig_node->router = NULL;
+	orig_node->batman_if = NULL;
+	orig_node->hna_buff = NULL;
+
+	size = num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS;
+
+	orig_node->bcast_own = kzalloc(size, GFP_ATOMIC);
+	if (!orig_node->bcast_own)
+		goto free_orig_node;
+
+	size = num_ifs * sizeof(uint8_t);
+	orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC);
+	if (!orig_node->bcast_own_sum)
+		goto free_bcast_own;
+
+	if (hash_add(orig_hash, orig_node) < 0)
+		goto free_bcast_own_sum;
+
+	if (orig_hash->elements * 4 > orig_hash->size) {
+		swaphash = hash_resize(orig_hash, orig_hash->size * 2);
+
+		if (swaphash == NULL)
+			printk(KERN_ERR
+			       "batman-adv:Couldn't resize orig hash table \n");
+		else
+			orig_hash = swaphash;
+	}
+
+	return orig_node;
+free_bcast_own_sum:
+	kfree(orig_node->bcast_own_sum);
+free_bcast_own:
+	kfree(orig_node->bcast_own);
+free_orig_node:
+	kfree(orig_node);
+	return NULL;
+}
+
+static bool purge_orig_neighbors(struct orig_node *orig_node,
+				 struct neigh_node **best_neigh_node)
+{
+	struct list_head *list_pos, *list_pos_tmp;
+	struct neigh_node *neigh_node;
+	bool neigh_purged = false;
+
+	*best_neigh_node = NULL;
+
+
+	/* for all neighbors towards this originator ... */
+	list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
+		neigh_node = list_entry(list_pos, struct neigh_node, list);
+
+		if (time_after(jiffies,
+			       (neigh_node->last_valid +
+				((PURGE_TIMEOUT * HZ) / 1000)))) {
+
+			bat_dbg(DBG_BATMAN, "neighbor timeout: originator %pM, neighbor: %pM, last_valid %lu\n", orig_node->orig, neigh_node->addr, (neigh_node->last_valid / HZ));
+
+			neigh_purged = true;
+			list_del(list_pos);
+			kfree(neigh_node);
+		} else {
+			if ((*best_neigh_node == NULL) ||
+			    (neigh_node->tq_avg > (*best_neigh_node)->tq_avg))
+				*best_neigh_node = neigh_node;
+		}
+	}
+	return neigh_purged;
+}
+
+
+static bool purge_orig_node(struct orig_node *orig_node)
+{
+	struct neigh_node *best_neigh_node;
+
+	if (time_after(jiffies,
+		       (orig_node->last_valid +
+			((2 * PURGE_TIMEOUT * HZ) / 1000)))) {
+
+		bat_dbg(DBG_BATMAN,
+			"Originator timeout: originator %pM, last_valid %lu\n",
+			orig_node->orig, (orig_node->last_valid / HZ));
+		return true;
+	} else {
+		if (purge_orig_neighbors(orig_node, &best_neigh_node))
+			update_routes(orig_node, best_neigh_node,
+				      orig_node->hna_buff,
+				      orig_node->hna_buff_len);
+	}
+	return false;
+}
+
+void purge_orig(struct work_struct *work)
+{
+	HASHIT(hashit);
+	struct orig_node *orig_node;
+	unsigned long flags;
+
+	spin_lock_irqsave(&orig_hash_lock, flags);
+
+	/* for all origins... */
+	while (hash_iterate(orig_hash, &hashit)) {
+		orig_node = hashit.bucket->data;
+		if (purge_orig_node(orig_node)) {
+			hash_remove_bucket(orig_hash, &hashit);
+			free_orig_node(orig_node);
+		}
+	}
+
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
+
+	start_purge_timer();
+}
+
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/originator.h linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/originator.h
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/originator.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/originator.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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-1301, USA
+ *
+ */
+
+int originator_init(void);
+void free_orig_node(void *data);
+void originator_free(void);
+void purge_orig(struct work_struct *work);
+struct orig_node *orig_find(char *mac);
+struct orig_node *get_orig_node(uint8_t *addr);
+struct neigh_node *
+create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
+		uint8_t *neigh, struct batman_if *if_incoming);
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/packet.h linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/packet.h
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/packet.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/packet.h	2010-05-16 17:17:36.000000000 -0400
@@ -90,7 +90,7 @@ struct vis_packet {
 	uint8_t  entries;	 /* number of entries behind this struct */
 	uint8_t  ttl;		 /* TTL */
 	uint8_t  vis_orig[6];	 /* originator that informs about its
-				  * neighbours */
+				  * neighbors */
 	uint8_t  target_orig[6]; /* who should receive this packet */
 	uint8_t  sender_orig[6]; /* who sent or rebroadcasted this packet */
 } __attribute__((packed));
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/proc.c linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/proc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/proc.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,23 +21,18 @@
 
 #include "main.h"
 #include "proc.h"
-#include "log.h"
 #include "routing.h"
 #include "translation-table.h"
 #include "hard-interface.h"
 #include "types.h"
 #include "hash.h"
 #include "vis.h"
-#include "compat.h"
-
-static uint8_t vis_format = DOT_DRAW;
 
 static struct proc_dir_entry *proc_batman_dir, *proc_interface_file;
 static struct proc_dir_entry *proc_orig_interval_file, *proc_originators_file;
-static struct proc_dir_entry *proc_log_file, *proc_log_level_file;
 static struct proc_dir_entry *proc_transt_local_file;
 static struct proc_dir_entry *proc_transt_global_file;
-static struct proc_dir_entry *proc_vis_file, *proc_vis_format_file;
+static struct proc_dir_entry *proc_vis_srv_file, *proc_vis_data_file;
 static struct proc_dir_entry *proc_aggr_file;
 
 static int proc_interfaces_read(struct seq_file *seq, void *offset)
@@ -68,7 +63,7 @@ static ssize_t proc_interfaces_write(str
 				     size_t count, loff_t *data)
 {
 	char *if_string, *colon_ptr = NULL, *cr_ptr = NULL;
-	int not_copied = 0, if_num = 0;
+	int not_copied = 0, if_num = 0, add_success;
 	struct batman_if *batman_if = NULL;
 
 	if_string = kmalloc(count, GFP_KERNEL);
@@ -77,8 +72,7 @@ static ssize_t proc_interfaces_write(str
 		return -ENOMEM;
 
 	if (count > IFNAMSIZ - 1) {
-		debug_log(LOG_TYPE_WARN,
-			  "Can't add interface: device name is too long\n");
+		printk(KERN_WARNING "batman-adv:Can't add interface: device name is too long\n");
 		goto end;
 	}
 
@@ -105,7 +99,7 @@ static ssize_t proc_interfaces_write(str
 	rcu_read_lock();
 	list_for_each_entry_rcu(batman_if, &if_list, list) {
 		if (strncmp(batman_if->dev, if_string, count) == 0) {
-			debug_log(LOG_TYPE_WARN, "Given interface is already active: %s\n", if_string);
+			printk(KERN_ERR "batman-adv:Given interface is already active: %s\n", if_string);
 			rcu_read_unlock();
 			goto end;
 
@@ -115,22 +109,17 @@ static ssize_t proc_interfaces_write(str
 	}
 	rcu_read_unlock();
 
-	hardif_add_interface(if_string, if_num);
+	add_success = hardif_add_interface(if_string, if_num);
+	if (add_success < 0)
+		goto end;
+
+	num_ifs = if_num + 1;
 
 	if ((atomic_read(&module_state) == MODULE_INACTIVE) &&
 	    (hardif_get_active_if_num() > 0))
 		activate_module();
 
-	rcu_read_lock();
-	if (list_empty(&if_list)) {
-		rcu_read_unlock();
-		goto end;
-	}
-	rcu_read_unlock();
-
-	num_ifs = if_num + 1;
 	return count;
-
 end:
 	kfree(if_string);
 	return count;
@@ -162,20 +151,18 @@ static ssize_t proc_orig_interval_write(
 
 	retval = strict_strtoul(interval_string, 10, &originator_interval_tmp);
 	if (retval) {
-		debug_log(LOG_TYPE_WARN, "New originator interval invalid\n");
+		printk(KERN_ERR "batman-adv:New originator interval invalid\n");
 		goto end;
 	}
 
 	if (originator_interval_tmp <= JITTER * 2) {
-		debug_log(LOG_TYPE_WARN,
-			  "New originator interval too small: %i (min: %i)\n",
-			  originator_interval_tmp, JITTER * 2);
+		printk(KERN_WARNING "batman-adv:New originator interval too small: %li (min: %i)\n",
+		       originator_interval_tmp, JITTER * 2);
 		goto end;
 	}
 
-	debug_log(LOG_TYPE_NOTICE,
-		  "Changing originator interval from: %i to: %i\n",
-		  atomic_read(&originator_interval), originator_interval_tmp);
+	printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li\n",
+	       atomic_read(&originator_interval), originator_interval_tmp);
 
 	atomic_set(&originator_interval, originator_interval_tmp);
 
@@ -191,11 +178,12 @@ static int proc_orig_interval_open(struc
 
 static int proc_originators_read(struct seq_file *seq, void *offset)
 {
-	struct hash_it_t *hashit = NULL;
+	HASHIT(hashit);
 	struct orig_node *orig_node;
 	struct neigh_node *neigh_node;
 	int batman_count = 0;
 	char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
+	unsigned long flags;
 
 	rcu_read_lock();
 	if (list_empty(&if_list)) {
@@ -218,11 +206,11 @@ static int proc_originators_read(struct
 		   ((struct batman_if *)if_list.next)->addr_str);
 
 	rcu_read_unlock();
-	spin_lock(&orig_hash_lock);
+	spin_lock_irqsave(&orig_hash_lock, flags);
 
-	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
+	while (hash_iterate(orig_hash, &hashit)) {
 
-		orig_node = hashit->bucket->data;
+		orig_node = hashit.bucket->data;
 
 		if (!orig_node->router)
 			continue;
@@ -249,7 +237,7 @@ static int proc_originators_read(struct
 
 	}
 
-	spin_unlock(&orig_hash_lock);
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
 
 	if (batman_count == 0)
 		seq_printf(seq, "No batman nodes in range ... \n");
@@ -263,84 +251,6 @@ static int proc_originators_open(struct
 	return single_open(file, proc_originators_read, NULL);
 }
 
-static int proc_log_level_read(struct seq_file *seq, void *offset)
-{
-
-	seq_printf(seq, "[x] %s (%d)\n", LOG_TYPE_CRIT_NAME, LOG_TYPE_CRIT);
-	seq_printf(seq, "[%c] %s (%d)\n",
-		   (LOG_TYPE_WARN & log_level) ? 'x' : ' ',
-		   LOG_TYPE_WARN_NAME, LOG_TYPE_WARN);
-	seq_printf(seq, "[%c] %s (%d)\n",
-		   (LOG_TYPE_NOTICE & log_level) ? 'x' : ' ',
-		   LOG_TYPE_NOTICE_NAME, LOG_TYPE_NOTICE);
-	seq_printf(seq, "[%c] %s (%d)\n",
-		   (LOG_TYPE_BATMAN & log_level) ? 'x' : ' ',
-		   LOG_TYPE_BATMAN_NAME, LOG_TYPE_BATMAN);
-	seq_printf(seq, "[%c] %s (%d)\n",
-		   (LOG_TYPE_ROUTES & log_level) ? 'x' : ' ',
-		   LOG_TYPE_ROUTES_NAME, LOG_TYPE_ROUTES);
-	return 0;
-}
-
-static int proc_log_level_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, proc_log_level_read, NULL);
-}
-
-static ssize_t proc_log_level_write(struct file *instance,
-				    const char __user *userbuffer,
-				    size_t count, loff_t *data)
-{
-	char *log_level_string, *tokptr, *cp;
-	int finished, not_copied = 0;
-	unsigned long log_level_tmp = 0;
-
-	log_level_string = kmalloc(count, GFP_KERNEL);
-
-	if (!log_level_string)
-		return -ENOMEM;
-
-	not_copied = copy_from_user(log_level_string, userbuffer, count);
-	log_level_string[count - not_copied - 1] = 0;
-
-	if (strict_strtoul(log_level_string, 10, &log_level_tmp) < 0) {
-		/* was not a number, doing textual parsing */
-		log_level_tmp = 0;
-		tokptr = log_level_string;
-
-		for (cp = log_level_string, finished = 0; !finished; cp++) {
-			switch (*cp) {
-			case 0:
-				finished = 1;
-			case ' ':
-			case '\n':
-			case '\t':
-				*cp = 0;
-				/* compare */
-				if (strcmp(tokptr, LOG_TYPE_WARN_NAME) == 0)
-					log_level_tmp |= LOG_TYPE_WARN;
-				if (strcmp(tokptr, LOG_TYPE_NOTICE_NAME) == 0)
-					log_level_tmp |= LOG_TYPE_NOTICE;
-				if (strcmp(tokptr, LOG_TYPE_BATMAN_NAME) == 0)
-					log_level_tmp |= LOG_TYPE_BATMAN;
-				if (strcmp(tokptr, LOG_TYPE_ROUTES_NAME) == 0)
-					log_level_tmp |= LOG_TYPE_ROUTES;
-				tokptr = cp + 1;
-				break;
-			default:
-				;
-			}
-		}
-	}
-
-	debug_log(LOG_TYPE_CRIT, "Changing log_level from: %i to: %i\n",
-		  log_level, log_level_tmp);
-	log_level = log_level_tmp;
-
-	kfree(log_level_string);
-	return count;
-}
-
 static int proc_transt_local_read(struct seq_file *seq, void *offset)
 {
 	char *buf;
@@ -405,251 +315,99 @@ static int proc_transt_global_open(struc
 	return single_open(file, proc_transt_global_read, NULL);
 }
 
-/* insert interface to the list of interfaces of one originator */
-
-static void proc_vis_insert_interface(const uint8_t *interface,
-				      struct vis_if_list **if_entry,
-				      bool primary)
+/* setting the mode of the vis server by the user */
+static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer,
+			      size_t count, loff_t *ppos)
 {
-	/* Did we get an empty list? (then insert imediately) */
-	if(*if_entry == NULL) {
-		*if_entry = kmalloc(sizeof(struct vis_if_list), GFP_KERNEL);
-		if (*if_entry == NULL)
-			return;
+	char *vis_mode_string;
+	int not_copied = 0;
 
-		(*if_entry)->primary = primary;
-		(*if_entry)->next = NULL;
-		memcpy((*if_entry)->addr, interface, ETH_ALEN);
-	} else {
-		struct vis_if_list *head_if_entry = *if_entry;
-		/* Do we already have this interface in our list? */
-		while (!compare_orig((*if_entry)->addr, (void *)interface)) {
+	vis_mode_string = kmalloc(count, GFP_KERNEL);
 
-			/* Or did we reach the end (then append the interface) */
-			if ((*if_entry)->next == NULL) {
-				(*if_entry)->next = kmalloc(sizeof(struct vis_if_list), GFP_KERNEL);
-				if ((*if_entry)->next == NULL)
-					return;
+	if (!vis_mode_string)
+		return -ENOMEM;
 
-				memcpy((*if_entry)->next->addr, interface, ETH_ALEN);
-				(*if_entry)->next->primary = primary;
-				(*if_entry)->next->next = NULL;
-				break;
-			}
-			*if_entry = (*if_entry)->next;
-		}
-		/* Rewind the list to its head */
-		*if_entry = head_if_entry;
-	}
-}
-/* read an entry  */
+	not_copied = copy_from_user(vis_mode_string, buffer, count);
+	vis_mode_string[count - not_copied - 1] = 0;
 
-static void proc_vis_read_entry(struct seq_file *seq,
-				struct vis_info_entry *entry,
-				struct vis_if_list **if_entry,
-				uint8_t *vis_orig,
-				uint8_t current_format,
-				uint8_t first_line)
-{
-	char from[40];
-	char to[40];
-	int int_part, frac_part;
+	if ((strcmp(vis_mode_string, "client") == 0) ||
+			(strcmp(vis_mode_string, "disabled") == 0)) {
+		printk(KERN_INFO "batman-adv:Setting VIS mode to client (disabling vis server)\n");
+		atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE);
+	} else if ((strcmp(vis_mode_string, "server") == 0) ||
+			(strcmp(vis_mode_string, "enabled") == 0)) {
+		printk(KERN_INFO "batman-adv:Setting VIS mode to server (enabling vis server)\n");
+		atomic_set(&vis_mode, VIS_TYPE_SERVER_SYNC);
+	} else
+		printk(KERN_ERR "batman-adv:Unknown VIS mode: %s\n",
+		       vis_mode_string);
 
-	addr_to_string(to, entry->dest);
-	if (entry->quality == 0) {
-#ifndef VIS_SUBCLUSTERS_DISABLED
-		proc_vis_insert_interface(vis_orig, if_entry, true);
-#endif /* VIS_SUBCLUSTERS_DISABLED */
-		addr_to_string(from, vis_orig);
-		if (current_format == DOT_DRAW) {
-			seq_printf(seq, "\t\"%s\" -> \"%s\" [label=\"HNA\"]\n",
-				   from, to);
-		} else {
-			seq_printf(seq,
-				   "%s\t{ router : \"%s\", gateway   : \"%s\", label : \"HNA\" }",
-				   (first_line ? "" : ",\n"), from, to);
-		}
-	} else {
-#ifndef VIS_SUBCLUSTERS_DISABLED
-		proc_vis_insert_interface(entry->src, if_entry, compare_orig(entry->src, vis_orig));
-#endif /* VIS_SUBCLUSTERS_DISABLED */
-		addr_to_string(from, entry->src);
+	kfree(vis_mode_string);
+	return count;
+}
 
-		/* kernel has no printf-support for %f? it'd be better to return
-		 * this in float. */
+static int proc_vis_srv_read(struct seq_file *seq, void *offset)
+{
+	int vis_server = atomic_read(&vis_mode);
 
-		int_part = TQ_MAX_VALUE / entry->quality;
-		frac_part = 1000 * TQ_MAX_VALUE / entry->quality - int_part * 1000;
+	seq_printf(seq, "[%c] client mode (server disabled) \n",
+			(vis_server == VIS_TYPE_CLIENT_UPDATE) ? 'x' : ' ');
+	seq_printf(seq, "[%c] server mode (server enabled) \n",
+			(vis_server == VIS_TYPE_SERVER_SYNC) ? 'x' : ' ');
 
-		if (current_format == DOT_DRAW) {
-			seq_printf(seq,
-				   "\t\"%s\" -> \"%s\" [label=\"%d.%d\"]\n",
-				   from, to, int_part, frac_part);
-		} else {
-			seq_printf(seq,
-				   "%s\t{ router : \"%s\", neighbour : \"%s\", label : %d.%d }",
-				   (first_line ? "" : ",\n"), from, to, int_part, frac_part);
-		}
-	}
+	return 0;
 }
 
+static int proc_vis_srv_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_vis_srv_read, NULL);
+}
 
-static int proc_vis_read(struct seq_file *seq, void *offset)
+static int proc_vis_data_read(struct seq_file *seq, void *offset)
 {
-	struct hash_it_t *hashit = NULL;
+	HASHIT(hashit);
 	struct vis_info *info;
 	struct vis_info_entry *entries;
-	struct vis_if_list *if_entries = NULL;
+	HLIST_HEAD(vis_if_list);
 	int i;
-	uint8_t current_format, first_line = 1;
-#ifndef VIS_SUBCLUSTERS_DISABLED
 	char tmp_addr_str[ETH_STR_LEN];
-	struct vis_if_list *tmp_if_next;
-#endif /* VIS_SUBCLUSTERS_DISABLED */
-
-	current_format = vis_format;
+	unsigned long flags;
+	int vis_server = atomic_read(&vis_mode);
 
 	rcu_read_lock();
-	if (list_empty(&if_list) || (!is_vis_server())) {
+	if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) {
 		rcu_read_unlock();
-		if (current_format == DOT_DRAW)
-			seq_printf(seq, "digraph {\n}\n");
 		goto end;
 	}
 
 	rcu_read_unlock();
 
-	if (current_format == DOT_DRAW)
-		seq_printf(seq, "digraph {\n");
-
-	spin_lock(&vis_hash_lock);
-	while (NULL != (hashit = hash_iterate(vis_hash, hashit))) {
-		info = hashit->bucket->data;
+	spin_lock_irqsave(&vis_hash_lock, flags);
+	while (hash_iterate(vis_hash, &hashit)) {
+		info = hashit.bucket->data;
 		entries = (struct vis_info_entry *)
 			((char *)info + sizeof(struct vis_info));
+		addr_to_string(tmp_addr_str, info->packet.vis_orig);
+		seq_printf(seq, "%s,", tmp_addr_str);
 
 		for (i = 0; i < info->packet.entries; i++) {
-			proc_vis_read_entry(seq, &entries[i], &if_entries,
-					    info->packet.vis_orig,
-					    current_format, first_line);
-			if (first_line)
-				first_line = 0;
+			proc_vis_read_entry(seq, &entries[i], &vis_if_list,
+					    info->packet.vis_orig);
 		}
 
-#ifndef VIS_SUBCLUSTERS_DISABLED
-		/* Generate subgraphs from the collected items */
-		if (current_format == DOT_DRAW) {
-
-			addr_to_string(tmp_addr_str, info->packet.vis_orig);
-			seq_printf(seq, "\tsubgraph \"cluster_%s\" {\n", tmp_addr_str);
-			while (if_entries != NULL) {
-
-				addr_to_string(tmp_addr_str, if_entries->addr);
-				if (if_entries->primary)
-					seq_printf(seq, "\t\t\"%s\" [peripheries=2]\n", tmp_addr_str);
-				else
-					seq_printf(seq, "\t\t\"%s\"\n", tmp_addr_str);
-
-				/* ... and empty the list while doing this */
-				tmp_if_next = if_entries->next;
-				kfree(if_entries);
-				if_entries = tmp_if_next;
-			}
-			seq_printf(seq, "\t}\n");
-		}
-#endif /* VIS_SUBCLUSTERS_DISABLED */
+		/* add primary/secondary records */
+		proc_vis_read_prim_sec(seq, &vis_if_list);
+		seq_printf(seq, "\n");
 	}
-	spin_unlock(&vis_hash_lock);
+	spin_unlock_irqrestore(&vis_hash_lock, flags);
 
-	if (current_format == DOT_DRAW)
-		seq_printf(seq, "}\n");
-	else
-		seq_printf(seq, "\n");
 end:
 	return 0;
 }
 
-/* setting the mode of the vis server by the user */
-static ssize_t proc_vis_write(struct file *file, const char __user * buffer,
-			      size_t count, loff_t *ppos)
-{
-	char *vis_mode_string;
-	int not_copied = 0;
-
-	vis_mode_string = kmalloc(count, GFP_KERNEL);
-
-	if (!vis_mode_string)
-		return -ENOMEM;
-
-	not_copied = copy_from_user(vis_mode_string, buffer, count);
-	vis_mode_string[count - not_copied - 1] = 0;
-
-	if (strcmp(vis_mode_string, "client") == 0) {
-		debug_log(LOG_TYPE_NOTICE, "Setting VIS mode to client\n");
-		vis_set_mode(VIS_TYPE_CLIENT_UPDATE);
-	} else if (strcmp(vis_mode_string, "server") == 0) {
-		debug_log(LOG_TYPE_NOTICE, "Setting VIS mode to server\n");
-		vis_set_mode(VIS_TYPE_SERVER_SYNC);
-	} else
-		debug_log(LOG_TYPE_WARN, "Unknown VIS mode: %s\n",
-			  vis_mode_string);
-
-	kfree(vis_mode_string);
-	return count;
-}
-
-static int proc_vis_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, proc_vis_read, NULL);
-}
-
-static int proc_vis_format_read(struct seq_file *seq, void *offset)
-{
-	uint8_t current_format = vis_format;
-
-	seq_printf(seq, "[%c] %s\n",
-		   (current_format == DOT_DRAW) ? 'x' : ' ',
-		   VIS_FORMAT_DD_NAME);
-	seq_printf(seq, "[%c] %s\n",
-		   (current_format == JSON) ? 'x' : ' ',
-		   VIS_FORMAT_JSON_NAME);
-	return 0;
-}
-
-static int proc_vis_format_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, proc_vis_format_read, NULL);
-}
-
-static ssize_t proc_vis_format_write(struct file *file,
-				     const char __user *buffer,
-				     size_t count, loff_t *ppos)
+static int proc_vis_data_open(struct inode *inode, struct file *file)
 {
-	char *vis_format_string;
-	int not_copied = 0;
-
-	vis_format_string = kmalloc(count, GFP_KERNEL);
-
-	if (!vis_format_string)
-		return -ENOMEM;
-
-	not_copied = copy_from_user(vis_format_string, buffer, count);
-	vis_format_string[count - not_copied - 1] = 0;
-
-	if (strcmp(vis_format_string, VIS_FORMAT_DD_NAME) == 0) {
-		debug_log(LOG_TYPE_NOTICE, "Setting VIS output format to: %s\n",
-			  VIS_FORMAT_DD_NAME);
-		vis_format = DOT_DRAW;
-	} else if (strcmp(vis_format_string, VIS_FORMAT_JSON_NAME) == 0) {
-		debug_log(LOG_TYPE_NOTICE, "Setting VIS output format to: %s\n",
-			  VIS_FORMAT_JSON_NAME);
-		vis_format = JSON;
-	} else
-		debug_log(LOG_TYPE_WARN, "Unknown VIS output format: %s\n",
-			  vis_format_string);
-
-	kfree(vis_format_string);
-	return count;
+	return single_open(file, proc_vis_data_read, NULL);
 }
 
 static int proc_aggr_read(struct seq_file *seq, void *offset)
@@ -665,6 +423,7 @@ static ssize_t proc_aggr_write(struct fi
 	char *aggr_string;
 	int not_copied = 0;
 	unsigned long aggregation_enabled_tmp;
+	int retval;
 
 	aggr_string = kmalloc(count, GFP_KERNEL);
 
@@ -674,22 +433,21 @@ static ssize_t proc_aggr_write(struct fi
 	not_copied = copy_from_user(aggr_string, buffer, count);
 	aggr_string[count - not_copied - 1] = 0;
 
-	strict_strtoul(aggr_string, 10, &aggregation_enabled_tmp);
+	retval = strict_strtoul(aggr_string, 10, &aggregation_enabled_tmp);
 
-	if ((aggregation_enabled_tmp != 0) && (aggregation_enabled_tmp != 1)) {
-		debug_log(LOG_TYPE_WARN, "Aggregation can only be enabled (1) or disabled (0), given value: %li\n", aggregation_enabled_tmp);
-		goto end;
+	if (retval || aggregation_enabled_tmp > 1) {
+		printk(KERN_ERR "batman-adv:Aggregation can only be enabled (1) or disabled (0), given value: %li\n", aggregation_enabled_tmp);
+	} else {
+		printk(KERN_INFO "batman-adv:Changing aggregation from: %s (%i) to: %s (%li)\n",
+		       (atomic_read(&aggregation_enabled) == 1 ?
+			"enabled" : "disabled"),
+		       atomic_read(&aggregation_enabled),
+		       (aggregation_enabled_tmp == 1 ? "enabled" : "disabled"),
+		       aggregation_enabled_tmp);
+		atomic_set(&aggregation_enabled,
+			   (unsigned)aggregation_enabled_tmp);
 	}
 
-	debug_log(LOG_TYPE_NOTICE, "Changing aggregation from: %s (%i) to: %s (%li)\n",
-		  (atomic_read(&aggregation_enabled) == 1 ?
-		   "enabled" : "disabled"),
-		  atomic_read(&aggregation_enabled),
-		  (aggregation_enabled_tmp == 1 ? "enabled" : "disabled"),
-		  aggregation_enabled_tmp);
-
-	atomic_set(&aggregation_enabled, (unsigned)aggregation_enabled_tmp);
-end:
 	kfree(aggr_string);
 	return count;
 }
@@ -715,20 +473,20 @@ static const struct file_operations proc
 	.release	= single_release,
 };
 
-static const struct file_operations proc_vis_format_fops = {
+static const struct file_operations proc_vis_srv_fops = {
 	.owner		= THIS_MODULE,
-	.open		= proc_vis_format_open,
+	.open		= proc_vis_srv_open,
 	.read		= seq_read,
-	.write		= proc_vis_format_write,
+	.write		= proc_vis_srv_write,
 	.llseek		= seq_lseek,
 	.release	= single_release,
 };
 
-static const struct file_operations proc_vis_fops = {
+static const struct file_operations proc_vis_data_fops = {
 	.owner		= THIS_MODULE,
-	.open		= proc_vis_open,
+	.open		= proc_vis_data_open,
 	.read		= seq_read,
-	.write		= proc_vis_write,
+	.write		= proc_dummy_write,
 	.llseek		= seq_lseek,
 	.release	= single_release,
 };
@@ -760,15 +518,6 @@ static const struct file_operations proc
 	.release	= single_release,
 };
 
-static const struct file_operations proc_log_level_fops = {
-	.owner		= THIS_MODULE,
-	.open		= proc_log_level_open,
-	.read		= seq_read,
-	.write		= proc_log_level_write,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
 static const struct file_operations proc_interfaces_fops = {
 	.owner		= THIS_MODULE,
 	.open		= proc_interfaces_open,
@@ -795,12 +544,6 @@ void cleanup_procfs(void)
 	if (proc_transt_local_file)
 		remove_proc_entry(PROC_FILE_TRANST_LOCAL, proc_batman_dir);
 
-	if (proc_log_file)
-		remove_proc_entry(PROC_FILE_LOG, proc_batman_dir);
-
-	if (proc_log_level_file)
-		remove_proc_entry(PROC_FILE_LOG_LEVEL, proc_batman_dir);
-
 	if (proc_originators_file)
 		remove_proc_entry(PROC_FILE_ORIGINATORS, proc_batman_dir);
 
@@ -810,11 +553,11 @@ void cleanup_procfs(void)
 	if (proc_interface_file)
 		remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir);
 
-	if (proc_vis_file)
-		remove_proc_entry(PROC_FILE_VIS, proc_batman_dir);
+	if (proc_vis_data_file)
+		remove_proc_entry(PROC_FILE_VIS_DATA, proc_batman_dir);
 
-	if (proc_vis_format_file)
-		remove_proc_entry(PROC_FILE_VIS_FORMAT, proc_batman_dir);
+	if (proc_vis_srv_file)
+		remove_proc_entry(PROC_FILE_VIS_SRV, proc_batman_dir);
 
 	if (proc_aggr_file)
 		remove_proc_entry(PROC_FILE_AGGR, proc_batman_dir);
@@ -862,17 +605,6 @@ int setup_procfs(void)
 		return -EFAULT;
 	}
 
-	proc_log_level_file = create_proc_entry(PROC_FILE_LOG_LEVEL,
-						S_IWUSR | S_IRUGO,
-						proc_batman_dir);
-	if (proc_log_level_file) {
-		proc_log_level_file->proc_fops = &proc_log_level_fops;
-	} else {
-		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_LOG_LEVEL);
-		cleanup_procfs();
-		return -EFAULT;
-	}
-
 	proc_originators_file = create_proc_entry(PROC_FILE_ORIGINATORS,
 						  S_IRUGO, proc_batman_dir);
 	if (proc_originators_file) {
@@ -883,16 +615,6 @@ int setup_procfs(void)
 		return -EFAULT;
 	}
 
-	proc_log_file = create_proc_entry(PROC_FILE_LOG,
-					  S_IRUGO, proc_batman_dir);
-	if (proc_log_file) {
-		proc_log_file->proc_fops = &proc_log_operations;
-	} else {
-		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_FILE_LOG, PROC_FILE_GATEWAYS);
-		cleanup_procfs();
-		return -EFAULT;
-	}
-
 	proc_transt_local_file = create_proc_entry(PROC_FILE_TRANST_LOCAL,
 						   S_IRUGO, proc_batman_dir);
 	if (proc_transt_local_file) {
@@ -913,23 +635,23 @@ int setup_procfs(void)
 		return -EFAULT;
 	}
 
-	proc_vis_file = create_proc_entry(PROC_FILE_VIS, S_IWUSR | S_IRUGO,
-					  proc_batman_dir);
-	if (proc_vis_file) {
-		proc_vis_file->proc_fops = &proc_vis_fops;
+	proc_vis_srv_file = create_proc_entry(PROC_FILE_VIS_SRV,
+						S_IWUSR | S_IRUGO,
+						proc_batman_dir);
+	if (proc_vis_srv_file) {
+		proc_vis_srv_file->proc_fops = &proc_vis_srv_fops;
 	} else {
-		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS);
+		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_SRV);
 		cleanup_procfs();
 		return -EFAULT;
 	}
 
-	proc_vis_format_file = create_proc_entry(PROC_FILE_VIS_FORMAT,
-						 S_IWUSR | S_IRUGO,
-						 proc_batman_dir);
-	if (proc_vis_format_file) {
-		proc_vis_format_file->proc_fops = &proc_vis_format_fops;
+	proc_vis_data_file = create_proc_entry(PROC_FILE_VIS_DATA, S_IRUGO,
+					  proc_batman_dir);
+	if (proc_vis_data_file) {
+		proc_vis_data_file->proc_fops = &proc_vis_data_fops;
 	} else {
-		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_FORMAT);
+		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_DATA);
 		cleanup_procfs();
 		return -EFAULT;
 	}
@@ -946,5 +668,3 @@ int setup_procfs(void)
 
 	return 0;
 }
-
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/proc.h linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/proc.h
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/proc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/proc.h	2010-05-16 17:17:36.000000000 -0400
@@ -31,19 +31,10 @@
 #define PROC_FILE_LOG_LEVEL "log_level"
 #define PROC_FILE_TRANST_LOCAL "transtable_local"
 #define PROC_FILE_TRANST_GLOBAL "transtable_global"
-#define PROC_FILE_VIS "vis"
-#define PROC_FILE_VIS_FORMAT "vis_format"
+#define PROC_FILE_VIS_SRV "vis_server"
+#define PROC_FILE_VIS_DATA "vis_data"
 #define PROC_FILE_AGGR "aggregate_ogm"
 
 void cleanup_procfs(void);
 int setup_procfs(void);
 
-/* While scanning for vis-entries of a particular vis-originator
- * this list collects its interfaces to create a subgraph/cluster
- * out of them later
- */
-struct vis_if_list {
-	uint8_t addr[ETH_ALEN];
-	bool primary;
-	struct vis_if_list *next;
-};
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/README linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/README
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/README	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/README	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,4 @@
-[state: 07-11-2009]
+[state: 06-01-2010]
 
 BATMAN-ADV
 ----------
@@ -15,19 +15,6 @@ above B.A.T.M.A.N. Advanced, prominent e
 This is batman-advanced implemented as Linux kernel driver. It does not depend
 on any network (other) driver, and can be used on wifi as well as ethernet,
 vpn, etc ... (anything with ethernet-style layer 2).
-It compiles against and should work with Linux 2.6.20 - 2.6.31. Supporting older
-versions is not planned, but it's probably easy to backport it. If you work on a
-backport, feel free to contact us.  :-)
-
-COMPILE
--------
-To compile against your currently installed kernel, just type:
-
-# make
-
-if you want to compile against some other kernel, use:
-
-# make KERNELPATH=/path/to/kernel
 
 USAGE
 -----
@@ -73,16 +60,9 @@ When configured as server, you can get a
 
 # cat /proc/net/batman-adv/vis
 
-This output format is a graphviz formatted text file which can be
-processed with graphviz-tools like dot.
-The labels are similar/compatible to the ETX metric, 1.0 means perfect
-connection (100%), 2.0 means 50%, 3.0 means 33% and so on.
-
-Alternatively, a JSON output format is available. The format can be set
-using by writing either "dot_draw" or "json" into the vis_format file.
-"dot_draw" is selected by default.
-
-echo "json" > /proc/net/batman-adv/vis_format
+The output is in a generic raw format. Use the batctl tool (See below)
+to convert this to other formats more suitable for graphing, eg
+graphviz dot, or JSON data-interchange format.
 
 In very mobile scenarios, you might want to adjust the originator
 interval to a lower value. This will make the mesh more responsive to
@@ -96,15 +76,59 @@ To deactivate batman, do:
 
 # echo "" > /proc/net/batman-adv/interfaces
 
+LOGGING/DEBUGGING
+-----------------
+
+All error messages, warnings and information messages are sent to the
+kernel log. Depending on your operating system distribution this can be
+read in one of a number of ways. Try using the commands: dmesg,
+logread, or looking in the files /var/log/kern.log or
+/var/log/syslog. All batman-adv messages are prefixed with
+"batman-adv:" So to see just these messages try
+
+dmesg | grep batman-adv
+
+When investigating problems with your mesh network it is sometimes
+necessary to see more detail debug messages. This must be enabled when
+compiling the batman-adv module. Use "make menuconfig" and enable the
+option "B.A.T.M.A.N. debugging".
+
+The additional debug output is by default disabled. It can be enabled
+either at kernel module load time or during run time. To enable debug
+output at module load time, add the module parameter debug=<value>.
+<value> can take one of four values.
+
+0 - All debug output disabled
+1 - Enable messages related to routing / flooding / broadcasting
+2 - Enable route or hna added / changed / deleted
+3 - Enable all messages
+
+e.g.
+
+modprobe batman-adv debug=2
+
+will load the module and enable debug messages for when routes or HNAs
+change.
+
+The debug output can also be changed at runtime using the file
+/sys/module/batman-adv/parameters/debug. e.g.
+
+echo 2 > /sys/module/batman-adv/parameters/debug
+
+enables debug messages for when routes or HNAs
+
+The debug output is sent to the kernel logs. So try dmesg, logread etc
+to see the debug messages.
+
 BATCTL
 ------
 
-B.A.T.M.A.N.  advanced  operates on layer 2 and thus all hosts partici-
-pating in the virtual switch are completely transparent for all  proto-
-cols above layer 2. Therefore the common diagnosis tools do not work as
-expected. To overcome these problems batctl was created. At the  moment
-the  batctl contains ping, traceroute, tcpdump and interfaces to the
-kernel module settings.
+B.A.T.M.A.N.  advanced operates on layer 2 and thus all hosts
+participating in the virtual switch are completely transparent for all
+protocols above layer 2. Therefore the common diagnosis tools do not
+work as expected. To overcome these problems batctl was created. At
+the moment the batctl contains ping, traceroute, tcpdump and
+interfaces to the kernel module settings.
 
 For more information, please see the manpage (man batctl).
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/routing.c linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/routing.c
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/routing.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/routing.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,304 +19,226 @@
  *
  */
 
-
-
-
-
 #include "main.h"
 #include "routing.h"
-#include "log.h"
 #include "send.h"
+#include "hash.h"
 #include "soft-interface.h"
 #include "hard-interface.h"
 #include "device.h"
 #include "translation-table.h"
+#include "originator.h"
 #include "types.h"
-#include "hash.h"
 #include "ring_buffer.h"
 #include "vis.h"
 #include "aggregation.h"
-#include "compat.h"
-
-
 
 DECLARE_WAIT_QUEUE_HEAD(thread_wait);
-static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig);
-
-static atomic_t data_ready_cond;
-atomic_t exit_cond;
-
-static void start_purge_timer(void)
-{
-	queue_delayed_work(bat_event_workqueue, &purge_orig_wq, 1 * HZ);
-}
-
-int originator_init(void)
-{
-	if (orig_hash)
-		return 1;
-
-	spin_lock(&orig_hash_lock);
-	orig_hash = hash_new(128, compare_orig, choose_orig);
-
-	if (!orig_hash)
-		goto err;
-
-	spin_unlock(&orig_hash_lock);
-	start_purge_timer();
-	return 1;
-
-err:
-	spin_unlock(&orig_hash_lock);
-	return 0;
-}
-
-void originator_free(void)
-{
-	if (!orig_hash)
-		return;
-
-	cancel_delayed_work_sync(&purge_orig_wq);
-
-	spin_lock(&orig_hash_lock);
-	hash_delete(orig_hash, free_orig_node);
-	orig_hash = NULL;
-	spin_unlock(&orig_hash_lock);
-}
 
-static struct neigh_node *create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, uint8_t *neigh, struct batman_if *if_incoming)
+void slide_own_bcast_window(struct batman_if *batman_if)
 {
-	struct neigh_node *neigh_node;
+	HASHIT(hashit);
+	struct orig_node *orig_node;
+	TYPE_OF_WORD *word;
+	unsigned long flags;
 
-	debug_log(LOG_TYPE_BATMAN, "Creating new last-hop neighbour of originator\n");
+	spin_lock_irqsave(&orig_hash_lock, flags);
 
-	neigh_node = kmalloc(sizeof(struct neigh_node), GFP_ATOMIC);
-	memset(neigh_node, 0, sizeof(struct neigh_node));
-	INIT_LIST_HEAD(&neigh_node->list);
+	while (hash_iterate(orig_hash, &hashit)) {
+		orig_node = hashit.bucket->data;
+		word = &(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]);
 
-	memcpy(neigh_node->addr, neigh, ETH_ALEN);
-	neigh_node->orig_node = orig_neigh_node;
-	neigh_node->if_incoming = if_incoming;
+		bit_get_packet(word, 1, 0);
+		orig_node->bcast_own_sum[batman_if->if_num] =
+			bit_packet_count(word);
+	}
 
-	list_add_tail(&neigh_node->list, &orig_node->neigh_list);
-	return neigh_node;
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
 }
 
-void free_orig_node(void *data)
+static void update_HNA(struct orig_node *orig_node,
+		       unsigned char *hna_buff, int hna_buff_len)
 {
-	struct list_head *list_pos, *list_pos_tmp;
-	struct neigh_node *neigh_node;
-	struct orig_node *orig_node = (struct orig_node *)data;
+	if ((hna_buff_len != orig_node->hna_buff_len) ||
+	    ((hna_buff_len > 0) &&
+	     (orig_node->hna_buff_len > 0) &&
+	     (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) {
 
-	/* for all neighbours towards this originator ... */
-	list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
-		neigh_node = list_entry(list_pos, struct neigh_node, list);
+		if (orig_node->hna_buff_len > 0)
+			hna_global_del_orig(orig_node,
+					    "originator changed hna");
 
-		list_del(list_pos);
-		kfree(neigh_node);
+		if ((hna_buff_len > 0) && (hna_buff != NULL))
+			hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
 	}
-
-	hna_global_del_orig(orig_node, "originator timed out");
-
-	kfree(orig_node->bcast_own);
-	kfree(orig_node->bcast_own_sum);
-	kfree(orig_node);
 }
 
-/* this function finds or creates an originator entry for the given address if it does not exits */
-static struct orig_node *get_orig_node(uint8_t *addr)
+static void update_route(struct orig_node *orig_node,
+			 struct neigh_node *neigh_node,
+			 unsigned char *hna_buff, int hna_buff_len)
 {
-	struct orig_node *orig_node;
-	struct hashtable_t *swaphash;
-	char orig_str[ETH_STR_LEN];
-
-	orig_node = ((struct orig_node *)hash_find(orig_hash, addr));
-
-	if (orig_node != NULL)
-		return orig_node;
-
-	addr_to_string(orig_str, addr);
-	debug_log(LOG_TYPE_BATMAN, "Creating new originator: %s \n", orig_str);
-
-	orig_node = kmalloc(sizeof(struct orig_node), GFP_ATOMIC);
-	memset(orig_node, 0, sizeof(struct orig_node));
-	INIT_LIST_HEAD(&orig_node->neigh_list);
-
-	memcpy(orig_node->orig, addr, ETH_ALEN);
-	orig_node->router = NULL;
-	orig_node->batman_if = NULL;
-	orig_node->hna_buff = NULL;
-
-	orig_node->bcast_own = kmalloc(num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS, GFP_ATOMIC);
-	memset(orig_node->bcast_own, 0, num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS);
+	/* route deleted */
+	if ((orig_node->router != NULL) && (neigh_node == NULL)) {
 
-	orig_node->bcast_own_sum = kmalloc(num_ifs * sizeof(uint8_t), GFP_ATOMIC);
-	memset(orig_node->bcast_own_sum, 0, num_ifs * sizeof(uint8_t));
+		bat_dbg(DBG_ROUTES, "Deleting route towards: %pM\n",
+			orig_node->orig);
+		hna_global_del_orig(orig_node, "originator timed out");
 
-	hash_add(orig_hash, orig_node);
+		/* route added */
+	} else if ((orig_node->router == NULL) && (neigh_node != NULL)) {
 
-	if (orig_hash->elements * 4 > orig_hash->size) {
-		swaphash = hash_resize(orig_hash, orig_hash->size * 2);
+		bat_dbg(DBG_ROUTES,
+			"Adding route towards: %pM (via %pM)\n",
+			orig_node->orig, neigh_node->addr);
+		hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
 
-		if (swaphash == NULL)
-			debug_log(LOG_TYPE_CRIT, "Couldn't resize orig hash table \n");
-		else
-			orig_hash = swaphash;
+		/* route changed */
+	} else {
+		bat_dbg(DBG_ROUTES, "Changing route towards: %pM (now via %pM - was via %pM)\n", orig_node->orig, neigh_node->addr, orig_node->router->addr);
 	}
 
-	return orig_node;
-}
-
-void slide_own_bcast_window(struct batman_if *batman_if)
-{
-	struct hash_it_t *hashit = NULL;
-	struct orig_node *orig_node;
-
-	spin_lock(&orig_hash_lock);
-
-	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
-		orig_node = hashit->bucket->data;
-
-		bit_get_packet((TYPE_OF_WORD *)&(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]), 1, 0);
-		orig_node->bcast_own_sum[batman_if->if_num] = bit_packet_count((TYPE_OF_WORD *)&(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]));
-	}
+	if (neigh_node != NULL)
+		orig_node->batman_if = neigh_node->if_incoming;
+	else
+		orig_node->batman_if = NULL;
 
-	spin_unlock(&orig_hash_lock);
+	orig_node->router = neigh_node;
 }
 
-static void update_routes(struct orig_node *orig_node, struct neigh_node *neigh_node, unsigned char *hna_buff, int hna_buff_len)
+
+void update_routes(struct orig_node *orig_node,
+			  struct neigh_node *neigh_node,
+			  unsigned char *hna_buff, int hna_buff_len)
 {
-	char orig_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
 
 	if (orig_node == NULL)
 		return;
 
-	if (orig_node->router != neigh_node) {
-		addr_to_string(orig_str, orig_node->orig);
-
-		/* route deleted */
-		if ((orig_node->router != NULL) && (neigh_node == NULL)) {
-
-			debug_log(LOG_TYPE_ROUTES, "Deleting route towards: %s\n", orig_str);
-			hna_global_del_orig(orig_node, "originator timed out");
-
-		/* route added */
-		} else if ((orig_node->router == NULL) && (neigh_node != NULL)) {
-
-			addr_to_string(neigh_str, neigh_node->addr);
-			debug_log(LOG_TYPE_ROUTES, "Adding route towards: %s (via %s)\n", orig_str, neigh_str);
-			hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
-
-		/* route changed */
-		} else {
-
-			addr_to_string(neigh_str, neigh_node->addr);
-			addr_to_string(router_str, orig_node->router->addr);
-			debug_log(LOG_TYPE_ROUTES, "Changing route towards: %s (now via %s - was via %s)\n", orig_str, neigh_str, router_str);
-
-		}
-
-		if (neigh_node != NULL)
-			orig_node->batman_if = neigh_node->if_incoming;
-		else
-			orig_node->batman_if = NULL;
-
-		orig_node->router = neigh_node;
-
+	if (orig_node->router != neigh_node)
+		update_route(orig_node, neigh_node, hna_buff, hna_buff_len);
 	/* may be just HNA changed */
-	} else {
-
-		if ((hna_buff_len != orig_node->hna_buff_len) || ((hna_buff_len > 0) && (orig_node->hna_buff_len > 0) && (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) {
-
-			if (orig_node->hna_buff_len > 0)
-				hna_global_del_orig(orig_node, "originator changed hna");
-
-			if ((hna_buff_len > 0) && (hna_buff != NULL))
-				hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
-
-		}
-
-	}
+	else
+		update_HNA(orig_node, hna_buff, hna_buff_len);
 }
 
-static int isBidirectionalNeigh(struct orig_node *orig_node, struct orig_node *orig_neigh_node, struct batman_packet *batman_packet, struct batman_if *if_incoming)
+static int isBidirectionalNeigh(struct orig_node *orig_node,
+				struct orig_node *orig_neigh_node,
+				struct batman_packet *batman_packet,
+				struct batman_if *if_incoming)
 {
 	struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
-	char orig_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN];
 	unsigned char total_count;
 
-	addr_to_string(orig_str, orig_node->orig);
-	addr_to_string(neigh_str, orig_neigh_node->orig);
-
 	if (orig_node == orig_neigh_node) {
-		list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
+		list_for_each_entry(tmp_neigh_node,
+				    &orig_node->neigh_list,
+				    list) {
 
-			if (compare_orig(tmp_neigh_node->addr, orig_neigh_node->orig) && (tmp_neigh_node->if_incoming == if_incoming))
+			if (compare_orig(tmp_neigh_node->addr,
+					 orig_neigh_node->orig) &&
+			    (tmp_neigh_node->if_incoming == if_incoming))
 				neigh_node = tmp_neigh_node;
 		}
 
-		if (neigh_node == NULL)
-			neigh_node = create_neighbor(orig_node, orig_neigh_node, orig_neigh_node->orig, if_incoming);
+		if (!neigh_node)
+			neigh_node = create_neighbor(orig_node,
+						     orig_neigh_node,
+						     orig_neigh_node->orig,
+						     if_incoming);
+		/* create_neighbor failed, return 0 */
+		if (!neigh_node)
+			return 0;
 
 		neigh_node->last_valid = jiffies;
 	} else {
 		/* find packet count of corresponding one hop neighbor */
-		list_for_each_entry(tmp_neigh_node, &orig_neigh_node->neigh_list, list) {
+		list_for_each_entry(tmp_neigh_node,
+				    &orig_neigh_node->neigh_list, list) {
 
-			if (compare_orig(tmp_neigh_node->addr, orig_neigh_node->orig) && (tmp_neigh_node->if_incoming == if_incoming))
+			if (compare_orig(tmp_neigh_node->addr,
+					 orig_neigh_node->orig) &&
+			    (tmp_neigh_node->if_incoming == if_incoming))
 				neigh_node = tmp_neigh_node;
 		}
 
-		if (neigh_node == NULL)
-			neigh_node = create_neighbor(orig_neigh_node, orig_neigh_node, orig_neigh_node->orig, if_incoming);
+		if (!neigh_node)
+			neigh_node = create_neighbor(orig_neigh_node,
+						     orig_neigh_node,
+						     orig_neigh_node->orig,
+						     if_incoming);
+		/* create_neighbor failed, return 0 */
+		if (!neigh_node)
+			return 0;
 	}
 
 	orig_node->last_valid = jiffies;
 
 	/* pay attention to not get a value bigger than 100 % */
-	total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] > neigh_node->real_packet_count ? neigh_node->real_packet_count : orig_neigh_node->bcast_own_sum[if_incoming->if_num]);
+	total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] >
+		       neigh_node->real_packet_count ?
+		       neigh_node->real_packet_count :
+		       orig_neigh_node->bcast_own_sum[if_incoming->if_num]);
 
 	/* if we have too few packets (too less data) we set tq_own to zero */
 	/* if we receive too few packets it is not considered bidirectional */
-	if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM))
+	if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) ||
+	    (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM))
 		orig_neigh_node->tq_own = 0;
 	else
-		/* neigh_node->real_packet_count is never zero as we only purge old information when getting new information */
-		orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) / neigh_node->real_packet_count;
+		/* neigh_node->real_packet_count is never zero as we
+		 * only purge old information when getting new
+		 * information */
+		orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) /
+			neigh_node->real_packet_count;
 
 	/*
-	 * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE
-	 * this does affect the nearly-symmetric links only a little,
-	 * but punishes asymmetric links more.
-	 * this will give a value between 0 and TQ_MAX_VALUE
+	 * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
+	 * affect the nearly-symmetric links only a little, but
+	 * punishes asymmetric links more.  This will give a value
+	 * between 0 and TQ_MAX_VALUE
 	 */
-	orig_neigh_node->tq_asym_penalty = TQ_MAX_VALUE - (TQ_MAX_VALUE *
-			(TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
-			(TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
-			(TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) /
-			(TQ_LOCAL_WINDOW_SIZE * TQ_LOCAL_WINDOW_SIZE * TQ_LOCAL_WINDOW_SIZE);
+	orig_neigh_node->tq_asym_penalty =
+		TQ_MAX_VALUE -
+		(TQ_MAX_VALUE *
+		 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
+		 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
+		 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) /
+		(TQ_LOCAL_WINDOW_SIZE *
+		 TQ_LOCAL_WINDOW_SIZE *
+		 TQ_LOCAL_WINDOW_SIZE);
 
-	batman_packet->tq = ((batman_packet->tq * orig_neigh_node->tq_own * orig_neigh_node->tq_asym_penalty) / (TQ_MAX_VALUE *  TQ_MAX_VALUE));
+	batman_packet->tq = ((batman_packet->tq *
+			      orig_neigh_node->tq_own *
+			      orig_neigh_node->tq_asym_penalty) /
+			     (TQ_MAX_VALUE *	 TQ_MAX_VALUE));
 
-	debug_log(LOG_TYPE_BATMAN, "bidirectional: orig = %-15s neigh = %-15s => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i \n",
-		  orig_str, neigh_str, total_count, neigh_node->real_packet_count, orig_neigh_node->tq_own, orig_neigh_node->tq_asym_penalty, batman_packet->tq);
+	bat_dbg(DBG_BATMAN, "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i \n",
+		orig_node->orig, orig_neigh_node->orig, total_count,
+		neigh_node->real_packet_count, orig_neigh_node->tq_own,
+		orig_neigh_node->tq_asym_penalty, batman_packet->tq);
 
-	/* if link has the minimum required transmission quality consider it bidirectional */
+	/* if link has the minimum required transmission quality
+	 * consider it bidirectional */
 	if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT)
 		return 1;
 
 	return 0;
 }
 
-static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, struct batman_packet *batman_packet, struct batman_if *if_incoming, unsigned char *hna_buff, int hna_buff_len, char is_duplicate)
+static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr,
+			struct batman_packet *batman_packet,
+			struct batman_if *if_incoming,
+			unsigned char *hna_buff, int hna_buff_len,
+			char is_duplicate)
 {
 	struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
 	int tmp_hna_buff_len;
 
-	debug_log(LOG_TYPE_BATMAN, "update_originator(): Searching and updating originator entry of received packet \n");
+	bat_dbg(DBG_BATMAN, "update_originator(): Searching and updating originator entry of received packet \n");
 
 	list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
-		if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && (tmp_neigh_node->if_incoming == if_incoming)) {
+		if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) &&
+		    (tmp_neigh_node->if_incoming == if_incoming)) {
 			neigh_node = tmp_neigh_node;
 			continue;
 		}
@@ -324,19 +246,34 @@ static void update_orig(struct orig_node
 		if (is_duplicate)
 			continue;
 
-		ring_buffer_set(tmp_neigh_node->tq_recv, &tmp_neigh_node->tq_index, 0);
-		tmp_neigh_node->tq_avg = ring_buffer_avg(tmp_neigh_node->tq_recv);
+		ring_buffer_set(tmp_neigh_node->tq_recv,
+				&tmp_neigh_node->tq_index, 0);
+		tmp_neigh_node->tq_avg =
+			ring_buffer_avg(tmp_neigh_node->tq_recv);
 	}
 
-	if (neigh_node == NULL)
-		neigh_node = create_neighbor(orig_node, get_orig_node(ethhdr->h_source), ethhdr->h_source, if_incoming);
-	else
-		debug_log(LOG_TYPE_BATMAN, "Updating existing last-hop neighbour of originator\n");
+	if (!neigh_node) {
+		struct orig_node *orig_tmp;
+
+		orig_tmp = get_orig_node(ethhdr->h_source);
+		if (!orig_tmp)
+			return;
+
+		neigh_node = create_neighbor(orig_node,
+					     orig_tmp,
+					     ethhdr->h_source, if_incoming);
+		if (!neigh_node)
+			return;
+	} else
+		bat_dbg(DBG_BATMAN,
+			"Updating existing last-hop neighbor of originator\n");
 
 	orig_node->flags = batman_packet->flags;
 	neigh_node->last_valid = jiffies;
 
-	ring_buffer_set(neigh_node->tq_recv, &neigh_node->tq_index, batman_packet->tq);
+	ring_buffer_set(neigh_node->tq_recv,
+			&neigh_node->tq_index,
+			batman_packet->tq);
 	neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
 
 	if (!is_duplicate) {
@@ -344,9 +281,11 @@ static void update_orig(struct orig_node
 		neigh_node->last_ttl = batman_packet->ttl;
 	}
 
-	tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ? batman_packet->num_hna * ETH_ALEN : hna_buff_len);
+	tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ?
+			    batman_packet->num_hna * ETH_ALEN : hna_buff_len);
 
-	/* if this neighbor already is our next hop there is nothing to change */
+	/* if this neighbor already is our next hop there is nothing
+	 * to change */
 	if (orig_node->router == neigh_node)
 		goto update_hna;
 
@@ -355,11 +294,12 @@ static void update_orig(struct orig_node
 	    (orig_node->router->tq_avg > neigh_node->tq_avg))
 		goto update_hna;
 
-	/* if the TQ is the same and the link not more symetric we won't consider it either */
+	/* if the TQ is the same and the link not more symetric we
+	 * won't consider it either */
 	if ((orig_node->router) &&
 	     ((neigh_node->tq_avg == orig_node->router->tq_avg) &&
-	     (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num] >=
-	      neigh_node->orig_node->bcast_own_sum[if_incoming->if_num])))
+	     (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num]
+	      >= neigh_node->orig_node->bcast_own_sum[if_incoming->if_num])))
 		goto update_hna;
 
 	update_routes(orig_node, neigh_node, hna_buff, tmp_hna_buff_len);
@@ -367,60 +307,72 @@ static void update_orig(struct orig_node
 
 update_hna:
 	update_routes(orig_node, orig_node->router, hna_buff, tmp_hna_buff_len);
-	return;
 }
 
-static char count_real_packets(struct ethhdr *ethhdr, struct batman_packet *batman_packet, struct batman_if *if_incoming)
+static char count_real_packets(struct ethhdr *ethhdr,
+			       struct batman_packet *batman_packet,
+			       struct batman_if *if_incoming)
 {
 	struct orig_node *orig_node;
 	struct neigh_node *tmp_neigh_node;
 	char is_duplicate = 0;
-
+	uint16_t seq_diff;
 
 	orig_node = get_orig_node(batman_packet->orig);
 	if (orig_node == NULL)
 		return 0;
 
-
 	list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
 
 		if (!is_duplicate)
-			is_duplicate = get_bit_status(tmp_neigh_node->real_bits, orig_node->last_real_seqno, batman_packet->seqno);
-
-		if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && (tmp_neigh_node->if_incoming == if_incoming))
-			bit_get_packet(tmp_neigh_node->real_bits, batman_packet->seqno - orig_node->last_real_seqno, 1);
+			is_duplicate =
+				get_bit_status(tmp_neigh_node->real_bits,
+					       orig_node->last_real_seqno,
+					       batman_packet->seqno);
+		seq_diff = batman_packet->seqno - orig_node->last_real_seqno;
+		if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) &&
+		    (tmp_neigh_node->if_incoming == if_incoming))
+			bit_get_packet(tmp_neigh_node->real_bits, seq_diff, 1);
 		else
-			bit_get_packet(tmp_neigh_node->real_bits, batman_packet->seqno - orig_node->last_real_seqno, 0);
+			bit_get_packet(tmp_neigh_node->real_bits, seq_diff, 0);
 
-		tmp_neigh_node->real_packet_count = bit_packet_count(tmp_neigh_node->real_bits);
+		tmp_neigh_node->real_packet_count =
+			bit_packet_count(tmp_neigh_node->real_bits);
 	}
 
 	if (!is_duplicate) {
-		debug_log(LOG_TYPE_BATMAN, "updating last_seqno: old %d, new %d \n", orig_node->last_real_seqno, batman_packet->seqno);
+		bat_dbg(DBG_BATMAN, "updating last_seqno: old %d, new %d \n",
+			orig_node->last_real_seqno, batman_packet->seqno);
 		orig_node->last_real_seqno = batman_packet->seqno;
 	}
 
 	return is_duplicate;
 }
 
-void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_packet, unsigned char *hna_buff, int hna_buff_len, struct batman_if *if_incoming)
+void receive_bat_packet(struct ethhdr *ethhdr,
+				struct batman_packet *batman_packet,
+				unsigned char *hna_buff, int hna_buff_len,
+				struct batman_if *if_incoming)
 {
 	struct batman_if *batman_if;
 	struct orig_node *orig_neigh_node, *orig_node;
-	char orig_str[ETH_STR_LEN], prev_sender_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN];
 	char has_directlink_flag;
-	char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0, is_broadcast = 0, is_bidirectional, is_single_hop_neigh, is_duplicate;
+	char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
+	char is_broadcast = 0, is_bidirectional, is_single_hop_neigh;
+	char is_duplicate;
 	unsigned short if_incoming_seqno;
 
-	/* Silently drop when the batman packet is actually not a correct packet.
+	/* Silently drop when the batman packet is actually not a
+	 * correct packet.
 	 *
 	 * This might happen if a packet is padded (e.g. Ethernet has a
 	 * minimum frame length of 64 byte) and the aggregation interprets
 	 * it as an additional length.
 	 *
-	 * TODO: A more sane solution would be to have a bit in the batman_packet
-	 * to detect whether the packet is the last packet in an aggregation.
-	 * Here we expect that the padding is always zero (or not 0x01)
+	 * TODO: A more sane solution would be to have a bit in the
+	 * batman_packet to detect whether the packet is the last
+	 * packet in an aggregation.  Here we expect that the padding
+	 * is always zero (or not 0x01)
 	 */
 	if (batman_packet->packet_type != BAT_PACKET)
 		return;
@@ -428,27 +380,31 @@ void receive_bat_packet(struct ethhdr *e
 	/* could be changed by schedule_own_packet() */
 	if_incoming_seqno = atomic_read(&if_incoming->seqno);
 
-	addr_to_string(orig_str, batman_packet->orig);
-	addr_to_string(prev_sender_str, batman_packet->prev_sender);
-	addr_to_string(neigh_str, ethhdr->h_source);
-
 	has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0);
 
-	is_single_hop_neigh = (compare_orig(ethhdr->h_source, batman_packet->orig) ? 1 : 0);
+	is_single_hop_neigh = (compare_orig(ethhdr->h_source,
+					    batman_packet->orig) ? 1 : 0);
 
-	debug_log(LOG_TYPE_BATMAN, "Received BATMAN packet via NB: %s, IF: %s [%s] (from OG: %s, via prev OG: %s, seqno %d, tq %d, TTL %d, V %d, IDF %d) \n", neigh_str, if_incoming->dev, if_incoming->addr_str, orig_str, prev_sender_str, batman_packet->seqno, batman_packet->tq, batman_packet->ttl, batman_packet->version, has_directlink_flag);
+	bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] (from OG: %pM, via prev OG: %pM, seqno %d, tq %d, TTL %d, V %d, IDF %d) \n",
+		ethhdr->h_source, if_incoming->dev, if_incoming->addr_str,
+		batman_packet->orig, batman_packet->prev_sender,
+		batman_packet->seqno, batman_packet->tq, batman_packet->ttl,
+		batman_packet->version, has_directlink_flag);
 
 	list_for_each_entry_rcu(batman_if, &if_list, list) {
 		if (batman_if->if_active != IF_ACTIVE)
 			continue;
 
-		if (compare_orig(ethhdr->h_source, batman_if->net_dev->dev_addr))
+		if (compare_orig(ethhdr->h_source,
+				 batman_if->net_dev->dev_addr))
 			is_my_addr = 1;
 
-		if (compare_orig(batman_packet->orig, batman_if->net_dev->dev_addr))
+		if (compare_orig(batman_packet->orig,
+				 batman_if->net_dev->dev_addr))
 			is_my_orig = 1;
 
-		if (compare_orig(batman_packet->prev_sender, batman_if->net_dev->dev_addr))
+		if (compare_orig(batman_packet->prev_sender,
+				 batman_if->net_dev->dev_addr))
 			is_my_oldorig = 1;
 
 		if (compare_orig(ethhdr->h_source, broadcastAddr))
@@ -456,44 +412,61 @@ void receive_bat_packet(struct ethhdr *e
 	}
 
 	if (batman_packet->version != COMPAT_VERSION) {
-		debug_log(LOG_TYPE_BATMAN, "Drop packet: incompatible batman version (%i) \n", batman_packet->version);
+		bat_dbg(DBG_BATMAN,
+			"Drop packet: incompatible batman version (%i)\n",
+			batman_packet->version);
 		return;
 	}
 
 	if (is_my_addr) {
-		debug_log(LOG_TYPE_BATMAN, "Drop packet: received my own broadcast (sender: %s) \n", neigh_str);
+		bat_dbg(DBG_BATMAN,
+			"Drop packet: received my own broadcast (sender: %pM)\n",
+			ethhdr->h_source);
 		return;
 	}
 
 	if (is_broadcast) {
-		debug_log(LOG_TYPE_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %s) \n", neigh_str);
+		bat_dbg(DBG_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %pM) \n", ethhdr->h_source);
 		return;
 	}
 
 	if (is_my_orig) {
+		TYPE_OF_WORD *word;
+		int offset;
+
 		orig_neigh_node = get_orig_node(ethhdr->h_source);
 
-		/* neighbour has to indicate direct link and it has to come via the corresponding interface */
-		/* if received seqno equals last send seqno save new seqno for bidirectional check */
-		if (has_directlink_flag && compare_orig(if_incoming->net_dev->dev_addr, batman_packet->orig) &&
-				  (batman_packet->seqno - if_incoming_seqno + 2 == 0)) {
-			bit_mark((TYPE_OF_WORD *)&(orig_neigh_node->bcast_own[if_incoming->if_num * NUM_WORDS]), 0);
-			orig_neigh_node->bcast_own_sum[if_incoming->if_num] = bit_packet_count((TYPE_OF_WORD *)&(orig_neigh_node->bcast_own[if_incoming->if_num * NUM_WORDS]));
+		if (!orig_neigh_node)
+			return;
+
+		/* neighbor has to indicate direct link and it has to
+		 * come via the corresponding interface */
+		/* if received seqno equals last send seqno save new
+		 * seqno for bidirectional check */
+		if (has_directlink_flag &&
+		    compare_orig(if_incoming->net_dev->dev_addr,
+				 batman_packet->orig) &&
+		    (batman_packet->seqno - if_incoming_seqno + 2 == 0)) {
+			offset = if_incoming->if_num * NUM_WORDS;
+			word = &(orig_neigh_node->bcast_own[offset]);
+			bit_mark(word, 0);
+			orig_neigh_node->bcast_own_sum[if_incoming->if_num] =
+				bit_packet_count(word);
 		}
 
-		debug_log(LOG_TYPE_BATMAN, "Drop packet: originator packet from myself (via neighbour) \n");
+		bat_dbg(DBG_BATMAN, "Drop packet: originator packet from myself (via neighbor) \n");
 		return;
 	}
 
 	if (batman_packet->tq == 0) {
 		count_real_packets(ethhdr, batman_packet, if_incoming);
 
-		debug_log(LOG_TYPE_BATMAN, "Drop packet: originator packet with tq equal 0 \n");
+		bat_dbg(DBG_BATMAN, "Drop packet: originator packet with tq equal 0 \n");
 		return;
 	}
 
 	if (is_my_oldorig) {
-		debug_log(LOG_TYPE_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %s) \n", neigh_str);
+		bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %pM) \n", ethhdr->h_source);
 		return;
 	}
 
@@ -504,507 +477,502 @@ void receive_bat_packet(struct ethhdr *e
 		return;
 
 	/* avoid temporary routing loops */
-	if ((orig_node->router) && (orig_node->router->orig_node->router) &&
-	    (compare_orig(orig_node->router->addr, batman_packet->prev_sender)) &&
+	if ((orig_node->router) &&
+	    (orig_node->router->orig_node->router) &&
+	    (compare_orig(orig_node->router->addr,
+			  batman_packet->prev_sender)) &&
 	    !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) &&
-	    (compare_orig(orig_node->router->addr, orig_node->router->orig_node->router->addr))) {
-		debug_log(LOG_TYPE_BATMAN, "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %s) \n", neigh_str);
+	    (compare_orig(orig_node->router->addr,
+			  orig_node->router->orig_node->router->addr))) {
+		bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM) \n", ethhdr->h_source);
 		return;
 	}
 
-	/* if sender is a direct neighbor the sender mac equals originator mac */
-	orig_neigh_node = (is_single_hop_neigh ? orig_node : get_orig_node(ethhdr->h_source));
+	/* if sender is a direct neighbor the sender mac equals
+	 * originator mac */
+	orig_neigh_node = (is_single_hop_neigh ?
+			   orig_node : get_orig_node(ethhdr->h_source));
 	if (orig_neigh_node == NULL)
 		return;
 
-	/* drop packet if sender is not a direct neighbor and if we don't route towards it */
-	if (!is_single_hop_neigh && (orig_neigh_node->router == NULL)) {
-		debug_log(LOG_TYPE_BATMAN, "Drop packet: OGM via unknown neighbor! \n");
+	/* drop packet if sender is not a direct neighbor and if we
+	 * don't route towards it */
+	if (!is_single_hop_neigh &&
+	    (orig_neigh_node->router == NULL)) {
+		bat_dbg(DBG_BATMAN, "Drop packet: OGM via unknown neighbor!\n");
 		return;
 	}
 
-	is_bidirectional = isBidirectionalNeigh(orig_node, orig_neigh_node, batman_packet, if_incoming);
+	is_bidirectional = isBidirectionalNeigh(orig_node, orig_neigh_node,
+						batman_packet, if_incoming);
 
-	/* update ranking if it is not a duplicate or has the same seqno and similar ttl as the non-duplicate */
-	if (is_bidirectional && (!is_duplicate ||
-		((orig_node->last_real_seqno == batman_packet->seqno) &&
-			(orig_node->last_ttl - 3 <= batman_packet->ttl))))
-		update_orig(orig_node, ethhdr, batman_packet, if_incoming, hna_buff, hna_buff_len, is_duplicate);
+	/* update ranking if it is not a duplicate or has the same
+	 * seqno and similar ttl as the non-duplicate */
+	if (is_bidirectional &&
+	    (!is_duplicate ||
+	     ((orig_node->last_real_seqno == batman_packet->seqno) &&
+	      (orig_node->last_ttl - 3 <= batman_packet->ttl))))
+		update_orig(orig_node, ethhdr, batman_packet,
+			    if_incoming, hna_buff, hna_buff_len, is_duplicate);
 
-	/* is single hop (direct) neighbour */
+	/* is single hop (direct) neighbor */
 	if (is_single_hop_neigh) {
 
 		/* mark direct link on incoming interface */
-		schedule_forward_packet(orig_node, ethhdr, batman_packet, 1, hna_buff_len, if_incoming);
+		schedule_forward_packet(orig_node, ethhdr, batman_packet,
+					1, hna_buff_len, if_incoming);
 
-		debug_log(LOG_TYPE_BATMAN, "Forwarding packet: rebroadcast neighbour packet with direct link flag \n");
+		bat_dbg(DBG_BATMAN, "Forwarding packet: rebroadcast neighbor packet with direct link flag\n");
 		return;
 	}
 
 	/* multihop originator */
 	if (!is_bidirectional) {
-		debug_log(LOG_TYPE_BATMAN, "Drop packet: not received via bidirectional link\n");
+		bat_dbg(DBG_BATMAN,
+			"Drop packet: not received via bidirectional link\n");
 		return;
 	}
 
 	if (is_duplicate) {
-		debug_log(LOG_TYPE_BATMAN, "Drop packet: duplicate packet received\n");
+		bat_dbg(DBG_BATMAN, "Drop packet: duplicate packet received\n");
 		return;
 	}
 
-	debug_log(LOG_TYPE_BATMAN, "Forwarding packet: rebroadcast originator packet \n");
-	schedule_forward_packet(orig_node, ethhdr, batman_packet, 0, hna_buff_len, if_incoming);
+	bat_dbg(DBG_BATMAN,
+		"Forwarding packet: rebroadcast originator packet\n");
+	schedule_forward_packet(orig_node, ethhdr, batman_packet,
+				0, hna_buff_len, if_incoming);
 }
 
-void purge_orig(struct work_struct *work)
+int recv_bat_packet(struct sk_buff *skb,
+				struct batman_if *batman_if)
 {
-	struct list_head *list_pos, *list_pos_tmp;
-	struct hash_it_t *hashit = NULL;
-	struct orig_node *orig_node;
-	struct neigh_node *neigh_node, *best_neigh_node;
-	char orig_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN], neigh_purged;
-
-	spin_lock(&orig_hash_lock);
-
-	/* for all origins... */
-	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
-
-		orig_node = hashit->bucket->data;
-		addr_to_string(orig_str, orig_node->orig);
-
-		if (time_after(jiffies, orig_node->last_valid + ((2 * PURGE_TIMEOUT * HZ) / 1000))) {
-
-			debug_log(LOG_TYPE_BATMAN, "Originator timeout: originator %s, last_valid %u \n", orig_str, (orig_node->last_valid / HZ));
+	struct ethhdr *ethhdr;
+	unsigned long flags;
 
-			hash_remove_bucket(orig_hash, hashit);
-			free_orig_node(orig_node);
+	/* drop packet if it has not necessary minimum size */
+	if (skb_headlen(skb) < sizeof(struct batman_packet))
+		return NET_RX_DROP;
 
-		} else {
+	ethhdr = (struct ethhdr *)skb_mac_header(skb);
 
-			best_neigh_node = NULL;
-			neigh_purged = 0;
+	/* packet with broadcast indication but unicast recipient */
+	if (!is_bcast(ethhdr->h_dest))
+		return NET_RX_DROP;
 
-			/* for all neighbours towards this originator ... */
-			list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
-				neigh_node = list_entry(list_pos, struct neigh_node, list);
+	/* packet with broadcast sender address */
+	if (is_bcast(ethhdr->h_source))
+		return NET_RX_DROP;
 
-				if (time_after(jiffies, neigh_node->last_valid + ((PURGE_TIMEOUT * HZ) / 1000))) {
+	spin_lock_irqsave(&orig_hash_lock, flags);
+	/* TODO: we use headlen instead of "length", because
+	 * only this data is paged in. */
+	/* TODO: is another skb_copy needed here? there will be
+	 * written on the data, but nobody (?) should further use
+	 * this data */
+	receive_aggr_bat_packet(ethhdr,
+				skb->data,
+				skb_headlen(skb),
+				batman_if);
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-					addr_to_string(neigh_str, neigh_node->addr);
-					debug_log(LOG_TYPE_BATMAN, "Neighbour timeout: originator %s, neighbour: %s, last_valid %u \n", orig_str, neigh_str, (neigh_node->last_valid / HZ));
+	kfree_skb(skb);
+	return NET_RX_SUCCESS;
+}
 
-					neigh_purged = 1;
-					list_del(list_pos);
-					kfree(neigh_node);
+static int recv_my_icmp_packet(struct sk_buff *skb)
+{
+	struct orig_node *orig_node;
+	struct icmp_packet *icmp_packet;
+	struct ethhdr *ethhdr;
+	struct sk_buff *skb_old;
+	struct batman_if *batman_if;
+	int ret;
+	unsigned long flags;
+	uint8_t dstaddr[ETH_ALEN];
 
-				} else {
+	icmp_packet = (struct icmp_packet *) skb->data;
+	ethhdr = (struct ethhdr *) skb_mac_header(skb);
 
-					if ((best_neigh_node == NULL) || (neigh_node->tq_avg > best_neigh_node->tq_avg))
-						best_neigh_node = neigh_node;
+	/* add data to device queue */
+	if (icmp_packet->msg_type != ECHO_REQUEST) {
+		bat_device_receive_packet(icmp_packet);
+		return NET_RX_DROP;
+	}
 
-				}
+	/* answer echo request (ping) */
+	/* get routing information */
+	spin_lock_irqsave(&orig_hash_lock, flags);
+	orig_node = ((struct orig_node *)hash_find(orig_hash,
+						   icmp_packet->orig));
+	ret = NET_RX_DROP;
 
-			}
+	if ((orig_node != NULL) &&
+	    (orig_node->batman_if != NULL) &&
+	    (orig_node->router != NULL)) {
 
-			if (neigh_purged)
-				update_routes(orig_node, best_neigh_node, orig_node->hna_buff, orig_node->hna_buff_len);
+		/* don't lock while sending the packets ... we therefore
+		 * copy the required data before sending */
+		batman_if = orig_node->batman_if;
+		memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
+		/* create a copy of the skb, if needed, to modify it. */
+		skb_old = NULL;
+		if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
+			skb_old = skb;
+			skb = skb_copy(skb, GFP_ATOMIC);
+			if (!skb)
+				return NET_RX_DROP;
+			icmp_packet = (struct icmp_packet *) skb->data;
+			kfree_skb(skb_old);
 		}
 
-	}
-
-	spin_unlock(&orig_hash_lock);
-
-	start_purge_timer();
-}
-
-static int receive_raw_packet(struct socket *raw_sock, unsigned char *packet_buff, int packet_buff_len)
-{
-	struct kvec iov;
-	struct msghdr msg;
+		memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
+		memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
+		icmp_packet->msg_type = ECHO_REPLY;
+		icmp_packet->ttl = TTL;
 
-	iov.iov_base = packet_buff;
-	iov.iov_len = packet_buff_len;
+		send_skb_packet(skb, batman_if, dstaddr);
+		ret = NET_RX_SUCCESS;
 
-	msg.msg_flags = MSG_DONTWAIT;	/* non-blocking */
-	msg.msg_name = NULL;
-	msg.msg_namelen = 0;
-	msg.msg_control = NULL;
+	} else
+		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-	return kernel_recvmsg(raw_sock, &msg, &iov, 1, packet_buff_len, MSG_DONTWAIT);
+	return ret;
 }
 
-int packet_recv_thread(void *data)
+static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
 {
-	struct batman_if *batman_if;
-	struct ethhdr *ethhdr;
-	struct batman_packet *batman_packet;
-	struct unicast_packet *unicast_packet;
-	struct bcast_packet *bcast_packet;
-	struct icmp_packet *icmp_packet;
-	struct vis_packet *vis_packet;
 	struct orig_node *orig_node;
-	unsigned char *packet_buff, src_str[ETH_STR_LEN], dst_str[ETH_STR_LEN];
-	int vis_info_len;
-	int result;
-
-	atomic_set(&data_ready_cond, 0);
-	atomic_set(&exit_cond, 0);
-	packet_buff = kmalloc(PACKBUFF_SIZE, GFP_KERNEL);
-	if (!packet_buff) {
-		debug_log(LOG_TYPE_CRIT, "Could allocate memory for the packet buffer. :(\n");
-		return -1;
-	}
-
-	while ((!kthread_should_stop()) && (!atomic_read(&exit_cond))) {
-
-		wait_event_interruptible(thread_wait, (atomic_read(&data_ready_cond) || atomic_read(&exit_cond)));
-
-		atomic_set(&data_ready_cond, 0);
-
-		if (kthread_should_stop() || atomic_read(&exit_cond))
-			break;
-
-		/* we only want to safely traverse the list, hard-interfaces
-		 * won't be deleted anyway as long as this thread runs. */
-
-		rcu_read_lock();
-		list_for_each_entry_rcu(batman_if, &if_list, list) {
-			rcu_read_unlock();
-
-			result = -1;
-
-			while (1) {
-				if (batman_if->if_active != IF_ACTIVE) {
-					if (batman_if->if_active != IF_TO_BE_ACTIVATED)
-						debug_log(LOG_TYPE_NOTICE,
-						          "Could not read from deactivated interface %s!\n",
-						          batman_if->dev);
-
-					if (batman_if->raw_sock)
-						receive_raw_packet(batman_if->raw_sock, packet_buff, PACKBUFF_SIZE);
-					result = 0;
-					break;
-				}
-
-				result = receive_raw_packet(batman_if->raw_sock, packet_buff, PACKBUFF_SIZE);
-				if (result <= 0)
-					break;
-
-				if (result < sizeof(struct ethhdr) + 2)
-					continue;
-
-				ethhdr = (struct ethhdr *)packet_buff;
-				batman_packet = (struct batman_packet *)(packet_buff + sizeof(struct ethhdr));
-
-				if (batman_packet->version != COMPAT_VERSION) {
-					debug_log(LOG_TYPE_BATMAN, "Drop packet: incompatible batman version (%i) \n", batman_packet->version);
-					continue;
-				}
-
-				switch (batman_packet->packet_type) {
-				/* batman originator packet */
-				case BAT_PACKET:
-					/* packet with broadcast indication but unicast recipient */
-					if (!is_bcast(ethhdr->h_dest))
-						continue;
-
-					/* packet with broadcast sender address */
-					if (is_bcast(ethhdr->h_source))
-						continue;
-
-					/* drop packet if it has not at least one batman packet as payload */
-					if (result < sizeof(struct ethhdr) + sizeof(struct batman_packet))
-						continue;
-
-					spin_lock(&orig_hash_lock);
-					receive_aggr_bat_packet(ethhdr,
-					                        packet_buff + sizeof(struct ethhdr),
-					                        result - sizeof(struct ethhdr),
-					                        batman_if);
-					spin_unlock(&orig_hash_lock);
-
-					break;
+	struct icmp_packet *icmp_packet;
+	struct ethhdr *ethhdr;
+	struct sk_buff *skb_old;
+	struct batman_if *batman_if;
+	int ret;
+	unsigned long flags;
+	uint8_t dstaddr[ETH_ALEN];
 
-				/* batman icmp packet */
-				case BAT_ICMP:
-					/* packet with unicast indication but broadcast recipient */
-					if (is_bcast(ethhdr->h_dest))
-						continue;
+	icmp_packet = (struct icmp_packet *)skb->data;
+	ethhdr = (struct ethhdr *)skb_mac_header(skb);
 
-					/* packet with broadcast sender address */
-					if (is_bcast(ethhdr->h_source))
-						continue;
+	/* send TTL exceeded if packet is an echo request (traceroute) */
+	if (icmp_packet->msg_type != ECHO_REQUEST) {
+		printk(KERN_WARNING "batman-adv:Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n",
+			icmp_packet->orig, icmp_packet->dst);
+		return NET_RX_DROP;
+	}
 
-					/* not for me */
-					if (!is_my_mac(ethhdr->h_dest))
-						continue;
+	/* get routing information */
+	spin_lock_irqsave(&orig_hash_lock, flags);
+	orig_node = ((struct orig_node *)
+		     hash_find(orig_hash, icmp_packet->orig));
+	ret = NET_RX_DROP;
 
-					/* drop packet if it has not necessary minimum size */
-					if (result < sizeof(struct ethhdr) + sizeof(struct icmp_packet))
-						continue;
+	if ((orig_node != NULL) &&
+	    (orig_node->batman_if != NULL) &&
+	    (orig_node->router != NULL)) {
 
-					icmp_packet = (struct icmp_packet *)(packet_buff + sizeof(struct ethhdr));
+		/* don't lock while sending the packets ... we therefore
+		 * copy the required data before sending */
+		batman_if = orig_node->batman_if;
+		memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-					/* packet for me */
-					if (is_my_mac(icmp_packet->dst)) {
+		/* create a copy of the skb, if needed, to modify it. */
+		if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
+			skb_old = skb;
+			skb = skb_copy(skb, GFP_ATOMIC);
+			if (!skb)
+				return NET_RX_DROP;
+			icmp_packet = (struct icmp_packet *) skb->data;
+			kfree_skb(skb_old);
+		}
 
-						/* add data to device queue */
-						if (icmp_packet->msg_type != ECHO_REQUEST) {
-							bat_device_receive_packet(icmp_packet);
-							continue;
-						}
+		memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
+		memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
+		icmp_packet->msg_type = TTL_EXCEEDED;
+		icmp_packet->ttl = TTL;
 
-						/* answer echo request (ping) */
-						/* get routing information */
-						spin_lock(&orig_hash_lock);
-						orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet->orig));
+		send_skb_packet(skb, batman_if, dstaddr);
+		ret = NET_RX_SUCCESS;
 
-						if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
+	} else
+		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-							memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
-							memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
-							icmp_packet->msg_type = ECHO_REPLY;
-							icmp_packet->ttl = TTL;
+	return ret;
+}
 
-							send_raw_packet(packet_buff + sizeof(struct ethhdr),
-							                result - sizeof(struct ethhdr),
-							                orig_node->batman_if,
-							                orig_node->router->addr);
 
-						}
+int recv_icmp_packet(struct sk_buff *skb)
+{
+	struct icmp_packet *icmp_packet;
+	struct ethhdr *ethhdr;
+	struct orig_node *orig_node;
+	struct sk_buff *skb_old;
+	struct batman_if *batman_if;
+	int hdr_size = sizeof(struct icmp_packet);
+	int ret;
+	unsigned long flags;
+	uint8_t dstaddr[ETH_ALEN];
 
-						spin_unlock(&orig_hash_lock);
-						continue;
+	/* drop packet if it has not necessary minimum size */
+	if (skb_headlen(skb) < hdr_size)
+		return NET_RX_DROP;
 
-					}
+	ethhdr = (struct ethhdr *)skb_mac_header(skb);
 
-					/* TTL exceeded */
-					if (icmp_packet->ttl < 2) {
+	/* packet with unicast indication but broadcast recipient */
+	if (is_bcast(ethhdr->h_dest))
+		return NET_RX_DROP;
 
-						addr_to_string(src_str, icmp_packet->orig);
-						addr_to_string(dst_str, icmp_packet->dst);
+	/* packet with broadcast sender address */
+	if (is_bcast(ethhdr->h_source))
+		return NET_RX_DROP;
 
-						debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str);
+	/* not for me */
+	if (!is_my_mac(ethhdr->h_dest))
+		return NET_RX_DROP;
 
-						/* send TTL exceeded if packet is an echo request (traceroute) */
-						if (icmp_packet->msg_type != ECHO_REQUEST)
-							continue;
+	icmp_packet = (struct icmp_packet *) skb->data;
 
-						/* get routing information */
-						spin_lock(&orig_hash_lock);
-						orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet->orig));
+	/* packet for me */
+	if (is_my_mac(icmp_packet->dst))
+		return recv_my_icmp_packet(skb);
 
-						if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
+	/* TTL exceeded */
+	if (icmp_packet->ttl < 2)
+		return recv_icmp_ttl_exceeded(skb);
 
-							memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
-							memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
-							icmp_packet->msg_type = TTL_EXCEEDED;
-							icmp_packet->ttl = TTL;
+	ret = NET_RX_DROP;
 
-							send_raw_packet(packet_buff + sizeof(struct ethhdr),
-							                result - sizeof(struct ethhdr),
-							                orig_node->batman_if,
-							                orig_node->router->addr);
+	/* get routing information */
+	spin_lock_irqsave(&orig_hash_lock, flags);
+	orig_node = ((struct orig_node *)
+		     hash_find(orig_hash, icmp_packet->dst));
 
-						}
+	if ((orig_node != NULL) &&
+	    (orig_node->batman_if != NULL) &&
+	    (orig_node->router != NULL)) {
 
-						spin_unlock(&orig_hash_lock);
-						continue;
+		/* don't lock while sending the packets ... we therefore
+		 * copy the required data before sending */
+		batman_if = orig_node->batman_if;
+		memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-					}
+		/* create a copy of the skb, if needed, to modify it. */
+		if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
+			skb_old = skb;
+			skb = skb_copy(skb, GFP_ATOMIC);
+			if (!skb)
+				return NET_RX_DROP;
+			icmp_packet = (struct icmp_packet *) skb->data;
+			kfree_skb(skb_old);
+		}
 
-					/* get routing information */
-					spin_lock(&orig_hash_lock);
-					orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet->dst));
+		/* decrement ttl */
+		icmp_packet->ttl--;
 
-					if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
+		/* route it */
+		send_skb_packet(skb, batman_if, dstaddr);
+		ret = NET_RX_SUCCESS;
 
-						/* decrement ttl */
-						icmp_packet->ttl--;
+	} else
+		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-						/* route it */
-						send_raw_packet(packet_buff + sizeof(struct ethhdr),
-						                result - sizeof(struct ethhdr),
-						                orig_node->batman_if,
-						                orig_node->router->addr);
-					}
+	return ret;
+}
 
-					spin_unlock(&orig_hash_lock);
-					break;
+int recv_unicast_packet(struct sk_buff *skb)
+{
+	struct unicast_packet *unicast_packet;
+	struct orig_node *orig_node;
+	struct ethhdr *ethhdr;
+	struct batman_if *batman_if;
+	struct sk_buff *skb_old;
+	uint8_t dstaddr[ETH_ALEN];
+	int hdr_size = sizeof(struct unicast_packet);
+	int ret;
+	unsigned long flags;
 
-				/* unicast packet */
-				case BAT_UNICAST:
-					/* packet with unicast indication but broadcast recipient */
-					if (is_bcast(ethhdr->h_dest))
-						continue;
+	/* drop packet if it has not necessary minimum size */
+	if (skb_headlen(skb) < hdr_size)
+		return NET_RX_DROP;
 
-					/* packet with broadcast sender address */
-					if (is_bcast(ethhdr->h_source))
-						continue;
+	ethhdr = (struct ethhdr *) skb_mac_header(skb);
 
-					/* not for me */
-					if (!is_my_mac(ethhdr->h_dest))
-						continue;
+	/* packet with unicast indication but broadcast recipient */
+	if (is_bcast(ethhdr->h_dest))
+		return NET_RX_DROP;
 
-					/* drop packet if it has not necessary minimum size */
-					if (result < sizeof(struct ethhdr) + sizeof(struct unicast_packet))
-						continue;
+	/* packet with broadcast sender address */
+	if (is_bcast(ethhdr->h_source))
+		return NET_RX_DROP;
 
-					unicast_packet = (struct unicast_packet *)(packet_buff + sizeof(struct ethhdr));
+	/* not for me */
+	if (!is_my_mac(ethhdr->h_dest))
+		return NET_RX_DROP;
 
-					/* packet for me */
-					if (is_my_mac(unicast_packet->dest)) {
+	unicast_packet = (struct unicast_packet *) skb->data;
 
-						interface_rx(soft_device, packet_buff + sizeof(struct ethhdr) + sizeof(struct unicast_packet), result - sizeof(struct ethhdr) - sizeof(struct unicast_packet));
-						continue;
+	/* packet for me */
+	if (is_my_mac(unicast_packet->dest)) {
+		interface_rx(skb, hdr_size);
+		return NET_RX_SUCCESS;
+	}
 
-					}
+	/* TTL exceeded */
+	if (unicast_packet->ttl < 2) {
+		printk(KERN_WARNING "batman-adv:Warning - can't forward unicast packet from %pM to %pM: ttl exceeded\n",
+		       ethhdr->h_source, unicast_packet->dest);
+		return NET_RX_DROP;
+	}
 
-					/* TTL exceeded */
-					if (unicast_packet->ttl < 2) {
-						addr_to_string(src_str, ((struct ethhdr *)(unicast_packet + 1))->h_source);
-						addr_to_string(dst_str, unicast_packet->dest);
+	ret = NET_RX_DROP;
+	/* get routing information */
+	spin_lock_irqsave(&orig_hash_lock, flags);
+	orig_node = ((struct orig_node *)
+		     hash_find(orig_hash, unicast_packet->dest));
 
-						debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str);
-						continue;
-					}
+	if ((orig_node != NULL) &&
+	    (orig_node->batman_if != NULL) &&
+	    (orig_node->router != NULL)) {
 
-					/* get routing information */
-					spin_lock(&orig_hash_lock);
-					orig_node = ((struct orig_node *)hash_find(orig_hash, unicast_packet->dest));
+		/* don't lock while sending the packets ... we therefore
+		 * copy the required data before sending */
+		batman_if = orig_node->batman_if;
+		memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-					if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
-						/* decrement ttl */
-						unicast_packet->ttl--;
+		/* create a copy of the skb, if needed, to modify it. */
+		if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) {
+			skb_old = skb;
+			skb = skb_copy(skb, GFP_ATOMIC);
+			if (!skb)
+				return NET_RX_DROP;
+			unicast_packet = (struct unicast_packet *) skb->data;
+			kfree_skb(skb_old);
+		}
+		/* decrement ttl */
+		unicast_packet->ttl--;
 
-						/* route it */
-						send_raw_packet(packet_buff + sizeof(struct ethhdr),
-						                result - sizeof(struct ethhdr),
-						                orig_node->batman_if,
-						                orig_node->router->addr);
-					}
+		/* route it */
+		send_skb_packet(skb, batman_if, dstaddr);
+		ret = NET_RX_SUCCESS;
 
-					spin_unlock(&orig_hash_lock);
-					break;
+	} else
+		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-				/* broadcast packet */
-				case BAT_BCAST:
-					/* packet with broadcast indication but unicast recipient */
-					if (!is_bcast(ethhdr->h_dest))
-						continue;
+	return ret;
+}
 
-					/* packet with broadcast sender address */
-					if (is_bcast(ethhdr->h_source))
-						continue;
 
-					/* drop packet if it has not necessary minimum size */
-					if (result < sizeof(struct ethhdr) + sizeof(struct bcast_packet))
-						continue;
+int recv_bcast_packet(struct sk_buff *skb)
+{
+	struct orig_node *orig_node;
+	struct bcast_packet *bcast_packet;
+	struct ethhdr *ethhdr;
+	int hdr_size = sizeof(struct bcast_packet);
+	unsigned long flags;
 
-					/* ignore broadcasts sent by myself */
-					if (is_my_mac(ethhdr->h_source))
-						continue;
+	/* drop packet if it has not necessary minimum size */
+	if (skb_headlen(skb) < hdr_size)
+		return NET_RX_DROP;
 
-					bcast_packet = (struct bcast_packet *)(packet_buff + sizeof(struct ethhdr));
+	ethhdr = (struct ethhdr *)skb_mac_header(skb);
 
-					/* ignore broadcasts originated by myself */
-					if (is_my_mac(bcast_packet->orig))
-						continue;
+	/* packet with broadcast indication but unicast recipient */
+	if (!is_bcast(ethhdr->h_dest))
+		return NET_RX_DROP;
 
-					spin_lock(&orig_hash_lock);
-					orig_node = ((struct orig_node *)hash_find(orig_hash, bcast_packet->orig));
+	/* packet with broadcast sender address */
+	if (is_bcast(ethhdr->h_source))
+		return NET_RX_DROP;
 
-					if (orig_node == NULL) {
-						spin_unlock(&orig_hash_lock);
-						continue;
-					}
+	/* ignore broadcasts sent by myself */
+	if (is_my_mac(ethhdr->h_source))
+		return NET_RX_DROP;
 
-					/* check flood history */
-					if (get_bit_status(orig_node->bcast_bits, orig_node->last_bcast_seqno, ntohs(bcast_packet->seqno))) {
-						spin_unlock(&orig_hash_lock);
-						continue;
-					}
+	bcast_packet = (struct bcast_packet *) skb->data;
 
-					/* mark broadcast in flood history */
-					if (bit_get_packet(orig_node->bcast_bits, ntohs(bcast_packet->seqno) - orig_node->last_bcast_seqno, 1))
-						orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno);
+	/* ignore broadcasts originated by myself */
+	if (is_my_mac(bcast_packet->orig))
+		return NET_RX_DROP;
 
-					spin_unlock(&orig_hash_lock);
+	spin_lock_irqsave(&orig_hash_lock, flags);
+	orig_node = ((struct orig_node *)
+		     hash_find(orig_hash, bcast_packet->orig));
 
-					/* broadcast for me */
-					interface_rx(soft_device, packet_buff + sizeof(struct ethhdr) + sizeof(struct bcast_packet), result - sizeof(struct ethhdr) - sizeof(struct bcast_packet));
+	if (orig_node == NULL) {
+		spin_unlock_irqrestore(&orig_hash_lock, flags);
+		return NET_RX_DROP;
+	}
 
-					/* rebroadcast packet */
-					add_bcast_packet_to_list(packet_buff + sizeof(struct ethhdr),
-									result - sizeof(struct ethhdr));
+	/* check flood history */
+	if (get_bit_status(orig_node->bcast_bits,
+			   orig_node->last_bcast_seqno,
+			   ntohs(bcast_packet->seqno))) {
+		spin_unlock_irqrestore(&orig_hash_lock, flags);
+		return NET_RX_DROP;
+	}
 
-					break;
+	/* mark broadcast in flood history */
+	if (bit_get_packet(orig_node->bcast_bits,
+			   ntohs(bcast_packet->seqno) -
+			   orig_node->last_bcast_seqno, 1))
+		orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno);
 
-				/* vis packet */
-				case BAT_VIS:
-					/* drop if too short. */
-					if (result < sizeof(struct ethhdr) + sizeof(struct vis_packet))
-						continue;
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-					/* not for me */
-					if (!is_my_mac(ethhdr->h_dest))
-						continue;
+	/* rebroadcast packet */
+	add_bcast_packet_to_list(skb);
 
-					vis_packet = (struct vis_packet *)(packet_buff + sizeof(struct ethhdr));
-					vis_info_len = result  - sizeof(struct ethhdr) - sizeof(struct vis_packet);
+	/* broadcast for me */
+	interface_rx(skb, hdr_size);
 
-					/* ignore own packets */
-					if (is_my_mac(vis_packet->vis_orig))
-						continue;
+	return NET_RX_SUCCESS;
+}
 
-					if (is_my_mac(vis_packet->sender_orig))
-						continue;
+int recv_vis_packet(struct sk_buff *skb)
+{
+	struct vis_packet *vis_packet;
+	struct ethhdr *ethhdr;
+	int hdr_size = sizeof(struct vis_packet);
 
-					switch (vis_packet->vis_type) {
-					case VIS_TYPE_SERVER_SYNC:
-						receive_server_sync_packet(vis_packet, vis_info_len);
-						break;
+	if (skb_headlen(skb) < hdr_size)
+		return NET_RX_DROP;
 
-					case VIS_TYPE_CLIENT_UPDATE:
-						receive_client_update_packet(vis_packet, vis_info_len);
-						break;
+	vis_packet = (struct vis_packet *) skb->data;
+	ethhdr = (struct ethhdr *)skb_mac_header(skb);
 
-					default:	/* ignore unknown packet */
-						break;
-					}
+	/* not for me */
+	if (!is_my_mac(ethhdr->h_dest))
+		return NET_RX_DROP;
 
-					break;
-				}
+	/* ignore own packets */
+	if (is_my_mac(vis_packet->vis_orig))
+		return NET_RX_DROP;
 
-			}
+	if (is_my_mac(vis_packet->sender_orig))
+		return NET_RX_DROP;
 
-			if ((result < 0) && (result != -EAGAIN))
-				debug_log(LOG_TYPE_CRIT, "Could not receive packet from interface %s: %i\n", batman_if->dev, result);
+	switch (vis_packet->vis_type) {
+	case VIS_TYPE_SERVER_SYNC:
+		/* TODO: handle fragmented skbs properly */
+		receive_server_sync_packet(vis_packet, skb_headlen(skb));
+		break;
 
-			/* lock for the next iteration */
-			rcu_read_lock();
-		}
-		rcu_read_unlock();
+	case VIS_TYPE_CLIENT_UPDATE:
+		/* TODO: handle fragmented skbs properly */
+		receive_client_update_packet(vis_packet, skb_headlen(skb));
+		break;
 
+	default:	/* ignore unknown packet */
+		break;
 	}
-	kfree(packet_buff);
-
-	/* do not exit until kthread_stop() is actually called, otherwise it will wait for us
-	 * forever. */
-	while (!kthread_should_stop())
-		schedule();
-
-	return 0;
-}
 
-void batman_data_ready(struct sock *sk, int len)
-{
-	void (*data_ready)(struct sock *, int) = sk->sk_user_data;
-
-	data_ready(sk, len);
-
-	atomic_set(&data_ready_cond, 1);
-	wake_up_interruptible(&thread_wait);
+	/* We take a copy of the data in the packet, so we should
+	   always free the skbuf. */
+	return NET_RX_DROP;
 }
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/routing.h linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/routing.h
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/routing.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/routing.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,13 +22,18 @@
 #include "types.h"
 
 extern wait_queue_head_t thread_wait;
-extern atomic_t exit_cond;
 
-int originator_init(void);
-void free_orig_node(void *data);
-void originator_free(void);
 void slide_own_bcast_window(struct batman_if *batman_if);
-void batman_data_ready(struct sock *sk, int len);
-void purge_orig(struct work_struct *work);
-int packet_recv_thread(void *data);
-void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_packet, unsigned char *hna_buff, int hna_buff_len, struct batman_if *if_incoming);
+void receive_bat_packet(struct ethhdr *ethhdr,
+				struct batman_packet *batman_packet,
+				unsigned char *hna_buff, int hna_buff_len,
+				struct batman_if *if_incoming);
+void update_routes(struct orig_node *orig_node,
+				struct neigh_node *neigh_node,
+				unsigned char *hna_buff, int hna_buff_len);
+int recv_icmp_packet(struct sk_buff *skb);
+int recv_unicast_packet(struct sk_buff *skb);
+int recv_bcast_packet(struct sk_buff *skb);
+int recv_vis_packet(struct sk_buff *skb);
+int recv_bat_packet(struct sk_buff *skb,
+				struct batman_if *batman_if);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/send.c linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/send.c
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/send.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/send.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,16 +21,14 @@
 
 #include "main.h"
 #include "send.h"
-#include "log.h"
 #include "routing.h"
 #include "translation-table.h"
+#include "soft-interface.h"
 #include "hard-interface.h"
 #include "types.h"
 #include "vis.h"
 #include "aggregation.h"
 
-#include "compat.h"
-
 /* apply hop penalty for a normal link */
 static uint8_t hop_penalty(const uint8_t tq)
 {
@@ -59,51 +57,69 @@ static unsigned long forward_send_time(v
 	return send_time;
 }
 
-/* sends a raw packet. */
-void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
-		     struct batman_if *batman_if, uint8_t *dst_addr)
+/* send out an already prepared packet to the given address via the
+ * specified batman interface */
+int send_skb_packet(struct sk_buff *skb,
+				struct batman_if *batman_if,
+				uint8_t *dst_addr)
 {
 	struct ethhdr *ethhdr;
-	struct sk_buff *skb;
-	int retval;
-	char *data;
 
 	if (batman_if->if_active != IF_ACTIVE)
-		return;
+		goto send_skb_err;
+
+	if (unlikely(!batman_if->net_dev))
+		goto send_skb_err;
 
 	if (!(batman_if->net_dev->flags & IFF_UP)) {
-		debug_log(LOG_TYPE_WARN,
-		         "Interface %s is not up - can't send packet via that interface (IF_TO_BE_DEACTIVATED was here) !\n",
-		          batman_if->dev);
-		return;
+		printk(KERN_WARNING
+		       "batman-adv:Interface %s is not up - can't send packet via that interface!\n",
+		       batman_if->dev);
+		goto send_skb_err;
 	}
 
-	skb = dev_alloc_skb(pack_buff_len + sizeof(struct ethhdr));
-	if (!skb)
-		return;
-	data = skb_put(skb, pack_buff_len + sizeof(struct ethhdr));
+	/* push to the ethernet header. */
+	if (my_skb_push(skb, sizeof(struct ethhdr)) < 0)
+		goto send_skb_err;
 
-	memcpy(data + sizeof(struct ethhdr), pack_buff, pack_buff_len);
+	skb_reset_mac_header(skb);
 
-	ethhdr = (struct ethhdr *) data;
+	ethhdr = (struct ethhdr *) skb_mac_header(skb);
 	memcpy(ethhdr->h_source, batman_if->net_dev->dev_addr, ETH_ALEN);
 	memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN);
 	ethhdr->h_proto = __constant_htons(ETH_P_BATMAN);
 
-	skb_reset_mac_header(skb);
 	skb_set_network_header(skb, ETH_HLEN);
 	skb->priority = TC_PRIO_CONTROL;
 	skb->protocol = __constant_htons(ETH_P_BATMAN);
+
 	skb->dev = batman_if->net_dev;
 
 	/* dev_queue_xmit() returns a negative result on error.	 However on
 	 * congestion and traffic shaping, it drops and returns NET_XMIT_DROP
 	 * (which is > 0). This will not be treated as an error. */
-	retval = dev_queue_xmit(skb);
-	if (retval < 0)
-		debug_log(LOG_TYPE_CRIT,
-		          "Can't write to raw socket (IF_TO_BE_DEACTIVATED was here): %i\n",
-		          retval);
+
+	return dev_queue_xmit(skb);
+send_skb_err:
+	kfree_skb(skb);
+	return NET_XMIT_DROP;
+}
+
+/* sends a raw packet. */
+void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
+		     struct batman_if *batman_if, uint8_t *dst_addr)
+{
+	struct sk_buff *skb;
+	char *data;
+
+	skb = dev_alloc_skb(pack_buff_len + sizeof(struct ethhdr));
+	if (!skb)
+		return;
+	data = skb_put(skb, pack_buff_len + sizeof(struct ethhdr));
+	memcpy(data + sizeof(struct ethhdr), pack_buff, pack_buff_len);
+	/* pull back to the batman "network header" */
+	skb_pull(skb, sizeof(struct ethhdr));
+	send_skb_packet(skb, batman_if, dst_addr);
 }
 
 /* Send a packet to a given interface */
@@ -114,7 +130,6 @@ static void send_packet_to_if(struct for
 	uint8_t packet_num;
 	int16_t buff_pos;
 	struct batman_packet *batman_packet;
-	char orig_str[ETH_STR_LEN];
 
 	if (batman_if->if_active != IF_ACTIVE)
 		return;
@@ -136,19 +151,18 @@ static void send_packet_to_if(struct for
 		else
 			batman_packet->flags &= ~DIRECTLINK;
 
-		addr_to_string(orig_str, batman_packet->orig);
 		fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
 							    "Sending own" :
 							    "Forwarding"));
-		debug_log(LOG_TYPE_BATMAN,
-			  "%s %spacket (originator %s, seqno %d, TQ %d, TTL %d, IDF %s) on interface %s [%s]\n",
-			  fwd_str,
-			  (packet_num > 0 ? "aggregated " : ""),
-			  orig_str, ntohs(batman_packet->seqno),
-			  batman_packet->tq, batman_packet->ttl,
-			  (batman_packet->flags & DIRECTLINK ?
-			   "on" : "off"),
-			  batman_if->dev, batman_if->addr_str);
+		bat_dbg(DBG_BATMAN,
+			"%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d, IDF %s) on interface %s [%s]\n",
+			fwd_str,
+			(packet_num > 0 ? "aggregated " : ""),
+			batman_packet->orig, ntohs(batman_packet->seqno),
+			batman_packet->tq, batman_packet->ttl,
+			(batman_packet->flags & DIRECTLINK ?
+			 "on" : "off"),
+			batman_if->dev, batman_if->addr_str);
 
 		buff_pos += sizeof(struct batman_packet) +
 			(batman_packet->num_hna * ETH_ALEN);
@@ -168,32 +182,28 @@ static void send_packet(struct forw_pack
 	struct batman_if *batman_if;
 	struct batman_packet *batman_packet =
 		(struct batman_packet *)(forw_packet->packet_buff);
-	char orig_str[ETH_STR_LEN];
 	unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
 
 	if (!forw_packet->if_incoming) {
-		debug_log(LOG_TYPE_CRIT,
-			  "Error - can't forward packet: incoming iface not specified\n");
+		printk(KERN_ERR "batman-adv: Error - can't forward packet: incoming iface not specified\n");
 		return;
 	}
 
 	if (forw_packet->if_incoming->if_active != IF_ACTIVE)
 		return;
 
-	addr_to_string(orig_str, batman_packet->orig);
-
 	/* multihomed peer assumed */
 	/* non-primary OGMs are only broadcasted on their interface */
 	if ((directlink && (batman_packet->ttl == 1)) ||
 	    (forw_packet->own && (forw_packet->if_incoming->if_num > 0))) {
 
 		/* FIXME: what about aggregated packets ? */
-		debug_log(LOG_TYPE_BATMAN,
-			  "%s packet (originator %s, seqno %d, TTL %d) on interface %s [%s]\n",
-			  (forw_packet->own ? "Sending own" : "Forwarding"),
-			  orig_str, ntohs(batman_packet->seqno),
-			  batman_packet->ttl, forw_packet->if_incoming->dev,
-			  forw_packet->if_incoming->addr_str);
+		bat_dbg(DBG_BATMAN,
+			"%s packet (originator %pM, seqno %d, TTL %d) on interface %s [%s]\n",
+			(forw_packet->own ? "Sending own" : "Forwarding"),
+			batman_packet->orig, ntohs(batman_packet->seqno),
+			batman_packet->ttl, forw_packet->if_incoming->dev,
+			forw_packet->if_incoming->addr_str);
 
 		send_raw_packet(forw_packet->packet_buff,
 				forw_packet->packet_len,
@@ -238,6 +248,7 @@ void schedule_own_packet(struct batman_i
 {
 	unsigned long send_time;
 	struct batman_packet *batman_packet;
+	int vis_server = atomic_read(&vis_mode);
 
 	/**
 	 * the interface gets activated here to avoid race conditions between
@@ -262,7 +273,7 @@ void schedule_own_packet(struct batman_i
 	/* change sequence number to network order */
 	batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno));
 
-	if (is_vis_server())
+	if (vis_server == VIS_TYPE_SERVER_SYNC)
 		batman_packet->flags = VIS_SERVER;
 	else
 		batman_packet->flags = 0;
@@ -286,7 +297,7 @@ void schedule_forward_packet(struct orig
 	unsigned long send_time;
 
 	if (batman_packet->ttl <= 1) {
-		debug_log(LOG_TYPE_BATMAN, "ttl exceeded \n");
+		bat_dbg(DBG_BATMAN, "ttl exceeded \n");
 		return;
 	}
 
@@ -314,9 +325,9 @@ void schedule_forward_packet(struct orig
 	/* apply hop penalty */
 	batman_packet->tq = hop_penalty(batman_packet->tq);
 
-	debug_log(LOG_TYPE_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i \n",
-		  in_tq, tq_avg, batman_packet->tq, in_ttl - 1,
-		  batman_packet->ttl);
+	bat_dbg(DBG_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i \n",
+		in_tq, tq_avg, batman_packet->tq, in_ttl - 1,
+		batman_packet->ttl);
 
 	batman_packet->seqno = htons(batman_packet->seqno);
 
@@ -333,6 +344,8 @@ void schedule_forward_packet(struct orig
 
 static void forw_packet_free(struct forw_packet *forw_packet)
 {
+	if (forw_packet->skb)
+		kfree_skb(forw_packet->skb);
 	kfree(forw_packet->packet_buff);
 	kfree(forw_packet);
 }
@@ -340,12 +353,13 @@ static void forw_packet_free(struct forw
 static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
 				      unsigned long send_time)
 {
+	unsigned long flags;
 	INIT_HLIST_NODE(&forw_packet->list);
 
 	/* add new packet to packet list */
-	spin_lock(&forw_bcast_list_lock);
+	spin_lock_irqsave(&forw_bcast_list_lock, flags);
 	hlist_add_head(&forw_packet->list, &forw_bcast_list);
-	spin_unlock(&forw_bcast_list_lock);
+	spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
 
 	/* start timer for this packet */
 	INIT_DELAYED_WORK(&forw_packet->delayed_work,
@@ -354,7 +368,7 @@ static void _add_bcast_packet_to_list(st
 			   send_time);
 }
 
-void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len)
+void add_bcast_packet_to_list(struct sk_buff *skb)
 {
 	struct forw_packet *forw_packet;
 
@@ -362,14 +376,16 @@ void add_bcast_packet_to_list(unsigned c
 	if (!forw_packet)
 		return;
 
-	forw_packet->packet_buff = kmalloc(packet_len, GFP_ATOMIC);
-	if (!forw_packet->packet_buff) {
+	skb = skb_copy(skb, GFP_ATOMIC);
+	if (!skb) {
 		kfree(forw_packet);
 		return;
 	}
 
-	forw_packet->packet_len = packet_len;
-	memcpy(forw_packet->packet_buff, packet_buff, forw_packet->packet_len);
+	skb_reset_mac_header(skb);
+
+	forw_packet->skb = skb;
+	forw_packet->packet_buff = NULL;
 
 	/* how often did we send the bcast packet ? */
 	forw_packet->num_packets = 0;
@@ -384,16 +400,20 @@ void send_outstanding_bcast_packet(struc
 		container_of(work, struct delayed_work, work);
 	struct forw_packet *forw_packet =
 		container_of(delayed_work, struct forw_packet, delayed_work);
+	unsigned long flags;
+	struct sk_buff *skb1;
 
-	spin_lock(&forw_bcast_list_lock);
+	spin_lock_irqsave(&forw_bcast_list_lock, flags);
 	hlist_del(&forw_packet->list);
-	spin_unlock(&forw_bcast_list_lock);
+	spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
 
 	/* rebroadcast packet */
 	rcu_read_lock();
 	list_for_each_entry_rcu(batman_if, &if_list, list) {
-		send_raw_packet(forw_packet->packet_buff,
-				forw_packet->packet_len,
+		/* send a copy of the saved skb */
+		skb1 = skb_copy(forw_packet->skb, GFP_ATOMIC);
+		if (skb1)
+			send_skb_packet(skb1,
 				batman_if, broadcastAddr);
 	}
 	rcu_read_unlock();
@@ -415,10 +435,11 @@ void send_outstanding_bat_packet(struct
 		container_of(work, struct delayed_work, work);
 	struct forw_packet *forw_packet =
 		container_of(delayed_work, struct forw_packet, delayed_work);
+	unsigned long flags;
 
-	spin_lock(&forw_bat_list_lock);
+	spin_lock_irqsave(&forw_bat_list_lock, flags);
 	hlist_del(&forw_packet->list);
-	spin_unlock(&forw_bat_list_lock);
+	spin_unlock_irqrestore(&forw_bat_list_lock, flags);
 
 	send_packet(forw_packet);
 
@@ -438,38 +459,39 @@ void purge_outstanding_packets(void)
 {
 	struct forw_packet *forw_packet;
 	struct hlist_node *tmp_node, *safe_tmp_node;
+	unsigned long flags;
 
-	debug_log(LOG_TYPE_BATMAN, "purge_outstanding_packets()\n");
+	bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n");
 
 	/* free bcast list */
-	spin_lock(&forw_bcast_list_lock);
+	spin_lock_irqsave(&forw_bcast_list_lock, flags);
 	hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
 				  &forw_bcast_list, list) {
 
-		spin_unlock(&forw_bcast_list_lock);
+		spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
 
 		/**
 		 * send_outstanding_bcast_packet() will lock the list to
 		 * delete the item from the list
 		 */
 		cancel_delayed_work_sync(&forw_packet->delayed_work);
-		spin_lock(&forw_bcast_list_lock);
+		spin_lock_irqsave(&forw_bcast_list_lock, flags);
 	}
-	spin_unlock(&forw_bcast_list_lock);
+	spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
 
 	/* free batman packet list */
-	spin_lock(&forw_bat_list_lock);
+	spin_lock_irqsave(&forw_bat_list_lock, flags);
 	hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
 				  &forw_bat_list, list) {
 
-		spin_unlock(&forw_bat_list_lock);
+		spin_unlock_irqrestore(&forw_bat_list_lock, flags);
 
 		/**
 		 * send_outstanding_bat_packet() will lock the list to
 		 * delete the item from the list
 		 */
 		cancel_delayed_work_sync(&forw_packet->delayed_work);
-		spin_lock(&forw_bat_list_lock);
+		spin_lock_irqsave(&forw_bat_list_lock, flags);
 	}
-	spin_unlock(&forw_bat_list_lock);
+	spin_unlock_irqrestore(&forw_bat_list_lock, flags);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/send.h linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/send.h
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/send.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/send.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,9 @@
 #include "types.h"
 
 void send_own_packet_work(struct work_struct *work);
+int send_skb_packet(struct sk_buff *skb,
+				struct batman_if *batman_if,
+				uint8_t *dst_addr);
 void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
 		     struct batman_if *batman_if, uint8_t *dst_addr);
 void schedule_own_packet(struct batman_if *batman_if);
@@ -30,7 +33,7 @@ void schedule_forward_packet(struct orig
 			     struct batman_packet *batman_packet,
 			     uint8_t directlink, int hna_buff_len,
 			     struct batman_if *if_outgoing);
-void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len);
+void add_bcast_packet_to_list(struct sk_buff *skb);
 void send_outstanding_bcast_packet(struct work_struct *work);
 void send_outstanding_bat_packet(struct work_struct *work);
 void purge_outstanding_packets(void);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/soft-interface.c linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/soft-interface.c
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/soft-interface.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/soft-interface.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,18 +24,16 @@
 #include "hard-interface.h"
 #include "send.h"
 #include "translation-table.h"
-#include "log.h"
 #include "types.h"
 #include "hash.h"
+#include <linux/slab.h>
 #include <linux/ethtool.h>
 #include <linux/etherdevice.h>
-#include "compat.h"
 
 static uint16_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid
 				  * broadcast storms */
 static int32_t skb_packets;
 static int32_t skb_bad_packets;
-static int32_t lock_dropped;
 
 unsigned char mainIfAddr[ETH_ALEN];
 static unsigned char mainIfAddr_default[ETH_ALEN];
@@ -68,12 +66,12 @@ int main_if_was_up(void)
 	return (memcmp(mainIfAddr, mainIfAddr_default, ETH_ALEN) != 0 ? 1 : 0);
 }
 
-static int my_skb_push(struct sk_buff *skb, unsigned int len)
+int my_skb_push(struct sk_buff *skb, unsigned int len)
 {
 	int result = 0;
 
 	skb_packets++;
-	if (skb->data - len < skb->head) {
+	if (skb_headroom(skb) < len) {
 		skb_bad_packets++;
 		result = pskb_expand_head(skb, len, 0, GFP_ATOMIC);
 
@@ -122,7 +120,7 @@ void interface_setup(struct net_device *
 
 	/* generate random address */
 	random_ether_addr(dev_addr);
-	memcpy(dev->dev_addr, dev_addr, sizeof(dev->dev_addr));
+	memcpy(dev->dev_addr, dev_addr, ETH_ALEN);
 
 	SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
 
@@ -147,9 +145,18 @@ struct net_device_stats *interface_stats
 	return &priv->stats;
 }
 
-int interface_set_mac_addr(struct net_device *dev, void *addr)
+int interface_set_mac_addr(struct net_device *dev, void *p)
 {
-	return -EBUSY;
+	struct sockaddr *addr = p;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	hna_local_remove(dev->dev_addr, "mac address changed");
+	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+	hna_local_add(dev->dev_addr);
+
+	return 0;
 }
 
 int interface_change_mtu(struct net_device *dev, int new_mtu)
@@ -170,7 +177,10 @@ int interface_tx(struct sk_buff *skb, st
 	struct orig_node *orig_node;
 	struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
 	struct bat_priv *priv = netdev_priv(dev);
+	struct batman_if *batman_if;
+	uint8_t dstaddr[6];
 	int data_len = skb->len;
+	unsigned long flags;
 
 	if (atomic_read(&module_state) != MODULE_ACTIVE)
 		goto dropped;
@@ -186,7 +196,6 @@ int interface_tx(struct sk_buff *skb, st
 			goto dropped;
 
 		bcast_packet = (struct bcast_packet *)skb->data;
-
 		bcast_packet->version = COMPAT_VERSION;
 
 		/* batman packet type: broadcast */
@@ -195,27 +204,21 @@ int interface_tx(struct sk_buff *skb, st
 		/* hw address of first interface is the orig mac because only
 		 * this mac is known throughout the mesh */
 		memcpy(bcast_packet->orig, mainIfAddr, ETH_ALEN);
+
 		/* set broadcast sequence number */
 		bcast_packet->seqno = htons(bcast_seqno);
 
 		bcast_seqno++;
 
 		/* broadcast packet */
-		add_bcast_packet_to_list(skb->data, skb->len);
+		add_bcast_packet_to_list(skb);
+		/* a copy is stored in the bcast list, therefore removing
+		 * the original skb. */
+		kfree_skb(skb);
 
 	/* unicast packet */
 	} else {
-
-		/* simply spin_lock()ing can deadlock when the lock is already
-		 * hold. */
-		/* TODO: defer the work in a working queue instead of
-		 * dropping */
-		if (!spin_trylock(&orig_hash_lock)) {
-			lock_dropped++;
-			debug_log(LOG_TYPE_NOTICE, "%d packets dropped because lock was hold\n", lock_dropped);
-			goto dropped;
-		}
-
+		spin_lock_irqsave(&orig_hash_lock, flags);
 		/* get routing information */
 		orig_node = ((struct orig_node *)hash_find(orig_hash,
 							   ethhdr->h_dest));
@@ -244,14 +247,17 @@ int interface_tx(struct sk_buff *skb, st
 			if (orig_node->batman_if->if_active != IF_ACTIVE)
 				goto unlock;
 
-			send_raw_packet(skb->data, skb->len,
-					orig_node->batman_if,
-					orig_node->router->addr);
+			/* don't lock while sending the packets ... we therefore
+			 * copy the required data before sending */
+
+			batman_if = orig_node->batman_if;
+			memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+			spin_unlock_irqrestore(&orig_hash_lock, flags);
+
+			send_skb_packet(skb, batman_if, dstaddr);
 		} else {
 			goto unlock;
 		}
-
-		spin_unlock(&orig_hash_lock);
 	}
 
 	priv->stats.tx_packets++;
@@ -259,42 +265,44 @@ int interface_tx(struct sk_buff *skb, st
 	goto end;
 
 unlock:
-	spin_unlock(&orig_hash_lock);
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
 dropped:
 	priv->stats.tx_dropped++;
 end:
-	kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
-void interface_rx(struct net_device *dev, void *packet, int packet_len)
+void interface_rx(struct sk_buff *skb, int hdr_size)
 {
-	struct sk_buff *skb;
+	struct net_device *dev = soft_device;
 	struct bat_priv *priv = netdev_priv(dev);
 
-	skb = dev_alloc_skb(packet_len);
-
-	if (!skb) {
-		priv->stats.rx_dropped++;
-		goto out;
+	/* check if enough space is available for pulling, and pull */
+	if (!pskb_may_pull(skb, hdr_size)) {
+		kfree_skb(skb);
+		return;
 	}
+	skb_pull_rcsum(skb, hdr_size);
+/*	skb_set_mac_header(skb, -sizeof(struct ethhdr));*/
 
-	memcpy(skb_put(skb, packet_len), packet, packet_len);
-
-	/* Write metadata, and then pass to the receive level */
 	skb->dev = dev;
 	skb->protocol = eth_type_trans(skb, dev);
-	skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+	/* should not be neccesary anymore as we use skb_pull_rcsum()
+	 * TODO: please verify this and remove this TODO
+	 * -- Dec 21st 2009, Simon Wunderlich */
+
+/*	skb->ip_summed = CHECKSUM_UNNECESSARY;*/
+
+	/* TODO: set skb->pkt_type to PACKET_BROADCAST, PACKET_MULTICAST,
+	 * PACKET_OTHERHOST or PACKET_HOST */
 
 	priv->stats.rx_packets++;
-	priv->stats.rx_bytes += packet_len;
+	priv->stats.rx_bytes += skb->len;
 
 	dev->last_rx = jiffies;
 
 	netif_rx(skb);
-
-out:
-	return;
 }
 
 /* ethtool */
@@ -330,7 +338,6 @@ static u32 bat_get_msglevel(struct net_d
 
 static void bat_set_msglevel(struct net_device *dev, u32 value)
 {
-	return;
 }
 
 static u32 bat_get_link(struct net_device *dev)
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/soft-interface.h linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/soft-interface.h
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/soft-interface.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/soft-interface.h	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@ struct net_device_stats *interface_stats
 int interface_set_mac_addr(struct net_device *dev, void *addr);
 int interface_change_mtu(struct net_device *dev, int new_mtu);
 int interface_tx(struct sk_buff *skb, struct net_device *dev);
-void interface_rx(struct net_device *dev, void *packet, int packet_len);
+void interface_rx(struct sk_buff *skb, int hdr_size);
+int my_skb_push(struct sk_buff *skb, unsigned int len);
 
 extern unsigned char mainIfAddr[];
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/TODO linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/TODO
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/TODO	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/TODO	2010-05-16 17:17:36.000000000 -0400
@@ -17,30 +17,6 @@
 -> transtable_global (read-only) [outputs the global translation table]
 -> transtable_local (read-only) [outputs the local translation table]
 
-=> vis "raw" data output
-* the raw format shall replace dot draw / json to offer a neutral that can
-* be converted
-* the format (comma seperated entries):
--> "mac" -> mac address of an originator (each line begins with it)
--> "TQ mac value" -> src mac's link quality towards mac address
--> "HNA mac" -> HNA announced by source mac
--> "PRIMARY" -> this is a primary interface
--> "SEC mac" -> secondary mac address of source (requires preceeding
--> PRIMARY)
-
-=> logging
-* the log level LOG_TYPE_CRIT, LOG_TYPE_WARN & LOG_TYPE_NOTICE will be
-* unified to use printk
-* LOG_TYPE_BATMAN & LOG_TYPE_ROUTES will also use printk but only after the
-* internal debug level has been raised
-* the internal debug level can be modified using a module parameter (debug)
-* or at run time via /sys/module/batman-adv/parameters/debug
-* make use of printk %pM support instead of converting mac addresses
-* manually
-
-=> strip out all backward compatibility support to older kernels
-   (only found in compat.h)
-
 => fix checkpatch.pl errors
 
 Please send all patches to:
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/translation-table.c linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/translation-table.c
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/translation-table.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/translation-table.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,11 +21,9 @@
 
 #include "main.h"
 #include "translation-table.h"
-#include "log.h"
 #include "soft-interface.h"
 #include "types.h"
 #include "hash.h"
-#include "compat.h"
 
 struct hashtable_t *hna_local_hash;
 static struct hashtable_t *hna_global_hash;
@@ -62,7 +60,6 @@ void hna_local_add(uint8_t *addr)
 	struct hna_local_entry *hna_local_entry;
 	struct hna_global_entry *hna_global_entry;
 	struct hashtable_t *swaphash;
-	char hna_str[ETH_STR_LEN];
 	unsigned long flags;
 
 	spin_lock_irqsave(&hna_local_hash_lock, flags);
@@ -75,19 +72,17 @@ void hna_local_add(uint8_t *addr)
 		return;
 	}
 
-	addr_to_string(hna_str, addr);
-
 	/* only announce as many hosts as possible in the batman-packet and
 	   space in batman_packet->num_hna That also should give a limit to
 	   MAC-flooding. */
 	if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) ||
 	    (num_hna + 1 > 255)) {
-		debug_log(LOG_TYPE_ROUTES, "Can't add new local hna entry (%s): number of local hna entries exceeds packet size \n", hna_str);
+		bat_dbg(DBG_ROUTES, "Can't add new local hna entry (%pM): number of local hna entries exceeds packet size \n", addr);
 		return;
 	}
 
-	debug_log(LOG_TYPE_ROUTES, "Creating new local hna entry: %s \n",
-		  hna_str);
+	bat_dbg(DBG_ROUTES, "Creating new local hna entry: %pM \n",
+		addr);
 
 	hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC);
 	if (!hna_local_entry)
@@ -113,7 +108,7 @@ void hna_local_add(uint8_t *addr)
 				       hna_local_hash->size * 2);
 
 		if (swaphash == NULL)
-			debug_log(LOG_TYPE_CRIT, "Couldn't resize local hna hash table \n");
+			printk(KERN_ERR "batman-adv:Couldn't resize local hna hash table \n");
 		else
 			hna_local_hash = swaphash;
 	}
@@ -135,18 +130,18 @@ void hna_local_add(uint8_t *addr)
 int hna_local_fill_buffer(unsigned char *buff, int buff_len)
 {
 	struct hna_local_entry *hna_local_entry;
-	struct hash_it_t *hashit = NULL;
+	HASHIT(hashit);
 	int i = 0;
 	unsigned long flags;
 
 	spin_lock_irqsave(&hna_local_hash_lock, flags);
 
-	while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
+	while (hash_iterate(hna_local_hash, &hashit)) {
 
 		if (buff_len < (i + 1) * ETH_ALEN)
 			break;
 
-		hna_local_entry = hashit->bucket->data;
+		hna_local_entry = hashit.bucket->data;
 		memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN);
 
 		i++;
@@ -164,18 +159,18 @@ int hna_local_fill_buffer(unsigned char
 int hna_local_fill_buffer_text(unsigned char *buff, int buff_len)
 {
 	struct hna_local_entry *hna_local_entry;
-	struct hash_it_t *hashit = NULL;
+	HASHIT(hashit);
 	int bytes_written = 0;
 	unsigned long flags;
 
 	spin_lock_irqsave(&hna_local_hash_lock, flags);
 
-	while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
+	while (hash_iterate(hna_local_hash, &hashit)) {
 
 		if (buff_len < bytes_written + ETH_STR_LEN + 4)
 			break;
 
-		hna_local_entry = hashit->bucket->data;
+		hna_local_entry = hashit.bucket->data;
 
 		bytes_written += snprintf(buff + bytes_written, ETH_STR_LEN + 4,
 					  " * %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -202,27 +197,39 @@ static void _hna_local_del(void *data)
 static void hna_local_del(struct hna_local_entry *hna_local_entry,
 			  char *message)
 {
-	char hna_str[ETH_STR_LEN];
-
-	addr_to_string(hna_str, hna_local_entry->addr);
-	debug_log(LOG_TYPE_ROUTES, "Deleting local hna entry (%s): %s \n",
-		  hna_str, message);
+	bat_dbg(DBG_ROUTES, "Deleting local hna entry (%pM): %s \n",
+		hna_local_entry->addr, message);
 
 	hash_remove(hna_local_hash, hna_local_entry->addr);
 	_hna_local_del(hna_local_entry);
 }
 
+void hna_local_remove(uint8_t *addr, char *message)
+{
+	struct hna_local_entry *hna_local_entry;
+	unsigned long flags;
+
+	spin_lock_irqsave(&hna_local_hash_lock, flags);
+
+	hna_local_entry = (struct hna_local_entry *)
+		hash_find(hna_local_hash, addr);
+	if (hna_local_entry)
+		hna_local_del(hna_local_entry, message);
+
+	spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+}
+
 void hna_local_purge(struct work_struct *work)
 {
 	struct hna_local_entry *hna_local_entry;
-	struct hash_it_t *hashit = NULL;
+	HASHIT(hashit);
 	unsigned long flags;
 	unsigned long timeout;
 
 	spin_lock_irqsave(&hna_local_hash_lock, flags);
 
-	while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
-		hna_local_entry = hashit->bucket->data;
+	while (hash_iterate(hna_local_hash, &hashit)) {
+		hna_local_entry = hashit.bucket->data;
 
 		timeout = hna_local_entry->last_seen +
 			((LOCAL_HNA_TIMEOUT / 1000) * HZ);
@@ -264,13 +271,10 @@ void hna_global_add_orig(struct orig_nod
 	struct hna_global_entry *hna_global_entry;
 	struct hna_local_entry *hna_local_entry;
 	struct hashtable_t *swaphash;
-	char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN];
 	int hna_buff_count = 0;
 	unsigned long flags;
 	unsigned char *hna_ptr;
 
-	addr_to_string(orig_str, orig_node->orig);
-
 	while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) {
 		spin_lock_irqsave(&hna_global_hash_lock, flags);
 
@@ -290,8 +294,9 @@ void hna_global_add_orig(struct orig_nod
 
 			memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN);
 
-			addr_to_string(hna_str, hna_global_entry->addr);
-			debug_log(LOG_TYPE_ROUTES, "Creating new global hna entry: %s (via %s)\n", hna_str, orig_str);
+			bat_dbg(DBG_ROUTES,
+				"Creating new global hna entry: %pM (via %pM)\n",
+				hna_global_entry->addr, orig_node->orig);
 
 			spin_lock_irqsave(&hna_global_hash_lock, flags);
 			hash_add(hna_global_hash, hna_global_entry);
@@ -316,14 +321,16 @@ void hna_global_add_orig(struct orig_nod
 		hna_buff_count++;
 	}
 
-	orig_node->hna_buff_len = hna_buff_len;
+	/* initialize, and overwrite if malloc succeeds */
+	orig_node->hna_buff = NULL;
+	orig_node->hna_buff_len = 0;
 
-	if (orig_node->hna_buff_len > 0) {
-		orig_node->hna_buff = kmalloc(orig_node->hna_buff_len,
-					      GFP_ATOMIC);
-		memcpy(orig_node->hna_buff, hna_buff, orig_node->hna_buff_len);
-	} else {
-		orig_node->hna_buff = NULL;
+	if (hna_buff_len > 0) {
+		orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC);
+		if (orig_node->hna_buff) {
+			memcpy(orig_node->hna_buff, hna_buff, hna_buff_len);
+			orig_node->hna_buff_len = hna_buff_len;
+		}
 	}
 
 	spin_lock_irqsave(&hna_global_hash_lock, flags);
@@ -333,7 +340,7 @@ void hna_global_add_orig(struct orig_nod
 				       hna_global_hash->size * 2);
 
 		if (swaphash == NULL)
-			debug_log(LOG_TYPE_CRIT, "Couldn't resize global hna hash table \n");
+			printk(KERN_ERR "batman-adv:Couldn't resize global hna hash table \n");
 		else
 			hna_global_hash = swaphash;
 	}
@@ -344,17 +351,17 @@ void hna_global_add_orig(struct orig_nod
 int hna_global_fill_buffer_text(unsigned char *buff, int buff_len)
 {
 	struct hna_global_entry *hna_global_entry;
-	struct hash_it_t *hashit = NULL;
+	HASHIT(hashit);
 	int bytes_written = 0;
 	unsigned long flags;
 
 	spin_lock_irqsave(&hna_global_hash_lock, flags);
 
-	while (NULL != (hashit = hash_iterate(hna_global_hash, hashit))) {
+	while (hash_iterate(hna_global_hash, &hashit)) {
 		if (buff_len < bytes_written + (2 * ETH_STR_LEN) + 10)
 			break;
 
-		hna_global_entry = hashit->bucket->data;
+		hna_global_entry = hashit.bucket->data;
 
 		bytes_written += snprintf(buff + bytes_written,
 					  (2 * ETH_STR_LEN) + 10,
@@ -381,12 +388,9 @@ int hna_global_fill_buffer_text(unsigned
 void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
 			  char *message)
 {
-	char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN];
-
-	addr_to_string(orig_str, hna_global_entry->orig_node->orig);
-	addr_to_string(hna_str, hna_global_entry->addr);
-
-	debug_log(LOG_TYPE_ROUTES, "Deleting global hna entry %s (via %s): %s \n", hna_str, orig_str, message);
+	bat_dbg(DBG_ROUTES, "Deleting global hna entry %pM (via %pM): %s \n",
+		hna_global_entry->addr, hna_global_entry->orig_node->orig,
+		message);
 
 	hash_remove(hna_global_hash, hna_global_entry->addr);
 	kfree(hna_global_entry);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/translation-table.h linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/translation-table.h
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/translation-table.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/translation-table.h	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 
 int hna_local_init(void);
 void hna_local_add(uint8_t *addr);
+void hna_local_remove(uint8_t *addr, char *message);
 int hna_local_fill_buffer(unsigned char *buff, int buff_len);
 int hna_local_fill_buffer_text(unsigned char *buff, int buff_len);
 void hna_local_purge(struct work_struct *work);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/types.h linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/types.h
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/types.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/types.h	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,6 @@ struct batman_if {
 	char if_active;
 	char addr_str[ETH_STR_LEN];
 	struct net_device *net_dev;
-	struct socket *raw_sock;
 	atomic_t seqno;
 	unsigned char *packet_buff;
 	int packet_len;
@@ -75,7 +74,7 @@ struct neigh_node {
 	uint8_t tq_index;
 	uint8_t tq_avg;
 	uint8_t last_ttl;
-	unsigned long last_valid;            /* when last packet via this neighbour was received */
+	unsigned long last_valid;            /* when last packet via this neighbor was received */
 	TYPE_OF_WORD real_bits[NUM_WORDS];
 	struct orig_node *orig_node;
 	struct batman_if *if_incoming;
@@ -113,6 +112,7 @@ struct forw_packet {               /* st
 	struct hlist_node list;
 	unsigned long send_time;
 	uint8_t own;
+	struct sk_buff *skb;
 	unsigned char *packet_buff;
 	uint16_t packet_len;
 	uint32_t direct_link_flags;
@@ -121,4 +121,14 @@ struct forw_packet {               /* st
 	struct batman_if *if_incoming;
 };
 
+/* While scanning for vis-entries of a particular vis-originator
+ * this list collects its interfaces to create a subgraph/cluster
+ * out of them later
+ */
+struct if_list_entry {
+	uint8_t addr[ETH_ALEN];
+	bool primary;
+	struct hlist_node list;
+};
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/vis.c linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/vis.c
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/vis.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/vis.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,11 +23,9 @@
 #include "send.h"
 #include "translation-table.h"
 #include "vis.h"
-#include "log.h"
 #include "soft-interface.h"
 #include "hard-interface.h"
 #include "hash.h"
-#include "compat.h"
 
 struct hashtable_t *vis_hash;
 DEFINE_SPINLOCK(vis_hash_lock);
@@ -50,39 +48,6 @@ static void free_info(void *data)
 	kfree(info);
 }
 
-/* set the mode of the visualization to client or server */
-void vis_set_mode(int mode)
-{
-	spin_lock(&vis_hash_lock);
-
-	if (my_vis_info != NULL)
-		my_vis_info->packet.vis_type = mode;
-
-	spin_unlock(&vis_hash_lock);
-}
-
-/* is_vis_server(), locked outside */
-static int is_vis_server_locked(void)
-{
-	if (my_vis_info != NULL)
-		if (my_vis_info->packet.vis_type == VIS_TYPE_SERVER_SYNC)
-			return 1;
-
-	return 0;
-}
-
-/* get the current set mode */
-int is_vis_server(void)
-{
-	int ret = 0;
-
-	spin_lock(&vis_hash_lock);
-	ret = is_vis_server_locked();
-	spin_unlock(&vis_hash_lock);
-
-	return ret;
-}
-
 /* Compare two vis packets, used by the hashing algorithm */
 static int vis_info_cmp(void *data1, void *data2)
 {
@@ -115,6 +80,68 @@ static int vis_info_choose(void *data, i
 	return hash % size;
 }
 
+/* insert interface to the list of interfaces of one originator, if it
+ * does not already exist in the list */
+static void proc_vis_insert_interface(const uint8_t *interface,
+				      struct hlist_head *if_list,
+				      bool primary)
+{
+	struct if_list_entry *entry;
+	struct hlist_node *pos;
+
+	hlist_for_each_entry(entry, pos, if_list, list) {
+		if (compare_orig(entry->addr, (void *)interface))
+			return;
+	}
+
+	/* its a new address, add it to the list */
+	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return;
+	memcpy(entry->addr, interface, ETH_ALEN);
+	entry->primary = primary;
+	hlist_add_head(&entry->list, if_list);
+}
+
+void proc_vis_read_prim_sec(struct seq_file *seq,
+			    struct hlist_head *if_list)
+{
+	struct if_list_entry *entry;
+	struct hlist_node *pos, *n;
+	char tmp_addr_str[ETH_STR_LEN];
+
+	hlist_for_each_entry_safe(entry, pos, n, if_list, list) {
+		if (entry->primary) {
+			seq_printf(seq, "PRIMARY, ");
+		} else {
+			addr_to_string(tmp_addr_str, entry->addr);
+			seq_printf(seq, "SEC %s, ", tmp_addr_str);
+		}
+
+		hlist_del(&entry->list);
+		kfree(entry);
+	}
+}
+
+/* read an entry  */
+void proc_vis_read_entry(struct seq_file *seq,
+				struct vis_info_entry *entry,
+				struct hlist_head *if_list,
+				uint8_t *vis_orig)
+{
+	char to[40];
+
+	addr_to_string(to, entry->dest);
+	if (entry->quality == 0) {
+		proc_vis_insert_interface(vis_orig, if_list, true);
+		seq_printf(seq, "HNA %s, ", to);
+	} else {
+		proc_vis_insert_interface(entry->src, if_list,
+					  compare_orig(entry->src, vis_orig));
+		seq_printf(seq, "TQ %s %d, ", to, entry->quality);
+	}
+}
+
 /* tries to add one entry to the receive list. */
 static void recv_list_add(struct list_head *recv_list, char *mac)
 {
@@ -208,21 +235,23 @@ void receive_server_sync_packet(struct v
 {
 	struct vis_info *info;
 	int is_new;
+	unsigned long flags;
+	int vis_server = atomic_read(&vis_mode);
 
-	spin_lock(&vis_hash_lock);
+	spin_lock_irqsave(&vis_hash_lock, flags);
 	info = add_packet(vis_packet, vis_info_len, &is_new);
 	if (info == NULL)
 		goto end;
 
 	/* only if we are server ourselves and packet is newer than the one in
 	 * hash.*/
-	if (is_vis_server_locked() && is_new) {
+	if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) {
 		memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
 		if (list_empty(&info->send_list))
 			list_add_tail(&info->send_list, &send_list);
 	}
 end:
-	spin_unlock(&vis_hash_lock);
+	spin_unlock_irqrestore(&vis_hash_lock, flags);
 }
 
 /* handle an incoming client update packet and schedule forward if needed. */
@@ -231,12 +260,14 @@ void receive_client_update_packet(struct
 {
 	struct vis_info *info;
 	int is_new;
+	unsigned long flags;
+	int vis_server = atomic_read(&vis_mode);
 
 	/* clients shall not broadcast. */
 	if (is_bcast(vis_packet->target_orig))
 		return;
 
-	spin_lock(&vis_hash_lock);
+	spin_lock_irqsave(&vis_hash_lock, flags);
 	info = add_packet(vis_packet, vis_info_len, &is_new);
 	if (info == NULL)
 		goto end;
@@ -244,7 +275,7 @@ void receive_client_update_packet(struct
 
 
 	/* send only if we're the target server or ... */
-	if (is_vis_server_locked() &&
+	if (vis_server == VIS_TYPE_SERVER_SYNC  &&
 	    is_my_mac(info->packet.target_orig) &&
 	    is_new) {
 		info->packet.vis_type = VIS_TYPE_SERVER_SYNC;	/* upgrade! */
@@ -258,7 +289,7 @@ void receive_client_update_packet(struct
 			list_add_tail(&info->send_list, &send_list);
 	}
 end:
-	spin_unlock(&vis_hash_lock);
+	spin_unlock_irqrestore(&vis_hash_lock, flags);
 }
 
 /* Walk the originators and find the VIS server with the best tq. Set the packet
@@ -267,12 +298,12 @@ end:
  * Must be called with the originator hash locked */
 static int find_best_vis_server(struct vis_info *info)
 {
-	struct hash_it_t *hashit = NULL;
+	HASHIT(hashit);
 	struct orig_node *orig_node;
 	int best_tq = -1;
 
-	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
-		orig_node = hashit->bucket->data;
+	while (hash_iterate(orig_hash, &hashit)) {
+		orig_node = hashit.bucket->data;
 		if ((orig_node != NULL) &&
 		    (orig_node->router != NULL) &&
 		    (orig_node->flags & VIS_SERVER) &&
@@ -298,7 +329,8 @@ static bool vis_packet_full(struct vis_i
  * returns 0 on success, -1 if no packet could be generated */
 static int generate_vis_packet(void)
 {
-	struct hash_it_t *hashit = NULL;
+	HASHIT(hashit_local);
+	HASHIT(hashit_global);
 	struct orig_node *orig_node;
 	struct vis_info *info = (struct vis_info *)my_vis_info;
 	struct vis_info_entry *entry, *entry_array;
@@ -307,27 +339,27 @@ static int generate_vis_packet(void)
 	unsigned long flags;
 
 	info->first_seen = jiffies;
+	info->packet.vis_type = atomic_read(&vis_mode);
 
-	spin_lock(&orig_hash_lock);
+	spin_lock_irqsave(&orig_hash_lock, flags);
 	memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
 	info->packet.ttl = TTL;
 	info->packet.seqno++;
 	info->packet.entries = 0;
 
-	if (!is_vis_server_locked()) {
+	if (info->packet.vis_type == VIS_TYPE_CLIENT_UPDATE) {
 		best_tq = find_best_vis_server(info);
 		if (best_tq < 0) {
-			spin_unlock(&orig_hash_lock);
+			spin_unlock_irqrestore(&orig_hash_lock, flags);
 			return -1;
 		}
 	}
-	hashit = NULL;
 
 	entry_array = (struct vis_info_entry *)
 		((char *)info + sizeof(struct vis_info));
 
-	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
-		orig_node = hashit->bucket->data;
+	while (hash_iterate(orig_hash, &hashit_global)) {
+		orig_node = hashit_global.bucket->data;
 		if (orig_node->router != NULL
 			&& compare_orig(orig_node->router->addr, orig_node->orig)
 			&& orig_node->batman_if
@@ -342,18 +374,17 @@ static int generate_vis_packet(void)
 			info->packet.entries++;
 
 			if (vis_packet_full(info)) {
-				spin_unlock(&orig_hash_lock);
+				spin_unlock_irqrestore(&orig_hash_lock, flags);
 				return 0;
 			}
 		}
 	}
 
-	spin_unlock(&orig_hash_lock);
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-	hashit = NULL;
 	spin_lock_irqsave(&hna_local_hash_lock, flags);
-	while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
-		hna_local_entry = hashit->bucket->data;
+	while (hash_iterate(hna_local_hash, &hashit_local)) {
+		hna_local_entry = hashit_local.bucket->data;
 		entry = &entry_array[info->packet.entries];
 		memset(entry->src, 0, ETH_ALEN);
 		memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN);
@@ -371,16 +402,16 @@ static int generate_vis_packet(void)
 
 static void purge_vis_packets(void)
 {
-	struct hash_it_t *hashit = NULL;
+	HASHIT(hashit);
 	struct vis_info *info;
 
-	while (NULL != (hashit = hash_iterate(vis_hash, hashit))) {
-		info = hashit->bucket->data;
+	while (hash_iterate(vis_hash, &hashit)) {
+		info = hashit.bucket->data;
 		if (info == my_vis_info)	/* never purge own data. */
 			continue;
 		if (time_after(jiffies,
-			       info->first_seen + (VIS_TIMEOUT/1000)*HZ)) {
-			hash_remove_bucket(vis_hash, hashit);
+			       info->first_seen + (VIS_TIMEOUT*HZ)/1000)) {
+			hash_remove_bucket(vis_hash, &hashit);
 			free_info(info);
 		}
 	}
@@ -388,14 +419,15 @@ static void purge_vis_packets(void)
 
 static void broadcast_vis_packet(struct vis_info *info, int packet_length)
 {
-	struct hash_it_t *hashit = NULL;
+	HASHIT(hashit);
 	struct orig_node *orig_node;
+	unsigned long flags;
 
-	spin_lock(&orig_hash_lock);
+	spin_lock_irqsave(&orig_hash_lock, flags);
 
 	/* send to all routers in range. */
-	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
-		orig_node = hashit->bucket->data;
+	while (hash_iterate(orig_hash, &hashit)) {
+		orig_node = hashit.bucket->data;
 
 		/* if it's a vis server and reachable, send it. */
 		if (orig_node &&
@@ -418,14 +450,15 @@ static void broadcast_vis_packet(struct
 		}
 	}
 	memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
-	spin_unlock(&orig_hash_lock);
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
 }
 
 static void unicast_vis_packet(struct vis_info *info, int packet_length)
 {
 	struct orig_node *orig_node;
+	unsigned long flags;
 
-	spin_lock(&orig_hash_lock);
+	spin_lock_irqsave(&orig_hash_lock, flags);
 	orig_node = ((struct orig_node *)
 		     hash_find(orig_hash, info->packet.target_orig));
 
@@ -436,7 +469,7 @@ static void unicast_vis_packet(struct vi
 				orig_node->batman_if,
 				orig_node->router->addr);
 	}
-	spin_unlock(&orig_hash_lock);
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
 }
 
 /* only send one vis packet. called from send_vis_packets() */
@@ -445,8 +478,7 @@ static void send_vis_packet(struct vis_i
 	int packet_length;
 
 	if (info->packet.ttl < 2) {
-		debug_log(LOG_TYPE_NOTICE,
-			  "Error - can't send vis packet: ttl exceeded\n");
+		printk(KERN_WARNING "batman-adv: Error - can't send vis packet: ttl exceeded\n");
 		return;
 	}
 
@@ -467,8 +499,9 @@ static void send_vis_packet(struct vis_i
 static void send_vis_packets(struct work_struct *work)
 {
 	struct vis_info *info, *temp;
+	unsigned long flags;
 
-	spin_lock(&vis_hash_lock);
+	spin_lock_irqsave(&vis_hash_lock, flags);
 	purge_vis_packets();
 
 	if (generate_vis_packet() == 0)
@@ -479,7 +512,7 @@ static void send_vis_packets(struct work
 		list_del_init(&info->send_list);
 		send_vis_packet(info);
 	}
-	spin_unlock(&vis_hash_lock);
+	spin_unlock_irqrestore(&vis_hash_lock, flags);
 	start_vis_timer();
 }
 static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets);
@@ -488,20 +521,21 @@ static DECLARE_DELAYED_WORK(vis_timer_wq
  * initialized (e.g. bat0 is initialized, interfaces have been added) */
 int vis_init(void)
 {
+	unsigned long flags;
 	if (vis_hash)
 		return 1;
 
-	spin_lock(&vis_hash_lock);
+	spin_lock_irqsave(&vis_hash_lock, flags);
 
 	vis_hash = hash_new(256, vis_info_cmp, vis_info_choose);
 	if (!vis_hash) {
-		debug_log(LOG_TYPE_CRIT, "Can't initialize vis_hash\n");
+		printk(KERN_ERR "batman-adv:Can't initialize vis_hash\n");
 		goto err;
 	}
 
 	my_vis_info = kmalloc(1000, GFP_ATOMIC);
 	if (!my_vis_info) {
-		debug_log(LOG_TYPE_CRIT, "Can't initialize vis packet\n");
+		printk(KERN_ERR "batman-adv:Can't initialize vis packet\n");
 		goto err;
 	}
 
@@ -511,7 +545,6 @@ int vis_init(void)
 	INIT_LIST_HEAD(&my_vis_info->send_list);
 	my_vis_info->packet.version = COMPAT_VERSION;
 	my_vis_info->packet.packet_type = BAT_VIS;
-	my_vis_info->packet.vis_type = VIS_TYPE_CLIENT_UPDATE;
 	my_vis_info->packet.ttl = TTL;
 	my_vis_info->packet.seqno = 0;
 	my_vis_info->packet.entries = 0;
@@ -522,19 +555,19 @@ int vis_init(void)
 	memcpy(my_vis_info->packet.sender_orig, mainIfAddr, ETH_ALEN);
 
 	if (hash_add(vis_hash, my_vis_info) < 0) {
-		debug_log(LOG_TYPE_CRIT,
-			  "Can't add own vis packet into hash\n");
+		printk(KERN_ERR
+			  "batman-adv:Can't add own vis packet into hash\n");
 		free_info(my_vis_info);	/* not in hash, need to remove it
 					 * manually. */
 		goto err;
 	}
 
-	spin_unlock(&vis_hash_lock);
+	spin_unlock_irqrestore(&vis_hash_lock, flags);
 	start_vis_timer();
 	return 1;
 
 err:
-	spin_unlock(&vis_hash_lock);
+	spin_unlock_irqrestore(&vis_hash_lock, flags);
 	vis_quit();
 	return 0;
 }
@@ -542,23 +575,23 @@ err:
 /* shutdown vis-server */
 void vis_quit(void)
 {
+	unsigned long flags;
 	if (!vis_hash)
 		return;
 
 	cancel_delayed_work_sync(&vis_timer_wq);
 
-	spin_lock(&vis_hash_lock);
+	spin_lock_irqsave(&vis_hash_lock, flags);
 	/* properly remove, kill timers ... */
 	hash_delete(vis_hash, free_info);
 	vis_hash = NULL;
 	my_vis_info = NULL;
-	spin_unlock(&vis_hash_lock);
+	spin_unlock_irqrestore(&vis_hash_lock, flags);
 }
 
 /* schedule packets for (re)transmission */
 static void start_vis_timer(void)
 {
 	queue_delayed_work(bat_event_workqueue, &vis_timer_wq,
-			   (atomic_read(&vis_interval)/1000) * HZ);
+			   (atomic_read(&vis_interval) * HZ) / 1000);
 }
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/vis.h linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/vis.h
--- linux-libre-2.6.33-gnu1/drivers/staging/batman-adv/vis.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/batman-adv/vis.h	2010-05-16 17:17:36.000000000 -0400
@@ -45,16 +45,15 @@ struct recvlist_node {
 	uint8_t mac[ETH_ALEN];
 };
 
-enum vis_formats {
-	DOT_DRAW,
-	JSON,
-};
-
 extern struct hashtable_t *vis_hash;
 extern spinlock_t vis_hash_lock;
 
-void vis_set_mode(int mode);
-int is_vis_server(void);
+void proc_vis_read_entry(struct seq_file *seq,
+				struct vis_info_entry *entry,
+				struct hlist_head *if_list,
+				uint8_t *vis_orig);
+void proc_vis_read_prim_sec(struct seq_file *seq,
+			    struct hlist_head *if_list);
 void receive_server_sync_packet(struct vis_packet *vis_packet,
 				int vis_info_len);
 void receive_client_update_packet(struct vis_packet *vis_packet,
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/comedi_compat32.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/comedi_compat32.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/comedi_compat32.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/comedi_compat32.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 
 #define __NO_VERSION__
 #include "comedi.h"
-#include <linux/smp_lock.h>
 #include <linux/uaccess.h>
 
 #include "comedi_compat32.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/comedi_fops.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/comedi_fops.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/comedi_fops.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/comedi_fops.c	2010-05-16 17:17:36.000000000 -0400
@@ -63,7 +63,7 @@ module_param(comedi_debug, int, 0644);
 int comedi_autoconfig = 1;
 module_param(comedi_autoconfig, bool, 0444);
 
-int comedi_num_legacy_minors = 0;
+int comedi_num_legacy_minors;
 module_param(comedi_num_legacy_minors, int, 0444);
 
 static DEFINE_SPINLOCK(comedi_file_info_table_lock);
@@ -1510,7 +1510,7 @@ static unsigned int comedi_poll(struct f
 }
 
 static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
-			    loff_t * offset)
+				loff_t *offset)
 {
 	struct comedi_subdevice *s;
 	struct comedi_async *async;
@@ -1612,7 +1612,7 @@ done:
 }
 
 static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
-			   loff_t * offset)
+				loff_t *offset)
 {
 	struct comedi_subdevice *s;
 	struct comedi_async *async;
@@ -2004,12 +2004,10 @@ void comedi_event(struct comedi_device *
 	if (async->cb_mask & s->async->events) {
 		if (comedi_get_subdevice_runflags(s) & SRF_USER) {
 			wake_up_interruptible(&async->wait_head);
-			if (s->subdev_flags & SDF_CMD_READ) {
+			if (s->subdev_flags & SDF_CMD_READ)
 				kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
-			}
-			if (s->subdev_flags & SDF_CMD_WRITE) {
+			if (s->subdev_flags & SDF_CMD_WRITE)
 				kill_fasync(&dev->async_queue, SIGIO, POLL_OUT);
-			}
 		} else {
 			if (async->cb_func)
 				async->cb_func(s->async->events, async->cb_arg);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/8255.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/8255.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/8255.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/8255.c	2010-05-16 17:17:36.000000000 -0400
@@ -81,6 +81,7 @@ I/O port base address can be found in th
 #include "../comedidev.h"
 
 #include <linux/ioport.h>
+#include <linux/slab.h>
 
 #define _8255_SIZE 4
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
@@ -173,11 +173,10 @@ int i_AddiHeaderRW_ReadEeprom(int i_NbOf
 			} while (dw_eeprom_busy == EEPROM_BUSY);
 
 			/* Select the upper address part */
-			if (i_Counter == 0) {
+			if (i_Counter == 0)
 				b_ReadLowByte = pb_ReadByte[0];
-			} else {
+			else
 				b_ReadHighByte = pb_ReadByte[0];
-			}
 
 			/* Sleep */
 			msleep(1);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/addi_common.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/addi_common.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/addi_common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/addi_common.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
@@ -50,7 +50,6 @@ You shoud also find the complete GPL in
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
@@ -58,6 +57,7 @@ You shoud also find the complete GPL in
 #include <linux/timex.h>
 #include <linux/timer.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include "../../comedidev.h"
 #include <asm/io.h>
 #if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300)
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/addi_common.h linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/addi_common.h
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/addi_common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/addi_common.h	2010-05-16 17:17:36.000000000 -0400
@@ -77,8 +77,8 @@ struct addi_board {
 	int i_NbrAoChannel;	/*  num of D/A chans */
 	int i_AiMaxdata;	/*  resolution of A/D */
 	int i_AoMaxdata;	/*  resolution of D/A */
-        const struct comedi_lrange *pr_AiRangelist;	/* rangelist for A/D */
-        const struct comedi_lrange *pr_AoRangelist;	/* rangelist for D/A */
+	const struct comedi_lrange *pr_AiRangelist;	/* rangelist for A/D */
+	const struct comedi_lrange *pr_AoRangelist;	/* rangelist for D/A */
 
 	int i_NbrDiChannel;	/*  Number of DI channels */
 	int i_NbrDoChannel;	/*  Number of DO channels */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
@@ -54,7 +54,7 @@ You shoud also find the complete GPL in
 #include "hwdrv_apci1032.h"
 #include <linux/delay.h>
 /* Global variables */
-unsigned int ui_InterruptStatus = 0;
+unsigned int ui_InterruptStatus;
 
 /*
 +----------------------------------------------------------------------------+
@@ -108,9 +108,9 @@ int i_APCI1032_ConfigDigitalInput(struct
 			ui_TmpValue =
 				inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
 		}		/* if (data[1] == ADDIDATA_OR) */
-		else {
+		else
 			outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
-		}		/* else if(data[1] == ADDIDATA_OR) */
+				/* else if(data[1] == ADDIDATA_OR) */
 	}			/*  if( data[0] == ADDIDATA_ENABLE) */
 	else {
 		ul_Command1 = ul_Command1 & 0xFFFF0000;
@@ -221,9 +221,9 @@ int i_APCI1032_ReadMoreDigitalInput(stru
 		}		/* switch(ui_NoOfChannels) */
 	}			/* if(data[1]==0) */
 	else {
-		if (data[1] == 1) {
+		if (data[1] == 1)
 			*data = ui_InterruptStatus;
-		}		/* if(data[1]==1) */
+				/* if(data[1]==1) */
 	}			/* else if(data[1]==0) */
 	return insn->n;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
@@ -45,7 +45,7 @@ You shoud also find the complete GPL in
 */
 
 #include "hwdrv_apci3120.h"
-static unsigned int ui_Temp = 0;
+static unsigned int ui_Temp;
 
 /* FUNCTION DEFINITIONS */
 
@@ -98,25 +98,22 @@ int i_APCI3120_InsnConfigAnalogInput(str
 
 		devpriv->b_InterruptMode = APCI3120_EOS_MODE;
 
-		if (data[1]) {
+		if (data[1])
 			devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
-		} else
+		else
 			devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
 		/*  Copy channel list and Range List to devpriv */
 
 		devpriv->ui_AiNbrofChannels = data[3];
-		for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) {
+		for (i = 0; i < devpriv->ui_AiNbrofChannels; i++)
 			devpriv->ui_AiChannelList[i] = data[4 + i];
-		}
 
-	} else			/*  EOC */
-	{
+	} else {			/*  EOC */
 		devpriv->b_InterruptMode = APCI3120_EOC_MODE;
-		if (data[1]) {
+		if (data[1])
 			devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
-		} else {
+		else
 			devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
-		}
 	}
 
 	return insn->n;
@@ -166,13 +163,9 @@ int i_APCI3120_InsnReadAnalogInput(struc
 	devpriv->us_OutputRegister = 0;
 /* devpriv->b_DigitalOutputRegister=0; */
 
-	if (insn->unused[0] == 222)	/*  second insn read */
-	{
-
-		for (i = 0; i < insn->n; i++) {
+	if (insn->unused[0] == 222) {	/*  second insn read */
+		for (i = 0; i < insn->n; i++)
 			data[i] = devpriv->ui_AiReadData[i];
-		}
-
 	} else {
 		devpriv->tsk_Current = current;	/*  Save the current process task structure */
 /*
@@ -519,9 +512,8 @@ int i_APCI3120_CommandTestAnalogInput(st
 
 	/* step 2: make sure trigger sources are unique and mutually compatible */
 
-	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) {
+	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
 		err++;
-	}
 
 	if (cmd->scan_begin_src != TRIG_TIMER &&
 		cmd->scan_begin_src != TRIG_FOLLOW)
@@ -548,16 +540,14 @@ int i_APCI3120_CommandTestAnalogInput(st
 		err++;
 	}
 
-	if (cmd->scan_begin_src == TRIG_TIMER)	/*  Test Delay timing */
-	{
+	if (cmd->scan_begin_src == TRIG_TIMER) {	/*  Test Delay timing */
 		if (cmd->scan_begin_arg < this_board->ui_MinDelaytimeNs) {
 			cmd->scan_begin_arg = this_board->ui_MinDelaytimeNs;
 			err++;
 		}
 	}
 
-	if (cmd->convert_src == TRIG_TIMER)	/*  Test Acquisition timing */
-	{
+	if (cmd->convert_src == TRIG_TIMER) {	/*  Test Acquisition timing */
 		if (cmd->scan_begin_src == TRIG_TIMER) {
 			if ((cmd->convert_arg)
 				&& (cmd->convert_arg <
@@ -653,11 +643,10 @@ int i_APCI3120_CommandAnalogInput(struct
 	/* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */
 	devpriv->ui_AiDataLength = s->async->prealloc_bufsz;
 
-	if (cmd->stop_src == TRIG_COUNT) {
+	if (cmd->stop_src == TRIG_COUNT)
 		devpriv->ui_AiNbrofScans = cmd->stop_arg;
-	} else {
+	else
 		devpriv->ui_AiNbrofScans = 0;
-	}
 
 	devpriv->ui_AiTimer0 = 0;	/*  variables changed to timer0,timer1 */
 	devpriv->ui_AiTimer1 = 0;
@@ -849,9 +838,8 @@ int i_APCI3120_CyclicAnalogInput(int mod
 	}
 /*** EL241003 End ******************************************************************************/
 
-	if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) {
+	if (devpriv->b_ExttrigEnable == APCI3120_ENABLE)
 		i_APCI3120_ExttrigEnable(dev);	/*  activate EXT trigger */
-	}
 	switch (mode) {
 	case 1:
 		/*  init timer0 in mode 2 */
@@ -1049,12 +1037,10 @@ int i_APCI3120_CyclicAnalogInput(int mod
 					dmalen1 = 4;
 			}
 		} else {	/*  isn't output buff smaller that our DMA buff? */
-			if (dmalen0 > (devpriv->ui_AiDataLength)) {
+			if (dmalen0 > (devpriv->ui_AiDataLength))
 				dmalen0 = devpriv->ui_AiDataLength;
-			}
-			if (dmalen1 > (devpriv->ui_AiDataLength)) {
+			if (dmalen1 > (devpriv->ui_AiDataLength))
 				dmalen1 = devpriv->ui_AiDataLength;
-			}
 		}
 		devpriv->ui_DmaBufferUsesize[0] = dmalen0;
 		devpriv->ui_DmaBufferUsesize[1] = dmalen1;
@@ -1356,11 +1342,10 @@ int i_APCI3120_SetupChannelList(struct c
 		/*  store range list to card */
 		us_TmpValue = CR_CHAN(chanlist[i]);	/*  get channel number; */
 
-		if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES) {
+		if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES)
 			us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff);	/*  set bipolar */
-		} else {
+		else
 			us_TmpValue |= APCI3120_UNIPOLAR;	/*  enable unipolar...... */
-		}
 
 		gain = CR_RANGE(chanlist[i]);	/*  get gain number */
 		us_TmpValue |= ((gain & 0x03) << 4);	/* <<4 for G0 and G1 bit in RAM */
@@ -1514,8 +1499,7 @@ void v_APCI3120_Interrupt(int irq, void
 	/*  Check If EOS interrupt */
 	if ((int_daq & 0x2) && (devpriv->b_InterruptMode == APCI3120_EOS_MODE)) {
 
-		if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE)	/*  enable this in without DMA ??? */
-		{
+		if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) {	/*  enable this in without DMA ??? */
 
 			if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) {
 				ui_Check = 0;
@@ -1966,8 +1950,7 @@ int i_APCI3120_InsnConfigTimer(struct co
 		APCI3120_DISABLE_EOS_INT;
 	outb(devpriv->b_ModeSelectRegister,
 		devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
-	if (data[0] == APCI3120_TIMER)	/* initialize timer */
-	{
+	if (data[0] == APCI3120_TIMER) {	/* initialize timer */
 		/* devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister |
 		 * APCI3120_ENABLE_TIMER_INT; */
 
@@ -2006,8 +1989,7 @@ int i_APCI3120_InsnConfigTimer(struct co
 		/*  timer2 in Timer mode enabled */
 		devpriv->b_Timer2Mode = APCI3120_TIMER;
 
-	} else			/*  Initialize Watch dog */
-	{
+	} else {			/*  Initialize Watch dog */
 
 		/* Set the Timer 2 in mode 5(Watchdog) */
 
@@ -2092,8 +2074,7 @@ int i_APCI3120_InsnWriteTimer(struct com
 		return -EINVAL;
 	}
 
-	if (data[0] == 2)	/*  write new value */
-	{
+	if (data[0] == 2) {	/*  write new value */
 		if (devpriv->b_Timer2Mode != APCI3120_TIMER) {
 			comedi_error(dev,
 				"write :timer2  not configured  in TIMER MODE");
@@ -2113,13 +2094,11 @@ int i_APCI3120_InsnWriteTimer(struct com
 
 		/*  Reset FC_TIMER BIT */
 		inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER);
-		if (devpriv->b_Timer2Mode == APCI3120_TIMER)	/* start timer */
-		{
+		if (devpriv->b_Timer2Mode == APCI3120_TIMER) {	/* start timer */
 			/* Enable Timer */
 			devpriv->b_ModeSelectRegister =
 				devpriv->b_ModeSelectRegister & 0x0B;
-		} else		/* start watch dog */
-		{
+		} else {		/* start watch dog */
 			/* Enable WatchDog */
 			devpriv->b_ModeSelectRegister =
 				(devpriv->
@@ -2146,8 +2125,7 @@ int i_APCI3120_InsnWriteTimer(struct com
 		outb(devpriv->b_ModeSelectRegister,
 			devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
 
-		if (devpriv->b_Timer2Mode == APCI3120_TIMER)	/* start timer */
-		{
+		if (devpriv->b_Timer2Mode == APCI3120_TIMER) {	/* start timer */
 			/* For Timer mode is  Gate2 must be activated   **timer started */
 			devpriv->us_OutputRegister =
 				devpriv->
@@ -2299,8 +2277,7 @@ int i_APCI3120_InsnReadTimer(struct come
 		/*  combining both words */
 		data[0] = (unsigned int) ((us_TmpValue) | ((us_TmpValue_2) << 16));
 
-	} else			/*  Read watch dog status */
-	{
+	} else {			/*  Read watch dog status */
 
 		us_StatusValue = inw(devpriv->iobase + APCI3120_RD_STATUS);
 		us_StatusValue =
@@ -2441,10 +2418,9 @@ int i_APCI3120_InsnConfigDigitalOutput(s
 		devpriv->b_OutputMemoryStatus = APCI3120_DISABLE;
 		devpriv->b_DigitalOutputRegister = 0;
 	}
-	if (!devpriv->b_OutputMemoryStatus) {
+	if (!devpriv->b_OutputMemoryStatus)
 		ui_Temp = 0;
-
-	}			/* if(!devpriv->b_OutputMemoryStatus ) */
+				/* if(!devpriv->b_OutputMemoryStatus ) */
 
 	return insn->n;
 }
@@ -2504,23 +2480,23 @@ int i_APCI3120_InsnBitsDigitalOutput(str
 
 /*
 +----------------------------------------------------------------------------+
-| Function name     :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,|
-|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) 			             |
-|                                            						         |
+| Function name		:int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,|
+|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)	|
+|										|
 +----------------------------------------------------------------------------+
-| Task              : Write digiatl output								     |
-|                     										                 |
+| Task			: Write digiatl output					|
+| 										|
 +----------------------------------------------------------------------------+
-| Input Parameters  : struct comedi_device *dev								 	 |
-|                     struct comedi_subdevice *s									 |
-|                     struct comedi_insn *insn                                      |
-|                     unsigned int *data 										 |
-                      data[0]     Value to be written
-                      data[1]    :1 Set digital o/p ON
-                      data[1]     2 Set digital o/p OFF with memory ON
+| Input Parameters	: struct comedi_device *dev				|
+|			struct comedi_subdevice *s			 	|
+|			struct comedi_insn *insn				|
+|			unsigned int *data					|
+			data[0]     Value to be written
+			data[1]    :1 Set digital o/p ON
+			data[1]     2 Set digital o/p OFF with memory ON
 +----------------------------------------------------------------------------+
-| Return Value      :              					                         |
-|                    													     |
+| Return Value		:							|
+|										|
 +----------------------------------------------------------------------------+
 */
 
@@ -2615,8 +2591,7 @@ int i_APCI3120_InsnWriteAnalogOutput(str
 	ui_Channel = CR_CHAN(insn->chanspec);
 
 	/* this_board->i_hwdrv_InsnWriteAnalogOutput(dev, ui_Range, ui_Channel,data[0]); */
-	if (ui_Range)		/*  if 1 then unipolar */
-	{
+	if (ui_Range) {		/*  if 1 then unipolar */
 
 		if (data[0] != 0)
 			data[0] =
@@ -2627,8 +2602,7 @@ int i_APCI3120_InsnWriteAnalogOutput(str
 				((((ui_Channel & 0x03) << 14) & 0xC000) | (1 <<
 					13) | 8192);
 
-	} else			/*  if 0 then   bipolar */
-	{
+	} else {			/*  if 0 then   bipolar */
 		data[0] =
 			((((ui_Channel & 0x03) << 14) & 0xC000) | (0 << 13) |
 			data[0]);
@@ -2639,8 +2613,7 @@ int i_APCI3120_InsnWriteAnalogOutput(str
  * out put n values at the given channel. printk("\nwaiting for
  * DA_READY BIT");
  */
-	do			/* Waiting of DA_READY BIT */
-	{
+	do {			/* Waiting of DA_READY BIT */
 		us_TmpValue =
 			((unsigned short) inw(devpriv->iobase +
 				APCI3120_RD_STATUS)) & 0x0001;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@ This program is distributed in the hope
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-You shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
 
 @endverbatim
 */
@@ -1206,7 +1206,7 @@ int i_APCI3XXX_InsnWriteTTLIO(struct com
 
 		if (b_Channel < 8) {
 	      /*****************************************************************************/
-			/* Read port 0 (first digital output port) and set/reset the selcted channel */
+			/* Read port 0 (first digital output port) and set/reset the selected channel */
 	      /*****************************************************************************/
 
 			dw_Status = inl(devpriv->iobase + 80);
@@ -1228,7 +1228,7 @@ int i_APCI3XXX_InsnWriteTTLIO(struct com
 				if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
 					== 0xFF) {
 		    /*****************************************************************************/
-					/* Read port 2 (first digital output port) and set/reset the selcted channel */
+					/* Read port 2 (first digital output port) and set/reset the selected channel */
 		    /*****************************************************************************/
 
 					dw_Status = inl(devpriv->iobase + 112);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/adl_pci9118.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/adl_pci9118.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/adl_pci9118.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/adl_pci9118.c	2010-05-16 17:17:36.000000000 -0400
@@ -66,6 +66,7 @@ Configuration options:
 #include "../pci_ids.h"
 
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/interrupt.h>
 
 #include "amcc_s5933.h"
@@ -88,9 +89,9 @@ Configuration options:
 #define IORANGE_9118 	64	/* I hope */
 #define PCI9118_CHANLEN	255	/* len of chanlist, some source say 256, but reality looks like 255 :-( */
 
-#define PCI9118_CNT0	0x00	/* R/W: 8254 couter 0 */
-#define PCI9118_CNT1	0x04	/* R/W: 8254 couter 0 */
-#define PCI9118_CNT2	0x08	/* R/W: 8254 couter 0 */
+#define PCI9118_CNT0	0x00	/* R/W: 8254 counter 0 */
+#define PCI9118_CNT1	0x04	/* R/W: 8254 counter 0 */
+#define PCI9118_CNT2	0x08	/* R/W: 8254 counter 0 */
 #define PCI9118_CNTCTRL	0x0c	/* W:   8254 counter control */
 #define PCI9118_AD_DATA	0x10	/* R:   A/D data */
 #define PCI9118_DA1	0x10	/* W:   D/A registers */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/adq12b.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/adq12b.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/adq12b.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/adq12b.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,23 +42,23 @@ If you do not specify any options, they
   option 1: I/O base address. The following table is provided as a help
    of the hardware jumpers.
 
-         address            jumper JADR
-          0x300                 1 (factory default)
-          0x320                 2
-          0x340                 3
-          0x360                 4
-          0x380                 5
-          0x3A0                 6
+	 address            jumper JADR
+	  0x300                 1 (factory default)
+	  0x320                 2
+	  0x340                 3
+	  0x360                 4
+	  0x380                 5
+	  0x3A0                 6
 
   option 2: unipolar/bipolar ADC selection: 0 -> bipolar, 1 -> unipolar
 
-        selection         comedi_config option            JUB
-         bipolar                0                         2-3 (factory default)
-         unipolar               1                         1-2
+	selection         comedi_config option            JUB
+	 bipolar                0                         2-3 (factory default)
+	 unipolar               1                         1-2
 
   option 3: single-ended/differential AI selection: 0 -> SE, 1 -> differential
 
-        selection         comedi_config option     JCHA    JCHB
+	selection         comedi_config option     JCHA    JCHB
        single-ended             0                  1-2     1-2 (factory default)
        differential             1                  2-3     2-3
 
@@ -140,7 +140,7 @@ static const struct adq12b_board adq12b_
 	.ai_bits = 12,
 	.di_chans = 8,
 	.do_chans = 5
-        }*/
+	}*/
 };
 
 #define thisboard ((const struct adq12b_board *)dev->board_ptr)
@@ -164,14 +164,15 @@ struct adq12b_private {
 static int adq12b_attach(struct comedi_device *dev,
 			 struct comedi_devconfig *it);
 static int adq12b_detach(struct comedi_device *dev);
+
 static struct comedi_driver driver_adq12b = {
-driver_name:"adq12b",
-module:THIS_MODULE,
-attach:adq12b_attach,
-detach:adq12b_detach,
-board_name:&adq12b_boards[0].name,
-offset:sizeof(struct adq12b_board),
-num_names:ARRAY_SIZE(adq12b_boards),
+	.driver_name = "adq12b",
+	.module = THIS_MODULE,
+	.attach = adq12b_attach,
+	.detach = adq12b_detach,
+	.board_name = &adq12b_boards[0].name,
+	.offset = sizeof(struct adq12b_board),
+	.num_names = ARRAY_SIZE(adq12b_boards),
 };
 
 static int adq12b_ai_rinsn(struct comedi_device *dev,
@@ -200,15 +201,16 @@ static int adq12b_attach(struct comedi_d
 	unipolar = it->options[1];
 	differential = it->options[2];
 
-	printk("comedi%d: adq12b called with options base=0x%03lx, %s and %s\n",
-	       dev->minor, iobase, (unipolar == 1) ? "unipolar" : "bipolar",
+	printk(KERN_INFO "comedi%d: adq12b called with options base=0x%03lx, "
+	       "%s and %s\n", dev->minor, iobase,
+	       (unipolar == 1) ? "unipolar" : "bipolar",
 	       (differential == 1) ? "differential" : "single-ended");
 
 	/* if no address was specified, try the default 0x300 */
 	if (iobase == 0) {
-		printk
-		    ("comedi%d: adq12b warning: I/O base address not specified. Trying the default 0x300.\n",
-		     dev->minor);
+		printk(KERN_WARNING "comedi%d: adq12b warning: I/O base "
+		       "address not specified. Trying the default 0x300.\n",
+		       dev->minor);
 		iobase = 0x300;
 	}
 
@@ -259,11 +261,10 @@ static int adq12b_attach(struct comedi_d
 		s->n_chan = thisboard->ai_se_chans;
 	}
 
-	if (unipolar) {
+	if (unipolar)
 		s->range_table = &range_adq12b_ai_unipolar;
-	} else {
+	else
 		s->range_table = &range_adq12b_ai_bipolar;
-	}
 
 	s->maxdata = (1 << thisboard->ai_bits) - 1;
 
@@ -289,7 +290,7 @@ static int adq12b_attach(struct comedi_d
 	s->range_table = &range_digital;
 	s->insn_bits = adq12b_do_insn_bits;
 
-	printk("attached\n");
+	printk(KERN_INFO "attached\n");
 
 	return 0;
 }
@@ -309,7 +310,7 @@ static int adq12b_detach(struct comedi_d
 
 	kfree(devpriv);
 
-	printk("comedi%d: adq12b: removed\n", dev->minor);
+	printk(KERN_INFO "comedi%d: adq12b: removed\n", dev->minor);
 
 	return 0;
 }
@@ -344,17 +345,18 @@ static int adq12b_ai_rinsn(struct comedi
 		/* wait for end of convertion */
 		i = 0;
 		do {
-/* udelay(1); */
+			/* udelay(1); */
 			status = inb(dev->iobase + ADQ12B_STINR);
 			status = status & ADQ12B_EOC;
 		} while (status == 0 && ++i < TIMEOUT);
-/* } while (++i < 10); */
+		/* } while (++i < 10); */
 
 		/* read data */
 		hi = inb(dev->iobase + ADQ12B_ADHIG);
 		lo = inb(dev->iobase + ADQ12B_ADLOW);
 
-		/* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", channel, range, status,  hi, lo); */
+		/* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n",
+		       channel, range, status,  hi, lo); */
 		data[n] = (hi << 8) | lo;
 
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/adv_pci1710.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/adv_pci1710.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/adv_pci1710.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/adv_pci1710.c	2010-05-16 17:17:36.000000000 -0400
@@ -84,9 +84,9 @@ Configuration options:
 #define PCI171x_DAREF	14	/* W:   D/A reference control */
 #define PCI171x_DI	16	/* R:   digi inputs */
 #define PCI171x_DO	16	/* R:   digi inputs */
-#define PCI171x_CNT0	24	/* R/W: 8254 couter 0 */
-#define PCI171x_CNT1	26	/* R/W: 8254 couter 1 */
-#define PCI171x_CNT2	28	/* R/W: 8254 couter 2 */
+#define PCI171x_CNT0	24	/* R/W: 8254 counter 0 */
+#define PCI171x_CNT1	26	/* R/W: 8254 counter 1 */
+#define PCI171x_CNT2	28	/* R/W: 8254 counter 2 */
 #define PCI171x_CNTCTRL	30	/* W:   8254 counter control */
 
 /* upper bits from status register (PCI171x_STATUS) (lower is same woth control reg) */
@@ -724,6 +724,7 @@ static int move_block_from_fifo(struct c
 			devpriv->ai_act_scan++;
 		}
 	}
+	s->async->cur_chan = j;
 	DPRINTK("adv_pci1710 EDBG: END: move_block_from_fifo(...)\n");
 	return 0;
 }
@@ -1034,14 +1035,6 @@ static int pci171x_ai_cmdtest(struct com
 		}
 	}
 
-	if (!cmd->chanlist_len) {
-		cmd->chanlist_len = 1;
-		err++;
-	}
-	if (cmd->chanlist_len > this_board->n_aichan) {
-		cmd->chanlist_len = this_board->n_aichan;
-		err++;
-	}
 	if (cmd->scan_end_arg != cmd->chanlist_len) {
 		cmd->scan_end_arg = cmd->chanlist_len;
 		err++;
@@ -1230,6 +1223,12 @@ static void setup_channel_list(struct co
 		DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
 			devpriv->act_chanlist[i]);
 	}
+#ifdef PCI171x_PARANOIDCHECK
+	for ( ; i < n_chan; i++) { /* store remainder of channel list */
+		devpriv->act_chanlist[i] =
+		    (CR_CHAN(chanlist[i]) << 12) & 0xf000;
+	}
+#endif
 
 	devpriv->ai_et_MuxVal =
 	    CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/aio_iiro_16.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/aio_iiro_16.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/aio_iiro_16.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/aio_iiro_16.c	2010-05-16 17:17:36.000000000 -0400
@@ -98,7 +98,7 @@ static int aio_iiro_16_attach(struct com
 	int iobase;
 	struct comedi_subdevice *s;
 
-	printk("comedi%d: aio_iiro_16: ", dev->minor);
+	printk(KERN_INFO "comedi%d: aio_iiro_16: ", dev->minor);
 
 	dev->board_name = thisboard->name;
 
@@ -140,7 +140,7 @@ static int aio_iiro_16_attach(struct com
 
 static int aio_iiro_16_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: aio_iiro_16: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: aio_iiro_16: remove\n", dev->minor);
 
 	if (dev->iobase)
 		release_region(dev->iobase, AIO_IIRO_16_SIZE);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/amplc_dio200.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/amplc_dio200.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/amplc_dio200.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/amplc_dio200.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,8 +48,8 @@ Passing a zero for an option is the same
 
 SUBDEVICES
 
-                    PC218E         PC212E      PC215E/PCI215
-                 -------------  -------------  -------------
+		    PC218E         PC212E      PC215E/PCI215
+		 -------------  -------------  -------------
   Subdevices           7              6              5
    0                 CTR-X1         PPI-X          PPI-X
    1                 CTR-X2         CTR-Y1         PPI-Y
@@ -59,8 +59,8 @@ SUBDEVICES
    5                 CTR-Z2       INTERRUPT
    6               INTERRUPT
 
-                    PC214E      PC272E/PCI272
-                 -------------  -------------
+		    PC214E      PC272E/PCI272
+		 -------------  -------------
   Subdevices           4              4
    0                 PPI-X          PPI-X
    1                 PPI-Y          PPI-Y
@@ -96,8 +96,8 @@ instructions are supported:
     0 to 7 as follows:
 
       0.  CLK n, the counter channel's dedicated CLK input from the SK1
-        connector.  (N.B. for other values, the counter channel's CLKn
-        pin on the SK1 connector is an output!)
+	connector.  (N.B. for other values, the counter channel's CLKn
+	pin on the SK1 connector is an output!)
       1.  Internal 10 MHz clock.
       2.  Internal 1 MHz clock.
       3.  Internal 100 kHz clock.
@@ -105,8 +105,8 @@ instructions are supported:
       5.  Internal 1 kHz clock.
       6.  OUT n-1, the output of counter channel n-1 (see note 1 below).
       7.  Ext Clock, the counter chip's dedicated Ext Clock input from
-        the SK1 connector.  This pin is shared by all three counter
-        channels on the chip.
+	the SK1 connector.  This pin is shared by all three counter
+	channels on the chip.
 
   INSN_CONFIG_GET_CLOCK_SRC.  Returns the counter channel's current
     clock source in data[1].  For internal clock sources, data[2] is set
@@ -120,10 +120,10 @@ instructions are supported:
       0.  VCC (internal +5V d.c.), i.e. gate permanently enabled.
       1.  GND (internal 0V d.c.), i.e. gate permanently disabled.
       2.  GAT n, the counter channel's dedicated GAT input from the SK1
-        connector.  (N.B. for other values, the counter channel's GATn
-        pin on the SK1 connector is an output!)
+	connector.  (N.B. for other values, the counter channel's GATn
+	pin on the SK1 connector is an output!)
       3.  /OUT n-2, the inverted output of counter channel n-2 (see note
-        2 below).
+	2 below).
       4.  Reserved.
       5.  Reserved.
       6.  Reserved.
@@ -153,8 +153,8 @@ below.
 
 INTERRUPT SOURCES
 
-                    PC218E         PC212E      PC215E/PCI215
-                 -------------  -------------  -------------
+		    PC218E         PC212E      PC215E/PCI215
+		 -------------  -------------  -------------
   Sources              6              6              6
    0              CTR-X1-OUT      PPI-X-C0       PPI-X-C0
    1              CTR-X2-OUT      PPI-X-C3       PPI-X-C3
@@ -163,8 +163,8 @@ INTERRUPT SOURCES
    4              CTR-Z1-OUT     CTR-Z1-OUT     CTR-Z1-OUT
    5              CTR-Z2-OUT     CTR-Z2-OUT     CTR-Z2-OUT
 
-                    PC214E      PC272E/PCI272
-                 -------------  -------------
+		    PC214E      PC272E/PCI272
+		 -------------  -------------
   Sources              1              6
    0               JUMPER-J5      PPI-X-C0
    1                              PPI-X-C3
@@ -206,6 +206,7 @@ order they appear in the channel list.
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include "../comedidev.h"
 
@@ -435,11 +436,13 @@ MODULE_DEVICE_TABLE(pci, dio200_pci_tabl
  * Useful for shorthand access to the particular board structure
  */
 #define thisboard ((const struct dio200_board *)dev->board_ptr)
-#define thislayout (&dio200_layouts[((struct dio200_board *)dev->board_ptr)->layout])
+#define thislayout (&dio200_layouts[((struct dio200_board *) \
+		    dev->board_ptr)->layout])
 
 /* this structure is for data unique to this hardware driver.  If
    several hardware drivers keep similar information in this structure,
-   feel free to suggest moving the variable to the struct comedi_device struct.  */
+   feel free to suggest moving the variable to the struct comedi_device struct.
+ */
 struct dio200_private {
 #ifdef CONFIG_COMEDI_PCI
 	struct pci_dev *pci_dev;	/* PCI device */
@@ -603,9 +606,8 @@ static void dio200_stop_intr(struct come
 
 	subpriv->active = 0;
 	subpriv->enabled_isns = 0;
-	if (subpriv->has_int_sce) {
+	if (subpriv->has_int_sce)
 		outb(0, subpriv->iobase);
-	}
 }
 
 /*
@@ -629,16 +631,14 @@ static int dio200_start_intr(struct come
 		/* Determine interrupt sources to enable. */
 		isn_bits = 0;
 		if (cmd->chanlist) {
-			for (n = 0; n < cmd->chanlist_len; n++) {
+			for (n = 0; n < cmd->chanlist_len; n++)
 				isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
-			}
 		}
 		isn_bits &= subpriv->valid_isns;
 		/* Enable interrupt sources. */
 		subpriv->enabled_isns = isn_bits;
-		if (subpriv->has_int_sce) {
+		if (subpriv->has_int_sce)
 			outb(isn_bits, subpriv->iobase);
-		}
 	}
 
 	return retval;
@@ -662,14 +662,13 @@ dio200_inttrig_start_intr(struct comedi_
 
 	spin_lock_irqsave(&subpriv->spinlock, flags);
 	s->async->inttrig = 0;
-	if (subpriv->active) {
+	if (subpriv->active)
 		event = dio200_start_intr(dev, s);
-	}
+
 	spin_unlock_irqrestore(&subpriv->spinlock, flags);
 
-	if (event) {
+	if (event)
 		comedi_event(dev, s);
-	}
 
 	return 1;
 }
@@ -726,9 +725,8 @@ static int dio200_handle_read_intr(struc
 		 * Reenable them NOW to minimize the time they are disabled.
 		 */
 		cur_enabled = subpriv->enabled_isns;
-		if (subpriv->has_int_sce) {
+		if (subpriv->has_int_sce)
 			outb(cur_enabled, subpriv->iobase);
-		}
 
 		if (subpriv->active) {
 			/*
@@ -747,9 +745,8 @@ static int dio200_handle_read_intr(struc
 				len = s->async->cmd.chanlist_len;
 				for (n = 0; n < len; n++) {
 					ch = CR_CHAN(s->async->cmd.chanlist[n]);
-					if (triggered & (1U << ch)) {
+					if (triggered & (1U << ch))
 						val |= (1U << n);
-					}
 				}
 				/* Write the scan to the buffer. */
 				if (comedi_buf_put(s->async, val)) {
@@ -781,9 +778,8 @@ static int dio200_handle_read_intr(struc
 	}
 	spin_unlock_irqrestore(&subpriv->spinlock, flags);
 
-	if (oldevents != s->async->events) {
+	if (oldevents != s->async->events)
 		comedi_event(dev, s);
-	}
 
 	return (triggered != 0);
 }
@@ -798,9 +794,9 @@ static int dio200_subdev_intr_cancel(str
 	unsigned long flags;
 
 	spin_lock_irqsave(&subpriv->spinlock, flags);
-	if (subpriv->active) {
+	if (subpriv->active)
 		dio200_stop_intr(dev, s);
-	}
+
 	spin_unlock_irqrestore(&subpriv->spinlock, flags);
 
 	return 0;
@@ -846,7 +842,8 @@ dio200_subdev_intr_cmdtest(struct comedi
 	if (err)
 		return 1;
 
-	/* step 2: make sure trigger sources are unique and mutually compatible */
+	/* step 2: make sure trigger sources are unique and mutually
+		   compatible */
 
 	/* these tests are true if more than one _src bit is set */
 	if ((cmd->start_src & (cmd->start_src - 1)) != 0)
@@ -952,9 +949,8 @@ static int dio200_subdev_intr_cmd(struct
 	}
 	spin_unlock_irqrestore(&subpriv->spinlock, flags);
 
-	if (event) {
+	if (event)
 		comedi_event(dev, s);
-	}
 
 	return 0;
 }
@@ -980,9 +976,8 @@ dio200_subdev_intr_init(struct comedi_de
 	subpriv->valid_isns = valid_isns;
 	spin_lock_init(&subpriv->spinlock);
 
-	if (has_int_sce) {
+	if (has_int_sce)
 		outb(0, subpriv->iobase);	/* Disable interrupt sources. */
-	}
 
 	s->private = subpriv;
 	s->type = COMEDI_SUBD_DI;
@@ -1013,10 +1008,7 @@ dio200_subdev_intr_cleanup(struct comedi
 			   struct comedi_subdevice *s)
 {
 	struct dio200_subdev_intr *subpriv = s->private;
-
-	if (subpriv) {
-		kfree(subpriv);
-	}
+	kfree(subpriv);
 }
 
 /*
@@ -1027,9 +1019,8 @@ static irqreturn_t dio200_interrupt(int
 	struct comedi_device *dev = d;
 	int handled;
 
-	if (!dev->attached) {
+	if (!dev->attached)
 		return IRQ_NONE;
-	}
 
 	if (devpriv->intr_sd >= 0) {
 		handled = dio200_handle_read_intr(dev,
@@ -1266,10 +1257,7 @@ dio200_subdev_8254_cleanup(struct comedi
 			   struct comedi_subdevice *s)
 {
 	struct dio200_subdev_intr *subpriv = s->private;
-
-	if (subpriv) {
-		kfree(subpriv);
-	}
+	kfree(subpriv);
 }
 
 /*
@@ -1348,9 +1336,8 @@ static int dio200_attach(struct comedi_d
 #endif
 	{
 		ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE);
-		if (ret < 0) {
+		if (ret < 0)
 			return ret;
-		}
 	}
 	dev->iobase = iobase;
 
@@ -1371,17 +1358,17 @@ static int dio200_attach(struct comedi_d
 			ret = dio200_subdev_8254_init(dev, s, iobase,
 						      layout->sdinfo[n],
 						      layout->has_clk_gat_sce);
-			if (ret < 0) {
+			if (ret < 0)
 				return ret;
-			}
+
 			break;
 		case sd_8255:
 			/* digital i/o subdevice (8255) */
 			ret = subdev_8255_init(dev, s, 0,
 					       iobase + layout->sdinfo[n]);
-			if (ret < 0) {
+			if (ret < 0)
 				return ret;
-			}
+
 			break;
 		case sd_intr:
 			/* 'INTERRUPT' subdevice */
@@ -1392,9 +1379,9 @@ static int dio200_attach(struct comedi_d
 							      layout->sdinfo[n],
 							      layout->
 							      has_int_sce);
-				if (ret < 0) {
+				if (ret < 0)
 					return ret;
-				}
+
 				devpriv->intr_sd = n;
 			} else {
 				s->type = COMEDI_SUBD_UNUSED;
@@ -1407,9 +1394,8 @@ static int dio200_attach(struct comedi_d
 	}
 
 	sdx = devpriv->intr_sd;
-	if (sdx >= 0 && sdx < dev->n_subdevices) {
+	if (sdx >= 0 && sdx < dev->n_subdevices)
 		dev->read_subdev = &dev->subdevices[sdx];
-	}
 
 	dev->board_name = thisboard->name;
 
@@ -1434,11 +1420,10 @@ static int dio200_attach(struct comedi_d
 		printk("(pci %s) ", pci_name(pci_dev));
 #endif
 	}
-	if (irq) {
+	if (irq)
 		printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
-	} else {
+	else
 		printk("(no irq) ");
-	}
 
 	printk("attached\n");
 
@@ -1461,9 +1446,8 @@ static int dio200_detach(struct comedi_d
 	printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
 	       DIO200_DRIVER_NAME);
 
-	if (dev->irq) {
+	if (dev->irq)
 		free_irq(dev->irq, dev);
-	}
 	if (dev->subdevices) {
 		layout = thislayout;
 		for (n = 0; n < dev->n_subdevices; n++) {
@@ -1486,22 +1470,19 @@ static int dio200_detach(struct comedi_d
 	if (devpriv) {
 #ifdef CONFIG_COMEDI_PCI
 		if (devpriv->pci_dev) {
-			if (dev->iobase) {
+			if (dev->iobase)
 				comedi_pci_disable(devpriv->pci_dev);
-			}
 			pci_dev_put(devpriv->pci_dev);
 		} else
 #endif
 		{
-			if (dev->iobase) {
+			if (dev->iobase)
 				release_region(dev->iobase, DIO200_IO_SIZE);
-			}
 		}
 	}
-	if (dev->board_name) {
+	if (dev->board_name)
 		printk(KERN_INFO "comedi%d: %s removed\n",
 		       dev->minor, dev->board_name);
-	}
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/amplc_pc236.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/amplc_pc236.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/amplc_pc236.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/amplc_pc236.c	2010-05-16 17:17:36.000000000 -0400
@@ -78,18 +78,18 @@ unused.
  */
 /* Disable interrupt, also clear any interrupt there */
 #define PCI236_INTR_DISABLE (PLX9052_INTCSR_LI1ENAB_DISABLED \
-        | PLX9052_INTCSR_LI1POL_HIGH \
-        | PLX9052_INTCSR_LI2POL_HIGH \
-        | PLX9052_INTCSR_PCIENAB_DISABLED \
-        | PLX9052_INTCSR_LI1SEL_EDGE \
-        | PLX9052_INTCSR_LI1CLRINT_ASSERTED)
+	| PLX9052_INTCSR_LI1POL_HIGH \
+	| PLX9052_INTCSR_LI2POL_HIGH \
+	| PLX9052_INTCSR_PCIENAB_DISABLED \
+	| PLX9052_INTCSR_LI1SEL_EDGE \
+	| PLX9052_INTCSR_LI1CLRINT_ASSERTED)
 /* Enable interrupt, also clear any interrupt there. */
 #define PCI236_INTR_ENABLE (PLX9052_INTCSR_LI1ENAB_ENABLED \
-        | PLX9052_INTCSR_LI1POL_HIGH \
-        | PLX9052_INTCSR_LI2POL_HIGH \
-        | PLX9052_INTCSR_PCIENAB_ENABLED \
-        | PLX9052_INTCSR_LI1SEL_EDGE \
-        | PLX9052_INTCSR_LI1CLRINT_ASSERTED)
+	| PLX9052_INTCSR_LI1POL_HIGH \
+	| PLX9052_INTCSR_LI2POL_HIGH \
+	| PLX9052_INTCSR_PCIENAB_ENABLED \
+	| PLX9052_INTCSR_LI1SEL_EDGE \
+	| PLX9052_INTCSR_LI1CLRINT_ASSERTED)
 
 /*
  * Board descriptions for Amplicon PC36AT and PCI236.
@@ -150,12 +150,13 @@ MODULE_DEVICE_TABLE(pci, pc236_pci_table
 
 /* this structure is for data unique to this hardware driver.  If
    several hardware drivers keep similar information in this structure,
-   feel free to suggest moving the variable to the struct comedi_device struct.  */
+   feel free to suggest moving the variable to the struct comedi_device struct.
+ */
 struct pc236_private {
 #ifdef CONFIG_COMEDI_PCI
 	/* PCI device */
 	struct pci_dev *pci_dev;
-	unsigned long lcr_iobase;	/* PLX PCI9052 config registers in PCIBAR1 */
+	unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */
 #endif
 	int enable_irq;
 };
@@ -345,9 +346,8 @@ static int pc236_attach(struct comedi_de
 #endif
 	{
 		ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE);
-		if (ret < 0) {
+		if (ret < 0)
 			return ret;
-		}
 	}
 	dev->iobase = iobase;
 
@@ -399,11 +399,10 @@ static int pc236_attach(struct comedi_de
 		printk("(pci %s) ", pci_name(pci_dev));
 #endif
 	}
-	if (irq) {
+	if (irq)
 		printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
-	} else {
+	else
 		printk("(no irq) ");
-	}
 
 	printk("attached\n");
 
@@ -422,27 +421,24 @@ static int pc236_detach(struct comedi_de
 {
 	printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
 	       PC236_DRIVER_NAME);
-	if (devpriv) {
+	if (devpriv)
 		pc236_intr_disable(dev);
-	}
+
 	if (dev->irq)
 		free_irq(dev->irq, dev);
-	if (dev->subdevices) {
+	if (dev->subdevices)
 		subdev_8255_cleanup(dev, dev->subdevices + 0);
-	}
 	if (devpriv) {
 #ifdef CONFIG_COMEDI_PCI
 		if (devpriv->pci_dev) {
-			if (dev->iobase) {
+			if (dev->iobase)
 				comedi_pci_disable(devpriv->pci_dev);
-			}
 			pci_dev_put(devpriv->pci_dev);
 		} else
 #endif
 		{
-			if (dev->iobase) {
+			if (dev->iobase)
 				release_region(dev->iobase, PC236_IO_SIZE);
-			}
 		}
 	}
 	if (dev->board_name) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/amplc_pci224.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/amplc_pci224.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/amplc_pci224.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/amplc_pci224.c	2010-05-16 17:17:36.000000000 -0400
@@ -104,6 +104,7 @@ Caveats:
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include "../comedidev.h"
 
@@ -1536,20 +1537,12 @@ static int pci224_detach(struct comedi_d
 
 		s = dev->subdevices + 0;
 		/* AO subdevice */
-		if (s->range_table_list) {
-			kfree(s->range_table_list);
-		}
+		kfree(s->range_table_list);
 	}
 	if (devpriv) {
-		if (devpriv->ao_readback) {
-			kfree(devpriv->ao_readback);
-		}
-		if (devpriv->ao_scan_vals) {
-			kfree(devpriv->ao_scan_vals);
-		}
-		if (devpriv->ao_scan_order) {
-			kfree(devpriv->ao_scan_order);
-		}
+		kfree(devpriv->ao_readback);
+		kfree(devpriv->ao_scan_vals);
+		kfree(devpriv->ao_scan_order);
 		if (devpriv->pci_dev) {
 			if (dev->iobase) {
 				comedi_pci_disable(devpriv->pci_dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/c6xdigio.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/c6xdigio.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/c6xdigio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/c6xdigio.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,7 +45,7 @@ http://robot0.ge.uiuc.edu/~spong/mecha/
 #include <linux/interrupt.h>
 #include <linux/timex.h>
 #include <linux/timer.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/pnp.h>
 
 #include "../comedidev.h"
@@ -220,11 +220,11 @@ static int C6X_encInput(unsigned long ba
 	/* printk("Inside C6X_encInput\n"); */
 
 	enc.value = 0;
-	if (channel == 0) {
+	if (channel == 0)
 		ppcmd = 0x48;
-	} else {
+	else
 		ppcmd = 0x50;
-	}
+
 	WriteByteToHwPort(baseAddr, ppcmd);
 	tmp = ReadByteFromHwPort(baseAddr + 1);
 	while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
@@ -391,9 +391,8 @@ static int c6xdigio_ei_insn_read(struct
 	int n;
 	int chan = CR_CHAN(insn->chanspec);
 
-	for (n = 0; n < insn->n; n++) {
+	for (n = 0; n < insn->n; n++)
 		data[n] = (C6X_encInput(dev->iobase, chan) & 0xffffff);
-	}
 
 	return n;
 }
@@ -420,9 +419,9 @@ static void board_init(struct comedi_dev
 
 static const struct pnp_device_id c6xdigio_pnp_tbl[] = {
 	/* Standard LPT Printer Port */
-	{.id = "PNP0400",.driver_data = 0},
+	{.id = "PNP0400", .driver_data = 0},
 	/* ECP Printer Port */
-	{.id = "PNP0401",.driver_data = 0},
+	{.id = "PNP0401", .driver_data = 0},
 	{}
 };
 
@@ -452,15 +451,14 @@ static int c6xdigio_attach(struct comedi
 	if (result < 0)
 		return result;
 
-	/*  Make sure that PnP ports gets activated */
+	/*  Make sure that PnP ports get activated */
 	pnp_register_driver(&c6xdigio_pnp_driver);
 
 	irq = it->options[1];
-	if (irq > 0) {
+	if (irq > 0)
 		printk("comedi%d: irq = %u ignored\n", dev->minor, irq);
-	} else if (irq == 0) {
+	else if (irq == 0)
 		printk("comedi%d: no irq\n", dev->minor);
-	}
 
 	s = dev->subdevices + 0;
 	/* pwm output subdevice */
@@ -483,19 +481,19 @@ static int c6xdigio_attach(struct comedi
 	s->maxdata = 0xffffff;
 	s->range_table = &range_unknown;
 
-	/*           s = dev->subdevices + 2; */
+	/*	s = dev->subdevices + 2; */
 	/* pwm output subdevice */
-	/*       s->type = COMEDI_SUBD_COUNTER;  // Not sure what to put here */
-	/*       s->subdev_flags = SDF_WRITEABLE; */
-	/*       s->n_chan = 1; */
-	/*       s->trig[0] = c6xdigio_ei_init; */
-	/*       s->insn_read = c6xdigio_ei_init_insn_read; */
-	/*       s->insn_write = c6xdigio_ei_init_insn_write; */
-	/*       s->maxdata = 0xFFFF;  // Really just a don't care */
-	/*       s->range_table = &range_unknown; // Not sure what to put here */
+	/*	s->type = COMEDI_SUBD_COUNTER;  // Not sure what to put here */
+	/*	s->subdev_flags = SDF_WRITEABLE; */
+	/*	s->n_chan = 1; */
+	/*	s->trig[0] = c6xdigio_ei_init; */
+	/*	s->insn_read = c6xdigio_ei_init_insn_read; */
+	/*	s->insn_write = c6xdigio_ei_init_insn_write; */
+	/*	s->maxdata = 0xFFFF;  // Really just a don't care */
+	/*	s->range_table = &range_unknown; // Not sure what to put here */
 
-	/*  I will call this init anyway but more than likely the DSP board will not be connect */
-	/*  when device driver is loaded. */
+	/*  I will call this init anyway but more than likely the DSP board */
+	/*  will not be connected when device driver is loaded. */
 	board_init(dev);
 
 	return 0;
@@ -503,16 +501,17 @@ static int c6xdigio_attach(struct comedi
 
 static int c6xdigio_detach(struct comedi_device *dev)
 {
-/* board_halt(dev);  may not need this */
+	/* board_halt(dev);  may not need this */
 
 	printk("comedi%d: c6xdigio: remove\n", dev->minor);
 
-	if (dev->iobase) {
+	if (dev->iobase)
 		release_region(dev->iobase, C6XDIGIO_SIZE);
-	}
-	if (dev->irq) {
+
+	/*  Not using IRQ so I am not sure if I need this */
+	if (dev->irq)
 		free_irq(dev->irq, dev);
-	}			/*  Not using IRQ so I am not sure if I need this */
+
 	pnp_unregister_driver(&c6xdigio_pnp_driver);
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/cb_das16_cs.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/cb_das16_cs.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/cb_das16_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/cb_das16_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@ Status: experimental
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 #include <linux/delay.h>
 #include <linux/pci.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/cb_pcidas.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/cb_pcidas.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/cb_pcidas.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/cb_pcidas.c	2010-05-16 17:17:36.000000000 -0400
@@ -518,7 +518,7 @@ static int trimpot_7376_write(struct com
 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
 			      uint8_t value);
 static int nvram_read(struct comedi_device *dev, unsigned int address,
-		      uint8_t * data);
+		      uint8_t *data);
 
 static inline unsigned int cal_enable_bits(struct comedi_device *dev)
 {
@@ -760,9 +760,8 @@ static int cb_pcidas_detach(struct comed
 	if (dev->subdevices)
 		subdev_8255_cleanup(dev, dev->subdevices + 2);
 	if (devpriv && devpriv->pci_dev) {
-		if (devpriv->s5933_config) {
+		if (devpriv->s5933_config)
 			comedi_pci_disable(devpriv->pci_dev);
-		}
 		pci_dev_put(devpriv->pci_dev);
 	}
 
@@ -1248,9 +1247,8 @@ static int cb_pcidas_ai_cmd(struct comed
 					cmd->flags & TRIG_ROUND_MASK);
 
 	/*  set number of conversions */
-	if (cmd->stop_src == TRIG_COUNT) {
+	if (cmd->stop_src == TRIG_COUNT)
 		devpriv->count = cmd->chanlist_len * cmd->stop_arg;
-	}
 	/*  enable interrupts */
 	spin_lock_irqsave(&dev->spinlock, flags);
 	devpriv->adc_fifo_bits |= INTE;
@@ -1449,9 +1447,8 @@ static int cb_pcidas_ao_cmd(struct comed
 			   devpriv->ao_divisor2, 2);
 	}
 	/*  set number of conversions */
-	if (cmd->stop_src == TRIG_COUNT) {
+	if (cmd->stop_src == TRIG_COUNT)
 		devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
-	}
 	/*  set pacer source */
 	spin_lock_irqsave(&dev->spinlock, flags);
 	switch (cmd->scan_begin_src) {
@@ -1494,9 +1491,8 @@ static int cb_pcidas_ao_inttrig(struct c
 					       num_points * sizeof(short));
 	num_points = num_bytes / sizeof(short);
 
-	if (cmd->stop_src == TRIG_COUNT) {
+	if (cmd->stop_src == TRIG_COUNT)
 		devpriv->ao_count -= num_points;
-	}
 	/*  write data to board's fifo */
 	outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
 
@@ -1534,9 +1530,8 @@ static irqreturn_t cb_pcidas_interrupt(i
 	static const int timeout = 10000;
 	unsigned long flags;
 
-	if (dev->attached == 0) {
+	if (dev->attached == 0)
 		return IRQ_NONE;
-	}
 
 	async = s->async;
 	async->events = 0;
@@ -1558,15 +1553,13 @@ static irqreturn_t cb_pcidas_interrupt(i
 
 	status = inw(devpriv->control_status + INT_ADCFIFO);
 #ifdef CB_PCIDAS_DEBUG
-	if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0) {
+	if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0)
 		comedi_error(dev, "spurious interrupt");
-	}
 #endif
 
 	/*  check for analog output interrupt */
-	if (status & (DAHFI | DAEMI)) {
+	if (status & (DAHFI | DAEMI))
 		handle_ao_interrupt(dev, status);
-	}
 	/*  check for analog input interrupts */
 	/*  if fifo half-full */
 	if (status & ADHFI) {
@@ -1675,9 +1668,8 @@ static void handle_ao_interrupt(struct c
 					       num_points * sizeof(short));
 		num_points = num_bytes / sizeof(short);
 
-		if (async->cmd.stop_src == TRIG_COUNT) {
+		if (async->cmd.stop_src == TRIG_COUNT)
 			devpriv->ao_count -= num_points;
-		}
 		/*  write data to board's fifo */
 		outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
 		      num_points);
@@ -1852,7 +1844,7 @@ static int wait_for_nvram_ready(unsigned
 }
 
 static int nvram_read(struct comedi_device *dev, unsigned int address,
-		      uint8_t * data)
+			uint8_t *data)
 {
 	unsigned long iobase = devpriv->s5933_config;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/cb_pcidda.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/cb_pcidda.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/cb_pcidda.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/cb_pcidda.c	2010-05-16 17:17:36.000000000 -0400
@@ -410,9 +410,8 @@ static int cb_pcidda_detach(struct comed
  */
 	if (devpriv) {
 		if (devpriv->pci_dev) {
-			if (devpriv->dac) {
+			if (devpriv->dac)
 				comedi_pci_disable(devpriv->pci_dev);
-			}
 			pci_dev_put(devpriv->pci_dev);
 		}
 	}
@@ -677,9 +676,8 @@ static unsigned int cb_pcidda_serial_in(
 
 	for (i = 1; i <= value_width; i++) {
 		/*  read bits most significant bit first */
-		if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT) {
+		if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT)
 			value |= 1 << (value_width - i);
-		}
 	}
 
 	return value;
@@ -716,9 +714,8 @@ static unsigned int cb_pcidda_read_eepro
 	/*  send serial output stream to eeprom */
 	cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT;
 	/*  deactivate caldacs (one caldac for every two channels) */
-	for (i = 0; i < max_num_caldacs; i++) {
+	for (i = 0; i < max_num_caldacs; i++)
 		cal2_bits |= DESELECT_CALDAC_BIT(i);
-	}
 	outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
 
 	/*  tell eeprom we want to read */
@@ -756,9 +753,8 @@ static void cb_pcidda_write_caldac(struc
 */
 	cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT;
 	/*  deactivate caldacs (one caldac for every two channels) */
-	for (i = 0; i < max_num_caldacs; i++) {
+	for (i = 0; i < max_num_caldacs; i++)
 		cal2_bits |= DESELECT_CALDAC_BIT(i);
-	}
 	/*  activate the caldac we want */
 	cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
 	outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/cb_pcidio.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/cb_pcidio.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/cb_pcidio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/cb_pcidio.c	2010-05-16 17:17:36.000000000 -0400
@@ -283,17 +283,15 @@ static int pcidio_detach(struct comedi_d
 	printk("comedi%d: cb_pcidio: remove\n", dev->minor);
 	if (devpriv) {
 		if (devpriv->pci_dev) {
-			if (devpriv->dio_reg_base) {
+			if (devpriv->dio_reg_base)
 				comedi_pci_disable(devpriv->pci_dev);
-			}
 			pci_dev_put(devpriv->pci_dev);
 		}
 	}
 	if (dev->subdevices) {
 		int i;
-		for (i = 0; i < thisboard->n_8255; i++) {
+		for (i = 0; i < thisboard->n_8255; i++)
 			subdev_8255_cleanup(dev, dev->subdevices + i);
-		}
 	}
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/cb_pcimdas.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/cb_pcimdas.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/cb_pcimdas.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/cb_pcimdas.c	2010-05-16 17:17:36.000000000 -0400
@@ -330,11 +330,10 @@ found:
 
 	s = dev->subdevices + 2;
 	/* digital i/o subdevice */
-	if (thisboard->has_dio) {
+	if (thisboard->has_dio)
 		subdev_8255_init(dev, s, NULL, devpriv->BADR4);
-	} else {
+	else
 		s->type = COMEDI_SUBD_UNUSED;
-	}
 
 	printk("attached\n");
 
@@ -365,9 +364,8 @@ static int cb_pcimdas_detach(struct come
 		free_irq(dev->irq, dev);
 	if (devpriv) {
 		if (devpriv->pci_dev) {
-			if (devpriv->BADR0) {
+			if (devpriv->BADR0)
 				comedi_pci_disable(devpriv->pci_dev);
-			}
 			pci_dev_put(devpriv->pci_dev);
 		}
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/cb_pcimdda.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/cb_pcimdda.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/cb_pcimdda.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/cb_pcimdda.c	2010-05-16 17:17:36.000000000 -0400
@@ -284,11 +284,10 @@ static int attach(struct comedi_device *
 	s->n_chan = thisboard->ao_chans;
 	s->maxdata = figure_out_maxdata(thisboard->ao_bits);
 	/* this is hard-coded here */
-	if (it->options[2]) {
+	if (it->options[2])
 		s->range_table = &range_bipolar10;
-	} else {
+	else
 		s->range_table = &range_bipolar5;
-	}
 	s->insn_write = &ao_winsn;
 	s->insn_read = &ao_rinsn;
 
@@ -337,9 +336,8 @@ static int detach(struct comedi_device *
 		}
 
 		if (devpriv->pci_dev) {
-			if (devpriv->registers) {
+			if (devpriv->registers)
 				comedi_pci_disable(devpriv->pci_dev);
-			}
 			pci_dev_put(devpriv->pci_dev);
 		}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/comedi_bond.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/comedi_bond.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/comedi_bond.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/comedi_bond.c	2010-05-16 17:17:36.000000000 -0400
@@ -90,6 +90,7 @@ Configuration Options:
 #include "../comedilib.h"
 #include "../comedidev.h"
 #include <linux/string.h>
+#include <linux/slab.h>
 
 /* The maxiumum number of channels per subdevice. */
 #define MAX_CHANS 256
@@ -417,7 +418,7 @@ static int doDevConfig(struct comedi_dev
 		int sdev = -1, nchans, tmp;
 		struct BondedDevice *bdev = NULL;
 
-		if (minor < 0 || minor > COMEDI_NUM_BOARD_MINORS) {
+		if (minor < 0 || minor >= COMEDI_NUM_BOARD_MINORS) {
 			ERROR("Minor %d is invalid!\n", minor);
 			return 0;
 		}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/contec_pci_dio.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/contec_pci_dio.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/contec_pci_dio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/contec_pci_dio.c	2010-05-16 17:17:36.000000000 -0400
@@ -173,9 +173,8 @@ static int contec_detach(struct comedi_d
 	printk("comedi%d: contec: remove\n", dev->minor);
 
 	if (devpriv && devpriv->pci_dev) {
-		if (dev->iobase) {
+		if (dev->iobase)
 			comedi_pci_disable(devpriv->pci_dev);
-		}
 		pci_dev_put(devpriv->pci_dev);
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/das08_cs.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/das08_cs.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/das08_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/das08_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,7 @@ This is the PCMCIA-specific support spli
 das08 driver.
 
 Options (for pcm-das08):
-        NONE
+	NONE
 
 Command support does not exist, but could be added for this board.
 */
@@ -43,6 +43,7 @@ Command support does not exist, but coul
 
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "das08.h"
 
@@ -52,7 +53,7 @@ Command support does not exist, but coul
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
 
-static struct pcmcia_device *cur_dev = NULL;
+static struct pcmcia_device *cur_dev;
 
 #define thisboard ((const struct das08_board_struct *)dev->board_ptr)
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/das16.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/das16.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/das16.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/das16.c	2010-05-16 17:17:36.000000000 -0400
@@ -79,6 +79,7 @@ Computer boards manuals also available f
 */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <asm/dma.h>
 #include "../comedidev.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/das1800.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/das1800.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/das1800.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/das1800.c	2010-05-16 17:17:36.000000000 -0400
@@ -101,6 +101,7 @@ TODO:
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 
 #include <linux/ioport.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/das6402.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/das6402.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/das6402.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/das6402.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,7 +45,7 @@ This driver has suffered bitrot.
 
 #define DAS6402_SIZE 16
 
-#define N_WORDS 3000*64
+#define N_WORDS (3000*64)
 
 #define STOP    0
 #define START   1
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/das800.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/das800.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/das800.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/das800.c	2010-05-16 17:17:36.000000000 -0400
@@ -399,9 +399,8 @@ static irqreturn_t das800_interrupt(int
 		} else {
 			fifo_empty = 0;	/*  cio-das802/16 has no fifo empty status bit */
 		}
-		if (fifo_empty) {
+		if (fifo_empty)
 			break;
-		}
 		/* strip off extraneous bits for 12 bit cards */
 		if (thisboard->resolution == 12)
 			dataPoint = (dataPoint >> 4) & 0xfff;
@@ -457,9 +456,8 @@ static int das800_attach(struct comedi_d
 	int board;
 
 	printk("comedi%d: das800: io 0x%lx", dev->minor, iobase);
-	if (irq) {
+	if (irq)
 		printk(", irq %u", irq);
-	}
 	printk("\n");
 
 	/* allocate and initialize dev->private */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/dmm32at.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/dmm32at.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/dmm32at.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/dmm32at.c	2010-05-16 17:17:36.000000000 -0400
@@ -1048,11 +1048,10 @@ static int dmm32at_dio_insn_config(struc
 	 * value COMEDI_INPUT or COMEDI_OUTPUT. */
 
 	/* if output clear the bit, otherwise set it */
-	if (data[0] == COMEDI_OUTPUT) {
+	if (data[0] == COMEDI_OUTPUT)
 		devpriv->dio_config &= ~chanbit;
-	} else {
+	else
 		devpriv->dio_config |= chanbit;
-	}
 	/* get access to the DIO regs */
 	dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC);
 	/* set the DIO's to the new configuration setting */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/dt2801.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/dt2801.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/dt2801.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/dt2801.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,10 +18,10 @@ Configuration options:
   [1] - unused
   [2] - A/D reference 0=differential, 1=single-ended
   [3] - A/D range
-          0 = [-10,10]
+	  0 = [-10, 10]
 	  1 = [0,10]
   [4] - D/A 0 range
-          0 = [-10,10]
+	  0 = [-10, 10]
 	  1 = [-5,5]
 	  2 = [-2.5,2.5]
 	  3 = [0,10]
@@ -279,9 +279,8 @@ static int dt2801_readdata(struct comedi
 
 	do {
 		stat = inb_p(dev->iobase + DT2801_STATUS);
-		if (stat & (DT_S_COMPOSITE_ERROR | DT_S_READY)) {
+		if (stat & (DT_S_COMPOSITE_ERROR | DT_S_READY))
 			return stat;
-		}
 		if (stat & DT_S_DATA_OUT_READY) {
 			*data = inb_p(dev->iobase + DT2801_DATA);
 			return 0;
@@ -315,9 +314,8 @@ static int dt2801_writedata(struct comed
 	do {
 		stat = inb_p(dev->iobase + DT2801_STATUS);
 
-		if (stat & DT_S_COMPOSITE_ERROR) {
+		if (stat & DT_S_COMPOSITE_ERROR)
 			return stat;
-		}
 		if (!(stat & DT_S_DATA_IN_FULL)) {
 			outb_p(data & 0xff, dev->iobase + DT2801_DATA);
 			return 0;
@@ -354,18 +352,15 @@ static int dt2801_wait_for_ready(struct
 	int stat;
 
 	stat = inb_p(dev->iobase + DT2801_STATUS);
-	if (stat & DT_S_READY) {
+	if (stat & DT_S_READY)
 		return 0;
-	}
 	do {
 		stat = inb_p(dev->iobase + DT2801_STATUS);
 
-		if (stat & DT_S_COMPOSITE_ERROR) {
+		if (stat & DT_S_COMPOSITE_ERROR)
 			return stat;
-		}
-		if (stat & DT_S_READY) {
+		if (stat & DT_S_READY)
 			return 0;
-		}
 	} while (--timeout > 0);
 
 	return -ETIME;
@@ -382,9 +377,8 @@ static int dt2801_writecmd(struct comedi
 		printk
 		    ("dt2801: composite-error in dt2801_writecmd(), ignoring\n");
 	}
-	if (!(stat & DT_S_READY)) {
+	if (!(stat & DT_S_READY))
 		printk("dt2801: !ready in dt2801_writecmd(), ignoring\n");
-	}
 	outb_p(command, dev->iobase + DT2801_CMD);
 
 	return 0;
@@ -418,9 +412,8 @@ static int dt2801_reset(struct comedi_de
 		if (stat & DT_S_READY)
 			break;
 	} while (timeout--);
-	if (!timeout) {
+	if (!timeout)
 		printk("dt2801: timeout 1 status=0x%02x\n", stat);
-	}
 
 	/* printk("dt2801: reading dummy\n"); */
 	/* dt2801_readdata(dev,&board_code); */
@@ -436,9 +429,8 @@ static int dt2801_reset(struct comedi_de
 		if (stat & DT_S_READY)
 			break;
 	} while (timeout--);
-	if (!timeout) {
+	if (!timeout)
 		printk("dt2801: timeout 2 status=0x%02x\n", stat);
-	}
 
 	DPRINTK("dt2801: reading code\n");
 	dt2801_readdata(dev, &board_code);
@@ -623,11 +615,10 @@ static int dt2801_detach(struct comedi_d
 static int dt2801_error(struct comedi_device *dev, int stat)
 {
 	if (stat < 0) {
-		if (stat == -ETIME) {
+		if (stat == -ETIME)
 			printk("dt2801: timeout\n");
-		} else {
+		else
 			printk("dt2801: error %d\n", stat);
-		}
 		return stat;
 	}
 	printk("dt2801: error status 0x%02x, resetting...\n", stat);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/dt2815.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/dt2815.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/dt2815.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/dt2815.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,19 +34,19 @@ Configuration options:
   [0] - I/O port base base address
   [1] - IRQ (unused)
   [2] - Voltage unipolar/bipolar configuration
-          0 == unipolar 5V  (0V -- +5V)
-	  1 == bipolar 5V  (-5V -- +5V)
+	0 == unipolar 5V  (0V -- +5V)
+	1 == bipolar 5V  (-5V -- +5V)
   [3] - Current offset configuration
-          0 == disabled  (0mA -- +32mAV)
-          1 == enabled  (+4mA -- +20mAV)
+	0 == disabled  (0mA -- +32mAV)
+	1 == enabled  (+4mA -- +20mAV)
   [4] - Firmware program configuration
-          0 == program 1 (see manual table 5-4)
-          1 == program 2 (see manual table 5-4)
-          2 == program 3 (see manual table 5-4)
-          3 == program 4 (see manual table 5-4)
+	0 == program 1 (see manual table 5-4)
+	1 == program 2 (see manual table 5-4)
+	2 == program 3 (see manual table 5-4)
+	3 == program 4 (see manual table 5-4)
   [5] - Analog output 0 range configuration
-          0 == voltage
-          1 == current
+	0 == voltage
+	1 == current
   [6] - Analog output 1 range configuration (same options)
   [7] - Analog output 2 range configuration (same options)
   [8] - Analog output 3 range configuration (same options)
@@ -61,17 +61,11 @@ Configuration options:
 #include <linux/ioport.h>
 #include <linux/delay.h>
 
-static const struct comedi_lrange range_dt2815_ao_32_current = { 1, {
-								     RANGE_mA(0,
-									      32)
-								     }
-};
+static const struct comedi_lrange
+	range_dt2815_ao_32_current = {1, {RANGE_mA(0, 32)} };
 
-static const struct comedi_lrange range_dt2815_ao_20_current = { 1, {
-								     RANGE_mA(4,
-									      20)
-								     }
-};
+static const struct comedi_lrange
+	range_dt2815_ao_20_current = {1, {RANGE_mA(4, 20)} };
 
 #define DT2815_SIZE 2
 
@@ -118,9 +112,8 @@ static int dt2815_ao_insn_read(struct co
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
 
-	for (i = 0; i < insn->n; i++) {
+	for (i = 0; i < insn->n; i++)
 		data[i] = devpriv->ao_readback[chan];
-	}
 
 	return i;
 }
@@ -139,9 +132,8 @@ static int dt2815_ao_insn(struct comedi_
 
 		status = dt2815_wait_for_status(dev, 0x00);
 		if (status != 0) {
-			printk
-			    ("dt2815: failed to write low byte on %d reason %x\n",
-			     chan, status);
+			printk(KERN_WARNING "dt2815: failed to write low byte "
+			       "on %d reason %x\n", chan, status);
 			return -EBUSY;
 		}
 
@@ -149,9 +141,8 @@ static int dt2815_ao_insn(struct comedi_
 
 		status = dt2815_wait_for_status(dev, 0x10);
 		if (status != 0x10) {
-			printk
-			    ("dt2815: failed to write high byte on %d reason %x\n",
-			     chan, status);
+			printk(KERN_WARNING "dt2815: failed to write high byte "
+			       "on %d reason %x\n", chan, status);
 			return -EBUSY;
 		}
 		devpriv->ao_readback[chan] = data[i];
@@ -163,24 +154,24 @@ static int dt2815_ao_insn(struct comedi_
   options[0]   Board base address
   options[1]   IRQ (not applicable)
   options[2]   Voltage unipolar/bipolar configuration
-                 0 == unipolar 5V  (0V -- +5V)
-		 1 == bipolar 5V  (-5V -- +5V)
+		0 == unipolar 5V  (0V -- +5V)
+		1 == bipolar 5V  (-5V -- +5V)
   options[3]   Current offset configuration
-                 0 == disabled  (0mA -- +32mAV)
-                 1 == enabled  (+4mA -- +20mAV)
+		0 == disabled  (0mA -- +32mAV)
+		1 == enabled  (+4mA -- +20mAV)
   options[4]   Firmware program configuration
-                 0 == program 1 (see manual table 5-4)
-                 1 == program 2 (see manual table 5-4)
-                 2 == program 3 (see manual table 5-4)
-                 3 == program 4 (see manual table 5-4)
+		0 == program 1 (see manual table 5-4)
+		1 == program 2 (see manual table 5-4)
+		2 == program 3 (see manual table 5-4)
+		3 == program 4 (see manual table 5-4)
   options[5]   Analog output 0 range configuration
-                 0 == voltage
-                 1 == current
+		0 == voltage
+		1 == current
   options[6]   Analog output 1 range configuration
   ...
   options[12]   Analog output 7 range configuration
-                 0 == voltage
-                 1 == current
+		0 == voltage
+		1 == current
  */
 
 static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
@@ -191,9 +182,9 @@ static int dt2815_attach(struct comedi_d
 	unsigned long iobase;
 
 	iobase = it->options[0];
-	printk("comedi%d: dt2815: 0x%04lx ", dev->minor, iobase);
+	printk(KERN_INFO "comedi%d: dt2815: 0x%04lx ", dev->minor, iobase);
 	if (!request_region(iobase, DT2815_SIZE, "dt2815")) {
-		printk("I/O port conflict\n");
+		printk(KERN_WARNING "I/O port conflict\n");
 		return -EIO;
 	}
 
@@ -236,19 +227,17 @@ static int dt2815_attach(struct comedi_d
 			unsigned int program;
 			program = (it->options[4] & 0x3) << 3 | 0x7;
 			outb(program, dev->iobase + DT2815_DATA);
-			printk(", program: 0x%x (@t=%d)\n", program, i);
+			printk(KERN_INFO ", program: 0x%x (@t=%d)\n",
+			       program, i);
 			break;
 		} else if (status != 0x00) {
-			printk("dt2815: unexpected status 0x%x (@t=%d)\n",
-			       status, i);
-			if (status & 0x60) {
+			printk(KERN_WARNING "dt2815: unexpected status 0x%x "
+			       "(@t=%d)\n", status, i);
+			if (status & 0x60)
 				outb(0x00, dev->iobase + DT2815_STATUS);
-			}
 		}
 	}
 
-	printk("\n");
-
 	return 0;
 }
 
@@ -260,7 +249,7 @@ static void dt2815_free_resources(struct
 
 static int dt2815_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: dt2815: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: dt2815: remove\n", dev->minor);
 
 	dt2815_free_resources(dev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/dt282x.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/dt282x.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/dt282x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/dt282x.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,6 +58,7 @@ Notes:
 
 #include "../comedidev.h"
 
+#include <linux/gfp.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <asm/dma.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/dt9812.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/dt9812.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/dt9812.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/dt9812.c	2010-05-16 17:17:36.000000000 -0400
@@ -264,7 +264,7 @@ struct dt9812_usb_cmd {
 
 static DECLARE_MUTEX(dt9812_mutex);
 
-static struct usb_device_id dt9812_table[] = {
+static const struct usb_device_id dt9812_table[] = {
 	{USB_DEVICE(0x0867, 0x9812)},
 	{}			/* Terminating entry */
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/fl512.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/fl512.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/fl512.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/fl512.c	2010-05-16 17:17:36.000000000 -0400
@@ -76,14 +76,14 @@ static int fl512_ai_insn(struct comedi_d
 	unsigned long iobase = dev->iobase;
 
 	for (n = 0; n < insn->n; n++) {	/* sample n times on selected channel */
-		/* XXX probably can move next step out of for() loop -- will make
-		 * AI a little bit faster. */
+		/* XXX probably can move next step out of for() loop -- will
+		 * make AI a little bit faster. */
 		outb(chan, iobase + 2);	/* select chan */
 		outb(0, iobase + 3);	/* start conversion */
 		/* XXX should test "done" flag instead of delay */
 		udelay(30);	/* sleep 30 usec */
 		lo_byte = inb(iobase + 2);	/* low 8 byte */
-		hi_byte = inb(iobase + 3) & 0xf;	/* high 4 bit and mask */
+		hi_byte = inb(iobase + 3) & 0xf; /* high 4 bit and mask */
 		data[n] = lo_byte + (hi_byte << 8);
 	}
 	return n;
@@ -101,8 +101,10 @@ static int fl512_ao_insn(struct comedi_d
 	unsigned long iobase = dev->iobase;	/* get base address  */
 
 	for (n = 0; n < insn->n; n++) {	/* write n data set */
-		outb(data[n] & 0x0ff, iobase + 4 + 2 * chan);	/* write low byte   */
-		outb((data[n] & 0xf00) >> 8, iobase + 4 + 2 * chan);	/* write high byte  */
+		/* write low byte   */
+		outb(data[n] & 0x0ff, iobase + 4 + 2 * chan);
+		/* write high byte  */
+		outb((data[n] & 0xf00) >> 8, iobase + 4 + 2 * chan);
 		inb(iobase + 4 + 2 * chan);	/* trig */
 
 		devpriv->ao_readback[chan] = data[n];
@@ -121,9 +123,8 @@ static int fl512_ao_insn_readback(struct
 	int n;
 	int chan = CR_CHAN(insn->chanspec);
 
-	for (n = 0; n < insn->n; n++) {
+	for (n = 0; n < insn->n; n++)
 		data[n] = devpriv->ao_readback[chan];
-	}
 
 	return n;
 }
@@ -134,13 +135,15 @@ static int fl512_ao_insn_readback(struct
 static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	unsigned long iobase;
-	struct comedi_subdevice *s;	/* pointer to the subdevice:
-					   Analog in, Analog out, ( not made ->and Digital IO) */
+
+	/* pointer to the subdevice: Analog in, Analog out,
+	   (not made ->and Digital IO) */
+	struct comedi_subdevice *s;
 
 	iobase = it->options[0];
-	printk("comedi:%d fl512: 0x%04lx", dev->minor, iobase);
+	printk(KERN_INFO "comedi:%d fl512: 0x%04lx", dev->minor, iobase);
 	if (!request_region(iobase, FL512_SIZE, "fl512")) {
-		printk(" I/O port conflict\n");
+		printk(KERN_WARNING " I/O port conflict\n");
 		return -EIO;
 	}
 	dev->iobase = iobase;
@@ -149,7 +152,7 @@ static int fl512_attach(struct comedi_de
 		return -ENOMEM;
 
 #if DEBUG
-	printk("malloc ok\n");
+	printk(KERN_DEBUG "malloc ok\n");
 #endif
 
 	if (alloc_subdevices(dev, 2) < 0)
@@ -160,24 +163,37 @@ static int fl512_attach(struct comedi_de
 	 */
 	/* Analog indput */
 	s = dev->subdevices + 0;
-	s->type = COMEDI_SUBD_AI;	/* define subdevice as Analog In   */
-	s->subdev_flags = SDF_READABLE | SDF_GROUND;	/* you can read it from userspace  */
-	s->n_chan = 16;		/* Number of Analog input channels */
-	s->maxdata = 0x0fff;	/* accept only 12 bits of data     */
-	s->range_table = &range_fl512;	/* device use one of the ranges    */
-	s->insn_read = fl512_ai_insn;	/* function to call when read AD   */
-	printk("comedi: fl512: subdevice 0 initialized\n");
+	/* define subdevice as Analog In */
+	s->type = COMEDI_SUBD_AI;
+	/* you can read it from userspace */
+	s->subdev_flags = SDF_READABLE | SDF_GROUND;
+	/* Number of Analog input channels */
+	s->n_chan = 16;
+	/* accept only 12 bits of data */
+	s->maxdata = 0x0fff;
+	/* device use one of the ranges */
+	s->range_table = &range_fl512;
+	/* function to call when read AD */
+	s->insn_read = fl512_ai_insn;
+	printk(KERN_INFO "comedi: fl512: subdevice 0 initialized\n");
 
 	/* Analog output */
 	s = dev->subdevices + 1;
-	s->type = COMEDI_SUBD_AO;	/* define subdevice as Analog OUT   */
-	s->subdev_flags = SDF_WRITABLE;	/* you can write it from userspace  */
-	s->n_chan = 2;		/* Number of Analog output channels */
-	s->maxdata = 0x0fff;	/* accept only 12 bits of data      */
-	s->range_table = &range_fl512;	/* device use one of the ranges     */
-	s->insn_write = fl512_ao_insn;	/* function to call when write DA   */
-	s->insn_read = fl512_ao_insn_readback;	/* function to call when reading DA   */
-	printk("comedi: fl512: subdevice 1 initialized\n");
+	/* define subdevice as Analog OUT */
+	s->type = COMEDI_SUBD_AO;
+	/* you can write it from userspace */
+	s->subdev_flags = SDF_WRITABLE;
+	/* Number of Analog output channels */
+	s->n_chan = 2;
+	/* accept only 12 bits of data */
+	s->maxdata = 0x0fff;
+	/* device use one of the ranges */
+	s->range_table = &range_fl512;
+	/* function to call when write DA */
+	s->insn_write = fl512_ao_insn;
+	/* function to call when reading DA */
+	s->insn_read = fl512_ao_insn_readback;
+	printk(KERN_INFO "comedi: fl512: subdevice 1 initialized\n");
 
 	return 1;
 }
@@ -186,6 +202,6 @@ static int fl512_detach(struct comedi_de
 {
 	if (dev->iobase)
 		release_region(dev->iobase, FL512_SIZE);
-	printk("comedi%d: fl512: dummy i detach\n", dev->minor);
+	printk(KERN_INFO "comedi%d: fl512: dummy i detach\n", dev->minor);
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/jr3_pci.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/jr3_pci.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/jr3_pci.c	2013-05-03 12:12:21.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/jr3_pci.c	2013-05-03 09:51:53.000000000 -0400
@@ -46,6 +46,7 @@ Devices: [JR3] PCI force sensor board (j
 #include <linux/ctype.h>
 #include <linux/firmware.h>
 #include <linux/jiffies.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include "comedi_pci.h"
 #include "jr3_pci.h"
@@ -954,6 +955,8 @@ out:
 	return result;
 }
 
+/*(DEBLOBBED)*/
+
 static int jr3_pci_detach(struct comedi_device *dev)
 {
 	int i;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/mpc624.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/mpc624.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/mpc624.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/mpc624.c	2010-05-16 17:17:36.000000000 -0400
@@ -284,7 +284,7 @@ static int mpc624_ai_rinsn(struct comedi
 	outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH);
 /* printk("Channel %d: \n", insn->chanspec); */
 	if (!insn->n) {
-		printk("MPC624: Warning, no data to aquire\n");
+		printk("MPC624: Warning, no data to acquire\n");
 		return 0;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_65xx.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_65xx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_65xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_65xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,12 +26,13 @@
 /*
 Driver: ni_65xx
 Description: National Instruments 65xx static dio boards
-Author: Jon Grierson <jd@renko.co.uk>, Frank Mori Hess <fmhess@users.sourceforge.net>
+Author: Jon Grierson <jd@renko.co.uk>,
+	Frank Mori Hess <fmhess@users.sourceforge.net>
 Status: testing
-Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510, PCI-6511,
-  PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514, PXI-6514, PCI-6515,
-  PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519, PCI-6520, PCI-6521, PXI-6521,
-  PCI-6528, PXI-6528
+Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510,
+  PCI-6511, PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514,
+  PXI-6514, PCI-6515, PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519,
+  PCI-6520, PCI-6521, PXI-6521, PCI-6528, PXI-6528
 Updated: Wed Oct 18 08:59:11 EDT 2006
 
 Based on the PCI-6527 driver by ds.
@@ -51,6 +52,7 @@ except maybe the 6514.
 #define DEBUG 1
 #define DEBUG_FLAGS
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 
 #include "mite.h"
@@ -418,9 +420,10 @@ static int ni_65xx_dio_insn_bits(struct
 		return -EINVAL;
 	base_bitfield_channel = CR_CHAN(insn->chanspec);
 	for (j = 0; j < max_ports_per_bitfield; ++j) {
-		const unsigned port_offset = ni_65xx_port_by_channel(base_bitfield_channel) + j;
+		const unsigned port_offset =
+			ni_65xx_port_by_channel(base_bitfield_channel) + j;
 		const unsigned port =
-		    sprivate(s)->base_port + port_offset;
+			sprivate(s)->base_port + port_offset;
 		unsigned base_port_channel;
 		unsigned port_mask, port_data, port_read_bits;
 		int bitshift;
@@ -463,11 +466,11 @@ static int ni_65xx_dio_insn_bits(struct
 			 * subdevice.) */
 			port_read_bits ^= 0xFF;
 		}
-		if (bitshift > 0) {
+		if (bitshift > 0)
 			port_read_bits <<= bitshift;
-		} else {
+		else
 			port_read_bits >>= -bitshift;
-		}
+
 		read_bits |= port_read_bits;
 	}
 	data[1] = read_bits;
@@ -532,7 +535,8 @@ static int ni_65xx_intr_cmdtest(struct c
 	if (err)
 		return 1;
 
-	/* step 2: make sure trigger sources are unique and mutually compatible */
+	/* step 2: make sure trigger sources are unique and mutually
+	compatible */
 
 	if (err)
 		return 2;
@@ -652,7 +656,7 @@ static int ni_65xx_attach(struct comedi_
 	unsigned i;
 	int ret;
 
-	printk("comedi%d: ni_65xx:", dev->minor);
+	printk(KERN_INFO "comedi%d: ni_65xx:", dev->minor);
 
 	ret = alloc_private(dev, sizeof(struct ni_65xx_private));
 	if (ret < 0)
@@ -664,15 +668,15 @@ static int ni_65xx_attach(struct comedi_
 
 	ret = mite_setup(private(dev)->mite);
 	if (ret < 0) {
-		printk("error setting up mite\n");
+		printk(KERN_WARNING "error setting up mite\n");
 		return ret;
 	}
 
 	dev->board_name = board(dev)->name;
 	dev->irq = mite_irq(private(dev)->mite);
-	printk(" %s", dev->board_name);
+	printk(KERN_INFO " %s", dev->board_name);
 
-	printk(" ID=0x%02x",
+	printk(KERN_INFO " ID=0x%02x",
 	       readb(private(dev)->mite->daq_io_addr + ID_Register));
 
 	ret = alloc_subdevices(dev, 4);
@@ -773,7 +777,7 @@ static int ni_65xx_attach(struct comedi_
 			  "ni_65xx", dev);
 	if (ret < 0) {
 		dev->irq = 0;
-		printk(" irq not available");
+		printk(KERN_WARNING " irq not available");
 	}
 
 	printk("\n");
@@ -790,21 +794,17 @@ static int ni_65xx_detach(struct comedi_
 		       Master_Interrupt_Control);
 	}
 
-	if (dev->irq) {
+	if (dev->irq)
 		free_irq(dev->irq, dev);
-	}
 
 	if (private(dev)) {
 		unsigned i;
 		for (i = 0; i < dev->n_subdevices; ++i) {
-			if (dev->subdevices[i].private) {
-				kfree(dev->subdevices[i].private);
-				dev->subdevices[i].private = NULL;
-			}
+			kfree(dev->subdevices[i].private);
+			dev->subdevices[i].private = NULL;
 		}
-		if (private(dev)->mite) {
+		if (private(dev)->mite)
 			mite_unsetup(private(dev)->mite);
-		}
 	}
 	return 0;
 }
@@ -830,7 +830,7 @@ static int ni_65xx_find_device(struct co
 			}
 		}
 	}
-	printk("no device found\n");
+	printk(KERN_WARNING "no device found\n");
 	mite_list_devices();
 	return -EIO;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_660x.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_660x.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_660x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_660x.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,7 +52,8 @@ enum ni_660x_constants {
 };
 
 #define NUM_PFI_CHANNELS 40
-/* really there are only up to 3 dma channels, but the register layout allows for 4 */
+/* really there are only up to 3 dma channels, but the register layout allows
+for 4 */
 #define MAX_DMA_CHANNEL 4
 
 /* See Register-Level Programmer Manual page 3.1 */
@@ -198,7 +199,7 @@ struct NI_660xRegisterData {
 	const char *name;	/*  Register Name */
 	int offset;		/*  Offset from base address from GPCT chip */
 	enum ni_660x_register_direction direction;
-	enum ni_660x_register_width size;	/*  1 byte, 2 bytes, or 4 bytes */
+	enum ni_660x_register_width size; /* 1 byte, 2 bytes, or 4 bytes */
 };
 
 static const struct NI_660xRegisterData registerData[NumRegisters] = {
@@ -382,8 +383,8 @@ enum global_interrupt_config_register_bi
 };
 
 /* Offset of the GPCT chips from the base-adress of the card */
-static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 };	/* First chip is at base-address +
-							   0x00, etc. */
+/* First chip is at base-address + 0x00, etc. */
+static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 };
 
 /* Board description*/
 struct ni_660x_board {
@@ -691,13 +692,13 @@ static enum NI_660x_Register ni_gpct_to_
 		ni_660x_register = G0StatusRegister;
 		break;
 	case NITIO_G1_Status_Reg:
-		ni_660x_register = G0StatusRegister;
+		ni_660x_register = G1StatusRegister;
 		break;
 	case NITIO_G2_Status_Reg:
-		ni_660x_register = G0StatusRegister;
+		ni_660x_register = G2StatusRegister;
 		break;
 	case NITIO_G3_Status_Reg:
-		ni_660x_register = G0StatusRegister;
+		ni_660x_register = G3StatusRegister;
 		break;
 	case NITIO_G0_Interrupt_Enable_Reg:
 		ni_660x_register = G0InterruptEnable;
@@ -712,7 +713,7 @@ static enum NI_660x_Register ni_gpct_to_
 		ni_660x_register = G3InterruptEnable;
 		break;
 	default:
-		printk("%s: unhandled register 0x%x in switch.\n",
+		printk(KERN_WARNING "%s: unhandled register 0x%x in switch.\n",
 		       __func__, reg);
 		BUG();
 		return 0;
@@ -737,7 +738,7 @@ static inline void ni_660x_write_registe
 		writel(bits, write_address);
 		break;
 	default:
-		printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
+		printk(KERN_WARNING "%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
 		       __FILE__, __func__, reg);
 		BUG();
 		break;
@@ -760,7 +761,7 @@ static inline unsigned ni_660x_read_regi
 		return readl(read_address);
 		break;
 	default:
-		printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
+		printk(KERN_WARNING "%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
 		       __FILE__, __func__, reg);
 		BUG();
 		break;
@@ -993,9 +994,9 @@ static int ni_660x_allocate_private(stru
 	spin_lock_init(&private(dev)->mite_channel_lock);
 	spin_lock_init(&private(dev)->interrupt_lock);
 	spin_lock_init(&private(dev)->soft_reg_copy_lock);
-	for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
+	for (i = 0; i < NUM_PFI_CHANNELS; ++i)
 		private(dev)->pfi_output_selects[i] = pfi_output_select_counter;
-	}
+
 	return 0;
 }
 
@@ -1008,9 +1009,8 @@ static int ni_660x_alloc_mite_rings(stru
 		for (j = 0; j < counters_per_chip; ++j) {
 			private(dev)->mite_rings[i][j] =
 			    mite_alloc_ring(private(dev)->mite);
-			if (private(dev)->mite_rings[i][j] == NULL) {
+			if (private(dev)->mite_rings[i][j] == NULL)
 				return -ENOMEM;
-			}
 		}
 	}
 	return 0;
@@ -1022,9 +1022,8 @@ static void ni_660x_free_mite_rings(stru
 	unsigned j;
 
 	for (i = 0; i < board(dev)->n_chips; ++i) {
-		for (j = 0; j < counters_per_chip; ++j) {
+		for (j = 0; j < counters_per_chip; ++j)
 			mite_free_ring(private(dev)->mite_rings[i][j]);
-		}
 	}
 }
 
@@ -1036,7 +1035,7 @@ static int ni_660x_attach(struct comedi_
 	unsigned i;
 	unsigned global_interrupt_config_bits;
 
-	printk("comedi%d: ni_660x: ", dev->minor);
+	printk(KERN_INFO "comedi%d: ni_660x: ", dev->minor);
 
 	ret = ni_660x_allocate_private(dev);
 	if (ret < 0)
@@ -1049,7 +1048,7 @@ static int ni_660x_attach(struct comedi_
 
 	ret = mite_setup2(private(dev)->mite, 1);
 	if (ret < 0) {
-		printk("error setting up mite\n");
+		printk(KERN_WARNING "error setting up mite\n");
 		return ret;
 	}
 	comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev);
@@ -1057,7 +1056,7 @@ static int ni_660x_attach(struct comedi_
 	if (ret < 0)
 		return ret;
 
-	printk(" %s ", dev->board_name);
+	printk(KERN_INFO " %s ", dev->board_name);
 
 	dev->n_subdevices = 2 + NI_660X_MAX_NUM_COUNTERS;
 
@@ -1078,15 +1077,16 @@ static int ni_660x_attach(struct comedi_
 	s->insn_bits = ni_660x_dio_insn_bits;
 	s->insn_config = ni_660x_dio_insn_config;
 	s->io_bits = 0;		/* all bits default to input */
-	/*  we use the ioconfig registers to control dio direction, so zero output enables in stc dio control reg */
+	/*  we use the ioconfig registers to control dio direction, so zero
+	output enables in stc dio control reg */
 	ni_660x_write_register(dev, 0, 0, STCDIOControl);
 
 	private(dev)->counter_dev = ni_gpct_device_construct(dev,
-							     &ni_gpct_write_register,
-							     &ni_gpct_read_register,
-							     ni_gpct_variant_660x,
-							     ni_660x_num_counters
-							     (dev));
+						     &ni_gpct_write_register,
+						     &ni_gpct_read_register,
+						     ni_gpct_variant_660x,
+						     ni_660x_num_counters
+						     (dev));
 	if (private(dev)->counter_dev == NULL)
 		return -ENOMEM;
 	for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) {
@@ -1118,12 +1118,12 @@ static int ni_660x_attach(struct comedi_
 			s->type = COMEDI_SUBD_UNUSED;
 		}
 	}
-	for (i = 0; i < board(dev)->n_chips; ++i) {
+	for (i = 0; i < board(dev)->n_chips; ++i)
 		init_tio_chip(dev, i);
-	}
-	for (i = 0; i < ni_660x_num_counters(dev); ++i) {
+
+	for (i = 0; i < ni_660x_num_counters(dev); ++i)
 		ni_tio_init_counter(&private(dev)->counter_dev->counters[i]);
-	}
+
 	for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
 		if (i < min_counter_pfi_chan)
 			ni_660x_set_pfi_routing(dev, i, pfi_output_select_do);
@@ -1134,13 +1134,13 @@ static int ni_660x_attach(struct comedi_
 	}
 	/* to be safe, set counterswap bits on tio chips after all the counter
 	   outputs have been set to high impedance mode */
-	for (i = 0; i < board(dev)->n_chips; ++i) {
+	for (i = 0; i < board(dev)->n_chips; ++i)
 		set_tio_counterswap(dev, i);
-	}
+
 	ret = request_irq(mite_irq(private(dev)->mite), ni_660x_interrupt,
 			  IRQF_SHARED, "ni_660x", dev);
 	if (ret < 0) {
-		printk(" irq not available\n");
+		printk(KERN_WARNING " irq not available\n");
 		return ret;
 	}
 	dev->irq = mite_irq(private(dev)->mite);
@@ -1149,13 +1149,13 @@ static int ni_660x_attach(struct comedi_
 		global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
 	ni_660x_write_register(dev, 0, global_interrupt_config_bits,
 			       GlobalInterruptConfigRegister);
-	printk("attached\n");
+	printk(KERN_INFO "attached\n");
 	return 0;
 }
 
 static int ni_660x_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: ni_660x: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: ni_660x: remove\n", dev->minor);
 
 	/* Free irq */
 	if (dev->irq)
@@ -1193,9 +1193,8 @@ static void init_tio_chip(struct comedi_
 			       private(dev)->
 			       dma_configuration_soft_copies[chipset],
 			       DMAConfigRegister);
-	for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
+	for (i = 0; i < NUM_PFI_CHANNELS; ++i)
 		ni_660x_write_register(dev, chipset, 0, IOConfigReg(i));
-	}
 }
 
 static int
@@ -1234,7 +1233,7 @@ static int ni_660x_find_device(struct co
 			}
 		}
 	}
-	printk("no device found\n");
+	printk(KERN_WARNING "no device found\n");
 	mite_list_devices();
 	return -EIO;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_670x.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_670x.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_670x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_670x.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@ Commands are not supported.
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 
 #include "mite.h"
@@ -93,7 +94,7 @@ static DEFINE_PCI_DEVICE_TABLE(ni_670x_p
 	{
 	PCI_VENDOR_ID_NATINST, 0x2c90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
 	PCI_VENDOR_ID_NATINST, 0x1920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	    /* { PCI_VENDOR_ID_NATINST, 0x0000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */
+	/*{ PCI_VENDOR_ID_NATINST, 0x0000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },*/
 	{
 	0}
 };
@@ -151,7 +152,7 @@ static int ni_670x_attach(struct comedi_
 	int ret;
 	int i;
 
-	printk("comedi%d: ni_670x: ", dev->minor);
+	printk(KERN_INFO "comedi%d: ni_670x: ", dev->minor);
 
 	ret = alloc_private(dev, sizeof(struct ni_670x_private));
 	if (ret < 0)
@@ -163,12 +164,12 @@ static int ni_670x_attach(struct comedi_
 
 	ret = mite_setup(devpriv->mite);
 	if (ret < 0) {
-		printk("error setting up mite\n");
+		printk(KERN_WARNING "error setting up mite\n");
 		return ret;
 	}
 	dev->board_name = thisboard->name;
 	dev->irq = mite_irq(devpriv->mite);
-	printk(" %s", dev->board_name);
+	printk(KERN_INFO " %s", dev->board_name);
 
 	if (alloc_subdevices(dev, 2) < 0)
 		return -ENOMEM;
@@ -207,21 +208,22 @@ static int ni_670x_attach(struct comedi_
 	s->insn_bits = ni_670x_dio_insn_bits;
 	s->insn_config = ni_670x_dio_insn_config;
 
-	writel(0x10, devpriv->mite->daq_io_addr + MISC_CONTROL_OFFSET);	/* Config of misc registers */
-	writel(0x00, devpriv->mite->daq_io_addr + AO_CONTROL_OFFSET);	/* Config of ao registers */
+	/* Config of misc registers */
+	writel(0x10, devpriv->mite->daq_io_addr + MISC_CONTROL_OFFSET);
+	/* Config of ao registers */
+	writel(0x00, devpriv->mite->daq_io_addr + AO_CONTROL_OFFSET);
 
-	printk("attached\n");
+	printk(KERN_INFO "attached\n");
 
 	return 1;
 }
 
 static int ni_670x_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: ni_670x: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: ni_670x: remove\n", dev->minor);
+
+	kfree(dev->subdevices[0].range_table_list);
 
-	if (dev->subdevices[0].range_table_list) {
-		kfree(dev->subdevices[0].range_table_list);
-	}
 	if (dev->private && devpriv->mite)
 		mite_unsetup(devpriv->mite);
 
@@ -250,8 +252,11 @@ static int ni_670x_ao_winsn(struct comed
 	   vch(15)      :       30      | ich(31)       :       31      */
 
 	for (i = 0; i < insn->n; i++) {
-		writel(((chan & 15) << 1) | ((chan & 16) >> 4), devpriv->mite->daq_io_addr + AO_CHAN_OFFSET);	/* First write in channel register which channel to use */
-		writel(data[i], devpriv->mite->daq_io_addr + AO_VALUE_OFFSET);	/* write channel value */
+		/* First write in channel register which channel to use */
+		writel(((chan & 15) << 1) | ((chan & 16) >> 4),
+		       devpriv->mite->daq_io_addr + AO_CHAN_OFFSET);
+		/* write channel value */
+		writel(data[i], devpriv->mite->daq_io_addr + AO_VALUE_OFFSET);
 		devpriv->ao_readback[chan] = data[i];
 	}
 
@@ -344,7 +349,7 @@ static int ni_670x_find_device(struct co
 			}
 		}
 	}
-	printk("no device found\n");
+	printk(KERN_INFO "no device found\n");
 	mite_list_devices();
 	return -EIO;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_at_a2150.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_at_a2150.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_at_a2150.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_at_a2150.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,6 +65,7 @@ TRIG_WAKE_EOS
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 
 #include <linux/ioport.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_atmio.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_atmio.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_atmio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_atmio.c	2010-05-16 17:17:36.000000000 -0400
@@ -329,11 +329,11 @@ static uint16_t ni_atmio_win_in(struct c
 }
 
 static struct pnp_device_id device_ids[] = {
-	{.id = "NIC1900",.driver_data = 0},
-	{.id = "NIC2400",.driver_data = 0},
-	{.id = "NIC2500",.driver_data = 0},
-	{.id = "NIC2600",.driver_data = 0},
-	{.id = "NIC2700",.driver_data = 0},
+	{.id = "NIC1900", .driver_data = 0},
+	{.id = "NIC2400", .driver_data = 0},
+	{.id = "NIC2500", .driver_data = 0},
+	{.id = "NIC2600", .driver_data = 0},
+	{.id = "NIC2700", .driver_data = 0},
 	{.id = ""}
 };
 
@@ -362,9 +362,9 @@ static int ni_atmio_detach(struct comedi
 
 	if (dev->iobase)
 		release_region(dev->iobase, NI_SIZE);
-	if (dev->irq) {
+	if (dev->irq)
 		free_irq(dev->irq, dev);
-	}
+
 	if (devpriv->isapnp_dev)
 		pnp_device_detach(devpriv->isapnp_dev);
 
@@ -387,8 +387,8 @@ static int ni_isapnp_find_board(struct p
 
 		if (pnp_device_attach(isapnp_dev) < 0) {
 			printk
-			    ("ni_atmio: %s found but already active, skipping.\n",
-			     ni_boards[i].name);
+			 ("ni_atmio: %s found but already active, skipping.\n",
+			  ni_boards[i].name);
 			continue;
 		}
 		if (pnp_activate_dev(isapnp_dev) < 0) {
@@ -496,9 +496,9 @@ static int ni_atmio_attach(struct comedi
 	/* generic E series stuff in ni_mio_common.c */
 
 	ret = ni_E_init(dev, it);
-	if (ret < 0) {
+	if (ret < 0)
 		return ret;
-	}
+
 
 	return 0;
 }
@@ -509,16 +509,16 @@ static int ni_getboardtype(struct comedi
 	int i;
 
 	for (i = 0; i < n_ni_boards; i++) {
-		if (ni_boards[i].device_id == device_id) {
+		if (ni_boards[i].device_id == device_id)
 			return i;
-		}
+
 	}
-	if (device_id == 255) {
+	if (device_id == 255)
 		printk(" can't find board\n");
-	} else if (device_id == 0) {
+	 else if (device_id == 0)
 		printk(" EEPROM read error (?) or device not found\n");
-	} else {
+	 else
 		printk(" unknown device ID %d -- contact author\n", device_id);
-	}
+
 	return -1;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_daq_700.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_daq_700.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_daq_700.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_daq_700.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@ IRQ is assigned but not used.
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 
 #include <linux/ioport.h>
@@ -76,13 +77,15 @@ struct dio700_board {
 static const struct dio700_board dio700_boards[] = {
 	{
 	 .name = "daqcard-700",
-	 .device_id = 0x4743,	/*  0x10b is manufacturer id, 0x4743 is device id */
+	  /*  0x10b is manufacturer id, 0x4743 is device id */
+	 .device_id = 0x4743,
 	 .bustype = pcmcia_bustype,
 	 .have_dio = 1,
 	 },
 	{
 	 .name = "ni_daq_700",
-	 .device_id = 0x4743,	/*  0x10b is manufacturer id, 0x4743 is device id */
+	  /*  0x10b is manufacturer id, 0x4743 is device id */
+	 .device_id = 0x4743,
 	 .bustype = pcmcia_bustype,
 	 .have_dio = 1,
 	 },
@@ -309,11 +312,11 @@ int subdev_700_init(struct comedi_device
 		return -ENOMEM;
 
 	CALLBACK_ARG = arg;
-	if (cb == NULL) {
+	if (cb == NULL)
 		CALLBACK_FUNC = subdev_700_cb;
-	} else {
+	 else
 		CALLBACK_FUNC = cb;
-	}
+
 	s->insn_bits = subdev_700_insn;
 	s->insn_config = subdev_700_insn_config;
 
@@ -345,12 +348,10 @@ int subdev_700_init_irq(struct comedi_de
 
 void subdev_700_cleanup(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-	if (s->private) {
-		if (subdevpriv->have_irq) {
-		}
+	if (s->private)
+		if (subdevpriv->have_irq)
 
-		kfree(s->private);
-	}
+			kfree(s->private);
 }
 
 EXPORT_SYMBOL(subdev_700_init);
@@ -390,9 +391,9 @@ static int dio700_attach(struct comedi_d
 	printk("comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor,
 	       thisboard->name, iobase);
 #ifdef incomplete
-	if (irq) {
+	if (irq)
 		printk(", irq %u", irq);
-	}
+
 #endif
 
 	printk("\n");
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_daq_dio24.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_daq_dio24.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_daq_dio24.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_daq_dio24.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@ the PCMCIA interface.
 #undef LABPC_DEBUG
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 
 #include <linux/ioport.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_labpc.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_labpc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_labpc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_labpc.c	2010-05-16 17:17:36.000000000 -0400
@@ -77,6 +77,7 @@ NI manuals:
 /* #define LABPC_DEBUG    enable debugging messages */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 
 #include <linux/delay.h>
@@ -90,8 +91,10 @@ NI manuals:
 
 #define DRV_NAME "ni_labpc"
 
-#define LABPC_SIZE           32	/*  size of io region used by board */
-#define LABPC_TIMER_BASE            500	/*  2 MHz master clock */
+/* size of io region used by board */
+#define LABPC_SIZE           32
+/* 2 MHz master clock */
+#define LABPC_TIMER_BASE            500
 
 /* Registers for the lab-pc+ */
 
@@ -99,69 +102,110 @@ NI manuals:
 #define COMMAND1_REG	0x0
 #define   ADC_GAIN_MASK	(0x7 << 4)
 #define   ADC_CHAN_BITS(x)	((x) & 0x7)
-#define   ADC_SCAN_EN_BIT	0x80	/*  enables multi channel scans */
+/* enables multi channel scans */
+#define   ADC_SCAN_EN_BIT	0x80
 #define COMMAND2_REG	0x1
-#define   PRETRIG_BIT	0x1	/*  enable pretriggering (used in conjunction with SWTRIG) */
-#define   HWTRIG_BIT	0x2	/*  enable paced conversions on external trigger */
-#define   SWTRIG_BIT	0x4	/*  enable paced conversions */
-#define   CASCADE_BIT	0x8	/*  use two cascaded counters for pacing */
+/* enable pretriggering (used in conjunction with SWTRIG) */
+#define   PRETRIG_BIT	0x1
+/* enable paced conversions on external trigger */
+#define   HWTRIG_BIT	0x2
+/* enable paced conversions */
+#define   SWTRIG_BIT	0x4
+/* use two cascaded counters for pacing */
+#define   CASCADE_BIT	0x8
 #define   DAC_PACED_BIT(channel)	(0x40 << ((channel) & 0x1))
 #define COMMAND3_REG	0x2
-#define   DMA_EN_BIT	0x1	/*  enable dma transfers */
-#define   DIO_INTR_EN_BIT	0x2	/*  enable interrupts for 8255 */
-#define   DMATC_INTR_EN_BIT	0x4	/*  enable dma terminal count interrupt */
-#define   TIMER_INTR_EN_BIT	0x8	/*  enable timer interrupt */
-#define   ERR_INTR_EN_BIT	0x10	/*  enable error interrupt */
-#define   ADC_FNE_INTR_EN_BIT	0x20	/*  enable fifo not empty interrupt */
+/* enable dma transfers */
+#define   DMA_EN_BIT	0x1
+/* enable interrupts for 8255 */
+#define   DIO_INTR_EN_BIT	0x2
+/* enable dma terminal count interrupt */
+#define   DMATC_INTR_EN_BIT	0x4
+/* enable timer interrupt */
+#define   TIMER_INTR_EN_BIT	0x8
+/* enable error interrupt */
+#define   ERR_INTR_EN_BIT	0x10
+/* enable fifo not empty interrupt */
+#define   ADC_FNE_INTR_EN_BIT	0x20
 #define ADC_CONVERT_REG	0x3
 #define DAC_LSB_REG(channel)	(0x4 + 2 * ((channel) & 0x1))
 #define DAC_MSB_REG(channel)	(0x5 + 2 * ((channel) & 0x1))
 #define ADC_CLEAR_REG	0x8
 #define DMATC_CLEAR_REG	0xa
 #define TIMER_CLEAR_REG	0xc
-#define COMMAND6_REG	0xe	/*  1200 boards only */
-#define   ADC_COMMON_BIT	0x1	/*  select ground or common-mode reference */
-#define   ADC_UNIP_BIT	0x2	/*  adc unipolar */
-#define   DAC_UNIP_BIT(channel)	(0x4 << ((channel) & 0x1))	/*  dac unipolar */
-#define   ADC_FHF_INTR_EN_BIT	0x20	/*  enable fifo half full interrupt */
-#define   A1_INTR_EN_BIT	0x40	/*  enable interrupt on end of hardware count */
-#define   ADC_SCAN_UP_BIT 0x80	/*  scan up from channel zero instead of down to zero */
+/* 1200 boards only */
+#define COMMAND6_REG	0xe
+/* select ground or common-mode reference */
+#define   ADC_COMMON_BIT	0x1
+/*  adc unipolar */
+#define   ADC_UNIP_BIT	0x2
+/*  dac unipolar */
+#define   DAC_UNIP_BIT(channel)	(0x4 << ((channel) & 0x1))
+/* enable fifo half full interrupt */
+#define   ADC_FHF_INTR_EN_BIT	0x20
+/* enable interrupt on end of hardware count */
+#define   A1_INTR_EN_BIT	0x40
+/* scan up from channel zero instead of down to zero */
+#define   ADC_SCAN_UP_BIT 0x80
 #define COMMAND4_REG	0xf
-#define   INTERVAL_SCAN_EN_BIT	0x1	/*  enables 'interval' scanning */
-#define   EXT_SCAN_EN_BIT	0x2	/*  enables external signal on counter b1 output to trigger scan */
-#define   EXT_CONVERT_OUT_BIT	0x4	/*  chooses direction (output or input) for EXTCONV* line */
-#define   ADC_DIFF_BIT	0x8	/*  chooses differential inputs for adc (in conjunction with board jumper) */
+/* enables 'interval' scanning */
+#define   INTERVAL_SCAN_EN_BIT	0x1
+/* enables external signal on counter b1 output to trigger scan */
+#define   EXT_SCAN_EN_BIT	0x2
+/* chooses direction (output or input) for EXTCONV* line */
+#define   EXT_CONVERT_OUT_BIT	0x4
+/* chooses differential inputs for adc (in conjunction with board jumper) */
+#define   ADC_DIFF_BIT	0x8
 #define   EXT_CONVERT_DISABLE_BIT	0x10
-#define COMMAND5_REG	0x1c	/*  1200 boards only, calibration stuff */
-#define   EEPROM_WRITE_UNPROTECT_BIT	0x4	/*  enable eeprom for write */
-#define   DITHER_EN_BIT	0x8	/*  enable dithering */
-#define   CALDAC_LOAD_BIT	0x10	/*  load calibration dac */
-#define   SCLOCK_BIT	0x20	/*  serial clock - rising edge writes, falling edge reads */
-#define   SDATA_BIT	0x40	/*  serial data bit for writing to eeprom or calibration dacs */
-#define   EEPROM_EN_BIT	0x80	/*  enable eeprom for read/write */
+/* 1200 boards only, calibration stuff */
+#define COMMAND5_REG	0x1c
+/* enable eeprom for write */
+#define   EEPROM_WRITE_UNPROTECT_BIT	0x4
+/* enable dithering */
+#define   DITHER_EN_BIT	0x8
+/* load calibration dac */
+#define   CALDAC_LOAD_BIT	0x10
+/* serial clock - rising edge writes, falling edge reads */
+#define   SCLOCK_BIT	0x20
+/* serial data bit for writing to eeprom or calibration dacs */
+#define   SDATA_BIT	0x40
+/* enable eeprom for read/write */
+#define   EEPROM_EN_BIT	0x80
 #define INTERVAL_COUNT_REG	0x1e
 #define INTERVAL_LOAD_REG	0x1f
 #define   INTERVAL_LOAD_BITS	0x1
 
 /* read-only registers */
 #define STATUS1_REG	0x0
-#define   DATA_AVAIL_BIT	0x1	/*  data is available in fifo */
-#define   OVERRUN_BIT	0x2	/*  overrun has occurred */
-#define   OVERFLOW_BIT	0x4	/*  fifo overflow */
-#define   TIMER_BIT	0x8	/*  timer interrupt has occured */
-#define   DMATC_BIT	0x10	/*  dma terminal count has occured */
-#define   EXT_TRIG_BIT	0x40	/*  external trigger has occured */
-#define STATUS2_REG	0x1d	/*  1200 boards only */
-#define   EEPROM_OUT_BIT	0x1	/*  programmable eeprom serial output */
-#define   A1_TC_BIT	0x2	/*  counter A1 terminal count */
-#define   FNHF_BIT	0x4	/*  fifo not half full */
+/* data is available in fifo */
+#define   DATA_AVAIL_BIT	0x1
+/* overrun has occurred */
+#define   OVERRUN_BIT	0x2
+/* fifo overflow */
+#define   OVERFLOW_BIT	0x4
+/* timer interrupt has occured */
+#define   TIMER_BIT	0x8
+/* dma terminal count has occured */
+#define   DMATC_BIT	0x10
+/* external trigger has occured */
+#define   EXT_TRIG_BIT	0x40
+/* 1200 boards only */
+#define STATUS2_REG	0x1d
+/* programmable eeprom serial output */
+#define   EEPROM_OUT_BIT	0x1
+/* counter A1 terminal count */
+#define   A1_TC_BIT	0x2
+/* fifo not half full */
+#define   FNHF_BIT	0x4
 #define ADC_FIFO_REG	0xa
 
 #define DIO_BASE_REG	0x10
 #define COUNTER_A_BASE_REG	0x14
 #define COUNTER_A_CONTROL_REG	(COUNTER_A_BASE_REG + 0x3)
-#define   INIT_A0_BITS	0x14	/*  check modes put conversion pacer output in harmless state (a0 mode 2) */
-#define   INIT_A1_BITS	0x70	/*  put hardware conversion counter output in harmless state (a1 mode 0) */
+/* check modes put conversion pacer output in harmless state (a0 mode 2) */
+#define   INIT_A0_BITS	0x14
+/* put hardware conversion counter output in harmless state (a1 mode 0) */
+#define   INIT_A1_BITS	0x70
 #define COUNTER_B_BASE_REG	0x18
 
 static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it);
@@ -423,7 +467,7 @@ static const struct labpc_board_struct l
 	 .ai_scan_up = 1,
 	 .memory_mapped_io = 1,
 	 },
-	/*  dummy entry so pci board works when comedi_config is passed driver name */
+/* dummy entry so pci board works when comedi_config is passed driver name */
 	{
 	 .name = DRV_NAME,
 	 .bustype = pci_bustype,
@@ -436,8 +480,10 @@ static const struct labpc_board_struct l
  */
 #define thisboard ((struct labpc_board_struct *)dev->board_ptr)
 
-static const int dma_buffer_size = 0xff00;	/*  size in bytes of dma buffer */
-static const int sample_size = 2;	/*  2 bytes per sample */
+/* size in bytes of dma buffer */
+static const int dma_buffer_size = 0xff00;
+/* 2 bytes per sample */
+static const int sample_size = 2;
 
 #define devpriv ((struct labpc_private *)dev->private)
 
@@ -483,12 +529,10 @@ int labpc_common_attach(struct comedi_de
 
 	printk("comedi%d: ni_labpc: %s, io 0x%lx", dev->minor, thisboard->name,
 	       iobase);
-	if (irq) {
+	if (irq)
 		printk(", irq %u", irq);
-	}
-	if (dma_chan) {
+	if (dma_chan)
 		printk(", dma %u", dma_chan);
-	}
 	printk("\n");
 
 	if (iobase == 0) {
@@ -513,7 +557,7 @@ int labpc_common_attach(struct comedi_de
 		devpriv->read_byte = labpc_inb;
 		devpriv->write_byte = labpc_outb;
 	}
-	/*  initialize board's command registers */
+	/* initialize board's command registers */
 	devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
 	devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
 	devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
@@ -538,12 +582,12 @@ int labpc_common_attach(struct comedi_de
 	}
 	dev->irq = irq;
 
-	/*  grab dma channel */
+	/* grab dma channel */
 	if (dma_chan > 3) {
 		printk(" invalid dma channel %u\n", dma_chan);
 		return -EINVAL;
 	} else if (dma_chan) {
-		/*  allocate dma buffer */
+		/* allocate dma buffer */
 		devpriv->dma_buffer =
 		    kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA);
 		if (devpriv->dma_buffer == NULL) {
@@ -575,7 +619,7 @@ int labpc_common_attach(struct comedi_de
 	    SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ;
 	s->n_chan = 8;
 	s->len_chanlist = 8;
-	s->maxdata = (1 << 12) - 1;	/*  12 bit resolution */
+	s->maxdata = (1 << 12) - 1;	/* 12 bit resolution */
 	s->range_table = thisboard->ai_range_table;
 	s->do_cmd = labpc_ai_cmd;
 	s->do_cmdtest = labpc_ai_cmdtest;
@@ -585,8 +629,11 @@ int labpc_common_attach(struct comedi_de
 	/* analog output */
 	s = dev->subdevices + 1;
 	if (thisboard->has_ao) {
-/* Could provide command support, except it only has a one sample
- * hardware buffer for analog output and no underrun flag. */
+		/*
+		 * Could provide command support, except it only has a
+		 * one sample hardware buffer for analog output and no
+		 * underrun flag.
+		 */
 		s->type = COMEDI_SUBD_AO;
 		s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
 		s->n_chan = NUM_AO_CHAN;
@@ -608,7 +655,8 @@ int labpc_common_attach(struct comedi_de
 
 	/* 8255 dio */
 	s = dev->subdevices + 2;
-	/*  if board uses io memory we have to give a custom callback function to the 8255 driver */
+	/*  if board uses io memory we have to give a custom callback
+	 * function to the 8255 driver */
 	if (thisboard->memory_mapped_io)
 		subdev_8255_init(dev, s, labpc_dio_mem_callback,
 				 (unsigned long)(dev->iobase + DIO_BASE_REG));
@@ -640,14 +688,12 @@ int labpc_common_attach(struct comedi_de
 		s->insn_read = labpc_eeprom_read_insn;
 		s->insn_write = labpc_eeprom_write_insn;
 
-		for (i = 0; i < EEPROM_SIZE; i++) {
+		for (i = 0; i < EEPROM_SIZE; i++)
 			devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i);
-		}
 #ifdef LABPC_DEBUG
 		printk(" eeprom:");
-		for (i = 0; i < EEPROM_SIZE; i++) {
+		for (i = 0; i < EEPROM_SIZE; i++)
 			printk(" %i:0x%x ", i, devpriv->eeprom_data[i]);
-		}
 		printk("\n");
 #endif
 	} else
@@ -669,7 +715,7 @@ static int labpc_attach(struct comedi_de
 	if (alloc_private(dev, sizeof(struct labpc_private)) < 0)
 		return -ENOMEM;
 
-	/*  get base address, irq etc. based on bustype */
+	/* get base address, irq etc. based on bustype */
 	switch (thisboard->bustype) {
 	case isa_bustype:
 		iobase = it->options[0];
@@ -679,9 +725,8 @@ static int labpc_attach(struct comedi_de
 	case pci_bustype:
 #ifdef CONFIG_COMEDI_PCI
 		retval = labpc_find_device(dev, it->options[0], it->options[1]);
-		if (retval < 0) {
+		if (retval < 0)
 			return retval;
-		}
 		retval = mite_setup(devpriv->mite);
 		if (retval < 0)
 			return retval;
@@ -715,7 +760,7 @@ static int labpc_find_device(struct come
 	for (mite = mite_devices; mite; mite = mite->next) {
 		if (mite->used)
 			continue;
-		/*  if bus/slot are specified then make sure we have the right bus/slot */
+/* if bus/slot are specified then make sure we have the right bus/slot */
 		if (bus || slot) {
 			if (bus != mite->pcidev->bus->number
 			    || slot != PCI_SLOT(mite->pcidev->devfn))
@@ -726,7 +771,7 @@ static int labpc_find_device(struct come
 				continue;
 			if (mite_device_id(mite) == labpc_boards[i].device_id) {
 				devpriv->mite = mite;
-				/*  fixup board pointer, in case we were using the dummy "ni_labpc" entry */
+/* fixup board pointer, in case we were using the dummy "ni_labpc" entry */
 				dev->board_ptr = &labpc_boards[i];
 				return 0;
 			}
@@ -994,7 +1039,7 @@ static int labpc_ai_cmdtest(struct comed
 	    cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE)
 		err++;
 
-	/*  can't have external stop and start triggers at once */
+	/* can't have external stop and start triggers at once */
 	if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
 		err++;
 
@@ -1008,9 +1053,9 @@ static int labpc_ai_cmdtest(struct comed
 		err++;
 	}
 
-	if (!cmd->chanlist_len) {
+	if (!cmd->chanlist_len)
 		err++;
-	}
+
 	if (cmd->scan_end_arg != cmd->chanlist_len) {
 		cmd->scan_end_arg = cmd->chanlist_len;
 		err++;
@@ -1022,7 +1067,7 @@ static int labpc_ai_cmdtest(struct comed
 			err++;
 		}
 	}
-	/*  make sure scan timing is not too fast */
+	/* make sure scan timing is not too fast */
 	if (cmd->scan_begin_src == TRIG_TIMER) {
 		if (cmd->convert_src == TRIG_TIMER &&
 		    cmd->scan_begin_arg <
@@ -1038,7 +1083,7 @@ static int labpc_ai_cmdtest(struct comed
 			err++;
 		}
 	}
-	/*  stop source */
+	/* stop source */
 	switch (cmd->stop_src) {
 	case TRIG_COUNT:
 		if (!cmd->stop_arg) {
@@ -1095,7 +1140,7 @@ static int labpc_ai_cmd(struct comedi_de
 	range = CR_RANGE(cmd->chanlist[0]);
 	aref = CR_AREF(cmd->chanlist[0]);
 
-	/*  make sure board is disabled before setting up aquisition */
+	/* make sure board is disabled before setting up aquisition */
 	spin_lock_irqsave(&dev->spinlock, flags);
 	devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT;
 	devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
@@ -1105,9 +1150,9 @@ static int labpc_ai_cmd(struct comedi_de
 	devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
 
 	/*  initialize software conversion count */
-	if (cmd->stop_src == TRIG_COUNT) {
+	if (cmd->stop_src == TRIG_COUNT)
 		devpriv->count = cmd->stop_arg * cmd->chanlist_len;
-	}
+
 	/*  setup hardware conversion counter */
 	if (cmd->stop_src == TRIG_EXT) {
 		/*  load counter a1 with count of 3 (pc+ manual says this is minimum allowed) using mode 0 */
@@ -1176,17 +1221,18 @@ static int labpc_ai_cmd(struct comedi_de
 		channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
 	else
 		channel = CR_CHAN(cmd->chanlist[0]);
-	/*  munge channel bits for differential / scan disabled mode */
+	/* munge channel bits for differential / scan disabled mode */
 	if (labpc_ai_scan_mode(cmd) != MODE_SINGLE_CHAN && aref == AREF_DIFF)
 		channel *= 2;
 	devpriv->command1_bits |= ADC_CHAN_BITS(channel);
 	devpriv->command1_bits |= thisboard->ai_range_code[range];
 	devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
-	/*  manual says to set scan enable bit on second pass */
+	/* manual says to set scan enable bit on second pass */
 	if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP ||
 	    labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_DOWN) {
 		devpriv->command1_bits |= ADC_SCAN_EN_BIT;
-		/* need a brief delay before enabling scan, or scan list will get screwed when you switch
+		/* need a brief delay before enabling scan, or scan
+		 * list will get screwed when you switch
 		 * between scan up to scan down mode - dunno why */
 		udelay(1);
 		devpriv->write_byte(devpriv->command1_bits,
@@ -1338,7 +1384,7 @@ static irqreturn_t labpc_interrupt(int i
 	cmd = &async->cmd;
 	async->events = 0;
 
-	/*  read board status */
+	/* read board status */
 	devpriv->status1_bits = devpriv->read_byte(dev->iobase + STATUS1_REG);
 	if (thisboard->register_layout == labpc_1200_layout)
 		devpriv->status2_bits =
@@ -1352,7 +1398,7 @@ static irqreturn_t labpc_interrupt(int i
 	}
 
 	if (devpriv->status1_bits & OVERRUN_BIT) {
-		/*  clear error interrupt */
+		/* clear error interrupt */
 		devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
 		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
 		comedi_event(dev, s);
@@ -1361,7 +1407,10 @@ static irqreturn_t labpc_interrupt(int i
 	}
 
 	if (devpriv->current_transfer == isa_dma_transfer) {
-		/*  if a dma terminal count of external stop trigger has occurred */
+		/*
+		 * if a dma terminal count of external stop trigger
+		 * has occurred
+		 */
 		if (devpriv->status1_bits & DMATC_BIT ||
 		    (thisboard->register_layout == labpc_1200_layout
 		     && devpriv->status2_bits & A1_TC_BIT)) {
@@ -1479,9 +1528,9 @@ static void labpc_drain_dma(struct comed
 	}
 
 	/* write data to comedi buffer */
-	for (i = 0; i < num_points; i++) {
+	for (i = 0; i < num_points; i++)
 		cfc_write_to_buffer(s, devpriv->dma_buffer[i]);
-	}
+
 	if (async->cmd.stop_src == TRIG_COUNT)
 		devpriv->count -= num_points;
 
@@ -1503,7 +1552,7 @@ static void handle_isa_dma(struct comedi
 	devpriv->write_byte(0x1, dev->iobase + DMATC_CLEAR_REG);
 }
 
-/* makes sure all data aquired by board is transfered to comedi (used
+/* makes sure all data acquired by board is transfered to comedi (used
  * when aquisition is terminated by stop_src == TRIG_EXT). */
 static void labpc_drain_dregs(struct comedi_device *dev)
 {
@@ -1537,41 +1586,41 @@ static int labpc_ai_rinsn(struct comedi_
 	chan = CR_CHAN(insn->chanspec);
 	range = CR_RANGE(insn->chanspec);
 	devpriv->command1_bits |= thisboard->ai_range_code[range];
-	/*  munge channel bits for differential/scan disabled mode */
+	/* munge channel bits for differential/scan disabled mode */
 	if (CR_AREF(insn->chanspec) == AREF_DIFF)
 		chan *= 2;
 	devpriv->command1_bits |= ADC_CHAN_BITS(chan);
 	devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
 
-	/*  setup command6 register for 1200 boards */
+	/* setup command6 register for 1200 boards */
 	if (thisboard->register_layout == labpc_1200_layout) {
 		/*  reference inputs to ground or common? */
 		if (CR_AREF(insn->chanspec) != AREF_GROUND)
 			devpriv->command6_bits |= ADC_COMMON_BIT;
 		else
 			devpriv->command6_bits &= ~ADC_COMMON_BIT;
-		/*  bipolar or unipolar range? */
+		/* bipolar or unipolar range? */
 		if (thisboard->ai_range_is_unipolar[range])
 			devpriv->command6_bits |= ADC_UNIP_BIT;
 		else
 			devpriv->command6_bits &= ~ADC_UNIP_BIT;
-		/*  don't interrupt on fifo half full */
+		/* don't interrupt on fifo half full */
 		devpriv->command6_bits &= ~ADC_FHF_INTR_EN_BIT;
-		/*  don't enable interrupt on counter a1 terminal count? */
+		/* don't enable interrupt on counter a1 terminal count? */
 		devpriv->command6_bits &= ~A1_INTR_EN_BIT;
-		/*  write to register */
+		/* write to register */
 		devpriv->write_byte(devpriv->command6_bits,
 				    dev->iobase + COMMAND6_REG);
 	}
-	/*  setup command4 register */
+	/* setup command4 register */
 	devpriv->command4_bits = 0;
 	devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT;
-	/*  single-ended/differential */
+	/* single-ended/differential */
 	if (CR_AREF(insn->chanspec) == AREF_DIFF)
 		devpriv->command4_bits |= ADC_DIFF_BIT;
 	devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
 
-	/*  initialize pacer counter output to make sure it doesn't cause any problems */
+	/* initialize pacer counter output to make sure it doesn't cause any problems */
 	devpriv->write_byte(INIT_A0_BITS, dev->iobase + COUNTER_A_CONTROL_REG);
 
 	labpc_clear_adc_fifo(dev);
@@ -1608,7 +1657,7 @@ static int labpc_ao_winsn(struct comedi_
 
 	channel = CR_CHAN(insn->chanspec);
 
-	/*  turn off pacing of analog output channel */
+	/* turn off pacing of analog output channel */
 	/* note: hardware bug in daqcard-1200 means pacing cannot
 	 * be independently enabled/disabled for its the two channels */
 	spin_lock_irqsave(&dev->spinlock, flags);
@@ -1616,7 +1665,7 @@ static int labpc_ao_winsn(struct comedi_
 	devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
 	spin_unlock_irqrestore(&dev->spinlock, flags);
 
-	/*  set range */
+	/* set range */
 	if (thisboard->register_layout == labpc_1200_layout) {
 		range = CR_RANGE(insn->chanspec);
 		if (range & AO_RANGE_IS_UNIPOLAR)
@@ -1627,13 +1676,13 @@ static int labpc_ao_winsn(struct comedi_
 		devpriv->write_byte(devpriv->command6_bits,
 				    dev->iobase + COMMAND6_REG);
 	}
-	/*  send data */
+	/* send data */
 	lsb = data[0] & 0xff;
 	msb = (data[0] >> 8) & 0xff;
 	devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(channel));
 	devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(channel));
 
-	/*  remember value for readback */
+	/* remember value for readback */
 	devpriv->ao_value[channel] = data[0];
 
 	return 1;
@@ -1705,14 +1754,14 @@ static unsigned int labpc_suggest_transf
 
 	if (cmd.convert_src == TRIG_TIMER)
 		freq = 1000000000 / cmd.convert_arg;
-	/*  return some default value */
+	/* return some default value */
 	else
 		freq = 0xffffffff;
 
-	/*  make buffer fill in no more than 1/3 second */
+	/* make buffer fill in no more than 1/3 second */
 	size = (freq / 3) * sample_size;
 
-	/*  set a minimum and maximum size allowed */
+	/* set a minimum and maximum size allowed */
 	if (size > dma_buffer_size)
 		size = dma_buffer_size - dma_buffer_size % sample_size;
 	else if (size < sample_size)
@@ -1724,13 +1773,21 @@ static unsigned int labpc_suggest_transf
 /* figures out what counter values to use based on command */
 static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
 {
-	const int max_counter_value = 0x10000;	/*  max value for 16 bit counter in mode 2 */
-	const int min_counter_value = 2;	/*  min value for 16 bit counter in mode 2 */
+	/* max value for 16 bit counter in mode 2 */
+	const int max_counter_value = 0x10000;
+	/* min value for 16 bit counter in mode 2 */
+	const int min_counter_value = 2;
 	unsigned int base_period;
 
-	/*  if both convert and scan triggers are TRIG_TIMER, then they both rely on counter b0 */
+	/*
+	 * if both convert and scan triggers are TRIG_TIMER, then they
+	 * both rely on counter b0
+	 */
 	if (labpc_ai_convert_period(cmd) && labpc_ai_scan_period(cmd)) {
-		/*  pick the lowest b0 divisor value we can (for maximum input clock speed on convert and scan counters) */
+		/*
+		 * pick the lowest b0 divisor value we can (for maximum input
+		 * clock speed on convert and scan counters)
+		 */
 		devpriv->divisor_b0 = (labpc_ai_scan_period(cmd) - 1) /
 		    (LABPC_TIMER_BASE * max_counter_value) + 1;
 		if (devpriv->divisor_b0 < min_counter_value)
@@ -1780,7 +1837,10 @@ static void labpc_adc_timing(struct come
 					    base_period * devpriv->divisor_a0);
 		labpc_set_ai_scan_period(cmd,
 					 base_period * devpriv->divisor_b1);
-		/*  if only one TRIG_TIMER is used, we can employ the generic cascaded timing functions */
+		/*
+		 * if only one TRIG_TIMER is used, we can employ the generic
+		 * cascaded timing functions
+		 */
 	} else if (labpc_ai_scan_period(cmd)) {
 		unsigned int scan_period;
 
@@ -1864,9 +1924,8 @@ static unsigned int labpc_serial_in(stru
 		udelay(1);
 		devpriv->status2_bits =
 		    devpriv->read_byte(dev->iobase + STATUS2_REG);
-		if (devpriv->status2_bits & EEPROM_OUT_BIT) {
+		if (devpriv->status2_bits & EEPROM_OUT_BIT)
 			value |= 1 << (value_width - i);
-		}
 	}
 
 	return value;
@@ -1876,8 +1935,10 @@ static unsigned int labpc_eeprom_read(st
 				      unsigned int address)
 {
 	unsigned int value;
-	const int read_instruction = 0x3;	/*  bits to tell eeprom to expect a read */
-	const int write_length = 8;	/*  8 bit write lengths to eeprom */
+	/*  bits to tell eeprom to expect a read */
+	const int read_instruction = 0x3;
+	/*  8 bit write lengths to eeprom */
+	const int write_length = 8;
 
 	/*  enable read/write to eeprom */
 	devpriv->command5_bits &= ~EEPROM_EN_BIT;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_labpc_cs.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_labpc_cs.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_labpc_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_labpc_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,6 +64,7 @@ NI manuals:
 #include "../comedidev.h"
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "8253.h"
 #include "8255.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_mio_common.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_mio_common.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_mio_common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_mio_common.c	2010-05-16 17:17:36.000000000 -0400
@@ -3795,7 +3795,7 @@ static int ni_cdo_inttrig(struct comedi_
 #endif
 	int retval = 0;
 	unsigned i;
-	const unsigned timeout = 100;
+	const unsigned timeout = 1000;
 
 	s->async->inttrig = NULL;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_pcidio.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_pcidio.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ni_pcidio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ni_pcidio.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,8 +1,8 @@
 /*
     comedi/drivers/ni_pcidio.c
     driver for National Instruments PCI-DIO-96/PCI-6508
-               National Instruments PCI-DIO-32HS
-               National Instruments PCI-6503
+		National Instruments PCI-DIO-32HS
+		National Instruments PCI-6503
 
     COMEDI - Linux Control and Measurement Device Interface
     Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
@@ -518,7 +518,8 @@ static irqreturn_t nidio_interrupt(int i
 	ni_pcidio_print_status(status);
 
 	/* printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf); */
-	/* printk("buf[4096]=%08x\n",*(unsigned int *)(async->prealloc_buf+4096)); */
+	/* printk("buf[4096]=%08x\n",
+	       *(unsigned int *)(async->prealloc_buf+4096)); */
 
 	spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags);
 	if (devpriv->di_mite_chan)
@@ -526,7 +527,9 @@ static irqreturn_t nidio_interrupt(int i
 #ifdef MITE_DEBUG
 	mite_print_chsr(m_status);
 #endif
-	/* printk("mite_bytes_transferred: %d\n",mite_bytes_transferred(mite,DI_DMA_CHAN)); */
+	/* printk("mite_bytes_transferred: %d\n",
+	       mite_bytes_transferred(mite,DI_DMA_CHAN)); */
+
 	/* mite_dump_regs(mite); */
 	if (m_status & CHSR_INT) {
 		if (m_status & CHSR_LINKC) {
@@ -565,7 +568,8 @@ static irqreturn_t nidio_interrupt(int i
 					DPRINTK("too much work in interrupt\n");
 					writeb(0x00,
 					       devpriv->mite->daq_io_addr +
-					       Master_DMA_And_Interrupt_Control);
+					       Master_DMA_And_Interrupt_Control
+					      );
 					goto out;
 				}
 				AuxData =
@@ -579,8 +583,10 @@ static irqreturn_t nidio_interrupt(int i
 				flags = readb(devpriv->mite->daq_io_addr +
 					      Group_1_Flags);
 			}
-			/* DPRINTK("buf_int_count: %d\n",async->buf_int_count); */
-			/* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",IntEn,flags,status); */
+			/* DPRINTK("buf_int_count: %d\n",
+				async->buf_int_count); */
+			/* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",
+				IntEn,flags,status); */
 			/* ni_pcidio_print_flags(flags); */
 			/* ni_pcidio_print_status(status); */
 			async->events |= COMEDI_CB_BLOCK;
@@ -627,8 +633,8 @@ static irqreturn_t nidio_interrupt(int i
 		flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
 		status = readb(devpriv->mite->daq_io_addr +
 			       Interrupt_And_Window_Status);
-		/* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,status=0x%02x\n", */
-		/* IntEn,flags,status); */
+		/* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,"
+			"status=0x%02x\n", IntEn, flags, status); */
 		/* ni_pcidio_print_flags(flags); */
 		/* ni_pcidio_print_status(status); */
 	}
@@ -655,11 +661,10 @@ static void ni_pcidio_print_flags(unsign
 {
 	int i;
 
-	printk("group_1_flags:");
+	printk(KERN_INFO "group_1_flags:");
 	for (i = 7; i >= 0; i--) {
-		if (flags & (1 << i)) {
+		if (flags & (1 << i))
 			printk(" %s", flags_strings[i]);
-		}
 	}
 	printk("\n");
 }
@@ -673,11 +678,10 @@ static void ni_pcidio_print_status(unsig
 {
 	int i;
 
-	printk("group_status:");
+	printk(KERN_INFO "group_status:");
 	for (i = 7; i >= 0; i--) {
-		if (flags & (1 << i)) {
+		if (flags & (1 << i))
 			printk(" %s", status_strings[i]);
-		}
 	}
 	printk("\n");
 }
@@ -793,7 +797,8 @@ static int ni_pcidio_cmdtest(struct come
 	if (err)
 		return 1;
 
-	/* step 2: make sure trigger sources are unique and mutually compatible */
+	/* step 2: make sure trigger sources are unique and mutually
+	compatible */
 
 	/* note that mutual compatibility is not an issue here */
 	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT)
@@ -974,7 +979,8 @@ static int ni_pcidio_cmd(struct comedi_d
 
 	/* clear and enable interrupts */
 	writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
-	/* writeb(ClearExpired,devpriv->mite->daq_io_addr+Group_1_Second_Clear); */
+	/* writeb(ClearExpired,
+	       devpriv->mite->daq_io_addr+Group_1_Second_Clear); */
 
 	writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
 	writeb(0x03,
@@ -1052,7 +1058,7 @@ static int ni_pcidio_change(struct comed
 }
 
 static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index,
-			      u8 * data, int data_len)
+			      u8 *data, int data_len)
 {
 	static const int timeout = 1000;
 	int i, j;
@@ -1066,9 +1072,8 @@ static int pci_6534_load_fpga(struct com
 		udelay(1);
 	}
 	if (i == timeout) {
-		printk
-		    ("ni_pcidio: failed to load fpga %i, waiting for status 0x2\n",
-		     fpga_index);
+		printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, "
+		       "waiting for status 0x2\n", fpga_index);
 		return -EIO;
 	}
 	writew(0x80 | fpga_index,
@@ -1079,9 +1084,8 @@ static int pci_6534_load_fpga(struct com
 		udelay(1);
 	}
 	if (i == timeout) {
-		printk
-		    ("ni_pcidio: failed to load fpga %i, waiting for status 0x3\n",
-		     fpga_index);
+		printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, "
+		       "waiting for status 0x3\n", fpga_index);
 		return -EIO;
 	}
 	for (j = 0; j + 1 < data_len;) {
@@ -1174,9 +1178,10 @@ static int nidio_attach(struct comedi_de
 	int n_subdevices;
 	unsigned int irq;
 
-	printk("comedi%d: nidio:", dev->minor);
+	printk(KERN_INFO "comedi%d: nidio:", dev->minor);
 
-	if ((ret = alloc_private(dev, sizeof(struct nidio96_private))) < 0)
+	ret = alloc_private(dev, sizeof(struct nidio96_private));
+	if (ret < 0)
 		return ret;
 	spin_lock_init(&devpriv->mite_channel_lock);
 
@@ -1186,7 +1191,7 @@ static int nidio_attach(struct comedi_de
 
 	ret = mite_setup(devpriv->mite);
 	if (ret < 0) {
-		printk("error setting up mite\n");
+		printk(KERN_WARNING "error setting up mite\n");
 		return ret;
 	}
 	comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
@@ -1196,18 +1201,19 @@ static int nidio_attach(struct comedi_de
 
 	dev->board_name = this_board->name;
 	irq = mite_irq(devpriv->mite);
-	printk(" %s", dev->board_name);
+	printk(KERN_INFO " %s", dev->board_name);
 	if (this_board->uses_firmware) {
 		ret = pci_6534_upload_firmware(dev, it->options);
 		if (ret < 0)
 			return ret;
 	}
-	if (!this_board->is_diodaq) {
+	if (!this_board->is_diodaq)
 		n_subdevices = this_board->n_8255;
-	} else {
+	else
 		n_subdevices = 1;
-	}
-	if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+
+	ret = alloc_subdevices(dev, n_subdevices);
+	if (ret < 0)
 		return ret;
 
 	if (!this_board->is_diodaq) {
@@ -1220,7 +1226,7 @@ static int nidio_attach(struct comedi_de
 		}
 	} else {
 
-		printk(" rev=%d",
+		printk(KERN_INFO " rev=%d",
 		       readb(devpriv->mite->daq_io_addr + Chip_Version));
 
 		s = dev->subdevices + 0;
@@ -1253,9 +1259,9 @@ static int nidio_attach(struct comedi_de
 
 		ret = request_irq(irq, nidio_interrupt, IRQF_SHARED,
 				  "ni_pcidio", dev);
-		if (ret < 0) {
-			printk(" irq not available");
-		}
+		if (ret < 0)
+			printk(KERN_WARNING " irq not available");
+
 		dev->irq = irq;
 	}
 
@@ -1269,9 +1275,8 @@ static int nidio_detach(struct comedi_de
 	int i;
 
 	if (this_board && !this_board->is_diodaq) {
-		for (i = 0; i < this_board->n_8255; i++) {
+		for (i = 0; i < this_board->n_8255; i++)
 			subdev_8255_cleanup(dev, dev->subdevices + i);
-		}
 	}
 
 	if (dev->irq)
@@ -1310,7 +1315,7 @@ static int nidio_find_device(struct come
 			}
 		}
 	}
-	printk("no device found\n");
+	printk(KERN_WARNING "no device found\n");
 	mite_list_devices();
 	return -EIO;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcl711.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcl711.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcl711.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcl711.c	2010-05-16 17:17:36.000000000 -0400
@@ -207,11 +207,10 @@ static irqreturn_t pcl711_interrupt(int
 
 	/* FIXME! Nothing else sets ntrig! */
 	if (!(--devpriv->ntrig)) {
-		if (this_board->is_8112) {
+		if (this_board->is_8112)
 			outb(1, dev->iobase + PCL711_MODE);
-		} else {
+		else
 			outb(0, dev->iobase + PCL711_MODE);
-		}
 
 		s->async->events |= COMEDI_CB_EOA;
 	}
@@ -232,15 +231,15 @@ static void pcl711_set_changain(struct c
 		/*
 		 *  Set the correct channel.  The two channel banks are switched
 		 *  using the mask value.
-		 *  NB: To use differential channels, you should use mask = 0x30,
-		 *  but I haven't written the support for this yet. /JJ
+		 *  NB: To use differential channels, you should use
+		 *  mask = 0x30, but I haven't written the support for this
+		 *  yet. /JJ
 		 */
 
-		if (chan_register >= 8) {
+		if (chan_register >= 8)
 			chan_register = 0x20 | (chan_register & 0x7);
-		} else {
+		else
 			chan_register |= 0x10;
-		}
 	} else {
 		outb(chan_register, dev->iobase + PCL711_MUX);
 	}
@@ -256,15 +255,13 @@ static int pcl711_ai_insn(struct comedi_
 
 	for (n = 0; n < insn->n; n++) {
 		/*
-		 *  Write the correct mode (software polling) and start polling by writing
-		 *  to the trigger register
+		 *  Write the correct mode (software polling) and start polling
+		 *  by writing to the trigger register
 		 */
 		outb(1, dev->iobase + PCL711_MODE);
 
-		if (this_board->is_8112) {
-		} else {
+		if (!this_board->is_8112)
 			outb(0, dev->iobase + PCL711_SOFTTRIG);
-		}
 
 		i = PCL711_TIMEOUT;
 		while (--i) {
@@ -462,9 +459,8 @@ static int pcl711_ao_insn_read(struct co
 	int n;
 	int chan = CR_CHAN(insn->chanspec);
 
-	for (n = 0; n < insn->n; n++) {
+	for (n = 0; n < insn->n; n++)
 		data[n] = devpriv->ao_readback[chan];
-	}
 
 	return n;
 
@@ -619,9 +615,8 @@ static int pcl711_attach(struct comedi_d
 	   this is the "base value" for the mode register, which is
 	   used for the irq on the PCL711
 	 */
-	if (this_board->is_pcl711b) {
+	if (this_board->is_pcl711b)
 		devpriv->mode = (dev->irq << 4);
-	}
 
 	/* clear DAC */
 	outb(0, dev->iobase + PCL711_DA0_LO);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcl724.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcl724.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcl724.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcl724.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,7 @@
      [0] - IO Base
      [1] - IRQ (0=disable IRQ) IRQ isn't supported at this time!
      [2] -number of DIO:
-              0, 144: 144 DIO configuration
+	      0, 144: 144 DIO configuration
 	      1,  96:  96 DIO configuration
 */
 /*
@@ -137,8 +137,8 @@ static int pcl724_attach(struct comedi_d
 	iorange = this_board->io_range;
 	if ((this_board->can_have96) && ((it->options[1] == 1)
 					 || (it->options[1] == 96)))
-		iorange = PCL722_96_SIZE;	/*  PCL-724 in 96 DIO configuration */
-	printk("comedi%d: pcl724: board=%s, 0x%03lx ", dev->minor,
+		iorange = PCL722_96_SIZE; /* PCL-724 in 96 DIO configuration */
+	printk(KERN_INFO "comedi%d: pcl724: board=%s, 0x%03lx ", dev->minor,
 	       this_board->name, iobase);
 	if (!request_region(iobase, iorange, "pcl724")) {
 		printk("I/O port conflict\n");
@@ -155,16 +155,16 @@ static int pcl724_attach(struct comedi_d
 		irq = it->options[1];
 		if (irq) {	/* we want to use IRQ */
 			if (((1 << irq) & this_board->IRQbits) == 0) {
-				printk
-				    (", IRQ %u is out of allowed range, DISABLING IT",
-				     irq);
+				printk(KERN_WARNING
+				       ", IRQ %u is out of allowed range, "
+				       "DISABLING IT", irq);
 				irq = 0;	/* Bad IRQ */
 			} else {
 				if (request_irq
 				    (irq, interrupt_pcl724, 0, "pcl724", dev)) {
-					printk
-					    (", unable to allocate IRQ %u, DISABLING IT",
-					     irq);
+					printk(KERN_WARNING
+					       ", unable to allocate IRQ %u, "
+					       "DISABLING IT", irq);
 					irq = 0;	/* Can't use IRQ */
 				} else {
 					printk(", irq=%u", irq);
@@ -207,16 +207,14 @@ static int pcl724_detach(struct comedi_d
 {
 	int i;
 
-/* printk("comedi%d: pcl724: remove\n",dev->minor); */
+	/* printk("comedi%d: pcl724: remove\n",dev->minor); */
 
-	for (i = 0; i < dev->n_subdevices; i++) {
+	for (i = 0; i < dev->n_subdevices; i++)
 		subdev_8255_cleanup(dev, dev->subdevices + i);
-	}
 
 #ifdef PCL724_IRQ
-	if (dev->irq) {
+	if (dev->irq)
 		free_irq(dev->irq, dev);
-	}
 #endif
 
 	release_region(dev->iobase, this_board->io_range);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcl725.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcl725.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcl725.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcl725.c	2010-05-16 17:17:36.000000000 -0400
@@ -66,7 +66,7 @@ static int pcl725_attach(struct comedi_d
 	unsigned long iobase;
 
 	iobase = it->options[0];
-	printk("comedi%d: pcl725: 0x%04lx ", dev->minor, iobase);
+	printk(KERN_INFO "comedi%d: pcl725: 0x%04lx ", dev->minor, iobase);
 	if (!request_region(iobase, PCL725_SIZE, "pcl725")) {
 		printk("I/O port conflict\n");
 		return -EIO;
@@ -96,14 +96,14 @@ static int pcl725_attach(struct comedi_d
 	s->insn_bits = pcl725_di_insn;
 	s->range_table = &range_digital;
 
-	printk("\n");
+	printk(KERN_INFO "\n");
 
 	return 0;
 }
 
 static int pcl725_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: pcl725: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: pcl725: remove\n", dev->minor);
 
 	if (dev->iobase)
 		release_region(dev->iobase, PCL725_SIZE);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcl730.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcl730.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcl730.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcl730.c	2010-05-16 17:17:36.000000000 -0400
@@ -99,7 +99,7 @@ static int pcl730_attach(struct comedi_d
 
 	iobase = it->options[0];
 	iorange = this_board->io_range;
-	printk("comedi%d: pcl730: board=%s 0x%04lx ", dev->minor,
+	printk(KERN_INFO "comedi%d: pcl730: board=%s 0x%04lx ", dev->minor,
 	       this_board->name, iobase);
 	if (!request_region(iobase, iorange, "pcl730")) {
 		printk("I/O port conflict\n");
@@ -152,14 +152,14 @@ static int pcl730_attach(struct comedi_d
 	s->range_table = &range_digital;
 	s->private = (void *)PCL730_DIO_LO;
 
-	printk("\n");
+	printk(KERN_INFO "\n");
 
 	return 0;
 }
 
 static int pcl730_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: pcl730: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: pcl730: remove\n", dev->minor);
 
 	if (dev->iobase)
 		release_region(dev->iobase, this_board->io_range);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcl812.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcl812.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcl812.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcl812.c	2010-05-16 17:17:36.000000000 -0400
@@ -108,6 +108,7 @@ Options for ACL-8113, ISO-813:
 */
 
 #include <linux/interrupt.h>
+#include <linux/gfp.h>
 #include "../comedidev.h"
 
 #include <linux/delay.h>
@@ -955,6 +956,7 @@ static irqreturn_t interrupt_pcl812_ai_i
 	unsigned int mask, timeout;
 	struct comedi_device *dev = d;
 	struct comedi_subdevice *s = dev->subdevices + 0;
+	unsigned int next_chan;
 
 	s->async->events = 0;
 
@@ -993,9 +995,18 @@ static irqreturn_t interrupt_pcl812_ai_i
 		       ((inb(dev->iobase + PCL812_AD_HI) << 8) |
 			inb(dev->iobase + PCL812_AD_LO)) & mask);
 
+	/* Set up next channel. Added by abbotti 2010-01-20, but untested. */
+	next_chan = s->async->cur_chan + 1;
+	if (next_chan >= devpriv->ai_n_chan)
+		next_chan = 0;
+	if (devpriv->ai_chanlist[s->async->cur_chan] !=
+			devpriv->ai_chanlist[next_chan])
+		setup_range_channel(dev, s, devpriv->ai_chanlist[next_chan], 0);
+
 	outb(0, dev->iobase + PCL812_CLRINT);	/* clear INT request */
 
-	if (s->async->cur_chan == 0) {	/* one scan done */
+	s->async->cur_chan = next_chan;
+	if (next_chan == 0) {	/* one scan done */
 		devpriv->ai_act_scan++;
 		if (!(devpriv->ai_neverending))
 			if (devpriv->ai_act_scan >= devpriv->ai_scans) {	/* all data sampled */
@@ -1021,7 +1032,9 @@ static void transfer_from_dma_buf(struct
 	for (i = len; i; i--) {
 		comedi_buf_put(s->async, ptr[bufptr++]);	/*  get one sample */
 
-		if (s->async->cur_chan == 0) {
+		s->async->cur_chan++;
+		if (s->async->cur_chan >= devpriv->ai_n_chan) {
+			s->async->cur_chan = 0;
 			devpriv->ai_act_scan++;
 			if (!devpriv->ai_neverending)
 				if (devpriv->ai_act_scan >= devpriv->ai_scans) {	/* all data sampled */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcl816.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcl816.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcl816.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcl816.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@ Configuration Options:
 
 #include <linux/ioport.h>
 #include <linux/mc146818rtc.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <asm/dma.h>
 
@@ -202,6 +203,7 @@ struct pcl816_private {
 	unsigned int ai_act_chanlist[16];	/*  MUX setting for actual AI operations */
 	unsigned int ai_act_chanlist_len;	/*  how long is actual MUX list */
 	unsigned int ai_act_chanlist_pos;	/*  actual position in MUX list */
+	unsigned int ai_n_chan;		/*  how many channels per scan */
 	unsigned int ai_poll_ptr;	/*  how many sampes transfer poll */
 	struct comedi_subdevice *sub_ai;	/*  ptr to AI subdevice */
 #ifdef unused
@@ -213,9 +215,12 @@ struct pcl816_private {
 /*
 ==============================================================================
 */
-static int check_and_setup_channel_list(struct comedi_device *dev,
-					struct comedi_subdevice *s,
-					unsigned int *chanlist, int chanlen);
+static int check_channel_list(struct comedi_device *dev,
+			      struct comedi_subdevice *s,
+			      unsigned int *chanlist, unsigned int chanlen);
+static void setup_channel_list(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       unsigned int *chanlist, unsigned int seglen);
 static int pcl816_ai_cancel(struct comedi_device *dev,
 			    struct comedi_subdevice *s);
 static void start_pacer(struct comedi_device *dev, int mode,
@@ -320,7 +325,9 @@ static irqreturn_t interrupt_pcl816_ai_m
 	if (++devpriv->ai_act_chanlist_pos >= devpriv->ai_act_chanlist_len)
 		devpriv->ai_act_chanlist_pos = 0;
 
-	if (s->async->cur_chan == 0) {
+	s->async->cur_chan++;
+	if (s->async->cur_chan >= devpriv->ai_n_chan) {
+		s->async->cur_chan = 0;
 		devpriv->ai_act_scan++;
 	}
 
@@ -353,6 +360,11 @@ static void transfer_from_dma_buf(struct
 		if (++devpriv->ai_act_chanlist_pos >=
 		    devpriv->ai_act_chanlist_len) {
 			devpriv->ai_act_chanlist_pos = 0;
+		}
+
+		s->async->cur_chan++;
+		if (s->async->cur_chan >= devpriv->ai_n_chan) {
+			s->async->cur_chan = 0;
 			devpriv->ai_act_scan++;
 		}
 
@@ -558,14 +570,6 @@ static int pcl816_ai_cmdtest(struct come
 		}
 	}
 
-	if (!cmd->chanlist_len) {
-		cmd->chanlist_len = 1;
-		err++;
-	}
-	if (cmd->chanlist_len > this_board->n_aichan) {
-		cmd->chanlist_len = this_board->n_aichan;
-		err++;
-	}
 	if (cmd->scan_end_arg != cmd->chanlist_len) {
 		cmd->scan_end_arg = cmd->chanlist_len;
 		err++;
@@ -603,6 +607,14 @@ static int pcl816_ai_cmdtest(struct come
 		return 4;
 	}
 
+	/* step 5: complain about special chanlist considerations */
+
+	if (cmd->chanlist) {
+		if (!check_channel_list(dev, s, cmd->chanlist,
+					cmd->chanlist_len))
+			return 5;	/*  incorrect channels list */
+	}
+
 	return 0;
 }
 
@@ -610,6 +622,7 @@ static int pcl816_ai_cmd(struct comedi_d
 {
 	unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq;
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int seglen;
 
 	if (cmd->start_src != TRIG_NOW)
 		return -EINVAL;
@@ -642,11 +655,13 @@ static int pcl816_ai_cmd(struct comedi_d
 
 	start_pacer(dev, -1, 0, 0);	/*  stop pacer */
 
-	if (!check_and_setup_channel_list(dev, s, cmd->chanlist,
-					  cmd->chanlist_len))
+	seglen = check_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len);
+	if (seglen < 1)
 		return -EINVAL;
+	setup_channel_list(dev, s, cmd->chanlist, seglen);
 	udelay(1);
 
+	devpriv->ai_n_chan = cmd->chanlist_len;
 	devpriv->ai_act_scan = 0;
 	s->async->cur_chan = 0;
 	devpriv->irq_blocked = 1;
@@ -871,12 +886,12 @@ start_pacer(struct comedi_device *dev, i
 /*
 ==============================================================================
  Check if channel list from user is builded correctly
- If it's ok, then program scan/gain logic
+ If it's ok, then return non-zero length of repeated segment of channel list
 */
 static int
-check_and_setup_channel_list(struct comedi_device *dev,
-			     struct comedi_subdevice *s, unsigned int *chanlist,
-			     int chanlen)
+check_channel_list(struct comedi_device *dev,
+		   struct comedi_subdevice *s, unsigned int *chanlist,
+		   unsigned int chanlen)
 {
 	unsigned int chansegment[16];
 	unsigned int i, nowmustbechan, seglen, segpos;
@@ -930,6 +945,20 @@ check_and_setup_channel_list(struct come
 		seglen = 1;
 	}
 
+	return seglen;	/*  we can serve this with MUX logic */
+}
+
+/*
+==============================================================================
+ Program scan/gain logic with channel list.
+*/
+static void
+setup_channel_list(struct comedi_device *dev,
+		   struct comedi_subdevice *s, unsigned int *chanlist,
+		   unsigned int seglen)
+{
+	unsigned int i;
+
 	devpriv->ai_act_chanlist_len = seglen;
 	devpriv->ai_act_chanlist_pos = 0;
 
@@ -942,8 +971,6 @@ check_and_setup_channel_list(struct come
 	udelay(1);
 
 	outb(devpriv->ai_act_chanlist[0] | (devpriv->ai_act_chanlist[seglen - 1] << 4), dev->iobase + PCL816_MUX);	/* select channel interval to scan */
-
-	return 1;		/*  we can serve this with MUX logic */
 }
 
 #ifdef unused
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcl818.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcl818.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcl818.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcl818.c	2010-05-16 17:17:36.000000000 -0400
@@ -102,6 +102,7 @@ A word or two about DMA. Driver support
 
 #include <linux/ioport.h>
 #include <linux/mc146818rtc.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <asm/dma.h>
 
@@ -557,8 +558,14 @@ conv_finish:
 		comedi_event(dev, s);
 		return IRQ_HANDLED;
 	}
-	if (s->async->cur_chan == 0) {
+	devpriv->act_chanlist_pos++;
+	if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
+		devpriv->act_chanlist_pos = 0;
+	}
+	s->async->cur_chan++;
+	if (s->async->cur_chan >= devpriv->ai_n_chan) {
 		/*  printk("E"); */
+		s->async->cur_chan = 0;
 		devpriv->ai_act_scan--;
 	}
 
@@ -627,9 +634,13 @@ static irqreturn_t interrupt_pcl818_ai_m
 
 		devpriv->act_chanlist_pos++;
 		if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
-			devpriv->ai_act_scan--;
 			devpriv->act_chanlist_pos = 0;
 		}
+		s->async->cur_chan++;
+		if (s->async->cur_chan >= devpriv->ai_n_chan) {
+			s->async->cur_chan = 0;
+			devpriv->ai_act_scan--;
+		}
 
 		if (!devpriv->neverending_ai)
 			if (devpriv->ai_act_scan == 0) {	/* all data sampled */
@@ -717,7 +728,14 @@ static irqreturn_t interrupt_pcl818_ai_m
 			comedi_buf_put(s->async, dmabuf[bufptr++] >> 4);	/*  get one sample */
 			bufptr &= (devpriv->dmasamplsize - 1);
 
-			if (s->async->cur_chan == 0) {
+			devpriv->act_chanlist_pos++;
+			if (devpriv->act_chanlist_pos >=
+					devpriv->act_chanlist_len) {
+				devpriv->act_chanlist_pos = 0;
+			}
+			s->async->cur_chan++;
+			if (s->async->cur_chan >= devpriv->ai_n_chan) {
+				s->async->cur_chan = 0;
 				devpriv->ai_act_scan--;
 			}
 
@@ -796,7 +814,13 @@ static irqreturn_t interrupt_pcl818_ai_m
 
 		comedi_buf_put(s->async, (lo >> 4) | (inb(dev->iobase + PCL818_FI_DATAHI) << 4));	/*  get one sample */
 
-		if (s->async->cur_chan == 0) {
+		devpriv->act_chanlist_pos++;
+		if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
+			devpriv->act_chanlist_pos = 0;
+		}
+		s->async->cur_chan++;
+		if (s->async->cur_chan >= devpriv->ai_n_chan) {
+			s->async->cur_chan = 0;
 			devpriv->ai_act_scan--;
 		}
 
@@ -1369,14 +1393,6 @@ static int ai_cmdtest(struct comedi_devi
 		}
 	}
 
-	if (!cmd->chanlist_len) {
-		cmd->chanlist_len = 1;
-		err++;
-	}
-	if (cmd->chanlist_len > s->n_chan) {
-		cmd->chanlist_len = s->n_chan;
-		err++;
-	}
 	if (cmd->scan_end_arg != cmd->chanlist_len) {
 		cmd->scan_end_arg = cmd->chanlist_len;
 		err++;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcm3724.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcm3724.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcm3724.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcm3724.c	2010-05-16 17:17:36.000000000 -0400
@@ -121,25 +121,22 @@ static int compute_buffer(int config, in
 {
 	/* 1 in io_bits indicates output */
 	if (s->io_bits & 0x0000ff) {
-		if (devno == 0) {
+		if (devno == 0)
 			config |= BUF_A0;
-		} else {
+		else
 			config |= BUF_A1;
-		}
 	}
 	if (s->io_bits & 0x00ff00) {
-		if (devno == 0) {
+		if (devno == 0)
 			config |= BUF_B0;
-		} else {
+		else
 			config |= BUF_B1;
-		}
 	}
 	if (s->io_bits & 0xff0000) {
-		if (devno == 0) {
+		if (devno == 0)
 			config |= BUF_C0;
-		} else {
+		else
 			config |= BUF_C1;
-		}
 	}
 	return config;
 }
@@ -155,26 +152,27 @@ static void do_3724_config(struct comedi
 	buffer_config = 0;
 
 	/* 1 in io_bits indicates output, 1 in config indicates input */
-	if (!(s->io_bits & 0x0000ff)) {
+	if (!(s->io_bits & 0x0000ff))
 		config |= CR_A_IO;
-	}
-	if (!(s->io_bits & 0x00ff00)) {
+
+	if (!(s->io_bits & 0x00ff00))
 		config |= CR_B_IO;
-	}
-	if (!(s->io_bits & 0xff0000)) {
+
+	if (!(s->io_bits & 0xff0000))
 		config |= CR_C_IO;
-	}
 
 	buffer_config = compute_buffer(0, 0, dev->subdevices);
 	buffer_config = compute_buffer(buffer_config, 1, (dev->subdevices) + 1);
 
-	if (s == dev->subdevices) {
+	if (s == dev->subdevices)
 		port_8255_cfg = dev->iobase + _8255_CR;
-	} else {
+	else
 		port_8255_cfg = dev->iobase + SIZE_8255 + _8255_CR;
-	}
+
 	outb(buffer_config, dev->iobase + 8);	/* update buffer register */
-	/* printk("pcm3724 buffer_config (%lx) %d, %x\n", dev->iobase + _8255_CR, chanspec, buffer_config); */
+	/* printk("pcm3724 buffer_config (%lx) %d, %x\n",
+	       dev->iobase + _8255_CR, chanspec, buffer_config); */
+
 	outb(config, port_8255_cfg);
 }
 
@@ -189,29 +187,29 @@ static void enable_chan(struct comedi_de
 	priv = (struct priv_pcm3724 *)(dev->private);
 
 	mask = 1 << CR_CHAN(chanspec);
-	if (s == dev->subdevices) {	/*  subdev 0 */
+	if (s == dev->subdevices)	/*  subdev 0 */
 		priv->dio_1 |= mask;
-	} else {		/* subdev 1 */
+	else		/* subdev 1 */
 		priv->dio_2 |= mask;
-	}
-	if (priv->dio_1 & 0xff0000) {
+
+	if (priv->dio_1 & 0xff0000)
 		gatecfg |= GATE_C0;
-	}
-	if (priv->dio_1 & 0xff00) {
+
+	if (priv->dio_1 & 0xff00)
 		gatecfg |= GATE_B0;
-	}
-	if (priv->dio_1 & 0xff) {
+
+	if (priv->dio_1 & 0xff)
 		gatecfg |= GATE_A0;
-	}
-	if (priv->dio_2 & 0xff0000) {
+
+	if (priv->dio_2 & 0xff0000)
 		gatecfg |= GATE_C1;
-	}
-	if (priv->dio_2 & 0xff00) {
+
+	if (priv->dio_2 & 0xff00)
 		gatecfg |= GATE_B1;
-	}
-	if (priv->dio_2 & 0xff) {
+
+	if (priv->dio_2 & 0xff)
 		gatecfg |= GATE_A1;
-	}
+
 	/*       printk("gate control %x\n", gatecfg); */
 	outb(gatecfg, dev->iobase + 9);
 }
@@ -225,15 +223,14 @@ static int subdev_3724_insn_config(struc
 	unsigned int bits;
 
 	mask = 1 << CR_CHAN(insn->chanspec);
-	if (mask & 0x0000ff) {
+	if (mask & 0x0000ff)
 		bits = 0x0000ff;
-	} else if (mask & 0x00ff00) {
+	else if (mask & 0x00ff00)
 		bits = 0x00ff00;
-	} else if (mask & 0x0f0000) {
+	else if (mask & 0x0f0000)
 		bits = 0x0f0000;
-	} else {
+	else
 		bits = 0xf00000;
-	}
 
 	switch (data[0]) {
 	case INSN_CONFIG_DIO_INPUT:
@@ -272,7 +269,7 @@ static int pcm3724_attach(struct comedi_
 	((struct priv_pcm3724 *)(dev->private))->dio_1 = 0;
 	((struct priv_pcm3724 *)(dev->private))->dio_2 = 0;
 
-	printk("comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor,
+	printk(KERN_INFO "comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor,
 	       this_board->name, iobase);
 	if (!iobase || !request_region(iobase, iorange, "pcm3724")) {
 		printk("I/O port conflict\n");
@@ -281,7 +278,7 @@ static int pcm3724_attach(struct comedi_
 
 	dev->iobase = iobase;
 	dev->board_name = this_board->name;
-	printk("\n");
+	printk(KERN_INFO "\n");
 
 	n_subdevices = this_board->numofports;
 
@@ -302,13 +299,11 @@ static int pcm3724_detach(struct comedi_
 	int i;
 
 	if (dev->subdevices) {
-		for (i = 0; i < dev->n_subdevices; i++) {
+		for (i = 0; i < dev->n_subdevices; i++)
 			subdev_8255_cleanup(dev, dev->subdevices + i);
-		}
 	}
-	if (dev->iobase) {
+	if (dev->iobase)
 		release_region(dev->iobase, this_board->io_range);
-	}
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcm3730.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcm3730.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcm3730.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcm3730.c	2010-05-16 17:17:36.000000000 -0400
@@ -73,7 +73,7 @@ static int pcm3730_attach(struct comedi_
 	unsigned long iobase;
 
 	iobase = it->options[0];
-	printk("comedi%d: pcm3730: 0x%04lx ", dev->minor, iobase);
+	printk(KERN_INFO "comedi%d: pcm3730: 0x%04lx ", dev->minor, iobase);
 	if (!request_region(iobase, PCM3730_SIZE, "pcm3730")) {
 		printk("I/O port conflict\n");
 		return -EIO;
@@ -140,14 +140,14 @@ static int pcm3730_attach(struct comedi_
 	s->range_table = &range_digital;
 	s->private = (void *)PCM3730_DIC;
 
-	printk("\n");
+	printk(KERN_INFO "\n");
 
 	return 0;
 }
 
 static int pcm3730_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: pcm3730: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: pcm3730: remove\n", dev->minor);
 
 	if (dev->iobase)
 		release_region(dev->iobase, PCM3730_SIZE);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcmad.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcmad.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcmad.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcmad.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,11 +34,11 @@ Configuration options:
   [0] - I/O port base
   [1] - unused
   [2] - Analog input reference
-          0 = single ended
-          1 = differential
+	0 = single ended
+	1 = differential
   [3] - Analog input encoding (must match jumpers)
-          0 = straight binary
-          1 = two's complement
+	0 = straight binary
+	1 = two's complement
 */
 
 #include <linux/interrupt.h>
@@ -113,9 +113,8 @@ static int pcmad_ai_insn_read(struct com
 		data[n] = inb(dev->iobase + PCMAD_LSB);
 		data[n] |= (inb(dev->iobase + PCMAD_MSB) << 8);
 
-		if (devpriv->twos_comp) {
+		if (devpriv->twos_comp)
 			data[n] ^= (1 << (this_board->n_ai_bits - 1));
-		}
 	}
 
 	return n;
@@ -135,11 +134,12 @@ static int pcmad_attach(struct comedi_de
 	unsigned long iobase;
 
 	iobase = it->options[0];
-	printk("comedi%d: pcmad: 0x%04lx ", dev->minor, iobase);
+	printk(KERN_INFO "comedi%d: pcmad: 0x%04lx ", dev->minor, iobase);
 	if (!request_region(iobase, PCMAD_SIZE, "pcmad")) {
-		printk("I/O port conflict\n");
+		printk(KERN_CONT "I/O port conflict\n");
 		return -EIO;
 	}
+	printk(KERN_CONT "\n");
 	dev->iobase = iobase;
 
 	ret = alloc_subdevices(dev, 1);
@@ -166,11 +166,11 @@ static int pcmad_attach(struct comedi_de
 
 static int pcmad_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: pcmad: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: pcmad: remove\n", dev->minor);
 
-	if (dev->irq) {
+	if (dev->irq)
 		free_irq(dev->irq, dev);
-	}
+
 	if (dev->iobase)
 		release_region(dev->iobase, PCMAD_SIZE);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcmmio.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcmmio.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcmmio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcmmio.c	2010-05-16 17:17:36.000000000 -0400
@@ -77,6 +77,7 @@ Configuration Options:
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 #include "pcm_common.h"
 #include <linux/pci.h>		/* for PCI devices */
@@ -550,7 +551,7 @@ static int pcmmio_attach(struct comedi_d
 
 	if (irq[0]) {
 		printk("irq: %u ", irq[0]);
-		if (irq[1] && thisboard->dio_num_asics == 2)
+		if (thisboard->dio_num_asics == 2 && irq[1])
 			printk("second ASIC irq: %u ", irq[1]);
 	} else {
 		printk("(IRQ mode disabled) ");
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcmuio.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcmuio.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/pcmuio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/pcmuio.c	2010-05-16 17:17:36.000000000 -0400
@@ -76,6 +76,7 @@ Configuration Options:
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 #include "pcm_common.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/poc.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/poc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/poc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/poc.c	2010-05-16 17:17:36.000000000 -0400
@@ -122,22 +122,21 @@ static int poc_attach(struct comedi_devi
 	unsigned int iosize;
 
 	iobase = it->options[0];
-	printk("comedi%d: poc: using %s iobase 0x%lx\n", dev->minor,
+	printk(KERN_INFO "comedi%d: poc: using %s iobase 0x%lx\n", dev->minor,
 	       this_board->name, iobase);
 
 	dev->board_name = this_board->name;
 
 	if (iobase == 0) {
-		printk("io base address required\n");
+		printk(KERN_ERR "io base address required\n");
 		return -EINVAL;
 	}
 
 	iosize = this_board->iosize;
 	/* check if io addresses are available */
 	if (!request_region(iobase, iosize, "dac02")) {
-		printk
-		    ("I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
-		     iobase, iobase + iosize - 1);
+		printk(KERN_ERR "I/O port conflict: failed to allocate ports "
+			"0x%lx to 0x%lx\n", iobase, iobase + iosize - 1);
 		return -EIO;
 	}
 	dev->iobase = iobase;
@@ -156,9 +155,8 @@ static int poc_attach(struct comedi_devi
 	s->insn_write = this_board->winsn;
 	s->insn_read = this_board->rinsn;
 	s->insn_bits = this_board->insnbits;
-	if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO) {
+	if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO)
 		s->subdev_flags = SDF_WRITABLE;
-	}
 
 	return 0;
 }
@@ -169,7 +167,7 @@ static int poc_detach(struct comedi_devi
 	if (dev->iobase)
 		release_region(dev->iobase, this_board->iosize);
 
-	printk("comedi%d: dac02: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: dac02: remove\n", dev->minor);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/rti800.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/rti800.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/rti800.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/rti800.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,22 +32,22 @@ Configuration options:
   [0] - I/O port base address
   [1] - IRQ
   [2] - A/D reference
-          0 = differential
-          1 = pseudodifferential (common)
-          2 = single-ended
+	0 = differential
+	1 = pseudodifferential (common)
+	2 = single-ended
   [3] - A/D range
-          0 = [-10,10]
-          1 = [-5,5]
-          2 = [0,10]
+	0 = [-10,10]
+	1 = [-5,5]
+	2 = [0,10]
   [4] - A/D encoding
-          0 = two's complement
-          1 = straight binary
+	0 = two's complement
+	1 = straight binary
   [5] - DAC 0 range
-          0 = [-10,10]
-          1 = [0,10]
+	0 = [-10,10]
+	1 = [0,10]
   [6] - DAC 0 encoding
-          0 = two's complement
-          1 = straight binary
+	0 = two's complement
+	1 = straight binary
   [7] - DAC 1 range (same as DAC 0)
   [8] - DAC 1 encoding (same as DAC 0)
 */
@@ -225,7 +225,7 @@ static int rti800_ai_insn_read(struct co
 		for (t = RTI800_TIMEOUT; t; t--) {
 			status = inb(dev->iobase + RTI800_CSR);
 			if (status & RTI800_OVERRUN) {
-				printk("rti800: a/d overrun\n");
+				printk(KERN_WARNING "rti800: a/d overrun\n");
 				outb(0, dev->iobase + RTI800_CLRFLAGS);
 				return -EIO;
 			}
@@ -234,15 +234,14 @@ static int rti800_ai_insn_read(struct co
 			udelay(1);
 		}
 		if (t == 0) {
-			printk("rti800: timeout\n");
+			printk(KERN_WARNING "rti800: timeout\n");
 			return -ETIME;
 		}
 		data[i] = inb(dev->iobase + RTI800_ADCLO);
 		data[i] |= (0xf & inb(dev->iobase + RTI800_ADCHI)) << 8;
 
-		if (devpriv->adc_coding == adc_2comp) {
+		if (devpriv->adc_coding == adc_2comp)
 			data[i] ^= 0x800;
-		}
 	}
 
 	return i;
@@ -271,9 +270,9 @@ static int rti800_ao_insn_write(struct c
 
 	for (i = 0; i < insn->n; i++) {
 		devpriv->ao_readback[chan] = d = data[i];
-		if (devpriv->dac0_coding == dac_2comp) {
+		if (devpriv->dac0_coding == dac_2comp)
 			d ^= 0x800;
-		}
+
 		outb(d & 0xff,
 		     dev->iobase + (chan ? RTI800_DAC1LO : RTI800_DAC0LO));
 		outb(d >> 8,
@@ -315,15 +314,15 @@ static int rti800_do_insn_bits(struct co
    options[0] - I/O port
    options[1] - irq
    options[2] - a/d mux
-   	0=differential, 1=pseudodiff, 2=single
+	0=differential, 1=pseudodiff, 2=single
    options[3] - a/d range
-   	0=bipolar10, 1=bipolar5, 2=unipolar10
+	0=bipolar10, 1=bipolar5, 2=unipolar10
    options[4] - a/d coding
-   	0=2's comp, 1=straight binary
+	0=2's comp, 1=straight binary
    options[5] - dac0 range
-   	0=bipolar10, 1=unipolar10
+	0=bipolar10, 1=unipolar10
    options[6] - dac0 coding
-   	0=2's comp, 1=straight binary
+	0=2's comp, 1=straight binary
    options[7] - dac1 range
    options[8] - dac1 coding
  */
@@ -336,15 +335,15 @@ static int rti800_attach(struct comedi_d
 	struct comedi_subdevice *s;
 
 	iobase = it->options[0];
-	printk("comedi%d: rti800: 0x%04lx ", dev->minor, iobase);
+	printk(KERN_INFO "comedi%d: rti800: 0x%04lx\n", dev->minor, iobase);
 	if (!request_region(iobase, RTI800_SIZE, "rti800")) {
-		printk("I/O port conflict\n");
+		printk(KERN_WARNING "I/O port conflict\n");
 		return -EIO;
 	}
 	dev->iobase = iobase;
 
 #ifdef DEBUG
-	printk("fingerprint=%x,%x,%x,%x,%x ",
+	printk(KERN_DEBUG "fingerprint=%x,%x,%x,%x,%x ",
 	       inb(dev->iobase + 0),
 	       inb(dev->iobase + 1),
 	       inb(dev->iobase + 2),
@@ -357,15 +356,15 @@ static int rti800_attach(struct comedi_d
 
 	irq = it->options[1];
 	if (irq) {
-		printk("( irq = %u )", irq);
+		printk(KERN_INFO "( irq = %u )\n", irq);
 		ret = request_irq(irq, rti800_interrupt, 0, "rti800", dev);
 		if (ret < 0) {
-			printk(" Failed to allocate IRQ\n");
+			printk(KERN_WARNING " Failed to allocate IRQ\n");
 			return ret;
 		}
 		dev->irq = irq;
 	} else {
-		printk("( no irq )");
+		printk(KERN_INFO "( no irq )\n");
 	}
 
 	dev->board_name = this_board->name;
@@ -461,14 +460,12 @@ static int rti800_attach(struct comedi_d
 	s->type = COMEDI_SUBD_TIMER;
 #endif
 
-	printk("\n");
-
 	return 0;
 }
 
 static int rti800_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: rti800: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: rti800: remove\n", dev->minor);
 
 	if (dev->iobase)
 		release_region(dev->iobase, RTI800_SIZE);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/rti802.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/rti802.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/rti802.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/rti802.c	2010-05-16 17:17:36.000000000 -0400
@@ -106,9 +106,9 @@ static int rti802_attach(struct comedi_d
 	unsigned long iobase;
 
 	iobase = it->options[0];
-	printk("comedi%d: rti802: 0x%04lx ", dev->minor, iobase);
+	printk(KERN_INFO "comedi%d: rti802: 0x%04lx ", dev->minor, iobase);
 	if (!request_region(iobase, RTI802_SIZE, "rti802")) {
-		printk("I/O port conflict\n");
+		printk(KERN_WARNING "I/O port conflict\n");
 		return -EIO;
 	}
 	dev->iobase = iobase;
@@ -138,14 +138,12 @@ static int rti802_attach(struct comedi_d
 		    ? &range_unipolar10 : &range_bipolar10;
 	}
 
-	printk("\n");
-
 	return 0;
 }
 
 static int rti802_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: rti802: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: rti802: remove\n", dev->minor);
 
 	if (dev->iobase)
 		release_region(dev->iobase, RTI802_SIZE);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/s626.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/s626.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/s626.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/s626.c	2010-05-16 17:17:36.000000000 -0400
@@ -140,7 +140,7 @@ struct s626_private {
 	short allocatedBuf;
 	uint8_t ai_cmd_running;	/*  ai_cmd is running */
 	uint8_t ai_continous;	/*  continous aquisition */
-	int ai_sample_count;	/*  number of samples to aquire */
+	int ai_sample_count;	/*  number of samples to acquire */
 	unsigned int ai_sample_timer;
 	/*  time between samples in  units of the timer */
 	int ai_convert_count;	/*  conversion counter */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/serial2002.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/serial2002.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/serial2002.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/serial2002.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@ Status: in development
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <asm/termios.h>
 #include <asm/ioctls.h>
@@ -397,7 +398,7 @@ static void serial_2002_open(struct come
 	char port[20];
 
 	sprintf(port, "/dev/ttyS%d", devpriv->port);
-	devpriv->tty = filp_open(port, 0, O_RDWR);
+	devpriv->tty = filp_open(port, O_RDWR, 0);
 	if (IS_ERR(devpriv->tty)) {
 		printk("serial_2002: file open error = %ld\n",
 		       PTR_ERR(devpriv->tty));
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ssv_dnp.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ssv_dnp.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/ssv_dnp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/ssv_dnp.c	2010-05-16 17:17:36.000000000 -0400
@@ -300,11 +300,11 @@ static int dnp_dio_insn_config(struct co
 
 	/* read 'old' direction of the port and set bits (out=1, in=0)             */
 	register_buffer = inb(CSCDR);
-	if (data[0] == COMEDI_OUTPUT) {
+	if (data[0] == COMEDI_OUTPUT)
 		register_buffer |= (1 << chan);
-	} else {
+	else
 		register_buffer &= ~(1 << chan);
-	}
+
 	outb(register_buffer, CSCDR);
 
 	return 1;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/unioxx5.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/unioxx5.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/unioxx5.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/unioxx5.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,6 +44,7 @@ Devices: [Fastwel] UNIOxx-5 (unioxx5),
 
 #include "../comedidev.h"
 #include <linux/ioport.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "unioxx5"
 #define UNIOXX5_SIZE 0x10
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/usbdux.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/usbdux.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/usbdux.c	2013-05-03 12:12:24.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/usbdux.c	2013-05-03 09:51:56.000000000 -0400
@@ -95,7 +95,6 @@ sampling rate. If you sample two channel
 #include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/usb.h>
-#include <linux/smp_lock.h>
 #include <linux/fcntl.h>
 #include <linux/compiler.h>
 #include <linux/firmware.h>
@@ -289,7 +288,7 @@ struct usbduxsub {
 	/* continous aquisition */
 	short int ai_continous;
 	short int ao_continous;
-	/* number of samples to aquire */
+	/* number of samples to acquire */
 	int ai_sample_count;
 	int ao_sample_count;
 	/* time between samples in units of the timer */
@@ -2833,7 +2832,7 @@ static struct comedi_driver driver_usbdu
 };
 
 /* Table with the USB-devices: just now only testing IDs */
-static struct usb_device_id usbduxsub_table[] = {
+static const struct usb_device_id usbduxsub_table[] = {
 	{USB_DEVICE(0x13d8, 0x0001)},
 	{USB_DEVICE(0x13d8, 0x0002)},
 	{}			/* Terminating entry */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/usbduxfast.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/usbduxfast.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/usbduxfast.c	2013-05-03 12:12:26.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/usbduxfast.c	2013-05-03 09:51:59.000000000 -0400
@@ -44,7 +44,6 @@
 #include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/usb.h>
-#include <linux/smp_lock.h>
 #include <linux/fcntl.h>
 #include <linux/compiler.h>
 #include "comedi_fc.h"
@@ -182,7 +181,7 @@ struct usbduxfastsub_s {
 						   context */
 	short int ai_cmd_running;	/* asynchronous command is running */
 	short int ai_continous;	/* continous aquisition */
-	long int ai_sample_count;	/* number of samples to aquire */
+	long int ai_sample_count;	/* number of samples to acquire */
 	uint8_t *dux_commands;	/* commands */
 	int ignore;		/* counter which ignores the first
 				   buffers */
@@ -1769,7 +1768,7 @@ static struct comedi_driver driver_usbdu
 /*
  * Table with the USB-devices: just now only testing IDs
  */
-static struct usb_device_id usbduxfastsub_table[] = {
+static const struct usb_device_id usbduxfastsub_table[] = {
 	/* { USB_DEVICE(0x4b4, 0x8613) }, testing */
 	{USB_DEVICE(0x13d8, 0x0010)},	/* real ID */
 	{USB_DEVICE(0x13d8, 0x0011)},	/* real ID */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/vmk80xx.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/vmk80xx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers/vmk80xx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers/vmk80xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -75,7 +75,7 @@ enum {
 	DEVICE_VMK8061
 };
 
-static struct usb_device_id vmk80xx_id_table[] = {
+static const struct usb_device_id vmk80xx_id_table[] = {
 	{USB_DEVICE(0x10cf, 0x5500), .driver_info = DEVICE_VMK8055},
 	{USB_DEVICE(0x10cf, 0x5501), .driver_info = DEVICE_VMK8055},
 	{USB_DEVICE(0x10cf, 0x5502), .driver_info = DEVICE_VMK8055},
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/drivers.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/drivers.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,7 +44,7 @@
 #include <linux/cdev.h>
 #include <linux/dma-mapping.h>
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/system.h>
 
 static int postconfig(struct comedi_device *dev);
@@ -99,11 +99,10 @@ static void cleanup_device(struct comedi
 static void __comedi_device_detach(struct comedi_device *dev)
 {
 	dev->attached = 0;
-	if (dev->driver) {
+	if (dev->driver)
 		dev->driver->detach(dev);
-	} else {
+	else
 		printk("BUG: dev->driver=NULL in comedi_device_detach()\n");
-	}
 	cleanup_device(dev);
 }
 
@@ -380,9 +379,8 @@ static int insn_rw_emulate_bits(struct c
 	if (ret < 0)
 		return ret;
 
-	if (insn->insn == INSN_READ) {
+	if (insn->insn == INSN_READ)
 		data[0] = (new_data[1] >> (chan - base_bitfield_channel)) & 1;
-	}
 
 	return 1;
 }
@@ -429,9 +427,9 @@ int comedi_buf_alloc(struct comedi_devic
 	new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
 
 	/* if no change is required, do nothing */
-	if (async->prealloc_buf && async->prealloc_bufsz == new_size) {
+	if (async->prealloc_buf && async->prealloc_bufsz == new_size)
 		return 0;
-	}
+
 	/*  deallocate old buffer */
 	if (async->prealloc_buf) {
 		vunmap(async->prealloc_buf);
@@ -494,9 +492,9 @@ int comedi_buf_alloc(struct comedi_devic
 					    (void *)
 					    get_zeroed_page(GFP_KERNEL);
 				}
-				if (async->buf_page_list[i].virt_addr == NULL) {
+				if (async->buf_page_list[i].virt_addr == NULL)
 					break;
-				}
+
 				mem_map_reserve(virt_to_page
 						(async->buf_page_list[i].
 						 virt_addr));
@@ -619,9 +617,9 @@ unsigned int comedi_buf_write_alloc(stru
 {
 	unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
 
-	if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0) {
+	if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0)
 		nbytes = free_end - async->buf_write_alloc_count;
-	}
+
 	async->buf_write_alloc_count += nbytes;
 	/* barrier insures the read of buf_read_count above occurs before
 	   we write data to the write-alloc'ed buffer space */
@@ -635,9 +633,9 @@ unsigned int comedi_buf_write_alloc_stri
 {
 	unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
 
-	if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0) {
+	if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0)
 		nbytes = 0;
-	}
+
 	async->buf_write_alloc_count += nbytes;
 	/* barrier insures the read of buf_read_count above occurs before
 	   we write data to the write-alloc'ed buffer space */
@@ -657,9 +655,9 @@ unsigned comedi_buf_write_free(struct co
 	async->buf_write_count += nbytes;
 	async->buf_write_ptr += nbytes;
 	comedi_buf_munge(async, async->buf_write_count - async->munge_count);
-	if (async->buf_write_ptr >= async->prealloc_bufsz) {
+	if (async->buf_write_ptr >= async->prealloc_bufsz)
 		async->buf_write_ptr %= async->prealloc_bufsz;
-	}
+
 	return nbytes;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/kcomedilib/kcomedilib_main.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/kcomedilib/kcomedilib_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/kcomedilib/kcomedilib_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,6 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <asm/io.h>
 
 #include "../comedi.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/comedi/kcomedilib/ksyms.c linux-libre-2.6.34-gnu1/drivers/staging/comedi/kcomedilib/ksyms.c
--- linux-libre-2.6.33-gnu1/drivers/staging/comedi/kcomedilib/ksyms.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/comedi/kcomedilib/ksyms.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,6 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 
 /* functions specific to kcomedilib */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/bc_dts_defs.h linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/bc_dts_defs.h
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/bc_dts_defs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/bc_dts_defs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,498 @@
+/********************************************************************
+ * Copyright(c) 2006-2009 Broadcom Corporation.
+ *
+ *  Name: bc_dts_defs.h
+ *
+ *  Description: Common definitions for all components. Only types
+ *		 is allowed to be included from this file.
+ *
+ *  AU
+ *
+ *  HISTORY:
+ *
+ ********************************************************************
+ * This header is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 2.1 of the License.
+ *
+ * This header is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this header.  If not, see <http://www.gnu.org/licenses/>.
+ *******************************************************************/
+
+#ifndef _BC_DTS_DEFS_H_
+#define _BC_DTS_DEFS_H_
+
+#include "bc_dts_types.h"
+
+/* BIT Mask */
+#define BC_BIT(_x)		(1 << (_x))
+
+typedef enum _BC_STATUS {
+	BC_STS_SUCCESS		= 0,
+	BC_STS_INV_ARG		= 1,
+	BC_STS_BUSY		= 2,
+	BC_STS_NOT_IMPL		= 3,
+	BC_STS_PGM_QUIT		= 4,
+	BC_STS_NO_ACCESS	= 5,
+	BC_STS_INSUFF_RES	= 6,
+	BC_STS_IO_ERROR		= 7,
+	BC_STS_NO_DATA		= 8,
+	BC_STS_VER_MISMATCH	= 9,
+	BC_STS_TIMEOUT		= 10,
+	BC_STS_FW_CMD_ERR	= 11,
+	BC_STS_DEC_NOT_OPEN	= 12,
+	BC_STS_ERR_USAGE	= 13,
+	BC_STS_IO_USER_ABORT	= 14,
+	BC_STS_IO_XFR_ERROR	= 15,
+	BC_STS_DEC_NOT_STARTED	= 16,
+	BC_STS_FWHEX_NOT_FOUND	= 17,
+	BC_STS_FMT_CHANGE	= 18,
+	BC_STS_HIF_ACCESS	= 19,
+	BC_STS_CMD_CANCELLED	= 20,
+	BC_STS_FW_AUTH_FAILED	= 21,
+	BC_STS_BOOTLOADER_FAILED = 22,
+	BC_STS_CERT_VERIFY_ERROR = 23,
+	BC_STS_DEC_EXIST_OPEN	= 24,
+	BC_STS_PENDING		= 25,
+	BC_STS_CLK_NOCHG	= 26,
+
+	/* Must be the last one.*/
+	BC_STS_ERROR		= -1
+} BC_STATUS;
+
+/*------------------------------------------------------*
+ *    Registry Key Definitions				*
+ *------------------------------------------------------*/
+#define BC_REG_KEY_MAIN_PATH	"Software\\Broadcom\\MediaPC\\70010"
+#define BC_REG_KEY_FWPATH		"FirmwareFilePath"
+#define BC_REG_KEY_SEC_OPT		"DbgOptions"
+
+/*
+ * Options:
+ *
+ *  b[5] = Enable RSA KEY in EEPROM Support
+ *  b[6] = Enable Old PIB scheme. (0 = Use PIB with video scheme)
+ *
+ *  b[12] = Enable send message to NotifyIcon
+ *
+ */
+
+typedef enum _BC_SW_OPTIONS {
+	BC_OPT_DOSER_OUT_ENCRYPT	= BC_BIT(3),
+	BC_OPT_LINK_OUT_ENCRYPT		= BC_BIT(29),
+} BC_SW_OPTIONS;
+
+typedef struct _BC_REG_CONFIG{
+	uint32_t		DbgOptions;
+} BC_REG_CONFIG;
+
+#if defined(__KERNEL__) || defined(__LINUX_USER__)
+#else
+/* Align data structures */
+#define ALIGN(x)	__declspec(align(x))
+#endif
+
+/* mode
+ * b[0]..b[7]	= _DtsDeviceOpenMode
+ * b[8]		=  Load new FW
+ * b[9]		=  Load file play back FW
+ * b[10]	=  Disk format (0 for HD DVD and 1 for BLU ray)
+ * b[11]-b[15]	=  default output resolution
+ * b[16]	=  Skip TX CPB Buffer Check
+ * b[17]	=  Adaptive Output Encrypt/Scramble Scheme
+ * b[18]-b[31]	=  reserved for future use
+ */
+
+/* To allow multiple apps to open the device. */
+enum _DtsDeviceOpenMode {
+	DTS_PLAYBACK_MODE = 0,
+	DTS_DIAG_MODE,
+	DTS_MONITOR_MODE,
+	DTS_HWINIT_MODE
+};
+
+/* To enable the filter to selectively enable/disable fixes or erratas */
+enum _DtsDeviceFixMode {
+	DTS_LOAD_NEW_FW		= BC_BIT(8),
+	DTS_LOAD_FILE_PLAY_FW	= BC_BIT(9),
+	DTS_DISK_FMT_BD		= BC_BIT(10),
+	/* b[11]-b[15] : Default output resolution */
+	DTS_SKIP_TX_CHK_CPB	= BC_BIT(16),
+	DTS_ADAPTIVE_OUTPUT_PER	= BC_BIT(17),
+	DTS_INTELLIMAP		= BC_BIT(18),
+	/* b[19]-b[21] : select clock frequency */
+	DTS_PLAYBACK_DROP_RPT_MODE = BC_BIT(22)
+};
+
+#define DTS_DFLT_RESOLUTION(x)	(x<<11)
+
+#define DTS_DFLT_CLOCK(x) (x<<19)
+
+/* F/W File Version corresponding to S/W Releases */
+enum _FW_FILE_VER {
+	/* S/W release: 02.04.02	F/W release 2.12.2.0 */
+	BC_FW_VER_020402 = ((12<<16) | (2<<8) | (0))
+};
+
+/*------------------------------------------------------*
+ *    Stream Types for DtsOpenDecoder()			*
+ *------------------------------------------------------*/
+enum _DtsOpenDecStreamTypes {
+	BC_STREAM_TYPE_ES		= 0,
+	BC_STREAM_TYPE_PES		= 1,
+	BC_STREAM_TYPE_TS		= 2,
+	BC_STREAM_TYPE_ES_TSTAMP	= 6,
+};
+
+/*------------------------------------------------------*
+ *    Video Algorithms for DtsSetVideoParams()		*
+ *------------------------------------------------------*/
+enum _DtsSetVideoParamsAlgo {
+	BC_VID_ALGO_H264		= 0,
+	BC_VID_ALGO_MPEG2		= 1,
+	BC_VID_ALGO_VC1			= 4,
+	BC_VID_ALGO_VC1MP		= 7,
+};
+
+/*------------------------------------------------------*
+ *    MPEG Extension to the PPB				*
+ *------------------------------------------------------*/
+#define BC_MPEG_VALID_PANSCAN		(1)
+
+typedef struct _BC_PIB_EXT_MPEG {
+	uint32_t	valid;
+	/* Always valid,  defaults to picture size if no
+	 * sequence display extension in the stream. */
+	uint32_t	display_horizontal_size;
+	uint32_t	display_vertical_size;
+
+	/* MPEG_VALID_PANSCAN
+	 * Offsets are a copy values from the MPEG stream. */
+	uint32_t	offset_count;
+	int32_t		horizontal_offset[3];
+	int32_t		vertical_offset[3];
+
+} BC_PIB_EXT_MPEG;
+
+/*------------------------------------------------------*
+ *    H.264 Extension to the PPB			*
+ *------------------------------------------------------*/
+/* Bit definitions for 'other.h264.valid' field */
+#define H264_VALID_PANSCAN		(1)
+#define H264_VALID_SPS_CROP		(2)
+#define H264_VALID_VUI			(4)
+
+typedef struct _BC_PIB_EXT_H264 {
+	/* 'valid' specifies which fields (or sets of
+	 * fields) below are valid.  If the corresponding
+	 * bit in 'valid' is NOT set then that field(s)
+	 * is (are) not initialized. */
+	uint32_t	valid;
+
+	/* H264_VALID_PANSCAN */
+	uint32_t	pan_scan_count;
+	int32_t		pan_scan_left[3];
+	int32_t		pan_scan_right[3];
+	int32_t		pan_scan_top[3];
+	int32_t		pan_scan_bottom[3];
+
+	/* H264_VALID_SPS_CROP */
+	int32_t		sps_crop_left;
+	int32_t		sps_crop_right;
+	int32_t		sps_crop_top;
+	int32_t		sps_crop_bottom;
+
+	/* H264_VALID_VUI */
+	uint32_t	chroma_top;
+	uint32_t	chroma_bottom;
+
+} BC_PIB_EXT_H264;
+
+/*------------------------------------------------------*
+ *    VC1 Extension to the PPB				*
+ *------------------------------------------------------*/
+#define VC1_VALID_PANSCAN		(1)
+
+typedef struct _BC_PIB_EXT_VC1 {
+	uint32_t	valid;
+
+	/* Always valid, defaults to picture size if no
+	 * sequence display extension in the stream. */
+	uint32_t	display_horizontal_size;
+	uint32_t	display_vertical_size;
+
+	/* VC1 pan scan windows */
+	uint32_t	num_panscan_windows;
+	int32_t		ps_horiz_offset[4];
+	int32_t		ps_vert_offset[4];
+	int32_t		ps_width[4];
+	int32_t		ps_height[4];
+
+} BC_PIB_EXT_VC1;
+
+
+/*------------------------------------------------------*
+ *    Picture Information Block				*
+ *------------------------------------------------------*/
+#if defined(_WIN32) || defined(_WIN64) || defined(__LINUX_USER__)
+/* Values for 'pulldown' field.  '0' means no pulldown information
+ * was present for this picture. */
+enum {
+	vdecNoPulldownInfo	= 0,
+	vdecTop			= 1,
+	vdecBottom		= 2,
+	vdecTopBottom		= 3,
+	vdecBottomTop		= 4,
+	vdecTopBottomTop	= 5,
+	vdecBottomTopBottom	= 6,
+	vdecFrame_X2		= 7,
+	vdecFrame_X3		= 8,
+	vdecFrame_X1		= 9,
+	vdecFrame_X4		= 10,
+};
+
+/* Values for the 'frame_rate' field. */
+enum {
+	vdecFrameRateUnknown = 0,
+	vdecFrameRate23_97,
+	vdecFrameRate24,
+	vdecFrameRate25,
+	vdecFrameRate29_97,
+	vdecFrameRate30,
+	vdecFrameRate50,
+	vdecFrameRate59_94,
+	vdecFrameRate60,
+};
+
+/* Values for the 'aspect_ratio' field. */
+enum {
+	vdecAspectRatioUnknown = 0,
+	vdecAspectRatioSquare,
+	vdecAspectRatio12_11,
+	vdecAspectRatio10_11,
+	vdecAspectRatio16_11,
+	vdecAspectRatio40_33,
+	vdecAspectRatio24_11,
+	vdecAspectRatio20_11,
+	vdecAspectRatio32_11,
+	vdecAspectRatio80_33,
+	vdecAspectRatio18_11,
+	vdecAspectRatio15_11,
+	vdecAspectRatio64_33,
+	vdecAspectRatio160_99,
+	vdecAspectRatio4_3,
+	vdecAspectRatio16_9,
+	vdecAspectRatio221_1,
+	vdecAspectRatioOther = 255,
+};
+
+/* Values for the 'colour_primaries' field. */
+enum {
+	vdecColourPrimariesUnknown = 0,
+	vdecColourPrimariesBT709,
+	vdecColourPrimariesUnspecified,
+	vdecColourPrimariesReserved,
+	vdecColourPrimariesBT470_2M = 4,
+	vdecColourPrimariesBT470_2BG,
+	vdecColourPrimariesSMPTE170M,
+	vdecColourPrimariesSMPTE240M,
+	vdecColourPrimariesGenericFilm,
+};
+
+enum {
+	vdecRESOLUTION_CUSTOM	= 0x00000000, /* custom */
+	vdecRESOLUTION_480i	= 0x00000001, /* 480i */
+	vdecRESOLUTION_1080i	= 0x00000002, /* 1080i (1920x1080, 60i) */
+	vdecRESOLUTION_NTSC	= 0x00000003, /* NTSC (720x483, 60i) */
+	vdecRESOLUTION_480p	= 0x00000004, /* 480p (720x480, 60p) */
+	vdecRESOLUTION_720p	= 0x00000005, /* 720p (1280x720, 60p) */
+	vdecRESOLUTION_PAL1	= 0x00000006, /* PAL_1 (720x576, 50i) */
+	vdecRESOLUTION_1080i25	= 0x00000007, /* 1080i25 (1920x1080, 50i) */
+	vdecRESOLUTION_720p50	= 0x00000008, /* 720p50 (1280x720, 50p) */
+	vdecRESOLUTION_576p	= 0x00000009, /* 576p (720x576, 50p) */
+	vdecRESOLUTION_1080i29_97 = 0x0000000A, /* 1080i (1920x1080, 59.94i) */
+	vdecRESOLUTION_720p59_94  = 0x0000000B, /* 720p (1280x720, 59.94p) */
+	vdecRESOLUTION_SD_DVD	= 0x0000000C, /* SD DVD (720x483, 60i) */
+	vdecRESOLUTION_480p656	= 0x0000000D, /* 480p (720x480, 60p), output bus width 8 bit, clock 74.25MHz */
+	vdecRESOLUTION_1080p23_976 = 0x0000000E, /* 1080p23_976 (1920x1080, 23.976p) */
+	vdecRESOLUTION_720p23_976  = 0x0000000F, /* 720p23_976 (1280x720p, 23.976p) */
+	vdecRESOLUTION_240p29_97   = 0x00000010, /* 240p (1440x240, 29.97p ) */
+	vdecRESOLUTION_240p30	= 0x00000011, /* 240p (1440x240, 30p) */
+	vdecRESOLUTION_288p25	= 0x00000012, /* 288p (1440x288p, 25p) */
+	vdecRESOLUTION_1080p29_97 = 0x00000013, /* 1080p29_97 (1920x1080, 29.97p) */
+	vdecRESOLUTION_1080p30	= 0x00000014, /* 1080p30 (1920x1080, 30p) */
+	vdecRESOLUTION_1080p24	= 0x00000015, /* 1080p24 (1920x1080, 24p) */
+	vdecRESOLUTION_1080p25	= 0x00000016, /* 1080p25 (1920x1080, 25p) */
+	vdecRESOLUTION_720p24	= 0x00000017, /* 720p24 (1280x720, 25p) */
+	vdecRESOLUTION_720p29_97  = 0x00000018, /* 720p29.97 (1280x720, 29.97p) */
+	vdecRESOLUTION_480p23_976 = 0x00000019, /* 480p23.976 (720*480, 23.976) */
+	vdecRESOLUTION_480p29_97  = 0x0000001A, /* 480p29.976 (720*480, 29.97p) */
+	vdecRESOLUTION_576p25	= 0x0000001B, /* 576p25 (720*576, 25p) */
+	/* For Zero Frame Rate */
+	vdecRESOLUTION_480p0	= 0x0000001C, /* 480p (720x480, 0p) */
+	vdecRESOLUTION_480i0	= 0x0000001D, /* 480i (720x480, 0i) */
+	vdecRESOLUTION_576p0	= 0x0000001E, /* 576p (720x576, 0p) */
+	vdecRESOLUTION_720p0	= 0x0000001F, /* 720p (1280x720, 0p) */
+	vdecRESOLUTION_1080p0	= 0x00000020, /* 1080p (1920x1080, 0p) */
+	vdecRESOLUTION_1080i0	= 0x00000021, /* 1080i (1920x1080, 0i) */
+};
+
+/* Bit definitions for 'flags' field */
+#define VDEC_FLAG_EOS				(0x0004)
+
+#define VDEC_FLAG_FRAME				(0x0000)
+#define VDEC_FLAG_FIELDPAIR			(0x0008)
+#define VDEC_FLAG_TOPFIELD			(0x0010)
+#define VDEC_FLAG_BOTTOMFIELD			(0x0018)
+
+#define VDEC_FLAG_PROGRESSIVE_SRC		(0x0000)
+#define VDEC_FLAG_INTERLACED_SRC		(0x0020)
+#define VDEC_FLAG_UNKNOWN_SRC			(0x0040)
+
+#define VDEC_FLAG_BOTTOM_FIRST			(0x0080)
+#define VDEC_FLAG_LAST_PICTURE			(0x0100)
+
+#define VDEC_FLAG_PICTURE_META_DATA_PRESENT	(0x40000)
+
+#endif /* _WIN32 || _WIN64 */
+
+enum _BC_OUTPUT_FORMAT {
+	MODE420				= 0x0,
+	MODE422_YUY2			= 0x1,
+	MODE422_UYVY			= 0x2,
+};
+
+typedef struct _BC_PIC_INFO_BLOCK {
+	/* Common fields. */
+	uint64_t	timeStamp;	/* Timestamp */
+	uint32_t	picture_number;	/* Ordinal display number  */
+	uint32_t	width;		/* pixels	    */
+	uint32_t	height;		/* pixels	    */
+	uint32_t	chroma_format;	/* 0x420, 0x422 or 0x444 */
+	uint32_t	pulldown;
+	uint32_t	flags;
+	uint32_t	frame_rate;
+	uint32_t	aspect_ratio;
+	uint32_t	colour_primaries;
+	uint32_t	picture_meta_payload;
+	uint32_t	sess_num;
+	uint32_t	ycom;
+	uint32_t	custom_aspect_ratio_width_height;
+	uint32_t	n_drop;	/* number of non-reference frames remaining to be dropped */
+
+	/* Protocol-specific extensions. */
+	union {
+		BC_PIB_EXT_H264	h264;
+		BC_PIB_EXT_MPEG	mpeg;
+		BC_PIB_EXT_VC1	 vc1;
+	} other;
+
+} BC_PIC_INFO_BLOCK, *PBC_PIC_INFO_BLOCK;
+
+/*------------------------------------------------------*
+ *    ProcOut Info					*
+ *------------------------------------------------------*/
+/* Optional flags for ProcOut Interface.*/
+enum _POUT_OPTIONAL_IN_FLAGS_{
+	/* Flags from App to Device */
+	BC_POUT_FLAGS_YV12	  = 0x01,	/* Copy Data in YV12 format */
+	BC_POUT_FLAGS_STRIDE	  = 0x02,	/* Stride size is valid. */
+	BC_POUT_FLAGS_SIZE	  = 0x04,	/* Take size information from Application */
+	BC_POUT_FLAGS_INTERLACED  = 0x08,	/* copy only half the bytes */
+	BC_POUT_FLAGS_INTERLEAVED = 0x10,	/* interleaved frame */
+
+	/* Flags from Device to APP */
+	BC_POUT_FLAGS_FMT_CHANGE  = 0x10000,	/* Data is not VALID when this flag is set */
+	BC_POUT_FLAGS_PIB_VALID	  = 0x20000,	/* PIB Information valid */
+	BC_POUT_FLAGS_ENCRYPTED	  = 0x40000,	/* Data is encrypted. */
+	BC_POUT_FLAGS_FLD_BOT	  = 0x80000,	/* Bottom Field data */
+};
+
+#if defined(__KERNEL__) || defined(__LINUX_USER__)
+typedef BC_STATUS(*dts_pout_callback)(void  *shnd, uint32_t width, uint32_t height, uint32_t stride, void *pOut);
+#else
+typedef BC_STATUS(*dts_pout_callback)(void  *shnd, uint32_t width, uint32_t height, uint32_t stride, struct _BC_DTS_PROC_OUT *pOut);
+#endif
+
+/* Line 21 Closed Caption */
+/* User Data */
+#define MAX_UD_SIZE		1792	/* 1920 - 128 */
+
+typedef struct _BC_DTS_PROC_OUT {
+	uint8_t		*Ybuff;			/* Caller Supplied buffer for Y data */
+	uint32_t	YbuffSz;		/* Caller Supplied Y buffer size */
+	uint32_t	YBuffDoneSz;		/* Transferred Y datasize */
+
+	uint8_t		*UVbuff;		/* Caller Supplied buffer for UV data */
+	uint32_t	UVbuffSz;		/* Caller Supplied UV buffer size */
+	uint32_t	UVBuffDoneSz;		/* Transferred UV data size */
+
+	uint32_t	StrideSz;		/* Caller supplied Stride Size */
+	uint32_t	PoutFlags;		/* Call IN Flags */
+
+	uint32_t	discCnt;		/* Picture discontinuity count */
+
+	BC_PIC_INFO_BLOCK PicInfo;		/* Picture Information Block Data */
+
+	/* Line 21 Closed Caption */
+	/* User Data */
+	uint32_t	UserDataSz;
+	uint8_t		UserData[MAX_UD_SIZE];
+
+	void		*hnd;
+	dts_pout_callback AppCallBack;
+	uint8_t		DropFrames;
+	uint8_t		b422Mode;		/* Picture output Mode */
+	uint8_t		bPibEnc;		/* PIB encrypted */
+	uint8_t		bRevertScramble;
+
+} BC_DTS_PROC_OUT;
+
+typedef struct _BC_DTS_STATUS {
+	uint8_t		ReadyListCount;	/* Number of frames in ready list (reported by driver) */
+	uint8_t		FreeListCount;	/* Number of frame buffers free.  (reported by driver) */
+	uint8_t		PowerStateChange; /* Number of active state power transitions (reported by driver) */
+	uint8_t		reserved_[1];
+
+	uint32_t	FramesDropped;	/* Number of frames dropped.  (reported by DIL) */
+	uint32_t	FramesCaptured;	/* Number of frames captured. (reported by DIL) */
+	uint32_t	FramesRepeated;	/* Number of frames repeated. (reported by DIL) */
+
+	uint32_t	InputCount;	/* Times compressed video has been sent to the HW.
+					 * i.e. Successful DtsProcInput() calls (reported by DIL) */
+	uint64_t	InputTotalSize;	/* Amount of compressed video that has been sent to the HW.
+					 * (reported by DIL) */
+	uint32_t	InputBusyCount;	/* Times compressed video has attempted to be sent to the HW
+					 * but the input FIFO was full. (reported by DIL) */
+
+	uint32_t	PIBMissCount;	/* Amount of times a PIB is invalid. (reported by DIL) */
+
+	uint32_t	cpbEmptySize;	/* supported only for H.264, specifically changed for
+					 * Adobe. Report size of CPB buffer available.
+					 * Reported by DIL */
+	uint64_t	NextTimeStamp;	/* TimeStamp of the next picture that will be returned
+					 * by a call to ProcOutput. Added for Adobe. Reported
+					 * back from the driver */
+	uint8_t		reserved__[16];
+
+} BC_DTS_STATUS;
+
+#define BC_SWAP32(_v)			\
+	((((_v) & 0xFF000000)>>24)|	\
+	  (((_v) & 0x00FF0000)>>8)|	\
+	  (((_v) & 0x0000FF00)<<8)|	\
+	  (((_v) & 0x000000FF)<<24))
+
+#define WM_AGENT_TRAYICON_DECODER_OPEN	10001
+#define WM_AGENT_TRAYICON_DECODER_CLOSE	10002
+#define WM_AGENT_TRAYICON_DECODER_START	10003
+#define WM_AGENT_TRAYICON_DECODER_STOP	10004
+#define WM_AGENT_TRAYICON_DECODER_RUN	10005
+#define WM_AGENT_TRAYICON_DECODER_PAUSE	10006
+
+
+#endif	/* _BC_DTS_DEFS_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/bc_dts_glob_lnx.h linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/bc_dts_glob_lnx.h
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/bc_dts_glob_lnx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/bc_dts_glob_lnx.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,299 @@
+/********************************************************************
+ * Copyright(c) 2006-2009 Broadcom Corporation.
+ *
+ *  Name: bc_dts_glob_lnx.h
+ *
+ *  Description: Wrapper to Windows dts_glob.h for Link-Linux usage.
+ *		 The idea is to define additional Linux related defs
+ *		 in this file to avoid changes to existing Windows
+ *		 glob file.
+ *
+ *  AU
+ *
+ *  HISTORY:
+ *
+ ********************************************************************
+ * This header is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 2.1 of the License.
+ *
+ * This header is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this header.  If not, see <http://www.gnu.org/licenses/>.
+ *******************************************************************/
+
+#ifndef _BC_DTS_GLOB_LNX_H_
+#define _BC_DTS_GLOB_LNX_H_
+
+#ifdef __LINUX_USER__
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+#include <netdb.h>
+#include <sys/time.h>
+#include <time.h>
+#include <arpa/inet.h>
+#include <asm/param.h>
+#include <linux/ioctl.h>
+#include <sys/select.h>
+
+#define DRVIFLIB_INT_API
+
+#endif
+
+#include "bc_dts_defs.h"
+#include "bcm_70012_regs.h"	/* Link Register defs */
+
+#define CRYSTALHD_API_NAME	"crystalhd"
+#define CRYSTALHD_API_DEV_NAME	"/dev/crystalhd"
+
+/*
+ * These are SW stack tunable parameters shared
+ * between the driver and the application.
+ */
+enum _BC_DTS_GLOBALS {
+	BC_MAX_FW_CMD_BUFF_SZ	= 0x40,		/* FW passthrough cmd/rsp buffer size */
+	PCI_CFG_SIZE		= 256,		/* PCI config size buffer */
+	BC_IOCTL_DATA_POOL_SIZE	= 8,		/* BC_IOCTL_DATA Pool size */
+	BC_LINK_MAX_OPENS	= 3,		/* Maximum simultaneous opens*/
+	BC_LINK_MAX_SGLS	= 1024,		/* Maximum SG elements 4M/4K */
+	BC_TX_LIST_CNT		= 2,		/* Max Tx DMA Rings */
+	BC_RX_LIST_CNT		= 8,		/* Max Rx DMA Rings*/
+	BC_PROC_OUTPUT_TIMEOUT	= 3000,		/* Milliseconds */
+	BC_INFIFO_THRESHOLD	= 0x10000,
+};
+
+typedef struct _BC_CMD_REG_ACC {
+	uint32_t		Offset;
+	uint32_t		Value;
+} BC_CMD_REG_ACC;
+
+typedef struct _BC_CMD_DEV_MEM {
+	uint32_t		StartOff;
+	uint32_t		NumDwords;
+	uint32_t		Rsrd;
+} BC_CMD_DEV_MEM;
+
+/* FW Passthrough command structure */
+enum _bc_fw_cmd_flags {
+	BC_FW_CMD_FLAGS_NONE	= 0,
+	BC_FW_CMD_PIB_QS	= 0x01,
+};
+
+typedef struct _BC_FW_CMD {
+	uint32_t		cmd[BC_MAX_FW_CMD_BUFF_SZ];
+	uint32_t		rsp[BC_MAX_FW_CMD_BUFF_SZ];
+	uint32_t		flags;
+	uint32_t		add_data;
+} BC_FW_CMD, *PBC_FW_CMD;
+
+typedef struct _BC_HW_TYPE {
+	uint16_t		PciDevId;
+	uint16_t		PciVenId;
+	uint8_t			HwRev;
+	uint8_t			Align[3];
+} BC_HW_TYPE;
+
+typedef struct _BC_PCI_CFG {
+	uint32_t		Size;
+	uint32_t		Offset;
+	uint8_t			pci_cfg_space[PCI_CFG_SIZE];
+} BC_PCI_CFG;
+
+typedef struct _BC_VERSION_INFO_ {
+	uint8_t			DriverMajor;
+	uint8_t			DriverMinor;
+	uint16_t		DriverRevision;
+} BC_VERSION_INFO;
+
+typedef struct _BC_START_RX_CAP_ {
+	uint32_t		Rsrd;
+	uint32_t		StartDeliveryThsh;
+	uint32_t		PauseThsh;
+	uint32_t		ResumeThsh;
+} BC_START_RX_CAP;
+
+typedef struct _BC_FLUSH_RX_CAP_ {
+	uint32_t		Rsrd;
+	uint32_t		bDiscardOnly;
+} BC_FLUSH_RX_CAP;
+
+typedef struct _BC_DTS_STATS {
+	uint8_t			drvRLL;
+	uint8_t			drvFLL;
+	uint8_t			eosDetected;
+	uint8_t			pwr_state_change;
+
+	/* Stats from App */
+	uint32_t		opFrameDropped;
+	uint32_t		opFrameCaptured;
+	uint32_t		ipSampleCnt;
+	uint64_t		ipTotalSize;
+	uint32_t		reptdFrames;
+	uint32_t		pauseCount;
+	uint32_t		pibMisses;
+	uint32_t		discCounter;
+
+	/* Stats from Driver */
+	uint32_t		TxFifoBsyCnt;
+	uint32_t		intCount;
+	uint32_t		DrvIgnIntrCnt;
+	uint32_t		DrvTotalFrmDropped;
+	uint32_t		DrvTotalHWErrs;
+	uint32_t		DrvTotalPIBFlushCnt;
+	uint32_t		DrvTotalFrmCaptured;
+	uint32_t		DrvPIBMisses;
+	uint32_t		DrvPauseTime;
+	uint32_t		DrvRepeatedFrms;
+	uint32_t		res1[13];
+
+} BC_DTS_STATS;
+
+typedef struct _BC_PROC_INPUT_ {
+	uint8_t			*pDmaBuff;
+	uint32_t		BuffSz;
+	uint8_t			Mapped;
+	uint8_t			Encrypted;
+	uint8_t			Rsrd[2];
+	uint32_t		DramOffset;	/* For debug use only */
+} BC_PROC_INPUT, *PBC_PROC_INPUT;
+
+typedef struct _BC_DEC_YUV_BUFFS {
+	uint32_t		b422Mode;
+	uint8_t			*YuvBuff;
+	uint32_t		YuvBuffSz;
+	uint32_t		UVbuffOffset;
+	uint32_t		YBuffDoneSz;
+	uint32_t		UVBuffDoneSz;
+	uint32_t		RefCnt;
+} BC_DEC_YUV_BUFFS;
+
+enum _DECOUT_COMPLETION_FLAGS{
+	COMP_FLAG_NO_INFO	= 0x00,
+	COMP_FLAG_FMT_CHANGE	= 0x01,
+	COMP_FLAG_PIB_VALID	= 0x02,
+	COMP_FLAG_DATA_VALID	= 0x04,
+	COMP_FLAG_DATA_ENC	= 0x08,
+	COMP_FLAG_DATA_BOT	= 0x10,
+};
+
+typedef struct _BC_DEC_OUT_BUFF{
+	BC_DEC_YUV_BUFFS	OutPutBuffs;
+	BC_PIC_INFO_BLOCK	PibInfo;
+	uint32_t		Flags;
+	uint32_t		BadFrCnt;
+} BC_DEC_OUT_BUFF;
+
+typedef struct _BC_NOTIFY_MODE {
+	uint32_t		Mode;
+	uint32_t		Rsvr[3];
+} BC_NOTIFY_MODE;
+
+typedef struct _BC_CLOCK {
+	uint32_t		clk;
+	uint32_t		Rsvr[3];
+} BC_CLOCK;
+
+typedef struct _BC_IOCTL_DATA {
+	BC_STATUS		RetSts;
+	uint32_t		IoctlDataSz;
+	uint32_t		Timeout;
+	union {
+		BC_CMD_REG_ACC		regAcc;
+		BC_CMD_DEV_MEM		devMem;
+		BC_FW_CMD		fwCmd;
+		BC_HW_TYPE		hwType;
+		BC_PCI_CFG		pciCfg;
+		BC_VERSION_INFO		VerInfo;
+		BC_PROC_INPUT		ProcInput;
+		BC_DEC_YUV_BUFFS	RxBuffs;
+		BC_DEC_OUT_BUFF		DecOutData;
+		BC_START_RX_CAP		RxCap;
+		BC_FLUSH_RX_CAP		FlushRxCap;
+		BC_DTS_STATS		drvStat;
+		BC_NOTIFY_MODE		NotifyMode;
+		BC_CLOCK			clockValue;
+	} u;
+	struct _BC_IOCTL_DATA	*next;
+} BC_IOCTL_DATA;
+
+typedef enum _BC_DRV_CMD{
+	DRV_CMD_VERSION = 0,	/* Get SW version */
+	DRV_CMD_GET_HWTYPE,	/* Get HW version and type Dozer/Tank */
+	DRV_CMD_REG_RD,		/* Read Device Register */
+	DRV_CMD_REG_WR,		/* Write Device Register */
+	DRV_CMD_FPGA_RD,	/* Read FPGA Register */
+	DRV_CMD_FPGA_WR,	/* Wrtie FPGA Reister */
+	DRV_CMD_MEM_RD,		/* Read Device Memory */
+	DRV_CMD_MEM_WR,		/* Write Device Memory */
+	DRV_CMD_RD_PCI_CFG,	/* Read PCI Config Space */
+	DRV_CMD_WR_PCI_CFG,	/* Write the PCI Configuration Space*/
+	DRV_CMD_FW_DOWNLOAD,	/* Download Firmware */
+	DRV_ISSUE_FW_CMD,	/* Issue FW Cmd (pass through mode) */
+	DRV_CMD_PROC_INPUT,	/* Process Input Sample */
+	DRV_CMD_ADD_RXBUFFS,	/* Add Rx side buffers to driver pool */
+	DRV_CMD_FETCH_RXBUFF,	/* Get Rx DMAed buffer */
+	DRV_CMD_START_RX_CAP,	/* Start Rx Buffer Capture */
+	DRV_CMD_FLUSH_RX_CAP,	/* Stop the capture for now...we will enhance this later*/
+	DRV_CMD_GET_DRV_STAT,	/* Get Driver Internal Statistics */
+	DRV_CMD_RST_DRV_STAT,	/* Reset Driver Internal Statistics */
+	DRV_CMD_NOTIFY_MODE,	/* Notify the Mode to driver in which the application is Operating*/
+	DRV_CMD_CHANGE_CLOCK,	/* Change the core clock to either save power or improve performance */
+
+	/* MUST be the last one.. */
+	DRV_CMD_END,			/* End of the List.. */
+} BC_DRV_CMD;
+
+#define BC_IOC_BASE		'b'
+#define BC_IOC_VOID		_IOC_NONE
+#define BC_IOC_IOWR(nr, type)	_IOWR(BC_IOC_BASE, nr, type)
+#define BC_IOCTL_MB		BC_IOCTL_DATA
+
+#define	BCM_IOC_GET_VERSION	BC_IOC_IOWR(DRV_CMD_VERSION, BC_IOCTL_MB)
+#define	BCM_IOC_GET_HWTYPE	BC_IOC_IOWR(DRV_CMD_GET_HWTYPE, BC_IOCTL_MB)
+#define	BCM_IOC_REG_RD		BC_IOC_IOWR(DRV_CMD_REG_RD, BC_IOCTL_MB)
+#define	BCM_IOC_REG_WR		BC_IOC_IOWR(DRV_CMD_REG_WR, BC_IOCTL_MB)
+#define	BCM_IOC_MEM_RD		BC_IOC_IOWR(DRV_CMD_MEM_RD, BC_IOCTL_MB)
+#define	BCM_IOC_MEM_WR		BC_IOC_IOWR(DRV_CMD_MEM_WR, BC_IOCTL_MB)
+#define BCM_IOC_FPGA_RD		BC_IOC_IOWR(DRV_CMD_FPGA_RD, BC_IOCTL_MB)
+#define BCM_IOC_FPGA_WR		BC_IOC_IOWR(DRV_CMD_FPGA_WR, BC_IOCTL_MB)
+#define	BCM_IOC_RD_PCI_CFG	BC_IOC_IOWR(DRV_CMD_RD_PCI_CFG, BC_IOCTL_MB)
+#define	BCM_IOC_WR_PCI_CFG	BC_IOC_IOWR(DRV_CMD_WR_PCI_CFG, BC_IOCTL_MB)
+#define BCM_IOC_PROC_INPUT	BC_IOC_IOWR(DRV_CMD_PROC_INPUT, BC_IOCTL_MB)
+#define BCM_IOC_ADD_RXBUFFS	BC_IOC_IOWR(DRV_CMD_ADD_RXBUFFS, BC_IOCTL_MB)
+#define BCM_IOC_FETCH_RXBUFF	BC_IOC_IOWR(DRV_CMD_FETCH_RXBUFF, BC_IOCTL_MB)
+#define	BCM_IOC_FW_CMD		BC_IOC_IOWR(DRV_ISSUE_FW_CMD, BC_IOCTL_MB)
+#define	BCM_IOC_START_RX_CAP	BC_IOC_IOWR(DRV_CMD_START_RX_CAP, BC_IOCTL_MB)
+#define BCM_IOC_FLUSH_RX_CAP	BC_IOC_IOWR(DRV_CMD_FLUSH_RX_CAP, BC_IOCTL_MB)
+#define BCM_IOC_GET_DRV_STAT	BC_IOC_IOWR(DRV_CMD_GET_DRV_STAT, BC_IOCTL_MB)
+#define BCM_IOC_RST_DRV_STAT	BC_IOC_IOWR(DRV_CMD_RST_DRV_STAT, BC_IOCTL_MB)
+#define BCM_IOC_NOTIFY_MODE	BC_IOC_IOWR(DRV_CMD_NOTIFY_MODE, BC_IOCTL_MB)
+#define	BCM_IOC_FW_DOWNLOAD	BC_IOC_IOWR(DRV_CMD_FW_DOWNLOAD, BC_IOCTL_MB)
+#define BCM_IOC_CHG_CLK		BC_IOC_IOWR(DRV_CMD_CHANGE_CLOCK, BC_IOCTL_MB)
+#define	BCM_IOC_END		BC_IOC_VOID
+
+/* Wrapper for main IOCTL data */
+typedef struct _crystalhd_ioctl_data {
+	BC_IOCTL_DATA		udata;		/* IOCTL from App..*/
+	uint32_t		u_id;		/* Driver specific user ID */
+	uint32_t		cmd;		/* Cmd ID for driver's use. */
+	void			*add_cdata;	/* Additional command specific data..*/
+	uint32_t		add_cdata_sz;	/* Additional command specific data size */
+	struct _crystalhd_ioctl_data *next;	/* List/Fifo management */
+} crystalhd_ioctl_data;
+
+
+enum _crystalhd_kmod_ver{
+	crystalhd_kmod_major	= 0,
+	crystalhd_kmod_minor	= 9,
+	crystalhd_kmod_rev	= 27,
+};
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/bc_dts_types.h linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/bc_dts_types.h
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/bc_dts_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/bc_dts_types.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,121 @@
+/********************************************************************
+ * Copyright(c) 2006-2009 Broadcom Corporation.
+ *
+ *  Name: bc_dts_types.h
+ *
+ *  Description: Data types
+ *
+ *  AU
+ *
+ *  HISTORY:
+ *
+ ********************************************************************
+ * This header is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 2.1 of the License.
+ *
+ * This header is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this header.  If not, see <http://www.gnu.org/licenses/>.
+ *******************************************************************/
+
+#ifndef _BC_DTS_TYPES_H_
+#define _BC_DTS_TYPES_H_
+
+#ifdef __LINUX_USER__  // Don't include these for KERNEL..
+#include <stdint.h>
+#endif
+
+#if defined(_WIN64) || defined(_WIN32)
+typedef uint32_t		U32;
+typedef int32_t			S32;
+typedef uint16_t		U16;
+typedef int16_t			S16;
+typedef unsigned char		U8;
+typedef char			S8;
+#endif
+
+#ifndef PVOID
+typedef void	*PVOID;
+#endif
+
+#ifndef BOOL
+typedef int	BOOL;
+#endif
+
+#ifdef WIN32
+    typedef unsigned __int64	U64;
+#elif defined(_WIN64)
+    typedef uint64_t U64;
+#endif
+
+#ifdef _WIN64
+#if !(defined(POINTER_32))
+#define POINTER_32	__ptr32
+#endif
+#else	/* _WIN32 */
+#define POINTER_32
+#endif
+
+#if defined(__KERNEL__) || defined(__LINUX_USER__)
+
+#ifdef __LINUX_USER__	/* Don't include these for KERNEL */
+typedef uint32_t	ULONG;
+typedef int32_t		LONG;
+typedef void		*HANDLE;
+#ifndef VOID
+typedef void		VOID;
+#endif
+typedef void		*LPVOID;
+typedef uint32_t	DWORD;
+typedef uint32_t	UINT32;
+typedef uint32_t	*LPDWORD;
+typedef unsigned char	*PUCHAR;
+
+#ifndef TRUE
+	#define TRUE		1
+#endif
+
+#ifndef FALSE
+	#define FALSE		0
+#endif
+
+#define TEXT
+
+#else
+
+/* For Kernel usage.. */
+typedef bool	bc_bool_t;
+#endif
+
+#else
+
+#ifndef uint64_t
+typedef struct _uint64_t {
+	uint32_t low_dw;
+	uint32_t hi_dw;
+} uint64_t;
+#endif
+
+#ifndef int32_t
+typedef signed long		int32_t;
+#endif
+
+#ifndef uint32_t
+typedef unsigned long	uint32_t;
+#endif
+
+#ifndef uint16_t
+typedef unsigned short	uint16_t;
+#endif
+
+#ifndef uint8_t
+typedef unsigned char	uint8_t;
+#endif
+#endif
+
+#endif
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/bcm_70012_regs.h linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/bcm_70012_regs.h
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/bcm_70012_regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/bcm_70012_regs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,757 @@
+/***************************************************************************
+ * Copyright (c) 1999-2009, Broadcom Corporation.
+ *
+ *  Name: bcm_70012_regs.h
+ *
+ *  Description: BCM70012 registers
+ *
+ ********************************************************************
+ * This header is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 2.1 of the License.
+ *
+ * This header is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this header.  If not, see <http://www.gnu.org/licenses/>.
+ ***************************************************************************/
+
+#ifndef MACFILE_H__
+#define MACFILE_H__
+
+/**
+ * m = memory, c = core, r = register, f = field, d = data.
+ */
+#if !defined(GET_FIELD) && !defined(SET_FIELD)
+#define BRCM_ALIGN(c,r,f)   c##_##r##_##f##_ALIGN
+#define BRCM_BITS(c,r,f)    c##_##r##_##f##_BITS
+#define BRCM_MASK(c,r,f)    c##_##r##_##f##_MASK
+#define BRCM_SHIFT(c,r,f)   c##_##r##_##f##_SHIFT
+
+#define GET_FIELD(m,c,r,f) \
+	((((m) & BRCM_MASK(c,r,f)) >> BRCM_SHIFT(c,r,f)) << BRCM_ALIGN(c,r,f))
+
+#define SET_FIELD(m,c,r,f,d) \
+	((m) = (((m) & ~BRCM_MASK(c,r,f)) | ((((d) >> BRCM_ALIGN(c,r,f)) << \
+	 BRCM_SHIFT(c,r,f)) & BRCM_MASK(c,r,f))) \
+	)
+
+#define SET_TYPE_FIELD(m,c,r,f,d) SET_FIELD(m,c,r,f,c##_##d)
+#define SET_NAME_FIELD(m,c,r,f,d) SET_FIELD(m,c,r,f,c##_##r##_##f##_##d)
+#define SET_VALUE_FIELD(m,c,r,f,d) SET_FIELD(m,c,r,f,d)
+
+#endif /* GET & SET */
+
+/****************************************************************************
+ * Core Enums.
+ ***************************************************************************/
+/****************************************************************************
+ * Enums: AES_RGR_BRIDGE_RESET_CTRL
+ ***************************************************************************/
+#define AES_RGR_BRIDGE_RESET_CTRL_DEASSERT                 0
+#define AES_RGR_BRIDGE_RESET_CTRL_ASSERT                   1
+
+/****************************************************************************
+ * Enums: CCE_RGR_BRIDGE_RESET_CTRL
+ ***************************************************************************/
+#define CCE_RGR_BRIDGE_RESET_CTRL_DEASSERT                 0
+#define CCE_RGR_BRIDGE_RESET_CTRL_ASSERT                   1
+
+/****************************************************************************
+ * Enums: DBU_RGR_BRIDGE_RESET_CTRL
+ ***************************************************************************/
+#define DBU_RGR_BRIDGE_RESET_CTRL_DEASSERT                 0
+#define DBU_RGR_BRIDGE_RESET_CTRL_ASSERT                   1
+
+/****************************************************************************
+ * Enums: DCI_RGR_BRIDGE_RESET_CTRL
+ ***************************************************************************/
+#define DCI_RGR_BRIDGE_RESET_CTRL_DEASSERT                 0
+#define DCI_RGR_BRIDGE_RESET_CTRL_ASSERT                   1
+
+/****************************************************************************
+ * Enums: GISB_ARBITER_DEASSERT_ASSERT
+ ***************************************************************************/
+#define GISB_ARBITER_DEASSERT_ASSERT_DEASSERT              0
+#define GISB_ARBITER_DEASSERT_ASSERT_ASSERT                1
+
+/****************************************************************************
+ * Enums: GISB_ARBITER_UNMASK_MASK
+ ***************************************************************************/
+#define GISB_ARBITER_UNMASK_MASK_UNMASK                    0
+#define GISB_ARBITER_UNMASK_MASK_MASK                      1
+
+/****************************************************************************
+ * Enums: GISB_ARBITER_DISABLE_ENABLE
+ ***************************************************************************/
+#define GISB_ARBITER_DISABLE_ENABLE_DISABLE                0
+#define GISB_ARBITER_DISABLE_ENABLE_ENABLE                 1
+
+/****************************************************************************
+ * Enums: I2C_GR_BRIDGE_RESET_CTRL
+ ***************************************************************************/
+#define I2C_GR_BRIDGE_RESET_CTRL_DEASSERT                  0
+#define I2C_GR_BRIDGE_RESET_CTRL_ASSERT                    1
+
+/****************************************************************************
+ * Enums: MISC_GR_BRIDGE_RESET_CTRL
+ ***************************************************************************/
+#define MISC_GR_BRIDGE_RESET_CTRL_DEASSERT                 0
+#define MISC_GR_BRIDGE_RESET_CTRL_ASSERT                   1
+
+/****************************************************************************
+ * Enums: OTP_GR_BRIDGE_RESET_CTRL
+ ***************************************************************************/
+#define OTP_GR_BRIDGE_RESET_CTRL_DEASSERT                  0
+#define OTP_GR_BRIDGE_RESET_CTRL_ASSERT                    1
+
+/****************************************************************************
+ * BCM70012_TGT_TOP_PCIE_CFG
+ ***************************************************************************/
+#define PCIE_CFG_DEVICE_VENDOR_ID      0x00000000 /* DEVICE_VENDOR_ID Register */
+#define PCIE_CFG_STATUS_COMMAND        0x00000004 /* STATUS_COMMAND Register */
+#define PCIE_CFG_PCI_CLASSCODE_AND_REVISION_ID 0x00000008 /* PCI_CLASSCODE_AND_REVISION_ID Register */
+#define PCIE_CFG_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE_SIZE 0x0000000c /* BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE_SIZE Register */
+#define PCIE_CFG_BASE_ADDRESS_1        0x00000010 /* BASE_ADDRESS_1 Register */
+#define PCIE_CFG_BASE_ADDRESS_2        0x00000014 /* BASE_ADDRESS_2 Register */
+#define PCIE_CFG_BASE_ADDRESS_3        0x00000018 /* BASE_ADDRESS_3 Register */
+#define PCIE_CFG_BASE_ADDRESS_4        0x0000001c /* BASE_ADDRESS_4 Register */
+#define PCIE_CFG_CARDBUS_CIS_POINTER   0x00000028 /* CARDBUS_CIS_POINTER Register */
+#define PCIE_CFG_SUBSYSTEM_DEVICE_VENDOR_ID 0x0000002c /* SUBSYSTEM_DEVICE_VENDOR_ID Register */
+#define PCIE_CFG_EXPANSION_ROM_BASE_ADDRESS 0x00000030 /* EXPANSION_ROM_BASE_ADDRESS Register */
+#define PCIE_CFG_CAPABILITIES_POINTER  0x00000034 /* CAPABILITIES_POINTER Register */
+#define PCIE_CFG_INTERRUPT             0x0000003c /* INTERRUPT Register */
+#define PCIE_CFG_VPD_CAPABILITIES      0x00000040 /* VPD_CAPABILITIES Register */
+#define PCIE_CFG_VPD_DATA              0x00000044 /* VPD_DATA Register */
+#define PCIE_CFG_POWER_MANAGEMENT_CAPABILITY 0x00000048 /* POWER_MANAGEMENT_CAPABILITY Register */
+#define PCIE_CFG_POWER_MANAGEMENT_CONTROL_STATUS 0x0000004c /* POWER_MANAGEMENT_CONTROL_STATUS Register */
+#define PCIE_CFG_MSI_CAPABILITY_HEADER 0x00000050 /* MSI_CAPABILITY_HEADER Register */
+#define PCIE_CFG_MSI_LOWER_ADDRESS     0x00000054 /* MSI_LOWER_ADDRESS Register */
+#define PCIE_CFG_MSI_UPPER_ADDRESS_REGISTER 0x00000058 /* MSI_UPPER_ADDRESS_REGISTER Register */
+#define PCIE_CFG_MSI_DATA              0x0000005c /* MSI_DATA Register */
+#define PCIE_CFG_BROADCOM_VENDOR_SPECIFIC_CAPABILITY_HEADER 0x00000060 /* BROADCOM_VENDOR_SPECIFIC_CAPABILITY_HEADER Register */
+#define PCIE_CFG_RESET_COUNTERS_INITIAL_VALUES 0x00000064 /* RESET_COUNTERS_INITIAL_VALUES Register */
+#define PCIE_CFG_MISCELLANEOUS_HOST_CONTROL 0x00000068 /* MISCELLANEOUS_HOST_CONTROL Register */
+#define PCIE_CFG_SPARE                 0x0000006c /* SPARE Register */
+#define PCIE_CFG_PCI_STATE             0x00000070 /* PCI_STATE Register */
+#define PCIE_CFG_CLOCK_CONTROL         0x00000074 /* CLOCK_CONTROL Register */
+#define PCIE_CFG_REGISTER_BASE         0x00000078 /* REGISTER_BASE Register */
+#define PCIE_CFG_MEMORY_BASE           0x0000007c /* MEMORY_BASE Register */
+#define PCIE_CFG_REGISTER_DATA         0x00000080 /* REGISTER_DATA Register */
+#define PCIE_CFG_MEMORY_DATA           0x00000084 /* MEMORY_DATA Register */
+#define PCIE_CFG_EXPANSION_ROM_BAR_SIZE 0x00000088 /* EXPANSION_ROM_BAR_SIZE Register */
+#define PCIE_CFG_EXPANSION_ROM_ADDRESS 0x0000008c /* EXPANSION_ROM_ADDRESS Register */
+#define PCIE_CFG_EXPANSION_ROM_DATA    0x00000090 /* EXPANSION_ROM_DATA Register */
+#define PCIE_CFG_VPD_INTERFACE         0x00000094 /* VPD_INTERFACE Register */
+#define PCIE_CFG_UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_UPPER 0x00000098 /* UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_UPPER Register */
+#define PCIE_CFG_UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_LOWER 0x0000009c /* UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_LOWER Register */
+#define PCIE_CFG_UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_UPPER 0x000000a0 /* UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_UPPER Register */
+#define PCIE_CFG_UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_LOWER 0x000000a4 /* UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_LOWER Register */
+#define PCIE_CFG_UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_UPPER 0x000000a8 /* UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_UPPER Register */
+#define PCIE_CFG_UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_LOWER 0x000000ac /* UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_LOWER Register */
+#define PCIE_CFG_INT_MAILBOX_UPPER     0x000000b0 /* INT_MAILBOX_UPPER Register */
+#define PCIE_CFG_INT_MAILBOX_LOWER     0x000000b4 /* INT_MAILBOX_LOWER Register */
+#define PCIE_CFG_PRODUCT_ID_AND_ASIC_REVISION 0x000000bc /* PRODUCT_ID_AND_ASIC_REVISION Register */
+#define PCIE_CFG_FUNCTION_EVENT        0x000000c0 /* FUNCTION_EVENT Register */
+#define PCIE_CFG_FUNCTION_EVENT_MASK   0x000000c4 /* FUNCTION_EVENT_MASK Register */
+#define PCIE_CFG_FUNCTION_PRESENT      0x000000c8 /* FUNCTION_PRESENT Register */
+#define PCIE_CFG_PCIE_CAPABILITIES     0x000000cc /* PCIE_CAPABILITIES Register */
+#define PCIE_CFG_DEVICE_CAPABILITIES   0x000000d0 /* DEVICE_CAPABILITIES Register */
+#define PCIE_CFG_DEVICE_STATUS_CONTROL 0x000000d4 /* DEVICE_STATUS_CONTROL Register */
+#define PCIE_CFG_LINK_CAPABILITY       0x000000d8 /* LINK_CAPABILITY Register */
+#define PCIE_CFG_LINK_STATUS_CONTROL   0x000000dc /* LINK_STATUS_CONTROL Register */
+#define PCIE_CFG_DEVICE_CAPABILITIES_2 0x000000f0 /* DEVICE_CAPABILITIES_2 Register */
+#define PCIE_CFG_DEVICE_STATUS_CONTROL_2 0x000000f4 /* DEVICE_STATUS_CONTROL_2 Register */
+#define PCIE_CFG_LINK_CAPABILITIES_2   0x000000f8 /* LINK_CAPABILITIES_2 Register */
+#define PCIE_CFG_LINK_STATUS_CONTROL_2 0x000000fc /* LINK_STATUS_CONTROL_2 Register */
+#define PCIE_CFG_ADVANCED_ERROR_REPORTING_ENHANCED_CAPABILITY_HEADER 0x00000100 /* ADVANCED_ERROR_REPORTING_ENHANCED_CAPABILITY_HEADER Register */
+#define PCIE_CFG_UNCORRECTABLE_ERROR_STATUS 0x00000104 /* UNCORRECTABLE_ERROR_STATUS Register */
+#define PCIE_CFG_UNCORRECTABLE_ERROR_MASK 0x00000108 /* UNCORRECTABLE_ERROR_MASK Register */
+#define PCIE_CFG_UNCORRECTABLE_ERROR_SEVERITY 0x0000010c /* UNCORRECTABLE_ERROR_SEVERITY Register */
+#define PCIE_CFG_CORRECTABLE_ERROR_STATUS 0x00000110 /* CORRECTABLE_ERROR_STATUS Register */
+#define PCIE_CFG_CORRECTABLE_ERROR_MASK 0x00000114 /* CORRECTABLE_ERROR_MASK Register */
+#define PCIE_CFG_ADVANCED_ERROR_CAPABILITIES_AND_CONTROL 0x00000118 /* ADVANCED_ERROR_CAPABILITIES_AND_CONTROL Register */
+#define PCIE_CFG_HEADER_LOG_1          0x0000011c /* HEADER_LOG_1 Register */
+#define PCIE_CFG_HEADER_LOG_2          0x00000120 /* HEADER_LOG_2 Register */
+#define PCIE_CFG_HEADER_LOG_3          0x00000124 /* HEADER_LOG_3 Register */
+#define PCIE_CFG_HEADER_LOG_4          0x00000128 /* HEADER_LOG_4 Register */
+#define PCIE_CFG_VIRTUAL_CHANNEL_ENHANCED_CAPABILITY_HEADER 0x0000013c /* VIRTUAL_CHANNEL_ENHANCED_CAPABILITY_HEADER Register */
+#define PCIE_CFG_PORT_VC_CAPABILITY    0x00000140 /* PORT_VC_CAPABILITY Register */
+#define PCIE_CFG_PORT_VC_CAPABILITY_2  0x00000144 /* PORT_VC_CAPABILITY_2 Register */
+#define PCIE_CFG_PORT_VC_STATUS_CONTROL 0x00000148 /* PORT_VC_STATUS_CONTROL Register */
+#define PCIE_CFG_VC_RESOURCE_CAPABILITY 0x0000014c /* VC_RESOURCE_CAPABILITY Register */
+#define PCIE_CFG_VC_RESOURCE_CONTROL   0x00000150 /* VC_RESOURCE_CONTROL Register */
+#define PCIE_CFG_VC_RESOURCE_STATUS    0x00000154 /* VC_RESOURCE_STATUS Register */
+#define PCIE_CFG_DEVICE_SERIAL_NO_ENHANCED_CAPABILITY_HEADER 0x00000160 /* DEVICE_SERIAL_NO_ENHANCED_CAPABILITY_HEADER Register */
+#define PCIE_CFG_DEVICE_SERIAL_NO_LOWER_DW 0x00000164 /* DEVICE_SERIAL_NO_LOWER_DW Register */
+#define PCIE_CFG_DEVICE_SERIAL_NO_UPPER_DW 0x00000168 /* DEVICE_SERIAL_NO_UPPER_DW Register */
+#define PCIE_CFG_POWER_BUDGETING_ENHANCED_CAPABILITY_HEADER 0x0000016c /* POWER_BUDGETING_ENHANCED_CAPABILITY_HEADER Register */
+#define PCIE_CFG_POWER_BUDGETING_DATA_SELECT 0x00000170 /* POWER_BUDGETING_DATA_SELECT Register */
+#define PCIE_CFG_POWER_BUDGETING_DATA  0x00000174 /* POWER_BUDGETING_DATA Register */
+#define PCIE_CFG_POWER_BUDGETING_CAPABILITY 0x00000178 /* POWER_BUDGETING_CAPABILITY Register */
+#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_2_1 0x0000017c /* FIRMWARE_POWER_BUDGETING_2_1 Register */
+#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_4_3 0x00000180 /* FIRMWARE_POWER_BUDGETING_4_3 Register */
+#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_6_5 0x00000184 /* FIRMWARE_POWER_BUDGETING_6_5 Register */
+#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_8_7 0x00000188 /* FIRMWARE_POWER_BUDGETING_8_7 Register */
+#define PCIE_CFG_PCIE_1_1_ADVISORY_NON_FATAL_ERROR_MASKING 0x0000018c /* PCIE_1_1_ADVISORY_NON_FATAL_ERROR_MASKING Register */
+
+
+/****************************************************************************
+ * BCM70012_TGT_TOP_PCIE_TL
+ ***************************************************************************/
+#define PCIE_TL_TL_CONTROL             0x00000400 /* TL_CONTROL Register */
+#define PCIE_TL_TRANSACTION_CONFIGURATION 0x00000404 /* TRANSACTION_CONFIGURATION Register */
+
+
+/****************************************************************************
+ * BCM70012_TGT_TOP_PCIE_DLL
+ ***************************************************************************/
+#define PCIE_DLL_DATA_LINK_CONTROL     0x00000500 /* DATA_LINK_CONTROL Register */
+#define PCIE_DLL_DATA_LINK_STATUS      0x00000504 /* DATA_LINK_STATUS Register */
+
+
+/****************************************************************************
+ * BCM70012_TGT_TOP_INTR
+ ***************************************************************************/
+#define INTR_INTR_STATUS               0x00000700 /* Interrupt Status Register */
+#define INTR_INTR_SET                  0x00000704 /* Interrupt Set Register */
+#define INTR_INTR_CLR_REG              0x00000708 /* Interrupt Clear Register */
+#define INTR_INTR_MSK_STS_REG          0x0000070c /* Interrupt Mask Status Register */
+#define INTR_INTR_MSK_SET_REG          0x00000710 /* Interrupt Mask Set Register */
+#define INTR_INTR_MSK_CLR_REG          0x00000714 /* Interrupt Mask Clear Register */
+#define INTR_EOI_CTRL                  0x00000720 /* End of interrupt control register */
+
+
+/****************************************************************************
+ * BCM70012_MISC_TOP_MISC1
+ ***************************************************************************/
+#define MISC1_TX_FIRST_DESC_L_ADDR_LIST0 0x00000c00 /* Tx DMA Descriptor List0 First Descriptor lower Address */
+#define MISC1_TX_FIRST_DESC_U_ADDR_LIST0 0x00000c04 /* Tx DMA Descriptor List0 First Descriptor Upper Address */
+#define MISC1_TX_FIRST_DESC_L_ADDR_LIST1 0x00000c08 /* Tx DMA Descriptor List1 First Descriptor Lower Address */
+#define MISC1_TX_FIRST_DESC_U_ADDR_LIST1 0x00000c0c /* Tx DMA Descriptor List1 First Descriptor Upper Address */
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS 0x00000c10 /* Tx DMA Software Descriptor List Control and Status */
+#define MISC1_TX_DMA_ERROR_STATUS      0x00000c18 /* Tx DMA Engine Error Status */
+#define MISC1_TX_DMA_LIST0_CUR_DESC_L_ADDR 0x00000c1c /* Tx DMA List0 Current Descriptor Lower Address */
+#define MISC1_TX_DMA_LIST0_CUR_DESC_U_ADDR 0x00000c20 /* Tx DMA List0 Current Descriptor Upper Address */
+#define MISC1_TX_DMA_LIST0_CUR_BYTE_CNT_REM 0x00000c24 /* Tx DMA List0 Current Descriptor Upper Address */
+#define MISC1_TX_DMA_LIST1_CUR_DESC_L_ADDR 0x00000c28 /* Tx DMA List1 Current Descriptor Lower Address */
+#define MISC1_TX_DMA_LIST1_CUR_DESC_U_ADDR 0x00000c2c /* Tx DMA List1 Current Descriptor Upper Address */
+#define MISC1_TX_DMA_LIST1_CUR_BYTE_CNT_REM 0x00000c30 /* Tx DMA List1 Current Descriptor Upper Address */
+#define MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0 0x00000c34 /* Y Rx Descriptor List0 First Descriptor Lower Address */
+#define MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST0 0x00000c38 /* Y Rx Descriptor List0 First Descriptor Upper Address */
+#define MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1 0x00000c3c /* Y Rx Descriptor List1 First Descriptor Lower Address */
+#define MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST1 0x00000c40 /* Y Rx Descriptor List1 First Descriptor Upper Address */
+#define MISC1_Y_RX_SW_DESC_LIST_CTRL_STS 0x00000c44 /* Y Rx Software Descriptor List Control and Status */
+#define MISC1_Y_RX_ERROR_STATUS        0x00000c4c /* Y Rx Engine Error Status */
+#define MISC1_Y_RX_LIST0_CUR_DESC_L_ADDR 0x00000c50 /* Y Rx List0 Current Descriptor Lower Address */
+#define MISC1_Y_RX_LIST0_CUR_DESC_U_ADDR 0x00000c54 /* Y Rx List0 Current Descriptor Upper Address */
+#define MISC1_Y_RX_LIST0_CUR_BYTE_CNT  0x00000c58 /* Y Rx List0 Current Descriptor Byte Count */
+#define MISC1_Y_RX_LIST1_CUR_DESC_L_ADDR 0x00000c5c /* Y Rx List1 Current Descriptor Lower address */
+#define MISC1_Y_RX_LIST1_CUR_DESC_U_ADDR 0x00000c60 /* Y Rx List1 Current Descriptor Upper address */
+#define MISC1_Y_RX_LIST1_CUR_BYTE_CNT  0x00000c64 /* Y Rx List1 Current Descriptor Byte Count */
+#define MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0 0x00000c68 /* UV Rx Descriptor List0 First Descriptor lower Address */
+#define MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST0 0x00000c6c /* UV Rx Descriptor List0 First Descriptor Upper Address */
+#define MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1 0x00000c70 /* UV Rx Descriptor List1 First Descriptor Lower Address */
+#define MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST1 0x00000c74 /* UV Rx Descriptor List1 First Descriptor Upper Address */
+#define MISC1_UV_RX_SW_DESC_LIST_CTRL_STS 0x00000c78 /* UV Rx Software Descriptor List Control and Status */
+#define MISC1_UV_RX_ERROR_STATUS       0x00000c7c /* UV Rx Engine Error Status */
+#define MISC1_UV_RX_LIST0_CUR_DESC_L_ADDR 0x00000c80 /* UV Rx List0 Current Descriptor Lower Address */
+#define MISC1_UV_RX_LIST0_CUR_DESC_U_ADDR 0x00000c84 /* UV Rx List0 Current Descriptor Upper Address */
+#define MISC1_UV_RX_LIST0_CUR_BYTE_CNT 0x00000c88 /* UV Rx List0 Current Descriptor Byte Count */
+#define MISC1_UV_RX_LIST1_CUR_DESC_L_ADDR 0x00000c8c /* UV Rx List1 Current Descriptor Lower Address */
+#define MISC1_UV_RX_LIST1_CUR_DESC_U_ADDR 0x00000c90 /* UV Rx List1 Current Descriptor Upper Address */
+#define MISC1_UV_RX_LIST1_CUR_BYTE_CNT 0x00000c94 /* UV Rx List1 Current Descriptor Byte Count */
+#define MISC1_DMA_DEBUG_OPTIONS_REG    0x00000c98 /* DMA Debug Options Register */
+#define MISC1_READ_CHANNEL_ERROR_STATUS 0x00000c9c /* Read Channel Error Status */
+#define MISC1_PCIE_DMA_CTRL            0x00000ca0 /* PCIE DMA Control Register */
+
+
+/****************************************************************************
+ * BCM70012_MISC_TOP_MISC2
+ ***************************************************************************/
+#define MISC2_GLOBAL_CTRL              0x00000d00 /* Global Control Register */
+#define MISC2_INTERNAL_STATUS          0x00000d04 /* Internal Status Register */
+#define MISC2_INTERNAL_STATUS_MUX_CTRL 0x00000d08 /* Internal Debug Mux Control */
+#define MISC2_DEBUG_FIFO_LENGTH        0x00000d0c /* Debug FIFO Length */
+
+
+/****************************************************************************
+ * BCM70012_MISC_TOP_MISC3
+ ***************************************************************************/
+#define MISC3_RESET_CTRL               0x00000e00 /* Reset Control Register */
+#define MISC3_BIST_CTRL                0x00000e04 /* BIST Control Register */
+#define MISC3_BIST_STATUS              0x00000e08 /* BIST Status Register */
+#define MISC3_RX_CHECKSUM              0x00000e0c /* Receive Checksum */
+#define MISC3_TX_CHECKSUM              0x00000e10 /* Transmit Checksum */
+#define MISC3_ECO_CTRL_CORE            0x00000e14 /* ECO Core Reset Control Register */
+#define MISC3_CSI_TEST_CTRL            0x00000e18 /* CSI Test Control Register */
+#define MISC3_HD_DVI_TEST_CTRL         0x00000e1c /* HD DVI Test Control Register */
+
+
+/****************************************************************************
+ * BCM70012_MISC_TOP_MISC_PERST
+ ***************************************************************************/
+#define MISC_PERST_ECO_CTRL_PERST      0x00000e80 /* ECO PCIE Reset Control Register */
+#define MISC_PERST_DECODER_CTRL        0x00000e84 /* Decoder Control Register */
+#define MISC_PERST_CCE_STATUS          0x00000e88 /* Config Copy Engine Status */
+#define MISC_PERST_PCIE_DEBUG          0x00000e8c /* PCIE Debug Control Register */
+#define MISC_PERST_PCIE_DEBUG_STATUS   0x00000e90 /* PCIE Debug Status Register */
+#define MISC_PERST_VREG_CTRL           0x00000e94 /* Voltage Regulator Control Register */
+#define MISC_PERST_MEM_CTRL            0x00000e98 /* Memory Control Register */
+#define MISC_PERST_CLOCK_CTRL          0x00000e9c /* Clock Control Register */
+
+
+/****************************************************************************
+ * BCM70012_MISC_TOP_GISB_ARBITER
+ ***************************************************************************/
+#define GISB_ARBITER_REVISION          0x00000f00 /* GISB ARBITER REVISION */
+#define GISB_ARBITER_SCRATCH           0x00000f04 /* GISB ARBITER Scratch Register */
+#define GISB_ARBITER_REQ_MASK          0x00000f08 /* GISB ARBITER Master Request Mask Register */
+#define GISB_ARBITER_TIMER             0x00000f0c /* GISB ARBITER Timer Value Register */
+
+
+/****************************************************************************
+ * BCM70012_OTP_TOP_OTP
+ ***************************************************************************/
+#define OTP_CONFIG_INFO                0x00001400 /* OTP Configuration Register */
+#define OTP_CMD                        0x00001404 /* OTP Command Register */
+#define OTP_STATUS                     0x00001408 /* OTP Status Register */
+#define OTP_CONTENT_MISC               0x0000140c /* Content : Miscellaneous Register */
+#define OTP_CONTENT_AES_0              0x00001410 /* Content : AES Key 0 Register */
+#define OTP_CONTENT_AES_1              0x00001414 /* Content : AES Key 1 Register */
+#define OTP_CONTENT_AES_2              0x00001418 /* Content : AES Key 2 Register */
+#define OTP_CONTENT_AES_3              0x0000141c /* Content : AES Key 3 Register */
+#define OTP_CONTENT_SHA_0              0x00001420 /* Content : SHA Key 0 Register */
+#define OTP_CONTENT_SHA_1              0x00001424 /* Content : SHA Key 1 Register */
+#define OTP_CONTENT_SHA_2              0x00001428 /* Content : SHA Key 2 Register */
+#define OTP_CONTENT_SHA_3              0x0000142c /* Content : SHA Key 3 Register */
+#define OTP_CONTENT_SHA_4              0x00001430 /* Content : SHA Key 4 Register */
+#define OTP_CONTENT_SHA_5              0x00001434 /* Content : SHA Key 5 Register */
+#define OTP_CONTENT_SHA_6              0x00001438 /* Content : SHA Key 6 Register */
+#define OTP_CONTENT_SHA_7              0x0000143c /* Content : SHA Key 7 Register */
+#define OTP_CONTENT_CHECKSUM           0x00001440 /* Content : Checksum  Register */
+#define OTP_PROG_CTRL                  0x00001444 /* Programming Control Register */
+#define OTP_PROG_STATUS                0x00001448 /* Programming Status Register */
+#define OTP_PROG_PULSE                 0x0000144c /* Program Pulse Width Register */
+#define OTP_VERIFY_PULSE               0x00001450 /* Verify Pulse Width Register */
+#define OTP_PROG_MASK                  0x00001454 /* Program Mask Register */
+#define OTP_DATA_INPUT                 0x00001458 /* Data Input Register */
+#define OTP_DATA_OUTPUT                0x0000145c /* Data Output Register */
+
+
+/****************************************************************************
+ * BCM70012_AES_TOP_AES
+ ***************************************************************************/
+#define AES_CONFIG_INFO                0x00001800 /* AES Configuration Information Register */
+#define AES_CMD                        0x00001804 /* AES Command Register */
+#define AES_STATUS                     0x00001808 /* AES Status Register */
+#define AES_EEPROM_CONFIG              0x0000180c /* AES EEPROM Configuration Register */
+#define AES_EEPROM_DATA_0              0x00001810 /* AES EEPROM Data Register 0 */
+#define AES_EEPROM_DATA_1              0x00001814 /* AES EEPROM Data Register 1 */
+#define AES_EEPROM_DATA_2              0x00001818 /* AES EEPROM Data Register 2 */
+#define AES_EEPROM_DATA_3              0x0000181c /* AES EEPROM Data Register 3 */
+
+
+/****************************************************************************
+ * BCM70012_DCI_TOP_DCI
+ ***************************************************************************/
+#define DCI_CMD                        0x00001c00 /* DCI Command Register */
+#define DCI_STATUS                     0x00001c04 /* DCI Status Register */
+#define DCI_DRAM_BASE_ADDR             0x00001c08 /* DRAM Base Address Register */
+#define DCI_FIRMWARE_ADDR              0x00001c0c /* Firmware Address Register */
+#define DCI_FIRMWARE_DATA              0x00001c10 /* Firmware Data Register */
+#define DCI_SIGNATURE_DATA_0           0x00001c14 /* Signature Data Register 0 */
+#define DCI_SIGNATURE_DATA_1           0x00001c18 /* Signature Data Register 1 */
+#define DCI_SIGNATURE_DATA_2           0x00001c1c /* Signature Data Register 2 */
+#define DCI_SIGNATURE_DATA_3           0x00001c20 /* Signature Data Register 3 */
+#define DCI_SIGNATURE_DATA_4           0x00001c24 /* Signature Data Register 4 */
+#define DCI_SIGNATURE_DATA_5           0x00001c28 /* Signature Data Register 5 */
+#define DCI_SIGNATURE_DATA_6           0x00001c2c /* Signature Data Register 6 */
+#define DCI_SIGNATURE_DATA_7           0x00001c30 /* Signature Data Register 7 */
+
+
+/****************************************************************************
+ * BCM70012_TGT_TOP_INTR
+ ***************************************************************************/
+/****************************************************************************
+ * INTR :: INTR_STATUS
+ ***************************************************************************/
+/* INTR :: INTR_STATUS :: reserved0 [31:26] */
+#define INTR_INTR_STATUS_reserved0_MASK                            0xfc000000
+#define INTR_INTR_STATUS_reserved0_ALIGN                           0
+#define INTR_INTR_STATUS_reserved0_BITS                            6
+#define INTR_INTR_STATUS_reserved0_SHIFT                           26
+
+/* INTR :: INTR_STATUS :: PCIE_TGT_CA_ATTN [25:25] */
+#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_MASK                     0x02000000
+#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_ALIGN                    0
+#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_BITS                     1
+#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_SHIFT                    25
+
+/* INTR :: INTR_STATUS :: PCIE_TGT_UR_ATTN [24:24] */
+#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_MASK                     0x01000000
+#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_ALIGN                    0
+#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_BITS                     1
+#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_SHIFT                    24
+
+/* INTR :: INTR_STATUS :: reserved1 [23:14] */
+#define INTR_INTR_STATUS_reserved1_MASK                            0x00ffc000
+#define INTR_INTR_STATUS_reserved1_ALIGN                           0
+#define INTR_INTR_STATUS_reserved1_BITS                            10
+#define INTR_INTR_STATUS_reserved1_SHIFT                           14
+
+/* INTR :: INTR_STATUS :: L1_UV_RX_DMA_ERR_INTR [13:13] */
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_MASK                0x00002000
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_ALIGN               0
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_BITS                1
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_SHIFT               13
+
+/* INTR :: INTR_STATUS :: L1_UV_RX_DMA_DONE_INTR [12:12] */
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK               0x00001000
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_ALIGN              0
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_BITS               1
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_SHIFT              12
+
+/* INTR :: INTR_STATUS :: L1_Y_RX_DMA_ERR_INTR [11:11] */
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_MASK                 0x00000800
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_ALIGN                0
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_BITS                 1
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_SHIFT                11
+
+/* INTR :: INTR_STATUS :: L1_Y_RX_DMA_DONE_INTR [10:10] */
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK                0x00000400
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_ALIGN               0
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_BITS                1
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_SHIFT               10
+
+/* INTR :: INTR_STATUS :: L1_TX_DMA_ERR_INTR [09:09] */
+#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_MASK                   0x00000200
+#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_ALIGN                  0
+#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_BITS                   1
+#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_SHIFT                  9
+
+/* INTR :: INTR_STATUS :: L1_TX_DMA_DONE_INTR [08:08] */
+#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_MASK                  0x00000100
+#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_ALIGN                 0
+#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_BITS                  1
+#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_SHIFT                 8
+
+/* INTR :: INTR_STATUS :: reserved2 [07:06] */
+#define INTR_INTR_STATUS_reserved2_MASK                            0x000000c0
+#define INTR_INTR_STATUS_reserved2_ALIGN                           0
+#define INTR_INTR_STATUS_reserved2_BITS                            2
+#define INTR_INTR_STATUS_reserved2_SHIFT                           6
+
+/* INTR :: INTR_STATUS :: L0_UV_RX_DMA_ERR_INTR [05:05] */
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_MASK                0x00000020
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_ALIGN               0
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_BITS                1
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_SHIFT               5
+
+/* INTR :: INTR_STATUS :: L0_UV_RX_DMA_DONE_INTR [04:04] */
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK               0x00000010
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_ALIGN              0
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_BITS               1
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_SHIFT              4
+
+/* INTR :: INTR_STATUS :: L0_Y_RX_DMA_ERR_INTR [03:03] */
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_MASK                 0x00000008
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_ALIGN                0
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_BITS                 1
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_SHIFT                3
+
+/* INTR :: INTR_STATUS :: L0_Y_RX_DMA_DONE_INTR [02:02] */
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK                0x00000004
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_ALIGN               0
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_BITS                1
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_SHIFT               2
+
+/* INTR :: INTR_STATUS :: L0_TX_DMA_ERR_INTR [01:01] */
+#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_MASK                   0x00000002
+#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_ALIGN                  0
+#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_BITS                   1
+#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_SHIFT                  1
+
+/* INTR :: INTR_STATUS :: L0_TX_DMA_DONE_INTR [00:00] */
+#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_MASK                  0x00000001
+#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_ALIGN                 0
+#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_BITS                  1
+#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_SHIFT                 0
+
+
+/****************************************************************************
+ * MISC1 :: TX_SW_DESC_LIST_CTRL_STS
+ ***************************************************************************/
+/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: reserved0 [31:04] */
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_MASK              0xfffffff0
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_ALIGN             0
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_BITS              28
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_SHIFT             4
+
+/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: DMA_DATA_SERV_PTR [03:03] */
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_MASK      0x00000008
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_ALIGN     0
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_BITS      1
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_SHIFT     3
+
+/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: DESC_SERV_PTR [02:02] */
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_MASK          0x00000004
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_ALIGN         0
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_BITS          1
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_SHIFT         2
+
+/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: TX_DMA_HALT_ON_ERROR [01:01] */
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_MASK   0x00000002
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_ALIGN  0
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_BITS   1
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_SHIFT  1
+
+/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: TX_DMA_RUN_STOP [00:00] */
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_MASK        0x00000001
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_ALIGN       0
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_BITS        1
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_SHIFT       0
+
+
+/****************************************************************************
+ * MISC1 :: TX_DMA_ERROR_STATUS
+ ***************************************************************************/
+/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved0 [31:10] */
+#define MISC1_TX_DMA_ERROR_STATUS_reserved0_MASK                   0xfffffc00
+#define MISC1_TX_DMA_ERROR_STATUS_reserved0_ALIGN                  0
+#define MISC1_TX_DMA_ERROR_STATUS_reserved0_BITS                   22
+#define MISC1_TX_DMA_ERROR_STATUS_reserved0_SHIFT                  10
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L1_DESC_TX_ABORT_ERRORS [09:09] */
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_MASK  0x00000200
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_ALIGN 0
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_BITS  1
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_SHIFT 9
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved1 [08:08] */
+#define MISC1_TX_DMA_ERROR_STATUS_reserved1_MASK                   0x00000100
+#define MISC1_TX_DMA_ERROR_STATUS_reserved1_ALIGN                  0
+#define MISC1_TX_DMA_ERROR_STATUS_reserved1_BITS                   1
+#define MISC1_TX_DMA_ERROR_STATUS_reserved1_SHIFT                  8
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L0_DESC_TX_ABORT_ERRORS [07:07] */
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_MASK  0x00000080
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_ALIGN 0
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_BITS  1
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_SHIFT 7
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved2 [06:06] */
+#define MISC1_TX_DMA_ERROR_STATUS_reserved2_MASK                   0x00000040
+#define MISC1_TX_DMA_ERROR_STATUS_reserved2_ALIGN                  0
+#define MISC1_TX_DMA_ERROR_STATUS_reserved2_BITS                   1
+#define MISC1_TX_DMA_ERROR_STATUS_reserved2_SHIFT                  6
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L1_DMA_DATA_TX_ABORT_ERRORS [05:05] */
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_MASK 0x00000020
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_ALIGN 0
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_BITS 1
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_SHIFT 5
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L1_FIFO_FULL_ERRORS [04:04] */
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK      0x00000010
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_ALIGN     0
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_BITS      1
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_SHIFT     4
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved3 [03:03] */
+#define MISC1_TX_DMA_ERROR_STATUS_reserved3_MASK                   0x00000008
+#define MISC1_TX_DMA_ERROR_STATUS_reserved3_ALIGN                  0
+#define MISC1_TX_DMA_ERROR_STATUS_reserved3_BITS                   1
+#define MISC1_TX_DMA_ERROR_STATUS_reserved3_SHIFT                  3
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L0_DMA_DATA_TX_ABORT_ERRORS [02:02] */
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_MASK 0x00000004
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_ALIGN 0
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_BITS 1
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_SHIFT 2
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L0_FIFO_FULL_ERRORS [01:01] */
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK      0x00000002
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_ALIGN     0
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_BITS      1
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_SHIFT     1
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved4 [00:00] */
+#define MISC1_TX_DMA_ERROR_STATUS_reserved4_MASK                   0x00000001
+#define MISC1_TX_DMA_ERROR_STATUS_reserved4_ALIGN                  0
+#define MISC1_TX_DMA_ERROR_STATUS_reserved4_BITS                   1
+#define MISC1_TX_DMA_ERROR_STATUS_reserved4_SHIFT                  0
+
+
+/****************************************************************************
+ * MISC1 :: Y_RX_ERROR_STATUS
+ ***************************************************************************/
+/* MISC1 :: Y_RX_ERROR_STATUS :: reserved0 [31:14] */
+#define MISC1_Y_RX_ERROR_STATUS_reserved0_MASK                     0xffffc000
+#define MISC1_Y_RX_ERROR_STATUS_reserved0_ALIGN                    0
+#define MISC1_Y_RX_ERROR_STATUS_reserved0_BITS                     18
+#define MISC1_Y_RX_ERROR_STATUS_reserved0_SHIFT                    14
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_UNDERRUN_ERROR [13:13] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK          0x00002000
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_ALIGN         0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_BITS          1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_SHIFT         13
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_OVERRUN_ERROR [12:12] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK           0x00001000
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_ALIGN          0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_BITS           1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_SHIFT          12
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_UNDERRUN_ERROR [11:11] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK          0x00000800
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_ALIGN         0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_BITS          1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_SHIFT         11
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_OVERRUN_ERROR [10:10] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK           0x00000400
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_ALIGN          0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_BITS           1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_SHIFT          10
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_DESC_TX_ABORT_ERRORS [09:09] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK    0x00000200
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_ALIGN   0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_BITS    1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_SHIFT   9
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: reserved1 [08:08] */
+#define MISC1_Y_RX_ERROR_STATUS_reserved1_MASK                     0x00000100
+#define MISC1_Y_RX_ERROR_STATUS_reserved1_ALIGN                    0
+#define MISC1_Y_RX_ERROR_STATUS_reserved1_BITS                     1
+#define MISC1_Y_RX_ERROR_STATUS_reserved1_SHIFT                    8
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_DESC_TX_ABORT_ERRORS [07:07] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK    0x00000080
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_ALIGN   0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_BITS    1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_SHIFT   7
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: reserved2 [06:05] */
+#define MISC1_Y_RX_ERROR_STATUS_reserved2_MASK                     0x00000060
+#define MISC1_Y_RX_ERROR_STATUS_reserved2_ALIGN                    0
+#define MISC1_Y_RX_ERROR_STATUS_reserved2_BITS                     2
+#define MISC1_Y_RX_ERROR_STATUS_reserved2_SHIFT                    5
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_FIFO_FULL_ERRORS [04:04] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK        0x00000010
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_ALIGN       0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_BITS        1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_SHIFT       4
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: reserved3 [03:02] */
+#define MISC1_Y_RX_ERROR_STATUS_reserved3_MASK                     0x0000000c
+#define MISC1_Y_RX_ERROR_STATUS_reserved3_ALIGN                    0
+#define MISC1_Y_RX_ERROR_STATUS_reserved3_BITS                     2
+#define MISC1_Y_RX_ERROR_STATUS_reserved3_SHIFT                    2
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_FIFO_FULL_ERRORS [01:01] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK        0x00000002
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_ALIGN       0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_BITS        1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_SHIFT       1
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: reserved4 [00:00] */
+#define MISC1_Y_RX_ERROR_STATUS_reserved4_MASK                     0x00000001
+#define MISC1_Y_RX_ERROR_STATUS_reserved4_ALIGN                    0
+#define MISC1_Y_RX_ERROR_STATUS_reserved4_BITS                     1
+#define MISC1_Y_RX_ERROR_STATUS_reserved4_SHIFT                    0
+
+
+/****************************************************************************
+ * MISC1 :: UV_RX_ERROR_STATUS
+ ***************************************************************************/
+/* MISC1 :: UV_RX_ERROR_STATUS :: reserved0 [31:14] */
+#define MISC1_UV_RX_ERROR_STATUS_reserved0_MASK                    0xffffc000
+#define MISC1_UV_RX_ERROR_STATUS_reserved0_ALIGN                   0
+#define MISC1_UV_RX_ERROR_STATUS_reserved0_BITS                    18
+#define MISC1_UV_RX_ERROR_STATUS_reserved0_SHIFT                   14
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_UNDERRUN_ERROR [13:13] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK         0x00002000
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_ALIGN        0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_BITS         1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_SHIFT        13
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_OVERRUN_ERROR [12:12] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK          0x00001000
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_ALIGN         0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_BITS          1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_SHIFT         12
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_UNDERRUN_ERROR [11:11] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK         0x00000800
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_ALIGN        0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_BITS         1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_SHIFT        11
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_OVERRUN_ERROR [10:10] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK          0x00000400
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_ALIGN         0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_BITS          1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_SHIFT         10
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_DESC_TX_ABORT_ERRORS [09:09] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK   0x00000200
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_ALIGN  0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_BITS   1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_SHIFT  9
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: reserved1 [08:08] */
+#define MISC1_UV_RX_ERROR_STATUS_reserved1_MASK                    0x00000100
+#define MISC1_UV_RX_ERROR_STATUS_reserved1_ALIGN                   0
+#define MISC1_UV_RX_ERROR_STATUS_reserved1_BITS                    1
+#define MISC1_UV_RX_ERROR_STATUS_reserved1_SHIFT                   8
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_DESC_TX_ABORT_ERRORS [07:07] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK   0x00000080
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_ALIGN  0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_BITS   1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_SHIFT  7
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: reserved2 [06:05] */
+#define MISC1_UV_RX_ERROR_STATUS_reserved2_MASK                    0x00000060
+#define MISC1_UV_RX_ERROR_STATUS_reserved2_ALIGN                   0
+#define MISC1_UV_RX_ERROR_STATUS_reserved2_BITS                    2
+#define MISC1_UV_RX_ERROR_STATUS_reserved2_SHIFT                   5
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_FIFO_FULL_ERRORS [04:04] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK       0x00000010
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_ALIGN      0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_BITS       1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_SHIFT      4
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: reserved3 [03:02] */
+#define MISC1_UV_RX_ERROR_STATUS_reserved3_MASK                    0x0000000c
+#define MISC1_UV_RX_ERROR_STATUS_reserved3_ALIGN                   0
+#define MISC1_UV_RX_ERROR_STATUS_reserved3_BITS                    2
+#define MISC1_UV_RX_ERROR_STATUS_reserved3_SHIFT                   2
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_FIFO_FULL_ERRORS [01:01] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK       0x00000002
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_ALIGN      0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_BITS       1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_SHIFT      1
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: reserved4 [00:00] */
+#define MISC1_UV_RX_ERROR_STATUS_reserved4_MASK                    0x00000001
+#define MISC1_UV_RX_ERROR_STATUS_reserved4_ALIGN                   0
+#define MISC1_UV_RX_ERROR_STATUS_reserved4_BITS                    1
+#define MISC1_UV_RX_ERROR_STATUS_reserved4_SHIFT                   0
+
+/****************************************************************************
+ * Datatype Definitions.
+ ***************************************************************************/
+#endif /* #ifndef MACFILE_H__ */
+
+/* End of File */
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_cmds.c linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_cmds.c
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_cmds.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_cmds.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1058 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ *  Name: crystalhd_cmds . c
+ *
+ *  Description:
+ *		BCM70010 Linux driver user command interfaces.
+ *
+ *  HISTORY:
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver.  If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#include "crystalhd_cmds.h"
+#include "crystalhd_hw.h"
+
+static struct crystalhd_user *bc_cproc_get_uid(struct crystalhd_cmd *ctx)
+{
+	struct crystalhd_user *user = NULL;
+	int i;
+
+	for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
+		if (!ctx->user[i].in_use) {
+			user = &ctx->user[i];
+			break;
+		}
+	}
+
+	return user;
+}
+
+static int bc_cproc_get_user_count(struct crystalhd_cmd *ctx)
+{
+	int i, count = 0;
+
+	for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
+		if (ctx->user[i].in_use)
+			count++;
+	}
+
+	return count;
+}
+
+static void bc_cproc_mark_pwr_state(struct crystalhd_cmd *ctx)
+{
+	int i;
+
+	for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
+		if (!ctx->user[i].in_use)
+			continue;
+		if (ctx->user[i].mode == DTS_DIAG_MODE ||
+		    ctx->user[i].mode == DTS_PLAYBACK_MODE) {
+			ctx->pwr_state_change = 1;
+			break;
+		}
+	}
+}
+
+static BC_STATUS bc_cproc_notify_mode(struct crystalhd_cmd *ctx,
+				      crystalhd_ioctl_data *idata)
+{
+	int rc = 0, i = 0;
+
+	if (!ctx || !idata) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return BC_STS_INV_ARG;
+	}
+
+	if (ctx->user[idata->u_id].mode != DTS_MODE_INV) {
+		BCMLOG_ERR("Close the handle first..\n");
+		return BC_STS_ERR_USAGE;
+	}
+	if (idata->udata.u.NotifyMode.Mode == DTS_MONITOR_MODE) {
+		ctx->user[idata->u_id].mode = idata->udata.u.NotifyMode.Mode;
+		return BC_STS_SUCCESS;
+	}
+	if (ctx->state != BC_LINK_INVALID) {
+		BCMLOG_ERR("Link invalid state %d \n", ctx->state);
+		return BC_STS_ERR_USAGE;
+	}
+	/* Check for duplicate playback sessions..*/
+	for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
+		if (ctx->user[i].mode == DTS_DIAG_MODE ||
+		    ctx->user[i].mode == DTS_PLAYBACK_MODE) {
+			BCMLOG_ERR("multiple playback sessions are not "
+				   "supported..\n");
+			return BC_STS_ERR_USAGE;
+		}
+	}
+	ctx->cin_wait_exit = 0;
+	ctx->user[idata->u_id].mode = idata->udata.u.NotifyMode.Mode;
+	/* Setup mmap pool for uaddr sgl mapping..*/
+	rc = crystalhd_create_dio_pool(ctx->adp, BC_LINK_MAX_SGLS);
+	if (rc)
+		return BC_STS_ERROR;
+
+	/* Setup Hardware DMA rings */
+	return crystalhd_hw_setup_dma_rings(&ctx->hw_ctx);
+}
+
+static BC_STATUS bc_cproc_get_version(struct crystalhd_cmd *ctx,
+				      crystalhd_ioctl_data *idata)
+{
+
+	if (!ctx || !idata) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return BC_STS_INV_ARG;
+	}
+	idata->udata.u.VerInfo.DriverMajor = crystalhd_kmod_major;
+	idata->udata.u.VerInfo.DriverMinor = crystalhd_kmod_minor;
+	idata->udata.u.VerInfo.DriverRevision	= crystalhd_kmod_rev;
+	return BC_STS_SUCCESS;
+}
+
+
+static BC_STATUS bc_cproc_get_hwtype(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata)
+{
+	if (!ctx || !idata) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return BC_STS_INV_ARG;
+	}
+
+	crystalhd_pci_cfg_rd(ctx->adp, 0, 2,
+			   (uint32_t *)&idata->udata.u.hwType.PciVenId);
+	crystalhd_pci_cfg_rd(ctx->adp, 2, 2,
+			   (uint32_t *)&idata->udata.u.hwType.PciDevId);
+	crystalhd_pci_cfg_rd(ctx->adp, 8, 1,
+			   (uint32_t *)&idata->udata.u.hwType.HwRev);
+
+	return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_reg_rd(struct crystalhd_cmd *ctx,
+				 crystalhd_ioctl_data *idata)
+{
+	if (!ctx || !idata)
+		return BC_STS_INV_ARG;
+	idata->udata.u.regAcc.Value = bc_dec_reg_rd(ctx->adp,
+					idata->udata.u.regAcc.Offset);
+	return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_reg_wr(struct crystalhd_cmd *ctx,
+				 crystalhd_ioctl_data *idata)
+{
+	if (!ctx || !idata)
+		return BC_STS_INV_ARG;
+
+	bc_dec_reg_wr(ctx->adp, idata->udata.u.regAcc.Offset,
+		      idata->udata.u.regAcc.Value);
+
+	return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_link_reg_rd(struct crystalhd_cmd *ctx,
+				      crystalhd_ioctl_data *idata)
+{
+	if (!ctx || !idata)
+		return BC_STS_INV_ARG;
+
+	idata->udata.u.regAcc.Value = crystalhd_reg_rd(ctx->adp,
+					idata->udata.u.regAcc.Offset);
+	return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_link_reg_wr(struct crystalhd_cmd *ctx,
+				      crystalhd_ioctl_data *idata)
+{
+	if (!ctx || !idata)
+		return BC_STS_INV_ARG;
+
+	crystalhd_reg_wr(ctx->adp, idata->udata.u.regAcc.Offset,
+		       idata->udata.u.regAcc.Value);
+
+	return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_mem_rd(struct crystalhd_cmd *ctx,
+				 crystalhd_ioctl_data *idata)
+{
+	BC_STATUS sts = BC_STS_SUCCESS;
+
+	if (!ctx || !idata || !idata->add_cdata)
+		return BC_STS_INV_ARG;
+
+	if (idata->udata.u.devMem.NumDwords > (idata->add_cdata_sz / 4)) {
+		BCMLOG_ERR("insufficient buffer\n");
+		return BC_STS_INV_ARG;
+	}
+	sts = crystalhd_mem_rd(ctx->adp, idata->udata.u.devMem.StartOff,
+			     idata->udata.u.devMem.NumDwords,
+			     (uint32_t *)idata->add_cdata);
+	return sts;
+
+}
+
+static BC_STATUS bc_cproc_mem_wr(struct crystalhd_cmd *ctx,
+				 crystalhd_ioctl_data *idata)
+{
+	BC_STATUS sts = BC_STS_SUCCESS;
+
+	if (!ctx || !idata || !idata->add_cdata)
+		return BC_STS_INV_ARG;
+
+	if (idata->udata.u.devMem.NumDwords > (idata->add_cdata_sz / 4)) {
+		BCMLOG_ERR("insufficient buffer\n");
+		return BC_STS_INV_ARG;
+	}
+
+	sts = crystalhd_mem_wr(ctx->adp, idata->udata.u.devMem.StartOff,
+			     idata->udata.u.devMem.NumDwords,
+			     (uint32_t *)idata->add_cdata);
+	return sts;
+}
+
+static BC_STATUS bc_cproc_cfg_rd(struct crystalhd_cmd *ctx,
+				 crystalhd_ioctl_data *idata)
+{
+	uint32_t ix, cnt, off, len;
+	BC_STATUS sts = BC_STS_SUCCESS;
+	uint32_t *temp;
+
+	if (!ctx || !idata)
+		return BC_STS_INV_ARG;
+
+	temp = (uint32_t *) idata->udata.u.pciCfg.pci_cfg_space;
+	off = idata->udata.u.pciCfg.Offset;
+	len = idata->udata.u.pciCfg.Size;
+
+	if (len <= 4)
+		return crystalhd_pci_cfg_rd(ctx->adp, off, len, temp);
+
+	/* Truncate to dword alignment..*/
+	len = 4;
+	cnt = idata->udata.u.pciCfg.Size / len;
+	for (ix = 0; ix < cnt; ix++) {
+		sts = crystalhd_pci_cfg_rd(ctx->adp, off, len, &temp[ix]);
+		if (sts != BC_STS_SUCCESS) {
+			BCMLOG_ERR("config read : %d\n", sts);
+			return sts;
+		}
+		off += len;
+	}
+
+	return sts;
+}
+
+static BC_STATUS bc_cproc_cfg_wr(struct crystalhd_cmd *ctx,
+				 crystalhd_ioctl_data *idata)
+{
+	uint32_t ix, cnt, off, len;
+	BC_STATUS sts = BC_STS_SUCCESS;
+	uint32_t *temp;
+
+	if (!ctx || !idata)
+		return BC_STS_INV_ARG;
+
+	temp = (uint32_t *) idata->udata.u.pciCfg.pci_cfg_space;
+	off = idata->udata.u.pciCfg.Offset;
+	len = idata->udata.u.pciCfg.Size;
+
+	if (len <= 4)
+		return crystalhd_pci_cfg_wr(ctx->adp, off, len, temp[0]);
+
+	/* Truncate to dword alignment..*/
+	len = 4;
+	cnt = idata->udata.u.pciCfg.Size / len;
+	for (ix = 0; ix < cnt; ix++) {
+		sts = crystalhd_pci_cfg_wr(ctx->adp, off, len, temp[ix]);
+		if (sts != BC_STS_SUCCESS) {
+			BCMLOG_ERR("config write : %d\n", sts);
+			return sts;
+		}
+		off += len;
+	}
+
+	return sts;
+}
+
+static BC_STATUS bc_cproc_download_fw(struct crystalhd_cmd *ctx,
+				      crystalhd_ioctl_data *idata)
+{
+	BC_STATUS sts = BC_STS_SUCCESS;
+
+	if (!ctx || !idata || !idata->add_cdata || !idata->add_cdata_sz) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return BC_STS_INV_ARG;
+	}
+
+	if (ctx->state != BC_LINK_INVALID) {
+		BCMLOG_ERR("Link invalid state %d \n", ctx->state);
+		return BC_STS_ERR_USAGE;
+	}
+
+	sts = crystalhd_download_fw(ctx->adp, (uint8_t *)idata->add_cdata,
+				  idata->add_cdata_sz);
+
+	if (sts != BC_STS_SUCCESS) {
+		BCMLOG_ERR("Firmware Download Failure!! - %d\n", sts);
+	} else
+		ctx->state |= BC_LINK_INIT;
+
+	return sts;
+}
+
+/*
+ * We use the FW_CMD interface to sync up playback state with application
+ * and  firmware. This function will perform the required pre and post
+ * processing of the Firmware commands.
+ *
+ * Pause -
+ *	Disable capture after decoder pause.
+ * Resume -
+ *	First enable capture and issue decoder resume command.
+ * Flush -
+ *	Abort pending input transfers and issue decoder flush command.
+ *
+ */
+static BC_STATUS bc_cproc_do_fw_cmd(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata)
+{
+	BC_STATUS sts;
+	uint32_t *cmd;
+
+	if (!(ctx->state & BC_LINK_INIT)) {
+		BCMLOG_ERR("Link invalid state %d \n", ctx->state);
+		return BC_STS_ERR_USAGE;
+	}
+
+	cmd = idata->udata.u.fwCmd.cmd;
+
+	/* Pre-Process */
+	if (cmd[0] == eCMD_C011_DEC_CHAN_PAUSE) {
+		if (!cmd[3]) {
+			ctx->state &= ~BC_LINK_PAUSED;
+			crystalhd_hw_unpause(&ctx->hw_ctx);
+		}
+	} else if (cmd[0] == eCMD_C011_DEC_CHAN_FLUSH) {
+		BCMLOG(BCMLOG_INFO, "Flush issued\n");
+		if (cmd[3])
+			ctx->cin_wait_exit = 1;
+	}
+
+	sts = crystalhd_do_fw_cmd(&ctx->hw_ctx, &idata->udata.u.fwCmd);
+
+	if (sts != BC_STS_SUCCESS) {
+		BCMLOG(BCMLOG_INFO, "fw cmd %x failed\n", cmd[0]);
+		return sts;
+	}
+
+	/* Post-Process */
+	if (cmd[0] == eCMD_C011_DEC_CHAN_PAUSE) {
+		if (cmd[3]) {
+			ctx->state |= BC_LINK_PAUSED;
+			crystalhd_hw_pause(&ctx->hw_ctx);
+		}
+	}
+
+	return sts;
+}
+
+static void bc_proc_in_completion(crystalhd_dio_req *dio_hnd,
+				  wait_queue_head_t *event, BC_STATUS sts)
+{
+	if (!dio_hnd || !event) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return;
+	}
+	if (sts == BC_STS_IO_USER_ABORT)
+		 return;
+
+	dio_hnd->uinfo.comp_sts = sts;
+	dio_hnd->uinfo.ev_sts = 1;
+	crystalhd_set_event(event);
+}
+
+static BC_STATUS bc_cproc_codein_sleep(struct crystalhd_cmd *ctx)
+{
+	wait_queue_head_t sleep_ev;
+	int rc = 0;
+
+	if (ctx->state & BC_LINK_SUSPEND)
+		return BC_STS_IO_USER_ABORT;
+
+	if (ctx->cin_wait_exit) {
+		ctx->cin_wait_exit = 0;
+		return BC_STS_CMD_CANCELLED;
+	}
+	crystalhd_create_event(&sleep_ev);
+	crystalhd_wait_on_event(&sleep_ev, 0, 100, rc, 0);
+	if (rc == -EINTR)
+		return BC_STS_IO_USER_ABORT;
+
+	return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_hw_txdma(struct crystalhd_cmd *ctx,
+				   crystalhd_ioctl_data *idata,
+				   crystalhd_dio_req *dio)
+{
+	uint32_t tx_listid = 0;
+	BC_STATUS sts = BC_STS_SUCCESS;
+	wait_queue_head_t event;
+	int rc = 0;
+
+	if (!ctx || !idata || !dio) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return BC_STS_INV_ARG;
+	}
+
+	crystalhd_create_event(&event);
+
+	ctx->tx_list_id = 0;
+	/* msleep_interruptible(2000); */
+	sts = crystalhd_hw_post_tx(&ctx->hw_ctx, dio, bc_proc_in_completion,
+				 &event, &tx_listid,
+				 idata->udata.u.ProcInput.Encrypted);
+
+	while (sts == BC_STS_BUSY) {
+		sts = bc_cproc_codein_sleep(ctx);
+		if (sts != BC_STS_SUCCESS)
+			break;
+		sts = crystalhd_hw_post_tx(&ctx->hw_ctx, dio,
+					 bc_proc_in_completion,
+					 &event, &tx_listid,
+					 idata->udata.u.ProcInput.Encrypted);
+	}
+	if (sts != BC_STS_SUCCESS) {
+		BCMLOG(BCMLOG_DBG, "_hw_txdma returning sts:%d\n", sts);
+		return sts;
+	}
+	if (ctx->cin_wait_exit)
+		ctx->cin_wait_exit = 0;
+
+	ctx->tx_list_id = tx_listid;
+
+	/* _post() succeeded.. wait for the completion. */
+	crystalhd_wait_on_event(&event, (dio->uinfo.ev_sts), 3000, rc, 0);
+	ctx->tx_list_id = 0;
+	if (!rc) {
+		return dio->uinfo.comp_sts;
+	} else if (rc == -EBUSY) {
+		BCMLOG(BCMLOG_DBG, "_tx_post() T/O \n");
+		sts = BC_STS_TIMEOUT;
+	} else if (rc == -EINTR) {
+		BCMLOG(BCMLOG_DBG, "Tx Wait Signal int.\n");
+		sts = BC_STS_IO_USER_ABORT;
+	} else {
+		sts = BC_STS_IO_ERROR;
+	}
+
+	/* We are cancelling the IO from the same context as the _post().
+	 * so no need to wait on the event again.. the return itself
+	 * ensures the release of our resources.
+	 */
+	crystalhd_hw_cancel_tx(&ctx->hw_ctx, tx_listid);
+
+	return sts;
+}
+
+/* Helper function to check on user buffers */
+static BC_STATUS bc_cproc_check_inbuffs(bool pin, void *ubuff, uint32_t ub_sz,
+					uint32_t uv_off, bool en_422)
+{
+	if (!ubuff || !ub_sz) {
+		BCMLOG_ERR("%s->Invalid Arg %p %x\n",
+			((pin) ? "TX" : "RX"), ubuff, ub_sz);
+		return BC_STS_INV_ARG;
+	}
+
+	/* Check for alignment */
+	if (((uintptr_t)ubuff) & 0x03) {
+		BCMLOG_ERR("%s-->Un-aligned address not implemented yet.. %p \n",
+				((pin) ? "TX" : "RX"), ubuff);
+		return BC_STS_NOT_IMPL;
+	}
+	if (pin)
+		return BC_STS_SUCCESS;
+
+	if (!en_422 && !uv_off) {
+		BCMLOG_ERR("Need UV offset for 420 mode.\n");
+		return BC_STS_INV_ARG;
+	}
+
+	if (en_422 && uv_off) {
+		BCMLOG_ERR("UV offset in 422 mode ??\n");
+		return BC_STS_INV_ARG;
+	}
+
+	return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_proc_input(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata)
+{
+	void *ubuff;
+	uint32_t ub_sz;
+	crystalhd_dio_req *dio_hnd = NULL;
+	BC_STATUS sts = BC_STS_SUCCESS;
+
+	if (!ctx || !idata) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return BC_STS_INV_ARG;
+	}
+
+	ubuff = idata->udata.u.ProcInput.pDmaBuff;
+	ub_sz = idata->udata.u.ProcInput.BuffSz;
+
+	sts = bc_cproc_check_inbuffs(1, ubuff, ub_sz, 0, 0);
+	if (sts != BC_STS_SUCCESS)
+		return sts;
+
+	sts = crystalhd_map_dio(ctx->adp, ubuff, ub_sz, 0, 0, 1, &dio_hnd);
+	if (sts != BC_STS_SUCCESS) {
+		BCMLOG_ERR("dio map - %d \n", sts);
+		return sts;
+	}
+
+	if (!dio_hnd)
+		return BC_STS_ERROR;
+
+	sts = bc_cproc_hw_txdma(ctx, idata, dio_hnd);
+
+	crystalhd_unmap_dio(ctx->adp, dio_hnd);
+
+	return sts;
+}
+
+static BC_STATUS bc_cproc_add_cap_buff(struct crystalhd_cmd *ctx,
+				       crystalhd_ioctl_data *idata)
+{
+	void *ubuff;
+	uint32_t ub_sz, uv_off;
+	bool en_422;
+	crystalhd_dio_req *dio_hnd = NULL;
+	BC_STATUS sts = BC_STS_SUCCESS;
+
+	if (!ctx || !idata) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return BC_STS_INV_ARG;
+	}
+
+	ubuff = idata->udata.u.RxBuffs.YuvBuff;
+	ub_sz = idata->udata.u.RxBuffs.YuvBuffSz;
+	uv_off = idata->udata.u.RxBuffs.UVbuffOffset;
+	en_422 = idata->udata.u.RxBuffs.b422Mode;
+
+	sts = bc_cproc_check_inbuffs(0, ubuff, ub_sz, uv_off, en_422);
+	if (sts != BC_STS_SUCCESS)
+		return sts;
+
+	sts = crystalhd_map_dio(ctx->adp, ubuff, ub_sz, uv_off,
+			      en_422, 0, &dio_hnd);
+	if (sts != BC_STS_SUCCESS) {
+		BCMLOG_ERR("dio map - %d \n", sts);
+		return sts;
+	}
+
+	if (!dio_hnd)
+		return BC_STS_ERROR;
+
+	sts = crystalhd_hw_add_cap_buffer(&ctx->hw_ctx, dio_hnd, (ctx->state == BC_LINK_READY));
+	if ((sts != BC_STS_SUCCESS) && (sts != BC_STS_BUSY)) {
+		crystalhd_unmap_dio(ctx->adp, dio_hnd);
+		return sts;
+	}
+
+	return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_fmt_change(struct crystalhd_cmd *ctx,
+				     crystalhd_dio_req *dio)
+{
+	BC_STATUS sts = BC_STS_SUCCESS;
+
+	sts = crystalhd_hw_add_cap_buffer(&ctx->hw_ctx, dio, 0);
+	if (sts != BC_STS_SUCCESS)
+		return sts;
+
+	ctx->state |= BC_LINK_FMT_CHG;
+	if (ctx->state == BC_LINK_READY)
+		sts = crystalhd_hw_start_capture(&ctx->hw_ctx);
+
+	return sts;
+}
+
+static BC_STATUS bc_cproc_fetch_frame(struct crystalhd_cmd *ctx,
+				      crystalhd_ioctl_data *idata)
+{
+	crystalhd_dio_req *dio = NULL;
+	BC_STATUS sts = BC_STS_SUCCESS;
+	BC_DEC_OUT_BUFF *frame;
+
+	if (!ctx || !idata) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return BC_STS_INV_ARG;
+	}
+
+	if (!(ctx->state & BC_LINK_CAP_EN)) {
+		BCMLOG(BCMLOG_DBG, "Capture not enabled..%x\n", ctx->state);
+		return BC_STS_ERR_USAGE;
+	}
+
+	frame = &idata->udata.u.DecOutData;
+
+	sts = crystalhd_hw_get_cap_buffer(&ctx->hw_ctx, &frame->PibInfo, &dio);
+	if (sts != BC_STS_SUCCESS)
+		return (ctx->state & BC_LINK_SUSPEND) ? BC_STS_IO_USER_ABORT : sts;
+
+	frame->Flags = dio->uinfo.comp_flags;
+
+	if (frame->Flags & COMP_FLAG_FMT_CHANGE)
+		return bc_cproc_fmt_change(ctx, dio);
+
+	frame->OutPutBuffs.YuvBuff = dio->uinfo.xfr_buff;
+	frame->OutPutBuffs.YuvBuffSz = dio->uinfo.xfr_len;
+	frame->OutPutBuffs.UVbuffOffset = dio->uinfo.uv_offset;
+	frame->OutPutBuffs.b422Mode = dio->uinfo.b422mode;
+
+	frame->OutPutBuffs.YBuffDoneSz = dio->uinfo.y_done_sz;
+	frame->OutPutBuffs.UVBuffDoneSz = dio->uinfo.uv_done_sz;
+
+	crystalhd_unmap_dio(ctx->adp, dio);
+
+	return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_start_capture(struct crystalhd_cmd *ctx,
+					crystalhd_ioctl_data *idata)
+{
+	ctx->state |= BC_LINK_CAP_EN;
+	if (ctx->state == BC_LINK_READY)
+		return crystalhd_hw_start_capture(&ctx->hw_ctx);
+
+	return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_flush_cap_buffs(struct crystalhd_cmd *ctx,
+					  crystalhd_ioctl_data *idata)
+{
+	crystalhd_dio_req *dio = NULL;
+	BC_STATUS sts = BC_STS_SUCCESS;
+	BC_DEC_OUT_BUFF *frame;
+	uint32_t count;
+
+	if (!ctx || !idata) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return BC_STS_INV_ARG;
+	}
+
+	if (!(ctx->state & BC_LINK_CAP_EN))
+		return BC_STS_ERR_USAGE;
+
+	/* We should ack flush even when we are in paused/suspend state */
+	if (!(ctx->state & BC_LINK_READY))
+		return crystalhd_hw_stop_capture(&ctx->hw_ctx);
+
+	ctx->state &= ~(BC_LINK_CAP_EN|BC_LINK_FMT_CHG);
+
+	frame = &idata->udata.u.DecOutData;
+	for (count = 0; count < BC_RX_LIST_CNT; count++) {
+
+		sts = crystalhd_hw_get_cap_buffer(&ctx->hw_ctx, &frame->PibInfo, &dio);
+		if (sts != BC_STS_SUCCESS)
+			break;
+
+		crystalhd_unmap_dio(ctx->adp, dio);
+	}
+
+	return crystalhd_hw_stop_capture(&ctx->hw_ctx);
+}
+
+static BC_STATUS bc_cproc_get_stats(struct crystalhd_cmd *ctx,
+				    crystalhd_ioctl_data *idata)
+{
+	BC_DTS_STATS *stats;
+	struct crystalhd_hw_stats	hw_stats;
+
+	if (!ctx || !idata) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return BC_STS_INV_ARG;
+	}
+
+	crystalhd_hw_stats(&ctx->hw_ctx, &hw_stats);
+
+	stats = &idata->udata.u.drvStat;
+	stats->drvRLL = hw_stats.rdyq_count;
+	stats->drvFLL = hw_stats.freeq_count;
+	stats->DrvTotalFrmDropped = hw_stats.rx_errors;
+	stats->DrvTotalHWErrs = hw_stats.rx_errors + hw_stats.tx_errors;
+	stats->intCount = hw_stats.num_interrupts;
+	stats->DrvIgnIntrCnt = hw_stats.num_interrupts -
+				hw_stats.dev_interrupts;
+	stats->TxFifoBsyCnt = hw_stats.cin_busy;
+	stats->pauseCount = hw_stats.pause_cnt;
+
+	if (ctx->pwr_state_change)
+		stats->pwr_state_change = 1;
+	if (ctx->state & BC_LINK_PAUSED)
+		stats->DrvPauseTime = 1;
+
+	return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_reset_stats(struct crystalhd_cmd *ctx,
+				      crystalhd_ioctl_data *idata)
+{
+	crystalhd_hw_stats(&ctx->hw_ctx, NULL);
+
+	return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_chg_clk(struct crystalhd_cmd *ctx,
+				  crystalhd_ioctl_data *idata)
+{
+	BC_CLOCK *clock;
+	uint32_t oldClk;
+	BC_STATUS sts = BC_STS_SUCCESS;
+
+	if (!ctx || !idata) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return BC_STS_INV_ARG;
+	}
+
+	clock = &idata->udata.u.clockValue;
+	oldClk = ctx->hw_ctx.core_clock_mhz;
+	ctx->hw_ctx.core_clock_mhz = clock->clk;
+
+	if (ctx->state & BC_LINK_READY) {
+		sts = crystalhd_hw_set_core_clock(&ctx->hw_ctx);
+		if (sts == BC_STS_CLK_NOCHG)
+			ctx->hw_ctx.core_clock_mhz = oldClk;
+	}
+
+	clock->clk = ctx->hw_ctx.core_clock_mhz;
+
+	return sts;
+}
+
+/*=============== Cmd Proc Table.. ======================================*/
+static const crystalhd_cmd_tbl_t	g_crystalhd_cproc_tbl[] = {
+	{ BCM_IOC_GET_VERSION,		bc_cproc_get_version,	0},
+	{ BCM_IOC_GET_HWTYPE,		bc_cproc_get_hwtype,	0},
+	{ BCM_IOC_REG_RD,		bc_cproc_reg_rd,	0},
+	{ BCM_IOC_REG_WR,		bc_cproc_reg_wr,	0},
+	{ BCM_IOC_FPGA_RD,		bc_cproc_link_reg_rd,	0},
+	{ BCM_IOC_FPGA_WR,		bc_cproc_link_reg_wr,	0},
+	{ BCM_IOC_MEM_RD,		bc_cproc_mem_rd,	0},
+	{ BCM_IOC_MEM_WR,		bc_cproc_mem_wr,	0},
+	{ BCM_IOC_RD_PCI_CFG,		bc_cproc_cfg_rd,	0},
+	{ BCM_IOC_WR_PCI_CFG,		bc_cproc_cfg_wr,	1},
+	{ BCM_IOC_FW_DOWNLOAD,		bc_cproc_download_fw,	1},
+	{ BCM_IOC_FW_CMD,		bc_cproc_do_fw_cmd,	1},
+	{ BCM_IOC_PROC_INPUT,		bc_cproc_proc_input,	1},
+	{ BCM_IOC_ADD_RXBUFFS,		bc_cproc_add_cap_buff,	1},
+	{ BCM_IOC_FETCH_RXBUFF,		bc_cproc_fetch_frame,	1},
+	{ BCM_IOC_START_RX_CAP,		bc_cproc_start_capture,	1},
+	{ BCM_IOC_FLUSH_RX_CAP,		bc_cproc_flush_cap_buffs, 1},
+	{ BCM_IOC_GET_DRV_STAT,		bc_cproc_get_stats,	0},
+	{ BCM_IOC_RST_DRV_STAT,		bc_cproc_reset_stats,	0},
+	{ BCM_IOC_NOTIFY_MODE,		bc_cproc_notify_mode,	0},
+	{ BCM_IOC_CHG_CLK,		bc_cproc_chg_clk, 0},
+	{ BCM_IOC_END,			NULL},
+};
+
+/*=============== Cmd Proc Functions.. ===================================*/
+
+/**
+ * crystalhd_suspend - Power management suspend request.
+ * @ctx: Command layer context.
+ * @idata: Iodata - required for internal use.
+ *
+ * Return:
+ *	status
+ *
+ * 1. Set the state to Suspend.
+ * 2. Flush the Rx Buffers it will unmap all the buffers and
+ *    stop the RxDMA engine.
+ * 3. Cancel The TX Io and Stop Dma Engine.
+ * 4. Put the DDR in to deep sleep.
+ * 5. Stop the hardware putting it in to Reset State.
+ *
+ * Current gstreamer frame work does not provide any power management
+ * related notification to user mode decoder plug-in. As a work-around
+ * we pass on the power mangement notification to our plug-in by completing
+ * all outstanding requests with BC_STS_IO_USER_ABORT return code.
+ */
+BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata)
+{
+	BC_STATUS sts = BC_STS_SUCCESS;
+
+	if (!ctx || !idata) {
+		BCMLOG_ERR("Invalid Parameters\n");
+		return BC_STS_ERROR;
+	}
+
+	if (ctx->state & BC_LINK_SUSPEND)
+		return BC_STS_SUCCESS;
+
+	if (ctx->state == BC_LINK_INVALID) {
+		BCMLOG(BCMLOG_DBG, "Nothing To Do Suspend Success\n");
+		return BC_STS_SUCCESS;
+	}
+
+	ctx->state |= BC_LINK_SUSPEND;
+
+	bc_cproc_mark_pwr_state(ctx);
+
+	if (ctx->state & BC_LINK_CAP_EN) {
+		sts = bc_cproc_flush_cap_buffs(ctx, idata);
+		if (sts != BC_STS_SUCCESS)
+			return sts;
+	}
+
+	if (ctx->tx_list_id) {
+		sts = crystalhd_hw_cancel_tx(&ctx->hw_ctx, ctx->tx_list_id);
+		if (sts != BC_STS_SUCCESS)
+			return sts;
+	}
+
+	sts = crystalhd_hw_suspend(&ctx->hw_ctx);
+	if (sts != BC_STS_SUCCESS)
+		return sts;
+
+	BCMLOG(BCMLOG_DBG, "BCM70012 suspend success\n");
+
+	return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_resume - Resume frame capture.
+ * @ctx: Command layer contextx.
+ *
+ * Return:
+ *	status
+ *
+ *
+ * Resume frame capture.
+ *
+ * PM_Resume can't resume the playback state back to pre-suspend state
+ * because we don't keep video clip related information within driver.
+ * To get back to the pre-suspend state App will re-open the device and
+ * start a new playback session from the pre-suspend clip position.
+ *
+ */
+BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx)
+{
+	BCMLOG(BCMLOG_DBG, "crystalhd_resume Success %x\n", ctx->state);
+
+	bc_cproc_mark_pwr_state(ctx);
+
+	return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_user_open - Create application handle.
+ * @ctx: Command layer contextx.
+ * @user_ctx: User ID context.
+ *
+ * Return:
+ *	status
+ *
+ * Creates an application specific UID and allocates
+ * application specific resources. HW layer initialization
+ * is done for the first open request.
+ */
+BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx,
+			    struct crystalhd_user **user_ctx)
+{
+	struct crystalhd_user *uc;
+
+	if (!ctx || !user_ctx) {
+		BCMLOG_ERR("Invalid arg..\n");
+		return BC_STS_INV_ARG;
+	}
+
+	uc = bc_cproc_get_uid(ctx);
+	if (!uc) {
+		BCMLOG(BCMLOG_INFO, "No free user context...\n");
+		return BC_STS_BUSY;
+	}
+
+	BCMLOG(BCMLOG_INFO, "Opening new user[%x] handle\n", uc->uid);
+
+	crystalhd_hw_open(&ctx->hw_ctx, ctx->adp);
+
+	uc->in_use = 1;
+
+	*user_ctx = uc;
+
+	return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_user_close - Close application handle.
+ * @ctx: Command layer contextx.
+ * @uc: User ID context.
+ *
+ * Return:
+ *	status
+ *
+ * Closer aplication handle and release app specific
+ * resources.
+ */
+BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc)
+{
+	uint32_t mode = uc->mode;
+
+	ctx->user[uc->uid].mode = DTS_MODE_INV;
+	ctx->user[uc->uid].in_use = 0;
+	ctx->cin_wait_exit = 1;
+	ctx->pwr_state_change = 0;
+
+	BCMLOG(BCMLOG_INFO, "Closing user[%x] handle\n", uc->uid);
+
+	if ((mode == DTS_DIAG_MODE) || (mode == DTS_PLAYBACK_MODE)) {
+		crystalhd_hw_free_dma_rings(&ctx->hw_ctx);
+		crystalhd_destroy_dio_pool(ctx->adp);
+	} else if (bc_cproc_get_user_count(ctx)) {
+		return BC_STS_SUCCESS;
+	}
+
+	crystalhd_hw_close(&ctx->hw_ctx);
+
+	ctx->state = BC_LINK_INVALID;
+
+	return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_setup_cmd_context - Setup Command layer resources.
+ * @ctx: Command layer contextx.
+ * @adp: Adapter context
+ *
+ * Return:
+ *	status
+ *
+ * Called at the time of driver load.
+ */
+BC_STATUS __devinit crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx,
+				    struct crystalhd_adp *adp)
+{
+	int i = 0;
+
+	if (!ctx || !adp) {
+		BCMLOG_ERR("Invalid arg!!\n");
+		return BC_STS_INV_ARG;
+	}
+
+	if (ctx->adp)
+		BCMLOG(BCMLOG_DBG, "Resetting Cmd context delete missing..\n");
+
+	ctx->adp = adp;
+	for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
+		ctx->user[i].uid = i;
+		ctx->user[i].in_use = 0;
+		ctx->user[i].mode = DTS_MODE_INV;
+	}
+
+	/*Open and Close the Hardware to put it in to sleep state*/
+	crystalhd_hw_open(&ctx->hw_ctx, ctx->adp);
+	crystalhd_hw_close(&ctx->hw_ctx);
+	return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_delete_cmd_context - Release Command layer resources.
+ * @ctx: Command layer contextx.
+ *
+ * Return:
+ *	status
+ *
+ * Called at the time of driver un-load.
+ */
+BC_STATUS __devexit crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx)
+{
+	BCMLOG(BCMLOG_DBG, "Deleting Command context..\n");
+
+	ctx->adp = NULL;
+
+	return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_get_cmd_proc  - Cproc table lookup.
+ * @ctx: Command layer contextx.
+ * @cmd: IOCTL command code.
+ * @uc: User ID context.
+ *
+ * Return:
+ *	command proc function pointer
+ *
+ * This function checks the process context, application's
+ * mode of operation and returns the function pointer
+ * from the cproc table.
+ */
+crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cmd,
+				      struct crystalhd_user *uc)
+{
+	crystalhd_cmd_proc cproc = NULL;
+	unsigned int i, tbl_sz;
+
+	if (!ctx) {
+		BCMLOG_ERR("Invalid arg.. Cmd[%d]\n", cmd);
+		return NULL;
+	}
+
+	if ((cmd != BCM_IOC_GET_DRV_STAT) && (ctx->state & BC_LINK_SUSPEND)) {
+		BCMLOG_ERR("Invalid State [suspend Set].. Cmd[%d]\n", cmd);
+		return NULL;
+	}
+
+	tbl_sz = sizeof(g_crystalhd_cproc_tbl) / sizeof(crystalhd_cmd_tbl_t);
+	for (i = 0; i < tbl_sz; i++) {
+		if (g_crystalhd_cproc_tbl[i].cmd_id == cmd) {
+			if ((uc->mode == DTS_MONITOR_MODE) &&
+			    (g_crystalhd_cproc_tbl[i].block_mon)) {
+				BCMLOG(BCMLOG_INFO, "Blocking cmd %d \n", cmd);
+				break;
+			}
+			cproc = g_crystalhd_cproc_tbl[i].cmd_proc;
+			break;
+		}
+	}
+
+	return cproc;
+}
+
+/**
+ * crystalhd_cmd_interrupt - ISR entry point
+ * @ctx: Command layer contextx.
+ *
+ * Return:
+ *	TRUE: If interrupt from bcm70012 device.
+ *
+ *
+ * ISR entry point from OS layer.
+ */
+bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx)
+{
+	if (!ctx) {
+		BCMLOG_ERR("Invalid arg..\n");
+		return 0;
+	}
+
+	return crystalhd_hw_interrupt(ctx->adp, &ctx->hw_ctx);
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_cmds.h linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_cmds.h
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_cmds.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_cmds.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,88 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ *  Name: crystalhd_cmds . h
+ *
+ *  Description:
+ *		BCM70010 Linux driver user command interfaces.
+ *
+ *  HISTORY:
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver.  If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#ifndef _CRYSTALHD_CMDS_H_
+#define _CRYSTALHD_CMDS_H_
+
+/*
+ * NOTE:: This is the main interface file between the Linux layer
+ *        and the harware layer. This file will use the definitions
+ *        from _dts_glob and dts_defs etc.. which are defined for
+ *        windows.
+ */
+#include "crystalhd_misc.h"
+#include "crystalhd_hw.h"
+
+enum _crystalhd_state{
+	BC_LINK_INVALID		= 0x00,
+	BC_LINK_INIT		= 0x01,
+	BC_LINK_CAP_EN		= 0x02,
+	BC_LINK_FMT_CHG		= 0x04,
+	BC_LINK_SUSPEND		= 0x10,
+	BC_LINK_PAUSED		= 0x20,
+	BC_LINK_READY	= (BC_LINK_INIT | BC_LINK_CAP_EN | BC_LINK_FMT_CHG),
+};
+
+struct crystalhd_user {
+	uint32_t	uid;
+	uint32_t	in_use;
+	uint32_t	mode;
+};
+
+#define DTS_MODE_INV	(-1)
+
+struct crystalhd_cmd {
+	uint32_t		state;
+	struct crystalhd_adp	*adp;
+	struct crystalhd_user	user[BC_LINK_MAX_OPENS];
+
+	spinlock_t		ctx_lock;
+	uint32_t		tx_list_id;
+	uint32_t		cin_wait_exit;
+	uint32_t		pwr_state_change;
+	struct crystalhd_hw	hw_ctx;
+};
+
+typedef BC_STATUS (*crystalhd_cmd_proc)(struct crystalhd_cmd *, crystalhd_ioctl_data *);
+
+typedef struct _crystalhd_cmd_tbl {
+	uint32_t		cmd_id;
+	const crystalhd_cmd_proc	cmd_proc;
+	uint32_t		block_mon;
+} crystalhd_cmd_tbl_t;
+
+
+BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata);
+BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx);
+crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cmd,
+				      struct crystalhd_user *uc);
+BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx, struct crystalhd_user **user_ctx);
+BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc);
+BC_STATUS crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx, struct crystalhd_adp *adp);
+BC_STATUS crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx);
+bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_fw_if.h linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_fw_if.h
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_fw_if.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_fw_if.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,369 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ *  Name: crystalhd_fw_if . h
+ *
+ *  Description:
+ *		BCM70012 Firmware interface definitions.
+ *
+ *  HISTORY:
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver.  If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#ifndef _CRYSTALHD_FW_IF_H_
+#define _CRYSTALHD_FW_IF_H_
+
+/* TBD: Pull in only required defs into this file.. */
+
+
+
+/* User Data Header */
+typedef struct user_data {
+   struct user_data	*next;
+   uint32_t		type;
+   uint32_t		size;
+} UD_HDR;
+
+
+
+/*------------------------------------------------------*
+ *    MPEG Extension to the PPB			 *
+ *------------------------------------------------------*/
+typedef struct {
+   uint32_t		to_be_defined;
+   uint32_t		valid;
+
+   /* Always valid, defaults to picture size if no
+      sequence display extension in the stream. */
+   uint32_t		display_horizontal_size;
+   uint32_t		display_vertical_size;
+
+   /* MPEG_VALID_PANSCAN
+      Offsets are a copy values from the MPEG stream. */
+   uint32_t		offset_count;
+   int32_t		horizontal_offset[3];
+   int32_t		vertical_offset[3];
+
+   /* MPEG_VALID_USERDATA
+      User data is in the form of a linked list. */
+   int32_t		userDataSize;
+   UD_HDR		*userData;
+
+} PPB_MPEG;
+
+
+/*------------------------------------------------------*
+ *    VC1 Extension to the PPB			  *
+ *------------------------------------------------------*/
+typedef struct {
+   uint32_t		to_be_defined;
+   uint32_t		valid;
+
+   /* Always valid, defaults to picture size if no
+      sequence display extension in the stream. */
+   uint32_t		display_horizontal_size;
+   uint32_t		display_vertical_size;
+
+  /* VC1 pan scan windows */
+   uint32_t		num_panscan_windows;
+   int32_t		ps_horiz_offset[4];
+   int32_t		ps_vert_offset[4];
+   int32_t		ps_width[4];
+   int32_t		ps_height[4];
+
+   /* VC1_VALID_USERDATA
+      User data is in the form of a linked list. */
+   int32_t		userDataSize;
+   UD_HDR		*userData;
+
+} PPB_VC1;
+
+/*------------------------------------------------------*
+ *    H.264 Extension to the PPB			*
+ *------------------------------------------------------*/
+
+/**
+ * @brief Film grain SEI message.
+ *
+ * Content of the film grain SEI message.
+ */
+
+/* maximum number of model-values as for Thomson spec(standard says 5) */
+#define MAX_FGT_MODEL_VALUE	 (3)
+
+/* maximum number of intervals(as many as 256 intervals?) */
+#define MAX_FGT_VALUE_INTERVAL	(256)
+
+typedef struct FGT_SEI {
+    struct FGT_SEI *next;
+    unsigned char model_values[3][MAX_FGT_VALUE_INTERVAL][MAX_FGT_MODEL_VALUE];
+    unsigned char upper_bound[3][MAX_FGT_VALUE_INTERVAL];
+    unsigned char lower_bound[3][MAX_FGT_VALUE_INTERVAL];
+
+    unsigned char cancel_flag;	/* Cancel flag: 1 no film grain. */
+    unsigned char model_id;	/* Model id. */
+
+    /* +unused SE based on Thomson spec */
+    unsigned char color_desc_flag;	/* Separate color descrition flag. */
+    unsigned char bit_depth_luma;	/* Bit depth luma minus 8. */
+    unsigned char bit_depth_chroma;	/* Bit depth chroma minus 8. */
+    unsigned char full_range_flag;	/* Full range flag. */
+    unsigned char color_primaries;	/* Color primaries. */
+    unsigned char transfer_charact;	/* Transfer characteristics. */
+    unsigned char matrix_coeff;		/*< Matrix coefficients. */
+    /* -unused SE based on Thomson spec */
+
+    unsigned char blending_mode_id;	/* Blending mode. */
+    unsigned char log2_scale_factor;	/* Log2 scale factor (2-7). */
+    unsigned char comp_flag[3];		/* Components [0,2] parameters present flag. */
+    unsigned char num_intervals_minus1[3]; /* Number of intensity level intervals. */
+    unsigned char num_model_values[3];	/* Number of model values. */
+    uint16_t      repetition_period;	/* Repetition period (0-16384) */
+
+} FGT_SEI;
+
+typedef struct {
+   /* 'valid' specifies which fields (or sets of
+    * fields) below are valid.  If the corresponding
+    * bit in 'valid' is NOT set then that field(s)
+    * is (are) not initialized. */
+   uint32_t	valid;
+
+   int32_t		poc_top;	/* POC for Top Field/Frame */
+   int32_t		poc_bottom;	/* POC for Bottom Field    */
+   uint32_t		idr_pic_id;
+
+   /* H264_VALID_PANSCAN */
+   uint32_t		pan_scan_count;
+   int32_t		pan_scan_left[3];
+   int32_t		pan_scan_right[3];
+   int32_t		pan_scan_top[3];
+   int32_t		pan_scan_bottom[3];
+
+   /* H264_VALID_CT_TYPE */
+   uint32_t		ct_type_count;
+   uint32_t		ct_type[3];
+
+   /* H264_VALID_SPS_CROP */
+   int32_t		sps_crop_left;
+   int32_t		sps_crop_right;
+   int32_t		sps_crop_top;
+   int32_t		sps_crop_bottom;
+
+   /* H264_VALID_VUI */
+   uint32_t		chroma_top;
+   uint32_t		chroma_bottom;
+
+   /* H264_VALID_USER */
+   uint32_t		user_data_size;
+   UD_HDR		*user_data;
+
+   /* H264 VALID FGT */
+   FGT_SEI		*pfgt;
+
+} PPB_H264;
+
+typedef struct {
+   /* Common fields. */
+   uint32_t	picture_number;	/* Ordinal display number */
+   uint32_t	video_buffer;	/* Video (picbuf) number */
+   uint32_t	video_address;	/* Address of picbuf Y */
+   uint32_t	video_address_uv; /* Address of picbuf UV */
+   uint32_t	video_stripe;	/* Picbuf stripe */
+   uint32_t	video_width;	/* Picbuf width */
+   uint32_t	video_height;	/* Picbuf height */
+
+   uint32_t	channel_id;	/* Decoder channel ID */
+   uint32_t	status;		/* reserved */
+   uint32_t	width;		/* pixels */
+   uint32_t	height;		/* pixels */
+   uint32_t	chroma_format;	/* see above */
+   uint32_t	pulldown;	/* see above */
+   uint32_t	flags;		/* see above */
+   uint32_t	pts;		/* 32 LSBs of PTS */
+   uint32_t	protocol;	/* protocolXXX (above) */
+
+   uint32_t	frame_rate;	/* see above */
+   uint32_t	matrix_coeff;	/* see above */
+   uint32_t	aspect_ratio;	/* see above */
+   uint32_t	colour_primaries; /* see above */
+   uint32_t	transfer_char;	/* see above */
+   uint32_t	pcr_offset;	/* 45kHz if PCR type; else 27MHz */
+   uint32_t	n_drop;		/* Number of pictures to be dropped */
+
+   uint32_t	custom_aspect_ratio_width_height;
+			/* upper 16-bits is Y and lower 16-bits is X */
+
+   uint32_t	picture_tag;	/* Indexing tag from BUD packets */
+   uint32_t	picture_done_payload;
+   uint32_t	picture_meta_payload;
+   uint32_t	reserved[1];
+
+   /* Protocol-specific extensions. */
+   union {
+      PPB_H264	h264;
+      PPB_MPEG	mpeg;
+      PPB_VC1	 vc1;
+   } other;
+
+} PPB;
+
+typedef struct {
+   uint32_t	bFormatChange;
+   uint32_t	resolution;
+   uint32_t	channelId;
+   uint32_t	ppbPtr;
+   int32_t	ptsStcOffset;
+   uint32_t	zeroPanscanValid;
+   uint32_t	dramOutBufAddr;
+   uint32_t	yComponent;
+   PPB			ppb;
+
+} C011_PIB;
+
+
+
+typedef struct {
+    uint32_t	command;
+    uint32_t	sequence;
+    uint32_t	status;
+    uint32_t	picBuf;
+    uint32_t	picRelBuf;
+    uint32_t	picInfoDeliveryQ;
+    uint32_t	picInfoReleaseQ;
+    uint32_t	channelStatus;
+    uint32_t	userDataDeliveryQ;
+    uint32_t	userDataReleaseQ;
+    uint32_t	transportStreamCaptureAddr;
+    uint32_t	asyncEventQ;
+
+} DecRspChannelStartVideo;
+
+#define eCMD_C011_CMD_BASE	  (0x73763000)
+
+/* host commands */
+typedef enum {
+    eCMD_TS_GET_NEXT_PIC	= 0x7376F100, /* debug get next picture */
+    eCMD_TS_GET_LAST_PIC	= 0x7376F102, /* debug get last pic status */
+    eCMD_TS_READ_WRITE_MEM	= 0x7376F104, /* debug read write memory */
+
+    /* New API commands */
+    /* General commands */
+    eCMD_C011_INIT		= eCMD_C011_CMD_BASE + 0x01,
+    eCMD_C011_RESET		= eCMD_C011_CMD_BASE + 0x02,
+    eCMD_C011_SELF_TEST		= eCMD_C011_CMD_BASE + 0x03,
+    eCMD_C011_GET_VERSION	= eCMD_C011_CMD_BASE + 0x04,
+    eCMD_C011_GPIO		= eCMD_C011_CMD_BASE + 0x05,
+    eCMD_C011_DEBUG_SETUP	= eCMD_C011_CMD_BASE + 0x06,
+
+    /* Decoding commands */
+    eCMD_C011_DEC_CHAN_OPEN			= eCMD_C011_CMD_BASE + 0x100,
+    eCMD_C011_DEC_CHAN_CLOSE			= eCMD_C011_CMD_BASE + 0x101,
+    eCMD_C011_DEC_CHAN_ACTIVATE			= eCMD_C011_CMD_BASE + 0x102,
+    eCMD_C011_DEC_CHAN_STATUS			= eCMD_C011_CMD_BASE + 0x103,
+    eCMD_C011_DEC_CHAN_FLUSH			= eCMD_C011_CMD_BASE + 0x104,
+    eCMD_C011_DEC_CHAN_TRICK_PLAY		= eCMD_C011_CMD_BASE + 0x105,
+    eCMD_C011_DEC_CHAN_TS_PIDS			= eCMD_C011_CMD_BASE + 0x106,
+    eCMD_C011_DEC_CHAN_PS_STREAM_ID		= eCMD_C011_CMD_BASE + 0x107,
+    eCMD_C011_DEC_CHAN_INPUT_PARAMS		= eCMD_C011_CMD_BASE + 0x108,
+    eCMD_C011_DEC_CHAN_VIDEO_OUTPUT		= eCMD_C011_CMD_BASE + 0x109,
+    eCMD_C011_DEC_CHAN_OUTPUT_FORMAT		= eCMD_C011_CMD_BASE + 0x10A,
+    eCMD_C011_DEC_CHAN_SCALING_FILTERS		= eCMD_C011_CMD_BASE + 0x10B,
+    eCMD_C011_DEC_CHAN_OSD_MODE			= eCMD_C011_CMD_BASE + 0x10D,
+    eCMD_C011_DEC_CHAN_DROP			= eCMD_C011_CMD_BASE + 0x10E,
+    eCMD_C011_DEC_CHAN_RELEASE			= eCMD_C011_CMD_BASE + 0x10F,
+    eCMD_C011_DEC_CHAN_STREAM_SETTINGS		= eCMD_C011_CMD_BASE + 0x110,
+    eCMD_C011_DEC_CHAN_PAUSE_OUTPUT		= eCMD_C011_CMD_BASE + 0x111,
+    eCMD_C011_DEC_CHAN_CHANGE			= eCMD_C011_CMD_BASE + 0x112,
+    eCMD_C011_DEC_CHAN_SET_STC			= eCMD_C011_CMD_BASE + 0x113,
+    eCMD_C011_DEC_CHAN_SET_PTS			= eCMD_C011_CMD_BASE + 0x114,
+    eCMD_C011_DEC_CHAN_CC_MODE			= eCMD_C011_CMD_BASE + 0x115,
+    eCMD_C011_DEC_CREATE_AUDIO_CONTEXT		= eCMD_C011_CMD_BASE + 0x116,
+    eCMD_C011_DEC_COPY_AUDIO_CONTEXT		= eCMD_C011_CMD_BASE + 0x117,
+    eCMD_C011_DEC_DELETE_AUDIO_CONTEXT		= eCMD_C011_CMD_BASE + 0x118,
+    eCMD_C011_DEC_CHAN_SET_DECYPTION		= eCMD_C011_CMD_BASE + 0x119,
+    eCMD_C011_DEC_CHAN_START_VIDEO		= eCMD_C011_CMD_BASE + 0x11A,
+    eCMD_C011_DEC_CHAN_STOP_VIDEO		= eCMD_C011_CMD_BASE + 0x11B,
+    eCMD_C011_DEC_CHAN_PIC_CAPTURE		= eCMD_C011_CMD_BASE + 0x11C,
+    eCMD_C011_DEC_CHAN_PAUSE			= eCMD_C011_CMD_BASE + 0x11D,
+    eCMD_C011_DEC_CHAN_PAUSE_STATE		= eCMD_C011_CMD_BASE + 0x11E,
+    eCMD_C011_DEC_CHAN_SET_SLOWM_RATE		= eCMD_C011_CMD_BASE + 0x11F,
+    eCMD_C011_DEC_CHAN_GET_SLOWM_RATE		= eCMD_C011_CMD_BASE + 0x120,
+    eCMD_C011_DEC_CHAN_SET_FF_RATE		= eCMD_C011_CMD_BASE + 0x121,
+    eCMD_C011_DEC_CHAN_GET_FF_RATE		= eCMD_C011_CMD_BASE + 0x122,
+    eCMD_C011_DEC_CHAN_FRAME_ADVANCE		= eCMD_C011_CMD_BASE + 0x123,
+    eCMD_C011_DEC_CHAN_SET_SKIP_PIC_MODE	= eCMD_C011_CMD_BASE + 0x124,
+    eCMD_C011_DEC_CHAN_GET_SKIP_PIC_MODE	= eCMD_C011_CMD_BASE + 0x125,
+    eCMD_C011_DEC_CHAN_FILL_PIC_BUF		= eCMD_C011_CMD_BASE + 0x126,
+    eCMD_C011_DEC_CHAN_SET_CONTINUITY_CHECK	= eCMD_C011_CMD_BASE + 0x127,
+    eCMD_C011_DEC_CHAN_GET_CONTINUITY_CHECK	= eCMD_C011_CMD_BASE + 0x128,
+    eCMD_C011_DEC_CHAN_SET_BRCM_TRICK_MODE	= eCMD_C011_CMD_BASE + 0x129,
+    eCMD_C011_DEC_CHAN_GET_BRCM_TRICK_MODE	= eCMD_C011_CMD_BASE + 0x12A,
+    eCMD_C011_DEC_CHAN_REVERSE_FIELD_STATUS	= eCMD_C011_CMD_BASE + 0x12B,
+    eCMD_C011_DEC_CHAN_I_PICTURE_FOUND		= eCMD_C011_CMD_BASE + 0x12C,
+    eCMD_C011_DEC_CHAN_SET_PARAMETER		= eCMD_C011_CMD_BASE + 0x12D,
+    eCMD_C011_DEC_CHAN_SET_USER_DATA_MODE	= eCMD_C011_CMD_BASE + 0x12E,
+    eCMD_C011_DEC_CHAN_SET_PAUSE_DISPLAY_MODE	= eCMD_C011_CMD_BASE + 0x12F,
+    eCMD_C011_DEC_CHAN_SET_SLOW_DISPLAY_MODE	= eCMD_C011_CMD_BASE + 0x130,
+    eCMD_C011_DEC_CHAN_SET_FF_DISPLAY_MODE	= eCMD_C011_CMD_BASE + 0x131,
+    eCMD_C011_DEC_CHAN_SET_DISPLAY_TIMING_MODE	= eCMD_C011_CMD_BASE + 0x132,
+    eCMD_C011_DEC_CHAN_SET_DISPLAY_MODE		= eCMD_C011_CMD_BASE + 0x133,
+    eCMD_C011_DEC_CHAN_GET_DISPLAY_MODE		= eCMD_C011_CMD_BASE + 0x134,
+    eCMD_C011_DEC_CHAN_SET_REVERSE_FIELD	= eCMD_C011_CMD_BASE + 0x135,
+    eCMD_C011_DEC_CHAN_STREAM_OPEN		= eCMD_C011_CMD_BASE + 0x136,
+    eCMD_C011_DEC_CHAN_SET_PCR_PID		= eCMD_C011_CMD_BASE + 0x137,
+    eCMD_C011_DEC_CHAN_SET_VID_PID		= eCMD_C011_CMD_BASE + 0x138,
+    eCMD_C011_DEC_CHAN_SET_PAN_SCAN_MODE	= eCMD_C011_CMD_BASE + 0x139,
+    eCMD_C011_DEC_CHAN_START_DISPLAY_AT_PTS	= eCMD_C011_CMD_BASE + 0x140,
+    eCMD_C011_DEC_CHAN_STOP_DISPLAY_AT_PTS	= eCMD_C011_CMD_BASE + 0x141,
+    eCMD_C011_DEC_CHAN_SET_DISPLAY_ORDER	= eCMD_C011_CMD_BASE + 0x142,
+    eCMD_C011_DEC_CHAN_GET_DISPLAY_ORDER	= eCMD_C011_CMD_BASE + 0x143,
+    eCMD_C011_DEC_CHAN_SET_HOST_TRICK_MODE	= eCMD_C011_CMD_BASE + 0x144,
+    eCMD_C011_DEC_CHAN_SET_OPERATION_MODE	= eCMD_C011_CMD_BASE + 0x145,
+    eCMD_C011_DEC_CHAN_DISPLAY_PAUSE_UNTO_PTS	= eCMD_C011_CMD_BASE + 0x146,
+    eCMD_C011_DEC_CHAN_SET_PTS_STC_DIFF_THRESHOLD = eCMD_C011_CMD_BASE + 0x147,
+    eCMD_C011_DEC_CHAN_SEND_COMPRESSED_BUF	= eCMD_C011_CMD_BASE + 0x148,
+    eCMD_C011_DEC_CHAN_SET_CLIPPING		= eCMD_C011_CMD_BASE + 0x149,
+    eCMD_C011_DEC_CHAN_SET_PARAMETERS_FOR_HARD_RESET_INTERRUPT_TO_HOST
+						= eCMD_C011_CMD_BASE + 0x150,
+
+    /* Decoder RevD commands */
+    eCMD_C011_DEC_CHAN_SET_CSC	= eCMD_C011_CMD_BASE + 0x180, /* color space conversion */
+    eCMD_C011_DEC_CHAN_SET_RANGE_REMAP	= eCMD_C011_CMD_BASE + 0x181,
+    eCMD_C011_DEC_CHAN_SET_FGT		= eCMD_C011_CMD_BASE + 0x182,
+    /* Note: 0x183 not implemented yet in Rev D main */
+    eCMD_C011_DEC_CHAN_SET_LASTPICTURE_PADDING = eCMD_C011_CMD_BASE + 0x183,
+
+    /* Decoder 7412 commands (7412-only) */
+    eCMD_C011_DEC_CHAN_SET_CONTENT_KEY	= eCMD_C011_CMD_BASE + 0x190,
+    eCMD_C011_DEC_CHAN_SET_SESSION_KEY	= eCMD_C011_CMD_BASE + 0x191,
+    eCMD_C011_DEC_CHAN_FMT_CHANGE_ACK	= eCMD_C011_CMD_BASE + 0x192,
+
+    eCMD_C011_DEC_CHAN_CUSTOM_VIDOUT    = eCMD_C011_CMD_BASE + 0x1FF,
+
+    /* Encoding commands */
+    eCMD_C011_ENC_CHAN_OPEN		= eCMD_C011_CMD_BASE + 0x200,
+    eCMD_C011_ENC_CHAN_CLOSE		= eCMD_C011_CMD_BASE + 0x201,
+    eCMD_C011_ENC_CHAN_ACTIVATE		= eCMD_C011_CMD_BASE + 0x202,
+    eCMD_C011_ENC_CHAN_CONTROL		= eCMD_C011_CMD_BASE + 0x203,
+    eCMD_C011_ENC_CHAN_STATISTICS	= eCMD_C011_CMD_BASE + 0x204,
+
+    eNOTIFY_C011_ENC_CHAN_EVENT		= eCMD_C011_CMD_BASE + 0x210,
+
+} eC011_TS_CMD;
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_hw.c linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_hw.c
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_hw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_hw.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,2396 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ *  Name: crystalhd_hw . c
+ *
+ *  Description:
+ *		BCM70010 Linux driver HW layer.
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver.  If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "crystalhd_hw.h"
+
+/* Functions internal to this file */
+
+static void crystalhd_enable_uarts(struct crystalhd_adp *adp)
+{
+	bc_dec_reg_wr(adp, UartSelectA, BSVS_UART_STREAM);
+	bc_dec_reg_wr(adp, UartSelectB, BSVS_UART_DEC_OUTER);
+}
+
+
+static void crystalhd_start_dram(struct crystalhd_adp *adp)
+{
+	bc_dec_reg_wr(adp, SDRAM_PARAM, ((40 / 5 - 1) <<  0) |
+	/* tras (40ns tras)/(5ns period) -1 ((15/5 - 1) <<  4) | // trcd */
+		      ((15 / 5 - 1) <<  7) |	/* trp */
+		      ((10 / 5 - 1) << 10) |	/* trrd */
+		      ((15 / 5 + 1) << 12) |	/* twr */
+		      ((2 + 1) << 16) |		/* twtr */
+		      ((70 / 5 - 2) << 19) |	/* trfc */
+		      (0 << 23));
+
+	bc_dec_reg_wr(adp, SDRAM_PRECHARGE, 0);
+	bc_dec_reg_wr(adp, SDRAM_EXT_MODE, 2);
+	bc_dec_reg_wr(adp, SDRAM_MODE, 0x132);
+	bc_dec_reg_wr(adp, SDRAM_PRECHARGE, 0);
+	bc_dec_reg_wr(adp, SDRAM_REFRESH, 0);
+	bc_dec_reg_wr(adp, SDRAM_REFRESH, 0);
+	bc_dec_reg_wr(adp, SDRAM_MODE, 0x32);
+	/* setting the refresh rate here */
+	bc_dec_reg_wr(adp, SDRAM_REF_PARAM, ((1 << 12) | 96));
+}
+
+
+static bool crystalhd_bring_out_of_rst(struct crystalhd_adp *adp)
+{
+	link_misc_perst_deco_ctrl rst_deco_cntrl;
+	link_misc_perst_clk_ctrl rst_clk_cntrl;
+	uint32_t temp;
+
+	/*
+	 * Link clocks: MISC_PERST_CLOCK_CTRL Clear PLL power down bit,
+	 * delay to allow PLL to lock Clear alternate clock, stop clock bits
+	 */
+	rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
+	rst_clk_cntrl.pll_pwr_dn = 0;
+	crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
+	msleep_interruptible(50);
+
+	rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
+	rst_clk_cntrl.stop_core_clk = 0;
+	rst_clk_cntrl.sel_alt_clk = 0;
+
+	crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
+	msleep_interruptible(50);
+
+	/*
+	 * Bus Arbiter Timeout: GISB_ARBITER_TIMER
+	 * Set internal bus arbiter timeout to 40us based on core clock speed
+	 * (63MHz * 40us = 0x9D8)
+	 */
+	crystalhd_reg_wr(adp, GISB_ARBITER_TIMER, 0x9D8);
+
+	/*
+	 * Decoder clocks: MISC_PERST_DECODER_CTRL
+	 * Enable clocks while 7412 reset is asserted, delay
+	 * De-assert 7412 reset
+	 */
+	rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_DECODER_CTRL);
+	rst_deco_cntrl.stop_bcm_7412_clk = 0;
+	rst_deco_cntrl.bcm7412_rst = 1;
+	crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL, rst_deco_cntrl.whole_reg);
+	msleep_interruptible(10);
+
+	rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_DECODER_CTRL);
+	rst_deco_cntrl.bcm7412_rst = 0;
+	crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL, rst_deco_cntrl.whole_reg);
+	msleep_interruptible(50);
+
+	/* Disable OTP_CONTENT_MISC to 0 to disable all secure modes */
+	crystalhd_reg_wr(adp, OTP_CONTENT_MISC, 0);
+
+	/* Clear bit 29 of 0x404 */
+	temp = crystalhd_reg_rd(adp, PCIE_TL_TRANSACTION_CONFIGURATION);
+	temp &= ~BC_BIT(29);
+	crystalhd_reg_wr(adp, PCIE_TL_TRANSACTION_CONFIGURATION, temp);
+
+	/* 2.5V regulator must be set to 2.6 volts (+6%) */
+	/* FIXME: jarod: what's the point of this reg read? */
+	temp = crystalhd_reg_rd(adp, MISC_PERST_VREG_CTRL);
+	crystalhd_reg_wr(adp, MISC_PERST_VREG_CTRL, 0xF3);
+
+	return true;
+}
+
+static bool crystalhd_put_in_reset(struct crystalhd_adp *adp)
+{
+	link_misc_perst_deco_ctrl rst_deco_cntrl;
+	link_misc_perst_clk_ctrl  rst_clk_cntrl;
+	uint32_t                  temp;
+
+	/*
+	 * Decoder clocks: MISC_PERST_DECODER_CTRL
+	 * Assert 7412 reset, delay
+	 * Assert 7412 stop clock
+	 */
+	rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_DECODER_CTRL);
+	rst_deco_cntrl.stop_bcm_7412_clk = 1;
+	crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL, rst_deco_cntrl.whole_reg);
+	msleep_interruptible(50);
+
+	/* Bus Arbiter Timeout: GISB_ARBITER_TIMER
+	 * Set internal bus arbiter timeout to 40us based on core clock speed
+	 * (6.75MHZ * 40us = 0x10E)
+	 */
+	crystalhd_reg_wr(adp, GISB_ARBITER_TIMER, 0x10E);
+
+	/* Link clocks: MISC_PERST_CLOCK_CTRL
+	 * Stop core clk, delay
+	 * Set alternate clk, delay, set PLL power down
+	 */
+	rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
+	rst_clk_cntrl.stop_core_clk = 1;
+	rst_clk_cntrl.sel_alt_clk = 1;
+	crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
+	msleep_interruptible(50);
+
+	rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
+	rst_clk_cntrl.pll_pwr_dn = 1;
+	crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
+
+	/*
+	 * Read and restore the Transaction Configuration Register
+	 * after core reset
+	 */
+	temp = crystalhd_reg_rd(adp, PCIE_TL_TRANSACTION_CONFIGURATION);
+
+	/*
+	 * Link core soft reset: MISC3_RESET_CTRL
+	 * - Write BIT[0]=1 and read it back for core reset to take place
+	 */
+	crystalhd_reg_wr(adp, MISC3_RESET_CTRL, 1);
+	rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC3_RESET_CTRL);
+	msleep_interruptible(50);
+
+	/* restore the transaction configuration register */
+	crystalhd_reg_wr(adp, PCIE_TL_TRANSACTION_CONFIGURATION, temp);
+
+	return true;
+}
+
+static void crystalhd_disable_interrupts(struct crystalhd_adp *adp)
+{
+	intr_mask_reg   intr_mask;
+	intr_mask.whole_reg = crystalhd_reg_rd(adp, INTR_INTR_MSK_STS_REG);
+	intr_mask.mask_pcie_err = 1;
+	intr_mask.mask_pcie_rbusmast_err = 1;
+	intr_mask.mask_pcie_rgr_bridge   = 1;
+	intr_mask.mask_rx_done = 1;
+	intr_mask.mask_rx_err  = 1;
+	intr_mask.mask_tx_done = 1;
+	intr_mask.mask_tx_err  = 1;
+	crystalhd_reg_wr(adp, INTR_INTR_MSK_SET_REG, intr_mask.whole_reg);
+
+	return;
+}
+
+static void crystalhd_enable_interrupts(struct crystalhd_adp *adp)
+{
+	intr_mask_reg   intr_mask;
+	intr_mask.whole_reg = crystalhd_reg_rd(adp, INTR_INTR_MSK_STS_REG);
+	intr_mask.mask_pcie_err = 1;
+	intr_mask.mask_pcie_rbusmast_err = 1;
+	intr_mask.mask_pcie_rgr_bridge   = 1;
+	intr_mask.mask_rx_done = 1;
+	intr_mask.mask_rx_err  = 1;
+	intr_mask.mask_tx_done = 1;
+	intr_mask.mask_tx_err  = 1;
+	crystalhd_reg_wr(adp, INTR_INTR_MSK_CLR_REG, intr_mask.whole_reg);
+
+	return;
+}
+
+static void crystalhd_clear_errors(struct crystalhd_adp *adp)
+{
+	uint32_t reg;
+
+	/* FIXME: jarod: wouldn't we want to write a 0 to the reg? Or does the write clear the bits specified? */
+	reg = crystalhd_reg_rd(adp, MISC1_Y_RX_ERROR_STATUS);
+	if (reg)
+		crystalhd_reg_wr(adp, MISC1_Y_RX_ERROR_STATUS, reg);
+
+	reg = crystalhd_reg_rd(adp, MISC1_UV_RX_ERROR_STATUS);
+	if (reg)
+		crystalhd_reg_wr(adp, MISC1_UV_RX_ERROR_STATUS, reg);
+
+	reg = crystalhd_reg_rd(adp, MISC1_TX_DMA_ERROR_STATUS);
+	if (reg)
+		crystalhd_reg_wr(adp, MISC1_TX_DMA_ERROR_STATUS, reg);
+}
+
+static void crystalhd_clear_interrupts(struct crystalhd_adp *adp)
+{
+	uint32_t intr_sts = crystalhd_reg_rd(adp, INTR_INTR_STATUS);
+
+	if (intr_sts) {
+		crystalhd_reg_wr(adp, INTR_INTR_CLR_REG, intr_sts);
+
+		/* Write End Of Interrupt for PCIE */
+		crystalhd_reg_wr(adp, INTR_EOI_CTRL, 1);
+	}
+}
+
+static void crystalhd_soft_rst(struct crystalhd_adp *adp)
+{
+	uint32_t val;
+
+	/* Assert c011 soft reset*/
+	bc_dec_reg_wr(adp, DecHt_HostSwReset, 0x00000001);
+	msleep_interruptible(50);
+
+	/* Release c011 soft reset*/
+	bc_dec_reg_wr(adp, DecHt_HostSwReset, 0x00000000);
+
+	/* Disable Stuffing..*/
+	val = crystalhd_reg_rd(adp, MISC2_GLOBAL_CTRL);
+	val |= BC_BIT(8);
+	crystalhd_reg_wr(adp, MISC2_GLOBAL_CTRL, val);
+}
+
+static bool crystalhd_load_firmware_config(struct crystalhd_adp *adp)
+{
+	uint32_t i = 0, reg;
+
+	crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (BC_DRAM_FW_CFG_ADDR >> 19));
+
+	crystalhd_reg_wr(adp, AES_CMD, 0);
+	crystalhd_reg_wr(adp, AES_CONFIG_INFO, (BC_DRAM_FW_CFG_ADDR & 0x7FFFF));
+	crystalhd_reg_wr(adp, AES_CMD, 0x1);
+
+	/* FIXME: jarod: I've seen this fail, and introducing extra delays helps... */
+	for (i = 0; i < 100; ++i) {
+		reg = crystalhd_reg_rd(adp, AES_STATUS);
+		if (reg & 0x1)
+			return true;
+		msleep_interruptible(10);
+	}
+
+	return false;
+}
+
+
+static bool crystalhd_start_device(struct crystalhd_adp *adp)
+{
+	uint32_t dbg_options, glb_cntrl = 0, reg_pwrmgmt = 0;
+
+	BCMLOG(BCMLOG_INFO, "Starting BCM70012 Device\n");
+
+	reg_pwrmgmt = crystalhd_reg_rd(adp, PCIE_DLL_DATA_LINK_CONTROL);
+	reg_pwrmgmt &= ~ASPM_L1_ENABLE;
+
+	crystalhd_reg_wr(adp, PCIE_DLL_DATA_LINK_CONTROL, reg_pwrmgmt);
+
+	if (!crystalhd_bring_out_of_rst(adp)) {
+		BCMLOG_ERR("Failed To Bring Link Out Of Reset\n");
+		return false;
+	}
+
+	crystalhd_disable_interrupts(adp);
+
+	crystalhd_clear_errors(adp);
+
+	crystalhd_clear_interrupts(adp);
+
+	crystalhd_enable_interrupts(adp);
+
+	/* Enable the option for getting the total no. of DWORDS
+	 * that have been transfered by the RXDMA engine
+	 */
+	dbg_options = crystalhd_reg_rd(adp, MISC1_DMA_DEBUG_OPTIONS_REG);
+	dbg_options |= 0x10;
+	crystalhd_reg_wr(adp, MISC1_DMA_DEBUG_OPTIONS_REG, dbg_options);
+
+	/* Enable PCI Global Control options */
+	glb_cntrl = crystalhd_reg_rd(adp, MISC2_GLOBAL_CTRL);
+	glb_cntrl |= 0x100;
+	glb_cntrl |= 0x8000;
+	crystalhd_reg_wr(adp, MISC2_GLOBAL_CTRL, glb_cntrl);
+
+	crystalhd_enable_interrupts(adp);
+
+	crystalhd_soft_rst(adp);
+	crystalhd_start_dram(adp);
+	crystalhd_enable_uarts(adp);
+
+	return true;
+}
+
+static bool crystalhd_stop_device(struct crystalhd_adp *adp)
+{
+	uint32_t reg;
+
+	BCMLOG(BCMLOG_INFO, "Stopping BCM70012 Device\n");
+	/* Clear and disable interrupts */
+	crystalhd_disable_interrupts(adp);
+	crystalhd_clear_errors(adp);
+	crystalhd_clear_interrupts(adp);
+
+	if (!crystalhd_put_in_reset(adp))
+		BCMLOG_ERR("Failed to Put Link To Reset State\n");
+
+	reg = crystalhd_reg_rd(adp, PCIE_DLL_DATA_LINK_CONTROL);
+	reg |= ASPM_L1_ENABLE;
+	crystalhd_reg_wr(adp, PCIE_DLL_DATA_LINK_CONTROL, reg);
+
+	/* Set PCI Clk Req */
+	reg = crystalhd_reg_rd(adp, PCIE_CLK_REQ_REG);
+	reg |= PCI_CLK_REQ_ENABLE;
+	crystalhd_reg_wr(adp, PCIE_CLK_REQ_REG, reg);
+
+	return true;
+}
+
+static crystalhd_rx_dma_pkt *crystalhd_hw_alloc_rx_pkt(struct crystalhd_hw *hw)
+{
+	unsigned long flags = 0;
+	crystalhd_rx_dma_pkt *temp = NULL;
+
+	if (!hw)
+		return NULL;
+
+	spin_lock_irqsave(&hw->lock, flags);
+	temp = hw->rx_pkt_pool_head;
+	if (temp) {
+		hw->rx_pkt_pool_head = hw->rx_pkt_pool_head->next;
+		temp->dio_req = NULL;
+		temp->pkt_tag = 0;
+		temp->flags = 0;
+	}
+	spin_unlock_irqrestore(&hw->lock, flags);
+
+	return temp;
+}
+
+static void crystalhd_hw_free_rx_pkt(struct crystalhd_hw *hw,
+				   crystalhd_rx_dma_pkt *pkt)
+{
+	unsigned long flags = 0;
+
+	if (!hw || !pkt)
+		return;
+
+	spin_lock_irqsave(&hw->lock, flags);
+	pkt->next = hw->rx_pkt_pool_head;
+	hw->rx_pkt_pool_head = pkt;
+	spin_unlock_irqrestore(&hw->lock, flags);
+}
+
+/*
+ * Call back from TX - IOQ deletion.
+ *
+ * This routine will release the TX DMA rings allocated
+ * druing setup_dma rings interface.
+ *
+ * Memory is allocated per DMA ring basis. This is just
+ * a place holder to be able to create the dio queues.
+ */
+static void crystalhd_tx_desc_rel_call_back(void *context, void *data)
+{
+}
+
+/*
+ * Rx Packet release callback..
+ *
+ * Release All user mapped capture buffers and Our DMA packets
+ * back to our free pool. The actual cleanup of the DMA
+ * ring descriptors happen during dma ring release.
+ */
+static void crystalhd_rx_pkt_rel_call_back(void *context, void *data)
+{
+	struct crystalhd_hw *hw = (struct crystalhd_hw *)context;
+	crystalhd_rx_dma_pkt *pkt = (crystalhd_rx_dma_pkt *)data;
+
+	if (!pkt || !hw) {
+		BCMLOG_ERR("Invalid arg - %p %p\n", hw, pkt);
+		return;
+	}
+
+	if (pkt->dio_req)
+		crystalhd_unmap_dio(hw->adp, pkt->dio_req);
+	else
+		BCMLOG_ERR("Missing dio_req: 0x%x\n", pkt->pkt_tag);
+
+	crystalhd_hw_free_rx_pkt(hw, pkt);
+}
+
+#define crystalhd_hw_delete_ioq(adp, q)		\
+	if (q) {				\
+		crystalhd_delete_dioq(adp, q);	\
+		q = NULL;			\
+	}
+
+static void crystalhd_hw_delete_ioqs(struct crystalhd_hw *hw)
+{
+	if (!hw)
+		return;
+
+	BCMLOG(BCMLOG_DBG, "Deleting IOQs \n");
+	crystalhd_hw_delete_ioq(hw->adp, hw->tx_actq);
+	crystalhd_hw_delete_ioq(hw->adp, hw->tx_freeq);
+	crystalhd_hw_delete_ioq(hw->adp, hw->rx_actq);
+	crystalhd_hw_delete_ioq(hw->adp, hw->rx_freeq);
+	crystalhd_hw_delete_ioq(hw->adp, hw->rx_rdyq);
+}
+
+#define crystalhd_hw_create_ioq(sts, hw, q, cb)			\
+do {								\
+	sts = crystalhd_create_dioq(hw->adp, &q, cb, hw);	\
+	if (sts != BC_STS_SUCCESS)				\
+		goto hw_create_ioq_err;				\
+} while (0)
+
+/*
+ * Create IOQs..
+ *
+ * TX - Active & Free
+ * RX - Active, Ready and Free.
+ */
+static BC_STATUS crystalhd_hw_create_ioqs(struct crystalhd_hw   *hw)
+{
+	BC_STATUS   sts = BC_STS_SUCCESS;
+
+	if (!hw) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return BC_STS_INV_ARG;
+	}
+
+	crystalhd_hw_create_ioq(sts, hw, hw->tx_freeq,
+			      crystalhd_tx_desc_rel_call_back);
+	crystalhd_hw_create_ioq(sts, hw, hw->tx_actq,
+			      crystalhd_tx_desc_rel_call_back);
+
+	crystalhd_hw_create_ioq(sts, hw, hw->rx_freeq,
+			      crystalhd_rx_pkt_rel_call_back);
+	crystalhd_hw_create_ioq(sts, hw, hw->rx_rdyq,
+			      crystalhd_rx_pkt_rel_call_back);
+	crystalhd_hw_create_ioq(sts, hw, hw->rx_actq,
+			      crystalhd_rx_pkt_rel_call_back);
+
+	return sts;
+
+hw_create_ioq_err:
+	crystalhd_hw_delete_ioqs(hw);
+
+	return sts;
+}
+
+
+static bool crystalhd_code_in_full(struct crystalhd_adp *adp, uint32_t needed_sz,
+				 bool b_188_byte_pkts,  uint8_t flags)
+{
+	uint32_t base, end, writep, readp;
+	uint32_t cpbSize, cpbFullness, fifoSize;
+
+	if (flags & 0x02) { /* ASF Bit is set */
+		base   = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2Base);
+		end    = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2End);
+		writep = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2Wrptr);
+		readp  = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2Rdptr);
+	} else if (b_188_byte_pkts) { /*Encrypted 188 byte packets*/
+		base   = bc_dec_reg_rd(adp, REG_Dec_TsUser0Base);
+		end    = bc_dec_reg_rd(adp, REG_Dec_TsUser0End);
+		writep = bc_dec_reg_rd(adp, REG_Dec_TsUser0Wrptr);
+		readp  = bc_dec_reg_rd(adp, REG_Dec_TsUser0Rdptr);
+	} else {
+		base   = bc_dec_reg_rd(adp, REG_DecCA_RegCinBase);
+		end    = bc_dec_reg_rd(adp, REG_DecCA_RegCinEnd);
+		writep = bc_dec_reg_rd(adp, REG_DecCA_RegCinWrPtr);
+		readp  = bc_dec_reg_rd(adp, REG_DecCA_RegCinRdPtr);
+	}
+
+	cpbSize = end - base;
+	if (writep >= readp)
+		cpbFullness = writep - readp;
+	else
+		cpbFullness = (end - base) - (readp - writep);
+
+	fifoSize = cpbSize - cpbFullness;
+
+	if (fifoSize < BC_INFIFO_THRESHOLD)
+		return true;
+
+	if (needed_sz > (fifoSize - BC_INFIFO_THRESHOLD))
+		return true;
+
+	return false;
+}
+
+static BC_STATUS crystalhd_hw_tx_req_complete(struct crystalhd_hw *hw,
+					    uint32_t list_id, BC_STATUS cs)
+{
+	tx_dma_pkt *tx_req;
+
+	if (!hw || !list_id) {
+		BCMLOG_ERR("Invalid Arg..\n");
+		return BC_STS_INV_ARG;
+	}
+
+	hw->pwr_lock--;
+
+	tx_req = (tx_dma_pkt *)crystalhd_dioq_find_and_fetch(hw->tx_actq, list_id);
+	if (!tx_req) {
+		if (cs != BC_STS_IO_USER_ABORT)
+			BCMLOG_ERR("Find and Fetch Did not find req\n");
+		return BC_STS_NO_DATA;
+	}
+
+	if (tx_req->call_back) {
+		tx_req->call_back(tx_req->dio_req, tx_req->cb_event, cs);
+		tx_req->dio_req   = NULL;
+		tx_req->cb_event  = NULL;
+		tx_req->call_back = NULL;
+	} else {
+		BCMLOG(BCMLOG_DBG, "Missing Tx Callback - %X\n",
+		       tx_req->list_tag);
+	}
+
+	/* Now put back the tx_list back in FreeQ */
+	tx_req->list_tag = 0;
+
+	return crystalhd_dioq_add(hw->tx_freeq, tx_req, false, 0);
+}
+
+static bool crystalhd_tx_list0_handler(struct crystalhd_hw *hw, uint32_t err_sts)
+{
+	uint32_t err_mask, tmp;
+	unsigned long flags = 0;
+
+	err_mask = MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_MASK |
+		MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_MASK |
+		MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK;
+
+	if (!(err_sts & err_mask))
+		return false;
+
+	BCMLOG_ERR("Error on Tx-L0 %x \n", err_sts);
+
+	tmp = err_mask;
+
+	if (err_sts & MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK)
+		tmp &= ~MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK;
+
+	if (tmp) {
+		spin_lock_irqsave(&hw->lock, flags);
+		/* reset list index.*/
+		hw->tx_list_post_index = 0;
+		spin_unlock_irqrestore(&hw->lock, flags);
+	}
+
+	tmp = err_sts & err_mask;
+	crystalhd_reg_wr(hw->adp, MISC1_TX_DMA_ERROR_STATUS, tmp);
+
+	return true;
+}
+
+static bool crystalhd_tx_list1_handler(struct crystalhd_hw *hw, uint32_t err_sts)
+{
+	uint32_t err_mask, tmp;
+	unsigned long flags = 0;
+
+	err_mask = MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_MASK |
+		MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_MASK |
+		MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK;
+
+	if (!(err_sts & err_mask))
+		return false;
+
+	BCMLOG_ERR("Error on Tx-L1 %x \n", err_sts);
+
+	tmp = err_mask;
+
+	if (err_sts & MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK)
+		tmp &= ~MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK;
+
+	if (tmp) {
+		spin_lock_irqsave(&hw->lock, flags);
+		/* reset list index.*/
+		hw->tx_list_post_index = 0;
+		spin_unlock_irqrestore(&hw->lock, flags);
+	}
+
+	tmp = err_sts & err_mask;
+	crystalhd_reg_wr(hw->adp, MISC1_TX_DMA_ERROR_STATUS, tmp);
+
+	return true;
+}
+
+static void crystalhd_tx_isr(struct crystalhd_hw *hw, uint32_t int_sts)
+{
+	uint32_t err_sts;
+
+	if (int_sts & INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_MASK)
+		crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 0,
+					   BC_STS_SUCCESS);
+
+	if (int_sts & INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_MASK)
+		crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 1,
+					   BC_STS_SUCCESS);
+
+	if (!(int_sts & (INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_MASK |
+			 INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_MASK))) {
+			 /* No error mask set.. */
+			 return;
+	}
+
+	/* Handle Tx errors. */
+	err_sts = crystalhd_reg_rd(hw->adp, MISC1_TX_DMA_ERROR_STATUS);
+
+	if (crystalhd_tx_list0_handler(hw, err_sts))
+		crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 0,
+					   BC_STS_ERROR);
+
+	if (crystalhd_tx_list1_handler(hw, err_sts))
+		crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 1,
+					   BC_STS_ERROR);
+
+	hw->stats.tx_errors++;
+}
+
+static void crystalhd_hw_dump_desc(pdma_descriptor p_dma_desc,
+				 uint32_t ul_desc_index, uint32_t cnt)
+{
+	uint32_t ix, ll = 0;
+
+	if (!p_dma_desc || !cnt)
+		return;
+
+	/* FIXME: jarod: perhaps a modparam desc_debug to enable this, rather than
+	 * setting ll (log level, I presume) to non-zero? */
+	if (!ll)
+		return;
+
+	for (ix = ul_desc_index; ix < (ul_desc_index + cnt); ix++) {
+		BCMLOG(ll, "%s[%d] Buff[%x:%x] Next:[%x:%x] XferSz:%x Intr:%x,Last:%x\n",
+		       ((p_dma_desc[ul_desc_index].dma_dir) ? "TDesc" : "RDesc"),
+		       ul_desc_index,
+		       p_dma_desc[ul_desc_index].buff_addr_high,
+		       p_dma_desc[ul_desc_index].buff_addr_low,
+		       p_dma_desc[ul_desc_index].next_desc_addr_high,
+		       p_dma_desc[ul_desc_index].next_desc_addr_low,
+		       p_dma_desc[ul_desc_index].xfer_size,
+		       p_dma_desc[ul_desc_index].intr_enable,
+		       p_dma_desc[ul_desc_index].last_rec_indicator);
+	}
+
+}
+
+static BC_STATUS crystalhd_hw_fill_desc(crystalhd_dio_req *ioreq,
+				      dma_descriptor *desc,
+				      dma_addr_t desc_paddr_base,
+				      uint32_t sg_cnt, uint32_t sg_st_ix,
+				      uint32_t sg_st_off, uint32_t xfr_sz)
+{
+	uint32_t count = 0, ix = 0, sg_ix = 0, len = 0, last_desc_ix = 0;
+	dma_addr_t desc_phy_addr = desc_paddr_base;
+	addr_64 addr_temp;
+
+	if (!ioreq || !desc || !desc_paddr_base || !xfr_sz ||
+	    (!sg_cnt && !ioreq->uinfo.dir_tx)) {
+		BCMLOG_ERR("Invalid Args\n");
+		return BC_STS_INV_ARG;
+	}
+
+	for (ix = 0; ix < sg_cnt; ix++) {
+
+		/* Setup SGLE index. */
+		sg_ix = ix + sg_st_ix;
+
+		/* Get SGLE length */
+		len = crystalhd_get_sgle_len(ioreq, sg_ix);
+		if (len % 4) {
+			BCMLOG_ERR(" len in sg %d %d %d\n", len, sg_ix, sg_cnt);
+			return BC_STS_NOT_IMPL;
+		}
+		/* Setup DMA desc with Phy addr & Length at current index. */
+		addr_temp.full_addr = crystalhd_get_sgle_paddr(ioreq, sg_ix);
+		if (sg_ix == sg_st_ix) {
+			addr_temp.full_addr += sg_st_off;
+			len -= sg_st_off;
+		}
+		memset(&desc[ix], 0, sizeof(desc[ix]));
+		desc[ix].buff_addr_low  = addr_temp.low_part;
+		desc[ix].buff_addr_high = addr_temp.high_part;
+		desc[ix].dma_dir        = ioreq->uinfo.dir_tx;
+
+		/* Chain DMA descriptor.  */
+		addr_temp.full_addr = desc_phy_addr + sizeof(dma_descriptor);
+		desc[ix].next_desc_addr_low = addr_temp.low_part;
+		desc[ix].next_desc_addr_high = addr_temp.high_part;
+
+		if ((count + len) > xfr_sz)
+			len = xfr_sz - count;
+
+		/* Debug.. */
+		if ((!len) || (len > crystalhd_get_sgle_len(ioreq, sg_ix))) {
+			BCMLOG_ERR("inv-len(%x) Ix(%d) count:%x xfr_sz:%x sg_cnt:%d\n",
+				   len, ix, count, xfr_sz, sg_cnt);
+			return BC_STS_ERROR;
+		}
+		/* Length expects Multiple of 4 */
+		desc[ix].xfer_size = (len / 4);
+
+		crystalhd_hw_dump_desc(desc, ix, 1);
+
+		count += len;
+		desc_phy_addr += sizeof(dma_descriptor);
+	}
+
+	last_desc_ix = ix - 1;
+
+	if (ioreq->fb_size) {
+		memset(&desc[ix], 0, sizeof(desc[ix]));
+		addr_temp.full_addr     = ioreq->fb_pa;
+		desc[ix].buff_addr_low  = addr_temp.low_part;
+		desc[ix].buff_addr_high = addr_temp.high_part;
+		desc[ix].dma_dir        = ioreq->uinfo.dir_tx;
+		desc[ix].xfer_size	= 1;
+		desc[ix].fill_bytes	= 4 - ioreq->fb_size;
+		count += ioreq->fb_size;
+		last_desc_ix++;
+	}
+
+	/* setup last descriptor..*/
+	desc[last_desc_ix].last_rec_indicator  = 1;
+	desc[last_desc_ix].next_desc_addr_low  = 0;
+	desc[last_desc_ix].next_desc_addr_high = 0;
+	desc[last_desc_ix].intr_enable = 1;
+
+	crystalhd_hw_dump_desc(desc, last_desc_ix, 1);
+
+	if (count != xfr_sz) {
+		BCMLOG_ERR("interal error sz curr:%x exp:%x\n", count, xfr_sz);
+		return BC_STS_ERROR;
+	}
+
+	return BC_STS_SUCCESS;
+}
+
+static BC_STATUS crystalhd_xlat_sgl_to_dma_desc(crystalhd_dio_req *ioreq,
+					      pdma_desc_mem pdesc_mem,
+					      uint32_t *uv_desc_index)
+{
+	dma_descriptor *desc = NULL;
+	dma_addr_t desc_paddr_base = 0;
+	uint32_t sg_cnt = 0, sg_st_ix = 0, sg_st_off = 0;
+	uint32_t xfr_sz = 0;
+	BC_STATUS sts = BC_STS_SUCCESS;
+
+	/* Check params.. */
+	if (!ioreq || !pdesc_mem || !uv_desc_index) {
+		BCMLOG_ERR("Invalid Args\n");
+		return BC_STS_INV_ARG;
+	}
+
+	if (!pdesc_mem->sz || !pdesc_mem->pdma_desc_start ||
+	    !ioreq->sg || (!ioreq->sg_cnt && !ioreq->uinfo.dir_tx)) {
+		BCMLOG_ERR("Invalid Args\n");
+		return BC_STS_INV_ARG;
+	}
+
+	if ((ioreq->uinfo.dir_tx) && (ioreq->uinfo.uv_offset)) {
+		BCMLOG_ERR("UV offset for TX??\n");
+		return BC_STS_INV_ARG;
+
+	}
+
+	desc = pdesc_mem->pdma_desc_start;
+	desc_paddr_base = pdesc_mem->phy_addr;
+
+	if (ioreq->uinfo.dir_tx || (ioreq->uinfo.uv_offset == 0)) {
+		sg_cnt = ioreq->sg_cnt;
+		xfr_sz = ioreq->uinfo.xfr_len;
+	} else {
+		sg_cnt = ioreq->uinfo.uv_sg_ix + 1;
+		xfr_sz = ioreq->uinfo.uv_offset;
+	}
+
+	sts = crystalhd_hw_fill_desc(ioreq, desc, desc_paddr_base, sg_cnt,
+				   sg_st_ix, sg_st_off, xfr_sz);
+
+	if ((sts != BC_STS_SUCCESS) || !ioreq->uinfo.uv_offset)
+		return sts;
+
+	/* Prepare for UV mapping.. */
+	desc = &pdesc_mem->pdma_desc_start[sg_cnt];
+	desc_paddr_base = pdesc_mem->phy_addr +
+			  (sg_cnt * sizeof(dma_descriptor));
+
+	/* Done with desc addr.. now update sg stuff.*/
+	sg_cnt    = ioreq->sg_cnt - ioreq->uinfo.uv_sg_ix;
+	xfr_sz    = ioreq->uinfo.xfr_len - ioreq->uinfo.uv_offset;
+	sg_st_ix  = ioreq->uinfo.uv_sg_ix;
+	sg_st_off = ioreq->uinfo.uv_sg_off;
+
+	sts = crystalhd_hw_fill_desc(ioreq, desc, desc_paddr_base, sg_cnt,
+				   sg_st_ix, sg_st_off, xfr_sz);
+	if (sts != BC_STS_SUCCESS)
+		return sts;
+
+	*uv_desc_index = sg_st_ix;
+
+	return sts;
+}
+
+static void crystalhd_start_tx_dma_engine(struct crystalhd_hw *hw)
+{
+	uint32_t dma_cntrl;
+
+	dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS);
+	if (!(dma_cntrl & DMA_START_BIT)) {
+		dma_cntrl |= DMA_START_BIT;
+		crystalhd_reg_wr(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS,
+			       dma_cntrl);
+	}
+
+	return;
+}
+
+/* _CHECK_THIS_
+ *
+ * Verify if the Stop generates a completion interrupt or not.
+ * if it does not generate an interrupt, then add polling here.
+ */
+static BC_STATUS crystalhd_stop_tx_dma_engine(struct crystalhd_hw *hw)
+{
+	uint32_t dma_cntrl, cnt = 30;
+	uint32_t l1 = 1, l2 = 1;
+	unsigned long flags = 0;
+
+	dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS);
+
+	BCMLOG(BCMLOG_DBG, "Stopping TX DMA Engine..\n");
+
+	/* FIXME: jarod: invert dma_ctrl and check bit? or are there missing parens? */
+	if (!dma_cntrl & DMA_START_BIT) {
+		BCMLOG(BCMLOG_DBG, "Already Stopped\n");
+		return BC_STS_SUCCESS;
+	}
+
+	crystalhd_disable_interrupts(hw->adp);
+
+	/* Issue stop to HW */
+	/* This bit when set gave problems. Please check*/
+	dma_cntrl &= ~DMA_START_BIT;
+	crystalhd_reg_wr(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+
+	BCMLOG(BCMLOG_DBG, "Cleared the DMA Start bit\n");
+
+	/* Poll for 3seconds (30 * 100ms) on both the lists..*/
+	while ((l1 || l2) && cnt) {
+
+		if (l1) {
+			l1 = crystalhd_reg_rd(hw->adp, MISC1_TX_FIRST_DESC_L_ADDR_LIST0);
+			l1 &= DMA_START_BIT;
+		}
+
+		if (l2) {
+			l2 = crystalhd_reg_rd(hw->adp, MISC1_TX_FIRST_DESC_L_ADDR_LIST1);
+			l2 &= DMA_START_BIT;
+		}
+
+		msleep_interruptible(100);
+
+		cnt--;
+	}
+
+	if (!cnt) {
+		BCMLOG_ERR("Failed to stop TX DMA.. l1 %d, l2 %d\n", l1, l2);
+		crystalhd_enable_interrupts(hw->adp);
+		return BC_STS_ERROR;
+	}
+
+	spin_lock_irqsave(&hw->lock, flags);
+	hw->tx_list_post_index = 0;
+	spin_unlock_irqrestore(&hw->lock, flags);
+	BCMLOG(BCMLOG_DBG, "stopped TX DMA..\n");
+	crystalhd_enable_interrupts(hw->adp);
+
+	return BC_STS_SUCCESS;
+}
+
+static uint32_t crystalhd_get_pib_avail_cnt(struct crystalhd_hw *hw)
+{
+	/*
+	* Position of the PIB Entries can be found at
+	* 0th and the 1st location of the Circular list.
+	*/
+	uint32_t Q_addr;
+	uint32_t pib_cnt, r_offset, w_offset;
+
+	Q_addr = hw->pib_del_Q_addr;
+
+	/* Get the Read Pointer */
+	crystalhd_mem_rd(hw->adp, Q_addr, 1, &r_offset);
+
+	/* Get the Write Pointer */
+	crystalhd_mem_rd(hw->adp, Q_addr + sizeof(uint32_t), 1, &w_offset);
+
+	if (r_offset == w_offset)
+		return 0;	/* Queue is empty */
+
+	if (w_offset > r_offset)
+		pib_cnt = w_offset - r_offset;
+	else
+		pib_cnt = (w_offset + MAX_PIB_Q_DEPTH) -
+			  (r_offset + MIN_PIB_Q_DEPTH);
+
+	if (pib_cnt > MAX_PIB_Q_DEPTH) {
+		BCMLOG_ERR("Invalid PIB Count (%u)\n", pib_cnt);
+		return 0;
+	}
+
+	return pib_cnt;
+}
+
+static uint32_t crystalhd_get_addr_from_pib_Q(struct crystalhd_hw *hw)
+{
+	uint32_t Q_addr;
+	uint32_t addr_entry, r_offset, w_offset;
+
+	Q_addr = hw->pib_del_Q_addr;
+
+	/* Get the Read Pointer 0Th Location is Read Pointer */
+	crystalhd_mem_rd(hw->adp, Q_addr, 1, &r_offset);
+
+	/* Get the Write Pointer 1st Location is Write pointer */
+	crystalhd_mem_rd(hw->adp, Q_addr + sizeof(uint32_t), 1, &w_offset);
+
+	/* Queue is empty */
+	if (r_offset == w_offset)
+		return 0;
+
+	if ((r_offset < MIN_PIB_Q_DEPTH) || (r_offset >= MAX_PIB_Q_DEPTH))
+		return 0;
+
+	/* Get the Actual Address of the PIB */
+	crystalhd_mem_rd(hw->adp, Q_addr + (r_offset * sizeof(uint32_t)),
+		       1, &addr_entry);
+
+	/* Increment the Read Pointer */
+	r_offset++;
+
+	if (MAX_PIB_Q_DEPTH == r_offset)
+		r_offset = MIN_PIB_Q_DEPTH;
+
+	/* Write back the read pointer to It's Location */
+	crystalhd_mem_wr(hw->adp, Q_addr, 1, &r_offset);
+
+	return addr_entry;
+}
+
+static bool crystalhd_rel_addr_to_pib_Q(struct crystalhd_hw *hw, uint32_t addr_to_rel)
+{
+	uint32_t Q_addr;
+	uint32_t r_offset, w_offset, n_offset;
+
+	Q_addr = hw->pib_rel_Q_addr;
+
+	/* Get the Read Pointer */
+	crystalhd_mem_rd(hw->adp, Q_addr, 1, &r_offset);
+
+	/* Get the Write Pointer */
+	crystalhd_mem_rd(hw->adp, Q_addr + sizeof(uint32_t), 1, &w_offset);
+
+	if ((r_offset < MIN_PIB_Q_DEPTH) ||
+	    (r_offset >= MAX_PIB_Q_DEPTH))
+		return false;
+
+	n_offset = w_offset + 1;
+
+	if (MAX_PIB_Q_DEPTH == n_offset)
+		n_offset = MIN_PIB_Q_DEPTH;
+
+	if (r_offset == n_offset)
+		return false; /* should never happen */
+
+	/* Write the DRAM ADDR to the Queue at Next Offset */
+	crystalhd_mem_wr(hw->adp, Q_addr + (w_offset * sizeof(uint32_t)),
+		       1, &addr_to_rel);
+
+	/* Put the New value of the write pointer in Queue */
+	crystalhd_mem_wr(hw->adp, Q_addr + sizeof(uint32_t), 1, &n_offset);
+
+	return true;
+}
+
+static void cpy_pib_to_app(C011_PIB *src_pib, BC_PIC_INFO_BLOCK *dst_pib)
+{
+	if (!src_pib || !dst_pib) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return;
+	}
+
+	dst_pib->timeStamp           = 0;
+	dst_pib->picture_number      = src_pib->ppb.picture_number;
+	dst_pib->width               = src_pib->ppb.width;
+	dst_pib->height              = src_pib->ppb.height;
+	dst_pib->chroma_format       = src_pib->ppb.chroma_format;
+	dst_pib->pulldown            = src_pib->ppb.pulldown;
+	dst_pib->flags               = src_pib->ppb.flags;
+	dst_pib->sess_num            = src_pib->ptsStcOffset;
+	dst_pib->aspect_ratio        = src_pib->ppb.aspect_ratio;
+	dst_pib->colour_primaries     = src_pib->ppb.colour_primaries;
+	dst_pib->picture_meta_payload = src_pib->ppb.picture_meta_payload;
+	dst_pib->frame_rate		= src_pib->resolution ;
+	return;
+}
+
+static void crystalhd_hw_proc_pib(struct crystalhd_hw *hw)
+{
+	unsigned int cnt;
+	C011_PIB src_pib;
+	uint32_t pib_addr, pib_cnt;
+	BC_PIC_INFO_BLOCK *AppPib;
+	crystalhd_rx_dma_pkt *rx_pkt = NULL;
+
+	pib_cnt = crystalhd_get_pib_avail_cnt(hw);
+
+	if (!pib_cnt)
+		return;
+
+	for (cnt = 0; cnt < pib_cnt; cnt++) {
+
+		pib_addr = crystalhd_get_addr_from_pib_Q(hw);
+		crystalhd_mem_rd(hw->adp, pib_addr, sizeof(C011_PIB) / 4,
+			       (uint32_t *)&src_pib);
+
+		if (src_pib.bFormatChange) {
+			rx_pkt = (crystalhd_rx_dma_pkt *)crystalhd_dioq_fetch(hw->rx_freeq);
+			if (!rx_pkt)
+				return;
+			rx_pkt->flags = 0;
+			rx_pkt->flags |= COMP_FLAG_PIB_VALID | COMP_FLAG_FMT_CHANGE;
+			AppPib = &rx_pkt->pib;
+			cpy_pib_to_app(&src_pib, AppPib);
+
+			BCMLOG(BCMLOG_DBG,
+			       "App PIB:%x %x %x %x %x %x %x %x %x %x\n",
+			       rx_pkt->pib.picture_number,
+			       rx_pkt->pib.aspect_ratio,
+			       rx_pkt->pib.chroma_format,
+			       rx_pkt->pib.colour_primaries,
+			       rx_pkt->pib.frame_rate,
+			       rx_pkt->pib.height,
+			       rx_pkt->pib.height,
+			       rx_pkt->pib.n_drop,
+			       rx_pkt->pib.pulldown,
+			       rx_pkt->pib.ycom);
+
+			crystalhd_dioq_add(hw->rx_rdyq, (void *)rx_pkt, true, rx_pkt->pkt_tag);
+
+		}
+
+		crystalhd_rel_addr_to_pib_Q(hw, pib_addr);
+	}
+}
+
+static void crystalhd_start_rx_dma_engine(struct crystalhd_hw *hw)
+{
+	uint32_t        dma_cntrl;
+
+	dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
+	if (!(dma_cntrl & DMA_START_BIT)) {
+		dma_cntrl |= DMA_START_BIT;
+		crystalhd_reg_wr(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+	}
+
+	dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
+	if (!(dma_cntrl & DMA_START_BIT)) {
+		dma_cntrl |= DMA_START_BIT;
+		crystalhd_reg_wr(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+	}
+
+	return;
+}
+
+static void crystalhd_stop_rx_dma_engine(struct crystalhd_hw *hw)
+{
+	uint32_t dma_cntrl = 0, count = 30;
+	uint32_t l0y = 1, l0uv = 1, l1y = 1, l1uv = 1;
+
+	dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
+	if ((dma_cntrl & DMA_START_BIT)) {
+		dma_cntrl &= ~DMA_START_BIT;
+		crystalhd_reg_wr(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+	}
+
+	dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
+	if ((dma_cntrl & DMA_START_BIT)) {
+		dma_cntrl &= ~DMA_START_BIT;
+		crystalhd_reg_wr(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+	}
+
+	/* Poll for 3seconds (30 * 100ms) on both the lists..*/
+	while ((l0y || l0uv || l1y || l1uv) && count) {
+
+		if (l0y) {
+			l0y = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0);
+			l0y &= DMA_START_BIT;
+			if (!l0y) {
+				hw->rx_list_sts[0] &= ~rx_waiting_y_intr;
+			}
+		}
+
+		if (l1y) {
+			l1y = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1);
+			l1y &= DMA_START_BIT;
+			if (!l1y) {
+				hw->rx_list_sts[1] &= ~rx_waiting_y_intr;
+			}
+		}
+
+		if (l0uv) {
+			l0uv = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0);
+			l0uv &= DMA_START_BIT;
+			if (!l0uv) {
+				hw->rx_list_sts[0] &= ~rx_waiting_uv_intr;
+			}
+		}
+
+		if (l1uv) {
+			l1uv = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1);
+			l1uv &= DMA_START_BIT;
+			if (!l1uv) {
+				hw->rx_list_sts[1] &= ~rx_waiting_uv_intr;
+			}
+		}
+		msleep_interruptible(100);
+		count--;
+	}
+
+	hw->rx_list_post_index = 0;
+
+	BCMLOG(BCMLOG_SSTEP, "Capture Stop: %d List0:Sts:%x List1:Sts:%x\n",
+	       count, hw->rx_list_sts[0], hw->rx_list_sts[1]);
+}
+
+static BC_STATUS crystalhd_hw_prog_rxdma(struct crystalhd_hw *hw, crystalhd_rx_dma_pkt *rx_pkt)
+{
+	uint32_t y_low_addr_reg, y_high_addr_reg;
+	uint32_t uv_low_addr_reg, uv_high_addr_reg;
+	addr_64 desc_addr;
+	unsigned long flags;
+
+	if (!hw || !rx_pkt) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return BC_STS_INV_ARG;
+	}
+
+	if (hw->rx_list_post_index >= DMA_ENGINE_CNT) {
+		BCMLOG_ERR("List Out Of bounds %x\n", hw->rx_list_post_index);
+		return BC_STS_INV_ARG;
+	}
+
+	spin_lock_irqsave(&hw->rx_lock, flags);
+	/* FIXME: jarod: sts_free is an enum for 0, in crystalhd_hw.h... yuk... */
+	if (sts_free != hw->rx_list_sts[hw->rx_list_post_index]) {
+		spin_unlock_irqrestore(&hw->rx_lock, flags);
+		return BC_STS_BUSY;
+	}
+
+	if (!hw->rx_list_post_index) {
+		y_low_addr_reg   = MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0;
+		y_high_addr_reg  = MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST0;
+		uv_low_addr_reg  = MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0;
+		uv_high_addr_reg = MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST0;
+	} else {
+		y_low_addr_reg   = MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1;
+		y_high_addr_reg  = MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST1;
+		uv_low_addr_reg  = MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1;
+		uv_high_addr_reg = MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST1;
+	}
+	rx_pkt->pkt_tag = hw->rx_pkt_tag_seed + hw->rx_list_post_index;
+	hw->rx_list_sts[hw->rx_list_post_index] |= rx_waiting_y_intr;
+	if (rx_pkt->uv_phy_addr)
+		hw->rx_list_sts[hw->rx_list_post_index] |= rx_waiting_uv_intr;
+	hw->rx_list_post_index = (hw->rx_list_post_index + 1) % DMA_ENGINE_CNT;
+	spin_unlock_irqrestore(&hw->rx_lock, flags);
+
+	crystalhd_dioq_add(hw->rx_actq, (void *)rx_pkt, false, rx_pkt->pkt_tag);
+
+	crystalhd_start_rx_dma_engine(hw);
+	/* Program the Y descriptor */
+	desc_addr.full_addr = rx_pkt->desc_mem.phy_addr;
+	crystalhd_reg_wr(hw->adp, y_high_addr_reg, desc_addr.high_part);
+	crystalhd_reg_wr(hw->adp, y_low_addr_reg, desc_addr.low_part | 0x01);
+
+	if (rx_pkt->uv_phy_addr) {
+		/* Program the UV descriptor */
+		desc_addr.full_addr = rx_pkt->uv_phy_addr;
+		crystalhd_reg_wr(hw->adp, uv_high_addr_reg, desc_addr.high_part);
+		crystalhd_reg_wr(hw->adp, uv_low_addr_reg, desc_addr.low_part | 0x01);
+	}
+
+	return BC_STS_SUCCESS;
+}
+
+static BC_STATUS crystalhd_hw_post_cap_buff(struct crystalhd_hw *hw,
+					  crystalhd_rx_dma_pkt *rx_pkt)
+{
+	BC_STATUS sts = crystalhd_hw_prog_rxdma(hw, rx_pkt);
+
+	if (sts == BC_STS_BUSY)
+		crystalhd_dioq_add(hw->rx_freeq, (void *)rx_pkt,
+				 false, rx_pkt->pkt_tag);
+
+	return sts;
+}
+
+static void crystalhd_get_dnsz(struct crystalhd_hw *hw, uint32_t list_index,
+			     uint32_t *y_dw_dnsz, uint32_t *uv_dw_dnsz)
+{
+	uint32_t y_dn_sz_reg, uv_dn_sz_reg;
+
+	if (!list_index) {
+		y_dn_sz_reg  = MISC1_Y_RX_LIST0_CUR_BYTE_CNT;
+		uv_dn_sz_reg = MISC1_UV_RX_LIST0_CUR_BYTE_CNT;
+	} else {
+		y_dn_sz_reg  = MISC1_Y_RX_LIST1_CUR_BYTE_CNT;
+		uv_dn_sz_reg = MISC1_UV_RX_LIST1_CUR_BYTE_CNT;
+	}
+
+	*y_dw_dnsz  = crystalhd_reg_rd(hw->adp, y_dn_sz_reg);
+	*uv_dw_dnsz = crystalhd_reg_rd(hw->adp, uv_dn_sz_reg);
+}
+
+/*
+ * This function should be called only after making sure that the two DMA
+ * lists are free. This function does not check if DMA's are active, before
+ * turning off the DMA.
+ */
+static void crystalhd_hw_finalize_pause(struct crystalhd_hw *hw)
+{
+	uint32_t dma_cntrl, aspm;
+
+	hw->stop_pending = 0;
+
+	dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
+	if (dma_cntrl & DMA_START_BIT) {
+		dma_cntrl &= ~DMA_START_BIT;
+		crystalhd_reg_wr(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+	}
+
+	dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
+	if (dma_cntrl & DMA_START_BIT) {
+		dma_cntrl &= ~DMA_START_BIT;
+		crystalhd_reg_wr(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+	}
+	hw->rx_list_post_index = 0;
+
+	aspm = crystalhd_reg_rd(hw->adp, PCIE_DLL_DATA_LINK_CONTROL);
+	aspm |= ASPM_L1_ENABLE;
+	/* NAREN BCMLOG(BCMLOG_INFO, "aspm on\n"); */
+	crystalhd_reg_wr(hw->adp, PCIE_DLL_DATA_LINK_CONTROL, aspm);
+}
+
+static BC_STATUS crystalhd_rx_pkt_done(struct crystalhd_hw *hw, uint32_t list_index,
+				     BC_STATUS comp_sts)
+{
+	crystalhd_rx_dma_pkt *rx_pkt = NULL;
+	uint32_t y_dw_dnsz, uv_dw_dnsz;
+	BC_STATUS sts = BC_STS_SUCCESS;
+
+	if (!hw || list_index >= DMA_ENGINE_CNT) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return BC_STS_INV_ARG;
+	}
+
+	rx_pkt = crystalhd_dioq_find_and_fetch(hw->rx_actq,
+					     hw->rx_pkt_tag_seed + list_index);
+	if (!rx_pkt) {
+		BCMLOG_ERR("Act-Q:PostIx:%x L0Sts:%x L1Sts:%x current L:%x tag:%x comp:%x\n",
+			   hw->rx_list_post_index, hw->rx_list_sts[0],
+			   hw->rx_list_sts[1], list_index,
+			   hw->rx_pkt_tag_seed + list_index, comp_sts);
+		return BC_STS_INV_ARG;
+	}
+
+	if (comp_sts == BC_STS_SUCCESS) {
+		crystalhd_get_dnsz(hw, list_index, &y_dw_dnsz, &uv_dw_dnsz);
+		rx_pkt->dio_req->uinfo.y_done_sz = y_dw_dnsz;
+		rx_pkt->flags = COMP_FLAG_DATA_VALID;
+		if (rx_pkt->uv_phy_addr)
+			rx_pkt->dio_req->uinfo.uv_done_sz = uv_dw_dnsz;
+		crystalhd_dioq_add(hw->rx_rdyq, rx_pkt, true,
+				hw->rx_pkt_tag_seed + list_index);
+		return sts;
+	}
+
+	/* Check if we can post this DIO again. */
+	return crystalhd_hw_post_cap_buff(hw, rx_pkt);
+}
+
+static bool crystalhd_rx_list0_handler(struct crystalhd_hw *hw, uint32_t int_sts,
+				     uint32_t y_err_sts, uint32_t uv_err_sts)
+{
+	uint32_t tmp;
+	list_sts tmp_lsts;
+
+	if (!(y_err_sts & GET_Y0_ERR_MSK) && !(uv_err_sts & GET_UV0_ERR_MSK))
+		return false;
+
+	tmp_lsts = hw->rx_list_sts[0];
+
+	/* Y0 - DMA */
+	tmp = y_err_sts & GET_Y0_ERR_MSK;
+	if (int_sts & INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK)
+		hw->rx_list_sts[0] &= ~rx_waiting_y_intr;
+
+	if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK) {
+		hw->rx_list_sts[0] &= ~rx_waiting_y_intr;
+		tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK;
+	}
+
+	if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK) {
+		hw->rx_list_sts[0] &= ~rx_y_mask;
+		hw->rx_list_sts[0] |= rx_y_error;
+		tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK;
+	}
+
+	if (tmp) {
+		hw->rx_list_sts[0] &= ~rx_y_mask;
+		hw->rx_list_sts[0] |= rx_y_error;
+		hw->rx_list_post_index = 0;
+	}
+
+	/* UV0 - DMA */
+	tmp = uv_err_sts & GET_UV0_ERR_MSK;
+	if (int_sts & INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK)
+		hw->rx_list_sts[0] &= ~rx_waiting_uv_intr;
+
+	if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK) {
+		hw->rx_list_sts[0] &= ~rx_waiting_uv_intr;
+		tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK;
+	}
+
+	if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK) {
+		hw->rx_list_sts[0] &= ~rx_uv_mask;
+		hw->rx_list_sts[0] |= rx_uv_error;
+		tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK;
+	}
+
+	if (tmp) {
+		hw->rx_list_sts[0] &= ~rx_uv_mask;
+		hw->rx_list_sts[0] |= rx_uv_error;
+		hw->rx_list_post_index = 0;
+	}
+
+	if (y_err_sts & GET_Y0_ERR_MSK) {
+		tmp = y_err_sts & GET_Y0_ERR_MSK;
+		crystalhd_reg_wr(hw->adp, MISC1_Y_RX_ERROR_STATUS, tmp);
+	}
+
+	if (uv_err_sts & GET_UV0_ERR_MSK) {
+		tmp = uv_err_sts & GET_UV0_ERR_MSK;
+		crystalhd_reg_wr(hw->adp, MISC1_UV_RX_ERROR_STATUS, tmp);
+	}
+
+	return (tmp_lsts != hw->rx_list_sts[0]);
+}
+
+static bool crystalhd_rx_list1_handler(struct crystalhd_hw *hw, uint32_t int_sts,
+				     uint32_t y_err_sts, uint32_t uv_err_sts)
+{
+	uint32_t tmp;
+	list_sts tmp_lsts;
+
+	if (!(y_err_sts & GET_Y1_ERR_MSK) && !(uv_err_sts & GET_UV1_ERR_MSK))
+		return false;
+
+	tmp_lsts = hw->rx_list_sts[1];
+
+	/* Y1 - DMA */
+	tmp = y_err_sts & GET_Y1_ERR_MSK;
+	if (int_sts & INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK)
+		hw->rx_list_sts[1] &= ~rx_waiting_y_intr;
+
+	if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK) {
+		hw->rx_list_sts[1] &= ~rx_waiting_y_intr;
+		tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK;
+	}
+
+	if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK) {
+		/* Add retry-support..*/
+		hw->rx_list_sts[1] &= ~rx_y_mask;
+		hw->rx_list_sts[1] |= rx_y_error;
+		tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK;
+	}
+
+	if (tmp) {
+		hw->rx_list_sts[1] &= ~rx_y_mask;
+		hw->rx_list_sts[1] |= rx_y_error;
+		hw->rx_list_post_index = 0;
+	}
+
+	/* UV1 - DMA */
+	tmp = uv_err_sts & GET_UV1_ERR_MSK;
+	if (int_sts & INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK) {
+		hw->rx_list_sts[1] &= ~rx_waiting_uv_intr;
+	}
+
+	if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK) {
+		hw->rx_list_sts[1] &= ~rx_waiting_uv_intr;
+		tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK;
+	}
+
+	if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK) {
+		/* Add retry-support*/
+		hw->rx_list_sts[1] &= ~rx_uv_mask;
+		hw->rx_list_sts[1] |= rx_uv_error;
+		tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK;
+	}
+
+	if (tmp) {
+		hw->rx_list_sts[1] &= ~rx_uv_mask;
+		hw->rx_list_sts[1] |= rx_uv_error;
+		hw->rx_list_post_index = 0;
+	}
+
+	if (y_err_sts & GET_Y1_ERR_MSK) {
+		tmp = y_err_sts & GET_Y1_ERR_MSK;
+		crystalhd_reg_wr(hw->adp, MISC1_Y_RX_ERROR_STATUS, tmp);
+	}
+
+	if (uv_err_sts & GET_UV1_ERR_MSK) {
+		tmp = uv_err_sts & GET_UV1_ERR_MSK;
+		crystalhd_reg_wr(hw->adp, MISC1_UV_RX_ERROR_STATUS, tmp);
+	}
+
+	return (tmp_lsts != hw->rx_list_sts[1]);
+}
+
+
+static void crystalhd_rx_isr(struct crystalhd_hw *hw, uint32_t intr_sts)
+{
+	unsigned long flags;
+	uint32_t i, list_avail = 0;
+	BC_STATUS comp_sts = BC_STS_NO_DATA;
+	uint32_t y_err_sts, uv_err_sts, y_dn_sz = 0, uv_dn_sz = 0;
+	bool ret = 0;
+
+	if (!hw) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return;
+	}
+
+	if (!(intr_sts & GET_RX_INTR_MASK))
+		return;
+
+	y_err_sts = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_ERROR_STATUS);
+	uv_err_sts = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_ERROR_STATUS);
+
+	for (i = 0; i < DMA_ENGINE_CNT; i++) {
+		/* Update States..*/
+		spin_lock_irqsave(&hw->rx_lock, flags);
+		if (i == 0)
+			ret = crystalhd_rx_list0_handler(hw, intr_sts, y_err_sts, uv_err_sts);
+		else
+			ret = crystalhd_rx_list1_handler(hw, intr_sts, y_err_sts, uv_err_sts);
+		if (ret) {
+			switch (hw->rx_list_sts[i]) {
+			case sts_free:
+				comp_sts = BC_STS_SUCCESS;
+				list_avail = 1;
+				break;
+			case rx_y_error:
+			case rx_uv_error:
+			case rx_sts_error:
+				/* We got error on both or Y or uv. */
+				hw->stats.rx_errors++;
+				crystalhd_get_dnsz(hw, i, &y_dn_sz, &uv_dn_sz);
+				/* FIXME: jarod: this is where my mini pci-e card is tripping up */
+				BCMLOG(BCMLOG_DBG, "list_index:%x rx[%d] Y:%x "
+				       "UV:%x Int:%x YDnSz:%x UVDnSz:%x\n",
+				       i, hw->stats.rx_errors, y_err_sts,
+				       uv_err_sts, intr_sts, y_dn_sz, uv_dn_sz);
+				hw->rx_list_sts[i] = sts_free;
+				comp_sts = BC_STS_ERROR;
+				break;
+			default:
+				/* Wait for completion..*/
+				comp_sts = BC_STS_NO_DATA;
+				break;
+			}
+		}
+		spin_unlock_irqrestore(&hw->rx_lock, flags);
+
+		/* handle completion...*/
+		if (comp_sts != BC_STS_NO_DATA) {
+			crystalhd_rx_pkt_done(hw, i, comp_sts);
+			comp_sts = BC_STS_NO_DATA;
+		}
+	}
+
+	if (list_avail) {
+		if (hw->stop_pending) {
+			if ((hw->rx_list_sts[0] == sts_free) &&
+			    (hw->rx_list_sts[1] == sts_free))
+				crystalhd_hw_finalize_pause(hw);
+		} else {
+			crystalhd_hw_start_capture(hw);
+		}
+	}
+}
+
+static BC_STATUS crystalhd_fw_cmd_post_proc(struct crystalhd_hw *hw,
+					  BC_FW_CMD *fw_cmd)
+{
+	BC_STATUS sts = BC_STS_SUCCESS;
+	DecRspChannelStartVideo *st_rsp = NULL;
+
+	switch (fw_cmd->cmd[0]) {
+	case eCMD_C011_DEC_CHAN_START_VIDEO:
+		st_rsp = (DecRspChannelStartVideo *)fw_cmd->rsp;
+		hw->pib_del_Q_addr = st_rsp->picInfoDeliveryQ;
+		hw->pib_rel_Q_addr = st_rsp->picInfoReleaseQ;
+		BCMLOG(BCMLOG_DBG, "DelQAddr:%x RelQAddr:%x\n",
+		       hw->pib_del_Q_addr, hw->pib_rel_Q_addr);
+		break;
+	case eCMD_C011_INIT:
+		if (!(crystalhd_load_firmware_config(hw->adp))) {
+			BCMLOG_ERR("Invalid Params.\n");
+			sts = BC_STS_FW_AUTH_FAILED;
+		}
+		break;
+	default:
+		break;
+	}
+	return sts;
+}
+
+static BC_STATUS crystalhd_put_ddr2sleep(struct crystalhd_hw *hw)
+{
+	uint32_t reg;
+	link_misc_perst_decoder_ctrl rst_cntrl_reg;
+
+	/* Pulse reset pin of 7412 (MISC_PERST_DECODER_CTRL) */
+	rst_cntrl_reg.whole_reg = crystalhd_reg_rd(hw->adp, MISC_PERST_DECODER_CTRL);
+
+	rst_cntrl_reg.bcm_7412_rst = 1;
+	crystalhd_reg_wr(hw->adp, MISC_PERST_DECODER_CTRL, rst_cntrl_reg.whole_reg);
+	msleep_interruptible(50);
+
+	rst_cntrl_reg.bcm_7412_rst = 0;
+	crystalhd_reg_wr(hw->adp, MISC_PERST_DECODER_CTRL, rst_cntrl_reg.whole_reg);
+
+	/* Close all banks, put DDR in idle */
+	bc_dec_reg_wr(hw->adp, SDRAM_PRECHARGE, 0);
+
+	/* Set bit 25 (drop CKE pin of DDR) */
+	reg = bc_dec_reg_rd(hw->adp, SDRAM_PARAM);
+	reg |= 0x02000000;
+	bc_dec_reg_wr(hw->adp, SDRAM_PARAM, reg);
+
+	/* Reset the audio block */
+	bc_dec_reg_wr(hw->adp, AUD_DSP_MISC_SOFT_RESET, 0x1);
+
+	/* Power down Raptor PLL */
+	reg = bc_dec_reg_rd(hw->adp, DecHt_PllCCtl);
+	reg |= 0x00008000;
+	bc_dec_reg_wr(hw->adp, DecHt_PllCCtl, reg);
+
+	/* Power down all Audio PLL */
+	bc_dec_reg_wr(hw->adp, AIO_MISC_PLL_RESET, 0x1);
+
+	/* Power down video clock (75MHz) */
+	reg = bc_dec_reg_rd(hw->adp, DecHt_PllECtl);
+	reg |= 0x00008000;
+	bc_dec_reg_wr(hw->adp, DecHt_PllECtl, reg);
+
+	/* Power down video clock (75MHz) */
+	reg = bc_dec_reg_rd(hw->adp, DecHt_PllDCtl);
+	reg |= 0x00008000;
+	bc_dec_reg_wr(hw->adp, DecHt_PllDCtl, reg);
+
+	/* Power down core clock (200MHz) */
+	reg = bc_dec_reg_rd(hw->adp, DecHt_PllACtl);
+	reg |= 0x00008000;
+	bc_dec_reg_wr(hw->adp, DecHt_PllACtl, reg);
+
+	/* Power down core clock (200MHz) */
+	reg = bc_dec_reg_rd(hw->adp, DecHt_PllBCtl);
+	reg |= 0x00008000;
+	bc_dec_reg_wr(hw->adp, DecHt_PllBCtl, reg);
+
+	return BC_STS_SUCCESS;
+}
+
+/************************************************
+**
+*************************************************/
+
+BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp, void *buffer, uint32_t sz)
+{
+	uint32_t reg_data, cnt, *temp_buff;
+	uint32_t fw_sig_len = 36;
+	uint32_t dram_offset = BC_FWIMG_ST_ADDR, sig_reg;
+
+	BCMLOG_ENTER;
+
+	if (!adp || !buffer || !sz) {
+		BCMLOG_ERR("Invalid Params.\n");
+		return BC_STS_INV_ARG;
+	}
+
+	reg_data = crystalhd_reg_rd(adp, OTP_CMD);
+	if (!(reg_data & 0x02)) {
+		BCMLOG_ERR("Invalid hw config.. otp not programmed\n");
+		return BC_STS_ERROR;
+	}
+
+	reg_data = 0;
+	crystalhd_reg_wr(adp, DCI_CMD, 0);
+	reg_data |= BC_BIT(0);
+	crystalhd_reg_wr(adp, DCI_CMD, reg_data);
+
+	reg_data = 0;
+	cnt = 1000;
+	msleep_interruptible(10);
+
+	while (reg_data != BC_BIT(4)) {
+		reg_data = crystalhd_reg_rd(adp, DCI_STATUS);
+		reg_data &= BC_BIT(4);
+		if (--cnt == 0) {
+			BCMLOG_ERR("Firmware Download RDY Timeout.\n");
+			return BC_STS_TIMEOUT;
+		}
+	}
+
+	msleep_interruptible(10);
+	/*  Load the FW to the FW_ADDR field in the DCI_FIRMWARE_ADDR */
+	crystalhd_reg_wr(adp, DCI_FIRMWARE_ADDR, dram_offset);
+	temp_buff = (uint32_t *)buffer;
+	for (cnt = 0; cnt < (sz - fw_sig_len); cnt += 4) {
+		crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (dram_offset >> 19));
+		crystalhd_reg_wr(adp, DCI_FIRMWARE_DATA, *temp_buff);
+		dram_offset += 4;
+		temp_buff++;
+	}
+	msleep_interruptible(10);
+
+	temp_buff++;
+
+	sig_reg = (uint32_t)DCI_SIGNATURE_DATA_7;
+	for (cnt = 0; cnt < 8; cnt++) {
+		uint32_t swapped_data = *temp_buff;
+		swapped_data = bswap_32_1(swapped_data);
+		crystalhd_reg_wr(adp, sig_reg, swapped_data);
+		sig_reg -= 4;
+		temp_buff++;
+	}
+	msleep_interruptible(10);
+
+	reg_data = 0;
+	reg_data |= BC_BIT(1);
+	crystalhd_reg_wr(adp, DCI_CMD, reg_data);
+	msleep_interruptible(10);
+
+	reg_data = 0;
+	reg_data = crystalhd_reg_rd(adp, DCI_STATUS);
+
+	if ((reg_data & BC_BIT(9)) == BC_BIT(9)) {
+		cnt = 1000;
+		while ((reg_data & BC_BIT(0)) != BC_BIT(0)) {
+			reg_data = crystalhd_reg_rd(adp, DCI_STATUS);
+			reg_data &= BC_BIT(0);
+			if (!(--cnt))
+				break;
+			msleep_interruptible(10);
+		}
+		reg_data = 0;
+		reg_data = crystalhd_reg_rd(adp, DCI_CMD);
+		reg_data |= BC_BIT(4);
+		crystalhd_reg_wr(adp, DCI_CMD, reg_data);
+
+	} else {
+		BCMLOG_ERR("F/w Signature mismatch\n");
+		return BC_STS_FW_AUTH_FAILED;
+	}
+
+	BCMLOG(BCMLOG_INFO, "Firmware Downloaded Successfully\n");
+	return BC_STS_SUCCESS;;
+}
+
+BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, BC_FW_CMD *fw_cmd)
+{
+	uint32_t cnt = 0, cmd_res_addr;
+	uint32_t *cmd_buff, *res_buff;
+	wait_queue_head_t fw_cmd_event;
+	int rc = 0;
+	BC_STATUS sts;
+
+	crystalhd_create_event(&fw_cmd_event);
+
+	BCMLOG_ENTER;
+
+	if (!hw || !fw_cmd) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return BC_STS_INV_ARG;
+	}
+
+	cmd_buff = fw_cmd->cmd;
+	res_buff = fw_cmd->rsp;
+
+	if (!cmd_buff || !res_buff) {
+		BCMLOG_ERR("Invalid Parameters for F/W Command \n");
+		return BC_STS_INV_ARG;
+	}
+
+	hw->pwr_lock++;
+
+	hw->fwcmd_evt_sts = 0;
+	hw->pfw_cmd_event = &fw_cmd_event;
+
+	/*Write the command to the memory*/
+	crystalhd_mem_wr(hw->adp, TS_Host2CpuSnd, FW_CMD_BUFF_SZ, cmd_buff);
+
+	/*Memory Read for memory arbitrator flush*/
+	crystalhd_mem_rd(hw->adp, TS_Host2CpuSnd, 1, &cnt);
+
+	/* Write the command address to mailbox */
+	bc_dec_reg_wr(hw->adp, Hst2CpuMbx1, TS_Host2CpuSnd);
+	msleep_interruptible(50);
+
+	crystalhd_wait_on_event(&fw_cmd_event, hw->fwcmd_evt_sts, 20000, rc, 0);
+
+	if (!rc) {
+		sts = BC_STS_SUCCESS;
+	} else if (rc == -EBUSY) {
+		BCMLOG_ERR("Firmware command T/O\n");
+		sts = BC_STS_TIMEOUT;
+	} else if (rc == -EINTR) {
+		BCMLOG(BCMLOG_DBG, "FwCmd Wait Signal int.\n");
+		sts = BC_STS_IO_USER_ABORT;
+	} else {
+		BCMLOG_ERR("FwCmd IO Error.\n");
+		sts = BC_STS_IO_ERROR;
+	}
+
+	if (sts != BC_STS_SUCCESS) {
+		BCMLOG_ERR("FwCmd Failed.\n");
+		hw->pwr_lock--;
+		return sts;
+	}
+
+	/*Get the Responce Address*/
+	cmd_res_addr = bc_dec_reg_rd(hw->adp, Cpu2HstMbx1);
+
+	/*Read the Response*/
+	crystalhd_mem_rd(hw->adp, cmd_res_addr, FW_CMD_BUFF_SZ, res_buff);
+
+	hw->pwr_lock--;
+
+	if (res_buff[2] != C011_RET_SUCCESS) {
+		BCMLOG_ERR("res_buff[2] != C011_RET_SUCCESS\n");
+		return BC_STS_FW_CMD_ERR;
+	}
+
+	sts = crystalhd_fw_cmd_post_proc(hw, fw_cmd);
+	if (sts != BC_STS_SUCCESS)
+		BCMLOG_ERR("crystalhd_fw_cmd_post_proc Failed.\n");
+
+	return sts;
+}
+
+bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw)
+{
+	uint32_t intr_sts = 0;
+	uint32_t deco_intr = 0;
+	bool rc = 0;
+
+	if (!adp || !hw->dev_started)
+		return rc;
+
+	hw->stats.num_interrupts++;
+	hw->pwr_lock++;
+
+	deco_intr = bc_dec_reg_rd(adp, Stream2Host_Intr_Sts);
+	intr_sts  = crystalhd_reg_rd(adp, INTR_INTR_STATUS);
+
+	if (intr_sts) {
+		/* let system know we processed interrupt..*/
+		rc = 1;
+		hw->stats.dev_interrupts++;
+	}
+
+	if (deco_intr && (deco_intr != 0xdeaddead)) {
+
+		if (deco_intr & 0x80000000) {
+			/*Set the Event and the status flag*/
+			if (hw->pfw_cmd_event) {
+				hw->fwcmd_evt_sts = 1;
+				crystalhd_set_event(hw->pfw_cmd_event);
+			}
+		}
+
+		if (deco_intr & BC_BIT(1))
+			crystalhd_hw_proc_pib(hw);
+
+		bc_dec_reg_wr(adp, Stream2Host_Intr_Sts, deco_intr);
+		/* FIXME: jarod: No udelay? might this be the real reason mini pci-e cards were stalling out? */
+		bc_dec_reg_wr(adp, Stream2Host_Intr_Sts, 0);
+		rc = 1;
+	}
+
+	/* Rx interrupts */
+	crystalhd_rx_isr(hw, intr_sts);
+
+	/* Tx interrupts*/
+	crystalhd_tx_isr(hw, intr_sts);
+
+	/* Clear interrupts */
+	if (rc) {
+		if (intr_sts)
+			crystalhd_reg_wr(adp, INTR_INTR_CLR_REG, intr_sts);
+
+		crystalhd_reg_wr(adp, INTR_EOI_CTRL, 1);
+	}
+
+	hw->pwr_lock--;
+
+	return rc;
+}
+
+BC_STATUS crystalhd_hw_open(struct crystalhd_hw *hw, struct crystalhd_adp *adp)
+{
+	if (!hw || !adp) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return BC_STS_INV_ARG;
+	}
+
+	if (hw->dev_started)
+		return BC_STS_SUCCESS;
+
+	memset(hw, 0, sizeof(struct crystalhd_hw));
+
+	hw->adp = adp;
+	spin_lock_init(&hw->lock);
+	spin_lock_init(&hw->rx_lock);
+	/* FIXME: jarod: what are these magic numbers?!? */
+	hw->tx_ioq_tag_seed = 0x70023070;
+	hw->rx_pkt_tag_seed = 0x70029070;
+
+	hw->stop_pending = 0;
+	crystalhd_start_device(hw->adp);
+	hw->dev_started = true;
+
+	/* set initial core clock  */
+	hw->core_clock_mhz = CLOCK_PRESET;
+	hw->prev_n = 0;
+	hw->pwr_lock = 0;
+	crystalhd_hw_set_core_clock(hw);
+
+	return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_close(struct crystalhd_hw *hw)
+{
+	if (!hw) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return BC_STS_INV_ARG;
+	}
+
+	if (!hw->dev_started)
+		return BC_STS_SUCCESS;
+
+	/* Stop and DDR sleep will happen in here */
+	crystalhd_hw_suspend(hw);
+	hw->dev_started = false;
+
+	return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *hw)
+{
+	unsigned int i;
+	void *mem;
+	size_t mem_len;
+	dma_addr_t phy_addr;
+	BC_STATUS sts = BC_STS_SUCCESS;
+	crystalhd_rx_dma_pkt *rpkt;
+
+	if (!hw || !hw->adp) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return BC_STS_INV_ARG;
+	}
+
+	sts = crystalhd_hw_create_ioqs(hw);
+	if (sts != BC_STS_SUCCESS) {
+		BCMLOG_ERR("Failed to create IOQs..\n");
+		return sts;
+	}
+
+	mem_len = BC_LINK_MAX_SGLS * sizeof(dma_descriptor);
+
+	for (i = 0; i < BC_TX_LIST_CNT; i++) {
+		mem = bc_kern_dma_alloc(hw->adp, mem_len, &phy_addr);
+		if (mem) {
+			memset(mem, 0, mem_len);
+		} else {
+			BCMLOG_ERR("Insufficient Memory For TX\n");
+			crystalhd_hw_free_dma_rings(hw);
+			return BC_STS_INSUFF_RES;
+		}
+		/* rx_pkt_pool -- static memory allocation  */
+		hw->tx_pkt_pool[i].desc_mem.pdma_desc_start = mem;
+		hw->tx_pkt_pool[i].desc_mem.phy_addr = phy_addr;
+		hw->tx_pkt_pool[i].desc_mem.sz = BC_LINK_MAX_SGLS *
+						 sizeof(dma_descriptor);
+		hw->tx_pkt_pool[i].list_tag = 0;
+
+		/* Add TX dma requests to Free Queue..*/
+		sts = crystalhd_dioq_add(hw->tx_freeq,
+				       &hw->tx_pkt_pool[i], false, 0);
+		if (sts != BC_STS_SUCCESS) {
+			crystalhd_hw_free_dma_rings(hw);
+			return sts;
+		}
+	}
+
+	for (i = 0; i < BC_RX_LIST_CNT; i++) {
+		rpkt = kzalloc(sizeof(*rpkt), GFP_KERNEL);
+		if (!rpkt) {
+			BCMLOG_ERR("Insufficient Memory For RX\n");
+			crystalhd_hw_free_dma_rings(hw);
+			return BC_STS_INSUFF_RES;
+		}
+
+		mem = bc_kern_dma_alloc(hw->adp, mem_len, &phy_addr);
+		if (mem) {
+			memset(mem, 0, mem_len);
+		} else {
+			BCMLOG_ERR("Insufficient Memory For RX\n");
+			crystalhd_hw_free_dma_rings(hw);
+			return BC_STS_INSUFF_RES;
+		}
+		rpkt->desc_mem.pdma_desc_start = mem;
+		rpkt->desc_mem.phy_addr = phy_addr;
+		rpkt->desc_mem.sz  = BC_LINK_MAX_SGLS * sizeof(dma_descriptor);
+		rpkt->pkt_tag = hw->rx_pkt_tag_seed + i;
+		crystalhd_hw_free_rx_pkt(hw, rpkt);
+	}
+
+	return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *hw)
+{
+	unsigned int i;
+	crystalhd_rx_dma_pkt *rpkt = NULL;
+
+	if (!hw || !hw->adp) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return BC_STS_INV_ARG;
+	}
+
+	/* Delete all IOQs.. */
+	crystalhd_hw_delete_ioqs(hw);
+
+	for (i = 0; i < BC_TX_LIST_CNT; i++) {
+		if (hw->tx_pkt_pool[i].desc_mem.pdma_desc_start) {
+			bc_kern_dma_free(hw->adp,
+				hw->tx_pkt_pool[i].desc_mem.sz,
+				hw->tx_pkt_pool[i].desc_mem.pdma_desc_start,
+				hw->tx_pkt_pool[i].desc_mem.phy_addr);
+
+			hw->tx_pkt_pool[i].desc_mem.pdma_desc_start = NULL;
+		}
+	}
+
+	BCMLOG(BCMLOG_DBG, "Releasing RX Pkt pool\n");
+	do {
+		rpkt = crystalhd_hw_alloc_rx_pkt(hw);
+		if (!rpkt)
+			break;
+		bc_kern_dma_free(hw->adp, rpkt->desc_mem.sz,
+				 rpkt->desc_mem.pdma_desc_start,
+				 rpkt->desc_mem.phy_addr);
+		kfree(rpkt);
+	} while (rpkt);
+
+	return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, crystalhd_dio_req *ioreq,
+			     hw_comp_callback call_back,
+			     wait_queue_head_t *cb_event, uint32_t *list_id,
+			     uint8_t data_flags)
+{
+	tx_dma_pkt *tx_dma_packet = NULL;
+	uint32_t first_desc_u_addr, first_desc_l_addr;
+	uint32_t low_addr, high_addr;
+	addr_64 desc_addr;
+	BC_STATUS sts, add_sts;
+	uint32_t dummy_index = 0;
+	unsigned long flags;
+	bool rc;
+
+	if (!hw || !ioreq || !call_back || !cb_event || !list_id) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return BC_STS_INV_ARG;
+	}
+
+	/*
+	 * Since we hit code in busy condition very frequently,
+	 * we will check the code in status first before
+	 * checking the availability of free elem.
+	 *
+	 * This will avoid the Q fetch/add in normal condition.
+	 */
+	rc = crystalhd_code_in_full(hw->adp, ioreq->uinfo.xfr_len,
+				  false, data_flags);
+	if (rc) {
+		hw->stats.cin_busy++;
+		return BC_STS_BUSY;
+	}
+
+	/* Get a list from TxFreeQ */
+	tx_dma_packet = (tx_dma_pkt *)crystalhd_dioq_fetch(hw->tx_freeq);
+	if (!tx_dma_packet) {
+		BCMLOG_ERR("No empty elements..\n");
+		return BC_STS_ERR_USAGE;
+	}
+
+	sts = crystalhd_xlat_sgl_to_dma_desc(ioreq,
+					   &tx_dma_packet->desc_mem,
+					   &dummy_index);
+	if (sts != BC_STS_SUCCESS) {
+		add_sts = crystalhd_dioq_add(hw->tx_freeq, tx_dma_packet,
+					   false, 0);
+		if (add_sts != BC_STS_SUCCESS)
+			BCMLOG_ERR("double fault..\n");
+
+		return sts;
+	}
+
+	hw->pwr_lock++;
+
+	desc_addr.full_addr = tx_dma_packet->desc_mem.phy_addr;
+	low_addr = desc_addr.low_part;
+	high_addr = desc_addr.high_part;
+
+	tx_dma_packet->call_back = call_back;
+	tx_dma_packet->cb_event  = cb_event;
+	tx_dma_packet->dio_req   = ioreq;
+
+	spin_lock_irqsave(&hw->lock, flags);
+
+	if (hw->tx_list_post_index == 0) {
+		first_desc_u_addr = MISC1_TX_FIRST_DESC_U_ADDR_LIST0;
+		first_desc_l_addr = MISC1_TX_FIRST_DESC_L_ADDR_LIST0;
+	} else {
+		first_desc_u_addr = MISC1_TX_FIRST_DESC_U_ADDR_LIST1;
+		first_desc_l_addr = MISC1_TX_FIRST_DESC_L_ADDR_LIST1;
+	}
+
+	*list_id = tx_dma_packet->list_tag = hw->tx_ioq_tag_seed +
+					     hw->tx_list_post_index;
+
+	hw->tx_list_post_index = (hw->tx_list_post_index + 1) % DMA_ENGINE_CNT;
+
+	spin_unlock_irqrestore(&hw->lock, flags);
+
+
+	/* Insert in Active Q..*/
+	crystalhd_dioq_add(hw->tx_actq, tx_dma_packet, false,
+			 tx_dma_packet->list_tag);
+
+	/*
+	 * Interrupt will come as soon as you write
+	 * the valid bit. So be ready for that. All
+	 * the initialization should happen before that.
+	 */
+	crystalhd_start_tx_dma_engine(hw);
+	crystalhd_reg_wr(hw->adp, first_desc_u_addr, desc_addr.high_part);
+
+	crystalhd_reg_wr(hw->adp, first_desc_l_addr, desc_addr.low_part | 0x01);
+					/* Be sure we set the valid bit ^^^^ */
+
+	return BC_STS_SUCCESS;
+}
+
+/*
+ * This is a force cancel and we are racing with ISR.
+ *
+ * Will try to remove the req from ActQ before ISR gets it.
+ * If ISR gets it first then the completion happens in the
+ * normal path and we will return _STS_NO_DATA from here.
+ *
+ * FIX_ME: Not Tested the actual condition..
+ */
+BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id)
+{
+	if (!hw || !list_id) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return BC_STS_INV_ARG;
+	}
+
+	crystalhd_stop_tx_dma_engine(hw);
+	crystalhd_hw_tx_req_complete(hw, list_id, BC_STS_IO_USER_ABORT);
+
+	return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw,
+				    crystalhd_dio_req *ioreq, bool en_post)
+{
+	crystalhd_rx_dma_pkt *rpkt;
+	uint32_t tag, uv_desc_ix = 0;
+	BC_STATUS sts;
+
+	if (!hw || !ioreq) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return BC_STS_INV_ARG;
+	}
+
+	rpkt = crystalhd_hw_alloc_rx_pkt(hw);
+	if (!rpkt) {
+		BCMLOG_ERR("Insufficient resources\n");
+		return BC_STS_INSUFF_RES;
+	}
+
+	rpkt->dio_req = ioreq;
+	tag = rpkt->pkt_tag;
+
+	sts = crystalhd_xlat_sgl_to_dma_desc(ioreq, &rpkt->desc_mem, &uv_desc_ix);
+	if (sts != BC_STS_SUCCESS)
+		return sts;
+
+	rpkt->uv_phy_addr = 0;
+
+	/* Store the address of UV in the rx packet for post*/
+	if (uv_desc_ix)
+		rpkt->uv_phy_addr = rpkt->desc_mem.phy_addr +
+				    (sizeof(dma_descriptor) * (uv_desc_ix + 1));
+
+	if (en_post)
+		sts = crystalhd_hw_post_cap_buff(hw, rpkt);
+	else
+		sts = crystalhd_dioq_add(hw->rx_freeq, rpkt, false, tag);
+
+	return sts;
+}
+
+BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw,
+				    BC_PIC_INFO_BLOCK *pib,
+				    crystalhd_dio_req **ioreq)
+{
+	crystalhd_rx_dma_pkt *rpkt;
+	uint32_t timeout = BC_PROC_OUTPUT_TIMEOUT / 1000;
+	uint32_t sig_pending = 0;
+
+
+	if (!hw || !ioreq || !pib) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return BC_STS_INV_ARG;
+	}
+
+	rpkt = crystalhd_dioq_fetch_wait(hw->rx_rdyq, timeout, &sig_pending);
+	if (!rpkt) {
+		if (sig_pending) {
+			BCMLOG(BCMLOG_INFO, "wait on frame time out %d\n", sig_pending);
+			return BC_STS_IO_USER_ABORT;
+		} else {
+			return BC_STS_TIMEOUT;
+		}
+	}
+
+	rpkt->dio_req->uinfo.comp_flags = rpkt->flags;
+
+	if (rpkt->flags & COMP_FLAG_PIB_VALID)
+		memcpy(pib, &rpkt->pib, sizeof(*pib));
+
+	*ioreq = rpkt->dio_req;
+
+	crystalhd_hw_free_rx_pkt(hw, rpkt);
+
+	return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw)
+{
+	crystalhd_rx_dma_pkt *rx_pkt;
+	BC_STATUS sts;
+	uint32_t i;
+
+	if (!hw) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return BC_STS_INV_ARG;
+	}
+
+	/* This is start of capture.. Post to both the lists.. */
+	for (i = 0; i < DMA_ENGINE_CNT; i++) {
+		rx_pkt = crystalhd_dioq_fetch(hw->rx_freeq);
+		if (!rx_pkt)
+			return BC_STS_NO_DATA;
+		sts = crystalhd_hw_post_cap_buff(hw, rx_pkt);
+		if (BC_STS_SUCCESS != sts)
+			break;
+
+	}
+
+	return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw)
+{
+	void *temp = NULL;
+
+	if (!hw) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return BC_STS_INV_ARG;
+	}
+
+	crystalhd_stop_rx_dma_engine(hw);
+
+	do {
+		temp = crystalhd_dioq_fetch(hw->rx_freeq);
+		if (temp)
+			crystalhd_rx_pkt_rel_call_back(hw, temp);
+	} while (temp);
+
+	return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw)
+{
+	hw->stats.pause_cnt++;
+	hw->stop_pending = 1;
+
+	if ((hw->rx_list_sts[0] == sts_free) &&
+	    (hw->rx_list_sts[1] == sts_free))
+		crystalhd_hw_finalize_pause(hw);
+
+	return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw)
+{
+	BC_STATUS sts;
+	uint32_t aspm;
+
+	hw->stop_pending = 0;
+
+	aspm = crystalhd_reg_rd(hw->adp, PCIE_DLL_DATA_LINK_CONTROL);
+	aspm &= ~ASPM_L1_ENABLE;
+/* NAREN BCMLOG(BCMLOG_INFO, "aspm off\n"); */
+	crystalhd_reg_wr(hw->adp, PCIE_DLL_DATA_LINK_CONTROL, aspm);
+
+	sts = crystalhd_hw_start_capture(hw);
+	return sts;
+}
+
+BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw)
+{
+	BC_STATUS sts;
+
+	if (!hw) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return BC_STS_INV_ARG;
+	}
+
+	sts = crystalhd_put_ddr2sleep(hw);
+	if (sts != BC_STS_SUCCESS) {
+		BCMLOG_ERR("Failed to Put DDR To Sleep!!\n");
+		return BC_STS_ERROR;
+	}
+
+	if (!crystalhd_stop_device(hw->adp)) {
+		BCMLOG_ERR("Failed to Stop Device!!\n");
+		return BC_STS_ERROR;
+	}
+
+	return BC_STS_SUCCESS;
+}
+
+void crystalhd_hw_stats(struct crystalhd_hw *hw, struct crystalhd_hw_stats *stats)
+{
+	if (!hw) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return;
+	}
+
+	/* if called w/NULL stats, its a req to zero out the stats */
+	if (!stats) {
+		memset(&hw->stats, 0, sizeof(hw->stats));
+		return;
+	}
+
+	hw->stats.freeq_count = crystalhd_dioq_count(hw->rx_freeq);
+	hw->stats.rdyq_count  = crystalhd_dioq_count(hw->rx_rdyq);
+	memcpy(stats, &hw->stats, sizeof(*stats));
+}
+
+BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *hw)
+{
+	uint32_t reg, n, i;
+	uint32_t vco_mg, refresh_reg;
+
+	if (!hw) {
+		BCMLOG_ERR("Invalid Arguments\n");
+		return BC_STS_INV_ARG;
+	}
+
+	/* FIXME: jarod: wha? */
+	/*n = (hw->core_clock_mhz * 3) / 20 + 1; */
+	n = hw->core_clock_mhz/5;
+
+	if (n == hw->prev_n)
+		return BC_STS_CLK_NOCHG;
+
+	if (hw->pwr_lock > 0) {
+		/* BCMLOG(BCMLOG_INFO,"pwr_lock is %u\n", hw->pwr_lock) */
+		return BC_STS_CLK_NOCHG;
+	}
+
+	i = n * 27;
+	if (i < 560)
+		vco_mg = 0;
+	else if (i < 900)
+		vco_mg = 1;
+	else if (i < 1030)
+		vco_mg = 2;
+	else
+		vco_mg = 3;
+
+	reg = bc_dec_reg_rd(hw->adp, DecHt_PllACtl);
+
+	reg &= 0xFFFFCFC0;
+	reg |= n;
+	reg |= vco_mg << 12;
+
+	BCMLOG(BCMLOG_INFO, "clock is moving to %d with n %d with vco_mg %d\n",
+	       hw->core_clock_mhz, n, vco_mg);
+
+	/* Change the DRAM refresh rate to accomodate the new frequency */
+	/* refresh reg = ((refresh_rate * clock_rate)/16) - 1; rounding up*/
+	refresh_reg = (7 * hw->core_clock_mhz / 16);
+	bc_dec_reg_wr(hw->adp, SDRAM_REF_PARAM, ((1 << 12) | refresh_reg));
+
+	bc_dec_reg_wr(hw->adp, DecHt_PllACtl, reg);
+
+	i = 0;
+
+	for (i = 0; i < 10; i++) {
+		reg = bc_dec_reg_rd(hw->adp, DecHt_PllACtl);
+
+		if (reg & 0x00020000) {
+			hw->prev_n = n;
+			/* FIXME: jarod: outputting a random "C" is... confusing... */
+			BCMLOG(BCMLOG_INFO, "C");
+			return BC_STS_SUCCESS;
+		} else {
+			msleep_interruptible(10);
+		}
+	}
+	BCMLOG(BCMLOG_INFO, "clk change failed\n");
+	return BC_STS_CLK_NOCHG;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_hw.h linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_hw.h
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_hw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,398 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ *  Name: crystalhd_hw . h
+ *
+ *  Description:
+ *		BCM70012 Linux driver hardware layer.
+ *
+ *  HISTORY:
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver.  If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#ifndef _CRYSTALHD_HW_H_
+#define _CRYSTALHD_HW_H_
+
+#include "crystalhd_misc.h"
+#include "crystalhd_fw_if.h"
+
+/* HW constants..*/
+#define DMA_ENGINE_CNT		2
+#define MAX_PIB_Q_DEPTH		64
+#define MIN_PIB_Q_DEPTH		2
+#define WR_POINTER_OFF		4
+
+#define ASPM_L1_ENABLE		(BC_BIT(27))
+
+/*************************************************
+  7412 Decoder  Registers.
+**************************************************/
+#define FW_CMD_BUFF_SZ		64
+#define TS_Host2CpuSnd		0x00000100
+#define Hst2CpuMbx1		0x00100F00
+#define Cpu2HstMbx1		0x00100F04
+#define MbxStat1		0x00100F08
+#define Stream2Host_Intr_Sts	0x00100F24
+#define C011_RET_SUCCESS	0x0	/* Reutrn status of firmware command. */
+
+/* TS input status register */
+#define TS_StreamAFIFOStatus	0x0010044C
+#define TS_StreamBFIFOStatus	0x0010084C
+
+/*UART Selection definitions*/
+#define UartSelectA		0x00100300
+#define UartSelectB		0x00100304
+
+#define BSVS_UART_DEC_NONE	0x00
+#define BSVS_UART_DEC_OUTER	0x01
+#define BSVS_UART_DEC_INNER	0x02
+#define BSVS_UART_STREAM	0x03
+
+/* Code-In fifo */
+#define REG_DecCA_RegCinCTL	0xa00
+#define REG_DecCA_RegCinBase	0xa0c
+#define REG_DecCA_RegCinEnd	0xa10
+#define REG_DecCA_RegCinWrPtr	0xa04
+#define REG_DecCA_RegCinRdPtr	0xa08
+
+#define REG_Dec_TsUser0Base	0x100864
+#define REG_Dec_TsUser0Rdptr	0x100868
+#define REG_Dec_TsUser0Wrptr	0x10086C
+#define REG_Dec_TsUser0End	0x100874
+
+/* ASF Case ...*/
+#define REG_Dec_TsAudCDB2Base	0x10036c
+#define REG_Dec_TsAudCDB2Rdptr  0x100378
+#define REG_Dec_TsAudCDB2Wrptr  0x100374
+#define REG_Dec_TsAudCDB2End	0x100370
+
+/* DRAM bringup Registers */
+#define SDRAM_PARAM		0x00040804
+#define SDRAM_PRECHARGE		0x000408B0
+#define SDRAM_EXT_MODE		0x000408A4
+#define SDRAM_MODE		0x000408A0
+#define SDRAM_REFRESH		0x00040890
+#define SDRAM_REF_PARAM		0x00040808
+
+#define DecHt_PllACtl		0x34000C
+#define DecHt_PllBCtl		0x340010
+#define DecHt_PllCCtl		0x340014
+#define DecHt_PllDCtl		0x340034
+#define DecHt_PllECtl		0x340038
+#define AUD_DSP_MISC_SOFT_RESET	0x00240104
+#define AIO_MISC_PLL_RESET	0x0026000C
+#define PCIE_CLK_REQ_REG	0xDC
+#define	PCI_CLK_REQ_ENABLE	(BC_BIT(8))
+
+/*************************************************
+  F/W Copy engine definitions..
+**************************************************/
+#define BC_FWIMG_ST_ADDR	0x00000000
+/* FIXME: jarod: there's a kernel function that'll do this for us... */
+#define rotr32_1(x, n)		(((x) >> n) | ((x) << (32 - n)))
+#define bswap_32_1(x)		((rotr32_1((x), 24) & 0x00ff00ff) | (rotr32_1((x), 8) & 0xff00ff00))
+
+#define DecHt_HostSwReset	0x340000
+#define BC_DRAM_FW_CFG_ADDR	0x001c2000
+
+typedef union _addr_64_ {
+	struct {
+		uint32_t	low_part;
+		uint32_t	high_part;
+	};
+
+	uint64_t	full_addr;
+
+} addr_64;
+
+typedef union _intr_mask_reg_ {
+	struct {
+		uint32_t	mask_tx_done:1;
+		uint32_t	mask_tx_err:1;
+		uint32_t	mask_rx_done:1;
+		uint32_t	mask_rx_err:1;
+		uint32_t	mask_pcie_err:1;
+		uint32_t	mask_pcie_rbusmast_err:1;
+		uint32_t	mask_pcie_rgr_bridge:1;
+		uint32_t	reserved:25;
+	};
+
+	uint32_t	whole_reg;
+
+} intr_mask_reg;
+
+typedef union _link_misc_perst_deco_ctrl_ {
+	struct {
+		uint32_t	bcm7412_rst:1;		/* 1 -> BCM7412 is held in reset. Reset value 1.*/
+		uint32_t	reserved0:3;		/* Reserved.No Effect*/
+		uint32_t	stop_bcm_7412_clk:1;	/* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/
+		uint32_t	reserved1:27;		/* Reseved. No Effect*/
+	};
+
+	uint32_t	whole_reg;
+
+} link_misc_perst_deco_ctrl;
+
+typedef union _link_misc_perst_clk_ctrl_ {
+	struct {
+		uint32_t	sel_alt_clk:1;	  /* When set, selects a 6.75MHz clock as the source of core_clk */
+		uint32_t	stop_core_clk:1;  /* When set, stops the branch of core_clk that is not needed for low power operation */
+		uint32_t	pll_pwr_dn:1;	  /* When set, powers down the main PLL. The alternate clock bit should be set
+						     to select an alternate clock before setting this bit.*/
+		uint32_t	reserved0:5;	  /* Reserved */
+		uint32_t	pll_mult:8;	  /* This setting controls the multiplier for the PLL. */
+		uint32_t	pll_div:4;	  /* This setting controls the divider for the PLL. */
+		uint32_t	reserved1:12;	  /* Reserved */
+	};
+
+	uint32_t	whole_reg;
+
+} link_misc_perst_clk_ctrl;
+
+
+typedef union _link_misc_perst_decoder_ctrl_ {
+	struct {
+		uint32_t	bcm_7412_rst:1; /* 1 -> BCM7412 is held in reset. Reset value 1.*/
+		uint32_t	res0:3; /* Reserved.No Effect*/
+		uint32_t	stop_7412_clk:1; /* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/
+		uint32_t	res1:27; /* Reseved. No Effect */
+	};
+
+	uint32_t	whole_reg;
+
+} link_misc_perst_decoder_ctrl;
+
+
+typedef union _desc_low_addr_reg_ {
+	struct {
+		uint32_t	list_valid:1;
+		uint32_t	reserved:4;
+		uint32_t	low_addr:27;
+	};
+
+	uint32_t	whole_reg;
+
+} desc_low_addr_reg;
+
+typedef struct _dma_descriptor_ {	/* 8 32-bit values */
+	/* 0th u32 */
+	uint32_t sdram_buff_addr:28;	/* bits 0-27:  SDRAM Address */
+	uint32_t res0:4;		/* bits 28-31: Reserved */
+
+	/* 1st u32 */
+	uint32_t buff_addr_low;		/* 1 buffer address low */
+	uint32_t buff_addr_high;	/* 2 buffer address high */
+
+	/* 3rd u32 */
+	uint32_t res2:2;		/* 0-1 - Reserved */
+	uint32_t xfer_size:23;		/* 2-24 = Xfer size in words */
+	uint32_t res3:6;		/* 25-30 reserved */
+	uint32_t intr_enable:1;		/* 31 - Interrupt After this desc */
+
+	/* 4th u32 */
+	uint32_t endian_xlat_align:2;	/* 0-1 Endian Translation */
+	uint32_t next_desc_cont:1;	/* 2 - Next desc is in contig memory */
+	uint32_t res4:25;		/* 3 - 27 Reserved bits */
+	uint32_t fill_bytes:2;		/* 28-29 Bits Fill Bytes */
+	uint32_t dma_dir:1;		/* 30 bit DMA Direction */
+	uint32_t last_rec_indicator:1;	/* 31 bit Last Record Indicator */
+
+	/* 5th u32 */
+	uint32_t next_desc_addr_low;	/* 32-bits Next Desc Addr lower */
+
+	/* 6th u32 */
+	uint32_t next_desc_addr_high;	/* 32-bits Next Desc Addr Higher */
+
+	/* 7th u32 */
+	uint32_t res8;			/* Last 32bits reserved */
+
+} dma_descriptor, *pdma_descriptor;
+
+/*
+ * We will allocate the memory in 4K pages
+ * the linked list will be a list of 32 byte descriptors.
+ * The  virtual address will determine what should be freed.
+ */
+typedef struct _dma_desc_mem_ {
+	pdma_descriptor		pdma_desc_start; /* 32-bytes for dma descriptor. should be first element */
+	dma_addr_t		phy_addr;	/* physical address of each DMA desc */
+	uint32_t		sz;
+	struct _dma_desc_mem_	*Next;		/* points to Next Descriptor in chain */
+
+} dma_desc_mem, *pdma_desc_mem;
+
+
+
+typedef enum _list_sts_ {
+	sts_free = 0,
+
+	/* RX-Y Bits 0:7 */
+	rx_waiting_y_intr	= 0x00000001,
+	rx_y_error		= 0x00000004,
+
+	/* RX-UV Bits 8:16 */
+	rx_waiting_uv_intr	= 0x0000100,
+	rx_uv_error		= 0x0000400,
+
+	rx_sts_waiting		= (rx_waiting_y_intr|rx_waiting_uv_intr),
+	rx_sts_error		= (rx_y_error|rx_uv_error),
+
+	rx_y_mask		= 0x000000FF,
+	rx_uv_mask		= 0x0000FF00,
+
+} list_sts;
+
+typedef struct _tx_dma_pkt_ {
+	dma_desc_mem		desc_mem;
+	hw_comp_callback	call_back;
+	crystalhd_dio_req		*dio_req;
+	wait_queue_head_t	*cb_event;
+	uint32_t		list_tag;
+
+} tx_dma_pkt;
+
+typedef struct _crystalhd_rx_dma_pkt {
+	dma_desc_mem			desc_mem;
+	crystalhd_dio_req			*dio_req;
+	uint32_t			pkt_tag;
+	uint32_t			flags;
+	BC_PIC_INFO_BLOCK		pib;
+	dma_addr_t			uv_phy_addr;
+	struct  _crystalhd_rx_dma_pkt	*next;
+
+} crystalhd_rx_dma_pkt;
+
+struct crystalhd_hw_stats{
+	uint32_t	rx_errors;
+	uint32_t	tx_errors;
+	uint32_t	freeq_count;
+	uint32_t	rdyq_count;
+	uint32_t	num_interrupts;
+	uint32_t	dev_interrupts;
+	uint32_t	cin_busy;
+	uint32_t	pause_cnt;
+};
+
+struct crystalhd_hw {
+	tx_dma_pkt		tx_pkt_pool[DMA_ENGINE_CNT];
+	spinlock_t		lock;
+
+	uint32_t		tx_ioq_tag_seed;
+	uint32_t		tx_list_post_index;
+
+	crystalhd_rx_dma_pkt	*rx_pkt_pool_head;
+	uint32_t		rx_pkt_tag_seed;
+
+	bool			dev_started;
+	void			*adp;
+
+	wait_queue_head_t	*pfw_cmd_event;
+	int			fwcmd_evt_sts;
+
+	uint32_t		pib_del_Q_addr;
+	uint32_t		pib_rel_Q_addr;
+
+	crystalhd_dioq_t		*tx_freeq;
+	crystalhd_dioq_t		*tx_actq;
+
+	/* Rx DMA Engine Specific Locks */
+	spinlock_t		rx_lock;
+	uint32_t		rx_list_post_index;
+	list_sts		rx_list_sts[DMA_ENGINE_CNT];
+	crystalhd_dioq_t		*rx_rdyq;
+	crystalhd_dioq_t		*rx_freeq;
+	crystalhd_dioq_t		*rx_actq;
+	uint32_t		stop_pending;
+
+	/* HW counters.. */
+	struct crystalhd_hw_stats	stats;
+
+	/* Core clock in MHz */
+	uint32_t		core_clock_mhz;
+	uint32_t		prev_n;
+	uint32_t		pwr_lock;
+};
+
+/* Clock defines for power control */
+#define CLOCK_PRESET 175
+
+/* DMA engine register BIT mask wrappers.. */
+#define DMA_START_BIT		MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_MASK
+
+#define GET_RX_INTR_MASK (INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_MASK |		\
+			  INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK |	\
+			  INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_MASK |		\
+			  INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK |		\
+			  INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_MASK |		\
+			  INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK |	\
+			  INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_MASK |		\
+			  INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK)
+
+#define GET_Y0_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK |		\
+			MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK |		\
+			MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK |	\
+			MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK)
+
+#define GET_UV0_ERR_MSK (MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK |		\
+			 MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK |		\
+			 MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK |	\
+			 MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK)
+
+#define GET_Y1_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK |		\
+			MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK |		\
+			MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK |	\
+			MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK)
+
+#define GET_UV1_ERR_MSK	(MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK |		\
+			 MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK |		\
+			 MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK |	\
+			 MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK)
+
+
+/**** API Exposed to the other layers ****/
+BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp,
+			      void *buffer, uint32_t sz);
+BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, BC_FW_CMD *fw_cmd);
+bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw);
+BC_STATUS crystalhd_hw_open(struct crystalhd_hw *, struct crystalhd_adp *);
+BC_STATUS crystalhd_hw_close(struct crystalhd_hw *);
+BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *);
+BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *);
+
+
+BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, crystalhd_dio_req *ioreq,
+			     hw_comp_callback call_back,
+			     wait_queue_head_t *cb_event,
+			     uint32_t *list_id, uint8_t data_flags);
+
+BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw);
+BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw);
+BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw);
+BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id);
+BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw,
+				    crystalhd_dio_req *ioreq, bool en_post);
+BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw,
+				    BC_PIC_INFO_BLOCK *pib,
+				    crystalhd_dio_req **ioreq);
+BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw);
+BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw);
+void crystalhd_hw_stats(struct crystalhd_hw *hw, struct crystalhd_hw_stats *stats);
+
+/* API to program the core clock on the decoder */
+BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_lnx.c linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_lnx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_lnx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_lnx.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,766 @@
+/***************************************************************************
+  BCM70010 Linux driver
+  Copyright (c) 2005-2009, Broadcom Corporation.
+
+  This driver is free software; 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 driver is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this driver.  If not, see <http://www.gnu.org/licenses/>.
+***************************************************************************/
+
+#include <linux/version.h>
+#include <linux/slab.h>
+
+#include "crystalhd_lnx.h"
+
+static struct class *crystalhd_class;
+
+static struct crystalhd_adp *g_adp_info;
+
+static irqreturn_t chd_dec_isr(int irq, void *arg)
+{
+	struct crystalhd_adp *adp = (struct crystalhd_adp *) arg;
+	int rc = 0;
+	if (adp)
+		rc = crystalhd_cmd_interrupt(&adp->cmds);
+
+	return IRQ_RETVAL(rc);
+}
+
+static int chd_dec_enable_int(struct crystalhd_adp *adp)
+{
+	int rc = 0;
+
+	if (!adp || !adp->pdev) {
+		BCMLOG_ERR("Invalid arg!!\n");
+		return -EINVAL;
+	}
+
+	if (adp->pdev->msi_enabled)
+		adp->msi = 1;
+	else
+		adp->msi = pci_enable_msi(adp->pdev);
+
+	rc = request_irq(adp->pdev->irq, chd_dec_isr, IRQF_SHARED,
+			 adp->name, (void *)adp);
+	if (rc) {
+		BCMLOG_ERR("Interrupt request failed.. \n");
+		pci_disable_msi(adp->pdev);
+	}
+
+	return rc;
+}
+
+static int chd_dec_disable_int(struct crystalhd_adp *adp)
+{
+	if (!adp || !adp->pdev) {
+		BCMLOG_ERR("Invalid arg!!\n");
+		return -EINVAL;
+	}
+
+	free_irq(adp->pdev->irq, adp);
+
+	if (adp->msi)
+		pci_disable_msi(adp->pdev);
+
+	return 0;
+}
+
+crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp, bool isr)
+{
+	unsigned long flags = 0;
+	crystalhd_ioctl_data *temp;
+
+	if (!adp)
+		return NULL;
+
+	spin_lock_irqsave(&adp->lock, flags);
+
+	temp = adp->idata_free_head;
+	if (temp) {
+		adp->idata_free_head = adp->idata_free_head->next;
+		memset(temp, 0, sizeof(*temp));
+	}
+
+	spin_unlock_irqrestore(&adp->lock, flags);
+	return temp;
+}
+
+void chd_dec_free_iodata(struct crystalhd_adp *adp, crystalhd_ioctl_data *iodata,
+			 bool isr)
+{
+	unsigned long flags = 0;
+
+	if (!adp || !iodata)
+		return;
+
+	spin_lock_irqsave(&adp->lock, flags);
+	iodata->next = adp->idata_free_head;
+	adp->idata_free_head = iodata;
+	spin_unlock_irqrestore(&adp->lock, flags);
+}
+
+static inline int crystalhd_user_data(unsigned long ud, void *dr, int size, int set)
+{
+	int rc;
+
+	if (!ud || !dr) {
+		BCMLOG_ERR("Invalid arg \n");
+		return -EINVAL;
+	}
+
+	if (set)
+		rc = copy_to_user((void *)ud, dr, size);
+	else
+		rc = copy_from_user(dr, (void *)ud, size);
+
+	if (rc) {
+		BCMLOG_ERR("Invalid args for command \n");
+		rc = -EFAULT;
+	}
+
+	return rc;
+}
+
+static int chd_dec_fetch_cdata(struct crystalhd_adp *adp, crystalhd_ioctl_data *io,
+			       uint32_t m_sz, unsigned long ua)
+{
+	unsigned long ua_off;
+	int rc = 0;
+
+	if (!adp || !io || !ua || !m_sz) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return -EINVAL;
+	}
+
+	io->add_cdata = vmalloc(m_sz);
+	if (!io->add_cdata) {
+		BCMLOG_ERR("kalloc fail for sz:%x\n", m_sz);
+		return -ENOMEM;
+	}
+
+	io->add_cdata_sz = m_sz;
+	ua_off = ua + sizeof(io->udata);
+	rc = crystalhd_user_data(ua_off, io->add_cdata, io->add_cdata_sz, 0);
+	if (rc) {
+		BCMLOG_ERR("failed to pull add_cdata sz:%x ua_off:%x\n",
+			   io->add_cdata_sz, (unsigned int)ua_off);
+		if (io->add_cdata) {
+			kfree(io->add_cdata);
+			io->add_cdata = NULL;
+		}
+		return -ENODATA;
+	}
+
+	return rc;
+}
+
+static int chd_dec_release_cdata(struct crystalhd_adp *adp,
+				 crystalhd_ioctl_data *io, unsigned long ua)
+{
+	unsigned long ua_off;
+	int rc;
+
+	if (!adp || !io || !ua) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return -EINVAL;
+	}
+
+	if (io->cmd != BCM_IOC_FW_DOWNLOAD) {
+		ua_off = ua + sizeof(io->udata);
+		rc = crystalhd_user_data(ua_off, io->add_cdata,
+					io->add_cdata_sz, 1);
+		if (rc) {
+			BCMLOG_ERR("failed to push add_cdata sz:%x ua_off:%x\n",
+				   io->add_cdata_sz, (unsigned int)ua_off);
+			return -ENODATA;
+		}
+	}
+
+	if (io->add_cdata) {
+		vfree(io->add_cdata);
+		io->add_cdata = NULL;
+	}
+
+	return 0;
+}
+
+static int chd_dec_proc_user_data(struct crystalhd_adp *adp,
+				  crystalhd_ioctl_data *io,
+				  unsigned long ua, int set)
+{
+	int rc;
+	uint32_t m_sz = 0;
+
+	if (!adp || !io || !ua) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return -EINVAL;
+	}
+
+	rc = crystalhd_user_data(ua, &io->udata, sizeof(io->udata), set);
+	if (rc) {
+		BCMLOG_ERR("failed to %s iodata \n", (set ? "set" : "get"));
+		return rc;
+	}
+
+	switch (io->cmd) {
+	case BCM_IOC_MEM_RD:
+	case BCM_IOC_MEM_WR:
+	case BCM_IOC_FW_DOWNLOAD:
+		m_sz = io->udata.u.devMem.NumDwords * 4;
+		if (set)
+			rc = chd_dec_release_cdata(adp, io, ua);
+		else
+			rc = chd_dec_fetch_cdata(adp, io, m_sz, ua);
+		break;
+	default:
+		break;
+	}
+
+	return rc;
+}
+
+static int chd_dec_api_cmd(struct crystalhd_adp *adp, unsigned long ua,
+			   uint32_t uid, uint32_t cmd, crystalhd_cmd_proc func)
+{
+	int rc;
+	crystalhd_ioctl_data *temp;
+	BC_STATUS sts = BC_STS_SUCCESS;
+
+	temp = chd_dec_alloc_iodata(adp, 0);
+	if (!temp) {
+		BCMLOG_ERR("Failed to get iodata..\n");
+		return -EINVAL;
+	}
+
+	temp->u_id = uid;
+	temp->cmd  = cmd;
+
+	rc = chd_dec_proc_user_data(adp, temp, ua, 0);
+	if (!rc) {
+		sts = func(&adp->cmds, temp);
+		if (sts == BC_STS_PENDING)
+			sts = BC_STS_NOT_IMPL;
+		temp->udata.RetSts = sts;
+		rc = chd_dec_proc_user_data(adp, temp, ua, 1);
+	}
+
+	if (temp) {
+		chd_dec_free_iodata(adp, temp, 0);
+		temp = NULL;
+	}
+
+	return rc;
+}
+
+/* API interfaces */
+static int chd_dec_ioctl(struct inode *in, struct file *fd,
+			 unsigned int cmd, unsigned long ua)
+{
+	struct crystalhd_adp *adp = chd_get_adp();
+	crystalhd_cmd_proc cproc;
+	struct crystalhd_user *uc;
+
+	if (!adp || !fd) {
+		BCMLOG_ERR("Invalid adp\n");
+		return -EINVAL;
+	}
+
+	uc = (struct crystalhd_user *)fd->private_data;
+	if (!uc) {
+		BCMLOG_ERR("Failed to get uc\n");
+		return -ENODATA;
+	}
+
+	cproc = crystalhd_get_cmd_proc(&adp->cmds, cmd, uc);
+	if (!cproc) {
+		BCMLOG_ERR("Unhandled command: %d\n", cmd);
+		return -EINVAL;
+	}
+
+	return chd_dec_api_cmd(adp, ua, uc->uid, cmd, cproc);
+}
+
+static int chd_dec_open(struct inode *in, struct file *fd)
+{
+	struct crystalhd_adp *adp = chd_get_adp();
+	int rc = 0;
+	BC_STATUS sts = BC_STS_SUCCESS;
+	struct crystalhd_user *uc = NULL;
+
+	BCMLOG_ENTER;
+	if (!adp) {
+		BCMLOG_ERR("Invalid adp\n");
+		return -EINVAL;
+	}
+
+	if (adp->cfg_users >= BC_LINK_MAX_OPENS) {
+		BCMLOG(BCMLOG_INFO, "Already in use.%d\n", adp->cfg_users);
+		return -EBUSY;
+	}
+
+	sts = crystalhd_user_open(&adp->cmds, &uc);
+	if (sts != BC_STS_SUCCESS) {
+		BCMLOG_ERR("cmd_user_open - %d \n", sts);
+		rc = -EBUSY;
+	}
+
+	adp->cfg_users++;
+
+	fd->private_data = uc;
+
+	return rc;
+}
+
+static int chd_dec_close(struct inode *in, struct file *fd)
+{
+	struct crystalhd_adp *adp = chd_get_adp();
+	struct crystalhd_user *uc;
+
+	BCMLOG_ENTER;
+	if (!adp) {
+		BCMLOG_ERR("Invalid adp \n");
+		return -EINVAL;
+	}
+
+	uc = (struct crystalhd_user *)fd->private_data;
+	if (!uc) {
+		BCMLOG_ERR("Failed to get uc\n");
+		return -ENODATA;
+	}
+
+	crystalhd_user_close(&adp->cmds, uc);
+
+	adp->cfg_users--;
+
+	return 0;
+}
+
+static const struct file_operations chd_dec_fops = {
+	.owner   = THIS_MODULE,
+	.ioctl   = chd_dec_ioctl,
+	.open    = chd_dec_open,
+	.release = chd_dec_close,
+};
+
+static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp)
+{
+	crystalhd_ioctl_data *temp;
+	struct device *dev;
+	int rc = -ENODEV, i = 0;
+
+	if (!adp)
+		goto fail;
+
+	adp->chd_dec_major = register_chrdev(0, CRYSTALHD_API_NAME,
+					     &chd_dec_fops);
+	if (adp->chd_dec_major < 0) {
+		BCMLOG_ERR("Failed to create config dev\n");
+		rc = adp->chd_dec_major;
+		goto fail;
+	}
+
+	/* register crystalhd class */
+	crystalhd_class = class_create(THIS_MODULE, "crystalhd");
+	if (IS_ERR(crystalhd_class)) {
+		BCMLOG_ERR("failed to create class\n");
+		goto fail;
+	}
+
+	dev = device_create(crystalhd_class, NULL, MKDEV(adp->chd_dec_major, 0),
+			    NULL, "crystalhd");
+	if (!dev) {
+		BCMLOG_ERR("failed to create device\n");
+		goto device_create_fail;
+	}
+
+	rc = crystalhd_create_elem_pool(adp, BC_LINK_ELEM_POOL_SZ);
+	if (rc) {
+		BCMLOG_ERR("failed to create device\n");
+		goto elem_pool_fail;
+	}
+
+	/* Allocate general purpose ioctl pool. */
+	for (i = 0; i < CHD_IODATA_POOL_SZ; i++) {
+		/* FIXME: jarod: why atomic? */
+		temp = kzalloc(sizeof(crystalhd_ioctl_data), GFP_ATOMIC);
+		if (!temp) {
+			BCMLOG_ERR("ioctl data pool kzalloc failed\n");
+			rc = -ENOMEM;
+			goto kzalloc_fail;
+		}
+		/* Add to global pool.. */
+		chd_dec_free_iodata(adp, temp, 0);
+	}
+
+	return 0;
+
+kzalloc_fail:
+	crystalhd_delete_elem_pool(adp);
+elem_pool_fail:
+	device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0));
+device_create_fail:
+	class_destroy(crystalhd_class);
+fail:
+	return rc;
+}
+
+static void __devexit chd_dec_release_chdev(struct crystalhd_adp *adp)
+{
+	crystalhd_ioctl_data *temp = NULL;
+	if (!adp)
+		return;
+
+	if (adp->chd_dec_major > 0) {
+		/* unregister crystalhd class */
+		device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0));
+		unregister_chrdev(adp->chd_dec_major, CRYSTALHD_API_NAME);
+		BCMLOG(BCMLOG_INFO, "released api device - %d\n",
+		       adp->chd_dec_major);
+		class_destroy(crystalhd_class);
+	}
+	adp->chd_dec_major = 0;
+
+	/* Clear iodata pool.. */
+	do {
+		temp = chd_dec_alloc_iodata(adp, 0);
+		if (temp)
+			kfree(temp);
+	} while (temp);
+
+	crystalhd_delete_elem_pool(adp);
+}
+
+static int __devinit chd_pci_reserve_mem(struct crystalhd_adp *pinfo)
+{
+	int rc;
+	unsigned long bar2 = pci_resource_start(pinfo->pdev, 2);
+	uint32_t mem_len   = pci_resource_len(pinfo->pdev, 2);
+	unsigned long bar0 = pci_resource_start(pinfo->pdev, 0);
+	uint32_t i2o_len   = pci_resource_len(pinfo->pdev, 0);
+
+	BCMLOG(BCMLOG_SSTEP, "bar2:0x%lx-0x%08x  bar0:0x%lx-0x%08x\n",
+	       bar2, mem_len, bar0, i2o_len);
+
+	rc = check_mem_region(bar2, mem_len);
+	if (rc) {
+		BCMLOG_ERR("No valid mem region...\n");
+		return -ENOMEM;
+	}
+
+	pinfo->addr = ioremap_nocache(bar2, mem_len);
+	if (!pinfo->addr) {
+		BCMLOG_ERR("Failed to remap mem region...\n");
+		return -ENOMEM;
+	}
+
+	pinfo->pci_mem_start = bar2;
+	pinfo->pci_mem_len   = mem_len;
+
+	rc = check_mem_region(bar0, i2o_len);
+	if (rc) {
+		BCMLOG_ERR("No valid mem region...\n");
+		return -ENOMEM;
+	}
+
+	pinfo->i2o_addr = ioremap_nocache(bar0, i2o_len);
+	if (!pinfo->i2o_addr) {
+		BCMLOG_ERR("Failed to remap mem region...\n");
+		return -ENOMEM;
+	}
+
+	pinfo->pci_i2o_start = bar0;
+	pinfo->pci_i2o_len   = i2o_len;
+
+	rc = pci_request_regions(pinfo->pdev, pinfo->name);
+	if (rc < 0) {
+		BCMLOG_ERR("Region request failed: %d\n", rc);
+		return rc;
+	}
+
+	BCMLOG(BCMLOG_SSTEP, "Mapped addr:0x%08lx  i2o_addr:0x%08lx\n",
+	       (unsigned long)pinfo->addr, (unsigned long)pinfo->i2o_addr);
+
+	return 0;
+}
+
+static void __devexit chd_pci_release_mem(struct crystalhd_adp *pinfo)
+{
+	if (!pinfo)
+		return;
+
+	if (pinfo->addr)
+		iounmap(pinfo->addr);
+
+	if (pinfo->i2o_addr)
+		iounmap(pinfo->i2o_addr);
+
+	pci_release_regions(pinfo->pdev);
+}
+
+
+static void __devexit chd_dec_pci_remove(struct pci_dev *pdev)
+{
+	struct crystalhd_adp *pinfo;
+	BC_STATUS sts = BC_STS_SUCCESS;
+
+	BCMLOG_ENTER;
+
+	pinfo = (struct crystalhd_adp *) pci_get_drvdata(pdev);
+	if (!pinfo) {
+		BCMLOG_ERR("could not get adp\n");
+		return;
+	}
+
+	sts = crystalhd_delete_cmd_context(&pinfo->cmds);
+	if (sts != BC_STS_SUCCESS)
+		BCMLOG_ERR("cmd delete :%d \n", sts);
+
+	chd_dec_release_chdev(pinfo);
+
+	chd_dec_disable_int(pinfo);
+
+	chd_pci_release_mem(pinfo);
+	pci_disable_device(pinfo->pdev);
+
+	kfree(pinfo);
+	g_adp_info = NULL;
+}
+
+static int __devinit chd_dec_pci_probe(struct pci_dev *pdev,
+			     const struct pci_device_id *entry)
+{
+	struct crystalhd_adp *pinfo;
+	int rc;
+	BC_STATUS sts = BC_STS_SUCCESS;
+
+	BCMLOG(BCMLOG_DBG, "PCI_INFO: Vendor:0x%04x Device:0x%04x "
+	       "s_vendor:0x%04x s_device: 0x%04x\n",
+	       pdev->vendor, pdev->device, pdev->subsystem_vendor,
+	       pdev->subsystem_device);
+
+	/* FIXME: jarod: why atomic? */
+	pinfo = kzalloc(sizeof(struct crystalhd_adp), GFP_ATOMIC);
+	if (!pinfo) {
+		BCMLOG_ERR("Failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	pinfo->pdev = pdev;
+
+	rc = pci_enable_device(pdev);
+	if (rc) {
+		BCMLOG_ERR("Failed to enable PCI device\n");
+		return rc;
+	}
+
+	snprintf(pinfo->name, 31, "crystalhd_pci_e:%d:%d:%d",
+		 pdev->bus->number, PCI_SLOT(pdev->devfn),
+		 PCI_FUNC(pdev->devfn));
+
+	rc = chd_pci_reserve_mem(pinfo);
+	if (rc) {
+		BCMLOG_ERR("Failed to setup memory regions.\n");
+		return -ENOMEM;
+	}
+
+	pinfo->present	= 1;
+	pinfo->drv_data = entry->driver_data;
+
+	/* Setup adapter level lock.. */
+	spin_lock_init(&pinfo->lock);
+
+	/* setup api stuff.. */
+	chd_dec_init_chdev(pinfo);
+	rc = chd_dec_enable_int(pinfo);
+	if (rc) {
+		BCMLOG_ERR("_enable_int err:%d \n", rc);
+		pci_disable_device(pdev);
+		return -ENODEV;
+	}
+
+	/* Set dma mask... */
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+		pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+		pinfo->dmabits = 64;
+	} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+		pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+		pinfo->dmabits = 32;
+	} else {
+		BCMLOG_ERR("Unabled to setup DMA %d\n", rc);
+		pci_disable_device(pdev);
+		return -ENODEV;
+	}
+
+	sts = crystalhd_setup_cmd_context(&pinfo->cmds, pinfo);
+	if (sts != BC_STS_SUCCESS) {
+		BCMLOG_ERR("cmd setup :%d \n", sts);
+		pci_disable_device(pdev);
+		return -ENODEV;
+	}
+
+	pci_set_master(pdev);
+
+	pci_set_drvdata(pdev, pinfo);
+
+	g_adp_info = pinfo;
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct crystalhd_adp *adp;
+	crystalhd_ioctl_data *temp;
+	BC_STATUS sts = BC_STS_SUCCESS;
+
+	adp = (struct crystalhd_adp *)pci_get_drvdata(pdev);
+	if (!adp) {
+		BCMLOG_ERR("could not get adp\n");
+		return -ENODEV;
+	}
+
+	temp = chd_dec_alloc_iodata(adp, false);
+	if (!temp) {
+		BCMLOG_ERR("could not get ioctl data\n");
+		return -ENODEV;
+	}
+
+	sts = crystalhd_suspend(&adp->cmds, temp);
+	if (sts != BC_STS_SUCCESS) {
+		BCMLOG_ERR("BCM70012 Suspend %d\n", sts);
+		return -ENODEV;
+	}
+
+	chd_dec_free_iodata(adp, temp, false);
+	chd_dec_disable_int(adp);
+	pci_save_state(pdev);
+
+	/* Disable IO/bus master/irq router */
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	return 0;
+}
+
+int chd_dec_pci_resume(struct pci_dev *pdev)
+{
+	struct crystalhd_adp *adp;
+	BC_STATUS sts = BC_STS_SUCCESS;
+	int rc;
+
+	adp = (struct crystalhd_adp *)pci_get_drvdata(pdev);
+	if (!adp) {
+		BCMLOG_ERR("could not get adp\n");
+		return -ENODEV;
+	}
+
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+
+	/* device's irq possibly is changed, driver should take care */
+	if (pci_enable_device(pdev)) {
+		BCMLOG_ERR("Failed to enable PCI device\n");
+		return 1;
+	}
+
+	pci_set_master(pdev);
+
+	rc = chd_dec_enable_int(adp);
+	if (rc) {
+		BCMLOG_ERR("_enable_int err:%d \n", rc);
+		pci_disable_device(pdev);
+		return -ENODEV;
+	}
+
+	sts = crystalhd_resume(&adp->cmds);
+	if (sts != BC_STS_SUCCESS) {
+		BCMLOG_ERR("BCM70012 Resume %d\n", sts);
+		pci_disable_device(pdev);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+#endif
+
+static DEFINE_PCI_DEVICE_TABLE(chd_dec_pci_id_table) = {
+	{ PCI_VDEVICE(BROADCOM, 0x1612), 8 },
+	{ 0, },
+};
+MODULE_DEVICE_TABLE(pci, chd_dec_pci_id_table);
+
+static struct pci_driver bc_chd_70012_driver = {
+	.name     = "Broadcom 70012 Decoder",
+	.probe    = chd_dec_pci_probe,
+	.remove   = __devexit_p(chd_dec_pci_remove),
+	.id_table = chd_dec_pci_id_table,
+#ifdef CONFIG_PM
+	.suspend  = chd_dec_pci_suspend,
+	.resume   = chd_dec_pci_resume
+#endif
+};
+
+void chd_set_log_level(struct crystalhd_adp *adp, char *arg)
+{
+	if ((!arg) || (strlen(arg) < 3))
+		g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA;
+	else if (!strncmp(arg, "sstep", 5))
+		g_linklog_level = BCMLOG_INFO | BCMLOG_DATA | BCMLOG_DBG |
+				  BCMLOG_SSTEP | BCMLOG_ERROR;
+	else if (!strncmp(arg, "info", 4))
+		g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO;
+	else if (!strncmp(arg, "debug", 5))
+		g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO |
+				  BCMLOG_DBG;
+	else if (!strncmp(arg, "pball", 5))
+		g_linklog_level = 0xFFFFFFFF & ~(BCMLOG_SPINLOCK);
+	else if (!strncmp(arg, "silent", 6))
+		g_linklog_level = 0;
+	else
+		g_linklog_level = 0;
+}
+
+struct crystalhd_adp *chd_get_adp(void)
+{
+	return g_adp_info;
+}
+
+static int __init chd_dec_module_init(void)
+{
+	int rc;
+
+	chd_set_log_level(NULL, "debug");
+	BCMLOG(BCMLOG_DATA, "Loading crystalhd %d.%d.%d \n",
+	       crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev);
+
+	rc = pci_register_driver(&bc_chd_70012_driver);
+
+	if (rc < 0)
+		BCMLOG_ERR("Could not find any devices. err:%d \n", rc);
+
+	return rc;
+}
+module_init(chd_dec_module_init);
+
+static void __exit chd_dec_module_cleanup(void)
+{
+	BCMLOG(BCMLOG_DATA, "unloading crystalhd %d.%d.%d \n",
+	       crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev);
+
+	pci_unregister_driver(&bc_chd_70012_driver);
+}
+module_exit(chd_dec_module_cleanup);
+
+MODULE_AUTHOR("Naren Sankar <nsankar@broadcom.com>");
+MODULE_AUTHOR("Prasad Bolisetty <prasadb@broadcom.com>");
+MODULE_DESCRIPTION(CRYSTAL_HD_NAME);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("bcm70012");
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_lnx.h linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_lnx.h
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_lnx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_lnx.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,96 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ *  Name: crystalhd_lnx . c
+ *
+ *  Description:
+ *		BCM70012 Linux driver
+ *
+ *  HISTORY:
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver.  If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#ifndef _CRYSTALHD_LNX_H_
+#define _CRYSTALHD_LNX_H_
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pagemap.h>
+#include <linux/vmalloc.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include "crystalhd_cmds.h"
+
+#define CRYSTAL_HD_NAME		"Broadcom Crystal HD Decoder (BCM70012) Driver"
+
+
+/* OS specific PCI information structure and adapter information. */
+struct crystalhd_adp {
+	/* Hardware borad/PCI specifics */
+	char			name[32];
+	struct pci_dev		*pdev;
+
+	unsigned long		pci_mem_start;
+	uint32_t		pci_mem_len;
+	void			*addr;
+
+	unsigned long		pci_i2o_start;
+	uint32_t		pci_i2o_len;
+	void			*i2o_addr;
+
+	unsigned int		drv_data;
+	unsigned int		dmabits;	/* 32 | 64 */
+	unsigned int		registered;
+	unsigned int		present;
+	unsigned int		msi;
+
+	spinlock_t		lock;
+
+	/* API Related */
+	unsigned int		chd_dec_major;
+	unsigned int		cfg_users;
+
+	crystalhd_ioctl_data	*idata_free_head;	/* ioctl data pool */
+	crystalhd_elem_t		*elem_pool_head;	/* Queue element pool */
+
+	struct crystalhd_cmd	cmds;
+
+	crystalhd_dio_req		*ua_map_free_head;
+	struct pci_pool		*fill_byte_pool;
+};
+
+
+struct crystalhd_adp *chd_get_adp(void);
+void chd_set_log_level(struct crystalhd_adp *adp, char *arg);
+
+#endif
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_misc.c linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_misc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_misc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_misc.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1032 @@
+/***************************************************************************
+ *	   Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ *  Name: crystalhd_misc . c
+ *
+ *  Description:
+ *		BCM70012 Linux driver misc routines.
+ *
+ *  HISTORY:
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver.  If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#include <linux/slab.h>
+
+#include "crystalhd_misc.h"
+#include "crystalhd_lnx.h"
+
+uint32_t g_linklog_level;
+
+static inline uint32_t crystalhd_dram_rd(struct crystalhd_adp *adp, uint32_t mem_off)
+{
+	crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (mem_off >> 19));
+	return bc_dec_reg_rd(adp, (0x00380000 | (mem_off & 0x0007FFFF)));
+}
+
+static inline void crystalhd_dram_wr(struct crystalhd_adp *adp, uint32_t mem_off, uint32_t val)
+{
+	crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (mem_off >> 19));
+	bc_dec_reg_wr(adp, (0x00380000 | (mem_off & 0x0007FFFF)), val);
+}
+
+static inline BC_STATUS bc_chk_dram_range(struct crystalhd_adp *adp, uint32_t start_off, uint32_t cnt)
+{
+	return BC_STS_SUCCESS;
+}
+
+static crystalhd_dio_req *crystalhd_alloc_dio(struct crystalhd_adp *adp)
+{
+	unsigned long flags = 0;
+	crystalhd_dio_req *temp = NULL;
+
+	if (!adp) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return temp;
+	}
+
+	spin_lock_irqsave(&adp->lock, flags);
+	temp = adp->ua_map_free_head;
+	if (temp)
+		adp->ua_map_free_head = adp->ua_map_free_head->next;
+	spin_unlock_irqrestore(&adp->lock, flags);
+
+	return temp;
+}
+
+static void crystalhd_free_dio(struct crystalhd_adp *adp, crystalhd_dio_req *dio)
+{
+	unsigned long flags = 0;
+
+	if (!adp || !dio)
+		return;
+	spin_lock_irqsave(&adp->lock, flags);
+	dio->sig = crystalhd_dio_inv;
+	dio->page_cnt = 0;
+	dio->fb_size = 0;
+	memset(&dio->uinfo, 0, sizeof(dio->uinfo));
+	dio->next = adp->ua_map_free_head;
+	adp->ua_map_free_head = dio;
+	spin_unlock_irqrestore(&adp->lock, flags);
+}
+
+static crystalhd_elem_t *crystalhd_alloc_elem(struct crystalhd_adp *adp)
+{
+	unsigned long flags = 0;
+	crystalhd_elem_t *temp = NULL;
+
+	if (!adp)
+		return temp;
+	spin_lock_irqsave(&adp->lock, flags);
+	temp = adp->elem_pool_head;
+	if (temp) {
+		adp->elem_pool_head = adp->elem_pool_head->flink;
+		memset(temp, 0, sizeof(*temp));
+	}
+	spin_unlock_irqrestore(&adp->lock, flags);
+
+	return temp;
+}
+static void crystalhd_free_elem(struct crystalhd_adp *adp, crystalhd_elem_t *elem)
+{
+	unsigned long flags = 0;
+
+	if (!adp || !elem)
+		return;
+	spin_lock_irqsave(&adp->lock, flags);
+	elem->flink = adp->elem_pool_head;
+	adp->elem_pool_head = elem;
+	spin_unlock_irqrestore(&adp->lock, flags);
+}
+
+static inline void crystalhd_set_sg(struct scatterlist *sg, struct page *page,
+				  unsigned int len, unsigned int offset)
+{
+	sg_set_page(sg, page, len, offset);
+#ifdef CONFIG_X86_64
+	sg->dma_length = len;
+#endif
+}
+
+static inline void crystalhd_init_sg(struct scatterlist *sg, unsigned int entries)
+{
+	/* http://lkml.org/lkml/2007/11/27/68 */
+	sg_init_table(sg, entries);
+}
+
+/*========================== Extern ========================================*/
+/**
+ * bc_dec_reg_rd - Read 7412's device register.
+ * @adp: Adapter instance
+ * @reg_off: Register offset.
+ *
+ * Return:
+ *	32bit value read
+ *
+ * 7412's device register read routine. This interface use
+ * 7412's device access range mapped from BAR-2 (4M) of PCIe
+ * configuration space.
+ */
+uint32_t bc_dec_reg_rd(struct crystalhd_adp *adp, uint32_t reg_off)
+{
+	if (!adp || (reg_off > adp->pci_mem_len)) {
+		BCMLOG_ERR("dec_rd_reg_off outof range: 0x%08x\n", reg_off);
+		return 0;
+	}
+
+	return readl(adp->addr + reg_off);
+}
+
+/**
+ * bc_dec_reg_wr - Write 7412's device register
+ * @adp: Adapter instance
+ * @reg_off: Register offset.
+ * @val: Dword value to be written.
+ *
+ * Return:
+ *	none.
+ *
+ * 7412's device register write routine. This interface use
+ * 7412's device access range mapped from BAR-2 (4M) of PCIe
+ * configuration space.
+ */
+void bc_dec_reg_wr(struct crystalhd_adp *adp, uint32_t reg_off, uint32_t val)
+{
+	if (!adp || (reg_off > adp->pci_mem_len)) {
+		BCMLOG_ERR("dec_wr_reg_off outof range: 0x%08x\n", reg_off);
+		return;
+	}
+	writel(val, adp->addr + reg_off);
+	udelay(8);
+}
+
+/**
+ * crystalhd_reg_rd - Read Link's device register.
+ * @adp: Adapter instance
+ * @reg_off: Register offset.
+ *
+ * Return:
+ *	32bit value read
+ *
+ * Link device register  read routine. This interface use
+ * Link's device access range mapped from BAR-1 (64K) of PCIe
+ * configuration space.
+ *
+ */
+uint32_t crystalhd_reg_rd(struct crystalhd_adp *adp, uint32_t reg_off)
+{
+	if (!adp || (reg_off > adp->pci_i2o_len)) {
+		BCMLOG_ERR("link_rd_reg_off outof range: 0x%08x\n", reg_off);
+		return 0;
+	}
+	return readl(adp->i2o_addr + reg_off);
+}
+
+/**
+ * crystalhd_reg_wr - Write Link's device register
+ * @adp: Adapter instance
+ * @reg_off: Register offset.
+ * @val: Dword value to be written.
+ *
+ * Return:
+ *	none.
+ *
+ * Link device register  write routine. This interface use
+ * Link's device access range mapped from BAR-1 (64K) of PCIe
+ * configuration space.
+ *
+ */
+void crystalhd_reg_wr(struct crystalhd_adp *adp, uint32_t reg_off, uint32_t val)
+{
+	if (!adp || (reg_off > adp->pci_i2o_len)) {
+		BCMLOG_ERR("link_wr_reg_off outof range: 0x%08x\n", reg_off);
+		return;
+	}
+	writel(val, adp->i2o_addr + reg_off);
+}
+
+/**
+ * crystalhd_mem_rd - Read data from 7412's DRAM area.
+ * @adp: Adapter instance
+ * @start_off: Start offset.
+ * @dw_cnt: Count in dwords.
+ * @rd_buff: Buffer to copy the data from dram.
+ *
+ * Return:
+ *	Status.
+ *
+ * 7412's Dram read routine.
+ */
+BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *adp, uint32_t start_off,
+			 uint32_t dw_cnt, uint32_t *rd_buff)
+{
+	uint32_t ix = 0;
+
+	if (!adp || !rd_buff ||
+	    (bc_chk_dram_range(adp, start_off, dw_cnt) != BC_STS_SUCCESS)) {
+		BCMLOG_ERR("Invalid arg \n");
+		return BC_STS_INV_ARG;
+	}
+	for (ix = 0; ix < dw_cnt; ix++)
+		rd_buff[ix] = crystalhd_dram_rd(adp, (start_off + (ix * 4)));
+
+	return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_mem_wr - Write data to 7412's DRAM area.
+ * @adp: Adapter instance
+ * @start_off: Start offset.
+ * @dw_cnt: Count in dwords.
+ * @wr_buff: Data Buffer to be written.
+ *
+ * Return:
+ *	Status.
+ *
+ * 7412's Dram write routine.
+ */
+BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *adp, uint32_t start_off,
+			 uint32_t dw_cnt, uint32_t *wr_buff)
+{
+	uint32_t ix = 0;
+
+	if (!adp || !wr_buff ||
+	    (bc_chk_dram_range(adp, start_off, dw_cnt) != BC_STS_SUCCESS)) {
+		BCMLOG_ERR("Invalid arg \n");
+		return BC_STS_INV_ARG;
+	}
+
+	for (ix = 0; ix < dw_cnt; ix++)
+		crystalhd_dram_wr(adp, (start_off + (ix * 4)), wr_buff[ix]);
+
+	return BC_STS_SUCCESS;
+}
+/**
+ * crystalhd_pci_cfg_rd - PCIe config read
+ * @adp: Adapter instance
+ * @off: PCI config space offset.
+ * @len: Size -- Byte, Word & dword.
+ * @val: Value read
+ *
+ * Return:
+ *	Status.
+ *
+ * Get value from Link's PCIe config space.
+ */
+BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *adp, uint32_t off,
+			     uint32_t len, uint32_t *val)
+{
+	BC_STATUS sts = BC_STS_SUCCESS;
+	int rc = 0;
+
+	if (!adp || !val) {
+		BCMLOG_ERR("Invalid arg \n");
+		return BC_STS_INV_ARG;
+	}
+
+	switch (len) {
+	case 1:
+		rc = pci_read_config_byte(adp->pdev, off, (u8 *)val);
+		break;
+	case 2:
+		rc = pci_read_config_word(adp->pdev, off, (u16 *)val);
+		break;
+	case 4:
+		rc = pci_read_config_dword(adp->pdev, off, (u32 *)val);
+		break;
+	default:
+		rc = -EINVAL;
+		sts = BC_STS_INV_ARG;
+		BCMLOG_ERR("Invalid len:%d\n", len);
+	};
+
+	if (rc && (sts == BC_STS_SUCCESS))
+		sts = BC_STS_ERROR;
+
+	return sts;
+}
+
+/**
+ * crystalhd_pci_cfg_wr - PCIe config write
+ * @adp: Adapter instance
+ * @off: PCI config space offset.
+ * @len: Size -- Byte, Word & dword.
+ * @val: Value to be written
+ *
+ * Return:
+ *	Status.
+ *
+ * Set value to Link's PCIe config space.
+ */
+BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *adp, uint32_t off,
+			     uint32_t len, uint32_t val)
+{
+	BC_STATUS sts = BC_STS_SUCCESS;
+	int rc = 0;
+
+	if (!adp || !val) {
+		BCMLOG_ERR("Invalid arg \n");
+		return BC_STS_INV_ARG;
+	}
+
+	switch (len) {
+	case 1:
+		rc = pci_write_config_byte(adp->pdev, off, (u8)val);
+		break;
+	case 2:
+		rc = pci_write_config_word(adp->pdev, off, (u16)val);
+		break;
+	case 4:
+		rc = pci_write_config_dword(adp->pdev, off, val);
+		break;
+	default:
+		rc = -EINVAL;
+		sts = BC_STS_INV_ARG;
+		BCMLOG_ERR("Invalid len:%d\n", len);
+	};
+
+	if (rc && (sts == BC_STS_SUCCESS))
+		sts = BC_STS_ERROR;
+
+	return sts;
+}
+
+/**
+ * bc_kern_dma_alloc - Allocate memory for Dma rings
+ * @adp: Adapter instance
+ * @sz: Size of the memory to allocate.
+ * @phy_addr: Physical address of the memory allocated.
+ *	   Typedef to system's dma_addr_t (u64)
+ *
+ * Return:
+ *  Pointer to allocated memory..
+ *
+ * Wrapper to Linux kernel interface.
+ *
+ */
+void *bc_kern_dma_alloc(struct crystalhd_adp *adp, uint32_t sz,
+			dma_addr_t *phy_addr)
+{
+	void *temp = NULL;
+
+	if (!adp || !sz || !phy_addr) {
+		BCMLOG_ERR("Invalide Arg..\n");
+		return temp;
+	}
+
+	temp = pci_alloc_consistent(adp->pdev, sz, phy_addr);
+	if (temp)
+		memset(temp, 0, sz);
+
+	return temp;
+}
+
+/**
+ * bc_kern_dma_free - Release Dma ring memory.
+ * @adp: Adapter instance
+ * @sz: Size of the memory to allocate.
+ * @ka: Kernel virtual address returned during _dio_alloc()
+ * @phy_addr: Physical address of the memory allocated.
+ *	   Typedef to system's dma_addr_t (u64)
+ *
+ * Return:
+ *     none.
+ */
+void bc_kern_dma_free(struct crystalhd_adp *adp, uint32_t sz, void *ka,
+		      dma_addr_t phy_addr)
+{
+	if (!adp || !ka || !sz || !phy_addr) {
+		BCMLOG_ERR("Invalide Arg..\n");
+		return;
+	}
+
+	pci_free_consistent(adp->pdev, sz, ka, phy_addr);
+}
+
+/**
+ * crystalhd_create_dioq - Create Generic DIO queue
+ * @adp: Adapter instance
+ * @dioq_hnd: Handle to the dio queue created
+ * @cb	: Optional - Call back To free the element.
+ * @cbctx: Context to pass to callback.
+ *
+ * Return:
+ *  status
+ *
+ * Initialize Generic DIO queue to hold any data. Callback
+ * will be used to free elements while deleting the queue.
+ */
+BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *adp,
+			      crystalhd_dioq_t **dioq_hnd,
+			      crystalhd_data_free_cb cb, void *cbctx)
+{
+	crystalhd_dioq_t *dioq = NULL;
+
+	if (!adp || !dioq_hnd) {
+		BCMLOG_ERR("Invalid arg!!\n");
+		return BC_STS_INV_ARG;
+	}
+
+	dioq = kzalloc(sizeof(*dioq), GFP_KERNEL);
+	if (!dioq)
+		return BC_STS_INSUFF_RES;
+
+	spin_lock_init(&dioq->lock);
+	dioq->sig = BC_LINK_DIOQ_SIG;
+	dioq->head = (crystalhd_elem_t *)&dioq->head;
+	dioq->tail = (crystalhd_elem_t *)&dioq->head;
+	crystalhd_create_event(&dioq->event);
+	dioq->adp = adp;
+	dioq->data_rel_cb = cb;
+	dioq->cb_context = cbctx;
+	*dioq_hnd = dioq;
+
+	return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_delete_dioq - Delete Generic DIO queue
+ * @adp: Adapter instance
+ * @dioq: DIOQ instance..
+ *
+ * Return:
+ *  None.
+ *
+ * Release Generic DIO queue. This function will remove
+ * all the entries from the Queue and will release data
+ * by calling the call back provided during creation.
+ *
+ */
+void crystalhd_delete_dioq(struct crystalhd_adp *adp, crystalhd_dioq_t *dioq)
+{
+	void *temp;
+
+	if (!dioq || (dioq->sig != BC_LINK_DIOQ_SIG))
+		return;
+
+	do {
+		temp = crystalhd_dioq_fetch(dioq);
+		if (temp && dioq->data_rel_cb)
+			dioq->data_rel_cb(dioq->cb_context, temp);
+	} while (temp);
+	dioq->sig = 0;
+	kfree(dioq);
+}
+
+/**
+ * crystalhd_dioq_add - Add new DIO request element.
+ * @ioq: DIO queue instance
+ * @t: DIO request to be added.
+ * @wake: True - Wake up suspended process.
+ * @tag: Special tag to assign - For search and get.
+ *
+ * Return:
+ *  Status.
+ *
+ * Insert new element to Q tail.
+ */
+BC_STATUS crystalhd_dioq_add(crystalhd_dioq_t *ioq, void *data,
+			   bool wake, uint32_t tag)
+{
+	unsigned long flags = 0;
+	crystalhd_elem_t *tmp;
+
+	if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG) || !data) {
+		BCMLOG_ERR("Invalid arg!!\n");
+		return BC_STS_INV_ARG;
+	}
+
+	tmp = crystalhd_alloc_elem(ioq->adp);
+	if (!tmp) {
+		BCMLOG_ERR("No free elements.\n");
+		return BC_STS_INSUFF_RES;
+	}
+
+	tmp->data = data;
+	tmp->tag = tag;
+	spin_lock_irqsave(&ioq->lock, flags);
+	tmp->flink = (crystalhd_elem_t *)&ioq->head;
+	tmp->blink = ioq->tail;
+	tmp->flink->blink = tmp;
+	tmp->blink->flink = tmp;
+	ioq->count++;
+	spin_unlock_irqrestore(&ioq->lock, flags);
+
+	if (wake)
+		crystalhd_set_event(&ioq->event);
+
+	return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_dioq_fetch - Fetch element from head.
+ * @ioq: DIO queue instance
+ *
+ * Return:
+ *	data element from the head..
+ *
+ * Remove an element from Queue.
+ */
+void *crystalhd_dioq_fetch(crystalhd_dioq_t *ioq)
+{
+	unsigned long flags = 0;
+	crystalhd_elem_t *tmp;
+	crystalhd_elem_t *ret = NULL;
+	void *data = NULL;
+
+	if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG)) {
+		BCMLOG_ERR("Invalid arg!!\n");
+		return data;
+	}
+
+	spin_lock_irqsave(&ioq->lock, flags);
+	tmp = ioq->head;
+	if (tmp != (crystalhd_elem_t *)&ioq->head) {
+		ret = tmp;
+		tmp->flink->blink = tmp->blink;
+		tmp->blink->flink = tmp->flink;
+		ioq->count--;
+	}
+	spin_unlock_irqrestore(&ioq->lock, flags);
+	if (ret) {
+		data = ret->data;
+		crystalhd_free_elem(ioq->adp, ret);
+	}
+
+	return data;
+}
+/**
+ * crystalhd_dioq_find_and_fetch - Search the tag and Fetch element
+ * @ioq: DIO queue instance
+ * @tag: Tag to search for.
+ *
+ * Return:
+ *	element from the head..
+ *
+ * Search TAG and remove the element.
+ */
+void *crystalhd_dioq_find_and_fetch(crystalhd_dioq_t *ioq, uint32_t tag)
+{
+	unsigned long flags = 0;
+	crystalhd_elem_t *tmp;
+	crystalhd_elem_t *ret = NULL;
+	void *data = NULL;
+
+	if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG)) {
+		BCMLOG_ERR("Invalid arg!!\n");
+		return data;
+	}
+
+	spin_lock_irqsave(&ioq->lock, flags);
+	tmp = ioq->head;
+	while (tmp != (crystalhd_elem_t *)&ioq->head) {
+		if (tmp->tag == tag) {
+			ret = tmp;
+			tmp->flink->blink = tmp->blink;
+			tmp->blink->flink = tmp->flink;
+			ioq->count--;
+			break;
+		}
+		tmp = tmp->flink;
+	}
+	spin_unlock_irqrestore(&ioq->lock, flags);
+
+	if (ret) {
+		data = ret->data;
+		crystalhd_free_elem(ioq->adp, ret);
+	}
+
+	return data;
+}
+
+/**
+ * crystalhd_dioq_fetch_wait - Fetch element from Head.
+ * @ioq: DIO queue instance
+ * @to_secs: Wait timeout in seconds..
+ *
+ * Return:
+ *	element from the head..
+ *
+ * Return element from head if Q is not empty. Wait for new element
+ * if Q is empty for Timeout seconds.
+ */
+void *crystalhd_dioq_fetch_wait(crystalhd_dioq_t *ioq, uint32_t to_secs,
+			      uint32_t *sig_pend)
+{
+	unsigned long flags = 0;
+	int rc = 0, count;
+	void *tmp = NULL;
+
+	if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG) || !to_secs || !sig_pend) {
+		BCMLOG_ERR("Invalid arg!!\n");
+		return tmp;
+	}
+
+	count = to_secs;
+	spin_lock_irqsave(&ioq->lock, flags);
+	while ((ioq->count == 0) && count) {
+		spin_unlock_irqrestore(&ioq->lock, flags);
+
+		crystalhd_wait_on_event(&ioq->event, (ioq->count > 0), 1000, rc, 0);
+		if (rc == 0) {
+			goto out;
+		} else if (rc == -EINTR) {
+			BCMLOG(BCMLOG_INFO, "Cancelling fetch wait\n");
+			*sig_pend = 1;
+			return tmp;
+		}
+		spin_lock_irqsave(&ioq->lock, flags);
+		count--;
+	}
+	spin_unlock_irqrestore(&ioq->lock, flags);
+
+out:
+	return crystalhd_dioq_fetch(ioq);
+}
+
+/**
+ * crystalhd_map_dio - Map user address for DMA
+ * @adp:	Adapter instance
+ * @ubuff:	User buffer to map.
+ * @ubuff_sz:	User buffer size.
+ * @uv_offset:	UV buffer offset.
+ * @en_422mode: TRUE:422 FALSE:420 Capture mode.
+ * @dir_tx:	TRUE for Tx (To device from host)
+ * @dio_hnd:	Handle to mapped DIO request.
+ *
+ * Return:
+ *	Status.
+ *
+ * This routine maps user address and lock pages for DMA.
+ *
+ */
+BC_STATUS crystalhd_map_dio(struct crystalhd_adp *adp, void *ubuff,
+			  uint32_t ubuff_sz, uint32_t uv_offset,
+			  bool en_422mode, bool dir_tx,
+			  crystalhd_dio_req **dio_hnd)
+{
+	crystalhd_dio_req	*dio;
+	/* FIXME: jarod: should some of these unsigned longs be uint32_t or uintptr_t? */
+	unsigned long start = 0, end = 0, uaddr = 0, count = 0;
+	unsigned long spsz = 0, uv_start = 0;
+	int i = 0, rw = 0, res = 0, nr_pages = 0, skip_fb_sg = 0;
+
+	if (!adp || !ubuff || !ubuff_sz || !dio_hnd) {
+		BCMLOG_ERR("Invalid arg \n");
+		return BC_STS_INV_ARG;
+	}
+	/* Compute pages */
+	uaddr = (unsigned long)ubuff;
+	count = (unsigned long)ubuff_sz;
+	end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	start = uaddr >> PAGE_SHIFT;
+	nr_pages = end - start;
+
+	if (!count || ((uaddr + count) < uaddr)) {
+		BCMLOG_ERR("User addr overflow!!\n");
+		return BC_STS_INV_ARG;
+	}
+
+	dio = crystalhd_alloc_dio(adp);
+	if (!dio) {
+		BCMLOG_ERR("dio pool empty..\n");
+		return BC_STS_INSUFF_RES;
+	}
+
+	if (dir_tx) {
+		rw = WRITE;
+		dio->direction = DMA_TO_DEVICE;
+	} else {
+		rw = READ;
+		dio->direction = DMA_FROM_DEVICE;
+	}
+
+	if (nr_pages > dio->max_pages) {
+		BCMLOG_ERR("max_pages(%d) exceeded(%d)!!\n",
+			   dio->max_pages, nr_pages);
+		crystalhd_unmap_dio(adp, dio);
+		return BC_STS_INSUFF_RES;
+	}
+
+	if (uv_offset) {
+		uv_start = (uaddr + (unsigned long)uv_offset)  >> PAGE_SHIFT;
+		dio->uinfo.uv_sg_ix = uv_start - start;
+		dio->uinfo.uv_sg_off = ((uaddr + (unsigned long)uv_offset) & ~PAGE_MASK);
+	}
+
+	dio->fb_size = ubuff_sz & 0x03;
+	if (dio->fb_size) {
+		res = copy_from_user(dio->fb_va,
+				     (void *)(uaddr + count - dio->fb_size),
+				     dio->fb_size);
+		if (res) {
+			BCMLOG_ERR("failed %d to copy %u fill bytes from %p\n",
+				   res, dio->fb_size,
+				   (void *)(uaddr + count-dio->fb_size));
+			crystalhd_unmap_dio(adp, dio);
+			return BC_STS_INSUFF_RES;
+		}
+	}
+
+	down_read(&current->mm->mmap_sem);
+	res = get_user_pages(current, current->mm, uaddr, nr_pages, rw == READ,
+			     0, dio->pages, NULL);
+	up_read(&current->mm->mmap_sem);
+
+	/* Save for release..*/
+	dio->sig = crystalhd_dio_locked;
+	if (res < nr_pages) {
+		BCMLOG_ERR("get pages failed: %d-%d\n", nr_pages, res);
+		dio->page_cnt = res;
+		crystalhd_unmap_dio(adp, dio);
+		return BC_STS_ERROR;
+	}
+
+	dio->page_cnt = nr_pages;
+	/* Get scatter/gather */
+	crystalhd_init_sg(dio->sg, dio->page_cnt);
+	crystalhd_set_sg(&dio->sg[0], dio->pages[0], 0, uaddr & ~PAGE_MASK);
+	if (nr_pages > 1) {
+		dio->sg[0].length = PAGE_SIZE - dio->sg[0].offset;
+
+#ifdef CONFIG_X86_64
+		dio->sg[0].dma_length = dio->sg[0].length;
+#endif
+		count -= dio->sg[0].length;
+		for (i = 1; i < nr_pages; i++) {
+			if (count < 4) {
+				spsz = count;
+				skip_fb_sg = 1;
+			} else {
+				spsz = (count < PAGE_SIZE) ?
+					(count & ~0x03) : PAGE_SIZE;
+			}
+			crystalhd_set_sg(&dio->sg[i], dio->pages[i], spsz, 0);
+			count -= spsz;
+		}
+	} else {
+		if (count < 4) {
+			dio->sg[0].length = count;
+			skip_fb_sg = 1;
+		} else {
+			dio->sg[0].length = count - dio->fb_size;
+		}
+#ifdef CONFIG_X86_64
+		dio->sg[0].dma_length = dio->sg[0].length;
+#endif
+	}
+	dio->sg_cnt = pci_map_sg(adp->pdev, dio->sg,
+				 dio->page_cnt, dio->direction);
+	if (dio->sg_cnt <= 0) {
+		BCMLOG_ERR("sg map %d-%d \n", dio->sg_cnt, dio->page_cnt);
+		crystalhd_unmap_dio(adp, dio);
+		return BC_STS_ERROR;
+	}
+	if (dio->sg_cnt && skip_fb_sg)
+		dio->sg_cnt -= 1;
+	dio->sig = crystalhd_dio_sg_mapped;
+	/* Fill in User info.. */
+	dio->uinfo.xfr_len   = ubuff_sz;
+	dio->uinfo.xfr_buff  = ubuff;
+	dio->uinfo.uv_offset = uv_offset;
+	dio->uinfo.b422mode  = en_422mode;
+	dio->uinfo.dir_tx    = dir_tx;
+
+	*dio_hnd = dio;
+
+	return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_unmap_sgl - Release mapped resources
+ * @adp: Adapter instance
+ * @dio: DIO request instance
+ *
+ * Return:
+ *	Status.
+ *
+ * This routine is to unmap the user buffer pages.
+ */
+BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *adp, crystalhd_dio_req *dio)
+{
+	struct page *page = NULL;
+	int j = 0;
+
+	if (!adp || !dio) {
+		BCMLOG_ERR("Invalid arg \n");
+		return BC_STS_INV_ARG;
+	}
+
+	if ((dio->page_cnt > 0) && (dio->sig != crystalhd_dio_inv)) {
+		for (j = 0; j < dio->page_cnt; j++) {
+			page = dio->pages[j];
+			if (page) {
+				if (!PageReserved(page) &&
+				    (dio->direction == DMA_FROM_DEVICE))
+					SetPageDirty(page);
+				page_cache_release(page);
+			}
+		}
+	}
+	if (dio->sig == crystalhd_dio_sg_mapped)
+		pci_unmap_sg(adp->pdev, dio->sg, dio->page_cnt, dio->direction);
+
+	crystalhd_free_dio(adp, dio);
+
+	return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_create_dio_pool - Allocate mem pool for DIO management.
+ * @adp: Adapter instance
+ * @max_pages: Max pages for size calculation.
+ *
+ * Return:
+ *	system error.
+ *
+ * This routine creates a memory pool to hold dio context for
+ * for HW Direct IO operation.
+ */
+int crystalhd_create_dio_pool(struct crystalhd_adp *adp, uint32_t max_pages)
+{
+	uint32_t asz = 0, i = 0;
+	uint8_t	*temp;
+	crystalhd_dio_req *dio;
+
+	if (!adp || !max_pages) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return -EINVAL;
+	}
+
+	/* Get dma memory for fill byte handling..*/
+	adp->fill_byte_pool = pci_pool_create("crystalhd_fbyte",
+					      adp->pdev, 8, 8, 0);
+	if (!adp->fill_byte_pool) {
+		BCMLOG_ERR("failed to create fill byte pool\n");
+		return -ENOMEM;
+	}
+
+	/* Get the max size from user based on 420/422 modes */
+	asz =  (sizeof(*dio->pages) * max_pages) +
+	       (sizeof(*dio->sg) * max_pages) + sizeof(*dio);
+
+	BCMLOG(BCMLOG_DBG, "Initializing Dio pool %d %d %x %p\n",
+	       BC_LINK_SG_POOL_SZ, max_pages, asz, adp->fill_byte_pool);
+
+	for (i = 0; i < BC_LINK_SG_POOL_SZ; i++) {
+		temp = (uint8_t *)kzalloc(asz, GFP_KERNEL);
+		if ((temp) == NULL) {
+			BCMLOG_ERR("Failed to alloc %d mem\n", asz);
+			return -ENOMEM;
+		}
+
+		dio = (crystalhd_dio_req *)temp;
+		temp += sizeof(*dio);
+		dio->pages = (struct page **)temp;
+		temp += (sizeof(*dio->pages) * max_pages);
+		dio->sg = (struct scatterlist *)temp;
+		dio->max_pages = max_pages;
+		dio->fb_va = pci_pool_alloc(adp->fill_byte_pool, GFP_KERNEL,
+					    &dio->fb_pa);
+		if (!dio->fb_va) {
+			BCMLOG_ERR("fill byte alloc failed.\n");
+			return -ENOMEM;
+		}
+
+		crystalhd_free_dio(adp, dio);
+	}
+
+	return 0;
+}
+
+/**
+ * crystalhd_destroy_dio_pool - Release DIO mem pool.
+ * @adp: Adapter instance
+ *
+ * Return:
+ *	none.
+ *
+ * This routine releases dio memory pool during close.
+ */
+void crystalhd_destroy_dio_pool(struct crystalhd_adp *adp)
+{
+	crystalhd_dio_req *dio;
+	int count = 0;
+
+	if (!adp) {
+		BCMLOG_ERR("Invalid Arg!!\n");
+		return;
+	}
+
+	do {
+		dio = crystalhd_alloc_dio(adp);
+		if (dio) {
+			if (dio->fb_va)
+				pci_pool_free(adp->fill_byte_pool,
+					      dio->fb_va, dio->fb_pa);
+			count++;
+			kfree(dio);
+		}
+	} while (dio);
+
+	if (adp->fill_byte_pool) {
+		pci_pool_destroy(adp->fill_byte_pool);
+		adp->fill_byte_pool = NULL;
+	}
+
+	BCMLOG(BCMLOG_DBG, "Released dio pool %d \n", count);
+}
+
+/**
+ * crystalhd_create_elem_pool - List element pool creation.
+ * @adp: Adapter instance
+ * @pool_size: Number of elements in the pool.
+ *
+ * Return:
+ *	0 - success, <0 error
+ *
+ * Create general purpose list element pool to hold pending,
+ * and active requests.
+ */
+int __devinit crystalhd_create_elem_pool(struct crystalhd_adp *adp,
+		uint32_t pool_size)
+{
+	uint32_t i;
+	crystalhd_elem_t *temp;
+
+	if (!adp || !pool_size)
+		return -EINVAL;
+
+	for (i = 0; i < pool_size; i++) {
+		temp = kzalloc(sizeof(*temp), GFP_KERNEL);
+		if (!temp) {
+			BCMLOG_ERR("kalloc failed \n");
+			return -ENOMEM;
+		}
+		crystalhd_free_elem(adp, temp);
+	}
+	BCMLOG(BCMLOG_DBG, "allocated %d elem\n", pool_size);
+	return 0;
+}
+
+/**
+ * crystalhd_delete_elem_pool - List element pool deletion.
+ * @adp: Adapter instance
+ *
+ * Return:
+ *	none
+ *
+ * Delete general purpose list element pool.
+ */
+void crystalhd_delete_elem_pool(struct crystalhd_adp *adp)
+{
+	crystalhd_elem_t *temp;
+	int dbg_cnt = 0;
+
+	if (!adp)
+		return;
+
+	do {
+		temp = crystalhd_alloc_elem(adp);
+		if (temp) {
+			kfree(temp);
+			dbg_cnt++;
+		}
+	} while (temp);
+
+	BCMLOG(BCMLOG_DBG, "released %d elem\n", dbg_cnt);
+}
+
+/*================ Debug support routines.. ================================*/
+void crystalhd_show_buffer(uint32_t off, uint8_t *buff, uint32_t dwcount)
+{
+	uint32_t i, k = 1;
+
+	for (i = 0; i < dwcount; i++) {
+		if (k == 1)
+			BCMLOG(BCMLOG_DATA, "0x%08X : ", off);
+
+		BCMLOG(BCMLOG_DATA, " 0x%08X ", *((uint32_t *)buff));
+
+		buff += sizeof(uint32_t);
+		off  += sizeof(uint32_t);
+		k++;
+		if ((i == dwcount - 1) || (k > 4)) {
+			BCMLOG(BCMLOG_DATA, "\n");
+			k = 1;
+		}
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_misc.h linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_misc.h
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/crystalhd_misc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/crystalhd_misc.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,229 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ *  Name: crystalhd_misc . h
+ *
+ *  Description:
+ *		BCM70012 Linux driver general purpose routines.
+ *		Includes reg/mem read and write routines.
+ *
+ *  HISTORY:
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver.  If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#ifndef _CRYSTALHD_MISC_H_
+#define _CRYSTALHD_MISC_H_
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/ioctl.h>
+#include <linux/dma-mapping.h>
+#include <linux/version.h>
+#include <linux/sched.h>
+#include <asm/system.h>
+#include "bc_dts_glob_lnx.h"
+
+/* Global log level variable defined in crystal_misc.c file */
+extern uint32_t g_linklog_level;
+
+/* Global element pool for all Queue management.
+ * TX: Active = BC_TX_LIST_CNT, Free = BC_TX_LIST_CNT.
+ * RX: Free = BC_RX_LIST_CNT, Active = 2
+ * FW-CMD: 4
+ */
+#define	BC_LINK_ELEM_POOL_SZ	((BC_TX_LIST_CNT * 2) + BC_RX_LIST_CNT + 2 + 4)
+
+/* Driver's IODATA pool count */
+#define	CHD_IODATA_POOL_SZ    (BC_IOCTL_DATA_POOL_SIZE * BC_LINK_MAX_OPENS)
+
+/* Scatter Gather memory pool size for Tx and Rx */
+#define BC_LINK_SG_POOL_SZ    (BC_TX_LIST_CNT + BC_RX_LIST_CNT)
+
+enum _crystalhd_dio_sig {
+	crystalhd_dio_inv = 0,
+	crystalhd_dio_locked,
+	crystalhd_dio_sg_mapped,
+};
+
+struct crystalhd_dio_user_info {
+	void			*xfr_buff;
+	uint32_t		xfr_len;
+	uint32_t		uv_offset;
+	bool			dir_tx;
+
+	uint32_t		uv_sg_ix;
+	uint32_t		uv_sg_off;
+	int			comp_sts;
+	int			ev_sts;
+	uint32_t		y_done_sz;
+	uint32_t		uv_done_sz;
+	uint32_t		comp_flags;
+	bool			b422mode;
+};
+
+typedef struct _crystalhd_dio_req {
+	uint32_t			sig;
+	uint32_t			max_pages;
+	struct page			**pages;
+	struct scatterlist		*sg;
+	int				sg_cnt;
+	int				page_cnt;
+	int				direction;
+	struct crystalhd_dio_user_info	uinfo;
+	void				*fb_va;
+	uint32_t			fb_size;
+	dma_addr_t			fb_pa;
+	struct _crystalhd_dio_req		*next;
+} crystalhd_dio_req;
+
+#define BC_LINK_DIOQ_SIG	(0x09223280)
+
+typedef struct _crystalhd_elem_s {
+	struct _crystalhd_elem_s	*flink;
+	struct _crystalhd_elem_s	*blink;
+	void			*data;
+	uint32_t		tag;
+} crystalhd_elem_t;
+
+typedef void (*crystalhd_data_free_cb)(void *context, void *data);
+
+typedef struct _crystalhd_dioq_s {
+	uint32_t		sig;
+	struct crystalhd_adp	*adp;
+	crystalhd_elem_t		*head;
+	crystalhd_elem_t		*tail;
+	uint32_t		count;
+	spinlock_t		lock;
+	wait_queue_head_t	event;
+	crystalhd_data_free_cb	data_rel_cb;
+	void			*cb_context;
+} crystalhd_dioq_t;
+
+typedef void (*hw_comp_callback)(crystalhd_dio_req *,
+				 wait_queue_head_t *event, BC_STATUS sts);
+
+/*========= Decoder (7412) register access routines.================= */
+uint32_t bc_dec_reg_rd(struct crystalhd_adp *, uint32_t);
+void bc_dec_reg_wr(struct crystalhd_adp *, uint32_t, uint32_t);
+
+/*========= Link (70012) register access routines.. =================*/
+uint32_t crystalhd_reg_rd(struct crystalhd_adp *, uint32_t);
+void crystalhd_reg_wr(struct crystalhd_adp *, uint32_t, uint32_t);
+
+/*========= Decoder (7412) memory access routines..=================*/
+BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *);
+BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *);
+
+/*==========Link (70012) PCIe Config access routines.================*/
+BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *);
+BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t);
+
+/*========= Linux Kernel Interface routines. ======================= */
+void *bc_kern_dma_alloc(struct crystalhd_adp *, uint32_t, dma_addr_t *);
+void bc_kern_dma_free(struct crystalhd_adp *, uint32_t,
+		      void *, dma_addr_t);
+#define crystalhd_create_event(_ev)	init_waitqueue_head(_ev)
+#define crystalhd_set_event(_ev)		wake_up_interruptible(_ev)
+#define crystalhd_wait_on_event(ev, condition, timeout, ret, nosig)	\
+do {									\
+	DECLARE_WAITQUEUE(entry, current);				\
+	unsigned long end = jiffies + ((timeout * HZ) / 1000);		\
+		ret = 0;						\
+	add_wait_queue(ev, &entry);					\
+	for (;;) {							\
+		__set_current_state(TASK_INTERRUPTIBLE);		\
+		if (condition) {					\
+			break;						\
+		}							\
+		if (time_after_eq(jiffies, end)) {			\
+			ret = -EBUSY;					\
+			break;						\
+		}							\
+		schedule_timeout((HZ / 100 > 1) ? HZ / 100 : 1);	\
+		if (!nosig && signal_pending(current)) {		\
+			ret = -EINTR;					\
+			break;						\
+		}							\
+	}								\
+	__set_current_state(TASK_RUNNING);				\
+	remove_wait_queue(ev, &entry);					\
+} while (0)
+
+/*================ Direct IO mapping routines ==================*/
+extern int crystalhd_create_dio_pool(struct crystalhd_adp *, uint32_t);
+extern void crystalhd_destroy_dio_pool(struct crystalhd_adp *);
+extern BC_STATUS crystalhd_map_dio(struct crystalhd_adp *, void *, uint32_t,
+				   uint32_t, bool, bool, crystalhd_dio_req**);
+
+extern BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *, crystalhd_dio_req*);
+#define crystalhd_get_sgle_paddr(_dio, _ix) (cpu_to_le64(sg_dma_address(&_dio->sg[_ix])))
+#define crystalhd_get_sgle_len(_dio, _ix) (cpu_to_le32(sg_dma_len(&_dio->sg[_ix])))
+
+/*================ General Purpose Queues ==================*/
+extern BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *, crystalhd_dioq_t **, crystalhd_data_free_cb , void *);
+extern void crystalhd_delete_dioq(struct crystalhd_adp *, crystalhd_dioq_t *);
+extern BC_STATUS crystalhd_dioq_add(crystalhd_dioq_t *ioq, void *data, bool wake, uint32_t tag);
+extern void *crystalhd_dioq_fetch(crystalhd_dioq_t *ioq);
+extern void *crystalhd_dioq_find_and_fetch(crystalhd_dioq_t *ioq, uint32_t tag);
+extern void *crystalhd_dioq_fetch_wait(crystalhd_dioq_t *ioq, uint32_t to_secs, uint32_t *sig_pend);
+
+#define crystalhd_dioq_count(_ioq)	((_ioq) ? _ioq->count : 0)
+
+extern int crystalhd_create_elem_pool(struct crystalhd_adp *, uint32_t);
+extern void crystalhd_delete_elem_pool(struct crystalhd_adp *);
+
+
+/*================ Debug routines/macros .. ================================*/
+extern void crystalhd_show_buffer(uint32_t off, uint8_t *buff, uint32_t dwcount);
+
+enum _chd_log_levels {
+	BCMLOG_ERROR		= 0x80000000,	/* Don't disable this option */
+	BCMLOG_DATA		= 0x40000000,	/* Data, enable by default */
+	BCMLOG_SPINLOCK		= 0x20000000,	/* Spcial case for Spin locks*/
+
+	/* Following are allowed only in debug mode */
+	BCMLOG_INFO		= 0x00000001,	/* Generic informational */
+	BCMLOG_DBG		= 0x00000002,	/* First level Debug info */
+	BCMLOG_SSTEP		= 0x00000004,	/* Stepping information */
+	BCMLOG_ENTER_LEAVE	= 0x00000008,	/* stack tracking */
+};
+
+#define BCMLOG_ENTER				\
+if (g_linklog_level & BCMLOG_ENTER_LEAVE) {	\
+	printk("Entered %s\n", __func__);	\
+}
+
+#define BCMLOG_LEAVE				\
+if (g_linklog_level & BCMLOG_ENTER_LEAVE) {	\
+	printk("Leaving %s\n", __func__);	\
+}
+
+#define BCMLOG(trace, fmt, args...)		\
+if (g_linklog_level & trace) {			\
+	printk(fmt, ##args);			\
+}
+
+#define BCMLOG_ERR(fmt, args...)					\
+do {									\
+	if (g_linklog_level & BCMLOG_ERROR) {				\
+		printk("*ERR*:%s:%d: "fmt, __FILE__, __LINE__, ##args);	\
+	}								\
+} while (0);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,6 @@
+config CRYSTALHD
+	tristate "Broadcom Crystal HD video decoder support"
+	depends on PCI
+	default n
+	help
+	  Support for the Broadcom Crystal HD video decoder chipset
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/Makefile linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,6 @@
+obj-$(CONFIG_CRYSTALHD)	+= crystalhd.o
+
+crystalhd-objs		:= crystalhd_cmds.o	\
+			   crystalhd_hw.o	\
+			   crystalhd_lnx.o	\
+			   crystalhd_misc.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/TODO linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/TODO
--- linux-libre-2.6.33-gnu1/drivers/staging/crystalhd/TODO	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/crystalhd/TODO	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,16 @@
+- Testing
+- Cleanup return codes
+- Cleanup typedefs
+- Cleanup all WIN* references
+- Allocate an Accelerator device class specific Major number,
+  since we don't have any other open sourced accelerators, it is the only
+  one in that category for now.
+  A somewhat similar device is the DXR2/3
+
+Please send patches to:
+Greg Kroah-Hartman <greg@kroah.com>
+Naren Sankar <nsankar@broadcom.com>
+Jarod Wilson <jarod@wilsonet.com>
+Scott Davilla <davilla@4pi.com>
+Manu Abraham <abraham.manu@gmail.com>
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-alsa.c linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-alsa.c
--- linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-alsa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-alsa.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/vmalloc.h>
 #include <linux/dma-mapping.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include <asm/delay.h>
 #include <sound/core.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-audio-upstream.c linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-audio-upstream.c
--- linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-audio-upstream.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-audio-upstream.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/file.h>
 #include <linux/fcntl.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-audups11.c linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-audups11.c
--- linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-audups11.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-audups11.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,8 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
+
 #include "cx25821-video.h"
 
 static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
@@ -343,10 +345,11 @@ static int vidioc_s_ctrl(struct file *fi
 			 struct v4l2_control *ctl)
 {
 	struct cx25821_fh *fh = priv;
-	struct cx25821_dev *dev = fh->dev;
+	struct cx25821_dev *dev;
 	int err;
 
 	if (fh) {
+		dev = fh->dev;
 		err = v4l2_prio_check(&dev->prio, &fh->prio);
 		if (0 != err)
 			return err;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-core.c linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-core.c
--- linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include "cx25821.h"
 #include "cx25821-sram.h"
 #include "cx25821-video.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-medusa-video.c linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-medusa-video.c
--- linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-medusa-video.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-medusa-video.c	2010-05-16 17:17:36.000000000 -0400
@@ -795,10 +795,8 @@ int medusa_video_init(struct cx25821_dev
 	value &= 0xFFFFFFDF;
 	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
 
-	if (ret_val < 0) {
-		mutex_unlock(&dev->lock);
+	if (ret_val < 0)
 		return -EINVAL;
-	}
 
 	mutex_unlock(&dev->lock);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-video.c linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-video.c
--- linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-video.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-video.c	2010-05-16 17:17:36.000000000 -0400
@@ -876,7 +876,7 @@ int cx25821_enum_input(struct cx25821_de
 	dprintk(1, "%s()\n", __func__);
 
 	n = i->index;
-	if (n > 2)
+	if (n >= 2)
 		return -EINVAL;
 
 	if (0 == INPUT(n)->type)
@@ -963,10 +963,11 @@ int cx25821_set_freq(struct cx25821_dev
 int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
 {
 	struct cx25821_fh *fh = priv;
-	struct cx25821_dev *dev = fh->dev;
+	struct cx25821_dev *dev;
 	int err;
 
 	if (fh) {
+		dev = fh->dev;
 		err = v4l2_prio_check(&dev->prio, &fh->prio);
 		if (0 != err)
 			return err;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-video-upstream.c linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-video-upstream.c
--- linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-video-upstream.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-video-upstream.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/syscalls.h>
 #include <linux/file.h>
 #include <linux/fcntl.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-video-upstream-ch2.c linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
--- linux-libre-2.6.33-gnu1/drivers/staging/cx25821/cx25821-video-upstream-ch2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/cx25821/cx25821-video-upstream-ch2.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/syscalls.h>
 #include <linux/file.h>
 #include <linux/fcntl.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,7 @@ config MSM_CAMERA_DEBUG
 
 config MSM_CAMERA_FLASH
 	bool "Qualcomm MSM camera flash support"
-	depends on MSM_CAMERA
+	depends on MSM_CAMERA && BROKEN
 	---help---
 	  Enable support for LED flash for msm camera
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/Makefile linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,3 +1,4 @@
+EXTRA_CFLAGS=-Idrivers/staging/dream/include
 obj-$(CONFIG_MT9T013) += mt9t013.o mt9t013_reg.o
 obj-$(CONFIG_MT9D112) += mt9d112.o mt9d112_reg.o
 obj-$(CONFIG_MT9P012) += mt9p012_fox.o mt9p012_reg.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/msm_camera.c linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/msm_camera.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/msm_camera.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/msm_camera.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
  * Copyright (C) 2008-2009 QUALCOMM Incorporated.
  */
 
-//FIXME: most allocations need not be GFP_ATOMIC
+/* FIXME: most allocations need not be GFP_ATOMIC */
 /* FIXME: management of mutexes */
 /* FIXME: msm_pmem_region_lookup return values */
 /* FIXME: way too many copy to/from user */
@@ -12,6 +12,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <mach/board.h>
@@ -76,14 +77,14 @@ static LIST_HEAD(msm_sensors);
 		list_del_init(&qcmd->list);			\
 		kfree(qcmd);					\
 	};							\
-} while(0)
+} while (0)
 
 #define MSM_DRAIN_QUEUE(sync, name) do {			\
 	unsigned long flags;					\
 	spin_lock_irqsave(&(sync)->name##_lock, flags);		\
 	MSM_DRAIN_QUEUE_NOSYNC(sync, name);			\
 	spin_unlock_irqrestore(&(sync)->name##_lock, flags);	\
-} while(0)
+} while (0)
 
 static int check_overlap(struct hlist_head *ptype,
 			unsigned long paddr,
@@ -361,7 +362,7 @@ static int __msm_get_frame(struct msm_sy
 	if (!frame->buffer) {
 		pr_err("%s: cannot get frame, invalid lookup address "
 			"y=%x cbcr=%x offset=%d\n",
-			__FUNCTION__,
+			__func__,
 			pphy->y_phy,
 			pphy->cbcr_phy,
 			frame->y_off);
@@ -455,7 +456,7 @@ static int msm_disable_vfe(struct msm_sy
 	return rc;
 }
 
-static struct msm_queue_cmd* __msm_control(struct msm_sync *sync,
+static struct msm_queue_cmd *__msm_control(struct msm_sync *sync,
 		struct msm_control_device_queue *queue,
 		struct msm_queue_cmd *qcmd,
 		int timeout)
@@ -592,8 +593,7 @@ end:
 	 * a result of a successful completion, we are freeing the qcmd that
 	 * we dequeued from queue->ctrl_status_q.
 	 */
-	if (qcmd)
-		kfree(qcmd);
+	kfree(qcmd);
 
 	CDBG("msm_control: end rc = %d\n", rc);
 	return rc;
@@ -670,7 +670,7 @@ static int msm_get_stats(struct msm_sync
 					&(stats.fd));
 			if (!stats.buffer) {
 				pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
-					__FUNCTION__);
+					__func__);
 				rc = -EINVAL;
 				goto failure;
 			}
@@ -718,8 +718,7 @@ static int msm_get_stats(struct msm_sync
 					buf.fmain.buffer =
 						(unsigned long)region.vaddr;
 					buf.fmain.fd = region.fd;
-				}
-				else {
+				} else {
 					pr_err("%s: pmem lookup failed\n",
 						__func__);
 					rc = -EINVAL;
@@ -796,8 +795,7 @@ static int msm_get_stats(struct msm_sync
 	}
 
 failure:
-	if (qcmd)
-		kfree(qcmd);
+	kfree(qcmd);
 
 	CDBG("msm_get_stats: %d\n", rc);
 	return rc;
@@ -838,8 +836,8 @@ static int msm_ctrl_cmd_done(struct msm_
 			kfree(qcmd);
 			goto end;
 		}
-	}
-	else ctrlcmd->value = NULL;
+	} else
+		ctrlcmd->value = NULL;
 
 end:
 	CDBG("msm_ctrl_cmd_done: end rc = %d\n", rc);
@@ -869,14 +867,14 @@ static int msm_config_vfe(struct msm_syn
 		return -EFAULT;
 	}
 
-	switch(cfgcmd.cmd_type) {
+	switch (cfgcmd.cmd_type) {
 	case CMD_STATS_ENABLE:
 		axi_data.bufnum1 =
 			msm_pmem_region_lookup(&sync->stats,
 					MSM_PMEM_AEC_AWB, &region[0],
 					NUM_WB_EXP_STAT_OUTPUT_BUFFERS);
 		if (!axi_data.bufnum1) {
-			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			pr_err("%s: pmem region lookup error\n", __func__);
 			return -EINVAL;
 		}
 		axi_data.region = &region[0];
@@ -888,7 +886,7 @@ static int msm_config_vfe(struct msm_syn
 					MSM_PMEM_AF, &region[0],
 					NUM_AF_STAT_OUTPUT_BUFFERS);
 		if (!axi_data.bufnum1) {
-			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			pr_err("%s: pmem region lookup error\n", __func__);
 			return -EINVAL;
 		}
 		axi_data.region = &region[0];
@@ -899,7 +897,7 @@ static int msm_config_vfe(struct msm_syn
 		break;
 	default:
 		pr_err("%s: unknown command type %d\n",
-			__FUNCTION__, cfgcmd.cmd_type);
+			__func__, cfgcmd.cmd_type);
 		return -EINVAL;
 	}
 
@@ -928,7 +926,7 @@ static int msm_frame_axi_cfg(struct msm_
 			msm_pmem_region_lookup(&sync->frame, pmem_type,
 				&region[0], 8);
 		if (!axi_data.bufnum1) {
-			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			pr_err("%s: pmem region lookup error\n", __func__);
 			return -EINVAL;
 		}
 		break;
@@ -939,7 +937,7 @@ static int msm_frame_axi_cfg(struct msm_
 			msm_pmem_region_lookup(&sync->frame, pmem_type,
 				&region[0], 8);
 		if (!axi_data.bufnum2) {
-			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			pr_err("%s: pmem region lookup error\n", __func__);
 			return -EINVAL;
 		}
 		break;
@@ -950,7 +948,7 @@ static int msm_frame_axi_cfg(struct msm_
 			msm_pmem_region_lookup(&sync->frame, pmem_type,
 				&region[0], 8);
 		if (!axi_data.bufnum1) {
-			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			pr_err("%s: pmem region lookup error\n", __func__);
 			return -EINVAL;
 		}
 
@@ -959,7 +957,7 @@ static int msm_frame_axi_cfg(struct msm_
 			msm_pmem_region_lookup(&sync->frame, pmem_type,
 				&region[axi_data.bufnum1], 8);
 		if (!axi_data.bufnum2) {
-			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			pr_err("%s: pmem region lookup error\n", __func__);
 			return -EINVAL;
 		}
 		break;
@@ -970,7 +968,7 @@ static int msm_frame_axi_cfg(struct msm_
 			msm_pmem_region_lookup(&sync->frame, pmem_type,
 				&region[0], 8);
 		if (!axi_data.bufnum2) {
-			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			pr_err("%s: pmem region lookup error\n", __func__);
 			return -EINVAL;
 		}
 		break;
@@ -981,7 +979,7 @@ static int msm_frame_axi_cfg(struct msm_
 
 	default:
 		pr_err("%s: unknown command type %d\n",
-			__FUNCTION__, cfgcmd->cmd_type);
+			__func__, cfgcmd->cmd_type);
 		return -EINVAL;
 	}
 
@@ -1047,7 +1045,7 @@ static int __msm_put_frame_buf(struct ms
 			rc = sync->vfefn.vfe_config(&cfgcmd, &pphy);
 	} else {
 		pr_err("%s: msm_pmem_frame_vtop_lookup failed\n",
-			__FUNCTION__);
+			__func__);
 		rc = -EINVAL;
 	}
 
@@ -1131,7 +1129,7 @@ static int msm_stats_axi_cfg(struct msm_
 		break;
 	default:
 		pr_err("%s: unknown command type %d\n",
-			__FUNCTION__, cfgcmd->cmd_type);
+			__func__, cfgcmd->cmd_type);
 		return -EINVAL;
 	}
 
@@ -1140,7 +1138,7 @@ static int msm_stats_axi_cfg(struct msm_
 			msm_pmem_region_lookup(&sync->stats, pmem_type,
 				&region[0], NUM_WB_EXP_STAT_OUTPUT_BUFFERS);
 		if (!axi_data.bufnum1) {
-			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			pr_err("%s: pmem region lookup error\n", __func__);
 			return -EINVAL;
 		}
 		axi_data.region = &region[0];
@@ -1177,7 +1175,7 @@ static int msm_put_stats_buffer(struct m
 			cfgcmd.cmd_type = CMD_STATS_AF_BUF_RELEASE;
 		else {
 			pr_err("%s: invalid buf type %d\n",
-				__FUNCTION__,
+				__func__,
 				buf.type);
 			rc = -EINVAL;
 			goto put_done;
@@ -1223,7 +1221,7 @@ static int msm_axi_config(struct msm_syn
 
 	default:
 		pr_err("%s: unknown command type %d\n",
-			__FUNCTION__,
+			__func__,
 			cfgcmd.cmd_type);
 		return -EINVAL;
 	}
@@ -1622,7 +1620,8 @@ static int msm_release_control(struct in
 	int rc;
 	struct msm_control_device *ctrl_pmsm = filep->private_data;
 	struct msm_device *pmsm = ctrl_pmsm->pmsm;
-	printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name);
+	printk(KERN_INFO "msm_camera: RELEASE %s\n",
+					filep->f_path.dentry->d_name.name);
 	rc = __msm_release(pmsm->sync);
 	if (!rc) {
 		MSM_DRAIN_QUEUE(&ctrl_pmsm->ctrl_q, ctrl_status_q);
@@ -1636,7 +1635,8 @@ static int msm_release_frame(struct inod
 {
 	int rc;
 	struct msm_device *pmsm = filep->private_data;
-	printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name);
+	printk(KERN_INFO "msm_camera: RELEASE %s\n",
+					filep->f_path.dentry->d_name.name);
 	rc = __msm_release(pmsm->sync);
 	if (!rc) {
 		MSM_DRAIN_QUEUE(pmsm->sync, prev_frame_q);
@@ -1720,7 +1720,7 @@ static void msm_vfe_sync(struct msm_vfe_
 	qcmd->type = qtype;
 
 	if (qtype == MSM_CAM_Q_VFE_MSG) {
-		switch(vdata->type) {
+		switch (vdata->type) {
 		case VFE_MSG_OUTPUT1:
 		case VFE_MSG_OUTPUT2:
 			qcmd_frame =
@@ -1885,8 +1885,10 @@ static int msm_open_control(struct inode
 		return -ENOMEM;
 
 	rc = msm_open_common(inode, filep, 0);
-	if (rc < 0)
+	if (rc < 0) {
+		kfree(ctrl_pmsm);
 		return rc;
+	}
 
 	ctrl_pmsm->pmsm = filep->private_data;
 	filep->private_data = ctrl_pmsm;
@@ -1929,7 +1931,7 @@ static int __msm_v4l2_control(struct msm
 	memcpy(out->value, ctrl->value, ctrl->length);
 
 end:
-	if (rcmd) kfree(rcmd);
+	kfree(rcmd);
 	CDBG("__msm_v4l2_control: end rc = %d\n", rc);
 	return rc;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/msm_v4l2.c linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/msm_v4l2.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/msm_v4l2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/msm_v4l2.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/spinlock.h>
 #include <linux/videodev2.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 #include <media/v4l2-dev.h>
 #include <media/msm_camera.h>
 #include <mach/camera.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/msm_vfe7x.c linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/msm_vfe7x.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/msm_vfe7x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/msm_vfe7x.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/android_pmem.h>
+#include <linux/slab.h>
 #include <mach/msm_adsp.h>
 #include <linux/delay.h>
 #include <linux/wait.h>
@@ -255,8 +256,7 @@ static int vfe_7x_init(struct msm_vfe_ca
 
 	extlen = sizeof(struct vfe_frame_extra);
 
-	extdata =
-		kmalloc(sizeof(extlen), GFP_ATOMIC);
+	extdata = kmalloc(extlen, GFP_ATOMIC);
 	if (!extdata) {
 		rc = -ENOMEM;
 		goto init_fail;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/msm_vfe8x.c linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/msm_vfe8x.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/msm_vfe8x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/msm_vfe8x.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2008-2009 QUALCOMM Incorporated.
  */
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/interrupt.h>
 #include <mach/irqs.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/mt9d112.c linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/mt9d112.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/mt9d112.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/mt9d112.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/i2c.h>
 #include <linux/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/mt9p012_fox.c linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/mt9p012_fox.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/mt9p012_fox.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/mt9p012_fox.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
 
 #include <linux/delay.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/mt9t013.c linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/mt9t013.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/mt9t013.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/mt9t013.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
 
 #include <linux/delay.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/s5k3e2fx.c linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/s5k3e2fx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/camera/s5k3e2fx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/camera/s5k3e2fx.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/i2c.h>
 #include <linux/uaccess.h>
@@ -743,12 +744,12 @@ static int s5k3e2fx_sensor_open_init(con
 	}
 
 	/* initialize AF */
-	if ((rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-			0x3146, 0x3A)) < 0)
+	rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3146, 0x3A);
+	if (rc < 0)
 		goto init_fail1;
 
-	if ((rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-			0x3130, 0x03)) < 0)
+	rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3130, 0x03);
+	if (rc < 0)
 		goto init_fail1;
 
 	goto init_done;
@@ -814,20 +815,20 @@ static uint16_t s5k3e2fx_get_prev_lines_
 
 static uint16_t s5k3e2fx_get_prev_pixels_pl(void)
 {
-	return (s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
-		s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p);
+	return s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
+		s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p;
 }
 
 static uint16_t s5k3e2fx_get_pict_lines_pf(void)
 {
-	return (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
-		s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l);
+	return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
+		s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l;
 }
 
 static uint16_t s5k3e2fx_get_pict_pixels_pl(void)
 {
-	return (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
-		s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p);
+	return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
+		s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p;
 }
 
 static uint32_t s5k3e2fx_get_pict_max_exp_lc(void)
@@ -1093,14 +1094,10 @@ static int32_t s5k3e2fx_move_focus(int d
 
 	actual_step = step_direction * (int16_t)num_steps;
 	pos_offset = init_code + s5k3e2fx_ctrl->curr_lens_pos;
-	gain = actual_step * 0x400 / 5;
+	gain = ((actual_step << 10) / 5) >> 10;
 
-	for (i = 0; i <= 4; i++) {
-		if (actual_step >= 0)
-			s_move[i] = ((((i+1)*gain+0x200) - (i*gain+0x200))/0x400);
-		else
-			s_move[i] = ((((i+1)*gain-0x200) - (i*gain-0x200))/0x400);
-	}
+	for (i = 0; i <= 4; i++)
+		s_move[i] = gain;
 
 	/* Ring Damping Code */
 	for (i = 0; i <= 4; i++) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/gpio_axis.c linux-libre-2.6.34-gnu1/drivers/staging/dream/gpio_axis.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/gpio_axis.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/gpio_axis.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/gpio_event.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/gpio_event.c linux-libre-2.6.34-gnu1/drivers/staging/dream/gpio_event.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/gpio_event.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/gpio_event.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
  */
 
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/input.h>
 #include <linux/gpio_event.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/gpio_input.c linux-libre-2.6.34-gnu1/drivers/staging/dream/gpio_input.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/gpio_input.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/gpio_input.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/hrtimer.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 enum {
 	DEBOUNCE_UNSTABLE     = BIT(0),	/* Got irq, while debouncing */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/gpio_matrix.c linux-libre-2.6.34-gnu1/drivers/staging/dream/gpio_matrix.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/gpio_matrix.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/gpio_matrix.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/gpio_event.h>
 #include <linux/hrtimer.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/linux/android_pmem.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/linux/android_pmem.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/linux/android_pmem.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/linux/android_pmem.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,80 @@
+/* drivers/staging/dream/include/linux/android_pmem.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _ANDROID_PMEM_H_
+#define _ANDROID_PMEM_H_
+
+#define PMEM_IOCTL_MAGIC 'p'
+#define PMEM_GET_PHYS		_IOW(PMEM_IOCTL_MAGIC, 1, unsigned int)
+#define PMEM_MAP		_IOW(PMEM_IOCTL_MAGIC, 2, unsigned int)
+#define PMEM_GET_SIZE		_IOW(PMEM_IOCTL_MAGIC, 3, unsigned int)
+#define PMEM_UNMAP		_IOW(PMEM_IOCTL_MAGIC, 4, unsigned int)
+/* This ioctl will allocate pmem space, backing the file, it will fail
+ * if the file already has an allocation, pass it the len as the argument
+ * to the ioctl */
+#define PMEM_ALLOCATE		_IOW(PMEM_IOCTL_MAGIC, 5, unsigned int)
+/* This will connect a one pmem file to another, pass the file that is already
+ * backed in memory as the argument to the ioctl
+ */
+#define PMEM_CONNECT		_IOW(PMEM_IOCTL_MAGIC, 6, unsigned int)
+/* Returns the total size of the pmem region it is sent to as a pmem_region
+ * struct (with offset set to 0).
+ */
+#define PMEM_GET_TOTAL_SIZE	_IOW(PMEM_IOCTL_MAGIC, 7, unsigned int)
+/* Revokes gpu registers and resets the gpu.  Pass a pointer to the
+ * start of the mapped gpu regs (the vaddr returned by mmap) as the argument.
+ */
+#define HW3D_REVOKE_GPU		_IOW(PMEM_IOCTL_MAGIC, 8, unsigned int)
+#define HW3D_GRANT_GPU		_IOW(PMEM_IOCTL_MAGIC, 9, unsigned int)
+#define HW3D_WAIT_FOR_INTERRUPT	_IOW(PMEM_IOCTL_MAGIC, 10, unsigned int)
+
+int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
+		  unsigned long *end, struct file **filp);
+int get_pmem_user_addr(struct file *file, unsigned long *start,
+		       unsigned long *end);
+void put_pmem_file(struct file* file);
+void flush_pmem_file(struct file *file, unsigned long start, unsigned long len);
+
+struct android_pmem_platform_data
+{
+	const char* name;
+	/* starting physical address of memory region */
+	unsigned long start;
+	/* size of memory region */
+	unsigned long size;
+	/* set to indicate the region should not be managed with an allocator */
+	unsigned no_allocator;
+	/* set to indicate maps of this region should be cached, if a mix of
+	 * cached and uncached is desired, set this and open the device with
+	 * O_SYNC to get an uncached region */
+	unsigned cached;
+	/* The MSM7k has bits to enable a write buffer in the bus controller*/
+	unsigned buffered;
+};
+
+struct pmem_region {
+	unsigned long offset;
+	unsigned long len;
+};
+
+int pmem_setup(struct android_pmem_platform_data *pdata,
+	       long (*ioctl)(struct file *, unsigned int, unsigned long),
+	       int (*release)(struct inode *, struct file *));
+
+int pmem_remap(struct pmem_region *region, struct file *file,
+	       unsigned operation);
+
+#endif //_ANDROID_PPP_H_
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/linux/gpio_event.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/linux/gpio_event.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/linux/gpio_event.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/linux/gpio_event.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,154 @@
+/* drivers/staging/dream/include/linux/gpio_event.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_GPIO_EVENT_H
+#define _LINUX_GPIO_EVENT_H
+
+#include <linux/input.h>
+
+enum {
+	GPIO_EVENT_FUNC_UNINIT  = 0x0,
+	GPIO_EVENT_FUNC_INIT    = 0x1,
+	GPIO_EVENT_FUNC_SUSPEND = 0x2,
+	GPIO_EVENT_FUNC_RESUME  = 0x3,
+};
+struct gpio_event_info {
+	int (*func)(struct input_dev *input_dev,
+		    struct gpio_event_info *info,
+		    void **data, int func);
+	int (*event)(struct input_dev *input_dev,
+		     struct gpio_event_info *info,
+		     void **data, unsigned int type,
+		     unsigned int code, int value); /* out events */
+};
+
+struct gpio_event_platform_data {
+	const char *name;
+	struct gpio_event_info **info;
+	size_t info_count;
+	int (*power)(const struct gpio_event_platform_data *pdata, bool on);
+};
+
+#define GPIO_EVENT_DEV_NAME "gpio-event"
+
+/* Key matrix */
+
+enum gpio_event_matrix_flags {
+	/* unset: drive active output low, set: drive active output high */
+	GPIOKPF_ACTIVE_HIGH              = 1U << 0,
+	GPIOKPF_DEBOUNCE                 = 1U << 1,
+	GPIOKPF_REMOVE_SOME_PHANTOM_KEYS = 1U << 2,
+	GPIOKPF_REMOVE_PHANTOM_KEYS      = GPIOKPF_REMOVE_SOME_PHANTOM_KEYS |
+					   GPIOKPF_DEBOUNCE,
+	GPIOKPF_DRIVE_INACTIVE           = 1U << 3,
+	GPIOKPF_LEVEL_TRIGGERED_IRQ      = 1U << 4,
+	GPIOKPF_PRINT_UNMAPPED_KEYS      = 1U << 16,
+	GPIOKPF_PRINT_MAPPED_KEYS        = 1U << 17,
+	GPIOKPF_PRINT_PHANTOM_KEYS       = 1U << 18,
+};
+
+extern int gpio_event_matrix_func(struct input_dev *input_dev,
+			struct gpio_event_info *info, void **data, int func);
+struct gpio_event_matrix_info {
+	/* initialize to gpio_event_matrix_func */
+	struct gpio_event_info info;
+	/* size must be ninputs * noutputs */
+	const unsigned short *keymap;
+	unsigned int *input_gpios;
+	unsigned int *output_gpios;
+	unsigned int ninputs;
+	unsigned int noutputs;
+	/* time to wait before reading inputs after driving each output */
+	ktime_t settle_time;
+	/* time to wait before scanning the keypad a second time */
+	ktime_t debounce_delay;
+	ktime_t poll_time;
+	unsigned flags;
+};
+
+/* Directly connected inputs and outputs */
+
+enum gpio_event_direct_flags {
+	GPIOEDF_ACTIVE_HIGH         = 1U << 0,
+/*	GPIOEDF_USE_DOWN_IRQ        = 1U << 1, */
+/*	GPIOEDF_USE_IRQ             = (1U << 2) | GPIOIDF_USE_DOWN_IRQ, */
+	GPIOEDF_PRINT_KEYS          = 1U << 8,
+	GPIOEDF_PRINT_KEY_DEBOUNCE  = 1U << 9,
+};
+
+struct gpio_event_direct_entry {
+	uint32_t gpio:23;
+	uint32_t code:9;
+};
+
+/* inputs */
+extern int gpio_event_input_func(struct input_dev *input_dev,
+			struct gpio_event_info *info, void **data, int func);
+struct gpio_event_input_info {
+	/* initialize to gpio_event_input_func */
+	struct gpio_event_info info;
+	ktime_t debounce_time;
+	ktime_t poll_time;
+	uint16_t flags;
+	uint16_t type;
+	const struct gpio_event_direct_entry *keymap;
+	size_t keymap_size;
+};
+
+/* outputs */
+extern int gpio_event_output_func(struct input_dev *input_dev,
+			struct gpio_event_info *info, void **data, int func);
+extern int gpio_event_output_event(struct input_dev *input_dev,
+			struct gpio_event_info *info, void **data,
+			unsigned int type, unsigned int code, int value);
+struct gpio_event_output_info {
+	/* initialize to gpio_event_output_func and gpio_event_output_event */
+	struct gpio_event_info info;
+	uint16_t flags;
+	uint16_t type;
+	const struct gpio_event_direct_entry *keymap;
+	size_t keymap_size;
+};
+
+
+/* axes */
+
+enum gpio_event_axis_flags {
+	GPIOEAF_PRINT_UNKNOWN_DIRECTION  = 1U << 16,
+	GPIOEAF_PRINT_RAW                = 1U << 17,
+	GPIOEAF_PRINT_EVENT              = 1U << 18,
+};
+
+extern int gpio_event_axis_func(struct input_dev *input_dev,
+			struct gpio_event_info *info, void **data, int func);
+struct gpio_event_axis_info {
+	/* initialize to gpio_event_axis_func */
+	struct gpio_event_info info;
+	uint8_t  count;
+	uint8_t  type; /* EV_REL or EV_ABS */
+	uint16_t code;
+	uint16_t decoded_size;
+	uint16_t (*map)(struct gpio_event_axis_info *info, uint16_t in);
+	uint32_t *gpio;
+	uint32_t flags;
+};
+#define gpio_axis_2bit_gray_map gpio_axis_4bit_gray_map
+#define gpio_axis_3bit_gray_map gpio_axis_4bit_gray_map
+uint16_t gpio_axis_4bit_gray_map(
+			struct gpio_event_axis_info *info, uint16_t in);
+uint16_t gpio_axis_5bit_singletrack_map(
+			struct gpio_event_axis_info *info, uint16_t in);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/linux/msm_adsp.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/linux/msm_adsp.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/linux/msm_adsp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/linux/msm_adsp.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,84 @@
+/* drivers/staging/dream/include/linux/msm_adsp.h
+ *
+ * Copyright (c) QUALCOMM Incorporated
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Iliyan Malchev <ibm@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __LINUX_MSM_ADSP_H
+#define __LINUX_MSM_ADSP_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define ADSP_IOCTL_MAGIC 'q'
+
+/* ADSP_IOCTL_WRITE_COMMAND */
+struct adsp_command_t {
+	uint16_t queue;
+	uint32_t len;		/* bytes */
+	uint8_t *data;
+};
+
+/* ADSP_IOCTL_GET_EVENT */
+struct adsp_event_t {
+	uint16_t type;		/* 1 == event (RPC), 0 == message (adsp) */
+	uint32_t timeout_ms;	/* -1 for infinite, 0 for immediate return */
+	uint16_t msg_id;
+	uint16_t flags;		/* 1 == 16--bit event, 0 == 32-bit event */
+	uint32_t len;		/* size in, number of bytes out */
+	uint8_t *data;
+};
+
+#define ADSP_IOCTL_ENABLE \
+	_IOR(ADSP_IOCTL_MAGIC, 1, unsigned)
+
+#define ADSP_IOCTL_DISABLE \
+	_IOR(ADSP_IOCTL_MAGIC, 2, unsigned)
+
+#define ADSP_IOCTL_DISABLE_ACK \
+	_IOR(ADSP_IOCTL_MAGIC, 3, unsigned)
+
+#define ADSP_IOCTL_WRITE_COMMAND \
+	_IOR(ADSP_IOCTL_MAGIC, 4, struct adsp_command_t *)
+
+#define ADSP_IOCTL_GET_EVENT \
+	_IOWR(ADSP_IOCTL_MAGIC, 5, struct adsp_event_data_t *)
+
+#define ADSP_IOCTL_SET_CLKRATE \
+	_IOR(ADSP_IOCTL_MAGIC, 6, unsigned)
+
+#define ADSP_IOCTL_DISABLE_EVENT_RSP \
+	_IOR(ADSP_IOCTL_MAGIC, 10, unsigned)
+
+struct adsp_pmem_info {
+        int fd;
+        void *vaddr;
+};
+
+#define ADSP_IOCTL_REGISTER_PMEM \
+	_IOW(ADSP_IOCTL_MAGIC, 13, unsigned)
+
+#define ADSP_IOCTL_UNREGISTER_PMEM \
+	_IOW(ADSP_IOCTL_MAGIC, 14, unsigned)
+
+/* Cause any further GET_EVENT ioctls to fail (-ENODEV)
+ * until the device is closed and reopened.  Useful for
+ * terminating event dispatch threads
+ */
+#define ADSP_IOCTL_ABORT_EVENT_READ \
+	_IOW(ADSP_IOCTL_MAGIC, 15, unsigned)
+
+#define ADSP_IOCTL_LINK_TASK \
+	_IOW(ADSP_IOCTL_MAGIC, 16, unsigned)
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/linux/msm_audio.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/linux/msm_audio.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/linux/msm_audio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/linux/msm_audio.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,115 @@
+/* drivers/staging/dream/include/linux/msm_audio.h
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __LINUX_MSM_AUDIO_H
+#define __LINUX_MSM_AUDIO_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/sizes.h>
+
+/* PCM Audio */
+
+#define AUDIO_IOCTL_MAGIC 'a'
+
+#define AUDIO_START        _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned)
+#define AUDIO_STOP         _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned)
+#define AUDIO_FLUSH        _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned)
+#define AUDIO_GET_CONFIG   _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned)
+#define AUDIO_SET_CONFIG   _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned)
+#define AUDIO_GET_STATS    _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned)
+#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned)
+#define AUDIO_SET_ADRC     _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned)
+#define AUDIO_SET_EQ       _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned)
+#define AUDIO_SET_RX_IIR   _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned)
+#define AUDIO_SET_VOLUME   _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned)
+#define AUDIO_ENABLE_AUDPRE  _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned)
+#define AUDIO_SET_AGC        _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned)
+#define AUDIO_SET_NS         _IOW(AUDIO_IOCTL_MAGIC, 13, unsigned)
+#define AUDIO_SET_TX_IIR     _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned)
+#define AUDIO_PAUSE	     _IOW(AUDIO_IOCTL_MAGIC, 15, unsigned)
+#define AUDIO_GET_PCM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 30, unsigned)
+#define AUDIO_SET_PCM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 31, unsigned)
+#define AUDIO_SWITCH_DEVICE  _IOW(AUDIO_IOCTL_MAGIC, 32, unsigned)
+
+#define	AUDIO_MAX_COMMON_IOCTL_NUM	100
+
+#define	AUDIO_MAX_COMMON_IOCTL_NUM	100
+
+struct msm_audio_config {
+	uint32_t buffer_size;
+	uint32_t buffer_count;
+	uint32_t channel_count;
+	uint32_t sample_rate;
+	uint32_t type;
+	uint32_t unused[3];
+};
+
+struct msm_audio_stats {
+	uint32_t byte_count;
+	uint32_t sample_count;
+	uint32_t unused[2];
+};
+
+/* Audio routing */
+
+#define SND_IOCTL_MAGIC 's'
+
+#define SND_MUTE_UNMUTED 0
+#define SND_MUTE_MUTED   1
+
+struct msm_snd_device_config {
+	uint32_t device;
+	uint32_t ear_mute;
+	uint32_t mic_mute;
+};
+
+#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *)
+
+#define SND_METHOD_VOICE 0
+
+struct msm_snd_volume_config {
+	uint32_t device;
+	uint32_t method;
+	uint32_t volume;
+};
+
+#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *)
+
+/* Returns the number of SND endpoints supported. */
+
+#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *)
+
+struct msm_snd_endpoint {
+	int id; /* input and output */
+	char name[64]; /* output only */
+};
+
+/* Takes an index between 0 and one less than the number returned by
+ * SND_GET_NUM_ENDPOINTS, and returns the SND index and name of a
+ * SND endpoint.  On input, the .id field contains the number of the
+ * endpoint, and on exit it contains the SND index, while .name contains
+ * the description of the endpoint.
+ */
+
+#define SND_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_snd_endpoint *)
+
+struct msm_audio_pcm_config {
+	uint32_t pcm_feedback;	/* 0 - disable > 0 - enable */
+	uint32_t buffer_count;	/* Number of buffers to allocate */
+	uint32_t buffer_size;	/* Size of buffer for capturing of
+				   PCM samples */
+};
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/linux/msm_rpcrouter.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/linux/msm_rpcrouter.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/linux/msm_rpcrouter.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/linux/msm_rpcrouter.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,47 @@
+/* drivers/staging/dream/include/linux/msm_rpcrouter.h
+ *
+ * Copyright (c) QUALCOMM Incorporated
+ * Copyright (C) 2007 Google, Inc.
+ * Author: San Mehat <san@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __LINUX_MSM_RPCROUTER_H
+#define __LINUX_MSM_RPCROUTER_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define RPC_ROUTER_VERSION_V1 0x00010000
+
+struct rpcrouter_ioctl_server_args {
+	uint32_t prog;
+	uint32_t vers;
+};
+
+#define RPC_ROUTER_IOCTL_MAGIC (0xC1)
+
+#define RPC_ROUTER_IOCTL_GET_VERSION \
+	_IOR(RPC_ROUTER_IOCTL_MAGIC, 0, unsigned int)
+
+#define RPC_ROUTER_IOCTL_GET_MTU \
+	_IOR(RPC_ROUTER_IOCTL_MAGIC, 1, unsigned int)
+
+#define RPC_ROUTER_IOCTL_REGISTER_SERVER \
+	_IOWR(RPC_ROUTER_IOCTL_MAGIC, 2, unsigned int)
+
+#define RPC_ROUTER_IOCTL_UNREGISTER_SERVER \
+	_IOWR(RPC_ROUTER_IOCTL_MAGIC, 3, unsigned int)
+
+#define RPC_ROUTER_IOCTL_GET_MINOR_VERSION \
+	_IOW(RPC_ROUTER_IOCTL_MAGIC, 4, unsigned int)
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/linux/wakelock.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/linux/wakelock.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/linux/wakelock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/linux/wakelock.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,91 @@
+/* drivers/staging/dream/include/linux/wakelock.h
+ *
+ * Copyright (C) 2007-2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_WAKELOCK_H
+#define _LINUX_WAKELOCK_H
+
+#include <linux/list.h>
+#include <linux/ktime.h>
+
+/* A wake_lock prevents the system from entering suspend or other low power
+ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
+ * prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power
+ * states that cause large interrupt latencies or that disable a set of
+ * interrupts will not entered from idle until the wake_locks are released.
+ */
+
+enum {
+	WAKE_LOCK_SUSPEND, /* Prevent suspend */
+	WAKE_LOCK_IDLE,    /* Prevent low power idle */
+	WAKE_LOCK_TYPE_COUNT
+};
+
+struct wake_lock {
+#ifdef CONFIG_HAS_WAKELOCK
+	struct list_head    link;
+	int                 flags;
+	const char         *name;
+	unsigned long       expires;
+#ifdef CONFIG_WAKELOCK_STAT
+	struct {
+		int             count;
+		int             expire_count;
+		int             wakeup_count;
+		ktime_t         total_time;
+		ktime_t         prevent_suspend_time;
+		ktime_t         max_time;
+		ktime_t         last_time;
+	} stat;
+#endif
+#endif
+};
+
+#ifdef CONFIG_HAS_WAKELOCK
+
+void wake_lock_init(struct wake_lock *lock, int type, const char *name);
+void wake_lock_destroy(struct wake_lock *lock);
+void wake_lock(struct wake_lock *lock);
+void wake_lock_timeout(struct wake_lock *lock, long timeout);
+void wake_unlock(struct wake_lock *lock);
+
+/* wake_lock_active returns a non-zero value if the wake_lock is currently
+ * locked. If the wake_lock has a timeout, it does not check the timeout
+ * but if the timeout had aready been checked it will return 0.
+ */
+int wake_lock_active(struct wake_lock *lock);
+
+/* has_wake_lock returns 0 if no wake locks of the specified type are active,
+ * and non-zero if one or more wake locks are held. Specifically it returns
+ * -1 if one or more wake locks with no timeout are active or the
+ * number of jiffies until all active wake locks time out.
+ */
+long has_wake_lock(int type);
+
+#else
+
+static inline void wake_lock_init(struct wake_lock *lock, int type,
+					const char *name) {}
+static inline void wake_lock_destroy(struct wake_lock *lock) {}
+static inline void wake_lock(struct wake_lock *lock) {}
+static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) {}
+static inline void wake_unlock(struct wake_lock *lock) {}
+
+static inline int wake_lock_active(struct wake_lock *lock) { return 0; }
+static inline long has_wake_lock(int type) { return 0; }
+
+#endif
+
+#endif
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/camera.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/camera.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/camera.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/camera.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+
+#ifndef __ASM__ARCH_CAMERA_H
+#define __ASM__ARCH_CAMERA_H
+
+#include <linux/list.h>
+#include <linux/poll.h>
+#include <linux/cdev.h>
+#include <linux/platform_device.h>
+#include "linux/types.h"
+
+#include <mach/board.h>
+#include <media/msm_camera.h>
+
+#ifdef CONFIG_MSM_CAMERA_DEBUG
+#define CDBG(fmt, args...) printk(KERN_INFO "msm_camera: " fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+#define MSM_CAMERA_MSG 0
+#define MSM_CAMERA_EVT 1
+#define NUM_WB_EXP_NEUTRAL_REGION_LINES 4
+#define NUM_WB_EXP_STAT_OUTPUT_BUFFERS  3
+#define NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS 16
+#define NUM_AF_STAT_OUTPUT_BUFFERS      3
+
+enum msm_queue {
+	MSM_CAM_Q_CTRL,     /* control command or control command status */
+	MSM_CAM_Q_VFE_EVT,  /* adsp event */
+	MSM_CAM_Q_VFE_MSG,  /* adsp message */
+	MSM_CAM_Q_V4L2_REQ, /* v4l2 request */
+};
+
+enum vfe_resp_msg {
+	VFE_EVENT,
+	VFE_MSG_GENERAL,
+	VFE_MSG_SNAPSHOT,
+	VFE_MSG_OUTPUT1,
+	VFE_MSG_OUTPUT2,
+	VFE_MSG_STATS_AF,
+	VFE_MSG_STATS_WE,
+};
+
+struct msm_vfe_phy_info {
+	uint32_t sbuf_phy;
+	uint32_t y_phy;
+	uint32_t cbcr_phy;
+};
+
+struct msm_vfe_resp {
+	enum vfe_resp_msg type;
+	struct msm_vfe_evt_msg evt_msg;
+	struct msm_vfe_phy_info phy;
+	void    *extdata;
+	int32_t extlen;
+};
+
+struct msm_vfe_callback {
+	void (*vfe_resp)(struct msm_vfe_resp *,
+		enum msm_queue, void *syncdata);
+	void* (*vfe_alloc)(int, void *syncdata);
+};
+
+struct msm_camvfe_fn {
+	int (*vfe_init)(struct msm_vfe_callback *, struct platform_device *);
+	int (*vfe_enable)(struct camera_enable_cmd *);
+	int (*vfe_config)(struct msm_vfe_cfg_cmd *, void *);
+	int (*vfe_disable)(struct camera_enable_cmd *,
+		struct platform_device *dev);
+	void (*vfe_release)(struct platform_device *);
+};
+
+struct msm_sensor_ctrl {
+	int (*s_init)(const struct msm_camera_sensor_info *);
+	int (*s_release)(void);
+	int (*s_config)(void __user *);
+};
+
+struct msm_sync {
+	/* These two queues are accessed from a process context only. */
+	struct hlist_head frame; /* most-frequently accessed */
+	struct hlist_head stats;
+
+	/* The message queue is used by the control thread to send commands
+	 * to the config thread, and also by the DSP to send messages to the
+	 * config thread.  Thus it is the only queue that is accessed from
+	 * both interrupt and process context.
+	 */
+	spinlock_t msg_event_q_lock;
+	struct list_head msg_event_q;
+	wait_queue_head_t msg_event_wait;
+
+	/* This queue contains preview frames. It is accessed by the DSP (in
+	 * in interrupt context, and by the frame thread.
+	 */
+	spinlock_t prev_frame_q_lock;
+	struct list_head prev_frame_q;
+	wait_queue_head_t prev_frame_wait;
+	int unblock_poll_frame;
+
+	/* This queue contains snapshot frames.  It is accessed by the DSP (in
+	 * interrupt context, and by the control thread.
+	 */
+	spinlock_t pict_frame_q_lock;
+	struct list_head pict_frame_q;
+	wait_queue_head_t pict_frame_wait;
+
+	struct msm_camera_sensor_info *sdata;
+	struct msm_camvfe_fn vfefn;
+	struct msm_sensor_ctrl sctrl;
+	struct platform_device *pdev;
+	uint8_t opencnt;
+	void *cropinfo;
+	int  croplen;
+	unsigned pict_pp;
+
+	const char *apps_id;
+
+	struct mutex lock;
+	struct list_head list;
+};
+
+#define MSM_APPS_ID_V4L2 "msm_v4l2"
+#define MSM_APPS_ID_PROP "msm_qct"
+
+struct msm_device {
+	struct msm_sync *sync; /* most-frequently accessed */
+	struct device *device;
+	struct cdev cdev;
+	/* opened is meaningful only for the config and frame nodes,
+	 * which may be opened only once.
+	 */
+	atomic_t opened;
+};
+
+struct msm_control_device_queue {
+	spinlock_t ctrl_status_q_lock;
+	struct list_head ctrl_status_q;
+	wait_queue_head_t ctrl_status_wait;
+};
+
+struct msm_control_device {
+	struct msm_device *pmsm;
+
+	/* This queue used by the config thread to send responses back to the
+	 * control thread.  It is accessed only from a process context.
+	 */
+	struct msm_control_device_queue ctrl_q;
+};
+
+/* this structure is used in kernel */
+struct msm_queue_cmd {
+	struct list_head list;
+	enum msm_queue type;
+	void *command;
+};
+
+struct register_address_value_pair {
+	uint16_t register_address;
+	uint16_t register_value;
+};
+
+struct msm_pmem_region {
+	struct hlist_node list;
+	int type;
+	void *vaddr;
+	unsigned long paddr;
+	unsigned long len;
+	struct file *file;
+	uint32_t y_off;
+	uint32_t cbcr_off;
+	int fd;
+	uint8_t  active;
+};
+
+struct axidata {
+	uint32_t bufnum1;
+	uint32_t bufnum2;
+	struct msm_pmem_region *region;
+};
+
+#ifdef CONFIG_MSM_CAMERA_FLASH
+int msm_camera_flash_set_led_state(unsigned led_state);
+#else
+static inline int msm_camera_flash_set_led_state(unsigned led_state)
+{
+	return -ENOTSUPP;
+}
+#endif
+
+/* Below functions are added for V4L2 kernel APIs */
+struct msm_v4l2_driver {
+	struct msm_sync *sync;
+	int (*open)(struct msm_sync *, const char *apps_id);
+	int (*release)(struct msm_sync *);
+	int (*ctrl)(struct msm_sync *, struct msm_ctrl_cmd *);
+	int (*reg_pmem)(struct msm_sync *, struct msm_pmem_info *);
+	int (*get_frame) (struct msm_sync *, struct msm_frame *);
+	int (*put_frame) (struct msm_sync *, struct msm_frame *);
+	int (*get_pict) (struct msm_sync *, struct msm_ctrl_cmd *);
+	unsigned int (*drv_poll) (struct msm_sync *, struct file *,
+				struct poll_table_struct *);
+};
+
+int msm_v4l2_register(struct msm_v4l2_driver *);
+int msm_v4l2_unregister(struct msm_v4l2_driver *);
+
+void msm_camvfe_init(void);
+int msm_camvfe_check(void *);
+void msm_camvfe_fn_init(struct msm_camvfe_fn *, void *);
+int msm_camera_drv_start(struct platform_device *dev,
+		int (*sensor_probe)(const struct msm_camera_sensor_info *,
+					struct msm_sensor_ctrl *));
+
+enum msm_camio_clk_type {
+	CAMIO_VFE_MDC_CLK,
+	CAMIO_MDC_CLK,
+	CAMIO_VFE_CLK,
+	CAMIO_VFE_AXI_CLK,
+
+	CAMIO_MAX_CLK
+};
+
+enum msm_camio_clk_src_type {
+	MSM_CAMIO_CLK_SRC_INTERNAL,
+	MSM_CAMIO_CLK_SRC_EXTERNAL,
+	MSM_CAMIO_CLK_SRC_MAX
+};
+
+enum msm_s_test_mode {
+	S_TEST_OFF,
+	S_TEST_1,
+	S_TEST_2,
+	S_TEST_3
+};
+
+enum msm_s_resolution {
+	S_QTR_SIZE,
+	S_FULL_SIZE,
+	S_INVALID_SIZE
+};
+
+enum msm_s_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	S_REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	S_UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	S_UPDATE_ALL,
+	/* Not valid update */
+	S_UPDATE_INVALID
+};
+
+enum msm_s_setting {
+	S_RES_PREVIEW,
+	S_RES_CAPTURE
+};
+
+int msm_camio_enable(struct platform_device *dev);
+
+int  msm_camio_clk_enable(enum msm_camio_clk_type clk);
+int  msm_camio_clk_disable(enum msm_camio_clk_type clk);
+int  msm_camio_clk_config(uint32_t freq);
+void msm_camio_clk_rate_set(int rate);
+void msm_camio_clk_axi_rate_set(int rate);
+
+void msm_camio_camif_pad_reg_reset(void);
+void msm_camio_camif_pad_reg_reset_2(void);
+
+void msm_camio_vfe_blk_reset(void);
+
+void msm_camio_clk_sel(enum msm_camio_clk_src_type);
+void msm_camio_disable(struct platform_device *);
+int msm_camio_probe_on(struct platform_device *);
+int msm_camio_probe_off(struct platform_device *);
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/msm_adsp.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/msm_adsp.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/msm_adsp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/msm_adsp.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,112 @@
+/* include/asm-arm/arch-msm/msm_adsp.h
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM__ARCH_MSM_ADSP_H
+#define __ASM__ARCH_MSM_ADSP_H
+
+struct msm_adsp_module;
+
+struct msm_adsp_ops {
+	/* event is called from interrupt context when a message
+	 * arrives from the DSP.  Use the provided function pointer
+	 * to copy the message into a local buffer.  Do NOT call
+	 * it multiple times.
+	 */
+	void (*event)(void *driver_data, unsigned id, size_t len,
+		      void (*getevent)(void *ptr, size_t len));
+};
+
+/* Get, Put, Enable, and Disable are synchronous and must only
+ * be called from thread context.  Enable and Disable will block
+ * up to one second in the event of a fatal DSP error but are
+ * much faster otherwise.
+ */
+int msm_adsp_get(const char *name, struct msm_adsp_module **module,
+		 struct msm_adsp_ops *ops, void *driver_data);
+void msm_adsp_put(struct msm_adsp_module *module);
+int msm_adsp_enable(struct msm_adsp_module *module);
+int msm_adsp_disable(struct msm_adsp_module *module);
+int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate);
+
+/* Write is safe to call from interrupt context.
+ */
+int msm_adsp_write(struct msm_adsp_module *module,
+		   unsigned queue_id,
+		   void *data, size_t len);
+
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+/* Command Queue Indexes */
+#define QDSP_lpmCommandQueue              0
+#define QDSP_mpuAfeQueue                  1
+#define QDSP_mpuGraphicsCmdQueue          2
+#define QDSP_mpuModmathCmdQueue           3
+#define QDSP_mpuVDecCmdQueue              4
+#define QDSP_mpuVDecPktQueue              5
+#define QDSP_mpuVEncCmdQueue              6
+#define QDSP_rxMpuDecCmdQueue             7
+#define QDSP_rxMpuDecPktQueue             8
+#define QDSP_txMpuEncQueue                9
+#define QDSP_uPAudPPCmd1Queue             10
+#define QDSP_uPAudPPCmd2Queue             11
+#define QDSP_uPAudPPCmd3Queue             12
+#define QDSP_uPAudPlay0BitStreamCtrlQueue 13
+#define QDSP_uPAudPlay1BitStreamCtrlQueue 14
+#define QDSP_uPAudPlay2BitStreamCtrlQueue 15
+#define QDSP_uPAudPlay3BitStreamCtrlQueue 16
+#define QDSP_uPAudPlay4BitStreamCtrlQueue 17
+#define QDSP_uPAudPreProcCmdQueue         18
+#define QDSP_uPAudRecBitStreamQueue       19
+#define QDSP_uPAudRecCmdQueue             20
+#define QDSP_uPDiagQueue                  21
+#define QDSP_uPJpegActionCmdQueue         22
+#define QDSP_uPJpegCfgCmdQueue            23
+#define QDSP_uPVocProcQueue               24
+#define QDSP_vfeCommandQueue              25
+#define QDSP_vfeCommandScaleQueue         26
+#define QDSP_vfeCommandTableQueue         27
+#define QDSP_MAX_NUM_QUEUES               28
+#else
+/* Command Queue Indexes */
+#define QDSP_lpmCommandQueue              0
+#define QDSP_mpuAfeQueue                  1
+#define QDSP_mpuGraphicsCmdQueue          2
+#define QDSP_mpuModmathCmdQueue           3
+#define QDSP_mpuVDecCmdQueue              4
+#define QDSP_mpuVDecPktQueue              5
+#define QDSP_mpuVEncCmdQueue              6
+#define QDSP_rxMpuDecCmdQueue             7
+#define QDSP_rxMpuDecPktQueue             8
+#define QDSP_txMpuEncQueue                9
+#define QDSP_uPAudPPCmd1Queue             10
+#define QDSP_uPAudPPCmd2Queue             11
+#define QDSP_uPAudPPCmd3Queue             12
+#define QDSP_uPAudPlay0BitStreamCtrlQueue 13
+#define QDSP_uPAudPlay1BitStreamCtrlQueue 14
+#define QDSP_uPAudPlay2BitStreamCtrlQueue 15
+#define QDSP_uPAudPlay3BitStreamCtrlQueue 16
+#define QDSP_uPAudPlay4BitStreamCtrlQueue 17
+#define QDSP_uPAudPreProcCmdQueue         18
+#define QDSP_uPAudRecBitStreamQueue       19
+#define QDSP_uPAudRecCmdQueue             20
+#define QDSP_uPJpegActionCmdQueue         21
+#define QDSP_uPJpegCfgCmdQueue            22
+#define QDSP_uPVocProcQueue               23
+#define QDSP_vfeCommandQueue              24
+#define QDSP_vfeCommandScaleQueue         25
+#define QDSP_vfeCommandTableQueue         26
+#define QDSP_QUEUE_MAX                    26
+#endif
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/msm_rpcrouter.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/msm_rpcrouter.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/msm_rpcrouter.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/msm_rpcrouter.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,179 @@
+/** include/asm-arm/arch-msm/msm_rpcrouter.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007-2009 QUALCOMM Incorporated
+ * Author: San Mehat <san@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM__ARCH_MSM_RPCROUTER_H
+#define __ASM__ARCH_MSM_RPCROUTER_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+/* RPC API version structure
+ * Version bit 31 : 1->hashkey versioning,
+ *                  0->major-minor (backward compatible) versioning
+ * hashkey versioning:
+ *   Version bits 31-0 hashkey
+ * major-minor (backward compatible) versioning
+ *   Version bits 30-28 reserved (no match)
+ *   Version bits 27-16 major (must match)
+ *   Version bits 15-0  minor (greater or equal)
+ */
+#define RPC_VERSION_MODE_MASK  0x80000000
+#define RPC_VERSION_MAJOR_MASK 0x0fff0000
+#define RPC_VERSION_MAJOR_OFFSET 16
+#define RPC_VERSION_MINOR_MASK 0x0000ffff
+
+#define MSM_RPC_VERS(major, minor)					\
+	((uint32_t)((((major) << RPC_VERSION_MAJOR_OFFSET) &		\
+		RPC_VERSION_MAJOR_MASK) |				\
+	((minor) & RPC_VERSION_MINOR_MASK)))
+#define MSM_RPC_GET_MAJOR(vers) (((vers) & RPC_VERSION_MAJOR_MASK) >>	\
+					RPC_VERSION_MAJOR_OFFSET)
+#define MSM_RPC_GET_MINOR(vers) ((vers) & RPC_VERSION_MINOR_MASK)
+#else
+#define MSM_RPC_VERS(major, minor) (major)
+#define MSM_RPC_GET_MAJOR(vers) (vers)
+#define MSM_RPC_GET_MINOR(vers) 0
+#endif
+
+struct msm_rpc_endpoint;
+
+struct rpcsvr_platform_device
+{
+	struct platform_device base;
+	uint32_t prog;
+	uint32_t vers;
+};
+
+#define RPC_DATA_IN	0
+/*
+ * Structures for sending / receiving direct RPC requests
+ * XXX: Any cred/verif lengths > 0 not supported
+ */
+
+struct rpc_request_hdr
+{
+	uint32_t xid;
+	uint32_t type;	/* 0 */
+	uint32_t rpc_vers; /* 2 */
+	uint32_t prog;
+	uint32_t vers;
+	uint32_t procedure;
+	uint32_t cred_flavor;
+	uint32_t cred_length;
+	uint32_t verf_flavor;
+	uint32_t verf_length;
+};
+
+typedef struct
+{
+	uint32_t low;
+	uint32_t high;
+} rpc_reply_progmismatch_data;
+
+typedef struct
+{
+} rpc_denied_reply_hdr;
+
+typedef struct
+{
+	uint32_t verf_flavor;
+	uint32_t verf_length;
+	uint32_t accept_stat;
+#define RPC_ACCEPTSTAT_SUCCESS 0
+#define RPC_ACCEPTSTAT_PROG_UNAVAIL 1
+#define RPC_ACCEPTSTAT_PROG_MISMATCH 2
+#define RPC_ACCEPTSTAT_PROC_UNAVAIL 3
+#define RPC_ACCEPTSTAT_GARBAGE_ARGS 4
+#define RPC_ACCEPTSTAT_SYSTEM_ERR 5
+#define RPC_ACCEPTSTAT_PROG_LOCKED 6
+	/*
+	 * Following data is dependant on accept_stat
+	 * If ACCEPTSTAT == PROG_MISMATCH then there is a
+	 * 'rpc_reply_progmismatch_data' structure following the header.
+	 * Otherwise the data is procedure specific
+	 */
+} rpc_accepted_reply_hdr;
+
+struct rpc_reply_hdr
+{
+	uint32_t xid;
+	uint32_t type;
+	uint32_t reply_stat;
+#define RPCMSG_REPLYSTAT_ACCEPTED 0
+#define RPCMSG_REPLYSTAT_DENIED 1
+	union {
+		rpc_accepted_reply_hdr acc_hdr;
+		rpc_denied_reply_hdr dny_hdr;
+	} data;
+};
+
+/* flags for msm_rpc_connect() */
+#define MSM_RPC_UNINTERRUPTIBLE 0x0001
+
+/* use IS_ERR() to check for failure */
+struct msm_rpc_endpoint *msm_rpc_open(void);
+/* Connect with the specified server version */
+struct msm_rpc_endpoint *msm_rpc_connect(uint32_t prog, uint32_t vers, unsigned flags);
+uint32_t msm_rpc_get_vers(struct msm_rpc_endpoint *ept);
+/* check if server version can handle client requested version */
+int msm_rpc_is_compatible_version(uint32_t server_version,
+				  uint32_t client_version);
+
+int msm_rpc_close(struct msm_rpc_endpoint *ept);
+int msm_rpc_write(struct msm_rpc_endpoint *ept,
+		  void *data, int len);
+int msm_rpc_read(struct msm_rpc_endpoint *ept,
+		 void **data, unsigned len, long timeout);
+void msm_rpc_setup_req(struct rpc_request_hdr *hdr,
+		       uint32_t prog, uint32_t vers, uint32_t proc);
+int msm_rpc_register_server(struct msm_rpc_endpoint *ept,
+			    uint32_t prog, uint32_t vers);
+int msm_rpc_unregister_server(struct msm_rpc_endpoint *ept,
+			      uint32_t prog, uint32_t vers);
+
+/* simple blocking rpc call
+ *
+ * request is mandatory and must have a rpc_request_hdr
+ * at the start.  The header will be filled out for you.
+ *
+ * reply provides a buffer for replies of reply_max_size
+ */
+int msm_rpc_call_reply(struct msm_rpc_endpoint *ept, uint32_t proc,
+		       void *request, int request_size,
+		       void *reply, int reply_max_size,
+		       long timeout);
+int msm_rpc_call(struct msm_rpc_endpoint *ept, uint32_t proc,
+		 void *request, int request_size,
+		 long timeout);
+
+struct msm_rpc_server
+{
+	struct list_head list;
+	uint32_t flags;
+
+	uint32_t prog;
+	uint32_t vers;
+
+	int (*rpc_call)(struct msm_rpc_server *server,
+			struct rpc_request_hdr *req, unsigned len);
+};
+
+int msm_rpc_create_server(struct msm_rpc_server *server);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/msm_smd.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/msm_smd.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/msm_smd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/msm_smd.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,107 @@
+/* linux/include/asm-arm/arch-msm/msm_smd.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_SMD_H
+#define __ASM_ARCH_MSM_SMD_H
+
+typedef struct smd_channel smd_channel_t;
+
+/* warning: notify() may be called before open returns */
+int smd_open(const char *name, smd_channel_t **ch, void *priv,
+	     void (*notify)(void *priv, unsigned event));
+
+#define SMD_EVENT_DATA 1
+#define SMD_EVENT_OPEN 2
+#define SMD_EVENT_CLOSE 3
+
+int smd_close(smd_channel_t *ch);
+
+/* passing a null pointer for data reads and discards */
+int smd_read(smd_channel_t *ch, void *data, int len);
+
+/* Write to stream channels may do a partial write and return
+** the length actually written.
+** Write to packet channels will never do a partial write --
+** it will return the requested length written or an error.
+*/
+int smd_write(smd_channel_t *ch, const void *data, int len);
+
+int smd_write_avail(smd_channel_t *ch);
+int smd_read_avail(smd_channel_t *ch);
+
+/* Returns the total size of the current packet being read.
+** Returns 0 if no packets available or a stream channel.
+*/
+int smd_cur_packet_size(smd_channel_t *ch);
+
+/* used for tty unthrottling and the like -- causes the notify()
+** callback to be called from the same lock context as is used
+** when it is called from channel updates
+*/
+void smd_kick(smd_channel_t *ch);
+
+
+#if 0
+/* these are interruptable waits which will block you until the specified
+** number of bytes are readable or writable.
+*/
+int smd_wait_until_readable(smd_channel_t *ch, int bytes);
+int smd_wait_until_writable(smd_channel_t *ch, int bytes);
+#endif
+
+typedef enum
+{
+	SMD_PORT_DS = 0,
+	SMD_PORT_DIAG,
+	SMD_PORT_RPC_CALL,
+	SMD_PORT_RPC_REPLY,
+	SMD_PORT_BT,
+	SMD_PORT_CONTROL,
+	SMD_PORT_MEMCPY_SPARE1,
+	SMD_PORT_DATA1,
+	SMD_PORT_DATA2,
+	SMD_PORT_DATA3,
+	SMD_PORT_DATA4,
+	SMD_PORT_DATA5,
+	SMD_PORT_DATA6,
+	SMD_PORT_DATA7,
+	SMD_PORT_DATA8,
+	SMD_PORT_DATA9,
+	SMD_PORT_DATA10,
+	SMD_PORT_DATA11,
+	SMD_PORT_DATA12,
+	SMD_PORT_DATA13,
+	SMD_PORT_DATA14,
+	SMD_PORT_DATA15,
+	SMD_PORT_DATA16,
+	SMD_PORT_DATA17,
+	SMD_PORT_DATA18,
+	SMD_PORT_DATA19,
+	SMD_PORT_DATA20,
+	SMD_PORT_GPS_NMEA,
+	SMD_PORT_BRIDGE_1,
+	SMD_PORT_BRIDGE_2,
+	SMD_PORT_BRIDGE_3,
+	SMD_PORT_BRIDGE_4,
+	SMD_PORT_BRIDGE_5,
+	SMD_PORT_LOOPBACK,
+	SMD_PORT_CS_APPS_MODEM,
+	SMD_PORT_CS_APPS_DSP,
+	SMD_PORT_CS_MODEM_DSP,
+	SMD_NUM_PORTS,
+} smd_port_id_type;
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,94 @@
+#ifndef QDSP5AUDPLAYCMDI_H
+#define QDSP5AUDPLAYCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+       Q D S P 5  A U D I O   P L A Y  T A S K   C O M M A N D S
+
+GENERAL DESCRIPTION
+  Command Interface for AUDPLAYTASK on QDSP5
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+
+  audplay_cmd_dec_data_avail
+    Send buffer to AUDPLAY task
+
+
+Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaycmdi.h#2 $
+
+===========================================================================*/
+
+#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL		0x0000
+#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_LEN	\
+	sizeof(audplay_cmd_bitstream_data_avail)
+
+/* Type specification of dec_data_avail message sent to AUDPLAYTASK
+*/
+typedef struct {
+	/*command ID*/
+	unsigned int cmd_id;
+
+	/* Decoder ID for which message is being sent */
+	unsigned int decoder_id;
+
+	/* Start address of data in ARM global memory */
+	unsigned int buf_ptr;
+
+	/* Number of 16-bit words of bit-stream data contiguously available at the
+	 * above-mentioned address. */
+	unsigned int buf_size;
+
+	/* Partition number used by audPlayTask to communicate with DSP's RTOS
+	 * kernel */
+	unsigned int partition_number;
+} __attribute__((packed)) audplay_cmd_bitstream_data_avail;
+
+#define AUDPLAY_CMD_HPCM_BUF_CFG 0x0003
+#define AUDPLAY_CMD_HPCM_BUF_CFG_LEN \
+	sizeof(struct audplay_cmd_hpcm_buf_cfg)
+
+struct audplay_cmd_hpcm_buf_cfg {
+	unsigned int cmd_id;
+	unsigned int hostpcm_config;
+	unsigned int feedback_frequency;
+	unsigned int byte_swap;
+	unsigned int max_buffers;
+	unsigned int partition_number;
+} __attribute__((packed));
+
+#define AUDPLAY_CMD_BUFFER_REFRESH 0x0004
+#define AUDPLAY_CMD_BUFFER_REFRESH_LEN \
+	sizeof(struct audplay_cmd_buffer_update)
+
+struct audplay_cmd_buffer_refresh {
+	unsigned int cmd_id;
+	unsigned int num_buffers;
+	unsigned int buf_read_count;
+	unsigned int buf0_address;
+	unsigned int buf0_length;
+	unsigned int buf1_address;
+	unsigned int buf1_length;
+} __attribute__((packed));
+#endif /* QDSP5AUDPLAYCMD_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,70 @@
+#ifndef QDSP5AUDPLAYMSG_H
+#define QDSP5AUDPLAYMSG_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+       Q D S P 5  A U D I O   P L A Y  T A S K   M S G
+
+GENERAL DESCRIPTION
+  Message sent by AUDPLAY task
+
+REFERENCES
+  None
+
+
+Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaymsg.h#3 $
+
+===========================================================================*/
+#define AUDPLAY_MSG_DEC_NEEDS_DATA		0x0001
+#define AUDPLAY_MSG_DEC_NEEDS_DATA_MSG_LEN	\
+	sizeof(audplay_msg_dec_needs_data)
+
+typedef struct{
+	/* reserved*/
+	unsigned int dec_id;
+
+	/* The read pointer offset of external memory until which the
+	 * bitstream has been DMAed in. */
+	unsigned int adecDataReadPtrOffset;
+
+	/* The buffer size of external memory. */
+	unsigned int adecDataBufSize;
+
+	unsigned int bitstream_free_len;
+	unsigned int bitstream_write_ptr;
+	unsigned int bitstarem_buf_start;
+	unsigned int bitstream_buf_len;
+} __attribute__((packed)) audplay_msg_dec_needs_data;
+
+#define AUDPLAY_MSG_BUFFER_UPDATE 0x0004
+#define AUDPLAY_MSG_BUFFER_UPDATE_LEN \
+	sizeof(struct audplay_msg_buffer_update)
+
+struct audplay_msg_buffer_update {
+	unsigned int buffer_write_count;
+	unsigned int num_of_buffer;
+	unsigned int buf0_address;
+	unsigned int buf0_length;
+	unsigned int buf1_address;
+	unsigned int buf1_length;
+} __attribute__((packed));
+#endif /* QDSP5AUDPLAYMSG_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,914 @@
+#ifndef QDSP5AUDPPCMDI_H
+#define QDSP5AUDPPCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+    A U D I O   P O S T   P R O C E S S I N G  I N T E R N A L  C O M M A N D S
+
+GENERAL DESCRIPTION
+  This file contains defintions of format blocks of commands
+  that are accepted by AUDPP Task
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+  None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppcmdi.h#2 $
+
+===========================================================================*/
+
+/*
+ * ARM to AUDPPTASK Commands
+ *
+ * ARM uses three command queues to communicate with AUDPPTASK
+ * 1)uPAudPPCmd1Queue : Used for more frequent and shorter length commands
+ * 	Location : MEMA
+ * 	Buffer Size : 6 words
+ * 	No of buffers in a queue : 20 for gaming audio and 5 for other images
+ * 2)uPAudPPCmd2Queue : Used for commands which are not much lengthier
+ * 	Location : MEMA
+ * 	Buffer Size : 23
+ * 	No of buffers in a queue : 2
+ * 3)uPAudOOCmd3Queue : Used for lengthier and more frequent commands
+ * 	Location : MEMA
+ * 	Buffer Size : 145
+ * 	No of buffers in a queue : 3
+ */
+
+/*
+ * Commands Related to uPAudPPCmd1Queue
+ */
+
+/*
+ * Command Structure to enable or disable the active decoders
+ */
+
+#define AUDPP_CMD_CFG_DEC_TYPE 		0x0001
+#define AUDPP_CMD_CFG_DEC_TYPE_LEN 	sizeof(audpp_cmd_cfg_dec_type)
+
+/* Enable the decoder */
+#define AUDPP_CMD_DEC_TYPE_M           	0x000F
+
+#define AUDPP_CMD_ENA_DEC_V         	0x4000
+#define AUDPP_CMD_DIS_DEC_V        	0x0000
+#define AUDPP_CMD_DEC_STATE_M          	0x4000
+
+#define AUDPP_CMD_UPDATDE_CFG_DEC	0x8000
+#define AUDPP_CMD_DONT_UPDATE_CFG_DEC	0x0000
+
+
+/* Type specification of cmd_cfg_dec */
+
+typedef struct {
+	unsigned short cmd_id;
+	unsigned short dec0_cfg;
+	unsigned short dec1_cfg;
+	unsigned short dec2_cfg;
+	unsigned short dec3_cfg;
+	unsigned short dec4_cfg;
+} __attribute__((packed)) audpp_cmd_cfg_dec_type;
+
+/*
+ * Command Structure to Pause , Resume and flushes the selected audio decoders
+ */
+
+#define AUDPP_CMD_DEC_CTRL		0x0002
+#define AUDPP_CMD_DEC_CTRL_LEN		sizeof(audpp_cmd_dec_ctrl)
+
+/* Decoder control commands for pause, resume and flush */
+#define AUDPP_CMD_FLUSH_V         		0x2000
+
+#define AUDPP_CMD_PAUSE_V		        0x4000
+#define AUDPP_CMD_RESUME_V		        0x0000
+
+#define AUDPP_CMD_UPDATE_V		        0x8000
+#define AUDPP_CMD_IGNORE_V		        0x0000
+
+
+/* Type Spec for decoder control command*/
+
+typedef struct {
+	unsigned short cmd_id;
+	unsigned short dec0_ctrl;
+	unsigned short dec1_ctrl;
+	unsigned short dec2_ctrl;
+	unsigned short dec3_ctrl;
+	unsigned short dec4_ctrl;
+} __attribute__((packed)) audpp_cmd_dec_ctrl;
+
+/*
+ * Command Structure to Configure the AVSync FeedBack Mechanism
+ */
+
+#define AUDPP_CMD_AVSYNC	0x0003
+#define AUDPP_CMD_AVSYNC_LEN	sizeof(audpp_cmd_avsync)
+
+typedef struct {
+	unsigned short cmd_id;
+	unsigned short object_number;
+	unsigned short interrupt_interval_lsw;
+	unsigned short interrupt_interval_msw;
+} __attribute__((packed)) audpp_cmd_avsync;
+
+/*
+ * Command Structure to enable or disable(sleep) the   AUDPPTASK
+ */
+
+#define AUDPP_CMD_CFG	0x0004
+#define AUDPP_CMD_CFG_LEN	sizeof(audpp_cmd_cfg)
+
+#define AUDPP_CMD_CFG_SLEEP   				0x0000
+#define AUDPP_CMD_CFG_ENABLE  				0xFFFF
+
+typedef struct {
+	unsigned short cmd_id;
+	unsigned short cfg;
+} __attribute__((packed)) audpp_cmd_cfg;
+
+/*
+ * Command Structure to Inject or drop the specified no of samples
+ */
+
+#define AUDPP_CMD_ADJUST_SAMP		0x0005
+#define AUDPP_CMD_ADJUST_SAMP_LEN	sizeof(audpp_cmd_adjust_samp)
+
+#define AUDPP_CMD_SAMP_DROP		-1
+#define AUDPP_CMD_SAMP_INSERT		0x0001
+
+#define AUDPP_CMD_NUM_SAMPLES		0x0001
+
+typedef struct {
+	unsigned short cmd_id;
+	unsigned short object_no;
+	signed short sample_insert_or_drop;
+	unsigned short num_samples;
+} __attribute__((packed)) audpp_cmd_adjust_samp;
+
+/*
+ * Command Structure to Configure AVSync Feedback Mechanism
+ */
+
+#define AUDPP_CMD_AVSYNC_CMD_2		0x0006
+#define AUDPP_CMD_AVSYNC_CMD_2_LEN	sizeof(audpp_cmd_avsync_cmd_2)
+
+typedef struct {
+	unsigned short cmd_id;
+	unsigned short object_number;
+	unsigned short interrupt_interval_lsw;
+	unsigned short interrupt_interval_msw;
+	unsigned short sample_counter_dlsw;
+	unsigned short sample_counter_dmsw;
+	unsigned short sample_counter_msw;
+	unsigned short byte_counter_dlsw;
+	unsigned short byte_counter_dmsw;
+	unsigned short byte_counter_msw;
+} __attribute__((packed)) audpp_cmd_avsync_cmd_2;
+
+/*
+ * Command Structure to Configure AVSync Feedback Mechanism
+ */
+
+#define AUDPP_CMD_AVSYNC_CMD_3		0x0007
+#define AUDPP_CMD_AVSYNC_CMD_3_LEN	sizeof(audpp_cmd_avsync_cmd_3)
+
+typedef struct {
+	unsigned short cmd_id;
+	unsigned short object_number;
+	unsigned short interrupt_interval_lsw;
+	unsigned short interrupt_interval_msw;
+	unsigned short sample_counter_dlsw;
+	unsigned short sample_counter_dmsw;
+	unsigned short sample_counter_msw;
+	unsigned short byte_counter_dlsw;
+	unsigned short byte_counter_dmsw;
+	unsigned short byte_counter_msw;
+} __attribute__((packed)) audpp_cmd_avsync_cmd_3;
+
+#define AUDPP_CMD_ROUTING_MODE      0x0008
+#define AUDPP_CMD_ROUTING_MODE_LEN  \
+sizeof(struct audpp_cmd_routing_mode)
+
+struct audpp_cmd_routing_mode {
+	unsigned short cmd_id;
+	unsigned short object_number;
+	unsigned short routing_mode;
+} __attribute__((packed));
+
+/*
+ * Commands Related to uPAudPPCmd2Queue
+ */
+
+/*
+ * Command Structure to configure Per decoder Parameters (Common)
+ */
+
+#define AUDPP_CMD_CFG_ADEC_PARAMS 		0x0000
+#define AUDPP_CMD_CFG_ADEC_PARAMS_COMMON_LEN	\
+	sizeof(audpp_cmd_cfg_adec_params_common)
+
+#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_FCM	0x4000
+#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_FCM	0x0000
+
+#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_DCM	0x8000
+#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_DCM	0x0000
+
+/* Sampling frequency*/
+#define  AUDPP_CMD_SAMP_RATE_96000 	0x0000
+#define  AUDPP_CMD_SAMP_RATE_88200 	0x0001
+#define  AUDPP_CMD_SAMP_RATE_64000 	0x0002
+#define  AUDPP_CMD_SAMP_RATE_48000 	0x0003
+#define  AUDPP_CMD_SAMP_RATE_44100 	0x0004
+#define  AUDPP_CMD_SAMP_RATE_32000 	0x0005
+#define  AUDPP_CMD_SAMP_RATE_24000 	0x0006
+#define  AUDPP_CMD_SAMP_RATE_22050 	0x0007
+#define  AUDPP_CMD_SAMP_RATE_16000 	0x0008
+#define  AUDPP_CMD_SAMP_RATE_12000 	0x0009
+#define  AUDPP_CMD_SAMP_RATE_11025 	0x000A
+#define  AUDPP_CMD_SAMP_RATE_8000  	0x000B
+
+
+/*
+ * Type specification of cmd_adec_cfg sent to all decoder
+ */
+
+typedef struct {
+  unsigned short cmd_id;
+  unsigned short  length;
+  unsigned short  dec_id;
+  unsigned short  status_msg_flag;
+  unsigned short  decoder_frame_counter_msg_period;
+  unsigned short  input_sampling_frequency;
+} __attribute__((packed)) audpp_cmd_cfg_adec_params_common;
+
+/*
+ * Command Structure to configure Per decoder Parameters (Wav)
+ */
+
+#define AUDPP_CMD_CFG_ADEC_PARAMS_WAV_LEN	\
+	sizeof(audpp_cmd_cfg_adec_params_wav)
+
+
+#define AUDPP_CMD_WAV_STEREO_CFG_MONO	0x0001
+#define AUDPP_CMD_WAV_STEREO_CFG_STEREO	0x0002
+
+#define AUDPP_CMD_WAV_PCM_WIDTH_8	0x0000
+#define AUDPP_CMD_WAV_PCM_WIDTH_16	0x0001
+#define AUDPP_CMD_WAV_PCM_WIDTH_32	0x0002
+
+typedef struct {
+	audpp_cmd_cfg_adec_params_common		common;
+	unsigned short					stereo_cfg;
+	unsigned short					pcm_width;
+	unsigned short 					sign;
+} __attribute__((packed)) audpp_cmd_cfg_adec_params_wav;
+
+/*
+ * Command Structure to configure Per decoder Parameters (ADPCM)
+ */
+
+#define AUDPP_CMD_CFG_ADEC_PARAMS_ADPCM_LEN	\
+	sizeof(audpp_cmd_cfg_adec_params_adpcm)
+
+
+#define	AUDPP_CMD_ADPCM_STEREO_CFG_MONO		0x0001
+#define AUDPP_CMD_ADPCM_STEREO_CFG_STEREO	0x0002
+
+typedef struct {
+	audpp_cmd_cfg_adec_params_common		common;
+	unsigned short					stereo_cfg;
+	unsigned short 					block_size;
+} __attribute__((packed)) audpp_cmd_cfg_adec_params_adpcm;
+
+/*
+ * Command Structure to configure Per decoder Parameters (MP3)
+ */
+
+#define AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN	\
+	sizeof(audpp_cmd_cfg_adec_params_mp3)
+
+typedef struct {
+   audpp_cmd_cfg_adec_params_common    common;
+} __attribute__((packed)) audpp_cmd_cfg_adec_params_mp3;
+
+
+/*
+ * Command Structure to configure Per decoder Parameters (AAC)
+ */
+
+#define AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN	\
+	sizeof(audpp_cmd_cfg_adec_params_aac)
+
+
+#define AUDPP_CMD_AAC_FORMAT_ADTS		-1
+#define	AUDPP_CMD_AAC_FORMAT_RAW		0x0000
+#define	AUDPP_CMD_AAC_FORMAT_PSUEDO_RAW		0x0001
+#define	AUDPP_CMD_AAC_FORMAT_LOAS		0x0002
+
+#define AUDPP_CMD_AAC_AUDIO_OBJECT_LC		0x0002
+#define AUDPP_CMD_AAC_AUDIO_OBJECT_LTP		0x0004
+#define AUDPP_CMD_AAC_AUDIO_OBJECT_ERLC	0x0011
+
+#define AUDPP_CMD_AAC_SBR_ON_FLAG_ON		0x0001
+#define AUDPP_CMD_AAC_SBR_ON_FLAG_OFF		0x0000
+
+#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_ON		0x0001
+#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_OFF	0x0000
+
+typedef struct {
+  audpp_cmd_cfg_adec_params_common	common;
+  signed short				format;
+  unsigned short			audio_object;
+  unsigned short			ep_config;
+  unsigned short                        aac_section_data_resilience_flag;
+  unsigned short                        aac_scalefactor_data_resilience_flag;
+  unsigned short                        aac_spectral_data_resilience_flag;
+  unsigned short                        sbr_on_flag;
+  unsigned short                        sbr_ps_on_flag;
+  unsigned short                        dual_mono_mode;
+  unsigned short                        channel_configuration;
+} __attribute__((packed)) audpp_cmd_cfg_adec_params_aac;
+
+/*
+ * Command Structure to configure Per decoder Parameters (V13K)
+ */
+
+#define AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN	\
+	sizeof(struct audpp_cmd_cfg_adec_params_v13k)
+
+
+#define AUDPP_CMD_STEREO_CFG_MONO		0x0001
+#define AUDPP_CMD_STEREO_CFG_STEREO		0x0002
+
+struct audpp_cmd_cfg_adec_params_v13k {
+   audpp_cmd_cfg_adec_params_common    	common;
+   unsigned short			stereo_cfg;
+} __attribute__((packed));
+
+#define AUDPP_CMD_CFG_ADEC_PARAMS_EVRC_LEN \
+	sizeof(struct audpp_cmd_cfg_adec_params_evrc)
+
+struct audpp_cmd_cfg_adec_params_evrc {
+	audpp_cmd_cfg_adec_params_common common;
+	unsigned short stereo_cfg;
+} __attribute__ ((packed));
+
+/*
+ * Command Structure to configure the  HOST PCM interface
+ */
+
+#define AUDPP_CMD_PCM_INTF	0x0001
+#define AUDPP_CMD_PCM_INTF_2	0x0002
+#define AUDPP_CMD_PCM_INTF_LEN	sizeof(audpp_cmd_pcm_intf)
+
+#define AUDPP_CMD_PCM_INTF_MONO_V		        0x0001
+#define AUDPP_CMD_PCM_INTF_STEREO_V         	0x0002
+
+/* These two values differentiate the two types of commands that could be issued
+ * Interface configuration command and Buffer update command */
+
+#define AUDPP_CMD_PCM_INTF_CONFIG_CMD_V	       	0x0000
+#define AUDPP_CMD_PCM_INTF_BUFFER_CMD_V	        -1
+
+#define AUDPP_CMD_PCM_INTF_RX_ENA_M              0x000F
+#define AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V     0x0008
+#define AUDPP_CMD_PCM_INTF_RX_ENA_DSPTOARM_V     0x0004
+
+/* These flags control the enabling and disabling of the interface together
+ *  with host interface bit mask. */
+
+#define AUDPP_CMD_PCM_INTF_ENA_V            -1
+#define AUDPP_CMD_PCM_INTF_DIS_V            0x0000
+
+
+#define  AUDPP_CMD_PCM_INTF_FULL_DUPLEX           0x0
+#define  AUDPP_CMD_PCM_INTF_HALF_DUPLEX_TODSP     0x1
+
+
+#define  AUDPP_CMD_PCM_INTF_OBJECT_NUM           0x5
+#define  AUDPP_CMD_PCM_INTF_COMMON_OBJECT_NUM    0x6
+
+
+typedef struct {
+	unsigned short  cmd_id;
+	unsigned short  object_num;
+	signed short  config;
+	unsigned short  intf_type;
+
+	/* DSP -> ARM Configuration */
+	unsigned short  read_buf1LSW;
+	unsigned short  read_buf1MSW;
+	unsigned short  read_buf1_len;
+
+	unsigned short  read_buf2LSW;
+	unsigned short  read_buf2MSW;
+	unsigned short  read_buf2_len;
+	/*   0:HOST_PCM_INTF disable
+	**  0xFFFF: HOST_PCM_INTF enable
+	*/
+	signed short  dsp_to_arm_flag;
+	unsigned short  partition_number;
+
+	/* ARM -> DSP Configuration */
+	unsigned short  write_buf1LSW;
+	unsigned short  write_buf1MSW;
+	unsigned short  write_buf1_len;
+
+	unsigned short  write_buf2LSW;
+	unsigned short  write_buf2MSW;
+	unsigned short  write_buf2_len;
+
+	/*   0:HOST_PCM_INTF disable
+	**  0xFFFF: HOST_PCM_INTF enable
+	*/
+	signed short  arm_to_rx_flag;
+	unsigned short  weight_decoder_to_rx;
+	unsigned short  weight_arm_to_rx;
+
+	unsigned short  partition_number_arm_to_dsp;
+	unsigned short  sample_rate;
+	unsigned short  channel_mode;
+} __attribute__((packed)) audpp_cmd_pcm_intf;
+
+/*
+ **  BUFFER UPDATE COMMAND
+ */
+#define AUDPP_CMD_PCM_INTF_SEND_BUF_PARAMS_LEN	\
+	sizeof(audpp_cmd_pcm_intf_send_buffer)
+
+typedef struct {
+  unsigned short  cmd_id;
+  unsigned short  host_pcm_object;
+  /* set config = 0xFFFF for configuration*/
+  signed short  config;
+  unsigned short  intf_type;
+  unsigned short  dsp_to_arm_buf_id;
+  unsigned short  arm_to_dsp_buf_id;
+  unsigned short  arm_to_dsp_buf_len;
+} __attribute__((packed)) audpp_cmd_pcm_intf_send_buffer;
+
+
+/*
+ * Commands Related to uPAudPPCmd3Queue
+ */
+
+/*
+ * Command Structure to configure post processing params (Commmon)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS		0x0000
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN		\
+	sizeof(audpp_cmd_cfg_object_params_common)
+
+#define AUDPP_CMD_OBJ0_UPDATE		0x8000
+#define AUDPP_CMD_OBJ0_DONT_UPDATE	0x0000
+
+#define AUDPP_CMD_OBJ1_UPDATE		0x8000
+#define AUDPP_CMD_OBJ1_DONT_UPDATE	0x0000
+
+#define AUDPP_CMD_OBJ2_UPDATE		0x8000
+#define AUDPP_CMD_OBJ2_DONT_UPDATE	0x0000
+
+#define AUDPP_CMD_OBJ3_UPDATE		0x8000
+#define AUDPP_CMD_OBJ3_DONT_UPDATE	0x0000
+
+#define AUDPP_CMD_OBJ4_UPDATE		0x8000
+#define AUDPP_CMD_OBJ4_DONT_UPDATE	0x0000
+
+#define AUDPP_CMD_HPCM_UPDATE		0x8000
+#define AUDPP_CMD_HPCM_DONT_UPDATE	0x0000
+
+#define AUDPP_CMD_COMMON_CFG_UPDATE		0x8000
+#define AUDPP_CMD_COMMON_CFG_DONT_UPDATE	0x0000
+
+typedef struct {
+	unsigned short  cmd_id;
+	unsigned short	obj0_cfg;
+	unsigned short	obj1_cfg;
+	unsigned short	obj2_cfg;
+	unsigned short	obj3_cfg;
+	unsigned short	obj4_cfg;
+	unsigned short	host_pcm_obj_cfg;
+	unsigned short	comman_cfg;
+	unsigned short  command_type;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_common;
+
+/*
+ * Command Structure to configure post processing params (Volume)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_VOLUME_LEN		\
+	sizeof(audpp_cmd_cfg_object_params_volume)
+
+typedef struct {
+	audpp_cmd_cfg_object_params_common 	common;
+	unsigned short					volume;
+	unsigned short					pan;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_volume;
+
+/*
+ * Command Structure to configure post processing params (PCM Filter) --DOUBT
+ */
+
+typedef struct {
+	unsigned short			numerator_b0_filter_lsw;
+	unsigned short			numerator_b0_filter_msw;
+	unsigned short			numerator_b1_filter_lsw;
+	unsigned short			numerator_b1_filter_msw;
+	unsigned short			numerator_b2_filter_lsw;
+	unsigned short			numerator_b2_filter_msw;
+} __attribute__((packed)) numerator;
+
+typedef struct {
+	unsigned short			denominator_a0_filter_lsw;
+	unsigned short			denominator_a0_filter_msw;
+	unsigned short			denominator_a1_filter_lsw;
+	unsigned short			denominator_a1_filter_msw;
+} __attribute__((packed)) denominator;
+
+typedef struct {
+	unsigned short			shift_factor_0;
+} __attribute__((packed)) shift_factor;
+
+typedef struct {
+	unsigned short			pan_filter_0;
+} __attribute__((packed)) pan;
+
+typedef struct {
+		numerator		numerator_filter;
+		denominator		denominator_filter;
+		shift_factor		shift_factor_filter;
+		pan			pan_filter;
+} __attribute__((packed)) filter_1;
+
+typedef struct {
+		numerator		numerator_filter[2];
+		denominator		denominator_filter[2];
+		shift_factor		shift_factor_filter[2];
+		pan			pan_filter[2];
+} __attribute__((packed)) filter_2;
+
+typedef struct {
+		numerator		numerator_filter[3];
+		denominator		denominator_filter[3];
+		shift_factor		shift_factor_filter[3];
+		pan			pan_filter[3];
+} __attribute__((packed)) filter_3;
+
+typedef struct {
+		numerator		numerator_filter[4];
+		denominator		denominator_filter[4];
+		shift_factor		shift_factor_filter[4];
+		pan			pan_filter[4];
+} __attribute__((packed)) filter_4;
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_PCM_LEN		\
+	sizeof(audpp_cmd_cfg_object_params_pcm)
+
+
+typedef struct {
+	audpp_cmd_cfg_object_params_common 	common;
+	unsigned short				active_flag;
+	unsigned short 				num_bands;
+	union {
+		filter_1			filter_1_params;
+		filter_2			filter_2_params;
+		filter_3			filter_3_params;
+		filter_4			filter_4_params;
+	} __attribute__((packed)) params_filter;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_pcm;
+
+
+/*
+ * Command Structure to configure post processing parameters (equalizer)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_EQALIZER_LEN		\
+	sizeof(audpp_cmd_cfg_object_params_eqalizer)
+
+typedef struct {
+	unsigned short			numerator_coeff_0_lsw;
+	unsigned short			numerator_coeff_0_msw;
+	unsigned short			numerator_coeff_1_lsw;
+	unsigned short			numerator_coeff_1_msw;
+	unsigned short			numerator_coeff_2_lsw;
+	unsigned short			numerator_coeff_2_msw;
+} __attribute__((packed)) eq_numerator;
+
+typedef struct {
+	unsigned short			denominator_coeff_0_lsw;
+	unsigned short			denominator_coeff_0_msw;
+	unsigned short			denominator_coeff_1_lsw;
+	unsigned short			denominator_coeff_1_msw;
+} __attribute__((packed)) eq_denominator;
+
+typedef struct {
+	unsigned short			shift_factor;
+} __attribute__((packed)) eq_shiftfactor;
+
+typedef struct {
+	eq_numerator	numerator;
+	eq_denominator	denominator;
+	eq_shiftfactor	shiftfactor;
+} __attribute__((packed)) eq_coeff_1;
+
+typedef struct {
+	eq_numerator	numerator[2];
+	eq_denominator	denominator[2];
+	eq_shiftfactor	shiftfactor[2];
+} __attribute__((packed)) eq_coeff_2;
+
+typedef struct {
+	eq_numerator	numerator[3];
+	eq_denominator	denominator[3];
+	eq_shiftfactor	shiftfactor[3];
+} __attribute__((packed)) eq_coeff_3;
+
+typedef struct {
+	eq_numerator	numerator[4];
+	eq_denominator	denominator[4];
+	eq_shiftfactor	shiftfactor[4];
+} __attribute__((packed)) eq_coeff_4;
+
+typedef struct {
+	eq_numerator	numerator[5];
+	eq_denominator	denominator[5];
+	eq_shiftfactor	shiftfactor[5];
+} __attribute__((packed)) eq_coeff_5;
+
+typedef struct {
+	eq_numerator	numerator[6];
+	eq_denominator	denominator[6];
+	eq_shiftfactor	shiftfactor[6];
+} __attribute__((packed)) eq_coeff_6;
+
+typedef struct {
+	eq_numerator	numerator[7];
+	eq_denominator	denominator[7];
+	eq_shiftfactor	shiftfactor[7];
+} __attribute__((packed)) eq_coeff_7;
+
+typedef struct {
+	eq_numerator	numerator[8];
+	eq_denominator	denominator[8];
+	eq_shiftfactor	shiftfactor[8];
+} __attribute__((packed)) eq_coeff_8;
+
+typedef struct {
+	eq_numerator	numerator[9];
+	eq_denominator	denominator[9];
+	eq_shiftfactor	shiftfactor[9];
+} __attribute__((packed)) eq_coeff_9;
+
+typedef struct {
+	eq_numerator	numerator[10];
+	eq_denominator	denominator[10];
+	eq_shiftfactor	shiftfactor[10];
+} __attribute__((packed)) eq_coeff_10;
+
+typedef struct {
+	eq_numerator	numerator[11];
+	eq_denominator	denominator[11];
+	eq_shiftfactor	shiftfactor[11];
+} __attribute__((packed)) eq_coeff_11;
+
+typedef struct {
+	eq_numerator	numerator[12];
+	eq_denominator	denominator[12];
+	eq_shiftfactor	shiftfactor[12];
+} __attribute__((packed)) eq_coeff_12;
+
+
+typedef struct {
+	audpp_cmd_cfg_object_params_common 	common;
+	unsigned short				eq_flag;
+	unsigned short				num_bands;
+	union {
+		eq_coeff_1	eq_coeffs_1;
+		eq_coeff_2	eq_coeffs_2;
+		eq_coeff_3	eq_coeffs_3;
+		eq_coeff_4	eq_coeffs_4;
+		eq_coeff_5	eq_coeffs_5;
+		eq_coeff_6	eq_coeffs_6;
+		eq_coeff_7	eq_coeffs_7;
+		eq_coeff_8	eq_coeffs_8;
+		eq_coeff_9	eq_coeffs_9;
+		eq_coeff_10	eq_coeffs_10;
+		eq_coeff_11	eq_coeffs_11;
+		eq_coeff_12	eq_coeffs_12;
+	} __attribute__((packed)) eq_coeff;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_eqalizer;
+
+
+/*
+ * Command Structure to configure post processing parameters (ADRC)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_ADRC_LEN		\
+	sizeof(audpp_cmd_cfg_object_params_adrc)
+
+
+#define AUDPP_CMD_ADRC_FLAG_DIS		0x0000
+#define AUDPP_CMD_ADRC_FLAG_ENA		-1
+
+typedef struct {
+	audpp_cmd_cfg_object_params_common 	common;
+	signed short				adrc_flag;
+	unsigned short				compression_th;
+	unsigned short				compression_slope;
+	unsigned short				rms_time;
+	unsigned short				attack_const_lsw;
+	unsigned short				attack_const_msw;
+	unsigned short				release_const_lsw;
+	unsigned short				release_const_msw;
+	unsigned short				adrc_system_delay;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_adrc;
+
+/*
+ * Command Structure to configure post processing parameters(Spectrum Analizer)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_SPECTRAM_LEN		\
+	sizeof(audpp_cmd_cfg_object_params_spectram)
+
+
+typedef struct {
+	audpp_cmd_cfg_object_params_common 	common;
+	unsigned short				sample_interval;
+	unsigned short				num_coeff;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_spectram;
+
+/*
+ * Command Structure to configure post processing parameters (QConcert)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_QCONCERT_LEN		\
+	sizeof(audpp_cmd_cfg_object_params_qconcert)
+
+
+#define AUDPP_CMD_QCON_ENA_FLAG_ENA		-1
+#define AUDPP_CMD_QCON_ENA_FLAG_DIS		0x0000
+
+#define AUDPP_CMD_QCON_OP_MODE_HEADPHONE	-1
+#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_FRONT	0x0000
+#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_SIDE	0x0001
+#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_DESKTOP	0x0002
+
+#define AUDPP_CMD_QCON_GAIN_UNIT			0x7FFF
+#define AUDPP_CMD_QCON_GAIN_SIX_DB			0x4027
+
+
+#define AUDPP_CMD_QCON_EXPANSION_MAX		0x7FFF
+
+
+typedef struct {
+	audpp_cmd_cfg_object_params_common 	common;
+	signed short				enable_flag;
+	signed short				output_mode;
+	signed short				gain;
+	signed short				expansion;
+	signed short				delay;
+	unsigned short				stages_per_mode;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_qconcert;
+
+/*
+ * Command Structure to configure post processing parameters (Side Chain)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_SIDECHAIN_LEN		\
+	sizeof(audpp_cmd_cfg_object_params_sidechain)
+
+
+#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_DIS	0x0000
+#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_ENA	-1
+
+typedef struct {
+	audpp_cmd_cfg_object_params_common 	common;
+	signed short				active_flag;
+	unsigned short				num_bands;
+	union {
+		filter_1			filter_1_params;
+		filter_2			filter_2_params;
+		filter_3			filter_3_params;
+		filter_4			filter_4_params;
+	} __attribute__((packed)) params_filter;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_sidechain;
+
+
+/*
+ * Command Structure to configure post processing parameters (QAFX)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_QAFX_LEN		\
+	sizeof(audpp_cmd_cfg_object_params_qafx)
+
+#define AUDPP_CMD_QAFX_ENA_DISA		0x0000
+#define AUDPP_CMD_QAFX_ENA_ENA_CFG	-1
+#define AUDPP_CMD_QAFX_ENA_DIS_CFG	0x0001
+
+#define AUDPP_CMD_QAFX_CMD_TYPE_ENV	0x0100
+#define AUDPP_CMD_QAFX_CMD_TYPE_OBJ	0x0010
+#define AUDPP_CMD_QAFX_CMD_TYPE_QUERY	0x1000
+
+#define AUDPP_CMD_QAFX_CMDS_ENV_OP_MODE	0x0100
+#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_POS	0x0101
+#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_ORI	0x0102
+#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_VEL	0X0103
+#define AUDPP_CMD_QAFX_CMDS_ENV_ENV_RES	0x0107
+
+#define AUDPP_CMD_QAFX_CMDS_OBJ_SAMP_FREQ	0x0010
+#define AUDPP_CMD_QAFX_CMDS_OBJ_VOL		0x0011
+#define AUDPP_CMD_QAFX_CMDS_OBJ_DIST		0x0012
+#define AUDPP_CMD_QAFX_CMDS_OBJ_POS		0x0013
+#define AUDPP_CMD_QAFX_CMDS_OBJ_VEL		0x0014
+
+
+typedef struct {
+	audpp_cmd_cfg_object_params_common 	common;
+	signed short				enable;
+	unsigned short				command_type;
+	unsigned short				num_commands;
+	unsigned short				commands;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_qafx;
+
+/*
+ * Command Structure to enable , disable or configure the reverberation effect
+ * (Common)
+ */
+
+#define AUDPP_CMD_REVERB_CONFIG		0x0001
+#define	AUDPP_CMD_REVERB_CONFIG_COMMON_LEN	\
+	sizeof(audpp_cmd_reverb_config_common)
+
+#define AUDPP_CMD_ENA_ENA	0xFFFF
+#define AUDPP_CMD_ENA_DIS	0x0000
+#define AUDPP_CMD_ENA_CFG	0x0001
+
+#define AUDPP_CMD_CMD_TYPE_ENV		0x0104
+#define AUDPP_CMD_CMD_TYPE_OBJ		0x0015
+#define AUDPP_CMD_CMD_TYPE_QUERY	0x1000
+
+
+typedef struct {
+	unsigned short			cmd_id;
+	unsigned short			enable;
+	unsigned short			cmd_type;
+} __attribute__((packed)) audpp_cmd_reverb_config_common;
+
+/*
+ * Command Structure to enable , disable or configure the reverberation effect
+ * (ENV-0x0104)
+ */
+
+#define	AUDPP_CMD_REVERB_CONFIG_ENV_104_LEN	\
+	sizeof(audpp_cmd_reverb_config_env_104)
+
+typedef struct {
+	audpp_cmd_reverb_config_common	common;
+	unsigned short			env_gain;
+	unsigned short			decay_msw;
+	unsigned short			decay_lsw;
+	unsigned short			decay_timeratio_msw;
+	unsigned short			decay_timeratio_lsw;
+	unsigned short			delay_time;
+	unsigned short			reverb_gain;
+	unsigned short			reverb_delay;
+} __attribute__((packed)) audpp_cmd_reverb_config_env_104;
+
+/*
+ * Command Structure to enable , disable or configure the reverberation effect
+ * (ENV-0x0015)
+ */
+
+#define	AUDPP_CMD_REVERB_CONFIG_ENV_15_LEN	\
+	sizeof(audpp_cmd_reverb_config_env_15)
+
+typedef struct {
+	audpp_cmd_reverb_config_common	common;
+	unsigned short			object_num;
+	unsigned short			absolute_gain;
+} __attribute__((packed)) audpp_cmd_reverb_config_env_15;
+
+
+#endif /* QDSP5AUDPPCMDI_H */
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,318 @@
+#ifndef QDSP5AUDPPMSG_H
+#define QDSP5AUDPPMSG_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+       Q D S P 5  A U D I O   P O S T   P R O C E S S I N G   M S G
+
+GENERAL DESCRIPTION
+  Messages sent by AUDPPTASK to ARM
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+  None
+
+Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+ $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppmsg.h#4 $
+
+===========================================================================*/
+
+/*
+ * AUDPPTASK uses audPPuPRlist to send messages to the ARM
+ * Location : MEMA
+ * Buffer Size : 45
+ * No of Buffers in a queue : 5 for gaming audio and 1 for other images
+ */
+
+/*
+ * MSG to Informs the ARM os Success/Failure of bringing up the decoder
+ */
+
+#define AUDPP_MSG_STATUS_MSG		0x0001
+#define AUDPP_MSG_STATUS_MSG_LEN	\
+	sizeof(audpp_msg_status_msg)
+
+#define AUDPP_MSG_STATUS_SLEEP		0x0000
+#define AUDPP_MSG__STATUS_INIT		0x0001
+#define AUDPP_MSG_MSG_STATUS_CFG	0x0002
+#define AUDPP_MSG_STATUS_PLAY		0x0003
+
+#define AUDPP_MSG_REASON_MIPS	0x0000
+#define AUDPP_MSG_REASON_MEM	0x0001
+
+typedef struct{
+	unsigned short dec_id;
+	unsigned short status;
+	unsigned short reason;
+} __attribute__((packed)) audpp_msg_status_msg;
+
+/*
+ * MSG to communicate the spectrum analyzer output bands to the ARM
+ */
+#define AUDPP_MSG_SPA_BANDS		0x0002
+#define AUDPP_MSG_SPA_BANDS_LEN	\
+	sizeof(audpp_msg_spa_bands)
+
+typedef struct {
+	unsigned short			current_object;
+	unsigned short			spa_band_1;
+	unsigned short			spa_band_2;
+	unsigned short			spa_band_3;
+	unsigned short			spa_band_4;
+	unsigned short			spa_band_5;
+	unsigned short			spa_band_6;
+	unsigned short			spa_band_7;
+	unsigned short			spa_band_8;
+	unsigned short			spa_band_9;
+	unsigned short			spa_band_10;
+	unsigned short			spa_band_11;
+	unsigned short			spa_band_12;
+	unsigned short			spa_band_13;
+	unsigned short			spa_band_14;
+	unsigned short			spa_band_15;
+	unsigned short			spa_band_16;
+	unsigned short			spa_band_17;
+	unsigned short			spa_band_18;
+	unsigned short			spa_band_19;
+	unsigned short			spa_band_20;
+	unsigned short			spa_band_21;
+	unsigned short			spa_band_22;
+	unsigned short			spa_band_23;
+	unsigned short			spa_band_24;
+	unsigned short			spa_band_25;
+	unsigned short			spa_band_26;
+	unsigned short			spa_band_27;
+	unsigned short			spa_band_28;
+	unsigned short			spa_band_29;
+	unsigned short			spa_band_30;
+	unsigned short			spa_band_31;
+	unsigned short			spa_band_32;
+} __attribute__((packed)) audpp_msg_spa_bands;
+
+/*
+ * MSG to communicate the PCM I/O buffer status to ARM
+ */
+#define  AUDPP_MSG_HOST_PCM_INTF_MSG		0x0003
+#define  AUDPP_MSG_HOST_PCM_INTF_MSG_LEN	\
+	sizeof(audpp_msg_host_pcm_intf_msg)
+
+#define AUDPP_MSG_HOSTPCM_ID_TX_ARM	0x0000
+#define AUDPP_MSG_HOSTPCM_ID_ARM_TX	0x0001
+#define AUDPP_MSG_HOSTPCM_ID_RX_ARM	0x0002
+#define AUDPP_MSG_HOSTPCM_ID_ARM_RX	0x0003
+
+#define AUDPP_MSG_SAMP_FREQ_INDX_96000	0x0000
+#define AUDPP_MSG_SAMP_FREQ_INDX_88200	0x0001
+#define AUDPP_MSG_SAMP_FREQ_INDX_64000	0x0002
+#define AUDPP_MSG_SAMP_FREQ_INDX_48000	0x0003
+#define AUDPP_MSG_SAMP_FREQ_INDX_44100	0x0004
+#define AUDPP_MSG_SAMP_FREQ_INDX_32000	0x0005
+#define AUDPP_MSG_SAMP_FREQ_INDX_24000	0x0006
+#define AUDPP_MSG_SAMP_FREQ_INDX_22050	0x0007
+#define AUDPP_MSG_SAMP_FREQ_INDX_16000	0x0008
+#define AUDPP_MSG_SAMP_FREQ_INDX_12000	0x0009
+#define AUDPP_MSG_SAMP_FREQ_INDX_11025	0x000A
+#define AUDPP_MSG_SAMP_FREQ_INDX_8000	0x000B
+
+#define AUDPP_MSG_CHANNEL_MODE_MONO		0x0001
+#define AUDPP_MSG_CHANNEL_MODE_STEREO	0x0002
+
+typedef struct{
+	unsigned short obj_num;
+	unsigned short numbers_of_samples;
+	unsigned short host_pcm_id;
+	unsigned short buf_indx;
+	unsigned short samp_freq_indx;
+	unsigned short channel_mode;
+} __attribute__((packed)) audpp_msg_host_pcm_intf_msg;
+
+
+/*
+ * MSG to communicate 3D position of the source and listener , source volume
+ * source rolloff, source orientation
+ */
+
+#define AUDPP_MSG_QAFX_POS		0x0004
+#define AUDPP_MSG_QAFX_POS_LEN		\
+	sizeof(audpp_msg_qafx_pos)
+
+typedef struct {
+	unsigned short	current_object;
+	unsigned short	x_pos_lis_msw;
+	unsigned short	x_pos_lis_lsw;
+	unsigned short	y_pos_lis_msw;
+	unsigned short	y_pos_lis_lsw;
+	unsigned short	z_pos_lis_msw;
+	unsigned short	z_pos_lis_lsw;
+	unsigned short	x_fwd_msw;
+	unsigned short	x_fwd_lsw;
+	unsigned short	y_fwd_msw;
+	unsigned short	y_fwd_lsw;
+	unsigned short	z_fwd_msw;
+	unsigned short	z_fwd_lsw;
+	unsigned short 	x_up_msw;
+	unsigned short	x_up_lsw;
+	unsigned short 	y_up_msw;
+	unsigned short	y_up_lsw;
+	unsigned short 	z_up_msw;
+	unsigned short	z_up_lsw;
+	unsigned short 	x_vel_lis_msw;
+	unsigned short 	x_vel_lis_lsw;
+	unsigned short 	y_vel_lis_msw;
+	unsigned short 	y_vel_lis_lsw;
+	unsigned short 	z_vel_lis_msw;
+	unsigned short 	z_vel_lis_lsw;
+	unsigned short	threed_enable_flag;
+	unsigned short 	volume;
+	unsigned short	x_pos_source_msw;
+	unsigned short	x_pos_source_lsw;
+	unsigned short	y_pos_source_msw;
+	unsigned short	y_pos_source_lsw;
+	unsigned short	z_pos_source_msw;
+	unsigned short	z_pos_source_lsw;
+	unsigned short	max_dist_0_msw;
+	unsigned short	max_dist_0_lsw;
+	unsigned short	min_dist_0_msw;
+	unsigned short	min_dist_0_lsw;
+	unsigned short	roll_off_factor;
+	unsigned short	mute_after_max_flag;
+	unsigned short	x_vel_source_msw;
+	unsigned short	x_vel_source_lsw;
+	unsigned short	y_vel_source_msw;
+	unsigned short	y_vel_source_lsw;
+	unsigned short	z_vel_source_msw;
+	unsigned short	z_vel_source_lsw;
+} __attribute__((packed)) audpp_msg_qafx_pos;
+
+/*
+ * MSG to provide AVSYNC feedback from DSP to ARM
+ */
+
+#define AUDPP_MSG_AVSYNC_MSG		0x0005
+#define AUDPP_MSG_AVSYNC_MSG_LEN	\
+	sizeof(audpp_msg_avsync_msg)
+
+typedef struct {
+	unsigned short	active_flag;
+	unsigned short	num_samples_counter0_HSW;
+	unsigned short	num_samples_counter0_MSW;
+	unsigned short	num_samples_counter0_LSW;
+	unsigned short	num_bytes_counter0_HSW;
+	unsigned short	num_bytes_counter0_MSW;
+	unsigned short	num_bytes_counter0_LSW;
+	unsigned short	samp_freq_obj_0;
+	unsigned short	samp_freq_obj_1;
+	unsigned short	samp_freq_obj_2;
+	unsigned short	samp_freq_obj_3;
+	unsigned short	samp_freq_obj_4;
+	unsigned short	samp_freq_obj_5;
+	unsigned short	samp_freq_obj_6;
+	unsigned short	samp_freq_obj_7;
+	unsigned short	samp_freq_obj_8;
+	unsigned short	samp_freq_obj_9;
+	unsigned short	samp_freq_obj_10;
+	unsigned short	samp_freq_obj_11;
+	unsigned short	samp_freq_obj_12;
+	unsigned short	samp_freq_obj_13;
+	unsigned short	samp_freq_obj_14;
+	unsigned short	samp_freq_obj_15;
+	unsigned short	num_samples_counter4_HSW;
+	unsigned short	num_samples_counter4_MSW;
+	unsigned short	num_samples_counter4_LSW;
+	unsigned short	num_bytes_counter4_HSW;
+	unsigned short	num_bytes_counter4_MSW;
+	unsigned short	num_bytes_counter4_LSW;
+} __attribute__((packed)) audpp_msg_avsync_msg;
+
+/*
+ * MSG to provide PCM DMA Missed feedback from the DSP to ARM
+ */
+
+#define  AUDPP_MSG_PCMDMAMISSED	0x0006
+#define  AUDPP_MSG_PCMDMAMISSED_LEN	\
+	sizeof(audpp_msg_pcmdmamissed);
+
+typedef struct{
+	/*
+	** Bit 0	0 = PCM DMA not missed for object 0
+	**        1 = PCM DMA missed for object0
+	** Bit 1	0 = PCM DMA not missed for object 1
+	**        1 = PCM DMA missed for object1
+	** Bit 2	0 = PCM DMA not missed for object 2
+	**        1 = PCM DMA missed for object2
+	** Bit 3	0 = PCM DMA not missed for object 3
+	**        1 = PCM DMA missed for object3
+	** Bit 4	0 = PCM DMA not missed for object 4
+	**        1 = PCM DMA missed for object4
+	*/
+	unsigned short pcmdmamissed;
+} __attribute__((packed)) audpp_msg_pcmdmamissed;
+
+/*
+ * MSG to AUDPP enable or disable feedback form DSP to ARM
+ */
+
+#define AUDPP_MSG_CFG_MSG	0x0007
+#define AUDPP_MSG_CFG_MSG_LEN	\
+    sizeof(audpp_msg_cfg_msg)
+
+#define AUDPP_MSG_ENA_ENA	0xFFFF
+#define AUDPP_MSG_ENA_DIS	0x0000
+
+typedef struct{
+	/*   Enabled  - 0xffff
+	**  Disabled - 0
+	*/
+	unsigned short enabled;
+} __attribute__((packed)) audpp_msg_cfg_msg;
+
+/*
+ * MSG to communicate the reverb  per object volume
+ */
+
+#define AUDPP_MSG_QREVERB_VOLUME	0x0008
+#define AUDPP_MSG_QREVERB_VOLUME_LEN	\
+	sizeof(audpp_msg_qreverb_volume)
+
+
+typedef struct {
+	unsigned short	obj_0_gain;
+	unsigned short	obj_1_gain;
+	unsigned short	obj_2_gain;
+	unsigned short	obj_3_gain;
+	unsigned short	obj_4_gain;
+	unsigned short	hpcm_obj_volume;
+} __attribute__((packed)) audpp_msg_qreverb_volume;
+
+#define AUDPP_MSG_ROUTING_ACK 0x0009
+#define AUDPP_MSG_ROUTING_ACK_LEN \
+  sizeof(struct audpp_msg_routing_ack)
+
+struct audpp_msg_routing_ack {
+	unsigned short dec_id;
+	unsigned short routing_mode;
+} __attribute__((packed));
+
+#define AUDPP_MSG_FLUSH_ACK 0x000A
+
+#endif /* QDSP5AUDPPMSG_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,256 @@
+#ifndef QDSP5AUDPREPROCCMDI_H
+#define QDSP5AUDPREPROCCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+    A U D I O   P R E   P R O C E S S I N G  I N T E R N A L  C O M M A N D S
+
+GENERAL DESCRIPTION
+  This file contains defintions of format blocks of commands
+  that are accepted by AUDPREPROC Task
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+  None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreproccmdi.h#2 $
+
+===========================================================================*/
+
+/*
+ * AUDIOPREPROC COMMANDS:
+ * ARM uses uPAudPreProcCmdQueue to communicate with AUDPREPROCTASK
+ * Location : MEMB
+ * Buffer size : 51
+ * Number of buffers in a queue : 3
+ */
+
+/*
+ * Command to configure the parameters of AGC
+ */
+
+#define	AUDPREPROC_CMD_CFG_AGC_PARAMS	0x0000
+#define	AUDPREPROC_CMD_CFG_AGC_PARAMS_LEN	\
+	sizeof(audpreproc_cmd_cfg_agc_params)
+
+#define	AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE	0x0009
+#define	AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH	0x000A
+#define	AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE	0x000B
+#define	AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH		0x000C
+#define	AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG		0x000D
+#define	AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN	0x000E
+#define	AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG	0x000F
+
+#define	AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA	-1
+#define	AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS	0x0000
+
+#define	AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_ADP_GAIN	-1
+#define	AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_STATIC_GAIN	0x0000
+
+#define	AUDPREPROC_CMD_PARAM_MASK_RMS_TAY	0x0004
+#define	AUDPREPROC_CMD_PARAM_MASK_RELEASEK	0x0005
+#define	AUDPREPROC_CMD_PARAM_MASK_DELAY		0x0006
+#define	AUDPREPROC_CMD_PARAM_MASK_ATTACKK	0x0007
+#define	AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW	0x0008
+#define	AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST	0x0009
+#define	AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK 	0x000A
+#define	AUDPREPROC_CMD_PARAM_MASK_AIG_MIN	0x000B
+#define	AUDPREPROC_CMD_PARAM_MASK_AIG_MAX	0x000C
+#define	AUDPREPROC_CMD_PARAM_MASK_LEAK_UP	0x000D
+#define	AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN	0x000E
+#define	AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK	0x000F
+
+typedef struct {
+	unsigned short	cmd_id;
+	unsigned short	tx_agc_param_mask;
+	unsigned short	tx_agc_enable_flag;
+	unsigned short	static_gain;
+	signed short	adaptive_gain_flag;
+	unsigned short	expander_th;
+	unsigned short	expander_slope;
+	unsigned short	compressor_th;
+	unsigned short	compressor_slope;
+	unsigned short	param_mask;
+	unsigned short	aig_attackk;
+	unsigned short	aig_leak_down;
+	unsigned short	aig_leak_up;
+	unsigned short	aig_max;
+	unsigned short	aig_min;
+	unsigned short	aig_releasek;
+	unsigned short	aig_leakrate_fast;
+	unsigned short	aig_leakrate_slow;
+	unsigned short	attackk_msw;
+	unsigned short	attackk_lsw;
+	unsigned short	delay;
+	unsigned short	releasek_msw;
+	unsigned short	releasek_lsw;
+	unsigned short	rms_tav;
+} __attribute__((packed)) audpreproc_cmd_cfg_agc_params;
+
+
+/*
+ * Command to configure the params of Advanved AGC
+ */
+
+#define	AUDPREPROC_CMD_CFG_AGC_PARAMS_2		0x0001
+#define	AUDPREPROC_CMD_CFG_AGC_PARAMS_2_LEN		\
+	sizeof(audpreproc_cmd_cfg_agc_params_2)
+
+#define	AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_ENA	-1;
+#define	AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_DIS	0x0000;
+
+typedef struct {
+	unsigned short	cmd_id;
+	unsigned short	agc_param_mask;
+	signed short	tx_agc_enable_flag;
+	unsigned short	comp_static_gain;
+	unsigned short	exp_th;
+	unsigned short	exp_slope;
+	unsigned short	comp_th;
+	unsigned short	comp_slope;
+	unsigned short	comp_rms_tav;
+	unsigned short	comp_samp_mask;
+	unsigned short	comp_attackk_msw;
+	unsigned short	comp_attackk_lsw;
+	unsigned short	comp_releasek_msw;
+	unsigned short	comp_releasek_lsw;
+	unsigned short	comp_delay;
+	unsigned short	comp_makeup_gain;
+} __attribute__((packed)) audpreproc_cmd_cfg_agc_params_2;
+
+/*
+ * Command to configure params for ns
+ */
+
+#define	AUDPREPROC_CMD_CFG_NS_PARAMS		0x0002
+#define	AUDPREPROC_CMD_CFG_NS_PARAMS_LEN	\
+	sizeof(audpreproc_cmd_cfg_ns_params)
+
+#define	AUDPREPROC_CMD_EC_MODE_NEW_NLMS_ENA	0x0001
+#define	AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS 	0x0000
+#define	AUDPREPROC_CMD_EC_MODE_NEW_DES_ENA	0x0002
+#define	AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS	0x0000
+#define	AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA	0x0004
+#define	AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS	0x0000
+#define	AUDPREPROC_CMD_EC_MODE_NEW_CNI_ENA	0x0008
+#define	AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS	0x0000
+
+#define	AUDPREPROC_CMD_EC_MODE_NEW_NLES_ENA	0x0010
+#define	AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS	0x0000
+#define	AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA	0x0020
+#define	AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS	0x0000
+#define	AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA	0x0040
+#define	AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS	0x0000
+#define	AUDPREPROC_CMD_EC_MODE_NEW_PCD_ENA	0x0080
+#define	AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS	0x0000
+#define	AUDPREPROC_CMD_EC_MODE_NEW_FEHI_ENA	0x0100
+#define	AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS 	0x0000
+#define	AUDPREPROC_CMD_EC_MODE_NEW_NEHI_ENA	0x0200
+#define	AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS 	0x0000
+#define	AUDPREPROC_CMD_EC_MODE_NEW_NLPP_ENA	0x0400
+#define	AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS	0x0000
+#define	AUDPREPROC_CMD_EC_MODE_NEW_FNE_ENA	0x0800
+#define	AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS	0x0000
+#define	AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_ENA 	0x1000
+#define	AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS 	0x0000
+
+typedef struct {
+	unsigned short	cmd_id;
+	unsigned short	ec_mode_new;
+	unsigned short	dens_gamma_n;
+	unsigned short	dens_nfe_block_size;
+	unsigned short	dens_limit_ns;
+	unsigned short	dens_limit_ns_d;
+	unsigned short	wb_gamma_e;
+	unsigned short	wb_gamma_n;
+} __attribute__((packed)) audpreproc_cmd_cfg_ns_params;
+
+/*
+ * Command to configure parameters for IIR tuning filter
+ */
+
+#define	AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS		0x0003
+#define	AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS_LEN	\
+	sizeof(audpreproc_cmd_cfg_iir_tuning_filter_params)
+
+#define	AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS	0x0000
+#define	AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA	0x0001
+
+typedef struct {
+	unsigned short	cmd_id;
+	unsigned short	active_flag;
+	unsigned short	num_bands;
+	unsigned short	numerator_coeff_b0_filter0_lsw;
+	unsigned short	numerator_coeff_b0_filter0_msw;
+	unsigned short	numerator_coeff_b1_filter0_lsw;
+	unsigned short	numerator_coeff_b1_filter0_msw;
+	unsigned short	numerator_coeff_b2_filter0_lsw;
+	unsigned short	numerator_coeff_b2_filter0_msw;
+	unsigned short	numerator_coeff_b0_filter1_lsw;
+	unsigned short	numerator_coeff_b0_filter1_msw;
+	unsigned short	numerator_coeff_b1_filter1_lsw;
+	unsigned short	numerator_coeff_b1_filter1_msw;
+	unsigned short	numerator_coeff_b2_filter1_lsw;
+	unsigned short	numerator_coeff_b2_filter1_msw;
+	unsigned short	numerator_coeff_b0_filter2_lsw;
+	unsigned short	numerator_coeff_b0_filter2_msw;
+	unsigned short	numerator_coeff_b1_filter2_lsw;
+	unsigned short	numerator_coeff_b1_filter2_msw;
+	unsigned short	numerator_coeff_b2_filter2_lsw;
+	unsigned short	numerator_coeff_b2_filter2_msw;
+	unsigned short	numerator_coeff_b0_filter3_lsw;
+	unsigned short	numerator_coeff_b0_filter3_msw;
+	unsigned short	numerator_coeff_b1_filter3_lsw;
+	unsigned short	numerator_coeff_b1_filter3_msw;
+	unsigned short	numerator_coeff_b2_filter3_lsw;
+	unsigned short	numerator_coeff_b2_filter3_msw;
+	unsigned short 	denominator_coeff_a0_filter0_lsw;
+	unsigned short 	denominator_coeff_a0_filter0_msw;
+	unsigned short 	denominator_coeff_a1_filter0_lsw;
+	unsigned short 	denominator_coeff_a1_filter0_msw;
+	unsigned short 	denominator_coeff_a0_filter1_lsw;
+	unsigned short 	denominator_coeff_a0_filter1_msw;
+	unsigned short 	denominator_coeff_a1_filter1_lsw;
+	unsigned short 	denominator_coeff_a1_filter1_msw;
+  unsigned short 	denominator_coeff_a0_filter2_lsw;
+	unsigned short 	denominator_coeff_a0_filter2_msw;
+	unsigned short 	denominator_coeff_a1_filter2_lsw;
+	unsigned short 	denominator_coeff_a1_filter2_msw;
+  unsigned short 	denominator_coeff_a0_filter3_lsw;
+	unsigned short 	denominator_coeff_a0_filter3_msw;
+	unsigned short 	denominator_coeff_a1_filter3_lsw;
+	unsigned short 	denominator_coeff_a1_filter3_msw;
+
+	unsigned short	shift_factor_filter0;
+	unsigned short	shift_factor_filter1;
+	unsigned short	shift_factor_filter2;
+	unsigned short	shift_factor_filter3;
+
+	unsigned short	channel_selected0;
+	unsigned short	channel_selected1;
+	unsigned short	channel_selected2;
+	unsigned short	channel_selected3;
+} __attribute__((packed))audpreproc_cmd_cfg_iir_tuning_filter_params;
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,85 @@
+#ifndef QDSP5AUDPREPROCMSG_H
+#define QDSP5AUDPREPROCMSG_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+    A U D I O   P R E   P R O C E S S I N G  M E S S A G E S
+
+GENERAL DESCRIPTION
+  This file contains defintions of format blocks of messages
+  that are rcvd by AUDPREPROC Task
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+  None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+ $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreprocmsg.h#3 $
+
+===========================================================================*/
+
+/*
+ * ADSPREPROCTASK Messages
+ * AUDPREPROCTASK uses audPreProcUpRlist to communicate with ARM
+ * Location	: MEMA
+ * Message Length  : 2
+ */
+
+/*
+ * Message to indicate particular feature has been enabled or disabled
+ */
+
+
+#define	AUDPREPROC_MSG_CMD_CFG_DONE_MSG	0x0000
+#define	AUDPREPROC_MSG_CMD_CFG_DONE_MSG_LEN	\
+	sizeof(audpreproc_msg_cmd_cfg_done_msg)
+
+#define	AUDPREPROC_MSG_TYPE_AGC			0x0000
+#define	AUDPREPROC_MSG_TYPE_NOISE_REDUCTION	0x0001
+#define	AUDPREPROC_MSG_TYPE_IIR_FILTER		0x0002
+
+
+#define	AUDPREPROC_MSG_STATUS_FLAG_ENA		-1
+#define	AUDPREPROC_MSG_STATUS_FLAG_DIS		0x0000
+
+typedef struct {
+	unsigned short	type;
+	signed short	status_flag;
+} __attribute__((packed)) audpreproc_msg_cmd_cfg_done_msg;
+
+
+/*
+ * Message to indicate particular feature has selected for wrong samp freq
+ */
+
+#define	AUDPREPROC_MSG_ERROR_MSG_ID		0x0001
+#define	AUDPREPROC_MSG_ERROR_MSG_ID_LEN	\
+	sizeof(audpreproc_msg_error_msg_id)
+
+#define	AUDPREPROC_MSG_ERR_INDEX_NS		0x0000
+
+typedef struct {
+	 unsigned short	err_index;
+} __attribute__((packed)) audpreproc_msg_error_msg_id;
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,176 @@
+#ifndef QDSP5AUDRECCMDI_H
+#define QDSP5AUDRECCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+    A U D I O   R E C O R D  I N T E R N A L  C O M M A N D S
+
+GENERAL DESCRIPTION
+  This file contains defintions of format blocks of commands
+  that are accepted by AUDREC Task
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+  None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+ $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audreccmdi.h#3 $
+
+============================================================================*/
+
+/*
+ * AUDRECTASK COMMANDS
+ * ARM uses 2 queues to communicate with the AUDRECTASK
+ * 1.uPAudRecCmdQueue
+ * Location :MEMC
+ * Buffer Size : 8
+ * No of Buffers in a queue : 3
+ * 2.audRecUpBitStreamQueue
+ * Location : MEMC
+ * Buffer Size : 4
+ * No of buffers in a queue : 2
+ */
+
+/*
+ * Commands on uPAudRecCmdQueue
+ */
+
+/*
+ * Command to initiate and terminate the audio recording section
+ */
+
+#define AUDREC_CMD_CFG		0x0000
+#define	AUDREC_CMD_CFG_LEN	sizeof(audrec_cmd_cfg)
+
+#define	AUDREC_CMD_TYPE_0_INDEX_WAV	0x0000
+#define	AUDREC_CMD_TYPE_0_INDEX_AAC	0x0001
+
+#define AUDREC_CMD_TYPE_0_ENA		0x4000
+#define AUDREC_CMD_TYPE_0_DIS		0x0000
+
+#define AUDREC_CMD_TYPE_0_NOUPDATE	0x0000
+#define AUDREC_CMD_TYPE_0_UPDATE	0x8000
+
+#define	AUDREC_CMD_TYPE_1_INDEX_SBC	0x0002
+
+#define AUDREC_CMD_TYPE_1_ENA		0x4000
+#define AUDREC_CMD_TYPE_1_DIS		0x0000
+
+#define AUDREC_CMD_TYPE_1_NOUPDATE	0x0000
+#define AUDREC_CMD_TYPE_1_UPDATE	0x8000
+
+typedef struct {
+	unsigned short 	cmd_id;
+	unsigned short	type_0;
+	unsigned short	type_1;
+} __attribute__((packed)) audrec_cmd_cfg;
+
+
+/*
+ * Command to configure the recording parameters for RecType0(AAC/WAV) encoder
+ */
+
+#define	AUDREC_CMD_AREC0PARAM_CFG	0x0001
+#define	AUDREC_CMD_AREC0PARAM_CFG_LEN	\
+	sizeof(audrec_cmd_arec0param_cfg)
+
+#define	AUDREC_CMD_SAMP_RATE_INDX_8000		0x000B
+#define	AUDREC_CMD_SAMP_RATE_INDX_11025		0x000A
+#define	AUDREC_CMD_SAMP_RATE_INDX_12000		0x0009
+#define	AUDREC_CMD_SAMP_RATE_INDX_16000		0x0008
+#define	AUDREC_CMD_SAMP_RATE_INDX_22050		0x0007
+#define	AUDREC_CMD_SAMP_RATE_INDX_24000		0x0006
+#define	AUDREC_CMD_SAMP_RATE_INDX_32000		0x0005
+#define	AUDREC_CMD_SAMP_RATE_INDX_44100		0x0004
+#define	AUDREC_CMD_SAMP_RATE_INDX_48000		0x0003
+
+#define AUDREC_CMD_STEREO_MODE_MONO		0x0000
+#define AUDREC_CMD_STEREO_MODE_STEREO		0x0001
+
+typedef struct {
+	unsigned short 	cmd_id;
+	unsigned short	ptr_to_extpkt_buffer_msw;
+	unsigned short	ptr_to_extpkt_buffer_lsw;
+	unsigned short	buf_len;
+	unsigned short	samp_rate_index;
+	unsigned short	stereo_mode;
+	unsigned short 	rec_quality;
+} __attribute__((packed)) audrec_cmd_arec0param_cfg;
+
+/*
+ * Command to configure the recording parameters for RecType1(SBC) encoder
+ */
+
+#define AUDREC_CMD_AREC1PARAM_CFG	0x0002
+#define AUDREC_CMD_AREC1PARAM_CFG_LEN	\
+	sizeof(audrec_cmd_arec1param_cfg)
+
+#define AUDREC_CMD_PARAM_BUF_BLOCKS_4	0x0000
+#define AUDREC_CMD_PARAM_BUF_BLOCKS_8	0x0001
+#define AUDREC_CMD_PARAM_BUF_BLOCKS_12	0x0002
+#define AUDREC_CMD_PARAM_BUF_BLOCKS_16	0x0003
+
+#define AUDREC_CMD_PARAM_BUF_SUB_BANDS_8	0x0010
+#define AUDREC_CMD_PARAM_BUF_MODE_MONO		0x0000
+#define AUDREC_CMD_PARAM_BUF_MODE_DUAL		0x0040
+#define AUDREC_CMD_PARAM_BUF_MODE_STEREO	0x0050
+#define AUDREC_CMD_PARAM_BUF_MODE_JSTEREO	0x0060
+#define AUDREC_CMD_PARAM_BUF_LOUDNESS		0x0000
+#define AUDREC_CMD_PARAM_BUF_SNR		0x0100
+#define AUDREC_CMD_PARAM_BUF_BASIC_VER		0x0000
+
+typedef struct {
+	unsigned short 	cmd_id;
+	unsigned short	ptr_to_extpkt_buffer_msw;
+	unsigned short	ptr_to_extpkt_buffer_lsw;
+	unsigned short	buf_len;
+	unsigned short	param_buf;
+	unsigned short	bit_rate_0;
+	unsigned short	bit_rate_1;
+} __attribute__((packed)) audrec_cmd_arec1param_cfg;
+
+
+/*
+ * Commands on audRecUpBitStreamQueue
+ */
+
+/*
+ * Command to indicate the current packet read count
+ */
+
+#define AUDREC_CMD_PACKET_EXT_PTR		0x0000
+#define AUDREC_CMD_PACKET_EXT_PTR_LEN	\
+	sizeof(audrec_cmd_packet_ext_ptr)
+
+#define AUDREC_CMD_TYPE_0	0x0000
+#define AUDREC_CMD_TYPE_1	0x0001
+
+typedef struct {
+	unsigned short  cmd_id;
+	unsigned short	type;
+	unsigned short 	curr_rec_count_msw;
+	unsigned short 	curr_rec_count_lsw;
+} __attribute__((packed)) audrec_cmd_packet_ext_ptr;
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,127 @@
+#ifndef QDSP5AUDRECMSGI_H
+#define QDSP5AUDRECMSGI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+    A U D I O   R E C O R D  M E S S A G E S
+
+GENERAL DESCRIPTION
+  This file contains defintions of format blocks of messages
+  that are sent by AUDREC Task
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+  None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+ $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audrecmsg.h#3 $
+
+============================================================================*/
+
+/*
+ * AUDRECTASK MESSAGES
+ * AUDRECTASK uses audRecUpRlist to communicate with ARM
+ * Location : MEMC
+ * Buffer size : 4
+ * No of buffers in a queue : 2
+ */
+
+/*
+ * Message to notify that config command is done
+ */
+
+#define AUDREC_MSG_CMD_CFG_DONE_MSG	0x0002
+#define AUDREC_MSG_CMD_CFG_DONE_MSG_LEN	\
+	sizeof(audrec_msg_cmd_cfg_done_msg)
+
+
+#define AUDREC_MSG_CFG_DONE_TYPE_0_ENA		0x4000
+#define AUDREC_MSG_CFG_DONE_TYPE_0_DIS		0x0000
+
+#define AUDREC_MSG_CFG_DONE_TYPE_0_NO_UPDATE	0x0000
+#define AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE	0x8000
+
+#define AUDREC_MSG_CFG_DONE_TYPE_1_ENA		0x4000
+#define AUDREC_MSG_CFG_DONE_TYPE_1_DIS		0x0000
+
+#define AUDREC_MSG_CFG_DONE_TYPE_1_NO_UPDATE	0x0000
+#define AUDREC_MSG_CFG_DONE_TYPE_1_UPDATE	0x8000
+
+typedef struct {
+	unsigned short	type_0;
+	unsigned short	type_1;
+} __attribute__((packed))audrec_msg_cmd_cfg_done_msg;
+
+
+/*
+ * Message to notify arec0/1 cfg done and recording params revd by task
+ */
+
+#define	AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG		0x0003
+#define	AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG_LEN	\
+	sizeof(audrec_msg_cmd_arec_param_cfg_done_msg)
+
+#define	AUDREC_MSG_AREC_PARAM_TYPE_0	0x0000
+#define	AUDREC_MSG_AREC_PARAM_TYPE_1	0x0001
+
+typedef struct {
+	unsigned short	type;
+} __attribute__((packed))audrec_msg_cmd_arec_param_cfg_done_msg;
+
+
+/*
+ * Message to notify no more buffers are available in ext mem to DME
+ */
+
+#define AUDREC_MSG_FATAL_ERR_MSG		0x0004
+#define AUDREC_MSG_FATAL_ERR_MSG_LEN	\
+	sizeof(audrec_msg_fatal_err_msg)
+
+#define AUDREC_MSG_FATAL_ERR_TYPE_0	0x0000
+#define AUDREC_MSG_FATAL_ERR_TYPE_1	0x0001
+
+typedef struct {
+	unsigned short	type;
+} __attribute__((packed))audrec_msg_fatal_err_msg;
+
+/*
+ * Message to notify DME deliverd the encoded pkt to ext pkt buffer
+ */
+
+#define AUDREC_MSG_PACKET_READY_MSG		0x0005
+#define AUDREC_MSG_PACKET_READY_MSG_LEN	\
+	sizeof(audrec_msg_packet_ready_msg)
+
+#define AUDREC_MSG_PACKET_READY_TYPE_0	0x0000
+#define AUDREC_MSG_PACKET_READY_TYPE_1	0x0001
+
+typedef struct {
+	unsigned short	type;
+	unsigned short	pkt_counter_msw;
+	unsigned short	pkt_counter_lsw;
+	unsigned short	pkt_read_cnt_msw;
+	unsigned short	pkt_read_cnt_lsw;
+} __attribute__((packed))audrec_msg_packet_ready_msg;
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,376 @@
+#ifndef QDSP5VIDJPEGCMDI_H
+#define QDSP5VIDJPEGCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+    J P E G  I N T E R N A L  C O M M A N D S
+
+GENERAL DESCRIPTION
+  This file contains defintions of format blocks of commands
+  that are accepted by JPEG Task
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+  None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+when       who     what, where, why
+--------   ---     ----------------------------------------------------------
+06/09/08   sv      initial version
+===========================================================================*/
+
+/*
+ * ARM to JPEG configuration commands are passed through the
+ * uPJpegCfgCmdQueue
+ */
+
+/*
+ * Command to configure JPEG Encoder
+ */
+
+#define	JPEG_CMD_ENC_CFG		0x0000
+#define	JPEG_CMD_ENC_CFG_LEN	sizeof(jpeg_cmd_enc_cfg)
+
+#define	JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_0		0x0000
+#define	JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_90		0x0100
+#define	JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_180	0x0200
+#define	JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_270	0x0300
+#define	JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_M	0x0003
+#define	JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V2	0x0000
+#define	JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V1	0x0001
+#define	JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H1V2	0x0002
+
+#define	JPEG_CMD_IP_SIZE_CFG_LUMA_HEIGHT_M		0x0000FFFF
+#define	JPEG_CMD_IP_SIZE_CFG_LUMA_WIDTH_M		0xFFFF0000
+#define	JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_ENA		0x0001
+#define	JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_DIS		0x0000
+
+#define	JPEG_CMD_FRAG_SIZE_LUMA_HEIGHT_M		0xFFFF
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	process_cfg;
+	unsigned int	ip_size_cfg;
+	unsigned int	op_size_cfg;
+	unsigned int	frag_cfg;
+	unsigned int	frag_cfg_part[16];
+
+	unsigned int    part_num;
+
+	unsigned int	op_buf_0_cfg_part1;
+	unsigned int	op_buf_0_cfg_part2;
+	unsigned int	op_buf_1_cfg_part1;
+	unsigned int	op_buf_1_cfg_part2;
+
+	unsigned int	luma_qunt_table[32];
+	unsigned int	chroma_qunt_table[32];
+
+	unsigned int	upsamp_ip_size_cfg;
+	unsigned int	upsamp_ip_frame_off;
+	unsigned int	upsamp_pp_filter_coeff[64];
+} __attribute__((packed)) jpeg_cmd_enc_cfg;
+
+/*
+ * Command to configure JPEG Decoder
+ */
+
+#define	JPEG_CMD_DEC_CFG		0x0001
+#define	JPEG_CMD_DEC_CFG_LEN		sizeof(jpeg_cmd_dec_cfg)
+
+#define	JPEG_CMD_DEC_OP_DATA_FORMAT_M		0x0001
+#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2	0x0000
+#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V1	0x0001
+
+#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_8	0x000000
+#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_4	0x010000
+#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_2	0x020000
+#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_1	0x030000
+
+#define	JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_NOT_FINAL	0x0000
+#define	JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_FINAL	0x0001
+
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	img_dimension_cfg;
+	unsigned int	op_data_format;
+	unsigned int	restart_interval;
+	unsigned int	ip_buf_partition_num;
+	unsigned int	ip_stream_buf_cfg_part1;
+	unsigned int	ip_stream_buf_cfg_part2;
+	unsigned int	ip_stream_buf_cfg_part3;
+	unsigned int	op_stream_buf_0_cfg_part1;
+	unsigned int	op_stream_buf_0_cfg_part2;
+	unsigned int	op_stream_buf_0_cfg_part3;
+	unsigned int	op_stream_buf_1_cfg_part1;
+	unsigned int	op_stream_buf_1_cfg_part2;
+	unsigned int	op_stream_buf_1_cfg_part3;
+	unsigned int	luma_qunt_table_0_3;
+	unsigned int	luma_qunt_table_4_7;
+	unsigned int	luma_qunt_table_8_11;
+	unsigned int	luma_qunt_table_12_15;
+	unsigned int	luma_qunt_table_16_19;
+	unsigned int	luma_qunt_table_20_23;
+	unsigned int	luma_qunt_table_24_27;
+	unsigned int	luma_qunt_table_28_31;
+	unsigned int	luma_qunt_table_32_35;
+	unsigned int	luma_qunt_table_36_39;
+	unsigned int	luma_qunt_table_40_43;
+	unsigned int	luma_qunt_table_44_47;
+	unsigned int	luma_qunt_table_48_51;
+	unsigned int	luma_qunt_table_52_55;
+	unsigned int	luma_qunt_table_56_59;
+	unsigned int	luma_qunt_table_60_63;
+	unsigned int	chroma_qunt_table_0_3;
+	unsigned int	chroma_qunt_table_4_7;
+	unsigned int	chroma_qunt_table_8_11;
+	unsigned int	chroma_qunt_table_12_15;
+	unsigned int	chroma_qunt_table_16_19;
+	unsigned int	chroma_qunt_table_20_23;
+	unsigned int	chroma_qunt_table_24_27;
+	unsigned int	chroma_qunt_table_28_31;
+	unsigned int	chroma_qunt_table_32_35;
+	unsigned int	chroma_qunt_table_36_39;
+	unsigned int	chroma_qunt_table_40_43;
+	unsigned int	chroma_qunt_table_44_47;
+	unsigned int	chroma_qunt_table_48_51;
+	unsigned int	chroma_qunt_table_52_55;
+	unsigned int	chroma_qunt_table_56_59;
+	unsigned int	chroma_qunt_table_60_63;
+	unsigned int	luma_dc_hm_code_cnt_table_0_3;
+	unsigned int	luma_dc_hm_code_cnt_table_4_7;
+	unsigned int	luma_dc_hm_code_cnt_table_8_11;
+	unsigned int	luma_dc_hm_code_cnt_table_12_15;
+	unsigned int	luma_dc_hm_code_val_table_0_3;
+	unsigned int	luma_dc_hm_code_val_table_4_7;
+	unsigned int	luma_dc_hm_code_val_table_8_11;
+	unsigned int	chroma_dc_hm_code_cnt_table_0_3;
+	unsigned int	chroma_dc_hm_code_cnt_table_4_7;
+	unsigned int	chroma_dc_hm_code_cnt_table_8_11;
+	unsigned int	chroma_dc_hm_code_cnt_table_12_15;
+	unsigned int	chroma_dc_hm_code_val_table_0_3;
+	unsigned int	chroma_dc_hm_code_val_table_4_7;
+	unsigned int	chroma_dc_hm_code_val_table_8_11;
+	unsigned int	luma_ac_hm_code_cnt_table_0_3;
+	unsigned int	luma_ac_hm_code_cnt_table_4_7;
+	unsigned int	luma_ac_hm_code_cnt_table_8_11;
+	unsigned int	luma_ac_hm_code_cnt_table_12_15;
+	unsigned int	luma_ac_hm_code_val_table_0_3;
+	unsigned int	luma_ac_hm_code_val_table_4_7;
+	unsigned int	luma_ac_hm_code_val_table_8_11;
+	unsigned int	luma_ac_hm_code_val_table_12_15;
+	unsigned int	luma_ac_hm_code_val_table_16_19;
+	unsigned int	luma_ac_hm_code_val_table_20_23;
+	unsigned int	luma_ac_hm_code_val_table_24_27;
+	unsigned int	luma_ac_hm_code_val_table_28_31;
+	unsigned int	luma_ac_hm_code_val_table_32_35;
+	unsigned int	luma_ac_hm_code_val_table_36_39;
+	unsigned int	luma_ac_hm_code_val_table_40_43;
+	unsigned int	luma_ac_hm_code_val_table_44_47;
+	unsigned int	luma_ac_hm_code_val_table_48_51;
+	unsigned int	luma_ac_hm_code_val_table_52_55;
+	unsigned int	luma_ac_hm_code_val_table_56_59;
+	unsigned int	luma_ac_hm_code_val_table_60_63;
+	unsigned int	luma_ac_hm_code_val_table_64_67;
+	unsigned int	luma_ac_hm_code_val_table_68_71;
+	unsigned int	luma_ac_hm_code_val_table_72_75;
+	unsigned int	luma_ac_hm_code_val_table_76_79;
+	unsigned int	luma_ac_hm_code_val_table_80_83;
+	unsigned int	luma_ac_hm_code_val_table_84_87;
+	unsigned int	luma_ac_hm_code_val_table_88_91;
+	unsigned int	luma_ac_hm_code_val_table_92_95;
+	unsigned int	luma_ac_hm_code_val_table_96_99;
+	unsigned int	luma_ac_hm_code_val_table_100_103;
+	unsigned int	luma_ac_hm_code_val_table_104_107;
+	unsigned int	luma_ac_hm_code_val_table_108_111;
+	unsigned int	luma_ac_hm_code_val_table_112_115;
+	unsigned int	luma_ac_hm_code_val_table_116_119;
+	unsigned int	luma_ac_hm_code_val_table_120_123;
+	unsigned int	luma_ac_hm_code_val_table_124_127;
+	unsigned int	luma_ac_hm_code_val_table_128_131;
+	unsigned int	luma_ac_hm_code_val_table_132_135;
+	unsigned int	luma_ac_hm_code_val_table_136_139;
+	unsigned int	luma_ac_hm_code_val_table_140_143;
+	unsigned int	luma_ac_hm_code_val_table_144_147;
+	unsigned int	luma_ac_hm_code_val_table_148_151;
+	unsigned int	luma_ac_hm_code_val_table_152_155;
+	unsigned int	luma_ac_hm_code_val_table_156_159;
+	unsigned int	luma_ac_hm_code_val_table_160_161;
+	unsigned int	chroma_ac_hm_code_cnt_table_0_3;
+	unsigned int	chroma_ac_hm_code_cnt_table_4_7;
+	unsigned int	chroma_ac_hm_code_cnt_table_8_11;
+	unsigned int	chroma_ac_hm_code_cnt_table_12_15;
+	unsigned int	chroma_ac_hm_code_val_table_0_3;
+	unsigned int	chroma_ac_hm_code_val_table_4_7;
+	unsigned int	chroma_ac_hm_code_val_table_8_11;
+	unsigned int	chroma_ac_hm_code_val_table_12_15;
+	unsigned int	chroma_ac_hm_code_val_table_16_19;
+	unsigned int	chroma_ac_hm_code_val_table_20_23;
+	unsigned int	chroma_ac_hm_code_val_table_24_27;
+	unsigned int	chroma_ac_hm_code_val_table_28_31;
+	unsigned int	chroma_ac_hm_code_val_table_32_35;
+	unsigned int	chroma_ac_hm_code_val_table_36_39;
+	unsigned int	chroma_ac_hm_code_val_table_40_43;
+	unsigned int	chroma_ac_hm_code_val_table_44_47;
+	unsigned int	chroma_ac_hm_code_val_table_48_51;
+	unsigned int	chroma_ac_hm_code_val_table_52_55;
+	unsigned int	chroma_ac_hm_code_val_table_56_59;
+	unsigned int	chroma_ac_hm_code_val_table_60_63;
+	unsigned int	chroma_ac_hm_code_val_table_64_67;
+	unsigned int	chroma_ac_hm_code_val_table_68_71;
+	unsigned int	chroma_ac_hm_code_val_table_72_75;
+	unsigned int	chroma_ac_hm_code_val_table_76_79;
+	unsigned int	chroma_ac_hm_code_val_table_80_83;
+	unsigned int	chroma_ac_hm_code_val_table_84_87;
+	unsigned int	chroma_ac_hm_code_val_table_88_91;
+	unsigned int	chroma_ac_hm_code_val_table_92_95;
+	unsigned int	chroma_ac_hm_code_val_table_96_99;
+	unsigned int	chroma_ac_hm_code_val_table_100_103;
+	unsigned int	chroma_ac_hm_code_val_table_104_107;
+	unsigned int	chroma_ac_hm_code_val_table_108_111;
+	unsigned int	chroma_ac_hm_code_val_table_112_115;
+	unsigned int	chroma_ac_hm_code_val_table_116_119;
+	unsigned int	chroma_ac_hm_code_val_table_120_123;
+	unsigned int	chroma_ac_hm_code_val_table_124_127;
+	unsigned int	chroma_ac_hm_code_val_table_128_131;
+	unsigned int	chroma_ac_hm_code_val_table_132_135;
+	unsigned int	chroma_ac_hm_code_val_table_136_139;
+	unsigned int	chroma_ac_hm_code_val_table_140_143;
+	unsigned int	chroma_ac_hm_code_val_table_144_147;
+	unsigned int	chroma_ac_hm_code_val_table_148_151;
+	unsigned int	chroma_ac_hm_code_val_table_152_155;
+	unsigned int	chroma_ac_hm_code_val_table_156_159;
+	unsigned int	chroma_ac_hm_code_val_table_160_161;
+} __attribute__((packed)) jpeg_cmd_dec_cfg;
+
+
+/*
+ * ARM to JPEG configuration commands are passed through the
+ * uPJpegActionCmdQueue
+ */
+
+/*
+ * Command to start the encode process
+ */
+
+#define	JPEG_CMD_ENC_ENCODE		0x0000
+#define	JPEG_CMD_ENC_ENCODE_LEN		sizeof(jpeg_cmd_enc_encode)
+
+
+typedef struct {
+	unsigned short	cmd_id;
+} __attribute__((packed)) jpeg_cmd_enc_encode;
+
+
+/*
+ * Command to transition from current state of encoder to IDLE state
+ */
+
+#define	JPEG_CMD_ENC_IDLE		0x0001
+#define	JPEG_CMD_ENC_IDLE_LEN		sizeof(jpeg_cmd_enc_idle)
+
+
+typedef struct {
+	unsigned short	cmd_id;
+} __attribute__((packed)) jpeg_cmd_enc_idle;
+
+
+/*
+ * Command to inform the encoder that another buffer is ready
+ */
+
+#define	JPEG_CMD_ENC_OP_CONSUMED	0x0002
+#define	JPEG_CMD_ENC_OP_CONSUMED_LEN	sizeof(jpeg_cmd_enc_op_consumed)
+
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	op_buf_addr;
+	unsigned int	op_buf_size;
+} __attribute__((packed)) jpeg_cmd_enc_op_consumed;
+
+
+/*
+ * Command to start the decoding process
+ */
+
+#define	JPEG_CMD_DEC_DECODE		0x0003
+#define	JPEG_CMD_DEC_DECODE_LEN	sizeof(jpeg_cmd_dec_decode)
+
+
+typedef struct {
+	unsigned short	cmd_id;
+} __attribute__((packed)) jpeg_cmd_dec_decode;
+
+
+/*
+ * Command to transition from the current state of decoder to IDLE
+ */
+
+#define	JPEG_CMD_DEC_IDLE	0x0004
+#define	JPEG_CMD_DEC_IDLE_LEN	sizeof(jpeg_cmd_dec_idle)
+
+
+typedef struct {
+	unsigned short	cmd_id;
+} __attribute__((packed)) jpeg_cmd_dec_idle;
+
+
+/*
+ * Command to inform that an op buffer is ready for use
+ */
+
+#define	JPEG_CMD_DEC_OP_CONSUMED	0x0005
+#define	JPEG_CMD_DEC_OP_CONSUMED_LEN	sizeof(jpeg_cmd_dec_op_consumed)
+
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	luma_op_buf_addr;
+	unsigned int	luma_op_buf_size;
+	unsigned int	chroma_op_buf_addr;
+} __attribute__((packed)) jpeg_cmd_dec_op_consumed;
+
+
+/*
+ * Command to pass a new ip buffer to the jpeg decoder
+ */
+
+#define	JPEG_CMD_DEC_IP	0x0006
+#define	JPEG_CMD_DEC_IP_LEN	sizeof(jpeg_cmd_dec_ip_len)
+
+#define	JPEG_CMD_EOI_INDICATOR_NOT_END	0x0000
+#define	JPEG_CMD_EOI_INDICATOR_END	0x0001
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	ip_buf_addr;
+	unsigned int	ip_buf_size;
+	unsigned int	eoi_indicator;
+} __attribute__((packed)) jpeg_cmd_dec_ip;
+
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,177 @@
+#ifndef QDSP5VIDJPEGMSGI_H
+#define QDSP5VIDJPEGMSGI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+   J P E G  I N T E R N A L  M E S S A G E S
+
+GENERAL DESCRIPTION
+  This file contains defintions of format blocks of messages
+  that are sent by JPEG Task
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+  None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+
+when       who     what, where, why
+--------   ---     ----------------------------------------------------------
+05/10/08   sv      initial version
+===========================================================================*/
+
+/*
+ * Messages from JPEG task to ARM through jpeguPMsgQueue
+ */
+
+/*
+ * Message is ACK for CMD_JPEGE_ENCODE cmd
+ */
+
+#define	JPEG_MSG_ENC_ENCODE_ACK	0x0000
+#define	JPEG_MSG_ENC_ENCODE_ACK_LEN	\
+	sizeof(jpeg_msg_enc_encode_ack)
+
+typedef struct {
+} __attribute__((packed)) jpeg_msg_enc_encode_ack;
+
+
+/*
+ * Message informs the up when op buffer is ready for consumption and
+ * when encoding is complete or errors
+ */
+
+#define	JPEG_MSG_ENC_OP_PRODUCED	0x0001
+#define	JPEG_MSG_ENC_OP_PRODUCED_LEN	\
+	sizeof(jpeg_msg_enc_op_produced)
+
+#define	JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_PROGRESS	0x0000
+#define	JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_COMPLETE	0x0001
+#define	JPEG_MSGOP_OP_BUF_STATUS_ENC_ERR		0x10000
+
+typedef struct {
+	unsigned int	op_buf_addr;
+	unsigned int	op_buf_size;
+	unsigned int	op_buf_status;
+} __attribute__((packed)) jpeg_msg_enc_op_produced;
+
+
+/*
+ * Message to ack CMD_JPEGE_IDLE
+ */
+
+#define	JPEG_MSG_ENC_IDLE_ACK	0x0002
+#define	JPEG_MSG_ENC_IDLE_ACK_LEN	sizeof(jpeg_msg_enc_idle_ack)
+
+
+typedef struct {
+} __attribute__ ((packed)) jpeg_msg_enc_idle_ack;
+
+
+/*
+ * Message to indicate the illegal command
+ */
+
+#define	JPEG_MSG_ENC_ILLEGAL_COMMAND	0x0003
+#define	JPEG_MSG_ENC_ILLEGAL_COMMAND_LEN	\
+	sizeof(jpeg_msg_enc_illegal_command)
+
+typedef struct {
+	unsigned int	status;
+} __attribute__((packed)) jpeg_msg_enc_illegal_command;
+
+
+/*
+ * Message to ACK CMD_JPEGD_DECODE
+ */
+
+#define	JPEG_MSG_DEC_DECODE_ACK		0x0004
+#define	JPEG_MSG_DEC_DECODE_ACK_LEN	\
+	sizeof(jpeg_msg_dec_decode_ack)
+
+
+typedef struct {
+} __attribute__((packed)) jpeg_msg_dec_decode_ack;
+
+
+/*
+ * Message to inform up that an op buffer is ready for consumption and when
+ * decoding is complete or an error occurs
+ */
+
+#define	JPEG_MSG_DEC_OP_PRODUCED		0x0005
+#define	JPEG_MSG_DEC_OP_PRODUCED_LEN	\
+	sizeof(jpeg_msg_dec_op_produced)
+
+#define	JPEG_MSG_DEC_OP_BUF_STATUS_PROGRESS	0x0000
+#define	JPEG_MSG_DEC_OP_BUF_STATUS_DONE		0x0001
+
+typedef struct {
+	unsigned int	luma_op_buf_addr;
+	unsigned int	chroma_op_buf_addr;
+	unsigned int	num_mcus;
+	unsigned int	op_buf_status;
+} __attribute__((packed)) jpeg_msg_dec_op_produced;
+
+/*
+ * Message to ack CMD_JPEGD_IDLE cmd
+ */
+
+#define	JPEG_MSG_DEC_IDLE_ACK	0x0006
+#define	JPEG_MSG_DEC_IDLE_ACK_LEN	sizeof(jpeg_msg_dec_idle_ack)
+
+
+typedef struct {
+} __attribute__((packed)) jpeg_msg_dec_idle_ack;
+
+
+/*
+ * Message to indicate illegal cmd was received
+ */
+
+#define	JPEG_MSG_DEC_ILLEGAL_COMMAND	0x0007
+#define	JPEG_MSG_DEC_ILLEGAL_COMMAND_LEN	\
+	sizeof(jpeg_msg_dec_illegal_command)
+
+
+typedef struct {
+	unsigned int	status;
+} __attribute__((packed)) jpeg_msg_dec_illegal_command;
+
+/*
+ * Message to request up for the next segment of ip bit stream
+ */
+
+#define	JPEG_MSG_DEC_IP_REQUEST		0x0008
+#define	JPEG_MSG_DEC_IP_REQUEST_LEN	\
+	sizeof(jpeg_msg_dec_ip_request)
+
+
+typedef struct {
+} __attribute__((packed)) jpeg_msg_dec_ip_request;
+
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,82 @@
+#ifndef QDSP5LPMCMDI_H
+#define QDSP5LPMCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+    L P M   I N T E R N A L   C O M M A N D S
+
+GENERAL DESCRIPTION
+  This file contains defintions of format blocks of commands
+  that are accepted by LPM Task
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+  None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+
+when       who     what, where, why
+--------   ---     ----------------------------------------------------------
+06/12/08   sv      initial version
+===========================================================================*/
+
+
+/*
+ * Command to start LPM processing based on the config params
+ */
+
+#define	LPM_CMD_START		0x0000
+#define	LPM_CMD_START_LEN	sizeof(lpm_cmd_start)
+
+#define	LPM_CMD_SPATIAL_FILTER_PART_OPMODE_0	0x00000000
+#define	LPM_CMD_SPATIAL_FILTER_PART_OPMODE_1	0x00010000
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	ip_data_cfg_part1;
+	unsigned int	ip_data_cfg_part2;
+	unsigned int	ip_data_cfg_part3;
+	unsigned int	ip_data_cfg_part4;
+	unsigned int	op_data_cfg_part1;
+	unsigned int	op_data_cfg_part2;
+	unsigned int	op_data_cfg_part3;
+	unsigned int	spatial_filter_part[32];
+} __attribute__((packed)) lpm_cmd_start;
+
+
+
+/*
+ * Command to stop LPM processing
+ */
+
+#define	LPM_CMD_IDLE		0x0001
+#define	LPM_CMD_IDLE_LEN	sizeof(lpm_cmd_idle)
+
+typedef struct {
+	unsigned int	cmd_id;
+} __attribute__((packed)) lpm_cmd_idle;
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,80 @@
+#ifndef QDSP5LPMMSGI_H
+#define QDSP5LPMMSGI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+    L P M   I N T E R N A L   M E S S A G E S
+
+GENERAL DESCRIPTION
+  This file contains defintions of format blocks of commands
+  that are accepted by LPM Task
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+  None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+
+when       who     what, where, why
+--------   ---     ----------------------------------------------------------
+06/12/08   sv      initial version
+===========================================================================*/
+
+/*
+ * Message to acknowledge CMD_LPM_IDLE command
+ */
+
+#define	LPM_MSG_IDLE_ACK	0x0000
+#define	LPM_MSG_IDLE_ACK_LEN	sizeof(lpm_msg_idle_ack)
+
+typedef struct {
+} __attribute__((packed)) lpm_msg_idle_ack;
+
+
+/*
+ * Message to acknowledge CMD_LPM_START command
+ */
+
+
+#define	LPM_MSG_START_ACK	0x0001
+#define	LPM_MSG_START_ACK_LEN	sizeof(lpm_msg_start_ack)
+
+
+typedef struct {
+} __attribute__((packed)) lpm_msg_start_ack;
+
+
+/*
+ * Message to notify the ARM that LPM processing is complete
+ */
+
+#define	LPM_MSG_DONE		0x0002
+#define	LPM_MSG_DONE_LEN	sizeof(lpm_msg_done)
+
+typedef struct {
+} __attribute__((packed)) lpm_msg_done;
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,235 @@
+#ifndef QDSP5VIDDECCMDI_H
+#define QDSP5VIDDECCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+    V I D E O  D E C O D E R  I N T E R N A L  C O M M A N D S
+
+GENERAL DESCRIPTION
+  This file contains defintions of format blocks of commands
+  that are accepted by VIDDEC Task
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+  None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdeccmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+
+when       who     what, where, why
+--------   ---     ----------------------------------------------------------
+05/10/08   ac      initial version
+===========================================================================*/
+
+
+/*
+ * Command to inform VIDDEC that new subframe packet is ready
+ */
+
+#define	VIDDEC_CMD_SUBFRAME_PKT		0x0000
+#define	VIDDEC_CMD_SUBFRAME_PKT_LEN \
+	sizeof(viddec_cmd_subframe_pkt)
+
+#define	VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DM		0x0000
+#define	VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DMA 	0x0001
+
+#define	VIDDEC_CMD_SF_INFO_0_SUBFRAME_CONTI		0x0000
+#define	VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST		0x0001
+#define	VIDDEC_CMD_SF_INFO_0_SUBFRAME_LAST		0x0002
+#define	VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST_AND_LAST 	0x0003
+
+#define	VIDDEC_CMD_CODEC_SELECTION_WORD_MPEG_4		0x0000
+#define	VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_P0	0x0001
+#define	VIDDEC_CMD_CODEC_SELECTION_WORD_H_264		0x0002
+#define	VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_p3	0x0003
+#define	VIDDEC_CMD_CODEC_SELECTION_WORD_RV9		0x0004
+#define	VIDDEC_CMD_CODEC_SELECTION_WORD_WMV9		0x0005
+#define	VIDDEC_CMD_CODEC_SELECTION_WORD_SMCDB		0x0006
+#define	VIDDEC_CMD_CODEC_SELECTION_WORD_QFRE		0x0007
+#define	VIDDEC_CMD_CODEC_SELECTION_WORD_VLD		0x0008
+
+typedef struct {
+	unsigned short	cmd_id;
+	unsigned short	packet_seq_number;
+	unsigned short	codec_instance_id;
+	unsigned short	subframe_packet_size_high;
+	unsigned short	subframe_packet_size_low;
+	unsigned short	subframe_packet_high;
+	unsigned short	subframe_packet_low;
+	unsigned short	subframe_packet_partition;
+	unsigned short	statistics_packet_size_high;
+	unsigned short	statistics_packet_size_low;
+	unsigned short	statistics_packet_high;
+	unsigned short	statistics_packet_low;
+	unsigned short	statistics_partition;
+	unsigned short	subframe_info_1;
+	unsigned short	subframe_info_0;
+	unsigned short	codec_selection_word;
+	unsigned short	num_mbs;
+} __attribute__((packed)) viddec_cmd_subframe_pkt;
+
+
+/*
+ * Command to inform VIDDEC task that post processing is required for the frame
+ */
+
+#define	VIDDEC_CMD_PP_ENABLE		0x0001
+#define	VIDDEC_CMD_PP_ENABLE_LEN \
+	sizeof(viddec_cmd_pp_enable)
+
+#define	VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DM		0x0000
+#define	VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DMA	0x0001
+
+typedef struct {
+	unsigned short	cmd_id;
+	unsigned short	packet_seq_num;
+	unsigned short	codec_instance_id;
+	unsigned short	postproc_info_0;
+	unsigned short	codec_selection_word;
+	unsigned short	pp_output_addr_high;
+	unsigned short	pp_output_addr_low;
+	unsigned short	postproc_info_1;
+	unsigned short	load_sharing_packet_size_high;
+	unsigned short	load_sharing_packet_size_low;
+	unsigned short	load_sharing_packet_high;
+	unsigned short	load_sharing_packet_low;
+	unsigned short	load_sharing_partition;
+	unsigned short	pp_param_0;
+	unsigned short	pp_param_1;
+	unsigned short	pp_param_2;
+	unsigned short	pp_param_3;
+} __attribute__((packed)) viddec_cmd_pp_enable;
+
+
+/*
+ * FRAME Header Packet : It is at the start of new frame
+ */
+
+#define	VIDDEC_CMD_FRAME_HEADER_PACKET	0x0002
+#define	VIDDEC_CMD_FRAME_HEADER_PACKET_LEN	\
+	sizeof(viddec_cmd_frame_header_packet)
+
+#define	VIDDEC_CMD_FRAME_INFO_0_ERROR_SKIP	0x0000
+#define	VIDDEC_CMD_FRAME_INFO_0_ERROR_BLACK	0x0800
+
+typedef struct {
+	unsigned short	packet_id;
+	unsigned short	x_dimension;
+	unsigned short	y_dimension;
+	unsigned short	line_width;
+	unsigned short	frame_info_0;
+	unsigned short	frame_buffer_0_high;
+	unsigned short	frame_buffer_0_low;
+	unsigned short	frame_buffer_1_high;
+	unsigned short	frame_buffer_1_low;
+	unsigned short	frame_buffer_2_high;
+	unsigned short	frame_buffer_2_low;
+	unsigned short	frame_buffer_3_high;
+	unsigned short	frame_buffer_3_low;
+	unsigned short	frame_buffer_4_high;
+	unsigned short	frame_buffer_4_low;
+	unsigned short	frame_buffer_5_high;
+	unsigned short	frame_buffer_5_low;
+	unsigned short	frame_buffer_6_high;
+	unsigned short	frame_buffer_6_low;
+	unsigned short	frame_buffer_7_high;
+	unsigned short	frame_buffer_7_low;
+	unsigned short	frame_buffer_8_high;
+	unsigned short	frame_buffer_8_low;
+	unsigned short	frame_buffer_9_high;
+	unsigned short	frame_buffer_9_low;
+	unsigned short	frame_buffer_10_high;
+	unsigned short	frame_buffer_10_low;
+	unsigned short	frame_buffer_11_high;
+	unsigned short	frame_buffer_11_low;
+	unsigned short	frame_buffer_12_high;
+	unsigned short	frame_buffer_12_low;
+	unsigned short	frame_buffer_13_high;
+	unsigned short	frame_buffer_13_low;
+	unsigned short	frame_buffer_14_high;
+	unsigned short	frame_buffer_14_low;
+	unsigned short	frame_buffer_15_high;
+	unsigned short	frame_buffer_15_low;
+	unsigned short	output_frame_buffer_high;
+	unsigned short	output_frame_buffer_low;
+	unsigned short	end_of_packet_marker;
+} __attribute__((packed)) viddec_cmd_frame_header_packet;
+
+
+/*
+ * SLICE HEADER PACKET
+ * I-Slice and P-Slice
+ */
+
+#define	VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE		0x0003
+#define	VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE_LEN	\
+	sizeof(viddec_cmd_slice_header_pkt_islice)
+
+#define	VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_PSLICE	0x0000
+#define	VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_BSLICE	0x0100
+#define	VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_ISLICE	0x0200
+#define	VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SPSLICE	0x0300
+#define	VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SISLICE	0x0400
+#define	VIDDEC_CMD_ISLICE_INFO_1_NOPADDING	0x0000
+#define	VIDDEC_CMD_ISLICE_INFO_1_PADDING	0x0800
+
+#define	VIDDEC_CMD_ISLICE_EOP_MARKER		0x7FFF
+
+typedef struct {
+	unsigned short	cmd_id;
+	unsigned short	packet_id;
+	unsigned short	slice_info_0;
+	unsigned short	slice_info_1;
+	unsigned short	slice_info_2;
+	unsigned short	num_bytes_in_rbsp_high;
+	unsigned short	num_bytes_in_rbsp_low;
+	unsigned short	num_bytes_in_rbsp_consumed;
+	unsigned short	end_of_packet_marker;
+} __attribute__((packed)) viddec_cmd_slice_header_pkt_islice;
+
+
+#define	VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE		0x0003
+#define	VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE_LEN	\
+	sizeof(viddec_cmd_slice_header_pkt_pslice)
+
+
+typedef struct {
+	unsigned short	cmd_id;
+	unsigned short	packet_id;
+	unsigned short	slice_info_0;
+	unsigned short	slice_info_1;
+	unsigned short	slice_info_2;
+	unsigned short	slice_info_3;
+	unsigned short	refidx_l0_map_tab_info_0;
+	unsigned short	refidx_l0_map_tab_info_1;
+	unsigned short	refidx_l0_map_tab_info_2;
+	unsigned short	refidx_l0_map_tab_info_3;
+	unsigned short	num_bytes_in_rbsp_high;
+	unsigned short	num_bytes_in_rbsp_low;
+	unsigned short	num_bytes_in_rbsp_consumed;
+	unsigned short	end_of_packet_marker;
+} __attribute__((packed)) viddec_cmd_slice_header_pkt_pslice;
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,107 @@
+#ifndef QDSP5VIDDECMSGI_H
+#define QDSP5VIDDECMSGI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+    V I D E O  D E C O D E R   I N T E R N A L  M E S S A G E S
+
+GENERAL DESCRIPTION
+  This file contains defintions of format blocks of messages
+  that are sent by VIDDEC Task
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+  None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdecmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+
+when       who     what, where, why
+--------   ---     ----------------------------------------------------------
+05/10/08   ac      initial version
+===========================================================================*/
+
+/*
+ * Message to inform ARM which VDEC_SUBFRAME_PKT_CMD processed by VIDDEC TASK
+ */
+
+#define	VIDDEC_MSG_SUBF_DONE	0x0000
+#define	VIDDEC_MSG_SUBF_DONE_LEN	\
+	sizeof(viddec_msg_subf_done)
+
+typedef struct {
+	unsigned short	packet_seq_number;
+	unsigned short	codec_instance_id;
+} __attribute__((packed)) viddec_msg_subf_done;
+
+
+/*
+ * Message to inform ARM one frame has been decoded
+ */
+
+#define	VIDDEC_MSG_FRAME_DONE	0x0001
+#define	VIDDEC_MSG_FRAME_DONE_LEN	\
+	sizeof(viddec_msg_frame_done)
+
+typedef struct {
+	unsigned short	packet_seq_number;
+	unsigned short	codec_instance_id;
+} __attribute__((packed)) viddec_msg_frame_done;
+
+
+/*
+ * Message to inform ARM that post processing frame has been decoded
+ */
+
+#define	VIDDEC_MSG_PP_ENABLE_CMD_DONE	0x0002
+#define	VIDDEC_MSG_PP_ENABLE_CMD_DONE_LEN	\
+	sizeof(viddec_msg_pp_enable_cmd_done)
+
+typedef struct {
+	unsigned short	packet_seq_number;
+	unsigned short	codec_instance_id;
+} __attribute__((packed)) viddec_msg_pp_enable_cmd_done;
+
+
+/*
+ * Message to inform ARM that one post processing frame has been decoded
+ */
+
+
+#define	VIDDEC_MSG_PP_FRAME_DONE		0x0003
+#define	VIDDEC_MSG_PP_FRAME_DONE_LEN	\
+	sizeof(viddec_msg_pp_frame_done)
+
+#define	VIDDEC_MSG_DISP_WORTHY_DISP		0x0000
+#define	VIDDEC_MSG_DISP_WORTHY_DISP_NONE	0xFFFF
+
+
+typedef struct {
+	unsigned short	packet_seq_number;
+	unsigned short	codec_instance_id;
+	unsigned short	display_worthy;
+} __attribute__((packed)) viddec_msg_pp_frame_done;
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,212 @@
+#ifndef QDSP5VIDENCCMDI_H
+#define QDSP5VIDENCCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+    V I D E O  E N C O D E R  I N T E R N A L  C O M M A N D S
+
+GENERAL DESCRIPTION
+  This file contains defintions of format blocks of commands
+  that are accepted by VIDENC Task
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+  None
+
+Copyright(c) 2008 by QUALCOMM, Incorporated.
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+			EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+Revision History:
+
+when       who     what, where, why
+--------   ---     ----------------------------------------------------------
+09/25/08   umeshp      initial version
+===========================================================================*/
+
+  #define VIDENC_CMD_CFG           0x0000
+  #define VIDENC_CMD_ACTIVE        0x0001
+  #define VIDENC_CMD_IDLE          0x0002
+  #define VIDENC_CMD_FRAME_START   0x0003
+  #define VIDENC_CMD_STATUS_QUERY  0x0004
+  #define VIDENC_CMD_RC_CFG        0x0005
+  #define VIDENC_CMD_DIS_CFG       0x0006
+  #define VIDENC_CMD_DIS           0x0007
+  #define VIDENC_CMD_INTRA_REFRESH 0x0008
+  #define VIDENC_CMD_DIGITAL_ZOOM  0x0009
+
+
+/*
+ * Command to pass the frame message information to VIDENC
+ */
+
+
+#define VIDENC_CMD_FRAME_START_LEN \
+	sizeof(videnc_cmd_frame_start)
+
+typedef struct {
+	unsigned short  cmd_id;
+	unsigned short  frame_info;
+	unsigned short  frame_rho_budget_word_high;
+	unsigned short  frame_rho_budget_word_low;
+	unsigned short  input_luma_addr_high;
+	unsigned short  input_luma_addr_low;
+	unsigned short  input_chroma_addr_high;
+	unsigned short  input_chroma_addr_low;
+	unsigned short  ref_vop_buf_ptr_high;
+	unsigned short  ref_vop_buf_ptr_low;
+	unsigned short  enc_pkt_buf_ptr_high;
+	unsigned short  enc_pkt_buf_ptr_low;
+	unsigned short  enc_pkt_buf_size_high;
+	unsigned short  enc_pkt_buf_size_low;
+	unsigned short  unfilt_recon_vop_buf_ptr_high;
+	unsigned short  unfilt_recon_vop_buf_ptr_low;
+	unsigned short  filt_recon_vop_buf_ptr_high;
+	unsigned short  filt_recon_vop_buf_ptr_low;
+} __attribute__((packed)) videnc_cmd_frame_start;
+
+/*
+ * Command to pass the frame-level digital stabilization parameters to VIDENC
+ */
+
+
+#define VIDENC_CMD_DIS_LEN \
+    sizeof(videnc_cmd_dis)
+
+typedef struct {
+	unsigned short  cmd_id;
+	unsigned short  vfe_out_prev_luma_addr_high;
+	unsigned short  vfe_out_prev_luma_addr_low;
+	unsigned short  stabilization_info;
+} __attribute__((packed)) videnc_cmd_dis;
+
+/*
+ * Command to pass the codec related parameters to VIDENC
+ */
+
+
+#define VIDENC_CMD_CFG_LEN \
+    sizeof(videnc_cmd_cfg)
+
+typedef struct {
+	unsigned short  cmd_id;
+	unsigned short  cfg_info_0;
+	unsigned short  cfg_info_1;
+	unsigned short  four_mv_threshold;
+	unsigned short  ise_fse_mv_cost_fac;
+	unsigned short  venc_frame_dim;
+	unsigned short  venc_DM_partition;
+} __attribute__((packed)) videnc_cmd_cfg;
+
+/*
+ * Command to start the video encoding
+ */
+
+
+#define VIDENC_CMD_ACTIVE_LEN \
+    sizeof(videnc_cmd_active)
+
+typedef struct {
+    unsigned short  cmd_id;
+} __attribute__((packed)) videnc_cmd_active;
+
+/*
+ * Command to stop the video encoding
+ */
+
+
+#define VIDENC_CMD_IDLE_LEN \
+    sizeof(videnc_cmd_idle)
+
+typedef struct {
+	unsigned short  cmd_id;
+} __attribute__((packed)) videnc_cmd_idle;
+
+/*
+ * Command to query staus of VIDENC
+ */
+
+
+#define VIDENC_CMD_STATUS_QUERY_LEN \
+    sizeof(videnc_cmd_status_query)
+
+typedef struct {
+	unsigned short  cmd_id;
+} __attribute__((packed)) videnc_cmd_status_query;
+
+/*
+ * Command to set rate control for a frame
+ */
+
+
+#define VIDENC_CMD_RC_CFG_LEN \
+    sizeof(videnc_cmd_rc_cfg)
+
+typedef struct {
+	unsigned short  cmd_id;
+	unsigned short  max_frame_qp_delta;
+	unsigned short  max_min_frame_qp;
+} __attribute__((packed)) videnc_cmd_rc_cfg;
+
+/*
+ * Command to set intra-refreshing
+ */
+
+
+#define VIDENC_CMD_INTRA_REFRESH_LEN \
+    sizeof(videnc_cmd_intra_refresh)
+
+typedef struct {
+	unsigned short  cmd_id;
+	unsigned short  num_mb_refresh;
+	unsigned short  mb_index[15];
+} __attribute__((packed)) videnc_cmd_intra_refresh;
+
+/*
+ * Command to pass digital zoom information to the VIDENC
+ */
+#define VIDENC_CMD_DIGITAL_ZOOM_LEN \
+    sizeof(videnc_cmd_digital_zoom)
+
+typedef struct {
+	unsigned short  cmd_id;
+	unsigned short  digital_zoom_en;
+	unsigned short  luma_frame_shift_X;
+	unsigned short  luma_frame_shift_Y;
+	unsigned short  up_ip_luma_rows;
+	unsigned short  up_ip_luma_cols;
+	unsigned short  up_ip_chroma_rows;
+	unsigned short  up_ip_chroma_cols;
+	unsigned short  luma_ph_incr_V_low;
+	unsigned short  luma_ph_incr_V_high;
+	unsigned short  luma_ph_incr_H_low;
+	unsigned short  luma_ph_incr_H_high;
+	unsigned short  chroma_ph_incr_V_low;
+	unsigned short  chroma_ph_incr_V_high;
+	unsigned short  chroma_ph_incr_H_low;
+	unsigned short  chroma_ph_incr_H_high;
+} __attribute__((packed)) videnc_cmd_digital_zoom;
+
+/*
+ * Command to configure digital stabilization parameters
+ */
+
+#define VIDENC_CMD_DIS_CFG_LEN \
+    sizeof(videnc_cmd_dis_cfg)
+
+typedef struct {
+	unsigned short  cmd_id;
+	unsigned short  image_stab_subf_start_row_col;
+	unsigned short  image_stab_subf_dim;
+	unsigned short  image_stab_info_0;
+} __attribute__((packed)) videnc_cmd_dis_cfg;
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,910 @@
+#ifndef QDSP5VFECMDI_H
+#define QDSP5VFECMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+    V F E   I N T E R N A L   C O M M A N D S
+
+GENERAL DESCRIPTION
+  This file contains defintions of format blocks of commands
+  that are accepted by VFE Task
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+  None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfecmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+
+when       who     what, where, why
+--------   ---     ----------------------------------------------------------
+06/12/08   sv      initial version
+===========================================================================*/
+
+/******************************************************************************
+ * Commands through vfeCommandScaleQueue
+ *****************************************************************************/
+
+/*
+ * Command to program scaler for op1 . max op of scaler is VGA
+ */
+
+
+#define	VFE_CMD_SCALE_OP1_CFG		0x0000
+#define	VFE_CMD_SCALE_OP1_CFG_LEN	\
+	sizeof(vfe_cmd_scale_op1_cfg)
+
+#define	VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_STANDARD	0x0000
+#define	VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_CASCADED	0x0001
+#define	VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_DIS	0x0000
+#define	VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_ENA	0x0002
+#define	VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_DIS	0x0000
+#define	VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_ENA	0x0004
+#define	VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_DIS	0x0000
+#define	VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_ENA	0x0008
+#define	VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_DIS	0x0000
+#define	VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_ENA	0x0010
+#define	VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_STANDARD	0x0000
+#define	VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_CASCADED	0x0020
+#define	VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_DIS		0x0000
+#define	VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_ENA		0x0040
+#define	VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_DIS		0x0000
+#define	VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_ENA		0x0080
+
+#define	VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS	0x80000000
+#define	VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS	0x80000000
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	scale_op1_sel;
+	unsigned int	y_scaler_cfg_part1;
+	unsigned int	y_scaler_cfg_part2;
+	unsigned int	cbcr_scaler_cfg_part1;
+	unsigned int	cbcr_scaler_cfg_part2;
+	unsigned int	cbcr_scaler_cfg_part3;
+	unsigned int	pp_y_scaler_cfg_part1;
+	unsigned int	pp_y_scaler_cfg_part2;
+	unsigned int	y_scaler_v_coeff_bank_part1[16];
+	unsigned int	y_scaler_v_coeff_bank_part2[16];
+	unsigned int	y_scaler_h_coeff_bank_part1[16];
+	unsigned int	y_scaler_h_coeff_bank_part2[16];
+} __attribute__((packed)) vfe_cmd_scale_op1_cfg;
+
+
+/*
+ * Command to program scaler for op2
+ */
+
+#define	VFE_CMD_SCALE_OP2_CFG		0x0001
+#define	VFE_CMD_SCALE_OP2_CFG_LEN	\
+	sizeof(vfe_cmd_scale_op2_cfg)
+
+#define	VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_STANDARD	0x0000
+#define	VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_CASCADED	0x0001
+#define	VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_DIS	0x0000
+#define	VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_ENA	0x0002
+#define	VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_DIS	0x0000
+#define	VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_ENA	0x0004
+#define	VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_DIS	0x0000
+#define	VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_ENA	0x0008
+#define	VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_DIS	0x0000
+#define	VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_ENA	0x0010
+#define	VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_STANDARD	0x0000
+#define	VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_CASCADED	0x0020
+#define	VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_DIS		0x0000
+#define	VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_ENA		0x0040
+#define	VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_DIS		0x0000
+#define	VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_ENA		0x0080
+
+#define	VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS	0x80000000
+#define	VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS		0x80000000
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	scale_op2_sel;
+	unsigned int	y_scaler_cfg_part1;
+	unsigned int	y_scaler_cfg_part2;
+	unsigned int	cbcr_scaler_cfg_part1;
+	unsigned int	cbcr_scaler_cfg_part2;
+	unsigned int	cbcr_scaler_cfg_part3;
+	unsigned int	pp_y_scaler_cfg_part1;
+	unsigned int	pp_y_scaler_cfg_part2;
+	unsigned int	y_scaler_v_coeff_bank_part1[16];
+	unsigned int	y_scaler_v_coeff_bank_part2[16];
+	unsigned int	y_scaler_h_coeff_bank_part1[16];
+	unsigned int	y_scaler_h_coeff_bank_part2[16];
+} __attribute__((packed)) vfe_cmd_scale_op2_cfg;
+
+
+/******************************************************************************
+ * Commands through vfeCommandTableQueue
+ *****************************************************************************/
+
+/*
+ * Command to program the AXI ip paths
+ */
+
+#define	VFE_CMD_AXI_IP_CFG		0x0000
+#define	VFE_CMD_AXI_IP_CFG_LEN		sizeof(vfe_cmd_axi_ip_cfg)
+
+#define	VFE_CMD_IP_SEL_IP_FORMAT_8	0x0000
+#define	VFE_CMD_IP_SEL_IP_FORMAT_10	0x0001
+#define	VFE_CMD_IP_SEL_IP_FORMAT_12	0x0002
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	ip_sel;
+	unsigned int	ip_cfg_part1;
+	unsigned int	ip_cfg_part2;
+	unsigned int	ip_unpack_cfg_part[6];
+	unsigned int	ip_buf_addr[8];
+} __attribute__ ((packed)) vfe_cmd_axi_ip_cfg;
+
+
+/*
+ * Command to program axi op paths
+ */
+
+#define	VFE_CMD_AXI_OP_CFG	0x0001
+#define	VFE_CMD_AXI_OP_CFG_LEN	sizeof(vfe_cmd_axi_op_cfg)
+
+#define	VFE_CMD_OP_SEL_OP1		0x0000
+#define	VFE_CMD_OP_SEL_OP2		0x0001
+#define	VFE_CMD_OP_SEL_OP1_OP2		0x0002
+#define	VFE_CMD_OP_SEL_CTOA		0x0003
+#define	VFE_CMD_OP_SEL_CTOA_OP1		0x0004
+#define	VFE_CMD_OP_SEL_CTOA_OP2		0x0005
+#define	VFE_CMD_OP_SEL_OP_FORMAT_8	0x0000
+#define	VFE_CMD_OP_SEL_OP_FORMAT_10	0x0008
+#define	VFE_CMD_OP_SEL_OP_FORMAT_12	0x0010
+
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	op_sel;
+	unsigned int	op1_y_cfg_part1;
+	unsigned int	op1_y_cfg_part2;
+	unsigned int	op1_cbcr_cfg_part1;
+	unsigned int	op1_cbcr_cfg_part2;
+	unsigned int	op2_y_cfg_part1;
+	unsigned int	op2_y_cfg_part2;
+	unsigned int	op2_cbcr_cfg_part1;
+	unsigned int	op2_cbcr_cfg_part2;
+	unsigned int	op1_buf1_addr[16];
+	unsigned int	op2_buf1_addr[16];
+} __attribute__((packed)) vfe_cmd_axi_op_cfg;
+
+
+
+
+/*
+ * Command to program the roll off correction module
+ */
+
+#define	VFE_CMD_ROLLOFF_CFG	0x0002
+#define	VFE_CMD_ROLLOFF_CFG_LEN	\
+	sizeof(vfe_cmd_rolloff_cfg)
+
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	correction_opt_center_pos;
+	unsigned int	radius_square_entry[32];
+	unsigned int	red_table_entry[32];
+	unsigned int	green_table_entry[32];
+	unsigned int	blue_table_entry[32];
+} __attribute__((packed)) vfe_cmd_rolloff_cfg;
+
+/*
+ * Command to program RGB gamma table
+ */
+
+#define	VFE_CMD_RGB_GAMMA_CFG		0x0003
+#define	VFE_CMD_RGB_GAMMA_CFG_LEN	\
+	sizeof(vfe_cmd_rgb_gamma_cfg)
+
+#define	VFE_CMD_RGB_GAMMA_SEL_LINEAR		0x0000
+#define	VFE_CMD_RGB_GAMMA_SEL_PW_LINEAR		0x0001
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	rgb_gamma_sel;
+	unsigned int	rgb_gamma_entry[256];
+} __attribute__((packed)) vfe_cmd_rgb_gamma_cfg;
+
+
+/*
+ * Command to program luma gamma table for the noise reduction path
+ */
+
+#define	VFE_CMD_Y_GAMMA_CFG		0x0004
+#define	VFE_CMD_Y_GAMMA_CFG_LEN		\
+	sizeof(vfe_cmd_y_gamma_cfg)
+
+#define	VFE_CMD_Y_GAMMA_SEL_LINEAR	0x0000
+#define	VFE_CMD_Y_GAMMA_SEL_PW_LINEAR	0x0001
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	y_gamma_sel;
+	unsigned int	y_gamma_entry[256];
+} __attribute__((packed)) vfe_cmd_y_gamma_cfg;
+
+
+
+/******************************************************************************
+ * Commands through vfeCommandQueue
+ *****************************************************************************/
+
+/*
+ * Command to reset the VFE to a known good state.All previously programmed
+ * Params will be lost
+ */
+
+
+#define	VFE_CMD_RESET		0x0000
+#define	VFE_CMD_RESET_LEN	sizeof(vfe_cmd_reset)
+
+
+typedef struct {
+	unsigned short	cmd_id;
+} __attribute__((packed)) vfe_cmd_reset;
+
+
+/*
+ * Command to start VFE processing based on the config params
+ */
+
+
+#define	VFE_CMD_START		0x0001
+#define	VFE_CMD_START_LEN	sizeof(vfe_cmd_start)
+
+#define	VFE_CMD_STARTUP_PARAMS_SRC_CAMIF	0x0000
+#define	VFE_CMD_STARTUP_PARAMS_SRC_AXI		0x0001
+#define	VFE_CMD_STARTUP_PARAMS_MODE_CONTINUOUS	0x0000
+#define	VFE_CMD_STARTUP_PARAMS_MODE_SNAPSHOT	0x0002
+
+#define	VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_DIS	0x0000
+#define	VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_ENA	0x0001
+#define	VFE_CMD_IMAGE_PL_ROLLOFF_CORR_DIS	0x0000
+#define	VFE_CMD_IMAGE_PL_ROLLOFF_CORR_ENA	0x0002
+#define	VFE_CMD_IMAGE_PL_WHITE_BAL_DIS		0x0000
+#define	VFE_CMD_IMAGE_PL_WHITE_BAL_ENA		0x0004
+#define	VFE_CMD_IMAGE_PL_RGB_GAMMA_DIS		0x0000
+#define	VFE_CMD_IMAGE_PL_RGB_GAMMA_ENA		0x0008
+#define	VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_DIS	0x0000
+#define	VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_ENA	0x0010
+#define	VFE_CMD_IMAGE_PL_ADP_FILTER_DIS		0x0000
+#define	VFE_CMD_IMAGE_PL_ADP_FILTER_ENA		0x0020
+#define	VFE_CMD_IMAGE_PL_CHROMA_SAMP_DIS	0x0000
+#define	VFE_CMD_IMAGE_PL_CHROMA_SAMP_ENA	0x0040
+
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	startup_params;
+	unsigned int	image_pipeline;
+	unsigned int	frame_dimension;
+} __attribute__((packed)) vfe_cmd_start;
+
+
+/*
+ * Command to halt all processing
+ */
+
+#define	VFE_CMD_STOP		0x0002
+#define	VFE_CMD_STOP_LEN	sizeof(vfe_cmd_stop)
+
+typedef struct {
+	unsigned short	cmd_id;
+} __attribute__((packed)) vfe_cmd_stop;
+
+
+/*
+ * Command to commit the params that have been programmed to take
+ * effect on the next frame
+ */
+
+#define	VFE_CMD_UPDATE		0x0003
+#define	VFE_CMD_UPDATE_LEN	sizeof(vfe_cmd_update)
+
+
+typedef struct {
+	unsigned short	cmd_id;
+} __attribute__((packed)) vfe_cmd_update;
+
+
+/*
+ * Command to program CAMIF module
+ */
+
+#define	VFE_CMD_CAMIF_CFG	0x0004
+#define	VFE_CMD_CAMIF_CFG_LEN	sizeof(vfe_cmd_camif_cfg)
+
+#define	VFE_CMD_CFG_VSYNC_SYNC_EDGE_HIGH	0x0000
+#define	VFE_CMD_CFG_VSYNC_SYNC_EDGE_LOW		0x0002
+#define	VFE_CMD_CFG_HSYNC_SYNC_EDGE_HIGH	0x0000
+#define	VFE_CMD_CFG_HSYNC_SYNC_EDGE_LOW		0x0004
+#define	VFE_CMD_CFG_SYNC_MODE_APS		0x0000
+#define	VFE_CMD_CFG_SYNC_MODE_EFS		0X0008
+#define	VFE_CMD_CFG_SYNC_MODE_ELS		0x0010
+#define	VFE_CMD_CFG_SYNC_MODE_RVD		0x0018
+#define	VFE_CMD_CFG_VFE_SUBSAMP_EN_DIS		0x0000
+#define	VFE_CMD_CFG_VFE_SUBSAMP_EN_ENA		0x0020
+#define	VFE_CMD_CFG_BUS_SUBSAMP_EN_DIS		0x0000
+#define	VFE_CMD_CFG_BUS_SUBSAMP_EN_ENA		0x0080
+#define	VFE_CMD_CFG_IRQ_SUBSAMP_EN_DIS		0x0000
+#define	VFE_CMD_CFG_IRQ_SUBSAMP_EN_ENA		0x0800
+
+#define	VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_16	0x0000
+#define	VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_12	0x0010
+
+#define	VFE_CMD_EPOCH_IRQ_1_DIS			0x0000
+#define	VFE_CMD_EPOCH_IRQ_1_ENA			0x4000
+#define	VFE_CMD_EPOCH_IRQ_2_DIS			0x0000
+#define	VFE_CMD_EPOCH_IRQ_2_ENA			0x8000
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	cfg;
+	unsigned int	efs_cfg;
+	unsigned int	frame_cfg;
+	unsigned int	window_width_cfg;
+	unsigned int	window_height_cfg;
+	unsigned int	subsamp1_cfg;
+	unsigned int	subsamp2_cfg;
+	unsigned int	epoch_irq;
+} __attribute__((packed)) vfe_cmd_camif_cfg;
+
+
+
+/*
+ * Command to program the black level module
+ */
+
+#define	VFE_CMD_BLACK_LVL_CFG		0x0005
+#define	VFE_CMD_BLACK_LVL_CFG_LEN	sizeof(vfe_cmd_black_lvl_cfg)
+
+#define	VFE_CMD_BL_SEL_MANUAL		0x0000
+#define	VFE_CMD_BL_SEL_AUTO		0x0001
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	black_lvl_sel;
+	unsigned int	cfg_part[3];
+} __attribute__((packed)) vfe_cmd_black_lvl_cfg;
+
+
+/*
+ * Command to program the active region by cropping the region of interest
+ */
+
+#define	VFE_CMD_ACTIVE_REGION_CFG	0x0006
+#define	VFE_CMD_ACTIVE_REGION_CFG_LEN	\
+	sizeof(vfe_cmd_active_region_cfg)
+
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	cfg_part1;
+	unsigned int	cfg_part2;
+} __attribute__((packed)) vfe_cmd_active_region_cfg;
+
+
+
+/*
+ * Command to program the defective pixel correction(DPC) ,
+ * adaptive bayer filter (ABF) and demosaic modules
+ */
+
+#define	VFE_CMD_DEMOSAIC_CFG		0x0007
+#define	VFE_CMD_DEMOSAIC_CFG_LEN	sizeof(vfe_cmd_demosaic_cfg)
+
+#define	VFE_CMD_DEMOSAIC_PART1_ABF_EN_DIS	0x0000
+#define	VFE_CMD_DEMOSAIC_PART1_ABF_EN_ENA	0x0001
+#define	VFE_CMD_DEMOSAIC_PART1_DPC_EN_DIS	0x0000
+#define	VFE_CMD_DEMOSAIC_PART1_DPC_EN_ENA	0x0002
+#define	VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_OFF	0x0000
+#define	VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_ON	0x0004
+#define	VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1	0x00000000
+#define	VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_2	0x10000000
+#define	VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_4	0x20000000
+#define	VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_8	0x30000000
+#define	VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_2	0x50000000
+#define	VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_4	0x60000000
+#define	VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_8	0x70000000
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	demosaic_part1;
+	unsigned int	demosaic_part2;
+	unsigned int	demosaic_part3;
+	unsigned int	demosaic_part4;
+	unsigned int	demosaic_part5;
+} __attribute__((packed)) vfe_cmd_demosaic_cfg;
+
+
+/*
+ * Command to program the ip format
+ */
+
+#define	VFE_CMD_IP_FORMAT_CFG		0x0008
+#define	VFE_CMD_IP_FORMAT_CFG_LEN	\
+	sizeof(vfe_cmd_ip_format_cfg)
+
+#define	VFE_CMD_IP_FORMAT_SEL_RGRG	0x0000
+#define	VFE_CMD_IP_FORMAT_SEL_GRGR	0x0001
+#define	VFE_CMD_IP_FORMAT_SEL_BGBG	0x0002
+#define	VFE_CMD_IP_FORMAT_SEL_GBGB	0x0003
+#define	VFE_CMD_IP_FORMAT_SEL_YCBYCR	0x0004
+#define	VFE_CMD_IP_FORMAT_SEL_YCRYCB	0x0005
+#define	VFE_CMD_IP_FORMAT_SEL_CBYCRY	0x0006
+#define	VFE_CMD_IP_FORMAT_SEL_CRYCBY	0x0007
+#define	VFE_CMD_IP_FORMAT_SEL_NO_CHROMA	0x0000
+#define	VFE_CMD_IP_FORMAT_SEL_CHROMA	0x0008
+
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	ip_format_sel;
+	unsigned int	balance_gains_part1;
+	unsigned int	balance_gains_part2;
+} __attribute__((packed)) vfe_cmd_ip_format_cfg;
+
+
+
+/*
+ * Command to program max and min allowed op values
+ */
+
+#define	VFE_CMD_OP_CLAMP_CFG		0x0009
+#define	VFE_CMD_OP_CLAMP_CFG_LEN	\
+	sizeof(vfe_cmd_op_clamp_cfg)
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	op_clamp_max;
+	unsigned int	op_clamp_min;
+} __attribute__((packed)) vfe_cmd_op_clamp_cfg;
+
+
+/*
+ * Command to program chroma sub sample module
+ */
+
+#define	VFE_CMD_CHROMA_SUBSAMPLE_CFG		0x000A
+#define	VFE_CMD_CHROMA_SUBSAMPLE_CFG_LEN	\
+	sizeof(vfe_cmd_chroma_subsample_cfg)
+
+#define	VFE_CMD_CHROMA_SUBSAMP_SEL_H_INTERESTIAL_SAMPS	0x0000
+#define	VFE_CMD_CHROMA_SUBSAMP_SEL_H_COSITED_SAMPS	0x0001
+#define	VFE_CMD_CHROMA_SUBSAMP_SEL_V_INTERESTIAL_SAMPS	0x0000
+#define	VFE_CMD_CHROMA_SUBSAMP_SEL_V_COSITED_SAMPS	0x0002
+#define	VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_DIS	0x0000
+#define	VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_ENA	0x0004
+#define	VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_DIS	0x0000
+#define	VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_ENA	0x0008
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	chroma_subsamp_sel;
+} __attribute__((packed)) vfe_cmd_chroma_subsample_cfg;
+
+
+/*
+ * Command to program the white balance module
+ */
+
+#define	VFE_CMD_WHITE_BALANCE_CFG	0x000B
+#define	VFE_CMD_WHITE_BALANCE_CFG_LEN	\
+	sizeof(vfe_cmd_white_balance_cfg)
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	white_balance_gains;
+} __attribute__((packed)) vfe_cmd_white_balance_cfg;
+
+
+/*
+ * Command to program the color processing module
+ */
+
+#define	VFE_CMD_COLOR_PROCESS_CFG	0x000C
+#define	VFE_CMD_COLOR_PROCESS_CFG_LEN	\
+	sizeof(vfe_cmd_color_process_cfg)
+
+#define	VFE_CMD_COLOR_CORRE_PART7_Q7_FACTORS	0x0000
+#define	VFE_CMD_COLOR_CORRE_PART7_Q8_FACTORS	0x0001
+#define	VFE_CMD_COLOR_CORRE_PART7_Q9_FACTORS	0x0002
+#define	VFE_CMD_COLOR_CORRE_PART7_Q10_FACTORS	0x0003
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	color_correction_part1;
+	unsigned int	color_correction_part2;
+	unsigned int	color_correction_part3;
+	unsigned int	color_correction_part4;
+	unsigned int	color_correction_part5;
+	unsigned int	color_correction_part6;
+	unsigned int	color_correction_part7;
+	unsigned int	chroma_enhance_part1;
+	unsigned int	chroma_enhance_part2;
+	unsigned int	chroma_enhance_part3;
+	unsigned int	chroma_enhance_part4;
+	unsigned int	chroma_enhance_part5;
+	unsigned int	luma_calc_part1;
+	unsigned int	luma_calc_part2;
+} __attribute__((packed)) vfe_cmd_color_process_cfg;
+
+
+/*
+ * Command to program adaptive filter module
+ */
+
+#define	VFE_CMD_ADP_FILTER_CFG		0x000D
+#define	VFE_CMD_ADP_FILTER_CFG_LEN	\
+	sizeof(vfe_cmd_adp_filter_cfg)
+
+#define	VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_DIS		0x0000
+#define	VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_ENA		0x0001
+#define	VFE_CMD_ASF_CFG_PART_NO_SHARP_MODE		0x0000
+#define	VFE_CMD_ASF_CFG_PART_SINGLE_FILTER		0x0002
+#define	VFE_CMD_ASF_CFG_PART_DUAL_FILTER		0x0004
+#define	VFE_CMD_ASF_CFG_PART_SHARP_MODE			0x0007
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	asf_cfg_part[7];
+} __attribute__((packed)) vfe_cmd_adp_filter_cfg;
+
+
+/*
+ * Command to program for frame skip pattern for op1 and op2
+ */
+
+#define	VFE_CMD_FRAME_SKIP_CFG		0x000E
+#define	VFE_CMD_FRAME_SKIP_CFG_LEN	\
+	sizeof(vfe_cmd_frame_skip_cfg)
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	frame_skip_pattern_op1;
+	unsigned int	frame_skip_pattern_op2;
+} __attribute__((packed)) vfe_cmd_frame_skip_cfg;
+
+
+/*
+ * Command to program field-of-view crop for digital zoom
+ */
+
+#define	VFE_CMD_FOV_CROP	0x000F
+#define	VFE_CMD_FOV_CROP_LEN	sizeof(vfe_cmd_fov_crop)
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	fov_crop_part1;
+	unsigned int	fov_crop_part2;
+} __attribute__((packed)) vfe_cmd_fov_crop;
+
+
+
+/*
+ * Command to program auto focus(AF) statistics module
+ */
+
+#define	VFE_CMD_STATS_AUTOFOCUS_CFG	0x0010
+#define	VFE_CMD_STATS_AUTOFOCUS_CFG_LEN	\
+	sizeof(vfe_cmd_stats_autofocus_cfg)
+
+#define	VFE_CMD_AF_STATS_SEL_STATS_DIS	0x0000
+#define	VFE_CMD_AF_STATS_SEL_STATS_ENA	0x0001
+#define	VFE_CMD_AF_STATS_SEL_PRI_FIXED	0x0000
+#define	VFE_CMD_AF_STATS_SEL_PRI_VAR	0x0002
+#define	VFE_CMD_AF_STATS_CFG_PART_METRIC_SUM	0x00000000
+#define	VFE_CMD_AF_STATS_CFG_PART_METRIC_MAX	0x00200000
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	af_stats_sel;
+	unsigned int	af_stats_cfg_part[8];
+	unsigned int	af_stats_op_buf_hdr;
+	unsigned int	af_stats_op_buf[3];
+} __attribute__((packed)) vfe_cmd_stats_autofocus_cfg;
+
+
+/*
+ * Command to program White balance(wb) and exposure (exp)
+ * statistics module
+ */
+
+#define	VFE_CMD_STATS_WB_EXP_CFG	0x0011
+#define	VFE_CMD_STATS_WB_EXP_CFG_LEN	\
+	sizeof(vfe_cmd_stats_wb_exp_cfg)
+
+#define	VFE_CMD_WB_EXP_STATS_SEL_STATS_DIS	0x0000
+#define	VFE_CMD_WB_EXP_STATS_SEL_STATS_ENA	0x0001
+#define	VFE_CMD_WB_EXP_STATS_SEL_PRI_FIXED	0x0000
+#define	VFE_CMD_WB_EXP_STATS_SEL_PRI_VAR	0x0002
+
+#define	VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_8_8	0x0000
+#define	VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_16_16	0x0001
+#define	VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_8_8	0x0000
+#define	VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_4_4	0x0002
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	wb_exp_stats_sel;
+	unsigned int	wb_exp_stats_cfg_part1;
+	unsigned int	wb_exp_stats_cfg_part2;
+	unsigned int	wb_exp_stats_cfg_part3;
+	unsigned int	wb_exp_stats_cfg_part4;
+	unsigned int	wb_exp_stats_op_buf_hdr;
+	unsigned int	wb_exp_stats_op_buf[3];
+} __attribute__((packed)) vfe_cmd_stats_wb_exp_cfg;
+
+
+/*
+ * Command to program histogram(hg) stats module
+ */
+
+#define	VFE_CMD_STATS_HG_CFG		0x0012
+#define	VFE_CMD_STATS_HG_CFG_LEN	\
+	sizeof(vfe_cmd_stats_hg_cfg)
+
+#define	VFE_CMD_HG_STATS_SEL_PRI_FIXED	0x0000
+#define	VFE_CMD_HG_STATS_SEL_PRI_VAR	0x0002
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	hg_stats_sel;
+	unsigned int	hg_stats_cfg_part1;
+	unsigned int	hg_stats_cfg_part2;
+	unsigned int	hg_stats_op_buf_hdr;
+	unsigned int	hg_stats_op_buf;
+} __attribute__((packed)) vfe_cmd_stats_hg_cfg;
+
+
+/*
+ * Command to acknowledge last MSG_VFE_OP1 message
+ */
+
+#define	VFE_CMD_OP1_ACK		0x0013
+#define	VFE_CMD_OP1_ACK_LEN	sizeof(vfe_cmd_op1_ack)
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	op1_buf_y_addr;
+	unsigned int	op1_buf_cbcr_addr;
+} __attribute__((packed)) vfe_cmd_op1_ack;
+
+
+
+/*
+ * Command to acknowledge last MSG_VFE_OP2 message
+ */
+
+#define	VFE_CMD_OP2_ACK		0x0014
+#define	VFE_CMD_OP2_ACK_LEN	sizeof(vfe_cmd_op2_ack)
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	op2_buf_y_addr;
+	unsigned int	op2_buf_cbcr_addr;
+} __attribute__((packed)) vfe_cmd_op2_ack;
+
+
+
+/*
+ * Command to acknowledge MSG_VFE_STATS_AUTOFOCUS msg
+ */
+
+#define	VFE_CMD_STATS_AF_ACK		0x0015
+#define	VFE_CMD_STATS_AF_ACK_LEN	sizeof(vfe_cmd_stats_af_ack)
+
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	af_stats_op_buf;
+} __attribute__((packed)) vfe_cmd_stats_af_ack;
+
+
+/*
+ * Command to acknowledge MSG_VFE_STATS_WB_EXP msg
+ */
+
+#define	VFE_CMD_STATS_WB_EXP_ACK	0x0016
+#define	VFE_CMD_STATS_WB_EXP_ACK_LEN	sizeof(vfe_cmd_stats_wb_exp_ack)
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	wb_exp_stats_op_buf;
+} __attribute__((packed)) vfe_cmd_stats_wb_exp_ack;
+
+
+/*
+ * Command to acknowledge MSG_VFE_EPOCH1 message
+ */
+
+#define	VFE_CMD_EPOCH1_ACK	0x0017
+#define	VFE_CMD_EPOCH1_ACK_LEN	sizeof(vfe_cmd_epoch1_ack)
+
+typedef struct {
+	unsigned short cmd_id;
+} __attribute__((packed)) vfe_cmd_epoch1_ack;
+
+
+/*
+ * Command to acknowledge MSG_VFE_EPOCH2 message
+ */
+
+#define	VFE_CMD_EPOCH2_ACK	0x0018
+#define	VFE_CMD_EPOCH2_ACK_LEN	sizeof(vfe_cmd_epoch2_ack)
+
+typedef struct {
+	unsigned short cmd_id;
+} __attribute__((packed)) vfe_cmd_epoch2_ack;
+
+
+
+/*
+ * Command to configure, enable or disable synchronous timer1
+ */
+
+#define	VFE_CMD_SYNC_TIMER1_CFG		0x0019
+#define	VFE_CMD_SYNC_TIMER1_CFG_LEN	\
+	sizeof(vfe_cmd_sync_timer1_cfg)
+
+#define	VFE_CMD_SYNC_T1_CFG_PART1_TIMER_DIS	0x0000
+#define	VFE_CMD_SYNC_T1_CFG_PART1_TIMER_ENA	0x0001
+#define	VFE_CMD_SYNC_T1_CFG_PART1_POL_HIGH	0x0000
+#define	VFE_CMD_SYNC_T1_CFG_PART1_POL_LOW	0x0002
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	sync_t1_cfg_part1;
+	unsigned int	sync_t1_h_sync_countdown;
+	unsigned int	sync_t1_pclk_countdown;
+	unsigned int	sync_t1_duration;
+} __attribute__((packed)) vfe_cmd_sync_timer1_cfg;
+
+
+/*
+ * Command to configure, enable or disable synchronous timer1
+ */
+
+#define	VFE_CMD_SYNC_TIMER2_CFG		0x001A
+#define	VFE_CMD_SYNC_TIMER2_CFG_LEN	\
+	sizeof(vfe_cmd_sync_timer2_cfg)
+
+#define	VFE_CMD_SYNC_T2_CFG_PART1_TIMER_DIS	0x0000
+#define	VFE_CMD_SYNC_T2_CFG_PART1_TIMER_ENA	0x0001
+#define	VFE_CMD_SYNC_T2_CFG_PART1_POL_HIGH	0x0000
+#define	VFE_CMD_SYNC_T2_CFG_PART1_POL_LOW	0x0002
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	sync_t2_cfg_part1;
+	unsigned int	sync_t2_h_sync_countdown;
+	unsigned int	sync_t2_pclk_countdown;
+	unsigned int	sync_t2_duration;
+} __attribute__((packed)) vfe_cmd_sync_timer2_cfg;
+
+
+/*
+ * Command to configure and start asynchronous timer1
+ */
+
+#define	VFE_CMD_ASYNC_TIMER1_START	0x001B
+#define	VFE_CMD_ASYNC_TIMER1_START_LEN	\
+	sizeof(vfe_cmd_async_timer1_start)
+
+#define	VFE_CMD_ASYNC_T1_POLARITY_A_HIGH	0x0000
+#define	VFE_CMD_ASYNC_T1_POLARITY_A_LOW		0x0001
+#define	VFE_CMD_ASYNC_T1_POLARITY_B_HIGH	0x0000
+#define	VFE_CMD_ASYNC_T1_POLARITY_B_LOW		0x0002
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	async_t1a_cfg;
+	unsigned int	async_t1b_cfg;
+	unsigned int	async_t1_polarity;
+} __attribute__((packed)) vfe_cmd_async_timer1_start;
+
+
+/*
+ * Command to configure and start asynchronous timer2
+ */
+
+#define	VFE_CMD_ASYNC_TIMER2_START	0x001C
+#define	VFE_CMD_ASYNC_TIMER2_START_LEN	\
+	sizeof(vfe_cmd_async_timer2_start)
+
+#define	VFE_CMD_ASYNC_T2_POLARITY_A_HIGH	0x0000
+#define	VFE_CMD_ASYNC_T2_POLARITY_A_LOW		0x0001
+#define	VFE_CMD_ASYNC_T2_POLARITY_B_HIGH	0x0000
+#define	VFE_CMD_ASYNC_T2_POLARITY_B_LOW		0x0002
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	async_t2a_cfg;
+	unsigned int	async_t2b_cfg;
+	unsigned int	async_t2_polarity;
+} __attribute__((packed)) vfe_cmd_async_timer2_start;
+
+
+/*
+ * Command to program partial configurations of auto focus(af)
+ */
+
+#define	VFE_CMD_STATS_AF_UPDATE		0x001D
+#define	VFE_CMD_STATS_AF_UPDATE_LEN	\
+	sizeof(vfe_cmd_stats_af_update)
+
+#define	VFE_CMD_AF_UPDATE_PART1_WINDOW_ONE	0x00000000
+#define	VFE_CMD_AF_UPDATE_PART1_WINDOW_MULTI	0x80000000
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	af_update_part1;
+	unsigned int	af_update_part2;
+} __attribute__((packed)) vfe_cmd_stats_af_update;
+
+
+/*
+ * Command to program partial cfg of wb and exp
+ */
+
+#define	VFE_CMD_STATS_WB_EXP_UPDATE	0x001E
+#define	VFE_CMD_STATS_WB_EXP_UPDATE_LEN	\
+	sizeof(vfe_cmd_stats_wb_exp_update)
+
+#define	VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_8_8		0x0000
+#define	VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_16_16	0x0001
+#define	VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_8_8	0x0000
+#define	VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_4_4	0x0002
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	wb_exp_update_part1;
+	unsigned int	wb_exp_update_part2;
+	unsigned int	wb_exp_update_part3;
+	unsigned int	wb_exp_update_part4;
+} __attribute__((packed)) vfe_cmd_stats_wb_exp_update;
+
+
+
+/*
+ * Command to re program the CAMIF FRAME CONFIG settings
+ */
+
+#define	VFE_CMD_UPDATE_CAMIF_FRAME_CFG		0x001F
+#define	VFE_CMD_UPDATE_CAMIF_FRAME_CFG_LEN	\
+	sizeof(vfe_cmd_update_camif_frame_cfg)
+
+typedef struct {
+	unsigned int	cmd_id;
+	unsigned int	camif_frame_cfg;
+} __attribute__((packed)) vfe_cmd_update_camif_frame_cfg;
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,290 @@
+#ifndef QDSP5VFEMSGI_H
+#define QDSP5VFEMSGI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+    V F E   I N T E R N A L   M E S S A G E S
+
+GENERAL DESCRIPTION
+  This file contains defintions of format blocks of commands
+  that are sent by VFE Task
+
+REFERENCES
+  None
+
+EXTERNALIZED FUNCTIONS
+  None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+                      EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfemsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+
+when       who     what, where, why
+--------   ---     ----------------------------------------------------------
+06/12/08   sv      initial version
+===========================================================================*/
+
+
+/*
+ * Message to acknowledge CMD_VFE_REST command
+ */
+
+#define	VFE_MSG_RESET_ACK	0x0000
+#define	VFE_MSG_RESET_ACK_LEN	sizeof(vfe_msg_reset_ack)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_reset_ack;
+
+
+/*
+ * Message to acknowledge CMD_VFE_START command
+ */
+
+#define	VFE_MSG_START_ACK	0x0001
+#define	VFE_MSG_START_ACK_LEN	sizeof(vfe_msg_start_ack)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_start_ack;
+
+/*
+ * Message to acknowledge CMD_VFE_STOP	command
+ */
+
+#define	VFE_MSG_STOP_ACK	0x0002
+#define	VFE_MSG_STOP_ACK_LEN	sizeof(vfe_msg_stop_ack)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_stop_ack;
+
+
+/*
+ * Message to acknowledge CMD_VFE_UPDATE command
+ */
+
+#define	VFE_MSG_UPDATE_ACK	0x0003
+#define	VFE_MSG_UPDATE_ACK_LEN	sizeof(vfe_msg_update_ack)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_update_ack;
+
+
+/*
+ * Message to notify the ARM that snapshot processing is complete
+ * and that the VFE is now STATE_VFE_IDLE
+ */
+
+#define	VFE_MSG_SNAPSHOT_DONE		0x0004
+#define	VFE_MSG_SNAPSHOT_DONE_LEN	\
+	sizeof(vfe_msg_snapshot_done)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_snapshot_done;
+
+
+
+/*
+ * Message to notify ARM that illegal cmd was received and
+ * system is in the IDLE state
+ */
+
+#define	VFE_MSG_ILLEGAL_CMD	0x0005
+#define	VFE_MSG_ILLEGAL_CMD_LEN	\
+	sizeof(vfe_msg_illegal_cmd)
+
+typedef struct {
+	unsigned int	status;
+} __attribute__((packed)) vfe_msg_illegal_cmd;
+
+
+/*
+ * Message to notify ARM that op1 buf is full and ready
+ */
+
+#define	VFE_MSG_OP1		0x0006
+#define	VFE_MSG_OP1_LEN		sizeof(vfe_msg_op1)
+
+typedef struct {
+	unsigned int	op1_buf_y_addr;
+	unsigned int	op1_buf_cbcr_addr;
+	unsigned int	black_level_even_col;
+	unsigned int	black_level_odd_col;
+	unsigned int	defect_pixels_detected;
+	unsigned int	asf_max_edge;
+} __attribute__((packed)) vfe_msg_op1;
+
+
+/*
+ * Message to notify ARM that op2 buf is full and ready
+ */
+
+#define	VFE_MSG_OP2		0x0007
+#define	VFE_MSG_OP2_LEN		sizeof(vfe_msg_op2)
+
+typedef struct {
+	unsigned int	op2_buf_y_addr;
+	unsigned int	op2_buf_cbcr_addr;
+	unsigned int	black_level_even_col;
+	unsigned int	black_level_odd_col;
+	unsigned int	defect_pixels_detected;
+	unsigned int	asf_max_edge;
+} __attribute__((packed)) vfe_msg_op2;
+
+
+/*
+ * Message to notify ARM that autofocus(af) stats are ready
+ */
+
+#define	VFE_MSG_STATS_AF	0x0008
+#define	VFE_MSG_STATS_AF_LEN	sizeof(vfe_msg_stats_af)
+
+typedef struct {
+	unsigned int	af_stats_op_buffer;
+} __attribute__((packed)) vfe_msg_stats_af;
+
+
+/*
+ * Message to notify ARM that white balance(wb) and exposure (exp)
+ * stats are ready
+ */
+
+#define	VFE_MSG_STATS_WB_EXP		0x0009
+#define	VFE_MSG_STATS_WB_EXP_LEN	\
+	sizeof(vfe_msg_stats_wb_exp)
+
+typedef struct {
+	unsigned int	wb_exp_stats_op_buf;
+} __attribute__((packed)) vfe_msg_stats_wb_exp;
+
+
+/*
+ * Message to notify the ARM that histogram(hg) stats are ready
+ */
+
+#define	VFE_MSG_STATS_HG	0x000A
+#define	VFE_MSG_STATS_HG_LEN	sizeof(vfe_msg_stats_hg)
+
+typedef struct {
+	unsigned int	hg_stats_op_buf;
+} __attribute__((packed)) vfe_msg_stats_hg;
+
+
+/*
+ * Message to notify the ARM that epoch1 event occurred in the CAMIF
+ */
+
+#define	VFE_MSG_EPOCH1		0x000B
+#define	VFE_MSG_EPOCH1_LEN	sizeof(vfe_msg_epoch1)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_epoch1;
+
+
+/*
+ * Message to notify the ARM that epoch2 event occurred in the CAMIF
+ */
+
+#define	VFE_MSG_EPOCH2		0x000C
+#define	VFE_MSG_EPOCH2_LEN	sizeof(vfe_msg_epoch2)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_epoch2;
+
+
+/*
+ * Message to notify the ARM that sync timer1 op is completed
+ */
+
+#define	VFE_MSG_SYNC_T1_DONE		0x000D
+#define	VFE_MSG_SYNC_T1_DONE_LEN	sizeof(vfe_msg_sync_t1_done)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_sync_t1_done;
+
+
+/*
+ * Message to notify the ARM that sync timer2 op is completed
+ */
+
+#define	VFE_MSG_SYNC_T2_DONE		0x000E
+#define	VFE_MSG_SYNC_T2_DONE_LEN	sizeof(vfe_msg_sync_t2_done)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_sync_t2_done;
+
+
+/*
+ * Message to notify the ARM that async t1 operation completed
+ */
+
+#define	VFE_MSG_ASYNC_T1_DONE		0x000F
+#define	VFE_MSG_ASYNC_T1_DONE_LEN	sizeof(vfe_msg_async_t1_done)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_async_t1_done;
+
+
+
+/*
+ * Message to notify the ARM that async t2 operation completed
+ */
+
+#define	VFE_MSG_ASYNC_T2_DONE		0x0010
+#define	VFE_MSG_ASYNC_T2_DONE_LEN	sizeof(vfe_msg_async_t2_done)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_async_t2_done;
+
+
+
+/*
+ * Message to notify the ARM that an error has occurred
+ */
+
+#define	VFE_MSG_ERROR		0x0011
+#define	VFE_MSG_ERROR_LEN	sizeof(vfe_msg_error)
+
+#define	VFE_MSG_ERR_COND_NO_CAMIF_ERR		0x0000
+#define	VFE_MSG_ERR_COND_CAMIF_ERR		0x0001
+#define	VFE_MSG_ERR_COND_OP1_Y_NO_BUS_OF	0x0000
+#define	VFE_MSG_ERR_COND_OP1_Y_BUS_OF		0x0002
+#define	VFE_MSG_ERR_COND_OP1_CBCR_NO_BUS_OF	0x0000
+#define	VFE_MSG_ERR_COND_OP1_CBCR_BUS_OF	0x0004
+#define	VFE_MSG_ERR_COND_OP2_Y_NO_BUS_OF	0x0000
+#define	VFE_MSG_ERR_COND_OP2_Y_BUS_OF		0x0008
+#define	VFE_MSG_ERR_COND_OP2_CBCR_NO_BUS_OF	0x0000
+#define	VFE_MSG_ERR_COND_OP2_CBCR_BUS_OF	0x0010
+#define	VFE_MSG_ERR_COND_AF_NO_BUS_OF		0x0000
+#define	VFE_MSG_ERR_COND_AF_BUS_OF		0x0020
+#define	VFE_MSG_ERR_COND_WB_EXP_NO_BUS_OF	0x0000
+#define	VFE_MSG_ERR_COND_WB_EXP_BUS_OF		0x0040
+#define	VFE_MSG_ERR_COND_NO_AXI_ERR		0x0000
+#define	VFE_MSG_ERR_COND_AXI_ERR		0x0080
+
+#define	VFE_MSG_CAMIF_STS_IDLE			0x0000
+#define	VFE_MSG_CAMIF_STS_CAPTURE_DATA		0x0001
+
+typedef struct {
+	unsigned int	err_cond;
+	unsigned int	camif_sts;
+} __attribute__((packed)) vfe_msg_error;
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/include/media/msm_camera.h linux-libre-2.6.34-gnu1/drivers/staging/dream/include/media/msm_camera.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/include/media/msm_camera.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/include/media/msm_camera.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+#ifndef __LINUX_MSM_CAMERA_H
+#define __LINUX_MSM_CAMERA_H
+
+#include <linux/types.h>
+#include <asm/sizes.h>
+#include <linux/ioctl.h>
+
+#define MSM_CAM_IOCTL_MAGIC 'm'
+
+#define MSM_CAM_IOCTL_GET_SENSOR_INFO \
+	_IOR(MSM_CAM_IOCTL_MAGIC, 1, struct msm_camsensor_info *)
+
+#define MSM_CAM_IOCTL_REGISTER_PMEM \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 2, struct msm_pmem_info *)
+
+#define MSM_CAM_IOCTL_UNREGISTER_PMEM \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 3, unsigned)
+
+#define MSM_CAM_IOCTL_CTRL_COMMAND \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 4, struct msm_ctrl_cmd *)
+
+#define MSM_CAM_IOCTL_CONFIG_VFE  \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 5, struct msm_camera_vfe_cfg_cmd *)
+
+#define MSM_CAM_IOCTL_GET_STATS \
+	_IOR(MSM_CAM_IOCTL_MAGIC, 6, struct msm_camera_stats_event_ctrl *)
+
+#define MSM_CAM_IOCTL_GETFRAME \
+	_IOR(MSM_CAM_IOCTL_MAGIC, 7, struct msm_camera_get_frame *)
+
+#define MSM_CAM_IOCTL_ENABLE_VFE \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 8, struct camera_enable_cmd *)
+
+#define MSM_CAM_IOCTL_CTRL_CMD_DONE \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 9, struct camera_cmd *)
+
+#define MSM_CAM_IOCTL_CONFIG_CMD \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 10, struct camera_cmd *)
+
+#define MSM_CAM_IOCTL_DISABLE_VFE \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 11, struct camera_enable_cmd *)
+
+#define MSM_CAM_IOCTL_PAD_REG_RESET2 \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 12, struct camera_enable_cmd *)
+
+#define MSM_CAM_IOCTL_VFE_APPS_RESET \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 13, struct camera_enable_cmd *)
+
+#define MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 14, struct camera_enable_cmd *)
+
+#define MSM_CAM_IOCTL_RELEASE_STATS_BUFFER \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 15, struct msm_stats_buf *)
+
+#define MSM_CAM_IOCTL_AXI_CONFIG \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 16, struct msm_camera_vfe_cfg_cmd *)
+
+#define MSM_CAM_IOCTL_GET_PICTURE \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 17, struct msm_camera_ctrl_cmd *)
+
+#define MSM_CAM_IOCTL_SET_CROP \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 18, struct crop_info *)
+
+#define MSM_CAM_IOCTL_PICT_PP \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 19, uint8_t *)
+
+#define MSM_CAM_IOCTL_PICT_PP_DONE \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 20, struct msm_snapshot_pp_status *)
+
+#define MSM_CAM_IOCTL_SENSOR_IO_CFG \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 21, struct sensor_cfg_data *)
+
+#define MSM_CAMERA_LED_OFF  0
+#define MSM_CAMERA_LED_LOW  1
+#define MSM_CAMERA_LED_HIGH 2
+
+#define MSM_CAM_IOCTL_FLASH_LED_CFG \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 22, unsigned *)
+
+#define MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME \
+	_IO(MSM_CAM_IOCTL_MAGIC, 23)
+
+#define MSM_CAM_IOCTL_CTRL_COMMAND_2 \
+	_IOW(MSM_CAM_IOCTL_MAGIC, 24, struct msm_ctrl_cmd *)
+
+#define MAX_SENSOR_NUM  3
+#define MAX_SENSOR_NAME 32
+
+#define MSM_CAM_CTRL_CMD_DONE  0
+#define MSM_CAM_SENSOR_VFE_CMD 1
+
+/*****************************************************
+ *  structure
+ *****************************************************/
+
+/* define five type of structures for userspace <==> kernel
+ * space communication:
+ * command 1 - 2 are from userspace ==> kernel
+ * command 3 - 4 are from kernel ==> userspace
+ *
+ * 1. control command: control command(from control thread),
+ *                     control status (from config thread);
+ */
+struct msm_ctrl_cmd {
+	uint16_t type;
+	uint16_t length;
+	void *value;
+	uint16_t status;
+	uint32_t timeout_ms;
+	int resp_fd; /* FIXME: to be used by the kernel, pass-through for now */
+};
+
+struct msm_vfe_evt_msg {
+	unsigned short type; /* 1 == event (RPC), 0 == message (adsp) */
+	unsigned short msg_id;
+	unsigned int len; /* size in, number of bytes out */
+	void *data;
+};
+
+#define MSM_CAM_RESP_CTRL         0
+#define MSM_CAM_RESP_STAT_EVT_MSG 1
+#define MSM_CAM_RESP_V4L2         2
+#define MSM_CAM_RESP_MAX          3
+
+/* this one is used to send ctrl/status up to config thread */
+struct msm_stats_event_ctrl {
+	/* 0 - ctrl_cmd from control thread,
+	 * 1 - stats/event kernel,
+	 * 2 - V4L control or read request */
+	int resptype;
+	int timeout_ms;
+	struct msm_ctrl_cmd ctrl_cmd;
+	/* struct  vfe_event_t  stats_event; */
+	struct msm_vfe_evt_msg stats_event;
+};
+
+/* 2. config command: config command(from config thread); */
+struct msm_camera_cfg_cmd {
+	/* what to config:
+	 * 1 - sensor config, 2 - vfe config */
+	uint16_t cfg_type;
+
+	/* sensor config type */
+	uint16_t cmd_type;
+	uint16_t queue;
+	uint16_t length;
+	void *value;
+};
+
+#define CMD_GENERAL			0
+#define CMD_AXI_CFG_OUT1		1
+#define CMD_AXI_CFG_SNAP_O1_AND_O2	2
+#define CMD_AXI_CFG_OUT2		3
+#define CMD_PICT_T_AXI_CFG		4
+#define CMD_PICT_M_AXI_CFG		5
+#define CMD_RAW_PICT_AXI_CFG		6
+#define CMD_STATS_AXI_CFG		7
+#define CMD_STATS_AF_AXI_CFG		8
+#define CMD_FRAME_BUF_RELEASE		9
+#define CMD_PREV_BUF_CFG		10
+#define CMD_SNAP_BUF_RELEASE		11
+#define CMD_SNAP_BUF_CFG		12
+#define CMD_STATS_DISABLE		13
+#define CMD_STATS_ENABLE		14
+#define CMD_STATS_AF_ENABLE		15
+#define CMD_STATS_BUF_RELEASE		16
+#define CMD_STATS_AF_BUF_RELEASE	17
+#define UPDATE_STATS_INVALID		18
+
+/* vfe config command: config command(from config thread)*/
+struct msm_vfe_cfg_cmd {
+	int cmd_type;
+	uint16_t length;
+	void *value;
+};
+
+#define MAX_CAMERA_ENABLE_NAME_LEN 32
+struct camera_enable_cmd {
+	char name[MAX_CAMERA_ENABLE_NAME_LEN];
+};
+
+#define MSM_PMEM_OUTPUT1		0
+#define MSM_PMEM_OUTPUT2		1
+#define MSM_PMEM_OUTPUT1_OUTPUT2	2
+#define MSM_PMEM_THUMBAIL		3
+#define MSM_PMEM_MAINIMG		4
+#define MSM_PMEM_RAW_MAINIMG		5
+#define MSM_PMEM_AEC_AWB		6
+#define MSM_PMEM_AF			7
+#define MSM_PMEM_MAX			8
+
+#define FRAME_PREVIEW_OUTPUT1		0
+#define FRAME_PREVIEW_OUTPUT2		1
+#define FRAME_SNAPSHOT			2
+#define FRAME_THUMBAIL			3
+#define FRAME_RAW_SNAPSHOT		4
+#define FRAME_MAX			5
+
+struct msm_pmem_info {
+	int type;
+	int fd;
+	void *vaddr;
+	uint32_t y_off;
+	uint32_t cbcr_off;
+	uint8_t active;
+};
+
+struct outputCfg {
+	uint32_t height;
+	uint32_t width;
+
+	uint32_t window_height_firstline;
+	uint32_t window_height_lastline;
+};
+
+#define OUTPUT_1	0
+#define OUTPUT_2	1
+#define OUTPUT_1_AND_2	2
+#define CAMIF_TO_AXI_VIA_OUTPUT_2		3
+#define OUTPUT_1_AND_CAMIF_TO_AXI_VIA_OUTPUT_2	4
+#define OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1	5
+#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 6
+
+#define MSM_FRAME_PREV_1	0
+#define MSM_FRAME_PREV_2	1
+#define MSM_FRAME_ENC		2
+
+struct msm_frame {
+	int path;
+	unsigned long buffer;
+	uint32_t y_off;
+	uint32_t cbcr_off;
+	int fd;
+
+	void *cropinfo;
+	int croplen;
+};
+
+#define STAT_AEAW	0
+#define STAT_AF		1
+#define STAT_MAX	2
+
+struct msm_stats_buf {
+	int type;
+	unsigned long buffer;
+	int fd;
+};
+
+#define MSM_V4L2_VID_CAP_TYPE	0
+#define MSM_V4L2_STREAM_ON	1
+#define MSM_V4L2_STREAM_OFF	2
+#define MSM_V4L2_SNAPSHOT	3
+#define MSM_V4L2_QUERY_CTRL	4
+#define MSM_V4L2_GET_CTRL	5
+#define MSM_V4L2_SET_CTRL	6
+#define MSM_V4L2_QUERY		7
+#define MSM_V4L2_MAX		8
+
+struct crop_info {
+	void *info;
+	int len;
+};
+
+struct msm_postproc {
+	int ftnum;
+	struct msm_frame fthumnail;
+	int fmnum;
+	struct msm_frame fmain;
+};
+
+struct msm_snapshot_pp_status {
+	void *status;
+};
+
+#define CFG_SET_MODE			0
+#define CFG_SET_EFFECT			1
+#define CFG_START			2
+#define CFG_PWR_UP			3
+#define CFG_PWR_DOWN			4
+#define CFG_WRITE_EXPOSURE_GAIN		5
+#define CFG_SET_DEFAULT_FOCUS		6
+#define CFG_MOVE_FOCUS			7
+#define CFG_REGISTER_TO_REAL_GAIN	8
+#define CFG_REAL_TO_REGISTER_GAIN	9
+#define CFG_SET_FPS			10
+#define CFG_SET_PICT_FPS		11
+#define CFG_SET_BRIGHTNESS		12
+#define CFG_SET_CONTRAST		13
+#define CFG_SET_ZOOM			14
+#define CFG_SET_EXPOSURE_MODE		15
+#define CFG_SET_WB			16
+#define CFG_SET_ANTIBANDING		17
+#define CFG_SET_EXP_GAIN		18
+#define CFG_SET_PICT_EXP_GAIN		19
+#define CFG_SET_LENS_SHADING		20
+#define CFG_GET_PICT_FPS		21
+#define CFG_GET_PREV_L_PF		22
+#define CFG_GET_PREV_P_PL		23
+#define CFG_GET_PICT_L_PF		24
+#define CFG_GET_PICT_P_PL		25
+#define CFG_GET_AF_MAX_STEPS		26
+#define CFG_GET_PICT_MAX_EXP_LC		27
+#define CFG_MAX				28
+
+#define MOVE_NEAR	0
+#define MOVE_FAR	1
+
+#define SENSOR_PREVIEW_MODE		0
+#define SENSOR_SNAPSHOT_MODE		1
+#define SENSOR_RAW_SNAPSHOT_MODE	2
+
+#define SENSOR_QTR_SIZE			0
+#define SENSOR_FULL_SIZE		1
+#define SENSOR_INVALID_SIZE		2
+
+#define CAMERA_EFFECT_OFF		0
+#define CAMERA_EFFECT_MONO		1
+#define CAMERA_EFFECT_NEGATIVE		2
+#define CAMERA_EFFECT_SOLARIZE		3
+#define CAMERA_EFFECT_PASTEL		4
+#define CAMERA_EFFECT_MOSAIC		5
+#define CAMERA_EFFECT_RESIZE		6
+#define CAMERA_EFFECT_SEPIA		7
+#define CAMERA_EFFECT_POSTERIZE		8
+#define CAMERA_EFFECT_WHITEBOARD	9
+#define CAMERA_EFFECT_BLACKBOARD	10
+#define CAMERA_EFFECT_AQUA		11
+#define CAMERA_EFFECT_MAX		12
+
+struct sensor_pict_fps {
+	uint16_t prevfps;
+	uint16_t pictfps;
+};
+
+struct exp_gain_cfg {
+	uint16_t gain;
+	uint32_t line;
+};
+
+struct focus_cfg {
+	int32_t steps;
+	int dir;
+};
+
+struct fps_cfg {
+	uint16_t f_mult;
+	uint16_t fps_div;
+	uint32_t pict_fps_div;
+};
+
+struct sensor_cfg_data {
+	int cfgtype;
+	int mode;
+	int rs;
+	uint8_t max_steps;
+
+	union {
+		int8_t effect;
+		uint8_t lens_shading;
+		uint16_t prevl_pf;
+		uint16_t prevp_pl;
+		uint16_t pictl_pf;
+		uint16_t pictp_pl;
+		uint32_t pict_max_exp_lc;
+		uint16_t p_fps;
+		struct sensor_pict_fps gfps;
+		struct exp_gain_cfg exp_gain;
+		struct focus_cfg focus;
+		struct fps_cfg fps;
+	} cfg;
+};
+
+#define GET_NAME			0
+#define GET_PREVIEW_LINE_PER_FRAME	1
+#define GET_PREVIEW_PIXELS_PER_LINE	2
+#define GET_SNAPSHOT_LINE_PER_FRAME	3
+#define GET_SNAPSHOT_PIXELS_PER_LINE	4
+#define GET_SNAPSHOT_FPS		5
+#define GET_SNAPSHOT_MAX_EP_LINE_CNT	6
+
+struct msm_camsensor_info {
+	char name[MAX_SENSOR_NAME];
+	uint8_t flash_enabled;
+};
+#endif /* __LINUX_MSM_CAMERA_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/pmem.c linux-libre-2.6.34-gnu1/drivers/staging/dream/pmem.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/pmem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/pmem.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/android_pmem.h>
 #include <linux/mempolicy.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
@@ -37,17 +38,17 @@
  * the file should not be released until put_pmem_file is called */
 #define PMEM_FLAGS_BUSY 0x1
 /* indicates that this is a suballocation of a larger master range */
-#define PMEM_FLAGS_CONNECTED 0x1 << 1
+#define PMEM_FLAGS_CONNECTED ( 0x1 << 1 )
 /* indicates this is a master and not a sub allocation and that it is mmaped */
-#define PMEM_FLAGS_MASTERMAP 0x1 << 2
+#define PMEM_FLAGS_MASTERMAP ( 0x1 << 2 )
 /* submap and unsubmap flags indicate:
  * 00: subregion has never been mmaped
  * 10: subregion has been mmaped, reference to the mm was taken
  * 11: subretion has ben released, refernece to the mm still held
  * 01: subretion has been released, reference to the mm has been released
  */
-#define PMEM_FLAGS_SUBMAP 0x1 << 3
-#define PMEM_FLAGS_UNSUBMAP 0x1 << 4
+#define PMEM_FLAGS_SUBMAP ( 0x1 << 3 )
+#define PMEM_FLAGS_UNSUBMAP ( 0x1 << 4 )
 
 
 struct pmem_data {
@@ -91,7 +92,7 @@ struct pmem_region_node {
 
 #define PMEM_DEBUG_MSGS 0
 #if PMEM_DEBUG_MSGS
-#define DLOG(fmt,args...) \
+#define DLOG(fmt, args...) \
 	do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
 		    ##args); } \
 	while (0)
@@ -152,7 +153,7 @@ struct pmem_info {
 static struct pmem_info pmem[PMEM_MAX_DEVICES];
 static int id_count;
 
-#define PMEM_IS_FREE(id, index) !(pmem[id].bitmap[index].allocated)
+#define PMEM_IS_FREE(id, index) ( !(pmem[id].bitmap[index].allocated) )
 #define PMEM_ORDER(id, index) pmem[id].bitmap[index].order
 #define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index)))
 #define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index)))
@@ -708,9 +709,8 @@ int get_pmem_addr(struct file *file, uns
 	struct pmem_data *data;
 	int id;
 
-	if (!is_pmem_file(file) || !has_allocation(file)) {
+	if (!is_pmem_file(file) || !has_allocation(file))
 		return -1;
-	}
 
 	data = (struct pmem_data *)file->private_data;
 	if (data->index == -1) {
@@ -789,9 +789,8 @@ void flush_pmem_file(struct file *file,
 	struct list_head *elt;
 	void *flush_start, *flush_end;
 
-	if (!is_pmem_file(file) || !has_allocation(file)) {
+	if (!is_pmem_file(file) || !has_allocation(file))
 		return;
-	}
 
 	id = get_id(file);
 	data = (struct pmem_data *)file->private_data;
@@ -833,7 +832,7 @@ static int pmem_connect(unsigned long co
 	src_file = fget_light(connect, &put_needed);
 	DLOG("connect %p to %p\n", file, src_file);
 	if (!src_file) {
-		printk("pmem: src file not found!\n");
+		printk(KERN_INFO "pmem: src file not found!\n");
 		ret = -EINVAL;
 		goto err_no_file;
 	}
@@ -846,7 +845,7 @@ static int pmem_connect(unsigned long co
 	src_data = (struct pmem_data *)src_file->private_data;
 
 	if (has_allocation(file) && (data->index != src_data->index)) {
-		printk("pmem: file is already mapped but doesn't match this"
+		printk(KERN_INFO "pmem: file is already mapped but doesn't match this"
 		       " src_file!\n");
 		ret = -EINVAL;
 		goto err_bad_file;
@@ -885,7 +884,7 @@ lock_mm:
 		mm = get_task_mm(data->task);
 		if (!mm) {
 #if PMEM_DEBUG
-			printk("pmem: can't remap task is gone!\n");
+			printk(KERN_DEBUG "pmem: can't remap task is gone!\n");
 #endif
 			up_read(&data->sem);
 			return -1;
@@ -936,7 +935,7 @@ int pmem_remap(struct pmem_region *regio
 	if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) ||
 		 !PMEM_IS_PAGE_ALIGNED(region->len))) {
 #if PMEM_DEBUG
-		printk("pmem: request for unaligned pmem suballocation "
+		printk(KERN_DEBUG "pmem: request for unaligned pmem suballocation "
 		       "%lx %lx\n", region->offset, region->len);
 #endif
 		return -EINVAL;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/adsp.c linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/adsp.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/adsp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/adsp.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/kthread.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/wait.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/adsp_driver.c linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/adsp_driver.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/adsp_driver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/adsp_driver.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/list.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 
 #include "adsp.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audio_aac.c linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audio_aac.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audio_aac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audio_aac.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/kthread.h>
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <linux/delay.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audio_amrnb.c linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audio_amrnb.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audio_amrnb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audio_amrnb.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/kthread.h>
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <linux/delay.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audio_evrc.c linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audio_evrc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audio_evrc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audio_evrc.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 #include <asm/atomic.h>
 #include <asm/ioctls.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audio_in.c linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audio_in.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audio_in.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audio_in.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/kthread.h>
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <linux/delay.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audio_mp3.c linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audio_mp3.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audio_mp3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audio_mp3.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/kthread.h>
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <linux/delay.h>
 
@@ -650,8 +651,7 @@ static long audio_ioctl(struct file *fil
 						       &audio->read_phys,
 						       GFP_KERNEL);
 				if (!audio->read_data) {
-					pr_err("audio_mp3: malloc pcm \
-					buf failed\n");
+					pr_err("audio_mp3: malloc pcm buf failed\n");
 					rc = -1;
 				} else {
 					uint8_t index;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audio_out.c linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audio_out.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audio_out.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audio_out.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/wakelock.h>
+#include <linux/gfp.h>
 
 #include <linux/msm_audio.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audio_qcelp.c linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audio_qcelp.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audio_qcelp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audio_qcelp.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <asm/ioctls.h>
 #include <mach/msm_adsp.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audmgr.c linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audmgr.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/audmgr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/audmgr.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <linux/kthread.h>
 #include <linux/wait.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/Makefile linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/qdsp5/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/qdsp5/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,3 +1,4 @@
+EXTRA_CFLAGS=-Idrivers/staging/dream/include
 obj-y += adsp.o
 ifeq ($(CONFIG_MSM_AMSS_VERSION_6350),y)
 obj-y += adsp_info.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/smd/Makefile linux-libre-2.6.34-gnu1/drivers/staging/dream/smd/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/smd/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/smd/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,3 +1,4 @@
+EXTRA_CFLAGS=-Idrivers/staging/dream/include
 obj-$(CONFIG_MSM_SMD) += smd.o smd_tty.o smd_qmi.o
 obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter.o
 obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_device.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/smd/smd_rpcrouter.c linux-libre-2.6.34-gnu1/drivers/staging/dream/smd/smd_rpcrouter.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/smd/smd_rpcrouter.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/smd/smd_rpcrouter.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,13 +33,12 @@
 #include <linux/err.h>
 #include <linux/sched.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
 
-#include <asm/byteorder.h>
-
 #include <mach/msm_smd.h>
 #include "smd_rpcrouter.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/smd/smd_rpcrouter_device.c linux-libre-2.6.34-gnu1/drivers/staging/dream/smd/smd_rpcrouter_device.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/smd/smd_rpcrouter_device.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/smd/smd_rpcrouter_device.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/poll.h>
 #include <linux/platform_device.h>
 #include <linux/msm_rpcrouter.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/smd/smd_rpcrouter_servers.c linux-libre-2.6.34-gnu1/drivers/staging/dream/smd/smd_rpcrouter_servers.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/smd/smd_rpcrouter_servers.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/smd/smd_rpcrouter_servers.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/wakelock.h>
+#include <linux/slab.h>
 
 #include <linux/msm_rpcrouter.h>
 #include <linux/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dream/synaptics_i2c_rmi.c linux-libre-2.6.34-gnu1/drivers/staging/dream/synaptics_i2c_rmi.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dream/synaptics_i2c_rmi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dream/synaptics_i2c_rmi.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #ifdef CONFIG_HAS_EARLYSUSPEND
 #include <linux/earlysuspend.h>
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dt3155/allocator.c linux-libre-2.6.34-gnu1/drivers/staging/dt3155/allocator.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dt3155/allocator.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dt3155/allocator.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,296 @@
+/*
+ * allocator.c -- allocate after high_memory, if available
+ *
+ * NOTE: this is different from my previous allocator, the one that
+ *       assembles pages, which revealed itself both slow and unreliable.
+ *
+ * Copyright (C) 1998   rubini@linux.it (Alessandro Rubini)
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+
+-- Changes --
+
+  Date	      Programmer  Description of changes made
+  -------------------------------------------------------------------
+  02-Aug-2002 NJC         allocator now steps in 1MB increments, rather
+			  than doubling its size each time.
+			  Also, allocator_init(u32 *) now returns
+			  (in the first arg) the size of the free
+			  space.  This is no longer consistent with
+			  using the allocator as a module, and some changes
+			  may be necessary for that purpose.  This was
+			  designed to work with the DT3155 driver, in
+			  stand alone mode only!!!
+  26-Oct-2009 SS	  Port to 2.6.30 kernel.
+ */
+
+
+#ifndef __KERNEL__
+#  define __KERNEL__
+#endif
+#ifndef MODULE
+#  define MODULE
+#endif
+
+#include <linux/version.h>
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/mm.h>	/* PAGE_ALIGN() */
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <asm/page.h>
+
+/*#define ALL_DEBUG*/
+#define ALL_MSG "allocator: "
+
+#undef PDEBUG             /* undef it, just in case */
+#ifdef ALL_DEBUG
+#  define __static
+#  define DUMP_LIST() dump_list()
+#  ifdef __KERNEL__
+     /* This one if debugging is on, and kernel space */
+#    define PDEBUG(fmt, args...) printk(KERN_DEBUG ALL_MSG fmt, ## args)
+#  else
+     /* This one for user space */
+#    define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
+#  endif
+#else
+#  define PDEBUG(fmt, args...) /* not debugging: nothing */
+#  define DUMP_LIST()
+#  define __static static
+#endif
+
+#undef PDEBUGG
+#define PDEBUGG(fmt, args...)
+/*#define PDEBUGG(fmt, args...) printk( KERN_DEBUG ALL_MSG fmt, ## args)*/
+
+
+int allocator_himem = 1; /* 0 = probe, pos. = megs, neg. = disable   */
+int allocator_step = 1;  /* This is the step size in MB              */
+int allocator_probe = 1; /* This is a flag -- 1=probe, 0=don't probe */
+
+static unsigned long allocator_buffer;		/* physical address */
+static unsigned long allocator_buffer_size;	/* kilobytes */
+
+/*
+ * The allocator keeps a list of DMA areas, so multiple devices
+ * can coexist. The list is kept sorted by address
+ */
+
+struct allocator_struct {
+	unsigned long address;
+	unsigned long size;
+	struct allocator_struct *next;
+};
+
+struct allocator_struct *allocator_list;
+
+
+#ifdef ALL_DEBUG
+static int dump_list(void)
+{
+	struct allocator_struct *ptr;
+
+	PDEBUG("Current list:\n");
+	for (ptr = allocator_list; ptr; ptr = ptr->next)
+		PDEBUG("0x%08lx (size %likB)\n", ptr->address, ptr->size>>10);
+	return 0;
+}
+#endif
+
+/* ========================================================================
+ * This function is the actual allocator.
+ *
+ * If space is available in high memory (as detected at load time), that
+ * one is returned. The return value is a physical address (i.e., it can
+ * be used straight ahead for DMA, but needs remapping for program use).
+ */
+
+unsigned long allocator_allocate_dma(unsigned long kilobytes, int prio)
+{
+	struct allocator_struct *ptr = allocator_list, *newptr;
+	unsigned long bytes = kilobytes << 10;
+
+	/* check if high memory is available */
+	if (!allocator_buffer)
+		return 0;
+
+	/* Round it to a multiple of the pagesize */
+	bytes = PAGE_ALIGN(bytes);
+	PDEBUG("request for %li bytes\n", bytes);
+
+	while (ptr && ptr->next) {
+		if (ptr->next->address - (ptr->address + ptr->size) >= bytes)
+			break; /* enough space */
+		ptr = ptr->next;
+	}
+	if (!ptr->next) {
+		DUMP_LIST();
+		PDEBUG("alloc failed\n");
+		return 0; /* end of list */
+	}
+	newptr = kmalloc(sizeof(struct allocator_struct), prio);
+	if (!newptr)
+		return 0;
+
+	/* ok, now stick it after ptr */
+	newptr->address = ptr->address + ptr->size;
+	newptr->size = bytes;
+	newptr->next = ptr->next;
+	ptr->next = newptr;
+
+	DUMP_LIST();
+	PDEBUG("returning 0x%08lx\n", newptr->address);
+	return newptr->address;
+}
+
+int allocator_free_dma(unsigned long address)
+{
+	struct allocator_struct *ptr = allocator_list, *prev;
+
+	while (ptr && ptr->next) {
+		if (ptr->next->address == address)
+			break;
+		ptr = ptr->next;
+	}
+	/* the one being freed is ptr->next */
+	prev = ptr; ptr = ptr->next;
+
+	if (!ptr) {
+		printk(KERN_ERR ALL_MSG
+			"free_dma(0x%08lx) but add. not allocated\n",
+			ptr->address);
+		return -EINVAL;
+	}
+	PDEBUGG("freeing: %08lx (%li) next %08lx\n", ptr->address, ptr->size,
+		ptr->next->address);
+	prev->next = ptr->next;
+	kfree(ptr);
+
+	/* dump_list(); */
+	return 0;
+}
+
+/* ========================================================================
+ * Init and cleanup
+ *
+ * On cleanup everything is released. If the list is not empty, that a
+ * problem of our clients
+ */
+int allocator_init(u32 *allocator_max)
+{
+	/* check how much free memory is there */
+	void *remapped;
+	unsigned long max;
+	unsigned long trial_size = allocator_himem<<20;
+	unsigned long last_trial = 0;
+	unsigned long step = allocator_step<<20;
+	unsigned long i = 0;
+	struct allocator_struct *head, *tail;
+	char test_string[] = "0123456789abcde"; /* 16 bytes */
+
+	PDEBUGG("himem = %i\n", allocator_himem);
+	if (allocator_himem < 0) /* don't even try */
+		return -EINVAL;
+
+	if (!trial_size)
+		trial_size = 1<<20; /* not specified: try one meg */
+
+	while (1) {
+		remapped = ioremap(__pa(high_memory), trial_size);
+		if (!remapped) {
+			PDEBUGG("%li megs failed!\n", trial_size>>20);
+			break;
+		}
+		PDEBUGG("Trying %li megs (at %p, %p)\n", trial_size>>20,
+			(void *)__pa(high_memory), remapped);
+		for (i = last_trial; i < trial_size; i += 16) {
+			strcpy((char *)(remapped)+i, test_string);
+			if (strcmp((char *)(remapped)+i, test_string))
+				break;
+			}
+		iounmap((void *)remapped);
+		schedule();
+		last_trial = trial_size;
+		if (i == trial_size)
+			trial_size += step; /* increment, if all went well */
+		else {
+			PDEBUGG("%li megs copy test failed!\n", trial_size>>20);
+			break;
+		}
+		if (!allocator_probe)
+			break;
+	}
+	PDEBUG("%li megs (%li k, %li b)\n", i>>20, i>>10, i);
+	allocator_buffer_size = i>>10; /* kilobytes */
+	allocator_buffer = __pa(high_memory);
+	if (!allocator_buffer_size) {
+		printk(KERN_WARNING ALL_MSG "no free high memory to use\n");
+		return -ENOMEM;
+	}
+
+	/*
+	* to simplify things, always have two cells in the list:
+	* the first and the last. This avoids some conditionals and
+	* extra code when allocating and deallocating: we only play
+	* in the middle of the list
+	*/
+	head = kmalloc(sizeof(struct allocator_struct), GFP_KERNEL);
+	if (!head)
+		return -ENOMEM;
+	tail = kmalloc(sizeof(struct allocator_struct), GFP_KERNEL);
+	if (!tail) {
+		kfree(head);
+		return -ENOMEM;
+	}
+
+	max = allocator_buffer_size<<10;
+
+	head->size = tail->size = 0;
+	head->address = allocator_buffer;
+	tail->address = allocator_buffer + max;
+	head->next = tail;
+	tail->next = NULL;
+	allocator_list = head;
+
+	/* Back to the user code, in KB */
+	*allocator_max = allocator_buffer_size;
+
+	return 0; /* ok, ready */
+}
+
+void allocator_cleanup(void)
+{
+	struct allocator_struct *ptr, *next;
+
+	for (ptr = allocator_list; ptr; ptr = next) {
+		next = ptr->next;
+		PDEBUG("freeing list: 0x%08lx\n", ptr->address);
+		kfree(ptr);
+	}
+
+	allocator_buffer      = 0;
+	allocator_buffer_size = 0;
+	allocator_list = NULL;
+}
+
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dt3155/allocator.h linux-libre-2.6.34-gnu1/drivers/staging/dt3155/allocator.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dt3155/allocator.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dt3155/allocator.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,28 @@
+/*
+ * allocator.h -- prototypes for allocating high memory
+ *
+ * NOTE: this is different from my previous allocator, the one that
+ *       assembles pages, which revealed itself both slow and unreliable.
+ *
+ * Copyright (C) 1998   rubini@linux.it (Alessandro Rubini)
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+void allocator_free_dma(unsigned long address);
+unsigned long allocator_allocate_dma(unsigned long kilobytes, int priority);
+int allocator_init(u32 *);
+void allocator_cleanup(void);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dt3155/allocator.README linux-libre-2.6.34-gnu1/drivers/staging/dt3155/allocator.README
--- linux-libre-2.6.33-gnu1/drivers/staging/dt3155/allocator.README	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dt3155/allocator.README	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,98 @@
+
+The allocator shown here  exploits high memory. This document explains
+how  a user can  deal   with drivers uses   this  allocator and how  a
+programmer can link in the module.
+
+The module is being used by my pxc and pxdrv device drivers (as well as
+other ones), available from ftp.systemy.it/pub/develop and
+ftp.linux.it/pub/People/Rubini
+
+	User's manual
+	=============
+
+
+One of the most compelling problems with any DMA-capable device is the
+allocation  of a suitable  memory buffer. The "allocator" module tries
+to deal with  the problem in  a clean way.  The module is  able to use
+high   memory  (above the  one   used in  normal   operation)  for DMA
+allocation.
+
+To prevent  the  kernel for using   high memory,  so  that it  remains
+available for  DMA, you should  pass a  command  line argument to  the
+kernel.  Command line arguments  can be passed to  Lilo, to Loadlin or
+to whichever loader  you are using  (unless it's very poor in design).
+For Lilo, either use  "append=" in  /etc/lilo.conf or add  commandline
+arguments to the  interactive prompt. For  example, I have a 32MB  box
+and reserve two megs for DMA:
+
+In lilo.conf:
+	image = /zImage
+	label = linux
+	append = "mem=30M"
+
+Or, interactively:
+	LILO: linux mem=30M
+
+Once  the kernel is booted  with the  right command-line argument, any
+driver  linked   with  the  allocator   module  will  be able   to get
+DMA-capable memory without  much  trouble (unless the  various drivers
+need more memory than available).
+
+The module implements an alloc/free  mechanism,  so that it can  serve
+multiple drivers  at the  same time. Note  however that  the allocator
+uses all of  high memory and assumes to  be the only piece of software
+using such memory.
+
+
+	Programmer's manual
+	===================
+
+The allocator,  as  released, is designed  to  be linked  to  a device
+driver.  In this  case, the driver  must call allocator_init()  before
+using   the  allocator   and  must  call   allocator_cleanup()  before
+unloading.  This is  usually  done   from within  init_module()    and
+cleanup_module(). If the allocator is linked to  a driver, it won't be
+possible for several drivers to allocate high DMA memory, as explained
+above.
+
+It is possible, on the other hand, to compile the module as a standalone
+module, so that several modules can rely on the allocator for they DMA
+buffers. To compile the allocator as a standalone module, do the
+following in this directory (or provide a suitable Makefile, or edit
+the source code):
+
+	make allocator.o CC="gcc -Dallocator_init=init_module -Dallocator_cleanup=cleanup_module -include /usr/include/linux/module.h"
+
+The previous commandline  tells   to include <linux/module.h>  in  the
+first place,  and to rename the init  and cleanup function to the ones
+needed for  module loading and  unloading.  Drivers using a standalone
+allocator won't need to call allocator_init() nor allocator_cleanup().
+
+The allocator exports the following functions (declared in allocator.h):
+
+   unsigned long allocator_allocate_dma (unsigned long kilobytes,
+					 int priority);
+
+	This function returns a physical address, over high_memory,
+	which corresponds to an area of at least "kilobytes" kilobytes.
+	The area will be owned by the module calling the function.
+	The returned address can be passed to device boards, to instruct
+	their DMA controllers, via phys_to_bus(). The address can be used
+	by C code after vremap()/ioremap(). The "priority" argument should
+	be GFP_KERNEL or GFP_ATOMIC, according to the context of the
+	caller; it is used to call kmalloc(), as the allocator must keep
+	track of any region it gives away. In case of error the function
+	returns 0, and the caller is expected to issue a -ENOMEM error.
+
+
+   void allocator_free_dma (unsigned long address);
+
+	This function is the reverse of the previous one. If a driver
+	doesn't free the DMA memory it allocated, the allocator will
+	consider such memory as busy. Note, however, that
+	allocator_cleanup() calls kfree() on every region it reclaimed,
+	so that a driver with the allocator linked in can avoid calling
+	allocator_free_dma() at unload time.
+
+
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155_drv.c linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155_drv.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155_drv.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155_drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1087 @@
+/*
+
+Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
+                         Jason Lapenta, Scott Smedley, Greg Sharp
+
+This file is part of the DT3155 Device Driver.
+
+The DT3155 Device Driver is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The DT3155 Device Driver is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the DT3155 Device Driver; if not, write to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+MA 02111-1307 USA
+
+-- Changes --
+
+  Date     Programmer	Description of changes made
+  -------------------------------------------------------------------
+  03-Jul-2000 JML       n/a
+  10-Oct-2001 SS        port to 2.4 kernel
+  02-Apr-2002 SS        Mods to use allocator as a standalone module;
+                        Merged John Roll's changes (john@cfa.harvard.edu)
+                        to make work with multiple boards.
+  02-Jul-2002 SS        Merged James Rose's chages (rosejr@purdue.edu) to:
+                         * fix successive interrupt-driven captures
+                         * add select/poll support.
+  10-Jul-2002 GCS       Add error check when ndevices > MAXBOARDS.
+  02-Aug-2002 GCS       Fix field mode so that odd (lower) field is stored
+                        in lower half of buffer.
+  05-Aug-2005 SS        port to 2.6 kernel.
+  26-Oct-2009 SS	port to 2.6.30 kernel.
+
+-- Notes --
+
+** appended "mem=124" in lilo.conf to allow for 4megs free on my 128meg system.
+ * using allocator.c and allocator.h from o'reilly book (alessandro rubini)
+    ftp://ftp.systemy.it/pub/develop (see README.allocator)
+
+ + might want to get rid of MAXboards for allocating initial buffer.
+    confusing and not necessary
+
+ + in cleanup_module the MOD_IN_USE looks like it is check after it should
+
+ * GFP_DMA should not be set with a PCI system (pg 291)
+
+ - NJC why are only two buffers allowed? (see isr, approx line 358)
+
+*/
+
+extern void printques(int);
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include "dt3155.h"
+#include "dt3155_drv.h"
+#include "dt3155_isr.h"
+#include "dt3155_io.h"
+#include "allocator.h"
+
+
+MODULE_LICENSE("GPL");
+
+/* Error variable.  Zero means no error. */
+int dt3155_errno = 0;
+
+#ifndef PCI_DEVICE_ID_INTEL_7116
+#define PCI_DEVICE_ID_INTEL_7116 0x1223
+#endif
+
+#define DT3155_VENDORID    PCI_VENDOR_ID_INTEL
+#define DT3155_DEVICEID    PCI_DEVICE_ID_INTEL_7116
+#define MAXPCI    16
+
+#ifdef DT_DEBUG
+#define DT_3155_DEBUG_MSG(x,y) printk(x,y)
+#else
+#define DT_3155_DEBUG_MSG(x,y)
+#endif
+
+/* wait queue for interrupts */
+wait_queue_head_t dt3155_read_wait_queue[ MAXBOARDS ];
+
+#define DT_3155_SUCCESS 0
+#define DT_3155_FAILURE -EIO
+
+/* set to dynamicaly allocate, but it is tunable: */
+/* insmod DT_3155 dt3155 dt3155_major=XX */
+int dt3155_major = 0;
+
+/* The minor numbers are 0 and 1 ... they are not tunable.
+ * They are used as the indices for the structure vectors,
+ * and register address vectors
+ */
+
+/* Global structures and variables */
+
+/* Status of each device */
+struct dt3155_status_s dt3155_status[ MAXBOARDS ];
+
+/* kernel logical address of the board */
+u8 *dt3155_lbase[ MAXBOARDS ] = { NULL
+#if MAXBOARDS == 2
+				      , NULL
+#endif
+};
+/* DT3155 registers              */
+u8 *dt3155_bbase = NULL;		  /* kernel logical address of the *
+					   * buffer region                 */
+u32  dt3155_dev_open[ MAXBOARDS ] = {0
+#if MAXBOARDS == 2
+				       , 0
+#endif
+};
+
+u32  ndevices = 0;
+u32 unique_tag = 0;;
+
+
+/*
+ * Stops interrupt generation right away and resets the status
+ * to idle.  I don't know why this works and the other way doesn't.
+ * (James Rose)
+ */
+static void quick_stop (int minor)
+{
+  // TODO: scott was here
+#if 1
+  ReadMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg);
+  /* disable interrupts */
+  int_csr_r.fld.FLD_END_EVE_EN = 0;
+  int_csr_r.fld.FLD_END_ODD_EN = 0;
+  WriteMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg );
+
+  dt3155_status[ minor ].state &= ~(DT3155_STATE_STOP|0xff);
+  /* mark the system stopped: */
+  dt3155_status[ minor ].state |= DT3155_STATE_IDLE;
+  dt3155_fbuffer[ minor ]->stop_acquire = 0;
+  dt3155_fbuffer[ minor ]->even_stopped = 0;
+#else
+  dt3155_status[minor].state |= DT3155_STATE_STOP;
+  dt3155_status[minor].fbuffer.stop_acquire = 1;
+#endif
+
+}
+
+
+/*****************************************************
+ *  dt3155_isr() Interrupt service routien
+ *
+ * - looks like this isr supports IRQ sharing (or could) JML
+ * - Assumes irq's are disabled, via SA_INTERRUPT flag
+ * being set in request_irq() call from init_module()
+ *****************************************************/
+static inline void dt3155_isr( int irq, void *dev_id, struct pt_regs *regs )
+{
+  int    minor = -1;
+  int    index;
+  unsigned long flags;
+  u32 buffer_addr;
+
+  /* find out who issued the interrupt */
+  for ( index = 0; index < ndevices; index++ ) {
+    if( dev_id == (void*) &dt3155_status[ index ])
+      {
+	minor = index;
+	break;
+      }
+  }
+
+  /* hopefully we should not get here */
+  if ( minor < 0 || minor >= MAXBOARDS ) {
+    printk(KERN_ERR "dt3155_isr called with invalid dev_id\n");
+    return;
+  }
+
+  /* Check for corruption and set a flag if so */
+  ReadMReg( (dt3155_lbase[ minor ] + CSR1), csr1_r.reg );
+
+  if ( (csr1_r.fld.FLD_CRPT_EVE) || (csr1_r.fld.FLD_CRPT_ODD) )
+    {
+      /* TODO: this should probably stop acquisition */
+      /* and set some flags so that dt3155_read      */
+      /* returns an error next time it is called     */
+      dt3155_errno = DT_ERR_CORRUPT;
+      printk("dt3155:  corrupt field\n");
+      return;
+    }
+
+  ReadMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg);
+
+  /* Handle the even field ... */
+  if (int_csr_r.fld.FLD_END_EVE)
+    {
+      if ( (dt3155_status[ minor ].state & DT3155_STATE_MODE) ==
+	   DT3155_STATE_FLD )
+	{
+	  dt3155_fbuffer[ minor ]->frame_count++;
+	}
+
+      ReadI2C(dt3155_lbase[ minor ], EVEN_CSR, &i2c_even_csr.reg);
+
+      /* Clear the interrupt? */
+      int_csr_r.fld.FLD_END_EVE = 1;
+
+      /* disable the interrupt if last field */
+      if (dt3155_fbuffer[ minor ]->stop_acquire)
+	{
+	  printk("dt3155:  even stopped.\n");
+	  dt3155_fbuffer[ minor ]->even_stopped = 1;
+	  if (i2c_even_csr.fld.SNGL_EVE)
+	    {
+	      int_csr_r.fld.FLD_END_EVE_EN = 0;
+	    }
+	  else
+	    {
+	      i2c_even_csr.fld.SNGL_EVE  = 1;
+	    }
+	}
+
+      WriteMReg( (dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg );
+
+      /* Set up next DMA if we are doing FIELDS */
+      if ( (dt3155_status[ minor ].state & DT3155_STATE_MODE ) ==
+	   DT3155_STATE_FLD)
+	{
+	  /* GCS (Aug 2, 2002) -- In field mode, dma the odd field
+	     into the lower half of the buffer */
+	  const u32 stride =  dt3155_status[ minor ].config.cols;
+	  buffer_addr = dt3155_fbuffer[ minor ]->
+	    frame_info[ dt3155_fbuffer[ minor ]->active_buf ].addr
+	    + (DT3155_MAX_ROWS / 2) * stride;
+	  local_save_flags(flags);
+	  local_irq_disable();
+	  wake_up_interruptible( &dt3155_read_wait_queue[ minor ] );
+
+	  /* Set up the DMA address for the next field */
+	  local_irq_restore(flags);
+	  WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_START), buffer_addr);
+	}
+
+      /* Check for errors. */
+      i2c_even_csr.fld.DONE_EVE = 1;
+      if ( i2c_even_csr.fld.ERROR_EVE )
+	dt3155_errno = DT_ERR_OVERRUN;
+
+      WriteI2C( dt3155_lbase[ minor ], EVEN_CSR, i2c_even_csr.reg );
+
+      /* Note that we actually saw an even field meaning  */
+      /* that subsequent odd field complete the frame     */
+      dt3155_fbuffer[ minor ]->even_happened = 1;
+
+      /* recording the time that the even field finished, this should be */
+      /* about time in the middle of the frame */
+      do_gettimeofday( &(dt3155_fbuffer[ minor ]->
+			 frame_info[ dt3155_fbuffer[ minor ]->
+				     active_buf ].time) );
+      return;
+    }
+
+  /* ... now handle the odd field */
+  if ( int_csr_r.fld.FLD_END_ODD )
+    {
+      ReadI2C( dt3155_lbase[ minor ], ODD_CSR, &i2c_odd_csr.reg );
+
+      /* Clear the interrupt? */
+      int_csr_r.fld.FLD_END_ODD = 1;
+
+      if (dt3155_fbuffer[ minor ]->even_happened ||
+	  (dt3155_status[ minor ].state & DT3155_STATE_MODE) ==
+	  DT3155_STATE_FLD)
+	{
+	  dt3155_fbuffer[ minor ]->frame_count++;
+	}
+
+      if ( dt3155_fbuffer[ minor ]->stop_acquire &&
+	   dt3155_fbuffer[ minor ]->even_stopped )
+	{
+	  printk(KERN_DEBUG "dt3155:  stopping odd..\n");
+	  if ( i2c_odd_csr.fld.SNGL_ODD )
+	    {
+	      /* disable interrupts */
+	      int_csr_r.fld.FLD_END_ODD_EN = 0;
+	      dt3155_status[ minor ].state &= ~(DT3155_STATE_STOP|0xff);
+
+	      /* mark the system stopped: */
+	      dt3155_status[ minor ].state |= DT3155_STATE_IDLE;
+	      dt3155_fbuffer[ minor ]->stop_acquire = 0;
+	      dt3155_fbuffer[ minor ]->even_stopped = 0;
+
+	      printk(KERN_DEBUG "dt3155:  state is now %x\n",
+		     dt3155_status[minor].state);
+	    }
+	  else
+	    {
+	      i2c_odd_csr.fld.SNGL_ODD  = 1;
+	    }
+	}
+
+      WriteMReg( (dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg );
+
+      /* if the odd field has been acquired, then     */
+      /* change the next dma location for both fields */
+      /* and wake up the process if sleeping          */
+      if ( dt3155_fbuffer[ minor ]->even_happened ||
+	   (dt3155_status[ minor ].state & DT3155_STATE_MODE) ==
+	   DT3155_STATE_FLD )
+	{
+
+	  local_save_flags(flags);
+	  local_irq_disable();
+
+#ifdef DEBUG_QUES_B
+	  printques( minor );
+#endif
+	  if ( dt3155_fbuffer[ minor ]->nbuffers > 2 )
+	    {
+	      if ( !are_empty_buffers( minor ) )
+		{
+		  /* The number of active + locked buffers is
+		   * at most 2, and since there are none empty, there
+		   * must be at least nbuffers-2 ready buffers.
+		   * This is where we 'drop frames', oldest first. */
+		  push_empty( pop_ready( minor ),  minor );
+		}
+
+	      /* The ready_que can't be full, since we know
+	       * there is one active buffer right now, so it's safe
+	       * to push the active buf on the ready_que. */
+	      push_ready( minor, dt3155_fbuffer[ minor ]->active_buf );
+	      /* There's at least 1 empty -- make it active */
+	      dt3155_fbuffer[ minor ]->active_buf = pop_empty( minor );
+	      dt3155_fbuffer[ minor ]->
+		frame_info[ dt3155_fbuffer[ minor ]->
+			    active_buf ].tag = ++unique_tag;
+	    }
+	  else /* nbuffers == 2, special case */
+	    { /* There is 1 active buffer.
+	       * If there is a locked buffer, keep the active buffer
+	       * the same -- that means we drop a frame.
+	       */
+	      if ( dt3155_fbuffer[ minor ]->locked_buf < 0 )
+		{
+		  push_ready( minor,
+			      dt3155_fbuffer[ minor ]->active_buf );
+		  if (are_empty_buffers( minor ) )
+		    {
+		      dt3155_fbuffer[ minor ]->active_buf =
+			pop_empty( minor );
+		    }
+		  else
+		    { /* no empty or locked buffers, so use a readybuf */
+		      dt3155_fbuffer[ minor ]->active_buf =
+			pop_ready( minor );
+		    }
+		}
+	    }
+
+#ifdef DEBUG_QUES_B
+	  printques( minor );
+#endif
+
+	  dt3155_fbuffer[ minor ]->even_happened = 0;
+
+	  wake_up_interruptible( &dt3155_read_wait_queue[ minor ] );
+
+	  local_irq_restore(flags);
+	}
+
+
+      /* Set up the DMA address for the next frame/field */
+      buffer_addr = dt3155_fbuffer[ minor ]->
+	frame_info[ dt3155_fbuffer[ minor ]->active_buf ].addr;
+      if ( (dt3155_status[ minor ].state & DT3155_STATE_MODE) ==
+	   DT3155_STATE_FLD )
+	{
+	  WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START), buffer_addr);
+	}
+      else
+	{
+	  WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START), buffer_addr);
+
+	  WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_START), buffer_addr
+		    + dt3155_status[ minor ].config.cols);
+	}
+
+      /* Do error checking */
+      i2c_odd_csr.fld.DONE_ODD = 1;
+      if ( i2c_odd_csr.fld.ERROR_ODD )
+	dt3155_errno = DT_ERR_OVERRUN;
+
+      WriteI2C(dt3155_lbase[ minor ], ODD_CSR, i2c_odd_csr.reg );
+
+      return;
+    }
+  /* If we get here, the Odd Field wasn't it either... */
+  printk( "neither even nor odd.  shared perhaps?\n");
+}
+
+/*****************************************************
+ * init_isr(int minor)
+ *   turns on interupt generation for the card
+ *   designated by "minor".
+ *   It is called *only* from inside ioctl().
+ *****************************************************/
+static void dt3155_init_isr(int minor)
+{
+  const u32 stride =  dt3155_status[ minor ].config.cols;
+
+  switch (dt3155_status[ minor ].state & DT3155_STATE_MODE)
+    {
+    case DT3155_STATE_FLD:
+      {
+	even_dma_start_r  = dt3155_status[ minor ].
+	  fbuffer.frame_info[ dt3155_status[ minor ].fbuffer.active_buf ].addr;
+	even_dma_stride_r = 0;
+	odd_dma_stride_r  = 0;
+
+	WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START),
+		  even_dma_start_r);
+	WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_STRIDE),
+		  even_dma_stride_r);
+	WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_STRIDE),
+		  odd_dma_stride_r);
+	break;
+      }
+
+    case DT3155_STATE_FRAME:
+    default:
+      {
+	even_dma_start_r  = dt3155_status[ minor ].
+	  fbuffer.frame_info[ dt3155_status[ minor ].fbuffer.active_buf ].addr;
+	odd_dma_start_r   =  even_dma_start_r + stride;
+	even_dma_stride_r =  stride;
+	odd_dma_stride_r  =  stride;
+
+	WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START),
+		  even_dma_start_r);
+	WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_START),
+		  odd_dma_start_r);
+	WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_STRIDE),
+		  even_dma_stride_r);
+	WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_STRIDE),
+		  odd_dma_stride_r);
+	break;
+      }
+    }
+
+  /* 50/60 Hz should be set before this point but let's make sure it is */
+  /* right anyway */
+
+  ReadI2C(dt3155_lbase[ minor ], CSR2, &i2c_csr2.reg);
+  i2c_csr2.fld.HZ50 = FORMAT50HZ;
+  WriteI2C(dt3155_lbase[ minor ], CSR2, i2c_csr2.reg);
+
+  /* enable busmaster chip, clear flags */
+
+  /*
+   * TODO:
+   * shouldn't we be concered with continuous values of
+   * DT3155_SNAP & DT3155_ACQ here? (SS)
+   */
+
+  csr1_r.reg                = 0;
+  csr1_r.fld.CAP_CONT_EVE   = 1; /* use continuous capture bits to */
+  csr1_r.fld.CAP_CONT_ODD   = 1; /* enable */
+  csr1_r.fld.FLD_DN_EVE     = 1; /* writing a 1 clears flags */
+  csr1_r.fld.FLD_DN_ODD     = 1;
+  csr1_r.fld.SRST           = 1; /* reset        - must be 1 */
+  csr1_r.fld.FIFO_EN        = 1; /* fifo control - must be 1 */
+  csr1_r.fld.FLD_CRPT_EVE   = 1; /* writing a 1 clears flags */
+  csr1_r.fld.FLD_CRPT_ODD   = 1;
+
+  WriteMReg((dt3155_lbase[ minor ] + CSR1),csr1_r.reg);
+
+  /* Enable interrupts at the end of each field */
+
+  int_csr_r.reg = 0;
+  int_csr_r.fld.FLD_END_EVE_EN = 1;
+  int_csr_r.fld.FLD_END_ODD_EN = 1;
+  int_csr_r.fld.FLD_START_EN = 0;
+
+  WriteMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg);
+
+  /* start internal BUSY bits */
+
+  ReadI2C(dt3155_lbase[ minor ], CSR2, &i2c_csr2.reg);
+  i2c_csr2.fld.BUSY_ODD  = 1;
+  i2c_csr2.fld.BUSY_EVE  = 1;
+  WriteI2C(dt3155_lbase[ minor ], CSR2, i2c_csr2.reg);
+
+  /* Now its up to the interrupt routine!! */
+
+  return;
+}
+
+
+/*****************************************************
+ * ioctl()
+ *
+ *****************************************************/
+static int dt3155_ioctl(struct inode *inode,
+			struct file *file,
+			unsigned int cmd,
+			unsigned long arg)
+{
+  int minor = MINOR(inode->i_rdev); /* What device are we ioctl()'ing? */
+
+  if ( minor >= MAXBOARDS || minor < 0 )
+    return -ENODEV;
+
+  /* make sure it is valid command */
+  if (_IOC_NR(cmd) > DT3155_IOC_MAXNR)
+    {
+      printk("DT3155: invalid IOCTL(0x%x)\n",cmd);
+      printk("DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n",
+	     (unsigned int)DT3155_GET_CONFIG,
+	     (unsigned int)DT3155_SET_CONFIG,
+	     (unsigned int)DT3155_START,
+	     (unsigned int)DT3155_STOP,
+	     (unsigned int)DT3155_FLUSH);
+      return -EINVAL;
+    }
+
+  switch (cmd)
+    {
+    case DT3155_SET_CONFIG:
+      {
+	if (dt3155_status[minor].state != DT3155_STATE_IDLE)
+	  return -EBUSY;
+
+	{
+	  struct dt3155_config_s tmp;
+	  if (copy_from_user((void *)&tmp, (void *) arg, sizeof(tmp)))
+	      return -EFAULT;
+	  /* check for valid settings */
+	  if (tmp.rows > DT3155_MAX_ROWS ||
+	      tmp.cols > DT3155_MAX_COLS ||
+	      (tmp.acq_mode != DT3155_MODE_FRAME &&
+	       tmp.acq_mode != DT3155_MODE_FIELD) ||
+	      (tmp.continuous != DT3155_SNAP &&
+	       tmp.continuous != DT3155_ACQ))
+	    {
+	      return -EINVAL;
+	    }
+	  dt3155_status[minor].config = tmp;
+	}
+	return 0;
+      }
+    case DT3155_GET_CONFIG:
+      {
+	if (copy_to_user((void *) arg, (void *) &dt3155_status[minor],
+		     sizeof(dt3155_status_t) ))
+	    return -EFAULT;
+	return 0;
+      }
+    case DT3155_FLUSH: /* Flushes the buffers -- ensures fresh data */
+      {
+	if (dt3155_status[minor].state != DT3155_STATE_IDLE)
+	  return -EBUSY;
+	return dt3155_flush(minor);
+      }
+    case DT3155_STOP:
+      {
+	if (dt3155_status[minor].state & DT3155_STATE_STOP ||
+	    dt3155_status[minor].fbuffer.stop_acquire)
+	  return -EBUSY;
+
+	if (dt3155_status[minor].state == DT3155_STATE_IDLE)
+	  return 0;
+
+	quick_stop(minor);
+	if (copy_to_user((void *) arg, (void *) &dt3155_status[minor],
+		     sizeof(dt3155_status_t)))
+	    return -EFAULT;
+	return 0;
+      }
+    case DT3155_START:
+      {
+	if (dt3155_status[minor].state != DT3155_STATE_IDLE)
+	  return -EBUSY;
+
+	dt3155_status[minor].fbuffer.stop_acquire = 0;
+	dt3155_status[minor].fbuffer.frame_count = 0;
+
+	/* Set the MODE in the status -- we default to FRAME */
+	if (dt3155_status[minor].config.acq_mode == DT3155_MODE_FIELD)
+	  {
+	    dt3155_status[minor].state = DT3155_STATE_FLD;
+	  }
+	else
+	  {
+	    dt3155_status[minor].state = DT3155_STATE_FRAME;
+	  }
+
+	dt3155_init_isr(minor);
+	if (copy_to_user( (void *) arg, (void *) &dt3155_status[minor],
+		      sizeof(dt3155_status_t)))
+	    return -EFAULT;
+	return 0;
+      }
+    default:
+      {
+	printk("DT3155: invalid IOCTL(0x%x)\n",cmd);
+      printk("DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n",
+	     (unsigned int)DT3155_GET_CONFIG,
+	     (unsigned int)DT3155_SET_CONFIG,
+	     DT3155_START, DT3155_STOP, DT3155_FLUSH);
+	return -ENOSYS;
+      }
+    }
+  return -ENOSYS;
+}
+
+/*****************************************************
+ * mmap()
+ *
+ * only allow the user to mmap the registers and buffer
+ * It is quite possible that this is broken, since the
+ * addition of of the capacity for two cards!!!!!!!!
+ * It *looks* like it should work but since I'm not
+ * sure how to use it, I'm not actually sure. (NJC? ditto by SS)
+ *****************************************************/
+static int dt3155_mmap (struct file * file, struct vm_area_struct * vma)
+{
+  /* which device are we mmapping? */
+  int				minor = MINOR(file->f_dentry->d_inode->i_rdev);
+  unsigned long	offset;
+  offset = vma->vm_pgoff << PAGE_SHIFT;
+
+  if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
+    vma->vm_flags |= VM_IO;
+
+  /* Don't try to swap out physical pages.. */
+  vma->vm_flags |= VM_RESERVED;
+
+  /* they are mapping the registers or the buffer */
+  if ((offset == dt3155_status[minor].reg_addr &&
+       vma->vm_end - vma->vm_start == PCI_PAGE_SIZE) ||
+      (offset == dt3155_status[minor].mem_addr &&
+       vma->vm_end - vma->vm_start == dt3155_status[minor].mem_size))
+    {
+      if (remap_pfn_range(vma,
+			vma->vm_start,
+			offset >> PAGE_SHIFT,
+			vma->vm_end - vma->vm_start,
+			vma->vm_page_prot)) {
+	  printk("DT3155: remap_page_range() failed.\n");
+	  return -EAGAIN;
+	}
+    }
+  else
+    {
+      printk("DT3155: dt3155_mmap() bad call.\n");
+      return -ENXIO;
+    }
+
+  return 0;
+}
+
+
+/*****************************************************
+ * open()
+ *
+ * Our special open code.
+ * MOD_INC_USE_COUNT make sure that the driver memory is not freed
+ * while the device is in use.
+ *****************************************************/
+static int dt3155_open( struct inode* inode, struct file* filep)
+{
+  int minor = MINOR(inode->i_rdev); /* what device are we opening? */
+  if (dt3155_dev_open[ minor ]) {
+    printk ("DT3155:  Already opened by another process.\n");
+    return -EBUSY;
+  }
+
+  if (dt3155_status[ minor ].device_installed==0)
+    {
+      printk("DT3155 Open Error: No such device dt3155 minor number %d\n",
+	     minor);
+      return -EIO;
+    }
+
+  if (dt3155_status[ minor ].state != DT3155_STATE_IDLE) {
+    printk ("DT3155:  Not in idle state (state = %x)\n",
+	    dt3155_status[ minor ].state);
+    return -EBUSY;
+  }
+
+  printk("DT3155: Device opened.\n");
+
+  dt3155_dev_open[ minor ] = 1 ;
+
+  dt3155_flush( minor );
+
+  /* Disable ALL interrupts */
+  int_csr_r.reg = 0;
+  WriteMReg( (dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg );
+
+  init_waitqueue_head(&(dt3155_read_wait_queue[minor]));
+
+  return 0;
+}
+
+
+/*****************************************************
+ * close()
+ *
+ * Now decrement the use count.
+ *
+ *****************************************************/
+static int dt3155_close( struct inode *inode, struct file *filep)
+{
+  int minor;
+
+  minor = MINOR(inode->i_rdev); /* which device are we closing */
+  if (!dt3155_dev_open[ minor ])
+    {
+      printk("DT3155: attempt to CLOSE a not OPEN device\n");
+    }
+  else
+    {
+      dt3155_dev_open[ minor ] = 0;
+
+      if (dt3155_status[ minor ].state != DT3155_STATE_IDLE)
+	{
+	  quick_stop(minor);
+	}
+    }
+  return 0;
+}
+
+/*****************************************************
+ * read()
+ *
+ *****************************************************/
+static ssize_t dt3155_read(struct file *filep, char __user *buf,
+			   size_t count, loff_t *ppos)
+{
+  /* which device are we reading from? */
+  int		minor = MINOR(filep->f_dentry->d_inode->i_rdev);
+  u32		offset;
+  int		frame_index;
+  frame_info_t	*frame_info_p;
+
+  /* TODO: this should check the error flag and */
+  /*   return an error on hardware failures */
+  if (count != sizeof(dt3155_read_t))
+    {
+      printk("DT3155 ERROR (NJC): count is not right\n");
+      return -EINVAL;
+    }
+
+
+  /* Hack here -- I'm going to allow reading even when idle.
+   * this is so that the frames can be read after STOP has
+   * been called.  Leaving it here, commented out, as a reminder
+   * for a short while to make sure there are no problems.
+   * Note that if the driver is not opened in non_blocking mode,
+   * and the device is idle, then it could sit here forever! */
+
+  /*  if (dt3155_status[minor].state == DT3155_STATE_IDLE)*/
+  /*    return -EBUSY;*/
+
+  /* non-blocking reads should return if no data */
+  if (filep->f_flags & O_NDELAY)
+    {
+      if ((frame_index = dt3155_get_ready_buffer(minor)) < 0) {
+	/*printk( "dt3155:  no buffers available (?)\n");*/
+	/* 		printques(minor); */
+	return -EAGAIN;
+      }
+    }
+  else
+    {
+      /*
+       * sleep till data arrives , or we get interrupted.
+       * Note that wait_event_interruptible() does not actually
+       * sleep/wait if it's condition evaluates to true upon entry.
+       */
+      wait_event_interruptible(dt3155_read_wait_queue[minor],
+			       (frame_index = dt3155_get_ready_buffer(minor))
+			       >= 0);
+
+      if (frame_index < 0)
+	{
+	  printk ("DT3155: read: interrupted\n");
+	  quick_stop (minor);
+	  printques(minor);
+	  return -EINTR;
+	}
+    }
+
+  frame_info_p = &dt3155_status[minor].fbuffer.frame_info[frame_index];
+
+  /* make this an offset */
+  offset = frame_info_p->addr - dt3155_status[minor].mem_addr;
+
+  put_user(offset, (unsigned int *) buf);
+  buf += sizeof(u32);
+  put_user( dt3155_status[minor].fbuffer.frame_count, (unsigned int *) buf);
+  buf += sizeof(u32);
+  put_user(dt3155_status[minor].state, (unsigned int *) buf);
+  buf += sizeof(u32);
+  if (copy_to_user(buf, frame_info_p, sizeof(frame_info_t)))
+      return -EFAULT;
+
+  return sizeof(dt3155_read_t);
+}
+
+static unsigned int dt3155_poll (struct file * filp, poll_table *wait)
+{
+  int minor = MINOR(filp->f_dentry->d_inode->i_rdev);
+
+  if (!is_ready_buf_empty(minor))
+    return POLLIN | POLLRDNORM;
+
+  poll_wait (filp, &dt3155_read_wait_queue[minor], wait);
+
+  return 0;
+}
+
+
+/*****************************************************
+ * file operations supported by DT3155 driver
+ *  needed by init_module
+ *  register_chrdev
+ *****************************************************/
+static struct file_operations dt3155_fops = {
+  read:		dt3155_read,
+  ioctl:		dt3155_ioctl,
+  mmap:		dt3155_mmap,
+  poll:           dt3155_poll,
+  open:		dt3155_open,
+  release:	dt3155_close
+};
+
+
+/*****************************************************
+ * find_PCI();
+ *
+ * PCI has been totally reworked in 2.1..
+ *****************************************************/
+static int find_PCI (void)
+{
+  struct pci_dev *pci_dev = NULL;
+  int error, pci_index = 0;
+  unsigned short rev_device;
+  unsigned long base;
+  unsigned char irq;
+
+  while ((pci_dev = pci_get_device
+	  (DT3155_VENDORID, DT3155_DEVICEID, pci_dev)) != NULL)
+    {
+      pci_index ++;
+
+      /* Is it really there? */
+      if ((error =
+	   pci_read_config_word(pci_dev, PCI_CLASS_DEVICE, &rev_device)))
+	continue;
+
+      /* Found a board */
+      DT_3155_DEBUG_MSG("DT3155: Device number %d \n", pci_index);
+
+      /* Make sure the driver was compiled with enough buffers to handle
+	 this many boards */
+      if (pci_index > MAXBOARDS) {
+	printk("DT3155: ERROR - found %d devices, but driver only configured "
+	       "for %d devices\n"
+	       "DT3155: Please change MAXBOARDS in dt3155.h\n",
+	       pci_index, MAXBOARDS);
+	goto err;
+      }
+
+      /* Now, just go out and make sure that this/these device(s) is/are
+	 actually mapped into the kernel address space */
+      if ((error = pci_read_config_dword( pci_dev, PCI_BASE_ADDRESS_0,
+					  (u32 *) &base)))
+	{
+	  printk("DT3155: Was not able to find device \n");
+	  goto err;
+	}
+
+      DT_3155_DEBUG_MSG("DT3155: Base address 0 for device is %lx \n", base);
+      dt3155_status[pci_index-1].reg_addr = base;
+
+      /* Remap the base address to a logical address through which we
+       * can access it. */
+      dt3155_lbase[ pci_index - 1 ] = ioremap(base,PCI_PAGE_SIZE);
+      dt3155_status[ pci_index - 1 ].reg_addr = base;
+      DT_3155_DEBUG_MSG("DT3155: New logical address is %p \n",
+			dt3155_lbase[pci_index-1]);
+      if ( !dt3155_lbase[pci_index-1] )
+	{
+	  printk("DT3155: Unable to remap control registers\n");
+	  goto err;
+	}
+
+      if ( (error = pci_read_config_byte( pci_dev, PCI_INTERRUPT_LINE, &irq)) )
+	{
+	  printk("DT3155: Was not able to find device \n");
+	  goto err;
+	}
+
+      DT_3155_DEBUG_MSG("DT3155: IRQ is %d \n",irq);
+      dt3155_status[ pci_index-1 ].irq = irq;
+      /* Set flag: kth device found! */
+      dt3155_status[ pci_index-1 ].device_installed = 1;
+      printk("DT3155: Installing device %d w/irq %d and address %p\n",
+	     pci_index,
+	     dt3155_status[pci_index-1].irq,
+	     dt3155_lbase[pci_index-1]);
+
+    }
+  ndevices = pci_index;
+
+  return DT_3155_SUCCESS;
+
+err:
+  pci_dev_put(pci_dev);
+  return DT_3155_FAILURE;
+}
+
+u32 allocatorAddr = 0;
+
+/*****************************************************
+ * init_module()
+ *****************************************************/
+int init_module(void)
+{
+  int index;
+  int rcode = 0;
+  char *devname[ MAXBOARDS ];
+
+  devname[ 0 ] = "dt3155a";
+#if MAXBOARDS == 2
+  devname[ 1 ] = "dt3155b";
+#endif
+
+  printk("DT3155: Loading module...\n");
+
+  /* Register the device driver */
+  rcode = register_chrdev( dt3155_major, "dt3155", &dt3155_fops );
+  if( rcode < 0 )
+    {
+      printk( KERN_INFO "DT3155: register_chrdev failed \n");
+      return rcode;
+    }
+
+  if( dt3155_major == 0 )
+    dt3155_major = rcode; /* dynamic */
+
+
+  /* init the status variables.                     */
+  /* DMA memory is taken care of in setup_buffers() */
+  for ( index = 0; index < MAXBOARDS; index++ )
+    {
+      dt3155_status[ index ].config.acq_mode   = DT3155_MODE_FRAME;
+      dt3155_status[ index ].config.continuous = DT3155_ACQ;
+      dt3155_status[ index ].config.cols       = DT3155_MAX_COLS;
+      dt3155_status[ index ].config.rows       = DT3155_MAX_ROWS;
+      dt3155_status[ index ].state = DT3155_STATE_IDLE;
+
+      /* find_PCI() will check if devices are installed; */
+      /* first assume they're not:                       */
+      dt3155_status[ index ].mem_addr          = 0;
+      dt3155_status[ index ].mem_size          = 0;
+      dt3155_status[ index ].state             = DT3155_STATE_IDLE;
+      dt3155_status[ index ].device_installed  = 0;
+    }
+
+  /* Now let's find the hardware.  find_PCI() will set ndevices to the
+   * number of cards found in this machine. */
+    {
+      if ( (rcode = find_PCI()) !=  DT_3155_SUCCESS )
+	{
+	  printk("DT3155 error: find_PCI() failed to find dt3155 board(s)\n");
+	  unregister_chrdev( dt3155_major, "dt3155" );
+	  return rcode;
+	}
+    }
+
+  /* Ok, time to setup the frame buffers */
+  if( (rcode = dt3155_setup_buffers(&allocatorAddr)) < 0 )
+    {
+      printk("DT3155: Error: setting up buffer not large enough.");
+      unregister_chrdev( dt3155_major, "dt3155" );
+      return rcode;
+    }
+
+  /* If we are this far, then there is enough RAM */
+  /* for the buffers: Print the configuration.    */
+  for(  index = 0;  index < ndevices;  index++ )
+    {
+      printk("DT3155: Device = %d; acq_mode = %d; "
+	     "continuous = %d; cols = %d; rows = %d;\n",
+	     index ,
+	     dt3155_status[ index ].config.acq_mode,
+	     dt3155_status[ index ].config.continuous,
+	     dt3155_status[ index ].config.cols,
+	     dt3155_status[ index ].config.rows);
+      printk("DT3155: m_addr = 0x%x; m_size = %ld; "
+	     "state = %d; device_installed = %d\n",
+	     dt3155_status[ index ].mem_addr,
+	     (long int)dt3155_status[ index ].mem_size,
+	     dt3155_status[ index ].state,
+	     dt3155_status[ index ].device_installed);
+    }
+
+  /* Disable ALL interrupts */
+  int_csr_r.reg = 0;
+  for(  index = 0;  index < ndevices;  index++ )
+    {
+      WriteMReg( (dt3155_lbase[ index ] + INT_CSR), int_csr_r.reg );
+      if( dt3155_status[ index ].device_installed )
+	{
+	  /*
+	   * This driver *looks* like it can handle sharing interrupts,
+	   * but I can't actually test myself. I've had reports that it
+	   * DOES work so I'll enable it for now. This comment will remain
+	   * as a reminder in case any problems arise. (SS)
+	   */
+	  /* in older kernels flags are: SA_SHIRQ | SA_INTERRUPT */
+	  rcode = request_irq( dt3155_status[ index ].irq, (void *)dt3155_isr,
+			       IRQF_SHARED | IRQF_DISABLED, devname[ index ],
+			       (void*) &dt3155_status[index]);
+	  if( rcode < 0 )
+	    {
+	      printk("DT3155: minor %d request_irq failed for IRQ %d\n",
+		     index, dt3155_status[index].irq);
+	      unregister_chrdev( dt3155_major, "dt3155" );
+	      return rcode;
+	    }
+	}
+    }
+
+  printk("DT3155: finished loading\n");
+
+  return 0;
+}
+
+/*****************************************************
+ * cleanup_module(void)
+ *
+ *****************************************************/
+void cleanup_module(void)
+{
+  int index;
+
+  printk("DT3155:  cleanup_module called\n");
+
+  /* removed DMA allocated with the allocator */
+#ifdef STANDALONE_ALLOCATOR
+  if (allocatorAddr != 0)
+    allocator_free_dma(allocatorAddr);
+#else
+  allocator_cleanup();
+#endif
+
+  unregister_chrdev( dt3155_major, "dt3155" );
+
+  for( index = 0; index < ndevices; index++ )
+    {
+      if( dt3155_status[ index ].device_installed == 1 )
+	{
+	  printk( "DT3155: Freeing irq %d for device %d\n",
+		  dt3155_status[ index ].irq, index );
+	  free_irq( dt3155_status[ index ].irq, (void*)&dt3155_status[index] );
+	}
+    }
+}
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155_drv.h linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155_drv.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155_drv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155_drv.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,45 @@
+/*
+
+Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
+		    Scott Smedley
+
+This file is part of the DT3155 Device Driver.
+
+The DT3155 Device Driver is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The DT3155 Device Driver is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the DT3155 Device Driver; if not, write to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+MA 02111-1307 USA
+*/
+
+#ifndef DT3155_DRV_INC
+#define DT3155_DRV_INC
+
+/* kernel logical address of the frame grabbers */
+extern u8 *dt3155_lbase[MAXBOARDS];
+
+/* kernel logical address of ram buffer */
+extern u8 *dt3155_bbase;
+
+#ifdef __KERNEL__
+#include <linux/wait.h>
+
+/* wait queue for reads */
+extern wait_queue_head_t dt3155_read_wait_queue[MAXBOARDS];
+#endif
+
+/* number of devices */
+extern u32 ndevices;
+
+extern int dt3155_errno;
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155.h linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,171 @@
+/*
+
+Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
+			 Jason Lapenta, Scott Smedley
+
+This file is part of the DT3155 Device Driver.
+
+The DT3155 Device Driver is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The DT3155 Device Driver is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the DT3155 Device Driver; if not, write to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+MA 02111-1307 USA
+
+-- Changes --
+
+  Date     Programmer  Description of changes made
+  -------------------------------------------------------------------
+  03-Jul-2000 JML     n/a
+  10-Oct-2001 SS      port to 2.4 kernel.
+  24-Jul-2002 SS      remove unused code & added GPL licence.
+  05-Aug-2005 SS      port to 2.6 kernel; make CCIR mode default.
+
+*/
+
+#ifndef _DT3155_INC
+#define _DT3155_INC
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#include <linux/time.h>		/* struct timeval */
+#else
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+
+#define TRUE  1
+#define FALSE 0
+
+/* Uncomment this for 50Hz CCIR */
+#define CCIR 1
+
+/* Can be 1 or 2 */
+#define MAXBOARDS 1
+
+#define BOARD_MAX_BUFFS	3
+#define MAXBUFFERS	(BOARD_MAX_BUFFS*MAXBOARDS)
+
+#define PCI_PAGE_SIZE	(1 << 12)
+
+#ifdef CCIR
+#define DT3155_MAX_ROWS	576
+#define DT3155_MAX_COLS	768
+#define FORMAT50HZ	TRUE
+#else
+#define DT3155_MAX_ROWS	480
+#define DT3155_MAX_COLS	640
+#define FORMAT50HZ	FALSE
+#endif
+
+/* Configuration structure */
+struct dt3155_config_s {
+	u32 acq_mode;
+	u32 cols, rows;
+	u32 continuous;
+};
+
+
+/* hold data for each frame */
+typedef struct {
+	u32 addr;		/* address of the buffer with the frame */
+	u32 tag;		/* unique number for the frame */
+	struct timeval time;	/* time that capture took place */
+} frame_info_t;
+
+/*
+ * Structure for interrupt and buffer handling.
+ * This is the setup for 1 card
+ */
+struct dt3155_fbuffer_s {
+	int    nbuffers;
+
+	frame_info_t frame_info[BOARD_MAX_BUFFS];
+
+	int empty_buffers[BOARD_MAX_BUFFS];	/* indexes empty frames */
+	int empty_len;				/* Number of empty buffers */
+						/* Zero means empty */
+
+	int active_buf;			/* Where data is currently dma'ing */
+	int locked_buf;			/* Buffers used by user */
+
+	int ready_que[BOARD_MAX_BUFFS];
+	u32 ready_head;	/* The most recent buffer located here */
+	u32 ready_len;	/* The number of ready buffers */
+
+	int even_happened;
+	int even_stopped;
+
+	int stop_acquire;	/* Flag to stop interrupts */
+	u32 frame_count;	/* Counter for frames acquired by this card */
+};
+
+
+
+#define DT3155_MODE_FRAME	1
+#define DT3155_MODE_FIELD	2
+
+#define DT3155_SNAP		1
+#define DT3155_ACQ		2
+
+/* There is one status structure for each card. */
+typedef struct dt3155_status_s {
+	int fixed_mode;		/* if 1, we are in fixed frame mode */
+	u32 reg_addr;	/* Register address for a single card */
+	u32 mem_addr;	/* Buffer start addr for this card */
+	u32 mem_size;	/* This is the amount of mem available  */
+	u32 irq;		/* this card's irq */
+	struct dt3155_config_s config;		/* configuration struct */
+	struct dt3155_fbuffer_s fbuffer;	/* frame buffer state struct */
+	u32 state;		/* this card's state */
+	u32 device_installed;	/* Flag if installed. 1=installed */
+} dt3155_status_t;
+
+/* Reference to global status structure */
+extern struct dt3155_status_s dt3155_status[MAXBOARDS];
+
+#define DT3155_STATE_IDLE	0x00
+#define DT3155_STATE_FRAME	0x01
+#define DT3155_STATE_FLD	0x02
+#define DT3155_STATE_STOP	0x100
+#define DT3155_STATE_ERROR	0x200
+#define DT3155_STATE_MODE	0x0ff
+
+#define DT3155_IOC_MAGIC	'!'
+
+#define DT3155_SET_CONFIG	_IOW(DT3155_IOC_MAGIC, 1, struct dt3155_config_s)
+#define DT3155_GET_CONFIG	_IOR(DT3155_IOC_MAGIC, 2, struct dt3155_status_s)
+#define DT3155_STOP		_IO(DT3155_IOC_MAGIC, 3)
+#define DT3155_START		_IO(DT3155_IOC_MAGIC, 4)
+#define DT3155_FLUSH		_IO(DT3155_IOC_MAGIC, 5)
+#define DT3155_IOC_MAXNR	5
+
+/* Error codes */
+
+#define DT_ERR_NO_BUFFERS	0x10000	/* not used but it might be one day */
+#define DT_ERR_CORRUPT		0x20000
+#define DT_ERR_OVERRUN		0x30000
+#define DT_ERR_I2C_TIMEOUT	0x40000
+#define DT_ERR_MASK		0xff0000/* not used but it might be one day */
+
+/* User code will probably want to declare one of these for each card */
+typedef struct dt3155_read_s {
+	u32 offset;
+	u32 frame_seq;
+	u32 state;
+
+	frame_info_t frame_info;
+} dt3155_read_t;
+
+#endif /* _DT3155_inc */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155_io.c linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155_io.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155_io.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155_io.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,175 @@
+/*
+ * Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
+ *			    Jason Lapenta, Scott Smedley
+ *
+ * This file is part of the DT3155 Device Driver.
+ *
+ * The DT3155 Device Driver is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * The DT3155 Device Driver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+ * Public License for more details.
+ */
+
+/*
+ * This file provides some basic register io routines.  It is modified from
+ * demo code provided by Data Translations.
+ */
+
+#include <linux/delay.h>
+#include "dt3155.h"
+#include "dt3155_io.h"
+#include "dt3155_drv.h"
+
+
+/****** local copies of board's 32 bit registers ******/
+u32 even_dma_start_r;	/*  bit 0 should always be 0 */
+u32 odd_dma_start_r;	/*               .. */
+u32 even_dma_stride_r;	/*  bits 0&1 should always be 0 */
+u32 odd_dma_stride_r;	/*               .. */
+u32 even_pixel_fmt_r;
+u32 odd_pixel_fmt_r;
+
+FIFO_TRIGGER_R		fifo_trigger_r;
+XFER_MODE_R		xfer_mode_r;
+CSR1_R			csr1_r;
+RETRY_WAIT_CNT_R	retry_wait_cnt_r;
+INT_CSR_R		int_csr_r;
+
+u32 even_fld_mask_r;
+u32 odd_fld_mask_r;
+
+MASK_LENGTH_R		mask_length_r;
+FIFO_FLAG_CNT_R		fifo_flag_cnt_r;
+IIC_CLK_DUR_R		iic_clk_dur_r;
+IIC_CSR1_R		iic_csr1_r;
+IIC_CSR2_R		iic_csr2_r;
+DMA_UPPER_LMT_R		even_dma_upper_lmt_r;
+DMA_UPPER_LMT_R		odd_dma_upper_lmt_r;
+
+
+
+/******** local copies of board's 8 bit I2C registers ******/
+I2C_CSR2 i2c_csr2;
+I2C_EVEN_CSR i2c_even_csr;
+I2C_ODD_CSR i2c_odd_csr;
+I2C_CONFIG i2c_config;
+u8 i2c_dt_id;
+u8 i2c_x_clip_start;
+u8 i2c_y_clip_start;
+u8 i2c_x_clip_end;
+u8 i2c_y_clip_end;
+u8 i2c_ad_addr;
+u8 i2c_ad_lut;
+I2C_AD_CMD i2c_ad_cmd;
+u8 i2c_dig_out;
+u8 i2c_pm_lut_addr;
+u8 i2c_pm_lut_data;
+
+/*
+ * wait_ibsyclr()
+ *
+ * This function handles read/write timing and r/w timeout error
+ *
+ * Returns TRUE  if NEW_CYCLE clears
+ * Returns FALSE if NEW_CYCLE doesn't clear in roughly 3 msecs, otherwise
+ * returns 0
+ */
+static int wait_ibsyclr(u8 *lpReg)
+{
+	/* wait 100 microseconds */
+	udelay(100L);
+	/* __delay(loops_per_sec/10000); */
+	if (iic_csr2_r.fld.NEW_CYCLE) {
+		/* if NEW_CYCLE didn't clear */
+		/* TIMEOUT ERROR */
+		dt3155_errno = DT_ERR_I2C_TIMEOUT;
+		return FALSE;
+	} else
+		return TRUE;	/* no error */
+}
+
+/*
+ * WriteI2C()
+ *
+ * This function handles writing to 8-bit DT3155 registers
+ *
+ * 1st parameter is pointer to 32-bit register base address
+ * 2nd parameter is reg. index;
+ * 3rd is value to be written
+ *
+ * Returns TRUE   -  Successful completion
+ *         FALSE  -  Timeout error - cycle did not complete!
+ */
+int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal)
+{
+	int writestat;	/* status for return */
+
+	/* read 32 bit IIC_CSR2 register data into union */
+
+	ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
+
+	/* for write operation */
+	iic_csr2_r.fld.DIR_RD      = 0;
+	/* I2C address of I2C register: */
+	iic_csr2_r.fld.DIR_ADDR    = wIregIndex;
+	/* 8 bit data to be written to I2C reg */
+	iic_csr2_r.fld.DIR_WR_DATA = byVal;
+	/* will start a direct I2C cycle: */
+	iic_csr2_r.fld.NEW_CYCLE   = 1;
+
+	/* xfer union data into 32 bit IIC_CSR2 register */
+	WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
+
+	/* wait for IIC cycle to finish */
+	writestat = wait_ibsyclr(lpReg);
+	return writestat;
+}
+
+/*
+ * ReadI2C()
+ *
+ * This function handles reading from 8-bit DT3155 registers
+ *
+ * 1st parameter is pointer to 32-bit register base address
+ * 2nd parameter is reg. index;
+ * 3rd is adrs of value to be read
+ *
+ * Returns TRUE   -  Successful completion
+ *         FALSE  -  Timeout error - cycle did not complete!
+ */
+int ReadI2C(u8 *lpReg, u_short wIregIndex, u8 *byVal)
+{
+	int writestat;	/* status for return */
+
+	/*  read 32 bit IIC_CSR2 register data into union */
+	ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
+
+	/*  for read operation */
+	iic_csr2_r.fld.DIR_RD     = 1;
+
+	/*  I2C address of I2C register: */
+	iic_csr2_r.fld.DIR_ADDR   = wIregIndex;
+
+	/*  will start a direct I2C cycle: */
+	iic_csr2_r.fld.NEW_CYCLE  = 1;
+
+	/*  xfer union's data into 32 bit IIC_CSR2 register */
+	WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
+
+	/* wait for IIC cycle to finish */
+	writestat = wait_ibsyclr(lpReg);
+
+	/* Next 2 commands read 32 bit IIC_CSR1 register's data into union */
+	/* first read data is in IIC_CSR1 */
+	ReadMReg((lpReg + IIC_CSR1), iic_csr1_r.reg);
+
+	/* now get data u8 out of register */
+	*byVal = (u8) iic_csr1_r.fld.RD_DATA;
+
+	return writestat;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155_io.h linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155_io.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155_io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155_io.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,358 @@
+/*
+
+Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
+		    Jason Lapenta, Scott Smedley
+
+This file is part of the DT3155 Device Driver.
+
+The DT3155 Device Driver is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The DT3155 Device Driver is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the DT3155 Device Driver; if not, write to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+MA 02111-1307 USA
+
+
+-- Changes --
+
+  Date     Programmer  Description of changes made
+  -------------------------------------------------------------------
+  24-Jul-2002 SS       GPL licence.
+
+*/
+
+/* This code is a modified version of examples provided by Data Translations.*/
+
+#ifndef DT3155_IO_INC
+#define DT3155_IO_INC
+
+/* macros to access registers */
+
+#define WriteMReg(Address, Data)	(*((u32 *)(Address)) = Data)
+#define ReadMReg(Address, Data)		(Data = *((u32 *)(Address)))
+
+/***************** 32 bit register globals  **************/
+
+/*  offsets for 32-bit memory mapped registers */
+
+#define EVEN_DMA_START		0x000
+#define ODD_DMA_START		0x00C
+#define EVEN_DMA_STRIDE		0x018
+#define ODD_DMA_STRIDE		0x024
+#define EVEN_PIXEL_FMT		0x030
+#define ODD_PIXEL_FMT		0x034
+#define FIFO_TRIGGER		0x038
+#define XFER_MODE		0x03C
+#define CSR1			0x040
+#define RETRY_WAIT_CNT		0x044
+#define INT_CSR			0x048
+#define EVEN_FLD_MASK		0x04C
+#define ODD_FLD_MASK		0x050
+#define MASK_LENGTH		0x054
+#define FIFO_FLAG_CNT		0x058
+#define IIC_CLK_DUR		0x05C
+#define IIC_CSR1		0x060
+#define IIC_CSR2		0x064
+#define EVEN_DMA_UPPR_LMT	0x08C
+#define ODD_DMA_UPPR_LMT	0x090
+
+#define CLK_DUR_VAL		0x01010101
+
+
+
+/******** Assignments and Typedefs for 32 bit Memory Mapped Registers ********/
+
+typedef union fifo_trigger_tag {
+	u32   reg;
+	struct {
+		u32 PACKED:6;
+		u32       :9;
+		u32 PLANER:7;
+		u32       :9;
+	} fld;
+} FIFO_TRIGGER_R;
+
+typedef union xfer_mode_tag {
+	u32   reg;
+	struct {
+		u32             :2;
+		u32 FIELD_TOGGLE:1;
+		u32             :5;
+		u32             :2;
+		u32             :22;
+	} fld;
+} XFER_MODE_R;
+
+typedef union csr1_tag {
+	u32   reg;
+	struct {
+		u32 CAP_CONT_EVE:1;
+		u32 CAP_CONT_ODD:1;
+		u32 CAP_SNGL_EVE:1;
+		u32 CAP_SNGL_ODD:1;
+		u32 FLD_DN_EVE  :1;
+		u32 FLD_DN_ODD  :1;
+		u32 SRST        :1;
+		u32 FIFO_EN     :1;
+		u32 FLD_CRPT_EVE:1;
+		u32 FLD_CRPT_ODD:1;
+		u32 ADDR_ERR_EVE:1;
+		u32 ADDR_ERR_ODD:1;
+		u32 CRPT_DIS    :1;
+		u32 RANGE_EN    :1;
+		u32             :16;
+	} fld;
+} CSR1_R;
+
+typedef union retry_wait_cnt_tag {
+	u32   reg;
+	struct {
+		u32 RTRY_WAIT_CNT:8;
+		u32              :24;
+	} fld;
+} RETRY_WAIT_CNT_R;
+
+typedef union int_csr_tag {
+	u32   reg;
+	struct {
+		u32 FLD_END_EVE   :1;
+		u32 FLD_END_ODD   :1;
+		u32 FLD_START     :1;
+		u32               :5;
+		u32 FLD_END_EVE_EN:1;
+		u32 FLD_END_ODD_EN:1;
+		u32 FLD_START_EN  :1;
+		u32               :21;
+	} fld;
+} INT_CSR_R;
+
+typedef union mask_length_tag {
+	u32   reg;
+	struct {
+		u32 MASK_LEN_EVE:5;
+		u32             :11;
+		u32 MASK_LEN_ODD:5;
+		u32             :11;
+	} fld;
+} MASK_LENGTH_R;
+
+typedef union fifo_flag_cnt_tag {
+	u32   reg;
+	struct {
+		u32 AF_COUNT:7;
+		u32         :9;
+		u32 AE_COUNT:7;
+		u32         :9;
+	} fld;
+} FIFO_FLAG_CNT_R;
+
+typedef union iic_clk_dur {
+	u32   reg;
+	struct {
+		u32 PHASE_1:8;
+		u32 PHASE_2:8;
+		u32 PHASE_3:8;
+		u32 PHASE_4:8;
+	} fld;
+} IIC_CLK_DUR_R;
+
+typedef union iic_csr1_tag {
+	u32   reg;
+	struct {
+		u32 AUTO_EN     :1;
+		u32 BYPASS      :1;
+		u32 SDA_OUT     :1;
+		u32 SCL_OUT     :1;
+		u32             :4;
+		u32 AUTO_ABORT  :1;
+		u32 DIRECT_ABORT:1;
+		u32 SDA_IN      :1;
+		u32 SCL_IN      :1;
+		u32             :4;
+		u32 AUTO_ADDR   :8;
+		u32 RD_DATA     :8;
+	} fld;
+} IIC_CSR1_R;
+
+/**********************************
+ * iic_csr2_tag
+ */
+typedef union iic_csr2_tag {
+	u32   reg;
+	struct {
+		u32 DIR_WR_DATA :8;
+		u32 DIR_SUB_ADDR:8;
+		u32 DIR_RD      :1;
+		u32 DIR_ADDR    :7;
+		u32 NEW_CYCLE   :1;
+		u32             :7;
+	} fld;
+}  IIC_CSR2_R;
+
+/* use for both EVEN and ODD DMA UPPER LIMITS */
+
+/*
+ * dma_upper_lmt_tag
+ */
+typedef union dma_upper_lmt_tag   {
+	u32 reg;
+	struct {
+		u32 DMA_UPPER_LMT_VAL:24;
+		u32                  :8;
+	} fld;
+} DMA_UPPER_LMT_R;
+
+
+/*
+ * Global declarations of local copies of boards' 32 bit registers
+ */
+extern u32 even_dma_start_r;		/*  bit 0 should always be 0 */
+extern u32 odd_dma_start_r;		/*               ..          */
+extern u32 even_dma_stride_r;	/*  bits 0&1 should always be 0 */
+extern u32 odd_dma_stride_r;		/*               ..             */
+extern u32 even_pixel_fmt_r;
+extern u32 odd_pixel_fmt_r;
+
+extern FIFO_TRIGGER_R		fifo_trigger_r;
+extern XFER_MODE_R		xfer_mode_r;
+extern CSR1_R			csr1_r;
+extern RETRY_WAIT_CNT_R		retry_wait_cnt_r;
+extern INT_CSR_R		int_csr_r;
+
+extern u32 even_fld_mask_r;
+extern u32 odd_fld_mask_r;
+
+extern MASK_LENGTH_R		mask_length_r;
+extern FIFO_FLAG_CNT_R		fifo_flag_cnt_r;
+extern IIC_CLK_DUR_R		iic_clk_dur_r;
+extern IIC_CSR1_R		iic_csr1_r;
+extern IIC_CSR2_R		iic_csr2_r;
+extern DMA_UPPER_LMT_R		even_dma_upper_lmt_r;
+extern DMA_UPPER_LMT_R		odd_dma_upper_lmt_r;
+
+
+
+/***************** 8 bit I2C register globals  ***********/
+#define CSR2		0x010	/* indices of 8-bit I2C mapped reg's*/
+#define EVEN_CSR	0x011
+#define ODD_CSR		0x012
+#define CONFIG		0x013
+#define DT_ID		0x01F
+#define X_CLIP_START	0x020
+#define Y_CLIP_START	0x022
+#define X_CLIP_END	0x024
+#define Y_CLIP_END	0x026
+#define AD_ADDR		0x030
+#define AD_LUT		0x031
+#define AD_CMD		0x032
+#define DIG_OUT		0x040
+#define PM_LUT_ADDR	0x050
+#define PM_LUT_DATA	0x051
+
+
+/******** Assignments and Typedefs for 8 bit I2C Registers********************/
+
+typedef union i2c_csr2_tag {
+	u8 reg;
+	struct {
+		u8 CHROM_FIL:1;
+		u8 SYNC_SNTL:1;
+		u8 HZ50:1;
+		u8 SYNC_PRESENT:1;
+		u8 BUSY_EVE:1;
+		u8 BUSY_ODD:1;
+		u8 DISP_PASS:1;
+	} fld;
+} I2C_CSR2;
+
+typedef union i2c_even_csr_tag {
+	u8    reg;
+	struct {
+		u8 DONE_EVE :1;
+		u8 SNGL_EVE :1;
+		u8 ERROR_EVE:1;
+		u8          :5;
+	} fld;
+} I2C_EVEN_CSR;
+
+typedef union i2c_odd_csr_tag {
+	u8 reg;
+	struct {
+		u8 DONE_ODD:1;
+		u8 SNGL_ODD:1;
+		u8 ERROR_ODD:1;
+		u8 :5;
+	} fld;
+} I2C_ODD_CSR;
+
+typedef union i2c_config_tag {
+	u8 reg;
+	struct {
+		u8 ACQ_MODE:2;
+		u8 EXT_TRIG_EN:1;
+		u8 EXT_TRIG_POL:1;
+		u8 H_SCALE:1;
+		u8 CLIP:1;
+		u8 PM_LUT_SEL:1;
+		u8 PM_LUT_PGM:1;
+	} fld;
+} I2C_CONFIG;
+
+
+typedef union i2c_ad_cmd_tag {
+	/* bits can have 3 different meanings depending on value of AD_ADDR */
+	u8 reg;
+	/* Bt252 Command Register if AD_ADDR = 00h */
+	struct {
+		u8             :2;
+		u8 SYNC_LVL_SEL:2;
+		u8 SYNC_CNL_SEL:2;
+		u8 DIGITIZE_CNL_SEL1:2;
+		} bt252_command;
+
+	/* Bt252 IOUT0 register if AD_ADDR = 01h */
+	struct {
+		u8 IOUT_DATA:8;
+	} bt252_iout0;
+
+	/* BT252 IOUT1 register if AD_ADDR = 02h */
+	struct {
+		u8 IOUT_DATA:8;
+	} bt252_iout1;
+} I2C_AD_CMD;
+
+
+/***** Global declarations of local copies of boards' 8 bit I2C registers ***/
+
+extern I2C_CSR2			i2c_csr2;
+extern I2C_EVEN_CSR		i2c_even_csr;
+extern I2C_ODD_CSR		i2c_odd_csr;
+extern I2C_CONFIG		i2c_config;
+extern u8			i2c_dt_id;
+extern u8			i2c_x_clip_start;
+extern u8			i2c_y_clip_start;
+extern u8			i2c_x_clip_end;
+extern u8			i2c_y_clip_end;
+extern u8			i2c_ad_addr;
+extern u8			i2c_ad_lut;
+extern I2C_AD_CMD		i2c_ad_cmd;
+extern u8			i2c_dig_out;
+extern u8			i2c_pm_lut_addr;
+extern u8			i2c_pm_lut_data;
+
+/* Functions for Global use */
+
+/* access 8-bit IIC registers */
+
+extern int ReadI2C(u8 *lpReg, u_short wIregIndex, u8 *byVal);
+extern int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155_isr.c linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155_isr.c
--- linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155_isr.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155_isr.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,516 @@
+/*
+
+Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
+                         Jason Lapenta, Scott Smedley, Greg Sharp
+
+This file is part of the DT3155 Device Driver.
+
+The DT3155 Device Driver is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The DT3155 Device Driver is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the DT3155 Device Driver; if not, write to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+MA 02111-1307 USA
+
+   File: dt3155_isr.c
+Purpose: Buffer management routines, and other routines for the ISR
+         (the actual isr is in dt3155_drv.c)
+
+-- Changes --
+
+  Date       Programmer  Description of changes made
+  -------------------------------------------------------------------
+  03-Jul-2000 JML       n/a
+  02-Apr-2002 SS        Mods to make work with separate allocator
+                        module; Merged John Roll's mods to make work with
+                        multiple boards.
+  10-Jul-2002 GCS       Complete rewrite of setup_buffers to disallow
+                        buffers which span a 4MB boundary.
+  24-Jul-2002 SS        GPL licence.
+  30-Jul-2002 NJC       Added support for buffer loop.
+  31-Jul-2002 NJC       Complete rewrite of buffer management
+  02-Aug-2002 NJC       Including slab.h instead of malloc.h (no warning).
+                        Also, allocator_init() now returns allocator_max
+                        so cleaned up allocate_buffers() accordingly.
+  08-Aug-2005 SS        port to 2.6 kernel.
+
+*/
+
+#include <asm/system.h>
+#include <linux/gfp.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+
+#include "dt3155.h"
+#include "dt3155_drv.h"
+#include "dt3155_io.h"
+#include "dt3155_isr.h"
+#include "allocator.h"
+
+#define FOUR_MB         (0x0400000)  /* Can't DMA accross a 4MB boundary!*/
+#define UPPER_10_BITS   (0x3FF<<22)  /* Can't DMA accross a 4MB boundary!*/
+
+
+/* Pointer into global structure for handling buffers */
+struct dt3155_fbuffer_s *dt3155_fbuffer[MAXBOARDS] = {NULL
+#if MAXBOARDS == 2
+						      , NULL
+#endif
+};
+
+/******************************************************************************
+ * Simple array based que struct
+ *
+ * Some handy functions using the buffering structure.
+ *****************************************************************************/
+
+
+/***************************
+ * are_empty_buffers
+ * m is minor # of device
+ ***************************/
+inline bool are_empty_buffers( int m )
+{
+  return ( dt3155_fbuffer[ m ]->empty_len );
+}
+
+/**************************
+ * push_empty
+ * m is minor # of device
+ *
+ * This is slightly confusing.  The number empty_len is the literal #
+ * of empty buffers.  After calling, empty_len-1 is the index into the
+ * empty buffer stack.  So, if empty_len == 1, there is one empty buffer,
+ * given by dt3155_fbuffer[m]->empty_buffers[0].
+ * empty_buffers should never fill up, though this is not checked.
+ **************************/
+inline void push_empty( int index, int m )
+{
+  dt3155_fbuffer[m]->empty_buffers[ dt3155_fbuffer[m]->empty_len ] = index;
+  dt3155_fbuffer[m]->empty_len++;
+}
+
+/**************************
+ * pop_empty( m )
+ * m is minor # of device
+ **************************/
+inline int pop_empty( int m )
+{
+  dt3155_fbuffer[m]->empty_len--;
+  return dt3155_fbuffer[m]->empty_buffers[ dt3155_fbuffer[m]->empty_len ];
+}
+
+/*************************
+ * is_ready_buf_empty( m )
+ * m is minor # of device
+ *************************/
+inline bool is_ready_buf_empty( int m )
+{
+  return ((dt3155_fbuffer[ m ]->ready_len) == 0);
+}
+
+/*************************
+ * is_ready_buf_full( m )
+ * m is minor # of device
+ * this should *never* be true if there are any active, locked or empty
+ * buffers, since it corresponds to nbuffers ready buffers!!
+ * 7/31/02: total rewrite. --NJC
+ *************************/
+inline bool is_ready_buf_full( int m )
+{
+  return ( dt3155_fbuffer[ m ]->ready_len == dt3155_fbuffer[ m ]->nbuffers );
+}
+
+/*****************************************************
+ * push_ready( m, buffer )
+ * m is minor # of device
+ *
+ *****************************************************/
+inline void push_ready( int m, int index )
+{
+  int head = dt3155_fbuffer[m]->ready_head;
+
+  dt3155_fbuffer[ m ]->ready_que[ head ] = index;
+  dt3155_fbuffer[ m ]->ready_head = ( (head + 1) %
+				      (dt3155_fbuffer[ m ]->nbuffers) );
+  dt3155_fbuffer[ m ]->ready_len++;
+
+}
+
+/*****************************************************
+ * get_tail()
+ * m is minor # of device
+ *
+ * Simply comptutes the tail given the head and the length.
+ *****************************************************/
+static inline int get_tail( int m )
+{
+  return ((dt3155_fbuffer[ m ]->ready_head -
+	   dt3155_fbuffer[ m ]->ready_len +
+	   dt3155_fbuffer[ m ]->nbuffers)%
+	  (dt3155_fbuffer[ m ]->nbuffers));
+}
+
+
+
+/*****************************************************
+ * pop_ready()
+ * m is minor # of device
+ *
+ * This assumes that there is a ready buffer ready... should
+ * be checked (e.g. with is_ready_buf_empty()  prior to call.
+ *****************************************************/
+inline int pop_ready( int m )
+{
+  int tail;
+  tail = get_tail(m);
+  dt3155_fbuffer[ m ]->ready_len--;
+  return dt3155_fbuffer[ m ]->ready_que[ tail ];
+}
+
+
+/*****************************************************
+ * printques
+ * m is minor # of device
+ *****************************************************/
+inline void printques( int m )
+{
+  int head = dt3155_fbuffer[ m ]->ready_head;
+  int tail;
+  int num = dt3155_fbuffer[ m ]->nbuffers;
+  int frame_index;
+  int index;
+
+  tail = get_tail(m);
+
+  printk("\n R:");
+  for ( index = tail; index != head; index++, index = index % (num) )
+    {
+      frame_index = dt3155_fbuffer[ m ]->ready_que[ index ];
+      printk(" %d ", frame_index );
+    }
+
+  printk("\n E:");
+  for ( index = 0; index < dt3155_fbuffer[ m ]->empty_len; index++ )
+    {
+      frame_index = dt3155_fbuffer[ m ]->empty_buffers[ index ];
+      printk(" %d ", frame_index );
+    }
+
+  frame_index = dt3155_fbuffer[ m ]->active_buf;
+  printk("\n A: %d", frame_index);
+
+  frame_index = dt3155_fbuffer[ m ]->locked_buf;
+  printk("\n L: %d \n", frame_index );
+
+}
+
+/*****************************************************
+ * adjust_4MB
+ *
+ *  If a buffer intersects the 4MB boundary, push
+ *  the start address up to the beginning of the
+ *  next 4MB chunk (assuming bufsize < 4MB).
+ *****************************************************/
+u32 adjust_4MB (u32 buf_addr, u32 bufsize) {
+  if (((buf_addr+bufsize) & UPPER_10_BITS) != (buf_addr & UPPER_10_BITS))
+    return (buf_addr+bufsize) & UPPER_10_BITS;
+  else
+    return buf_addr;
+}
+
+
+/*****************************************************
+ * allocate_buffers
+ *
+ *  Try to allocate enough memory for all requested
+ *  buffers.  If there is not enough free space
+ *  try for less memory.
+ *****************************************************/
+void allocate_buffers (u32 *buf_addr, u32* total_size_kbs,
+		       u32 bufsize)
+{
+  /* Compute the minimum amount of memory guaranteed to hold all
+     MAXBUFFERS such that no buffer crosses the 4MB boundary.
+     Store this value in the variable "full_size" */
+
+  u32 allocator_max;
+  u32 bufs_per_chunk = (FOUR_MB / bufsize);
+  u32 filled_chunks = (MAXBUFFERS-1) / bufs_per_chunk;
+  u32 leftover_bufs = MAXBUFFERS - filled_chunks * bufs_per_chunk;
+
+  u32 full_size = bufsize      /* possibly unusable part of 1st chunk */
+    + filled_chunks * FOUR_MB   /* max # of completely filled 4mb chunks */
+    + leftover_bufs * bufsize;  /* these buffs will be in a partly filled
+				   chunk at beginning or end */
+
+  u32 full_size_kbs = 1 + (full_size-1) / 1024;
+  u32 min_size_kbs = 2*ndevices*bufsize / 1024;
+  u32 size_kbs;
+
+  /* Now, try to allocate full_size.  If this fails, keep trying for
+     less & less memory until it succeeds. */
+#ifndef STANDALONE_ALLOCATOR
+  /* initialize the allocator            */
+  allocator_init(&allocator_max);
+#endif
+  size_kbs = full_size_kbs;
+  *buf_addr = 0;
+  printk("DT3155: We would like to get: %d KB\n", full_size_kbs);
+  printk("DT3155: ...but need at least: %d KB\n", min_size_kbs);
+  printk("DT3155: ...the allocator has: %d KB\n", allocator_max);
+  size_kbs = (full_size_kbs <= allocator_max ? full_size_kbs : allocator_max);
+  if (size_kbs > min_size_kbs) {
+    if ((*buf_addr = allocator_allocate_dma (size_kbs, GFP_KERNEL)) != 0) {
+      printk("DT3155:  Managed to allocate: %d KB\n", size_kbs);
+      *total_size_kbs = size_kbs;
+      return;
+    }
+  }
+  /* If we got here, the allocation failed */
+  printk ("DT3155: Allocator failed!\n");
+  *buf_addr = 0;
+  *total_size_kbs = 0;
+  return;
+
+}
+
+
+/*****************************************************
+ * dt3155_setup_buffers
+ *
+ *  setup_buffers just puts the buffering system into
+ *  a consistent state before the start of interrupts
+ *
+ * JML : it looks like all the buffers need to be
+ * continuous. So I'm going to try and allocate one
+ * continuous buffer.
+ *
+ * GCS : Fix DMA problems when buffer spans
+ * 4MB boundary.  Also, add error checking.  This
+ * function will return -ENOMEM when not enough memory.
+ *****************************************************/
+u32 dt3155_setup_buffers(u32 *allocatorAddr)
+
+{
+  u32 index;
+  u32 rambuff_addr; /* start of allocation */
+  u32 rambuff_size; /* total size allocated to driver */
+  u32 rambuff_acm;  /* accumlator, keep track of how much
+			  is left after being split up*/
+  u32 rambuff_end;  /* end of rambuff */
+  u32 numbufs;      /* number of useful buffers allocated (per device) */
+  u32 bufsize      = DT3155_MAX_ROWS * DT3155_MAX_COLS;
+  int m;               /* minor # of device, looped for all devs */
+
+  /* zero the fbuffer status and address structure */
+  for ( m = 0; m < ndevices; m++)
+    {
+      dt3155_fbuffer[ m ] = &(dt3155_status[ m ].fbuffer);
+
+      /* Make sure the buffering variables are consistent */
+      {
+	u8 *ptr = (u8 *) dt3155_fbuffer[ m ];
+	for( index = 0; index < sizeof(struct dt3155_fbuffer_s); index++)
+	  *(ptr++)=0;
+      }
+    }
+
+  /* allocate a large contiguous chunk of RAM */
+  allocate_buffers (&rambuff_addr, &rambuff_size, bufsize);
+  printk("DT3155: mem info\n");
+  printk("  - rambuf_addr = 0x%x \n", rambuff_addr);
+  printk("  - length (kb) = %u \n", rambuff_size);
+  if( rambuff_addr == 0 )
+    {
+      printk( KERN_INFO
+	      "DT3155: Error setup_buffers() allocator dma failed \n" );
+      return -ENOMEM;
+    }
+  *allocatorAddr = rambuff_addr;
+  rambuff_end = rambuff_addr + 1024 * rambuff_size;
+
+  /* after allocation, we need to count how many useful buffers there
+     are so we can give an equal number to each device */
+  rambuff_acm = rambuff_addr;
+  for ( index = 0; index < MAXBUFFERS; index++) {
+    rambuff_acm = adjust_4MB (rambuff_acm, bufsize);/*avoid spanning 4MB bdry*/
+    if (rambuff_acm + bufsize > rambuff_end)
+      break;
+    rambuff_acm += bufsize;
+  }
+  /* Following line is OK, will waste buffers if index
+   * not evenly divisible by ndevices -NJC*/
+  numbufs = index / ndevices;
+  printk("  - numbufs = %u\n", numbufs);
+  if (numbufs < 2) {
+    printk( KERN_INFO
+	    "DT3155: Error setup_buffers() couldn't allocate 2 bufs/board\n" );
+    return -ENOMEM;
+  }
+
+  /* now that we have board memory we spit it up */
+  /* between the boards and the buffers          */
+  rambuff_acm = rambuff_addr;
+  for ( m = 0; m < ndevices; m ++)
+    {
+      rambuff_acm = adjust_4MB (rambuff_acm, bufsize);
+
+      /* Save the start of this boards buffer space (for mmap).  */
+      dt3155_status[ m ].mem_addr = rambuff_acm;
+
+      for (index = 0; index < numbufs; index++)
+	{
+	  rambuff_acm = adjust_4MB (rambuff_acm, bufsize);
+	  if (rambuff_acm + bufsize > rambuff_end) {
+	    /* Should never happen */
+	    printk ("DT3155 PROGRAM ERROR (GCS)\n"
+		    "Error distributing allocated buffers\n");
+	    return -ENOMEM;
+	  }
+
+	  dt3155_fbuffer[ m ]->frame_info[ index ].addr = rambuff_acm;
+	  push_empty( index, m );
+	  /* printk("  - Buffer : %lx\n",
+	   * dt3155_fbuffer[ m ]->frame_info[ index ].addr );
+	   */
+	  dt3155_fbuffer[ m ]->nbuffers += 1;
+	  rambuff_acm += bufsize;
+	}
+
+      /* Make sure there is an active buffer there. */
+      dt3155_fbuffer[ m ]->active_buf    = pop_empty( m );
+      dt3155_fbuffer[ m ]->even_happened = 0;
+      dt3155_fbuffer[ m ]->even_stopped  = 0;
+
+      /* make sure there is no locked_buf JML 2/28/00 */
+      dt3155_fbuffer[ m ]->locked_buf = -1;
+
+      dt3155_status[ m ].mem_size =
+	rambuff_acm - dt3155_status[ m ].mem_addr;
+
+      /* setup the ready queue */
+      dt3155_fbuffer[ m ]->ready_head = 0;
+      dt3155_fbuffer[ m ]->ready_len = 0;
+      printk("Available buffers for device %d: %d\n",
+	     m, dt3155_fbuffer[ m ]->nbuffers);
+    }
+
+  return 1;
+}
+
+/*****************************************************
+ * internal_release_locked_buffer
+ *
+ * The internal function for releasing a locked buffer.
+ * It assumes interrupts are turned off.
+ *
+ * m is minor number of device
+ *****************************************************/
+static inline void internal_release_locked_buffer( int m )
+{
+  /* Pointer into global structure for handling buffers */
+  if ( dt3155_fbuffer[ m ]->locked_buf >= 0 )
+    {
+      push_empty( dt3155_fbuffer[ m ]->locked_buf, m );
+      dt3155_fbuffer[ m ]->locked_buf = -1;
+    }
+}
+
+
+/*****************************************************
+ * dt3155_release_locked_buffer()
+ * m is minor # of device
+ *
+ * The user function of the above.
+ *
+ *****************************************************/
+inline void dt3155_release_locked_buffer( int m )
+{
+	unsigned long int flags;
+	local_save_flags(flags);
+	local_irq_disable();
+	internal_release_locked_buffer(m);
+	local_irq_restore(flags);
+}
+
+
+/*****************************************************
+ * dt3155_flush()
+ * m is minor # of device
+ *
+ *****************************************************/
+inline int dt3155_flush( int m )
+{
+  int index;
+  unsigned long int flags;
+  local_save_flags(flags);
+  local_irq_disable();
+
+  internal_release_locked_buffer( m );
+  dt3155_fbuffer[ m ]->empty_len = 0;
+
+  for ( index = 0; index < dt3155_fbuffer[ m ]->nbuffers; index++ )
+    push_empty( index,  m );
+
+  /* Make sure there is an active buffer there. */
+  dt3155_fbuffer[ m ]->active_buf = pop_empty( m );
+
+  dt3155_fbuffer[ m ]->even_happened = 0;
+  dt3155_fbuffer[ m ]->even_stopped  = 0;
+
+  /* setup the ready queue  */
+  dt3155_fbuffer[ m ]->ready_head = 0;
+  dt3155_fbuffer[ m ]->ready_len = 0;
+
+  local_irq_restore(flags);
+
+  return 0;
+}
+
+/*****************************************************
+ * dt3155_get_ready_buffer()
+ * m is minor # of device
+ *
+ * get_ready_buffer will grab the next chunk of data
+ * if it is already there, otherwise it returns 0.
+ * If the user has a buffer locked it will unlock
+ * that buffer before returning the new one.
+ *****************************************************/
+inline int dt3155_get_ready_buffer( int m )
+{
+  int frame_index;
+  unsigned long int flags;
+  local_save_flags(flags);
+  local_irq_disable();
+
+#ifdef DEBUG_QUES_A
+  printques( m );
+#endif
+
+  internal_release_locked_buffer( m );
+
+  if (is_ready_buf_empty( m ))
+    frame_index = -1;
+  else
+    {
+      frame_index = pop_ready( m );
+      dt3155_fbuffer[ m ]->locked_buf = frame_index;
+    }
+
+#ifdef DEBUG_QUES_B
+  printques( m );
+#endif
+
+  local_irq_restore(flags);
+
+  return frame_index;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155_isr.h linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155_isr.h
--- linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155_isr.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155_isr.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,77 @@
+/*
+
+Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
+		    Jason Lapenta, Scott Smedley
+
+This file is part of the DT3155 Device Driver.
+
+The DT3155 Device Driver is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The DT3155 Device Driver is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the DT3155 Device Driver; if not, write to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+MA 02111-1307 USA
+
+
+-- Changes --
+
+  Date     Programmer   Description of changes made
+  -------------------------------------------------------------------
+  03-Jul-2000 JML       n/a
+  24-Jul-2002 SS        GPL licence.
+  26-Oct-2009 SS	Porting to 2.6.30 kernel.
+
+-- notes --
+
+*/
+
+#ifndef DT3155_ISR_H
+#define DT3155_ISR_H
+
+extern struct dt3155_fbuffer_s *dt3155_fbuffer[MAXBOARDS];
+
+/* User functions for buffering */
+/* Initialize the buffering system.  This should */
+/* be called prior to enabling interrupts */
+
+u32 dt3155_setup_buffers(u32 *allocatorAddr);
+
+/* Get the next frame of data if it is ready.  Returns */
+/* zero if no data is ready.  If there is data but */
+/* the user has a locked buffer, it will unlock that */
+/* buffer and return it to the free list. */
+
+int dt3155_get_ready_buffer(int minor);
+
+/* Return a locked buffer to the free list */
+
+void dt3155_release_locked_buffer(int minor);
+
+/* Flush the buffer system */
+int dt3155_flush(int minor);
+
+/**********************************
+ * Simple array based que struct
+ **********************************/
+
+bool are_empty_buffers(int minor);
+void push_empty(int index, int minor);
+
+int  pop_empty(int minor);
+
+bool is_ready_buf_empty(int minor);
+bool is_ready_buf_full(int minor);
+
+void push_ready(int minor, int index);
+int  pop_ready(int minor);
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155.sysvinit linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155.sysvinit
--- linux-libre-2.6.33-gnu1/drivers/staging/dt3155/dt3155.sysvinit	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dt3155/dt3155.sysvinit	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,60 @@
+#! /bin/sh
+#
+# Module load/unload script for use with SysV-style /etc/init.d/ systems.
+# On a Debian system, copy this to /etc/init.d/dt3155 and then run
+# 	/usr/sbin/update-rc.d dt3155 defaults 55
+# to create the appropriate /etc/rc?.d/[SK]55dt3155 start/stop links.
+# (The "55" is arbitrary but is what I use to load this rather late.)
+#
+#    Andy Dougherty   Feb 22 2000	doughera@lafayette.edu
+#    Dept. of Physics
+#    Lafayette College, Easton PA 18042
+#
+
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+
+# Edit to point to your local copy.
+FILE=/usr/local/lib/modules/dt3155/dt3155.o
+NAME="dt3155"
+DESC="dt3155 Frame Grabber module"
+DEV="dt3155"
+
+if test ! -f $FILE; then
+    echo "Unable to locate $FILE"
+    exit 0
+fi
+
+set -e
+
+case "$1" in
+  start)
+    echo -n "Loading $DESC "
+    if /sbin/insmod -v -f $FILE; then
+	major=`grep $DEV /proc/devices | awk "{print \\$1}"`
+	rm -f /dev/dt3155?
+	mknod /dev/dt3155a c $major 0
+	mknod /dev/dt3155b c $major 1
+	chmod go+rw /dev/dt3155?
+	echo
+    else
+	echo "$FILE not loaded."
+    fi
+    ;;
+  stop)
+    echo -n "Unloading $DESC: "
+    if /sbin/rmmod $NAME ; then
+	echo
+    else
+	echo "$DEV not removed"
+	exit 0
+    fi
+    rm -f /dev/dt3155?
+    ;;
+  *)
+    echo "Usage: /etc/init.d/$NAME {start|stop}"
+    exit 1
+    ;;
+esac
+
+exit 0
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dt3155/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/dt3155/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/dt3155/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dt3155/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,4 @@
+config DT3155
+	tristate "DT3155 Digitizer support"
+	depends on PCI
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dt3155/Makefile linux-libre-2.6.34-gnu1/drivers/staging/dt3155/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/dt3155/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dt3155/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,6 @@
+obj-$(CONFIG_DT3155)	+= dt3155.o
+dt3155-objs :=	\
+		dt3155_drv.o	\
+		dt3155_isr.o	\
+		dt3155_io.o	\
+		allocator.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/dt3155/TODO linux-libre-2.6.34-gnu1/drivers/staging/dt3155/TODO
--- linux-libre-2.6.33-gnu1/drivers/staging/dt3155/TODO	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/dt3155/TODO	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,10 @@
+TODO:
+	- fix checkpatch.pl issues
+	- remove old kernel support, it is not needed
+	- convert to proper PCI device API
+	- fix sparse warnings
+	- audit for correct subsystem interaction
+	- review review review!
+
+Please send patches to Greg Kroah-Hartman <greg@kroah.com>
+and Scott Smedley <ss@aao.gov.au>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_address_map.h linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_address_map.h
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_address_map.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_address_map.h	2010-05-16 17:17:36.000000000 -0400
@@ -149,7 +149,7 @@
  * GLOBAL Module of JAGCore Address Mapping
  * Located at address 0x0000
  */
-typedef struct _GLOBAL_t {			/* Location: */
+struct global_regs {			/* Location: */
 	u32 txq_start_addr;			/*  0x0000 */
 	u32 txq_end_addr;			/*  0x0004 */
 	u32 rxq_start_addr;			/*  0x0008 */
@@ -165,9 +165,7 @@ typedef struct _GLOBAL_t {			/* Location
 	u32 msi_config;				/*  0x0030 */
 	u32 loopback;			/*  0x0034 */
 	u32 watchdog_timer;			/*  0x0038 */
-} GLOBAL_t, *PGLOBAL_t;
-
-/* END OF GLOBAL REGISTER ADDRESS MAP */
+};
 
 
 /* START OF TXDMA REGISTER ADDRESS MAP */
@@ -255,7 +253,7 @@ extern inline void add_12bit(u32 *v, int
  * Tx DMA Module of JAGCore Address Mapping
  * Located at address 0x1000
  */
-typedef struct _TXDMA_t {		/* Location: */
+struct txdma_regs {			/* Location: */
 	u32 csr;			/*  0x1000 */
 	u32 pr_base_hi;			/*  0x1004 */
 	u32 pr_base_lo;			/*  0x1008 */
@@ -282,7 +280,7 @@ typedef struct _TXDMA_t {		/* Location:
 	u32 DroppedTLPCount;		/*  0x105c */
 	u32 NewServiceComplete;		/*  0x1060 */
 	u32 EthernetPacketCount;	/*  0x1064 */
-} TXDMA_t, *PTXDMA_t;
+};
 
 /* END OF TXDMA REGISTER ADDRESS MAP */
 
@@ -292,45 +290,25 @@ typedef struct _TXDMA_t {		/* Location:
 /*
  * structure for control status reg in rxdma address map
  * Located at address 0x2000
+ *
+ * CSR
+ * 0: halt
+ * 1-3: tc
+ * 4: fbr_big_endian
+ * 5: psr_big_endian
+ * 6: pkt_big_endian
+ * 7: dma_big_endian
+ * 8-9: fbr0_size
+ * 10: fbr0_enable
+ * 11-12: fbr1_size
+ * 13: fbr1_enable
+ * 14: unused
+ * 15: pkt_drop_disable
+ * 16: pkt_done_flush
+ * 17: halt_status
+ * 18-31: unused
  */
-typedef union _RXDMA_CSR_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused2:14;		/* bits 18-31 */
-		u32 halt_status:1;	/* bit 17 */
-		u32 pkt_done_flush:1;	/* bit 16 */
-		u32 pkt_drop_disable:1;	/* bit 15 */
-		u32 unused1:1;		/* bit 14 */
-		u32 fbr1_enable:1;	/* bit 13 */
-		u32 fbr1_size:2;	/* bits 11-12 */
-		u32 fbr0_enable:1;	/* bit 10 */
-		u32 fbr0_size:2;	/* bits 8-9 */
-		u32 dma_big_endian:1;	/* bit 7 */
-		u32 pkt_big_endian:1;	/* bit 6 */
-		u32 psr_big_endian:1;	/* bit 5 */
-		u32 fbr_big_endian:1;	/* bit 4 */
-		u32 tc:3;		/* bits 1-3 */
-		u32 halt:1;		/* bit 0 */
-#else
-		u32 halt:1;		/* bit 0 */
-		u32 tc:3;		/* bits 1-3 */
-		u32 fbr_big_endian:1;	/* bit 4 */
-		u32 psr_big_endian:1;	/* bit 5 */
-		u32 pkt_big_endian:1;	/* bit 6 */
-		u32 dma_big_endian:1;	/* bit 7 */
-		u32 fbr0_size:2;	/* bits 8-9 */
-		u32 fbr0_enable:1;	/* bit 10 */
-		u32 fbr1_size:2;	/* bits 11-12 */
-		u32 fbr1_enable:1;	/* bit 13 */
-		u32 unused1:1;		/* bit 14 */
-		u32 pkt_drop_disable:1;	/* bit 15 */
-		u32 pkt_done_flush:1;	/* bit 16 */
-		u32 halt_status:1;	/* bit 17 */
-		u32 unused2:14;		/* bits 18-31 */
-#endif
-	} bits;
-} RXDMA_CSR_t, *PRXDMA_CSR_t;
+
 
 /*
  * structure for dma writeback lo reg in rxdma address map
@@ -451,18 +429,6 @@ typedef union _RXDMA_CSR_t {
  * 31-10: unused
  * 9-0: fbr ndesc
  */
-typedef union _RXDMA_FBR_NUM_DES_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:22;		/* bits 10-31 */
-		u32 fbr_ndesc:10;	/* bits 0-9 */
-#else
-		u32 fbr_ndesc:10;	/* bits 0-9 */
-		u32 unused:22;		/* bits 10-31 */
-#endif
-	} bits;
-} RXDMA_FBR_NUM_DES_t, *PRXDMA_FBR_NUM_DES_t;
 
 /*
  * structure for free buffer ring 0 available offset reg in rxdma address map
@@ -532,8 +498,8 @@ typedef union _RXDMA_FBR_NUM_DES_t {
  * Rx DMA Module of JAGCore Address Mapping
  * Located at address 0x2000
  */
-typedef struct _RXDMA_t {				/* Location: */
-	RXDMA_CSR_t csr;				/*  0x2000 */
+struct rxdma_regs {					/* Location: */
+	u32 csr;					/*  0x2000 */
 	u32 dma_wb_base_lo;				/*  0x2004 */
 	u32 dma_wb_base_hi;				/*  0x2008 */
 	u32 num_pkt_done;				/*  0x200C */
@@ -562,7 +528,7 @@ typedef struct _RXDMA_t {				/* Location
 	u32 fbr1_full_offset;				/*  0x2068 */
 	u32 fbr1_rd_index;				/*  0x206C */
 	u32 fbr1_min_des;				/*  0x2070 */
-} RXDMA_t, *PRXDMA_t;
+};
 
 /* END OF RXDMA REGISTER ADDRESS MAP */
 
@@ -572,33 +538,18 @@ typedef struct _RXDMA_t {				/* Location
 /*
  * structure for control reg in txmac address map
  * located at address 0x3000
+ *
+ * bits
+ * 31-8: unused
+ * 7: cklseg_disable
+ * 6: ckbcnt_disable
+ * 5: cksegnum
+ * 4: async_disable
+ * 3: fc_disable
+ * 2: mcif_disable
+ * 1: mif_disable
+ * 0: txmac_en
  */
-typedef union _TXMAC_CTL_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:24;		/* bits 8-31 */
-		u32 cklseg_diable:1;	/* bit 7 */
-		u32 ckbcnt_disable:1;	/* bit 6 */
-		u32 cksegnum:1;		/* bit 5 */
-		u32 async_disable:1;	/* bit 4 */
-		u32 fc_disable:1;	/* bit 3 */
-		u32 mcif_disable:1;	/* bit 2 */
-		u32 mif_disable:1;	/* bit 1 */
-		u32 txmac_en:1;		/* bit 0 */
-#else
-		u32 txmac_en:1;		/* bit 0 */
-		u32 mif_disable:1;	/* bit 1 mac interface */
-		u32 mcif_disable:1;	/* bit 2 mem. contr. interface */
-		u32 fc_disable:1;	/* bit 3 */
-		u32 async_disable:1;	/* bit 4 */
-		u32 cksegnum:1;		/* bit 5 */
-		u32 ckbcnt_disable:1;	/* bit 6 */
-		u32 cklseg_diable:1;	/* bit 7 */
-		u32 unused:24;		/* bits 8-31 */
-#endif
-	} bits;
-} TXMAC_CTL_t, *PTXMAC_CTL_t;
 
 /*
  * structure for shadow pointer reg in txmac address map
@@ -612,23 +563,12 @@ typedef union _TXMAC_CTL_t {
 /*
  * structure for error count reg in txmac address map
  * located at address 0x3008
+ *
+ * 31-12: unused
+ * 11-8: reserved
+ * 7-4: txq_underrun
+ * 3-0: fifo_underrun
  */
-typedef union _TXMAC_ERR_CNT_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:20;		/* bits 12-31 */
-		u32 reserved:4;		/* bits 8-11 */
-		u32 txq_underrun:4;	/* bits 4-7 */
-		u32 fifo_underrun:4;	/* bits 0-3 */
-#else
-		u32 fifo_underrun:4;	/* bits 0-3 */
-		u32 txq_underrun:4;	/* bits 4-7 */
-		u32 reserved:4;		/* bits 8-11 */
-		u32 unused:20;		/* bits 12-31 */
-#endif
-	} bits;
-} TXMAC_ERR_CNT_t, *PTXMAC_ERR_CNT_t;
 
 /*
  * structure for max fill reg in txmac address map
@@ -657,64 +597,32 @@ typedef union _TXMAC_ERR_CNT_t {
 /*
  * structure for error reg in txmac address map
  * located at address 0x3018
+ *
+ * 31-9: unused
+ * 8: fifo_underrun
+ * 7-6: unused
+ * 5: ctrl2_err
+ * 4: txq_underrun
+ * 3: bcnt_err
+ * 2: lseg_err
+ * 1: segnum_err
+ * 0: seg0_err
  */
-typedef union _TXMAC_ERR_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused2:23;		/* bits 9-31 */
-		u32 fifo_underrun:1;	/* bit 8 */
-		u32 unused1:2;		/* bits 6-7 */
-		u32 ctrl2_err:1;	/* bit 5 */
-		u32 txq_underrun:1;	/* bit 4 */
-		u32 bcnt_err:1;		/* bit 3 */
-		u32 lseg_err:1;		/* bit 2 */
-		u32 segnum_err:1;	/* bit 1 */
-		u32 seg0_err:1;		/* bit 0 */
-#else
-		u32 seg0_err:1;		/* bit 0 */
-		u32 segnum_err:1;	/* bit 1 */
-		u32 lseg_err:1;		/* bit 2 */
-		u32 bcnt_err:1;		/* bit 3 */
-		u32 txq_underrun:1;	/* bit 4 */
-		u32 ctrl2_err:1;	/* bit 5 */
-		u32 unused1:2;		/* bits 6-7 */
-		u32 fifo_underrun:1;	/* bit 8 */
-		u32 unused2:23;		/* bits 9-31 */
-#endif
-	} bits;
-} TXMAC_ERR_t, *PTXMAC_ERR_t;
 
 /*
  * structure for error interrupt reg in txmac address map
  * located at address 0x301C
+ *
+ * 31-9: unused
+ * 8: fifo_underrun
+ * 7-6: unused
+ * 5: ctrl2_err
+ * 4: txq_underrun
+ * 3: bcnt_err
+ * 2: lseg_err
+ * 1: segnum_err
+ * 0: seg0_err
  */
-typedef union _TXMAC_ERR_INT_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused2:23;		/* bits 9-31 */
-		u32 fifo_underrun:1;	/* bit 8 */
-		u32 unused1:2;		/* bits 6-7 */
-		u32 ctrl2_err:1;	/* bit 5 */
-		u32 txq_underrun:1;	/* bit 4 */
-		u32 bcnt_err:1;		/* bit 3 */
-		u32 lseg_err:1;		/* bit 2 */
-		u32 segnum_err:1;	/* bit 1 */
-		u32 seg0_err:1;		/* bit 0 */
-#else
-		u32 seg0_err:1;		/* bit 0 */
-		u32 segnum_err:1;	/* bit 1 */
-		u32 lseg_err:1;		/* bit 2 */
-		u32 bcnt_err:1;		/* bit 3 */
-		u32 txq_underrun:1;	/* bit 4 */
-		u32 ctrl2_err:1;	/* bit 5 */
-		u32 unused1:2;		/* bits 6-7 */
-		u32 fifo_underrun:1;	/* bit 8 */
-		u32 unused2:23;		/* bits 9-31 */
-#endif
-	} bits;
-} TXMAC_ERR_INT_t, *PTXMAC_ERR_INT_t;
 
 /*
  * structure for error interrupt reg in txmac address map
@@ -728,17 +636,17 @@ typedef union _TXMAC_ERR_INT_t {
 /*
  * Tx MAC Module of JAGCore Address Mapping
  */
-typedef struct _TXMAC_t {		/* Location: */
-	TXMAC_CTL_t ctl;		/*  0x3000 */
+struct txmac_regs {			/* Location: */
+	u32 ctl;			/*  0x3000 */
 	u32 shadow_ptr;			/*  0x3004 */
-	TXMAC_ERR_CNT_t err_cnt;	/*  0x3008 */
+	u32 err_cnt;			/*  0x3008 */
 	u32 max_fill;			/*  0x300C */
 	u32 cf_param;			/*  0x3010 */
 	u32 tx_test;			/*  0x3014 */
-	TXMAC_ERR_t err;		/*  0x3018 */
-	TXMAC_ERR_INT_t err_int;	/*  0x301C */
+	u32 err;			/*  0x3018 */
+	u32 err_int;			/*  0x301C */
 	u32 bp_ctrl;			/*  0x3020 */
-} TXMAC_t, *PTXMAC_t;
+};
 
 /* END OF TXMAC REGISTER ADDRESS MAP */
 
@@ -747,106 +655,47 @@ typedef struct _TXMAC_t {		/* Location:
 /*
  * structure for rxmac control reg in rxmac address map
  * located at address 0x4000
+ *
+ * 31-7: reserved
+ * 6: rxmac_int_disable
+ * 5: async_disable
+ * 4: mif_disable
+ * 3: wol_disable
+ * 2: pkt_filter_disable
+ * 1: mcif_disable
+ * 0: rxmac_en
  */
-typedef union _RXMAC_CTRL_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved:25;		/* bits 7-31 */
-		u32 rxmac_int_disable:1;	/* bit 6 */
-		u32 async_disable:1;		/* bit 5 */
-		u32 mif_disable:1;		/* bit 4 */
-		u32 wol_disable:1;		/* bit 3 */
-		u32 pkt_filter_disable:1;	/* bit 2 */
-		u32 mcif_disable:1;		/* bit 1 */
-		u32 rxmac_en:1;			/* bit 0 */
-#else
-		u32 rxmac_en:1;			/* bit 0 */
-		u32 mcif_disable:1;		/* bit 1 */
-		u32 pkt_filter_disable:1;	/* bit 2 */
-		u32 wol_disable:1;		/* bit 3 */
-		u32 mif_disable:1;		/* bit 4 */
-		u32 async_disable:1;		/* bit 5 */
-		u32 rxmac_int_disable:1;	/* bit 6 */
-		u32 reserved:25;		/* bits 7-31 */
-#endif
-	} bits;
-} RXMAC_CTRL_t, *PRXMAC_CTRL_t;
 
 /*
  * structure for Wake On Lan Control and CRC 0 reg in rxmac address map
  * located at address 0x4004
+ * 31-16: crc
+ * 15-12: reserved
+ * 11: ignore_pp
+ * 10: ignore_mp
+ * 9: clr_intr
+ * 8: ignore_link_chg
+ * 7: ignore_uni
+ * 6: ignore_multi
+ * 5: ignore_broad
+ * 4-0: valid_crc 4-0
  */
-typedef union _RXMAC_WOL_CTL_CRC0_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 crc0:16;		/* bits 16-31 */
-		u32 reserve:4;		/* bits 12-15 */
-		u32 ignore_pp:1;	/* bit 11 */
-		u32 ignore_mp:1;	/* bit 10 */
-		u32 clr_intr:1;		/* bit 9 */
-		u32 ignore_link_chg:1;	/* bit 8 */
-		u32 ignore_uni:1;	/* bit 7 */
-		u32 ignore_multi:1;	/* bit 6 */
-		u32 ignore_broad:1;	/* bit 5 */
-		u32 valid_crc4:1;	/* bit 4 */
-		u32 valid_crc3:1;	/* bit 3 */
-		u32 valid_crc2:1;	/* bit 2 */
-		u32 valid_crc1:1;	/* bit 1 */
-		u32 valid_crc0:1;	/* bit 0 */
-#else
-		u32 valid_crc0:1;	/* bit 0 */
-		u32 valid_crc1:1;	/* bit 1 */
-		u32 valid_crc2:1;	/* bit 2 */
-		u32 valid_crc3:1;	/* bit 3 */
-		u32 valid_crc4:1;	/* bit 4 */
-		u32 ignore_broad:1;	/* bit 5 */
-		u32 ignore_multi:1;	/* bit 6 */
-		u32 ignore_uni:1;	/* bit 7 */
-		u32 ignore_link_chg:1;	/* bit 8 */
-		u32 clr_intr:1;		/* bit 9 */
-		u32 ignore_mp:1;	/* bit 10 */
-		u32 ignore_pp:1;	/* bit 11 */
-		u32 reserve:4;		/* bits 12-15 */
-		u32 crc0:16;		/* bits 16-31 */
-#endif
-	} bits;
-} RXMAC_WOL_CTL_CRC0_t, *PRXMAC_WOL_CTL_CRC0_t;
 
 /*
  * structure for CRC 1 and CRC 2 reg in rxmac address map
  * located at address 0x4008
+ *
+ * 31-16: crc2
+ * 15-0: crc1
  */
-typedef union _RXMAC_WOL_CRC12_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 crc2:16;	/* bits 16-31 */
-		u32 crc1:16;	/* bits 0-15 */
-#else
-		u32 crc1:16;	/* bits 0-15 */
-		u32 crc2:16;	/* bits 16-31 */
-#endif
-	} bits;
-} RXMAC_WOL_CRC12_t, *PRXMAC_WOL_CRC12_t;
 
 /*
  * structure for CRC 3 and CRC 4 reg in rxmac address map
  * located at address 0x400C
+ *
+ * 31-16: crc4
+ * 15-0: crc3
  */
-typedef union _RXMAC_WOL_CRC34_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 crc4:16;	/* bits 16-31 */
-		u32 crc3:16;	/* bits 0-15 */
-#else
-		u32 crc3:16;	/* bits 0-15 */
-		u32 crc4:16;	/* bits 16-31 */
-#endif
-	} bits;
-} RXMAC_WOL_CRC34_t, *PRXMAC_WOL_CRC34_t;
 
 /*
  * structure for Wake On Lan Source Address Lo reg in rxmac address map
@@ -966,164 +815,84 @@ typedef union _RXMAC_UNI_PF_ADDR3_t {
 /*
  * structure for Packet Filter Control reg in rxmac address map
  * located at address 0x4084
+ *
+ * 31-23: unused
+ * 22-16: min_pkt_size
+ * 15-4: unused
+ * 3: filter_frag_en
+ * 2: filter_uni_en
+ * 1: filter_multi_en
+ * 0: filter_broad_en
  */
-typedef union _RXMAC_PF_CTRL_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused2:9;		/* bits 23-31 */
-		u32 min_pkt_size:7;	/* bits 16-22 */
-		u32 unused1:12;		/* bits 4-15 */
-		u32 filter_frag_en:1;	/* bit 3 */
-		u32 filter_uni_en:1;	/* bit 2 */
-		u32 filter_multi_en:1;	/* bit 1 */
-		u32 filter_broad_en:1;	/* bit 0 */
-#else
-		u32 filter_broad_en:1;	/* bit 0 */
-		u32 filter_multi_en:1;	/* bit 1 */
-		u32 filter_uni_en:1;	/* bit 2 */
-		u32 filter_frag_en:1;	/* bit 3 */
-		u32 unused1:12;		/* bits 4-15 */
-		u32 min_pkt_size:7;	/* bits 16-22 */
-		u32 unused2:9;		/* bits 23-31 */
-#endif
-	} bits;
-} RXMAC_PF_CTRL_t, *PRXMAC_PF_CTRL_t;
 
 /*
  * structure for Memory Controller Interface Control Max Segment reg in rxmac
  * address map.  Located at address 0x4088
+ *
+ * 31-10: reserved
+ * 9-2: max_size
+ * 1: fc_en
+ * 0: seg_en
  */
-typedef union _RXMAC_MCIF_CTRL_MAX_SEG_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved:22;	/* bits 10-31 */
-		u32 max_size:8;	/* bits 2-9 */
-		u32 fc_en:1;	/* bit 1 */
-		u32 seg_en:1;	/* bit 0 */
-#else
-		u32 seg_en:1;	/* bit 0 */
-		u32 fc_en:1;	/* bit 1 */
-		u32 max_size:8;	/* bits 2-9 */
-		u32 reserved:22;	/* bits 10-31 */
-#endif
-	} bits;
-} RXMAC_MCIF_CTRL_MAX_SEG_t, *PRXMAC_MCIF_CTRL_MAX_SEG_t;
 
 /*
  * structure for Memory Controller Interface Water Mark reg in rxmac address
  * map.  Located at address 0x408C
+ *
+ * 31-26: unused
+ * 25-16: mark_hi
+ * 15-10: unused
+ * 9-0: mark_lo
  */
-typedef union _RXMAC_MCIF_WATER_MARK_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved2:6;	/* bits 26-31 */
-		u32 mark_hi:10;	/* bits 16-25 */
-		u32 reserved1:6;	/* bits 10-15 */
-		u32 mark_lo:10;	/* bits 0-9 */
-#else
-		u32 mark_lo:10;	/* bits 0-9 */
-		u32 reserved1:6;	/* bits 10-15 */
-		u32 mark_hi:10;	/* bits 16-25 */
-		u32 reserved2:6;	/* bits 26-31 */
-#endif
-	} bits;
-} RXMAC_MCIF_WATER_MARK_t, *PRXMAC_MCIF_WATER_MARK_t;
 
 /*
  * structure for Rx Queue Dialog reg in rxmac address map.
  * located at address 0x4090
+ *
+ * 31-26: reserved
+ * 25-16: rd_ptr
+ * 15-10: reserved
+ * 9-0: wr_ptr
  */
-typedef union _RXMAC_RXQ_DIAG_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved2:6;	/* bits 26-31 */
-		u32 rd_ptr:10;	/* bits 16-25 */
-		u32 reserved1:6;	/* bits 10-15 */
-		u32 wr_ptr:10;	/* bits 0-9 */
-#else
-		u32 wr_ptr:10;	/* bits 0-9 */
-		u32 reserved1:6;	/* bits 10-15 */
-		u32 rd_ptr:10;	/* bits 16-25 */
-		u32 reserved2:6;	/* bits 26-31 */
-#endif
-	} bits;
-} RXMAC_RXQ_DIAG_t, *PRXMAC_RXQ_DIAG_t;
 
 /*
  * structure for space availiable reg in rxmac address map.
  * located at address 0x4094
+ *
+ * 31-17: reserved
+ * 16: space_avail_en
+ * 15-10: reserved
+ * 9-0: space_avail
  */
-typedef union _RXMAC_SPACE_AVAIL_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved2:15;		/* bits 17-31 */
-		u32 space_avail_en:1;	/* bit 16 */
-		u32 reserved1:6;		/* bits 10-15 */
-		u32 space_avail:10;	/* bits 0-9 */
-#else
-		u32 space_avail:10;	/* bits 0-9 */
-		u32 reserved1:6;		/* bits 10-15 */
-		u32 space_avail_en:1;	/* bit 16 */
-		u32 reserved2:15;		/* bits 17-31 */
-#endif
-	} bits;
-} RXMAC_SPACE_AVAIL_t, *PRXMAC_SPACE_AVAIL_t;
 
 /*
  * structure for management interface reg in rxmac address map.
  * located at address 0x4098
+ *
+ * 31-18: reserved
+ * 17: drop_pkt_en
+ * 16-0: drop_pkt_mask
  */
-typedef union _RXMAC_MIF_CTL_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserve:14;		/* bits 18-31 */
-		u32 drop_pkt_en:1;		/* bit 17 */
-		u32 drop_pkt_mask:17;	/* bits 0-16 */
-#else
-		u32 drop_pkt_mask:17;	/* bits 0-16 */
-		u32 drop_pkt_en:1;		/* bit 17 */
-		u32 reserve:14;		/* bits 18-31 */
-#endif
-	} bits;
-} RXMAC_MIF_CTL_t, *PRXMAC_MIF_CTL_t;
 
 /*
  * structure for Error reg in rxmac address map.
  * located at address 0x409C
+ *
+ * 31-4: unused
+ * 3: mif
+ * 2: async
+ * 1: pkt_filter
+ * 0: mcif
  */
-typedef union _RXMAC_ERROR_REG_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserve:28;	/* bits 4-31 */
-		u32 mif:1;		/* bit 3 */
-		u32 async:1;	/* bit 2 */
-		u32 pkt_filter:1;	/* bit 1 */
-		u32 mcif:1;	/* bit 0 */
-#else
-		u32 mcif:1;	/* bit 0 */
-		u32 pkt_filter:1;	/* bit 1 */
-		u32 async:1;	/* bit 2 */
-		u32 mif:1;		/* bit 3 */
-		u32 reserve:28;	/* bits 4-31 */
-#endif
-	} bits;
-} RXMAC_ERROR_REG_t, *PRXMAC_ERROR_REG_t;
 
 /*
  * Rx MAC Module of JAGCore Address Mapping
  */
 typedef struct _RXMAC_t {				/* Location: */
-	RXMAC_CTRL_t ctrl;				/*  0x4000 */
-	RXMAC_WOL_CTL_CRC0_t crc0;			/*  0x4004 */
-	RXMAC_WOL_CRC12_t crc12;			/*  0x4008 */
-	RXMAC_WOL_CRC34_t crc34;			/*  0x400C */
+	u32 ctrl;					/*  0x4000 */
+	u32 crc0;					/*  0x4004 */
+	u32 crc12;					/*  0x4008 */
+	u32 crc34;					/*  0x400C */
 	RXMAC_WOL_SA_LO_t sa_lo;			/*  0x4010 */
 	RXMAC_WOL_SA_HI_t sa_hi;			/*  0x4014 */
 	u32 mask0_word0;				/*  0x4018 */
@@ -1153,17 +922,17 @@ typedef struct _RXMAC_t {				/* Location
 	u32 multi_hash2;				/*  0x4078 */
 	u32 multi_hash3;				/*  0x407C */
 	u32 multi_hash4;				/*  0x4080 */
-	RXMAC_PF_CTRL_t pf_ctrl;			/*  0x4084 */
-	RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg;	/*  0x4088 */
-	RXMAC_MCIF_WATER_MARK_t mcif_water_mark;	/*  0x408C */
-	RXMAC_RXQ_DIAG_t rxq_diag;			/*  0x4090 */
-	RXMAC_SPACE_AVAIL_t space_avail;		/*  0x4094 */
+	u32 pf_ctrl;					/*  0x4084 */
+	u32 mcif_ctrl_max_seg;				/*  0x4088 */
+	u32 mcif_water_mark;				/*  0x408C */
+	u32 rxq_diag;					/*  0x4090 */
+	u32 space_avail;				/*  0x4094 */
 
-	RXMAC_MIF_CTL_t mif_ctrl;			/*  0x4098 */
-	RXMAC_ERROR_REG_t err_reg;			/*  0x409C */
+	u32 mif_ctrl;					/*  0x4098 */
+	u32 err_reg;					/*  0x409C */
 } RXMAC_t, *PRXMAC_t;
 
-/* END OF TXMAC REGISTER ADDRESS MAP */
+/* END OF RXMAC REGISTER ADDRESS MAP */
 
 
 /* START OF MAC REGISTER ADDRESS MAP */
@@ -1337,37 +1106,19 @@ typedef struct _RXMAC_t {				/* Location
 /*
  * structure for Interface Status reg in mac address map.
  * located at address 0x503C
+ *
+ * 31-10: reserved
+ * 9: excess_defer
+ * 8: clash
+ * 7: phy_jabber
+ * 6: phy_link_ok
+ * 5: phy_full_duplex
+ * 4: phy_speed
+ * 3: pe100x_link_fail
+ * 2: pe10t_loss_carrier
+ * 1: pe10t_sqe_error
+ * 0: pe10t_jabber
  */
-typedef union _MAC_IF_STAT_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved:22;		/* bits 10-31 */
-		u32 excess_defer:1;	/* bit 9 */
-		u32 clash:1;		/* bit 8 */
-		u32 phy_jabber:1;		/* bit 7 */
-		u32 phy_link_ok:1;		/* bit 6 */
-		u32 phy_full_duplex:1;	/* bit 5 */
-		u32 phy_speed:1;		/* bit 4 */
-		u32 pe100x_link_fail:1;	/* bit 3 */
-		u32 pe10t_loss_carrie:1;	/* bit 2 */
-		u32 pe10t_sqe_error:1;	/* bit 1 */
-		u32 pe10t_jabber:1;	/* bit 0 */
-#else
-		u32 pe10t_jabber:1;	/* bit 0 */
-		u32 pe10t_sqe_error:1;	/* bit 1 */
-		u32 pe10t_loss_carrie:1;	/* bit 2 */
-		u32 pe100x_link_fail:1;	/* bit 3 */
-		u32 phy_speed:1;		/* bit 4 */
-		u32 phy_full_duplex:1;	/* bit 5 */
-		u32 phy_link_ok:1;		/* bit 6 */
-		u32 phy_jabber:1;		/* bit 7 */
-		u32 clash:1;		/* bit 8 */
-		u32 excess_defer:1;	/* bit 9 */
-		u32 reserved:22;		/* bits 10-31 */
-#endif
-	} bits;
-} MAC_IF_STAT_t, *PMAC_IF_STAT_t;
 
 /*
  * structure for Mac Station Address, Part 1 reg in mac address map.
@@ -1428,7 +1179,7 @@ typedef struct _MAC_t {					/* Location:
 	u32 mii_mgmt_stat;				/*  0x5030 */
 	u32 mii_mgmt_indicator;				/*  0x5034 */
 	u32 if_ctrl;					/*  0x5038 */
-	MAC_IF_STAT_t if_stat;				/*  0x503C */
+	u32 if_stat;					/*  0x503C */
 	MAC_STATION_ADDR1_t station_addr_1;		/*  0x5040 */
 	MAC_STATION_ADDR2_t station_addr_2;		/*  0x5044 */
 } MAC_t, *PMAC_t;
@@ -1498,8 +1249,9 @@ typedef struct _MAC_t {					/* Location:
 /*
  * MAC STATS Module of JAGCore Address Mapping
  */
-typedef struct _MAC_STAT_t {		/* Location: */
-	u32 pad[32];		/*  0x6000 - 607C */
+struct macstat_regs
+{					/* Location: */
+	u32 pad[32];			/*  0x6000 - 607C */
 
 	/* Tx/Rx 0-64 Byte Frame Counter */
 	u32 TR64;			/*  0x6080 */
@@ -1644,7 +1396,7 @@ typedef struct _MAC_STAT_t {		/* Locatio
 
 	/* Carry Register Two Mask Register */
 	u32 Carry2M;			/*  0x613C */
-} MAC_STAT_t, *PMAC_STAT_t;
+};
 
 /* END OF MAC STAT REGISTER ADDRESS MAP */
 
@@ -1682,70 +1434,49 @@ typedef struct _MAC_STAT_t {		/* Locatio
 /*
  * Memory Control Module of JAGCore Address Mapping
  */
-typedef struct _MMC_t {			/* Location: */
+struct mmc_regs {		/* Location: */
 	u32 mmc_ctrl;		/*  0x7000 */
 	u32 sram_access;	/*  0x7004 */
 	u32 sram_word1;		/*  0x7008 */
 	u32 sram_word2;		/*  0x700C */
 	u32 sram_word3;		/*  0x7010 */
 	u32 sram_word4;		/*  0x7014 */
-} MMC_t, *PMMC_t;
+};
 
 /* END OF MMC REGISTER ADDRESS MAP */
 
 
-/* START OF EXP ROM REGISTER ADDRESS MAP */
-
-/*
- * Expansion ROM Module of JAGCore Address Mapping
- */
-
-/* Take this out until it is not empty */
-#if 0
-typedef struct _EXP_ROM_t {
-
-} EXP_ROM_t, *PEXP_ROM_t;
-#endif
-
-/* END OF EXP ROM REGISTER ADDRESS MAP */
-
-
 /*
  * JAGCore Address Mapping
  */
 typedef struct _ADDRESS_MAP_t {
-	GLOBAL_t global;
+	struct global_regs global;
 	/* unused section of global address map */
-	u8 unused_global[4096 - sizeof(GLOBAL_t)];
-	TXDMA_t txdma;
+	u8 unused_global[4096 - sizeof(struct global_regs)];
+	struct txdma_regs txdma;
 	/* unused section of txdma address map */
-	u8 unused_txdma[4096 - sizeof(TXDMA_t)];
-	RXDMA_t rxdma;
+	u8 unused_txdma[4096 - sizeof(struct txdma_regs)];
+	struct rxdma_regs rxdma;
 	/* unused section of rxdma address map */
-	u8 unused_rxdma[4096 - sizeof(RXDMA_t)];
-	TXMAC_t txmac;
+	u8 unused_rxdma[4096 - sizeof(struct rxdma_regs)];
+	struct txmac_regs txmac;
 	/* unused section of txmac address map */
-	u8 unused_txmac[4096 - sizeof(TXMAC_t)];
+	u8 unused_txmac[4096 - sizeof(struct txmac_regs)];
 	RXMAC_t rxmac;
 	/* unused section of rxmac address map */
 	u8 unused_rxmac[4096 - sizeof(RXMAC_t)];
 	MAC_t mac;
 	/* unused section of mac address map */
 	u8 unused_mac[4096 - sizeof(MAC_t)];
-	MAC_STAT_t macStat;
+	struct macstat_regs macstat;
 	/* unused section of mac stat address map */
-	u8 unused_mac_stat[4096 - sizeof(MAC_STAT_t)];
-	MMC_t mmc;
+	u8 unused_mac_stat[4096 - sizeof(struct macstat_regs)];
+	struct mmc_regs mmc;
 	/* unused section of mmc address map */
-	u8 unused_mmc[4096 - sizeof(MMC_t)];
+	u8 unused_mmc[4096 - sizeof(struct mmc_regs)];
 	/* unused section of address map */
 	u8 unused_[1015808];
 
-/* Take this out until it is not empty */
-#if 0
-	EXP_ROM_t exp_rom;
-#endif
-
 	u8 unused_exp_rom[4096];	/* MGS-size TBD */
 	u8 unused__[524288];	/* unused section of address map */
 } ADDRESS_MAP_t, *PADDRESS_MAP_t;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_eeprom.c linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_eeprom.c
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_eeprom.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_eeprom.c	2010-05-16 17:17:36.000000000 -0400
@@ -66,7 +66,6 @@
 
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
@@ -84,17 +83,42 @@
 #include <linux/ioport.h>
 
 #include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-#include "et1310_eeprom.h"
-
 #include "et131x_adapter.h"
-#include "et131x_initpci.h"
-#include "et131x_isr.h"
+#include "et131x.h"
 
-#include "et1310_tx.h"
+/*
+ * EEPROM Defines
+ */
+
+/* LBCIF Register Groups (addressed via 32-bit offsets) */
+#define LBCIF_DWORD0_GROUP       0xAC
+#define LBCIF_DWORD1_GROUP       0xB0
+
+/* LBCIF Registers (addressed via 8-bit offsets) */
+#define LBCIF_ADDRESS_REGISTER   0xAC
+#define LBCIF_DATA_REGISTER      0xB0
+#define LBCIF_CONTROL_REGISTER   0xB1
+#define LBCIF_STATUS_REGISTER    0xB2
+
+/* LBCIF Control Register Bits */
+#define LBCIF_CONTROL_SEQUENTIAL_READ   0x01
+#define LBCIF_CONTROL_PAGE_WRITE        0x02
+#define LBCIF_CONTROL_EEPROM_RELOAD     0x08
+#define LBCIF_CONTROL_TWO_BYTE_ADDR     0x20
+#define LBCIF_CONTROL_I2C_WRITE         0x40
+#define LBCIF_CONTROL_LBCIF_ENABLE      0x80
 
+/* LBCIF Status Register Bits */
+#define LBCIF_STATUS_PHY_QUEUE_AVAIL    0x01
+#define LBCIF_STATUS_I2C_IDLE           0x02
+#define LBCIF_STATUS_ACK_ERROR          0x04
+#define LBCIF_STATUS_GENERAL_ERROR      0x08
+#define LBCIF_STATUS_CHECKSUM_ERROR     0x40
+#define LBCIF_STATUS_EEPROM_PRESENT     0x80
 
+/* Miscellaneous Constraints */
+#define MAX_NUM_REGISTER_POLLS          1000
+#define MAX_NUM_WRITE_RETRIES           2
 
 static int eeprom_wait_ready(struct pci_dev *pdev, u32 *status)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_eeprom.h linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_eeprom.h
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_eeprom.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_eeprom.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,103 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright Â© 2005 Agere Systems Inc.
- * All rights reserved.
- *   http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et1310_eeprom.h - Defines, structs, enums, prototypes, etc. used for EEPROM
- *                   access routines
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software.  Using this
- * software indicates your acceptance of these terms and conditions.  If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright Â© 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- *    well as in the documentation and/or other materials provided with the
- *    distribution.
- *
- * . Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following Disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * . Neither the name of Agere Systems Inc. nor the names of the contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 __ET1310_EEPROM_H__
-#define __ET1310_EEPROM_H__
-
-#include "et1310_address_map.h"
-
-/*
- * EEPROM Defines
- */
-
-/* LBCIF Register Groups (addressed via 32-bit offsets) */
-#define LBCIF_DWORD0_GROUP       0xAC
-#define LBCIF_DWORD1_GROUP       0xB0
-
-/* LBCIF Registers (addressed via 8-bit offsets) */
-#define LBCIF_ADDRESS_REGISTER   0xAC
-#define LBCIF_DATA_REGISTER      0xB0
-#define LBCIF_CONTROL_REGISTER   0xB1
-#define LBCIF_STATUS_REGISTER    0xB2
-
-/* LBCIF Control Register Bits */
-#define LBCIF_CONTROL_SEQUENTIAL_READ   0x01
-#define LBCIF_CONTROL_PAGE_WRITE        0x02
-#define LBCIF_CONTROL_EEPROM_RELOAD     0x08
-#define LBCIF_CONTROL_TWO_BYTE_ADDR     0x20
-#define LBCIF_CONTROL_I2C_WRITE         0x40
-#define LBCIF_CONTROL_LBCIF_ENABLE      0x80
-
-/* LBCIF Status Register Bits */
-#define LBCIF_STATUS_PHY_QUEUE_AVAIL    0x01
-#define LBCIF_STATUS_I2C_IDLE           0x02
-#define LBCIF_STATUS_ACK_ERROR          0x04
-#define LBCIF_STATUS_GENERAL_ERROR      0x08
-#define LBCIF_STATUS_CHECKSUM_ERROR     0x40
-#define LBCIF_STATUS_EEPROM_PRESENT     0x80
-
-/* Miscellaneous Constraints */
-#define MAX_NUM_REGISTER_POLLS          1000
-#define MAX_NUM_WRITE_RETRIES           2
-
-/* Forward declaration of the private adapter structure */
-struct et131x_adapter;
-
-int et131x_init_eeprom(struct et131x_adapter *etdev);
-
-#endif /* _ET1310_EEPROM_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_jagcore.h linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_jagcore.h
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_jagcore.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_jagcore.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,94 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright Â© 2005 Agere Systems Inc.
- * All rights reserved.
- *   http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et1310_jagcore.h - Defines, structs, enums, prototypes, etc. pertaining to
- *                    the JAGCore
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software.  Using this
- * software indicates your acceptance of these terms and conditions.  If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright Â© 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- *    well as in the documentation and/or other materials provided with the
- *    distribution.
- *
- * . Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following Disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * . Neither the name of Agere Systems Inc. nor the names of the contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 __ET1310_JAGCORE_H__
-#define __ET1310_JAGCORE_H__
-
-#include "et1310_address_map.h"
-
-
-#define INTERNAL_MEM_SIZE       0x400	/* 1024 of internal memory */
-#define INTERNAL_MEM_RX_OFFSET  0x1FF	/* 50%   Tx, 50%   Rx */
-
-/*
- * For interrupts, normal running is:
- *       rxdma_xfr_done, phy_interrupt, mac_stat_interrupt,
- *       watchdog_interrupt & txdma_xfer_done
- *
- * In both cases, when flow control is enabled for either Tx or bi-direction,
- * we additional enable rx_fbr0_low and rx_fbr1_low, so we know when the
- * buffer rings are running low.
- */
-#define INT_MASK_DISABLE            0xffffffff
-
-/* NOTE: Masking out MAC_STAT Interrupt for now...
- * #define INT_MASK_ENABLE             0xfff6bf17
- * #define INT_MASK_ENABLE_NO_FLOW     0xfff6bfd7
- */
-#define INT_MASK_ENABLE             0xfffebf17
-#define INT_MASK_ENABLE_NO_FLOW     0xfffebfd7
-
-/* Forward declaration of the private adapter structure */
-struct et131x_adapter;
-
-void ConfigGlobalRegs(struct et131x_adapter *pAdapter);
-void ConfigMMCRegs(struct et131x_adapter *pAdapter);
-void et131x_enable_interrupts(struct et131x_adapter *adapter);
-void et131x_disable_interrupts(struct et131x_adapter *adapter);
-
-#endif /* __ET1310_JAGCORE_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_mac.c linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_mac.c
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_mac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_mac.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,7 +65,6 @@
 
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
@@ -85,12 +84,19 @@
 #include <linux/crc32.h>
 
 #include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-#include "et1310_mac.h"
-
 #include "et131x_adapter.h"
-#include "et131x_initpci.h"
+#include "et131x.h"
+
+
+#define COUNTER_WRAP_28_BIT 0x10000000
+#define COUNTER_WRAP_22_BIT 0x400000
+#define COUNTER_WRAP_16_BIT 0x10000
+#define COUNTER_WRAP_12_BIT 0x1000
+
+#define COUNTER_MASK_28_BIT (COUNTER_WRAP_28_BIT - 1)
+#define COUNTER_MASK_22_BIT (COUNTER_WRAP_22_BIT - 1)
+#define COUNTER_MASK_16_BIT (COUNTER_WRAP_16_BIT - 1)
+#define COUNTER_MASK_12_BIT (COUNTER_WRAP_12_BIT - 1)
 
 /**
  * ConfigMacRegs1 - Initialize the first part of MAC regs
@@ -163,9 +169,9 @@ void ConfigMACRegs2(struct et131x_adapte
 	u32 cfg1;
 	u32 cfg2;
 	u32 ifctrl;
-	TXMAC_CTL_t ctl;
+	u32 ctl;
 
-	ctl.value = readl(&etdev->regs->txmac.ctl.value);
+	ctl = readl(&etdev->regs->txmac.ctl);
 	cfg1 = readl(&pMac->cfg1);
 	cfg2 = readl(&pMac->cfg2);
 	ifctrl = readl(&pMac->if_ctrl);
@@ -219,9 +225,8 @@ void ConfigMACRegs2(struct et131x_adapte
 	}
 
 	/* Enable TXMAC */
-	ctl.bits.txmac_en = 0x1;
-	ctl.bits.fc_disable = 0x1;
-	writel(ctl.value, &etdev->regs->txmac.ctl.value);
+	ctl |= 0x09;	/* TX mac enable, FC disable */
+	writel(ctl, &etdev->regs->txmac.ctl);
 
 	/* Ready to start the RXDMA/TXDMA engine */
 	if (etdev->Flags & fMP_ADAPTER_LOWER_POWER) {
@@ -235,15 +240,15 @@ void ConfigRxMacRegs(struct et131x_adapt
 	struct _RXMAC_t __iomem *pRxMac = &etdev->regs->rxmac;
 	RXMAC_WOL_SA_LO_t sa_lo;
 	RXMAC_WOL_SA_HI_t sa_hi;
-	RXMAC_PF_CTRL_t pf_ctrl = { 0 };
+	u32 pf_ctrl = 0;
 
 	/* Disable the MAC while it is being configured (also disable WOL) */
-	writel(0x8, &pRxMac->ctrl.value);
+	writel(0x8, &pRxMac->ctrl);
 
 	/* Initialize WOL to disabled. */
-	writel(0, &pRxMac->crc0.value);
-	writel(0, &pRxMac->crc12.value);
-	writel(0, &pRxMac->crc34.value);
+	writel(0, &pRxMac->crc0);
+	writel(0, &pRxMac->crc12);
+	writel(0, &pRxMac->crc34);
 
 	/* We need to set the WOL mask0 - mask4 next.  We initialize it to
 	 * its default Values of 0x00000000 because there are not WOL masks
@@ -286,12 +291,12 @@ void ConfigRxMacRegs(struct et131x_adapt
 	writel(sa_hi.value, &pRxMac->sa_hi.value);
 
 	/* Disable all Packet Filtering */
-	writel(0, &pRxMac->pf_ctrl.value);
+	writel(0, &pRxMac->pf_ctrl);
 
 	/* Let's initialize the Unicast Packet filtering address */
 	if (etdev->PacketFilter & ET131X_PACKET_TYPE_DIRECTED) {
 		SetupDeviceForUnicast(etdev);
-		pf_ctrl.bits.filter_uni_en = 1;
+		pf_ctrl |= 4;	/* Unicast filter */
 	} else {
 		writel(0, &pRxMac->uni_pf_addr1.value);
 		writel(0, &pRxMac->uni_pf_addr2.value);
@@ -299,20 +304,16 @@ void ConfigRxMacRegs(struct et131x_adapt
 	}
 
 	/* Let's initialize the Multicast hash */
-	if (etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST) {
-		pf_ctrl.bits.filter_multi_en = 0;
-	} else {
-		pf_ctrl.bits.filter_multi_en = 1;
+	if (!(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) {
+		pf_ctrl |= 2;	/* Multicast filter */
 		SetupDeviceForMulticast(etdev);
 	}
 
 	/* Runt packet filtering.  Didn't work in version A silicon. */
-	pf_ctrl.bits.min_pkt_size = NIC_MIN_PACKET_SIZE + 4;
-	pf_ctrl.bits.filter_frag_en = 1;
-
-	if (etdev->RegistryJumboPacket > 8192) {
-		RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg;
+	pf_ctrl |= (NIC_MIN_PACKET_SIZE + 4) << 16;
+	pf_ctrl |= 8;	/* Fragment filter */
 
+	if (etdev->RegistryJumboPacket > 8192)
 		/* In order to transmit jumbo packets greater than 8k, the
 		 * FIFO between RxMAC and RxDMA needs to be reduced in size
 		 * to (16k - Jumbo packet size).  In order to implement this,
@@ -320,25 +321,21 @@ void ConfigRxMacRegs(struct et131x_adapt
 		 * packets down into segments which are (max_size * 16).  In
 		 * this case we selected 256 bytes, since this is the size of
 		 * the PCI-Express TLP's that the 1310 uses.
+		 *
+		 * seg_en on, fc_en off, size 0x10
 		 */
-		mcif_ctrl_max_seg.bits.seg_en = 0x1;
-		mcif_ctrl_max_seg.bits.fc_en = 0x0;
-		mcif_ctrl_max_seg.bits.max_size = 0x10;
-
-		writel(mcif_ctrl_max_seg.value,
-		       &pRxMac->mcif_ctrl_max_seg.value);
-	} else {
-		writel(0, &pRxMac->mcif_ctrl_max_seg.value);
-	}
+		writel(0x41, &pRxMac->mcif_ctrl_max_seg);
+	else
+		writel(0, &pRxMac->mcif_ctrl_max_seg);
 
 	/* Initialize the MCIF water marks */
-	writel(0, &pRxMac->mcif_water_mark.value);
+	writel(0, &pRxMac->mcif_water_mark);
 
 	/*  Initialize the MIF control */
-	writel(0, &pRxMac->mif_ctrl.value);
+	writel(0, &pRxMac->mif_ctrl);
 
 	/* Initialize the Space Available Register */
-	writel(0, &pRxMac->space_avail.value);
+	writel(0, &pRxMac->space_avail);
 
 	/* Initialize the the mif_ctrl register
 	 * bit 3:  Receive code error. One or more nibbles were signaled as
@@ -354,9 +351,9 @@ void ConfigRxMacRegs(struct et131x_adapt
 	 * bit 17: Drop packet enable
 	 */
 	if (etdev->linkspeed == TRUEPHY_SPEED_100MBPS)
-		writel(0x30038, &pRxMac->mif_ctrl.value);
+		writel(0x30038, &pRxMac->mif_ctrl);
 	else
-		writel(0x30030, &pRxMac->mif_ctrl.value);
+		writel(0x30030, &pRxMac->mif_ctrl);
 
 	/* Finally we initialize RxMac to be enabled & WOL disabled.  Packet
 	 * filter is always enabled since it is where the runt packets are
@@ -364,28 +361,28 @@ void ConfigRxMacRegs(struct et131x_adapt
 	 * dropping doesn't work, so it is disabled in the pf_ctrl register,
 	 * but we still leave the packet filter on.
 	 */
-	writel(pf_ctrl.value, &pRxMac->pf_ctrl.value);
-	writel(0x9, &pRxMac->ctrl.value);
+	writel(pf_ctrl, &pRxMac->pf_ctrl);
+	writel(0x9, &pRxMac->ctrl);
 }
 
 void ConfigTxMacRegs(struct et131x_adapter *etdev)
 {
-	struct _TXMAC_t __iomem *pTxMac = &etdev->regs->txmac;
+	struct txmac_regs *txmac = &etdev->regs->txmac;
 
 	/* We need to update the Control Frame Parameters
 	 * cfpt - control frame pause timer set to 64 (0x40)
 	 * cfep - control frame extended pause timer set to 0x0
 	 */
 	if (etdev->FlowControl == None)
-		writel(0, &pTxMac->cf_param);
+		writel(0, &txmac->cf_param);
 	else
-		writel(0x40, &pTxMac->cf_param);
+		writel(0x40, &txmac->cf_param);
 }
 
 void ConfigMacStatRegs(struct et131x_adapter *etdev)
 {
-	struct _MAC_STAT_t __iomem *macstat =
-		&etdev->regs->macStat;
+	struct macstat_regs __iomem *macstat =
+		&etdev->regs->macstat;
 
 	/* Next we need to initialize all the MAC_STAT registers to zero on
 	 * the device.
@@ -456,8 +453,8 @@ void ConfigFlowControl(struct et131x_ada
 void UpdateMacStatHostCounters(struct et131x_adapter *etdev)
 {
 	struct _ce_stats_t *stats = &etdev->Stats;
-	struct _MAC_STAT_t __iomem *macstat =
-		&etdev->regs->macStat;
+	struct macstat_regs __iomem *macstat =
+		&etdev->regs->macstat;
 
 	stats->collisions += readl(&macstat->TNcl);
 	stats->first_collision += readl(&macstat->TScl);
@@ -493,11 +490,11 @@ void HandleMacStatInterrupt(struct et131
 	/* Read the interrupt bits from the register(s).  These are Clear On
 	 * Write.
 	 */
-	Carry1 = readl(&etdev->regs->macStat.Carry1);
-	Carry2 = readl(&etdev->regs->macStat.Carry2);
+	Carry1 = readl(&etdev->regs->macstat.Carry1);
+	Carry2 = readl(&etdev->regs->macstat.Carry2);
 
-	writel(Carry1, &etdev->regs->macStat.Carry1);
-	writel(Carry2, &etdev->regs->macStat.Carry2);
+	writel(Carry1, &etdev->regs->macstat.Carry1);
+	writel(Carry2, &etdev->regs->macstat.Carry2);
 
 	/* We need to do update the host copy of all the MAC_STAT counters.
 	 * For each counter, check it's overflow bit.  If the overflow bit is
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_mac.h linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_mac.h
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_mac.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_mac.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,93 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright Â© 2005 Agere Systems Inc.
- * All rights reserved.
- *   http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et1310_mac.h -  Defines, structs, enums, prototypes, etc. pertaining to the
- *                 MAC.
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software.  Using this
- * software indicates your acceptance of these terms and conditions.  If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright Â© 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- *    well as in the documentation and/or other materials provided with the
- *    distribution.
- *
- * . Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following Disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * . Neither the name of Agere Systems Inc. nor the names of the contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 _ET1310_MAC_H_
-#define _ET1310_MAC_H_
-
-
-#include "et1310_address_map.h"
-
-
-#define COUNTER_WRAP_28_BIT 0x10000000
-#define COUNTER_WRAP_22_BIT 0x400000
-#define COUNTER_WRAP_16_BIT 0x10000
-#define COUNTER_WRAP_12_BIT 0x1000
-
-#define COUNTER_MASK_28_BIT (COUNTER_WRAP_28_BIT - 1)
-#define COUNTER_MASK_22_BIT (COUNTER_WRAP_22_BIT - 1)
-#define COUNTER_MASK_16_BIT (COUNTER_WRAP_16_BIT - 1)
-#define COUNTER_MASK_12_BIT (COUNTER_WRAP_12_BIT - 1)
-
-#define UPDATE_COUNTER(HostCnt, DevCnt) \
-    HostCnt = HostCnt + DevCnt;
-
-/* Forward declaration of the private adapter structure */
-struct et131x_adapter;
-
-void ConfigMACRegs1(struct et131x_adapter *adapter);
-void ConfigMACRegs2(struct et131x_adapter *adapter);
-void ConfigRxMacRegs(struct et131x_adapter *adapter);
-void ConfigTxMacRegs(struct et131x_adapter *adapter);
-void ConfigMacStatRegs(struct et131x_adapter *adapter);
-void ConfigFlowControl(struct et131x_adapter *adapter);
-void UpdateMacStatHostCounters(struct et131x_adapter *adapter);
-void HandleMacStatInterrupt(struct et131x_adapter *adapter);
-void SetupDeviceForMulticast(struct et131x_adapter *adapter);
-void SetupDeviceForUnicast(struct et131x_adapter *adapter);
-
-#endif /* _ET1310_MAC_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_phy.c linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_phy.c
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_phy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_phy.c	2010-05-16 17:17:36.000000000 -0400
@@ -66,7 +66,6 @@
 
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
@@ -85,17 +84,14 @@
 #include <linux/random.h>
 
 #include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
 
 #include "et131x_adapter.h"
-#include "et131x_netdev.h"
-#include "et131x_initpci.h"
 
 #include "et1310_address_map.h"
 #include "et1310_tx.h"
 #include "et1310_rx.h"
-#include "et1310_mac.h"
+
+#include "et131x.h"
 
 /* Prototypes for functions with local scope */
 static void et131x_xcvr_init(struct et131x_adapter *etdev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_phy.h linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_phy.h
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_phy.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_phy.h	2010-05-16 17:17:36.000000000 -0400
@@ -736,32 +736,8 @@ typedef union _MI_LCR2_t {
 
 /* MI Register 29 - 31: Reserved Reg(0x1D - 0x1E) */
 
-/* Forward declaration of the private adapter structure */
-struct et131x_adapter;
 
 /* Prototypes for ET1310_phy.c */
-int et131x_xcvr_find(struct et131x_adapter *adapter);
-void et131x_setphy_normal(struct et131x_adapter *adapter);
-
-/* static inline function does not work because et131x_adapter is not always
- * defined
- */
-int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr,
-	      u8 xcvrReg, u16 *value);
-#define MiRead(adapter, xcvrReg, value) \
-	PhyMiRead((adapter), (adapter)->Stats.xcvr_addr, (xcvrReg), (value))
-
-int32_t MiWrite(struct et131x_adapter *adapter,
-		u8 xcvReg, u16 value);
-void et131x_Mii_check(struct et131x_adapter *pAdapter,
-		      MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints);
-
-/* This last is not strictly required (the driver could call the TPAL
- * version instead), but this sets the adapter up correctly, and calls the
- * access routine indirectly.  This protects the driver from changes in TPAL.
- */
-void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter);
-
 /* Defines for PHY access routines */
 
 /* Define bit operation flags */
@@ -843,14 +819,4 @@ void SetPhy_10BaseTHalfDuplex(struct et1
 					/* #define TRU_VMI_LINK_CONTROL_REGISTER           29 */
 					/* #define TRU_VMI_TIMING_CONTROL_REGISTER */
 
-/* Prototypes for PHY access routines */
-void ET1310_PhyInit(struct et131x_adapter *adapter);
-void ET1310_PhyReset(struct et131x_adapter *adapter);
-void ET1310_PhyPowerDown(struct et131x_adapter *adapter, bool down);
-void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *adapter,
-				  u16 duplex);
-void ET1310_PhyAccessMiBit(struct et131x_adapter *adapter,
-			   u16 action,
-			   u16 regnum, u16 bitnum, u8 *value);
-
 #endif /* _ET1310_PHY_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_pm.c linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_pm.c
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_pm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_pm.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,7 +65,6 @@
 
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
@@ -83,13 +82,9 @@
 #include <linux/ioport.h>
 
 #include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-#include "et1310_mac.h"
 #include "et1310_rx.h"
-
 #include "et131x_adapter.h"
-#include "et131x_initpci.h"
+#include "et131x.h"
 
 /**
  * EnablePhyComa - called when network cable is unplugged
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_pm.h linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_pm.h
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_pm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_pm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,85 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright Â© 2005 Agere Systems Inc.
- * All rights reserved.
- *   http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et1310_pm.h - Defines, structs, enums, prototypes, etc. pertaining to power
- *               management.
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software.  Using this
- * software indicates your acceptance of these terms and conditions.  If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright Â© 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- *    well as in the documentation and/or other materials provided with the
- *    distribution.
- *
- * . Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following Disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * . Neither the name of Agere Systems Inc. nor the names of the contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 _ET1310_PM_H_
-#define _ET1310_PM_H_
-
-#include "et1310_address_map.h"
-
-typedef struct _MP_POWER_MGMT {
-	/* variable putting the phy into coma mode when boot up with no cable
-	 * plugged in after 5 seconds
-	 */
-	u8 TransPhyComaModeOnBoot;
-
-	/* Next two used to save power information at power down. This
-	 * information will be used during power up to set up parts of Power
-	 * Management in JAGCore
-	 */
-	u16 PowerDownSpeed;
-	u8 PowerDownDuplex;
-} MP_POWER_MGMT, *PMP_POWER_MGMT;
-
-/* Forward declaration of the private adapter structure
- */
-struct et131x_adapter;
-
-void EnablePhyComa(struct et131x_adapter *adapter);
-void DisablePhyComa(struct et131x_adapter *adapter);
-
-#endif /* _ET1310_PM_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_rx.c linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_rx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -84,14 +84,9 @@
 #include <linux/ioport.h>
 
 #include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-
 #include "et131x_adapter.h"
-#include "et131x_initpci.h"
-
 #include "et1310_rx.h"
-
+#include "et131x.h"
 
 void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd);
 
@@ -109,17 +104,16 @@ int et131x_rx_dma_memory_alloc(struct et
 	u32 i, j;
 	u32 bufsize;
 	u32 pktStatRingSize, FBRChunkSize;
-	RX_RING_t *rx_ring;
+	struct rx_ring *rx_ring;
 
 	/* Setup some convenience pointers */
-	rx_ring = (RX_RING_t *) &adapter->RxRing;
+	rx_ring = &adapter->rx_ring;
 
 	/* Alloc memory for the lookup table */
 #ifdef USE_FBR0
-	rx_ring->Fbr[0] = kmalloc(sizeof(FBRLOOKUPTABLE), GFP_KERNEL);
+	rx_ring->fbr[0] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL);
 #endif
-
-	rx_ring->Fbr[1] = kmalloc(sizeof(FBRLOOKUPTABLE), GFP_KERNEL);
+	rx_ring->fbr[1] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL);
 
 	/* The first thing we will do is configure the sizes of the buffer
 	 * rings. These will change based on jumbo packet support.  Larger
@@ -163,14 +157,14 @@ int et131x_rx_dma_memory_alloc(struct et
 	}
 
 #ifdef USE_FBR0
-	adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr0NumEntries +
-	    adapter->RxRing.Fbr1NumEntries;
+	adapter->rx_ring.PsrNumEntries = adapter->rx_ring.Fbr0NumEntries +
+	    adapter->rx_ring.Fbr1NumEntries;
 #else
-	adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr1NumEntries;
+	adapter->rx_ring.PsrNumEntries = adapter->rx_ring.Fbr1NumEntries;
 #endif
 
 	/* Allocate an area of memory for Free Buffer Ring 1 */
-	bufsize = (sizeof(FBR_DESC_t) * rx_ring->Fbr1NumEntries) + 0xfff;
+	bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr1NumEntries) + 0xfff;
 	rx_ring->pFbr1RingVa = pci_alloc_consistent(adapter->pdev,
 						    bufsize,
 						    &rx_ring->pFbr1RingPa);
@@ -194,12 +188,12 @@ int et131x_rx_dma_memory_alloc(struct et
 				      &rx_ring->Fbr1Realpa,
 				      &rx_ring->Fbr1offset, 0x0FFF);
 
-	rx_ring->pFbr1RingVa = (void *)((uint8_t *) rx_ring->pFbr1RingVa +
+	rx_ring->pFbr1RingVa = (void *)((u8 *) rx_ring->pFbr1RingVa +
 					rx_ring->Fbr1offset);
 
 #ifdef USE_FBR0
 	/* Allocate an area of memory for Free Buffer Ring 0 */
-	bufsize = (sizeof(FBR_DESC_t) * rx_ring->Fbr0NumEntries) + 0xfff;
+	bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr0NumEntries) + 0xfff;
 	rx_ring->pFbr0RingVa = pci_alloc_consistent(adapter->pdev,
 						    bufsize,
 						    &rx_ring->pFbr0RingPa);
@@ -223,7 +217,7 @@ int et131x_rx_dma_memory_alloc(struct et
 				      &rx_ring->Fbr0Realpa,
 				      &rx_ring->Fbr0offset, 0x0FFF);
 
-	rx_ring->pFbr0RingVa = (void *)((uint8_t *) rx_ring->pFbr0RingVa +
+	rx_ring->pFbr0RingVa = (void *)((u8 *) rx_ring->pFbr0RingVa +
 					rx_ring->Fbr0offset);
 #endif
 
@@ -270,23 +264,23 @@ int et131x_rx_dma_memory_alloc(struct et
 			/* Save the Virtual address of this index for quick
 			 * access later
 			 */
-			rx_ring->Fbr[1]->Va[index] =
-			    (uint8_t *) rx_ring->Fbr1MemVa[i] +
+			rx_ring->fbr[1]->virt[index] =
+			    (u8 *) rx_ring->Fbr1MemVa[i] +
 			    (j * rx_ring->Fbr1BufferSize) + Fbr1Offset;
 
 			/* now store the physical address in the descriptor
 			 * so the device can access it
 			 */
-			rx_ring->Fbr[1]->PAHigh[index] =
+			rx_ring->fbr[1]->bus_high[index] =
 			    (u32) (Fbr1TempPa >> 32);
-			rx_ring->Fbr[1]->PALow[index] = (u32) Fbr1TempPa;
+			rx_ring->fbr[1]->bus_low[index] = (u32) Fbr1TempPa;
 
 			Fbr1TempPa += rx_ring->Fbr1BufferSize;
 
-			rx_ring->Fbr[1]->Buffer1[index] =
-			    rx_ring->Fbr[1]->Va[index];
-			rx_ring->Fbr[1]->Buffer2[index] =
-			    rx_ring->Fbr[1]->Va[index] - 4;
+			rx_ring->fbr[1]->buffer1[index] =
+			    rx_ring->fbr[1]->virt[index];
+			rx_ring->fbr[1]->buffer2[index] =
+			    rx_ring->fbr[1]->virt[index] - 4;
 		}
 	}
 
@@ -319,27 +313,27 @@ int et131x_rx_dma_memory_alloc(struct et
 		for (j = 0; j < FBR_CHUNKS; j++) {
 			u32 index = (i * FBR_CHUNKS) + j;
 
-			rx_ring->Fbr[0]->Va[index] =
-			    (uint8_t *) rx_ring->Fbr0MemVa[i] +
+			rx_ring->fbr[0]->virt[index] =
+			    (u8 *) rx_ring->Fbr0MemVa[i] +
 			    (j * rx_ring->Fbr0BufferSize) + Fbr0Offset;
 
-			rx_ring->Fbr[0]->PAHigh[index] =
+			rx_ring->fbr[0]->bus_high[index] =
 			    (u32) (Fbr0TempPa >> 32);
-			rx_ring->Fbr[0]->PALow[index] = (u32) Fbr0TempPa;
+			rx_ring->fbr[0]->bus_low[index] = (u32) Fbr0TempPa;
 
 			Fbr0TempPa += rx_ring->Fbr0BufferSize;
 
-			rx_ring->Fbr[0]->Buffer1[index] =
-			    rx_ring->Fbr[0]->Va[index];
-			rx_ring->Fbr[0]->Buffer2[index] =
-			    rx_ring->Fbr[0]->Va[index] - 4;
+			rx_ring->fbr[0]->buffer1[index] =
+			    rx_ring->fbr[0]->virt[index];
+			rx_ring->fbr[0]->buffer2[index] =
+			    rx_ring->fbr[0]->virt[index] - 4;
 		}
 	}
 #endif
 
 	/* Allocate an area of memory for FIFO of Packet Status ring entries */
 	pktStatRingSize =
-	    sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries;
+	    sizeof(struct pkt_stat_desc) * adapter->rx_ring.PsrNumEntries;
 
 	rx_ring->pPSRingVa = pci_alloc_consistent(adapter->pdev,
 						  pktStatRingSize,
@@ -360,16 +354,16 @@ int et131x_rx_dma_memory_alloc(struct et
 	 */
 
 	/* Allocate an area of memory for writeback of status information */
-	rx_ring->pRxStatusVa = pci_alloc_consistent(adapter->pdev,
-						    sizeof(RX_STATUS_BLOCK_t),
-						    &rx_ring->pRxStatusPa);
-	if (!rx_ring->pRxStatusVa) {
+	rx_ring->rx_status_block = pci_alloc_consistent(adapter->pdev,
+					    sizeof(struct rx_status_block),
+					    &rx_ring->rx_status_bus);
+	if (!rx_ring->rx_status_block) {
 		dev_err(&adapter->pdev->dev,
 			  "Cannot alloc memory for Status Block\n");
 		return -ENOMEM;
 	}
 	rx_ring->NumRfd = NIC_DEFAULT_NUM_RFD;
-	printk("PRS %lx\n", (unsigned long)rx_ring->pRxStatusPa);
+	printk("PRS %lx\n", (unsigned long)rx_ring->rx_status_bus);
 
 	/* Recv
 	 * pci_pool_create initializes a lookaside list. After successful
@@ -403,10 +397,10 @@ void et131x_rx_dma_memory_free(struct et
 	u32 bufsize;
 	u32 pktStatRingSize;
 	PMP_RFD rfd;
-	RX_RING_t *rx_ring;
+	struct rx_ring *rx_ring;
 
 	/* Setup some convenience pointers */
-	rx_ring = (RX_RING_t *) &adapter->RxRing;
+	rx_ring = &adapter->rx_ring;
 
 	/* Free RFDs and associated packet descriptors */
 	WARN_ON(rx_ring->nReadyRecv != rx_ring->NumRfd);
@@ -417,7 +411,7 @@ void et131x_rx_dma_memory_free(struct et
 
 		list_del(&rfd->list_node);
 		rfd->Packet = NULL;
-		kmem_cache_free(adapter->RxRing.RecvLookaside, rfd);
+		kmem_cache_free(adapter->rx_ring.RecvLookaside, rfd);
 	}
 
 	/* Free Free Buffer Ring 1 */
@@ -447,15 +441,14 @@ void et131x_rx_dma_memory_free(struct et
 		}
 
 		/* Now the FIFO itself */
-		rx_ring->pFbr1RingVa = (void *)((uint8_t *)
+		rx_ring->pFbr1RingVa = (void *)((u8 *)
 				rx_ring->pFbr1RingVa - rx_ring->Fbr1offset);
 
-		bufsize =
-		    (sizeof(FBR_DESC_t) * rx_ring->Fbr1NumEntries) + 0xfff;
+		bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr1NumEntries)
+	                                                        + 0xfff;
 
-		pci_free_consistent(adapter->pdev,
-				    bufsize,
-				    rx_ring->pFbr1RingVa, rx_ring->pFbr1RingPa);
+		pci_free_consistent(adapter->pdev, bufsize,
+                                rx_ring->pFbr1RingVa, rx_ring->pFbr1RingPa);
 
 		rx_ring->pFbr1RingVa = NULL;
 	}
@@ -481,11 +474,11 @@ void et131x_rx_dma_memory_free(struct et
 		}
 
 		/* Now the FIFO itself */
-		rx_ring->pFbr0RingVa = (void *)((uint8_t *)
+		rx_ring->pFbr0RingVa = (void *)((u8 *)
 				rx_ring->pFbr0RingVa - rx_ring->Fbr0offset);
 
-		bufsize =
-		    (sizeof(FBR_DESC_t) * rx_ring->Fbr0NumEntries) + 0xfff;
+		bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr0NumEntries)
+                                                                + 0xfff;
 
 		pci_free_consistent(adapter->pdev,
 				    bufsize,
@@ -498,7 +491,7 @@ void et131x_rx_dma_memory_free(struct et
 	/* Free Packet Status Ring */
 	if (rx_ring->pPSRingVa) {
 		pktStatRingSize =
-		    sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries;
+		    sizeof(struct pkt_stat_desc) * adapter->rx_ring.PsrNumEntries;
 
 		pci_free_consistent(adapter->pdev, pktStatRingSize,
 				    rx_ring->pPSRingVa, rx_ring->pPSRingPa);
@@ -507,12 +500,11 @@ void et131x_rx_dma_memory_free(struct et
 	}
 
 	/* Free area of memory for the writeback of status information */
-	if (rx_ring->pRxStatusVa) {
+	if (rx_ring->rx_status_block) {
 		pci_free_consistent(adapter->pdev,
-				sizeof(RX_STATUS_BLOCK_t),
-				rx_ring->pRxStatusVa, rx_ring->pRxStatusPa);
-
-		rx_ring->pRxStatusVa = NULL;
+			sizeof(struct rx_status_block),
+			rx_ring->rx_status_block, rx_ring->rx_status_bus);
+        	rx_ring->rx_status_block = NULL;
 	}
 
 	/* Free receive buffer pool */
@@ -527,10 +519,10 @@ void et131x_rx_dma_memory_free(struct et
 
 	/* Free the FBR Lookup Table */
 #ifdef USE_FBR0
-	kfree(rx_ring->Fbr[0]);
+	kfree(rx_ring->fbr[0]);
 #endif
 
-	kfree(rx_ring->Fbr[1]);
+	kfree(rx_ring->fbr[1]);
 
 	/* Reset Counters */
 	rx_ring->nReadyRecv = 0;
@@ -548,10 +540,10 @@ int et131x_init_recv(struct et131x_adapt
 	PMP_RFD rfd = NULL;
 	u32 rfdct;
 	u32 numrfd = 0;
-	RX_RING_t *rx_ring = NULL;
+	struct rx_ring *rx_ring;
 
 	/* Setup some convenience pointers */
-	rx_ring = (RX_RING_t *) &adapter->RxRing;
+	rx_ring = &adapter->rx_ring;
 
 	/* Setup each RFD */
 	for (rfdct = 0; rfdct < rx_ring->NumRfd; rfdct++) {
@@ -594,9 +586,9 @@ int et131x_init_recv(struct et131x_adapt
  */
 void ConfigRxDmaRegs(struct et131x_adapter *etdev)
 {
-	struct _RXDMA_t __iomem *rx_dma = &etdev->regs->rxdma;
-	struct _rx_ring_t *rx_local = &etdev->RxRing;
-	PFBR_DESC_t fbr_entry;
+	struct rxdma_regs __iomem *rx_dma = &etdev->regs->rxdma;
+	struct rx_ring *rx_local = &etdev->rx_ring;
+	struct fbr_desc *fbr_entry;
 	u32 entry;
 	u32 psr_num_des;
 	unsigned long flags;
@@ -611,11 +603,11 @@ void ConfigRxDmaRegs(struct et131x_adapt
 	 * are ever returned, make sure the high part is retrieved here
 	 * before storing the adjusted address.
 	 */
-	writel((u32) ((u64)rx_local->pRxStatusPa >> 32),
+	writel((u32) ((u64)rx_local->rx_status_bus >> 32),
 	       &rx_dma->dma_wb_base_hi);
-	writel((u32) rx_local->pRxStatusPa, &rx_dma->dma_wb_base_lo);
+	writel((u32) rx_local->rx_status_bus, &rx_dma->dma_wb_base_lo);
 
-	memset(rx_local->pRxStatusVa, 0, sizeof(RX_STATUS_BLOCK_t));
+	memset(rx_local->rx_status_block, 0, sizeof(struct rx_status_block));
 
 	/* Set the address and parameters of the packet status ring into the
 	 * 1310's registers
@@ -636,11 +628,11 @@ void ConfigRxDmaRegs(struct et131x_adapt
 	rx_local->local_psr_full = 0;
 
 	/* Now's the best time to initialize FBR1 contents */
-	fbr_entry = (PFBR_DESC_t) rx_local->pFbr1RingVa;
+	fbr_entry = (struct fbr_desc *) rx_local->pFbr1RingVa;
 	for (entry = 0; entry < rx_local->Fbr1NumEntries; entry++) {
-		fbr_entry->addr_hi = rx_local->Fbr[1]->PAHigh[entry];
-		fbr_entry->addr_lo = rx_local->Fbr[1]->PALow[entry];
-		fbr_entry->word2.bits.bi = entry;
+		fbr_entry->addr_hi = rx_local->fbr[1]->bus_high[entry];
+		fbr_entry->addr_lo = rx_local->fbr[1]->bus_low[entry];
+		fbr_entry->word2 = entry;
 		fbr_entry++;
 	}
 
@@ -661,11 +653,11 @@ void ConfigRxDmaRegs(struct et131x_adapt
 
 #ifdef USE_FBR0
 	/* Now's the best time to initialize FBR0 contents */
-	fbr_entry = (PFBR_DESC_t) rx_local->pFbr0RingVa;
+	fbr_entry = (struct fbr_desc *) rx_local->pFbr0RingVa;
 	for (entry = 0; entry < rx_local->Fbr0NumEntries; entry++) {
-		fbr_entry->addr_hi = rx_local->Fbr[0]->PAHigh[entry];
-		fbr_entry->addr_lo = rx_local->Fbr[0]->PALow[entry];
-		fbr_entry->word2.bits.bi = entry;
+		fbr_entry->addr_hi = rx_local->fbr[0]->bus_high[entry];
+		fbr_entry->addr_lo = rx_local->fbr[0]->bus_low[entry];
+		fbr_entry->word2 = entry;
 		fbr_entry++;
 	}
 
@@ -721,18 +713,17 @@ void SetRxDmaTimer(struct et131x_adapter
  */
 void et131x_rx_dma_disable(struct et131x_adapter *etdev)
 {
-	RXDMA_CSR_t csr;
-
+        u32 csr;
 	/* Setup the receive dma configuration register */
-	writel(0x00002001, &etdev->regs->rxdma.csr.value);
-	csr.value = readl(&etdev->regs->rxdma.csr.value);
-	if (csr.bits.halt_status != 1) {
+	writel(0x00002001, &etdev->regs->rxdma.csr);
+	csr = readl(&etdev->regs->rxdma.csr);
+	if ((csr & 0x00020000) != 1) {	/* Check halt status (bit 17) */
 		udelay(5);
-		csr.value = readl(&etdev->regs->rxdma.csr.value);
-		if (csr.bits.halt_status != 1)
+		csr = readl(&etdev->regs->rxdma.csr);
+		if ((csr & 0x00020000) != 1)
 			dev_err(&etdev->pdev->dev,
-				"RX Dma failed to enter halt state. CSR 0x%08x\n",
-				csr.value);
+			"RX Dma failed to enter halt state. CSR 0x%08x\n",
+				csr);
 	}
 }
 
@@ -743,34 +734,33 @@ void et131x_rx_dma_disable(struct et131x
 void et131x_rx_dma_enable(struct et131x_adapter *etdev)
 {
 	/* Setup the receive dma configuration register for normal operation */
-	RXDMA_CSR_t csr = { 0 };
+	u32 csr =  0x2000;	/* FBR1 enable */
 
-	csr.bits.fbr1_enable = 1;
-	if (etdev->RxRing.Fbr1BufferSize == 4096)
-		csr.bits.fbr1_size = 1;
-	else if (etdev->RxRing.Fbr1BufferSize == 8192)
-		csr.bits.fbr1_size = 2;
-	else if (etdev->RxRing.Fbr1BufferSize == 16384)
-		csr.bits.fbr1_size = 3;
+	if (etdev->rx_ring.Fbr1BufferSize == 4096)
+		csr |= 0x0800;
+	else if (etdev->rx_ring.Fbr1BufferSize == 8192)
+		csr |= 0x1000;
+	else if (etdev->rx_ring.Fbr1BufferSize == 16384)
+		csr |= 0x1800;
 #ifdef USE_FBR0
-	csr.bits.fbr0_enable = 1;
-	if (etdev->RxRing.Fbr0BufferSize == 256)
-		csr.bits.fbr0_size = 1;
-	else if (etdev->RxRing.Fbr0BufferSize == 512)
-		csr.bits.fbr0_size = 2;
-	else if (etdev->RxRing.Fbr0BufferSize == 1024)
-		csr.bits.fbr0_size = 3;
+        csr |= 0x0400;		/* FBR0 enable */
+	if (etdev->rx_ring.Fbr0BufferSize == 256)
+	        csr |= 0x0100;
+	else if (etdev->rx_ring.Fbr0BufferSize == 512)
+		csr |= 0x0200;
+	else if (etdev->rx_ring.Fbr0BufferSize == 1024)
+		csr |= 0x0300;
 #endif
-	writel(csr.value, &etdev->regs->rxdma.csr.value);
+	writel(csr, &etdev->regs->rxdma.csr);
 
-	csr.value = readl(&etdev->regs->rxdma.csr.value);
-	if (csr.bits.halt_status != 0) {
+	csr = readl(&etdev->regs->rxdma.csr);
+	if ((csr & 0x00020000) != 0) {
 		udelay(5);
-		csr.value = readl(&etdev->regs->rxdma.csr.value);
-		if (csr.bits.halt_status != 0) {
+		csr = readl(&etdev->regs->rxdma.csr);
+        	if ((csr & 0x00020000) != 0) {
 			dev_err(&etdev->pdev->dev,
 			    "RX Dma failed to exit halt state.  CSR 0x%08x\n",
-				csr.value);
+				csr);
 		}
 	}
 }
@@ -788,46 +778,44 @@ void et131x_rx_dma_enable(struct et131x_
  */
 PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
 {
-	struct _rx_ring_t *rx_local = &etdev->RxRing;
-	PRX_STATUS_BLOCK_t status;
-	PPKT_STAT_DESC_t psr;
+	struct rx_ring *rx_local = &etdev->rx_ring;
+	struct rx_status_block *status;
+	struct pkt_stat_desc *psr;
 	PMP_RFD rfd;
 	u32 i;
-	uint8_t *buf;
+	u8 *buf;
 	unsigned long flags;
 	struct list_head *element;
-	uint8_t rindex;
-	uint16_t bindex;
+	u8 rindex;
+	u16 bindex;
 	u32 len;
-	PKT_STAT_DESC_WORD0_t Word0;
+	u32 word0;
+	u32 word1;
 
 	/* RX Status block is written by the DMA engine prior to every
 	 * interrupt. It contains the next to be used entry in the Packet
 	 * Status Ring, and also the two Free Buffer rings.
 	 */
-	status = (PRX_STATUS_BLOCK_t) rx_local->pRxStatusVa;
+	status = rx_local->rx_status_block;
+	word1 = status->Word1 >> 16;	/* Get the useful bits */
 
-	/* FIXME: tidy later when conversions complete */
-	if (status->Word1.bits.PSRoffset ==
-			(rx_local->local_psr_full & 0xFFF) &&
-			status->Word1.bits.PSRwrap ==
-			((rx_local->local_psr_full >> 12) & 1)) {
+	/* Check the PSR and wrap bits do not match */
+	if ((word1 & 0x1FFF) == (rx_local->local_psr_full & 0x1FFF))
 		/* Looks like this ring is not updated yet */
 		return NULL;
-	}
 
 	/* The packet status ring indicates that data is available. */
-	psr = (PPKT_STAT_DESC_t) (rx_local->pPSRingVa) +
+	psr = (struct pkt_stat_desc *) (rx_local->pPSRingVa) +
 			(rx_local->local_psr_full & 0xFFF);
 
 	/* Grab any information that is required once the PSR is
 	 * advanced, since we can no longer rely on the memory being
 	 * accurate
 	 */
-	len = psr->word1.bits.length;
-	rindex = (uint8_t) psr->word1.bits.ri;
-	bindex = (uint16_t) psr->word1.bits.bi;
-	Word0 = psr->word0;
+	len = psr->word1 & 0xFFFF;
+	rindex = (psr->word1 >> 26) & 0x03;
+	bindex = (psr->word1 >> 16) & 0x3FF;
+	word0 = psr->word0;
 
 	/* Indicate that we have used this PSR entry. */
 	/* FIXME wrap 12 */
@@ -842,9 +830,8 @@ PMP_RFD nic_rx_pkts(struct et131x_adapte
 	       &etdev->regs->rxdma.psr_full_offset);
 
 #ifndef USE_FBR0
-	if (rindex != 1) {
+	if (rindex != 1)
 		return NULL;
-	}
 #endif
 
 #ifdef USE_FBR0
@@ -899,7 +886,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapte
 
 	if (len) {
 		if (etdev->ReplicaPhyLoopbk == 1) {
-			buf = rx_local->Fbr[rindex]->Va[bindex];
+			buf = rx_local->fbr[rindex]->virt[bindex];
 
 			if (memcmp(&buf[6], &etdev->CurrentAddress[0],
 				   ETH_ALEN) == 0) {
@@ -911,8 +898,8 @@ PMP_RFD nic_rx_pkts(struct et131x_adapte
 		}
 
 		/* Determine if this is a multicast packet coming in */
-		if ((Word0.value & ALCATEL_MULTICAST_PKT) &&
-		    !(Word0.value & ALCATEL_BROADCAST_PKT)) {
+		if ((word0 & ALCATEL_MULTICAST_PKT) &&
+		    !(word0 & ALCATEL_BROADCAST_PKT)) {
 			/* Promiscuous mode and Multicast mode are
 			 * not mutually exclusive as was first
 			 * thought.  I guess Promiscuous is just
@@ -923,8 +910,8 @@ PMP_RFD nic_rx_pkts(struct et131x_adapte
 			if ((etdev->PacketFilter & ET131X_PACKET_TYPE_MULTICAST)
 			    && !(etdev->PacketFilter & ET131X_PACKET_TYPE_PROMISCUOUS)
 			    && !(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) {
-				buf = rx_local->Fbr[rindex]->
-						Va[bindex];
+				buf = rx_local->fbr[rindex]->
+						virt[bindex];
 
 				/* Loop through our list to see if the
 				 * destination address of this packet
@@ -963,7 +950,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapte
 
 			if (len > 0)
 				etdev->Stats.multircv++;
-		} else if (Word0.value & ALCATEL_BROADCAST_PKT)
+		} else if (word0 & ALCATEL_BROADCAST_PKT)
 			etdev->Stats.brdcstrcv++;
 		else
 			/* Not sure what this counter measures in
@@ -990,7 +977,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapte
 		etdev->net_stats.rx_bytes += rfd->PacketSize;
 
 		memcpy(skb_put(skb, rfd->PacketSize),
-		       rx_local->Fbr[rindex]->Va[bindex],
+		       rx_local->fbr[rindex]->virt[bindex],
 		       rfd->PacketSize);
 
 		skb->dev = etdev->netdev;
@@ -1014,7 +1001,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapte
  */
 void et131x_reset_recv(struct et131x_adapter *etdev)
 {
-	WARN_ON(list_empty(&etdev->RxRing.RecvList));
+	WARN_ON(list_empty(&etdev->rx_ring.RecvList));
 
 }
 
@@ -1032,8 +1019,8 @@ void et131x_handle_recv_interrupt(struct
 
 	/* Process up to available RFD's */
 	while (count < NUM_PACKETS_HANDLED) {
-		if (list_empty(&etdev->RxRing.RecvList)) {
-			WARN_ON(etdev->RxRing.nReadyRecv != 0);
+		if (list_empty(&etdev->rx_ring.RecvList)) {
+			WARN_ON(etdev->rx_ring.nReadyRecv != 0);
 			done = false;
 			break;
 		}
@@ -1058,7 +1045,7 @@ void et131x_handle_recv_interrupt(struct
 		etdev->Stats.ipackets++;
 
 		/* Set the status on the packet, either resources or success */
-		if (etdev->RxRing.nReadyRecv < RFD_LOW_WATER_MARK) {
+		if (etdev->rx_ring.nReadyRecv < RFD_LOW_WATER_MARK) {
 			dev_warn(&etdev->pdev->dev,
 				    "RFD's are running out\n");
 		}
@@ -1066,12 +1053,12 @@ void et131x_handle_recv_interrupt(struct
 	}
 
 	if (count == NUM_PACKETS_HANDLED || !done) {
-		etdev->RxRing.UnfinishedReceives = true;
+		etdev->rx_ring.UnfinishedReceives = true;
 		writel(PARM_TX_TIME_INT_DEF * NANO_IN_A_MICRO,
 		       &etdev->regs->global.watchdog_timer);
 	} else
 		/* Watchdog timer will disable itself if appropriate. */
-		etdev->RxRing.UnfinishedReceives = false;
+		etdev->rx_ring.UnfinishedReceives = false;
 }
 
 static inline u32 bump_fbr(u32 *fbr, u32 limit)
@@ -1099,10 +1086,10 @@ static inline u32 bump_fbr(u32 *fbr, u32
  */
 void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd)
 {
-	struct _rx_ring_t *rx_local = &etdev->RxRing;
-	struct _RXDMA_t __iomem *rx_dma = &etdev->regs->rxdma;
-	uint16_t bi = rfd->bufferindex;
-	uint8_t ri = rfd->ringindex;
+	struct rx_ring *rx_local = &etdev->rx_ring;
+	struct rxdma_regs __iomem *rx_dma = &etdev->regs->rxdma;
+	u16 bi = rfd->bufferindex;
+	u8 ri = rfd->ringindex;
 	unsigned long flags;
 
 	/* We don't use any of the OOB data besides status. Otherwise, we
@@ -1116,17 +1103,17 @@ void nic_return_rfd(struct et131x_adapte
 		spin_lock_irqsave(&etdev->FbrLock, flags);
 
 		if (ri == 1) {
-			PFBR_DESC_t next =
-			    (PFBR_DESC_t) (rx_local->pFbr1RingVa) +
-			    INDEX10(rx_local->local_Fbr1_full);
+			struct fbr_desc *next =
+			    (struct fbr_desc *) (rx_local->pFbr1RingVa) +
+                		            INDEX10(rx_local->local_Fbr1_full);
 
 			/* Handle the Free Buffer Ring advancement here. Write
 			 * the PA / Buffer Index for the returned buffer into
 			 * the oldest (next to be freed)FBR entry
 			 */
-			next->addr_hi = rx_local->Fbr[1]->PAHigh[bi];
-			next->addr_lo = rx_local->Fbr[1]->PALow[bi];
-			next->word2.value = bi;
+			next->addr_hi = rx_local->fbr[1]->bus_high[bi];
+			next->addr_lo = rx_local->fbr[1]->bus_low[bi];
+			next->word2 = bi;
 
 			writel(bump_fbr(&rx_local->local_Fbr1_full,
 				rx_local->Fbr1NumEntries - 1),
@@ -1134,17 +1121,17 @@ void nic_return_rfd(struct et131x_adapte
 		}
 #ifdef USE_FBR0
 		else {
-			PFBR_DESC_t next =
-			    (PFBR_DESC_t) rx_local->pFbr0RingVa +
-			    INDEX10(rx_local->local_Fbr0_full);
+			struct fbr_desc *next = (struct fbr_desc *)
+				rx_local->pFbr0RingVa +
+					INDEX10(rx_local->local_Fbr0_full);
 
 			/* Handle the Free Buffer Ring advancement here. Write
 			 * the PA / Buffer Index for the returned buffer into
 			 * the oldest (next to be freed) FBR entry
 			 */
-			next->addr_hi = rx_local->Fbr[0]->PAHigh[bi];
-			next->addr_lo = rx_local->Fbr[0]->PALow[bi];
-			next->word2.value = bi;
+			next->addr_hi = rx_local->fbr[0]->bus_high[bi];
+			next->addr_lo = rx_local->fbr[0]->bus_low[bi];
+			next->word2 = bi;
 
 			writel(bump_fbr(&rx_local->local_Fbr0_full,
 					rx_local->Fbr0NumEntries - 1),
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_rx.h linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_rx.h
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_rx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_rx.h	2010-05-16 17:17:36.000000000 -0400
@@ -91,120 +91,60 @@
 #define ALCATEL_BROADCAST_PKT	0x02000000
 
 /* typedefs for Free Buffer Descriptors */
-typedef union _FBR_WORD2_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved:22;	/* bits 10-31 */
-		u32 bi:10;		/* bits 0-9(Buffer Index) */
-#else
-		u32 bi:10;		/* bits 0-9(Buffer Index) */
-		u32 reserved:22;	/* bit 10-31 */
-#endif
-	} bits;
-} FBR_WORD2_t, *PFBR_WORD2_t;
-
-typedef struct _FBR_DESC_t {
+struct fbr_desc
+{
 	u32 addr_lo;
 	u32 addr_hi;
-	FBR_WORD2_t word2;
-} FBR_DESC_t, *PFBR_DESC_t;
-
-/* Typedefs for Packet Status Ring Descriptors */
-typedef union _PKT_STAT_DESC_WORD0_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		/* top 16 bits are from the Alcatel Status Word as enumerated in */
-		/* PE-MCXMAC Data Sheet IPD DS54 0210-1 (also IPD-DS80 0205-2) */
-#if 0
-		u32 asw_trunc:1;		/* bit 31(Rx frame truncated) */
-#endif
-		u32 asw_long_evt:1;	/* bit 31(Rx long event) */
-		u32 asw_VLAN_tag:1;	/* bit 30(VLAN tag detected) */
-		u32 asw_unsupported_op:1;	/* bit 29(unsupported OP code) */
-		u32 asw_pause_frame:1;	/* bit 28(is a pause frame) */
-		u32 asw_control_frame:1;	/* bit 27(is a control frame) */
-		u32 asw_dribble_nibble:1;	/* bit 26(spurious bits after EOP) */
-		u32 asw_broadcast:1;	/* bit 25(has a broadcast address) */
-		u32 asw_multicast:1;	/* bit 24(has a multicast address) */
-		u32 asw_OK:1;		/* bit 23(valid CRC + no code error) */
-		u32 asw_too_long:1;	/* bit 22(frame length > 1518 bytes) */
-		u32 asw_len_chk_err:1;	/* bit 21(frame length field incorrect) */
-		u32 asw_CRC_err:1;		/* bit 20(CRC error) */
-		u32 asw_code_err:1;	/* bit 19(one or more nibbles signalled as errors) */
-		u32 asw_false_carrier_event:1;	/* bit 18(bad carrier since last good packet) */
-		u32 asw_RX_DV_event:1;	/* bit 17(short receive event detected) */
-		u32 asw_prev_pkt_dropped:1;/* bit 16(e.g. IFG too small on previous) */
-		u32 unused:5;		/* bits 11-15 */
-		u32 vp:1;			/* bit 10(VLAN Packet) */
-		u32 jp:1;			/* bit 9(Jumbo Packet) */
-		u32 ft:1;			/* bit 8(Frame Truncated) */
-		u32 drop:1;		/* bit 7(Drop packet) */
-		u32 rxmac_error:1;		/* bit 6(RXMAC Error Indicator) */
-		u32 wol:1;			/* bit 5(WOL Event) */
-		u32 tcpp:1;		/* bit 4(TCP checksum pass) */
-		u32 tcpa:1;		/* bit 3(TCP checksum assist) */
-		u32 ipp:1;			/* bit 2(IP checksum pass) */
-		u32 ipa:1;			/* bit 1(IP checksum assist) */
-		u32 hp:1;			/* bit 0(hash pass) */
-#else
-		u32 hp:1;			/* bit 0(hash pass) */
-		u32 ipa:1;			/* bit 1(IP checksum assist) */
-		u32 ipp:1;			/* bit 2(IP checksum pass) */
-		u32 tcpa:1;		/* bit 3(TCP checksum assist) */
-		u32 tcpp:1;		/* bit 4(TCP checksum pass) */
-		u32 wol:1;			/* bit 5(WOL Event) */
-		u32 rxmac_error:1;		/* bit 6(RXMAC Error Indicator) */
-		u32 drop:1;		/* bit 7(Drop packet) */
-		u32 ft:1;			/* bit 8(Frame Truncated) */
-		u32 jp:1;			/* bit 9(Jumbo Packet) */
-		u32 vp:1;			/* bit 10(VLAN Packet) */
-		u32 unused:5;		/* bits 11-15 */
-		u32 asw_prev_pkt_dropped:1;/* bit 16(e.g. IFG too small on previous) */
-		u32 asw_RX_DV_event:1;	/* bit 17(short receive event detected) */
-		u32 asw_false_carrier_event:1;	/* bit 18(bad carrier since last good packet) */
-		u32 asw_code_err:1;	/* bit 19(one or more nibbles signalled as errors) */
-		u32 asw_CRC_err:1;		/* bit 20(CRC error) */
-		u32 asw_len_chk_err:1;	/* bit 21(frame length field incorrect) */
-		u32 asw_too_long:1;	/* bit 22(frame length > 1518 bytes) */
-		u32 asw_OK:1;		/* bit 23(valid CRC + no code error) */
-		u32 asw_multicast:1;	/* bit 24(has a multicast address) */
-		u32 asw_broadcast:1;	/* bit 25(has a broadcast address) */
-		u32 asw_dribble_nibble:1;	/* bit 26(spurious bits after EOP) */
-		u32 asw_control_frame:1;	/* bit 27(is a control frame) */
-		u32 asw_pause_frame:1;	/* bit 28(is a pause frame) */
-		u32 asw_unsupported_op:1;	/* bit 29(unsupported OP code) */
-		u32 asw_VLAN_tag:1;	/* bit 30(VLAN tag detected) */
-		u32 asw_long_evt:1;	/* bit 31(Rx long event) */
-#if 0
-		u32 asw_trunc:1;		/* bit 31(Rx frame truncated) */
-#endif
-#endif
-	} bits;
-} PKT_STAT_DESC_WORD0_t, *PPKT_STAT_WORD0_t;
+	u32 word2;		/* Bits 10-31 reserved, 0-9 descriptor */
+};
 
-typedef union _PKT_STAT_DESC_WORD1_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:4;	/* bits 28-31 */
-		u32 ri:2;		/* bits 26-27(Ring Index) */
-		u32 bi:10;		/* bits 16-25(Buffer Index) */
-		u32 length:16;	/* bit 0-15(length in bytes) */
-#else
-		u32 length:16;	/* bit 0-15(length in bytes) */
-		u32 bi:10;		/* bits 16-25(Buffer Index) */
-		u32 ri:2;		/* bits 26-27(Ring Index) */
-		u32 unused:4;	/* bits 28-31 */
-#endif
-	} bits;
-} PKT_STAT_DESC_WORD1_t, *PPKT_STAT_WORD1_t;
+/* Packet Status Ring Descriptors
+ *
+ * Word 0:
+ *
+ * top 16 bits are from the Alcatel Status Word as enumerated in
+ * PE-MCXMAC Data Sheet IPD DS54 0210-1 (also IPD-DS80 0205-2)
+ *
+ * 0: hp			hash pass
+ * 1: ipa			IP checksum assist
+ * 2: ipp			IP checksum pass
+ * 3: tcpa			TCP checksum assist
+ * 4: tcpp			TCP checksum pass
+ * 5: wol			WOL Event
+ * 6: rxmac_error		RXMAC Error Indicator
+ * 7: drop			Drop packet
+ * 8: ft			Frame Truncated
+ * 9: jp			Jumbo Packet
+ * 10: vp			VLAN Packet
+ * 11-15: unused
+ * 16: asw_prev_pkt_dropped 	e.g. IFG too small on previous
+ * 17: asw_RX_DV_event		short receive event detected
+ * 18: asw_false_carrier_event	bad carrier since last good packet
+ * 19: asw_code_err		one or more nibbles signalled as errors
+ * 20: asw_CRC_err		CRC error
+ * 21: asw_len_chk_err		frame length field incorrect
+ * 22: asw_too_long		frame length > 1518 bytes
+ * 23: asw_OK			valid CRC + no code error
+ * 24: asw_multicast		has a multicast address
+ * 25: asw_broadcast		has a broadcast address
+ * 26: asw_dribble_nibble	spurious bits after EOP
+ * 27: asw_control_frame	is a control frame
+ * 28: asw_pause_frame		is a pause frame
+ * 29: asw_unsupported_op	unsupported OP code
+ * 30: asw_VLAN_tag		VLAN tag detected
+ * 31: asw_long_evt		Rx long event
+ *
+ * Word 1:
+ * 0-15: length			length in bytes
+ * 16-25: bi			Buffer Index
+ * 26-27: ri			Ring Index
+ * 28-31: reserved
+ */
 
-typedef struct _PKT_STAT_DESC_t {
-	PKT_STAT_DESC_WORD0_t word0;
-	PKT_STAT_DESC_WORD1_t word1;
-} PKT_STAT_DESC_t, *PPKT_STAT_DESC_t;
+struct pkt_stat_desc {
+	u32 word0;
+	u32 word1;
+};
 
 /* Typedefs for the RX DMA status word */
 
@@ -223,59 +163,38 @@ typedef struct _PKT_STAT_DESC_t {
  * RXSTAT_WORD1_t structure holds part of the status bits of the Rx DMA engine
  * that get copied out to memory by the ET-1310.  Word 3 is a 32 bit word
  * which contains the Packet Status Ring available offset.
+ *
+ * bit 0-15 reserved
+ * bit 16-27 PSRoffset
+ * bit 28 PSRwrap
+ * bit 29-31 unused
  */
 
-#define RXSTAT1_OFFSET	16
-#define RXSTAT1_MASK	0xFFF
-#define RXSTAT1_WRAP	0x10000000
-
-typedef union _rxstat_word1_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 PSRunused:3;	/* bits 29-31 */
-		u32 PSRwrap:1;	/* bit 28 */
-		u32 PSRoffset:12;	/* bits 16-27 */
-		u32 reserved:16;	/* bits 0-15 */
-#else
-		u32 reserved:16;	/* bits 0-15 */
-		u32 PSRoffset:12;	/* bits 16-27 */
-		u32 PSRwrap:1;	/* bit 28 */
-		u32 PSRunused:3;	/* bits 29-31 */
-#endif
-	} bits;
-} RXSTAT_WORD1_t, *PRXSTAT_WORD1_t;
-
 /*
- * RX_STATUS_BLOCK_t is sructure representing the status of the Rx DMA engine
- * it sits in free memory, and is pointed to by 0x101c / 0x1020
+ * struct rx_status_block is a structure representing the status of the Rx
+ * DMA engine it sits in free memory, and is pointed to by 0x101c / 0x1020
  */
-typedef struct _rx_status_block_t {
+struct rx_status_block {
 	u32 Word0;
-	RXSTAT_WORD1_t Word1;
-} RX_STATUS_BLOCK_t, *PRX_STATUS_BLOCK_t;
+	u32 Word1;
+};
 
 /*
  * Structure for look-up table holding free buffer ring pointers
  */
-typedef struct _FbrLookupTable {
-	void *Va[MAX_DESC_PER_RING_RX];
-	void *Buffer1[MAX_DESC_PER_RING_RX];
-	void *Buffer2[MAX_DESC_PER_RING_RX];
-	u32 PAHigh[MAX_DESC_PER_RING_RX];
-	u32 PALow[MAX_DESC_PER_RING_RX];
-} FBRLOOKUPTABLE, *PFBRLOOKUPTABLE;
-
-typedef enum {
-	ONE_PACKET_INTERRUPT,
-	FOUR_PACKET_INTERRUPT
-} eRX_INTERRUPT_STATE_t, *PeRX_INTERRUPT_STATE_t;
+struct fbr_lookup {
+	void *virt[MAX_DESC_PER_RING_RX];
+	void *buffer1[MAX_DESC_PER_RING_RX];
+	void *buffer2[MAX_DESC_PER_RING_RX];
+	u32 bus_high[MAX_DESC_PER_RING_RX];
+	u32 bus_low[MAX_DESC_PER_RING_RX];
+};
 
 /*
- * RX_RING_t is sructure representing the adaptor's local reference(s) to the
- * rings
+ * struct rx_ring is the ssructure representing the adaptor's local
+ * reference(s) to the rings
  */
-typedef struct _rx_ring_t {
+struct rx_ring {
 #ifdef USE_FBR0
 	void *pFbr0RingVa;
 	dma_addr_t pFbr0RingPa;
@@ -293,7 +212,7 @@ typedef struct _rx_ring_t {
 	dma_addr_t Fbr1MemPa[MAX_DESC_PER_RING_RX / FBR_CHUNKS];
 	uint64_t Fbr1Realpa;
 	uint64_t Fbr1offset;
-	FBRLOOKUPTABLE *Fbr[2];
+	struct fbr_lookup *fbr[2];	/* One per ring */
 	u32 local_Fbr1_full;
 	u32 Fbr1NumEntries;
 	u32 Fbr1BufferSize;
@@ -303,8 +222,8 @@ typedef struct _rx_ring_t {
 	u32 local_psr_full;
 	u32 PsrNumEntries;
 
-	void *pRxStatusVa;
-	dma_addr_t pRxStatusPa;
+	struct rx_status_block *rx_status_block;
+	dma_addr_t rx_status_bus;
 
 	struct list_head RecvBufferPool;
 
@@ -320,30 +239,6 @@ typedef struct _rx_ring_t {
 
 	/* lookaside lists */
 	struct kmem_cache *RecvLookaside;
-} RX_RING_t, *PRX_RING_t;
-
-/* Forward reference of RFD */
-struct _MP_RFD;
-
-/* Forward declaration of the private adapter structure */
-struct et131x_adapter;
-
-/* PROTOTYPES for Initialization */
-int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter);
-void et131x_rx_dma_memory_free(struct et131x_adapter *adapter);
-int et131x_rfd_resources_alloc(struct et131x_adapter *adapter,
-			       struct _MP_RFD *pMpRfd);
-void et131x_rfd_resources_free(struct et131x_adapter *adapter,
-			       struct _MP_RFD *pMpRfd);
-int et131x_init_recv(struct et131x_adapter *adapter);
-
-void ConfigRxDmaRegs(struct et131x_adapter *adapter);
-void SetRxDmaTimer(struct et131x_adapter *adapter);
-void et131x_rx_dma_disable(struct et131x_adapter *adapter);
-void et131x_rx_dma_enable(struct et131x_adapter *adapter);
-
-void et131x_reset_recv(struct et131x_adapter *adapter);
-
-void et131x_handle_recv_interrupt(struct et131x_adapter *adapter);
+};
 
 #endif /* __ET1310_RX_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_tx.c linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_tx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -84,15 +84,9 @@
 #include <linux/ioport.h>
 
 #include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-
 #include "et131x_adapter.h"
-#include "et131x_initpci.h"
-#include "et131x_isr.h"
-
 #include "et1310_tx.h"
-
+#include "et131x.h"
 
 static inline void et131x_free_send_packet(struct et131x_adapter *etdev,
 					   struct tcb *tcb);
@@ -200,7 +194,7 @@ void et131x_tx_dma_memory_free(struct et
  */
 void ConfigTxDmaRegs(struct et131x_adapter *etdev)
 {
-	struct _TXDMA_t __iomem *txdma = &etdev->regs->txdma;
+	struct txdma_regs __iomem *txdma = &etdev->regs->txdma;
 
 	/* Load the hardware with the start of the transmit descriptor ring. */
 	writel((u32) ((u64)etdev->tx_ring.tx_desc_ring_pa >> 32),
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_tx.h linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_tx.h
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et1310_tx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et1310_tx.h	2010-05-16 17:17:36.000000000 -0400
@@ -147,18 +147,4 @@ struct tx_ring {
 	int since_irq;
 };
 
-/* Forward declaration of the private adapter structure */
-struct et131x_adapter;
-
-/* PROTOTYPES for et1310_tx.c */
-int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter);
-void et131x_tx_dma_memory_free(struct et131x_adapter *adapter);
-void ConfigTxDmaRegs(struct et131x_adapter *adapter);
-void et131x_init_send(struct et131x_adapter *adapter);
-void et131x_tx_dma_disable(struct et131x_adapter *adapter);
-void et131x_tx_dma_enable(struct et131x_adapter *adapter);
-void et131x_handle_send_interrupt(struct et131x_adapter *adapter);
-void et131x_free_busy_send_packets(struct et131x_adapter *adapter);
-int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev);
-
 #endif /* __ET1310_TX_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_adapter.h linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_adapter.h
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_adapter.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_adapter.h	2010-05-16 17:17:36.000000000 -0400
@@ -77,38 +77,11 @@
  */
 #define NUM_TRAFFIC_CLASSES          1
 
-/*
- * There are three ways of counting errors - if there are more than X errors
- * in Y packets (represented by the "SAMPLE" macros), if there are more than
- * N errors in a S mSec time period (the "PERIOD" macros), or if there are
- * consecutive packets with errors (CONSEC_ERRORED_THRESH).  This last covers
- * for "Bursty" errors, and the errored packets may well not be contiguous,
- * but several errors where the packet counter has changed by less than a
- * small amount will cause this count to increment.
- */
-#define TX_PACKETS_IN_SAMPLE        10000
-#define TX_MAX_ERRORS_IN_SAMPLE     50
-
 #define TX_ERROR_PERIOD             1000
-#define TX_MAX_ERRORS_IN_PERIOD     10
-
-#define LINK_DETECTION_TIMER        5000
-
-#define TX_CONSEC_RANGE             5
-#define TX_CONSEC_ERRORED_THRESH    10
 
 #define LO_MARK_PERCENT_FOR_PSR     15
 #define LO_MARK_PERCENT_FOR_RX      15
 
-/* Counters for error rate monitoring */
-typedef struct _MP_ERR_COUNTERS {
-	u32 PktCountTxPackets;
-	u32 PktCountTxErrors;
-	u32 TimerBasedTxErrors;
-	u32 PktCountLastError;
-	u32 ErredConsecPackets;
-} MP_ERR_COUNTERS, *PMP_ERR_COUNTERS;
-
 /* RFD (Receive Frame Descriptor) */
 typedef struct _MP_RFD {
 	struct list_head list_node;
@@ -174,6 +147,20 @@ typedef struct _ce_stats_t {
 	u32 InterruptStatus;
 } CE_STATS_t, *PCE_STATS_t;
 
+typedef struct _MP_POWER_MGMT {
+	/* variable putting the phy into coma mode when boot up with no cable
+	 * plugged in after 5 seconds
+	 */
+	u8 TransPhyComaModeOnBoot;
+
+	/* Next two used to save power information at power down. This
+	 * information will be used during power up to set up parts of Power
+	 * Management in JAGCore
+	 */
+	u16 PowerDownSpeed;
+	u8 PowerDownDuplex;
+} MP_POWER_MGMT, *PMP_POWER_MGMT;
+
 /* The private adapter structure */
 struct et131x_adapter {
 	struct net_device *netdev;
@@ -248,7 +235,7 @@ struct et131x_adapter {
 	struct tx_ring tx_ring;
 
 	/* Rx Memory Variables */
-	RX_RING_t RxRing;
+	struct rx_ring rx_ring;
 
 	/* Loopback specifics */
 	u8 ReplicaPhyLoopbk;	/* Replica Enable */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_config.h linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_config.h
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_config.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_config.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,67 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *   http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et131x_config.h - Defines, structs, enums, prototypes, etc. to support
- *                   et131x_config.c
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software.  Using this
- * software indicates your acceptance of these terms and conditions.  If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- *    well as in the documentation and/or other materials provided with the
- *    distribution.
- *
- * . Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following Disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * . Neither the name of Agere Systems Inc. nor the names of the contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 __ET131X_CONFIG_H__
-#define __ET131X_CONFIG_H__
-
-/* Forward declaration of the private adapter structure */
-struct et131x_adapter;
-
-void et131x_config_parse(struct et131x_adapter *adapter);
-
-#endif /* __ET131X_CONFIG_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x.h linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x.h
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,153 @@
+/*
+ * Merged from files
+ *
+ * Copyright Â© 2005 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright Â© 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, 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 as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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.
+ *
+ */
+
+/* et131x_eeprom.c */
+int et131x_init_eeprom(struct et131x_adapter *etdev);
+
+/* et131x_initpci.c */
+void ConfigGlobalRegs(struct et131x_adapter *pAdapter);
+void ConfigMMCRegs(struct et131x_adapter *pAdapter);
+void et131x_enable_interrupts(struct et131x_adapter *adapter);
+void et131x_disable_interrupts(struct et131x_adapter *adapter);
+void et131x_align_allocated_memory(struct et131x_adapter *adapter,
+				   u64 *phys_addr,
+				   u64 *offset, u64 mask);
+
+int et131x_adapter_setup(struct et131x_adapter *adapter);
+int et131x_adapter_memory_alloc(struct et131x_adapter *adapter);
+void et131x_adapter_memory_free(struct et131x_adapter *adapter);
+void et131x_hwaddr_init(struct et131x_adapter *adapter);
+void et131x_soft_reset(struct et131x_adapter *adapter);
+
+/* et131x_isr.c */
+irqreturn_t et131x_isr(int irq, void *dev_id);
+void et131x_isr_handler(struct work_struct *work);
+
+/* et1310_mac.c */
+void ConfigMACRegs1(struct et131x_adapter *adapter);
+void ConfigMACRegs2(struct et131x_adapter *adapter);
+void ConfigRxMacRegs(struct et131x_adapter *adapter);
+void ConfigTxMacRegs(struct et131x_adapter *adapter);
+void ConfigMacStatRegs(struct et131x_adapter *adapter);
+void ConfigFlowControl(struct et131x_adapter *adapter);
+void UpdateMacStatHostCounters(struct et131x_adapter *adapter);
+void HandleMacStatInterrupt(struct et131x_adapter *adapter);
+void SetupDeviceForMulticast(struct et131x_adapter *adapter);
+void SetupDeviceForUnicast(struct et131x_adapter *adapter);
+
+/* et131x_netdev.c */
+struct net_device *et131x_device_alloc(void);
+
+/* et131x_pm.c */
+void EnablePhyComa(struct et131x_adapter *adapter);
+void DisablePhyComa(struct et131x_adapter *adapter);
+
+/* et131x_phy.c */
+void ET1310_PhyInit(struct et131x_adapter *adapter);
+void ET1310_PhyReset(struct et131x_adapter *adapter);
+void ET1310_PhyPowerDown(struct et131x_adapter *adapter, bool down);
+void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *adapter,
+				  u16 duplex);
+void ET1310_PhyAccessMiBit(struct et131x_adapter *adapter,
+			   u16 action,
+			   u16 regnum, u16 bitnum, u8 *value);
+
+int et131x_xcvr_find(struct et131x_adapter *adapter);
+void et131x_setphy_normal(struct et131x_adapter *adapter);
+
+/* static inline function does not work because et131x_adapter is not always
+ * defined
+ */
+int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr,
+	      u8 xcvrReg, u16 *value);
+#define MiRead(adapter, xcvrReg, value) \
+	PhyMiRead((adapter), (adapter)->Stats.xcvr_addr, (xcvrReg), (value))
+
+int32_t MiWrite(struct et131x_adapter *adapter,
+		u8 xcvReg, u16 value);
+void et131x_Mii_check(struct et131x_adapter *pAdapter,
+		      MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints);
+
+/* This last is not strictly required (the driver could call the TPAL
+ * version instead), but this sets the adapter up correctly, and calls the
+ * access routine indirectly.  This protects the driver from changes in TPAL.
+ */
+void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter);
+
+
+/* et1310_rx.c */
+int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter);
+void et131x_rx_dma_memory_free(struct et131x_adapter *adapter);
+int et131x_rfd_resources_alloc(struct et131x_adapter *adapter,
+			       struct _MP_RFD *pMpRfd);
+void et131x_rfd_resources_free(struct et131x_adapter *adapter,
+			       struct _MP_RFD *pMpRfd);
+int et131x_init_recv(struct et131x_adapter *adapter);
+
+void ConfigRxDmaRegs(struct et131x_adapter *adapter);
+void SetRxDmaTimer(struct et131x_adapter *adapter);
+void et131x_rx_dma_disable(struct et131x_adapter *adapter);
+void et131x_rx_dma_enable(struct et131x_adapter *adapter);
+
+void et131x_reset_recv(struct et131x_adapter *adapter);
+
+void et131x_handle_recv_interrupt(struct et131x_adapter *adapter);
+
+/* et131x_tx.c */
+int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter);
+void et131x_tx_dma_memory_free(struct et131x_adapter *adapter);
+void ConfigTxDmaRegs(struct et131x_adapter *adapter);
+void et131x_init_send(struct et131x_adapter *adapter);
+void et131x_tx_dma_disable(struct et131x_adapter *adapter);
+void et131x_tx_dma_enable(struct et131x_adapter *adapter);
+void et131x_handle_send_interrupt(struct et131x_adapter *adapter);
+void et131x_free_busy_send_packets(struct et131x_adapter *adapter);
+int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev);
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_initpci.c linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_initpci.c
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_initpci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_initpci.c	2010-05-16 17:17:36.000000000 -0400
@@ -68,7 +68,6 @@
 
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
@@ -87,20 +86,16 @@
 #include <linux/random.h>
 
 #include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
 
 #include "et131x_adapter.h"
-#include "et131x_netdev.h"
-#include "et131x_config.h"
-#include "et131x_isr.h"
 
 #include "et1310_address_map.h"
 #include "et1310_tx.h"
 #include "et1310_rx.h"
-#include "et1310_mac.h"
-#include "et1310_eeprom.h"
+#include "et131x.h"
 
+#define INTERNAL_MEM_SIZE       0x400	/* 1024 of internal memory */
+#define INTERNAL_MEM_RX_OFFSET  0x1FF	/* 50%   Tx, 50%   Rx */
 
 /* Defines for Parameter Default/Min/Max vaules */
 #define PARM_SPEED_DUPLEX_MIN   0
@@ -327,7 +322,7 @@ void et131x_link_detection_handler(unsig
  */
 void ConfigGlobalRegs(struct et131x_adapter *etdev)
 {
-	struct _GLOBAL_t __iomem *regs = &etdev->regs->global;
+	struct global_regs __iomem *regs = &etdev->regs->global;
 
 	writel(0, &regs->rxq_start_addr);
 	writel(INTERNAL_MEM_SIZE - 1, &regs->txq_end_addr);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_initpci.h linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_initpci.h
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_initpci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_initpci.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,73 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright Â© 2005 Agere Systems Inc.
- * All rights reserved.
- *   http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et131x_initpci.h - Header which includes common data and function prototypes
- *                    related to the driver's PCI (and PCI Express) information.
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software.  Using this
- * software indicates your acceptance of these terms and conditions.  If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright Â© 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- *    well as in the documentation and/or other materials provided with the
- *    distribution.
- *
- * . Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following Disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * . Neither the name of Agere Systems Inc. nor the names of the contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 __ET131X_INITPCI_H__
-#define __ET131X_INITPCI_H__
-
-/* Function Prototypes */
-void et131x_align_allocated_memory(struct et131x_adapter *adapter,
-				   u64 *phys_addr,
-				   u64 *offset, u64 mask);
-
-int et131x_adapter_setup(struct et131x_adapter *adapter);
-int et131x_adapter_memory_alloc(struct et131x_adapter *adapter);
-void et131x_adapter_memory_free(struct et131x_adapter *adapter);
-void et131x_hwaddr_init(struct et131x_adapter *adapter);
-void et131x_soft_reset(struct et131x_adapter *adapter);
-
-#endif /* __ET131X_INITPCI_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_isr.c linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_isr.c
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_isr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_isr.c	2010-05-16 17:17:36.000000000 -0400
@@ -66,7 +66,6 @@
 
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
@@ -85,11 +84,27 @@
 #include <linux/ioport.h>
 
 #include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-#include "et1310_mac.h"
-
 #include "et131x_adapter.h"
+#include "et131x.h"
+
+/*
+ * For interrupts, normal running is:
+ *       rxdma_xfr_done, phy_interrupt, mac_stat_interrupt,
+ *       watchdog_interrupt & txdma_xfer_done
+ *
+ * In both cases, when flow control is enabled for either Tx or bi-direction,
+ * we additional enable rx_fbr0_low and rx_fbr1_low, so we know when the
+ * buffer rings are running low.
+ */
+#define INT_MASK_DISABLE            0xffffffff
+
+/* NOTE: Masking out MAC_STAT Interrupt for now...
+ * #define INT_MASK_ENABLE             0xfff6bf17
+ * #define INT_MASK_ENABLE_NO_FLOW     0xfff6bfd7
+ */
+#define INT_MASK_ENABLE             0xfffebf17
+#define INT_MASK_ENABLE_NO_FLOW     0xfffebfd7
+
 
 /**
  *	et131x_enable_interrupts	-	enable interrupt
@@ -185,7 +200,7 @@ irqreturn_t et131x_isr(int irq, void *de
 			if (++tcb->stale > 1)
 				status |= ET_INTR_TXDMA_ISR;
 
-		if (adapter->RxRing.UnfinishedReceives)
+		if (adapter->rx_ring.UnfinishedReceives)
 			status |= ET_INTR_RXDMA_XFR_DONE;
 		else if (tcb == NULL)
 			writel(0, &adapter->regs->global.watchdog_timer);
@@ -390,7 +405,7 @@ void et131x_isr_handler(struct work_stru
 
 		/* Let's move on to the TxMac */
 		if (status & ET_INTR_TXMAC) {
-			u32 err = readl(&iomem->txmac.err.value);
+			u32 err = readl(&iomem->txmac.err);
 
 			/*
 			 * When any of the errors occur and TXMAC generates
@@ -425,12 +440,12 @@ void et131x_isr_handler(struct work_stru
 
 			dev_warn(&etdev->pdev->dev,
 			  "RXMAC interrupt, error 0x%08x.  Requesting reset\n",
-				    readl(&iomem->rxmac.err_reg.value));
+				    readl(&iomem->rxmac.err_reg));
 
 			dev_warn(&etdev->pdev->dev,
 				    "Enable 0x%08x, Diag 0x%08x\n",
-				    readl(&iomem->rxmac.ctrl.value),
-				    readl(&iomem->rxmac.rxq_diag.value));
+				    readl(&iomem->rxmac.ctrl),
+				    readl(&iomem->rxmac.rxq_diag));
 
 			/*
 			 * If we are debugging, we want to see this error,
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_isr.h linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_isr.h
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_isr.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_isr.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,65 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright Â© 2005 Agere Systems Inc.
- * All rights reserved.
- *   http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et131x_isr.h - Defines, structs, enums, prototypes, etc. pertaining to the
- *                ISR processing code.
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software.  Using this
- * software indicates your acceptance of these terms and conditions.  If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright Â© 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- *    well as in the documentation and/or other materials provided with the
- *    distribution.
- *
- * . Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following Disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * . Neither the name of Agere Systems Inc. nor the names of the contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 __ET131X_ISR_H__
-#define __ET131X_ISR_H__
-
-irqreturn_t et131x_isr(int irq, void *dev_id);
-void et131x_isr_handler(struct work_struct *work);
-
-#endif /* __ET131X_ISR_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_netdev.c linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_netdev.c
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_netdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_netdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,7 +65,6 @@
 
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
@@ -85,14 +84,9 @@
 #include <linux/ioport.h>
 
 #include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-#include "et1310_mac.h"
 #include "et1310_tx.h"
-
 #include "et131x_adapter.h"
-#include "et131x_isr.h"
-#include "et131x_initpci.h"
+#include "et131x.h"
 
 struct net_device_stats *et131x_stats(struct net_device *netdev);
 int et131x_open(struct net_device *netdev);
@@ -339,66 +333,64 @@ int et131x_ioctl(struct net_device *netd
  * et131x_set_packet_filter - Configures the Rx Packet filtering on the device
  * @adapter: pointer to our private adapter structure
  *
+ * FIXME: lot of dups with MAC code
+ *
  * Returns 0 on success, errno on failure
  */
 int et131x_set_packet_filter(struct et131x_adapter *adapter)
 {
 	int status = 0;
 	uint32_t filter = adapter->PacketFilter;
-	RXMAC_CTRL_t ctrl;
-	RXMAC_PF_CTRL_t pf_ctrl;
+	u32 ctrl;
+	u32 pf_ctrl;
 
-	ctrl.value = readl(&adapter->regs->rxmac.ctrl.value);
-	pf_ctrl.value = readl(&adapter->regs->rxmac.pf_ctrl.value);
+	ctrl = readl(&adapter->regs->rxmac.ctrl);
+	pf_ctrl = readl(&adapter->regs->rxmac.pf_ctrl);
 
 	/* Default to disabled packet filtering.  Enable it in the individual
 	 * case statements that require the device to filter something
 	 */
-	ctrl.bits.pkt_filter_disable = 1;
+	ctrl |= 0x04;
 
 	/* Set us to be in promiscuous mode so we receive everything, this
 	 * is also true when we get a packet filter of 0
 	 */
-	if ((filter & ET131X_PACKET_TYPE_PROMISCUOUS) || filter == 0) {
-		pf_ctrl.bits.filter_broad_en = 0;
-		pf_ctrl.bits.filter_multi_en = 0;
-		pf_ctrl.bits.filter_uni_en = 0;
-	} else {
+	if ((filter & ET131X_PACKET_TYPE_PROMISCUOUS) || filter == 0)
+		pf_ctrl &= ~7;	/* Clear filter bits */
+	else {
 		/*
 		 * Set us up with Multicast packet filtering.  Three cases are
 		 * possible - (1) we have a multi-cast list, (2) we receive ALL
 		 * multicast entries or (3) we receive none.
 		 */
-		if (filter & ET131X_PACKET_TYPE_ALL_MULTICAST) {
-			pf_ctrl.bits.filter_multi_en = 0;
-		} else {
+		if (filter & ET131X_PACKET_TYPE_ALL_MULTICAST)
+			pf_ctrl &= ~2;	/* Multicast filter bit */
+		else {
 			SetupDeviceForMulticast(adapter);
-			pf_ctrl.bits.filter_multi_en = 1;
-			ctrl.bits.pkt_filter_disable = 0;
+			pf_ctrl |= 2;
+			ctrl &= ~0x04;
 		}
 
 		/* Set us up with Unicast packet filtering */
 		if (filter & ET131X_PACKET_TYPE_DIRECTED) {
 			SetupDeviceForUnicast(adapter);
-			pf_ctrl.bits.filter_uni_en = 1;
-			ctrl.bits.pkt_filter_disable = 0;
+			pf_ctrl |= 4;
+			ctrl &= ~0x04;
 		}
 
 		/* Set us up with Broadcast packet filtering */
 		if (filter & ET131X_PACKET_TYPE_BROADCAST) {
-			pf_ctrl.bits.filter_broad_en = 1;
-			ctrl.bits.pkt_filter_disable = 0;
-		} else {
-			pf_ctrl.bits.filter_broad_en = 0;
-		}
+			pf_ctrl |= 1;	/* Broadcast filter bit */
+			ctrl &= ~0x04;
+		} else
+			pf_ctrl &= ~1;
 
 		/* Setup the receive mac configuration registers - Packet
 		 * Filter control + the enable / disable for packet filter
 		 * in the control reg.
 		 */
-		writel(pf_ctrl.value,
-		       &adapter->regs->rxmac.pf_ctrl.value);
-		writel(ctrl.value, &adapter->regs->rxmac.ctrl.value);
+		writel(pf_ctrl, &adapter->regs->rxmac.pf_ctrl);
+		writel(ctrl, &adapter->regs->rxmac.ctrl);
 	}
 	return status;
 }
@@ -411,9 +403,9 @@ void et131x_multicast(struct net_device
 {
 	struct et131x_adapter *adapter = netdev_priv(netdev);
 	uint32_t PacketFilter = 0;
-	uint32_t count;
 	unsigned long flags;
-	struct dev_mc_list *mclist = netdev->mc_list;
+	struct dev_mc_list *mclist;
+	int i;
 
 	spin_lock_irqsave(&adapter->Lock, flags);
 
@@ -444,11 +436,11 @@ void et131x_multicast(struct net_device
 		adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST;
 	}
 
-	if (netdev->mc_count > NIC_MAX_MCAST_LIST) {
+	if (netdev_mc_count(netdev) > NIC_MAX_MCAST_LIST) {
 		adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST;
 	}
 
-	if (netdev->mc_count < 1) {
+	if (netdev_mc_count(netdev) < 1) {
 		adapter->PacketFilter &= ~ET131X_PACKET_TYPE_ALL_MULTICAST;
 		adapter->PacketFilter &= ~ET131X_PACKET_TYPE_MULTICAST;
 	} else {
@@ -456,12 +448,13 @@ void et131x_multicast(struct net_device
 	}
 
 	/* Set values in the private adapter struct */
-	adapter->MCAddressCount = netdev->mc_count;
-
-	if (netdev->mc_count) {
-		count = netdev->mc_count - 1;
-		memcpy(adapter->MCList[count], mclist->dmi_addr, ETH_ALEN);
+	i = 0;
+	netdev_for_each_mc_addr(mclist, netdev) {
+		if (i == NIC_MAX_MCAST_LIST)
+			break;
+		memcpy(adapter->MCList[i++], mclist->dmi_addr, ETH_ALEN);
 	}
+	adapter->MCAddressCount = i;
 
 	/* Are the new flags different from the previous ones? If not, then no
 	 * action is required
@@ -674,12 +667,8 @@ int et131x_set_mac_addr(struct net_devic
 
 	memcpy(netdev->dev_addr, address->sa_data, netdev->addr_len);
 
-	printk(KERN_INFO
-		"%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n",
-			netdev->name,
-			netdev->dev_addr[0], netdev->dev_addr[1],
-			netdev->dev_addr[2], netdev->dev_addr[3],
-			netdev->dev_addr[4], netdev->dev_addr[5]);
+	printk(KERN_INFO "%s: Setting MAC address to %pM\n",
+			netdev->name, netdev->dev_addr);
 
 	/* Free Rx DMA memory */
 	et131x_adapter_memory_free(adapter);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_netdev.h linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_netdev.h
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_netdev.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_netdev.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,64 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright Â© 2005 Agere Systems Inc.
- * All rights reserved.
- *   http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et131x_netdev.h - Defines, structs, enums, prototypes, etc. related to the
- *                   driver's net_device support.
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software.  Using this
- * software indicates your acceptance of these terms and conditions.  If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright Â© 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- *    well as in the documentation and/or other materials provided with the
- *    distribution.
- *
- * . Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following Disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * . Neither the name of Agere Systems Inc. nor the names of the contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 __ET131X_NETDEV_H__
-#define __ET131X_NETDEV_H__
-
-struct net_device *et131x_device_alloc(void);
-
-#endif /* __ET131X_NETDEV_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_version.h linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_version.h
--- linux-libre-2.6.33-gnu1/drivers/staging/et131x/et131x_version.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/et131x/et131x_version.h	2010-05-16 17:17:36.000000000 -0400
@@ -62,20 +62,13 @@
 #define DRIVER_LICENSE		"Dual BSD/GPL"
 #define DRIVER_DEVICE_STRING	"ET1310"
 #define DRIVER_NAME		"et131x"
-#define DRIVER_MAJOR_VERSION	1
-#define DRIVER_MINOR_VERSION	2
-#define DRIVER_PATCH_VERSION	3
-#define DRIVER_VERSION_STRING	"1.2.3"
+#define DRIVER_VERSION_STRING	"1.2.3-lk"
 #define DRIVER_VENDOR		"Agere Systems, http://www.agere.com"
 #define DRIVER_DESC		"10/100/1000 Base-T Ethernet Driver"
 
-#define STRUCT_MODULE		"net"	/* blux: missed by the kernel */
-
 #define DRIVER_INFO		DRIVER_DESC " for the "\
 				DRIVER_DEVICE_STRING ", v" \
 				DRIVER_VERSION_STRING " by " \
 				DRIVER_VENDOR
 
-#define DRIVER_NAME_EXT		"et131x.ko"
-
 #endif /* __ET131X_VERSION_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/frontier/alphatrack.c linux-libre-2.6.34-gnu1/drivers/staging/frontier/alphatrack.c
--- linux-libre-2.6.33-gnu1/drivers/staging/frontier/alphatrack.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/frontier/alphatrack.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,7 +58,7 @@
 #endif
 
 /* table of devices that work with this driver */
-static struct usb_device_id usb_alphatrack_table[] = {
+static const struct usb_device_id usb_alphatrack_table[] = {
 	{USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
 	{}			/* Terminating entry */
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/frontier/tranzport.c linux-libre-2.6.34-gnu1/drivers/staging/frontier/tranzport.c
--- linux-libre-2.6.33-gnu1/drivers/staging/frontier/tranzport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/frontier/tranzport.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,7 +55,7 @@
 #endif
 
 /* table of devices that work with this driver */
-static struct usb_device_id usb_tranzport_table[] = {
+static const struct usb_device_id usb_tranzport_table[] = {
 	{USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
 	{}			/* Terminating entry */
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/go7007/go7007-driver.c linux-libre-2.6.34-gnu1/drivers/staging/go7007/go7007-driver.c
--- linux-libre-2.6.33-gnu1/drivers/staging/go7007/go7007-driver.c	2013-05-03 12:07:14.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/go7007/go7007-driver.c	2013-05-03 09:46:35.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/firmware.h>
 #include <linux/mutex.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <linux/videodev2.h>
 #include <media/tuner.h>
@@ -128,6 +129,8 @@ static int go7007_load_encoder(struct go
 	return rv;
 }
 
+/*(DEBLOBBED)*/
+
 /*
  * Boot the encoder and register the I2C adapter if requested.  Do the
  * minimum initialization necessary, since the board-specific code may
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/go7007/go7007-fw.c linux-libre-2.6.34-gnu1/drivers/staging/go7007/go7007-fw.c
--- linux-libre-2.6.33-gnu1/drivers/staging/go7007/go7007-fw.c	2013-05-03 12:07:14.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/go7007/go7007-fw.c	2013-05-03 09:46:35.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/device.h>
 #include <linux/i2c.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 
 #include "go7007-priv.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/go7007/go7007-usb.c linux-libre-2.6.34-gnu1/drivers/staging/go7007/go7007-usb.c
--- linux-libre-2.6.33-gnu1/drivers/staging/go7007/go7007-usb.c	2013-05-03 12:07:16.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/go7007/go7007-usb.c	2013-05-03 09:46:37.000000000 -0400
@@ -444,7 +444,9 @@ static struct go7007_usb_board board_sen
 	},
 };
 
-static struct usb_device_id go7007_usb_id_table[] = {
+/*(DEBLOBBED)*/
+
+static const struct usb_device_id go7007_usb_id_table[] = {
 	{
 		.match_flags	= USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
 					USB_DEVICE_ID_MATCH_INT_INFO,
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/go7007/go7007-v4l2.c linux-libre-2.6.34-gnu1/drivers/staging/go7007/go7007-v4l2.c
--- linux-libre-2.6.33-gnu1/drivers/staging/go7007/go7007-v4l2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/go7007/go7007-v4l2.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/unistd.h>
 #include <linux/time.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/go7007/s2250-board.c linux-libre-2.6.34-gnu1/drivers/staging/go7007/s2250-board.c
--- linux-libre-2.6.33-gnu1/drivers/staging/go7007/s2250-board.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/go7007/s2250-board.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/usb.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-i2c-drv.h>
@@ -159,7 +160,7 @@ static int write_reg(struct i2c_client *
 	struct go7007 *go = i2c_get_adapdata(client->adapter);
 	struct go7007_usb *usb;
 	int rc;
-	int dev_addr = client->addr;
+	int dev_addr = client->addr << 1;  /* firmware wants 8-bit address */
 	u8 *buf;
 
 	if (go == NULL)
@@ -667,7 +668,7 @@ static int s2250_remove(struct i2c_clien
 	return 0;
 }
 
-static struct i2c_device_id s2250_id[] = {
+static const struct i2c_device_id s2250_id[] = {
 	{ "s2250", 0 },
 	{ }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/go7007/s2250-loader.c linux-libre-2.6.34-gnu1/drivers/staging/go7007/s2250-loader.c
--- linux-libre-2.6.33-gnu1/drivers/staging/go7007/s2250-loader.c	2013-05-03 12:07:21.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/go7007/s2250-loader.c	2013-05-03 09:46:41.000000000 -0400
@@ -17,6 +17,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/usb.h>
 #include <dvb-usb.h>
@@ -139,7 +140,7 @@ failed2:
 
 static void s2250loader_disconnect(struct usb_interface *interface)
 {
-	pdevice_extension_t s = usb_get_intfdata(interface);
+	pdevice_extension_t s;
 	printk(KERN_INFO "s2250: disconnect\n");
 	lock_kernel();
 	s = usb_get_intfdata(interface);
@@ -148,7 +149,7 @@ static void s2250loader_disconnect(struc
 	unlock_kernel();
 }
 
-static struct usb_device_id s2250loader_ids[] = {
+static const struct usb_device_id s2250loader_ids[] = {
 	{USB_DEVICE(0x1943, 0xa250)},
 	{}                          /* Terminating entry */
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/go7007/saa7134-go7007.c linux-libre-2.6.34-gnu1/drivers/staging/go7007/saa7134-go7007.c
--- linux-libre-2.6.33-gnu1/drivers/staging/go7007/saa7134-go7007.c	2013-05-03 12:07:19.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/go7007/saa7134-go7007.c	2013-05-03 09:46:39.000000000 -0400
@@ -84,6 +84,7 @@ static struct go7007_board_info board_vo
 		},
 	},
 };
+/*(DEBLOBBED)*/
 
 /********************* Driver for GPIO HPI interface *********************/
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/go7007/snd-go7007.c linux-libre-2.6.34-gnu1/drivers/staging/go7007/snd-go7007.c
--- linux-libre-2.6.33-gnu1/drivers/staging/go7007/snd-go7007.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/go7007/snd-go7007.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/i2c.h>
 #include <linux/mutex.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/go7007/wis-ov7640.c linux-libre-2.6.34-gnu1/drivers/staging/go7007/wis-ov7640.c
--- linux-libre-2.6.33-gnu1/drivers/staging/go7007/wis-ov7640.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/go7007/wis-ov7640.c	2010-05-16 17:17:36.000000000 -0400
@@ -77,7 +77,7 @@ static int wis_ov7640_remove(struct i2c_
 	return 0;
 }
 
-static struct i2c_device_id wis_ov7640_id[] = {
+static const struct i2c_device_id wis_ov7640_id[] = {
 	{ "wis_ov7640", 0 },
 	{ }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/go7007/wis-saa7113.c linux-libre-2.6.34-gnu1/drivers/staging/go7007/wis-saa7113.c
--- linux-libre-2.6.33-gnu1/drivers/staging/go7007/wis-saa7113.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/go7007/wis-saa7113.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 
 #include "wis-i2c.h"
 
@@ -304,7 +305,7 @@ static int wis_saa7113_remove(struct i2c
 	return 0;
 }
 
-static struct i2c_device_id wis_saa7113_id[] = {
+static const struct i2c_device_id wis_saa7113_id[] = {
 	{ "wis_saa7113", 0 },
 	{ }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/go7007/wis-saa7115.c linux-libre-2.6.34-gnu1/drivers/staging/go7007/wis-saa7115.c
--- linux-libre-2.6.33-gnu1/drivers/staging/go7007/wis-saa7115.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/go7007/wis-saa7115.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 
 #include "wis-i2c.h"
 
@@ -437,7 +438,7 @@ static int wis_saa7115_remove(struct i2c
 	return 0;
 }
 
-static struct i2c_device_id wis_saa7115_id[] = {
+static const struct i2c_device_id wis_saa7115_id[] = {
 	{ "wis_saa7115", 0 },
 	{ }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/go7007/wis-sony-tuner.c linux-libre-2.6.34-gnu1/drivers/staging/go7007/wis-sony-tuner.c
--- linux-libre-2.6.33-gnu1/drivers/staging/go7007/wis-sony-tuner.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/go7007/wis-sony-tuner.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/tuner.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
@@ -688,7 +689,7 @@ static int wis_sony_tuner_remove(struct
 	return 0;
 }
 
-static struct i2c_device_id wis_sony_tuner_id[] = {
+static const struct i2c_device_id wis_sony_tuner_id[] = {
 	{ "wis_sony_tuner", 0 },
 	{ }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/go7007/wis-tw2804.c linux-libre-2.6.34-gnu1/drivers/staging/go7007/wis-tw2804.c
--- linux-libre-2.6.33-gnu1/drivers/staging/go7007/wis-tw2804.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/go7007/wis-tw2804.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 
 #include "wis-i2c.h"
 
@@ -327,7 +328,7 @@ static int wis_tw2804_remove(struct i2c_
 	return 0;
 }
 
-static struct i2c_device_id wis_tw2804_id[] = {
+static const struct i2c_device_id wis_tw2804_id[] = {
 	{ "wis_tw2804", 0 },
 	{ }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/go7007/wis-tw9903.c linux-libre-2.6.34-gnu1/drivers/staging/go7007/wis-tw9903.c
--- linux-libre-2.6.33-gnu1/drivers/staging/go7007/wis-tw9903.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/go7007/wis-tw9903.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 
 #include "wis-i2c.h"
 
@@ -309,7 +310,7 @@ static int wis_tw9903_remove(struct i2c_
 	return 0;
 }
 
-static struct i2c_device_id wis_tw9903_id[] = {
+static const struct i2c_device_id wis_tw9903_id[] = {
 	{ "wis_tw9903", 0 },
 	{ }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/go7007/wis-uda1342.c linux-libre-2.6.34-gnu1/drivers/staging/go7007/wis-uda1342.c
--- linux-libre-2.6.33-gnu1/drivers/staging/go7007/wis-uda1342.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/go7007/wis-uda1342.c	2010-05-16 17:17:36.000000000 -0400
@@ -82,7 +82,7 @@ static int wis_uda1342_remove(struct i2c
 	return 0;
 }
 
-static struct i2c_device_id wis_uda1342_id[] = {
+static const struct i2c_device_id wis_uda1342_id[] = {
 	{ "wis_uda1342", 0 },
 	{ }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/blkvsc_drv.c linux-libre-2.6.34-gnu1/drivers/staging/hv/blkvsc_drv.c
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/blkvsc_drv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/blkvsc_drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,12 +25,14 @@
 #include <linux/major.h>
 #include <linux/delay.h>
 #include <linux/hdreg.h>
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_dbg.h>
 #include "osd.h"
 #include "logging.h"
+#include "VersionInfo.h"
 #include "vmbus.h"
 #include "StorVscApi.h"
 
@@ -92,7 +94,7 @@ struct blkvsc_request {
 /* Per device structure */
 struct block_device_context {
 	/* point back to our device context */
-	struct device_context *device_ctx;
+	struct vm_device *device_ctx;
 	struct kmem_cache *request_pool;
 	spinlock_t lock;
 	struct gendisk *gd;
@@ -254,7 +256,7 @@ static int blkvsc_probe(struct device *d
 				(struct blkvsc_driver_context *)driver_ctx;
 	struct storvsc_driver_object *storvsc_drv_obj =
 				&blkvsc_drv_ctx->drv_obj;
-	struct device_context *device_ctx = device_to_device_context(device);
+	struct vm_device *device_ctx = device_to_vm_device(device);
 	struct hv_device *device_obj = &device_ctx->device_obj;
 
 	struct block_device_context *blkdev = NULL;
@@ -363,10 +365,7 @@ static int blkvsc_probe(struct device *d
 	blkdev->gd->queue = blk_init_queue(blkvsc_request, &blkdev->lock);
 
 	blk_queue_max_segment_size(blkdev->gd->queue, PAGE_SIZE);
-	blk_queue_max_phys_segments(blkdev->gd->queue,
-				    MAX_MULTIPAGE_BUFFER_COUNT);
-	blk_queue_max_hw_segments(blkdev->gd->queue,
-				  MAX_MULTIPAGE_BUFFER_COUNT);
+	blk_queue_max_segments(blkdev->gd->queue, MAX_MULTIPAGE_BUFFER_COUNT);
 	blk_queue_segment_boundary(blkdev->gd->queue, PAGE_SIZE-1);
 	blk_queue_bounce_limit(blkdev->gd->queue, BLK_BOUNCE_ANY);
 	blk_queue_dma_alignment(blkdev->gd->queue, 511);
@@ -745,7 +744,7 @@ static int blkvsc_remove(struct device *
 				(struct blkvsc_driver_context *)driver_ctx;
 	struct storvsc_driver_object *storvsc_drv_obj =
 				&blkvsc_drv_ctx->drv_obj;
-	struct device_context *device_ctx = device_to_device_context(device);
+	struct vm_device *device_ctx = device_to_vm_device(device);
 	struct hv_device *device_obj = &device_ctx->device_obj;
 	struct block_device_context *blkdev = dev_get_drvdata(device);
 	unsigned long flags;
@@ -865,7 +864,7 @@ static int blkvsc_submit_request(struct
 			void (*request_completion)(struct hv_storvsc_request *))
 {
 	struct block_device_context *blkdev = blkvsc_req->dev;
-	struct device_context *device_ctx = blkdev->device_ctx;
+	struct vm_device *device_ctx = blkdev->device_ctx;
 	struct driver_context *driver_ctx =
 			driver_to_driver_context(device_ctx->device.driver);
 	struct blkvsc_driver_context *blkvsc_drv_ctx =
@@ -1507,6 +1506,7 @@ static void __exit blkvsc_exit(void)
 }
 
 MODULE_LICENSE("GPL");
+MODULE_VERSION(HV_DRV_VERSION);
 module_param(blkvsc_ringbuffer_size, int, S_IRUGO);
 module_init(blkvsc_init);
 module_exit(blkvsc_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/Channel.c linux-libre-2.6.34-gnu1/drivers/staging/hv/Channel.c
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/Channel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/Channel.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include "osd.h"
 #include "logging.h"
 #include "VmbusPrivate.h"
@@ -991,9 +992,8 @@ void VmbusChannelOnTimer(unsigned long d
 {
 	struct vmbus_channel *channel = (struct vmbus_channel *)data;
 
-	if (channel->OnChannelCallback) {
+	if (channel->OnChannelCallback)
 		channel->OnChannelCallback(channel->ChannelCallbackContext);
-	}
 }
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/ChannelMgmt.c linux-libre-2.6.34-gnu1/drivers/staging/hv/ChannelMgmt.c
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/ChannelMgmt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/ChannelMgmt.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include "osd.h"
 #include "logging.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/Connection.c linux-libre-2.6.34-gnu1/drivers/staging/hv/Connection.c
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/Connection.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/Connection.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include "osd.h"
 #include "logging.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/Hv.c linux-libre-2.6.34-gnu1/drivers/staging/hv/Hv.c
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/Hv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/Hv.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include "osd.h"
 #include "logging.h"
@@ -208,50 +209,51 @@ int HvInit(void)
 	/* HvQueryHypervisorFeatures(maxLeaf); */
 
 	/*
-	 * Determine if we are running on xenlinux (ie x2v shim) or native
-	 * linux
+	 * We only support running on top of Hyper-V
 	 */
 	rdmsrl(HV_X64_MSR_GUEST_OS_ID, gHvContext.GuestId);
-	if (gHvContext.GuestId == 0) {
-		/* Write our OS info */
-		wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID);
-		gHvContext.GuestId = HV_LINUX_GUEST_ID;
+
+	if (gHvContext.GuestId != 0) {
+		DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!",
+				gHvContext.GuestId);
+		goto Cleanup;
 	}
 
+	/* Write our OS info */
+	wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID);
+	gHvContext.GuestId = HV_LINUX_GUEST_ID;
+
 	/* See if the hypercall page is already set */
 	rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
-	if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
-		/* Allocate the hypercall page memory */
-		/* virtAddr = osd_PageAlloc(1); */
-		virtAddr = osd_VirtualAllocExec(PAGE_SIZE);
 
-		if (!virtAddr) {
-			DPRINT_ERR(VMBUS,
-				   "unable to allocate hypercall page!!");
-			goto Cleanup;
-		}
+	/*
+	* Allocate the hypercall page memory
+	* virtAddr = osd_PageAlloc(1);
+	*/
+	virtAddr = osd_VirtualAllocExec(PAGE_SIZE);
 
-		hypercallMsr.Enable = 1;
-		/* hypercallMsr.GuestPhysicalAddress =
-		 * 		virt_to_phys(virtAddr) >> PAGE_SHIFT; */
-		hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr);
-		wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+	if (!virtAddr) {
+		DPRINT_ERR(VMBUS,
+			   "unable to allocate hypercall page!!");
+		goto Cleanup;
+	}
 
-		/* Confirm that hypercall page did get setup. */
-		hypercallMsr.AsUINT64 = 0;
-		rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
-		if (!hypercallMsr.Enable) {
-			DPRINT_ERR(VMBUS, "unable to set hypercall page!!");
-			goto Cleanup;
-		}
+	hypercallMsr.Enable = 1;
 
-		gHvContext.HypercallPage = virtAddr;
-	} else {
-		DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!",
-				gHvContext.GuestId);
+	hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr);
+	wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+
+	/* Confirm that hypercall page did get setup. */
+	hypercallMsr.AsUINT64 = 0;
+	rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+
+	if (!hypercallMsr.Enable) {
+		DPRINT_ERR(VMBUS, "unable to set hypercall page!!");
 		goto Cleanup;
 	}
 
+	gHvContext.HypercallPage = virtAddr;
+
 	DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx",
 		    gHvContext.HypercallPage,
 		    (u64)hypercallMsr.GuestPhysicalAddress << PAGE_SHIFT);
@@ -273,8 +275,6 @@ int HvInit(void)
 	gHvContext.SignalEventParam->FlagNumber = 0;
 	gHvContext.SignalEventParam->RsvdZ = 0;
 
-	/* DPRINT_DBG(VMBUS, "My id %llu", HvGetCurrentPartitionId()); */
-
 	DPRINT_EXIT(VMBUS);
 
 	return ret;
@@ -306,22 +306,19 @@ void HvCleanup(void)
 	DPRINT_ENTER(VMBUS);
 
 	if (gHvContext.SignalEventBuffer) {
+		kfree(gHvContext.SignalEventBuffer);
 		gHvContext.SignalEventBuffer = NULL;
 		gHvContext.SignalEventParam = NULL;
-		kfree(gHvContext.SignalEventBuffer);
 	}
 
-	if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
-		if (gHvContext.HypercallPage) {
-			hypercallMsr.AsUINT64 = 0;
-			wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
-			vfree(gHvContext.HypercallPage);
-			gHvContext.HypercallPage = NULL;
-		}
+	if (gHvContext.HypercallPage) {
+		hypercallMsr.AsUINT64 = 0;
+		wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+		vfree(gHvContext.HypercallPage);
+		gHvContext.HypercallPage = NULL;
 	}
 
 	DPRINT_EXIT(VMBUS);
-
 }
 
 /**
@@ -393,7 +390,7 @@ void HvSynicInit(void *irqarg)
 	union hv_synic_siefp siefp;
 	union hv_synic_sint sharedSint;
 	union hv_synic_scontrol sctrl;
-	u64 guestID;
+
 	u32 irqVector = *((u32 *)(irqarg));
 	int cpu = smp_processor_id();
 
@@ -409,71 +406,41 @@ void HvSynicInit(void *irqarg)
 
 	DPRINT_INFO(VMBUS, "SynIC version: %llx", version);
 
-	/* TODO: Handle SMP */
-	if (gHvContext.GuestId == HV_XENLINUX_GUEST_ID) {
-		DPRINT_INFO(VMBUS, "Skipping SIMP and SIEFP setup since "
-				"it is already set.");
-
-		rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
-		rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+	gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
 
-		DPRINT_DBG(VMBUS, "Simp: %llx, Sifep: %llx",
-			   simp.AsUINT64, siefp.AsUINT64);
+	if (gHvContext.synICMessagePage[cpu] == NULL) {
+		DPRINT_ERR(VMBUS,
+			   "unable to allocate SYNIC message page!!");
+		goto Cleanup;
+	}
 
-		/*
-		 * Determine if we are running on xenlinux (ie x2v shim) or
-		 * native linux
-		 */
-		rdmsrl(HV_X64_MSR_GUEST_OS_ID, guestID);
-		if (guestID == HV_LINUX_GUEST_ID) {
-			gHvContext.synICMessagePage[cpu] =
-				phys_to_virt(simp.BaseSimpGpa << PAGE_SHIFT);
-			gHvContext.synICEventPage[cpu] =
-				phys_to_virt(siefp.BaseSiefpGpa << PAGE_SHIFT);
-		} else {
-			DPRINT_ERR(VMBUS, "unknown guest id!!");
-			goto Cleanup;
-		}
-		DPRINT_DBG(VMBUS, "MAPPED: Simp: %p, Sifep: %p",
-			   gHvContext.synICMessagePage[cpu],
-			   gHvContext.synICEventPage[cpu]);
-	} else {
-		gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
-		if (gHvContext.synICMessagePage[cpu] == NULL) {
-			DPRINT_ERR(VMBUS,
-				   "unable to allocate SYNIC message page!!");
-			goto Cleanup;
-		}
+	gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
 
-		gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
-		if (gHvContext.synICEventPage[cpu] == NULL) {
-			DPRINT_ERR(VMBUS,
-				   "unable to allocate SYNIC event page!!");
-			goto Cleanup;
-		}
+	if (gHvContext.synICEventPage[cpu] == NULL) {
+		DPRINT_ERR(VMBUS,
+			   "unable to allocate SYNIC event page!!");
+		goto Cleanup;
+	}
 
-		/* Setup the Synic's message page */
-		rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
-		simp.SimpEnabled = 1;
-		simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[cpu])
-					>> PAGE_SHIFT;
+	/* Setup the Synic's message page */
+	rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+	simp.SimpEnabled = 1;
+	simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[cpu])
+		>> PAGE_SHIFT;
 
-		DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx",
-				simp.AsUINT64);
+	DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.AsUINT64);
 
-		wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+	wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
 
-		/* Setup the Synic's event page */
-		rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
-		siefp.SiefpEnabled = 1;
-		siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[cpu])
-					>> PAGE_SHIFT;
+	/* Setup the Synic's event page */
+	rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+	siefp.SiefpEnabled = 1;
+	siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[cpu])
+		>> PAGE_SHIFT;
 
-		DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx",
-				siefp.AsUINT64);
+	DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.AsUINT64);
 
-		wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
-	}
+	wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
 
 	/* Setup the interception SINT. */
 	/* wrmsrl((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX), */
@@ -505,13 +472,11 @@ void HvSynicInit(void *irqarg)
 	return;
 
 Cleanup:
-	if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
-		if (gHvContext.synICEventPage[cpu])
-			osd_PageFree(gHvContext.synICEventPage[cpu], 1);
+	if (gHvContext.synICEventPage[cpu])
+		osd_PageFree(gHvContext.synICEventPage[cpu], 1);
 
-		if (gHvContext.synICMessagePage[cpu])
-			osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
-	}
+	if (gHvContext.synICMessagePage[cpu])
+		osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
 
 	DPRINT_EXIT(VMBUS);
 	return;
@@ -542,27 +507,20 @@ void HvSynicCleanup(void *arg)
 	/* Disable the interrupt */
 	wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
 
-	/*
-	 * Disable and free the resources only if we are running as
-	 * native linux since in xenlinux, we are sharing the
-	 * resources with the x2v shim
-	 */
-	if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
-		rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
-		simp.SimpEnabled = 0;
-		simp.BaseSimpGpa = 0;
+	rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+	simp.SimpEnabled = 0;
+	simp.BaseSimpGpa = 0;
 
-		wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+	wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
 
-		rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
-		siefp.SiefpEnabled = 0;
-		siefp.BaseSiefpGpa = 0;
+	rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+	siefp.SiefpEnabled = 0;
+	siefp.BaseSiefpGpa = 0;
 
-		wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+	wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
 
-		osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
-		osd_PageFree(gHvContext.synICEventPage[cpu], 1);
-	}
+	osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
+	osd_PageFree(gHvContext.synICEventPage[cpu], 1);
 
 	DPRINT_EXIT(VMBUS);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/Hv.h linux-libre-2.6.34-gnu1/drivers/staging/hv/Hv.h
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/Hv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/Hv.h	2010-05-16 17:17:36.000000000 -0400
@@ -41,11 +41,6 @@ enum {
 
 #define HV_PRESENT_BIT			0x80000000
 
-#define HV_XENLINUX_GUEST_ID_LO		0x00000000
-#define HV_XENLINUX_GUEST_ID_HI		0x0B00B135
-#define HV_XENLINUX_GUEST_ID		(((u64)HV_XENLINUX_GUEST_ID_HI << 32) \
-					  | HV_XENLINUX_GUEST_ID_LO)
-
 #define HV_LINUX_GUEST_ID_LO		0x00000000
 #define HV_LINUX_GUEST_ID_HI		0xB16B00B5
 #define HV_LINUX_GUEST_ID		(((u64)HV_LINUX_GUEST_ID_HI << 32) | \
@@ -102,8 +97,9 @@ struct hv_input_signal_event_buffer {
 };
 
 struct hv_context {
-	/* XenLinux or native Linux. If XenLinux, the hypercall and synic pages
-	 * has already been initialized */
+	/* We only support running on top of Hyper-V
+	* So at this point this really can only contain the Hyper-V ID
+	*/
 	u64 GuestId;
 
 	void *HypercallPage;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/NetVscApi.h linux-libre-2.6.34-gnu1/drivers/staging/hv/NetVscApi.h
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/NetVscApi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/NetVscApi.h	2010-05-16 17:17:36.000000000 -0400
@@ -105,8 +105,6 @@ struct netvsc_driver {
 	void (*OnLinkStatusChanged)(struct hv_device *dev, u32 Status);
 
 	/* Specific to this driver */
-	int (*OnOpen)(struct hv_device *dev);
-	int (*OnClose)(struct hv_device *dev);
 	int (*OnSend)(struct hv_device *dev, struct hv_netvsc_packet *packet);
 
 	void *Context;
@@ -119,5 +117,7 @@ struct netvsc_device_info {
 
 /* Interface */
 int NetVscInitialize(struct hv_driver *drv);
+int RndisFilterOnOpen(struct hv_device *Device);
+int RndisFilterOnClose(struct hv_device *Device);
 
 #endif /* _NETVSC_API_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/NetVsc.c linux-libre-2.6.34-gnu1/drivers/staging/hv/NetVsc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/NetVsc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/NetVsc.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include "osd.h"
 #include "logging.h"
 #include "NetVsc.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/netvsc_drv.c linux-libre-2.6.34-gnu1/drivers/staging/hv/netvsc_drv.c
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/netvsc_drv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/netvsc_drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,20 +29,20 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/in.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 #include <net/route.h>
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 #include "osd.h"
 #include "logging.h"
+#include "VersionInfo.h"
 #include "vmbus.h"
 #include "NetVscApi.h"
 
-MODULE_LICENSE("GPL");
-
 struct net_device_context {
 	/* point back to our device context */
-	struct device_context *device_ctx;
+	struct vm_device *device_ctx;
 	struct net_device_stats stats;
 };
 
@@ -72,11 +72,6 @@ static void netvsc_set_multicast_list(st
 static int netvsc_open(struct net_device *net)
 {
 	struct net_device_context *net_device_ctx = netdev_priv(net);
-	struct driver_context *driver_ctx =
-	    driver_to_driver_context(net_device_ctx->device_ctx->device.driver);
-	struct netvsc_driver_context *net_drv_ctx =
-		(struct netvsc_driver_context *)driver_ctx;
-	struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
 	struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj;
 	int ret = 0;
 
@@ -87,7 +82,7 @@ static int netvsc_open(struct net_device
 		       sizeof(struct net_device_stats));
 
 		/* Open up the device */
-		ret = net_drv_obj->OnOpen(device_obj);
+		ret = RndisFilterOnOpen(device_obj);
 		if (ret != 0) {
 			DPRINT_ERR(NETVSC_DRV,
 				   "unable to open device (ret %d).", ret);
@@ -106,11 +101,6 @@ static int netvsc_open(struct net_device
 static int netvsc_close(struct net_device *net)
 {
 	struct net_device_context *net_device_ctx = netdev_priv(net);
-	struct driver_context *driver_ctx =
-	    driver_to_driver_context(net_device_ctx->device_ctx->device.driver);
-	struct netvsc_driver_context *net_drv_ctx =
-		(struct netvsc_driver_context *)driver_ctx;
-	struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
 	struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj;
 	int ret;
 
@@ -118,7 +108,7 @@ static int netvsc_close(struct net_devic
 
 	netif_stop_queue(net);
 
-	ret = net_drv_obj->OnClose(device_obj);
+	ret = RndisFilterOnClose(device_obj);
 	if (ret != 0)
 		DPRINT_ERR(NETVSC_DRV, "unable to close device (ret %d).", ret);
 
@@ -282,7 +272,7 @@ retry_send:
 static void netvsc_linkstatus_callback(struct hv_device *device_obj,
 				       unsigned int status)
 {
-	struct device_context *device_ctx = to_device_context(device_obj);
+	struct vm_device *device_ctx = to_vm_device(device_obj);
 	struct net_device *net = dev_get_drvdata(&device_ctx->device);
 
 	DPRINT_ENTER(NETVSC_DRV);
@@ -309,7 +299,7 @@ static void netvsc_linkstatus_callback(s
 static int netvsc_recv_callback(struct hv_device *device_obj,
 				struct hv_netvsc_packet *packet)
 {
-	struct device_context *device_ctx = to_device_context(device_obj);
+	struct vm_device *device_ctx = to_vm_device(device_obj);
 	struct net_device *net = dev_get_drvdata(&device_ctx->device);
 	struct net_device_context *net_device_ctx;
 	struct sk_buff *skb;
@@ -401,7 +391,7 @@ static int netvsc_probe(struct device *d
 	struct netvsc_driver_context *net_drv_ctx =
 		(struct netvsc_driver_context *)driver_ctx;
 	struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
-	struct device_context *device_ctx = device_to_device_context(device);
+	struct vm_device *device_ctx = device_to_vm_device(device);
 	struct hv_device *device_obj = &device_ctx->device_obj;
 	struct net_device *net = NULL;
 	struct net_device_context *net_device_ctx;
@@ -413,8 +403,7 @@ static int netvsc_probe(struct device *d
 	if (!net_drv_obj->Base.OnDeviceAdd)
 		return -1;
 
-	net = alloc_netdev(sizeof(struct net_device_context), "seth%d",
-			   ether_setup);
+	net = alloc_etherdev(sizeof(struct net_device_context));
 	if (!net)
 		return -1;
 
@@ -473,7 +462,7 @@ static int netvsc_remove(struct device *
 	struct netvsc_driver_context *net_drv_ctx =
 		(struct netvsc_driver_context *)driver_ctx;
 	struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
-	struct device_context *device_ctx = device_to_device_context(device);
+	struct vm_device *device_ctx = device_to_vm_device(device);
 	struct net_device *net = dev_get_drvdata(&device_ctx->device);
 	struct hv_device *device_obj = &device_ctx->device_obj;
 	int ret;
@@ -613,6 +602,8 @@ static void __exit netvsc_exit(void)
 	DPRINT_EXIT(NETVSC_DRV);
 }
 
+MODULE_LICENSE("GPL");
+MODULE_VERSION(HV_DRV_VERSION);
 module_param(netvsc_ringbuffer_size, int, S_IRUGO);
 
 module_init(netvsc_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/osd.c linux-libre-2.6.34-gnu1/drivers/staging/hv/osd.c
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/osd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/osd.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/time.h>
 #include <linux/io.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include "osd.h"
 
 struct osd_callback_struct {
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/RingBuffer.c linux-libre-2.6.34-gnu1/drivers/staging/hv/RingBuffer.c
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/RingBuffer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/RingBuffer.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,7 +48,7 @@ Description:
 static inline void
 GetRingBufferAvailBytes(RING_BUFFER_INFO *rbi, u32 *read, u32 *write)
 {
-	u32 read_loc,write_loc;
+	u32 read_loc, write_loc;
 
 	/* Capture the read/write indices before they changed */
 	read_loc = rbi->RingBuffer->ReadIndex;
@@ -68,7 +68,7 @@ Description:
 
 --*/
 static inline u32
-GetNextWriteLocation(RING_BUFFER_INFO* RingInfo)
+GetNextWriteLocation(RING_BUFFER_INFO *RingInfo)
 {
 	u32 next = RingInfo->RingBuffer->WriteIndex;
 
@@ -87,7 +87,7 @@ Description:
 
 --*/
 static inline void
-SetNextWriteLocation(RING_BUFFER_INFO* RingInfo, u32 NextWriteLocation)
+SetNextWriteLocation(RING_BUFFER_INFO *RingInfo, u32 NextWriteLocation)
 {
 	RingInfo->RingBuffer->WriteIndex = NextWriteLocation;
 }
@@ -102,7 +102,7 @@ Description:
 
 --*/
 static inline u32
-GetNextReadLocation(RING_BUFFER_INFO* RingInfo)
+GetNextReadLocation(RING_BUFFER_INFO *RingInfo)
 {
 	u32 next = RingInfo->RingBuffer->ReadIndex;
 
@@ -122,7 +122,7 @@ Description:
 
 --*/
 static inline u32
-GetNextReadLocationWithOffset(RING_BUFFER_INFO* RingInfo, u32 Offset)
+GetNextReadLocationWithOffset(RING_BUFFER_INFO *RingInfo, u32 Offset)
 {
 	u32 next = RingInfo->RingBuffer->ReadIndex;
 
@@ -143,7 +143,7 @@ Description:
 
 --*/
 static inline void
-SetNextReadLocation(RING_BUFFER_INFO* RingInfo, u32 NextReadLocation)
+SetNextReadLocation(RING_BUFFER_INFO *RingInfo, u32 NextReadLocation)
 {
 	RingInfo->RingBuffer->ReadIndex = NextReadLocation;
 }
@@ -159,7 +159,7 @@ Description:
 
 --*/
 static inline void *
-GetRingBuffer(RING_BUFFER_INFO* RingInfo)
+GetRingBuffer(RING_BUFFER_INFO *RingInfo)
 {
 	return (void *)RingInfo->RingBuffer->Buffer;
 }
@@ -175,7 +175,7 @@ Description:
 
 --*/
 static inline u32
-GetRingBufferSize(RING_BUFFER_INFO* RingInfo)
+GetRingBufferSize(RING_BUFFER_INFO *RingInfo)
 {
 	return RingInfo->RingDataSize;
 }
@@ -190,9 +190,10 @@ Description:
 
 --*/
 static inline u64
-GetRingBufferIndices(RING_BUFFER_INFO* RingInfo)
+GetRingBufferIndices(RING_BUFFER_INFO *RingInfo)
 {
-	return ((u64)RingInfo->RingBuffer->WriteIndex << 32) || RingInfo->RingBuffer->ReadIndex;
+	return ((u64)RingInfo->RingBuffer->WriteIndex << 32)
+	|| RingInfo->RingBuffer->ReadIndex;
 }
 
 
@@ -210,9 +211,14 @@ void DumpRingInfo(RING_BUFFER_INFO *Ring
 	u32 bytesAvailToWrite;
 	u32 bytesAvailToRead;
 
-	GetRingBufferAvailBytes(RingInfo, &bytesAvailToRead, &bytesAvailToWrite);
+	GetRingBufferAvailBytes(RingInfo,
+	&bytesAvailToRead,
+	&bytesAvailToWrite);
 
-	DPRINT(VMBUS, DEBUG_RING_LVL, "%s <<ringinfo %p buffer %p avail write %u avail read %u read idx %u write idx %u>>",
+	DPRINT(VMBUS,
+		DEBUG_RING_LVL,
+		"%s <<ringinfo %p buffer %p avail write %u "
+		"avail read %u read idx %u write idx %u>>",
 		Prefix,
 		RingInfo,
 		RingInfo->RingBuffer->Buffer,
@@ -229,13 +235,13 @@ static u32
 CopyToRingBuffer(
 	RING_BUFFER_INFO	*RingInfo,
 	u32				StartWriteOffset,
-	void *				Src,
+	void				*Src,
 	u32				SrcLen);
 
 static u32
 CopyFromRingBuffer(
 	RING_BUFFER_INFO	*RingInfo,
-	void *				Dest,
+	void				*Dest,
 	u32				DestLen,
 	u32				StartReadOffset);
 
@@ -256,15 +262,15 @@ void RingBufferGetDebugInfo(RING_BUFFER_
 	u32 bytesAvailToWrite;
 	u32 bytesAvailToRead;
 
-	if (RingInfo->RingBuffer)
-	{
-		GetRingBufferAvailBytes(RingInfo, &bytesAvailToRead, &bytesAvailToWrite);
+	if (RingInfo->RingBuffer) {
+		GetRingBufferAvailBytes(RingInfo,
+					&bytesAvailToRead,
+					&bytesAvailToWrite);
 
 		DebugInfo->BytesAvailToRead = bytesAvailToRead;
 		DebugInfo->BytesAvailToWrite = bytesAvailToWrite;
 		DebugInfo->CurrentReadIndex = RingInfo->RingBuffer->ReadIndex;
 		DebugInfo->CurrentWriteIndex = RingInfo->RingBuffer->WriteIndex;
-
 		DebugInfo->CurrentInterruptMask = RingInfo->RingBuffer->InterruptMask;
 	}
 }
@@ -299,7 +305,7 @@ int RingBufferInit(RING_BUFFER_INFO *Rin
 
 	memset(RingInfo, 0, sizeof(RING_BUFFER_INFO));
 
-	RingInfo->RingBuffer = (RING_BUFFER*)Buffer;
+	RingInfo->RingBuffer = (RING_BUFFER *)Buffer;
 	RingInfo->RingBuffer->ReadIndex = RingInfo->RingBuffer->WriteIndex = 0;
 
 	RingInfo->RingSize = BufferLen;
@@ -319,7 +325,7 @@ Description:
 	Cleanup the ring buffer
 
 --*/
-void RingBufferCleanup(RING_BUFFER_INFO* RingInfo)
+void RingBufferCleanup(RING_BUFFER_INFO *RingInfo)
 {
 }
 
@@ -335,14 +341,14 @@ Description:
 int RingBufferWrite(RING_BUFFER_INFO *OutRingInfo,
 		    struct scatterlist *sglist, u32 sgcount)
 {
-	int i=0;
+	int i = 0;
 	u32 byteAvailToWrite;
 	u32 byteAvailToRead;
-	u32 totalBytesToWrite=0;
+	u32 totalBytesToWrite = 0;
 
 	struct scatterlist *sg;
 	volatile u32 nextWriteLocation;
-	u64 prevIndices=0;
+	u64 prevIndices = 0;
 	unsigned long flags;
 
 	DPRINT_ENTER(VMBUS);
@@ -356,17 +362,23 @@ int RingBufferWrite(RING_BUFFER_INFO *Ou
 
 	spin_lock_irqsave(&OutRingInfo->ring_lock, flags);
 
-	GetRingBufferAvailBytes(OutRingInfo, &byteAvailToRead, &byteAvailToWrite);
+	GetRingBufferAvailBytes(OutRingInfo,
+				&byteAvailToRead,
+				&byteAvailToWrite);
 
 	DPRINT_DBG(VMBUS, "Writing %u bytes...", totalBytesToWrite);
 
 	/* DumpRingInfo(OutRingInfo, "BEFORE "); */
 
-	/* If there is only room for the packet, assume it is full. Otherwise, the next time around, we think the ring buffer */
+	/* If there is only room for the packet, assume it is full. */
+	/* Otherwise, the next time around, we think the ring buffer */
 	/* is empty since the read index == write index */
-	if (byteAvailToWrite <= totalBytesToWrite)
-	{
-		DPRINT_DBG(VMBUS, "No more space left on outbound ring buffer (needed %u, avail %u)", totalBytesToWrite, byteAvailToWrite);
+	if (byteAvailToWrite <= totalBytesToWrite) {
+		DPRINT_DBG(VMBUS,
+			"No more space left on outbound ring buffer "
+			"(needed %u, avail %u)",
+			totalBytesToWrite,
+			byteAvailToWrite);
 
 		spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags);
 
@@ -423,17 +435,22 @@ int RingBufferPeek(RING_BUFFER_INFO *InR
 {
 	u32 bytesAvailToWrite;
 	u32 bytesAvailToRead;
-	u32 nextReadLocation=0;
+	u32 nextReadLocation = 0;
 	unsigned long flags;
 
 	spin_lock_irqsave(&InRingInfo->ring_lock, flags);
 
-	GetRingBufferAvailBytes(InRingInfo, &bytesAvailToRead, &bytesAvailToWrite);
+	GetRingBufferAvailBytes(InRingInfo,
+				&bytesAvailToRead,
+				&bytesAvailToWrite);
 
 	/* Make sure there is something to read */
-	if (bytesAvailToRead < BufferLen )
-	{
-		/* DPRINT_DBG(VMBUS, "got callback but not enough to read <avail to read %d read size %d>!!", bytesAvailToRead, BufferLen); */
+	if (bytesAvailToRead < BufferLen) {
+		/* DPRINT_DBG(VMBUS,
+			"got callback but not enough to read "
+			"<avail to read %d read size %d>!!",
+			bytesAvailToRead,
+			BufferLen); */
 
 		spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
 
@@ -444,9 +461,9 @@ int RingBufferPeek(RING_BUFFER_INFO *InR
 	nextReadLocation = GetNextReadLocation(InRingInfo);
 
 	nextReadLocation = CopyFromRingBuffer(InRingInfo,
-											Buffer,
-											BufferLen,
-											nextReadLocation);
+						Buffer,
+						BufferLen,
+						nextReadLocation);
 
 	spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
 
@@ -468,24 +485,29 @@ int RingBufferRead(RING_BUFFER_INFO *InR
 {
 	u32 bytesAvailToWrite;
 	u32 bytesAvailToRead;
-	u32 nextReadLocation=0;
-	u64 prevIndices=0;
+	u32 nextReadLocation = 0;
+	u64 prevIndices = 0;
 	unsigned long flags;
 
 	ASSERT(BufferLen > 0);
 
 	spin_lock_irqsave(&InRingInfo->ring_lock, flags);
 
-	GetRingBufferAvailBytes(InRingInfo, &bytesAvailToRead, &bytesAvailToWrite);
+	GetRingBufferAvailBytes(InRingInfo,
+				&bytesAvailToRead,
+				&bytesAvailToWrite);
 
 	DPRINT_DBG(VMBUS, "Reading %u bytes...", BufferLen);
 
 	/* DumpRingInfo(InRingInfo, "BEFORE "); */
 
 	/* Make sure there is something to read */
-	if (bytesAvailToRead < BufferLen )
-	{
-		DPRINT_DBG(VMBUS, "got callback but not enough to read <avail to read %d read size %d>!!", bytesAvailToRead, BufferLen);
+	if (bytesAvailToRead < BufferLen) {
+		DPRINT_DBG(VMBUS,
+			"got callback but not enough to read "
+			"<avail to read %d read size %d>!!",
+			bytesAvailToRead,
+			BufferLen);
 
 		spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
 
@@ -495,17 +517,18 @@ int RingBufferRead(RING_BUFFER_INFO *InR
 	nextReadLocation = GetNextReadLocationWithOffset(InRingInfo, Offset);
 
 	nextReadLocation = CopyFromRingBuffer(InRingInfo,
-											Buffer,
-											BufferLen,
-											nextReadLocation);
+						Buffer,
+						BufferLen,
+						nextReadLocation);
 
 	nextReadLocation = CopyFromRingBuffer(InRingInfo,
-											&prevIndices,
-											sizeof(u64),
-											nextReadLocation);
+						&prevIndices,
+						sizeof(u64),
+						nextReadLocation);
 
 	/* Make sure all reads are done before we update the read index since */
-	/* the writer may start writing to the read area once the read index is updated */
+	/* the writer may start writing to the read area once the read index */
+	/*is updated */
 	mb();
 
 	/* Update the read index */
@@ -533,25 +556,22 @@ static u32
 CopyToRingBuffer(
 	RING_BUFFER_INFO	*RingInfo,
 	u32				StartWriteOffset,
-	void *				Src,
+	void				*Src,
 	u32				SrcLen)
 {
-	void * ringBuffer=GetRingBuffer(RingInfo);
-	u32 ringBufferSize=GetRingBufferSize(RingInfo);
+	void *ringBuffer = GetRingBuffer(RingInfo);
+	u32 ringBufferSize = GetRingBufferSize(RingInfo);
 	u32 fragLen;
 
-	if (SrcLen > ringBufferSize - StartWriteOffset) /* wrap-around detected! */
-	{
+	/* wrap-around detected! */
+	if (SrcLen > ringBufferSize - StartWriteOffset) {
 		DPRINT_DBG(VMBUS, "wrap-around detected!");
 
 		fragLen = ringBufferSize - StartWriteOffset;
 		memcpy(ringBuffer + StartWriteOffset, Src, fragLen);
 		memcpy(ringBuffer, Src + fragLen, SrcLen - fragLen);
-	}
-	else
-	{
+	} else
 		memcpy(ringBuffer + StartWriteOffset, Src, SrcLen);
-	}
 
 	StartWriteOffset += SrcLen;
 	StartWriteOffset %= ringBufferSize;
@@ -573,28 +593,27 @@ Description:
 static u32
 CopyFromRingBuffer(
 	RING_BUFFER_INFO	*RingInfo,
-	void *				Dest,
+	void				*Dest,
 	u32				DestLen,
 	u32				StartReadOffset)
 {
-	void * ringBuffer=GetRingBuffer(RingInfo);
-	u32 ringBufferSize=GetRingBufferSize(RingInfo);
+	void *ringBuffer = GetRingBuffer(RingInfo);
+	u32 ringBufferSize = GetRingBufferSize(RingInfo);
 
 	u32 fragLen;
 
-	if (DestLen > ringBufferSize - StartReadOffset) /* wrap-around detected at the src */
-	{
+	/* wrap-around detected at the src */
+	if (DestLen > ringBufferSize - StartReadOffset) {
 		DPRINT_DBG(VMBUS, "src wrap-around detected!");
 
 		fragLen = ringBufferSize - StartReadOffset;
 
 		memcpy(Dest, ringBuffer + StartReadOffset, fragLen);
 		memcpy(Dest + fragLen, ringBuffer, DestLen - fragLen);
-	}
-	else
-	{
+	} else
+
 		memcpy(Dest, ringBuffer + StartReadOffset, DestLen);
-	}
+
 
 	StartReadOffset += DestLen;
 	StartReadOffset %= ringBufferSize;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/RndisFilter.c linux-libre-2.6.34-gnu1/drivers/staging/hv/RndisFilter.c
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/RndisFilter.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/RndisFilter.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 #include "osd.h"
 #include "logging.h"
@@ -85,10 +86,6 @@ static int RndisFilterOnDeviceRemove(str
 
 static void RndisFilterOnCleanup(struct hv_driver *Driver);
 
-static int RndisFilterOnOpen(struct hv_device *Device);
-
-static int RndisFilterOnClose(struct hv_device *Device);
-
 static int RndisFilterOnSend(struct hv_device *Device,
 			     struct hv_netvsc_packet *Packet);
 
@@ -654,8 +651,6 @@ int RndisFilterInit(struct netvsc_driver
 	Driver->Base.OnDeviceRemove = RndisFilterOnDeviceRemove;
 	Driver->Base.OnCleanup = RndisFilterOnCleanup;
 	Driver->OnSend = RndisFilterOnSend;
-	Driver->OnOpen = RndisFilterOnOpen;
-	Driver->OnClose = RndisFilterOnClose;
 	/* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */
 	Driver->OnReceiveCallback = RndisFilterOnReceive;
 
@@ -756,6 +751,7 @@ static int RndisFilterOpenDevice(struct
 
 	ret = RndisFilterSetPacketFilter(Device,
 					 NDIS_PACKET_TYPE_BROADCAST |
+					 NDIS_PACKET_TYPE_ALL_MULTICAST |
 					 NDIS_PACKET_TYPE_DIRECTED);
 	if (ret == 0)
 		Device->State = RNDIS_DEV_DATAINITIALIZED;
@@ -888,7 +884,7 @@ static void RndisFilterOnCleanup(struct
 	DPRINT_EXIT(NETVSC);
 }
 
-static int RndisFilterOnOpen(struct hv_device *Device)
+int RndisFilterOnOpen(struct hv_device *Device)
 {
 	int ret;
 	struct netvsc_device *netDevice = Device->Extension;
@@ -903,7 +899,7 @@ static int RndisFilterOnOpen(struct hv_d
 	return ret;
 }
 
-static int RndisFilterOnClose(struct hv_device *Device)
+int RndisFilterOnClose(struct hv_device *Device)
 {
 	int ret;
 	struct netvsc_device *netDevice = Device->Extension;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/StorVscApi.h linux-libre-2.6.34-gnu1/drivers/staging/hv/StorVscApi.h
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/StorVscApi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/StorVscApi.h	2010-05-16 17:17:36.000000000 -0400
@@ -91,13 +91,9 @@ struct storvsc_driver_object {
 	/* Maximum # of requests in flight per channel/device */
 	u32 MaxOutstandingRequestsPerChannel;
 
-	/* Set by the caller to allow us to re-enumerate the bus on the host */
-	void (*OnHostRescan)(struct hv_device *Device);
-
 	/* Specific to this driver */
 	int (*OnIORequest)(struct hv_device *Device,
 			   struct hv_storvsc_request *Request);
-	int (*OnHostReset)(struct hv_device *Device);
 };
 
 struct storvsc_device_info {
@@ -108,6 +104,7 @@ struct storvsc_device_info {
 
 /* Interface */
 int StorVscInitialize(struct hv_driver *driver);
+int StorVscOnHostReset(struct hv_device *Device);
 int BlkVscInitialize(struct hv_driver *driver);
 
 #endif /* _STORVSC_API_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/StorVsc.c linux-libre-2.6.34-gnu1/drivers/staging/hv/StorVsc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/StorVsc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/StorVsc.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include "osd.h"
@@ -625,7 +626,7 @@ static int StorVscOnDeviceRemove(struct
 	return 0;
 }
 
-static int StorVscOnHostReset(struct hv_device *Device)
+int StorVscOnHostReset(struct hv_device *Device)
 {
 	struct storvsc_device *storDevice;
 	struct storvsc_request_extension *request;
@@ -842,7 +843,6 @@ int StorVscInitialize(struct hv_driver *
 	storDriver->Base.OnCleanup	= StorVscOnCleanup;
 
 	storDriver->OnIORequest		= StorVscOnIORequest;
-	storDriver->OnHostReset		= StorVscOnHostReset;
 
 	DPRINT_EXIT(STORVSC);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/storvsc_drv.c linux-libre-2.6.34-gnu1/drivers/staging/hv/storvsc_drv.c
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/storvsc_drv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/storvsc_drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  *   Hank Janssen  <hjanssen@microsoft.com>
  */
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/blkdev.h>
@@ -32,6 +33,7 @@
 #include <scsi/scsi_dbg.h>
 #include "osd.h"
 #include "logging.h"
+#include "VersionInfo.h"
 #include "vmbus.h"
 #include "StorVscApi.h"
 
@@ -39,10 +41,8 @@
 struct host_device_context {
 	/* must be 1st field
 	 * FIXME this is a bug */
-	struct work_struct host_rescan_work;
-
 	/* point back to our device context */
-	struct device_context *device_ctx;
+	struct vm_device *device_ctx;
 	struct kmem_cache *request_pool;
 	unsigned int port;
 	unsigned char path;
@@ -77,8 +77,6 @@ static int storvsc_queuecommand(struct s
 static int storvsc_device_alloc(struct scsi_device *);
 static int storvsc_device_configure(struct scsi_device *);
 static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd);
-static void storvsc_host_rescan_callback(struct work_struct *work);
-static void storvsc_host_rescan(struct hv_device *device_obj);
 static int storvsc_remove(struct device *dev);
 
 static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl,
@@ -94,8 +92,6 @@ static unsigned int copy_to_bounce_buffe
 					  struct scatterlist *bounce_sgl,
 					  unsigned int orig_sgl_count);
 
-static int storvsc_report_luns(struct scsi_device *sdev, unsigned int luns[],
-			       unsigned int *lun_count);
 static int storvsc_get_chs(struct scsi_device *sdev, struct block_device *bdev,
 			   sector_t capacity, int *info);
 
@@ -148,7 +144,6 @@ static int storvsc_drv_init(int (*drv_in
 	vmbus_get_interface(&storvsc_drv_obj->Base.VmbusChannelInterface);
 
 	storvsc_drv_obj->RingBufferSize = storvsc_ringbuffer_size;
-	storvsc_drv_obj->OnHostRescan = storvsc_host_rescan;
 
 	/* Callback to client driver to complete the initialization */
 	drv_init(&storvsc_drv_obj->Base);
@@ -240,7 +235,7 @@ static int storvsc_probe(struct device *
 				(struct storvsc_driver_context *)driver_ctx;
 	struct storvsc_driver_object *storvsc_drv_obj =
 				&storvsc_drv_ctx->drv_obj;
-	struct device_context *device_ctx = device_to_device_context(device);
+	struct vm_device *device_ctx = device_to_vm_device(device);
 	struct hv_device *device_obj = &device_ctx->device_obj;
 	struct Scsi_Host *host;
 	struct host_device_context *host_device_ctx;
@@ -266,9 +261,6 @@ static int storvsc_probe(struct device *
 	host_device_ctx->port = host->host_no;
 	host_device_ctx->device_ctx = device_ctx;
 
-	INIT_WORK(&host_device_ctx->host_rescan_work,
-		  storvsc_host_rescan_callback);
-
 	host_device_ctx->request_pool =
 				kmem_cache_create(dev_name(&device_ctx->device),
 					sizeof(struct storvsc_cmd_request) +
@@ -339,7 +331,7 @@ static int storvsc_remove(struct device
 			(struct storvsc_driver_context *)driver_ctx;
 	struct storvsc_driver_object *storvsc_drv_obj =
 			&storvsc_drv_ctx->drv_obj;
-	struct device_context *device_ctx = device_to_device_context(device);
+	struct vm_device *device_ctx = device_to_vm_device(device);
 	struct hv_device *device_obj = &device_ctx->device_obj;
 	struct Scsi_Host *host = dev_get_drvdata(device);
 	struct host_device_context *host_device_ctx =
@@ -640,7 +632,7 @@ static int storvsc_queuecommand(struct s
 	int ret;
 	struct host_device_context *host_device_ctx =
 		(struct host_device_context *)scmnd->device->host->hostdata;
-	struct device_context *device_ctx = host_device_ctx->device_ctx;
+	struct vm_device *device_ctx = host_device_ctx->device_ctx;
 	struct driver_context *driver_ctx =
 		driver_to_driver_context(device_ctx->device.driver);
 	struct storvsc_driver_context *storvsc_drv_ctx =
@@ -879,14 +871,7 @@ static int storvsc_host_reset_handler(st
 	int ret;
 	struct host_device_context *host_device_ctx =
 		(struct host_device_context *)scmnd->device->host->hostdata;
-	struct device_context *device_ctx = host_device_ctx->device_ctx;
-	struct driver_context *driver_ctx =
-			driver_to_driver_context(device_ctx->device.driver);
-	struct storvsc_driver_context *storvsc_drv_ctx =
-			(struct storvsc_driver_context *)driver_ctx;
-
-	struct storvsc_driver_object *storvsc_drv_obj =
-			&storvsc_drv_ctx->drv_obj;
+	struct vm_device *device_ctx = host_device_ctx->device_ctx;
 
 	DPRINT_ENTER(STORVSC_DRV);
 
@@ -894,8 +879,7 @@ static int storvsc_host_reset_handler(st
 		    scmnd->device, &device_ctx->device_obj);
 
 	/* Invokes the vsc to reset the host/bus */
-	ASSERT(storvsc_drv_obj->OnHostReset);
-	ret = storvsc_drv_obj->OnHostReset(&device_ctx->device_obj);
+	ret = StorVscOnHostReset(&device_ctx->device_obj);
 	if (ret != 0) {
 		DPRINT_EXIT(STORVSC_DRV);
 		return ret;
@@ -909,201 +893,6 @@ static int storvsc_host_reset_handler(st
 	return ret;
 }
 
-/**
- * storvsc_host_rescan - Rescan the scsi HBA
- */
-static void storvsc_host_rescan_callback(struct work_struct *work)
-{
-	struct hv_device *device_obj =
-	    &((struct host_device_context *)work)->device_ctx->device_obj;
-	struct device_context *device_ctx = to_device_context(device_obj);
-	struct Scsi_Host *host = dev_get_drvdata(&device_ctx->device);
-	struct scsi_device *sdev;
-	struct host_device_context *host_device_ctx;
-	struct scsi_device **sdevs_remove_list;
-	unsigned int sdevs_count = 0;
-	unsigned int found;
-	unsigned int i;
-	unsigned int lun_count = 0;
-	unsigned int *lun_list;
-
-	DPRINT_ENTER(STORVSC_DRV);
-
-	host_device_ctx = (struct host_device_context *)host->hostdata;
-	lun_list = kcalloc(STORVSC_MAX_LUNS_PER_TARGET, sizeof(unsigned int),
-			   GFP_ATOMIC);
-	if (!lun_list) {
-		DPRINT_ERR(STORVSC_DRV, "unable to allocate lun list");
-		return;
-	}
-
-	sdevs_remove_list = kcalloc(STORVSC_MAX_LUNS_PER_TARGET,
-				    sizeof(void *), GFP_ATOMIC);
-	if (!sdevs_remove_list) {
-		kfree(lun_list);
-		DPRINT_ERR(STORVSC_DRV, "unable to allocate lun remove list");
-		return;
-	}
-
-	DPRINT_INFO(STORVSC_DRV, "rescanning host for new scsi devices...");
-
-	/* Rescan for new device */
-	scsi_scan_target(&host->shost_gendev, host_device_ctx->path,
-			 host_device_ctx->target, SCAN_WILD_CARD, 1);
-
-	DPRINT_INFO(STORVSC_DRV, "rescanning host for removed scsi device...");
-
-	/* Use the 1st device to send the report luns cmd */
-	shost_for_each_device(sdev, host) {
-		lun_count = STORVSC_MAX_LUNS_PER_TARGET;
-		storvsc_report_luns(sdev, lun_list, &lun_count);
-
-		DPRINT_INFO(STORVSC_DRV,
-			    "report luns on scsi device (%p) found %u luns ",
-			    sdev, lun_count);
-		DPRINT_INFO(STORVSC_DRV,
-			    "existing luns on scsi device (%p) host (%d)",
-			    sdev, host->host_no);
-
-		scsi_device_put(sdev);
-		break;
-	}
-
-	for (i = 0; i < lun_count; i++)
-		DPRINT_INFO(STORVSC_DRV, "%d) lun %u", i, lun_list[i]);
-
-	/* Rescan for devices that may have been removed.
-	 * We do not have to worry that new devices may have been added since
-	 * this callback is serialized by the workqueue ie add/remove are done
-	 * here.
-	 */
-	shost_for_each_device(sdev, host) {
-		/* See if this device is still here */
-		found = 0;
-		for (i = 0; i < lun_count; i++) {
-			if (sdev->lun == lun_list[i]) {
-				found = 1;
-				break;
-			}
-		}
-		if (!found) {
-			DPRINT_INFO(STORVSC_DRV, "lun (%u) does not exists",
-				    sdev->lun);
-			sdevs_remove_list[sdevs_count++] = sdev;
-		}
-	}
-
-	/* Now remove the devices */
-	for (i = 0; i < sdevs_count; i++) {
-		DPRINT_INFO(STORVSC_DRV,
-			    "removing scsi device (%p) lun (%u)...",
-			    sdevs_remove_list[i], sdevs_remove_list[i]->lun);
-
-		/* make sure it is not removed from underneath us */
-		if (!scsi_device_get(sdevs_remove_list[i])) {
-			scsi_remove_device(sdevs_remove_list[i]);
-			scsi_device_put(sdevs_remove_list[i]);
-		}
-	}
-
-	DPRINT_INFO(STORVSC_DRV, "rescan completed on dev obj (%p) "
-		    "target (%u) bus (%u)", device_obj,
-		    host_device_ctx->target, host_device_ctx->path);
-
-	kfree(lun_list);
-	kfree(sdevs_remove_list);
-
-	DPRINT_EXIT(STORVSC_DRV);
-}
-
-static int storvsc_report_luns(struct scsi_device *sdev, unsigned int luns[],
-			       unsigned int *lun_count)
-{
-	int i, j;
-	unsigned int lun = 0;
-	unsigned int num_luns;
-	int result;
-	unsigned char *data;
-	struct scsi_sense_hdr sshdr;
-	unsigned char cmd[16] = {0};
-	/* Add 1 to cover the report_lun header */
-	unsigned int report_len = 8 * (STORVSC_MAX_LUNS_PER_TARGET+1);
-	unsigned long long *report_luns;
-	const unsigned int in_lun_count = *lun_count;
-
-	*lun_count = 0;
-
-	report_luns = kzalloc(report_len, GFP_ATOMIC);
-	if (!report_luns)
-		return -ENOMEM;
-
-	cmd[0] = REPORT_LUNS;
-
-	/* cmd length */
-	*(unsigned int *)&cmd[6] = cpu_to_be32(report_len);
-
-	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE,
-				  (unsigned char *)report_luns, report_len,
-				  &sshdr, 30 * HZ, 3, NULL);
-	if (result != 0) {
-		kfree(report_luns);
-		return -EBUSY;
-	}
-
-	/* get the length from the first four bytes */
-	report_len = be32_to_cpu(*(unsigned int *)&report_luns[0]);
-
-	num_luns = (report_len / sizeof(unsigned long long));
-	if (num_luns > in_lun_count) {
-		kfree(report_luns);
-		return -EINVAL;
-	}
-
-	*lun_count = num_luns;
-
-	DPRINT_DBG(STORVSC_DRV,
-		   "report luns on scsi device (%p) found %u luns ",
-		   sdev, num_luns);
-
-	/* lun id starts at 1 */
-	for (i = 1; i < num_luns + 1; i++) {
-		lun = 0;
-		data = (unsigned char *)&report_luns[i];
-		for (j = 0; j < sizeof(lun); j += 2) {
-			lun = lun | (((data[j] << 8) | data[j + 1]) <<
-				(j * 8));
-		}
-
-		luns[i-1] = lun;
-	}
-
-	kfree(report_luns);
-	return 0;
-}
-
-static void storvsc_host_rescan(struct hv_device *device_obj)
-{
-	struct device_context *device_ctx = to_device_context(device_obj);
-	struct Scsi_Host *host = dev_get_drvdata(&device_ctx->device);
-	struct host_device_context *host_device_ctx;
-
-	DPRINT_ENTER(STORVSC_DRV);
-
-	host_device_ctx = (struct host_device_context *)host->hostdata;
-
-	DPRINT_INFO(STORVSC_DRV, "initiating rescan on dev obj (%p) "
-		    "target (%u) bus (%u)...", device_obj,
-		    host_device_ctx->target, host_device_ctx->path);
-
-	/*
-	 * We need to queue this since the scanning may block and the caller
-	 * may be in an intr context
-	 */
-	/* scsi_queue_work(host, &host_device_ctx->host_rescan_work); */
-	schedule_work(&host_device_ctx->host_rescan_work);
-	DPRINT_EXIT(STORVSC_DRV);
-}
-
 static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
 			   sector_t capacity, int *info)
 {
@@ -1203,6 +992,7 @@ static void __exit storvsc_exit(void)
 }
 
 MODULE_LICENSE("GPL");
+MODULE_VERSION(HV_DRV_VERSION);
 module_param(storvsc_ringbuffer_size, int, S_IRUGO);
 module_init(storvsc_init);
 module_exit(storvsc_exit);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/VersionInfo.h linux-libre-2.6.34-gnu1/drivers/staging/hv/VersionInfo.h
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/VersionInfo.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/VersionInfo.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,8 +24,24 @@
 #ifndef __HV_VERSION_INFO
 #define __HV_VERSION_INFO
 
-static const char VersionDate[] = __DATE__;
-static const char VersionTime[] = __TIME__;
-static const char VersionDesc[] = "Version 2.0";
+/*
+ * We use the same version numbering for all Hyper-V modules.
+ *
+ * Definition of versioning is as follows;
+ *
+ * 	Major Number 	Changes for these scenarios;
+ *			1.	When a new version of Windows Hyper-V
+ *				is released.
+ *			2.	A Major change has occurred in the
+ *			       	Linux IC's.
+ *			(For example the merge for the first time
+ *			into the kernel) Every time the Major Number
+ *			changes, the Revision number is reset to 0.
+ *	Minor Number	Changes when new functionality is added
+ *			to the Linux IC's that is not a bug fix.
+ *
+ */
+#define HV_DRV_VERSION           "3.0"
+
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/Vmbus.c linux-libre-2.6.34-gnu1/drivers/staging/hv/Vmbus.c
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/Vmbus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/Vmbus.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include "osd.h"
 #include "logging.h"
 #include "VersionInfo.h"
@@ -273,10 +274,8 @@ int VmbusInitialize(struct hv_driver *dr
 
 	DPRINT_ENTER(VMBUS);
 
-	DPRINT_INFO(VMBUS, "+++++++ Build Date=%s %s +++++++",
-			VersionDate, VersionTime);
-	DPRINT_INFO(VMBUS, "+++++++ Build Description=%s +++++++",
-			VersionDesc);
+	DPRINT_INFO(VMBUS, "+++++++ HV Driver version = %s +++++++",
+		    HV_DRV_VERSION);
 	DPRINT_INFO(VMBUS, "+++++++ Vmbus supported version = %d +++++++",
 			VMBUS_REVISION_NUMBER);
 	DPRINT_INFO(VMBUS, "+++++++ Vmbus using SINT %d +++++++",
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/vmbus_drv.c linux-libre-2.6.34-gnu1/drivers/staging/hv/vmbus_drv.c
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/vmbus_drv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/vmbus_drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,10 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/sysctl.h>
+#include <linux/pci.h>
+#include <linux/dmi.h>
+#include <linux/slab.h>
+#include "VersionInfo.h"
 #include "osd.h"
 #include "logging.h"
 #include "vmbus.h"
@@ -47,7 +51,7 @@ struct vmbus_driver_context {
 	struct tasklet_struct event_dpc;
 
 	/* The bus root device */
-	struct device_context device_ctx;
+	struct vm_device device_ctx;
 };
 
 static int vmbus_match(struct device *device, struct device_driver *driver);
@@ -135,7 +139,7 @@ static ssize_t vmbus_show_device_attr(st
 				      struct device_attribute *dev_attr,
 				      char *buf)
 {
-	struct device_context *device_ctx = device_to_device_context(dev);
+	struct vm_device *device_ctx = device_to_vm_device(dev);
 	struct hv_device_info device_info;
 
 	memset(&device_info, 0, sizeof(struct hv_device_info));
@@ -245,7 +249,7 @@ static int vmbus_bus_init(int (*drv_init
 {
 	struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv;
 	struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
-	struct device_context *dev_ctx = &g_vmbus_drv.device_ctx;
+	struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx;
 	int ret;
 	unsigned int vector;
 
@@ -307,7 +311,7 @@ static int vmbus_bus_init(int (*drv_init
 	DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector);
 
 	/* Call to bus driver to add the root device */
-	memset(dev_ctx, 0, sizeof(struct device_context));
+	memset(dev_ctx, 0, sizeof(struct vm_device));
 
 	ret = vmbus_drv_obj->Base.OnDeviceAdd(&dev_ctx->device_obj, &vector);
 	if (ret != 0) {
@@ -368,7 +372,7 @@ static void vmbus_bus_exit(void)
 	struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
 	struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv;
 
-	struct device_context *dev_ctx = &g_vmbus_drv.device_ctx;
+	struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx;
 
 	DPRINT_ENTER(VMBUS_DRV);
 
@@ -471,13 +475,13 @@ static struct hv_device *vmbus_child_dev
 						   struct hv_guid *instance,
 						   void *context)
 {
-	struct device_context *child_device_ctx;
+	struct vm_device *child_device_ctx;
 	struct hv_device *child_device_obj;
 
 	DPRINT_ENTER(VMBUS_DRV);
 
 	/* Allocate the new child device */
-	child_device_ctx = kzalloc(sizeof(struct device_context), GFP_KERNEL);
+	child_device_ctx = kzalloc(sizeof(struct vm_device), GFP_KERNEL);
 	if (!child_device_ctx) {
 		DPRINT_ERR(VMBUS_DRV,
 			"unable to allocate device_context for child device");
@@ -526,10 +530,10 @@ static int vmbus_child_device_register(s
 				       struct hv_device *child_device_obj)
 {
 	int ret = 0;
-	struct device_context *root_device_ctx =
-				to_device_context(root_device_obj);
-	struct device_context *child_device_ctx =
-				to_device_context(child_device_obj);
+	struct vm_device *root_device_ctx =
+				to_vm_device(root_device_obj);
+	struct vm_device *child_device_ctx =
+				to_vm_device(child_device_obj);
 	static atomic_t device_num = ATOMIC_INIT(0);
 
 	DPRINT_ENTER(VMBUS_DRV);
@@ -572,7 +576,7 @@ static int vmbus_child_device_register(s
  */
 static void vmbus_child_device_unregister(struct hv_device *device_obj)
 {
-	struct device_context *device_ctx = to_device_context(device_obj);
+	struct vm_device *device_ctx = to_vm_device(device_obj);
 
 	DPRINT_ENTER(VMBUS_DRV);
 
@@ -610,7 +614,7 @@ static void vmbus_child_device_destroy(s
  */
 static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
 {
-	struct device_context *device_ctx = device_to_device_context(device);
+	struct vm_device *device_ctx = device_to_vm_device(device);
 	int ret;
 
 	DPRINT_ENTER(VMBUS_DRV);
@@ -687,7 +691,7 @@ static int vmbus_match(struct device *de
 {
 	int match = 0;
 	struct driver_context *driver_ctx = driver_to_driver_context(driver);
-	struct device_context *device_ctx = device_to_device_context(device);
+	struct vm_device *device_ctx = device_to_vm_device(device);
 
 	DPRINT_ENTER(VMBUS_DRV);
 
@@ -724,7 +728,7 @@ static int vmbus_match(struct device *de
  */
 static void vmbus_probe_failed_cb(struct work_struct *context)
 {
-	struct device_context *device_ctx = (struct device_context *)context;
+	struct vm_device *device_ctx = (struct vm_device *)context;
 
 	DPRINT_ENTER(VMBUS_DRV);
 
@@ -746,8 +750,8 @@ static int vmbus_probe(struct device *ch
 	int ret = 0;
 	struct driver_context *driver_ctx =
 			driver_to_driver_context(child_device->driver);
-	struct device_context *device_ctx =
-			device_to_device_context(child_device);
+	struct vm_device *device_ctx =
+			device_to_vm_device(child_device);
 
 	DPRINT_ENTER(VMBUS_DRV);
 
@@ -871,7 +875,7 @@ static void vmbus_bus_release(struct dev
  */
 static void vmbus_device_release(struct device *device)
 {
-	struct device_context *device_ctx = device_to_device_context(device);
+	struct vm_device *device_ctx = device_to_vm_device(device);
 
 	DPRINT_ENTER(VMBUS_DRV);
 
@@ -946,6 +950,19 @@ static irqreturn_t vmbus_isr(int irq, vo
 	}
 }
 
+static struct dmi_system_id __initdata microsoft_hv_dmi_table[] = {
+	{
+		.ident = "Hyper-V",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
+			DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
+		},
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(dmi, microsoft_hv_dmi_table);
+
 static int __init vmbus_init(void)
 {
 	int ret = 0;
@@ -957,6 +974,9 @@ static int __init vmbus_init(void)
 		vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel));
 	/* Todo: it is used for loglevel, to be ported to new kernel. */
 
+	if (!dmi_check_system(microsoft_hv_dmi_table))
+		return -ENODEV;
+
 	ret = vmbus_bus_init(VmbusInitialize);
 
 	DPRINT_EXIT(VMBUS_DRV);
@@ -973,7 +993,20 @@ static void __exit vmbus_exit(void)
 	return;
 }
 
+/*
+ * We use a PCI table to determine if we should autoload this driver  This is
+ * needed by distro tools to determine if the hyperv drivers should be
+ * installed and/or configured.  We don't do anything else with the table, but
+ * it needs to be present.
+ */
+const static struct pci_device_id microsoft_hv_pci_table[] = {
+	{ PCI_DEVICE(0x1414, 0x5353) },	/* VGA compatible controller */
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table);
+
 MODULE_LICENSE("GPL");
+MODULE_VERSION(HV_DRV_VERSION);
 module_param(vmbus_irq, int, S_IRUGO);
 module_param(vmbus_loglevel, int, S_IRUGO);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/hv/vmbus.h linux-libre-2.6.34-gnu1/drivers/staging/hv/vmbus.h
--- linux-libre-2.6.33-gnu1/drivers/staging/hv/vmbus.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/hv/vmbus.h	2010-05-16 17:17:36.000000000 -0400
@@ -43,23 +43,23 @@ struct driver_context {
 	void (*shutdown)(struct device *);
 };
 
-struct device_context {
+struct vm_device {
 	struct work_struct probe_failed_work_item;
 	struct hv_guid class_id;
 	struct hv_guid device_id;
 	int probe_error;
-	struct device device;
 	struct hv_device device_obj;
+	struct device device;
 };
 
-static inline struct device_context *to_device_context(struct hv_device *d)
+static inline struct vm_device *to_vm_device(struct hv_device *d)
 {
-	return container_of(d, struct device_context, device_obj);
+	return container_of(d, struct vm_device, device_obj);
 }
 
-static inline struct device_context *device_to_device_context(struct device *d)
+static inline struct vm_device *device_to_vm_device(struct device *d)
 {
-	return container_of(d, struct device_context, device);
+	return container_of(d, struct vm_device, device);
 }
 
 static inline struct driver_context *driver_to_driver_context(struct device_driver *d)
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/accel/kxsd9.c linux-libre-2.6.34-gnu1/drivers/staging/iio/accel/kxsd9.c
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/accel/kxsd9.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/accel/kxsd9.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/sysfs.h>
 #include <linux/rtc.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/accel/lis3l02dq_core.c linux-libre-2.6.34-gnu1/drivers/staging/iio/accel/lis3l02dq_core.c
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/accel/lis3l02dq_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/accel/lis3l02dq_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 
 #include <linux/sysfs.h>
 #include <linux/list.h>
@@ -617,7 +618,7 @@ static int lis3l02dq_thresh_handler_th(s
 static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s)
 {
 	struct iio_work_cont *wc
-		= container_of(work_s, struct iio_work_cont, ws_nocheck);
+		= container_of(work_s, struct iio_work_cont, ws);
 	struct lis3l02dq_state *st = wc->st;
 	u8 t;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/accel/lis3l02dq_ring.c linux-libre-2.6.34-gnu1/drivers/staging/iio/accel/lis3l02dq_ring.c
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/accel/lis3l02dq_ring.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/accel/lis3l02dq_ring.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
 #include <linux/spi/spi.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -492,6 +493,9 @@ int lis3l02dq_probe_trigger(struct iio_d
 	struct lis3l02dq_state *state = indio_dev->dev_data;
 
 	state->trig = iio_allocate_trigger();
+	if (!state->trig)
+		return -ENOMEM;
+
 	state->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
 	if (!state->trig->name) {
 		ret = -ENOMEM;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/accel/sca3000_core.c linux-libre-2.6.34-gnu1/drivers/staging/iio/accel/sca3000_core.c
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/accel/sca3000_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/accel/sca3000_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/gpio.h>
 #include <linux/fs.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/sysfs.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/accel/sca3000_ring.c linux-libre-2.6.34-gnu1/drivers/staging/iio/accel/sca3000_ring.c
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/accel/sca3000_ring.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/accel/sca3000_ring.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/gpio.h>
 #include <linux/fs.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/sysfs.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/adc/max1363_core.c linux-libre-2.6.34-gnu1/drivers/staging/iio/adc/max1363_core.c
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/adc/max1363_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/adc/max1363_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/i2c.h>
 #include <linux/rtc.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -556,6 +557,7 @@ error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
 error_free_st:
+	i2c_set_clientdata(client, NULL);
 	kfree(st);
 
 error_ret:
@@ -573,6 +575,7 @@ static int max1363_remove(struct i2c_cli
 		regulator_disable(st->reg);
 		regulator_put(st->reg);
 	}
+	i2c_set_clientdata(client, NULL);
 	kfree(st);
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/adc/max1363_ring.c linux-libre-2.6.34-gnu1/drivers/staging/iio/adc/max1363_ring.c
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/adc/max1363_ring.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/adc/max1363_ring.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/gpio.h>
 #include <linux/workqueue.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/industrialio-core.c linux-libre-2.6.34-gnu1/drivers/staging/iio/industrialio-core.c
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/industrialio-core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/industrialio-core.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/cdev.h>
+#include <linux/slab.h>
 #include "iio.h"
 #include "trigger_consumer.h"
 
@@ -79,11 +80,14 @@ EXPORT_SYMBOL(__iio_change_event);
 	/* Does anyone care? */
 	mutex_lock(&ev_int->event_list_lock);
 	if (test_bit(IIO_BUSY_BIT_POS, &ev_int->handler.flags)) {
-		if (ev_int->current_events == ev_int->max_events)
+		if (ev_int->current_events == ev_int->max_events) {
+			mutex_unlock(&ev_int->event_list_lock);
 			return 0;
+		}
 		ev = kmalloc(sizeof(*ev), GFP_KERNEL);
 		if (ev == NULL) {
 			ret = -ENOMEM;
+			mutex_unlock(&ev_int->event_list_lock);
 			goto error_ret;
 		}
 		ev->ev.id = ev_code;
@@ -115,7 +119,7 @@ int iio_push_event(struct iio_dev *dev_i
 EXPORT_SYMBOL(iio_push_event);
 
 /* Generic interrupt line interrupt handler */
-irqreturn_t iio_interrupt_handler(int irq, void *_int_info)
+static irqreturn_t iio_interrupt_handler(int irq, void *_int_info)
 {
 	struct iio_interrupt *int_info = _int_info;
 	struct iio_dev *dev_info = int_info->dev_info;
@@ -249,10 +253,10 @@ void iio_remove_event_from_list(struct i
 }
 EXPORT_SYMBOL(iio_remove_event_from_list);
 
-ssize_t iio_event_chrdev_read(struct file *filep,
-			      char *buf,
-			      size_t count,
-			      loff_t *f_ps)
+static ssize_t iio_event_chrdev_read(struct file *filep,
+				     char __user *buf,
+				     size_t count,
+				     loff_t *f_ps)
 {
 	struct iio_event_interface *ev_int = filep->private_data;
 	struct iio_detected_event_list *el;
@@ -289,16 +293,16 @@ ssize_t iio_event_chrdev_read(struct fil
 	mutex_unlock(&ev_int->event_list_lock);
 	/*
 	 * Possible concurency issue if an update of this event is on its way
-	 * through. May lead to new even being removed whilst the reported event
-	 * was the unescalated event. In typical use case this is not a problem
-	 * as userspace will say read half the buffer due to a 50% full event
-	 * which would make the correct 100% full incorrect anyway.
+	 * through. May lead to new event being removed whilst the reported
+	 * event was the unescalated event. In typical use case this is not a
+	 * problem as userspace will say read half the buffer due to a 50%
+	 * full event which would make the correct 100% full incorrect anyway.
 	 */
-	spin_lock(&el->shared_pointer->lock);
-	if (el->shared_pointer)
+	if (el->shared_pointer) {
+		spin_lock(&el->shared_pointer->lock);
 		(el->shared_pointer->ev_p) = NULL;
-	spin_unlock(&el->shared_pointer->lock);
-
+		spin_unlock(&el->shared_pointer->lock);
+	}
 	kfree(el);
 
 	return len;
@@ -310,7 +314,7 @@ error_ret:
 	return ret;
 }
 
-int iio_event_chrdev_release(struct inode *inode, struct file *filep)
+static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
 {
 	struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev);
 	struct iio_event_interface *ev_int = hand->private;
@@ -332,7 +336,7 @@ int iio_event_chrdev_release(struct inod
 	return 0;
 }
 
-int iio_event_chrdev_open(struct inode *inode, struct file *filep)
+static int iio_event_chrdev_open(struct inode *inode, struct file *filep)
 {
 	struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev);
 	struct iio_event_interface *ev_int = hand->private;
@@ -533,6 +537,7 @@ static void iio_device_unregister_sysfs(
 	sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
 }
 
+/* Return a negative errno on failure */
 int iio_get_new_idr_val(struct idr *this_idr)
 {
 	int ret;
@@ -656,7 +661,7 @@ static int iio_device_register_eventset(
 	for (i = 0; i < dev_info->num_interrupt_lines; i++) {
 		dev_info->event_interfaces[i].owner = dev_info->driver_module;
 		ret = iio_get_new_idr_val(&iio_event_idr);
-		if (ret)
+		if (ret < 0)
 			goto error_free_setup_ev_ints;
 		else
 			dev_info->event_interfaces[i].id = ret;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/industrialio-ring.c linux-libre-2.6.34-gnu1/drivers/staging/iio/industrialio-ring.c
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/industrialio-ring.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/industrialio-ring.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/cdev.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 
 #include "iio.h"
 #include "ring_generic.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/industrialio-trigger.c linux-libre-2.6.34-gnu1/drivers/staging/iio/industrialio-trigger.c
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/industrialio-trigger.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/industrialio-trigger.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 
 #include "iio.h"
 #include "trigger.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/light/tsl2563.c linux-libre-2.6.34-gnu1/drivers/staging/iio/light/tsl2563.c
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/light/tsl2563.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/light/tsl2563.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/pm.h>
 #include <linux/hwmon.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include "../iio.h"
 #include "tsl2563.h"
@@ -681,6 +682,7 @@ static int __devinit tsl2563_probe(struc
 fail2:
 	iio_device_unregister(chip->indio_dev);
 fail1:
+	i2c_set_clientdata(client, NULL);
 	kfree(chip);
 	return err;
 }
@@ -691,6 +693,7 @@ static int tsl2563_remove(struct i2c_cli
 
 	iio_device_unregister(chip->indio_dev);
 
+	i2c_set_clientdata(client, NULL);
 	kfree(chip);
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/ring_generic.h linux-libre-2.6.34-gnu1/drivers/staging/iio/ring_generic.h
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/ring_generic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/ring_generic.h	2010-05-16 17:17:36.000000000 -0400
@@ -146,8 +146,7 @@ static inline void __iio_init_ring_buffe
 	ring->length = length;
 	ring->loopcount = 0;
 	ring->shared_ev_pointer.ev_p = 0;
-	ring->shared_ev_pointer.lock =
-		__SPIN_LOCK_UNLOCKED(ring->shared_ev_pointer->loc);
+	spin_lock_init(&ring->shared_ev_pointer.lock);
 }
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/ring_sw.c linux-libre-2.6.34-gnu1/drivers/staging/iio/ring_sw.c
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/ring_sw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/ring_sw.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,8 +7,8 @@
  * the Free Software Foundation.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
-#include <linux/device.h>
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/workqueue.h>
@@ -21,7 +21,7 @@ static inline int __iio_init_sw_ring_buf
 		return -EINVAL;
 
 	__iio_init_ring_buffer(&ring->buf, bytes_per_datum, length);
-	ring->use_lock = __SPIN_LOCK_UNLOCKED((ring)->use_lock);
+	spin_lock_init(&ring->use_lock);
 	ring->data = kmalloc(length*ring->buf.bpd, GFP_KERNEL);
 	ring->read_p = 0;
 	ring->write_p = 0;
@@ -293,7 +293,7 @@ again:
 		return -EAGAIN;
 	memcpy(data, last_written_p_copy, ring->buf.bpd);
 
-	if (unlikely(ring->last_written_p >= last_written_p_copy))
+	if (unlikely(ring->last_written_p != last_written_p_copy))
 		goto again;
 
 	iio_unmark_sw_rb_in_use(&ring->buf);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/trigger/iio-trig-gpio.c linux-libre-2.6.34-gnu1/drivers/staging/iio/trigger/iio-trig-gpio.c
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/trigger/iio-trig-gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/trigger/iio-trig-gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include "../iio.h"
 #include "../trigger.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c linux-libre-2.6.34-gnu1/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/rtc.h>
 #include "../iio.h"
 #include "../trigger.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/iio/trigger_consumer.h linux-libre-2.6.34-gnu1/drivers/staging/iio/trigger_consumer.h
--- linux-libre-2.6.33-gnu1/drivers/staging/iio/trigger_consumer.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/iio/trigger_consumer.h	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,7 @@ int iio_device_unregister_trigger_consum
  * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers
  * @dev_info: iio_dev associated with the device that will consume the trigger
  **/
-int iio_device_register_trigger_consumer(struct iio_dev *dev_info)
+static int iio_device_register_trigger_consumer(struct iio_dev *dev_info)
 {
 	return 0;
 };
@@ -36,7 +36,7 @@ int iio_device_register_trigger_consumer
  * iio_device_unregister_trigger_consumer() - reverse the registration process
  * @dev_info: iio_dev associated with the device that consumed the trigger
  **/
-int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info)
+static int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info)
 {
 	return 0;
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -71,8 +71,6 @@ source "drivers/staging/asus_oled/Kconfi
 
 source "drivers/staging/panel/Kconfig"
 
-source "drivers/staging/altpciechdma/Kconfig"
-
 source "drivers/staging/rtl8187se/Kconfig"
 
 source "drivers/staging/rtl8192su/Kconfig"
@@ -81,20 +79,14 @@ source "drivers/staging/rtl8192u/Kconfig
 
 source "drivers/staging/rtl8192e/Kconfig"
 
-source "drivers/staging/mimio/Kconfig"
-
 source "drivers/staging/frontier/Kconfig"
 
 source "drivers/staging/dream/Kconfig"
 
 source "drivers/staging/pohmelfs/Kconfig"
 
-source "drivers/staging/b3dfg/Kconfig"
-
 source "drivers/staging/phison/Kconfig"
 
-source "drivers/staging/p9auth/Kconfig"
-
 source "drivers/staging/line6/Kconfig"
 
 source "drivers/gpu/drm/vmwgfx/Kconfig"
@@ -117,7 +109,7 @@ source "drivers/staging/hv/Kconfig"
 
 source "drivers/staging/vme/Kconfig"
 
-source "drivers/staging/rar/Kconfig"
+source "drivers/staging/rar_register/Kconfig"
 
 source "drivers/staging/sep/Kconfig"
 
@@ -143,5 +135,9 @@ source "drivers/staging/netwave/Kconfig"
 
 source "drivers/staging/sm7xx/Kconfig"
 
+source "drivers/staging/dt3155/Kconfig"
+
+source "drivers/staging/crystalhd/Kconfig"
+
 endif # !STAGING_EXCLUDE_BUILD
 endif # STAGING
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/line6/capture.c linux-libre-2.6.34-gnu1/drivers/staging/line6/capture.c
--- linux-libre-2.6.33-gnu1/drivers/staging/line6/capture.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/line6/capture.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,8 @@
 
 #include "driver.h"
 
+#include <linux/slab.h>
+
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/line6/driver.c linux-libre-2.6.34-gnu1/drivers/staging/line6/driver.c
--- linux-libre-2.6.33-gnu1/drivers/staging/line6/driver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/line6/driver.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "audio.h"
@@ -33,7 +34,7 @@
 
 
 /* table of devices that work with this driver */
-static struct usb_device_id line6_id_table[] = {
+static const struct usb_device_id line6_id_table[] = {
 	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT) },
 	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE) },
 	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO) },
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/line6/dumprequest.c linux-libre-2.6.34-gnu1/drivers/staging/line6/dumprequest.c
--- linux-libre-2.6.33-gnu1/drivers/staging/line6/dumprequest.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/line6/dumprequest.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,9 @@
  */
 
 #include "driver.h"
+
+#include <linux/slab.h>
+
 #include "dumprequest.h"
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/line6/midi.c linux-libre-2.6.34-gnu1/drivers/staging/line6/midi.c
--- linux-libre-2.6.33-gnu1/drivers/staging/line6/midi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/line6/midi.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include "driver.h"
 
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include <sound/core.h>
 #include <sound/rawmidi.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/line6/pcm.c linux-libre-2.6.34-gnu1/drivers/staging/line6/pcm.c
--- linux-libre-2.6.33-gnu1/drivers/staging/line6/pcm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/line6/pcm.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,8 @@
 
 #include "driver.h"
 
+#include <linux/slab.h>
+
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/line6/playback.c linux-libre-2.6.34-gnu1/drivers/staging/line6/playback.c
--- linux-libre-2.6.33-gnu1/drivers/staging/line6/playback.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/line6/playback.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,8 @@
 
 #include "driver.h"
 
+#include <linux/slab.h>
+
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/line6/pod.c linux-libre-2.6.34-gnu1/drivers/staging/line6/pod.c
--- linux-libre-2.6.33-gnu1/drivers/staging/line6/pod.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/line6/pod.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,8 @@
 
 #include "driver.h"
 
+#include <linux/slab.h>
+
 #include "audio.h"
 #include "capture.h"
 #include "control.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/line6/variax.c linux-libre-2.6.34-gnu1/drivers/staging/line6/variax.c
--- linux-libre-2.6.33-gnu1/drivers/staging/line6/variax.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/line6/variax.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,8 @@
 
 #include "driver.h"
 
+#include <linux/slab.h>
+
 #include "audio.h"
 #include "control.h"
 #include "variax.h"
@@ -254,7 +256,7 @@ static ssize_t variax_set_active(struct
 	if (ret)
 		return ret;
 
-	variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value ? 1: 0;
+	variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value ? 1 : 0;
 	line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
 				     sizeof(variax_activate));
 	return count;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/Makefile linux-libre-2.6.34-gnu1/drivers/staging/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -18,18 +18,14 @@ obj-$(CONFIG_RT2870)		+= rt2870/
 obj-$(CONFIG_COMEDI)		+= comedi/
 obj-$(CONFIG_ASUS_OLED)		+= asus_oled/
 obj-$(CONFIG_PANEL)		+= panel/
-obj-$(CONFIG_ALTERA_PCIE_CHDMA)	+= altpciechdma/
 obj-$(CONFIG_R8187SE)		+= rtl8187se/
 obj-$(CONFIG_RTL8192SU)		+= rtl8192su/
 obj-$(CONFIG_RTL8192U)		+= rtl8192u/
 obj-$(CONFIG_RTL8192E)		+= rtl8192e/
-obj-$(CONFIG_INPUT_MIMIO)	+= mimio/
 obj-$(CONFIG_TRANZPORT)		+= frontier/
 obj-$(CONFIG_DREAM)		+= dream/
 obj-$(CONFIG_POHMELFS)		+= pohmelfs/
-obj-$(CONFIG_B3DFG)		+= b3dfg/
 obj-$(CONFIG_IDE_PHISON)	+= phison/
-obj-$(CONFIG_PLAN9AUTH)		+= p9auth/
 obj-$(CONFIG_LINE6_USB)		+= line6/
 obj-$(CONFIG_USB_SERIAL_QUATECH2)	+= serqt_usb2/
 obj-$(CONFIG_USB_SERIAL_QUATECH_USB2)	+= quatech_usb2/
@@ -39,7 +35,7 @@ obj-$(CONFIG_VT6656)		+= vt6656/
 obj-$(CONFIG_FB_UDL)		+= udlfb/
 obj-$(CONFIG_HYPERV)		+= hv/
 obj-$(CONFIG_VME_BUS)		+= vme/
-obj-$(CONFIG_RAR_REGISTER)	+= rar/
+obj-$(CONFIG_RAR_REGISTER)	+= rar_register/
 obj-$(CONFIG_DX_SEP)		+= sep/
 obj-$(CONFIG_IIO)		+= iio/
 obj-$(CONFIG_RAMZSWAP)		+= ramzswap/
@@ -53,3 +49,5 @@ obj-$(CONFIG_WAVELAN)		+= wavelan/
 obj-$(CONFIG_PCMCIA_WAVELAN)	+= wavelan/
 obj-$(CONFIG_PCMCIA_NETWAVE)	+= netwave/
 obj-$(CONFIG_FB_SM7XX)		+= sm7xx/
+obj-$(CONFIG_DT3155)		+= dt3155/
+obj-$(CONFIG_CRYSTALHD)		+= crystalhd/
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/mimio/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/mimio/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/mimio/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/mimio/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,10 +0,0 @@
-config INPUT_MIMIO
-	tristate "Mimio Xi interactive whiteboard support"
-	depends on USB && INPUT
-	default N
-	help
-	  Say Y here if you want to use a Mimio Xi interactive
-	  whiteboard device.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called mimio.
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/mimio/Makefile linux-libre-2.6.34-gnu1/drivers/staging/mimio/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/mimio/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/mimio/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-obj-$(CONFIG_INPUT_MIMIO)	+= mimio.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/mimio/mimio.c linux-libre-2.6.34-gnu1/drivers/staging/mimio/mimio.c
--- linux-libre-2.6.33-gnu1/drivers/staging/mimio/mimio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/mimio/mimio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,914 +0,0 @@
-/*
- * Hardware event => input event mapping:
- *
- *
- *
- input.h:#define BTN_TOOL_PEN            0x140 black
- input.h:#define BTN_TOOL_RUBBER         0x141 blue
- input.h:#define BTN_TOOL_BRUSH          0x142 green
- input.h:#define BTN_TOOL_PENCIL         0x143 red
- input.h:#define BTN_TOOL_AIRBRUSH       0x144 eraser
- input.h:#define BTN_TOOL_FINGER         0x145 small eraser
- input.h:#define BTN_TOOL_MOUSE          0x146 mimio interactive
- input.h:#define BTN_TOOL_LENS           0x147 mimio interactive but1
- input.h:#define LOCALBTN_TOOL_EXTRA1    0x14a mimio interactive but2 == BTN_TOUCH
- input.h:#define LOCALBTN_TOOL_EXTRA2    0x14b mimio extra pens (orange, brown, yellow, purple) == BTN_STYLUS
- input.h:#define LOCALBTN_TOOL_EXTRA3    0x14c unused == BTN_STYLUS2
- input.h:#define BTN_TOOL_DOUBLETAP      0x14d unused
- input.h:#define BTN_TOOL_TRIPLETAP      0x14e unused
- *
- * MIMIO_EV_PENDOWN(MIMIO_PEN_K)     => EV_KEY BIT(BTN_TOOL_PEN)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_B)     => EV_KEY BIT(BTN_TOOL_RUBBER)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_G)     => EV_KEY BIT(BTN_TOOL_BRUSH)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_R)     => EV_KEY BIT(BTN_TOOL_PENCIL)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_E)     => EV_KEY BIT(BTN_TOOL_AIRBRUSH)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_ES)    => EV_KEY BIT(BTN_TOOL_FINGER)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_I)     => EV_KEY BIT(BTN_TOOL_MOUSE)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_IL)    => EV_KEY BIT(BTN_TOOL_LENS)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_IR)    => EV_KEY BIT(BTN_TOOL_DOUBLETAP)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_EX)    => EV_KEY BIT(BTN_TOOL_TRIPLETAP)
- * MIMIO_EV_PENDATA                 => EV_ABS BIT(ABS_X), BIT(ABS_Y)
- * MIMIO_EV_MEMRESET              => EV_KEY BIT(BTN_0)
- * MIMIO_EV_ACC(ACC_NEWPAGE)       => EV_KEY BIT(BTN_1)
- * MIMIO_EV_ACC(ACC_TAGPAGE)      => EV_KEY BIT(BTN_2)
- * MIMIO_EV_ACC(ACC_PRINTPAGE)      => EV_KEY BIT(BTN_3)
- * MIMIO_EV_ACC(ACC_MAXIMIZE)      => EV_KEY BIT(BTN_4)
- * MIMIO_EV_ACC(ACC_FINDCTLPNL)      => EV_KEY BIT(BTN_5)
- *
- *
- * open issues:
- *      - cold-load of data captured when mimio in standalone mode not yet
- *         supported; need to snoop Win32 box to see datastream for this.
- *       - mimio mouse not yet supported; need to snoop Win32 box to see the
- *         datastream for this.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-
-#define DRIVER_VERSION		"v0.031"
-#define DRIVER_AUTHOR		"mwilder@cs.nmsu.edu"
-#define DRIVER_DESC		"USB mimio-xi driver"
-
-enum {UPVALUE, DOWNVALUE, MOVEVALUE};
-
-#define MIMIO_XRANGE_MAX	9600
-#define MIMIO_YRANGE_MAX	4800
-
-#define LOCALBTN_TOOL_EXTRA1	BTN_TOUCH
-#define LOCALBTN_TOOL_EXTRA2	BTN_STYLUS
-#define LOCALBTN_TOOL_EXTRA3	BTN_STYLUS2
-
-#define MIMIO_VENDOR_ID		0x08d3
-#define MIMIO_PRODUCT_ID	0x0001
-#define MIMIO_MAXPAYLOAD	(8)
-#define MIMIO_MAXNAMELEN	(64)
-#define MIMIO_TXWAIT		(1)
-#define MIMIO_TXDONE		(2)
-
-#define MIMIO_EV_PENDOWN	(0x22)
-#define MIMIO_EV_PENDATA	(0x24)
-#define MIMIO_EV_PENUP		(0x51)
-#define MIMIO_EV_MEMRESET	(0x45)
-#define MIMIO_EV_ACC		(0xb2)
-
-#define MIMIO_PEN_K		(1)	/* black pen */
-#define MIMIO_PEN_B		(2)	/* blue pen */
-#define MIMIO_PEN_G		(3)	/* green pen */
-#define MIMIO_PEN_R		(4)	/* red pen */
-/* 5, 6, 7, 8 are extra pens */
-#define MIMIO_PEN_E		(9)	/* big eraser */
-#define MIMIO_PEN_ES		(10)	/* lil eraser */
-#define MIMIO_PENJUMP_START	(10)
-#define MIMIO_PENJUMP		(6)
-#define MIMIO_PEN_I		(17)	/* mimio interactive */
-#define MIMIO_PEN_IL		(18)	/* mimio interactive button 1 */
-#define MIMIO_PEN_IR		(19)	/* mimio interactive button 2 */
-
-#define MIMIO_PEN_MAX		(MIMIO_PEN_IR)
-
-#define ACC_DONE		(0)
-#define ACC_NEWPAGE		(1)
-#define ACC_TAGPAGE		(2)
-#define ACC_PRINTPAGE		(4)
-#define ACC_MAXIMIZE		(8)
-#define ACC_FINDCTLPNL		(16)
-
-#define isvalidtxsize(n)	((n) > 0 && (n) <= MIMIO_MAXPAYLOAD)
-
-
-struct pktbuf {
-	unsigned char instr;
-	unsigned char buf[16];
-	unsigned char *p;
-	unsigned char *q;
-};
-
-struct usbintendpt {
-	dma_addr_t dma;
-	struct urb *urb;
-	unsigned char *buf;
-	struct usb_endpoint_descriptor *desc;
-};
-
-struct mimio {
-	struct input_dev *idev;
-	struct usb_device *udev;
-	struct usb_interface *uifc;
-	int open;
-	int present;
-	int greeted;
-	int txflags;
-	char phys[MIMIO_MAXNAMELEN];
-	struct usbintendpt in;
-	struct usbintendpt out;
-	struct pktbuf pktbuf;
-	unsigned char minor;
-	wait_queue_head_t waitq;
-	spinlock_t txlock;
-	void (*rxhandler)(struct mimio *, unsigned char *, unsigned int);
-	int last_pen_down;
-};
-
-static void mimio_close(struct input_dev *);
-static void mimio_dealloc(struct mimio *);
-static void mimio_disconnect(struct usb_interface *);
-static int mimio_greet(struct mimio *);
-static void mimio_irq_in(struct urb *);
-static void mimio_irq_out(struct urb *);
-static int mimio_open(struct input_dev *);
-static int mimio_probe(struct usb_interface *, const struct usb_device_id *);
-static void mimio_rx_handler(struct mimio *, unsigned char *, unsigned int);
-static int mimio_tx(struct mimio *, const char *, int);
-
-static char mimio_name[] = "VirtualInk mimio-Xi";
-static struct usb_device_id mimio_table [] = {
-	{ USB_DEVICE(MIMIO_VENDOR_ID, MIMIO_PRODUCT_ID) },
-	{ USB_DEVICE(0x0525, 0xa4a0) }, /* gadget zero firmware */
-	{ }
-};
-
-MODULE_DEVICE_TABLE(usb, mimio_table);
-
-static struct usb_driver mimio_driver = {
-	.name = "mimio",
-	.probe = mimio_probe,
-	.disconnect = mimio_disconnect,
-	.id_table = mimio_table,
-};
-
-static DECLARE_MUTEX(disconnect_sem);
-
-static void mimio_close(struct input_dev *idev)
-{
-	struct mimio *mimio;
-
-	mimio = input_get_drvdata(idev);
-	if (!mimio) {
-		dev_err(&idev->dev, "null mimio attached to input device\n");
-		return;
-	}
-
-	if (mimio->open <= 0)
-		dev_err(&idev->dev, "mimio not open.\n");
-	else
-		mimio->open--;
-
-	if (mimio->present == 0 && mimio->open == 0)
-		mimio_dealloc(mimio);
-}
-
-static void mimio_dealloc(struct mimio *mimio)
-{
-	if (mimio == NULL)
-		return;
-
-	usb_kill_urb(mimio->in.urb);
-
-	usb_kill_urb(mimio->out.urb);
-
-	if (mimio->idev) {
-		input_unregister_device(mimio->idev);
-		if (mimio->idev->grab)
-			input_close_device(mimio->idev->grab);
-		else
-			dev_dbg(&mimio->idev->dev, "mimio->idev->grab == NULL"
-				" -- didn't call input_close_device\n");
-	}
-
-	usb_free_urb(mimio->in.urb);
-
-	usb_free_urb(mimio->out.urb);
-
-	if (mimio->in.buf) {
-		usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->in.buf,
-				mimio->in.dma);
-	}
-
-	if (mimio->out.buf)
-		usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->out.buf,
-				mimio->out.dma);
-
-	if (mimio->idev)
-		input_free_device(mimio->idev);
-
-	kfree(mimio);
-}
-
-static void mimio_disconnect(struct usb_interface *ifc)
-{
-	struct mimio *mimio;
-
-	down(&disconnect_sem);
-
-	mimio = usb_get_intfdata(ifc);
-	usb_set_intfdata(ifc, NULL);
-	dev_dbg(&mimio->idev->dev, "disconnect\n");
-
-	if (mimio) {
-		mimio->present = 0;
-
-		if (mimio->open <= 0)
-			mimio_dealloc(mimio);
-	}
-
-	up(&disconnect_sem);
-}
-
-static int mimio_greet(struct mimio *mimio)
-{
-	const struct grtpkt {
-		int nbytes;
-		unsigned delay;
-		char data[8];
-	} grtpkts[] = {
-		{ 3, 0, { 0x11, 0x55, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00 } },
-		{ 5, 0, { 0x53, 0x55, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00 } },
-		{ 5, 0, { 0x43, 0x55, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00 } },
-		{ 5, 0, { 0x33, 0x55, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00 } },
-		{ 5, 0, { 0x13, 0x00, 0x5e, 0x02, 0x4f, 0x00, 0x00, 0x00 } },
-		{ 5, 0, { 0x13, 0x00, 0x04, 0x03, 0x14, 0x00, 0x00, 0x00 } },
-		{ 5, 2, { 0x13, 0x00, 0x00, 0x04, 0x17, 0x00, 0x00, 0x00 } },
-		{ 5, 0, { 0x13, 0x00, 0x0d, 0x08, 0x16, 0x00, 0x00, 0x00 } },
-		{ 5, 0, { 0x13, 0x00, 0x4d, 0x01, 0x5f, 0x00, 0x00, 0x00 } },
-		{ 3, 0, { 0xf1, 0x55, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00 } },
-		{ 7, 2, { 0x52, 0x55, 0x00, 0x07, 0x31, 0x55, 0x64, 0x00 } },
-		{ 0, 0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
-	};
-	int rslt;
-	const struct grtpkt *pkt;
-
-	for (pkt = grtpkts; pkt->nbytes; pkt++) {
-		rslt = mimio_tx(mimio, pkt->data, pkt->nbytes);
-		if (rslt)
-			return rslt;
-		if (pkt->delay)
-			msleep(pkt->delay);
-	}
-
-	return 0;
-}
-
-static void mimio_irq_in(struct urb *urb)
-{
-	int rslt;
-	char *data;
-	const char *reason = "going down";
-	struct mimio *mimio;
-
-	mimio = urb->context;
-
-	if (mimio == NULL)
-		/* paranoia */
-		return;
-
-	switch (urb->status) {
-	case 0:
-		/* success */
-		break;
-	case -ETIMEDOUT:
-		reason = "timeout -- unplugged?";
-	case -ECONNRESET:
-	case -ENOENT:
-	case -ESHUTDOWN:
-		dev_dbg(&mimio->idev->dev, "%s.\n", reason);
-		return;
-	default:
-		dev_dbg(&mimio->idev->dev, "unknown urb-status: %d.\n",
-			urb->status);
-		goto exit;
-	}
-	data = mimio->in.buf;
-
-	if (mimio->rxhandler)
-		mimio->rxhandler(mimio, data, urb->actual_length);
-exit:
-	/*
-	 * Keep listening to device on same urb.
-	 */
-	rslt = usb_submit_urb(urb, GFP_ATOMIC);
-	if (rslt)
-		dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n",
-			rslt);
-}
-
-static void mimio_irq_out(struct urb *urb)
-{
-	unsigned long flags;
-	struct mimio *mimio;
-
-	mimio = urb->context;
-
-	if (urb->status)
-		dev_dbg(&mimio->idev->dev, "urb-status: %d.\n", urb->status);
-
-	spin_lock_irqsave(&mimio->txlock, flags);
-	mimio->txflags |= MIMIO_TXDONE;
-	spin_unlock_irqrestore(&mimio->txlock, flags);
-	wmb();
-	wake_up(&mimio->waitq);
-}
-
-static int mimio_open(struct input_dev *idev)
-{
-	int rslt;
-	struct mimio *mimio;
-
-	rslt = 0;
-	down(&disconnect_sem);
-	mimio = input_get_drvdata(idev);
-	dev_dbg(&idev->dev, "mimio_open\n");
-
-	if (mimio == NULL) {
-		dev_err(&idev->dev, "null mimio.\n");
-		rslt = -ENODEV;
-		goto exit;
-	}
-
-	if (mimio->open++)
-		goto exit;
-
-	if (mimio->present && !mimio->greeted) {
-		struct urb *urb = mimio->in.urb;
-		mimio->in.urb->dev = mimio->udev;
-		rslt = usb_submit_urb(mimio->in.urb, GFP_KERNEL);
-		if (rslt) {
-			dev_err(&idev->dev, "usb_submit_urb failure "
-				"(res = %d: %s). Not greeting.\n",
-				rslt,
-				(!urb ? "urb is NULL" :
-				 (urb->hcpriv ? "urb->hcpriv is non-NULL" :
-				  (!urb->complete ? "urb is not complete" :
-				   (urb->number_of_packets <= 0 ? "urb has no packets" :
-				    (urb->interval <= 0 ? "urb interval too small" :
-				     "urb interval too large or some other error"))))));
-			rslt = -EIO;
-			goto exit;
-		}
-		rslt = mimio_greet(mimio);
-		if (rslt == 0) {
-			dev_dbg(&idev->dev, "Mimio greeted OK.\n");
-			mimio->greeted = 1;
-		} else {
-			dev_dbg(&idev->dev, "Mimio greet Failure (%d)\n",
-				rslt);
-		}
-	}
-
-exit:
-	up(&disconnect_sem);
-	return rslt;
-}
-
-static int mimio_probe(struct usb_interface *ifc,
-		       const struct usb_device_id *id)
-{
-	char path[64];
-	int pipe, maxp;
-	struct mimio *mimio;
-	struct usb_device *udev;
-	struct usb_host_interface *hostifc;
-	struct input_dev *input_dev;
-	int res = 0;
-	int i;
-
-	udev = interface_to_usbdev(ifc);
-
-	mimio = kzalloc(sizeof(struct mimio), GFP_KERNEL);
-	if (!mimio)
-		return -ENOMEM;
-
-	input_dev = input_allocate_device();
-	if (!input_dev) {
-		mimio_dealloc(mimio);
-		return -ENOMEM;
-	}
-
-	mimio->uifc = ifc;
-	mimio->udev = udev;
-	mimio->pktbuf.p = mimio->pktbuf.buf;
-	mimio->pktbuf.q = mimio->pktbuf.buf;
-	/* init_input_dev(mimio->idev); */
-	mimio->idev = input_dev;
-	init_waitqueue_head(&mimio->waitq);
-	spin_lock_init(&mimio->txlock);
-	hostifc = ifc->cur_altsetting;
-
-	if (hostifc->desc.bNumEndpoints != 2) {
-		dev_err(&udev->dev, "Unexpected endpoint count: %d.\n",
-			hostifc->desc.bNumEndpoints);
-		mimio_dealloc(mimio);
-		return -ENODEV;
-	}
-
-	mimio->in.desc = &(hostifc->endpoint[0].desc);
-	mimio->out.desc = &(hostifc->endpoint[1].desc);
-
-	mimio->in.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL,
-					 &mimio->in.dma);
-	mimio->out.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL,
-					  &mimio->out.dma);
-
-	if (mimio->in.buf == NULL || mimio->out.buf == NULL) {
-		dev_err(&udev->dev, "usb_buffer_alloc failure.\n");
-		mimio_dealloc(mimio);
-		return -ENOMEM;
-	}
-
-	mimio->in.urb = usb_alloc_urb(0, GFP_KERNEL);
-	mimio->out.urb = usb_alloc_urb(0, GFP_KERNEL);
-
-	if (mimio->in.urb == NULL || mimio->out.urb == NULL) {
-		dev_err(&udev->dev, "usb_alloc_urb failure.\n");
-		mimio_dealloc(mimio);
-		return -ENOMEM;
-	}
-
-	/*
-	 * Build the input urb.
-	 */
-	pipe = usb_rcvintpipe(udev, mimio->in.desc->bEndpointAddress);
-	maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
-	if (maxp > MIMIO_MAXPAYLOAD)
-		maxp = MIMIO_MAXPAYLOAD;
-	usb_fill_int_urb(mimio->in.urb, udev, pipe, mimio->in.buf, maxp,
-			 mimio_irq_in, mimio, mimio->in.desc->bInterval);
-	mimio->in.urb->transfer_dma = mimio->in.dma;
-	mimio->in.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
-	/*
-	 * Build the output urb.
-	 */
-	pipe = usb_sndintpipe(udev, mimio->out.desc->bEndpointAddress);
-	maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
-	if (maxp > MIMIO_MAXPAYLOAD)
-		maxp = MIMIO_MAXPAYLOAD;
-	usb_fill_int_urb(mimio->out.urb, udev, pipe, mimio->out.buf, maxp,
-			 mimio_irq_out, mimio, mimio->out.desc->bInterval);
-	mimio->out.urb->transfer_dma = mimio->out.dma;
-	mimio->out.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
-	/*
-	 * Build input device info
-	 */
-	usb_make_path(udev, path, 64);
-	snprintf(mimio->phys, MIMIO_MAXNAMELEN, "%s/input0", path);
-	input_set_drvdata(input_dev, mimio);
-	/* input_dev->dev = &ifc->dev; */
-	input_dev->open = mimio_open;
-	input_dev->close = mimio_close;
-	input_dev->name = mimio_name;
-	input_dev->phys = mimio->phys;
-	input_dev->dev.parent = &ifc->dev;
-
-	input_dev->id.bustype = BUS_USB;
-	input_dev->id.vendor = le16_to_cpu(udev->descriptor.idVendor);
-	input_dev->id.product = le16_to_cpu(udev->descriptor.idProduct);
-	input_dev->id.version = le16_to_cpu(udev->descriptor.bcdDevice);
-
-	input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
-	for (i = BTN_TOOL_PEN; i <= LOCALBTN_TOOL_EXTRA2; ++i)
-		set_bit(i, input_dev->keybit);
-
-	input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) |
-						 BIT_MASK(BTN_1) |
-						 BIT_MASK(BTN_2) |
-						 BIT_MASK(BTN_3) |
-						 BIT_MASK(BTN_4) |
-						 BIT_MASK(BTN_5);
-	/*   input_dev->keybit[BTN_MOUSE] |= BIT(BTN_LEFT); */
-	input_dev->absbit[0] |= BIT_MASK(ABS_X) | BIT_MASK(ABS_Y);
-	input_set_abs_params(input_dev, ABS_X, 0, MIMIO_XRANGE_MAX, 0, 0);
-	input_set_abs_params(input_dev, ABS_Y, 0, MIMIO_YRANGE_MAX, 0, 0);
-	input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
-
-#if 0
-	input_dev->absmin[ABS_X] = 0;
-	input_dev->absmin[ABS_Y] = 0;
-	input_dev->absmax[ABS_X] = 9600;
-	input_dev->absmax[ABS_Y] = 4800;
-	input_dev->absfuzz[ABS_X] = 0;
-	input_dev->absfuzz[ABS_Y] = 0;
-	input_dev->absflat[ABS_X] = 0;
-	input_dev->absflat[ABS_Y] = 0;
-#endif
-
-#if 0
-	/* this will just reduce the precision */
-	input_dev->absfuzz[ABS_X] = 8; /* experimental; may need to change */
-	input_dev->absfuzz[ABS_Y] = 8; /* experimental; may need to change */
-#endif
-
-	/*
-	 * Register the input device.
-	 */
-	res = input_register_device(mimio->idev);
-	if (res) {
-		dev_err(&udev->dev, "input_register_device failure (%d)\n",
-			res);
-		mimio_dealloc(mimio);
-		return -EIO;
-	}
-	dev_dbg(&mimio->idev->dev, "input: %s on %s (res = %d).\n",
-		input_dev->name, input_dev->phys, res);
-
-	usb_set_intfdata(ifc, mimio);
-	mimio->present = 1;
-
-	/*
-	 * Submit the input urb to the usb subsystem.
-	 */
-	mimio->in.urb->dev = mimio->udev;
-	res = usb_submit_urb(mimio->in.urb, GFP_KERNEL);
-	if (res) {
-		dev_err(&mimio->idev->dev, "usb_submit_urb failure (%d)\n",
-			res);
-		mimio_dealloc(mimio);
-		return -EIO;
-	}
-
-	/*
-	 * Attempt to greet the mimio after giving
-	 * it some post-init settling time.
-	 *
-	 * note: sometimes this sleep interval isn't
-	 * long enough to permit the device to re-init
-	 * after a hot-swap; maybe need to bump it up.
-	 *
-	 * As it is, this probably breaks module unloading support!
-	 */
-	msleep(1024);
-
-	res = mimio_greet(mimio);
-	if (res == 0) {
-		dev_dbg(&mimio->idev->dev, "Mimio greeted OK.\n");
-		mimio->greeted = 1;
-		mimio->rxhandler = mimio_rx_handler;
-	} else {
-		dev_dbg(&mimio->idev->dev, "Mimio greet Failure (%d)\n", res);
-	}
-
-	return 0;
-}
-
-static int handle_mimio_rx_penupdown(struct mimio *mimio,
-				     int down,
-				     const char *const instr[],
-				     const int instr_ofst[])
-{
-	int penid, x;
-	if (mimio->pktbuf.q - mimio->pktbuf.p < (down ? 4 : 3))
-		return 1; 		/* partial pkt */
-
-	if (down) {
-		x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^
-			*(mimio->pktbuf.p + 2);
-		if (x != *(mimio->pktbuf.p + 3)) {
-			dev_dbg(&mimio->idev->dev, "EV_PEN%s: bad xsum.\n",
-				down ? "DOWN":"UP");
-			/* skip this event data */
-			mimio->pktbuf.p += 4;
-			/* decode any remaining events */
-			return 0;
-		}
-		penid = mimio->pktbuf.instr = *(mimio->pktbuf.p + 2);
-		if (penid > MIMIO_PEN_MAX) {
-			dev_dbg(&mimio->idev->dev,
-				"Unmapped penID (not in [0, %d]): %d\n",
-				MIMIO_PEN_MAX, (int)mimio->pktbuf.instr);
-			penid = mimio->pktbuf.instr = 0;
-		}
-		mimio->last_pen_down = penid;
-	} else {
-		penid = mimio->last_pen_down;
-	}
-	dev_dbg(&mimio->idev->dev, "%s (id %d, code %d) %s.\n", instr[penid],
-		instr_ofst[penid], penid, down ? "down" : "up");
-
-	if (instr_ofst[penid] >= 0) {
-		int code = BTN_TOOL_PEN + instr_ofst[penid];
-		int value = down ? DOWNVALUE : UPVALUE;
-		if (code > KEY_MAX)
-			dev_dbg(&mimio->idev->dev, "input_event will ignore "
-				"-- code (%d) > KEY_MAX\n", code);
-		if (!test_bit(code, mimio->idev->keybit))
-			dev_dbg(&mimio->idev->dev, "input_event will ignore "
-				"-- bit for code (%d) not enabled\n", code);
-		if (!!test_bit(code, mimio->idev->key) == value)
-			dev_dbg(&mimio->idev->dev, "input_event will ignore "
-				"-- bit for code (%d) already set to %d\n",
-				code, value);
-		if (value != DOWNVALUE) {
-			/* input_regs(mimio->idev, regs); */
-			input_report_key(mimio->idev, code, value);
-			input_sync(mimio->idev);
-		} else {
-			/* wait until we get some coordinates */
-		}
-	} else {
-		dev_dbg(&mimio->idev->dev, "penID offset[%d] == %d is < 0 "
-			"- not sending\n", penid, instr_ofst[penid]);
-	}
-	mimio->pktbuf.p += down ? 4 : 3; /* 3 for up, 4 for down */
-	return 0;
-}
-
-/*
- * Stay tuned for partial-packet excitement.
- *
- * This routine buffers data packets received from the mimio device
- * in the mimio's data space.  This buffering is necessary because
- * the mimio's in endpoint can serve us partial packets of data, and
- * we want the driver to support the servicing of multiple mimios.
- * Empirical evidence gathered so far suggests that the method of
- * buffering packet data in the mimio's data space works.  Previous
- * versions of this driver did not buffer packet data in each mimio's
- * data-space, and were therefore not able to service multiple mimios.
- * Note that since the caller of this routine is running in interrupt
- * context, care needs to be taken to ensure that this routine does not
- * become bloated, and it may be that another spinlock is needed in each
- * mimio to guard the buffered packet data properly.
- */
-static void mimio_rx_handler(struct mimio *mimio,
-			     unsigned char *data,
-			     unsigned int nbytes)
-{
-	struct device *dev = &mimio->idev->dev;
-	unsigned int x;
-	unsigned int y;
-	static const char * const instr[] = {
-		"?0",
-		"black pen", "blue pen", "green pen", "red pen",
-		"brown pen", "orange pen", "purple pen", "yellow pen",
-		"big eraser", "lil eraser",
-		"?11", "?12", "?13", "?14", "?15", "?16",
-		"mimio interactive", "interactive button1",
-		"interactive button2"
-	};
-
-	/* Mimio Interactive gives:
-	 * down: [0x22 0x01 0x11 0x32 0x24]
-	 * b1  : [0x22 0x01 0x12 0x31 0x24]
-	 * b2  : [0x22 0x01 0x13 0x30 0x24]
-	 */
-	static const int instr_ofst[] = {
-		-1,
-		0, 1, 2, 3,
-		9, 9, 9, 9,
-		4, 5,
-		-1, -1, -1, -1, -1, -1,
-		6, 7, 8,
-	};
-
-	memcpy(mimio->pktbuf.q, data, nbytes);
-	mimio->pktbuf.q += nbytes;
-
-	while (mimio->pktbuf.p < mimio->pktbuf.q) {
-		int t = *mimio->pktbuf.p;
-		switch (t) {
-		case MIMIO_EV_PENUP:
-		case MIMIO_EV_PENDOWN:
-			if (handle_mimio_rx_penupdown(mimio,
-						      t == MIMIO_EV_PENDOWN,
-						      instr, instr_ofst))
-				return; /* partial packet */
-			break;
-
-		case MIMIO_EV_PENDATA:
-			if (mimio->pktbuf.q - mimio->pktbuf.p < 6)
-				/* partial pkt */
-				return;
-			x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^
-				*(mimio->pktbuf.p + 2) ^
-				*(mimio->pktbuf.p + 3) ^
-				*(mimio->pktbuf.p + 4);
-			if (x != *(mimio->pktbuf.p + 5)) {
-				dev_dbg(dev, "EV_PENDATA: bad xsum.\n");
-				mimio->pktbuf.p += 6; /* skip this event data */
-				break; /* decode any remaining events */
-			}
-			x = *(mimio->pktbuf.p + 1);
-			x <<= 8;
-			x |= *(mimio->pktbuf.p + 2);
-			y = *(mimio->pktbuf.p + 3);
-			y <<= 8;
-			y |= *(mimio->pktbuf.p + 4);
-			dev_dbg(dev, "coord: (%d, %d)\n", x, y);
-			if (instr_ofst[mimio->pktbuf.instr] >= 0) {
-				int code = BTN_TOOL_PEN +
-					   instr_ofst[mimio->last_pen_down];
-#if 0
-				/* Utter hack to ensure we get forwarded _AND_
-				 * so we can identify when a complete signal is
-				 * received */
-				mimio->idev->abs[ABS_Y] = -1;
-				mimio->idev->abs[ABS_X] = -1;
-#endif
-				/* input_regs(mimio->idev, regs); */
-				input_report_abs(mimio->idev, ABS_X, x);
-				input_report_abs(mimio->idev, ABS_Y, y);
-				/* fake a penup */
-				change_bit(code, mimio->idev->key);
-				input_report_key(mimio->idev,
-						 code,
-						 DOWNVALUE);
-				/* always sync here */
-				mimio->idev->sync = 0;
-				input_sync(mimio->idev);
-			}
-			mimio->pktbuf.p += 6;
-			break;
-		case MIMIO_EV_MEMRESET:
-			if (mimio->pktbuf.q - mimio->pktbuf.p < 7)
-				/* partial pkt */
-				return;
-			dev_dbg(dev, "mem-reset.\n");
-			/* input_regs(mimio->idev, regs); */
-			input_event(mimio->idev, EV_KEY, BTN_0, 1);
-			input_event(mimio->idev, EV_KEY, BTN_0, 0);
-			input_sync(mimio->idev);
-			mimio->pktbuf.p += 7;
-			break;
-		case MIMIO_EV_ACC:
-			if (mimio->pktbuf.q - mimio->pktbuf.p < 4)
-				/* partial pkt */
-				return;
-			x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^
-				*(mimio->pktbuf.p + 2);
-			if (x != *(mimio->pktbuf.p + 3)) {
-				dev_dbg(dev, "EV_ACC: bad xsum.\n");
-				mimio->pktbuf.p += 4; /* skip this event data */
-				break; /* decode any remaining events */
-			}
-			switch (*(mimio->pktbuf.p + 2)) {
-			case ACC_NEWPAGE:
-				dev_dbg(&mimio->idev->dev, "new-page.\n");
-				/* input_regs(mimio->idev, regs); */
-				input_event(mimio->idev, EV_KEY, BTN_1, 1);
-				input_event(mimio->idev, EV_KEY, BTN_1, 0);
-				input_sync(mimio->idev);
-				break;
-			case ACC_TAGPAGE:
-				dev_dbg(&mimio->idev->dev, "tag-page.\n");
-				/* input_regs(mimio->idev, regs); */
-				input_event(mimio->idev, EV_KEY, BTN_2, 1);
-				input_event(mimio->idev, EV_KEY, BTN_2, 0);
-				input_sync(mimio->idev);
-				break;
-			case ACC_PRINTPAGE:
-				dev_dbg(&mimio->idev->dev, "print-page.\n");
-				/* input_regs(mimio->idev, regs);*/
-				input_event(mimio->idev, EV_KEY, BTN_3, 1);
-				input_event(mimio->idev, EV_KEY, BTN_3, 0);
-				input_sync(mimio->idev);
-				break;
-			case ACC_MAXIMIZE:
-				dev_dbg(&mimio->idev->dev,
-					"maximize-window.\n");
-				/* input_regs(mimio->idev, regs); */
-				input_event(mimio->idev, EV_KEY, BTN_4, 1);
-				input_event(mimio->idev, EV_KEY, BTN_4, 0);
-				input_sync(mimio->idev);
-				break;
-			case ACC_FINDCTLPNL:
-				dev_dbg(&mimio->idev->dev, "find-ctl-panel.\n");
-				/* input_regs(mimio->idev, regs); */
-				input_event(mimio->idev, EV_KEY, BTN_5, 1);
-				input_event(mimio->idev, EV_KEY, BTN_5, 0);
-				input_sync(mimio->idev);
-				break;
-			case ACC_DONE:
-				dev_dbg(&mimio->idev->dev, "acc-done.\n");
-				/* no event is dispatched to the input
-				 * subsystem for this device event.
-				 */
-				break;
-			default:
-				dev_dbg(dev, "unknown acc event.\n");
-				break;
-			}
-			mimio->pktbuf.p += 4;
-			break;
-		default:
-			mimio->pktbuf.p++;
-			break;
-		}
-	}
-
-	/*
-	 * No partial event was received, so reset mimio's pktbuf ptrs.
-	 */
-	mimio->pktbuf.p = mimio->pktbuf.q = mimio->pktbuf.buf;
-}
-
-static int mimio_tx(struct mimio *mimio, const char *buf, int nbytes)
-{
-	int rslt;
-	int timeout;
-	unsigned long flags;
-	DECLARE_WAITQUEUE(wait, current);
-
-	if (!(isvalidtxsize(nbytes))) {
-		dev_err(&mimio->idev->dev, "invalid arg: nbytes: %d.\n",
-			nbytes);
-		return -EINVAL;
-	}
-
-	/*
-	 * Init the out urb and copy the data to send.
-	 */
-	mimio->out.urb->dev = mimio->udev;
-	mimio->out.urb->transfer_buffer_length = nbytes;
-	memcpy(mimio->out.urb->transfer_buffer, buf, nbytes);
-
-	/*
-	 * Send the data.
-	 */
-	spin_lock_irqsave(&mimio->txlock, flags);
-	mimio->txflags = MIMIO_TXWAIT;
-	rslt = usb_submit_urb(mimio->out.urb, GFP_ATOMIC);
-	spin_unlock_irqrestore(&mimio->txlock, flags);
-	dev_dbg(&mimio->idev->dev, "rslt: %d.\n", rslt);
-
-	if (rslt) {
-		dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n",
-			rslt);
-		return rslt;
-	}
-
-	/*
-	 * Wait for completion to be signalled (the mimio_irq_out
-	 * completion routine will or MIMIO_TXDONE in with txflags).
-	 */
-	timeout = HZ;
-	set_current_state(TASK_INTERRUPTIBLE);
-	add_wait_queue(&mimio->waitq, &wait);
-
-	while (timeout && ((mimio->txflags & MIMIO_TXDONE) == 0)) {
-		timeout = schedule_timeout(timeout);
-		rmb();
-	}
-
-	if ((mimio->txflags & MIMIO_TXDONE) == 0)
-		dev_dbg(&mimio->idev->dev, "tx timed out.\n");
-
-	/*
-	 * Now that completion has been signalled,
-	 * unlink the urb so that it can be recycled.
-	 */
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&mimio->waitq, &wait);
-	usb_unlink_urb(mimio->out.urb);
-
-	return rslt;
-}
-
-static int __init mimio_init(void)
-{
-	int rslt;
-
-	rslt = usb_register(&mimio_driver);
-	if (rslt != 0) {
-		err("%s: usb_register failure: %d", __func__, rslt);
-		return rslt;
-	}
-
-	printk(KERN_INFO KBUILD_MODNAME ":"
-	       DRIVER_DESC " " DRIVER_VERSION "\n");
-	return rslt;
-}
-
-static void __exit mimio_exit(void)
-{
-	usb_deregister(&mimio_driver);
-}
-
-module_init(mimio_init);
-module_exit(mimio_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/netwave/netwave_cs.c linux-libre-2.6.34-gnu1/drivers/staging/netwave/netwave_cs.c
--- linux-libre-2.6.33-gnu1/drivers/staging/netwave/netwave_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/netwave/netwave_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -46,7 +46,6 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/errno.h>
@@ -1341,15 +1340,15 @@ static void set_multicast_list(struct ne
 #ifdef PCMCIA_DEBUG
     {
 	xstatic int old;
-	if (old != dev->mc_count) {
-	    old = dev->mc_count;
+	if (old != netdev_mc_count(dev)) {
+	    old = netdev_mc_count(dev);
 	    pr_debug("%s: setting Rx mode to %d addresses.\n",
-		  dev->name, dev->mc_count);
+		  dev->name, netdev_mc_count(dev));
 	}
     }
 #endif
 	
-    if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) {
+    if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI)) {
 	/* Multicast Mode */
 	rcvMode = rxConfRxEna + rxConfAMP + rxConfBcast;
     } else if (dev->flags & IFF_PROMISC) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/cvmx-helper-board.c linux-libre-2.6.34-gnu1/drivers/staging/octeon/cvmx-helper-board.c
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/cvmx-helper-board.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/cvmx-helper-board.c	2010-05-16 17:17:36.000000000 -0400
@@ -153,6 +153,14 @@ int cvmx_helper_board_get_mii_address(in
 		 * through switch.
 		 */
 		return -1;
+
+	case CVMX_BOARD_TYPE_CUST_WSX16:
+		if (ipd_port >= 0 && ipd_port <= 3)
+			return ipd_port;
+		else if (ipd_port >= 16 && ipd_port <= 19)
+			return ipd_port - 16 + 4;
+		else
+			return -1;
 	}
 
 	/* Some unknown board. Somebody forgot to update this function... */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet.c linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet.c
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,8 +29,8 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
-#include <linux/delay.h>
 #include <linux/phy.h>
+#include <linux/slab.h>
 
 #include <net/dst.h>
 
@@ -43,8 +43,6 @@
 #include "ethernet-tx.h"
 #include "ethernet-mdio.h"
 #include "ethernet-util.h"
-#include "ethernet-proc.h"
-
 
 #include "cvmx-pip.h"
 #include "cvmx-pko.h"
@@ -104,13 +102,15 @@ MODULE_PARM_DESC(pow_send_list, "\n"
 	"\t\"eth2,spi3,spi7\" would cause these three devices to transmit\n"
 	"\tusing the pow_send_group.");
 
-static int disable_core_queueing = 1;
-module_param(disable_core_queueing, int, 0444);
-MODULE_PARM_DESC(disable_core_queueing, "\n"
-	"\tWhen set the networking core's tx_queue_len is set to zero.  This\n"
-	"\tallows packets to be sent without lock contention in the packet\n"
-	"\tscheduler resulting in some cases in improved throughput.\n");
+int max_rx_cpus = -1;
+module_param(max_rx_cpus, int, 0444);
+MODULE_PARM_DESC(max_rx_cpus, "\n"
+	"\t\tThe maximum number of CPUs to use for packet reception.\n"
+	"\t\tUse -1 to use all available CPUs.");
 
+int rx_napi_weight = 32;
+module_param(rx_napi_weight, int, 0444);
+MODULE_PARM_DESC(rx_napi_weight, "The NAPI WEIGHT parameter.");
 
 /*
  * The offset from mac_addr_base that should be used for the next port
@@ -122,9 +122,16 @@ MODULE_PARM_DESC(disable_core_queueing,
 static unsigned int cvm_oct_mac_addr_offset;
 
 /**
- * Periodic timer to check auto negotiation
+ * cvm_oct_poll_queue - Workqueue for polling operations.
  */
-static struct timer_list cvm_oct_poll_timer;
+struct workqueue_struct *cvm_oct_poll_queue;
+
+/**
+ * cvm_oct_poll_queue_stopping - flag to indicate polling should stop.
+ *
+ * Set to one right before cvm_oct_poll_queue is destroyed.
+ */
+atomic_t cvm_oct_poll_queue_stopping = ATOMIC_INIT(0);
 
 /**
  * Array of every ethernet device owned by this driver indexed by
@@ -132,65 +139,44 @@ static struct timer_list cvm_oct_poll_ti
  */
 struct net_device *cvm_oct_device[TOTAL_NUMBER_OF_PORTS];
 
-/**
- * Periodic timer tick for slow management operations
- *
- * @arg:    Device to check
- */
-static void cvm_do_timer(unsigned long arg)
+u64 cvm_oct_tx_poll_interval;
+
+static void cvm_oct_rx_refill_worker(struct work_struct *work);
+static DECLARE_DELAYED_WORK(cvm_oct_rx_refill_work, cvm_oct_rx_refill_worker);
+
+static void cvm_oct_rx_refill_worker(struct work_struct *work)
 {
-	int32_t skb_to_free, undo;
-	int queues_per_port;
-	int qos;
-	struct octeon_ethernet *priv;
-	static int port;
+	/*
+	 * FPA 0 may have been drained, try to refill it if we need
+	 * more than num_packet_buffers / 2, otherwise normal receive
+	 * processing will refill it.  If it were drained, no packets
+	 * could be received so cvm_oct_napi_poll would never be
+	 * invoked to do the refill.
+	 */
+	cvm_oct_rx_refill_pool(num_packet_buffers / 2);
 
-	if (port >= CVMX_PIP_NUM_INPUT_PORTS) {
-		/*
-		 * All ports have been polled. Start the next
-		 * iteration through the ports in one second.
-		 */
-		port = 0;
-		mod_timer(&cvm_oct_poll_timer, jiffies + HZ);
-		return;
-	}
-	if (!cvm_oct_device[port])
-		goto out;
+	if (!atomic_read(&cvm_oct_poll_queue_stopping))
+		queue_delayed_work(cvm_oct_poll_queue,
+				   &cvm_oct_rx_refill_work, HZ);
+}
+
+static void cvm_oct_periodic_worker(struct work_struct *work)
+{
+	struct octeon_ethernet *priv = container_of(work,
+						    struct octeon_ethernet,
+						    port_periodic_work.work);
 
-	priv = netdev_priv(cvm_oct_device[port]);
 	if (priv->poll)
-		priv->poll(cvm_oct_device[port]);
+		priv->poll(cvm_oct_device[priv->port]);
 
-	queues_per_port = cvmx_pko_get_num_queues(port);
-	/* Drain any pending packets in the free list */
-	for (qos = 0; qos < queues_per_port; qos++) {
-		if (skb_queue_len(&priv->tx_free_list[qos]) == 0)
-			continue;
-		skb_to_free = cvmx_fau_fetch_and_add32(priv->fau + qos * 4,
-						       MAX_SKB_TO_FREE);
-		undo = skb_to_free > 0 ?
-			MAX_SKB_TO_FREE : skb_to_free + MAX_SKB_TO_FREE;
-		if (undo > 0)
-			cvmx_fau_atomic_add32(priv->fau+qos*4, -undo);
-		skb_to_free = -skb_to_free > MAX_SKB_TO_FREE ?
-			MAX_SKB_TO_FREE : -skb_to_free;
-		cvm_oct_free_tx_skbs(priv, skb_to_free, qos, 1);
-	}
-	cvm_oct_device[port]->netdev_ops->ndo_get_stats(cvm_oct_device[port]);
+	cvm_oct_device[priv->port]->netdev_ops->ndo_get_stats(cvm_oct_device[priv->port]);
 
-out:
-	port++;
-	/* Poll the next port in a 50th of a second.
-	   This spreads the polling of ports out a little bit */
-	mod_timer(&cvm_oct_poll_timer, jiffies + HZ / 50);
-}
+	if (!atomic_read(&cvm_oct_poll_queue_stopping))
+		queue_delayed_work(cvm_oct_poll_queue, &priv->port_periodic_work, HZ);
+ }
 
-/**
- * Configure common hardware for all interfaces
- */
 static __init void cvm_oct_configure_common_hw(void)
 {
-	int r;
 	/* Setup the FPA */
 	cvmx_fpa_enable();
 	cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
@@ -205,28 +191,13 @@ static __init void cvm_oct_configure_com
 		cvmx_helper_setup_red(num_packet_buffers / 4,
 				      num_packet_buffers / 8);
 
-	/* Enable the MII interface */
-	if (!octeon_is_simulation())
-		cvmx_write_csr(CVMX_SMIX_EN(0), 1);
-
-	/* Register an IRQ hander for to receive POW interrupts */
-	r = request_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group,
-			cvm_oct_do_interrupt, IRQF_SHARED, "Ethernet",
-			cvm_oct_device);
-
-#if defined(CONFIG_SMP) && 0
-	if (USE_MULTICORE_RECEIVE) {
-		irq_set_affinity(OCTEON_IRQ_WORKQ0 + pow_receive_group,
-				 cpu_online_mask);
-	}
-#endif
 }
 
 /**
- * Free a work queue entry received in a intercept callback.
+ * cvm_oct_free_work- Free a work queue entry
+ *
+ * @work_queue_entry: Work queue entry to free
  *
- * @work_queue_entry:
- *               Work queue entry to free
  * Returns Zero on success, Negative on failure.
  */
 int cvm_oct_free_work(void *work_queue_entry)
@@ -253,9 +224,9 @@ int cvm_oct_free_work(void *work_queue_e
 EXPORT_SYMBOL(cvm_oct_free_work);
 
 /**
- * Get the low level ethernet statistics
- *
+ * cvm_oct_common_get_stats - get the low level ethernet statistics
  * @dev:    Device to get the statistics from
+ *
  * Returns Pointer to the statistics
  */
 static struct net_device_stats *cvm_oct_common_get_stats(struct net_device *dev)
@@ -299,8 +270,7 @@ static struct net_device_stats *cvm_oct_
 }
 
 /**
- * Change the link MTU. Unimplemented
- *
+ * cvm_oct_common_change_mtu - change the link MTU
  * @dev:     Device to change
  * @new_mtu: The new MTU
  *
@@ -364,8 +334,7 @@ static int cvm_oct_common_change_mtu(str
 }
 
 /**
- * Set the multicast list. Currently unimplemented.
- *
+ * cvm_oct_common_set_multicast_list - set the multicast list
  * @dev:    Device to work on
  */
 static void cvm_oct_common_set_multicast_list(struct net_device *dev)
@@ -382,7 +351,7 @@ static void cvm_oct_common_set_multicast
 		control.u64 = 0;
 		control.s.bcst = 1;	/* Allow broadcast MAC addresses */
 
-		if (dev->mc_list || (dev->flags & IFF_ALLMULTI) ||
+		if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI) ||
 		    (dev->flags & IFF_PROMISC))
 			/* Force accept multicast packets */
 			control.s.mcst = 2;
@@ -420,10 +389,10 @@ static void cvm_oct_common_set_multicast
 }
 
 /**
- * Set the hardware MAC address for a device
- *
- * @dev:    Device to change the MAC address for
- * @addr:   Address structure to change it too. MAC address is addr + 2.
+ * cvm_oct_common_set_mac_address - set the hardware MAC address for a device
+ * @dev:    The device in question.
+ * @addr:   Address structure to change it too.
+
  * Returns Zero on success
  */
 static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr)
@@ -470,9 +439,9 @@ static int cvm_oct_common_set_mac_addres
 }
 
 /**
- * Per network device initialization
- *
+ * cvm_oct_common_init - per network device initialization
  * @dev:    Device to initialize
+ *
  * Returns Zero on success
  */
 int cvm_oct_common_init(struct net_device *dev)
@@ -510,8 +479,11 @@ int cvm_oct_common_init(struct net_devic
 	    && (always_use_pow || strstr(pow_send_list, dev->name)))
 		priv->queue = -1;
 
-	if (priv->queue != -1 && USE_HW_TCPUDP_CHECKSUM)
-		dev->features |= NETIF_F_IP_CSUM;
+	if (priv->queue != -1) {
+		dev->features |= NETIF_F_SG;
+		if (USE_HW_TCPUDP_CHECKSUM)
+			dev->features |= NETIF_F_IP_CSUM;
+	}
 
 	/* We do our own locking, Linux doesn't need to */
 	dev->features |= NETIF_F_LLTX;
@@ -625,12 +597,6 @@ static const struct net_device_ops cvm_o
 
 extern void octeon_mdiobus_force_mod_depencency(void);
 
-/**
- * Module/ driver initialization. Creates the linux network
- * devices.
- *
- * Returns Zero on success
- */
 static int __init cvm_oct_init_module(void)
 {
 	int num_interfaces;
@@ -648,8 +614,12 @@ static int __init cvm_oct_init_module(vo
 	else
 		cvm_oct_mac_addr_offset = 0;
 
-	cvm_oct_proc_initialize();
-	cvm_oct_rx_initialize();
+	cvm_oct_poll_queue = create_singlethread_workqueue("octeon-ethernet");
+	if (cvm_oct_poll_queue == NULL) {
+		pr_err("octeon-ethernet: Cannot create workqueue");
+		return -ENOMEM;
+	}
+
 	cvm_oct_configure_common_hw();
 
 	cvmx_helper_initialize_packet_io_global();
@@ -682,6 +652,9 @@ static int __init cvm_oct_init_module(vo
 	 */
 	cvmx_fau_atomic_write32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
 
+	/* Initialize the FAU used for counting tx SKBs that need to be freed */
+	cvmx_fau_atomic_write32(FAU_TOTAL_TX_TO_CLEAN, 0);
+
 	if ((pow_send_group != -1)) {
 		struct net_device *dev;
 		pr_info("\tConfiguring device for POW only access\n");
@@ -689,7 +662,6 @@ static int __init cvm_oct_init_module(vo
 		if (dev) {
 			/* Initialize the device private structure. */
 			struct octeon_ethernet *priv = netdev_priv(dev);
-			memset(priv, 0, sizeof(struct octeon_ethernet));
 
 			dev->netdev_ops = &cvm_oct_pow_netdev_ops;
 			priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED;
@@ -700,19 +672,16 @@ static int __init cvm_oct_init_module(vo
 				skb_queue_head_init(&priv->tx_free_list[qos]);
 
 			if (register_netdev(dev) < 0) {
-				pr_err("Failed to register ethernet "
-					 "device for POW\n");
+				pr_err("Failed to register ethernet device for POW\n");
 				kfree(dev);
 			} else {
 				cvm_oct_device[CVMX_PIP_NUM_INPUT_PORTS] = dev;
-				pr_info("%s: POW send group %d, receive "
-					"group %d\n",
-				     dev->name, pow_send_group,
-				     pow_receive_group);
+				pr_info("%s: POW send group %d, receive group %d\n",
+					dev->name, pow_send_group,
+					pow_receive_group);
 			}
 		} else {
-			pr_err("Failed to allocate ethernet device "
-				 "for POW\n");
+			pr_err("Failed to allocate ethernet device for POW\n");
 		}
 	}
 
@@ -730,17 +699,15 @@ static int __init cvm_oct_init_module(vo
 			struct net_device *dev =
 			    alloc_etherdev(sizeof(struct octeon_ethernet));
 			if (!dev) {
-				pr_err("Failed to allocate ethernet device "
-					 "for port %d\n", port);
+				pr_err("Failed to allocate ethernet device for port %d\n", port);
 				continue;
 			}
-			if (disable_core_queueing)
-				dev->tx_queue_len = 0;
 
 			/* Initialize the device private structure. */
 			priv = netdev_priv(dev);
-			memset(priv, 0, sizeof(struct octeon_ethernet));
 
+			INIT_DELAYED_WORK(&priv->port_periodic_work,
+					  cvm_oct_periodic_worker);
 			priv->imode = imode;
 			priv->port = port;
 			priv->queue = cvmx_pko_get_base_queue(priv->port);
@@ -803,44 +770,25 @@ static int __init cvm_oct_init_module(vo
 				fau -=
 				    cvmx_pko_get_num_queues(priv->port) *
 				    sizeof(uint32_t);
+				queue_delayed_work(cvm_oct_poll_queue,
+						   &priv->port_periodic_work, HZ);
 			}
 		}
 	}
 
-	if (INTERRUPT_LIMIT) {
-		/*
-		 * Set the POW timer rate to give an interrupt at most
-		 * INTERRUPT_LIMIT times per second.
-		 */
-		cvmx_write_csr(CVMX_POW_WQ_INT_PC,
-			       octeon_bootinfo->eclock_hz / (INTERRUPT_LIMIT *
-							     16 * 256) << 8);
+	cvm_oct_tx_initialize();
+	cvm_oct_rx_initialize();
 
-		/*
-		 * Enable POW timer interrupt. It will count when
-		 * there are packets available.
-		 */
-		cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group),
-			       0x1ful << 24);
-	} else {
-		/* Enable POW interrupt when our port has at least one packet */
-		cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0x1001);
-	}
+	/*
+	 * 150 uS: about 10 1500-byte packtes at 1GE.
+	 */
+	cvm_oct_tx_poll_interval = 150 * (octeon_get_clock_rate() / 1000000);
 
-	/* Enable the poll timer for checking RGMII status */
-	init_timer(&cvm_oct_poll_timer);
-	cvm_oct_poll_timer.data = 0;
-	cvm_oct_poll_timer.function = cvm_do_timer;
-	mod_timer(&cvm_oct_poll_timer, jiffies + HZ);
+	queue_delayed_work(cvm_oct_poll_queue, &cvm_oct_rx_refill_work, HZ);
 
 	return 0;
 }
 
-/**
- * Module / driver shutdown
- *
- * Returns Zero on success
- */
 static void __exit cvm_oct_cleanup_module(void)
 {
 	int port;
@@ -853,22 +801,31 @@ static void __exit cvm_oct_cleanup_modul
 	/* Free the interrupt handler */
 	free_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group, cvm_oct_device);
 
-	del_timer(&cvm_oct_poll_timer);
+	atomic_inc_return(&cvm_oct_poll_queue_stopping);
+	cancel_delayed_work_sync(&cvm_oct_rx_refill_work);
+
 	cvm_oct_rx_shutdown();
+	cvm_oct_tx_shutdown();
+
 	cvmx_pko_disable();
 
 	/* Free the ethernet devices */
 	for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
 		if (cvm_oct_device[port]) {
-			cvm_oct_tx_shutdown(cvm_oct_device[port]);
-			unregister_netdev(cvm_oct_device[port]);
-			kfree(cvm_oct_device[port]);
+			struct net_device *dev = cvm_oct_device[port];
+			struct octeon_ethernet *priv = netdev_priv(dev);
+			cancel_delayed_work_sync(&priv->port_periodic_work);
+
+			cvm_oct_tx_shutdown_dev(dev);
+			unregister_netdev(dev);
+			kfree(dev);
 			cvm_oct_device[port] = NULL;
 		}
 	}
 
+	destroy_workqueue(cvm_oct_poll_queue);
+
 	cvmx_pko_shutdown();
-	cvm_oct_proc_shutdown();
 
 	cvmx_ipd_free_ptr();
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-defines.h linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-defines.h
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-defines.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-defines.h	2010-05-16 17:17:36.000000000 -0400
@@ -41,17 +41,10 @@
  *      Tells the driver to populate the packet buffers with kernel skbuffs.
  *      This allows the driver to receive packets without copying them. It also
  *      means that 32bit userspace can't access the packet buffers.
- *  USE_32BIT_SHARED
- *      This define tells the driver to allocate memory for buffers from the
- *      32bit sahred region instead of the kernel memory space.
  *  USE_HW_TCPUDP_CHECKSUM
  *      Controls if the Octeon TCP/UDP checksum engine is used for packet
  *      output. If this is zero, the kernel will perform the checksum in
  *      software.
- *  USE_MULTICORE_RECEIVE
- *      Process receive interrupts on multiple cores. This spreads the network
- *      load across the first 8 processors. If ths is zero, only one core
- *      processes incomming packets.
  *  USE_ASYNC_IOBDMA
  *      Use asynchronous IO access to hardware. This uses Octeon's asynchronous
  *      IOBDMAs to issue IO accesses without stalling. Set this to zero
@@ -75,29 +68,15 @@
 #define CONFIG_CAVIUM_RESERVE32 0
 #endif
 
-#if CONFIG_CAVIUM_RESERVE32
-#define USE_32BIT_SHARED            1
-#define USE_SKBUFFS_IN_HW           0
-#define REUSE_SKBUFFS_WITHOUT_FREE  0
-#else
-#define USE_32BIT_SHARED            0
 #define USE_SKBUFFS_IN_HW           1
 #ifdef CONFIG_NETFILTER
 #define REUSE_SKBUFFS_WITHOUT_FREE  0
 #else
 #define REUSE_SKBUFFS_WITHOUT_FREE  1
 #endif
-#endif
-
-/* Max interrupts per second per core */
-#define INTERRUPT_LIMIT             10000
 
-/* Don't limit the number of interrupts */
-/*#define INTERRUPT_LIMIT             0     */
 #define USE_HW_TCPUDP_CHECKSUM      1
 
-#define USE_MULTICORE_RECEIVE       1
-
 /* Enable Random Early Dropping under load */
 #define USE_RED                     1
 #define USE_ASYNC_IOBDMA            (CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0)
@@ -115,21 +94,12 @@
 /* Use this to not have FPA frees control L2 */
 /*#define DONT_WRITEBACK(x)         0   */
 
-/* Maximum number of packets to process per interrupt. */
-#define MAX_RX_PACKETS 120
 /* Maximum number of SKBs to try to free per xmit packet. */
-#define MAX_SKB_TO_FREE 10
 #define MAX_OUT_QUEUE_DEPTH 1000
 
-#ifndef CONFIG_SMP
-#undef USE_MULTICORE_RECEIVE
-#define USE_MULTICORE_RECEIVE 0
-#endif
-
-#define IP_PROTOCOL_TCP             6
-#define IP_PROTOCOL_UDP             0x11
+#define FAU_TOTAL_TX_TO_CLEAN (CVMX_FAU_REG_END - sizeof(uint32_t))
+#define FAU_NUM_PACKET_BUFFERS_TO_FREE (FAU_TOTAL_TX_TO_CLEAN - sizeof(uint32_t))
 
-#define FAU_NUM_PACKET_BUFFERS_TO_FREE (CVMX_FAU_REG_END - sizeof(uint32_t))
 #define TOTAL_NUMBER_OF_PORTS       (CVMX_PIP_NUM_INPUT_PORTS+1)
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-mdio.c linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-mdio.c
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-mdio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-mdio.c	2010-05-16 17:17:36.000000000 -0400
@@ -96,11 +96,11 @@ const struct ethtool_ops cvm_oct_ethtool
 };
 
 /**
- * IOCTL support for PHY control
- *
+ * cvm_oct_ioctl - IOCTL support for PHY control
  * @dev:    Device to change
  * @rq:     the request
  * @cmd:    the command
+ *
  * Returns Zero on success
  */
 int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -153,7 +153,7 @@ static void cvm_oct_adjust_link(struct n
 
 
 /**
- * Setup the PHY
+ * cvm_oct_phy_setup_device - setup the PHY
  *
  * @dev:    Device to setup
  *
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-mdio.h linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-mdio.h
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-mdio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-mdio.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,6 @@
 #include <linux/ip.h>
 #include <linux/string.h>
 #include <linux/ethtool.h>
-#include <linux/mii.h>
 #include <linux/seq_file.h>
 #include <linux/proc_fs.h>
 #include <net/dst.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-mem.c linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-mem.c
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-mem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-mem.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2007 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -26,8 +26,7 @@
 **********************************************************************/
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
-#include <linux/mii.h>
-#include <net/dst.h>
+#include <linux/slab.h>
 
 #include <asm/octeon/octeon.h>
 
@@ -36,18 +35,19 @@
 #include "cvmx-fpa.h"
 
 /**
- * Fill the supplied hardware pool with skbuffs
- *
+ * cvm_oct_fill_hw_skbuff - fill the supplied hardware pool with skbuffs
  * @pool:     Pool to allocate an skbuff for
  * @size:     Size of the buffer needed for the pool
  * @elements: Number of buffers to allocate
+ *
+ * Returns the actual number of buffers allocated.
  */
 static int cvm_oct_fill_hw_skbuff(int pool, int size, int elements)
 {
 	int freed = elements;
 	while (freed) {
 
-		struct sk_buff *skb = dev_alloc_skb(size + 128);
+		struct sk_buff *skb = dev_alloc_skb(size + 256);
 		if (unlikely(skb == NULL)) {
 			pr_warning
 			    ("Failed to allocate skb for hardware pool %d\n",
@@ -55,7 +55,7 @@ static int cvm_oct_fill_hw_skbuff(int po
 			break;
 		}
 
-		skb_reserve(skb, 128 - (((unsigned long)skb->data) & 0x7f));
+		skb_reserve(skb, 256 - (((unsigned long)skb->data) & 0x7f));
 		*(struct sk_buff **)(skb->data - sizeof(void *)) = skb;
 		cvmx_fpa_free(skb->data, pool, DONT_WRITEBACK(size / 128));
 		freed--;
@@ -64,8 +64,7 @@ static int cvm_oct_fill_hw_skbuff(int po
 }
 
 /**
- * Free the supplied hardware pool of skbuffs
- *
+ * cvm_oct_free_hw_skbuff- free hardware pool skbuffs
  * @pool:     Pool to allocate an skbuff for
  * @size:     Size of the buffer needed for the pool
  * @elements: Number of buffers to allocate
@@ -93,96 +92,76 @@ static void cvm_oct_free_hw_skbuff(int p
 }
 
 /**
- * This function fills a hardware pool with memory. Depending
- * on the config defines, this memory might come from the
- * kernel or global 32bit memory allocated with
- * cvmx_bootmem_alloc.
- *
+ * cvm_oct_fill_hw_memory - fill a hardware pool with memory.
  * @pool:     Pool to populate
  * @size:     Size of each buffer in the pool
  * @elements: Number of buffers to allocate
+ *
+ * Returns the actual number of buffers allocated.
  */
 static int cvm_oct_fill_hw_memory(int pool, int size, int elements)
 {
 	char *memory;
+	char *fpa;
 	int freed = elements;
 
-	if (USE_32BIT_SHARED) {
-		extern uint64_t octeon_reserve32_memory;
-
-		memory =
-		    cvmx_bootmem_alloc_range(elements * size, 128,
-					     octeon_reserve32_memory,
-					     octeon_reserve32_memory +
-					     (CONFIG_CAVIUM_RESERVE32 << 20) -
-					     1);
-		if (memory == NULL)
-			panic("Unable to allocate %u bytes for FPA pool %d\n",
-			      elements * size, pool);
-
-		pr_notice("Memory range %p - %p reserved for "
-			  "hardware\n", memory,
-			  memory + elements * size - 1);
-
-		while (freed) {
-			cvmx_fpa_free(memory, pool, 0);
-			memory += size;
-			freed--;
-		}
-	} else {
-		while (freed) {
-			/* We need to force alignment to 128 bytes here */
-			memory = kmalloc(size + 127, GFP_ATOMIC);
-			if (unlikely(memory == NULL)) {
-				pr_warning("Unable to allocate %u bytes for "
-					   "FPA pool %d\n",
-				     elements * size, pool);
-				break;
-			}
-			memory = (char *)(((unsigned long)memory + 127) & -128);
-			cvmx_fpa_free(memory, pool, 0);
-			freed--;
+	while (freed) {
+		/*
+		 * FPA memory must be 128 byte aligned.  Since we are
+		 * aligning we need to save the original pointer so we
+		 * can feed it to kfree when the memory is returned to
+		 * the kernel.
+		 *
+		 * We allocate an extra 256 bytes to allow for
+		 * alignment and space for the original pointer saved
+		 * just before the block.
+		 */
+		memory = kmalloc(size + 256, GFP_ATOMIC);
+		if (unlikely(memory == NULL)) {
+			pr_warning("Unable to allocate %u bytes for FPA pool %d\n",
+				   elements * size, pool);
+			break;
 		}
+		fpa = (char *)(((unsigned long)memory + 256) & ~0x7fUL);
+		*((char **)fpa - 1) = memory;
+		cvmx_fpa_free(fpa, pool, 0);
+		freed--;
 	}
 	return elements - freed;
 }
 
 /**
- * Free memory previously allocated with cvm_oct_fill_hw_memory
- *
+ * cvm_oct_free_hw_memory - Free memory allocated by cvm_oct_fill_hw_memory
  * @pool:     FPA pool to free
  * @size:     Size of each buffer in the pool
  * @elements: Number of buffers that should be in the pool
  */
 static void cvm_oct_free_hw_memory(int pool, int size, int elements)
 {
-	if (USE_32BIT_SHARED) {
-		pr_warning("Warning: 32 shared memory is not freeable\n");
-	} else {
-		char *memory;
-		do {
-			memory = cvmx_fpa_alloc(pool);
-			if (memory) {
-				elements--;
-				kfree(phys_to_virt(cvmx_ptr_to_phys(memory)));
-			}
-		} while (memory);
+	char *memory;
+	char *fpa;
+	do {
+		fpa = cvmx_fpa_alloc(pool);
+		if (fpa) {
+			elements--;
+			fpa = (char *)phys_to_virt(cvmx_ptr_to_phys(fpa));
+			memory = *((char **)fpa - 1);
+			kfree(memory);
+		}
+	} while (fpa);
 
-		if (elements < 0)
-			pr_warning("Freeing of pool %u had too many "
-				   "buffers (%d)\n",
-			       pool, elements);
-		else if (elements > 0)
-			pr_warning("Warning: Freeing of pool %u is "
-				"missing %d buffers\n",
-			     pool, elements);
-	}
+	if (elements < 0)
+		pr_warning("Freeing of pool %u had too many buffers (%d)\n",
+			pool, elements);
+	else if (elements > 0)
+		pr_warning("Warning: Freeing of pool %u is missing %d buffers\n",
+			pool, elements);
 }
 
 int cvm_oct_mem_fill_fpa(int pool, int size, int elements)
 {
 	int freed;
-	if (USE_SKBUFFS_IN_HW)
+	if (USE_SKBUFFS_IN_HW && pool == CVMX_FPA_PACKET_POOL)
 		freed = cvm_oct_fill_hw_skbuff(pool, size, elements);
 	else
 		freed = cvm_oct_fill_hw_memory(pool, size, elements);
@@ -191,7 +170,7 @@ int cvm_oct_mem_fill_fpa(int pool, int s
 
 void cvm_oct_mem_empty_fpa(int pool, int size, int elements)
 {
-	if (USE_SKBUFFS_IN_HW)
+	if (USE_SKBUFFS_IN_HW && pool == CVMX_FPA_PACKET_POOL)
 		cvm_oct_free_hw_skbuff(pool, size, elements);
 	else
 		cvm_oct_free_hw_memory(pool, size, elements);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-proc.c linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-proc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-proc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-proc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,144 +0,0 @@
-/**********************************************************************
- * Author: Cavium Networks
- *
- * Contact: support@caviumnetworks.com
- * This file is part of the OCTEON SDK
- *
- * Copyright (c) 2003-2007 Cavium Networks
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, Version 2, as
- * published by the Free Software Foundation.
- *
- * This file is distributed in the hope that it will be useful, but
- * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
- * NONINFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this file; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- * or visit http://www.gnu.org/licenses/.
- *
- * This file may also be available under a different license from Cavium.
- * Contact Cavium Networks for more information
-**********************************************************************/
-#include <linux/kernel.h>
-#include <linux/seq_file.h>
-#include <linux/proc_fs.h>
-#include <net/dst.h>
-
-#include <asm/octeon/octeon.h>
-
-#include "octeon-ethernet.h"
-#include "ethernet-defines.h"
-
-#include "cvmx-helper.h"
-#include "cvmx-pip.h"
-
-/**
- * User is reading /proc/octeon_ethernet_stats
- *
- * @m:
- * @v:
- * Returns
- */
-static int cvm_oct_stats_show(struct seq_file *m, void *v)
-{
-	struct octeon_ethernet *priv;
-	int port;
-
-	for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
-
-		if (cvm_oct_device[port]) {
-			priv = netdev_priv(cvm_oct_device[port]);
-
-			seq_printf(m, "\nOcteon Port %d (%s)\n", port,
-				   cvm_oct_device[port]->name);
-			seq_printf(m,
-				   "rx_packets:             %12lu\t"
-				   "tx_packets:             %12lu\n",
-				   priv->stats.rx_packets,
-				   priv->stats.tx_packets);
-			seq_printf(m,
-				   "rx_bytes:               %12lu\t"
-				   "tx_bytes:               %12lu\n",
-				   priv->stats.rx_bytes, priv->stats.tx_bytes);
-			seq_printf(m,
-				   "rx_errors:              %12lu\t"
-				   "tx_errors:              %12lu\n",
-				   priv->stats.rx_errors,
-				   priv->stats.tx_errors);
-			seq_printf(m,
-				   "rx_dropped:             %12lu\t"
-				   "tx_dropped:             %12lu\n",
-				   priv->stats.rx_dropped,
-				   priv->stats.tx_dropped);
-			seq_printf(m,
-				   "rx_length_errors:       %12lu\t"
-				   "tx_aborted_errors:      %12lu\n",
-				   priv->stats.rx_length_errors,
-				   priv->stats.tx_aborted_errors);
-			seq_printf(m,
-				   "rx_over_errors:         %12lu\t"
-				   "tx_carrier_errors:      %12lu\n",
-				   priv->stats.rx_over_errors,
-				   priv->stats.tx_carrier_errors);
-			seq_printf(m,
-				   "rx_crc_errors:          %12lu\t"
-				   "tx_fifo_errors:         %12lu\n",
-				   priv->stats.rx_crc_errors,
-				   priv->stats.tx_fifo_errors);
-			seq_printf(m,
-				   "rx_frame_errors:        %12lu\t"
-				   "tx_heartbeat_errors:    %12lu\n",
-				   priv->stats.rx_frame_errors,
-				   priv->stats.tx_heartbeat_errors);
-			seq_printf(m,
-				   "rx_fifo_errors:         %12lu\t"
-				   "tx_window_errors:       %12lu\n",
-				   priv->stats.rx_fifo_errors,
-				   priv->stats.tx_window_errors);
-			seq_printf(m,
-				   "rx_missed_errors:       %12lu\t"
-				   "multicast:              %12lu\n",
-				   priv->stats.rx_missed_errors,
-				   priv->stats.multicast);
-		}
-	}
-
-	return 0;
-}
-
-/**
- * /proc/octeon_ethernet_stats was openned. Use the single_open iterator
- *
- * @inode:
- * @file:
- * Returns
- */
-static int cvm_oct_stats_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, cvm_oct_stats_show, NULL);
-}
-
-static const struct file_operations cvm_oct_stats_operations = {
-	.open = cvm_oct_stats_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-
-void cvm_oct_proc_initialize(void)
-{
-	struct proc_dir_entry *entry =
-	    create_proc_entry("octeon_ethernet_stats", 0, NULL);
-	if (entry)
-		entry->proc_fops = &cvm_oct_stats_operations;
-}
-
-void cvm_oct_proc_shutdown(void)
-{
-	remove_proc_entry("octeon_ethernet_stats", NULL);
-}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-proc.h linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-proc.h
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-proc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-proc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,29 +0,0 @@
-/*********************************************************************
- * Author: Cavium Networks
- *
- * Contact: support@caviumnetworks.com
- * This file is part of the OCTEON SDK
- *
- * Copyright (c) 2003-2007 Cavium Networks
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, Version 2, as
- * published by the Free Software Foundation.
- *
- * This file is distributed in the hope that it will be useful, but
- * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
- * NONINFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this file; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- * or visit http://www.gnu.org/licenses/.
- *
- * This file may also be available under a different license from Cavium.
- * Contact Cavium Networks for more information
-*********************************************************************/
-
-void cvm_oct_proc_initialize(void);
-void cvm_oct_proc_shutdown(void);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-rgmii.c linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-rgmii.c
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-rgmii.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-rgmii.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,7 @@
 **********************************************************************/
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
-#include <linux/mii.h>
+#include <linux/phy.h>
 #include <net/dst.h>
 
 #include <asm/octeon/octeon.h>
@@ -48,14 +48,20 @@ static int number_rgmii_ports;
 static void cvm_oct_rgmii_poll(struct net_device *dev)
 {
 	struct octeon_ethernet *priv = netdev_priv(dev);
-	unsigned long flags;
+	unsigned long flags = 0;
 	cvmx_helper_link_info_t link_info;
+	int use_global_register_lock = (priv->phydev == NULL);
 
-	/*
-	 * Take the global register lock since we are going to touch
-	 * registers that affect more than one port.
-	 */
-	spin_lock_irqsave(&global_register_lock, flags);
+	BUG_ON(in_interrupt());
+	if (use_global_register_lock) {
+		/*
+		 * Take the global register lock since we are going to
+		 * touch registers that affect more than one port.
+		 */
+		spin_lock_irqsave(&global_register_lock, flags);
+	} else {
+		mutex_lock(&priv->phydev->bus->mdio_lock);
+	}
 
 	link_info = cvmx_helper_link_get(priv->port);
 	if (link_info.u64 == priv->link_info) {
@@ -115,7 +121,11 @@ static void cvm_oct_rgmii_poll(struct ne
 				     dev->name);
 			}
 		}
-		spin_unlock_irqrestore(&global_register_lock, flags);
+
+		if (use_global_register_lock)
+			spin_unlock_irqrestore(&global_register_lock, flags);
+		else
+			mutex_unlock(&priv->phydev->bus->mdio_lock);
 		return;
 	}
 
@@ -151,7 +161,12 @@ static void cvm_oct_rgmii_poll(struct ne
 		link_info = cvmx_helper_link_autoconf(priv->port);
 		priv->link_info = link_info.u64;
 	}
-	spin_unlock_irqrestore(&global_register_lock, flags);
+
+	if (use_global_register_lock)
+		spin_unlock_irqrestore(&global_register_lock, flags);
+	else {
+		mutex_unlock(&priv->phydev->bus->mdio_lock);
+	}
 
 	if (priv->phydev == NULL) {
 		/* Tell core. */
@@ -213,8 +228,11 @@ static irqreturn_t cvm_oct_rgmii_rml_int
 				struct net_device *dev =
 				    cvm_oct_device[cvmx_helper_get_ipd_port
 						   (interface, index)];
-				if (dev)
-					cvm_oct_rgmii_poll(dev);
+				struct octeon_ethernet *priv = netdev_priv(dev);
+
+				if (dev && !atomic_read(&cvm_oct_poll_queue_stopping))
+					queue_work(cvm_oct_poll_queue, &priv->port_work);
+
 				gmx_rx_int_reg.u64 = 0;
 				gmx_rx_int_reg.s.phy_dupx = 1;
 				gmx_rx_int_reg.s.phy_link = 1;
@@ -252,8 +270,11 @@ static irqreturn_t cvm_oct_rgmii_rml_int
 				struct net_device *dev =
 				    cvm_oct_device[cvmx_helper_get_ipd_port
 						   (interface, index)];
-				if (dev)
-					cvm_oct_rgmii_poll(dev);
+				struct octeon_ethernet *priv = netdev_priv(dev);
+
+				if (dev && !atomic_read(&cvm_oct_poll_queue_stopping))
+					queue_work(cvm_oct_poll_queue, &priv->port_work);
+
 				gmx_rx_int_reg.u64 = 0;
 				gmx_rx_int_reg.s.phy_dupx = 1;
 				gmx_rx_int_reg.s.phy_link = 1;
@@ -302,6 +323,12 @@ int cvm_oct_rgmii_stop(struct net_device
 	return 0;
 }
 
+static void cvm_oct_rgmii_immediate_poll(struct work_struct *work)
+{
+	struct octeon_ethernet *priv = container_of(work, struct octeon_ethernet, port_work);
+	cvm_oct_rgmii_poll(cvm_oct_device[priv->port]);
+}
+
 int cvm_oct_rgmii_init(struct net_device *dev)
 {
 	struct octeon_ethernet *priv = netdev_priv(dev);
@@ -309,7 +336,7 @@ int cvm_oct_rgmii_init(struct net_device
 
 	cvm_oct_common_init(dev);
 	dev->netdev_ops->ndo_stop(dev);
-
+	INIT_WORK(&priv->port_work, cvm_oct_rgmii_immediate_poll);
 	/*
 	 * Due to GMX errata in CN3XXX series chips, it is necessary
 	 * to take the link down immediately when the PHY changes
@@ -397,4 +424,5 @@ void cvm_oct_rgmii_uninit(struct net_dev
 	number_rgmii_ports--;
 	if (number_rgmii_ports == 0)
 		free_irq(OCTEON_IRQ_RML, &number_rgmii_ports);
+	cancel_work_sync(&priv->port_work);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-rx.c linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-rx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2007 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -27,16 +27,14 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/cache.h>
+#include <linux/cpumask.h>
 #include <linux/netdevice.h>
 #include <linux/init.h>
 #include <linux/etherdevice.h>
 #include <linux/ip.h>
 #include <linux/string.h>
 #include <linux/prefetch.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/seq_file.h>
-#include <linux/proc_fs.h>
+#include <linux/smp.h>
 #include <net/dst.h>
 #ifdef CONFIG_XFRM
 #include <linux/xfrm.h>
@@ -48,8 +46,9 @@
 #include <asm/octeon/octeon.h>
 
 #include "ethernet-defines.h"
-#include "octeon-ethernet.h"
 #include "ethernet-mem.h"
+#include "ethernet-rx.h"
+#include "octeon-ethernet.h"
 #include "ethernet-util.h"
 
 #include "cvmx-helper.h"
@@ -61,62 +60,88 @@
 
 #include "cvmx-gmxx-defs.h"
 
-struct cvm_tasklet_wrapper {
-	struct tasklet_struct t;
-};
+struct cvm_napi_wrapper {
+	struct napi_struct napi;
+} ____cacheline_aligned_in_smp;
 
-/*
- * Aligning the tasklet_struct on cachline boundries seems to decrease
- * throughput even though in theory it would reduce contantion on the
- * cache lines containing the locks.
- */
+static struct cvm_napi_wrapper cvm_oct_napi[NR_CPUS] __cacheline_aligned_in_smp;
 
-static struct cvm_tasklet_wrapper cvm_oct_tasklet[NR_CPUS];
+struct cvm_oct_core_state {
+	int baseline_cores;
+	/*
+	 * The number of additional cores that could be processing
+	 * input packtes.
+	 */
+	atomic_t available_cores;
+	cpumask_t cpu_state;
+} ____cacheline_aligned_in_smp;
 
-/**
- * Interrupt handler. The interrupt occurs whenever the POW
- * transitions from 0->1 packets in our group.
- *
- * @cpl:
- * @dev_id:
- * @regs:
- * Returns
- */
-irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id)
+static struct cvm_oct_core_state core_state __cacheline_aligned_in_smp;
+
+static void cvm_oct_enable_napi(void *_)
 {
-	/* Acknowledge the interrupt */
-	if (INTERRUPT_LIMIT)
-		cvmx_write_csr(CVMX_POW_WQ_INT, 1 << pow_receive_group);
-	else
-		cvmx_write_csr(CVMX_POW_WQ_INT, 0x10001 << pow_receive_group);
-	preempt_disable();
-	tasklet_schedule(&cvm_oct_tasklet[smp_processor_id()].t);
-	preempt_enable();
-	return IRQ_HANDLED;
+	int cpu = smp_processor_id();
+	napi_schedule(&cvm_oct_napi[cpu].napi);
+}
+
+static void cvm_oct_enable_one_cpu(void)
+{
+	int v;
+	int cpu;
+
+	/* Check to see if more CPUs are available for receive processing... */
+	v = atomic_sub_if_positive(1, &core_state.available_cores);
+	if (v < 0)
+		return;
+
+	/* ... if a CPU is available, Turn on NAPI polling for that CPU.  */
+	for_each_online_cpu(cpu) {
+		if (!cpu_test_and_set(cpu, core_state.cpu_state)) {
+			v = smp_call_function_single(cpu, cvm_oct_enable_napi,
+						     NULL, 0);
+			if (v)
+				panic("Can't enable NAPI.");
+			break;
+		}
+	}
+}
+
+static void cvm_oct_no_more_work(void)
+{
+	int cpu = smp_processor_id();
+
+	/*
+	 * CPU zero is special.  It always has the irq enabled when
+	 * waiting for incoming packets.
+	 */
+	if (cpu == 0) {
+		enable_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group);
+		return;
+	}
+
+	cpu_clear(cpu, core_state.cpu_state);
+	atomic_add(1, &core_state.available_cores);
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
 /**
- * This is called when the kernel needs to manually poll the
- * device. For Octeon, this is simply calling the interrupt
- * handler. We actually poll all the devices, not just the
- * one supplied.
+ * cvm_oct_do_interrupt - interrupt handler.
+ *
+ * The interrupt occurs whenever the POW has packets in our group.
  *
- * @dev:    Device to poll. Unused
  */
-void cvm_oct_poll_controller(struct net_device *dev)
+static irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id)
 {
-	preempt_disable();
-	tasklet_schedule(&cvm_oct_tasklet[smp_processor_id()].t);
-	preempt_enable();
+	/* Disable the IRQ and start napi_poll. */
+	disable_irq_nosync(OCTEON_IRQ_WORKQ0 + pow_receive_group);
+	cvm_oct_enable_napi(NULL);
+
+	return IRQ_HANDLED;
 }
-#endif
 
 /**
- * This is called on receive errors, and determines if the packet
- * can be dropped early-on in cvm_oct_tasklet_rx().
- *
+ * cvm_oct_check_rcv_error - process receive errors
  * @work: Work queue entry pointing to the packet.
+ *
  * Returns Non-zero if the packet can be dropped, zero otherwise.
  */
 static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)
@@ -199,19 +224,20 @@ static inline int cvm_oct_check_rcv_erro
 }
 
 /**
- * Tasklet function that is scheduled on a core when an interrupt occurs.
+ * cvm_oct_napi_poll - the NAPI poll function.
+ * @napi: The NAPI instance, or null if called from cvm_oct_poll_controller
+ * @budget: Maximum number of packets to receive.
  *
- * @unused:
+ * Returns the number of packets processed.
  */
-void cvm_oct_tasklet_rx(unsigned long unused)
+static int cvm_oct_napi_poll(struct napi_struct *napi, int budget)
 {
-	const int coreid = cvmx_get_core_num();
-	uint64_t old_group_mask;
-	uint64_t old_scratch;
-	int rx_count = 0;
-	int number_to_free;
-	int num_freed;
-	int packet_not_copied;
+	const int	coreid = cvmx_get_core_num();
+	uint64_t	old_group_mask;
+	uint64_t	old_scratch;
+	int		rx_count = 0;
+	int		did_work_request = 0;
+	int		packet_not_copied;
 
 	/* Prefetch cvm_oct_device since we know we need it soon */
 	prefetch(cvm_oct_device);
@@ -227,59 +253,63 @@ void cvm_oct_tasklet_rx(unsigned long un
 	cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid),
 		       (old_group_mask & ~0xFFFFull) | 1 << pow_receive_group);
 
-	if (USE_ASYNC_IOBDMA)
+	if (USE_ASYNC_IOBDMA) {
 		cvmx_pow_work_request_async(CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT);
+		did_work_request = 1;
+	}
 
-	while (1) {
+	while (rx_count < budget) {
 		struct sk_buff *skb = NULL;
+		struct sk_buff **pskb = NULL;
 		int skb_in_hw;
 		cvmx_wqe_t *work;
 
-		if (USE_ASYNC_IOBDMA) {
+		if (USE_ASYNC_IOBDMA && did_work_request)
 			work = cvmx_pow_work_response_async(CVMX_SCR_SCRATCH);
-		} else {
-			if ((INTERRUPT_LIMIT == 0)
-			    || likely(rx_count < MAX_RX_PACKETS))
-				work =
-				    cvmx_pow_work_request_sync
-				    (CVMX_POW_NO_WAIT);
-			else
-				work = NULL;
-		}
+		else
+			work = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
+
 		prefetch(work);
-		if (work == NULL)
+		did_work_request = 0;
+		if (work == NULL) {
+			union cvmx_pow_wq_int wq_int;
+			wq_int.u64 = 0;
+			wq_int.s.iq_dis = 1 << pow_receive_group;
+			wq_int.s.wq_int = 1 << pow_receive_group;
+			cvmx_write_csr(CVMX_POW_WQ_INT, wq_int.u64);
 			break;
+		}
+		pskb = (struct sk_buff **)(cvm_oct_get_buffer_ptr(work->packet_ptr) - sizeof(void *));
+		prefetch(pskb);
 
-		/*
-		 * Limit each core to processing MAX_RX_PACKETS
-		 * packets without a break.  This way the RX can't
-		 * starve the TX task.
-		 */
-		if (USE_ASYNC_IOBDMA) {
+		if (USE_ASYNC_IOBDMA && rx_count < (budget - 1)) {
+			cvmx_pow_work_request_async_nocheck(CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT);
+			did_work_request = 1;
+		}
 
-			if ((INTERRUPT_LIMIT == 0)
-			    || likely(rx_count < MAX_RX_PACKETS))
-				cvmx_pow_work_request_async_nocheck
-				    (CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT);
-			else {
-				cvmx_scratch_write64(CVMX_SCR_SCRATCH,
-						     0x8000000000000000ull);
-				cvmx_pow_tag_sw_null_nocheck();
-			}
+		if (rx_count == 0) {
+			/*
+			 * First time through, see if there is enough
+			 * work waiting to merit waking another
+			 * CPU.
+			 */
+			union cvmx_pow_wq_int_cntx counts;
+			int backlog;
+			int cores_in_use = core_state.baseline_cores - atomic_read(&core_state.available_cores);
+			counts.u64 = cvmx_read_csr(CVMX_POW_WQ_INT_CNTX(pow_receive_group));
+			backlog = counts.s.iq_cnt + counts.s.ds_cnt;
+			if (backlog > budget * cores_in_use && napi != NULL)
+				cvm_oct_enable_one_cpu();
 		}
 
 		skb_in_hw = USE_SKBUFFS_IN_HW && work->word2.s.bufs == 1;
 		if (likely(skb_in_hw)) {
-			skb =
-			    *(struct sk_buff
-			      **)(cvm_oct_get_buffer_ptr(work->packet_ptr) -
-				  sizeof(void *));
+			skb = *pskb;
 			prefetch(&skb->head);
 			prefetch(&skb->len);
 		}
 		prefetch(cvm_oct_device[work->ipprt]);
 
-		rx_count++;
 		/* Immediately throw away all packets with receive errors */
 		if (unlikely(work->word2.snoip.rcv_error)) {
 			if (cvm_oct_check_rcv_error(work))
@@ -292,39 +322,27 @@ void cvm_oct_tasklet_rx(unsigned long un
 		 * buffer.
 		 */
 		if (likely(skb_in_hw)) {
-			/*
-			 * This calculation was changed in case the
-			 * skb header is using a different address
-			 * aliasing type than the buffer. It doesn't
-			 * make any differnece now, but the new one is
-			 * more correct.
-			 */
-			skb->data =
-			    skb->head + work->packet_ptr.s.addr -
-			    cvmx_ptr_to_phys(skb->head);
+			skb->data = skb->head + work->packet_ptr.s.addr - cvmx_ptr_to_phys(skb->head);
 			prefetch(skb->data);
 			skb->len = work->len;
 			skb_set_tail_pointer(skb, skb->len);
 			packet_not_copied = 1;
 		} else {
-
 			/*
 			 * We have to copy the packet. First allocate
 			 * an skbuff for it.
 			 */
 			skb = dev_alloc_skb(work->len);
 			if (!skb) {
-				DEBUGPRINT("Port %d failed to allocate "
-					   "skbuff, packet dropped\n",
-				     work->ipprt);
+				DEBUGPRINT("Port %d failed to allocate skbuff, packet dropped\n",
+					   work->ipprt);
 				cvm_oct_free_work(work);
 				continue;
 			}
 
 			/*
 			 * Check if we've received a packet that was
-			 * entirely stored in the work entry. This is
-			 * untested.
+			 * entirely stored in the work entry.
 			 */
 			if (unlikely(work->word2.s.bufs == 0)) {
 				uint8_t *ptr = work->packet_data;
@@ -343,15 +361,13 @@ void cvm_oct_tasklet_rx(unsigned long un
 				/* No packet buffers to free */
 			} else {
 				int segments = work->word2.s.bufs;
-				union cvmx_buf_ptr segment_ptr =
-					work->packet_ptr;
+				union cvmx_buf_ptr segment_ptr = work->packet_ptr;
 				int len = work->len;
 
 				while (segments--) {
 					union cvmx_buf_ptr next_ptr =
-					    *(union cvmx_buf_ptr *)
-					    cvmx_phys_to_ptr(segment_ptr.s.
-							     addr - 8);
+					    *(union cvmx_buf_ptr *)cvmx_phys_to_ptr(segment_ptr.s.addr - 8);
+
 			/*
 			 * Octeon Errata PKI-100: The segment size is
 			 * wrong. Until it is fixed, calculate the
@@ -361,22 +377,18 @@ void cvm_oct_tasklet_rx(unsigned long un
 			 * one: int segment_size =
 			 * segment_ptr.s.size;
 			 */
-					int segment_size =
-					    CVMX_FPA_PACKET_POOL_SIZE -
-					    (segment_ptr.s.addr -
-					     (((segment_ptr.s.addr >> 7) -
-					       segment_ptr.s.back) << 7));
-					/* Don't copy more than what is left
-					   in the packet */
+					int segment_size = CVMX_FPA_PACKET_POOL_SIZE -
+						(segment_ptr.s.addr - (((segment_ptr.s.addr >> 7) - segment_ptr.s.back) << 7));
+					/*
+					 * Don't copy more than what
+					 * is left in the packet.
+					 */
 					if (segment_size > len)
 						segment_size = len;
 					/* Copy the data into the packet */
 					memcpy(skb_put(skb, segment_size),
-					       cvmx_phys_to_ptr(segment_ptr.s.
-								addr),
+					       cvmx_phys_to_ptr(segment_ptr.s.addr),
 					       segment_size);
-					/* Reduce the amount of bytes left
-					   to copy */
 					len -= segment_size;
 					segment_ptr = next_ptr;
 				}
@@ -389,16 +401,15 @@ void cvm_oct_tasklet_rx(unsigned long un
 			struct net_device *dev = cvm_oct_device[work->ipprt];
 			struct octeon_ethernet *priv = netdev_priv(dev);
 
-			/* Only accept packets for devices
-			   that are currently up */
+			/*
+			 * Only accept packets for devices that are
+			 * currently up.
+			 */
 			if (likely(dev->flags & IFF_UP)) {
 				skb->protocol = eth_type_trans(skb, dev);
 				skb->dev = dev;
 
-				if (unlikely
-				    (work->word2.s.not_IP
-				     || work->word2.s.IP_exc
-				     || work->word2.s.L4_error))
+				if (unlikely(work->word2.s.not_IP || work->word2.s.IP_exc || work->word2.s.L4_error))
 					skb->ip_summed = CHECKSUM_NONE;
 				else
 					skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -414,15 +425,13 @@ void cvm_oct_tasklet_rx(unsigned long un
 #endif
 				}
 				netif_receive_skb(skb);
+				rx_count++;
 			} else {
+				/* Drop any packet received for a device that isn't up */
 				/*
-				 * Drop any packet received for a
-				 * device that isn't up.
-				 */
-				/*
-				   DEBUGPRINT("%s: Device not up, packet dropped\n",
-				   dev->name);
-				 */
+				DEBUGPRINT("%s: Device not up, packet dropped\n",
+					   dev->name);
+				*/
 #ifdef CONFIG_64BIT
 				atomic64_add(1, (atomic64_t *)&priv->stats.rx_dropped);
 #else
@@ -435,9 +444,8 @@ void cvm_oct_tasklet_rx(unsigned long un
 			 * Drop any packet received for a device that
 			 * doesn't exist.
 			 */
-			DEBUGPRINT("Port %d not controlled by Linux, packet "
-				   "dropped\n",
-			     work->ipprt);
+			DEBUGPRINT("Port %d not controlled by Linux, packet dropped\n",
+				   work->ipprt);
 			dev_kfree_skb_irq(skb);
 		}
 		/*
@@ -459,47 +467,93 @@ void cvm_oct_tasklet_rx(unsigned long un
 			cvm_oct_free_work(work);
 		}
 	}
-
 	/* Restore the original POW group mask */
 	cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid), old_group_mask);
 	if (USE_ASYNC_IOBDMA) {
 		/* Restore the scratch area */
 		cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
 	}
+	cvm_oct_rx_refill_pool(0);
 
-	if (USE_SKBUFFS_IN_HW) {
-		/* Refill the packet buffer pool */
-		number_to_free =
-		    cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
-
-		if (number_to_free > 0) {
-			cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
-					      -number_to_free);
-			num_freed =
-			    cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL,
-						 CVMX_FPA_PACKET_POOL_SIZE,
-						 number_to_free);
-			if (num_freed != number_to_free) {
-				cvmx_fau_atomic_add32
-				    (FAU_NUM_PACKET_BUFFERS_TO_FREE,
-				     number_to_free - num_freed);
-			}
-		}
+	if (rx_count < budget && napi != NULL) {
+		/* No more work */
+		napi_complete(napi);
+		cvm_oct_no_more_work();
 	}
+	return rx_count;
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/**
+ * cvm_oct_poll_controller - poll for receive packets
+ * device.
+ *
+ * @dev:    Device to poll. Unused
+ */
+void cvm_oct_poll_controller(struct net_device *dev)
+{
+	cvm_oct_napi_poll(NULL, 16);
+}
+#endif
+
 void cvm_oct_rx_initialize(void)
 {
 	int i;
-	/* Initialize all of the tasklets */
-	for (i = 0; i < NR_CPUS; i++)
-		tasklet_init(&cvm_oct_tasklet[i].t, cvm_oct_tasklet_rx, 0);
+	struct net_device *dev_for_napi = NULL;
+	union cvmx_pow_wq_int_thrx int_thr;
+	union cvmx_pow_wq_int_pc int_pc;
+
+	for (i = 0; i < TOTAL_NUMBER_OF_PORTS; i++) {
+		if (cvm_oct_device[i]) {
+			dev_for_napi = cvm_oct_device[i];
+			break;
+		}
+	}
+
+	if (NULL == dev_for_napi)
+		panic("No net_devices were allocated.");
+
+	if (max_rx_cpus > 1  && max_rx_cpus < num_online_cpus())
+		atomic_set(&core_state.available_cores, max_rx_cpus);
+	else
+		atomic_set(&core_state.available_cores, num_online_cpus());
+	core_state.baseline_cores = atomic_read(&core_state.available_cores);
+
+	core_state.cpu_state = CPU_MASK_NONE;
+	for_each_possible_cpu(i) {
+		netif_napi_add(dev_for_napi, &cvm_oct_napi[i].napi,
+			       cvm_oct_napi_poll, rx_napi_weight);
+		napi_enable(&cvm_oct_napi[i].napi);
+	}
+	/* Register an IRQ hander for to receive POW interrupts */
+	i = request_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group,
+			cvm_oct_do_interrupt, 0, "Ethernet", cvm_oct_device);
+
+	if (i)
+		panic("Could not acquire Ethernet IRQ %d\n",
+		      OCTEON_IRQ_WORKQ0 + pow_receive_group);
+
+	disable_irq_nosync(OCTEON_IRQ_WORKQ0 + pow_receive_group);
+
+	int_thr.u64 = 0;
+	int_thr.s.tc_en = 1;
+	int_thr.s.tc_thr = 1;
+	/* Enable POW interrupt when our port has at least one packet */
+	cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), int_thr.u64);
+
+	int_pc.u64 = 0;
+	int_pc.s.pc_thr = 5;
+	cvmx_write_csr(CVMX_POW_WQ_INT_PC, int_pc.u64);
+
+
+	/* Scheduld NAPI now.  This will indirectly enable interrupts. */
+	cvm_oct_enable_one_cpu();
 }
 
 void cvm_oct_rx_shutdown(void)
 {
 	int i;
-	/* Shutdown all of the tasklets */
-	for (i = 0; i < NR_CPUS; i++)
-		tasklet_kill(&cvm_oct_tasklet[i].t);
+	/* Shutdown all of the NAPIs */
+	for_each_possible_cpu(i)
+		netif_napi_del(&cvm_oct_napi[i].napi);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-rx.h linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-rx.h
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-rx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-rx.h	2010-05-16 17:17:36.000000000 -0400
@@ -24,10 +24,29 @@
  * This file may also be available under a different license from Cavium.
  * Contact Cavium Networks for more information
 *********************************************************************/
+#include "cvmx-fau.h"
 
-irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id);
 void cvm_oct_poll_controller(struct net_device *dev);
-void cvm_oct_tasklet_rx(unsigned long unused);
-
 void cvm_oct_rx_initialize(void);
 void cvm_oct_rx_shutdown(void);
+
+static inline void cvm_oct_rx_refill_pool(int fill_threshold)
+{
+	int number_to_free;
+	int num_freed;
+	/* Refill the packet buffer pool */
+	number_to_free =
+		cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
+
+	if (number_to_free > fill_threshold) {
+		cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
+				      -number_to_free);
+		num_freed = cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL,
+						 CVMX_FPA_PACKET_POOL_SIZE,
+						 number_to_free);
+		if (num_freed != number_to_free) {
+			cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
+					number_to_free - num_freed);
+		}
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-sgmii.c linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-sgmii.c
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-sgmii.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-sgmii.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 **********************************************************************/
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
-#include <linux/mii.h>
 #include <net/dst.h>
 
 #include <asm/octeon/octeon.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-spi.c linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-spi.c
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-spi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-spi.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 **********************************************************************/
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
-#include <linux/mii.h>
 #include <net/dst.h>
 
 #include <asm/octeon/octeon.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-tx.c linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-tx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2007 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -31,10 +31,6 @@
 #include <linux/etherdevice.h>
 #include <linux/ip.h>
 #include <linux/string.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/seq_file.h>
-#include <linux/proc_fs.h>
 #include <net/dst.h>
 #ifdef CONFIG_XFRM
 #include <linux/xfrm.h>
@@ -52,11 +48,14 @@
 
 #include "cvmx-wqe.h"
 #include "cvmx-fau.h"
+#include "cvmx-pip.h"
 #include "cvmx-pko.h"
 #include "cvmx-helper.h"
 
 #include "cvmx-gmxx-defs.h"
 
+#define CVM_OCT_SKB_CB(skb)	((u64 *)((skb)->cb))
+
 /*
  * You can define GET_SKBUFF_QOS() to override how the skbuff output
  * function determines which output queue is used. The default
@@ -68,12 +67,81 @@
 #define GET_SKBUFF_QOS(skb) 0
 #endif
 
+static void cvm_oct_tx_do_cleanup(unsigned long arg);
+static DECLARE_TASKLET(cvm_oct_tx_cleanup_tasklet, cvm_oct_tx_do_cleanup, 0);
+
+/* Maximum number of SKBs to try to free per xmit packet. */
+#define MAX_SKB_TO_FREE (MAX_OUT_QUEUE_DEPTH * 2)
+
+static inline int32_t cvm_oct_adjust_skb_to_free(int32_t skb_to_free, int fau)
+{
+	int32_t undo;
+	undo = skb_to_free > 0 ? MAX_SKB_TO_FREE : skb_to_free + MAX_SKB_TO_FREE;
+	if (undo > 0)
+		cvmx_fau_atomic_add32(fau, -undo);
+	skb_to_free = -skb_to_free > MAX_SKB_TO_FREE ? MAX_SKB_TO_FREE : -skb_to_free;
+	return skb_to_free;
+}
+
+static void cvm_oct_kick_tx_poll_watchdog(void)
+{
+	union cvmx_ciu_timx ciu_timx;
+	ciu_timx.u64 = 0;
+	ciu_timx.s.one_shot = 1;
+	ciu_timx.s.len = cvm_oct_tx_poll_interval;
+	cvmx_write_csr(CVMX_CIU_TIMX(1), ciu_timx.u64);
+}
+
+void cvm_oct_free_tx_skbs(struct net_device *dev)
+{
+	int32_t skb_to_free;
+	int qos, queues_per_port;
+	int total_freed = 0;
+	int total_remaining = 0;
+	unsigned long flags;
+	struct octeon_ethernet *priv = netdev_priv(dev);
+
+	queues_per_port = cvmx_pko_get_num_queues(priv->port);
+	/* Drain any pending packets in the free list */
+	for (qos = 0; qos < queues_per_port; qos++) {
+		if (skb_queue_len(&priv->tx_free_list[qos]) == 0)
+			continue;
+		skb_to_free = cvmx_fau_fetch_and_add32(priv->fau+qos*4, MAX_SKB_TO_FREE);
+		skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free, priv->fau+qos*4);
+
+
+		total_freed += skb_to_free;
+		if (skb_to_free > 0) {
+			struct sk_buff *to_free_list = NULL;
+			spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
+			while (skb_to_free > 0) {
+				struct sk_buff *t = __skb_dequeue(&priv->tx_free_list[qos]);
+				t->next = to_free_list;
+				to_free_list = t;
+				skb_to_free--;
+			}
+			spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags);
+			/* Do the actual freeing outside of the lock. */
+			while (to_free_list) {
+				struct sk_buff *t = to_free_list;
+				to_free_list = to_free_list->next;
+				dev_kfree_skb_any(t);
+			}
+		}
+		total_remaining += skb_queue_len(&priv->tx_free_list[qos]);
+	}
+	if (total_freed >= 0 && netif_queue_stopped(dev))
+		netif_wake_queue(dev);
+	if (total_remaining)
+		cvm_oct_kick_tx_poll_watchdog();
+}
+
 /**
- * Packet transmit
- *
+ * cvm_oct_xmit - transmit a packet
  * @skb:    Packet to send
  * @dev:    Device info structure
- * Returns Always returns zero
+ *
+ * Returns Always returns NETDEV_TX_OK
  */
 int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
 {
@@ -81,13 +149,15 @@ int cvm_oct_xmit(struct sk_buff *skb, st
 	union cvmx_buf_ptr hw_buffer;
 	uint64_t old_scratch;
 	uint64_t old_scratch2;
-	int dropped;
 	int qos;
-	int queue_it_up;
+	int i;
+	enum {QUEUE_CORE, QUEUE_HW, QUEUE_DROP} queue_type;
 	struct octeon_ethernet *priv = netdev_priv(dev);
+	struct sk_buff *to_free_list;
 	int32_t skb_to_free;
-	int32_t undo;
 	int32_t buffers_to_free;
+	u32 total_to_clean;
+	unsigned long flags;
 #if REUSE_SKBUFFS_WITHOUT_FREE
 	unsigned char *fpa_head;
 #endif
@@ -98,9 +168,6 @@ int cvm_oct_xmit(struct sk_buff *skb, st
 	 */
 	prefetch(priv);
 
-	/* Start off assuming no drop */
-	dropped = 0;
-
 	/*
 	 * The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to
 	 * completely remove "qos" in the event neither interface
@@ -135,6 +202,28 @@ int cvm_oct_xmit(struct sk_buff *skb, st
 	}
 
 	/*
+	 * We have space for 6 segment pointers, If there will be more
+	 * than that, we must linearize.
+	 */
+	if (unlikely(skb_shinfo(skb)->nr_frags > 5)) {
+		if (unlikely(__skb_linearize(skb))) {
+			queue_type = QUEUE_DROP;
+			if (USE_ASYNC_IOBDMA) {
+				/* Get the number of skbuffs in use by the hardware */
+				CVMX_SYNCIOBDMA;
+				skb_to_free = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
+			} else {
+				/* Get the number of skbuffs in use by the hardware */
+				skb_to_free = cvmx_fau_fetch_and_add32(priv->fau + qos * 4,
+								       MAX_SKB_TO_FREE);
+			}
+			skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free, priv->fau + qos * 4);
+			spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
+			goto skip_xmit;
+		}
+	}
+
+	/*
 	 * The CN3XXX series of parts has an errata (GMX-401) which
 	 * causes the GMX block to hang if a collision occurs towards
 	 * the end of a <68 byte packet. As a workaround for this, we
@@ -162,13 +251,6 @@ int cvm_oct_xmit(struct sk_buff *skb, st
 		}
 	}
 
-	/* Build the PKO buffer pointer */
-	hw_buffer.u64 = 0;
-	hw_buffer.s.addr = cvmx_ptr_to_phys(skb->data);
-	hw_buffer.s.pool = 0;
-	hw_buffer.s.size =
-	    (unsigned long)skb_end_pointer(skb) - (unsigned long)skb->head;
-
 	/* Build the PKO command */
 	pko_command.u64 = 0;
 	pko_command.s.n2 = 1;	/* Don't pollute L2 with the outgoing packet */
@@ -178,7 +260,31 @@ int cvm_oct_xmit(struct sk_buff *skb, st
 	pko_command.s.subone0 = 1;
 
 	pko_command.s.dontfree = 1;
-	pko_command.s.reg0 = priv->fau + qos * 4;
+
+	/* Build the PKO buffer pointer */
+	hw_buffer.u64 = 0;
+	if (skb_shinfo(skb)->nr_frags == 0) {
+		hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)skb->data);
+		hw_buffer.s.pool = 0;
+		hw_buffer.s.size = skb->len;
+	} else {
+		hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)skb->data);
+		hw_buffer.s.pool = 0;
+		hw_buffer.s.size = skb_headlen(skb);
+		CVM_OCT_SKB_CB(skb)[0] = hw_buffer.u64;
+		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+			struct skb_frag_struct *fs = skb_shinfo(skb)->frags + i;
+			hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)(page_address(fs->page) + fs->page_offset));
+			hw_buffer.s.size = fs->size;
+			CVM_OCT_SKB_CB(skb)[i + 1] = hw_buffer.u64;
+		}
+		hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)CVM_OCT_SKB_CB(skb));
+		hw_buffer.s.size = skb_shinfo(skb)->nr_frags + 1;
+		pko_command.s.segs = skb_shinfo(skb)->nr_frags + 1;
+		pko_command.s.gather = 1;
+		goto dont_put_skbuff_in_hw;
+	}
+
 	/*
 	 * See if we can put this skb in the FPA pool. Any strange
 	 * behavior from the Linux networking stack will most likely
@@ -190,7 +296,7 @@ int cvm_oct_xmit(struct sk_buff *skb, st
 	 * shown a 25% increase in performance under some loads.
 	 */
 #if REUSE_SKBUFFS_WITHOUT_FREE
-	fpa_head = skb->head + 128 - ((unsigned long)skb->head & 0x7f);
+	fpa_head = skb->head + 256 - ((unsigned long)skb->head & 0x7f);
 	if (unlikely(skb->data < fpa_head)) {
 		/*
 		 * printk("TX buffer beginning can't meet FPA
@@ -248,10 +354,9 @@ int cvm_oct_xmit(struct sk_buff *skb, st
 	 * We can use this buffer in the FPA.  We don't need the FAU
 	 * update anymore
 	 */
-	pko_command.s.reg0 = 0;
 	pko_command.s.dontfree = 0;
 
-	hw_buffer.s.back = (skb->data - fpa_head) >> 7;
+	hw_buffer.s.back = ((unsigned long)skb->data >> 7) - ((unsigned long)fpa_head >> 7);
 	*(struct sk_buff **)(fpa_head - sizeof(void *)) = skb;
 
 	/*
@@ -272,16 +377,16 @@ int cvm_oct_xmit(struct sk_buff *skb, st
 	skb->tc_verd = 0;
 #endif /* CONFIG_NET_CLS_ACT */
 #endif /* CONFIG_NET_SCHED */
+#endif /* REUSE_SKBUFFS_WITHOUT_FREE */
 
 dont_put_skbuff_in_hw:
-#endif /* REUSE_SKBUFFS_WITHOUT_FREE */
 
 	/* Check if we can use the hardware checksumming */
 	if (USE_HW_TCPUDP_CHECKSUM && (skb->protocol == htons(ETH_P_IP)) &&
 	    (ip_hdr(skb)->version == 4) && (ip_hdr(skb)->ihl == 5) &&
 	    ((ip_hdr(skb)->frag_off == 0) || (ip_hdr(skb)->frag_off == 1 << 14))
-	    && ((ip_hdr(skb)->protocol == IP_PROTOCOL_TCP)
-		|| (ip_hdr(skb)->protocol == IP_PROTOCOL_UDP))) {
+	    && ((ip_hdr(skb)->protocol == IPPROTO_TCP)
+		|| (ip_hdr(skb)->protocol == IPPROTO_UDP))) {
 		/* Use hardware checksum calc */
 		pko_command.s.ipoffp1 = sizeof(struct ethhdr) + 1;
 	}
@@ -299,89 +404,116 @@ dont_put_skbuff_in_hw:
 		    cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
 	}
 
-	/*
-	 * We try to claim MAX_SKB_TO_FREE buffers.  If there were not
-	 * that many available, we have to un-claim (undo) any that
-	 * were in excess.  If skb_to_free is positive we will free
-	 * that many buffers.
-	 */
-	undo = skb_to_free > 0 ?
-		MAX_SKB_TO_FREE : skb_to_free + MAX_SKB_TO_FREE;
-	if (undo > 0)
-		cvmx_fau_atomic_add32(priv->fau+qos*4, -undo);
-	skb_to_free = -skb_to_free > MAX_SKB_TO_FREE ?
-		MAX_SKB_TO_FREE : -skb_to_free;
+	skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free, priv->fau+qos*4);
 
 	/*
 	 * If we're sending faster than the receive can free them then
 	 * don't do the HW free.
 	 */
-	if ((buffers_to_free < -100) && !pko_command.s.dontfree) {
+	if ((buffers_to_free < -100) && !pko_command.s.dontfree)
 		pko_command.s.dontfree = 1;
-		pko_command.s.reg0 = priv->fau + qos * 4;
+
+	if (pko_command.s.dontfree) {
+		queue_type = QUEUE_CORE;
+		pko_command.s.reg0 = priv->fau+qos*4;
+	} else {
+		queue_type = QUEUE_HW;
 	}
+	if (USE_ASYNC_IOBDMA)
+		cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH, FAU_TOTAL_TX_TO_CLEAN, 1);
 
-	cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos,
-				     CVMX_PKO_LOCK_CMD_QUEUE);
+	spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
 
 	/* Drop this packet if we have too many already queued to the HW */
-	if (unlikely
-	    (skb_queue_len(&priv->tx_free_list[qos]) >= MAX_OUT_QUEUE_DEPTH)) {
-		/*
-		   DEBUGPRINT("%s: Tx dropped. Too many queued\n", dev->name);
-		 */
-		dropped = 1;
+	if (unlikely(skb_queue_len(&priv->tx_free_list[qos]) >= MAX_OUT_QUEUE_DEPTH)) {
+		if (dev->tx_queue_len != 0) {
+			/* Drop the lock when notifying the core.  */
+			spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags);
+			netif_stop_queue(dev);
+			spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
+		} else {
+			/* If not using normal queueing.  */
+			queue_type = QUEUE_DROP;
+			goto skip_xmit;
+		}
 	}
+
+	cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos,
+				     CVMX_PKO_LOCK_NONE);
+
 	/* Send the packet to the output queue */
-	else if (unlikely
-		 (cvmx_pko_send_packet_finish
-		  (priv->port, priv->queue + qos, pko_command, hw_buffer,
-		   CVMX_PKO_LOCK_CMD_QUEUE))) {
+	if (unlikely(cvmx_pko_send_packet_finish(priv->port,
+						 priv->queue + qos,
+						 pko_command, hw_buffer,
+						 CVMX_PKO_LOCK_NONE))) {
 		DEBUGPRINT("%s: Failed to send the packet\n", dev->name);
-		dropped = 1;
+		queue_type = QUEUE_DROP;
+	}
+skip_xmit:
+	to_free_list = NULL;
+
+	switch (queue_type) {
+	case QUEUE_DROP:
+		skb->next = to_free_list;
+		to_free_list = skb;
+		priv->stats.tx_dropped++;
+		break;
+	case QUEUE_HW:
+		cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, -1);
+		break;
+	case QUEUE_CORE:
+		__skb_queue_tail(&priv->tx_free_list[qos], skb);
+		break;
+	default:
+		BUG();
+	}
+
+	while (skb_to_free > 0) {
+		struct sk_buff *t = __skb_dequeue(&priv->tx_free_list[qos]);
+		t->next = to_free_list;
+		to_free_list = t;
+		skb_to_free--;
+	}
+
+	spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags);
+
+	/* Do the actual freeing outside of the lock. */
+	while (to_free_list) {
+		struct sk_buff *t = to_free_list;
+		to_free_list = to_free_list->next;
+		dev_kfree_skb_any(t);
 	}
 
 	if (USE_ASYNC_IOBDMA) {
+		CVMX_SYNCIOBDMA;
+		total_to_clean = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
 		/* Restore the scratch area */
 		cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
 		cvmx_scratch_write64(CVMX_SCR_SCRATCH + 8, old_scratch2);
-	}
-
-	queue_it_up = 0;
-	if (unlikely(dropped)) {
-		dev_kfree_skb_any(skb);
-		priv->stats.tx_dropped++;
 	} else {
-		if (USE_SKBUFFS_IN_HW) {
-			/* Put this packet on the queue to be freed later */
-			if (pko_command.s.dontfree)
-				queue_it_up = 1;
-			else
-				cvmx_fau_atomic_add32
-				    (FAU_NUM_PACKET_BUFFERS_TO_FREE, -1);
-		} else {
-			/* Put this packet on the queue to be freed later */
-			queue_it_up = 1;
-		}
+		total_to_clean = cvmx_fau_fetch_and_add32(FAU_TOTAL_TX_TO_CLEAN, 1);
 	}
 
-	if (queue_it_up) {
-		spin_lock(&priv->tx_free_list[qos].lock);
-		__skb_queue_tail(&priv->tx_free_list[qos], skb);
-		cvm_oct_free_tx_skbs(priv, skb_to_free, qos, 0);
-		spin_unlock(&priv->tx_free_list[qos].lock);
-	} else {
-		cvm_oct_free_tx_skbs(priv, skb_to_free, qos, 1);
+	if (total_to_clean & 0x3ff) {
+		/*
+		 * Schedule the cleanup tasklet every 1024 packets for
+		 * the pathological case of high traffic on one port
+		 * delaying clean up of packets on a different port
+		 * that is blocked waiting for the cleanup.
+		 */
+		tasklet_schedule(&cvm_oct_tx_cleanup_tasklet);
 	}
 
-	return 0;
+	cvm_oct_kick_tx_poll_watchdog();
+
+	return NETDEV_TX_OK;
 }
 
 /**
- * Packet transmit to the POW
- *
+ * cvm_oct_xmit_pow - transmit a packet to the POW
  * @skb:    Packet to send
  * @dev:    Device info structure
+
  * Returns Always returns zero
  */
 int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev)
@@ -459,8 +591,8 @@ int cvm_oct_xmit_pow(struct sk_buff *skb
 		work->word2.s.dec_ipcomp = 0;	/* FIXME */
 #endif
 		work->word2.s.tcp_or_udp =
-		    (ip_hdr(skb)->protocol == IP_PROTOCOL_TCP)
-		    || (ip_hdr(skb)->protocol == IP_PROTOCOL_UDP);
+		    (ip_hdr(skb)->protocol == IPPROTO_TCP)
+		    || (ip_hdr(skb)->protocol == IPPROTO_UDP);
 #if 0
 		/* FIXME */
 		work->word2.s.dec_ipsec = 0;
@@ -529,116 +661,63 @@ int cvm_oct_xmit_pow(struct sk_buff *skb
 }
 
 /**
- * Transmit a work queue entry out of the ethernet port. Both
- * the work queue entry and the packet data can optionally be
- * freed. The work will be freed on error as well.
- *
- * @dev:     Device to transmit out.
- * @work_queue_entry:
- *                Work queue entry to send
- * @do_free: True if the work queue entry and packet data should be
- *                freed. If false, neither will be freed.
- * @qos:     Index into the queues for this port to transmit on. This
- *                is used to implement QoS if their are multiple queues per
- *                port. This parameter must be between 0 and the number of
- *                queues per port minus 1. Values outside of this range will
- *                be change to zero.
+ * cvm_oct_tx_shutdown_dev - free all skb that are currently queued for TX.
+ * @dev:    Device being shutdown
  *
- * Returns Zero on success, negative on failure.
  */
-int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
-			 int do_free, int qos)
+void cvm_oct_tx_shutdown_dev(struct net_device *dev)
 {
-	unsigned long flags;
-	union cvmx_buf_ptr hw_buffer;
-	cvmx_pko_command_word0_t pko_command;
-	int dropped;
 	struct octeon_ethernet *priv = netdev_priv(dev);
-	cvmx_wqe_t *work = work_queue_entry;
+	unsigned long flags;
+	int qos;
 
-	if (!(dev->flags & IFF_UP)) {
-		DEBUGPRINT("%s: Device not up\n", dev->name);
-		if (do_free)
-			cvm_oct_free_work(work);
-		return -1;
+	for (qos = 0; qos < 16; qos++) {
+		spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
+		while (skb_queue_len(&priv->tx_free_list[qos]))
+			dev_kfree_skb_any(__skb_dequeue
+					  (&priv->tx_free_list[qos]));
+		spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags);
 	}
+}
 
-	/* The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to completely
-	   remove "qos" in the event neither interface supports
-	   multiple queues per port */
-	if ((CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 > 1) ||
-	    (CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 > 1)) {
-		if (qos <= 0)
-			qos = 0;
-		else if (qos >= cvmx_pko_get_num_queues(priv->port))
-			qos = 0;
-	} else
-		qos = 0;
-
-	/* Start off assuming no drop */
-	dropped = 0;
-
-	local_irq_save(flags);
-	cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos,
-				     CVMX_PKO_LOCK_CMD_QUEUE);
-
-	/* Build the PKO buffer pointer */
-	hw_buffer.u64 = 0;
-	hw_buffer.s.addr = work->packet_ptr.s.addr;
-	hw_buffer.s.pool = CVMX_FPA_PACKET_POOL;
-	hw_buffer.s.size = CVMX_FPA_PACKET_POOL_SIZE;
-	hw_buffer.s.back = work->packet_ptr.s.back;
+static void cvm_oct_tx_do_cleanup(unsigned long arg)
+{
+	int port;
 
-	/* Build the PKO command */
-	pko_command.u64 = 0;
-	pko_command.s.n2 = 1;	/* Don't pollute L2 with the outgoing packet */
-	pko_command.s.dontfree = !do_free;
-	pko_command.s.segs = work->word2.s.bufs;
-	pko_command.s.total_bytes = work->len;
+	for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
+		if (cvm_oct_device[port]) {
+			struct net_device *dev = cvm_oct_device[port];
+			cvm_oct_free_tx_skbs(dev);
+		}
+	}
+}
 
-	/* Check if we can use the hardware checksumming */
-	if (unlikely(work->word2.s.not_IP || work->word2.s.IP_exc))
-		pko_command.s.ipoffp1 = 0;
-	else
-		pko_command.s.ipoffp1 = sizeof(struct ethhdr) + 1;
+static irqreturn_t cvm_oct_tx_cleanup_watchdog(int cpl, void *dev_id)
+{
+	/* Disable the interrupt.  */
+	cvmx_write_csr(CVMX_CIU_TIMX(1), 0);
+	/* Do the work in the tasklet.  */
+	tasklet_schedule(&cvm_oct_tx_cleanup_tasklet);
+	return IRQ_HANDLED;
+}
 
-	/* Send the packet to the output queue */
-	if (unlikely
-	    (cvmx_pko_send_packet_finish
-	     (priv->port, priv->queue + qos, pko_command, hw_buffer,
-	      CVMX_PKO_LOCK_CMD_QUEUE))) {
-		DEBUGPRINT("%s: Failed to send the packet\n", dev->name);
-		dropped = -1;
-	}
-	local_irq_restore(flags);
+void cvm_oct_tx_initialize(void)
+{
+	int i;
 
-	if (unlikely(dropped)) {
-		if (do_free)
-			cvm_oct_free_work(work);
-		priv->stats.tx_dropped++;
-	} else if (do_free)
-		cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
+	/* Disable the interrupt.  */
+	cvmx_write_csr(CVMX_CIU_TIMX(1), 0);
+	/* Register an IRQ hander for to receive CIU_TIMX(1) interrupts */
+	i = request_irq(OCTEON_IRQ_TIMER1,
+			cvm_oct_tx_cleanup_watchdog, 0,
+			"Ethernet", cvm_oct_device);
 
-	return dropped;
+	if (i)
+		panic("Could not acquire Ethernet IRQ %d\n", OCTEON_IRQ_TIMER1);
 }
-EXPORT_SYMBOL(cvm_oct_transmit_qos);
 
-/**
- * This function frees all skb that are currently queued for TX.
- *
- * @dev:    Device being shutdown
- */
-void cvm_oct_tx_shutdown(struct net_device *dev)
+void cvm_oct_tx_shutdown(void)
 {
-	struct octeon_ethernet *priv = netdev_priv(dev);
-	unsigned long flags;
-	int qos;
-
-	for (qos = 0; qos < 16; qos++) {
-		spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
-		while (skb_queue_len(&priv->tx_free_list[qos]))
-			dev_kfree_skb_any(__skb_dequeue
-					  (&priv->tx_free_list[qos]));
-		spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags);
-	}
+	/* Free the interrupt handler */
+	free_irq(OCTEON_IRQ_TIMER1, cvm_oct_device);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-tx.h linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-tx.h
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-tx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-tx.h	2010-05-16 17:17:36.000000000 -0400
@@ -29,29 +29,6 @@ int cvm_oct_xmit(struct sk_buff *skb, st
 int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev);
 int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
 			 int do_free, int qos);
-void cvm_oct_tx_shutdown(struct net_device *dev);
-
-/**
- * Free dead transmit skbs.
- *
- * @priv:		The driver data
- * @skb_to_free:	The number of SKBs to free (free none if negative).
- * @qos:		The queue to free from.
- * @take_lock:		If true, acquire the skb list lock.
- */
-static inline void cvm_oct_free_tx_skbs(struct octeon_ethernet *priv,
-					int skb_to_free,
-					int qos, int take_lock)
-{
-	/* Free skbuffs not in use by the hardware.  */
-	if (skb_to_free > 0) {
-		if (take_lock)
-			spin_lock(&priv->tx_free_list[qos].lock);
-		while (skb_to_free > 0) {
-			dev_kfree_skb(__skb_dequeue(&priv->tx_free_list[qos]));
-			skb_to_free--;
-		}
-		if (take_lock)
-			spin_unlock(&priv->tx_free_list[qos].lock);
-	}
-}
+void cvm_oct_tx_initialize(void);
+void cvm_oct_tx_shutdown(void);
+void cvm_oct_tx_shutdown_dev(struct net_device *dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-util.h linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-util.h
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-util.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-util.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,10 +30,9 @@
 				} while (0)
 
 /**
- * Given a packet data address, return a pointer to the
- * beginning of the packet buffer.
- *
+ * cvm_oct_get_buffer_ptr - convert packet data address to pointer
  * @packet_ptr: Packet data hardware address
+ *
  * Returns Packet buffer pointer
  */
 static inline void *cvm_oct_get_buffer_ptr(union cvmx_buf_ptr packet_ptr)
@@ -43,9 +42,7 @@ static inline void *cvm_oct_get_buffer_p
 }
 
 /**
- * Given an IPD/PKO port number, return the logical interface it is
- * on.
- *
+ * INTERFACE - convert IPD port to locgical interface
  * @ipd_port: Port to check
  *
  * Returns Logical interface
@@ -65,9 +62,7 @@ static inline int INTERFACE(int ipd_port
 }
 
 /**
- * Given an IPD/PKO port number, return the port's index on a
- * logical interface.
- *
+ * INDEX - convert IPD/PKO port number to the port's interface index
  * @ipd_port: Port to check
  *
  * Returns Index into interface port list
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-xaui.c linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-xaui.c
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/ethernet-xaui.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/ethernet-xaui.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 **********************************************************************/
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
-#include <linux/mii.h>
 #include <net/dst.h>
 
 #include <asm/octeon/octeon.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/Makefile linux-libre-2.6.34-gnu1/drivers/staging/octeon/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@ obj-${CONFIG_OCTEON_ETHERNET} :=  octeon
 octeon-ethernet-objs := ethernet.o
 octeon-ethernet-objs += ethernet-mdio.o
 octeon-ethernet-objs += ethernet-mem.o
-octeon-ethernet-objs += ethernet-proc.o
 octeon-ethernet-objs += ethernet-rgmii.o
 octeon-ethernet-objs += ethernet-rx.o
 octeon-ethernet-objs += ethernet-sgmii.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/octeon/octeon-ethernet.h linux-libre-2.6.34-gnu1/drivers/staging/octeon/octeon-ethernet.h
--- linux-libre-2.6.33-gnu1/drivers/staging/octeon/octeon-ethernet.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/octeon/octeon-ethernet.h	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2007 Cavium Networks
+ * Copyright (c) 2003-2010 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -57,58 +57,12 @@ struct octeon_ethernet {
 	uint64_t link_info;
 	/* Called periodically to check link status */
 	void (*poll) (struct net_device *dev);
+	struct delayed_work	port_periodic_work;
+	struct work_struct	port_work;	/* may be unused. */
 };
 
-/**
- * Free a work queue entry received in a intercept callback.
- *
- * @work_queue_entry:
- *               Work queue entry to free
- * Returns Zero on success, Negative on failure.
- */
 int cvm_oct_free_work(void *work_queue_entry);
 
-/**
- * Transmit a work queue entry out of the ethernet port. Both
- * the work queue entry and the packet data can optionally be
- * freed. The work will be freed on error as well.
- *
- * @dev:     Device to transmit out.
- * @work_queue_entry:
- *                Work queue entry to send
- * @do_free: True if the work queue entry and packet data should be
- *                freed. If false, neither will be freed.
- * @qos:     Index into the queues for this port to transmit on. This
- *                is used to implement QoS if their are multiple queues per
- *                port. This parameter must be between 0 and the number of
- *                queues per port minus 1. Values outside of this range will
- *                be change to zero.
- *
- * Returns Zero on success, negative on failure.
- */
-int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
-			 int do_free, int qos);
-
-/**
- * Transmit a work queue entry out of the ethernet port. Both
- * the work queue entry and the packet data can optionally be
- * freed. The work will be freed on error as well. This simply
- * wraps cvmx_oct_transmit_qos() for backwards compatability.
- *
- * @dev:     Device to transmit out.
- * @work_queue_entry:
- *                Work queue entry to send
- * @do_free: True if the work queue entry and packet data should be
- *                freed. If false, neither will be freed.
- *
- * Returns Zero on success, negative on failure.
- */
-static inline int cvm_oct_transmit(struct net_device *dev,
-				   void *work_queue_entry, int do_free)
-{
-	return cvm_oct_transmit_qos(dev, work_queue_entry, do_free, 0);
-}
-
 extern int cvm_oct_rgmii_init(struct net_device *dev);
 extern void cvm_oct_rgmii_uninit(struct net_device *dev);
 extern int cvm_oct_rgmii_open(struct net_device *dev);
@@ -134,5 +88,11 @@ extern int pow_send_group;
 extern int pow_receive_group;
 extern char pow_send_list[];
 extern struct net_device *cvm_oct_device[];
+extern struct workqueue_struct *cvm_oct_poll_queue;
+extern atomic_t cvm_oct_poll_queue_stopping;
+extern u64 cvm_oct_tx_poll_interval;
+
+extern int max_rx_cpus;
+extern int rx_napi_weight;
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/cagg.c linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/cagg.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/cagg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/cagg.c	2010-05-16 17:17:36.000000000 -0400
@@ -1832,14 +1832,12 @@ u16_t zfAggRxClear(zdev_t* dev, u32_t ti
 
 struct agg_tid_rx* zfAggRxEnabled(zdev_t* dev, zbuf_t* buf)
 {
-    u16_t   dst0, src[3], ac, aid, fragOff;
-    u8_t    up;
+    u16_t   dst0, src[3], aid;
     u16_t   offset = 0;
     u16_t   seq_no;
     u16_t frameType;
     u16_t frameCtrl;
     u16_t frameSubtype;
-    u32_t tcp_seq;
     //struct aggSta *agg_sta;
 #if ZM_AGG_FPGA_REORDERING
     struct agg_tid_rx *tid_rx;
@@ -1864,13 +1862,17 @@ struct agg_tid_rx* zfAggRxEnabled(zdev_t
         return NULL;
     }
 #ifdef ZM_ENABLE_PERFORMANCE_EVALUATION
-    tcp_seq = zmw_rx_buf_readb(dev, buf, 22+36) << 24;
-    tcp_seq += zmw_rx_buf_readb(dev, buf, 22+37) << 16;
-    tcp_seq += zmw_rx_buf_readb(dev, buf, 22+38) << 8;
-    tcp_seq += zmw_rx_buf_readb(dev, buf, 22+39);
+    {
+        u32_t tcp_seq;
+
+        tcp_seq = zmw_rx_buf_readb(dev, buf, 22+36) << 24;
+        tcp_seq += zmw_rx_buf_readb(dev, buf, 22+37) << 16;
+        tcp_seq += zmw_rx_buf_readb(dev, buf, 22+38) << 8;
+        tcp_seq += zmw_rx_buf_readb(dev, buf, 22+39);
+        ZM_SEQ_DEBUG("In                   %5d, %12u\n", seq_no, tcp_seq);
+    }
 #endif
 
-    ZM_SEQ_DEBUG("In                   %5d, %12u\n", seq_no, tcp_seq);
     dst0 = zmw_rx_buf_readh(dev, buf, offset+4);
 
     src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/ccmd.c linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/ccmd.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/ccmd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/ccmd.c	2010-05-16 17:17:36.000000000 -0400
@@ -1659,7 +1659,7 @@ void zfiWlanSetPacketTypePromiscuous(zde
 	if (setValue) {
 		/* write register for sniffer mode */
 		zfHpSetSnifferMode(dev, 1);
-		zm_msg0_mm(ZM_LV_1, "enalbe sniffer mode");
+		zm_msg0_mm(ZM_LV_1, "enable sniffer mode");
 	} else {
 		zfHpSetSnifferMode(dev, 0);
 		zm_msg0_mm(ZM_LV_0, "disalbe sniffer mode");
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/cfunc.c linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/cfunc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/cfunc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/cfunc.c	2010-05-16 17:17:36.000000000 -0400
@@ -1194,8 +1194,6 @@ u16_t zfFindMinimumUtilizationChannelInd
     u8_t   i;
     u16_t  tempMinIndex, tempMinValue;
 
-    zmw_get_wlan_dev(dev);
-
     i = 1;
     tempMinIndex = 0;
     tempMinValue = array[tempMinIndex];
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/cmm.c linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/cmm.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/cmm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/cmm.c	2010-05-16 17:17:36.000000000 -0400
@@ -346,8 +346,6 @@ u16_t zfFindSuperGElement(zdev_t* dev, z
     u8_t super_feature;
     u8_t ouiSuperG[6] = {0x00,0x03,0x7f,0x01, 0x01, 0x00};
 
-    zmw_get_wlan_dev(dev);
-
     /* Get offset of first element */
     subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4);
     if ((offset = zgElementOffsetTable[subType]) == 0xff)
@@ -411,8 +409,6 @@ u16_t zfFindXRElement(zdev_t* dev, zbuf_
     u8_t id;
     u8_t ouixr[6] = {0x00,0x03,0x7f,0x03, 0x01, 0x00};
 
-    zmw_get_wlan_dev(dev);
-
     /* Get offset of first element */
     subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4);
     if ((offset = zgElementOffsetTable[subType]) == 0xff)
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/cmmsta.c linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/cmmsta.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/cmmsta.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/cmmsta.c	2010-05-16 17:17:36.000000000 -0400
@@ -2808,7 +2808,7 @@ void zfStaProcessProbeReq(zdev_t* dev, z
     zmw_get_wlan_dev(dev);
 
     /* check mode : AP/IBSS */
-    if ((wd->wlanMode != ZM_MODE_AP) || (wd->wlanMode != ZM_MODE_IBSS))
+    if ((wd->wlanMode != ZM_MODE_AP) && (wd->wlanMode != ZM_MODE_IBSS))
     {
         zm_msg0_mm(ZM_LV_3, "Ignore probe req");
         return;
@@ -4848,8 +4848,6 @@ u16_t zfStaAddIePowerCap(zdev_t* dev, zb
     u8_t MaxTxPower;
     u8_t MinTxPower;
 
-    zmw_get_wlan_dev(dev);
-
     /* Element ID */
     zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_POWER_CAPABILITY);
 
@@ -5276,7 +5274,6 @@ u16_t zfStaRxValidateFrame(zdev_t* dev,
     u8_t   da0;
     //u16_t  sa[3];
     u16_t  ret;
-    u16_t  i;
     //u8_t    sa0;
 
     zmw_get_wlan_dev(dev);
@@ -5738,8 +5735,6 @@ u16_t zfComputeBssInfoWeightValue(zdev_t
 	u8_t  weightOfN40BelowThr = 16;
 	u8_t  weightOfN40UpThr    = 32;
 
-    zmw_get_wlan_dev(dev);
-
     if( isBMode == 0 )
         return (signalStrength + weightOfB);    // pure b mode , do not add the weight value for this AP !
     else
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/cpsmgr.c linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/cpsmgr.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/cpsmgr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/cpsmgr.c	2010-05-16 17:17:36.000000000 -0400
@@ -381,8 +381,6 @@ static void zfPowerSavingMgrSleepIfIdle(
 
 static void zfPowerSavingMgrDisconnectMain(zdev_t* dev)
 {
-    zmw_get_wlan_dev(dev);
-
 #ifdef ZM_ENABLE_DISCONNECT_PS
     switch(wd->sta.psMgr.state)
     {
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/cscanmgr.c linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/cscanmgr.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/cscanmgr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/cscanmgr.c	2010-05-16 17:17:36.000000000 -0400
@@ -289,8 +289,6 @@ static void zfScanMgrEventSetFreqComplet
 
 static void zfScanMgrEventScanCompleteCb(zdev_t* dev)
 {
-    zmw_get_wlan_dev(dev);
-
     if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
     {
         zfSendNullData(dev, 0);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/ctkip.c linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/ctkip.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/ctkip.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/ctkip.c	2010-05-16 17:17:36.000000000 -0400
@@ -255,7 +255,8 @@ void zfTkipInit(u8_t* key, u8_t* ta, str
     zfMemoryCopy(pSeed->ta, ta, 6);
     zfMemoryCopy(pSeed->tk, key, 16);
 
-    iv16 = *initIv++;
+    iv16 = *initIv;
+    initIv++;
     iv16 += *initIv<<8;
     initIv++;
 
@@ -264,7 +265,7 @@ void zfTkipInit(u8_t* key, u8_t* ta, str
     for(i=0; i<4; i++)      // initiv is little endian
     {
         iv32 += *initIv<<(i*8);
-        *initIv++;
+        initIv++;
     }
 
     pSeed->iv32 = iv32+1; // Force Recalculating on Tkip Phase1
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/ctxrx.c linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/ctxrx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/ctxrx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/ctxrx.c	2010-05-16 17:17:36.000000000 -0400
@@ -536,8 +536,7 @@ void zfProtRspSim(zdev_t* dev, zbuf_t* b
         zm_msg2_rx(ZM_LV_2, "ip1=", dip[1]);
 
         //ARP request to 192.168.1.15
-        if ((arpOp == 0x0100) && (dip[0] == 0xa8c0) && (dip[1] == 0x0f01));
-        {
+        if ((arpOp == 0x0100) && (dip[0] == 0xa8c0) && (dip[1] == 0x0f01)) {
             zm_msg0_rx(ZM_LV_2, "ARP");
             /* ARP response */
             zmw_rx_buf_writeh(dev, buf, 20, 0x0200);
@@ -883,7 +882,6 @@ zlError:
 /************************************************************************/
 u16_t zfTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u16_t flag)
 {
-    u16_t err;
     //u16_t addrTblSize;
     //struct zsAddrTbl addrTbl;
     u16_t removeLen;
@@ -905,7 +903,6 @@ u16_t zfTxSendEth(zdev_t* dev, zbuf_t* b
     u8_t qosType, keyIdx = 0;
     u16_t fragOff;
     u16_t newFlag;
-    struct zsMicVar*  pMicKey;
     u8_t tkipFrameOffset = 0;
 
     zmw_get_wlan_dev(dev);
@@ -1693,8 +1690,6 @@ void zfShowTxEAPOL(zdev_t* dev, zbuf_t*
     u16_t  packetLen, keyInfo, keyLen, keyDataLen, length, Op_Code;
     u32_t  replayCounterH, replayCounterL, vendorId, VendorType;
 
-    zmw_get_wlan_dev(dev);
-
     zm_debug_msg1("EAPOL Packet size = ", zfwBufGetSize(dev, buf));
 
     /* EAPOL packet type */
@@ -2437,7 +2432,6 @@ void zfiRecv80211(zdev_t* dev, zbuf_t* b
                     u16_t IvOffset;
                     u8_t keyLen = 5;
                     u8_t iv[3];
-                    u8_t *wepKey;
                     u8_t keyIdx;
 
                     IvOffset = offset + ZM_SIZE_OF_WLAN_DATA_HEADER;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/ledmgr.c linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/ledmgr.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/ledmgr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/ledmgr.c	2010-05-16 17:17:36.000000000 -0400
@@ -187,7 +187,6 @@ void zfLedCtrlType2_scan(zdev_t* dev);
 
 void zfLedCtrlType2(zdev_t* dev)
 {
-    u32_t ton, toff, tmp, period;
     u16_t OperateLED;
     zmw_get_wlan_dev(dev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/pub_zfi.h linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/pub_zfi.h
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/80211core/pub_zfi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/80211core/pub_zfi.h	2010-05-16 17:17:36.000000000 -0400
@@ -814,7 +814,6 @@ extern void zfiRxPerformanceReg(zdev_t*
 #define ZM_PERFORMANCE_RX_AMSDU(dev, buf, len)
 #define ZM_PERFORMANCE_RX_FLUSH(dev)
 #define ZM_PERFORMANCE_RX_CLEAR(dev)
-#define ZM_SEQ_DEBUG
 #define ZM_PERFORMANCE_RX_REORDER(dev)
 #endif
 /***** End of section 3 *****/
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/apdbg.c linux-libre-2.6.34-gnu1/drivers/staging/otus/apdbg.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/apdbg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/apdbg.c	2010-05-16 17:17:36.000000000 -0400
@@ -90,8 +90,27 @@ struct zdap_ioctl {
 
 #endif
 
-char hex(char);
-unsigned char asctohex(char *str);
+static char hex(char v)
+{
+	if (isdigit(v))
+		return v - '0';
+	else if (isxdigit(v))
+		return tolower(v) - 'a' + 10;
+	else
+		return 0;
+}
+
+static unsigned char asctohex(char *str)
+{
+	unsigned char value;
+
+	value = hex(*str) & 0x0f;
+	value = value << 4;
+	str++;
+	value |= hex(*str) & 0x0f;
+
+	return value;
+}
 
 char *prgname;
 
@@ -109,10 +128,10 @@ int set_ioctl(int sock, struct ifreq *re
 
 int read_reg(int sock, struct ifreq *req)
 {
-	struct zdap_ioctl *zdreq = 0;
+	struct zdap_ioctl *zdreq = NULL;
 
 	if (!set_ioctl(sock, req))
-			return -1;
+		return -1;
 
 	/*
 	 * zdreq = (struct zdap_ioctl *)req->ifr_data;
@@ -125,7 +144,7 @@ int read_reg(int sock, struct ifreq *req
 
 int read_mem(int sock, struct ifreq *req)
 {
-	struct zdap_ioctl *zdreq = 0;
+	struct zdap_ioctl *zdreq = NULL;
 	int i;
 
 	if (!set_ioctl(sock, req))
@@ -368,7 +387,7 @@ int main(int argc, char **argv)
 
 		zdreq.addr = addr;
 		zdreq.cmd = ZM_IOCTL_SET_PIBSS_MODE;
-	} else 	{
+	} else {
 		fprintf(stderr, "error action\n");
 		exit(1);
 	}
@@ -380,25 +399,3 @@ fail:
 	exit(0);
 }
 
-unsigned char asctohex(char *str)
-{
-	unsigned char value;
-
-	value = hex(*str) & 0x0f;
-	value = value << 4;
-	str++;
-	value |= hex(*str) & 0x0f;
-
-	return value;
-}
-
-char hex(char v)
-{
-	if (isdigit(v))
-		return v - '0';
-	else if (isxdigit(v))
-		return tolower(v) - 'a' + 10;
-	else
-		return 0;
-}
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/hal/hpmain.c linux-libre-2.6.34-gnu1/drivers/staging/otus/hal/hpmain.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/hal/hpmain.c	2013-05-03 12:10:48.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/hal/hpmain.c	2013-05-03 09:50:19.000000000 -0400
@@ -1310,7 +1310,6 @@ void zfHpSetFrequencyEx(zdev_t* dev, u32
         u8_t extOffset, u8_t initRF)
 {
     u32_t cmd[9];
-    u32_t cmdB[3];
     u16_t ret;
     u8_t old_band;
     u8_t new_band;
@@ -3428,7 +3427,6 @@ void zfSetPowerCalTable(zdev_t* dev, u32
     /* Write PHY regs 672-703 */
     for (i=0; i<128; i+=4)
     {
-        u32_t regAddr = 0x9800 + (672 * 4);
         u32_t val;
 
         val = ((u32_t)vpd_chain1[i+3]<<24) |
@@ -3479,7 +3477,6 @@ void zfSetPowerCalTable(zdev_t* dev, u32
     /* Write PHY regs 672-703 + 0x1000 */
     for (i=0; i<128; i+=4)
     {
-        u32_t regAddr = 0x9800 + (672 * 4) + 0x1000;
         u32_t val;
 
         val = ((u32_t)vpd_chain3[i+3]<<24) |
@@ -4578,7 +4575,6 @@ void zfHpSetRollCallTable(zdev_t* dev)
 void zfHpSetTTSIFSTime(zdev_t* dev, u8_t sifs_time)
 {
     u32_t reg_value = 0;
-    zmw_get_wlan_dev(dev);
 
     sifs_time &= 0x3f;
     reg_value = 0x14400b | (((u32_t)sifs_time)<<24);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/hal/hpreg.c linux-libre-2.6.34-gnu1/drivers/staging/otus/hal/hpreg.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/hal/hpreg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/hal/hpreg.c	2010-05-16 17:17:36.000000000 -0400
@@ -786,45 +786,6 @@ enum {
 	WT1_5760_5800,
 };
 
-static REG_DMN_FREQ_BAND regDmn5GhzTurboFreq[] = {
-	{ 5130, 5210, 5,  6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	/* T1_5130_5210 */
-	{ 5250, 5330, 5,  6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0},	/* T1_5250_5330 */
-	{ 5370, 5490, 5,  6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	/* T1_5370_5490 */
-	{ 5530, 5650, 5,  6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0},	/* T1_5530_5650 */
-
-	{ 5150, 5190, 5,  6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	/* T1_5150_5190 */
-	{ 5230, 5310, 5,  6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0},	/* T1_5230_5310 */
-	{ 5350, 5470, 5,  6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	/* T1_5350_5470 */
-	{ 5510, 5670, 5,  6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0},	/* T1_5510_5670 */
-
-	{ 5200, 5240, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	/* T1_5200_5240 */
-	{ 5200, 5240, 23, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	/* T2_5200_5240 */
-	{ 5210, 5210, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	/* T1_5210_5210 */
-	{ 5210, 5210, 23, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	/* T2_5210_5210 */
-
-	{ 5280, 5280, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0},	/* T1_5280_5280 */
-	{ 5280, 5280, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0},	/* T2_5280_5280 */
-	{ 5250, 5250, 17, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0},	/* T1_5250_5250 */
-	{ 5290, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0},	/* T1_5290_5290 */
-	{ 5250, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0},	/* T1_5250_5290 */
-	{ 5250, 5290, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0},	/* T2_5250_5290 */
-
-	{ 5540, 5660, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0},	/* T1_5540_5660 */
-	{ 5760, 5800, 20, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	/* T1_5760_5800 */
-	{ 5760, 5800, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	/* T2_5760_5800 */
-
-	{ 5765, 5805, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	/* T1_5765_5805 */
-
-	/*
-	 * Below are the WWR frequencies
-	 */
-
-	{ 5210, 5250, 15, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0}, /* WT1_5210_5250 */
-	{ 5290, 5290, 18, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0}, /* WT1_5290_5290 */
-	{ 5540, 5660, 20, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0}, /* WT1_5540_5660 */
-	{ 5760, 5800, 20, 0, 40, 40, NO_DFS, PSCAN_WWR, 0, 0},	/* WT1_5760_5800 */
-};
-
 /*
  * 2GHz 11b channel tags
  */
@@ -864,45 +825,6 @@ enum {
 	W2_2484_2484,
 };
 
-static REG_DMN_FREQ_BAND regDmn2GhzFreq[] = {
-	{ 2312, 2372, 5,  6, 20, 5, NO_DFS, NO_PSCAN, 0, 0},	/* F1_2312_2372 */
-	{ 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0},	/* F2_2312_2372 */
-
-	{ 2412, 2472, 5,  6, 20, 5, NO_DFS, NO_PSCAN, 0, 0},	/* F1_2412_2472 */
-	{ 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0, 0},	/* F2_2412_2472 */
-	{ 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0},	/* F3_2412_2472 */
-
-	{ 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0},	/* F1_2412_2462 */
-	{ 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0, 0},	/* F2_2412_2462 */
-	{ 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0},	/* F1_2432_2442 */
-
-	{ 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0},	/* F1_2457_2472 */
-
-	{ 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0, 0}, /* F1_2467_2472 */
-
-	{ 2484, 2484, 5,  6, 20, 5, NO_DFS, NO_PSCAN, 0, 0},	/* F1_2484_2484 */
-	{ 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0, 0},	/* F2_2484_2484 */
-
-	{ 2512, 2732, 5,  6, 20, 5, NO_DFS, NO_PSCAN, 0, 0},	/* F1_2512_2732 */
-
-	/*
-	 * WWR have powers opened up to 20dBm.  Limits should often come from CTL/Max powers
-	 */
-
-	{ 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0},	/* W1_2312_2372 */
-	{ 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0},	/* W1_2412_2412 */
-	{ 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0},	/* W1_2417_2432 */
-	{ 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0},	/* W1_2437_2442 */
-	{ 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0},	/* W1_2447_2457 */
-	{ 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0},	/* W1_2462_2462 */
-	{ 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* W1_2467_2467 */
-	{ 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0},	/* W2_2467_2467 */
-	{ 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* W1_2472_2472 */
-	{ 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0},	/* W2_2472_2472 */
-	{ 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* W1_2484_2484 */
-	{ 2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0},	/* W2_2484_2484 */
-};
-
 
 /*
  * 2GHz 11g channel tags
@@ -984,16 +906,6 @@ enum {
 	T1_2512_2732
 };
 
-static REG_DMN_FREQ_BAND regDmn2Ghz11gTurboFreq[] = {
-	{ 2312, 2372, 5,  6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},  /* T1_2312_2372 */
-	{ 2437, 2437, 5,  6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},  /* T1_2437_2437 */
-	{ 2437, 2437, 20, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},  /* T2_2437_2437 */
-	{ 2437, 2437, 18, 6, 40, 40, NO_DFS, PSCAN_WWR, 0, 0}, /* T3_2437_2437 */
-	{ 2512, 2732, 5,  6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},  /* T1_2512_2732 */
-};
-
-
-
 /*
  * 2GHz 11n frequency tags
  */
@@ -1005,15 +917,6 @@ enum {
     NG_DEMO_ALL_CHANNELS,
 };
 
-static REG_DMN_FREQ_BAND regDmn2Ghz11ngFreq[] = {
-    { 2422, 2452, 20, 0, 40, 5, NO_DFS, NO_PSCAN, 0, 0},    /* NG1_2422_2452 */
-    { 2422, 2452, 27, 0, 40, 5, NO_DFS, NO_PSCAN, 0, 0},    /* NG2_2422_2452 */
-    { 2422, 2452, 30, 0, 40, 5, NO_DFS, NO_PSCAN, 0, 0},    /* NG3_2422_2452 */
-
-	{ 2312, 2732, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0},    /* NG_DEMO_ALL_CHANNELS */
-};
-
-
 /*
  * 5GHz 11n frequency tags
  */
@@ -1050,42 +953,6 @@ enum {
     NA_DEMO_ALL_CHANNELS,
 };
 
-static REG_DMN_FREQ_BAND regDmn5Ghz11naFreq[] = {
-    /*
-     * ToDo: This table needs to be completely populated with 5GHz 11n properties
-     */
-	{ 5190, 5230, 15,  0, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	    /* NA1_5190_5230 */
-	{ 5190, 5230, 17,  6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	/* NA2_5190_5230 */
-	{ 5190, 5230, 18,  6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	    /* NA3_5190_5230 */
-	{ 5190, 5230, 20,  0, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	/* NA4_5190_5230 */
-	{ 5190, 5230, 23,  6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	    /* NA5_5190_5230 */
-
-	{ 5270, 5270, 23,  6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1},  /* NA1_5270_5270 */
-
-	{ 5270, 5310, 18,  6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1},  /* NA1_5270_5310 */
-	{ 5270, 5310, 20,  0, 40, 40, DFS_FCC3|DFS_ETSI|DFS_MKK4, NO_PSCAN, 0, 1},  /* NA2_5270_5310 */
-	{ 5270, 5310, 23,  6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1},  /* NA3_5270_5310 */
-	{ 5270, 5310, 30,  6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1},  /* NA4_5270_5310 */
-
-	{ 5310, 5310, 17,  6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1},  /* NA1_5310_5310 */
-
-	{ 5510, 5630, 30,  6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1},  /* NA1_5510_5630 */
-
-	{ 5510, 5670, 20,  6, 40, 40, DFS_FCC3|DFS_ETSI|DFS_MKK4, NO_PSCAN, 0, 1},  /* NA1_5510_5670 */
-	{ 5510, 5670, 27,  0, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1},  /* NA2_5510_5670 */
-	{ 5510, 5670, 30,  6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 1},   /* NA3_5510_5670 */
-
-	{ 5755, 5795, 17,  0, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	    /* NA1_5755_5795 */
-	{ 5755, 5795, 20,  6, 40, 40, DFS_ETSI, NO_PSCAN, 0, 0},	    /* NA2_5755_5795 */
-	{ 5755, 5795, 23,  0, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	    /* NA3_5755_5795 */
-	{ 5755, 5795, 30,  0, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	/* NA4_5755_5795 */
-	{ 5755, 5795, 30,  6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	    /* NA5_5755_5795 */
-
-	{ 5795, 5795, 30,  6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	    /* NA1_5795_5795 */
-
-    { 4920, 6100, 30,  6, 40, 40, NO_DFS, NO_PSCAN, 0, 0},	/* NA_DEMO_ALL_CHANNELS */
-};
-
 typedef struct regDomain {
 	u16_t regDmnEnum;	/* value from EnumRd table */
 	u8_t conformanceTestLimit;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/hal/hprw.c linux-libre-2.6.34-gnu1/drivers/staging/otus/hal/hprw.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/hal/hprw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/hal/hprw.c	2010-05-16 17:17:36.000000000 -0400
@@ -282,7 +282,6 @@ void zfIdlRsp(zdev_t* dev, u32_t* rsp, u
     else if (src == ZM_OID_FLASH_READ)
     {
         u32_t  datalen;
-        u16_t i;
 
         datalen = (rsp[0] & 255);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/ioctl.c linux-libre-2.6.34-gnu1/drivers/staging/otus/ioctl.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 /*     Platform dependent.                                              */
 /*                                                                      */
 /************************************************************************/
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/if_arp.h>
 #include <linux/uaccess.h>
@@ -866,15 +867,15 @@ int usbdrvwext_giwscan(struct net_device
 	char *current_ev = extra;
 	char *end_buf;
 	int i;
-	/* struct zsBssList BssList; */
-	struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1),
-								GFP_KERNEL);
 	/* BssList = wd->sta.pBssList; */
 	/* zmw_get_wlan_dev(dev); */
 
 	if (macp->DeviceOpened != 1)
 		return 0;
 
+	/* struct zsBssList BssList; */
+	struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1),
+								GFP_KERNEL);
 	if (data->length == 0)
 		end_buf = extra + IW_SCAN_MAX_DATA;
 	else
@@ -930,7 +931,7 @@ int usbdrvwext_siwessid(struct net_devic
 		return -EINVAL;
 
 	if (essid->flags == 1) {
-		if (essid->length > (IW_ESSID_MAX_SIZE + 1))
+		if (essid->length > IW_ESSID_MAX_SIZE)
 			return -E2BIG;
 
 		if (copy_from_user(&EssidBuf, essid->pointer, essid->length))
@@ -2227,7 +2228,8 @@ int usbdrv_wpa_ioctl(struct net_device *
 	case ZD_CMD_SCAN_REQ:
 		printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SCAN_REQ\n");
 		break;
-	case ZD_CMD_SET_GENERIC_ELEMENT:
+	case ZD_CMD_SET_GENERIC_ELEMENT: {
+		u8_t len, *wpaie;
 		printk(KERN_ERR "usbdrv_wpa_ioctl:"
 					" ZD_CMD_SET_GENERIC_ELEMENT\n");
 
@@ -2250,8 +2252,8 @@ int usbdrv_wpa_ioctl(struct net_device *
 		/* zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data,
 		* zdparm->u.generic_elem.len);
 		*/
-		u8_t len = zdparm->u.generic_elem.len;
-		u8_t *wpaie = (u8_t *)zdparm->u.generic_elem.data;
+		len = zdparm->u.generic_elem.len;
+		wpaie = zdparm->u.generic_elem.data;
 
 		printk(KERN_ERR "wd->ap.wpaLen : % d\n", len);
 
@@ -2273,6 +2275,7 @@ int usbdrv_wpa_ioctl(struct net_device *
 		* #endif
 		*/
 		break;
+	}
 
 	/* #ifdef ZM_HOSTAPD_SUPPORT */
 	case ZD_CMD_GET_TSC:
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/otus/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,8 @@
 config OTUS
 	tristate "Atheros OTUS 802.11n USB wireless support"
 	depends on USB && WLAN && MAC80211
+	select WIRELESS_EXT
+	select WEXT_PRIV
 	default N
 	---help---
 	  Enable support for Atheros 802.11n USB hardware:
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/usbdrv.c linux-libre-2.6.34-gnu1/drivers/staging/otus/usbdrv.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/usbdrv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/usbdrv.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 
 #include "linux/netlink.h"
 #include "linux/rtnetlink.h"
+#include "linux/slab.h"
 
 #include <net/iw_handler.h>
 
@@ -829,7 +830,7 @@ int zfLnxRegisterVapDev(struct net_devic
 {
     /* Allocate net device structure */
     vap[vapId].dev = alloc_etherdev(0);
-    printk("Register vap dev=%x\n", (u32_t)vap[vapId].dev);
+    printk("Register vap dev=%p\n", vap[vapId].dev);
 
     if(vap[vapId].dev == NULL) {
         printk("alloc_etherdev fail\n");
@@ -883,7 +884,7 @@ int zfLnxUnregisterVapDev(struct net_dev
     printk("Unregister VAP dev : %s\n", vap[vapId].dev->name);
 
     if(vap[vapId].dev != NULL) {
-        printk("Unregister vap dev=%x\n", (u32_t)vap[vapId].dev);
+        printk("Unregister vap dev=%p\n", vap[vapId].dev);
         //
         //unregister_netdevice(wds[wdsId].dev);
         unregister_netdev(vap[vapId].dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/usbdrv.h linux-libre-2.6.34-gnu1/drivers/staging/otus/usbdrv.h
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/usbdrv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/usbdrv.h	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/uaccess.h>
 #include <linux/wireless.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 
 #include "zdcompat.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/wrap_mem.c linux-libre-2.6.34-gnu1/drivers/staging/otus/wrap_mem.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/wrap_mem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/wrap_mem.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
+#include <linux/slab.h>
 #include <net/iw_handler.h>
 
 /* Memory management */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/wrap_pkt.c linux-libre-2.6.34-gnu1/drivers/staging/otus/wrap_pkt.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/wrap_pkt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/wrap_pkt.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
+#include <linux/gfp.h>
 #include <net/iw_handler.h>
 
 
@@ -58,7 +59,7 @@ void zfLnxRecv80211(zdev_t *dev, zbuf_t
 			skb1 = skb_copy(buf, GFP_ATOMIC);
 			if (skb1 != NULL) {
 				skb1->dev = dev;
-				skb1->mac_header = skb1->data;
+				skb_reset_mac_header(skb1);
 				skb1->ip_summed = CHECKSUM_NONE;
 				skb1->pkt_type = PACKET_OTHERHOST;
 				/* ETH_P_80211_RAW */
@@ -85,13 +86,7 @@ void zfLnxRecvEth(zdev_t *dev, zbuf_t *b
 	/* new_buf = dev_alloc_skb(2048);	*/
 	new_buf = dev_alloc_skb(buf->len);
 
-#ifdef NET_SKBUFF_DATA_USES_OFFSET
-	new_buf->tail = 0;
-	new_buf->len = 0;
-#else
-	new_buf->tail = new_buf->data;
-	new_buf->len = 0;
-#endif
+	skb_reset_tail_pointer(new_buf);
 
 	skb_put(new_buf, buf->len);
 	memcpy(new_buf->data, buf->data, buf->len);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/wrap_usb.c linux-libre-2.6.34-gnu1/drivers/staging/otus/wrap_usb.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/wrap_usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/wrap_usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
+#include <linux/slab.h>
 #include <net/iw_handler.h>
 
 extern void zfLnxInitUsbTxQ(zdev_t *dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/wwrap.c linux-libre-2.6.34-gnu1/drivers/staging/otus/wwrap.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/wwrap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/wwrap.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
+#include <linux/slab.h>
 #include <net/iw_handler.h>
 
 extern void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/otus/zdusb.c linux-libre-2.6.34-gnu1/drivers/staging/otus/zdusb.c
--- linux-libre-2.6.33-gnu1/drivers/staging/otus/zdusb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/otus/zdusb.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #endif
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "usbdrv.h"
@@ -45,7 +46,7 @@ MODULE_LICENSE("Dual BSD/GPL");
 static const char driver_name[] = "Otus";
 
 /* table of devices that work with this driver */
-static struct usb_device_id zd1221_ids [] = {
+static const struct usb_device_id zd1221_ids[] = {
 	{ USB_DEVICE(VENDOR_ATHR, PRODUCT_AR9170) },
         { USB_DEVICE(VENDOR_DLINK, PRODUCT_DWA160A) },
 	{ USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WNDA3100) },
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/p9auth/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/p9auth/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/p9auth/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/p9auth/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,9 +0,0 @@
-config PLAN9AUTH
-	tristate "Plan 9 style capability device implementation"
-	default n
-	depends on CRYPTO
-	help
-	  This module implements the Plan 9 style capability device.
-
-	  To compile this driver as a module, choose
-	  M here: the module will be called p9auth.
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/p9auth/Makefile linux-libre-2.6.34-gnu1/drivers/staging/p9auth/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/p9auth/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/p9auth/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-obj-$(CONFIG_PLAN9AUTH)	+= p9auth.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/p9auth/p9auth.c linux-libre-2.6.34-gnu1/drivers/staging/p9auth/p9auth.c
--- linux-libre-2.6.33-gnu1/drivers/staging/p9auth/p9auth.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/p9auth/p9auth.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,408 +0,0 @@
-/*
- * Plan 9 style capability device implementation for the Linux Kernel
- *
- * Copyright 2008, 2009 Ashwin Ganti <ashwin.ganti@gmail.com>
- *
- * Released under the GPLv2
- *
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/errno.h>
-#include <linux/fcntl.h>
-#include <linux/cdev.h>
-#include <linux/uaccess.h>
-#include <linux/list.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/crypto.h>
-#include <linux/highmem.h>
-#include <linux/scatterlist.h>
-#include <linux/sched.h>
-#include <linux/cred.h>
-
-#ifndef CAP_MAJOR
-#define CAP_MAJOR 0
-#endif
-
-#ifndef CAP_NR_DEVS
-#define CAP_NR_DEVS 2		/* caphash and capuse */
-#endif
-
-#ifndef CAP_NODE_SIZE
-#define CAP_NODE_SIZE 20
-#endif
-
-#define MAX_DIGEST_SIZE  20
-
-struct cap_node {
-	char data[CAP_NODE_SIZE];
-	struct list_head list;
-};
-
-struct cap_dev {
-	struct cap_node *head;
-	int node_size;
-	unsigned long size;
-	struct semaphore sem;
-	struct cdev cdev;
-};
-
-static int cap_major = CAP_MAJOR;
-static int cap_minor;
-static int cap_nr_devs = CAP_NR_DEVS;
-static int cap_node_size = CAP_NODE_SIZE;
-
-module_param(cap_major, int, S_IRUGO);
-module_param(cap_minor, int, S_IRUGO);
-module_param(cap_nr_devs, int, S_IRUGO);
-
-MODULE_AUTHOR("Ashwin Ganti");
-MODULE_LICENSE("GPL");
-
-static struct cap_dev *cap_devices;
-
-static void hexdump(unsigned char *buf, unsigned int len)
-{
-	while (len--)
-		printk("%02x", *buf++);
-	printk("\n");
-}
-
-static char *cap_hash(char *plain_text, unsigned int plain_text_size,
-		      char *key, unsigned int key_size)
-{
-	struct scatterlist sg;
-	char *result;
-	struct crypto_hash *tfm;
-	struct hash_desc desc;
-	int ret;
-
-	tfm = crypto_alloc_hash("hmac(sha1)", 0, CRYPTO_ALG_ASYNC);
-	if (IS_ERR(tfm)) {
-		printk(KERN_ERR
-		       "failed to load transform for hmac(sha1): %ld\n",
-		       PTR_ERR(tfm));
-		return NULL;
-	}
-
-	desc.tfm = tfm;
-	desc.flags = 0;
-
-	result = kzalloc(MAX_DIGEST_SIZE, GFP_KERNEL);
-	if (!result) {
-		printk(KERN_ERR "out of memory!\n");
-		goto out;
-	}
-
-	sg_set_buf(&sg, plain_text, plain_text_size);
-
-	ret = crypto_hash_setkey(tfm, key, key_size);
-	if (ret) {
-		printk(KERN_ERR "setkey() failed ret=%d\n", ret);
-		kfree(result);
-		result = NULL;
-		goto out;
-	}
-
-	ret = crypto_hash_digest(&desc, &sg, plain_text_size, result);
-	if (ret) {
-		printk(KERN_ERR "digest () failed ret=%d\n", ret);
-		kfree(result);
-		result = NULL;
-		goto out;
-	}
-
-	printk(KERN_DEBUG "crypto hash digest size %d\n",
-	       crypto_hash_digestsize(tfm));
-	hexdump(result, MAX_DIGEST_SIZE);
-
-out:
-	crypto_free_hash(tfm);
-	return result;
-}
-
-static int cap_trim(struct cap_dev *dev)
-{
-	struct cap_node *tmp;
-	struct list_head *pos, *q;
-	if (dev->head != NULL) {
-		list_for_each_safe(pos, q, &(dev->head->list)) {
-			tmp = list_entry(pos, struct cap_node, list);
-			list_del(pos);
-			kfree(tmp);
-		}
-	}
-	return 0;
-}
-
-static int cap_open(struct inode *inode, struct file *filp)
-{
-	struct cap_dev *dev;
-	dev = container_of(inode->i_cdev, struct cap_dev, cdev);
-	filp->private_data = dev;
-
-	/* trim to 0 the length of the device if open was write-only */
-	if ((filp->f_flags & O_ACCMODE) == O_WRONLY) {
-		if (down_interruptible(&dev->sem))
-			return -ERESTARTSYS;
-		cap_trim(dev);
-		up(&dev->sem);
-	}
-	/* initialise the head if it is NULL */
-	if (dev->head == NULL) {
-		dev->head = kmalloc(sizeof(struct cap_node), GFP_KERNEL);
-		INIT_LIST_HEAD(&(dev->head->list));
-	}
-	return 0;
-}
-
-static int cap_release(struct inode *inode, struct file *filp)
-{
-	return 0;
-}
-
-static ssize_t cap_write(struct file *filp, const char __user *buf,
-			 size_t count, loff_t *f_pos)
-{
-	struct cap_node *node_ptr, *tmp;
-	struct list_head *pos;
-	struct cap_dev *dev = filp->private_data;
-	ssize_t retval = -ENOMEM;
-	struct cred *new;
-	int len, target_int, source_int, flag = 0;
-	char *user_buf, *user_buf_running, *source_user, *target_user,
-	    *rand_str, *hash_str, *result;
-
-	if (down_interruptible(&dev->sem))
-		return -ERESTARTSYS;
-
-	user_buf_running = NULL;
-	hash_str = NULL;
-	node_ptr = kmalloc(sizeof(struct cap_node), GFP_KERNEL);
-	user_buf = kzalloc(count+1, GFP_KERNEL);
-	if (!node_ptr || !user_buf)
-		goto out;
-
-	if (copy_from_user(user_buf, buf, count)) {
-		retval = -EFAULT;
-		goto out;
-	}
-
-	/*
-	 * If the minor number is 0 ( /dev/caphash ) then simply add the
-	 * hashed capability supplied by the user to the list of hashes
-	 */
-	if (0 == iminor(filp->f_dentry->d_inode)) {
-		if (count > CAP_NODE_SIZE) {
-			retval = -EINVAL;
-			goto out;
-		}
-		printk(KERN_INFO "Capability being written to /dev/caphash : \n");
-		hexdump(user_buf, count);
-		memcpy(node_ptr->data, user_buf, count);
-		list_add(&(node_ptr->list), &(dev->head->list));
-		node_ptr = NULL;
-	} else {
-		char *tmpu;
-		if (!cap_devices[0].head ||
-				list_empty(&(cap_devices[0].head->list))) {
-			retval = -EINVAL;
-			goto out;
-		}
-		/*
-		 * break the supplied string into tokens with @ as the
-		 * delimiter If the string is "user1@user2@randomstring" we
-		 * need to split it and hash 'user1@user2' using 'randomstring'
-		 * as the key.
-		 */
-		tmpu = user_buf_running = kstrdup(user_buf, GFP_KERNEL);
-		source_user = strsep(&tmpu, "@");
-		target_user = strsep(&tmpu, "@");
-		rand_str = tmpu;
-		if (!source_user || !target_user || !rand_str) {
-			retval = -EINVAL;
-			goto out;
-		}
-
-		/* hash the string user1@user2 with rand_str as the key */
-		len = strlen(source_user) + strlen(target_user) + 1;
-		/* src, @, len, \0 */
-		hash_str = kzalloc(len+1, GFP_KERNEL);
-		strcat(hash_str, source_user);
-		strcat(hash_str, "@");
-		strcat(hash_str, target_user);
-
-		printk(KERN_ALERT "the source user is %s \n", source_user);
-		printk(KERN_ALERT "the target user is %s \n", target_user);
-
-		result = cap_hash(hash_str, len, rand_str, strlen(rand_str));
-		if (NULL == result) {
-			retval = -EFAULT;
-			goto out;
-		}
-		memcpy(node_ptr->data, result, CAP_NODE_SIZE);  /* why? */
-		/* Change the process's uid if the hash is present in the
-		 * list of hashes
-		 */
-		list_for_each(pos, &(cap_devices->head->list)) {
-			/*
-			 * Change the user id of the process if the hashes
-			 * match
-			 */
-			if (0 ==
-			    memcmp(result,
-				   list_entry(pos, struct cap_node,
-					      list)->data,
-				   CAP_NODE_SIZE)) {
-				target_int = (unsigned int)
-				    simple_strtol(target_user, NULL, 0);
-				source_int = (unsigned int)
-				    simple_strtol(source_user, NULL, 0);
-				flag = 1;
-
-				/*
-				 * Check whether the process writing to capuse
-				 * is actually owned by the source owner
-				 */
-				if (source_int != current_uid()) {
-					printk(KERN_ALERT
-					       "Process is not owned by the source user of the capability.\n");
-					retval = -EFAULT;
-					goto out;
-				}
-				/*
-				 * What all id's need to be changed here? uid,
-				 * euid, fsid, savedids ??  Currently I am
-				 * changing the effective user id since most of
-				 * the authorisation decisions are based on it
-				 */
-				new = prepare_creds();
-				if (!new) {
-					retval = -ENOMEM;
-					goto out;
-				}
-				new->uid = (uid_t) target_int;
-				new->euid = (uid_t) target_int;
-				retval = commit_creds(new);
-				if (retval)
-					goto out;
-
-				/*
-				 * Remove the capability from the list and
-				 * break
-				 */
-				tmp = list_entry(pos, struct cap_node, list);
-				list_del(pos);
-				kfree(tmp);
-				break;
-			}
-		}
-		if (0 == flag) {
-			/*
-			 * The capability is not present in the list of the
-			 * hashes stored, hence return failure
-			 */
-			printk(KERN_ALERT
-			       "Invalid capabiliy written to /dev/capuse \n");
-			retval = -EFAULT;
-			goto out;
-		}
-	}
-	*f_pos += count;
-	retval = count;
-	/* update the size */
-	if (dev->size < *f_pos)
-		dev->size = *f_pos;
-
-out:
-	kfree(node_ptr);
-	kfree(user_buf);
-	kfree(user_buf_running);
-	kfree(hash_str);
-	up(&dev->sem);
-	return retval;
-}
-
-static const struct file_operations cap_fops = {
-	.owner = THIS_MODULE,
-	.write = cap_write,
-	.open = cap_open,
-	.release = cap_release,
-};
-
-/* no __exit here because it can be called by the init function */
-static void cap_cleanup_module(void)
-{
-	int i;
-	dev_t devno = MKDEV(cap_major, cap_minor);
-	if (cap_devices) {
-		for (i = 0; i < cap_nr_devs; i++) {
-			cap_trim(cap_devices + i);
-			cdev_del(&cap_devices[i].cdev);
-		}
-		kfree(cap_devices);
-	}
-	unregister_chrdev_region(devno, cap_nr_devs);
-
-}
-
-static void cap_setup_cdev(struct cap_dev *dev, int index)
-{
-	int err, devno = MKDEV(cap_major, cap_minor + index);
-	cdev_init(&dev->cdev, &cap_fops);
-	dev->cdev.owner = THIS_MODULE;
-	dev->cdev.ops = &cap_fops;
-	err = cdev_add(&dev->cdev, devno, 1);
-	if (err)
-		printk(KERN_NOTICE "Error %d adding cap%d", err, index);
-}
-
-static int __init cap_init_module(void)
-{
-	int result, i;
-	dev_t dev = 0;
-
-	if (cap_major) {
-		dev = MKDEV(cap_major, cap_minor);
-		result = register_chrdev_region(dev, cap_nr_devs, "cap");
-	} else {
-		result = alloc_chrdev_region(&dev, cap_minor, cap_nr_devs,
-					     "cap");
-		cap_major = MAJOR(dev);
-	}
-
-	if (result < 0) {
-		printk(KERN_WARNING "cap: can't get major %d\n",
-		       cap_major);
-		return result;
-	}
-
-	cap_devices = kzalloc(cap_nr_devs * sizeof(struct cap_dev),
-			      GFP_KERNEL);
-	if (!cap_devices) {
-		result = -ENOMEM;
-		goto fail;
-	}
-
-	/* Initialize each device. */
-	for (i = 0; i < cap_nr_devs; i++) {
-		cap_devices[i].node_size = cap_node_size;
-		init_MUTEX(&cap_devices[i].sem);
-		cap_setup_cdev(&cap_devices[i], i);
-	}
-
-	return 0;
-
-fail:
-	cap_cleanup_module();
-	return result;
-}
-
-module_init(cap_init_module);
-module_exit(cap_cleanup_module);
-
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/panel/panel.c linux-libre-2.6.34-gnu1/drivers/staging/panel/panel.c
--- linux-libre-2.6.33-gnu1/drivers/staging/panel/panel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/panel/panel.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,6 @@
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/miscdevice.h>
 #include <linux/slab.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/phison/phison.c linux-libre-2.6.34-gnu1/drivers/staging/phison/phison.c
--- linux-libre-2.6.33-gnu1/drivers/staging/phison/phison.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/phison/phison.c	2010-05-16 17:17:36.000000000 -0400
@@ -62,14 +62,14 @@ static int phison_init_one(struct pci_de
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
 
-	ret = ata_pci_sff_init_one(pdev, ppi, &phison_sht, NULL);
+	ret = ata_pci_sff_init_one(pdev, ppi, &phison_sht, NULL, 0);
 
 	dev_dbg(&pdev->dev, "phison_init_one(), ret = %x\n", ret);
 
 	return ret;
 }
 
-static struct pci_device_id phison_pci_tbl[] = {
+static const struct pci_device_id phison_pci_tbl[] = {
 	{ PCI_VENDOR_ID_PHISON, PCI_DEVICE_ID_PS5000, PCI_ANY_ID, PCI_ANY_ID,
 	  PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 },
 	{ 0, },
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/poch/poch.c linux-libre-2.6.34-gnu1/drivers/staging/poch/poch.c
--- linux-libre-2.6.33-gnu1/drivers/staging/poch/poch.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/poch/poch.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/ioctl.h>
 #include <linux/io.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include "poch.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/pohmelfs/config.c linux-libre-2.6.34-gnu1/drivers/staging/pohmelfs/config.c
--- linux-libre-2.6.33-gnu1/drivers/staging/pohmelfs/config.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/pohmelfs/config.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/mutex.h>
 #include <linux/string.h>
 #include <linux/in.h>
+#include <linux/slab.h>
 
 #include "netfs.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/pohmelfs/dir.c linux-libre-2.6.34-gnu1/drivers/staging/pohmelfs/dir.c
--- linux-libre-2.6.33-gnu1/drivers/staging/pohmelfs/dir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/pohmelfs/dir.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/fs.h>
 #include <linux/jhash.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
 
 #include "netfs.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/pohmelfs/inode.c linux-libre-2.6.34-gnu1/drivers/staging/pohmelfs/inode.c
--- linux-libre-2.6.33-gnu1/drivers/staging/pohmelfs/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/pohmelfs/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #define POHMELFS_MAGIC_NUM	0x504f482e
 
 static struct kmem_cache *pohmelfs_inode_cache;
+static atomic_t psb_bdi_num = ATOMIC_INIT(0);
 
 /*
  * Removes inode from all trees, drops local name cache and removes all queued
@@ -322,7 +323,7 @@ int pohmelfs_write_create_inode(struct p
 	t = netfs_trans_alloc(psb, err + 1, 0, 0);
 	if (!t) {
 		err = -ENOMEM;
-		goto err_out_put;
+		goto err_out_exit;
 	}
 	t->complete = pohmelfs_write_inode_complete;
 	t->private = igrab(inode);
@@ -395,7 +396,8 @@ int pohmelfs_remove_child(struct pohmelf
 /*
  * Writeback for given inode.
  */
-static int pohmelfs_write_inode(struct inode *inode, int sync)
+static int pohmelfs_write_inode(struct inode *inode,
+				struct writeback_control *wbc)
 {
 	struct pohmelfs_inode *pi = POHMELFS_I(inode);
 
@@ -969,7 +971,7 @@ int pohmelfs_setattr_raw(struct inode *i
 
 	if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
 	    (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
-		err = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
+		err = dquot_transfer(inode, attr);
 		if (err)
 			goto err_out_exit;
 	}
@@ -1331,6 +1333,8 @@ static void pohmelfs_put_super(struct su
 	pohmelfs_crypto_exit(psb);
 	pohmelfs_state_exit(psb);
 
+	bdi_destroy(&psb->bdi);
+
 	kfree(psb);
 	sb->s_fs_info = NULL;
 }
@@ -1767,8 +1771,7 @@ static int pohmelfs_show_stats(struct se
 		seq_printf(m, "%u ", ctl->idx);
 		if (ctl->addr.sa_family == AF_INET) {
 			struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr;
-			/* seq_printf(m, "%pi4:%u", &sin->sin_addr.s_addr, ntohs(sin->sin_port)); */
-			seq_printf(m, "%u.%u.%u.%u:%u", NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+			seq_printf(m, "%pI4:%u", &sin->sin_addr.s_addr, ntohs(sin->sin_port));
 		} else if (ctl->addr.sa_family == AF_INET6) {
 			struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr;
 			seq_printf(m, "%pi6:%u", &sin->sin6_addr, ntohs(sin->sin6_port));
@@ -1815,11 +1818,22 @@ static int pohmelfs_fill_super(struct su
 	if (!psb)
 		goto err_out_exit;
 
+	err = bdi_init(&psb->bdi);
+	if (err)
+		goto err_out_free_sb;
+
+	err = bdi_register(&psb->bdi, NULL, "pfs-%d", atomic_inc_return(&psb_bdi_num));
+	if (err) {
+		bdi_destroy(&psb->bdi);
+		goto err_out_free_sb;
+	}
+
 	sb->s_fs_info = psb;
 	sb->s_op = &pohmelfs_sb_ops;
 	sb->s_magic = POHMELFS_MAGIC_NUM;
 	sb->s_maxbytes = MAX_LFS_FILESIZE;
 	sb->s_blocksize = PAGE_SIZE;
+	sb->s_bdi = &psb->bdi;
 
 	psb->sb = sb;
 
@@ -1863,11 +1877,11 @@ static int pohmelfs_fill_super(struct su
 
 	err = pohmelfs_parse_options((char *) data, psb, 0);
 	if (err)
-		goto err_out_free_sb;
+		goto err_out_free_bdi;
 
 	err = pohmelfs_copy_crypto(psb);
 	if (err)
-		goto err_out_free_sb;
+		goto err_out_free_bdi;
 
 	err = pohmelfs_state_init(psb);
 	if (err)
@@ -1916,6 +1930,8 @@ err_out_state_exit:
 err_out_free_strings:
 	kfree(psb->cipher_string);
 	kfree(psb->hash_string);
+err_out_free_bdi:
+	bdi_destroy(&psb->bdi);
 err_out_free_sb:
 	kfree(psb);
 err_out_exit:
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/pohmelfs/lock.c linux-libre-2.6.34-gnu1/drivers/staging/pohmelfs/lock.c
--- linux-libre-2.6.33-gnu1/drivers/staging/pohmelfs/lock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/pohmelfs/lock.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/backing-dev.h>
 #include <linux/fs.h>
 #include <linux/fsnotify.h>
-#include <linux/slab.h>
 #include <linux/mempool.h>
 
 #include "netfs.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/pohmelfs/net.c linux-libre-2.6.34-gnu1/drivers/staging/pohmelfs/net.c
--- linux-libre-2.6.33-gnu1/drivers/staging/pohmelfs/net.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/pohmelfs/net.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/kthread.h>
 #include <linux/pagemap.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/swap.h>
 #include <linux/syscalls.h>
 #include <linux/vmalloc.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/pohmelfs/netfs.h linux-libre-2.6.34-gnu1/drivers/staging/pohmelfs/netfs.h
--- linux-libre-2.6.33-gnu1/drivers/staging/pohmelfs/netfs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/pohmelfs/netfs.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 
 #include <linux/types.h>
 #include <linux/connector.h>
+#include <linux/backing-dev.h>
 
 #define POHMELFS_CN_IDX			5
 #define POHMELFS_CN_VAL			0
@@ -624,6 +625,8 @@ struct pohmelfs_sb {
 
 	struct super_block	*sb;
 
+	struct backing_dev_info	bdi;
+
 	/*
 	 * Algorithm strings.
 	 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/pohmelfs/path_entry.c linux-libre-2.6.34-gnu1/drivers/staging/pohmelfs/path_entry.c
--- linux-libre-2.6.33-gnu1/drivers/staging/pohmelfs/path_entry.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/pohmelfs/path_entry.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/ktime.h>
 #include <linux/fs_struct.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/quatech_usb2/quatech_usb2.c linux-libre-2.6.34-gnu1/drivers/staging/quatech_usb2/quatech_usb2.c
--- linux-libre-2.6.33-gnu1/drivers/staging/quatech_usb2/quatech_usb2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/quatech_usb2/quatech_usb2.c	2010-05-16 17:17:36.000000000 -0400
@@ -116,7 +116,7 @@ static int debug;
 #define FOURTHCHAR	((unsigned char *)(urb->transfer_buffer))[i + 3]
 #define FIFTHCHAR	((unsigned char *)(urb->transfer_buffer))[i + 4]
 
-static struct usb_device_id quausb2_id_table[] = {
+static const struct usb_device_id quausb2_id_table[] = {
 	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU2_100)},
 	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_100)},
 	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_400)},
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@ config RAMZSWAP
 	select LZO_DECOMPRESS
 	default n
 	help
-	  Creates virtual block devices which can be used (only) as a swap
+	  Creates virtual block devices which can (only) be used as swap
 	  disks. Pages swapped to these disks are compressed and stored in
 	  memory itself.
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/ramzswap_drv.c linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/ramzswap_drv.c
--- linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/ramzswap_drv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/ramzswap_drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Compressed RAM based swap device
  *
- * Copyright (C) 2008, 2009  Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010  Nitin Gupta
  *
  * This code is released using a dual license strategy: BSD/GPL
  * You can choose the licence that better fits your requirements.
@@ -23,13 +23,12 @@
 #include <linux/device.h>
 #include <linux/genhd.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 #include <linux/lzo.h>
-#include <linux/mutex.h>
 #include <linux/string.h>
 #include <linux/swap.h>
 #include <linux/swapops.h>
 #include <linux/vmalloc.h>
-#include <linux/version.h>
 
 #include "ramzswap_drv.h"
 
@@ -222,7 +221,7 @@ out:
 	return ret;
 }
 
-void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
+static void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
 			struct ramzswap_ioctl_stats *s)
 {
 	strncpy(s->backing_swap_name, rzs->backing_swap_name,
@@ -240,7 +239,8 @@ void ramzswap_ioctl_get_stats(struct ram
 
 	mem_used = xv_get_total_size_bytes(rzs->mem_pool)
 			+ (rs->pages_expand << PAGE_SHIFT);
-	succ_writes = rs->num_writes - rs->failed_writes;
+	succ_writes = rzs_stat64_read(rzs, &rs->num_writes) -
+			rzs_stat64_read(rzs, &rs->failed_writes);
 
 	if (succ_writes && rs->pages_stored) {
 		good_compress_perc = rs->good_compress * 100
@@ -249,11 +249,12 @@ void ramzswap_ioctl_get_stats(struct ram
 					/ rs->pages_stored;
 	}
 
-	s->num_reads = rs->num_reads;
-	s->num_writes = rs->num_writes;
-	s->failed_reads = rs->failed_reads;
-	s->failed_writes = rs->failed_writes;
-	s->invalid_io = rs->invalid_io;
+	s->num_reads = rzs_stat64_read(rzs, &rs->num_reads);
+	s->num_writes = rzs_stat64_read(rzs, &rs->num_writes);
+	s->failed_reads = rzs_stat64_read(rzs, &rs->failed_reads);
+	s->failed_writes = rzs_stat64_read(rzs, &rs->failed_writes);
+	s->invalid_io = rzs_stat64_read(rzs, &rs->invalid_io);
+	s->notify_free = rzs_stat64_read(rzs, &rs->notify_free);
 	s->pages_zero = rs->pages_zero;
 
 	s->good_compress_pct = good_compress_perc;
@@ -265,8 +266,8 @@ void ramzswap_ioctl_get_stats(struct ram
 	s->compr_data_size = rs->compr_size;
 	s->mem_used_total = mem_used;
 
-	s->bdev_num_reads = rs->bdev_num_reads;
-	s->bdev_num_writes = rs->bdev_num_writes;
+	s->bdev_num_reads = rzs_stat64_read(rzs, &rs->bdev_num_reads);
+	s->bdev_num_writes = rzs_stat64_read(rzs, &rs->bdev_num_writes);
 	}
 #endif /* CONFIG_RAMZSWAP_STATS */
 }
@@ -502,6 +503,14 @@ static int setup_backing_swap(struct ram
 			goto bad_param;
 		}
 		disksize = i_size_read(inode);
+		/*
+		 * Can happen if user gives an extended partition as
+		 * backing swap or simply a bad disk.
+		 */
+		if (!disksize) {
+			pr_err("Error reading backing swap size.\n");
+			goto bad_param;
+		}
 	} else if (S_ISREG(inode->i_mode)) {
 		bdev = inode->i_sb->s_bdev;
 		if (IS_SWAPFILE(inode)) {
@@ -519,7 +528,6 @@ static int setup_backing_swap(struct ram
 	rzs->swap_file = swap_file;
 	rzs->backing_swap = bdev;
 	rzs->disksize = disksize;
-	BUG_ON(!rzs->disksize);
 
 	return 0;
 
@@ -537,7 +545,7 @@ out:
  * Map logical page number 'pagenum' to physical page number
  * on backing swap device. For block device, this is a nop.
  */
-u32 map_backing_swap_page(struct ramzswap *rzs, u32 pagenum)
+static u32 map_backing_swap_page(struct ramzswap *rzs, u32 pagenum)
 {
 	u32 skip_pages, entries_per_page;
 	size_t delta, se_offset, skipped;
@@ -593,9 +601,13 @@ static void ramzswap_free_page(struct ra
 	u32 offset = rzs->table[index].offset;
 
 	if (unlikely(!page)) {
+		/*
+		 * No memory is allocated for zero filled pages.
+		 * Simply clear zero page flag.
+		 */
 		if (rzs_test_flag(rzs, index, RZS_ZERO)) {
 			rzs_clear_flag(rzs, index, RZS_ZERO);
-			stat_dec(rzs->stats.pages_zero);
+			rzs_stat_dec(&rzs->stats.pages_zero);
 		}
 		return;
 	}
@@ -604,7 +616,7 @@ static void ramzswap_free_page(struct ra
 		clen = PAGE_SIZE;
 		__free_page(page);
 		rzs_clear_flag(rzs, index, RZS_UNCOMPRESSED);
-		stat_dec(rzs->stats.pages_expand);
+		rzs_stat_dec(&rzs->stats.pages_expand);
 		goto out;
 	}
 
@@ -614,11 +626,11 @@ static void ramzswap_free_page(struct ra
 
 	xv_free(rzs->mem_pool, page, offset);
 	if (clen <= PAGE_SIZE / 2)
-		stat_dec(rzs->stats.good_compress);
+		rzs_stat_dec(&rzs->stats.good_compress);
 
 out:
 	rzs->stats.compr_size -= clen;
-	stat_dec(rzs->stats.pages_stored);
+	rzs_stat_dec(&rzs->stats.pages_stored);
 
 	rzs->table[index].page = NULL;
 	rzs->table[index].offset = 0;
@@ -664,7 +676,6 @@ static int handle_uncompressed_page(stru
 	return 0;
 }
 
-
 /*
  * Called when request page is not present in ramzswap.
  * Its either in backing swap device (if present) or
@@ -680,8 +691,8 @@ static int handle_ramzswap_fault(struct
 	 */
 	if (rzs->backing_swap) {
 		u32 pagenum;
-		stat_dec(rzs->stats.num_reads);
-		stat_inc(rzs->stats.bdev_num_reads);
+		rzs_stat64_dec(rzs, &rzs->stats.num_reads);
+		rzs_stat64_inc(rzs, &rzs->stats.bdev_num_reads);
 		bio->bi_bdev = rzs->backing_swap;
 
 		/*
@@ -719,7 +730,7 @@ static int ramzswap_read(struct ramzswap
 	struct zobj_header *zheader;
 	unsigned char *user_mem, *cmem;
 
-	stat_inc(rzs->stats.num_reads);
+	rzs_stat64_inc(rzs, &rzs->stats.num_reads);
 
 	page = bio->bi_io_vec[0].bv_page;
 	index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
@@ -731,7 +742,7 @@ static int ramzswap_read(struct ramzswap
 	if (!rzs->table[index].page)
 		return handle_ramzswap_fault(rzs, bio);
 
-	/* Page is stored uncompressed since its incompressible */
+	/* Page is stored uncompressed since it's incompressible */
 	if (unlikely(rzs_test_flag(rzs, index, RZS_UNCOMPRESSED)))
 		return handle_uncompressed_page(rzs, bio);
 
@@ -753,7 +764,7 @@ static int ramzswap_read(struct ramzswap
 	if (unlikely(ret != LZO_E_OK)) {
 		pr_err("Decompression failed! err=%d, page=%u\n",
 			ret, index);
-		stat_inc(rzs->stats.failed_reads);
+		rzs_stat64_inc(rzs, &rzs->stats.failed_reads);
 		goto out;
 	}
 
@@ -777,7 +788,7 @@ static int ramzswap_write(struct ramzswa
 	struct page *page, *page_store;
 	unsigned char *user_mem, *cmem, *src;
 
-	stat_inc(rzs->stats.num_writes);
+	rzs_stat64_inc(rzs, &rzs->stats.num_writes);
 
 	page = bio->bi_io_vec[0].bv_page;
 	index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
@@ -789,25 +800,16 @@ static int ramzswap_write(struct ramzswa
 	 * is no longer referenced by any process. So, its now safe
 	 * to free the memory that was allocated for this page.
 	 */
-	if (rzs->table[index].page)
+	if (rzs->table[index].page || rzs_test_flag(rzs, index, RZS_ZERO))
 		ramzswap_free_page(rzs, index);
 
-	/*
-	 * No memory ia allocated for zero filled pages.
-	 * Simply clear zero page flag.
-	 */
-	if (rzs_test_flag(rzs, index, RZS_ZERO)) {
-		stat_dec(rzs->stats.pages_zero);
-		rzs_clear_flag(rzs, index, RZS_ZERO);
-	}
-
 	mutex_lock(&rzs->lock);
 
 	user_mem = kmap_atomic(page, KM_USER0);
 	if (page_zero_filled(user_mem)) {
 		kunmap_atomic(user_mem, KM_USER0);
 		mutex_unlock(&rzs->lock);
-		stat_inc(rzs->stats.pages_zero);
+		rzs_stat_inc(&rzs->stats.pages_zero);
 		rzs_set_flag(rzs, index, RZS_ZERO);
 
 		set_bit(BIO_UPTODATE, &bio->bi_flags);
@@ -831,7 +833,7 @@ static int ramzswap_write(struct ramzswa
 	if (unlikely(ret != LZO_E_OK)) {
 		mutex_unlock(&rzs->lock);
 		pr_err("Compression failed! err=%d\n", ret);
-		stat_inc(rzs->stats.failed_writes);
+		rzs_stat64_inc(rzs, &rzs->stats.failed_writes);
 		goto out;
 	}
 
@@ -854,13 +856,13 @@ static int ramzswap_write(struct ramzswa
 			mutex_unlock(&rzs->lock);
 			pr_info("Error allocating memory for incompressible "
 				"page: %u\n", index);
-			stat_inc(rzs->stats.failed_writes);
+			rzs_stat64_inc(rzs, &rzs->stats.failed_writes);
 			goto out;
 		}
 
 		offset = 0;
 		rzs_set_flag(rzs, index, RZS_UNCOMPRESSED);
-		stat_inc(rzs->stats.pages_expand);
+		rzs_stat_inc(&rzs->stats.pages_expand);
 		rzs->table[index].page = page_store;
 		src = kmap_atomic(page, KM_USER0);
 		goto memstore;
@@ -872,7 +874,7 @@ static int ramzswap_write(struct ramzswa
 		mutex_unlock(&rzs->lock);
 		pr_info("Error allocating memory for compressed "
 			"page: %u, size=%zu\n", index, clen);
-		stat_inc(rzs->stats.failed_writes);
+		rzs_stat64_inc(rzs, &rzs->stats.failed_writes);
 		if (rzs->backing_swap)
 			fwd_write_request = 1;
 		goto out;
@@ -901,9 +903,9 @@ memstore:
 
 	/* Update stats */
 	rzs->stats.compr_size += clen;
-	stat_inc(rzs->stats.pages_stored);
+	rzs_stat_inc(&rzs->stats.pages_stored);
 	if (clen <= PAGE_SIZE / 2)
-		stat_inc(rzs->stats.good_compress);
+		rzs_stat_inc(&rzs->stats.good_compress);
 
 	mutex_unlock(&rzs->lock);
 
@@ -913,7 +915,7 @@ memstore:
 
 out:
 	if (fwd_write_request) {
-		stat_inc(rzs->stats.bdev_num_writes);
+		rzs_stat64_inc(rzs, &rzs->stats.bdev_num_writes);
 		bio->bi_bdev = rzs->backing_swap;
 #if 0
 		/*
@@ -941,7 +943,6 @@ out:
 	return 0;
 }
 
-
 /*
  * Check if request is within bounds and page aligned.
  */
@@ -975,7 +976,7 @@ static int ramzswap_make_request(struct
 	}
 
 	if (!valid_swap_request(rzs, bio)) {
-		stat_inc(rzs->stats.invalid_io);
+		rzs_stat64_inc(rzs, &rzs->stats.invalid_io);
 		bio_io_error(bio);
 		return 0;
 	}
@@ -1000,6 +1001,9 @@ static void reset_device(struct ramzswap
 	unsigned entries_per_page;
 	unsigned long num_table_pages, entry = 0;
 
+	/* Do not accept any new I/O request */
+	rzs->init_done = 0;
+
 	if (rzs->backing_swap && !rzs->num_extents)
 		is_backing_blkdev = 1;
 
@@ -1066,6 +1070,7 @@ static void reset_device(struct ramzswap
 			bd_release(rzs->backing_swap);
 		filp_close(rzs->swap_file, NULL);
 		rzs->backing_swap = NULL;
+		memset(rzs->backing_swap_name, 0, MAX_SWAP_NAME_LEN);
 	}
 
 	/* Reset stats */
@@ -1073,9 +1078,6 @@ static void reset_device(struct ramzswap
 
 	rzs->disksize = 0;
 	rzs->memlimit = 0;
-
-	/* Back to uninitialized state */
-	rzs->init_done = 0;
 }
 
 static int ramzswap_ioctl_init_device(struct ramzswap *rzs)
@@ -1276,6 +1278,11 @@ static int ramzswap_ioctl(struct block_d
 			ret = -EBUSY;
 			goto out;
 		}
+
+		/* Make sure all pending I/O is finished */
+		if (bdev)
+			fsync_bdev(bdev);
+
 		ret = ramzswap_ioctl_reset_device(rzs);
 		break;
 
@@ -1293,16 +1300,20 @@ static struct block_device_operations ra
 	.owner = THIS_MODULE,
 };
 
-static void create_device(struct ramzswap *rzs, int device_id)
+static int create_device(struct ramzswap *rzs, int device_id)
 {
+	int ret = 0;
+
 	mutex_init(&rzs->lock);
+	spin_lock_init(&rzs->stat64_lock);
 	INIT_LIST_HEAD(&rzs->backing_swap_extent_list);
 
 	rzs->queue = blk_alloc_queue(GFP_KERNEL);
 	if (!rzs->queue) {
 		pr_err("Error allocating disk queue for device %d\n",
 			device_id);
-		return;
+		ret = -ENOMEM;
+		goto out;
 	}
 
 	blk_queue_make_request(rzs->queue, ramzswap_make_request);
@@ -1314,7 +1325,8 @@ static void create_device(struct ramzswa
 		blk_cleanup_queue(rzs->queue);
 		pr_warning("Error allocating disk structure for device %d\n",
 			device_id);
-		return;
+		ret = -ENOMEM;
+		goto out;
 	}
 
 	rzs->disk->major = ramzswap_major;
@@ -1329,9 +1341,16 @@ static void create_device(struct ramzswa
 	 * or set equal to backing swap device (if provided)
 	 */
 	set_capacity(rzs->disk, 0);
+
+	blk_queue_physical_block_size(rzs->disk->queue, PAGE_SIZE);
+	blk_queue_logical_block_size(rzs->disk->queue, PAGE_SIZE);
+
 	add_disk(rzs->disk);
 
 	rzs->init_done = 0;
+
+out:
+	return ret;
 }
 
 static void destroy_device(struct ramzswap *rzs)
@@ -1347,18 +1366,20 @@ static void destroy_device(struct ramzsw
 
 static int __init ramzswap_init(void)
 {
-	int i, ret;
+	int ret, dev_id;
 
 	if (num_devices > max_num_devices) {
 		pr_warning("Invalid value for num_devices: %u\n",
 				num_devices);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 
 	ramzswap_major = register_blkdev(0, "ramzswap");
 	if (ramzswap_major <= 0) {
 		pr_warning("Unable to get major number\n");
-		return -EBUSY;
+		ret = -EBUSY;
+		goto out;
 	}
 
 	if (!num_devices) {
@@ -1371,15 +1392,23 @@ static int __init ramzswap_init(void)
 	devices = kzalloc(num_devices * sizeof(struct ramzswap), GFP_KERNEL);
 	if (!devices) {
 		ret = -ENOMEM;
-		goto out;
+		goto unregister;
 	}
 
-	for (i = 0; i < num_devices; i++)
-		create_device(&devices[i], i);
+	for (dev_id = 0; dev_id < num_devices; dev_id++) {
+		ret = create_device(&devices[dev_id], dev_id);
+		if (ret)
+			goto free_devices;
+	}
 
 	return 0;
-out:
+
+free_devices:
+	while (dev_id)
+		destroy_device(&devices[--dev_id]);
+unregister:
 	unregister_blkdev(ramzswap_major, "ramzswap");
+out:
 	return ret;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/ramzswap_drv.h linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/ramzswap_drv.h
--- linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/ramzswap_drv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/ramzswap_drv.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Compressed RAM based swap device
  *
- * Copyright (C) 2008, 2009  Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010  Nitin Gupta
  *
  * This code is released using a dual license strategy: BSD/GPL
  * You can choose the licence that better fits your requirements.
@@ -15,6 +15,9 @@
 #ifndef _RAMZSWAP_DRV_H_
 #define _RAMZSWAP_DRV_H_
 
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+
 #include "ramzswap_ioctl.h"
 #include "xvmalloc.h"
 
@@ -71,15 +74,6 @@ static const unsigned max_zpage_size_nob
 #define SECTORS_PER_PAGE_SHIFT	(PAGE_SHIFT - SECTOR_SHIFT)
 #define SECTORS_PER_PAGE	(1 << SECTORS_PER_PAGE_SHIFT)
 
-/* Debugging and Stats */
-#if defined(CONFIG_RAMZSWAP_STATS)
-#define stat_inc(stat)	((stat)++)
-#define stat_dec(stat)	((stat)--)
-#else
-#define stat_inc(x)
-#define stat_dec(x)
-#endif
-
 /* Flags for ramzswap pages (table[page_no].flags) */
 enum rzs_pageflags {
 	/* Page is stored uncompressed */
@@ -102,7 +96,7 @@ struct table {
 	u16 offset;
 	u8 count;	/* object ref count (not yet used) */
 	u8 flags;
-} __attribute__((aligned(4)));;
+} __attribute__((aligned(4)));
 
 /*
  * Swap extent information in case backing swap is a regular
@@ -121,9 +115,10 @@ struct ramzswap_stats {
 #if defined(CONFIG_RAMZSWAP_STATS)
 	u64 num_reads;		/* failed + successful */
 	u64 num_writes;		/* --do-- */
-	u64 failed_reads;	/* can happen when memory is too low */
-	u64 failed_writes;	/* should NEVER! happen */
+	u64 failed_reads;	/* should NEVER! happen */
+	u64 failed_writes;	/* can happen when memory is too low */
 	u64 invalid_io;		/* non-swap I/O requests */
+	u64 notify_free;	/* no. of swap slot free notifications */
 	u32 pages_zero;		/* no. of zero filled pages */
 	u32 pages_stored;	/* no. of pages currently stored */
 	u32 good_compress;	/* % of pages with compression ratio<=50% */
@@ -138,6 +133,7 @@ struct ramzswap {
 	void *compress_workmem;
 	void *compress_buffer;
 	struct table *table;
+	spinlock_t stat64_lock;	/* protect 64-bit stats */
 	struct mutex lock;
 	struct request_queue *queue;
 	struct gendisk *disk;
@@ -167,5 +163,48 @@ struct ramzswap {
 
 /*-- */
 
-#endif
+/* Debugging and Stats */
+#if defined(CONFIG_RAMZSWAP_STATS)
+static void rzs_stat_inc(u32 *v)
+{
+	*v = *v + 1;
+}
+
+static void rzs_stat_dec(u32 *v)
+{
+	*v = *v - 1;
+}
 
+static void rzs_stat64_inc(struct ramzswap *rzs, u64 *v)
+{
+	spin_lock(&rzs->stat64_lock);
+	*v = *v + 1;
+	spin_unlock(&rzs->stat64_lock);
+}
+
+static void rzs_stat64_dec(struct ramzswap *rzs, u64 *v)
+{
+	spin_lock(&rzs->stat64_lock);
+	*v = *v - 1;
+	spin_unlock(&rzs->stat64_lock);
+}
+
+static u64 rzs_stat64_read(struct ramzswap *rzs, u64 *v)
+{
+	u64 val;
+
+	spin_lock(&rzs->stat64_lock);
+	val = *v;
+	spin_unlock(&rzs->stat64_lock);
+
+	return val;
+}
+#else
+#define rzs_stat_inc(v)
+#define rzs_stat_dec(v)
+#define rzs_stat64_inc(r, v)
+#define rzs_stat64_dec(r, v)
+#define rzs_stat64_read(r, v)
+#endif /* CONFIG_RAMZSWAP_STATS */
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/ramzswap_ioctl.h linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/ramzswap_ioctl.h
--- linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/ramzswap_ioctl.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/ramzswap_ioctl.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Compressed RAM based swap device
  *
- * Copyright (C) 2008, 2009  Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010  Nitin Gupta
  *
  * This code is released using a dual license strategy: BSD/GPL
  * You can choose the licence that better fits your requirements.
@@ -24,9 +24,10 @@ struct ramzswap_ioctl_stats {
 				 * size (if present) */
 	u64 num_reads;		/* failed + successful */
 	u64 num_writes;		/* --do-- */
-	u64 failed_reads;	/* can happen when memory is too low */
-	u64 failed_writes;	/* should NEVER! happen */
+	u64 failed_reads;	/* should NEVER! happen */
+	u64 failed_writes;	/* can happen when memory is too low */
 	u64 invalid_io;		/* non-swap I/O requests */
+	u64 notify_free;	/* no. of swap slot free notifications */
 	u32 pages_zero;		/* no. of zero filled pages */
 	u32 good_compress_pct;	/* no. of pages with compression ratio<=50% */
 	u32 pages_expand_pct;	/* no. of incompressible pages */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/ramzswap.txt linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/ramzswap.txt
--- linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/ramzswap.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/ramzswap.txt	2010-05-16 17:17:36.000000000 -0400
@@ -5,9 +5,9 @@ Project home: http://compcache.googlecod
 
 * Introduction
 
-It creates RAM based block devices which can be used (only) as swap disks.
-Pages swapped to these devices are compressed and stored in memory itself.
-See project home for use cases, performance numbers and a lot more.
+The ramzswap module creates RAM based block devices which can (only) be used as
+swap disks. Pages swapped to these devices are compressed and stored in memory
+itself. See project home for use cases, performance numbers and a lot more.
 
 Individual ramzswap devices are configured and initialized using rzscontrol
 userspace utility as shown in examples below. See rzscontrol man page for more
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/xvmalloc.c linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/xvmalloc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/xvmalloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/xvmalloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * xvmalloc memory allocator
  *
- * Copyright (C) 2008, 2009  Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010  Nitin Gupta
  *
  * This code is released using a dual license strategy: BSD/GPL
  * You can choose the licence that better fits your requirements.
@@ -273,7 +273,7 @@ static void remove_block(struct xv_pool
 }
 
 /*
- * Allocate a page and add it freelist of given pool.
+ * Allocate a page and add it to freelist of given pool.
  */
 static int grow_pool(struct xv_pool *pool, gfp_t flags)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/xvmalloc.h linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/xvmalloc.h
--- linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/xvmalloc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/xvmalloc.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * xvmalloc memory allocator
  *
- * Copyright (C) 2008, 2009  Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010  Nitin Gupta
  *
  * This code is released using a dual license strategy: BSD/GPL
  * You can choose the licence that better fits your requirements.
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/xvmalloc_int.h linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/xvmalloc_int.h
--- linux-libre-2.6.33-gnu1/drivers/staging/ramzswap/xvmalloc_int.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/ramzswap/xvmalloc_int.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * xvmalloc memory allocator
  *
- * Copyright (C) 2008, 2009  Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010  Nitin Gupta
  *
  * This code is released using a dual license strategy: BSD/GPL
  * You can choose the licence that better fits your requirements.
@@ -62,7 +62,7 @@ struct link_free {
 
 struct block_header {
 	union {
-		/* This common header must be ALIGN bytes */
+		/* This common header must be XV_ALIGN bytes */
 		u8 common[XV_ALIGN];
 		struct {
 			u16 size;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rar/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/rar/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/rar/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rar/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-#
-# RAR device configuration
-#
-
-menu "RAR Register Driver"
-#
-#	Restricted Access Register Manager
-#
-config RAR_REGISTER
-	tristate "Restricted Access Region Register Driver"
-	default n
-	---help---
-		This driver allows other kernel drivers access to the
-		contents of the restricted access region control
-		registers.
-
-endmenu
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rar/Makefile linux-libre-2.6.34-gnu1/drivers/staging/rar/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/rar/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rar/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,2 +0,0 @@
-EXTRA_CFLAGS += -DLITTLE__ENDIAN
-obj-$(CONFIG_RAR_REGISTER) += rar_driver.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rar/rar_driver.c linux-libre-2.6.34-gnu1/drivers/staging/rar/rar_driver.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rar/rar_driver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rar/rar_driver.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,444 +0,0 @@
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/kdev_t.h>
-#include <linux/semaphore.h>
-#include <linux/mm.h>
-#include <linux/poll.h>
-#include <linux/wait.h>
-#include <linux/ioctl.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/pagemap.h>
-#include <linux/pci.h>
-#include <linux/firmware.h>
-#include <linux/sched.h>
-#include "rar_driver.h"
-
-/* The following defines are for the IPC process to retrieve RAR in */
-
-/* === Lincroft Message Bus Interface === */
-/* Message Control Register */
-#define LNC_MCR_OFFSET 0xD0
-
-/* Message Data Register */
-#define LNC_MDR_OFFSET 0xD4
-
-/* Message Opcodes */
-#define LNC_MESSAGE_READ_OPCODE  0xD0
-#define LNC_MESSAGE_WRITE_OPCODE 0xE0
-
-/* Message Write Byte Enables */
-#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF
-
-/* B-unit Port */
-#define LNC_BUNIT_PORT 0x3
-
-/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */
-#define LNC_BRAR0L  0x10
-#define LNC_BRAR0H  0x11
-#define LNC_BRAR1L  0x12
-#define LNC_BRAR1H  0x13
-
-/* Reserved for SeP */
-#define LNC_BRAR2L  0x14
-#define LNC_BRAR2H  0x15
-
-
-/* This structure is only used during module initialization. */
-struct RAR_offsets {
-	int low; /* Register offset for low RAR physical address. */
-	int high; /* Register offset for high RAR physical address. */
-};
-
-struct pci_dev *rar_dev;
-static uint32_t registered;
-
-/* Moorestown supports three restricted access regions. */
-#define MRST_NUM_RAR 3
-
-struct RAR_address_struct rar_addr[MRST_NUM_RAR];
-
-/* prototype for init */
-static int __init rar_init_handler(void);
-static void __exit rar_exit_handler(void);
-
-/*
-  function that is activated on the successfull probe of the RAR device
-*/
-static int __devinit rar_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
-
-static struct pci_device_id rar_pci_id_tbl[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4110) },
-	{ 0 }
-};
-
-MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl);
-
-/* field for registering driver to PCI device */
-static struct pci_driver rar_pci_driver = {
-	.name = "rar_driver",
-	.id_table = rar_pci_id_tbl,
-	.probe = rar_probe
-};
-
-/* This function is used to retrieved RAR info using the IPC message
-   bus interface */
-static int memrar_get_rar_addr(struct pci_dev* pdev,
-	                      int offset,
-	                      u32 *addr)
-{
-	/*
-	 * ======== The Lincroft Message Bus Interface ========
-	 * Lincroft registers may be obtained from the PCI
-	 * (the Host Bridge) using the Lincroft Message Bus
-	 * Interface.  That message bus interface is generally
-	 * comprised of two registers: a control register (MCR, 0xDO)
-	 * and a data register (MDR, 0xD4).
-	 *
-	 * The MCR (message control register) format is the following:
-	 *   1.  [31:24]: Opcode
-	 *   2.  [23:16]: Port
-	 *   3.  [15:8]: Register Offset
-	 *   4.  [7:4]: Byte Enables (use 0xF to set all of these bits
-	 *              to 1)
-	 *   5.  [3:0]: reserved
-	 *
-	 *  Read (0xD0) and write (0xE0) opcodes are written to the
-	 *  control register when reading and writing to Lincroft
-	 *  registers, respectively.
-	 *
-	 *  We're interested in registers found in the Lincroft
-	 *  B-unit.  The B-unit port is 0x3.
-	 *
-	 *  The six B-unit RAR register offsets we use are listed
-	 *  earlier in this file.
-	 *
-	 *  Lastly writing to the MCR register requires the "Byte
-	 *  enables" bits to be set to 1.  This may be achieved by
-	 *  writing 0xF at bit 4.
-	 *
-	 * The MDR (message data register) format is the following:
-	 *   1. [31:0]: Read/Write Data
-	 *
-	 *  Data being read from this register is only available after
-	 *  writing the appropriate control message to the MCR
-	 *  register.
-	 *
-	 *  Data being written to this register must be written before
-	 *  writing the appropriate control message to the MCR
-	 *  register.
-	 */
-
-	int result = 0; /* result */
-	/* Construct control message */
-	u32 const message =
-	       (LNC_MESSAGE_READ_OPCODE << 24)
-	       | (LNC_BUNIT_PORT << 16)
-	       | (offset << 8)
-	       | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
-
-	printk(KERN_WARNING "rar- offset to LNC MSG is %x\n",offset);
-
-	if (addr == 0)
-		return -EINVAL;
-
-	/* Send the control message */
-	result = pci_write_config_dword(pdev,
-	                          LNC_MCR_OFFSET,
-	                          message);
-
-	printk(KERN_WARNING "rar- result from send ctl register is %x\n"
-	  ,result);
-
-	if (!result)
-		result = pci_read_config_dword(pdev,
-		                              LNC_MDR_OFFSET,
-				              addr);
-
-	printk(KERN_WARNING "rar- result from read data register is %x\n",
-	  result);
-
-	printk(KERN_WARNING "rar- value read from data register is %x\n",
-	  *addr);
-
-	if (result)
-		return -1;
-	else
-		return 0;
-}
-
-static int memrar_set_rar_addr(struct pci_dev* pdev,
-	                      int offset,
-	                      u32 addr)
-{
-	/*
-	 * ======== The Lincroft Message Bus Interface ========
-	 * Lincroft registers may be obtained from the PCI
-	 * (the Host Bridge) using the Lincroft Message Bus
-	 * Interface.  That message bus interface is generally
-	 * comprised of two registers: a control register (MCR, 0xDO)
-	 * and a data register (MDR, 0xD4).
-	 *
-	 * The MCR (message control register) format is the following:
-	 *   1.  [31:24]: Opcode
-	 *   2.  [23:16]: Port
-	 *   3.  [15:8]: Register Offset
-	 *   4.  [7:4]: Byte Enables (use 0xF to set all of these bits
-	 *              to 1)
-	 *   5.  [3:0]: reserved
-	 *
-	 *  Read (0xD0) and write (0xE0) opcodes are written to the
-	 *  control register when reading and writing to Lincroft
-	 *  registers, respectively.
-	 *
-	 *  We're interested in registers found in the Lincroft
-	 *  B-unit.  The B-unit port is 0x3.
-	 *
-	 *  The six B-unit RAR register offsets we use are listed
-	 *  earlier in this file.
-	 *
-	 *  Lastly writing to the MCR register requires the "Byte
-	 *  enables" bits to be set to 1.  This may be achieved by
-	 *  writing 0xF at bit 4.
-	 *
-	 * The MDR (message data register) format is the following:
-	 *   1. [31:0]: Read/Write Data
-	 *
-	 *  Data being read from this register is only available after
-	 *  writing the appropriate control message to the MCR
-	 *  register.
-	 *
-	 *  Data being written to this register must be written before
-	 *  writing the appropriate control message to the MCR
-	 *  register.
-	 */
-
-	int result = 0; /* result */
-
-	/* Construct control message */
-	u32 const message =
-	       (LNC_MESSAGE_WRITE_OPCODE << 24)
-	       | (LNC_BUNIT_PORT << 16)
-	       | (offset << 8)
-	       | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
-
-	printk(KERN_WARNING "rar- offset to LNC MSG is %x\n",offset);
-
-	if (addr == 0)
-		return -EINVAL;
-
-	/* Send the control message */
-	result = pci_write_config_dword(pdev,
-	                          LNC_MDR_OFFSET,
-	                          addr);
-
-	printk(KERN_WARNING "rar- result from send ctl register is %x\n"
-	  ,result);
-
-	if (!result)
-		result = pci_write_config_dword(pdev,
-		                              LNC_MCR_OFFSET,
-				              message);
-
-	printk(KERN_WARNING "rar- result from write data register is %x\n",
-	  result);
-
-	printk(KERN_WARNING "rar- value read to data register is %x\n",
-	  addr);
-
-	if (result)
-		return -1;
-	else
-		return 0;
-}
-
-/*
-
- * Initialize RAR parameters, such as physical addresses, etc.
-
- */
-static int memrar_init_rar_params(struct pci_dev *pdev)
-{
-	struct RAR_offsets const offsets[] = {
-	       { LNC_BRAR0L, LNC_BRAR0H },
-	       { LNC_BRAR1L, LNC_BRAR1H },
-	       { LNC_BRAR2L, LNC_BRAR2H }
-	};
-
-	size_t const num_offsets = sizeof(offsets) / sizeof(offsets[0]);
-	struct RAR_offsets const *end = offsets + num_offsets;
-	struct RAR_offsets const *i;
-	unsigned int n = 0;
-	int result = 0;
-
-	/* Retrieve RAR start and end physical addresses. */
-
-	/*
-	 * Access the RAR registers through the Lincroft Message Bus
-	 * Interface on PCI device: 00:00.0 Host bridge.
-	 */
-
-	/* struct pci_dev *pdev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); */
-
-	if (pdev == NULL)
-	       return -ENODEV;
-
-	for (i = offsets; i != end; ++i, ++n) {
-	       if (memrar_get_rar_addr (pdev,
-		                       (*i).low,
-		                       &(rar_addr[n].low)) != 0
-		   || memrar_get_rar_addr (pdev,
-		                          (*i).high,
-		                          &(rar_addr[n].high)) != 0) {
-		       result = -1;
-		       break;
-	       }
-	}
-
-	/* Done accessing the device. */
-	/* pci_dev_put(pdev); */
-
-	if (result == 0) {
-	if(1) {
-	       size_t z;
-	       for (z = 0; z != MRST_NUM_RAR; ++z) {
-			printk(KERN_WARNING "rar - BRAR[%Zd] physical address low\n"
-			     "\tlow:  0x%08x\n"
-			     "\thigh: 0x%08x\n",
-			     z,
-			     rar_addr[z].low,
-			     rar_addr[z].high);
-			}
-	       }
-	}
-
-	return result;
-}
-
-/*
-  function that is activated on the successfull probe of the RAR device
-*/
-static int __devinit rar_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	/* error */
-	int error;
-
-	/*------------------------
-	CODE
-	---------------------------*/
-
-	DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
-	  "Rar pci probe starting\n");
-	error = 0;
-
-	/* enable the device */
-	error = pci_enable_device(pdev);
-	if (error) {
-		DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
-		  "error enabling pci device\n");
-		goto end_function;
-	}
-
-	rar_dev = pdev;
-	registered = 1;
-
-	/* Initialize the RAR parameters, which have to be retrieved */
-	/* via the message bus service */
-	error=memrar_init_rar_params(rar_dev);
-
-	if (error) {
-		DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
-		  "error getting RAR addresses device\n");
-		registered = 0;
-		goto end_function;
-		}
-
-end_function:
-
-	return error;
-}
-
-/*
-  this function registers th driver to
-  the device subsystem( either PCI, USB, etc)
-*/
-static int __init rar_init_handler(void)
-{
-	return pci_register_driver(&rar_pci_driver);
-}
-
-static void __exit rar_exit_handler(void)
-{
-	pci_unregister_driver(&rar_pci_driver);
-}
-
-module_init(rar_init_handler);
-module_exit(rar_exit_handler);
-
-MODULE_LICENSE("GPL");
-
-
-/* The get_rar_address function is used by other device drivers
- * to obtain RAR address information on a RAR. It takes two
- * parameter:
- *
- * int rar_index
- * The rar_index is an index to the rar for which you wish to retrieve
- * the address information.
- * Values can be 0,1, or 2.
- *
- * struct RAR_address_struct is a pointer to a place to which the function
- * can return the address structure for the RAR.
- *
- * The function returns a 0 upon success or a -1 if there is no RAR
- * facility on this system.
- */
-int get_rar_address(int rar_index,struct RAR_address_struct *addresses)
-{
-	if (registered && (rar_index < 3) && (rar_index >= 0)) {
-		*addresses=rar_addr[rar_index];
-		/* strip off lock bit information  */
-		addresses->low = addresses->low & 0xfffffff0;
-		addresses->high = addresses->high & 0xfffffff0;
-		return 0;
-		}
-
-	else {
-		return -ENODEV;
-		}
-}
-
-
-EXPORT_SYMBOL(get_rar_address);
-
-/* The lock_rar function is ued by other device drivers to lock an RAR.
- * once an RAR is locked, it stays locked until the next system reboot.
- * The function takes one parameter:
- *
- * int rar_index
- * The rar_index is an index to the rar that you want to lock.
- * Values can be 0,1, or 2.
- *
- * The function returns a 0 upon success or a -1 if there is no RAR
- * facility on this system.
- */
-int lock_rar(int rar_index)
-{
-	u32 working_addr;
-	int result;
-if (registered && (rar_index < 3) && (rar_index >= 0)) {
-	/* first make sure that lock bits are clear (this does lock) */
-	working_addr=rar_addr[rar_index].low & 0xfffffff0;
-
-	/* now send that value to the register using the IPC */
-        result=memrar_set_rar_addr(rar_dev,rar_index,working_addr);
-	return result;
-	}
-
-else {
-	return -ENODEV;
-	}
-}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rar/rar_driver.h linux-libre-2.6.34-gnu1/drivers/staging/rar/rar_driver.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rar/rar_driver.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rar/rar_driver.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,99 +0,0 @@
-/* === RAR Physical Addresses === */
-struct RAR_address_struct {
-        u32 low;
-        u32 high;
-};
-
-/* The get_rar_address function is used by other device drivers
- * to obtain RAR address information on a RAR. It takes two
- * parameter:
- *
- * int rar_index
- * The rar_index is an index to the rar for which you wish to retrieve
- * the address information.
- * Values can be 0,1, or 2.
- *
- * struct RAR_address_struct is a pointer to a place to which the function
- * can return the address structure for the RAR.
- *
- * The function returns a 0 upon success or a -1 if there is no RAR
- * facility on this system.
- */
-int get_rar_address(int rar_index,struct RAR_address_struct *addresses);
-
-
-/* The lock_rar function is ued by other device drivers to lock an RAR.
- * once an RAR is locked, it stays locked until the next system reboot.
- * The function takes one parameter:
- *
- * int rar_index
- * The rar_index is an index to the rar that you want to lock.
- * Values can be 0,1, or 2.
- *
- * The function returns a 0 upon success or a -1 if there is no RAR
- * facility on this system.
- */
-int lock_rar(int rar_index);
-
-
-/* DEBUG LEVEL MASKS */
-#define RAR_DEBUG_LEVEL_BASIC       0x1
-
-#define RAR_DEBUG_LEVEL_REGISTERS   0x2
-
-#define RAR_DEBUG_LEVEL_EXTENDED    0x4
-
-#define DEBUG_LEVEL	0x7
-
-/* FUNCTIONAL MACROS */
-
-/* debug macro without paramaters */
-#define DEBUG_PRINT_0(DEBUG_LEVEL , info) \
-do \
-{ \
-  if(DEBUG_LEVEL) \
-  { \
-    printk(KERN_WARNING info); \
-  } \
-}while(0)
-
-/* debug macro with 1 paramater */
-#define DEBUG_PRINT_1(DEBUG_LEVEL , info , param1) \
-do \
-{ \
-  if(DEBUG_LEVEL) \
-  { \
-    printk(KERN_WARNING info , param1); \
-  } \
-}while(0)
-
-/* debug macro with 2 paramaters */
-#define DEBUG_PRINT_2(DEBUG_LEVEL , info , param1, param2) \
-do \
-{ \
-  if(DEBUG_LEVEL) \
-  { \
-    printk(KERN_WARNING info , param1, param2); \
-  } \
-}while(0)
-
-/* debug macro with 3 paramaters */
-#define DEBUG_PRINT_3(DEBUG_LEVEL , info , param1, param2 , param3) \
-do \
-{ \
-  if(DEBUG_LEVEL) \
-  { \
-    printk(KERN_WARNING info , param1, param2 , param3); \
-  } \
-}while(0)
-
-/* debug macro with 4 paramaters */
-#define DEBUG_PRINT_4(DEBUG_LEVEL , info , param1, param2 , param3 , param4) \
-do \
-{ \
-  if(DEBUG_LEVEL) \
-  { \
-    printk(KERN_WARNING info , param1, param2 , param3 , param4); \
-  } \
-}while(0)
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rar_register/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/rar_register/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/rar_register/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rar_register/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,30 @@
+#
+# RAR device configuration
+#
+
+menu "RAR Register Driver"
+#
+#	Restricted Access Register Manager
+#
+config RAR_REGISTER
+	tristate "Restricted Access Region Register Driver"
+	default n
+	---help---
+		This driver allows other kernel drivers access to the
+		contents of the restricted access region control
+		registers.
+
+		The restricted access region control registers
+		(rar_registers) are used to pass address and
+		locking information on restricted access regions
+		to other drivers that use restricted access regions
+
+		The restricted access regions are regions of memory
+		on the Intel MID Platform that are not accessible to
+		the x86 processor, but are accessible to dedicated
+		processors on board peripheral devices.
+
+		The purpose of the restricted access regions is to
+		protect sensitive data from compromise by unauthorized
+		programs running on the x86 processor.
+endmenu
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rar_register/Makefile linux-libre-2.6.34-gnu1/drivers/staging/rar_register/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/rar_register/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rar_register/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,2 @@
+EXTRA_CFLAGS += -DLITTLE__ENDIAN
+obj-$(CONFIG_RAR_REGISTER) += rar_register.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rar_register/rar_register.c linux-libre-2.6.34-gnu1/drivers/staging/rar_register/rar_register.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rar_register/rar_register.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rar_register/rar_register.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,615 @@
+/*
+ *  rar_register.c - An Intel Restricted Access Region register driver
+ *
+ *  Copyright(c) 2009 Intel Corporation. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License as
+ *  published by the Free Software Foundation; either version 2 of the
+ *  License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You 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.
+ *
+ * -------------------------------------------------------------------
+ *  20091204 Mark Allyn <mark.a.allyn@intel.com>
+ *	     Ossama Othman <ossama.othman@intel.com>
+ *	Cleanup per feedback from Alan Cox and Arjan Van De Ven
+ *
+ *  20090806 Ossama Othman <ossama.othman@intel.com>
+ *      Return zero high address if upper 22 bits is zero.
+ *      Cleaned up checkpatch errors.
+ *      Clarified that driver is dealing with bus addresses.
+ *
+ *  20090702 Ossama Othman <ossama.othman@intel.com>
+ *      Removed unnecessary include directives
+ *      Cleaned up spinlocks.
+ *      Cleaned up logging.
+ *      Improved invalid parameter checks.
+ *      Fixed and simplified RAR address retrieval and RAR locking
+ *      code.
+ *
+ *  20090626 Mark Allyn <mark.a.allyn@intel.com>
+ *      Initial publish
+ */
+
+#define DEBUG 1
+
+#include "rar_register.h"
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+
+/* === Lincroft Message Bus Interface === */
+/* Message Control Register */
+#define LNC_MCR_OFFSET 0xD0
+
+/* Maximum number of clients (other drivers using this driver) */
+#define MAX_RAR_CLIENTS 10
+
+/* Message Data Register */
+#define LNC_MDR_OFFSET 0xD4
+
+/* Message Opcodes */
+#define LNC_MESSAGE_READ_OPCODE 0xD0
+#define LNC_MESSAGE_WRITE_OPCODE 0xE0
+
+/* Message Write Byte Enables */
+#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF
+
+/* B-unit Port */
+#define LNC_BUNIT_PORT 0x3
+
+/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */
+#define LNC_BRAR0L 0x10
+#define LNC_BRAR0H 0x11
+#define LNC_BRAR1L 0x12
+#define LNC_BRAR1H 0x13
+
+/* Reserved for SeP */
+#define LNC_BRAR2L 0x14
+#define LNC_BRAR2H 0x15
+
+/* Moorestown supports three restricted access regions. */
+#define MRST_NUM_RAR 3
+
+
+/* RAR Bus Address Range */
+struct RAR_address_range {
+	dma_addr_t low;
+	dma_addr_t high;
+};
+
+/* Structure containing low and high RAR register offsets. */
+struct RAR_offsets {
+	u32 low;  /* Register offset for low  RAR bus address. */
+	u32 high; /* Register offset for high RAR bus address. */
+};
+
+struct client {
+	int (*client_callback)(void *client_data);
+	void *customer_data;
+	int client_called;
+	};
+
+static DEFINE_MUTEX(rar_mutex);
+static DEFINE_MUTEX(lnc_reg_mutex);
+
+struct RAR_device {
+	struct RAR_offsets const rar_offsets[MRST_NUM_RAR];
+	struct RAR_address_range rar_addr[MRST_NUM_RAR];
+	struct pci_dev *rar_dev;
+	bool registered;
+	};
+
+/* this platform has only one rar_device for 3 rar regions */
+static struct RAR_device my_rar_device = {
+	.rar_offsets = {
+		[0].low = LNC_BRAR0L,
+		[0].high = LNC_BRAR0H,
+		[1].low = LNC_BRAR1L,
+		[1].high = LNC_BRAR1H,
+		[2].low = LNC_BRAR2L,
+		[2].high = LNC_BRAR2H
+	}
+};
+
+/* this data is for handling requests from other drivers which arrive
+ * prior to this driver initializing
+ */
+
+static struct client clients[MAX_RAR_CLIENTS];
+static int num_clients;
+
+/*
+ * This function is used to retrieved RAR info using the Lincroft
+ * message bus interface.
+ */
+static int retrieve_rar_addr(struct pci_dev *pdev,
+	int offset,
+	dma_addr_t *addr)
+{
+	/*
+	 * ======== The Lincroft Message Bus Interface ========
+	 * Lincroft registers may be obtained from the PCI
+	 * (the Host Bridge) using the Lincroft Message Bus
+	 * Interface.  That message bus interface is generally
+	 * comprised of two registers: a control register (MCR, 0xDO)
+	 * and a data register (MDR, 0xD4).
+	 *
+	 * The MCR (message control register) format is the following:
+	 *   1.  [31:24]: Opcode
+	 *   2.  [23:16]: Port
+	 *   3.  [15:8]: Register Offset
+	 *   4.  [7:4]: Byte Enables (use 0xF to set all of these bits
+	 *              to 1)
+	 *   5.  [3:0]: reserved
+	 *
+	 *  Read (0xD0) and write (0xE0) opcodes are written to the
+	 *  control register when reading and writing to Lincroft
+	 *  registers, respectively.
+	 *
+	 *  We're interested in registers found in the Lincroft
+	 *  B-unit.  The B-unit port is 0x3.
+	 *
+	 *  The six B-unit RAR register offsets we use are listed
+	 *  earlier in this file.
+	 *
+	 *  Lastly writing to the MCR register requires the "Byte
+	 *  enables" bits to be set to 1.  This may be achieved by
+	 *  writing 0xF at bit 4.
+	 *
+	 * The MDR (message data register) format is the following:
+	 *   1. [31:0]: Read/Write Data
+	 *
+	 *  Data being read from this register is only available after
+	 *  writing the appropriate control message to the MCR
+	 *  register.
+	 *
+	 *  Data being written to this register must be written before
+	 *  writing the appropriate control message to the MCR
+	 *  register.
+	*/
+
+	int result;
+
+	/* Construct control message */
+	u32 const message =
+		 (LNC_MESSAGE_READ_OPCODE << 24)
+		 | (LNC_BUNIT_PORT << 16)
+		 | (offset << 8)
+		 | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
+
+	dev_dbg(&pdev->dev, "Offset for 'get' LNC MSG is %x\n", offset);
+
+	if (addr == 0) {
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	/*
+	* We synchronize access to the Lincroft MCR and MDR registers
+	* until BOTH the command is issued through the MCR register
+	* and the corresponding data is read from the MDR register.
+	* Otherwise a race condition would exist between accesses to
+	* both registers.
+	*/
+
+	mutex_lock(&lnc_reg_mutex);
+
+	/* Send the control message */
+	result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message);
+
+	dev_dbg(&pdev->dev, "Result from send ctl register is %x\n", result);
+
+	if (!result) {
+		result = pci_read_config_dword(pdev, LNC_MDR_OFFSET,
+			(u32 *)addr);
+		dev_dbg(&pdev->dev,
+			"Result from read data register is %x\n", result);
+
+		dev_dbg(&pdev->dev,
+			"Value read from data register is %lx\n",
+			 (unsigned long)*addr);
+	}
+
+	mutex_unlock(&lnc_reg_mutex);
+
+	return result;
+}
+
+static int set_rar_address(struct pci_dev *pdev,
+	int offset,
+	dma_addr_t addr)
+{
+	/*
+	* Data being written to this register must be written before
+	* writing the appropriate control message to the MCR
+	* register.
+	* @note See rar_get_address() for a description of the
+	* message bus interface being used here.
+	*/
+
+	int result = 0;
+
+	/* Construct control message */
+	u32 const message = (LNC_MESSAGE_WRITE_OPCODE << 24)
+		| (LNC_BUNIT_PORT << 16)
+		| (offset << 8)
+		| (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
+
+	if (addr == 0) {
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	dev_dbg(&pdev->dev, "Offset for 'set' LNC MSG is %x\n", offset);
+
+	/*
+	* We synchronize access to the Lincroft MCR and MDR registers
+	* until BOTH the command is issued through the MCR register
+	* and the corresponding data is read from the MDR register.
+	* Otherwise a race condition would exist between accesses to
+	* both registers.
+	*/
+
+	mutex_lock(&lnc_reg_mutex);
+
+	/* Send the control message */
+	result = pci_write_config_dword(pdev, LNC_MDR_OFFSET, addr);
+
+	dev_dbg(&pdev->dev, "Result from write data register is %x\n", result);
+
+	if (!result) {
+		dev_dbg(&pdev->dev,
+			"Value written to data register is %lx\n",
+			 (unsigned long)addr);
+
+		result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message);
+
+		dev_dbg(&pdev->dev, "Result from send ctl register is %x\n",
+			result);
+	}
+
+	mutex_unlock(&lnc_reg_mutex);
+
+	return result;
+}
+
+/*
+* Initialize RAR parameters, such as bus addresses, etc.
+*/
+static int init_rar_params(struct pci_dev *pdev)
+{
+	unsigned int i;
+	int result = 0;
+
+	/* Retrieve RAR start and end bus addresses.
+	* Access the RAR registers through the Lincroft Message Bus
+	* Interface on PCI device: 00:00.0 Host bridge.
+	*/
+
+	for (i = 0; i < MRST_NUM_RAR; ++i) {
+		struct RAR_offsets const *offset =
+			&my_rar_device.rar_offsets[i];
+		struct RAR_address_range *addr = &my_rar_device.rar_addr[i];
+
+	if ((retrieve_rar_addr(pdev, offset->low, &addr->low) != 0)
+		|| (retrieve_rar_addr(pdev, offset->high, &addr->high) != 0)) {
+		result = -1;
+		break;
+		}
+
+		/*
+		* Only the upper 22 bits of the RAR addresses are
+		* stored in their corresponding RAR registers so we
+		* must set the lower 10 bits accordingly.
+
+		* The low address has its lower 10 bits cleared, and
+		* the high address has all its lower 10 bits set,
+		* e.g.:
+		* low = 0x2ffffc00
+		*/
+
+		addr->low &= (dma_addr_t)0xfffffc00u;
+
+		/*
+		* Set bits 9:0 on uppser address if bits 31:10 are non
+		* zero; otherwize clear all bits
+		*/
+
+		if ((addr->high & 0xfffffc00u) == 0)
+			addr->high = 0;
+		else
+			addr->high |= 0x3ffu;
+	}
+	/* Done accessing the device. */
+
+	if (result == 0) {
+		int z;
+		for (z = 0; z != MRST_NUM_RAR; ++z) {
+			/*
+			* "BRAR" refers to the RAR registers in the
+			* Lincroft B-unit.
+			*/
+			dev_info(&pdev->dev, "BRAR[%u] bus address range = "
+			  "[%lx, %lx]\n", z,
+			  (unsigned long)my_rar_device.rar_addr[z].low,
+			  (unsigned long)my_rar_device.rar_addr[z].high);
+		}
+	}
+
+	return result;
+}
+
+/*
+ * The rar_get_address function is used by other device drivers
+ * to obtain RAR address information on a RAR. It takes three
+ * parameters:
+ *
+ * int rar_index
+ * The rar_index is an index to the rar for which you wish to retrieve
+ * the address information.
+ * Values can be 0,1, or 2.
+ *
+ * The function returns a 0 upon success or a -1 if there is no RAR
+ * facility on this system.
+ */
+int rar_get_address(int rar_index,
+	dma_addr_t *start_address,
+	dma_addr_t *end_address)
+{
+	int result = -ENODEV;
+
+	if (my_rar_device.registered) {
+		if (start_address == 0 || end_address == 0
+			|| rar_index >= MRST_NUM_RAR || rar_index < 0) {
+			result = -EINVAL;
+		} else {
+			*start_address =
+				my_rar_device.rar_addr[rar_index].low;
+			*end_address =
+				my_rar_device.rar_addr[rar_index].high;
+
+			result = 0;
+		}
+	}
+
+	return result;
+}
+EXPORT_SYMBOL(rar_get_address);
+
+/*
+ * The rar_lock function is ued by other device drivers to lock an RAR.
+ * once an RAR is locked, it stays locked until the next system reboot.
+ * The function takes one parameter:
+ *
+ * int rar_index
+ * The rar_index is an index to the rar that you want to lock.
+ * Values can be 0,1, or 2.
+ *
+ * The function returns a 0 upon success or a -1 if there is no RAR
+ * facility on this system.
+ */
+int rar_lock(int rar_index)
+{
+	int result = -ENODEV;
+
+	if (rar_index >= MRST_NUM_RAR || rar_index < 0) {
+		result = -EINVAL;
+		return result;
+	}
+
+	dev_dbg(&my_rar_device.rar_dev->dev, "rar_lock mutex locking\n");
+	mutex_lock(&rar_mutex);
+
+	if (my_rar_device.registered) {
+
+		dma_addr_t low = my_rar_device.rar_addr[rar_index].low &
+			0xfffffc00u;
+
+		dma_addr_t high = my_rar_device.rar_addr[rar_index].high &
+			0xfffffc00u;
+
+		/*
+		* Only allow I/O from the graphics and Langwell;
+		* Not from the x96 processor
+		*/
+		if (rar_index == (int)RAR_TYPE_VIDEO) {
+			low |= 0x00000009;
+			high |= 0x00000015;
+		}
+
+		else if (rar_index == (int)RAR_TYPE_AUDIO) {
+			/* Only allow I/O from Langwell; nothing from x86 */
+			low |= 0x00000008;
+			high |= 0x00000018;
+		}
+
+		else
+			/* Read-only from all agents */
+			high |= 0x00000018;
+
+		/*
+		* Now program the register using the Lincroft message
+		* bus interface.
+		*/
+		result = set_rar_address(my_rar_device.rar_dev,
+			my_rar_device.rar_offsets[rar_index].low,
+			low);
+
+		if (result == 0)
+			result = set_rar_address(
+			my_rar_device.rar_dev,
+			my_rar_device.rar_offsets[rar_index].high,
+			high);
+	}
+
+	dev_dbg(&my_rar_device.rar_dev->dev, "rar_lock mutex unlocking\n");
+	mutex_unlock(&rar_mutex);
+	return result;
+}
+EXPORT_SYMBOL(rar_lock);
+
+/* The register_rar function is to used by other device drivers
+ * to ensure that this driver is ready. As we cannot be sure of
+ * the compile/execute order of dirvers in ther kernel, it is
+ * best to give this driver a callback function to call when
+ * it is ready to give out addresses. The callback function
+ * would have those steps that continue the initialization of
+ * a driver that do require a valid RAR address. One of those
+ * steps would be to call rar_get_address()
+ * This function return 0 on success an -1 on failure.
+*/
+int register_rar(int (*callback)(void *yourparameter), void *yourparameter)
+{
+
+	int result = -ENODEV;
+
+	if (callback == NULL)
+		return -EINVAL;
+
+	mutex_lock(&rar_mutex);
+
+	if (my_rar_device.registered) {
+
+		mutex_unlock(&rar_mutex);
+		/*
+		* if the driver already registered, then we can simply
+		* call the callback right now
+		*/
+
+		return (*callback)(yourparameter);
+	}
+
+	if (num_clients < MRST_NUM_RAR) {
+
+		clients[num_clients].client_callback = callback;
+		clients[num_clients].customer_data = yourparameter;
+		num_clients += 1;
+		result = 0;
+	}
+
+	mutex_unlock(&rar_mutex);
+	return result;
+
+}
+EXPORT_SYMBOL(register_rar);
+
+/* Suspend - returns -ENOSYS */
+static int rar_suspend(struct pci_dev *dev, pm_message_t state)
+{
+	return -ENOSYS;
+}
+
+static int rar_resume(struct pci_dev *dev)
+{
+	return -ENOSYS;
+}
+
+/*
+ * This function registers the driver with the device subsystem (
+ * either PCI, USB, etc).
+ * Function that is activaed on the succesful probe of the RAR device
+ * (Moorestown host controller).
+ */
+static int rar_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	int error;
+	int counter;
+
+	dev_dbg(&dev->dev, "PCI probe starting\n");
+
+	/* enable the device */
+	error = pci_enable_device(dev);
+	if (error) {
+		dev_err(&dev->dev,
+			"Error enabling RAR register PCI device\n");
+		goto end_function;
+	}
+
+	/* we have only one device; fill in the rar_device structure */
+	my_rar_device.rar_dev = dev;
+
+	/*
+	* Initialize the RAR parameters, which have to be retrieved
+	* via the message bus interface.
+	*/
+	error = init_rar_params(dev);
+	if (error) {
+		pci_disable_device(dev);
+
+		dev_err(&dev->dev,
+			"Error retrieving RAR addresses\n");
+
+		goto end_function;
+	}
+
+	dev_dbg(&dev->dev, "PCI probe locking\n");
+	mutex_lock(&rar_mutex);
+	my_rar_device.registered = 1;
+
+	/* now call anyone who has registered (using callbacks) */
+	for (counter = 0; counter < num_clients; counter += 1) {
+		if (clients[counter].client_callback) {
+			error = (*clients[counter].client_callback)(
+				clients[counter].customer_data);
+			/* set callback to NULL to indicate it has been done */
+			clients[counter].client_callback = NULL;
+				dev_dbg(&my_rar_device.rar_dev->dev,
+				"Callback called for %d\n",
+			counter);
+		}
+	}
+
+	dev_dbg(&dev->dev, "PCI probe unlocking\n");
+	mutex_unlock(&rar_mutex);
+
+end_function:
+
+	return error;
+}
+
+const struct pci_device_id rar_pci_id_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_RAR_DEVICE_ID) },
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl);
+
+const struct pci_device_id *my_id_table = rar_pci_id_tbl;
+
+/* field for registering driver to PCI device */
+static struct pci_driver rar_pci_driver = {
+	.name = "rar_register_driver",
+	.id_table = rar_pci_id_tbl,
+	.probe = rar_probe,
+	.suspend = rar_suspend,
+	.resume = rar_resume
+};
+
+static int __init rar_init_handler(void)
+{
+	return pci_register_driver(&rar_pci_driver);
+}
+
+static void __exit rar_exit_handler(void)
+{
+	pci_unregister_driver(&rar_pci_driver);
+}
+
+module_init(rar_init_handler);
+module_exit(rar_exit_handler);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Intel Restricted Access Region Register Driver");
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rar_register/rar_register.h linux-libre-2.6.34-gnu1/drivers/staging/rar_register/rar_register.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rar_register/rar_register.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rar_register/rar_register.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General
+ * Public License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA  02111-1307, USA.
+ * The full GNU General Public License is included in this
+ * distribution in the file called COPYING.
+ */
+
+
+#ifndef _RAR_REGISTER_H
+#define _RAR_REGISTER_H
+
+# include <linux/types.h>
+
+/* following are used both in drivers as well as user space apps */
+enum RAR_type {
+	RAR_TYPE_VIDEO = 0,
+	RAR_TYPE_AUDIO,
+	RAR_TYPE_IMAGE,
+	RAR_TYPE_DATA
+};
+
+#ifdef __KERNEL__
+
+/* PCI device id for controller */
+#define PCI_RAR_DEVICE_ID 0x4110
+
+/* The register_rar function is to used by other device drivers
+ * to ensure that this driver is ready. As we cannot be sure of
+ * the compile/execute order of dirvers in ther kernel, it is
+ * best to give this driver a callback function to call when
+ * it is ready to give out addresses. The callback function
+ * would have those steps that continue the initialization of
+ * a driver that do require a valid RAR address. One of those
+ * steps would be to call get_rar_address()
+ * This function return 0 on success an -1 on failure.
+ */
+int register_rar(int (*callback)(void *yourparameter), void *yourparameter);
+
+/* The get_rar_address function is used by other device drivers
+ * to obtain RAR address information on a RAR. It takes two
+ * parameter:
+ *
+ * int rar_index
+ * The rar_index is an index to the rar for which you wish to retrieve
+ * the address information.
+ * Values can be 0,1, or 2.
+ *
+ * struct RAR_address_struct is a pointer to a place to which the function
+ * can return the address structure for the RAR.
+ *
+ * The function returns a 0 upon success or a -1 if there is no RAR
+ * facility on this system.
+ */
+int rar_get_address(int rar_index,
+		dma_addr_t *start_address,
+		dma_addr_t *end_address);
+
+/* The lock_rar function is ued by other device drivers to lock an RAR.
+ * once an RAR is locked, it stays locked until the next system reboot.
+ * The function takes one parameter:
+ *
+ * int rar_index
+ * The rar_index is an index to the rar that you want to lock.
+ * Values can be 0,1, or 2.
+ *
+ * The function returns a 0 upon success or a -1 if there is no RAR
+ * facility on this system.
+ */
+int rar_lock(int rar_index);
+
+#endif  /* __KERNEL__ */
+#endif  /* _RAR_REGISTER_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rt2860/common/rtmp_mcu.c linux-libre-2.6.34-gnu1/drivers/staging/rt2860/common/rtmp_mcu.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rt2860/common/rtmp_mcu.c	2013-05-03 12:11:21.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/rt2860/common/rtmp_mcu.c	2013-05-03 09:50:52.000000000 -0400
@@ -37,33 +37,38 @@
 
 #include	"../rt_config.h"
 
-#if defined(RT2860) || defined(RT3090)
+#include <linux/crc-ccitt.h>
+#include <linux/firmware.h>
+
+#ifdef RTMP_MAC_USB
+
+#define FIRMWAREIMAGE_LENGTH		0x1000
+
+#define FIRMWARE_2870_MIN_VERSION	12
+#define FIRMWARE_2870_FILENAME		"/*(DEBLOBBED)*/"
 /*(DEBLOBBED)*/
-#endif
-#ifdef RT2870
+
+#define FIRMWARE_3070_MIN_VERSION	17
+#define FIRMWARE_3070_FILENAME		"/*(DEBLOBBED)*/"
 /*(DEBLOBBED)*/
-#endif
 
-#include <linux/bitrev.h>
+#define FIRMWARE_3071_MIN_VERSION	17
+#define FIRMWARE_3071_FILENAME		"/*(DEBLOBBED)*/"	/* for RT3071/RT3072 */
+/*(DEBLOBBED)*/
 
-#ifdef RTMP_MAC_USB
-/* */
-/* RT2870 Firmware Spec only used 1 oct for version expression */
-/* */
-#define FIRMWARE_MINOR_VERSION	7
-#endif /* RTMP_MAC_USB // */
+#else /* RTMP_MAC_PCI */
 
-/* New 8k byte firmware size for RT3071/RT3072 */
-#define FIRMWAREIMAGE_MAX_LENGTH	0x2000
-#define FIRMWAREIMAGE_LENGTH			(sizeof (FirmwareImage) / sizeof(u8))
-#define FIRMWARE_MAJOR_VERSION		0
+#define FIRMWAREIMAGE_LENGTH		0x2000
 
-#define FIRMWAREIMAGEV1_LENGTH		0x1000
-#define FIRMWAREIMAGEV2_LENGTH		0x1000
+#define FIRMWARE_2860_MIN_VERSION	11
+#define FIRMWARE_2860_FILENAME		"/*(DEBLOBBED)*/"
+/*(DEBLOBBED)*/
 
-#ifdef RTMP_MAC_PCI
-#define FIRMWARE_MINOR_VERSION		2
-#endif /* RTMP_MAC_PCI // */
+#define FIRMWARE_3090_MIN_VERSION	19
+#define FIRMWARE_3090_FILENAME		"/*(DEBLOBBED)*/"	/* for RT3090/RT3390 */
+/*(DEBLOBBED)*/
+
+#endif
 
 /*
 	========================================================================
@@ -88,6 +93,78 @@ int RtmpAsicEraseFirmware(struct rt_rtmp
 	return 0;
 }
 
+static const struct firmware *rtmp_get_firmware(struct rt_rtmp_adapter *adapter)
+{
+	const char *name;
+	const struct firmware *fw = NULL;
+	u8 min_version;
+	struct device *dev;
+	int err;
+
+	if (adapter->firmware)
+		return adapter->firmware;
+
+#ifdef RTMP_MAC_USB
+	if (IS_RT3071(adapter)) {
+		name = FIRMWARE_3071_FILENAME;
+		min_version = FIRMWARE_3071_MIN_VERSION;
+	} else if (IS_RT3070(adapter)) {
+		name = FIRMWARE_3070_FILENAME;
+		min_version = FIRMWARE_3070_MIN_VERSION;
+	} else {
+		name = FIRMWARE_2870_FILENAME;
+		min_version = FIRMWARE_2870_MIN_VERSION;
+	}
+	dev = &((struct os_cookie *)adapter->OS_Cookie)->pUsb_Dev->dev;
+#else /* RTMP_MAC_PCI */
+	if (IS_RT3090(adapter) || IS_RT3390(adapter)) {
+		name = FIRMWARE_3090_FILENAME;
+		min_version = FIRMWARE_3090_MIN_VERSION;
+	} else {
+		name = FIRMWARE_2860_FILENAME;
+		min_version = FIRMWARE_2860_MIN_VERSION;
+	}
+	dev = &((struct os_cookie *)adapter->OS_Cookie)->pci_dev->dev;
+#endif
+
+	err = reject_firmware(&fw, name, dev);
+	if (err) {
+		dev_err(dev, "firmware file %s request failed (%d)\n",
+			name, err);
+		return NULL;
+	}
+
+	if (fw->size < FIRMWAREIMAGE_LENGTH) {
+		dev_err(dev, "firmware file %s size is invalid\n", name);
+		goto invalid;
+	}
+
+	/* is it new enough? */
+	adapter->FirmwareVersion = fw->data[FIRMWAREIMAGE_LENGTH - 3];
+	if (adapter->FirmwareVersion < min_version) {
+		dev_err(dev,
+			"firmware file %s is too old;"
+			" driver requires v%d or later\n",
+			name, min_version);
+		goto invalid;
+	}
+
+	/* is the internal CRC correct? */
+	if (crc_ccitt(0xffff, fw->data, FIRMWAREIMAGE_LENGTH - 2) !=
+	    (fw->data[FIRMWAREIMAGE_LENGTH - 2] |
+	     (fw->data[FIRMWAREIMAGE_LENGTH - 1] << 8))) {
+		dev_err(dev, "firmware file %s failed internal CRC\n", name);
+		goto invalid;
+	}
+
+	adapter->firmware = fw;
+	return fw;
+
+invalid:
+	release_firmware(fw);
+	return NULL;
+}
+
 /*
 	========================================================================
 
@@ -107,50 +184,16 @@ int RtmpAsicEraseFirmware(struct rt_rtmp
 */
 int RtmpAsicLoadFirmware(struct rt_rtmp_adapter *pAd)
 {
-
+	const struct firmware *fw;
 	int Status = NDIS_STATUS_SUCCESS;
-	u8 *pFirmwareImage = NULL;
-	unsigned long FileLength, Index;
+	unsigned long Index;
 	u32 MacReg = 0;
-#ifdef RTMP_MAC_USB
-	u32 Version = (pAd->MACVersion >> 16);
-#endif
 
-	/* New 8k byte firmware size for RT3071/RT3072 */
-	{
-#ifdef RTMP_MAC_PCI
-		if (IS_RT3090(pAd) || IS_RT3390(pAd)) {
-			return printk("%s: missing Free firmware\n", __func__),
-				NDIS_STATUS_FAILURE;
-			/*(DEBLOBBED)*/
-		} else {
-			return printk("%s: missing Free firmware\n", __func__),
-				NDIS_STATUS_FAILURE;
-			/*(DEBLOBBED)*/
-		}
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-		/* the firmware image consists of two parts */
-		if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070)) {	/* use the second part */
-			/*printk("KH:Use New Version,part2\n"); */
-			return printk("%s: missing Free firmware\n", __func__),
-				NDIS_STATUS_FAILURE;
-			/*(DEBLOBBED)*/
-		} else {
-			/*printk("KH:Use New Version,part1\n"); */
-			if (Version == 0x3070)
-				return printk("%s: missing Free firmware\n", __func__),
-					NDIS_STATUS_FAILURE;
-				/*(DEBLOBBED)*/
-			else
-				return printk("%s: missing Free firmware\n", __func__),
-					NDIS_STATUS_FAILURE;
-				/*(DEBLOBBED)*/
-		}
-#endif /* RTMP_MAC_USB // */
-	}
+	fw = rtmp_get_firmware(pAd);
+	if (!fw)
+		return NDIS_STATUS_FAILURE;
 
-	RTMP_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
+	RTMP_WRITE_FIRMWARE(pAd, fw->data, FIRMWAREIMAGE_LENGTH);
 
 	/* check if MCU is ready */
 	Index = 0;
@@ -223,7 +266,7 @@ int RtmpAsicSendCommandToMcu(struct rt_r
 				 ("AsicSendCommanToMcu::Mail box is busy\n"));
 		} while (i++ < 100);
 
-		if (i >= 100) {
+		if (i > 100) {
 			DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
 			return FALSE;
 		}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rt2860/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/rt2860/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/rt2860/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rt2860/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,8 @@ config RT2860
 	depends on PCI && X86 && WLAN
 	select WIRELESS_EXT
 	select WEXT_PRIV
+	select CRC_CCITT
+	select FW_LOADER
 	---help---
 	  This is an experimental driver for the Ralink 2860 and 3090
 	  wireless chips.
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rt2860/pci_main_dev.c linux-libre-2.6.34-gnu1/drivers/staging/rt2860/pci_main_dev.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rt2860/pci_main_dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rt2860/pci_main_dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 
 #include "rt_config.h"
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 /* Following information will be show when you run 'modinfo' */
 /* *** If you have a solution for the bug in current version of driver, please mail to me. */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rt2860/rt_linux.c linux-libre-2.6.34-gnu1/drivers/staging/rt2860/rt_linux.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rt2860/rt_linux.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rt2860/rt_linux.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,9 @@
  *************************************************************************
  */
 
+#include <linux/firmware.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "rt_config.h"
 
 unsigned long RTDebugLevel = RT_DEBUG_ERROR;
@@ -260,6 +262,8 @@ void RTMPFreeAdapter(struct rt_rtmp_adap
 
 	NdisFreeSpinLock(&pAd->irq_lock);
 
+	release_firmware(pAd->firmware);
+
 	vfree(pAd);		/* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */
 	if (os_cookie)
 		kfree(os_cookie);
@@ -462,9 +466,9 @@ void *duplicate_pkt(struct rt_rtmp_adapt
 	if ((skb =
 	     __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL) {
 		skb_reserve(skb, 2);
-		NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
+		NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
 		skb_put(skb, HdrLen);
-		NdisMoveMemory(skb->tail, pData, DataSize);
+		NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
 		skb_put(skb, DataSize);
 		skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
 		pPacket = OSPKT_TO_RTPKT(skb);
@@ -515,7 +519,7 @@ void *ClonePacket(struct rt_rtmp_adapter
 		pClonedPkt->dev = pRxPkt->dev;
 		pClonedPkt->data = pData;
 		pClonedPkt->len = DataSize;
-		pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
+		skb_set_tail_pointer(pClonedPkt, DataSize)
 		ASSERT(DataSize < 1530);
 	}
 	return pClonedPkt;
@@ -535,7 +539,7 @@ void update_os_packet_info(struct rt_rtm
 	pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
 	pOSPkt->data = pRxBlk->pData;
 	pOSPkt->len = pRxBlk->DataSize;
-	pOSPkt->tail = pOSPkt->data + pOSPkt->len;
+	skb_set_tail_pointer(pOSPkt, pOSPkt->len);
 }
 
 void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd,
@@ -553,7 +557,7 @@ void wlan_802_11_to_802_3_packet(struct
 	pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
 	pOSPkt->data = pRxBlk->pData;
 	pOSPkt->len = pRxBlk->DataSize;
-	pOSPkt->tail = pOSPkt->data + pOSPkt->len;
+	skb_set_tail_pointer(pOSPkt, pOSPkt->len);
 
 	/* */
 	/* copy 802.3 header */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rt2860/rt_linux.h linux-libre-2.6.34-gnu1/drivers/staging/rt2860/rt_linux.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rt2860/rt_linux.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rt2860/rt_linux.h	2010-05-16 17:17:36.000000000 -0400
@@ -658,9 +658,9 @@ void linux_pci_unmap_single(void *handle
 		(RTPKT_TO_OSPKT(_pkt)->len) = (_len)
 
 #define GET_OS_PKT_DATATAIL(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt)->tail)
+		(skb_tail_pointer(RTPKT_TO_OSPKT(_pkt))
 #define SET_OS_PKT_DATATAIL(_pkt, _start, _len)	\
-		((RTPKT_TO_OSPKT(_pkt))->tail) = (u8 *)((_start) + (_len))
+		(skb_set_tail_pointer(RTPKT_TO_OSPKT(_pkt), _len))
 
 #define GET_OS_PKT_HEAD(_pkt) \
 		(RTPKT_TO_OSPKT(_pkt)->head)
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rt2860/rt_main_dev.c linux-libre-2.6.34-gnu1/drivers/staging/rt2860/rt_main_dev.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rt2860/rt_main_dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rt2860/rt_main_dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -216,7 +216,7 @@ int rt28xx_close(struct net_device *dev)
 	u32 i = 0;
 
 #ifdef RTMP_MAC_USB
-	DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup);
+	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
 	DECLARE_WAITQUEUE(wait, current);
 #endif /* RTMP_MAC_USB // */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rt2860/rtmp.h linux-libre-2.6.34-gnu1/drivers/staging/rt2860/rtmp.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rt2860/rtmp.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rt2860/rtmp.h	2010-05-16 17:17:36.000000000 -0400
@@ -1719,6 +1719,7 @@ struct rt_rtmp_adapter {
 	void *OS_Cookie;	/* save specific structure relative to OS */
 	struct net_device *net_dev;
 	unsigned long VirtualIfCnt;
+	const struct firmware *firmware;
 
 	struct rt_rtmp_chip_op chipOps;
 	u16 ThisTbttNumToNextWakeUp;
@@ -4043,10 +4044,10 @@ int RTUSBMultiRead(struct rt_rtmp_adapte
 			u16 Offset, u8 *pData, u16 length);
 
 int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd,
-			 u16 Offset, u8 *pData, u16 length);
+		    u16 Offset, const u8 *pData, u16 length);
 
 int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd,
-				 u16 Offset, u8 *pData);
+			    u16 Offset, const u8 *pData);
 
 int RTUSBReadBBPRegister(struct rt_rtmp_adapter *pAd,
 			      u8 Id, u8 *pValue);
@@ -4112,7 +4113,7 @@ int RTUSBSingleWrite(struct rt_rtmp_adap
 			  u16 Offset, u16 Value);
 
 int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd,
-			    u8 *pFwImage, unsigned long FwLen);
+		       const u8 *pFwImage, unsigned long FwLen);
 
 int RTUSBVenderReset(struct rt_rtmp_adapter *pAd);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rt2860/sta/connect.c linux-libre-2.6.34-gnu1/drivers/staging/rt2860/sta/connect.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rt2860/sta/connect.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rt2860/sta/connect.c	2010-05-16 17:17:36.000000000 -0400
@@ -62,8 +62,8 @@ u8 CipherSuiteWpaNoneAes[] = {
 u8 CipherSuiteWpaNoneAesLen =
     (sizeof(CipherSuiteWpaNoneAes) / sizeof(u8));
 
-/* The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS, */
-/* or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */
+/* The following MACRO is called after 1. starting an new IBSS, 2. successfully JOIN an IBSS, */
+/* or 3. successfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */
 /* All settings successfuly negotiated furing MLME state machines become final settings */
 /* and are copied to pAd->StaActive */
 #define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd)                                 \
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rt2860/sta_ioctl.c linux-libre-2.6.34-gnu1/drivers/staging/rt2860/sta_ioctl.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rt2860/sta_ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rt2860/sta_ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -975,10 +975,7 @@ int rt_ioctl_giwscan(struct net_device *
 		/*================================ */
 		memset(&iwe, 0, sizeof(iwe));
 		iwe.cmd = SIOCGIWFREQ;
-		if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
-			iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
-		else
-			iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
+		iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
 		iwe.u.freq.e = 0;
 		iwe.u.freq.i = 0;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rt2860/usb_main_dev.c linux-libre-2.6.34-gnu1/drivers/staging/rt2860/usb_main_dev.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rt2860/usb_main_dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rt2860/usb_main_dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -63,6 +63,7 @@ struct usb_device_id rtusb_usb_id[] = {
 	{USB_DEVICE(0x07D1, 0x3C11)},	/* D-Link */
 	{USB_DEVICE(0x14B2, 0x3C07)},	/* AL */
 	{USB_DEVICE(0x050D, 0x8053)},	/* Belkin */
+	{USB_DEVICE(0x050D, 0x825B)},	/* Belkin */
 	{USB_DEVICE(0x14B2, 0x3C23)},	/* Airlink */
 	{USB_DEVICE(0x14B2, 0x3C27)},	/* Airlink */
 	{USB_DEVICE(0x07AA, 0x002F)},	/* Corega */
@@ -216,10 +217,6 @@ static int rt2870_suspend(struct usb_int
 static int rt2870_resume(struct usb_interface *intf);
 #endif /* CONFIG_PM // */
 
-static int rtusb_probe(struct usb_interface *intf,
-		       const struct usb_device_id *id);
-static void rtusb_disconnect(struct usb_interface *intf);
-
 static BOOLEAN USBDevConfigInit(IN struct usb_device *dev,
 				IN struct usb_interface *intf,
 				struct rt_rtmp_adapter *pAd)
@@ -296,7 +293,7 @@ static BOOLEAN USBDevConfigInit(IN struc
 
 }
 
-static int rtusb_probe(struct usb_interface *intf,
+static int __devinit rtusb_probe(struct usb_interface *intf,
 		       const struct usb_device_id *id)
 {
 	struct rt_rtmp_adapter *pAd;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rt2870/common/rtusb_io.c linux-libre-2.6.34-gnu1/drivers/staging/rt2870/common/rtusb_io.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rt2870/common/rtusb_io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rt2870/common/rtusb_io.c	2010-05-16 17:17:36.000000000 -0400
@@ -84,7 +84,7 @@ static int RTUSBFirmwareRun(struct rt_rt
 	========================================================================
 */
 int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd,
-			    u8 *pFwImage, unsigned long FwLen)
+		       const u8 *pFwImage, unsigned long FwLen)
 {
 	u32 MacReg;
 	int Status;
@@ -167,7 +167,7 @@ int RTUSBMultiRead(struct rt_rtmp_adapte
 	========================================================================
 */
 int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd,
-				 u16 Offset, u8 *pData)
+			    u16 Offset, const u8 *pData)
 {
 	int Status;
 
@@ -175,18 +175,18 @@ int RTUSBMultiWrite_OneByte(struct rt_rt
 	Status = RTUSB_VendorRequest(pAd,
 				     USBD_TRANSFER_DIRECTION_OUT,
 				     DEVICE_VENDOR_REQUEST_OUT,
-				     0x6, 0, Offset, pData, 1);
+				     0x6, 0, Offset, (u8 *)pData, 1);
 
 	return Status;
 }
 
 int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd,
-			 u16 Offset, u8 *pData, u16 length)
+		    u16 Offset, const u8 *pData, u16 length)
 {
 	int Status;
 
 	u16 index = 0, Value;
-	u8 *pSrc = pData;
+	const u8 *pSrc = pData;
 	u16 resude = 0;
 
 	resude = length % 2;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rt2870/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/rt2870/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/rt2870/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rt2870/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -3,5 +3,7 @@ config RT2870
 	depends on USB && X86 && WLAN
 	select WIRELESS_EXT
 	select WEXT_PRIV
+	select CRC_CCITT
+	select FW_LOADER
 	---help---
 	  This is an experimental driver for the Ralink xx70 wireless chips.
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rt3070/md4.h linux-libre-2.6.34-gnu1/drivers/staging/rt3070/md4.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rt3070/md4.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rt3070/md4.h	2010-05-16 17:17:36.000000000 -0400
@@ -35,8 +35,8 @@ typedef	struct	_MD4_CTX_	{
 	u8	buffer[64];      /* input buffer */
 }	MD4_CTX;
 
-void MD4Init (MD4_CTX *);
-void MD4Update (MD4_CTX *, u8 *, UINT);
-void MD4Final (u8 [16], MD4_CTX *);
+void MD4Init(MD4_CTX *);
+void MD4Update(MD4_CTX *, u8 *, UINT);
+void MD4Final(u8 [16], MD4_CTX *);
 
-#endif //__MD4_H__
\ No newline at end of file
+#endif /*__MD4_H__*/
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c	2010-05-16 17:17:36.000000000 -0400
@@ -285,7 +285,7 @@ static int ieee80211_ccmp_decrypt(struct
 	if (!(keyidx & (1 << 5))) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "CCMP: received packet without ExtIV"
-			       " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+			       " flag from %pM\n", hdr->addr2);
 		}
 		key->dot11RSNAStatsCCMPFormatErrors++;
 		return -2;
@@ -298,9 +298,9 @@ static int ieee80211_ccmp_decrypt(struct
 	}
 	if (!key->key_set) {
 		if (net_ratelimit()) {
-			printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
+			printk(KERN_DEBUG "CCMP: received packet from %pM"
 			       " with keyid=%d that does not have a configured"
-			       " key\n", MAC_ARG(hdr->addr2), keyidx);
+			       " key\n", hdr->addr2, keyidx);
 		}
 		return -3;
 	}
@@ -315,11 +315,9 @@ static int ieee80211_ccmp_decrypt(struct
 
 	if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
 		if (net_ratelimit()) {
-			printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
-			       " previous PN %02x%02x%02x%02x%02x%02x "
-			       "received PN %02x%02x%02x%02x%02x%02x\n",
-			       MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
-			       MAC_ARG(pn));
+			printk(KERN_DEBUG "CCMP: replay detected: STA=%pM"
+			       " previous PN %pm received PN %pm\n",
+			       hdr->addr2, key->rx_pn, pn);
 		}
 		key->dot11RSNAStatsCCMPReplays++;
 		return -4;
@@ -347,7 +345,7 @@ static int ieee80211_ccmp_decrypt(struct
 	if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "CCMP: decrypt failed: STA="
-			       MAC_FMT "\n", MAC_ARG(hdr->addr2));
+			       "%pM\n", hdr->addr2);
 		}
 		key->dot11RSNAStatsCCMPDecryptErrors++;
 		return -5;
@@ -423,11 +421,10 @@ static char * ieee80211_ccmp_print_stats
 {
 	struct ieee80211_ccmp_data *ccmp = priv;
 	p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
-		     "tx_pn=%02x%02x%02x%02x%02x%02x "
-		     "rx_pn=%02x%02x%02x%02x%02x%02x "
+		     "tx_pn=%pm rx_pn=%pm "
 		     "format_errors=%d replays=%d decrypt_errors=%d\n",
 		     ccmp->key_idx, ccmp->key_set,
-		     MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
+		     ccmp->tx_pn, ccmp->rx_pn,
 		     ccmp->dot11RSNAStatsCCMPFormatErrors,
 		     ccmp->dot11RSNAStatsCCMPReplays,
 		     ccmp->dot11RSNAStatsCCMPDecryptErrors);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c	2010-05-16 17:17:36.000000000 -0400
@@ -385,7 +385,7 @@ static int ieee80211_tkip_decrypt(struct
 	if (!(keyidx & (1 << 5))) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "TKIP: received packet without ExtIV"
-			       " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+			       " flag from %pM\n", hdr->addr2);
 		}
 		return -2;
 	}
@@ -397,9 +397,9 @@ static int ieee80211_tkip_decrypt(struct
 	}
 	if (!tkey->key_set) {
 		if (net_ratelimit()) {
-			printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
+			printk(KERN_DEBUG "TKIP: received packet from %pM"
 			       " with keyid=%d that does not have a configured"
-			       " key\n", MAC_ARG(hdr->addr2), keyidx);
+			       " key\n", hdr->addr2, keyidx);
 		}
 		return -3;
 	}
@@ -410,9 +410,9 @@ static int ieee80211_tkip_decrypt(struct
 	if (iv32 < tkey->rx_iv32 ||
 	    (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
 		if (net_ratelimit()) {
-			printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
+			printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
 			       " previous TSC %08x%04x received TSC "
-			       "%08x%04x\n", MAC_ARG(hdr->addr2),
+			       "%08x%04x\n", hdr->addr2,
 			       tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
 		}
 		tkey->dot11RSNAStatsTKIPReplays++;
@@ -431,8 +431,8 @@ static int ieee80211_tkip_decrypt(struct
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG ": TKIP: failed to decrypt "
-			       "received packet from " MAC_FMT "\n",
-			       MAC_ARG(hdr->addr2));
+			       "received packet from %pM\n",
+			       hdr->addr2);
 		}
 		return -7;
 	}
@@ -450,7 +450,7 @@ static int ieee80211_tkip_decrypt(struct
 		}
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "TKIP: ICV error detected: STA="
-			       MAC_FMT "\n", MAC_ARG(hdr->addr2));
+			       "%pM\n", hdr->addr2);
 		}
 		tkey->dot11RSNAStatsTKIPICVErrors++;
 		return -5;
@@ -604,8 +604,8 @@ static int ieee80211_michael_mic_verify(
 		struct ieee80211_hdr_4addr *hdr;
 		hdr = (struct ieee80211_hdr_4addr *)skb->data;
 		printk(KERN_DEBUG "%s: Michael MIC verification failed for "
-		       "MSDU from " MAC_FMT " keyidx=%d\n",
-		       skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
+		       "MSDU from %pM keyidx=%d\n",
+		       skb->dev ? skb->dev->name : "N/A", hdr->addr2,
 		       keyidx);
 		if (skb->dev)
 			ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211.h	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/jiffies.h>
 #include <linux/timer.h>
 #include <linux/sched.h>
+#include <linux/semaphore.h>
 #include <linux/wireless.h>
 #include <linux/ieee80211.h>
 
@@ -161,10 +162,6 @@ do { if (ieee80211_debug_level & (level)
 #define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
 #endif	/* CONFIG_IEEE80211_DEBUG */
 
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2], \
-		   ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5]
-
 /*
  * To use the debug system;
  *
@@ -482,15 +479,6 @@ struct ieee80211_header_data {
 	u16 seq_ctrl;
 };
 
-struct ieee80211_hdr_3addr {
-	u16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	u16 seq_ctl;
-} __attribute__ ((packed));
-
 struct ieee80211_hdr_4addr {
 	u16 frame_ctl;
 	u16 duration_id;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -311,8 +311,8 @@ ieee80211_rx_frame_decrypt(struct ieee80
 	    strcmp(crypt->ops->name, "TKIP") == 0) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-			       "received packet from " MAC_FMT "\n",
-			       ieee->dev->name, MAC_ARG(hdr->addr2));
+			       "received packet from %pM\n",
+			       ieee->dev->name, hdr->addr2);
 		}
 		return -1;
 	}
@@ -323,8 +323,8 @@ ieee80211_rx_frame_decrypt(struct ieee80
 	atomic_dec(&crypt->refcnt);
 	if (res < 0) {
 		IEEE80211_DEBUG_DROP(
-			"decryption failed (SA=" MAC_FMT
-			") res=%d\n", MAC_ARG(hdr->addr2), res);
+			"decryption failed (SA=%pM"
+			") res=%d\n", hdr->addr2, res);
 		if (res == -2)
 			IEEE80211_DEBUG_DROP("Decryption failed ICV "
 					     "mismatch (key %d)\n",
@@ -356,8 +356,8 @@ ieee80211_rx_frame_decrypt_msdu(struct i
 	atomic_dec(&crypt->refcnt);
 	if (res < 0) {
 		printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
-		       " (SA=" MAC_FMT " keyidx=%d)\n",
-		       ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
+		       " (SA=%pM keyidx=%d)\n",
+		       ieee->dev->name, hdr->addr2, keyidx);
 		return -1;
 	}
 
@@ -550,8 +550,8 @@ int ieee80211_rtl_rx(struct ieee80211_de
 			 * frames silently instead of filling system log with
 			 * these reports. */
 			IEEE80211_DEBUG_DROP("Decryption failed (not set)"
-					     " (SA=" MAC_FMT ")\n",
-					     MAC_ARG(hdr->addr2));
+					     " (SA=%pM)\n",
+					     hdr->addr2);
 			ieee->ieee_stats.rx_discards_undecryptable++;
 			goto rx_dropped;
 		}
@@ -709,8 +709,8 @@ int ieee80211_rtl_rx(struct ieee80211_de
 		} else {
 			IEEE80211_DEBUG_DROP(
 				"encryption configured, but RX "
-				"frame not encrypted (SA=" MAC_FMT ")\n",
-				MAC_ARG(hdr->addr2));
+				"frame not encrypted (SA=%pM)\n",
+				hdr->addr2);
 			goto rx_dropped;
 		}
 	}
@@ -729,9 +729,9 @@ int ieee80211_rtl_rx(struct ieee80211_de
 	    !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
 		IEEE80211_DEBUG_DROP(
 			"dropped unencrypted RX data "
-			"frame from " MAC_FMT
+			"frame from %pM"
 			" (drop_unencrypted=1)\n",
-			MAC_ARG(hdr->addr2));
+			hdr->addr2);
 		goto rx_dropped;
 	}
 /*
@@ -1196,11 +1196,11 @@ inline int ieee80211_network_init(
 	}
 
 	if (network->mode == 0) {
-		IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
+		IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
 				     "network.\n",
 				     escape_essid(network->ssid,
 						  network->ssid_len),
-				     MAC_ARG(network->bssid));
+				     network->bssid);
 		return 1;
 	}
 
@@ -1341,9 +1341,9 @@ inline void ieee80211_process_probe_resp
 	memset(&network, 0, sizeof(struct ieee80211_network));
 
 	IEEE80211_DEBUG_SCAN(
-		"'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
+		"'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
 		escape_essid(info_element->data, info_element->len),
-		MAC_ARG(beacon->header.addr3),
+		beacon->header.addr3,
 		(beacon->capability & (1<<0xf)) ? '1' : '0',
 		(beacon->capability & (1<<0xe)) ? '1' : '0',
 		(beacon->capability & (1<<0xd)) ? '1' : '0',
@@ -1362,10 +1362,10 @@ inline void ieee80211_process_probe_resp
 		(beacon->capability & (1<<0x0)) ? '1' : '0');
 
 	if (ieee80211_network_init(ieee, beacon, &network, stats)) {
-		IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
+		IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
 				     escape_essid(info_element->data,
 						  info_element->len),
-				     MAC_ARG(beacon->header.addr3),
+				     beacon->header.addr3,
 				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
 				     IEEE80211_STYPE_PROBE_RESP ?
 				     "PROBE RESPONSE" : "BEACON");
@@ -1464,11 +1464,11 @@ inline void ieee80211_process_probe_resp
 			/* If there are no more slots, expire the oldest */
 			list_del(&oldest->list);
 			target = oldest;
-			IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
+			IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
 					     "network list.\n",
 					     escape_essid(target->ssid,
 							  target->ssid_len),
-					     MAC_ARG(target->bssid));
+					     target->bssid);
 		} else {
 			/* Otherwise just pull from the free list */
 			target = list_entry(ieee->network_free_list.next,
@@ -1478,10 +1478,10 @@ inline void ieee80211_process_probe_resp
 
 
 #ifdef CONFIG_IEEE80211_DEBUG
-		IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
+		IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
 				     escape_essid(network.ssid,
 						  network.ssid_len),
-				     MAC_ARG(network.bssid),
+				     network.bssid,
 				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
 				     IEEE80211_STYPE_PROBE_RESP ?
 				     "PROBE RESPONSE" : "BEACON");
@@ -1492,10 +1492,10 @@ inline void ieee80211_process_probe_resp
 		if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
 			ieee80211_softmac_new_net(ieee,&network);
 	} else {
-		IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
+		IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
 				     escape_essid(target->ssid,
 						  target->ssid_len),
-				     MAC_ARG(target->bssid),
+				     target->bssid,
 				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
 				     IEEE80211_STYPE_PROBE_RESP ?
 				     "PROBE RESPONSE" : "BEACON");
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 
 #include <linux/random.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include <asm/uaccess.h>
 
@@ -203,7 +204,7 @@ inline void softmac_mgmt_xmit(struct sk_
 
 			enqueue_mgmt(ieee,skb);
 		}else{
-			header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
+			header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
 
 			if (ieee->seq_ctrl[0] == 0xFFF)
 				ieee->seq_ctrl[0] = 0;
@@ -220,7 +221,7 @@ inline void softmac_mgmt_xmit(struct sk_
 		spin_unlock_irqrestore(&ieee->lock, flags);
 		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
 
-		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
+		header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
 
 		if (ieee->seq_ctrl[0] == 0xFFF)
 			ieee->seq_ctrl[0] = 0;
@@ -246,7 +247,7 @@ inline void softmac_ps_mgmt_xmit(struct
 
 	if(single){
 
-		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
+		header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
 
 		if (ieee->seq_ctrl[0] == 0xFFF)
 			ieee->seq_ctrl[0] = 0;
@@ -259,7 +260,7 @@ inline void softmac_ps_mgmt_xmit(struct
 
 	}else{
 
-		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
+		header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
 
 		if (ieee->seq_ctrl[0] == 0xFFF)
 			ieee->seq_ctrl[0] = 0;
@@ -287,7 +288,7 @@ inline struct sk_buff *ieee80211_disasso
 		return NULL;
 
 	disass = (struct ieee80211_disassoc_frame *) skb_put(skb,sizeof(struct ieee80211_disassoc_frame));
-	disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
+	disass->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
 	disass->header.duration_id = 0;
 
 	memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
@@ -905,7 +906,7 @@ struct sk_buff* ieee80211_assoc_resp(str
 	assoc = (struct ieee80211_assoc_response_frame *)
 		skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
 
-	assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
+	assoc->header.frame_control = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
 	memcpy(assoc->header.addr1, dest,ETH_ALEN);
 	memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
 	memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
@@ -981,7 +982,7 @@ struct sk_buff* ieee80211_null_func(stru
 	memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
 	memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
 
-	hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
+	hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
 		IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
 		(pwr ? IEEE80211_FCTL_PM:0));
 
@@ -1084,7 +1085,7 @@ inline struct sk_buff *ieee80211_associa
 		skb_put(skb, sizeof(struct ieee80211_assoc_request_frame));
 
 
-	hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
+	hdr->header.frame_control = IEEE80211_STYPE_ASSOC_REQ;
 	hdr->header.duration_id= 37; //FIXME
 	memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
 	memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
@@ -1573,7 +1574,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_d
 		ieee80211_resp_to_assoc_rq(ieee, dest);
 	}
 
-	printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
+	printk(KERN_INFO"New client associated: %pM\n", dest);
 }
 
 
@@ -1786,11 +1787,11 @@ ieee80211_rx_frame_softmac(struct ieee80
 
 		tasklet_schedule(&ieee->ps_task);
 
-	if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
-		WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
+	if (WLAN_FC_GET_STYPE(header->frame_control) != IEEE80211_STYPE_PROBE_RESP &&
+		WLAN_FC_GET_STYPE(header->frame_control) != IEEE80211_STYPE_BEACON)
 		ieee->last_rx_ps_time = jiffies;
 
-	switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
+	switch (WLAN_FC_GET_STYPE(header->frame_control)) {
 
 		case IEEE80211_STYPE_ASSOC_RESP:
 		case IEEE80211_STYPE_REASSOC_RESP:
@@ -2064,7 +2065,7 @@ void ieee80211_rtl_wake_queue(struct iee
 
 			header = (struct ieee80211_hdr_3addr  *) skb->data;
 
-			header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
+			header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
 
 			if (ieee->seq_ctrl[0] == 0xFFF)
 				ieee->seq_ctrl[0] = 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c	2010-05-16 17:17:36.000000000 -0400
@@ -482,8 +482,7 @@ int ieee80211_wx_set_power(struct ieee80
 		(!ieee->enter_sleep_state) ||
 		(!ieee->ps_is_queue_empty)){
 
-		printk("ERROR. PS mode is tryied to be use but\
-driver missed a callback\n\n");
+		printk("ERROR. PS mode tried to be use but driver missed a callback\n\n");
 
 		return -1;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -198,8 +198,8 @@ int ieee80211_encrypt_fragment(
 		header = (struct ieee80211_hdr_4addr *)frag->data;
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-			       "TX packet to " MAC_FMT "\n",
-			       ieee->dev->name, MAC_ARG(header->addr1));
+			       "TX packet to %pM\n",
+			       ieee->dev->name, header->addr1);
 		}
 		return -1;
 	}
@@ -407,7 +407,7 @@ int ieee80211_rtl_xmit(struct sk_buff *s
 			memcpy(&header.addr2, src, ETH_ALEN);
 			memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
 		}
-	//	printk(KERN_WARNING "essid MAC address is "MAC_FMT, MAC_ARG(&header.addr1));
+	//	printk(KERN_WARNING "essid MAC address is %pM", &header.addr1);
 		header.frame_ctl = cpu_to_le16(fc);
 		//hdr_len = IEEE80211_3ADDR_LEN;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 ******************************************************************************/
 #include <linux/wireless.h>
 #include <linux/kmod.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 
 #include "ieee80211.h"
@@ -234,10 +235,10 @@ int ieee80211_wx_get_scan(struct ieee802
 			else
 				IEEE80211_DEBUG_SCAN(
 					"Not showing network '%s ("
-					MAC_FMT ")' due to age (%lums).\n",
+					"%pM)' due to age (%lums).\n",
 					escape_essid(network->ssid,
 						     network->ssid_len),
-					MAC_ARG(network->bssid),
+					network->bssid,
 					(jiffies - network->last_scanned) / (HZ / 100));
 		}
 	}
@@ -694,7 +695,7 @@ int ieee80211_wx_set_auth(struct ieee802
 #if 1
 	case IW_AUTH_WPA_ENABLED:
 		ieee->wpa_enabled = (data->value)?1:0;
-		//printk("enalbe wpa:%d\n", ieee->wpa_enabled);
+		//printk("enable wpa:%d\n", ieee->wpa_enabled);
 		break;
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@ config R8187SE
 	depends on PCI && WLAN
 	select WIRELESS_EXT
 	select WEXT_PRIV
+	select EEPROM_93CX6
 	default N
 	---help---
 	  If built as a module, it will be called r8187se.ko.
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/Makefile linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@ EXTRA_CFLAGS += -DENABLE_LPS
 
 r8187se-objs :=			\
 		r8180_core.o		\
-		r8180_93cx6.o		\
 		r8180_wx.o		\
 		r8180_rtl8225z2.o	\
 		r8185b_init.o		\
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/r8180_93cx6.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/r8180_93cx6.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/r8180_93cx6.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/r8180_93cx6.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,146 +0,0 @@
-/*
-   This files contains card eeprom (93c46 or 93c56) programming routines,
-   memory is addressed by 16 bits words.
-
-   This is part of rtl8180 OpenSource driver.
-   Copyright (C) Andrea Merello 2004  <andreamrl@tiscali.it>
-   Released under the terms of GPL (General Public Licence)
-
-   Parts of this driver are based on the GPL part of the
-   official realtek driver.
-
-   Parts of this driver are based on the rtl8180 driver skeleton
-   from Patric Schenke & Andres Salomon.
-
-   Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
-
-   We want to tanks the Authors of those projects and the Ndiswrapper
-   project Authors.
-*/
-
-#include "r8180_93cx6.h"
-
-void eprom_cs(struct net_device *dev, short bit)
-{
-	if(bit)
-		write_nic_byte(dev, EPROM_CMD,
-			       (1<<EPROM_CS_SHIFT) | \
-			       read_nic_byte(dev, EPROM_CMD)); //enable EPROM
-	else
-		write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
-			       &~(1<<EPROM_CS_SHIFT)); //disable EPROM
-
-	force_pci_posting(dev);
-	udelay(EPROM_DELAY);
-}
-
-
-void eprom_ck_cycle(struct net_device *dev)
-{
-	write_nic_byte(dev, EPROM_CMD,
-		       (1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD));
-	force_pci_posting(dev);
-	udelay(EPROM_DELAY);
-	write_nic_byte(dev, EPROM_CMD,
-		       read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT));
-	force_pci_posting(dev);
-	udelay(EPROM_DELAY);
-}
-
-
-void eprom_w(struct net_device *dev,short bit)
-{
-	if(bit)
-		write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
-			       read_nic_byte(dev,EPROM_CMD));
-	else
-		write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\
-			       &~(1<<EPROM_W_SHIFT));
-
-	force_pci_posting(dev);
-	udelay(EPROM_DELAY);
-}
-
-
-short eprom_r(struct net_device *dev)
-{
-	short bit;
-
-	bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) );
-	udelay(EPROM_DELAY);
-
-	if(bit) return 1;
-	return 0;
-}
-
-
-void eprom_send_bits_string(struct net_device *dev, short b[], int len)
-{
-	int i;
-
-	for(i=0; i<len; i++){
-		eprom_w(dev, b[i]);
-		eprom_ck_cycle(dev);
-	}
-}
-
-
-u32 eprom_read(struct net_device *dev, u32 addr)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	short read_cmd[]={1,1,0};
-	short addr_str[8];
-	int i;
-	int addr_len;
-	u32 ret;
-
-	ret=0;
-        //enable EPROM programming
-	write_nic_byte(dev, EPROM_CMD,
-		       (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
-	force_pci_posting(dev);
-	udelay(EPROM_DELAY);
-
-	if (priv->epromtype==EPROM_93c56){
-		addr_str[7]=addr & 1;
-		addr_str[6]=addr & (1<<1);
-		addr_str[5]=addr & (1<<2);
-		addr_str[4]=addr & (1<<3);
-		addr_str[3]=addr & (1<<4);
-		addr_str[2]=addr & (1<<5);
-		addr_str[1]=addr & (1<<6);
-		addr_str[0]=addr & (1<<7);
-		addr_len=8;
-	}else{
-		addr_str[5]=addr & 1;
-		addr_str[4]=addr & (1<<1);
-		addr_str[3]=addr & (1<<2);
-		addr_str[2]=addr & (1<<3);
-		addr_str[1]=addr & (1<<4);
-		addr_str[0]=addr & (1<<5);
-		addr_len=6;
-	}
-	eprom_cs(dev, 1);
-	eprom_ck_cycle(dev);
-	eprom_send_bits_string(dev, read_cmd, 3);
-	eprom_send_bits_string(dev, addr_str, addr_len);
-
-	//keep chip pin D to low state while reading.
-	//I'm unsure if it is necessary, but anyway shouldn't hurt
-	eprom_w(dev, 0);
-
-	for(i=0;i<16;i++){
-		//eeprom needs a clk cycle between writing opcode&adr
-		//and reading data. (eeprom outs a dummy 0)
-		eprom_ck_cycle(dev);
-		ret |= (eprom_r(dev)<<(15-i));
-	}
-
-	eprom_cs(dev, 0);
-	eprom_ck_cycle(dev);
-
-	//disable EPROM programming
-	write_nic_byte(dev, EPROM_CMD,
-		       (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
-	return ret;
-}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/r8180_93cx6.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/r8180_93cx6.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/r8180_93cx6.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/r8180_93cx6.h	2010-05-16 17:17:36.000000000 -0400
@@ -45,13 +45,10 @@
 
 #define	EPROM_TXPW_OFDM_CH1_2 0x20
 
-//#define	EPROM_TXPW_CH1_2 0x10
-#define  EPROM_TXPW_CH1_2 0x30
-#define	EPROM_TXPW_CH3_4 0x11
-#define	EPROM_TXPW_CH5_6 0x12
-#define	EPROM_TXPW_CH7_8 0x13
-#define	EPROM_TXPW_CH9_10 0x14
-#define	EPROM_TXPW_CH11_12 0x15
-#define	EPROM_TXPW_CH13_14 0x16
+#define	EPROM_TXPW_CH1_2 0x30
+
+#define RTL818X_EEPROM_CMD_READ		(1 << 0)
+#define RTL818X_EEPROM_CMD_WRITE	(1 << 1)
+#define RTL818X_EEPROM_CMD_CK		(1 << 2)
+#define RTL818X_EEPROM_CMD_CS		(1 << 3)
 
-u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/r8180_core.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/r8180_core.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/r8180_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/r8180_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,9 @@
 #undef RX_DONT_PASS_UL
 #undef DUMMY_RX
 
+#include <linux/slab.h>
 #include <linux/syscalls.h>
+#include <linux/eeprom_93cx6.h>
 
 #include "r8180_hw.h"
 #include "r8180.h"
@@ -41,13 +43,6 @@
 
 #include "ieee80211/dot11d.h"
 
-#ifndef PCI_VENDOR_ID_BELKIN
-	#define PCI_VENDOR_ID_BELKIN 0x1799
-#endif
-#ifndef PCI_VENDOR_ID_DLINK
-	#define PCI_VENDOR_ID_DLINK 0x1186
-#endif
-
 static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = {
         {
                 .vendor = PCI_VENDOR_ID_REALTEK,
@@ -669,11 +664,8 @@ unsigned char STRENGTH_MAP[] = {
 
 void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual)
 {
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	u32 temp;
 	u32 temp2;
-	u32 temp3;
-	u32 lsb;
 	u32 q;
 	u32 orig_qual;
 	u8  _rssi;
@@ -695,88 +687,6 @@ void rtl8180_RSSI_calc(struct net_device
 	*qual = temp;
 	temp2 = *rssi;
 
-	switch(priv->rf_chip){
-	case RFCHIPID_RFMD:
-		lsb = temp2 & 1;
-		temp2 &= 0x7e;
-		if ( !lsb || !(temp2 <= 0x3c) ) {
-			temp2 = 0x64;
-		} else {
-			temp2 = 100 * temp2 / 0x3c;
-		}
-		*rssi = temp2 & 0xff;
-		_rssi = temp2 & 0xff;
-		break;
-	case RFCHIPID_INTERSIL:
-		lsb = temp2;
-		temp2 &= 0xfffffffe;
-		temp2 *= 251;
-		temp3 = temp2;
-		temp2 <<= 6;
-		temp3 += temp2;
-		temp3 <<= 1;
-		temp2 = 0x4950df;
-		temp2 -= temp3;
-		lsb &= 1;
-		if ( temp2 <= 0x3e0000 ) {
-			if ( temp2 < 0xffef0000 )
-				temp2 = 0xffef0000;
-		} else {
-			temp2 = 0x3e0000;
-		}
-		if ( !lsb ) {
-			temp2 -= 0xf0000;
-		} else {
-			temp2 += 0xf0000;
-		}
-
-		temp3 = 0x4d0000;
-		temp3 -= temp2;
-		temp3 *= 100;
-		temp3 = temp3 / 0x6d;
-		temp3 >>= 0x10;
-		_rssi = temp3 & 0xff;
-		*rssi = temp3 & 0xff;
-		break;
-	case RFCHIPID_GCT:
-	        lsb = temp2 & 1;
-		temp2 &= 0x7e;
-		if ( ! lsb || !(temp2 <= 0x3c) ){
-			temp2 = 0x64;
-		} else {
-			temp2 = (100 * temp2) / 0x3c;
-		}
-		*rssi = temp2 & 0xff;
-		_rssi = temp2 & 0xff;
-		break;
-	case RFCHIPID_PHILIPS:
-		if( orig_qual <= 0x4e ){
-			_rssi = STRENGTH_MAP[orig_qual];
-			*rssi = _rssi;
-		} else {
-			orig_qual -= 0x80;
-			if ( !orig_qual ){
-				_rssi = 1;
-				*rssi = 1;
-			} else {
-				_rssi = 0x32;
-				*rssi = 0x32;
-			}
-		}
-		break;
-	case RFCHIPID_MAXIM:
-		lsb = temp2 & 1;
-		temp2 &= 0x7e;
-		temp2 >>= 1;
-		temp2 += 0x42;
-		if( lsb != 0 ){
-			temp2 += 0xa;
-		}
-		*rssi = temp2 & 0xff;
-		_rssi = temp2 & 0xff;
-		break;
-	}
-
 	if ( _rssi < 0x64 ){
 		if ( _rssi == 0 ) {
 			*rssi = 1;
@@ -1421,11 +1331,9 @@ u16 N_DBPSOfRate(u16 DataRate)
 	return N_DBPS;
 }
 
-//{by amy 080312
 //
 //	Description:
 // 	For Netgear case, they want good-looking singal strength.
-//		2004.12.05, by rcnjko.
 //
 long NetgearSignalStrengthTranslate(long LastSS, long CurrSS)
 {
@@ -1481,7 +1389,6 @@ long TranslateToDbm8185(u8 SignalStrengt
 //		This is different with PerformSignalSmoothing8185 in smoothing fomula.
 //		No dramatic adjustion is apply because dynamic mechanism need some degree
 //		of correctness. Ported from 8187B.
-//	2007-02-26, by Bruce.
 //
 void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv,
 					   bool bCckRate)
@@ -1502,7 +1409,6 @@ void PerformUndecoratedSignalSmoothing81
 		priv->CurCCKRSSI = 0;
 }
 
-//by amy 080312}
 
 /* This is rough RX isr handling routine*/
 void rtl8180_rx(struct net_device *dev)
@@ -1638,7 +1544,7 @@ void rtl8180_rx(struct net_device *dev)
 		}
 
 		signal=(unsigned char)(((*(priv->rxringtail+3))& (0x00ff0000))>>16);
-		signal=(signal&0xfe)>>1;	// Modify by hikaru 6.6
+		signal = (signal & 0xfe) >> 1;
 
 		quality=(unsigned char)((*(priv->rxringtail+3)) & (0xff));
 
@@ -1652,7 +1558,6 @@ void rtl8180_rx(struct net_device *dev)
 
 		stats.rate = rtl8180_rate2rate(rate);
 		Antenna = (((*(priv->rxringtail +3))& (0x00008000)) == 0 )? 0:1 ;
-//by amy for antenna
 		if(!rtl8180_IsWirelessBMode(stats.rate))
 		{ // OFDM rate.
 
@@ -1691,11 +1596,10 @@ void rtl8180_rx(struct net_device *dev)
 			RXAGC=(95-RXAGC)*100/65;
 		}
 		priv->SignalStrength = (u8)RXAGC;
-		priv->RecvSignalPower = RxAGC_dBm ;  // It can use directly by SD3 CMLin
+		priv->RecvSignalPower = RxAGC_dBm;
 		priv->RxPower = rxpower;
 		priv->RSSI = RSSI;
-//{by amy 080312
-		// SQ translation formular is provided by SD3 DZ. 2006.06.27, by rcnjko.
+		/* SQ translation formula is provided by SD3 DZ. 2006.06.27 */
 		if(quality >= 127)
 			quality = 1;//0; //0 will cause epc to show signal zero , walk aroud now;
 		else if(quality < 27)
@@ -1712,7 +1616,6 @@ void rtl8180_rx(struct net_device *dev)
 	//	printk("==========================>rx : RXAGC is %d,signalstrength is %d\n",RXAGC,stats.signalstrength);
 		stats.rssi = priv->wstats.qual.qual = priv->SignalQuality;
 		stats.noise = priv->wstats.qual.noise = 100 - priv ->wstats.qual.qual;
-//by amy 080312}
 		bHwError = (((*(priv->rxringtail))& (0x00000fff)) == 4080)| (((*(priv->rxringtail))& (0x04000000)) != 0 )
 			| (((*(priv->rxringtail))& (0x08000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x10000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x20000000)) != 0 );
 		bCRC = ((*(priv->rxringtail)) & (0x00002000)) >> 13;
@@ -1725,11 +1628,12 @@ void rtl8180_rx(struct net_device *dev)
 				(eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
 				 && (!bHwError) && (!bCRC)&& (!bICV))
 			{
-//by amy 080312
-				// Perform signal smoothing for dynamic mechanism on demand.
-				// This is different with PerformSignalSmoothing8185 in smoothing fomula.
-				// No dramatic adjustion is apply because dynamic mechanism need some degree
-				// of correctness. 2007.01.23, by shien chang.
+				/* Perform signal smoothing for dynamic
+				 * mechanism on demand. This is different
+				 * with PerformSignalSmoothing8185 in smoothing
+				 * fomula. No dramatic adjustion is apply
+				 * because dynamic mechanism need some degree
+				 * of correctness. */
 				PerformUndecoratedSignalSmoothing8185(priv,bCckRate);
 				//
 				// For good-looking singal strength.
@@ -1749,12 +1653,9 @@ void rtl8180_rx(struct net_device *dev)
 
 		// Figure out which antenna that received the lasted packet.
 				priv->LastRxPktAntenna = Antenna ? 1 : 0; // 0: aux, 1: main.
-//by amy 080312
 			    SwAntennaDiversityRxOk8185(dev, priv->SignalStrength);
 			}
 
-//by amy for antenna
-#ifndef DUMMY_RX
 		if(first){
 			if(!priv->rx_skb_complete){
 				/* seems that HW sometimes fails to reiceve and
@@ -1810,19 +1711,12 @@ void rtl8180_rx(struct net_device *dev)
 		if(last && !priv->rx_skb_complete){
 			if(priv->rx_skb->len > 4)
 				skb_trim(priv->rx_skb,priv->rx_skb->len-4);
-#ifndef RX_DONT_PASS_UL
 			if(!ieee80211_rtl_rx(priv->ieee80211,
-					 priv->rx_skb, &stats)){
-#endif // RX_DONT_PASS_UL
-
+					 priv->rx_skb, &stats))
 				dev_kfree_skb_any(priv->rx_skb);
-#ifndef RX_DONT_PASS_UL
-			}
-#endif
 			priv->rx_skb_complete=1;
 		}
 
-#endif //DUMMY_RX
 		pci_dma_sync_single_for_device(priv->pdev,
 				    priv->rxbuffer->dma,
 				    priv->rxbuffersize * \
@@ -1890,7 +1784,7 @@ rate)
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	int mode;
 	struct ieee80211_hdr_3addr  *h = (struct ieee80211_hdr_3addr  *) skb->data;
-	short morefrag = (h->frame_ctl) & IEEE80211_FCTL_MOREFRAGS;
+	short morefrag = (h->frame_control) & IEEE80211_FCTL_MOREFRAGS;
 	unsigned long flags;
 	int priority;
 
@@ -2056,7 +1950,7 @@ short rtl8180_tx(struct net_device *dev,
 	u16			RtsDur = 0;
 	u16			ThisFrameTime = 0;
 	u16			TxDescDuration = 0;
-	u8 			ownbit_flag = false; //added by david woo for sync Tx, 2007.12.14
+	u8 			ownbit_flag = false;
 
 	switch(priority) {
 	case MANAGE_PRIORITY:
@@ -2123,7 +2017,8 @@ short rtl8180_tx(struct net_device *dev,
 			//YJ,add,080828,for Keep alive
 			priv->NumTxUnicast++;
 
-			// Figure out ACK rate according to BSS basic rate and Tx rate, 2006.03.08 by rcnjko.
+			/* Figure out ACK rate according to BSS basic rate
+			 * and Tx rate. */
 			AckTime = ComputeTxTime(14, 10,0, 0);	// AckCTSLng = 14 use 1M bps send
 
 			if ( ((len + sCrcLng) > priv->rts) && priv->rts )
@@ -2158,7 +2053,7 @@ short rtl8180_tx(struct net_device *dev,
 				TxDescDuration = ThisFrameTime + aSifsTime + AckTime;
 			}
 
-			if(!(frag_hdr->frame_ctl & IEEE80211_FCTL_MOREFRAGS)) { //no more fragment
+			if (!(frag_hdr->frame_control & IEEE80211_FCTL_MOREFRAGS)) {
 				// ThisFrame-ACK.
 				Duration = aSifsTime + AckTime;
 			} else { // One or more fragments remained.
@@ -2206,7 +2101,7 @@ short rtl8180_tx(struct net_device *dev,
 		*tail |= (1<<15); /* no encrypt */
 
 		if(remain==len && !descfrag) {
-			ownbit_flag = false;	//added by david woo,2007.12.14
+			ownbit_flag = false;
 			*tail = *tail| (1<<29) ; //fist segment of the packet
 			*tail = *tail |(len);
 		} else {
@@ -2556,27 +2451,16 @@ void watch_dog_adaptive(unsigned long da
 	}
 
 	// Tx High Power Mechanism.
-#ifdef HIGH_POWER
 	if(CheckHighPower((struct net_device *)data))
-	{
 		queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->tx_pw_wq);
-	}
-#endif
 
 	// Tx Power Tracking on 87SE.
-#ifdef TX_TRACK
-	//if( priv->bTxPowerTrack )	//lzm mod 080826
-	if( CheckTxPwrTracking((struct net_device *)data));
+	if (CheckTxPwrTracking((struct net_device *)data))
 		TxPwrTracking87SE((struct net_device *)data);
-#endif
 
 	// Perform DIG immediately.
-#ifdef SW_DIG
 	if(CheckDig((struct net_device *)data) == true)
-	{
 		queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_dig_wq);
-	}
-#endif
    	rtl8180_watch_dog((struct net_device *)data);
 
 	queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->GPIOChangeRFWorkItem);
@@ -2675,6 +2559,36 @@ static void rtl8180_link_detect_init(pli
 }
 //YJ,add,080828,end
 
+static void rtl8187se_eeprom_register_read(struct eeprom_93cx6 *eeprom)
+{
+	struct net_device *dev = eeprom->data;
+	u8 reg = read_nic_byte(dev, EPROM_CMD);
+
+	eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE;
+	eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ;
+	eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK;
+	eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS;
+}
+
+static void rtl8187se_eeprom_register_write(struct eeprom_93cx6 *eeprom)
+{
+	struct net_device *dev = eeprom->data;
+	u8 reg = 2 << 6;
+
+	if (eeprom->reg_data_in)
+		reg |= RTL818X_EEPROM_CMD_WRITE;
+	if (eeprom->reg_data_out)
+		reg |= RTL818X_EEPROM_CMD_READ;
+	if (eeprom->reg_data_clock)
+		reg |= RTL818X_EEPROM_CMD_CK;
+	if (eeprom->reg_chip_select)
+		reg |= RTL818X_EEPROM_CMD_CS;
+
+	write_nic_byte(dev, EPROM_CMD, reg);
+	read_nic_byte(dev, EPROM_CMD);
+	udelay(10);
+}
+
 short rtl8180_init(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
@@ -2683,8 +2597,16 @@ short rtl8180_init(struct net_device *de
 	u32 usValue;
 	u16 tmpu16;
 	int i, j;
+	struct eeprom_93cx6 eeprom;
+	u16 eeprom_val;
 
-	priv->channel_plan = eprom_read(dev, EEPROM_COUNTRY_CODE>>1) & 0xFF;
+	eeprom.data = dev;
+	eeprom.register_read = rtl8187se_eeprom_register_read;
+	eeprom.register_write = rtl8187se_eeprom_register_write;
+	eeprom.width = PCI_EEPROM_WIDTH_93C46;
+
+	eeprom_93cx6_read(&eeprom, EEPROM_COUNTRY_CODE>>1, &eeprom_val);
+	priv->channel_plan = eeprom_val & 0xFF;
 	if(priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN){
 		printk("rtl8180_init:Error channel plan! Set to default.\n");
 		priv->channel_plan = 0;
@@ -2701,8 +2623,6 @@ short rtl8180_init(struct net_device *de
 	priv->txbeaconcount = 2;
 	priv->rx_skb_complete = 1;
 
-	priv->RegThreeWireMode = HW_THREE_WIRE_SI;
-
 	priv->RFChangeInProgress = false;
 	priv->SetRFPowerStateInProgress = false;
 	priv->RFProgType = 0;
@@ -2747,10 +2667,8 @@ short rtl8180_init(struct net_device *de
 	priv->TxPollingTimes = 0;//lzm add 080826
 	priv->bLeisurePs = true;
 	priv->dot11PowerSaveMode = eActive;
-//by amy for antenna
 	priv->AdMinCheckPeriod = 5;
 	priv->AdMaxCheckPeriod = 10;
-// Lower signal strength threshold to fit the HW participation in antenna diversity. +by amy 080312
 	priv->AdMaxRxSsThreshold = 30;//60->30
 	priv->AdRxSsThreshold = 20;//50->20
 	priv->AdCheckPeriod = priv->AdMinCheckPeriod;
@@ -2765,8 +2683,6 @@ short rtl8180_init(struct net_device *de
 	init_timer(&priv->SwAntennaDiversityTimer);
 	priv->SwAntennaDiversityTimer.data = (unsigned long)dev;
 	priv->SwAntennaDiversityTimer.function = (void *)SwAntennaDiversityTimerCallback;
-//by amy for antenna
-//{by amy 080312
 	priv->bDigMechanism = 1;
 	priv->InitialGain = 6;
 	priv->bXtalCalibration = false;
@@ -2803,58 +2719,63 @@ short rtl8180_init(struct net_device *de
 	priv->NumTxUnicast = 0;
 	priv->keepAliveLevel = DEFAULT_KEEP_ALIVE_LEVEL;
 	priv->PowerProfile = POWER_PROFILE_AC;
-    priv->CurrRetryCnt=0;
-    priv->LastRetryCnt=0;
-    priv->LastTxokCnt=0;
-    priv->LastRxokCnt=0;
-    priv->LastRetryRate=0;
-    priv->bTryuping=0;
-    priv->CurrTxRate=0;
-    priv->CurrRetryRate=0;
-    priv->TryupingCount=0;
-    priv->TryupingCountNoData=0;
-    priv->TryDownCountLowData=0;
-    priv->LastTxOKBytes=0;
-    priv->LastFailTxRate=0;
-    priv->LastFailTxRateSS=0;
-    priv->FailTxRateCount=0;
-    priv->LastTxThroughput=0;
-    priv->NumTxOkBytesTotal=0;
+	priv->CurrRetryCnt = 0;
+	priv->LastRetryCnt = 0;
+	priv->LastTxokCnt = 0;
+	priv->LastRxokCnt = 0;
+	priv->LastRetryRate = 0;
+	priv->bTryuping = 0;
+	priv->CurrTxRate = 0;
+	priv->CurrRetryRate = 0;
+	priv->TryupingCount = 0;
+	priv->TryupingCountNoData = 0;
+	priv->TryDownCountLowData = 0;
+	priv->LastTxOKBytes = 0;
+	priv->LastFailTxRate = 0;
+	priv->LastFailTxRateSS = 0;
+	priv->FailTxRateCount = 0;
+	priv->LastTxThroughput = 0;
+	priv->NumTxOkBytesTotal = 0;
 	priv->ForcedDataRate = 0;
 	priv->RegBModeGainStage = 1;
 
-	priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
+	priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
 	spin_lock_init(&priv->irq_lock);
 	spin_lock_init(&priv->irq_th_lock);
 	spin_lock_init(&priv->tx_lock);
 	spin_lock_init(&priv->ps_lock);
 	spin_lock_init(&priv->rf_ps_lock);
-	sema_init(&priv->wx_sem,1);
-	sema_init(&priv->rf_state,1);
-	INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart_wq);
-	INIT_WORK(&priv->tx_irq_wq,(void*) rtl8180_tx_irq_wq);
-	INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8180_hw_wakeup_wq);
-	INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8180_hw_sleep_wq);
-	INIT_WORK(&priv->ieee80211->wmm_param_update_wq,(void*) rtl8180_wmm_param_update);
-	INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter);//+by amy 080312
-	INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq);//+by amy 080312
-	INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq);//+by amy 080312
-
-	INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,(void*) GPIOChangeRFWorkItemCallBack);
-
+	sema_init(&priv->wx_sem, 1);
+	sema_init(&priv->rf_state, 1);
+	INIT_WORK(&priv->reset_wq, (void *)rtl8180_restart_wq);
+	INIT_WORK(&priv->tx_irq_wq, (void *)rtl8180_tx_irq_wq);
+	INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,
+			  (void *)rtl8180_hw_wakeup_wq);
+	INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,
+			  (void *)rtl8180_hw_sleep_wq);
+	INIT_WORK(&priv->ieee80211->wmm_param_update_wq,
+		  (void *)rtl8180_wmm_param_update);
+	INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,
+			  (void *)rtl8180_rate_adapter);
+	INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,
+			 (void *)rtl8180_hw_dig_wq);
+	INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,
+			 (void *)rtl8180_tx_pw_wq);
+	INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,
+			 (void *) GPIOChangeRFWorkItemCallBack);
 	tasklet_init(&priv->irq_rx_tasklet,
 		     (void(*)(unsigned long)) rtl8180_irq_rx_tasklet,
 		     (unsigned long)priv);
 
-    init_timer(&priv->watch_dog_timer);
+	init_timer(&priv->watch_dog_timer);
 	priv->watch_dog_timer.data = (unsigned long)dev;
 	priv->watch_dog_timer.function = watch_dog_adaptive;
 
-    init_timer(&priv->rateadapter_timer);
-        priv->rateadapter_timer.data = (unsigned long)dev;
-        priv->rateadapter_timer.function = timer_rate_adaptive;
-		priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;
-		priv->bEnhanceTxPwr=false;
+	init_timer(&priv->rateadapter_timer);
+	priv->rateadapter_timer.data = (unsigned long)dev;
+	priv->rateadapter_timer.function = timer_rate_adaptive;
+	priv->RateAdaptivePeriod = RATE_ADAPTIVE_TIMER_PERIOD;
+	priv->bEnhanceTxPwr = false;
 
 	priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit;
 	priv->ieee80211->set_chan = rtl8180_set_chan;
@@ -2877,30 +2798,28 @@ short rtl8180_init(struct net_device *de
 
 	priv->CSMethod = (0x01 << 29);
 
-	priv->TransmitConfig	=
-									1<<TCR_DurProcMode_OFFSET |		//for RTL8185B, duration setting by HW
-									(7<<TCR_MXDMA_OFFSET) |	// Max DMA Burst Size per Tx DMA Burst, 7: reservied.
-									(priv->ShortRetryLimit<<TCR_SRL_OFFSET) |	// Short retry limit
-									(priv->LongRetryLimit<<TCR_LRL_OFFSET) |	// Long retry limit
-									(0 ? TCR_SAT : 0);	// FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
+	priv->TransmitConfig =	TCR_DurProcMode_OFFSET |
+				(7<<TCR_MXDMA_OFFSET) |
+				(priv->ShortRetryLimit<<TCR_SRL_OFFSET) |
+				(priv->LongRetryLimit<<TCR_LRL_OFFSET) |
+				(0 ? TCR_SAT : 0);
 
-	priv->ReceiveConfig	=
-								RCR_AMF | RCR_ADF |				//accept management/data
-								RCR_ACF |						//accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
-								RCR_AB | RCR_AM | RCR_APM |		//accept BC/MC/UC
-								(7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
-								(priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
-								(priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
+	priv->ReceiveConfig =	RCR_AMF | RCR_ADF | RCR_ACF |
+				RCR_AB | RCR_AM | RCR_APM |
+				(7<<RCR_MXDMA_OFFSET) |
+				(priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) |
+				(priv->EarlyRxThreshold == 7 ?
+					 RCR_ONLYERLPKT : 0);
 
 	priv->IntrMask		= IMR_TMGDOK | IMR_TBDER | IMR_THPDER |
-								IMR_THPDER | IMR_THPDOK |
-								IMR_TVODER | IMR_TVODOK |
-								IMR_TVIDER | IMR_TVIDOK |
-								IMR_TBEDER | IMR_TBEDOK |
-								IMR_TBKDER | IMR_TBKDOK |
-								IMR_RDU |						// To handle the defragmentation not enough Rx descriptors case. Annie, 2006-03-27.
-								IMR_RER | IMR_ROK |
-								IMR_RQoSOK; // <NOTE> ROK and RQoSOK are mutually exclusive, so, we must handle RQoSOK interrupt to receive QoS frames, 2005.12.09, by rcnjko.
+				  IMR_THPDER | IMR_THPDOK |
+				  IMR_TVODER | IMR_TVODOK |
+				  IMR_TVIDER | IMR_TVIDOK |
+				  IMR_TBEDER | IMR_TBEDOK |
+				  IMR_TBKDER | IMR_TBKDOK |
+				  IMR_RDU |
+				  IMR_RER | IMR_ROK |
+				  IMR_RQoSOK;
 
 	priv->InitialGain = 6;
 
@@ -2913,7 +2832,8 @@ short rtl8180_init(struct net_device *de
 	// just for sync 85
 	priv->enable_gpio0 = 0;
 
-	usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET);
+	eeprom_93cx6_read(&eeprom, EEPROM_SW_REVD_OFFSET, &eeprom_val);
+	usValue = eeprom_val;
 	DMESG("usValue is 0x%x\n",usValue);
 	//3Read AntennaDiversity
 
@@ -2953,54 +2873,46 @@ short rtl8180_init(struct net_device *de
 	else
 		priv->epromtype=EPROM_93c46;
 
-	dev->dev_addr[0]=eprom_read(dev,MAC_ADR) & 0xff;
-	dev->dev_addr[1]=(eprom_read(dev,MAC_ADR) & 0xff00)>>8;
-	dev->dev_addr[2]=eprom_read(dev,MAC_ADR+1) & 0xff;
-	dev->dev_addr[3]=(eprom_read(dev,MAC_ADR+1) & 0xff00)>>8;
-	dev->dev_addr[4]=eprom_read(dev,MAC_ADR+2) & 0xff;
-	dev->dev_addr[5]=(eprom_read(dev,MAC_ADR+2) & 0xff00)>>8;
+	eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)
+			       dev->dev_addr, 3);
 
 	for(i=1,j=0; i<14; i+=2,j++){
-		word = eprom_read(dev,EPROM_TXPW_CH1_2 + j);
+		eeprom_93cx6_read(&eeprom, EPROM_TXPW_CH1_2 + j, &word);
 		priv->chtxpwr[i]=word & 0xff;
 		priv->chtxpwr[i+1]=(word & 0xff00)>>8;
 	}
 	for (i = 1, j = 0; i < 14; i += 2, j++) {
-		word = eprom_read(dev, EPROM_TXPW_OFDM_CH1_2 + j);
+		eeprom_93cx6_read(&eeprom, EPROM_TXPW_OFDM_CH1_2 + j, &word);
 		priv->chtxpwr_ofdm[i] = word & 0xff;
-		priv->chtxpwr_ofdm[i+1] = (word & 0xff00)>>8;
+		priv->chtxpwr_ofdm[i+1] = (word & 0xff00) >> 8;
 	}
 
-	//3Read crystal calibtration and thermal meter indication on 87SE.
-
-	// By SD3 SY's request. Added by Roger, 2007.12.11.
-
-	tmpu16 = eprom_read(dev, EEPROM_RSV>>1);
+	/* 3Read crystal calibtration and thermal meter indication on 87SE. */
+	eeprom_93cx6_read(&eeprom, EEPROM_RSV>>1, &tmpu16);
 
-		// Crystal calibration for Xin and Xout resp.
-		priv->XtalCal_Xout = tmpu16 & EEPROM_XTAL_CAL_XOUT_MASK; // 0~7.5pF
-		priv->XtalCal_Xin = (tmpu16 & EEPROM_XTAL_CAL_XIN_MASK)>>4; // 0~7.5pF
-		if((tmpu16 & EEPROM_XTAL_CAL_ENABLE)>>12)
-			priv->bXtalCalibration = true;
+	/* Crystal calibration for Xin and Xout resp. */
+	priv->XtalCal_Xout = tmpu16 & EEPROM_XTAL_CAL_XOUT_MASK;
+	priv->XtalCal_Xin = (tmpu16 & EEPROM_XTAL_CAL_XIN_MASK) >> 4;
+	if ((tmpu16 & EEPROM_XTAL_CAL_ENABLE) >> 12)
+		priv->bXtalCalibration = true;
 
-		// Thermal meter reference indication.
-		priv->ThermalMeter =  (u8)((tmpu16 & EEPROM_THERMAL_METER_MASK)>>8);
-		if((tmpu16 & EEPROM_THERMAL_METER_ENABLE)>>13)
-			priv->bTxPowerTrack = true;
+	/* Thermal meter reference indication. */
+	priv->ThermalMeter =  (u8)((tmpu16 & EEPROM_THERMAL_METER_MASK) >> 8);
+	if ((tmpu16 & EEPROM_THERMAL_METER_ENABLE) >> 13)
+		priv->bTxPowerTrack = true;
 
-	word = eprom_read(dev,EPROM_TXPW_BASE);
+	eeprom_93cx6_read(&eeprom, EPROM_TXPW_BASE, &word);
 	priv->cck_txpwr_base = word & 0xf;
 	priv->ofdm_txpwr_base = (word>>4) & 0xf;
 
-	version = eprom_read(dev,EPROM_VERSION);
+	eeprom_93cx6_read(&eeprom, EPROM_VERSION, &version);
 	DMESG("EEPROM version %x",version);
 	priv->rcr_csense = 3;
 
-	priv->cs_treshold = (eprom_read(dev, ENERGY_TRESHOLD) & 0xff00) >> 8;
-
-	priv->rf_chip = 0xff & eprom_read(dev, RFCHIPID);
+	eeprom_93cx6_read(&eeprom, ENERGY_TRESHOLD, &eeprom_val);
+	priv->cs_treshold = (eeprom_val & 0xff00) >> 8;
 
-	priv->rf_chip = RF_ZEBRA4;
+	eeprom_93cx6_read(&eeprom, RFCHIPID, &eeprom_val);
 	priv->rf_sleep = rtl8225z4_rf_sleep;
 	priv->rf_wakeup = rtl8225z4_rf_wakeup;
 	DMESGW("**PLEASE** REPORT SUCCESSFUL/UNSUCCESSFUL TO Realtek!");
@@ -3010,7 +2922,6 @@ short rtl8180_init(struct net_device *de
 	priv->rf_set_chan = rtl8225z2_rf_set_chan;
 	priv->rf_set_sens = NULL;
 
-
 	if (0!=alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount))
 		return -ENOMEM;
 
@@ -3042,11 +2953,7 @@ short rtl8180_init(struct net_device *de
 				  TX_BEACON_RING_ADDR))
 		return -ENOMEM;
 
-#if !defined(SA_SHIRQ)
         if(request_irq(dev->irq, (void *)rtl8180_interrupt, IRQF_SHARED, dev->name, dev)){
-#else
-        if(request_irq(dev->irq, (void *)rtl8180_interrupt, SA_SHIRQ, dev->name, dev)){
-#endif
                 DMESGE("Error allocating IRQ %d",dev->irq);
                 return -1;
 	}else{
@@ -3169,43 +3076,6 @@ void write_phy_cck (struct net_device *d
 	rtl8185_write_phy(dev, adr, data | 0x10000);
 }
 
-/* 70*3 = 210 ms
- * I hope this is enougth
- */
-#define MAX_PHY 70
-void write_phy(struct net_device *dev, u8 adr, u8 data)
-{
-	u32 phy;
-	int i;
-
-	phy = 0xff0000;
-	phy |= adr;
-	phy |= 0x80; /* this should enable writing */
-	phy |= (data<<8);
-
-	//PHY_ADR, PHY_R and PHY_W  are contig and treated as one dword
-	write_nic_dword(dev,PHY_ADR, phy);
-
-	phy= 0xffff00;
-	phy |= adr;
-
-	write_nic_dword(dev,PHY_ADR, phy);
-	for(i=0;i<MAX_PHY;i++){
-		phy=read_nic_dword(dev,PHY_ADR);
-		phy= phy & 0xff0000;
-		phy= phy >> 16;
-		if(phy == data){ //SUCCESS!
-			force_pci_posting(dev);
-			mdelay(3); //random value
-			return;
-		}else{
-			force_pci_posting(dev);
-			mdelay(3); //random value
-		}
-	}
-	DMESGW ("Phy writing %x %x failed!", adr,data);
-}
-
 void rtl8185_set_rate(struct net_device *dev)
 {
 	int i;
@@ -3335,7 +3205,6 @@ static struct net_device_stats *rtl8180_
 }
 //
 // Change current and default preamble mode.
-// 2005.01.06, by rcnjko.
 //
 bool
 MgntActSet_802_11_PowerSaveMode(
@@ -3454,7 +3323,6 @@ void rtl8180_watch_dog(struct net_device
 	MgntLinkKeepAlive(priv);
 
 	//YJ,add,080828,for LPS
-#ifdef ENABLE_LPS
 	if (priv->PowerProfile == POWER_PROFILE_BATTERY)
 		priv->bLeisurePs = true;
 	else if (priv->PowerProfile == POWER_PROFILE_AC) {
@@ -3464,7 +3332,6 @@ void rtl8180_watch_dog(struct net_device
 
 	if(priv->ieee80211->state == IEEE80211_LINKED){
 		priv->link_detect.NumRxOkInPeriod = priv->ieee80211->NumRxDataInPeriod;
-		//printk("TxOk=%d RxOk=%d\n", priv->link_detect.NumTxOkInPeriod, priv->link_detect.NumRxOkInPeriod);
 		if(	priv->link_detect.NumRxOkInPeriod> 666 ||
 			priv->link_detect.NumTxOkInPeriod> 666 ) {
 			bBusyTraffic = true;
@@ -3481,7 +3348,6 @@ void rtl8180_watch_dog(struct net_device
 			LeisurePSLeave(priv);
 	} else
 		LeisurePSLeave(priv);
-#endif
 	priv->link_detect.bBusyTraffic = bBusyTraffic;
 	priv->link_detect.NumRxOkInPeriod = 0;
 	priv->link_detect.NumTxOkInPeriod = 0;
@@ -3503,16 +3369,11 @@ int _rtl8180_up(struct net_device *dev)
 		if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
 			IPSLeave(dev);
 	}
-#ifdef RATE_ADAPT
        timer_rate_adaptive((unsigned long)dev);
-#endif
 	watch_dog_adaptive((unsigned long)dev);
-#ifdef SW_ANTE
         if(priv->bSwAntennaDiverity)
 			SwAntennaDiversityTimerCallback(dev);
-#endif
 	ieee80211_softmac_start_protocol(priv->ieee80211);
-
 	return 0;
 }
 
@@ -3748,7 +3609,7 @@ static int __devinit rtl8180_pci_probe(s
 	dev->wireless_handlers = &r8180_wx_handlers_def;
 
 	dev->type=ARPHRD_ETHER;
-	dev->watchdog_timeo = HZ*3; //added by david woo, 2007.12.13
+	dev->watchdog_timeo = HZ*3;
 
 	if (dev_alloc_name(dev, ifname) < 0){
                 DMESG("Oops: devname already taken! Trying wlan%%d...\n");
@@ -3864,8 +3725,7 @@ static int __init rtl8180_pci_module_ini
 		return ret;
 	}
 
-	printk(KERN_INFO "\nLinux kernel driver for RTL8180 \
-/ RTL8185 based WLAN cards\n");
+	printk(KERN_INFO "\nLinux kernel driver for RTL8180 / RTL8185 based WLAN cards\n");
 	printk(KERN_INFO "Copyright (c) 2004-2005, Andrea Merello\n");
 	DMESG("Initializing module");
 	DMESG("Wireless extensions version %d", WIRELESS_EXT);
@@ -4236,60 +4096,51 @@ void GPIOChangeRFWorkItemCallBack(struct
         static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL};
 	static int readf_count = 0;
 
-#ifdef ENABLE_LPS
 	if(readf_count % 10 == 0)
 		priv->PowerProfile = read_acadapter_file("/proc/acpi/ac_adapter/AC0/state");
 
 	readf_count = (readf_count+1)%0xffff;
-#endif
-		{
-			// We should turn off LED before polling FF51[4].
+	/* We should turn off LED before polling FF51[4]. */
 
-			//Turn off LED.
-			btPSR = read_nic_byte(dev, PSR);
-			write_nic_byte(dev, PSR, (btPSR & ~BIT3));
+	/* Turn off LED. */
+	btPSR = read_nic_byte(dev, PSR);
+	write_nic_byte(dev, PSR, (btPSR & ~BIT3));
 
-			//It need to delay 4us suggested by Jong, 2008-01-16
-			udelay(4);
+	/* It need to delay 4us suggested by Jong, 2008-01-16 */
+	udelay(4);
 
-			//HW radio On/Off according to the value of FF51[4](config0)
-			btConfig0 = btPSR = read_nic_byte(dev, CONFIG0);
+	/* HW radio On/Off according to the value of FF51[4](config0) */
+	btConfig0 = btPSR = read_nic_byte(dev, CONFIG0);
 
-			//Turn on LED.
-			write_nic_byte(dev, PSR, btPSR| BIT3);
+	eRfPowerStateToSet = (btConfig0 & BIT4) ?  eRfOn : eRfOff;
 
-			eRfPowerStateToSet = (btConfig0 & BIT4) ?  eRfOn : eRfOff;
+	/* Turn LED back on when radio enabled */
+	if (eRfPowerStateToSet == eRfOn)
+		write_nic_byte(dev, PSR, btPSR | BIT3);
 
-			if((priv->ieee80211->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn))
-			{
-				priv->ieee80211->bHwRadioOff = false;
-				bActuallySet = true;
-			}
-			else if((priv->ieee80211->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff))
-			{
-				priv->ieee80211->bHwRadioOff = true;
-				bActuallySet = true;
-			}
+	if ((priv->ieee80211->bHwRadioOff == true) &&
+	   (eRfPowerStateToSet == eRfOn)) {
+		priv->ieee80211->bHwRadioOff = false;
+		bActuallySet = true;
+	} else if ((priv->ieee80211->bHwRadioOff == false) &&
+		  (eRfPowerStateToSet == eRfOff)) {
+		priv->ieee80211->bHwRadioOff = true;
+		bActuallySet = true;
+	}
 
-			if(bActuallySet)
-			{
-				MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
+	if (bActuallySet) {
+		MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
 
-				/* To update the UI status for Power status changed */
-                                if(priv->ieee80211->bHwRadioOff == true)
-                                        argv[1] = "RFOFF";
-                                else{
-                                        //if(!priv->RfOffReason)
-                                                argv[1] = "RFON";
-                                        //else
-                                        //      argv[1] = "RFOFF";
-                                }
-                                argv[0] = RadioPowerPath;
-                                argv[2] = NULL;
+		/* To update the UI status for Power status changed */
+		if (priv->ieee80211->bHwRadioOff == true)
+			argv[1] = "RFOFF";
+		else
+			argv[1] = "RFON";
+		argv[0] = RadioPowerPath;
+		argv[2] = NULL;
 
-                                call_usermodehelper(RadioPowerPath,argv,envp,1);
-			}
-		}
+		call_usermodehelper(RadioPowerPath, argv, envp, 1);
+	}
 }
 
 static u8 read_acadapter_file(char *filename)
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/r8180_dm.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/r8180_dm.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/r8180_dm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/r8180_dm.c	2010-05-16 17:17:36.000000000 -0400
@@ -282,30 +282,13 @@ DIG_Zebra(
 //		Dispatch DIG implementation according to RF.
 //
 void
-DynamicInitGain(
-	struct net_device *dev
-	)
+DynamicInitGain(struct net_device *dev)
 {
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	switch(priv->rf_chip)
-	{
-		case RF_ZEBRA2:  // [AnnieWorkaround] For Zebra2, 2005-08-01.
-		case RF_ZEBRA4:
-			DIG_Zebra( dev );
-			break;
-
-		default:
-			printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);
-			break;
-	}
+	DIG_Zebra(dev);
 }
 
 void rtl8180_hw_dig_wq (struct work_struct *work)
 {
-//      struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
-//      struct ieee80211_device * ieee = (struct ieee80211_device*)
-//                                             container_of(work, struct ieee80211_device, watch_dog_wq);
 	struct delayed_work *dwork = to_delayed_work(work);
         struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
         struct net_device *dev = ieee->dev;
@@ -1310,44 +1293,24 @@ SetAntenna8185(
 	switch(u1bAntennaIndex)
 	{
 	case 0:
-		switch(priv->rf_chip)
-		{
-		case RF_ZEBRA2:
-		case RF_ZEBRA4:
-			// Mac register, main antenna
-			write_nic_byte(dev, ANTSEL, 0x03);
-			//base band
-			write_phy_cck(dev,0x11, 0x9b); // Config CCK RX antenna.
-			write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
-
-
-			bAntennaSwitched = true;
-			break;
+		/* Mac register, main antenna */
+		write_nic_byte(dev, ANTSEL, 0x03);
+		/* base band */
+		write_phy_cck(dev, 0x11, 0x9b); /* Config CCK RX antenna. */
+		write_phy_ofdm(dev, 0x0d, 0x5c); /* Config OFDM RX antenna. */
 
-		default:
-			printk("SetAntenna8185: unknown RFChipID(%d)\n", priv->rf_chip);
-			break;
-		}
+		bAntennaSwitched = true;
 		break;
 
 	case 1:
-		switch(priv->rf_chip)
-		{
-		case RF_ZEBRA2:
-		case RF_ZEBRA4:
-			// Mac register, aux antenna
-			write_nic_byte(dev, ANTSEL, 0x00);
-			//base band
-			write_phy_cck(dev, 0x11, 0xbb); // Config CCK RX antenna.
-			write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
+		/* Mac register, aux antenna */
+		write_nic_byte(dev, ANTSEL, 0x00);
+		/* base band */
+		write_phy_cck(dev, 0x11, 0xbb); /* Config CCK RX antenna. */
+		write_phy_ofdm(dev, 0x0d, 0x54); /* Config OFDM RX antenna. */
 
-			bAntennaSwitched = true;
-			break;
+		bAntennaSwitched = true;
 
-		default:
-			printk("SetAntenna8185: unknown RFChipID(%d)\n", priv->rf_chip);
-			break;
-		}
 		break;
 
 	default:
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/r8180.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/r8180.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/r8180.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/r8180.h	2010-05-16 17:17:36.000000000 -0400
@@ -366,7 +366,6 @@ typedef struct r8180_priv
 	short diversity;
 	u8 cs_treshold;
 	short rcr_csense;
-	short rf_chip;
 	u32 key0[4];
 	short (*rf_set_sens)(struct net_device *dev,short sens);
 	void (*rf_set_chan)(struct net_device *dev,short ch);
@@ -479,9 +478,6 @@ typedef struct r8180_priv
 	u8 retry_rts;
 	u16 rts;
 
-//add for RF power on power off by lizhaoming 080512
-	u8	 RegThreeWireMode; // See "Three wire mode" defined above, 2006.05.31, by rcnjko.
-
 //by amy for led
 	LED_STRATEGY_8185 LedStrategy;
 //by amy for led
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/r8180_rtl8225z2.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/r8180_rtl8225z2.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/r8180_rtl8225z2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/r8180_rtl8225z2.c	2010-05-16 17:17:36.000000000 -0400
@@ -854,134 +854,48 @@ bool SetZebraRFPowerState8185(struct net
 	btConfig3 = read_nic_byte(dev, CONFIG3);
 	write_nic_byte(dev, CONFIG3, (btConfig3 | CONFIG3_PARM_En));
 
-	switch (priv->rf_chip) {
-	case RF_ZEBRA2:
-		switch (eRFPowerState) {
-		case eRfOn:
-			RF_WriteReg(dev,0x4,0x9FF);
-
-			write_nic_dword(dev, ANAPARAM, ANAPARM_ON);
-			write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON);
-
-			write_nic_byte(dev, CONFIG4, priv->RFProgType);
-
-			/* turn on CCK and OFDM */
-			u1bTmp = read_nic_byte(dev, 0x24E);
-			write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6))));
-			break;
-		case eRfSleep:
-			break;
-		case eRfOff:
-			break;
-		default:
-			bResult = false;
-			break;
-		}
-		break;
-	case RF_ZEBRA4:
-		switch (eRFPowerState) {
-		case eRfOn:
-			write_nic_word(dev, 0x37C, 0x00EC);
-
-			/* turn on AFE */
-			write_nic_byte(dev, 0x54, 0x00);
-			write_nic_byte(dev, 0x62, 0x00);
-
-			/* turn on RF */
-			RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
-			RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
-
-			/* turn on RF again */
-			RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
-			RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
-
-			/* turn on BB */
-			write_phy_ofdm(dev,0x10,0x40);
-			write_phy_ofdm(dev,0x12,0x40);
-
-			/* Avoid power down at init time. */
-			write_nic_byte(dev, CONFIG4, priv->RFProgType);
-
-			u1bTmp = read_nic_byte(dev, 0x24E);
-			write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6))));
-			break;
-		case eRfSleep:
-			for (QueueID = 0, i = 0; QueueID < 6;) {
-				if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) {
-					QueueID++;
-					continue;
-				} else {
-					priv->TxPollingTimes ++;
-					if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
-						bActionAllowed = false;
-						break;
-					} else
-						udelay(10);
-				}
-			}
-
-			if (bActionAllowed) {
-				/* turn off BB RXIQ matrix to cut off rx signal */
-				write_phy_ofdm(dev, 0x10, 0x00);
-				write_phy_ofdm(dev, 0x12, 0x00);
-
-				/* turn off RF */
-				RF_WriteReg(dev, 0x4, 0x0000);
-				RF_WriteReg(dev, 0x0, 0x0000);
-
-				/* turn off AFE except PLL */
-				write_nic_byte(dev, 0x62, 0xff);
-				write_nic_byte(dev, 0x54, 0xec);
-
-				mdelay(1);
+	switch (eRFPowerState) {
+	case eRfOn:
+		write_nic_word(dev, 0x37C, 0x00EC);
 
-				{
-					int i = 0;
-					while (true) {
-						u8 tmp24F = read_nic_byte(dev, 0x24f);
+		/* turn on AFE */
+		write_nic_byte(dev, 0x54, 0x00);
+		write_nic_byte(dev, 0x62, 0x00);
 
-						if ((tmp24F == 0x01) || (tmp24F == 0x09)) {
-							bTurnOffBB = true;
-							break;
-						} else {
-							udelay(10);
-							i++;
-							priv->TxPollingTimes++;
+		/* turn on RF */
+		RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
+		RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
 
-							if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
-								bTurnOffBB = false;
-								break;
-							} else
-								udelay(10);
-						}
-					}
-				}
+		/* turn on RF again */
+		RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
+		RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
 
-				if (bTurnOffBB) {
-					/* turn off BB */
-					u1bTmp = read_nic_byte(dev, 0x24E);
-					write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6));
+		/* turn on BB */
+		write_phy_ofdm(dev, 0x10, 0x40);
+		write_phy_ofdm(dev, 0x12, 0x40);
 
-					/* turn off AFE PLL */
-					write_nic_byte(dev, 0x54, 0xFC);
-					write_nic_word(dev, 0x37C, 0x00FC);
-				}
-			}
-			break;
-		case eRfOff:
-			for (QueueID = 0, i = 0; QueueID < 6;) {
-				if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) {
-					QueueID++;
-					continue;
-				} else {
-					udelay(10);
-					i++;
-				}
+		/* Avoid power down at init time. */
+		write_nic_byte(dev, CONFIG4, priv->RFProgType);
 
-				if (i >= MAX_DOZE_WAITING_TIMES_85B)
+		u1bTmp = read_nic_byte(dev, 0x24E);
+		write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6))));
+		break;
+	case eRfSleep:
+		for (QueueID = 0, i = 0; QueueID < 6;) {
+			if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) {
+				QueueID++;
+				continue;
+			} else {
+				priv->TxPollingTimes++;
+				if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
+					bActionAllowed = false;
 					break;
+				} else
+					udelay(10);
 			}
+		}
 
+		if (bActionAllowed) {
 			/* turn off BB RXIQ matrix to cut off rx signal */
 			write_phy_ofdm(dev, 0x10, 0x00);
 			write_phy_ofdm(dev, 0x12, 0x00);
@@ -998,22 +912,23 @@ bool SetZebraRFPowerState8185(struct net
 
 			{
 				int i = 0;
-
-				while (true)
-				{
+				while (true) {
 					u8 tmp24F = read_nic_byte(dev, 0x24f);
 
 					if ((tmp24F == 0x01) || (tmp24F == 0x09)) {
 						bTurnOffBB = true;
 						break;
 					} else {
-						bTurnOffBB = false;
 						udelay(10);
 						i++;
-					}
+						priv->TxPollingTimes++;
 
-					if (i > MAX_POLLING_24F_TIMES_87SE)
-						break;
+						if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
+							bTurnOffBB = false;
+							break;
+						} else
+							udelay(10);
+					}
 				}
 			}
 
@@ -1022,15 +937,68 @@ bool SetZebraRFPowerState8185(struct net
 				u1bTmp = read_nic_byte(dev, 0x24E);
 				write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6));
 
-				/* turn off AFE PLL (80M) */
+				/* turn off AFE PLL */
 				write_nic_byte(dev, 0x54, 0xFC);
 				write_nic_word(dev, 0x37C, 0x00FC);
 			}
-			break;
-		default:
-			bResult = false;
-			printk("SetZebraRFPowerState8185(): unknown state to set: 0x%X!!!\n", eRFPowerState);
-			break;
+		}
+		break;
+	case eRfOff:
+		for (QueueID = 0, i = 0; QueueID < 6;) {
+			if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) {
+				QueueID++;
+				continue;
+			} else {
+				udelay(10);
+				i++;
+			}
+
+			if (i >= MAX_DOZE_WAITING_TIMES_85B)
+				break;
+		}
+
+		/* turn off BB RXIQ matrix to cut off rx signal */
+		write_phy_ofdm(dev, 0x10, 0x00);
+		write_phy_ofdm(dev, 0x12, 0x00);
+
+		/* turn off RF */
+		RF_WriteReg(dev, 0x4, 0x0000);
+		RF_WriteReg(dev, 0x0, 0x0000);
+
+		/* turn off AFE except PLL */
+		write_nic_byte(dev, 0x62, 0xff);
+		write_nic_byte(dev, 0x54, 0xec);
+
+		mdelay(1);
+
+		{
+			int i = 0;
+
+			while (true) {
+				u8 tmp24F = read_nic_byte(dev, 0x24f);
+
+				if ((tmp24F == 0x01) || (tmp24F == 0x09)) {
+					bTurnOffBB = true;
+					break;
+				} else {
+					bTurnOffBB = false;
+					udelay(10);
+					i++;
+				}
+
+				if (i > MAX_POLLING_24F_TIMES_87SE)
+					break;
+			}
+		}
+
+		if (bTurnOffBB) {
+			/* turn off BB */
+			u1bTmp = read_nic_byte(dev, 0x24E);
+			write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6));
+
+			/* turn off AFE PLL (80M) */
+			write_nic_byte(dev, 0x54, 0xFC);
+			write_nic_word(dev, 0x37C, 0x00FC);
 		}
 		break;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/r8185b_init.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/r8185b_init.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/r8185b_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/r8185b_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -238,100 +238,12 @@ PlatformIORead4Byte(
 	return data;
 }
 
-void
-SetOutputEnableOfRfPins(
-	struct net_device *dev
-	)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	switch(priv->rf_chip)
-	{
-	case RFCHIPID_RTL8225:
-	case RF_ZEBRA2:
-	case RF_ZEBRA4:
-		write_nic_word(dev, RFPinsEnable, 0x1bff);
-		//write_nic_word(dev, RFPinsEnable, 0x1fff);
-		break;
-	}
-}
-
-void
-ZEBRA_RFSerialWrite(
-	struct net_device *dev,
-	u32			data2Write,
-	u8			totalLength,
-	u8			low2high
-	)
+void SetOutputEnableOfRfPins(struct net_device *dev)
 {
-	ThreeWireReg		twreg;
-	int 				i;
-	u16				oval,oval2,oval3;
-	u32				mask;
-	u16				UshortBuffer;
-
-	u8			u1bTmp;
-	// RTL8187S HSSI Read/Write Function
-	u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
-	u1bTmp |=   RF_SW_CFG_SI;   //reg08[1]=1 Serial Interface(SI)
-	write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
-	UshortBuffer = read_nic_word(dev, RFPinsOutput);
-	oval = UshortBuffer & 0xfff8; // We shall clear bit0, 1, 2 first, 2005.10.28, by rcnjko.
-
-	oval2 = read_nic_word(dev, RFPinsEnable);
-	oval3 = read_nic_word(dev, RFPinsSelect);
-
-	// <RJ_NOTE> 3-wire should be controled by HW when we finish SW 3-wire programming. 2005.08.10, by rcnjko.
-	oval3 &= 0xfff8;
-
-	write_nic_word(dev, RFPinsEnable, (oval2|0x0007)); // Set To Output Enable
-	write_nic_word(dev, RFPinsSelect, (oval3|0x0007)); // Set To SW Switch
-	udelay(10);
-
-	// Add this to avoid hardware and software 3-wire conflict.
-	// 2005.03.01, by rcnjko.
-	twreg.longData = 0;
-	twreg.struc.enableB = 1;
-	write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); // Set SI_EN (RFLE)
-	udelay(2);
-	twreg.struc.enableB = 0;
-	write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); // Clear SI_EN (RFLE)
-	udelay(10);
-
-	mask = (low2high)?0x01:((u32)0x01<<(totalLength-1));
-
-	for(i=0; i<totalLength/2; i++)
-	{
-		twreg.struc.data = ((data2Write&mask)!=0) ? 1 : 0;
-		write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
-		twreg.struc.clk = 1;
-		write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
-		write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
-
-		mask = (low2high)?(mask<<1):(mask>>1);
-		twreg.struc.data = ((data2Write&mask)!=0) ? 1 : 0;
-		write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
-		write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
-		twreg.struc.clk = 0;
-		write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
-		mask = (low2high)?(mask<<1):(mask>>1);
-	}
-
-	twreg.struc.enableB = 1;
-	twreg.struc.clk = 0;
-	twreg.struc.data = 0;
-	write_nic_word(dev, RFPinsOutput, twreg.longData|oval);
-	udelay(10);
-
-	write_nic_word(dev, RFPinsOutput, oval|0x0004);
-	write_nic_word(dev, RFPinsSelect, oval3|0x0000);
-
-	SetOutputEnableOfRfPins(dev);
+	write_nic_word(dev, RFPinsEnable, 0x1bff);
 }
-//by amy
-
 
-int
+static int
 HwHSSIThreeWire(
 	struct net_device *dev,
 	u8			*pDataBuf,
@@ -469,420 +381,30 @@ HwHSSIThreeWire(
 
 	return bResult;
 }
-//by amy
-
-int
-HwThreeWire(
-	struct net_device *dev,
-	u8			*pDataBuf,
-	u8			nDataBufBitCnt,
-	int			bHold,
-	int			bWrite
-	)
-{
-	int	bResult = 1;
-	u8	TryCnt;
-	u8	u1bTmp;
-
-	do
-	{
-		// Check if WE and RE are cleared.
-		for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
-		{
-			u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
-			if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 )
-			{
-				break;
-			}
-			udelay(10);
-		}
-		if (TryCnt == TC_3W_POLL_MAX_TRY_CNT)
-			panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp);
-
-		// Fill up data buffer for write operation.
-		if(nDataBufBitCnt == 16)
-		{
-			write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
-		}
-		else if(nDataBufBitCnt == 64)
-		{
-			write_nic_dword(dev, SW_3W_DB0, *((u32 *)pDataBuf));
-			write_nic_dword(dev, SW_3W_DB1, *((u32 *)(pDataBuf + 4)));
-		}
-		else
-		{
-			int idx;
-			int ByteCnt = nDataBufBitCnt / 8;
-
-			if ((nDataBufBitCnt % 8) != 0)
-				panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
-				nDataBufBitCnt);
-
-			if (nDataBufBitCnt > 64)
-				panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
-				nDataBufBitCnt);
-
-			for(idx = 0; idx < ByteCnt; idx++)
-			{
-				write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
-			}
-		}
-
-		// Fill up length field.
-		u1bTmp = (u8)(nDataBufBitCnt - 1); // Number of bits - 1.
-		if(bHold)
-			u1bTmp |= SW_3W_CMD0_HOLD;
-		write_nic_byte(dev, SW_3W_CMD0, u1bTmp);
-
-		// Set up command: WE or RE.
-		if(bWrite)
-		{
-			write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
-		}
-		else
-		{
-			write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
-		}
-
-		// Check if WE and RE are cleared and DONE is set.
-		for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
-		{
-			u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
-			if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 &&
-				(u1bTmp & SW_3W_CMD1_DONE) != 0 )
-			{
-				break;
-			}
-			udelay(10);
-		}
-		if(TryCnt == TC_3W_POLL_MAX_TRY_CNT)
-		{
-			//RT_ASSERT(TryCnt != TC_3W_POLL_MAX_TRY_CNT,
-			//	("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear or DONE is not set!!\n", u1bTmp));
-			// Workaround suggested by wcchu: clear WE here. 2006.07.07, by rcnjko.
-			write_nic_byte(dev, SW_3W_CMD1, 0);
-		}
-
-		// Read back data for read operation.
-		// <RJ_TODO> I am not sure if this is correct output format of a read operation.
-		if(bWrite == 0)
-		{
-			if(nDataBufBitCnt == 16)
-			{
-				*((u16 *)pDataBuf) = read_nic_word(dev, SW_3W_DB0);
-			}
-			else if(nDataBufBitCnt == 64)
-			{
-				*((u32 *)pDataBuf) = read_nic_dword(dev, SW_3W_DB0);
-				*((u32 *)(pDataBuf + 4)) = read_nic_dword(dev, SW_3W_DB1);
-			}
-			else
-			{
-				int idx;
-				int ByteCnt = nDataBufBitCnt / 8;
-
-				if ((nDataBufBitCnt % 8) != 0)
-					panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
-					nDataBufBitCnt);
-
-				if (nDataBufBitCnt > 64)
-					panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
-					nDataBufBitCnt);
-
-				for(idx = 0; idx < ByteCnt; idx++)
-				{
-					*(pDataBuf+idx) = read_nic_byte(dev, (SW_3W_DB0+idx));
-				}
-			}
-		}
-
-	}while(0);
-
-	return bResult;
-}
-
 
 void
-RF_WriteReg(
-	struct net_device *dev,
-	u8		offset,
-	u32		data
-	)
-{
-	//RFReg			reg;
-	u32			data2Write;
-	u8			len;
-	u8			low2high;
-	//u32			RF_Read = 0;
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-
-	switch(priv->rf_chip)
-	{
-	case RFCHIPID_RTL8225:
-	case RF_ZEBRA2:		// Annie 2006-05-12.
-	case RF_ZEBRA4:        //by amy
-		switch(priv->RegThreeWireMode)
-		{
-		case SW_THREE_WIRE:
-			{ // Perform SW 3-wire programming by driver.
-				data2Write = (data << 4) | (u32)(offset & 0x0f);
-				len = 16;
-				low2high = 0;
-				ZEBRA_RFSerialWrite(dev, data2Write, len, low2high);
-       			}
-			break;
-
- 		case HW_THREE_WIRE:
-			{ // Pure HW 3-wire.
-				data2Write = (data << 4) | (u32)(offset & 0x0f);
-				len = 16;
-				HwThreeWire(
-					dev,
-					(u8 *)(&data2Write),	// pDataBuf,
-					len,				// nDataBufBitCnt,
-					0,					// bHold,
-					1);					// bWrite
-         		}
-			break;
-			case HW_THREE_WIRE_PI: //Parallel Interface
-			{ // Pure HW 3-wire.
-				data2Write = (data << 4) | (u32)(offset & 0x0f);
-				len = 16;
-					HwHSSIThreeWire(
-						dev,
-						(u8*)(&data2Write),	// pDataBuf,
-						len,						// nDataBufBitCnt,
-						0, 					// bSI
-						1); 					// bWrite
-
-                                //printk("33333\n");
-			}
-			break;
-
-			case HW_THREE_WIRE_SI: //Serial Interface
-			{ // Pure HW 3-wire.
-				data2Write = (data << 4) | (u32)(offset & 0x0f);
-				len = 16;
-//                                printk(" enter  ZEBRA_RFSerialWrite\n ");
-//                                low2high = 0;
-//                                ZEBRA_RFSerialWrite(dev, data2Write, len, low2high);
-
-				HwHSSIThreeWire(
-					dev,
-					(u8*)(&data2Write),	// pDataBuf,
-					len,						// nDataBufBitCnt,
-					1, 					// bSI
-					1); 					// bWrite
-
-//                                 printk(" exit ZEBRA_RFSerialWrite\n ");
-			}
-			break;
-
-
-		default:
-			DMESGE("RF_WriteReg(): invalid RegThreeWireMode(%d) !!!", priv->RegThreeWireMode);
-			break;
-		}
-		break;
-
-	default:
-		DMESGE("RF_WriteReg(): unknown RFChipID: %#X", priv->rf_chip);
-		break;
-	}
-}
-
-
-void
-ZEBRA_RFSerialRead(
-	struct net_device *dev,
-	u32		data2Write,
-	u8		wLength,
-	u32		*data2Read,
-	u8		rLength,
-	u8		low2high
-	)
+RF_WriteReg(struct net_device *dev, u8 offset, u32 data)
 {
-	ThreeWireReg	twreg;
-	int				i;
-	u16			oval,oval2,oval3,tmp, wReg80;
-	u32			mask;
-	u8			u1bTmp;
-	ThreeWireReg	tdata;
-	//PHAL_DATA_8187	pHalData = GetHalData8187(pAdapter);
-	{ // RTL8187S HSSI Read/Write Function
-		u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
-		u1bTmp |=   RF_SW_CFG_SI;   //reg08[1]=1 Serial Interface(SI)
-		write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
-	}
-
-	wReg80 = oval = read_nic_word(dev, RFPinsOutput);
-	oval2 = read_nic_word(dev, RFPinsEnable);
-	oval3 = read_nic_word(dev, RFPinsSelect);
-
-	write_nic_word(dev, RFPinsEnable, oval2|0xf);
-	write_nic_word(dev, RFPinsSelect, oval3|0xf);
-
-	*data2Read = 0;
-
-	// We must clear BIT0-3 here, otherwise,
-	// SW_Enalbe will be true when we first call ZEBRA_RFSerialRead() after 8187MPVC open,
-	// which will cause the value read become 0. 2005.04.11, by rcnjko.
-	oval &= ~0xf;
-
-	// Avoid collision with hardware three-wire.
-	twreg.longData = 0;
-	twreg.struc.enableB = 1;
-	write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(4);
-
-	twreg.longData = 0;
-	twreg.struc.enableB = 0;
-	twreg.struc.clk = 0;
-	twreg.struc.read_write = 0;
-	write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(5);
-
-	mask = (low2high) ? 0x01 : ((u32)0x01<<(32-1));
-	for(i = 0; i < wLength/2; i++)
-	{
-		twreg.struc.data = ((data2Write&mask) != 0) ? 1 : 0;
-		write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
-		twreg.struc.clk = 1;
-		write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
-		write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
-
-		mask = (low2high) ? (mask<<1): (mask>>1);
-
-		if(i == 2)
-		{
-			// Commented out by Jackie, 2004.08.26. <RJ_NOTE> We must comment out the following two lines for we cannot pull down VCOPDN during RF Serail Read.
-			//PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, 0xe);     // turn off data enable
-			//PlatformEFIOWrite2Byte(pAdapter, RFPinsSelect, 0xe);
-
-			twreg.struc.read_write=1;
-			write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
-			twreg.struc.clk = 0;
-			write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
-			break;
-		}
-		twreg.struc.data = ((data2Write&mask) != 0) ? 1: 0;
-		write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
-		write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
-
-		twreg.struc.clk = 0;
-		write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
-
-		mask = (low2high) ? (mask<<1) : (mask>>1);
-	}
-
-	twreg.struc.clk = 0;
-	twreg.struc.data = 0;
-	write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
-	mask = (low2high) ? 0x01 : ((u32)0x01 << (12-1));
-
-	//
-	// 061016, by rcnjko:
-	// We must set data pin to HW controled, otherwise RF can't driver it and
-	// value RF register won't be able to read back properly.
-	//
-	write_nic_word(dev, RFPinsEnable, ( ((oval2|0x0E) & (~0x01))) );
-
-	for(i = 0; i < rLength; i++)
-	{
-		write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
-		twreg.struc.clk = 1;
-		write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
-		write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
-		write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
-		tmp = read_nic_word(dev, RFPinsInput);
-		tdata.longData = tmp;
-		*data2Read |= tdata.struc.clk ? mask : 0;
-
-		twreg.struc.clk = 0;
-		write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
+	u32 data2Write;
+	u8 len;
 
-		mask = (low2high) ? (mask<<1) : (mask>>1);
-	}
-	twreg.struc.enableB = 1;
-	twreg.struc.clk = 0;
-	twreg.struc.data = 0;
-	twreg.struc.read_write = 1;
-	write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
+	/* Pure HW 3-wire. */
+	data2Write = (data << 4) | (u32)(offset & 0x0f);
+	len = 16;
 
-	//PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, oval2|0x8);   // Set To Output Enable
-	write_nic_word(dev, RFPinsEnable, oval2);   // Set To Output Enable, <RJ_NOTE> We cannot enable BIT3 here, otherwise, we will failed to switch channel. 2005.04.12.
-	//PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, 0x1bff);
-	write_nic_word(dev, RFPinsSelect, oval3);   // Set To SW Switch
-	//PlatformEFIOWrite2Byte(pAdapter, RFPinsSelect, 0x0488);
-	write_nic_word(dev, RFPinsOutput, 0x3a0);
-	//PlatformEFIOWrite2Byte(pAdapter, RFPinsOutput, 0x0480);
+	HwHSSIThreeWire(dev, (u8 *)(&data2Write), len, 1, 1);
 }
 
-
-u32
-RF_ReadReg(
-	struct net_device *dev,
-	u8		offset
-	)
+u32 RF_ReadReg(struct net_device *dev, u8 offset)
 {
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	u32			data2Write;
-	u8			wlen;
-	u8			rlen;
-	u8			low2high;
-	u32			dataRead;
-
-	switch(priv->rf_chip)
-	{
-	case RFCHIPID_RTL8225:
-	case RF_ZEBRA2:
-	case RF_ZEBRA4:
-		switch(priv->RegThreeWireMode)
-		{
-			case HW_THREE_WIRE_PI: // For 87S  Parallel Interface.
-			{
-				data2Write = ((u32)(offset&0x0f));
-				wlen=16;
-				HwHSSIThreeWire(
-					dev,
-					(u8*)(&data2Write),	// pDataBuf,
-					wlen,					// nDataBufBitCnt,
-					0, 					// bSI
-					0); 					// bWrite
-				dataRead= data2Write;
-			}
-			break;
-
-			case HW_THREE_WIRE_SI: // For 87S Serial Interface.
-			{
-				data2Write = ((u32)(offset&0x0f)) ;
-				wlen=16;
-				HwHSSIThreeWire(
-					dev,
-					(u8*)(&data2Write),	// pDataBuf,
-					wlen,					// nDataBufBitCnt,
-					1, 					// bSI
-					0					// bWrite
-					);
-				dataRead= data2Write;
-			}
-			break;
+	u32 data2Write;
+	u8 wlen;
+	u32 dataRead;
 
-			// Perform SW 3-wire programming by driver.
-			default:
-			{
-				data2Write = ((u32)(offset&0x1f)) << 27; // For Zebra E-cut. 2005.04.11, by rcnjko.
-				wlen = 6;
-				rlen = 12;
-				low2high = 0;
-				ZEBRA_RFSerialRead(dev, data2Write, wlen,&dataRead,rlen, low2high);
-			}
-			break;
-		}
-		break;
-	default:
-		dataRead = 0;
-		break;
-	}
+	data2Write = ((u32)(offset & 0x0f));
+	wlen = 16;
+	HwHSSIThreeWire(dev, (u8 *)(&data2Write), wlen, 1, 0);
+	dataRead = data2Write;
 
 	return dataRead;
 }
@@ -1043,15 +565,12 @@ ZEBRA_Config_85BASIC_HardCode(
 
 	// Page0 : reg0-reg15
 
-//	RF_WriteReg(dev, 0x00, 0x003f);			mdelay(1);//1
 	RF_WriteReg(dev, 0x00, 0x009f);      	mdelay(1);// 1
 
 	RF_WriteReg(dev, 0x01, 0x06e0);			mdelay(1);
 
-//	RF_WriteReg(dev, 0x02, 0x004c);			mdelay(1);//2
 	RF_WriteReg(dev, 0x02, 0x004d);			mdelay(1);// 2
 
-//	RF_WriteReg(dev, 0x03, 0x0000);			mdelay(1);//3
 	RF_WriteReg(dev, 0x03, 0x07f1);			mdelay(1);// 3
 
 	RF_WriteReg(dev, 0x04, 0x0975);			mdelay(1);
@@ -1080,8 +599,6 @@ ZEBRA_Config_85BASIC_HardCode(
 
 	RF_WriteReg(dev, 0x07, 0x01A0);			mdelay(1);
 // Don't write RF23/RF24 to make a difference between 87S C cut and D cut. asked by SD3 stevenl.
-//	RF_WriteReg(dev, 0x08, 0x0597);			mdelay(1);
-//	RF_WriteReg(dev, 0x09, 0x050a);			mdelay(1);
 	RF_WriteReg(dev, 0x0a, 0x0001);			mdelay(1);
 	RF_WriteReg(dev, 0x0b, 0x0418);			mdelay(1);
 
@@ -1097,7 +614,6 @@ ZEBRA_Config_85BASIC_HardCode(
 
 	RF_WriteReg(dev, 0x0f, 0x0acc);			mdelay(1);
 
-//	RF_WriteReg(dev, 0x00, 0x017f);			mdelay(1);//6
 	RF_WriteReg(dev, 0x00, 0x01d7);			mdelay(1);// 6
 
 	RF_WriteReg(dev, 0x03, 0x0e00);			mdelay(1);
@@ -1106,20 +622,14 @@ ZEBRA_Config_85BASIC_HardCode(
 	{
 		RF_WriteReg(dev, 0x01, i);                     mdelay(1);
 		RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
-		//DbgPrint("RF - 0x%x = 0x%x", i, ZEBRA_RF_RX_GAIN_TABLE[i]);
 	}
 
 	RF_WriteReg(dev, 0x05, 0x0203);			mdelay(1); 	/// 203, 343
-	//RF_WriteReg(dev, 0x06, 0x0300);			mdelay(1);	// 400
 	RF_WriteReg(dev, 0x06, 0x0200);			mdelay(1);	// 400
 
 	RF_WriteReg(dev, 0x00, 0x0137);			mdelay(1);	// switch to reg16-reg30, and HSSI disable 137
 	mdelay(10); 	// Deay 10 ms. //0xfd
 
-//	RF_WriteReg(dev, 0x0c, 0x09be);			mdelay(1);	// 7
-	//RF_WriteReg(dev, 0x0c, 0x07be);			mdelay(1);
-	//mdelay(10); 	// Deay 10 ms. //0xfd
-
 	RF_WriteReg(dev, 0x0d, 0x0008);			mdelay(1);	// Z4 synthesizer loop filter setting, 392
 	mdelay(10); 	// Deay 10 ms. //0xfd
 
@@ -1165,10 +675,8 @@ ZEBRA_Config_85BASIC_HardCode(
 		RF_WriteReg(dev, 0x0f, 0x0acc);			mdelay(1);
 	}
 //by amy 080312
-//	RF_WriteReg(dev, 0x0f, 0x0acc);			mdelay(1);  //-by amy 080312
 
 	RF_WriteReg(dev, 0x00, 0x00bf);			mdelay(1); // switch to reg0-reg15, and HSSI enable
-//	RF_WriteReg(dev, 0x0d, 0x009f);			mdelay(1); // Rx BB start calibration, 00c//-edward
 	RF_WriteReg(dev, 0x0d, 0x08df);			mdelay(1); // Rx BB start calibration, 00c//+edward
 	RF_WriteReg(dev, 0x02, 0x004d);			mdelay(1); // temperature meter off
 	RF_WriteReg(dev, 0x04, 0x0975);			mdelay(1); // Rx mode
@@ -1217,13 +725,10 @@ ZEBRA_Config_85BASIC_HardCode(
 	// AGC.txt
 	//=============================================================================
 
-//	PlatformIOWrite4Byte( dev, PhyAddr, 0x00001280);	// Annie, 2006-05-05
 	write_phy_ofdm(dev, 0x00, 0x12);
-	//WriteBBPortUchar(dev, 0x00001280);
 
 	for (i=0; i<128; i++)
 	{
-		//DbgPrint("AGC - [%x+1] = 0x%x\n", i, ZEBRA_AGC[i+1]);
 
 		data = ZEBRA_AGC[i+1];
 		data = data << 8;
@@ -1239,7 +744,6 @@ ZEBRA_Config_85BASIC_HardCode(
 	}
 
 	PlatformIOWrite4Byte( dev, PhyAddr, 0x00001080);	// Annie, 2006-05-05
-	//WriteBBPortUchar(dev, 0x00001080);
 
 	//=============================================================================
 
@@ -1252,8 +756,6 @@ ZEBRA_Config_85BASIC_HardCode(
 		u4bRegOffset=i;
 		u4bRegValue=OFDM_CONFIG[i];
 
-		//DbgPrint("OFDM - 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
-
 		WriteBBPortUchar(dev,
 						(0x00000080 |
 						(u4bRegOffset & 0x7f) |
@@ -1277,9 +779,6 @@ UpdateInitialGain(
 	)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	//unsigned char* IGTable;
-	//u8			DIG_CurrentInitialGain = 4;
-	//unsigned char u1Tmp;
 
 	//lzm add 080826
 	if(priv->eRFPowerState != eRfOn)
@@ -1291,81 +790,59 @@ UpdateInitialGain(
 		return;
 	}
 
-	switch(priv->rf_chip)
-	{
-	case RF_ZEBRA4:
-		// Dynamic set initial gain, follow 87B
-		switch(priv->InitialGain)
-		{
-			case 1: //m861dBm
-				//DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm \n");
-				write_phy_ofdm(dev, 0x17, 0x26);	mdelay(1);
-				write_phy_ofdm(dev, 0x24, 0x86);	mdelay(1);
-				write_phy_ofdm(dev, 0x05, 0xfa);	mdelay(1);
-				break;
-
-			case 2: //m862dBm
-				//DMESG("RTL8187 + 8225 Initial Gain State 2: -82 dBm \n");
-				write_phy_ofdm(dev, 0x17, 0x36);	mdelay(1);
-				write_phy_ofdm(dev, 0x24, 0x86);	mdelay(1);
-				write_phy_ofdm(dev, 0x05, 0xfa);	mdelay(1);
-				break;
-
-			case 3: //m863dBm
-				//DMESG("RTL8187 + 8225 Initial Gain State 3: -82 dBm \n");
-				write_phy_ofdm(dev, 0x17, 0x36);	mdelay(1);
-				write_phy_ofdm(dev, 0x24, 0x86);	mdelay(1);
-				write_phy_ofdm(dev, 0x05, 0xfb);	mdelay(1);
-				break;
-
-			case 4: //m864dBm
-				//DMESG("RTL8187 + 8225 Initial Gain State 4: -78 dBm \n");
-				write_phy_ofdm(dev, 0x17, 0x46);	mdelay(1);
-				write_phy_ofdm(dev, 0x24, 0x86);	mdelay(1);
-				write_phy_ofdm(dev, 0x05, 0xfb);	mdelay(1);
-				break;
+	switch (priv->InitialGain) {
+	case 1: /* m861dBm */
+		write_phy_ofdm(dev, 0x17, 0x26);	mdelay(1);
+		write_phy_ofdm(dev, 0x24, 0x86);	mdelay(1);
+		write_phy_ofdm(dev, 0x05, 0xfa);	mdelay(1);
+		break;
 
-			case 5: //m82dBm
-				//DMESG("RTL8187 + 8225 Initial Gain State 5: -74 dBm \n");
-				write_phy_ofdm(dev, 0x17, 0x46);	mdelay(1);
-				write_phy_ofdm(dev, 0x24, 0x96);	mdelay(1);
-				write_phy_ofdm(dev, 0x05, 0xfb);	mdelay(1);
-				break;
+	case 2: /* m862dBm */
+		write_phy_ofdm(dev, 0x17, 0x36);	mdelay(1);
+		write_phy_ofdm(dev, 0x24, 0x86);	mdelay(1);
+		write_phy_ofdm(dev, 0x05, 0xfa);	mdelay(1);
+		break;
 
-			case 6: //m78dBm
-				//DMESG ("RTL8187 + 8225 Initial Gain State 6: -70 dBm \n");
-				write_phy_ofdm(dev, 0x17, 0x56);	mdelay(1);
-				write_phy_ofdm(dev, 0x24, 0x96);	mdelay(1);
-				write_phy_ofdm(dev, 0x05, 0xfc);	mdelay(1);
-				break;
+	case 3: /* m863dBm */
+		write_phy_ofdm(dev, 0x17, 0x36);	mdelay(1);
+		write_phy_ofdm(dev, 0x24, 0x86);	mdelay(1);
+		write_phy_ofdm(dev, 0x05, 0xfb);	mdelay(1);
+		break;
 
-			case 7: //m74dBm
-				//DMESG("RTL8187 + 8225 Initial Gain State 7: -66 dBm \n");
-				write_phy_ofdm(dev, 0x17, 0x56);	mdelay(1);
-				write_phy_ofdm(dev, 0x24, 0xa6);	mdelay(1);
-				write_phy_ofdm(dev, 0x05, 0xfc);	mdelay(1);
-				break;
+	case 4: /* m864dBm */
+		write_phy_ofdm(dev, 0x17, 0x46);	mdelay(1);
+		write_phy_ofdm(dev, 0x24, 0x86);	mdelay(1);
+		write_phy_ofdm(dev, 0x05, 0xfb);	mdelay(1);
+		break;
 
-			case 8:
-				//DMESG("RTL8187 + 8225 Initial Gain State 8:\n");
-				write_phy_ofdm(dev, 0x17, 0x66);	mdelay(1);
-				write_phy_ofdm(dev, 0x24, 0xb6);	mdelay(1);
-				write_phy_ofdm(dev, 0x05, 0xfc);	mdelay(1);
-				break;
+	case 5: /* m82dBm */
+		write_phy_ofdm(dev, 0x17, 0x46);	mdelay(1);
+		write_phy_ofdm(dev, 0x24, 0x96);	mdelay(1);
+		write_phy_ofdm(dev, 0x05, 0xfb);	mdelay(1);
+		break;
 
+	case 6: /* m78dBm */
+		write_phy_ofdm(dev, 0x17, 0x56);	mdelay(1);
+		write_phy_ofdm(dev, 0x24, 0x96);	mdelay(1);
+		write_phy_ofdm(dev, 0x05, 0xfc);	mdelay(1);
+		break;
 
-			default:	//MP
-				//DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm (default)\n");
-				write_phy_ofdm(dev, 0x17, 0x26);	mdelay(1);
-				write_phy_ofdm(dev, 0x24, 0x86);	mdelay(1);
-				write_phy_ofdm(dev, 0x05, 0xfa);	mdelay(1);
-				break;
-		}
+	case 7: /* m74dBm */
+		write_phy_ofdm(dev, 0x17, 0x56);	mdelay(1);
+		write_phy_ofdm(dev, 0x24, 0xa6);	mdelay(1);
+		write_phy_ofdm(dev, 0x05, 0xfc);	mdelay(1);
 		break;
 
+	case 8:
+		write_phy_ofdm(dev, 0x17, 0x66);	mdelay(1);
+		write_phy_ofdm(dev, 0x24, 0xb6);	mdelay(1);
+		write_phy_ofdm(dev, 0x05, 0xfc);	mdelay(1);
+		break;
 
-	default:
-		DMESG("UpdateInitialGain(): unknown RFChipID: %#X\n", priv->rf_chip);
+	default:	/* MP */
+		write_phy_ofdm(dev, 0x17, 0x26);	mdelay(1);
+		write_phy_ofdm(dev, 0x24, 0x86);	mdelay(1);
+		write_phy_ofdm(dev, 0x05, 0xfa);	mdelay(1);
 		break;
 	}
 }
@@ -1379,13 +856,11 @@ InitTxPwrTracking87SE(
 	struct net_device *dev
 )
 {
-	//struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	u32	u4bRfReg;
 
 	u4bRfReg = RF_ReadReg(dev, 0x02);
 
 	// Enable Thermal meter indication.
-	//printk("InitTxPwrTracking87SE(): Enable thermal meter indication, Write RF[0x02] = %#x", u4bRfReg|PWR_METER_EN);
 	RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN);			mdelay(1);
 }
 
@@ -1397,21 +872,14 @@ PhyConfig8185(
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        write_nic_dword(dev, RCR, priv->ReceiveConfig);
 	   priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03;
-     	// RF config
-	switch(priv->rf_chip)
-	{
-	case RF_ZEBRA2:
-	case RF_ZEBRA4:
-		ZEBRA_Config_85BASIC_HardCode( dev);
-		break;
-	}
+	/*  RF config */
+	ZEBRA_Config_85BASIC_HardCode(dev);
 //{by amy 080312
 	// Set default initial gain state to 4, approved by SD3 DZ, by Bruce, 2007-06-06.
 	if(priv->bDigMechanism)
 	{
 		if(priv->InitialGain == 0)
 			priv->InitialGain = 4;
-		//printk("PhyConfig8185(): DIG is enabled, set default initial gain index to %d\n", priv->InitialGain);
 	}
 
 	//
@@ -1429,34 +897,17 @@ PhyConfig8185(
 	return;
 }
 
-
-
-
 void
 HwConfigureRTL8185(
 		struct net_device *dev
 		)
 {
 	//RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control.
-//	u8		bUNIVERSAL_CONTROL_RL = 1;
         u8              bUNIVERSAL_CONTROL_RL = 0;
-
 	u8		bUNIVERSAL_CONTROL_AGC = 1;
 	u8		bUNIVERSAL_CONTROL_ANT = 1;
 	u8		bAUTO_RATE_FALLBACK_CTL = 1;
 	u8		val8;
-	//struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	//struct ieee80211_device *ieee = priv->ieee80211;
-      	//if(IS_WIRELESS_MODE_A(dev) || IS_WIRELESS_MODE_G(dev))
-//{by amy 080312	if((ieee->mode == IEEE_G)||(ieee->mode == IEEE_A))
-//	{
-//		write_nic_word(dev, BRSR, 0xffff);
-//	}
-//	else
-//	{
-//		write_nic_word(dev, BRSR, 0x000f);
-//	}
-//by amy 080312}
         write_nic_word(dev, BRSR, 0x0fff);
 	// Retry limit
 	val8 = read_nic_byte(dev, CW_CONF);
@@ -1507,20 +958,11 @@ HwConfigureRTL8185(
 		val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1;
 
 		// <RJ_TODO_8185B> We shall set up the ARFR according to user's setting.
-		//write_nic_word(dev, ARFR, 0x0fff); // set 1M ~ 54M
-//by amy
-	        // Aadded by Roger, 2007.11.15.
 	        PlatformIOWrite2Byte(dev, ARFR, 0x0fff); //set 1M ~ 54Mbps.
-//by amy
-	}
-	else
-	{
 	}
 	write_nic_byte(dev, RATE_FALLBACK, val8);
 }
 
-
-
 static void
 MacConfig_85BASIC_HardCode(
 	struct net_device *dev)
@@ -1548,14 +990,11 @@ MacConfig_85BASIC_HardCode(
                 {
                     u4bRegOffset |= (u4bPageIndex << 8);
                 }
-                //DbgPrint("MAC - 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
 		write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
 	}
 	//============================================================================
 }
 
-
-
 static void
 MacConfig_85BASIC(
 	struct net_device *dev)
@@ -1578,8 +1017,6 @@ MacConfig_85BASIC(
 	PlatformIOWrite1Byte(dev, 0x1F8, 0x00);
 
 	// Asked for by SD3 CM Lin, 2006.06.27, by rcnjko.
-	//PlatformIOWrite4Byte(dev, RFTiming, 0x00004001);
-//by amy
 	// power save parameter based on "87SE power save parameters 20071127.doc", as follow.
 
 	//Enable DA10 TX power saving
@@ -1598,35 +1035,18 @@ MacConfig_85BASIC(
 	write_nic_word(dev, 0x378, 0x0560);
 	write_nic_word(dev, 0x37A, 0x0560);
 	write_nic_word(dev, 0x37C, 0x00EC);
-//	write_nic_word(dev, 0x37E, 0x00FE);//-edward
 	write_nic_word(dev, 0x37E, 0x00EC);//+edward
        write_nic_byte(dev, 0x24E,0x01);
-//by amy
-
 }
 
-
-
-
 u8
 GetSupportedWirelessMode8185(
 	struct net_device *dev
 )
 {
 	u8			btSupportedWirelessMode = 0;
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	switch(priv->rf_chip)
-	{
-	case RF_ZEBRA2:
-	case RF_ZEBRA4:
-		btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
-		break;
-	default:
-		btSupportedWirelessMode = WIRELESS_MODE_B;
-		break;
-	}
 
+	btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
 	return btSupportedWirelessMode;
 }
 
@@ -1641,7 +1061,6 @@ ActUpdateChannelAccessSetting(
 	struct ieee80211_device *ieee = priv->ieee80211;
 	AC_CODING	eACI;
 	AC_PARAM	AcParam;
-	//PSTA_QOS	pStaQos = Adapter->MgntInfo.pStaQos;
 	u8	bFollowLegacySetting = 0;
 	u8   u1bAIFS;
 
@@ -1663,40 +1082,14 @@ ActUpdateChannelAccessSetting(
 	ChnlAccessSetting->CWmaxIndex = 7; // 2006.06.02, by rcnjko.
 
 	write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer);
-	//Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_SLOT_TIME, &ChnlAccessSetting->SlotTimeTimer );	// Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29.
 	write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer);	// Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29.
 
 	u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer );
 
-	//write_nic_byte(dev, AC_VO_PARAM, u1bAIFS);
-	//write_nic_byte(dev, AC_VI_PARAM, u1bAIFS);
-	//write_nic_byte(dev, AC_BE_PARAM, u1bAIFS);
-	//write_nic_byte(dev, AC_BK_PARAM, u1bAIFS);
-
 	write_nic_byte(dev, EIFS, ChnlAccessSetting->EIFS_Timer);
 
 	write_nic_byte(dev, AckTimeOutReg, 0x5B); // <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
 
-#ifdef TODO
-	// <RJ_TODO_NOW_8185B> Update ECWmin/ECWmax, AIFS, TXOP Limit of each AC to the value defined by SPEC.
-	if( pStaQos->CurrentQosMode > QOS_DISABLE )
-	{ // QoS mode.
-		if(pStaQos->QBssWirelessMode == WirelessMode)
-		{
-			// Follow AC Parameters of the QBSS.
-			for(eACI = 0; eACI < AC_MAX; eACI++)
-			{
-				Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) );
-			}
-		}
-		else
-		{
-			// Follow Default WMM AC Parameters.
-			bFollowLegacySetting = 1;
-		}
-	}
-	else
-#endif
 	{ // Legacy 802.11.
 		bFollowLegacySetting = 1;
 
@@ -1719,14 +1112,12 @@ ActUpdateChannelAccessSetting(
 		AcParam.f.TXOPLimit = 0;
 
 		//lzm reserved 080826
-#if 1
 		// For turbo mode setting. port from 87B by Isaiah 2008-08-01
 		if( ieee->current_network.Turbo_Enable == 1 )
 			AcParam.f.TXOPLimit = 0x01FF;
 		// For 87SE with Intel 4965  Ad-Hoc mode have poor throughput (19MB)
 		if (ieee->iw_mode == IW_MODE_ADHOC)
 			AcParam.f.TXOPLimit = 0x0020;
-#endif
 
 		for(eACI = 0; eACI < AC_MAX; eACI++)
 		{
@@ -1770,18 +1161,13 @@ ActUpdateChannelAccessSetting(
 
 				// Cehck ACM bit.
 				// If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
-				//write_nic_byte(dev, ACM_CONTROL, pAcParam->f.AciAifsn);
 				{
 					PACI_AIFSN	pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn);
 					AC_CODING	eACI = pAciAifsn->f.ACI;
 
 					//modified Joseph
 					//for 8187B AsynIORead issue
-#ifdef TODO
-					u8	AcmCtrl = pHalData->AcmControl;
-#else
 					u8	AcmCtrl = 0;
-#endif
 					if( pAciAifsn->f.ACM )
 					{ // ACM bit is 1.
 						switch(eACI)
@@ -1823,19 +1209,10 @@ ActUpdateChannelAccessSetting(
 								break;
 						}
 					}
-
-					//printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
-
-#ifdef TO_DO
-					pHalData->AcmControl = AcmCtrl;
-#endif
-					//write_nic_byte(dev, ACM_CONTROL, AcmCtrl);
 					write_nic_byte(dev, ACM_CONTROL, 0);
 				}
 			}
 		}
-
-
 	}
 }
 
@@ -1847,7 +1224,6 @@ ActSetWirelessMode8185(
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	struct ieee80211_device *ieee = priv->ieee80211;
-	//PMGNT_INFO		pMgntInfo = &(Adapter->MgntInfo);
 	u8	btSupportedWirelessMode = GetSupportedWirelessMode8185(dev);
 
 	if( (btWirelessMode & btSupportedWirelessMode) == 0 )
@@ -1880,24 +1256,11 @@ ActSetWirelessMode8185(
 		}
 	}
 
-
-	// 2. Swtich band: RF or BB specific actions,
-	// for example, refresh tables in omc8255, or change initial gain if necessary.
-	switch(priv->rf_chip)
-	{
-	case RF_ZEBRA2:
-	case RF_ZEBRA4:
-		{
-			// Nothing to do for Zebra to switch band.
-			// Update current wireless mode if we swtich to specified band successfully.
-			ieee->mode = (WIRELESS_MODE)btWirelessMode;
-		}
-		break;
-
-	default:
-		DMESGW("ActSetWirelessMode8185(): unsupported RF: 0x%X !!!\n", priv->rf_chip);
-		break;
-	}
+	/* 2. Swtich band: RF or BB specific actions,
+	 * for example, refresh tables in omc8255, or change initial gain if necessary.
+	 * Nothing to do for Zebra to switch band.
+	 * Update current wireless mode if we swtich to specified band successfully. */
+	ieee->mode = (WIRELESS_MODE)btWirelessMode;
 
 	// 3. Change related setting.
 	if( ieee->mode == WIRELESS_MODE_A ){
@@ -1909,7 +1272,6 @@ ActSetWirelessMode8185(
 	else if( ieee->mode == WIRELESS_MODE_G ){
 		DMESG("WIRELESS_MODE_G\n");
 	}
-
 	ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting);
 }
 
@@ -1927,11 +1289,7 @@ DrvIFIndicateDisassociation(
 	u16			reason
 	)
 {
-	//printk("==> DrvIFIndicateDisassociation()\n");
-
 	// nothing is needed after disassociation request.
-
-	//printk("<== DrvIFIndicateDisassociation()\n");
 }
 void
 MgntDisconnectIBSS(
@@ -1941,11 +1299,7 @@ MgntDisconnectIBSS(
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	u8			i;
 
-	//printk("XXXXXXXXXX MgntDisconnect IBSS\n");
-
 	DrvIFIndicateDisassociation(dev, unspec_reason);
-
-//	PlatformZeroMemory( pMgntInfo->Bssid, 6 );
 	for(i=0;i<6;i++)  priv->ieee80211->current_network.bssid[i] = 0x55;
 
 	priv->ieee80211->state = IEEE80211_NOLINK;
@@ -1957,16 +1311,10 @@ MgntDisconnectIBSS(
 	// Because Bcn DMA isn't complete, mgnt queue would stuck until Bcn packet send.
 
 	// Disable Beacon Queue Own bit, suggested by jong
-//	Adapter->HalFunc.SetTxDescOWNHandler(Adapter, BEACON_QUEUE, 0, 0);
 	ieee80211_stop_send_beacons(priv->ieee80211);
 
 	priv->ieee80211->link_change(dev);
 	notify_wx_assoc_event(priv->ieee80211);
-
-	// Stop SW Beacon.Use hw beacon so do not need to do so.by amy
-
-//		MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE );
-
 }
 void
 MlmeDisassociateRequest(
@@ -1986,14 +1334,8 @@ MlmeDisassociateRequest(
 		DrvIFIndicateDisassociation(dev, unspec_reason);
 
 
-	//	pMgntInfo->AsocTimestamp = 0;
 		for(i=0;i<6;i++)  priv->ieee80211->current_network.bssid[i] = 0x22;
-//		pMgntInfo->mBrates.Length = 0;
-//		Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_BASIC_RATE, (pu1Byte)(&pMgntInfo->mBrates) );
-
 		ieee80211_disassociate(priv->ieee80211);
-
-
 	}
 
 }
@@ -2011,23 +1353,12 @@ MgntDisconnectAP(
 // I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
 //
 //	//2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success
-//	SecClearAllKeys(Adapter);
 
 	// In WPA WPA2 need to Clear all key ... because new key will set after new handshaking.
-#ifdef TODO
-	if(   pMgntInfo->SecurityInfo.AuthMode > RT_802_11AuthModeAutoSwitch ||
-		(pMgntInfo->bAPSuportCCKM && pMgntInfo->bCCX8021xenable) )  // In CCKM mode will Clear key
-	{
-		SecClearAllKeys(Adapter);
-		RT_TRACE(COMP_SEC, DBG_LOUD,("======>CCKM clear key..."))
-	}
-#endif
 	// 2004.10.11, by rcnjko.
-	//MlmeDisassociateRequest( Adapter, pMgntInfo->Bssid, disas_lv_ss );
 	MlmeDisassociateRequest( dev, priv->ieee80211->current_network.bssid, asRsn );
 
 	priv->ieee80211->state = IEEE80211_NOLINK;
-//	pMgntInfo->AsocTimestamp = 0;
 }
 bool
 MgntDisconnect(
@@ -2039,20 +1370,7 @@ MgntDisconnect(
 	//
 	// Schedule an workitem to wake up for ps mode, 070109, by rcnjko.
 	//
-#ifdef TODO
-	if(pMgntInfo->mPss != eAwake)
-	{
-		//
-		// Using AwkaeTimer to prevent mismatch ps state.
-		// In the timer the state will be changed according to the RF is being awoke or not. By Bruce, 2007-10-31.
-		//
-		// PlatformScheduleWorkItem( &(pMgntInfo->AwakeWorkItem) );
-		PlatformSetTimer( Adapter, &(pMgntInfo->AwakeTimer), 0 );
-	}
-#endif
 
-	// Indication of disassociation event.
-	//DrvIFIndicateDisassociation(Adapter, asRsn);
 	if(IS_DOT11D_ENABLE(priv->ieee80211))
 		Dot11d_Reset(priv->ieee80211);
 	// In adhoc mode, update beacon frame.
@@ -2060,8 +1378,6 @@ MgntDisconnect(
 	{
 		if( priv->ieee80211->iw_mode == IW_MODE_ADHOC )
 		{
-//			RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> MgntDisconnectIBSS\n"));
-			//printk("MgntDisconnect() ===> MgntDisconnectIBSS\n");
 			MgntDisconnectIBSS(dev);
 		}
 		if( priv->ieee80211->iw_mode == IW_MODE_INFRA )
@@ -2071,17 +1387,10 @@ MgntDisconnect(
 			// e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is
 			// used to handle disassociation related things to AP, e.g. send Disassoc
 			// frame to AP.  2005.01.27, by rcnjko.
-//			SecClearAllKeys(Adapter);
-
-//			RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> MgntDisconnectAP\n"));
-			//printk("MgntDisconnect() ===> MgntDisconnectAP\n");
 			MgntDisconnectAP(dev, asRsn);
 		}
-
 		// Inidicate Disconnect, 2005.02.23, by rcnjko.
-//		MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE);
 	}
-
 	return true;
 }
 //
@@ -2101,25 +1410,12 @@ SetRFPowerState(
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	bool			bResult = false;
 
-//	printk("---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState);
 	if(eRFPowerState == priv->eRFPowerState)
 	{
-//		printk("<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState);
 		return bResult;
 	}
 
-	switch(priv->rf_chip)
-	{
-		case RF_ZEBRA2:
-		case RF_ZEBRA4:
-			 bResult = SetZebraRFPowerState8185(dev, eRFPowerState);
-			break;
-
-		default:
-			printk("SetRFPowerState8185(): unknown RFChipID: 0x%X!!!\n", priv->rf_chip);
-			break;;
-}
-//	printk("<--------- SetRFPowerState(): bResult(%d)\n", bResult);
+	 bResult = SetZebraRFPowerState8185(dev, eRFPowerState);
 
 	return bResult;
 }
@@ -2149,33 +1445,25 @@ MgntActSet_RF_State(
 	RT_RF_POWER_STATE 	rtState;
 	u16				RFWaitCounter = 0;
 	unsigned long flag;
-//	 printk("===>MgntActSet_RF_State(): StateToSet(%d), ChangeSource(0x%x)\n",StateToSet, ChangeSource);
 	//
 	// Prevent the race condition of RF state change. By Bruce, 2007-11-28.
 	// Only one thread can change the RF state at one time, and others should wait to be executed.
 	//
-#if 1
 	while(true)
 	{
-//		down(&priv->rf_state);
 		spin_lock_irqsave(&priv->rf_ps_lock,flag);
 		if(priv->RFChangeInProgress)
 		{
-//			printk("====================>haha111111111\n");
-//			up(&priv->rf_state);
-//			RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet));
 			spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
 			// Set RF after the previous action is done.
 			while(priv->RFChangeInProgress)
 			{
 				RFWaitCounter ++;
-//				RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter));
 				udelay(1000); // 1 ms
 
 				// Wait too long, return FALSE to avoid to be stuck here.
 				if(RFWaitCounter > 1000) // 1sec
 				{
-//					RT_ASSERT(FALSE, ("MgntActSet_RF_State(): Wait too logn to set RF\n"));
 					printk("MgntActSet_RF_State(): Wait too long to set RF\n");
 					// TODO: Reset RF state?
 					return false;
@@ -2184,17 +1472,13 @@ MgntActSet_RF_State(
 		}
 		else
 		{
-//			printk("========================>haha2\n");
 			priv->RFChangeInProgress = true;
-//			up(&priv->rf_state);
 			spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
 			break;
 		}
 	}
-#endif
 	rtState = priv->eRFPowerState;
 
-
 	switch(StateToSet)
 	{
 	case eRfOn:
@@ -2215,7 +1499,6 @@ MgntActSet_RF_State(
 			}
 		}
 		else
-//			RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", pMgntInfo->RfOffReason, ChangeSource));
 			;
 		break;
 
@@ -2232,38 +1515,26 @@ MgntActSet_RF_State(
 				//
 				// Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(),
 				// because we do NOT need to set ssid to dummy ones.
-				// Revised by Roger, 2007.12.04.
 				//
 				MgntDisconnect( dev, disas_lv_ss );
 
 				// Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI.
-				// 2007.05.28, by shien chang.
-//				PlatformZeroMemory( pMgntInfo->bssDesc, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
-//				pMgntInfo->NumBssDesc = 0;
-//				PlatformZeroMemory( pMgntInfo->bssDesc4Query, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
-//				pMgntInfo->NumBssDesc4Query = 0;
 			}
 
-
-
 		priv->RfOffReason |= ChangeSource;
 		bActionAllowed = true;
 		break;
-
 	case eRfSleep:
 		priv->RfOffReason |= ChangeSource;
 		bActionAllowed = true;
 		break;
-
 	default:
 		break;
 	}
 
 	if(bActionAllowed)
 	{
-//		RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, pMgntInfo->RfOffReason));
                 // Config HW to the specified mode.
-//		printk("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->RfOffReason);
 		SetRFPowerState(dev, StateToSet);
 
 		// Turn on RF.
@@ -2273,7 +1544,6 @@ MgntActSet_RF_State(
 			if(bConnectBySSID)
 			{
 			// by amy not supported
-//				MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE );
 			}
 		}
 		// Turn off RF.
@@ -2282,18 +1552,11 @@ MgntActSet_RF_State(
 			HalDisableRx8185Dummy(dev);
 		}
 	}
-	else
-	{
-	//	printk("MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->RfOffReason);
-	}
 
 	// Release RF spinlock
-//	down(&priv->rf_state);
 	spin_lock_irqsave(&priv->rf_ps_lock,flag);
 	priv->RFChangeInProgress = false;
-//	up(&priv->rf_state);
 	spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
-//	printk("<===MgntActSet_RF_State()\n");
 	return bActionAllowed;
 }
 void
@@ -2302,15 +1565,12 @@ InactivePowerSave(
 	)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	//u8 index = 0;
-
 	//
 	// This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
 	// is really scheduled.
 	// The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
 	// previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
 	// blocks the IPS procedure of switching RF.
-	// By Bruce, 2007-12-25.
 	//
 	priv->bSwRfProcessing = true;
 
@@ -2326,7 +1586,6 @@ InactivePowerSave(
 //
 //	Description:
 //		Enter the inactive power save mode. RF will be off
-//	2007.08.17, by shien chang.
 //
 void
 IPSEnter(
@@ -2335,13 +1594,11 @@ IPSEnter(
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	RT_RF_POWER_STATE rtState;
-	//printk("==============================>enter IPS\n");
 	if (priv->bInactivePs)
 	{
 		rtState = priv->eRFPowerState;
 
 		//
-		// Added by Bruce, 2007-12-25.
 		// Do not enter IPS in the following conditions:
 		// (1) RF is already OFF or Sleep
 		// (2) bSwRfProcessing (indicates the IPS is still under going)
@@ -2352,12 +1609,10 @@ IPSEnter(
 		if (rtState == eRfOn && !priv->bSwRfProcessing
 			&& (priv->ieee80211->state != IEEE80211_LINKED ))
 		{
-	//		printk("IPSEnter(): Turn off RF.\n");
 			priv->eInactivePowerState = eRfOff;
 			InactivePowerSave(dev);
 		}
 	}
-//	printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
 }
 void
 IPSLeave(
@@ -2366,20 +1621,17 @@ IPSLeave(
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	RT_RF_POWER_STATE rtState;
-	//printk("===================================>leave IPS\n");
 	if (priv->bInactivePs)
 	{
 		rtState = priv->eRFPowerState;
 		if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS)
 		{
-//			printk("IPSLeave(): Turn on RF.\n");
 			priv->eInactivePowerState = eRfOn;
 			InactivePowerSave(dev);
 		}
 	}
-//	printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
 }
-//by amy for power save
+
 void rtl8185b_adapter_start(struct net_device *dev)
 {
       struct r8180_priv *priv = ieee80211_priv(dev);
@@ -2388,75 +1640,45 @@ void rtl8185b_adapter_start(struct net_d
 	u8 SupportedWirelessMode;
 	u8			InitWirelessMode;
 	u8			bInvalidWirelessMode = 0;
-	//int i;
 	u8 tmpu8;
-    	//u8 u1tmp,u2tmp;
 	u8 btCR9346;
 	u8 TmpU1b;
 	u8 btPSR;
 
-	//rtl8180_rtx_disable(dev);
-//{by amy 080312
 	write_nic_byte(dev,0x24e, (BIT5|BIT6|BIT0));
-//by amy 080312}
 	rtl8180_reset(dev);
 
 	priv->dma_poll_mask = 0;
 	priv->dma_poll_stop_mask = 0;
 
-	//rtl8180_beacon_tx_disable(dev);
-
 	HwConfigureRTL8185(dev);
-
 	write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
 	write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
-
 	write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3);	// default network type to 'No	Link'
-
-	//write_nic_byte(dev, BRSR, 0x0);		// Set BRSR= 1M
-
 	write_nic_word(dev, BcnItv, 100);
 	write_nic_word(dev, AtimWnd, 2);
-
-	//PlatformEFIOWrite2Byte(dev, FEMR, 0xFFFF);
 	PlatformIOWrite2Byte(dev, FEMR, 0xFFFF);
-
 	write_nic_byte(dev, WPA_CONFIG, 0);
-
 	MacConfig_85BASIC(dev);
-
 	// Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko.
 	// BT_DEMO_BOARD type
 	PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a);
-//by amy
-//#ifdef CONFIG_RTL818X_S
-		// for jong required
-//	PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x9a56);
-//#endif
-//by amy
-	//BT_QA_BOARD
-	//PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x9a56);
 
 	//-----------------------------------------------------------------------------
 	// Set up PHY related.
 	//-----------------------------------------------------------------------------
 	// Enable Config3.PARAM_En to revise AnaaParm.
 	write_nic_byte(dev, CR9346, 0xc0);	// enable config register write
-//by amy
 	tmpu8 = read_nic_byte(dev, CONFIG3);
 	write_nic_byte(dev, CONFIG3, (tmpu8 |CONFIG3_PARM_En) );
-//by amy
 	// Turn on Analog power.
 	// Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko.
 	write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
 	write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
-//by amy
 	write_nic_word(dev, ANAPARAM3, 0x0010);
-//by amy
 
 	write_nic_byte(dev, CONFIG3, tmpu8);
 	write_nic_byte(dev, CR9346, 0x00);
-//{by amy 080312 for led
 	// enable EEM0 and EEM1 in 9346CR
 	btCR9346 = read_nic_byte(dev, CR9346);
 	write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
@@ -2474,7 +1696,6 @@ void rtl8185b_adapter_start(struct net_d
 	// B-cut RF Radio on/off  5e[3]=0
 	btPSR = read_nic_byte(dev, PSR);
 	write_nic_byte(dev, PSR, (btPSR | BIT3));
-//by amy 080312 for led}
 	// setup initial timing for RFE.
 	write_nic_word(dev, RFPinsOutput, 0x0480);
 	SetOutputEnableOfRfPins(dev);
@@ -2537,55 +1758,19 @@ void rtl8185b_adapter_start(struct net_d
 		InitWirelessMode = ieee->mode;
 	}
 //by amy for power save
-//	printk("initialize ENABLE_IPS\n");
 	priv->eRFPowerState = eRfOff;
 	priv->RfOffReason = 0;
 	{
-	//	u32 tmp2;
-	//	u32 tmp = jiffies;
 		MgntActSet_RF_State(dev, eRfOn, 0);
-	//	tmp2 = jiffies;
-	//	printk("rf on cost jiffies:%lx\n", (tmp2-tmp)*1000/HZ);
 	}
-//	DrvIFIndicateCurrentPhyStatus(priv);
 		//
 		// If inactive power mode is enabled, disable rf while in disconnected state.
-		// 2007.07.16, by shien chang.
 		//
 	if (priv->bInactivePs)
 	{
-	//	u32 tmp2;
-	//	u32 tmp = jiffies;
 		MgntActSet_RF_State(dev,eRfOff, RF_CHANGE_BY_IPS);
-	//	tmp2 = jiffies;
-	//	printk("rf off cost jiffies:%lx\n", (tmp2-tmp)*1000/HZ);
-
 	}
-//	IPSEnter(dev);
 //by amy for power save
-#ifdef TODO
-	// Turn off RF if necessary. 2005.08.23, by rcnjko.
-	// We shall turn off RF after setting CMDR, otherwise,
-	// RF will be turnned on after we enable MAC Tx/Rx.
-	if(Adapter->MgntInfo.RegRfOff == TRUE)
-	{
-		SetRFPowerState8185(Adapter, RF_OFF);
-	}
-	else
-	{
-		SetRFPowerState8185(Adapter, RF_ON);
-	}
-#endif
-
-/*   //these is equal with above TODO.
-	write_nic_byte(dev, CR9346, 0xc0);	// enable config register write
-	write_nic_byte(dev, CONFIG3, read_nic_byte(dev, CONFIG3) | CONFIG3_PARM_En);
-	RF_WriteReg(dev, 0x4, 0x9FF);
-	write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
-	write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
-	write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)&(~CONFIG3_PARM_En)));
-	write_nic_byte(dev, CR9346, 0x00);
-*/
 
 	ActSetWirelessMode8185(dev, (u8)(InitWirelessMode));
 
@@ -2594,14 +1779,11 @@ void rtl8185b_adapter_start(struct net_d
 	rtl8185b_irq_enable(dev);
 
 	netif_start_queue(dev);
-
  }
 
-
 void rtl8185b_rx_enable(struct net_device *dev)
 {
 	u8 cmd;
-	//u32 rxconf;
 	/* for now we accept data, management & ctl frame*/
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
@@ -2613,11 +1795,6 @@ void rtl8185b_rx_enable(struct net_devic
 		priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP;
 	}
 
-	/*if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
-		rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
-		rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
-	}*/
-
 	if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
 		priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF | RCR_APWRMGT | RCR_AICV;
 	}
@@ -2629,9 +1806,6 @@ void rtl8185b_rx_enable(struct net_devic
 
 	fix_rx_fifo(dev);
 
-#ifdef DEBUG_RX
-	DMESG("rxconf: %x %x",priv->ReceiveConfig ,read_nic_dword(dev,RCR));
-#endif
 	cmd=read_nic_byte(dev,CMD);
 	write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
 
@@ -2640,9 +1814,7 @@ void rtl8185b_rx_enable(struct net_devic
 void rtl8185b_tx_enable(struct net_device *dev)
 {
 	u8 cmd;
-	//u8 tx_agc_ctl;
 	u8 byte;
-	//u32 txconf;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
 	write_nic_dword(dev, TCR, priv->TransmitConfig);
@@ -2652,21 +1824,7 @@ void rtl8185b_tx_enable(struct net_devic
 
 	fix_tx_fifo(dev);
 
-#ifdef DEBUG_TX
-	DMESG("txconf: %x %x",priv->TransmitConfig,read_nic_dword(dev,TCR));
-#endif
-
 	cmd=read_nic_byte(dev,CMD);
 	write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
-
-	//write_nic_dword(dev,TX_CONF,txconf);
-
-
-/*
-	rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
-	write_nic_byte(dev, TX_DMA_POLLING, priv->dma_poll_mask);
-	rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
-	*/
 }
 
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/TODO linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/TODO
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8187se/TODO	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8187se/TODO	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,6 @@ TODO:
 - switch to use shared "librtl" instead of private ieee80211 stack
 - switch to use LIB80211
 - switch to use MAC80211
-- switch to use EEPROM_93CX6
 - use kernel coding style
 - checkpatch.pl fixes
 - sparse fixes
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/dot11d.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/dot11d.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/dot11d.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/dot11d.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,102 +1,96 @@
-#ifndef __INC_DOT11D_H
-#define __INC_DOT11D_H
+#ifndef INC_DOT11D_H
+#define INC_DOT11D_H
 
 #ifdef ENABLE_DOT11D
 #include "ieee80211.h"
 
-//#define ENABLE_DOT11D
-
-//#define DOT11D_MAX_CHNL_NUM 83
-
 typedef struct _CHNL_TXPOWER_TRIPLE {
 	u8 FirstChnl;
 	u8  NumChnls;
 	u8  MaxTxPowerInDbm;
-}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
+} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
 
 typedef enum _DOT11D_STATE {
 	DOT11D_STATE_NONE = 0,
 	DOT11D_STATE_LEARNED,
 	DOT11D_STATE_DONE,
-}DOT11D_STATE;
+} DOT11D_STATE;
 
-typedef struct _RT_DOT11D_INFO {
-	//DECLARE_RT_OBJECT(RT_DOT11D_INFO);
+/**
+ * struct _RT_DOT11D_INFO
+ * @CountryIeLen: value greater than 0 if @CountryIeBuf contains
+ * 	          valid country information element.
+ * @chanell_map: holds channel values
+ *		0 - invalid,
+ *		1 - valid (active scan),
+ *	 	2 - valid (passive scan)
+ * @CountryIeSrcAddr - Source AP of the country IE
+ */
 
-	bool bEnabled; // dot11MultiDomainCapabilityEnabled
+typedef struct _RT_DOT11D_INFO {
+	bool bEnabled;
 
-	u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
-	u8  CountryIeBuf[MAX_IE_LEN];
-	u8  CountryIeSrcAddr[6]; // Source AP of the country IE.
-	u8  CountryIeWatchdog;
+	u16 CountryIeLen;
+	u8 CountryIeBuf[MAX_IE_LEN];
+	u8 CountryIeSrcAddr[6];
+	u8 CountryIeWatchdog;
 
-	u8  channel_map[MAX_CHANNEL_NUMBER+1];  //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
-	//u8  ChnlListLen; // #Bytes valid in ChnlList[].
-	//u8  ChnlList[DOT11D_MAX_CHNL_NUM];
-	u8  MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
+	u8 channel_map[MAX_CHANNEL_NUMBER+1];
+	u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
 
 	DOT11D_STATE State;
-}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
-#define eqMacAddr(a,b)		( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
-#define cpMacAddr(des,src)	      ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
-#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
+} RT_DOT11D_INFO, *PRT_DOT11D_INFO;
+
+#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == \
+			(b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && \
+			(a)[5] == (b)[5]) ? 1 : 0)
+
+#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], \
+			(des)[2] = (src)[2], (des)[3] = (src)[3], \
+			(des)[4] = (src)[4], (des)[5] = (src)[5])
+
+#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO) \
+			((__pIeeeDev)->pDot11dInfo))
 
 #define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
-#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
+#define IS_COUNTRY_IE_VALID(__pIeeeDev) \
+			(GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
 
-#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) \
+		eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+
+#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) \
+		cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
 
 #define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
-	(((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
-	FALSE : \
-	(!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
+	(((__Ie).Length == 0 || (__Ie).Length != \
+	GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? FALSE : \
+	(!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, \
+	(__Ie).Octet, (__Ie).Length)))
 
 #define CIE_WATCHDOG_TH 1
 #define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
 #define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
 #define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
 
-#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
+#define IS_DOT11D_STATE_DONE(__pIeeeDev) \
+		(GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
 
 
-void
-Dot11d_Init(
-	struct ieee80211_device *dev
-	);
+void Dot11d_Init(struct ieee80211_device *dev);
 
-void
-Dot11d_Reset(
-	struct ieee80211_device *dev
-	);
+void Dot11d_Reset(struct ieee80211_device *dev);
 
-void
-Dot11d_UpdateCountryIe(
-	struct ieee80211_device *dev,
-	u8 *		pTaddr,
-	u16	CoutryIeLen,
-	u8 * pCoutryIe
-	);
+void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
+		u16 CoutryIeLen, u8 *pCoutryIe);
 
-u8
-DOT11D_GetMaxTxPwrInDbm(
-	struct ieee80211_device *dev,
-	u8 Channel
-	);
+u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 channel);
 
-void
-DOT11D_ScanComplete(
-	struct ieee80211_device * dev
-	);
+void DOT11D_ScanComplete(struct ieee80211_device *dev);
 
-int IsLegalChannel(
-	struct ieee80211_device * dev,
-	u8 channel
-);
+int IsLegalChannel(struct ieee80211_device *dev, u8 channel);
 
-int ToLegalChannel(
-	struct ieee80211_device * dev,
-	u8 channel
-);
-#endif //ENABLE_DOT11D
-#endif // #ifndef __INC_DOT11D_H
+int ToLegalChannel(struct ieee80211_device *dev, u8 channel);
+
+#endif /* ENABLE_DOT11D */
+#endif /* INC_DOT11D_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c	2010-05-16 17:17:36.000000000 -0400
@@ -225,7 +225,7 @@ out:
 }
 
 
-void __exit ieee80211_crypto_deinit(void)
+void ieee80211_crypto_deinit(void)
 {
 	struct list_head *ptr, *n;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c	2010-05-16 17:17:36.000000000 -0400
@@ -331,7 +331,7 @@ static int ieee80211_ccmp_decrypt(struct
 	if (!(keyidx & (1 << 5))) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "CCMP: received packet without ExtIV"
-			       " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+			       " flag from %pM\n", hdr->addr2);
 		}
 		key->dot11RSNAStatsCCMPFormatErrors++;
 		return -2;
@@ -344,9 +344,9 @@ static int ieee80211_ccmp_decrypt(struct
 	}
 	if (!key->key_set) {
 		if (net_ratelimit()) {
-			printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
+			printk(KERN_DEBUG "CCMP: received packet from %pM"
 			       " with keyid=%d that does not have a configured"
-			       " key\n", MAC_ARG(hdr->addr2), keyidx);
+			       " key\n", hdr->addr2, keyidx);
 		}
 		return -3;
 	}
@@ -361,11 +361,9 @@ static int ieee80211_ccmp_decrypt(struct
 
 	if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
 		if (net_ratelimit()) {
-			printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
-			       " previous PN %02x%02x%02x%02x%02x%02x "
-			       "received PN %02x%02x%02x%02x%02x%02x\n",
-			       MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
-			       MAC_ARG(pn));
+			//printk(KERN_DEBUG "CCMP: replay detected: STA=%pM"
+			//       " previous PN %pm received PN %pm\n",
+			//       hdr->addr2, key->rx_pn, pn);
 		}
 		key->dot11RSNAStatsCCMPReplays++;
 		return -4;
@@ -402,7 +400,7 @@ static int ieee80211_ccmp_decrypt(struct
 		if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
 			if (net_ratelimit()) {
 				printk(KERN_DEBUG "CCMP: decrypt failed: STA="
-				MAC_FMT "\n", MAC_ARG(hdr->addr2));
+				"%pM\n", hdr->addr2);
 			}
 			key->dot11RSNAStatsCCMPDecryptErrors++;
 			return -5;
@@ -477,12 +475,19 @@ static int ieee80211_ccmp_get_key(void *
 static char * ieee80211_ccmp_print_stats(char *p, void *priv)
 {
 	struct ieee80211_ccmp_data *ccmp = priv;
-	p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
-		     "tx_pn=%02x%02x%02x%02x%02x%02x "
-		     "rx_pn=%02x%02x%02x%02x%02x%02x "
-		     "format_errors=%d replays=%d decrypt_errors=%d\n",
-		     ccmp->key_idx, ccmp->key_set,
-		     MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
+	int i;
+
+	p += sprintf(p, "key[%d] alg=CCMP key_set=%d tx_pn=",
+		     ccmp->key_idx, ccmp->key_set);
+
+	for (i = 0; i < ARRAY_SIZE(ccmp->tx_pn); i++)
+		p += sprintf(p, "%02x", ccmp->tx_pn[i]);
+
+	sprintf(p, " rx_pn=");
+	for (i = 0; i < ARRAY_SIZE(ccmp->rx_pn); i++)
+		p += sprintf(p, "%02x", ccmp->tx_pn[i]);
+
+	p += sprintf(p, " format_errors=%d replays=%d decrypt_errors=%d\n",
 		     ccmp->dot11RSNAStatsCCMPFormatErrors,
 		     ccmp->dot11RSNAStatsCCMPReplays,
 		     ccmp->dot11RSNAStatsCCMPDecryptErrors);
@@ -519,7 +524,7 @@ int __init ieee80211_crypto_ccmp_init(vo
 }
 
 
-void __exit ieee80211_crypto_ccmp_exit(void)
+void ieee80211_crypto_ccmp_exit(void)
 {
 	ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c	2010-05-16 17:17:36.000000000 -0400
@@ -520,7 +520,7 @@ static int ieee80211_tkip_decrypt(struct
 	if (!(keyidx & (1 << 5))) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "TKIP: received packet without ExtIV"
-			       " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+			       " flag from %pM\n", hdr->addr2);
 		}
 		return -2;
 	}
@@ -532,9 +532,9 @@ static int ieee80211_tkip_decrypt(struct
 	}
 	if (!tkey->key_set) {
 		if (net_ratelimit()) {
-			printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
+			printk(KERN_DEBUG "TKIP: received packet from %pM"
 			       " with keyid=%d that does not have a configured"
-			       " key\n", MAC_ARG(hdr->addr2), keyidx);
+			       " key\n", hdr->addr2, keyidx);
 		}
 		return -3;
 	}
@@ -547,9 +547,9 @@ static int ieee80211_tkip_decrypt(struct
 		if (iv32 < tkey->rx_iv32 ||
 		(iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
 			if (net_ratelimit()) {
-				printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
+				printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
 				" previous TSC %08x%04x received TSC "
-				"%08x%04x\n", MAC_ARG(hdr->addr2),
+				"%08x%04x\n", hdr->addr2,
 				tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
 			}
 			tkey->dot11RSNAStatsTKIPReplays++;
@@ -582,8 +582,8 @@ static int ieee80211_tkip_decrypt(struct
 		if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
 			if (net_ratelimit()) {
 				printk(KERN_DEBUG ": TKIP: failed to decrypt "
-						"received packet from " MAC_FMT "\n",
-						MAC_ARG(hdr->addr2));
+						"received packet from %pM\n",
+						hdr->addr2);
 			}
 			return -7;
 		}
@@ -606,8 +606,9 @@ static int ieee80211_tkip_decrypt(struct
 				tkey->rx_phase1_done = 0;
 			}
 			if (net_ratelimit()) {
-				printk(KERN_DEBUG "TKIP: ICV error detected: STA="
-				MAC_FMT "\n", MAC_ARG(hdr->addr2));
+				printk(KERN_DEBUG
+				       "TKIP: ICV error detected: STA=%pM\n",
+				       hdr->addr2);
 			}
 			tkey->dot11RSNAStatsTKIPICVErrors++;
 			return -5;
@@ -816,8 +817,8 @@ static void ieee80211_michael_mic_failur
 
 	/* TODO: needed parameters: count, keyid, key type, TSC */
 	sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
-		MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
-		MAC_ARG(hdr->addr2));
+		"%pM)", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
+		hdr->addr2);
 	memset(&wrqu, 0, sizeof(wrqu));
 	wrqu.data.length = strlen(buf);
 	wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
@@ -862,8 +863,8 @@ static int ieee80211_michael_mic_verify(
 		struct ieee80211_hdr_4addr *hdr;
 		hdr = (struct ieee80211_hdr_4addr *) skb->data;
 		printk(KERN_DEBUG "%s: Michael MIC verification failed for "
-		       "MSDU from " MAC_FMT " keyidx=%d\n",
-		       skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
+		       "MSDU from %pM keyidx=%d\n",
+		       skb->dev ? skb->dev->name : "N/A", hdr->addr2,
 		       keyidx);
 		if (skb->dev)
 			ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
@@ -1011,7 +1012,7 @@ int __init ieee80211_crypto_tkip_init(vo
 }
 
 
-void __exit ieee80211_crypto_tkip_exit(void)
+void ieee80211_crypto_tkip_exit(void)
 {
 	ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211.h	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #endif
 #include <linux/timer.h>
 #include <linux/sched.h>
+#include <linux/semaphore.h>
 
 #include <linux/delay.h>
 #include <linux/wireless.h>
@@ -180,6 +181,8 @@ typedef struct cb_desc {
         u8 DrvAggrNum;
 	u16 pkt_size;
         u8 reserved12;
+
+	u8 bdhcp;
 }cb_desc, *pcb_desc;
 
 /*--------------------------Define -------------------------------------------*/
@@ -615,9 +618,6 @@ do { if (ieee80211_debug_level & (level)
 
 /* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
 
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
-
 /*
  * To use the debug system;
  *
@@ -743,6 +743,8 @@ 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_FC_MORE_DATA(fc) ((fc) & IEEE80211_FCTL_MOREDATA)
+
 
 #define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE)
 #define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
@@ -1055,7 +1057,7 @@ struct ieee80211_device;
 #define SEC_ALG_NONE            0
 #define SEC_ALG_WEP             1
 #define SEC_ALG_TKIP            2
-#define SEC_ALG_CCMP            3
+#define SEC_ALG_CCMP            4
 
 #define WEP_KEYS 		4
 #define WEP_KEY_LEN		13
@@ -1124,6 +1126,14 @@ enum ieee80211_mfie {
 /* Minimal header; can be used for passing 802.11 frames with sufficient
  * information to determine what type of underlying data type is actually
  * stored in the data. */
+ struct ieee80211_pspoll_hdr {
+        __le16 frame_ctl;
+        __le16 aid;
+	u8 bssid[ETH_ALEN];
+        u8 ta[ETH_ALEN];
+        //u8 payload[0];
+} __attribute__ ((packed));
+
 struct ieee80211_hdr {
         __le16 frame_ctl;
         __le16 duration_id;
@@ -1660,6 +1670,7 @@ struct ieee80211_network {
 	bool ralink_cap_exist;
 	bool atheros_cap_exist;
 	bool cisco_cap_exist;
+	bool marvell_cap_exist;
 	bool unknown_cap_exist;
 //	u8	berp_info;
 	bool	berp_info_valid;
@@ -1865,6 +1876,19 @@ typedef struct _RT_POWER_SAVE_CONTROL
 	// Leisre Poswer Save : Disable RF if connected but traffic is not busy
 	//
 	bool				bLeisurePs;
+	u32				PowerProfile;
+	u8				LpsIdleCount;
+	u8				RegMaxLPSAwakeIntvl;
+	u8				LPSAwakeIntvl;
+
+	u32				CurPsLevel;
+	u32				RegRfPsLevel;
+
+	bool				bFwCtrlLPS;
+	u8				FWCtrlPSMode;
+
+	bool				LinkReqInIPSRFOffPgs;
+	bool				BufConnectinfoBefore;
 
 }RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL;
 
@@ -1905,14 +1929,121 @@ typedef struct _RT_LINK_DETECT_T{
 
 	u32				NumTxOkInPeriod;
 	u32				NumRxOkInPeriod;
+	u32				NumRxUnicastOkInPeriod;
 	bool				bBusyTraffic;
 }RT_LINK_DETECT_T, *PRT_LINK_DETECT_T;
 
+//added by amy 090330
+typedef enum _HW_VARIABLES{
+	HW_VAR_ETHER_ADDR,
+	HW_VAR_MULTICAST_REG,
+	HW_VAR_BASIC_RATE,
+	HW_VAR_BSSID,
+	HW_VAR_MEDIA_STATUS,
+	HW_VAR_SECURITY_CONF,
+	HW_VAR_BEACON_INTERVAL,
+	HW_VAR_ATIM_WINDOW,
+	HW_VAR_LISTEN_INTERVAL,
+	HW_VAR_CS_COUNTER,
+	HW_VAR_DEFAULTKEY0,
+	HW_VAR_DEFAULTKEY1,
+	HW_VAR_DEFAULTKEY2,
+	HW_VAR_DEFAULTKEY3,
+	HW_VAR_SIFS,
+	HW_VAR_DIFS,
+	HW_VAR_EIFS,
+	HW_VAR_SLOT_TIME,
+	HW_VAR_ACK_PREAMBLE,
+	HW_VAR_CW_CONFIG,
+	HW_VAR_CW_VALUES,
+	HW_VAR_RATE_FALLBACK_CONTROL,
+	HW_VAR_CONTENTION_WINDOW,
+	HW_VAR_RETRY_COUNT,
+	HW_VAR_TR_SWITCH,
+	HW_VAR_COMMAND,			// For Command Register, Annie, 2006-04-07.
+	HW_VAR_WPA_CONFIG,		//2004/08/23, kcwu, for 8187 Security config
+	HW_VAR_AMPDU_MIN_SPACE,	// The spacing between sub-frame. Roger, 2008.07.04.
+	HW_VAR_SHORTGI_DENSITY,	// The density for shortGI. Roger, 2008.07.04.
+	HW_VAR_AMPDU_FACTOR,
+	HW_VAR_MCS_RATE_AVAILABLE,
+	HW_VAR_AC_PARAM,			// For AC Parameters, 2005.12.01, by rcnjko.
+	HW_VAR_ACM_CTRL,			// For ACM Control, Annie, 2005-12-13.
+	HW_VAR_DIS_Req_Qsize,		// For DIS_Reg_Qsize, Joseph
+	HW_VAR_CCX_CHNL_LOAD,		// For CCX 2 channel load request, 2006.05.04.
+	HW_VAR_CCX_NOISE_HISTOGRAM,	// For CCX 2 noise histogram request, 2006.05.04.
+	HW_VAR_CCX_CLM_NHM,			// For CCX 2 parallel channel load request and noise histogram request, 2006.05.12.
+	HW_VAR_TxOPLimit,				// For turbo mode related settings, added by Roger, 2006.12.07
+	HW_VAR_TURBO_MODE,			// For turbo mode related settings, added by Roger, 2006.12.15.
+	HW_VAR_RF_STATE, 			// For change or query RF power state, 061214, rcnjko.
+	HW_VAR_RF_OFF_BY_HW,		// For UI to query if external HW signal disable RF, 061229, rcnjko.
+	HW_VAR_BUS_SPEED, 		// In unit of bps. 2006.07.03, by rcnjko.
+        HW_VAR_SET_DEV_POWER,	// Set to low power, added by LanHsin, 2007.
+
+	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	//1Attention Please!!!<11n or 8190 specific code should be put below this line>
+	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	HW_VAR_RCR,				//for RCR, David 2006,05,11
+	HW_VAR_RATR_0,
+	HW_VAR_RRSR,
+	HW_VAR_CPU_RST,
+	HW_VAR_CECHK_BSSID,
+        HW_VAR_LBK_MODE,			// Set lookback mode, 2008.06.11. added by Roger.
+	// Set HW related setting for 11N AES bug.
+	HW_VAR_AES_11N_FIX,
+	// Set Usb Rx Aggregation
+	HW_VAR_USB_RX_AGGR,
+	HW_VAR_USER_CONTROL_TURBO_MODE,
+	HW_VAR_RETRY_LIMIT,
+#ifndef _RTL8192_EXT_PATCH_
+	HW_VAR_INIT_TX_RATE,  //Get Current Tx rate register. 2008.12.10. Added by tynli
+#endif
+	HW_VAR_TX_RATE_REG,  //Get Current Tx rate register. 2008.12.10. Added by tynli
+	HW_VAR_EFUSE_USAGE, //Get current EFUSE utilization. 2008.12.19. Added by Roger.
+	HW_VAR_EFUSE_BYTES,
+	HW_VAR_AUTOLOAD_STATUS, //Get current autoload status, 0: autoload success, 1: autoload fail. 2008.12.19. Added by Roger.
+	HW_VAR_RF_2R_DISABLE, // 2R disable
+	HW_VAR_SET_RPWM,
+	HW_VAR_H2C_FW_PWRMODE, // For setting FW related H2C cmd structure. by tynli. 2009.2.18
+	HW_VAR_H2C_FW_JOINBSSRPT, // For setting FW related H2C cmd structure. by tynli. 2009.2.18
+	HW_VAR_1X1_RECV_COMBINE,	// For 1T2R but only 1SS, Add by hpfan 2009.04.16 hpfan
+	HW_VAR_STOP_SEND_BEACON,
+	HW_VAR_TSF_TIMER,			// Read from TSF register to get the current TSF timer, by Bruce, 2009-07-22.
+	HW_VAR_IO_CMD,
+	HW_VAR_HANDLE_FW_C2H,		//Added by tynli. For handling FW C2H command. 2009.10.07.
+	HW_VAR_DL_FW_RSVD_PAGE, 		//Added by tynli. Download the packets that FW will use to RSVD page. 2009.10.14.
+	HW_VAR_AID,				//Added by tynli.
+	HW_VAR_HW_SEQ_ENABLE,		//Added by tynli. 2009.10.20.
+	HW_VAR_UPDATE_TSF,			//Added by tynli. 2009.10.22. For Hw count TBTT time.
+	HW_VAR_BCN_VALID,				//Added by tynli.
+	HW_VAR_FWLPS_RF_ON			//Added by tynli. 2009.11.09. For checking if Fw finishs RF on sequence.
+}HW_VARIABLES;
+
+#define RT_CHECK_FOR_HANG_PERIOD 2
 
 struct ieee80211_device {
 	struct net_device *dev;
         struct ieee80211_security sec;
 
+	bool	need_sw_enc;
+#ifdef ENABLE_LPS
+	bool bAwakePktSent;
+	u8  LPSDelayCnt;
+	bool bIsAggregateFrame;
+	bool polling;
+	void (*LeisurePSLeave)(struct net_device *dev);
+#endif
+
+#ifdef ENABLE_IPS
+	bool proto_stoppping;
+	bool wx_set_enc;
+	struct semaphore ips_sem;
+	struct work_struct ips_leave_wq;
+        void (*ieee80211_ips_leave_wq) (struct net_device *dev);
+        void (*ieee80211_ips_leave)(struct net_device *dev);
+#endif
+	void (*SetHwRegHandler)(struct net_device *dev,u8 variable,u8* val);
+	u8   (*rtllib_ap_sec_type)(struct ieee80211_device *ieee);
+
 	//hw security related
 //	u8 hwsec_support; //support?
 	u8 hwsec_active;  //hw security active.
@@ -2319,7 +2450,7 @@ struct ieee80211_device {
 	 * stop_send_bacons is NOT guaranteed to be called only
 	 * after start_send_beacons.
 	 */
-	void (*start_send_beacons) (struct net_device *dev,u16 tx_rate);
+	void (*start_send_beacons) (struct net_device *dev);
 	void (*stop_send_beacons) (struct net_device *dev);
 
 	/* power save mode related */
@@ -2373,6 +2504,19 @@ struct ieee80211_device {
 	u8 priv[0];
 };
 
+#define	RT_RF_OFF_LEVL_ASPM			BIT0	// PCI ASPM
+#define	RT_RF_OFF_LEVL_CLK_REQ		BIT1	// PCI clock request
+#define	RT_RF_OFF_LEVL_PCI_D3			BIT2	// PCI D3 mode
+#define	RT_RF_OFF_LEVL_HALT_NIC		BIT3	// NIC halt, re-initialize hw parameters
+#define	RT_RF_OFF_LEVL_FREE_FW		BIT4	// FW free, re-download the FW
+#define	RT_RF_OFF_LEVL_FW_32K		BIT5	// FW in 32k
+#define	RT_RF_PS_LEVEL_ALWAYS_ASPM	BIT6	// Always enable ASPM and Clock Req in initialization.
+#define	RT_RF_LPS_DISALBE_2R			BIT30	// When LPS is on, disable 2R if no packet is received or transmittd.
+#define	RT_RF_LPS_LEVEL_ASPM			BIT31	// LPS with ASPM
+#define	RT_IN_PS_LEVEL(pPSC, _PS_FLAG)	((pPSC->CurPsLevel & _PS_FLAG) ? true : false)
+#define	RT_CLEAR_PS_LEVEL(pPSC, _PS_FLAG)	(pPSC->CurPsLevel &= (~(_PS_FLAG)))
+#define	RT_SET_PS_LEVEL(pPSC, _PS_FLAG)	(pPSC->CurPsLevel |= _PS_FLAG)
+
 #define IEEE_A            (1<<0)
 #define IEEE_B            (1<<1)
 #define IEEE_G            (1<<2)
@@ -2609,9 +2753,9 @@ extern void ieee80211_stop_scan(struct i
 extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
 extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
 extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
+extern void ieee80211_stop_protocol(struct ieee80211_device *ieee,u8 shutdown);
 extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
+extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee,u8 shutdown);
 extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
 extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee);
 extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee);
@@ -2798,5 +2942,7 @@ extern int ieee80211_parse_info_param(st
 		struct ieee80211_rx_stats *stats);
 
 void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8  index);
+void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr);
+void ieee80211_sta_ps_send_pspoll_frame(struct ieee80211_device *ieee);
 #define RT_ASOC_RETRY_LIMIT	5
 #endif /* IEEE80211_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -312,6 +312,17 @@ static int ieee80211_is_eapol_frame(stru
 	if (skb->len < 24)
 		return 0;
 
+#if 1
+        if (ieee->hwsec_active)
+        {
+                cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
+                tcb_desc->bHwSec = 1;
+
+                if(ieee->need_sw_enc)
+                        tcb_desc->bHwSec = 0;
+        }
+#endif
+
 	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	fc = le16_to_cpu(hdr->frame_ctl);
 
@@ -366,8 +377,8 @@ ieee80211_rx_frame_decrypt(struct ieee80
 	    strcmp(crypt->ops->name, "TKIP") == 0) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-			       "received packet from " MAC_FMT "\n",
-			       ieee->dev->name, MAC_ARG(hdr->addr2));
+			       "received packet from %pM\n",
+			       ieee->dev->name, hdr->addr2);
 		}
 		return -1;
 	}
@@ -378,8 +389,8 @@ ieee80211_rx_frame_decrypt(struct ieee80
 	atomic_dec(&crypt->refcnt);
 	if (res < 0) {
 		IEEE80211_DEBUG_DROP(
-			"decryption failed (SA=" MAC_FMT
-			") res=%d\n", MAC_ARG(hdr->addr2), res);
+			"decryption failed (SA=%pM"
+			") res=%d\n", hdr->addr2, res);
 		if (res == -2)
 			IEEE80211_DEBUG_DROP("Decryption failed ICV "
 					     "mismatch (key %d)\n",
@@ -406,6 +417,10 @@ ieee80211_rx_frame_decrypt_msdu(struct i
 	{
 		cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
 		tcb_desc->bHwSec = 1;
+
+                if(ieee->need_sw_enc)
+                        tcb_desc->bHwSec = 0;
+
 	}
 
 	hdr = (struct ieee80211_hdr_4addr *) skb->data;
@@ -416,8 +431,8 @@ ieee80211_rx_frame_decrypt_msdu(struct i
 	atomic_dec(&crypt->refcnt);
 	if (res < 0) {
 		printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
-		       " (SA=" MAC_FMT " keyidx=%d)\n",
-		       ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
+		       " (SA=%pM keyidx=%d)\n",
+		       ieee->dev->name, hdr->addr2, keyidx);
 		return -1;
 	}
 
@@ -799,7 +814,7 @@ void RxReorderIndicatePacket( struct iee
 #endif
 }
 
-u8 parse_subframe(struct sk_buff *skb,
+u8 parse_subframe(struct ieee80211_device* ieee,struct sk_buff *skb,
                   struct ieee80211_rx_stats *rx_stats,
 		  struct ieee80211_rxb *rxb,u8* src,u8* dst)
 {
@@ -839,6 +854,7 @@ u8 parse_subframe(struct sk_buff *skb,
 	}
 
 	skb_pull(skb, LLCOffset);
+	ieee->bIsAggregateFrame = bIsAggregateFrame;//added by amy for Leisure PS
 
 	if(!bIsAggregateFrame) {
 		rxb->nr_subframes = 1;
@@ -940,6 +956,7 @@ int ieee80211_rtl_rx(struct ieee80211_de
 	u8	TID = 0;
 	u16	SeqNum = 0;
 	PRX_TS_RECORD pTS = NULL;
+	bool unicast_packet = false;
 	//bool bIsAggregateFrame = false;
 	//added by amy for reorder
 #ifdef NOT_YET
@@ -1045,8 +1062,8 @@ int ieee80211_rtl_rx(struct ieee80211_de
 			 * frames silently instead of filling system log with
 			 * these reports. */
 			IEEE80211_DEBUG_DROP("Decryption failed (not set)"
-					     " (SA=" MAC_FMT ")\n",
-					     MAC_ARG(hdr->addr2));
+					     " (SA=%pM)\n",
+					     hdr->addr2);
 			ieee->ieee_stats.rx_discards_undecryptable++;
 			goto rx_dropped;
 		}
@@ -1114,8 +1131,8 @@ int ieee80211_rtl_rx(struct ieee80211_de
 		    (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0)
 		{
 			printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
-			       "from " MAC_FMT "\n", dev->name,
-			       MAC_ARG(hdr->addr2));
+			       "from %pM\n", dev->name,
+			       hdr->addr2);
 			/* TODO: could inform hostapd about this so that it
 			 * could send auth failure report */
 			goto rx_dropped;
@@ -1215,6 +1232,24 @@ int ieee80211_rtl_rx(struct ieee80211_de
         if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN))
                 goto rx_dropped;
 
+#ifdef ENABLE_LPS
+	if ((ieee->iw_mode == IW_MODE_INFRA)  && (ieee->sta_sleep == 1)
+		&& (ieee->polling)) {
+		if (WLAN_FC_MORE_DATA(fc)) {
+			/* more data bit is set, let's request a new frame from the AP */
+			ieee80211_sta_ps_send_pspoll_frame(ieee);
+		} else {
+			ieee->polling =  false;
+		}
+	}
+#endif
+
+	ieee->need_sw_enc = 0;
+
+        if((!rx_stats->Decrypted)){
+                ieee->need_sw_enc = 1;
+        }
+
 	/* skb: hdr + (possibly fragmented, possibly encrypted) payload */
 
 	if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
@@ -1296,6 +1331,9 @@ int ieee80211_rtl_rx(struct ieee80211_de
 	ieee->LinkDetectInfo.NumRxOkInPeriod++;
 
 	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	if((!is_multicast_ether_addr(hdr->addr1)) && (!is_broadcast_ether_addr(hdr->addr1)))
+		unicast_packet = true;
+
 	if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
 		if (/*ieee->ieee802_1x &&*/
 		    ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
@@ -1311,8 +1349,8 @@ int ieee80211_rtl_rx(struct ieee80211_de
 		} else {
 			IEEE80211_DEBUG_DROP(
 				"encryption configured, but RX "
-				"frame not encrypted (SA=" MAC_FMT ")\n",
-				MAC_ARG(hdr->addr2));
+				"frame not encrypted (SA=%pM)\n",
+				hdr->addr2);
 			goto rx_dropped;
 		}
 	}
@@ -1331,9 +1369,9 @@ int ieee80211_rtl_rx(struct ieee80211_de
 	    !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
 		IEEE80211_DEBUG_DROP(
 			"dropped unencrypted RX data "
-			"frame from " MAC_FMT
+			"frame from %pM"
 			" (drop_unencrypted=1)\n",
-			MAC_ARG(hdr->addr2));
+			hdr->addr2);
 		goto rx_dropped;
 	}
 /*
@@ -1367,7 +1405,7 @@ int ieee80211_rtl_rx(struct ieee80211_de
 	}
 	/* to parse amsdu packets */
 	/* qos data packets & reserved bit is 1 */
-	if(parse_subframe(skb,rx_stats,rxb,src,dst) == 0) {
+	if(parse_subframe(ieee, skb,rx_stats,rxb,src,dst) == 0) {
 		/* only to free rxb, and not submit the packets to upper layer */
 		for(i =0; i < rxb->nr_subframes; i++) {
 			dev_kfree_skb(rxb->subframes[i]);
@@ -1377,6 +1415,32 @@ int ieee80211_rtl_rx(struct ieee80211_de
 		goto rx_dropped;
 	}
 
+#ifdef ENABLE_LPS
+		if(unicast_packet)
+		{
+			if (type == IEEE80211_FTYPE_DATA)
+			{
+
+				if(ieee->bIsAggregateFrame)
+					ieee->LinkDetectInfo.NumRxUnicastOkInPeriod+=rxb->nr_subframes;
+				else
+					ieee->LinkDetectInfo.NumRxUnicastOkInPeriod++;
+
+				// 2009.03.03 Leave DC mode immediately when detect high traffic
+				// DbgPrint("ending Seq %d\n", Frame_SeqNum(pduOS));
+				if((ieee->state == IEEE80211_LINKED) /*&& !MgntInitAdapterInProgress(pMgntInfo)*/)
+				{
+					if(	((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod +ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
+						(ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) )
+					{
+						if(ieee->LeisurePSLeave)
+							ieee->LeisurePSLeave(dev);
+					}
+				}
+			}
+		}
+#endif
+
 	ieee->last_rx_ps_time = jiffies;
 //added by amy for reorder
 	if(ieee->pHTInfo->bCurRxReorderEnable == false ||pTS == NULL){
@@ -2013,12 +2077,22 @@ int ieee80211_parse_info_param(struct ie
 				info_element->data[1] == 0x13 &&
 				info_element->data[2] == 0x74))
 			{
-				printk("========>%s(): athros AP is exist\n",__FUNCTION__);
+				//printk("========>%s(): athros AP is exist\n",__FUNCTION__);
 				network->atheros_cap_exist = true;
 			}
 			else
 				network->atheros_cap_exist = false;
 
+			if ((info_element->len >= 3 &&
+						info_element->data[0] == 0x00 &&
+						info_element->data[1] == 0x50 &&
+						info_element->data[2] == 0x43) )
+			{
+				network->marvell_cap_exist = true;
+				//printk("========>%s(): marvel AP is exist\n",__FUNCTION__);
+			}
+
+
 			if(info_element->len >= 3 &&
 				info_element->data[0] == 0x00 &&
 				info_element->data[1] == 0x40 &&
@@ -2219,7 +2293,8 @@ int ieee80211_parse_info_param(struct ie
 	}
 
 	if(!network->atheros_cap_exist && !network->broadcom_cap_exist &&
-		!network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation)
+		!network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation &&
+		!network->marvell_cap_exist)
 	{
 		network->unknown_cap_exist = true;
 	}
@@ -2333,6 +2408,7 @@ static inline int ieee80211_network_init
         network->broadcom_cap_exist = false;
 	network->ralink_cap_exist = false;
 	network->atheros_cap_exist = false;
+	network->marvell_cap_exist = false;
 	network->cisco_cap_exist = false;
 	network->unknown_cap_exist = false;
 #ifdef THOMAS_TURBO
@@ -2369,11 +2445,11 @@ static inline int ieee80211_network_init
 	}
 
 	if (network->mode == 0) {
-		IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
+		IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
 				     "network.\n",
 				     escape_essid(network->ssid,
 						  network->ssid_len),
-				     MAC_ARG(network->bssid));
+				     network->bssid);
 		return 1;
 	}
 
@@ -2463,6 +2539,7 @@ static inline void update_network(struct
 	dst->broadcom_cap_exist = src->broadcom_cap_exist;
 	dst->ralink_cap_exist = src->ralink_cap_exist;
 	dst->atheros_cap_exist = src->atheros_cap_exist;
+	dst->marvell_cap_exist = src->marvell_cap_exist;
 	dst->cisco_cap_exist = src->cisco_cap_exist;
 	dst->unknown_cap_exist = src->unknown_cap_exist;
 	memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
@@ -2557,9 +2634,9 @@ static inline void ieee80211_process_pro
 
 	memset(&network, 0, sizeof(struct ieee80211_network));
 	IEEE80211_DEBUG_SCAN(
-		"'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
+		"'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
 		escape_essid(info_element->data, info_element->len),
-		MAC_ARG(beacon->header.addr3),
+		beacon->header.addr3,
 		(beacon->capability & (1<<0xf)) ? '1' : '0',
 		(beacon->capability & (1<<0xe)) ? '1' : '0',
 		(beacon->capability & (1<<0xd)) ? '1' : '0',
@@ -2578,10 +2655,10 @@ static inline void ieee80211_process_pro
 		(beacon->capability & (1<<0x0)) ? '1' : '0');
 
 	if (ieee80211_network_init(ieee, beacon, &network, stats)) {
-		IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
+		IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
 				     escape_essid(info_element->data,
 						  info_element->len),
-				     MAC_ARG(beacon->header.addr3),
+				     beacon->header.addr3,
 				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
 				     IEEE80211_STYPE_PROBE_RESP ?
 				     "PROBE RESPONSE" : "BEACON");
@@ -2692,11 +2769,11 @@ static inline void ieee80211_process_pro
 			/* If there are no more slots, expire the oldest */
 			list_del(&oldest->list);
 			target = oldest;
-			IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
+			IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
 					     "network list.\n",
 					     escape_essid(target->ssid,
 							  target->ssid_len),
-					     MAC_ARG(target->bssid));
+					     target->bssid);
 		} else {
 			/* Otherwise just pull from the free list */
 			target = list_entry(ieee->network_free_list.next,
@@ -2706,10 +2783,10 @@ static inline void ieee80211_process_pro
 
 
 #ifdef CONFIG_IEEE80211_DEBUG
-		IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
+		IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
 				     escape_essid(network.ssid,
 						  network.ssid_len),
-				     MAC_ARG(network.bssid),
+				     network.bssid,
 				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
 				     IEEE80211_STYPE_PROBE_RESP ?
 				     "PROBE RESPONSE" : "BEACON");
@@ -2719,10 +2796,10 @@ static inline void ieee80211_process_pro
 		if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
 			ieee80211_softmac_new_net(ieee,&network);
 	} else {
-		IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
+		IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
 				     escape_essid(target->ssid,
 						  target->ssid_len),
-				     MAC_ARG(target->bssid),
+				     target->bssid,
 				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
 				     IEEE80211_STYPE_PROBE_RESP ?
 				     "PROBE RESPONSE" : "BEACON");
@@ -2761,12 +2838,14 @@ void ieee80211_rx_mgt(struct ieee80211_d
 		      struct ieee80211_hdr_4addr *header,
 		      struct ieee80211_rx_stats *stats)
 {
+#if 0
 	if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
 				ieee->iw_mode == IW_MODE_INFRA &&
 				ieee->state == IEEE80211_LINKED))
 	{
 		tasklet_schedule(&ieee->ps_task);
 	}
+#endif
 
 	if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
 		WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
@@ -2780,6 +2859,15 @@ void ieee80211_rx_mgt(struct ieee80211_d
 		IEEE80211_DEBUG_SCAN("Beacon\n");
 		ieee80211_process_probe_response(
 			ieee, (struct ieee80211_probe_response *)header, stats);
+
+		//printk("----------->%s()\n", __func__);
+		if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
+					ieee->iw_mode == IW_MODE_INFRA &&
+					ieee->state == IEEE80211_LINKED))
+		{
+			tasklet_schedule(&ieee->ps_task);
+		}
+
 		break;
 
 	case IEEE80211_STYPE_PROBE_RESP:
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 
 #include <linux/random.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include <asm/uaccess.h>
 #ifdef ENABLE_DOT11D
@@ -646,7 +647,7 @@ void ieee80211_stop_send_beacons(struct
 void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
 {
 	if(ieee->start_send_beacons)
-		ieee->start_send_beacons(ieee->dev,ieee->basic_rate);
+		ieee->start_send_beacons(ieee->dev);
 	if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
 		ieee80211_beacons_start(ieee);
 }
@@ -686,6 +687,11 @@ void ieee80211_stop_scan(struct ieee8021
 /* called with ieee->lock held */
 void ieee80211_rtl_start_scan(struct ieee80211_device *ieee)
 {
+#ifdef ENABLE_IPS
+	if(ieee->ieee80211_ips_leave_wq != NULL)
+		ieee->ieee80211_ips_leave_wq(ieee->dev);
+#endif
+
 #ifdef ENABLE_DOT11D
 	if(IS_DOT11D_ENABLE(ieee) )
 	{
@@ -1093,6 +1099,40 @@ struct sk_buff* ieee80211_null_func(stru
 
 }
 
+struct sk_buff* ieee80211_pspoll_func(struct ieee80211_device *ieee)
+{
+	struct sk_buff *skb;
+	struct ieee80211_pspoll_hdr* hdr;
+
+#ifdef USB_USE_ALIGNMENT
+        u32 Tmpaddr=0;
+        int alignment=0;
+        skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll_hdr) + ieee->tx_headroom + USB_512B_ALIGNMENT_SIZE);
+#else
+	skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll_hdr)+ieee->tx_headroom);
+#endif
+	if (!skb)
+		return NULL;
+
+#ifdef USB_USE_ALIGNMENT
+        Tmpaddr = (u32)skb->data;
+        alignment = Tmpaddr & 0x1ff;
+        skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
+#endif
+	skb_reserve(skb, ieee->tx_headroom);
+
+	hdr = (struct ieee80211_pspoll_hdr*)skb_put(skb,sizeof(struct ieee80211_pspoll_hdr));
+
+	memcpy(hdr->bssid, ieee->current_network.bssid, ETH_ALEN);
+	memcpy(hdr->ta, ieee->dev->dev_addr, ETH_ALEN);
+
+	hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000);
+	hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_CTL |IEEE80211_STYPE_PSPOLL | IEEE80211_FCTL_PM);
+
+	return skb;
+
+}
+
 
 void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
 {
@@ -1582,6 +1622,11 @@ void ieee80211_associate_procedure_wq(st
 {
 #endif
 	ieee->sync_scan_hurryup = 1;
+#ifdef ENABLE_IPS
+	if(ieee->ieee80211_ips_leave != NULL)
+        	ieee->ieee80211_ips_leave(ieee->dev);
+#endif
+
 	down(&ieee->wx_sem);
 
 	if (ieee->data_hard_stop)
@@ -1592,6 +1637,17 @@ void ieee80211_associate_procedure_wq(st
 	//ieee->set_chan(ieee->dev, ieee->current_network.channel);
 	HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
 
+#ifdef ENABLE_IPS
+	if(ieee->eRFPowerState == eRfOff)
+	{
+		if(ieee->ieee80211_ips_leave_wq != NULL)
+			ieee->ieee80211_ips_leave_wq(ieee->dev);
+
+		up(&ieee->wx_sem);
+		return;
+	}
+#endif
+
 	ieee->associate_seq = 1;
 	ieee80211_associate_step1(ieee);
 
@@ -1897,7 +1953,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_d
 		ieee80211_resp_to_assoc_rq(ieee, dest);
 	}
 
-	printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
+	printk(KERN_INFO"New client associated: %pM\n", dest);
 	//FIXME
 	#if 0
 	spin_lock_irqsave(&ieee->lock,flags);
@@ -1918,43 +1974,92 @@ void ieee80211_sta_ps_send_null_frame(st
 
 }
 
+void ieee80211_sta_ps_send_pspoll_frame(struct ieee80211_device *ieee)
+{
+
+	struct sk_buff *buf = ieee80211_pspoll_func(ieee);
+
+	if (buf)
+		softmac_ps_mgmt_xmit(buf, ieee);
+
+}
 
 short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
 {
 	int timeout = ieee->ps_timeout;
 	u8 dtim;
-	/*if(ieee->ps == IEEE80211_PS_DISABLED ||
-		ieee->iw_mode != IW_MODE_INFRA ||
-		ieee->state != IEEE80211_LINKED)
+	PRT_POWER_SAVE_CONTROL	pPSC = (PRT_POWER_SAVE_CONTROL)(&(ieee->PowerSaveControl));
 
+	if(ieee->LPSDelayCnt)
+	{
+		//printk("===============>Delay enter LPS for DHCP and ARP packets...\n");
+		ieee->LPSDelayCnt --;
 		return 0;
-	*/
+	}
+
 	dtim = ieee->current_network.dtim_data;
-	//printk("DTIM\n");
+//	printk("%s():DTIM:%d\n",__FUNCTION__,dtim);
 	if(!(dtim & IEEE80211_DTIM_VALID))
 		return 0;
 	timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
 	//printk("VALID\n");
 	ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
-
-	if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
+	/* there's no need to nofity AP that I find you buffered with broadcast packet */
+	if(dtim & (IEEE80211_DTIM_UCAST & ieee->ps))
 		return 2;
 
-	if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
+	if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout))){
+//		printk("%s():111Oh Oh ,it is not time out return 0\n",__FUNCTION__);
 		return 0;
-
-	if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
+	}
+	if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout))){
+//		printk("%s():222Oh Oh ,it is not time out return 0\n",__FUNCTION__);
 		return 0;
-
+	}
 	if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
 		(ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
 		return 0;
 
 	if(time_l){
+		if(ieee->bAwakePktSent == true) {
+			pPSC->LPSAwakeIntvl = 1;//tx wake one beacon
+		} else {
+			u8		MaxPeriod = 1;
+
+			if(pPSC->LPSAwakeIntvl == 0)
+				pPSC->LPSAwakeIntvl = 1;
+			//pNdisCommon->RegLPSMaxIntvl /// 0x0 - eFastPs, 0xFF -DTIM, 0xNN - 0xNN * BeaconIntvl
+			if(pPSC->RegMaxLPSAwakeIntvl == 0) // Default (0x0 - eFastPs, 0xFF -DTIM, 0xNN - 0xNN * BeaconIntvl)
+				MaxPeriod = 1; // 1 Beacon interval
+			else if(pPSC->RegMaxLPSAwakeIntvl == 0xFF) // DTIM
+				MaxPeriod = ieee->current_network.dtim_period;
+			else
+				MaxPeriod = pPSC->RegMaxLPSAwakeIntvl;
+			pPSC->LPSAwakeIntvl = (pPSC->LPSAwakeIntvl >= MaxPeriod) ? MaxPeriod : (pPSC->LPSAwakeIntvl + 1);
+		}
+		{
+			u8 LPSAwakeIntvl_tmp = 0;
+			u8 period = ieee->current_network.dtim_period;
+			u8 count = ieee->current_network.tim.tim_count;
+			if(count == 0 ) {
+				if(pPSC->LPSAwakeIntvl > period)
+					LPSAwakeIntvl_tmp = period + (pPSC->LPSAwakeIntvl - period) -((pPSC->LPSAwakeIntvl-period)%period);
+				else
+					LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl;
+
+			} else {
+				if(pPSC->LPSAwakeIntvl > ieee->current_network.tim.tim_count)
+					LPSAwakeIntvl_tmp = count + (pPSC->LPSAwakeIntvl - count) -((pPSC->LPSAwakeIntvl-count)%period);
+				else
+					LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl;//ieee->current_network.tim.tim_count;//pPSC->LPSAwakeIntvl;
+			}
+			//printk("=========>%s()assoc_id:%d(%#x),bAwakePktSent:%d,DTIM:%d, sleep interval:%d, LPSAwakeIntvl_tmp:%d, count:%d\n",__func__,ieee->assoc_id,cpu_to_le16(ieee->assoc_id),ieee->bAwakePktSent,ieee->current_network.dtim_period,pPSC->LPSAwakeIntvl,LPSAwakeIntvl_tmp,count);
+
 		*time_l = ieee->current_network.last_dtim_sta_time[0]
-			+ (ieee->current_network.beacon_interval);
+			+ MSECS(ieee->current_network.beacon_interval * LPSAwakeIntvl_tmp);
 		//	* ieee->current_network.dtim_period) * 1000;
 	}
+	}
 
 	if(time_h){
 		*time_h = ieee->current_network.last_dtim_sta_time[1];
@@ -1982,6 +2087,8 @@ inline void ieee80211_sta_ps(struct ieee
 		ieee->state != IEEE80211_LINKED)){
 
 	//	#warning CHECK_LOCK_HERE
+		printk("=====>%s(): no need to ps,wake up!! ieee->ps is %d,ieee->iw_mode is %d,ieee->state is %d\n",
+			__FUNCTION__,ieee->ps,ieee->iw_mode,ieee->state);
 		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
 
 		ieee80211_sta_wakeup(ieee, 1);
@@ -1991,27 +2098,27 @@ inline void ieee80211_sta_ps(struct ieee
 
 	sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
 	/* 2 wake, 1 sleep, 0 do nothing */
-	if(sleep == 0)
+	if(sleep == 0)//it is not time out or dtim is not valid
+	{
+		//printk("===========>sleep is 0,do nothing\n");
 		goto out;
-
+	}
 	if(sleep == 1){
-
-		if(ieee->sta_sleep == 1)
+		//printk("===========>sleep is 1,to sleep\n");
+		if(ieee->sta_sleep == 1){
+			//printk("%s(1): sta_sleep = 1, sleep again ++++++++++ \n", __func__);
 			ieee->enter_sleep_state(ieee->dev,th,tl);
+		}
 
 		else if(ieee->sta_sleep == 0){
 		//	printk("send null 1\n");
 			spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
 
 			if(ieee->ps_is_queue_empty(ieee->dev)){
-
-
 				ieee->sta_sleep = 2;
-
 				ieee->ack_tx_to_ieee = 1;
-
+				//printk("%s(2): sta_sleep = 0, notify AP we will sleeped ++++++++++ SendNullFunctionData\n", __func__);
 				ieee80211_sta_ps_send_null_frame(ieee,1);
-
 				ieee->ps_th = th;
 				ieee->ps_tl = tl;
 			}
@@ -2019,11 +2126,13 @@ inline void ieee80211_sta_ps(struct ieee
 
 		}
 
+		ieee->bAwakePktSent = false;//after null to power save we set it to false. not listen every beacon.
 
 	}else if(sleep == 2){
-//#warning CHECK_LOCK_HERE
+		//printk("==========>sleep is 2,to wakeup\n");
 		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
 
+		//printk("%s(3): pkt buffered in ap will awake ++++++++++ ieee80211_sta_wakeup\n", __func__);
 		ieee80211_sta_wakeup(ieee,1);
 
 		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
@@ -2038,9 +2147,19 @@ void ieee80211_sta_wakeup(struct ieee802
 {
 	if(ieee->sta_sleep == 0){
 		if(nl){
-			printk("Warning: driver is probably failing to report TX ps error\n");
-			ieee->ack_tx_to_ieee = 1;
-			ieee80211_sta_ps_send_null_frame(ieee, 0);
+			if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING)
+			{
+				//printk("%s(1): notify AP we are awaked ++++++++++ SendNullFunctionData\n", __func__);
+				//printk("Warning: driver is probably failing to report TX ps error\n");
+				ieee->ack_tx_to_ieee = 1;
+				ieee80211_sta_ps_send_null_frame(ieee, 0);
+			}
+			else
+			{
+				ieee->ack_tx_to_ieee = 1;
+				//printk("%s(2): notify AP we are awaked ++++++++++ Send PS-Poll\n", __func__);
+				ieee80211_sta_ps_send_pspoll_frame(ieee);
+			}
 		}
 		return;
 
@@ -2048,12 +2167,27 @@ void ieee80211_sta_wakeup(struct ieee802
 
 	if(ieee->sta_sleep == 1)
 		ieee->sta_wake_up(ieee->dev);
+	if(nl){
 
-	ieee->sta_sleep = 0;
+			if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING)
+			{
+				//printk("%s(3): notify AP we are awaked ++++++++++ SendNullFunctionData\n", __func__);
+				//printk("Warning: driver is probably failing to report TX ps error\n");
+				ieee->ack_tx_to_ieee = 1;
+				ieee80211_sta_ps_send_null_frame(ieee, 0);
+			}
+			else
+			{
+				ieee->ack_tx_to_ieee = 1;
+			ieee->polling = true;
+				//printk("%s(4): notify AP we are awaked ++++++++++ Send PS-Poll\n", __func__);
+				//ieee80211_sta_ps_send_null_frame(ieee, 0);
+				ieee80211_sta_ps_send_pspoll_frame(ieee);
+			}
 
-	if(nl){
-		ieee->ack_tx_to_ieee = 1;
-		ieee80211_sta_ps_send_null_frame(ieee, 0);
+	} else {
+		ieee->sta_sleep = 0;
+		ieee->polling = false;
 	}
 }
 
@@ -2067,23 +2201,30 @@ void ieee80211_ps_tx_ack(struct ieee8021
 		/* Null frame with PS bit set */
 		if(success){
 			ieee->sta_sleep = 1;
+			//printk("notify AP we will sleep and send null ok, so sleep now++++++++++ enter_sleep_state\n");
 			ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
 		}
-		/* if the card report not success we can't be sure the AP
-		 * has not RXed so we can't assume the AP believe us awake
-		 */
-	}
-	/* 21112005 - tx again null without PS bit if lost */
-	else {
+	} else {/* 21112005 - tx again null without PS bit if lost */
 
 		if((ieee->sta_sleep == 0) && !success){
 			spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-			ieee80211_sta_ps_send_null_frame(ieee, 0);
+			//ieee80211_sta_ps_send_null_frame(ieee, 0);
+			if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING)
+			{
+				//printk("notify AP we will sleep but send bull failed, so resend++++++++++ SendNullFunctionData\n");
+				ieee80211_sta_ps_send_null_frame(ieee, 0);
+			}
+			else
+			{
+				//printk("notify AP we are awaked but send pspoll failed, so resend++++++++++ Send PS-Poll\n");
+				ieee80211_sta_ps_send_pspoll_frame(ieee);
+			}
 			spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
 		}
 	}
 	spin_unlock_irqrestore(&ieee->lock, flags);
 }
+
 void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb)
 {
 	struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data;
@@ -2227,7 +2368,7 @@ ieee80211_rx_frame_softmac(struct ieee80
 								{
 									if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
 									{
-												// WEP or TKIP encryption
+										// WEP or TKIP encryption
 										if(IsHTHalfNmodeAPs(ieee))
 										{
 											bSupportNmode = true;
@@ -2238,7 +2379,7 @@ ieee80211_rx_frame_softmac(struct ieee80
 											bSupportNmode = false;
 											bHalfSupportNmode = false;
 										}
-									printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode);
+									printk("==========>to link with AP using SEC(%d, %d)\n", bSupportNmode, bHalfSupportNmode);
 									}
 								}
 								/* Dummy wirless mode setting to avoid encryption issue */
@@ -2574,6 +2715,7 @@ void ieee80211_start_ibss_wq(struct ieee
 		ieee->ssid_set = 1;
 	}
 
+	ieee->state = IEEE80211_NOLINK;
 	/* check if we have this cell in our network list */
 	ieee80211_softmac_check_all_nets(ieee);
 
@@ -2705,6 +2847,10 @@ void ieee80211_start_bss(struct ieee8021
 	spin_lock_irqsave(&ieee->lock, flags);
 
 	if (ieee->state == IEEE80211_NOLINK){
+#ifdef ENABLE_IPS
+		if(ieee->ieee80211_ips_leave_wq != NULL)
+			ieee->ieee80211_ips_leave_wq(ieee->dev);
+#endif
 		ieee->actscanning = true;
 		ieee80211_rtl_start_scan(ieee);
 	}
@@ -2823,21 +2969,23 @@ struct sk_buff *ieee80211_get_beacon(str
 	return skb;
 }
 
-void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
+void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee, u8 shutdown)
 {
 	ieee->sync_scan_hurryup = 1;
 	down(&ieee->wx_sem);
-	ieee80211_stop_protocol(ieee);
+	ieee80211_stop_protocol(ieee, shutdown);
 	up(&ieee->wx_sem);
 }
 
 
-void ieee80211_stop_protocol(struct ieee80211_device *ieee)
+void ieee80211_stop_protocol(struct ieee80211_device *ieee, u8 shutdown)
 {
 	if (!ieee->proto_started)
 		return;
 
-	ieee->proto_started = 0;
+	if(shutdown)
+		ieee->proto_started = 0;
+	ieee->proto_stoppping = 1;
 
 	ieee80211_stop_send_beacons(ieee);
 	del_timer_sync(&ieee->associate_timer);
@@ -2849,6 +2997,8 @@ void ieee80211_stop_protocol(struct ieee
 
 	ieee80211_disassociate(ieee);
 	RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
+
+	ieee->proto_stoppping = 0;
 }
 
 void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
@@ -2894,6 +3044,8 @@ void ieee80211_start_protocol(struct iee
 
 	ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
 
+	ieee->state = IEEE80211_NOLINK;
+
 
 	/* if the user set the MAC of the ad-hoc cell and then
 	 * switch to managed mode, shall we  make sure that association
@@ -3013,7 +3165,9 @@ void ieee80211_softmac_init(struct ieee8
 #endif
 	sema_init(&ieee->wx_sem, 1);
 	sema_init(&ieee->scan_sem, 1);
-
+#ifdef ENABLE_IPS
+	sema_init(&ieee->ips_sem,1);
+#endif
 	spin_lock_init(&ieee->mgmt_tx_lock);
 	spin_lock_init(&ieee->beacon_lock);
 
@@ -3537,5 +3691,6 @@ EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan
 EXPORT_SYMBOL_NOVERS(ieee80211_send_probe_requests);
 EXPORT_SYMBOL_NOVERS(ieee80211_softmac_scan_syncro);
 EXPORT_SYMBOL_NOVERS(ieee80211_start_scan_syncro);
+EXPORT_SYMBOL_NOVERS(ieee80211_sta_ps_send_null_frame);
+EXPORT_SYMBOL_NOVERS(ieee80211_sta_ps_send_pspoll_frame);
 #endif
-//EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c	2010-05-16 17:17:36.000000000 -0400
@@ -160,7 +160,7 @@ int ieee80211_wx_set_wap(struct ieee8021
 	}
 
 	if (ifup)
-		ieee80211_stop_protocol(ieee);
+		ieee80211_stop_protocol(ieee,true);
 
 	/* just to avoid to give inconsistent infos in the
 	 * get wx method. not really needed otherwise
@@ -302,7 +302,7 @@ int ieee80211_wx_set_mode(struct ieee802
 	if (!ieee->proto_started){
 		ieee->iw_mode = wrqu->mode;
 	}else{
-		ieee80211_stop_protocol(ieee);
+		ieee80211_stop_protocol(ieee,true);
 		ieee->iw_mode = wrqu->mode;
 		ieee80211_start_protocol(ieee);
 	}
@@ -326,6 +326,17 @@ void ieee80211_wx_sync_scan_wq(struct ie
 	int b40M = 0;
 	static int count = 0;
 	chan = ieee->current_network.channel;
+
+#ifdef ENABLE_LPS
+	if (ieee->LeisurePSLeave) {
+		ieee->LeisurePSLeave(ieee->dev);
+	}
+
+	/* notify AP to be in PS mode */
+	ieee80211_sta_ps_send_null_frame(ieee, 1);
+	ieee80211_sta_ps_send_null_frame(ieee, 1);
+#endif
+
 	netif_carrier_off(ieee->dev);
 
 	if (ieee->data_hard_stop)
@@ -360,6 +371,12 @@ void ieee80211_wx_sync_scan_wq(struct ie
 	ieee->InitialGainHandler(ieee->dev,IG_Restore);
 	ieee->state = IEEE80211_LINKED;
 	ieee->link_change(ieee->dev);
+
+#ifdef ENABLE_LPS
+	/* Notify AP that I wake up again */
+	ieee80211_sta_ps_send_null_frame(ieee, 0);
+#endif
+
 	// To prevent the immediately calling watch_dog after scan.
 	if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
 	{
@@ -429,8 +446,9 @@ int ieee80211_wx_set_essid(struct ieee80
 		goto out;
 	}
 
-	if(proto_started)
-		ieee80211_stop_protocol(ieee);
+	if(proto_started){
+		ieee80211_stop_protocol(ieee,true);
+	}
 
 
 	/* this is just to be sure that the GET wx callback
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -200,8 +200,8 @@ int ieee80211_encrypt_fragment(
 		header = (struct ieee80211_hdr *) frag->data;
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-			       "TX packet to " MAC_FMT "\n",
-			       ieee->dev->name, MAC_ARG(header->addr1));
+			       "TX packet to %pM\n",
+			       ieee->dev->name, header->addr1);
 		}
 		return -1;
 	}
@@ -334,6 +334,13 @@ void ieee80211_tx_query_agg_cap(struct i
 	if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
 		return;
 #endif
+
+        if(tcb_desc->bdhcp)// || ieee->CntAfterLink<2)
+        {
+                return;
+        }
+
+
 #if 1
 	if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
 	{
@@ -628,6 +635,7 @@ int ieee80211_rtl_xmit(struct sk_buff *s
 	int qos_actived = ieee->current_network.qos_data.active;
 
 	struct ieee80211_crypt_data* crypt;
+	bool    bdhcp =false;
 
 	cb_desc *tcb_desc;
 
@@ -672,6 +680,55 @@ int ieee80211_rtl_xmit(struct sk_buff *s
 		}
 	#endif
 
+		// The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time
+		// to prevent DHCP protocol fail
+		if (skb->len > 282){//MINIMUM_DHCP_PACKET_SIZE) {
+			if (ETH_P_IP == ether_type) {// IP header
+				const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14);
+				if (IPPROTO_UDP == ip->protocol) {//FIXME windows is 11 but here UDP in linux kernel is 17.
+					struct udphdr *udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2));
+					//if(((ntohs(udp->source) == 68) && (ntohs(udp->dest) == 67)) ||
+					///   ((ntohs(udp->source) == 67) && (ntohs(udp->dest) == 68))) {
+					if(((((u8 *)udp)[1] == 68) && (((u8 *)udp)[3] == 67)) ||
+							((((u8 *)udp)[1] == 67) && (((u8 *)udp)[3] == 68))) {
+						// 68 : UDP BOOTP client
+						// 67 : UDP BOOTP server
+						printk("DHCP pkt src port:%d, dest port:%d!!\n", ((u8 *)udp)[1],((u8 *)udp)[3]);
+						// Use low rate to send DHCP packet.
+						//if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom)
+						//{
+						//      tcb_desc->DataRate = MgntQuery_TxRateExcludeCCKRates(ieee);//0xc;//ofdm 6m
+						//      tcb_desc->bTxDisableRateFallBack = false;
+						//}
+						//else
+						//pTcb->DataRate = Adapter->MgntInfo.LowestBasicRate;
+						//RTPRINT(FDM, WA_IOT, ("DHCP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate));
+
+						bdhcp = true;
+#ifdef _RTL8192_EXT_PATCH_
+						ieee->LPSDelayCnt = 100;//pPSC->LPSAwakeIntvl*2; //AMY,090701
+#else
+						ieee->LPSDelayCnt = 100;//pPSC->LPSAwakeIntvl*2;
+#endif
+					}
+				}
+				}else if(ETH_P_ARP == ether_type){// IP ARP packet
+					printk("=================>DHCP Protocol start tx ARP pkt!!\n");
+					bdhcp = true;
+					ieee->LPSDelayCnt = ieee->current_network.tim.tim_count;
+
+					//if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom)
+					//{
+					//      tcb_desc->DataRate = MgntQuery_TxRateExcludeCCKRates(Adapter->MgntInfo.mBrates);//0xc;//ofdm 6m
+					//      tcb_desc->bTxDisableRateFallBack = FALSE;
+					//}
+					//else
+					//      tcb_desc->DataRate = Adapter->MgntInfo.LowestBasicRate;
+					//RTPRINT(FDM, WA_IOT, ("ARP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate));
+
+				}
+			}
+
 		/* Save source and destination addresses */
 		memcpy(&dest, skb->data, ETH_ALEN);
 		memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
@@ -895,6 +952,25 @@ int ieee80211_rtl_xmit(struct sk_buff *s
 		else
 			//tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
 			tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
+
+		if(bdhcp == true){
+			// Use low rate to send DHCP packet.
+			//if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) {
+			//	tcb_desc->data_rate = MGN_1M;//MgntQuery_TxRateExcludeCCKRates(ieee);//0xc;//ofdm 6m
+			//	tcb_desc->bTxDisableRateFallBack = false;
+			//}
+			//else
+			{
+				tcb_desc->data_rate = MGN_1M;
+				tcb_desc->bTxDisableRateFallBack = 1;
+			}
+
+			tcb_desc->RATRIndex = 7;
+			tcb_desc->bTxUseDriverAssingedRate = 1;
+			tcb_desc->bdhcp = 1;
+		}
+
+
 		ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
 		ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
 		ieee80211_query_HTCapShortGI(ieee, tcb_desc);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/wireless.h>
 #include <linux/version.h>
 #include <linux/kmod.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 
 #include "ieee80211.h"
@@ -386,10 +387,10 @@ int ieee80211_wx_get_scan(struct ieee802
 		else
 			IEEE80211_DEBUG_SCAN(
 				"Not showing network '%s ("
-				MAC_FMT ")' due to age (%lums).\n",
+				"%pM)' due to age (%lums).\n",
 				escape_essid(network->ssid,
 					     network->ssid_len),
-				MAC_ARG(network->bssid),
+				network->bssid,
 				(jiffies - network->last_scanned) / (HZ / 100));
 	}
 
@@ -933,7 +934,7 @@ int ieee80211_wx_set_auth(struct ieee802
 #if 1
 	case IW_AUTH_WPA_ENABLED:
 		ieee->wpa_enabled = (data->value)?1:0;
-		//printk("enalbe wpa:%d\n", ieee->wpa_enabled);
+		//printk("enable wpa:%d\n", ieee->wpa_enabled);
 		break;
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c	2010-05-16 17:17:36.000000000 -0400
@@ -113,7 +113,7 @@ static struct sk_buff* ieee80211_ADDBA(s
 	u16 tmp = 0;
 	u16 len = ieee->tx_headroom + 9;
 	//category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) +  BA Timeout Value(2) +  BA Start SeqCtrl(2)(or StatusCode(2))
-	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev);
+	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev);
 	if (pBA == NULL||ieee == NULL)
 	{
 		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
@@ -243,7 +243,7 @@ static struct sk_buff* ieee80211_DELBA(
 	u16 len = 6 + ieee->tx_headroom;
 
 	if (net_ratelimit())
-	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst));
+	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst);
 
 	memset(&DelbaParamSet, 0, 2);
 
@@ -397,7 +397,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80
 	pBaTimeoutVal = (u16*)(tag + 5);
 	pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
 
-	printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst));
+	printk("====================>rx ADDBAREQ from :%pM\n", dst);
 //some other capability is not ready now.
 	if(	(ieee->current_network.qos_data.active == 0) ||
 		(ieee->pHTInfo->bCurrentHTSupport == false)) //||
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h	2010-05-16 17:17:36.000000000 -0400
@@ -458,7 +458,8 @@ typedef enum _HT_IOT_PEER
 	HT_IOT_PEER_RALINK = 3,
 	HT_IOT_PEER_ATHEROS = 4,
 	HT_IOT_PEER_CISCO= 5,
-	HT_IOT_PEER_MAX = 6
+        HT_IOT_PEER_MARVELL=6,
+	HT_IOT_PEER_MAX = 7
 }HT_IOT_PEER_E, *PHTIOT_PEER_E;
 
 //
@@ -475,6 +476,7 @@ typedef enum _HT_IOT_ACTION{
 	HT_IOT_ACT_CDD_FSYNC = 0x00000080,
 	HT_IOT_ACT_PURE_N_MODE = 0x00000100,
 	HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200,
+	HT_IOT_ACT_NULL_DATA_POWER_SAVING = 0x00800000,
 }HT_IOT_ACTION_E, *PHT_IOT_ACTION_E;
 
 #endif //_RTL819XU_HTTYPE_H_
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,7 @@ u16 MCS_DATA_RATE[2][2][77] =
 static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
 static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
 static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
-static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f};
+//static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f};
 static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f};	//cosa 03202008
 static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
 static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
@@ -40,8 +40,9 @@ static u8 EDIMAX_RALINK[3] = {0x00, 0x0e
 static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
 static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0};
 static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
+static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
 
-// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the
+// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the
 // code in other place??
 //static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96};
 /********************************************************************************************************************
@@ -349,12 +350,12 @@ bool IsHTHalfNmodeAPs(struct ieee80211_d
 	bool			retValue = false;
 	struct ieee80211_network* net = &ieee->current_network;
 #if 0
-	if(pMgntInfo->bHalfNMode == false)
+	if(ieee->bHalfNMode == false)
 		retValue = false;
 	else
 #endif
 	if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
-		     (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
+	   	     (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
 		     (memcmp(net->bssid, PCI_RALINK, 3)==0) ||
 		     (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) ||
 		     (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) ||
@@ -363,7 +364,7 @@ bool IsHTHalfNmodeAPs(struct ieee80211_d
 	else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
     		    (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
     		    (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
-    		    (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ||
+    		    //(memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ||
     		    (net->broadcom_cap_exist))
     		  retValue = true;
 	else if(net->bssht.bdRT2RTAggregation)
@@ -387,13 +388,15 @@ void HTIOTPeerDetermine(struct ieee80211
 	struct ieee80211_network* net = &ieee->current_network;
 	if(net->bssht.bdRT2RTAggregation)
 		pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK;
-	else if(net->broadcom_cap_exist)
+	else if(net->broadcom_cap_exist){
 		pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
+	}
 	else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
 			(memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
-			(memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
-			(memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) )
+			(memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)){//||
+			//(memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ){
 		pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
+	}
 	else if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
 			(memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
 			(memcmp(net->bssid, PCI_RALINK, 3)==0) ||
@@ -405,6 +408,10 @@ void HTIOTPeerDetermine(struct ieee80211
 		pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS;
 	else if(memcmp(net->bssid, CISCO_BROADCOM, 3)==0)
 		pHTInfo->IOTPeer = HT_IOT_PEER_CISCO;
+        else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) ||
+			net->marvell_cap_exist){
+		pHTInfo->IOTPeer = HT_IOT_PEER_MARVELL;
+	}
 	else
 		pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
 
@@ -442,6 +449,18 @@ u8 HTIOTActIsDisableMCS14(struct ieee802
 	return ret;
  }
 
+u8 HTIOTActIsForcedCTS2Self(struct ieee80211_device *ieee, struct ieee80211_network *network)
+{
+        u8      retValue = 0;
+        //if(network->marvell_cap_exist)
+        if(ieee->pHTInfo->IOTPeer == HT_IOT_PEER_MARVELL)
+        {
+                retValue = 1;
+        }
+
+        return retValue;
+}
+
 
 /**
 * Function:	HTIOTActIsDisableMCS15
@@ -578,6 +597,23 @@ u8 HTIOTActIsCCDFsync(u8* PeerMacAddr)
 	return retValue;
 }
 
+//
+//  Send null data for to tell AP that we are awake.
+//
+bool
+HTIOTActIsNullDataPowerSaving(struct ieee80211_device* ieee,struct ieee80211_network *network)
+{
+	bool	retValue = false;
+
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	{
+		if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) // ||(pBssDesc->Vender == HT_IOT_PEER_ATHEROS && pBssDesc->SubTypeOfVender == HT_IOT_PEER_ATHEROS_DIR635))
+			return true;
+
+	}
+	return retValue;
+}
+
 void HTResetIOTSetting(
 	PRT_HIGH_THROUGHPUT		pHTInfo
 )
@@ -1071,6 +1107,13 @@ void HTOnAssocRsp(struct ieee80211_devic
 	// Config and configure A-MSDU setting
 	//
 	pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
+        if (ieee->rtllib_ap_sec_type &&
+           (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))){
+                if( (pHTInfo->IOTPeer== HT_IOT_PEER_ATHEROS) ||
+                                (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN) )
+                        pHTInfo->bCurrentAMPDUEnable = false;
+        }
+
 
 	nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize==0)?3839:7935;
 
@@ -1515,6 +1558,9 @@ void HTResetSelfAndSavePeerSetting(struc
 		bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid);
 		if(bIOTAction)
 			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14;
+		bIOTAction = HTIOTActIsForcedCTS2Self(ieee, pNetwork);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
 
 		bIOTAction = HTIOTActIsDisableMCS15(ieee);
 		if(bIOTAction)
@@ -1537,6 +1583,9 @@ void HTResetSelfAndSavePeerSetting(struc
 		if(bIOTAction)
 			pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC;
 
+		bIOTAction = HTIOTActIsNullDataPowerSaving(ieee, pNetwork);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_NULL_DATA_POWER_SAVING;
 
 	}
 	else
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,6 @@
 #include "ieee80211.h"
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include "rtl819x_TS.h"
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
@@ -304,7 +305,7 @@ PTS_COMMON_INFO SearchAdmitTRStream(stru
 		if(search_dir[dir] ==false )
 			continue;
 		list_for_each_entry(pRet, psearch_list, List){
-	//		IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
+	//		IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
 			if (memcmp(pRet->Addr, Addr, 6) == 0)
 				if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
 					if(pRet->TSpec.f.TSInfo.field.ucDirection == dir)
@@ -466,7 +467,7 @@ bool GetTs(
 					ResetRxTsEntry(tmp);
 				}
 
-				IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr));
+				IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr);
 				// Prepare TS Info releated field
 				pTSInfo->field.ucTrafficType = 0;			// Traffic type: WMM is reserved in this field
 				pTSInfo->field.ucTSID = UP;			// TSID
@@ -552,7 +553,7 @@ void RemoveTsEntry(
 void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr)
 {
 	PTS_COMMON_INFO	pTS, pTmpTS;
-	printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr));
+	printk("===========>RemovePeerTS,%pM\n", Addr);
 #if 1
 	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
 	{
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/ieee80211.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/ieee80211.h	2010-05-16 17:17:36.000000000 -0400
@@ -547,9 +547,6 @@ do { if (ieee80211_debug_level & (level)
 
 /* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
 
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
-
 /*
  * To use the debug system;
  *
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/Makefile linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,13 +1,15 @@
 NIC_SELECT = RTL8192E
 
-
 EXTRA_CFLAGS += -DRTL8192E
 EXTRA_CFLAGS += -std=gnu89
 EXTRA_CFLAGS += -O2
 EXTRA_CFLAGS += -DTHOMAS_TURBO
 EXTRA_CFLAGS += -DENABLE_DOT11D
 
-r8192_pci-objs :=		\
+EXTRA_CFLAGS += -DENABLE_IPS
+EXTRA_CFLAGS += -DENABLE_LPS
+
+r8192e_pci-objs :=		\
 	r8192E_core.o		\
 	r8180_93cx6.o		\
 	r8192E_wx.o		\
@@ -31,4 +33,5 @@ r8192_pci-objs :=		\
 	ieee80211/ieee80211_crypt_ccmp.o	\
 	ieee80211/ieee80211_crypt_wep.o
 
-obj-$(CONFIG_RTL8192E) += r8192_pci.o
+obj-$(CONFIG_RTL8192E) += r8192e_pci.o
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8180_93cx6.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8180_93cx6.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8180_93cx6.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8180_93cx6.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,7 @@
 
 static void eprom_cs(struct net_device *dev, short bit)
 {
-	if(bit)
+	if (bit)
 		write_nic_byte(dev, EPROM_CMD,
 			       (1<<EPROM_CS_SHIFT) | \
 			       read_nic_byte(dev, EPROM_CMD)); //enable EPROM
@@ -38,23 +38,23 @@ static void eprom_cs(struct net_device *
 static void eprom_ck_cycle(struct net_device *dev)
 {
 	write_nic_byte(dev, EPROM_CMD,
-		       (1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD));
+		       (1<<EPROM_CK_SHIFT) | read_nic_byte(dev, EPROM_CMD));
 	force_pci_posting(dev);
 	udelay(EPROM_DELAY);
 	write_nic_byte(dev, EPROM_CMD,
-		       read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT));
+		       read_nic_byte(dev, EPROM_CMD) & ~(1<<EPROM_CK_SHIFT));
 	force_pci_posting(dev);
 	udelay(EPROM_DELAY);
 }
 
 
-static void eprom_w(struct net_device *dev,short bit)
+static void eprom_w(struct net_device *dev, short bit)
 {
-	if(bit)
+	if (bit)
 		write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
-			       read_nic_byte(dev,EPROM_CMD));
+			       read_nic_byte(dev, EPROM_CMD));
 	else
-		write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\
+		write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
 			       &~(1<<EPROM_W_SHIFT));
 
 	force_pci_posting(dev);
@@ -66,10 +66,11 @@ static short eprom_r(struct net_device *
 {
 	short bit;
 
-	bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) );
+	bit = (read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT));
 	udelay(EPROM_DELAY);
 
-	if(bit) return 1;
+	if (bit)
+		return 1;
 	return 0;
 }
 
@@ -78,7 +79,7 @@ static void eprom_send_bits_string(struc
 {
 	int i;
 
-	for(i=0; i<len; i++){
+	for (i = 0; i < len; i++) {
 		eprom_w(dev, b[i]);
 		eprom_ck_cycle(dev);
 	}
@@ -88,37 +89,37 @@ static void eprom_send_bits_string(struc
 u32 eprom_read(struct net_device *dev, u32 addr)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
-	short read_cmd[]={1,1,0};
+	short read_cmd[] = {1, 1, 0};
 	short addr_str[8];
 	int i;
 	int addr_len;
 	u32 ret;
 
-	ret=0;
+	ret = 0;
         //enable EPROM programming
 	write_nic_byte(dev, EPROM_CMD,
 		       (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
 	force_pci_posting(dev);
 	udelay(EPROM_DELAY);
 
-	if (priv->epromtype==EPROM_93c56){
-		addr_str[7]=addr & 1;
-		addr_str[6]=addr & (1<<1);
-		addr_str[5]=addr & (1<<2);
-		addr_str[4]=addr & (1<<3);
-		addr_str[3]=addr & (1<<4);
-		addr_str[2]=addr & (1<<5);
-		addr_str[1]=addr & (1<<6);
-		addr_str[0]=addr & (1<<7);
-		addr_len=8;
-	}else{
-		addr_str[5]=addr & 1;
-		addr_str[4]=addr & (1<<1);
-		addr_str[3]=addr & (1<<2);
-		addr_str[2]=addr & (1<<3);
-		addr_str[1]=addr & (1<<4);
-		addr_str[0]=addr & (1<<5);
-		addr_len=6;
+	if (priv->epromtype == EPROM_93c56) {
+		addr_str[7] = addr & 1;
+		addr_str[6] = addr & (1<<1);
+		addr_str[5] = addr & (1<<2);
+		addr_str[4] = addr & (1<<3);
+		addr_str[3] = addr & (1<<4);
+		addr_str[2] = addr & (1<<5);
+		addr_str[1] = addr & (1<<6);
+		addr_str[0] = addr & (1<<7);
+		addr_len = 8;
+	} else {
+		addr_str[5] = addr & 1;
+		addr_str[4] = addr & (1<<1);
+		addr_str[3] = addr & (1<<2);
+		addr_str[2] = addr & (1<<3);
+		addr_str[1] = addr & (1<<4);
+		addr_str[0] = addr & (1<<5);
+		addr_len = 6;
 	}
 	eprom_cs(dev, 1);
 	eprom_ck_cycle(dev);
@@ -129,7 +130,7 @@ u32 eprom_read(struct net_device *dev, u
 	//I'm unsure if it is necessary, but anyway shouldn't hurt
 	eprom_w(dev, 0);
 
-	for(i=0;i<16;i++){
+	for (i = 0; i < 16; i++) {
 		//eeprom needs a clk cycle between writing opcode&adr
 		//and reading data. (eeprom outs a dummy 0)
 		eprom_ck_cycle(dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8180_93cx6.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8180_93cx6.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8180_93cx6.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8180_93cx6.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,17 +1,18 @@
-/*
-	This is part of rtl8187 OpenSource driver
-	Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
-	Released under the terms of GPL (General Public Licence)
-
-	Parts of this driver are based on the GPL part of the official realtek driver
-	Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
-	Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
-
-	We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
-*/
-
-/*This files contains card eeprom (93c46 or 93c56) programming routines*/
-/*memory is addressed by WORDS*/
+/* r8180_93cx6.h - 93c46 or 93c56 eeprom card programming routines
+ *
+ * This is part of rtl8187 OpenSource driver
+ * Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
+ * Released under the terms of GPL (General Public Licence)
+ * Parts of this driver are based on the GPL part of the official realtek driver
+ *
+ * Parts of this driver are based on the rtl8180 driver skeleton from
+ * Patric Schenke & Andres Salomon.
+ *
+ * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
+ *
+ * We want to thank the authors of the above mentioned projects and to
+ * the authors of the Ndiswrapper project.
+ */
 
 #include "r8192E.h"
 #include "r8192E_hw.h"
@@ -36,5 +37,5 @@
 #define EPROM_TXPW2 0x1b
 #define EPROM_TXPW1 0x3d
 
-
-u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word
+/* Reads a 16 bits word. */
+u32 eprom_read(struct net_device *dev, u32 addr);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8190_rtl8256.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8190_rtl8256.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8190_rtl8256.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8190_rtl8256.c	2010-05-16 17:17:36.000000000 -0400
@@ -429,11 +429,12 @@ SetRFPowerState8190(
 	bool bResult = true;
 	//u8 eRFPath;
 	u8	i = 0, QueueID = 0;
-	ptx_ring	head=NULL,tail=NULL;
+	//ptx_ring	head=NULL,tail=NULL;
+	struct rtl8192_tx_ring  *ring = NULL;
 
 	if(priv->SetRFPowerStateInProgress == true)
 		return false;
-	RT_TRACE(COMP_POWER, "===========> SetRFPowerState8190()!\n");
+	//RT_TRACE(COMP_PS, "===========> SetRFPowerState8190()!\n");
 	priv->SetRFPowerStateInProgress = true;
 
 	switch(priv->rf_chip)
@@ -442,11 +443,11 @@ SetRFPowerState8190(
 		switch( eRFPowerState )
 		{
 			case eRfOn:
-				RT_TRACE(COMP_POWER, "SetRFPowerState8190() eRfOn !\n");
+				//RT_TRACE(COMP_PS, "SetRFPowerState8190() eRfOn !\n");
 						//RXTX enable control: On
 					//for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
-					//	PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2);
-				#ifdef RTL8190P
+					//	PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2);
+#ifdef RTL8190P
 				if(priv->rf_type == RF_2T4R)
 				{
 					//enable RF-Chip A/B
@@ -479,36 +480,92 @@ SetRFPowerState8190(
 					//analog to digital part2 on
 					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1800, 0x3); // 0x880[12:11]
 				}
-				#else
-				write_nic_byte(dev, ANAPAR, 0x37);//160MHz
-				write_nic_byte(dev, MacBlkCtrl, 0x17); // 0x403
-				mdelay(1);
-				//enable clock 80/88 MHz
+				else if(priv->rf_type == RF_1T1R)	//RF-C
+				{
+					//enable RF-Chip C/D
+					rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4]
+					//analog to digital on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x400, 0x1);// 0x88c[10]
+					//digital to analog on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x80, 0x1); // 0x880[7]
+					//rx antenna on
+					rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x4, 0x1);// 0xc04[2]
+					//rx antenna on
+					rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x4, 0x1);// 0xd04[2]
+					//analog to digital part2 on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x800, 0x1); // 0x880[11]
+				}
 
-				priv->bHwRfOffAction = 0;
-				//}
+#elif defined RTL8192E
+				// turn on RF
+				if((priv->ieee80211->eRFPowerState == eRfOff) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC))
+				{ // The current RF state is OFF and the RF OFF level is halting the NIC, re-initialize the NIC.
+					bool rtstatus = true;
+					u32 InitilizeCount = 3;
+					do
+					{
+						InitilizeCount--;
+						priv->RegRfOff = false;
+						rtstatus = NicIFEnableNIC(dev);
+					}while( (rtstatus != true) &&(InitilizeCount >0) );
 
-				// Baseband reset 2008.09.30 add
-				write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0));
+					if(rtstatus != true)
+					{
+						RT_TRACE(COMP_ERR,"%s():Initialize Adapter fail,return\n",__FUNCTION__);
+						priv->SetRFPowerStateInProgress = false;
+						return false;
+					}
 
-				//2 AFE
-				// 2008.09.30 add
-				rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x1); // 0x884
-				//analog to digital part2 on
-					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3);		// 0x880[6:5]
-				//digital to analog on
-				rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x13); // 0x880[4:3]
-				//analog to digital on
-				rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0xf03);// 0x88c[9:8]
-				//rx antenna on
-				//PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
-				//rx antenna on 2008.09.30 mark
-				//PHY_SetBBReg(Adapter, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
+					RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
+				} else {
+					write_nic_byte(dev, ANAPAR, 0x37);//160MHz
+					//write_nic_byte(dev, MacBlkCtrl, 0x17); // 0x403
+					mdelay(1);
+					//enable clock 80/88 MHz
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x1); // 0x880[2]
+					priv->bHwRfOffAction = 0;
+					//}
 
-				//2 RF
-				//enable RF-Chip A/B
+					//RF-A, RF-B
+					//enable RF-Chip A/B
 					rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1);		// 0x860[4]
-				rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x1);		// 0x864[4]
+					//analog to digital on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8]
+					//digital to analog on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3]
+					//rx antenna on
+					rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
+					//rx antenna on
+					rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
+					//analog to digital part2 on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); 	// 0x880[6:5]
+
+					// Baseband reset 2008.09.30 add
+					//write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0));
+
+				//2 	AFE
+					// 2008.09.30 add
+					//rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x1); // 0x884
+					//analog to digital part2 on
+					//rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3);		// 0x880[6:5]
+
+
+					//digital to analog on
+					//rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x13); // 0x880[4:3]
+					//analog to digital on
+					//rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0xf03);// 0x88c[9:8]
+					//rx antenna on
+					//PHY_SetBBReg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
+					//rx antenna on 2008.09.30 mark
+					//PHY_SetBBReg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
+
+				//2 	RF
+					//enable RF-Chip A/B
+					//rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1);		// 0x860[4]
+					//rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x1);		// 0x864[4]
+
+				}
+
 				#endif
 						break;
 
@@ -517,119 +574,137 @@ SetRFPowerState8190(
 				// By Bruce, 2008-01-16.
 				//
 			case eRfSleep:
-			case eRfOff:
-				RT_TRACE(COMP_POWER, "SetRFPowerState8190() eRfOff/Sleep !\n");
-				if (pPSC->bLeisurePs)
+			{
+				// HW setting had been configured with deeper mode.
+				if(priv->ieee80211->eRFPowerState == eRfOff)
+					break;
+
+				// Update current RF state variable.
+				//priv->ieee80211->eRFPowerState = eRFPowerState;
+
+				//if (pPSC->bLeisurePs)
 				{
 					for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; )
 					{
-						switch(QueueID) {
-							case MGNT_QUEUE:
-								tail=priv->txmapringtail;
-								head=priv->txmapringhead;
-								break;
+							ring = &priv->tx_ring[QueueID];
 
-							case BK_QUEUE:
-								tail=priv->txbkpringtail;
-								head=priv->txbkpringhead;
-								break;
+							if(skb_queue_len(&ring->queue) == 0)
+							{
+								QueueID++;
+								continue;
+							}
+							else
+							{
+								RT_TRACE((COMP_POWER|COMP_RF), "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID);
+								udelay(10);
+								i++;
+							}
 
-							case BE_QUEUE:
-								tail=priv->txbepringtail;
-								head=priv->txbepringhead;
+							if(i >= MAX_DOZE_WAITING_TIMES_9x)
+							{
+								RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID);
 								break;
+							}
+						}
+				}
 
-							case VI_QUEUE:
-								tail=priv->txvipringtail;
-								head=priv->txvipringhead;
+				//if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
+#ifdef RTL8190P
+				{
+					PHY_SetRtl8190pRfOff(dev);
+				}
+				//else if(Adapter->HardwareType == HARDWARE_TYPE_RTL8192E)
+#elif defined RTL8192E
+				{
+					PHY_SetRtl8192eRfOff(dev);
+				}
+#endif
+			}
 								break;
 
-							case VO_QUEUE:
-								tail=priv->txvopringtail;
-								head=priv->txvopringhead;
-								break;
+			case eRfOff:
+				//RT_TRACE(COMP_PS, "SetRFPowerState8190() eRfOff/Sleep !\n");
 
-							default:
-								tail=head=NULL;
-								break;
-						}
-						if(tail == head)
+				// Update current RF state variable.
+				//priv->ieee80211->eRFPowerState = eRFPowerState;
+
+				//
+				// Disconnect with Any AP or STA.
+				//
+				for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; )
+				{
+					ring = &priv->tx_ring[QueueID];
+
+					if(skb_queue_len(&ring->queue) == 0)
 						{
-							//DbgPrint("QueueID = %d", QueueID);
 							QueueID++;
 							continue;
 						}
 						else
 						{
-							RT_TRACE(COMP_POWER, "eRf Off/Sleep: %d times BusyQueue[%d] !=0 before doze!\n", (i+1), QueueID);
+							RT_TRACE(COMP_POWER,
+							"eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID);
 							udelay(10);
 							i++;
 						}
 
 						if(i >= MAX_DOZE_WAITING_TIMES_9x)
 						{
-							RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times BusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID);
+							RT_TRACE(COMP_POWER, "\n\n\n SetZebraRFPowerState8185B(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID);
 							break;
 						}
 					}
-				}
-				#ifdef RTL8190P
-				if(priv->rf_type == RF_2T4R)
+
+				//if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
+#if defined RTL8190P
 				{
-					//disable RF-Chip A/B
-					rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);		// 0x860[4]
+					PHY_SetRtl8190pRfOff(dev);
 				}
-				//disable RF-Chip C/D
-				rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x0); // 0x868[4]
-				//analog to digital off, for power save
-				rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
-				//digital to analog off, for power save
-				rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e0, 0x0); // 0x880[8:5]
-				//rx antenna off
-				rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0]
-				//rx antenna off
-				rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0]
-				//analog to digital part2 off, for power save
-				rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e00, 0x0); // 0x880[12:9]
-#else //8192E
-					//2 RF
-				//disable RF-Chip A/B
-				rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);		// 0x860[4]
-					rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x0);		// 0x864[4]
-					//2 AFE
-				//analog to digital off, for power save
-					//PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
-					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0x0); //  2008.09.30 Modify
-				//digital to analog off, for power save
-					//PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter1, 0x18, 0x0); // 0x880[4:3]
-					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x0); // 0x880 2008.09.30 Modify
-					//rx antenna off  2008.09.30 mark
-					//PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0]
-					//rx antenna off  2008.09.30 mark
-					//PHY_SetBBReg(Adapter, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0]
-				//analog to digital part2 off, for power save
-					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0);		// 0x880[6:5]
-					// 2008.09.30 add
-					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x0); // 0x884
-
+				//else if(Adapter->HardwareType == HARDWARE_TYPE_RTL8192E)
+#elif defined RTL8192E
+				{
+					//if(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC) && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
+					if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC))
+					{ // Disable all components.
+						//
+						// Note:
+						//	NicIFSetLinkStatus is a big problem when we indicate the status to OS,
+						//	the OS(XP) will reset. But now, we cnnot find why the NIC is hard to receive
+						//	packets after RF ON. Just keep this function here and still work to find out the root couse.
+						//	By Bruce, 2009-05-01.
+						//
+						//NicIFSetLinkStatus( Adapter, RT_MEDIA_DISCONNECT );
+						//if HW radio of , need to indicate scan complete first for not be reset.
+						//if(MgntScanInProgress(pMgntInfo))
+						//	MgntResetScanProcess( Adapter );
 
-					//disable clock 80/88 MHz 2008.09.30 mark
-					//PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter1, 0x4, 0x0); // 0x880[2]
-					//2 BB
-					// Baseband reset 2008.09.30 add
-					write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0)); // 0x101
-					//MAC: off
-					write_nic_byte(dev, MacBlkCtrl, 0x0); // 0x403
-					//slow down cpu/lbus clock from 160MHz to Lower
-					write_nic_byte(dev, ANAPAR, 0x07); // 0x 17 40MHz
-				priv->bHwRfOffAction = 0;
-				//}
+						// <1> Disable Interrupt
+						//rtl8192_irq_disable(dev);
+						// <2> Stop all timer
+						//MgntCancelAllTimer(Adapter);
+						// <3> Disable Adapter
+						//NicIFHaltAdapter(Adapter, false);
+						NicIFDisableNIC(dev);
+						RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
+					}
+					else if (!(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC))
+					{ // Normal case.
+				  		// IPS should go to this.
+						PHY_SetRtl8192eRfOff(dev);
+					}
+				}
+#else
+				else
+				{
+					RT_TRACE(COMP_DBG,DBG_TRACE,("It is not 8190Pci and 8192PciE \n"));
+				}
 				#endif
+
 					break;
 
 			default:
 					bResult = false;
-					RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknown state to set: 0x%X!!!\n", eRFPowerState);
+					RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state to set: 0x%X!!!\n", eRFPowerState);
 					break;
 		}
 
@@ -644,64 +719,11 @@ SetRFPowerState8190(
 	{
 		// Update current RF state variable.
 		priv->ieee80211->eRFPowerState = eRFPowerState;
-
-		switch(priv->rf_chip )
-		{
-			case RF_8256:
-			switch(priv->ieee80211->eRFPowerState)
-			{
-				case eRfOff:
-				//
-				//If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015
-				//
-					if(priv->ieee80211->RfOffReason==RF_CHANGE_BY_IPS )
-					{
-						#ifdef TO_DO
-						Adapter->HalFunc.LedControlHandler(Adapter,LED_CTL_NO_LINK);
-						#endif
-					}
-					else
-					{
-					// Turn off LED if RF is not ON.
-						#ifdef TO_DO
-						Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF);
-						#endif
-					}
-					break;
-
-				case eRfOn:
-				// Turn on RF we are still linked, which might happen when
-				// we quickly turn off and on HW RF. 2006.05.12, by rcnjko.
-					if( priv->ieee80211->state == IEEE80211_LINKED)
-					{
-						#ifdef TO_DO
-						Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK);
-						#endif
-					}
-					else
-					{
-					// Turn off LED if RF is not ON.
-						#ifdef TO_DO
-						Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK);
-						#endif
-					}
-					break;
-
-				default:
-			// do nothing.
-					break;
-			}// Switch RF state
-
-			break;
-
-			default:
-				RT_TRACE(COMP_ERR, "SetRFPowerState8190(): Unknown RF type\n");
-				break;
-		}// Switch RFChipID
 	}
 
+	//printk("%s()priv->ieee80211->eRFPowerState:%s\n" ,__func__,priv->ieee80211->eRFPowerState == eRfOn ? "On" : "Off");
 	priv->SetRFPowerStateInProgress = false;
-	RT_TRACE(COMP_POWER, "<=========== SetRFPowerState8190() bResult = %d!\n", bResult);
+	//RT_TRACE(COMP_PS, "<=========== SetRFPowerState8190() bResult = %d!\n", bResult);
 	return bResult;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8190_rtl8256.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8190_rtl8256.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8190_rtl8256.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8190_rtl8256.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,28 +1,33 @@
-/*
-  This is part of the rtl8180-sa2400 driver
-  released under the GPL (See file COPYING for details).
-  Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
-
-  This files contains programming code for the rtl8256
-  radio frontend.
-
-  *Many* thanks to Realtek Corp. for their great support!
-
-*/
+/* r8190_rtl8256.h - rtl8256 radio frontend
+ *
+ * This is part of the rtl8180-sa2400 driver
+ * released under the GPL (See file COPYING for details).
+ * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Many thanks to Realtek Corp. for their great support!
+ */
 
-#ifndef RTL8225H
-#define RTL8225H
+#ifndef RTL8225_H
+#define RTL8225_H
 
 #ifdef RTL8190P
-#define RTL819X_TOTAL_RF_PATH	4
+#define RTL819X_TOTAL_RF_PATH 4
 #else
-#define RTL819X_TOTAL_RF_PATH 2 //for 8192E
+#define RTL819X_TOTAL_RF_PATH 2 /* for 8192E */
 #endif
-extern void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth);
-extern RT_STATUS PHY_RF8256_Config(struct net_device* dev);
-extern RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev);
-extern void PHY_SetRF8256CCKTxPower(struct net_device*	dev, u8	powerlevel);
-extern void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel);
-extern bool MgntActSet_RF_State(struct net_device* dev, RT_RF_POWER_STATE StateToSet, RT_RF_CHANGE_SOURCE ChangeSource);
 
-#endif
+extern void PHY_SetRF8256Bandwidth(struct net_device *dev,
+				   HT_CHANNEL_WIDTH Bandwidth);
+
+extern RT_STATUS PHY_RF8256_Config(struct net_device *dev);
+
+extern RT_STATUS phy_RF8256_Config_ParaFile(struct net_device *dev);
+
+extern void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8 powerlevel);
+extern void PHY_SetRF8256OFDMTxPower(struct net_device *dev, u8 powerlevel);
+
+extern bool MgntActSet_RF_State(struct net_device *dev,
+				RT_RF_POWER_STATE StateToSet,
+				RT_RF_CHANGE_SOURCE ChangeSource);
+
+#endif /* RTL8225_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8192E_core.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8192E_core.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8192E_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8192E_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -47,6 +47,7 @@
 
 //#define CONFIG_RTL8192_IO_MAP
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include "r8192E_hw.h"
 #include "r8192E.h"
@@ -66,7 +67,7 @@
 #endif
 
 #ifdef ENABLE_DOT11D
-#include "dot11d.h"
+#include "ieee80211/dot11d.h"
 #endif
 
 //set here to open your trace code. //WB
@@ -75,7 +76,7 @@ u32 rt_global_debug_component = \
 			//	COMP_EPROM   	|
 		//		COMP_PHY	|
 		//		COMP_RF		|
-				COMP_FIRMWARE	|
+//				COMP_FIRMWARE	|
 			//	COMP_TRACE	|
 		//		COMP_DOWN	|
 		//		COMP_SWBW	|
@@ -343,6 +344,141 @@ void write_nic_word(struct net_device *d
 
 #endif /* RTL_IO_MAP */
 
+u8 rtl8192e_ap_sec_type(struct ieee80211_device *ieee)
+{
+	//struct r8192_priv* priv = ieee80211_priv(dev);
+	//struct ieee80211_device *ieee = priv->ieee80211;
+
+	static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
+	static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
+	int wpa_ie_len= ieee->wpa_ie_len;
+	struct ieee80211_crypt_data* crypt;
+	int encrypt;
+
+	crypt = ieee->crypt[ieee->tx_keyidx];
+
+	encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) ||\
+		  (ieee->host_encrypt && crypt && crypt->ops && \
+		   (0 == strcmp(crypt->ops->name,"WEP")));
+
+	/* simply judge  */
+	if(encrypt && (wpa_ie_len == 0)) {
+		// wep encryption, no N mode setting */
+		return SEC_ALG_WEP;
+	} else if((wpa_ie_len != 0)) {
+		// parse pairwise key type */
+		if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) ||
+				((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
+			return SEC_ALG_CCMP;
+		else
+			return SEC_ALG_TKIP;
+	} else {
+		return SEC_ALG_NONE;
+	}
+}
+
+void
+rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val)
+{
+	struct r8192_priv* priv = ieee80211_priv(dev);
+
+	switch(variable)
+	{
+
+		case HW_VAR_BSSID:
+			write_nic_dword(dev, BSSIDR, ((u32*)(val))[0]);
+			write_nic_word(dev, BSSIDR+2, ((u16*)(val+2))[0]);
+		break;
+
+		case HW_VAR_MEDIA_STATUS:
+		{
+			RT_OP_MODE	OpMode = *((RT_OP_MODE *)(val));
+			//LED_CTL_MODE	LedAction = LED_CTL_NO_LINK;
+			u8		btMsr = read_nic_byte(dev, MSR);
+
+			btMsr &= 0xfc;
+
+			switch(OpMode)
+			{
+			case RT_OP_MODE_INFRASTRUCTURE:
+				btMsr |= MSR_INFRA;
+				//LedAction = LED_CTL_LINK;
+				break;
+
+			case RT_OP_MODE_IBSS:
+				btMsr |= MSR_ADHOC;
+				// led link set seperate
+				break;
+
+			case RT_OP_MODE_AP:
+				btMsr |= MSR_AP;
+				//LedAction = LED_CTL_LINK;
+				break;
+
+			default:
+				btMsr |= MSR_NOLINK;
+				break;
+			}
+
+			write_nic_byte(dev, MSR, btMsr);
+
+			//priv->ieee80211->LedControlHandler(dev, LedAction);
+		}
+		break;
+
+		case HW_VAR_CECHK_BSSID:
+		{
+			u32	RegRCR, Type;
+
+			Type = ((u8*)(val))[0];
+			//priv->ieee80211->GetHwRegHandler(dev, HW_VAR_RCR, (u8*)(&RegRCR));
+			RegRCR = read_nic_dword(dev,RCR);
+			priv->ReceiveConfig = RegRCR;
+
+			if (Type == true)
+				RegRCR |= (RCR_CBSSID);
+			else if (Type == false)
+				RegRCR &= (~RCR_CBSSID);
+
+			//priv->ieee80211->SetHwRegHandler( dev, HW_VAR_RCR, (u8*)(&RegRCR) );
+			write_nic_dword(dev, RCR,RegRCR);
+			priv->ReceiveConfig = RegRCR;
+
+		}
+		break;
+
+		case HW_VAR_SLOT_TIME:
+		{
+			//PSTA_QOS	pStaQos = Adapter->MgntInfo.pStaQos;
+			//AC_CODING	eACI;
+
+			priv->slot_time = val[0];
+			write_nic_byte(dev, SLOT_TIME, val[0]);
+
+		}
+		break;
+
+		case HW_VAR_ACK_PREAMBLE:
+		{
+			u32 regTmp = 0;
+			priv->short_preamble = (bool)(*(u8*)val );
+			regTmp = priv->basic_rate;
+			if (priv->short_preamble)
+				regTmp |= BRSR_AckShortPmb;
+			write_nic_dword(dev, RRSR, regTmp);
+		}
+		break;
+
+		case HW_VAR_CPU_RST:
+			write_nic_dword(dev, CPU_GEN, ((u32*)(val))[0]);
+		break;
+
+		default:
+		break;
+	}
+
+}
+
 
 ///////////////////////////////////////////////////////////
 
@@ -365,11 +501,6 @@ void rtl8192_restart(struct work_struct
 //void rtl8192_rq_tx_ack(struct work_struct *work);
 
 void watch_dog_timer_callback(unsigned long data);
-#ifdef ENABLE_IPS
-void IPSEnter(struct net_device *dev);
-void IPSLeave(struct net_device *dev);
-void InactivePsWorkItemCallback(struct net_device *dev);
-#endif
 /****************************************************************************
    -----------------------------PROCFS STUFF-------------------------
 *****************************************************************************/
@@ -707,7 +838,7 @@ static void rtl8192_irq_enable(struct ne
 }
 
 
-static void rtl8192_irq_disable(struct net_device *dev)
+void rtl8192_irq_disable(struct net_device *dev)
 {
 	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 
@@ -717,6 +848,7 @@ static void rtl8192_irq_disable(struct n
 }
 
 
+#if 0
 static void rtl8192_set_mode(struct net_device *dev,int mode)
 {
 	u8 ecmd;
@@ -727,7 +859,7 @@ static void rtl8192_set_mode(struct net_
 	ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
 	write_nic_byte(dev, EPROM_CMD, ecmd);
 }
-
+#endif
 
 void rtl8192_update_msr(struct net_device *dev)
 {
@@ -861,7 +993,7 @@ static void rtl8192_free_tx_ring(struct
     ring->desc = NULL;
 }
 
-
+#if 0
 static void rtl8192_beacon_disable(struct net_device *dev)
 {
 	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
@@ -873,38 +1005,116 @@ static void rtl8192_beacon_disable(struc
 	reg &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
 	write_nic_dword(priv->ieee80211->dev, INTA_MASK, reg);
 }
+#endif
 
-void rtl8192_rtx_disable(struct net_device *dev)
+void PHY_SetRtl8192eRfOff(struct net_device* dev	)
 {
-	u8 cmd;
+	//struct r8192_priv *priv = ieee80211_priv(dev);
+
+	//disable RF-Chip A/B
+	rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);
+	//analog to digital off, for power save
+	rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0);
+	//digital to analog off, for power save
+	rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0);
+	//rx antenna off
+	rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);
+	//rx antenna off
+	rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);
+	//analog to digital part2 off, for power save
+	rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0);
+	rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x0);
+	// Analog parameter!!Change bias and Lbus control.
+	write_nic_byte(dev, ANAPAR_FOR_8192PciE, 0x07);
+
+}
+
+void rtl8192_halt_adapter(struct net_device *dev, bool reset)
+{
+	//u8 	cmd;
 	struct r8192_priv *priv = ieee80211_priv(dev);
-        int i;
+	int i;
+	u8	OpMode;
+	u8	u1bTmp;
+	u32	ulRegRead;
+
+	OpMode = RT_OP_MODE_NO_LINK;
+	priv->ieee80211->SetHwRegHandler(dev, HW_VAR_MEDIA_STATUS, &OpMode);
 
+#if 1
+	if(!priv->ieee80211->bSupportRemoteWakeUp)
+	{
+		u1bTmp = 0x0;	// disable tx/rx. In 8185 we write 0x10 (Reset bit), but here we make reference to WMAC and wirte 0x0. 2006.11.21 Emily
+		//priv->ieee80211->SetHwRegHandler(dev, HW_VAR_COMMAND, &u1bTmp );	// Using HW_VAR_COMMAND instead of writing CMDR directly. Rewrited by Annie, 2006-04-07.
+		write_nic_byte(dev, CMDR, u1bTmp);
+	}
+#else
 	cmd=read_nic_byte(dev,CMDR);
-//	if(!priv->ieee80211->bSupportRemoteWakeUp) {
-		write_nic_byte(dev, CMDR, cmd &~ \
-				(CR_TE|CR_RE));
-//	}
-	force_pci_posting(dev);
-	mdelay(30);
+	write_nic_byte(dev, CMDR, cmd &~ (CR_TE|CR_RE));
+#endif
 
-        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
-                skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
-        }
-        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
-                skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
-        }
+	mdelay(20);
+
+	if(!reset)
+	{
+		//PlatformStallExecution(150000);
+		mdelay(150);
 
+#ifdef RTL8192E
+			priv->bHwRfOffAction = 2;
+#endif
+
+		//
+		// Call MgntActSet_RF_State instead to prevent RF config race condition.
+		// By Bruce, 2008-01-17.
+		//
+		if(!priv->ieee80211->bSupportRemoteWakeUp)
+		{
+			//MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_INIT);
+			//MgntActSet_RF_State(Adapter, eRfOff, Adapter->MgntInfo.RfOffReason);
+			//if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
+
+			PHY_SetRtl8192eRfOff(dev);
+
+			// 2006.11.30. System reset bit
+			//priv->ieee80211->GetHwRegHandler(dev, HW_VAR_CPU_RST, (u32*)(&ulRegRead) );
+			ulRegRead = read_nic_dword(dev,CPU_GEN);
+			ulRegRead|=CPU_GEN_SYSTEM_RESET;
+			//priv->ieee80211->SetHwRegHandler(dev, HW_VAR_CPU_RST, &ulRegRead);
+			write_nic_dword(dev,CPU_GEN, ulRegRead);
+		}
+	 	else
+		{
+			//2008.06.03 for WOL
+			write_nic_dword(dev, WFCRC0, 0xffffffff);
+			write_nic_dword(dev, WFCRC1, 0xffffffff);
+			write_nic_dword(dev, WFCRC2, 0xffffffff);
+
+			//Write PMR register
+			write_nic_byte(dev, PMR, 0x5);
+			//Disable tx, enanble rx
+			write_nic_byte(dev, MacBlkCtrl, 0xa);
+		}
+	}
+
+	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+		skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
+	}
+	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+		skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
+	}
 
 	skb_queue_purge(&priv->skb_queue);
 	return;
 }
 
+#if 0
 static void rtl8192_reset(struct net_device *dev)
 {
     rtl8192_irq_disable(dev);
     printk("This is RTL819xP Reset procedure\n");
 }
+#endif
 
 static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
 inline u16 rtl8192_rate2rate(short rate)
@@ -954,6 +1164,12 @@ static void rtl8192_hard_data_xmit(struc
 	/* shall not be referred by command packet */
 	assert(queue_index != TXCMD_QUEUE);
 
+	if((priv->bHwRadioOff == true)||(!priv->up))
+	{
+		kfree_skb(skb);
+		return;
+	}
+
 	//spin_lock_irqsave(&priv->tx_lock,flags);
 
         memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
@@ -996,6 +1212,13 @@ static int rtl8192_hard_start_xmit(struc
         cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
         u8 queue_index = tcb_desc->queue_index;
 
+        if(queue_index != TXCMD_QUEUE){
+		if((priv->bHwRadioOff == true)||(!priv->up))
+		{
+               	 	kfree_skb(skb);
+                	return 0;
+            	}
+        }
 
 	//spin_lock_irqsave(&priv->tx_lock,flags);
 
@@ -1379,6 +1602,15 @@ short rtl8192_tx(struct net_device *dev,
     u8*   pda_addr = NULL;
     int   idx;
 
+    if(priv->bdisable_nic){
+       	RT_TRACE(COMP_ERR,"%s: ERR!! Nic is disabled! Can't tx packet len=%d qidx=%d!!!\n", __FUNCTION__, skb->len, tcb_desc->queue_index);
+		return skb->len;
+    }
+
+#ifdef ENABLE_LPS
+	priv->ieee80211->bAwakePktSent = true;
+#endif
+
     mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
     /* collect the tx packets statitcs */
     pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI);
@@ -1481,6 +1713,7 @@ short rtl8192_tx(struct net_device *dev,
     if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
 	    RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \
 			    tcb_desc->queue_index,ring->idx, idx,skb->len);
+	    spin_unlock_irqrestore(&priv->irq_th_lock,flags);
 	    return skb->len;
     }
 
@@ -1575,7 +1808,7 @@ static short rtl8192_alloc_rx_desc_ring(
             return 0;
         priv->rx_buf[i] = skb;
         mapping = (dma_addr_t *)skb->cb;
-        *mapping = pci_map_single(priv->pdev, skb->tail,//skb_tail_pointer(skb),
+        *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb),
                 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
 
         entry->BufferAddress = cpu_to_le32(*mapping);
@@ -1779,7 +2012,7 @@ static void rtl8192_qos_activate(struct
 				(((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
 				(((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
 				((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
-		printk("===>u4bAcParam:%x, ", u4bAcParam);
+		//printk("===>u4bAcParam:%x, ", u4bAcParam);
 		write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
 		//write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
 	}
@@ -1964,11 +2197,24 @@ void rtl8192_update_ratr_table(struct ne
 	write_nic_byte(dev, UFWP, 1);
 }
 
+#if 0
 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
+#endif
+
 static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
 {
 #if 1
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device *ieee = priv->ieee80211;
+	if (ieee->rtllib_ap_sec_type &&
+	   (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))) {
+		return false;
+	} else {
+		return true;
+	}
+#else
 	struct r8192_priv* priv = ieee80211_priv(dev);
 	struct ieee80211_device* ieee = priv->ieee80211;
         int wpa_ie_len= ieee->wpa_ie_len;
@@ -1995,18 +2241,6 @@ static bool GetNmodeSupportBySecCfg8190P
 		return true;
 	}
 
-#if 0
-        //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
-        //We can't force in G mode if Pairwie key is AES and group key is TKIP
-        if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption)  ||
-           (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) ||
-           (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption))
-        {
-                return  false;
-        }
-        else
-                return true;
-#endif
 	return true;
 #endif
 }
@@ -2080,7 +2314,7 @@ static void rtl8192_SetWirelessMode(stru
 			wireless_mode = WIRELESS_MODE_B;
 		}
 	}
-#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
+#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
 	ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
 #endif
 	priv->ieee80211->mode = wireless_mode;
@@ -2127,7 +2361,19 @@ short rtl8192_is_tx_queue_empty(struct n
 }
 static void rtl8192_hw_sleep_down(struct net_device *dev)
 {
-	RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&priv->rf_ps_lock,flags);
+	if (priv->RFChangeInProgress) {
+		spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
+		RT_TRACE(COMP_RF, "rtl8192_hw_sleep_down(): RF Change in progress! \n");
+		printk("rtl8192_hw_sleep_down(): RF Change in progress!\n");
+		return;
+	}
+	spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
+	//RT_TRACE(COMP_PS, "%s()============>come to sleep down\n", __FUNCTION__);
+
 	MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
 }
 static void rtl8192_hw_sleep_wq (struct work_struct *work)
@@ -2138,21 +2384,29 @@ static void rtl8192_hw_sleep_wq (struct
         struct delayed_work *dwork = container_of(work,struct delayed_work,work);
         struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
         struct net_device *dev = ieee->dev;
-	//printk("=========>%s()\n", __FUNCTION__);
+
         rtl8192_hw_sleep_down(dev);
 }
-//	printk("dev is %d\n",dev);
-//	printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
+
 static void rtl8192_hw_wakeup(struct net_device* dev)
 {
-//	u32 flags = 0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	unsigned long flags = 0;
 
-//	spin_lock_irqsave(&priv->ps_lock,flags);
-	RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
+	spin_lock_irqsave(&priv->rf_ps_lock,flags);
+	if (priv->RFChangeInProgress) {
+		spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
+		RT_TRACE(COMP_RF, "rtl8192_hw_wakeup(): RF Change in progress! \n");
+		printk("rtl8192_hw_wakeup(): RF Change in progress! schedule wake up task again\n");
+		queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->hw_wakeup_wq,MSECS(10));//PowerSave is not supported if kernel version is below 2.6.20
+		return;
+	}
+	spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
+
+	//RT_TRACE(COMP_PS, "%s()============>come to wake up\n", __FUNCTION__);
 	MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
-	//FIXME: will we send package stored while nic is sleep?
-//	spin_unlock_irqrestore(&priv->ps_lock,flags);
 }
+
 void rtl8192_hw_wakeup_wq (struct work_struct *work)
 {
 //	struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
@@ -2169,7 +2423,6 @@ void rtl8192_hw_wakeup_wq (struct work_s
 #define MAX_SLEEP_TIME 10000
 static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
 {
-
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
 	u32 rb = jiffies;
@@ -2177,58 +2430,55 @@ static void rtl8192_hw_to_sleep(struct n
 
 	spin_lock_irqsave(&priv->ps_lock,flags);
 
-	/* Writing HW register with 0 equals to disable
-	 * the timer, that is not really what we want
-	 */
-	tl -= MSECS(4+16+7);
-
-	//if(tl == 0) tl = 1;
-
-	/* FIXME HACK FIXME HACK */
-//	force_pci_posting(dev);
-	//mdelay(1);
-
-//	rb = read_nic_dword(dev, TSFTR);
+	// Writing HW register with 0 equals to disable
+	// the timer, that is not really what we want
+	//
+	tl -= MSECS(8+16+7);
 
-	/* If the interval in witch we are requested to sleep is too
-	 * short then give up and remain awake
-	 */
+	// If the interval in witch we are requested to sleep is too
+	// short then give up and remain awake
+	// when we sleep after send null frame, the timer will be too short to sleep.
+	//
 	if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
-		||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
+			||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
 		spin_unlock_irqrestore(&priv->ps_lock,flags);
-		printk("too short to sleep\n");
+		printk("too short to sleep::%x, %x, %lx\n",tl, rb,  MSECS(MIN_SLEEP_TIME));
 		return;
 	}
 
-//	write_nic_dword(dev, TimerInt, tl);
-//	rb = read_nic_dword(dev, TSFTR);
-	{
-		u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
-	//	if (tl<rb)
-		queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
-	}
-	/* if we suspect the TimerInt is gone beyond tl
-	 * while setting it, then give up
-	 */
-#if 1
 	if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
-		((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
+			((tl < rb) && (tl>MSECS(69)) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))||
+			((tl<rb)&&(tl<MSECS(69))&&((tl+0xffffffff-rb)>MSECS(MAX_SLEEP_TIME)))) {
 		printk("========>too long to sleep:%x, %x, %lx\n", tl, rb,  MSECS(MAX_SLEEP_TIME));
 		spin_unlock_irqrestore(&priv->ps_lock,flags);
 		return;
 	}
-#endif
-//	if(priv->rf_sleep)
-//		priv->rf_sleep(dev);
-
-	//printk("<=========%s()\n", __FUNCTION__);
-	queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
+	{
+		u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
+		queue_delayed_work(priv->ieee80211->wq,
+				&priv->ieee80211->hw_wakeup_wq,tmp);
+		//PowerSave not supported when kernel version less 2.6.20
+	}
+	queue_delayed_work(priv->ieee80211->wq,
+			(void *)&priv->ieee80211->hw_sleep_wq,0);
 	spin_unlock_irqrestore(&priv->ps_lock,flags);
+
 }
 static void rtl8192_init_priv_variable(struct net_device* dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	u8 i;
+	PRT_POWER_SAVE_CONTROL	pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+
+	// Default Halt the NIC if RF is OFF.
+	pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_HALT_NIC;
+	pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_CLK_REQ;
+	pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_ASPM;
+	pPSC->RegRfPsLevel |= RT_RF_LPS_LEVEL_ASPM;
+	pPSC->bLeisurePs = true;
+	pPSC->RegMaxLPSAwakeIntvl = 5;
+	priv->bHwRadioOff = false;
+
 	priv->being_init_adapter = false;
 	priv->txbuffsize = 1600;//1024;
 	priv->txfwbuffersize = 4096;
@@ -2328,6 +2578,17 @@ static void rtl8192_init_priv_variable(s
 	//added by amy
 	priv->ieee80211->InitialGainHandler = InitialGain819xPci;
 
+#ifdef ENABLE_IPS
+	priv->ieee80211->ieee80211_ips_leave_wq = ieee80211_ips_leave_wq;
+	priv->ieee80211->ieee80211_ips_leave = ieee80211_ips_leave;
+#endif
+#ifdef ENABLE_LPS
+        priv->ieee80211->LeisurePSLeave            = LeisurePSLeave;
+#endif//ENABL
+
+	priv->ieee80211->SetHwRegHandler = rtl8192e_SetHwReg;
+	priv->ieee80211->rtllib_ap_sec_type = rtl8192e_ap_sec_type;
+
 	priv->card_type = USB;
 	{
 		priv->ShortRetryLimit = 0x30;
@@ -2400,6 +2661,10 @@ static void rtl8192_init_priv_task(struc
 	priv->priv_wq = create_workqueue(DRV_NAME);
 #endif
 
+#ifdef ENABLE_IPS
+	INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq);
+#endif
+
 //	INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
 	INIT_WORK(&priv->reset_wq,  rtl8192_restart);
 //	INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
@@ -2550,10 +2815,7 @@ static void rtl8192_read_eeprom_info(str
 		memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
 	}
 
-	RT_TRACE(COMP_INIT, "Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
-			dev->dev_addr[0], dev->dev_addr[1],
-			dev->dev_addr[2], dev->dev_addr[3],
-			dev->dev_addr[4], dev->dev_addr[5]);
+	RT_TRACE(COMP_INIT, "Permanent Address = %pM\n", dev->dev_addr);
 
 		//2 TX Power Check EEPROM Fail or not
 	if(priv->card_8192_version > VERSION_8190_BD) {
@@ -2926,13 +3188,14 @@ static void rtl8192_read_eeprom_info(str
 		#endif
 			break;
 	}
-/*
-	//2008.06.03, for WOL
+
+
 	if( priv->eeprom_vid == 0x1186 &&  priv->eeprom_did == 0x3304)
-		priv->ieee80211->bSupportRemoteWakeUp = TRUE;
+		priv->ieee80211->bSupportRemoteWakeUp = true;
 	else
-		priv->ieee80211->bSupportRemoteWakeUp = FALSE;
-*/
+		priv->ieee80211->bSupportRemoteWakeUp = false;
+
+
 	RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan);
 	RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan);
 	RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy);
@@ -4006,12 +4269,19 @@ static void rtl819x_ifsilentreset(struct
 	struct ieee80211_device *ieee = priv->ieee80211;
 
 
+	return;
+
 	// 2007.07.20. If we need to check CCK stop, please uncomment this line.
 	//bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
 
 	if(priv->ResetProgress==RESET_TYPE_NORESET)
 	{
 RESET_START:
+#ifdef ENABLE_LPS
+                //LZM for PS-Poll AID issue. 090429
+                if(priv->ieee80211->state == IEEE80211_LINKED)
+                    LeisurePSLeave(dev);
+#endif
 
 		RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
 
@@ -4051,9 +4321,9 @@ RESET_START:
 		}
 		else{
 			printk("ieee->state is NOT LINKED\n");
-			ieee80211_softmac_stop_protocol(priv->ieee80211);
+			ieee80211_softmac_stop_protocol(priv->ieee80211,true);
 		}
-		rtl8192_rtx_disable(dev);
+		rtl8192_halt_adapter(dev, true);
 		up(&priv->wx_sem);
 		RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
 		RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
@@ -4150,6 +4420,128 @@ void InactivePsWorkItemCallback(struct n
 	RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n");
 }
 
+#ifdef ENABLE_LPS
+//
+// Change current and default preamble mode.
+// 2005.01.06, by rcnjko.
+//
+bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev,	u8 rtPsMode)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+	//u8 RpwmVal, FwPwrMode;
+
+	// Currently, we do not change power save mode on IBSS mode.
+	if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+	{
+		return false;
+	}
+
+	//
+	// <RJ_NOTE> If we make HW to fill up the PwrMgt bit for us,
+	// some AP will not response to our mgnt frames with PwrMgt bit set,
+	// e.g. cannot associate the AP.
+	// So I commented out it. 2005.02.16, by rcnjko.
+	//
+//	// Change device's power save mode.
+//	Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode );
+
+	// Update power save mode configured.
+	//RT_TRACE(COMP_LPS,"%s(): set ieee->ps = %x\n",__FUNCTION__,rtPsMode);
+	if(!priv->ps_force) {
+		priv->ieee80211->ps = rtPsMode;
+	}
+
+	// Awake immediately
+	if(priv->ieee80211->sta_sleep != 0 && rtPsMode == IEEE80211_PS_DISABLED)
+	{
+                unsigned long flags;
+
+		//PlatformSetTimer(Adapter, &(pMgntInfo->AwakeTimer), 0);
+		// Notify the AP we awke.
+		rtl8192_hw_wakeup(dev);
+		priv->ieee80211->sta_sleep = 0;
+
+                spin_lock_irqsave(&(priv->ieee80211->mgmt_tx_lock), flags);
+		printk("LPS leave: notify AP we are awaked ++++++++++ SendNullFunctionData\n");
+		ieee80211_sta_ps_send_null_frame(priv->ieee80211, 0);
+                spin_unlock_irqrestore(&(priv->ieee80211->mgmt_tx_lock), flags);
+	}
+
+	return true;
+}
+
+//================================================================================
+// Leisure Power Save in linked state.
+//================================================================================
+
+//
+//	Description:
+//		Enter the leisure power save mode.
+//
+void LeisurePSEnter(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+
+	//RT_TRACE(COMP_PS, "LeisurePSEnter()...\n");
+	//RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d,pPSC->LpsIdleCount is %d,RT_CHECK_FOR_HANG_PERIOD is %d\n",
+	//	pPSC->bLeisurePs, priv->ieee80211->ps,pPSC->LpsIdleCount,RT_CHECK_FOR_HANG_PERIOD);
+
+	if(!((priv->ieee80211->iw_mode == IW_MODE_INFRA) &&
+		(priv->ieee80211->state == IEEE80211_LINKED)) ||
+		(priv->ieee80211->iw_mode == IW_MODE_ADHOC) ||
+		(priv->ieee80211->iw_mode == IW_MODE_MASTER))
+		return;
+
+	if (pPSC->bLeisurePs)
+	{
+		// Idle for a while if we connect to AP a while ago.
+		if(pPSC->LpsIdleCount >= RT_CHECK_FOR_HANG_PERIOD) //  4 Sec
+		{
+
+			if(priv->ieee80211->ps == IEEE80211_PS_DISABLED)
+			{
+
+				//RT_TRACE(COMP_LPS, "LeisurePSEnter(): Enter 802.11 power save mode...\n");
+				MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST);
+
+			}
+		}
+		else
+			pPSC->LpsIdleCount++;
+	}
+}
+
+
+//
+//	Description:
+//		Leave the leisure power save mode.
+//
+void LeisurePSLeave(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+
+
+	//RT_TRACE(COMP_PS, "LeisurePSLeave()...\n");
+	//RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d\n",
+	//	pPSC->bLeisurePs, priv->ieee80211->ps);
+
+	if (pPSC->bLeisurePs)
+	{
+		if(priv->ieee80211->ps != IEEE80211_PS_DISABLED)
+		{
+			// move to lps_wakecomplete()
+			//RT_TRACE(COMP_LPS, "LeisurePSLeave(): Busy Traffic , Leave 802.11 power save..\n");
+			MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_DISABLED);
+
+		}
+	}
+}
+#endif
+
+
 //
 //	Description:
 //		Enter the inactive power save mode. RF will be off
@@ -4178,6 +4570,7 @@ IPSEnter(struct net_device *dev)
 			&& (priv->ieee80211->state != IEEE80211_LINKED) )
 		{
 			RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n");
+			//printk("IPSEnter(): Turn off RF.\n");
 			pPSC->eInactivePowerState = eRfOff;
 //			queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
 			InactivePsWorkItemCallback(dev);
@@ -4203,12 +4596,53 @@ IPSLeave(struct net_device *dev)
 		if (rtState != eRfOn  && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS)
 		{
 			RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n");
+			//printk("IPSLeave(): Turn on RF.\n");
 			pPSC->eInactivePowerState = eRfOn;
 //			queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
 			InactivePsWorkItemCallback(dev);
 		}
 	}
 }
+
+void IPSLeave_wq(void *data)
+{
+	struct ieee80211_device *ieee = container_of(data,struct ieee80211_device,ips_leave_wq);
+	struct net_device *dev = ieee->dev;
+
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	down(&priv->ieee80211->ips_sem);
+	IPSLeave(dev);
+	up(&priv->ieee80211->ips_sem);
+}
+
+void ieee80211_ips_leave_wq(struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	RT_RF_POWER_STATE	rtState;
+	rtState = priv->ieee80211->eRFPowerState;
+
+	if(priv->ieee80211->PowerSaveControl.bInactivePs){
+		if(rtState == eRfOff){
+			if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
+			{
+				RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
+				return;
+			}
+			else{
+				printk("=========>%s(): IPSLeave\n",__FUNCTION__);
+				queue_work(priv->ieee80211->wq,&priv->ieee80211->ips_leave_wq);
+			}
+		}
+	}
+}
+//added by amy 090331 end
+void ieee80211_ips_leave(struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	down(&priv->ieee80211->ips_sem);
+	IPSLeave(dev);
+	up(&priv->ieee80211->ips_sem);
+}
 #endif
 
 static void rtl819x_update_rxcounts(
@@ -4244,15 +4678,23 @@ void rtl819x_watchdog_wqcallback(struct
 	unsigned long flags;
 	bool bBusyTraffic = false;
 	static u8 last_time = 0;
+	bool bEnterPS = false;
+
+	if((!priv->up) || (priv->bHwRadioOff == true))
+		return;
+
 	if(!priv->up)
 		return;
 	hal_dm_watchdog(dev);
 #ifdef ENABLE_IPS
 //	printk("watch_dog ENABLE_IPS\n");
 	if(ieee->actscanning == false){
-		if((ieee->iw_mode != IW_MODE_ADHOC) && (ieee->state == IEEE80211_NOLINK) && (ieee->beinretry == false) && (ieee->eRFPowerState == eRfOn) && !ieee->is_set_key){
+		//printk("%d,%d,%d,%d\n", ieee->eRFPowerState, ieee->is_set_key, ieee->proto_stoppping, ieee->wx_set_enc);
+		if((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_NOLINK) &&\
+		    (ieee->eRFPowerState == eRfOn)&&!ieee->is_set_key &&\
+		    (!ieee->proto_stoppping) && !ieee->wx_set_enc){
 			if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){
-				printk("====================>haha:IPSEnter()\n");
+				//printk("====================>haha:IPSEnter()\n");
 				IPSEnter(dev);
 				//ieee80211_stop_scan(priv->ieee80211);
 			}
@@ -4262,14 +4704,49 @@ void rtl819x_watchdog_wqcallback(struct
 	{//to get busy traffic condition
 		if(ieee->state == IEEE80211_LINKED)
 		{
-			if(	ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
-				ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
+			if(	ieee->LinkDetectInfo.NumRxOkInPeriod> 100 ||
+				ieee->LinkDetectInfo.NumTxOkInPeriod> 100 ) {
 				bBusyTraffic = true;
 			}
 
+#ifdef ENABLE_LPS
+			//added by amy for Leisure PS
+			if(	((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod + ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
+				(ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) )
+			{
+				//printk("ieee->LinkDetectInfo.NumRxUnicastOkInPeriod is %d,ieee->LinkDetectInfo.NumTxOkInPeriod is %d\n",
+				//	ieee->LinkDetectInfo.NumRxUnicastOkInPeriod,ieee->LinkDetectInfo.NumTxOkInPeriod);
+				bEnterPS= false;
+			}
+			else
+			{
+				bEnterPS= true;
+			}
+
+			//printk("***bEnterPS = %d\n", bEnterPS);
+			// LeisurePS only work in infra mode.
+			if(bEnterPS)
+			{
+				LeisurePSEnter(dev);
+			}
+			else
+			{
+				LeisurePSLeave(dev);
+			}
+#endif
+
+		}
+		else
+		{
+#ifdef ENABLE_LPS
+			//RT_TRACE(COMP_LPS,"====>no link LPS leave\n");
+			LeisurePSLeave(dev);
+#endif
 		}
+
 	        ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
 	        ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
+		ieee->LinkDetectInfo.NumRxUnicastOkInPeriod = 0;
 		ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
 	}
 
@@ -4288,14 +4765,14 @@ void rtl819x_watchdog_wqcallback(struct
 				if( ieee->eRFPowerState == eRfOff)
 					RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
 				printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
-		//		Dot11d_Reset(dev);
+				//		Dot11d_Reset(dev);
 				ieee->state = IEEE80211_ASSOCIATING;
 				notify_wx_assoc_event(priv->ieee80211);
-                                RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
+				RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
 				ieee->is_roaming = true;
 				ieee->is_set_key = false;
-                             ieee->link_change(dev);
-                                queue_work(ieee->wq, &ieee->associate_procedure_wq);
+				ieee->link_change(dev);
+				queue_work(ieee->wq, &ieee->associate_procedure_wq);
 			}
 		}
 	      ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
@@ -4348,6 +4825,7 @@ int _rtl8192_up(struct net_device *dev)
 	RT_STATUS init_status = RT_STATUS_SUCCESS;
 	priv->up=1;
 	priv->ieee80211->ieee_up=1;
+	priv->bdisable_nic = false;  //YJ,add,091111
 	RT_TRACE(COMP_INIT, "Bringing up iface");
 
 	init_status = rtl8192_adapter_start(dev);
@@ -4422,6 +4900,12 @@ int rtl8192_down(struct net_device *dev)
 #endif
 	if (priv->up == 0) return -1;
 
+#ifdef ENABLE_LPS
+	//LZM for PS-Poll AID issue. 090429
+	if(priv->ieee80211->state == IEEE80211_LINKED)
+		LeisurePSLeave(dev);
+#endif
+
 	priv->up=0;
 	priv->ieee80211->ieee_up = 0;
 	RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
@@ -4459,11 +4943,9 @@ int rtl8192_down(struct net_device *dev)
 	deinit_hal_dm(dev);
 	del_timer_sync(&priv->watch_dog_timer);
 
-	ieee80211_softmac_stop_protocol(priv->ieee80211);
-#ifdef ENABLE_IPS
-	MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
-#endif
-	rtl8192_rtx_disable(dev);
+	ieee80211_softmac_stop_protocol(priv->ieee80211,true);
+
+	rtl8192_halt_adapter(dev,false);
 	memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
 
 	RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
@@ -4479,10 +4961,10 @@ void rtl8192_commit(struct net_device *d
 	if (priv->up == 0) return ;
 
 
-	ieee80211_softmac_stop_protocol(priv->ieee80211);
+	ieee80211_softmac_stop_protocol(priv->ieee80211,true);
 
 	rtl8192_irq_disable(dev);
-	rtl8192_rtx_disable(dev);
+	rtl8192_halt_adapter(dev,true);
 	_rtl8192_up(dev);
 }
 
@@ -5806,8 +6288,7 @@ static void rtl8192_rx(struct net_device
 
                 skb = new_skb;
                 priv->rx_buf[priv->rx_idx] = skb;
-                *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb->tail, priv->rxbuffersize, PCI_DMA_FROMDEVICE);
-//                *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
+                *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
             }
 
         }
@@ -6036,7 +6517,7 @@ void rtl8192_cancel_deferred_work(struct
 	/* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
          * is  or is newer than 2.6.20 and work structure is defined to be struct work_struct.
          * Otherwise call cancel_delayed_work is enough.
-         * FIXME (2.6.20 shoud 2.6.22, work_struct shoud not cancel)
+         * FIXME (2.6.20 should 2.6.22, work_struct should not cancel)
          * */
 	cancel_delayed_work(&priv->watch_dog_wq);
 	cancel_delayed_work(&priv->update_beacon_wq);
@@ -6381,11 +6862,13 @@ void setKey(	struct net_device *dev,
 			if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
 			{
 				RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
-				up(&priv->wx_sem);
+				//up(&priv->wx_sem);
 				return ;
 			}
 			else{
+				down(&priv->ieee80211->ips_sem);
 				IPSLeave(dev);
+				up(&priv->ieee80211->ips_sem);
 			}
 		}
 	}
@@ -6394,7 +6877,7 @@ void setKey(	struct net_device *dev,
 	if (EntryNo >= TOTAL_CAM_ENTRY)
 		RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
 
-	RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr));
+	RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
 
 	if (DefaultKey)
 		usConfig |= BIT15 | (KeyType<<2);
@@ -6455,6 +6938,65 @@ void CamPrintDbgReg(struct net_device* d
 	RT_TRACE(COMP_SEC, "WPA_Config=%x \n",ucValue);
 }
 
+bool NicIFEnableNIC(struct net_device* dev)
+{
+	RT_STATUS init_status = RT_STATUS_SUCCESS;
+	struct r8192_priv* priv = ieee80211_priv(dev);
+	PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+
+	//YJ,add,091109
+	if (priv->up == 0){
+		RT_TRACE(COMP_ERR, "ERR!!! %s(): Driver is already down!\n",__FUNCTION__);
+		priv->bdisable_nic = false;  //YJ,add,091111
+		return false;
+	}
+	// <1> Reset memory: descriptor, buffer,..
+	//NicIFResetMemory(Adapter);
+
+	// <2> Enable Adapter
+	//printk("===========>%s()\n",__FUNCTION__);
+	//priv->bfirst_init = true;
+	init_status = rtl8192_adapter_start(dev);
+	if (init_status != RT_STATUS_SUCCESS) {
+		RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
+		priv->bdisable_nic = false;  //YJ,add,091111
+		return -1;
+	}
+	//printk("start adapter finished\n");
+	RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
+	//priv->bfirst_init = false;
+
+	// <3> Enable Interrupt
+	rtl8192_irq_enable(dev);
+	priv->bdisable_nic = false;
+	//RT_TRACE(COMP_PS,"<===========%s()\n",__FUNCTION__);
+	return (init_status == RT_STATUS_SUCCESS) ? true:false;
+}
+bool NicIFDisableNIC(struct net_device* dev)
+{
+	bool	status = true;
+	struct r8192_priv* priv = ieee80211_priv(dev);
+	u8 tmp_state = 0;
+	// <1> Disable Interrupt
+	//RT_TRACE(COMP_PS, "=========>%s()\n",__FUNCTION__);
+	priv->bdisable_nic = true;	//YJ,move,091109
+	tmp_state = priv->ieee80211->state;
+
+	ieee80211_softmac_stop_protocol(priv->ieee80211, false);
+
+	priv->ieee80211->state = tmp_state;
+	rtl8192_cancel_deferred_work(priv);
+	rtl8192_irq_disable(dev);
+	// <2> Stop all timer
+
+	// <3> Disable Adapter
+	rtl8192_halt_adapter(dev, false);
+//	priv->bdisable_nic = true;
+	//RT_TRACE(COMP_PS, "<=========%s()\n",__FUNCTION__);
+
+	return status;
+}
+
 
 /***************************************************************************
      ------------------- module init / exit stubs ----------------
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8192E_dm.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8192E_dm.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8192E_dm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8192E_dm.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,26 +19,28 @@ Major Change History:
 #include "r819xE_phy.h"
 #include "r819xE_phyreg.h"
 #include "r8190_rtl8256.h"
+
+#define DRV_NAME "rtl819xE"
 /*---------------------------Define Local Constant---------------------------*/
 //
 // Indicate different AP vendor for IOT issue.
 //
 #ifdef  RTL8190P
 static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
-{ 0x5e4322, 	0x5e4322, 	0x5e4322,  	0x604322, 	0xa44f, 	0x5e4322};
+{ 0x5e4322, 	0x5e4322, 	0x5e4322,  	0x604322, 	0xa44f, 	0x5e4322,	0x5e4322};
 static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
-{ 0x5e4322, 	0xa44f, 	0x5e4322,  	0x604322, 	0x5e4322, 	0x5e4322};
+{ 0x5e4322, 	0xa44f, 	0x5e4322,  	0x604322, 	0x5e4322, 	0x5e4322,	0x5e4322};
 #else
 #ifdef RTL8192E
 static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
-{ 0x5e4322, 	0x5e4322, 	0x5e4322, 	0x604322, 	0xa44f, 	0x5e4322};
+{ 0x5e4322, 	0x5e4322, 	0x5e4322, 	0x604322, 	0xa44f, 	0x5e4322,	0x5e4322};
 static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
-{ 0x5e4322, 	0xa44f,		0x5e4322,  	0x604322, 	0x5e4322, 	0x5e4322};
+{ 0x5e4322, 	0xa44f,		0x5e4322,  	0x604322, 	0x5e4322, 	0x5e4322, 	0x5e4322};
 #else
 static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
-{ 0x5e4322, 	0x5e4322, 	0x5e4322, 	0x604322, 	0xa44f, 	0x5ea44f};
+{ 0x5e4322, 	0x5e4322, 	0x5e4322, 	0x604322, 	0xa44f, 	0x5ea44f, 	0x5e4322};
 static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
-{ 0x5e4322, 	0xa44f, 	0x5e4322, 	0x604322, 	0x5ea44f, 	0x5ea44f};
+{ 0x5e4322, 	0xa44f, 	0x5e4322, 	0x604322, 	0x5ea44f, 	0x5ea44f, 	0x5e4322};
 #endif
 #endif
 
@@ -275,6 +277,30 @@ void dm_CheckRxAggregation(struct net_de
 #endif
 
 
+// call the script file to enable
+void dm_check_ac_dc_power(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	static char *ac_dc_check_script_path = "/etc/acpi/wireless-rtl-ac-dc-power.sh";
+	char *argv[] = {ac_dc_check_script_path,DRV_NAME,NULL};
+	static char *envp[] = {"HOME=/",
+			"TERM=linux",
+			"PATH=/usr/bin:/bin",
+			 NULL};
+
+	if(priv->ResetProgress == RESET_TYPE_SILENT)
+	{
+		RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF), "GPIOChangeRFWorkItemCallBack(): Silent Reseting!!!!!!!\n");
+		return;
+	}
+
+	if(priv->ieee80211->state != IEEE80211_LINKED) {
+		return;
+	}
+	call_usermodehelper(ac_dc_check_script_path,argv,envp,1);
+
+	return;
+};
 
 void hal_dm_watchdog(struct net_device *dev)
 {
@@ -282,6 +308,8 @@ void hal_dm_watchdog(struct net_device *
 
 	//static u8 	previous_bssid[6] ={0};
 
+	dm_check_ac_dc_power(dev);
+
 	/*Add by amy 2008/05/15 ,porting from windows code.*/
 	dm_check_rate_adaptive(dev);
 	dm_dynamic_txpower(dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8192E.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8192E.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8192E.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8192E.h	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,7 @@
 #include <linux/random.h>
 #include <linux/version.h>
 #include <asm/io.h>
-#include "ieee80211.h"
+#include "ieee80211/ieee80211.h"
 
 
 
@@ -1003,6 +1003,11 @@ typedef struct r8192_priv
 	int irq;
 	short irq_enabled;
 	struct ieee80211_device *ieee80211;
+#ifdef ENABLE_LPS
+	bool ps_force;
+	bool force_lps;
+	bool bdisable_nic;
+#endif
 	bool being_init_adapter;
 	u8 Rf_Mode;
 	short card_8192; /* O: rtl8192, 1:rtl8185 V B/C, 2:rtl8185 V D */
@@ -1477,7 +1482,7 @@ void write_nic_word(struct net_device *d
 void write_nic_dword(struct net_device *dev, int x,u32 y);
 void force_pci_posting(struct net_device *dev);
 
-void rtl8192_rtx_disable(struct net_device *);
+void rtl8192_halt_adapter(struct net_device *dev, bool reset);
 void rtl8192_rx_enable(struct net_device *);
 void rtl8192_tx_enable(struct net_device *);
 
@@ -1512,5 +1517,19 @@ short rtl8192_is_tx_queue_empty(struct n
 #ifdef ENABLE_IPS
 void IPSEnter(struct net_device *dev);
 void IPSLeave(struct net_device *dev);
+void InactivePsWorkItemCallback(struct net_device *dev);
+void IPSLeave_wq(void *data);
+void ieee80211_ips_leave_wq(struct net_device *dev);
+void ieee80211_ips_leave(struct net_device *dev);
+#endif
+#ifdef ENABLE_LPS
+void LeisurePSEnter(struct net_device *dev);
+void LeisurePSLeave(struct net_device *dev);
 #endif
+
+bool NicIFEnableNIC(struct net_device* dev);
+bool NicIFDisableNIC(struct net_device* dev);
+
+void rtl8192_irq_disable(struct net_device *dev);
+void PHY_SetRtl8192eRfOff(struct net_device* dev);
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8192E_hw.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8192E_hw.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8192E_hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8192E_hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -808,4 +808,12 @@ enum _RTL8192Pci_HW {
 #define GPI 0x108
 #define GPO 0x109
 #define GPE 0x10a
+
+#define	ANAPAR_FOR_8192PciE							0x17		// Analog parameter register
+
+#define	MSR_NOLINK					0x00
+#define	MSR_ADHOC					0x01
+#define	MSR_INFRA					0x02
+#define	MSR_AP						0x03
+
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8192E_wx.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8192E_wx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8192E_wx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8192E_wx.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,7 @@
 #include "r8192E_hw.h"
 #include "r8192E_wx.h"
 #ifdef ENABLE_DOT11D
-#include "dot11d.h"
+#include "ieee80211/dot11d.h"
 #endif
 
 #define RATE_COUNT 12
@@ -70,6 +70,9 @@ static int r8192_wx_set_rate(struct net_
 	int ret;
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	down(&priv->wx_sem);
 
 	ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
@@ -87,6 +90,9 @@ static int r8192_wx_set_rts(struct net_d
 	int ret;
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	down(&priv->wx_sem);
 
 	ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
@@ -111,6 +117,9 @@ static int r8192_wx_set_power(struct net
 	int ret;
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	down(&priv->wx_sem);
 
 	ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
@@ -290,6 +299,9 @@ static int r8192_wx_set_rawtx(struct net
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	int ret;
 
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	down(&priv->wx_sem);
 
 	ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
@@ -325,6 +337,9 @@ static int r8192_wx_set_crcmon(struct ne
 	int enable = (parms[0] > 0);
 	short prev = priv->crcmon;
 
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	down(&priv->wx_sem);
 
 	if(enable)
@@ -352,6 +367,9 @@ static int r8192_wx_set_mode(struct net_
 	RT_RF_POWER_STATE	rtState;
 	int ret;
 
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	rtState = priv->ieee80211->eRFPowerState;
 	down(&priv->wx_sem);
 #ifdef ENABLE_IPS
@@ -366,8 +384,10 @@ static int r8192_wx_set_mode(struct net_
 					return -1;
 				}
 				else{
-				printk("=========>%s(): IPSLeave\n",__FUNCTION__);
+					RT_TRACE(COMP_ERR, "%s(): IPSLeave\n",__FUNCTION__);
+					down(&priv->ieee80211->ips_sem);
 					IPSLeave(dev);
+					up(&priv->ieee80211->ips_sem);
 				}
 			}
 		}
@@ -425,7 +445,7 @@ static int rtl8180_wx_get_range(struct n
 	 */
 
 	/* ~5 Mb/s real (802.11b) */
-	range->throughput = 5 * 1000 * 1000;
+	range->throughput = 130 * 1000 * 1000;
 
 	// TODO: Not used in 802.11b?
 //	range->min_nwid;	/* Minimal NWID we are able to set */
@@ -468,7 +488,7 @@ static int rtl8180_wx_get_range(struct n
 	range->pmt_flags = IW_POWER_TIMEOUT;
 	range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
 	range->we_version_compiled = WIRELESS_EXT;
-	range->we_version_source = 16;
+	range->we_version_source = 18;
 
 //	range->retry_capa;	/* What retry options are supported */
 //	range->retry_flags;	/* How to decode max/min retry limit */
@@ -517,7 +537,12 @@ static int r8192_wx_set_scan(struct net_
 	struct ieee80211_device* ieee = priv->ieee80211;
 	RT_RF_POWER_STATE	rtState;
 	int ret;
+
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	rtState = priv->ieee80211->eRFPowerState;
+
 	if(!priv->up) return -ENETDOWN;
 	if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
 		return -EAGAIN;
@@ -547,8 +572,10 @@ static int r8192_wx_set_scan(struct net_
 					return -1;
 				}
 				else{
-					printk("=========>%s(): IPSLeave\n",__FUNCTION__);
+					//RT_TRACE(COMP_PS, "%s(): IPSLeave\n",__FUNCTION__);
+					down(&priv->ieee80211->ips_sem);
 					IPSLeave(dev);
+					up(&priv->ieee80211->ips_sem);
 				}
 			}
 		}
@@ -580,6 +607,9 @@ static int r8192_wx_get_scan(struct net_
 	int ret;
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	if(!priv->up) return -ENETDOWN;
 
 	down(&priv->wx_sem);
@@ -599,23 +629,16 @@ static int r8192_wx_set_essid(struct net
 	RT_RF_POWER_STATE	rtState;
 	int ret;
 
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	rtState = priv->ieee80211->eRFPowerState;
 	down(&priv->wx_sem);
+
 #ifdef ENABLE_IPS
-	if(priv->ieee80211->PowerSaveControl.bInactivePs){
-		if(rtState == eRfOff){
-			if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
-			{
-				RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
-				up(&priv->wx_sem);
-				return -1;
-			}
-			else{
-				printk("=========>%s(): IPSLeave\n",__FUNCTION__);
-				IPSLeave(dev);
-			}
-		}
-	}
+        down(&priv->ieee80211->ips_sem);
+        IPSLeave(dev);
+        up(&priv->ieee80211->ips_sem);
 #endif
 	ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
 
@@ -650,6 +673,9 @@ static int r8192_wx_set_freq(struct net_
 	int ret;
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	down(&priv->wx_sem);
 
 	ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
@@ -673,6 +699,9 @@ static int r8192_wx_set_frag(struct net_
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	if (wrqu->frag.disabled)
 		priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
 	else {
@@ -711,8 +740,16 @@ static int r8192_wx_set_wap(struct net_d
 	struct r8192_priv *priv = ieee80211_priv(dev);
 //        struct sockaddr *temp = (struct sockaddr *)awrq;
 
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	down(&priv->wx_sem);
 
+#ifdef ENABLE_IPS
+        down(&priv->ieee80211->ips_sem);
+        IPSLeave(dev);
+        up(&priv->ieee80211->ips_sem);
+#endif
 	ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
 
 	up(&priv->wx_sem);
@@ -753,14 +790,24 @@ static int r8192_wx_set_enc(struct net_d
 	u32 hwkey[4]={0,0,0,0};
 	u8 mask=0xff;
 	u32 key_idx=0;
-	u8 zero_addr[4][6] ={	{0x00,0x00,0x00,0x00,0x00,0x00},
+	u8 zero_addr[4][6] ={{0x00,0x00,0x00,0x00,0x00,0x00},
 				{0x00,0x00,0x00,0x00,0x00,0x01},
 				{0x00,0x00,0x00,0x00,0x00,0x02},
 				{0x00,0x00,0x00,0x00,0x00,0x03} };
 	int i;
 
+	if(priv->bHwRadioOff == true)
+		return 0;
+
        if(!priv->up) return -ENETDOWN;
 
+        priv->ieee80211->wx_set_enc = 1;
+#ifdef ENABLE_IPS
+        down(&priv->ieee80211->ips_sem);
+        IPSLeave(dev);
+        up(&priv->ieee80211->ips_sem);
+#endif
+
 	down(&priv->wx_sem);
 
 	RT_TRACE(COMP_SEC, "Setting SW wep key");
@@ -768,7 +815,6 @@ static int r8192_wx_set_enc(struct net_d
 
 	up(&priv->wx_sem);
 
-
 	//sometimes, the length is zero while we do not type key value
 	if(wrqu->encoding.length!=0){
 
@@ -868,6 +914,8 @@ static int r8192_wx_set_enc(struct net_d
 	}
 #endif
 
+	priv->ieee80211->wx_set_enc = 0;
+
 	return ret;
 }
 
@@ -893,6 +941,9 @@ static int r8192_wx_set_retry(struct net
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	int err = 0;
 
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	down(&priv->wx_sem);
 
 	if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
@@ -985,6 +1036,10 @@ static int r8192_wx_set_sens(struct net_
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
 	short err = 0;
+
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	down(&priv->wx_sem);
 	//DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
 	if(priv->rf_set_sens == NULL) {
@@ -1011,7 +1066,19 @@ static int r8192_wx_set_enc_ext(struct n
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	struct ieee80211_device* ieee = priv->ieee80211;
 
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	down(&priv->wx_sem);
+
+	priv->ieee80211->wx_set_enc = 1;
+
+#ifdef ENABLE_IPS
+        down(&priv->ieee80211->ips_sem);
+        IPSLeave(dev);
+        up(&priv->ieee80211->ips_sem);
+#endif
+
 	ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra);
 
 	{
@@ -1091,6 +1158,7 @@ static int r8192_wx_set_enc_ext(struct n
 	}
 
 end_hw_sec:
+	priv->ieee80211->wx_set_enc = 0;
 	up(&priv->wx_sem);
 	return ret;
 
@@ -1102,6 +1170,10 @@ static int r8192_wx_set_auth(struct net_
 	int ret=0;
 	//printk("====>%s()\n", __FUNCTION__);
 	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	down(&priv->wx_sem);
 	ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
 	up(&priv->wx_sem);
@@ -1116,6 +1188,10 @@ static int r8192_wx_set_mlme(struct net_
 
 	int ret=0;
 	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if(priv->bHwRadioOff == true)
+		return 0;
+
 	down(&priv->wx_sem);
 	ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
 	up(&priv->wx_sem);
@@ -1129,6 +1205,10 @@ static int r8192_wx_set_gen_ie(struct ne
 	   //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
 	int ret=0;
         struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if(priv->bHwRadioOff == true)
+		return 0;
+
         down(&priv->wx_sem);
         ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
         up(&priv->wx_sem);
@@ -1142,6 +1222,42 @@ static int dummy(struct net_device *dev,
 	return -1;
 }
 
+// check ac/dc status with the help of user space application */
+static int r8192_wx_adapter_power_status(struct net_device *dev,
+		struct iw_request_info *info,
+		union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#ifdef ENABLE_LPS
+	PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+	struct ieee80211_device* ieee = priv->ieee80211;
+#endif
+	down(&priv->wx_sem);
+
+#ifdef ENABLE_LPS
+	RT_TRACE(COMP_POWER, "%s(): %s\n",__FUNCTION__, (*extra ==  6)?"DC power":"AC power");
+	// ieee->ps shall not be set under DC mode, otherwise it conflict
+	// with Leisure power save mode setting.
+	//
+	if(*extra || priv->force_lps) {
+		priv->ps_force = false;
+		pPSC->bLeisurePs = true;
+	} else {
+		//LZM for PS-Poll AID issue. 090429
+		if(priv->ieee80211->state == IEEE80211_LINKED)
+			LeisurePSLeave(dev);
+
+		priv->ps_force = true;
+		pPSC->bLeisurePs = false;
+		ieee->ps = *extra;
+	}
+
+#endif
+	up(&priv->wx_sem);
+	return 0;
+
+}
+
 
 static iw_handler r8192_wx_handlers[] =
 {
@@ -1231,72 +1347,28 @@ static const struct iw_priv_args r8192_p
 		SIOCIWFIRSTPRIV + 0x2,
 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
 	}
-#ifdef JOHN_IOCTL
 	,
 	{
 		SIOCIWFIRSTPRIV + 0x3,
-                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
+
 	}
 	,
 	{
 		SIOCIWFIRSTPRIV + 0x4,
-                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
-	}
-	,
-	{
-		SIOCIWFIRSTPRIV + 0x5,
-                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
-	}
-	,
-	{
-		SIOCIWFIRSTPRIV + 0x6,
-                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
-	}
-        ,
-        {
-                SIOCIWFIRSTPRIV + 0x7,
-                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
-        }
-        ,
-        {
-                SIOCIWFIRSTPRIV + 0x8,
-                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
-        }
-        ,
-        {
-                SIOCIWFIRSTPRIV + 0x9,
-                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
-        }
-
-#endif
-	,
-	{
-		SIOCIWFIRSTPRIV + 0x3,
-		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
-
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
+		"set_power"
 	}
 
 };
 
 
 static iw_handler r8192_private_handler[] = {
-//	r8192_wx_set_monitor,  /* SIOCIWFIRSTPRIV */
 	r8192_wx_set_crcmon,   /*SIOCIWSECONDPRIV*/
-//	r8192_wx_set_forceassociate,
-//	r8192_wx_set_beaconinterval,
-//	r8192_wx_set_monitor_type,
 	r8192_wx_set_scan_type,
 	r8192_wx_set_rawtx,
-#ifdef JOHN_IOCTL
-	r8192_wx_read_regs,
-	r8192_wx_write_regs,
-	r8192_wx_read_bb,
-	r8192_wx_write_bb,
-        r8192_wx_read_nicb,
-        r8192_wx_write_nicb,
-	r8192_wx_get_ap_status
-#endif
 	r8192_wx_force_reset,
+	r8192_wx_adapter_power_status,
 };
 
 //#if WIRELESS_EXT >= 17
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8192E_wx.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8192E_wx.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r8192E_wx.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r8192E_wx.h	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 #ifndef R8180_WX_H
 #define R8180_WX_H
 //#include <linux/wireless.h>
-//#include "ieee80211.h"
 extern struct iw_handler_def r8192_wx_handlers_def;
 /* Enable  the rtl819x_core.c to share this function, david 2008.9.22 */
 extern struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r819xE_cmdpkt.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r819xE_cmdpkt.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r819xE_cmdpkt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r819xE_cmdpkt.c	2010-05-16 17:17:36.000000000 -0400
@@ -135,7 +135,7 @@ RT_STATUS cmpk_message_handle_tx(
              * Transform from little endian to big endian
              * and pending  zero
              */
-            seg_ptr = skb->tail;
+            seg_ptr = skb_tail_pointer(skb);
             for(i=0 ; i < frag_length; i+=4) {
                 *seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0;
                 *seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r819xE_firmware.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r819xE_firmware.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r819xE_firmware.c	2013-05-03 12:11:27.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r819xE_firmware.c	2013-05-03 09:50:59.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Procedure:    Init boot code/firmware code/data session
+ * Procedure: Init boot code/firmware code/data session
  *
  * Description: This routine will intialize firmware. If any error occurs
  *		during the initialization process, the routine shall terminate
@@ -7,19 +7,21 @@
  *		NdisOpenFile only from MiniportInitialize.
  *
  * Arguments:   The pointer of the adapter
-
+ *
  * Returns:
  *		NDIS_STATUS_FAILURE - the following initialization process
  *				      should be terminated
  *		NDIS_STATUS_SUCCESS - if firmware initialization process
  *				      success
  */
+
 #include "r8192E.h"
 #include "r8192E_hw.h"
+
 #include <linux/firmware.h>
 
 /* It should be double word alignment */
-#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v)	(4 * (v / 4) - 8)
+#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4 * (v / 4) - 8)
 
 enum firmware_init_step {
 	FW_INIT_STEP0_BOOT = 0,
@@ -47,17 +49,17 @@ void firmware_init_param(struct net_devi
 static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address,
 			     u32 buffer_len)
 {
-	struct r8192_priv   *priv = ieee80211_priv(dev);
-	bool 		    rt_status = true;
-	u16		    frag_threshold;
-	u16		    frag_length, frag_offset = 0;
-	int		    i;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	bool rt_status = true;
+	u16 frag_threshold;
+	u16 frag_length, frag_offset = 0;
+	int i;
 
-	rt_firmware	    *pfirmware = priv->pFirmware;
-	struct sk_buff	    *skb;
-	unsigned char	    *seg_ptr;
-	cb_desc		    *tcb_desc;
-	u8                  bLastIniPkt;
+	rt_firmware *pfirmware = priv->pFirmware;
+	struct sk_buff *skb;
+	unsigned char *seg_ptr;
+	cb_desc *tcb_desc;
+	u8 bLastIniPkt;
 
 	firmware_init_param(dev);
 
@@ -89,10 +91,17 @@ static bool fw_download_code(struct net_
 		 * Transform from little endian to big endian and pending zero
 		 */
 		for (i = 0; i < frag_length; i += 4) {
-			*seg_ptr++ = ((i+0) < frag_length) ? code_virtual_address[i+3] : 0;
-			*seg_ptr++ = ((i+1) < frag_length) ? code_virtual_address[i+2] : 0;
-			*seg_ptr++ = ((i+2) < frag_length) ? code_virtual_address[i+1] : 0;
-			*seg_ptr++ = ((i+3) < frag_length) ? code_virtual_address[i+0] : 0;
+			*seg_ptr++ = ((i+0) < frag_length) ? \
+					code_virtual_address[i+3] : 0;
+
+			*seg_ptr++ = ((i+1) < frag_length) ? \
+					code_virtual_address[i+2] : 0;
+
+			*seg_ptr++ = ((i+2) < frag_length) ? \
+					code_virtual_address[i+1] : 0;
+
+			*seg_ptr++ = ((i+3) < frag_length) ? \
+					code_virtual_address[i+0] : 0;
 		}
 		tcb_desc->txbuf_size = (u16)i;
 		skb_put(skb, i);
@@ -204,16 +213,16 @@ CPUCheckFirmwareReady_Fail:
 
 bool init_firmware(struct net_device *dev)
 {
-	struct r8192_priv 	*priv = ieee80211_priv(dev);
-	bool			rt_status = TRUE;
-	u32			file_length = 0;
-	u8			*mapped_file = NULL;
-	u32			init_step = 0;
-	enum opt_rst_type	rst_opt = OPT_SYSTEM_RESET;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	bool rt_status = true;
+	u32 file_length = 0;
+	u8 *mapped_file = NULL;
+	u32 init_step = 0;
+	enum opt_rst_type rst_opt = OPT_SYSTEM_RESET;
 	enum firmware_init_step	starting_state = FW_INIT_STEP0_BOOT;
 
-	rt_firmware		*pfirmware = priv->pFirmware;
-	const struct firmware 	*fw_entry;
+	rt_firmware *pfirmware = priv->pFirmware;
+	const struct firmware *fw_entry;
 	const char *fw_name[3] = { "/*(DEBLOBBED)*/",
 				   "/*(DEBLOBBED)*/",
 				   "/*(DEBLOBBED)*/"};
@@ -240,31 +249,37 @@ bool init_firmware(struct net_device *de
 	 * Download boot, main, and data image for System reset.
 	 * Download data image for firmware reseta
 	 */
-	for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) {
+	for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; \
+			init_step++) {
 		/*
 		 * Open Image file, and map file to contineous memory if open file success.
 		 * or read image file from array. Default load from IMG file
 		 */
 		if (rst_opt == OPT_SYSTEM_RESET) {
 			if (pfirmware->firmware_buf_size[init_step] == 0) {
-				rc = reject_firmware(&fw_entry, fw_name[init_step], &priv->pdev->dev);
+				rc = reject_firmware(&fw_entry,
+					fw_name[init_step], &priv->pdev->dev);
+
 				if (rc < 0) {
 					RT_TRACE(COMP_FIRMWARE, "request firmware fail!\n");
 					goto download_firmware_fail;
 				}
 
 				if (fw_entry->size > sizeof(pfirmware->firmware_buf[init_step])) {
-					RT_TRACE(COMP_FIRMWARE, "img file size exceed the container buffer fail!\n");
+					RT_TRACE(COMP_FIRMWARE, \
+						"img file size exceed the container buffer fail!\n");
 					goto download_firmware_fail;
 				}
 
 				if (init_step != FW_INIT_STEP1_MAIN) {
-					memcpy(pfirmware->firmware_buf[init_step], fw_entry->data, fw_entry->size);
+					memcpy(pfirmware->firmware_buf[init_step],
+							fw_entry->data, fw_entry->size);
 					pfirmware->firmware_buf_size[init_step] = fw_entry->size;
 
 				} else {
 					memset(pfirmware->firmware_buf[init_step], 0, 128);
-					memcpy(&pfirmware->firmware_buf[init_step][128], fw_entry->data, fw_entry->size);
+					memcpy(&pfirmware->firmware_buf[init_step][128], fw_entry->data,
+									fw_entry->size);
 					pfirmware->firmware_buf_size[init_step] = fw_entry->size+128;
 				}
 
@@ -273,6 +288,7 @@ bool init_firmware(struct net_device *de
 			}
 			mapped_file = pfirmware->firmware_buf[init_step];
 			file_length = pfirmware->firmware_buf_size[init_step];
+
 		} else if (rst_opt == OPT_FIRMWARE_RESET) {
 			/* we only need to download data.img here */
 			mapped_file = pfirmware->firmware_buf[init_step];
@@ -346,7 +362,8 @@ bool init_firmware(struct net_device *de
 
 download_firmware_fail:
 	RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
-	rt_status = FALSE;
+	rt_status = false;
 	return rt_status;
-
 }
+
+/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r819xE_phy.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r819xE_phy.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r819xE_phy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r819xE_phy.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,7 @@
 #include "r819xE_phy.h"
 #include "r8192E_dm.h"
 #ifdef ENABLE_DOT11D
-#include "dot11d.h"
+#include "ieee80211/dot11d.h"
 #endif
 static u32 RF_CHANNEL_TABLE_ZEBRA[] = {
 	0,
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r819xE_phy.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r819xE_phy.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r819xE_phy.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r819xE_phy.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,43 +1,46 @@
 #ifndef _R819XU_PHY_H
 #define _R819XU_PHY_H
-/* Channel switch:The size of command tables for switch channel*/
+
+/* Channel switch: the size of command tables for switch channel */
 #define MAX_PRECMD_CNT 16
 #define MAX_RFDEPENDCMD_CNT 16
 #define MAX_POSTCMD_CNT 16
 
 #ifdef RTL8190P
 #define MACPHY_Array_PGLength 21
-#define Rtl819XMACPHY_Array_PG			Rtl8190PciMACPHY_Array_PG
-#define Rtl819XMACPHY_Array				Rtl8190PciMACPHY_Array
+#define Rtl819XMACPHY_Array_PG Rtl8190PciMACPHY_Array_PG
+#define Rtl819XMACPHY_Array Rtl8190PciMACPHY_Array
 #define RadioC_ArrayLength 246
 #define RadioD_ArrayLength 78
-#define Rtl819XRadioA_Array					Rtl8190PciRadioA_Array
-#define Rtl819XRadioB_Array					Rtl8190PciRadioB_Array
-#define Rtl819XRadioC_Array					Rtl8190PciRadioC_Array
-#define Rtl819XRadioD_Array					Rtl8190PciRadioD_Array
-#define Rtl819XAGCTAB_Array				Rtl8190PciAGCTAB_Array
-#define PHY_REGArrayLength 				280
-#define Rtl819XPHY_REGArray				Rtl8190PciPHY_REGArray
-#define PHY_REG_1T2RArrayLength 		280
-#define Rtl819XPHY_REG_1T2RArray		Rtl8190PciPHY_REG_1T2RArray
+#define Rtl819XRadioA_Array Rtl8190PciRadioA_Array
+#define Rtl819XRadioB_Array Rtl8190PciRadioB_Array
+#define Rtl819XRadioC_Array Rtl8190PciRadioC_Array
+#define Rtl819XRadioD_Array Rtl8190PciRadioD_Array
+#define Rtl819XAGCTAB_Array Rtl8190PciAGCTAB_Array
+#define PHY_REGArrayLength 280
+#define Rtl819XPHY_REGArray Rtl8190PciPHY_REGArray
+#define PHY_REG_1T2RArrayLength 280
+#define Rtl819XPHY_REG_1T2RArray Rtl8190PciPHY_REG_1T2RArray
+#endif
+
+
+#ifdef RTL8192E
+#define MACPHY_Array_PGLength 30
+#define Rtl819XMACPHY_Array_PG Rtl8192PciEMACPHY_Array_PG
+#define Rtl819XMACPHY_Array Rtl8192PciEMACPHY_Array
+#define RadioC_ArrayLength 1
+#define RadioD_ArrayLength 1
+#define Rtl819XRadioA_Array Rtl8192PciERadioA_Array
+#define Rtl819XRadioB_Array Rtl8192PciERadioB_Array
+#define Rtl819XRadioC_Array Rtl8192PciERadioC_Array
+#define Rtl819XRadioD_Array Rtl8192PciERadioD_Array
+#define Rtl819XAGCTAB_Array Rtl8192PciEAGCTAB_Array
+#define PHY_REGArrayLength 1
+#define Rtl819XPHY_REGArray Rtl8192PciEPHY_REGArray
+#define PHY_REG_1T2RArrayLength 296
+#define Rtl819XPHY_REG_1T2RArray Rtl8192PciEPHY_REG_1T2RArray
 #endif
 
-	#ifdef RTL8192E
-	#define MACPHY_Array_PGLength 30
-	#define Rtl819XMACPHY_Array_PG			Rtl8192PciEMACPHY_Array_PG
-	#define Rtl819XMACPHY_Array				Rtl8192PciEMACPHY_Array
-	#define RadioC_ArrayLength 1
-	#define RadioD_ArrayLength 1
-	#define Rtl819XRadioA_Array					Rtl8192PciERadioA_Array
-	#define Rtl819XRadioB_Array					Rtl8192PciERadioB_Array
-	#define Rtl819XRadioC_Array					Rtl8192PciERadioC_Array
-	#define Rtl819XRadioD_Array					Rtl8192PciERadioD_Array
-	#define Rtl819XAGCTAB_Array				Rtl8192PciEAGCTAB_Array
-	#define PHY_REGArrayLength 				1
-	#define Rtl819XPHY_REGArray				Rtl8192PciEPHY_REGArray
-	#define PHY_REG_1T2RArrayLength 		296
-	#define Rtl819XPHY_REG_1T2RArray		Rtl8192PciEPHY_REG_1T2RArray
-	#endif
 #define AGCTAB_ArrayLength 384
 #define MACPHY_ArrayLength 18
 
@@ -45,7 +48,7 @@
 #define RadioB_ArrayLength 78
 
 
-typedef enum _SwChnlCmdID{
+typedef enum _SwChnlCmdID {
 	CmdID_End,
 	CmdID_SetTxPowerLevel,
 	CmdID_BBRegWrite10,
@@ -53,16 +56,15 @@ typedef enum _SwChnlCmdID{
 	CmdID_WritePortUshort,
 	CmdID_WritePortUchar,
 	CmdID_RF_WriteReg,
-}SwChnlCmdID;
+} SwChnlCmdID;
 
-/*--------------------------------Define structure--------------------------------*/
-/* 1. Switch channel related */
-typedef struct _SwChnlCmd{
-	SwChnlCmdID	CmdID;
-	u32			Para1;
-	u32			Para2;
-	u32			msDelay;
-}__attribute__ ((packed)) SwChnlCmd;
+/* switch channel data structure */
+typedef struct _SwChnlCmd {
+	SwChnlCmdID CmdID;
+	u32 Para1;
+	u32 Para2;
+	u32 msDelay;
+} __attribute__ ((packed)) SwChnlCmd;
 
 extern u32 rtl819XMACPHY_Array_PG[];
 extern u32 rtl819XPHY_REG_1T2RArray[];
@@ -72,54 +74,90 @@ extern u32 rtl819XRadioB_Array[];
 extern u32 rtl819XRadioC_Array[];
 extern u32 rtl819XRadioD_Array[];
 
-typedef enum _HW90_BLOCK{
+typedef enum _HW90_BLOCK {
 	HW90_BLOCK_MAC = 0,
 	HW90_BLOCK_PHY0 = 1,
 	HW90_BLOCK_PHY1 = 2,
 	HW90_BLOCK_RF = 3,
-	HW90_BLOCK_MAXIMUM = 4, // Never use this
-}HW90_BLOCK_E, *PHW90_BLOCK_E;
+	/* Don't ever use this. */
+	HW90_BLOCK_MAXIMUM = 4,
+} HW90_BLOCK_E, *PHW90_BLOCK_E;
 
-typedef enum _RF90_RADIO_PATH{
-	RF90_PATH_A = 0,			//Radio Path A
-	RF90_PATH_B = 1,			//Radio Path B
-	RF90_PATH_C = 2,			//Radio Path C
-	RF90_PATH_D = 3,			//Radio Path D
-	RF90_PATH_MAX				//Max RF number 92 support
-}RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E;
+typedef enum _RF90_RADIO_PATH {
+	/* Radio paths */
+	RF90_PATH_A = 0,
+	RF90_PATH_B = 1,
+	RF90_PATH_C = 2,
+	RF90_PATH_D = 3,
 
-#define bMaskByte0                0xff
-#define bMaskByte1                0xff00
-#define bMaskByte2                0xff0000
-#define bMaskByte3                0xff000000
-#define bMaskHWord                0xffff0000
-#define bMaskLWord                0x0000ffff
-#define bMaskDWord                0xffffffff
+	/* Max RF number 92 support */
+	RF90_PATH_MAX
+} RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E;
+
+#define bMaskByte0 0xff
+#define bMaskByte1 0xff00
+#define bMaskByte2 0xff0000
+#define bMaskByte3 0xff000000
+#define bMaskHWord 0xffff0000
+#define bMaskLWord 0x0000ffff
+#define bMaskDWord 0xffffffff
+
+/*extern u32 rtl8192_CalculateBitShift(u32 dwBitMask);
+
+extern u32 rtl8192_phy_RFSerialRead(struct net_device *dev,
+			RF90_RADIO_PATH_E eRFPath, u32 Offset);
+
+extern void rtl8192_phy_RFSerialWrite(struct net_device *dev,
+		RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data);
+
+extern void rtl8192_InitBBRFRegDef(struct net_device *dev);
+
+extern RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device *dev); */
+
+extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device *dev, u32 eRFPath);
+
+extern void rtl8192_setBBreg(struct net_device *dev, u32 dwRegAddr,
+			     u32 dwBitMask, u32 dwData);
+
+extern u32 rtl8192_QueryBBReg(struct net_device *dev, u32 dwRegAddr,
+			     u32 dwBitMask);
+
+extern void rtl8192_phy_SetRFReg(struct net_device *dev,
+		RF90_RADIO_PATH_E eRFPath, u32 RegAddr,
+		u32 BitMask, u32 Data);
+
+extern u32 rtl8192_phy_QueryRFReg(struct net_device *dev,
+		RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask);
+
+extern void rtl8192_phy_configmac(struct net_device *dev);
+
+extern void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType);
+
+extern RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device *dev,
+		HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath);
+
+extern RT_STATUS rtl8192_BBConfig(struct net_device *dev);
+
+extern void rtl8192_phy_getTxPower(struct net_device *dev);
+
+extern void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel);
 
-//extern u32 rtl8192_CalculateBitShift(u32 dwBitMask);
-extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath);
-extern void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 dwData);
-extern u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask);
-//extern u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset);
-//extern void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data);
-extern void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data);
-extern u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask);
-extern void rtl8192_phy_configmac(struct net_device* dev);
-extern void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType);
-//extern void rtl8192_InitBBRFRegDef(struct net_device* dev);
-extern RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath);
-//extern RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev);
-extern RT_STATUS rtl8192_BBConfig(struct net_device* dev);
-extern void rtl8192_phy_getTxPower(struct net_device* dev);
-extern void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel);
 extern RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev);
+
 extern void rtl8192_phy_updateInitGain(struct net_device* dev);
-extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E	eRFPath);
 
-extern u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel);
-extern void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET Offset);
+extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev,
+					RF90_RADIO_PATH_E eRFPath);
+
+extern u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel);
+
+extern void rtl8192_SetBWMode(struct net_device *dev,
+		HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
+
 extern void rtl8192_SwChnl_WorkItem(struct net_device *dev);
+
 extern void rtl8192_SetBWModeWorkItem(struct net_device *dev);
+
 extern void InitialGain819xPci(struct net_device *dev, u8 Operation);
 
-#endif
+#endif /* _R819XU_PHY_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r819xE_phyreg.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r819xE_phyreg.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192e/r819xE_phyreg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192e/r819xE_phyreg.h	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,8 @@
 #define	MCS_TXAGC				0x340	// MCS AGC
 #define	CCK_TXAGC				0x348	// CCK AGC
 
+#define	MacBlkCtrl				0x403					// Mac block on/off control register
+
 //page8
 #define rFPGA0_RFMOD              		0x800  //RF mode & CCK TxSC
 #define rFPGA0_TxInfo             		0x804
@@ -79,55 +81,70 @@
 #define rFPGA0_XB_LSSIReadBack    	0x8a4
 #define rFPGA0_XC_LSSIReadBack    	0x8a8
 #define rFPGA0_XD_LSSIReadBack    	0x8ac
-#define rFPGA0_PSDReport          		0x8b4
+#define rFPGA0_PSDReport		0x8b4
 #define rFPGA0_XAB_RFInterfaceRB  	0x8e0
 #define rFPGA0_XCD_RFInterfaceRB  	0x8e4
 
-//page 9
-#define rFPGA1_RFMOD              		0x900  //RF mode & OFDM TxSC
-#define rFPGA1_TxBlock            		0x904
-#define rFPGA1_DebugSelect        		0x908
-#define rFPGA1_TxInfo             		0x90c
+/* Page 9 - RF mode & OFDM TxSC */
+#define rFPGA1_RFMOD      		0x900
+#define rFPGA1_TxBlock            	0x904
+#define rFPGA1_DebugSelect        	0x908
+#define rFPGA1_TxInfo             	0x90c
 
-//page a
-#define rCCK0_System              		0xa00
-#define rCCK0_AFESetting          		0xa04
-#define rCCK0_CCA                 			0xa08
-#define rCCK0_RxAGC1              		0xa0c  //AGC default value, saturation level
-#define rCCK0_RxAGC2              		0xa10  //AGC & DAGC
-#define rCCK0_RxHP                		0xa14
-#define rCCK0_DSPParameter1       	0xa18  //Timing recovery & Channel estimation threshold
-#define rCCK0_DSPParameter2       	0xa1c  //SQ threshold
-#define rCCK0_TxFilter1           		0xa20
-#define rCCK0_TxFilter2           		0xa24
-#define rCCK0_DebugPort           		0xa28  //debug port and Tx filter3
-#define rCCK0_FalseAlarmReport    	0xa2c  //0xa2d
-#define rCCK0_TRSSIReport         		0xa50
-#define rCCK0_RxReport            		0xa54  //0xa57
-#define rCCK0_FACounterLower      	0xa5c  //0xa5b
-#define rCCK0_FACounterUpper      	0xa58  //0xa5c
+/* Page a */
+#define rCCK0_System              	0xa00
+#define rCCK0_AFESetting          	0xa04
+#define rCCK0_CCA                 	0xa08
+/* AGC default value, saturation level */
+#define rCCK0_RxAGC1              	0xa0c
+/* AGC & DAGC */
+#define rCCK0_RxAGC2              	0xa10
+#define rCCK0_RxHP                	0xa14
+/* Timing recovery & channel estimation threshold */
+#define rCCK0_DSPParameter1       	0xa18
+/* SQ threshold */
+#define rCCK0_DSPParameter2       	0xa1c
+#define rCCK0_TxFilter1           	0xa20
+#define rCCK0_TxFilter2           	0xa24
+/* Debug port and TX filter 3 */
+#define rCCK0_DebugPort           	0xa28
+#define rCCK0_FalseAlarmReport    	0xa2c
+#define rCCK0_TRSSIReport         	0xa50
+#define rCCK0_RxReport            	0xa54
+#define rCCK0_FACounterLower      	0xa5c
+#define rCCK0_FACounterUpper      	0xa58
 
-//page c
-#define rOFDM0_LSTF               		0xc00
+/* Page c */
+#define rOFDM0_LSTF              	0xc00
 #define rOFDM0_TRxPathEnable      	0xc04
-#define rOFDM0_TRMuxPar           		0xc08
-#define rOFDM0_TRSWIsolation      		0xc0c
-#define rOFDM0_XARxAFE            		0xc10  //RxIQ DC offset, Rx digital filter, DC notch filter
-#define rOFDM0_XARxIQImbalance    	0xc14  //RxIQ imblance matrix
-#define rOFDM0_XBRxAFE            		0xc18
+#define rOFDM0_TRMuxPar           	0xc08
+#define rOFDM0_TRSWIsolation      	0xc0c
+/* RxIQ DC offset, Rx digital filter, DC notch filter */
+#define rOFDM0_XARxAFE            	0xc10
+/* RxIQ imblance matrix */
+#define rOFDM0_XARxIQImbalance    	0xc14
+#define rOFDM0_XBRxAFE            	0xc18
 #define rOFDM0_XBRxIQImbalance    	0xc1c
-#define rOFDM0_XCRxAFE            		0xc20
+#define rOFDM0_XCRxAFE           	0xc20
 #define rOFDM0_XCRxIQImbalance    	0xc24
-#define rOFDM0_XDRxAFE            		0xc28
+#define rOFDM0_XDRxAFE            	0xc28
 #define rOFDM0_XDRxIQImbalance    	0xc2c
-#define rOFDM0_RxDetector1        		0xc30  //PD,BW & SBD
-#define rOFDM0_RxDetector2        		0xc34  //SBD & Fame Sync.
-#define rOFDM0_RxDetector3        		0xc38  //Frame Sync.
-#define rOFDM0_RxDetector4        		0xc3c  //PD, SBD, Frame Sync & Short-GI
-#define rOFDM0_RxDSP              		0xc40  //Rx Sync Path
-#define rOFDM0_CFOandDAGC         	0xc44  //CFO & DAGC
-#define rOFDM0_CCADropThreshold   	0xc48 //CCA Drop threshold
-#define rOFDM0_ECCAThreshold      	0xc4c // energy CCA
+/* PD, BW & SBD */
+#define rOFDM0_RxDetector1        	0xc30
+/* SBD */
+#define rOFDM0_RxDetector2		0xc34
+/* Frame Sync */
+#define rOFDM0_RxDetector3         	0xc38
+/* PD, SBD, Frame Sync & Short-GI */
+#define rOFDM0_RxDetector4        	0xc3c
+/* Rx Sync Path */
+#define rOFDM0_RxDSP			0xc40
+/* CFO & DAGC */
+#define rOFDM0_CFOandDAGC         	0xc44
+/* CCA Drop threshold */
+#define rOFDM0_CCADropThreshold   	0xc48
+/* Energy CCA */
+#define rOFDM0_ECCAThreshold      	0xc4c
 #define rOFDM0_XAAGCCore1         	0xc50
 #define rOFDM0_XAAGCCore2         	0xc54
 #define rOFDM0_XBAGCCore1         	0xc58
@@ -139,501 +156,517 @@
 #define rOFDM0_AGCParameter1      	0xc70
 #define rOFDM0_AGCParameter2      	0xc74
 #define rOFDM0_AGCRSSITable       	0xc78
-#define rOFDM0_HTSTFAGC           		0xc7c
+#define rOFDM0_HTSTFAGC           	0xc7c
 #define rOFDM0_XATxIQImbalance   	0xc80
-#define rOFDM0_XATxAFE            		0xc84
+#define rOFDM0_XATxAFE            	0xc84
 #define rOFDM0_XBTxIQImbalance    	0xc88
-#define rOFDM0_XBTxAFE            		0xc8c
+#define rOFDM0_XBTxAFE            	0xc8c
 #define rOFDM0_XCTxIQImbalance    	0xc90
-#define rOFDM0_XCTxAFE            		0xc94
+#define rOFDM0_XCTxAFE            	0xc94
 #define rOFDM0_XDTxIQImbalance    	0xc98
-#define rOFDM0_XDTxAFE            		0xc9c
+#define rOFDM0_XDTxAFE            	0xc9c
 #define rOFDM0_RxHPParameter      	0xce0
 #define rOFDM0_TxPseudoNoiseWgt   	0xce4
-#define rOFDM0_FrameSync          		0xcf0
-#define rOFDM0_DFSReport          		0xcf4
-#define rOFDM0_TxCoeff1           		0xca4
-#define rOFDM0_TxCoeff2           		0xca8
-#define rOFDM0_TxCoeff3           		0xcac
-#define rOFDM0_TxCoeff4           		0xcb0
-#define rOFDM0_TxCoeff5           		0xcb4
-#define rOFDM0_TxCoeff6           		0xcb8
+#define rOFDM0_FrameSync          	0xcf0
+#define rOFDM0_DFSReport          	0xcf4
+#define rOFDM0_TxCoeff1           	0xca4
+#define rOFDM0_TxCoeff2           	0xca8
+#define rOFDM0_TxCoeff3           	0xcac
+#define rOFDM0_TxCoeff4           	0xcb0
+#define rOFDM0_TxCoeff5           	0xcb4
+#define rOFDM0_TxCoeff6           	0xcb8
 
 
-//page d
-#define rOFDM1_LSTF               		0xd00
+/* Page d */
+#define rOFDM1_LSTF               	0xd00
 #define rOFDM1_TRxPathEnable      	0xd04
-#define rOFDM1_CFO                		0xd08
-#define rOFDM1_CSI1               		0xd10
-#define rOFDM1_SBD                		0xd14
-#define rOFDM1_CSI2               		0xd18
-#define rOFDM1_CFOTracking        		0xd2c
+#define rOFDM1_CFO                	0xd08
+#define rOFDM1_CSI1               	0xd10
+#define rOFDM1_SBD                	0xd14
+#define rOFDM1_CSI2               	0xd18
+#define rOFDM1_CFOTracking        	0xd2c
 #define rOFDM1_TRxMesaure1        	0xd34
-#define rOFDM1_IntfDet            		0xd3c
-#define rOFDM1_PseudoNoiseStateAB 0xd50
-#define rOFDM1_PseudoNoiseStateCD 0xd54
-#define rOFDM1_RxPseudoNoiseWgt   0xd58
-#define rOFDM_PHYCounter1         		0xda0  //cca, parity fail
-#define rOFDM_PHYCounter2         		0xda4  //rate illegal, crc8 fail
-#define rOFDM_PHYCounter3         		0xda8  //MCS not support
-#define rOFDM_ShortCFOAB          		0xdac
-#define rOFDM_ShortCFOCD          		0xdb0
-#define rOFDM_LongCFOAB           		0xdb4
-#define rOFDM_LongCFOCD           		0xdb8
-#define rOFDM_TailCFOAB           		0xdbc
-#define rOFDM_TailCFOCD           		0xdc0
+#define rOFDM1_IntfDet            	0xd3c
+#define rOFDM1_PseudoNoiseStateAB 	0xd50
+#define rOFDM1_PseudoNoiseStateCD 	0xd54
+#define rOFDM1_RxPseudoNoiseWgt   	0xd58
+/* cca, parity fail */
+#define rOFDM_PHYCounter1         	0xda0
+/* rate illegal, crc8 fail */
+#define rOFDM_PHYCounter2   		0xda4
+/* MCS not supported */
+#define rOFDM_PHYCounter3         	0xda8
+#define rOFDM_ShortCFOAB          	0xdac
+#define rOFDM_ShortCFOCD          	0xdb0
+#define rOFDM_LongCFOAB           	0xdb4
+#define rOFDM_LongCFOCD           	0xdb8
+#define rOFDM_TailCFOAB           	0xdbc
+#define rOFDM_TailCFOCD           	0xdc0
 #define rOFDM_PWMeasure1          	0xdc4
 #define rOFDM_PWMeasure2          	0xdc8
-#define rOFDM_BWReport            		0xdcc
-#define rOFDM_AGCReport           		0xdd0
-#define rOFDM_RxSNR               		0xdd4
-#define rOFDM_RxEVMCSI            		0xdd8
-#define rOFDM_SIGReport           		0xddc
+#define rOFDM_BWReport            	0xdcc
+#define rOFDM_AGCReport           	0xdd0
+#define rOFDM_RxSNR               	0xdd4
+#define rOFDM_RxEVMCSI            	0xdd8
+#define rOFDM_SIGReport           	0xddc
 
-//page e
-#define rTxAGC_Rate18_06			0xe00
-#define rTxAGC_Rate54_24			0xe04
-#define rTxAGC_CCK_Mcs32			0xe08
-#define rTxAGC_Mcs03_Mcs00			0xe10
-#define rTxAGC_Mcs07_Mcs04			0xe14
-#define rTxAGC_Mcs11_Mcs08			0xe18
-#define rTxAGC_Mcs15_Mcs12			0xe1c
+/* Page e */
+#define rTxAGC_Rate18_06		0xe00
+#define rTxAGC_Rate54_24		0xe04
+#define rTxAGC_CCK_Mcs32		0xe08
+#define rTxAGC_Mcs03_Mcs00		0xe10
+#define rTxAGC_Mcs07_Mcs04		0xe14
+#define rTxAGC_Mcs11_Mcs08		0xe18
+#define rTxAGC_Mcs15_Mcs12		0xe1c
 
 
-//RF
-//Zebra1
+/* RF Zebra 1 */
 #define rZebra1_HSSIEnable            	0x0
 #define rZebra1_TRxEnable1            	0x1
 #define rZebra1_TRxEnable2           	0x2
-#define rZebra1_AGC                   		0x4
+#define rZebra1_AGC                   	0x4
 #define rZebra1_ChargePump            	0x5
-#define rZebra1_Channel               		0x7
-#define rZebra1_TxGain               	 	0x8
-#define rZebra1_TxLPF                 		0x9
-#define rZebra1_RxLPF                 		0xb
+#define rZebra1_Channel               	0x7
+#define rZebra1_TxGain               	0x8
+#define rZebra1_TxLPF                 	0x9
+#define rZebra1_RxLPF                 	0xb
 #define rZebra1_RxHPFCorner           	0xc
 
-//Zebra4
-#define rGlobalCtrl                   		0
-#define rRTL8256_TxLPF                		19
-#define rRTL8256_RxLPF                		11
+/* Zebra 4 */
+#define rGlobalCtrl                   	0
+#define rRTL8256_TxLPF                	19
+#define rRTL8256_RxLPF                	11
 
-//RTL8258
-#define rRTL8258_TxLPF                		0x11
-#define rRTL8258_RxLPF                		0x13
+/* RTL8258 */
+#define rRTL8258_TxLPF                	0x11
+#define rRTL8258_RxLPF                  0x13
 #define rRTL8258_RSSILPF              	0xa
 
-//Bit Mask
-//page-1
-#define bBBResetB                 			0x100
-#define bGlobalResetB             		0x200
-#define bOFDMTxStart              		0x4
-#define bCCKTxStart               			0x8
-#define bCRC32Debug               		0x100
-#define bPMACLoopback             		0x10
-#define bTxLSIG                   			0xffffff
-#define bOFDMTxRate               		0xf
-#define bOFDMTxReserved           		0x10
-#define bOFDMTxLength             		0x1ffe0
-#define bOFDMTxParity             		0x20000
-#define bTxHTSIG1                 			0xffffff
-#define bTxHTMCSRate              		0x7f
-#define bTxHTBW                   			0x80
-#define bTxHTLength               		0xffff00
-#define bTxHTSIG2                 			0xffffff
-#define bTxHTSmoothing            		0x1
-#define bTxHTSounding             		0x2
-#define bTxHTReserved             		0x4
-#define bTxHTAggreation           		0x8
-#define bTxHTSTBC                 			0x30
-#define bTxHTAdvanceCoding        		0x40
-#define bTxHTShortGI              		0x80
-#define bTxHTNumberHT_LTF         		0x300
-#define bTxHTCRC8                 			0x3fc00
-#define bCounterReset             		0x10000
-#define bNumOfOFDMTx              		0xffff
-#define bNumOfCCKTx               		0xffff0000
-#define bTxIdleInterval           			0xffff
-#define bOFDMService              		0xffff0000
-#define bTxMACHeader              		0xffffffff
-#define bTxDataInit               			0xff
-#define bTxHTMode                 		0x100
-#define bTxDataType               		0x30000
-#define bTxRandomSeed             		0xffffffff
-#define bCCKTxPreamble           		0x1
-#define bCCKTxSFD                 			0xffff0000
-#define bCCKTxSIG                 			0xff
-#define bCCKTxService             		0xff00
-#define bCCKLengthExt             		0x8000
-#define bCCKTxLength              		0xffff0000
-#define bCCKTxCRC16               		0xffff
-#define bCCKTxStatus              		0x1
-#define bOFDMTxStatus             		0x2
+/* Bit Mask */
+/* Page 1 */
+#define bBBResetB                 	0x100
+#define bGlobalResetB             	0x200
+#define bOFDMTxStart              	0x4
+#define bCCKTxStart               	0x8
+#define bCRC32Debug               	0x100
+#define bPMACLoopback             	0x10
+#define bTxLSIG                   	0xffffff
+#define bOFDMTxRate               	0xf
+#define bOFDMTxReserved           	0x10
+#define bOFDMTxLength             	0x1ffe0
+#define bOFDMTxParity             	0x20000
+#define bTxHTSIG1                 	0xffffff
+#define bTxHTMCSRate              	0x7f
+#define bTxHTBW                   	0x80
+#define bTxHTLength               	0xffff00
+#define bTxHTSIG2                 	0xffffff
+#define bTxHTSmoothing            	0x1
+#define bTxHTSounding             	0x2
+#define bTxHTReserved             	0x4
+#define bTxHTAggreation           	0x8
+#define bTxHTSTBC                 	0x30
+#define bTxHTAdvanceCoding        	0x40
+#define bTxHTShortGI              	0x80
+#define bTxHTNumberHT_LTF         	0x300
+#define bTxHTCRC8                 	0x3fc00
+#define bCounterReset             	0x10000
+#define bNumOfOFDMTx              	0xffff
+#define bNumOfCCKTx               	0xffff0000
+#define bTxIdleInterval           	0xffff
+#define bOFDMService              	0xffff0000
+#define bTxMACHeader              	0xffffffff
+#define bTxDataInit               	0xff
+#define bTxHTMode                 	0x100
+#define bTxDataType               	0x30000
+#define bTxRandomSeed             	0xffffffff
+#define bCCKTxPreamble           	0x1
+#define bCCKTxSFD                 	0xffff0000
+#define bCCKTxSIG                 	0xff
+#define bCCKTxService             	0xff00
+#define bCCKLengthExt             	0x8000
+#define bCCKTxLength              	0xffff0000
+#define bCCKTxCRC16               	0xffff
+#define bCCKTxStatus              	0x1
+#define bOFDMTxStatus             	0x2
 
-//page-8
-#define bRFMOD                    			0x1
-#define bJapanMode                		0x2
-#define bCCKTxSC                  			0x30
-#define bCCKEn                    			0x1000000
-#define bOFDMEn                   			0x2000000
-#define bOFDMRxADCPhase           		0x10000
-#define bOFDMTxDACPhase           		0x40000
-#define bXATxAGC                  			0x3f
-#define bXBTxAGC                  			0xf00
-#define bXCTxAGC                  			0xf000
-#define bXDTxAGC                  			0xf0000
-#define bPAStart                  			0xf0000000
-#define bTRStart                  			0x00f00000
-#define bRFStart                  			0x0000f000
-#define bBBStart                  			0x000000f0
-#define bBBCCKStart               		0x0000000f
-#define bPAEnd                    			0xf          //Reg0x814
-#define bTREnd                    			0x0f000000
-#define bRFEnd                    			0x000f0000
-#define bCCAMask                  			0x000000f0   //T2R
-#define bR2RCCAMask               		0x00000f00
-#define bHSSI_R2TDelay            		0xf8000000
-#define bHSSI_T2RDelay            		0xf80000
-#define bContTxHSSI               		0x400     //channel gain at continue Tx
-#define bIGFromCCK                		0x200
-#define bAGCAddress               		0x3f
-#define bRxHPTx                   			0x7000
-#define bRxHPT2R                  			0x38000
-#define bRxHPCCKIni               		0xc0000
-#define bAGCTxCode                		0xc00000
-#define bAGCRxCode                		0x300000
-#define b3WireDataLength          		0x800
-#define b3WireAddressLength       		0x400
-#define b3WireRFPowerDown         		0x1
-//#define bHWSISelect               		0x8
-#define b5GPAPEPolarity           		0x40000000
-#define b2GPAPEPolarity           		0x80000000
-#define bRFSW_TxDefaultAnt        		0x3
-#define bRFSW_TxOptionAnt         		0x30
-#define bRFSW_RxDefaultAnt        		0x300
-#define bRFSW_RxOptionAnt         		0x3000
-#define bRFSI_3WireData           		0x1
-#define bRFSI_3WireClock          		0x2
-#define bRFSI_3WireLoad           		0x4
-#define bRFSI_3WireRW             		0x8
-#define bRFSI_3Wire               			0xf  //3-wire total control
-#define bRFSI_RFENV               		0x10
-#define bRFSI_TRSW                		0x20
-#define bRFSI_TRSWB               		0x40
-#define bRFSI_ANTSW               		0x100
-#define bRFSI_ANTSWB              		0x200
-#define bRFSI_PAPE                			0x400
-#define bRFSI_PAPE5G              		0x800
-#define bBandSelect               			0x1
-#define bHTSIG2_GI                			0x80
-#define bHTSIG2_Smoothing         		0x01
-#define bHTSIG2_Sounding          		0x02
-#define bHTSIG2_Aggreaton         		0x08
-#define bHTSIG2_STBC              		0x30
-#define bHTSIG2_AdvCoding         		0x40
+/* Page 8 */
+#define bRFMOD                    	0x1
+#define bJapanMode                	0x2
+#define bCCKTxSC                  	0x30
+#define bCCKEn                    	0x1000000
+#define bOFDMEn                   	0x2000000
+#define bOFDMRxADCPhase           	0x10000
+#define bOFDMTxDACPhase           	0x40000
+#define bXATxAGC                  	0x3f
+#define bXBTxAGC                  	0xf00
+#define bXCTxAGC                  	0xf000
+#define bXDTxAGC                  	0xf0000
+#define bPAStart                  	0xf0000000
+#define bTRStart                  	0x00f00000
+#define bRFStart                  	0x0000f000
+#define bBBStart                  	0x000000f0
+#define bBBCCKStart               	0x0000000f
+/* Reg)x814 */
+#define bPAEnd                    	0xf
+#define bTREnd                    	0x0f000000
+#define bRFEnd                    	0x000f0000
+/* T2R */
+#define bCCAMask                  	0x000000f0
+#define bR2RCCAMask               	0x00000f00
+#define bHSSI_R2TDelay            	0xf8000000
+#define bHSSI_T2RDelay            	0xf80000
+/* Channel gain at continue TX. */
+#define bContTxHSSI               	0x400
+#define bIGFromCCK                	0x200
+#define bAGCAddress               	0x3f
+#define bRxHPTx                   	0x7000
+#define bRxHPT2R                  	0x38000
+#define bRxHPCCKIni               	0xc0000
+#define bAGCTxCode                	0xc00000
+#define bAGCRxCode                	0x300000
+#define b3WireDataLength          	0x800
+#define b3WireAddressLength       	0x400
+#define b3WireRFPowerDown         	0x1
+/*#define bHWSISelect               	0x8 */
+#define b5GPAPEPolarity           	0x40000000
+#define b2GPAPEPolarity           	0x80000000
+#define bRFSW_TxDefaultAnt        	0x3
+#define bRFSW_TxOptionAnt         	0x30
+#define bRFSW_RxDefaultAnt        	0x300
+#define bRFSW_RxOptionAnt         	0x3000
+#define bRFSI_3WireData           	0x1
+#define bRFSI_3WireClock          	0x2
+#define bRFSI_3WireLoad           	0x4
+#define bRFSI_3WireRW             	0x8
+/* 3-wire total control */
+#define bRFSI_3Wire               	0xf
+#define bRFSI_RFENV               	0x10
+#define bRFSI_TRSW                	0x20
+#define bRFSI_TRSWB               	0x40
+#define bRFSI_ANTSW               	0x100
+#define bRFSI_ANTSWB              	0x200
+#define bRFSI_PAPE                	0x400
+#define bRFSI_PAPE5G              	0x800
+#define bBandSelect               	0x1
+#define bHTSIG2_GI                	0x80
+#define bHTSIG2_Smoothing         	0x01
+#define bHTSIG2_Sounding          	0x02
+#define bHTSIG2_Aggreaton         	0x08
+#define bHTSIG2_STBC              	0x30
+#define bHTSIG2_AdvCoding         	0x40
 #define bHTSIG2_NumOfHTLTF        	0x300
-#define bHTSIG2_CRC8              		0x3fc
-#define bHTSIG1_MCS               		0x7f
-#define bHTSIG1_BandWidth         		0x80
-#define bHTSIG1_HTLength          		0xffff
-#define bLSIG_Rate                			0xf
-#define bLSIG_Reserved            		0x10
-#define bLSIG_Length              		0x1fffe
-#define bLSIG_Parity              			0x20
-#define bCCKRxPhase               		0x4
-#define bLSSIReadAddress          		0x3f000000   //LSSI "Read" Address
-#define bLSSIReadEdge             		0x80000000   //LSSI "Read" edge signal
-#define bLSSIReadBackData         		0xfff
-#define bLSSIReadOKFlag           		0x1000
-#define bCCKSampleRate            		0x8       //0: 44MHz, 1:88MHz
+#define bHTSIG2_CRC8              	0x3fc
+#define bHTSIG1_MCS               	0x7f
+#define bHTSIG1_BandWidth         	0x80
+#define bHTSIG1_HTLength          	0xffff
+#define bLSIG_Rate                	0xf
+#define bLSIG_Reserved            	0x10
+#define bLSIG_Length              	0x1fffe
+#define bLSIG_Parity              	0x20
+#define bCCKRxPhase               	0x4
+/* LSSI "read" address */
+#define bLSSIReadAddress          	0x3f000000
+/* LSSI "read" edge signal */
+#define bLSSIReadEdge             	0x80000000
+#define bLSSIReadBackData         	0xfff
+#define bLSSIReadOKFlag           	0x1000
+/* 0: 44 MHz, 1: 88MHz */
+#define bCCKSampleRate            	0x8
 
-#define bRegulator0Standby        		0x1
-#define bRegulatorPLLStandby      		0x2
-#define bRegulator1Standby        		0x4
-#define bPLLPowerUp               		0x8
-#define bDPLLPowerUp              		0x10
-#define bDA10PowerUp              		0x20
-#define bAD7PowerUp               		0x200
-#define bDA6PowerUp               		0x2000
-#define bXtalPowerUp              		0x4000
-#define b40MDClkPowerUP           		0x8000
-#define bDA6DebugMode             		0x20000
-#define bDA6Swing                 			0x380000
-#define bADClkPhase               		0x4000000
-#define b80MClkDelay              		0x18000000
-#define bAFEWatchDogEnable        		0x20000000
-#define bXtalCap                			0x0f000000
-#define bXtalCap01                			0xc0000000
-#define bXtalCap23                			0x3
-#define bXtalCap92x					0x0f000000
-#define bIntDifClkEnable          		0x400
-#define bExtSigClkEnable         	 	0x800
+#define bRegulator0Standby        	0x1
+#define bRegulatorPLLStandby      	0x2
+#define bRegulator1Standby        	0x4
+#define bPLLPowerUp               	0x8
+#define bDPLLPowerUp              	0x10
+#define bDA10PowerUp              	0x20
+#define bAD7PowerUp               	0x200
+#define bDA6PowerUp               	0x2000
+#define bXtalPowerUp              	0x4000
+#define b40MDClkPowerUP           	0x8000
+#define bDA6DebugMode             	0x20000
+#define bDA6Swing                 	0x380000
+#define bADClkPhase               	0x4000000
+#define b80MClkDelay              	0x18000000
+#define bAFEWatchDogEnable        	0x20000000
+#define bXtalCap                	0x0f000000
+#define bXtalCap01                	0xc0000000
+#define bXtalCap23                	0x3
+#define bXtalCap92x			0x0f000000
+#define bIntDifClkEnable          	0x400
+#define bExtSigClkEnable         	0x800
 #define bBandgapMbiasPowerUp      	0x10000
-#define bAD11SHGain               		0xc0000
-#define bAD11InputRange           		0x700000
-#define bAD11OPCurrent            		0x3800000
-#define bIPathLoopback            		0x4000000
-#define bQPathLoopback            		0x8000000
-#define bAFELoopback              		0x10000000
-#define bDA10Swing                		0x7e0
-#define bDA10Reverse              		0x800
-#define bDAClkSource              		0x1000
-#define bAD7InputRange            		0x6000
-#define bAD7Gain                  			0x38000
-#define bAD7OutputCMMode          		0x40000
-#define bAD7InputCMMode           		0x380000
-#define bAD7Current               			0xc00000
-#define bRegulatorAdjust          		0x7000000
-#define bAD11PowerUpAtTx          		0x1
-#define bDA10PSAtTx               		0x10
-#define bAD11PowerUpAtRx          		0x100
-#define bDA10PSAtRx               		0x1000
+#define bAD11SHGain               	0xc0000
+#define bAD11InputRange           	0x700000
+#define bAD11OPCurrent            	0x3800000
+#define bIPathLoopback            	0x4000000
+#define bQPathLoopback            	0x8000000
+#define bAFELoopback              	0x10000000
+#define bDA10Swing                	0x7e0
+#define bDA10Reverse              	0x800
+#define bDAClkSource              	0x1000
+#define bAD7InputRange            	0x6000
+#define bAD7Gain                  	0x38000
+#define bAD7OutputCMMode          	0x40000
+#define bAD7InputCMMode           	0x380000
+#define bAD7Current               	0xc00000
+#define bRegulatorAdjust          	0x7000000
+#define bAD11PowerUpAtTx          	0x1
+#define bDA10PSAtTx               	0x10
+#define bAD11PowerUpAtRx          	0x100
+#define bDA10PSAtRx               	0x1000
 
-#define bCCKRxAGCFormat           		0x200
+#define bCCKRxAGCFormat           	0x200
 
-#define bPSDFFTSamplepPoint       		0xc000
-#define bPSDAverageNum            		0x3000
-#define bIQPathControl            		0xc00
-#define bPSDFreq                  			0x3ff
-#define bPSDAntennaPath           		0x30
-#define bPSDIQSwitch              		0x40
-#define bPSDRxTrigger             		0x400000
-#define bPSDTxTrigger             		0x80000000
-#define bPSDSineToneScale        		0x7f000000
-#define bPSDReport                			0xffff
+#define bPSDFFTSamplepPoint       	0xc000
+#define bPSDAverageNum            	0x3000
+#define bIQPathControl            	0xc00
+#define bPSDFreq                  	0x3ff
+#define bPSDAntennaPath           	0x30
+#define bPSDIQSwitch              	0x40
+#define bPSDRxTrigger             	0x400000
+#define bPSDTxTrigger             	0x80000000
+#define bPSDSineToneScale        	0x7f000000
+#define bPSDReport                	0xffff
 
-//page-9
-#define bOFDMTxSC                 		0x30000000
-#define bCCKTxOn                  			0x1
-#define bOFDMTxOn                 		0x2
-#define bDebugPage                		0xfff  //reset debug page and also HWord, LWord
-#define bDebugItem                		0xff   //reset debug page and LWord
-#define bAntL              	       		0x10
-#define bAntNonHT           	      			0x100
-#define bAntHT1               			0x1000
-#define bAntHT2                   			0x10000
-#define bAntHT1S1                 			0x100000
-#define bAntNonHTS1               		0x1000000
+/* Page 8 */
+#define bOFDMTxSC                 	0x30000000
+#define bCCKTxOn                  	0x1
+#define bOFDMTxOn                 	0x2
+/* Reset debug page and also HWord, LWord */
+#define bDebugPage                	0xfff
+/* Reset debug page and LWord */
+#define bDebugItem                	0xff
+#define bAntL              	       	0x10
+#define bAntNonHT           	      	0x100
+#define bAntHT1               		0x1000
+#define bAntHT2                   	0x10000
+#define bAntHT1S1                 	0x100000
+#define bAntNonHTS1               	0x1000000
 
-//page-a
-#define bCCKBBMode                		0x3
-#define bCCKTxPowerSaving         		0x80
-#define bCCKRxPowerSaving         		0x40
-#define bCCKSideBand              		0x10
-#define bCCKScramble              		0x8
-#define bCCKAntDiversity    		      	0x8000
+/* Page a */
+#define bCCKBBMode                	0x3
+#define bCCKTxPowerSaving         	0x80
+#define bCCKRxPowerSaving         	0x40
+#define bCCKSideBand              	0x10
+#define bCCKScramble              	0x8
+#define bCCKAntDiversity    		0x8000
 #define bCCKCarrierRecovery   	    	0x4000
-#define bCCKTxRate           		     	0x3000
-#define bCCKDCCancel             	 	0x0800
-#define bCCKISICancel             		0x0400
-#define bCCKMatchFilter           		0x0200
-#define bCCKEqualizer             		0x0100
-#define bCCKPreambleDetect       	 	0x800000
-#define bCCKFastFalseCCA          		0x400000
-#define bCCKChEstStart            		0x300000
-#define bCCKCCACount              		0x080000
-#define bCCKcs_lim                			0x070000
-#define bCCKBistMode              		0x80000000
-#define bCCKCCAMask             	  	0x40000000
+#define bCCKTxRate           		0x3000
+#define bCCKDCCancel             	0x0800
+#define bCCKISICancel             	0x0400
+#define bCCKMatchFilter           	0x0200
+#define bCCKEqualizer             	0x0100
+#define bCCKPreambleDetect       	0x800000
+#define bCCKFastFalseCCA          	0x400000
+#define bCCKChEstStart            	0x300000
+#define bCCKCCACount              	0x080000
+#define bCCKcs_lim                	0x070000
+#define bCCKBistMode              	0x80000000
+#define bCCKCCAMask             	0x40000000
 #define bCCKTxDACPhase         	   	0x4
-#define bCCKRxADCPhase         	   	0x20000000   //r_rx_clk
+/* r_rx_clk */
+#define bCCKRxADCPhase         	 	0x20000000
 #define bCCKr_cp_mode0         	   	0x0100
-#define bCCKTxDCOffset           	 	0xf0
-#define bCCKRxDCOffset           	 	0xf
-#define bCCKCCAMode              	 	0xc000
-#define bCCKFalseCS_lim           		0x3f00
-#define bCCKCS_ratio              		0xc00000
-#define bCCKCorgBit_sel           		0x300000
-#define bCCKPD_lim                			0x0f0000
-#define bCCKNewCCA                		0x80000000
-#define bCCKRxHPofIG              		0x8000
-#define bCCKRxIG                  			0x7f00
-#define bCCKLNAPolarity           		0x800000
-#define bCCKRx1stGain             		0x7f0000
-#define bCCKRFExtend              		0x20000000 //CCK Rx Iinital gain polarity
-#define bCCKRxAGCSatLevel        	 	0x1f000000
-#define bCCKRxAGCSatCount       	  	0xe0
-#define bCCKRxRFSettle            		0x1f       //AGCsamp_dly
-#define bCCKFixedRxAGC           	 	0x8000
-//#define bCCKRxAGCFormat         	 	0x4000   //remove to HSSI register 0x824
-#define bCCKAntennaPolarity      	 	0x2000
-#define bCCKTxFilterType          		0x0c00
+#define bCCKTxDCOffset           	0xf0
+#define bCCKRxDCOffset         		0xf
+#define bCCKCCAMode              	0xc000
+#define bCCKFalseCS_lim           	0x3f00
+#define bCCKCS_ratio              	0xc00000
+#define bCCKCorgBit_sel           	0x300000
+#define bCCKPD_lim                	0x0f0000
+#define bCCKNewCCA                	0x80000000
+#define bCCKRxHPofIG              	0x8000
+#define bCCKRxIG                  	0x7f00
+#define bCCKLNAPolarity           	0x800000
+#define bCCKRx1stGain             	0x7f0000
+/* CCK Rx Initial gain polarity */
+#define bCCKRFExtend              	0x20000000
+#define bCCKRxAGCSatLevel        	0x1f000000
+#define bCCKRxAGCSatCount       	0xe0
+/* AGCSAmp_dly */
+#define bCCKRxRFSettle            	0x1f
+#define bCCKFixedRxAGC           	0x8000
+/*#define bCCKRxAGCFormat         	0x4000  remove to HSSI register 0x824 */
+#define bCCKAntennaPolarity      	0x2000
+#define bCCKTxFilterType          	0x0c00
 #define bCCKRxAGCReportType   	   	0x0300
-#define bCCKRxDAGCEn              		0x80000000
-#define bCCKRxDAGCPeriod        	  	0x20000000
+#define bCCKRxDAGCEn              	0x80000000
+#define bCCKRxDAGCPeriod        	0x20000000
 #define bCCKRxDAGCSatLevel     	   	0x1f000000
-#define bCCKTimingRecovery       	 	0x800000
-#define bCCKTxC0                  			0x3f0000
-#define bCCKTxC1                  			0x3f000000
-#define bCCKTxC2                  			0x3f
-#define bCCKTxC3                  			0x3f00
-#define bCCKTxC4                  			0x3f0000
-#define bCCKTxC5                  			0x3f000000
-#define bCCKTxC6                  			0x3f
-#define bCCKTxC7                  			0x3f00
-#define bCCKDebugPort             		0xff0000
-#define bCCKDACDebug              		0x0f000000
-#define bCCKFalseAlarmEnable      		0x8000
-#define bCCKFalseAlarmRead        		0x4000
-#define bCCKTRSSI                 			0x7f
-#define bCCKRxAGCReport           		0xfe
-#define bCCKRxReport_AntSel       		0x80000000
-#define bCCKRxReport_MFOff        		0x40000000
+#define bCCKTimingRecovery       	0x800000
+#define bCCKTxC0                  	0x3f0000
+#define bCCKTxC1                  	0x3f000000
+#define bCCKTxC2                  	0x3f
+#define bCCKTxC3                  	0x3f00
+#define bCCKTxC4                  	0x3f0000
+#define bCCKTxC5                  	0x3f000000
+#define bCCKTxC6                  	0x3f
+#define bCCKTxC7                  	0x3f00
+#define bCCKDebugPort             	0xff0000
+#define bCCKDACDebug              	0x0f000000
+#define bCCKFalseAlarmEnable      	0x8000
+#define bCCKFalseAlarmRead        	0x4000
+#define bCCKTRSSI                 	0x7f
+#define bCCKRxAGCReport           	0xfe
+#define bCCKRxReport_AntSel       	0x80000000
+#define bCCKRxReport_MFOff        	0x40000000
 #define bCCKRxRxReport_SQLoss     	0x20000000
-#define bCCKRxReport_Pktloss      		0x10000000
+#define bCCKRxReport_Pktloss      	0x10000000
 #define bCCKRxReport_Lockedbit    	0x08000000
 #define bCCKRxReport_RateError    	0x04000000
-#define bCCKRxReport_RxRate       		0x03000000
+#define bCCKRxReport_RxRate       	0x03000000
 #define bCCKRxFACounterLower      	0xff
 #define bCCKRxFACounterUpper      	0xff000000
-#define bCCKRxHPAGCStart          		0xe000
-#define bCCKRxHPAGCFinal          		0x1c00
+#define bCCKRxHPAGCStart          	0xe000
+#define bCCKRxHPAGCFinal          	0x1c00
 
 #define bCCKRxFalseAlarmEnable    	0x8000
-#define bCCKFACounterFreeze       		0x4000
+#define bCCKFACounterFreeze       	0x4000
 
-#define bCCKTxPathSel             		0x10000000
-#define bCCKDefaultRxPath         		0xc000000
-#define bCCKOptionRxPath          		0x3000000
+#define bCCKTxPathSel             	0x10000000
+#define bCCKDefaultRxPath         	0xc000000
+#define bCCKOptionRxPath          	0x3000000
 
-//page c
-#define bNumOfSTF                			0x3
-#define bShift_L                 			0xc0
-#define bGI_TH                   			0xc
-#define bRxPathA                 			0x1
-#define bRxPathB                 			0x2
-#define bRxPathC                 			0x4
-#define bRxPathD                 			0x8
-#define bTxPathA                 			0x1
-#define bTxPathB                 			0x2
-#define bTxPathC                 			0x4
-#define bTxPathD                 			0x8
-#define bTRSSIFreq               			0x200
-#define bADCBackoff              			0x3000
-#define bDFIRBackoff             			0xc000
-#define bTRSSILatchPhase         		0x10000
-#define bRxIDCOffset             			0xff
-#define bRxQDCOffset             			0xff00
-#define bRxDFIRMode              		0x1800000
-#define bRxDCNFType              		0xe000000
-#define bRXIQImb_A               			0x3ff
-#define bRXIQImb_B               			0xfc00
-#define bRXIQImb_C               			0x3f0000
-#define bRXIQImb_D               			0xffc00000
-#define bDC_dc_Notch             		0x60000
-#define bRxNBINotch              			0x1f000000
-#define bPD_TH                   			0xf
-#define bPD_TH_Opt2              		0xc000
-#define bPWED_TH                 			0x700
-#define bIfMF_Win_L              			0x800
-#define bPD_Option               			0x1000
-#define bMF_Win_L                			0xe000
-#define bBW_Search_L             		0x30000
-#define bwin_enh_L               			0xc0000
-#define bBW_TH                   			0x700000
-#define bED_TH2                  			0x3800000
-#define bBW_option               			0x4000000
-#define bRatio_TH                			0x18000000
-#define bWindow_L                			0xe0000000
-#define bSBD_Option              			0x1
-#define bFrame_TH                			0x1c
-#define bFS_Option               			0x60
-#define bDC_Slope_check          		0x80
-#define bFGuard_Counter_DC_L     		0xe00
-#define bFrame_Weight_Short      		0x7000
-#define bSub_Tune                			0xe00000
-#define bFrame_DC_Length         		0xe000000
-#define bSBD_start_offset        		0x30000000
-#define bFrame_TH_2              		0x7
-#define bFrame_GI2_TH            		0x38
-#define bGI2_Sync_en             		0x40
-#define bSarch_Short_Early       		0x300
-#define bSarch_Short_Late        		0xc00
-#define bSarch_GI2_Late          		0x70000
-#define bCFOAntSum               		0x1
-#define bCFOAcc                  			0x2
-#define bCFOStartOffset          		0xc
-#define bCFOLookBack             		0x70
-#define bCFOSumWeight            		0x80
-#define bDAGCEnable              			0x10000
-#define bTXIQImb_A               			0x3ff
-#define bTXIQImb_B               			0xfc00
-#define bTXIQImb_C               			0x3f0000
-#define bTXIQImb_D               			0xffc00000
-#define bTxIDCOffset             			0xff
-#define bTxQDCOffset             			0xff00
-#define bTxDFIRMode              		0x10000
-#define bTxPesudoNoiseOn         		0x4000000
-#define bTxPesudoNoise_A         		0xff
-#define bTxPesudoNoise_B         		0xff00
-#define bTxPesudoNoise_C         		0xff0000
-#define bTxPesudoNoise_D         		0xff000000
-#define bCCADropOption           		0x20000
-#define bCCADropThres            		0xfff00000
-#define bEDCCA_H                 			0xf
-#define bEDCCA_L                 			0xf0
-#define bLambda_ED               0x300
-#define bRxInitialGain           0x7f
-#define bRxAntDivEn              0x80
-#define bRxAGCAddressForLNA      0x7f00
-#define bRxHighPowerFlow         0x8000
-#define bRxAGCFreezeThres        0xc0000
-#define bRxFreezeStep_AGC1       0x300000
-#define bRxFreezeStep_AGC2       0xc00000
-#define bRxFreezeStep_AGC3       0x3000000
-#define bRxFreezeStep_AGC0       0xc000000
-#define bRxRssi_Cmp_En           0x10000000
-#define bRxQuickAGCEn            0x20000000
-#define bRxAGCFreezeThresMode    0x40000000
-#define bRxOverFlowCheckType     0x80000000
-#define bRxAGCShift              0x7f
-#define bTRSW_Tri_Only           0x80
-#define bPowerThres              0x300
-#define bRxAGCEn                 0x1
-#define bRxAGCTogetherEn         0x2
-#define bRxAGCMin                0x4
-#define bRxHP_Ini                0x7
-#define bRxHP_TRLNA              0x70
-#define bRxHP_RSSI               0x700
-#define bRxHP_BBP1               0x7000
-#define bRxHP_BBP2               0x70000
-#define bRxHP_BBP3               0x700000
-#define bRSSI_H                  0x7f0000     //the threshold for high power
-#define bRSSI_Gen                0x7f000000   //the threshold for ant diversity
-#define bRxSettle_TRSW           0x7
-#define bRxSettle_LNA            0x38
-#define bRxSettle_RSSI           0x1c0
-#define bRxSettle_BBP            0xe00
-#define bRxSettle_RxHP           0x7000
-#define bRxSettle_AntSW_RSSI     0x38000
-#define bRxSettle_AntSW          0xc0000
-#define bRxProcessTime_DAGC      0x300000
-#define bRxSettle_HSSI           0x400000
-#define bRxProcessTime_BBPPW     0x800000
-#define bRxAntennaPowerShift     0x3000000
-#define bRSSITableSelect         0xc000000
-#define bRxHP_Final              0x7000000
-#define bRxHTSettle_BBP          0x7
-#define bRxHTSettle_HSSI         0x8
-#define bRxHTSettle_RxHP         0x70
-#define bRxHTSettle_BBPPW        0x80
-#define bRxHTSettle_Idle         0x300
-#define bRxHTSettle_Reserved     0x1c00
-#define bRxHTRxHPEn              0x8000
-#define bRxHTAGCFreezeThres      0x30000
-#define bRxHTAGCTogetherEn       0x40000
-#define bRxHTAGCMin              0x80000
-#define bRxHTAGCEn               0x100000
-#define bRxHTDAGCEn              0x200000
-#define bRxHTRxHP_BBP            0x1c00000
-#define bRxHTRxHP_Final          0xe0000000
-#define bRxPWRatioTH             0x3
-#define bRxPWRatioEn             0x4
-#define bRxMFHold                0x3800
-#define bRxPD_Delay_TH1          0x38
-#define bRxPD_Delay_TH2          0x1c0
-#define bRxPD_DC_COUNT_MAX       0x600
-//#define bRxMF_Hold               0x3800
+/* Page c */
+#define bNumOfSTF                	0x3
+#define bShift_L                 	0xc0
+#define bGI_TH                   	0xc
+#define bRxPathA                 	0x1
+#define bRxPathB                 	0x2
+#define bRxPathC                 	0x4
+#define bRxPathD                 	0x8
+#define bTxPathA                 	0x1
+#define bTxPathB                 	0x2
+#define bTxPathC                 	0x4
+#define bTxPathD                 	0x8
+#define bTRSSIFreq               	0x200
+#define bADCBackoff              	0x3000
+#define bDFIRBackoff             	0xc000
+#define bTRSSILatchPhase         	0x10000
+#define bRxIDCOffset             	0xff
+#define bRxQDCOffset             	0xff00
+#define bRxDFIRMode              	0x1800000
+#define bRxDCNFType              	0xe000000
+#define bRXIQImb_A               	0x3ff
+#define bRXIQImb_B               	0xfc00
+#define bRXIQImb_C               	0x3f0000
+#define bRXIQImb_D               	0xffc00000
+#define bDC_dc_Notch             	0x60000
+#define bRxNBINotch              	0x1f000000
+#define bPD_TH                   	0xf
+#define bPD_TH_Opt2              	0xc000
+#define bPWED_TH                 	0x700
+#define bIfMF_Win_L              	0x800
+#define bPD_Option               	0x1000
+#define bMF_Win_L                	0xe000
+#define bBW_Search_L             	0x30000
+#define bwin_enh_L               	0xc0000
+#define bBW_TH                   	0x700000
+#define bED_TH2                  	0x3800000
+#define bBW_option               	0x4000000
+#define bRatio_TH                	0x18000000
+#define bWindow_L                	0xe0000000
+#define bSBD_Option              	0x1
+#define bFrame_TH                	0x1c
+#define bFS_Option               	0x60
+#define bDC_Slope_check          	0x80
+#define bFGuard_Counter_DC_L     	0xe00
+#define bFrame_Weight_Short      	0x7000
+#define bSub_Tune                	0xe00000
+#define bFrame_DC_Length         	0xe000000
+#define bSBD_start_offset        	0x30000000
+#define bFrame_TH_2              	0x7
+#define bFrame_GI2_TH            	0x38
+#define bGI2_Sync_en             	0x40
+#define bSarch_Short_Early       	0x300
+#define bSarch_Short_Late        	0xc00
+#define bSarch_GI2_Late          	0x70000
+#define bCFOAntSum               	0x1
+#define bCFOAcc                  	0x2
+#define bCFOStartOffset          	0xc
+#define bCFOLookBack             	0x70
+#define bCFOSumWeight            	0x80
+#define bDAGCEnable              	0x10000
+#define bTXIQImb_A               	0x3ff
+#define bTXIQImb_B               	0xfc00
+#define bTXIQImb_C               	0x3f0000
+#define bTXIQImb_D               	0xffc00000
+#define bTxIDCOffset             	0xff
+#define bTxQDCOffset             	0xff00
+#define bTxDFIRMode              	0x10000
+#define bTxPesudoNoiseOn         	0x4000000
+#define bTxPesudoNoise_A         	0xff
+#define bTxPesudoNoise_B         	0xff00
+#define bTxPesudoNoise_C         	0xff0000
+#define bTxPesudoNoise_D         	0xff000000
+#define bCCADropOption           	0x20000
+#define bCCADropThres            	0xfff00000
+#define bEDCCA_H                 	0xf
+#define bEDCCA_L                 	0xf0
+#define bLambda_ED               	0x300
+#define bRxInitialGain           	0x7f
+#define bRxAntDivEn              	0x80
+#define bRxAGCAddressForLNA      	0x7f00
+#define bRxHighPowerFlow         	0x8000
+#define bRxAGCFreezeThres        	0xc0000
+#define bRxFreezeStep_AGC1       	0x300000
+#define bRxFreezeStep_AGC2       	0xc00000
+#define bRxFreezeStep_AGC3       	0x3000000
+#define bRxFreezeStep_AGC0       	0xc000000
+#define bRxRssi_Cmp_En           	0x10000000
+#define bRxQuickAGCEn            	0x20000000
+#define bRxAGCFreezeThresMode    	0x40000000
+#define bRxOverFlowCheckType     	0x80000000
+#define bRxAGCShift              	0x7f
+#define bTRSW_Tri_Only           	0x80
+#define bPowerThres              	0x300
+#define bRxAGCEn                	0x1
+#define bRxAGCTogetherEn         	0x2
+#define bRxAGCMin                	0x4
+#define bRxHP_Ini                	0x7
+#define bRxHP_TRLNA              	0x70
+#define bRxHP_RSSI               	0x700
+#define bRxHP_BBP1               	0x7000
+#define bRxHP_BBP2               	0x70000
+#define bRxHP_BBP3               	0x700000
+/* The threshold for high power */
+#define bRSSI_H                  	0x7f0000
+/* The threshold for ant diversity */
+#define bRSSI_Gen                	0x7f000000
+#define bRxSettle_TRSW           	0x7
+#define bRxSettle_LNA            	0x38
+#define bRxSettle_RSSI           	0x1c0
+#define bRxSettle_BBP            	0xe00
+#define bRxSettle_RxHP           	0x7000
+#define bRxSettle_AntSW_RSSI     	0x38000
+#define bRxSettle_AntSW          	0xc0000
+#define bRxProcessTime_DAGC      	0x300000
+#define bRxSettle_HSSI           	0x400000
+#define bRxProcessTime_BBPPW     	0x800000
+#define bRxAntennaPowerShift     	0x3000000
+#define bRSSITableSelect         	0xc000000
+#define bRxHP_Final              	0x7000000
+#define bRxHTSettle_BBP          	0x7
+#define bRxHTSettle_HSSI         	0x8
+#define bRxHTSettle_RxHP         	0x70
+#define bRxHTSettle_BBPPW        	0x80
+#define bRxHTSettle_Idle         	0x300
+#define bRxHTSettle_Reserved     	0x1c00
+#define bRxHTRxHPEn              	0x8000
+#define bRxHTAGCFreezeThres      	0x30000
+#define bRxHTAGCTogetherEn       	0x40000
+#define bRxHTAGCMin              	0x80000
+#define bRxHTAGCEn               	0x100000
+#define bRxHTDAGCEn              	0x200000
+#define bRxHTRxHP_BBP            	0x1c00000
+#define bRxHTRxHP_Final          	0xe0000000
+#define bRxPWRatioTH             	0x3
+#define bRxPWRatioEn             	0x4
+#define bRxMFHold                	0x3800
+#define bRxPD_Delay_TH1          	0x38
+#define bRxPD_Delay_TH2          	0x1c0
+#define bRxPD_DC_COUNT_MAX       	0x600
+/*#define bRxMF_Hold               	0x3800*/
 #define bRxPD_Delay_TH           0x8000
 #define bRxProcess_Delay         0xf0000
 #define bRxSearchrange_GI2_Early 0x700000
@@ -659,7 +692,7 @@
 
 #define bExtLNAGain              0x7c00
 
-//page d
+/* Page d */
 #define bSTBCEn                  0x4
 #define bAntennaMapping          0x10
 #define bNss                     0x20
@@ -669,12 +702,12 @@
 #define bOFDMContinueTx          0x10000000
 #define bOFDMSingleCarrier       0x20000000
 #define bOFDMSingleTone          0x40000000
-//#define bRxPath1                 0x01
-//#define bRxPath2                 0x02
-//#define bRxPath3                 0x04
-//#define bRxPath4                 0x08
-//#define bTxPath1                 0x10
-//#define bTxPath2                 0x20
+/*#define bRxPath1                 0x01
+#define bRxPath2                 0x02
+#define bRxPath3                 0x04
+#define bRxPath4                 0x08
+#define bTxPath1                 0x10
+#define bTxPath2                 0x20*/
 #define bHTDetect                0x100
 #define bCFOEn                   0x10000
 #define bCFOValue                0xfff00000
@@ -687,8 +720,10 @@
 #define bCounter_MCSNoSupport    0xffff
 #define bCounter_FastSync        0xffff
 #define bShortCFO                0xfff
-#define bShortCFOTLength         12   //total
-#define bShortCFOFLength         11   //fraction
+/* total */
+#define bShortCFOTLength         12
+/* fraction */
+#define bShortCFOFLength         11
 #define bLongCFO                 0x7ff
 #define bLongCFOTLength          11
 #define bLongCFOFLength          11
@@ -765,18 +800,18 @@
 #define bUChCfg                  0x7000000
 #define bUpdEqz                  0x8000000
 
-//page e
-#define bTxAGCRate18_06			0x7f7f7f7f
-#define bTxAGCRate54_24			0x7f7f7f7f
+/* Page e */
+#define bTxAGCRate18_06		0x7f7f7f7f
+#define bTxAGCRate54_24		0x7f7f7f7f
 #define bTxAGCRateMCS32		0x7f
-#define bTxAGCRateCCK			0x7f00
+#define bTxAGCRateCCK		0x7f00
 #define bTxAGCRateMCS3_MCS0	0x7f7f7f7f
 #define bTxAGCRateMCS7_MCS4	0x7f7f7f7f
 #define bTxAGCRateMCS11_MCS8	0x7f7f7f7f
 #define bTxAGCRateMCS15_MCS12	0x7f7f7f7f
 
 
-//Rx Pseduo noise
+/* Rx Pseduo noise */
 #define bRxPesudoNoiseOn         0x20000000
 #define bRxPesudoNoise_A         0xff
 #define bRxPesudoNoise_B         0xff00
@@ -787,8 +822,7 @@
 #define bPesudoNoiseState_C      0xffff
 #define bPesudoNoiseState_D      0xffff0000
 
-//RF
-//Zebra1
+/* RF Zebra 1 */
 #define bZebra1_HSSIEnable        0x8
 #define bZebra1_TRxControl        0xc00
 #define bZebra1_TRxGainSetting    0x07f
@@ -799,7 +833,7 @@
 #define bZebra1_TxLPFBW           0x400
 #define bZebra1_RxLPFBW           0x600
 
-//Zebra4
+/* Zebra4 */
 #define bRTL8256RegModeCtrl1      0x100
 #define bRTL8256RegModeCtrl0      0x40
 #define bRTL8256_TxLPFBW          0x18
@@ -810,7 +844,7 @@
 #define bRTL8258_RxLPFBW          0xc00
 #define bRTL8258_RSSILPFBW        0xc0
 
-//byte endable for sb_write
+/* byte endable for sb_write */
 #define bByte0                    0x1
 #define bByte1                    0x2
 #define bByte2                    0x4
@@ -819,7 +853,7 @@
 #define bWord1                    0xc
 #define bDWord                    0xf
 
-//for PutRegsetting & GetRegSetting BitMask
+/* for PutRegsetting & GetRegSetting BitMask */
 #define bMaskByte0                0xff
 #define bMaskByte1                0xff00
 #define bMaskByte2                0xff0000
@@ -828,7 +862,7 @@
 #define bMaskLWord                0x0000ffff
 #define bMaskDWord                0xffffffff
 
-//for PutRFRegsetting & GetRFRegSetting BitMask
+/* for PutRFRegsetting & GetRFRegSetting BitMask */
 #define bMask12Bits               0xfff
 
 #define bEnable                   0x1
@@ -837,14 +871,16 @@
 #define LeftAntenna               0x0
 #define RightAntenna              0x1
 
-#define tCheckTxStatus            500   //500ms
-#define tUpdateRxCounter          100   //100ms
+/* 500 ms */
+#define tCheckTxStatus            500
+/* 100 ms */
+#define tUpdateRxCounter          100
 
 #define rateCCK     0
 #define rateOFDM    1
 #define rateHT      2
 
-//define Register-End
+/* define Register-End */
 #define bPMAC_End                 0x1ff
 #define bFPGAPHY0_End             0x8ff
 #define bFPGAPHY1_End             0x9ff
@@ -852,12 +888,12 @@
 #define bOFDMPHY0_End             0xcff
 #define bOFDMPHY1_End             0xdff
 
-//define max debug item in each debug page
-//#define bMaxItem_FPGA_PHY0        0x9
-//#define bMaxItem_FPGA_PHY1        0x3
-//#define bMaxItem_PHY_11B          0x16
-//#define bMaxItem_OFDM_PHY0        0x29
-//#define bMaxItem_OFDM_PHY1        0x0
+/*#define max debug item in each debug page
+#define bMaxItem_FPGA_PHY0        0x9
+#define bMaxItem_FPGA_PHY1        0x3
+#define bMaxItem_PHY_11B          0x16
+#define bMaxItem_OFDM_PHY0        0x29
+#define bMaxItem_OFDM_PHY1        0x0 */
 
 #define bPMACControl              0x0
 #define bWMACControl              0x1
@@ -868,11 +904,12 @@
 #define PathC                     0x2
 #define PathD                     0x3
 
-#define	rRTL8256RxMixerPole		0xb
-#define 	bZebraRxMixerPole		0x6
-#define 	rRTL8256TxBBOPBias        0x9
-#define 	bRTL8256TxBBOPBias       0x400
-#define 	rRTL8256TxBBBW             19
-#define 	bRTL8256TxBBBW            	0x18
+#define rRTL8256RxMixerPole	0xb
+#define bZebraRxMixerPole	0x6
+#define rRTL8256TxBBOPBias	0x9
+#define bRTL8256TxBBOPBias	0x400
+#define rRTL8256TxBBBW		19
+#define bRTL8256TxBBBW		0x18
 
-#endif	//__INC_HAL8190PCIPHYREG_H
+
+#endif	/* __INC_HAL8190PCIPHYREG_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c	2010-05-16 17:17:36.000000000 -0400
@@ -226,19 +226,20 @@ out:
 void __exit ieee80211_crypto_deinit(void)
 {
 	struct list_head *ptr, *n;
+	struct ieee80211_crypto_alg *alg = NULL;
 
 	if (hcrypt == NULL)
 		return;
 
-	for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
-	     ptr = n, n = ptr->next) {
-		struct ieee80211_crypto_alg *alg =
-			(struct ieee80211_crypto_alg *) ptr;
-		list_del(ptr);
-		printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
-		       "'%s' (deinit)\n", alg->ops->name);
-		kfree(alg);
+	list_for_each_safe(ptr, n, &hcrypt->algs) {
+		alg = list_entry(ptr, struct ieee80211_crypto_alg, list);
+		if (alg) {
+			list_del(ptr);
+			printk(KERN_DEBUG
+			       "ieee80211_crypt: unregistered algorithm '%s' (deinit)\n",
+			       alg->ops->name);
+			kfree(alg);
+		}
 	}
-
 	kfree(hcrypt);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c	2010-05-16 17:17:36.000000000 -0400
@@ -288,7 +288,7 @@ static int ieee80211_ccmp_decrypt(struct
 	if (!(keyidx & (1 << 5))) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "CCMP: received packet without ExtIV"
-			       " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+			       " flag from %pM\n", hdr->addr2);
 		}
 		key->dot11RSNAStatsCCMPFormatErrors++;
 		return -2;
@@ -301,9 +301,9 @@ static int ieee80211_ccmp_decrypt(struct
 	}
 	if (!key->key_set) {
 		if (net_ratelimit()) {
-			printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
+			printk(KERN_DEBUG "CCMP: received packet from %pM"
 			       " with keyid=%d that does not have a configured"
-			       " key\n", MAC_ARG(hdr->addr2), keyidx);
+			       " key\n", hdr->addr2, keyidx);
 		}
 		return -3;
 	}
@@ -318,11 +318,9 @@ static int ieee80211_ccmp_decrypt(struct
 
 	if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
 		if (net_ratelimit()) {
-			printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
-			       " previous PN %02x%02x%02x%02x%02x%02x "
-			       "received PN %02x%02x%02x%02x%02x%02x\n",
-			       MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
-			       MAC_ARG(pn));
+			printk(KERN_DEBUG "CCMP: replay detected: STA=%pM"
+			       " previous PN %pm received PN %pm\n",
+			       hdr->addr2, key->rx_pn, pn);
 		}
 		key->dot11RSNAStatsCCMPReplays++;
 		return -4;
@@ -359,7 +357,7 @@ static int ieee80211_ccmp_decrypt(struct
 		if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
 			if (net_ratelimit()) {
 				printk(KERN_DEBUG "CCMP: decrypt failed: STA="
-				MAC_FMT "\n", MAC_ARG(hdr->addr2));
+				"%pM\n", hdr->addr2);
 			}
 			key->dot11RSNAStatsCCMPDecryptErrors++;
 			return -5;
@@ -435,11 +433,10 @@ static char * ieee80211_ccmp_print_stats
 {
 	struct ieee80211_ccmp_data *ccmp = priv;
 	p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
-		     "tx_pn=%02x%02x%02x%02x%02x%02x "
-		     "rx_pn=%02x%02x%02x%02x%02x%02x "
+		     "tx_pn=%pm rx_pn=%pm "
 		     "format_errors=%d replays=%d decrypt_errors=%d\n",
 		     ccmp->key_idx, ccmp->key_set,
-		     MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
+		     ccmp->tx_pn, ccmp->rx_pn,
 		     ccmp->dot11RSNAStatsCCMPFormatErrors,
 		     ccmp->dot11RSNAStatsCCMPReplays,
 		     ccmp->dot11RSNAStatsCCMPDecryptErrors);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c	2010-05-16 17:17:36.000000000 -0400
@@ -410,7 +410,7 @@ static int ieee80211_tkip_decrypt(struct
 	if (!(keyidx & (1 << 5))) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "TKIP: received packet without ExtIV"
-			       " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+			       " flag from %pM\n", hdr->addr2);
 		}
 		return -2;
 	}
@@ -422,9 +422,9 @@ static int ieee80211_tkip_decrypt(struct
 	}
 	if (!tkey->key_set) {
 		if (net_ratelimit()) {
-			printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
+			printk(KERN_DEBUG "TKIP: received packet from %pM"
 			       " with keyid=%d that does not have a configured"
-			       " key\n", MAC_ARG(hdr->addr2), keyidx);
+			       " key\n", hdr->addr2, keyidx);
 		}
 		return -3;
 	}
@@ -437,9 +437,9 @@ static int ieee80211_tkip_decrypt(struct
 		if (iv32 < tkey->rx_iv32 ||
 		(iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
 			if (net_ratelimit()) {
-				printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
+				printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
 				" previous TSC %08x%04x received TSC "
-				"%08x%04x\n", MAC_ARG(hdr->addr2),
+				"%08x%04x\n", hdr->addr2,
 				tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
 			}
 			tkey->dot11RSNAStatsTKIPReplays++;
@@ -460,8 +460,8 @@ static int ieee80211_tkip_decrypt(struct
 		if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
 			if (net_ratelimit()) {
 				printk(KERN_DEBUG ": TKIP: failed to decrypt "
-						"received packet from " MAC_FMT "\n",
-						MAC_ARG(hdr->addr2));
+						"received packet from %pM\n",
+						hdr->addr2);
 			}
 			return -7;
 		}
@@ -480,7 +480,7 @@ static int ieee80211_tkip_decrypt(struct
 			}
 			if (net_ratelimit()) {
 				printk(KERN_DEBUG "TKIP: ICV error detected: STA="
-				MAC_FMT "\n", MAC_ARG(hdr->addr2));
+				"%pM\n", hdr->addr2);
 			}
 			tkey->dot11RSNAStatsTKIPICVErrors++;
 			return -5;
@@ -635,8 +635,8 @@ static int ieee80211_michael_mic_verify(
 		struct ieee80211_hdr_4addr *hdr;
 		hdr = (struct ieee80211_hdr_4addr *) skb->data;
 		printk(KERN_DEBUG "%s: Michael MIC verification failed for "
-		       "MSDU from " MAC_FMT " keyidx=%d\n",
-		       skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
+		       "MSDU from %pM keyidx=%d\n",
+		       skb->dev ? skb->dev->name : "N/A", hdr->addr2,
 		       keyidx);
 		if (skb->dev)
 			ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/jiffies.h>
 #include <linux/timer.h>
 #include <linux/sched.h>
+#include <linux/semaphore.h>
 
 #include <linux/delay.h>
 #include <linux/wireless.h>
@@ -195,10 +196,6 @@ extern u32 ieee80211_debug_level;
 #define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0)
 #endif	/* CONFIG_IEEE80211_DEBUG */
 
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2], \
-		   ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5]
-
 /*
  * To use the debug system;
  *
@@ -609,16 +606,6 @@ struct ieee80211_hdr_2addr {
         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;
@@ -1672,7 +1659,7 @@ static inline u8 *ieee80211_get_payload(
         case IEEE80211_2ADDR_LEN:
                 return ((struct ieee80211_hdr_2addr *)hdr)->payload;
         case IEEE80211_3ADDR_LEN:
-                return ((struct ieee80211_hdr_3addr *)hdr)->payload;
+                return (void *)hdr+sizeof(struct ieee80211_hdr_3addr);
         case IEEE80211_4ADDR_LEN:
                 return ((struct ieee80211_hdr_4addr *)hdr)->payload;
         }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c	2010-05-16 17:17:36.000000000 -0400
@@ -262,7 +262,7 @@ static int store_debug_level(struct file
 			     unsigned long count, void *data)
 {
 	char buf[] = "0x00000000";
-	unsigned long len = min(sizeof(buf) - 1, count);
+	unsigned long len = min_t(unsigned long, sizeof(buf) - 1, count);
 	char *p = (char *)buf;
 	unsigned long val;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h	2010-05-16 17:17:36.000000000 -0400
@@ -201,7 +201,7 @@ typedef union _frameqos {
 static inline u8 Frame_QoSTID(u8 *buf)
 {
 	struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)buf;
-	u16 fc = le16_to_cpu(hdr->frame_ctl);
+	u16 fc = le16_to_cpu(hdr->frame_control);
 
 	return (u8)((frameqos *)(buf +
 		(((fc & IEEE80211_FCTL_TODS) &&
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -314,8 +314,8 @@ ieee80211_rx_frame_decrypt(struct ieee80
 	    strcmp(crypt->ops->name, "TKIP") == 0) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-			       "received packet from " MAC_FMT "\n",
-			       ieee->dev->name, MAC_ARG(hdr->addr2));
+			       "received packet from %pM\n",
+			       ieee->dev->name, hdr->addr2);
 		}
 		return -1;
 	}
@@ -326,8 +326,8 @@ ieee80211_rx_frame_decrypt(struct ieee80
 	atomic_dec(&crypt->refcnt);
 	if (res < 0) {
 		IEEE80211_DEBUG_DROP(
-			"decryption failed (SA=" MAC_FMT
-			") res=%d\n", MAC_ARG(hdr->addr2), res);
+			"decryption failed (SA=%pM"
+			") res=%d\n", hdr->addr2, res);
 		if (res == -2)
 			IEEE80211_DEBUG_DROP("Decryption failed ICV "
 					     "mismatch (key %d)\n",
@@ -364,8 +364,8 @@ ieee80211_rx_frame_decrypt_msdu(struct i
 	atomic_dec(&crypt->refcnt);
 	if (res < 0) {
 		printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
-		       " (SA=" MAC_FMT " keyidx=%d)\n",
-		       ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
+		       " (SA=%pM keyidx=%d)\n",
+		       ieee->dev->name, hdr->addr2, keyidx);
 		return -1;
 	}
 
@@ -744,7 +744,7 @@ u8 parse_subframe(struct sk_buff *skb,
 		  struct ieee80211_rxb *rxb,u8* src,u8* dst)
 {
 	struct ieee80211_hdr_3addr  *hdr = (struct ieee80211_hdr_3addr* )skb->data;
-	u16		fc = le16_to_cpu(hdr->frame_ctl);
+	u16		fc = le16_to_cpu(hdr->frame_control);
 
 	u16		LLCOffset= sizeof(struct ieee80211_hdr_3addr);
 	u16		ChkLength;
@@ -756,7 +756,7 @@ u8 parse_subframe(struct sk_buff *skb,
 	struct sk_buff *sub_skb;
 	u8             *data_ptr;
 	/* just for debug purpose */
-	SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctl));
+	SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctrl));
 
 	if((IEEE80211_QOS_HAS_SEQ(fc))&&\
 			(((frameqos *)(skb->data + IEEE80211_3ADDR_LEN))->field.reserved)) {
@@ -939,8 +939,8 @@ int ieee80211_rtl_rx(struct ieee80211_de
 			 * frames silently instead of filling system log with
 			 * these reports. */
 			IEEE80211_DEBUG_DROP("Decryption failed (not set)"
-					     " (SA=" MAC_FMT ")\n",
-					     MAC_ARG(hdr->addr2));
+					     " (SA=%pM)\n",
+					     hdr->addr2);
 			ieee->ieee_stats.rx_discards_undecryptable++;
 			goto rx_dropped;
 		}
@@ -1143,8 +1143,8 @@ int ieee80211_rtl_rx(struct ieee80211_de
 		} else {
 			IEEE80211_DEBUG_DROP(
 				"encryption configured, but RX "
-				"frame not encrypted (SA=" MAC_FMT ")\n",
-				MAC_ARG(hdr->addr2));
+				"frame not encrypted (SA=%pM)\n",
+				hdr->addr2);
 			goto rx_dropped;
 		}
 	}
@@ -1163,9 +1163,9 @@ int ieee80211_rtl_rx(struct ieee80211_de
 	    !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
 		IEEE80211_DEBUG_DROP(
 			"dropped unencrypted RX data "
-			"frame from " MAC_FMT
+			"frame from %pM"
 			" (drop_unencrypted=1)\n",
-			MAC_ARG(hdr->addr2));
+			hdr->addr2);
 		goto rx_dropped;
 	}
 /*
@@ -2159,11 +2159,11 @@ static inline int ieee80211_network_init
 	}
 
 	if (network->mode == 0) {
-		IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
+		IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
 				     "network.\n",
 				     escape_essid(network->ssid,
 						  network->ssid_len),
-				     MAC_ARG(network->bssid));
+				     network->bssid);
 		return 1;
 	}
 
@@ -2345,9 +2345,9 @@ static inline void ieee80211_process_pro
 
 	memset(&network, 0, sizeof(struct ieee80211_network));
 	IEEE80211_DEBUG_SCAN(
-		"'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
+		"'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
 		escape_essid(info_element->data, info_element->len),
-		MAC_ARG(beacon->header.addr3),
+		beacon->header.addr3,
 		(beacon->capability & (1<<0xf)) ? '1' : '0',
 		(beacon->capability & (1<<0xe)) ? '1' : '0',
 		(beacon->capability & (1<<0xd)) ? '1' : '0',
@@ -2366,11 +2366,11 @@ static inline void ieee80211_process_pro
 		(beacon->capability & (1<<0x0)) ? '1' : '0');
 
 	if (ieee80211_network_init(ieee, beacon, &network, stats)) {
-		IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
+		IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
 				     escape_essid(info_element->data,
 						  info_element->len),
-				     MAC_ARG(beacon->header.addr3),
-				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
+				     beacon->header.addr3,
+				     WLAN_FC_GET_STYPE(beacon->header.frame_control) ==
 				     IEEE80211_STYPE_PROBE_RESP ?
 				     "PROBE RESPONSE" : "BEACON");
 		return;
@@ -2387,7 +2387,7 @@ static inline void ieee80211_process_pro
 		return;
 	if(ieee->bGlobalDomain)
 	{
-		if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
+		if (WLAN_FC_GET_STYPE(beacon->header.frame_control) == IEEE80211_STYPE_PROBE_RESP)
 		{
 			// Case 1: Country code
 			if(IS_COUNTRY_IE_VALID(ieee) )
@@ -2454,7 +2454,7 @@ static inline void ieee80211_process_pro
 		else
 			ieee->current_network.buseprotection = false;
 		}
-		if(is_beacon(beacon->header.frame_ctl))
+		if(is_beacon(beacon->header.frame_control))
 		{
 			if(ieee->state == IEEE80211_LINKED)
 				ieee->LinkDetectInfo.NumRecvBcnInPeriod++;
@@ -2478,11 +2478,11 @@ static inline void ieee80211_process_pro
 			/* If there are no more slots, expire the oldest */
 			list_del(&oldest->list);
 			target = oldest;
-			IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
+			IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
 					     "network list.\n",
 					     escape_essid(target->ssid,
 							  target->ssid_len),
-					     MAC_ARG(target->bssid));
+					     target->bssid);
 		} else {
 			/* Otherwise just pull from the free list */
 			target = list_entry(ieee->network_free_list.next,
@@ -2492,11 +2492,11 @@ static inline void ieee80211_process_pro
 
 
 #ifdef CONFIG_IEEE80211_DEBUG
-		IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
+		IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
 				     escape_essid(network.ssid,
 						  network.ssid_len),
-				     MAC_ARG(network.bssid),
-				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
+				     network.bssid,
+				     WLAN_FC_GET_STYPE(beacon->header.frame_control) ==
 				     IEEE80211_STYPE_PROBE_RESP ?
 				     "PROBE RESPONSE" : "BEACON");
 #endif
@@ -2505,11 +2505,11 @@ static inline void ieee80211_process_pro
 		if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
 			ieee80211_softmac_new_net(ieee,&network);
 	} else {
-		IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
+		IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
 				     escape_essid(target->ssid,
 						  target->ssid_len),
-				     MAC_ARG(target->bssid),
-				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
+				     target->bssid,
+				     WLAN_FC_GET_STYPE(beacon->header.frame_control) ==
 				     IEEE80211_STYPE_PROBE_RESP ?
 				     "PROBE RESPONSE" : "BEACON");
 
@@ -2519,7 +2519,7 @@ static inline void ieee80211_process_pro
 		 */
 		renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
 		//YJ,add,080819,for hidden ap
-		if(is_beacon(beacon->header.frame_ctl) == 0)
+		if(is_beacon(beacon->header.frame_control) == 0)
 			network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
 		//if(strncmp(network.ssid, "linksys-c",9) == 0)
 		//	printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
@@ -2535,7 +2535,7 @@ static inline void ieee80211_process_pro
 	}
 
 	spin_unlock_irqrestore(&ieee->lock, flags);
-	if (is_beacon(beacon->header.frame_ctl)&&is_same_network(&ieee->current_network, &network, ieee)&&\
+	if (is_beacon(beacon->header.frame_control)&&is_same_network(&ieee->current_network, &network, ieee)&&\
 		(ieee->state == IEEE80211_LINKED)) {
 		if(ieee->handle_beacon != NULL) {
 			ieee->handle_beacon(ieee->dev,beacon,&ieee->current_network);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 
 #include <linux/random.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include <asm/uaccess.h>
 #include "dot11d.h"
@@ -242,7 +243,7 @@ inline void softmac_mgmt_xmit(struct sk_
 		if(ieee->queue_stop){
 			enqueue_mgmt(ieee,skb);
 		}else{
-			header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
+			header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
 
 			if (ieee->seq_ctrl[0] == 0xFFF)
 				ieee->seq_ctrl[0] = 0;
@@ -260,7 +261,7 @@ inline void softmac_mgmt_xmit(struct sk_
 		spin_unlock_irqrestore(&ieee->lock, flags);
 		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
 
-		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
+		header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
 
 		if (ieee->seq_ctrl[0] == 0xFFF)
 			ieee->seq_ctrl[0] = 0;
@@ -302,7 +303,7 @@ inline void softmac_ps_mgmt_xmit(struct
 	//printk("=============>%s()\n", __FUNCTION__);
 	if(single){
 
-		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
+		header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
 
 		if (ieee->seq_ctrl[0] == 0xFFF)
 			ieee->seq_ctrl[0] = 0;
@@ -315,7 +316,7 @@ inline void softmac_ps_mgmt_xmit(struct
 
 	}else{
 
-		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
+		header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
 
 		if (ieee->seq_ctrl[0] == 0xFFF)
 			ieee->seq_ctrl[0] = 0;
@@ -347,7 +348,7 @@ inline struct sk_buff *ieee80211_probe_r
 	skb_reserve(skb, ieee->tx_headroom);
 
 	req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
-	req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
+	req->header.frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
 	req->header.duration_id = 0; //FIXME: is this OK ?
 
 	memset(req->header.addr1, 0xff, ETH_ALEN);
@@ -662,8 +663,8 @@ inline struct sk_buff *ieee80211_authent
 	auth = (struct ieee80211_authentication *)
 		skb_put(skb, sizeof(struct ieee80211_authentication));
 
-	auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
-	if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
+	auth->header.frame_control = IEEE80211_STYPE_AUTH;
+	if (challengelen) auth->header.frame_control |= IEEE80211_FCTL_WEP;
 
 	auth->header.duration_id = 0x013a; //FIXME
 
@@ -801,7 +802,7 @@ static struct sk_buff* ieee80211_probe_r
 		beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
 
 
-	beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
+	beacon_buf->header.frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
 	beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
 	beacon_buf->info_element[0].len = ssid_len;
 
@@ -880,7 +881,7 @@ struct sk_buff* ieee80211_assoc_resp(str
 	assoc = (struct ieee80211_assoc_response_frame *)
 		skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
 
-	assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
+	assoc->header.frame_control = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
 	memcpy(assoc->header.addr1, dest,ETH_ALEN);
 	memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
 	memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
@@ -935,7 +936,7 @@ struct sk_buff* ieee80211_auth_resp(stru
 	memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
 	memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
 	memcpy(auth->header.addr1, dest, ETH_ALEN);
-	auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
+	auth->header.frame_control = cpu_to_le16(IEEE80211_STYPE_AUTH);
 	return skb;
 
 
@@ -957,7 +958,7 @@ struct sk_buff* ieee80211_null_func(stru
 	memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
 	memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
 
-	hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
+	hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
 		IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
 		(pwr ? IEEE80211_FCTL_PM:0));
 
@@ -1083,7 +1084,7 @@ inline struct sk_buff *ieee80211_associa
 		skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
 
 
-	hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
+	hdr->header.frame_control = IEEE80211_STYPE_ASSOC_REQ;
 	hdr->header.duration_id= 37; //FIXME
 	memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
 	memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
@@ -1709,7 +1710,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_d
 		ieee80211_resp_to_assoc_rq(ieee, dest);
 	}
 
-	printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
+	printk(KERN_INFO"New client associated: %pM\n", dest);
 	//FIXME
 }
 
@@ -1940,13 +1941,13 @@ ieee80211_rx_frame_softmac(struct ieee80
 	if(!ieee->proto_started)
 		return 0;
 
-	switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
+	switch (WLAN_FC_GET_STYPE(header->frame_control)) {
 
 		case IEEE80211_STYPE_ASSOC_RESP:
 		case IEEE80211_STYPE_REASSOC_RESP:
 
 			IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
-					WLAN_FC_GET_STYPE(header->frame_ctl));
+					WLAN_FC_GET_STYPE(header->frame_control));
 			if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
 				ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
 				ieee->iw_mode == IW_MODE_INFRA){
@@ -2088,7 +2089,7 @@ ieee80211_rx_frame_softmac(struct ieee80
 			if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
 				ieee->state == IEEE80211_LINKED &&
 				ieee->iw_mode == IW_MODE_INFRA){
-				printk("==========>received disassoc/deauth(%x) frame, reason code:%x\n",WLAN_FC_GET_STYPE(header->frame_ctl), ((struct ieee80211_disassoc*)skb->data)->reason);
+				printk("==========>received disassoc/deauth(%x) frame, reason code:%x\n",WLAN_FC_GET_STYPE(header->frame_control), ((struct ieee80211_disassoc*)skb->data)->reason);
 				ieee->state = IEEE80211_ASSOCIATING;
 				ieee->softmac_stats.reassoc++;
 				ieee->is_roaming = true;
@@ -2145,8 +2146,8 @@ void ieee80211_softmac_xmit(struct ieee8
 	ieee80211_sta_wakeup(ieee,0);
 
 	/* update the tx status */
-//	ieee->stats.tx_bytes += txb->payload_size;
-//	ieee->stats.tx_packets++;
+	ieee->stats.tx_bytes += txb->payload_size;
+	ieee->stats.tx_packets++;
 	tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
 	if(tcb_desc->bMulticast) {
 		ieee->stats.multicast++;
@@ -2239,7 +2240,7 @@ void ieee80211_rtl_wake_queue(struct iee
 
 			header = (struct ieee80211_hdr_3addr  *) skb->data;
 
-			header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
+			header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
 
 			if (ieee->seq_ctrl[0] == 0xFFF)
 				ieee->seq_ctrl[0] = 0;
@@ -2574,7 +2575,7 @@ struct sk_buff *ieee80211_get_beacon_(st
 		return NULL;
 
 	b = (struct ieee80211_probe_response *) skb->data;
-	b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
+	b->header.frame_control = cpu_to_le16(IEEE80211_STYPE_BEACON);
 
 	return skb;
 
@@ -2590,7 +2591,7 @@ struct sk_buff *ieee80211_get_beacon(str
 		return NULL;
 
 	b = (struct ieee80211_probe_response *) skb->data;
-	b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
+	b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
 
 	if (ieee->seq_ctrl[0] == 0xFFF)
 		ieee->seq_ctrl[0] = 0;
@@ -3139,7 +3140,7 @@ inline struct sk_buff *ieee80211_disasso
 		return NULL;
 
 	disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
-	disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
+	disass->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
 	disass->header.duration_id = 0;
 
 	memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -199,8 +199,8 @@ int ieee80211_encrypt_fragment(
 		header = (struct rtl_ieee80211_hdr *)frag->data;
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-			       "TX packet to " MAC_FMT "\n",
-			       ieee->dev->name, MAC_ARG(header->addr1));
+			       "TX packet to %pM\n",
+			       ieee->dev->name, header->addr1);
 		}
 		return -1;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 ******************************************************************************/
 #include <linux/wireless.h>
 #include <linux/kmod.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 
 #include "ieee80211.h"
@@ -261,10 +262,10 @@ int ieee80211_wx_get_scan(struct ieee802
 		else
 			IEEE80211_DEBUG_SCAN(
 				"Not showing network '%s ("
-				MAC_FMT ")' due to age (%lums).\n",
+				"%pM)' due to age (%lums).\n",
 				escape_essid(network->ssid,
 					     network->ssid_len),
-				MAC_ARG(network->bssid),
+				network->bssid,
 				(jiffies - network->last_scanned) / (HZ / 100));
 	}
 
@@ -731,7 +732,7 @@ int ieee80211_wx_set_auth(struct ieee802
 #if 1
 	case IW_AUTH_WPA_ENABLED:
 		ieee->wpa_enabled = (data->value)?1:0;
-		//printk("enalbe wpa:%d\n", ieee->wpa_enabled);
+		//printk("enable wpa:%d\n", ieee->wpa_enabled);
 		break;
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c	2010-05-16 17:17:36.000000000 -0400
@@ -113,7 +113,7 @@ static struct sk_buff* ieee80211_ADDBA(s
 	u16 tmp = 0;
 	u16 len = ieee->tx_headroom + 9;
 	//category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) +  BA Timeout Value(2) +  BA Start SeqCtrl(2)(or StatusCode(2))
-	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev);
+	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev);
 	if (pBA == NULL||ieee == NULL)
 	{
 		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
@@ -136,7 +136,7 @@ static struct sk_buff* ieee80211_ADDBA(s
 
 	memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN);
 
-	BAReq->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
+	BAReq->frame_control = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
 
 	//tag += sizeof( struct ieee80211_hdr_3addr); //move to action field
 	tag = (u8*)skb_put(skb, 9);
@@ -200,7 +200,7 @@ static struct sk_buff* ieee80211_DELBA(
 	u16 len = 6 + ieee->tx_headroom;
 
 	if (net_ratelimit())
-	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst));
+	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst);
 
 	memset(&DelbaParamSet, 0, 2);
 
@@ -221,7 +221,7 @@ static struct sk_buff* ieee80211_DELBA(
 	memcpy(Delba->addr1, dst, ETH_ALEN);
 	memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN);
 	memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN);
-	Delba->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
+	Delba->frame_control = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
 
 	tag = (u8*)skb_put(skb, 6);
 
@@ -339,7 +339,10 @@ int ieee80211_rx_ADDBAReq( struct ieee80
 
 	if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
 	{
-		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %ld)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 9));
+		IEEE80211_DEBUG(IEEE80211_DL_ERR,
+				" Invalid skb len in BAREQ(%d / %zd)\n",
+				skb->len,
+				sizeof(struct ieee80211_hdr_3addr) + 9);
 		return -1;
 	}
 
@@ -354,7 +357,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80
 	pBaTimeoutVal = (u16*)(tag + 5);
 	pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
 
-	printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst));
+	printk("====================>rx ADDBAREQ from :%pM\n", dst);
 //some other capability is not ready now.
 	if(	(ieee->current_network.qos_data.active == 0) ||
 		(ieee->pHTInfo->bCurrentHTSupport == false) ||
@@ -440,7 +443,10 @@ int ieee80211_rx_ADDBARsp( struct ieee80
 
 	if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
 	{
-		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %ld)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 9));
+		IEEE80211_DEBUG(IEEE80211_DL_ERR,
+				" Invalid skb len in BARSP(%d / %zd)\n",
+				skb->len,
+				sizeof(struct ieee80211_hdr_3addr) + 9);
 		return -1;
 	}
 	rsp = ( struct ieee80211_hdr_3addr*)skb->data;
@@ -570,7 +576,10 @@ int ieee80211_rx_DELBA(struct ieee80211_
 
 	if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6)
 	{
-		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %ld)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 6));
+		IEEE80211_DEBUG(IEEE80211_DL_ERR,
+				" Invalid skb len in DELBA(%d / %zd)\n",
+				skb->len,
+				sizeof(struct ieee80211_hdr_3addr) + 6);
 		return -1;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,7 +42,7 @@ static u8 DLINK_ATHEROS_1[3] = {0x00, 0x
 static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91};
 static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
 static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
-// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the
+// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the
 // code in other place??
 //static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96};
 /********************************************************************************************************************
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,6 @@
 #include "ieee80211.h"
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include "rtl819x_TS.h"
 
 void TsSetupTimeOut(unsigned long data)
@@ -291,7 +292,7 @@ PTS_COMMON_INFO SearchAdmitTRStream(stru
 		if(search_dir[dir] ==false )
 			continue;
 		list_for_each_entry(pRet, psearch_list, List){
-	//		IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
+	//		IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
 			if (memcmp(pRet->Addr, Addr, 6) == 0)
 				if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
 					if(pRet->TSpec.f.TSInfo.field.ucDirection == dir)
@@ -447,7 +448,7 @@ bool GetTs(
 					ResetRxTsEntry(tmp);
 				}
 
-				IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr));
+				IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr);
 				// Prepare TS Info releated field
 				pTSInfo->field.ucTrafficType = 0;			// Traffic type: WMM is reserved in this field
 				pTSInfo->field.ucTSID = UP;			// TSID
@@ -533,7 +534,7 @@ void RemoveTsEntry(
 void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr)
 {
 	PTS_COMMON_INFO	pTS, pTmpTS;
-	printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr));
+	printk("===========>RemovePeerTS,%pM\n", Addr);
 #if 1
 	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
 	{
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 config RTL8192SU
 	tristate "RealTek RTL8192SU Wireless LAN NIC driver"
 	depends on PCI && WLAN && USB
-	depends on WIRELESS_EXT
+	select WIRELESS_EXT
+	select WEXT_PRIV
 	default N
 	---help---
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/r8192S_firmware.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/r8192S_firmware.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/r8192S_firmware.c	2013-05-03 12:11:33.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/r8192S_firmware.c	2013-05-03 09:51:05.000000000 -0400
@@ -360,78 +360,56 @@ bool FirmwareDownload92S(struct net_devi
 
 	RT_TRACE(COMP_FIRMWARE, " --->FirmwareDownload92S()\n");
 
-	//3//
-	//3 //<1> Open Image file, and map file to contineous memory if open file success.
-	//3  //        or read image file from array. Default load from BIN file
-	//3//
-	priv->firmware_source = FW_SOURCE_IMG_FILE;// We should decided by Reg.
-
-	switch( priv->firmware_source )
+/*(DEBLOBBED)*/
+	if(pFirmware->szFwTmpBufferLen == 0)
 	{
-		case FW_SOURCE_IMG_FILE:
-			if(pFirmware->szFwTmpBufferLen == 0)
-			{
-
-				rc = reject_firmware(&fw_entry, pFwImageFileName[ulInitStep],&priv->udev->dev);//===>1
-				if(rc < 0 ) {
-					RT_TRACE(COMP_ERR, "request firmware fail!\n");
-					goto DownloadFirmware_Fail;
-				}
-
-				if(fw_entry->size > sizeof(pFirmware->szFwTmpBuffer))
-				{
-					RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n");
-					release_firmware(fw_entry);
-					goto DownloadFirmware_Fail;
-				}
+		rc = reject_firmware(&fw_entry, pFwImageFileName[ulInitStep],&priv->udev->dev);
+			if(rc < 0 ) {
+				RT_TRACE(COMP_ERR, "request firmware fail!\n");
+				goto DownloadFirmware_Fail;
+			}
 
-				memcpy(pFirmware->szFwTmpBuffer,fw_entry->data,fw_entry->size);
-				pFirmware->szFwTmpBufferLen = fw_entry->size;
+			if(fw_entry->size > sizeof(pFirmware->szFwTmpBuffer)) {
+				RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n");
 				release_firmware(fw_entry);
+				goto DownloadFirmware_Fail;
+			}
 
-				pucMappedFile = pFirmware->szFwTmpBuffer;
-				file_length = pFirmware->szFwTmpBufferLen;
+			memcpy(pFirmware->szFwTmpBuffer,fw_entry->data,fw_entry->size);
+			pFirmware->szFwTmpBufferLen = fw_entry->size;
+			release_firmware(fw_entry);
 
-				//Retrieve FW header.
-				pFirmware->pFwHeader = (PRT_8192S_FIRMWARE_HDR) pucMappedFile;
-				pFwHdr = pFirmware->pFwHeader;
-				RT_TRACE(COMP_FIRMWARE,"signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", \
-						pFwHdr->Signature, pFwHdr->Version, pFwHdr->DMEMSize, \
-						pFwHdr->IMG_IMEM_SIZE, pFwHdr->IMG_SRAM_SIZE);
-				pFirmware->FirmwareVersion =  byte(pFwHdr->Version ,0);
-				if ((pFwHdr->IMG_IMEM_SIZE==0) || (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM)))
-				{
-					RT_TRACE(COMP_ERR, "%s: memory for data image is less than IMEM required\n",\
-							__FUNCTION__);
-					goto DownloadFirmware_Fail;
-				} else {
-					pucMappedFile+=FwHdrSize;
+			pucMappedFile = pFirmware->szFwTmpBuffer;
+			file_length = pFirmware->szFwTmpBufferLen;
 
-					//Retrieve IMEM image.
-					memcpy(pFirmware->FwIMEM, pucMappedFile, pFwHdr->IMG_IMEM_SIZE);
-					pFirmware->FwIMEMLen = pFwHdr->IMG_IMEM_SIZE;
-				}
+			/* Retrieve FW header. */
+			pFirmware->pFwHeader = (PRT_8192S_FIRMWARE_HDR) pucMappedFile;
+			pFwHdr = pFirmware->pFwHeader;
+			RT_TRACE(COMP_FIRMWARE,"signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", \
+					pFwHdr->Signature, pFwHdr->Version, pFwHdr->DMEMSize, \
+					pFwHdr->IMG_IMEM_SIZE, pFwHdr->IMG_SRAM_SIZE);
+			pFirmware->FirmwareVersion =  byte(pFwHdr->Version ,0);
+			if ((pFwHdr->IMG_IMEM_SIZE==0) || (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM))) {
+				RT_TRACE(COMP_ERR, "%s: memory for data image is less than IMEM required\n",\
+					__FUNCTION__);
+				goto DownloadFirmware_Fail;
+			} else {
+				pucMappedFile+=FwHdrSize;
+				/* Retrieve IMEM image. */
+				memcpy(pFirmware->FwIMEM, pucMappedFile, pFwHdr->IMG_IMEM_SIZE);
+				pFirmware->FwIMEMLen = pFwHdr->IMG_IMEM_SIZE;
+			}
 
-				if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM))
-				{
-					RT_TRACE(COMP_ERR, "%s: memory for data image is less than EMEM required\n",\
-							__FUNCTION__);
+			if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM)) {
+				RT_TRACE(COMP_ERR, "%s: memory for data image is less than EMEM required\n",\
+					__FUNCTION__);
 					goto DownloadFirmware_Fail;
 				} else {
 					pucMappedFile += pFirmware->FwIMEMLen;
-
 					/* Retriecve EMEM image */
 					memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE);//===>6
 					pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE;
 				}
-
-
-			}
-			break;
-
-		/*(DEBLOBBED)*/
-		default:
-			break;
 	}
 
 	FwStatus = FirmwareGetNextStatus(pFirmware->FWStatus);
@@ -499,3 +477,4 @@ bool FirmwareDownload92S(struct net_devi
 	return rtStatus;
 }
 
+/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/r8192S_firmware.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/r8192S_firmware.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/r8192S_firmware.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/r8192S_firmware.h	2010-05-16 17:17:36.000000000 -0400
@@ -59,12 +59,6 @@ typedef enum _desc_packet_type_e{
 	DESC_PACKET_TYPE_NORMAL = 1,
 }desc_packet_type_e;
 
-typedef enum _firmware_source{
-	FW_SOURCE_IMG_FILE = 0,
-	FW_SOURCE_HEADER_FILE = 1,
-}firmware_source_e, *pfirmware_source_e;
-
-
 typedef enum _opt_rst_type{
 	OPT_SYSTEM_RESET = 0,
 	OPT_FIRMWARE_RESET = 1,
@@ -185,7 +179,6 @@ typedef enum _FIRMWARE_8192S_STATUS{
 #define RTL8190_MAX_FIRMWARE_CODE_SIZE  64000   //64k
 
 typedef struct _rt_firmware{
-	firmware_source_e	eFWSource;
 	PRT_8192S_FIRMWARE_HDR	pFwHeader;
 	FIRMWARE_8192S_STATUS	FWStatus;
 	u16             FirmwareVersion;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/r8192S_phy.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/r8192S_phy.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/r8192S_phy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/r8192S_phy.c	2010-05-16 17:17:36.000000000 -0400
@@ -2407,8 +2407,8 @@ void PHY_SetBWModeCallback8192S(struct n
 			break;
 
 		default:
-			RT_TRACE(COMP_DBG, "SetBWModeCallback8190Pci():\
-						unknown Bandwidth: %#X\n",priv->CurrentChannelBW);
+			RT_TRACE(COMP_DBG, "SetBWModeCallback8190Pci(): unknown Bandwidth: %#X\n",
+				 priv->CurrentChannelBW);
 			break;
 	}
 
@@ -3398,8 +3398,8 @@ void SwChnlCallback8192SUsb(struct net_d
 	u32			delay;
 //	bool			ret;
 
-	RT_TRACE(COMP_SCAN, "==>SwChnlCallback8190Pci(), switch to channel\
-				%d\n", priv->chan);
+	RT_TRACE(COMP_SCAN, "==>SwChnlCallback8190Pci(), switch to channel %d\n",
+		 priv->chan);
 
 
 	if(!priv->up)
@@ -3525,8 +3525,8 @@ void SetBWModeCallback8192SUsb(struct ne
 			break;
 
 		default:
-			RT_TRACE(COMP_DBG, "SetChannelBandwidth8190Pci():\
-						unknown Bandwidth: %#X\n",priv->CurrentChannelBW);
+			RT_TRACE(COMP_DBG, "SetChannelBandwidth8190Pci(): unknown Bandwidth: %#X\n",
+				 priv->CurrentChannelBW);
 			break;
 	}
 
@@ -3660,8 +3660,8 @@ void SetBWModeCallback8192SUsbWorkItem(s
 			break;
 
 		default:
-			RT_TRACE(COMP_DBG, "SetBWModeCallback8192SUsbWorkItem():\
-						unknown Bandwidth: %#X\n",priv->CurrentChannelBW);
+			RT_TRACE(COMP_DBG, "SetBWModeCallback8192SUsbWorkItem(): unknown Bandwidth: %#X\n",
+				 priv->CurrentChannelBW);
 			break;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/r8192SU_HWImg.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/r8192SU_HWImg.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/r8192SU_HWImg.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/r8192SU_HWImg.h	2010-05-16 17:17:36.000000000 -0400
@@ -5,8 +5,6 @@
 
 /*Created on  2009/ 3/ 6,  5:29*/
 
-#define ImgArrayLength 68368
-extern u8 Rtl8192SUFwImgArray[ImgArrayLength];
 #define MainArrayLength 1
 extern u8 Rtl8192SUFwMainArray[MainArrayLength];
 #define DataArrayLength 1
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/r8192U_core.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/r8192U_core.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/r8192U_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/r8192U_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
  */
 
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #undef LOOP_TEST
 #undef DUMP_RX
@@ -110,16 +111,19 @@ u32 rt_global_debug_component = \
 #define TOTAL_CAM_ENTRY 32
 #define CAM_CONTENT_COUNT 8
 
-static struct usb_device_id rtl8192_usb_id_tbl[] = {
+static const struct usb_device_id rtl8192_usb_id_tbl[] = {
 	/* Realtek */
+	{USB_DEVICE(0x0bda, 0x8171)},
 	{USB_DEVICE(0x0bda, 0x8192)},
 	{USB_DEVICE(0x0bda, 0x8709)},
 	/* Corega */
 	{USB_DEVICE(0x07aa, 0x0043)},
 	/* Belkin */
 	{USB_DEVICE(0x050d, 0x805E)},
+	{USB_DEVICE(0x050d, 0x815F)}, /* Belkin F5D8053 v6 */
 	/* Sitecom */
 	{USB_DEVICE(0x0df6, 0x0031)},
+	{USB_DEVICE(0x0df6, 0x004b)},	/* WL-349 */
 	/* EnGenius */
 	{USB_DEVICE(0x1740, 0x9201)},
 	/* Dlink */
@@ -2340,25 +2344,24 @@ short rtl8192SU_tx(struct net_device *de
 				    skb->len, rtl8192_tx_isr, skb);
 
 	status = usb_submit_urb(tx_urb, GFP_ATOMIC);
-	if (!status){
-//we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted. Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
+	if (!status) {
+		/*
+		 * we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted.
+		 * Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
+		 */
 		bool bSend0Byte = false;
 		u8 zero = 0;
-		if(udev->speed == USB_SPEED_HIGH)
-		{
+		if(udev->speed == USB_SPEED_HIGH) {
 			if (skb->len > 0 && skb->len % 512 == 0)
 				bSend0Byte = true;
 		}
-		else
-		{
+		else {
 			if (skb->len > 0 && skb->len % 64 == 0)
 				bSend0Byte = true;
 		}
-		if (bSend0Byte)
-		{
-#if 1
+		if (bSend0Byte) {
 			tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
-			if(!tx_urb_zero){
+			if(!tx_urb_zero) {
 				RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
 				return -ENOMEM;
 			}
@@ -2366,16 +2369,23 @@ short rtl8192SU_tx(struct net_device *de
 					usb_sndbulkpipe(udev,idx_pipe), &zero,
 					0, tx_zero_isr, dev);
 			status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
-			if (status){
-			RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
-			return -1;
+			switch (status) {
+				case 0:
+					break;
+				case -ECONNRESET:
+				case -ENOENT:
+				case -ESHUTDOWN:
+					break;
+				default:
+					RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d",
+						atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
+					return -1;
 			}
-#endif
 		}
 		dev->trans_start = jiffies;
 		atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
 		return 0;
-	}else{
+	} else {
 		RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
 				status);
 		return -1;
@@ -2952,7 +2962,7 @@ void rtl8192_SetWirelessMode(struct net_
 			wireless_mode = WIRELESS_MODE_B;
 		}
 	}
-#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
+#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
 	ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
 #endif
 	//LZM 090306 usb crash here, mark it temp
@@ -3359,6 +3369,46 @@ u8 rtl8192SU_BoardTypeToRFtype(struct ne
 	return RFtype;
 }
 
+void update_hal_variables(struct r8192_priv *priv)
+{
+	int rf_path;
+	int i;
+	u8 index;
+
+	for (rf_path = 0; rf_path < 2; rf_path++) {
+		for (i = 0; i < 3; i++)	{
+			RT_TRACE((COMP_INIT), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfCckChnlAreaTxPwr[rf_path][i]);
+			RT_TRACE((COMP_INIT), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
+			RT_TRACE((COMP_INIT), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
+		}
+		/* Assign dedicated channel tx power */
+		for(i = 0; i < 14; i++) {
+			/* channel 1-3 use the same Tx Power Level. */
+			if (i < 3)			/* Channel 1-3 */
+				index = 0;
+			else if (i < 9)			/* Channel 4-9 */
+				index = 1;
+			else				/* Channel 10-14 */
+				index = 2;
+			/* Record A & B CCK /OFDM - 1T/2T Channel area tx power */
+			priv->RfTxPwrLevelCck[rf_path][i] = priv->RfCckChnlAreaTxPwr[rf_path][index];
+			priv->RfTxPwrLevelOfdm1T[rf_path][i]  = priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
+			priv->RfTxPwrLevelOfdm2T[rf_path][i]  = priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
+			if (rf_path == 0) {
+				priv->TxPowerLevelOFDM24G[i] = priv->RfTxPwrLevelOfdm1T[rf_path][i] ;
+				priv->TxPowerLevelCCK[i] = priv->RfTxPwrLevelCck[rf_path][i];
+			}
+		}
+		for(i = 0; i < 14; i++) {
+			RT_TRACE((COMP_INIT),
+			"Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
+				rf_path, i, priv->RfTxPwrLevelCck[rf_path][i],
+				priv->RfTxPwrLevelOfdm1T[rf_path][i] ,
+				priv->RfTxPwrLevelOfdm2T[rf_path][i] );
+		}
+	}
+}
+
 //
 //	Description:
 //		Config HW adapter information into initial value.
@@ -3374,7 +3424,7 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoL
 	struct r8192_priv 	*priv = ieee80211_priv(dev);
 	//u16			i,usValue;
 	//u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
-	u8		rf_path, index;	// For EEPROM/EFUSE After V0.6_1117
+	u8		rf_path;	// For EEPROM/EFUSE After V0.6_1117
 	int	i;
 
 	RT_TRACE(COMP_INIT, "====> ConfigAdapterInfo8192SForAutoLoadFail\n");
@@ -3426,10 +3476,9 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoL
 	write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
 	write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
 
-	RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
-			dev->dev_addr[0], dev->dev_addr[1],
-			dev->dev_addr[2], dev->dev_addr[3],
-			dev->dev_addr[4], dev->dev_addr[5]);
+	RT_TRACE(COMP_INIT,
+		"ReadAdapterInfo8192SEFuse(), Permanent Address = %pM\n",
+		dev->dev_addr);
 
 	priv->EEPROMBoardType = EEPROM_Default_BoardType;
 	priv->rf_type = RF_1T2R; //RF_2T2R
@@ -3455,42 +3504,7 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoL
 		}
 	}
 
-	for (i = 0; i < 3; i++)
-	{
-		//RT_TRACE((COMP_EFUSE), "CCK RF-%d CHan_Area-%d = 0x%x\n",  rf_path, i,
-		//priv->RfCckChnlAreaTxPwr[rf_path][i]);
-		//RT_TRACE((COMP_EFUSE), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n",  rf_path, i,
-		//priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
-		//RT_TRACE((COMP_EFUSE), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n",  rf_path, i,
-		//priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
-	}
-
-	// Assign dedicated channel tx power
-	for(i=0; i<14; i++)	// channel 1~3 use the same Tx Power Level.
-		{
-		if (i < 3)			// Cjanel 1-3
-			index = 0;
-		else if (i < 9)		// Channel 4-9
-			index = 1;
-		else				// Channel 10-14
-			index = 2;
-
-		// Record A & B CCK /OFDM - 1T/2T Channel area tx power
-		priv->RfTxPwrLevelCck[rf_path][i]  =
-		priv->RfCckChnlAreaTxPwr[rf_path][index];
-		priv->RfTxPwrLevelOfdm1T[rf_path][i]  =
-		priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
-		priv->RfTxPwrLevelOfdm2T[rf_path][i]  =
-		priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
-		}
-
-		for(i=0; i<14; i++)
-		{
-		//RT_TRACE((COMP_EFUSE), "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
-		//rf_path, i, priv->RfTxPwrLevelCck[0][i],
-		//priv->RfTxPwrLevelOfdm1T[0][i] ,
-		//priv->RfTxPwrLevelOfdm2T[0][i] );
-		}
+	update_hal_variables(priv);
 
 	//
 	// Update remained HAL variables.
@@ -3767,10 +3781,9 @@ rtl8192SU_ReadAdapterInfo8192SUsb(struct
 	write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
 	write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
 
-	RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
-			dev->dev_addr[0], dev->dev_addr[1],
-			dev->dev_addr[2], dev->dev_addr[3],
-			dev->dev_addr[4], dev->dev_addr[5]);
+	RT_TRACE(COMP_INIT,
+		"ReadAdapterInfo8192SEFuse(), Permanent Address = %pM\n",
+		dev->dev_addr);
 
 	//
 	// Get CustomerID(Boad Type)
@@ -3901,53 +3914,7 @@ rtl8192SU_ReadAdapterInfo8192SUsb(struct
 			}
 
 		}
-//
-		// Update Tx Power HAL variables.
-//
-		for (rf_path = 0; rf_path < 2; rf_path++)
-		{
-			for (i = 0; i < 3; i++)
-			{
-				RT_TRACE((COMP_INIT),  "CCK RF-%d CHan_Area-%d = 0x%x\n",  rf_path, i,
-				priv->RfCckChnlAreaTxPwr[rf_path][i]);
-				RT_TRACE((COMP_INIT), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n",  rf_path, i,
-				priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
-				RT_TRACE((COMP_INIT), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n",  rf_path, i, priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
-			}
-
-			// Assign dedicated channel tx power
-			for(i=0; i<14; i++)	// channel 1~3 use the same Tx Power Level.
-			{
-				if (i < 3)			// Cjanel 1-3
-					index = 0;
-				else if (i < 9)		// Channel 4-9
-					index = 1;
-				else				// Channel 10-14
-					index = 2;
-
-				// Record A & B CCK /OFDM - 1T/2T Channel area tx power
-				priv->RfTxPwrLevelCck[rf_path][i]  =
-				priv->RfCckChnlAreaTxPwr[rf_path][index];
-				priv->RfTxPwrLevelOfdm1T[rf_path][i]  =
-				priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
-				priv->RfTxPwrLevelOfdm2T[rf_path][i]  =
-				priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
-				if (rf_path == 0)
-				{
-					priv->TxPowerLevelOFDM24G[i] = priv->RfTxPwrLevelOfdm1T[rf_path][i] ;
-					priv->TxPowerLevelCCK[i] = priv->RfTxPwrLevelCck[rf_path][i];
-				}
-			}
-
-			for(i=0; i<14; i++)
-			{
-				RT_TRACE((COMP_INIT),
-				"Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
-				rf_path, i, priv->RfTxPwrLevelCck[rf_path][i],
-				priv->RfTxPwrLevelOfdm1T[rf_path][i] ,
-				priv->RfTxPwrLevelOfdm2T[rf_path][i] );
-			}
-		}
+		update_hal_variables(priv);
 	}
 
 	//
@@ -6168,7 +6135,7 @@ void rtl8192_process_phyinfo(struct r819
 	u16 sc ;
 	unsigned int frag,seq;
 	hdr = (struct ieee80211_hdr_3addr *)buffer;
-	sc = le16_to_cpu(hdr->seq_ctl);
+	sc = le16_to_cpu(hdr->seq_ctrl);
 	frag = WLAN_GET_SEQ_FRAG(sc);
 	seq = WLAN_GET_SEQ_SEQ(sc);
 	//cosa add 04292008 to record the sequence number
@@ -6827,7 +6794,7 @@ void rtl8192SU_TranslateRxSignalStuff(st
 	tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
 
 	hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
-	fc = le16_to_cpu(hdr->frame_ctl);
+	fc = le16_to_cpu(hdr->frame_control);
 	type = WLAN_FC_GET_TYPE(fc);
 	praddr = hdr->addr1;
 
@@ -7677,7 +7644,7 @@ void setKey(	struct net_device *dev,
 	if (EntryNo >= TOTAL_CAM_ENTRY)
 		RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
 
-	RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr));
+	RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
 
 	if (DefaultKey)
 		usConfig |= BIT15 | (KeyType<<2);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/r8192U_dm.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/r8192U_dm.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/r8192U_dm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/r8192U_dm.c	2010-05-16 17:17:36.000000000 -0400
@@ -2697,7 +2697,7 @@ static void dm_check_edca_turbo(
 		u8* peername[11] = {"unknown", "realtek", "realtek_92se", "broadcom", "ralink", "atheros", "cisco", "marvell", "92u_softap", "self_softap"};
 		static int wb_tmp = 0;
 		if (wb_tmp == 0){
-			printk("%s():iot peer is %#x:%s, bssid:"MAC_FMT"\n",__FUNCTION__,pHTInfo->IOTPeer,peername[pHTInfo->IOTPeer], MAC_ARG(priv->ieee80211->current_network.bssid));
+			printk("%s():iot peer is %#x:%s, bssid:%pM\n",__FUNCTION__,pHTInfo->IOTPeer,peername[pHTInfo->IOTPeer], priv->ieee80211->current_network.bssid);
 			wb_tmp = 1;
 		}
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/r8192U.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/r8192U.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/r8192U.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/r8192U.h	2010-05-16 17:17:36.000000000 -0400
@@ -1258,7 +1258,6 @@ typedef struct r8192_priv
 	u8 Rf_Mode; //add for Firmware RF -R/W switch
 	prt_firmware		pFirmware;
 	rtl819xUsb_loopback_e	LoopbackMode;
-	firmware_source_e	firmware_source;
 	bool usb_error;
 
 	u16 EEPROMTxPowerDiff;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/TODO linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/TODO
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192su/TODO	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192su/TODO	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,6 @@ TODO:
   - cleanup ieee80211.h
   - move rtl8192su's specific code out from ieee80211.h
   - abstract rtl819su's specific code
-  - use list_for_each_safe() in ieee80211_crypto_deinit
 - switch to use shared "librtl" instead of private ieee80211 stack
 - switch to use LIB80211
 - switch to use MAC80211
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c	2010-05-16 17:17:36.000000000 -0400
@@ -288,7 +288,7 @@ static int ieee80211_ccmp_decrypt(struct
 	if (!(keyidx & (1 << 5))) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "CCMP: received packet without ExtIV"
-			       " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+			       " flag from %pM\n", hdr->addr2);
 		}
 		key->dot11RSNAStatsCCMPFormatErrors++;
 		return -2;
@@ -301,9 +301,9 @@ static int ieee80211_ccmp_decrypt(struct
 	}
 	if (!key->key_set) {
 		if (net_ratelimit()) {
-			printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
+			printk(KERN_DEBUG "CCMP: received packet from %pM"
 			       " with keyid=%d that does not have a configured"
-			       " key\n", MAC_ARG(hdr->addr2), keyidx);
+			       " key\n", hdr->addr2, keyidx);
 		}
 		return -3;
 	}
@@ -318,11 +318,9 @@ static int ieee80211_ccmp_decrypt(struct
 
 	if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
 		if (net_ratelimit()) {
-			printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
-			       " previous PN %02x%02x%02x%02x%02x%02x "
-			       "received PN %02x%02x%02x%02x%02x%02x\n",
-			       MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
-			       MAC_ARG(pn));
+			printk(KERN_DEBUG "CCMP: replay detected: STA=%pM"
+			       " previous PN %pm received PN %pm\n",
+			       hdr->addr2, key->rx_pn, pn);
 		}
 		key->dot11RSNAStatsCCMPReplays++;
 		return -4;
@@ -359,7 +357,7 @@ static int ieee80211_ccmp_decrypt(struct
 		if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
 			if (net_ratelimit()) {
 				printk(KERN_DEBUG "CCMP: decrypt failed: STA="
-				MAC_FMT "\n", MAC_ARG(hdr->addr2));
+				"%pM\n", hdr->addr2);
 			}
 			key->dot11RSNAStatsCCMPDecryptErrors++;
 			return -5;
@@ -435,11 +433,10 @@ static char * ieee80211_ccmp_print_stats
 {
 	struct ieee80211_ccmp_data *ccmp = priv;
 	p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
-		     "tx_pn=%02x%02x%02x%02x%02x%02x "
-		     "rx_pn=%02x%02x%02x%02x%02x%02x "
+		     "tx_pn=%pm rx_pn=%pm "
 		     "format_errors=%d replays=%d decrypt_errors=%d\n",
 		     ccmp->key_idx, ccmp->key_set,
-		     MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
+		     ccmp->tx_pn, ccmp->rx_pn,
 		     ccmp->dot11RSNAStatsCCMPFormatErrors,
 		     ccmp->dot11RSNAStatsCCMPReplays,
 		     ccmp->dot11RSNAStatsCCMPDecryptErrors);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c	2010-05-16 17:17:36.000000000 -0400
@@ -410,7 +410,7 @@ static int ieee80211_tkip_decrypt(struct
 	if (!(keyidx & (1 << 5))) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "TKIP: received packet without ExtIV"
-			       " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+			       " flag from %pM\n", hdr->addr2);
 		}
 		return -2;
 	}
@@ -422,9 +422,9 @@ static int ieee80211_tkip_decrypt(struct
 	}
 	if (!tkey->key_set) {
 		if (net_ratelimit()) {
-			printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
+			printk(KERN_DEBUG "TKIP: received packet from %pM"
 			       " with keyid=%d that does not have a configured"
-			       " key\n", MAC_ARG(hdr->addr2), keyidx);
+			       " key\n", hdr->addr2, keyidx);
 		}
 		return -3;
 	}
@@ -437,9 +437,9 @@ static int ieee80211_tkip_decrypt(struct
 		if (iv32 < tkey->rx_iv32 ||
 		(iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
 			if (net_ratelimit()) {
-				printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
+				printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
 				" previous TSC %08x%04x received TSC "
-				"%08x%04x\n", MAC_ARG(hdr->addr2),
+				"%08x%04x\n", hdr->addr2,
 				tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
 			}
 			tkey->dot11RSNAStatsTKIPReplays++;
@@ -460,8 +460,8 @@ static int ieee80211_tkip_decrypt(struct
 		if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
 			if (net_ratelimit()) {
 				printk(KERN_DEBUG ": TKIP: failed to decrypt "
-						"received packet from " MAC_FMT "\n",
-						MAC_ARG(hdr->addr2));
+						"received packet from %pM\n",
+						hdr->addr2);
 			}
 			return -7;
 		}
@@ -480,7 +480,7 @@ static int ieee80211_tkip_decrypt(struct
 			}
 			if (net_ratelimit()) {
 				printk(KERN_DEBUG "TKIP: ICV error detected: STA="
-				MAC_FMT "\n", MAC_ARG(hdr->addr2));
+				"%pM\n", hdr->addr2);
 			}
 			tkey->dot11RSNAStatsTKIPICVErrors++;
 			return -5;
@@ -635,8 +635,8 @@ static int ieee80211_michael_mic_verify(
 		struct ieee80211_hdr_4addr *hdr;
 		hdr = (struct ieee80211_hdr_4addr *) skb->data;
 		printk(KERN_DEBUG "%s: Michael MIC verification failed for "
-		       "MSDU from " MAC_FMT " keyidx=%d\n",
-		       skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
+		       "MSDU from %pM keyidx=%d\n",
+		       skb->dev ? skb->dev->name : "N/A", hdr->addr2,
 		       keyidx);
 		if (skb->dev)
 			ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/jiffies.h>
 #include <linux/timer.h>
 #include <linux/sched.h>
+#include <linux/semaphore.h>
 
 #include <linux/delay.h>
 #include <linux/wireless.h>
@@ -551,9 +552,6 @@ do { if (ieee80211_debug_level & (level)
 
 /* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
 
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
-
 /*
  * To use the debug system;
  *
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c	2010-05-16 17:17:36.000000000 -0400
@@ -260,7 +260,7 @@ static int store_debug_level(struct file
 			     unsigned long count, void *data)
 {
 	char buf[] = "0x00000000";
-	unsigned long len = min(sizeof(buf) - 1, count);
+	unsigned long len = min_t(unsigned long, sizeof(buf) - 1, count);
 	char *p = (char *)buf;
 	unsigned long val;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -360,8 +360,8 @@ ieee80211_rx_frame_decrypt(struct ieee80
 	    strcmp(crypt->ops->name, "TKIP") == 0) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-			       "received packet from " MAC_FMT "\n",
-			       ieee->dev->name, MAC_ARG(hdr->addr2));
+			       "received packet from %pM\n",
+			       ieee->dev->name, hdr->addr2);
 		}
 		return -1;
 	}
@@ -372,8 +372,8 @@ ieee80211_rx_frame_decrypt(struct ieee80
 	atomic_dec(&crypt->refcnt);
 	if (res < 0) {
 		IEEE80211_DEBUG_DROP(
-			"decryption failed (SA=" MAC_FMT
-			") res=%d\n", MAC_ARG(hdr->addr2), res);
+			"decryption failed (SA=%pM"
+			") res=%d\n", hdr->addr2, res);
 		if (res == -2)
 			IEEE80211_DEBUG_DROP("Decryption failed ICV "
 					     "mismatch (key %d)\n",
@@ -410,8 +410,8 @@ ieee80211_rx_frame_decrypt_msdu(struct i
 	atomic_dec(&crypt->refcnt);
 	if (res < 0) {
 		printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
-		       " (SA=" MAC_FMT " keyidx=%d)\n",
-		       ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
+		       " (SA=%pM keyidx=%d)\n",
+		       ieee->dev->name, hdr->addr2, keyidx);
 		return -1;
 	}
 
@@ -1016,8 +1016,8 @@ int ieee80211_rx(struct ieee80211_device
 			 * frames silently instead of filling system log with
 			 * these reports. */
 			IEEE80211_DEBUG_DROP("Decryption failed (not set)"
-					     " (SA=" MAC_FMT ")\n",
-					     MAC_ARG(hdr->addr2));
+					     " (SA=%pM)\n",
+					     hdr->addr2);
 			ieee->ieee_stats.rx_discards_undecryptable++;
 			goto rx_dropped;
 		}
@@ -1256,8 +1256,8 @@ int ieee80211_rx(struct ieee80211_device
 		} else {
 			IEEE80211_DEBUG_DROP(
 				"encryption configured, but RX "
-				"frame not encrypted (SA=" MAC_FMT ")\n",
-				MAC_ARG(hdr->addr2));
+				"frame not encrypted (SA=%pM)\n",
+				hdr->addr2);
 			goto rx_dropped;
 		}
 	}
@@ -1276,9 +1276,9 @@ int ieee80211_rx(struct ieee80211_device
 	    !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
 		IEEE80211_DEBUG_DROP(
 			"dropped unencrypted RX data "
-			"frame from " MAC_FMT
+			"frame from %pM"
 			" (drop_unencrypted=1)\n",
-			MAC_ARG(hdr->addr2));
+			hdr->addr2);
 		goto rx_dropped;
 	}
 /*
@@ -2260,11 +2260,11 @@ static inline int ieee80211_network_init
 	}
 
 	if (network->mode == 0) {
-		IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
+		IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
 				     "network.\n",
 				     escape_essid(network->ssid,
 						  network->ssid_len),
-				     MAC_ARG(network->bssid));
+				     network->bssid);
 		return 1;
 	}
 
@@ -2439,9 +2439,9 @@ static inline void ieee80211_process_pro
 
 	memset(&network, 0, sizeof(struct ieee80211_network));
 	IEEE80211_DEBUG_SCAN(
-		"'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
+		"'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
 		escape_essid(info_element->data, info_element->len),
-		MAC_ARG(beacon->header.addr3),
+		beacon->header.addr3,
 		(beacon->capability & (1<<0xf)) ? '1' : '0',
 		(beacon->capability & (1<<0xe)) ? '1' : '0',
 		(beacon->capability & (1<<0xd)) ? '1' : '0',
@@ -2460,10 +2460,10 @@ static inline void ieee80211_process_pro
 		(beacon->capability & (1<<0x0)) ? '1' : '0');
 
 	if (ieee80211_network_init(ieee, beacon, &network, stats)) {
-		IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
+		IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
 				     escape_essid(info_element->data,
 						  info_element->len),
-				     MAC_ARG(beacon->header.addr3),
+				     beacon->header.addr3,
 				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
 				     IEEE80211_STYPE_PROBE_RESP ?
 				     "PROBE RESPONSE" : "BEACON");
@@ -2574,11 +2574,11 @@ static inline void ieee80211_process_pro
 			/* If there are no more slots, expire the oldest */
 			list_del(&oldest->list);
 			target = oldest;
-			IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
+			IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
 					     "network list.\n",
 					     escape_essid(target->ssid,
 							  target->ssid_len),
-					     MAC_ARG(target->bssid));
+					     target->bssid);
 		} else {
 			/* Otherwise just pull from the free list */
 			target = list_entry(ieee->network_free_list.next,
@@ -2588,10 +2588,10 @@ static inline void ieee80211_process_pro
 
 
 #ifdef CONFIG_IEEE80211_DEBUG
-		IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
+		IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
 				     escape_essid(network.ssid,
 						  network.ssid_len),
-				     MAC_ARG(network.bssid),
+				     network.bssid,
 				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
 				     IEEE80211_STYPE_PROBE_RESP ?
 				     "PROBE RESPONSE" : "BEACON");
@@ -2601,10 +2601,10 @@ static inline void ieee80211_process_pro
 		if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
 			ieee80211_softmac_new_net(ieee,&network);
 	} else {
-		IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
+		IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
 				     escape_essid(target->ssid,
 						  target->ssid_len),
-				     MAC_ARG(target->bssid),
+				     target->bssid,
 				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
 				     IEEE80211_STYPE_PROBE_RESP ?
 				     "PROBE RESPONSE" : "BEACON");
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 
 #include <linux/random.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include <asm/uaccess.h>
 #ifdef ENABLE_DOT11D
@@ -1731,7 +1732,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_d
 		ieee80211_resp_to_assoc_rq(ieee, dest);
 	}
 
-	printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
+	printk(KERN_INFO"New client associated: %pM\n", dest);
 	//FIXME
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -200,8 +200,8 @@ int ieee80211_encrypt_fragment(
 		header = (struct ieee80211_hdr *) frag->data;
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-			       "TX packet to " MAC_FMT "\n",
-			       ieee->dev->name, MAC_ARG(header->addr1));
+			       "TX packet to %pM\n",
+			       ieee->dev->name, header->addr1);
 		}
 		return -1;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/wireless.h>
 #include <linux/version.h>
 #include <linux/kmod.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 
 #include "ieee80211.h"
@@ -289,10 +290,10 @@ int ieee80211_wx_get_scan(struct ieee802
 		else
 			IEEE80211_DEBUG_SCAN(
 				"Not showing network '%s ("
-				MAC_FMT ")' due to age (%lums).\n",
+				"%pM)' due to age (%lums).\n",
 				escape_essid(network->ssid,
 					     network->ssid_len),
-				MAC_ARG(network->bssid),
+				network->bssid,
 				(jiffies - network->last_scanned) / (HZ / 100));
 	}
 
@@ -718,7 +719,7 @@ int ieee80211_wx_get_encode_ext(struct i
 	} else
 		idx = ieee->tx_keyidx;
 
-	if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY &&
+	if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
 	    ext->alg != IW_ENCODE_ALG_WEP)
 		if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
 			return -EINVAL;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c	2010-05-16 17:17:36.000000000 -0400
@@ -113,7 +113,7 @@ static struct sk_buff* ieee80211_ADDBA(s
 	u16 tmp = 0;
 	u16 len = ieee->tx_headroom + 9;
 	//category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) +  BA Timeout Value(2) +  BA Start SeqCtrl(2)(or StatusCode(2))
-	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev);
+	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev);
 	if (pBA == NULL||ieee == NULL)
 	{
 		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
@@ -201,7 +201,7 @@ static struct sk_buff* ieee80211_DELBA(
 	u16 len = 6 + ieee->tx_headroom;
 
 	if (net_ratelimit())
-	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst));
+	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst);
 
 	memset(&DelbaParamSet, 0, 2);
 
@@ -355,7 +355,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80
 	pBaTimeoutVal = (u16*)(tag + 5);
 	pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
 
-	printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst));
+	printk("====================>rx ADDBAREQ from :%pM\n", dst);
 //some other capability is not ready now.
 	if(	(ieee->current_network.qos_data.active == 0) ||
 		(ieee->pHTInfo->bCurrentHTSupport == false)) //||
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,7 @@ static u8 AIRLINK_RALINK[3] = {0x00, 0x1
 //static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0};
 static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
 
-// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the
+// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the
 // code in other place??
 //static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96};
 /********************************************************************************************************************
@@ -1342,7 +1342,7 @@ void HTUseDefaultSetting(struct ieee8021
 
 		pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
 
-		pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity;
+		pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
 
 		// Set BWOpMode register
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,6 @@
 #include "ieee80211.h"
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include "rtl819x_TS.h"
 
 void TsSetupTimeOut(unsigned long data)
@@ -290,7 +291,7 @@ PTS_COMMON_INFO SearchAdmitTRStream(stru
 		if(search_dir[dir] ==false )
 			continue;
 		list_for_each_entry(pRet, psearch_list, List){
-	//		IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
+	//		IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
 			if (memcmp(pRet->Addr, Addr, 6) == 0)
 				if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
 					if(pRet->TSpec.f.TSInfo.field.ucDirection == dir)
@@ -445,7 +446,7 @@ bool GetTs(
 					ResetRxTsEntry(tmp);
 				}
 
-				IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr));
+				IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr);
 				// Prepare TS Info releated field
 				pTSInfo->field.ucTrafficType = 0;			// Traffic type: WMM is reserved in this field
 				pTSInfo->field.ucTSID = UP;			// TSID
@@ -531,7 +532,7 @@ void RemoveTsEntry(
 void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr)
 {
 	PTS_COMMON_INFO	pTS, pTmpTS;
-	printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr));
+	printk("===========>RemovePeerTS,%pM\n", Addr);
 	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
 	{
 		if (memcmp(pTS->Addr, Addr, 6) == 0)
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211.h linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211.h
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/ieee80211.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/ieee80211.h	2010-05-16 17:17:36.000000000 -0400
@@ -551,9 +551,6 @@ do { if (ieee80211_debug_level & (level)
 
 /* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
 
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
-
 /*
  * To use the debug system;
  *
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 config RTL8192U
 	tristate "RealTek RTL8192U Wireless LAN NIC driver"
 	depends on PCI && WLAN && USB
-	depends on WIRELESS_EXT
+	select WIRELESS_EXT
+	select WEXT_PRIV
 	default N
 	---help---
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/Makefile linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -3,7 +3,7 @@ NIC_SELECT = RTL8192U
 EXTRA_CFLAGS += -std=gnu89
 EXTRA_CFLAGS += -O2
 
-EXTRA_CFLAGS += -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y
+EXTRA_CFLAGS += -DCONFIG_FORCE_HARD_FLOAT=y
 EXTRA_CFLAGS += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX
 EXTRA_CFLAGS += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO
 #EXTRA_CFLAGS += -DUSB_TX_DRIVER_AGGREGATION_ENABLE
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/r8192U_core.c linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/r8192U_core.c
--- linux-libre-2.6.33-gnu1/drivers/staging/rtl8192u/r8192U_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/rtl8192u/r8192U_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -70,6 +70,7 @@ double __extendsfdf2(float a) {return a;
 #include "r8192U_dm.h"
 //#include "r8192xU_phyreg.h"
 #include <linux/usb.h>
+#include <linux/slab.h>
 // FIXME: check if 2.6.7 is ok
 
 #ifdef CONFIG_RTL8192_PM
@@ -104,7 +105,7 @@ u32 rt_global_debug_component = \
 #define TOTAL_CAM_ENTRY 32
 #define CAM_CONTENT_COUNT 8
 
-static struct usb_device_id rtl8192_usb_id_tbl[] = {
+static const struct usb_device_id rtl8192_usb_id_tbl[] = {
 	/* Realtek */
 	{USB_DEVICE(0x0bda, 0x8192)},
 	{USB_DEVICE(0x0bda, 0x8709)},
@@ -2719,7 +2720,7 @@ void rtl8192_SetWirelessMode(struct net_
 			wireless_mode = WIRELESS_MODE_B;
 		}
 	}
-#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
+#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
 	ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
 #endif
 	priv->ieee80211->mode = wireless_mode;
@@ -2976,7 +2977,7 @@ static void rtl8192_read_eeprom_info(str
 		memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
 		//should I set IDR0 here?
 	}
-	RT_TRACE(COMP_EPROM, "MAC addr:"MAC_FMT"\n", MAC_ARG(dev->dev_addr));
+	RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr);
 	priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
 	priv->rf_chip = RF_8256;
 
@@ -6037,7 +6038,7 @@ void setKey(	struct net_device *dev,
 	if (EntryNo >= TOTAL_CAM_ENTRY)
 		RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
 
-	RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr));
+	RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
 
 	if (DefaultKey)
 		usConfig |= BIT15 | (KeyType<<2);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/samsung-laptop/samsung-laptop.c linux-libre-2.6.34-gnu1/drivers/staging/samsung-laptop/samsung-laptop.c
--- linux-libre-2.6.33-gnu1/drivers/staging/samsung-laptop/samsung-laptop.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/samsung-laptop/samsung-laptop.c	2010-05-16 17:17:36.000000000 -0400
@@ -99,7 +99,8 @@ static struct rfkill *rfk;
 
 static int force;
 module_param(force, bool, 0);
-MODULE_PARM_DESC(force, "Disable the DMI check and forces the driver to be loaded");
+MODULE_PARM_DESC(force,
+		"Disable the DMI check and forces the driver to be loaded");
 
 static int debug;
 module_param(debug, bool, S_IRUGO | S_IWUSR);
@@ -370,7 +371,8 @@ static struct dmi_system_id __initdata s
 	{
 		.ident = "N128",
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+			DMI_MATCH(DMI_SYS_VENDOR,
+					"SAMSUNG ELECTRONICS CO., LTD."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "N128"),
 			DMI_MATCH(DMI_BOARD_NAME, "N128"),
 		},
@@ -379,7 +381,8 @@ static struct dmi_system_id __initdata s
 	{
 		.ident = "N130",
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+			DMI_MATCH(DMI_SYS_VENDOR,
+					"SAMSUNG ELECTRONICS CO., LTD."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "N130"),
 			DMI_MATCH(DMI_BOARD_NAME, "N130"),
 		},
@@ -391,6 +394,7 @@ MODULE_DEVICE_TABLE(dmi, samsung_dmi_tab
 
 static int __init samsung_init(void)
 {
+	struct backlight_properties props;
 	struct sabi_retval sretval;
 	const char *testStr = "SECLINUX";
 	void __iomem *memcheck;
@@ -483,12 +487,14 @@ static int __init samsung_init(void)
 		goto error_no_platform;
 
 	/* create a backlight device to talk to this one */
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = MAX_BRIGHT;
 	backlight_device = backlight_device_register("samsung", &sdev->dev,
-						     NULL, &backlight_ops);
+						     NULL, &backlight_ops,
+						     &props);
 	if (IS_ERR(backlight_device))
 		goto error_no_backlight;
 
-	backlight_device->props.max_brightness = MAX_BRIGHT;
 	backlight_device->props.brightness = read_brightness();
 	backlight_device->props.power = FB_BLANK_UNBLANK;
 	backlight_update_status(backlight_device);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/sep/sep_driver.c linux-libre-2.6.34-gnu1/drivers/staging/sep/sep_driver.c
--- linux-libre-2.6.33-gnu1/drivers/staging/sep/sep_driver.c	2013-05-03 12:14:59.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/sep/sep_driver.c	2013-05-03 09:54:36.000000000 -0400
@@ -35,12 +35,14 @@
 #include <linux/cdev.h>
 #include <linux/kdev_t.h>
 #include <linux/mutex.h>
+#include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/poll.h>
 #include <linux/wait.h>
 #include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <asm/ioctl.h>
 #include <linux/ioport.h>
 #include <asm/io.h>
@@ -222,6 +224,8 @@ static int sep_load_firmware(struct sep_
 	return 0;
 }
 
+/*(DEBLOBBED)*/
+
 /**
  *	sep_map_and_alloc_shared_area	-	allocate shared block
  *	@sep: security processor
@@ -273,8 +277,8 @@ static dma_addr_t sep_shared_virt_to_bus
 						void *virt_address)
 {
 	dma_addr_t pa = sep->shared_bus + (virt_address - sep->shared_addr);
-	edbg("sep: virt to bus b %08llx v %p\n",
-		(unsigned long long)pa, virt_address);
+	edbg("sep: virt to bus b %08llx v %p\n", (unsigned long long) pa,
+								virt_address);
 	return pa;
 }
 
@@ -380,8 +384,7 @@ static int sep_mmap(struct file *filp, s
 	   shared area */
 	if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) {
 		edbg("SEP Driver mmap requested size is more than allowed\n");
-		printk(KERN_WARNING "SEP Driver mmap requested size is more \
-			than allowed\n");
+		printk(KERN_WARNING "SEP Driver mmap requested size is more than allowed\n");
 		printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_end);
 		printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_start);
 		return -EAGAIN;
@@ -941,8 +944,9 @@ static int sep_lock_user_pages(struct se
 			dbg("data_size is %lu\n", data_size);
 			while (1);
 		}
-		edbg("lli_array[%lu].physical_address is %08lx, \
-		lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
+		edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n",
+		     count, lli_array[count].physical_address,
+		     count, lli_array[count].block_size);
 	}
 
 	/* set output params */
@@ -1771,7 +1775,7 @@ static struct sep_flow_context_t *sep_fi
 static int sep_create_flow_dma_tables_handler(struct sep_device *sep,
 							unsigned long arg)
 {
-	int error;
+	int error = -ENOENT;
 	struct sep_driver_build_flow_table_t command_args;
 	/* first table - output */
 	struct sep_lli_entry_t first_table_data;
@@ -2232,7 +2236,7 @@ static int sep_set_flow_id_handler(struc
 	return error;
 }
 
-static int sep_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
 	int error = 0;
 	struct sep_device *sep = filp->private_data;
@@ -2586,7 +2590,7 @@ end_function:
 	return error;
 }
 
-static struct pci_device_id sep_pci_id_tbl[] = {
+static const struct pci_device_id sep_pci_id_tbl[] = {
 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)},
 	{0}
 };
@@ -2607,7 +2611,7 @@ static dev_t sep_devno;
 /* the files operations structure of the driver */
 static struct file_operations sep_file_operations = {
 	.owner = THIS_MODULE,
-	.ioctl = sep_ioctl,
+	.unlocked_ioctl = sep_ioctl,
 	.poll = sep_poll,
 	.open = sep_open,
 	.release = sep_release,
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/serqt_usb2/serqt_usb2.c linux-libre-2.6.34-gnu1/drivers/staging/serqt_usb2/serqt_usb2.c
--- linux-libre-2.6.33-gnu1/drivers/staging/serqt_usb2/serqt_usb2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/serqt_usb2/serqt_usb2.c	2010-05-16 17:17:36.000000000 -0400
@@ -126,7 +126,7 @@ static int debug;
 #define MODEM_CTRL          0x40
 #define RS232_MODE          0x00
 
-static struct usb_device_id serqt_id_table[] = {
+static const struct usb_device_id serqt_id_table[] = {
 	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU100)},
 	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU200)},
 	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU100)},
@@ -1277,7 +1277,7 @@ static void qt_set_termios(struct tty_st
 	if (cflag & CSTOPB)
 		new_LCR |= SERIAL_TWO_STOPB;
 	else
-		new_LCR |= SERIAL_TWO_STOPB;
+		new_LCR |= SERIAL_ONE_STOPB;
 
 	dbg("%s - 4\n", __func__);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/slicoss/slic.h linux-libre-2.6.34-gnu1/drivers/staging/slicoss/slic.h
--- linux-libre-2.6.33-gnu1/drivers/staging/slicoss/slic.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/slicoss/slic.h	2010-05-16 17:17:36.000000000 -0400
@@ -527,15 +527,6 @@ struct adapter {
     (largestat) += ((newstat) - (oldstat));                              \
 }
 
-#define ETHER_EQ_ADDR(_AddrA, _AddrB, _Result)                           \
-{                                                                        \
-    _Result = true;                                                      \
-    if (*(u32 *)(_AddrA) != *(u32 *)(_AddrB))                          \
-	_Result = false;                                                 \
-    if (*(u16 *)(&((_AddrA)[4])) != *(u16 *)(&((_AddrB)[4])))        \
-	_Result = false;                                                 \
-}
-
 #if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
 #define   SLIC_GET_ADDR_LOW(_addr)  (u32)((u64)(_addr) & \
 	0x00000000FFFFFFFF)
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/slicoss/slicoss.c linux-libre-2.6.34-gnu1/drivers/staging/slicoss/slicoss.c
--- linux-libre-2.6.33-gnu1/drivers/staging/slicoss/slicoss.c	2013-05-03 12:08:27.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/slicoss/slicoss.c	2013-05-03 09:47:58.000000000 -0400
@@ -101,7 +101,7 @@ static struct net_device_stats *slic_get
 static int slic_entry_open(struct net_device *dev);
 static int slic_entry_halt(struct net_device *dev);
 static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev);
 static void slic_xmit_fail(struct adapter *adapter, struct sk_buff *skb,
 			   void *cmd, u32 skbtype, u32 status);
 static void slic_config_pci(struct pci_dev *pcidev);
@@ -194,14 +194,10 @@ MODULE_PARM_DESC(dynamic_intagg, "Dynami
 module_param(intagg_delay, int, 0);
 MODULE_PARM_DESC(intagg_delay, "uSec Interrupt Aggregation Delay");
 
-static struct pci_device_id slic_pci_tbl[] __devinitdata = {
-	{PCI_VENDOR_ID_ALACRITECH,
-	 SLIC_1GB_DEVICE_ID,
-	 PCI_ANY_ID, PCI_ANY_ID,},
-	{PCI_VENDOR_ID_ALACRITECH,
-	 SLIC_2GB_DEVICE_ID,
-	 PCI_ANY_ID, PCI_ANY_ID,},
-	{0,}
+static DEFINE_PCI_DEVICE_TABLE(slic_pci_tbl) = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_ALACRITECH, SLIC_1GB_DEVICE_ID) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_ALACRITECH, SLIC_2GB_DEVICE_ID) },
+	{ 0 }
 };
 
 MODULE_DEVICE_TABLE(pci, slic_pci_tbl);
@@ -292,7 +288,7 @@ static void slic_init_adapter(struct net
 {
 	ushort index;
 	struct slic_handle *pslic_handle;
-	struct adapter *adapter = (struct adapter *)netdev_priv(netdev);
+	struct adapter *adapter = netdev_priv(netdev);
 
 /*	adapter->pcidev = pcidev;*/
 	adapter->vendid = pci_tbl_entry->vendor;
@@ -370,6 +366,7 @@ static int __devinit slic_entry_probe(st
 	ulong mmio_start = 0;
 	ulong mmio_len = 0;
 	struct sliccard *card = NULL;
+	int pci_using_dac = 0;
 
 	slic_global.dynamic_intagg = dynamic_intagg;
 
@@ -383,16 +380,26 @@ static int __devinit slic_entry_probe(st
 		printk(KERN_DEBUG "%s\n", slic_proc_version);
 	}
 
-	err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64));
-	if (err) {
-		err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32));
-		if (err)
+	if (!pci_set_dma_mask(pcidev, DMA_BIT_MASK(64))) {
+		pci_using_dac = 1;
+		if (pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64))) {
+			dev_err(&pcidev->dev, "unable to obtain 64-bit DMA for "
+					"consistent allocations\n");
 			goto err_out_disable_pci;
+		}
+	} else if (pci_set_dma_mask(pcidev, DMA_BIT_MASK(32))) {
+		pci_using_dac = 0;
+		pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32));
+	} else {
+		dev_err(&pcidev->dev, "no usable DMA configuration\n");
+		goto err_out_disable_pci;
 	}
 
 	err = pci_request_regions(pcidev, DRV_NAME);
-	if (err)
+	if (err) {
+		dev_err(&pcidev->dev, "can't obtain PCI resources\n");
 		goto err_out_disable_pci;
+	}
 
 	pci_set_master(pcidev);
 
@@ -408,6 +415,8 @@ static int __devinit slic_entry_probe(st
 	adapter = netdev_priv(netdev);
 	adapter->netdev = netdev;
 	adapter->pcidev = pcidev;
+	if (pci_using_dac)
+		netdev->features |= NETIF_F_HIGHDMA;
 
 	mmio_start = pci_resource_start(pcidev, 0);
 	mmio_len = pci_resource_len(pcidev, 0);
@@ -484,7 +493,7 @@ err_out_disable_pci:
 
 static int slic_entry_open(struct net_device *dev)
 {
-	struct adapter *adapter = (struct adapter *) netdev_priv(dev);
+	struct adapter *adapter = netdev_priv(dev);
 	struct sliccard *card = adapter->card;
 	u32 locked = 0;
 	int status;
@@ -534,7 +543,7 @@ static void __devexit slic_entry_remove(
 	struct net_device *dev = pci_get_drvdata(pcidev);
 	u32 mmio_start = 0;
 	uint mmio_len = 0;
-	struct adapter *adapter = (struct adapter *) netdev_priv(dev);
+	struct adapter *adapter = netdev_priv(dev);
 	struct sliccard *card;
 	struct mcast_address *mcaddr, *mlist;
 
@@ -581,7 +590,7 @@ static void __devexit slic_entry_remove(
 
 static int slic_entry_halt(struct net_device *dev)
 {
-	struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+	struct adapter *adapter = netdev_priv(dev);
 	struct sliccard *card = adapter->card;
 	__iomem struct slic_regs *slic_regs = adapter->slic_regs;
 
@@ -624,7 +633,7 @@ static int slic_entry_halt(struct net_de
 
 static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-	struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+	struct adapter *adapter = netdev_priv(dev);
 	struct ethtool_cmd edata;
 	struct ethtool_cmd ecmd;
 	u32 data[7];
@@ -649,8 +658,7 @@ static int slic_ioctl(struct net_device
 
 			if (copy_from_user(data, rq->ifr_data, 28)) {
 				PRINT_ERROR
-				    ("slic: copy_from_user FAILED getting \
-				     initial simba param\n");
+				    ("slic: copy_from_user FAILED getting initial simba param\n");
 				return -EFAULT;
 			}
 
@@ -665,8 +673,7 @@ static int slic_ioctl(struct net_device
 				   (tracemon_request ==
 				    SLIC_DUMP_IN_PROGRESS)) {
 				PRINT_ERROR
-				    ("ATK Diagnostic Trace Dump Requested but \
-				     already in progress... ignore\n");
+				    ("ATK Diagnostic Trace Dump Requested but already in progress... ignore\n");
 			} else {
 				PRINT_ERROR
 				    ("ATK Diagnostic Trace Dump Requested\n");
@@ -784,10 +791,10 @@ static void slic_xmit_build_request(stru
 
 #define NORMAL_ETHFRAME     0
 
-static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
 {
 	struct sliccard *card;
-	struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+	struct adapter *adapter = netdev_priv(dev);
 	struct slic_hostcmd *hcmd = NULL;
 	u32 status = 0;
 	u32 skbtype = NORMAL_ETHFRAME;
@@ -1071,7 +1078,7 @@ static void slic_xmit_complete(struct ad
 static irqreturn_t slic_interrupt(int irq, void *dev_id)
 {
 	struct net_device *dev = (struct net_device *)dev_id;
-	struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+	struct adapter *adapter = netdev_priv(dev);
 	u32 isr;
 
 	if ((adapter->pshmem) && (adapter->pshmem->isr)) {
@@ -1229,22 +1236,21 @@ static void slic_init_cleanup(struct ada
 
 static struct net_device_stats *slic_get_stats(struct net_device *dev)
 {
-	struct adapter *adapter = (struct adapter *)netdev_priv(dev);
-	struct net_device_stats *stats;
+	struct adapter *adapter = netdev_priv(dev);
 
 	ASSERT(adapter);
-	stats = &adapter->stats;
-	stats->collisions = adapter->slic_stats.iface.xmit_collisions;
-	stats->rx_errors = adapter->slic_stats.iface.rcv_errors;
-	stats->tx_errors = adapter->slic_stats.iface.xmt_errors;
-	stats->rx_missed_errors = adapter->slic_stats.iface.rcv_discards;
-	stats->tx_heartbeat_errors = 0;
-	stats->tx_aborted_errors = 0;
-	stats->tx_window_errors = 0;
-	stats->tx_fifo_errors = 0;
-	stats->rx_frame_errors = 0;
-	stats->rx_length_errors = 0;
-	return &adapter->stats;
+	dev->stats.collisions = adapter->slic_stats.iface.xmit_collisions;
+	dev->stats.rx_errors = adapter->slic_stats.iface.rcv_errors;
+	dev->stats.tx_errors = adapter->slic_stats.iface.xmt_errors;
+	dev->stats.rx_missed_errors = adapter->slic_stats.iface.rcv_discards;
+	dev->stats.tx_heartbeat_errors = 0;
+	dev->stats.tx_aborted_errors = 0;
+	dev->stats.tx_window_errors = 0;
+	dev->stats.tx_fifo_errors = 0;
+	dev->stats.rx_frame_errors = 0;
+	dev->stats.rx_length_errors = 0;
+
+	return &dev->stats;
 }
 
 /*
@@ -1254,13 +1260,11 @@ static struct net_device_stats *slic_get
 static int slic_mcast_add_list(struct adapter *adapter, char *address)
 {
 	struct mcast_address *mcaddr, *mlist;
-	bool equaladdr;
 
 	/* Check to see if it already exists */
 	mlist = adapter->mcastaddrs;
 	while (mlist) {
-		ETHER_EQ_ADDR(mlist->address, address, equaladdr);
-		if (equaladdr)
+		if (!compare_ether_addr(mlist->address, address))
 			return STATUS_SUCCESS;
 		mlist = mlist->next;
 	}
@@ -1360,27 +1364,19 @@ static void slic_mcast_set_bit(struct ad
 
 static void slic_mcast_set_list(struct net_device *dev)
 {
-	struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+	struct adapter *adapter = netdev_priv(dev);
 	int status = STATUS_SUCCESS;
-	int i;
 	char *addresses;
-	struct dev_mc_list *mc_list = dev->mc_list;
-	int mc_count = dev->mc_count;
+	struct dev_mc_list *mc_list;
 
 	ASSERT(adapter);
 
-	for (i = 1; i <= mc_count; i++) {
+	netdev_for_each_mc_addr(mc_list, dev) {
 		addresses = (char *) &mc_list->dmi_addr;
-		if (mc_list->dmi_addrlen == 6) {
-			status = slic_mcast_add_list(adapter, addresses);
-			if (status != STATUS_SUCCESS)
-				break;
-		} else {
-			status = -EINVAL;
+		status = slic_mcast_add_list(adapter, addresses);
+		if (status != STATUS_SUCCESS)
 			break;
-		}
 		slic_mcast_set_bit(adapter, addresses);
-		mc_list = mc_list->next;
 	}
 
 	if (adapter->devflags_prev != dev->flags) {
@@ -1860,6 +1856,8 @@ static int slic_card_download_gbrcv(stru
 	return 0;
 }
 
+/*(DEBLOBBED)*/
+
 static int slic_card_download(struct adapter *adapter)
 {
 	const struct firmware *fw;
@@ -1971,6 +1969,8 @@ static int slic_card_download(struct ada
 	return STATUS_SUCCESS;
 }
 
+/*(DEBLOBBED)*/
+
 static void slic_adapter_set_hwaddr(struct adapter *adapter)
 {
 	struct sliccard *card = adapter->card;
@@ -2474,7 +2474,6 @@ static bool slic_mac_filter(struct adapt
 	u32 opts = adapter->macopts;
 	u32 *dhost4 = (u32 *)&ether_frame->ether_dhost[0];
 	u16 *dhost2 = (u16 *)&ether_frame->ether_dhost[4];
-	bool equaladdr;
 
 	if (opts & MAC_PROMISC)
 		return true;
@@ -2498,10 +2497,8 @@ static bool slic_mac_filter(struct adapt
 			struct mcast_address *mcaddr = adapter->mcastaddrs;
 
 			while (mcaddr) {
-				ETHER_EQ_ADDR(mcaddr->address,
-					      ether_frame->ether_dhost,
-					      equaladdr);
-				if (equaladdr) {
+				if (!compare_ether_addr(mcaddr->address,
+							ether_frame->ether_dhost)) {
 					adapter->rcv_multicasts++;
 					adapter->stats.multicast++;
 					return true;
@@ -2523,7 +2520,7 @@ static bool slic_mac_filter(struct adapt
 
 static int slic_mac_set_address(struct net_device *dev, void *ptr)
 {
-	struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+	struct adapter *adapter = netdev_priv(dev);
 	struct sockaddr *addr = ptr;
 
 	if (netif_running(dev))
@@ -2531,6 +2528,9 @@ static int slic_mac_set_address(struct n
 	if (!adapter)
 		return -EBUSY;
 
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EINVAL;
+
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 	memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len);
 
@@ -3965,10 +3965,8 @@ static void slic_debug_adapter_create(st
 
 static void slic_debug_adapter_destroy(struct adapter *adapter)
 {
-	if (adapter->debugfs_entry) {
-		debugfs_remove(adapter->debugfs_entry);
-		adapter->debugfs_entry = NULL;
-	}
+	debugfs_remove(adapter->debugfs_entry);
+	adapter->debugfs_entry = NULL;
 }
 
 static void slic_debug_card_create(struct sliccard *card)
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/sm7xx/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/sm7xx/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/sm7xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/sm7xx/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -6,10 +6,3 @@ config FB_SM7XX
 	select FB_CFB_IMAGEBLIT
 	help
 	  Frame Buffer driver for the Silicon Motion SM7XX serial graphic card.
-
-config FB_SM7XX_ACCEL
-	bool "Siliconmotion Acceleration functions (EXPERIMENTAL)"
-	depends on FB_SM7XX && EXPERIMENTAL
-	help
-	  This will compile the Trident frame buffer device with
-	  acceleration functions.
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/sm7xx/smtc2d.c linux-libre-2.6.34-gnu1/drivers/staging/sm7xx/smtc2d.c
--- linux-libre-2.6.33-gnu1/drivers/staging/sm7xx/smtc2d.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/sm7xx/smtc2d.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,979 +0,0 @@
-/*
- * Silicon Motion SM7XX 2D drawing engine functions.
- *
- * Copyright (C) 2006 Silicon Motion Technology Corp.
- * Author: Boyod boyod.yang@siliconmotion.com.cn
- *
- * Copyright (C) 2009 Lemote, Inc.
- * Author: Wu Zhangjin, wuzj@lemote.com
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License. See the file COPYING in the main directory of this archive for
- *  more details.
- *
- * Version 0.10.26192.21.01
- * 	- Add PowerPC support
- * 	- Add 2D support for Lynx -
- * Verified on 2.6.19.2
- * 	Boyod.yang  <boyod.yang@siliconmotion.com.cn>
- */
-
-unsigned char smtc_de_busy;
-
-void SMTC_write2Dreg(unsigned long nOffset, unsigned long nData)
-{
-	writel(nData, smtc_2DBaseAddress + nOffset);
-}
-
-unsigned long SMTC_read2Dreg(unsigned long nOffset)
-{
-	return readl(smtc_2DBaseAddress + nOffset);
-}
-
-void SMTC_write2Ddataport(unsigned long nOffset, unsigned long nData)
-{
-	writel(nData, smtc_2Ddataport + nOffset);
-}
-
-/**********************************************************************
- *
- * deInit
- *
- * Purpose
- *    Drawing engine initialization.
- *
- **********************************************************************/
-
-void deInit(unsigned int nModeWidth, unsigned int nModeHeight,
-		unsigned int bpp)
-{
-	/* Get current power configuration. */
-	unsigned char clock;
-	clock = smtc_seqr(0x21);
-
-	/* initialize global 'mutex lock' variable */
-	smtc_de_busy = 0;
-
-	/* Enable 2D Drawing Engine */
-	smtc_seqw(0x21, clock & 0xF8);
-
-	SMTC_write2Dreg(DE_CLIP_TL,
-			FIELD_VALUE(0, DE_CLIP_TL, TOP, 0) |
-			FIELD_SET(0, DE_CLIP_TL, STATUS, DISABLE) |
-			FIELD_SET(0, DE_CLIP_TL, INHIBIT, OUTSIDE) |
-			FIELD_VALUE(0, DE_CLIP_TL, LEFT, 0));
-
-	if (bpp >= 24) {
-		SMTC_write2Dreg(DE_PITCH,
-				FIELD_VALUE(0, DE_PITCH, DESTINATION,
-					    nModeWidth * 3) | FIELD_VALUE(0,
-								  DE_PITCH,
-								  SOURCE,
-								  nModeWidth
-								  * 3));
-	} else {
-		SMTC_write2Dreg(DE_PITCH,
-				FIELD_VALUE(0, DE_PITCH, DESTINATION,
-					    nModeWidth) | FIELD_VALUE(0,
-							      DE_PITCH,
-							      SOURCE,
-							      nModeWidth));
-	}
-
-	SMTC_write2Dreg(DE_WINDOW_WIDTH,
-			FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
-				    nModeWidth) | FIELD_VALUE(0,
-							      DE_WINDOW_WIDTH,
-							      SOURCE,
-							      nModeWidth));
-
-	switch (bpp) {
-	case 8:
-		SMTC_write2Dreg(DE_STRETCH_FORMAT,
-				FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
-					  NORMAL) | FIELD_VALUE(0,
-							DE_STRETCH_FORMAT,
-							PATTERN_Y,
-							0) |
-				FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
-				    0) | FIELD_SET(0, DE_STRETCH_FORMAT,
-						   PIXEL_FORMAT,
-						   8) | FIELD_SET(0,
-							  DE_STRETCH_FORMAT,
-							  ADDRESSING,
-							  XY) |
-				FIELD_VALUE(0, DE_STRETCH_FORMAT,
-					SOURCE_HEIGHT, 3));
-		break;
-	case 24:
-		SMTC_write2Dreg(DE_STRETCH_FORMAT,
-				FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
-					  NORMAL) | FIELD_VALUE(0,
-							DE_STRETCH_FORMAT,
-							PATTERN_Y,
-							0) |
-				FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
-				    0) | FIELD_SET(0, DE_STRETCH_FORMAT,
-							   PIXEL_FORMAT,
-							   24) | FIELD_SET(0,
-							   DE_STRETCH_FORMAT,
-							   ADDRESSING,
-							   XY) |
-				FIELD_VALUE(0, DE_STRETCH_FORMAT,
-					SOURCE_HEIGHT, 3));
-		break;
-	case 16:
-	default:
-		SMTC_write2Dreg(DE_STRETCH_FORMAT,
-				FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
-					  NORMAL) | FIELD_VALUE(0,
-							DE_STRETCH_FORMAT,
-							PATTERN_Y,
-							0) |
-				FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
-				    0) | FIELD_SET(0, DE_STRETCH_FORMAT,
-							   PIXEL_FORMAT,
-							   16) | FIELD_SET(0,
-							   DE_STRETCH_FORMAT,
-							   ADDRESSING,
-							   XY) |
-				FIELD_VALUE(0, DE_STRETCH_FORMAT,
-					SOURCE_HEIGHT, 3));
-		break;
-	}
-
-	SMTC_write2Dreg(DE_MASKS,
-			FIELD_VALUE(0, DE_MASKS, BYTE_MASK, 0xFFFF) |
-			FIELD_VALUE(0, DE_MASKS, BIT_MASK, 0xFFFF));
-	SMTC_write2Dreg(DE_COLOR_COMPARE_MASK,
-			FIELD_VALUE(0, DE_COLOR_COMPARE_MASK, MASKS, \
-				0xFFFFFF));
-	SMTC_write2Dreg(DE_COLOR_COMPARE,
-			FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, 0xFFFFFF));
-}
-
-void deVerticalLine(unsigned long dst_base,
-		    unsigned long dst_pitch,
-		    unsigned long nX,
-		    unsigned long nY,
-		    unsigned long dst_height, unsigned long nColor)
-{
-	deWaitForNotBusy();
-
-	SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
-			FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
-				    dst_base));
-
-	SMTC_write2Dreg(DE_PITCH,
-			FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) |
-			FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch));
-
-	SMTC_write2Dreg(DE_WINDOW_WIDTH,
-			FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
-			    dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH,
-						     SOURCE,
-						     dst_pitch));
-
-	SMTC_write2Dreg(DE_FOREGROUND,
-			FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
-
-	SMTC_write2Dreg(DE_DESTINATION,
-			FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
-			FIELD_VALUE(0, DE_DESTINATION, X, nX) |
-			FIELD_VALUE(0, DE_DESTINATION, Y, nY));
-
-	SMTC_write2Dreg(DE_DIMENSION,
-			FIELD_VALUE(0, DE_DIMENSION, X, 1) |
-			FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
-
-	SMTC_write2Dreg(DE_CONTROL,
-			FIELD_SET(0, DE_CONTROL, STATUS, START) |
-			FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
-			FIELD_SET(0, DE_CONTROL, MAJOR, Y) |
-			FIELD_SET(0, DE_CONTROL, STEP_X, NEGATIVE) |
-			FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) |
-			FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
-			FIELD_SET(0, DE_CONTROL, COMMAND, SHORT_STROKE) |
-			FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
-			FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C));
-
-	smtc_de_busy = 1;
-}
-
-void deHorizontalLine(unsigned long dst_base,
-		      unsigned long dst_pitch,
-		      unsigned long nX,
-		      unsigned long nY,
-		      unsigned long dst_width, unsigned long nColor)
-{
-	deWaitForNotBusy();
-
-	SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
-			FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
-				    dst_base));
-
-	SMTC_write2Dreg(DE_PITCH,
-			FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) |
-			FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch));
-
-	SMTC_write2Dreg(DE_WINDOW_WIDTH,
-			FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
-			    dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH,
-						     SOURCE,
-						     dst_pitch));
-	SMTC_write2Dreg(DE_FOREGROUND,
-			FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
-	SMTC_write2Dreg(DE_DESTINATION,
-			FIELD_SET(0, DE_DESTINATION, WRAP,
-			  DISABLE) | FIELD_VALUE(0, DE_DESTINATION, X,
-						 nX) | FIELD_VALUE(0,
-							   DE_DESTINATION,
-							   Y,
-							   nY));
-	SMTC_write2Dreg(DE_DIMENSION,
-			FIELD_VALUE(0, DE_DIMENSION, X,
-			    dst_width) | FIELD_VALUE(0, DE_DIMENSION,
-						     Y_ET, 1));
-	SMTC_write2Dreg(DE_CONTROL,
-		FIELD_SET(0, DE_CONTROL, STATUS, START) | FIELD_SET(0,
-							    DE_CONTROL,
-							    DIRECTION,
-							    RIGHT_TO_LEFT)
-		| FIELD_SET(0, DE_CONTROL, MAJOR, X) | FIELD_SET(0,
-							 DE_CONTROL,
-							 STEP_X,
-							 POSITIVE)
-		| FIELD_SET(0, DE_CONTROL, STEP_Y,
-			    NEGATIVE) | FIELD_SET(0, DE_CONTROL,
-						  LAST_PIXEL,
-						  OFF) | FIELD_SET(0,
-							   DE_CONTROL,
-							   COMMAND,
-							   SHORT_STROKE)
-		| FIELD_SET(0, DE_CONTROL, ROP_SELECT,
-			    ROP2) | FIELD_VALUE(0, DE_CONTROL, ROP,
-						0x0C));
-
-	smtc_de_busy = 1;
-}
-
-void deLine(unsigned long dst_base,
-	    unsigned long dst_pitch,
-	    unsigned long nX1,
-	    unsigned long nY1,
-	    unsigned long nX2, unsigned long nY2, unsigned long nColor)
-{
-	unsigned long nCommand =
-	    FIELD_SET(0, DE_CONTROL, STATUS, START) |
-	    FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
-	    FIELD_SET(0, DE_CONTROL, MAJOR, X) |
-	    FIELD_SET(0, DE_CONTROL, STEP_X, POSITIVE) |
-	    FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) |
-	    FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
-	    FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
-	    FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C);
-	unsigned long DeltaX;
-	unsigned long DeltaY;
-
-	/* Calculate delta X */
-	if (nX1 <= nX2)
-		DeltaX = nX2 - nX1;
-	else {
-		DeltaX = nX1 - nX2;
-		nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_X, NEGATIVE);
-	}
-
-	/* Calculate delta Y */
-	if (nY1 <= nY2)
-		DeltaY = nY2 - nY1;
-	else {
-		DeltaY = nY1 - nY2;
-		nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_Y, NEGATIVE);
-	}
-
-	/* Determine the major axis */
-	if (DeltaX < DeltaY)
-		nCommand = FIELD_SET(nCommand, DE_CONTROL, MAJOR, Y);
-
-	/* Vertical line? */
-	if (nX1 == nX2)
-		deVerticalLine(dst_base, dst_pitch, nX1, nY1, DeltaY, nColor);
-
-	/* Horizontal line? */
-	else if (nY1 == nY2)
-		deHorizontalLine(dst_base, dst_pitch, nX1, nY1, \
-				DeltaX, nColor);
-
-	/* Diagonal line? */
-	else if (DeltaX == DeltaY) {
-		deWaitForNotBusy();
-
-		SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
-				FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE,
-					    ADDRESS, dst_base));
-
-		SMTC_write2Dreg(DE_PITCH,
-				FIELD_VALUE(0, DE_PITCH, DESTINATION,
-					    dst_pitch) | FIELD_VALUE(0,
-							     DE_PITCH,
-							     SOURCE,
-							     dst_pitch));
-
-		SMTC_write2Dreg(DE_WINDOW_WIDTH,
-				FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
-					    dst_pitch) | FIELD_VALUE(0,
-							     DE_WINDOW_WIDTH,
-							     SOURCE,
-							     dst_pitch));
-
-		SMTC_write2Dreg(DE_FOREGROUND,
-				FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
-
-		SMTC_write2Dreg(DE_DESTINATION,
-				FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
-				FIELD_VALUE(0, DE_DESTINATION, X, 1) |
-				FIELD_VALUE(0, DE_DESTINATION, Y, nY1));
-
-		SMTC_write2Dreg(DE_DIMENSION,
-				FIELD_VALUE(0, DE_DIMENSION, X, 1) |
-				FIELD_VALUE(0, DE_DIMENSION, Y_ET, DeltaX));
-
-		SMTC_write2Dreg(DE_CONTROL,
-				FIELD_SET(nCommand, DE_CONTROL, COMMAND,
-					  SHORT_STROKE));
-	}
-
-	/* Generic line */
-	else {
-		unsigned int k1, k2, et, w;
-		if (DeltaX < DeltaY) {
-			k1 = 2 * DeltaX;
-			et = k1 - DeltaY;
-			k2 = et - DeltaY;
-			w = DeltaY + 1;
-		} else {
-			k1 = 2 * DeltaY;
-			et = k1 - DeltaX;
-			k2 = et - DeltaX;
-			w = DeltaX + 1;
-		}
-
-		deWaitForNotBusy();
-
-		SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
-				FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE,
-					    ADDRESS, dst_base));
-
-		SMTC_write2Dreg(DE_PITCH,
-				FIELD_VALUE(0, DE_PITCH, DESTINATION,
-					    dst_pitch) | FIELD_VALUE(0,
-							     DE_PITCH,
-							     SOURCE,
-							     dst_pitch));
-
-		SMTC_write2Dreg(DE_WINDOW_WIDTH,
-				FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
-					    dst_pitch) | FIELD_VALUE(0,
-							     DE_WINDOW_WIDTH,
-							     SOURCE,
-							     dst_pitch));
-
-		SMTC_write2Dreg(DE_FOREGROUND,
-				FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
-
-		SMTC_write2Dreg(DE_SOURCE,
-				FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
-				FIELD_VALUE(0, DE_SOURCE, X_K1, k1) |
-				FIELD_VALUE(0, DE_SOURCE, Y_K2, k2));
-
-		SMTC_write2Dreg(DE_DESTINATION,
-				FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
-				FIELD_VALUE(0, DE_DESTINATION, X, nX1) |
-				FIELD_VALUE(0, DE_DESTINATION, Y, nY1));
-
-		SMTC_write2Dreg(DE_DIMENSION,
-				FIELD_VALUE(0, DE_DIMENSION, X, w) |
-				FIELD_VALUE(0, DE_DIMENSION, Y_ET, et));
-
-		SMTC_write2Dreg(DE_CONTROL,
-				FIELD_SET(nCommand, DE_CONTROL, COMMAND,
-					  LINE_DRAW));
-	}
-
-	smtc_de_busy = 1;
-}
-
-void deFillRect(unsigned long dst_base,
-		unsigned long dst_pitch,
-		unsigned long dst_X,
-		unsigned long dst_Y,
-		unsigned long dst_width,
-		unsigned long dst_height, unsigned long nColor)
-{
-	deWaitForNotBusy();
-
-	SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
-			FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
-				    dst_base));
-
-	if (dst_pitch) {
-		SMTC_write2Dreg(DE_PITCH,
-				FIELD_VALUE(0, DE_PITCH, DESTINATION,
-					    dst_pitch) | FIELD_VALUE(0,
-							     DE_PITCH,
-							     SOURCE,
-							     dst_pitch));
-
-		SMTC_write2Dreg(DE_WINDOW_WIDTH,
-				FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
-					    dst_pitch) | FIELD_VALUE(0,
-							     DE_WINDOW_WIDTH,
-							     SOURCE,
-							     dst_pitch));
-	}
-
-	SMTC_write2Dreg(DE_FOREGROUND,
-			FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
-
-	SMTC_write2Dreg(DE_DESTINATION,
-			FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
-			FIELD_VALUE(0, DE_DESTINATION, X, dst_X) |
-			FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y));
-
-	SMTC_write2Dreg(DE_DIMENSION,
-			FIELD_VALUE(0, DE_DIMENSION, X, dst_width) |
-			FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
-
-	SMTC_write2Dreg(DE_CONTROL,
-			FIELD_SET(0, DE_CONTROL, STATUS, START) |
-			FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
-			FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
-			FIELD_SET(0, DE_CONTROL, COMMAND, RECTANGLE_FILL) |
-			FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
-			FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C));
-
-	smtc_de_busy = 1;
-}
-
-/**********************************************************************
- *
- * deRotatePattern
- *
- * Purpose
- *    Rotate the given pattern if necessary
- *
- * Parameters
- *    [in]
- *	   pPattern  - Pointer to DE_SURFACE structure containing
- *		       pattern attributes
- *	   patternX  - X position (0-7) of pattern origin
- *	   patternY  - Y position (0-7) of pattern origin
- *
- *    [out]
- *	   pattern_dstaddr - Pointer to pre-allocated buffer containing
- *	   rotated pattern
- *
- **********************************************************************/
-void deRotatePattern(unsigned char *pattern_dstaddr,
-		     unsigned long pattern_src_addr,
-		     unsigned long pattern_BPP,
-		     unsigned long pattern_stride, int patternX, int patternY)
-{
-	unsigned int i;
-	unsigned long pattern[PATTERN_WIDTH * PATTERN_HEIGHT];
-	unsigned int x, y;
-	unsigned char *pjPatByte;
-
-	if (pattern_dstaddr != NULL) {
-		deWaitForNotBusy();
-
-		if (patternX || patternY) {
-			/* Rotate pattern */
-			pjPatByte = (unsigned char *)pattern;
-
-			switch (pattern_BPP) {
-			case 8:
-				{
-					for (y = 0; y < 8; y++) {
-						unsigned char *pjBuffer =
-						    pattern_dstaddr +
-						    ((patternY + y) & 7) * 8;
-						for (x = 0; x < 8; x++) {
-							pjBuffer[(patternX +
-								  x) & 7] =
-							    pjPatByte[x];
-						}
-						pjPatByte += pattern_stride;
-					}
-					break;
-				}
-
-			case 16:
-				{
-					for (y = 0; y < 8; y++) {
-						unsigned short *pjBuffer =
-						    (unsigned short *)
-						    pattern_dstaddr +
-						    ((patternY + y) & 7) * 8;
-						for (x = 0; x < 8; x++) {
-							pjBuffer[(patternX +
-								  x) & 7] =
-							    ((unsigned short *)
-							     pjPatByte)[x];
-						}
-						pjPatByte += pattern_stride;
-					}
-					break;
-				}
-
-			case 32:
-				{
-					for (y = 0; y < 8; y++) {
-						unsigned long *pjBuffer =
-						    (unsigned long *)
-						    pattern_dstaddr +
-						    ((patternY + y) & 7) * 8;
-						for (x = 0; x < 8; x++) {
-							pjBuffer[(patternX +
-								  x) & 7] =
-							    ((unsigned long *)
-							     pjPatByte)[x];
-						}
-						pjPatByte += pattern_stride;
-					}
-					break;
-				}
-			}
-		} else {
-			/*Don't rotate,just copy pattern into pattern_dstaddr*/
-			for (i = 0; i < (pattern_BPP * 2); i++) {
-				((unsigned long *)pattern_dstaddr)[i] =
-				    pattern[i];
-			}
-		}
-
-	}
-}
-
-/**********************************************************************
- *
- * deCopy
- *
- * Purpose
- *    Copy a rectangular area of the source surface to a destination surface
- *
- * Remarks
- *    Source bitmap must have the same color depth (BPP) as the destination
- *    bitmap.
- *
-**********************************************************************/
-void deCopy(unsigned long dst_base,
-	    unsigned long dst_pitch,
-	    unsigned long dst_BPP,
-	    unsigned long dst_X,
-	    unsigned long dst_Y,
-	    unsigned long dst_width,
-	    unsigned long dst_height,
-	    unsigned long src_base,
-	    unsigned long src_pitch,
-	    unsigned long src_X,
-	    unsigned long src_Y, pTransparent pTransp, unsigned char nROP2)
-{
-	unsigned long nDirection = 0;
-	unsigned long nTransparent = 0;
-	/* Direction of ROP2 operation:
-	 * 1 = Left to Right,
-	 * (-1) = Right to Left
-	 */
-	unsigned long opSign = 1;
-	/* xWidth is in pixels */
-	unsigned long xWidth = 192 / (dst_BPP / 8);
-	unsigned long de_ctrl = 0;
-
-	deWaitForNotBusy();
-
-	SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
-			FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
-				    dst_base));
-
-	SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE,
-			FIELD_VALUE(0, DE_WINDOW_SOURCE_BASE, ADDRESS,
-				    src_base));
-
-	if (dst_pitch && src_pitch) {
-		SMTC_write2Dreg(DE_PITCH,
-			FIELD_VALUE(0, DE_PITCH, DESTINATION,
-				    dst_pitch) | FIELD_VALUE(0,
-						     DE_PITCH,
-						     SOURCE,
-						     src_pitch));
-
-		SMTC_write2Dreg(DE_WINDOW_WIDTH,
-			FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
-				    dst_pitch) | FIELD_VALUE(0,
-						     DE_WINDOW_WIDTH,
-						     SOURCE,
-						     src_pitch));
-	}
-
-	/* Set transparent bits if necessary */
-	if (pTransp != NULL) {
-		nTransparent =
-		    pTransp->match | pTransp->select | pTransp->control;
-
-		/* Set color compare register */
-		SMTC_write2Dreg(DE_COLOR_COMPARE,
-				FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR,
-					    pTransp->color));
-	}
-
-	/* Determine direction of operation */
-	if (src_Y < dst_Y) {
-		/* +----------+
-		   |S         |
-		   |          +----------+
-		   |          |      |   |
-		   |          |      |   |
-		   +---|------+      |
-		   |               D |
-		   +----------+ */
-
-		nDirection = BOTTOM_TO_TOP;
-	} else if (src_Y > dst_Y) {
-		/* +----------+
-		   |D         |
-		   |          +----------+
-		   |          |      |   |
-		   |          |      |   |
-		   +---|------+      |
-		   |               S |
-		   +----------+ */
-
-		nDirection = TOP_TO_BOTTOM;
-	} else {
-		/* src_Y == dst_Y */
-
-		if (src_X <= dst_X) {
-			/* +------+---+------+
-			   |S     |   |     D|
-			   |      |   |      |
-			   |      |   |      |
-			   |      |   |      |
-			   +------+---+------+ */
-
-			nDirection = RIGHT_TO_LEFT;
-		} else {
-			/* src_X > dst_X */
-
-			/* +------+---+------+
-			   |D     |   |     S|
-			   |      |   |      |
-			   |      |   |      |
-			   |      |   |      |
-			   +------+---+------+ */
-
-			nDirection = LEFT_TO_RIGHT;
-		}
-	}
-
-	if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) {
-		src_X += dst_width - 1;
-		src_Y += dst_height - 1;
-		dst_X += dst_width - 1;
-		dst_Y += dst_height - 1;
-		opSign = (-1);
-	}
-
-	if (dst_BPP >= 24) {
-		src_X *= 3;
-		src_Y *= 3;
-		dst_X *= 3;
-		dst_Y *= 3;
-		dst_width *= 3;
-		if ((nDirection == BOTTOM_TO_TOP)
-		    || (nDirection == RIGHT_TO_LEFT)) {
-			src_X += 2;
-			dst_X += 2;
-		}
-	}
-
-	/* Workaround for 192 byte hw bug */
-	if ((nROP2 != 0x0C) && ((dst_width * (dst_BPP / 8)) >= 192)) {
-		/*
-		 * Perform the ROP2 operation in chunks of (xWidth *
-		 * dst_height)
-		 */
-		while (1) {
-			deWaitForNotBusy();
-
-			SMTC_write2Dreg(DE_SOURCE,
-				FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
-				FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) |
-				FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y));
-
-			SMTC_write2Dreg(DE_DESTINATION,
-				FIELD_SET(0, DE_DESTINATION, WRAP,
-				  DISABLE) | FIELD_VALUE(0,
-							 DE_DESTINATION,
-							 X,
-							 dst_X)
-			| FIELD_VALUE(0, DE_DESTINATION, Y,
-						      dst_Y));
-
-			SMTC_write2Dreg(DE_DIMENSION,
-				FIELD_VALUE(0, DE_DIMENSION, X,
-				    xWidth) | FIELD_VALUE(0,
-							  DE_DIMENSION,
-							  Y_ET,
-							  dst_height));
-
-			de_ctrl =
-			    FIELD_VALUE(0, DE_CONTROL, ROP,
-				nROP2) | nTransparent | FIELD_SET(0,
-							  DE_CONTROL,
-							  ROP_SELECT,
-							  ROP2)
-			    | FIELD_SET(0, DE_CONTROL, COMMAND,
-				BITBLT) | ((nDirection ==
-					    1) ? FIELD_SET(0,
-						   DE_CONTROL,
-						   DIRECTION,
-						   RIGHT_TO_LEFT)
-					   : FIELD_SET(0, DE_CONTROL,
-					       DIRECTION,
-					       LEFT_TO_RIGHT)) |
-			    FIELD_SET(0, DE_CONTROL, STATUS, START);
-
-			SMTC_write2Dreg(DE_CONTROL, de_ctrl);
-
-			src_X += (opSign * xWidth);
-			dst_X += (opSign * xWidth);
-			dst_width -= xWidth;
-
-			if (dst_width <= 0) {
-				/* ROP2 operation is complete */
-				break;
-			}
-
-			if (xWidth > dst_width)
-				xWidth = dst_width;
-		}
-	} else {
-		deWaitForNotBusy();
-		SMTC_write2Dreg(DE_SOURCE,
-			FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
-			FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) |
-			FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y));
-
-		SMTC_write2Dreg(DE_DESTINATION,
-			FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
-			FIELD_VALUE(0, DE_DESTINATION, X, dst_X) |
-			FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y));
-
-		SMTC_write2Dreg(DE_DIMENSION,
-			FIELD_VALUE(0, DE_DIMENSION, X, dst_width) |
-			FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
-
-		de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, nROP2) |
-		    nTransparent |
-		    FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
-		    FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) |
-		    ((nDirection == 1) ? FIELD_SET(0, DE_CONTROL, DIRECTION,
-						   RIGHT_TO_LEFT)
-		     : FIELD_SET(0, DE_CONTROL, DIRECTION,
-				 LEFT_TO_RIGHT)) | FIELD_SET(0, DE_CONTROL,
-							     STATUS, START);
-		SMTC_write2Dreg(DE_CONTROL, de_ctrl);
-	}
-
-	smtc_de_busy = 1;
-}
-
-/*
- * This function sets the pixel format that will apply to the 2D Engine.
- */
-void deSetPixelFormat(unsigned long bpp)
-{
-	unsigned long de_format;
-
-	de_format = SMTC_read2Dreg(DE_STRETCH_FORMAT);
-
-	switch (bpp) {
-	case 8:
-		de_format =
-		    FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 8);
-		break;
-	default:
-	case 16:
-		de_format =
-		    FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 16);
-		break;
-	case 32:
-		de_format =
-		    FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 32);
-		break;
-	}
-
-	SMTC_write2Dreg(DE_STRETCH_FORMAT, de_format);
-}
-
-/*
- * System memory to Video memory monochrome expansion.
- *
- * Source is monochrome image in system memory.  This function expands the
- * monochrome data to color image in video memory.
- */
-
-long deSystemMem2VideoMemMonoBlt(const char *pSrcbuf,
-				 long srcDelta,
-				 unsigned long startBit,
-				 unsigned long dBase,
-				 unsigned long dPitch,
-				 unsigned long bpp,
-				 unsigned long dx, unsigned long dy,
-				 unsigned long width, unsigned long height,
-				 unsigned long fColor,
-				 unsigned long bColor,
-				 unsigned long rop2) {
-	unsigned long bytePerPixel;
-	unsigned long ulBytesPerScan;
-	unsigned long ul4BytesPerScan;
-	unsigned long ulBytesRemain;
-	unsigned long de_ctrl = 0;
-	unsigned char ajRemain[4];
-	long i, j;
-
-	bytePerPixel = bpp / 8;
-
-	/* Just make sure the start bit is within legal range */
-	startBit &= 7;
-
-	ulBytesPerScan = (width + startBit + 7) / 8;
-	ul4BytesPerScan = ulBytesPerScan & ~3;
-	ulBytesRemain = ulBytesPerScan & 3;
-
-	if (smtc_de_busy)
-		deWaitForNotBusy();
-
-	/*
-	 * 2D Source Base.  Use 0 for HOST Blt.
-	 */
-
-	SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, 0);
-
-	/*
-	 * 2D Destination Base.
-	 *
-	 * It is an address offset (128 bit aligned) from the beginning of
-	 * frame buffer.
-	 */
-
-	SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, dBase);
-
-	if (dPitch) {
-
-		/*
-		 * Program pitch (distance between the 1st points of two
-		 * adjacent lines).
-		 *
-		 * Note that input pitch is BYTE value, but the 2D Pitch
-		 * register uses pixel values. Need Byte to pixel convertion.
-		 */
-
-		SMTC_write2Dreg(DE_PITCH,
-			FIELD_VALUE(0, DE_PITCH, DESTINATION,
-			    dPitch /
-			    bytePerPixel) | FIELD_VALUE(0,
-							DE_PITCH,
-							SOURCE,
-							dPitch /
-							bytePerPixel));
-
-		/* Screen Window width in Pixels.
-		 *
-		 * 2D engine uses this value to calculate the linear address in
-		 * frame buffer for a given point.
-		 */
-
-		SMTC_write2Dreg(DE_WINDOW_WIDTH,
-			FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
-			    (dPitch /
-			     bytePerPixel)) | FIELD_VALUE(0,
-							  DE_WINDOW_WIDTH,
-							  SOURCE,
-							  (dPitch
-							   /
-							   bytePerPixel)));
-	}
-	/* Note: For 2D Source in Host Write, only X_K1 field is needed, and
-	 * Y_K2 field is not used. For mono bitmap, use startBit for X_K1.
-	 */
-
-	SMTC_write2Dreg(DE_SOURCE,
-			FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
-			FIELD_VALUE(0, DE_SOURCE, X_K1, startBit) |
-			FIELD_VALUE(0, DE_SOURCE, Y_K2, 0));
-
-	SMTC_write2Dreg(DE_DESTINATION,
-			FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
-			FIELD_VALUE(0, DE_DESTINATION, X, dx) |
-			FIELD_VALUE(0, DE_DESTINATION, Y, dy));
-
-	SMTC_write2Dreg(DE_DIMENSION,
-			FIELD_VALUE(0, DE_DIMENSION, X, width) |
-			FIELD_VALUE(0, DE_DIMENSION, Y_ET, height));
-
-	SMTC_write2Dreg(DE_FOREGROUND, fColor);
-	SMTC_write2Dreg(DE_BACKGROUND, bColor);
-
-	if (bpp)
-		deSetPixelFormat(bpp);
-	/* Set the pixel format of the destination */
-
-	de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) |
-	    FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
-	    FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) |
-	    FIELD_SET(0, DE_CONTROL, HOST, MONO) |
-	    FIELD_SET(0, DE_CONTROL, STATUS, START);
-
-	SMTC_write2Dreg(DE_CONTROL, de_ctrl | deGetTransparency());
-
-	/* Write MONO data (line by line) to 2D Engine data port */
-	for (i = 0; i < height; i++) {
-		/* For each line, send the data in chunks of 4 bytes */
-		for (j = 0; j < (ul4BytesPerScan / 4); j++)
-			SMTC_write2Ddataport(0,
-					     *(unsigned long *)(pSrcbuf +
-								(j * 4)));
-
-		if (ulBytesRemain) {
-			memcpy(ajRemain, pSrcbuf + ul4BytesPerScan,
-			       ulBytesRemain);
-			SMTC_write2Ddataport(0, *(unsigned long *)ajRemain);
-		}
-
-		pSrcbuf += srcDelta;
-	}
-	smtc_de_busy = 1;
-
-	return 0;
-}
-
-/*
- * This function gets the transparency status from DE_CONTROL register.
- * It returns a double word with the transparent fields properly set,
- * while other fields are 0.
- */
-unsigned long deGetTransparency(void)
-{
-	unsigned long de_ctrl;
-
-	de_ctrl = SMTC_read2Dreg(DE_CONTROL);
-
-	de_ctrl &=
-	    FIELD_MASK(DE_CONTROL_TRANSPARENCY_MATCH) |
-	    FIELD_MASK(DE_CONTROL_TRANSPARENCY_SELECT) |
-	    FIELD_MASK(DE_CONTROL_TRANSPARENCY);
-
-	return de_ctrl;
-}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/sm7xx/smtc2d.h linux-libre-2.6.34-gnu1/drivers/staging/sm7xx/smtc2d.h
--- linux-libre-2.6.33-gnu1/drivers/staging/sm7xx/smtc2d.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/sm7xx/smtc2d.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,530 +0,0 @@
-/*
- * Silicon Motion SM712 2D drawing engine functions.
- *
- * Copyright (C) 2006 Silicon Motion Technology Corp.
- * Author: Ge Wang, gewang@siliconmotion.com
- *
- * Copyright (C) 2009 Lemote, Inc.
- * Author: Wu Zhangjin, wuzj@lemote.com
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License. See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#ifndef NULL
-#define NULL	 0
-#endif
-
-/* Internal macros */
-
-#define _F_START(f)		(0 ? f)
-#define _F_END(f)		(1 ? f)
-#define _F_SIZE(f)		(1 + _F_END(f) - _F_START(f))
-#define _F_MASK(f)		(((1ULL << _F_SIZE(f)) - 1) << _F_START(f))
-#define _F_NORMALIZE(v, f)	(((v) & _F_MASK(f)) >> _F_START(f))
-#define _F_DENORMALIZE(v, f)	(((v) << _F_START(f)) & _F_MASK(f))
-
-/* Global macros */
-
-#define FIELD_GET(x, reg, field) \
-( \
-    _F_NORMALIZE((x), reg ## _ ## field) \
-)
-
-#define FIELD_SET(x, reg, field, value) \
-( \
-    (x & ~_F_MASK(reg ## _ ## field)) \
-    | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \
-)
-
-#define FIELD_VALUE(x, reg, field, value) \
-( \
-    (x & ~_F_MASK(reg ## _ ## field)) \
-    | _F_DENORMALIZE(value, reg ## _ ## field) \
-)
-
-#define FIELD_CLEAR(reg, field) \
-( \
-    ~_F_MASK(reg ## _ ## field) \
-)
-
-/* Field Macros                        */
-
-#define FIELD_START(field)	(0 ? field)
-#define FIELD_END(field)	(1 ? field)
-#define FIELD_SIZE(field) \
-	(1 + FIELD_END(field) - FIELD_START(field))
-
-#define FIELD_MASK(field) \
-	(((1 << (FIELD_SIZE(field)-1)) \
-	| ((1 << (FIELD_SIZE(field)-1)) - 1)) \
-	<< FIELD_START(field))
-
-#define FIELD_NORMALIZE(reg, field) \
-	(((reg) & FIELD_MASK(field)) >> FIELD_START(field))
-
-#define FIELD_DENORMALIZE(field, value) \
-	(((value) << FIELD_START(field)) & FIELD_MASK(field))
-
-#define FIELD_INIT(reg, field, value) \
-	FIELD_DENORMALIZE(reg ## _ ## field, \
-		reg ## _ ## field ## _ ## value)
-
-#define FIELD_INIT_VAL(reg, field, value) \
-	(FIELD_DENORMALIZE(reg ## _ ## field, value))
-
-#define FIELD_VAL_SET(x, r, f, v) ({ \
-	x = (x & ~FIELD_MASK(r ## _ ## f)) \
-	| FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) \
-})
-
-#define RGB(r, g, b)	((unsigned long)(((r) << 16) | ((g) << 8) | (b)))
-
-/* Transparent info definition */
-typedef struct {
-	unsigned long match;	/* Matching pixel is OPAQUE/TRANSPARENT */
-	unsigned long select;	/* Transparency controlled by SRC/DST */
-	unsigned long control;	/* ENABLE/DISABLE transparency */
-	unsigned long color;	/* Transparent color */
-} Transparent, *pTransparent;
-
-#define PIXEL_DEPTH_1_BP	0	/* 1 bit per pixel */
-#define PIXEL_DEPTH_8_BPP	1	/* 8 bits per pixel */
-#define PIXEL_DEPTH_16_BPP	2	/* 16 bits per pixel */
-#define PIXEL_DEPTH_32_BPP	3	/* 32 bits per pixel */
-#define PIXEL_DEPTH_YUV422	8	/* 16 bits per pixel YUV422 */
-#define PIXEL_DEPTH_YUV420	9	/* 16 bits per pixel YUV420 */
-
-#define PATTERN_WIDTH		8
-#define PATTERN_HEIGHT		8
-
-#define	TOP_TO_BOTTOM		0
-#define	BOTTOM_TO_TOP		1
-#define RIGHT_TO_LEFT		BOTTOM_TO_TOP
-#define LEFT_TO_RIGHT		TOP_TO_BOTTOM
-
-/* Constants used in Transparent structure */
-#define MATCH_OPAQUE		0x00000000
-#define MATCH_TRANSPARENT	0x00000400
-#define SOURCE			0x00000000
-#define DESTINATION		0x00000200
-
-/* 2D registers. */
-
-#define	DE_SOURCE			0x000000
-#define	DE_SOURCE_WRAP			31 : 31
-#define	DE_SOURCE_WRAP_DISABLE		0
-#define	DE_SOURCE_WRAP_ENABLE		1
-#define	DE_SOURCE_X_K1			29 : 16
-#define	DE_SOURCE_Y_K2			15 : 0
-
-#define	DE_DESTINATION			0x000004
-#define	DE_DESTINATION_WRAP		31 : 31
-#define	DE_DESTINATION_WRAP_DISABLE	0
-#define	DE_DESTINATION_WRAP_ENABLE	1
-#define	DE_DESTINATION_X		28 : 16
-#define	DE_DESTINATION_Y		15 : 0
-
-#define	DE_DIMENSION			0x000008
-#define	DE_DIMENSION_X			28 : 16
-#define	DE_DIMENSION_Y_ET		15 : 0
-
-#define	DE_CONTROL			0x00000C
-#define	DE_CONTROL_STATUS		31 : 31
-#define	DE_CONTROL_STATUS_STOP		0
-#define	DE_CONTROL_STATUS_START		1
-#define	DE_CONTROL_PATTERN		30 : 30
-#define	DE_CONTROL_PATTERN_MONO		0
-#define	DE_CONTROL_PATTERN_COLOR	1
-#define	DE_CONTROL_UPDATE_DESTINATION_X		29 : 29
-#define	DE_CONTROL_UPDATE_DESTINATION_X_DISABLE	0
-#define	DE_CONTROL_UPDATE_DESTINATION_X_ENABLE	1
-#define	DE_CONTROL_QUICK_START			28 : 28
-#define	DE_CONTROL_QUICK_START_DISABLE		0
-#define	DE_CONTROL_QUICK_START_ENABLE		1
-#define	DE_CONTROL_DIRECTION			27 : 27
-#define	DE_CONTROL_DIRECTION_LEFT_TO_RIGHT	0
-#define	DE_CONTROL_DIRECTION_RIGHT_TO_LEFT	1
-#define	DE_CONTROL_MAJOR			26 : 26
-#define	DE_CONTROL_MAJOR_X			0
-#define	DE_CONTROL_MAJOR_Y			1
-#define	DE_CONTROL_STEP_X			25 : 25
-#define	DE_CONTROL_STEP_X_POSITIVE		1
-#define	DE_CONTROL_STEP_X_NEGATIVE		0
-#define	DE_CONTROL_STEP_Y			24 : 24
-#define	DE_CONTROL_STEP_Y_POSITIVE		1
-#define	DE_CONTROL_STEP_Y_NEGATIVE		0
-#define	DE_CONTROL_STRETCH			23 : 23
-#define	DE_CONTROL_STRETCH_DISABLE		0
-#define	DE_CONTROL_STRETCH_ENABLE		1
-#define	DE_CONTROL_HOST				22 : 22
-#define	DE_CONTROL_HOST_COLOR			0
-#define	DE_CONTROL_HOST_MONO			1
-#define	DE_CONTROL_LAST_PIXEL			21 : 21
-#define	DE_CONTROL_LAST_PIXEL_OFF		0
-#define	DE_CONTROL_LAST_PIXEL_ON		1
-#define	DE_CONTROL_COMMAND			20 : 16
-#define	DE_CONTROL_COMMAND_BITBLT		0
-#define	DE_CONTROL_COMMAND_RECTANGLE_FILL	1
-#define	DE_CONTROL_COMMAND_DE_TILE		2
-#define	DE_CONTROL_COMMAND_TRAPEZOID_FILL	3
-#define	DE_CONTROL_COMMAND_ALPHA_BLEND		4
-#define	DE_CONTROL_COMMAND_RLE_STRIP		5
-#define	DE_CONTROL_COMMAND_SHORT_STROKE		6
-#define	DE_CONTROL_COMMAND_LINE_DRAW		7
-#define	DE_CONTROL_COMMAND_HOST_WRITE		8
-#define	DE_CONTROL_COMMAND_HOST_READ		9
-#define	DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP	10
-#define	DE_CONTROL_COMMAND_ROTATE		11
-#define	DE_CONTROL_COMMAND_FONT			12
-#define	DE_CONTROL_COMMAND_TEXTURE_LOAD		15
-#define	DE_CONTROL_ROP_SELECT			15 : 15
-#define	DE_CONTROL_ROP_SELECT_ROP3		0
-#define	DE_CONTROL_ROP_SELECT_ROP2		1
-#define	DE_CONTROL_ROP2_SOURCE			14 : 14
-#define	DE_CONTROL_ROP2_SOURCE_BITMAP		0
-#define	DE_CONTROL_ROP2_SOURCE_PATTERN		1
-#define	DE_CONTROL_MONO_DATA			13 : 12
-#define	DE_CONTROL_MONO_DATA_NOT_PACKED		0
-#define	DE_CONTROL_MONO_DATA_8_PACKED		1
-#define	DE_CONTROL_MONO_DATA_16_PACKED		2
-#define	DE_CONTROL_MONO_DATA_32_PACKED		3
-#define	DE_CONTROL_REPEAT_ROTATE		11 : 11
-#define	DE_CONTROL_REPEAT_ROTATE_DISABLE	0
-#define	DE_CONTROL_REPEAT_ROTATE_ENABLE		1
-#define	DE_CONTROL_TRANSPARENCY_MATCH		10 : 10
-#define	DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE		0
-#define	DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT	1
-#define	DE_CONTROL_TRANSPARENCY_SELECT			9 : 9
-#define	DE_CONTROL_TRANSPARENCY_SELECT_SOURCE		0
-#define	DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION	1
-#define	DE_CONTROL_TRANSPARENCY				8 : 8
-#define	DE_CONTROL_TRANSPARENCY_DISABLE			0
-#define	DE_CONTROL_TRANSPARENCY_ENABLE			1
-#define	DE_CONTROL_ROP					7 : 0
-
-/* Pseudo fields. */
-
-#define	DE_CONTROL_SHORT_STROKE_DIR			27 : 24
-#define	DE_CONTROL_SHORT_STROKE_DIR_225			0
-#define	DE_CONTROL_SHORT_STROKE_DIR_135			1
-#define	DE_CONTROL_SHORT_STROKE_DIR_315			2
-#define	DE_CONTROL_SHORT_STROKE_DIR_45			3
-#define	DE_CONTROL_SHORT_STROKE_DIR_270			4
-#define	DE_CONTROL_SHORT_STROKE_DIR_90			5
-#define	DE_CONTROL_SHORT_STROKE_DIR_180			8
-#define	DE_CONTROL_SHORT_STROKE_DIR_0			10
-#define	DE_CONTROL_ROTATION				25 : 24
-#define	DE_CONTROL_ROTATION_0				0
-#define	DE_CONTROL_ROTATION_270				1
-#define	DE_CONTROL_ROTATION_90				2
-#define	DE_CONTROL_ROTATION_180				3
-
-#define	DE_PITCH					0x000010
-#define	DE_PITCH_DESTINATION				28 : 16
-#define	DE_PITCH_SOURCE					12 : 0
-
-#define	DE_FOREGROUND					0x000014
-#define	DE_FOREGROUND_COLOR				31 : 0
-
-#define	DE_BACKGROUND					0x000018
-#define	DE_BACKGROUND_COLOR				31 : 0
-
-#define	DE_STRETCH_FORMAT				0x00001C
-#define	DE_STRETCH_FORMAT_PATTERN_XY			30 : 30
-#define	DE_STRETCH_FORMAT_PATTERN_XY_NORMAL		0
-#define	DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE		1
-#define	DE_STRETCH_FORMAT_PATTERN_Y			29 : 27
-#define	DE_STRETCH_FORMAT_PATTERN_X			25 : 23
-#define	DE_STRETCH_FORMAT_PIXEL_FORMAT			21 : 20
-#define	DE_STRETCH_FORMAT_PIXEL_FORMAT_8		0
-#define	DE_STRETCH_FORMAT_PIXEL_FORMAT_16		1
-#define	DE_STRETCH_FORMAT_PIXEL_FORMAT_24		3
-#define	DE_STRETCH_FORMAT_PIXEL_FORMAT_32		2
-#define	DE_STRETCH_FORMAT_ADDRESSING			19 : 16
-#define	DE_STRETCH_FORMAT_ADDRESSING_XY			0
-#define	DE_STRETCH_FORMAT_ADDRESSING_LINEAR		15
-#define	DE_STRETCH_FORMAT_SOURCE_HEIGHT			11 : 0
-
-#define	DE_COLOR_COMPARE				0x000020
-#define	DE_COLOR_COMPARE_COLOR				23 : 0
-
-#define	DE_COLOR_COMPARE_MASK				0x000024
-#define	DE_COLOR_COMPARE_MASK_MASKS			23 : 0
-
-#define	DE_MASKS					0x000028
-#define	DE_MASKS_BYTE_MASK				31 : 16
-#define	DE_MASKS_BIT_MASK				15 : 0
-
-#define	DE_CLIP_TL					0x00002C
-#define	DE_CLIP_TL_TOP					31 : 16
-#define	DE_CLIP_TL_STATUS				13 : 13
-#define	DE_CLIP_TL_STATUS_DISABLE			0
-#define	DE_CLIP_TL_STATUS_ENABLE			1
-#define	DE_CLIP_TL_INHIBIT				12 : 12
-#define	DE_CLIP_TL_INHIBIT_OUTSIDE			0
-#define	DE_CLIP_TL_INHIBIT_INSIDE			1
-#define	DE_CLIP_TL_LEFT					11 : 0
-
-#define	DE_CLIP_BR					0x000030
-#define	DE_CLIP_BR_BOTTOM				31 : 16
-#define	DE_CLIP_BR_RIGHT				12 : 0
-
-#define	DE_MONO_PATTERN_LOW				0x000034
-#define	DE_MONO_PATTERN_LOW_PATTERN			31 : 0
-
-#define	DE_MONO_PATTERN_HIGH				0x000038
-#define	DE_MONO_PATTERN_HIGH_PATTERN			31 : 0
-
-#define	DE_WINDOW_WIDTH					0x00003C
-#define	DE_WINDOW_WIDTH_DESTINATION			28 : 16
-#define	DE_WINDOW_WIDTH_SOURCE				12 : 0
-
-#define	DE_WINDOW_SOURCE_BASE				0x000040
-#define	DE_WINDOW_SOURCE_BASE_EXT			27 : 27
-#define	DE_WINDOW_SOURCE_BASE_EXT_LOCAL			0
-#define	DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL		1
-#define	DE_WINDOW_SOURCE_BASE_CS			26 : 26
-#define	DE_WINDOW_SOURCE_BASE_CS_0			0
-#define	DE_WINDOW_SOURCE_BASE_CS_1			1
-#define	DE_WINDOW_SOURCE_BASE_ADDRESS			25 : 0
-
-#define	DE_WINDOW_DESTINATION_BASE			0x000044
-#define	DE_WINDOW_DESTINATION_BASE_EXT			27 : 27
-#define	DE_WINDOW_DESTINATION_BASE_EXT_LOCAL		0
-#define	DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL		1
-#define	DE_WINDOW_DESTINATION_BASE_CS			26 : 26
-#define	DE_WINDOW_DESTINATION_BASE_CS_0			0
-#define	DE_WINDOW_DESTINATION_BASE_CS_1			1
-#define	DE_WINDOW_DESTINATION_BASE_ADDRESS		25 : 0
-
-#define	DE_ALPHA					0x000048
-#define	DE_ALPHA_VALUE					7 : 0
-
-#define	DE_WRAP						0x00004C
-#define	DE_WRAP_X					31 : 16
-#define	DE_WRAP_Y					15 : 0
-
-#define	DE_STATUS					0x000050
-#define	DE_STATUS_CSC					1 : 1
-#define	DE_STATUS_CSC_CLEAR				0
-#define	DE_STATUS_CSC_NOT_ACTIVE			0
-#define	DE_STATUS_CSC_ACTIVE				1
-#define	DE_STATUS_2D					0 : 0
-#define	DE_STATUS_2D_CLEAR				0
-#define	DE_STATUS_2D_NOT_ACTIVE				0
-#define	DE_STATUS_2D_ACTIVE				1
-
-/* Color Space Conversion registers. */
-
-#define	CSC_Y_SOURCE_BASE				0x0000C8
-#define	CSC_Y_SOURCE_BASE_EXT				27 : 27
-#define	CSC_Y_SOURCE_BASE_EXT_LOCAL			0
-#define	CSC_Y_SOURCE_BASE_EXT_EXTERNAL			1
-#define	CSC_Y_SOURCE_BASE_CS				26 : 26
-#define	CSC_Y_SOURCE_BASE_CS_0				0
-#define	CSC_Y_SOURCE_BASE_CS_1				1
-#define	CSC_Y_SOURCE_BASE_ADDRESS			25 : 0
-
-#define	CSC_CONSTANTS					0x0000CC
-#define	CSC_CONSTANTS_Y					31 : 24
-#define	CSC_CONSTANTS_R					23 : 16
-#define	CSC_CONSTANTS_G					15 : 8
-#define	CSC_CONSTANTS_B					7 : 0
-
-#define	CSC_Y_SOURCE_X					0x0000D0
-#define	CSC_Y_SOURCE_X_INTEGER				26 : 16
-#define	CSC_Y_SOURCE_X_FRACTION				15 : 3
-
-#define	CSC_Y_SOURCE_Y					0x0000D4
-#define	CSC_Y_SOURCE_Y_INTEGER				27 : 16
-#define	CSC_Y_SOURCE_Y_FRACTION				15 : 3
-
-#define	CSC_U_SOURCE_BASE				0x0000D8
-#define	CSC_U_SOURCE_BASE_EXT				27 : 27
-#define	CSC_U_SOURCE_BASE_EXT_LOCAL			0
-#define	CSC_U_SOURCE_BASE_EXT_EXTERNAL			1
-#define	CSC_U_SOURCE_BASE_CS				26 : 26
-#define	CSC_U_SOURCE_BASE_CS_0				0
-#define	CSC_U_SOURCE_BASE_CS_1				1
-#define	CSC_U_SOURCE_BASE_ADDRESS			25 : 0
-
-#define	CSC_V_SOURCE_BASE				0x0000DC
-#define	CSC_V_SOURCE_BASE_EXT				27 : 27
-#define	CSC_V_SOURCE_BASE_EXT_LOCAL			0
-#define	CSC_V_SOURCE_BASE_EXT_EXTERNAL			1
-#define	CSC_V_SOURCE_BASE_CS				26 : 26
-#define	CSC_V_SOURCE_BASE_CS_0				0
-#define	CSC_V_SOURCE_BASE_CS_1				1
-#define	CSC_V_SOURCE_BASE_ADDRESS			25 : 0
-
-#define	CSC_SOURCE_DIMENSION				0x0000E0
-#define	CSC_SOURCE_DIMENSION_X				31 : 16
-#define	CSC_SOURCE_DIMENSION_Y				15 : 0
-
-#define	CSC_SOURCE_PITCH				0x0000E4
-#define	CSC_SOURCE_PITCH_Y				31 : 16
-#define	CSC_SOURCE_PITCH_UV				15 : 0
-
-#define	CSC_DESTINATION					0x0000E8
-#define	CSC_DESTINATION_WRAP				31 : 31
-#define	CSC_DESTINATION_WRAP_DISABLE			0
-#define	CSC_DESTINATION_WRAP_ENABLE			1
-#define	CSC_DESTINATION_X				27 : 16
-#define	CSC_DESTINATION_Y				11 : 0
-
-#define	CSC_DESTINATION_DIMENSION			0x0000EC
-#define	CSC_DESTINATION_DIMENSION_X			31 : 16
-#define	CSC_DESTINATION_DIMENSION_Y			15 : 0
-
-#define	CSC_DESTINATION_PITCH				0x0000F0
-#define	CSC_DESTINATION_PITCH_X				31 : 16
-#define	CSC_DESTINATION_PITCH_Y				15 : 0
-
-#define	CSC_SCALE_FACTOR				0x0000F4
-#define	CSC_SCALE_FACTOR_HORIZONTAL			31 : 16
-#define	CSC_SCALE_FACTOR_VERTICAL			15 : 0
-
-#define	CSC_DESTINATION_BASE				0x0000F8
-#define	CSC_DESTINATION_BASE_EXT			27 : 27
-#define	CSC_DESTINATION_BASE_EXT_LOCAL			0
-#define	CSC_DESTINATION_BASE_EXT_EXTERNAL		1
-#define	CSC_DESTINATION_BASE_CS				26 : 26
-#define	CSC_DESTINATION_BASE_CS_0			0
-#define	CSC_DESTINATION_BASE_CS_1			1
-#define	CSC_DESTINATION_BASE_ADDRESS			25 : 0
-
-#define	CSC_CONTROL					0x0000FC
-#define	CSC_CONTROL_STATUS				31 : 31
-#define	CSC_CONTROL_STATUS_STOP				0
-#define	CSC_CONTROL_STATUS_START			1
-#define	CSC_CONTROL_SOURCE_FORMAT			30 : 28
-#define	CSC_CONTROL_SOURCE_FORMAT_YUV422		0
-#define	CSC_CONTROL_SOURCE_FORMAT_YUV420I		1
-#define	CSC_CONTROL_SOURCE_FORMAT_YUV420		2
-#define	CSC_CONTROL_SOURCE_FORMAT_YVU9			3
-#define	CSC_CONTROL_SOURCE_FORMAT_IYU1			4
-#define	CSC_CONTROL_SOURCE_FORMAT_IYU2			5
-#define	CSC_CONTROL_SOURCE_FORMAT_RGB565		6
-#define	CSC_CONTROL_SOURCE_FORMAT_RGB8888		7
-#define	CSC_CONTROL_DESTINATION_FORMAT			27 : 26
-#define	CSC_CONTROL_DESTINATION_FORMAT_RGB565		0
-#define	CSC_CONTROL_DESTINATION_FORMAT_RGB8888		1
-#define	CSC_CONTROL_HORIZONTAL_FILTER			25 : 25
-#define	CSC_CONTROL_HORIZONTAL_FILTER_DISABLE		0
-#define	CSC_CONTROL_HORIZONTAL_FILTER_ENABLE		1
-#define	CSC_CONTROL_VERTICAL_FILTER			24 : 24
-#define	CSC_CONTROL_VERTICAL_FILTER_DISABLE		0
-#define	CSC_CONTROL_VERTICAL_FILTER_ENABLE		1
-#define	CSC_CONTROL_BYTE_ORDER				23 : 23
-#define	CSC_CONTROL_BYTE_ORDER_YUYV			0
-#define	CSC_CONTROL_BYTE_ORDER_UYVY			1
-
-#define	DE_DATA_PORT_501				0x110000
-#define	DE_DATA_PORT_712				0x400000
-#define	DE_DATA_PORT_722				0x6000
-
-/* point to virtual Memory Map IO starting address */
-extern char *smtc_RegBaseAddress;
-/* point to virtual video memory starting address */
-extern char *smtc_VRAMBaseAddress;
-extern unsigned char smtc_de_busy;
-
-extern unsigned long memRead32(unsigned long nOffset);
-extern void memWrite32(unsigned long nOffset, unsigned long nData);
-extern unsigned long SMTC_read2Dreg(unsigned long nOffset);
-
-/* 2D functions */
-extern void deInit(unsigned int nModeWidth, unsigned int nModeHeight,
-		   unsigned int bpp);
-
-extern void deWaitForNotBusy(void);
-
-extern void deVerticalLine(unsigned long dst_base,
-	unsigned long dst_pitch,
-	unsigned long nX,
-	unsigned long nY,
-	unsigned long dst_height,
-	unsigned long nColor);
-
-extern void deHorizontalLine(unsigned long dst_base,
-	unsigned long dst_pitch,
-	unsigned long nX,
-	unsigned long nY,
-	unsigned long dst_width,
-	unsigned long nColor);
-
-extern void deLine(unsigned long dst_base,
-	unsigned long dst_pitch,
-	unsigned long nX1,
-	unsigned long nY1,
-	unsigned long nX2,
-	unsigned long nY2,
-	unsigned long nColor);
-
-extern void deFillRect(unsigned long dst_base,
-	unsigned long dst_pitch,
-	unsigned long dst_X,
-	unsigned long dst_Y,
-	unsigned long dst_width,
-	unsigned long dst_height,
-	unsigned long nColor);
-
-extern void deRotatePattern(unsigned char *pattern_dstaddr,
-	unsigned long pattern_src_addr,
-	unsigned long pattern_BPP,
-	unsigned long pattern_stride,
-	int	patternX,
-	int	patternY);
-
-extern void deCopy(unsigned long dst_base,
-	unsigned long dst_pitch,
-	unsigned long dst_BPP,
-	unsigned long dst_X,
-	unsigned long dst_Y,
-	unsigned long dst_width,
-	unsigned long dst_height,
-	unsigned long src_base,
-	unsigned long src_pitch,
-	unsigned long src_X,
-	unsigned long src_Y,
-	pTransparent	pTransp,
-	unsigned char nROP2);
-
-/*
- * System memory to Video memory monochrome expansion.
- *
- * Source is monochrome image in system memory.  This function expands the
- * monochrome data to color image in video memory.
- *
- * @pSrcbuf: pointer to start of source buffer in system memory
- * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top
- * 		down and -ive mean button up
- * @startBit: Mono data can start at any bit in a byte, this value should
- * 		be 0 to 7
- * @dBase: Address of destination :  offset in frame buffer
- * @dPitch: Pitch value of destination surface in BYTE
- * @bpp: Color depth of destination surface
- * @dx, dy: Starting coordinate of destination surface
- * @width, height: width and height of rectange in pixel value
- * @fColor,bColor: Foreground, Background color (corresponding to a 1, 0 in
- * 	the monochrome data)
- * @rop2: ROP value
- */
-
-extern long deSystemMem2VideoMemMonoBlt(
-	const char *pSrcbuf,
-	long srcDelta,
-	unsigned long startBit,
-	unsigned long dBase,
-	unsigned long dPitch,
-	unsigned long bpp,
-	unsigned long dx, unsigned long dy,
-	unsigned long width, unsigned long height,
-	unsigned long fColor,
-	unsigned long bColor,
-	unsigned long rop2);
-
-extern unsigned long deGetTransparency(void);
-extern void deSetPixelFormat(unsigned long bpp);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/sm7xx/smtcfb.c linux-libre-2.6.34-gnu1/drivers/staging/sm7xx/smtcfb.c
--- linux-libre-2.6.33-gnu1/drivers/staging/sm7xx/smtcfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/sm7xx/smtcfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  * 	    Boyod boyod.yang@siliconmotion.com.cn
  *
  * Copyright (C) 2009 Lemote, Inc.
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Author: Wu Zhangjin, wuzhangjin@gmail.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
@@ -34,6 +34,7 @@
 #include <linux/fb.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/console.h>
 #include <linux/screen_info.h>
@@ -45,7 +46,6 @@
 struct screen_info smtc_screen_info;
 
 #include "smtcfb.h"
-#include "smtc2d.h"
 
 #ifdef DEBUG
 #define smdbg(format, arg...)	printk(KERN_DEBUG format , ## arg)
@@ -120,10 +120,6 @@ static struct vesa_mode_table vesa_mode[
 char __iomem *smtc_RegBaseAddress;	/* Memory Map IO starting address */
 char __iomem *smtc_VRAMBaseAddress;	/* video memory starting address */
 
-char *smtc_2DBaseAddress;	/* 2D engine starting address */
-char *smtc_2Ddataport;		/* 2D data port offset */
-short smtc_2Dacceleration;
-
 static u32 colreg[17];
 static struct par_info hw;	/* hardware information */
 
@@ -135,16 +131,6 @@ u16 smtc_ChipIDs[] = {
 
 #define numSMTCchipIDs (sizeof(smtc_ChipIDs) / sizeof(u16))
 
-void deWaitForNotBusy(void)
-{
-	unsigned long i = 0x1000000;
-	while (i--) {
-		if ((smtc_seqr(0x16) & 0x18) == 0x10)
-			break;
-	}
-	smtc_de_busy = 0;
-}
-
 static void sm712_set_timing(struct smtcfb_info *sfb,
 			     struct par_info *ppar_info)
 {
@@ -324,7 +310,7 @@ static inline unsigned int chan_to_field
 	return chan << bf->offset;
 }
 
-static int smtcfb_blank(int blank_mode, struct fb_info *info)
+static int cfb_blank(int blank_mode, struct fb_info *info)
 {
 	/* clear DPMS setting */
 	switch (blank_mode) {
@@ -622,93 +608,13 @@ smtcfb_write(struct fb_info *info, const
 }
 #endif	/* ! __BIG_ENDIAN */
 
-#include "smtc2d.c"
-
-void smtcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
-{
-	struct par_info *p = (struct par_info *)info->par;
-
-	if (smtc_2Dacceleration) {
-		if (!area->width || !area->height)
-			return;
-
-		deCopy(p->BaseAddressInVRAM, 0, info->var.bits_per_pixel,
-		       area->dx, area->dy, area->width, area->height,
-		       p->BaseAddressInVRAM, 0, area->sx, area->sy, 0, 0xC);
-
-	} else
-		cfb_copyarea(info, area);
-}
-
-void smtcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
-{
-	struct par_info *p = (struct par_info *)info->par;
-
-	if (smtc_2Dacceleration) {
-		if (!rect->width || !rect->height)
-			return;
-		if (info->var.bits_per_pixel >= 24)
-			deFillRect(p->BaseAddressInVRAM, 0, rect->dx * 3,
-				   rect->dy * 3, rect->width * 3, rect->height,
-				   rect->color);
-		else
-			deFillRect(p->BaseAddressInVRAM, 0, rect->dx, rect->dy,
-				   rect->width, rect->height, rect->color);
-	} else
-		cfb_fillrect(info, rect);
-}
-
-void smtcfb_imageblit(struct fb_info *info, const struct fb_image *image)
-{
-	struct par_info *p = (struct par_info *)info->par;
-	u32 bg_col = 0, fg_col = 0;
-
-	if ((smtc_2Dacceleration) && (image->depth == 1)) {
-		if (smtc_de_busy)
-			deWaitForNotBusy();
-
-		switch (info->var.bits_per_pixel) {
-		case 8:
-			bg_col = image->bg_color;
-			fg_col = image->fg_color;
-			break;
-		case 16:
-			bg_col =
-			    ((u32 *) (info->pseudo_palette))[image->bg_color];
-			fg_col =
-			    ((u32 *) (info->pseudo_palette))[image->fg_color];
-			break;
-		case 32:
-			bg_col =
-			    ((u32 *) (info->pseudo_palette))[image->bg_color];
-			fg_col =
-			    ((u32 *) (info->pseudo_palette))[image->fg_color];
-			break;
-		}
-
-		deSystemMem2VideoMemMonoBlt(
-			image->data,
-			image->width / 8,
-			0,
-			p->BaseAddressInVRAM,
-			0,
-			0,
-			image->dx, image->dy,
-			image->width, image->height,
-			fg_col, bg_col,
-			0x0C);
-
-	} else
-		cfb_imageblit(info, image);
-}
-
 static struct fb_ops smtcfb_ops = {
 	.owner = THIS_MODULE,
 	.fb_setcolreg = smtc_setcolreg,
-	.fb_blank = smtcfb_blank,
-	.fb_fillrect = smtcfb_fillrect,
-	.fb_imageblit = smtcfb_imageblit,
-	.fb_copyarea = smtcfb_copyarea,
+	.fb_blank = cfb_blank,
+	.fb_fillrect = cfb_fillrect,
+	.fb_imageblit = cfb_imageblit,
+	.fb_copyarea = cfb_copyarea,
 #ifdef __BIG_ENDIAN
 	.fb_read = smtcfb_read,
 	.fb_write = smtcfb_write,
@@ -772,12 +678,6 @@ void smtcfb_setmode(struct smtcfb_info *
 	hw.height = sfb->fb.var.yres;
 	hw.hz = 60;
 	smtc_set_timing(sfb, &hw);
-	if (smtc_2Dacceleration) {
-		printk("2D acceleration enabled!\n");
-		/* Init smtc drawing engine */
-		deInit(sfb->fb.var.xres, sfb->fb.var.yres,
-				sfb->fb.var.bits_per_pixel);
-	}
 }
 
 /*
@@ -1004,9 +904,7 @@ static int __init smtcfb_pci_probe(struc
 #endif
 		hw.m_pMMIO = (smtc_RegBaseAddress =
 		    smtc_VRAMBaseAddress + 0x00700000);
-		smtc_2DBaseAddress = (hw.m_pDPR =
-		    smtc_VRAMBaseAddress + 0x00408000);
-		smtc_2Ddataport = smtc_VRAMBaseAddress + DE_DATA_PORT_712;
+		hw.m_pDPR = smtc_VRAMBaseAddress + 0x00408000;
 		hw.m_pVPR = hw.m_pLFB + 0x0040c000;
 #ifdef __BIG_ENDIAN
 		if (sfb->fb.var.bits_per_pixel == 32) {
@@ -1035,27 +933,21 @@ static int __init smtcfb_pci_probe(struc
 		if (sfb->fb.var.bits_per_pixel == 32)
 			smtc_seqw(0x17, 0x30);
 #endif
-#ifdef CONFIG_FB_SM7XX_ACCEL
-		smtc_2Dacceleration = 1;
-#endif
 		break;
 	case 0x720:
 		sfb->fb.fix.mmio_start = pFramebufferPhysical;
 		sfb->fb.fix.mmio_len = 0x00200000;
 		smem_size = SM722_VIDEOMEMORYSIZE;
-		smtc_2DBaseAddress = (hw.m_pDPR =
-		    ioremap(pFramebufferPhysical, 0x00a00000));
+		hw.m_pDPR = ioremap(pFramebufferPhysical, 0x00a00000);
 		hw.m_pLFB = (smtc_VRAMBaseAddress =
-		    smtc_2DBaseAddress + 0x00200000);
+		    hw.m_pDPR + 0x00200000);
 		hw.m_pMMIO = (smtc_RegBaseAddress =
-		    smtc_2DBaseAddress + 0x000c0000);
-		smtc_2Ddataport = smtc_2DBaseAddress + DE_DATA_PORT_722;
-		hw.m_pVPR = smtc_2DBaseAddress + 0x800;
+		    hw.m_pDPR + 0x000c0000);
+		hw.m_pVPR = hw.m_pDPR + 0x800;
 
 		smtc_seqw(0x62, 0xff);
 		smtc_seqw(0x6a, 0x0d);
 		smtc_seqw(0x6b, 0x02);
-		smtc_2Dacceleration = 0;
 		break;
 	default:
 		printk(KERN_INFO
@@ -1103,7 +995,7 @@ static int __init smtcfb_pci_probe(struc
 
 
 /* Jason (08/11/2009) PCI_DRV wrapper essential structs */
-static struct pci_device_id smtcfb_pci_table[] = {
+static const struct pci_device_id smtcfb_pci_table[] = {
 	{0x126f, 0x710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x126f, 0x712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x126f, 0x720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/sm7xx/smtcfb.h linux-libre-2.6.34-gnu1/drivers/staging/sm7xx/smtcfb.h
--- linux-libre-2.6.33-gnu1/drivers/staging/sm7xx/smtcfb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/sm7xx/smtcfb.h	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@
  *	 	Boyod boyod.yang@siliconmotion.com.cn
  *
  * Copyright (C) 2009 Lemote, Inc.
- * Author: Wu Zhangjin, wuzj@lemote.com
+ * Author: Wu Zhangjin, wuzhangjin@gmail.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
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/sm7xx/TODO linux-libre-2.6.34-gnu1/drivers/staging/sm7xx/TODO
--- linux-libre-2.6.33-gnu1/drivers/staging/sm7xx/TODO	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/sm7xx/TODO	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,6 @@
 TODO:
 - Dual head support
+- 2D acceleration support
 - use kernel coding style
 - checkpatch.pl clean
 - refine the code and remove unused code
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/strip/strip.c linux-libre-2.6.34-gnu1/drivers/staging/strip/strip.c
--- linux-libre-2.6.33-gnu1/drivers/staging/strip/strip.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/strip/strip.c	2010-05-16 17:17:36.000000000 -0400
@@ -107,6 +107,7 @@ static const char StripVersion[] = "1.3A
 #include <linux/serialP.h>
 #include <linux/rcupdate.h>
 #include <linux/compat.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 #include <net/net_namespace.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/udlfb/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/udlfb/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/udlfb/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/udlfb/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,8 +1,14 @@
 config FB_UDL
 	tristate "Displaylink USB Framebuffer support"
 	depends on FB && USB
+	select FB_MODE_HELPERS
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	select FB_DEFERRED_IO
 	---help---
-	  This is an experimental driver for DisplayLink USB devices
-	  that provides a framebuffer device.  A normal framebuffer can
-	  be used with this driver, or xorg can be run on the device
-	  using it.
+	  This is a kernel framebuffer driver for DisplayLink USB devices.
+	  Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
+	  mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices.
+	  To compile as a module, choose M here: the module name is udlfb.
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/udlfb/udlfb.c linux-libre-2.6.34-gnu1/drivers/staging/udlfb/udlfb.c
--- linux-libre-2.6.33-gnu1/drivers/staging/udlfb/udlfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/udlfb/udlfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,17 +1,20 @@
-/*****************************************************************************
- *                          DLFB Kernel Driver                               *
- *                            Version 0.2 (udlfb)                            *
- *             (C) 2009 Roberto De Ioris <roberto@unbit.it>                  *
- *                                                                           *
- *     This file is licensed under the GPLv2. See COPYING in the package.    *
- * Based on the amazing work of Florian Echtler and libdlo 0.1               *
- *                                                                           *
- *                                                                           *
- * 10.06.09 release 0.2.3 (edid ioctl, fallback for unsupported modes)       *
- * 05.06.09 release 0.2.2 (real screen blanking, rle compression, double buffer) *
- * 31.05.09 release 0.2                                                      *
- * 22.05.09 First public (ugly) release                                      *
- *****************************************************************************/
+/*
+ * udlfb.c -- Framebuffer driver for DisplayLink USB controller
+ *
+ * Copyright (C) 2009 Roberto De Ioris <roberto@unbit.it>
+ * Copyright (C) 2009 Jaya Kumar <jayakumar.lkml@gmail.com>
+ * Copyright (C) 2009 Bernie Thompson <bernie@plugable.com>
+ *
+ * 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.
+ *
+ * Layout is based on skeletonfb by James Simmons and Geert Uytterhoeven,
+ * usb-skeleton by GregKH.
+ *
+ * Device-specific portions based on information from Displaylink, with work
+ * from Florian Echtler, Henrik Bjerregaard Pedersen, and others.
+ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -20,60 +23,283 @@
 #include <linux/uaccess.h>
 #include <linux/mm.h>
 #include <linux/fb.h>
-#include <linux/mutex.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include "udlfb.h"
 
-#define DRIVER_VERSION "DLFB 0.2"
+static struct fb_fix_screeninfo dlfb_fix = {
+	.id =           "udlfb",
+	.type =         FB_TYPE_PACKED_PIXELS,
+	.visual =       FB_VISUAL_TRUECOLOR,
+	.xpanstep =     0,
+	.ypanstep =     0,
+	.ywrapstep =    0,
+	.accel =        FB_ACCEL_NONE,
+};
 
-/* memory functions taken from vfb */
+static const u32 udlfb_info_flags = FBINFO_DEFAULT | FBINFO_READS_FAST |
+#ifdef FBINFO_VIRTFB
+		FBINFO_VIRTFB |
+#endif
+		FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_FILLRECT |
+		FBINFO_HWACCEL_COPYAREA | FBINFO_MISC_ALWAYS_SETPAR;
 
-static void *rvmalloc(unsigned long size)
+/*
+ * There are many DisplayLink-based products, all with unique PIDs. We are able
+ * to support all volume ones (circa 2009) with a single driver, so we match
+ * globally on VID. TODO: Probe() needs to detect when we might be running
+ * "future" chips, and bail on those, so a compatible driver can match.
+ */
+static struct usb_device_id id_table[] = {
+	{.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,},
+	{},
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+#ifndef CONFIG_FB_DEFERRED_IO
+#warning message "kernel FB_DEFFERRED_IO option to support generic fbdev apps"
+#endif
+
+#ifndef CONFIG_FB_SYS_IMAGEBLIT
+#ifndef CONFIG_FB_SYS_IMAGEBLIT_MODULE
+#warning message "FB_SYS_* in kernel or module option to support fb console"
+#endif
+#endif
+
+#ifndef CONFIG_FB_MODE_HELPERS
+#warning message "kernel FB_MODE_HELPERS required. Expect build break"
+#endif
+
+/* dlfb keeps a list of urbs for efficient bulk transfers */
+static void dlfb_urb_completion(struct urb *urb);
+static struct urb *dlfb_get_urb(struct dlfb_data *dev);
+static int dlfb_submit_urb(struct dlfb_data *dev, struct urb * urb, size_t len);
+static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size);
+static void dlfb_free_urb_list(struct dlfb_data *dev);
+
+/* other symbols with dependents */
+#ifdef CONFIG_FB_DEFERRED_IO
+static struct fb_deferred_io dlfb_defio;
+#endif
+
+/*
+ * All DisplayLink bulk operations start with 0xAF, followed by specific code
+ * All operations are written to buffers which then later get sent to device
+ */
+static char *dlfb_set_register(char *buf, u8 reg, u8 val)
 {
-	void *mem;
-	unsigned long adr;
+	*buf++ = 0xAF;
+	*buf++ = 0x20;
+	*buf++ = reg;
+	*buf++ = val;
+	return buf;
+}
 
-	size = PAGE_ALIGN(size);
-	mem = vmalloc_32(size);
-	if (!mem)
-		return NULL;
+static char *dlfb_vidreg_lock(char *buf)
+{
+	return dlfb_set_register(buf, 0xFF, 0x00);
+}
 
-	memset(mem, 0, size);	/* Clear the ram out, no junk to the user */
-	adr = (unsigned long)mem;
-	while (size > 0) {
-		SetPageReserved(vmalloc_to_page((void *)adr));
-		adr += PAGE_SIZE;
-		size -= PAGE_SIZE;
-	}
+static char *dlfb_vidreg_unlock(char *buf)
+{
+	return dlfb_set_register(buf, 0xFF, 0xFF);
+}
 
-	return mem;
+/*
+ * On/Off for driving the DisplayLink framebuffer to the display
+ */
+static char *dlfb_enable_hvsync(char *buf, bool enable)
+{
+	if (enable)
+		return dlfb_set_register(buf, 0x1F, 0x00);
+	else
+		return dlfb_set_register(buf, 0x1F, 0x01);
 }
 
-static void rvfree(void *mem, unsigned long size)
+static char *dlfb_set_color_depth(char *buf, u8 selection)
 {
-	unsigned long adr;
+	return dlfb_set_register(buf, 0x00, selection);
+}
 
-	if (!mem)
-		return;
+static char *dlfb_set_base16bpp(char *wrptr, u32 base)
+{
+	/* the base pointer is 16 bits wide, 0x20 is hi byte. */
+	wrptr = dlfb_set_register(wrptr, 0x20, base >> 16);
+	wrptr = dlfb_set_register(wrptr, 0x21, base >> 8);
+	return dlfb_set_register(wrptr, 0x22, base);
+}
 
-	adr = (unsigned long)mem;
-	while ((long)size > 0) {
-		ClearPageReserved(vmalloc_to_page((void *)adr));
-		adr += PAGE_SIZE;
-		size -= PAGE_SIZE;
+/*
+ * DisplayLink HW has separate 16bpp and 8bpp framebuffers.
+ * In 24bpp modes, the low 323 RGB bits go in the 8bpp framebuffer
+ */
+static char *dlfb_set_base8bpp(char *wrptr, u32 base)
+{
+	wrptr = dlfb_set_register(wrptr, 0x26, base >> 16);
+	wrptr = dlfb_set_register(wrptr, 0x27, base >> 8);
+	return dlfb_set_register(wrptr, 0x28, base);
+}
+
+static char *dlfb_set_register_16(char *wrptr, u8 reg, u16 value)
+{
+	wrptr = dlfb_set_register(wrptr, reg, value >> 8);
+	return dlfb_set_register(wrptr, reg+1, value);
+}
+
+/*
+ * This is kind of weird because the controller takes some
+ * register values in a different byte order than other registers.
+ */
+static char *dlfb_set_register_16be(char *wrptr, u8 reg, u16 value)
+{
+	wrptr = dlfb_set_register(wrptr, reg, value);
+	return dlfb_set_register(wrptr, reg+1, value >> 8);
+}
+
+/*
+ * LFSR is linear feedback shift register. The reason we have this is
+ * because the display controller needs to minimize the clock depth of
+ * various counters used in the display path. So this code reverses the
+ * provided value into the lfsr16 value by counting backwards to get
+ * the value that needs to be set in the hardware comparator to get the
+ * same actual count. This makes sense once you read above a couple of
+ * times and think about it from a hardware perspective.
+ */
+static u16 dlfb_lfsr16(u16 actual_count)
+{
+	u32 lv = 0xFFFF; /* This is the lfsr value that the hw starts with */
+
+	while (actual_count--) {
+		lv =	 ((lv << 1) |
+			(((lv >> 15) ^ (lv >> 4) ^ (lv >> 2) ^ (lv >> 1)) & 1))
+			& 0xFFFF;
 	}
-	vfree(mem);
+
+	return (u16) lv;
 }
 
-static int dlfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+/*
+ * This does LFSR conversion on the value that is to be written.
+ * See LFSR explanation above for more detail.
+ */
+static char *dlfb_set_register_lfsr16(char *wrptr, u8 reg, u16 value)
+{
+	return dlfb_set_register_16(wrptr, reg, dlfb_lfsr16(value));
+}
+
+/*
+ * This takes a standard fbdev screeninfo struct and all of its monitor mode
+ * details and converts them into the DisplayLink equivalent register commands.
+ */
+static char *dlfb_set_vid_cmds(char *wrptr, struct fb_var_screeninfo *var)
+{
+	u16 xds, yds;
+	u16 xde, yde;
+	u16 yec;
+
+	/* x display start */
+	xds = var->left_margin + var->hsync_len;
+	wrptr = dlfb_set_register_lfsr16(wrptr, 0x01, xds);
+	/* x display end */
+	xde = xds + var->xres;
+	wrptr = dlfb_set_register_lfsr16(wrptr, 0x03, xde);
+
+	/* y display start */
+	yds = var->upper_margin + var->vsync_len;
+	wrptr = dlfb_set_register_lfsr16(wrptr, 0x05, yds);
+	/* y display end */
+	yde = yds + var->yres;
+	wrptr = dlfb_set_register_lfsr16(wrptr, 0x07, yde);
+
+	/* x end count is active + blanking - 1 */
+	wrptr = dlfb_set_register_lfsr16(wrptr, 0x09,
+			xde + var->right_margin - 1);
+
+	/* libdlo hardcodes hsync start to 1 */
+	wrptr = dlfb_set_register_lfsr16(wrptr, 0x0B, 1);
+
+	/* hsync end is width of sync pulse + 1 */
+	wrptr = dlfb_set_register_lfsr16(wrptr, 0x0D, var->hsync_len + 1);
+
+	/* hpixels is active pixels */
+	wrptr = dlfb_set_register_16(wrptr, 0x0F, var->xres);
+
+	/* yendcount is vertical active + vertical blanking */
+	yec = var->yres + var->upper_margin + var->lower_margin +
+			var->vsync_len;
+	wrptr = dlfb_set_register_lfsr16(wrptr, 0x11, yec);
+
+	/* libdlo hardcodes vsync start to 0 */
+	wrptr = dlfb_set_register_lfsr16(wrptr, 0x13, 0);
+
+	/* vsync end is width of vsync pulse */
+	wrptr = dlfb_set_register_lfsr16(wrptr, 0x15, var->vsync_len);
+
+	/* vpixels is active pixels */
+	wrptr = dlfb_set_register_16(wrptr, 0x17, var->yres);
+
+	/* convert picoseconds to 5kHz multiple for pclk5k = x * 1E12/5k */
+	wrptr = dlfb_set_register_16be(wrptr, 0x1B,
+			200*1000*1000/var->pixclock);
+
+	return wrptr;
+}
+
+/*
+ * This takes a standard fbdev screeninfo struct that was fetched or prepared
+ * and then generates the appropriate command sequence that then drives the
+ * display controller.
+ */
+static int dlfb_set_video_mode(struct dlfb_data *dev,
+				struct fb_var_screeninfo *var)
+{
+	char *buf;
+	char *wrptr;
+	int retval = 0;
+	int writesize;
+	struct urb *urb;
+
+	if (!atomic_read(&dev->usb_active))
+		return -EPERM;
+
+	urb = dlfb_get_urb(dev);
+	if (!urb)
+		return -ENOMEM;
+	buf = (char *) urb->transfer_buffer;
+
+	/*
+	* This first section has to do with setting the base address on the
+	* controller * associated with the display. There are 2 base
+	* pointers, currently, we only * use the 16 bpp segment.
+	*/
+	wrptr = dlfb_vidreg_lock(buf);
+	wrptr = dlfb_set_color_depth(wrptr, 0x00);
+	/* set base for 16bpp segment to 0 */
+	wrptr = dlfb_set_base16bpp(wrptr, 0);
+	/* set base for 8bpp segment to end of fb */
+	wrptr = dlfb_set_base8bpp(wrptr, dev->info->fix.smem_len);
+
+	wrptr = dlfb_set_vid_cmds(wrptr, var);
+	wrptr = dlfb_enable_hvsync(wrptr, true);
+	wrptr = dlfb_vidreg_unlock(wrptr);
+
+	writesize = wrptr - buf;
+
+	retval = dlfb_submit_urb(dev, urb, writesize);
+
+	return retval;
+}
+
+static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
 	unsigned long start = vma->vm_start;
 	unsigned long size = vma->vm_end - vma->vm_start;
 	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
 	unsigned long page, pos;
+	struct dlfb_data *dev = info->par;
 
-	printk("MMAP: %lu %u\n", offset + size, info->fix.smem_len);
+	dl_notice("MMAP: %lu %u\n", offset + size, info->fix.smem_len);
 
 	if (offset + size > info->fix.smem_len)
 		return -EINVAL;
@@ -98,824 +324,1116 @@ static int dlfb_mmap(struct fb_info *inf
 
 }
 
-/* ioctl structure */
-struct dloarea {
-	int x, y;
-	int w, h;
-	int x2, y2;
-};
-
 /*
-static struct usb_device_id id_table [] = {
-	{ USB_DEVICE(0x17e9, 0x023d) },
-	{ }
-};
-*/
-
-static struct usb_device_id id_table[] = {
-	{.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,},
-	{},
-};
-MODULE_DEVICE_TABLE(usb, id_table);
-
-static struct usb_driver dlfb_driver;
-
-// thanks to Henrik Bjerregaard Pedersen for this function
-static char *rle_compress16(uint16_t * src, char *dst, int rem)
+ * Trims identical data from front and back of line
+ * Sets new front buffer address and width
+ * And returns byte count of identical pixels
+ * Assumes CPU natural alignment (unsigned long)
+ * for back and front buffer ptrs and width
+ */
+static int dlfb_trim_hline(const u8 *bback, const u8 **bfront, int *width_bytes)
 {
+	int j, k;
+	const unsigned long *back = (const unsigned long *) bback;
+	const unsigned long *front = (const unsigned long *) *bfront;
+	const int width = *width_bytes / sizeof(unsigned long);
+	int identical = width;
+	int start = width;
+	int end = width;
 
-	int rl;
-	uint16_t pix0;
-	char *end_if_raw = dst + 6 + 2 * rem;
-
-	dst += 6;		// header will be filled in if RLE is worth it
+	prefetch((void *) front);
+	prefetch((void *) back);
 
-	while (rem && dst < end_if_raw) {
-		char *start = (char *)src;
+	for (j = 0; j < width; j++) {
+		if (back[j] != front[j]) {
+			start = j;
+			break;
+		}
+	}
 
-		pix0 = *src++;
-		rl = 1;
-		rem--;
-		while (rem && *src == pix0)
-			rem--, rl++, src++;
-		*dst++ = rl;
-		*dst++ = start[1];
-		*dst++ = start[0];
+	for (k = width - 1; k > j; k--) {
+		if (back[k] != front[k]) {
+			end = k+1;
+			break;
+		}
 	}
 
-	return dst;
+	identical = start + (width - end);
+	*bfront = (u8 *) &front[start];
+	*width_bytes = (end - start) * sizeof(unsigned long);
+
+	return identical * sizeof(unsigned long);
 }
 
 /*
-Thanks to Henrik Bjerregaard Pedersen for rle implementation and code refactoring.
-Next step is huffman compression.
-*/
-
-static int
-image_blit(struct dlfb_data *dev_info, int x, int y, int width, int height,
-	   char *data)
-{
+Render a command stream for an encoded horizontal line segment of pixels.
 
-	int i, j, base;
-	int rem = width;
-	int ret;
+A command buffer holds several commands.
+It always begins with a fresh command header
+(the protocol doesn't require this, but we enforce it to allow
+multiple buffers to be potentially encoded and sent in parallel).
+A single command encodes one contiguous horizontal line of pixels
 
-	int firstdiff, thistime;
+The function relies on the client to do all allocation, so that
+rendering can be done directly to output buffers (e.g. USB URBs).
+The function fills the supplied command buffer, providing information
+on where it left off, so the client may call in again with additional
+buffers if the line will take several buffers to complete.
 
-	char *bufptr;
+A single command can transmit a maximum of 256 pixels,
+regardless of the compression ratio (protocol design limit).
+To the hardware, 0 for a size byte means 256
 
-	if (x + width > dev_info->info->var.xres)
-		return -EINVAL;
+Rather than 256 pixel commands which are either rl or raw encoded,
+the rlx command simply assumes alternating raw and rl spans within one cmd.
+This has a slightly larger header overhead, but produces more even results.
+It also processes all data (read and write) in a single pass.
+Performance benchmarks of common cases show it having just slightly better
+compression than 256 pixel raw -or- rle commands, with similar CPU consumpion.
+But for very rl friendly data, will compress not quite as well.
+*/
+static void dlfb_compress_hline(
+	const uint16_t **pixel_start_ptr,
+	const uint16_t *const pixel_end,
+	uint32_t *device_address_ptr,
+	uint8_t **command_buffer_ptr,
+	const uint8_t *const cmd_buffer_end)
+{
+	const uint16_t *pixel = *pixel_start_ptr;
+	uint32_t dev_addr  = *device_address_ptr;
+	uint8_t *cmd = *command_buffer_ptr;
+	const int bpp = 2;
 
-	if (y + height > dev_info->info->var.yres)
-		return -EINVAL;
+	while ((pixel_end > pixel) &&
+	       (cmd_buffer_end - MIN_RLX_CMD_BYTES > cmd)) {
+		uint8_t *raw_pixels_count_byte = 0;
+		uint8_t *cmd_pixels_count_byte = 0;
+		const uint16_t *raw_pixel_start = 0;
+		const uint16_t *cmd_pixel_start, *cmd_pixel_end = 0;
+		const uint32_t be_dev_addr = cpu_to_be32(dev_addr);
 
-	mutex_lock(&dev_info->bulk_mutex);
+		prefetchw((void *) cmd); /* pull in one cache line at least */
 
-	base =
-	    dev_info->base16 + ((dev_info->info->var.xres * 2 * y) + (x * 2));
+		*cmd++ = 0xAF;
+		*cmd++ = 0x6B;
+		*cmd++ = (uint8_t) ((be_dev_addr >> 8) & 0xFF);
+		*cmd++ = (uint8_t) ((be_dev_addr >> 16) & 0xFF);
+		*cmd++ = (uint8_t) ((be_dev_addr >> 24) & 0xFF);
 
-	data += (dev_info->info->var.xres * 2 * y) + (x * 2);
+		cmd_pixels_count_byte = cmd++; /*  we'll know this later */
+		cmd_pixel_start = pixel;
 
-	/* printk("IMAGE_BLIT\n"); */
+		raw_pixels_count_byte = cmd++; /*  we'll know this later */
+		raw_pixel_start = pixel;
 
-	bufptr = dev_info->buf;
+		cmd_pixel_end = pixel + min(MAX_CMD_PIXELS + 1,
+			min((int)(pixel_end - pixel),
+			    (int)(cmd_buffer_end - cmd) / bpp));
 
-	for (i = y; i < y + height; i++) {
+		prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp);
 
-		if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
-			ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
-			bufptr = dev_info->buf;
-		}
+		while (pixel < cmd_pixel_end) {
+			const uint16_t * const repeating_pixel = pixel;
 
-		rem = width;
+			*(uint16_t *)cmd = cpu_to_be16p(pixel);
+			cmd += 2;
+			pixel++;
 
-		/* printk("WRITING LINE %d\n", i); */
+			if (unlikely((pixel < cmd_pixel_end) &&
+				     (*pixel == *repeating_pixel))) {
+				/* go back and fill in raw pixel count */
+				*raw_pixels_count_byte = ((repeating_pixel -
+						raw_pixel_start) + 1) & 0xFF;
 
-		while (rem) {
+				while ((pixel < cmd_pixel_end)
+				       && (*pixel == *repeating_pixel)) {
+					pixel++;
+				}
 
-			if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
-				ret =
-				    dlfb_bulk_msg(dev_info,
-						  bufptr - dev_info->buf);
-				bufptr = dev_info->buf;
-			}
-			// number of pixels to consider this time
-			thistime = rem;
-			if (thistime > 255)
-				thistime = 255;
+				/* immediately after raw data is repeat byte */
+				*cmd++ = ((pixel - repeating_pixel) - 1) & 0xFF;
 
-			// find position of first pixel that has changed
-			firstdiff = -1;
-			for (j = 0; j < thistime * 2; j++) {
-				if (dev_info->backing_buffer
-				    [base - dev_info->base16 + j] != data[j]) {
-					firstdiff = j / 2;
-					break;
-				}
+				/* Then start another raw pixel span */
+				raw_pixel_start = pixel;
+				raw_pixels_count_byte = cmd++;
 			}
+		}
 
-			if (firstdiff >= 0) {
-				char *end_of_rle;
+		if (pixel > raw_pixel_start) {
+			/* finalize last RAW span */
+			*raw_pixels_count_byte = (pixel-raw_pixel_start) & 0xFF;
+		}
 
-				end_of_rle =
-				    rle_compress16((uint16_t *) (data +
-								 firstdiff * 2),
-						   bufptr,
-						   thistime - firstdiff);
+		*cmd_pixels_count_byte = (pixel - cmd_pixel_start) & 0xFF;
+		dev_addr += (pixel - cmd_pixel_start) * bpp;
+	}
 
-				if (end_of_rle <
-				    bufptr + 6 + 2 * (thistime - firstdiff)) {
-					bufptr[0] = 0xAF;
-					bufptr[1] = 0x69;
+	if (cmd_buffer_end <= MIN_RLX_CMD_BYTES + cmd) {
+		/* Fill leftover bytes with no-ops */
+		if (cmd_buffer_end > cmd)
+			memset(cmd, 0xAF, cmd_buffer_end - cmd);
+		cmd = (uint8_t *) cmd_buffer_end;
+	}
 
-					bufptr[2] =
-					    (char)((base +
-						    firstdiff * 2) >> 16);
-					bufptr[3] =
-					    (char)((base + firstdiff * 2) >> 8);
-					bufptr[4] =
-					    (char)(base + firstdiff * 2);
-					bufptr[5] = thistime - firstdiff;
+	*command_buffer_ptr = cmd;
+	*pixel_start_ptr = pixel;
+	*device_address_ptr = dev_addr;
 
-					bufptr = end_of_rle;
+	return;
+}
 
-				} else {
-					// fallback to raw (or some other encoding?)
-					*bufptr++ = 0xAF;
-					*bufptr++ = 0x68;
+/*
+ * There are 3 copies of every pixel: The front buffer that the fbdev
+ * client renders to, the actual framebuffer across the USB bus in hardware
+ * (that we can only write to, slowly, and can never read), and (optionally)
+ * our shadow copy that tracks what's been sent to that hardware buffer.
+ */
+static void dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
+			      const char *front, char **urb_buf_ptr,
+			      u32 byte_offset, u32 byte_width,
+			      int *ident_ptr, int *sent_ptr)
+{
+	const u8 *line_start, *line_end, *next_pixel;
+	u32 dev_addr = dev->base16 + byte_offset;
+	struct urb *urb = *urb_ptr;
+	u8 *cmd = *urb_buf_ptr;
+	u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length;
 
-					*bufptr++ =
-					    (char)((base +
-						    firstdiff * 2) >> 16);
-					*bufptr++ =
-					    (char)((base + firstdiff * 2) >> 8);
-					*bufptr++ =
-					    (char)(base + firstdiff * 2);
-					*bufptr++ = thistime - firstdiff;
-					// PUT COMPRESSION HERE
-					for (j = firstdiff * 2;
-					     j < thistime * 2; j += 2) {
-						*bufptr++ = data[j + 1];
-						*bufptr++ = data[j];
-					}
-				}
-			}
+	line_start = (u8 *) (front + byte_offset);
+	next_pixel = line_start;
+	line_end = next_pixel + byte_width;
 
-			base += thistime * 2;
-			data += thistime * 2;
-			rem -= thistime;
-		}
+	if (dev->backing_buffer) {
+		int offset;
+		const u8 *back_start = (u8 *) (dev->backing_buffer
+						+ byte_offset);
 
-		memcpy(dev_info->backing_buffer + (base - dev_info->base16) -
-		       (width * 2), data - (width * 2), width * 2);
+		*ident_ptr += dlfb_trim_hline(back_start, &next_pixel,
+			&byte_width);
 
-		base += (dev_info->info->var.xres * 2) - (width * 2);
-		data += (dev_info->info->var.xres * 2) - (width * 2);
+		offset = next_pixel - line_start;
+		line_end = next_pixel + byte_width;
+		dev_addr += offset;
+		back_start += offset;
+		line_start += offset;
 
+		memcpy((char *)back_start, (char *) line_start,
+		       byte_width);
 	}
 
-	if (bufptr > dev_info->buf) {
-		ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
-	}
+	while (next_pixel < line_end) {
 
-	mutex_unlock(&dev_info->bulk_mutex);
+		dlfb_compress_hline((const uint16_t **) &next_pixel,
+			     (const uint16_t *) line_end, &dev_addr,
+			(u8 **) &cmd, (u8 *) cmd_end);
 
-	return base;
+		if (cmd >= cmd_end) {
+			int len = cmd - (u8 *) urb->transfer_buffer;
+			if (dlfb_submit_urb(dev, urb, len))
+				return; /* lost pixels is set */
+			*sent_ptr += len;
+			urb = dlfb_get_urb(dev);
+			if (!urb)
+				return; /* lost_pixels is set */
+			*urb_ptr = urb;
+			cmd = urb->transfer_buffer;
+			cmd_end = &cmd[urb->transfer_buffer_length];
+		}
+	}
 
+	*urb_buf_ptr = cmd;
 }
 
-static int
-draw_rect(struct dlfb_data *dev_info, int x, int y, int width, int height,
-	  unsigned char red, unsigned char green, unsigned char blue)
+int dlfb_handle_damage(struct dlfb_data *dev, int x, int y,
+	       int width, int height, char *data)
 {
+	int i, ret;
+	char *cmd;
+	cycles_t start_cycles, end_cycles;
+	int bytes_sent = 0;
+	int bytes_identical = 0;
+	struct urb *urb;
+	int aligned_x;
 
-	int i, j, base;
-	int ret;
-	unsigned short col =
-	    (((((red) & 0xF8) | ((green) >> 5)) & 0xFF) << 8) +
-	    (((((green) & 0x1C) << 3) | ((blue) >> 3)) & 0xFF);
-	int rem = width;
+	start_cycles = get_cycles();
 
-	char *bufptr;
+	aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long));
+	width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long));
+	x = aligned_x;
 
-	if (x + width > dev_info->info->var.xres)
+	if ((width <= 0) ||
+	    (x + width > dev->info->var.xres) ||
+	    (y + height > dev->info->var.yres))
 		return -EINVAL;
 
-	if (y + height > dev_info->info->var.yres)
-		return -EINVAL;
+	if (!atomic_read(&dev->usb_active))
+		return 0;
 
-	mutex_lock(&dev_info->bulk_mutex);
+	urb = dlfb_get_urb(dev);
+	if (!urb)
+		return 0;
+	cmd = urb->transfer_buffer;
 
-	base = dev_info->base16 + (dev_info->info->var.xres * 2 * y) + (x * 2);
+	for (i = y; i < y + height ; i++) {
+		const int line_offset = dev->info->fix.line_length * i;
+		const int byte_offset = line_offset + (x * BPP);
 
-	bufptr = dev_info->buf;
+		dlfb_render_hline(dev, &urb, (char *) dev->info->fix.smem_start,
+				  &cmd, byte_offset, width * BPP,
+				  &bytes_identical, &bytes_sent);
+	}
 
-	for (i = y; i < y + height; i++) {
+	if (cmd > (char *) urb->transfer_buffer) {
+		/* Send partial buffer remaining before exiting */
+		int len = cmd - (char *) urb->transfer_buffer;
+		ret = dlfb_submit_urb(dev, urb, len);
+		bytes_sent += len;
+	} else
+		dlfb_urb_completion(urb);
 
-		for (j = 0; j < width * 2; j += 2) {
-			dev_info->backing_buffer[base - dev_info->base16 + j] =
-			    (char)(col >> 8);
-			dev_info->backing_buffer[base - dev_info->base16 + j +
-						 1] = (char)(col);
-		}
-		if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
-			ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
-			bufptr = dev_info->buf;
-		}
+	atomic_add(bytes_sent, &dev->bytes_sent);
+	atomic_add(bytes_identical, &dev->bytes_identical);
+	atomic_add(width*height*2, &dev->bytes_rendered);
+	end_cycles = get_cycles();
+	atomic_add(((unsigned int) ((end_cycles - start_cycles)
+		    >> 10)), /* Kcycles */
+		   &dev->cpu_kcycles_used);
 
-		rem = width;
+	return 0;
+}
 
-		while (rem) {
+/* hardware has native COPY command (see libdlo), but not worth it for fbcon */
+static void dlfb_ops_copyarea(struct fb_info *info,
+				const struct fb_copyarea *area)
+{
 
-			if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
-				ret =
-				    dlfb_bulk_msg(dev_info,
-						  bufptr - dev_info->buf);
-				bufptr = dev_info->buf;
-			}
+	struct dlfb_data *dev = info->par;
 
-			*bufptr++ = 0xAF;
-			*bufptr++ = 0x69;
+#if defined CONFIG_FB_SYS_COPYAREA || defined CONFIG_FB_SYS_COPYAREA_MODULE
 
-			*bufptr++ = (char)(base >> 16);
-			*bufptr++ = (char)(base >> 8);
-			*bufptr++ = (char)(base);
+	sys_copyarea(info, area);
 
-			if (rem > 255) {
-				*bufptr++ = 255;
-				*bufptr++ = 255;
-				rem -= 255;
-				base += 255 * 2;
-			} else {
-				*bufptr++ = rem;
-				*bufptr++ = rem;
-				base += rem * 2;
-				rem = 0;
-			}
+	dlfb_handle_damage(dev, area->dx, area->dy,
+			area->width, area->height, info->screen_base);
+#endif
+	atomic_inc(&dev->copy_count);
 
-			*bufptr++ = (char)(col >> 8);
-			*bufptr++ = (char)(col);
+}
 
-		}
+static void dlfb_ops_imageblit(struct fb_info *info,
+				const struct fb_image *image)
+{
+	struct dlfb_data *dev = info->par;
 
-		base += (dev_info->info->var.xres * 2) - (width * 2);
+#if defined CONFIG_FB_SYS_IMAGEBLIT || defined CONFIG_FB_SYS_IMAGEBLIT_MODULE
 
-	}
+	sys_imageblit(info, image);
 
-	if (bufptr > dev_info->buf)
-		ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
+	dlfb_handle_damage(dev, image->dx, image->dy,
+			image->width, image->height, info->screen_base);
 
-	mutex_unlock(&dev_info->bulk_mutex);
+#endif
 
-	return 1;
+	atomic_inc(&dev->blit_count);
 }
 
-static void swapfb(struct dlfb_data *dev_info)
+static void dlfb_ops_fillrect(struct fb_info *info,
+			  const struct fb_fillrect *rect)
 {
+	struct dlfb_data *dev = info->par;
 
-	int tmpbase;
-	char *bufptr;
-
-	mutex_lock(&dev_info->bulk_mutex);
-
-	tmpbase = dev_info->base16;
-
-	dev_info->base16 = dev_info->base16d;
-	dev_info->base16d = tmpbase;
-
-	bufptr = dev_info->buf;
-
-	bufptr = dlfb_set_register(bufptr, 0xFF, 0x00);
+#if defined CONFIG_FB_SYS_FILLRECT || defined CONFIG_FB_SYS_FILLRECT_MODULE
 
-	// set addresses
-	bufptr =
-	    dlfb_set_register(bufptr, 0x20, (char)(dev_info->base16 >> 16));
-	bufptr = dlfb_set_register(bufptr, 0x21, (char)(dev_info->base16 >> 8));
-	bufptr = dlfb_set_register(bufptr, 0x22, (char)(dev_info->base16));
+	sys_fillrect(info, rect);
 
-	bufptr = dlfb_set_register(bufptr, 0xFF, 0x00);
+	dlfb_handle_damage(dev, rect->dx, rect->dy, rect->width,
+			      rect->height, info->screen_base);
+#endif
 
-	dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
+	atomic_inc(&dev->fill_count);
 
-	mutex_unlock(&dev_info->bulk_mutex);
 }
 
-static int copyfb(struct dlfb_data *dev_info)
+static void dlfb_get_edid(struct dlfb_data *dev)
 {
-	int base;
-	int source;
-	int rem;
-	int i, ret;
+	int i;
+	int ret;
+	char rbuf[2];
 
-	char *bufptr;
+	for (i = 0; i < sizeof(dev->edid); i++) {
+		ret = usb_control_msg(dev->udev,
+				    usb_rcvctrlpipe(dev->udev, 0), (0x02),
+				    (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2,
+				    0);
+		dev->edid[i] = rbuf[1];
+	}
+}
 
-	base = dev_info->base16d;
+static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd,
+				unsigned long arg)
+{
 
-	mutex_lock(&dev_info->bulk_mutex);
+	struct dlfb_data *dev = info->par;
+	struct dloarea *area = NULL;
 
-	source = dev_info->base16;
+	if (!atomic_read(&dev->usb_active))
+		return 0;
 
-	bufptr = dev_info->buf;
+	/* TODO: Update X server to get this from sysfs instead */
+	if (cmd == DLFB_IOCTL_RETURN_EDID) {
+		char *edid = (char *)arg;
+		dlfb_get_edid(dev);
+		if (copy_to_user(edid, dev->edid, sizeof(dev->edid)))
+			return -EFAULT;
+		return 0;
+	}
 
-	for (i = 0; i < dev_info->info->var.yres; i++) {
+	/* TODO: Help propose a standard fb.h ioctl to report mmap damage */
+	if (cmd == DLFB_IOCTL_REPORT_DAMAGE) {
 
-		if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
-			ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
-			bufptr = dev_info->buf;
-		}
+		area = (struct dloarea *)arg;
 
-		rem = dev_info->info->var.xres;
+		if (area->x < 0)
+			area->x = 0;
 
-		while (rem) {
+		if (area->x > info->var.xres)
+			area->x = info->var.xres;
 
-			if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
-				ret =
-				    dlfb_bulk_msg(dev_info,
-						  bufptr - dev_info->buf);
-				bufptr = dev_info->buf;
+		if (area->y < 0)
+			area->y = 0;
 
-			}
+		if (area->y > info->var.yres)
+			area->y = info->var.yres;
 
-			*bufptr++ = 0xAF;
-			*bufptr++ = 0x6A;
+		atomic_set(&dev->use_defio, 0);
 
-			*bufptr++ = (char)(base >> 16);
-			*bufptr++ = (char)(base >> 8);
-			*bufptr++ = (char)(base);
+		dlfb_handle_damage(dev, area->x, area->y, area->w, area->h,
+			   info->screen_base);
+		atomic_inc(&dev->damage_count);
+	}
 
-			if (rem > 255) {
-				*bufptr++ = 255;
-				*bufptr++ = (char)(source >> 16);
-				*bufptr++ = (char)(source >> 8);
-				*bufptr++ = (char)(source);
+	return 0;
+}
 
-				rem -= 255;
-				base += 255 * 2;
-				source += 255 * 2;
+/* taken from vesafb */
+static int
+dlfb_ops_setcolreg(unsigned regno, unsigned red, unsigned green,
+	       unsigned blue, unsigned transp, struct fb_info *info)
+{
+	int err = 0;
 
-			} else {
-				*bufptr++ = rem;
-				*bufptr++ = (char)(source >> 16);
-				*bufptr++ = (char)(source >> 8);
-				*bufptr++ = (char)(source);
+	if (regno >= info->cmap.len)
+		return 1;
 
-				base += rem * 2;
-				source += rem * 2;
-				rem = 0;
-			}
+	if (regno < 16) {
+		if (info->var.red.offset == 10) {
+			/* 1:5:5:5 */
+			((u32 *) (info->pseudo_palette))[regno] =
+			    ((red & 0xf800) >> 1) |
+			    ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11);
+		} else {
+			/* 0:5:6:5 */
+			((u32 *) (info->pseudo_palette))[regno] =
+			    ((red & 0xf800)) |
+			    ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
 		}
 	}
 
-	if (bufptr > dev_info->buf)
-		ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
+	return err;
+}
 
-	mutex_unlock(&dev_info->bulk_mutex);
+/*
+ * It's common for several clients to have framebuffer open simultaneously.
+ * e.g. both fbcon and X. Makes things interesting.
+ */
+static int dlfb_ops_open(struct fb_info *info, int user)
+{
+	struct dlfb_data *dev = info->par;
 
-	return 1;
+/*	if (user == 0)
+ *		We could special case kernel mode clients (fbcon) here
+ */
 
-}
+	mutex_lock(&dev->fb_open_lock);
 
-static int
-copyarea(struct dlfb_data *dev_info, int dx, int dy, int sx, int sy,
-	 int width, int height)
-{
-	int base;
-	int source;
-	int rem;
-	int i, ret;
+	dev->fb_count++;
 
-	char *bufptr;
+#ifdef CONFIG_FB_DEFERRED_IO
+	if ((atomic_read(&dev->use_defio)) && (info->fbdefio == NULL)) {
+		/* enable defio */
+		info->fbdefio = &dlfb_defio;
+		fb_deferred_io_init(info);
+	}
+#endif
 
-	if (dx + width > dev_info->info->var.xres)
-		return -EINVAL;
+	dl_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n",
+	    info->node, user, info, dev->fb_count);
 
-	if (dy + height > dev_info->info->var.yres)
-		return -EINVAL;
+	mutex_unlock(&dev->fb_open_lock);
 
-	mutex_lock(&dev_info->bulk_mutex);
+	return 0;
+}
 
-	base =
-	    dev_info->base16 + (dev_info->info->var.xres * 2 * dy) + (dx * 2);
-	source = (dev_info->info->var.xres * 2 * sy) + (sx * 2);
+static int dlfb_ops_release(struct fb_info *info, int user)
+{
+	struct dlfb_data *dev = info->par;
 
-	bufptr = dev_info->buf;
+	mutex_lock(&dev->fb_open_lock);
 
-	for (i = sy; i < sy + height; i++) {
+	dev->fb_count--;
 
-		memcpy(dev_info->backing_buffer + base - dev_info->base16,
-		       dev_info->backing_buffer + source, width * 2);
+#ifdef CONFIG_FB_DEFERRED_IO
+	if ((dev->fb_count == 0) && (info->fbdefio)) {
+		fb_deferred_io_cleanup(info);
+		info->fbdefio = NULL;
+		info->fbops->fb_mmap = dlfb_ops_mmap;
+	}
+#endif
 
-		if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
-			ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
-			bufptr = dev_info->buf;
-		}
+	dl_notice("release /dev/fb%d user=%d count=%d\n",
+		  info->node, user, dev->fb_count);
 
-		rem = width;
+	mutex_unlock(&dev->fb_open_lock);
 
-		while (rem) {
+	return 0;
+}
 
-			if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
-				ret =
-				    dlfb_bulk_msg(dev_info,
-						  bufptr - dev_info->buf);
-				bufptr = dev_info->buf;
-			}
+/*
+ * Called when all client interfaces to start transactions have been disabled,
+ * and all references to our device instance (dlfb_data) are released.
+ * Every transaction must have a reference, so we know are fully spun down
+ */
+static void dlfb_delete(struct kref *kref)
+{
+	struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref);
 
-			*bufptr++ = 0xAF;
-			*bufptr++ = 0x6A;
+	if (dev->backing_buffer)
+		vfree(dev->backing_buffer);
 
-			*bufptr++ = (char)(base >> 16);
-			*bufptr++ = (char)(base >> 8);
-			*bufptr++ = (char)(base);
+	mutex_destroy(&dev->fb_open_lock);
 
-			if (rem > 255) {
-				*bufptr++ = 255;
-				*bufptr++ = (char)(source >> 16);
-				*bufptr++ = (char)(source >> 8);
-				*bufptr++ = (char)(source);
+	kfree(dev);
+}
 
-				rem -= 255;
-				base += 255 * 2;
-				source += 255 * 2;
+/*
+ * Called by fbdev as last part of unregister_framebuffer() process
+ * No new clients can open connections. Deallocate everything fb_info.
+ */
+static void dlfb_ops_destroy(struct fb_info *info)
+{
+	struct dlfb_data *dev = info->par;
 
-			} else {
-				*bufptr++ = rem;
-				*bufptr++ = (char)(source >> 16);
-				*bufptr++ = (char)(source >> 8);
-				*bufptr++ = (char)(source);
+	if (info->cmap.len != 0)
+		fb_dealloc_cmap(&info->cmap);
+	if (info->monspecs.modedb)
+		fb_destroy_modedb(info->monspecs.modedb);
+	if (info->screen_base)
+		vfree(info->screen_base);
 
-				base += rem * 2;
-				source += rem * 2;
-				rem = 0;
-			}
-		}
+	fb_destroy_modelist(&info->modelist);
 
-		base += (dev_info->info->var.xres * 2) - (width * 2);
-		source += (dev_info->info->var.xres * 2) - (width * 2);
-	}
+	framebuffer_release(info);
 
-	if (bufptr > dev_info->buf)
-		ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
+	/* ref taken before register_framebuffer() for dlfb_data clients */
+	kref_put(&dev->kref, dlfb_delete);
+}
 
-	mutex_unlock(&dev_info->bulk_mutex);
+/*
+ * Check whether a video mode is supported by the DisplayLink chip
+ * We start from monitor's modes, so don't need to filter that here
+ */
+static int dlfb_is_valid_mode(struct fb_videomode *mode,
+		struct fb_info *info)
+{
+	struct dlfb_data *dev = info->par;
+
+	if (mode->xres * mode->yres > dev->sku_pixel_limit)
+		return 0;
 
 	return 1;
 }
 
-static void dlfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+static void dlfb_var_color_format(struct fb_var_screeninfo *var)
 {
+	const struct fb_bitfield red = { 11, 5, 0 };
+	const struct fb_bitfield green = { 5, 6, 0 };
+	const struct fb_bitfield blue = { 0, 5, 0 };
 
-	struct dlfb_data *dev = info->par;
+	var->bits_per_pixel = 16;
+	var->red = red;
+	var->green = green;
+	var->blue = blue;
+}
 
-	copyarea(dev, area->dx, area->dy, area->sx, area->sy, area->width,
-		 area->height);
+static int dlfb_ops_check_var(struct fb_var_screeninfo *var,
+				struct fb_info *info)
+{
+	struct fb_videomode mode;
 
-	/* printk("COPY AREA %d %d %d %d %d %d !!!\n", area->dx, area->dy, area->sx, area->sy, area->width, area->height); */
+	/* TODO: support dynamically changing framebuffer size */
+	if ((var->xres * var->yres * 2) > info->fix.smem_len)
+		return -EINVAL;
+
+	/* set device-specific elements of var unrelated to mode */
+	dlfb_var_color_format(var);
+
+	fb_var_to_videomode(&mode, var);
 
+	if (!dlfb_is_valid_mode(&mode, info))
+		return -EINVAL;
+
+	return 0;
 }
 
-static void dlfb_imageblit(struct fb_info *info, const struct fb_image *image)
+static int dlfb_ops_set_par(struct fb_info *info)
 {
-
-	int ret;
 	struct dlfb_data *dev = info->par;
-	/* printk("IMAGE BLIT (1) %d %d %d %d DEPTH %d {%p}!!!\n", image->dx, image->dy, image->width, image->height, image->depth, dev->udev); */
-	cfb_imageblit(info, image);
-	ret =
-	    image_blit(dev, image->dx, image->dy, image->width, image->height,
-		       info->screen_base);
-	/* printk("IMAGE BLIT (2) %d %d %d %d DEPTH %d {%p} %d!!!\n", image->dx, image->dy, image->width, image->height, image->depth, dev->udev, ret); */
+
+	dl_notice("set_par mode %dx%d\n", info->var.xres, info->var.yres);
+
+	return dlfb_set_video_mode(dev, &info->var);
 }
 
-static void dlfb_fillrect(struct fb_info *info,
-			  const struct fb_fillrect *region)
+static int dlfb_ops_blank(int blank_mode, struct fb_info *info)
 {
-
-	unsigned char red, green, blue;
 	struct dlfb_data *dev = info->par;
+	char *bufptr;
+	struct urb *urb;
 
-	memcpy(&red, &region->color, 1);
-	memcpy(&green, &region->color + 1, 1);
-	memcpy(&blue, &region->color + 2, 1);
-	draw_rect(dev, region->dx, region->dy, region->width, region->height,
-		  red, green, blue);
-	/* printk("FILL RECT %d %d !!!\n", region->dx, region->dy); */
+	urb = dlfb_get_urb(dev);
+	if (!urb)
+		return 0;
+	bufptr = (char *) urb->transfer_buffer;
 
+	/* overloading usb_active.  UNBLANK can conflict with teardown */
+
+	bufptr = dlfb_vidreg_lock(bufptr);
+	if (blank_mode != FB_BLANK_UNBLANK) {
+		atomic_set(&dev->usb_active, 0);
+		bufptr = dlfb_enable_hvsync(bufptr, false);
+	} else {
+		atomic_set(&dev->usb_active, 1);
+		bufptr = dlfb_enable_hvsync(bufptr, true);
+	}
+	bufptr = dlfb_vidreg_unlock(bufptr);
+
+	dlfb_submit_urb(dev, urb, bufptr - (char *) urb->transfer_buffer);
+
+	return 0;
 }
 
-static int dlfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+static struct fb_ops dlfb_ops = {
+	.owner = THIS_MODULE,
+	.fb_setcolreg = dlfb_ops_setcolreg,
+	.fb_fillrect = dlfb_ops_fillrect,
+	.fb_copyarea = dlfb_ops_copyarea,
+	.fb_imageblit = dlfb_ops_imageblit,
+	.fb_mmap = dlfb_ops_mmap,
+	.fb_ioctl = dlfb_ops_ioctl,
+	.fb_open = dlfb_ops_open,
+	.fb_release = dlfb_ops_release,
+	.fb_blank = dlfb_ops_blank,
+	.fb_check_var = dlfb_ops_check_var,
+	.fb_set_par = dlfb_ops_set_par,
+};
+
+/*
+ * Calls dlfb_get_edid() to query the EDID of attached monitor via usb cmds
+ * Then parses EDID into three places used by various parts of fbdev:
+ * fb_var_screeninfo contains the timing of the monitor's preferred mode
+ * fb_info.monspecs is full parsed EDID info, including monspecs.modedb
+ * fb_info.modelist is a linked list of all monitor & VESA modes which work
+ *
+ * If EDID is not readable/valid, then modelist is all VESA modes,
+ * monspecs is NULL, and fb_var_screeninfo is set to safe VESA mode
+ * Returns 0 if EDID parses successfully
+ */
+static int dlfb_parse_edid(struct dlfb_data *dev,
+			    struct fb_var_screeninfo *var,
+			    struct fb_info *info)
 {
+	int i;
+	const struct fb_videomode *default_vmode = NULL;
+	int result = 0;
 
-	struct dlfb_data *dev_info = info->par;
-	struct dloarea *area = NULL;
+	fb_destroy_modelist(&info->modelist);
+	memset(&info->monspecs, 0, sizeof(info->monspecs));
 
-	if (cmd == 0xAD) {
-		char *edid = (char *)arg;
-		dlfb_edid(dev_info);
-		if (copy_to_user(edid, dev_info->edid, 128)) {
-			return -EFAULT;
+	dlfb_get_edid(dev);
+	fb_edid_to_monspecs(dev->edid, &info->monspecs);
+
+	if (info->monspecs.modedb_len > 0) {
+
+		for (i = 0; i < info->monspecs.modedb_len; i++) {
+			if (dlfb_is_valid_mode(&info->monspecs.modedb[i], info))
+				fb_add_videomode(&info->monspecs.modedb[i],
+					&info->modelist);
 		}
-		return 0;
+
+		default_vmode = fb_find_best_display(&info->monspecs,
+						     &info->modelist);
+	} else {
+		struct fb_videomode fb_vmode = {0};
+
+		dl_err("Unable to get valid EDID from device/display\n");
+		result = 1;
+
+		/*
+		 * Add the standard VESA modes to our modelist
+		 * Since we don't have EDID, there may be modes that
+		 * overspec monitor and/or are incorrect aspect ratio, etc.
+		 * But at least the user has a chance to choose
+		 */
+		for (i = 0; i < VESA_MODEDB_SIZE; i++) {
+			if (dlfb_is_valid_mode((struct fb_videomode *)
+						&vesa_modes[i], info))
+				fb_add_videomode(&vesa_modes[i],
+						 &info->modelist);
+		}
+
+		/*
+		 * default to resolution safe for projectors
+		 * (since they are most common case without EDID)
+		 */
+		fb_vmode.xres = 800;
+		fb_vmode.yres = 600;
+		fb_vmode.refresh = 60;
+		default_vmode = fb_find_nearest_mode(&fb_vmode,
+						     &info->modelist);
 	}
 
-	if (cmd == 0xAA || cmd == 0xAB || cmd == 0xAC) {
+	fb_videomode_to_var(var, default_vmode);
+	dlfb_var_color_format(var);
 
-		area = (struct dloarea *)arg;
+	return result;
+}
 
-		if (area->x < 0)
-			area->x = 0;
+static ssize_t metrics_bytes_rendered_show(struct device *fbdev,
+				   struct device_attribute *a, char *buf) {
+	struct fb_info *fb_info = dev_get_drvdata(fbdev);
+	struct dlfb_data *dev = fb_info->par;
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			atomic_read(&dev->bytes_rendered));
+}
 
-		if (area->x > info->var.xres)
-			area->x = info->var.xres;
+static ssize_t metrics_bytes_identical_show(struct device *fbdev,
+				   struct device_attribute *a, char *buf) {
+	struct fb_info *fb_info = dev_get_drvdata(fbdev);
+	struct dlfb_data *dev = fb_info->par;
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			atomic_read(&dev->bytes_identical));
+}
 
-		if (area->y < 0)
-			area->y = 0;
+static ssize_t metrics_bytes_sent_show(struct device *fbdev,
+				   struct device_attribute *a, char *buf) {
+	struct fb_info *fb_info = dev_get_drvdata(fbdev);
+	struct dlfb_data *dev = fb_info->par;
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			atomic_read(&dev->bytes_sent));
+}
 
-		if (area->y > info->var.yres)
-			area->y = info->var.yres;
-	}
+static ssize_t metrics_cpu_kcycles_used_show(struct device *fbdev,
+				   struct device_attribute *a, char *buf) {
+	struct fb_info *fb_info = dev_get_drvdata(fbdev);
+	struct dlfb_data *dev = fb_info->par;
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			atomic_read(&dev->cpu_kcycles_used));
+}
 
-	if (cmd == 0xAA) {
-		image_blit(dev_info, area->x, area->y, area->w, area->h,
-			   info->screen_base);
-	}
-	if (cmd == 0xAC) {
-		copyfb(dev_info);
-		image_blit(dev_info, area->x, area->y, area->w, area->h,
-			   info->screen_base);
-		swapfb(dev_info);
-	} else if (cmd == 0xAB) {
+static ssize_t metrics_misc_show(struct device *fbdev,
+				   struct device_attribute *a, char *buf) {
+	struct fb_info *fb_info = dev_get_drvdata(fbdev);
+	struct dlfb_data *dev = fb_info->par;
+	return snprintf(buf, PAGE_SIZE,
+			"Calls to\ndamage: %u\nblit: %u\n"
+			"defio faults: %u\ncopy: %u\n"
+			"fill: %u\n\n"
+			"active framebuffer clients: %d\n"
+			"urbs available %d(%d)\n"
+			"Shadow framebuffer in use? %s\n"
+			"Any lost pixels? %s\n",
+			atomic_read(&dev->damage_count),
+			atomic_read(&dev->blit_count),
+			atomic_read(&dev->defio_fault_count),
+			atomic_read(&dev->copy_count),
+			atomic_read(&dev->fill_count),
+			dev->fb_count,
+			dev->urbs.available, dev->urbs.limit_sem.count,
+			(dev->backing_buffer) ? "yes" : "no",
+			atomic_read(&dev->lost_pixels) ? "yes" : "no");
+}
 
-		if (area->x2 < 0)
-			area->x2 = 0;
+static ssize_t edid_show(struct kobject *kobj, struct bin_attribute *a,
+			 char *buf, loff_t off, size_t count) {
+	struct device *fbdev = container_of(kobj, struct device, kobj);
+	struct fb_info *fb_info = dev_get_drvdata(fbdev);
+	struct dlfb_data *dev = fb_info->par;
+	char *edid = &dev->edid[0];
+	const size_t size = sizeof(dev->edid);
 
-		if (area->y2 < 0)
-			area->y2 = 0;
+	if (dlfb_parse_edid(dev, &fb_info->var, fb_info))
+		return 0;
 
-		copyarea(dev_info,
-			 area->x2, area->y2, area->x, area->y, area->w,
-			 area->h);
-	}
-	return 0;
+	if (off >= size)
+		return 0;
+
+	if (off + count > size)
+		count = size - off;
+	memcpy(buf, edid + off, count);
+
+	return count;
 }
 
-/* taken from vesafb */
 
-static int
-dlfb_setcolreg(unsigned regno, unsigned red, unsigned green,
-	       unsigned blue, unsigned transp, struct fb_info *info)
+static ssize_t metrics_reset_store(struct device *fbdev,
+			   struct device_attribute *attr,
+			   const char *buf, size_t count)
 {
-	int err = 0;
+	struct fb_info *fb_info = dev_get_drvdata(fbdev);
+	struct dlfb_data *dev = fb_info->par;
 
-	if (regno >= info->cmap.len)
-		return 1;
+	atomic_set(&dev->bytes_rendered, 0);
+	atomic_set(&dev->bytes_identical, 0);
+	atomic_set(&dev->bytes_sent, 0);
+	atomic_set(&dev->cpu_kcycles_used, 0);
+	atomic_set(&dev->blit_count, 0);
+	atomic_set(&dev->copy_count, 0);
+	atomic_set(&dev->fill_count, 0);
+	atomic_set(&dev->defio_fault_count, 0);
+	atomic_set(&dev->damage_count, 0);
 
-	if (regno < 16) {
-		if (info->var.red.offset == 10) {
-			/* 1:5:5:5 */
-			((u32 *) (info->pseudo_palette))[regno] =
-			    ((red & 0xf800) >> 1) |
-			    ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11);
-		} else {
-			/* 0:5:6:5 */
-			((u32 *) (info->pseudo_palette))[regno] =
-			    ((red & 0xf800)) |
-			    ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
-		}
-	}
+	return count;
+}
 
-	return err;
+static ssize_t use_defio_show(struct device *fbdev,
+				   struct device_attribute *a, char *buf) {
+	struct fb_info *fb_info = dev_get_drvdata(fbdev);
+	struct dlfb_data *dev = fb_info->par;
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+			atomic_read(&dev->use_defio));
 }
 
-static int dlfb_release(struct fb_info *info, int user)
+static ssize_t use_defio_store(struct device *fbdev,
+			   struct device_attribute *attr,
+			   const char *buf, size_t count)
 {
-	struct dlfb_data *dev_info = info->par;
-	image_blit(dev_info, 0, 0, info->var.xres, info->var.yres,
-		   info->screen_base);
-	return 0;
+	struct fb_info *fb_info = dev_get_drvdata(fbdev);
+	struct dlfb_data *dev = fb_info->par;
+
+	if (count > 0) {
+		if (buf[0] == '0')
+			atomic_set(&dev->use_defio, 0);
+		if (buf[0] == '1')
+			atomic_set(&dev->use_defio, 1);
+	}
+	return count;
 }
 
-static int dlfb_blank(int blank_mode, struct fb_info *info)
+static struct bin_attribute edid_attr = {
+	.attr.name = "edid",
+	.attr.mode = 0444,
+	.size = 128,
+	.read = edid_show,
+};
+
+static struct device_attribute fb_device_attrs[] = {
+	__ATTR_RO(metrics_bytes_rendered),
+	__ATTR_RO(metrics_bytes_identical),
+	__ATTR_RO(metrics_bytes_sent),
+	__ATTR_RO(metrics_cpu_kcycles_used),
+	__ATTR_RO(metrics_misc),
+	__ATTR(metrics_reset, S_IWUGO, NULL, metrics_reset_store),
+	__ATTR_RW(use_defio),
+};
+
+#ifdef CONFIG_FB_DEFERRED_IO
+static void dlfb_dpy_deferred_io(struct fb_info *info,
+				struct list_head *pagelist)
 {
-	struct dlfb_data *dev_info = info->par;
-	char *bufptr = dev_info->buf;
+	struct page *cur;
+	struct fb_deferred_io *fbdefio = info->fbdefio;
+	struct dlfb_data *dev = info->par;
+	struct urb *urb;
+	char *cmd;
+	cycles_t start_cycles, end_cycles;
+	int bytes_sent = 0;
+	int bytes_identical = 0;
+	int bytes_rendered = 0;
+	int fault_count = 0;
 
-	bufptr = dlfb_set_register(bufptr, 0xFF, 0x00);
-	if (blank_mode != FB_BLANK_UNBLANK) {
-		bufptr = dlfb_set_register(bufptr, 0x1F, 0x01);
-	} else {
-		bufptr = dlfb_set_register(bufptr, 0x1F, 0x00);
+	if (!atomic_read(&dev->use_defio))
+		return;
+
+	if (!atomic_read(&dev->usb_active))
+		return;
+
+	start_cycles = get_cycles();
+
+	urb = dlfb_get_urb(dev);
+	if (!urb)
+		return;
+	cmd = urb->transfer_buffer;
+
+	/* walk the written page list and render each to device */
+	list_for_each_entry(cur, &fbdefio->pagelist, lru) {
+		dlfb_render_hline(dev, &urb, (char *) info->fix.smem_start,
+				  &cmd, cur->index << PAGE_SHIFT,
+				  PAGE_SIZE, &bytes_identical, &bytes_sent);
+		bytes_rendered += PAGE_SIZE;
+		fault_count++;
 	}
-	bufptr = dlfb_set_register(bufptr, 0xFF, 0xFF);
 
-	dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
+	if (cmd > (char *) urb->transfer_buffer) {
+		/* Send partial buffer remaining before exiting */
+		int len = cmd - (char *) urb->transfer_buffer;
+		dlfb_submit_urb(dev, urb, len);
+		bytes_sent += len;
+	} else
+		dlfb_urb_completion(urb);
 
-	return 0;
+	atomic_add(fault_count, &dev->defio_fault_count);
+	atomic_add(bytes_sent, &dev->bytes_sent);
+	atomic_add(bytes_identical, &dev->bytes_identical);
+	atomic_add(bytes_rendered, &dev->bytes_rendered);
+	end_cycles = get_cycles();
+	atomic_add(((unsigned int) ((end_cycles - start_cycles)
+		    >> 10)), /* Kcycles */
+		   &dev->cpu_kcycles_used);
 }
 
-static struct fb_ops dlfb_ops = {
-	.fb_setcolreg = dlfb_setcolreg,
-	.fb_fillrect = dlfb_fillrect,
-	.fb_copyarea = dlfb_copyarea,
-	.fb_imageblit = dlfb_imageblit,
-	.fb_mmap = dlfb_mmap,
-	.fb_ioctl = dlfb_ioctl,
-	.fb_release = dlfb_release,
-	.fb_blank = dlfb_blank,
+static struct fb_deferred_io dlfb_defio = {
+	.delay          = 5,
+	.deferred_io    = dlfb_dpy_deferred_io,
 };
 
-static int
-dlfb_probe(struct usb_interface *interface, const struct usb_device_id *id)
-{
-	struct dlfb_data *dev_info;
-	struct fb_info *info;
+#endif
 
+/*
+ * This is necessary before we can communicate with the display controller.
+ */
+static int dlfb_select_std_channel(struct dlfb_data *dev)
+{
 	int ret;
-	char rbuf[4];
-
-	dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL);
-	if (dev_info == NULL) {
-		printk("cannot allocate dev_info structure.\n");
-		return -ENOMEM;
-	}
+	u8 set_def_chn[] = {	   0x57, 0xCD, 0xDC, 0xA7,
+				0x1C, 0x88, 0x5E, 0x15,
+				0x60, 0xFE, 0xC6, 0x97,
+				0x16, 0x3D, 0x47, 0xF2  };
 
-	mutex_init(&dev_info->bulk_mutex);
+	ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+			NR_USB_REQUEST_CHANNEL,
+			(USB_DIR_OUT | USB_TYPE_VENDOR), 0, 0,
+			set_def_chn, sizeof(set_def_chn), USB_CTRL_SET_TIMEOUT);
+	return ret;
+}
 
-	dev_info->udev = usb_get_dev(interface_to_usbdev(interface));
-	dev_info->interface = interface;
 
-	printk("DisplayLink device attached\n");
+static int dlfb_usb_probe(struct usb_interface *interface,
+			const struct usb_device_id *id)
+{
+	struct usb_device *usbdev;
+	struct dlfb_data *dev;
+	struct fb_info *info;
+	int videomemorysize;
+	int i;
+	unsigned char *videomemory;
+	int retval = -ENOMEM;
+	struct fb_var_screeninfo *var;
+	int registered = 0;
+	u16 *pix_framebuffer;
 
-	/* add framebuffer info to usb interface */
-	usb_set_intfdata(interface, dev_info);
+	/* usb initialization */
 
-	dev_info->buf = kmalloc(BUF_SIZE, GFP_KERNEL);
-	/* usb_buffer_alloc(dev_info->udev, BUF_SIZE , GFP_KERNEL, &dev_info->tx_urb->transfer_dma); */
+	usbdev = interface_to_usbdev(interface);
 
-	if (dev_info->buf == NULL) {
-		printk("unable to allocate memory for dlfb commands\n");
-		goto out;
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev == NULL) {
+		err("dlfb_usb_probe: failed alloc of dev struct\n");
+		goto error;
 	}
-	dev_info->bufend = dev_info->buf + BUF_SIZE;
-
-	dev_info->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
-	usb_fill_bulk_urb(dev_info->tx_urb, dev_info->udev,
-			  usb_sndbulkpipe(dev_info->udev, 1), dev_info->buf, 0,
-			  dlfb_bulk_callback, dev_info);
 
-	ret =
-	    usb_control_msg(dev_info->udev, usb_rcvctrlpipe(dev_info->udev, 0),
-			    (0x06), (0x80 | (0x02 << 5)), 0, 0, rbuf, 4, 0);
-	printk("ret control msg 0: %d %x%x%x%x\n", ret, rbuf[0], rbuf[1],
-	       rbuf[2], rbuf[3]);
-
-	dlfb_edid(dev_info);
+	/* we need to wait for both usb and fbdev to spin down on disconnect */
+	kref_init(&dev->kref); /* matching kref_put in usb .disconnect fn */
+	kref_get(&dev->kref); /* matching kref_put in .fb_destroy function*/
 
-	info = framebuffer_alloc(sizeof(u32) * 256, &dev_info->udev->dev);
+	dev->udev = usbdev;
+	dev->gdev = &usbdev->dev; /* our generic struct device * */
+	usb_set_intfdata(interface, dev);
 
-	if (!info) {
-		printk("non posso allocare il framebuffer displaylink");
-		goto out;
+	if (!dlfb_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
+		retval = -ENOMEM;
+		dl_err("dlfb_alloc_urb_list failed\n");
+		goto error;
 	}
 
-	fb_parse_edid(dev_info->edid, &info->var);
+	mutex_init(&dev->fb_open_lock);
 
-	printk("EDID XRES %d YRES %d\n", info->var.xres, info->var.yres);
+	/* We don't register a new USB class. Our client interface is fbdev */
 
-	if (dlfb_set_video_mode(dev_info, info->var.xres, info->var.yres) != 0) {
-		info->var.xres = 1280;
-		info->var.yres = 1024;
-		if (dlfb_set_video_mode
-		    (dev_info, info->var.xres, info->var.yres) != 0) {
-			goto out;
-		}
+	/* allocates framebuffer driver structure, not framebuffer memory */
+	info = framebuffer_alloc(0, &usbdev->dev);
+	if (!info) {
+		retval = -ENOMEM;
+		dl_err("framebuffer_alloc failed\n");
+		goto error;
 	}
+	dev->info = info;
+	info->par = dev;
+	info->pseudo_palette = dev->pseudo_palette;
+	info->fbops = &dlfb_ops;
 
-	printk("found valid mode...%d\n", info->var.pixclock);
+	var = &info->var;
 
-	info->pseudo_palette = info->par;
-	info->par = dev_info;
+	/* TODO set limit based on actual SKU detection */
+	dev->sku_pixel_limit = 2048 * 1152;
 
-	dev_info->info = info;
+	INIT_LIST_HEAD(&info->modelist);
+	dlfb_parse_edid(dev, var, info);
 
-	info->flags =
-	    FBINFO_DEFAULT | FBINFO_READS_FAST | FBINFO_HWACCEL_IMAGEBLIT |
-	    FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT;
-	info->fbops = &dlfb_ops;
-	info->screen_base = rvmalloc(dev_info->screen_size);
+	/*
+	 * ok, now that we've got the size info, we can alloc our framebuffer.
+	 */
+	info->fix = dlfb_fix;
+	info->fix.line_length = var->xres * (var->bits_per_pixel / 8);
+	videomemorysize = info->fix.line_length * var->yres;
 
-	if (info->screen_base == NULL) {
-		printk
-		    ("cannot allocate framebuffer virtual memory of %d bytes\n",
-		     dev_info->screen_size);
-		goto out0;
+	/*
+	 * The big chunk of system memory we use as a virtual framebuffer.
+	 * TODO: Handle fbcon cursor code calling blit in interrupt context
+	 */
+	videomemory = vmalloc(videomemorysize);
+	if (!videomemory) {
+		retval = -ENOMEM;
+		dl_err("Virtual framebuffer alloc failed\n");
+		goto error;
 	}
 
-	printk("screen base allocated !!!\n");
+	info->screen_base = videomemory;
+	info->fix.smem_len = PAGE_ALIGN(videomemorysize);
+	info->fix.smem_start = (unsigned long) videomemory;
+	info->flags = udlfb_info_flags;
 
-	dev_info->backing_buffer = kzalloc(dev_info->screen_size, GFP_KERNEL);
 
-	if (!dev_info->backing_buffer)
-		printk("non posso allocare il backing buffer\n");
+	/*
+	 * Second framebuffer copy, mirroring the state of the framebuffer
+	 * on the physical USB device. We can function without this.
+	 * But with imperfect damage info we may end up sending pixels over USB
+	 * that were, in fact, unchanged -- wasting limited USB bandwidth
+	 */
+	dev->backing_buffer = vmalloc(videomemorysize);
+	if (!dev->backing_buffer)
+		dl_warn("No shadow/backing buffer allcoated\n");
+	else
+		memset(dev->backing_buffer, 0, videomemorysize);
 
-	/* info->var = dev_info->si; */
+	retval = fb_alloc_cmap(&info->cmap, 256, 0);
+	if (retval < 0) {
+		dl_err("fb_alloc_cmap failed %x\n", retval);
+		goto error;
+	}
 
-	info->var.bits_per_pixel = 16;
-	info->var.activate = FB_ACTIVATE_TEST;
-	info->var.vmode = FB_VMODE_NONINTERLACED;
+	/* ready to begin using device */
 
-	info->var.red.offset = 11;
-	info->var.red.length = 5;
-	info->var.red.msb_right = 0;
+#ifdef CONFIG_FB_DEFERRED_IO
+	atomic_set(&dev->use_defio, 1);
+#endif
+	atomic_set(&dev->usb_active, 1);
+	dlfb_select_std_channel(dev);
 
-	info->var.green.offset = 5;
-	info->var.green.length = 6;
-	info->var.green.msb_right = 0;
+	dlfb_ops_check_var(var, info);
+	dlfb_ops_set_par(info);
 
-	info->var.blue.offset = 0;
-	info->var.blue.length = 5;
-	info->var.blue.msb_right = 0;
+	/* paint greenscreen */
+	pix_framebuffer = (u16 *) videomemory;
+	for (i = 0; i < videomemorysize / 2; i++)
+		pix_framebuffer[i] = 0x37e6;
 
-	/* info->var.pixclock =  (10000000 / FB_W * 1000 / FB_H)/2 ; */
+	dlfb_handle_damage(dev, 0, 0, info->var.xres, info->var.yres,
+				videomemory);
 
-	info->fix.smem_start = (unsigned long)info->screen_base;
-	info->fix.smem_len = PAGE_ALIGN(dev_info->screen_size);
-	if (strlen(dev_info->udev->product) > 15) {
-		memcpy(info->fix.id, dev_info->udev->product, 15);
-	} else {
-		memcpy(info->fix.id, dev_info->udev->product,
-		       strlen(dev_info->udev->product));
+	retval = register_framebuffer(info);
+	if (retval < 0) {
+		dl_err("register_framebuffer failed %d\n", retval);
+		goto error;
 	}
-	info->fix.type = FB_TYPE_PACKED_PIXELS;
-	info->fix.visual = FB_VISUAL_TRUECOLOR;
-	info->fix.accel = info->flags;
-	info->fix.line_length = dev_info->line_length;
-
-	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0)
-		goto out1;
+	registered = 1;
 
-	printk("colormap allocated\n");
-	if (register_framebuffer(info) < 0)
-		goto out2;
+	for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
+		device_create_file(info->dev, &fb_device_attrs[i]);
 
-	draw_rect(dev_info, 0, 0, dev_info->info->var.xres,
-		  dev_info->info->var.yres, 0x30, 0xff, 0x30);
+	device_create_bin_file(info->dev, &edid_attr);
 
+	dl_err("DisplayLink USB device /dev/fb%d attached. %dx%d resolution."
+			" Using %dK framebuffer memory\n", info->node,
+			var->xres, var->yres,
+			((dev->backing_buffer) ?
+			videomemorysize * 2 : videomemorysize) >> 10);
 	return 0;
 
-out2:
-	fb_dealloc_cmap(&info->cmap);
-out1:
-	rvfree(info->screen_base, dev_info->screen_size);
-out0:
-	framebuffer_release(info);
-out:
-	usb_set_intfdata(interface, NULL);
-	usb_put_dev(dev_info->udev);
-	kfree(dev_info);
-	return -ENOMEM;
+error:
+	if (dev) {
+		if (registered) {
+			unregister_framebuffer(info);
+			dlfb_ops_destroy(info);
+		} else
+			kref_put(&dev->kref, dlfb_delete);
+
+		if (dev->urbs.count > 0)
+			dlfb_free_urb_list(dev);
+		kref_put(&dev->kref, dlfb_delete); /* last ref from kref_init */
+
+		/* dev has been deallocated. Do not dereference */
+	}
 
+	return retval;
 }
 
-static void dlfb_disconnect(struct usb_interface *interface)
+static void dlfb_usb_disconnect(struct usb_interface *interface)
 {
-	struct dlfb_data *dev_info = usb_get_intfdata(interface);
+	struct dlfb_data *dev;
+	struct fb_info *info;
+	int i;
 
-	mutex_unlock(&dev_info->bulk_mutex);
+	dev = usb_get_intfdata(interface);
+	info = dev->info;
+
+	/* when non-active we'll update virtual framebuffer, but no new urbs */
+	atomic_set(&dev->usb_active, 0);
 
-	usb_kill_urb(dev_info->tx_urb);
-	usb_free_urb(dev_info->tx_urb);
 	usb_set_intfdata(interface, NULL);
-	usb_put_dev(dev_info->udev);
 
-	if (dev_info->info) {
-		unregister_framebuffer(dev_info->info);
-		fb_dealloc_cmap(&dev_info->info->cmap);
-		rvfree(dev_info->info->screen_base, dev_info->screen_size);
-		kfree(dev_info->backing_buffer);
-		framebuffer_release(dev_info->info);
+	for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
+		device_remove_file(info->dev, &fb_device_attrs[i]);
+
+	device_remove_bin_file(info->dev, &edid_attr);
 
+	/* this function will wait for all in-flight urbs to complete */
+	dlfb_free_urb_list(dev);
+
+	if (info) {
+		dl_notice("Detaching /dev/fb%d\n", info->node);
+		unregister_framebuffer(info);
+		dlfb_ops_destroy(info);
 	}
 
-	kfree(dev_info);
+	/* release reference taken by kref_init in probe() */
+	kref_put(&dev->kref, dlfb_delete);
 
-	printk("DisplayLink device disconnected\n");
+	/* consider dlfb_data freed */
+
+	return;
 }
 
 static struct usb_driver dlfb_driver = {
 	.name = "udlfb",
-	.probe = dlfb_probe,
-	.disconnect = dlfb_disconnect,
+	.probe = dlfb_usb_probe,
+	.disconnect = dlfb_usb_disconnect,
 	.id_table = id_table,
 };
 
-static int __init dlfb_init(void)
+static int __init dlfb_module_init(void)
 {
 	int res;
 
-	dlfb_init_modes();
-
 	res = usb_register(&dlfb_driver);
 	if (res)
 		err("usb_register failed. Error number %d", res);
@@ -925,14 +1443,186 @@ static int __init dlfb_init(void)
 	return res;
 }
 
-static void __exit dlfb_exit(void)
+static void __exit dlfb_module_exit(void)
 {
 	usb_deregister(&dlfb_driver);
 }
 
-module_init(dlfb_init);
-module_exit(dlfb_exit);
+module_init(dlfb_module_init);
+module_exit(dlfb_module_exit);
 
-MODULE_AUTHOR("Roberto De Ioris <roberto@unbit.it>");
-MODULE_DESCRIPTION(DRIVER_VERSION);
+static void dlfb_urb_completion(struct urb *urb)
+{
+	struct urb_node *unode = urb->context;
+	struct dlfb_data *dev = unode->dev;
+	unsigned long flags;
+
+	/* sync/async unlink faults aren't errors */
+	if (urb->status) {
+		if (!(urb->status == -ENOENT ||
+		    urb->status == -ECONNRESET ||
+		    urb->status == -ESHUTDOWN)) {
+			dl_err("%s - nonzero write bulk status received: %d\n",
+				__func__, urb->status);
+			atomic_set(&dev->lost_pixels, 1);
+		}
+	}
+
+	urb->transfer_buffer_length = dev->urbs.size; /* reset to actual */
+
+	spin_lock_irqsave(&dev->urbs.lock, flags);
+	list_add_tail(&unode->entry, &dev->urbs.list);
+	dev->urbs.available++;
+	spin_unlock_irqrestore(&dev->urbs.lock, flags);
+
+	up(&dev->urbs.limit_sem);
+}
+
+static void dlfb_free_urb_list(struct dlfb_data *dev)
+{
+	int count = dev->urbs.count;
+	struct list_head *node;
+	struct urb_node *unode;
+	struct urb *urb;
+	int ret;
+	unsigned long flags;
+
+	dl_notice("Waiting for completes and freeing all render urbs\n");
+
+	/* keep waiting and freeing, until we've got 'em all */
+	while (count--) {
+		/* Timeout means a memory leak and/or fault */
+		ret = down_timeout(&dev->urbs.limit_sem, FREE_URB_TIMEOUT);
+		if (ret) {
+			BUG_ON(ret);
+			break;
+		}
+		spin_lock_irqsave(&dev->urbs.lock, flags);
+
+		node = dev->urbs.list.next; /* have reserved one with sem */
+		list_del_init(node);
+
+		spin_unlock_irqrestore(&dev->urbs.lock, flags);
+
+		unode = list_entry(node, struct urb_node, entry);
+		urb = unode->urb;
+
+		/* Free each separately allocated piece */
+		usb_buffer_free(urb->dev, dev->urbs.size,
+			urb->transfer_buffer, urb->transfer_dma);
+		usb_free_urb(urb);
+		kfree(node);
+	}
+
+	kref_put(&dev->kref, dlfb_delete);
+
+}
+
+static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size)
+{
+	int i = 0;
+	struct urb *urb;
+	struct urb_node *unode;
+	char *buf;
+
+	spin_lock_init(&dev->urbs.lock);
+
+	dev->urbs.size = size;
+	INIT_LIST_HEAD(&dev->urbs.list);
+
+	while (i < count) {
+		unode = kzalloc(sizeof(struct urb_node), GFP_KERNEL);
+		if (!unode)
+			break;
+		unode->dev = dev;
+
+		urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!urb) {
+			kfree(unode);
+			break;
+		}
+		unode->urb = urb;
+
+		buf = usb_buffer_alloc(dev->udev, MAX_TRANSFER, GFP_KERNEL,
+					&urb->transfer_dma);
+		if (!buf) {
+			kfree(unode);
+			usb_free_urb(urb);
+			break;
+		}
+
+		/* urb->transfer_buffer_length set to actual before submit */
+		usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 1),
+			buf, size, dlfb_urb_completion, unode);
+		urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+		list_add_tail(&unode->entry, &dev->urbs.list);
+
+		i++;
+	}
+
+	sema_init(&dev->urbs.limit_sem, i);
+	dev->urbs.count = i;
+	dev->urbs.available = i;
+
+	kref_get(&dev->kref); /* released in free_render_urbs() */
+
+	dl_notice("allocated %d %d byte urbs \n", i, (int) size);
+
+	return i;
+}
+
+static struct urb *dlfb_get_urb(struct dlfb_data *dev)
+{
+	int ret = 0;
+	struct list_head *entry;
+	struct urb_node *unode;
+	struct urb *urb = NULL;
+	unsigned long flags;
+
+	/* Wait for an in-flight buffer to complete and get re-queued */
+	ret = down_timeout(&dev->urbs.limit_sem, GET_URB_TIMEOUT);
+	if (ret) {
+		atomic_set(&dev->lost_pixels, 1);
+		dl_err("wait for urb interrupted: %x\n", ret);
+		goto error;
+	}
+
+	spin_lock_irqsave(&dev->urbs.lock, flags);
+
+	BUG_ON(list_empty(&dev->urbs.list)); /* reserved one with limit_sem */
+	entry = dev->urbs.list.next;
+	list_del_init(entry);
+	dev->urbs.available--;
+
+	spin_unlock_irqrestore(&dev->urbs.lock, flags);
+
+	unode = list_entry(entry, struct urb_node, entry);
+	urb = unode->urb;
+
+error:
+	return urb;
+}
+
+static int dlfb_submit_urb(struct dlfb_data *dev, struct urb *urb, size_t len)
+{
+	int ret;
+
+	BUG_ON(len > dev->urbs.size);
+
+	urb->transfer_buffer_length = len; /* set to actual payload len */
+	ret = usb_submit_urb(urb, GFP_KERNEL);
+	if (ret) {
+		dlfb_urb_completion(urb); /* because no one else will */
+		atomic_set(&dev->lost_pixels, 1);
+		dl_err("usb_submit_urb error %x\n", ret);
+	}
+	return ret;
+}
+
+MODULE_AUTHOR("Roberto De Ioris <roberto@unbit.it>, "
+	      "Jaya Kumar <jayakumar.lkml@gmail.com>, "
+	      "Bernie Thompson <bernie@plugable.com>");
+MODULE_DESCRIPTION("DisplayLink kernel framebuffer driver");
 MODULE_LICENSE("GPL");
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/udlfb/udlfb.h linux-libre-2.6.34-gnu1/drivers/staging/udlfb/udlfb.h
--- linux-libre-2.6.33-gnu1/drivers/staging/udlfb/udlfb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/udlfb/udlfb.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,225 +1,106 @@
 #ifndef UDLFB_H
 #define UDLFB_H
 
-#define MAX_VMODES	4
-#define FB_BPP		16
+/*
+ * TODO: Propose standard fb.h ioctl for reporting damage,
+ * using _IOWR() and one of the existing area structs from fb.h
+ * Consider these ioctls deprecated, but they're still used by the
+ * DisplayLink X server as yet - need both to be modified in tandem
+ * when new ioctl(s) are ready.
+ */
+#define DLFB_IOCTL_RETURN_EDID	 0xAD
+#define DLFB_IOCTL_REPORT_DAMAGE 0xAA
+struct dloarea {
+	int x, y;
+	int w, h;
+	int x2, y2;
+};
 
-#define STD_CHANNEL	"\x57\xCD\xDC\xA7\x1C\x88\x5E\x15"	\
-			"\x60\xFE\xC6\x97\x16\x3D\x47\xF2"
+struct urb_node {
+	struct list_head entry;
+	struct dlfb_data *dev;
+	struct urb *urb;
+};
 
-/* as libdlo */
-#define BUF_HIGH_WATER_MARK	1024
-#define BUF_SIZE		(64*1024)
+struct urb_list {
+	struct list_head list;
+	spinlock_t lock;
+	struct semaphore limit_sem;
+	int available;
+	int count;
+	size_t size;
+};
 
 struct dlfb_data {
 	struct usb_device *udev;
-	struct usb_interface *interface;
-	struct urb *tx_urb, *ctrl_urb;
-	struct usb_ctrlrequest dr;
+	struct device *gdev; /* &udev->dev */
 	struct fb_info *info;
-	char *buf;
-	char *bufend;
+	struct urb_list urbs;
+	struct kref kref;
 	char *backing_buffer;
-	struct mutex bulk_mutex;
+	struct delayed_work deferred_work;
+	struct mutex fb_open_lock;
+	int fb_count;
+	atomic_t usb_active; /* 0 = update virtual buffer, but no usb traffic */
+	atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */
+	atomic_t use_defio; /* 0 = rely on ioctls and blit/copy/fill rects */
 	char edid[128];
-	int screen_size;
-	int line_length;
-	struct completion done;
+	int sku_pixel_limit;
 	int base16;
-	int base16d;
 	int base8;
-	int base8d;
+	u32 pseudo_palette[256];
+	/* blit-only rendering path metrics, exposed through sysfs */
+	atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */
+	atomic_t bytes_identical; /* saved effort with backbuffer comparison */
+	atomic_t bytes_sent; /* to usb, after compression including overhead */
+	atomic_t cpu_kcycles_used; /* transpired during pixel processing */
+	/* interface usage metrics. Clients can call driver via several */
+	atomic_t blit_count;
+	atomic_t copy_count;
+	atomic_t fill_count;
+	atomic_t damage_count;
+	atomic_t defio_fault_count;
 };
 
-struct dlfb_video_mode {
-	uint8_t col;
-	uint32_t hclock;
-	uint32_t vclock;
-	uint8_t unknown1[6];
-	uint16_t xres;
-	uint8_t unknown2[6];
-	uint16_t yres;
-	uint8_t unknown3[4];
-} __attribute__ ((__packed__));
-
-static struct dlfb_video_mode dlfb_video_modes[MAX_VMODES];
-
-static void dlfb_bulk_callback(struct urb *urb)
-{
-	struct dlfb_data *dev_info = urb->context;
-	complete(&dev_info->done);
-}
-
-static void dlfb_edid(struct dlfb_data *dev_info)
-{
-	int i;
-	int ret;
-	char rbuf[2];
-
-	for (i = 0; i < 128; i++) {
-		ret =
-		    usb_control_msg(dev_info->udev,
-				    usb_rcvctrlpipe(dev_info->udev, 0), (0x02),
-				    (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2,
-				    0);
-		/*printk("ret control msg edid %d: %d [%d]\n",i, ret, rbuf[1]); */
-		dev_info->edid[i] = rbuf[1];
-	}
-
-}
-
-static int dlfb_bulk_msg(struct dlfb_data *dev_info, int len)
-{
-	int ret;
-
-	init_completion(&dev_info->done);
-
-	dev_info->tx_urb->actual_length = 0;
-	dev_info->tx_urb->transfer_buffer_length = len;
-
-	ret = usb_submit_urb(dev_info->tx_urb, GFP_KERNEL);
-	if (!wait_for_completion_timeout(&dev_info->done, 1000)) {
-		usb_kill_urb(dev_info->tx_urb);
-		printk("usb timeout !!!\n");
-	}
-
-	return dev_info->tx_urb->actual_length;
-}
-
-static void dlfb_init_modes(void)
-{
-	dlfb_video_modes[0].col = 0;
-	memcpy(&dlfb_video_modes[0].hclock, "\x20\x3C\x7A\xC9", 4);
-	memcpy(&dlfb_video_modes[0].vclock, "\xF2\x6C\x48\xF9", 4);
-	memcpy(&dlfb_video_modes[0].unknown1, "\x70\x53\xFF\xFF\x21\x27", 6);
-	dlfb_video_modes[0].xres = 800;
-	memcpy(&dlfb_video_modes[0].unknown2, "\x91\xF3\xFF\xFF\xFF\xF9", 6);
-	dlfb_video_modes[0].yres = 480;
-	memcpy(&dlfb_video_modes[0].unknown3, "\x01\x02\xC8\x19", 4);
-
-	dlfb_video_modes[1].col = 0;
-	memcpy(&dlfb_video_modes[1].hclock, "\x36\x18\xD5\x10", 4);
-	memcpy(&dlfb_video_modes[1].vclock, "\x60\xA9\x7B\x33", 4);
-	memcpy(&dlfb_video_modes[1].unknown1, "\xA1\x2B\x27\x32\xFF\xFF", 6);
-	dlfb_video_modes[1].xres = 1024;
-	memcpy(&dlfb_video_modes[1].unknown2, "\xD9\x9A\xFF\xCA\xFF\xFF", 6);
-	dlfb_video_modes[1].yres = 768;
-	memcpy(&dlfb_video_modes[1].unknown3, "\x04\x03\xC8\x32", 4);
-
-	dlfb_video_modes[2].col = 0;
-	memcpy(&dlfb_video_modes[2].hclock, "\x98\xF8\x0D\x57", 4);
-	memcpy(&dlfb_video_modes[2].vclock, "\x2A\x55\x4D\x54", 4);
-	memcpy(&dlfb_video_modes[2].unknown1, "\xCA\x0D\xFF\xFF\x94\x43", 6);
-	dlfb_video_modes[2].xres = 1280;
-	memcpy(&dlfb_video_modes[2].unknown2, "\x9A\xA8\xFF\xFF\xFF\xF9", 6);
-	dlfb_video_modes[2].yres = 1024;
-	memcpy(&dlfb_video_modes[2].unknown3, "\x04\x02\x60\x54", 4);
-
-	dlfb_video_modes[3].col = 0;
-	memcpy(&dlfb_video_modes[3].hclock, "\x42\x24\x38\x36", 4);
-	memcpy(&dlfb_video_modes[3].vclock, "\xC1\x52\xD9\x29", 4);
-	memcpy(&dlfb_video_modes[3].unknown1, "\xEA\xB8\x32\x60\xFF\xFF", 6);
-	dlfb_video_modes[3].xres = 1400;
-	memcpy(&dlfb_video_modes[3].unknown2, "\xC9\x4E\xFF\xFF\xFF\xF2", 6);
-	dlfb_video_modes[3].yres = 1050;
-	memcpy(&dlfb_video_modes[3].unknown3, "\x04\x02\x1E\x5F", 4);
-}
-
-static char *dlfb_set_register(char *bufptr, uint8_t reg, uint8_t val)
-{
-	*bufptr++ = 0xAF;
-	*bufptr++ = 0x20;
-	*bufptr++ = reg;
-	*bufptr++ = val;
-
-	return bufptr;
-}
-
-static int dlfb_set_video_mode(struct dlfb_data *dev_info, int width, int height)
-{
-	int i, ret;
-	unsigned char j;
-	char *bufptr = dev_info->buf;
-	uint8_t *vdata;
-
-	for (i = 0; i < MAX_VMODES; i++) {
-		printk("INIT VIDEO %d %d %d\n", i, dlfb_video_modes[i].xres,
-		       dlfb_video_modes[i].yres);
-		if (dlfb_video_modes[i].xres == width
-		    && dlfb_video_modes[i].yres == height) {
-
-			dev_info->base16 = 0;
-			dev_info->base16d = width * height * (FB_BPP / 8);
-
-			//dev_info->base8 = width * height * (FB_BPP / 8);
-
-			dev_info->base8 = dev_info->base16;
-			dev_info->base8d = dev_info->base16d;
-
-			/* set encryption key (null) */
-			memcpy(dev_info->buf, STD_CHANNEL, 16);
-			ret =
-			    usb_control_msg(dev_info->udev,
-					    usb_sndctrlpipe(dev_info->udev, 0),
-					    0x12, (0x02 << 5), 0, 0,
-					    dev_info->buf, 16, 0);
-			printk("ret control msg 1 (STD_CHANNEL): %d\n", ret);
-
-			/* set registers */
-			bufptr = dlfb_set_register(bufptr, 0xFF, 0x00);
-
-			/* set color depth */
-			bufptr = dlfb_set_register(bufptr, 0x00, 0x00);
-
-			/* set addresses */
-			bufptr =
-			    dlfb_set_register(bufptr, 0x20,
-					      (char)(dev_info->base16 >> 16));
-			bufptr =
-			    dlfb_set_register(bufptr, 0x21,
-					      (char)(dev_info->base16 >> 8));
-			bufptr =
-			    dlfb_set_register(bufptr, 0x22,
-					      (char)(dev_info->base16));
-
-			bufptr =
-			    dlfb_set_register(bufptr, 0x26,
-					      (char)(dev_info->base8 >> 16));
-			bufptr =
-			    dlfb_set_register(bufptr, 0x27,
-					      (char)(dev_info->base8 >> 8));
-			bufptr =
-			    dlfb_set_register(bufptr, 0x28,
-					      (char)(dev_info->base8));
+#define NR_USB_REQUEST_I2C_SUB_IO 0x02
+#define NR_USB_REQUEST_CHANNEL 0x12
 
-			/* set video mode */
-			vdata = (uint8_t *)&dlfb_video_modes[i];
-			for (j = 0; j < 29; j++)
-				bufptr = dlfb_set_register(bufptr, j, vdata[j]);
+/* -BULK_SIZE as per usb-skeleton. Can we get full page and avoid overhead? */
+#define BULK_SIZE 512
+#define MAX_TRANSFER (PAGE_SIZE*16 - BULK_SIZE)
+#define WRITES_IN_FLIGHT (4)
 
-			/* blank */
-			bufptr = dlfb_set_register(bufptr, 0x1F, 0x00);
+#define GET_URB_TIMEOUT	HZ
+#define FREE_URB_TIMEOUT (HZ*2)
 
-			/* end registers */
-			bufptr = dlfb_set_register(bufptr, 0xFF, 0xFF);
+#define BPP                     2
+#define MAX_CMD_PIXELS		255
 
-			/* send */
-			ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
-			printk("ret bulk 2: %d %td\n", ret,
-			       bufptr - dev_info->buf);
+#define RLX_HEADER_BYTES	7
+#define MIN_RLX_PIX_BYTES       4
+#define MIN_RLX_CMD_BYTES	(RLX_HEADER_BYTES + MIN_RLX_PIX_BYTES)
 
-			/* flush */
-			ret = dlfb_bulk_msg(dev_info, 0);
-			printk("ret bulk 3: %d\n", ret);
+#define RLE_HEADER_BYTES	6
+#define MIN_RLE_PIX_BYTES	3
+#define MIN_RLE_CMD_BYTES	(RLE_HEADER_BYTES + MIN_RLE_PIX_BYTES)
 
-			dev_info->screen_size = width * height * (FB_BPP / 8);
-			dev_info->line_length = width * (FB_BPP / 8);
+#define RAW_HEADER_BYTES	6
+#define MIN_RAW_PIX_BYTES	2
+#define MIN_RAW_CMD_BYTES	(RAW_HEADER_BYTES + MIN_RAW_PIX_BYTES)
 
-			return 0;
-		}
-	}
+/* remove these once align.h patch is taken into kernel */
+#define DL_ALIGN_UP(x, a) ALIGN(x, a)
+#define DL_ALIGN_DOWN(x, a) ALIGN(x-(a-1), a)
 
-	return -1;
-}
+/* remove once this gets added to sysfs.h */
+#define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store)
 
+#define dl_err(format, arg...) \
+	dev_err(dev->gdev, "dlfb: " format, ## arg)
+#define dl_warn(format, arg...) \
+	dev_warn(dev->gdev, "dlfb: " format, ## arg)
+#define dl_notice(format, arg...) \
+	dev_notice(dev->gdev, "dlfb: " format, ## arg)
+#define dl_info(format, arg...) \
+	dev_info(dev->gdev, "dlfb: " format, ## arg)
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/usbip/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/usbip/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/usbip/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/usbip/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -34,3 +34,10 @@ config USB_IP_HOST
 
 	 To compile this driver as a module, choose M here: the
 	 module will be called usbip.
+
+config USB_IP_DEBUG_ENABLE
+	bool "USB-IP Debug Enable"
+	depends on USB_IP_COMMON
+	default N
+	---help---
+	  This enables the debug messages from the USB-IP drivers.
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/usbip/Makefile linux-libre-2.6.34-gnu1/drivers/staging/usbip/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/usbip/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/usbip/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,6 @@ vhci-hcd-objs := vhci_sysfs.o vhci_tx.o
 obj-$(CONFIG_USB_IP_HOST) += usbip.o
 usbip-objs := stub_dev.o stub_main.o stub_rx.o stub_tx.o
 
-ifeq ($(CONFIG_USB_DEBUG),y)
+ifeq ($(CONFIG_USB_IP_DEBUG_ENABLE),y)
 	EXTRA_CFLAGS += -DDEBUG
 endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/usbip/stub_dev.c linux-libre-2.6.34-gnu1/drivers/staging/usbip/stub_dev.c
--- linux-libre-2.6.33-gnu1/drivers/staging/usbip/stub_dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/usbip/stub_dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,8 @@
  * USA.
  */
 
+#include <linux/slab.h>
+
 #include "usbip_common.h"
 #include "stub.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/usbip/stub_main.c linux-libre-2.6.34-gnu1/drivers/staging/usbip/stub_main.c
--- linux-libre-2.6.33-gnu1/drivers/staging/usbip/stub_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/usbip/stub_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  * USA.
  */
 
+#include <linux/slab.h>
 
 #include "usbip_common.h"
 #include "stub.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/usbip/stub_rx.c linux-libre-2.6.34-gnu1/drivers/staging/usbip/stub_rx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/usbip/stub_rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/usbip/stub_rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,8 @@
  * USA.
  */
 
+#include <linux/slab.h>
+
 #include "usbip_common.h"
 #include "stub.h"
 #include "../../usb/core/hcd.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/usbip/stub_tx.c linux-libre-2.6.34-gnu1/drivers/staging/usbip/stub_tx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/usbip/stub_tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/usbip/stub_tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,8 @@
  * USA.
  */
 
+#include <linux/slab.h>
+
 #include "usbip_common.h"
 #include "stub.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/usbip/usbip_common.c linux-libre-2.6.34-gnu1/drivers/staging/usbip/usbip_common.c
--- linux-libre-2.6.33-gnu1/drivers/staging/usbip/usbip_common.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/usbip/usbip_common.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/tcp.h>
 #include <linux/in.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include "usbip_common.h"
 
 /* version information */
@@ -33,7 +34,7 @@
 /*-------------------------------------------------------------------------*/
 /* debug routines */
 
-#ifdef CONFIG_USB_DEBUG
+#ifdef CONFIG_USB_IP_DEBUG_ENABLE
 unsigned long usbip_debug_flag = 0xffffffff;
 #else
 unsigned long usbip_debug_flag;
@@ -55,10 +56,7 @@ static ssize_t show_flag(struct device *
 static ssize_t store_flag(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
-	unsigned long flag;
-
-	sscanf(buf, "%lx", &flag);
-	usbip_debug_flag = flag;
+	sscanf(buf, "%lx", &usbip_debug_flag);
 
 	return count;
 }
@@ -66,33 +64,8 @@ DEVICE_ATTR(usbip_debug, (S_IRUGO | S_IW
 
 static void usbip_dump_buffer(char *buff, int bufflen)
 {
-	int i;
-
-	if (bufflen > 128) {
-		for (i = 0; i < 128; i++) {
-			if (i%24 == 0)
-				printk(KERN_DEBUG "   ");
-			printk(KERN_DEBUG "%02x ", (unsigned char) buff[i]);
-			if (i%4 == 3)
-				printk(KERN_DEBUG "| ");
-			if (i%24 == 23)
-				printk(KERN_DEBUG "\n");
-		}
-		printk(KERN_DEBUG "... (%d byte)\n", bufflen);
-		return;
-	}
-
-	for (i = 0; i < bufflen; i++) {
-		if (i%24 == 0)
-			printk(KERN_DEBUG "   ");
-		printk(KERN_DEBUG "%02x ", (unsigned char) buff[i]);
-		if (i%4 == 3)
-			printk(KERN_DEBUG "| ");
-		if (i%24 == 23)
-			printk(KERN_DEBUG "\n");
-	}
-	printk(KERN_DEBUG "\n");
-
+	print_hex_dump(KERN_DEBUG, "usb-ip", DUMP_PREFIX_OFFSET, 16, 4,
+		       buff, bufflen, false);
 }
 
 static void usbip_dump_pipe(unsigned int p)
@@ -558,60 +531,6 @@ err:
 }
 EXPORT_SYMBOL_GPL(usbip_xmit);
 
-
-/* now a usrland utility should set options. */
-#if 0
-int setquickack(struct socket *socket)
-{
-	mm_segment_t oldfs;
-	int val = 1;
-	int ret;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_QUICKACK,
-			(char __user *) &val, sizeof(ret));
-	set_fs(oldfs);
-
-	return ret;
-}
-
-int setnodelay(struct socket *socket)
-{
-	mm_segment_t oldfs;
-	int val = 1;
-	int ret;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_NODELAY,
-			(char __user *) &val, sizeof(ret));
-	set_fs(oldfs);
-
-	return ret;
-}
-
-int setkeepalive(struct socket *socket)
-{
-	mm_segment_t oldfs;
-	int val = 1;
-	int ret;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	ret = socket->ops->setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE,
-			(char __user *) &val, sizeof(ret));
-	set_fs(oldfs);
-
-	return ret;
-}
-
-void setreuse(struct socket *socket)
-{
-	socket->sk->sk_reuse = 1;
-}
-#endif
-
 struct socket *sockfd_to_socket(unsigned int sockfd)
 {
 	struct socket *socket;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/usbip/usbip_common.h linux-libre-2.6.34-gnu1/drivers/staging/usbip/usbip_common.h
--- linux-libre-2.6.33-gnu1/drivers/staging/usbip/usbip_common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/usbip/usbip_common.h	2010-05-16 17:17:36.000000000 -0400
@@ -33,12 +33,12 @@
  */
 
 /**
- * usbip_udbg - print debug messages if CONFIG_USB_DEBUG is defined
+ * usbip_udbg - print debug messages if CONFIG_USB_IP_DEBUG_ENABLE is defined
  * @fmt:
  * @args:
  */
 
-#ifdef CONFIG_USB_DEBUG
+#ifdef CONFIG_USB_IP_DEBUG_ENABLE
 
 #define usbip_udbg(fmt, args...)					\
 	do {								\
@@ -47,11 +47,11 @@
 			__FILE__, __LINE__, __func__, ##args);		\
 	} while (0)
 
-#else  /* CONFIG_USB_DEBUG */
+#else  /* CONFIG_USB_IP_DEBUG_ENABLE */
 
 #define usbip_udbg(fmt, args...)		do { } while (0)
 
-#endif /* CONFIG_USB_DEBUG */
+#endif /* CONFIG_USB_IP_DEBUG_ENABLE */
 
 
 enum {
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/usbip/usbip_event.c linux-libre-2.6.34-gnu1/drivers/staging/usbip/usbip_event.c
--- linux-libre-2.6.33-gnu1/drivers/staging/usbip/usbip_event.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/usbip/usbip_event.c	2010-05-16 17:17:36.000000000 -0400
@@ -117,6 +117,9 @@ void usbip_stop_eh(struct usbip_device *
 {
 	struct usbip_task *eh = &ud->eh;
 
+	if (eh->thread == current)
+		return; /* do not wait for myself */
+
 	wait_for_completion(&eh->thread_done);
 	usbip_dbg_eh("usbip_eh has finished\n");
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/usbip/vhci_hcd.c linux-libre-2.6.34-gnu1/drivers/staging/usbip/vhci_hcd.c
--- linux-libre-2.6.33-gnu1/drivers/staging/usbip/vhci_hcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/usbip/vhci_hcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  * USA.
  */
 
+#include <linux/slab.h>
 
 #include "usbip_common.h"
 #include "vhci.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/usbip/vhci_rx.c linux-libre-2.6.34-gnu1/drivers/staging/usbip/vhci_rx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/usbip/vhci_rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/usbip/vhci_rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,8 @@
  * USA.
  */
 
+#include <linux/slab.h>
+
 #include "usbip_common.h"
 #include "vhci.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/usbip/vhci_sysfs.c linux-libre-2.6.34-gnu1/drivers/staging/usbip/vhci_sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/staging/usbip/vhci_sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/usbip/vhci_sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -144,7 +144,7 @@ static int valid_args(__u32 rhport, enum
 	case USB_SPEED_LOW:
 	case USB_SPEED_FULL:
 	case USB_SPEED_HIGH:
-	case USB_SPEED_VARIABLE:
+	case USB_SPEED_WIRELESS:
 		break;
 	default:
 		usbip_uerr("speed %d\n", speed);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/usbip/vhci_tx.c linux-libre-2.6.34-gnu1/drivers/staging/usbip/vhci_tx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/usbip/vhci_tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/usbip/vhci_tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,8 @@
  * USA.
  */
 
+#include <linux/slab.h>
+
 #include "usbip_common.h"
 #include "vhci.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/boards/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/vme/boards/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/boards/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/boards/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,9 @@
+comment "VME Board Drivers"
+
+config VMIVME_7805
+	tristate "VMIVME-7805"
+	help
+	  If you say Y here you get support for the VMIVME-7805 board.
+	  This board has an additional control interface to the Universe II
+	  chip. This driver has to be included if you want to access VME bus
+	  with VMIVME-7805 board.
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/boards/Makefile linux-libre-2.6.34-gnu1/drivers/staging/vme/boards/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/boards/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/boards/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,5 @@
+#
+# Makefile for the VME board drivers.
+#
+
+obj-$(CONFIG_VMIVME_7805)	+= vme_vmivme7805.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/boards/vme_vmivme7805.c linux-libre-2.6.34-gnu1/drivers/staging/vme/boards/vme_vmivme7805.c
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/boards/vme_vmivme7805.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/boards/vme_vmivme7805.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,124 @@
+/*
+ * Support for the VMIVME-7805 board access to the Universe II bridge.
+ *
+ * Author: Arthur Benilov <arthur.benilov@iba-group.com>
+ * Copyright 2010 Ion Beam Application, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/poll.h>
+#include <linux/io.h>
+
+#include "vme_vmivme7805.h"
+
+static int __init vmic_init(void);
+static int vmic_probe(struct pci_dev *, const struct pci_device_id *);
+static void vmic_remove(struct pci_dev *);
+static void __exit vmic_exit(void);
+
+/** Base address to access FPGA register */
+static void *vmic_base;
+
+static char driver_name[] = "vmivme_7805";
+
+static struct pci_device_id vmic_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_VMIC, PCI_DEVICE_ID_VTIMR) },
+	{ },
+};
+
+static struct pci_driver vmic_driver = {
+	.name = driver_name,
+	.id_table = vmic_ids,
+	.probe = vmic_probe,
+	.remove = vmic_remove,
+};
+
+static int __init vmic_init(void)
+{
+	return pci_register_driver(&vmic_driver);
+}
+
+static int vmic_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	int retval;
+	u32 data;
+
+	/* Enable the device */
+	retval = pci_enable_device(pdev);
+	if (retval) {
+		dev_err(&pdev->dev, "Unable to enable device\n");
+		goto err;
+	}
+
+	/* Map Registers */
+	retval = pci_request_regions(pdev, driver_name);
+	if (retval) {
+		dev_err(&pdev->dev, "Unable to reserve resources\n");
+		goto err_resource;
+	}
+
+	/* Map registers in BAR 0 */
+	vmic_base = ioremap_nocache(pci_resource_start(pdev, 0), 16);
+	if (!vmic_base) {
+		dev_err(&pdev->dev, "Unable to remap CRG region\n");
+		retval = -EIO;
+		goto err_remap;
+	}
+
+	/* Clear the FPGA VME IF contents */
+	iowrite32(0, vmic_base + VME_CONTROL);
+
+	/* Clear any initial BERR  */
+	data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF;
+	data |= BM_VME_CONTROL_BERRST;
+	iowrite32(data, vmic_base + VME_CONTROL);
+
+	/* Enable the vme interface and byte swapping */
+	data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF;
+	data = data | BM_VME_CONTROL_MASTER_ENDIAN |
+			BM_VME_CONTROL_SLAVE_ENDIAN |
+			BM_VME_CONTROL_ABLE |
+			BM_VME_CONTROL_BERRI |
+			BM_VME_CONTROL_BPENA |
+			BM_VME_CONTROL_VBENA;
+	iowrite32(data, vmic_base + VME_CONTROL);
+
+	return 0;
+
+err_remap:
+	pci_release_regions(pdev);
+err_resource:
+	pci_disable_device(pdev);
+err:
+	return retval;
+}
+
+static void vmic_remove(struct pci_dev *pdev)
+{
+	iounmap(vmic_base);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+
+}
+
+static void __exit vmic_exit(void)
+{
+	pci_unregister_driver(&vmic_driver);
+}
+
+MODULE_DESCRIPTION("VMIVME-7805 board support driver");
+MODULE_AUTHOR("Arthur Benilov <arthur.benilov@iba-group.com>");
+MODULE_LICENSE("GPL");
+
+module_init(vmic_init);
+module_exit(vmic_exit);
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/boards/vme_vmivme7805.h linux-libre-2.6.34-gnu1/drivers/staging/vme/boards/vme_vmivme7805.h
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/boards/vme_vmivme7805.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/boards/vme_vmivme7805.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,37 @@
+/*
+ * vmivme_7805.h
+ *
+ * Support for the VMIVME-7805 board access to the Universe II bridge.
+ *
+ * Author: Arthur Benilov <arthur.benilov@iba-group.com>
+ * Copyright 2010 Ion Beam Application, 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 _VMIVME_7805_H
+#define _VMIVME_7805_H
+
+#ifndef PCI_VENDOR_ID_VMIC
+#define PCI_VENDOR_ID_VMIC		0x114A
+#endif
+
+#ifndef PCI_DEVICE_ID_VTIMR
+#define PCI_DEVICE_ID_VTIMR		0x0004
+#endif
+
+#define VME_CONTROL			0x0000
+#define BM_VME_CONTROL_MASTER_ENDIAN	0x0001
+#define BM_VME_CONTROL_SLAVE_ENDIAN	0x0002
+#define BM_VME_CONTROL_ABLE		0x0004
+#define BM_VME_CONTROL_BERRI		0x0040
+#define BM_VME_CONTROL_BERRST		0x0080
+#define BM_VME_CONTROL_BPENA		0x0400
+#define BM_VME_CONTROL_VBENA		0x0800
+
+#endif /* _VMIVME_7805_H */
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/bridges/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/vme/bridges/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/bridges/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/bridges/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -2,12 +2,14 @@ comment "VME Bridge Drivers"
 
 config VME_CA91CX42
 	tristate "Universe II"
+	depends on VIRT_TO_BUS
 	help
 	 If you say Y here you get support for the Tundra CA91C142
 	 (Universe II) VME bridge chip.
 
 config VME_TSI148
 	tristate "Tempe"
+	depends on VIRT_TO_BUS
 	help
 	 If you say Y here you get support for the Tundra TSI148 VME bridge
 	 chip.
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/bridges/vme_ca91cx42.c linux-libre-2.6.34-gnu1/drivers/staging/vme/bridges/vme_ca91cx42.c
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/bridges/vme_ca91cx42.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/bridges/vme_ca91cx42.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,8 +1,8 @@
 /*
  * Support for the Tundra Universe I/II VME-PCI Bridge Chips
  *
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Author: Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * Based on work by Tom Armistead and Ajit Prem
  * Copyright 2004 Motorola Inc.
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/time.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -38,25 +39,12 @@ static int ca91cx42_probe(struct pci_dev
 static void ca91cx42_remove(struct pci_dev *);
 static void __exit ca91cx42_exit(void);
 
-struct vme_bridge *ca91cx42_bridge;
-wait_queue_head_t dma_queue;
-wait_queue_head_t iack_queue;
-wait_queue_head_t lm_queue;
-wait_queue_head_t mbox_queue;
-
-void (*lm_callback[4])(int);    /* Called in interrupt handler, be careful! */
-void *crcsr_kernel;
-dma_addr_t crcsr_bus;
-
-struct mutex vme_rmw;   /* Only one RMW cycle at a time */
-struct mutex vme_int;   /*
-			 * Only one VME interrupt can be
-			 * generated at a time, provide locking
-			 */
+/* Module parameters */
+static int geoid;
 
 static char driver_name[] = "vme_ca91cx42";
 
-static struct pci_device_id ca91cx42_ids[] = {
+static const struct pci_device_id ca91cx42_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C142) },
 	{ },
 };
@@ -68,14 +56,14 @@ static struct pci_driver ca91cx42_driver
 	.remove = ca91cx42_remove,
 };
 
-static u32 ca91cx42_DMA_irqhandler(void)
+static u32 ca91cx42_DMA_irqhandler(struct ca91cx42_driver *bridge)
 {
-	wake_up(&dma_queue);
+	wake_up(&(bridge->dma_queue));
 
 	return CA91CX42_LINT_DMA;
 }
 
-static u32 ca91cx42_LM_irqhandler(u32 stat)
+static u32 ca91cx42_LM_irqhandler(struct ca91cx42_driver *bridge, u32 stat)
 {
 	int i;
 	u32 serviced = 0;
@@ -83,7 +71,7 @@ static u32 ca91cx42_LM_irqhandler(u32 st
 	for (i = 0; i < 4; i++) {
 		if (stat & CA91CX42_LINT_LM[i]) {
 			/* We only enable interrupts if the callback is set */
-			lm_callback[i](i);
+			bridge->lm_callback[i](i);
 			serviced |= CA91CX42_LINT_LM[i];
 		}
 	}
@@ -92,40 +80,25 @@ static u32 ca91cx42_LM_irqhandler(u32 st
 }
 
 /* XXX This needs to be split into 4 queues */
-static u32 ca91cx42_MB_irqhandler(int mbox_mask)
+static u32 ca91cx42_MB_irqhandler(struct ca91cx42_driver *bridge, int mbox_mask)
 {
-	wake_up(&mbox_queue);
+	wake_up(&(bridge->mbox_queue));
 
 	return CA91CX42_LINT_MBOX;
 }
 
-static u32 ca91cx42_IACK_irqhandler(void)
+static u32 ca91cx42_IACK_irqhandler(struct ca91cx42_driver *bridge)
 {
-	wake_up(&iack_queue);
+	wake_up(&(bridge->iack_queue));
 
 	return CA91CX42_LINT_SW_IACK;
 }
 
-#if 0
-int ca91cx42_bus_error_chk(int clrflag)
-{
-	int tmp;
-	tmp = ioread32(ca91cx42_bridge->base + PCI_COMMAND);
-	if (tmp & 0x08000000) {	/* S_TA is Set */
-		if (clrflag)
-			iowrite32(tmp | 0x08000000,
-			       ca91cx42_bridge->base + PCI_COMMAND);
-		return 1;
-	}
-	return 0;
-}
-#endif
-
-static u32 ca91cx42_VERR_irqhandler(void)
+static u32 ca91cx42_VERR_irqhandler(struct ca91cx42_driver *bridge)
 {
 	int val;
 
-	val = ioread32(ca91cx42_bridge->base + DGCS);
+	val = ioread32(bridge->base + DGCS);
 
 	if (!(val & 0x00000800)) {
 		printk(KERN_ERR "ca91c042: ca91cx42_VERR_irqhandler DMA Read "
@@ -135,11 +108,11 @@ static u32 ca91cx42_VERR_irqhandler(void
 	return CA91CX42_LINT_VERR;
 }
 
-static u32 ca91cx42_LERR_irqhandler(void)
+static u32 ca91cx42_LERR_irqhandler(struct ca91cx42_driver *bridge)
 {
 	int val;
 
-	val = ioread32(ca91cx42_bridge->base + DGCS);
+	val = ioread32(bridge->base + DGCS);
 
 	if (!(val & 0x00000800)) {
 		printk(KERN_ERR "ca91c042: ca91cx42_LERR_irqhandler DMA Read "
@@ -151,13 +124,18 @@ static u32 ca91cx42_LERR_irqhandler(void
 }
 
 
-static u32 ca91cx42_VIRQ_irqhandler(int stat)
+static u32 ca91cx42_VIRQ_irqhandler(struct vme_bridge *ca91cx42_bridge,
+	int stat)
 {
 	int vec, i, serviced = 0;
+	struct ca91cx42_driver *bridge;
+
+	bridge = ca91cx42_bridge->driver_priv;
+
 
 	for (i = 7; i > 0; i--) {
 		if (stat & (1 << i)) {
-			vec = ioread32(ca91cx42_bridge->base +
+			vec = ioread32(bridge->base +
 				CA91CX42_V_STATID[i]) & 0xff;
 
 			vme_irq_handler(ca91cx42_bridge, i, vec);
@@ -169,15 +147,18 @@ static u32 ca91cx42_VIRQ_irqhandler(int
 	return serviced;
 }
 
-static irqreturn_t ca91cx42_irqhandler(int irq, void *dev_id)
+static irqreturn_t ca91cx42_irqhandler(int irq, void *ptr)
 {
 	u32 stat, enable, serviced = 0;
+	struct vme_bridge *ca91cx42_bridge;
+	struct ca91cx42_driver *bridge;
 
-	if (dev_id != ca91cx42_bridge->base)
-		return IRQ_NONE;
+	ca91cx42_bridge = ptr;
 
-	enable = ioread32(ca91cx42_bridge->base + LINT_EN);
-	stat = ioread32(ca91cx42_bridge->base + LINT_STAT);
+	bridge = ca91cx42_bridge->driver_priv;
+
+	enable = ioread32(bridge->base + LINT_EN);
+	stat = ioread32(bridge->base + LINT_STAT);
 
 	/* Only look at unmasked interrupts */
 	stat &= enable;
@@ -186,42 +167,45 @@ static irqreturn_t ca91cx42_irqhandler(i
 		return IRQ_NONE;
 
 	if (stat & CA91CX42_LINT_DMA)
-		serviced |= ca91cx42_DMA_irqhandler();
+		serviced |= ca91cx42_DMA_irqhandler(bridge);
 	if (stat & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 |
 			CA91CX42_LINT_LM3))
-		serviced |= ca91cx42_LM_irqhandler(stat);
+		serviced |= ca91cx42_LM_irqhandler(bridge, stat);
 	if (stat & CA91CX42_LINT_MBOX)
-		serviced |= ca91cx42_MB_irqhandler(stat);
+		serviced |= ca91cx42_MB_irqhandler(bridge, stat);
 	if (stat & CA91CX42_LINT_SW_IACK)
-		serviced |= ca91cx42_IACK_irqhandler();
+		serviced |= ca91cx42_IACK_irqhandler(bridge);
 	if (stat & CA91CX42_LINT_VERR)
-		serviced |= ca91cx42_VERR_irqhandler();
+		serviced |= ca91cx42_VERR_irqhandler(bridge);
 	if (stat & CA91CX42_LINT_LERR)
-		serviced |= ca91cx42_LERR_irqhandler();
+		serviced |= ca91cx42_LERR_irqhandler(bridge);
 	if (stat & (CA91CX42_LINT_VIRQ1 | CA91CX42_LINT_VIRQ2 |
 			CA91CX42_LINT_VIRQ3 | CA91CX42_LINT_VIRQ4 |
 			CA91CX42_LINT_VIRQ5 | CA91CX42_LINT_VIRQ6 |
 			CA91CX42_LINT_VIRQ7))
-		serviced |= ca91cx42_VIRQ_irqhandler(stat);
+		serviced |= ca91cx42_VIRQ_irqhandler(ca91cx42_bridge, stat);
 
 	/* Clear serviced interrupts */
-	iowrite32(stat, ca91cx42_bridge->base + LINT_STAT);
+	iowrite32(stat, bridge->base + LINT_STAT);
 
 	return IRQ_HANDLED;
 }
 
-static int ca91cx42_irq_init(struct vme_bridge *bridge)
+static int ca91cx42_irq_init(struct vme_bridge *ca91cx42_bridge)
 {
 	int result, tmp;
 	struct pci_dev *pdev;
+	struct ca91cx42_driver *bridge;
+
+	bridge = ca91cx42_bridge->driver_priv;
 
 	/* Need pdev */
-	pdev = container_of(bridge->parent, struct pci_dev, dev);
+	pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev);
 
 	/* Initialise list for VME bus errors */
-	INIT_LIST_HEAD(&(bridge->vme_errors));
+	INIT_LIST_HEAD(&(ca91cx42_bridge->vme_errors));
 
-	mutex_init(&(bridge->irq_mtx));
+	mutex_init(&(ca91cx42_bridge->irq_mtx));
 
 	/* Disable interrupts from PCI to VME */
 	iowrite32(0, bridge->base + VINT_EN);
@@ -232,7 +216,7 @@ static int ca91cx42_irq_init(struct vme_
 	iowrite32(0x00FFFFFF, bridge->base + LINT_STAT);
 
 	result = request_irq(pdev->irq, ca91cx42_irqhandler, IRQF_SHARED,
-			driver_name, pdev);
+			driver_name, ca91cx42_bridge);
 	if (result) {
 		dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n",
 		       pdev->irq);
@@ -254,15 +238,16 @@ static int ca91cx42_irq_init(struct vme_
 	return 0;
 }
 
-static void ca91cx42_irq_exit(struct pci_dev *pdev)
+static void ca91cx42_irq_exit(struct ca91cx42_driver *bridge,
+	struct pci_dev *pdev)
 {
 	/* Disable interrupts from PCI to VME */
-	iowrite32(0, ca91cx42_bridge->base + VINT_EN);
+	iowrite32(0, bridge->base + VINT_EN);
 
 	/* Disable PCI interrupts */
-	iowrite32(0, ca91cx42_bridge->base + LINT_EN);
+	iowrite32(0, bridge->base + LINT_EN);
 	/* Clear Any Pending PCI Interrupts */
-	iowrite32(0x00FFFFFF, ca91cx42_bridge->base + LINT_STAT);
+	iowrite32(0x00FFFFFF, bridge->base + LINT_STAT);
 
 	free_irq(pdev->irq, pdev);
 }
@@ -270,21 +255,25 @@ static void ca91cx42_irq_exit(struct pci
 /*
  * Set up an VME interrupt
  */
-void ca91cx42_irq_set(int level, int state, int sync)
+void ca91cx42_irq_set(struct vme_bridge *ca91cx42_bridge, int level, int state,
+	int sync)
 
 {
 	struct pci_dev *pdev;
 	u32 tmp;
+	struct ca91cx42_driver *bridge;
+
+	bridge = ca91cx42_bridge->driver_priv;
 
 	/* Enable IRQ level */
-	tmp = ioread32(ca91cx42_bridge->base + LINT_EN);
+	tmp = ioread32(bridge->base + LINT_EN);
 
 	if (state == 0)
 		tmp &= ~CA91CX42_LINT_VIRQ[level];
 	else
 		tmp |= CA91CX42_LINT_VIRQ[level];
 
-	iowrite32(tmp, ca91cx42_bridge->base + LINT_EN);
+	iowrite32(tmp, bridge->base + LINT_EN);
 
 	if ((state == 0) && (sync != 0)) {
 		pdev = container_of(ca91cx42_bridge->parent, struct pci_dev,
@@ -294,34 +283,38 @@ void ca91cx42_irq_set(int level, int sta
 	}
 }
 
-int ca91cx42_irq_generate(int level, int statid)
+int ca91cx42_irq_generate(struct vme_bridge *ca91cx42_bridge, int level,
+	int statid)
 {
 	u32 tmp;
+	struct ca91cx42_driver *bridge;
+
+	bridge = ca91cx42_bridge->driver_priv;
 
 	/* Universe can only generate even vectors */
 	if (statid & 1)
 		return -EINVAL;
 
-	mutex_lock(&(vme_int));
+	mutex_lock(&(bridge->vme_int));
 
-	tmp = ioread32(ca91cx42_bridge->base + VINT_EN);
+	tmp = ioread32(bridge->base + VINT_EN);
 
 	/* Set Status/ID */
-	iowrite32(statid << 24, ca91cx42_bridge->base + STATID);
+	iowrite32(statid << 24, bridge->base + STATID);
 
 	/* Assert VMEbus IRQ */
 	tmp = tmp | (1 << (level + 24));
-	iowrite32(tmp, ca91cx42_bridge->base + VINT_EN);
+	iowrite32(tmp, bridge->base + VINT_EN);
 
 	/* Wait for IACK */
-	wait_event_interruptible(iack_queue, 0);
+	wait_event_interruptible(bridge->iack_queue, 0);
 
 	/* Return interrupt to low state */
-	tmp = ioread32(ca91cx42_bridge->base + VINT_EN);
+	tmp = ioread32(bridge->base + VINT_EN);
 	tmp = tmp & ~(1 << (level + 24));
-	iowrite32(tmp, ca91cx42_bridge->base + VINT_EN);
+	iowrite32(tmp, bridge->base + VINT_EN);
 
-	mutex_unlock(&(vme_int));
+	mutex_unlock(&(bridge->vme_int));
 
 	return 0;
 }
@@ -330,9 +323,12 @@ int ca91cx42_slave_set(struct vme_slave_
 	unsigned long long vme_base, unsigned long long size,
 	dma_addr_t pci_base, vme_address_t aspace, vme_cycle_t cycle)
 {
-	unsigned int i, addr = 0, granularity = 0;
+	unsigned int i, addr = 0, granularity;
 	unsigned int temp_ctl = 0;
 	unsigned int vme_bound, pci_offset;
+	struct ca91cx42_driver *bridge;
+
+	bridge = image->parent->driver_priv;
 
 	i = image->number;
 
@@ -366,13 +362,9 @@ int ca91cx42_slave_set(struct vme_slave_
 	 * Bound address is a valid address for the window, adjust
 	 * accordingly
 	 */
-	vme_bound = vme_base + size - granularity;
+	vme_bound = vme_base + size;
 	pci_offset = pci_base - vme_base;
 
-	/* XXX Need to check that vme_base, vme_bound and pci_offset aren't
-	 * too big for registers
-	 */
-
 	if ((i == 0) || (i == 4))
 		granularity = 0x1000;
 	else
@@ -392,26 +384,14 @@ int ca91cx42_slave_set(struct vme_slave_
 	}
 
 	/* Disable while we are mucking around */
-	temp_ctl = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]);
+	temp_ctl = ioread32(bridge->base + CA91CX42_VSI_CTL[i]);
 	temp_ctl &= ~CA91CX42_VSI_CTL_EN;
-	iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]);
+	iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]);
 
 	/* Setup mapping */
-	iowrite32(vme_base, ca91cx42_bridge->base + CA91CX42_VSI_BS[i]);
-	iowrite32(vme_bound, ca91cx42_bridge->base + CA91CX42_VSI_BD[i]);
-	iowrite32(pci_offset, ca91cx42_bridge->base + CA91CX42_VSI_TO[i]);
-
-/* XXX Prefetch stuff currently unsupported */
-#if 0
-	if (vmeIn->wrPostEnable)
-		temp_ctl |= CA91CX42_VSI_CTL_PWEN;
-	if (vmeIn->prefetchEnable)
-		temp_ctl |= CA91CX42_VSI_CTL_PREN;
-	if (vmeIn->rmwLock)
-		temp_ctl |= CA91CX42_VSI_CTL_LLRMW;
-	if (vmeIn->data64BitCapable)
-		temp_ctl |= CA91CX42_VSI_CTL_LD64EN;
-#endif
+	iowrite32(vme_base, bridge->base + CA91CX42_VSI_BS[i]);
+	iowrite32(vme_bound, bridge->base + CA91CX42_VSI_BD[i]);
+	iowrite32(pci_offset, bridge->base + CA91CX42_VSI_TO[i]);
 
 	/* Setup address space */
 	temp_ctl &= ~CA91CX42_VSI_CTL_VAS_M;
@@ -429,12 +409,12 @@ int ca91cx42_slave_set(struct vme_slave_
 		temp_ctl |= CA91CX42_VSI_CTL_PGM_DATA;
 
 	/* Write ctl reg without enable */
-	iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]);
+	iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]);
 
 	if (enabled)
 		temp_ctl |= CA91CX42_VSI_CTL_EN;
 
-	iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]);
+	iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]);
 
 	return 0;
 }
@@ -445,6 +425,9 @@ int ca91cx42_slave_get(struct vme_slave_
 {
 	unsigned int i, granularity = 0, ctl = 0;
 	unsigned long long vme_bound, pci_offset;
+	struct ca91cx42_driver *bridge;
+
+	bridge = image->parent->driver_priv;
 
 	i = image->number;
 
@@ -454,11 +437,11 @@ int ca91cx42_slave_get(struct vme_slave_
 		granularity = 0x10000;
 
 	/* Read Registers */
-	ctl = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]);
+	ctl = ioread32(bridge->base + CA91CX42_VSI_CTL[i]);
 
-	*vme_base = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_BS[i]);
-	vme_bound = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_BD[i]);
-	pci_offset = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_TO[i]);
+	*vme_base = ioread32(bridge->base + CA91CX42_VSI_BS[i]);
+	vme_bound = ioread32(bridge->base + CA91CX42_VSI_BD[i]);
+	pci_offset = ioread32(bridge->base + CA91CX42_VSI_TO[i]);
 
 	*pci_base = (dma_addr_t)vme_base + pci_offset;
 	*size = (unsigned long long)((vme_bound - *vme_base) + granularity);
@@ -502,6 +485,9 @@ static int ca91cx42_alloc_resource(struc
 	unsigned long long existing_size;
 	int retval = 0;
 	struct pci_dev *pdev;
+	struct vme_bridge *ca91cx42_bridge;
+
+	ca91cx42_bridge = image->parent;
 
 	/* Find pci_dev container of dev */
 	if (ca91cx42_bridge->parent == NULL) {
@@ -510,8 +496,8 @@ static int ca91cx42_alloc_resource(struc
 	}
 	pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev);
 
-	existing_size = (unsigned long long)(image->pci_resource.end -
-		image->pci_resource.start);
+	existing_size = (unsigned long long)(image->bus_resource.end -
+		image->bus_resource.start);
 
 	/* If the existing size is OK, return */
 	if (existing_size == (size - 1))
@@ -520,15 +506,15 @@ static int ca91cx42_alloc_resource(struc
 	if (existing_size != 0) {
 		iounmap(image->kern_base);
 		image->kern_base = NULL;
-		if (image->pci_resource.name != NULL)
-			kfree(image->pci_resource.name);
-		release_resource(&(image->pci_resource));
-		memset(&(image->pci_resource), 0, sizeof(struct resource));
+		if (image->bus_resource.name != NULL)
+			kfree(image->bus_resource.name);
+		release_resource(&(image->bus_resource));
+		memset(&(image->bus_resource), 0, sizeof(struct resource));
 	}
 
-	if (image->pci_resource.name == NULL) {
-		image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
-		if (image->pci_resource.name == NULL) {
+	if (image->bus_resource.name == NULL) {
+		image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
+		if (image->bus_resource.name == NULL) {
 			printk(KERN_ERR "Unable to allocate memory for resource"
 				" name\n");
 			retval = -ENOMEM;
@@ -536,26 +522,26 @@ static int ca91cx42_alloc_resource(struc
 		}
 	}
 
-	sprintf((char *)image->pci_resource.name, "%s.%d",
+	sprintf((char *)image->bus_resource.name, "%s.%d",
 		ca91cx42_bridge->name, image->number);
 
-	image->pci_resource.start = 0;
-	image->pci_resource.end = (unsigned long)size;
-	image->pci_resource.flags = IORESOURCE_MEM;
+	image->bus_resource.start = 0;
+	image->bus_resource.end = (unsigned long)size;
+	image->bus_resource.flags = IORESOURCE_MEM;
 
 	retval = pci_bus_alloc_resource(pdev->bus,
-		&(image->pci_resource), size, size, PCIBIOS_MIN_MEM,
+		&(image->bus_resource), size, size, PCIBIOS_MIN_MEM,
 		0, NULL, NULL);
 	if (retval) {
 		printk(KERN_ERR "Failed to allocate mem resource for "
 			"window %d size 0x%lx start 0x%lx\n",
 			image->number, (unsigned long)size,
-			(unsigned long)image->pci_resource.start);
+			(unsigned long)image->bus_resource.start);
 		goto err_resource;
 	}
 
 	image->kern_base = ioremap_nocache(
-		image->pci_resource.start, size);
+		image->bus_resource.start, size);
 	if (image->kern_base == NULL) {
 		printk(KERN_ERR "Failed to remap resource\n");
 		retval = -ENOMEM;
@@ -567,24 +553,24 @@ static int ca91cx42_alloc_resource(struc
 	iounmap(image->kern_base);
 	image->kern_base = NULL;
 err_remap:
-	release_resource(&(image->pci_resource));
+	release_resource(&(image->bus_resource));
 err_resource:
-	kfree(image->pci_resource.name);
-	memset(&(image->pci_resource), 0, sizeof(struct resource));
+	kfree(image->bus_resource.name);
+	memset(&(image->bus_resource), 0, sizeof(struct resource));
 err_name:
 	return retval;
 }
 
 /*
- *  * Free and unmap PCI Resource
- *   */
+ * Free and unmap PCI Resource
+ */
 static void ca91cx42_free_resource(struct vme_master_resource *image)
 {
 	iounmap(image->kern_base);
 	image->kern_base = NULL;
-	release_resource(&(image->pci_resource));
-	kfree(image->pci_resource.name);
-	memset(&(image->pci_resource), 0, sizeof(struct resource));
+	release_resource(&(image->bus_resource));
+	kfree(image->bus_resource.name);
+	memset(&(image->bus_resource), 0, sizeof(struct resource));
 }
 
 
@@ -593,17 +579,27 @@ int ca91cx42_master_set(struct vme_maste
 	vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
 {
 	int retval = 0;
-	unsigned int i;
+	unsigned int i, granularity = 0;
 	unsigned int temp_ctl = 0;
 	unsigned long long pci_bound, vme_offset, pci_base;
+	struct ca91cx42_driver *bridge;
+
+	bridge = image->parent->driver_priv;
+
+	i = image->number;
+
+	if ((i == 0) || (i == 4))
+		granularity = 0x1000;
+	else
+		granularity = 0x10000;
 
 	/* Verify input data */
-	if (vme_base & 0xFFF) {
+	if (vme_base & (granularity - 1)) {
 		printk(KERN_ERR "Invalid VME Window alignment\n");
 		retval = -EINVAL;
 		goto err_window;
 	}
-	if (size & 0xFFF) {
+	if (size & (granularity - 1)) {
 		printk(KERN_ERR "Invalid VME Window alignment\n");
 		retval = -EINVAL;
 		goto err_window;
@@ -611,9 +607,6 @@ int ca91cx42_master_set(struct vme_maste
 
 	spin_lock(&(image->lock));
 
-	/* XXX We should do this much later, so that we can exit without
-	 *     needing to redo the mapping...
-	 */
 	/*
 	 * Let's allocate the resource here rather than further up the stack as
 	 * it avoids pushing loads of bus dependant stuff up the stack
@@ -627,27 +620,19 @@ int ca91cx42_master_set(struct vme_maste
 		goto err_res;
 	}
 
-	pci_base = (unsigned long long)image->pci_resource.start;
+	pci_base = (unsigned long long)image->bus_resource.start;
 
 	/*
 	 * Bound address is a valid address for the window, adjust
 	 * according to window granularity.
 	 */
-	pci_bound = pci_base + (size - 0x1000);
+	pci_bound = pci_base + size;
 	vme_offset = vme_base - pci_base;
 
-	i = image->number;
-
 	/* Disable while we are mucking around */
-	temp_ctl = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]);
+	temp_ctl = ioread32(bridge->base + CA91CX42_LSI_CTL[i]);
 	temp_ctl &= ~CA91CX42_LSI_CTL_EN;
-	iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]);
-
-/* XXX Prefetch stuff currently unsupported */
-#if 0
-	if (vmeOut->wrPostEnable)
-		temp_ctl |= 0x40000000;
-#endif
+	iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]);
 
 	/* Setup cycle types */
 	temp_ctl &= ~CA91CX42_LSI_CTL_VCT_M;
@@ -718,17 +703,17 @@ int ca91cx42_master_set(struct vme_maste
 		temp_ctl |= CA91CX42_LSI_CTL_PGM_PGM;
 
 	/* Setup mapping */
-	iowrite32(pci_base, ca91cx42_bridge->base + CA91CX42_LSI_BS[i]);
-	iowrite32(pci_bound, ca91cx42_bridge->base + CA91CX42_LSI_BD[i]);
-	iowrite32(vme_offset, ca91cx42_bridge->base + CA91CX42_LSI_TO[i]);
+	iowrite32(pci_base, bridge->base + CA91CX42_LSI_BS[i]);
+	iowrite32(pci_bound, bridge->base + CA91CX42_LSI_BD[i]);
+	iowrite32(vme_offset, bridge->base + CA91CX42_LSI_TO[i]);
 
 	/* Write ctl reg without enable */
-	iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]);
+	iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]);
 
 	if (enabled)
 		temp_ctl |= CA91CX42_LSI_CTL_EN;
 
-	iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]);
+	iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]);
 
 	spin_unlock(&(image->lock));
 	return 0;
@@ -747,17 +732,20 @@ int __ca91cx42_master_get(struct vme_mas
 {
 	unsigned int i, ctl;
 	unsigned long long pci_base, pci_bound, vme_offset;
+	struct ca91cx42_driver *bridge;
+
+	bridge = image->parent->driver_priv;
 
 	i = image->number;
 
-	ctl = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]);
+	ctl = ioread32(bridge->base + CA91CX42_LSI_CTL[i]);
 
-	pci_base = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BS[i]);
-	vme_offset = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_TO[i]);
-	pci_bound = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BD[i]);
+	pci_base = ioread32(bridge->base + CA91CX42_LSI_BS[i]);
+	vme_offset = ioread32(bridge->base + CA91CX42_LSI_TO[i]);
+	pci_bound = ioread32(bridge->base + CA91CX42_LSI_BD[i]);
 
 	*vme_base = pci_base + vme_offset;
-	*size = (pci_bound - pci_base) + 0x1000;
+	*size = (unsigned long long)(pci_bound - pci_base);
 
 	*enabled = 0;
 	*aspace = 0;
@@ -822,12 +810,6 @@ int __ca91cx42_master_get(struct vme_mas
 		break;
 	}
 
-/* XXX Prefetch stuff currently unsupported */
-#if 0
-	if (ctl & 0x40000000)
-		vmeOut->wrPostEnable = 1;
-#endif
-
 	return 0;
 }
 
@@ -850,7 +832,7 @@ int ca91cx42_master_get(struct vme_maste
 ssize_t ca91cx42_master_read(struct vme_master_resource *image, void *buf,
 	size_t count, loff_t offset)
 {
-	int retval;
+	ssize_t retval;
 
 	spin_lock(&(image->lock));
 
@@ -877,12 +859,528 @@ ssize_t ca91cx42_master_write(struct vme
 	return retval;
 }
 
-int ca91cx42_slot_get(void)
+unsigned int ca91cx42_master_rmw(struct vme_master_resource *image,
+	unsigned int mask, unsigned int compare, unsigned int swap,
+	loff_t offset)
+{
+	u32 pci_addr, result;
+	int i;
+	struct ca91cx42_driver *bridge;
+	struct device *dev;
+
+	bridge = image->parent->driver_priv;
+	dev = image->parent->parent;
+
+	/* Find the PCI address that maps to the desired VME address */
+	i = image->number;
+
+	/* Locking as we can only do one of these at a time */
+	mutex_lock(&(bridge->vme_rmw));
+
+	/* Lock image */
+	spin_lock(&(image->lock));
+
+	pci_addr = (u32)image->kern_base + offset;
+
+	/* Address must be 4-byte aligned */
+	if (pci_addr & 0x3) {
+		dev_err(dev, "RMW Address not 4-byte aligned\n");
+		return -EINVAL;
+	}
+
+	/* Ensure RMW Disabled whilst configuring */
+	iowrite32(0, bridge->base + SCYC_CTL);
+
+	/* Configure registers */
+	iowrite32(mask, bridge->base + SCYC_EN);
+	iowrite32(compare, bridge->base + SCYC_CMP);
+	iowrite32(swap, bridge->base + SCYC_SWP);
+	iowrite32(pci_addr, bridge->base + SCYC_ADDR);
+
+	/* Enable RMW */
+	iowrite32(CA91CX42_SCYC_CTL_CYC_RMW, bridge->base + SCYC_CTL);
+
+	/* Kick process off with a read to the required address. */
+	result = ioread32(image->kern_base + offset);
+
+	/* Disable RMW */
+	iowrite32(0, bridge->base + SCYC_CTL);
+
+	spin_unlock(&(image->lock));
+
+	mutex_unlock(&(bridge->vme_rmw));
+
+	return result;
+}
+
+int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
+	struct vme_dma_attr *dest, size_t count)
+{
+	struct ca91cx42_dma_entry *entry, *prev;
+	struct vme_dma_pci *pci_attr;
+	struct vme_dma_vme *vme_attr;
+	dma_addr_t desc_ptr;
+	int retval = 0;
+
+	/* XXX descriptor must be aligned on 64-bit boundaries */
+	entry = (struct ca91cx42_dma_entry *)
+		kmalloc(sizeof(struct ca91cx42_dma_entry), GFP_KERNEL);
+	if (entry == NULL) {
+		printk(KERN_ERR "Failed to allocate memory for dma resource "
+			"structure\n");
+		retval = -ENOMEM;
+		goto err_mem;
+	}
+
+	/* Test descriptor alignment */
+	if ((unsigned long)&(entry->descriptor) & CA91CX42_DCPP_M) {
+		printk("Descriptor not aligned to 16 byte boundary as "
+			"required: %p\n", &(entry->descriptor));
+		retval = -EINVAL;
+		goto err_align;
+	}
+
+	memset(&(entry->descriptor), 0, sizeof(struct ca91cx42_dma_descriptor));
+
+	if (dest->type == VME_DMA_VME) {
+		entry->descriptor.dctl |= CA91CX42_DCTL_L2V;
+		vme_attr = (struct vme_dma_vme *)dest->private;
+		pci_attr = (struct vme_dma_pci *)src->private;
+	} else {
+		vme_attr = (struct vme_dma_vme *)src->private;
+		pci_attr = (struct vme_dma_pci *)dest->private;
+	}
+
+	/* Check we can do fullfill required attributes */
+	if ((vme_attr->aspace & ~(VME_A16 | VME_A24 | VME_A32 | VME_USER1 |
+		VME_USER2)) != 0) {
+
+		printk(KERN_ERR "Unsupported cycle type\n");
+		retval = -EINVAL;
+		goto err_aspace;
+	}
+
+	if ((vme_attr->cycle & ~(VME_SCT | VME_BLT | VME_SUPER | VME_USER |
+		VME_PROG | VME_DATA)) != 0) {
+
+		printk(KERN_ERR "Unsupported cycle type\n");
+		retval = -EINVAL;
+		goto err_cycle;
+	}
+
+	/* Check to see if we can fullfill source and destination */
+	if (!(((src->type == VME_DMA_PCI) && (dest->type == VME_DMA_VME)) ||
+		((src->type == VME_DMA_VME) && (dest->type == VME_DMA_PCI)))) {
+
+		printk(KERN_ERR "Cannot perform transfer with this "
+			"source-destination combination\n");
+		retval = -EINVAL;
+		goto err_direct;
+	}
+
+	/* Setup cycle types */
+	if (vme_attr->cycle & VME_BLT)
+		entry->descriptor.dctl |= CA91CX42_DCTL_VCT_BLT;
+
+	/* Setup data width */
+	switch (vme_attr->dwidth) {
+	case VME_D8:
+		entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D8;
+		break;
+	case VME_D16:
+		entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D16;
+		break;
+	case VME_D32:
+		entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D32;
+		break;
+	case VME_D64:
+		entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D64;
+		break;
+	default:
+		printk(KERN_ERR "Invalid data width\n");
+		return -EINVAL;
+	}
+
+	/* Setup address space */
+	switch (vme_attr->aspace) {
+	case VME_A16:
+		entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A16;
+		break;
+	case VME_A24:
+		entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A24;
+		break;
+	case VME_A32:
+		entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A32;
+		break;
+	case VME_USER1:
+		entry->descriptor.dctl |= CA91CX42_DCTL_VAS_USER1;
+		break;
+	case VME_USER2:
+		entry->descriptor.dctl |= CA91CX42_DCTL_VAS_USER2;
+		break;
+	default:
+		printk(KERN_ERR "Invalid address space\n");
+		return -EINVAL;
+		break;
+	}
+
+	if (vme_attr->cycle & VME_SUPER)
+		entry->descriptor.dctl |= CA91CX42_DCTL_SUPER_SUPR;
+	if (vme_attr->cycle & VME_PROG)
+		entry->descriptor.dctl |= CA91CX42_DCTL_PGM_PGM;
+
+	entry->descriptor.dtbc = count;
+	entry->descriptor.dla = pci_attr->address;
+	entry->descriptor.dva = vme_attr->address;
+	entry->descriptor.dcpp = CA91CX42_DCPP_NULL;
+
+	/* Add to list */
+	list_add_tail(&(entry->list), &(list->entries));
+
+	/* Fill out previous descriptors "Next Address" */
+	if (entry->list.prev != &(list->entries)) {
+		prev = list_entry(entry->list.prev, struct ca91cx42_dma_entry,
+			list);
+		/* We need the bus address for the pointer */
+		desc_ptr = virt_to_bus(&(entry->descriptor));
+		prev->descriptor.dcpp = desc_ptr & ~CA91CX42_DCPP_M;
+	}
+
+	return 0;
+
+err_cycle:
+err_aspace:
+err_direct:
+err_align:
+	kfree(entry);
+err_mem:
+	return retval;
+}
+
+static int ca91cx42_dma_busy(struct vme_bridge *ca91cx42_bridge)
+{
+	u32 tmp;
+	struct ca91cx42_driver *bridge;
+
+	bridge = ca91cx42_bridge->driver_priv;
+
+	tmp = ioread32(bridge->base + DGCS);
+
+	if (tmp & CA91CX42_DGCS_ACT)
+		return 0;
+	else
+		return 1;
+}
+
+int ca91cx42_dma_list_exec(struct vme_dma_list *list)
+{
+	struct vme_dma_resource *ctrlr;
+	struct ca91cx42_dma_entry *entry;
+	int retval = 0;
+	dma_addr_t bus_addr;
+	u32 val;
+
+	struct ca91cx42_driver *bridge;
+
+	ctrlr = list->parent;
+
+	bridge = ctrlr->parent->driver_priv;
+
+	mutex_lock(&(ctrlr->mtx));
+
+	if (!(list_empty(&(ctrlr->running)))) {
+		/*
+		 * XXX We have an active DMA transfer and currently haven't
+		 *     sorted out the mechanism for "pending" DMA transfers.
+		 *     Return busy.
+		 */
+		/* Need to add to pending here */
+		mutex_unlock(&(ctrlr->mtx));
+		return -EBUSY;
+	} else {
+		list_add(&(list->list), &(ctrlr->running));
+	}
+
+	/* Get first bus address and write into registers */
+	entry = list_first_entry(&(list->entries), struct ca91cx42_dma_entry,
+		list);
+
+	bus_addr = virt_to_bus(&(entry->descriptor));
+
+	mutex_unlock(&(ctrlr->mtx));
+
+	iowrite32(0, bridge->base + DTBC);
+	iowrite32(bus_addr & ~CA91CX42_DCPP_M, bridge->base + DCPP);
+
+	/* Start the operation */
+	val = ioread32(bridge->base + DGCS);
+
+	/* XXX Could set VMEbus On and Off Counters here */
+	val &= (CA91CX42_DGCS_VON_M | CA91CX42_DGCS_VOFF_M);
+
+	val |= (CA91CX42_DGCS_CHAIN | CA91CX42_DGCS_STOP | CA91CX42_DGCS_HALT |
+		CA91CX42_DGCS_DONE | CA91CX42_DGCS_LERR | CA91CX42_DGCS_VERR |
+		CA91CX42_DGCS_PERR);
+
+	iowrite32(val, bridge->base + DGCS);
+
+	val |= CA91CX42_DGCS_GO;
+
+	iowrite32(val, bridge->base + DGCS);
+
+	wait_event_interruptible(bridge->dma_queue,
+		ca91cx42_dma_busy(ctrlr->parent));
+
+	/*
+	 * Read status register, this register is valid until we kick off a
+	 * new transfer.
+	 */
+	val = ioread32(bridge->base + DGCS);
+
+	if (val & (CA91CX42_DGCS_LERR | CA91CX42_DGCS_VERR |
+		CA91CX42_DGCS_PERR)) {
+
+		printk(KERN_ERR "ca91c042: DMA Error. DGCS=%08X\n", val);
+		val = ioread32(bridge->base + DCTL);
+	}
+
+	/* Remove list from running list */
+	mutex_lock(&(ctrlr->mtx));
+	list_del(&(list->list));
+	mutex_unlock(&(ctrlr->mtx));
+
+	return retval;
+
+}
+
+int ca91cx42_dma_list_empty(struct vme_dma_list *list)
+{
+	struct list_head *pos, *temp;
+	struct ca91cx42_dma_entry *entry;
+
+	/* detach and free each entry */
+	list_for_each_safe(pos, temp, &(list->entries)) {
+		list_del(pos);
+		entry = list_entry(pos, struct ca91cx42_dma_entry, list);
+		kfree(entry);
+	}
+
+	return 0;
+}
+
+/*
+ * All 4 location monitors reside at the same base - this is therefore a
+ * system wide configuration.
+ *
+ * This does not enable the LM monitor - that should be done when the first
+ * callback is attached and disabled when the last callback is removed.
+ */
+int ca91cx42_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base,
+	vme_address_t aspace, vme_cycle_t cycle)
+{
+	u32 temp_base, lm_ctl = 0;
+	int i;
+	struct ca91cx42_driver *bridge;
+	struct device *dev;
+
+	bridge = lm->parent->driver_priv;
+	dev = lm->parent->parent;
+
+	/* Check the alignment of the location monitor */
+	temp_base = (u32)lm_base;
+	if (temp_base & 0xffff) {
+		dev_err(dev, "Location monitor must be aligned to 64KB "
+			"boundary");
+		return -EINVAL;
+	}
+
+	mutex_lock(&(lm->mtx));
+
+	/* If we already have a callback attached, we can't move it! */
+	for (i = 0; i < lm->monitors; i++) {
+		if (bridge->lm_callback[i] != NULL) {
+			mutex_unlock(&(lm->mtx));
+			dev_err(dev, "Location monitor callback attached, "
+				"can't reset\n");
+			return -EBUSY;
+		}
+	}
+
+	switch (aspace) {
+	case VME_A16:
+		lm_ctl |= CA91CX42_LM_CTL_AS_A16;
+		break;
+	case VME_A24:
+		lm_ctl |= CA91CX42_LM_CTL_AS_A24;
+		break;
+	case VME_A32:
+		lm_ctl |= CA91CX42_LM_CTL_AS_A32;
+		break;
+	default:
+		mutex_unlock(&(lm->mtx));
+		dev_err(dev, "Invalid address space\n");
+		return -EINVAL;
+		break;
+	}
+
+	if (cycle & VME_SUPER)
+		lm_ctl |= CA91CX42_LM_CTL_SUPR;
+	if (cycle & VME_USER)
+		lm_ctl |= CA91CX42_LM_CTL_NPRIV;
+	if (cycle & VME_PROG)
+		lm_ctl |= CA91CX42_LM_CTL_PGM;
+	if (cycle & VME_DATA)
+		lm_ctl |= CA91CX42_LM_CTL_DATA;
+
+	iowrite32(lm_base, bridge->base + LM_BS);
+	iowrite32(lm_ctl, bridge->base + LM_CTL);
+
+	mutex_unlock(&(lm->mtx));
+
+	return 0;
+}
+
+/* Get configuration of the callback monitor and return whether it is enabled
+ * or disabled.
+ */
+int ca91cx42_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base,
+	vme_address_t *aspace, vme_cycle_t *cycle)
+{
+	u32 lm_ctl, enabled = 0;
+	struct ca91cx42_driver *bridge;
+
+	bridge = lm->parent->driver_priv;
+
+	mutex_lock(&(lm->mtx));
+
+	*lm_base = (unsigned long long)ioread32(bridge->base + LM_BS);
+	lm_ctl = ioread32(bridge->base + LM_CTL);
+
+	if (lm_ctl & CA91CX42_LM_CTL_EN)
+		enabled = 1;
+
+	if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A16)
+		*aspace = VME_A16;
+	if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A24)
+		*aspace = VME_A24;
+	if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A32)
+		*aspace = VME_A32;
+
+	*cycle = 0;
+	if (lm_ctl & CA91CX42_LM_CTL_SUPR)
+		*cycle |= VME_SUPER;
+	if (lm_ctl & CA91CX42_LM_CTL_NPRIV)
+		*cycle |= VME_USER;
+	if (lm_ctl & CA91CX42_LM_CTL_PGM)
+		*cycle |= VME_PROG;
+	if (lm_ctl & CA91CX42_LM_CTL_DATA)
+		*cycle |= VME_DATA;
+
+	mutex_unlock(&(lm->mtx));
+
+	return enabled;
+}
+
+/*
+ * Attach a callback to a specific location monitor.
+ *
+ * Callback will be passed the monitor triggered.
+ */
+int ca91cx42_lm_attach(struct vme_lm_resource *lm, int monitor,
+	void (*callback)(int))
+{
+	u32 lm_ctl, tmp;
+	struct ca91cx42_driver *bridge;
+	struct device *dev;
+
+	bridge = lm->parent->driver_priv;
+	dev = lm->parent->parent;
+
+	mutex_lock(&(lm->mtx));
+
+	/* Ensure that the location monitor is configured - need PGM or DATA */
+	lm_ctl = ioread32(bridge->base + LM_CTL);
+	if ((lm_ctl & (CA91CX42_LM_CTL_PGM | CA91CX42_LM_CTL_DATA)) == 0) {
+		mutex_unlock(&(lm->mtx));
+		dev_err(dev, "Location monitor not properly configured\n");
+		return -EINVAL;
+	}
+
+	/* Check that a callback isn't already attached */
+	if (bridge->lm_callback[monitor] != NULL) {
+		mutex_unlock(&(lm->mtx));
+		dev_err(dev, "Existing callback attached\n");
+		return -EBUSY;
+	}
+
+	/* Attach callback */
+	bridge->lm_callback[monitor] = callback;
+
+	/* Enable Location Monitor interrupt */
+	tmp = ioread32(bridge->base + LINT_EN);
+	tmp |= CA91CX42_LINT_LM[monitor];
+	iowrite32(tmp, bridge->base + LINT_EN);
+
+	/* Ensure that global Location Monitor Enable set */
+	if ((lm_ctl & CA91CX42_LM_CTL_EN) == 0) {
+		lm_ctl |= CA91CX42_LM_CTL_EN;
+		iowrite32(lm_ctl, bridge->base + LM_CTL);
+	}
+
+	mutex_unlock(&(lm->mtx));
+
+	return 0;
+}
+
+/*
+ * Detach a callback function forn a specific location monitor.
+ */
+int ca91cx42_lm_detach(struct vme_lm_resource *lm, int monitor)
+{
+	u32 tmp;
+	struct ca91cx42_driver *bridge;
+
+	bridge = lm->parent->driver_priv;
+
+	mutex_lock(&(lm->mtx));
+
+	/* Disable Location Monitor and ensure previous interrupts are clear */
+	tmp = ioread32(bridge->base + LINT_EN);
+	tmp &= ~CA91CX42_LINT_LM[monitor];
+	iowrite32(tmp, bridge->base + LINT_EN);
+
+	iowrite32(CA91CX42_LINT_LM[monitor],
+		 bridge->base + LINT_STAT);
+
+	/* Detach callback */
+	bridge->lm_callback[monitor] = NULL;
+
+	/* If all location monitors disabled, disable global Location Monitor */
+	if ((tmp & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 |
+			CA91CX42_LINT_LM3)) == 0) {
+		tmp = ioread32(bridge->base + LM_CTL);
+		tmp &= ~CA91CX42_LM_CTL_EN;
+		iowrite32(tmp, bridge->base + LM_CTL);
+	}
+
+	mutex_unlock(&(lm->mtx));
+
+	return 0;
+}
+
+int ca91cx42_slot_get(struct vme_bridge *ca91cx42_bridge)
 {
 	u32 slot = 0;
+	struct ca91cx42_driver *bridge;
+
+	bridge = ca91cx42_bridge->driver_priv;
+
+	if (!geoid) {
+		slot = ioread32(bridge->base + VCSR_BS);
+		slot = ((slot & CA91CX42_VCSR_BS_SLOT_M) >> 27);
+	} else
+		slot = geoid;
 
-	slot = ioread32(ca91cx42_bridge->base + VCSR_BS);
-	slot = ((slot & CA91CX42_VCSR_BS_SLOT_M) >> 27);
 	return (int)slot;
 
 }
@@ -900,19 +1398,21 @@ static int __init ca91cx42_init(void)
  * Auto-ID or Geographic address. This function ensures that the window is
  * enabled at an offset consistent with the boards geopgraphic address.
  */
-static int ca91cx42_crcsr_init(struct pci_dev *pdev)
+static int ca91cx42_crcsr_init(struct vme_bridge *ca91cx42_bridge,
+	struct pci_dev *pdev)
 {
 	unsigned int crcsr_addr;
 	int tmp, slot;
+	struct ca91cx42_driver *bridge;
+
+	bridge = ca91cx42_bridge->driver_priv;
+
+	slot = ca91cx42_slot_get(ca91cx42_bridge);
+
+	/* Write CSR Base Address if slot ID is supplied as a module param */
+	if (geoid)
+		iowrite32(geoid << 27, bridge->base + VCSR_BS);
 
-/* XXX We may need to set this somehow as the Universe II does not support
- *     geographical addressing.
- */
-#if 0
-	if (vme_slotnum != -1)
-		iowrite32(vme_slotnum << 27, ca91cx42_bridge->base + VCSR_BS);
-#endif
-	slot = ca91cx42_slot_get();
 	dev_info(&pdev->dev, "CR/CSR Offset: %d\n", slot);
 	if (slot == 0) {
 		dev_err(&pdev->dev, "Slot number is unset, not configuring "
@@ -921,39 +1421,44 @@ static int ca91cx42_crcsr_init(struct pc
 	}
 
 	/* Allocate mem for CR/CSR image */
-	crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE,
-		&crcsr_bus);
-	if (crcsr_kernel == NULL) {
+	bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE,
+		&(bridge->crcsr_bus));
+	if (bridge->crcsr_kernel == NULL) {
 		dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR "
 			"image\n");
 		return -ENOMEM;
 	}
 
-	memset(crcsr_kernel, 0, VME_CRCSR_BUF_SIZE);
+	memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE);
 
 	crcsr_addr = slot * (512 * 1024);
-	iowrite32(crcsr_bus - crcsr_addr, ca91cx42_bridge->base + VCSR_TO);
+	iowrite32(bridge->crcsr_bus - crcsr_addr, bridge->base + VCSR_TO);
 
-	tmp = ioread32(ca91cx42_bridge->base + VCSR_CTL);
+	tmp = ioread32(bridge->base + VCSR_CTL);
 	tmp |= CA91CX42_VCSR_CTL_EN;
-	iowrite32(tmp, ca91cx42_bridge->base + VCSR_CTL);
+	iowrite32(tmp, bridge->base + VCSR_CTL);
 
 	return 0;
 }
 
-static void ca91cx42_crcsr_exit(struct pci_dev *pdev)
+static void ca91cx42_crcsr_exit(struct vme_bridge *ca91cx42_bridge,
+	struct pci_dev *pdev)
 {
 	u32 tmp;
+	struct ca91cx42_driver *bridge;
+
+	bridge = ca91cx42_bridge->driver_priv;
 
 	/* Turn off CR/CSR space */
-	tmp = ioread32(ca91cx42_bridge->base + VCSR_CTL);
+	tmp = ioread32(bridge->base + VCSR_CTL);
 	tmp &= ~CA91CX42_VCSR_CTL_EN;
-	iowrite32(tmp, ca91cx42_bridge->base + VCSR_CTL);
+	iowrite32(tmp, bridge->base + VCSR_CTL);
 
 	/* Free image */
-	iowrite32(0, ca91cx42_bridge->base + VCSR_TO);
+	iowrite32(0, bridge->base + VCSR_TO);
 
-	pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, crcsr_kernel, crcsr_bus);
+	pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel,
+		bridge->crcsr_bus);
 }
 
 static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -961,11 +1466,11 @@ static int ca91cx42_probe(struct pci_dev
 	int retval, i;
 	u32 data;
 	struct list_head *pos = NULL;
+	struct vme_bridge *ca91cx42_bridge;
+	struct ca91cx42_driver *ca91cx42_device;
 	struct vme_master_resource *master_image;
 	struct vme_slave_resource *slave_image;
-#if 0
 	struct vme_dma_resource *dma_ctrlr;
-#endif
 	struct vme_lm_resource *lm;
 
 	/* We want to support more than one of each bridge so we need to
@@ -982,6 +1487,19 @@ static int ca91cx42_probe(struct pci_dev
 
 	memset(ca91cx42_bridge, 0, sizeof(struct vme_bridge));
 
+	ca91cx42_device = kmalloc(sizeof(struct ca91cx42_driver), GFP_KERNEL);
+
+	if (ca91cx42_device == NULL) {
+		dev_err(&pdev->dev, "Failed to allocate memory for device "
+			"structure\n");
+		retval = -ENOMEM;
+		goto err_driver;
+	}
+
+	memset(ca91cx42_device, 0, sizeof(struct ca91cx42_driver));
+
+	ca91cx42_bridge->driver_priv = ca91cx42_device;
+
 	/* Enable the device */
 	retval = pci_enable_device(pdev);
 	if (retval) {
@@ -997,16 +1515,16 @@ static int ca91cx42_probe(struct pci_dev
 	}
 
 	/* map registers in BAR 0 */
-	ca91cx42_bridge->base = ioremap_nocache(pci_resource_start(pdev, 0),
+	ca91cx42_device->base = ioremap_nocache(pci_resource_start(pdev, 0),
 		4096);
-	if (!ca91cx42_bridge->base) {
+	if (!ca91cx42_device->base) {
 		dev_err(&pdev->dev, "Unable to remap CRG region\n");
 		retval = -EIO;
 		goto err_remap;
 	}
 
 	/* Check to see if the mapping worked out */
-	data = ioread32(ca91cx42_bridge->base + CA91CX42_PCI_ID) & 0x0000FFFF;
+	data = ioread32(ca91cx42_device->base + CA91CX42_PCI_ID) & 0x0000FFFF;
 	if (data != PCI_VENDOR_ID_TUNDRA) {
 		dev_err(&pdev->dev, "PCI_ID check failed\n");
 		retval = -EIO;
@@ -1014,11 +1532,10 @@ static int ca91cx42_probe(struct pci_dev
 	}
 
 	/* Initialize wait queues & mutual exclusion flags */
-	/* XXX These need to be moved to the vme_bridge structure */
-	init_waitqueue_head(&dma_queue);
-	init_waitqueue_head(&iack_queue);
-	mutex_init(&(vme_int));
-	mutex_init(&(vme_rmw));
+	init_waitqueue_head(&(ca91cx42_device->dma_queue));
+	init_waitqueue_head(&(ca91cx42_device->iack_queue));
+	mutex_init(&(ca91cx42_device->vme_int));
+	mutex_init(&(ca91cx42_device->vme_rmw));
 
 	ca91cx42_bridge->parent = &(pdev->dev);
 	strcpy(ca91cx42_bridge->name, driver_name);
@@ -1050,7 +1567,7 @@ static int ca91cx42_probe(struct pci_dev
 		master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
 			VME_SUPER | VME_USER | VME_PROG | VME_DATA;
 		master_image->width_attr = VME_D8 | VME_D16 | VME_D32 | VME_D64;
-		memset(&(master_image->pci_resource), 0,
+		memset(&(master_image->bus_resource), 0,
 			sizeof(struct resource));
 		master_image->kern_base  = NULL;
 		list_add_tail(&(master_image->list),
@@ -1084,7 +1601,7 @@ static int ca91cx42_probe(struct pci_dev
 		list_add_tail(&(slave_image->list),
 			&(ca91cx42_bridge->slave_resources));
 	}
-#if 0
+
 	/* Add dma engines to list */
 	INIT_LIST_HEAD(&(ca91cx42_bridge->dma_resources));
 	for (i = 0; i < CA91C142_MAX_DMA; i++) {
@@ -1100,12 +1617,14 @@ static int ca91cx42_probe(struct pci_dev
 		mutex_init(&(dma_ctrlr->mtx));
 		dma_ctrlr->locked = 0;
 		dma_ctrlr->number = i;
+		dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM |
+			VME_DMA_MEM_TO_VME;
 		INIT_LIST_HEAD(&(dma_ctrlr->pending));
 		INIT_LIST_HEAD(&(dma_ctrlr->running));
 		list_add_tail(&(dma_ctrlr->list),
 			&(ca91cx42_bridge->dma_resources));
 	}
-#endif
+
 	/* Add location monitor to list */
 	INIT_LIST_HEAD(&(ca91cx42_bridge->lm_resources));
 	lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL);
@@ -1128,33 +1647,26 @@ static int ca91cx42_probe(struct pci_dev
 	ca91cx42_bridge->master_set = ca91cx42_master_set;
 	ca91cx42_bridge->master_read = ca91cx42_master_read;
 	ca91cx42_bridge->master_write = ca91cx42_master_write;
-#if 0
 	ca91cx42_bridge->master_rmw = ca91cx42_master_rmw;
 	ca91cx42_bridge->dma_list_add = ca91cx42_dma_list_add;
 	ca91cx42_bridge->dma_list_exec = ca91cx42_dma_list_exec;
 	ca91cx42_bridge->dma_list_empty = ca91cx42_dma_list_empty;
-#endif
 	ca91cx42_bridge->irq_set = ca91cx42_irq_set;
 	ca91cx42_bridge->irq_generate = ca91cx42_irq_generate;
-#if 0
 	ca91cx42_bridge->lm_set = ca91cx42_lm_set;
 	ca91cx42_bridge->lm_get = ca91cx42_lm_get;
 	ca91cx42_bridge->lm_attach = ca91cx42_lm_attach;
 	ca91cx42_bridge->lm_detach = ca91cx42_lm_detach;
-#endif
 	ca91cx42_bridge->slot_get = ca91cx42_slot_get;
 
-	data = ioread32(ca91cx42_bridge->base + MISC_CTL);
+	data = ioread32(ca91cx42_device->base + MISC_CTL);
 	dev_info(&pdev->dev, "Board is%s the VME system controller\n",
 		(data & CA91CX42_MISC_CTL_SYSCON) ? "" : " not");
-	dev_info(&pdev->dev, "Slot ID is %d\n", ca91cx42_slot_get());
+	dev_info(&pdev->dev, "Slot ID is %d\n",
+		ca91cx42_slot_get(ca91cx42_bridge));
 
-	if (ca91cx42_crcsr_init(pdev)) {
+	if (ca91cx42_crcsr_init(ca91cx42_bridge, pdev)) {
 		dev_err(&pdev->dev, "CR/CSR configuration failed.\n");
-		retval = -EINVAL;
-#if 0
-		goto err_crcsr;
-#endif
 	}
 
 	/* Need to save ca91cx42_bridge pointer locally in link list for use in
@@ -1166,14 +1678,13 @@ static int ca91cx42_probe(struct pci_dev
 		goto err_reg;
 	}
 
+	pci_set_drvdata(pdev, ca91cx42_bridge);
+
 	return 0;
 
 	vme_unregister_bridge(ca91cx42_bridge);
 err_reg:
-	ca91cx42_crcsr_exit(pdev);
-#if 0
-err_crcsr:
-#endif
+	ca91cx42_crcsr_exit(ca91cx42_bridge, pdev);
 err_lm:
 	/* resources are stored in link list */
 	list_for_each(pos, &(ca91cx42_bridge->lm_resources)) {
@@ -1181,7 +1692,6 @@ err_lm:
 		list_del(pos);
 		kfree(lm);
 	}
-#if 0
 err_dma:
 	/* resources are stored in link list */
 	list_for_each(pos, &(ca91cx42_bridge->dma_resources)) {
@@ -1189,7 +1699,6 @@ err_dma:
 		list_del(pos);
 		kfree(dma_ctrlr);
 	}
-#endif
 err_slave:
 	/* resources are stored in link list */
 	list_for_each(pos, &(ca91cx42_bridge->slave_resources)) {
@@ -1206,15 +1715,17 @@ err_master:
 		kfree(master_image);
 	}
 
-	ca91cx42_irq_exit(pdev);
+	ca91cx42_irq_exit(ca91cx42_device, pdev);
 err_irq:
 err_test:
-	iounmap(ca91cx42_bridge->base);
+	iounmap(ca91cx42_device->base);
 err_remap:
 	pci_release_regions(pdev);
 err_resource:
 	pci_disable_device(pdev);
 err_enable:
+	kfree(ca91cx42_device);
+err_driver:
 	kfree(ca91cx42_bridge);
 err_struct:
 	return retval;
@@ -1228,32 +1739,37 @@ void ca91cx42_remove(struct pci_dev *pde
 	struct vme_slave_resource *slave_image;
 	struct vme_dma_resource *dma_ctrlr;
 	struct vme_lm_resource *lm;
+	struct ca91cx42_driver *bridge;
+	struct vme_bridge *ca91cx42_bridge = pci_get_drvdata(pdev);
+
+	bridge = ca91cx42_bridge->driver_priv;
+
 
 	/* Turn off Ints */
-	iowrite32(0, ca91cx42_bridge->base + LINT_EN);
+	iowrite32(0, bridge->base + LINT_EN);
 
 	/* Turn off the windows */
-	iowrite32(0x00800000, ca91cx42_bridge->base + LSI0_CTL);
-	iowrite32(0x00800000, ca91cx42_bridge->base + LSI1_CTL);
-	iowrite32(0x00800000, ca91cx42_bridge->base + LSI2_CTL);
-	iowrite32(0x00800000, ca91cx42_bridge->base + LSI3_CTL);
-	iowrite32(0x00800000, ca91cx42_bridge->base + LSI4_CTL);
-	iowrite32(0x00800000, ca91cx42_bridge->base + LSI5_CTL);
-	iowrite32(0x00800000, ca91cx42_bridge->base + LSI6_CTL);
-	iowrite32(0x00800000, ca91cx42_bridge->base + LSI7_CTL);
-	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI0_CTL);
-	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI1_CTL);
-	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI2_CTL);
-	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI3_CTL);
-	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI4_CTL);
-	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI5_CTL);
-	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI6_CTL);
-	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI7_CTL);
+	iowrite32(0x00800000, bridge->base + LSI0_CTL);
+	iowrite32(0x00800000, bridge->base + LSI1_CTL);
+	iowrite32(0x00800000, bridge->base + LSI2_CTL);
+	iowrite32(0x00800000, bridge->base + LSI3_CTL);
+	iowrite32(0x00800000, bridge->base + LSI4_CTL);
+	iowrite32(0x00800000, bridge->base + LSI5_CTL);
+	iowrite32(0x00800000, bridge->base + LSI6_CTL);
+	iowrite32(0x00800000, bridge->base + LSI7_CTL);
+	iowrite32(0x00F00000, bridge->base + VSI0_CTL);
+	iowrite32(0x00F00000, bridge->base + VSI1_CTL);
+	iowrite32(0x00F00000, bridge->base + VSI2_CTL);
+	iowrite32(0x00F00000, bridge->base + VSI3_CTL);
+	iowrite32(0x00F00000, bridge->base + VSI4_CTL);
+	iowrite32(0x00F00000, bridge->base + VSI5_CTL);
+	iowrite32(0x00F00000, bridge->base + VSI6_CTL);
+	iowrite32(0x00F00000, bridge->base + VSI7_CTL);
 
 	vme_unregister_bridge(ca91cx42_bridge);
-#if 0
-	ca91cx42_crcsr_exit(pdev);
-#endif
+
+	ca91cx42_crcsr_exit(ca91cx42_bridge, pdev);
+
 	/* resources are stored in link list */
 	list_for_each(pos, &(ca91cx42_bridge->lm_resources)) {
 		lm = list_entry(pos, struct vme_lm_resource, list);
@@ -1283,9 +1799,9 @@ void ca91cx42_remove(struct pci_dev *pde
 		kfree(master_image);
 	}
 
-	ca91cx42_irq_exit(pdev);
+	ca91cx42_irq_exit(bridge, pdev);
 
-	iounmap(ca91cx42_bridge->base);
+	iounmap(bridge->base);
 
 	pci_release_regions(pdev);
 
@@ -1299,588 +1815,11 @@ static void __exit ca91cx42_exit(void)
 	pci_unregister_driver(&ca91cx42_driver);
 }
 
+MODULE_PARM_DESC(geoid, "Override geographical addressing");
+module_param(geoid, int, 0);
+
 MODULE_DESCRIPTION("VME driver for the Tundra Universe II VME bridge");
 MODULE_LICENSE("GPL");
 
 module_init(ca91cx42_init);
 module_exit(ca91cx42_exit);
-
-/*----------------------------------------------------------------------------
- * STAGING
- *--------------------------------------------------------------------------*/
-
-#if 0
-#define	SWIZZLE(X) ( ((X & 0xFF000000) >> 24) | ((X & 0x00FF0000) >>  8) | ((X & 0x0000FF00) <<  8) | ((X & 0x000000FF) << 24))
-
-int ca91cx42_master_rmw(vmeRmwCfg_t *vmeRmw)
-{
-	int temp_ctl = 0;
-	int tempBS = 0;
-	int tempBD = 0;
-	int tempTO = 0;
-	int vmeBS = 0;
-	int vmeBD = 0;
-	int *rmw_pci_data_ptr = NULL;
-	int *vaDataPtr = NULL;
-	int i;
-	vmeOutWindowCfg_t vmeOut;
-	if (vmeRmw->maxAttempts < 1) {
-		return -EINVAL;
-	}
-	if (vmeRmw->targetAddrU) {
-		return -EINVAL;
-	}
-	/* Find the PCI address that maps to the desired VME address */
-	for (i = 0; i < 8; i++) {
-		temp_ctl = ioread32(ca91cx42_bridge->base +
-			CA91CX42_LSI_CTL[i]);
-		if ((temp_ctl & 0x80000000) == 0) {
-			continue;
-		}
-		memset(&vmeOut, 0, sizeof(vmeOut));
-		vmeOut.windowNbr = i;
-		ca91cx42_get_out_bound(&vmeOut);
-		if (vmeOut.addrSpace != vmeRmw->addrSpace) {
-			continue;
-		}
-		tempBS = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BS[i]);
-		tempBD = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BD[i]);
-		tempTO = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_TO[i]);
-		vmeBS = tempBS + tempTO;
-		vmeBD = tempBD + tempTO;
-		if ((vmeRmw->targetAddr >= vmeBS) &&
-		    (vmeRmw->targetAddr < vmeBD)) {
-			rmw_pci_data_ptr =
-			    (int *)(tempBS + (vmeRmw->targetAddr - vmeBS));
-			vaDataPtr =
-			    (int *)(out_image_va[i] +
-				    (vmeRmw->targetAddr - vmeBS));
-			break;
-		}
-	}
-
-	/* If no window - fail. */
-	if (rmw_pci_data_ptr == NULL) {
-		return -EINVAL;
-	}
-	/* Setup the RMW registers. */
-	iowrite32(0, ca91cx42_bridge->base + SCYC_CTL);
-	iowrite32(SWIZZLE(vmeRmw->enableMask), ca91cx42_bridge->base + SCYC_EN);
-	iowrite32(SWIZZLE(vmeRmw->compareData), ca91cx42_bridge->base +
-		SCYC_CMP);
-	iowrite32(SWIZZLE(vmeRmw->swapData), ca91cx42_bridge->base + SCYC_SWP);
-	iowrite32((int)rmw_pci_data_ptr, ca91cx42_bridge->base + SCYC_ADDR);
-	iowrite32(1, ca91cx42_bridge->base + SCYC_CTL);
-
-	/* Run the RMW cycle until either success or max attempts. */
-	vmeRmw->numAttempts = 1;
-	while (vmeRmw->numAttempts <= vmeRmw->maxAttempts) {
-
-		if ((ioread32(vaDataPtr) & vmeRmw->enableMask) ==
-		    (vmeRmw->swapData & vmeRmw->enableMask)) {
-
-			iowrite32(0, ca91cx42_bridge->base + SCYC_CTL);
-			break;
-
-		}
-		vmeRmw->numAttempts++;
-	}
-
-	/* If no success, set num Attempts to be greater than max attempts */
-	if (vmeRmw->numAttempts > vmeRmw->maxAttempts) {
-		vmeRmw->numAttempts = vmeRmw->maxAttempts + 1;
-	}
-
-	return 0;
-}
-
-int uniSetupDctlReg(vmeDmaPacket_t * vmeDma, int *dctlregreturn)
-{
-	unsigned int dctlreg = 0x80;
-	struct vmeAttr *vmeAttr;
-
-	if (vmeDma->srcBus == VME_DMA_VME) {
-		dctlreg = 0;
-		vmeAttr = &vmeDma->srcVmeAttr;
-	} else {
-		dctlreg = 0x80000000;
-		vmeAttr = &vmeDma->dstVmeAttr;
-	}
-
-	switch (vmeAttr->maxDataWidth) {
-	case VME_D8:
-		break;
-	case VME_D16:
-		dctlreg |= 0x00400000;
-		break;
-	case VME_D32:
-		dctlreg |= 0x00800000;
-		break;
-	case VME_D64:
-		dctlreg |= 0x00C00000;
-		break;
-	}
-
-	switch (vmeAttr->addrSpace) {
-	case VME_A16:
-		break;
-	case VME_A24:
-		dctlreg |= 0x00010000;
-		break;
-	case VME_A32:
-		dctlreg |= 0x00020000;
-		break;
-	case VME_USER1:
-		dctlreg |= 0x00060000;
-		break;
-	case VME_USER2:
-		dctlreg |= 0x00070000;
-		break;
-
-	case VME_A64:		/* not supported in Universe DMA */
-	case VME_CRCSR:
-	case VME_USER3:
-	case VME_USER4:
-		return -EINVAL;
-		break;
-	}
-	if (vmeAttr->userAccessType == VME_PROG) {
-		dctlreg |= 0x00004000;
-	}
-	if (vmeAttr->dataAccessType == VME_SUPER) {
-		dctlreg |= 0x00001000;
-	}
-	if (vmeAttr->xferProtocol != VME_SCT) {
-		dctlreg |= 0x00000100;
-	}
-	*dctlregreturn = dctlreg;
-	return 0;
-}
-
-unsigned int
-ca91cx42_start_dma(int channel, unsigned int dgcsreg, TDMA_Cmd_Packet *vmeLL)
-{
-	unsigned int val;
-
-	/* Setup registers as needed for direct or chained. */
-	if (dgcsreg & 0x8000000) {
-		iowrite32(0, ca91cx42_bridge->base + DTBC);
-		iowrite32((unsigned int)vmeLL, ca91cx42_bridge->base + DCPP);
-	} else {
-#if	0
-		printk(KERN_ERR "Starting: DGCS = %08x\n", dgcsreg);
-		printk(KERN_ERR "Starting: DVA  = %08x\n",
-			ioread32(&vmeLL->dva));
-		printk(KERN_ERR "Starting: DLV  = %08x\n",
-			ioread32(&vmeLL->dlv));
-		printk(KERN_ERR "Starting: DTBC = %08x\n",
-			ioread32(&vmeLL->dtbc));
-		printk(KERN_ERR "Starting: DCTL = %08x\n",
-			ioread32(&vmeLL->dctl));
-#endif
-		/* Write registers */
-		iowrite32(ioread32(&vmeLL->dva), ca91cx42_bridge->base + DVA);
-		iowrite32(ioread32(&vmeLL->dlv), ca91cx42_bridge->base + DLA);
-		iowrite32(ioread32(&vmeLL->dtbc), ca91cx42_bridge->base + DTBC);
-		iowrite32(ioread32(&vmeLL->dctl), ca91cx42_bridge->base + DCTL);
-		iowrite32(0, ca91cx42_bridge->base + DCPP);
-	}
-
-	/* Start the operation */
-	iowrite32(dgcsreg, ca91cx42_bridge->base + DGCS);
-	val = get_tbl();
-	iowrite32(dgcsreg | 0x8000000F, ca91cx42_bridge->base + DGCS);
-	return val;
-}
-
-TDMA_Cmd_Packet *ca91cx42_setup_dma(vmeDmaPacket_t * vmeDma)
-{
-	vmeDmaPacket_t *vmeCur;
-	int maxPerPage;
-	int currentLLcount;
-	TDMA_Cmd_Packet *startLL;
-	TDMA_Cmd_Packet *currentLL;
-	TDMA_Cmd_Packet *nextLL;
-	unsigned int dctlreg = 0;
-
-	maxPerPage = PAGESIZE / sizeof(TDMA_Cmd_Packet) - 1;
-	startLL = (TDMA_Cmd_Packet *) __get_free_pages(GFP_KERNEL, 0);
-	if (startLL == 0) {
-		return startLL;
-	}
-	/* First allocate pages for descriptors and create linked list */
-	vmeCur = vmeDma;
-	currentLL = startLL;
-	currentLLcount = 0;
-	while (vmeCur != 0) {
-		if (vmeCur->pNextPacket != 0) {
-			currentLL->dcpp = (unsigned int)(currentLL + 1);
-			currentLLcount++;
-			if (currentLLcount >= maxPerPage) {
-				currentLL->dcpp =
-				    __get_free_pages(GFP_KERNEL, 0);
-				currentLLcount = 0;
-			}
-			currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
-		} else {
-			currentLL->dcpp = (unsigned int)0;
-		}
-		vmeCur = vmeCur->pNextPacket;
-	}
-
-	/* Next fill in information for each descriptor */
-	vmeCur = vmeDma;
-	currentLL = startLL;
-	while (vmeCur != 0) {
-		if (vmeCur->srcBus == VME_DMA_VME) {
-			iowrite32(vmeCur->srcAddr, &currentLL->dva);
-			iowrite32(vmeCur->dstAddr, &currentLL->dlv);
-		} else {
-			iowrite32(vmeCur->srcAddr, &currentLL->dlv);
-			iowrite32(vmeCur->dstAddr, &currentLL->dva);
-		}
-		uniSetupDctlReg(vmeCur, &dctlreg);
-		iowrite32(dctlreg, &currentLL->dctl);
-		iowrite32(vmeCur->byteCount, &currentLL->dtbc);
-
-		currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
-		vmeCur = vmeCur->pNextPacket;
-	}
-
-	/* Convert Links to PCI addresses. */
-	currentLL = startLL;
-	while (currentLL != 0) {
-		nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
-		if (nextLL == 0) {
-			iowrite32(1, &currentLL->dcpp);
-		} else {
-			iowrite32((unsigned int)virt_to_bus(nextLL),
-			       &currentLL->dcpp);
-		}
-		currentLL = nextLL;
-	}
-
-	/* Return pointer to descriptors list */
-	return startLL;
-}
-
-int ca91cx42_free_dma(TDMA_Cmd_Packet *startLL)
-{
-	TDMA_Cmd_Packet *currentLL;
-	TDMA_Cmd_Packet *prevLL;
-	TDMA_Cmd_Packet *nextLL;
-	unsigned int dcppreg;
-
-	/* Convert Links to virtual addresses. */
-	currentLL = startLL;
-	while (currentLL != 0) {
-		dcppreg = ioread32(&currentLL->dcpp);
-		dcppreg &= ~6;
-		if (dcppreg & 1) {
-			currentLL->dcpp = 0;
-		} else {
-			currentLL->dcpp = (unsigned int)bus_to_virt(dcppreg);
-		}
-		currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
-	}
-
-	/* Free all pages associated with the descriptors. */
-	currentLL = startLL;
-	prevLL = currentLL;
-	while (currentLL != 0) {
-		nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
-		if (currentLL + 1 != nextLL) {
-			free_pages((int)prevLL, 0);
-			prevLL = nextLL;
-		}
-		currentLL = nextLL;
-	}
-
-	/* Return pointer to descriptors list */
-	return 0;
-}
-
-int ca91cx42_do_dma(vmeDmaPacket_t *vmeDma)
-{
-	unsigned int dgcsreg = 0;
-	unsigned int dctlreg = 0;
-	int val;
-	int channel, x;
-	vmeDmaPacket_t *curDma;
-	TDMA_Cmd_Packet *dmaLL;
-
-	/* Sanity check the VME chain. */
-	channel = vmeDma->channel_number;
-	if (channel > 0) {
-		return -EINVAL;
-	}
-	curDma = vmeDma;
-	while (curDma != 0) {
-		if (curDma->byteCount == 0) {
-			return -EINVAL;
-		}
-		if (curDma->byteCount >= 0x1000000) {
-			return -EINVAL;
-		}
-		if ((curDma->srcAddr & 7) != (curDma->dstAddr & 7)) {
-			return -EINVAL;
-		}
-		switch (curDma->srcBus) {
-		case VME_DMA_PCI:
-			if (curDma->dstBus != VME_DMA_VME) {
-				return -EINVAL;
-			}
-			break;
-		case VME_DMA_VME:
-			if (curDma->dstBus != VME_DMA_PCI) {
-				return -EINVAL;
-			}
-			break;
-		default:
-			return -EINVAL;
-			break;
-		}
-		if (uniSetupDctlReg(curDma, &dctlreg) < 0) {
-			return -EINVAL;
-		}
-
-		curDma = curDma->pNextPacket;
-		if (curDma == vmeDma) {	/* Endless Loop! */
-			return -EINVAL;
-		}
-	}
-
-	/* calculate control register */
-	if (vmeDma->pNextPacket != 0) {
-		dgcsreg = 0x8000000;
-	} else {
-		dgcsreg = 0;
-	}
-
-	for (x = 0; x < 8; x++) {	/* vme block size */
-		if ((256 << x) >= vmeDma->maxVmeBlockSize) {
-			break;
-		}
-	}
-	if (x == 8)
-		x = 7;
-	dgcsreg |= (x << 20);
-
-	if (vmeDma->vmeBackOffTimer) {
-		for (x = 1; x < 8; x++) {	/* vme timer */
-			if ((16 << (x - 1)) >= vmeDma->vmeBackOffTimer) {
-				break;
-			}
-		}
-		if (x == 8)
-			x = 7;
-		dgcsreg |= (x << 16);
-	}
-	/*` Setup the dma chain */
-	dmaLL = ca91cx42_setup_dma(vmeDma);
-
-	/* Start the DMA */
-	if (dgcsreg & 0x8000000) {
-		vmeDma->vmeDmaStartTick =
-		    ca91cx42_start_dma(channel, dgcsreg,
-				  (TDMA_Cmd_Packet *) virt_to_phys(dmaLL));
-	} else {
-		vmeDma->vmeDmaStartTick =
-		    ca91cx42_start_dma(channel, dgcsreg, dmaLL);
-	}
-
-	wait_event_interruptible(dma_queue,
-		ioread32(ca91cx42_bridge->base + DGCS) & 0x800);
-
-	val = ioread32(ca91cx42_bridge->base + DGCS);
-	iowrite32(val | 0xF00, ca91cx42_bridge->base + DGCS);
-
-	vmeDma->vmeDmaStatus = 0;
-
-	if (!(val & 0x00000800)) {
-		vmeDma->vmeDmaStatus = val & 0x700;
-		printk(KERN_ERR "ca91c042: DMA Error in ca91cx42_DMA_irqhandler"
-			" DGCS=%08X\n", val);
-		val = ioread32(ca91cx42_bridge->base + DCPP);
-		printk(KERN_ERR "ca91c042: DCPP=%08X\n", val);
-		val = ioread32(ca91cx42_bridge->base + DCTL);
-		printk(KERN_ERR "ca91c042: DCTL=%08X\n", val);
-		val = ioread32(ca91cx42_bridge->base + DTBC);
-		printk(KERN_ERR "ca91c042: DTBC=%08X\n", val);
-		val = ioread32(ca91cx42_bridge->base + DLA);
-		printk(KERN_ERR "ca91c042: DLA=%08X\n", val);
-		val = ioread32(ca91cx42_bridge->base + DVA);
-		printk(KERN_ERR "ca91c042: DVA=%08X\n", val);
-
-	}
-	/* Free the dma chain */
-	ca91cx42_free_dma(dmaLL);
-
-	return 0;
-}
-
-int ca91cx42_lm_set(vmeLmCfg_t *vmeLm)
-{
-	int temp_ctl = 0;
-
-	if (vmeLm->addrU)
-		return -EINVAL;
-
-	switch (vmeLm->addrSpace) {
-	case VME_A64:
-	case VME_USER3:
-	case VME_USER4:
-		return -EINVAL;
-	case VME_A16:
-		temp_ctl |= 0x00000;
-		break;
-	case VME_A24:
-		temp_ctl |= 0x10000;
-		break;
-	case VME_A32:
-		temp_ctl |= 0x20000;
-		break;
-	case VME_CRCSR:
-		temp_ctl |= 0x50000;
-		break;
-	case VME_USER1:
-		temp_ctl |= 0x60000;
-		break;
-	case VME_USER2:
-		temp_ctl |= 0x70000;
-		break;
-	}
-
-	/* Disable while we are mucking around */
-	iowrite32(0x00000000, ca91cx42_bridge->base + LM_CTL);
-
-	iowrite32(vmeLm->addr, ca91cx42_bridge->base + LM_BS);
-
-	/* Setup CTL register. */
-	if (vmeLm->userAccessType & VME_SUPER)
-		temp_ctl |= 0x00200000;
-	if (vmeLm->userAccessType & VME_USER)
-		temp_ctl |= 0x00100000;
-	if (vmeLm->dataAccessType & VME_PROG)
-		temp_ctl |= 0x00800000;
-	if (vmeLm->dataAccessType & VME_DATA)
-		temp_ctl |= 0x00400000;
-
-
-	/* Write ctl reg and enable */
-	iowrite32(0x80000000 | temp_ctl, ca91cx42_bridge->base + LM_CTL);
-	temp_ctl = ioread32(ca91cx42_bridge->base + LM_CTL);
-
-	return 0;
-}
-
-int ca91cx42_wait_lm(vmeLmCfg_t *vmeLm)
-{
-	unsigned long flags;
-	unsigned int tmp;
-
-	spin_lock_irqsave(&lm_lock, flags);
-	spin_unlock_irqrestore(&lm_lock, flags);
-	if (tmp == 0) {
-		if (vmeLm->lmWait < 10)
-			vmeLm->lmWait = 10;
-		interruptible_sleep_on_timeout(&lm_queue, vmeLm->lmWait);
-	}
-	iowrite32(0x00000000, ca91cx42_bridge->base + LM_CTL);
-
-	return 0;
-}
-
-
-
-int ca91cx42_set_arbiter(vmeArbiterCfg_t *vmeArb)
-{
-	int temp_ctl = 0;
-	int vbto = 0;
-
-	temp_ctl = ioread32(ca91cx42_bridge->base + MISC_CTL);
-	temp_ctl &= 0x00FFFFFF;
-
-	if (vmeArb->globalTimeoutTimer == 0xFFFFFFFF) {
-		vbto = 7;
-	} else if (vmeArb->globalTimeoutTimer > 1024) {
-		return -EINVAL;
-	} else if (vmeArb->globalTimeoutTimer == 0) {
-		vbto = 0;
-	} else {
-		vbto = 1;
-		while ((16 * (1 << (vbto - 1))) < vmeArb->globalTimeoutTimer)
-			vbto += 1;
-	}
-	temp_ctl |= (vbto << 28);
-
-	if (vmeArb->arbiterMode == VME_PRIORITY_MODE)
-		temp_ctl |= 1 << 26;
-
-	if (vmeArb->arbiterTimeoutFlag)
-		temp_ctl |= 2 << 24;
-
-	iowrite32(temp_ctl, ca91cx42_bridge->base + MISC_CTL);
-	return 0;
-}
-
-int ca91cx42_get_arbiter(vmeArbiterCfg_t *vmeArb)
-{
-	int temp_ctl = 0;
-	int vbto = 0;
-
-	temp_ctl = ioread32(ca91cx42_bridge->base + MISC_CTL);
-
-	vbto = (temp_ctl >> 28) & 0xF;
-	if (vbto != 0)
-		vmeArb->globalTimeoutTimer = (16 * (1 << (vbto - 1)));
-
-	if (temp_ctl & (1 << 26))
-		vmeArb->arbiterMode = VME_PRIORITY_MODE;
-	else
-		vmeArb->arbiterMode = VME_R_ROBIN_MODE;
-
-	if (temp_ctl & (3 << 24))
-		vmeArb->arbiterTimeoutFlag = 1;
-
-	return 0;
-}
-
-int ca91cx42_set_requestor(vmeRequesterCfg_t *vmeReq)
-{
-	int temp_ctl = 0;
-
-	temp_ctl = ioread32(ca91cx42_bridge->base + MAST_CTL);
-	temp_ctl &= 0xFF0FFFFF;
-
-	if (vmeReq->releaseMode == 1)
-		temp_ctl |= (1 << 20);
-
-	if (vmeReq->fairMode == 1)
-		temp_ctl |= (1 << 21);
-
-	temp_ctl |= (vmeReq->requestLevel << 22);
-
-	iowrite32(temp_ctl, ca91cx42_bridge->base + MAST_CTL);
-	return 0;
-}
-
-int ca91cx42_get_requestor(vmeRequesterCfg_t *vmeReq)
-{
-	int temp_ctl = 0;
-
-	temp_ctl = ioread32(ca91cx42_bridge->base + MAST_CTL);
-
-	if (temp_ctl & (1 << 20))
-		vmeReq->releaseMode = 1;
-
-	if (temp_ctl & (1 << 21))
-		vmeReq->fairMode = 1;
-
-	vmeReq->requestLevel = (temp_ctl & 0xC00000) >> 22;
-
-	return 0;
-}
-
-
-#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/bridges/vme_ca91cx42.h linux-libre-2.6.34-gnu1/drivers/staging/vme/bridges/vme_ca91cx42.h
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/bridges/vme_ca91cx42.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/bridges/vme_ca91cx42.h	2010-05-16 17:17:36.000000000 -0400
@@ -7,8 +7,8 @@
  * Updated by Ajit Prem
  * Copyright 2004 Motorola Inc.
  *
- * Further updated by Martyn Welch <martyn.welch@gefanuc.com>
- * Copyright 2009 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Further updated by Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2009 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * Derived from ca91c042.h by Michael Wyrick
  *
@@ -37,11 +37,27 @@
 #define CA91C142_MAX_DMA		1	/* Max DMA Controllers */
 #define CA91C142_MAX_MAILBOX		4	/* Max Mail Box registers */
 
+/* Structure used to hold driver specific information */
+struct ca91cx42_driver {
+	void *base;	/* Base Address of device registers */
+	wait_queue_head_t dma_queue;
+	wait_queue_head_t iack_queue;
+	wait_queue_head_t mbox_queue;
+	void (*lm_callback[4])(int);	/* Called in interrupt handler */
+	void *crcsr_kernel;
+	dma_addr_t crcsr_bus;
+	struct mutex vme_rmw;		/* Only one RMW cycle at a time */
+	struct mutex vme_int;		/*
+					 * Only one VME interrupt can be
+					 * generated at a time, provide locking
+					 */
+};
+
 /* See Page 2-77 in the Universe User Manual */
 struct ca91cx42_dma_descriptor {
 	unsigned int dctl;      /* DMA Control */
 	unsigned int dtbc;      /* Transfer Byte Count */
-	unsigned int dlv;       /* PCI Address */
+	unsigned int dla;       /* PCI Address */
 	unsigned int res1;      /* Reserved */
 	unsigned int dva;       /* Vme Address */
 	unsigned int res2;      /* Reserved */
@@ -237,32 +253,6 @@ static const int CA91CX42_VSI_TO[] = { V
 #define VCSR_SET		0x0FF8
 #define VCSR_BS			0x0FFC
 
-// DMA General Control/Status Register DGCS (0x220)
-// 32-24 ||  GO   | STOPR | HALTR |   0   || CHAIN |   0   |   0   |   0   ||
-// 23-16 ||              VON              ||             VOFF              ||
-// 15-08 ||  ACT  | STOP  | HALT  |   0   || DONE  | LERR  | VERR  | P_ERR ||
-// 07-00 ||   0   | INT_S | INT_H |   0   || I_DNE | I_LER | I_VER | I_PER ||
-
-// VON - Length Per DMA VMEBus Transfer
-//  0000 = None
-//  0001 = 256 Bytes
-//  0010 = 512
-//  0011 = 1024
-//  0100 = 2048
-//  0101 = 4096
-//  0110 = 8192
-//  0111 = 16384
-
-// VOFF - wait between DMA tenures
-//  0000 = 0    us
-//  0001 = 16
-//  0010 = 32
-//  0011 = 64
-//  0100 = 128
-//  0101 = 256
-//  0110 = 512
-//  0111 = 1024
-
 /*
  * PCI Class Register
  * offset 008
@@ -326,6 +316,16 @@ static const int CA91CX42_VSI_TO[] = { V
 #define CA91CX42_LSI_CTL_VCT_MBLT	(1<<8)
 #define CA91CX42_LSI_CTL_LAS		(1<<0)
 
+/*
+ * SCYC_CTL Register
+ * offset 178
+ */
+#define CA91CX42_SCYC_CTL_LAS_PCIMEM	0
+#define CA91CX42_SCYC_CTL_LAS_PCIIO	(1<<2)
+
+#define CA91CX42_SCYC_CTL_CYC_M		(3<<0)
+#define CA91CX42_SCYC_CTL_CYC_RMW	(1<<0)
+#define CA91CX42_SCYC_CTL_CYC_ADOH	(1<<1)
 
 /*
  * LMISC Register
@@ -355,6 +355,71 @@ static const int CA91CX42_VSI_TO[] = { V
 #define CA91CX42_BM_SLSI_RESERVED           0x3F0F0000
 
 /*
+ * DCTL Register
+ * offset 200
+ */
+#define CA91CX42_DCTL_L2V		(1<<31)
+#define CA91CX42_DCTL_VDW_M		(3<<22)
+#define CA91CX42_DCTL_VDW_M		(3<<22)
+#define CA91CX42_DCTL_VDW_D8		0
+#define CA91CX42_DCTL_VDW_D16		(1<<22)
+#define CA91CX42_DCTL_VDW_D32		(1<<23)
+#define CA91CX42_DCTL_VDW_D64		(3<<22)
+
+#define CA91CX42_DCTL_VAS_M		(7<<16)
+#define CA91CX42_DCTL_VAS_A16		0
+#define CA91CX42_DCTL_VAS_A24		(1<<16)
+#define CA91CX42_DCTL_VAS_A32		(1<<17)
+#define CA91CX42_DCTL_VAS_USER1		(3<<17)
+#define CA91CX42_DCTL_VAS_USER2		(7<<16)
+
+#define CA91CX42_DCTL_PGM_M		(1<<14)
+#define CA91CX42_DCTL_PGM_DATA		0
+#define CA91CX42_DCTL_PGM_PGM		(1<<14)
+
+#define CA91CX42_DCTL_SUPER_M		(1<<12)
+#define CA91CX42_DCTL_SUPER_NPRIV	0
+#define CA91CX42_DCTL_SUPER_SUPR	(1<<12)
+
+#define CA91CX42_DCTL_VCT_M		(1<<8)
+#define CA91CX42_DCTL_VCT_BLT		(1<<8)
+#define CA91CX42_DCTL_LD64EN		(1<<7)
+
+/*
+ * DCPP Register
+ * offset 218
+ */
+#define CA91CX42_DCPP_M			0xf
+#define CA91CX42_DCPP_NULL		(1<<0)
+
+/*
+ * DMA General Control/Status Register (DGCS)
+ * offset 220
+ */
+#define CA91CX42_DGCS_GO		(1<<31)
+#define CA91CX42_DGCS_STOP_REQ		(1<<30)
+#define CA91CX42_DGCS_HALT_REQ		(1<<29)
+#define CA91CX42_DGCS_CHAIN		(1<<27)
+
+#define CA91CX42_DGCS_VON_M		(7<<20)
+
+#define CA91CX42_DGCS_VOFF_M		(0xf<<16)
+
+#define CA91CX42_DGCS_ACT		(1<<15)
+#define CA91CX42_DGCS_STOP		(1<<14)
+#define CA91CX42_DGCS_HALT		(1<<13)
+#define CA91CX42_DGCS_DONE		(1<<11)
+#define CA91CX42_DGCS_LERR		(1<<10)
+#define CA91CX42_DGCS_VERR		(1<<9)
+#define CA91CX42_DGCS_PERR		(1<<8)
+#define CA91CX42_DGCS_INT_STOP		(1<<6)
+#define CA91CX42_DGCS_INT_HALT		(1<<5)
+#define CA91CX42_DGCS_INT_DONE		(1<<3)
+#define CA91CX42_DGCS_INT_LERR		(1<<2)
+#define CA91CX42_DGCS_INT_VERR		(1<<1)
+#define CA91CX42_DGCS_INT_PERR		(1<<0)
+
+/*
  * PCI Interrupt Enable Register
  * offset  300
  */
@@ -475,6 +540,19 @@ static const int CA91CX42_LINT_LM[] = {
 #define CA91CX42_VSI_CTL_LAS_PCI_IO	(1<<0)
 #define CA91CX42_VSI_CTL_LAS_PCI_CONF	(1<<1)
 
+/* LM_CTL Register
+ * offset  F64
+ */
+#define CA91CX42_LM_CTL_EN		(1<<31)
+#define CA91CX42_LM_CTL_PGM		(1<<23)
+#define CA91CX42_LM_CTL_DATA		(1<<22)
+#define CA91CX42_LM_CTL_SUPR		(1<<21)
+#define CA91CX42_LM_CTL_NPRIV		(1<<20)
+#define CA91CX42_LM_CTL_AS_M		(5<<16)
+#define CA91CX42_LM_CTL_AS_A16		0
+#define CA91CX42_LM_CTL_AS_A24		(1<<16)
+#define CA91CX42_LM_CTL_AS_A32		(1<<17)
+
 /*
  * VRAI_CTL Register
  * offset  F70
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/bridges/vme_tsi148.c linux-libre-2.6.34-gnu1/drivers/staging/vme/bridges/vme_tsi148.c
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/bridges/vme_tsi148.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/bridges/vme_tsi148.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,8 +1,8 @@
 /*
  * Support for the Tundra TSI148 VME-PCI Bridge Chip
  *
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Author: Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * Based on work by Tom Armistead and Ajit Prem
  * Copyright 2004 Motorola Inc.
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/time.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -59,28 +60,14 @@ int tsi148_dma_list_add (struct vme_dma_
 int tsi148_dma_list_exec(struct vme_dma_list *);
 int tsi148_dma_list_empty(struct vme_dma_list *);
 int tsi148_generate_irq(int, int);
-int tsi148_slot_get(void);
-
-/* Modue parameter */
-int err_chk = 0;
 
-/* XXX These should all be in a per device structure */
-struct vme_bridge *tsi148_bridge;
-wait_queue_head_t dma_queue[2];
-wait_queue_head_t iack_queue;
-void (*lm_callback[4])(int);	/* Called in interrupt handler, be careful! */
-void *crcsr_kernel;
-dma_addr_t crcsr_bus;
-struct vme_master_resource *flush_image;
-struct mutex vme_rmw;	/* Only one RMW cycle at a time */
-struct mutex vme_int;	/*
-				 * Only one VME interrupt can be
-				 * generated at a time, provide locking
-				 */
+/* Module parameter */
+static int err_chk;
+static int geoid;
 
 static char driver_name[] = "vme_tsi148";
 
-static struct pci_device_id tsi148_ids[] = {
+static const struct pci_device_id tsi148_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) },
 	{ },
 };
@@ -109,16 +96,17 @@ static void reg_split(unsigned long long
 /*
  * Wakes up DMA queue.
  */
-static u32 tsi148_DMA_irqhandler(int channel_mask)
+static u32 tsi148_DMA_irqhandler(struct tsi148_driver *bridge,
+	int channel_mask)
 {
 	u32 serviced = 0;
 
 	if (channel_mask & TSI148_LCSR_INTS_DMA0S) {
-		wake_up(&dma_queue[0]);
+		wake_up(&(bridge->dma_queue[0]));
 		serviced |= TSI148_LCSR_INTC_DMA0C;
 	}
 	if (channel_mask & TSI148_LCSR_INTS_DMA1S) {
-		wake_up(&dma_queue[1]);
+		wake_up(&(bridge->dma_queue[1]));
 		serviced |= TSI148_LCSR_INTC_DMA1C;
 	}
 
@@ -128,7 +116,7 @@ static u32 tsi148_DMA_irqhandler(int cha
 /*
  * Wake up location monitor queue
  */
-static u32 tsi148_LM_irqhandler(u32 stat)
+static u32 tsi148_LM_irqhandler(struct tsi148_driver *bridge, u32 stat)
 {
 	int i;
 	u32 serviced = 0;
@@ -136,7 +124,7 @@ static u32 tsi148_LM_irqhandler(u32 stat
 	for (i = 0; i < 4; i++) {
 		if(stat & TSI148_LCSR_INTS_LMS[i]) {
 			/* We only enable interrupts if the callback is set */
-			lm_callback[i](i);
+			bridge->lm_callback[i](i);
 			serviced |= TSI148_LCSR_INTC_LMC[i];
 		}
 	}
@@ -149,7 +137,7 @@ static u32 tsi148_LM_irqhandler(u32 stat
  *
  * XXX This functionality is not exposed up though API.
  */
-static u32 tsi148_MB_irqhandler(u32 stat)
+static u32 tsi148_MB_irqhandler(struct tsi148_driver *bridge, u32 stat)
 {
 	int i;
 	u32 val;
@@ -157,8 +145,7 @@ static u32 tsi148_MB_irqhandler(u32 stat
 
 	for (i = 0; i < 4; i++) {
 		if(stat & TSI148_LCSR_INTS_MBS[i]) {
-			val = ioread32be(tsi148_bridge->base +
-				TSI148_GCSR_MBOX[i]);
+			val = ioread32be(bridge->base +	TSI148_GCSR_MBOX[i]);
 			printk("VME Mailbox %d received: 0x%x\n", i, val);
 			serviced |= TSI148_LCSR_INTC_MBC[i];
 		}
@@ -170,22 +157,21 @@ static u32 tsi148_MB_irqhandler(u32 stat
 /*
  * Display error & status message when PERR (PCI) exception interrupt occurs.
  */
-static u32 tsi148_PERR_irqhandler(void)
+static u32 tsi148_PERR_irqhandler(struct tsi148_driver *bridge)
 {
 	printk(KERN_ERR
 		"PCI Exception at address: 0x%08x:%08x, attributes: %08x\n",
-		ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPAU),
-		ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPAL),
-		ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPAT)
+		ioread32be(bridge->base + TSI148_LCSR_EDPAU),
+		ioread32be(bridge->base + TSI148_LCSR_EDPAL),
+		ioread32be(bridge->base + TSI148_LCSR_EDPAT)
 		);
 	printk(KERN_ERR
 		"PCI-X attribute reg: %08x, PCI-X split completion reg: %08x\n",
-		ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPXA),
-		ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPXS)
+		ioread32be(bridge->base + TSI148_LCSR_EDPXA),
+		ioread32be(bridge->base + TSI148_LCSR_EDPXS)
 		);
 
-	iowrite32be(TSI148_LCSR_EDPAT_EDPCL,
-		tsi148_bridge->base + TSI148_LCSR_EDPAT);
+	iowrite32be(TSI148_LCSR_EDPAT_EDPCL, bridge->base + TSI148_LCSR_EDPAT);
 
 	return TSI148_LCSR_INTC_PERRC;
 }
@@ -193,16 +179,19 @@ static u32 tsi148_PERR_irqhandler(void)
 /*
  * Save address and status when VME error interrupt occurs.
  */
-static u32 tsi148_VERR_irqhandler(void)
+static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge)
 {
 	unsigned int error_addr_high, error_addr_low;
 	unsigned long long error_addr;
 	u32 error_attrib;
 	struct vme_bus_error *error;
+	struct tsi148_driver *bridge;
 
-	error_addr_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_VEAU);
-	error_addr_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_VEAL);
-	error_attrib = ioread32be(tsi148_bridge->base + TSI148_LCSR_VEAT);
+	bridge = tsi148_bridge->driver_priv;
+
+	error_addr_high = ioread32be(bridge->base + TSI148_LCSR_VEAU);
+	error_addr_low = ioread32be(bridge->base + TSI148_LCSR_VEAL);
+	error_attrib = ioread32be(bridge->base + TSI148_LCSR_VEAT);
 
 	reg_join(error_addr_high, error_addr_low, &error_addr);
 
@@ -226,8 +215,7 @@ static u32 tsi148_VERR_irqhandler(void)
 	}
 
 	/* Clear Status */
-	iowrite32be(TSI148_LCSR_VEAT_VESCL,
-		tsi148_bridge->base + TSI148_LCSR_VEAT);
+	iowrite32be(TSI148_LCSR_VEAT_VESCL, bridge->base + TSI148_LCSR_VEAT);
 
 	return TSI148_LCSR_INTC_VERRC;
 }
@@ -235,9 +223,9 @@ static u32 tsi148_VERR_irqhandler(void)
 /*
  * Wake up IACK queue.
  */
-static u32 tsi148_IACK_irqhandler(void)
+static u32 tsi148_IACK_irqhandler(struct tsi148_driver *bridge)
 {
-	wake_up(&iack_queue);
+	wake_up(&(bridge->iack_queue));
 
 	return TSI148_LCSR_INTC_IACKC;
 }
@@ -245,9 +233,13 @@ static u32 tsi148_IACK_irqhandler(void)
 /*
  * Calling VME bus interrupt callback if provided.
  */
-static u32 tsi148_VIRQ_irqhandler(u32 stat)
+static u32 tsi148_VIRQ_irqhandler(struct vme_bridge *tsi148_bridge,
+	u32 stat)
 {
 	int vec, i, serviced = 0;
+	struct tsi148_driver *bridge;
+
+	bridge = tsi148_bridge->driver_priv;
 
 	for (i = 7; i > 0; i--) {
 		if (stat & (1 << i)) {
@@ -257,8 +249,7 @@ static u32 tsi148_VIRQ_irqhandler(u32 st
 			 * 	8-bit IACK cycles on the bus, read from offset
 			 * 	3.
 			 */
-			vec = ioread8(tsi148_bridge->base +
-				TSI148_LCSR_VIACK[i] + 3);
+			vec = ioread8(bridge->base + TSI148_LCSR_VIACK[i] + 3);
 
 			vme_irq_handler(tsi148_bridge, i, vec);
 
@@ -273,13 +264,19 @@ static u32 tsi148_VIRQ_irqhandler(u32 st
  * Top level interrupt handler.  Clears appropriate interrupt status bits and
  * then calls appropriate sub handler(s).
  */
-static irqreturn_t tsi148_irqhandler(int irq, void *dev_id)
+static irqreturn_t tsi148_irqhandler(int irq, void *ptr)
 {
 	u32 stat, enable, serviced = 0;
+	struct vme_bridge *tsi148_bridge;
+	struct tsi148_driver *bridge;
+
+	tsi148_bridge = ptr;
+
+	bridge = tsi148_bridge->driver_priv;
 
 	/* Determine which interrupts are unmasked and set */
-	enable = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
-	stat = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTS);
+	enable = ioread32be(bridge->base + TSI148_LCSR_INTEO);
+	stat = ioread32be(bridge->base + TSI148_LCSR_INTS);
 
 	/* Only look at unmasked interrupts */
 	stat &= enable;
@@ -291,61 +288,63 @@ static irqreturn_t tsi148_irqhandler(int
 	/* Call subhandlers as appropriate */
 	/* DMA irqs */
 	if (stat & (TSI148_LCSR_INTS_DMA1S | TSI148_LCSR_INTS_DMA0S))
-		serviced |= tsi148_DMA_irqhandler(stat);
+		serviced |= tsi148_DMA_irqhandler(bridge, stat);
 
 	/* Location monitor irqs */
 	if (stat & (TSI148_LCSR_INTS_LM3S | TSI148_LCSR_INTS_LM2S |
 			TSI148_LCSR_INTS_LM1S | TSI148_LCSR_INTS_LM0S))
-		serviced |= tsi148_LM_irqhandler(stat);
+		serviced |= tsi148_LM_irqhandler(bridge, stat);
 
 	/* Mail box irqs */
 	if (stat & (TSI148_LCSR_INTS_MB3S | TSI148_LCSR_INTS_MB2S |
 			TSI148_LCSR_INTS_MB1S | TSI148_LCSR_INTS_MB0S))
-		serviced |= tsi148_MB_irqhandler(stat);
+		serviced |= tsi148_MB_irqhandler(bridge, stat);
 
 	/* PCI bus error */
 	if (stat & TSI148_LCSR_INTS_PERRS)
-		serviced |= tsi148_PERR_irqhandler();
+		serviced |= tsi148_PERR_irqhandler(bridge);
 
 	/* VME bus error */
 	if (stat & TSI148_LCSR_INTS_VERRS)
-		serviced |= tsi148_VERR_irqhandler();
+		serviced |= tsi148_VERR_irqhandler(tsi148_bridge);
 
 	/* IACK irq */
 	if (stat & TSI148_LCSR_INTS_IACKS)
-		serviced |= tsi148_IACK_irqhandler();
+		serviced |= tsi148_IACK_irqhandler(bridge);
 
 	/* VME bus irqs */
 	if (stat & (TSI148_LCSR_INTS_IRQ7S | TSI148_LCSR_INTS_IRQ6S |
 			TSI148_LCSR_INTS_IRQ5S | TSI148_LCSR_INTS_IRQ4S |
 			TSI148_LCSR_INTS_IRQ3S | TSI148_LCSR_INTS_IRQ2S |
 			TSI148_LCSR_INTS_IRQ1S))
-		serviced |= tsi148_VIRQ_irqhandler(stat);
+		serviced |= tsi148_VIRQ_irqhandler(tsi148_bridge, stat);
 
 	/* Clear serviced interrupts */
-	iowrite32be(serviced, tsi148_bridge->base + TSI148_LCSR_INTC);
+	iowrite32be(serviced, bridge->base + TSI148_LCSR_INTC);
 
 	return IRQ_HANDLED;
 }
 
-static int tsi148_irq_init(struct vme_bridge *bridge)
+static int tsi148_irq_init(struct vme_bridge *tsi148_bridge)
 {
 	int result;
 	unsigned int tmp;
 	struct pci_dev *pdev;
+	struct tsi148_driver *bridge;
 
-	/* Need pdev */
-        pdev = container_of(bridge->parent, struct pci_dev, dev);
+	pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
+
+	bridge = tsi148_bridge->driver_priv;
 
 	/* Initialise list for VME bus errors */
-	INIT_LIST_HEAD(&(bridge->vme_errors));
+	INIT_LIST_HEAD(&(tsi148_bridge->vme_errors));
 
-	mutex_init(&(bridge->irq_mtx));
+	mutex_init(&(tsi148_bridge->irq_mtx));
 
 	result = request_irq(pdev->irq,
 			     tsi148_irqhandler,
 			     IRQF_SHARED,
-			     driver_name, pdev);
+			     driver_name, tsi148_bridge);
 	if (result) {
 		dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n",
 			pdev->irq);
@@ -359,7 +358,7 @@ static int tsi148_irq_init(struct vme_br
 		TSI148_LCSR_INTEO_PERREO | TSI148_LCSR_INTEO_VERREO |
 		TSI148_LCSR_INTEO_IACKEO;
 
-	/* XXX This leaves the following interrupts masked.
+	/* This leaves the following interrupts masked.
 	 * TSI148_LCSR_INTEO_VIEEO
 	 * TSI148_LCSR_INTEO_SYSFLEO
 	 * TSI148_LCSR_INTEO_ACFLEO
@@ -392,14 +391,14 @@ static int tsi148_irq_init(struct vme_br
 	return 0;
 }
 
-static void tsi148_irq_exit(struct pci_dev *pdev)
+static void tsi148_irq_exit(struct tsi148_driver *bridge, struct pci_dev *pdev)
 {
 	/* Turn off interrupts */
-	iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTEO);
-	iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTEN);
+	iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEO);
+	iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEN);
 
 	/* Clear all interrupts */
-	iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_INTC);
+	iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_INTC);
 
 	/* Detach interrupt handler */
 	free_irq(pdev->irq, pdev);
@@ -408,11 +407,11 @@ static void tsi148_irq_exit(struct pci_d
 /*
  * Check to see if an IACk has been received, return true (1) or false (0).
  */
-int tsi148_iack_received(void)
+int tsi148_iack_received(struct tsi148_driver *bridge)
 {
 	u32 tmp;
 
-	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR);
+	tmp = ioread32be(bridge->base + TSI148_LCSR_VICR);
 
 	if (tmp & TSI148_LCSR_VICR_IRQS)
 		return 0;
@@ -423,20 +422,24 @@ int tsi148_iack_received(void)
 /*
  * Configure VME interrupt
  */
-void tsi148_irq_set(int level, int state, int sync)
+void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level,
+	int state, int sync)
 {
 	struct pci_dev *pdev;
 	u32 tmp;
+	struct tsi148_driver *bridge;
+
+	bridge = tsi148_bridge->driver_priv;
 
 	/* We need to do the ordering differently for enabling and disabling */
 	if (state == 0) {
-		tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
+		tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
 		tmp &= ~TSI148_LCSR_INTEN_IRQEN[level - 1];
-		iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN);
+		iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
 
-		tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
+		tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
 		tmp &= ~TSI148_LCSR_INTEO_IRQEO[level - 1];
-		iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
+		iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
 
 		if (sync != 0) {
 			pdev = container_of(tsi148_bridge->parent,
@@ -445,13 +448,13 @@ void tsi148_irq_set(int level, int state
 			synchronize_irq(pdev->irq);
 		}
 	} else {
-		tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
+		tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
 		tmp |= TSI148_LCSR_INTEO_IRQEO[level - 1];
-		iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
+		iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
 
-		tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
+		tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
 		tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1];
-		iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN);
+		iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
 	}
 }
 
@@ -459,28 +462,32 @@ void tsi148_irq_set(int level, int state
  * Generate a VME bus interrupt at the requested level & vector. Wait for
  * interrupt to be acked.
  */
-int tsi148_irq_generate(int level, int statid)
+int tsi148_irq_generate(struct vme_bridge *tsi148_bridge, int level, int statid)
 {
 	u32 tmp;
+	struct tsi148_driver *bridge;
 
-	mutex_lock(&(vme_int));
+	bridge = tsi148_bridge->driver_priv;
+
+	mutex_lock(&(bridge->vme_int));
 
 	/* Read VICR register */
-	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR);
+	tmp = ioread32be(bridge->base + TSI148_LCSR_VICR);
 
 	/* Set Status/ID */
 	tmp = (tmp & ~TSI148_LCSR_VICR_STID_M) |
 		(statid & TSI148_LCSR_VICR_STID_M);
-	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VICR);
+	iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR);
 
 	/* Assert VMEbus IRQ */
 	tmp = tmp | TSI148_LCSR_VICR_IRQL[level];
-	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VICR);
+	iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR);
 
 	/* XXX Consider implementing a timeout? */
-	wait_event_interruptible(iack_queue, tsi148_iack_received());
+	wait_event_interruptible(bridge->iack_queue,
+		tsi148_iack_received(bridge));
 
-	mutex_unlock(&(vme_int));
+	mutex_unlock(&(bridge->vme_int));
 
 	return 0;
 }
@@ -488,8 +495,8 @@ int tsi148_irq_generate(int level, int s
 /*
  * Find the first error in this address range
  */
-static struct vme_bus_error *tsi148_find_error(vme_address_t aspace,
-	unsigned long long address, size_t count)
+static struct vme_bus_error *tsi148_find_error(struct vme_bridge *tsi148_bridge,
+	vme_address_t aspace, unsigned long long address, size_t count)
 {
 	struct list_head *err_pos;
 	struct vme_bus_error *vme_err, *valid = NULL;
@@ -520,8 +527,8 @@ static struct vme_bus_error *tsi148_find
 /*
  * Clear errors in the provided address range.
  */
-static void tsi148_clear_errors(vme_address_t aspace,
-	unsigned long long address, size_t count)
+static void tsi148_clear_errors(struct vme_bridge *tsi148_bridge,
+	vme_address_t aspace, unsigned long long address, size_t count)
 {
 	struct list_head *err_pos, *temp;
 	struct vme_bus_error *vme_err;
@@ -561,16 +568,9 @@ int tsi148_slave_set(struct vme_slave_re
 	unsigned int vme_bound_low, vme_bound_high;
 	unsigned int pci_offset_low, pci_offset_high;
 	unsigned long long vme_bound, pci_offset;
+	struct tsi148_driver *bridge;
 
-#if 0
-        printk("Set slave image %d to:\n", image->number);
- 	printk("\tEnabled: %s\n", (enabled == 1)? "yes" : "no");
-	printk("\tVME Base:0x%llx\n", vme_base);
-	printk("\tWindow Size:0x%llx\n", size);
-	printk("\tPCI Base:0x%lx\n", (unsigned long)pci_base);
-	printk("\tAddress Space:0x%x\n", aspace);
-	printk("\tTransfer Cycle Properties:0x%x\n", cycle);
-#endif
+	bridge = image->parent->driver_priv;
 
 	i = image->number;
 
@@ -627,49 +627,27 @@ int tsi148_slave_set(struct vme_slave_re
 		return -EINVAL;
 	}
 
-#if 0
-	printk("\tVME Bound:0x%llx\n", vme_bound);
-	printk("\tPCI Offset:0x%llx\n", pci_offset);
-#endif
-
 	/*  Disable while we are mucking around */
-	temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	temp_ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITAT);
 	temp_ctl &= ~TSI148_LCSR_ITAT_EN;
-	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITAT);
 
 	/* Setup mapping */
-	iowrite32be(vme_base_high, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	iowrite32be(vme_base_high, bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITSAU);
-	iowrite32be(vme_base_low, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	iowrite32be(vme_base_low, bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITSAL);
-	iowrite32be(vme_bound_high, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	iowrite32be(vme_bound_high, bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITEAU);
-	iowrite32be(vme_bound_low, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	iowrite32be(vme_bound_low, bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITEAL);
-	iowrite32be(pci_offset_high, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	iowrite32be(pci_offset_high, bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITOFU);
-	iowrite32be(pci_offset_low, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	iowrite32be(pci_offset_low, bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITOFL);
 
-/* XXX Prefetch stuff currently unsupported */
-#if 0
-
-	for (x = 0; x < 4; x++) {
-		if ((64 << x) >= vmeIn->prefetchSize) {
-			break;
-		}
-	}
-	if (x == 4)
-		x--;
-	temp_ctl |= (x << 16);
-
-	if (vmeIn->prefetchThreshold)
-		if (vmeIn->prefetchThreshold)
-			temp_ctl |= 0x40000;
-#endif
-
 	/* Setup 2eSST speeds */
 	temp_ctl &= ~TSI148_LCSR_ITAT_2eSSTM_M;
 	switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
@@ -712,13 +690,13 @@ int tsi148_slave_set(struct vme_slave_re
 		temp_ctl |= TSI148_LCSR_ITAT_DATA;
 
 	/* Write ctl reg without enable */
-	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITAT);
 
 	if (enabled)
 		temp_ctl |= TSI148_LCSR_ITAT_EN;
 
-	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITAT);
 
 	return 0;
@@ -726,8 +704,6 @@ int tsi148_slave_set(struct vme_slave_re
 
 /*
  * Get slave window configuration.
- *
- * XXX Prefetch currently unsupported.
  */
 int tsi148_slave_get(struct vme_slave_resource *image, int *enabled,
 	unsigned long long *vme_base, unsigned long long *size,
@@ -738,25 +714,27 @@ int tsi148_slave_get(struct vme_slave_re
 	unsigned int vme_bound_low, vme_bound_high;
 	unsigned int pci_offset_low, pci_offset_high;
 	unsigned long long vme_bound, pci_offset;
+	struct tsi148_driver *bridge;
 
+	bridge = image->parent->driver_priv;
 
 	i = image->number;
 
 	/* Read registers */
-	ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITAT);
 
-	vme_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	vme_base_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITSAU);
-	vme_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	vme_base_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITSAL);
-	vme_bound_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	vme_bound_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITEAU);
-	vme_bound_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	vme_bound_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITEAL);
-	pci_offset_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	pci_offset_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITOFU);
-	pci_offset_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+	pci_offset_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
 		TSI148_LCSR_OFFSET_ITOFL);
 
 	/* Convert 64-bit variables to 2x 32-bit variables */
@@ -833,6 +811,9 @@ static int tsi148_alloc_resource(struct
 	unsigned long long existing_size;
 	int retval = 0;
 	struct pci_dev *pdev;
+	struct vme_bridge *tsi148_bridge;
+
+	tsi148_bridge = image->parent;
 
 	/* Find pci_dev container of dev */
         if (tsi148_bridge->parent == NULL) {
@@ -841,8 +822,8 @@ static int tsi148_alloc_resource(struct
         }
         pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
 
-	existing_size = (unsigned long long)(image->pci_resource.end -
-		image->pci_resource.start);
+	existing_size = (unsigned long long)(image->bus_resource.end -
+		image->bus_resource.start);
 
 	/* If the existing size is OK, return */
 	if ((size != 0) && (existing_size == (size - 1)))
@@ -851,10 +832,10 @@ static int tsi148_alloc_resource(struct
 	if (existing_size != 0) {
 		iounmap(image->kern_base);
 		image->kern_base = NULL;
-		if (image->pci_resource.name != NULL)
-			kfree(image->pci_resource.name);
-		release_resource(&(image->pci_resource));
-		memset(&(image->pci_resource), 0, sizeof(struct resource));
+		if (image->bus_resource.name != NULL)
+			kfree(image->bus_resource.name);
+		release_resource(&(image->bus_resource));
+		memset(&(image->bus_resource), 0, sizeof(struct resource));
 	}
 
 	/* Exit here if size is zero */
@@ -862,9 +843,9 @@ static int tsi148_alloc_resource(struct
 		return 0;
 	}
 
-	if (image->pci_resource.name == NULL) {
-		image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
-		if (image->pci_resource.name == NULL) {
+	if (image->bus_resource.name == NULL) {
+		image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
+		if (image->bus_resource.name == NULL) {
 			printk(KERN_ERR "Unable to allocate memory for resource"
 				" name\n");
 			retval = -ENOMEM;
@@ -872,26 +853,26 @@ static int tsi148_alloc_resource(struct
 		}
 	}
 
-	sprintf((char *)image->pci_resource.name, "%s.%d", tsi148_bridge->name,
+	sprintf((char *)image->bus_resource.name, "%s.%d", tsi148_bridge->name,
 		image->number);
 
-	image->pci_resource.start = 0;
-	image->pci_resource.end = (unsigned long)size;
-	image->pci_resource.flags = IORESOURCE_MEM;
+	image->bus_resource.start = 0;
+	image->bus_resource.end = (unsigned long)size;
+	image->bus_resource.flags = IORESOURCE_MEM;
 
 	retval = pci_bus_alloc_resource(pdev->bus,
-		&(image->pci_resource), size, size, PCIBIOS_MIN_MEM,
+		&(image->bus_resource), size, size, PCIBIOS_MIN_MEM,
 		0, NULL, NULL);
 	if (retval) {
 		printk(KERN_ERR "Failed to allocate mem resource for "
 			"window %d size 0x%lx start 0x%lx\n",
 			image->number, (unsigned long)size,
-			(unsigned long)image->pci_resource.start);
+			(unsigned long)image->bus_resource.start);
 		goto err_resource;
 	}
 
 	image->kern_base = ioremap_nocache(
-		image->pci_resource.start, size);
+		image->bus_resource.start, size);
 	if (image->kern_base == NULL) {
 		printk(KERN_ERR "Failed to remap resource\n");
 		retval = -ENOMEM;
@@ -903,10 +884,10 @@ static int tsi148_alloc_resource(struct
 	iounmap(image->kern_base);
 	image->kern_base = NULL;
 err_remap:
-	release_resource(&(image->pci_resource));
+	release_resource(&(image->bus_resource));
 err_resource:
-	kfree(image->pci_resource.name);
-	memset(&(image->pci_resource), 0, sizeof(struct resource));
+	kfree(image->bus_resource.name);
+	memset(&(image->bus_resource), 0, sizeof(struct resource));
 err_name:
 	return retval;
 }
@@ -918,9 +899,9 @@ static void tsi148_free_resource(struct
 {
 	iounmap(image->kern_base);
 	image->kern_base = NULL;
-	release_resource(&(image->pci_resource));
-	kfree(image->pci_resource.name);
-	memset(&(image->pci_resource), 0, sizeof(struct resource));
+	release_resource(&(image->bus_resource));
+	kfree(image->bus_resource.name);
+	memset(&(image->bus_resource), 0, sizeof(struct resource));
 }
 
 /*
@@ -937,6 +918,9 @@ int tsi148_master_set( struct vme_master
 	unsigned int pci_bound_low, pci_bound_high;
 	unsigned int vme_offset_low, vme_offset_high;
 	unsigned long long pci_bound, vme_offset, pci_base;
+	struct tsi148_driver *bridge;
+
+	bridge = image->parent->driver_priv;
 
 	/* Verify input data */
 	if (vme_base & 0xFFFF) {
@@ -970,7 +954,7 @@ int tsi148_master_set( struct vme_master
 		pci_bound = 0;
 		vme_offset = 0;
 	} else {
-		pci_base = (unsigned long long)image->pci_resource.start;
+		pci_base = (unsigned long long)image->bus_resource.start;
 
 		/*
 		 * Bound address is a valid address for the window, adjust
@@ -1007,26 +991,12 @@ int tsi148_master_set( struct vme_master
 	i = image->number;
 
 	/* Disable while we are mucking around */
-	temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	temp_ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTAT);
 	temp_ctl &= ~TSI148_LCSR_OTAT_EN;
-	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTAT);
 
-/* XXX Prefetch stuff currently unsupported */
-#if 0
-	if (vmeOut->prefetchEnable) {
-		temp_ctl |= 0x40000;
-		for (x = 0; x < 4; x++) {
-			if ((2 << x) >= vmeOut->prefetchSize)
-				break;
-		}
-		if (x == 4)
-			x = 3;
-		temp_ctl |= (x << 16);
-	}
-#endif
-
 	/* Setup 2eSST speeds */
 	temp_ctl &= ~TSI148_LCSR_OTAT_2eSSTM_M;
 	switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
@@ -1126,33 +1096,27 @@ int tsi148_master_set( struct vme_master
 		temp_ctl |= TSI148_LCSR_OTAT_PGM;
 
 	/* Setup mapping */
-	iowrite32be(pci_base_high, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	iowrite32be(pci_base_high, bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTSAU);
-	iowrite32be(pci_base_low, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	iowrite32be(pci_base_low, bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTSAL);
-	iowrite32be(pci_bound_high, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	iowrite32be(pci_bound_high, bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTEAU);
-	iowrite32be(pci_bound_low, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	iowrite32be(pci_bound_low, bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTEAL);
-	iowrite32be(vme_offset_high, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	iowrite32be(vme_offset_high, bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTOFU);
-	iowrite32be(vme_offset_low, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	iowrite32be(vme_offset_low, bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTOFL);
 
-/* XXX We need to deal with OTBS */
-#if 0
-	iowrite32be(vmeOut->bcastSelect2esst, tsi148_bridge->base +
-		TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTBS);
-#endif
-
 	/* Write ctl reg without enable */
-	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTAT);
 
 	if (enabled)
 		temp_ctl |= TSI148_LCSR_OTAT_EN;
 
-	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTAT);
 
 	spin_unlock(&(image->lock));
@@ -1183,23 +1147,26 @@ int __tsi148_master_get( struct vme_mast
 	unsigned int vme_offset_low, vme_offset_high;
 
 	unsigned long long pci_base, pci_bound, vme_offset;
+	struct tsi148_driver *bridge;
+
+	bridge = image->parent->driver_priv;
 
 	i = image->number;
 
-	ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTAT);
 
-	pci_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	pci_base_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTSAU);
-	pci_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	pci_base_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTSAL);
-	pci_bound_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	pci_bound_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTEAU);
-	pci_bound_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	pci_bound_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTEAL);
-	vme_offset_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	vme_offset_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTOFU);
-	vme_offset_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	vme_offset_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTOFL);
 
 	/* Convert 64-bit variables to 2x 32-bit variables */
@@ -1305,6 +1272,9 @@ ssize_t tsi148_master_read(struct vme_ma
 	vme_cycle_t cycle;
 	vme_width_t dwidth;
 	struct vme_bus_error *vme_err = NULL;
+	struct vme_bridge *tsi148_bridge;
+
+	tsi148_bridge = image->parent;
 
 	spin_lock(&(image->lock));
 
@@ -1317,13 +1287,15 @@ ssize_t tsi148_master_read(struct vme_ma
 	__tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle,
 		&dwidth);
 
-	vme_err = tsi148_find_error(aspace, vme_base + offset, count);
+	vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset,
+		count);
 	if(vme_err != NULL) {
 		dev_err(image->parent->parent, "First VME read error detected "
 			"an at address 0x%llx\n", vme_err->address);
 		retval = vme_err->address - (vme_base + offset);
 		/* Clear down save errors in this address range */
-		tsi148_clear_errors(aspace, vme_base + offset, count);
+		tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset,
+			count);
 	}
 
 skip_chk:
@@ -1333,9 +1305,6 @@ skip_chk:
 }
 
 
-/* XXX We need to change vme_master_resource->mtx to a spinlock so that read
- *     and write functions can be used in an interrupt context
- */
 ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
 	size_t count, loff_t offset)
 {
@@ -1346,6 +1315,12 @@ ssize_t tsi148_master_write(struct vme_m
 	vme_width_t dwidth;
 
 	struct vme_bus_error *vme_err = NULL;
+	struct vme_bridge *tsi148_bridge;
+	struct tsi148_driver *bridge;
+
+	tsi148_bridge = image->parent;
+
+	bridge = tsi148_bridge->driver_priv;
 
 	spin_lock(&(image->lock));
 
@@ -1373,15 +1348,17 @@ ssize_t tsi148_master_write(struct vme_m
 	__tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle,
 		&dwidth);
 
-	ioread16(flush_image->kern_base + 0x7F000);
+	ioread16(bridge->flush_image->kern_base + 0x7F000);
 
-	vme_err = tsi148_find_error(aspace, vme_base + offset, count);
+	vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset,
+		count);
 	if(vme_err != NULL) {
 		printk("First VME write error detected an at address 0x%llx\n",
 			vme_err->address);
 		retval = vme_err->address - (vme_base + offset);
 		/* Clear down save errors in this address range */
-		tsi148_clear_errors(aspace, vme_base + offset, count);
+		tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset,
+			count);
 	}
 
 skip_chk:
@@ -1403,48 +1380,50 @@ unsigned int tsi148_master_rmw(struct vm
 	unsigned int pci_addr_high, pci_addr_low;
 	u32 tmp, result;
 	int i;
+	struct tsi148_driver *bridge;
 
+	bridge = image->parent->driver_priv;
 
 	/* Find the PCI address that maps to the desired VME address */
 	i = image->number;
 
 	/* Locking as we can only do one of these at a time */
-	mutex_lock(&(vme_rmw));
+	mutex_lock(&(bridge->vme_rmw));
 
 	/* Lock image */
 	spin_lock(&(image->lock));
 
-	pci_addr_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	pci_addr_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTSAU);
-	pci_addr_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+	pci_addr_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
 		TSI148_LCSR_OFFSET_OTSAL);
 
 	reg_join(pci_addr_high, pci_addr_low, &pci_addr);
 	reg_split(pci_addr + offset, &pci_addr_high, &pci_addr_low);
 
 	/* Configure registers */
-	iowrite32be(mask, tsi148_bridge->base + TSI148_LCSR_RMWEN);
-	iowrite32be(compare, tsi148_bridge->base + TSI148_LCSR_RMWC);
-	iowrite32be(swap, tsi148_bridge->base + TSI148_LCSR_RMWS);
-	iowrite32be(pci_addr_high, tsi148_bridge->base + TSI148_LCSR_RMWAU);
-	iowrite32be(pci_addr_low, tsi148_bridge->base + TSI148_LCSR_RMWAL);
+	iowrite32be(mask, bridge->base + TSI148_LCSR_RMWEN);
+	iowrite32be(compare, bridge->base + TSI148_LCSR_RMWC);
+	iowrite32be(swap, bridge->base + TSI148_LCSR_RMWS);
+	iowrite32be(pci_addr_high, bridge->base + TSI148_LCSR_RMWAU);
+	iowrite32be(pci_addr_low, bridge->base + TSI148_LCSR_RMWAL);
 
 	/* Enable RMW */
-	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL);
+	tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL);
 	tmp |= TSI148_LCSR_VMCTRL_RMWEN;
-	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VMCTRL);
+	iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL);
 
 	/* Kick process off with a read to the required address. */
 	result = ioread32be(image->kern_base + offset);
 
 	/* Disable RMW */
-	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL);
+	tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL);
 	tmp &= ~TSI148_LCSR_VMCTRL_RMWEN;
-	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VMCTRL);
+	iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL);
 
 	spin_unlock(&(image->lock));
 
-	mutex_unlock(&(vme_rmw));
+	mutex_unlock(&(bridge->vme_rmw));
 
 	return result;
 }
@@ -1637,8 +1616,6 @@ static int tsi148_dma_set_vme_dest_attri
 
 /*
  * Add a link list descriptor to the list
- *
- * XXX Need to handle 2eSST Broadcast select bits
  */
 int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src,
 	struct vme_dma_attr *dest, size_t count)
@@ -1651,7 +1628,7 @@ int tsi148_dma_list_add (struct vme_dma_
 	dma_addr_t desc_ptr;
 	int retval = 0;
 
-	/* XXX descriptor must be aligned on 64-bit boundaries */
+	/* Descriptor must be aligned on 64-bit boundaries */
 	entry = (struct tsi148_dma_entry *)kmalloc(
 		sizeof(struct tsi148_dma_entry), GFP_KERNEL);
 	if (entry == NULL) {
@@ -1788,11 +1765,14 @@ err_mem:
 /*
  * Check to see if the provided DMA channel is busy.
  */
-static int tsi148_dma_busy(int channel)
+static int tsi148_dma_busy(struct vme_bridge *tsi148_bridge, int channel)
 {
 	u32 tmp;
+	struct tsi148_driver *bridge;
 
-	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] +
+	bridge = tsi148_bridge->driver_priv;
+
+	tmp = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] +
 		TSI148_LCSR_OFFSET_DSTA);
 
 	if (tmp & TSI148_LCSR_DSTA_BSY)
@@ -1815,12 +1795,12 @@ int tsi148_dma_list_exec(struct vme_dma_
 	dma_addr_t bus_addr;
 	u32 bus_addr_high, bus_addr_low;
 	u32 val, dctlreg = 0;
-#if 0
-	int x;
-#endif
+	struct tsi148_driver *bridge;
 
 	ctrlr = list->parent;
 
+	bridge = ctrlr->parent->driver_priv;
+
 	mutex_lock(&(ctrlr->mtx));
 
 	channel = ctrlr->number;
@@ -1837,48 +1817,6 @@ int tsi148_dma_list_exec(struct vme_dma_
 	} else {
 		list_add(&(list->list), &(ctrlr->running));
 	}
-#if 0
-	/* XXX Still todo */
-	for (x = 0; x < 8; x++) {	/* vme block size */
-		if ((32 << x) >= vmeDma->maxVmeBlockSize) {
-			break;
-		}
-	}
-	if (x == 8)
-		x = 7;
-	dctlreg |= (x << 12);
-
-	for (x = 0; x < 8; x++) {	/* pci block size */
-		if ((32 << x) >= vmeDma->maxPciBlockSize) {
-			break;
-		}
-	}
-	if (x == 8)
-		x = 7;
-	dctlreg |= (x << 4);
-
-	if (vmeDma->vmeBackOffTimer) {
-		for (x = 1; x < 8; x++) {	/* vme timer */
-			if ((1 << (x - 1)) >= vmeDma->vmeBackOffTimer) {
-				break;
-			}
-		}
-		if (x == 8)
-			x = 7;
-		dctlreg |= (x << 8);
-	}
-
-	if (vmeDma->pciBackOffTimer) {
-		for (x = 1; x < 8; x++) {	/* pci timer */
-			if ((1 << (x - 1)) >= vmeDma->pciBackOffTimer) {
-				break;
-			}
-		}
-		if (x == 8)
-			x = 7;
-		dctlreg |= (x << 0);
-	}
-#endif
 
 	/* Get first bus address and write into registers */
 	entry = list_first_entry(&(list->entries), struct tsi148_dma_entry,
@@ -1890,21 +1828,22 @@ int tsi148_dma_list_exec(struct vme_dma_
 
 	reg_split(bus_addr, &bus_addr_high, &bus_addr_low);
 
-	iowrite32be(bus_addr_high, tsi148_bridge->base +
+	iowrite32be(bus_addr_high, bridge->base +
 		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAU);
-	iowrite32be(bus_addr_low, tsi148_bridge->base +
+	iowrite32be(bus_addr_low, bridge->base +
 		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAL);
 
 	/* Start the operation */
-	iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, tsi148_bridge->base +
+	iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, bridge->base +
 		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
 
-	wait_event_interruptible(dma_queue[channel], tsi148_dma_busy(channel));
+	wait_event_interruptible(bridge->dma_queue[channel],
+		tsi148_dma_busy(ctrlr->parent, channel));
 	/*
 	 * Read status register, this register is valid until we kick off a
 	 * new transfer.
 	 */
-	val = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] +
+	val = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] +
 		TSI148_LCSR_OFFSET_DSTA);
 
 	if (val & TSI148_LCSR_DSTA_VBE) {
@@ -1952,12 +1891,15 @@ int tsi148_lm_set(struct vme_lm_resource
 {
 	u32 lm_base_high, lm_base_low, lm_ctl = 0;
 	int i;
+	struct tsi148_driver *bridge;
+
+	bridge = lm->parent->driver_priv;
 
 	mutex_lock(&(lm->mtx));
 
 	/* If we already have a callback attached, we can't move it! */
 	for (i = 0; i < lm->monitors; i++) {
-		if(lm_callback[i] != NULL) {
+		if (bridge->lm_callback[i] != NULL) {
 			mutex_unlock(&(lm->mtx));
 			printk("Location monitor callback attached, can't "
 				"reset\n");
@@ -1996,9 +1938,9 @@ int tsi148_lm_set(struct vme_lm_resource
 
 	reg_split(lm_base, &lm_base_high, &lm_base_low);
 
-	iowrite32be(lm_base_high, tsi148_bridge->base + TSI148_LCSR_LMBAU);
-	iowrite32be(lm_base_low, tsi148_bridge->base + TSI148_LCSR_LMBAL);
-	iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT);
+	iowrite32be(lm_base_high, bridge->base + TSI148_LCSR_LMBAU);
+	iowrite32be(lm_base_low, bridge->base + TSI148_LCSR_LMBAL);
+	iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT);
 
 	mutex_unlock(&(lm->mtx));
 
@@ -2012,12 +1954,15 @@ int tsi148_lm_get(struct vme_lm_resource
 	vme_address_t *aspace, vme_cycle_t *cycle)
 {
 	u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0;
+	struct tsi148_driver *bridge;
+
+	bridge = lm->parent->driver_priv;
 
 	mutex_lock(&(lm->mtx));
 
-	lm_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAU);
-	lm_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAL);
-	lm_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT);
+	lm_base_high = ioread32be(bridge->base + TSI148_LCSR_LMBAU);
+	lm_base_low = ioread32be(bridge->base + TSI148_LCSR_LMBAL);
+	lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT);
 
 	reg_join(lm_base_high, lm_base_low, lm_base);
 
@@ -2060,11 +2005,14 @@ int tsi148_lm_attach(struct vme_lm_resou
 	void (*callback)(int))
 {
 	u32 lm_ctl, tmp;
+	struct tsi148_driver *bridge;
+
+	bridge = lm->parent->driver_priv;
 
 	mutex_lock(&(lm->mtx));
 
 	/* Ensure that the location monitor is configured - need PGM or DATA */
-	lm_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT);
+	lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT);
 	if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) {
 		mutex_unlock(&(lm->mtx));
 		printk("Location monitor not properly configured\n");
@@ -2072,28 +2020,28 @@ int tsi148_lm_attach(struct vme_lm_resou
 	}
 
 	/* Check that a callback isn't already attached */
-	if (lm_callback[monitor] != NULL) {
+	if (bridge->lm_callback[monitor] != NULL) {
 		mutex_unlock(&(lm->mtx));
 		printk("Existing callback attached\n");
 		return -EBUSY;
 	}
 
 	/* Attach callback */
-	lm_callback[monitor] = callback;
+	bridge->lm_callback[monitor] = callback;
 
 	/* Enable Location Monitor interrupt */
-	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
+	tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
 	tmp |= TSI148_LCSR_INTEN_LMEN[monitor];
-	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN);
+	iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
 
-	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
+	tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
 	tmp |= TSI148_LCSR_INTEO_LMEO[monitor];
-	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
+	iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
 
 	/* Ensure that global Location Monitor Enable set */
 	if ((lm_ctl & TSI148_LCSR_LMAT_EN) == 0) {
 		lm_ctl |= TSI148_LCSR_LMAT_EN;
-		iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT);
+		iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT);
 	}
 
 	mutex_unlock(&(lm->mtx));
@@ -2107,30 +2055,33 @@ int tsi148_lm_attach(struct vme_lm_resou
 int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor)
 {
 	u32 lm_en, tmp;
+	struct tsi148_driver *bridge;
+
+	bridge = lm->parent->driver_priv;
 
 	mutex_lock(&(lm->mtx));
 
 	/* Disable Location Monitor and ensure previous interrupts are clear */
-	lm_en = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
+	lm_en = ioread32be(bridge->base + TSI148_LCSR_INTEN);
 	lm_en &= ~TSI148_LCSR_INTEN_LMEN[monitor];
-	iowrite32be(lm_en, tsi148_bridge->base + TSI148_LCSR_INTEN);
+	iowrite32be(lm_en, bridge->base + TSI148_LCSR_INTEN);
 
-	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
+	tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
 	tmp &= ~TSI148_LCSR_INTEO_LMEO[monitor];
-	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
+	iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
 
 	iowrite32be(TSI148_LCSR_INTC_LMC[monitor],
-		 tsi148_bridge->base + TSI148_LCSR_INTC);
+		 bridge->base + TSI148_LCSR_INTC);
 
 	/* Detach callback */
-	lm_callback[monitor] = NULL;
+	bridge->lm_callback[monitor] = NULL;
 
 	/* If all location monitors disabled, disable global Location Monitor */
 	if ((lm_en & (TSI148_LCSR_INTS_LM0S | TSI148_LCSR_INTS_LM1S |
 			TSI148_LCSR_INTS_LM2S | TSI148_LCSR_INTS_LM3S)) == 0) {
-		tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT);
+		tmp = ioread32be(bridge->base + TSI148_LCSR_LMAT);
 		tmp &= ~TSI148_LCSR_LMAT_EN;
-		iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_LMAT);
+		iowrite32be(tmp, bridge->base + TSI148_LCSR_LMAT);
 	}
 
 	mutex_unlock(&(lm->mtx));
@@ -2141,12 +2092,19 @@ int tsi148_lm_detach(struct vme_lm_resou
 /*
  * Determine Geographical Addressing
  */
-int tsi148_slot_get(void)
+int tsi148_slot_get(struct vme_bridge *tsi148_bridge)
 {
         u32 slot = 0;
+	struct tsi148_driver *bridge;
+
+	bridge = tsi148_bridge->driver_priv;
+
+	if (!geoid) {
+		slot = ioread32be(bridge->base + TSI148_LCSR_VSTAT);
+		slot = slot & TSI148_LCSR_VSTAT_GA_M;
+	} else
+		slot = geoid;
 
-	slot = ioread32be(tsi148_bridge->base + TSI148_LCSR_VSTAT);
-	slot = slot & TSI148_LCSR_VSTAT_GA_M;
 	return (int)slot;
 }
 
@@ -2167,45 +2125,50 @@ static int __init tsi148_init(void)
  * boards registers, this means there is a fix length 508kB window which must
  * be mapped onto PCI memory.
  */
-static int tsi148_crcsr_init(struct pci_dev *pdev)
+static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge,
+	struct pci_dev *pdev)
 {
 	u32 cbar, crat, vstat;
 	u32 crcsr_bus_high, crcsr_bus_low;
 	int retval;
+	struct tsi148_driver *bridge;
+
+	bridge = tsi148_bridge->driver_priv;
 
 	/* Allocate mem for CR/CSR image */
-	crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE,
-		&crcsr_bus);
-	if (crcsr_kernel == NULL) {
+	bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE,
+		&(bridge->crcsr_bus));
+	if (bridge->crcsr_kernel == NULL) {
 		dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR "
 			"image\n");
 		return -ENOMEM;
 	}
 
-	memset(crcsr_kernel, 0, VME_CRCSR_BUF_SIZE);
+	memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE);
 
-	reg_split(crcsr_bus, &crcsr_bus_high, &crcsr_bus_low);
+	reg_split(bridge->crcsr_bus, &crcsr_bus_high, &crcsr_bus_low);
 
-	iowrite32be(crcsr_bus_high, tsi148_bridge->base + TSI148_LCSR_CROU);
-	iowrite32be(crcsr_bus_low, tsi148_bridge->base + TSI148_LCSR_CROL);
+	iowrite32be(crcsr_bus_high, bridge->base + TSI148_LCSR_CROU);
+	iowrite32be(crcsr_bus_low, bridge->base + TSI148_LCSR_CROL);
 
 	/* Ensure that the CR/CSR is configured at the correct offset */
-	cbar = ioread32be(tsi148_bridge->base + TSI148_CBAR);
+	cbar = ioread32be(bridge->base + TSI148_CBAR);
 	cbar = (cbar & TSI148_CRCSR_CBAR_M)>>3;
 
-	vstat = tsi148_slot_get();
+	vstat = tsi148_slot_get(tsi148_bridge);
 
 	if (cbar != vstat) {
+		cbar = vstat;
 		dev_info(&pdev->dev, "Setting CR/CSR offset\n");
-		iowrite32be(cbar<<3, tsi148_bridge->base + TSI148_CBAR);
+		iowrite32be(cbar<<3, bridge->base + TSI148_CBAR);
 	}
 	dev_info(&pdev->dev, "CR/CSR Offset: %d\n", cbar);
 
-	crat = ioread32be(tsi148_bridge->base + TSI148_LCSR_CRAT);
+	crat = ioread32be(bridge->base + TSI148_LCSR_CRAT);
 	if (crat & TSI148_LCSR_CRAT_EN) {
 		dev_info(&pdev->dev, "Enabling CR/CSR space\n");
 		iowrite32be(crat | TSI148_LCSR_CRAT_EN,
-			tsi148_bridge->base + TSI148_LCSR_CRAT);
+			bridge->base + TSI148_LCSR_CRAT);
 	} else
 		dev_info(&pdev->dev, "CR/CSR already enabled\n");
 
@@ -2214,8 +2177,9 @@ static int tsi148_crcsr_init(struct pci_
 	 * through VME writes.
 	 */
 	if(err_chk) {
-		retval = tsi148_master_set(flush_image, 1, (vstat * 0x80000),
-			0x80000, VME_CRCSR, VME_SCT, VME_D16);
+		retval = tsi148_master_set(bridge->flush_image, 1,
+			(vstat * 0x80000), 0x80000, VME_CRCSR, VME_SCT,
+			VME_D16);
 		if (retval)
 			dev_err(&pdev->dev, "Configuring flush image failed\n");
 	}
@@ -2224,20 +2188,25 @@ static int tsi148_crcsr_init(struct pci_
 
 }
 
-static void tsi148_crcsr_exit(struct pci_dev *pdev)
+static void tsi148_crcsr_exit(struct vme_bridge *tsi148_bridge,
+	struct pci_dev *pdev)
 {
 	u32 crat;
+	struct tsi148_driver *bridge;
+
+	bridge = tsi148_bridge->driver_priv;
 
 	/* Turn off CR/CSR space */
-	crat = ioread32be(tsi148_bridge->base + TSI148_LCSR_CRAT);
+	crat = ioread32be(bridge->base + TSI148_LCSR_CRAT);
 	iowrite32be(crat & ~TSI148_LCSR_CRAT_EN,
-		tsi148_bridge->base + TSI148_LCSR_CRAT);
+		bridge->base + TSI148_LCSR_CRAT);
 
 	/* Free image */
-	iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_CROU);
-	iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_CROL);
+	iowrite32be(0, bridge->base + TSI148_LCSR_CROU);
+	iowrite32be(0, bridge->base + TSI148_LCSR_CROL);
 
-	pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, crcsr_kernel, crcsr_bus);
+	pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel,
+		bridge->crcsr_bus);
 }
 
 static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -2245,6 +2214,8 @@ static int tsi148_probe(struct pci_dev *
 	int retval, i, master_num;
 	u32 data;
 	struct list_head *pos = NULL;
+	struct vme_bridge *tsi148_bridge;
+	struct tsi148_driver *tsi148_device;
 	struct vme_master_resource *master_image;
 	struct vme_slave_resource *slave_image;
 	struct vme_dma_resource *dma_ctrlr;
@@ -2264,6 +2235,18 @@ static int tsi148_probe(struct pci_dev *
 
 	memset(tsi148_bridge, 0, sizeof(struct vme_bridge));
 
+	tsi148_device = kmalloc(sizeof(struct tsi148_driver), GFP_KERNEL);
+	if (tsi148_device == NULL) {
+		dev_err(&pdev->dev, "Failed to allocate memory for device "
+			"structure\n");
+		retval = -ENOMEM;
+		goto err_driver;
+	}
+
+	memset(tsi148_device, 0, sizeof(struct tsi148_driver));
+
+	tsi148_bridge->driver_priv = tsi148_device;
+
 	/* Enable the device */
 	retval = pci_enable_device(pdev);
 	if (retval) {
@@ -2279,15 +2262,16 @@ static int tsi148_probe(struct pci_dev *
 	}
 
 	/* map registers in BAR 0 */
-	tsi148_bridge->base = ioremap_nocache(pci_resource_start(pdev, 0), 4096);
-	if (!tsi148_bridge->base) {
+	tsi148_device->base = ioremap_nocache(pci_resource_start(pdev, 0),
+		4096);
+	if (!tsi148_device->base) {
 		dev_err(&pdev->dev, "Unable to remap CRG region\n");
 		retval = -EIO;
 		goto err_remap;
 	}
 
 	/* Check to see if the mapping worked out */
-	data = ioread32(tsi148_bridge->base + TSI148_PCFS_ID) & 0x0000FFFF;
+	data = ioread32(tsi148_device->base + TSI148_PCFS_ID) & 0x0000FFFF;
 	if (data != PCI_VENDOR_ID_TUNDRA) {
 		dev_err(&pdev->dev, "CRG region check failed\n");
 		retval = -EIO;
@@ -2295,12 +2279,11 @@ static int tsi148_probe(struct pci_dev *
 	}
 
 	/* Initialize wait queues & mutual exclusion flags */
-	/* XXX These need to be moved to the vme_bridge structure */
-	init_waitqueue_head(&dma_queue[0]);
-	init_waitqueue_head(&dma_queue[1]);
-	init_waitqueue_head(&iack_queue);
-	mutex_init(&(vme_int));
-	mutex_init(&(vme_rmw));
+	init_waitqueue_head(&(tsi148_device->dma_queue[0]));
+	init_waitqueue_head(&(tsi148_device->dma_queue[1]));
+	init_waitqueue_head(&(tsi148_device->iack_queue));
+	mutex_init(&(tsi148_device->vme_int));
+	mutex_init(&(tsi148_device->vme_rmw));
 
 	tsi148_bridge->parent = &(pdev->dev);
 	strcpy(tsi148_bridge->name, driver_name);
@@ -2320,29 +2303,29 @@ static int tsi148_probe(struct pci_dev *
 	master_num = TSI148_MAX_MASTER;
 	if(err_chk){
 		master_num--;
-		/* XXX */
-		flush_image = (struct vme_master_resource *)kmalloc(
-			sizeof(struct vme_master_resource), GFP_KERNEL);
-		if (flush_image == NULL) {
+
+		tsi148_device->flush_image = (struct vme_master_resource *)
+			kmalloc(sizeof(struct vme_master_resource), GFP_KERNEL);
+		if (tsi148_device->flush_image == NULL) {
 			dev_err(&pdev->dev, "Failed to allocate memory for "
 			"flush resource structure\n");
 			retval = -ENOMEM;
 			goto err_master;
 		}
-		flush_image->parent = tsi148_bridge;
-		spin_lock_init(&(flush_image->lock));
-		flush_image->locked = 1;
-		flush_image->number = master_num;
-		flush_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
-			VME_A64;
-		flush_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
-			VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
-			VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
-			VME_PROG | VME_DATA;
-		flush_image->width_attr = VME_D16 | VME_D32;
-		memset(&(flush_image->pci_resource), 0,
+		tsi148_device->flush_image->parent = tsi148_bridge;
+		spin_lock_init(&(tsi148_device->flush_image->lock));
+		tsi148_device->flush_image->locked = 1;
+		tsi148_device->flush_image->number = master_num;
+		tsi148_device->flush_image->address_attr = VME_A16 | VME_A24 |
+			VME_A32 | VME_A64;
+		tsi148_device->flush_image->cycle_attr = VME_SCT | VME_BLT |
+			VME_MBLT | VME_2eVME | VME_2eSST | VME_2eSSTB |
+			VME_2eSST160 | VME_2eSST267 | VME_2eSST320 | VME_SUPER |
+			VME_USER | VME_PROG | VME_DATA;
+		tsi148_device->flush_image->width_attr = VME_D16 | VME_D32;
+		memset(&(tsi148_device->flush_image->bus_resource), 0,
 			sizeof(struct resource));
-		flush_image->kern_base  = NULL;
+		tsi148_device->flush_image->kern_base  = NULL;
 	}
 
 	/* Add master windows to list */
@@ -2367,7 +2350,7 @@ static int tsi148_probe(struct pci_dev *
 			VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
 			VME_PROG | VME_DATA;
 		master_image->width_attr = VME_D16 | VME_D32;
-		memset(&(master_image->pci_resource), 0,
+		memset(&(master_image->bus_resource), 0,
 			sizeof(struct resource));
 		master_image->kern_base  = NULL;
 		list_add_tail(&(master_image->list),
@@ -2415,6 +2398,10 @@ static int tsi148_probe(struct pci_dev *
 		mutex_init(&(dma_ctrlr->mtx));
 		dma_ctrlr->locked = 0;
 		dma_ctrlr->number = i;
+		dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM |
+			VME_DMA_MEM_TO_VME | VME_DMA_VME_TO_VME |
+			VME_DMA_MEM_TO_MEM | VME_DMA_PATTERN_TO_VME |
+			VME_DMA_PATTERN_TO_MEM;
 		INIT_LIST_HEAD(&(dma_ctrlr->pending));
 		INIT_LIST_HEAD(&(dma_ctrlr->running));
 		list_add_tail(&(dma_ctrlr->list),
@@ -2455,40 +2442,43 @@ static int tsi148_probe(struct pci_dev *
 	tsi148_bridge->lm_detach = tsi148_lm_detach;
 	tsi148_bridge->slot_get = tsi148_slot_get;
 
-	data = ioread32be(tsi148_bridge->base + TSI148_LCSR_VSTAT);
+	data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT);
 	dev_info(&pdev->dev, "Board is%s the VME system controller\n",
 		(data & TSI148_LCSR_VSTAT_SCONS)? "" : " not");
-	dev_info(&pdev->dev, "VME geographical address is %d\n",
-		data & TSI148_LCSR_VSTAT_GA_M);
+	if (!geoid)
+		dev_info(&pdev->dev, "VME geographical address is %d\n",
+			data & TSI148_LCSR_VSTAT_GA_M);
+	else
+		dev_info(&pdev->dev, "VME geographical address is set to %d\n",
+			geoid);
+
 	dev_info(&pdev->dev, "VME Write and flush and error check is %s\n",
 		err_chk ? "enabled" : "disabled");
 
-	if(tsi148_crcsr_init(pdev)) {
+	if (tsi148_crcsr_init(tsi148_bridge, pdev)) {
 		dev_err(&pdev->dev, "CR/CSR configuration failed.\n");
 		goto err_crcsr;
-
 	}
 
-	/* Need to save tsi148_bridge pointer locally in link list for use in
-	 * tsi148_remove()
-	 */
 	retval = vme_register_bridge(tsi148_bridge);
 	if (retval != 0) {
 		dev_err(&pdev->dev, "Chip Registration failed.\n");
 		goto err_reg;
 	}
 
+	pci_set_drvdata(pdev, tsi148_bridge);
+
 	/* Clear VME bus "board fail", and "power-up reset" lines */
-	data = ioread32be(tsi148_bridge->base + TSI148_LCSR_VSTAT);
+	data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT);
 	data &= ~TSI148_LCSR_VSTAT_BRDFL;
 	data |= TSI148_LCSR_VSTAT_CPURST;
-	iowrite32be(data, tsi148_bridge->base + TSI148_LCSR_VSTAT);
+	iowrite32be(data, tsi148_device->base + TSI148_LCSR_VSTAT);
 
 	return 0;
 
 	vme_unregister_bridge(tsi148_bridge);
 err_reg:
-	tsi148_crcsr_exit(pdev);
+	tsi148_crcsr_exit(tsi148_bridge, pdev);
 err_crcsr:
 err_lm:
 	/* resources are stored in link list */
@@ -2519,15 +2509,17 @@ err_master:
 		kfree(master_image);
 	}
 
-	tsi148_irq_exit(pdev);
+	tsi148_irq_exit(tsi148_device, pdev);
 err_irq:
 err_test:
-	iounmap(tsi148_bridge->base);
+	iounmap(tsi148_device->base);
 err_remap:
 	pci_release_regions(pdev);
 err_resource:
 	pci_disable_device(pdev);
 err_enable:
+	kfree(tsi148_device);
+err_driver:
 	kfree(tsi148_bridge);
 err_struct:
 	return retval;
@@ -2541,56 +2533,58 @@ static void tsi148_remove(struct pci_dev
 	struct vme_slave_resource *slave_image;
 	struct vme_dma_resource *dma_ctrlr;
 	int i;
+	struct tsi148_driver *bridge;
+	struct vme_bridge *tsi148_bridge = pci_get_drvdata(pdev);
 
-	dev_dbg(&pdev->dev, "Driver is being unloaded.\n");
+	bridge = tsi148_bridge->driver_priv;
 
-	/* XXX We need to find the pdev->dev in the list of vme_bridge->dev's */
+
+	dev_dbg(&pdev->dev, "Driver is being unloaded.\n");
 
 	/*
 	 *  Shutdown all inbound and outbound windows.
 	 */
 	for (i = 0; i < 8; i++) {
-		iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		iowrite32be(0, bridge->base + TSI148_LCSR_IT[i] +
 			TSI148_LCSR_OFFSET_ITAT);
-		iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		iowrite32be(0, bridge->base + TSI148_LCSR_OT[i] +
 			TSI148_LCSR_OFFSET_OTAT);
 	}
 
 	/*
 	 *  Shutdown Location monitor.
 	 */
-	iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_LMAT);
+	iowrite32be(0, bridge->base + TSI148_LCSR_LMAT);
 
 	/*
 	 *  Shutdown CRG map.
 	 */
-	iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_CSRAT);
+	iowrite32be(0, bridge->base + TSI148_LCSR_CSRAT);
 
 	/*
 	 *  Clear error status.
 	 */
-	iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_EDPAT);
-	iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_VEAT);
-	iowrite32be(0x07000700, tsi148_bridge->base + TSI148_LCSR_PSTAT);
+	iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_EDPAT);
+	iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_VEAT);
+	iowrite32be(0x07000700, bridge->base + TSI148_LCSR_PSTAT);
 
 	/*
 	 *  Remove VIRQ interrupt (if any)
 	 */
-	if (ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR) & 0x800) {
-		iowrite32be(0x8000, tsi148_bridge->base + TSI148_LCSR_VICR);
-	}
+	if (ioread32be(bridge->base + TSI148_LCSR_VICR) & 0x800)
+		iowrite32be(0x8000, bridge->base + TSI148_LCSR_VICR);
 
 	/*
 	 *  Map all Interrupts to PCI INTA
 	 */
-	iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTM1);
-	iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTM2);
+	iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM1);
+	iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM2);
 
-	tsi148_irq_exit(pdev);
+	tsi148_irq_exit(bridge, pdev);
 
 	vme_unregister_bridge(tsi148_bridge);
 
-	tsi148_crcsr_exit(pdev);
+	tsi148_crcsr_exit(tsi148_bridge, pdev);
 
 	/* resources are stored in link list */
 	list_for_each(pos, &(tsi148_bridge->dma_resources)) {
@@ -2608,19 +2602,22 @@ static void tsi148_remove(struct pci_dev
 
 	/* resources are stored in link list */
 	list_for_each(pos, &(tsi148_bridge->master_resources)) {
-		master_image = list_entry(pos, struct vme_master_resource,				list);
+		master_image = list_entry(pos, struct vme_master_resource,
+			list);
 		list_del(pos);
 		kfree(master_image);
 	}
 
-	tsi148_irq_exit(pdev);
+	tsi148_irq_exit(bridge, pdev);
 
-	iounmap(tsi148_bridge->base);
+	iounmap(bridge->base);
 
 	pci_release_regions(pdev);
 
 	pci_disable_device(pdev);
 
+	kfree(tsi148_bridge->driver_priv);
+
 	kfree(tsi148_bridge);
 }
 
@@ -2634,250 +2631,11 @@ static void __exit tsi148_exit(void)
 MODULE_PARM_DESC(err_chk, "Check for VME errors on reads and writes");
 module_param(err_chk, bool, 0);
 
+MODULE_PARM_DESC(geoid, "Override geographical addressing");
+module_param(geoid, int, 0);
+
 MODULE_DESCRIPTION("VME driver for the Tundra Tempe VME bridge");
 MODULE_LICENSE("GPL");
 
 module_init(tsi148_init);
 module_exit(tsi148_exit);
-
-/*----------------------------------------------------------------------------
- * STAGING
- *--------------------------------------------------------------------------*/
-
-#if 0
-/*
- * Direct Mode DMA transfer
- *
- * XXX Not looking at direct mode for now, we can always use link list mode
- *     with a single entry.
- */
-int tsi148_dma_run(struct vme_dma_resource *resource, struct vme_dma_attr src,
-	struct vme_dma_attr dest, size_t count)
-{
-	u32 dctlreg = 0;
-	unsigned int tmp;
-	int val;
-	int channel, x;
-	struct vmeDmaPacket *cur_dma;
-	struct tsi148_dma_descriptor *dmaLL;
-
-	/* direct mode */
-	dctlreg = 0x800000;
-
-	for (x = 0; x < 8; x++) {	/* vme block size */
-		if ((32 << x) >= vmeDma->maxVmeBlockSize) {
-			break;
-		}
-	}
-	if (x == 8)
-		x = 7;
-	dctlreg |= (x << 12);
-
-	for (x = 0; x < 8; x++) {	/* pci block size */
-		if ((32 << x) >= vmeDma->maxPciBlockSize) {
-			break;
-		}
-	}
-	if (x == 8)
-		x = 7;
-	dctlreg |= (x << 4);
-
-	if (vmeDma->vmeBackOffTimer) {
-		for (x = 1; x < 8; x++) {	/* vme timer */
-			if ((1 << (x - 1)) >= vmeDma->vmeBackOffTimer) {
-				break;
-			}
-		}
-		if (x == 8)
-			x = 7;
-		dctlreg |= (x << 8);
-	}
-
-	if (vmeDma->pciBackOffTimer) {
-		for (x = 1; x < 8; x++) {	/* pci timer */
-			if ((1 << (x - 1)) >= vmeDma->pciBackOffTimer) {
-				break;
-			}
-		}
-		if (x == 8)
-			x = 7;
-		dctlreg |= (x << 0);
-	}
-
-	/* Program registers for DMA transfer */
-	iowrite32be(dmaLL->dsau, tsi148_bridge->base +
-		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSAU);
-	iowrite32be(dmaLL->dsal, tsi148_bridge->base +
-		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSAL);
-	iowrite32be(dmaLL->ddau, tsi148_bridge->base +
-		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDAU);
-	iowrite32be(dmaLL->ddal, tsi148_bridge->base +
-		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDAL);
-	iowrite32be(dmaLL->dsat, tsi148_bridge->base +
-		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSAT);
-	iowrite32be(dmaLL->ddat, tsi148_bridge->base +
-		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDAT);
-	iowrite32be(dmaLL->dcnt, tsi148_bridge->base +
-		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCNT);
-	iowrite32be(dmaLL->ddbs, tsi148_bridge->base +
-		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDBS);
-
-	/* Start the operation */
-	iowrite32be(dctlreg | 0x2000000, tsi148_bridge->base +
-		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
-
-	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] +
-		TSI148_LCSR_OFFSET_DSTA);
-	wait_event_interruptible(dma_queue[channel], (tmp & 0x1000000) == 0);
-
-	/*
-	 * Read status register, we should probably do this in some error
-	 * handler rather than here so that we can be sure we haven't kicked off
-	 * another DMA transfer.
-	 */
-	val = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] +
-		TSI148_LCSR_OFFSET_DSTA);
-
-	vmeDma->vmeDmaStatus = 0;
-	if (val & 0x10000000) {
-		printk(KERN_ERR
-			"DMA Error in DMA_tempe_irqhandler DSTA=%08X\n",
-			val);
-		vmeDma->vmeDmaStatus = val;
-
-	}
-	return (0);
-}
-#endif
-
-#if 0
-
-/* Global VME controller information */
-struct pci_dev *vme_pci_dev;
-
-/*
- * Set the VME bus arbiter with the requested attributes
- */
-int tempe_set_arbiter(vmeArbiterCfg_t * vmeArb)
-{
-	int temp_ctl = 0;
-	int gto = 0;
-
-	temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VCTRL);
-	temp_ctl &= 0xFFEFFF00;
-
-	if (vmeArb->globalTimeoutTimer == 0xFFFFFFFF) {
-		gto = 8;
-	} else if (vmeArb->globalTimeoutTimer > 2048) {
-		return (-EINVAL);
-	} else if (vmeArb->globalTimeoutTimer == 0) {
-		gto = 0;
-	} else {
-		gto = 1;
-		while ((16 * (1 << (gto - 1))) < vmeArb->globalTimeoutTimer) {
-			gto += 1;
-		}
-	}
-	temp_ctl |= gto;
-
-	if (vmeArb->arbiterMode != VME_PRIORITY_MODE) {
-		temp_ctl |= 1 << 6;
-	}
-
-	if (vmeArb->arbiterTimeoutFlag) {
-		temp_ctl |= 1 << 7;
-	}
-
-	if (vmeArb->noEarlyReleaseFlag) {
-		temp_ctl |= 1 << 20;
-	}
-	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_VCTRL);
-
-	return (0);
-}
-
-/*
- * Return the attributes of the VME bus arbiter.
- */
-int tempe_get_arbiter(vmeArbiterCfg_t * vmeArb)
-{
-	int temp_ctl = 0;
-	int gto = 0;
-
-
-	temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VCTRL);
-
-	gto = temp_ctl & 0xF;
-	if (gto != 0) {
-		vmeArb->globalTimeoutTimer = (16 * (1 << (gto - 1)));
-	}
-
-	if (temp_ctl & (1 << 6)) {
-		vmeArb->arbiterMode = VME_R_ROBIN_MODE;
-	} else {
-		vmeArb->arbiterMode = VME_PRIORITY_MODE;
-	}
-
-	if (temp_ctl & (1 << 7)) {
-		vmeArb->arbiterTimeoutFlag = 1;
-	}
-
-	if (temp_ctl & (1 << 20)) {
-		vmeArb->noEarlyReleaseFlag = 1;
-	}
-
-	return (0);
-}
-
-/*
- * Set the VME bus requestor with the requested attributes
- */
-int tempe_set_requestor(vmeRequesterCfg_t * vmeReq)
-{
-	int temp_ctl = 0;
-
-	temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL);
-	temp_ctl &= 0xFFFF0000;
-
-	if (vmeReq->releaseMode == 1) {
-		temp_ctl |= (1 << 3);
-	}
-
-	if (vmeReq->fairMode == 1) {
-		temp_ctl |= (1 << 2);
-	}
-
-	temp_ctl |= (vmeReq->timeonTimeoutTimer & 7) << 8;
-	temp_ctl |= (vmeReq->timeoffTimeoutTimer & 7) << 12;
-	temp_ctl |= vmeReq->requestLevel;
-
-	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_VMCTRL);
-	return (0);
-}
-
-/*
- * Return the attributes of the VME bus requestor
- */
-int tempe_get_requestor(vmeRequesterCfg_t * vmeReq)
-{
-	int temp_ctl = 0;
-
-	temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL);
-
-	if (temp_ctl & 0x18) {
-		vmeReq->releaseMode = 1;
-	}
-
-	if (temp_ctl & (1 << 2)) {
-		vmeReq->fairMode = 1;
-	}
-
-	vmeReq->requestLevel = temp_ctl & 3;
-	vmeReq->timeonTimeoutTimer = (temp_ctl >> 8) & 7;
-	vmeReq->timeoffTimeoutTimer = (temp_ctl >> 12) & 7;
-
-	return (0);
-}
-
-
-#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/bridges/vme_tsi148.h linux-libre-2.6.34-gnu1/drivers/staging/vme/bridges/vme_tsi148.h
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/bridges/vme_tsi148.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/bridges/vme_tsi148.h	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,22 @@
 #define TSI148_MAX_MAILBOX		4	/* Max Mail Box registers */
 #define TSI148_MAX_SEMAPHORE		8	/* Max Semaphores */
 
+/* Structure used to hold driver specific information */
+struct tsi148_driver {
+	void *base;	/* Base Address of device registers */
+	wait_queue_head_t dma_queue[2];
+	wait_queue_head_t iack_queue;
+	void (*lm_callback[4])(int);	/* Called in interrupt handler */
+	void *crcsr_kernel;
+	dma_addr_t crcsr_bus;
+	struct vme_master_resource *flush_image;
+	struct mutex vme_rmw;		/* Only one RMW cycle at a time */
+	struct mutex vme_int;		/*
+					 * Only one VME interrupt can be
+					 * generated at a time, provide locking
+					 */
+};
+
 /*
  * Layout of a DMAC Linked-List Descriptor
  *
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/devices/vme_user.c linux-libre-2.6.34-gnu1/drivers/staging/vme/devices/vme_user.c
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/devices/vme_user.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/devices/vme_user.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,8 +1,8 @@
 /*
  * VMEbus User access driver
  *
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Author: Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * Based on work by:
  *   Tom Armistead and Ajit Prem
@@ -28,6 +28,7 @@
 #include <linux/pagemap.h>
 #include <linux/pci.h>
 #include <linux/semaphore.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/syscalls.h>
 #include <linux/types.h>
@@ -400,8 +401,39 @@ static ssize_t vme_user_write(struct fil
 
 static loff_t vme_user_llseek(struct file *file, loff_t off, int whence)
 {
-	printk(KERN_ERR "Llseek currently incomplete\n");
-	return -EINVAL;
+	loff_t absolute = -1;
+	unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
+	size_t image_size;
+
+	down(&image[minor].sem);
+	image_size = vme_get_size(image[minor].resource);
+
+	switch (whence) {
+	case SEEK_SET:
+		absolute = off;
+		break;
+	case SEEK_CUR:
+		absolute = file->f_pos + off;
+		break;
+	case SEEK_END:
+		absolute = image_size + off;
+		break;
+	default:
+		up(&image[minor].sem);
+		return -EINVAL;
+		break;
+	}
+
+	if ((absolute < 0) || (absolute >= image_size)) {
+		up(&image[minor].sem);
+		return -EINVAL;
+	}
+
+	file->f_pos = absolute;
+
+	up(&image[minor].sem);
+
+	return absolute;
 }
 
 /*
@@ -574,8 +606,8 @@ static int __init vme_user_init(void)
 	 * in future revisions if that ever becomes necessary.
 	 */
 	if (bus_num > USER_BUS_MAX) {
-		printk(KERN_ERR "%s: Driver only able to handle %d PIO2 "
-			"Cards\n", driver_name, USER_BUS_MAX);
+		printk(KERN_ERR "%s: Driver only able to handle %d buses\n",
+			driver_name, USER_BUS_MAX);
 		bus_num = USER_BUS_MAX;
 	}
 
@@ -670,8 +702,12 @@ static int __init vme_user_probe(struct
 	/* Request slave resources and allocate buffers (128kB wide) */
 	for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) {
 		/* XXX Need to properly request attributes */
+		/* For ca91cx42 bridge there are only two slave windows
+		 * supporting A16 addressing, so we request A24 supported
+		 * by all windows.
+		 */
 		image[i].resource = vme_slave_request(vme_user_bridge,
-			VME_A16, VME_SCT);
+			VME_A24, VME_SCT);
 		if (image[i].resource == NULL) {
 			printk(KERN_WARNING "Unable to allocate slave "
 				"resource\n");
@@ -703,6 +739,14 @@ static int __init vme_user_probe(struct
 				"resource\n");
 			goto err_master;
 		}
+		image[i].size_buf = PCI_BUF_SIZE;
+		image[i].kern_buf = kmalloc(image[i].size_buf, GFP_KERNEL);
+		if (image[i].kern_buf == NULL) {
+			printk(KERN_WARNING "Unable to allocate memory for "
+				"master window buffers\n");
+			err = -ENOMEM;
+			goto err_master_buf;
+		}
 	}
 
 	/* Create sysfs entries - on udev systems this creates the dev files */
@@ -756,6 +800,9 @@ err_sysfs:
 
 	/* Ensure counter set correcty to unalloc all master windows */
 	i = MASTER_MAX + 1;
+err_master_buf:
+	for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++)
+		kfree(image[i].kern_buf);
 err_master:
 	while (i > MASTER_MINOR) {
 		i--;
@@ -791,6 +838,9 @@ static int __exit vme_user_remove(struct
 	}
 	class_destroy(vme_user_sysfs_class);
 
+	for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++)
+		kfree(image[i].kern_buf);
+
 	for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) {
 		vme_slave_set(image[i].resource, 0, 0, 0, 0, VME_A32, 0);
 		vme_slave_free(image[i].resource);
@@ -818,7 +868,7 @@ MODULE_PARM_DESC(bus, "Enumeration of VM
 module_param_array(bus, int, &bus_num, 0);
 
 MODULE_DESCRIPTION("VME User Space Access Driver");
-MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com");
+MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
 MODULE_LICENSE("GPL");
 
 module_init(vme_user_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/vme/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -14,4 +14,6 @@ source "drivers/staging/vme/bridges/Kcon
 
 source "drivers/staging/vme/devices/Kconfig"
 
+source "drivers/staging/vme/boards/Kconfig"
+
 endif # VME
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/Makefile linux-libre-2.6.34-gnu1/drivers/staging/vme/Makefile
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,3 +5,4 @@ obj-$(CONFIG_VME_BUS)		+= vme.o
 
 obj-y				+= bridges/
 obj-y				+= devices/
+obj-y				+= boards/
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/TODO linux-libre-2.6.34-gnu1/drivers/staging/vme/TODO
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/TODO	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/TODO	2010-05-16 17:17:36.000000000 -0400
@@ -4,28 +4,6 @@
 API
 ===
 
-DMA Resource Allocation incomplete
-----------------------------------
-
-The current DMA resource Allocation provides no means of selecting the
-suitability of a DMA controller based on it's supported modes of operation, as
-opposed to the resource allocation mechanisms for master and slave windows:
-
-	struct vme_resource *vme_dma_request(struct device *dev);
-
-As opposed to:
-
-	struct vme_resource * vme_master_request(struct device *dev,
-		vme_address_t aspace, vme_cycle_t cycle, vme_width_t width);
-
-The TSI148 can perform, VME-to-PCI, PCI-to-VME, PATTERN-to-VME, PATTERN-to-PCI,
-VME-to-VME and PCI-to-PCI transfers. The CA91C142 can only provide VME-to-PCI
-and PCI-to-VME.
-
-Add a mechanism to select a VME controller based on source/target type,
-required aspace, cycle and width requirements.
-
-
 Master window broadcast select mask
 -----------------------------------
 
@@ -59,7 +37,6 @@ chips. They are currently not supported
 Core
 ====
 
-- Rename vme_master_resource's "pci_resource" to be bus agnostic.
 - Improve generic sanity checks (Such as does an offset and size fit within a
   window and parameter checking).
 
@@ -69,7 +46,6 @@ Bridge Support
 Tempe (tsi148)
 --------------
 
-- Driver can currently only support a single bridge.
 - 2eSST Broadcast mode.
 - Mailboxes unsupported.
 - Improve error detection.
@@ -80,10 +56,6 @@ Tempe (tsi148)
 Universe II (ca91c142)
 ----------------------
 
-- Driver can currently only support a single bridge.
-- DMA unsupported.
-- RMW transactions unsupported.
-- Location Monitors unsupported.
 - Mailboxes unsupported.
 - Error Detection.
 - Control of prefetch size, threshold.
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/vme_api.txt linux-libre-2.6.34-gnu1/drivers/staging/vme/vme_api.txt
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/vme_api.txt	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/vme_api.txt	2010-05-16 17:17:36.000000000 -0400
@@ -77,16 +77,21 @@ driver in question:
 	struct vme_resource * vme_slave_request(struct device *dev,
 		vme_address_t aspace, vme_cycle_t cycle);
 
-	struct vme_resource *vme_dma_request(struct device *dev);
+	struct vme_resource *vme_dma_request(struct device *dev,
+		vme_dma_route_t route);
 
 For slave windows these attributes are split into those of type 'vme_address_t'
-and 'vme_cycle_t'. Master windows add a further set of attributes 'vme_cycle_t'.
-These attributes are defined as bitmasks and as such any combination of the
-attributes can be requested for a single window, the core will assign a window
-that meets the requirements, returning a pointer of type vme_resource that
-should be used to identify the allocated resource when it is used. If an
-unallocated window fitting the requirements can not be found a NULL pointer will
-be returned.
+and 'vme_cycle_t'. Master windows add a further set of attributes
+'vme_cycle_t'.  These attributes are defined as bitmasks and as such any
+combination of the attributes can be requested for a single window, the core
+will assign a window that meets the requirements, returning a pointer of type
+vme_resource that should be used to identify the allocated resource when it is
+used. For DMA controllers, the request function requires the potential
+direction of any transfers to be provided in the route attributes. This is
+typically VME-to-MEM and/or MEM-to-VME, though some hardware can support
+VME-to-VME and MEM-to-MEM transfers as well as test pattern generation. If an
+unallocated window fitting the requirements can not be found a NULL pointer
+will be returned.
 
 Functions are also provided to free window allocations once they are no longer
 required. These functions should be passed the pointer to the resource provided
@@ -237,6 +242,12 @@ covered under "Transfer Attributes"):
 		struct vme_dma_attr *src, struct vme_dma_attr *dest,
 		size_t count);
 
+NOTE:	The detailed attributes of the transfers source and destination
+	are not checked until an entry is added to a DMA list, the request
+	for a DMA channel purely checks the directions in which the
+	controller is expected to transfer data. As a result it is
+	possible for this call to return an error, for example if the
+	source or destination is in an unsupported VME address space.
 
 Transfer Attributes
 -------------------
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/vme_bridge.h linux-libre-2.6.34-gnu1/drivers/staging/vme/vme_bridge.h
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/vme_bridge.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/vme_bridge.h	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,7 @@ struct vme_master_resource {
 	vme_address_t address_attr;
 	vme_cycle_t cycle_attr;
 	vme_width_t width_attr;
-	struct resource pci_resource;	/* XXX Rename to be bus agnostic */
+	struct resource bus_resource;
 	void *kern_base;
 };
 
@@ -64,6 +64,7 @@ struct vme_dma_resource {
 	int number;
 	struct list_head pending;
 	struct list_head running;
+	vme_dma_route_t route_attr;
 };
 
 struct vme_lm_resource {
@@ -101,7 +102,7 @@ struct vme_irq {
  * Currently we assume that all chips are PCI-based
  */
 struct vme_bridge {
-        char name[VMENAMSIZ];
+	char name[VMENAMSIZ];
 	int num;
 	struct list_head master_resources;
 	struct list_head slave_resources;
@@ -112,7 +113,7 @@ struct vme_bridge {
 
 	/* Bridge Info - XXX Move to private structure? */
 	struct device *parent;	/* Generic device struct (pdev->dev for PCI) */
-	void * base;		/* Base Address of device registers */
+	void *driver_priv;	/* Private pointer for the bridge driver */
 
 	struct device dev[VME_SLOTS_MAX];	/* Device registered with
 						 * device model on VME bus
@@ -151,8 +152,8 @@ struct vme_bridge {
 	int (*dma_list_empty) (struct vme_dma_list *);
 
 	/* Interrupt Functions */
-	void (*irq_set) (int, int, int);
-	int (*irq_generate) (int, int);
+	void (*irq_set) (struct vme_bridge *, int, int, int);
+	int (*irq_generate) (struct vme_bridge *, int, int);
 
 	/* Location monitor functions */
 	int (*lm_set) (struct vme_lm_resource *, unsigned long long,
@@ -163,102 +164,12 @@ struct vme_bridge {
 	int (*lm_detach) (struct vme_lm_resource *, int);
 
 	/* CR/CSR space functions */
-	int (*slot_get) (void);
-	/* Use standard master read and write functions to access CR/CSR */
-
-#if 0
-	int (*set_prefetch) (void);
-	int (*get_prefetch) (void);
-	int (*set_arbiter) (void);
-	int (*get_arbiter) (void);
-	int (*set_requestor) (void);
-	int (*get_requestor) (void);
-#endif
+	int (*slot_get) (struct vme_bridge *);
 };
 
 void vme_irq_handler(struct vme_bridge *, int, int);
 
-int vme_register_bridge (struct vme_bridge *);
-void vme_unregister_bridge (struct vme_bridge *);
+int vme_register_bridge(struct vme_bridge *);
+void vme_unregister_bridge(struct vme_bridge *);
 
 #endif /* _VME_BRIDGE_H_ */
-
-#if 0
-/*
- *  VMEbus GET INFO Arg Structure
- */
-struct vmeInfoCfg {
-	int vmeSlotNum;		/*  VME slot number of interest */
-	int boardResponded;	/* Board responded */
-	char sysConFlag;	/*  System controller flag */
-	int vmeControllerID;	/*  Vendor/device ID of VME bridge */
-	int vmeControllerRev;	/*  Revision of VME bridge */
-	char osName[8];		/*  Name of OS e.g. "Linux" */
-	int vmeSharedDataValid;	/*  Validity of data struct */
-	int vmeDriverRev;	/*  Revision of VME driver */
-	unsigned int vmeAddrHi[8];	/* Address on VME bus */
-	unsigned int vmeAddrLo[8];	/* Address on VME bus */
-	unsigned int vmeSize[8];	/* Size on VME bus */
-	unsigned int vmeAm[8];	/* Address modifier on VME bus */
-	int reserved;		/* For future use */
-};
-typedef struct vmeInfoCfg vmeInfoCfg_t;
-
-/*
- *  VMEbus Requester Arg Structure
- */
-struct vmeRequesterCfg {
-	int requestLevel;	/*  Requester Bus Request Level */
-	char fairMode;		/*  Requester Fairness Mode Indicator */
-	int releaseMode;	/*  Requester Bus Release Mode */
-	int timeonTimeoutTimer;	/*  Master Time-on Time-out Timer */
-	int timeoffTimeoutTimer;	/*  Master Time-off Time-out Timer */
-	int reserved;		/* For future use */
-};
-typedef struct vmeRequesterCfg vmeRequesterCfg_t;
-
-/*
- *  VMEbus Arbiter Arg Structure
- */
-struct vmeArbiterCfg {
-	vme_arbitration_t arbiterMode;	/*  Arbitration Scheduling Algorithm */
-	char arbiterTimeoutFlag;	/*  Arbiter Time-out Timer Indicator */
-	int globalTimeoutTimer;	/*  VMEbus Global Time-out Timer */
-	char noEarlyReleaseFlag;	/*  No Early Release on BBUSY */
-	int reserved;		/* For future use */
-};
-typedef struct vmeArbiterCfg vmeArbiterCfg_t;
-
-
-/*
- *  VMEbus RMW Configuration Data
- */
-struct vmeRmwCfg {
-	unsigned int targetAddrU;	/*  VME Address (Upper) to trigger RMW cycle */
-	unsigned int targetAddr;	/*  VME Address (Lower) to trigger RMW cycle */
-	vme_address_t addrSpace;	/*  VME Address Space */
-	int enableMask;		/*  Bit mask defining the bits of interest */
-	int compareData;	/*  Data to be compared with the data read */
-	int swapData;		/*  Data written to the VMEbus on success */
-	int maxAttempts;	/*  Maximum times to try */
-	int numAttempts;	/*  Number of attempts before success */
-	int reserved;		/* For future use */
-
-};
-typedef struct vmeRmwCfg vmeRmwCfg_t;
-
-/*
- *  VMEbus Location Monitor Arg Structure
- */
-struct vmeLmCfg {
-	unsigned int addrU;	/*  Location Monitor Address upper */
-	unsigned int addr;	/*  Location Monitor Address lower */
-	vme_address_t addrSpace;	/*  Address Space */
-	int userAccessType;	/*  User/Supervisor Access Type */
-	int dataAccessType;	/*  Data/Program Access Type */
-	int lmWait;		/* Time to wait for access */
-	int lmEvents;		/* Lm event mask */
-	int reserved;		/* For future use */
-};
-typedef struct vmeLmCfg vmeLmCfg_t;
-#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/vme.c linux-libre-2.6.34-gnu1/drivers/staging/vme/vme.c
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/vme.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/vme.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,8 +1,8 @@
 /*
  * VME Bridge Framework
  *
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Author: Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * Based on work by Tom Armistead and Ajit Prem
  * Copyright 2004 Motorola Inc.
@@ -29,6 +29,7 @@
 #include <linux/syscalls.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 
 #include "vme.h"
 #include "vme_bridge.h"
@@ -37,8 +38,8 @@
 static unsigned int vme_bus_numbers;
 DEFINE_MUTEX(vme_bus_num_mtx);
 
-static void __exit vme_exit (void);
-static int __init vme_init (void);
+static void __exit vme_exit(void);
+static int __init vme_init(void);
 
 
 /*
@@ -86,26 +87,26 @@ static struct vme_bridge *find_bridge(st
  * XXX VME bridges could be available on buses other than PCI. At the momment
  *     this framework only supports PCI devices.
  */
-void * vme_alloc_consistent(struct vme_resource *resource, size_t size,
+void *vme_alloc_consistent(struct vme_resource *resource, size_t size,
 	dma_addr_t *dma)
 {
 	struct vme_bridge *bridge;
 	struct pci_dev *pdev;
 
-	if(resource == NULL) {
-		printk("No resource\n");
+	if (resource == NULL) {
+		printk(KERN_ERR "No resource\n");
 		return NULL;
 	}
 
 	bridge = find_bridge(resource);
-	if(bridge == NULL) {
-		printk("Can't find bridge\n");
+	if (bridge == NULL) {
+		printk(KERN_ERR "Can't find bridge\n");
 		return NULL;
 	}
 
 	/* Find pci_dev container of dev */
 	if (bridge->parent == NULL) {
-		printk("Dev entry NULL\n");
+		printk(KERN_ERR "Dev entry NULL\n");
 		return NULL;
 	}
 	pdev = container_of(bridge->parent, struct pci_dev, dev);
@@ -126,14 +127,14 @@ void vme_free_consistent(struct vme_reso
 	struct vme_bridge *bridge;
 	struct pci_dev *pdev;
 
-	if(resource == NULL) {
-		printk("No resource\n");
+	if (resource == NULL) {
+		printk(KERN_ERR "No resource\n");
 		return;
 	}
 
 	bridge = find_bridge(resource);
-	if(bridge == NULL) {
-		printk("Can't find bridge\n");
+	if (bridge == NULL) {
+		printk(KERN_ERR "Can't find bridge\n");
 		return;
 	}
 
@@ -216,7 +217,7 @@ static int vme_check_window(vme_address_
 		/* User Defined */
 		break;
 	default:
-		printk("Invalid address space\n");
+		printk(KERN_ERR "Invalid address space\n");
 		retval = -EINVAL;
 		break;
 	}
@@ -228,7 +229,7 @@ static int vme_check_window(vme_address_
  * Request a slave image with specific attributes, return some unique
  * identifier.
  */
-struct vme_resource * vme_slave_request(struct device *dev,
+struct vme_resource *vme_slave_request(struct device *dev,
 	vme_address_t address, vme_cycle_t cycle)
 {
 	struct vme_bridge *bridge;
@@ -249,13 +250,13 @@ struct vme_resource * vme_slave_request(
 			struct vme_slave_resource, list);
 
 		if (slave_image == NULL) {
-			printk("Registered NULL Slave resource\n");
+			printk(KERN_ERR "Registered NULL Slave resource\n");
 			continue;
 		}
 
 		/* Find an unlocked and compatible image */
 		mutex_lock(&(slave_image->mtx));
-		if(((slave_image->address_attr & address) == address) &&
+		if (((slave_image->address_attr & address) == address) &&
 			((slave_image->cycle_attr & cycle) == cycle) &&
 			(slave_image->locked == 0)) {
 
@@ -292,7 +293,7 @@ err_bus:
 }
 EXPORT_SYMBOL(vme_slave_request);
 
-int vme_slave_set (struct vme_resource *resource, int enabled,
+int vme_slave_set(struct vme_resource *resource, int enabled,
 	unsigned long long vme_base, unsigned long long size,
 	dma_addr_t buf_base, vme_address_t aspace, vme_cycle_t cycle)
 {
@@ -301,25 +302,25 @@ int vme_slave_set (struct vme_resource *
 	int retval;
 
 	if (resource->type != VME_SLAVE) {
-		printk("Not a slave resource\n");
+		printk(KERN_ERR "Not a slave resource\n");
 		return -EINVAL;
 	}
 
 	image = list_entry(resource->entry, struct vme_slave_resource, list);
 
 	if (bridge->slave_set == NULL) {
-		printk("Function not supported\n");
+		printk(KERN_ERR "Function not supported\n");
 		return -ENOSYS;
 	}
 
-	if(!(((image->address_attr & aspace) == aspace) &&
+	if (!(((image->address_attr & aspace) == aspace) &&
 		((image->cycle_attr & cycle) == cycle))) {
-		printk("Invalid attributes\n");
+		printk(KERN_ERR "Invalid attributes\n");
 		return -EINVAL;
 	}
 
 	retval = vme_check_window(aspace, vme_base, size);
-	if(retval)
+	if (retval)
 		return retval;
 
 	return bridge->slave_set(image, enabled, vme_base, size, buf_base,
@@ -327,7 +328,7 @@ int vme_slave_set (struct vme_resource *
 }
 EXPORT_SYMBOL(vme_slave_set);
 
-int vme_slave_get (struct vme_resource *resource, int *enabled,
+int vme_slave_get(struct vme_resource *resource, int *enabled,
 	unsigned long long *vme_base, unsigned long long *size,
 	dma_addr_t *buf_base, vme_address_t *aspace, vme_cycle_t *cycle)
 {
@@ -335,14 +336,14 @@ int vme_slave_get (struct vme_resource *
 	struct vme_slave_resource *image;
 
 	if (resource->type != VME_SLAVE) {
-		printk("Not a slave resource\n");
+		printk(KERN_ERR "Not a slave resource\n");
 		return -EINVAL;
 	}
 
 	image = list_entry(resource->entry, struct vme_slave_resource, list);
 
 	if (bridge->slave_get == NULL) {
-		printk("vme_slave_get not supported\n");
+		printk(KERN_ERR "vme_slave_get not supported\n");
 		return -EINVAL;
 	}
 
@@ -356,14 +357,14 @@ void vme_slave_free(struct vme_resource
 	struct vme_slave_resource *slave_image;
 
 	if (resource->type != VME_SLAVE) {
-		printk("Not a slave resource\n");
+		printk(KERN_ERR "Not a slave resource\n");
 		return;
 	}
 
 	slave_image = list_entry(resource->entry, struct vme_slave_resource,
 		list);
 	if (slave_image == NULL) {
-		printk("Can't find slave resource\n");
+		printk(KERN_ERR "Can't find slave resource\n");
 		return;
 	}
 
@@ -384,7 +385,7 @@ EXPORT_SYMBOL(vme_slave_free);
  * Request a master image with specific attributes, return some unique
  * identifier.
  */
-struct vme_resource * vme_master_request(struct device *dev,
+struct vme_resource *vme_master_request(struct device *dev,
 	vme_address_t address, vme_cycle_t cycle, vme_width_t dwidth)
 {
 	struct vme_bridge *bridge;
@@ -411,7 +412,7 @@ struct vme_resource * vme_master_request
 
 		/* Find an unlocked and compatible image */
 		spin_lock(&(master_image->lock));
-		if(((master_image->address_attr & address) == address) &&
+		if (((master_image->address_attr & address) == address) &&
 			((master_image->cycle_attr & cycle) == cycle) &&
 			((master_image->width_attr & dwidth) == dwidth) &&
 			(master_image->locked == 0)) {
@@ -452,7 +453,7 @@ err_bus:
 }
 EXPORT_SYMBOL(vme_master_request);
 
-int vme_master_set (struct vme_resource *resource, int enabled,
+int vme_master_set(struct vme_resource *resource, int enabled,
 	unsigned long long vme_base, unsigned long long size,
 	vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
 {
@@ -461,26 +462,26 @@ int vme_master_set (struct vme_resource
 	int retval;
 
 	if (resource->type != VME_MASTER) {
-		printk("Not a master resource\n");
+		printk(KERN_ERR "Not a master resource\n");
 		return -EINVAL;
 	}
 
 	image = list_entry(resource->entry, struct vme_master_resource, list);
 
 	if (bridge->master_set == NULL) {
-		printk("vme_master_set not supported\n");
+		printk(KERN_WARNING "vme_master_set not supported\n");
 		return -EINVAL;
 	}
 
-	if(!(((image->address_attr & aspace) == aspace) &&
+	if (!(((image->address_attr & aspace) == aspace) &&
 		((image->cycle_attr & cycle) == cycle) &&
 		((image->width_attr & dwidth) == dwidth))) {
-		printk("Invalid attributes\n");
+		printk(KERN_WARNING "Invalid attributes\n");
 		return -EINVAL;
 	}
 
 	retval = vme_check_window(aspace, vme_base, size);
-	if(retval)
+	if (retval)
 		return retval;
 
 	return bridge->master_set(image, enabled, vme_base, size, aspace,
@@ -488,7 +489,7 @@ int vme_master_set (struct vme_resource
 }
 EXPORT_SYMBOL(vme_master_set);
 
-int vme_master_get (struct vme_resource *resource, int *enabled,
+int vme_master_get(struct vme_resource *resource, int *enabled,
 	unsigned long long *vme_base, unsigned long long *size,
 	vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
 {
@@ -496,14 +497,14 @@ int vme_master_get (struct vme_resource
 	struct vme_master_resource *image;
 
 	if (resource->type != VME_MASTER) {
-		printk("Not a master resource\n");
+		printk(KERN_ERR "Not a master resource\n");
 		return -EINVAL;
 	}
 
 	image = list_entry(resource->entry, struct vme_master_resource, list);
 
 	if (bridge->master_get == NULL) {
-		printk("vme_master_set not supported\n");
+		printk(KERN_WARNING "vme_master_set not supported\n");
 		return -EINVAL;
 	}
 
@@ -515,7 +516,7 @@ EXPORT_SYMBOL(vme_master_get);
 /*
  * Read data out of VME space into a buffer.
  */
-ssize_t vme_master_read (struct vme_resource *resource, void *buf, size_t count,
+ssize_t vme_master_read(struct vme_resource *resource, void *buf, size_t count,
 	loff_t offset)
 {
 	struct vme_bridge *bridge = find_bridge(resource);
@@ -523,12 +524,12 @@ ssize_t vme_master_read (struct vme_reso
 	size_t length;
 
 	if (bridge->master_read == NULL) {
-		printk("Reading from resource not supported\n");
+		printk(KERN_WARNING "Reading from resource not supported\n");
 		return -EINVAL;
 	}
 
 	if (resource->type != VME_MASTER) {
-		printk("Not a master resource\n");
+		printk(KERN_ERR "Not a master resource\n");
 		return -EINVAL;
 	}
 
@@ -537,7 +538,7 @@ ssize_t vme_master_read (struct vme_reso
 	length = vme_get_size(resource);
 
 	if (offset > length) {
-		printk("Invalid Offset\n");
+		printk(KERN_WARNING "Invalid Offset\n");
 		return -EFAULT;
 	}
 
@@ -552,7 +553,7 @@ EXPORT_SYMBOL(vme_master_read);
 /*
  * Write data out to VME space from a buffer.
  */
-ssize_t vme_master_write (struct vme_resource *resource, void *buf,
+ssize_t vme_master_write(struct vme_resource *resource, void *buf,
 	size_t count, loff_t offset)
 {
 	struct vme_bridge *bridge = find_bridge(resource);
@@ -560,12 +561,12 @@ ssize_t vme_master_write (struct vme_res
 	size_t length;
 
 	if (bridge->master_write == NULL) {
-		printk("Writing to resource not supported\n");
+		printk(KERN_WARNING "Writing to resource not supported\n");
 		return -EINVAL;
 	}
 
 	if (resource->type != VME_MASTER) {
-		printk("Not a master resource\n");
+		printk(KERN_ERR "Not a master resource\n");
 		return -EINVAL;
 	}
 
@@ -574,7 +575,7 @@ ssize_t vme_master_write (struct vme_res
 	length = vme_get_size(resource);
 
 	if (offset > length) {
-		printk("Invalid Offset\n");
+		printk(KERN_WARNING "Invalid Offset\n");
 		return -EFAULT;
 	}
 
@@ -588,19 +589,19 @@ EXPORT_SYMBOL(vme_master_write);
 /*
  * Perform RMW cycle to provided location.
  */
-unsigned int vme_master_rmw (struct vme_resource *resource, unsigned int mask,
+unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask,
 	unsigned int compare, unsigned int swap, loff_t offset)
 {
 	struct vme_bridge *bridge = find_bridge(resource);
 	struct vme_master_resource *image;
 
 	if (bridge->master_rmw == NULL) {
-		printk("Writing to resource not supported\n");
+		printk(KERN_WARNING "Writing to resource not supported\n");
 		return -EINVAL;
 	}
 
 	if (resource->type != VME_MASTER) {
-		printk("Not a master resource\n");
+		printk(KERN_ERR "Not a master resource\n");
 		return -EINVAL;
 	}
 
@@ -615,14 +616,14 @@ void vme_master_free(struct vme_resource
 	struct vme_master_resource *master_image;
 
 	if (resource->type != VME_MASTER) {
-		printk("Not a master resource\n");
+		printk(KERN_ERR "Not a master resource\n");
 		return;
 	}
 
 	master_image = list_entry(resource->entry, struct vme_master_resource,
 		list);
 	if (master_image == NULL) {
-		printk("Can't find master resource\n");
+		printk(KERN_ERR "Can't find master resource\n");
 		return;
 	}
 
@@ -643,7 +644,7 @@ EXPORT_SYMBOL(vme_master_free);
  * Request a DMA controller with specific attributes, return some unique
  * identifier.
  */
-struct vme_resource *vme_dma_request(struct device *dev)
+struct vme_resource *vme_dma_request(struct device *dev, vme_dma_route_t route)
 {
 	struct vme_bridge *bridge;
 	struct list_head *dma_pos = NULL;
@@ -666,13 +667,15 @@ struct vme_resource *vme_dma_request(str
 			struct vme_dma_resource, list);
 
 		if (dma_ctrlr == NULL) {
-			printk("Registered NULL DMA resource\n");
+			printk(KERN_ERR "Registered NULL DMA resource\n");
 			continue;
 		}
 
-		/* Find an unlocked controller */
+		/* Find an unlocked and compatible controller */
 		mutex_lock(&(dma_ctrlr->mtx));
-		if(dma_ctrlr->locked == 0) {
+		if (((dma_ctrlr->route_attr & route) == route) &&
+			(dma_ctrlr->locked == 0)) {
+
 			dma_ctrlr->locked = 1;
 			mutex_unlock(&(dma_ctrlr->mtx));
 			allocated_ctrlr = dma_ctrlr;
@@ -715,16 +718,15 @@ struct vme_dma_list *vme_new_dma_list(st
 	struct vme_dma_list *dma_list;
 
 	if (resource->type != VME_DMA) {
-		printk("Not a DMA resource\n");
+		printk(KERN_ERR "Not a DMA resource\n");
 		return NULL;
 	}
 
 	ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
 
-	dma_list = (struct vme_dma_list *)kmalloc(
-		sizeof(struct vme_dma_list), GFP_KERNEL);
-	if(dma_list == NULL) {
-		printk("Unable to allocate memory for new dma list\n");
+	dma_list = kmalloc(sizeof(struct vme_dma_list), GFP_KERNEL);
+	if (dma_list == NULL) {
+		printk(KERN_ERR "Unable to allocate memory for new dma list\n");
 		return NULL;
 	}
 	INIT_LIST_HEAD(&(dma_list->entries));
@@ -744,17 +746,17 @@ struct vme_dma_attr *vme_dma_pattern_att
 	struct vme_dma_attr *attributes;
 	struct vme_dma_pattern *pattern_attr;
 
-	attributes = (struct vme_dma_attr *)kmalloc(
-		sizeof(struct vme_dma_attr), GFP_KERNEL);
-	if(attributes == NULL) {
-		printk("Unable to allocate memory for attributes structure\n");
+	attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL);
+	if (attributes == NULL) {
+		printk(KERN_ERR "Unable to allocate memory for attributes "
+			"structure\n");
 		goto err_attr;
 	}
 
-	pattern_attr = (struct vme_dma_pattern *)kmalloc(
-		sizeof(struct vme_dma_pattern), GFP_KERNEL);
-	if(pattern_attr == NULL) {
-		printk("Unable to allocate memory for pattern attributes\n");
+	pattern_attr = kmalloc(sizeof(struct vme_dma_pattern), GFP_KERNEL);
+	if (pattern_attr == NULL) {
+		printk(KERN_ERR "Unable to allocate memory for pattern "
+			"attributes\n");
 		goto err_pat;
 	}
 
@@ -784,17 +786,17 @@ struct vme_dma_attr *vme_dma_pci_attribu
 
 	/* XXX Run some sanity checks here */
 
-	attributes = (struct vme_dma_attr *)kmalloc(
-		sizeof(struct vme_dma_attr), GFP_KERNEL);
-	if(attributes == NULL) {
-		printk("Unable to allocate memory for attributes structure\n");
+	attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL);
+	if (attributes == NULL) {
+		printk(KERN_ERR "Unable to allocate memory for attributes "
+			"structure\n");
 		goto err_attr;
 	}
 
-	pci_attr = (struct vme_dma_pci *)kmalloc(sizeof(struct vme_dma_pci),
-		GFP_KERNEL);
-	if(pci_attr == NULL) {
-		printk("Unable to allocate memory for pci attributes\n");
+	pci_attr = kmalloc(sizeof(struct vme_dma_pci), GFP_KERNEL);
+	if (pci_attr == NULL) {
+		printk(KERN_ERR "Unable to allocate memory for pci "
+			"attributes\n");
 		goto err_pci;
 	}
 
@@ -824,19 +826,18 @@ struct vme_dma_attr *vme_dma_vme_attribu
 	struct vme_dma_attr *attributes;
 	struct vme_dma_vme *vme_attr;
 
-	/* XXX Run some sanity checks here */
-
-	attributes = (struct vme_dma_attr *)kmalloc(
+	attributes = kmalloc(
 		sizeof(struct vme_dma_attr), GFP_KERNEL);
-	if(attributes == NULL) {
-		printk("Unable to allocate memory for attributes structure\n");
+	if (attributes == NULL) {
+		printk(KERN_ERR "Unable to allocate memory for attributes "
+			"structure\n");
 		goto err_attr;
 	}
 
-	vme_attr = (struct vme_dma_vme *)kmalloc(sizeof(struct vme_dma_vme),
-		GFP_KERNEL);
-	if(vme_attr == NULL) {
-		printk("Unable to allocate memory for vme attributes\n");
+	vme_attr = kmalloc(sizeof(struct vme_dma_vme), GFP_KERNEL);
+	if (vme_attr == NULL) {
+		printk(KERN_ERR "Unable to allocate memory for vme "
+			"attributes\n");
 		goto err_vme;
 	}
 
@@ -875,12 +876,12 @@ int vme_dma_list_add(struct vme_dma_list
 	int retval;
 
 	if (bridge->dma_list_add == NULL) {
-		printk("Link List DMA generation not supported\n");
+		printk(KERN_WARNING "Link List DMA generation not supported\n");
 		return -EINVAL;
 	}
 
 	if (!mutex_trylock(&(list->mtx))) {
-		printk("Link List already submitted\n");
+		printk(KERN_ERR "Link List already submitted\n");
 		return -EINVAL;
 	}
 
@@ -898,7 +899,7 @@ int vme_dma_list_exec(struct vme_dma_lis
 	int retval;
 
 	if (bridge->dma_list_exec == NULL) {
-		printk("Link List DMA execution not supported\n");
+		printk(KERN_ERR "Link List DMA execution not supported\n");
 		return -EINVAL;
 	}
 
@@ -918,12 +919,12 @@ int vme_dma_list_free(struct vme_dma_lis
 	int retval;
 
 	if (bridge->dma_list_empty == NULL) {
-		printk("Emptying of Link Lists not supported\n");
+		printk(KERN_WARNING "Emptying of Link Lists not supported\n");
 		return -EINVAL;
 	}
 
 	if (!mutex_trylock(&(list->mtx))) {
-		printk("Link List in use\n");
+		printk(KERN_ERR "Link List in use\n");
 		return -EINVAL;
 	}
 
@@ -933,7 +934,7 @@ int vme_dma_list_free(struct vme_dma_lis
 	 */
 	retval = bridge->dma_list_empty(list);
 	if (retval) {
-		printk("Unable to empty link-list entries\n");
+		printk(KERN_ERR "Unable to empty link-list entries\n");
 		mutex_unlock(&(list->mtx));
 		return retval;
 	}
@@ -949,19 +950,19 @@ int vme_dma_free(struct vme_resource *re
 	struct vme_dma_resource *ctrlr;
 
 	if (resource->type != VME_DMA) {
-		printk("Not a DMA resource\n");
+		printk(KERN_ERR "Not a DMA resource\n");
 		return -EINVAL;
 	}
 
 	ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
 
 	if (!mutex_trylock(&(ctrlr->mtx))) {
-		printk("Resource busy, can't free\n");
+		printk(KERN_ERR "Resource busy, can't free\n");
 		return -EBUSY;
 	}
 
 	if (!(list_empty(&(ctrlr->pending)) && list_empty(&(ctrlr->running)))) {
-		printk("Resource still processing transfers\n");
+		printk(KERN_WARNING "Resource still processing transfers\n");
 		mutex_unlock(&(ctrlr->mtx));
 		return -EBUSY;
 	}
@@ -991,7 +992,7 @@ void vme_irq_handler(struct vme_bridge *
 EXPORT_SYMBOL(vme_irq_handler);
 
 int vme_irq_request(struct device *dev, int level, int statid,
-	void (*callback)(int level, int vector, void *priv_data),
+	void (*callback)(int, int, void *),
 	void *priv_data)
 {
 	struct vme_bridge *bridge;
@@ -1002,7 +1003,7 @@ int vme_irq_request(struct device *dev,
 		return -EINVAL;
 	}
 
-	if((level < 1) || (level > 7)) {
+	if ((level < 1) || (level > 7)) {
 		printk(KERN_ERR "Invalid interrupt level\n");
 		return -EINVAL;
 	}
@@ -1025,7 +1026,7 @@ int vme_irq_request(struct device *dev,
 	bridge->irq[level - 1].callback[statid].func = callback;
 
 	/* Enable IRQ level */
-	bridge->irq_set(level, 1, 1);
+	bridge->irq_set(bridge, level, 1, 1);
 
 	mutex_unlock(&(bridge->irq_mtx));
 
@@ -1043,7 +1044,7 @@ void vme_irq_free(struct device *dev, in
 		return;
 	}
 
-	if((level < 1) || (level > 7)) {
+	if ((level < 1) || (level > 7)) {
 		printk(KERN_ERR "Invalid interrupt level\n");
 		return;
 	}
@@ -1059,7 +1060,7 @@ void vme_irq_free(struct device *dev, in
 
 	/* Disable IRQ level if no more interrupts attached at this level*/
 	if (bridge->irq[level - 1].count == 0)
-		bridge->irq_set(level, 0, 1);
+		bridge->irq_set(bridge, level, 0, 1);
 
 	bridge->irq[level - 1].callback[statid].func = NULL;
 	bridge->irq[level - 1].callback[statid].priv_data = NULL;
@@ -1078,17 +1079,17 @@ int vme_irq_generate(struct device *dev,
 		return -EINVAL;
 	}
 
-	if((level < 1) || (level > 7)) {
+	if ((level < 1) || (level > 7)) {
 		printk(KERN_WARNING "Invalid interrupt level\n");
 		return -EINVAL;
 	}
 
 	if (bridge->irq_generate == NULL) {
-		printk("Interrupt generation not supported\n");
+		printk(KERN_WARNING "Interrupt generation not supported\n");
 		return -EINVAL;
 	}
 
-	return bridge->irq_generate(level, statid);
+	return bridge->irq_generate(bridge, level, statid);
 }
 EXPORT_SYMBOL(vme_irq_generate);
 
@@ -1189,8 +1190,6 @@ int vme_lm_set(struct vme_resource *reso
 		return -EINVAL;
 	}
 
-	/* XXX Check parameters */
-
 	return bridge->lm_set(lm, lm_base, aspace, cycle);
 }
 EXPORT_SYMBOL(vme_lm_set);
@@ -1297,11 +1296,11 @@ int vme_slot_get(struct device *bus)
 	}
 
 	if (bridge->slot_get == NULL) {
-		printk("vme_slot_get not supported\n");
+		printk(KERN_WARNING "vme_slot_get not supported\n");
 		return -EINVAL;
 	}
 
-	return bridge->slot_get();
+	return bridge->slot_get(bridge);
 }
 EXPORT_SYMBOL(vme_slot_get);
 
@@ -1331,7 +1330,7 @@ static void vme_free_bus_num(int bus)
 	mutex_unlock(&vme_bus_num_mtx);
 }
 
-int vme_register_bridge (struct vme_bridge *bridge)
+int vme_register_bridge(struct vme_bridge *bridge)
 {
 	struct device *dev;
 	int retval;
@@ -1358,7 +1357,7 @@ int vme_register_bridge (struct vme_brid
 		dev_set_name(dev, "vme-%x.%x", bridge->num, i + 1);
 
 		retval = device_register(dev);
-		if(retval)
+		if (retval)
 			goto err_reg;
 	}
 
@@ -1375,7 +1374,7 @@ err_reg:
 }
 EXPORT_SYMBOL(vme_register_bridge);
 
-void vme_unregister_bridge (struct vme_bridge *bridge)
+void vme_unregister_bridge(struct vme_bridge *bridge)
 {
 	int i;
 	struct device *dev;
@@ -1392,7 +1391,7 @@ EXPORT_SYMBOL(vme_unregister_bridge);
 
 /* - Driver Registration --------------------------------------------------- */
 
-int vme_register_driver (struct vme_driver *drv)
+int vme_register_driver(struct vme_driver *drv)
 {
 	drv->driver.name = drv->name;
 	drv->driver.bus = &vme_bus_type;
@@ -1401,7 +1400,7 @@ int vme_register_driver (struct vme_driv
 }
 EXPORT_SYMBOL(vme_register_driver);
 
-void vme_unregister_driver (struct vme_driver *drv)
+void vme_unregister_driver(struct vme_driver *drv)
 {
 	driver_unregister(&drv->driver);
 }
@@ -1418,10 +1417,10 @@ int vme_calc_slot(struct device *dev)
 
 	/* Determine slot number */
 	num = 0;
-	while(num < VME_SLOTS_MAX) {
-		if(&(bridge->dev[num]) == dev) {
+	while (num < VME_SLOTS_MAX) {
+		if (&(bridge->dev[num]) == dev)
 			break;
-		}
+
 		num++;
 	}
 	if (num == VME_SLOTS_MAX) {
@@ -1437,8 +1436,8 @@ err_dev:
 
 static struct vme_driver *dev_to_vme_driver(struct device *dev)
 {
-	if(dev->driver == NULL)
-		printk("Bugger dev->driver is NULL\n");
+	if (dev->driver == NULL)
+		printk(KERN_ERR "Bugger dev->driver is NULL\n");
 
 	return container_of(dev->driver, struct vme_driver, driver);
 }
@@ -1462,7 +1461,7 @@ static int vme_bus_match(struct device *
 	}
 
 	i = 0;
-	while((driver->bind_table[i].bus != 0) ||
+	while ((driver->bind_table[i].bus != 0) ||
 		(driver->bind_table[i].slot != 0)) {
 
 		if (bridge->num == driver->bind_table[i].bus) {
@@ -1493,9 +1492,8 @@ static int vme_bus_probe(struct device *
 	driver = dev_to_vme_driver(dev);
 	bridge = dev_to_bridge(dev);
 
-	if(driver->probe != NULL) {
+	if (driver->probe != NULL)
 		retval = driver->probe(dev, bridge->num, vme_calc_slot(dev));
-	}
 
 	return retval;
 }
@@ -1509,9 +1507,8 @@ static int vme_bus_remove(struct device
 	driver = dev_to_vme_driver(dev);
 	bridge = dev_to_bridge(dev);
 
-	if(driver->remove != NULL) {
+	if (driver->remove != NULL)
 		retval = driver->remove(dev, bridge->num, vme_calc_slot(dev));
-	}
 
 	return retval;
 }
@@ -1524,18 +1521,18 @@ struct bus_type vme_bus_type = {
 };
 EXPORT_SYMBOL(vme_bus_type);
 
-static int __init vme_init (void)
+static int __init vme_init(void)
 {
 	return bus_register(&vme_bus_type);
 }
 
-static void __exit vme_exit (void)
+static void __exit vme_exit(void)
 {
 	bus_unregister(&vme_bus_type);
 }
 
 MODULE_DESCRIPTION("VME bridge driver framework");
-MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com");
+MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
 MODULE_LICENSE("GPL");
 
 module_init(vme_init);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vme/vme.h linux-libre-2.6.34-gnu1/drivers/staging/vme/vme.h
--- linux-libre-2.6.33-gnu1/drivers/staging/vme/vme.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vme/vme.h	2010-05-16 17:17:36.000000000 -0400
@@ -68,6 +68,14 @@ typedef u32 vme_pattern_t;
 #define VME_DMA_PATTERN_WORD		(1<<1)
 #define VME_DMA_PATTERN_INCREMENT	(1<<2)
 
+typedef u32 vme_dma_route_t;
+#define VME_DMA_VME_TO_MEM		(1<<0)
+#define VME_DMA_MEM_TO_VME		(1<<1)
+#define VME_DMA_VME_TO_VME		(1<<2)
+#define VME_DMA_MEM_TO_MEM		(1<<3)
+#define VME_DMA_PATTERN_TO_VME		(1<<4)
+#define VME_DMA_PATTERN_TO_MEM		(1<<5)
+
 struct vme_dma_attr {
 	vme_dma_t type;
 	void *private;
@@ -98,32 +106,33 @@ struct vme_driver {
 	struct device_driver    driver;
 };
 
-void * vme_alloc_consistent(struct vme_resource *, size_t, dma_addr_t *);
+void *vme_alloc_consistent(struct vme_resource *, size_t, dma_addr_t *);
 void vme_free_consistent(struct vme_resource *, size_t,  void *,
 	dma_addr_t);
 
 size_t vme_get_size(struct vme_resource *);
 
-struct vme_resource * vme_slave_request(struct device *, vme_address_t, vme_cycle_t);
-int vme_slave_set (struct vme_resource *, int, unsigned long long,
+struct vme_resource *vme_slave_request(struct device *, vme_address_t,
+	vme_cycle_t);
+int vme_slave_set(struct vme_resource *, int, unsigned long long,
 	unsigned long long, dma_addr_t, vme_address_t, vme_cycle_t);
-int vme_slave_get (struct vme_resource *, int *, unsigned long long *,
+int vme_slave_get(struct vme_resource *, int *, unsigned long long *,
 	unsigned long long *, dma_addr_t *, vme_address_t *, vme_cycle_t *);
 void vme_slave_free(struct vme_resource *);
 
-struct vme_resource * vme_master_request(struct device *, vme_address_t, vme_cycle_t,
-	vme_width_t);
-int vme_master_set (struct vme_resource *, int, unsigned long long,
+struct vme_resource *vme_master_request(struct device *, vme_address_t,
+	vme_cycle_t, vme_width_t);
+int vme_master_set(struct vme_resource *, int, unsigned long long,
 	unsigned long long, vme_address_t, vme_cycle_t, vme_width_t);
-int vme_master_get (struct vme_resource *, int *, unsigned long long *,
+int vme_master_get(struct vme_resource *, int *, unsigned long long *,
 	unsigned long long *, vme_address_t *, vme_cycle_t *, vme_width_t *);
 ssize_t vme_master_read(struct vme_resource *, void *, size_t, loff_t);
 ssize_t vme_master_write(struct vme_resource *, void *, size_t, loff_t);
-unsigned int vme_master_rmw (struct vme_resource *, unsigned int, unsigned int,
+unsigned int vme_master_rmw(struct vme_resource *, unsigned int, unsigned int,
 	unsigned int, loff_t);
 void vme_master_free(struct vme_resource *);
 
-struct vme_resource *vme_dma_request(struct device *);
+struct vme_resource *vme_dma_request(struct device *, vme_dma_route_t);
 struct vme_dma_list *vme_new_dma_list(struct vme_resource *);
 struct vme_dma_attr *vme_dma_pattern_attribute(u32, vme_pattern_t);
 struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t);
@@ -153,8 +162,8 @@ void vme_lm_free(struct vme_resource *);
 
 int vme_slot_get(struct device *);
 
-int vme_register_driver (struct vme_driver *);
-void vme_unregister_driver (struct vme_driver *);
+int vme_register_driver(struct vme_driver *);
+void vme_unregister_driver(struct vme_driver *);
 
 
 #endif /* _VME_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vt6655/card.c linux-libre-2.6.34-gnu1/drivers/staging/vt6655/card.c
--- linux-libre-2.6.33-gnu1/drivers/staging/vt6655/card.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vt6655/card.c	2010-05-16 17:17:36.000000000 -0400
@@ -2788,16 +2788,18 @@ void CARDvUpdateBasicTopRate (PVOID pDev
 
      //Determines the highest basic rate.
      for (ii = RATE_54M; ii >= RATE_6M; ii --) {
-         if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) )
+         if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) {
              byTopOFDM = ii;
              break;
+         }
      }
      pDevice->byTopOFDMBasicRate = byTopOFDM;
 
      for (ii = RATE_11M;; ii --) {
-         if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) )
+         if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) {
              byTopCCK = ii;
              break;
+         }
          if (ii == RATE_1M)
             break;
      }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vt6655/device_main.c linux-libre-2.6.34-gnu1/drivers/staging/vt6655/device_main.c
--- linux-libre-2.6.33-gnu1/drivers/staging/vt6655/device_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vt6655/device_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -84,6 +84,7 @@
 #include "iowpa.h"
 #include <linux/delay.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 //#define	DEBUG
 /*---------------------  Static Definitions -------------------------*/
@@ -1105,10 +1106,7 @@ static void device_print_info(PSDevice p
     struct net_device* dev=pDevice->dev;
 
     DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n",dev->name, get_chip_name(pDevice->chip_id));
-    DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
-        dev->name,
-        dev->dev_addr[0],dev->dev_addr[1],dev->dev_addr[2],
-        dev->dev_addr[3],dev->dev_addr[4],dev->dev_addr[5]);
+    DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%pM", dev->name, dev->dev_addr);
 #ifdef IO_MAP
     DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx  ",(ULONG) pDevice->ioaddr);
     DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IRQ=%d \n", pDevice->dev->irq);
@@ -3082,8 +3080,7 @@ static void device_set_multi(struct net_
 
     PSMgmtObject     pMgmt = pDevice->pMgmt;
     u32              mc_filter[2];
-    int              i;
-    struct dev_mc_list  *mclist;
+    struct dev_mc_list *mclist;
 
 
     VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode));
@@ -3093,7 +3090,7 @@ static void device_set_multi(struct net_
         /* Unconditionally log net taps. */
         pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
     }
-    else if ((dev->mc_count > pDevice->multicast_limit)
+    else if ((netdev_mc_count(dev) > pDevice->multicast_limit)
         ||  (dev->flags & IFF_ALLMULTI)) {
         MACvSelectPage1(pDevice->PortOffset);
         VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, 0xffffffff);
@@ -3103,8 +3100,7 @@ static void device_set_multi(struct net_
     }
     else {
         memset(mc_filter, 0, sizeof(mc_filter));
-        for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-             i++, mclist = mclist->next) {
+	netdev_for_each_mc_addr(mclist, dev) {
             int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
             mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
         }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vt6655/iwctl.c linux-libre-2.6.34-gnu1/drivers/staging/vt6655/iwctl.c
--- linux-libre-2.6.33-gnu1/drivers/staging/vt6655/iwctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vt6655/iwctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -1472,7 +1472,7 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0)
 		if ( index < 4 ) {
 		    pDevice->byKeyIndex = index;
 		}
-		else if(!wrq->flags & IW_ENCODE_MODE) {
+		else if(!(wrq->flags & IW_ENCODE_MODE)) {
 				rc = -EINVAL;
 				return rc;
 	    }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/vt6656/main_usb.c linux-libre-2.6.34-gnu1/drivers/staging/vt6656/main_usb.c
--- linux-libre-2.6.33-gnu1/drivers/staging/vt6656/main_usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/vt6656/main_usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -1596,7 +1596,7 @@ static void device_set_multi(struct net_
     PSMgmtObject     pMgmt = &(pDevice->sMgmtObj);
     u32              mc_filter[2];
     int              ii;
-    struct dev_mc_list  *mclist;
+    struct dev_mc_list *mclist;
     BYTE             pbyData[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
     BYTE             byTmpMode = 0;
     int              rc;
@@ -1619,7 +1619,8 @@ static void device_set_multi(struct net_
         // Unconditionally log net taps.
         pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
     }
-    else if ((dev->mc_count > pDevice->multicast_limit) || (dev->flags & IFF_ALLMULTI)) {
+    else if ((netdev_mc_count(dev) > pDevice->multicast_limit) ||
+	     (dev->flags & IFF_ALLMULTI)) {
         CONTROLnsRequestOut(pDevice,
                             MESSAGE_TYPE_WRITE,
                             MAC_REG_MAR0,
@@ -1631,8 +1632,7 @@ static void device_set_multi(struct net_
     }
     else {
         memset(mc_filter, 0, sizeof(mc_filter));
-        for (ii = 0, mclist = dev->mc_list; mclist && ii < dev->mc_count;
-             ii++, mclist = mclist->next) {
+	netdev_for_each_mc_addr(mclist, dev) {
             int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
             mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
         }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wavelan/wavelan.c linux-libre-2.6.34-gnu1/drivers/staging/wavelan/wavelan.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wavelan/wavelan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wavelan/wavelan.c	2010-05-16 17:17:36.000000000 -0400
@@ -1367,7 +1367,7 @@ static void wavelan_set_multicast_list(s
 #ifdef DEBUG_IOCTL_INFO
 	printk(KERN_DEBUG
 	       "%s: wavelan_set_multicast_list(): setting Rx mode %02X to %d addresses.\n",
-	       dev->name, dev->flags, dev->mc_count);
+	       dev->name, dev->flags, netdev_mc_count(dev));
 #endif
 
 	/* Are we asking for promiscuous mode,
@@ -1375,7 +1375,7 @@ static void wavelan_set_multicast_list(s
 	 * or too many multicast addresses for the hardware filter? */
 	if ((dev->flags & IFF_PROMISC) ||
 	    (dev->flags & IFF_ALLMULTI) ||
-	    (dev->mc_count > I82586_MAX_MULTICAST_ADDRESSES)) {
+	    (netdev_mc_count(dev) > I82586_MAX_MULTICAST_ADDRESSES)) {
 		/*
 		 * Enable promiscuous mode: receive all packets.
 		 */
@@ -1387,17 +1387,17 @@ static void wavelan_set_multicast_list(s
 		}
 	} else
 		/* Are there multicast addresses to send? */
-	if (dev->mc_list != (struct dev_mc_list *) NULL) {
+	if (!netdev_mc_empty(dev)) {
 		/*
 		 * Disable promiscuous mode, but receive all packets
 		 * in multicast list
 		 */
 #ifdef MULTICAST_AVOID
-		if (lp->promiscuous || (dev->mc_count != lp->mc_count))
+		if (lp->promiscuous || (netdev_mc_count(dev) != lp->mc_count))
 #endif
 		{
 			lp->promiscuous = 0;
-			lp->mc_count = dev->mc_count;
+			lp->mc_count = netdev_mc_count(dev);
 
 			wv_82586_reconfig(dev);
 		}
@@ -3531,7 +3531,7 @@ static void wv_82586_config(struct net_d
 
 	/* Any address to set? */
 	if (lp->mc_count) {
-		for (dmi = dev->mc_list; dmi; dmi = dmi->next)
+		netdev_for_each_mc_addr(dmi, dev)
 			outsw(PIOP1(ioaddr), (u16 *) dmi->dmi_addr,
 			      WAVELAN_ADDR_SIZE >> 1);
 
@@ -3539,7 +3539,7 @@ static void wv_82586_config(struct net_d
 		printk(KERN_DEBUG
 		       "%s: wv_82586_config(): set %d multicast addresses:\n",
 		       dev->name, lp->mc_count);
-		for (dmi = dev->mc_list; dmi; dmi = dmi->next)
+		netdev_for_each_mc_addr(dmi, dev)
 			printk(KERN_DEBUG " %pM\n", dmi->dmi_addr);
 #endif
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wavelan/wavelan_cs.c linux-libre-2.6.34-gnu1/drivers/staging/wavelan/wavelan_cs.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wavelan/wavelan_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wavelan/wavelan_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -1373,7 +1373,7 @@ wavelan_set_multicast_list(struct net_de
 
 #ifdef DEBUG_IOCTL_INFO
   printk(KERN_DEBUG "%s: wavelan_set_multicast_list(): setting Rx mode %02X to %d addresses.\n",
-	 dev->name, dev->flags, dev->mc_count);
+	 dev->name, dev->flags, netdev_mc_count(dev));
 #endif
 
   if(dev->flags & IFF_PROMISC)
@@ -1394,7 +1394,7 @@ wavelan_set_multicast_list(struct net_de
     /* If all multicast addresses
      * or too much multicast addresses for the hardware filter */
     if((dev->flags & IFF_ALLMULTI) ||
-       (dev->mc_count > I82593_MAX_MULTICAST_ADDRESSES))
+       (netdev_mc_count(dev) > I82593_MAX_MULTICAST_ADDRESSES))
       {
 	/*
 	 * Disable promiscuous mode, but active the all multicast mode
@@ -1410,20 +1410,19 @@ wavelan_set_multicast_list(struct net_de
       }
     else
       /* If there is some multicast addresses to send */
-      if(dev->mc_list != (struct dev_mc_list *) NULL)
-	{
+      if (!netdev_mc_empty(dev)) {
 	  /*
 	   * Disable promiscuous mode, but receive all packets
 	   * in multicast list
 	   */
 #ifdef MULTICAST_AVOID
 	  if(lp->promiscuous || lp->allmulticast ||
-	     (dev->mc_count != lp->mc_count))
+	     (netdev_mc_count(dev) != lp->mc_count))
 #endif
 	    {
 	      lp->promiscuous = 0;
 	      lp->allmulticast = 0;
-	      lp->mc_count = dev->mc_count;
+	      lp->mc_count = netdev_mc_count(dev);
 
 	      wv_82593_reconfig(dev);
 	    }
@@ -3598,13 +3597,13 @@ wv_82593_config(struct net_device *	dev)
   /* If any multicast address to set */
   if(lp->mc_count)
     {
-      struct dev_mc_list *	dmi;
+      struct dev_mc_list *dmi;
       int			addrs_len = WAVELAN_ADDR_SIZE * lp->mc_count;
 
 #ifdef DEBUG_CONFIG_INFO
       printk(KERN_DEBUG "%s: wv_hw_config(): set %d multicast addresses:\n",
 	     dev->name, lp->mc_count);
-      for(dmi=dev->mc_list; dmi; dmi=dmi->next)
+      netdev_for_each_mc_addr(dmi, dev)
 	printk(KERN_DEBUG " %pM\n", dmi->dmi_addr);
 #endif
 
@@ -3613,7 +3612,7 @@ wv_82593_config(struct net_device *	dev)
       outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
       outb(addrs_len & 0xff, PIOP(base));	/* byte count lsb */
       outb((addrs_len >> 8), PIOP(base));	/* byte count msb */
-      for(dmi=dev->mc_list; dmi; dmi=dmi->next)
+      netdev_for_each_mc_addr(dmi, dev)
 	outsb(PIOP(base), dmi->dmi_addr, dmi->dmi_addrlen);
 
       /* reset transmit DMA pointer */
@@ -3622,7 +3621,8 @@ wv_82593_config(struct net_device *	dev)
       if(!wv_82593_cmd(dev, "wv_82593_config(): mc-setup",
 		       OP0_MC_SETUP, SR0_MC_SETUP_DONE))
 	ret = FALSE;
-      lp->mc_count = dev->mc_count;	/* remember to avoid repeated reset */
+      /* remember to avoid repeated reset */
+      lp->mc_count = netdev_mc_count(dev);
     }
 
   /* Job done, clear the flag */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/winbond/core.h linux-libre-2.6.34-gnu1/drivers/staging/winbond/core.h
--- linux-libre-2.6.33-gnu1/drivers/staging/winbond/core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/winbond/core.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,7 @@
 struct wbsoft_priv {
 	u32 adapterIndex;	// 20060703.4 Add for using padapterContext global adapter point
 
-	WB_LOCALDESCRIPT sLocalPara;	// Myself connected parameters
+	struct wb_local_para sLocalPara;	// Myself connected parameters
 
 	MLME_FRAME sMlmeFrame;	// connect to peerSTA parameters
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/winbond/localpara.h linux-libre-2.6.34-gnu1/drivers/staging/winbond/localpara.h
--- linux-libre-2.6.33-gnu1/drivers/staging/winbond/localpara.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/winbond/localpara.h	2010-05-16 17:17:36.000000000 -0400
@@ -110,33 +110,20 @@
 // 20061108 WPS IE buffer
 #define MAX_IE_APPEND_SIZE					256 + 4 // Due to [E id][Length][OUI][Data] may 257 bytes
 
-typedef struct _EVENTLOG
-{
-	u16		Count;			//Total count from start
-	u16		index;			//Buffer index, 0 ~ 63
-	u32		EventValue[64];	//BYTE 3~2 : count, BYTE 1 : Event, BYTE 0 : reason
-} Event_Log, *pEvent_Log;
-
-typedef struct _ChanInfo
+struct chan_info
 {
 	u8		band;
 	u8		ChanNo;
-} ChanInfo, *pChanInfo;
-
-typedef struct _CHAN_LIST
-{
-	u16				Count;
-	ChanInfo		Channel[50]; // 100B
-} CHAN_LIST, *psCHAN_LIST;
+};
 
-typedef struct _RadioOff
+struct radio_off
 {
 	u8			boHwRadioOff;
 	u8			boSwRadioOff;
-} RadioOff, *psRadioOff;
+};
 
 //===========================================================================
-typedef struct LOCAL_PARA
+struct wb_local_para
 {
 	u8			PermanentAddress[ MAC_ADDR_LENGTH + 2 ]; 	// read from EPROM, manufacture set for each NetCard
     u8    		ThisMacAddress[ MAC_ADDR_LENGTH + 2 ];			// the driver will use actually.
@@ -186,7 +173,7 @@ typedef struct LOCAL_PARA
     u16			ListenInterval;     	// The listen interval when SME invoking MLME_
             	                    	// (Re)Associate_Request().
 
-	RadioOff		RadioOffStatus;
+	struct radio_off		RadioOffStatus;
 	u8			Reserved0[2];
 
 	u8			boMsRadioOff;			// Ndis demands to be true when set Disassoc. OID and be false when set SSID OID.
@@ -196,7 +183,7 @@ typedef struct LOCAL_PARA
 	u8			RoamStatus;
 	u8			reserved7[3];
 
-	ChanInfo	CurrentChan;			//Current channel no. and channel band. It may be changed by scanning.
+	struct chan_info	CurrentChan;			//Current channel no. and channel band. It may be changed by scanning.
 	u8			boHandover;				// Roaming, Hnadover to other AP.
 	u8			boCCAbusy;
 
@@ -253,19 +240,16 @@ typedef struct LOCAL_PARA
     u32	   		_dot11WEPUndecryptableCount;
     u32	   		_dot11FrameDuplicateCount;
 
-	ChanInfo	IbssChanSetting;	// 2B. Start IBSS Channel setting by registry or WWU.
+	struct chan_info	IbssChanSetting;	// 2B. Start IBSS Channel setting by registry or WWU.
 	u8		reserved_5[2];		//It may not be used after considering RF type,
 									//region and modulation type.
 
-	CHAN_LIST	sSupportChanList;	// 86B. It will be obtained according to RF type and region
 	u8		reserved_6[2];		//two variables are for wep key error detection added by ws 02/02/04
 
     u32	      bWepKeyError;
     u32         bToSelfPacketReceived;
     u32         WepKeyDetectTimerCount;
 
-	Event_Log	EventLog;
-
 	u16		SignalLostTh;
 	u16		SignalRoamTh;
 
@@ -274,6 +258,6 @@ typedef struct LOCAL_PARA
 	u16		IE_Append_size;
 	u16		reserved_7;
 
-} WB_LOCALDESCRIPT, *PWB_LOCALDESCRIPT;
+};
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/winbond/mds_f.h linux-libre-2.6.34-gnu1/drivers/staging/winbond/mds_f.h
--- linux-libre-2.6.33-gnu1/drivers/staging/winbond/mds_f.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/winbond/mds_f.h	2010-05-16 17:17:36.000000000 -0400
@@ -11,9 +11,6 @@ void Mds_SendComplete(  struct wbsoft_pr
 void Mds_MpduProcess(  struct wbsoft_priv *adapter,  struct wb35_descriptor *pRxDes );
 extern void DataDmp(u8 *pdata, u32 len, u32 offset);
 
-// For Asynchronous indicating. The routine collocates with USB.
-void Mds_MsduProcess(  struct wbsoft_priv *adapter,  PRXLAYER1 pRxLayer1,  u8 SlotIndex);
-
 // For data frame sending 20060802
 u16 MDS_GetPacketSize(  struct wbsoft_priv *adapter );
 void MDS_GetNextPacket(  struct wbsoft_priv *adapter,  struct wb35_descriptor *pDes );
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/winbond/mds_s.h linux-libre-2.6.34-gnu1/drivers/staging/winbond/mds_s.h
--- linux-libre-2.6.33-gnu1/drivers/staging/winbond/mds_s.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/winbond/mds_s.h	2010-05-16 17:17:36.000000000 -0400
@@ -133,32 +133,4 @@ struct wb35_mds {
 
 };
 
-//
-// Reveive Layer 1 Format.
-//----------------------------
-typedef struct _RXLAYER1
-{
-    u16  SequenceNumber;     // The sequence number of the last received packet.
-	u16	BufferTotalSize;
-
-	u32	InUsed;
-    u32   DecryptionMethod;   // The desired defragment number of the next incoming packet.
-
-	u8	DeFragmentNumber;
-	u8	FrameType;
-    u8	TypeEncapsulated;
-	u8	BufferNumber;
-
-	u32	FirstFrameArrivedTime;
-
-	u8		LastFrameType; // 20061004 for fix intel 3945 's bug
-	u8		RESERVED[3];  //@@ anson
-
-	/////////////////////////////////////////////////////////////////////////////////////////////
-	// For brand-new Rx system
-	u8	ReservedBuffer[ 2400 ];//If Buffer ID is reserved one, it must copy the data into this area
-	u8	*ReservedBufferPoint;// Point to the next availabe address of reserved buffer
-
-}RXLAYER1, * PRXLAYER1;
-
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/winbond/mlme_s.h linux-libre-2.6.34-gnu1/drivers/staging/winbond/mlme_s.h
--- linux-libre-2.6.33-gnu1/drivers/staging/winbond/mlme_s.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/winbond/mlme_s.h	2010-05-16 17:17:36.000000000 -0400
@@ -165,14 +165,6 @@ typedef struct _AUTHREQ {
 
 } MLME_AUTHREQ_PARA, *psMLME_AUTHREQ_PARA;
 
-struct _Reason_Code {
-
-	u8	peerMACaddr[MAC_ADDR_LENGTH];
-	u16	wReasonCode;
-};
-typedef struct _Reason_Code MLME_DEAUTHREQ_PARA, *psMLME_DEAUTHREQ_PARA;
-typedef struct _Reason_Code MLME_DISASSOCREQ_PARA, *psMLME_DISASSOCREQ_PARA;
-
 typedef struct _ASSOCREQ {
   u8       PeerSTAAddr[MAC_ADDR_LENGTH];
   u16       CapabilityInfo;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/winbond/mto.h linux-libre-2.6.34-gnu1/drivers/staging/winbond/mto.h
--- linux-libre-2.6.33-gnu1/drivers/staging/winbond/mto.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/winbond/mto.h	2010-05-16 17:17:36.000000000 -0400
@@ -141,11 +141,6 @@ extern u16  MTO_Frag_Th_Tbl[];
 #define MTO_DATA_RATE()          MTO_Data_Rate_Tbl[MTO_RATE_LEVEL()]
 #define MTO_FRAG_TH()            MTO_Frag_Th_Tbl[MTO_FRAG_TH_LEVEL()]
 
-typedef struct {
-	u8 tx_rate;
-	u8 tx_retry_rate;
-} TXRETRY_REC;
-
 extern void MTO_Init(struct wbsoft_priv *);
 extern void MTO_PeriodicTimerExpired(struct wbsoft_priv *);
 extern void MTO_SetDTORateRange(struct wbsoft_priv *, u8 *, u8);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/winbond/reg.c linux-libre-2.6.34-gnu1/drivers/staging/winbond/reg.c
--- linux-libre-2.6.33-gnu1/drivers/staging/winbond/reg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/winbond/reg.c	2010-05-16 17:17:36.000000000 -0400
@@ -1823,12 +1823,12 @@ BBProcessor_initial(  struct hw_data * p
 		reg->SQ3_filter[i] = 0x2f; // half of Bit 0 ~ 6
 }
 
-void set_tx_power_per_channel_max2829(  struct hw_data * pHwData,  ChanInfo Channel)
+void set_tx_power_per_channel_max2829(  struct hw_data * pHwData,  struct chan_info Channel)
 {
 	RFSynthesizer_SetPowerIndex( pHwData, 100 ); // 20060620.1 Modify
 }
 
-void set_tx_power_per_channel_al2230(  struct hw_data * pHwData,  ChanInfo Channel )
+void set_tx_power_per_channel_al2230(  struct hw_data * pHwData,  struct chan_info Channel )
 {
 	u8	index = 100;
 
@@ -1838,7 +1838,7 @@ void set_tx_power_per_channel_al2230(  s
 	RFSynthesizer_SetPowerIndex( pHwData, index );
 }
 
-void set_tx_power_per_channel_al7230(  struct hw_data * pHwData,  ChanInfo Channel)
+void set_tx_power_per_channel_al7230(  struct hw_data * pHwData,  struct chan_info Channel)
 {
 	u8	i, index = 100;
 
@@ -1868,7 +1868,7 @@ void set_tx_power_per_channel_al7230(  s
 	RFSynthesizer_SetPowerIndex( pHwData, index );
 }
 
-void set_tx_power_per_channel_wb242(  struct hw_data * pHwData,  ChanInfo Channel)
+void set_tx_power_per_channel_wb242(  struct hw_data * pHwData,  struct chan_info Channel)
 {
 	u8	index = 100;
 
@@ -1901,7 +1901,7 @@ void set_tx_power_per_channel_wb242(  st
 //   None.
 //=============================================================================================================
 void
-RFSynthesizer_SwitchingChannel(  struct hw_data * pHwData,  ChanInfo Channel )
+RFSynthesizer_SwitchingChannel(  struct hw_data * pHwData,  struct chan_info Channel )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 	u32	pltmp[16]; // The 16 is the maximum capability of hardware
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/winbond/scan_s.h linux-libre-2.6.34-gnu1/drivers/staging/winbond/scan_s.h
--- linux-libre-2.6.33-gnu1/drivers/staging/winbond/scan_s.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/winbond/scan_s.h	2010-05-16 17:17:36.000000000 -0400
@@ -35,7 +35,6 @@ typedef struct _SCAN_REQ_PARA	//mandator
 {
 	u32				ScanType;			//passive/active scan
 
-	CHAN_LIST		sChannelList;	// 86B
 	u8			reserved_1[2];
 
 	struct SSID_Element	sSSID; // 34B. scan only for this SSID
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/winbond/sme_api.h linux-libre-2.6.34-gnu1/drivers/staging/winbond/sme_api.h
--- linux-libre-2.6.33-gnu1/drivers/staging/winbond/sme_api.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/winbond/sme_api.h	2010-05-16 17:17:36.000000000 -0400
@@ -193,8 +193,6 @@ s8 sme_get_cwmin_value(void *pcore_data,
 s8 sme_get_cwmax_value(void *pcore_data, u16 *cwmax);
 s8 sme_get_ms_radio_mode(void *pcore_data, u8 * pMsRadioOff);
 s8 sme_set_ms_radio_mode(void *pcore_data, u8 boMsRadioOff);
-s8 sme_get_radio_mode(void *pcore_data, psRadioOff pRadioOffData);
-s8 sme_set_radio_mode(void *pcore_data, RadioOff RadioOffData);
 
 void sme_get_tx_power_level(void *pcore_data, u32 *TxPower);
 u8 sme_set_tx_power_level(void *pcore_data, u32 TxPower);
@@ -203,7 +201,7 @@ void sme_get_rx_antenna(void *pcore_data
 u8 sme_set_rx_antenna(void *pcore_data, u32 RxAntenna);
 void sme_get_tx_antenna(void *pcore_data, u32 *TxAntenna);
 s8 sme_set_tx_antenna(void *pcore_data, u32 TxAntenna);
-s8 sme_set_IBSS_chan(void *pcore_data, ChanInfo chan);
+s8 sme_set_IBSS_chan(void *pcore_data, struct chan_info chan);
 
 //20061108 WPS
 s8 sme_set_IE_append(void *pcore_data, u8 *buffer, u16 buf_len);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/winbond/wb35reg.c linux-libre-2.6.34-gnu1/drivers/staging/winbond/wb35reg.c
--- linux-libre-2.6.33-gnu1/drivers/staging/winbond/wb35reg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/winbond/wb35reg.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,6 +2,7 @@
 #include "wb35reg_f.h"
 
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 extern void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/winbond/wb35reg_f.h linux-libre-2.6.34-gnu1/drivers/staging/winbond/wb35reg_f.h
--- linux-libre-2.6.33-gnu1/drivers/staging/winbond/wb35reg_f.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/winbond/wb35reg_f.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,7 @@ void Dxx_initial(  struct hw_data * pHwD
 void Mxx_initial(  struct hw_data * pHwData );
 void RFSynthesizer_initial(  struct hw_data * pHwData );
 //void RFSynthesizer_SwitchingChannel(  struct hw_data * pHwData,  s8 Channel );
-void RFSynthesizer_SwitchingChannel(  struct hw_data * pHwData,  ChanInfo Channel );
+void RFSynthesizer_SwitchingChannel(  struct hw_data * pHwData,  struct chan_info Channel );
 void BBProcessor_initial(  struct hw_data * pHwData );
 void BBProcessor_RateChanging(  struct hw_data * pHwData,  u8 rate ); // 20060613.1
 //void RF_RateChanging(  struct hw_data * pHwData,  u8 rate ); // 20060626.5.c Add
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/winbond/wb35rx.c linux-libre-2.6.34-gnu1/drivers/staging/winbond/wb35rx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/winbond/wb35rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/winbond/wb35rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 //
 //============================================================================
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include "core.h"
 #include "sysdef.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/winbond/wb35tx.c linux-libre-2.6.34-gnu1/drivers/staging/winbond/wb35tx.c
--- linux-libre-2.6.33-gnu1/drivers/staging/winbond/wb35tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/winbond/wb35tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 //
 //============================================================================
 #include <linux/usb.h>
+#include <linux/gfp.h>
 
 #include "wb35tx_f.h"
 #include "mds_f.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/winbond/wbusb.c linux-libre-2.6.34-gnu1/drivers/staging/winbond/wbusb.c
--- linux-libre-2.6.33-gnu1/drivers/staging/winbond/wbusb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/winbond/wbusb.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,7 @@ MODULE_DESCRIPTION("IS89C35 802.11bg WLA
 MODULE_LICENSE("GPL");
 MODULE_VERSION("0.1");
 
-static struct usb_device_id wb35_table[] __devinitdata = {
+static const struct usb_device_id wb35_table[] __devinitconst = {
 	{ USB_DEVICE(0x0416, 0x0035) },
 	{ USB_DEVICE(0x18E8, 0x6201) },
 	{ USB_DEVICE(0x18E8, 0x6206) },
@@ -65,17 +65,17 @@ static void hal_set_beacon_period(struct
 }
 
 static int wbsoft_add_interface(struct ieee80211_hw *dev,
-				struct ieee80211_if_init_conf *conf)
+				struct ieee80211_vif *vif)
 {
 	struct wbsoft_priv *priv = dev->priv;
 
-	hal_set_beacon_period(&priv->sHwData, conf->vif->bss_conf.beacon_int);
+	hal_set_beacon_period(&priv->sHwData, vif->bss_conf.beacon_int);
 
 	return 0;
 }
 
 static void wbsoft_remove_interface(struct ieee80211_hw *dev,
-				    struct ieee80211_if_init_conf *conf)
+				    struct ieee80211_vif *vif)
 {
 	printk("wbsoft_remove interface called\n");
 }
@@ -92,13 +92,6 @@ static int wbsoft_get_stats(struct ieee8
 	return 0;
 }
 
-static int wbsoft_get_tx_stats(struct ieee80211_hw *hw,
-			       struct ieee80211_tx_queue_stats *stats)
-{
-	printk(KERN_INFO "%s called\n", __func__);
-	return 0;
-}
-
 static u64 wbsoft_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
 				    struct dev_addr_list *mc_list)
 {
@@ -161,7 +154,7 @@ static void hal_set_radio_mode(struct hw
 }
 
 static void
-hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo channel)
+hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info channel)
 {
 	struct wb35_reg *reg = &pHwData->reg;
 
@@ -180,10 +173,10 @@ hal_set_current_channel_ex(struct hw_dat
 	reg->M28_MacControl &= ~0xff;	// Clean channel information field
 	reg->M28_MacControl |= channel.ChanNo;
 	Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl,
-				       (s8 *) & channel, sizeof(ChanInfo));
+				       (s8 *) & channel, sizeof(struct chan_info));
 }
 
-static void hal_set_current_channel(struct hw_data *pHwData, ChanInfo channel)
+static void hal_set_current_channel(struct hw_data *pHwData, struct chan_info channel)
 {
 	hal_set_current_channel_ex(pHwData, channel);
 }
@@ -253,7 +246,7 @@ static void hal_set_accept_beacon(struct
 static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
 {
 	struct wbsoft_priv *priv = dev->priv;
-	ChanInfo ch;
+	struct chan_info ch;
 
 	printk("wbsoft_config called\n");
 
@@ -287,7 +280,6 @@ static const struct ieee80211_ops wbsoft
 	.prepare_multicast	= wbsoft_prepare_multicast,
 	.configure_filter	= wbsoft_configure_filter,
 	.get_stats		= wbsoft_get_stats,
-	.get_tx_stats		= wbsoft_get_tx_stats,
 	.get_tsf		= wbsoft_get_tsf,
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_cs.c linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_cs.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_cs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_cs.c	2010-05-16 17:17:36.000000000 -0400
@@ -67,7 +67,6 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_main.c linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_main.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_main.c	2013-05-03 12:09:29.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_main.c	2013-05-03 09:49:00.000000000 -0400
@@ -3793,7 +3793,7 @@ static int write_int(struct file *file,
 	}
 	if  (count > 0 ) {
 		proc_number[count] = 0;
-		nr = wl_atoi( proc_number );
+		nr = simple_strtoul(proc_number , NULL, 0);
  		*(unsigned int *)data = nr;
 		if ( nr & 0x8000 ) {	//;?kludgy but it is unclear to me were else to place this
 #if DBG
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_netdev.c linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_netdev.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_netdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_netdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,6 +65,7 @@
 #include <wl_version.h>
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 // #include <linux/sched.h>
@@ -360,7 +361,7 @@ int wl_open(struct net_device *dev)
     wl_lock( lp, &flags );
 
     if( status != HCF_SUCCESS ) {
-	// Unsuccesfull, try reset of the card to recover
+	// Unsuccessful, try reset of the card to recover
 	status = wl_reset( dev );
     }
 
@@ -1049,7 +1050,7 @@ void wl_multicast( struct net_device *de
 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
 
     int                 x;
-    struct dev_mc_list  *mclist;
+    struct dev_mc_list *mclist;
     struct wl_private   *lp = wl_priv(dev);
     unsigned long       flags;
     /*------------------------------------------------------------------------*/
@@ -1070,13 +1071,11 @@ void wl_multicast( struct net_device *de
             ( dev->flags & IFF_MULTICAST ) ? "Multicast " : "",
             ( dev->flags & IFF_ALLMULTI ) ? "All-Multicast" : "" );
 
-        DBG_PRINT( "  mc_count: %d\n", dev->mc_count );
+        DBG_PRINT( "  mc_count: %d\n", netdev_mc_count(dev));
 
-        for( x = 0, mclist = dev->mc_list; mclist && x < dev->mc_count;
-             x++, mclist = mclist->next ) {
+	netdev_for_each_mc_addr(mclist, dev)
             DBG_PRINT( "    %s (%d)\n", DbgHwAddr(mclist->dmi_addr),
                        mclist->dmi_addrlen );
-        }
     }
 #endif /* DBG */
 
@@ -1103,7 +1102,7 @@ void wl_multicast( struct net_device *de
                 DBG_PRINT( "Enabling Promiscuous mode (IFF_PROMISC)\n" );
                 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
             }
-            else if(( dev->mc_count > HCF_MAX_MULTICAST ) ||
+            else if ((netdev_mc_count(dev) > HCF_MAX_MULTICAST) ||
                     ( dev->flags & IFF_ALLMULTI )) {
                 /* Shutting off this filter will enable all multicast frames to
                    be sent up from the device; however, this is a static RID, so
@@ -1115,17 +1114,15 @@ void wl_multicast( struct net_device *de
                 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
                 wl_apply( lp );
             }
-            else if( dev->mc_count != 0 ) {
+            else if (!netdev_mc_empty(dev)) {
                 /* Set the multicast addresses */
-                lp->ltvRecord.len = ( dev->mc_count * 3 ) + 1;
+                lp->ltvRecord.len = ( netdev_mc_count(dev) * 3 ) + 1;
                 lp->ltvRecord.typ = CFG_GROUP_ADDR;
 
-                for( x = 0, mclist = dev->mc_list;
-                ( x < dev->mc_count ) && ( mclist != NULL );
-                    x++, mclist = mclist->next ) {
-                    memcpy( &( lp->ltvRecord.u.u8[x * ETH_ALEN] ),
-                            mclist->dmi_addr, ETH_ALEN );
-                }
+		x = 0;
+		netdev_for_each_mc_addr(mclist, dev)
+                    memcpy(&(lp->ltvRecord.u.u8[x++ * ETH_ALEN]),
+                           mclist->dmi_addr, ETH_ALEN);
                 DBG_PRINT( "Setting multicast list\n" );
                 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
             } else {
@@ -1194,9 +1191,7 @@ static const struct net_device_ops wl_ne
     .ndo_stop               = &wl_adapter_close,
     .ndo_do_ioctl           = &wl_ioctl,
 
-#ifdef HAVE_TX_TIMEOUT
     .ndo_tx_timeout         = &wl_tx_timeout,
-#endif
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
     .ndo_poll_controller    = wl_poll,
@@ -1270,9 +1265,7 @@ struct net_device * wl_device_alloc( voi
     dev->stop               = &wl_adapter_close;
     dev->do_ioctl           = &wl_ioctl;
 
-#ifdef HAVE_TX_TIMEOUT
     dev->tx_timeout         = &wl_tx_timeout;
-#endif
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
     dev->poll_controller = wl_poll;
@@ -1280,9 +1273,7 @@ struct net_device * wl_device_alloc( voi
 
 #endif // (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30))
 
-#ifdef HAVE_TX_TIMEOUT
     dev->watchdog_timeo     = TX_TIMEOUT;
-#endif
 
     dev->ethtool_ops	    = &wl_ethtool_ops;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_pci.c linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_pci.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -71,7 +71,6 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 //#include <linux/timer.h>
@@ -81,7 +80,6 @@
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_priv.c linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_priv.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_priv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_priv.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,6 +65,7 @@
 
 #include <linux/if_arp.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <asm/uaccess.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_profile.c linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_profile.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_profile.c	2013-05-03 12:09:29.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_profile.c	2013-05-03 09:49:00.000000000 -0400
@@ -383,15 +383,15 @@ void translate_option( char *buffer, str
 				DbgInfo->DebugFlag |= DBG_DEFAULTS;
 			}
 		} else {
-			DbgInfo->DebugFlag = wl_atoi( value ); //;?DebugFlag;
+			DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); //;?DebugFlag;
 		}
-		DbgInfo->DebugFlag = wl_atoi( value ); //;?Delete ASAP
+		DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); //;?Delete ASAP
 	}
 #endif /* DBG */
 	if ( strcmp( key, PARM_NAME_AUTH_KEY_MGMT_SUITE ) == 0 ) {
 		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_AUTH_KEY_MGMT_SUITE, value );
 
-		value_convert = wl_atoi( value );
+		value_convert = simple_strtoul(value, NULL, 0);
 		if (( value_convert >= PARM_MIN_AUTH_KEY_MGMT_SUITE ) || ( value_convert <= PARM_MAX_AUTH_KEY_MGMT_SUITE )) {
 			lp->AuthKeyMgmtSuite = value_convert;
 		} else {
@@ -401,7 +401,7 @@ void translate_option( char *buffer, str
 	else if ( strcmp( key, PARM_NAME_BRSC_2GHZ ) == 0 ) {
 		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_2GHZ, value );
 
-		value_convert = wl_atoi( value );
+		value_convert = simple_strtoul(value, NULL, 0);
 		if (( value_convert >= PARM_MIN_BRSC ) || ( value_convert <= PARM_MAX_BRSC )) {
 			lp->brsc[0] = value_convert;
 		} else {
@@ -411,7 +411,7 @@ void translate_option( char *buffer, str
 	else if ( strcmp( key, PARM_NAME_BRSC_5GHZ ) == 0 ) {
 		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ, value );
 
-		value_convert = wl_atoi( value );
+		value_convert = simple_strtoul(value, NULL, 0);
 		if (( value_convert >= PARM_MIN_BRSC ) || ( value_convert <= PARM_MAX_BRSC )) {
 			lp->brsc[1] = value_convert;
 		} else {
@@ -448,7 +448,7 @@ void translate_option( char *buffer, str
 	else if ( strcmp( key, PARM_NAME_ENABLE_ENCRYPTION ) == 0 ) {
 		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_ENABLE_ENCRYPTION, value );
 
-		value_convert = wl_atoi( value );
+		value_convert = simple_strtoul(value, NULL, 0);
 		if (( value_convert >= PARM_MIN_ENABLE_ENCRYPTION ) && ( value_convert <= PARM_MAX_ENABLE_ENCRYPTION )) {
 			lp->EnableEncryption = value_convert;
 		} else {
@@ -529,7 +529,7 @@ void translate_option( char *buffer, str
 	else if ( strcmp( key, PARM_NAME_MULTICAST_RATE ) == 0 ) {
 		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RATE, value );
 
-		value_convert = wl_atoi( value );
+		value_convert = simple_strtoul(value, NULL, 0);
 
 		if (( value_convert >= PARM_MIN_MULTICAST_RATE ) && ( value_convert <= PARM_MAX_MULTICAST_RATE )) {
 			lp->MulticastRate[0] = value_convert;
@@ -540,7 +540,7 @@ void translate_option( char *buffer, str
 	else if ( strcmp( key, PARM_NAME_OWN_CHANNEL ) == 0 ) {
 		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_CHANNEL, value );
 
-		value_convert = wl_atoi( value );
+		value_convert = simple_strtoul(value, NULL, 0);
 		if ( wl_is_a_valid_chan( value_convert )) {
 			if ( value_convert > 14 ) {
 				value_convert = value_convert | 0x100;
@@ -567,7 +567,7 @@ void translate_option( char *buffer, str
 	else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD ) == 0 ) {
 		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD, value );
 
-		value_convert = wl_atoi( value );
+		value_convert = simple_strtoul(value, NULL, 0);
 		if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
 			lp->RTSThreshold = value_convert;
 		} else {
@@ -577,7 +577,7 @@ void translate_option( char *buffer, str
 	else if ( strcmp( key, PARM_NAME_SRSC_2GHZ ) == 0 ) {
 		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_2GHZ, value );
 
-		value_convert = wl_atoi( value );
+		value_convert = simple_strtoul(value, NULL, 0);
 		if (( value_convert >= PARM_MIN_SRSC ) || ( value_convert <= PARM_MAX_SRSC )) {
 			lp->srsc[0] = value_convert;
 		} else {
@@ -587,7 +587,7 @@ void translate_option( char *buffer, str
 	else if ( strcmp( key, PARM_NAME_SRSC_5GHZ ) == 0 ) {
 		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ, value );
 
-		value_convert = wl_atoi( value );
+		value_convert = simple_strtoul(value, NULL, 0);
 		if (( value_convert >= PARM_MIN_SRSC ) || ( value_convert <= PARM_MAX_SRSC )) {
 			lp->srsc[1] = value_convert;
 		} else {
@@ -597,7 +597,7 @@ void translate_option( char *buffer, str
 	else if ( strcmp( key, PARM_NAME_SYSTEM_SCALE ) == 0 ) {
 		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE, value );
 
-		value_convert = wl_atoi( value );
+		value_convert = simple_strtoul(value, NULL, 0);
 		if (( value_convert >= PARM_MIN_SYSTEM_SCALE ) && ( value_convert <= PARM_MAX_SYSTEM_SCALE )) {
 			lp->DistanceBetweenAPs = value_convert;
 		} else {
@@ -607,9 +607,9 @@ void translate_option( char *buffer, str
 	else if ( strcmp( key, PARM_NAME_TX_KEY ) == 0 ) {
 		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_KEY, value );
 
-		value_convert = wl_atoi( value );
+		value_convert = simple_strtoul(value, NULL, 0);
 		if (( value_convert >= PARM_MIN_TX_KEY ) && ( value_convert <= PARM_MAX_TX_KEY )) {
-			lp->TransmitKeyID = wl_atoi( value );
+			lp->TransmitKeyID = simple_strtoul(value, NULL, 0);
 		} else {
 			DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_KEY );
 		}
@@ -617,7 +617,7 @@ void translate_option( char *buffer, str
 	else if ( strcmp( key, PARM_NAME_TX_RATE ) == 0 ) {
 		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE, value );
 
-		value_convert = wl_atoi( value );
+		value_convert = simple_strtoul(value, NULL, 0);
 		if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
 			lp->TxRateControl[0] = value_convert;
 		} else {
@@ -627,7 +627,7 @@ void translate_option( char *buffer, str
 	else if ( strcmp( key, PARM_NAME_TX_POW_LEVEL ) == 0 ) {
 		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_POW_LEVEL, value );
 
-		value_convert = wl_atoi( value );
+		value_convert = simple_strtoul(value, NULL, 0);
 		if (( value_convert >= PARM_MIN_TX_POW_LEVEL ) || ( value_convert <= PARM_MAX_TX_POW_LEVEL )) {
 			lp->txPowLevel = value_convert;
 		} else {
@@ -645,7 +645,7 @@ void translate_option( char *buffer, str
 		if ( strcmp( key, PARM_NAME_PORT_TYPE ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PORT_TYPE, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert == PARM_MIN_PORT_TYPE ) || ( value_convert == PARM_MAX_PORT_TYPE )) {
 				lp->PortType = value_convert;
 			} else {
@@ -654,7 +654,7 @@ void translate_option( char *buffer, str
 		}
 		else if ( strcmp( key, PARM_NAME_PM_ENABLED ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PM_ENABLED, value );
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 	/* ;? how about wl_main.c containing
 	 * VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
 	 *					 ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
@@ -677,7 +677,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_MAX_SLEEP ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MAX_SLEEP, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= 0 ) && ( value_convert <= 65535 )) {
 				lp->MaxSleepDuration = value_convert;
 			} else {
@@ -696,7 +696,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_AUTHENTICATION ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_AUTHENTICATION, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_AUTHENTICATION ) && ( value_convert <= PARM_MAX_AUTHENTICATION )) {
 				lp->authentication = value_convert;
 			} else {
@@ -706,7 +706,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_OWN_ATIM_WINDOW ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_ATIM_WINDOW, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_OWN_ATIM_WINDOW ) && ( value_convert <= PARM_MAX_OWN_ATIM_WINDOW )) {
 				lp->atimWindow = value_convert;
 			} else {
@@ -716,7 +716,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_PM_HOLDOVER_DURATION ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PM_HOLDOVER_DURATION, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_PM_HOLDOVER_DURATION ) && ( value_convert <= PARM_MAX_PM_HOLDOVER_DURATION )) {
 				lp->holdoverDuration = value_convert;
 			} else {
@@ -730,7 +730,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_CONNECTION_CONTROL ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_CONNECTION_CONTROL, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_CONNECTION_CONTROL ) && ( value_convert <= PARM_MAX_CONNECTION_CONTROL )) {
 				lp->connectionControl = value_convert;
 			} else {
@@ -749,7 +749,7 @@ void translate_option( char *buffer, str
 		if ( strcmp( key, PARM_NAME_OWN_DTIM_PERIOD ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_DTIM_PERIOD, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if ( value_convert >= PARM_MIN_OWN_DTIM_PERIOD ) {
 				lp->DTIMPeriod = value_convert;
 			} else {
@@ -775,7 +775,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_OWN_BEACON_INTERVAL ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_BEACON_INTERVAL, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if ( value_convert >= PARM_MIN_OWN_BEACON_INTERVAL ) {
 				lp->ownBeaconInterval = value_convert;
 			} else {
@@ -785,7 +785,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_COEXISTENCE ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_COEXISTENCE, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if ( value_convert >= PARM_MIN_COEXISTENCE ) {
 				lp->coexistence = value_convert;
 			} else {
@@ -797,7 +797,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD1 ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD1, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
 				lp->wds_port[0].rtsThreshold = value_convert;
 			} else {
@@ -807,7 +807,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD2 ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD2, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
 				lp->wds_port[1].rtsThreshold = value_convert;
 			} else {
@@ -817,7 +817,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD3 ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD3, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
 				lp->wds_port[2].rtsThreshold = value_convert;
 			} else {
@@ -827,7 +827,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD4 ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD4, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
 				lp->wds_port[3].rtsThreshold = value_convert;
 			} else {
@@ -837,7 +837,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD5 ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD5, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
 				lp->wds_port[4].rtsThreshold = value_convert;
 			} else {
@@ -847,7 +847,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD6 ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD6, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
 				lp->wds_port[5].rtsThreshold = value_convert;
 			} else {
@@ -857,7 +857,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_TX_RATE1 ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE1, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
 				lp->wds_port[0].txRateCntl = value_convert;
 			} else {
@@ -867,7 +867,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_TX_RATE2 ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE2, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
 				lp->wds_port[1].txRateCntl = value_convert;
 			} else {
@@ -877,7 +877,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_TX_RATE3 ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE3, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
 				lp->wds_port[2].txRateCntl = value_convert;
 			} else {
@@ -887,7 +887,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_TX_RATE4 ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE4, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
 				lp->wds_port[3].txRateCntl = value_convert;
 			} else {
@@ -897,7 +897,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_TX_RATE5 ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE5, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
 				lp->wds_port[4].txRateCntl = value_convert;
 			} else {
@@ -907,7 +907,7 @@ void translate_option( char *buffer, str
 		else if ( strcmp( key, PARM_NAME_TX_RATE6 ) == 0 ) {
 			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE6, value );
 
-			value_convert = wl_atoi( value );
+			value_convert = simple_strtoul(value, NULL, 0);
 			if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
 				lp->wds_port[5].txRateCntl = value_convert;
 			} else {
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_util.c linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_util.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_util.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_util.c	2010-05-16 17:17:36.000000000 -0400
@@ -1536,52 +1536,3 @@ int wl_get_tallies(struct wl_private *lp
     return ret;
 }
 
-/*******************************************************************************
- *	wl_atoi()
- *******************************************************************************
- *
- *  DESCRIPTION:
- *
- *      Believe it or not, we need our own implementation of atoi in the kernel.
- *
- *  PARAMETERS:
- *
- *      string  - the ASCII string to convert to an integer
- *
- *  RETURNS:
- *
- *      unsigned integer
- *
- ******************************************************************************/
-unsigned int wl_atoi( char *string )
-{
-unsigned int base = 10;				//default to decimal
-unsigned int value = 0;
-unsigned int c;
-int i = strlen( string );
-
-	if ( i > 2 && string[0] == '0' && ( string[1] | ('X'^'x') ) == 'x' ) {
-		base = 16;
-		string +=2;
-	}
-	while ( ( c = *string++ ) != '\0' ) {
-		if ( value > UINT_MAX / base ) {	//test for overrun
-			DBG_FUNC( "wl_atoi" );	//don't overload the log file with good messages
-			DBG_ENTER( DbgInfo );
-			DBG_ERROR( DbgInfo, "string \"%s\", lenght exceeds expectations\n", string );
-			printk( "<1>string \"%s\", lenght exceeds expectations\n", string );
-			DBG_LEAVE( DbgInfo );
-			break;
-		}
-		c -= '0';
-		if ( 0 <= c && c <= 9 ) value = base * value + c;
-		else if ( base == 16 ) {
-			c += '0';
-			c |= 'A'^'a';
-			c = c - 'a'+ 10;
-			if ( 10 <= c && c <= 15 ) value = base * value + c;
-		}
-	}
-	return value;
-} // wl_atoi
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_util.h linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_util.h
--- linux-libre-2.6.33-gnu1/drivers/staging/wlags49_h2/wl_util.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlags49_h2/wl_util.h	2010-05-16 17:17:36.000000000 -0400
@@ -100,6 +100,4 @@ void wl_process_updated_record( struct w
 void wl_process_assoc_status( struct wl_private *lp );
 void wl_process_security_status( struct wl_private *lp );
 
-unsigned int wl_atoi( char *string );
-
 #endif  // __WL_UTIL_H__
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/hfa384x.h linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/hfa384x.h
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/hfa384x.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/hfa384x.h	2010-05-16 17:17:36.000000000 -0400
@@ -61,17 +61,17 @@
 #include <linux/if_ether.h>
 
 /*--- Mins & Maxs -----------------------------------*/
-#define		HFA384x_PORTID_MAX		((u16)7)
-#define		HFA384x_NUMPORTS_MAX		((u16)(HFA384x_PORTID_MAX+1))
-#define		HFA384x_PDR_LEN_MAX		((u16)512)	/* in bytes, from EK */
-#define		HFA384x_PDA_RECS_MAX		((u16)200)	/* a guess */
-#define		HFA384x_PDA_LEN_MAX		((u16)1024)	/* in bytes, from EK */
-#define		HFA384x_SCANRESULT_MAX		((u16)31)
-#define		HFA384x_HSCANRESULT_MAX		((u16)31)
-#define		HFA384x_CHINFORESULT_MAX	((u16)16)
-#define		HFA384x_RID_GUESSING_MAXLEN	2048	/* I'm not really sure */
-#define		HFA384x_RIDDATA_MAXLEN		HFA384x_RID_GUESSING_MAXLEN
-#define		HFA384x_USB_RWMEM_MAXLEN	2048
+#define	HFA384x_PORTID_MAX		((u16)7)
+#define	HFA384x_NUMPORTS_MAX		((u16)(HFA384x_PORTID_MAX+1))
+#define	HFA384x_PDR_LEN_MAX		((u16)512) /* in bytes, from EK */
+#define	HFA384x_PDA_RECS_MAX		((u16)200) /* a guess */
+#define	HFA384x_PDA_LEN_MAX		((u16)1024) /* in bytes, from EK*/
+#define	HFA384x_SCANRESULT_MAX		((u16)31)
+#define	HFA384x_HSCANRESULT_MAX		((u16)31)
+#define	HFA384x_CHINFORESULT_MAX	((u16)16)
+#define	HFA384x_RID_GUESSING_MAXLEN	2048	/* I'm not really sure */
+#define	HFA384x_RIDDATA_MAXLEN		HFA384x_RID_GUESSING_MAXLEN
+#define	HFA384x_USB_RWMEM_MAXLEN	2048
 
 /*--- Support Constants -----------------------------*/
 #define		HFA384x_PORTTYPE_IBSS			((u16)0)
@@ -115,8 +115,8 @@
 
 /* Make a 32-bit flat address from AUX format 16-bit page and offset */
 #define		HFA384x_ADDR_AUX_MKFLAT(p, o)	\
-		(((u32)(((u16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) << 7) | \
-		((u32)(((u16)(o))&HFA384x_ADDR_AUX_OFF_MASK))
+		((((u32)(((u16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) << 7) | \
+		((u32)(((u16)(o))&HFA384x_ADDR_AUX_OFF_MASK)))
 
 /* Make CMD format offset and page from a 32-bit flat address */
 #define		HFA384x_ADDR_CMD_MKPAGE(f) \
@@ -135,12 +135,21 @@
 #define		HFA384x_DLSTATE_FLASHENABLED		2
 
 /*--- Register Field Masks --------------------------*/
-#define		HFA384x_CMD_AINFO		((u16)(BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | BIT(8)))
-#define		HFA384x_CMD_MACPORT		((u16)(BIT(10) | BIT(9) | BIT(8)))
+#define		HFA384x_CMD_AINFO		((u16)(BIT(14) | BIT(13) \
+							| BIT(12) | BIT(11) \
+							| BIT(10) | BIT(9) \
+							| BIT(8)))
+#define		HFA384x_CMD_MACPORT		((u16)(BIT(10) | BIT(9) | \
+							BIT(8)))
 #define		HFA384x_CMD_PROGMODE		((u16)(BIT(9) | BIT(8)))
-#define		HFA384x_CMD_CMDCODE		((u16)(BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)))
+#define		HFA384x_CMD_CMDCODE		((u16)(BIT(5) | BIT(4) | \
+							BIT(3) | BIT(2) | \
+							BIT(1) | BIT(0)))
 
-#define		HFA384x_STATUS_RESULT		((u16)(BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | BIT(8)))
+#define		HFA384x_STATUS_RESULT		((u16)(BIT(14) | BIT(13) \
+							| BIT(12) | BIT(11) \
+							| BIT(10) | BIT(9) \
+							| BIT(8)))
 
 /*--- Command Code Constants --------------------------*/
 /*--- Controller Commands --------------------------*/
@@ -244,8 +253,10 @@ Information RID Lengths:  MAC Informatio
   This is the length of JUST the DATA part of the RID (does not
   include the len or code fields)
 --------------------------------------------------------------------*/
-#define		HFA384x_RID_DBMCOMMSQUALITY_LEN		((u16)sizeof(hfa384x_dbmcommsquality_t))
-#define		HFA384x_RID_JOINREQUEST_LEN		((u16)sizeof(hfa384x_JoinRequest_data_t))
+#define		HFA384x_RID_DBMCOMMSQUALITY_LEN	 \
+	((u16) sizeof(hfa384x_dbmcommsquality_t))
+#define		HFA384x_RID_JOINREQUEST_LEN \
+	((u16)sizeof(hfa384x_JoinRequest_data_t))
 
 /*--------------------------------------------------------------------
 Information RIDs:  Modem Information
@@ -322,9 +333,11 @@ PD Record codes
 
 /*--- Register Test/Get/Set Field macros ------------------------*/
 
-#define		HFA384x_CMD_AINFO_SET(value)		((u16)((u16)(value) << 8))
-#define		HFA384x_CMD_MACPORT_SET(value)		((u16)HFA384x_CMD_AINFO_SET(value))
-#define		HFA384x_CMD_PROGMODE_SET(value)		((u16)HFA384x_CMD_AINFO_SET((u16)value))
+#define		HFA384x_CMD_AINFO_SET(value)	((u16)((u16)(value) << 8))
+#define		HFA384x_CMD_MACPORT_SET(value)	\
+			((u16)HFA384x_CMD_AINFO_SET(value))
+#define		HFA384x_CMD_PROGMODE_SET(value)	\
+			((u16)HFA384x_CMD_AINFO_SET((u16)value))
 #define		HFA384x_CMD_CMDCODE_SET(value)		((u16)(value))
 
 #define		HFA384x_STATUS_RESULT_SET(value)	(((u16)(value)) << 8)
@@ -402,7 +415,7 @@ typedef struct hfa384x_authenticateStati
 /*-- Configuration Record: WPAData       (data portion only) --*/
 typedef struct hfa384x_WPAData {
 	u16 datalen;
-	u8 data[0];		// max 80
+	u8 data[0];		/* max 80 */
 } __attribute__ ((packed)) hfa384x_WPAData_t;
 
 /*--------------------------------------------------------------------
@@ -479,7 +492,8 @@ Communication Frames: Field Masks for Tr
 #define		HFA384x_TXSTATUS_AGEDERR		((u16)BIT(1))
 #define		HFA384x_TXSTATUS_RETRYERR		((u16)BIT(0))
 /*-- Transmit Control Field --*/
-#define		HFA384x_TX_MACPORT			((u16)(BIT(10) | BIT(9) | BIT(8)))
+#define		HFA384x_TX_MACPORT			((u16)(BIT(10) | \
+							  BIT(9) | BIT(8)))
 #define		HFA384x_TX_STRUCTYPE			((u16)(BIT(4) | BIT(3)))
 #define		HFA384x_TX_TXEX				((u16)BIT(2))
 #define		HFA384x_TX_TXOK				((u16)BIT(1))
@@ -496,7 +510,8 @@ Communication Frames: Test/Get/Set Field
 #define	HFA384x_TX_SET(v, m, s)		((((u16)(v))<<((u16)(s)))&((u16)(m)))
 
 #define	HFA384x_TX_MACPORT_SET(v)	HFA384x_TX_SET(v, HFA384x_TX_MACPORT, 8)
-#define	HFA384x_TX_STRUCTYPE_SET(v)	HFA384x_TX_SET(v, HFA384x_TX_STRUCTYPE, 3)
+#define	HFA384x_TX_STRUCTYPE_SET(v)	HFA384x_TX_SET(v, \
+						HFA384x_TX_STRUCTYPE, 3)
 #define	HFA384x_TX_TXEX_SET(v)		HFA384x_TX_SET(v, HFA384x_TX_TXEX, 2)
 #define	HFA384x_TX_TXOK_SET(v)		HFA384x_TX_SET(v, HFA384x_TX_TXOK, 1)
 /*--------------------------------------------------------------------
@@ -534,13 +549,17 @@ Communication Frames: Field Masks for Re
 --------------------------------------------------------------------*/
 
 /*-- Status Fields --*/
-#define		HFA384x_RXSTATUS_MACPORT		((u16)(BIT(10) | BIT(9) | BIT(8)))
+#define		HFA384x_RXSTATUS_MACPORT		((u16)(BIT(10) | \
+								BIT(9) | \
+								BIT(8)))
 #define		HFA384x_RXSTATUS_FCSERR			((u16)BIT(0))
 /*--------------------------------------------------------------------
 Communication Frames: Test/Get/Set Field Values for Receive Frames
 --------------------------------------------------------------------*/
-#define		HFA384x_RXSTATUS_MACPORT_GET(value)	((u16)((((u16)(value)) & HFA384x_RXSTATUS_MACPORT) >> 8))
-#define		HFA384x_RXSTATUS_ISFCSERR(value)	((u16)(((u16)(value)) & HFA384x_RXSTATUS_FCSERR))
+#define		HFA384x_RXSTATUS_MACPORT_GET(value)	((u16)((((u16)(value)) \
+					    & HFA384x_RXSTATUS_MACPORT) >> 8))
+#define		HFA384x_RXSTATUS_ISFCSERR(value)	((u16)(((u16)(value)) \
+						  & HFA384x_RXSTATUS_FCSERR))
 /*--------------------------------------------------------------------
  FRAME STRUCTURES: Information Types and Information Frame Structures
 ----------------------------------------------------------------------
@@ -1133,7 +1152,7 @@ struct hfa384x;
 
 typedef void (*ctlx_cmdcb_t) (struct hfa384x *, const struct hfa384x_usbctlx *);
 
-typedef void (*ctlx_usercb_t) (struct hfa384x * hw,
+typedef void (*ctlx_usercb_t) (struct hfa384x *hw,
 			       void *ctlxresult, void *usercb_data);
 
 typedef struct hfa384x_usbctlx {
@@ -1174,14 +1193,14 @@ typedef struct hfa484x_metacmd {
 } hfa384x_metacmd_t;
 
 #define	MAX_GRP_ADDR		32
-#define WLAN_COMMENT_MAX	80	/* Max. length of user comment string. */
+#define WLAN_COMMENT_MAX	80  /* Max. length of user comment string. */
 
-#define WLAN_AUTH_MAX           60	/* Max. # of authenticated stations. */
-#define WLAN_ACCESS_MAX		60	/* Max. # of stations in an access list. */
-#define WLAN_ACCESS_NONE	0	/* No stations may be authenticated. */
-#define WLAN_ACCESS_ALL		1	/* All stations may be authenticated. */
-#define WLAN_ACCESS_ALLOW	2	/* Authenticate only "allowed" stations. */
-#define WLAN_ACCESS_DENY	3	/* Do not authenticate "denied" stations. */
+#define WLAN_AUTH_MAX           60  /* Max. # of authenticated stations. */
+#define WLAN_ACCESS_MAX		60  /* Max. # of stations in an access list. */
+#define WLAN_ACCESS_NONE	0   /* No stations may be authenticated. */
+#define WLAN_ACCESS_ALL		1   /* All stations may be authenticated. */
+#define WLAN_ACCESS_ALLOW	2   /* Authenticate only "allowed" stations. */
+#define WLAN_ACCESS_DENY	3   /* Do not authenticate "denied" stations. */
 
 /* XXX These are going away ASAP */
 typedef struct prism2sta_authlist {
@@ -1294,10 +1313,23 @@ typedef struct hfa384x {
 	hfa384x_caplevel_t cap_sup_ap;
 
 	/* Actor compatibility ranges */
-	hfa384x_caplevel_t cap_act_pri_cfi;	/* pri f/w to controller interface */
-	hfa384x_caplevel_t cap_act_sta_cfi;	/* sta f/w to controller interface */
+	hfa384x_caplevel_t cap_act_pri_cfi;	/*
+						 * pri f/w to controller
+						 * interface
+						 */
+
+	hfa384x_caplevel_t cap_act_sta_cfi;	/*
+						 * sta f/w to controller
+						 * interface
+						 */
+
 	hfa384x_caplevel_t cap_act_sta_mfi;	/* sta f/w to modem interface */
-	hfa384x_caplevel_t cap_act_ap_cfi;	/* ap f/w to controller interface */
+
+	hfa384x_caplevel_t cap_act_ap_cfi;	/*
+						 * ap f/w to controller
+						 * interface
+						 */
+
 	hfa384x_caplevel_t cap_act_ap_mfi;	/* ap f/w to modem interface */
 
 	u32 psusercount;	/* Power save user count. */
@@ -1320,25 +1352,25 @@ typedef struct hfa384x {
 
 } hfa384x_t;
 
-void hfa384x_create(hfa384x_t * hw, struct usb_device *usb);
-void hfa384x_destroy(hfa384x_t * hw);
+void hfa384x_create(hfa384x_t *hw, struct usb_device *usb);
+void hfa384x_destroy(hfa384x_t *hw);
 
 int
-hfa384x_corereset(hfa384x_t * hw, int holdtime, int settletime, int genesis);
-int hfa384x_drvr_commtallies(hfa384x_t * hw);
-int hfa384x_drvr_disable(hfa384x_t * hw, u16 macport);
-int hfa384x_drvr_enable(hfa384x_t * hw, u16 macport);
-int hfa384x_drvr_flashdl_enable(hfa384x_t * hw);
-int hfa384x_drvr_flashdl_disable(hfa384x_t * hw);
-int hfa384x_drvr_flashdl_write(hfa384x_t * hw, u32 daddr, void *buf, u32 len);
-int hfa384x_drvr_getconfig(hfa384x_t * hw, u16 rid, void *buf, u16 len);
-int hfa384x_drvr_ramdl_enable(hfa384x_t * hw, u32 exeaddr);
-int hfa384x_drvr_ramdl_disable(hfa384x_t * hw);
-int hfa384x_drvr_ramdl_write(hfa384x_t * hw, u32 daddr, void *buf, u32 len);
-int hfa384x_drvr_readpda(hfa384x_t * hw, void *buf, unsigned int len);
-int hfa384x_drvr_setconfig(hfa384x_t * hw, u16 rid, void *buf, u16 len);
+hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis);
+int hfa384x_drvr_commtallies(hfa384x_t *hw);
+int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport);
+int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport);
+int hfa384x_drvr_flashdl_enable(hfa384x_t *hw);
+int hfa384x_drvr_flashdl_disable(hfa384x_t *hw);
+int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len);
+int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
+int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr);
+int hfa384x_drvr_ramdl_disable(hfa384x_t *hw);
+int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len);
+int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len);
+int hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
 
-static inline int hfa384x_drvr_getconfig16(hfa384x_t * hw, u16 rid, void *val)
+static inline int hfa384x_drvr_getconfig16(hfa384x_t *hw, u16 rid, void *val)
 {
 	int result = 0;
 	result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u16));
@@ -1347,46 +1379,46 @@ static inline int hfa384x_drvr_getconfig
 	return result;
 }
 
-static inline int hfa384x_drvr_setconfig16(hfa384x_t * hw, u16 rid, u16 val)
+static inline int hfa384x_drvr_setconfig16(hfa384x_t *hw, u16 rid, u16 val)
 {
 	u16 value = cpu_to_le16(val);
 	return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value));
 }
 
 int
-hfa384x_drvr_getconfig_async(hfa384x_t * hw,
+hfa384x_drvr_getconfig_async(hfa384x_t *hw,
 			     u16 rid, ctlx_usercb_t usercb, void *usercb_data);
 
 int
-hfa384x_drvr_setconfig_async(hfa384x_t * hw,
+hfa384x_drvr_setconfig_async(hfa384x_t *hw,
 			     u16 rid,
 			     void *buf,
 			     u16 len, ctlx_usercb_t usercb, void *usercb_data);
 
 static inline int
-hfa384x_drvr_setconfig16_async(hfa384x_t * hw, u16 rid, u16 val)
+hfa384x_drvr_setconfig16_async(hfa384x_t *hw, u16 rid, u16 val)
 {
 	u16 value = cpu_to_le16(val);
 	return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value),
 					    NULL, NULL);
 }
 
-int hfa384x_drvr_start(hfa384x_t * hw);
-int hfa384x_drvr_stop(hfa384x_t * hw);
+int hfa384x_drvr_start(hfa384x_t *hw);
+int hfa384x_drvr_stop(hfa384x_t *hw);
 int
-hfa384x_drvr_txframe(hfa384x_t * hw, struct sk_buff *skb,
-		     p80211_hdr_t * p80211_hdr, p80211_metawep_t * p80211_wep);
-void hfa384x_tx_timeout(wlandevice_t * wlandev);
+hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
+		     p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
+void hfa384x_tx_timeout(wlandevice_t *wlandev);
 
-int hfa384x_cmd_initialize(hfa384x_t * hw);
-int hfa384x_cmd_enable(hfa384x_t * hw, u16 macport);
-int hfa384x_cmd_disable(hfa384x_t * hw, u16 macport);
-int hfa384x_cmd_allocate(hfa384x_t * hw, u16 len);
-int hfa384x_cmd_monitor(hfa384x_t * hw, u16 enable);
+int hfa384x_cmd_initialize(hfa384x_t *hw);
+int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport);
+int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport);
+int hfa384x_cmd_allocate(hfa384x_t *hw, u16 len);
+int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable);
 int
-hfa384x_cmd_download(hfa384x_t * hw,
+hfa384x_cmd_download(hfa384x_t *hw,
 		     u16 mode, u16 lowaddr, u16 highaddr, u16 codelen);
 
-#endif /* __KERNEL__ */
+#endif /*__KERNEL__ */
 
-#endif /* _HFA384x_H */
+#endif /*_HFA384x_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/hfa384x_usb.c linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/hfa384x_usb.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/hfa384x_usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/hfa384x_usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,7 +52,7 @@
 * around the register accesses.  The next higher level represents C-callable
 * prism2 API functions that match the Intersil documentation as closely
 * as is reasonable.  The next higher layer implements common sequences
-* of invokations of the API layer (e.g. write to bap, followed by cmd).
+* of invocations of the API layer (e.g. write to bap, followed by cmd).
 *
 * Common sequences:
 * hfa384x_drvr_xxx	Highest level abstractions provided by the
@@ -118,15 +118,15 @@
 #include <linux/wireless.h>
 #include <linux/netdevice.h>
 #include <linux/timer.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <asm/byteorder.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <linux/list.h>
 #include <linux/usb.h>
 #include <linux/byteorder/generic.h>
 
-#define SUBMIT_URB(u,f)  usb_submit_urb(u,f)
+#define SUBMIT_URB(u, f)  usb_submit_urb(u, f)
 
 #include "p80211types.h"
 #include "p80211hdr.h"
@@ -627,7 +627,7 @@ static hfa384x_usbctlx_t *usbctlx_alloc(
 {
 	hfa384x_usbctlx_t *ctlx;
 
-	ctlx = kmalloc(sizeof(*ctlx), in_interrupt()? GFP_ATOMIC : GFP_KERNEL);
+	ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
 	if (ctlx != NULL) {
 		memset(ctlx, 0, sizeof(*ctlx));
 		init_completion(&ctlx->done);
@@ -675,7 +675,7 @@ struct usbctlx_cmd_completor {
 };
 typedef struct usbctlx_cmd_completor usbctlx_cmd_completor_t;
 
-static int usbctlx_cmd_completor_fn(usbctlx_completor_t * head)
+static int usbctlx_cmd_completor_fn(usbctlx_completor_t *head)
 {
 	usbctlx_cmd_completor_t *complete = (usbctlx_cmd_completor_t *) head;
 	return usbctlx_get_status(complete->cmdresp, complete->result);
@@ -1909,18 +1909,19 @@ int hfa384x_drvr_flashdl_enable(hfa384x_
 		return -EINVAL;
 
 	/* Retrieve the buffer loc&size and timeout */
-	if ((result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
-					     &(hw->bufinfo),
-					     sizeof(hw->bufinfo)))) {
+	result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
+					&(hw->bufinfo), sizeof(hw->bufinfo));
+	if (result)
 		return result;
-	}
+
 	hw->bufinfo.page = le16_to_cpu(hw->bufinfo.page);
 	hw->bufinfo.offset = le16_to_cpu(hw->bufinfo.offset);
 	hw->bufinfo.len = le16_to_cpu(hw->bufinfo.len);
-	if ((result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
-					       &(hw->dltimeout)))) {
+	result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
+					  &(hw->dltimeout));
+	if (result)
 		return result;
-	}
+
 	hw->dltimeout = le16_to_cpu(hw->dltimeout);
 
 	pr_debug("flashdl_enable\n");
@@ -3071,9 +3072,9 @@ static void hfa384x_usbctlxq_run(hfa384x
 				  hfa384x_ctlxout_callback, hw);
 		hw->ctlx_urb.transfer_flags |= USB_QUEUE_BULK;
 
-		/* Now submit the URB and update the CTLX's state
-		 */
-		if ((result = SUBMIT_URB(&hw->ctlx_urb, GFP_ATOMIC)) == 0) {
+		/* Now submit the URB and update the CTLX's state */
+		result = SUBMIT_URB(&hw->ctlx_urb, GFP_ATOMIC);
+		if (result == 0) {
 			/* This CTLX is now running on the active queue */
 			head->state = CTLX_REQ_SUBMITTED;
 
@@ -3599,7 +3600,8 @@ static void hfa384x_int_rxmonitor(wlande
 			 skblen - sizeof(p80211_caphdr_t));
 	}
 
-	if ((skb = dev_alloc_skb(skblen)) == NULL) {
+	skb = dev_alloc_skb(skblen);
+	if (skb == NULL) {
 		printk(KERN_ERR
 		       "alloc_skb failed trying to allocate %d bytes\n",
 		       skblen);
@@ -3642,7 +3644,7 @@ static void hfa384x_int_rxmonitor(wlande
 		/* check for unencrypted stuff if WEP bit set. */
 		if (*(datap - hdrlen + 1) & 0x40)	/* wep set */
 			if ((*(datap) == 0xaa) && (*(datap + 1) == 0xaa))
-				*(datap - hdrlen + 1) &= 0xbf;	// clear wep; it's the 802.2 header!
+				*(datap - hdrlen + 1) &= 0xbf;	/* clear wep; it's the 802.2 header! */
 	}
 
 	if (hw->sniff_fcs) {
@@ -3870,9 +3872,9 @@ retry:
 
 delresp:
 	if (delete_resptimer) {
-		if ((timer_ok = del_timer(&hw->resptimer)) != 0) {
+		timer_ok = del_timer(&hw->resptimer);
+		if (timer_ok != 0)
 			hw->resp_timer_done = 1;
-		}
 	}
 
 	spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/Kconfig linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,8 @@
 config PRISM2_USB
 	tristate "Prism2.5/3 USB driver"
-	depends on WLAN && USB && WIRELESS_EXT
+	depends on WLAN && USB
+	select WIRELESS_EXT
+	select WEXT_PRIV
 	default n
 	---help---
 	  This is the wlan-ng prism 2.5/3 USB driver for a wide range of
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211conv.c linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211conv.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211conv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211conv.c	2010-05-16 17:17:36.000000000 -0400
@@ -206,12 +206,11 @@ int skb_ether_to_p80211(wlandevice_t *wl
 		/* XXXX need to pick keynum other than default? */
 
 		p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC);
-
-		if ((foo = wep_encrypt(wlandev, skb->data, p80211_wep->data,
-				       skb->len,
-				       (wlandev->hostwep &
-					HOSTWEP_DEFAULTKEY_MASK),
-				       p80211_wep->iv, p80211_wep->icv))) {
+		foo = wep_encrypt(wlandev, skb->data, p80211_wep->data,
+				  skb->len,
+				  (wlandev->hostwep &HOSTWEP_DEFAULTKEY_MASK),
+				  p80211_wep->iv, p80211_wep->icv);
+		if (foo) {
 			printk(KERN_WARNING
 			       "Host en-WEP failed, dropping frame (%d).\n",
 			       foo);
@@ -323,11 +322,12 @@ int skb_p80211_to_ether(wlandevice_t *wl
 			       skb->len);
 			return 1;
 		}
-		if ((foo = wep_decrypt(wlandev, skb->data + payload_offset + 4,
+		foo = wep_decrypt(wlandev, skb->data + payload_offset + 4,
 				       payload_length - 8, -1,
 				       skb->data + payload_offset,
 				       skb->data + payload_offset +
-				       payload_length - 4))) {
+				       payload_length - 4);
+		if (foo) {
 			/* de-wep failed, drop skb. */
 			pr_debug("Host de-WEP failed, dropping frame (%d).\n",
 				 foo);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211conv.h linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211conv.h
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211conv.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211conv.h	2010-05-16 17:17:36.000000000 -0400
@@ -153,8 +153,8 @@ struct wlandevice;
 int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv,
 			struct sk_buff *skb);
 int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv,
-			struct sk_buff *skb, p80211_hdr_t * p80211_hdr,
-			p80211_metawep_t * p80211_wep);
+			struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
+			p80211_metawep_t *p80211_wep);
 
 int p80211_stt_findproto(u16 proto);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211metadef.h linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211metadef.h
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211metadef.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211metadef.h	2010-05-16 17:17:36.000000000 -0400
@@ -190,9 +190,9 @@
 			(P80211DID_MKSECTION(2) | \
 			P80211DID_MKGROUP(1))
 #define DIDmib_dot11mac_dot11OperationTable_dot11MACAddress \
-                        (P80211DID_MKSECTION(2) | \
-                        P80211DID_MKGROUP(1) | \
-                        P80211DID_MKITEM(1) | 0x18000000)
+			(P80211DID_MKSECTION(2) | \
+			P80211DID_MKGROUP(1) | \
+			P80211DID_MKITEM(1) | 0x18000000)
 #define DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold \
 			(P80211DID_MKSECTION(2) | \
 			P80211DID_MKGROUP(1) | \
@@ -210,18 +210,18 @@
 			P80211DID_MKGROUP(1) | \
 			P80211DID_MKITEM(5) | 0x18000000)
 #define DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime \
-                       (P80211DID_MKSECTION(2) | \
-                       P80211DID_MKGROUP(1) | \
-                       P80211DID_MKITEM(6) | 0x10000000)
+			(P80211DID_MKSECTION(2) | \
+			P80211DID_MKGROUP(1) | \
+			P80211DID_MKITEM(6) | 0x10000000)
 #define DIDmib_cat_dot11phy \
 			P80211DID_MKSECTION(3)
 #define DIDmib_dot11phy_dot11PhyOperationTable \
 			(P80211DID_MKSECTION(3) | \
 			P80211DID_MKGROUP(1))
 #define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel \
-                       (P80211DID_MKSECTION(3) | \
-                       P80211DID_MKGROUP(3) | \
-                       P80211DID_MKITEM(10) | 0x18000000)
+			(P80211DID_MKSECTION(3) | \
+			P80211DID_MKGROUP(3) | \
+			P80211DID_MKITEM(10) | 0x18000000)
 #define DIDmib_dot11phy_dot11PhyDSSSTable \
 			(P80211DID_MKSECTION(3) | \
 			P80211DID_MKGROUP(5))
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211mgmt.h linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211mgmt.h
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211mgmt.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211mgmt.h	2010-05-16 17:17:36.000000000 -0400
@@ -100,7 +100,7 @@
 #ifndef _P80211MGMT_H
 #define _P80211MGMT_H
 
-#ifndef  _P80211HDR_H
+#ifndef _P80211HDR_H
 #include "p80211hdr.h"
 #endif
 
@@ -496,25 +496,25 @@ typedef struct wlan_fr_deauthen {
 
 } wlan_fr_deauthen_t;
 
-void wlan_mgmt_encode_beacon(wlan_fr_beacon_t * f);
-void wlan_mgmt_decode_beacon(wlan_fr_beacon_t * f);
-void wlan_mgmt_encode_disassoc(wlan_fr_disassoc_t * f);
-void wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t * f);
-void wlan_mgmt_encode_assocreq(wlan_fr_assocreq_t * f);
-void wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t * f);
-void wlan_mgmt_encode_assocresp(wlan_fr_assocresp_t * f);
-void wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t * f);
-void wlan_mgmt_encode_reassocreq(wlan_fr_reassocreq_t * f);
-void wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t * f);
-void wlan_mgmt_encode_reassocresp(wlan_fr_reassocresp_t * f);
-void wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t * f);
-void wlan_mgmt_encode_probereq(wlan_fr_probereq_t * f);
-void wlan_mgmt_decode_probereq(wlan_fr_probereq_t * f);
-void wlan_mgmt_encode_proberesp(wlan_fr_proberesp_t * f);
-void wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t * f);
-void wlan_mgmt_encode_authen(wlan_fr_authen_t * f);
-void wlan_mgmt_decode_authen(wlan_fr_authen_t * f);
-void wlan_mgmt_encode_deauthen(wlan_fr_deauthen_t * f);
-void wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t * f);
+void wlan_mgmt_encode_beacon(wlan_fr_beacon_t *f);
+void wlan_mgmt_decode_beacon(wlan_fr_beacon_t *f);
+void wlan_mgmt_encode_disassoc(wlan_fr_disassoc_t *f);
+void wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t *f);
+void wlan_mgmt_encode_assocreq(wlan_fr_assocreq_t *f);
+void wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t *f);
+void wlan_mgmt_encode_assocresp(wlan_fr_assocresp_t *f);
+void wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t *f);
+void wlan_mgmt_encode_reassocreq(wlan_fr_reassocreq_t *f);
+void wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t *f);
+void wlan_mgmt_encode_reassocresp(wlan_fr_reassocresp_t *f);
+void wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t *f);
+void wlan_mgmt_encode_probereq(wlan_fr_probereq_t *f);
+void wlan_mgmt_decode_probereq(wlan_fr_probereq_t *f);
+void wlan_mgmt_encode_proberesp(wlan_fr_proberesp_t *f);
+void wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t *f);
+void wlan_mgmt_encode_authen(wlan_fr_authen_t *f);
+void wlan_mgmt_decode_authen(wlan_fr_authen_t *f);
+void wlan_mgmt_encode_deauthen(wlan_fr_deauthen_t *f);
+void wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t *f);
 
 #endif /* _P80211MGMT_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211netdev.c linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211netdev.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211netdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211netdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -586,7 +586,8 @@ static int p80211knetdev_do_ioctl(netdev
 	}
 
 	/* Allocate a buf of size req->len */
-	if ((msgbuf = kmalloc(req->len, GFP_KERNEL))) {
+	msgbuf = kmalloc(req->len, GFP_KERNEL);
+	if (msgbuf) {
 		if (copy_from_user(msgbuf, (void __user *)req->data, req->len))
 			result = -EFAULT;
 		else
@@ -646,7 +647,7 @@ static int p80211knetdev_set_mac_address
 
 	/* Set up some convenience pointers. */
 	mibattr = &dot11req.mibattribute;
-	macaddr = (p80211item_pstr6_t *) & mibattr->data;
+	macaddr = (p80211item_pstr6_t *) &mibattr->data;
 	resultcode = &dot11req.resultcode;
 
 	/* Set up a dot11req_mibset */
@@ -674,7 +675,7 @@ static int p80211knetdev_set_mac_address
 	resultcode->data = 0;
 
 	/* now fire the request */
-	result = p80211req_dorequest(dev->ml_priv, (u8 *) & dot11req);
+	result = p80211req_dorequest(dev->ml_priv, (u8 *) &dot11req);
 
 	/* If the request wasn't successful, report an error and don't
 	 * change the netdev address
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211netdev.h linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211netdev.h
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211netdev.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211netdev.h	2010-05-16 17:17:36.000000000 -0400
@@ -179,16 +179,16 @@ typedef struct wlandevice {
 	unsigned int ethconv;
 
 	/* device methods (init by MSD, used by p80211 */
-	int (*open) (struct wlandevice * wlandev);
-	int (*close) (struct wlandevice * wlandev);
-	void (*reset) (struct wlandevice * wlandev);
-	int (*txframe) (struct wlandevice * wlandev, struct sk_buff * skb,
-			p80211_hdr_t * p80211_hdr,
-			p80211_metawep_t * p80211_wep);
-	int (*mlmerequest) (struct wlandevice * wlandev, p80211msg_t * msg);
-	int (*set_multicast_list) (struct wlandevice * wlandev,
-				   netdevice_t * dev);
-	void (*tx_timeout) (struct wlandevice * wlandev);
+	int (*open) (struct wlandevice *wlandev);
+	int (*close) (struct wlandevice *wlandev);
+	void (*reset) (struct wlandevice *wlandev);
+	int (*txframe) (struct wlandevice *wlandev, struct sk_buff *skb,
+			p80211_hdr_t *p80211_hdr,
+			p80211_metawep_t *p80211_wep);
+	int (*mlmerequest) (struct wlandevice *wlandev, p80211msg_t *msg);
+	int (*set_multicast_list) (struct wlandevice *wlandev,
+				   netdevice_t *dev);
+	void (*tx_timeout) (struct wlandevice *wlandev);
 
 	/* 802.11 State */
 	u8 bssid[WLAN_BSSID_LEN];
@@ -227,16 +227,16 @@ typedef struct wlandevice {
 } wlandevice_t;
 
 /* WEP stuff */
-int wep_change_key(wlandevice_t * wlandev, int keynum, u8 * key, int keylen);
-int wep_decrypt(wlandevice_t * wlandev, u8 * buf, u32 len, int key_override,
-		u8 * iv, u8 * icv);
-int wep_encrypt(wlandevice_t * wlandev, u8 * buf, u8 * dst, u32 len, int keynum,
-		u8 * iv, u8 * icv);
+int wep_change_key(wlandevice_t *wlandev, int keynum, u8 *key, int keylen);
+int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override,
+		u8 *iv, u8 *icv);
+int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
+		u8 *iv, u8 *icv);
 
-int wlan_setup(wlandevice_t * wlandev);
-int wlan_unsetup(wlandevice_t * wlandev);
-int register_wlandev(wlandevice_t * wlandev);
-int unregister_wlandev(wlandevice_t * wlandev);
-void p80211netdev_rx(wlandevice_t * wlandev, struct sk_buff *skb);
-void p80211netdev_hwremoved(wlandevice_t * wlandev);
+int wlan_setup(wlandevice_t *wlandev);
+int wlan_unsetup(wlandevice_t *wlandev);
+int register_wlandev(wlandevice_t *wlandev);
+int unregister_wlandev(wlandevice_t *wlandev);
+void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+void p80211netdev_hwremoved(wlandevice_t *wlandev);
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211req.c linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211req.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211req.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211req.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,7 +55,6 @@
 #include <linux/sched.h>
 #include <linux/types.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/wireless.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -94,7 +93,7 @@ static int p80211req_mibset_mibget(wland
 *	Potentially blocks the caller, so it's a good idea to
 *	not call this function from an interrupt context.
 ----------------------------------------------------------------*/
-int p80211req_dorequest(wlandevice_t * wlandev, u8 * msgbuf)
+int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf)
 {
 	int result = 0;
 	p80211msg_t *msg = (p80211msg_t *) msgbuf;
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211req.h linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211req.h
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211req.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211req.h	2010-05-16 17:17:36.000000000 -0400
@@ -48,6 +48,6 @@
 #ifndef _LINUX_P80211REQ_H
 #define _LINUX_P80211REQ_H
 
-int p80211req_dorequest(wlandevice_t * wlandev, u8 * msgbuf);
+int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf);
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211types.h linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211types.h
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211types.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211types.h	2010-05-16 17:17:36.000000000 -0400
@@ -168,12 +168,12 @@
 					P80211DID_MASK_ISTABLE, \
 					P80211DID_LSB_ISTABLE)
 
-#define P80211DID_MKID(s,g,i,n,t,a)	(P80211DID_MKSECTION(s) | \
-						P80211DID_MKGROUP(g) | \
-				 		P80211DID_MKITEM(i) | \
-				 		P80211DID_MKINDEX(n) | \
-						P80211DID_MKISTABLE(t) | \
-						(a))
+#define P80211DID_MKID(s, g, i, n, t, a)	(P80211DID_MKSECTION(s) | \
+					P80211DID_MKGROUP(g) | \
+					P80211DID_MKITEM(i) | \
+					P80211DID_MKINDEX(n) | \
+					P80211DID_MKISTABLE(t) | \
+					(a))
 
 #define P80211DID_GET(a, m, l)	((((u32)(a)) >> (l)) & (m))
 
@@ -340,11 +340,11 @@ struct catlistitem;
 /*  metadata items.  Some components may choose to use more, */
 /*  less or different metadata items. */
 
-typedef void (*p80211_totext_t) (struct catlistitem *, u32 did, u8 * itembuf,
+typedef void (*p80211_totext_t) (struct catlistitem *, u32 did, u8 *itembuf,
 				 char *textbuf);
-typedef void (*p80211_fromtext_t) (struct catlistitem *, u32 did, u8 * itembuf,
+typedef void (*p80211_fromtext_t) (struct catlistitem *, u32 did, u8 *itembuf,
 				   char *textbuf);
-typedef u32(*p80211_valid_t) (struct catlistitem *, u32 did, u8 * itembuf);
+typedef u32(*p80211_valid_t) (struct catlistitem *, u32 did, u8 *itembuf);
 
 /*----------------------------------------------------------------*/
 /* Enumeration Lists */
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211wep.c linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211wep.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211wep.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211wep.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,7 +50,6 @@
 
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/kernel.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211wext.c linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211wext.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/p80211wext.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/p80211wext.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,14 +40,13 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
 #include <linux/if_arp.h>
-#include <asm/bitops.h>
-#include <asm/uaccess.h>
+#include <linux/bitops.h>
+#include <linux/uaccess.h>
 #include <asm/byteorder.h>
 #include <linux/if_ether.h>
 #include <linux/bitops.h>
@@ -134,10 +133,11 @@ static int p80211wext_dorequest(wlandevi
 	int result;
 
 	msg.msgcode = DIDmsg_dot11req_mibset;
+	memset(&mibitem, 0, sizeof(mibitem));
 	mibitem.did = did;
 	mibitem.data = data;
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 	return result;
 }
@@ -174,7 +174,7 @@ static int p80211wext_autojoin(wlandevic
 	memcpy(msg.ssid.data.data, ssid, data.length);
 	msg.ssid.data.len = data.length;
 
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -211,7 +211,7 @@ struct iw_statistics *p80211wext_get_wir
 	if (wlandev->mlmerequest == NULL)
 		return NULL;
 
-	retval = wlandev->mlmerequest(wlandev, (p80211msg_t *) & quality);
+	retval = wlandev->mlmerequest(wlandev, (p80211msg_t *) &quality);
 
 	wstats->qual.qual = qual_as_percent(quality.link.data);	/* overall link quality */
 	wstats->qual.level = quality.level.data;	/* instant signal level */
@@ -269,9 +269,10 @@ static int p80211wext_giwfreq(netdevice_
 	int err = 0;
 
 	msg.msgcode = DIDmsg_dot11req_mibget;
+	memset(&mibitem, 0, sizeof(mibitem));
 	mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -309,6 +310,7 @@ static int p80211wext_siwfreq(netdevice_
 	}
 
 	msg.msgcode = DIDmsg_dot11req_mibset;
+	memset(&mibitem, 0, sizeof(mibitem));
 	mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
 	mibitem.status = P80211ENUM_msgitem_status_data_ok;
 
@@ -318,7 +320,7 @@ static int p80211wext_siwfreq(netdevice_
 		mibitem.data = p80211_mhz_to_channel(freq->m);
 
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -396,10 +398,11 @@ static int p80211wext_siwmode(netdevice_
 
 	/* Set Operation mode to the PORT TYPE RID */
 	msg.msgcode = DIDmsg_dot11req_mibset;
+	memset(&mibitem, 0, sizeof(mibitem));
 	mibitem.did = DIDmib_p2_p2Static_p2CnfPortType;
 	mibitem.data = (*mode == IW_MODE_ADHOC) ? 0 : 1;
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 	if (result)
 		err = -EFAULT;
@@ -549,14 +552,14 @@ static int p80211wext_siwencode(netdevic
 	}
 
 	/* Check the Key index first. */
-	if ((i = (erq->flags & IW_ENCODE_INDEX))) {
-
+	i = (erq->flags & IW_ENCODE_INDEX);
+	if (i) {
 		if ((i < 1) || (i > NUM_WEPKEYS)) {
 			err = -EINVAL;
 			goto exit;
-		} else
+		} else {
 			i--;
-
+		}
 		/* Set current key number only if no keys are given */
 		if (erq->flags & IW_ENCODE_NOKEY) {
 			result =
@@ -621,7 +624,7 @@ static int p80211wext_siwencode(netdevic
 
 			msg.msgcode = DIDmsg_dot11req_mibset;
 			memcpy(&msg.mibattribute.data, &pstr, sizeof(pstr));
-			result = p80211req_dorequest(wlandev, (u8 *) & msg);
+			result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 			if (result) {
 				err = -EFAULT;
@@ -729,7 +732,7 @@ static int p80211wext_siwessid(netdevice
 	msg.ssid.data.len = length;
 
 	pr_debug("autojoin_ssid for %s \n", essid);
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 	pr_debug("autojoin_ssid %d\n", result);
 
 	if (result) {
@@ -771,9 +774,10 @@ static int p80211wext_giwrate(netdevice_
 	int err = 0;
 
 	msg.msgcode = DIDmsg_dot11req_mibget;
+	memset(&mibitem, 0, sizeof(mibitem));
 	mibitem.did = DIDmib_p2_p2MAC_p2CurrentTxRate;
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -822,9 +826,10 @@ static int p80211wext_giwrts(netdevice_t
 	int err = 0;
 
 	msg.msgcode = DIDmsg_dot11req_mibget;
+	memset(&mibitem, 0, sizeof(mibitem));
 	mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -857,6 +862,7 @@ static int p80211wext_siwrts(netdevice_t
 	}
 
 	msg.msgcode = DIDmsg_dot11req_mibget;
+	memset(&mibitem, 0, sizeof(mibitem));
 	mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
 	if (rts->disabled)
 		mibitem.data = 2347;
@@ -864,7 +870,7 @@ static int p80211wext_siwrts(netdevice_t
 		mibitem.data = rts->value;
 
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -886,10 +892,11 @@ static int p80211wext_giwfrag(netdevice_
 	int err = 0;
 
 	msg.msgcode = DIDmsg_dot11req_mibget;
+	memset(&mibitem, 0, sizeof(mibitem));
 	mibitem.did =
 	    DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -922,6 +929,7 @@ static int p80211wext_siwfrag(netdevice_
 	}
 
 	msg.msgcode = DIDmsg_dot11req_mibset;
+	memset(&mibitem, 0, sizeof(mibitem));
 	mibitem.did =
 	    DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
 
@@ -931,7 +939,7 @@ static int p80211wext_siwfrag(netdevice_
 		mibitem.data = frag->value;
 
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -962,10 +970,11 @@ static int p80211wext_giwretry(netdevice
 	u16 shortretry, longretry, lifetime;
 
 	msg.msgcode = DIDmsg_dot11req_mibget;
+	memset(&mibitem, 0, sizeof(mibitem));
 	mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
 
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -979,7 +988,7 @@ static int p80211wext_giwretry(netdevice
 	mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
 
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -994,7 +1003,7 @@ static int p80211wext_giwretry(netdevice
 	    DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
 
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -1037,6 +1046,8 @@ static int p80211wext_siwretry(netdevice
 	int result;
 	int err = 0;
 
+	memset(&mibitem, 0, sizeof(mibitem));
+
 	if (!wlan_wext_write) {
 		err = (-EOPNOTSUPP);
 		goto exit;
@@ -1055,7 +1066,7 @@ static int p80211wext_siwretry(netdevice
 		mibitem.data = rrq->value /= 1024;
 
 		memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-		result = p80211req_dorequest(wlandev, (u8 *) & msg);
+		result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 		if (result) {
 			err = -EFAULT;
@@ -1069,7 +1080,7 @@ static int p80211wext_siwretry(netdevice
 
 			memcpy(&msg.mibattribute.data, &mibitem,
 			       sizeof(mibitem));
-			result = p80211req_dorequest(wlandev, (u8 *) & msg);
+			result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 			if (result) {
 				err = -EFAULT;
@@ -1084,7 +1095,7 @@ static int p80211wext_siwretry(netdevice
 
 			memcpy(&msg.mibattribute.data, &mibitem,
 			       sizeof(mibitem));
-			result = p80211req_dorequest(wlandev, (u8 *) & msg);
+			result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 			if (result) {
 				err = -EFAULT;
@@ -1114,6 +1125,7 @@ static int p80211wext_siwtxpow(netdevice
 	}
 
 	msg.msgcode = DIDmsg_dot11req_mibset;
+	memset(&mibitem, 0, sizeof(mibitem));
 	mibitem.did =
 	    DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
 	if (rrq->fixed == 0)
@@ -1121,7 +1133,7 @@ static int p80211wext_siwtxpow(netdevice
 	else
 		mibitem.data = rrq->value;
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -1143,11 +1155,13 @@ static int p80211wext_giwtxpow(netdevice
 	int err = 0;
 
 	msg.msgcode = DIDmsg_dot11req_mibget;
+
+	memset(&mibitem, 0, sizeof(mibitem));
 	mibitem.did =
 	    DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
 
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -1295,7 +1309,7 @@ static int p80211wext_siwscan(netdevice_
 	msg.maxchanneltime.data = 250;
 	msg.minchanneltime.data = 200;
 
-	result = p80211req_dorequest(wlandev, (u8 *) & msg);
+	result = p80211req_dorequest(wlandev, (u8 *) &msg);
 	if (result)
 		err = prism2_result2err(msg.resultcode.data);
 
@@ -1414,7 +1428,7 @@ static int p80211wext_giwscan(netdevice_
 		msg.msgcode = DIDmsg_dot11req_scan_results;
 		msg.bssindex.data = i;
 
-		result = p80211req_dorequest(wlandev, (u8 *) & msg);
+		result = p80211req_dorequest(wlandev, (u8 *) &msg);
 		if ((result != 0) ||
 		    (msg.resultcode.data != P80211ENUM_resultcode_success)) {
 			break;
@@ -1489,7 +1503,7 @@ static int p80211wext_set_encodeext(stru
 		memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len);
 
 		memset(&msg, 0, sizeof(msg));
-		pstr = (p80211item_pstr32_t *) & msg.mibattribute.data;
+		pstr = (p80211item_pstr32_t *) &msg.mibattribute.data;
 		memcpy(pstr->data.data, ext->key, ext->key_len);
 		pstr->data.len = ext->key_len;
 		switch (idx) {
@@ -1513,7 +1527,7 @@ static int p80211wext_set_encodeext(stru
 			break;
 		}
 		msg.msgcode = DIDmsg_dot11req_mibset;
-		result = p80211req_dorequest(wlandev, (u8 *) & msg);
+		result = p80211req_dorequest(wlandev, (u8 *) &msg);
 		pr_debug("result (%d)\n", result);
 	}
 	return result;
@@ -1729,15 +1743,11 @@ static iw_handler p80211wext_handlers[]
 
 struct iw_handler_def p80211wext_handler_def = {
 	.num_standard = ARRAY_SIZE(p80211wext_handlers),
-	.num_private = 0,
-	.num_private_args = 0,
 	.standard = p80211wext_handlers,
-	.private = NULL,
-	.private_args = NULL,
 	.get_wireless_stats = p80211wext_get_wireless_stats
 };
 
-int p80211wext_event_associated(wlandevice_t * wlandev, int assoc)
+int p80211wext_event_associated(wlandevice_t *wlandev, int assoc)
 {
 	union iwreq_data data;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/prism2fw.c linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/prism2fw.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/prism2fw.c	2013-05-03 12:10:50.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/prism2fw.c	2013-05-03 09:50:21.000000000 -0400
@@ -48,11 +48,13 @@
 /*================================================================*/
 /* System Includes */
 #include <linux/ihex.h>
+#include <linux/slab.h>
 
 /*================================================================*/
 /* Local Constants */
 
 #define PRISM2_USB_FWFILE	"/*(DEBLOBBED)*/"
+/*(DEBLOBBED)*/
 
 #define S3DATA_MAX		5000
 #define S3PLUG_MAX		200
@@ -108,9 +110,9 @@ typedef struct pda {
 } pda_t;
 
 typedef struct imgchunk {
-	u32 addr;		/* start address */
-	u32 len;		/* in bytes */
-	u16 crc;		/* CRC value (if it falls at a chunk boundary) */
+	u32 addr;	/* start address */
+	u32 len;	/* in bytes */
+	u16 crc;	/* CRC value (if it falls at a chunk boundary) */
 	u8 *data;
 } imgchunk_t;
 
@@ -204,7 +206,7 @@ int prism2_fwtry(struct usb_device *udev
 		return 1;
 	}
 
-	printk(KERN_INFO "prism2_usb: %s will be processed, size %d\n",
+	printk(KERN_INFO "prism2_usb: %s will be processed, size %zu\n",
 	       PRISM2_USB_FWFILE, fw_entry->size);
 	prism2_fwapply((const struct ihex_binrec *)fw_entry->data, wlandev);
 
@@ -264,7 +266,7 @@ int prism2_fwapply(const struct ihex_bin
 	/* Build the PDA we're going to use. */
 	if (read_cardpda(&pda, wlandev)) {
 		printk(KERN_ERR "load_cardpda failed, exiting.\n");
-		return (1);
+		return 1;
 	}
 
 	/* read the card's PRI-SUP */
@@ -286,9 +288,8 @@ int prism2_fwapply(const struct ihex_bin
 
 	/* DIDmsg_dot11req_mibget */
 	prism2mgmt_mibset_mibget(wlandev, &getmsg);
-	if (getmsg.resultcode.data != P80211ENUM_resultcode_success) {
+	if (getmsg.resultcode.data != P80211ENUM_resultcode_success)
 		printk(KERN_ERR "Couldn't fetch PRI-SUP info\n");
-	}
 
 	/* Already in host order */
 	priid.role = *data++;
@@ -301,19 +302,19 @@ int prism2_fwapply(const struct ihex_bin
 	result = read_fwfile(rfptr);
 	if (result) {
 		printk(KERN_ERR "Failed to read the data exiting.\n");
-		return (1);
+		return 1;
 	}
 
 	result = validate_identity();
 
 	if (result) {
 		printk(KERN_ERR "Incompatible firmware image.\n");
-		return (1);
+		return 1;
 	}
 
 	if (startaddr == 0x00000000) {
 		printk(KERN_ERR "Can't RAM download a Flash image!\n");
-		return (1);
+		return 1;
 	}
 
 	/* Make the image chunks */
@@ -323,20 +324,20 @@ int prism2_fwapply(const struct ihex_bin
 	result = plugimage(fchunk, nfchunks, s3plug, ns3plug, &pda);
 	if (result) {
 		printk(KERN_ERR "Failed to plug data.\n");
-		return (1);
+		return 1;
 	}
 
 	/* Insert any CRCs */
 	if (crcimage(fchunk, nfchunks, s3crc, ns3crc)) {
 		printk(KERN_ERR "Failed to insert all CRCs\n");
-		return (1);
+		return 1;
 	}
 
 	/* Write the image */
 	result = writeimage(wlandev, fchunk, nfchunks);
 	if (result) {
 		printk(KERN_ERR "Failed to ramwrite image data.\n");
-		return (1);
+		return 1;
 	}
 
 	/* clear any allocated memory */
@@ -434,9 +435,8 @@ void free_chunks(imgchunk_t *fchunk, uns
 {
 	int i;
 	for (i = 0; i < *nfchunks; i++) {
-		if (fchunk[i].data != NULL) {
+		if (fchunk[i].data != NULL)
 			kfree(fchunk[i].data);
-		}
 	}
 	*nfchunks = 0;
 	memset(fchunk, 0, sizeof(*fchunk));
@@ -531,7 +531,7 @@ int mkimage(imgchunk_t *clist, unsigned
 		if (clist[i].data == NULL) {
 			printk(KERN_ERR
 			       "failed to allocate image space, exitting.\n");
-			return (1);
+			return 1;
 		}
 		memset(clist[i].data, 0, clist[i].len);
 		pr_debug("chunk[%d]: addr=0x%06x len=%d\n",
@@ -545,15 +545,14 @@ int mkimage(imgchunk_t *clist, unsigned
 		for (j = 0; j < *ccnt; j++) {
 			cstart = clist[j].addr;
 			cend = cstart + clist[j].len - 1;
-			if (s3start >= cstart && s3end <= cend) {
+			if (s3start >= cstart && s3end <= cend)
 				break;
-			}
 		}
 		if (((unsigned int)j) >= (*ccnt)) {
 			printk(KERN_ERR
 			       "s3rec(a=0x%06x,l=%d), no chunk match, exiting.\n",
 			       s3start, s3data[i].len);
-			return (1);
+			return 1;
 		}
 		coffset = s3start - cstart;
 		memcpy(clist[j].data + coffset, s3data[i].data, s3data[i].len);
@@ -586,7 +585,7 @@ int mkpdrlist(pda_t *pda)
 	curroff = 0;
 	while (curroff < (HFA384x_PDA_LEN_MAX / 2) &&
 	       le16_to_cpu(pda16[curroff + 1]) != HFA384x_PDR_END_OF_PDA) {
-		pda->rec[pda->nrec] = (hfa384x_pdrec_t *) & (pda16[curroff]);
+		pda->rec[pda->nrec] = (hfa384x_pdrec_t *) &(pda16[curroff]);
 
 		if (le16_to_cpu(pda->rec[pda->nrec]->code) == HFA384x_PDR_NICID) {
 			memcpy(&nicid, &pda->rec[pda->nrec]->data.nicid,
@@ -623,10 +622,10 @@ int mkpdrlist(pda_t *pda)
 		printk(KERN_ERR
 		       "no end record found or invalid lengths in "
 		       "PDR data, exiting. %x %d\n", curroff, pda->nrec);
-		return (1);
+		return 1;
 	}
 	if (le16_to_cpu(pda16[curroff + 1]) == HFA384x_PDR_END_OF_PDA) {
-		pda->rec[pda->nrec] = (hfa384x_pdrec_t *) & (pda16[curroff]);
+		pda->rec[pda->nrec] = (hfa384x_pdrec_t *) &(pda16[curroff]);
 		(pda->nrec)++;
 	}
 	return result;
@@ -869,7 +868,7 @@ int read_fwfile(const struct ihex_binrec
 		ptr16 = (u16 *) record->data;
 
 		/* parse what was an S3 srec and put it in the right array */
-		switch(addr) {
+		switch (addr) {
 		case S3ADDR_START:
 			startaddr = *ptr32;
 			pr_debug("  S7 start addr, record=%d "
@@ -890,7 +889,7 @@ int read_fwfile(const struct ihex_binrec
 				      s3plug[ns3plug].len);
 
 			ns3plug++;
-			if ( ns3plug == S3PLUG_MAX ) {
+			if (ns3plug == S3PLUG_MAX) {
 				printk(KERN_ERR "S3 plugrec limit reached - aborting\n");
 				return 1;
 			}
@@ -907,7 +906,7 @@ int read_fwfile(const struct ihex_binrec
 				      s3crc[ns3crc].len,
 				      s3crc[ns3crc].dowrite);
 			ns3crc++;
-			if ( ns3crc == S3CRC_MAX ) {
+			if (ns3crc == S3CRC_MAX) {
 				printk(KERN_ERR "S3 crcrec limit reached - aborting\n");
 				return 1;
 			}
@@ -921,12 +920,12 @@ int read_fwfile(const struct ihex_binrec
 				      rcnt,
 				      s3info[ns3info].len,
 				      s3info[ns3info].type);
-			if ( ((s3info[ns3info].len - 1) * sizeof(u16)) > sizeof(s3info[ns3info].info) ) {
+			if (((s3info[ns3info].len - 1) * sizeof(u16)) > sizeof(s3info[ns3info].info)) {
 				printk(KERN_ERR " S3 inforec length too long - aborting\n");
 				return 1;
 			}
 
-			tmpinfo = (u16*)&(s3info[ns3info].info.version);
+			tmpinfo = (u16 *)&(s3info[ns3info].info.version);
 			pr_debug("            info=");
 			for (i = 0; i < s3info[ns3info].len - 1; i++) {
 				tmpinfo[i] = *(ptr16 + 2 + i);
@@ -935,7 +934,7 @@ int read_fwfile(const struct ihex_binrec
 			pr_debug("\n");
 
 			ns3info++;
-			if ( ns3info == S3INFO_MAX ) {
+			if (ns3info == S3INFO_MAX) {
 				printk(KERN_ERR "S3 inforec limit reached - aborting\n");
 				return 1;
 			}
@@ -945,7 +944,7 @@ int read_fwfile(const struct ihex_binrec
 			s3data[ns3data].len = len;
 			s3data[ns3data].data = (uint8_t *) record->data;
 			ns3data++;
-			if ( ns3data == S3DATA_MAX ) {
+			if (ns3data == S3DATA_MAX) {
 				printk(KERN_ERR "S3 datarec limit reached - aborting\n");
 				return 1;
 			}
@@ -1023,7 +1022,7 @@ int writeimage(wlandevice_t *wlandev, im
 	rstatemsg.enable.data = P80211ENUM_truth_true;
 	rstatemsg.exeaddr.data = startaddr;
 
-	msgp = (p80211msg_t *) & rstatemsg;
+	msgp = (p80211msg_t *) &rstatemsg;
 	result = prism2mgmt_ramdl_state(wlandev, msgp);
 	if (result) {
 		printk(KERN_ERR
@@ -1063,7 +1062,7 @@ int writeimage(wlandevice_t *wlandev, im
 			    ("Sending xxxdl_write message addr=%06x len=%d.\n",
 			     currdaddr, currlen);
 
-			msgp = (p80211msg_t *) & rwritemsg;
+			msgp = (p80211msg_t *) &rwritemsg;
 			result = prism2mgmt_ramdl_write(wlandev, msgp);
 
 			/* Check the results */
@@ -1090,7 +1089,7 @@ int writeimage(wlandevice_t *wlandev, im
 	rstatemsg.enable.data = P80211ENUM_truth_false;
 	rstatemsg.exeaddr.data = 0;
 
-	msgp = (p80211msg_t *) & rstatemsg;
+	msgp = (p80211msg_t *) &rstatemsg;
 	result = prism2mgmt_ramdl_state(wlandev, msgp);
 	if (result) {
 		printk(KERN_ERR
@@ -1161,7 +1160,7 @@ int validate_identity(void)
 			/* SEC compat range */
 			if ((s3info[i].info.compat.role == 1) &&
 			    (s3info[i].info.compat.id == 4)) {
-
+				/* FIXME: isn't something missing here? */
 			}
 
 			break;
@@ -1196,8 +1195,9 @@ int validate_identity(void)
 			pr_debug("Unknown inforec type %d\n", s3info[i].type);
 		}
 	}
-	// walk through
+	/* walk through */
 
-	if (trump && (result != 2)) result = 0;
+	if (trump && (result != 2))
+		result = 0;
 	return result;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/prism2mgmt.c linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/prism2mgmt.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/prism2mgmt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/prism2mgmt.c	2010-05-16 17:17:36.000000000 -0400
@@ -63,11 +63,10 @@
 #include <linux/wait.h>
 #include <linux/sched.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/wireless.h>
 #include <linux/netdevice.h>
 #include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/byteorder.h>
 #include <linux/random.h>
 #include <linux/usb.h>
@@ -541,7 +540,7 @@ int prism2mgmt_start(wlandevice_t *wland
 	/*** STATION ***/
 	/* Set the REQUIRED config items */
 	/* SSID */
-	pstr = (p80211pstrd_t *) & (msg->ssid.data);
+	pstr = (p80211pstrd_t *) &(msg->ssid.data);
 	prism2mgmt_pstr2bytestr(p2bytestr, pstr);
 	result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
 					bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
@@ -1034,7 +1033,7 @@ int prism2mgmt_autojoin(wlandevice_t *wl
 
 	/* Set the ssid */
 	memset(bytebuf, 0, 256);
-	pstr = (p80211pstrd_t *) & (msg->ssid.data);
+	pstr = (p80211pstrd_t *) &(msg->ssid.data);
 	prism2mgmt_pstr2bytestr(p2bytestr, pstr);
 	result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
 					bytebuf,
@@ -1123,8 +1122,8 @@ int prism2mgmt_wlansniff(wlandevice_t *w
 		if (hw->presniff_port_type != 0) {
 			word = hw->presniff_port_type;
 			result = hfa384x_drvr_setconfig16(hw,
-							  HFA384x_RID_CNFPORTTYPE,
-							  word);
+						  HFA384x_RID_CNFPORTTYPE,
+						  word);
 			if (result) {
 				pr_debug
 				    ("failed to restore porttype, result=%d\n",
@@ -1156,10 +1155,8 @@ int prism2mgmt_wlansniff(wlandevice_t *w
 			if (wlandev->netdev->type == ARPHRD_ETHER) {
 				/* Save macport 0 state */
 				result = hfa384x_drvr_getconfig16(hw,
-								  HFA384x_RID_CNFPORTTYPE,
-								  &
-								  (hw->
-								   presniff_port_type));
+						  HFA384x_RID_CNFPORTTYPE,
+						  &(hw->presniff_port_type));
 				if (result) {
 					pr_debug
 					    ("failed to read porttype, result=%d\n",
@@ -1168,10 +1165,8 @@ int prism2mgmt_wlansniff(wlandevice_t *w
 				}
 				/* Save the wepflags state */
 				result = hfa384x_drvr_getconfig16(hw,
-								  HFA384x_RID_CNFWEPFLAGS,
-								  &
-								  (hw->
-								   presniff_wepflags));
+						  HFA384x_RID_CNFWEPFLAGS,
+						  &(hw->presniff_wepflags));
 				if (result) {
 					pr_debug
 					    ("failed to read wepflags, result=%d\n",
@@ -1218,8 +1213,8 @@ int prism2mgmt_wlansniff(wlandevice_t *w
 			/* Set the port type to pIbss */
 			word = HFA384x_PORTTYPE_PSUEDOIBSS;
 			result = hfa384x_drvr_setconfig16(hw,
-							  HFA384x_RID_CNFPORTTYPE,
-							  word);
+						  HFA384x_RID_CNFPORTTYPE,
+						  word);
 			if (result) {
 				pr_debug
 				    ("failed to set porttype %d, result=%d\n",
@@ -1235,8 +1230,8 @@ int prism2mgmt_wlansniff(wlandevice_t *w
 				    HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
 				result =
 				    hfa384x_drvr_setconfig16(hw,
-							     HFA384x_RID_CNFWEPFLAGS,
-							     word);
+						     HFA384x_RID_CNFWEPFLAGS,
+						     word);
 			}
 
 			if (result) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/prism2mgmt.h linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/prism2mgmt.h
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/prism2mgmt.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/prism2mgmt.h	2010-05-16 17:17:36.000000000 -0400
@@ -63,43 +63,43 @@
 extern int prism2_reset_holdtime;
 extern int prism2_reset_settletime;
 
-u32 prism2sta_ifstate(wlandevice_t * wlandev, u32 ifstate);
+u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate);
 
-void prism2sta_ev_info(wlandevice_t * wlandev, hfa384x_InfFrame_t * inf);
-void prism2sta_ev_txexc(wlandevice_t * wlandev, u16 status);
-void prism2sta_ev_tx(wlandevice_t * wlandev, u16 status);
-void prism2sta_ev_rx(wlandevice_t * wlandev, struct sk_buff *skb);
-void prism2sta_ev_alloc(wlandevice_t * wlandev);
+void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status);
+void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status);
+void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+void prism2sta_ev_alloc(wlandevice_t *wlandev);
 
-int prism2mgmt_mibset_mibget(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_scan(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_scan_results(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_start(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_wlansniff(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_readpda(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_ramdl_state(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_ramdl_write(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_flashdl_state(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_flashdl_write(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_autojoin(wlandevice_t * wlandev, void *msgp);
+int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_start(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp);
 
 /*---------------------------------------------------------------
 * conversion functions going between wlan message data types and
 * Prism2 data types
 ---------------------------------------------------------------*/
 /* byte area conversion functions*/
-void prism2mgmt_pstr2bytearea(u8 * bytearea, p80211pstrd_t * pstr);
-void prism2mgmt_bytearea2pstr(u8 * bytearea, p80211pstrd_t * pstr, int len);
+void prism2mgmt_pstr2bytearea(u8 *bytearea, p80211pstrd_t *pstr);
+void prism2mgmt_bytearea2pstr(u8 *bytearea, p80211pstrd_t *pstr, int len);
 
 /* byte string conversion functions*/
-void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t * bytestr, p80211pstrd_t * pstr);
-void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t * bytestr, p80211pstrd_t * pstr);
+void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
+void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
 
 /* functions to convert Group Addresses */
-void prism2mgmt_get_grpaddr(u32 did, p80211pstrd_t * pstr, hfa384x_t * priv);
+void prism2mgmt_get_grpaddr(u32 did, p80211pstrd_t *pstr, hfa384x_t *priv);
 int prism2mgmt_set_grpaddr(u32 did,
-			   u8 * prism2buf, p80211pstrd_t * pstr,
-			   hfa384x_t * priv);
+			   u8 *prism2buf, p80211pstrd_t *pstr,
+			   hfa384x_t *priv);
 int prism2mgmt_get_grpaddr_index(u32 did);
 
 void prism2sta_processing_defer(struct work_struct *data);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/prism2mib.c linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/prism2mib.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/prism2mib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/prism2mib.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,7 +54,6 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/wireless.h>
 #include <linux/netdevice.h>
 #include <linux/io.h>
@@ -114,7 +113,7 @@ static int prism2mib_flag(mibrec_t *mib,
 
 static int prism2mib_wepdefaultkey(mibrec_t *mib,
 				   int isget,
-				   wlandevice_t * wlandev,
+				   wlandevice_t *wlandev,
 				   hfa384x_t *hw,
 				   p80211msg_dot11req_mibset_t *msg,
 				   void *data);
@@ -726,7 +725,7 @@ static int prism2mib_priv(mibrec_t *mib,
 			if (isget) {
 				hfa384x_drvr_getconfig(hw,
 						       HFA384x_RID_CNFWPADATA,
-						       (u8 *) & wpa,
+						       (u8 *) &wpa,
 						       sizeof(wpa));
 				pstr->len = le16_to_cpu(wpa.datalen);
 				memcpy(pstr->data, wpa.data, pstr->len);
@@ -736,9 +735,9 @@ static int prism2mib_priv(mibrec_t *mib,
 
 				result =
 				    hfa384x_drvr_setconfig(hw,
-							   HFA384x_RID_CNFWPADATA,
-							   (u8 *) & wpa,
-							   sizeof(wpa));
+						   HFA384x_RID_CNFWPADATA,
+						   (u8 *) &wpa,
+						   sizeof(wpa));
 			}
 			break;
 		}
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/prism2sta.c linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/prism2sta.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/prism2sta.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/prism2sta.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,7 +64,7 @@
 #include <linux/byteorder/generic.h>
 #include <linux/ctype.h>
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <asm/byteorder.h>
 #include <linux/if_arp.h>
@@ -1023,13 +1023,13 @@ static void prism2sta_inf_tallies(wlande
 
 	cnt = sizeof(hfa384x_CommTallies32_t) / sizeof(u32);
 	if (inf->framelen > 22) {
-		dst = (u32 *) & hw->tallies;
-		src32 = (u32 *) & inf->info.commtallies32;
+		dst = (u32 *) &hw->tallies;
+		src32 = (u32 *) &inf->info.commtallies32;
 		for (i = 0; i < cnt; i++, dst++, src32++)
 			*dst += le32_to_cpu(*src32);
 	} else {
-		dst = (u32 *) & hw->tallies;
-		src16 = (u16 *) & inf->info.commtallies16;
+		dst = (u32 *) &hw->tallies;
+		src16 = (u16 *) &inf->info.commtallies16;
 		for (i = 0; i < cnt; i++, dst++, src16++)
 			*dst += le16_to_cpu(*src16);
 	}
@@ -1280,7 +1280,7 @@ void prism2sta_processing_defer(struct w
 				     HFA384x_RID_CURRENTSSID, result);
 				goto failed;
 			}
-			prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) & ssid,
+			prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid,
 						(p80211pstrd_t *) &
 						wlandev->ssid);
 
@@ -1368,8 +1368,8 @@ void prism2sta_processing_defer(struct w
 				 HFA384x_RID_CURRENTSSID, result);
 			goto failed;
 		}
-		prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) & ssid,
-					(p80211pstrd_t *) & wlandev->ssid);
+		prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid,
+					(p80211pstrd_t *) &wlandev->ssid);
 
 		hw->link_status = HFA384x_LINK_CONNECTED;
 		netif_carrier_on(wlandev->netdev);
@@ -2028,8 +2028,8 @@ void prism2sta_commsqual_defer(struct wo
 			 HFA384x_RID_CURRENTSSID, result);
 		goto done;
 	}
-	prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) & ssid,
-				(p80211pstrd_t *) & wlandev->ssid);
+	prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid,
+				(p80211pstrd_t *) &wlandev->ssid);
 
 	/* Reschedule timer */
 	mod_timer(&hw->commsqual_timer, jiffies + HZ);
diff -druNp linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/prism2usb.c linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/prism2usb.c
--- linux-libre-2.6.33-gnu1/drivers/staging/wlan-ng/prism2usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/staging/wlan-ng/prism2usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,8 +24,9 @@ static struct usb_device_id usb_prism_tb
 	 (0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter")},
 	{PRISM_USB_DEVICE
 	 (0x067c, 0x1022, "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter")},
-	{PRISM_USB_DEVICE(0x049f, 0x0033,
-			  "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x049f, 0x0033,
+	 "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")},
 	{PRISM_USB_DEVICE
 	 (0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter")},
 	{PRISM_USB_DEVICE
@@ -55,7 +56,6 @@ static struct usb_device_id usb_prism_tb
 	 (0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter")},
 	{PRISM_USB_DEVICE(0x0846, 0x4110, "NetGear MA111")},
 	{PRISM_USB_DEVICE(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter")},
-/*      {PRISM_USB_DEVICE(0x0ace, 0x1201, "ZyDAS ZD1201 Wireless USB Adapter")}, */
 	{PRISM_USB_DEVICE(0x2821, 0x3300, "ASUS-WL140 Wireless USB Adapter")},
 	{PRISM_USB_DEVICE(0x2001, 0x3700, "DWL-122 Wireless USB Adapter")},
 	{PRISM_USB_DEVICE
diff -druNp linux-libre-2.6.33-gnu1/drivers/tc/tc.c linux-libre-2.6.34-gnu1/drivers/tc/tc.c
--- linux-libre-2.6.33-gnu1/drivers/tc/tc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/tc/tc.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/tc.h>
 #include <linux/types.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/thermal/thermal_sys.c linux-libre-2.6.34-gnu1/drivers/thermal/thermal_sys.c
--- linux-libre-2.6.33-gnu1/drivers/thermal/thermal_sys.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/thermal/thermal_sys.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/kdev_t.h>
 #include <linux/idr.h>
 #include <linux/thermal.h>
@@ -505,6 +506,7 @@ thermal_add_hwmon_sysfs(struct thermal_z
 	tz->temp_input.attr.attr.name = tz->temp_input.name;
 	tz->temp_input.attr.attr.mode = 0444;
 	tz->temp_input.attr.show = temp_input_show;
+	sysfs_attr_init(&tz->temp_input.attr.attr);
 	result = device_create_file(hwmon->device, &tz->temp_input.attr);
 	if (result)
 		goto unregister_hwmon_device;
@@ -517,6 +519,7 @@ thermal_add_hwmon_sysfs(struct thermal_z
 			tz->temp_crit.attr.attr.name = tz->temp_crit.name;
 			tz->temp_crit.attr.attr.mode = 0444;
 			tz->temp_crit.attr.show = temp_crit_show;
+			sysfs_attr_init(&tz->temp_crit.attr.attr);
 			result = device_create_file(hwmon->device,
 						    &tz->temp_crit.attr);
 			if (result)
@@ -725,6 +728,7 @@ int thermal_zone_bind_cooling_device(str
 		goto release_idr;
 
 	sprintf(dev->attr_name, "cdev%d_trip_point", dev->id);
+	sysfs_attr_init(&dev->attr.attr);
 	dev->attr.attr.name = dev->attr_name;
 	dev->attr.attr.mode = 0444;
 	dev->attr.show = thermal_cooling_device_trip_point_show;
diff -druNp linux-libre-2.6.33-gnu1/drivers/uio/Kconfig linux-libre-2.6.34-gnu1/drivers/uio/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/uio/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uio/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -44,17 +44,6 @@ config UIO_PDRV_GENIRQ
 
 	  If you don't know what to do here, say N.
 
-config UIO_SMX
-	tristate "SMX cryptengine UIO interface"
-	help
-	  Userspace IO interface to the Cryptography engine found on the
-	  Nias Digital SMX boards.  These will be available from Q4 2008
-	  from http://www.niasdigital.com.  The userspace part of this
-	  driver will be released under the GPL at the same time as the
-	  hardware and will be able to be downloaded from the same site.
-
-	  If you compile this as a module, it will be called uio_smx.
-
 config UIO_AEC
 	tristate "AEC video timestamp device"
 	depends on PCI
@@ -74,6 +63,7 @@ config UIO_AEC
 
 config UIO_SERCOS3
 	tristate "Automata Sercos III PCI card driver"
+	depends on PCI
 	help
 	  Userspace I/O interface for the Sercos III PCI card from
 	  Automata GmbH. The userspace part of this driver will be
@@ -87,11 +77,21 @@ config UIO_SERCOS3
 config UIO_PCI_GENERIC
 	tristate "Generic driver for PCI 2.3 and PCI Express cards"
 	depends on PCI
-	default n
 	help
 	  Generic driver that you can bind, dynamically, to any
 	  PCI 2.3 compliant and PCI Express card. It is useful,
 	  primarily, for virtualization scenarios.
 	  If you compile this as a module, it will be called uio_pci_generic.
 
+config UIO_NETX
+	tristate "Hilscher NetX Card driver"
+	depends on PCI
+	help
+	  Driver for Hilscher NetX based fieldbus cards (cifX, comX).
+	  This driver requires a userspace component that comes with the card
+	  or is available from Hilscher (http://www.hilscher.com).
+
+	  To compile this driver as a module, choose M here; the module
+	  will be called uio_netx.
+
 endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/uio/Makefile linux-libre-2.6.34-gnu1/drivers/uio/Makefile
--- linux-libre-2.6.33-gnu1/drivers/uio/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uio/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@ obj-$(CONFIG_UIO)	+= uio.o
 obj-$(CONFIG_UIO_CIF)	+= uio_cif.o
 obj-$(CONFIG_UIO_PDRV)	+= uio_pdrv.o
 obj-$(CONFIG_UIO_PDRV_GENIRQ)	+= uio_pdrv_genirq.o
-obj-$(CONFIG_UIO_SMX)	+= uio_smx.o
 obj-$(CONFIG_UIO_AEC)	+= uio_aec.o
 obj-$(CONFIG_UIO_SERCOS3)	+= uio_sercos3.o
 obj-$(CONFIG_UIO_PCI_GENERIC)	+= uio_pci_generic.o
+obj-$(CONFIG_UIO_NETX)	+= uio_netx.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/uio/uio_aec.c linux-libre-2.6.34-gnu1/drivers/uio/uio_aec.c
--- linux-libre-2.6.33-gnu1/drivers/uio/uio_aec.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uio/uio_aec.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/io.h>
 #include <linux/uaccess.h>
 #include <linux/uio_driver.h>
+#include <linux/slab.h>
 
 #define PCI_VENDOR_ID_AEC 0xaecb
 #define PCI_DEVICE_ID_AEC_VITCLTC 0x6250
diff -druNp linux-libre-2.6.33-gnu1/drivers/uio/uio.c linux-libre-2.6.34-gnu1/drivers/uio/uio.c
--- linux-libre-2.6.33-gnu1/drivers/uio/uio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uio/uio.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/idr.h>
 #include <linux/sched.h>
@@ -129,7 +130,7 @@ static ssize_t map_type_show(struct kobj
 	return entry->show(mem, buf);
 }
 
-static struct sysfs_ops map_sysfs_ops = {
+static const struct sysfs_ops map_sysfs_ops = {
 	.show = map_type_show,
 };
 
@@ -217,7 +218,7 @@ static ssize_t portio_type_show(struct k
 	return entry->show(port, buf);
 }
 
-static struct sysfs_ops portio_sysfs_ops = {
+static const struct sysfs_ops portio_sysfs_ops = {
 	.show = portio_type_show,
 };
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uio/uio_cif.c linux-libre-2.6.34-gnu1/drivers/uio/uio_cif.c
--- linux-libre-2.6.33-gnu1/drivers/uio/uio_cif.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uio/uio_cif.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/uio_driver.h>
 
 #include <asm/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/uio/uio_netx.c linux-libre-2.6.34-gnu1/drivers/uio/uio_netx.c
--- linux-libre-2.6.33-gnu1/drivers/uio/uio_netx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uio/uio_netx.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,173 @@
+/*
+ * UIO driver for Hilscher NetX based fieldbus cards (cifX, comX).
+ * See http://www.hilscher.com for details.
+ *
+ * (C) 2007 Hans J. Koch <hjk@linutronix.de>
+ * (C) 2008 Manuel Traut <manut@linutronix.de>
+ *
+ * Licensed under GPL version 2 only.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/uio_driver.h>
+
+#define PCI_VENDOR_ID_HILSCHER		0x15CF
+#define PCI_DEVICE_ID_HILSCHER_NETX	0x0000
+#define PCI_SUBDEVICE_ID_NXSB_PCA	0x3235
+#define PCI_SUBDEVICE_ID_NXPCA		0x3335
+
+#define DPM_HOST_INT_EN0	0xfff0
+#define DPM_HOST_INT_STAT0	0xffe0
+
+#define DPM_HOST_INT_MASK	0xe600ffff
+#define DPM_HOST_INT_GLOBAL_EN	0x80000000
+
+static irqreturn_t netx_handler(int irq, struct uio_info *dev_info)
+{
+	void __iomem *int_enable_reg = dev_info->mem[0].internal_addr
+					+ DPM_HOST_INT_EN0;
+	void __iomem *int_status_reg = dev_info->mem[0].internal_addr
+					+ DPM_HOST_INT_STAT0;
+
+	/* Is one of our interrupts enabled and active ? */
+	if (!(ioread32(int_enable_reg) & ioread32(int_status_reg)
+		& DPM_HOST_INT_MASK))
+		return IRQ_NONE;
+
+	/* Disable interrupt */
+	iowrite32(ioread32(int_enable_reg) & ~DPM_HOST_INT_GLOBAL_EN,
+		int_enable_reg);
+	return IRQ_HANDLED;
+}
+
+static int __devinit netx_pci_probe(struct pci_dev *dev,
+					const struct pci_device_id *id)
+{
+	struct uio_info *info;
+	int bar;
+
+	info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	if (pci_enable_device(dev))
+		goto out_free;
+
+	if (pci_request_regions(dev, "netx"))
+		goto out_disable;
+
+	switch (id->device) {
+	case PCI_DEVICE_ID_HILSCHER_NETX:
+		bar = 0;
+		info->name = "netx";
+		break;
+	default:
+		bar = 2;
+		info->name = "netx_plx";
+	}
+
+	/* BAR0 or 2 points to the card's dual port memory */
+	info->mem[0].addr = pci_resource_start(dev, bar);
+	if (!info->mem[0].addr)
+		goto out_release;
+	info->mem[0].internal_addr = ioremap(pci_resource_start(dev, bar),
+						pci_resource_len(dev, bar));
+
+	if (!info->mem[0].internal_addr)
+			goto out_release;
+
+	info->mem[0].size = pci_resource_len(dev, bar);
+	info->mem[0].memtype = UIO_MEM_PHYS;
+	info->irq = dev->irq;
+	info->irq_flags = IRQF_SHARED;
+	info->handler = netx_handler;
+	info->version = "0.0.1";
+
+	/* Make sure all interrupts are disabled */
+	iowrite32(0, info->mem[0].internal_addr + DPM_HOST_INT_EN0);
+
+	if (uio_register_device(&dev->dev, info))
+		goto out_unmap;
+
+	pci_set_drvdata(dev, info);
+	dev_info(&dev->dev, "Found %s card, registered UIO device.\n",
+				info->name);
+
+	return 0;
+
+out_unmap:
+	iounmap(info->mem[0].internal_addr);
+out_release:
+	pci_release_regions(dev);
+out_disable:
+	pci_disable_device(dev);
+out_free:
+	kfree(info);
+	return -ENODEV;
+}
+
+static void netx_pci_remove(struct pci_dev *dev)
+{
+	struct uio_info *info = pci_get_drvdata(dev);
+
+	/* Disable all interrupts */
+	iowrite32(0, info->mem[0].internal_addr + DPM_HOST_INT_EN0);
+	uio_unregister_device(info);
+	pci_release_regions(dev);
+	pci_disable_device(dev);
+	pci_set_drvdata(dev, NULL);
+	iounmap(info->mem[0].internal_addr);
+
+	kfree(info);
+}
+
+static struct pci_device_id netx_pci_ids[] = {
+	{
+		.vendor =	PCI_VENDOR_ID_HILSCHER,
+		.device =	PCI_DEVICE_ID_HILSCHER_NETX,
+		.subvendor =	0,
+		.subdevice =	0,
+	},
+	{
+		.vendor =	PCI_VENDOR_ID_PLX,
+		.device =	PCI_DEVICE_ID_PLX_9030,
+		.subvendor =	PCI_VENDOR_ID_PLX,
+		.subdevice =	PCI_SUBDEVICE_ID_NXSB_PCA,
+	},
+	{
+		.vendor =	PCI_VENDOR_ID_PLX,
+		.device =	PCI_DEVICE_ID_PLX_9030,
+		.subvendor =	PCI_VENDOR_ID_PLX,
+		.subdevice =	PCI_SUBDEVICE_ID_NXPCA,
+	},
+	{ 0, }
+};
+
+static struct pci_driver netx_pci_driver = {
+	.name = "netx",
+	.id_table = netx_pci_ids,
+	.probe = netx_pci_probe,
+	.remove = netx_pci_remove,
+};
+
+static int __init netx_init_module(void)
+{
+	return pci_register_driver(&netx_pci_driver);
+}
+
+static void __exit netx_exit_module(void)
+{
+	pci_unregister_driver(&netx_pci_driver);
+}
+
+module_init(netx_init_module);
+module_exit(netx_exit_module);
+
+MODULE_DEVICE_TABLE(pci, netx_pci_ids);
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Hans J. Koch, Manuel Traut");
diff -druNp linux-libre-2.6.33-gnu1/drivers/uio/uio_pci_generic.c linux-libre-2.6.34-gnu1/drivers/uio/uio_pci_generic.c
--- linux-libre-2.6.33-gnu1/drivers/uio/uio_pci_generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uio/uio_pci_generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/uio_driver.h>
 #include <linux/spinlock.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uio/uio_pdrv.c linux-libre-2.6.34-gnu1/drivers/uio/uio_pdrv.c
--- linux-libre-2.6.33-gnu1/drivers/uio/uio_pdrv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uio/uio_pdrv.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/platform_device.h>
 #include <linux/uio_driver.h>
 #include <linux/stringify.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "uio_pdrv"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uio/uio_pdrv_genirq.c linux-libre-2.6.34-gnu1/drivers/uio/uio_pdrv_genirq.c
--- linux-libre-2.6.33-gnu1/drivers/uio/uio_pdrv_genirq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uio/uio_pdrv_genirq.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/stringify.h>
 #include <linux/pm_runtime.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "uio_pdrv_genirq"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uio/uio_sercos3.c linux-libre-2.6.34-gnu1/drivers/uio/uio_sercos3.c
--- linux-libre-2.6.33-gnu1/drivers/uio/uio_sercos3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uio/uio_sercos3.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/pci.h>
 #include <linux/uio_driver.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 /* ID's for SERCOS III PCI card (PLX 9030) */
 #define SERCOS_SUB_VENDOR_ID  0x1971
diff -druNp linux-libre-2.6.33-gnu1/drivers/uio/uio_smx.c linux-libre-2.6.34-gnu1/drivers/uio/uio_smx.c
--- linux-libre-2.6.33-gnu1/drivers/uio/uio_smx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uio/uio_smx.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,140 +0,0 @@
-/*
- * UIO SMX Cryptengine driver.
- *
- * (C) 2008 Nias Digital P/L <bn@niasdigital.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/device.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/uio_driver.h>
-#include <linux/io.h>
-
-#define DRV_NAME "smx-ce"
-#define DRV_VERSION "0.03"
-
-#define SMX_CSR  0x00000000
-#define SMX_EnD  0x00000001
-#define SMX_RUN  0x00000002
-#define SMX_DRDY 0x00000004
-#define SMX_ERR  0x00000008
-
-static irqreturn_t smx_handler(int irq, struct uio_info *dev_info)
-{
-	void __iomem *csr = dev_info->mem[0].internal_addr + SMX_CSR;
-
-	u32 status = ioread32(csr);
-
-	if (!(status & SMX_DRDY))
-		return IRQ_NONE;
-
-	/* Disable interrupt */
-	iowrite32(status & ~SMX_DRDY, csr);
-	return IRQ_HANDLED;
-}
-
-static int __devinit smx_ce_probe(struct platform_device *dev)
-{
-
-	int ret = -ENODEV;
-	struct uio_info *info;
-	struct resource *regs;
-
-	info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
-	if (!info)
-		return -ENOMEM;
-
-	regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
-	if (!regs) {
-		dev_err(&dev->dev, "No memory resource specified\n");
-		goto out_free;
-	}
-
-	info->mem[0].addr = regs->start;
-	if (!info->mem[0].addr) {
-		dev_err(&dev->dev, "Invalid memory resource\n");
-		goto out_free;
-	}
-
-	info->mem[0].size = regs->end - regs->start + 1;
-	info->mem[0].internal_addr = ioremap(regs->start, info->mem[0].size);
-
-	if (!info->mem[0].internal_addr) {
-		dev_err(&dev->dev, "Can't remap memory address range\n");
-		goto out_free;
-	}
-
-	info->mem[0].memtype = UIO_MEM_PHYS;
-
-	info->name = "smx-ce";
-	info->version = "0.03";
-
-	info->irq = platform_get_irq(dev, 0);
-	if (info->irq < 0) {
-		ret = info->irq;
-		dev_err(&dev->dev, "No (or invalid) IRQ resource specified\n");
-		goto out_unmap;
-	}
-
-	info->irq_flags = IRQF_SHARED;
-	info->handler = smx_handler;
-
-	platform_set_drvdata(dev, info);
-
-	ret = uio_register_device(&dev->dev, info);
-
-	if (ret)
-		goto out_unmap;
-
-	return 0;
-
-out_unmap:
-	iounmap(info->mem[0].internal_addr);
-out_free:
-	kfree(info);
-
-	return ret;
-}
-
-static int __devexit smx_ce_remove(struct platform_device *dev)
-{
-	struct uio_info *info = platform_get_drvdata(dev);
-
-	uio_unregister_device(info);
-	platform_set_drvdata(dev, NULL);
-	iounmap(info->mem[0].internal_addr);
-
-	kfree(info);
-
-	return 0;
-}
-
-static struct platform_driver smx_ce_driver = {
-	.probe		= smx_ce_probe,
-	.remove		= __devexit_p(smx_ce_remove),
-	.driver		= {
-		.name	= DRV_NAME,
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init smx_ce_init_module(void)
-{
-	return platform_driver_register(&smx_ce_driver);
-}
-module_init(smx_ce_init_module);
-
-static void __exit smx_ce_exit_module(void)
-{
-	platform_driver_unregister(&smx_ce_driver);
-}
-module_exit(smx_ce_exit_module);
-
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
-MODULE_AUTHOR("Ben Nizette <bn@niasdigital.com>");
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/atm/cxacru.c linux-libre-2.6.34-gnu1/drivers/usb/atm/cxacru.c
--- linux-libre-2.6.33-gnu1/drivers/usb/atm/cxacru.c	2013-05-03 12:12:51.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/usb/atm/cxacru.c	2013-05-03 09:52:23.000000000 -0400
@@ -5,6 +5,7 @@
  *  Copyright (C) 2004 David Woodhouse, Duncan Sands, Roman Kagan
  *  Copyright (C) 2005 Duncan Sands, Roman Kagan (rkagan % mail ! ru)
  *  Copyright (C) 2007 Simon Arlott
+ *  Copyright (C) 2009 Simon Arlott
  *
  *  This program is free software; you can redistribute it and/or modify it
  *  under the terms of the GNU General Public License as published by the Free
@@ -43,7 +44,7 @@
 #include "usbatm.h"
 
 #define DRIVER_AUTHOR	"Roman Kagan, David Woodhouse, Duncan Sands, Simon Arlott"
-#define DRIVER_VERSION	"0.3"
+#define DRIVER_VERSION	"0.4"
 #define DRIVER_DESC	"Conexant AccessRunner ADSL USB modem driver"
 
 static const char cxacru_driver_name[] = "cxacru";
@@ -52,6 +53,7 @@ static const char cxacru_driver_name[] =
 #define CXACRU_EP_DATA		0x02	/* Bulk in/out */
 
 #define CMD_PACKET_SIZE		64	/* Should be maxpacket(ep)? */
+#define CMD_MAX_CONFIG		((CMD_PACKET_SIZE / 4 - 1) / 2)
 
 /* Addresses */
 #define PLLFCLK_ADDR	0x00350068
@@ -105,6 +107,26 @@ enum cxacru_cm_request {
 	CM_REQUEST_MAX,
 };
 
+/* commands for interaction with the flash memory
+ *
+ * read:  response is the contents of the first 60 bytes of flash memory
+ * write: request contains the 60 bytes of data to write to flash memory
+ *        response is the contents of the first 60 bytes of flash memory
+ *
+ * layout: PP PP VV VV  MM MM MM MM  MM MM ?? ??  SS SS SS SS  SS SS SS SS
+ *         SS SS SS SS  SS SS SS SS  00 00 00 00  00 00 00 00  00 00 00 00
+ *         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00
+ *
+ *   P: le16  USB Product ID
+ *   V: le16  USB Vendor ID
+ *   M: be48  MAC Address
+ *   S: le16  ASCII Serial Number
+ */
+enum cxacru_cm_flash {
+	CM_FLASH_READ = 0xa1,
+	CM_FLASH_WRITE = 0xa2
+};
+
 /* reply codes to the commands above */
 enum cxacru_cm_status {
 	CM_STATUS_UNDEFINED,
@@ -196,23 +218,32 @@ static DEVICE_ATTR(_name, S_IRUGO, cxacr
 static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, \
 	cxacru_sysfs_show_##_name, cxacru_sysfs_store_##_name)
 
+#define CXACRU_SET_INIT(_name) \
+static DEVICE_ATTR(_name, S_IWUSR, \
+	NULL, cxacru_sysfs_store_##_name)
+
 #define CXACRU_ATTR_INIT(_value, _type, _name) \
 static ssize_t cxacru_sysfs_show_##_name(struct device *dev, \
 	struct device_attribute *attr, char *buf) \
 { \
-	struct usb_interface *intf = to_usb_interface(dev); \
-	struct usbatm_data *usbatm_instance = usb_get_intfdata(intf); \
-	struct cxacru_data *instance = usbatm_instance->driver_data; \
+	struct cxacru_data *instance = to_usbatm_driver_data(\
+		to_usb_interface(dev)); \
+\
+	if (instance == NULL) \
+		return -ENODEV; \
+\
 	return cxacru_sysfs_showattr_##_type(instance->card_info[_value], buf); \
 } \
 CXACRU__ATTR_INIT(_name)
 
 #define CXACRU_ATTR_CREATE(_v, _t, _name) CXACRU_DEVICE_CREATE_FILE(_name)
 #define CXACRU_CMD_CREATE(_name)          CXACRU_DEVICE_CREATE_FILE(_name)
+#define CXACRU_SET_CREATE(_name)          CXACRU_DEVICE_CREATE_FILE(_name)
 #define CXACRU__ATTR_CREATE(_name)        CXACRU_DEVICE_CREATE_FILE(_name)
 
 #define CXACRU_ATTR_REMOVE(_v, _t, _name) CXACRU_DEVICE_REMOVE_FILE(_name)
 #define CXACRU_CMD_REMOVE(_name)          CXACRU_DEVICE_REMOVE_FILE(_name)
+#define CXACRU_SET_REMOVE(_name)          CXACRU_DEVICE_REMOVE_FILE(_name)
 #define CXACRU__ATTR_REMOVE(_name)        CXACRU_DEVICE_REMOVE_FILE(_name)
 
 static ssize_t cxacru_sysfs_showattr_u32(u32 value, char *buf)
@@ -267,12 +298,12 @@ static ssize_t cxacru_sysfs_showattr_LIN
 static ssize_t cxacru_sysfs_showattr_MODU(u32 value, char *buf)
 {
 	static char *str[] = {
-			NULL,
+			"",
 			"ANSI T1.413",
 			"ITU-T G.992.1 (G.DMT)",
 			"ITU-T G.992.2 (G.LITE)"
 	};
-	if (unlikely(value >= ARRAY_SIZE(str) || str[value] == NULL))
+	if (unlikely(value >= ARRAY_SIZE(str)))
 		return snprintf(buf, PAGE_SIZE, "%u\n", value);
 	return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
 }
@@ -288,22 +319,28 @@ static ssize_t cxacru_sysfs_showattr_MOD
 static ssize_t cxacru_sysfs_show_mac_address(struct device *dev,
 	struct device_attribute *attr, char *buf)
 {
-	struct usb_interface *intf = to_usb_interface(dev);
-	struct usbatm_data *usbatm_instance = usb_get_intfdata(intf);
-	struct atm_dev *atm_dev = usbatm_instance->atm_dev;
+	struct cxacru_data *instance = to_usbatm_driver_data(
+			to_usb_interface(dev));
 
-	return snprintf(buf, PAGE_SIZE, "%pM\n", atm_dev->esi);
+	if (instance == NULL || instance->usbatm->atm_dev == NULL)
+		return -ENODEV;
+
+	return snprintf(buf, PAGE_SIZE, "%pM\n",
+		instance->usbatm->atm_dev->esi);
 }
 
 static ssize_t cxacru_sysfs_show_adsl_state(struct device *dev,
 	struct device_attribute *attr, char *buf)
 {
-	struct usb_interface *intf = to_usb_interface(dev);
-	struct usbatm_data *usbatm_instance = usb_get_intfdata(intf);
-	struct cxacru_data *instance = usbatm_instance->driver_data;
-	u32 value = instance->card_info[CXINF_LINE_STARTABLE];
-
 	static char *str[] = { "running", "stopped" };
+	struct cxacru_data *instance = to_usbatm_driver_data(
+			to_usb_interface(dev));
+	u32 value;
+
+	if (instance == NULL)
+		return -ENODEV;
+
+	value = instance->card_info[CXINF_LINE_STARTABLE];
 	if (unlikely(value >= ARRAY_SIZE(str)))
 		return snprintf(buf, PAGE_SIZE, "%u\n", value);
 	return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
@@ -312,9 +349,8 @@ static ssize_t cxacru_sysfs_show_adsl_st
 static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev,
 	struct device_attribute *attr, const char *buf, size_t count)
 {
-	struct usb_interface *intf = to_usb_interface(dev);
-	struct usbatm_data *usbatm_instance = usb_get_intfdata(intf);
-	struct cxacru_data *instance = usbatm_instance->driver_data;
+	struct cxacru_data *instance = to_usbatm_driver_data(
+			to_usb_interface(dev));
 	int ret;
 	int poll = -1;
 	char str_cmd[8];
@@ -328,13 +364,16 @@ static ssize_t cxacru_sysfs_store_adsl_s
 		return -EINVAL;
 	ret = 0;
 
+	if (instance == NULL)
+		return -ENODEV;
+
 	if (mutex_lock_interruptible(&instance->adsl_state_serialize))
 		return -ERESTARTSYS;
 
 	if (!strcmp(str_cmd, "stop") || !strcmp(str_cmd, "restart")) {
 		ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_STOP, NULL, 0, NULL, 0);
 		if (ret < 0) {
-			atm_err(usbatm_instance, "change adsl state:"
+			atm_err(instance->usbatm, "change adsl state:"
 				" CHIP_ADSL_LINE_STOP returned %d\n", ret);
 
 			ret = -EIO;
@@ -354,7 +393,7 @@ static ssize_t cxacru_sysfs_store_adsl_s
 	if (!strcmp(str_cmd, "start") || !strcmp(str_cmd, "restart")) {
 		ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0);
 		if (ret < 0) {
-			atm_err(usbatm_instance, "change adsl state:"
+			atm_err(instance->usbatm, "change adsl state:"
 				" CHIP_ADSL_LINE_START returned %d\n", ret);
 
 			ret = -EIO;
@@ -407,6 +446,72 @@ static ssize_t cxacru_sysfs_store_adsl_s
 	return ret;
 }
 
+/* CM_REQUEST_CARD_DATA_GET times out, so no show attribute */
+
+static ssize_t cxacru_sysfs_store_adsl_config(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct cxacru_data *instance = to_usbatm_driver_data(
+			to_usb_interface(dev));
+	int len = strlen(buf);
+	int ret, pos, num;
+	__le32 data[CMD_PACKET_SIZE / 4];
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EACCES;
+
+	if (instance == NULL)
+		return -ENODEV;
+
+	pos = 0;
+	num = 0;
+	while (pos < len) {
+		int tmp;
+		u32 index;
+		u32 value;
+
+		ret = sscanf(buf + pos, "%x=%x%n", &index, &value, &tmp);
+		if (ret < 2)
+			return -EINVAL;
+		if (index < 0 || index > 0x7f)
+			return -EINVAL;
+		pos += tmp;
+
+		/* skip trailing newline */
+		if (buf[pos] == '\n' && pos == len-1)
+			pos++;
+
+		data[num * 2 + 1] = cpu_to_le32(index);
+		data[num * 2 + 2] = cpu_to_le32(value);
+		num++;
+
+		/* send config values when data buffer is full
+		 * or no more data
+		 */
+		if (pos >= len || num >= CMD_MAX_CONFIG) {
+			char log[CMD_MAX_CONFIG * 12 + 1]; /* %02x=%08x */
+
+			data[0] = cpu_to_le32(num);
+			ret = cxacru_cm(instance, CM_REQUEST_CARD_DATA_SET,
+				(u8 *) data, 4 + num * 8, NULL, 0);
+			if (ret < 0) {
+				atm_err(instance->usbatm,
+					"set card data returned %d\n", ret);
+				return -EIO;
+			}
+
+			for (tmp = 0; tmp < num; tmp++)
+				snprintf(log + tmp*12, 13, " %02x=%08x",
+					le32_to_cpu(data[tmp * 2 + 1]),
+					le32_to_cpu(data[tmp * 2 + 2]));
+			atm_info(instance->usbatm, "config%s\n", log);
+			num = 0;
+		}
+	}
+
+	return len;
+}
+
 /*
  * All device attributes are included in CXACRU_ALL_FILES
  * so that the same list can be used multiple times:
@@ -442,7 +547,8 @@ CXACRU_ATTR_##_action(CXINF_MODULATION,
 CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND,              u32,  adsl_headend); \
 CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND_ENVIRONMENT,  u32,  adsl_headend_environment); \
 CXACRU_ATTR_##_action(CXINF_CONTROLLER_VERSION,        u32,  adsl_controller_version); \
-CXACRU_CMD_##_action(                                        adsl_state);
+CXACRU_CMD_##_action(                                        adsl_state); \
+CXACRU_SET_##_action(                                        adsl_config);
 
 CXACRU_ALL_FILES(INIT);
 
@@ -596,7 +702,7 @@ static int cxacru_cm_get_array(struct cx
 	len = ret / 4;
 	for (offb = 0; offb < len; ) {
 		int l = le32_to_cpu(buf[offb++]);
-		if (l > stride || l > (len - offb) / 2) {
+		if (l < 0 || l > stride || l > (len - offb) / 2) {
 			if (printk_ratelimit())
 				usb_err(instance->usbatm, "invalid data length from cm %#x: %d\n",
 					cm, l);
@@ -649,9 +755,6 @@ static int cxacru_atm_start(struct usbat
 {
 	struct cxacru_data *instance = usbatm_instance->driver_data;
 	struct usb_interface *intf = usbatm_instance->usb_intf;
-	/*
-	struct atm_dev *atm_dev = usbatm_instance->atm_dev;
-	*/
 	int ret;
 	int start_polling = 1;
 
@@ -697,6 +800,9 @@ static int cxacru_atm_start(struct usbat
 	mutex_unlock(&instance->poll_state_serialize);
 	mutex_unlock(&instance->adsl_state_serialize);
 
+	printk(KERN_INFO "%s%d: %s %pM\n", atm_dev->type, atm_dev->number,
+			usbatm_instance->description, atm_dev->esi);
+
 	if (start_polling)
 		cxacru_poll_status(&instance->poll_work.work);
 	return 0;
@@ -873,11 +979,9 @@ cleanup:
 
 static void cxacru_upload_firmware(struct cxacru_data *instance,
 				   const struct firmware *fw,
-				   const struct firmware *bp,
-				   const struct firmware *cf)
+				   const struct firmware *bp)
 {
 	int ret;
-	int off;
 	struct usbatm_data *usbatm = instance->usbatm;
 	struct usb_device *usb_dev = usbatm->usb_dev;
 	__le16 signature[] = { usb_dev->descriptor.idVendor,
@@ -911,6 +1015,7 @@ static void cxacru_upload_firmware(struc
 	}
 
 	/* Firmware */
+	usb_info(usbatm, "loading firmware\n");
 	ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size);
 	if (ret) {
 		usb_err(usbatm, "Firmware upload failed: %d\n", ret);
@@ -919,6 +1024,7 @@ static void cxacru_upload_firmware(struc
 
 	/* Boot ROM patch */
 	if (instance->modem_type->boot_rom_patch) {
+		usb_info(usbatm, "loading boot ROM patch\n");
 		ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size);
 		if (ret) {
 			usb_err(usbatm, "Boot ROM patching failed: %d\n", ret);
@@ -933,6 +1039,7 @@ static void cxacru_upload_firmware(struc
 		return;
 	}
 
+	usb_info(usbatm, "starting device\n");
 	if (instance->modem_type->boot_rom_patch) {
 		val = cpu_to_le32(BR_ADDR);
 		ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4);
@@ -958,26 +1065,6 @@ static void cxacru_upload_firmware(struc
 		usb_err(usbatm, "modem failed to initialize: %d\n", ret);
 		return;
 	}
-
-	/* Load config data (le32), doing one packet at a time */
-	if (cf)
-		for (off = 0; off < cf->size / 4; ) {
-			__le32 buf[CMD_PACKET_SIZE / 4 - 1];
-			int i, len = min_t(int, cf->size / 4 - off, CMD_PACKET_SIZE / 4 / 2 - 1);
-			buf[0] = cpu_to_le32(len);
-			for (i = 0; i < len; i++, off++) {
-				buf[i * 2 + 1] = cpu_to_le32(off);
-				memcpy(buf + i * 2 + 2, cf->data + off * 4, 4);
-			}
-			ret = cxacru_cm(instance, CM_REQUEST_CARD_DATA_SET,
-					(u8 *) buf, len, NULL, 0);
-			if (ret < 0) {
-				usb_err(usbatm, "load config data failed: %d\n", ret);
-				return;
-			}
-		}
-
-	msleep_interruptible(4000);
 }
 
 static int cxacru_find_firmware(struct cxacru_data *instance,
@@ -1003,7 +1090,7 @@ static int cxacru_find_firmware(struct c
 static int cxacru_heavy_init(struct usbatm_data *usbatm_instance,
 			     struct usb_interface *usb_intf)
 {
-	const struct firmware *fw, *bp, *cf;
+	const struct firmware *fw, *bp;
 	struct cxacru_data *instance = usbatm_instance->driver_data;
 
 	int ret = cxacru_find_firmware(instance, "fw", &fw);
@@ -1021,13 +1108,8 @@ static int cxacru_heavy_init(struct usba
 		}
 	}
 
-	if (cxacru_find_firmware(instance, "cf", &cf))		/* optional */
-		cf = NULL;
-
-	cxacru_upload_firmware(instance, fw, bp, cf);
+	cxacru_upload_firmware(instance, fw, bp);
 
-	if (cf)
-		release_firmware(cf);
 	if (instance->modem_type->boot_rom_patch)
 		release_firmware(bp);
 	release_firmware(fw);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/atm/speedtch.c linux-libre-2.6.34-gnu1/drivers/usb/atm/speedtch.c
--- linux-libre-2.6.33-gnu1/drivers/usb/atm/speedtch.c	2013-05-03 12:12:53.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/usb/atm/speedtch.c	2013-05-03 09:52:26.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/firmware.h>
-#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/atm/ueagle-atm.c linux-libre-2.6.34-gnu1/drivers/usb/atm/ueagle-atm.c
--- linux-libre-2.6.33-gnu1/drivers/usb/atm/ueagle-atm.c	2013-05-03 12:12:56.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/usb/atm/ueagle-atm.c	2013-05-03 09:52:28.000000000 -0400
@@ -66,6 +66,7 @@
 #include <linux/kthread.h>
 #include <linux/mutex.h>
 #include <linux/freezer.h>
+#include <linux/slab.h>
 
 #include <asm/unaligned.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/atm/usbatm.c linux-libre-2.6.34-gnu1/drivers/usb/atm/usbatm.c
--- linux-libre-2.6.33-gnu1/drivers/usb/atm/usbatm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/atm/usbatm.c	2010-05-16 17:17:36.000000000 -0400
@@ -1333,6 +1333,7 @@ void usbatm_usb_disconnect(struct usb_in
 	if (instance->atm_dev) {
 		sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device");
 		atm_dev_deregister(instance->atm_dev);
+		instance->atm_dev = NULL;
 	}
 
 	usbatm_put_instance(instance);	/* taken in usbatm_usb_probe */
@@ -1348,7 +1349,7 @@ static int __init usbatm_usb_init(void)
 {
 	dbg("%s: driver version %s", __func__, DRIVER_VERSION);
 
-	if (sizeof(struct usbatm_control) > sizeof(((struct sk_buff *) 0)->cb)) {
+	if (sizeof(struct usbatm_control) > FIELD_SIZEOF(struct sk_buff, cb)) {
 		printk(KERN_ERR "%s unusable with this kernel!\n", usbatm_driver_name);
 		return -EIO;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/atm/usbatm.h linux-libre-2.6.34-gnu1/drivers/usb/atm/usbatm.h
--- linux-libre-2.6.33-gnu1/drivers/usb/atm/usbatm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/atm/usbatm.h	2010-05-16 17:17:36.000000000 -0400
@@ -204,4 +204,19 @@ struct usbatm_data {
 	struct urb *urbs[0];
 };
 
+static inline void *to_usbatm_driver_data(struct usb_interface *intf)
+{
+	struct usbatm_data *usbatm_instance;
+
+	if (intf == NULL)
+		return NULL;
+
+	usbatm_instance = usb_get_intfdata(intf);
+
+	if (usbatm_instance == NULL) /* set NULL before unbind() */
+		return NULL;
+
+	return usbatm_instance->driver_data; /* set NULL after unbind() */
+}
+
 #endif	/* _USBATM_H_ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/c67x00/c67x00-drv.c linux-libre-2.6.34-gnu1/drivers/usb/c67x00/c67x00-drv.c
--- linux-libre-2.6.33-gnu1/drivers/usb/c67x00/c67x00-drv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/c67x00/c67x00-drv.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/c67x00.h>
 
@@ -137,13 +138,13 @@ static int __devinit c67x00_drv_probe(st
 	if (!c67x00)
 		return -ENOMEM;
 
-	if (!request_mem_region(res->start, res->end - res->start + 1,
+	if (!request_mem_region(res->start, resource_size(res),
 				pdev->name)) {
 		dev_err(&pdev->dev, "Memory region busy\n");
 		ret = -EBUSY;
 		goto request_mem_failed;
 	}
-	c67x00->hpi.base = ioremap(res->start, res->end - res->start + 1);
+	c67x00->hpi.base = ioremap(res->start, resource_size(res));
 	if (!c67x00->hpi.base) {
 		dev_err(&pdev->dev, "Unable to map HPI registers\n");
 		ret = -EIO;
@@ -182,7 +183,7 @@ static int __devinit c67x00_drv_probe(st
  request_irq_failed:
 	iounmap(c67x00->hpi.base);
  map_failed:
-	release_mem_region(res->start, res->end - res->start + 1);
+	release_mem_region(res->start, resource_size(res));
  request_mem_failed:
 	kfree(c67x00);
 
@@ -208,7 +209,7 @@ static int __devexit c67x00_drv_remove(s
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res)
-		release_mem_region(res->start, res->end - res->start + 1);
+		release_mem_region(res->start, resource_size(res));
 
 	kfree(c67x00);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/c67x00/c67x00-sched.c linux-libre-2.6.34-gnu1/drivers/usb/c67x00/c67x00-sched.c
--- linux-libre-2.6.33-gnu1/drivers/usb/c67x00/c67x00-sched.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/c67x00/c67x00-sched.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  */
 
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 #include "c67x00.h"
 #include "c67x00-hcd.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/class/cdc-acm.c linux-libre-2.6.34-gnu1/drivers/usb/class/cdc-acm.c
--- linux-libre-2.6.33-gnu1/drivers/usb/class/cdc-acm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/class/cdc-acm.c	2010-05-16 17:17:36.000000000 -0400
@@ -170,6 +170,7 @@ static void acm_write_done(struct acm *a
 {
 	wb->use = 0;
 	acm->transmitting--;
+	usb_autopm_put_interface_async(acm->control);
 }
 
 /*
@@ -211,9 +212,12 @@ static int acm_write_start(struct acm *a
 	}
 
 	dbg("%s susp_count: %d", __func__, acm->susp_count);
+	usb_autopm_get_interface_async(acm->control);
 	if (acm->susp_count) {
-		acm->delayed_wb = wb;
-		schedule_work(&acm->waker);
+		if (!acm->delayed_wb)
+			acm->delayed_wb = wb;
+		else
+			usb_autopm_put_interface_async(acm->control);
 		spin_unlock_irqrestore(&acm->write_lock, flags);
 		return 0;	/* A white lie */
 	}
@@ -424,7 +428,6 @@ next_buffer:
 		throttled = acm->throttle;
 		spin_unlock_irqrestore(&acm->throttle_lock, flags);
 		if (!throttled) {
-			tty_buffer_request_room(tty, buf->size);
 			tty_insert_flip_string(tty, buf->base, buf->size);
 			tty_flip_buffer_push(tty);
 		} else {
@@ -534,23 +537,6 @@ static void acm_softint(struct work_stru
 	tty_kref_put(tty);
 }
 
-static void acm_waker(struct work_struct *waker)
-{
-	struct acm *acm = container_of(waker, struct acm, waker);
-	int rv;
-
-	rv = usb_autopm_get_interface(acm->control);
-	if (rv < 0) {
-		dev_err(&acm->dev->dev, "Autopm failure in %s\n", __func__);
-		return;
-	}
-	if (acm->delayed_wb) {
-		acm_start_wb(acm, acm->delayed_wb);
-		acm->delayed_wb = NULL;
-	}
-	usb_autopm_put_interface(acm->control);
-}
-
 /*
  * TTY handlers
  */
@@ -566,7 +552,7 @@ static int acm_tty_open(struct tty_struc
 
 	acm = acm_table[tty->index];
 	if (!acm || !acm->dev)
-		goto err_out;
+		goto out;
 	else
 		rv = 0;
 
@@ -582,8 +568,9 @@ static int acm_tty_open(struct tty_struc
 
 	mutex_lock(&acm->mutex);
 	if (acm->port.count++) {
+		mutex_unlock(&acm->mutex);
 		usb_autopm_put_interface(acm->control);
-		goto done;
+		goto out;
 	}
 
 	acm->ctrlurb->dev = acm->dev;
@@ -612,18 +599,18 @@ static int acm_tty_open(struct tty_struc
 	set_bit(ASYNCB_INITIALIZED, &acm->port.flags);
 	rv = tty_port_block_til_ready(&acm->port, tty, filp);
 	tasklet_schedule(&acm->urb_task);
-done:
+
 	mutex_unlock(&acm->mutex);
-err_out:
+out:
 	mutex_unlock(&open_mutex);
 	return rv;
 
 full_bailout:
 	usb_kill_urb(acm->ctrlurb);
 bail_out:
-	usb_autopm_put_interface(acm->control);
 	acm->port.count--;
 	mutex_unlock(&acm->mutex);
+	usb_autopm_put_interface(acm->control);
 early_bail:
 	mutex_unlock(&open_mutex);
 	tty_port_tty_set(&acm->port, NULL);
@@ -1023,7 +1010,7 @@ static int acm_probe(struct usb_interfac
 		case USB_CDC_CALL_MANAGEMENT_TYPE:
 			call_management_function = buffer[3];
 			call_interface_num = buffer[4];
-			if ((call_management_function & 3) != 3)
+			if ( (quirks & NOT_A_MODEM) == 0 && (call_management_function & 3) != 3)
 				dev_err(&intf->dev, "This device cannot do calls on its own. It is not a modem.\n");
 			break;
 		default:
@@ -1178,7 +1165,6 @@ made_compressed_probe:
 	acm->urb_task.func = acm_rx_tasklet;
 	acm->urb_task.data = (unsigned long) acm;
 	INIT_WORK(&acm->work, acm_softint);
-	INIT_WORK(&acm->waker, acm_waker);
 	init_waitqueue_head(&acm->drain_wait);
 	spin_lock_init(&acm->throttle_lock);
 	spin_lock_init(&acm->write_lock);
@@ -1343,7 +1329,6 @@ static void stop_data_traffic(struct acm
 	tasklet_enable(&acm->urb_task);
 
 	cancel_work_sync(&acm->work);
-	cancel_work_sync(&acm->waker);
 }
 
 static void acm_disconnect(struct usb_interface *intf)
@@ -1435,6 +1420,7 @@ static int acm_suspend(struct usb_interf
 static int acm_resume(struct usb_interface *intf)
 {
 	struct acm *acm = usb_get_intfdata(intf);
+	struct acm_wb *wb;
 	int rv = 0;
 	int cnt;
 
@@ -1449,6 +1435,21 @@ static int acm_resume(struct usb_interfa
 	mutex_lock(&acm->mutex);
 	if (acm->port.count) {
 		rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO);
+
+		spin_lock_irq(&acm->write_lock);
+		if (acm->delayed_wb) {
+			wb = acm->delayed_wb;
+			acm->delayed_wb = NULL;
+			spin_unlock_irq(&acm->write_lock);
+			acm_start_wb(acm, wb);
+		} else {
+			spin_unlock_irq(&acm->write_lock);
+		}
+
+		/*
+		 * delayed error checking because we must
+		 * do the write path at all cost
+		 */
 		if (rv < 0)
 			goto err_out;
 
@@ -1460,6 +1461,23 @@ err_out:
 	return rv;
 }
 
+static int acm_reset_resume(struct usb_interface *intf)
+{
+	struct acm *acm = usb_get_intfdata(intf);
+	struct tty_struct *tty;
+
+	mutex_lock(&acm->mutex);
+	if (acm->port.count) {
+		tty = tty_port_tty_get(&acm->port);
+		if (tty) {
+			tty_hangup(tty);
+			tty_kref_put(tty);
+		}
+	}
+	mutex_unlock(&acm->mutex);
+	return acm_resume(intf);
+}
+
 #endif /* CONFIG_PM */
 
 #define NOKIA_PCSUITE_ACM_INFO(x) \
@@ -1471,7 +1489,7 @@ err_out:
  * USB driver structure.
  */
 
-static struct usb_device_id acm_ids[] = {
+static const struct usb_device_id acm_ids[] = {
 	/* quirky and broken devices */
 	{ USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */
 	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
@@ -1524,6 +1542,9 @@ static struct usb_device_id acm_ids[] =
 	{ USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */
 	.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
 	},
+	{ USB_DEVICE(0x1576, 0x03b1), /* Maretron USB100 */
+	.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
+	},
 
 	/* Nokia S60 phones expose two ACM channels. The first is
 	 * a modem and is picked up by the standard AT-command
@@ -1576,6 +1597,11 @@ static struct usb_device_id acm_ids[] =
 
 	/* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */
 
+	/* Support Lego NXT using pbLua firmware */
+	{ USB_DEVICE(0x0694, 0xff00),
+	.driver_info = NOT_A_MODEM,
+       	},
+
 	/* control interfaces with various AT-command sets */
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
 		USB_CDC_ACM_PROTO_AT_V25TER) },
@@ -1602,6 +1628,7 @@ static struct usb_driver acm_driver = {
 #ifdef CONFIG_PM
 	.suspend =	acm_suspend,
 	.resume =	acm_resume,
+	.reset_resume =	acm_reset_resume,
 #endif
 	.id_table =	acm_ids,
 #ifdef CONFIG_PM
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/class/cdc-acm.h linux-libre-2.6.34-gnu1/drivers/usb/class/cdc-acm.h
--- linux-libre-2.6.33-gnu1/drivers/usb/class/cdc-acm.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/class/cdc-acm.h	2010-05-16 17:17:36.000000000 -0400
@@ -112,7 +112,6 @@ struct acm {
 	struct mutex mutex;
 	struct usb_cdc_line_coding line;		/* bits, stop, parity */
 	struct work_struct work;			/* work queue entry for line discipline waking up */
-	struct work_struct waker;
 	wait_queue_head_t drain_wait;			/* close processing */
 	struct tasklet_struct urb_task;                 /* rx processing */
 	spinlock_t throttle_lock;			/* synchronize throtteling and read callback */
@@ -137,3 +136,4 @@ struct acm {
 #define NO_UNION_NORMAL			1
 #define SINGLE_RX_URB			2
 #define NO_CAP_LINE			4
+#define NOT_A_MODEM			8
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/class/cdc-wdm.c linux-libre-2.6.34-gnu1/drivers/usb/class/cdc-wdm.c
--- linux-libre-2.6.33-gnu1/drivers/usb/class/cdc-wdm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/class/cdc-wdm.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,7 @@
 #define DRIVER_AUTHOR "Oliver Neukum"
 #define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management"
 
-static struct usb_device_id wdm_ids[] = {
+static const struct usb_device_id wdm_ids[] = {
 	{
 		.match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
 				 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
@@ -52,7 +52,8 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
 #define WDM_READ		4
 #define WDM_INT_STALL		5
 #define WDM_POLL_RUNNING	6
-
+#define WDM_RESPONDING		7
+#define WDM_SUSPENDING		8
 
 #define WDM_MAX			16
 
@@ -87,9 +88,7 @@ struct wdm_device {
 	int			count;
 	dma_addr_t		shandle;
 	dma_addr_t		ihandle;
-	struct mutex		wlock;
-	struct mutex		rlock;
-	struct mutex		plock;
+	struct mutex		lock;
 	wait_queue_head_t	wait;
 	struct work_struct	rxwork;
 	int			werr;
@@ -117,21 +116,22 @@ static void wdm_in_callback(struct urb *
 	int status = urb->status;
 
 	spin_lock(&desc->iuspin);
+	clear_bit(WDM_RESPONDING, &desc->flags);
 
 	if (status) {
 		switch (status) {
 		case -ENOENT:
 			dev_dbg(&desc->intf->dev,
 				"nonzero urb status received: -ENOENT");
-			break;
+			goto skip_error;
 		case -ECONNRESET:
 			dev_dbg(&desc->intf->dev,
 				"nonzero urb status received: -ECONNRESET");
-			break;
+			goto skip_error;
 		case -ESHUTDOWN:
 			dev_dbg(&desc->intf->dev,
 				"nonzero urb status received: -ESHUTDOWN");
-			break;
+			goto skip_error;
 		case -EPIPE:
 			dev_err(&desc->intf->dev,
 				"nonzero urb status received: -EPIPE\n");
@@ -147,6 +147,7 @@ static void wdm_in_callback(struct urb *
 	desc->reslength = urb->actual_length;
 	memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength);
 	desc->length += desc->reslength;
+skip_error:
 	wake_up(&desc->wait);
 
 	set_bit(WDM_READ, &desc->flags);
@@ -229,13 +230,16 @@ static void wdm_int_callback(struct urb
 	desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 	spin_lock(&desc->iuspin);
 	clear_bit(WDM_READ, &desc->flags);
-	if (!test_bit(WDM_DISCONNECTING, &desc->flags)) {
+	set_bit(WDM_RESPONDING, &desc->flags);
+	if (!test_bit(WDM_DISCONNECTING, &desc->flags)
+		&& !test_bit(WDM_SUSPENDING, &desc->flags)) {
 		rv = usb_submit_urb(desc->response, GFP_ATOMIC);
 		dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d",
 			__func__, rv);
 	}
 	spin_unlock(&desc->iuspin);
 	if (rv < 0) {
+		clear_bit(WDM_RESPONDING, &desc->flags);
 		if (rv == -EPERM)
 			return;
 		if (rv == -ENOMEM) {
@@ -305,14 +309,38 @@ static ssize_t wdm_write
 	if (we < 0)
 		return -EIO;
 
-	r = mutex_lock_interruptible(&desc->wlock); /* concurrent writes */
+	desc->outbuf = buf = kmalloc(count, GFP_KERNEL);
+	if (!buf) {
+		rv = -ENOMEM;
+		goto outnl;
+	}
+
+	r = copy_from_user(buf, buffer, count);
+	if (r > 0) {
+		kfree(buf);
+		rv = -EFAULT;
+		goto outnl;
+	}
+
+	/* concurrent writes and disconnect */
+	r = mutex_lock_interruptible(&desc->lock);
 	rv = -ERESTARTSYS;
-	if (r)
+	if (r) {
+		kfree(buf);
 		goto outnl;
+	}
+
+	if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
+		kfree(buf);
+		rv = -ENODEV;
+		goto outnp;
+	}
 
 	r = usb_autopm_get_interface(desc->intf);
-	if (r < 0)
+	if (r < 0) {
+		kfree(buf);
 		goto outnp;
+	}
 
 	if (!file->f_flags && O_NONBLOCK)
 		r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
@@ -320,24 +348,8 @@ static ssize_t wdm_write
 	else
 		if (test_bit(WDM_IN_USE, &desc->flags))
 			r = -EAGAIN;
-	if (r < 0)
-		goto out;
-
-	if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
-		rv = -ENODEV;
-		goto out;
-	}
-
-	desc->outbuf = buf = kmalloc(count, GFP_KERNEL);
-	if (!buf) {
-		rv = -ENOMEM;
-		goto out;
-	}
-
-	r = copy_from_user(buf, buffer, count);
-	if (r > 0) {
+	if (r < 0) {
 		kfree(buf);
-		rv = -EFAULT;
 		goto out;
 	}
 
@@ -374,7 +386,7 @@ static ssize_t wdm_write
 out:
 	usb_autopm_put_interface(desc->intf);
 outnp:
-	mutex_unlock(&desc->wlock);
+	mutex_unlock(&desc->lock);
 outnl:
 	return rv < 0 ? rv : count;
 }
@@ -387,7 +399,7 @@ static ssize_t wdm_read
 	struct wdm_device *desc = file->private_data;
 
 
-	rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */
+	rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */
 	if (rv < 0)
 		return -ERESTARTSYS;
 
@@ -424,11 +436,8 @@ retry:
 		spin_lock_irq(&desc->iuspin);
 
 		if (desc->rerr) { /* read completed, error happened */
-			int t = desc->rerr;
 			desc->rerr = 0;
 			spin_unlock_irq(&desc->iuspin);
-			dev_err(&desc->intf->dev,
-				"reading had resulted in %d\n", t);
 			rv = -EIO;
 			goto err;
 		}
@@ -465,9 +474,7 @@ retry:
 	rv = cntr;
 
 err:
-	mutex_unlock(&desc->rlock);
-	if (rv < 0 && rv != -EAGAIN)
-		dev_err(&desc->intf->dev, "wdm_read: exit error\n");
+	mutex_unlock(&desc->lock);
 	return rv;
 }
 
@@ -533,7 +540,7 @@ static int wdm_open(struct inode *inode,
 	}
 	intf->needs_remote_wakeup = 1;
 
-	mutex_lock(&desc->plock);
+	mutex_lock(&desc->lock);
 	if (!desc->count++) {
 		rv = usb_submit_urb(desc->validity, GFP_KERNEL);
 		if (rv < 0) {
@@ -544,7 +551,7 @@ static int wdm_open(struct inode *inode,
 	} else {
 		rv = 0;
 	}
-	mutex_unlock(&desc->plock);
+	mutex_unlock(&desc->lock);
 	usb_autopm_put_interface(desc->intf);
 out:
 	mutex_unlock(&wdm_mutex);
@@ -556,9 +563,9 @@ static int wdm_release(struct inode *ino
 	struct wdm_device *desc = file->private_data;
 
 	mutex_lock(&wdm_mutex);
-	mutex_lock(&desc->plock);
+	mutex_lock(&desc->lock);
 	desc->count--;
-	mutex_unlock(&desc->plock);
+	mutex_unlock(&desc->lock);
 
 	if (!desc->count) {
 		dev_dbg(&desc->intf->dev, "wdm_release: cleanup");
@@ -655,9 +662,7 @@ next_desc:
 	desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
 	if (!desc)
 		goto out;
-	mutex_init(&desc->wlock);
-	mutex_init(&desc->rlock);
-	mutex_init(&desc->plock);
+	mutex_init(&desc->lock);
 	spin_lock_init(&desc->iuspin);
 	init_waitqueue_head(&desc->wait);
 	desc->wMaxCommand = maxcom;
@@ -771,14 +776,17 @@ static void wdm_disconnect(struct usb_in
 	/* to terminate pending flushes */
 	clear_bit(WDM_IN_USE, &desc->flags);
 	spin_unlock_irqrestore(&desc->iuspin, flags);
-	cancel_work_sync(&desc->rxwork);
+	mutex_lock(&desc->lock);
 	kill_urbs(desc);
+	cancel_work_sync(&desc->rxwork);
+	mutex_unlock(&desc->lock);
 	wake_up_all(&desc->wait);
 	if (!desc->count)
 		cleanup(desc);
 	mutex_unlock(&wdm_mutex);
 }
 
+#ifdef CONFIG_PM
 static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	struct wdm_device *desc = usb_get_intfdata(intf);
@@ -786,22 +794,30 @@ static int wdm_suspend(struct usb_interf
 
 	dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);
 
-	mutex_lock(&desc->plock);
-#ifdef CONFIG_PM
+	/* if this is an autosuspend the caller does the locking */
+	if (!(message.event & PM_EVENT_AUTO))
+		mutex_lock(&desc->lock);
+	spin_lock_irq(&desc->iuspin);
+
 	if ((message.event & PM_EVENT_AUTO) &&
-			test_bit(WDM_IN_USE, &desc->flags)) {
+			(test_bit(WDM_IN_USE, &desc->flags)
+			|| test_bit(WDM_RESPONDING, &desc->flags))) {
+		spin_unlock_irq(&desc->iuspin);
 		rv = -EBUSY;
 	} else {
-#endif
-		cancel_work_sync(&desc->rxwork);
+
+		set_bit(WDM_SUSPENDING, &desc->flags);
+		spin_unlock_irq(&desc->iuspin);
+		/* callback submits work - order is essential */
 		kill_urbs(desc);
-#ifdef CONFIG_PM
+		cancel_work_sync(&desc->rxwork);
 	}
-#endif
-	mutex_unlock(&desc->plock);
+	if (!(message.event & PM_EVENT_AUTO))
+		mutex_unlock(&desc->lock);
 
 	return rv;
 }
+#endif
 
 static int recover_from_urb_loss(struct wdm_device *desc)
 {
@@ -815,23 +831,27 @@ static int recover_from_urb_loss(struct
 	}
 	return rv;
 }
+
+#ifdef CONFIG_PM
 static int wdm_resume(struct usb_interface *intf)
 {
 	struct wdm_device *desc = usb_get_intfdata(intf);
 	int rv;
 
 	dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor);
-	mutex_lock(&desc->plock);
+
+	clear_bit(WDM_SUSPENDING, &desc->flags);
 	rv = recover_from_urb_loss(desc);
-	mutex_unlock(&desc->plock);
+
 	return rv;
 }
+#endif
 
 static int wdm_pre_reset(struct usb_interface *intf)
 {
 	struct wdm_device *desc = usb_get_intfdata(intf);
 
-	mutex_lock(&desc->plock);
+	mutex_lock(&desc->lock);
 	return 0;
 }
 
@@ -841,7 +861,7 @@ static int wdm_post_reset(struct usb_int
 	int rv;
 
 	rv = recover_from_urb_loss(desc);
-	mutex_unlock(&desc->plock);
+	mutex_unlock(&desc->lock);
 	return 0;
 }
 
@@ -849,9 +869,11 @@ static struct usb_driver wdm_driver = {
 	.name =		"cdc_wdm",
 	.probe =	wdm_probe,
 	.disconnect =	wdm_disconnect,
+#ifdef CONFIG_PM
 	.suspend =	wdm_suspend,
 	.resume =	wdm_resume,
 	.reset_resume =	wdm_resume,
+#endif
 	.pre_reset =	wdm_pre_reset,
 	.post_reset =	wdm_post_reset,
 	.id_table =	wdm_ids,
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/class/usblp.c linux-libre-2.6.34-gnu1/drivers/usb/class/usblp.c
--- linux-libre-2.6.33-gnu1/drivers/usb/class/usblp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/class/usblp.c	2010-05-16 17:17:36.000000000 -0400
@@ -163,7 +163,6 @@ struct usblp {
 	unsigned char		used;			/* True if open */
 	unsigned char		present;		/* True if not disconnected */
 	unsigned char		bidir;			/* interface is bidirectional */
-	unsigned char		sleeping;		/* interface is suspended */
 	unsigned char		no_paper;		/* Paper Out happened */
 	unsigned char		*device_id_string;	/* IEEE 1284 DEVICE ID string (ptr) */
 							/* first 2 bytes are (big-endian) length */
@@ -191,7 +190,6 @@ static void usblp_dump(struct usblp *usb
 	dbg("quirks=%d", usblp->quirks);
 	dbg("used=%d", usblp->used);
 	dbg("bidir=%d", usblp->bidir);
-	dbg("sleeping=%d", usblp->sleeping);
 	dbg("device_id_string=\"%s\"",
 		usblp->device_id_string ?
 			usblp->device_id_string + 2 :
@@ -376,7 +374,7 @@ static int usblp_check_status(struct usb
 
 static int handle_bidir (struct usblp *usblp)
 {
-	if (usblp->bidir && usblp->used && !usblp->sleeping) {
+	if (usblp->bidir && usblp->used) {
 		if (usblp_submit_read(usblp) < 0)
 			return -EIO;
 	}
@@ -503,11 +501,6 @@ static long usblp_ioctl(struct file *fil
 		goto done;
 	}
 
-	if (usblp->sleeping) {
-		retval = -ENODEV;
-		goto done;
-	}
-
 	dbg("usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)", cmd, _IOC_TYPE(cmd),
 		_IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd) );
 
@@ -914,8 +907,6 @@ static int usblp_wtest(struct usblp *usb
 		return 0;
 	}
 	spin_unlock_irqrestore(&usblp->lock, flags);
-	if (usblp->sleeping)
-		return -ENODEV;
 	if (nonblock)
 		return -EAGAIN;
 	return 1;
@@ -968,8 +959,6 @@ static int usblp_rtest(struct usblp *usb
 		return 0;
 	}
 	spin_unlock_irqrestore(&usblp->lock, flags);
-	if (usblp->sleeping)
-		return -ENODEV;
 	if (nonblock)
 		return -EAGAIN;
 	return 1;
@@ -1377,12 +1366,10 @@ static void usblp_disconnect(struct usb_
 	mutex_unlock (&usblp_mutex);
 }
 
-static int usblp_suspend (struct usb_interface *intf, pm_message_t message)
+static int usblp_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	struct usblp *usblp = usb_get_intfdata (intf);
 
-	/* we take no more IO */
-	usblp->sleeping = 1;
 	usblp_unlink_urbs(usblp);
 #if 0 /* XXX Do we want this? What if someone is reading, should we fail? */
 	/* not strictly necessary, but just in case */
@@ -1393,18 +1380,17 @@ static int usblp_suspend (struct usb_int
 	return 0;
 }
 
-static int usblp_resume (struct usb_interface *intf)
+static int usblp_resume(struct usb_interface *intf)
 {
 	struct usblp *usblp = usb_get_intfdata (intf);
 	int r;
 
-	usblp->sleeping = 0;
 	r = handle_bidir (usblp);
 
 	return r;
 }
 
-static struct usb_device_id usblp_ids [] = {
+static const struct usb_device_id usblp_ids[] = {
 	{ USB_DEVICE_INFO(7, 1, 1) },
 	{ USB_DEVICE_INFO(7, 1, 2) },
 	{ USB_DEVICE_INFO(7, 1, 3) },
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/class/usbtmc.c linux-libre-2.6.34-gnu1/drivers/usb/class/usbtmc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/class/usbtmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/class/usbtmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/fs.h>
 #include <linux/uaccess.h>
 #include <linux/kref.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/usb.h>
 #include <linux/usb/tmc.h>
@@ -48,7 +49,7 @@
  */
 #define USBTMC_MAX_READS_TO_CLEAR_BULK_IN	100
 
-static struct usb_device_id usbtmc_devices[] = {
+static const struct usb_device_id usbtmc_devices[] = {
 	{ USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), },
 	{ USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 1), },
 	{ 0, } /* terminating entry */
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/devices.c linux-libre-2.6.34-gnu1/drivers/usb/core/devices.c
--- linux-libre-2.6.33-gnu1/drivers/usb/core/devices.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/devices.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,7 +50,7 @@
 
 #include <linux/fs.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/poll.h>
 #include <linux/usb.h>
 #include <linux/smp_lock.h>
@@ -117,12 +117,20 @@ static const char *format_endpt =
  * However, these will come from functions that return ptrs to each of them.
  */
 
-static DECLARE_WAIT_QUEUE_HEAD(deviceconndiscwq);
-static unsigned int conndiscevcnt;
-
-/* this struct stores the poll state for <mountpoint>/devices pollers */
-struct usb_device_status {
-	unsigned int lastev;
+/*
+ * Wait for an connect/disconnect event to happen. We initialize
+ * the event counter with an odd number, and each event will increment
+ * the event counter by two, so it will always _stay_ odd. That means
+ * that it will never be zero, so "event 0" will never match a current
+ * event, and thus 'poll' will always trigger as readable for the first
+ * time it gets called.
+ */
+static struct device_connect_event {
+	atomic_t count;
+	wait_queue_head_t wait;
+} device_event = {
+	.count = ATOMIC_INIT(1),
+	.wait = __WAIT_QUEUE_HEAD_INITIALIZER(device_event.wait)
 };
 
 struct class_info {
@@ -156,8 +164,8 @@ static const struct class_info clas_info
 
 void usbfs_conn_disc_event(void)
 {
-	conndiscevcnt++;
-	wake_up(&deviceconndiscwq);
+	atomic_add(2, &device_event.count);
+	wake_up(&device_event.wait);
 }
 
 static const char *class_decode(const int class)
@@ -629,55 +637,16 @@ static ssize_t usb_device_read(struct fi
 static unsigned int usb_device_poll(struct file *file,
 				    struct poll_table_struct *wait)
 {
-	struct usb_device_status *st = file->private_data;
-	unsigned int mask = 0;
-
-	lock_kernel();
-	if (!st) {
-		st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);
+	unsigned int event_count;
 
-		/* we may have dropped BKL -
-		 * need to check for having lost the race */
-		if (file->private_data) {
-			kfree(st);
-			st = file->private_data;
-			goto lost_race;
-		}
-		/* we haven't lost - check for allocation failure now */
-		if (!st) {
-			unlock_kernel();
-			return POLLIN;
-		}
+	poll_wait(file, &device_event.wait, wait);
 
-		/*
-		 * need to prevent the module from being unloaded, since
-		 * proc_unregister does not call the release method and
-		 * we would have a memory leak
-		 */
-		st->lastev = conndiscevcnt;
-		file->private_data = st;
-		mask = POLLIN;
+	event_count = atomic_read(&device_event.count);
+	if (file->f_version != event_count) {
+		file->f_version = event_count;
+		return POLLIN | POLLRDNORM;
 	}
-lost_race:
-	if (file->f_mode & FMODE_READ)
-		poll_wait(file, &deviceconndiscwq, wait);
-	if (st->lastev != conndiscevcnt)
-		mask |= POLLIN;
-	st->lastev = conndiscevcnt;
-	unlock_kernel();
-	return mask;
-}
-
-static int usb_device_open(struct inode *inode, struct file *file)
-{
-	file->private_data = NULL;
-	return 0;
-}
 
-static int usb_device_release(struct inode *inode, struct file *file)
-{
-	kfree(file->private_data);
-	file->private_data = NULL;
 	return 0;
 }
 
@@ -685,7 +654,7 @@ static loff_t usb_device_lseek(struct fi
 {
 	loff_t ret;
 
-	lock_kernel();
+	mutex_lock(&file->f_dentry->d_inode->i_mutex);
 
 	switch (orig) {
 	case 0:
@@ -701,7 +670,7 @@ static loff_t usb_device_lseek(struct fi
 		ret = -EINVAL;
 	}
 
-	unlock_kernel();
+	mutex_unlock(&file->f_dentry->d_inode->i_mutex);
 	return ret;
 }
 
@@ -709,6 +678,4 @@ const struct file_operations usbfs_devic
 	.llseek =	usb_device_lseek,
 	.read =		usb_device_read,
 	.poll =		usb_device_poll,
-	.open =		usb_device_open,
-	.release =	usb_device_release,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/devio.c linux-libre-2.6.34-gnu1/drivers/usb/core/devio.c
--- linux-libre-2.6.33-gnu1/drivers/usb/core/devio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/devio.c	2010-05-16 17:17:36.000000000 -0400
@@ -122,7 +122,7 @@ static loff_t usbdev_lseek(struct file *
 {
 	loff_t ret;
 
-	lock_kernel();
+	mutex_lock(&file->f_dentry->d_inode->i_mutex);
 
 	switch (orig) {
 	case 0:
@@ -138,7 +138,7 @@ static loff_t usbdev_lseek(struct file *
 		ret = -EINVAL;
 	}
 
-	unlock_kernel();
+	mutex_unlock(&file->f_dentry->d_inode->i_mutex);
 	return ret;
 }
 
@@ -310,7 +310,8 @@ static struct async *async_getpending(st
 
 static void snoop_urb(struct usb_device *udev,
 		void __user *userurb, int pipe, unsigned length,
-		int timeout_or_status, enum snoop_when when)
+		int timeout_or_status, enum snoop_when when,
+		unsigned char *data, unsigned data_len)
 {
 	static const char *types[] = {"isoc", "int", "ctrl", "bulk"};
 	static const char *dirs[] = {"out", "in"};
@@ -344,6 +345,11 @@ static void snoop_urb(struct usb_device
 					"status %d\n",
 					ep, t, d, length, timeout_or_status);
 	}
+
+	if (data && data_len > 0) {
+		print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE, 32, 1,
+			data, data_len, 1);
+	}
 }
 
 #define AS_CONTINUATION	1
@@ -410,7 +416,9 @@ static void async_completed(struct urb *
 	}
 	snoop(&urb->dev->dev, "urb complete\n");
 	snoop_urb(urb->dev, as->userurb, urb->pipe, urb->actual_length,
-			as->status, COMPLETE);
+			as->status, COMPLETE,
+			((urb->transfer_flags & URB_DIR_MASK) == USB_DIR_OUT) ?
+				NULL : urb->transfer_buffer, urb->actual_length);
 	if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET &&
 			as->status != -ENOENT)
 		cancel_bulk_urbs(ps, as->bulk_addr);
@@ -653,20 +661,20 @@ static int usbdev_open(struct inode *ino
 	const struct cred *cred = current_cred();
 	int ret;
 
-	lock_kernel();
-	/* Protect against simultaneous removal or release */
-	mutex_lock(&usbfs_mutex);
-
 	ret = -ENOMEM;
 	ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL);
 	if (!ps)
-		goto out;
+		goto out_free_ps;
 
 	ret = -ENODEV;
 
+	/* Protect against simultaneous removal or release */
+	mutex_lock(&usbfs_mutex);
+
 	/* usbdev device-node */
 	if (imajor(inode) == USB_DEVICE_MAJOR)
 		dev = usbdev_lookup_by_devt(inode->i_rdev);
+
 #ifdef CONFIG_USB_DEVICEFS
 	/* procfs file */
 	if (!dev) {
@@ -678,13 +686,19 @@ static int usbdev_open(struct inode *ino
 			dev = NULL;
 	}
 #endif
-	if (!dev || dev->state == USB_STATE_NOTATTACHED)
-		goto out;
+	mutex_unlock(&usbfs_mutex);
+
+	if (!dev)
+		goto out_free_ps;
+
+	usb_lock_device(dev);
+	if (dev->state == USB_STATE_NOTATTACHED)
+		goto out_unlock_device;
+
 	ret = usb_autoresume_device(dev);
 	if (ret)
-		goto out;
+		goto out_unlock_device;
 
-	ret = 0;
 	ps->dev = dev;
 	ps->file = file;
 	spin_lock_init(&ps->lock);
@@ -702,15 +716,16 @@ static int usbdev_open(struct inode *ino
 	smp_wmb();
 	list_add_tail(&ps->list, &dev->filelist);
 	file->private_data = ps;
+	usb_unlock_device(dev);
 	snoop(&dev->dev, "opened by process %d: %s\n", task_pid_nr(current),
 			current->comm);
- out:
-	if (ret) {
-		kfree(ps);
-		usb_put_dev(dev);
-	}
-	mutex_unlock(&usbfs_mutex);
-	unlock_kernel();
+	return ret;
+
+ out_unlock_device:
+	usb_unlock_device(dev);
+	usb_put_dev(dev);
+ out_free_ps:
+	kfree(ps);
 	return ret;
 }
 
@@ -724,10 +739,7 @@ static int usbdev_release(struct inode *
 	usb_lock_device(dev);
 	usb_hub_release_all_ports(dev, ps);
 
-	/* Protect against simultaneous open */
-	mutex_lock(&usbfs_mutex);
 	list_del_init(&ps->list);
-	mutex_unlock(&usbfs_mutex);
 
 	for (ifnum = 0; ps->ifclaimed && ifnum < 8*sizeof(ps->ifclaimed);
 			ifnum++) {
@@ -770,6 +782,13 @@ static int proc_control(struct dev_state
 	if (!tbuf)
 		return -ENOMEM;
 	tmo = ctrl.timeout;
+	snoop(&dev->dev, "control urb: bRequestType=%02x "
+		"bRequest=%02x wValue=%04x "
+		"wIndex=%04x wLength=%04x\n",
+		ctrl.bRequestType, ctrl.bRequest,
+		__le16_to_cpup(&ctrl.wValue),
+		__le16_to_cpup(&ctrl.wIndex),
+		__le16_to_cpup(&ctrl.wLength));
 	if (ctrl.bRequestType & 0x80) {
 		if (ctrl.wLength && !access_ok(VERIFY_WRITE, ctrl.data,
 					       ctrl.wLength)) {
@@ -777,15 +796,15 @@ static int proc_control(struct dev_state
 			return -EINVAL;
 		}
 		pipe = usb_rcvctrlpipe(dev, 0);
-		snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT);
+		snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT, NULL, 0);
 
 		usb_unlock_device(dev);
 		i = usb_control_msg(dev, pipe, ctrl.bRequest,
 				    ctrl.bRequestType, ctrl.wValue, ctrl.wIndex,
 				    tbuf, ctrl.wLength, tmo);
 		usb_lock_device(dev);
-		snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE);
-
+		snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE,
+			tbuf, i);
 		if ((i > 0) && ctrl.wLength) {
 			if (copy_to_user(ctrl.data, tbuf, i)) {
 				free_page((unsigned long)tbuf);
@@ -800,14 +819,15 @@ static int proc_control(struct dev_state
 			}
 		}
 		pipe = usb_sndctrlpipe(dev, 0);
-		snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT);
+		snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT,
+			tbuf, ctrl.wLength);
 
 		usb_unlock_device(dev);
 		i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest,
 				    ctrl.bRequestType, ctrl.wValue, ctrl.wIndex,
 				    tbuf, ctrl.wLength, tmo);
 		usb_lock_device(dev);
-		snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE);
+		snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, NULL, 0);
 	}
 	free_page((unsigned long)tbuf);
 	if (i < 0 && i != -EPIPE) {
@@ -853,12 +873,12 @@ static int proc_bulk(struct dev_state *p
 			kfree(tbuf);
 			return -EINVAL;
 		}
-		snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT);
+		snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, NULL, 0);
 
 		usb_unlock_device(dev);
 		i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo);
 		usb_lock_device(dev);
-		snoop_urb(dev, NULL, pipe, len2, i, COMPLETE);
+		snoop_urb(dev, NULL, pipe, len2, i, COMPLETE, tbuf, len2);
 
 		if (!i && len2) {
 			if (copy_to_user(bulk.data, tbuf, len2)) {
@@ -873,12 +893,12 @@ static int proc_bulk(struct dev_state *p
 				return -EFAULT;
 			}
 		}
-		snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT);
+		snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, tbuf, len1);
 
 		usb_unlock_device(dev);
 		i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo);
 		usb_lock_device(dev);
-		snoop_urb(dev, NULL, pipe, len2, i, COMPLETE);
+		snoop_urb(dev, NULL, pipe, len2, i, COMPLETE, NULL, 0);
 	}
 	kfree(tbuf);
 	if (i < 0)
@@ -1097,6 +1117,13 @@ static int proc_do_submiturb(struct dev_
 			is_in = 0;
 			uurb->endpoint &= ~USB_DIR_IN;
 		}
+		snoop(&ps->dev->dev, "control urb: bRequestType=%02x "
+			"bRequest=%02x wValue=%04x "
+			"wIndex=%04x wLength=%04x\n",
+			dr->bRequestType, dr->bRequest,
+			__le16_to_cpup(&dr->wValue),
+			__le16_to_cpup(&dr->wIndex),
+			__le16_to_cpup(&dr->wLength));
 		break;
 
 	case USBDEVFS_URB_TYPE_BULK:
@@ -1104,13 +1131,25 @@ static int proc_do_submiturb(struct dev_
 		case USB_ENDPOINT_XFER_CONTROL:
 		case USB_ENDPOINT_XFER_ISOC:
 			return -EINVAL;
-		/* allow single-shot interrupt transfers, at bogus rates */
+		case USB_ENDPOINT_XFER_INT:
+			/* allow single-shot interrupt transfers */
+			uurb->type = USBDEVFS_URB_TYPE_INTERRUPT;
+			goto interrupt_urb;
 		}
 		uurb->number_of_packets = 0;
 		if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
 			return -EINVAL;
 		break;
 
+	case USBDEVFS_URB_TYPE_INTERRUPT:
+		if (!usb_endpoint_xfer_int(&ep->desc))
+			return -EINVAL;
+ interrupt_urb:
+		uurb->number_of_packets = 0;
+		if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
+			return -EINVAL;
+		break;
+
 	case USBDEVFS_URB_TYPE_ISO:
 		/* arbitrary limit */
 		if (uurb->number_of_packets < 1 ||
@@ -1143,14 +1182,6 @@ static int proc_do_submiturb(struct dev_
 		uurb->buffer_length = totlen;
 		break;
 
-	case USBDEVFS_URB_TYPE_INTERRUPT:
-		uurb->number_of_packets = 0;
-		if (!usb_endpoint_xfer_int(&ep->desc))
-			return -EINVAL;
-		if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
-			return -EINVAL;
-		break;
-
 	default:
 		return -EINVAL;
 	}
@@ -1176,6 +1207,13 @@ static int proc_do_submiturb(struct dev_
 			free_async(as);
 			return -ENOMEM;
 		}
+		/* Isochronous input data may end up being discontiguous
+		 * if some of the packets are short.  Clear the buffer so
+		 * that the gaps don't leak kernel data to userspace.
+		 */
+		if (is_in && uurb->type == USBDEVFS_URB_TYPE_ISO)
+			memset(as->urb->transfer_buffer, 0,
+					uurb->buffer_length);
 	}
 	as->urb->dev = ps->dev;
 	as->urb->pipe = (uurb->type << 30) |
@@ -1236,7 +1274,9 @@ static int proc_do_submiturb(struct dev_
 		}
 	}
 	snoop_urb(ps->dev, as->userurb, as->urb->pipe,
-			as->urb->transfer_buffer_length, 0, SUBMIT);
+			as->urb->transfer_buffer_length, 0, SUBMIT,
+			is_in ? NULL : as->urb->transfer_buffer,
+				uurb->buffer_length);
 	async_newpending(as);
 
 	if (usb_endpoint_xfer_bulk(&ep->desc)) {
@@ -1274,7 +1314,7 @@ static int proc_do_submiturb(struct dev_
 		dev_printk(KERN_DEBUG, &ps->dev->dev,
 			   "usbfs: usb_submit_urb returned %d\n", ret);
 		snoop_urb(ps->dev, as->userurb, as->urb->pipe,
-				0, ret, COMPLETE);
+				0, ret, COMPLETE, NULL, 0);
 		async_removepending(as);
 		free_async(as);
 		return ret;
@@ -1312,10 +1352,14 @@ static int processcompl(struct async *as
 	void __user *addr = as->userurb;
 	unsigned int i;
 
-	if (as->userbuffer && urb->actual_length)
-		if (copy_to_user(as->userbuffer, urb->transfer_buffer,
-				 urb->actual_length))
+	if (as->userbuffer && urb->actual_length) {
+		if (urb->number_of_packets > 0)		/* Isochronous */
+			i = urb->transfer_buffer_length;
+		else					/* Non-Isoc */
+			i = urb->actual_length;
+		if (copy_to_user(as->userbuffer, urb->transfer_buffer, i))
 			goto err_out;
+	}
 	if (put_user(as->status, &userurb->status))
 		goto err_out;
 	if (put_user(urb->actual_length, &userurb->actual_length))
@@ -1628,7 +1672,10 @@ static int proc_ioctl(struct dev_state *
 		if (driver == NULL || driver->ioctl == NULL) {
 			retval = -ENOTTY;
 		} else {
+			/* keep API that guarantees BKL */
+			lock_kernel();
 			retval = driver->ioctl(intf, ctl->ioctl_code, buf);
+			unlock_kernel();
 			if (retval == -ENOIOCTLCMD)
 				retval = -ENOTTY;
 		}
@@ -1711,6 +1758,7 @@ static long usbdev_do_ioctl(struct file
 
 	if (!(file->f_mode & FMODE_WRITE))
 		return -EPERM;
+
 	usb_lock_device(dev);
 	if (!connected(ps)) {
 		usb_unlock_device(dev);
@@ -1877,9 +1925,7 @@ static long usbdev_ioctl(struct file *fi
 {
 	int ret;
 
-	lock_kernel();
 	ret = usbdev_do_ioctl(file, cmd, (void __user *)arg);
-	unlock_kernel();
 
 	return ret;
 }
@@ -1890,9 +1936,7 @@ static long usbdev_compat_ioctl(struct f
 {
 	int ret;
 
-	lock_kernel();
 	ret = usbdev_do_ioctl(file, cmd, compat_ptr(arg));
-	unlock_kernel();
 
 	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/driver.c linux-libre-2.6.34-gnu1/drivers/usb/core/driver.c
--- linux-libre-2.6.33-gnu1/drivers/usb/core/driver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/driver.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,9 +23,10 @@
  */
 
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/quirks.h>
-#include <linux/workqueue.h>
+#include <linux/pm_runtime.h>
 #include "hcd.h"
 #include "usb.h"
 
@@ -221,7 +222,7 @@ static int usb_probe_device(struct devic
 {
 	struct usb_device_driver *udriver = to_usb_device_driver(dev->driver);
 	struct usb_device *udev = to_usb_device(dev);
-	int error = -ENODEV;
+	int error = 0;
 
 	dev_dbg(dev, "%s\n", __func__);
 
@@ -230,18 +231,23 @@ static int usb_probe_device(struct devic
 	/* The device should always appear to be in use
 	 * unless the driver suports autosuspend.
 	 */
-	udev->pm_usage_cnt = !(udriver->supports_autosuspend);
+	if (!udriver->supports_autosuspend)
+		error = usb_autoresume_device(udev);
 
-	error = udriver->probe(udev);
+	if (!error)
+		error = udriver->probe(udev);
 	return error;
 }
 
 /* called from driver core with dev locked */
 static int usb_unbind_device(struct device *dev)
 {
+	struct usb_device *udev = to_usb_device(dev);
 	struct usb_device_driver *udriver = to_usb_device_driver(dev->driver);
 
-	udriver->disconnect(to_usb_device(dev));
+	udriver->disconnect(udev);
+	if (!udriver->supports_autosuspend)
+		usb_autosuspend_device(udev);
 	return 0;
 }
 
@@ -274,60 +280,62 @@ static int usb_probe_interface(struct de
 	intf->needs_binding = 0;
 
 	if (usb_device_is_owned(udev))
-		return -ENODEV;
+		return error;
 
 	if (udev->authorized == 0) {
 		dev_err(&intf->dev, "Device is not authorized for usage\n");
-		return -ENODEV;
+		return error;
 	}
 
 	id = usb_match_id(intf, driver->id_table);
 	if (!id)
 		id = usb_match_dynamic_id(intf, driver);
-	if (id) {
-		dev_dbg(dev, "%s - got id\n", __func__);
-
-		error = usb_autoresume_device(udev);
-		if (error)
-			return error;
+	if (!id)
+		return error;
 
-		/* Interface "power state" doesn't correspond to any hardware
-		 * state whatsoever.  We use it to record when it's bound to
-		 * a driver that may start I/0:  it's not frozen/quiesced.
-		 */
-		mark_active(intf);
-		intf->condition = USB_INTERFACE_BINDING;
+	dev_dbg(dev, "%s - got id\n", __func__);
 
-		/* The interface should always appear to be in use
-		 * unless the driver suports autosuspend.
-		 */
-		atomic_set(&intf->pm_usage_cnt, !driver->supports_autosuspend);
+	error = usb_autoresume_device(udev);
+	if (error)
+		return error;
 
-		/* Carry out a deferred switch to altsetting 0 */
-		if (intf->needs_altsetting0) {
-			error = usb_set_interface(udev, intf->altsetting[0].
-					desc.bInterfaceNumber, 0);
-			if (error < 0)
-				goto err;
+	intf->condition = USB_INTERFACE_BINDING;
 
-			intf->needs_altsetting0 = 0;
-		}
+	/* Probed interfaces are initially active.  They are
+	 * runtime-PM-enabled only if the driver has autosuspend support.
+	 * They are sensitive to their children's power states.
+	 */
+	pm_runtime_set_active(dev);
+	pm_suspend_ignore_children(dev, false);
+	if (driver->supports_autosuspend)
+		pm_runtime_enable(dev);
 
-		error = driver->probe(intf, id);
-		if (error)
+	/* Carry out a deferred switch to altsetting 0 */
+	if (intf->needs_altsetting0) {
+		error = usb_set_interface(udev, intf->altsetting[0].
+				desc.bInterfaceNumber, 0);
+		if (error < 0)
 			goto err;
-
-		intf->condition = USB_INTERFACE_BOUND;
-		usb_autosuspend_device(udev);
+		intf->needs_altsetting0 = 0;
 	}
 
+	error = driver->probe(intf, id);
+	if (error)
+		goto err;
+
+	intf->condition = USB_INTERFACE_BOUND;
+	usb_autosuspend_device(udev);
 	return error;
 
-err:
-	mark_quiesced(intf);
+ err:
 	intf->needs_remote_wakeup = 0;
 	intf->condition = USB_INTERFACE_UNBOUND;
 	usb_cancel_queued_reset(intf);
+
+	/* Unbound interfaces are always runtime-PM-disabled and -suspended */
+	pm_runtime_disable(dev);
+	pm_runtime_set_suspended(dev);
+
 	usb_autosuspend_device(udev);
 	return error;
 }
@@ -377,9 +385,17 @@ static int usb_unbind_interface(struct d
 	usb_set_intfdata(intf, NULL);
 
 	intf->condition = USB_INTERFACE_UNBOUND;
-	mark_quiesced(intf);
 	intf->needs_remote_wakeup = 0;
 
+	/* Unbound interfaces are always runtime-PM-disabled and -suspended */
+	pm_runtime_disable(dev);
+	pm_runtime_set_suspended(dev);
+
+	/* Undo any residual pm_autopm_get_interface_* calls */
+	for (r = atomic_read(&intf->pm_usage_cnt); r > 0; --r)
+		usb_autopm_put_interface_no_suspend(intf);
+	atomic_set(&intf->pm_usage_cnt, 0);
+
 	if (!error)
 		usb_autosuspend_device(udev);
 
@@ -410,7 +426,6 @@ int usb_driver_claim_interface(struct us
 				struct usb_interface *iface, void *priv)
 {
 	struct device *dev = &iface->dev;
-	struct usb_device *udev = interface_to_usbdev(iface);
 	int retval = 0;
 
 	if (dev->driver)
@@ -420,11 +435,16 @@ int usb_driver_claim_interface(struct us
 	usb_set_intfdata(iface, priv);
 	iface->needs_binding = 0;
 
-	usb_pm_lock(udev);
 	iface->condition = USB_INTERFACE_BOUND;
-	mark_active(iface);
-	atomic_set(&iface->pm_usage_cnt, !driver->supports_autosuspend);
-	usb_pm_unlock(udev);
+
+	/* Claimed interfaces are initially inactive (suspended).  They are
+	 * runtime-PM-enabled only if the driver has autosuspend support.
+	 * They are sensitive to their children's power states.
+	 */
+	pm_runtime_set_suspended(dev);
+	pm_suspend_ignore_children(dev, false);
+	if (driver->supports_autosuspend)
+		pm_runtime_enable(dev);
 
 	/* if interface was already added, bind now; else let
 	 * the future device_add() bind it, bypassing probe()
@@ -470,10 +490,10 @@ void usb_driver_release_interface(struct
 	if (device_is_registered(dev)) {
 		device_release_driver(dev);
 	} else {
-		down(&dev->sem);
+		device_lock(dev);
 		usb_unbind_interface(dev);
 		dev->driver = NULL;
-		up(&dev->sem);
+		device_unlock(dev);
 	}
 }
 EXPORT_SYMBOL_GPL(usb_driver_release_interface);
@@ -691,9 +711,6 @@ static int usb_uevent(struct device *dev
 {
 	struct usb_device *usb_dev;
 
-	/* driver is often null here; dev_dbg() would oops */
-	pr_debug("usb %s: uevent\n", dev_name(dev));
-
 	if (is_usb_device(dev)) {
 		usb_dev = to_usb_device(dev);
 	} else if (is_usb_interface(dev)) {
@@ -705,6 +722,7 @@ static int usb_uevent(struct device *dev
 	}
 
 	if (usb_dev->devnum < 0) {
+		/* driver is often null here; dev_dbg() would oops */
 		pr_debug("usb %s: already deleted?\n", dev_name(dev));
 		return -ENODEV;
 	}
@@ -983,7 +1001,6 @@ static void do_unbind_rebind(struct usb_
 	}
 }
 
-/* Caller has locked udev's pm_mutex */
 static int usb_suspend_device(struct usb_device *udev, pm_message_t msg)
 {
 	struct usb_device_driver	*udriver;
@@ -1007,7 +1024,6 @@ static int usb_suspend_device(struct usb
 	return status;
 }
 
-/* Caller has locked udev's pm_mutex */
 static int usb_resume_device(struct usb_device *udev, pm_message_t msg)
 {
 	struct usb_device_driver	*udriver;
@@ -1022,6 +1038,14 @@ static int usb_resume_device(struct usb_
 		goto done;
 	}
 
+	/* Non-root devices on a full/low-speed bus must wait for their
+	 * companion high-speed root hub, in case a handoff is needed.
+	 */
+	if (!(msg.event & PM_EVENT_AUTO) && udev->parent &&
+			udev->bus->hs_companion)
+		device_pm_wait_for_dev(&udev->dev,
+				&udev->bus->hs_companion->root_hub->dev);
+
 	if (udev->quirks & USB_QUIRK_RESET_RESUME)
 		udev->reset_resume = 1;
 
@@ -1033,27 +1057,20 @@ static int usb_resume_device(struct usb_
 	return status;
 }
 
-/* Caller has locked intf's usb_device's pm mutex */
 static int usb_suspend_interface(struct usb_device *udev,
 		struct usb_interface *intf, pm_message_t msg)
 {
 	struct usb_driver	*driver;
 	int			status = 0;
 
-	/* with no hardware, USB interfaces only use FREEZE and ON states */
-	if (udev->state == USB_STATE_NOTATTACHED || !is_active(intf))
-		goto done;
-
-	/* This can happen; see usb_driver_release_interface() */
-	if (intf->condition == USB_INTERFACE_UNBOUND)
+	if (udev->state == USB_STATE_NOTATTACHED ||
+			intf->condition == USB_INTERFACE_UNBOUND)
 		goto done;
 	driver = to_usb_driver(intf->dev.driver);
 
 	if (driver->suspend) {
 		status = driver->suspend(intf, msg);
-		if (status == 0)
-			mark_quiesced(intf);
-		else if (!(msg.event & PM_EVENT_AUTO))
+		if (status && !(msg.event & PM_EVENT_AUTO))
 			dev_err(&intf->dev, "%s error %d\n",
 					"suspend", status);
 	} else {
@@ -1061,7 +1078,6 @@ static int usb_suspend_interface(struct
 		intf->needs_binding = 1;
 		dev_warn(&intf->dev, "no %s for driver %s?\n",
 				"suspend", driver->name);
-		mark_quiesced(intf);
 	}
 
  done:
@@ -1069,14 +1085,13 @@ static int usb_suspend_interface(struct
 	return status;
 }
 
-/* Caller has locked intf's usb_device's pm_mutex */
 static int usb_resume_interface(struct usb_device *udev,
 		struct usb_interface *intf, pm_message_t msg, int reset_resume)
 {
 	struct usb_driver	*driver;
 	int			status = 0;
 
-	if (udev->state == USB_STATE_NOTATTACHED || is_active(intf))
+	if (udev->state == USB_STATE_NOTATTACHED)
 		goto done;
 
 	/* Don't let autoresume interfere with unbinding */
@@ -1127,90 +1142,11 @@ static int usb_resume_interface(struct u
 
 done:
 	dev_vdbg(&intf->dev, "%s: status %d\n", __func__, status);
-	if (status == 0 && intf->condition == USB_INTERFACE_BOUND)
-		mark_active(intf);
 
 	/* Later we will unbind the driver and/or reprobe, if necessary */
 	return status;
 }
 
-#ifdef	CONFIG_USB_SUSPEND
-
-/* Internal routine to check whether we may autosuspend a device. */
-static int autosuspend_check(struct usb_device *udev, int reschedule)
-{
-	int			i;
-	struct usb_interface	*intf;
-	unsigned long		suspend_time, j;
-
-	/* For autosuspend, fail fast if anything is in use or autosuspend
-	 * is disabled.  Also fail if any interfaces require remote wakeup
-	 * but it isn't available.
-	 */
-	if (udev->pm_usage_cnt > 0)
-		return -EBUSY;
-	if (udev->autosuspend_delay < 0 || udev->autosuspend_disabled)
-		return -EPERM;
-
-	suspend_time = udev->last_busy + udev->autosuspend_delay;
-	if (udev->actconfig) {
-		for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
-			intf = udev->actconfig->interface[i];
-			if (!is_active(intf))
-				continue;
-			if (atomic_read(&intf->pm_usage_cnt) > 0)
-				return -EBUSY;
-			if (intf->needs_remote_wakeup &&
-					!udev->do_remote_wakeup) {
-				dev_dbg(&udev->dev, "remote wakeup needed "
-						"for autosuspend\n");
-				return -EOPNOTSUPP;
-			}
-
-			/* Don't allow autosuspend if the device will need
-			 * a reset-resume and any of its interface drivers
-			 * doesn't include support.
-			 */
-			if (udev->quirks & USB_QUIRK_RESET_RESUME) {
-				struct usb_driver *driver;
-
-				driver = to_usb_driver(intf->dev.driver);
-				if (!driver->reset_resume ||
-				    intf->needs_remote_wakeup)
-					return -EOPNOTSUPP;
-			}
-		}
-	}
-
-	/* If everything is okay but the device hasn't been idle for long
-	 * enough, queue a delayed autosuspend request.  If the device
-	 * _has_ been idle for long enough and the reschedule flag is set,
-	 * likewise queue a delayed (1 second) autosuspend request.
-	 */
-	j = jiffies;
-	if (time_before(j, suspend_time))
-		reschedule = 1;
-	else
-		suspend_time = j + HZ;
-	if (reschedule) {
-		if (!timer_pending(&udev->autosuspend.timer)) {
-			queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
-				round_jiffies_up_relative(suspend_time - j));
-		}
-		return -EAGAIN;
-	}
-	return 0;
-}
-
-#else
-
-static inline int autosuspend_check(struct usb_device *udev, int reschedule)
-{
-	return 0;
-}
-
-#endif	/* CONFIG_USB_SUSPEND */
-
 /**
  * usb_suspend_both - suspend a USB device and its interfaces
  * @udev: the usb_device to suspend
@@ -1222,52 +1158,29 @@ static inline int autosuspend_check(stru
  * all the interfaces which were suspended are resumed so that they remain
  * in the same state as the device.
  *
- * If an autosuspend is in progress the routine checks first to make sure
- * that neither the device itself or any of its active interfaces is in use
- * (pm_usage_cnt is greater than 0).  If they are, the autosuspend fails.
- *
- * If the suspend succeeds, the routine recursively queues an autosuspend
- * request for @udev's parent device, thereby propagating the change up
- * the device tree.  If all of the parent's children are now suspended,
- * the parent will autosuspend in turn.
- *
- * The suspend method calls are subject to mutual exclusion under control
- * of @udev's pm_mutex.  Many of these calls are also under the protection
- * of @udev's device lock (including all requests originating outside the
- * USB subsystem), but autosuspend requests generated by a child device or
- * interface driver may not be.  Usbcore will insure that the method calls
- * do not arrive during bind, unbind, or reset operations.  However, drivers
- * must be prepared to handle suspend calls arriving at unpredictable times.
- * The only way to block such calls is to do an autoresume (preventing
- * autosuspends) while holding @udev's device lock (preventing outside
- * suspends).
- *
- * The caller must hold @udev->pm_mutex.
+ * Autosuspend requests originating from a child device or an interface
+ * driver may be made without the protection of @udev's device lock, but
+ * all other suspend calls will hold the lock.  Usbcore will insure that
+ * method calls do not arrive during bind, unbind, or reset operations.
+ * However drivers must be prepared to handle suspend calls arriving at
+ * unpredictable times.
  *
  * This routine can run only in process context.
  */
 static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
 {
 	int			status = 0;
-	int			i = 0;
+	int			i = 0, n = 0;
 	struct usb_interface	*intf;
-	struct usb_device	*parent = udev->parent;
 
 	if (udev->state == USB_STATE_NOTATTACHED ||
 			udev->state == USB_STATE_SUSPENDED)
 		goto done;
 
-	udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
-
-	if (msg.event & PM_EVENT_AUTO) {
-		status = autosuspend_check(udev, 0);
-		if (status < 0)
-			goto done;
-	}
-
 	/* Suspend all the interfaces and then udev itself */
 	if (udev->actconfig) {
-		for (; i < udev->actconfig->desc.bNumInterfaces; i++) {
+		n = udev->actconfig->desc.bNumInterfaces;
+		for (i = n - 1; i >= 0; --i) {
 			intf = udev->actconfig->interface[i];
 			status = usb_suspend_interface(udev, intf, msg);
 			if (status != 0)
@@ -1279,35 +1192,21 @@ static int usb_suspend_both(struct usb_d
 
 	/* If the suspend failed, resume interfaces that did get suspended */
 	if (status != 0) {
-		pm_message_t msg2;
-
-		msg2.event = msg.event ^ (PM_EVENT_SUSPEND | PM_EVENT_RESUME);
-		while (--i >= 0) {
+		msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME);
+		while (++i < n) {
 			intf = udev->actconfig->interface[i];
-			usb_resume_interface(udev, intf, msg2, 0);
+			usb_resume_interface(udev, intf, msg, 0);
 		}
 
-		/* Try another autosuspend when the interfaces aren't busy */
-		if (msg.event & PM_EVENT_AUTO)
-			autosuspend_check(udev, status == -EBUSY);
-
-	/* If the suspend succeeded then prevent any more URB submissions,
-	 * flush any outstanding URBs, and propagate the suspend up the tree.
+	/* If the suspend succeeded then prevent any more URB submissions
+	 * and flush any outstanding URBs.
 	 */
 	} else {
-		cancel_delayed_work(&udev->autosuspend);
 		udev->can_submit = 0;
 		for (i = 0; i < 16; ++i) {
 			usb_hcd_flush_endpoint(udev, udev->ep_out[i]);
 			usb_hcd_flush_endpoint(udev, udev->ep_in[i]);
 		}
-
-		/* If this is just a FREEZE or a PRETHAW, udev might
-		 * not really be suspended.  Only true suspends get
-		 * propagated up the device tree.
-		 */
-		if (parent && udev->state == USB_STATE_SUSPENDED)
-			usb_autosuspend_device(parent);
 	}
 
  done:
@@ -1324,23 +1223,12 @@ static int usb_suspend_both(struct usb_d
  * the resume method for @udev and then calls the resume methods for all
  * the interface drivers in @udev.
  *
- * Before starting the resume, the routine calls itself recursively for
- * the parent device of @udev, thereby propagating the change up the device
- * tree and assuring that @udev will be able to resume.  If the parent is
- * unable to resume successfully, the routine fails.
- *
- * The resume method calls are subject to mutual exclusion under control
- * of @udev's pm_mutex.  Many of these calls are also under the protection
- * of @udev's device lock (including all requests originating outside the
- * USB subsystem), but autoresume requests generated by a child device or
- * interface driver may not be.  Usbcore will insure that the method calls
- * do not arrive during bind, unbind, or reset operations.  However, drivers
- * must be prepared to handle resume calls arriving at unpredictable times.
- * The only way to block such calls is to do an autoresume (preventing
- * other autoresumes) while holding @udev's device lock (preventing outside
- * resumes).
- *
- * The caller must hold @udev->pm_mutex.
+ * Autoresume requests originating from a child device or an interface
+ * driver may be made without the protection of @udev's device lock, but
+ * all other resume calls will hold the lock.  Usbcore will insure that
+ * method calls do not arrive during bind, unbind, or reset operations.
+ * However drivers must be prepared to handle resume calls arriving at
+ * unpredictable times.
  *
  * This routine can run only in process context.
  */
@@ -1349,48 +1237,18 @@ static int usb_resume_both(struct usb_de
 	int			status = 0;
 	int			i;
 	struct usb_interface	*intf;
-	struct usb_device	*parent = udev->parent;
 
-	cancel_delayed_work(&udev->autosuspend);
 	if (udev->state == USB_STATE_NOTATTACHED) {
 		status = -ENODEV;
 		goto done;
 	}
 	udev->can_submit = 1;
 
-	/* Propagate the resume up the tree, if necessary */
-	if (udev->state == USB_STATE_SUSPENDED) {
-		if (parent) {
-			status = usb_autoresume_device(parent);
-			if (status == 0) {
-				status = usb_resume_device(udev, msg);
-				if (status || udev->state ==
-						USB_STATE_NOTATTACHED) {
-					usb_autosuspend_device(parent);
-
-					/* It's possible usb_resume_device()
-					 * failed after the port was
-					 * unsuspended, causing udev to be
-					 * logically disconnected.  We don't
-					 * want usb_disconnect() to autosuspend
-					 * the parent again, so tell it that
-					 * udev disconnected while still
-					 * suspended. */
-					if (udev->state ==
-							USB_STATE_NOTATTACHED)
-						udev->discon_suspended = 1;
-				}
-			}
-		} else {
-
-			/* We can't progagate beyond the USB subsystem,
-			 * so if a root hub's controller is suspended
-			 * then we're stuck. */
-			status = usb_resume_device(udev, msg);
-		}
-	} else if (udev->reset_resume)
+	/* Resume the device */
+	if (udev->state == USB_STATE_SUSPENDED || udev->reset_resume)
 		status = usb_resume_device(udev, msg);
 
+	/* Resume the interfaces */
 	if (status == 0 && udev->actconfig) {
 		for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
 			intf = udev->actconfig->interface[i];
@@ -1406,55 +1264,128 @@ static int usb_resume_both(struct usb_de
 	return status;
 }
 
-#ifdef CONFIG_USB_SUSPEND
+static void choose_wakeup(struct usb_device *udev, pm_message_t msg)
+{
+	int			w, i;
+	struct usb_interface	*intf;
 
-/* Internal routine to adjust a device's usage counter and change
- * its autosuspend state.
- */
-static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt)
+	/* Remote wakeup is needed only when we actually go to sleep.
+	 * For things like FREEZE and QUIESCE, if the device is already
+	 * autosuspended then its current wakeup setting is okay.
+	 */
+	if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_QUIESCE) {
+		if (udev->state != USB_STATE_SUSPENDED)
+			udev->do_remote_wakeup = 0;
+		return;
+	}
+
+	/* If remote wakeup is permitted, see whether any interface drivers
+	 * actually want it.
+	 */
+	w = 0;
+	if (device_may_wakeup(&udev->dev) && udev->actconfig) {
+		for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
+			intf = udev->actconfig->interface[i];
+			w |= intf->needs_remote_wakeup;
+		}
+	}
+
+	/* If the device is autosuspended with the wrong wakeup setting,
+	 * autoresume now so the setting can be changed.
+	 */
+	if (udev->state == USB_STATE_SUSPENDED && w != udev->do_remote_wakeup)
+		pm_runtime_resume(&udev->dev);
+	udev->do_remote_wakeup = w;
+}
+
+/* The device lock is held by the PM core */
+int usb_suspend(struct device *dev, pm_message_t msg)
 {
-	int	status = 0;
+	struct usb_device	*udev = to_usb_device(dev);
 
-	usb_pm_lock(udev);
-	udev->pm_usage_cnt += inc_usage_cnt;
-	WARN_ON(udev->pm_usage_cnt < 0);
-	if (inc_usage_cnt)
-		udev->last_busy = jiffies;
-	if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) {
-		if (udev->state == USB_STATE_SUSPENDED)
-			status = usb_resume_both(udev, PMSG_AUTO_RESUME);
-		if (status != 0)
-			udev->pm_usage_cnt -= inc_usage_cnt;
-		else if (inc_usage_cnt)
+	do_unbind_rebind(udev, DO_UNBIND);
+	choose_wakeup(udev, msg);
+	return usb_suspend_both(udev, msg);
+}
+
+/* The device lock is held by the PM core */
+int usb_resume(struct device *dev, pm_message_t msg)
+{
+	struct usb_device	*udev = to_usb_device(dev);
+	int			status;
+
+	/* For PM complete calls, all we do is rebind interfaces */
+	if (msg.event == PM_EVENT_ON) {
+		if (udev->state != USB_STATE_NOTATTACHED)
+			do_unbind_rebind(udev, DO_REBIND);
+		status = 0;
+
+	/* For all other calls, take the device back to full power and
+	 * tell the PM core in case it was autosuspended previously.
+	 */
+	} else {
+		status = usb_resume_both(udev, msg);
+		if (status == 0) {
+			pm_runtime_disable(dev);
+			pm_runtime_set_active(dev);
+			pm_runtime_enable(dev);
 			udev->last_busy = jiffies;
-	} else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) {
-		status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
+		}
 	}
-	usb_pm_unlock(udev);
+
+	/* Avoid PM error messages for devices disconnected while suspended
+	 * as we'll display regular disconnect messages just a bit later.
+	 */
+	if (status == -ENODEV)
+		status = 0;
 	return status;
 }
 
-/* usb_autosuspend_work - callback routine to autosuspend a USB device */
-void usb_autosuspend_work(struct work_struct *work)
-{
-	struct usb_device *udev =
-		container_of(work, struct usb_device, autosuspend.work);
+#endif /* CONFIG_PM */
 
-	usb_autopm_do_device(udev, 0);
+#ifdef CONFIG_USB_SUSPEND
+
+/**
+ * usb_enable_autosuspend - allow a USB device to be autosuspended
+ * @udev: the USB device which may be autosuspended
+ *
+ * This routine allows @udev to be autosuspended.  An autosuspend won't
+ * take place until the autosuspend_delay has elapsed and all the other
+ * necessary conditions are satisfied.
+ *
+ * The caller must hold @udev's device lock.
+ */
+int usb_enable_autosuspend(struct usb_device *udev)
+{
+	if (udev->autosuspend_disabled) {
+		udev->autosuspend_disabled = 0;
+		usb_autosuspend_device(udev);
+	}
+	return 0;
 }
+EXPORT_SYMBOL_GPL(usb_enable_autosuspend);
 
-/* usb_autoresume_work - callback routine to autoresume a USB device */
-void usb_autoresume_work(struct work_struct *work)
+/**
+ * usb_disable_autosuspend - prevent a USB device from being autosuspended
+ * @udev: the USB device which may not be autosuspended
+ *
+ * This routine prevents @udev from being autosuspended and wakes it up
+ * if it is already autosuspended.
+ *
+ * The caller must hold @udev's device lock.
+ */
+int usb_disable_autosuspend(struct usb_device *udev)
 {
-	struct usb_device *udev =
-		container_of(work, struct usb_device, autoresume);
+	int rc = 0;
 
-	/* Wake it up, let the drivers do their thing, and then put it
-	 * back to sleep.
-	 */
-	if (usb_autopm_do_device(udev, 1) == 0)
-		usb_autopm_do_device(udev, -1);
+	if (!udev->autosuspend_disabled) {
+		rc = usb_autoresume_device(udev);
+		if (rc == 0)
+			udev->autosuspend_disabled = 1;
+	}
+	return rc;
 }
+EXPORT_SYMBOL_GPL(usb_disable_autosuspend);
 
 /**
  * usb_autosuspend_device - delayed autosuspend of a USB device and its interfaces
@@ -1464,15 +1395,11 @@ void usb_autoresume_work(struct work_str
  * @udev and wants to allow it to autosuspend.  Examples would be when
  * @udev's device file in usbfs is closed or after a configuration change.
  *
- * @udev's usage counter is decremented.  If it or any of the usage counters
- * for an active interface is greater than 0, no autosuspend request will be
- * queued.  (If an interface driver does not support autosuspend then its
- * usage counter is permanently positive.)  Furthermore, if an interface
- * driver requires remote-wakeup capability during autosuspend but remote
- * wakeup is disabled, the autosuspend will fail.
+ * @udev's usage counter is decremented; if it drops to 0 and all the
+ * interfaces are inactive then a delayed autosuspend will be attempted.
+ * The attempt may fail (see autosuspend_check()).
  *
- * Often the caller will hold @udev's device lock, but this is not
- * necessary.
+ * The caller must hold @udev's device lock.
  *
  * This routine can run only in process context.
  */
@@ -1480,9 +1407,11 @@ void usb_autosuspend_device(struct usb_d
 {
 	int	status;
 
-	status = usb_autopm_do_device(udev, -1);
-	dev_vdbg(&udev->dev, "%s: cnt %d\n",
-			__func__, udev->pm_usage_cnt);
+	udev->last_busy = jiffies;
+	status = pm_runtime_put_sync(&udev->dev);
+	dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n",
+			__func__, atomic_read(&udev->dev.power.usage_count),
+			status);
 }
 
 /**
@@ -1492,17 +1421,22 @@ void usb_autosuspend_device(struct usb_d
  * This routine should be called when a core subsystem thinks @udev may
  * be ready to autosuspend.
  *
- * @udev's usage counter left unchanged.  If it or any of the usage counters
- * for an active interface is greater than 0, or autosuspend is not allowed
- * for any other reason, no autosuspend request will be queued.
+ * @udev's usage counter left unchanged.  If it is 0 and all the interfaces
+ * are inactive then an autosuspend will be attempted.  The attempt may
+ * fail or be delayed.
+ *
+ * The caller must hold @udev's device lock.
  *
  * This routine can run only in process context.
  */
 void usb_try_autosuspend_device(struct usb_device *udev)
 {
-	usb_autopm_do_device(udev, 0);
-	dev_vdbg(&udev->dev, "%s: cnt %d\n",
-			__func__, udev->pm_usage_cnt);
+	int	status;
+
+	status = pm_runtime_idle(&udev->dev);
+	dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n",
+			__func__, atomic_read(&udev->dev.power.usage_count),
+			status);
 }
 
 /**
@@ -1511,16 +1445,15 @@ void usb_try_autosuspend_device(struct u
  *
  * This routine should be called when a core subsystem wants to use @udev
  * and needs to guarantee that it is not suspended.  No autosuspend will
- * occur until usb_autosuspend_device is called.  (Note that this will not
- * prevent suspend events originating in the PM core.)  Examples would be
- * when @udev's device file in usbfs is opened or when a remote-wakeup
+ * occur until usb_autosuspend_device() is called.  (Note that this will
+ * not prevent suspend events originating in the PM core.)  Examples would
+ * be when @udev's device file in usbfs is opened or when a remote-wakeup
  * request is received.
  *
  * @udev's usage counter is incremented to prevent subsequent autosuspends.
  * However if the autoresume fails then the usage counter is re-decremented.
  *
- * Often the caller will hold @udev's device lock, but this is not
- * necessary (and attempting it might cause deadlock).
+ * The caller must hold @udev's device lock.
  *
  * This routine can run only in process context.
  */
@@ -1528,42 +1461,14 @@ int usb_autoresume_device(struct usb_dev
 {
 	int	status;
 
-	status = usb_autopm_do_device(udev, 1);
-	dev_vdbg(&udev->dev, "%s: status %d cnt %d\n",
-			__func__, status, udev->pm_usage_cnt);
-	return status;
-}
-
-/* Internal routine to adjust an interface's usage counter and change
- * its device's autosuspend state.
- */
-static int usb_autopm_do_interface(struct usb_interface *intf,
-		int inc_usage_cnt)
-{
-	struct usb_device	*udev = interface_to_usbdev(intf);
-	int			status = 0;
-
-	usb_pm_lock(udev);
-	if (intf->condition == USB_INTERFACE_UNBOUND)
-		status = -ENODEV;
-	else {
-		atomic_add(inc_usage_cnt, &intf->pm_usage_cnt);
-		udev->last_busy = jiffies;
-		if (inc_usage_cnt >= 0 &&
-				atomic_read(&intf->pm_usage_cnt) > 0) {
-			if (udev->state == USB_STATE_SUSPENDED)
-				status = usb_resume_both(udev,
-						PMSG_AUTO_RESUME);
-			if (status != 0)
-				atomic_sub(inc_usage_cnt, &intf->pm_usage_cnt);
-			else
-				udev->last_busy = jiffies;
-		} else if (inc_usage_cnt <= 0 &&
-				atomic_read(&intf->pm_usage_cnt) <= 0) {
-			status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
-		}
-	}
-	usb_pm_unlock(udev);
+	status = pm_runtime_get_sync(&udev->dev);
+	if (status < 0)
+		pm_runtime_put_sync(&udev->dev);
+	dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n",
+			__func__, atomic_read(&udev->dev.power.usage_count),
+			status);
+	if (status > 0)
+		status = 0;
 	return status;
 }
 
@@ -1577,34 +1482,25 @@ static int usb_autopm_do_interface(struc
  * closed.
  *
  * The routine decrements @intf's usage counter.  When the counter reaches
- * 0, a delayed autosuspend request for @intf's device is queued.  When
- * the delay expires, if @intf->pm_usage_cnt is still <= 0 along with all
- * the other usage counters for the sibling interfaces and @intf's
- * usb_device, the device and all its interfaces will be autosuspended.
- *
- * Note that @intf->pm_usage_cnt is owned by the interface driver.  The
- * core will not change its value other than the increment and decrement
- * in usb_autopm_get_interface and usb_autopm_put_interface.  The driver
- * may use this simple counter-oriented discipline or may set the value
- * any way it likes.
+ * 0, a delayed autosuspend request for @intf's device is attempted.  The
+ * attempt may fail (see autosuspend_check()).
  *
  * If the driver has set @intf->needs_remote_wakeup then autosuspend will
  * take place only if the device's remote-wakeup facility is enabled.
  *
- * Suspend method calls queued by this routine can arrive at any time
- * while @intf is resumed and its usage counter is equal to 0.  They are
- * not protected by the usb_device's lock but only by its pm_mutex.
- * Drivers must provide their own synchronization.
- *
  * This routine can run only in process context.
  */
 void usb_autopm_put_interface(struct usb_interface *intf)
 {
-	int	status;
+	struct usb_device	*udev = interface_to_usbdev(intf);
+	int			status;
 
-	status = usb_autopm_do_interface(intf, -1);
-	dev_vdbg(&intf->dev, "%s: status %d cnt %d\n",
-			__func__, status, atomic_read(&intf->pm_usage_cnt));
+	udev->last_busy = jiffies;
+	atomic_dec(&intf->pm_usage_cnt);
+	status = pm_runtime_put_sync(&intf->dev);
+	dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n",
+			__func__, atomic_read(&intf->dev.power.usage_count),
+			status);
 }
 EXPORT_SYMBOL_GPL(usb_autopm_put_interface);
 
@@ -1612,11 +1508,11 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interfa
  * usb_autopm_put_interface_async - decrement a USB interface's PM-usage counter
  * @intf: the usb_interface whose counter should be decremented
  *
- * This routine does essentially the same thing as
- * usb_autopm_put_interface(): it decrements @intf's usage counter and
- * queues a delayed autosuspend request if the counter is <= 0.  The
- * difference is that it does not acquire the device's pm_mutex;
- * callers must handle all synchronization issues themselves.
+ * This routine does much the same thing as usb_autopm_put_interface():
+ * It decrements @intf's usage counter and schedules a delayed
+ * autosuspend request if the counter is <= 0.  The difference is that it
+ * does not perform any synchronization; callers should hold a private
+ * lock and handle all synchronization issues themselves.
  *
  * Typically a driver would call this routine during an URB's completion
  * handler, if no more URBs were pending.
@@ -1626,28 +1522,58 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interfa
 void usb_autopm_put_interface_async(struct usb_interface *intf)
 {
 	struct usb_device	*udev = interface_to_usbdev(intf);
+	unsigned long		last_busy;
 	int			status = 0;
 
-	if (intf->condition == USB_INTERFACE_UNBOUND) {
-		status = -ENODEV;
-	} else {
-		udev->last_busy = jiffies;
-		atomic_dec(&intf->pm_usage_cnt);
-		if (udev->autosuspend_disabled || udev->autosuspend_delay < 0)
-			status = -EPERM;
-		else if (atomic_read(&intf->pm_usage_cnt) <= 0 &&
-				!timer_pending(&udev->autosuspend.timer)) {
-			queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
+	last_busy = udev->last_busy;
+	udev->last_busy = jiffies;
+	atomic_dec(&intf->pm_usage_cnt);
+	pm_runtime_put_noidle(&intf->dev);
+
+	if (!udev->autosuspend_disabled) {
+		/* Optimization: Don't schedule a delayed autosuspend if
+		 * the timer is already running and the expiration time
+		 * wouldn't change.
+		 *
+		 * We have to use the interface's timer.  Attempts to
+		 * schedule a suspend for the device would fail because
+		 * the interface is still active.
+		 */
+		if (intf->dev.power.timer_expires == 0 ||
+				round_jiffies_up(last_busy) !=
+				round_jiffies_up(jiffies)) {
+			status = pm_schedule_suspend(&intf->dev,
+					jiffies_to_msecs(
 					round_jiffies_up_relative(
-						udev->autosuspend_delay));
+						udev->autosuspend_delay)));
 		}
 	}
-	dev_vdbg(&intf->dev, "%s: status %d cnt %d\n",
-			__func__, status, atomic_read(&intf->pm_usage_cnt));
+	dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n",
+			__func__, atomic_read(&intf->dev.power.usage_count),
+			status);
 }
 EXPORT_SYMBOL_GPL(usb_autopm_put_interface_async);
 
 /**
+ * usb_autopm_put_interface_no_suspend - decrement a USB interface's PM-usage counter
+ * @intf: the usb_interface whose counter should be decremented
+ *
+ * This routine decrements @intf's usage counter but does not carry out an
+ * autosuspend.
+ *
+ * This routine can run in atomic context.
+ */
+void usb_autopm_put_interface_no_suspend(struct usb_interface *intf)
+{
+	struct usb_device	*udev = interface_to_usbdev(intf);
+
+	udev->last_busy = jiffies;
+	atomic_dec(&intf->pm_usage_cnt);
+	pm_runtime_put_noidle(&intf->dev);
+}
+EXPORT_SYMBOL_GPL(usb_autopm_put_interface_no_suspend);
+
+/**
  * usb_autopm_get_interface - increment a USB interface's PM-usage counter
  * @intf: the usb_interface whose counter should be incremented
  *
@@ -1659,25 +1585,8 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interfa
  * or @intf is unbound.  A typical example would be a character-device
  * driver when its device file is opened.
  *
- *
- * The routine increments @intf's usage counter.  (However if the
- * autoresume fails then the counter is re-decremented.)  So long as the
- * counter is greater than 0, autosuspend will not be allowed for @intf
- * or its usb_device.  When the driver is finished using @intf it should
- * call usb_autopm_put_interface() to decrement the usage counter and
- * queue a delayed autosuspend request (if the counter is <= 0).
- *
- *
- * Note that @intf->pm_usage_cnt is owned by the interface driver.  The
- * core will not change its value other than the increment and decrement
- * in usb_autopm_get_interface and usb_autopm_put_interface.  The driver
- * may use this simple counter-oriented discipline or may set the value
- * any way it likes.
- *
- * Resume method calls generated by this routine can arrive at any time
- * while @intf is suspended.  They are not protected by the usb_device's
- * lock but only by its pm_mutex.  Drivers must provide their own
- * synchronization.
+ * @intf's usage counter is incremented to prevent subsequent autosuspends.
+ * However if the autoresume fails then the counter is re-decremented.
  *
  * This routine can run only in process context.
  */
@@ -1685,9 +1594,16 @@ int usb_autopm_get_interface(struct usb_
 {
 	int	status;
 
-	status = usb_autopm_do_interface(intf, 1);
-	dev_vdbg(&intf->dev, "%s: status %d cnt %d\n",
-			__func__, status, atomic_read(&intf->pm_usage_cnt));
+	status = pm_runtime_get_sync(&intf->dev);
+	if (status < 0)
+		pm_runtime_put_sync(&intf->dev);
+	else
+		atomic_inc(&intf->pm_usage_cnt);
+	dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n",
+			__func__, atomic_read(&intf->dev.power.usage_count),
+			status);
+	if (status > 0)
+		status = 0;
 	return status;
 }
 EXPORT_SYMBOL_GPL(usb_autopm_get_interface);
@@ -1697,149 +1613,207 @@ EXPORT_SYMBOL_GPL(usb_autopm_get_interfa
  * @intf: the usb_interface whose counter should be incremented
  *
  * This routine does much the same thing as
- * usb_autopm_get_interface(): it increments @intf's usage counter and
- * queues an autoresume request if the result is > 0.  The differences
- * are that it does not acquire the device's pm_mutex (callers must
- * handle all synchronization issues themselves), and it does not
- * autoresume the device directly (it only queues a request).  After a
- * successful call, the device will generally not yet be resumed.
+ * usb_autopm_get_interface(): It increments @intf's usage counter and
+ * queues an autoresume request if the device is suspended.  The
+ * differences are that it does not perform any synchronization (callers
+ * should hold a private lock and handle all synchronization issues
+ * themselves), and it does not autoresume the device directly (it only
+ * queues a request).  After a successful call, the device may not yet be
+ * resumed.
  *
  * This routine can run in atomic context.
  */
 int usb_autopm_get_interface_async(struct usb_interface *intf)
 {
-	struct usb_device	*udev = interface_to_usbdev(intf);
-	int			status = 0;
+	int		status = 0;
+	enum rpm_status	s;
 
-	if (intf->condition == USB_INTERFACE_UNBOUND)
-		status = -ENODEV;
-	else {
+	/* Don't request a resume unless the interface is already suspending
+	 * or suspended.  Doing so would force a running suspend timer to be
+	 * cancelled.
+	 */
+	pm_runtime_get_noresume(&intf->dev);
+	s = ACCESS_ONCE(intf->dev.power.runtime_status);
+	if (s == RPM_SUSPENDING || s == RPM_SUSPENDED)
+		status = pm_request_resume(&intf->dev);
+
+	if (status < 0 && status != -EINPROGRESS)
+		pm_runtime_put_noidle(&intf->dev);
+	else
 		atomic_inc(&intf->pm_usage_cnt);
-		if (atomic_read(&intf->pm_usage_cnt) > 0 &&
-				udev->state == USB_STATE_SUSPENDED)
-			queue_work(ksuspend_usb_wq, &udev->autoresume);
-	}
-	dev_vdbg(&intf->dev, "%s: status %d cnt %d\n",
-			__func__, status, atomic_read(&intf->pm_usage_cnt));
+	dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n",
+			__func__, atomic_read(&intf->dev.power.usage_count),
+			status);
+	if (status > 0)
+		status = 0;
 	return status;
 }
 EXPORT_SYMBOL_GPL(usb_autopm_get_interface_async);
 
-#else
-
-void usb_autosuspend_work(struct work_struct *work)
-{}
-
-void usb_autoresume_work(struct work_struct *work)
-{}
-
-#endif /* CONFIG_USB_SUSPEND */
-
 /**
- * usb_external_suspend_device - external suspend of a USB device and its interfaces
- * @udev: the usb_device to suspend
- * @msg: Power Management message describing this state transition
+ * usb_autopm_get_interface_no_resume - increment a USB interface's PM-usage counter
+ * @intf: the usb_interface whose counter should be incremented
  *
- * This routine handles external suspend requests: ones not generated
- * internally by a USB driver (autosuspend) but rather coming from the user
- * (via sysfs) or the PM core (system sleep).  The suspend will be carried
- * out regardless of @udev's usage counter or those of its interfaces,
- * and regardless of whether or not remote wakeup is enabled.  Of course,
- * interface drivers still have the option of failing the suspend (if
- * there are unsuspended children, for example).
+ * This routine increments @intf's usage counter but does not carry out an
+ * autoresume.
  *
- * The caller must hold @udev's device lock.
+ * This routine can run in atomic context.
  */
-int usb_external_suspend_device(struct usb_device *udev, pm_message_t msg)
+void usb_autopm_get_interface_no_resume(struct usb_interface *intf)
 {
-	int	status;
+	struct usb_device	*udev = interface_to_usbdev(intf);
 
-	do_unbind_rebind(udev, DO_UNBIND);
-	usb_pm_lock(udev);
-	status = usb_suspend_both(udev, msg);
-	usb_pm_unlock(udev);
-	return status;
+	udev->last_busy = jiffies;
+	atomic_inc(&intf->pm_usage_cnt);
+	pm_runtime_get_noresume(&intf->dev);
 }
+EXPORT_SYMBOL_GPL(usb_autopm_get_interface_no_resume);
 
-/**
- * usb_external_resume_device - external resume of a USB device and its interfaces
- * @udev: the usb_device to resume
- * @msg: Power Management message describing this state transition
- *
- * This routine handles external resume requests: ones not generated
- * internally by a USB driver (autoresume) but rather coming from the user
- * (via sysfs), the PM core (system resume), or the device itself (remote
- * wakeup).  @udev's usage counter is unaffected.
- *
- * The caller must hold @udev's device lock.
- */
-int usb_external_resume_device(struct usb_device *udev, pm_message_t msg)
+/* Internal routine to check whether we may autosuspend a device. */
+static int autosuspend_check(struct usb_device *udev)
 {
-	int	status;
+	int			i;
+	struct usb_interface	*intf;
+	unsigned long		suspend_time, j;
 
-	usb_pm_lock(udev);
-	status = usb_resume_both(udev, msg);
-	udev->last_busy = jiffies;
-	usb_pm_unlock(udev);
-	if (status == 0)
-		do_unbind_rebind(udev, DO_REBIND);
+	/* Fail if autosuspend is disabled, or any interfaces are in use, or
+	 * any interface drivers require remote wakeup but it isn't available.
+	 */
+	udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
+	if (udev->actconfig) {
+		for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
+			intf = udev->actconfig->interface[i];
 
-	/* Now that the device is awake, we can start trying to autosuspend
-	 * it again. */
-	if (status == 0)
-		usb_try_autosuspend_device(udev);
-	return status;
+			/* We don't need to check interfaces that are
+			 * disabled for runtime PM.  Either they are unbound
+			 * or else their drivers don't support autosuspend
+			 * and so they are permanently active.
+			 */
+			if (intf->dev.power.disable_depth)
+				continue;
+			if (atomic_read(&intf->dev.power.usage_count) > 0)
+				return -EBUSY;
+			if (intf->needs_remote_wakeup &&
+					!udev->do_remote_wakeup) {
+				dev_dbg(&udev->dev, "remote wakeup needed "
+						"for autosuspend\n");
+				return -EOPNOTSUPP;
+			}
+
+			/* Don't allow autosuspend if the device will need
+			 * a reset-resume and any of its interface drivers
+			 * doesn't include support or needs remote wakeup.
+			 */
+			if (udev->quirks & USB_QUIRK_RESET_RESUME) {
+				struct usb_driver *driver;
+
+				driver = to_usb_driver(intf->dev.driver);
+				if (!driver->reset_resume ||
+						intf->needs_remote_wakeup)
+					return -EOPNOTSUPP;
+			}
+		}
+	}
+
+	/* If everything is okay but the device hasn't been idle for long
+	 * enough, queue a delayed autosuspend request.
+	 */
+	j = ACCESS_ONCE(jiffies);
+	suspend_time = udev->last_busy + udev->autosuspend_delay;
+	if (time_before(j, suspend_time)) {
+		pm_schedule_suspend(&udev->dev, jiffies_to_msecs(
+				round_jiffies_up_relative(suspend_time - j)));
+		return -EAGAIN;
+	}
+	return 0;
 }
 
-int usb_suspend(struct device *dev, pm_message_t msg)
+static int usb_runtime_suspend(struct device *dev)
 {
-	struct usb_device	*udev;
-
-	udev = to_usb_device(dev);
+	int	status = 0;
 
-	/* If udev is already suspended, we can skip this suspend and
-	 * we should also skip the upcoming system resume.  High-speed
-	 * root hubs are an exception; they need to resume whenever the
-	 * system wakes up in order for USB-PERSIST port handover to work
-	 * properly.
+	/* A USB device can be suspended if it passes the various autosuspend
+	 * checks.  Runtime suspend for a USB device means suspending all the
+	 * interfaces and then the device itself.
 	 */
-	if (udev->state == USB_STATE_SUSPENDED) {
-		if (udev->parent || udev->speed != USB_SPEED_HIGH)
-			udev->skip_sys_resume = 1;
-		return 0;
+	if (is_usb_device(dev)) {
+		struct usb_device	*udev = to_usb_device(dev);
+
+		if (autosuspend_check(udev) != 0)
+			return -EAGAIN;
+
+		status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
+
+		/* If an interface fails the suspend, adjust the last_busy
+		 * time so that we don't get another suspend attempt right
+		 * away.
+		 */
+		if (status) {
+			udev->last_busy = jiffies +
+					(udev->autosuspend_delay == 0 ?
+						HZ/2 : 0);
+		}
+
+		/* Prevent the parent from suspending immediately after */
+		else if (udev->parent) {
+			udev->parent->last_busy = jiffies;
+		}
 	}
 
-	udev->skip_sys_resume = 0;
-	return usb_external_suspend_device(udev, msg);
+	/* Runtime suspend for a USB interface doesn't mean anything. */
+	return status;
 }
 
-int usb_resume(struct device *dev, pm_message_t msg)
+static int usb_runtime_resume(struct device *dev)
 {
-	struct usb_device	*udev;
-	int			status;
+	/* Runtime resume for a USB device means resuming both the device
+	 * and all its interfaces.
+	 */
+	if (is_usb_device(dev)) {
+		struct usb_device	*udev = to_usb_device(dev);
+		int			status;
 
-	udev = to_usb_device(dev);
+		status = usb_resume_both(udev, PMSG_AUTO_RESUME);
+		udev->last_busy = jiffies;
+		return status;
+	}
 
-	/* If udev->skip_sys_resume is set then udev was already suspended
-	 * when the system sleep started, so we don't want to resume it
-	 * during this system wakeup.
-	 */
-	if (udev->skip_sys_resume)
-		return 0;
-	status = usb_external_resume_device(udev, msg);
+	/* Runtime resume for a USB interface doesn't mean anything. */
+	return 0;
+}
 
-	/* Avoid PM error messages for devices disconnected while suspended
-	 * as we'll display regular disconnect messages just a bit later.
+static int usb_runtime_idle(struct device *dev)
+{
+	/* An idle USB device can be suspended if it passes the various
+	 * autosuspend checks.  An idle interface can be suspended at
+	 * any time.
 	 */
-	if (status == -ENODEV)
-		return 0;
-	return status;
+	if (is_usb_device(dev)) {
+		struct usb_device	*udev = to_usb_device(dev);
+
+		if (autosuspend_check(udev) != 0)
+			return 0;
+	}
+
+	pm_runtime_suspend(dev);
+	return 0;
 }
 
-#endif /* CONFIG_PM */
+static struct dev_pm_ops usb_bus_pm_ops = {
+	.runtime_suspend =	usb_runtime_suspend,
+	.runtime_resume =	usb_runtime_resume,
+	.runtime_idle =		usb_runtime_idle,
+};
+
+#else
+
+#define usb_bus_pm_ops	(*(struct dev_pm_ops *) NULL)
+
+#endif /* CONFIG_USB_SUSPEND */
 
 struct bus_type usb_bus_type = {
 	.name =		"usb",
 	.match =	usb_device_match,
 	.uevent =	usb_uevent,
+	.pm =		&usb_bus_pm_ops,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/endpoint.c linux-libre-2.6.34-gnu1/drivers/usb/core/endpoint.c
--- linux-libre-2.6.33-gnu1/drivers/usb/core/endpoint.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/endpoint.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/idr.h>
 #include <linux/usb.h>
 #include "usb.h"
@@ -186,6 +187,7 @@ int usb_create_ep_devs(struct device *pa
 	ep_dev->dev.parent = parent;
 	ep_dev->dev.release = ep_device_release;
 	dev_set_name(&ep_dev->dev, "ep_%02x", endpoint->desc.bEndpointAddress);
+	device_enable_async_suspend(&ep_dev->dev);
 
 	retval = device_register(&ep_dev->dev);
 	if (retval)
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/file.c linux-libre-2.6.34-gnu1/drivers/usb/core/file.c
--- linux-libre-2.6.33-gnu1/drivers/usb/core/file.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/file.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/rwsem.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/usb.h>
 
@@ -34,7 +35,6 @@ static int usb_open(struct inode * inode
 	int err = -ENODEV;
 	const struct file_operations *old_fops, *new_fops = NULL;
 
-	lock_kernel();
 	down_read(&minor_rwsem);
 	c = usb_minors[minor];
 
@@ -53,7 +53,6 @@ static int usb_open(struct inode * inode
 	fops_put(old_fops);
  done:
 	up_read(&minor_rwsem);
-	unlock_kernel();
 	return err;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/generic.c linux-libre-2.6.34-gnu1/drivers/usb/core/generic.c
--- linux-libre-2.6.33-gnu1/drivers/usb/core/generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -120,7 +120,7 @@ int usb_choose_configuration(struct usb_
 		 * than a vendor-specific driver. */
 		else if (udev->descriptor.bDeviceClass !=
 						USB_CLASS_VENDOR_SPEC &&
-				(!desc || desc->bInterfaceClass !=
+				(desc && desc->bInterfaceClass !=
 						USB_CLASS_VENDOR_SPEC)) {
 			best = c;
 			break;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/hcd.c linux-libre-2.6.34-gnu1/drivers/usb/core/hcd.c
--- linux-libre-2.6.33-gnu1/drivers/usb/core/hcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/hcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/platform_device.h>
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
+#include <linux/pm_runtime.h>
 
 #include <linux/usb.h>
 
@@ -141,7 +142,7 @@ static const u8 usb3_rh_dev_descriptor[1
 	0x09,       /*  __u8  bMaxPacketSize0; 2^9 = 512 Bytes */
 
 	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation */
-	0x02, 0x00, /*  __le16 idProduct; device 0x0002 */
+	0x03, 0x00, /*  __le16 idProduct; device 0x0003 */
 	KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */
 
 	0x03,       /*  __u8  iManufacturer; */
@@ -1670,11 +1671,16 @@ int usb_hcd_alloc_bandwidth(struct usb_d
 			}
 		}
 		for (i = 0; i < num_intfs; ++i) {
+			struct usb_host_interface *first_alt;
+			int iface_num;
+
+			first_alt = &new_config->intf_cache[i]->altsetting[0];
+			iface_num = first_alt->desc.bInterfaceNumber;
 			/* Set up endpoints for alternate interface setting 0 */
-			alt = usb_find_alt_setting(new_config, i, 0);
+			alt = usb_find_alt_setting(new_config, iface_num, 0);
 			if (!alt)
 				/* No alt setting 0? Pick the first setting. */
-				alt = &new_config->intf_cache[i]->altsetting[0];
+				alt = first_alt;
 
 			for (j = 0; j < alt->desc.bNumEndpoints; j++) {
 				ret = hcd->driver->add_endpoint(hcd, udev, &alt->endpoint[j]);
@@ -1853,6 +1859,10 @@ int hcd_bus_resume(struct usb_device *rh
 	return status;
 }
 
+#endif	/* CONFIG_PM */
+
+#ifdef	CONFIG_USB_SUSPEND
+
 /* Workqueue routine for root-hub remote wakeup */
 static void hcd_resume_work(struct work_struct *work)
 {
@@ -1860,8 +1870,7 @@ static void hcd_resume_work(struct work_
 	struct usb_device *udev = hcd->self.root_hub;
 
 	usb_lock_device(udev);
-	usb_mark_last_busy(udev);
-	usb_external_resume_device(udev, PMSG_REMOTE_RESUME);
+	usb_remote_wakeup(udev);
 	usb_unlock_device(udev);
 }
 
@@ -1880,12 +1889,12 @@ void usb_hcd_resume_root_hub (struct usb
 
 	spin_lock_irqsave (&hcd_root_hub_lock, flags);
 	if (hcd->rh_registered)
-		queue_work(ksuspend_usb_wq, &hcd->wakeup_work);
+		queue_work(pm_wq, &hcd->wakeup_work);
 	spin_unlock_irqrestore (&hcd_root_hub_lock, flags);
 }
 EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub);
 
-#endif
+#endif	/* CONFIG_USB_SUSPEND */
 
 /*-------------------------------------------------------------------------*/
 
@@ -2030,7 +2039,7 @@ struct usb_hcd *usb_create_hcd (const st
 	init_timer(&hcd->rh_timer);
 	hcd->rh_timer.function = rh_timer_func;
 	hcd->rh_timer.data = (unsigned long) hcd;
-#ifdef CONFIG_PM
+#ifdef CONFIG_USB_SUSPEND
 	INIT_WORK(&hcd->wakeup_work, hcd_resume_work);
 #endif
 	mutex_init(&hcd->bandwidth_mutex);
@@ -2230,7 +2239,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
 	hcd->rh_registered = 0;
 	spin_unlock_irq (&hcd_root_hub_lock);
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_USB_SUSPEND
 	cancel_work_sync(&hcd->wakeup_work);
 #endif
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/hcd.h linux-libre-2.6.34-gnu1/drivers/usb/core/hcd.h
--- linux-libre-2.6.33-gnu1/drivers/usb/core/hcd.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/hcd.h	2010-05-16 17:17:36.000000000 -0400
@@ -80,7 +80,7 @@ struct usb_hcd {
 
 	struct timer_list	rh_timer;	/* drives root-hub polling */
 	struct urb		*status_urb;	/* the current status urb */
-#ifdef CONFIG_PM
+#ifdef CONFIG_USB_SUSPEND
 	struct work_struct	wakeup_work;	/* for remote wakeup */
 #endif
 
@@ -248,7 +248,7 @@ struct hc_driver {
 	/* xHCI specific functions */
 		/* Called by usb_alloc_dev to alloc HC device structures */
 	int	(*alloc_dev)(struct usb_hcd *, struct usb_device *);
-		/* Called by usb_release_dev to free HC device structures */
+		/* Called by usb_disconnect to free HC device structures */
 	void	(*free_dev)(struct usb_hcd *, struct usb_device *);
 
 	/* Bandwidth computation functions */
@@ -286,6 +286,7 @@ struct hc_driver {
 		 */
 	int	(*update_hub_device)(struct usb_hcd *, struct usb_device *hdev,
 			struct usb_tt *tt, gfp_t mem_flags);
+	int	(*reset_device)(struct usb_hcd *, struct usb_device *);
 };
 
 extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
@@ -463,16 +464,20 @@ extern int usb_find_interface_driver(str
 #define usb_endpoint_out(ep_dir)	(!((ep_dir) & USB_DIR_IN))
 
 #ifdef CONFIG_PM
-extern void usb_hcd_resume_root_hub(struct usb_hcd *hcd);
 extern void usb_root_hub_lost_power(struct usb_device *rhdev);
 extern int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg);
 extern int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg);
+#endif /* CONFIG_PM */
+
+#ifdef CONFIG_USB_SUSPEND
+extern void usb_hcd_resume_root_hub(struct usb_hcd *hcd);
 #else
 static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd)
 {
 	return;
 }
-#endif /* CONFIG_PM */
+#endif /* CONFIG_USB_SUSPEND */
+
 
 /*
  * USB device fs stuff
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/hcd-pci.c linux-libre-2.6.34-gnu1/drivers/usb/core/hcd-pci.c
--- linux-libre-2.6.33-gnu1/drivers/usb/core/hcd-pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/hcd-pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/pm_runtime.h>
 #include <linux/usb.h>
 
 #include <asm/io.h>
@@ -37,6 +38,122 @@
 
 /* PCI-based HCs are common, but plenty of non-PCI HCs are used too */
 
+#ifdef CONFIG_PM_SLEEP
+
+/* Coordinate handoffs between EHCI and companion controllers
+ * during system resume
+ */
+
+static DEFINE_MUTEX(companions_mutex);
+
+#define CL_UHCI		PCI_CLASS_SERIAL_USB_UHCI
+#define CL_OHCI		PCI_CLASS_SERIAL_USB_OHCI
+#define CL_EHCI		PCI_CLASS_SERIAL_USB_EHCI
+
+enum companion_action {
+	SET_HS_COMPANION, CLEAR_HS_COMPANION, WAIT_FOR_COMPANIONS
+};
+
+static void companion_common(struct pci_dev *pdev, struct usb_hcd *hcd,
+		enum companion_action action)
+{
+	struct pci_dev		*companion;
+	struct usb_hcd		*companion_hcd;
+	unsigned int		slot = PCI_SLOT(pdev->devfn);
+
+	/* Iterate through other PCI functions in the same slot.
+	 * If pdev is OHCI or UHCI then we are looking for EHCI, and
+	 * vice versa.
+	 */
+	companion = NULL;
+	for (;;) {
+		companion = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, companion);
+		if (!companion)
+			break;
+		if (companion->bus != pdev->bus ||
+				PCI_SLOT(companion->devfn) != slot)
+			continue;
+
+		companion_hcd = pci_get_drvdata(companion);
+		if (!companion_hcd)
+			continue;
+
+		/* For SET_HS_COMPANION, store a pointer to the EHCI bus in
+		 * the OHCI/UHCI companion bus structure.
+		 * For CLEAR_HS_COMPANION, clear the pointer to the EHCI bus
+		 * in the OHCI/UHCI companion bus structure.
+		 * For WAIT_FOR_COMPANIONS, wait until the OHCI/UHCI
+		 * companion controllers have fully resumed.
+		 */
+
+		if ((pdev->class == CL_OHCI || pdev->class == CL_UHCI) &&
+				companion->class == CL_EHCI) {
+			/* action must be SET_HS_COMPANION */
+			dev_dbg(&companion->dev, "HS companion for %s\n",
+					dev_name(&pdev->dev));
+			hcd->self.hs_companion = &companion_hcd->self;
+
+		} else if (pdev->class == CL_EHCI &&
+				(companion->class == CL_OHCI ||
+				companion->class == CL_UHCI)) {
+			switch (action) {
+			case SET_HS_COMPANION:
+				dev_dbg(&pdev->dev, "HS companion for %s\n",
+						dev_name(&companion->dev));
+				companion_hcd->self.hs_companion = &hcd->self;
+				break;
+			case CLEAR_HS_COMPANION:
+				companion_hcd->self.hs_companion = NULL;
+				break;
+			case WAIT_FOR_COMPANIONS:
+				device_pm_wait_for_dev(&pdev->dev,
+						&companion->dev);
+				break;
+			}
+		}
+	}
+}
+
+static void set_hs_companion(struct pci_dev *pdev, struct usb_hcd *hcd)
+{
+	mutex_lock(&companions_mutex);
+	dev_set_drvdata(&pdev->dev, hcd);
+	companion_common(pdev, hcd, SET_HS_COMPANION);
+	mutex_unlock(&companions_mutex);
+}
+
+static void clear_hs_companion(struct pci_dev *pdev, struct usb_hcd *hcd)
+{
+	mutex_lock(&companions_mutex);
+	dev_set_drvdata(&pdev->dev, NULL);
+
+	/* If pdev is OHCI or UHCI, just clear its hs_companion pointer */
+	if (pdev->class == CL_OHCI || pdev->class == CL_UHCI)
+		hcd->self.hs_companion = NULL;
+
+	/* Otherwise search for companion buses and clear their pointers */
+	else
+		companion_common(pdev, hcd, CLEAR_HS_COMPANION);
+	mutex_unlock(&companions_mutex);
+}
+
+static void wait_for_companions(struct pci_dev *pdev, struct usb_hcd *hcd)
+{
+	/* Only EHCI controllers need to wait.
+	 * No locking is needed because a controller cannot be resumed
+	 * while one of its companions is getting unbound.
+	 */
+	if (pdev->class == CL_EHCI)
+		companion_common(pdev, hcd, WAIT_FOR_COMPANIONS);
+}
+
+#else /* !CONFIG_PM_SLEEP */
+
+static inline void set_hs_companion(struct pci_dev *d, struct usb_hcd *h) {}
+static inline void clear_hs_companion(struct pci_dev *d, struct usb_hcd *h) {}
+static inline void wait_for_companions(struct pci_dev *d, struct usb_hcd *h) {}
+
+#endif /* !CONFIG_PM_SLEEP */
 
 /*-------------------------------------------------------------------------*/
 
@@ -123,7 +240,7 @@ int usb_hcd_pci_probe(struct pci_dev *de
 		if (region == PCI_ROM_RESOURCE) {
 			dev_dbg(&dev->dev, "no i/o regions available\n");
 			retval = -EBUSY;
-			goto err1;
+			goto err2;
 		}
 	}
 
@@ -132,6 +249,7 @@ int usb_hcd_pci_probe(struct pci_dev *de
 	retval = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED);
 	if (retval != 0)
 		goto err4;
+	set_hs_companion(dev, hcd);
 	return retval;
 
  err4:
@@ -142,6 +260,7 @@ int usb_hcd_pci_probe(struct pci_dev *de
 	} else
 		release_region(hcd->rsrc_start, hcd->rsrc_len);
  err2:
+	clear_hs_companion(dev, hcd);
 	usb_put_hcd(hcd);
  err1:
 	pci_disable_device(dev);
@@ -180,6 +299,7 @@ void usb_hcd_pci_remove(struct pci_dev *
 	} else {
 		release_region(hcd->rsrc_start, hcd->rsrc_len);
 	}
+	clear_hs_companion(dev, hcd);
 	usb_put_hcd(hcd);
 	pci_disable_device(dev);
 }
@@ -344,6 +464,11 @@ static int resume_common(struct device *
 	clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
 
 	if (hcd->driver->pci_resume) {
+		/* This call should be made only during system resume,
+		 * not during runtime resume.
+		 */
+		wait_for_companions(pci_dev, hcd);
+
 		retval = hcd->driver->pci_resume(hcd, hibernated);
 		if (retval) {
 			dev_err(dev, "PCI post-resume error %d!\n", retval);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/hub.c linux-libre-2.6.34-gnu1/drivers/usb/core/hub.c
--- linux-libre-2.6.33-gnu1/drivers/usb/core/hub.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/hub.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/kthread.h>
 #include <linux/mutex.h>
 #include <linux/freezer.h>
+#include <linux/pm_runtime.h>
 
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
@@ -71,7 +72,6 @@ struct usb_hub {
 
 	unsigned		mA_per_port;	/* current for each child */
 
-	unsigned		init_done:1;
 	unsigned		limited_power:1;
 	unsigned		quiescing:1;
 	unsigned		disconnected:1;
@@ -820,7 +820,6 @@ static void hub_activate(struct usb_hub
 	}
  init3:
 	hub->quiescing = 0;
-	hub->init_done = 1;
 
 	status = usb_submit_urb(hub->urb, GFP_NOIO);
 	if (status < 0)
@@ -861,11 +860,6 @@ static void hub_quiesce(struct usb_hub *
 	int i;
 
 	cancel_delayed_work_sync(&hub->init_work);
-	if (!hub->init_done) {
-		hub->init_done = 1;
-		usb_autopm_put_interface_no_suspend(
-				to_usb_interface(hub->intfdev));
-	}
 
 	/* khubd and related activity won't re-trigger */
 	hub->quiescing = 1;
@@ -1224,6 +1218,9 @@ static int hub_probe(struct usb_interfac
 	desc = intf->cur_altsetting;
 	hdev = interface_to_usbdev(intf);
 
+	/* Hubs have proper suspend/resume support */
+	usb_enable_autosuspend(hdev);
+
 	if (hdev->level == MAX_TOPO_LEVEL) {
 		dev_err(&intf->dev,
 			"Unsupported bus topology: hub nested too deep\n");
@@ -1402,10 +1399,8 @@ static void recursively_mark_NOTATTACHED
 		if (udev->children[i])
 			recursively_mark_NOTATTACHED(udev->children[i]);
 	}
-	if (udev->state == USB_STATE_SUSPENDED) {
-		udev->discon_suspended = 1;
+	if (udev->state == USB_STATE_SUSPENDED)
 		udev->active_duration -= jiffies;
-	}
 	udev->state = USB_STATE_NOTATTACHED;
 }
 
@@ -1448,11 +1443,11 @@ void usb_set_device_state(struct usb_dev
 					|| new_state == USB_STATE_SUSPENDED)
 				;	/* No change to wakeup settings */
 			else if (new_state == USB_STATE_CONFIGURED)
-				device_init_wakeup(&udev->dev,
+				device_set_wakeup_capable(&udev->dev,
 					(udev->actconfig->desc.bmAttributes
 					 & USB_CONFIG_ATT_WAKEUP));
 			else
-				device_init_wakeup(&udev->dev, 0);
+				device_set_wakeup_capable(&udev->dev, 0);
 		}
 		if (udev->state == USB_STATE_SUSPENDED &&
 			new_state != USB_STATE_SUSPENDED)
@@ -1529,31 +1524,15 @@ static void update_address(struct usb_de
 		udev->devnum = devnum;
 }
 
-#ifdef	CONFIG_USB_SUSPEND
-
-static void usb_stop_pm(struct usb_device *udev)
+static void hub_free_dev(struct usb_device *udev)
 {
-	/* Synchronize with the ksuspend thread to prevent any more
-	 * autosuspend requests from being submitted, and decrement
-	 * the parent's count of unsuspended children.
-	 */
-	usb_pm_lock(udev);
-	if (udev->parent && !udev->discon_suspended)
-		usb_autosuspend_device(udev->parent);
-	usb_pm_unlock(udev);
+	struct usb_hcd *hcd = bus_to_hcd(udev->bus);
 
-	/* Stop any autosuspend or autoresume requests already submitted */
-	cancel_delayed_work_sync(&udev->autosuspend);
-	cancel_work_sync(&udev->autoresume);
+	/* Root hubs aren't real devices, so don't free HCD resources */
+	if (hcd->driver->free_dev && udev->parent)
+		hcd->driver->free_dev(hcd, udev);
 }
 
-#else
-
-static inline void usb_stop_pm(struct usb_device *udev)
-{ }
-
-#endif
-
 /**
  * usb_disconnect - disconnect a device (usbcore-internal)
  * @pdev: pointer to device being disconnected
@@ -1622,7 +1601,7 @@ void usb_disconnect(struct usb_device **
 	*pdev = NULL;
 	spin_unlock_irq(&device_state_lock);
 
-	usb_stop_pm(udev);
+	hub_free_dev(udev);
 
 	put_device(&udev->dev);
 }
@@ -1799,9 +1778,18 @@ int usb_new_device(struct usb_device *ud
 {
 	int err;
 
-	/* Increment the parent's count of unsuspended children */
-	if (udev->parent)
-		usb_autoresume_device(udev->parent);
+	if (udev->parent) {
+		/* Initialize non-root-hub device wakeup to disabled;
+		 * device (un)configuration controls wakeup capable
+		 * sysfs power/wakeup controls wakeup enabled/disabled
+		 */
+		device_init_wakeup(&udev->dev, 0);
+		device_set_wakeup_enable(&udev->dev, 1);
+	}
+
+	/* Tell the runtime-PM framework the device is active */
+	pm_runtime_set_active(&udev->dev);
+	pm_runtime_enable(&udev->dev);
 
 	usb_detect_quirks(udev);
 	err = usb_enumerate_device(udev);	/* Read descriptors */
@@ -1817,6 +1805,7 @@ int usb_new_device(struct usb_device *ud
 	/* Tell the world! */
 	announce_device(udev);
 
+	device_enable_async_suspend(&udev->dev);
 	/* Register the device.  The device driver is responsible
 	 * for configuring the device and invoking the add-device
 	 * notifier chain (used by usbfs and possibly others).
@@ -1832,7 +1821,8 @@ int usb_new_device(struct usb_device *ud
 
 fail:
 	usb_set_device_state(udev, USB_STATE_NOTATTACHED);
-	usb_stop_pm(udev);
+	pm_runtime_disable(&udev->dev);
+	pm_runtime_set_suspended(&udev->dev);
 	return err;
 }
 
@@ -1981,7 +1971,7 @@ static int hub_port_wait_reset(struct us
 		if (!(portstatus & USB_PORT_STAT_RESET) &&
 		    (portstatus & USB_PORT_STAT_ENABLE)) {
 			if (hub_is_wusb(hub))
-				udev->speed = USB_SPEED_VARIABLE;
+				udev->speed = USB_SPEED_WIRELESS;
 			else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
 				udev->speed = USB_SPEED_HIGH;
 			else if (portstatus & USB_PORT_STAT_LOW_SPEED)
@@ -2007,7 +1997,9 @@ static int hub_port_reset(struct usb_hub
 				struct usb_device *udev, unsigned int delay)
 {
 	int i, status;
+	struct usb_hcd *hcd;
 
+	hcd = bus_to_hcd(udev->bus);
 	/* Block EHCI CF initialization during the port reset.
 	 * Some companion controllers don't like it when they mix.
 	 */
@@ -2035,6 +2027,14 @@ static int hub_port_reset(struct usb_hub
 			/* TRSTRCY = 10 ms; plus some extra */
 			msleep(10 + 40);
 			update_address(udev, 0);
+			if (hcd->driver->reset_device) {
+				status = hcd->driver->reset_device(hcd, udev);
+				if (status < 0) {
+					dev_err(&udev->dev, "Cannot reset "
+							"HCD device state\n");
+					break;
+				}
+			}
 			/* FALL THROUGH */
 		case -ENOTCONN:
 		case -ENODEV:
@@ -2380,14 +2380,17 @@ int usb_port_resume(struct usb_device *u
 }
 
 /* caller has locked udev */
-static int remote_wakeup(struct usb_device *udev)
+int usb_remote_wakeup(struct usb_device *udev)
 {
 	int	status = 0;
 
 	if (udev->state == USB_STATE_SUSPENDED) {
 		dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-");
-		usb_mark_last_busy(udev);
-		status = usb_external_resume_device(udev, PMSG_REMOTE_RESUME);
+		status = usb_autoresume_device(udev);
+		if (status == 0) {
+			/* Let the drivers do their thing, then... */
+			usb_autosuspend_device(udev);
+		}
 	}
 	return status;
 }
@@ -2424,11 +2427,6 @@ int usb_port_resume(struct usb_device *u
 	return status;
 }
 
-static inline int remote_wakeup(struct usb_device *udev)
-{
-	return 0;
-}
-
 #endif
 
 static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
@@ -2495,11 +2493,6 @@ EXPORT_SYMBOL_GPL(usb_root_hub_lost_powe
 
 #else	/* CONFIG_PM */
 
-static inline int remote_wakeup(struct usb_device *udev)
-{
-	return 0;
-}
-
 #define hub_suspend		NULL
 #define hub_resume		NULL
 #define hub_reset_resume	NULL
@@ -2644,14 +2637,7 @@ hub_port_init (struct usb_hub *hub, stru
 
 	mutex_lock(&usb_address0_mutex);
 
-	if ((hcd->driver->flags & HCD_USB3) && udev->config) {
-		/* FIXME this will need special handling by the xHCI driver. */
-		dev_dbg(&udev->dev,
-				"xHCI reset of configured device "
-				"not supported yet.\n");
-		retval = -EINVAL;
-		goto fail;
-	} else if (!udev->config && oldspeed == USB_SPEED_SUPER) {
+	if (!udev->config && oldspeed == USB_SPEED_SUPER) {
 		/* Don't reset USB 3.0 devices during an initial setup */
 		usb_set_device_state(udev, USB_STATE_DEFAULT);
 	} else {
@@ -2677,7 +2663,7 @@ hub_port_init (struct usb_hub *hub, stru
 	 */
 	switch (udev->speed) {
 	case USB_SPEED_SUPER:
-	case USB_SPEED_VARIABLE:	/* fixed at 512 */
+	case USB_SPEED_WIRELESS:	/* fixed at 512 */
 		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
 		break;
 	case USB_SPEED_HIGH:		/* fixed at 64 */
@@ -2705,7 +2691,7 @@ hub_port_init (struct usb_hub *hub, stru
 	case USB_SPEED_SUPER:
 				speed = "super";
 				break;
-	case USB_SPEED_VARIABLE:
+	case USB_SPEED_WIRELESS:
 				speed = "variable";
 				type = "Wireless ";
 				break;
@@ -3005,7 +2991,7 @@ static void hub_port_connect_change(stru
 			/* For a suspended device, treat this as a
 			 * remote wakeup event.
 			 */
-			status = remote_wakeup(udev);
+			status = usb_remote_wakeup(udev);
 #endif
 
 		} else {
@@ -3191,6 +3177,7 @@ loop_disable:
 loop:
 		usb_ep0_reinit(udev);
 		release_address(udev);
+		hub_free_dev(udev);
 		usb_put_dev(udev);
 		if ((status == -ENOTCONN) || (status == -ENOTSUPP))
 			break;
@@ -3258,7 +3245,7 @@ static void hub_events(void)
 		 * disconnected while waiting for the lock to succeed. */
 		usb_lock_device(hdev);
 		if (unlikely(hub->disconnected))
-			goto loop2;
+			goto loop_disconnected;
 
 		/* If the hub has died, clean up after it */
 		if (hdev->state == USB_STATE_NOTATTACHED) {
@@ -3351,7 +3338,7 @@ static void hub_events(void)
 					msleep(10);
 
 					usb_lock_device(udev);
-					ret = remote_wakeup(hdev->
+					ret = usb_remote_wakeup(hdev->
 							children[i-1]);
 					usb_unlock_device(udev);
 					if (ret < 0)
@@ -3418,7 +3405,7 @@ static void hub_events(void)
 		 * kick_khubd() and allow autosuspend.
 		 */
 		usb_autopm_put_interface(intf);
- loop2:
+ loop_disconnected:
 		usb_unlock_device(hdev);
 		kref_put(&hub->kref, hub_release);
 
@@ -3445,7 +3432,7 @@ static int hub_thread(void *__unused)
 	return 0;
 }
 
-static struct usb_device_id hub_id_table [] = {
+static const struct usb_device_id hub_id_table[] = {
     { .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS,
       .bDeviceClass = USB_CLASS_HUB},
     { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/inode.c linux-libre-2.6.34-gnu1/drivers/usb/core/inode.c
--- linux-libre-2.6.33-gnu1/drivers/usb/core/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -380,6 +380,7 @@ static int usbfs_rmdir(struct inode *dir
 	mutex_lock(&inode->i_mutex);
 	dentry_unhash(dentry);
 	if (usbfs_empty(dentry)) {
+		dont_mount(dentry);
 		drop_nlink(dentry->d_inode);
 		drop_nlink(dentry->d_inode);
 		dput(dentry);
@@ -515,13 +516,13 @@ static int fs_create_by_name (const char
 	*dentry = NULL;
 	mutex_lock(&parent->d_inode->i_mutex);
 	*dentry = lookup_one_len(name, parent, strlen(name));
-	if (!IS_ERR(dentry)) {
+	if (!IS_ERR(*dentry)) {
 		if ((mode & S_IFMT) == S_IFDIR)
 			error = usbfs_mkdir (parent->d_inode, *dentry, mode);
 		else 
 			error = usbfs_create (parent->d_inode, *dentry, mode);
 	} else
-		error = PTR_ERR(dentry);
+		error = PTR_ERR(*dentry);
 	mutex_unlock(&parent->d_inode->i_mutex);
 
 	return error;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/Kconfig linux-libre-2.6.34-gnu1/drivers/usb/core/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/usb/core/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -91,8 +91,8 @@ config USB_DYNAMIC_MINORS
 	  If you are unsure about this, say N here.
 
 config USB_SUSPEND
-	bool "USB selective suspend/resume and wakeup"
-	depends on USB && PM
+	bool "USB runtime power management (suspend/resume and wakeup)"
+	depends on USB && PM_RUNTIME
 	help
 	  If you say Y here, you can use driver calls or the sysfs
 	  "power/level" file to suspend or resume individual USB
@@ -109,7 +109,7 @@ config USB_SUSPEND
 config USB_OTG
 	bool
 	depends on USB && EXPERIMENTAL
-	select USB_SUSPEND
+	depends on USB_SUSPEND
 	default n
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/message.c linux-libre-2.6.34-gnu1/drivers/usb/core/message.c
--- linux-libre-2.6.33-gnu1/drivers/usb/core/message.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/message.c	2010-05-16 17:17:36.000000000 -0400
@@ -1316,7 +1316,7 @@ int usb_set_interface(struct usb_device
 
 	alt = usb_altnum_to_altsetting(iface, alternate);
 	if (!alt) {
-		dev_warn(&dev->dev, "selecting invalid altsetting %d",
+		dev_warn(&dev->dev, "selecting invalid altsetting %d\n",
 			 alternate);
 		return -EINVAL;
 	}
@@ -1471,7 +1471,7 @@ int usb_reset_configuration(struct usb_d
 	/* If not, reinstate the old alternate settings */
 	if (retval < 0) {
 reset_old_alts:
-		for (; i >= 0; i--) {
+		for (i--; i >= 0; i--) {
 			struct usb_interface *intf = config->interface[i];
 			struct usb_host_interface *alt;
 
@@ -1843,7 +1843,6 @@ free_interfaces:
 		intf->dev.dma_mask = dev->dev.dma_mask;
 		INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);
 		device_initialize(&intf->dev);
-		mark_quiesced(intf);
 		dev_set_name(&intf->dev, "%d-%s:%d.%d",
 			dev->bus->busnum, dev->devpath,
 			configuration, alt->desc.bInterfaceNumber);
@@ -1867,6 +1866,7 @@ free_interfaces:
 			"adding %s (config #%d, interface %d)\n",
 			dev_name(&intf->dev), configuration,
 			intf->cur_altsetting->desc.bInterfaceNumber);
+		device_enable_async_suspend(&intf->dev);
 		ret = device_add(&intf->dev);
 		if (ret != 0) {
 			dev_err(&dev->dev, "device_add(%s) --> %d\n",
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/quirks.c linux-libre-2.6.34-gnu1/drivers/usb/core/quirks.c
--- linux-libre-2.6.33-gnu1/drivers/usb/core/quirks.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/quirks.c	2010-05-16 17:17:36.000000000 -0400
@@ -103,10 +103,19 @@ void usb_detect_quirks(struct usb_device
 		dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
 				udev->quirks);
 
-	/* By default, disable autosuspend for all non-hubs */
 #ifdef	CONFIG_USB_SUSPEND
-	if (udev->descriptor.bDeviceClass != USB_CLASS_HUB)
-		udev->autosuspend_disabled = 1;
+
+	/* By default, disable autosuspend for all devices.  The hub driver
+	 * will enable it for hubs.
+	 */
+	usb_disable_autosuspend(udev);
+
+	/* Autosuspend can also be disabled if the initial autosuspend_delay
+	 * is negative.
+	 */
+	if (udev->autosuspend_delay < 0)
+		usb_autoresume_device(udev);
+
 #endif
 
 	/* For the present, all devices default to USB-PERSIST enabled */
@@ -120,6 +129,7 @@ void usb_detect_quirks(struct usb_device
 	 * for all devices.  It will affect things like hub resets
 	 * and EMF-related port disables.
 	 */
-	udev->persist_enabled = 1;
+	if (!(udev->quirks & USB_QUIRK_RESET_MORPHS))
+		udev->persist_enabled = 1;
 #endif	/* CONFIG_PM */
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/sysfs.c linux-libre-2.6.34-gnu1/drivers/usb/core/sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/usb/core/sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -115,7 +115,7 @@ show_speed(struct device *dev, struct de
 	case USB_SPEED_HIGH:
 		speed = "480";
 		break;
-	case USB_SPEED_VARIABLE:
+	case USB_SPEED_WIRELESS:
 		speed = "480";
 		break;
 	case USB_SPEED_SUPER:
@@ -191,6 +191,36 @@ show_quirks(struct device *dev, struct d
 static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL);
 
 static ssize_t
+show_avoid_reset_quirk(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct usb_device *udev;
+
+	udev = to_usb_device(dev);
+	return sprintf(buf, "%d\n", !!(udev->quirks & USB_QUIRK_RESET_MORPHS));
+}
+
+static ssize_t
+set_avoid_reset_quirk(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct usb_device	*udev = to_usb_device(dev);
+	int			config;
+
+	if (sscanf(buf, "%d", &config) != 1 || config < 0 || config > 1)
+		return -EINVAL;
+	usb_lock_device(udev);
+	if (config)
+		udev->quirks |= USB_QUIRK_RESET_MORPHS;
+	else
+		udev->quirks &= ~USB_QUIRK_RESET_MORPHS;
+	usb_unlock_device(udev);
+	return count;
+}
+
+static DEVICE_ATTR(avoid_reset_quirk, S_IRUGO | S_IWUSR,
+		show_avoid_reset_quirk, set_avoid_reset_quirk);
+
+static ssize_t
 show_urbnum(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct usb_device *udev;
@@ -226,9 +256,10 @@ set_persist(struct device *dev, struct d
 
 	if (sscanf(buf, "%d", &value) != 1)
 		return -EINVAL;
-	usb_pm_lock(udev);
+
+	usb_lock_device(udev);
 	udev->persist_enabled = !!value;
-	usb_pm_unlock(udev);
+	usb_unlock_device(udev);
 	return count;
 }
 
@@ -315,20 +346,34 @@ set_autosuspend(struct device *dev, stru
 		const char *buf, size_t count)
 {
 	struct usb_device *udev = to_usb_device(dev);
-	int value;
+	int value, old_delay;
+	int rc;
 
 	if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/HZ ||
 			value <= - INT_MAX/HZ)
 		return -EINVAL;
 	value *= HZ;
 
+	usb_lock_device(udev);
+	old_delay = udev->autosuspend_delay;
 	udev->autosuspend_delay = value;
-	if (value >= 0)
-		usb_try_autosuspend_device(udev);
-	else {
-		if (usb_autoresume_device(udev) == 0)
+
+	if (old_delay < 0) {	/* Autosuspend wasn't allowed */
+		if (value >= 0)
 			usb_autosuspend_device(udev);
+	} else {		/* Autosuspend was allowed */
+		if (value < 0) {
+			rc = usb_autoresume_device(udev);
+			if (rc < 0) {
+				count = rc;
+				udev->autosuspend_delay = old_delay;
+			}
+		} else {
+			usb_try_autosuspend_device(udev);
+		}
 	}
+
+	usb_unlock_device(udev);
 	return count;
 }
 
@@ -356,34 +401,25 @@ set_level(struct device *dev, struct dev
 	struct usb_device *udev = to_usb_device(dev);
 	int len = count;
 	char *cp;
-	int rc = 0;
-	int old_autosuspend_disabled;
+	int rc;
 
 	cp = memchr(buf, '\n', count);
 	if (cp)
 		len = cp - buf;
 
 	usb_lock_device(udev);
-	old_autosuspend_disabled = udev->autosuspend_disabled;
 
-	/* Setting the flags without calling usb_pm_lock is a subject to
-	 * races, but who cares...
-	 */
 	if (len == sizeof on_string - 1 &&
-			strncmp(buf, on_string, len) == 0) {
-		udev->autosuspend_disabled = 1;
-		rc = usb_external_resume_device(udev, PMSG_USER_RESUME);
+			strncmp(buf, on_string, len) == 0)
+		rc = usb_disable_autosuspend(udev);
 
-	} else if (len == sizeof auto_string - 1 &&
-			strncmp(buf, auto_string, len) == 0) {
-		udev->autosuspend_disabled = 0;
-		rc = usb_external_resume_device(udev, PMSG_USER_RESUME);
+	else if (len == sizeof auto_string - 1 &&
+			strncmp(buf, auto_string, len) == 0)
+		rc = usb_enable_autosuspend(udev);
 
-	} else
+	else
 		rc = -EINVAL;
 
-	if (rc)
-		udev->autosuspend_disabled = old_autosuspend_disabled;
 	usb_unlock_device(udev);
 	return (rc < 0 ? rc : count);
 }
@@ -558,6 +594,7 @@ static struct attribute *dev_attrs[] = {
 	&dev_attr_version.attr,
 	&dev_attr_maxchild.attr,
 	&dev_attr_quirks.attr,
+	&dev_attr_avoid_reset_quirk.attr,
 	&dev_attr_authorized.attr,
 	&dev_attr_remove.attr,
 	NULL,
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/urb.c linux-libre-2.6.34-gnu1/drivers/usb/core/urb.c
--- linux-libre-2.6.33-gnu1/drivers/usb/core/urb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/urb.c	2010-05-16 17:17:36.000000000 -0400
@@ -387,6 +387,13 @@ int usb_submit_urb(struct urb *urb, gfp_
 	{
 	unsigned int	orig_flags = urb->transfer_flags;
 	unsigned int	allowed;
+	static int pipetypes[4] = {
+		PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT
+	};
+
+	/* Check that the pipe's type matches the endpoint's type */
+	if (usb_pipetype(urb->pipe) != pipetypes[xfertype])
+		return -EPIPE;		/* The most suitable error code :-) */
 
 	/* enforce simple/standard policy */
 	allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP |
@@ -430,7 +437,7 @@ int usb_submit_urb(struct urb *urb, gfp_
 	case USB_ENDPOINT_XFER_INT:
 		/* too small? */
 		switch (dev->speed) {
-		case USB_SPEED_VARIABLE:
+		case USB_SPEED_WIRELESS:
 			if (urb->interval < 6)
 				return -EINVAL;
 			break;
@@ -446,7 +453,8 @@ int usb_submit_urb(struct urb *urb, gfp_
 			if (urb->interval > (1 << 15))
 				return -EINVAL;
 			max = 1 << 15;
-		case USB_SPEED_VARIABLE:
+			break;
+		case USB_SPEED_WIRELESS:
 			if (urb->interval > 16)
 				return -EINVAL;
 			break;
@@ -473,7 +481,7 @@ int usb_submit_urb(struct urb *urb, gfp_
 		default:
 			return -EINVAL;
 		}
-		if (dev->speed != USB_SPEED_VARIABLE) {
+		if (dev->speed != USB_SPEED_WIRELESS) {
 			/* Round down to a power of 2, no more than max */
 			urb->interval = min(max, 1 << ilog2(urb->interval));
 		}
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/usb.c linux-libre-2.6.34-gnu1/drivers/usb/core/usb.c
--- linux-libre-2.6.33-gnu1/drivers/usb/core/usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,9 +49,6 @@ const char *usbcore_name = "usbcore";
 
 static int nousb;	/* Disable USB when built into kernel image */
 
-/* Workqueue for autosuspend and for remote wakeup of root hubs */
-struct workqueue_struct *ksuspend_usb_wq;
-
 #ifdef	CONFIG_USB_SUSPEND
 static int usb_autosuspend_delay = 2;		/* Default delay value,
 						 * in seconds */
@@ -228,9 +225,6 @@ static void usb_release_dev(struct devic
 	hcd = bus_to_hcd(udev->bus);
 
 	usb_destroy_configuration(udev);
-	/* Root hubs aren't real devices, so don't free HCD resources */
-	if (hcd->driver->free_dev && udev->parent)
-		hcd->driver->free_dev(hcd, udev);
 	usb_put_hcd(hcd);
 	kfree(udev->product);
 	kfree(udev->manufacturer);
@@ -264,23 +258,6 @@ static int usb_dev_uevent(struct device
 
 #ifdef	CONFIG_PM
 
-static int ksuspend_usb_init(void)
-{
-	/* This workqueue is supposed to be both freezable and
-	 * singlethreaded.  Its job doesn't justify running on more
-	 * than one CPU.
-	 */
-	ksuspend_usb_wq = create_freezeable_workqueue("ksuspend_usbd");
-	if (!ksuspend_usb_wq)
-		return -ENOMEM;
-	return 0;
-}
-
-static void ksuspend_usb_cleanup(void)
-{
-	destroy_workqueue(ksuspend_usb_wq);
-}
-
 /* USB device Power-Management thunks.
  * There's no need to distinguish here between quiescing a USB device
  * and powering it down; the generic_suspend() routine takes care of
@@ -296,7 +273,7 @@ static int usb_dev_prepare(struct device
 static void usb_dev_complete(struct device *dev)
 {
 	/* Currently used only for rebinding interfaces */
-	usb_resume(dev, PMSG_RESUME);	/* Message event is meaningless */
+	usb_resume(dev, PMSG_ON);	/* FIXME: change to PMSG_COMPLETE */
 }
 
 static int usb_dev_suspend(struct device *dev)
@@ -342,9 +319,7 @@ static const struct dev_pm_ops usb_devic
 
 #else
 
-#define ksuspend_usb_init()	0
-#define ksuspend_usb_cleanup()	do {} while (0)
-#define usb_device_pm_ops	(*(struct dev_pm_ops *)0)
+#define usb_device_pm_ops	(*(struct dev_pm_ops *) NULL)
 
 #endif	/* CONFIG_PM */
 
@@ -472,9 +447,6 @@ struct usb_device *usb_alloc_dev(struct
 	INIT_LIST_HEAD(&dev->filelist);
 
 #ifdef	CONFIG_PM
-	mutex_init(&dev->pm_mutex);
-	INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work);
-	INIT_WORK(&dev->autoresume, usb_autoresume_work);
 	dev->autosuspend_delay = usb_autosuspend_delay * HZ;
 	dev->connect_time = jiffies;
 	dev->active_duration = -jiffies;
@@ -746,7 +718,7 @@ int __usb_get_extra_descriptor(char *buf
 EXPORT_SYMBOL_GPL(__usb_get_extra_descriptor);
 
 /**
- * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
+ * usb_alloc_coherent - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
  * @dev: device the buffer will be used with
  * @size: requested buffer size
  * @mem_flags: affect whether allocation may block
@@ -765,30 +737,30 @@ EXPORT_SYMBOL_GPL(__usb_get_extra_descri
  * architectures where CPU caches are not DMA-coherent.  On systems without
  * bus-snooping caches, these buffers are uncached.
  *
- * When the buffer is no longer used, free it with usb_buffer_free().
+ * When the buffer is no longer used, free it with usb_free_coherent().
  */
-void *usb_buffer_alloc(struct usb_device *dev, size_t size, gfp_t mem_flags,
-		       dma_addr_t *dma)
+void *usb_alloc_coherent(struct usb_device *dev, size_t size, gfp_t mem_flags,
+			 dma_addr_t *dma)
 {
 	if (!dev || !dev->bus)
 		return NULL;
 	return hcd_buffer_alloc(dev->bus, size, mem_flags, dma);
 }
-EXPORT_SYMBOL_GPL(usb_buffer_alloc);
+EXPORT_SYMBOL_GPL(usb_alloc_coherent);
 
 /**
- * usb_buffer_free - free memory allocated with usb_buffer_alloc()
+ * usb_free_coherent - free memory allocated with usb_alloc_coherent()
  * @dev: device the buffer was used with
  * @size: requested buffer size
  * @addr: CPU address of buffer
  * @dma: DMA address of buffer
  *
  * This reclaims an I/O buffer, letting it be reused.  The memory must have
- * been allocated using usb_buffer_alloc(), and the parameters must match
+ * been allocated using usb_alloc_coherent(), and the parameters must match
  * those provided in that allocation request.
  */
-void usb_buffer_free(struct usb_device *dev, size_t size, void *addr,
-		     dma_addr_t dma)
+void usb_free_coherent(struct usb_device *dev, size_t size, void *addr,
+		       dma_addr_t dma)
 {
 	if (!dev || !dev->bus)
 		return;
@@ -796,7 +768,7 @@ void usb_buffer_free(struct usb_device *
 		return;
 	hcd_buffer_free(dev->bus, size, addr, dma);
 }
-EXPORT_SYMBOL_GPL(usb_buffer_free);
+EXPORT_SYMBOL_GPL(usb_free_coherent);
 
 /**
  * usb_buffer_map - create DMA mapping(s) for an urb
@@ -1117,9 +1089,6 @@ static int __init usb_init(void)
 	if (retval)
 		goto out;
 
-	retval = ksuspend_usb_init();
-	if (retval)
-		goto out;
 	retval = bus_register(&usb_bus_type);
 	if (retval)
 		goto bus_register_failed;
@@ -1159,7 +1128,7 @@ major_init_failed:
 bus_notifier_failed:
 	bus_unregister(&usb_bus_type);
 bus_register_failed:
-	ksuspend_usb_cleanup();
+	usb_debugfs_cleanup();
 out:
 	return retval;
 }
@@ -1181,7 +1150,6 @@ static void __exit usb_exit(void)
 	usb_hub_cleanup();
 	bus_unregister_notifier(&usb_bus_type, &usb_bus_nb);
 	bus_unregister(&usb_bus_type);
-	ksuspend_usb_cleanup();
 	usb_debugfs_cleanup();
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/core/usb.h linux-libre-2.6.34-gnu1/drivers/usb/core/usb.h
--- linux-libre-2.6.33-gnu1/drivers/usb/core/usb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/core/usb.h	2010-05-16 17:17:36.000000000 -0400
@@ -55,24 +55,8 @@ extern void usb_major_cleanup(void);
 extern int usb_suspend(struct device *dev, pm_message_t msg);
 extern int usb_resume(struct device *dev, pm_message_t msg);
 
-extern void usb_autosuspend_work(struct work_struct *work);
-extern void usb_autoresume_work(struct work_struct *work);
 extern int usb_port_suspend(struct usb_device *dev, pm_message_t msg);
 extern int usb_port_resume(struct usb_device *dev, pm_message_t msg);
-extern int usb_external_suspend_device(struct usb_device *udev,
-		pm_message_t msg);
-extern int usb_external_resume_device(struct usb_device *udev,
-		pm_message_t msg);
-
-static inline void usb_pm_lock(struct usb_device *udev)
-{
-	mutex_lock_nested(&udev->pm_mutex, udev->level);
-}
-
-static inline void usb_pm_unlock(struct usb_device *udev)
-{
-	mutex_unlock(&udev->pm_mutex);
-}
 
 #else
 
@@ -86,9 +70,6 @@ static inline int usb_port_resume(struct
 	return 0;
 }
 
-static inline void usb_pm_lock(struct usb_device *udev) {}
-static inline void usb_pm_unlock(struct usb_device *udev) {}
-
 #endif
 
 #ifdef CONFIG_USB_SUSPEND
@@ -96,6 +77,7 @@ static inline void usb_pm_unlock(struct
 extern void usb_autosuspend_device(struct usb_device *udev);
 extern void usb_try_autosuspend_device(struct usb_device *udev);
 extern int usb_autoresume_device(struct usb_device *udev);
+extern int usb_remote_wakeup(struct usb_device *dev);
 
 #else
 
@@ -106,9 +88,13 @@ static inline int usb_autoresume_device(
 	return 0;
 }
 
+static inline int usb_remote_wakeup(struct usb_device *udev)
+{
+	return 0;
+}
+
 #endif
 
-extern struct workqueue_struct *ksuspend_usb_wq;
 extern struct bus_type usb_bus_type;
 extern struct device_type usb_device_type;
 extern struct device_type usb_if_device_type;
@@ -138,23 +124,6 @@ static inline int is_usb_device_driver(s
 			for_devices;
 }
 
-/* Interfaces and their "power state" are owned by usbcore */
-
-static inline void mark_active(struct usb_interface *f)
-{
-	f->is_active = 1;
-}
-
-static inline void mark_quiesced(struct usb_interface *f)
-{
-	f->is_active = 0;
-}
-
-static inline int is_active(const struct usb_interface *f)
-{
-	return f->is_active;
-}
-
 
 /* for labeling diagnostics */
 extern const char *usbcore_name;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/early/ehci-dbgp.c linux-libre-2.6.34-gnu1/drivers/usb/early/ehci-dbgp.c
--- linux-libre-2.6.33-gnu1/drivers/usb/early/ehci-dbgp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/early/ehci-dbgp.c	2010-05-16 17:17:36.000000000 -0400
@@ -66,8 +66,6 @@ static struct ehci_dev ehci_dev;
 
 #define USB_DEBUG_DEVNUM 127
 
-#define DBGP_DATA_TOGGLE	0x8800
-
 #ifdef DBGP_DEBUG
 #define dbgp_printk printk
 static void dbgp_ehci_status(char *str)
@@ -88,11 +86,6 @@ static inline void dbgp_ehci_status(char
 static inline void dbgp_printk(const char *fmt, ...) { }
 #endif
 
-static inline u32 dbgp_pid_update(u32 x, u32 tok)
-{
-	return ((x ^ DBGP_DATA_TOGGLE) & 0xffff00) | (tok & 0xff);
-}
-
 static inline u32 dbgp_len_update(u32 x, u32 len)
 {
 	return (x & ~0x0f) | (len & 0x0f);
@@ -136,6 +129,19 @@ static inline u32 dbgp_len_update(u32 x,
 
 #define DBGP_MAX_PACKET		8
 #define DBGP_TIMEOUT		(250 * 1000)
+#define DBGP_LOOPS		1000
+
+static inline u32 dbgp_pid_write_update(u32 x, u32 tok)
+{
+	static int data0 = USB_PID_DATA1;
+	data0 ^= USB_PID_DATA_TOGGLE;
+	return (x & 0xffff0000) | (data0 << 8) | (tok & 0xff);
+}
+
+static inline u32 dbgp_pid_read_update(u32 x, u32 tok)
+{
+	return (x & 0xffff0000) | (USB_PID_DATA0 << 8) | (tok & 0xff);
+}
 
 static int dbgp_wait_until_complete(void)
 {
@@ -180,7 +186,7 @@ static int dbgp_wait_until_done(unsigned
 {
 	u32 pids, lpid;
 	int ret;
-	int loop = 3;
+	int loop = DBGP_LOOPS;
 
 retry:
 	writel(ctrl | DBGP_GO, &ehci_debug->control);
@@ -197,6 +203,8 @@ retry:
 		 */
 		if (ret == -DBGP_TIMEOUT && !dbgp_not_safe)
 			dbgp_not_safe = 1;
+		if (ret == -DBGP_ERR_BAD && --loop > 0)
+			goto retry;
 		return ret;
 	}
 
@@ -245,12 +253,20 @@ static inline void dbgp_get_data(void *b
 		bytes[i] = (hi >> (8*(i - 4))) & 0xff;
 }
 
-static int dbgp_out(u32 addr, const char *bytes, int size)
+static int dbgp_bulk_write(unsigned devnum, unsigned endpoint,
+			 const char *bytes, int size)
 {
+	int ret;
+	u32 addr;
 	u32 pids, ctrl;
 
+	if (size > DBGP_MAX_PACKET)
+		return -1;
+
+	addr = DBGP_EPADDR(devnum, endpoint);
+
 	pids = readl(&ehci_debug->pids);
-	pids = dbgp_pid_update(pids, USB_PID_OUT);
+	pids = dbgp_pid_write_update(pids, USB_PID_OUT);
 
 	ctrl = readl(&ehci_debug->control);
 	ctrl = dbgp_len_update(ctrl, size);
@@ -260,34 +276,7 @@ static int dbgp_out(u32 addr, const char
 	dbgp_set_data(bytes, size);
 	writel(addr, &ehci_debug->address);
 	writel(pids, &ehci_debug->pids);
-	return dbgp_wait_until_done(ctrl);
-}
-
-static int dbgp_bulk_write(unsigned devnum, unsigned endpoint,
-			 const char *bytes, int size)
-{
-	int ret;
-	int loops = 5;
-	u32 addr;
-	if (size > DBGP_MAX_PACKET)
-		return -1;
-
-	addr = DBGP_EPADDR(devnum, endpoint);
-try_again:
-	if (loops--) {
-		ret = dbgp_out(addr, bytes, size);
-		if (ret == -DBGP_ERR_BAD) {
-			int try_loops = 3;
-			do {
-				/* Emit a dummy packet to re-sync communication
-				 * with the debug device */
-				if (dbgp_out(addr, "12345678", 8) >= 0) {
-					udelay(2);
-					goto try_again;
-				}
-			} while (try_loops--);
-		}
-	}
+	ret = dbgp_wait_until_done(ctrl);
 
 	return ret;
 }
@@ -304,7 +293,7 @@ static int dbgp_bulk_read(unsigned devnu
 	addr = DBGP_EPADDR(devnum, endpoint);
 
 	pids = readl(&ehci_debug->pids);
-	pids = dbgp_pid_update(pids, USB_PID_IN);
+	pids = dbgp_pid_read_update(pids, USB_PID_IN);
 
 	ctrl = readl(&ehci_debug->control);
 	ctrl = dbgp_len_update(ctrl, size);
@@ -362,7 +351,6 @@ static int dbgp_control_msg(unsigned dev
 	return dbgp_bulk_read(devnum, 0, data, size);
 }
 
-
 /* Find a PCI capability */
 static u32 __init find_cap(u32 num, u32 slot, u32 func, int cap)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/at91_udc.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/at91_udc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/at91_udc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/at91_udc.c	2010-05-16 17:17:36.000000000 -0400
@@ -1370,6 +1370,12 @@ static irqreturn_t at91_udc_irq (int irq
 {
 	struct at91_udc		*udc = _udc;
 	u32			rescans = 5;
+	int			disable_clock = 0;
+
+	if (!udc->clocked) {
+		clk_on(udc);
+		disable_clock = 1;
+	}
 
 	while (rescans--) {
 		u32 status;
@@ -1458,6 +1464,9 @@ static irqreturn_t at91_udc_irq (int irq
 		}
 	}
 
+	if (disable_clock)
+		clk_off(udc);
+
 	return IRQ_HANDLED;
 }
 
@@ -1656,9 +1665,7 @@ static int __init at91udc_probe(struct p
 	if (!res)
 		return -ENXIO;
 
-	if (!request_mem_region(res->start,
-			res->end - res->start + 1,
-			driver_name)) {
+	if (!request_mem_region(res->start, resource_size(res), driver_name)) {
 		DBG("someone's using UDC memory\n");
 		return -EBUSY;
 	}
@@ -1699,7 +1706,7 @@ static int __init at91udc_probe(struct p
 		udc->ep[3].maxpacket = 64;
 	}
 
-	udc->udp_baseaddr = ioremap(res->start, res->end - res->start + 1);
+	udc->udp_baseaddr = ioremap(res->start, resource_size(res));
 	if (!udc->udp_baseaddr) {
 		retval = -ENOMEM;
 		goto fail0a;
@@ -1781,7 +1788,7 @@ fail0a:
 	if (cpu_is_at91rm9200())
 		gpio_free(udc->board.pullup_pin);
 fail0:
-	release_mem_region(res->start, res->end - res->start + 1);
+	release_mem_region(res->start, resource_size(res));
 	DBG("%s probe failed, %d\n", driver_name, retval);
 	return retval;
 }
@@ -1813,7 +1820,7 @@ static int __exit at91udc_remove(struct
 		gpio_free(udc->board.pullup_pin);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(res->start, res->end - res->start + 1);
+	release_mem_region(res->start, resource_size(res));
 
 	clk_put(udc->iclk);
 	clk_put(udc->fclk);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/atmel_usba_udc.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/atmel_usba_udc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/atmel_usba_udc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/atmel_usba_udc.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/list.h>
@@ -320,7 +321,7 @@ static inline void usba_cleanup_debugfs(
 static int vbus_is_present(struct usba_udc *udc)
 {
 	if (gpio_is_valid(udc->vbus_pin))
-		return gpio_get_value(udc->vbus_pin);
+		return gpio_get_value(udc->vbus_pin) ^ udc->vbus_pin_inverted;
 
 	/* No Vbus detection: Assume always present */
 	return 1;
@@ -1763,7 +1764,7 @@ static irqreturn_t usba_vbus_irq(int irq
 	if (!udc->driver)
 		goto out;
 
-	vbus = gpio_get_value(udc->vbus_pin);
+	vbus = vbus_is_present(udc);
 	if (vbus != udc->vbus_prev) {
 		if (vbus) {
 			toggle_bias(1);
@@ -1914,14 +1915,14 @@ static int __init usba_udc_probe(struct
 	udc->vbus_pin = -ENODEV;
 
 	ret = -ENOMEM;
-	udc->regs = ioremap(regs->start, regs->end - regs->start + 1);
+	udc->regs = ioremap(regs->start, resource_size(regs));
 	if (!udc->regs) {
 		dev_err(&pdev->dev, "Unable to map I/O memory, aborting.\n");
 		goto err_map_regs;
 	}
 	dev_info(&pdev->dev, "MMIO registers at 0x%08lx mapped at %p\n",
 		 (unsigned long)regs->start, udc->regs);
-	udc->fifo = ioremap(fifo->start, fifo->end - fifo->start + 1);
+	udc->fifo = ioremap(fifo->start, resource_size(fifo));
 	if (!udc->fifo) {
 		dev_err(&pdev->dev, "Unable to map FIFO, aborting.\n");
 		goto err_map_fifo;
@@ -2000,6 +2001,7 @@ static int __init usba_udc_probe(struct
 	if (gpio_is_valid(pdata->vbus_pin)) {
 		if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) {
 			udc->vbus_pin = pdata->vbus_pin;
+			udc->vbus_pin_inverted = pdata->vbus_pin_inverted;
 
 			ret = request_irq(gpio_to_irq(udc->vbus_pin),
 					usba_vbus_irq, 0,
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/atmel_usba_udc.h linux-libre-2.6.34-gnu1/drivers/usb/gadget/atmel_usba_udc.h
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/atmel_usba_udc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/atmel_usba_udc.h	2010-05-16 17:17:36.000000000 -0400
@@ -323,6 +323,7 @@ struct usba_udc {
 	struct platform_device *pdev;
 	int irq;
 	int vbus_pin;
+	int vbus_pin_inverted;
 	struct clk *pclk;
 	struct clk *hclk;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/ci13xxx_udc.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/ci13xxx_udc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/ci13xxx_udc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/ci13xxx_udc.c	2010-05-16 17:17:36.000000000 -0400
@@ -62,6 +62,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/config.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/config.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/config.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/config.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/string.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/epautoconf.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/epautoconf.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/epautoconf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/epautoconf.c	2010-05-16 17:17:36.000000000 -0400
@@ -265,16 +265,24 @@ struct usb_ep * __init usb_ep_autoconfig
 				return ep;
 		}
 
-	} else if (gadget_is_sh (gadget) && USB_ENDPOINT_XFER_INT == type) {
-		/* single buffering is enough; maybe 8 byte fifo is too */
-		ep = find_ep (gadget, "ep3in-bulk");
-		if (ep && ep_matches (gadget, ep, desc))
-			return ep;
-
-	} else if (gadget_is_mq11xx (gadget) && USB_ENDPOINT_XFER_INT == type) {
-		ep = find_ep (gadget, "ep1-bulk");
+#ifdef CONFIG_BLACKFIN
+	} else if (gadget_is_musbhdrc(gadget)) {
+		if ((USB_ENDPOINT_XFER_BULK == type) ||
+		    (USB_ENDPOINT_XFER_ISOC == type)) {
+			if (USB_DIR_IN & desc->bEndpointAddress)
+				ep = find_ep (gadget, "ep5in");
+			else
+				ep = find_ep (gadget, "ep6out");
+		} else if (USB_ENDPOINT_XFER_INT == type) {
+			if (USB_DIR_IN & desc->bEndpointAddress)
+				ep = find_ep(gadget, "ep1in");
+			else
+				ep = find_ep(gadget, "ep2out");
+		} else
+			ep = NULL;
 		if (ep && ep_matches (gadget, ep, desc))
 			return ep;
+#endif
 	}
 
 	/* Second, look at endpoints until an unclaimed one looks usable */
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/ether.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/ether.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/ether.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/ether.c	2010-05-16 17:17:36.000000000 -0400
@@ -259,7 +259,7 @@ static struct usb_configuration rndis_co
 
 /*-------------------------------------------------------------------------*/
 
-#ifdef USB_ETH_EEM
+#ifdef CONFIG_USB_ETH_EEM
 static int use_eem = 1;
 #else
 static int use_eem;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_acm.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_acm.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_acm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_acm.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 
 /* #define VERBOSE_DEBUG */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 
@@ -702,14 +703,6 @@ acm_unbind(struct usb_configuration *c,
 /* Some controllers can't support CDC ACM ... */
 static inline bool can_support_cdc(struct usb_configuration *c)
 {
-	/* SH3 doesn't support multiple interfaces */
-	if (gadget_is_sh(c->cdev->gadget))
-		return false;
-
-	/* sa1100 doesn't have a third interrupt endpoint */
-	if (gadget_is_sa1100(c->cdev->gadget))
-		return false;
-
 	/* everything else is *probably* fine ... */
 	return true;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_audio.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_audio.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_audio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_audio.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  * Licensed under the GPL-2 or later.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <asm/atomic.h>
@@ -60,7 +61,7 @@ DECLARE_UAC_AC_HEADER_DESCRIPTOR(2);
 #define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH + UAC_DT_INPUT_TERMINAL_SIZE \
 	+ UAC_DT_OUTPUT_TERMINAL_SIZE + UAC_DT_FEATURE_UNIT_SIZE(0))
 /* B.3.2  Class-Specific AC Interface Descriptor */
-static struct uac_ac_header_descriptor_2 ac_header_desc = {
+static struct uac_ac_header_descriptor_v1_2 ac_header_desc = {
 	.bLength =		UAC_DT_AC_HEADER_LENGTH,
 	.bDescriptorType =	USB_DT_CS_INTERFACE,
 	.bDescriptorSubtype =	UAC_HEADER,
@@ -124,7 +125,7 @@ static struct usb_audio_control_selector
 };
 
 #define OUTPUT_TERMINAL_ID	3
-static struct uac_output_terminal_descriptor output_terminal_desc = {
+static struct uac_output_terminal_descriptor_v1 output_terminal_desc = {
 	.bLength		= UAC_DT_OUTPUT_TERMINAL_SIZE,
 	.bDescriptorType	= USB_DT_CS_INTERFACE,
 	.bDescriptorSubtype	= UAC_OUTPUT_TERMINAL,
@@ -154,7 +155,7 @@ static struct usb_interface_descriptor a
 };
 
 /* B.4.2  Class-Specific AS Interface Descriptor */
-static struct uac_as_header_descriptor as_header_desc = {
+static struct uac_as_header_descriptor_v1 as_header_desc = {
 	.bLength =		UAC_DT_AS_HEADER_SIZE,
 	.bDescriptorType =	USB_DT_CS_INTERFACE,
 	.bDescriptorSubtype =	UAC_AS_GENERAL,
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_ecm.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_ecm.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_ecm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_ecm.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 
 /* #define VERBOSE_DEBUG */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/etherdevice.h>
@@ -497,12 +498,9 @@ static int ecm_set_alt(struct usb_functi
 			struct net_device	*net;
 
 			/* Enable zlps by default for ECM conformance;
-			 * override for musb_hdrc (avoids txdma ovhead)
-			 * and sa1100 (can't).
+			 * override for musb_hdrc (avoids txdma ovhead).
 			 */
-			ecm->port.is_zlp_ok = !(
-				   gadget_is_sa1100(cdev->gadget)
-				|| gadget_is_musbhdrc(cdev->gadget)
+			ecm->port.is_zlp_ok = !(gadget_is_musbhdrc(cdev->gadget)
 				);
 			ecm->port.cdc_filter = DEFAULT_FILTER;
 			DBG(cdev, "activate ecm\n");
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_eem.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_eem.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_eem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_eem.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/device.h>
 #include <linux/etherdevice.h>
 #include <linux/crc32.h>
+#include <linux/slab.h>
 
 #include "u_ether.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/file_storage.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/file_storage.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/file_storage.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/file_storage.c	2010-05-16 17:17:36.000000000 -0400
@@ -1448,7 +1448,7 @@ static void invalidate_sub(struct fsg_lu
 	unsigned long	rc;
 
 	rc = invalidate_mapping_pages(inode->i_mapping, 0, -1);
-	VLDBG(curlun, "invalidate_inode_pages -> %ld\n", rc);
+	VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc);
 }
 
 static int do_verify(struct fsg_dev *fsg)
@@ -3208,15 +3208,11 @@ static int __init check_parameters(struc
 	 * halt bulk endpoints correctly.  If one of them is present,
 	 * disable stalls.
 	 */
-	if (gadget_is_sh(fsg->gadget) || gadget_is_at91(fsg->gadget))
+	if (gadget_is_at91(fsg->gadget))
 		mod_data.can_stall = 0;
 
 	if (mod_data.release == 0xffff) {	// Parameter wasn't set
-		/* The sa1100 controller is not supported */
-		if (gadget_is_sa1100(fsg->gadget))
-			gcnum = -1;
-		else
-			gcnum = usb_gadget_controller_number(fsg->gadget);
+		gcnum = usb_gadget_controller_number(fsg->gadget);
 		if (gcnum >= 0)
 			mod_data.release = 0x0300 + gcnum;
 		else {
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_loopback.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_loopback.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_loopback.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_loopback.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 
 /* #define VERBOSE_DEBUG */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_mass_storage.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_mass_storage.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_mass_storage.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_mass_storage.c	2010-05-16 17:17:36.000000000 -0400
@@ -368,7 +368,7 @@ struct fsg_common {
 	struct task_struct	*thread_task;
 
 	/* Callback function to call when thread exits. */
-	void			(*thread_exits)(struct fsg_common *common);
+	int			(*thread_exits)(struct fsg_common *common);
 	/* Gadget's private data. */
 	void			*private_data;
 
@@ -392,8 +392,12 @@ struct fsg_config {
 	const char		*lun_name_format;
 	const char		*thread_name;
 
-	/* Callback function to call when thread exits. */
-	void			(*thread_exits)(struct fsg_common *common);
+	/* Callback function to call when thread exits.  If no
+	 * callback is set or it returns value lower then zero MSF
+	 * will force eject all LUNs it operates on (including those
+	 * marked as non-removable or with prevent_medium_removal flag
+	 * set). */
+	int			(*thread_exits)(struct fsg_common *common);
 	/* Gadget's private data. */
 	void			*private_data;
 
@@ -614,7 +618,12 @@ static int fsg_setup(struct usb_function
 			return -EDOM;
 		VDBG(fsg, "get max LUN\n");
 		*(u8 *) req->buf = fsg->common->nluns - 1;
-		return 1;
+
+		/* Respond with data/status */
+		req->length = min((u16)1, w_length);
+		fsg->common->ep0req_name =
+			ctrl->bRequestType & USB_DIR_IN ? "ep0-in" : "ep0-out";
+		return ep0_queue(fsg->common);
 	}
 
 	VDBG(fsg,
@@ -1041,7 +1050,7 @@ static void invalidate_sub(struct fsg_lu
 	unsigned long	rc;
 
 	rc = invalidate_mapping_pages(inode->i_mapping, 0, -1);
-	VLDBG(curlun, "invalidate_inode_pages -> %ld\n", rc);
+	VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc);
 }
 
 static int do_verify(struct fsg_common *common)
@@ -2524,14 +2533,6 @@ static void handle_exception(struct fsg_
 
 	case FSG_STATE_CONFIG_CHANGE:
 		rc = do_set_config(common, new_config);
-		if (common->ep0_req_tag != exception_req_tag)
-			break;
-		if (rc != 0) {			/* STALL on errors */
-			DBG(common, "ep0 set halt\n");
-			usb_ep_set_halt(common->ep0);
-		} else {			/* Complete the status stage */
-			ep0_queue(common);
-		}
 		break;
 
 	case FSG_STATE_EXIT:
@@ -2615,8 +2616,20 @@ static int fsg_main_thread(void *common_
 	common->thread_task = NULL;
 	spin_unlock_irq(&common->lock);
 
-	if (common->thread_exits)
-		common->thread_exits(common);
+	if (!common->thread_exits || common->thread_exits(common) < 0) {
+		struct fsg_lun *curlun = common->luns;
+		unsigned i = common->nluns;
+
+		down_write(&common->filesem);
+		for (; i--; ++curlun) {
+			if (!fsg_lun_is_open(curlun))
+				continue;
+
+			fsg_lun_close(curlun);
+			curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT;
+		}
+		up_write(&common->filesem);
+	}
 
 	/* Let the unbind and cleanup routines know the thread has exited */
 	complete_and_exit(&common->thread_notifier, 0);
@@ -2763,10 +2776,7 @@ static struct fsg_common *fsg_common_ini
 	if (cfg->release != 0xffff) {
 		i = cfg->release;
 	} else {
-		/* The sa1100 controller is not supported */
-		i = gadget_is_sa1100(gadget)
-			? -1
-			: usb_gadget_controller_number(gadget);
+		i = usb_gadget_controller_number(gadget);
 		if (i >= 0) {
 			i = 0x0300 + i;
 		} else {
@@ -2791,8 +2801,7 @@ static struct fsg_common *fsg_common_ini
 	 * disable stalls.
 	 */
 	common->can_stall = cfg->can_stall &&
-		!(gadget_is_sh(common->gadget) ||
-		  gadget_is_at91(common->gadget));
+		!(gadget_is_at91(common->gadget));
 
 
 	spin_lock_init(&common->lock);
@@ -2852,7 +2861,6 @@ error_release:
 	/* Call fsg_common_release() directly, ref might be not
 	 * initialised */
 	fsg_common_release(&common->ref);
-	complete(&common->thread_notifier);
 	return ERR_PTR(rc);
 }
 
@@ -2902,7 +2910,7 @@ static void fsg_unbind(struct usb_config
 }
 
 
-static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+static int __init fsg_bind(struct usb_configuration *c, struct usb_function *f)
 {
 	struct fsg_dev		*fsg = fsg_from_func(f);
 	struct usb_gadget	*gadget = c->cdev->gadget;
@@ -2946,7 +2954,6 @@ static int fsg_bind(struct usb_configura
 autoconf_fail:
 	ERROR(fsg, "unable to autoconfigure all endpoints\n");
 	rc = -ENOTSUPP;
-	fsg_unbind(c, f);
 	return rc;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_obex.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_obex.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_obex.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_obex.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 
 /* #define VERBOSE_DEBUG */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_phonet.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_phonet.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_phonet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_phonet.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  * 02110-1301 USA
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_rndis.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_rndis.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_rndis.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_rndis.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 
 /* #define VERBOSE_DEBUG */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/etherdevice.h>
@@ -769,10 +770,6 @@ rndis_unbind(struct usb_configuration *c
 /* Some controllers can't support RNDIS ... */
 static inline bool can_support_rndis(struct usb_configuration *c)
 {
-	/* only two endpoints on sa1100 */
-	if (gadget_is_sa1100(c->cdev->gadget))
-		return false;
-
 	/* everything else is *presumably* fine */
 	return true;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_serial.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_serial.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  * either version 2 of that License or (at your option) any later version.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/fsl_mx3_udc.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/fsl_mx3_udc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/fsl_mx3_udc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/fsl_mx3_udc.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,8 @@
 #include <linux/fsl_devices.h>
 #include <linux/platform_device.h>
 
+#include <mach/hardware.h>
+
 static struct clk *mxc_ahb_clk;
 static struct clk *mxc_usb_clk;
 
@@ -28,14 +30,16 @@ int fsl_udc_clk_init(struct platform_dev
 
 	pdata = pdev->dev.platform_data;
 
-	mxc_ahb_clk = clk_get(&pdev->dev, "usb_ahb");
-	if (IS_ERR(mxc_ahb_clk))
-		return PTR_ERR(mxc_ahb_clk);
+	if (!cpu_is_mx35()) {
+		mxc_ahb_clk = clk_get(&pdev->dev, "usb_ahb");
+		if (IS_ERR(mxc_ahb_clk))
+			return PTR_ERR(mxc_ahb_clk);
 
-	ret = clk_enable(mxc_ahb_clk);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "clk_enable(\"usb_ahb\") failed\n");
-		goto eenahb;
+		ret = clk_enable(mxc_ahb_clk);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "clk_enable(\"usb_ahb\") failed\n");
+			goto eenahb;
+		}
 	}
 
 	/* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */
@@ -50,6 +54,7 @@ int fsl_udc_clk_init(struct platform_dev
 	if (pdata->phy_mode != FSL_USB2_PHY_ULPI &&
 	    (freq < 59999000 || freq > 60001000)) {
 		dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq);
+		ret = -EINVAL;
 		goto eclkrate;
 	}
 
@@ -66,9 +71,11 @@ eclkrate:
 	clk_put(mxc_usb_clk);
 	mxc_usb_clk = NULL;
 egusb:
-	clk_disable(mxc_ahb_clk);
+	if (!cpu_is_mx35())
+		clk_disable(mxc_ahb_clk);
 eenahb:
-	clk_put(mxc_ahb_clk);
+	if (!cpu_is_mx35())
+		clk_put(mxc_ahb_clk);
 	return ret;
 }
 
@@ -90,6 +97,8 @@ void fsl_udc_clk_release(void)
 		clk_disable(mxc_usb_clk);
 		clk_put(mxc_usb_clk);
 	}
-	clk_disable(mxc_ahb_clk);
-	clk_put(mxc_ahb_clk);
+	if (!cpu_is_mx35()) {
+		clk_disable(mxc_ahb_clk);
+		clk_put(mxc_ahb_clk);
+	}
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/fsl_qe_udc.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/fsl_qe_udc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/fsl_qe_udc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/fsl_qe_udc.c	2010-05-16 17:17:36.000000000 -0400
@@ -2749,7 +2749,7 @@ static int __devexit qe_udc_remove(struc
 }
 
 /*-------------------------------------------------------------------------*/
-static struct of_device_id __devinitdata qe_udc_match[] = {
+static const struct of_device_id qe_udc_match[] __devinitconst = {
 	{
 		.compatible = "fsl,mpc8323-qe-usb",
 		.data = (void *)PORT_QE,
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_sourcesink.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_sourcesink.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_sourcesink.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_sourcesink.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 
 /* #define VERBOSE_DEBUG */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_subset.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_subset.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/f_subset.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/f_subset.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/etherdevice.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/gadget_chips.h linux-libre-2.6.34-gnu1/drivers/usb/gadget/gadget_chips.h
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/gadget_chips.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/gadget_chips.h	2010-05-16 17:17:36.000000000 -0400
@@ -45,46 +45,18 @@
 #define	gadget_is_goku(g)	0
 #endif
 
-/* SH3 UDC -- not yet ported 2.4 --> 2.6 */
-#ifdef CONFIG_USB_GADGET_SUPERH
-#define	gadget_is_sh(g)		!strcmp("sh_udc", (g)->name)
-#else
-#define	gadget_is_sh(g)		0
-#endif
-
-/* not yet stable on 2.6 (would help "original Zaurus") */
-#ifdef CONFIG_USB_GADGET_SA1100
-#define	gadget_is_sa1100(g)	!strcmp("sa1100_udc", (g)->name)
-#else
-#define	gadget_is_sa1100(g)	0
-#endif
-
 #ifdef CONFIG_USB_GADGET_LH7A40X
 #define	gadget_is_lh7a40x(g)	!strcmp("lh7a40x_udc", (g)->name)
 #else
 #define	gadget_is_lh7a40x(g)	0
 #endif
 
-/* handhelds.org tree (?) */
-#ifdef CONFIG_USB_GADGET_MQ11XX
-#define	gadget_is_mq11xx(g)	!strcmp("mq11xx_udc", (g)->name)
-#else
-#define	gadget_is_mq11xx(g)	0
-#endif
-
 #ifdef CONFIG_USB_GADGET_OMAP
 #define	gadget_is_omap(g)	!strcmp("omap_udc", (g)->name)
 #else
 #define	gadget_is_omap(g)	0
 #endif
 
-/* not yet ported 2.4 --> 2.6 */
-#ifdef CONFIG_USB_GADGET_N9604
-#define	gadget_is_n9604(g)	!strcmp("n9604_udc", (g)->name)
-#else
-#define	gadget_is_n9604(g)	0
-#endif
-
 /* various unstable versions available */
 #ifdef CONFIG_USB_GADGET_PXA27X
 #define	gadget_is_pxa27x(g)	!strcmp("pxa27x_udc", (g)->name)
@@ -122,14 +94,6 @@
 #define gadget_is_fsl_usb2(g)	0
 #endif
 
-/* Mentor high speed function controller */
-/* from Montavista kernel (?) */
-#ifdef CONFIG_USB_GADGET_MUSBHSFC
-#define gadget_is_musbhsfc(g)	!strcmp("musbhsfc_udc", (g)->name)
-#else
-#define gadget_is_musbhsfc(g)	0
-#endif
-
 /* Mentor high speed "dual role" controller, in peripheral role */
 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
 #define gadget_is_musbhdrc(g)	!strcmp("musb_hdrc", (g)->name)
@@ -143,13 +107,6 @@
 #define gadget_is_langwell(g)	0
 #endif
 
-/* from Montavista kernel (?) */
-#ifdef CONFIG_USB_GADGET_MPC8272
-#define gadget_is_mpc8272(g)	!strcmp("mpc8272_udc", (g)->name)
-#else
-#define gadget_is_mpc8272(g)	0
-#endif
-
 #ifdef CONFIG_USB_GADGET_M66592
 #define	gadget_is_m66592(g)	!strcmp("m66592_udc", (g)->name)
 #else
@@ -179,6 +136,12 @@
 #define	gadget_is_r8a66597(g)	0
 #endif
 
+#ifdef CONFIG_USB_S3C_HSOTG
+#define gadget_is_s3c_hsotg(g)    (!strcmp("s3c-hsotg", (g)->name))
+#else
+#define gadget_is_s3c_hsotg(g)    0
+#endif
+
 
 /**
  * usb_gadget_controller_number - support bcdDevice id convention
@@ -203,20 +166,12 @@ static inline int usb_gadget_controller_
 		return 0x02;
 	else if (gadget_is_pxa(gadget))
 		return 0x03;
-	else if (gadget_is_sh(gadget))
-		return 0x04;
-	else if (gadget_is_sa1100(gadget))
-		return 0x05;
 	else if (gadget_is_goku(gadget))
 		return 0x06;
-	else if (gadget_is_mq11xx(gadget))
-		return 0x07;
 	else if (gadget_is_omap(gadget))
 		return 0x08;
 	else if (gadget_is_lh7a40x(gadget))
 		return 0x09;
-	else if (gadget_is_n9604(gadget))
-		return 0x10;
 	else if (gadget_is_pxa27x(gadget))
 		return 0x11;
 	else if (gadget_is_s3c2410(gadget))
@@ -225,12 +180,8 @@ static inline int usb_gadget_controller_
 		return 0x13;
 	else if (gadget_is_imx(gadget))
 		return 0x14;
-	else if (gadget_is_musbhsfc(gadget))
-		return 0x15;
 	else if (gadget_is_musbhdrc(gadget))
 		return 0x16;
-	else if (gadget_is_mpc8272(gadget))
-		return 0x17;
 	else if (gadget_is_atmel_usba(gadget))
 		return 0x18;
 	else if (gadget_is_fsl_usb2(gadget))
@@ -247,6 +198,8 @@ static inline int usb_gadget_controller_
 		return 0x24;
 	else if (gadget_is_r8a66597(gadget))
 		return 0x25;
+	else if (gadget_is_s3c_hsotg(gadget))
+		return 0x26;
 	return -ENOENT;
 }
 
@@ -265,10 +218,6 @@ static inline bool gadget_supports_altse
 	if (gadget_is_pxa27x(gadget))
 		return false;
 
-	/* SH3 hardware just doesn't do altsettings */
-	if (gadget_is_sh(gadget))
-		return false;
-
 	/* Everything else is *presumably* fine ... */
 	return true;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/gmidi.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/gmidi.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/gmidi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/gmidi.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 /* #define VERBOSE_DEBUG */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/utsname.h>
 #include <linux/device.h>
 
@@ -237,7 +238,7 @@ static const struct usb_interface_descri
 };
 
 /* B.3.2  Class-Specific AC Interface Descriptor */
-static const struct uac_ac_header_descriptor_1 ac_header_desc = {
+static const struct uac_ac_header_descriptor_v1_1 ac_header_desc = {
 	.bLength =		UAC_DT_AC_HEADER_SIZE(1),
 	.bDescriptorType =	USB_DT_CS_INTERFACE,
 	.bDescriptorSubtype =	USB_MS_HEADER,
@@ -618,11 +619,6 @@ gmidi_set_config(struct gmidi_device *de
 	}
 #endif
 
-	if (gadget_is_sa1100(gadget) && dev->config) {
-		/* tx fifo is full, but we can't clear it...*/
-		ERROR(dev, "can't change configurations\n");
-		return -ESPIPE;
-	}
 	gmidi_reset_config(dev);
 
 	switch (number) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/goku_udc.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/goku_udc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/goku_udc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/goku_udc.c	2010-05-16 17:17:36.000000000 -0400
@@ -1768,7 +1768,7 @@ static int goku_probe(struct pci_dev *pd
 	 * usb_gadget_driver_{register,unregister}() must change.
 	 */
 	if (the_controller) {
-		WARNING(dev, "ignoring %s\n", pci_name(pdev));
+		pr_warning("ignoring %s\n", pci_name(pdev));
 		return -EBUSY;
 	}
 	if (!pdev->irq) {
@@ -1859,7 +1859,7 @@ done:
 
 /*-------------------------------------------------------------------------*/
 
-static struct pci_device_id pci_ids [] = { {
+static const struct pci_device_id pci_ids[] = { {
 	.class =	((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
 	.class_mask =	~0,
 	.vendor =	0x102f,		/* Toshiba */
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/imx_udc.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/imx_udc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/imx_udc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/imx_udc.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/inode.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/inode.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -194,7 +194,7 @@ enum ep_state {
 };
 
 struct ep_data {
-	struct semaphore		lock;
+	struct mutex			lock;
 	enum ep_state			state;
 	atomic_t			count;
 	struct dev_data			*dev;
@@ -298,10 +298,10 @@ get_ready_ep (unsigned f_flags, struct e
 	int	val;
 
 	if (f_flags & O_NONBLOCK) {
-		if (down_trylock (&epdata->lock) != 0)
+		if (!mutex_trylock(&epdata->lock))
 			goto nonblock;
 		if (epdata->state != STATE_EP_ENABLED) {
-			up (&epdata->lock);
+			mutex_unlock(&epdata->lock);
 nonblock:
 			val = -EAGAIN;
 		} else
@@ -309,7 +309,8 @@ nonblock:
 		return val;
 	}
 
-	if ((val = down_interruptible (&epdata->lock)) < 0)
+	val = mutex_lock_interruptible(&epdata->lock);
+	if (val < 0)
 		return val;
 
 	switch (epdata->state) {
@@ -323,7 +324,7 @@ nonblock:
 		// FALLTHROUGH
 	case STATE_EP_UNBOUND:			/* clean disconnect */
 		val = -ENODEV;
-		up (&epdata->lock);
+		mutex_unlock(&epdata->lock);
 	}
 	return val;
 }
@@ -393,7 +394,7 @@ ep_read (struct file *fd, char __user *b
 		if (likely (data->ep != NULL))
 			usb_ep_set_halt (data->ep);
 		spin_unlock_irq (&data->dev->lock);
-		up (&data->lock);
+		mutex_unlock(&data->lock);
 		return -EBADMSG;
 	}
 
@@ -411,7 +412,7 @@ ep_read (struct file *fd, char __user *b
 		value = -EFAULT;
 
 free1:
-	up (&data->lock);
+	mutex_unlock(&data->lock);
 	kfree (kbuf);
 	return value;
 }
@@ -436,7 +437,7 @@ ep_write (struct file *fd, const char __
 		if (likely (data->ep != NULL))
 			usb_ep_set_halt (data->ep);
 		spin_unlock_irq (&data->dev->lock);
-		up (&data->lock);
+		mutex_unlock(&data->lock);
 		return -EBADMSG;
 	}
 
@@ -455,7 +456,7 @@ ep_write (struct file *fd, const char __
 	VDEBUG (data->dev, "%s write %zu IN, status %d\n",
 		data->name, len, (int) value);
 free1:
-	up (&data->lock);
+	mutex_unlock(&data->lock);
 	kfree (kbuf);
 	return value;
 }
@@ -466,7 +467,8 @@ ep_release (struct inode *inode, struct
 	struct ep_data		*data = fd->private_data;
 	int value;
 
-	if ((value = down_interruptible(&data->lock)) < 0)
+	value = mutex_lock_interruptible(&data->lock);
+	if (value < 0)
 		return value;
 
 	/* clean up if this can be reopened */
@@ -476,7 +478,7 @@ ep_release (struct inode *inode, struct
 		data->hs_desc.bDescriptorType = 0;
 		usb_ep_disable(data->ep);
 	}
-	up (&data->lock);
+	mutex_unlock(&data->lock);
 	put_ep (data);
 	return 0;
 }
@@ -507,7 +509,7 @@ static long ep_ioctl(struct file *fd, un
 	} else
 		status = -ENODEV;
 	spin_unlock_irq (&data->dev->lock);
-	up (&data->lock);
+	mutex_unlock(&data->lock);
 	return status;
 }
 
@@ -673,7 +675,7 @@ fail:
 		value = -ENODEV;
 	spin_unlock_irq(&epdata->dev->lock);
 
-	up(&epdata->lock);
+	mutex_unlock(&epdata->lock);
 
 	if (unlikely(value)) {
 		kfree(priv);
@@ -765,7 +767,8 @@ ep_config (struct file *fd, const char _
 	u32			tag;
 	int			value, length = len;
 
-	if ((value = down_interruptible (&data->lock)) < 0)
+	value = mutex_lock_interruptible(&data->lock);
+	if (value < 0)
 		return value;
 
 	if (data->state != STATE_EP_READY) {
@@ -854,7 +857,7 @@ fail:
 		data->desc.bDescriptorType = 0;
 		data->hs_desc.bDescriptorType = 0;
 	}
-	up (&data->lock);
+	mutex_unlock(&data->lock);
 	return value;
 fail0:
 	value = -EINVAL;
@@ -870,7 +873,7 @@ ep_open (struct inode *inode, struct fil
 	struct ep_data		*data = inode->i_private;
 	int			value = -EBUSY;
 
-	if (down_interruptible (&data->lock) != 0)
+	if (mutex_lock_interruptible(&data->lock) != 0)
 		return -EINTR;
 	spin_lock_irq (&data->dev->lock);
 	if (data->dev->state == STATE_DEV_UNBOUND)
@@ -885,7 +888,7 @@ ep_open (struct inode *inode, struct fil
 		DBG (data->dev, "%s state %d\n",
 			data->name, data->state);
 	spin_unlock_irq (&data->dev->lock);
-	up (&data->lock);
+	mutex_unlock(&data->lock);
 	return value;
 }
 
@@ -1631,7 +1634,7 @@ static int activate_ep_files (struct dev
 		if (!data)
 			goto enomem0;
 		data->state = STATE_EP_DISABLED;
-		init_MUTEX (&data->lock);
+		mutex_init(&data->lock);
 		init_waitqueue_head (&data->wait);
 
 		strncpy (data->name, ep->name, sizeof (data->name) - 1);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/Kconfig linux-libre-2.6.34-gnu1/drivers/usb/gadget/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -747,7 +747,7 @@ config USB_MASS_STORAGE
 	  which may be used with composite framework.
 
 	  Say "y" to link the driver statically, or "m" to build
-	  a dynamically linked module called "g_file_storage".  If unsure,
+	  a dynamically linked module called "g_mass_storage".  If unsure,
 	  consider File-backed Storage Gadget.
 
 config USB_G_SERIAL
@@ -812,6 +812,16 @@ config USB_CDC_COMPOSITE
 	  Say "y" to link the driver statically, or "m" to build a
 	  dynamically linked module.
 
+config USB_G_NOKIA
+	tristate "Nokia composite gadget"
+	depends on PHONET
+	help
+	  The Nokia composite gadget provides support for acm, obex
+	  and phonet in only one composite gadget driver.
+
+	  It's only really useful for N900 hardware. If you're building
+	  a kernel for N900, say Y or M here. If unsure, say N.
+
 config USB_G_MULTI
 	tristate "Multifunction Composite Gadget (EXPERIMENTAL)"
 	depends on BLOCK && NET
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/lh7a40x_udc.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/lh7a40x_udc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/lh7a40x_udc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/lh7a40x_udc.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include "lh7a40x_udc.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/m66592-udc.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/m66592-udc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/m66592-udc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/m66592-udc.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/Makefile linux-libre-2.6.34-gnu1/drivers/usb/gadget/Makefile
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,7 @@ g_mass_storage-objs		:= mass_storage.o
 g_printer-objs			:= printer.o
 g_cdc-objs			:= cdc2.o
 g_multi-objs			:= multi.o
+g_nokia-objs			:= nokia.o
 
 obj-$(CONFIG_USB_ZERO)		+= g_zero.o
 obj-$(CONFIG_USB_AUDIO)		+= g_audio.o
@@ -55,4 +56,5 @@ obj-$(CONFIG_USB_G_PRINTER)	+= g_printer
 obj-$(CONFIG_USB_MIDI_GADGET)	+= g_midi.o
 obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o
 obj-$(CONFIG_USB_G_MULTI)	+= g_multi.o
+obj-$(CONFIG_USB_G_NOKIA)	+= g_nokia.o
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/mass_storage.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/mass_storage.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/mass_storage.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/mass_storage.c	2010-05-16 17:17:36.000000000 -0400
@@ -135,6 +135,12 @@ FSG_MODULE_PARAMETERS(/* no prefix */, m
 static unsigned long msg_registered = 0;
 static void msg_cleanup(void);
 
+static int msg_thread_exits(struct fsg_common *common)
+{
+	msg_cleanup();
+	return 0;
+}
+
 static int __init msg_do_config(struct usb_configuration *c)
 {
 	struct fsg_common *common;
@@ -147,7 +153,7 @@ static int __init msg_do_config(struct u
 	}
 
 	fsg_config_from_params(&config, &mod_data);
-	config.thread_exits = (void(*)(struct fsg_common*))&msg_cleanup;
+	config.thread_exits = msg_thread_exits;
 	common = fsg_common_init(0, c->cdev, &config);
 	if (IS_ERR(common))
 		return PTR_ERR(common);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/multi.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/multi.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/multi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/multi.c	2010-05-16 17:17:36.000000000 -0400
@@ -211,8 +211,6 @@ static int __init cdc_do_config(struct u
 	ret = fsg_add(c->cdev, c, fsg_common);
 	if (ret < 0)
 		return ret;
-	if (ret < 0)
-		return ret;
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/nokia.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/nokia.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/nokia.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/nokia.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,259 @@
+/*
+ * nokia.c -- Nokia Composite Gadget Driver
+ *
+ * Copyright (C) 2008-2010 Nokia Corporation
+ * Contact: Felipe Balbi <felipe.balbi@nokia.com>
+ *
+ * This gadget driver borrows from serial.c which is:
+ *
+ * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
+ * Copyright (C) 2008 by David Brownell
+ * Copyright (C) 2008 by Nokia Corporation
+ *
+ * This software is distributed under the terms of the GNU General
+ * Public License ("GPL") as published by the Free Software Foundation,
+ * version 2 of that License.
+ */
+
+#include <linux/kernel.h>
+#include <linux/utsname.h>
+#include <linux/device.h>
+
+#include "u_serial.h"
+#include "u_ether.h"
+#include "u_phonet.h"
+#include "gadget_chips.h"
+
+/* Defines */
+
+#define NOKIA_VERSION_NUM		0x0211
+#define NOKIA_LONG_NAME			"N900 (PC-Suite Mode)"
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module.  So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "composite.c"
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+#include "u_serial.c"
+#include "f_acm.c"
+#include "f_ecm.c"
+#include "f_obex.c"
+#include "f_serial.c"
+#include "f_phonet.c"
+#include "u_ether.c"
+
+/*-------------------------------------------------------------------------*/
+
+#define NOKIA_VENDOR_ID			0x0421	/* Nokia */
+#define NOKIA_PRODUCT_ID		0x01c8	/* Nokia Gadget */
+
+/* string IDs are assigned dynamically */
+
+#define STRING_MANUFACTURER_IDX		0
+#define STRING_PRODUCT_IDX		1
+#define STRING_DESCRIPTION_IDX		2
+
+static char manufacturer_nokia[] = "Nokia";
+static const char product_nokia[] = NOKIA_LONG_NAME;
+static const char description_nokia[] = "PC-Suite Configuration";
+
+static struct usb_string strings_dev[] = {
+	[STRING_MANUFACTURER_IDX].s = manufacturer_nokia,
+	[STRING_PRODUCT_IDX].s = NOKIA_LONG_NAME,
+	[STRING_DESCRIPTION_IDX].s = description_nokia,
+	{  } /* end of list */
+};
+
+static struct usb_gadget_strings stringtab_dev = {
+	.language	= 0x0409,	/* en-us */
+	.strings	= strings_dev,
+};
+
+static struct usb_gadget_strings *dev_strings[] = {
+	&stringtab_dev,
+	NULL,
+};
+
+static struct usb_device_descriptor device_desc = {
+	.bLength		= USB_DT_DEVICE_SIZE,
+	.bDescriptorType	= USB_DT_DEVICE,
+	.bcdUSB			= __constant_cpu_to_le16(0x0200),
+	.bDeviceClass		= USB_CLASS_COMM,
+	.idVendor		= __constant_cpu_to_le16(NOKIA_VENDOR_ID),
+	.idProduct		= __constant_cpu_to_le16(NOKIA_PRODUCT_ID),
+	/* .iManufacturer = DYNAMIC */
+	/* .iProduct = DYNAMIC */
+	.bNumConfigurations =	1,
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* Module */
+MODULE_DESCRIPTION("Nokia composite gadget driver for N900");
+MODULE_AUTHOR("Felipe Balbi");
+MODULE_LICENSE("GPL");
+
+/*-------------------------------------------------------------------------*/
+
+static u8 hostaddr[ETH_ALEN];
+
+static int __init nokia_bind_config(struct usb_configuration *c)
+{
+	int status = 0;
+
+	status = phonet_bind_config(c);
+	if (status)
+		printk(KERN_DEBUG "could not bind phonet config\n");
+
+	status = obex_bind_config(c, 0);
+	if (status)
+		printk(KERN_DEBUG "could not bind obex config %d\n", 0);
+
+	status = obex_bind_config(c, 1);
+	if (status)
+		printk(KERN_DEBUG "could not bind obex config %d\n", 0);
+
+	status = acm_bind_config(c, 2);
+	if (status)
+		printk(KERN_DEBUG "could not bind acm config\n");
+
+	status = ecm_bind_config(c, hostaddr);
+	if (status)
+		printk(KERN_DEBUG "could not bind ecm config\n");
+
+	return status;
+}
+
+static struct usb_configuration nokia_config_500ma_driver = {
+	.label		= "Bus Powered",
+	.bind		= nokia_bind_config,
+	.bConfigurationValue = 1,
+	/* .iConfiguration = DYNAMIC */
+	.bmAttributes	= USB_CONFIG_ATT_ONE,
+	.bMaxPower	= 250, /* 500mA */
+};
+
+static struct usb_configuration nokia_config_100ma_driver = {
+	.label		= "Self Powered",
+	.bind		= nokia_bind_config,
+	.bConfigurationValue = 2,
+	/* .iConfiguration = DYNAMIC */
+	.bmAttributes	= USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
+	.bMaxPower	= 50, /* 100 mA */
+};
+
+static int __init nokia_bind(struct usb_composite_dev *cdev)
+{
+	int			gcnum;
+	struct usb_gadget	*gadget = cdev->gadget;
+	int			status;
+
+	status = gphonet_setup(cdev->gadget);
+	if (status < 0)
+		goto err_phonet;
+
+	status = gserial_setup(cdev->gadget, 3);
+	if (status < 0)
+		goto err_serial;
+
+	status = gether_setup(cdev->gadget, hostaddr);
+	if (status < 0)
+		goto err_ether;
+
+	status = usb_string_id(cdev);
+	if (status < 0)
+		goto err_usb;
+	strings_dev[STRING_MANUFACTURER_IDX].id = status;
+
+	device_desc.iManufacturer = status;
+
+	status = usb_string_id(cdev);
+	if (status < 0)
+		goto err_usb;
+	strings_dev[STRING_PRODUCT_IDX].id = status;
+
+	device_desc.iProduct = status;
+
+	/* config description */
+	status = usb_string_id(cdev);
+	if (status < 0)
+		goto err_usb;
+	strings_dev[STRING_DESCRIPTION_IDX].id = status;
+
+	nokia_config_500ma_driver.iConfiguration = status;
+	nokia_config_100ma_driver.iConfiguration = status;
+
+	/* set up other descriptors */
+	gcnum = usb_gadget_controller_number(gadget);
+	if (gcnum >= 0)
+		device_desc.bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM);
+	else {
+		/* this should only work with hw that supports altsettings
+		 * and several endpoints, anything else, panic.
+		 */
+		pr_err("nokia_bind: controller '%s' not recognized\n",
+			gadget->name);
+		goto err_usb;
+	}
+
+	/* finaly register the configuration */
+	status = usb_add_config(cdev, &nokia_config_500ma_driver);
+	if (status < 0)
+		goto err_usb;
+
+	status = usb_add_config(cdev, &nokia_config_100ma_driver);
+	if (status < 0)
+		goto err_usb;
+
+	dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME);
+
+	return 0;
+
+err_usb:
+	gether_cleanup();
+err_ether:
+	gserial_cleanup();
+err_serial:
+	gphonet_cleanup();
+err_phonet:
+	return status;
+}
+
+static int __exit nokia_unbind(struct usb_composite_dev *cdev)
+{
+	gphonet_cleanup();
+	gserial_cleanup();
+	gether_cleanup();
+
+	return 0;
+}
+
+static struct usb_composite_driver nokia_driver = {
+	.name		= "g_nokia",
+	.dev		= &device_desc,
+	.strings	= dev_strings,
+	.bind		= nokia_bind,
+	.unbind		= __exit_p(nokia_unbind),
+};
+
+static int __init nokia_init(void)
+{
+	return usb_composite_register(&nokia_driver);
+}
+module_init(nokia_init);
+
+static void __exit nokia_cleanup(void)
+{
+	usb_composite_unregister(&nokia_driver);
+}
+module_exit(nokia_cleanup);
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/printer.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/printer.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/printer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/printer.c	2010-05-16 17:17:36.000000000 -0400
@@ -949,12 +949,6 @@ printer_set_config(struct printer_dev *d
 	int			result = 0;
 	struct usb_gadget	*gadget = dev->gadget;
 
-	if (gadget_is_sa1100(gadget) && dev->config) {
-		/* tx fifo is full, but we can't clear it...*/
-		INFO(dev, "can't change configurations\n");
-		return -ESPIPE;
-	}
-
 	switch (number) {
 	case DEV_CONFIG_VALUE:
 		result = 0;
@@ -1033,12 +1027,6 @@ set_interface(struct printer_dev *dev, u
 {
 	int			result = 0;
 
-	if (gadget_is_sa1100(dev->gadget) && dev->interface < 0) {
-		/* tx fifo is full, but we can't clear it...*/
-		INFO(dev, "can't change interfaces\n");
-		return -ESPIPE;
-	}
-
 	/* Free the current interface */
 	switch (dev->interface) {
 	case PRINTER_INTERFACE:
@@ -1392,12 +1380,6 @@ printer_bind(struct usb_gadget *gadget)
 		goto fail;
 	}
 
-	if (gadget_is_sa1100(gadget)) {
-		/* hardware can't write zero length packets. */
-		ERROR(dev, "SA1100 controller is unsupport by this driver\n");
-		goto fail;
-	}
-
 	gcnum = usb_gadget_controller_number(gadget);
 	if (gcnum >= 0) {
 		device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/pxa25x_udc.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/pxa25x_udc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/pxa25x_udc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/pxa25x_udc.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,6 +65,10 @@
 #include <mach/pxa25x-udc.h>
 #endif
 
+#ifdef CONFIG_ARCH_LUBBOCK
+#include <mach/lubbock.h>
+#endif
+
 #include <asm/mach/udc_pxa2xx.h>
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/pxa27x_udc.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/pxa27x_udc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/pxa27x_udc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/pxa27x_udc.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <asm/byteorder.h>
 #include <mach/hardware.h>
@@ -742,13 +743,17 @@ static void ep_del_request(struct pxa_ep
  * @ep: pxa physical endpoint
  * @req: pxa request
  * @status: usb request status sent to gadget API
+ * @pflags: flags of previous spinlock_irq_save() or NULL if no lock held
  *
- * Context: ep->lock held
+ * Context: ep->lock held if flags not NULL, else ep->lock released
  *
  * Retire a pxa27x usb request. Endpoint must be locked.
  */
-static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status)
+static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status,
+	unsigned long *pflags)
 {
+	unsigned long	flags;
+
 	ep_del_request(ep, req);
 	if (likely(req->req.status == -EINPROGRESS))
 		req->req.status = status;
@@ -760,38 +765,48 @@ static void req_done(struct pxa_ep *ep,
 			&req->req, status,
 			req->req.actual, req->req.length);
 
+	if (pflags)
+		spin_unlock_irqrestore(&ep->lock, *pflags);
+	local_irq_save(flags);
 	req->req.complete(&req->udc_usb_ep->usb_ep, &req->req);
+	local_irq_restore(flags);
+	if (pflags)
+		spin_lock_irqsave(&ep->lock, *pflags);
 }
 
 /**
  * ep_end_out_req - Ends endpoint OUT request
  * @ep: physical endpoint
  * @req: pxa request
+ * @pflags: flags of previous spinlock_irq_save() or NULL if no lock held
  *
- * Context: ep->lock held
+ * Context: ep->lock held or released (see req_done())
  *
  * Ends endpoint OUT request (completes usb request).
  */
-static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
+static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req,
+	unsigned long *pflags)
 {
 	inc_ep_stats_reqs(ep, !USB_DIR_IN);
-	req_done(ep, req, 0);
+	req_done(ep, req, 0, pflags);
 }
 
 /**
  * ep0_end_out_req - Ends control endpoint OUT request (ends data stage)
  * @ep: physical endpoint
  * @req: pxa request
+ * @pflags: flags of previous spinlock_irq_save() or NULL if no lock held
  *
- * Context: ep->lock held
+ * Context: ep->lock held or released (see req_done())
  *
  * Ends control endpoint OUT request (completes usb request), and puts
  * control endpoint into idle state
  */
-static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
+static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req,
+	unsigned long *pflags)
 {
 	set_ep0state(ep->dev, OUT_STATUS_STAGE);
-	ep_end_out_req(ep, req);
+	ep_end_out_req(ep, req, pflags);
 	ep0_idle(ep->dev);
 }
 
@@ -799,31 +814,35 @@ static void ep0_end_out_req(struct pxa_e
  * ep_end_in_req - Ends endpoint IN request
  * @ep: physical endpoint
  * @req: pxa request
+ * @pflags: flags of previous spinlock_irq_save() or NULL if no lock held
  *
- * Context: ep->lock held
+ * Context: ep->lock held or released (see req_done())
  *
  * Ends endpoint IN request (completes usb request).
  */
-static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
+static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req,
+	unsigned long *pflags)
 {
 	inc_ep_stats_reqs(ep, USB_DIR_IN);
-	req_done(ep, req, 0);
+	req_done(ep, req, 0, pflags);
 }
 
 /**
  * ep0_end_in_req - Ends control endpoint IN request (ends data stage)
  * @ep: physical endpoint
  * @req: pxa request
+ * @pflags: flags of previous spinlock_irq_save() or NULL if no lock held
  *
- * Context: ep->lock held
+ * Context: ep->lock held or released (see req_done())
  *
  * Ends control endpoint IN request (completes usb request), and puts
  * control endpoint into status state
  */
-static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
+static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req,
+	unsigned long *pflags)
 {
 	set_ep0state(ep->dev, IN_STATUS_STAGE);
-	ep_end_in_req(ep, req);
+	ep_end_in_req(ep, req, pflags);
 }
 
 /**
@@ -831,19 +850,22 @@ static void ep0_end_in_req(struct pxa_ep
  * @ep: pxa endpoint
  * @status: usb request status
  *
- * Context: ep->lock held
+ * Context: ep->lock released
  *
  * Dequeues all requests on an endpoint. As a side effect, interrupts will be
  * disabled on that endpoint (because no more requests).
  */
 static void nuke(struct pxa_ep *ep, int status)
 {
-	struct pxa27x_request *req;
+	struct pxa27x_request	*req;
+	unsigned long		flags;
 
+	spin_lock_irqsave(&ep->lock, flags);
 	while (!list_empty(&ep->queue)) {
 		req = list_entry(ep->queue.next, struct pxa27x_request, queue);
-		req_done(ep, req, status);
+		req_done(ep, req, status, &flags);
 	}
+	spin_unlock_irqrestore(&ep->lock, flags);
 }
 
 /**
@@ -1123,6 +1145,7 @@ static int pxa_ep_queue(struct usb_ep *_
 	int			rc = 0;
 	int			is_first_req;
 	unsigned		length;
+	int			recursion_detected;
 
 	req = container_of(_req, struct pxa27x_request, req);
 	udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
@@ -1152,6 +1175,7 @@ static int pxa_ep_queue(struct usb_ep *_
 		return -EMSGSIZE;
 
 	spin_lock_irqsave(&ep->lock, flags);
+	recursion_detected = ep->in_handle_ep;
 
 	is_first_req = list_empty(&ep->queue);
 	ep_dbg(ep, "queue req %p(first=%s), len %d buf %p\n",
@@ -1161,12 +1185,12 @@ static int pxa_ep_queue(struct usb_ep *_
 	if (!ep->enabled) {
 		_req->status = -ESHUTDOWN;
 		rc = -ESHUTDOWN;
-		goto out;
+		goto out_locked;
 	}
 
 	if (req->in_use) {
 		ep_err(ep, "refusing to queue req %p (already queued)\n", req);
-		goto out;
+		goto out_locked;
 	}
 
 	length = _req->length;
@@ -1174,12 +1198,13 @@ static int pxa_ep_queue(struct usb_ep *_
 	_req->actual = 0;
 
 	ep_add_request(ep, req);
+	spin_unlock_irqrestore(&ep->lock, flags);
 
 	if (is_ep0(ep)) {
 		switch (dev->ep0state) {
 		case WAIT_ACK_SET_CONF_INTERF:
 			if (length == 0) {
-				ep_end_in_req(ep, req);
+				ep_end_in_req(ep, req, NULL);
 			} else {
 				ep_err(ep, "got a request of %d bytes while"
 					"in state WAIT_ACK_SET_CONF_INTERF\n",
@@ -1192,12 +1217,12 @@ static int pxa_ep_queue(struct usb_ep *_
 		case IN_DATA_STAGE:
 			if (!ep_is_full(ep))
 				if (write_ep0_fifo(ep, req))
-					ep0_end_in_req(ep, req);
+					ep0_end_in_req(ep, req, NULL);
 			break;
 		case OUT_DATA_STAGE:
 			if ((length == 0) || !epout_has_pkt(ep))
 				if (read_ep0_fifo(ep, req))
-					ep0_end_out_req(ep, req);
+					ep0_end_out_req(ep, req, NULL);
 			break;
 		default:
 			ep_err(ep, "odd state %s to send me a request\n",
@@ -1207,12 +1232,15 @@ static int pxa_ep_queue(struct usb_ep *_
 			break;
 		}
 	} else {
-		handle_ep(ep);
+		if (!recursion_detected)
+			handle_ep(ep);
 	}
 
 out:
-	spin_unlock_irqrestore(&ep->lock, flags);
 	return rc;
+out_locked:
+	spin_unlock_irqrestore(&ep->lock, flags);
+	goto out;
 }
 
 /**
@@ -1242,13 +1270,14 @@ static int pxa_ep_dequeue(struct usb_ep
 	/* make sure it's actually queued on this endpoint */
 	list_for_each_entry(req, &ep->queue, queue) {
 		if (&req->req == _req) {
-			req_done(ep, req, -ECONNRESET);
 			rc = 0;
 			break;
 		}
 	}
 
 	spin_unlock_irqrestore(&ep->lock, flags);
+	if (!rc)
+		req_done(ep, req, -ECONNRESET, NULL);
 	return rc;
 }
 
@@ -1445,7 +1474,6 @@ static int pxa_ep_disable(struct usb_ep
 {
 	struct pxa_ep		*ep;
 	struct udc_usb_ep	*udc_usb_ep;
-	unsigned long		flags;
 
 	if (!_ep)
 		return -EINVAL;
@@ -1455,10 +1483,8 @@ static int pxa_ep_disable(struct usb_ep
 	if (!ep || is_ep0(ep) || !list_empty(&ep->queue))
 		return -EINVAL;
 
-	spin_lock_irqsave(&ep->lock, flags);
 	ep->enabled = 0;
 	nuke(ep, -ESHUTDOWN);
-	spin_unlock_irqrestore(&ep->lock, flags);
 
 	pxa_ep_fifo_flush(_ep);
 	udc_usb_ep->pxa_ep = NULL;
@@ -1907,8 +1933,10 @@ static void handle_ep0_ctrl_req(struct p
 	} u;
 	int i;
 	int have_extrabytes = 0;
+	unsigned long flags;
 
 	nuke(ep, -EPROTO);
+	spin_lock_irqsave(&ep->lock, flags);
 
 	/*
 	 * In the PXA320 manual, in the section about Back-to-Back setup
@@ -1947,10 +1975,13 @@ static void handle_ep0_ctrl_req(struct p
 	/* Tell UDC to enter Data Stage */
 	ep_write_UDCCSR(ep, UDCCSR0_SA | UDCCSR0_OPC);
 
+	spin_unlock_irqrestore(&ep->lock, flags);
 	i = udc->driver->setup(&udc->gadget, &u.r);
+	spin_lock_irqsave(&ep->lock, flags);
 	if (i < 0)
 		goto stall;
 out:
+	spin_unlock_irqrestore(&ep->lock, flags);
 	return;
 stall:
 	ep_dbg(ep, "protocol STALL, udccsr0=%03x err %d\n",
@@ -2055,13 +2086,13 @@ static void handle_ep0(struct pxa_udc *u
 		if (req && !ep_is_full(ep))
 			completed = write_ep0_fifo(ep, req);
 		if (completed)
-			ep0_end_in_req(ep, req);
+			ep0_end_in_req(ep, req, NULL);
 		break;
 	case OUT_DATA_STAGE:			/* SET_DESCRIPTOR */
 		if (epout_has_pkt(ep) && req)
 			completed = read_ep0_fifo(ep, req);
 		if (completed)
-			ep0_end_out_req(ep, req);
+			ep0_end_out_req(ep, req, NULL);
 		break;
 	case STALL:
 		ep_write_UDCCSR(ep, UDCCSR0_FST);
@@ -2091,7 +2122,7 @@ static void handle_ep0(struct pxa_udc *u
  * Tries to transfer all pending request data into the endpoint and/or
  * transfer all pending data in the endpoint into usb requests.
  *
- * Is always called when in_interrupt() or with ep->lock held.
+ * Is always called when in_interrupt() and with ep->lock released.
  */
 static void handle_ep(struct pxa_ep *ep)
 {
@@ -2100,10 +2131,17 @@ static void handle_ep(struct pxa_ep *ep)
 	u32 udccsr;
 	int is_in = ep->dir_in;
 	int loop = 0;
+	unsigned long		flags;
+
+	spin_lock_irqsave(&ep->lock, flags);
+	if (ep->in_handle_ep)
+		goto recursion_detected;
+	ep->in_handle_ep = 1;
 
 	do {
 		completed = 0;
 		udccsr = udc_ep_readl(ep, UDCCSR);
+
 		if (likely(!list_empty(&ep->queue)))
 			req = list_entry(ep->queue.next,
 					struct pxa27x_request, queue);
@@ -2122,15 +2160,22 @@ static void handle_ep(struct pxa_ep *ep)
 		if (unlikely(is_in)) {
 			if (likely(!ep_is_full(ep)))
 				completed = write_fifo(ep, req);
-			if (completed)
-				ep_end_in_req(ep, req);
 		} else {
 			if (likely(epout_has_pkt(ep)))
 				completed = read_fifo(ep, req);
-			if (completed)
-				ep_end_out_req(ep, req);
+		}
+
+		if (completed) {
+			if (is_in)
+				ep_end_in_req(ep, req, &flags);
+			else
+				ep_end_out_req(ep, req, &flags);
 		}
 	} while (completed);
+
+	ep->in_handle_ep = 0;
+recursion_detected:
+	spin_unlock_irqrestore(&ep->lock, flags);
 }
 
 /**
@@ -2218,9 +2263,13 @@ static void irq_handle_data(int irq, str
 			continue;
 
 		udc_writel(udc, UDCISR0, UDCISR_INT(i, UDCISR_INT_MASK));
-		ep = &udc->pxa_ep[i];
-		ep->stats.irqs++;
-		handle_ep(ep);
+
+		WARN_ON(i >= ARRAY_SIZE(udc->pxa_ep));
+		if (i < ARRAY_SIZE(udc->pxa_ep)) {
+			ep = &udc->pxa_ep[i];
+			ep->stats.irqs++;
+			handle_ep(ep);
+		}
 	}
 
 	for (i = 16; udcisr1 != 0 && i < 24; udcisr1 >>= 2, i++) {
@@ -2228,9 +2277,12 @@ static void irq_handle_data(int irq, str
 		if (!(udcisr1 & UDCISR_INT_MASK))
 			continue;
 
-		ep = &udc->pxa_ep[i];
-		ep->stats.irqs++;
-		handle_ep(ep);
+		WARN_ON(i >= ARRAY_SIZE(udc->pxa_ep));
+		if (i < ARRAY_SIZE(udc->pxa_ep)) {
+			ep = &udc->pxa_ep[i];
+			ep->stats.irqs++;
+			handle_ep(ep);
+		}
 	}
 
 }
@@ -2439,7 +2491,7 @@ static int __init pxa_udc_probe(struct p
 	}
 
 	retval = -ENOMEM;
-	udc->regs = ioremap(regs->start, regs->end - regs->start + 1);
+	udc->regs = ioremap(regs->start, resource_size(regs));
 	if (!udc->regs) {
 		dev_err(&pdev->dev, "Unable to map UDC I/O memory\n");
 		goto err_map;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/pxa27x_udc.h linux-libre-2.6.34-gnu1/drivers/usb/gadget/pxa27x_udc.h
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/pxa27x_udc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/pxa27x_udc.h	2010-05-16 17:17:36.000000000 -0400
@@ -318,6 +318,11 @@ struct udc_usb_ep {
  * @queue: requests queue
  * @lock: lock to pxa_ep data (queues and stats)
  * @enabled: true when endpoint enabled (not stopped by gadget layer)
+ * @in_handle_ep: number of recursions of handle_ep() function
+ * 	Prevents deadlocks or infinite recursions of types :
+ *	  irq->handle_ep()->req_done()->req.complete()->pxa_ep_queue()->handle_ep()
+ *      or
+ *        pxa_ep_queue()->handle_ep()->req_done()->req.complete()->pxa_ep_queue()
  * @idx: endpoint index (1 => epA, 2 => epB, ..., 24 => epX)
  * @name: endpoint name (for trace/debug purpose)
  * @dir_in: 1 if IN endpoint, 0 if OUT endpoint
@@ -346,6 +351,7 @@ struct pxa_ep {
 	spinlock_t		lock;		/* Protects this structure */
 						/* (queues, stats) */
 	unsigned		enabled:1;
+	unsigned		in_handle_ep:1;
 
 	unsigned		idx:5;
 	char			*name;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/r8a66597-udc.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/r8a66597-udc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/r8a66597-udc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/r8a66597-udc.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/rndis.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/rndis.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/rndis.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/rndis.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/netdevice.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/s3c-hsotg.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/s3c-hsotg.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/s3c-hsotg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/s3c-hsotg.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/seq_file.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
@@ -30,7 +31,7 @@
 
 #include <plat/regs-usb-hsotg-phy.h>
 #include <plat/regs-usb-hsotg.h>
-#include <plat/regs-sys.h>
+#include <mach/regs-sys.h>
 #include <plat/udc-hs.h>
 
 #define DMA_ADDR_INVALID (~((dma_addr_t)0))
@@ -317,7 +318,8 @@ static void s3c_hsotg_init_fifo(struct s
  *
  * Allocate a new USB request structure appropriate for the specified endpoint
  */
-struct usb_request *s3c_hsotg_ep_alloc_request(struct usb_ep *ep, gfp_t flags)
+static struct usb_request *s3c_hsotg_ep_alloc_request(struct usb_ep *ep,
+						      gfp_t flags)
 {
 	struct s3c_hsotg_req *req;
 
@@ -373,7 +375,7 @@ static void s3c_hsotg_unmap_dma(struct s
 		req->dma = DMA_ADDR_INVALID;
 		hs_req->mapped = 0;
 	} else {
-		dma_sync_single(hsotg->dev, req->dma, req->length, dir);
+		dma_sync_single_for_cpu(hsotg->dev, req->dma, req->length, dir);
 	}
 }
 
@@ -755,7 +757,7 @@ static int s3c_hsotg_map_dma(struct s3c_
 		hs_req->mapped = 1;
 		req->dma = dma;
 	} else {
-		dma_sync_single(hsotg->dev, req->dma, req->length, dir);
+		dma_sync_single_for_cpu(hsotg->dev, req->dma, req->length, dir);
 		hs_req->mapped = 0;
 	}
 
@@ -1460,7 +1462,7 @@ static u32 s3c_hsotg_read_frameno(struct
  * as the actual data should be sent to the memory directly and we turn
  * on the completion interrupts to get notifications of transfer completion.
  */
-void s3c_hsotg_handle_rx(struct s3c_hsotg *hsotg)
+static void s3c_hsotg_handle_rx(struct s3c_hsotg *hsotg)
 {
 	u32 grxstsr = readl(hsotg->regs + S3C_GRXSTSP);
 	u32 epnum, status, size;
@@ -2143,6 +2145,7 @@ static int s3c_hsotg_ep_enable(struct us
 	u32 epctrl;
 	u32 mps;
 	int dir_in;
+	int ret = 0;
 
 	dev_dbg(hsotg->dev,
 		"%s: ep %s: a 0x%02x, attr 0x%02x, mps 0x%04x, intr %d\n",
@@ -2194,7 +2197,8 @@ static int s3c_hsotg_ep_enable(struct us
 	switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
 	case USB_ENDPOINT_XFER_ISOC:
 		dev_err(hsotg->dev, "no current ISOC support\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 
 	case USB_ENDPOINT_XFER_BULK:
 		epctrl |= S3C_DxEPCTL_EPType_Bulk;
@@ -2233,8 +2237,9 @@ static int s3c_hsotg_ep_enable(struct us
 	/* enable the endpoint interrupt */
 	s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1);
 
+out:
 	spin_unlock_irqrestore(&hs_ep->lock, flags);
-	return 0;
+	return ret;
 }
 
 static int s3c_hsotg_ep_disable(struct usb_ep *ep)
@@ -3094,7 +3099,7 @@ static void s3c_hsotg_gate(struct platfo
 	local_irq_restore(flags);
 }
 
-struct s3c_hsotg_plat s3c_hsotg_default_pdata;
+static struct s3c_hsotg_plat s3c_hsotg_default_pdata;
 
 static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/u_audio.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/u_audio.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/u_audio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/u_audio.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/delay.h>
 #include <linux/ctype.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/u_ether.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/u_ether.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/u_ether.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/u_ether.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 /* #define VERBOSE_DEBUG */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/device.h>
 #include <linux/ctype.h>
 #include <linux/etherdevice.h>
@@ -746,6 +747,10 @@ static const struct net_device_ops eth_n
 	.ndo_validate_addr	= eth_validate_addr,
 };
 
+static struct device_type gadget_type = {
+	.name	= "gadget",
+};
+
 /**
  * gether_setup - initialize one ethernet-over-usb link
  * @g: gadget to associated with these links
@@ -808,6 +813,7 @@ int __init gether_setup(struct usb_gadge
 
 	dev->gadget = g;
 	SET_NETDEV_DEV(net, &g->dev);
+	SET_NETDEV_DEVTYPE(net, &gadget_type);
 
 	status = register_netdev(net);
 	if (status < 0) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/u_ether.h linux-libre-2.6.34-gnu1/drivers/usb/gadget/u_ether.h
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/u_ether.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/u_ether.h	2010-05-16 17:17:36.000000000 -0400
@@ -93,13 +93,6 @@ static inline bool can_support_ecm(struc
 	if (!gadget_supports_altsettings(gadget))
 		return false;
 
-	/* SA1100 can do ECM, *without* status endpoint ... but we'll
-	 * only use it in non-ECM mode for backwards compatibility
-	 * (and since we currently require a status endpoint)
-	 */
-	if (gadget_is_sa1100(gadget))
-		return false;
-
 	/* Everything else is *presumably* fine ... but this is a bit
 	 * chancy, so be **CERTAIN** there are no hardware issues with
 	 * your controller.  Add it above if it can't handle CDC.
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/u_serial.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/u_serial.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/u_serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/u_serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
+#include <linux/slab.h>
 
 #include "u_serial.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/gadget/zero.c linux-libre-2.6.34-gnu1/drivers/usb/gadget/zero.c
--- linux-libre-2.6.33-gnu1/drivers/usb/gadget/zero.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/gadget/zero.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,6 +50,7 @@
 /* #define VERBOSE_DEBUG */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/utsname.h>
 #include <linux/device.h>
 
@@ -297,12 +298,10 @@ static int __init zero_bind(struct usb_c
 	 */
 	if (loopdefault) {
 		loopback_add(cdev, autoresume != 0);
-		if (!gadget_is_sh(gadget))
-			sourcesink_add(cdev, autoresume != 0);
+		sourcesink_add(cdev, autoresume != 0);
 	} else {
 		sourcesink_add(cdev, autoresume != 0);
-		if (!gadget_is_sh(gadget))
-			loopback_add(cdev, autoresume != 0);
+		loopback_add(cdev, autoresume != 0);
 	}
 
 	gcnum = usb_gadget_controller_number(gadget);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-atmel.c linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-atmel.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-atmel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-atmel.c	2010-05-16 17:17:36.000000000 -0400
@@ -149,7 +149,7 @@ static int __init ehci_atmel_drv_probe(s
 		goto fail_request_resource;
 	}
 	hcd->rsrc_start = res->start;
-	hcd->rsrc_len = res->end - res->start + 1;
+	hcd->rsrc_len = resource_size(res);
 
 	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
 				driver->description)) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-au1xxx.c linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-au1xxx.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-au1xxx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-au1xxx.c	2010-05-16 17:17:36.000000000 -0400
@@ -121,6 +121,7 @@ static int ehci_hcd_au1xxx_drv_probe(str
 {
 	struct usb_hcd *hcd;
 	struct ehci_hcd *ehci;
+	struct resource *res;
 	int ret;
 
 	if (usb_disabled())
@@ -144,8 +145,9 @@ static int ehci_hcd_au1xxx_drv_probe(str
 	if (!hcd)
 		return -ENOMEM;
 
-	hcd->rsrc_start = pdev->resource[0].start;
-	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	hcd->rsrc_start = res->start;
+	hcd->rsrc_len = resource_size(res);
 
 	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
 		pr_debug("request_mem_region failed");
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-fsl.c linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-fsl.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-fsl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-fsl.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2005 MontaVista Software
+ * Copyright 2005-2009 MontaVista Software, Inc.
+ * Copyright 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
@@ -17,17 +18,20 @@
  *
  * Ported to 834x by Randy Vinson <rvinson@mvista.com> using code provided
  * by Hunter Wu.
+ * Power Management support by Dave Liu <daveliu@freescale.com>,
+ * Jerry Huang <Chang-Ming.Huang@freescale.com> and
+ * Anton Vorontsov <avorontsov@ru.mvista.com>.
  */
 
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
 #include <linux/platform_device.h>
 #include <linux/fsl_devices.h>
 
 #include "ehci-fsl.h"
 
-/* FIXME: Power Management is un-ported so temporarily disable it */
-#undef CONFIG_PM
-
-
 /* configure so an HC device and id are always provided */
 /* always called with process context; sleeping is OK */
 
@@ -40,8 +44,8 @@
  * Allocates basic resources for this USB host controller.
  *
  */
-int usb_hcd_fsl_probe(const struct hc_driver *driver,
-		      struct platform_device *pdev)
+static int usb_hcd_fsl_probe(const struct hc_driver *driver,
+			     struct platform_device *pdev)
 {
 	struct fsl_usb2_platform_data *pdata;
 	struct usb_hcd *hcd;
@@ -147,7 +151,8 @@ int usb_hcd_fsl_probe(const struct hc_dr
  * Reverses the effect of usb_hcd_fsl_probe().
  *
  */
-void usb_hcd_fsl_remove(struct usb_hcd *hcd, struct platform_device *pdev)
+static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
+			       struct platform_device *pdev)
 {
 	usb_remove_hcd(hcd);
 	iounmap(hcd->regs);
@@ -284,10 +289,81 @@ static int ehci_fsl_setup(struct usb_hcd
 	return retval;
 }
 
+struct ehci_fsl {
+	struct ehci_hcd	ehci;
+
+#ifdef CONFIG_PM
+	/* Saved USB PHY settings, need to restore after deep sleep. */
+	u32 usb_ctrl;
+#endif
+};
+
+#ifdef CONFIG_PM
+
+static struct ehci_fsl *hcd_to_ehci_fsl(struct usb_hcd *hcd)
+{
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+
+	return container_of(ehci, struct ehci_fsl, ehci);
+}
+
+static int ehci_fsl_drv_suspend(struct device *dev)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd);
+	void __iomem *non_ehci = hcd->regs;
+
+	if (!fsl_deep_sleep())
+		return 0;
+
+	ehci_fsl->usb_ctrl = in_be32(non_ehci + FSL_SOC_USB_CTRL);
+	return 0;
+}
+
+static int ehci_fsl_drv_resume(struct device *dev)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd);
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	void __iomem *non_ehci = hcd->regs;
+
+	if (!fsl_deep_sleep())
+		return 0;
+
+	usb_root_hub_lost_power(hcd->self.root_hub);
+
+	/* Restore USB PHY settings and enable the controller. */
+	out_be32(non_ehci + FSL_SOC_USB_CTRL, ehci_fsl->usb_ctrl);
+
+	ehci_reset(ehci);
+	ehci_fsl_reinit(ehci);
+
+	return 0;
+}
+
+static int ehci_fsl_drv_restore(struct device *dev)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+
+	usb_root_hub_lost_power(hcd->self.root_hub);
+	return 0;
+}
+
+static struct dev_pm_ops ehci_fsl_pm_ops = {
+	.suspend = ehci_fsl_drv_suspend,
+	.resume = ehci_fsl_drv_resume,
+	.restore = ehci_fsl_drv_restore,
+};
+
+#define EHCI_FSL_PM_OPS		(&ehci_fsl_pm_ops)
+#else
+#define EHCI_FSL_PM_OPS		NULL
+#endif /* CONFIG_PM */
+
 static const struct hc_driver ehci_fsl_hc_driver = {
 	.description = hcd_name,
 	.product_desc = "Freescale On-Chip EHCI Host Controller",
-	.hcd_priv_size = sizeof(struct ehci_hcd),
+	.hcd_priv_size = sizeof(struct ehci_fsl),
 
 	/*
 	 * generic hardware linkage
@@ -354,6 +430,7 @@ static struct platform_driver ehci_fsl_d
 	.remove = ehci_fsl_drv_remove,
 	.shutdown = usb_hcd_platform_shutdown,
 	.driver = {
-		   .name = "fsl-ehci",
+		.name = "fsl-ehci",
+		.pm = EHCI_FSL_PM_OPS,
 	},
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ehci.h linux-libre-2.6.34-gnu1/drivers/usb/host/ehci.h
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ehci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ehci.h	2010-05-16 17:17:36.000000000 -0400
@@ -87,8 +87,9 @@ struct ehci_hcd {			/* one per controlle
 	int			next_uframe;	/* scan periodic, start here */
 	unsigned		periodic_sched;	/* periodic activity count */
 
-	/* list of itds completed while clock_frame was still active */
+	/* list of itds & sitds completed while clock_frame was still active */
 	struct list_head	cached_itd_list;
+	struct list_head	cached_sitd_list;
 	unsigned		clock_frame;
 
 	/* per root hub port */
@@ -195,7 +196,7 @@ timer_action_done (struct ehci_hcd *ehci
 	clear_bit (action, &ehci->actions);
 }
 
-static void free_cached_itd_list(struct ehci_hcd *ehci);
+static void free_cached_lists(struct ehci_hcd *ehci);
 
 /*-------------------------------------------------------------------------*/
 
@@ -394,9 +395,8 @@ struct ehci_iso_sched {
  * acts like a qh would, if EHCI had them for ISO.
  */
 struct ehci_iso_stream {
-	/* first two fields match QH, but info1 == 0 */
-	__hc32			hw_next;
-	__hc32			hw_info1;
+	/* first field matches ehci_hq, but is NULL */
+	struct ehci_qh_hw	*hw;
 
 	u32			refcount;
 	u8			bEndpointAddress;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-hcd.c linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-hcd.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-hcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-hcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -35,6 +34,7 @@
 #include <linux/moduleparam.h>
 #include <linux/dma-mapping.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 #include "../core/hcd.h"
 
@@ -543,6 +543,7 @@ static int ehci_init(struct usb_hcd *hcd
 	 */
 	ehci->periodic_size = DEFAULT_I_TDPS;
 	INIT_LIST_HEAD(&ehci->cached_itd_list);
+	INIT_LIST_HEAD(&ehci->cached_sitd_list);
 	if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0)
 		return retval;
 
@@ -995,7 +996,7 @@ rescan:
 	/* endpoints can be iso streams.  for now, we don't
 	 * accelerate iso completions ... so spin a while.
 	 */
-	if (qh->hw->hw_info1 == 0) {
+	if (qh->hw == NULL) {
 		ehci_vdbg (ehci, "iso delay\n");
 		goto idle_timeout;
 	}
@@ -1118,7 +1119,7 @@ MODULE_LICENSE ("GPL");
 #define	PLATFORM_DRIVER		ehci_hcd_au1xxx_driver
 #endif
 
-#ifdef CONFIG_ARCH_OMAP34XX
+#ifdef CONFIG_ARCH_OMAP3
 #include "ehci-omap.c"
 #define        PLATFORM_DRIVER         ehci_hcd_omap_driver
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-hub.c linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-hub.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-hub.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-hub.c	2010-05-16 17:17:36.000000000 -0400
@@ -801,7 +801,7 @@ static int ehci_hub_control (
 			 * this bit; seems too long to spin routinely...
 			 */
 			retval = handshake(ehci, status_reg,
-					PORT_RESET, 0, 750);
+					PORT_RESET, 0, 1000);
 			if (retval != 0) {
 				ehci_err (ehci, "port %d reset error %d\n",
 					wIndex + 1, retval);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-mem.c linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-mem.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-mem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-mem.c	2010-05-16 17:17:36.000000000 -0400
@@ -136,7 +136,7 @@ static inline void qh_put (struct ehci_q
 
 static void ehci_mem_cleanup (struct ehci_hcd *ehci)
 {
-	free_cached_itd_list(ehci);
+	free_cached_lists(ehci);
 	if (ehci->async)
 		qh_put (ehci->async);
 	ehci->async = NULL;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-mxc.c linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-mxc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-mxc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-mxc.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/usb/otg.h>
+#include <linux/slab.h>
 
 #include <mach/mxc_ehci.h>
 
@@ -162,6 +163,17 @@ static int ehci_mxc_drv_probe(struct pla
 		goto err_ioremap;
 	}
 
+	/* call platform specific init function */
+	if (pdata->init) {
+		ret = pdata->init(pdev);
+		if (ret) {
+			dev_err(dev, "platform init failed\n");
+			goto err_init;
+		}
+		/* platforms need some time to settle changed IO settings */
+		mdelay(10);
+	}
+
 	/* enable clocks */
 	priv->usbclk = clk_get(dev, "usb");
 	if (IS_ERR(priv->usbclk)) {
@@ -192,18 +204,6 @@ static int ehci_mxc_drv_probe(struct pla
 	if (ret < 0)
 		goto err_init;
 
-	/* call platform specific init function */
-	if (pdata->init) {
-		ret = pdata->init(pdev);
-		if (ret) {
-			dev_err(dev, "platform init failed\n");
-			goto err_init;
-		}
-	}
-
-	/* most platforms need some time to settle changed IO settings */
-	mdelay(10);
-
 	/* Initialize the transceiver */
 	if (pdata->otg) {
 		pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-omap.c linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-omap.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-omap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-omap.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,10 +26,9 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  *
- * TODO (last updated Feb 23rd, 2009):
+ * TODO (last updated Feb 12, 2010):
  *	- add kernel-doc
  *	- enable AUTOIDLE
- *	- move DPLL5 programming to clock fw
  *	- add suspend/resume
  *	- move workarounds to board-files
  */
@@ -37,6 +36,8 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include <plat/usb.h>
 
 /*
@@ -178,6 +179,11 @@ struct ehci_hcd_omap {
 	void __iomem		*uhh_base;
 	void __iomem		*tll_base;
 	void __iomem		*ehci_base;
+
+	/* Regulators for USB PHYs.
+	 * Each PHY can have a seperate regulator.
+	 */
+	struct regulator        *regulator[OMAP3_HS_USB_PORTS];
 };
 
 /*-------------------------------------------------------------------------*/
@@ -546,6 +552,8 @@ static int ehci_hcd_omap_probe(struct pl
 
 	int irq = platform_get_irq(pdev, 0);
 	int ret = -ENODEV;
+	int i;
+	char supply[7];
 
 	if (!pdata) {
 		dev_dbg(&pdev->dev, "missing platform_data\n");
@@ -613,6 +621,23 @@ static int ehci_hcd_omap_probe(struct pl
 		goto err_tll_ioremap;
 	}
 
+	/* get ehci regulator and enable */
+	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
+		if (omap->port_mode[i] != EHCI_HCD_OMAP_MODE_PHY) {
+			omap->regulator[i] = NULL;
+			continue;
+		}
+		snprintf(supply, sizeof(supply), "hsusb%d", i);
+		omap->regulator[i] = regulator_get(omap->dev, supply);
+		if (IS_ERR(omap->regulator[i])) {
+			omap->regulator[i] = NULL;
+			dev_dbg(&pdev->dev,
+			"failed to get ehci port%d regulator\n", i);
+		} else {
+			regulator_enable(omap->regulator[i]);
+		}
+	}
+
 	ret = omap_start_ehc(omap, hcd);
 	if (ret) {
 		dev_dbg(&pdev->dev, "failed to start ehci\n");
@@ -622,13 +647,12 @@ static int ehci_hcd_omap_probe(struct pl
 	omap->ehci->regs = hcd->regs
 		+ HC_LENGTH(readl(&omap->ehci->caps->hc_capbase));
 
+	dbg_hcs_params(omap->ehci, "reset");
+	dbg_hcc_params(omap->ehci, "reset");
+
 	/* cache this readonly data; minimize chip reads */
 	omap->ehci->hcs_params = readl(&omap->ehci->caps->hcs_params);
 
-	/* SET 1 micro-frame Interrupt interval */
-	writel(readl(&omap->ehci->regs->command) | (1 << 16),
-			&omap->ehci->regs->command);
-
 	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
 	if (ret) {
 		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
@@ -641,6 +665,12 @@ err_add_hcd:
 	omap_stop_ehc(omap, hcd);
 
 err_start:
+	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
+		if (omap->regulator[i]) {
+			regulator_disable(omap->regulator[i]);
+			regulator_put(omap->regulator[i]);
+		}
+	}
 	iounmap(omap->tll_base);
 
 err_tll_ioremap:
@@ -674,13 +704,21 @@ static int ehci_hcd_omap_remove(struct p
 {
 	struct ehci_hcd_omap *omap = platform_get_drvdata(pdev);
 	struct usb_hcd *hcd = ehci_to_hcd(omap->ehci);
+	int i;
 
 	usb_remove_hcd(hcd);
 	omap_stop_ehc(omap, hcd);
 	iounmap(hcd->regs);
+	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
+		if (omap->regulator[i]) {
+			regulator_disable(omap->regulator[i]);
+			regulator_put(omap->regulator[i]);
+		}
+	}
 	iounmap(omap->tll_base);
 	iounmap(omap->uhh_base);
 	usb_put_hcd(hcd);
+	kfree(omap);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-orion.c linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-orion.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-orion.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-orion.c	2010-05-16 17:17:36.000000000 -0400
@@ -222,14 +222,14 @@ static int __devinit ehci_orion_drv_prob
 		goto err1;
 	}
 
-	if (!request_mem_region(res->start, res->end - res->start + 1,
+	if (!request_mem_region(res->start, resource_size(res),
 				ehci_orion_hc_driver.description)) {
 		dev_dbg(&pdev->dev, "controller already in use\n");
 		err = -EBUSY;
 		goto err1;
 	}
 
-	regs = ioremap(res->start, res->end - res->start + 1);
+	regs = ioremap(res->start, resource_size(res));
 	if (regs == NULL) {
 		dev_dbg(&pdev->dev, "error mapping memory\n");
 		err = -EFAULT;
@@ -244,7 +244,7 @@ static int __devinit ehci_orion_drv_prob
 	}
 
 	hcd->rsrc_start = res->start;
-	hcd->rsrc_len = res->end - res->start + 1;
+	hcd->rsrc_len = resource_size(res);
 	hcd->regs = regs;
 
 	ehci = hcd_to_ehci(hcd);
@@ -287,7 +287,7 @@ err4:
 err3:
 	iounmap(regs);
 err2:
-	release_mem_region(res->start, res->end - res->start + 1);
+	release_mem_region(res->start, resource_size(res));
 err1:
 	dev_err(&pdev->dev, "init %s fail, %d\n",
 		dev_name(&pdev->dev), err);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-ppc-of.c linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-ppc-of.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-ppc-of.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-ppc-of.c	2010-05-16 17:17:36.000000000 -0400
@@ -134,21 +134,21 @@ ehci_hcd_ppc_of_probe(struct of_device *
 	hcd->rsrc_len = res.end - res.start + 1;
 
 	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
-		printk(KERN_ERR __FILE__ ": request_mem_region failed\n");
+		printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__);
 		rv = -EBUSY;
 		goto err_rmr;
 	}
 
 	irq = irq_of_parse_and_map(dn, 0);
 	if (irq == NO_IRQ) {
-		printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n");
+		printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__);
 		rv = -EBUSY;
 		goto err_irq;
 	}
 
 	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
 	if (!hcd->regs) {
-		printk(KERN_ERR __FILE__ ": ioremap failed\n");
+		printk(KERN_ERR "%s: ioremap failed\n", __FILE__);
 		rv = -ENOMEM;
 		goto err_ioremap;
 	}
@@ -161,9 +161,9 @@ ehci_hcd_ppc_of_probe(struct of_device *
 			ehci->ohci_hcctrl_reg = ioremap(res.start +
 					OHCI_HCCTRL_OFFSET, OHCI_HCCTRL_LEN);
 		else
-			pr_debug(__FILE__ ": no ohci offset in fdt\n");
+			pr_debug("%s: no ohci offset in fdt\n", __FILE__);
 		if (!ehci->ohci_hcctrl_reg) {
-			pr_debug(__FILE__ ": ioremap for ohci hcctrl failed\n");
+			pr_debug("%s: ioremap for ohci hcctrl failed\n", __FILE__);
 		} else {
 			ehci->has_amcc_usb23 = 1;
 		}
@@ -241,7 +241,7 @@ static int ehci_hcd_ppc_of_remove(struct
 				else
 					release_mem_region(res.start, 0x4);
 			else
-				pr_debug(__FILE__ ": no ohci offset in fdt\n");
+				pr_debug("%s: no ohci offset in fdt\n", __FILE__);
 			of_node_put(np);
 		}
 
@@ -264,7 +264,7 @@ static int ehci_hcd_ppc_of_shutdown(stru
 }
 
 
-static struct of_device_id ehci_hcd_ppc_of_match[] = {
+static const struct of_device_id ehci_hcd_ppc_of_match[] = {
 	{
 		.compatible = "usb-ehci",
 	},
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-sched.c linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-sched.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-sched.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-sched.c	2010-05-16 17:17:36.000000000 -0400
@@ -510,6 +510,8 @@ static int disable_periodic (struct ehci
 	ehci_writel(ehci, cmd, &ehci->regs->command);
 	/* posted write ... */
 
+	free_cached_lists(ehci);
+
 	ehci->next_uframe = -1;
 	return 0;
 }
@@ -1121,8 +1123,8 @@ iso_stream_find (struct ehci_hcd *ehci,
 					urb->interval);
 		}
 
-	/* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */
-	} else if (unlikely (stream->hw_info1 != 0)) {
+	/* if dev->ep [epnum] is a QH, hw is set */
+	} else if (unlikely (stream->hw != NULL)) {
 		ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n",
 			urb->dev->devpath, epnum,
 			usb_pipein(urb->pipe) ? "in" : "out");
@@ -1563,13 +1565,27 @@ itd_patch(
 static inline void
 itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd)
 {
-	/* always prepend ITD/SITD ... only QH tree is order-sensitive */
-	itd->itd_next = ehci->pshadow [frame];
-	itd->hw_next = ehci->periodic [frame];
-	ehci->pshadow [frame].itd = itd;
+	union ehci_shadow	*prev = &ehci->pshadow[frame];
+	__hc32			*hw_p = &ehci->periodic[frame];
+	union ehci_shadow	here = *prev;
+	__hc32			type = 0;
+
+	/* skip any iso nodes which might belong to previous microframes */
+	while (here.ptr) {
+		type = Q_NEXT_TYPE(ehci, *hw_p);
+		if (type == cpu_to_hc32(ehci, Q_TYPE_QH))
+			break;
+		prev = periodic_next_shadow(ehci, prev, type);
+		hw_p = shadow_next_periodic(ehci, &here, type);
+		here = *prev;
+	}
+
+	itd->itd_next = here;
+	itd->hw_next = *hw_p;
+	prev->itd = itd;
 	itd->frame = frame;
 	wmb ();
-	ehci->periodic[frame] = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
+	*hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
 }
 
 /* fit urb's itds into the selected schedule slot; activate as needed */
@@ -2123,13 +2139,27 @@ sitd_complete (
 			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
 	}
 	iso_stream_put (ehci, stream);
-	/* OK to recycle this SITD now that its completion callback ran. */
+
 done:
 	sitd->urb = NULL;
-	sitd->stream = NULL;
-	list_move(&sitd->sitd_list, &stream->free_list);
-	iso_stream_put(ehci, stream);
-
+	if (ehci->clock_frame != sitd->frame) {
+		/* OK to recycle this SITD now. */
+		sitd->stream = NULL;
+		list_move(&sitd->sitd_list, &stream->free_list);
+		iso_stream_put(ehci, stream);
+	} else {
+		/* HW might remember this SITD, so we can't recycle it yet.
+		 * Move it to a safe place until a new frame starts.
+		 */
+		list_move(&sitd->sitd_list, &ehci->cached_sitd_list);
+		if (stream->refcount == 2) {
+			/* If iso_stream_put() were called here, stream
+			 * would be freed.  Instead, just prevent reuse.
+			 */
+			stream->ep->hcpriv = NULL;
+			stream->ep = NULL;
+		}
+	}
 	return retval;
 }
 
@@ -2195,9 +2225,10 @@ done:
 
 /*-------------------------------------------------------------------------*/
 
-static void free_cached_itd_list(struct ehci_hcd *ehci)
+static void free_cached_lists(struct ehci_hcd *ehci)
 {
 	struct ehci_itd *itd, *n;
+	struct ehci_sitd *sitd, *sn;
 
 	list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) {
 		struct ehci_iso_stream	*stream = itd->stream;
@@ -2205,6 +2236,13 @@ static void free_cached_itd_list(struct
 		list_move(&itd->itd_list, &stream->free_list);
 		iso_stream_put(ehci, stream);
 	}
+
+	list_for_each_entry_safe(sitd, sn, &ehci->cached_sitd_list, sitd_list) {
+		struct ehci_iso_stream	*stream = sitd->stream;
+		sitd->stream = NULL;
+		list_move(&sitd->sitd_list, &stream->free_list);
+		iso_stream_put(ehci, stream);
+	}
 }
 
 /*-------------------------------------------------------------------------*/
@@ -2231,7 +2269,7 @@ scan_periodic (struct ehci_hcd *ehci)
 		clock_frame = -1;
 	}
 	if (ehci->clock_frame != clock_frame) {
-		free_cached_itd_list(ehci);
+		free_cached_lists(ehci);
 		ehci->clock_frame = clock_frame;
 	}
 	clock %= mod;
@@ -2322,9 +2360,13 @@ restart:
 				 * No need to check for activity unless the
 				 * frame is current.
 				 */
-				if (frame == clock_frame && live &&
-						(q.sitd->hw_results &
-							SITD_ACTIVE(ehci))) {
+				if (((frame == clock_frame) ||
+				     (((frame + 1) % ehci->periodic_size)
+				      == clock_frame))
+				    && live
+				    && (q.sitd->hw_results &
+					SITD_ACTIVE(ehci))) {
+
 					incomplete = true;
 					q_p = &q.sitd->sitd_next;
 					hw_p = &q.sitd->hw_next;
@@ -2394,7 +2436,7 @@ restart:
 			clock = now;
 			clock_frame = clock >> 3;
 			if (ehci->clock_frame != clock_frame) {
-				free_cached_itd_list(ehci);
+				free_cached_lists(ehci);
 				ehci->clock_frame = clock_frame;
 			}
 		} else {
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-xilinx-of.c linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-xilinx-of.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ehci-xilinx-of.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ehci-xilinx-of.c	2010-05-16 17:17:36.000000000 -0400
@@ -177,21 +177,21 @@ ehci_hcd_xilinx_of_probe(struct of_devic
 	hcd->rsrc_len = res.end - res.start + 1;
 
 	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
-		printk(KERN_ERR __FILE__ ": request_mem_region failed\n");
+		printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__);
 		rv = -EBUSY;
 		goto err_rmr;
 	}
 
 	irq = irq_of_parse_and_map(dn, 0);
 	if (irq == NO_IRQ) {
-		printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n");
+		printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__);
 		rv = -EBUSY;
 		goto err_irq;
 	}
 
 	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
 	if (!hcd->regs) {
-		printk(KERN_ERR __FILE__ ": ioremap failed\n");
+		printk(KERN_ERR "%s: ioremap failed\n", __FILE__);
 		rv = -ENOMEM;
 		goto err_ioremap;
 	}
@@ -281,7 +281,7 @@ static int ehci_hcd_xilinx_of_shutdown(s
 }
 
 
-static struct of_device_id ehci_hcd_xilinx_of_match[] = {
+static const struct of_device_id ehci_hcd_xilinx_of_match[] = {
 		{.compatible = "xlnx,xps-usb-host-1.00.a",},
 	{},
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/fhci-hcd.c linux-libre-2.6.34-gnu1/drivers/usb/host/fhci-hcd.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/fhci-hcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/fhci-hcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/usb.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
+#include <linux/slab.h>
 #include <asm/qe.h>
 #include <asm/fsl_gtm.h>
 #include "../core/hcd.h"
@@ -433,7 +434,7 @@ static int fhci_urb_enqueue(struct usb_h
 		return -ENOMEM;
 
 	/* allocate the private part of the URB */
-	urb_priv->tds = kzalloc(size * sizeof(struct td), mem_flags);
+	urb_priv->tds = kcalloc(size, sizeof(*urb_priv->tds), mem_flags);
 	if (!urb_priv->tds) {
 		kfree(urb_priv);
 		return -ENOMEM;
@@ -805,7 +806,7 @@ static int __devexit of_fhci_remove(stru
 	return fhci_remove(&ofdev->dev);
 }
 
-static struct of_device_id of_fhci_match[] = {
+static const struct of_device_id of_fhci_match[] = {
 	{ .compatible = "fsl,mpc8323-qe-usb", },
 	{},
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/fhci-mem.c linux-libre-2.6.34-gnu1/drivers/usb/host/fhci-mem.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/fhci-mem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/fhci-mem.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/usb.h>
 #include "../core/hcd.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/fhci-q.c linux-libre-2.6.34-gnu1/drivers/usb/host/fhci-q.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/fhci-q.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/fhci-q.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/usb.h>
 #include "../core/hcd.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/fhci-tds.c linux-libre-2.6.34-gnu1/drivers/usb/host/fhci-tds.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/fhci-tds.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/fhci-tds.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/io.h>
 #include <linux/usb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/hwa-hc.c linux-libre-2.6.34-gnu1/drivers/usb/host/hwa-hc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/hwa-hc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/hwa-hc.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,6 +55,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/workqueue.h>
 #include <linux/wait.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/imx21-dbg.c linux-libre-2.6.34-gnu1/drivers/usb/host/imx21-dbg.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/imx21-dbg.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/imx21-dbg.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 2009 by Martin Fuzzey
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the 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 file is part of imx21-hcd.c */
+
+#ifndef DEBUG
+
+static inline void create_debug_files(struct imx21 *imx21) { }
+static inline void remove_debug_files(struct imx21 *imx21) { }
+static inline void debug_urb_submitted(struct imx21 *imx21, struct urb *urb) {}
+static inline void debug_urb_completed(struct imx21 *imx21, struct urb *urb,
+	int status) {}
+static inline void debug_urb_unlinked(struct imx21 *imx21, struct urb *urb) {}
+static inline void debug_urb_queued_for_etd(struct imx21 *imx21,
+	struct urb *urb) {}
+static inline void debug_urb_queued_for_dmem(struct imx21 *imx21,
+	struct urb *urb) {}
+static inline void debug_etd_allocated(struct imx21 *imx21) {}
+static inline void debug_etd_freed(struct imx21 *imx21) {}
+static inline void debug_dmem_allocated(struct imx21 *imx21, int size) {}
+static inline void debug_dmem_freed(struct imx21 *imx21, int size) {}
+static inline void debug_isoc_submitted(struct imx21 *imx21,
+	int frame, struct td *td) {}
+static inline void debug_isoc_completed(struct imx21 *imx21,
+	int frame, struct td *td, int cc, int len) {}
+
+#else
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static const char *dir_labels[] = {
+	"TD 0",
+	"OUT",
+	"IN",
+	"TD 1"
+};
+
+static const char *speed_labels[] = {
+	"Full",
+	"Low"
+};
+
+static const char *format_labels[] = {
+	"Control",
+	"ISO",
+	"Bulk",
+	"Interrupt"
+};
+
+static inline struct debug_stats *stats_for_urb(struct imx21 *imx21,
+	struct urb *urb)
+{
+	return usb_pipeisoc(urb->pipe) ?
+		&imx21->isoc_stats : &imx21->nonisoc_stats;
+}
+
+static void debug_urb_submitted(struct imx21 *imx21, struct urb *urb)
+{
+	stats_for_urb(imx21, urb)->submitted++;
+}
+
+static void debug_urb_completed(struct imx21 *imx21, struct urb *urb, int st)
+{
+	if (st)
+		stats_for_urb(imx21, urb)->completed_failed++;
+	else
+		stats_for_urb(imx21, urb)->completed_ok++;
+}
+
+static void debug_urb_unlinked(struct imx21 *imx21, struct urb *urb)
+{
+	stats_for_urb(imx21, urb)->unlinked++;
+}
+
+static void debug_urb_queued_for_etd(struct imx21 *imx21, struct urb *urb)
+{
+	stats_for_urb(imx21, urb)->queue_etd++;
+}
+
+static void debug_urb_queued_for_dmem(struct imx21 *imx21, struct urb *urb)
+{
+	stats_for_urb(imx21, urb)->queue_dmem++;
+}
+
+static inline void debug_etd_allocated(struct imx21 *imx21)
+{
+	imx21->etd_usage.maximum = max(
+			++(imx21->etd_usage.value),
+			imx21->etd_usage.maximum);
+}
+
+static inline void debug_etd_freed(struct imx21 *imx21)
+{
+	imx21->etd_usage.value--;
+}
+
+static inline void debug_dmem_allocated(struct imx21 *imx21, int size)
+{
+	imx21->dmem_usage.value += size;
+	imx21->dmem_usage.maximum = max(
+			imx21->dmem_usage.value,
+			imx21->dmem_usage.maximum);
+}
+
+static inline void debug_dmem_freed(struct imx21 *imx21, int size)
+{
+	imx21->dmem_usage.value -= size;
+}
+
+
+static void debug_isoc_submitted(struct imx21 *imx21,
+	int frame, struct td *td)
+{
+	struct debug_isoc_trace *trace = &imx21->isoc_trace[
+		imx21->isoc_trace_index++];
+
+	imx21->isoc_trace_index %= ARRAY_SIZE(imx21->isoc_trace);
+	trace->schedule_frame = td->frame;
+	trace->submit_frame = frame;
+	trace->request_len = td->len;
+	trace->td = td;
+}
+
+static inline void debug_isoc_completed(struct imx21 *imx21,
+	int frame, struct td *td, int cc, int len)
+{
+	struct debug_isoc_trace *trace, *trace_failed;
+	int i;
+	int found = 0;
+
+	trace = imx21->isoc_trace;
+	for (i = 0; i < ARRAY_SIZE(imx21->isoc_trace); i++, trace++) {
+		if (trace->td == td) {
+			trace->done_frame = frame;
+			trace->done_len = len;
+			trace->cc = cc;
+			trace->td = NULL;
+			found = 1;
+			break;
+		}
+	}
+
+	if (found && cc) {
+		trace_failed = &imx21->isoc_trace_failed[
+					imx21->isoc_trace_index_failed++];
+
+		imx21->isoc_trace_index_failed %= ARRAY_SIZE(
+						imx21->isoc_trace_failed);
+		*trace_failed = *trace;
+	}
+}
+
+
+static char *format_ep(struct usb_host_endpoint *ep, char *buf, int bufsize)
+{
+	if (ep)
+		snprintf(buf, bufsize, "ep_%02x (type:%02X kaddr:%p)",
+			ep->desc.bEndpointAddress,
+			usb_endpoint_type(&ep->desc),
+			ep);
+	else
+		snprintf(buf, bufsize, "none");
+	return buf;
+}
+
+static char *format_etd_dword0(u32 value, char *buf, int bufsize)
+{
+	snprintf(buf, bufsize,
+		"addr=%d ep=%d dir=%s speed=%s format=%s halted=%d",
+		value & 0x7F,
+		(value >> DW0_ENDPNT) & 0x0F,
+		dir_labels[(value >> DW0_DIRECT) & 0x03],
+		speed_labels[(value >> DW0_SPEED) & 0x01],
+		format_labels[(value >> DW0_FORMAT) & 0x03],
+		(value >> DW0_HALTED) & 0x01);
+	return buf;
+}
+
+static int debug_status_show(struct seq_file *s, void *v)
+{
+	struct imx21 *imx21 = s->private;
+	int etds_allocated = 0;
+	int etds_sw_busy = 0;
+	int etds_hw_busy = 0;
+	int dmem_blocks = 0;
+	int queued_for_etd = 0;
+	int queued_for_dmem = 0;
+	unsigned int dmem_bytes = 0;
+	int i;
+	struct etd_priv *etd;
+	u32 etd_enable_mask;
+	unsigned long flags;
+	struct imx21_dmem_area *dmem;
+	struct ep_priv *ep_priv;
+
+	spin_lock_irqsave(&imx21->lock, flags);
+
+	etd_enable_mask = readl(imx21->regs + USBH_ETDENSET);
+	for (i = 0, etd = imx21->etd; i < USB_NUM_ETD; i++, etd++) {
+		if (etd->alloc)
+			etds_allocated++;
+		if (etd->urb)
+			etds_sw_busy++;
+		if (etd_enable_mask & (1<<i))
+			etds_hw_busy++;
+	}
+
+	list_for_each_entry(dmem, &imx21->dmem_list, list) {
+		dmem_bytes += dmem->size;
+		dmem_blocks++;
+	}
+
+	list_for_each_entry(ep_priv, &imx21->queue_for_etd, queue)
+		queued_for_etd++;
+
+	list_for_each_entry(etd, &imx21->queue_for_dmem, queue)
+		queued_for_dmem++;
+
+	spin_unlock_irqrestore(&imx21->lock, flags);
+
+	seq_printf(s,
+		"Frame: %d\n"
+		"ETDs allocated: %d/%d (max=%d)\n"
+		"ETDs in use sw: %d\n"
+		"ETDs in use hw: %d\n"
+		"DMEM alocated: %d/%d (max=%d)\n"
+		"DMEM blocks: %d\n"
+		"Queued waiting for ETD: %d\n"
+		"Queued waiting for DMEM: %d\n",
+		readl(imx21->regs + USBH_FRMNUB) & 0xFFFF,
+		etds_allocated, USB_NUM_ETD, imx21->etd_usage.maximum,
+		etds_sw_busy,
+		etds_hw_busy,
+		dmem_bytes, DMEM_SIZE, imx21->dmem_usage.maximum,
+		dmem_blocks,
+		queued_for_etd,
+		queued_for_dmem);
+
+	return 0;
+}
+
+static int debug_dmem_show(struct seq_file *s, void *v)
+{
+	struct imx21 *imx21 = s->private;
+	struct imx21_dmem_area *dmem;
+	unsigned long flags;
+	char ep_text[40];
+
+	spin_lock_irqsave(&imx21->lock, flags);
+
+	list_for_each_entry(dmem, &imx21->dmem_list, list)
+		seq_printf(s,
+			"%04X: size=0x%X "
+			"ep=%s\n",
+			dmem->offset, dmem->size,
+			format_ep(dmem->ep, ep_text, sizeof(ep_text)));
+
+	spin_unlock_irqrestore(&imx21->lock, flags);
+
+	return 0;
+}
+
+static int debug_etd_show(struct seq_file *s, void *v)
+{
+	struct imx21 *imx21 = s->private;
+	struct etd_priv *etd;
+	char buf[60];
+	u32 dword;
+	int i, j;
+	unsigned long flags;
+
+	spin_lock_irqsave(&imx21->lock, flags);
+
+	for (i = 0, etd = imx21->etd; i < USB_NUM_ETD; i++, etd++) {
+		int state = -1;
+		struct urb_priv *urb_priv;
+		if (etd->urb) {
+			urb_priv = etd->urb->hcpriv;
+			if (urb_priv)
+				state = urb_priv->state;
+		}
+
+		seq_printf(s,
+			"etd_num: %d\n"
+			"ep: %s\n"
+			"alloc: %d\n"
+			"len: %d\n"
+			"busy sw: %d\n"
+			"busy hw: %d\n"
+			"urb state: %d\n"
+			"current urb: %p\n",
+
+			i,
+			format_ep(etd->ep, buf, sizeof(buf)),
+			etd->alloc,
+			etd->len,
+			etd->urb != NULL,
+			(readl(imx21->regs + USBH_ETDENSET) & (1 << i)) > 0,
+			state,
+			etd->urb);
+
+		for (j = 0; j < 4; j++) {
+			dword = etd_readl(imx21, i, j);
+			switch (j) {
+			case 0:
+				format_etd_dword0(dword, buf, sizeof(buf));
+				break;
+			case 2:
+				snprintf(buf, sizeof(buf),
+					"cc=0X%02X", dword >> DW2_COMPCODE);
+				break;
+			default:
+				*buf = 0;
+				break;
+			}
+			seq_printf(s,
+				"dword %d: submitted=%08X cur=%08X [%s]\n",
+				j,
+				etd->submitted_dwords[j],
+				dword,
+				buf);
+		}
+		seq_printf(s, "\n");
+	}
+
+	spin_unlock_irqrestore(&imx21->lock, flags);
+
+	return 0;
+}
+
+static void debug_statistics_show_one(struct seq_file *s,
+	const char *name, struct debug_stats *stats)
+{
+	seq_printf(s, "%s:\n"
+		"submitted URBs: %lu\n"
+		"completed OK: %lu\n"
+		"completed failed: %lu\n"
+		"unlinked: %lu\n"
+		"queued for ETD: %lu\n"
+		"queued for DMEM: %lu\n\n",
+		name,
+		stats->submitted,
+		stats->completed_ok,
+		stats->completed_failed,
+		stats->unlinked,
+		stats->queue_etd,
+		stats->queue_dmem);
+}
+
+static int debug_statistics_show(struct seq_file *s, void *v)
+{
+	struct imx21 *imx21 = s->private;
+	unsigned long flags;
+
+	spin_lock_irqsave(&imx21->lock, flags);
+
+	debug_statistics_show_one(s, "nonisoc", &imx21->nonisoc_stats);
+	debug_statistics_show_one(s, "isoc", &imx21->isoc_stats);
+	seq_printf(s, "unblock kludge triggers: %lu\n", imx21->debug_unblocks);
+	spin_unlock_irqrestore(&imx21->lock, flags);
+
+	return 0;
+}
+
+static void debug_isoc_show_one(struct seq_file *s,
+	const char *name, int index, 	struct debug_isoc_trace *trace)
+{
+	seq_printf(s, "%s %d:\n"
+		"cc=0X%02X\n"
+		"scheduled frame %d (%d)\n"
+		"submittted frame %d (%d)\n"
+		"completed frame %d (%d)\n"
+		"requested length=%d\n"
+		"completed length=%d\n\n",
+		name, index,
+		trace->cc,
+		trace->schedule_frame, trace->schedule_frame & 0xFFFF,
+		trace->submit_frame, trace->submit_frame & 0xFFFF,
+		trace->done_frame, trace->done_frame & 0xFFFF,
+		trace->request_len,
+		trace->done_len);
+}
+
+static int debug_isoc_show(struct seq_file *s, void *v)
+{
+	struct imx21 *imx21 = s->private;
+	struct debug_isoc_trace *trace;
+	unsigned long flags;
+	int i;
+
+	spin_lock_irqsave(&imx21->lock, flags);
+
+	trace = imx21->isoc_trace_failed;
+	for (i = 0; i < ARRAY_SIZE(imx21->isoc_trace_failed); i++, trace++)
+		debug_isoc_show_one(s, "isoc failed", i, trace);
+
+	trace = imx21->isoc_trace;
+	for (i = 0; i < ARRAY_SIZE(imx21->isoc_trace); i++, trace++)
+		debug_isoc_show_one(s, "isoc", i, trace);
+
+	spin_unlock_irqrestore(&imx21->lock, flags);
+
+	return 0;
+}
+
+static int debug_status_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, debug_status_show, inode->i_private);
+}
+
+static int debug_dmem_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, debug_dmem_show, inode->i_private);
+}
+
+static int debug_etd_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, debug_etd_show, inode->i_private);
+}
+
+static int debug_statistics_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, debug_statistics_show, inode->i_private);
+}
+
+static int debug_isoc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, debug_isoc_show, inode->i_private);
+}
+
+static const struct file_operations debug_status_fops = {
+	.open = debug_status_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static const struct file_operations debug_dmem_fops = {
+	.open = debug_dmem_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static const struct file_operations debug_etd_fops = {
+	.open = debug_etd_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static const struct file_operations debug_statistics_fops = {
+	.open = debug_statistics_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static const struct file_operations debug_isoc_fops = {
+	.open = debug_isoc_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static void create_debug_files(struct imx21 *imx21)
+{
+	imx21->debug_root = debugfs_create_dir(dev_name(imx21->dev), NULL);
+	if (!imx21->debug_root)
+		goto failed_create_rootdir;
+
+	if (!debugfs_create_file("status", S_IRUGO,
+			imx21->debug_root, imx21, &debug_status_fops))
+		goto failed_create;
+
+	if (!debugfs_create_file("dmem", S_IRUGO,
+			imx21->debug_root, imx21, &debug_dmem_fops))
+		goto failed_create;
+
+	if (!debugfs_create_file("etd", S_IRUGO,
+			imx21->debug_root, imx21, &debug_etd_fops))
+		goto failed_create;
+
+	if (!debugfs_create_file("statistics", S_IRUGO,
+			imx21->debug_root, imx21, &debug_statistics_fops))
+		goto failed_create;
+
+	if (!debugfs_create_file("isoc", S_IRUGO,
+			imx21->debug_root, imx21, &debug_isoc_fops))
+		goto failed_create;
+
+	return;
+
+failed_create:
+	debugfs_remove_recursive(imx21->debug_root);
+
+failed_create_rootdir:
+	imx21->debug_root = NULL;
+}
+
+
+static void remove_debug_files(struct imx21 *imx21)
+{
+	if (imx21->debug_root) {
+		debugfs_remove_recursive(imx21->debug_root);
+		imx21->debug_root = NULL;
+	}
+}
+
+#endif
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/imx21-hcd.c linux-libre-2.6.34-gnu1/drivers/usb/host/imx21-hcd.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/imx21-hcd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/imx21-hcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1790 @@
+/*
+ * USB Host Controller Driver for IMX21
+ *
+ * Copyright (C) 2006 Loping Dog Embedded Systems
+ * Copyright (C) 2009 Martin Fuzzey
+ * Originally written by Jay Monkman <jtm@lopingdog.com>
+ * Ported to 2.6.30, debugged and enhanced by Martin Fuzzey
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the 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 i.MX21 USB hardware contains
+  *    * 32 transfer descriptors (called ETDs)
+  *    * 4Kb of Data memory
+  *
+  * The data memory is shared between the host and fuction controlers
+  * (but this driver only supports the host controler)
+  *
+  * So setting up a transfer involves:
+  *    * Allocating a ETD
+  *    * Fill in ETD with appropriate information
+  *    * Allocating data memory (and putting the offset in the ETD)
+  *    * Activate the ETD
+  *    * Get interrupt when done.
+  *
+  * An ETD is assigned to each active endpoint.
+  *
+  * Low resource (ETD and Data memory) situations are handled differently for
+  * isochronous and non insosynchronous transactions :
+  *
+  * Non ISOC transfers are queued if either ETDs or Data memory are unavailable
+  *
+  * ISOC transfers use 2 ETDs per endpoint to achieve double buffering.
+  * They allocate both ETDs and Data memory during URB submission
+  * (and fail if unavailable).
+  */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+
+#include "../core/hcd.h"
+#include "imx21-hcd.h"
+
+#ifdef DEBUG
+#define DEBUG_LOG_FRAME(imx21, etd, event) \
+	(etd)->event##_frame = readl((imx21)->regs + USBH_FRMNUB)
+#else
+#define DEBUG_LOG_FRAME(imx21, etd, event) do { } while (0)
+#endif
+
+static const char hcd_name[] = "imx21-hcd";
+
+static inline struct imx21 *hcd_to_imx21(struct usb_hcd *hcd)
+{
+	return (struct imx21 *)hcd->hcd_priv;
+}
+
+
+/* =========================================== */
+/* Hardware access helpers			*/
+/* =========================================== */
+
+static inline void set_register_bits(struct imx21 *imx21, u32 offset, u32 mask)
+{
+	void __iomem *reg = imx21->regs + offset;
+	writel(readl(reg) | mask, reg);
+}
+
+static inline void clear_register_bits(struct imx21 *imx21,
+	u32 offset, u32 mask)
+{
+	void __iomem *reg = imx21->regs + offset;
+	writel(readl(reg) & ~mask, reg);
+}
+
+static inline void clear_toggle_bit(struct imx21 *imx21, u32 offset, u32 mask)
+{
+	void __iomem *reg = imx21->regs + offset;
+
+	if (readl(reg) & mask)
+		writel(mask, reg);
+}
+
+static inline void set_toggle_bit(struct imx21 *imx21, u32 offset, u32 mask)
+{
+	void __iomem *reg = imx21->regs + offset;
+
+	if (!(readl(reg) & mask))
+		writel(mask, reg);
+}
+
+static void etd_writel(struct imx21 *imx21, int etd_num, int dword, u32 value)
+{
+	writel(value, imx21->regs + USB_ETD_DWORD(etd_num, dword));
+}
+
+static u32 etd_readl(struct imx21 *imx21, int etd_num, int dword)
+{
+	return readl(imx21->regs + USB_ETD_DWORD(etd_num, dword));
+}
+
+static inline int wrap_frame(int counter)
+{
+	return counter & 0xFFFF;
+}
+
+static inline int frame_after(int frame, int after)
+{
+	/* handle wrapping like jiffies time_afer */
+	return (s16)((s16)after - (s16)frame) < 0;
+}
+
+static int imx21_hc_get_frame(struct usb_hcd *hcd)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+
+	return wrap_frame(readl(imx21->regs + USBH_FRMNUB));
+}
+
+
+#include "imx21-dbg.c"
+
+/* =========================================== */
+/* ETD management				*/
+/* ===========================================	*/
+
+static int alloc_etd(struct imx21 *imx21)
+{
+	int i;
+	struct etd_priv *etd = imx21->etd;
+
+	for (i = 0; i < USB_NUM_ETD; i++, etd++) {
+		if (etd->alloc == 0) {
+			memset(etd, 0, sizeof(imx21->etd[0]));
+			etd->alloc = 1;
+			debug_etd_allocated(imx21);
+			return i;
+		}
+	}
+	return -1;
+}
+
+static void disactivate_etd(struct imx21 *imx21, int num)
+{
+	int etd_mask = (1 << num);
+	struct etd_priv *etd = &imx21->etd[num];
+
+	writel(etd_mask, imx21->regs + USBH_ETDENCLR);
+	clear_register_bits(imx21, USBH_ETDDONEEN, etd_mask);
+	writel(etd_mask, imx21->regs + USB_ETDDMACHANLCLR);
+	clear_toggle_bit(imx21, USBH_ETDDONESTAT, etd_mask);
+
+	etd->active_count = 0;
+
+	DEBUG_LOG_FRAME(imx21, etd, disactivated);
+}
+
+static void reset_etd(struct imx21 *imx21, int num)
+{
+	struct etd_priv *etd = imx21->etd + num;
+	int i;
+
+	disactivate_etd(imx21, num);
+
+	for (i = 0; i < 4; i++)
+		etd_writel(imx21, num, i, 0);
+	etd->urb = NULL;
+	etd->ep = NULL;
+	etd->td = NULL;;
+}
+
+static void free_etd(struct imx21 *imx21, int num)
+{
+	if (num < 0)
+		return;
+
+	if (num >= USB_NUM_ETD) {
+		dev_err(imx21->dev, "BAD etd=%d!\n", num);
+		return;
+	}
+	if (imx21->etd[num].alloc == 0) {
+		dev_err(imx21->dev, "ETD %d already free!\n", num);
+		return;
+	}
+
+	debug_etd_freed(imx21);
+	reset_etd(imx21, num);
+	memset(&imx21->etd[num], 0, sizeof(imx21->etd[0]));
+}
+
+
+static void setup_etd_dword0(struct imx21 *imx21,
+	int etd_num, struct urb *urb,  u8 dir, u16 maxpacket)
+{
+	etd_writel(imx21, etd_num, 0,
+		((u32) usb_pipedevice(urb->pipe)) <<  DW0_ADDRESS |
+		((u32) usb_pipeendpoint(urb->pipe) << DW0_ENDPNT) |
+		((u32) dir << DW0_DIRECT) |
+		((u32) ((urb->dev->speed == USB_SPEED_LOW) ?
+			1 : 0) << DW0_SPEED) |
+		((u32) fmt_urb_to_etd[usb_pipetype(urb->pipe)] << DW0_FORMAT) |
+		((u32) maxpacket << DW0_MAXPKTSIZ));
+}
+
+static void activate_etd(struct imx21 *imx21,
+	int etd_num, dma_addr_t dma, u8 dir)
+{
+	u32 etd_mask = 1 << etd_num;
+	struct etd_priv *etd = &imx21->etd[etd_num];
+
+	clear_toggle_bit(imx21, USBH_ETDDONESTAT, etd_mask);
+	set_register_bits(imx21, USBH_ETDDONEEN, etd_mask);
+	clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask);
+	clear_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask);
+
+	if (dma) {
+		set_register_bits(imx21, USB_ETDDMACHANLCLR, etd_mask);
+		clear_toggle_bit(imx21, USBH_XBUFSTAT, etd_mask);
+		clear_toggle_bit(imx21, USBH_YBUFSTAT, etd_mask);
+		writel(dma, imx21->regs + USB_ETDSMSA(etd_num));
+		set_register_bits(imx21, USB_ETDDMAEN, etd_mask);
+	} else {
+		if (dir != TD_DIR_IN) {
+			/* need to set for ZLP */
+			set_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask);
+			set_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask);
+		}
+	}
+
+	DEBUG_LOG_FRAME(imx21, etd, activated);
+
+#ifdef DEBUG
+	if (!etd->active_count) {
+		int i;
+		etd->activated_frame = readl(imx21->regs + USBH_FRMNUB);
+		etd->disactivated_frame = -1;
+		etd->last_int_frame = -1;
+		etd->last_req_frame = -1;
+
+		for (i = 0; i < 4; i++)
+			etd->submitted_dwords[i] = etd_readl(imx21, etd_num, i);
+	}
+#endif
+
+	etd->active_count = 1;
+	writel(etd_mask, imx21->regs + USBH_ETDENSET);
+}
+
+/* ===========================================	*/
+/* Data memory management			*/
+/* ===========================================	*/
+
+static int alloc_dmem(struct imx21 *imx21, unsigned int size,
+		      struct usb_host_endpoint *ep)
+{
+	unsigned int offset = 0;
+	struct imx21_dmem_area *area;
+	struct imx21_dmem_area *tmp;
+
+	size += (~size + 1) & 0x3; /* Round to 4 byte multiple */
+
+	if (size > DMEM_SIZE) {
+		dev_err(imx21->dev, "size=%d > DMEM_SIZE(%d)\n",
+			size, DMEM_SIZE);
+		return -EINVAL;
+	}
+
+	list_for_each_entry(tmp, &imx21->dmem_list, list) {
+		if ((size + offset) < offset)
+			goto fail;
+		if ((size + offset) <= tmp->offset)
+			break;
+		offset = tmp->size + tmp->offset;
+		if ((offset + size) > DMEM_SIZE)
+			goto fail;
+	}
+
+	area = kmalloc(sizeof(struct imx21_dmem_area), GFP_ATOMIC);
+	if (area == NULL)
+		return -ENOMEM;
+
+	area->ep = ep;
+	area->offset = offset;
+	area->size = size;
+	list_add_tail(&area->list, &tmp->list);
+	debug_dmem_allocated(imx21, size);
+	return offset;
+
+fail:
+	return -ENOMEM;
+}
+
+/* Memory now available for a queued ETD - activate it */
+static void activate_queued_etd(struct imx21 *imx21,
+	struct etd_priv *etd, u32 dmem_offset)
+{
+	struct urb_priv *urb_priv = etd->urb->hcpriv;
+	int etd_num = etd - &imx21->etd[0];
+	u32 maxpacket = etd_readl(imx21, etd_num, 1) >> DW1_YBUFSRTAD;
+	u8 dir = (etd_readl(imx21, etd_num, 2) >> DW2_DIRPID) & 0x03;
+
+	dev_dbg(imx21->dev, "activating queued ETD %d now DMEM available\n",
+		etd_num);
+	etd_writel(imx21, etd_num, 1,
+	    ((dmem_offset + maxpacket) << DW1_YBUFSRTAD) | dmem_offset);
+
+	urb_priv->active = 1;
+	activate_etd(imx21, etd_num, etd->dma_handle, dir);
+}
+
+static void free_dmem(struct imx21 *imx21, int offset)
+{
+	struct imx21_dmem_area *area;
+	struct etd_priv *etd, *tmp;
+	int found = 0;
+
+	list_for_each_entry(area, &imx21->dmem_list, list) {
+		if (area->offset == offset) {
+			debug_dmem_freed(imx21, area->size);
+			list_del(&area->list);
+			kfree(area);
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found)  {
+		dev_err(imx21->dev,
+			"Trying to free unallocated DMEM %d\n", offset);
+		return;
+	}
+
+	/* Try again to allocate memory for anything we've queued */
+	list_for_each_entry_safe(etd, tmp, &imx21->queue_for_dmem, queue) {
+		offset = alloc_dmem(imx21, etd->dmem_size, etd->ep);
+		if (offset >= 0) {
+			list_del(&etd->queue);
+			activate_queued_etd(imx21, etd, (u32)offset);
+		}
+	}
+}
+
+static void free_epdmem(struct imx21 *imx21, struct usb_host_endpoint *ep)
+{
+	struct imx21_dmem_area *area, *tmp;
+
+	list_for_each_entry_safe(area, tmp, &imx21->dmem_list, list) {
+		if (area->ep == ep) {
+			dev_err(imx21->dev,
+				"Active DMEM %d for disabled ep=%p\n",
+				area->offset, ep);
+			list_del(&area->list);
+			kfree(area);
+		}
+	}
+}
+
+
+/* ===========================================	*/
+/* End handling 				*/
+/* ===========================================	*/
+static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb);
+
+/* Endpoint now idle - release it's ETD(s) or asssign to queued request */
+static void ep_idle(struct imx21 *imx21, struct ep_priv *ep_priv)
+{
+	int etd_num;
+	int i;
+
+	for (i = 0; i < NUM_ISO_ETDS; i++) {
+		etd_num = ep_priv->etd[i];
+		if (etd_num < 0)
+			continue;
+
+		ep_priv->etd[i] = -1;
+		if (list_empty(&imx21->queue_for_etd)) {
+			free_etd(imx21, etd_num);
+			continue;
+		}
+
+		dev_dbg(imx21->dev,
+			"assigning idle etd %d for queued request\n", etd_num);
+		ep_priv = list_first_entry(&imx21->queue_for_etd,
+			struct ep_priv, queue);
+		list_del(&ep_priv->queue);
+		reset_etd(imx21, etd_num);
+		ep_priv->waiting_etd = 0;
+		ep_priv->etd[i] = etd_num;
+
+		if (list_empty(&ep_priv->ep->urb_list)) {
+			dev_err(imx21->dev, "No urb for queued ep!\n");
+			continue;
+		}
+		schedule_nonisoc_etd(imx21, list_first_entry(
+			&ep_priv->ep->urb_list, struct urb, urb_list));
+	}
+}
+
+static void urb_done(struct usb_hcd *hcd, struct urb *urb, int status)
+__releases(imx21->lock)
+__acquires(imx21->lock)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	struct ep_priv *ep_priv = urb->ep->hcpriv;
+	struct urb_priv *urb_priv = urb->hcpriv;
+
+	debug_urb_completed(imx21, urb, status);
+	dev_vdbg(imx21->dev, "urb %p done %d\n", urb, status);
+
+	kfree(urb_priv->isoc_td);
+	kfree(urb->hcpriv);
+	urb->hcpriv = NULL;
+	usb_hcd_unlink_urb_from_ep(hcd, urb);
+	spin_unlock(&imx21->lock);
+	usb_hcd_giveback_urb(hcd, urb, status);
+	spin_lock(&imx21->lock);
+	if (list_empty(&ep_priv->ep->urb_list))
+		ep_idle(imx21, ep_priv);
+}
+
+/* ===========================================	*/
+/* ISOC Handling ... 				*/
+/* ===========================================	*/
+
+static void schedule_isoc_etds(struct usb_hcd *hcd,
+	struct usb_host_endpoint *ep)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	struct ep_priv *ep_priv = ep->hcpriv;
+	struct etd_priv *etd;
+	struct urb_priv *urb_priv;
+	struct td *td;
+	int etd_num;
+	int i;
+	int cur_frame;
+	u8 dir;
+
+	for (i = 0; i < NUM_ISO_ETDS; i++) {
+too_late:
+		if (list_empty(&ep_priv->td_list))
+			break;
+
+		etd_num = ep_priv->etd[i];
+		if (etd_num < 0)
+			break;
+
+		etd = &imx21->etd[etd_num];
+		if (etd->urb)
+			continue;
+
+		td = list_entry(ep_priv->td_list.next, struct td, list);
+		list_del(&td->list);
+		urb_priv = td->urb->hcpriv;
+
+		cur_frame = imx21_hc_get_frame(hcd);
+		if (frame_after(cur_frame, td->frame)) {
+			dev_dbg(imx21->dev, "isoc too late frame %d > %d\n",
+				cur_frame, td->frame);
+			urb_priv->isoc_status = -EXDEV;
+			td->urb->iso_frame_desc[
+				td->isoc_index].actual_length = 0;
+			td->urb->iso_frame_desc[td->isoc_index].status = -EXDEV;
+			if (--urb_priv->isoc_remaining == 0)
+				urb_done(hcd, td->urb, urb_priv->isoc_status);
+			goto too_late;
+		}
+
+		urb_priv->active = 1;
+		etd->td = td;
+		etd->ep = td->ep;
+		etd->urb = td->urb;
+		etd->len = td->len;
+
+		debug_isoc_submitted(imx21, cur_frame, td);
+
+		dir = usb_pipeout(td->urb->pipe) ? TD_DIR_OUT : TD_DIR_IN;
+		setup_etd_dword0(imx21, etd_num, td->urb, dir, etd->dmem_size);
+		etd_writel(imx21, etd_num, 1, etd->dmem_offset);
+		etd_writel(imx21, etd_num, 2,
+			(TD_NOTACCESSED << DW2_COMPCODE) |
+			((td->frame & 0xFFFF) << DW2_STARTFRM));
+		etd_writel(imx21, etd_num, 3,
+			(TD_NOTACCESSED << DW3_COMPCODE0) |
+			(td->len << DW3_PKTLEN0));
+
+		activate_etd(imx21, etd_num, td->data, dir);
+	}
+}
+
+static void isoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	int etd_mask = 1 << etd_num;
+	struct urb_priv *urb_priv = urb->hcpriv;
+	struct etd_priv *etd = imx21->etd + etd_num;
+	struct td *td = etd->td;
+	struct usb_host_endpoint *ep = etd->ep;
+	int isoc_index = td->isoc_index;
+	unsigned int pipe = urb->pipe;
+	int dir_in = usb_pipein(pipe);
+	int cc;
+	int bytes_xfrd;
+
+	disactivate_etd(imx21, etd_num);
+
+	cc = (etd_readl(imx21, etd_num, 3) >> DW3_COMPCODE0) & 0xf;
+	bytes_xfrd = etd_readl(imx21, etd_num, 3) & 0x3ff;
+
+	/* Input doesn't always fill the buffer, don't generate an error
+	 * when this happens.
+	 */
+	if (dir_in && (cc == TD_DATAUNDERRUN))
+		cc = TD_CC_NOERROR;
+
+	if (cc == TD_NOTACCESSED)
+		bytes_xfrd = 0;
+
+	debug_isoc_completed(imx21,
+		imx21_hc_get_frame(hcd), td, cc, bytes_xfrd);
+	if (cc) {
+		urb_priv->isoc_status = -EXDEV;
+		dev_dbg(imx21->dev,
+			"bad iso cc=0x%X frame=%d sched frame=%d "
+			"cnt=%d len=%d urb=%p etd=%d index=%d\n",
+			cc,  imx21_hc_get_frame(hcd), td->frame,
+			bytes_xfrd, td->len, urb, etd_num, isoc_index);
+	}
+
+	if (dir_in)
+		clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask);
+
+	urb->actual_length += bytes_xfrd;
+	urb->iso_frame_desc[isoc_index].actual_length = bytes_xfrd;
+	urb->iso_frame_desc[isoc_index].status = cc_to_error[cc];
+
+	etd->td = NULL;
+	etd->urb = NULL;
+	etd->ep = NULL;
+
+	if (--urb_priv->isoc_remaining == 0)
+		urb_done(hcd, urb, urb_priv->isoc_status);
+
+	schedule_isoc_etds(hcd, ep);
+}
+
+static struct ep_priv *alloc_isoc_ep(
+	struct imx21 *imx21, struct usb_host_endpoint *ep)
+{
+	struct ep_priv *ep_priv;
+	int i;
+
+	ep_priv = kzalloc(sizeof(struct ep_priv), GFP_ATOMIC);
+	if (ep_priv == NULL)
+		return NULL;
+
+	/* Allocate the ETDs */
+	for (i = 0; i < NUM_ISO_ETDS; i++) {
+		ep_priv->etd[i] = alloc_etd(imx21);
+		if (ep_priv->etd[i] < 0) {
+			int j;
+			dev_err(imx21->dev, "isoc: Couldn't allocate etd\n");
+			for (j = 0; j < i; j++)
+				free_etd(imx21, ep_priv->etd[j]);
+			goto alloc_etd_failed;
+		}
+		imx21->etd[ep_priv->etd[i]].ep = ep;
+	}
+
+	INIT_LIST_HEAD(&ep_priv->td_list);
+	ep_priv->ep = ep;
+	ep->hcpriv = ep_priv;
+	return ep_priv;
+
+alloc_etd_failed:
+	kfree(ep_priv);
+	return NULL;
+}
+
+static int imx21_hc_urb_enqueue_isoc(struct usb_hcd *hcd,
+				     struct usb_host_endpoint *ep,
+				     struct urb *urb, gfp_t mem_flags)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	struct urb_priv *urb_priv;
+	unsigned long flags;
+	struct ep_priv *ep_priv;
+	struct td *td = NULL;
+	int i;
+	int ret;
+	int cur_frame;
+	u16 maxpacket;
+
+	urb_priv = kzalloc(sizeof(struct urb_priv), mem_flags);
+	if (urb_priv == NULL)
+		return -ENOMEM;
+
+	urb_priv->isoc_td = kzalloc(
+		sizeof(struct td) * urb->number_of_packets, mem_flags);
+	if (urb_priv->isoc_td == NULL) {
+		ret = -ENOMEM;
+		goto alloc_td_failed;
+	}
+
+	spin_lock_irqsave(&imx21->lock, flags);
+
+	if (ep->hcpriv == NULL) {
+		ep_priv = alloc_isoc_ep(imx21, ep);
+		if (ep_priv == NULL) {
+			ret = -ENOMEM;
+			goto alloc_ep_failed;
+		}
+	} else {
+		ep_priv = ep->hcpriv;
+	}
+
+	ret = usb_hcd_link_urb_to_ep(hcd, urb);
+	if (ret)
+		goto link_failed;
+
+	urb->status = -EINPROGRESS;
+	urb->actual_length = 0;
+	urb->error_count = 0;
+	urb->hcpriv = urb_priv;
+	urb_priv->ep = ep;
+
+	/* allocate data memory for largest packets if not already done */
+	maxpacket = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
+	for (i = 0; i < NUM_ISO_ETDS; i++) {
+		struct etd_priv *etd = &imx21->etd[ep_priv->etd[i]];
+
+		if (etd->dmem_size > 0 && etd->dmem_size < maxpacket) {
+			/* not sure if this can really occur.... */
+			dev_err(imx21->dev, "increasing isoc buffer %d->%d\n",
+				etd->dmem_size, maxpacket);
+			ret = -EMSGSIZE;
+			goto alloc_dmem_failed;
+		}
+
+		if (etd->dmem_size == 0) {
+			etd->dmem_offset = alloc_dmem(imx21, maxpacket, ep);
+			if (etd->dmem_offset < 0) {
+				dev_dbg(imx21->dev, "failed alloc isoc dmem\n");
+				ret = -EAGAIN;
+				goto alloc_dmem_failed;
+			}
+			etd->dmem_size = maxpacket;
+		}
+	}
+
+	/* calculate frame */
+	cur_frame = imx21_hc_get_frame(hcd);
+	if (urb->transfer_flags & URB_ISO_ASAP) {
+		if (list_empty(&ep_priv->td_list))
+			urb->start_frame = cur_frame + 5;
+		else
+			urb->start_frame = list_entry(
+				ep_priv->td_list.prev,
+				struct td, list)->frame + urb->interval;
+	}
+	urb->start_frame = wrap_frame(urb->start_frame);
+	if (frame_after(cur_frame, urb->start_frame)) {
+		dev_dbg(imx21->dev,
+			"enqueue: adjusting iso start %d (cur=%d) asap=%d\n",
+			urb->start_frame, cur_frame,
+			(urb->transfer_flags & URB_ISO_ASAP) != 0);
+		urb->start_frame = wrap_frame(cur_frame + 1);
+	}
+
+	/* set up transfers */
+	td = urb_priv->isoc_td;
+	for (i = 0; i < urb->number_of_packets; i++, td++) {
+		td->ep = ep;
+		td->urb = urb;
+		td->len = urb->iso_frame_desc[i].length;
+		td->isoc_index = i;
+		td->frame = wrap_frame(urb->start_frame + urb->interval * i);
+		td->data = urb->transfer_dma + urb->iso_frame_desc[i].offset;
+		list_add_tail(&td->list, &ep_priv->td_list);
+	}
+
+	urb_priv->isoc_remaining = urb->number_of_packets;
+	dev_vdbg(imx21->dev, "setup %d packets for iso frame %d->%d\n",
+		urb->number_of_packets, urb->start_frame, td->frame);
+
+	debug_urb_submitted(imx21, urb);
+	schedule_isoc_etds(hcd, ep);
+
+	spin_unlock_irqrestore(&imx21->lock, flags);
+	return 0;
+
+alloc_dmem_failed:
+	usb_hcd_unlink_urb_from_ep(hcd, urb);
+
+link_failed:
+alloc_ep_failed:
+	spin_unlock_irqrestore(&imx21->lock, flags);
+	kfree(urb_priv->isoc_td);
+
+alloc_td_failed:
+	kfree(urb_priv);
+	return ret;
+}
+
+static void dequeue_isoc_urb(struct imx21 *imx21,
+	struct urb *urb, struct ep_priv *ep_priv)
+{
+	struct urb_priv *urb_priv = urb->hcpriv;
+	struct td *td, *tmp;
+	int i;
+
+	if (urb_priv->active) {
+		for (i = 0; i < NUM_ISO_ETDS; i++) {
+			int etd_num = ep_priv->etd[i];
+			if (etd_num != -1 && imx21->etd[etd_num].urb == urb) {
+				struct etd_priv *etd = imx21->etd + etd_num;
+
+				reset_etd(imx21, etd_num);
+				if (etd->dmem_size)
+					free_dmem(imx21, etd->dmem_offset);
+				etd->dmem_size = 0;
+			}
+		}
+	}
+
+	list_for_each_entry_safe(td, tmp, &ep_priv->td_list, list) {
+		if (td->urb == urb) {
+			dev_vdbg(imx21->dev, "removing td %p\n", td);
+			list_del(&td->list);
+		}
+	}
+}
+
+/* =========================================== */
+/* NON ISOC Handling ... 			*/
+/* =========================================== */
+
+static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb)
+{
+	unsigned int pipe = urb->pipe;
+	struct urb_priv *urb_priv = urb->hcpriv;
+	struct ep_priv *ep_priv = urb_priv->ep->hcpriv;
+	int state = urb_priv->state;
+	int etd_num = ep_priv->etd[0];
+	struct etd_priv *etd;
+	int dmem_offset;
+	u32 count;
+	u16 etd_buf_size;
+	u16 maxpacket;
+	u8 dir;
+	u8 bufround;
+	u8 datatoggle;
+	u8 interval = 0;
+	u8 relpolpos = 0;
+
+	if (etd_num < 0) {
+		dev_err(imx21->dev, "No valid ETD\n");
+		return;
+	}
+	if (readl(imx21->regs + USBH_ETDENSET) & (1 << etd_num))
+		dev_err(imx21->dev, "submitting to active ETD %d\n", etd_num);
+
+	etd = &imx21->etd[etd_num];
+	maxpacket = usb_maxpacket(urb->dev, pipe, usb_pipeout(pipe));
+	if (!maxpacket)
+		maxpacket = 8;
+
+	if (usb_pipecontrol(pipe) && (state != US_CTRL_DATA)) {
+		if (state == US_CTRL_SETUP) {
+			dir = TD_DIR_SETUP;
+			etd->dma_handle = urb->setup_dma;
+			bufround = 0;
+			count = 8;
+			datatoggle = TD_TOGGLE_DATA0;
+		} else {	/* US_CTRL_ACK */
+			dir = usb_pipeout(pipe) ? TD_DIR_IN : TD_DIR_OUT;
+			etd->dma_handle = urb->transfer_dma;
+			bufround = 0;
+			count = 0;
+			datatoggle = TD_TOGGLE_DATA1;
+		}
+	} else {
+		dir = usb_pipeout(pipe) ? TD_DIR_OUT : TD_DIR_IN;
+		bufround = (dir == TD_DIR_IN) ? 1 : 0;
+		etd->dma_handle = urb->transfer_dma;
+		if (usb_pipebulk(pipe) && (state == US_BULK0))
+			count = 0;
+		else
+			count = urb->transfer_buffer_length;
+
+		if (usb_pipecontrol(pipe)) {
+			datatoggle = TD_TOGGLE_DATA1;
+		} else {
+			if (usb_gettoggle(
+					urb->dev,
+					usb_pipeendpoint(urb->pipe),
+					usb_pipeout(urb->pipe)))
+				datatoggle = TD_TOGGLE_DATA1;
+			else
+				datatoggle = TD_TOGGLE_DATA0;
+		}
+	}
+
+	etd->urb = urb;
+	etd->ep = urb_priv->ep;
+	etd->len = count;
+
+	if (usb_pipeint(pipe)) {
+		interval = urb->interval;
+		relpolpos = (readl(imx21->regs + USBH_FRMNUB) + 1) & 0xff;
+	}
+
+	/* Write ETD to device memory */
+	setup_etd_dword0(imx21, etd_num, urb, dir, maxpacket);
+
+	etd_writel(imx21, etd_num, 2,
+		(u32) interval << DW2_POLINTERV |
+		((u32) relpolpos << DW2_RELPOLPOS) |
+		((u32) dir << DW2_DIRPID) |
+		((u32) bufround << DW2_BUFROUND) |
+		((u32) datatoggle << DW2_DATATOG) |
+		((u32) TD_NOTACCESSED << DW2_COMPCODE));
+
+	/* DMA will always transfer buffer size even if TOBYCNT in DWORD3
+	   is smaller. Make sure we don't overrun the buffer!
+	 */
+	if (count && count < maxpacket)
+		etd_buf_size = count;
+	else
+		etd_buf_size = maxpacket;
+
+	etd_writel(imx21, etd_num, 3,
+		((u32) (etd_buf_size - 1) << DW3_BUFSIZE) | (u32) count);
+
+	if (!count)
+		etd->dma_handle = 0;
+
+	/* allocate x and y buffer space at once */
+	etd->dmem_size = (count > maxpacket) ? maxpacket * 2 : maxpacket;
+	dmem_offset = alloc_dmem(imx21, etd->dmem_size, urb_priv->ep);
+	if (dmem_offset < 0) {
+		/* Setup everything we can in HW and update when we get DMEM */
+		etd_writel(imx21, etd_num, 1, (u32)maxpacket << 16);
+
+		dev_dbg(imx21->dev, "Queuing etd %d for DMEM\n", etd_num);
+		debug_urb_queued_for_dmem(imx21, urb);
+		list_add_tail(&etd->queue, &imx21->queue_for_dmem);
+		return;
+	}
+
+	etd_writel(imx21, etd_num, 1,
+		(((u32) dmem_offset + (u32) maxpacket) << DW1_YBUFSRTAD) |
+		(u32) dmem_offset);
+
+	urb_priv->active = 1;
+
+	/* enable the ETD to kick off transfer */
+	dev_vdbg(imx21->dev, "Activating etd %d for %d bytes %s\n",
+		etd_num, count, dir != TD_DIR_IN ? "out" : "in");
+	activate_etd(imx21, etd_num, etd->dma_handle, dir);
+
+}
+
+static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	struct etd_priv *etd = &imx21->etd[etd_num];
+	u32 etd_mask = 1 << etd_num;
+	struct urb_priv *urb_priv = urb->hcpriv;
+	int dir;
+	u16 xbufaddr;
+	int cc;
+	u32 bytes_xfrd;
+	int etd_done;
+
+	disactivate_etd(imx21, etd_num);
+
+	dir = (etd_readl(imx21, etd_num, 0) >> DW0_DIRECT) & 0x3;
+	xbufaddr = etd_readl(imx21, etd_num, 1) & 0xffff;
+	cc = (etd_readl(imx21, etd_num, 2) >> DW2_COMPCODE) & 0xf;
+	bytes_xfrd = etd->len - (etd_readl(imx21, etd_num, 3) & 0x1fffff);
+
+	/* save toggle carry */
+	usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+		      usb_pipeout(urb->pipe),
+		      (etd_readl(imx21, etd_num, 0) >> DW0_TOGCRY) & 0x1);
+
+	if (dir == TD_DIR_IN) {
+		clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask);
+		clear_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask);
+	}
+	free_dmem(imx21, xbufaddr);
+
+	urb->error_count = 0;
+	if (!(urb->transfer_flags & URB_SHORT_NOT_OK)
+			&& (cc == TD_DATAUNDERRUN))
+		cc = TD_CC_NOERROR;
+
+	if (cc != 0)
+		dev_vdbg(imx21->dev, "cc is 0x%x\n", cc);
+
+	etd_done = (cc_to_error[cc] != 0);	/* stop if error */
+
+	switch (usb_pipetype(urb->pipe)) {
+	case PIPE_CONTROL:
+		switch (urb_priv->state) {
+		case US_CTRL_SETUP:
+			if (urb->transfer_buffer_length > 0)
+				urb_priv->state = US_CTRL_DATA;
+			else
+				urb_priv->state = US_CTRL_ACK;
+			break;
+		case US_CTRL_DATA:
+			urb->actual_length += bytes_xfrd;
+			urb_priv->state = US_CTRL_ACK;
+			break;
+		case US_CTRL_ACK:
+			etd_done = 1;
+			break;
+		default:
+			dev_err(imx21->dev,
+				"Invalid pipe state %d\n", urb_priv->state);
+			etd_done = 1;
+			break;
+		}
+		break;
+
+	case PIPE_BULK:
+		urb->actual_length += bytes_xfrd;
+		if ((urb_priv->state == US_BULK)
+		    && (urb->transfer_flags & URB_ZERO_PACKET)
+		    && urb->transfer_buffer_length > 0
+		    && ((urb->transfer_buffer_length %
+			 usb_maxpacket(urb->dev, urb->pipe,
+				       usb_pipeout(urb->pipe))) == 0)) {
+			/* need a 0-packet */
+			urb_priv->state = US_BULK0;
+		} else {
+			etd_done = 1;
+		}
+		break;
+
+	case PIPE_INTERRUPT:
+		urb->actual_length += bytes_xfrd;
+		etd_done = 1;
+		break;
+	}
+
+	if (!etd_done) {
+		dev_vdbg(imx21->dev, "next state=%d\n", urb_priv->state);
+		schedule_nonisoc_etd(imx21, urb);
+	} else {
+		struct usb_host_endpoint *ep = urb->ep;
+
+		urb_done(hcd, urb, cc_to_error[cc]);
+		etd->urb = NULL;
+
+		if (!list_empty(&ep->urb_list)) {
+			urb = list_first_entry(&ep->urb_list,
+				struct urb, urb_list);
+			dev_vdbg(imx21->dev, "next URB %p\n", urb);
+			schedule_nonisoc_etd(imx21, urb);
+		}
+	}
+}
+
+static struct ep_priv *alloc_ep(void)
+{
+	int i;
+	struct ep_priv *ep_priv;
+
+	ep_priv = kzalloc(sizeof(struct ep_priv), GFP_ATOMIC);
+	if (!ep_priv)
+		return NULL;
+
+	for (i = 0; i < NUM_ISO_ETDS; ++i)
+		ep_priv->etd[i] = -1;
+
+	return ep_priv;
+}
+
+static int imx21_hc_urb_enqueue(struct usb_hcd *hcd,
+				struct urb *urb, gfp_t mem_flags)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	struct usb_host_endpoint *ep = urb->ep;
+	struct urb_priv *urb_priv;
+	struct ep_priv *ep_priv;
+	struct etd_priv *etd;
+	int ret;
+	unsigned long flags;
+	int new_ep = 0;
+
+	dev_vdbg(imx21->dev,
+		"enqueue urb=%p ep=%p len=%d "
+		"buffer=%p dma=%08X setupBuf=%p setupDma=%08X\n",
+		urb, ep,
+		urb->transfer_buffer_length,
+		urb->transfer_buffer, urb->transfer_dma,
+		urb->setup_packet, urb->setup_dma);
+
+	if (usb_pipeisoc(urb->pipe))
+		return imx21_hc_urb_enqueue_isoc(hcd, ep, urb, mem_flags);
+
+	urb_priv = kzalloc(sizeof(struct urb_priv), mem_flags);
+	if (!urb_priv)
+		return -ENOMEM;
+
+	spin_lock_irqsave(&imx21->lock, flags);
+
+	ep_priv = ep->hcpriv;
+	if (ep_priv == NULL) {
+		ep_priv = alloc_ep();
+		if (!ep_priv) {
+			ret = -ENOMEM;
+			goto failed_alloc_ep;
+		}
+		ep->hcpriv = ep_priv;
+		ep_priv->ep = ep;
+		new_ep = 1;
+	}
+
+	ret = usb_hcd_link_urb_to_ep(hcd, urb);
+	if (ret)
+		goto failed_link;
+
+	urb->status = -EINPROGRESS;
+	urb->actual_length = 0;
+	urb->error_count = 0;
+	urb->hcpriv = urb_priv;
+	urb_priv->ep = ep;
+
+	switch (usb_pipetype(urb->pipe)) {
+	case PIPE_CONTROL:
+		urb_priv->state = US_CTRL_SETUP;
+		break;
+	case PIPE_BULK:
+		urb_priv->state = US_BULK;
+		break;
+	}
+
+	debug_urb_submitted(imx21, urb);
+	if (ep_priv->etd[0] < 0) {
+		if (ep_priv->waiting_etd) {
+			dev_dbg(imx21->dev,
+				"no ETD available already queued %p\n",
+				ep_priv);
+			debug_urb_queued_for_etd(imx21, urb);
+			goto out;
+		}
+		ep_priv->etd[0] = alloc_etd(imx21);
+		if (ep_priv->etd[0] < 0) {
+			dev_dbg(imx21->dev,
+				"no ETD available queueing %p\n", ep_priv);
+			debug_urb_queued_for_etd(imx21, urb);
+			list_add_tail(&ep_priv->queue, &imx21->queue_for_etd);
+			ep_priv->waiting_etd = 1;
+			goto out;
+		}
+	}
+
+	/* Schedule if no URB already active for this endpoint */
+	etd = &imx21->etd[ep_priv->etd[0]];
+	if (etd->urb == NULL) {
+		DEBUG_LOG_FRAME(imx21, etd, last_req);
+		schedule_nonisoc_etd(imx21, urb);
+	}
+
+out:
+	spin_unlock_irqrestore(&imx21->lock, flags);
+	return 0;
+
+failed_link:
+failed_alloc_ep:
+	spin_unlock_irqrestore(&imx21->lock, flags);
+	kfree(urb_priv);
+	return ret;
+}
+
+static int imx21_hc_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
+				int status)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	unsigned long flags;
+	struct usb_host_endpoint *ep;
+	struct ep_priv *ep_priv;
+	struct urb_priv *urb_priv = urb->hcpriv;
+	int ret = -EINVAL;
+
+	dev_vdbg(imx21->dev, "dequeue urb=%p iso=%d status=%d\n",
+		urb, usb_pipeisoc(urb->pipe), status);
+
+	spin_lock_irqsave(&imx21->lock, flags);
+
+	ret = usb_hcd_check_unlink_urb(hcd, urb, status);
+	if (ret)
+		goto fail;
+	ep = urb_priv->ep;
+	ep_priv = ep->hcpriv;
+
+	debug_urb_unlinked(imx21, urb);
+
+	if (usb_pipeisoc(urb->pipe)) {
+		dequeue_isoc_urb(imx21, urb, ep_priv);
+		schedule_isoc_etds(hcd, ep);
+	} else if (urb_priv->active) {
+		int etd_num = ep_priv->etd[0];
+		if (etd_num != -1) {
+			disactivate_etd(imx21, etd_num);
+			free_dmem(imx21, etd_readl(imx21, etd_num, 1) & 0xffff);
+			imx21->etd[etd_num].urb = NULL;
+		}
+	}
+
+	urb_done(hcd, urb, status);
+
+	spin_unlock_irqrestore(&imx21->lock, flags);
+	return 0;
+
+fail:
+	spin_unlock_irqrestore(&imx21->lock, flags);
+	return ret;
+}
+
+/* =========================================== */
+/* Interrupt dispatch	 			*/
+/* =========================================== */
+
+static void process_etds(struct usb_hcd *hcd, struct imx21 *imx21, int sof)
+{
+	int etd_num;
+	int enable_sof_int = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&imx21->lock, flags);
+
+	for (etd_num = 0; etd_num < USB_NUM_ETD; etd_num++) {
+		u32 etd_mask = 1 << etd_num;
+		u32 enabled = readl(imx21->regs + USBH_ETDENSET) & etd_mask;
+		u32 done = readl(imx21->regs + USBH_ETDDONESTAT) & etd_mask;
+		struct etd_priv *etd = &imx21->etd[etd_num];
+
+
+		if (done) {
+			DEBUG_LOG_FRAME(imx21, etd, last_int);
+		} else {
+/*
+ * Kludge warning!
+ *
+ * When multiple transfers are using the bus we sometimes get into a state
+ * where the transfer has completed (the CC field of the ETD is != 0x0F),
+ * the ETD has self disabled but the ETDDONESTAT flag is not set
+ * (and hence no interrupt occurs).
+ * This causes the transfer in question to hang.
+ * The kludge below checks for this condition at each SOF and processes any
+ * blocked ETDs (after an arbitary 10 frame wait)
+ *
+ * With a single active transfer the usbtest test suite will run for days
+ * without the kludge.
+ * With other bus activity (eg mass storage) even just test1 will hang without
+ * the kludge.
+ */
+			u32 dword0;
+			int cc;
+
+			if (etd->active_count && !enabled) /* suspicious... */
+				enable_sof_int = 1;
+
+			if (!sof || enabled || !etd->active_count)
+				continue;
+
+			cc = etd_readl(imx21, etd_num, 2) >> DW2_COMPCODE;
+			if (cc == TD_NOTACCESSED)
+				continue;
+
+			if (++etd->active_count < 10)
+				continue;
+
+			dword0 = etd_readl(imx21, etd_num, 0);
+			dev_dbg(imx21->dev,
+				"unblock ETD %d dev=0x%X ep=0x%X cc=0x%02X!\n",
+				etd_num, dword0 & 0x7F,
+				(dword0 >> DW0_ENDPNT) & 0x0F,
+				cc);
+
+#ifdef DEBUG
+			dev_dbg(imx21->dev,
+				"frame: act=%d disact=%d"
+				" int=%d req=%d cur=%d\n",
+				etd->activated_frame,
+				etd->disactivated_frame,
+				etd->last_int_frame,
+				etd->last_req_frame,
+				readl(imx21->regs + USBH_FRMNUB));
+			imx21->debug_unblocks++;
+#endif
+			etd->active_count = 0;
+/* End of kludge */
+		}
+
+		if (etd->ep == NULL || etd->urb == NULL) {
+			dev_dbg(imx21->dev,
+				"Interrupt for unexpected etd %d"
+				" ep=%p urb=%p\n",
+				etd_num, etd->ep, etd->urb);
+			disactivate_etd(imx21, etd_num);
+			continue;
+		}
+
+		if (usb_pipeisoc(etd->urb->pipe))
+			isoc_etd_done(hcd, etd->urb, etd_num);
+		else
+			nonisoc_etd_done(hcd, etd->urb, etd_num);
+	}
+
+	/* only enable SOF interrupt if it may be needed for the kludge */
+	if (enable_sof_int)
+		set_register_bits(imx21, USBH_SYSIEN, USBH_SYSIEN_SOFINT);
+	else
+		clear_register_bits(imx21, USBH_SYSIEN, USBH_SYSIEN_SOFINT);
+
+
+	spin_unlock_irqrestore(&imx21->lock, flags);
+}
+
+static irqreturn_t imx21_irq(struct usb_hcd *hcd)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	u32 ints = readl(imx21->regs + USBH_SYSISR);
+
+	if (ints & USBH_SYSIEN_HERRINT)
+		dev_dbg(imx21->dev, "Scheduling error\n");
+
+	if (ints & USBH_SYSIEN_SORINT)
+		dev_dbg(imx21->dev, "Scheduling overrun\n");
+
+	if (ints & (USBH_SYSISR_DONEINT | USBH_SYSISR_SOFINT))
+		process_etds(hcd, imx21, ints & USBH_SYSISR_SOFINT);
+
+	writel(ints, imx21->regs + USBH_SYSISR);
+	return IRQ_HANDLED;
+}
+
+static void imx21_hc_endpoint_disable(struct usb_hcd *hcd,
+				      struct usb_host_endpoint *ep)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	unsigned long flags;
+	struct ep_priv *ep_priv;
+	int i;
+
+	if (ep == NULL)
+		return;
+
+	spin_lock_irqsave(&imx21->lock, flags);
+	ep_priv = ep->hcpriv;
+	dev_vdbg(imx21->dev, "disable ep=%p, ep->hcpriv=%p\n", ep, ep_priv);
+
+	if (!list_empty(&ep->urb_list))
+		dev_dbg(imx21->dev, "ep's URB list is not empty\n");
+
+	if (ep_priv != NULL) {
+		for (i = 0; i < NUM_ISO_ETDS; i++) {
+			if (ep_priv->etd[i] > -1)
+				dev_dbg(imx21->dev, "free etd %d for disable\n",
+					ep_priv->etd[i]);
+
+			free_etd(imx21, ep_priv->etd[i]);
+		}
+		kfree(ep_priv);
+		ep->hcpriv = NULL;
+	}
+
+	for (i = 0; i < USB_NUM_ETD; i++) {
+		if (imx21->etd[i].alloc && imx21->etd[i].ep == ep) {
+			dev_err(imx21->dev,
+				"Active etd %d for disabled ep=%p!\n", i, ep);
+			free_etd(imx21, i);
+		}
+	}
+	free_epdmem(imx21, ep);
+	spin_unlock_irqrestore(&imx21->lock, flags);
+}
+
+/* =========================================== */
+/* Hub handling		 			*/
+/* =========================================== */
+
+static int get_hub_descriptor(struct usb_hcd *hcd,
+			      struct usb_hub_descriptor *desc)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	desc->bDescriptorType = 0x29;	/* HUB descriptor */
+	desc->bHubContrCurrent = 0;
+
+	desc->bNbrPorts = readl(imx21->regs + USBH_ROOTHUBA)
+		& USBH_ROOTHUBA_NDNSTMPRT_MASK;
+	desc->bDescLength = 9;
+	desc->bPwrOn2PwrGood = 0;
+	desc->wHubCharacteristics = (__force __u16) cpu_to_le16(
+		0x0002 |	/* No power switching */
+		0x0010 |	/* No over current protection */
+		0);
+
+	desc->bitmap[0] = 1 << 1;
+	desc->bitmap[1] = ~0;
+	return 0;
+}
+
+static int imx21_hc_hub_status_data(struct usb_hcd *hcd, char *buf)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	int ports;
+	int changed = 0;
+	int i;
+	unsigned long flags;
+
+	spin_lock_irqsave(&imx21->lock, flags);
+	ports = readl(imx21->regs + USBH_ROOTHUBA)
+		& USBH_ROOTHUBA_NDNSTMPRT_MASK;
+	if (ports > 7) {
+		ports = 7;
+		dev_err(imx21->dev, "ports %d > 7\n", ports);
+	}
+	for (i = 0; i < ports; i++) {
+		if (readl(imx21->regs + USBH_PORTSTAT(i)) &
+			(USBH_PORTSTAT_CONNECTSC |
+			USBH_PORTSTAT_PRTENBLSC |
+			USBH_PORTSTAT_PRTSTATSC |
+			USBH_PORTSTAT_OVRCURIC |
+			USBH_PORTSTAT_PRTRSTSC)) {
+
+			changed = 1;
+			buf[0] |= 1 << (i + 1);
+		}
+	}
+	spin_unlock_irqrestore(&imx21->lock, flags);
+
+	if (changed)
+		dev_info(imx21->dev, "Hub status changed\n");
+	return changed;
+}
+
+static int imx21_hc_hub_control(struct usb_hcd *hcd,
+				u16 typeReq,
+				u16 wValue, u16 wIndex, char *buf, u16 wLength)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	int rc = 0;
+	u32 status_write = 0;
+
+	switch (typeReq) {
+	case ClearHubFeature:
+		dev_dbg(imx21->dev, "ClearHubFeature\n");
+		switch (wValue) {
+		case C_HUB_OVER_CURRENT:
+			dev_dbg(imx21->dev, "    OVER_CURRENT\n");
+			break;
+		case C_HUB_LOCAL_POWER:
+			dev_dbg(imx21->dev, "    LOCAL_POWER\n");
+			break;
+		default:
+			dev_dbg(imx21->dev, "    unknown\n");
+			rc = -EINVAL;
+			break;
+		}
+		break;
+
+	case ClearPortFeature:
+		dev_dbg(imx21->dev, "ClearPortFeature\n");
+		switch (wValue) {
+		case USB_PORT_FEAT_ENABLE:
+			dev_dbg(imx21->dev, "    ENABLE\n");
+			status_write = USBH_PORTSTAT_CURCONST;
+			break;
+		case USB_PORT_FEAT_SUSPEND:
+			dev_dbg(imx21->dev, "    SUSPEND\n");
+			status_write = USBH_PORTSTAT_PRTOVRCURI;
+			break;
+		case USB_PORT_FEAT_POWER:
+			dev_dbg(imx21->dev, "    POWER\n");
+			status_write = USBH_PORTSTAT_LSDEVCON;
+			break;
+		case USB_PORT_FEAT_C_ENABLE:
+			dev_dbg(imx21->dev, "    C_ENABLE\n");
+			status_write = USBH_PORTSTAT_PRTENBLSC;
+			break;
+		case USB_PORT_FEAT_C_SUSPEND:
+			dev_dbg(imx21->dev, "    C_SUSPEND\n");
+			status_write = USBH_PORTSTAT_PRTSTATSC;
+			break;
+		case USB_PORT_FEAT_C_CONNECTION:
+			dev_dbg(imx21->dev, "    C_CONNECTION\n");
+			status_write = USBH_PORTSTAT_CONNECTSC;
+			break;
+		case USB_PORT_FEAT_C_OVER_CURRENT:
+			dev_dbg(imx21->dev, "    C_OVER_CURRENT\n");
+			status_write = USBH_PORTSTAT_OVRCURIC;
+			break;
+		case USB_PORT_FEAT_C_RESET:
+			dev_dbg(imx21->dev, "    C_RESET\n");
+			status_write = USBH_PORTSTAT_PRTRSTSC;
+			break;
+		default:
+			dev_dbg(imx21->dev, "    unknown\n");
+			rc = -EINVAL;
+			break;
+		}
+
+		break;
+
+	case GetHubDescriptor:
+		dev_dbg(imx21->dev, "GetHubDescriptor\n");
+		rc = get_hub_descriptor(hcd, (void *)buf);
+		break;
+
+	case GetHubStatus:
+		dev_dbg(imx21->dev, "  GetHubStatus\n");
+		*(__le32 *) buf = 0;
+		break;
+
+	case GetPortStatus:
+		dev_dbg(imx21->dev, "GetPortStatus: port: %d, 0x%x\n",
+		    wIndex, USBH_PORTSTAT(wIndex - 1));
+		*(__le32 *) buf = readl(imx21->regs +
+			USBH_PORTSTAT(wIndex - 1));
+		break;
+
+	case SetHubFeature:
+		dev_dbg(imx21->dev, "SetHubFeature\n");
+		switch (wValue) {
+		case C_HUB_OVER_CURRENT:
+			dev_dbg(imx21->dev, "    OVER_CURRENT\n");
+			break;
+
+		case C_HUB_LOCAL_POWER:
+			dev_dbg(imx21->dev, "    LOCAL_POWER\n");
+			break;
+		default:
+			dev_dbg(imx21->dev, "    unknown\n");
+			rc = -EINVAL;
+			break;
+		}
+
+		break;
+
+	case SetPortFeature:
+		dev_dbg(imx21->dev, "SetPortFeature\n");
+		switch (wValue) {
+		case USB_PORT_FEAT_SUSPEND:
+			dev_dbg(imx21->dev, "    SUSPEND\n");
+			status_write = USBH_PORTSTAT_PRTSUSPST;
+			break;
+		case USB_PORT_FEAT_POWER:
+			dev_dbg(imx21->dev, "    POWER\n");
+			status_write = USBH_PORTSTAT_PRTPWRST;
+			break;
+		case USB_PORT_FEAT_RESET:
+			dev_dbg(imx21->dev, "    RESET\n");
+			status_write = USBH_PORTSTAT_PRTRSTST;
+			break;
+		default:
+			dev_dbg(imx21->dev, "    unknown\n");
+			rc = -EINVAL;
+			break;
+		}
+		break;
+
+	default:
+		dev_dbg(imx21->dev, "  unknown\n");
+		rc = -EINVAL;
+		break;
+	}
+
+	if (status_write)
+		writel(status_write, imx21->regs + USBH_PORTSTAT(wIndex - 1));
+	return rc;
+}
+
+/* =========================================== */
+/* Host controller management 			*/
+/* =========================================== */
+
+static int imx21_hc_reset(struct usb_hcd *hcd)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	unsigned long timeout;
+	unsigned long flags;
+
+	spin_lock_irqsave(&imx21->lock, flags);
+
+	/* Reset the Host controler modules */
+	writel(USBOTG_RST_RSTCTRL | USBOTG_RST_RSTRH |
+		USBOTG_RST_RSTHSIE | USBOTG_RST_RSTHC,
+		imx21->regs + USBOTG_RST_CTRL);
+
+	/* Wait for reset to finish */
+	timeout = jiffies + HZ;
+	while (readl(imx21->regs + USBOTG_RST_CTRL) != 0) {
+		if (time_after(jiffies, timeout)) {
+			spin_unlock_irqrestore(&imx21->lock, flags);
+			dev_err(imx21->dev, "timeout waiting for reset\n");
+			return -ETIMEDOUT;
+		}
+		spin_unlock_irq(&imx21->lock);
+		schedule_timeout(1);
+		spin_lock_irq(&imx21->lock);
+	}
+	spin_unlock_irqrestore(&imx21->lock, flags);
+	return 0;
+}
+
+static int __devinit imx21_hc_start(struct usb_hcd *hcd)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	unsigned long flags;
+	int i, j;
+	u32 hw_mode = USBOTG_HWMODE_CRECFG_HOST;
+	u32 usb_control = 0;
+
+	hw_mode |= ((imx21->pdata->host_xcvr << USBOTG_HWMODE_HOSTXCVR_SHIFT) &
+			USBOTG_HWMODE_HOSTXCVR_MASK);
+	hw_mode |= ((imx21->pdata->otg_xcvr << USBOTG_HWMODE_OTGXCVR_SHIFT) &
+			USBOTG_HWMODE_OTGXCVR_MASK);
+
+	if (imx21->pdata->host1_txenoe)
+		usb_control |= USBCTRL_HOST1_TXEN_OE;
+
+	if (!imx21->pdata->host1_xcverless)
+		usb_control |= USBCTRL_HOST1_BYP_TLL;
+
+	if (imx21->pdata->otg_ext_xcvr)
+		usb_control |= USBCTRL_OTC_RCV_RXDP;
+
+
+	spin_lock_irqsave(&imx21->lock, flags);
+
+	writel((USBOTG_CLK_CTRL_HST | USBOTG_CLK_CTRL_MAIN),
+		imx21->regs + USBOTG_CLK_CTRL);
+	writel(hw_mode, imx21->regs + USBOTG_HWMODE);
+	writel(usb_control, imx21->regs + USBCTRL);
+	writel(USB_MISCCONTROL_SKPRTRY  | USB_MISCCONTROL_ARBMODE,
+		imx21->regs + USB_MISCCONTROL);
+
+	/* Clear the ETDs */
+	for (i = 0; i < USB_NUM_ETD; i++)
+		for (j = 0; j < 4; j++)
+			etd_writel(imx21, i, j, 0);
+
+	/* Take the HC out of reset */
+	writel(USBH_HOST_CTRL_HCUSBSTE_OPERATIONAL | USBH_HOST_CTRL_CTLBLKSR_1,
+		imx21->regs + USBH_HOST_CTRL);
+
+	/* Enable ports */
+	if (imx21->pdata->enable_otg_host)
+		writel(USBH_PORTSTAT_PRTPWRST | USBH_PORTSTAT_PRTENABST,
+			imx21->regs + USBH_PORTSTAT(0));
+
+	if (imx21->pdata->enable_host1)
+		writel(USBH_PORTSTAT_PRTPWRST | USBH_PORTSTAT_PRTENABST,
+			imx21->regs + USBH_PORTSTAT(1));
+
+	if (imx21->pdata->enable_host2)
+		writel(USBH_PORTSTAT_PRTPWRST | USBH_PORTSTAT_PRTENABST,
+			imx21->regs + USBH_PORTSTAT(2));
+
+
+	hcd->state = HC_STATE_RUNNING;
+
+	/* Enable host controller interrupts */
+	set_register_bits(imx21, USBH_SYSIEN,
+		USBH_SYSIEN_HERRINT |
+		USBH_SYSIEN_DONEINT | USBH_SYSIEN_SORINT);
+	set_register_bits(imx21, USBOTG_CINT_STEN, USBOTG_HCINT);
+
+	spin_unlock_irqrestore(&imx21->lock, flags);
+
+	return 0;
+}
+
+static void imx21_hc_stop(struct usb_hcd *hcd)
+{
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	unsigned long flags;
+
+	spin_lock_irqsave(&imx21->lock, flags);
+
+	writel(0, imx21->regs + USBH_SYSIEN);
+	clear_register_bits(imx21, USBOTG_CINT_STEN, USBOTG_HCINT);
+	clear_register_bits(imx21, USBOTG_CLK_CTRL_HST | USBOTG_CLK_CTRL_MAIN,
+					USBOTG_CLK_CTRL);
+	spin_unlock_irqrestore(&imx21->lock, flags);
+}
+
+/* =========================================== */
+/* Driver glue		 			*/
+/* =========================================== */
+
+static struct hc_driver imx21_hc_driver = {
+	.description = hcd_name,
+	.product_desc = "IMX21 USB Host Controller",
+	.hcd_priv_size = sizeof(struct imx21),
+
+	.flags = HCD_USB11,
+	.irq = imx21_irq,
+
+	.reset = imx21_hc_reset,
+	.start = imx21_hc_start,
+	.stop = imx21_hc_stop,
+
+	/* I/O requests */
+	.urb_enqueue = imx21_hc_urb_enqueue,
+	.urb_dequeue = imx21_hc_urb_dequeue,
+	.endpoint_disable = imx21_hc_endpoint_disable,
+
+	/* scheduling support */
+	.get_frame_number = imx21_hc_get_frame,
+
+	/* Root hub support */
+	.hub_status_data = imx21_hc_hub_status_data,
+	.hub_control = imx21_hc_hub_control,
+
+};
+
+static struct mx21_usbh_platform_data default_pdata = {
+	.host_xcvr = MX21_USBXCVR_TXDIF_RXDIF,
+	.otg_xcvr = MX21_USBXCVR_TXDIF_RXDIF,
+	.enable_host1 = 1,
+	.enable_host2 = 1,
+	.enable_otg_host = 1,
+
+};
+
+static int imx21_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct imx21 *imx21 = hcd_to_imx21(hcd);
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	remove_debug_files(imx21);
+	usb_remove_hcd(hcd);
+
+	if (res != NULL) {
+		clk_disable(imx21->clk);
+		clk_put(imx21->clk);
+		iounmap(imx21->regs);
+		release_mem_region(res->start, resource_size(res));
+	}
+
+	kfree(hcd);
+	return 0;
+}
+
+
+static int imx21_probe(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd;
+	struct imx21 *imx21;
+	struct resource *res;
+	int ret;
+	int irq;
+
+	printk(KERN_INFO "%s\n", imx21_hc_driver.product_desc);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return -ENXIO;
+
+	hcd = usb_create_hcd(&imx21_hc_driver,
+		&pdev->dev, dev_name(&pdev->dev));
+	if (hcd == NULL) {
+		dev_err(&pdev->dev, "Cannot create hcd (%s)\n",
+		    dev_name(&pdev->dev));
+		return -ENOMEM;
+	}
+
+	imx21 = hcd_to_imx21(hcd);
+	imx21->dev = &pdev->dev;
+	imx21->pdata = pdev->dev.platform_data;
+	if (!imx21->pdata)
+		imx21->pdata = &default_pdata;
+
+	spin_lock_init(&imx21->lock);
+	INIT_LIST_HEAD(&imx21->dmem_list);
+	INIT_LIST_HEAD(&imx21->queue_for_etd);
+	INIT_LIST_HEAD(&imx21->queue_for_dmem);
+	create_debug_files(imx21);
+
+	res = request_mem_region(res->start, resource_size(res), hcd_name);
+	if (!res) {
+		ret = -EBUSY;
+		goto failed_request_mem;
+	}
+
+	imx21->regs = ioremap(res->start, resource_size(res));
+	if (imx21->regs == NULL) {
+		dev_err(imx21->dev, "Cannot map registers\n");
+		ret = -ENOMEM;
+		goto failed_ioremap;
+	}
+
+	/* Enable clocks source */
+	imx21->clk = clk_get(imx21->dev, NULL);
+	if (IS_ERR(imx21->clk)) {
+		dev_err(imx21->dev, "no clock found\n");
+		ret = PTR_ERR(imx21->clk);
+		goto failed_clock_get;
+	}
+
+	ret = clk_set_rate(imx21->clk, clk_round_rate(imx21->clk, 48000000));
+	if (ret)
+		goto failed_clock_set;
+	ret = clk_enable(imx21->clk);
+	if (ret)
+		goto failed_clock_enable;
+
+	dev_info(imx21->dev, "Hardware HC revision: 0x%02X\n",
+		(readl(imx21->regs + USBOTG_HWMODE) >> 16) & 0xFF);
+
+	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+	if (ret != 0) {
+		dev_err(imx21->dev, "usb_add_hcd() returned %d\n", ret);
+		goto failed_add_hcd;
+	}
+
+	return 0;
+
+failed_add_hcd:
+	clk_disable(imx21->clk);
+failed_clock_enable:
+failed_clock_set:
+	clk_put(imx21->clk);
+failed_clock_get:
+	iounmap(imx21->regs);
+failed_ioremap:
+	release_mem_region(res->start, res->end - res->start);
+failed_request_mem:
+	remove_debug_files(imx21);
+	usb_put_hcd(hcd);
+	return ret;
+}
+
+static struct platform_driver imx21_hcd_driver = {
+	.driver = {
+		   .name = (char *)hcd_name,
+		   },
+	.probe = imx21_probe,
+	.remove = imx21_remove,
+	.suspend = NULL,
+	.resume = NULL,
+};
+
+static int __init imx21_hcd_init(void)
+{
+	return platform_driver_register(&imx21_hcd_driver);
+}
+
+static void __exit imx21_hcd_cleanup(void)
+{
+	platform_driver_unregister(&imx21_hcd_driver);
+}
+
+module_init(imx21_hcd_init);
+module_exit(imx21_hcd_cleanup);
+
+MODULE_DESCRIPTION("i.MX21 USB Host controller");
+MODULE_AUTHOR("Martin Fuzzey");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx21-hcd");
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/imx21-hcd.h linux-libre-2.6.34-gnu1/drivers/usb/host/imx21-hcd.h
--- linux-libre-2.6.33-gnu1/drivers/usb/host/imx21-hcd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/imx21-hcd.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,436 @@
+/*
+ * Macros and prototypes for i.MX21
+ *
+ * Copyright (C) 2006 Loping Dog Embedded Systems
+ * Copyright (C) 2009 Martin Fuzzey
+ * Originally written by Jay Monkman <jtm@lopingdog.com>
+ * Ported to 2.6.30, debugged and enhanced by Martin Fuzzey
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __LINUX_IMX21_HCD_H__
+#define __LINUX_IMX21_HCD_H__
+
+#include <mach/mx21-usbhost.h>
+
+#define NUM_ISO_ETDS 	2
+#define USB_NUM_ETD	32
+#define DMEM_SIZE   	4096
+
+/* Register definitions */
+#define USBOTG_HWMODE		0x00
+#define USBOTG_HWMODE_ANASDBEN		(1 << 14)
+#define USBOTG_HWMODE_OTGXCVR_SHIFT	6
+#define USBOTG_HWMODE_OTGXCVR_MASK	(3 << 6)
+#define USBOTG_HWMODE_OTGXCVR_TD_RD	(0 << 6)
+#define USBOTG_HWMODE_OTGXCVR_TS_RD	(2 << 6)
+#define USBOTG_HWMODE_OTGXCVR_TD_RS	(1 << 6)
+#define USBOTG_HWMODE_OTGXCVR_TS_RS	(3 << 6)
+#define USBOTG_HWMODE_HOSTXCVR_SHIFT	4
+#define USBOTG_HWMODE_HOSTXCVR_MASK	(3 << 4)
+#define USBOTG_HWMODE_HOSTXCVR_TD_RD	(0 << 4)
+#define USBOTG_HWMODE_HOSTXCVR_TS_RD	(2 << 4)
+#define USBOTG_HWMODE_HOSTXCVR_TD_RS	(1 << 4)
+#define USBOTG_HWMODE_HOSTXCVR_TS_RS	(3 << 4)
+#define USBOTG_HWMODE_CRECFG_MASK	(3 << 0)
+#define USBOTG_HWMODE_CRECFG_HOST	(1 << 0)
+#define USBOTG_HWMODE_CRECFG_FUNC	(2 << 0)
+#define USBOTG_HWMODE_CRECFG_HNP	(3 << 0)
+
+#define USBOTG_CINT_STAT	0x04
+#define USBOTG_CINT_STEN	0x08
+#define USBOTG_ASHNPINT			(1 << 5)
+#define USBOTG_ASFCINT			(1 << 4)
+#define USBOTG_ASHCINT			(1 << 3)
+#define USBOTG_SHNPINT			(1 << 2)
+#define USBOTG_FCINT			(1 << 1)
+#define USBOTG_HCINT			(1 << 0)
+
+#define USBOTG_CLK_CTRL		0x0c
+#define USBOTG_CLK_CTRL_FUNC		(1 << 2)
+#define USBOTG_CLK_CTRL_HST		(1 << 1)
+#define USBOTG_CLK_CTRL_MAIN		(1 << 0)
+
+#define USBOTG_RST_CTRL		0x10
+#define USBOTG_RST_RSTI2C		(1 << 15)
+#define USBOTG_RST_RSTCTRL		(1 << 5)
+#define USBOTG_RST_RSTFC		(1 << 4)
+#define USBOTG_RST_RSTFSKE		(1 << 3)
+#define USBOTG_RST_RSTRH		(1 << 2)
+#define USBOTG_RST_RSTHSIE		(1 << 1)
+#define USBOTG_RST_RSTHC		(1 << 0)
+
+#define USBOTG_FRM_INTVL    	0x14
+#define USBOTG_FRM_REMAIN   	0x18
+#define USBOTG_HNP_CSR	    	0x1c
+#define USBOTG_HNP_ISR	    	0x2c
+#define USBOTG_HNP_IEN	    	0x30
+
+#define USBOTG_I2C_TXCVR_REG(x)	(0x100 + (x))
+#define USBOTG_I2C_XCVR_DEVAD		0x118
+#define USBOTG_I2C_SEQ_OP_REG		0x119
+#define USBOTG_I2C_SEQ_RD_STARTAD	0x11a
+#define USBOTG_I2C_OP_CTRL_REG	     	0x11b
+#define USBOTG_I2C_SCLK_TO_SCK_HPER  	0x11e
+#define USBOTG_I2C_MASTER_INT_REG    	0x11f
+
+#define USBH_HOST_CTRL		0x80
+#define USBH_HOST_CTRL_HCRESET			(1 << 31)
+#define USBH_HOST_CTRL_SCHDOVR(x)		((x) << 16)
+#define USBH_HOST_CTRL_RMTWUEN			(1 << 4)
+#define USBH_HOST_CTRL_HCUSBSTE_RESET		(0 << 2)
+#define USBH_HOST_CTRL_HCUSBSTE_RESUME		(1 << 2)
+#define USBH_HOST_CTRL_HCUSBSTE_OPERATIONAL	(2 << 2)
+#define USBH_HOST_CTRL_HCUSBSTE_SUSPEND	(3 << 2)
+#define USBH_HOST_CTRL_CTLBLKSR_1		(0 << 0)
+#define USBH_HOST_CTRL_CTLBLKSR_2		(1 << 0)
+#define USBH_HOST_CTRL_CTLBLKSR_3		(2 << 0)
+#define USBH_HOST_CTRL_CTLBLKSR_4		(3 << 0)
+
+#define USBH_SYSISR		0x88
+#define USBH_SYSISR_PSCINT		(1 << 6)
+#define USBH_SYSISR_FMOFINT		(1 << 5)
+#define USBH_SYSISR_HERRINT		(1 << 4)
+#define USBH_SYSISR_RESDETINT		(1 << 3)
+#define USBH_SYSISR_SOFINT		(1 << 2)
+#define USBH_SYSISR_DONEINT		(1 << 1)
+#define USBH_SYSISR_SORINT		(1 << 0)
+
+#define USBH_SYSIEN	    	0x8c
+#define USBH_SYSIEN_PSCINT		(1 << 6)
+#define USBH_SYSIEN_FMOFINT		(1 << 5)
+#define USBH_SYSIEN_HERRINT		(1 << 4)
+#define USBH_SYSIEN_RESDETINT		(1 << 3)
+#define USBH_SYSIEN_SOFINT		(1 << 2)
+#define USBH_SYSIEN_DONEINT		(1 << 1)
+#define USBH_SYSIEN_SORINT		(1 << 0)
+
+#define USBH_XBUFSTAT	    	0x98
+#define USBH_YBUFSTAT	    	0x9c
+#define USBH_XYINTEN	    	0xa0
+#define USBH_XFILLSTAT	    	0xa8
+#define USBH_YFILLSTAT	    	0xac
+#define USBH_ETDENSET	    	0xc0
+#define USBH_ETDENCLR	    	0xc4
+#define USBH_IMMEDINT	    	0xcc
+#define USBH_ETDDONESTAT    	0xd0
+#define USBH_ETDDONEEN	    	0xd4
+#define USBH_FRMNUB	    	0xe0
+#define USBH_LSTHRESH	    	0xe4
+
+#define USBH_ROOTHUBA	    	0xe8
+#define USBH_ROOTHUBA_PWRTOGOOD_MASK	(0xff)
+#define USBH_ROOTHUBA_PWRTOGOOD_SHIFT	(24)
+#define USBH_ROOTHUBA_NOOVRCURP	(1 << 12)
+#define USBH_ROOTHUBA_OVRCURPM		(1 << 11)
+#define USBH_ROOTHUBA_DEVTYPE		(1 << 10)
+#define USBH_ROOTHUBA_PWRSWTMD		(1 << 9)
+#define USBH_ROOTHUBA_NOPWRSWT		(1 << 8)
+#define USBH_ROOTHUBA_NDNSTMPRT_MASK	(0xff)
+
+#define USBH_ROOTHUBB		0xec
+#define USBH_ROOTHUBB_PRTPWRCM(x)	(1 << ((x) + 16))
+#define USBH_ROOTHUBB_DEVREMOVE(x)	(1 << (x))
+
+#define USBH_ROOTSTAT		0xf0
+#define USBH_ROOTSTAT_CLRRMTWUE	(1 << 31)
+#define USBH_ROOTSTAT_OVRCURCHG	(1 << 17)
+#define USBH_ROOTSTAT_DEVCONWUE	(1 << 15)
+#define USBH_ROOTSTAT_OVRCURI		(1 << 1)
+#define USBH_ROOTSTAT_LOCPWRS		(1 << 0)
+
+#define USBH_PORTSTAT(x)	(0xf4 + ((x) * 4))
+#define USBH_PORTSTAT_PRTRSTSC		(1 << 20)
+#define USBH_PORTSTAT_OVRCURIC		(1 << 19)
+#define USBH_PORTSTAT_PRTSTATSC	(1 << 18)
+#define USBH_PORTSTAT_PRTENBLSC	(1 << 17)
+#define USBH_PORTSTAT_CONNECTSC	(1 << 16)
+#define USBH_PORTSTAT_LSDEVCON		(1 << 9)
+#define USBH_PORTSTAT_PRTPWRST		(1 << 8)
+#define USBH_PORTSTAT_PRTRSTST		(1 << 4)
+#define USBH_PORTSTAT_PRTOVRCURI	(1 << 3)
+#define USBH_PORTSTAT_PRTSUSPST	(1 << 2)
+#define USBH_PORTSTAT_PRTENABST	(1 << 1)
+#define USBH_PORTSTAT_CURCONST		(1 << 0)
+
+#define USB_DMAREV		0x800
+#define USB_DMAINTSTAT	    	0x804
+#define USB_DMAINTSTAT_EPERR		(1 << 1)
+#define USB_DMAINTSTAT_ETDERR		(1 << 0)
+
+#define USB_DMAINTEN	    	0x808
+#define USB_DMAINTEN_EPERRINTEN	(1 << 1)
+#define USB_DMAINTEN_ETDERRINTEN	(1 << 0)
+
+#define USB_ETDDMAERSTAT    	0x80c
+#define USB_EPDMAERSTAT	    	0x810
+#define USB_ETDDMAEN	    	0x820
+#define USB_EPDMAEN	    	0x824
+#define USB_ETDDMAXTEN	    	0x828
+#define USB_EPDMAXTEN	    	0x82c
+#define USB_ETDDMAENXYT	    	0x830
+#define USB_EPDMAENXYT	    	0x834
+#define USB_ETDDMABST4EN    	0x838
+#define USB_EPDMABST4EN	    	0x83c
+
+#define USB_MISCCONTROL	    	0x840
+#define USB_MISCCONTROL_ISOPREVFRM	(1 << 3)
+#define USB_MISCCONTROL_SKPRTRY	(1 << 2)
+#define USB_MISCCONTROL_ARBMODE	(1 << 1)
+#define USB_MISCCONTROL_FILTCC		(1 << 0)
+
+#define USB_ETDDMACHANLCLR  	0x848
+#define USB_EPDMACHANLCLR   	0x84c
+#define USB_ETDSMSA(x)	    	(0x900 + ((x) * 4))
+#define USB_EPSMSA(x)	    	(0x980 + ((x) * 4))
+#define USB_ETDDMABUFPTR(x) 	(0xa00 + ((x) * 4))
+#define USB_EPDMABUFPTR(x)  	(0xa80 + ((x) * 4))
+
+#define USB_ETD_DWORD(x, w)	(0x200 + ((x) * 16) + ((w) * 4))
+#define DW0_ADDRESS	0
+#define	DW0_ENDPNT	7
+#define	DW0_DIRECT	11
+#define	DW0_SPEED	13
+#define DW0_FORMAT	14
+#define DW0_MAXPKTSIZ	16
+#define DW0_HALTED	27
+#define	DW0_TOGCRY	28
+#define	DW0_SNDNAK	30
+
+#define DW1_XBUFSRTAD	0
+#define DW1_YBUFSRTAD	16
+
+#define DW2_RTRYDELAY	0
+#define DW2_POLINTERV	0
+#define DW2_STARTFRM	0
+#define DW2_RELPOLPOS	8
+#define DW2_DIRPID	16
+#define	DW2_BUFROUND	18
+#define DW2_DELAYINT	19
+#define DW2_DATATOG	22
+#define DW2_ERRORCNT	24
+#define	DW2_COMPCODE	28
+
+#define DW3_TOTBYECNT	0
+#define DW3_PKTLEN0	0
+#define DW3_COMPCODE0	12
+#define DW3_PKTLEN1	16
+#define DW3_BUFSIZE	21
+#define DW3_COMPCODE1	28
+
+#define USBCTRL		    	0x600
+#define USBCTRL_I2C_WU_INT_STAT	(1 << 27)
+#define USBCTRL_OTG_WU_INT_STAT	(1 << 26)
+#define USBCTRL_HOST_WU_INT_STAT	(1 << 25)
+#define USBCTRL_FNT_WU_INT_STAT	(1 << 24)
+#define USBCTRL_I2C_WU_INT_EN		(1 << 19)
+#define USBCTRL_OTG_WU_INT_EN		(1 << 18)
+#define USBCTRL_HOST_WU_INT_EN		(1 << 17)
+#define USBCTRL_FNT_WU_INT_EN		(1 << 16)
+#define USBCTRL_OTC_RCV_RXDP		(1 << 13)
+#define USBCTRL_HOST1_BYP_TLL		(1 << 12)
+#define USBCTRL_OTG_BYP_VAL(x)		((x) << 10)
+#define USBCTRL_HOST1_BYP_VAL(x)	((x) << 8)
+#define USBCTRL_OTG_PWR_MASK		(1 << 6)
+#define USBCTRL_HOST1_PWR_MASK		(1 << 5)
+#define USBCTRL_HOST2_PWR_MASK		(1 << 4)
+#define USBCTRL_USB_BYP			(1 << 2)
+#define USBCTRL_HOST1_TXEN_OE		(1 << 1)
+
+
+/* Values in TD blocks */
+#define TD_DIR_SETUP	    0
+#define TD_DIR_OUT	    1
+#define TD_DIR_IN	    2
+#define TD_FORMAT_CONTROL   0
+#define TD_FORMAT_ISO	    1
+#define TD_FORMAT_BULK	    2
+#define TD_FORMAT_INT	    3
+#define TD_TOGGLE_CARRY	    0
+#define TD_TOGGLE_DATA0	    2
+#define TD_TOGGLE_DATA1	    3
+
+/* control transfer states */
+#define US_CTRL_SETUP	2
+#define US_CTRL_DATA	1
+#define US_CTRL_ACK	0
+
+/* bulk transfer main state and 0-length packet */
+#define US_BULK		1
+#define US_BULK0	0
+
+/*ETD format description*/
+#define IMX_FMT_CTRL   0x0
+#define IMX_FMT_ISO    0x1
+#define IMX_FMT_BULK   0x2
+#define IMX_FMT_INT    0x3
+
+static char fmt_urb_to_etd[4] = {
+/*PIPE_ISOCHRONOUS*/ IMX_FMT_ISO,
+/*PIPE_INTERRUPT*/ IMX_FMT_INT,
+/*PIPE_CONTROL*/ IMX_FMT_CTRL,
+/*PIPE_BULK*/ IMX_FMT_BULK
+};
+
+/* condition (error) CC codes and mapping (OHCI like) */
+
+#define TD_CC_NOERROR		0x00
+#define TD_CC_CRC		0x01
+#define TD_CC_BITSTUFFING	0x02
+#define TD_CC_DATATOGGLEM	0x03
+#define TD_CC_STALL		0x04
+#define TD_DEVNOTRESP		0x05
+#define TD_PIDCHECKFAIL		0x06
+/*#define TD_UNEXPECTEDPID	0x07 - reserved, not active on MX2*/
+#define TD_DATAOVERRUN		0x08
+#define TD_DATAUNDERRUN		0x09
+#define TD_BUFFEROVERRUN	0x0C
+#define TD_BUFFERUNDERRUN	0x0D
+#define	TD_SCHEDULEOVERRUN	0x0E
+#define TD_NOTACCESSED		0x0F
+
+static const int cc_to_error[16] = {
+	/* No  Error  */ 0,
+	/* CRC Error  */ -EILSEQ,
+	/* Bit Stuff  */ -EPROTO,
+	/* Data Togg  */ -EILSEQ,
+	/* Stall      */ -EPIPE,
+	/* DevNotResp */ -ETIMEDOUT,
+	/* PIDCheck   */ -EPROTO,
+	/* UnExpPID   */ -EPROTO,
+	/* DataOver   */ -EOVERFLOW,
+	/* DataUnder  */ -EREMOTEIO,
+	/* (for hw)   */ -EIO,
+	/* (for hw)   */ -EIO,
+	/* BufferOver */ -ECOMM,
+	/* BuffUnder  */ -ENOSR,
+	/* (for HCD)  */ -ENOSPC,
+	/* (for HCD)  */ -EALREADY
+};
+
+/* HCD data associated with a usb core URB */
+struct urb_priv {
+	struct urb *urb;
+	struct usb_host_endpoint *ep;
+	int active;
+	int state;
+	struct td *isoc_td;
+	int isoc_remaining;
+	int isoc_status;
+};
+
+/* HCD data associated with a usb core endpoint */
+struct ep_priv {
+	struct usb_host_endpoint *ep;
+	struct list_head td_list;
+	struct list_head queue;
+	int etd[NUM_ISO_ETDS];
+	int waiting_etd;
+};
+
+/* isoc packet */
+struct td {
+	struct list_head list;
+	struct urb *urb;
+	struct usb_host_endpoint *ep;
+	dma_addr_t data;
+	unsigned long buf_addr;
+	int len;
+	int frame;
+	int isoc_index;
+};
+
+/* HCD data associated with a hardware ETD */
+struct etd_priv {
+	struct usb_host_endpoint *ep;
+	struct urb *urb;
+	struct td *td;
+	struct list_head queue;
+	dma_addr_t dma_handle;
+	int alloc;
+	int len;
+	int dmem_size;
+	int dmem_offset;
+	int active_count;
+#ifdef DEBUG
+	int activated_frame;
+	int disactivated_frame;
+	int last_int_frame;
+	int last_req_frame;
+	u32 submitted_dwords[4];
+#endif
+};
+
+/* Hardware data memory info */
+struct imx21_dmem_area {
+	struct usb_host_endpoint *ep;
+	unsigned int offset;
+	unsigned int size;
+	struct list_head list;
+};
+
+#ifdef DEBUG
+struct debug_usage_stats {
+	unsigned int value;
+	unsigned int maximum;
+};
+
+struct debug_stats {
+	unsigned long submitted;
+	unsigned long completed_ok;
+	unsigned long completed_failed;
+	unsigned long unlinked;
+	unsigned long queue_etd;
+	unsigned long queue_dmem;
+};
+
+struct debug_isoc_trace {
+	int schedule_frame;
+	int submit_frame;
+	int request_len;
+	int done_frame;
+	int done_len;
+	int cc;
+	struct td *td;
+};
+#endif
+
+/* HCD data structure */
+struct imx21 {
+	spinlock_t lock;
+	struct device *dev;
+	struct mx21_usbh_platform_data *pdata;
+	struct list_head dmem_list;
+	struct list_head queue_for_etd; /* eps queued due to etd shortage */
+	struct list_head queue_for_dmem; /* etds queued due to dmem shortage */
+	struct etd_priv etd[USB_NUM_ETD];
+	struct clk *clk;
+	void __iomem *regs;
+#ifdef DEBUG
+	struct dentry *debug_root;
+	struct debug_stats nonisoc_stats;
+	struct debug_stats isoc_stats;
+	struct debug_usage_stats etd_usage;
+	struct debug_usage_stats dmem_usage;
+	struct debug_isoc_trace isoc_trace[20];
+	struct debug_isoc_trace isoc_trace_failed[20];
+	unsigned long debug_unblocks;
+	int isoc_trace_index;
+	int isoc_trace_index_failed;
+#endif
+};
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/isp116x-hcd.c linux-libre-2.6.34-gnu1/drivers/usb/host/isp116x-hcd.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/isp116x-hcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/isp116x-hcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -62,6 +62,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/isp116x.h>
 #include <linux/platform_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/isp1362-hcd.c linux-libre-2.6.34-gnu1/drivers/usb/host/isp1362-hcd.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/isp1362-hcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/isp1362-hcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -1257,7 +1257,7 @@ static int isp1362_urb_enqueue(struct us
 
 	/* avoid all allocations within spinlocks: request or endpoint */
 	if (!hep->hcpriv) {
-		ep = kcalloc(1, sizeof *ep, mem_flags);
+		ep = kzalloc(sizeof *ep, mem_flags);
 		if (!ep)
 			return -ENOMEM;
 	}
@@ -2719,24 +2719,11 @@ static int __init isp1362_probe(struct p
 	}
 	irq = irq_res->start;
 
-#ifdef CONFIG_USB_HCD_DMA
-	if (pdev->dev.dma_mask) {
-		struct resource *dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
-
-		if (!dma_res) {
-			retval = -ENODEV;
-			goto err1;
-		}
-		isp1362_hcd->data_dma = dma_res->start;
-		isp1362_hcd->max_dma_size = resource_len(dma_res);
-	}
-#else
 	if (pdev->dev.dma_mask) {
 		DBG(1, "won't do DMA");
 		retval = -ENODEV;
 		goto err1;
 	}
-#endif
 
 	if (!request_mem_region(addr->start, resource_len(addr), hcd_name)) {
 		retval = -EBUSY;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/isp1760-hcd.c linux-libre-2.6.34-gnu1/drivers/usb/host/isp1760-hcd.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/isp1760-hcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/isp1760-hcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,9 @@
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/mm.h>
 #include <asm/unaligned.h>
+#include <asm/cacheflush.h>
 
 #include "../core/hcd.h"
 #include "isp1760-hcd.h"
@@ -904,6 +906,14 @@ __acquires(priv->lock)
 			status = 0;
 	}
 
+	if (usb_pipein(urb->pipe) && usb_pipetype(urb->pipe) != PIPE_CONTROL) {
+		void *ptr;
+		for (ptr = urb->transfer_buffer;
+		     ptr < urb->transfer_buffer + urb->transfer_buffer_length;
+		     ptr += PAGE_SIZE)
+			flush_dcache_page(virt_to_page(ptr));
+	}
+
 	/* complete() can reenter this HCD */
 	usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb);
 	spin_unlock(&priv->lock);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/isp1760-if.c linux-libre-2.6.34-gnu1/drivers/usb/host/isp1760-if.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/isp1760-if.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/isp1760-if.c	2010-05-16 17:17:36.000000000 -0400
@@ -109,7 +109,7 @@ static int of_isp1760_remove(struct of_d
 	return 0;
 }
 
-static struct of_device_id of_isp1760_match[] = {
+static const struct of_device_id of_isp1760_match[] = {
 	{
 		.compatible = "nxp,usb-isp1760",
 	},
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/Kconfig linux-libre-2.6.34-gnu1/drivers/usb/host/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/usb/host/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -399,3 +399,14 @@ config USB_HWA_HCD
 
 	  To compile this driver a module, choose M here: the module
 	  will be called "hwa-hc".
+
+config USB_IMX21_HCD
+       tristate "iMX21 HCD support"
+       depends on USB && ARM && MACH_MX21
+       help
+         This driver enables support for the on-chip USB host in the
+         iMX21 processor.
+
+         To compile this driver as a module, choose M here: the
+         module will be called "imx21-hcd".
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/Makefile linux-libre-2.6.34-gnu1/drivers/usb/host/Makefile
--- linux-libre-2.6.33-gnu1/drivers/usb/host/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,7 @@ fhci-objs := fhci-hcd.o fhci-hub.o fhci-
 ifeq ($(CONFIG_FHCI_DEBUG),y)
 fhci-objs += fhci-dbg.o
 endif
-xhci-objs := xhci-hcd.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o
+xhci-hcd-objs := xhci.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o
 
 obj-$(CONFIG_USB_WHCI_HCD)	+= whci/
 
@@ -25,10 +25,12 @@ obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
-obj-$(CONFIG_USB_XHCI_HCD)	+= xhci.o
+obj-$(CONFIG_USB_XHCI_HCD)	+= xhci-hcd.o
 obj-$(CONFIG_USB_SL811_HCD)	+= sl811-hcd.o
 obj-$(CONFIG_USB_SL811_CS)	+= sl811_cs.o
 obj-$(CONFIG_USB_U132_HCD)	+= u132-hcd.o
 obj-$(CONFIG_USB_R8A66597_HCD)	+= r8a66597-hcd.o
 obj-$(CONFIG_USB_ISP1760_HCD)	+= isp1760.o
 obj-$(CONFIG_USB_HWA_HCD)	+= hwa-hc.o
+obj-$(CONFIG_USB_IMX21_HCD)	+= imx21-hcd.o
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-at91.c linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-at91.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-at91.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-at91.c	2010-05-16 17:17:36.000000000 -0400
@@ -331,6 +331,8 @@ ohci_hcd_at91_drv_suspend(struct platfor
 	 */
 	if (at91_suspend_entering_slow_clock()) {
 		ohci_usb_reset (ohci);
+		/* flush the writes */
+		(void) ohci_readl (ohci, &ohci->regs->control);
 		at91_stop_clock();
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-da8xx.c linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-da8xx.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-da8xx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-da8xx.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,456 @@
+/*
+ * OHCI HCD (Host Controller Driver) for USB.
+ *
+ * TI DA8xx (OMAP-L1x) Bus Glue
+ *
+ * Derived from: ohci-omap.c and ohci-s3c2410.c
+ * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <mach/da8xx.h>
+#include <mach/usb.h>
+
+#ifndef CONFIG_ARCH_DAVINCI_DA8XX
+#error "This file is DA8xx bus glue.  Define CONFIG_ARCH_DAVINCI_DA8XX."
+#endif
+
+#define CFGCHIP2	DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)
+
+static struct clk *usb11_clk;
+static struct clk *usb20_clk;
+
+/* Over-current indicator change bitmask */
+static volatile u16 ocic_mask;
+
+static void ohci_da8xx_clock(int on)
+{
+	u32 cfgchip2;
+
+	cfgchip2 = __raw_readl(CFGCHIP2);
+	if (on) {
+		clk_enable(usb11_clk);
+
+		/*
+		 * If USB 1.1 reference clock is sourced from USB 2.0 PHY, we
+		 * need to enable the USB 2.0 module clocking, start its PHY,
+		 * and not allow it to stop the clock during USB 2.0 suspend.
+		 */
+		if (!(cfgchip2 & CFGCHIP2_USB1PHYCLKMUX)) {
+			clk_enable(usb20_clk);
+
+			cfgchip2 &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN);
+			cfgchip2 |= CFGCHIP2_PHY_PLLON;
+			__raw_writel(cfgchip2, CFGCHIP2);
+
+			pr_info("Waiting for USB PHY clock good...\n");
+			while (!(__raw_readl(CFGCHIP2) & CFGCHIP2_PHYCLKGD))
+				cpu_relax();
+		}
+
+		/* Enable USB 1.1 PHY */
+		cfgchip2 |= CFGCHIP2_USB1SUSPENDM;
+	} else {
+		clk_disable(usb11_clk);
+		if (!(cfgchip2 & CFGCHIP2_USB1PHYCLKMUX))
+			clk_disable(usb20_clk);
+
+		/* Disable USB 1.1 PHY */
+		cfgchip2 &= ~CFGCHIP2_USB1SUSPENDM;
+	}
+	__raw_writel(cfgchip2, CFGCHIP2);
+}
+
+/*
+ * Handle the port over-current indicator change.
+ */
+static void ohci_da8xx_ocic_handler(struct da8xx_ohci_root_hub *hub,
+				    unsigned port)
+{
+	ocic_mask |= 1 << port;
+
+	/* Once over-current is detected, the port needs to be powered down */
+	if (hub->get_oci(port) > 0)
+		hub->set_power(port, 0);
+}
+
+static int ohci_da8xx_init(struct usb_hcd *hcd)
+{
+	struct device *dev		= hcd->self.controller;
+	struct da8xx_ohci_root_hub *hub	= dev->platform_data;
+	struct ohci_hcd	*ohci		= hcd_to_ohci(hcd);
+	int result;
+	u32 rh_a;
+
+	dev_dbg(dev, "starting USB controller\n");
+
+	ohci_da8xx_clock(1);
+
+	/*
+	 * DA8xx only have 1 port connected to the pins but the HC root hub
+	 * register A reports 2 ports, thus we'll have to override it...
+	 */
+	ohci->num_ports = 1;
+
+	result = ohci_init(ohci);
+	if (result < 0)
+		return result;
+
+	/*
+	 * Since we're providing a board-specific root hub port power control
+	 * and over-current reporting, we have to override the HC root hub A
+	 * register's default value, so that ohci_hub_control() could return
+	 * the correct hub descriptor...
+	 */
+	rh_a = ohci_readl(ohci, &ohci->regs->roothub.a);
+	if (hub->set_power) {
+		rh_a &= ~RH_A_NPS;
+		rh_a |=  RH_A_PSM;
+	}
+	if (hub->get_oci) {
+		rh_a &= ~RH_A_NOCP;
+		rh_a |=  RH_A_OCPM;
+	}
+	rh_a &= ~RH_A_POTPGT;
+	rh_a |= hub->potpgt << 24;
+	ohci_writel(ohci, rh_a, &ohci->regs->roothub.a);
+
+	return result;
+}
+
+static void ohci_da8xx_stop(struct usb_hcd *hcd)
+{
+	ohci_stop(hcd);
+	ohci_da8xx_clock(0);
+}
+
+static int ohci_da8xx_start(struct usb_hcd *hcd)
+{
+	struct ohci_hcd	*ohci		= hcd_to_ohci(hcd);
+	int result;
+
+	result = ohci_run(ohci);
+	if (result < 0)
+		ohci_da8xx_stop(hcd);
+
+	return result;
+}
+
+/*
+ * Update the status data from the hub with the over-current indicator change.
+ */
+static int ohci_da8xx_hub_status_data(struct usb_hcd *hcd, char *buf)
+{
+	int length		= ohci_hub_status_data(hcd, buf);
+
+	/* See if we have OCIC bit set on port 1 */
+	if (ocic_mask & (1 << 1)) {
+		dev_dbg(hcd->self.controller, "over-current indicator change "
+			"on port 1\n");
+
+		if (!length)
+			length = 1;
+
+		buf[0] |= 1 << 1;
+	}
+	return length;
+}
+
+/*
+ * Look at the control requests to the root hub and see if we need to override.
+ */
+static int ohci_da8xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+				  u16 wIndex, char *buf, u16 wLength)
+{
+	struct device *dev		= hcd->self.controller;
+	struct da8xx_ohci_root_hub *hub	= dev->platform_data;
+	int temp;
+
+	switch (typeReq) {
+	case GetPortStatus:
+		/* Check the port number */
+		if (wIndex != 1)
+			break;
+
+		dev_dbg(dev, "GetPortStatus(%u)\n", wIndex);
+
+		temp = roothub_portstatus(hcd_to_ohci(hcd), wIndex - 1);
+
+		/* The port power status (PPS) bit defaults to 1 */
+		if (hub->get_power && hub->get_power(wIndex) == 0)
+			temp &= ~RH_PS_PPS;
+
+		/* The port over-current indicator (POCI) bit is always 0 */
+		if (hub->get_oci && hub->get_oci(wIndex) > 0)
+			temp |=  RH_PS_POCI;
+
+		/* The over-current indicator change (OCIC) bit is 0 too */
+		if (ocic_mask & (1 << wIndex))
+			temp |=  RH_PS_OCIC;
+
+		put_unaligned(cpu_to_le32(temp), (__le32 *)buf);
+		return 0;
+	case SetPortFeature:
+		temp = 1;
+		goto check_port;
+	case ClearPortFeature:
+		temp = 0;
+
+check_port:
+		/* Check the port number */
+		if (wIndex != 1)
+			break;
+
+		switch (wValue) {
+		case USB_PORT_FEAT_POWER:
+			dev_dbg(dev, "%sPortFeature(%u): %s\n",
+				temp ? "Set" : "Clear", wIndex, "POWER");
+
+			if (!hub->set_power)
+				return -EPIPE;
+
+			return hub->set_power(wIndex, temp) ? -EPIPE : 0;
+		case USB_PORT_FEAT_C_OVER_CURRENT:
+			dev_dbg(dev, "%sPortFeature(%u): %s\n",
+				temp ? "Set" : "Clear", wIndex,
+				"C_OVER_CURRENT");
+
+			if (temp)
+				ocic_mask |= 1 << wIndex;
+			else
+				ocic_mask &= ~(1 << wIndex);
+			return 0;
+		}
+	}
+
+	return ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+}
+
+static const struct hc_driver ohci_da8xx_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "DA8xx OHCI",
+	.hcd_priv_size		= sizeof(struct ohci_hcd),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq			= ohci_irq,
+	.flags			= HCD_USB11 | HCD_MEMORY,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	.reset			= ohci_da8xx_init,
+	.start			= ohci_da8xx_start,
+	.stop			= ohci_da8xx_stop,
+	.shutdown		= ohci_shutdown,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue		= ohci_urb_enqueue,
+	.urb_dequeue		= ohci_urb_dequeue,
+	.endpoint_disable	= ohci_endpoint_disable,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number	= ohci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data	= ohci_da8xx_hub_status_data,
+	.hub_control		= ohci_da8xx_hub_control,
+
+#ifdef	CONFIG_PM
+	.bus_suspend		= ohci_bus_suspend,
+	.bus_resume		= ohci_bus_resume,
+#endif
+	.start_port_reset	= ohci_start_port_reset,
+};
+
+/*-------------------------------------------------------------------------*/
+
+
+/**
+ * usb_hcd_da8xx_probe - initialize DA8xx-based HCDs
+ * Context: !in_interrupt()
+ *
+ * Allocates basic resources for this USB host controller, and
+ * then invokes the start() method for the HCD associated with it
+ * through the hotplug entry's driver_data.
+ */
+static int usb_hcd_da8xx_probe(const struct hc_driver *driver,
+			       struct platform_device *pdev)
+{
+	struct da8xx_ohci_root_hub *hub	= pdev->dev.platform_data;
+	struct usb_hcd	*hcd;
+	struct resource *mem;
+	int error, irq;
+
+	if (hub == NULL)
+		return -ENODEV;
+
+	usb11_clk = clk_get(&pdev->dev, "usb11");
+	if (IS_ERR(usb11_clk))
+		return PTR_ERR(usb11_clk);
+
+	usb20_clk = clk_get(&pdev->dev, "usb20");
+	if (IS_ERR(usb20_clk)) {
+		error = PTR_ERR(usb20_clk);
+		goto err0;
+	}
+
+	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+	if (!hcd) {
+		error = -ENOMEM;
+		goto err1;
+	}
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		error = -ENODEV;
+		goto err2;
+	}
+	hcd->rsrc_start = mem->start;
+	hcd->rsrc_len = mem->end - mem->start + 1;
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+		dev_dbg(&pdev->dev, "request_mem_region failed\n");
+		error = -EBUSY;
+		goto err2;
+	}
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		dev_err(&pdev->dev, "ioremap failed\n");
+		error = -ENOMEM;
+		goto err3;
+	}
+
+	ohci_hcd_init(hcd_to_ohci(hcd));
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		error = -ENODEV;
+		goto err4;
+	}
+	error = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+	if (error)
+		goto err4;
+
+	if (hub->ocic_notify) {
+		error = hub->ocic_notify(ohci_da8xx_ocic_handler);
+		if (!error)
+			return 0;
+	}
+
+	usb_remove_hcd(hcd);
+err4:
+	iounmap(hcd->regs);
+err3:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err2:
+	usb_put_hcd(hcd);
+err1:
+	clk_put(usb20_clk);
+err0:
+	clk_put(usb11_clk);
+	return error;
+}
+
+/**
+ * usb_hcd_da8xx_remove - shutdown processing for DA8xx-based HCDs
+ * @dev: USB Host Controller being removed
+ * Context: !in_interrupt()
+ *
+ * Reverses the effect of usb_hcd_da8xx_probe(), first invoking
+ * the HCD's stop() method.  It is always called from a thread
+ * context, normally "rmmod", "apmd", or something similar.
+ */
+static inline void
+usb_hcd_da8xx_remove(struct usb_hcd *hcd, struct platform_device *pdev)
+{
+	struct da8xx_ohci_root_hub *hub	= pdev->dev.platform_data;
+
+	hub->ocic_notify(NULL);
+	usb_remove_hcd(hcd);
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+	clk_put(usb20_clk);
+	clk_put(usb11_clk);
+}
+
+static int ohci_hcd_da8xx_drv_probe(struct platform_device *dev)
+{
+	return usb_hcd_da8xx_probe(&ohci_da8xx_hc_driver, dev);
+}
+
+static int ohci_hcd_da8xx_drv_remove(struct platform_device *dev)
+{
+	struct usb_hcd	*hcd = platform_get_drvdata(dev);
+
+	usb_hcd_da8xx_remove(hcd, dev);
+	platform_set_drvdata(dev, NULL);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int ohci_da8xx_suspend(struct platform_device *dev, pm_message_t message)
+{
+	struct usb_hcd	*hcd	= platform_get_drvdata(dev);
+	struct ohci_hcd	*ohci	= hcd_to_ohci(hcd);
+
+	if (time_before(jiffies, ohci->next_statechange))
+		msleep(5);
+	ohci->next_statechange = jiffies;
+
+	ohci_da8xx_clock(0);
+	hcd->state = HC_STATE_SUSPENDED;
+	dev->dev.power.power_state = PMSG_SUSPEND;
+	return 0;
+}
+
+static int ohci_da8xx_resume(struct platform_device *dev)
+{
+	struct usb_hcd	*hcd	= platform_get_drvdata(dev);
+	struct ohci_hcd	*ohci	= hcd_to_ohci(hcd);
+
+	if (time_before(jiffies, ohci->next_statechange))
+		msleep(5);
+	ohci->next_statechange = jiffies;
+
+	ohci_da8xx_clock(1);
+	dev->dev.power.power_state = PMSG_ON;
+	usb_hcd_resume_root_hub(hcd);
+	return 0;
+}
+#endif
+
+/*
+ * Driver definition to register with platform structure.
+ */
+static struct platform_driver ohci_hcd_da8xx_driver = {
+	.probe		= ohci_hcd_da8xx_drv_probe,
+	.remove		= ohci_hcd_da8xx_drv_remove,
+	.shutdown 	= usb_hcd_platform_shutdown,
+#ifdef	CONFIG_PM
+	.suspend	= ohci_da8xx_suspend,
+	.resume		= ohci_da8xx_resume,
+#endif
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= "ohci",
+	},
+};
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-dbg.c linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-dbg.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-dbg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-dbg.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,13 +53,13 @@ urb_print(struct urb * urb, char * str,
 		int i, len;
 
 		if (usb_pipecontrol (pipe)) {
-			printk (KERN_DEBUG __FILE__ ": setup(8):");
+			printk (KERN_DEBUG "%s: setup(8):", __FILE__);
 			for (i = 0; i < 8 ; i++)
 				printk (" %02x", ((__u8 *) urb->setup_packet) [i]);
 			printk ("\n");
 		}
 		if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) {
-			printk (KERN_DEBUG __FILE__ ": data(%d/%d):",
+			printk (KERN_DEBUG "%s: data(%d/%d):", __FILE__,
 				urb->actual_length,
 				urb->transfer_buffer_length);
 			len = usb_pipeout (pipe)?
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-hcd.c linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-hcd.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-hcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-hcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -1051,6 +1051,11 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		usb_hcd_pnx4008_driver
 #endif
 
+#ifdef CONFIG_ARCH_DAVINCI_DA8XX
+#include "ohci-da8xx.c"
+#define PLATFORM_DRIVER		ohci_hcd_da8xx_driver
+#endif
+
 #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
     defined(CONFIG_CPU_SUBTYPE_SH7721) || \
     defined(CONFIG_CPU_SUBTYPE_SH7763) || \
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-hub.c linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-hub.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-hub.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-hub.c	2010-05-16 17:17:36.000000000 -0400
@@ -697,7 +697,7 @@ static int ohci_hub_control (
 	u16		wLength
 ) {
 	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
-	int		ports = hcd_to_bus (hcd)->root_hub->maxchild;
+	int		ports = ohci->num_ports;
 	u32		temp;
 	int		retval = 0;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-lh7a404.c linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-lh7a404.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-lh7a404.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-lh7a404.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,8 +28,8 @@ extern int usb_disabled(void);
 
 static void lh7a404_start_hc(struct platform_device *dev)
 {
-	printk(KERN_DEBUG __FILE__
-	       ": starting LH7A404 OHCI USB Controller\n");
+	printk(KERN_DEBUG "%s: starting LH7A404 OHCI USB Controller\n",
+	       __FILE__);
 
 	/*
 	 * Now, carefully enable the USB clock, and take
@@ -39,14 +39,13 @@ static void lh7a404_start_hc(struct plat
 	udelay(1000);
 	USBH_CMDSTATUS = OHCI_HCR;
 
-	printk(KERN_DEBUG __FILE__
-		   ": Clock to USB host has been enabled \n");
+	printk(KERN_DEBUG "%s: Clock to USB host has been enabled \n", __FILE__);
 }
 
 static void lh7a404_stop_hc(struct platform_device *dev)
 {
-	printk(KERN_DEBUG __FILE__
-	       ": stopping LH7A404 OHCI USB Controller\n");
+	printk(KERN_DEBUG "%s: stopping LH7A404 OHCI USB Controller\n",
+	       __FILE__);
 
 	CSC_PWRCNT &= ~CSC_PWRCNT_USBH_EN; /* Disable clock */
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-pnx4008.c linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-pnx4008.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-pnx4008.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-pnx4008.c	2010-05-16 17:17:36.000000000 -0400
@@ -327,7 +327,7 @@ static int __devinit usb_hcd_pnx4008_pro
 	}
 	i2c_adap = i2c_get_adapter(2);
 	memset(&i2c_info, 0, sizeof(struct i2c_board_info));
-	strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE);
+	strlcpy(i2c_info.type, "isp1301_pnx", I2C_NAME_SIZE);
 	isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,
 						   normal_i2c);
 	i2c_put_adapter(i2c_adap);
@@ -411,7 +411,7 @@ out3:
 out2:
 	clk_put(usb_clk);
 out1:
-	i2c_unregister_client(isp1301_i2c_client);
+	i2c_unregister_device(isp1301_i2c_client);
 	isp1301_i2c_client = NULL;
 out_i2c_driver:
 	i2c_del_driver(&isp1301_driver);
@@ -430,7 +430,7 @@ static int usb_hcd_pnx4008_remove(struct
 	pnx4008_unset_usb_bits();
 	clk_disable(usb_clk);
 	clk_put(usb_clk);
-	i2c_unregister_client(isp1301_i2c_client);
+	i2c_unregister_device(isp1301_i2c_client);
 	isp1301_i2c_client = NULL;
 	i2c_del_driver(&isp1301_driver);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-ppc-of.c linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-ppc-of.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-ppc-of.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-ppc-of.c	2010-05-16 17:17:36.000000000 -0400
@@ -114,21 +114,21 @@ ohci_hcd_ppc_of_probe(struct of_device *
 	hcd->rsrc_len = res.end - res.start + 1;
 
 	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
-		printk(KERN_ERR __FILE__ ": request_mem_region failed\n");
+		printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__);
 		rv = -EBUSY;
 		goto err_rmr;
 	}
 
 	irq = irq_of_parse_and_map(dn, 0);
 	if (irq == NO_IRQ) {
-		printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n");
+		printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__);
 		rv = -EBUSY;
 		goto err_irq;
 	}
 
 	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
 	if (!hcd->regs) {
-		printk(KERN_ERR __FILE__ ": ioremap failed\n");
+		printk(KERN_ERR "%s: ioremap failed\n", __FILE__);
 		rv = -ENOMEM;
 		goto err_ioremap;
 	}
@@ -169,7 +169,7 @@ ohci_hcd_ppc_of_probe(struct of_device *
 			} else
 				release_mem_region(res.start, 0x4);
 		} else
-		    pr_debug(__FILE__ ": cannot get ehci offset from fdt\n");
+			pr_debug("%s: cannot get ehci offset from fdt\n", __FILE__);
 	}
 
 	iounmap(hcd->regs);
@@ -212,7 +212,7 @@ static int ohci_hcd_ppc_of_shutdown(stru
 }
 
 
-static struct of_device_id ohci_hcd_ppc_of_match[] = {
+static const struct of_device_id ohci_hcd_ppc_of_match[] = {
 #ifdef CONFIG_USB_OHCI_HCD_PPC_OF_BE
 	{
 		.name = "usb",
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-ppc-soc.c linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-ppc-soc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-ppc-soc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-ppc-soc.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,14 +41,14 @@ static int usb_hcd_ppc_soc_probe(const s
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!res) {
-		pr_debug(__FILE__ ": no irq\n");
+		pr_debug("%s: no irq\n", __FILE__);
 		return -ENODEV;
 	}
 	irq = res->start;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
-		pr_debug(__FILE__ ": no reg addr\n");
+		pr_debug("%s: no reg addr\n", __FILE__);
 		return -ENODEV;
 	}
 
@@ -59,14 +59,14 @@ static int usb_hcd_ppc_soc_probe(const s
 	hcd->rsrc_len = res->end - res->start + 1;
 
 	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
-		pr_debug(__FILE__ ": request_mem_region failed\n");
+		pr_debug("%s: request_mem_region failed\n", __FILE__);
 		retval = -EBUSY;
 		goto err1;
 	}
 
 	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
 	if (!hcd->regs) {
-		pr_debug(__FILE__ ": ioremap failed\n");
+		pr_debug("%s: ioremap failed\n", __FILE__);
 		retval = -ENOMEM;
 		goto err2;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-q.c linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-q.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-q.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-q.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  */
 
 #include <linux/irq.h>
+#include <linux/slab.h>
 
 static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-sa1111.c linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-sa1111.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/ohci-sa1111.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/ohci-sa1111.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,8 +31,8 @@ static void sa1111_start_hc(struct sa111
 {
 	unsigned int usb_rst = 0;
 
-	printk(KERN_DEBUG __FILE__
-	       ": starting SA-1111 OHCI USB Controller\n");
+	printk(KERN_DEBUG "%s: starting SA-1111 OHCI USB Controller\n",
+	       __FILE__);
 
 #ifdef CONFIG_SA1100_BADGE4
 	if (machine_is_badge4()) {
@@ -65,8 +65,8 @@ static void sa1111_start_hc(struct sa111
 static void sa1111_stop_hc(struct sa1111_dev *dev)
 {
 	unsigned int usb_rst;
-	printk(KERN_DEBUG __FILE__
-	       ": stopping SA-1111 OHCI USB Controller\n");
+	printk(KERN_DEBUG "%s: stopping SA-1111 OHCI USB Controller\n",
+	       __FILE__);
 
 	/*
 	 * Put the USB host controller into reset.
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/oxu210hp-hcd.c linux-libre-2.6.34-gnu1/drivers/usb/host/oxu210hp-hcd.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/oxu210hp-hcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/oxu210hp-hcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -660,13 +660,13 @@ static struct ehci_qh *oxu_qh_alloc(stru
 		if (qh->dummy == NULL) {
 			oxu_dbg(oxu, "no dummy td\n");
 			oxu->qh_used[i] = 0;
-
-			return NULL;
+			qh = NULL;
+			goto unlock;
 		}
 
 		oxu->qh_used[i] = 1;
 	}
-
+unlock:
 	spin_unlock(&oxu->mem_lock);
 
 	return qh;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/r8a66597-hcd.c linux-libre-2.6.34-gnu1/drivers/usb/host/r8a66597-hcd.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/r8a66597-hcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/r8a66597-hcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/io.h>
 #include <linux/mm.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <asm/cacheflush.h>
 
 #include "../core/hcd.h"
@@ -418,7 +419,7 @@ static u8 alloc_usb_address(struct r8a66
 
 /* this function must be called with interrupt disabled */
 static void free_usb_address(struct r8a66597 *r8a66597,
-			     struct r8a66597_device *dev)
+			     struct r8a66597_device *dev, int reset)
 {
 	int port;
 
@@ -430,7 +431,13 @@ static void free_usb_address(struct r8a6
 	dev->state = USB_STATE_DEFAULT;
 	r8a66597->address_map &= ~(1 << dev->address);
 	dev->address = 0;
-	dev_set_drvdata(&dev->udev->dev, NULL);
+	/*
+	 * Only when resetting USB, it is necessary to erase drvdata. When
+	 * a usb device with usb hub is disconnect, "dev->udev" is already
+	 * freed on usb_desconnect(). So we cannot access the data.
+	 */
+	if (reset)
+		dev_set_drvdata(&dev->udev->dev, NULL);
 	list_del(&dev->device_list);
 	kfree(dev);
 
@@ -1069,7 +1076,7 @@ static void r8a66597_usb_disconnect(stru
 	struct r8a66597_device *dev = r8a66597->root_hub[port].dev;
 
 	disable_r8a66597_pipe_all(r8a66597, dev);
-	free_usb_address(r8a66597, dev);
+	free_usb_address(r8a66597, dev, 0);
 
 	start_root_hub_sampling(r8a66597, port, 0);
 }
@@ -2085,7 +2092,7 @@ static void update_usb_address_map(struc
 				spin_lock_irqsave(&r8a66597->lock, flags);
 				dev = get_r8a66597_device(r8a66597, addr);
 				disable_r8a66597_pipe_all(r8a66597, dev);
-				free_usb_address(r8a66597, dev);
+				free_usb_address(r8a66597, dev, 0);
 				put_child_connect_map(r8a66597, addr);
 				spin_unlock_irqrestore(&r8a66597->lock, flags);
 			}
@@ -2228,7 +2235,7 @@ static int r8a66597_hub_control(struct u
 			rh->port |= (1 << USB_PORT_FEAT_RESET);
 
 			disable_r8a66597_pipe_all(r8a66597, dev);
-			free_usb_address(r8a66597, dev);
+			free_usb_address(r8a66597, dev, 1);
 
 			r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT,
 				      get_dvstctr_reg(port));
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/sl811-hcd.c linux-libre-2.6.34-gnu1/drivers/usb/host/sl811-hcd.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/sl811-hcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/sl811-hcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,6 +51,7 @@
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/byteorder.h>
+#include <asm/unaligned.h>
 
 #include "../core/hcd.h"
 #include "sl811.h"
@@ -719,10 +720,10 @@ retry:
 		/* port status seems weird until after reset, so
 		 * force the reset and make khubd clean up later.
 		 */
-		if (sl811->stat_insrmv & 1)
-			sl811->port1 |= 1 << USB_PORT_FEAT_CONNECTION;
-		else
+		if (irqstat & SL11H_INTMASK_RD)
 			sl811->port1 &= ~(1 << USB_PORT_FEAT_CONNECTION);
+		else
+			sl811->port1 |= 1 << USB_PORT_FEAT_CONNECTION;
 
 		sl811->port1 |= 1 << USB_PORT_FEAT_C_CONNECTION;
 
@@ -1272,12 +1273,12 @@ sl811h_hub_control(
 		sl811h_hub_descriptor(sl811, (struct usb_hub_descriptor *) buf);
 		break;
 	case GetHubStatus:
-		*(__le32 *) buf = cpu_to_le32(0);
+		put_unaligned_le32(0, buf);
 		break;
 	case GetPortStatus:
 		if (wIndex != 1)
 			goto error;
-		*(__le32 *) buf = cpu_to_le32(sl811->port1);
+		put_unaligned_le32(sl811->port1, buf);
 
 #ifndef	VERBOSE
 	if (*(u16*)(buf+2))	/* only if wPortChange is interesting */
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/uhci-debug.c linux-libre-2.6.34-gnu1/drivers/usb/host/uhci-debug.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/uhci-debug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/uhci-debug.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  * (C) Copyright 1999-2001 Johannes Erdfelt
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/debugfs.h>
 #include <linux/smp_lock.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/uhci-hcd.c linux-libre-2.6.34-gnu1/drivers/usb/host/uhci-hcd.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/uhci-hcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/uhci-hcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -735,6 +735,7 @@ static void uhci_stop(struct usb_hcd *hc
 		uhci_hc_died(uhci);
 	uhci_scan_schedule(uhci);
 	spin_unlock_irq(&uhci->lock);
+	synchronize_irq(hcd->irq);
 
 	del_timer_sync(&uhci->fsbr_timer);
 	release_uhci(uhci);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/whci/asl.c linux-libre-2.6.34-gnu1/drivers/usb/host/whci/asl.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/whci/asl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/whci/asl.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/dma-mapping.h>
 #include <linux/uwb/umc.h>
 #include <linux/usb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/whci/debug.c linux-libre-2.6.34-gnu1/drivers/usb/host/whci/debug.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/whci/debug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/whci/debug.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
  * 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/slab.h>
 #include <linux/kernel.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/whci/init.c linux-libre-2.6.34-gnu1/drivers/usb/host/whci/init.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/whci/init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/whci/init.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/dma-mapping.h>
 #include <linux/uwb/umc.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/whci/pzl.c linux-libre-2.6.34-gnu1/drivers/usb/host/whci/pzl.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/whci/pzl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/whci/pzl.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/dma-mapping.h>
 #include <linux/uwb/umc.h>
 #include <linux/usb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/whci/qset.c linux-libre-2.6.34-gnu1/drivers/usb/host/whci/qset.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/whci/qset.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/whci/qset.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <linux/uwb/umc.h>
 #include <linux/usb.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/xhci.c linux-libre-2.6.34-gnu1/drivers/usb/host/xhci.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/xhci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/xhci.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1918 @@
+/*
+ * xHCI host controller driver
+ *
+ * Copyright (C) 2008 Intel Corp.
+ *
+ * Author: Sarah Sharp
+ * Some code borrowed from the Linux EHCI driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+
+#include "xhci.h"
+
+#define DRIVER_AUTHOR "Sarah Sharp"
+#define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
+
+/* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */
+static int link_quirk;
+module_param(link_quirk, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB");
+
+/* TODO: copied from ehci-hcd.c - can this be refactored? */
+/*
+ * handshake - spin reading hc until handshake completes or fails
+ * @ptr: address of hc register to be read
+ * @mask: bits to look at in result of read
+ * @done: value of those bits when handshake succeeds
+ * @usec: timeout in microseconds
+ *
+ * Returns negative errno, or zero on success
+ *
+ * Success happens when the "mask" bits have the specified value (hardware
+ * handshake done).  There are two failure modes:  "usec" have passed (major
+ * hardware flakeout), or the register reads as all-ones (hardware removed).
+ */
+static int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
+		      u32 mask, u32 done, int usec)
+{
+	u32	result;
+
+	do {
+		result = xhci_readl(xhci, ptr);
+		if (result == ~(u32)0)		/* card removed */
+			return -ENODEV;
+		result &= mask;
+		if (result == done)
+			return 0;
+		udelay(1);
+		usec--;
+	} while (usec > 0);
+	return -ETIMEDOUT;
+}
+
+/*
+ * Disable interrupts and begin the xHCI halting process.
+ */
+void xhci_quiesce(struct xhci_hcd *xhci)
+{
+	u32 halted;
+	u32 cmd;
+	u32 mask;
+
+	mask = ~(XHCI_IRQS);
+	halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT;
+	if (!halted)
+		mask &= ~CMD_RUN;
+
+	cmd = xhci_readl(xhci, &xhci->op_regs->command);
+	cmd &= mask;
+	xhci_writel(xhci, cmd, &xhci->op_regs->command);
+}
+
+/*
+ * Force HC into halt state.
+ *
+ * Disable any IRQs and clear the run/stop bit.
+ * HC will complete any current and actively pipelined transactions, and
+ * should halt within 16 microframes of the run/stop bit being cleared.
+ * Read HC Halted bit in the status register to see when the HC is finished.
+ * XXX: shouldn't we set HC_STATE_HALT here somewhere?
+ */
+int xhci_halt(struct xhci_hcd *xhci)
+{
+	xhci_dbg(xhci, "// Halt the HC\n");
+	xhci_quiesce(xhci);
+
+	return handshake(xhci, &xhci->op_regs->status,
+			STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
+}
+
+/*
+ * Reset a halted HC, and set the internal HC state to HC_STATE_HALT.
+ *
+ * This resets pipelines, timers, counters, state machines, etc.
+ * Transactions will be terminated immediately, and operational registers
+ * will be set to their defaults.
+ */
+int xhci_reset(struct xhci_hcd *xhci)
+{
+	u32 command;
+	u32 state;
+
+	state = xhci_readl(xhci, &xhci->op_regs->status);
+	if ((state & STS_HALT) == 0) {
+		xhci_warn(xhci, "Host controller not halted, aborting reset.\n");
+		return 0;
+	}
+
+	xhci_dbg(xhci, "// Reset the HC\n");
+	command = xhci_readl(xhci, &xhci->op_regs->command);
+	command |= CMD_RESET;
+	xhci_writel(xhci, command, &xhci->op_regs->command);
+	/* XXX: Why does EHCI set this here?  Shouldn't other code do this? */
+	xhci_to_hcd(xhci)->state = HC_STATE_HALT;
+
+	return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000);
+}
+
+
+#if 0
+/* Set up MSI-X table for entry 0 (may claim other entries later) */
+static int xhci_setup_msix(struct xhci_hcd *xhci)
+{
+	int ret;
+	struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+
+	xhci->msix_count = 0;
+	/* XXX: did I do this right?  ixgbe does kcalloc for more than one */
+	xhci->msix_entries = kmalloc(sizeof(struct msix_entry), GFP_KERNEL);
+	if (!xhci->msix_entries) {
+		xhci_err(xhci, "Failed to allocate MSI-X entries\n");
+		return -ENOMEM;
+	}
+	xhci->msix_entries[0].entry = 0;
+
+	ret = pci_enable_msix(pdev, xhci->msix_entries, xhci->msix_count);
+	if (ret) {
+		xhci_err(xhci, "Failed to enable MSI-X\n");
+		goto free_entries;
+	}
+
+	/*
+	 * Pass the xhci pointer value as the request_irq "cookie".
+	 * If more irqs are added, this will need to be unique for each one.
+	 */
+	ret = request_irq(xhci->msix_entries[0].vector, &xhci_irq, 0,
+			"xHCI", xhci_to_hcd(xhci));
+	if (ret) {
+		xhci_err(xhci, "Failed to allocate MSI-X interrupt\n");
+		goto disable_msix;
+	}
+	xhci_dbg(xhci, "Finished setting up MSI-X\n");
+	return 0;
+
+disable_msix:
+	pci_disable_msix(pdev);
+free_entries:
+	kfree(xhci->msix_entries);
+	xhci->msix_entries = NULL;
+	return ret;
+}
+
+/* XXX: code duplication; can xhci_setup_msix call this? */
+/* Free any IRQs and disable MSI-X */
+static void xhci_cleanup_msix(struct xhci_hcd *xhci)
+{
+	struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+	if (!xhci->msix_entries)
+		return;
+
+	free_irq(xhci->msix_entries[0].vector, xhci);
+	pci_disable_msix(pdev);
+	kfree(xhci->msix_entries);
+	xhci->msix_entries = NULL;
+	xhci_dbg(xhci, "Finished cleaning up MSI-X\n");
+}
+#endif
+
+/*
+ * Initialize memory for HCD and xHC (one-time init).
+ *
+ * Program the PAGESIZE register, initialize the device context array, create
+ * device contexts (?), set up a command ring segment (or two?), create event
+ * ring (one for now).
+ */
+int xhci_init(struct usb_hcd *hcd)
+{
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+	int retval = 0;
+
+	xhci_dbg(xhci, "xhci_init\n");
+	spin_lock_init(&xhci->lock);
+	if (link_quirk) {
+		xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n");
+		xhci->quirks |= XHCI_LINK_TRB_QUIRK;
+	} else {
+		xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n");
+	}
+	retval = xhci_mem_init(xhci, GFP_KERNEL);
+	xhci_dbg(xhci, "Finished xhci_init\n");
+
+	return retval;
+}
+
+/*
+ * Called in interrupt context when there might be work
+ * queued on the event ring
+ *
+ * xhci->lock must be held by caller.
+ */
+static void xhci_work(struct xhci_hcd *xhci)
+{
+	u32 temp;
+	u64 temp_64;
+
+	/*
+	 * Clear the op reg interrupt status first,
+	 * so we can receive interrupts from other MSI-X interrupters.
+	 * Write 1 to clear the interrupt status.
+	 */
+	temp = xhci_readl(xhci, &xhci->op_regs->status);
+	temp |= STS_EINT;
+	xhci_writel(xhci, temp, &xhci->op_regs->status);
+	/* FIXME when MSI-X is supported and there are multiple vectors */
+	/* Clear the MSI-X event interrupt status */
+
+	/* Acknowledge the interrupt */
+	temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
+	temp |= 0x3;
+	xhci_writel(xhci, temp, &xhci->ir_set->irq_pending);
+	/* Flush posted writes */
+	xhci_readl(xhci, &xhci->ir_set->irq_pending);
+
+	if (xhci->xhc_state & XHCI_STATE_DYING)
+		xhci_dbg(xhci, "xHCI dying, ignoring interrupt. "
+				"Shouldn't IRQs be disabled?\n");
+	else
+		/* FIXME this should be a delayed service routine
+		 * that clears the EHB.
+		 */
+		xhci_handle_event(xhci);
+
+	/* Clear the event handler busy flag (RW1C); the event ring should be empty. */
+	temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
+	xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue);
+	/* Flush posted writes -- FIXME is this necessary? */
+	xhci_readl(xhci, &xhci->ir_set->irq_pending);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * xHCI spec says we can get an interrupt, and if the HC has an error condition,
+ * we might get bad data out of the event ring.  Section 4.10.2.7 has a list of
+ * indicators of an event TRB error, but we check the status *first* to be safe.
+ */
+irqreturn_t xhci_irq(struct usb_hcd *hcd)
+{
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+	u32 temp, temp2;
+	union xhci_trb *trb;
+
+	spin_lock(&xhci->lock);
+	trb = xhci->event_ring->dequeue;
+	/* Check if the xHC generated the interrupt, or the irq is shared */
+	temp = xhci_readl(xhci, &xhci->op_regs->status);
+	temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending);
+	if (temp == 0xffffffff && temp2 == 0xffffffff)
+		goto hw_died;
+
+	if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) {
+		spin_unlock(&xhci->lock);
+		return IRQ_NONE;
+	}
+	xhci_dbg(xhci, "op reg status = %08x\n", temp);
+	xhci_dbg(xhci, "ir set irq_pending = %08x\n", temp2);
+	xhci_dbg(xhci, "Event ring dequeue ptr:\n");
+	xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n",
+			(unsigned long long)xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, trb),
+			lower_32_bits(trb->link.segment_ptr),
+			upper_32_bits(trb->link.segment_ptr),
+			(unsigned int) trb->link.intr_target,
+			(unsigned int) trb->link.control);
+
+	if (temp & STS_FATAL) {
+		xhci_warn(xhci, "WARNING: Host System Error\n");
+		xhci_halt(xhci);
+hw_died:
+		xhci_to_hcd(xhci)->state = HC_STATE_HALT;
+		spin_unlock(&xhci->lock);
+		return -ESHUTDOWN;
+	}
+
+	xhci_work(xhci);
+	spin_unlock(&xhci->lock);
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
+void xhci_event_ring_work(unsigned long arg)
+{
+	unsigned long flags;
+	int temp;
+	u64 temp_64;
+	struct xhci_hcd *xhci = (struct xhci_hcd *) arg;
+	int i, j;
+
+	xhci_dbg(xhci, "Poll event ring: %lu\n", jiffies);
+
+	spin_lock_irqsave(&xhci->lock, flags);
+	temp = xhci_readl(xhci, &xhci->op_regs->status);
+	xhci_dbg(xhci, "op reg status = 0x%x\n", temp);
+	if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) {
+		xhci_dbg(xhci, "HW died, polling stopped.\n");
+		spin_unlock_irqrestore(&xhci->lock, flags);
+		return;
+	}
+
+	temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
+	xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp);
+	xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled);
+	xhci_dbg(xhci, "HC error bitmask = 0x%x\n", xhci->error_bitmask);
+	xhci->error_bitmask = 0;
+	xhci_dbg(xhci, "Event ring:\n");
+	xhci_debug_segment(xhci, xhci->event_ring->deq_seg);
+	xhci_dbg_ring_ptrs(xhci, xhci->event_ring);
+	temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
+	temp_64 &= ~ERST_PTR_MASK;
+	xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64);
+	xhci_dbg(xhci, "Command ring:\n");
+	xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg);
+	xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
+	xhci_dbg_cmd_ptrs(xhci);
+	for (i = 0; i < MAX_HC_SLOTS; ++i) {
+		if (!xhci->devs[i])
+			continue;
+		for (j = 0; j < 31; ++j) {
+			struct xhci_ring *ring = xhci->devs[i]->eps[j].ring;
+			if (!ring)
+				continue;
+			xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j);
+			xhci_debug_segment(xhci, ring->deq_seg);
+		}
+	}
+
+	if (xhci->noops_submitted != NUM_TEST_NOOPS)
+		if (xhci_setup_one_noop(xhci))
+			xhci_ring_cmd_db(xhci);
+	spin_unlock_irqrestore(&xhci->lock, flags);
+
+	if (!xhci->zombie)
+		mod_timer(&xhci->event_ring_timer, jiffies + POLL_TIMEOUT * HZ);
+	else
+		xhci_dbg(xhci, "Quit polling the event ring.\n");
+}
+#endif
+
+/*
+ * Start the HC after it was halted.
+ *
+ * This function is called by the USB core when the HC driver is added.
+ * Its opposite is xhci_stop().
+ *
+ * xhci_init() must be called once before this function can be called.
+ * Reset the HC, enable device slot contexts, program DCBAAP, and
+ * set command ring pointer and event ring pointer.
+ *
+ * Setup MSI-X vectors and enable interrupts.
+ */
+int xhci_run(struct usb_hcd *hcd)
+{
+	u32 temp;
+	u64 temp_64;
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+	void (*doorbell)(struct xhci_hcd *) = NULL;
+
+	hcd->uses_new_polling = 1;
+	hcd->poll_rh = 0;
+
+	xhci_dbg(xhci, "xhci_run\n");
+#if 0	/* FIXME: MSI not setup yet */
+	/* Do this at the very last minute */
+	ret = xhci_setup_msix(xhci);
+	if (!ret)
+		return ret;
+
+	return -ENOSYS;
+#endif
+#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
+	init_timer(&xhci->event_ring_timer);
+	xhci->event_ring_timer.data = (unsigned long) xhci;
+	xhci->event_ring_timer.function = xhci_event_ring_work;
+	/* Poll the event ring */
+	xhci->event_ring_timer.expires = jiffies + POLL_TIMEOUT * HZ;
+	xhci->zombie = 0;
+	xhci_dbg(xhci, "Setting event ring polling timer\n");
+	add_timer(&xhci->event_ring_timer);
+#endif
+
+	xhci_dbg(xhci, "Command ring memory map follows:\n");
+	xhci_debug_ring(xhci, xhci->cmd_ring);
+	xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
+	xhci_dbg_cmd_ptrs(xhci);
+
+	xhci_dbg(xhci, "ERST memory map follows:\n");
+	xhci_dbg_erst(xhci, &xhci->erst);
+	xhci_dbg(xhci, "Event ring:\n");
+	xhci_debug_ring(xhci, xhci->event_ring);
+	xhci_dbg_ring_ptrs(xhci, xhci->event_ring);
+	temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
+	temp_64 &= ~ERST_PTR_MASK;
+	xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64);
+
+	xhci_dbg(xhci, "// Set the interrupt modulation register\n");
+	temp = xhci_readl(xhci, &xhci->ir_set->irq_control);
+	temp &= ~ER_IRQ_INTERVAL_MASK;
+	temp |= (u32) 160;
+	xhci_writel(xhci, temp, &xhci->ir_set->irq_control);
+
+	/* Set the HCD state before we enable the irqs */
+	hcd->state = HC_STATE_RUNNING;
+	temp = xhci_readl(xhci, &xhci->op_regs->command);
+	temp |= (CMD_EIE);
+	xhci_dbg(xhci, "// Enable interrupts, cmd = 0x%x.\n",
+			temp);
+	xhci_writel(xhci, temp, &xhci->op_regs->command);
+
+	temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
+	xhci_dbg(xhci, "// Enabling event ring interrupter %p by writing 0x%x to irq_pending\n",
+			xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp));
+	xhci_writel(xhci, ER_IRQ_ENABLE(temp),
+			&xhci->ir_set->irq_pending);
+	xhci_print_ir_set(xhci, xhci->ir_set, 0);
+
+	if (NUM_TEST_NOOPS > 0)
+		doorbell = xhci_setup_one_noop(xhci);
+
+	temp = xhci_readl(xhci, &xhci->op_regs->command);
+	temp |= (CMD_RUN);
+	xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n",
+			temp);
+	xhci_writel(xhci, temp, &xhci->op_regs->command);
+	/* Flush PCI posted writes */
+	temp = xhci_readl(xhci, &xhci->op_regs->command);
+	xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp);
+	if (doorbell)
+		(*doorbell)(xhci);
+
+	xhci_dbg(xhci, "Finished xhci_run\n");
+	return 0;
+}
+
+/*
+ * Stop xHCI driver.
+ *
+ * This function is called by the USB core when the HC driver is removed.
+ * Its opposite is xhci_run().
+ *
+ * Disable device contexts, disable IRQs, and quiesce the HC.
+ * Reset the HC, finish any completed transactions, and cleanup memory.
+ */
+void xhci_stop(struct usb_hcd *hcd)
+{
+	u32 temp;
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+
+	spin_lock_irq(&xhci->lock);
+	xhci_halt(xhci);
+	xhci_reset(xhci);
+	spin_unlock_irq(&xhci->lock);
+
+#if 0	/* No MSI yet */
+	xhci_cleanup_msix(xhci);
+#endif
+#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
+	/* Tell the event ring poll function not to reschedule */
+	xhci->zombie = 1;
+	del_timer_sync(&xhci->event_ring_timer);
+#endif
+
+	xhci_dbg(xhci, "// Disabling event ring interrupts\n");
+	temp = xhci_readl(xhci, &xhci->op_regs->status);
+	xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status);
+	temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
+	xhci_writel(xhci, ER_IRQ_DISABLE(temp),
+			&xhci->ir_set->irq_pending);
+	xhci_print_ir_set(xhci, xhci->ir_set, 0);
+
+	xhci_dbg(xhci, "cleaning up memory\n");
+	xhci_mem_cleanup(xhci);
+	xhci_dbg(xhci, "xhci_stop completed - status = %x\n",
+		    xhci_readl(xhci, &xhci->op_regs->status));
+}
+
+/*
+ * Shutdown HC (not bus-specific)
+ *
+ * This is called when the machine is rebooting or halting.  We assume that the
+ * machine will be powered off, and the HC's internal state will be reset.
+ * Don't bother to free memory.
+ */
+void xhci_shutdown(struct usb_hcd *hcd)
+{
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+
+	spin_lock_irq(&xhci->lock);
+	xhci_halt(xhci);
+	spin_unlock_irq(&xhci->lock);
+
+#if 0
+	xhci_cleanup_msix(xhci);
+#endif
+
+	xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n",
+		    xhci_readl(xhci, &xhci->op_regs->status));
+}
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and
+ * HCDs.  Find the index for an endpoint given its descriptor.  Use the return
+ * value to right shift 1 for the bitmask.
+ *
+ * Index  = (epnum * 2) + direction - 1,
+ * where direction = 0 for OUT, 1 for IN.
+ * For control endpoints, the IN index is used (OUT index is unused), so
+ * index = (epnum * 2) + direction - 1 = (epnum * 2) + 1 - 1 = (epnum * 2)
+ */
+unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc)
+{
+	unsigned int index;
+	if (usb_endpoint_xfer_control(desc))
+		index = (unsigned int) (usb_endpoint_num(desc)*2);
+	else
+		index = (unsigned int) (usb_endpoint_num(desc)*2) +
+			(usb_endpoint_dir_in(desc) ? 1 : 0) - 1;
+	return index;
+}
+
+/* Find the flag for this endpoint (for use in the control context).  Use the
+ * endpoint index to create a bitmask.  The slot context is bit 0, endpoint 0 is
+ * bit 1, etc.
+ */
+unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc)
+{
+	return 1 << (xhci_get_endpoint_index(desc) + 1);
+}
+
+/* Find the flag for this endpoint (for use in the control context).  Use the
+ * endpoint index to create a bitmask.  The slot context is bit 0, endpoint 0 is
+ * bit 1, etc.
+ */
+unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index)
+{
+	return 1 << (ep_index + 1);
+}
+
+/* Compute the last valid endpoint context index.  Basically, this is the
+ * endpoint index plus one.  For slot contexts with more than valid endpoint,
+ * we find the most significant bit set in the added contexts flags.
+ * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000
+ * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one.
+ */
+unsigned int xhci_last_valid_endpoint(u32 added_ctxs)
+{
+	return fls(added_ctxs) - 1;
+}
+
+/* Returns 1 if the arguments are OK;
+ * returns 0 this is a root hub; returns -EINVAL for NULL pointers.
+ */
+int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev,
+		struct usb_host_endpoint *ep, int check_ep, const char *func) {
+	if (!hcd || (check_ep && !ep) || !udev) {
+		printk(KERN_DEBUG "xHCI %s called with invalid args\n",
+				func);
+		return -EINVAL;
+	}
+	if (!udev->parent) {
+		printk(KERN_DEBUG "xHCI %s called for root hub\n",
+				func);
+		return 0;
+	}
+	if (!udev->slot_id) {
+		printk(KERN_DEBUG "xHCI %s called with unaddressed device\n",
+				func);
+		return -EINVAL;
+	}
+	return 1;
+}
+
+static int xhci_configure_endpoint(struct xhci_hcd *xhci,
+		struct usb_device *udev, struct xhci_command *command,
+		bool ctx_change, bool must_succeed);
+
+/*
+ * Full speed devices may have a max packet size greater than 8 bytes, but the
+ * USB core doesn't know that until it reads the first 8 bytes of the
+ * descriptor.  If the usb_device's max packet size changes after that point,
+ * we need to issue an evaluate context command and wait on it.
+ */
+static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,
+		unsigned int ep_index, struct urb *urb)
+{
+	struct xhci_container_ctx *in_ctx;
+	struct xhci_container_ctx *out_ctx;
+	struct xhci_input_control_ctx *ctrl_ctx;
+	struct xhci_ep_ctx *ep_ctx;
+	int max_packet_size;
+	int hw_max_packet_size;
+	int ret = 0;
+
+	out_ctx = xhci->devs[slot_id]->out_ctx;
+	ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
+	hw_max_packet_size = MAX_PACKET_DECODED(ep_ctx->ep_info2);
+	max_packet_size = urb->dev->ep0.desc.wMaxPacketSize;
+	if (hw_max_packet_size != max_packet_size) {
+		xhci_dbg(xhci, "Max Packet Size for ep 0 changed.\n");
+		xhci_dbg(xhci, "Max packet size in usb_device = %d\n",
+				max_packet_size);
+		xhci_dbg(xhci, "Max packet size in xHCI HW = %d\n",
+				hw_max_packet_size);
+		xhci_dbg(xhci, "Issuing evaluate context command.\n");
+
+		/* Set up the modified control endpoint 0 */
+		xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx,
+				xhci->devs[slot_id]->out_ctx, ep_index);
+		in_ctx = xhci->devs[slot_id]->in_ctx;
+		ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index);
+		ep_ctx->ep_info2 &= ~MAX_PACKET_MASK;
+		ep_ctx->ep_info2 |= MAX_PACKET(max_packet_size);
+
+		/* Set up the input context flags for the command */
+		/* FIXME: This won't work if a non-default control endpoint
+		 * changes max packet sizes.
+		 */
+		ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
+		ctrl_ctx->add_flags = EP0_FLAG;
+		ctrl_ctx->drop_flags = 0;
+
+		xhci_dbg(xhci, "Slot %d input context\n", slot_id);
+		xhci_dbg_ctx(xhci, in_ctx, ep_index);
+		xhci_dbg(xhci, "Slot %d output context\n", slot_id);
+		xhci_dbg_ctx(xhci, out_ctx, ep_index);
+
+		ret = xhci_configure_endpoint(xhci, urb->dev, NULL,
+				true, false);
+
+		/* Clean up the input context for later use by bandwidth
+		 * functions.
+		 */
+		ctrl_ctx->add_flags = SLOT_FLAG;
+	}
+	return ret;
+}
+
+/*
+ * non-error returns are a promise to giveback() the urb later
+ * we drop ownership so next owner (or urb unlink) can get it
+ */
+int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
+{
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+	unsigned long flags;
+	int ret = 0;
+	unsigned int slot_id, ep_index;
+
+
+	if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0)
+		return -EINVAL;
+
+	slot_id = urb->dev->slot_id;
+	ep_index = xhci_get_endpoint_index(&urb->ep->desc);
+
+	if (!xhci->devs || !xhci->devs[slot_id]) {
+		if (!in_interrupt())
+			dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n");
+		ret = -EINVAL;
+		goto exit;
+	}
+	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
+		if (!in_interrupt())
+			xhci_dbg(xhci, "urb submitted during PCI suspend\n");
+		ret = -ESHUTDOWN;
+		goto exit;
+	}
+	if (usb_endpoint_xfer_control(&urb->ep->desc)) {
+		/* Check to see if the max packet size for the default control
+		 * endpoint changed during FS device enumeration
+		 */
+		if (urb->dev->speed == USB_SPEED_FULL) {
+			ret = xhci_check_maxpacket(xhci, slot_id,
+					ep_index, urb);
+			if (ret < 0)
+				return ret;
+		}
+
+		/* We have a spinlock and interrupts disabled, so we must pass
+		 * atomic context to this function, which may allocate memory.
+		 */
+		spin_lock_irqsave(&xhci->lock, flags);
+		if (xhci->xhc_state & XHCI_STATE_DYING)
+			goto dying;
+		ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
+				slot_id, ep_index);
+		spin_unlock_irqrestore(&xhci->lock, flags);
+	} else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) {
+		spin_lock_irqsave(&xhci->lock, flags);
+		if (xhci->xhc_state & XHCI_STATE_DYING)
+			goto dying;
+		ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
+				slot_id, ep_index);
+		spin_unlock_irqrestore(&xhci->lock, flags);
+	} else if (usb_endpoint_xfer_int(&urb->ep->desc)) {
+		spin_lock_irqsave(&xhci->lock, flags);
+		if (xhci->xhc_state & XHCI_STATE_DYING)
+			goto dying;
+		ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb,
+				slot_id, ep_index);
+		spin_unlock_irqrestore(&xhci->lock, flags);
+	} else {
+		ret = -EINVAL;
+	}
+exit:
+	return ret;
+dying:
+	xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for "
+			"non-responsive xHCI host.\n",
+			urb->ep->desc.bEndpointAddress, urb);
+	spin_unlock_irqrestore(&xhci->lock, flags);
+	return -ESHUTDOWN;
+}
+
+/*
+ * Remove the URB's TD from the endpoint ring.  This may cause the HC to stop
+ * USB transfers, potentially stopping in the middle of a TRB buffer.  The HC
+ * should pick up where it left off in the TD, unless a Set Transfer Ring
+ * Dequeue Pointer is issued.
+ *
+ * The TRBs that make up the buffers for the canceled URB will be "removed" from
+ * the ring.  Since the ring is a contiguous structure, they can't be physically
+ * removed.  Instead, there are two options:
+ *
+ *  1) If the HC is in the middle of processing the URB to be canceled, we
+ *     simply move the ring's dequeue pointer past those TRBs using the Set
+ *     Transfer Ring Dequeue Pointer command.  This will be the common case,
+ *     when drivers timeout on the last submitted URB and attempt to cancel.
+ *
+ *  2) If the HC is in the middle of a different TD, we turn the TRBs into a
+ *     series of 1-TRB transfer no-op TDs.  (No-ops shouldn't be chained.)  The
+ *     HC will need to invalidate the any TRBs it has cached after the stop
+ *     endpoint command, as noted in the xHCI 0.95 errata.
+ *
+ *  3) The TD may have completed by the time the Stop Endpoint Command
+ *     completes, so software needs to handle that case too.
+ *
+ * This function should protect against the TD enqueueing code ringing the
+ * doorbell while this code is waiting for a Stop Endpoint command to complete.
+ * It also needs to account for multiple cancellations on happening at the same
+ * time for the same endpoint.
+ *
+ * Note that this function can be called in any context, or so says
+ * usb_hcd_unlink_urb()
+ */
+int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+{
+	unsigned long flags;
+	int ret;
+	u32 temp;
+	struct xhci_hcd *xhci;
+	struct xhci_td *td;
+	unsigned int ep_index;
+	struct xhci_ring *ep_ring;
+	struct xhci_virt_ep *ep;
+
+	xhci = hcd_to_xhci(hcd);
+	spin_lock_irqsave(&xhci->lock, flags);
+	/* Make sure the URB hasn't completed or been unlinked already */
+	ret = usb_hcd_check_unlink_urb(hcd, urb, status);
+	if (ret || !urb->hcpriv)
+		goto done;
+	temp = xhci_readl(xhci, &xhci->op_regs->status);
+	if (temp == 0xffffffff) {
+		xhci_dbg(xhci, "HW died, freeing TD.\n");
+		td = (struct xhci_td *) urb->hcpriv;
+
+		usb_hcd_unlink_urb_from_ep(hcd, urb);
+		spin_unlock_irqrestore(&xhci->lock, flags);
+		usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN);
+		kfree(td);
+		return ret;
+	}
+	if (xhci->xhc_state & XHCI_STATE_DYING) {
+		xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on "
+				"non-responsive xHCI host.\n",
+				urb->ep->desc.bEndpointAddress, urb);
+		/* Let the stop endpoint command watchdog timer (which set this
+		 * state) finish cleaning up the endpoint TD lists.  We must
+		 * have caught it in the middle of dropping a lock and giving
+		 * back an URB.
+		 */
+		goto done;
+	}
+
+	xhci_dbg(xhci, "Cancel URB %p\n", urb);
+	xhci_dbg(xhci, "Event ring:\n");
+	xhci_debug_ring(xhci, xhci->event_ring);
+	ep_index = xhci_get_endpoint_index(&urb->ep->desc);
+	ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index];
+	ep_ring = ep->ring;
+	xhci_dbg(xhci, "Endpoint ring:\n");
+	xhci_debug_ring(xhci, ep_ring);
+	td = (struct xhci_td *) urb->hcpriv;
+
+	list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list);
+	/* Queue a stop endpoint command, but only if this is
+	 * the first cancellation to be handled.
+	 */
+	if (!(ep->ep_state & EP_HALT_PENDING)) {
+		ep->ep_state |= EP_HALT_PENDING;
+		ep->stop_cmds_pending++;
+		ep->stop_cmd_timer.expires = jiffies +
+			XHCI_STOP_EP_CMD_TIMEOUT * HZ;
+		add_timer(&ep->stop_cmd_timer);
+		xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index);
+		xhci_ring_cmd_db(xhci);
+	}
+done:
+	spin_unlock_irqrestore(&xhci->lock, flags);
+	return ret;
+}
+
+/* Drop an endpoint from a new bandwidth configuration for this device.
+ * Only one call to this function is allowed per endpoint before
+ * check_bandwidth() or reset_bandwidth() must be called.
+ * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will
+ * add the endpoint to the schedule with possibly new parameters denoted by a
+ * different endpoint descriptor in usb_host_endpoint.
+ * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is
+ * not allowed.
+ *
+ * The USB core will not allow URBs to be queued to an endpoint that is being
+ * disabled, so there's no need for mutual exclusion to protect
+ * the xhci->devs[slot_id] structure.
+ */
+int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
+		struct usb_host_endpoint *ep)
+{
+	struct xhci_hcd *xhci;
+	struct xhci_container_ctx *in_ctx, *out_ctx;
+	struct xhci_input_control_ctx *ctrl_ctx;
+	struct xhci_slot_ctx *slot_ctx;
+	unsigned int last_ctx;
+	unsigned int ep_index;
+	struct xhci_ep_ctx *ep_ctx;
+	u32 drop_flag;
+	u32 new_add_flags, new_drop_flags, new_slot_info;
+	int ret;
+
+	ret = xhci_check_args(hcd, udev, ep, 1, __func__);
+	if (ret <= 0)
+		return ret;
+	xhci = hcd_to_xhci(hcd);
+	xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
+
+	drop_flag = xhci_get_endpoint_flag(&ep->desc);
+	if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) {
+		xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n",
+				__func__, drop_flag);
+		return 0;
+	}
+
+	if (!xhci->devs || !xhci->devs[udev->slot_id]) {
+		xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	in_ctx = xhci->devs[udev->slot_id]->in_ctx;
+	out_ctx = xhci->devs[udev->slot_id]->out_ctx;
+	ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
+	ep_index = xhci_get_endpoint_index(&ep->desc);
+	ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
+	/* If the HC already knows the endpoint is disabled,
+	 * or the HCD has noted it is disabled, ignore this request
+	 */
+	if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED ||
+			ctrl_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) {
+		xhci_warn(xhci, "xHCI %s called with disabled ep %p\n",
+				__func__, ep);
+		return 0;
+	}
+
+	ctrl_ctx->drop_flags |= drop_flag;
+	new_drop_flags = ctrl_ctx->drop_flags;
+
+	ctrl_ctx->add_flags &= ~drop_flag;
+	new_add_flags = ctrl_ctx->add_flags;
+
+	last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags);
+	slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
+	/* Update the last valid endpoint context, if we deleted the last one */
+	if ((slot_ctx->dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) {
+		slot_ctx->dev_info &= ~LAST_CTX_MASK;
+		slot_ctx->dev_info |= LAST_CTX(last_ctx);
+	}
+	new_slot_info = slot_ctx->dev_info;
+
+	xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep);
+
+	xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n",
+			(unsigned int) ep->desc.bEndpointAddress,
+			udev->slot_id,
+			(unsigned int) new_drop_flags,
+			(unsigned int) new_add_flags,
+			(unsigned int) new_slot_info);
+	return 0;
+}
+
+/* Add an endpoint to a new possible bandwidth configuration for this device.
+ * Only one call to this function is allowed per endpoint before
+ * check_bandwidth() or reset_bandwidth() must be called.
+ * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will
+ * add the endpoint to the schedule with possibly new parameters denoted by a
+ * different endpoint descriptor in usb_host_endpoint.
+ * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is
+ * not allowed.
+ *
+ * The USB core will not allow URBs to be queued to an endpoint until the
+ * configuration or alt setting is installed in the device, so there's no need
+ * for mutual exclusion to protect the xhci->devs[slot_id] structure.
+ */
+int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
+		struct usb_host_endpoint *ep)
+{
+	struct xhci_hcd *xhci;
+	struct xhci_container_ctx *in_ctx, *out_ctx;
+	unsigned int ep_index;
+	struct xhci_ep_ctx *ep_ctx;
+	struct xhci_slot_ctx *slot_ctx;
+	struct xhci_input_control_ctx *ctrl_ctx;
+	u32 added_ctxs;
+	unsigned int last_ctx;
+	u32 new_add_flags, new_drop_flags, new_slot_info;
+	int ret = 0;
+
+	ret = xhci_check_args(hcd, udev, ep, 1, __func__);
+	if (ret <= 0) {
+		/* So we won't queue a reset ep command for a root hub */
+		ep->hcpriv = NULL;
+		return ret;
+	}
+	xhci = hcd_to_xhci(hcd);
+
+	added_ctxs = xhci_get_endpoint_flag(&ep->desc);
+	last_ctx = xhci_last_valid_endpoint(added_ctxs);
+	if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) {
+		/* FIXME when we have to issue an evaluate endpoint command to
+		 * deal with ep0 max packet size changing once we get the
+		 * descriptors
+		 */
+		xhci_dbg(xhci, "xHCI %s - can't add slot or ep 0 %#x\n",
+				__func__, added_ctxs);
+		return 0;
+	}
+
+	if (!xhci->devs || !xhci->devs[udev->slot_id]) {
+		xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	in_ctx = xhci->devs[udev->slot_id]->in_ctx;
+	out_ctx = xhci->devs[udev->slot_id]->out_ctx;
+	ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
+	ep_index = xhci_get_endpoint_index(&ep->desc);
+	ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
+	/* If the HCD has already noted the endpoint is enabled,
+	 * ignore this request.
+	 */
+	if (ctrl_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) {
+		xhci_warn(xhci, "xHCI %s called with enabled ep %p\n",
+				__func__, ep);
+		return 0;
+	}
+
+	/*
+	 * Configuration and alternate setting changes must be done in
+	 * process context, not interrupt context (or so documenation
+	 * for usb_set_interface() and usb_set_configuration() claim).
+	 */
+	if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id],
+				udev, ep, GFP_NOIO) < 0) {
+		dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n",
+				__func__, ep->desc.bEndpointAddress);
+		return -ENOMEM;
+	}
+
+	ctrl_ctx->add_flags |= added_ctxs;
+	new_add_flags = ctrl_ctx->add_flags;
+
+	/* If xhci_endpoint_disable() was called for this endpoint, but the
+	 * xHC hasn't been notified yet through the check_bandwidth() call,
+	 * this re-adds a new state for the endpoint from the new endpoint
+	 * descriptors.  We must drop and re-add this endpoint, so we leave the
+	 * drop flags alone.
+	 */
+	new_drop_flags = ctrl_ctx->drop_flags;
+
+	slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
+	/* Update the last valid endpoint context, if we just added one past */
+	if ((slot_ctx->dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) {
+		slot_ctx->dev_info &= ~LAST_CTX_MASK;
+		slot_ctx->dev_info |= LAST_CTX(last_ctx);
+	}
+	new_slot_info = slot_ctx->dev_info;
+
+	/* Store the usb_device pointer for later use */
+	ep->hcpriv = udev;
+
+	xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n",
+			(unsigned int) ep->desc.bEndpointAddress,
+			udev->slot_id,
+			(unsigned int) new_drop_flags,
+			(unsigned int) new_add_flags,
+			(unsigned int) new_slot_info);
+	return 0;
+}
+
+static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev)
+{
+	struct xhci_input_control_ctx *ctrl_ctx;
+	struct xhci_ep_ctx *ep_ctx;
+	struct xhci_slot_ctx *slot_ctx;
+	int i;
+
+	/* When a device's add flag and drop flag are zero, any subsequent
+	 * configure endpoint command will leave that endpoint's state
+	 * untouched.  Make sure we don't leave any old state in the input
+	 * endpoint contexts.
+	 */
+	ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
+	ctrl_ctx->drop_flags = 0;
+	ctrl_ctx->add_flags = 0;
+	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
+	slot_ctx->dev_info &= ~LAST_CTX_MASK;
+	/* Endpoint 0 is always valid */
+	slot_ctx->dev_info |= LAST_CTX(1);
+	for (i = 1; i < 31; ++i) {
+		ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, i);
+		ep_ctx->ep_info = 0;
+		ep_ctx->ep_info2 = 0;
+		ep_ctx->deq = 0;
+		ep_ctx->tx_info = 0;
+	}
+}
+
+static int xhci_configure_endpoint_result(struct xhci_hcd *xhci,
+		struct usb_device *udev, int *cmd_status)
+{
+	int ret;
+
+	switch (*cmd_status) {
+	case COMP_ENOMEM:
+		dev_warn(&udev->dev, "Not enough host controller resources "
+				"for new device state.\n");
+		ret = -ENOMEM;
+		/* FIXME: can we allocate more resources for the HC? */
+		break;
+	case COMP_BW_ERR:
+		dev_warn(&udev->dev, "Not enough bandwidth "
+				"for new device state.\n");
+		ret = -ENOSPC;
+		/* FIXME: can we go back to the old state? */
+		break;
+	case COMP_TRB_ERR:
+		/* the HCD set up something wrong */
+		dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, "
+				"add flag = 1, "
+				"and endpoint is not disabled.\n");
+		ret = -EINVAL;
+		break;
+	case COMP_SUCCESS:
+		dev_dbg(&udev->dev, "Successful Endpoint Configure command\n");
+		ret = 0;
+		break;
+	default:
+		xhci_err(xhci, "ERROR: unexpected command completion "
+				"code 0x%x.\n", *cmd_status);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int xhci_evaluate_context_result(struct xhci_hcd *xhci,
+		struct usb_device *udev, int *cmd_status)
+{
+	int ret;
+	struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id];
+
+	switch (*cmd_status) {
+	case COMP_EINVAL:
+		dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate "
+				"context command.\n");
+		ret = -EINVAL;
+		break;
+	case COMP_EBADSLT:
+		dev_warn(&udev->dev, "WARN: slot not enabled for"
+				"evaluate context command.\n");
+	case COMP_CTX_STATE:
+		dev_warn(&udev->dev, "WARN: invalid context state for "
+				"evaluate context command.\n");
+		xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1);
+		ret = -EINVAL;
+		break;
+	case COMP_SUCCESS:
+		dev_dbg(&udev->dev, "Successful evaluate context command\n");
+		ret = 0;
+		break;
+	default:
+		xhci_err(xhci, "ERROR: unexpected command completion "
+				"code 0x%x.\n", *cmd_status);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+/* Issue a configure endpoint command or evaluate context command
+ * and wait for it to finish.
+ */
+static int xhci_configure_endpoint(struct xhci_hcd *xhci,
+		struct usb_device *udev,
+		struct xhci_command *command,
+		bool ctx_change, bool must_succeed)
+{
+	int ret;
+	int timeleft;
+	unsigned long flags;
+	struct xhci_container_ctx *in_ctx;
+	struct completion *cmd_completion;
+	int *cmd_status;
+	struct xhci_virt_device *virt_dev;
+
+	spin_lock_irqsave(&xhci->lock, flags);
+	virt_dev = xhci->devs[udev->slot_id];
+	if (command) {
+		in_ctx = command->in_ctx;
+		cmd_completion = command->completion;
+		cmd_status = &command->status;
+		command->command_trb = xhci->cmd_ring->enqueue;
+		list_add_tail(&command->cmd_list, &virt_dev->cmd_list);
+	} else {
+		in_ctx = virt_dev->in_ctx;
+		cmd_completion = &virt_dev->cmd_completion;
+		cmd_status = &virt_dev->cmd_status;
+	}
+	init_completion(cmd_completion);
+
+	if (!ctx_change)
+		ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma,
+				udev->slot_id, must_succeed);
+	else
+		ret = xhci_queue_evaluate_context(xhci, in_ctx->dma,
+				udev->slot_id);
+	if (ret < 0) {
+		if (command)
+			list_del(&command->cmd_list);
+		spin_unlock_irqrestore(&xhci->lock, flags);
+		xhci_dbg(xhci, "FIXME allocate a new ring segment\n");
+		return -ENOMEM;
+	}
+	xhci_ring_cmd_db(xhci);
+	spin_unlock_irqrestore(&xhci->lock, flags);
+
+	/* Wait for the configure endpoint command to complete */
+	timeleft = wait_for_completion_interruptible_timeout(
+			cmd_completion,
+			USB_CTRL_SET_TIMEOUT);
+	if (timeleft <= 0) {
+		xhci_warn(xhci, "%s while waiting for %s command\n",
+				timeleft == 0 ? "Timeout" : "Signal",
+				ctx_change == 0 ?
+					"configure endpoint" :
+					"evaluate context");
+		/* FIXME cancel the configure endpoint command */
+		return -ETIME;
+	}
+
+	if (!ctx_change)
+		return xhci_configure_endpoint_result(xhci, udev, cmd_status);
+	return xhci_evaluate_context_result(xhci, udev, cmd_status);
+}
+
+/* Called after one or more calls to xhci_add_endpoint() or
+ * xhci_drop_endpoint().  If this call fails, the USB core is expected
+ * to call xhci_reset_bandwidth().
+ *
+ * Since we are in the middle of changing either configuration or
+ * installing a new alt setting, the USB core won't allow URBs to be
+ * enqueued for any endpoint on the old config or interface.  Nothing
+ * else should be touching the xhci->devs[slot_id] structure, so we
+ * don't need to take the xhci->lock for manipulating that.
+ */
+int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
+{
+	int i;
+	int ret = 0;
+	struct xhci_hcd *xhci;
+	struct xhci_virt_device	*virt_dev;
+	struct xhci_input_control_ctx *ctrl_ctx;
+	struct xhci_slot_ctx *slot_ctx;
+
+	ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
+	if (ret <= 0)
+		return ret;
+	xhci = hcd_to_xhci(hcd);
+
+	if (!udev->slot_id || !xhci->devs || !xhci->devs[udev->slot_id]) {
+		xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
+				__func__);
+		return -EINVAL;
+	}
+	xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
+	virt_dev = xhci->devs[udev->slot_id];
+
+	/* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */
+	ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
+	ctrl_ctx->add_flags |= SLOT_FLAG;
+	ctrl_ctx->add_flags &= ~EP0_FLAG;
+	ctrl_ctx->drop_flags &= ~SLOT_FLAG;
+	ctrl_ctx->drop_flags &= ~EP0_FLAG;
+	xhci_dbg(xhci, "New Input Control Context:\n");
+	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
+	xhci_dbg_ctx(xhci, virt_dev->in_ctx,
+			LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
+
+	ret = xhci_configure_endpoint(xhci, udev, NULL,
+			false, false);
+	if (ret) {
+		/* Callee should call reset_bandwidth() */
+		return ret;
+	}
+
+	xhci_dbg(xhci, "Output context after successful config ep cmd:\n");
+	xhci_dbg_ctx(xhci, virt_dev->out_ctx,
+			LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
+
+	xhci_zero_in_ctx(xhci, virt_dev);
+	/* Install new rings and free or cache any old rings */
+	for (i = 1; i < 31; ++i) {
+		if (!virt_dev->eps[i].new_ring)
+			continue;
+		/* Only cache or free the old ring if it exists.
+		 * It may not if this is the first add of an endpoint.
+		 */
+		if (virt_dev->eps[i].ring) {
+			xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i);
+		}
+		virt_dev->eps[i].ring = virt_dev->eps[i].new_ring;
+		virt_dev->eps[i].new_ring = NULL;
+	}
+
+	return ret;
+}
+
+void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
+{
+	struct xhci_hcd *xhci;
+	struct xhci_virt_device	*virt_dev;
+	int i, ret;
+
+	ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
+	if (ret <= 0)
+		return;
+	xhci = hcd_to_xhci(hcd);
+
+	if (!xhci->devs || !xhci->devs[udev->slot_id]) {
+		xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
+				__func__);
+		return;
+	}
+	xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
+	virt_dev = xhci->devs[udev->slot_id];
+	/* Free any rings allocated for added endpoints */
+	for (i = 0; i < 31; ++i) {
+		if (virt_dev->eps[i].new_ring) {
+			xhci_ring_free(xhci, virt_dev->eps[i].new_ring);
+			virt_dev->eps[i].new_ring = NULL;
+		}
+	}
+	xhci_zero_in_ctx(xhci, virt_dev);
+}
+
+static void xhci_setup_input_ctx_for_config_ep(struct xhci_hcd *xhci,
+		struct xhci_container_ctx *in_ctx,
+		struct xhci_container_ctx *out_ctx,
+		u32 add_flags, u32 drop_flags)
+{
+	struct xhci_input_control_ctx *ctrl_ctx;
+	ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
+	ctrl_ctx->add_flags = add_flags;
+	ctrl_ctx->drop_flags = drop_flags;
+	xhci_slot_copy(xhci, in_ctx, out_ctx);
+	ctrl_ctx->add_flags |= SLOT_FLAG;
+
+	xhci_dbg(xhci, "Input Context:\n");
+	xhci_dbg_ctx(xhci, in_ctx, xhci_last_valid_endpoint(add_flags));
+}
+
+void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci,
+		unsigned int slot_id, unsigned int ep_index,
+		struct xhci_dequeue_state *deq_state)
+{
+	struct xhci_container_ctx *in_ctx;
+	struct xhci_ep_ctx *ep_ctx;
+	u32 added_ctxs;
+	dma_addr_t addr;
+
+	xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx,
+			xhci->devs[slot_id]->out_ctx, ep_index);
+	in_ctx = xhci->devs[slot_id]->in_ctx;
+	ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index);
+	addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg,
+			deq_state->new_deq_ptr);
+	if (addr == 0) {
+		xhci_warn(xhci, "WARN Cannot submit config ep after "
+				"reset ep command\n");
+		xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n",
+				deq_state->new_deq_seg,
+				deq_state->new_deq_ptr);
+		return;
+	}
+	ep_ctx->deq = addr | deq_state->new_cycle_state;
+
+	added_ctxs = xhci_get_endpoint_flag_from_index(ep_index);
+	xhci_setup_input_ctx_for_config_ep(xhci, xhci->devs[slot_id]->in_ctx,
+			xhci->devs[slot_id]->out_ctx, added_ctxs, added_ctxs);
+}
+
+void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
+		struct usb_device *udev, unsigned int ep_index)
+{
+	struct xhci_dequeue_state deq_state;
+	struct xhci_virt_ep *ep;
+
+	xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n");
+	ep = &xhci->devs[udev->slot_id]->eps[ep_index];
+	/* We need to move the HW's dequeue pointer past this TD,
+	 * or it will attempt to resend it on the next doorbell ring.
+	 */
+	xhci_find_new_dequeue_state(xhci, udev->slot_id,
+			ep_index, ep->stopped_td,
+			&deq_state);
+
+	/* HW with the reset endpoint quirk will use the saved dequeue state to
+	 * issue a configure endpoint command later.
+	 */
+	if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) {
+		xhci_dbg(xhci, "Queueing new dequeue state\n");
+		xhci_queue_new_dequeue_state(xhci, udev->slot_id,
+				ep_index, &deq_state);
+	} else {
+		/* Better hope no one uses the input context between now and the
+		 * reset endpoint completion!
+		 */
+		xhci_dbg(xhci, "Setting up input context for "
+				"configure endpoint command\n");
+		xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id,
+				ep_index, &deq_state);
+	}
+}
+
+/* Deal with stalled endpoints.  The core should have sent the control message
+ * to clear the halt condition.  However, we need to make the xHCI hardware
+ * reset its sequence number, since a device will expect a sequence number of
+ * zero after the halt condition is cleared.
+ * Context: in_interrupt
+ */
+void xhci_endpoint_reset(struct usb_hcd *hcd,
+		struct usb_host_endpoint *ep)
+{
+	struct xhci_hcd *xhci;
+	struct usb_device *udev;
+	unsigned int ep_index;
+	unsigned long flags;
+	int ret;
+	struct xhci_virt_ep *virt_ep;
+
+	xhci = hcd_to_xhci(hcd);
+	udev = (struct usb_device *) ep->hcpriv;
+	/* Called with a root hub endpoint (or an endpoint that wasn't added
+	 * with xhci_add_endpoint()
+	 */
+	if (!ep->hcpriv)
+		return;
+	ep_index = xhci_get_endpoint_index(&ep->desc);
+	virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index];
+	if (!virt_ep->stopped_td) {
+		xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n",
+				ep->desc.bEndpointAddress);
+		return;
+	}
+	if (usb_endpoint_xfer_control(&ep->desc)) {
+		xhci_dbg(xhci, "Control endpoint stall already handled.\n");
+		return;
+	}
+
+	xhci_dbg(xhci, "Queueing reset endpoint command\n");
+	spin_lock_irqsave(&xhci->lock, flags);
+	ret = xhci_queue_reset_ep(xhci, udev->slot_id, ep_index);
+	/*
+	 * Can't change the ring dequeue pointer until it's transitioned to the
+	 * stopped state, which is only upon a successful reset endpoint
+	 * command.  Better hope that last command worked!
+	 */
+	if (!ret) {
+		xhci_cleanup_stalled_ring(xhci, udev, ep_index);
+		kfree(virt_ep->stopped_td);
+		xhci_ring_cmd_db(xhci);
+	}
+	spin_unlock_irqrestore(&xhci->lock, flags);
+
+	if (ret)
+		xhci_warn(xhci, "FIXME allocate a new ring segment\n");
+}
+
+/*
+ * This submits a Reset Device Command, which will set the device state to 0,
+ * set the device address to 0, and disable all the endpoints except the default
+ * control endpoint.  The USB core should come back and call
+ * xhci_address_device(), and then re-set up the configuration.  If this is
+ * called because of a usb_reset_and_verify_device(), then the old alternate
+ * settings will be re-installed through the normal bandwidth allocation
+ * functions.
+ *
+ * Wait for the Reset Device command to finish.  Remove all structures
+ * associated with the endpoints that were disabled.  Clear the input device
+ * structure?  Cache the rings?  Reset the control endpoint 0 max packet size?
+ */
+int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
+{
+	int ret, i;
+	unsigned long flags;
+	struct xhci_hcd *xhci;
+	unsigned int slot_id;
+	struct xhci_virt_device *virt_dev;
+	struct xhci_command *reset_device_cmd;
+	int timeleft;
+	int last_freed_endpoint;
+
+	ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
+	if (ret <= 0)
+		return ret;
+	xhci = hcd_to_xhci(hcd);
+	slot_id = udev->slot_id;
+	virt_dev = xhci->devs[slot_id];
+	if (!virt_dev) {
+		xhci_dbg(xhci, "%s called with invalid slot ID %u\n",
+				__func__, slot_id);
+		return -EINVAL;
+	}
+
+	xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id);
+	/* Allocate the command structure that holds the struct completion.
+	 * Assume we're in process context, since the normal device reset
+	 * process has to wait for the device anyway.  Storage devices are
+	 * reset as part of error handling, so use GFP_NOIO instead of
+	 * GFP_KERNEL.
+	 */
+	reset_device_cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO);
+	if (!reset_device_cmd) {
+		xhci_dbg(xhci, "Couldn't allocate command structure.\n");
+		return -ENOMEM;
+	}
+
+	/* Attempt to submit the Reset Device command to the command ring */
+	spin_lock_irqsave(&xhci->lock, flags);
+	reset_device_cmd->command_trb = xhci->cmd_ring->enqueue;
+	list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list);
+	ret = xhci_queue_reset_device(xhci, slot_id);
+	if (ret) {
+		xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
+		list_del(&reset_device_cmd->cmd_list);
+		spin_unlock_irqrestore(&xhci->lock, flags);
+		goto command_cleanup;
+	}
+	xhci_ring_cmd_db(xhci);
+	spin_unlock_irqrestore(&xhci->lock, flags);
+
+	/* Wait for the Reset Device command to finish */
+	timeleft = wait_for_completion_interruptible_timeout(
+			reset_device_cmd->completion,
+			USB_CTRL_SET_TIMEOUT);
+	if (timeleft <= 0) {
+		xhci_warn(xhci, "%s while waiting for reset device command\n",
+				timeleft == 0 ? "Timeout" : "Signal");
+		spin_lock_irqsave(&xhci->lock, flags);
+		/* The timeout might have raced with the event ring handler, so
+		 * only delete from the list if the item isn't poisoned.
+		 */
+		if (reset_device_cmd->cmd_list.next != LIST_POISON1)
+			list_del(&reset_device_cmd->cmd_list);
+		spin_unlock_irqrestore(&xhci->lock, flags);
+		ret = -ETIME;
+		goto command_cleanup;
+	}
+
+	/* The Reset Device command can't fail, according to the 0.95/0.96 spec,
+	 * unless we tried to reset a slot ID that wasn't enabled,
+	 * or the device wasn't in the addressed or configured state.
+	 */
+	ret = reset_device_cmd->status;
+	switch (ret) {
+	case COMP_EBADSLT: /* 0.95 completion code for bad slot ID */
+	case COMP_CTX_STATE: /* 0.96 completion code for same thing */
+		xhci_info(xhci, "Can't reset device (slot ID %u) in %s state\n",
+				slot_id,
+				xhci_get_slot_state(xhci, virt_dev->out_ctx));
+		xhci_info(xhci, "Not freeing device rings.\n");
+		/* Don't treat this as an error.  May change my mind later. */
+		ret = 0;
+		goto command_cleanup;
+	case COMP_SUCCESS:
+		xhci_dbg(xhci, "Successful reset device command.\n");
+		break;
+	default:
+		if (xhci_is_vendor_info_code(xhci, ret))
+			break;
+		xhci_warn(xhci, "Unknown completion code %u for "
+				"reset device command.\n", ret);
+		ret = -EINVAL;
+		goto command_cleanup;
+	}
+
+	/* Everything but endpoint 0 is disabled, so free or cache the rings. */
+	last_freed_endpoint = 1;
+	for (i = 1; i < 31; ++i) {
+		if (!virt_dev->eps[i].ring)
+			continue;
+		xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i);
+		last_freed_endpoint = i;
+	}
+	xhci_dbg(xhci, "Output context after successful reset device cmd:\n");
+	xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint);
+	ret = 0;
+
+command_cleanup:
+	xhci_free_command(xhci, reset_device_cmd);
+	return ret;
+}
+
+/*
+ * At this point, the struct usb_device is about to go away, the device has
+ * disconnected, and all traffic has been stopped and the endpoints have been
+ * disabled.  Free any HC data structures associated with that device.
+ */
+void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
+{
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+	struct xhci_virt_device *virt_dev;
+	unsigned long flags;
+	u32 state;
+	int i;
+
+	if (udev->slot_id == 0)
+		return;
+	virt_dev = xhci->devs[udev->slot_id];
+	if (!virt_dev)
+		return;
+
+	/* Stop any wayward timer functions (which may grab the lock) */
+	for (i = 0; i < 31; ++i) {
+		virt_dev->eps[i].ep_state &= ~EP_HALT_PENDING;
+		del_timer_sync(&virt_dev->eps[i].stop_cmd_timer);
+	}
+
+	spin_lock_irqsave(&xhci->lock, flags);
+	/* Don't disable the slot if the host controller is dead. */
+	state = xhci_readl(xhci, &xhci->op_regs->status);
+	if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) {
+		xhci_free_virt_device(xhci, udev->slot_id);
+		spin_unlock_irqrestore(&xhci->lock, flags);
+		return;
+	}
+
+	if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) {
+		spin_unlock_irqrestore(&xhci->lock, flags);
+		xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
+		return;
+	}
+	xhci_ring_cmd_db(xhci);
+	spin_unlock_irqrestore(&xhci->lock, flags);
+	/*
+	 * Event command completion handler will free any data structures
+	 * associated with the slot.  XXX Can free sleep?
+	 */
+}
+
+/*
+ * Returns 0 if the xHC ran out of device slots, the Enable Slot command
+ * timed out, or allocating memory failed.  Returns 1 on success.
+ */
+int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
+{
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+	unsigned long flags;
+	int timeleft;
+	int ret;
+
+	spin_lock_irqsave(&xhci->lock, flags);
+	ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0);
+	if (ret) {
+		spin_unlock_irqrestore(&xhci->lock, flags);
+		xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
+		return 0;
+	}
+	xhci_ring_cmd_db(xhci);
+	spin_unlock_irqrestore(&xhci->lock, flags);
+
+	/* XXX: how much time for xHC slot assignment? */
+	timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
+			USB_CTRL_SET_TIMEOUT);
+	if (timeleft <= 0) {
+		xhci_warn(xhci, "%s while waiting for a slot\n",
+				timeleft == 0 ? "Timeout" : "Signal");
+		/* FIXME cancel the enable slot request */
+		return 0;
+	}
+
+	if (!xhci->slot_id) {
+		xhci_err(xhci, "Error while assigning device slot ID\n");
+		return 0;
+	}
+	/* xhci_alloc_virt_device() does not touch rings; no need to lock */
+	if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_KERNEL)) {
+		/* Disable slot, if we can do it without mem alloc */
+		xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
+		spin_lock_irqsave(&xhci->lock, flags);
+		if (!xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id))
+			xhci_ring_cmd_db(xhci);
+		spin_unlock_irqrestore(&xhci->lock, flags);
+		return 0;
+	}
+	udev->slot_id = xhci->slot_id;
+	/* Is this a LS or FS device under a HS hub? */
+	/* Hub or peripherial? */
+	return 1;
+}
+
+/*
+ * Issue an Address Device command (which will issue a SetAddress request to
+ * the device).
+ * We should be protected by the usb_address0_mutex in khubd's hub_port_init, so
+ * we should only issue and wait on one address command at the same time.
+ *
+ * We add one to the device address issued by the hardware because the USB core
+ * uses address 1 for the root hubs (even though they're not really devices).
+ */
+int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
+{
+	unsigned long flags;
+	int timeleft;
+	struct xhci_virt_device *virt_dev;
+	int ret = 0;
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+	struct xhci_slot_ctx *slot_ctx;
+	struct xhci_input_control_ctx *ctrl_ctx;
+	u64 temp_64;
+
+	if (!udev->slot_id) {
+		xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id);
+		return -EINVAL;
+	}
+
+	virt_dev = xhci->devs[udev->slot_id];
+
+	/* If this is a Set Address to an unconfigured device, setup ep 0 */
+	if (!udev->config)
+		xhci_setup_addressable_virt_dev(xhci, udev);
+	/* Otherwise, assume the core has the device configured how it wants */
+	xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
+	xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
+
+	spin_lock_irqsave(&xhci->lock, flags);
+	ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma,
+					udev->slot_id);
+	if (ret) {
+		spin_unlock_irqrestore(&xhci->lock, flags);
+		xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
+		return ret;
+	}
+	xhci_ring_cmd_db(xhci);
+	spin_unlock_irqrestore(&xhci->lock, flags);
+
+	/* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */
+	timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
+			USB_CTRL_SET_TIMEOUT);
+	/* FIXME: From section 4.3.4: "Software shall be responsible for timing
+	 * the SetAddress() "recovery interval" required by USB and aborting the
+	 * command on a timeout.
+	 */
+	if (timeleft <= 0) {
+		xhci_warn(xhci, "%s while waiting for a slot\n",
+				timeleft == 0 ? "Timeout" : "Signal");
+		/* FIXME cancel the address device command */
+		return -ETIME;
+	}
+
+	switch (virt_dev->cmd_status) {
+	case COMP_CTX_STATE:
+	case COMP_EBADSLT:
+		xhci_err(xhci, "Setup ERROR: address device command for slot %d.\n",
+				udev->slot_id);
+		ret = -EINVAL;
+		break;
+	case COMP_TX_ERR:
+		dev_warn(&udev->dev, "Device not responding to set address.\n");
+		ret = -EPROTO;
+		break;
+	case COMP_SUCCESS:
+		xhci_dbg(xhci, "Successful Address Device command\n");
+		break;
+	default:
+		xhci_err(xhci, "ERROR: unexpected command completion "
+				"code 0x%x.\n", virt_dev->cmd_status);
+		xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id);
+		xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2);
+		ret = -EINVAL;
+		break;
+	}
+	if (ret) {
+		return ret;
+	}
+	temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr);
+	xhci_dbg(xhci, "Op regs DCBAA ptr = %#016llx\n", temp_64);
+	xhci_dbg(xhci, "Slot ID %d dcbaa entry @%p = %#016llx\n",
+			udev->slot_id,
+			&xhci->dcbaa->dev_context_ptrs[udev->slot_id],
+			(unsigned long long)
+				xhci->dcbaa->dev_context_ptrs[udev->slot_id]);
+	xhci_dbg(xhci, "Output Context DMA address = %#08llx\n",
+			(unsigned long long)virt_dev->out_ctx->dma);
+	xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
+	xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
+	xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id);
+	xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2);
+	/*
+	 * USB core uses address 1 for the roothubs, so we add one to the
+	 * address given back to us by the HC.
+	 */
+	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx);
+	udev->devnum = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1;
+	/* Zero the input context control for later use */
+	ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
+	ctrl_ctx->add_flags = 0;
+	ctrl_ctx->drop_flags = 0;
+
+	xhci_dbg(xhci, "Device address = %d\n", udev->devnum);
+	/* XXX Meh, not sure if anyone else but choose_address uses this. */
+	set_bit(udev->devnum, udev->bus->devmap.devicemap);
+
+	return 0;
+}
+
+/* Once a hub descriptor is fetched for a device, we need to update the xHC's
+ * internal data structures for the device.
+ */
+int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
+			struct usb_tt *tt, gfp_t mem_flags)
+{
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+	struct xhci_virt_device *vdev;
+	struct xhci_command *config_cmd;
+	struct xhci_input_control_ctx *ctrl_ctx;
+	struct xhci_slot_ctx *slot_ctx;
+	unsigned long flags;
+	unsigned think_time;
+	int ret;
+
+	/* Ignore root hubs */
+	if (!hdev->parent)
+		return 0;
+
+	vdev = xhci->devs[hdev->slot_id];
+	if (!vdev) {
+		xhci_warn(xhci, "Cannot update hub desc for unknown device.\n");
+		return -EINVAL;
+	}
+	config_cmd = xhci_alloc_command(xhci, true, true, mem_flags);
+	if (!config_cmd) {
+		xhci_dbg(xhci, "Could not allocate xHCI command structure.\n");
+		return -ENOMEM;
+	}
+
+	spin_lock_irqsave(&xhci->lock, flags);
+	xhci_slot_copy(xhci, config_cmd->in_ctx, vdev->out_ctx);
+	ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx);
+	ctrl_ctx->add_flags |= SLOT_FLAG;
+	slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx);
+	slot_ctx->dev_info |= DEV_HUB;
+	if (tt->multi)
+		slot_ctx->dev_info |= DEV_MTT;
+	if (xhci->hci_version > 0x95) {
+		xhci_dbg(xhci, "xHCI version %x needs hub "
+				"TT think time and number of ports\n",
+				(unsigned int) xhci->hci_version);
+		slot_ctx->dev_info2 |= XHCI_MAX_PORTS(hdev->maxchild);
+		/* Set TT think time - convert from ns to FS bit times.
+		 * 0 = 8 FS bit times, 1 = 16 FS bit times,
+		 * 2 = 24 FS bit times, 3 = 32 FS bit times.
+		 */
+		think_time = tt->think_time;
+		if (think_time != 0)
+			think_time = (think_time / 666) - 1;
+		slot_ctx->tt_info |= TT_THINK_TIME(think_time);
+	} else {
+		xhci_dbg(xhci, "xHCI version %x doesn't need hub "
+				"TT think time or number of ports\n",
+				(unsigned int) xhci->hci_version);
+	}
+	slot_ctx->dev_state = 0;
+	spin_unlock_irqrestore(&xhci->lock, flags);
+
+	xhci_dbg(xhci, "Set up %s for hub device.\n",
+			(xhci->hci_version > 0x95) ?
+			"configure endpoint" : "evaluate context");
+	xhci_dbg(xhci, "Slot %u Input Context:\n", hdev->slot_id);
+	xhci_dbg_ctx(xhci, config_cmd->in_ctx, 0);
+
+	/* Issue and wait for the configure endpoint or
+	 * evaluate context command.
+	 */
+	if (xhci->hci_version > 0x95)
+		ret = xhci_configure_endpoint(xhci, hdev, config_cmd,
+				false, false);
+	else
+		ret = xhci_configure_endpoint(xhci, hdev, config_cmd,
+				true, false);
+
+	xhci_dbg(xhci, "Slot %u Output Context:\n", hdev->slot_id);
+	xhci_dbg_ctx(xhci, vdev->out_ctx, 0);
+
+	xhci_free_command(xhci, config_cmd);
+	return ret;
+}
+
+int xhci_get_frame(struct usb_hcd *hcd)
+{
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+	/* EHCI mods by the periodic size.  Why? */
+	return xhci_readl(xhci, &xhci->run_regs->microframe_index) >> 3;
+}
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE("GPL");
+
+static int __init xhci_hcd_init(void)
+{
+#ifdef CONFIG_PCI
+	int retval = 0;
+
+	retval = xhci_register_pci();
+
+	if (retval < 0) {
+		printk(KERN_DEBUG "Problem registering PCI driver.");
+		return retval;
+	}
+#endif
+	/*
+	 * Check the compiler generated sizes of structures that must be laid
+	 * out in specific ways for hardware access.
+	 */
+	BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8);
+	BUILD_BUG_ON(sizeof(struct xhci_slot_ctx) != 8*32/8);
+	BUILD_BUG_ON(sizeof(struct xhci_ep_ctx) != 8*32/8);
+	/* xhci_device_control has eight fields, and also
+	 * embeds one xhci_slot_ctx and 31 xhci_ep_ctx
+	 */
+	BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8);
+	BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8);
+	BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8);
+	BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 7*32/8);
+	BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8);
+	/* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */
+	BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8);
+	BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8);
+	return 0;
+}
+module_init(xhci_hcd_init);
+
+static void __exit xhci_hcd_cleanup(void)
+{
+#ifdef CONFIG_PCI
+	xhci_unregister_pci();
+#endif
+}
+module_exit(xhci_hcd_cleanup);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/xhci-dbg.c linux-libre-2.6.34-gnu1/drivers/usb/host/xhci-dbg.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/xhci-dbg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/xhci-dbg.c	2010-05-16 17:17:36.000000000 -0400
@@ -406,6 +406,25 @@ static void dbg_rsvd64(struct xhci_hcd *
 	}
 }
 
+char *xhci_get_slot_state(struct xhci_hcd *xhci,
+		struct xhci_container_ctx *ctx)
+{
+	struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx);
+
+	switch (GET_SLOT_STATE(slot_ctx->dev_state)) {
+	case 0:
+		return "enabled/disabled";
+	case 1:
+		return "default";
+	case 2:
+		return "addressed";
+	case 3:
+		return "configured";
+	default:
+		return "reserved";
+	}
+}
+
 void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx)
 {
 	/* Fields are 32 bits wide, DMA addresses are in bytes */
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/xhci-ext-caps.h linux-libre-2.6.34-gnu1/drivers/usb/host/xhci-ext-caps.h
--- linux-libre-2.6.33-gnu1/drivers/usb/host/xhci-ext-caps.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/xhci-ext-caps.h	2010-05-16 17:17:36.000000000 -0400
@@ -101,12 +101,15 @@ static inline int xhci_find_next_cap_off
 
 	next = readl(base + ext_offset);
 
-	if (ext_offset == XHCI_HCC_PARAMS_OFFSET)
+	if (ext_offset == XHCI_HCC_PARAMS_OFFSET) {
 		/* Find the first extended capability */
 		next = XHCI_HCC_EXT_CAPS(next);
-	else
+		ext_offset = 0;
+	} else {
 		/* Find the next extended capability */
 		next = XHCI_EXT_CAPS_NEXT(next);
+	}
+
 	if (!next)
 		return 0;
 	/*
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/xhci.h linux-libre-2.6.34-gnu1/drivers/usb/host/xhci.h
--- linux-libre-2.6.33-gnu1/drivers/usb/host/xhci.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/xhci.h	2010-05-16 17:17:36.000000000 -0400
@@ -609,6 +609,10 @@ struct xhci_ep_ctx {
 #define MAX_PACKET_MASK		(0xffff << 16)
 #define MAX_PACKET_DECODED(p)	(((p) >> 16) & 0xffff)
 
+/* tx_info bitmasks */
+#define AVG_TRB_LENGTH_FOR_EP(p)	((p) & 0xffff)
+#define MAX_ESIT_PAYLOAD_FOR_EP(p)	(((p) & 0xffff) << 16)
+
 
 /**
  * struct xhci_input_control_context
@@ -1210,6 +1214,8 @@ void xhci_dbg_erst(struct xhci_hcd *xhci
 void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci);
 void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring);
 void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int last_ep);
+char *xhci_get_slot_state(struct xhci_hcd *xhci,
+		struct xhci_container_ctx *ctx);
 
 /* xHCI memory management */
 void xhci_mem_cleanup(struct xhci_hcd *xhci);
@@ -1233,8 +1239,12 @@ int xhci_endpoint_init(struct xhci_hcd *
 		struct usb_device *udev, struct usb_host_endpoint *ep,
 		gfp_t mem_flags);
 void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring);
+void xhci_free_or_cache_endpoint_ring(struct xhci_hcd *xhci,
+		struct xhci_virt_device *virt_dev,
+		unsigned int ep_index);
 struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci,
-		bool allocate_completion, gfp_t mem_flags);
+		bool allocate_in_ctx, bool allocate_completion,
+		gfp_t mem_flags);
 void xhci_free_command(struct xhci_hcd *xhci,
 		struct xhci_command *command);
 
@@ -1264,6 +1274,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd
 int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep);
 int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep);
 void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep);
+int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev);
 int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
 void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
 
@@ -1272,6 +1283,7 @@ dma_addr_t xhci_trb_virt_to_dma(struct x
 struct xhci_segment *trb_in_td(struct xhci_segment *start_seg,
 		union xhci_trb *start_trb, union xhci_trb *end_trb,
 		dma_addr_t suspect_dma);
+int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code);
 void xhci_ring_cmd_db(struct xhci_hcd *xhci);
 void *xhci_setup_one_noop(struct xhci_hcd *xhci);
 void xhci_handle_event(struct xhci_hcd *xhci);
@@ -1293,6 +1305,7 @@ int xhci_queue_evaluate_context(struct x
 		u32 slot_id);
 int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id,
 		unsigned int ep_index);
+int xhci_queue_reset_device(struct xhci_hcd *xhci, u32 slot_id);
 void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
 		unsigned int slot_id, unsigned int ep_index,
 		struct xhci_td *cur_td, struct xhci_dequeue_state *state);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/xhci-hcd.c linux-libre-2.6.34-gnu1/drivers/usb/host/xhci-hcd.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/xhci-hcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/xhci-hcd.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1806 +0,0 @@
-/*
- * xHCI host controller driver
- *
- * Copyright (C) 2008 Intel Corp.
- *
- * Author: Sarah Sharp
- * Some code borrowed from the Linux EHCI driver.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/irq.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-
-#include "xhci.h"
-
-#define DRIVER_AUTHOR "Sarah Sharp"
-#define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
-
-/* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */
-static int link_quirk;
-module_param(link_quirk, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB");
-
-/* TODO: copied from ehci-hcd.c - can this be refactored? */
-/*
- * handshake - spin reading hc until handshake completes or fails
- * @ptr: address of hc register to be read
- * @mask: bits to look at in result of read
- * @done: value of those bits when handshake succeeds
- * @usec: timeout in microseconds
- *
- * Returns negative errno, or zero on success
- *
- * Success happens when the "mask" bits have the specified value (hardware
- * handshake done).  There are two failure modes:  "usec" have passed (major
- * hardware flakeout), or the register reads as all-ones (hardware removed).
- */
-static int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
-		      u32 mask, u32 done, int usec)
-{
-	u32	result;
-
-	do {
-		result = xhci_readl(xhci, ptr);
-		if (result == ~(u32)0)		/* card removed */
-			return -ENODEV;
-		result &= mask;
-		if (result == done)
-			return 0;
-		udelay(1);
-		usec--;
-	} while (usec > 0);
-	return -ETIMEDOUT;
-}
-
-/*
- * Disable interrupts and begin the xHCI halting process.
- */
-void xhci_quiesce(struct xhci_hcd *xhci)
-{
-	u32 halted;
-	u32 cmd;
-	u32 mask;
-
-	mask = ~(XHCI_IRQS);
-	halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT;
-	if (!halted)
-		mask &= ~CMD_RUN;
-
-	cmd = xhci_readl(xhci, &xhci->op_regs->command);
-	cmd &= mask;
-	xhci_writel(xhci, cmd, &xhci->op_regs->command);
-}
-
-/*
- * Force HC into halt state.
- *
- * Disable any IRQs and clear the run/stop bit.
- * HC will complete any current and actively pipelined transactions, and
- * should halt within 16 microframes of the run/stop bit being cleared.
- * Read HC Halted bit in the status register to see when the HC is finished.
- * XXX: shouldn't we set HC_STATE_HALT here somewhere?
- */
-int xhci_halt(struct xhci_hcd *xhci)
-{
-	xhci_dbg(xhci, "// Halt the HC\n");
-	xhci_quiesce(xhci);
-
-	return handshake(xhci, &xhci->op_regs->status,
-			STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
-}
-
-/*
- * Reset a halted HC, and set the internal HC state to HC_STATE_HALT.
- *
- * This resets pipelines, timers, counters, state machines, etc.
- * Transactions will be terminated immediately, and operational registers
- * will be set to their defaults.
- */
-int xhci_reset(struct xhci_hcd *xhci)
-{
-	u32 command;
-	u32 state;
-
-	state = xhci_readl(xhci, &xhci->op_regs->status);
-	if ((state & STS_HALT) == 0) {
-		xhci_warn(xhci, "Host controller not halted, aborting reset.\n");
-		return 0;
-	}
-
-	xhci_dbg(xhci, "// Reset the HC\n");
-	command = xhci_readl(xhci, &xhci->op_regs->command);
-	command |= CMD_RESET;
-	xhci_writel(xhci, command, &xhci->op_regs->command);
-	/* XXX: Why does EHCI set this here?  Shouldn't other code do this? */
-	xhci_to_hcd(xhci)->state = HC_STATE_HALT;
-
-	return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000);
-}
-
-
-#if 0
-/* Set up MSI-X table for entry 0 (may claim other entries later) */
-static int xhci_setup_msix(struct xhci_hcd *xhci)
-{
-	int ret;
-	struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
-
-	xhci->msix_count = 0;
-	/* XXX: did I do this right?  ixgbe does kcalloc for more than one */
-	xhci->msix_entries = kmalloc(sizeof(struct msix_entry), GFP_KERNEL);
-	if (!xhci->msix_entries) {
-		xhci_err(xhci, "Failed to allocate MSI-X entries\n");
-		return -ENOMEM;
-	}
-	xhci->msix_entries[0].entry = 0;
-
-	ret = pci_enable_msix(pdev, xhci->msix_entries, xhci->msix_count);
-	if (ret) {
-		xhci_err(xhci, "Failed to enable MSI-X\n");
-		goto free_entries;
-	}
-
-	/*
-	 * Pass the xhci pointer value as the request_irq "cookie".
-	 * If more irqs are added, this will need to be unique for each one.
-	 */
-	ret = request_irq(xhci->msix_entries[0].vector, &xhci_irq, 0,
-			"xHCI", xhci_to_hcd(xhci));
-	if (ret) {
-		xhci_err(xhci, "Failed to allocate MSI-X interrupt\n");
-		goto disable_msix;
-	}
-	xhci_dbg(xhci, "Finished setting up MSI-X\n");
-	return 0;
-
-disable_msix:
-	pci_disable_msix(pdev);
-free_entries:
-	kfree(xhci->msix_entries);
-	xhci->msix_entries = NULL;
-	return ret;
-}
-
-/* XXX: code duplication; can xhci_setup_msix call this? */
-/* Free any IRQs and disable MSI-X */
-static void xhci_cleanup_msix(struct xhci_hcd *xhci)
-{
-	struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
-	if (!xhci->msix_entries)
-		return;
-
-	free_irq(xhci->msix_entries[0].vector, xhci);
-	pci_disable_msix(pdev);
-	kfree(xhci->msix_entries);
-	xhci->msix_entries = NULL;
-	xhci_dbg(xhci, "Finished cleaning up MSI-X\n");
-}
-#endif
-
-/*
- * Initialize memory for HCD and xHC (one-time init).
- *
- * Program the PAGESIZE register, initialize the device context array, create
- * device contexts (?), set up a command ring segment (or two?), create event
- * ring (one for now).
- */
-int xhci_init(struct usb_hcd *hcd)
-{
-	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	int retval = 0;
-
-	xhci_dbg(xhci, "xhci_init\n");
-	spin_lock_init(&xhci->lock);
-	if (link_quirk) {
-		xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n");
-		xhci->quirks |= XHCI_LINK_TRB_QUIRK;
-	} else {
-		xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n");
-	}
-	retval = xhci_mem_init(xhci, GFP_KERNEL);
-	xhci_dbg(xhci, "Finished xhci_init\n");
-
-	return retval;
-}
-
-/*
- * Called in interrupt context when there might be work
- * queued on the event ring
- *
- * xhci->lock must be held by caller.
- */
-static void xhci_work(struct xhci_hcd *xhci)
-{
-	u32 temp;
-	u64 temp_64;
-
-	/*
-	 * Clear the op reg interrupt status first,
-	 * so we can receive interrupts from other MSI-X interrupters.
-	 * Write 1 to clear the interrupt status.
-	 */
-	temp = xhci_readl(xhci, &xhci->op_regs->status);
-	temp |= STS_EINT;
-	xhci_writel(xhci, temp, &xhci->op_regs->status);
-	/* FIXME when MSI-X is supported and there are multiple vectors */
-	/* Clear the MSI-X event interrupt status */
-
-	/* Acknowledge the interrupt */
-	temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
-	temp |= 0x3;
-	xhci_writel(xhci, temp, &xhci->ir_set->irq_pending);
-	/* Flush posted writes */
-	xhci_readl(xhci, &xhci->ir_set->irq_pending);
-
-	if (xhci->xhc_state & XHCI_STATE_DYING)
-		xhci_dbg(xhci, "xHCI dying, ignoring interrupt. "
-				"Shouldn't IRQs be disabled?\n");
-	else
-		/* FIXME this should be a delayed service routine
-		 * that clears the EHB.
-		 */
-		xhci_handle_event(xhci);
-
-	/* Clear the event handler busy flag (RW1C); the event ring should be empty. */
-	temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
-	xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue);
-	/* Flush posted writes -- FIXME is this necessary? */
-	xhci_readl(xhci, &xhci->ir_set->irq_pending);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * xHCI spec says we can get an interrupt, and if the HC has an error condition,
- * we might get bad data out of the event ring.  Section 4.10.2.7 has a list of
- * indicators of an event TRB error, but we check the status *first* to be safe.
- */
-irqreturn_t xhci_irq(struct usb_hcd *hcd)
-{
-	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	u32 temp, temp2;
-	union xhci_trb *trb;
-
-	spin_lock(&xhci->lock);
-	trb = xhci->event_ring->dequeue;
-	/* Check if the xHC generated the interrupt, or the irq is shared */
-	temp = xhci_readl(xhci, &xhci->op_regs->status);
-	temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending);
-	if (temp == 0xffffffff && temp2 == 0xffffffff)
-		goto hw_died;
-
-	if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) {
-		spin_unlock(&xhci->lock);
-		return IRQ_NONE;
-	}
-	xhci_dbg(xhci, "op reg status = %08x\n", temp);
-	xhci_dbg(xhci, "ir set irq_pending = %08x\n", temp2);
-	xhci_dbg(xhci, "Event ring dequeue ptr:\n");
-	xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n",
-			(unsigned long long)xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, trb),
-			lower_32_bits(trb->link.segment_ptr),
-			upper_32_bits(trb->link.segment_ptr),
-			(unsigned int) trb->link.intr_target,
-			(unsigned int) trb->link.control);
-
-	if (temp & STS_FATAL) {
-		xhci_warn(xhci, "WARNING: Host System Error\n");
-		xhci_halt(xhci);
-hw_died:
-		xhci_to_hcd(xhci)->state = HC_STATE_HALT;
-		spin_unlock(&xhci->lock);
-		return -ESHUTDOWN;
-	}
-
-	xhci_work(xhci);
-	spin_unlock(&xhci->lock);
-
-	return IRQ_HANDLED;
-}
-
-#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
-void xhci_event_ring_work(unsigned long arg)
-{
-	unsigned long flags;
-	int temp;
-	u64 temp_64;
-	struct xhci_hcd *xhci = (struct xhci_hcd *) arg;
-	int i, j;
-
-	xhci_dbg(xhci, "Poll event ring: %lu\n", jiffies);
-
-	spin_lock_irqsave(&xhci->lock, flags);
-	temp = xhci_readl(xhci, &xhci->op_regs->status);
-	xhci_dbg(xhci, "op reg status = 0x%x\n", temp);
-	if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) {
-		xhci_dbg(xhci, "HW died, polling stopped.\n");
-		spin_unlock_irqrestore(&xhci->lock, flags);
-		return;
-	}
-
-	temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
-	xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp);
-	xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled);
-	xhci_dbg(xhci, "HC error bitmask = 0x%x\n", xhci->error_bitmask);
-	xhci->error_bitmask = 0;
-	xhci_dbg(xhci, "Event ring:\n");
-	xhci_debug_segment(xhci, xhci->event_ring->deq_seg);
-	xhci_dbg_ring_ptrs(xhci, xhci->event_ring);
-	temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
-	temp_64 &= ~ERST_PTR_MASK;
-	xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64);
-	xhci_dbg(xhci, "Command ring:\n");
-	xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg);
-	xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
-	xhci_dbg_cmd_ptrs(xhci);
-	for (i = 0; i < MAX_HC_SLOTS; ++i) {
-		if (!xhci->devs[i])
-			continue;
-		for (j = 0; j < 31; ++j) {
-			struct xhci_ring *ring = xhci->devs[i]->eps[j].ring;
-			if (!ring)
-				continue;
-			xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j);
-			xhci_debug_segment(xhci, ring->deq_seg);
-		}
-	}
-
-	if (xhci->noops_submitted != NUM_TEST_NOOPS)
-		if (xhci_setup_one_noop(xhci))
-			xhci_ring_cmd_db(xhci);
-	spin_unlock_irqrestore(&xhci->lock, flags);
-
-	if (!xhci->zombie)
-		mod_timer(&xhci->event_ring_timer, jiffies + POLL_TIMEOUT * HZ);
-	else
-		xhci_dbg(xhci, "Quit polling the event ring.\n");
-}
-#endif
-
-/*
- * Start the HC after it was halted.
- *
- * This function is called by the USB core when the HC driver is added.
- * Its opposite is xhci_stop().
- *
- * xhci_init() must be called once before this function can be called.
- * Reset the HC, enable device slot contexts, program DCBAAP, and
- * set command ring pointer and event ring pointer.
- *
- * Setup MSI-X vectors and enable interrupts.
- */
-int xhci_run(struct usb_hcd *hcd)
-{
-	u32 temp;
-	u64 temp_64;
-	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	void (*doorbell)(struct xhci_hcd *) = NULL;
-
-	hcd->uses_new_polling = 1;
-	hcd->poll_rh = 0;
-
-	xhci_dbg(xhci, "xhci_run\n");
-#if 0	/* FIXME: MSI not setup yet */
-	/* Do this at the very last minute */
-	ret = xhci_setup_msix(xhci);
-	if (!ret)
-		return ret;
-
-	return -ENOSYS;
-#endif
-#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
-	init_timer(&xhci->event_ring_timer);
-	xhci->event_ring_timer.data = (unsigned long) xhci;
-	xhci->event_ring_timer.function = xhci_event_ring_work;
-	/* Poll the event ring */
-	xhci->event_ring_timer.expires = jiffies + POLL_TIMEOUT * HZ;
-	xhci->zombie = 0;
-	xhci_dbg(xhci, "Setting event ring polling timer\n");
-	add_timer(&xhci->event_ring_timer);
-#endif
-
-	xhci_dbg(xhci, "Command ring memory map follows:\n");
-	xhci_debug_ring(xhci, xhci->cmd_ring);
-	xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
-	xhci_dbg_cmd_ptrs(xhci);
-
-	xhci_dbg(xhci, "ERST memory map follows:\n");
-	xhci_dbg_erst(xhci, &xhci->erst);
-	xhci_dbg(xhci, "Event ring:\n");
-	xhci_debug_ring(xhci, xhci->event_ring);
-	xhci_dbg_ring_ptrs(xhci, xhci->event_ring);
-	temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
-	temp_64 &= ~ERST_PTR_MASK;
-	xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64);
-
-	xhci_dbg(xhci, "// Set the interrupt modulation register\n");
-	temp = xhci_readl(xhci, &xhci->ir_set->irq_control);
-	temp &= ~ER_IRQ_INTERVAL_MASK;
-	temp |= (u32) 160;
-	xhci_writel(xhci, temp, &xhci->ir_set->irq_control);
-
-	/* Set the HCD state before we enable the irqs */
-	hcd->state = HC_STATE_RUNNING;
-	temp = xhci_readl(xhci, &xhci->op_regs->command);
-	temp |= (CMD_EIE);
-	xhci_dbg(xhci, "// Enable interrupts, cmd = 0x%x.\n",
-			temp);
-	xhci_writel(xhci, temp, &xhci->op_regs->command);
-
-	temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
-	xhci_dbg(xhci, "// Enabling event ring interrupter %p by writing 0x%x to irq_pending\n",
-			xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp));
-	xhci_writel(xhci, ER_IRQ_ENABLE(temp),
-			&xhci->ir_set->irq_pending);
-	xhci_print_ir_set(xhci, xhci->ir_set, 0);
-
-	if (NUM_TEST_NOOPS > 0)
-		doorbell = xhci_setup_one_noop(xhci);
-
-	temp = xhci_readl(xhci, &xhci->op_regs->command);
-	temp |= (CMD_RUN);
-	xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n",
-			temp);
-	xhci_writel(xhci, temp, &xhci->op_regs->command);
-	/* Flush PCI posted writes */
-	temp = xhci_readl(xhci, &xhci->op_regs->command);
-	xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp);
-	if (doorbell)
-		(*doorbell)(xhci);
-
-	xhci_dbg(xhci, "Finished xhci_run\n");
-	return 0;
-}
-
-/*
- * Stop xHCI driver.
- *
- * This function is called by the USB core when the HC driver is removed.
- * Its opposite is xhci_run().
- *
- * Disable device contexts, disable IRQs, and quiesce the HC.
- * Reset the HC, finish any completed transactions, and cleanup memory.
- */
-void xhci_stop(struct usb_hcd *hcd)
-{
-	u32 temp;
-	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-
-	spin_lock_irq(&xhci->lock);
-	xhci_halt(xhci);
-	xhci_reset(xhci);
-	spin_unlock_irq(&xhci->lock);
-
-#if 0	/* No MSI yet */
-	xhci_cleanup_msix(xhci);
-#endif
-#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
-	/* Tell the event ring poll function not to reschedule */
-	xhci->zombie = 1;
-	del_timer_sync(&xhci->event_ring_timer);
-#endif
-
-	xhci_dbg(xhci, "// Disabling event ring interrupts\n");
-	temp = xhci_readl(xhci, &xhci->op_regs->status);
-	xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status);
-	temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
-	xhci_writel(xhci, ER_IRQ_DISABLE(temp),
-			&xhci->ir_set->irq_pending);
-	xhci_print_ir_set(xhci, xhci->ir_set, 0);
-
-	xhci_dbg(xhci, "cleaning up memory\n");
-	xhci_mem_cleanup(xhci);
-	xhci_dbg(xhci, "xhci_stop completed - status = %x\n",
-		    xhci_readl(xhci, &xhci->op_regs->status));
-}
-
-/*
- * Shutdown HC (not bus-specific)
- *
- * This is called when the machine is rebooting or halting.  We assume that the
- * machine will be powered off, and the HC's internal state will be reset.
- * Don't bother to free memory.
- */
-void xhci_shutdown(struct usb_hcd *hcd)
-{
-	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-
-	spin_lock_irq(&xhci->lock);
-	xhci_halt(xhci);
-	spin_unlock_irq(&xhci->lock);
-
-#if 0
-	xhci_cleanup_msix(xhci);
-#endif
-
-	xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n",
-		    xhci_readl(xhci, &xhci->op_regs->status));
-}
-
-/*-------------------------------------------------------------------------*/
-
-/**
- * xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and
- * HCDs.  Find the index for an endpoint given its descriptor.  Use the return
- * value to right shift 1 for the bitmask.
- *
- * Index  = (epnum * 2) + direction - 1,
- * where direction = 0 for OUT, 1 for IN.
- * For control endpoints, the IN index is used (OUT index is unused), so
- * index = (epnum * 2) + direction - 1 = (epnum * 2) + 1 - 1 = (epnum * 2)
- */
-unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc)
-{
-	unsigned int index;
-	if (usb_endpoint_xfer_control(desc))
-		index = (unsigned int) (usb_endpoint_num(desc)*2);
-	else
-		index = (unsigned int) (usb_endpoint_num(desc)*2) +
-			(usb_endpoint_dir_in(desc) ? 1 : 0) - 1;
-	return index;
-}
-
-/* Find the flag for this endpoint (for use in the control context).  Use the
- * endpoint index to create a bitmask.  The slot context is bit 0, endpoint 0 is
- * bit 1, etc.
- */
-unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc)
-{
-	return 1 << (xhci_get_endpoint_index(desc) + 1);
-}
-
-/* Find the flag for this endpoint (for use in the control context).  Use the
- * endpoint index to create a bitmask.  The slot context is bit 0, endpoint 0 is
- * bit 1, etc.
- */
-unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index)
-{
-	return 1 << (ep_index + 1);
-}
-
-/* Compute the last valid endpoint context index.  Basically, this is the
- * endpoint index plus one.  For slot contexts with more than valid endpoint,
- * we find the most significant bit set in the added contexts flags.
- * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000
- * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one.
- */
-unsigned int xhci_last_valid_endpoint(u32 added_ctxs)
-{
-	return fls(added_ctxs) - 1;
-}
-
-/* Returns 1 if the arguments are OK;
- * returns 0 this is a root hub; returns -EINVAL for NULL pointers.
- */
-int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev,
-		struct usb_host_endpoint *ep, int check_ep, const char *func) {
-	if (!hcd || (check_ep && !ep) || !udev) {
-		printk(KERN_DEBUG "xHCI %s called with invalid args\n",
-				func);
-		return -EINVAL;
-	}
-	if (!udev->parent) {
-		printk(KERN_DEBUG "xHCI %s called for root hub\n",
-				func);
-		return 0;
-	}
-	if (!udev->slot_id) {
-		printk(KERN_DEBUG "xHCI %s called with unaddressed device\n",
-				func);
-		return -EINVAL;
-	}
-	return 1;
-}
-
-static int xhci_configure_endpoint(struct xhci_hcd *xhci,
-		struct usb_device *udev, struct xhci_command *command,
-		bool ctx_change, bool must_succeed);
-
-/*
- * Full speed devices may have a max packet size greater than 8 bytes, but the
- * USB core doesn't know that until it reads the first 8 bytes of the
- * descriptor.  If the usb_device's max packet size changes after that point,
- * we need to issue an evaluate context command and wait on it.
- */
-static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,
-		unsigned int ep_index, struct urb *urb)
-{
-	struct xhci_container_ctx *in_ctx;
-	struct xhci_container_ctx *out_ctx;
-	struct xhci_input_control_ctx *ctrl_ctx;
-	struct xhci_ep_ctx *ep_ctx;
-	int max_packet_size;
-	int hw_max_packet_size;
-	int ret = 0;
-
-	out_ctx = xhci->devs[slot_id]->out_ctx;
-	ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
-	hw_max_packet_size = MAX_PACKET_DECODED(ep_ctx->ep_info2);
-	max_packet_size = urb->dev->ep0.desc.wMaxPacketSize;
-	if (hw_max_packet_size != max_packet_size) {
-		xhci_dbg(xhci, "Max Packet Size for ep 0 changed.\n");
-		xhci_dbg(xhci, "Max packet size in usb_device = %d\n",
-				max_packet_size);
-		xhci_dbg(xhci, "Max packet size in xHCI HW = %d\n",
-				hw_max_packet_size);
-		xhci_dbg(xhci, "Issuing evaluate context command.\n");
-
-		/* Set up the modified control endpoint 0 */
-		xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx,
-				xhci->devs[slot_id]->out_ctx, ep_index);
-		in_ctx = xhci->devs[slot_id]->in_ctx;
-		ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index);
-		ep_ctx->ep_info2 &= ~MAX_PACKET_MASK;
-		ep_ctx->ep_info2 |= MAX_PACKET(max_packet_size);
-
-		/* Set up the input context flags for the command */
-		/* FIXME: This won't work if a non-default control endpoint
-		 * changes max packet sizes.
-		 */
-		ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
-		ctrl_ctx->add_flags = EP0_FLAG;
-		ctrl_ctx->drop_flags = 0;
-
-		xhci_dbg(xhci, "Slot %d input context\n", slot_id);
-		xhci_dbg_ctx(xhci, in_ctx, ep_index);
-		xhci_dbg(xhci, "Slot %d output context\n", slot_id);
-		xhci_dbg_ctx(xhci, out_ctx, ep_index);
-
-		ret = xhci_configure_endpoint(xhci, urb->dev, NULL,
-				true, false);
-
-		/* Clean up the input context for later use by bandwidth
-		 * functions.
-		 */
-		ctrl_ctx->add_flags = SLOT_FLAG;
-	}
-	return ret;
-}
-
-/*
- * non-error returns are a promise to giveback() the urb later
- * we drop ownership so next owner (or urb unlink) can get it
- */
-int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
-{
-	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	unsigned long flags;
-	int ret = 0;
-	unsigned int slot_id, ep_index;
-
-
-	if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0)
-		return -EINVAL;
-
-	slot_id = urb->dev->slot_id;
-	ep_index = xhci_get_endpoint_index(&urb->ep->desc);
-
-	if (!xhci->devs || !xhci->devs[slot_id]) {
-		if (!in_interrupt())
-			dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n");
-		ret = -EINVAL;
-		goto exit;
-	}
-	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
-		if (!in_interrupt())
-			xhci_dbg(xhci, "urb submitted during PCI suspend\n");
-		ret = -ESHUTDOWN;
-		goto exit;
-	}
-	if (usb_endpoint_xfer_control(&urb->ep->desc)) {
-		/* Check to see if the max packet size for the default control
-		 * endpoint changed during FS device enumeration
-		 */
-		if (urb->dev->speed == USB_SPEED_FULL) {
-			ret = xhci_check_maxpacket(xhci, slot_id,
-					ep_index, urb);
-			if (ret < 0)
-				return ret;
-		}
-
-		/* We have a spinlock and interrupts disabled, so we must pass
-		 * atomic context to this function, which may allocate memory.
-		 */
-		spin_lock_irqsave(&xhci->lock, flags);
-		if (xhci->xhc_state & XHCI_STATE_DYING)
-			goto dying;
-		ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
-				slot_id, ep_index);
-		spin_unlock_irqrestore(&xhci->lock, flags);
-	} else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) {
-		spin_lock_irqsave(&xhci->lock, flags);
-		if (xhci->xhc_state & XHCI_STATE_DYING)
-			goto dying;
-		ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
-				slot_id, ep_index);
-		spin_unlock_irqrestore(&xhci->lock, flags);
-	} else if (usb_endpoint_xfer_int(&urb->ep->desc)) {
-		spin_lock_irqsave(&xhci->lock, flags);
-		if (xhci->xhc_state & XHCI_STATE_DYING)
-			goto dying;
-		ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb,
-				slot_id, ep_index);
-		spin_unlock_irqrestore(&xhci->lock, flags);
-	} else {
-		ret = -EINVAL;
-	}
-exit:
-	return ret;
-dying:
-	xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for "
-			"non-responsive xHCI host.\n",
-			urb->ep->desc.bEndpointAddress, urb);
-	spin_unlock_irqrestore(&xhci->lock, flags);
-	return -ESHUTDOWN;
-}
-
-/*
- * Remove the URB's TD from the endpoint ring.  This may cause the HC to stop
- * USB transfers, potentially stopping in the middle of a TRB buffer.  The HC
- * should pick up where it left off in the TD, unless a Set Transfer Ring
- * Dequeue Pointer is issued.
- *
- * The TRBs that make up the buffers for the canceled URB will be "removed" from
- * the ring.  Since the ring is a contiguous structure, they can't be physically
- * removed.  Instead, there are two options:
- *
- *  1) If the HC is in the middle of processing the URB to be canceled, we
- *     simply move the ring's dequeue pointer past those TRBs using the Set
- *     Transfer Ring Dequeue Pointer command.  This will be the common case,
- *     when drivers timeout on the last submitted URB and attempt to cancel.
- *
- *  2) If the HC is in the middle of a different TD, we turn the TRBs into a
- *     series of 1-TRB transfer no-op TDs.  (No-ops shouldn't be chained.)  The
- *     HC will need to invalidate the any TRBs it has cached after the stop
- *     endpoint command, as noted in the xHCI 0.95 errata.
- *
- *  3) The TD may have completed by the time the Stop Endpoint Command
- *     completes, so software needs to handle that case too.
- *
- * This function should protect against the TD enqueueing code ringing the
- * doorbell while this code is waiting for a Stop Endpoint command to complete.
- * It also needs to account for multiple cancellations on happening at the same
- * time for the same endpoint.
- *
- * Note that this function can be called in any context, or so says
- * usb_hcd_unlink_urb()
- */
-int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
-{
-	unsigned long flags;
-	int ret;
-	u32 temp;
-	struct xhci_hcd *xhci;
-	struct xhci_td *td;
-	unsigned int ep_index;
-	struct xhci_ring *ep_ring;
-	struct xhci_virt_ep *ep;
-
-	xhci = hcd_to_xhci(hcd);
-	spin_lock_irqsave(&xhci->lock, flags);
-	/* Make sure the URB hasn't completed or been unlinked already */
-	ret = usb_hcd_check_unlink_urb(hcd, urb, status);
-	if (ret || !urb->hcpriv)
-		goto done;
-	temp = xhci_readl(xhci, &xhci->op_regs->status);
-	if (temp == 0xffffffff) {
-		xhci_dbg(xhci, "HW died, freeing TD.\n");
-		td = (struct xhci_td *) urb->hcpriv;
-
-		usb_hcd_unlink_urb_from_ep(hcd, urb);
-		spin_unlock_irqrestore(&xhci->lock, flags);
-		usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN);
-		kfree(td);
-		return ret;
-	}
-	if (xhci->xhc_state & XHCI_STATE_DYING) {
-		xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on "
-				"non-responsive xHCI host.\n",
-				urb->ep->desc.bEndpointAddress, urb);
-		/* Let the stop endpoint command watchdog timer (which set this
-		 * state) finish cleaning up the endpoint TD lists.  We must
-		 * have caught it in the middle of dropping a lock and giving
-		 * back an URB.
-		 */
-		goto done;
-	}
-
-	xhci_dbg(xhci, "Cancel URB %p\n", urb);
-	xhci_dbg(xhci, "Event ring:\n");
-	xhci_debug_ring(xhci, xhci->event_ring);
-	ep_index = xhci_get_endpoint_index(&urb->ep->desc);
-	ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index];
-	ep_ring = ep->ring;
-	xhci_dbg(xhci, "Endpoint ring:\n");
-	xhci_debug_ring(xhci, ep_ring);
-	td = (struct xhci_td *) urb->hcpriv;
-
-	list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list);
-	/* Queue a stop endpoint command, but only if this is
-	 * the first cancellation to be handled.
-	 */
-	if (!(ep->ep_state & EP_HALT_PENDING)) {
-		ep->ep_state |= EP_HALT_PENDING;
-		ep->stop_cmds_pending++;
-		ep->stop_cmd_timer.expires = jiffies +
-			XHCI_STOP_EP_CMD_TIMEOUT * HZ;
-		add_timer(&ep->stop_cmd_timer);
-		xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index);
-		xhci_ring_cmd_db(xhci);
-	}
-done:
-	spin_unlock_irqrestore(&xhci->lock, flags);
-	return ret;
-}
-
-/* Drop an endpoint from a new bandwidth configuration for this device.
- * Only one call to this function is allowed per endpoint before
- * check_bandwidth() or reset_bandwidth() must be called.
- * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will
- * add the endpoint to the schedule with possibly new parameters denoted by a
- * different endpoint descriptor in usb_host_endpoint.
- * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is
- * not allowed.
- *
- * The USB core will not allow URBs to be queued to an endpoint that is being
- * disabled, so there's no need for mutual exclusion to protect
- * the xhci->devs[slot_id] structure.
- */
-int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
-		struct usb_host_endpoint *ep)
-{
-	struct xhci_hcd *xhci;
-	struct xhci_container_ctx *in_ctx, *out_ctx;
-	struct xhci_input_control_ctx *ctrl_ctx;
-	struct xhci_slot_ctx *slot_ctx;
-	unsigned int last_ctx;
-	unsigned int ep_index;
-	struct xhci_ep_ctx *ep_ctx;
-	u32 drop_flag;
-	u32 new_add_flags, new_drop_flags, new_slot_info;
-	int ret;
-
-	ret = xhci_check_args(hcd, udev, ep, 1, __func__);
-	if (ret <= 0)
-		return ret;
-	xhci = hcd_to_xhci(hcd);
-	xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
-
-	drop_flag = xhci_get_endpoint_flag(&ep->desc);
-	if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) {
-		xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n",
-				__func__, drop_flag);
-		return 0;
-	}
-
-	if (!xhci->devs || !xhci->devs[udev->slot_id]) {
-		xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
-				__func__);
-		return -EINVAL;
-	}
-
-	in_ctx = xhci->devs[udev->slot_id]->in_ctx;
-	out_ctx = xhci->devs[udev->slot_id]->out_ctx;
-	ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
-	ep_index = xhci_get_endpoint_index(&ep->desc);
-	ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
-	/* If the HC already knows the endpoint is disabled,
-	 * or the HCD has noted it is disabled, ignore this request
-	 */
-	if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED ||
-			ctrl_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) {
-		xhci_warn(xhci, "xHCI %s called with disabled ep %p\n",
-				__func__, ep);
-		return 0;
-	}
-
-	ctrl_ctx->drop_flags |= drop_flag;
-	new_drop_flags = ctrl_ctx->drop_flags;
-
-	ctrl_ctx->add_flags &= ~drop_flag;
-	new_add_flags = ctrl_ctx->add_flags;
-
-	last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags);
-	slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
-	/* Update the last valid endpoint context, if we deleted the last one */
-	if ((slot_ctx->dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) {
-		slot_ctx->dev_info &= ~LAST_CTX_MASK;
-		slot_ctx->dev_info |= LAST_CTX(last_ctx);
-	}
-	new_slot_info = slot_ctx->dev_info;
-
-	xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep);
-
-	xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n",
-			(unsigned int) ep->desc.bEndpointAddress,
-			udev->slot_id,
-			(unsigned int) new_drop_flags,
-			(unsigned int) new_add_flags,
-			(unsigned int) new_slot_info);
-	return 0;
-}
-
-/* Add an endpoint to a new possible bandwidth configuration for this device.
- * Only one call to this function is allowed per endpoint before
- * check_bandwidth() or reset_bandwidth() must be called.
- * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will
- * add the endpoint to the schedule with possibly new parameters denoted by a
- * different endpoint descriptor in usb_host_endpoint.
- * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is
- * not allowed.
- *
- * The USB core will not allow URBs to be queued to an endpoint until the
- * configuration or alt setting is installed in the device, so there's no need
- * for mutual exclusion to protect the xhci->devs[slot_id] structure.
- */
-int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
-		struct usb_host_endpoint *ep)
-{
-	struct xhci_hcd *xhci;
-	struct xhci_container_ctx *in_ctx, *out_ctx;
-	unsigned int ep_index;
-	struct xhci_ep_ctx *ep_ctx;
-	struct xhci_slot_ctx *slot_ctx;
-	struct xhci_input_control_ctx *ctrl_ctx;
-	u32 added_ctxs;
-	unsigned int last_ctx;
-	u32 new_add_flags, new_drop_flags, new_slot_info;
-	int ret = 0;
-
-	ret = xhci_check_args(hcd, udev, ep, 1, __func__);
-	if (ret <= 0) {
-		/* So we won't queue a reset ep command for a root hub */
-		ep->hcpriv = NULL;
-		return ret;
-	}
-	xhci = hcd_to_xhci(hcd);
-
-	added_ctxs = xhci_get_endpoint_flag(&ep->desc);
-	last_ctx = xhci_last_valid_endpoint(added_ctxs);
-	if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) {
-		/* FIXME when we have to issue an evaluate endpoint command to
-		 * deal with ep0 max packet size changing once we get the
-		 * descriptors
-		 */
-		xhci_dbg(xhci, "xHCI %s - can't add slot or ep 0 %#x\n",
-				__func__, added_ctxs);
-		return 0;
-	}
-
-	if (!xhci->devs || !xhci->devs[udev->slot_id]) {
-		xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
-				__func__);
-		return -EINVAL;
-	}
-
-	in_ctx = xhci->devs[udev->slot_id]->in_ctx;
-	out_ctx = xhci->devs[udev->slot_id]->out_ctx;
-	ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
-	ep_index = xhci_get_endpoint_index(&ep->desc);
-	ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
-	/* If the HCD has already noted the endpoint is enabled,
-	 * ignore this request.
-	 */
-	if (ctrl_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) {
-		xhci_warn(xhci, "xHCI %s called with enabled ep %p\n",
-				__func__, ep);
-		return 0;
-	}
-
-	/*
-	 * Configuration and alternate setting changes must be done in
-	 * process context, not interrupt context (or so documenation
-	 * for usb_set_interface() and usb_set_configuration() claim).
-	 */
-	if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id],
-				udev, ep, GFP_KERNEL) < 0) {
-		dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n",
-				__func__, ep->desc.bEndpointAddress);
-		return -ENOMEM;
-	}
-
-	ctrl_ctx->add_flags |= added_ctxs;
-	new_add_flags = ctrl_ctx->add_flags;
-
-	/* If xhci_endpoint_disable() was called for this endpoint, but the
-	 * xHC hasn't been notified yet through the check_bandwidth() call,
-	 * this re-adds a new state for the endpoint from the new endpoint
-	 * descriptors.  We must drop and re-add this endpoint, so we leave the
-	 * drop flags alone.
-	 */
-	new_drop_flags = ctrl_ctx->drop_flags;
-
-	slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
-	/* Update the last valid endpoint context, if we just added one past */
-	if ((slot_ctx->dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) {
-		slot_ctx->dev_info &= ~LAST_CTX_MASK;
-		slot_ctx->dev_info |= LAST_CTX(last_ctx);
-	}
-	new_slot_info = slot_ctx->dev_info;
-
-	/* Store the usb_device pointer for later use */
-	ep->hcpriv = udev;
-
-	xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n",
-			(unsigned int) ep->desc.bEndpointAddress,
-			udev->slot_id,
-			(unsigned int) new_drop_flags,
-			(unsigned int) new_add_flags,
-			(unsigned int) new_slot_info);
-	return 0;
-}
-
-static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev)
-{
-	struct xhci_input_control_ctx *ctrl_ctx;
-	struct xhci_ep_ctx *ep_ctx;
-	struct xhci_slot_ctx *slot_ctx;
-	int i;
-
-	/* When a device's add flag and drop flag are zero, any subsequent
-	 * configure endpoint command will leave that endpoint's state
-	 * untouched.  Make sure we don't leave any old state in the input
-	 * endpoint contexts.
-	 */
-	ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
-	ctrl_ctx->drop_flags = 0;
-	ctrl_ctx->add_flags = 0;
-	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
-	slot_ctx->dev_info &= ~LAST_CTX_MASK;
-	/* Endpoint 0 is always valid */
-	slot_ctx->dev_info |= LAST_CTX(1);
-	for (i = 1; i < 31; ++i) {
-		ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, i);
-		ep_ctx->ep_info = 0;
-		ep_ctx->ep_info2 = 0;
-		ep_ctx->deq = 0;
-		ep_ctx->tx_info = 0;
-	}
-}
-
-static int xhci_configure_endpoint_result(struct xhci_hcd *xhci,
-		struct usb_device *udev, int *cmd_status)
-{
-	int ret;
-
-	switch (*cmd_status) {
-	case COMP_ENOMEM:
-		dev_warn(&udev->dev, "Not enough host controller resources "
-				"for new device state.\n");
-		ret = -ENOMEM;
-		/* FIXME: can we allocate more resources for the HC? */
-		break;
-	case COMP_BW_ERR:
-		dev_warn(&udev->dev, "Not enough bandwidth "
-				"for new device state.\n");
-		ret = -ENOSPC;
-		/* FIXME: can we go back to the old state? */
-		break;
-	case COMP_TRB_ERR:
-		/* the HCD set up something wrong */
-		dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, "
-				"add flag = 1, "
-				"and endpoint is not disabled.\n");
-		ret = -EINVAL;
-		break;
-	case COMP_SUCCESS:
-		dev_dbg(&udev->dev, "Successful Endpoint Configure command\n");
-		ret = 0;
-		break;
-	default:
-		xhci_err(xhci, "ERROR: unexpected command completion "
-				"code 0x%x.\n", *cmd_status);
-		ret = -EINVAL;
-		break;
-	}
-	return ret;
-}
-
-static int xhci_evaluate_context_result(struct xhci_hcd *xhci,
-		struct usb_device *udev, int *cmd_status)
-{
-	int ret;
-	struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id];
-
-	switch (*cmd_status) {
-	case COMP_EINVAL:
-		dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate "
-				"context command.\n");
-		ret = -EINVAL;
-		break;
-	case COMP_EBADSLT:
-		dev_warn(&udev->dev, "WARN: slot not enabled for"
-				"evaluate context command.\n");
-	case COMP_CTX_STATE:
-		dev_warn(&udev->dev, "WARN: invalid context state for "
-				"evaluate context command.\n");
-		xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1);
-		ret = -EINVAL;
-		break;
-	case COMP_SUCCESS:
-		dev_dbg(&udev->dev, "Successful evaluate context command\n");
-		ret = 0;
-		break;
-	default:
-		xhci_err(xhci, "ERROR: unexpected command completion "
-				"code 0x%x.\n", *cmd_status);
-		ret = -EINVAL;
-		break;
-	}
-	return ret;
-}
-
-/* Issue a configure endpoint command or evaluate context command
- * and wait for it to finish.
- */
-static int xhci_configure_endpoint(struct xhci_hcd *xhci,
-		struct usb_device *udev,
-		struct xhci_command *command,
-		bool ctx_change, bool must_succeed)
-{
-	int ret;
-	int timeleft;
-	unsigned long flags;
-	struct xhci_container_ctx *in_ctx;
-	struct completion *cmd_completion;
-	int *cmd_status;
-	struct xhci_virt_device *virt_dev;
-
-	spin_lock_irqsave(&xhci->lock, flags);
-	virt_dev = xhci->devs[udev->slot_id];
-	if (command) {
-		in_ctx = command->in_ctx;
-		cmd_completion = command->completion;
-		cmd_status = &command->status;
-		command->command_trb = xhci->cmd_ring->enqueue;
-		list_add_tail(&command->cmd_list, &virt_dev->cmd_list);
-	} else {
-		in_ctx = virt_dev->in_ctx;
-		cmd_completion = &virt_dev->cmd_completion;
-		cmd_status = &virt_dev->cmd_status;
-	}
-
-	if (!ctx_change)
-		ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma,
-				udev->slot_id, must_succeed);
-	else
-		ret = xhci_queue_evaluate_context(xhci, in_ctx->dma,
-				udev->slot_id);
-	if (ret < 0) {
-		spin_unlock_irqrestore(&xhci->lock, flags);
-		xhci_dbg(xhci, "FIXME allocate a new ring segment\n");
-		return -ENOMEM;
-	}
-	xhci_ring_cmd_db(xhci);
-	spin_unlock_irqrestore(&xhci->lock, flags);
-
-	/* Wait for the configure endpoint command to complete */
-	timeleft = wait_for_completion_interruptible_timeout(
-			cmd_completion,
-			USB_CTRL_SET_TIMEOUT);
-	if (timeleft <= 0) {
-		xhci_warn(xhci, "%s while waiting for %s command\n",
-				timeleft == 0 ? "Timeout" : "Signal",
-				ctx_change == 0 ?
-					"configure endpoint" :
-					"evaluate context");
-		/* FIXME cancel the configure endpoint command */
-		return -ETIME;
-	}
-
-	if (!ctx_change)
-		return xhci_configure_endpoint_result(xhci, udev, cmd_status);
-	return xhci_evaluate_context_result(xhci, udev, cmd_status);
-}
-
-/* Called after one or more calls to xhci_add_endpoint() or
- * xhci_drop_endpoint().  If this call fails, the USB core is expected
- * to call xhci_reset_bandwidth().
- *
- * Since we are in the middle of changing either configuration or
- * installing a new alt setting, the USB core won't allow URBs to be
- * enqueued for any endpoint on the old config or interface.  Nothing
- * else should be touching the xhci->devs[slot_id] structure, so we
- * don't need to take the xhci->lock for manipulating that.
- */
-int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
-{
-	int i;
-	int ret = 0;
-	struct xhci_hcd *xhci;
-	struct xhci_virt_device	*virt_dev;
-	struct xhci_input_control_ctx *ctrl_ctx;
-	struct xhci_slot_ctx *slot_ctx;
-
-	ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
-	if (ret <= 0)
-		return ret;
-	xhci = hcd_to_xhci(hcd);
-
-	if (!udev->slot_id || !xhci->devs || !xhci->devs[udev->slot_id]) {
-		xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
-				__func__);
-		return -EINVAL;
-	}
-	xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
-	virt_dev = xhci->devs[udev->slot_id];
-
-	/* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */
-	ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
-	ctrl_ctx->add_flags |= SLOT_FLAG;
-	ctrl_ctx->add_flags &= ~EP0_FLAG;
-	ctrl_ctx->drop_flags &= ~SLOT_FLAG;
-	ctrl_ctx->drop_flags &= ~EP0_FLAG;
-	xhci_dbg(xhci, "New Input Control Context:\n");
-	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
-	xhci_dbg_ctx(xhci, virt_dev->in_ctx,
-			LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
-
-	ret = xhci_configure_endpoint(xhci, udev, NULL,
-			false, false);
-	if (ret) {
-		/* Callee should call reset_bandwidth() */
-		return ret;
-	}
-
-	xhci_dbg(xhci, "Output context after successful config ep cmd:\n");
-	xhci_dbg_ctx(xhci, virt_dev->out_ctx,
-			LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
-
-	xhci_zero_in_ctx(xhci, virt_dev);
-	/* Install new rings and free or cache any old rings */
-	for (i = 1; i < 31; ++i) {
-		int rings_cached;
-
-		if (!virt_dev->eps[i].new_ring)
-			continue;
-		/* Only cache or free the old ring if it exists.
-		 * It may not if this is the first add of an endpoint.
-		 */
-		if (virt_dev->eps[i].ring) {
-			rings_cached = virt_dev->num_rings_cached;
-			if (rings_cached < XHCI_MAX_RINGS_CACHED) {
-				virt_dev->num_rings_cached++;
-				rings_cached = virt_dev->num_rings_cached;
-				virt_dev->ring_cache[rings_cached] =
-					virt_dev->eps[i].ring;
-				xhci_dbg(xhci, "Cached old ring, "
-						"%d ring%s cached\n",
-						rings_cached,
-						(rings_cached > 1) ? "s" : "");
-			} else {
-				xhci_ring_free(xhci, virt_dev->eps[i].ring);
-				xhci_dbg(xhci, "Ring cache full (%d rings), "
-						"freeing ring\n",
-						virt_dev->num_rings_cached);
-			}
-		}
-		virt_dev->eps[i].ring = virt_dev->eps[i].new_ring;
-		virt_dev->eps[i].new_ring = NULL;
-	}
-
-	return ret;
-}
-
-void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
-{
-	struct xhci_hcd *xhci;
-	struct xhci_virt_device	*virt_dev;
-	int i, ret;
-
-	ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
-	if (ret <= 0)
-		return;
-	xhci = hcd_to_xhci(hcd);
-
-	if (!xhci->devs || !xhci->devs[udev->slot_id]) {
-		xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
-				__func__);
-		return;
-	}
-	xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
-	virt_dev = xhci->devs[udev->slot_id];
-	/* Free any rings allocated for added endpoints */
-	for (i = 0; i < 31; ++i) {
-		if (virt_dev->eps[i].new_ring) {
-			xhci_ring_free(xhci, virt_dev->eps[i].new_ring);
-			virt_dev->eps[i].new_ring = NULL;
-		}
-	}
-	xhci_zero_in_ctx(xhci, virt_dev);
-}
-
-static void xhci_setup_input_ctx_for_config_ep(struct xhci_hcd *xhci,
-		struct xhci_container_ctx *in_ctx,
-		struct xhci_container_ctx *out_ctx,
-		u32 add_flags, u32 drop_flags)
-{
-	struct xhci_input_control_ctx *ctrl_ctx;
-	ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
-	ctrl_ctx->add_flags = add_flags;
-	ctrl_ctx->drop_flags = drop_flags;
-	xhci_slot_copy(xhci, in_ctx, out_ctx);
-	ctrl_ctx->add_flags |= SLOT_FLAG;
-
-	xhci_dbg(xhci, "Input Context:\n");
-	xhci_dbg_ctx(xhci, in_ctx, xhci_last_valid_endpoint(add_flags));
-}
-
-void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci,
-		unsigned int slot_id, unsigned int ep_index,
-		struct xhci_dequeue_state *deq_state)
-{
-	struct xhci_container_ctx *in_ctx;
-	struct xhci_ep_ctx *ep_ctx;
-	u32 added_ctxs;
-	dma_addr_t addr;
-
-	xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx,
-			xhci->devs[slot_id]->out_ctx, ep_index);
-	in_ctx = xhci->devs[slot_id]->in_ctx;
-	ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index);
-	addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg,
-			deq_state->new_deq_ptr);
-	if (addr == 0) {
-		xhci_warn(xhci, "WARN Cannot submit config ep after "
-				"reset ep command\n");
-		xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n",
-				deq_state->new_deq_seg,
-				deq_state->new_deq_ptr);
-		return;
-	}
-	ep_ctx->deq = addr | deq_state->new_cycle_state;
-
-	added_ctxs = xhci_get_endpoint_flag_from_index(ep_index);
-	xhci_setup_input_ctx_for_config_ep(xhci, xhci->devs[slot_id]->in_ctx,
-			xhci->devs[slot_id]->out_ctx, added_ctxs, added_ctxs);
-}
-
-void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
-		struct usb_device *udev, unsigned int ep_index)
-{
-	struct xhci_dequeue_state deq_state;
-	struct xhci_virt_ep *ep;
-
-	xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n");
-	ep = &xhci->devs[udev->slot_id]->eps[ep_index];
-	/* We need to move the HW's dequeue pointer past this TD,
-	 * or it will attempt to resend it on the next doorbell ring.
-	 */
-	xhci_find_new_dequeue_state(xhci, udev->slot_id,
-			ep_index, ep->stopped_td,
-			&deq_state);
-
-	/* HW with the reset endpoint quirk will use the saved dequeue state to
-	 * issue a configure endpoint command later.
-	 */
-	if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) {
-		xhci_dbg(xhci, "Queueing new dequeue state\n");
-		xhci_queue_new_dequeue_state(xhci, udev->slot_id,
-				ep_index, &deq_state);
-	} else {
-		/* Better hope no one uses the input context between now and the
-		 * reset endpoint completion!
-		 */
-		xhci_dbg(xhci, "Setting up input context for "
-				"configure endpoint command\n");
-		xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id,
-				ep_index, &deq_state);
-	}
-}
-
-/* Deal with stalled endpoints.  The core should have sent the control message
- * to clear the halt condition.  However, we need to make the xHCI hardware
- * reset its sequence number, since a device will expect a sequence number of
- * zero after the halt condition is cleared.
- * Context: in_interrupt
- */
-void xhci_endpoint_reset(struct usb_hcd *hcd,
-		struct usb_host_endpoint *ep)
-{
-	struct xhci_hcd *xhci;
-	struct usb_device *udev;
-	unsigned int ep_index;
-	unsigned long flags;
-	int ret;
-	struct xhci_virt_ep *virt_ep;
-
-	xhci = hcd_to_xhci(hcd);
-	udev = (struct usb_device *) ep->hcpriv;
-	/* Called with a root hub endpoint (or an endpoint that wasn't added
-	 * with xhci_add_endpoint()
-	 */
-	if (!ep->hcpriv)
-		return;
-	ep_index = xhci_get_endpoint_index(&ep->desc);
-	virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index];
-	if (!virt_ep->stopped_td) {
-		xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n",
-				ep->desc.bEndpointAddress);
-		return;
-	}
-	if (usb_endpoint_xfer_control(&ep->desc)) {
-		xhci_dbg(xhci, "Control endpoint stall already handled.\n");
-		return;
-	}
-
-	xhci_dbg(xhci, "Queueing reset endpoint command\n");
-	spin_lock_irqsave(&xhci->lock, flags);
-	ret = xhci_queue_reset_ep(xhci, udev->slot_id, ep_index);
-	/*
-	 * Can't change the ring dequeue pointer until it's transitioned to the
-	 * stopped state, which is only upon a successful reset endpoint
-	 * command.  Better hope that last command worked!
-	 */
-	if (!ret) {
-		xhci_cleanup_stalled_ring(xhci, udev, ep_index);
-		kfree(virt_ep->stopped_td);
-		xhci_ring_cmd_db(xhci);
-	}
-	spin_unlock_irqrestore(&xhci->lock, flags);
-
-	if (ret)
-		xhci_warn(xhci, "FIXME allocate a new ring segment\n");
-}
-
-/*
- * At this point, the struct usb_device is about to go away, the device has
- * disconnected, and all traffic has been stopped and the endpoints have been
- * disabled.  Free any HC data structures associated with that device.
- */
-void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
-{
-	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	struct xhci_virt_device *virt_dev;
-	unsigned long flags;
-	u32 state;
-	int i;
-
-	if (udev->slot_id == 0)
-		return;
-	virt_dev = xhci->devs[udev->slot_id];
-	if (!virt_dev)
-		return;
-
-	/* Stop any wayward timer functions (which may grab the lock) */
-	for (i = 0; i < 31; ++i) {
-		virt_dev->eps[i].ep_state &= ~EP_HALT_PENDING;
-		del_timer_sync(&virt_dev->eps[i].stop_cmd_timer);
-	}
-
-	spin_lock_irqsave(&xhci->lock, flags);
-	/* Don't disable the slot if the host controller is dead. */
-	state = xhci_readl(xhci, &xhci->op_regs->status);
-	if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) {
-		xhci_free_virt_device(xhci, udev->slot_id);
-		spin_unlock_irqrestore(&xhci->lock, flags);
-		return;
-	}
-
-	if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) {
-		spin_unlock_irqrestore(&xhci->lock, flags);
-		xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
-		return;
-	}
-	xhci_ring_cmd_db(xhci);
-	spin_unlock_irqrestore(&xhci->lock, flags);
-	/*
-	 * Event command completion handler will free any data structures
-	 * associated with the slot.  XXX Can free sleep?
-	 */
-}
-
-/*
- * Returns 0 if the xHC ran out of device slots, the Enable Slot command
- * timed out, or allocating memory failed.  Returns 1 on success.
- */
-int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
-{
-	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	unsigned long flags;
-	int timeleft;
-	int ret;
-
-	spin_lock_irqsave(&xhci->lock, flags);
-	ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0);
-	if (ret) {
-		spin_unlock_irqrestore(&xhci->lock, flags);
-		xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
-		return 0;
-	}
-	xhci_ring_cmd_db(xhci);
-	spin_unlock_irqrestore(&xhci->lock, flags);
-
-	/* XXX: how much time for xHC slot assignment? */
-	timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
-			USB_CTRL_SET_TIMEOUT);
-	if (timeleft <= 0) {
-		xhci_warn(xhci, "%s while waiting for a slot\n",
-				timeleft == 0 ? "Timeout" : "Signal");
-		/* FIXME cancel the enable slot request */
-		return 0;
-	}
-
-	if (!xhci->slot_id) {
-		xhci_err(xhci, "Error while assigning device slot ID\n");
-		return 0;
-	}
-	/* xhci_alloc_virt_device() does not touch rings; no need to lock */
-	if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_KERNEL)) {
-		/* Disable slot, if we can do it without mem alloc */
-		xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
-		spin_lock_irqsave(&xhci->lock, flags);
-		if (!xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id))
-			xhci_ring_cmd_db(xhci);
-		spin_unlock_irqrestore(&xhci->lock, flags);
-		return 0;
-	}
-	udev->slot_id = xhci->slot_id;
-	/* Is this a LS or FS device under a HS hub? */
-	/* Hub or peripherial? */
-	return 1;
-}
-
-/*
- * Issue an Address Device command (which will issue a SetAddress request to
- * the device).
- * We should be protected by the usb_address0_mutex in khubd's hub_port_init, so
- * we should only issue and wait on one address command at the same time.
- *
- * We add one to the device address issued by the hardware because the USB core
- * uses address 1 for the root hubs (even though they're not really devices).
- */
-int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
-{
-	unsigned long flags;
-	int timeleft;
-	struct xhci_virt_device *virt_dev;
-	int ret = 0;
-	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	struct xhci_slot_ctx *slot_ctx;
-	struct xhci_input_control_ctx *ctrl_ctx;
-	u64 temp_64;
-
-	if (!udev->slot_id) {
-		xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id);
-		return -EINVAL;
-	}
-
-	virt_dev = xhci->devs[udev->slot_id];
-
-	/* If this is a Set Address to an unconfigured device, setup ep 0 */
-	if (!udev->config)
-		xhci_setup_addressable_virt_dev(xhci, udev);
-	/* Otherwise, assume the core has the device configured how it wants */
-	xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
-	xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
-
-	spin_lock_irqsave(&xhci->lock, flags);
-	ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma,
-					udev->slot_id);
-	if (ret) {
-		spin_unlock_irqrestore(&xhci->lock, flags);
-		xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
-		return ret;
-	}
-	xhci_ring_cmd_db(xhci);
-	spin_unlock_irqrestore(&xhci->lock, flags);
-
-	/* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */
-	timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
-			USB_CTRL_SET_TIMEOUT);
-	/* FIXME: From section 4.3.4: "Software shall be responsible for timing
-	 * the SetAddress() "recovery interval" required by USB and aborting the
-	 * command on a timeout.
-	 */
-	if (timeleft <= 0) {
-		xhci_warn(xhci, "%s while waiting for a slot\n",
-				timeleft == 0 ? "Timeout" : "Signal");
-		/* FIXME cancel the address device command */
-		return -ETIME;
-	}
-
-	switch (virt_dev->cmd_status) {
-	case COMP_CTX_STATE:
-	case COMP_EBADSLT:
-		xhci_err(xhci, "Setup ERROR: address device command for slot %d.\n",
-				udev->slot_id);
-		ret = -EINVAL;
-		break;
-	case COMP_TX_ERR:
-		dev_warn(&udev->dev, "Device not responding to set address.\n");
-		ret = -EPROTO;
-		break;
-	case COMP_SUCCESS:
-		xhci_dbg(xhci, "Successful Address Device command\n");
-		break;
-	default:
-		xhci_err(xhci, "ERROR: unexpected command completion "
-				"code 0x%x.\n", virt_dev->cmd_status);
-		xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id);
-		xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2);
-		ret = -EINVAL;
-		break;
-	}
-	if (ret) {
-		return ret;
-	}
-	temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr);
-	xhci_dbg(xhci, "Op regs DCBAA ptr = %#016llx\n", temp_64);
-	xhci_dbg(xhci, "Slot ID %d dcbaa entry @%p = %#016llx\n",
-			udev->slot_id,
-			&xhci->dcbaa->dev_context_ptrs[udev->slot_id],
-			(unsigned long long)
-				xhci->dcbaa->dev_context_ptrs[udev->slot_id]);
-	xhci_dbg(xhci, "Output Context DMA address = %#08llx\n",
-			(unsigned long long)virt_dev->out_ctx->dma);
-	xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
-	xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
-	xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id);
-	xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2);
-	/*
-	 * USB core uses address 1 for the roothubs, so we add one to the
-	 * address given back to us by the HC.
-	 */
-	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx);
-	udev->devnum = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1;
-	/* Zero the input context control for later use */
-	ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
-	ctrl_ctx->add_flags = 0;
-	ctrl_ctx->drop_flags = 0;
-
-	xhci_dbg(xhci, "Device address = %d\n", udev->devnum);
-	/* XXX Meh, not sure if anyone else but choose_address uses this. */
-	set_bit(udev->devnum, udev->bus->devmap.devicemap);
-
-	return 0;
-}
-
-/* Once a hub descriptor is fetched for a device, we need to update the xHC's
- * internal data structures for the device.
- */
-int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
-			struct usb_tt *tt, gfp_t mem_flags)
-{
-	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	struct xhci_virt_device *vdev;
-	struct xhci_command *config_cmd;
-	struct xhci_input_control_ctx *ctrl_ctx;
-	struct xhci_slot_ctx *slot_ctx;
-	unsigned long flags;
-	unsigned think_time;
-	int ret;
-
-	/* Ignore root hubs */
-	if (!hdev->parent)
-		return 0;
-
-	vdev = xhci->devs[hdev->slot_id];
-	if (!vdev) {
-		xhci_warn(xhci, "Cannot update hub desc for unknown device.\n");
-		return -EINVAL;
-	}
-	config_cmd = xhci_alloc_command(xhci, true, mem_flags);
-	if (!config_cmd) {
-		xhci_dbg(xhci, "Could not allocate xHCI command structure.\n");
-		return -ENOMEM;
-	}
-
-	spin_lock_irqsave(&xhci->lock, flags);
-	xhci_slot_copy(xhci, config_cmd->in_ctx, vdev->out_ctx);
-	ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx);
-	ctrl_ctx->add_flags |= SLOT_FLAG;
-	slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx);
-	slot_ctx->dev_info |= DEV_HUB;
-	if (tt->multi)
-		slot_ctx->dev_info |= DEV_MTT;
-	if (xhci->hci_version > 0x95) {
-		xhci_dbg(xhci, "xHCI version %x needs hub "
-				"TT think time and number of ports\n",
-				(unsigned int) xhci->hci_version);
-		slot_ctx->dev_info2 |= XHCI_MAX_PORTS(hdev->maxchild);
-		/* Set TT think time - convert from ns to FS bit times.
-		 * 0 = 8 FS bit times, 1 = 16 FS bit times,
-		 * 2 = 24 FS bit times, 3 = 32 FS bit times.
-		 */
-		think_time = tt->think_time;
-		if (think_time != 0)
-			think_time = (think_time / 666) - 1;
-		slot_ctx->tt_info |= TT_THINK_TIME(think_time);
-	} else {
-		xhci_dbg(xhci, "xHCI version %x doesn't need hub "
-				"TT think time or number of ports\n",
-				(unsigned int) xhci->hci_version);
-	}
-	slot_ctx->dev_state = 0;
-	spin_unlock_irqrestore(&xhci->lock, flags);
-
-	xhci_dbg(xhci, "Set up %s for hub device.\n",
-			(xhci->hci_version > 0x95) ?
-			"configure endpoint" : "evaluate context");
-	xhci_dbg(xhci, "Slot %u Input Context:\n", hdev->slot_id);
-	xhci_dbg_ctx(xhci, config_cmd->in_ctx, 0);
-
-	/* Issue and wait for the configure endpoint or
-	 * evaluate context command.
-	 */
-	if (xhci->hci_version > 0x95)
-		ret = xhci_configure_endpoint(xhci, hdev, config_cmd,
-				false, false);
-	else
-		ret = xhci_configure_endpoint(xhci, hdev, config_cmd,
-				true, false);
-
-	xhci_dbg(xhci, "Slot %u Output Context:\n", hdev->slot_id);
-	xhci_dbg_ctx(xhci, vdev->out_ctx, 0);
-
-	xhci_free_command(xhci, config_cmd);
-	return ret;
-}
-
-int xhci_get_frame(struct usb_hcd *hcd)
-{
-	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	/* EHCI mods by the periodic size.  Why? */
-	return xhci_readl(xhci, &xhci->run_regs->microframe_index) >> 3;
-}
-
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_LICENSE("GPL");
-
-static int __init xhci_hcd_init(void)
-{
-#ifdef CONFIG_PCI
-	int retval = 0;
-
-	retval = xhci_register_pci();
-
-	if (retval < 0) {
-		printk(KERN_DEBUG "Problem registering PCI driver.");
-		return retval;
-	}
-#endif
-	/*
-	 * Check the compiler generated sizes of structures that must be laid
-	 * out in specific ways for hardware access.
-	 */
-	BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8);
-	BUILD_BUG_ON(sizeof(struct xhci_slot_ctx) != 8*32/8);
-	BUILD_BUG_ON(sizeof(struct xhci_ep_ctx) != 8*32/8);
-	/* xhci_device_control has eight fields, and also
-	 * embeds one xhci_slot_ctx and 31 xhci_ep_ctx
-	 */
-	BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8);
-	BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8);
-	BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8);
-	BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 7*32/8);
-	BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8);
-	/* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */
-	BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8);
-	BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8);
-	return 0;
-}
-module_init(xhci_hcd_init);
-
-static void __exit xhci_hcd_cleanup(void)
-{
-#ifdef CONFIG_PCI
-	xhci_unregister_pci();
-#endif
-}
-module_exit(xhci_hcd_cleanup);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/xhci-hub.c linux-libre-2.6.34-gnu1/drivers/usb/host/xhci-hub.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/xhci-hub.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/xhci-hub.c	2010-05-16 17:17:36.000000000 -0400
@@ -129,6 +129,50 @@ static u32 xhci_port_state_to_neutral(u3
 	return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS);
 }
 
+static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex,
+		u32 __iomem *addr, u32 port_status)
+{
+	/* Write 1 to disable the port */
+	xhci_writel(xhci, port_status | PORT_PE, addr);
+	port_status = xhci_readl(xhci, addr);
+	xhci_dbg(xhci, "disable port, actual port %d status  = 0x%x\n",
+			wIndex, port_status);
+}
+
+static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
+		u16 wIndex, u32 __iomem *addr, u32 port_status)
+{
+	char *port_change_bit;
+	u32 status;
+
+	switch (wValue) {
+	case USB_PORT_FEAT_C_RESET:
+		status = PORT_RC;
+		port_change_bit = "reset";
+		break;
+	case USB_PORT_FEAT_C_CONNECTION:
+		status = PORT_CSC;
+		port_change_bit = "connect";
+		break;
+	case USB_PORT_FEAT_C_OVER_CURRENT:
+		status = PORT_OCC;
+		port_change_bit = "over-current";
+		break;
+	case USB_PORT_FEAT_C_ENABLE:
+		status = PORT_PEC;
+		port_change_bit = "enable/disable";
+		break;
+	default:
+		/* Should never happen */
+		return;
+	}
+	/* Change bits are all write 1 to clear */
+	xhci_writel(xhci, port_status | status, addr);
+	port_status = xhci_readl(xhci, addr);
+	xhci_dbg(xhci, "clear port %s change, actual port %d status  = 0x%x\n",
+			port_change_bit, wIndex, port_status);
+}
+
 int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		u16 wIndex, char *buf, u16 wLength)
 {
@@ -138,7 +182,6 @@ int xhci_hub_control(struct usb_hcd *hcd
 	u32 temp, status;
 	int retval = 0;
 	u32 __iomem *addr;
-	char *port_change_bit;
 
 	ports = HCS_MAX_PORTS(xhci->hcs_params1);
 
@@ -229,26 +272,18 @@ int xhci_hub_control(struct usb_hcd *hcd
 		temp = xhci_port_state_to_neutral(temp);
 		switch (wValue) {
 		case USB_PORT_FEAT_C_RESET:
-			status = PORT_RC;
-			port_change_bit = "reset";
-			break;
 		case USB_PORT_FEAT_C_CONNECTION:
-			status = PORT_CSC;
-			port_change_bit = "connect";
-			break;
 		case USB_PORT_FEAT_C_OVER_CURRENT:
-			status = PORT_OCC;
-			port_change_bit = "over-current";
+		case USB_PORT_FEAT_C_ENABLE:
+			xhci_clear_port_change_bit(xhci, wValue, wIndex,
+					addr, temp);
+			break;
+		case USB_PORT_FEAT_ENABLE:
+			xhci_disable_port(xhci, wIndex, addr, temp);
 			break;
 		default:
 			goto error;
 		}
-		/* Change bits are all write 1 to clear */
-		xhci_writel(xhci, temp | status, addr);
-		temp = xhci_readl(xhci, addr);
-		xhci_dbg(xhci, "clear port %s change, actual port %d status  = 0x%x\n",
-				port_change_bit, wIndex, temp);
-		temp = xhci_readl(xhci, addr); /* unblock any posted writes */
 		break;
 	default:
 error:
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/xhci-mem.c linux-libre-2.6.34-gnu1/drivers/usb/host/xhci-mem.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/xhci-mem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/xhci-mem.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/usb.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/dmapool.h>
 
 #include "xhci.h"
@@ -198,6 +199,31 @@ fail:
 	return 0;
 }
 
+void xhci_free_or_cache_endpoint_ring(struct xhci_hcd *xhci,
+		struct xhci_virt_device *virt_dev,
+		unsigned int ep_index)
+{
+	int rings_cached;
+
+	rings_cached = virt_dev->num_rings_cached;
+	if (rings_cached < XHCI_MAX_RINGS_CACHED) {
+		virt_dev->num_rings_cached++;
+		rings_cached = virt_dev->num_rings_cached;
+		virt_dev->ring_cache[rings_cached] =
+			virt_dev->eps[ep_index].ring;
+		xhci_dbg(xhci, "Cached old ring, "
+				"%d ring%s cached\n",
+				rings_cached,
+				(rings_cached > 1) ? "s" : "");
+	} else {
+		xhci_ring_free(xhci, virt_dev->eps[ep_index].ring);
+		xhci_dbg(xhci, "Ring cache full (%d rings), "
+				"freeing ring\n",
+				virt_dev->num_rings_cached);
+	}
+	virt_dev->eps[ep_index].ring = NULL;
+}
+
 /* Zero an endpoint ring (except for link TRBs) and move the enqueue and dequeue
  * pointers to the beginning of the ring.
  */
@@ -242,6 +268,8 @@ struct xhci_container_ctx *xhci_alloc_co
 void xhci_free_container_ctx(struct xhci_hcd *xhci,
 			     struct xhci_container_ctx *ctx)
 {
+	if (!ctx)
+		return;
 	dma_pool_free(xhci->device_pool, ctx->bytes, ctx->dma);
 	kfree(ctx);
 }
@@ -427,7 +455,7 @@ int xhci_setup_addressable_virt_dev(stru
 	case USB_SPEED_LOW:
 		slot_ctx->dev_info |= (u32) SLOT_SPEED_LS;
 		break;
-	case USB_SPEED_VARIABLE:
+	case USB_SPEED_WIRELESS:
 		xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n");
 		return -EINVAL;
 		break;
@@ -471,7 +499,7 @@ int xhci_setup_addressable_virt_dev(stru
 	case USB_SPEED_LOW:
 		ep0_ctx->ep_info2 |= MAX_PACKET(8);
 		break;
-	case USB_SPEED_VARIABLE:
+	case USB_SPEED_WIRELESS:
 		xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n");
 		return -EINVAL;
 		break;
@@ -539,8 +567,13 @@ static inline unsigned int xhci_get_endp
 			if (interval < 3)
 				interval = 3;
 			if ((1 << interval) != 8*ep->desc.bInterval)
-				dev_warn(&udev->dev, "ep %#x - rounding interval to %d microframes\n",
-						ep->desc.bEndpointAddress, 1 << interval);
+				dev_warn(&udev->dev,
+						"ep %#x - rounding interval"
+						" to %d microframes, "
+						"ep desc says %d microframes\n",
+						ep->desc.bEndpointAddress,
+						1 << interval,
+						8*ep->desc.bInterval);
 		}
 		break;
 	default:
@@ -549,6 +582,19 @@ static inline unsigned int xhci_get_endp
 	return EP_INTERVAL(interval);
 }
 
+/* The "Mult" field in the endpoint context is only set for SuperSpeed devices.
+ * High speed endpoint descriptors can define "the number of additional
+ * transaction opportunities per microframe", but that goes in the Max Burst
+ * endpoint context field.
+ */
+static inline u32 xhci_get_endpoint_mult(struct usb_device *udev,
+		struct usb_host_endpoint *ep)
+{
+	if (udev->speed != USB_SPEED_SUPER || !ep->ss_ep_comp)
+		return 0;
+	return ep->ss_ep_comp->desc.bmAttributes;
+}
+
 static inline u32 xhci_get_endpoint_type(struct usb_device *udev,
 		struct usb_host_endpoint *ep)
 {
@@ -579,6 +625,36 @@ static inline u32 xhci_get_endpoint_type
 	return type;
 }
 
+/* Return the maximum endpoint service interval time (ESIT) payload.
+ * Basically, this is the maxpacket size, multiplied by the burst size
+ * and mult size.
+ */
+static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci,
+		struct usb_device *udev,
+		struct usb_host_endpoint *ep)
+{
+	int max_burst;
+	int max_packet;
+
+	/* Only applies for interrupt or isochronous endpoints */
+	if (usb_endpoint_xfer_control(&ep->desc) ||
+			usb_endpoint_xfer_bulk(&ep->desc))
+		return 0;
+
+	if (udev->speed == USB_SPEED_SUPER) {
+		if (ep->ss_ep_comp)
+			return ep->ss_ep_comp->desc.wBytesPerInterval;
+		xhci_warn(xhci, "WARN no SS endpoint companion descriptor.\n");
+		/* Assume no bursts, no multiple opportunities to send. */
+		return ep->desc.wMaxPacketSize;
+	}
+
+	max_packet = ep->desc.wMaxPacketSize & 0x3ff;
+	max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11;
+	/* A 0 in max burst means 1 transfer per ESIT */
+	return max_packet * (max_burst + 1);
+}
+
 int xhci_endpoint_init(struct xhci_hcd *xhci,
 		struct xhci_virt_device *virt_dev,
 		struct usb_device *udev,
@@ -590,6 +666,7 @@ int xhci_endpoint_init(struct xhci_hcd *
 	struct xhci_ring *ep_ring;
 	unsigned int max_packet;
 	unsigned int max_burst;
+	u32 max_esit_payload;
 
 	ep_index = xhci_get_endpoint_index(&ep->desc);
 	ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
@@ -611,6 +688,7 @@ int xhci_endpoint_init(struct xhci_hcd *
 	ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state;
 
 	ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep);
+	ep_ctx->ep_info |= EP_MULT(xhci_get_endpoint_mult(udev, ep));
 
 	/* FIXME dig Mult and streams info out of ep companion desc */
 
@@ -656,6 +734,26 @@ int xhci_endpoint_init(struct xhci_hcd *
 	default:
 		BUG();
 	}
+	max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep);
+	ep_ctx->tx_info = MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload);
+
+	/*
+	 * XXX no idea how to calculate the average TRB buffer length for bulk
+	 * endpoints, as the driver gives us no clue how big each scatter gather
+	 * list entry (or buffer) is going to be.
+	 *
+	 * For isochronous and interrupt endpoints, we set it to the max
+	 * available, until we have new API in the USB core to allow drivers to
+	 * declare how much bandwidth they actually need.
+	 *
+	 * Normally, it would be calculated by taking the total of the buffer
+	 * lengths in the TD and then dividing by the number of TRBs in a TD,
+	 * including link TRBs, No-op TRBs, and Event data TRBs.  Since we don't
+	 * use Event Data TRBs, and we don't chain in a link TRB on short
+	 * transfers, we're basically dividing by 1.
+	 */
+	ep_ctx->tx_info |= AVG_TRB_LENGTH_FOR_EP(max_esit_payload);
+
 	/* FIXME Debug endpoint context */
 	return 0;
 }
@@ -819,7 +917,8 @@ static void scratchpad_free(struct xhci_
 }
 
 struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci,
-		bool allocate_completion, gfp_t mem_flags)
+		bool allocate_in_ctx, bool allocate_completion,
+		gfp_t mem_flags)
 {
 	struct xhci_command *command;
 
@@ -827,11 +926,14 @@ struct xhci_command *xhci_alloc_command(
 	if (!command)
 		return NULL;
 
-	command->in_ctx =
-		xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_INPUT, mem_flags);
-	if (!command->in_ctx) {
-		kfree(command);
-		return NULL;
+	if (allocate_in_ctx) {
+		command->in_ctx =
+			xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_INPUT,
+					mem_flags);
+		if (!command->in_ctx) {
+			kfree(command);
+			return NULL;
+		}
 	}
 
 	if (allocate_completion) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/xhci-pci.c linux-libre-2.6.34-gnu1/drivers/usb/host/xhci-pci.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/xhci-pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/xhci-pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -139,6 +139,7 @@ static const struct hc_driver xhci_pci_h
 	.reset_bandwidth =	xhci_reset_bandwidth,
 	.address_device =	xhci_address_device,
 	.update_hub_device =	xhci_update_hub_device,
+	.reset_device =		xhci_reset_device,
 
 	/*
 	 * scheduling support
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/host/xhci-ring.c linux-libre-2.6.34-gnu1/drivers/usb/host/xhci-ring.c
--- linux-libre-2.6.33-gnu1/drivers/usb/host/xhci-ring.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/host/xhci-ring.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,6 +65,7 @@
  */
 
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include "xhci.h"
 
 /*
@@ -953,6 +954,17 @@ bandwidth_change:
 	case TRB_TYPE(TRB_RESET_EP):
 		handle_reset_ep_completion(xhci, event, xhci->cmd_ring->dequeue);
 		break;
+	case TRB_TYPE(TRB_RESET_DEV):
+		xhci_dbg(xhci, "Completed reset device command.\n");
+		slot_id = TRB_TO_SLOT_ID(
+				xhci->cmd_ring->dequeue->generic.field[3]);
+		virt_dev = xhci->devs[slot_id];
+		if (virt_dev)
+			handle_cmd_in_cmd_wait_list(xhci, virt_dev, event);
+		else
+			xhci_warn(xhci, "Reset device command completion "
+					"for disabled slot %u\n", slot_id);
+		break;
 	default:
 		/* Skip over unknown commands on the event ring */
 		xhci->error_bitmask |= 1 << 6;
@@ -1080,6 +1092,20 @@ static int xhci_requires_manual_halt_cle
 	return 0;
 }
 
+int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code)
+{
+	if (trb_comp_code >= 224 && trb_comp_code <= 255) {
+		/* Vendor defined "informational" completion code,
+		 * treat as not-an-error.
+		 */
+		xhci_dbg(xhci, "Vendor defined info completion code %u\n",
+				trb_comp_code);
+		xhci_dbg(xhci, "Treating code as success.\n");
+		return 1;
+	}
+	return 0;
+}
+
 /*
  * If this function returns an error condition, it means it got a Transfer
  * event with a corrupted Slot ID, Endpoint ID, or TRB DMA address.
@@ -1196,13 +1222,7 @@ static int handle_tx_event(struct xhci_h
 		status = -ENOSR;
 		break;
 	default:
-		if (trb_comp_code >= 224 && trb_comp_code <= 255) {
-			/* Vendor defined "informational" completion code,
-			 * treat as not-an-error.
-			 */
-			xhci_dbg(xhci, "Vendor defined info completion code %u\n",
-					trb_comp_code);
-			xhci_dbg(xhci, "Treating code as success.\n");
+		if (xhci_is_vendor_info_code(xhci, trb_comp_code)) {
 			status = 0;
 			break;
 		}
@@ -2181,6 +2201,14 @@ int xhci_queue_address_device(struct xhc
 			false);
 }
 
+/* Queue a reset device command TRB */
+int xhci_queue_reset_device(struct xhci_hcd *xhci, u32 slot_id)
+{
+	return queue_command(xhci, 0, 0, 0,
+			TRB_TYPE(TRB_RESET_DEV) | SLOT_ID_FOR_TRB(slot_id),
+			false);
+}
+
 /* Queue a configure endpoint command TRB */
 int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
 		u32 slot_id, bool command_must_succeed)
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/image/mdc800.c linux-libre-2.6.34-gnu1/drivers/usb/image/mdc800.c
--- linux-libre-2.6.33-gnu1/drivers/usb/image/mdc800.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/image/mdc800.c	2010-05-16 17:17:36.000000000 -0400
@@ -967,7 +967,7 @@ static const struct file_operations mdc8
 
 
 
-static struct usb_device_id mdc800_table [] = {
+static const struct usb_device_id mdc800_table[] = {
 	{ USB_DEVICE(MDC800_VENDOR_ID, MDC800_PRODUCT_ID) },
 	{ }						/* Terminating entry */
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/image/microtek.c linux-libre-2.6.34-gnu1/drivers/usb/image/microtek.c
--- linux-libre-2.6.33-gnu1/drivers/usb/image/microtek.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/image/microtek.c	2010-05-16 17:17:36.000000000 -0400
@@ -155,7 +155,7 @@ static int mts_usb_probe(struct usb_inte
 			 const struct usb_device_id *id);
 static void mts_usb_disconnect(struct usb_interface *intf);
 
-static struct usb_device_id mts_usb_ids [];
+static const struct usb_device_id mts_usb_ids[];
 
 static struct usb_driver mts_usb_driver = {
 	.name =		"microtekX6",
@@ -656,7 +656,7 @@ static struct scsi_host_template mts_scs
 /* The entries of microtek_table must correspond, line-by-line to
    the entries of mts_supported_products[]. */
 
-static struct usb_device_id mts_usb_ids [] =
+static const struct usb_device_id mts_usb_ids[] =
 {
 	{ USB_DEVICE(0x4ce, 0x0300) },
 	{ USB_DEVICE(0x5da, 0x0094) },
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/Kconfig linux-libre-2.6.34-gnu1/drivers/usb/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/usb/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@ config USB_ARCH_HAS_HCD
 	default y if USB_ARCH_HAS_EHCI
 	default y if PCMCIA && !M32R			# sl811_cs
 	default y if ARM				# SL-811
+	default y if BLACKFIN				# SL-811
 	default y if SUPERH				# r8a66597-hcd
 	default PCI
 
@@ -39,6 +40,7 @@ config USB_ARCH_HAS_OHCI
 	default y if ARCH_PNX4008 && I2C
 	default y if MFD_TC6393XB
 	default y if ARCH_W90X900
+	default y if ARCH_DAVINCI_DA8XX
 	# PPC:
 	default y if STB03xxx
 	default y if PPC_MPC52xx
@@ -61,7 +63,7 @@ config USB_ARCH_HAS_EHCI
 	default y if ARCH_W90X900
 	default y if ARCH_AT91SAM9G45
 	default y if ARCH_MXC
-	default y if ARCH_OMAP34XX
+	default y if ARCH_OMAP3
 	default PCI
 
 # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/Makefile linux-libre-2.6.34-gnu1/drivers/usb/Makefile
--- linux-libre-2.6.33-gnu1/drivers/usb/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@ obj-$(CONFIG_USB_U132_HCD)	+= host/
 obj-$(CONFIG_USB_R8A66597_HCD)	+= host/
 obj-$(CONFIG_USB_HWA_HCD)	+= host/
 obj-$(CONFIG_USB_ISP1760_HCD)	+= host/
+obj-$(CONFIG_USB_IMX21_HCD)	+= host/
 
 obj-$(CONFIG_USB_C67X00_HCD)	+= c67x00/
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/adutux.c linux-libre-2.6.34-gnu1/drivers/usb/misc/adutux.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/adutux.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/adutux.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,7 +38,7 @@ static int debug = 1;
 #define dbg(lvl, format, arg...) 					\
 do { 									\
 	if (debug >= lvl)						\
-		printk(KERN_DEBUG __FILE__ " : " format " \n", ## arg);	\
+		printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg);	\
 } while (0)
 
 
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(debug, "Debug enabled o
 #define ADU_PRODUCT_ID 0x0064
 
 /* table of devices that work with this driver */
-static struct usb_device_id device_table [] = {
+static const struct usb_device_id device_table[] = {
 	{ USB_DEVICE(ADU_VENDOR_ID, ADU_PRODUCT_ID) },		/* ADU100 */
 	{ USB_DEVICE(ADU_VENDOR_ID, ADU_PRODUCT_ID+20) }, 	/* ADU120 */
 	{ USB_DEVICE(ADU_VENDOR_ID, ADU_PRODUCT_ID+30) }, 	/* ADU130 */
@@ -132,8 +132,8 @@ static void adu_debug_data(int level, co
 	if (debug < level)
 		return;
 
-	printk(KERN_DEBUG __FILE__": %s - length = %d, data = ",
-	       function, size);
+	printk(KERN_DEBUG "%s: %s - length = %d, data = ",
+	       __FILE__, function, size);
 	for (i = 0; i < size; ++i)
 		printk("%.2x ", data[i]);
 	printk("\n");
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/appledisplay.c linux-libre-2.6.34-gnu1/drivers/usb/misc/appledisplay.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/appledisplay.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/appledisplay.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/backlight.h>
 #include <linux/timer.h>
@@ -57,7 +58,7 @@
 	.bInterfaceProtocol = 0x00
 
 /* table of devices that work with this driver */
-static struct usb_device_id appledisplay_table [] = {
+static const struct usb_device_id appledisplay_table[] = {
 	{ APPLEDISPLAY_DEVICE(0x9218) },
 	{ APPLEDISPLAY_DEVICE(0x9219) },
 	{ APPLEDISPLAY_DEVICE(0x921c) },
@@ -179,7 +180,7 @@ static int appledisplay_bl_get_brightnes
 		return pdata->msgdata[1];
 }
 
-static struct backlight_ops appledisplay_bl_data = {
+static const struct backlight_ops appledisplay_bl_data = {
 	.get_brightness	= appledisplay_bl_get_brightness,
 	.update_status	= appledisplay_bl_update_status,
 };
@@ -202,6 +203,7 @@ static void appledisplay_work(struct wor
 static int appledisplay_probe(struct usb_interface *iface,
 	const struct usb_device_id *id)
 {
+	struct backlight_properties props;
 	struct appledisplay *pdata;
 	struct usb_device *udev = interface_to_usbdev(iface);
 	struct usb_host_interface *iface_desc;
@@ -279,15 +281,16 @@ static int appledisplay_probe(struct usb
 	/* Register backlight device */
 	snprintf(bl_name, sizeof(bl_name), "appledisplay%d",
 		atomic_inc_return(&count_displays) - 1);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = 0xff;
 	pdata->bd = backlight_device_register(bl_name, NULL, pdata,
-						&appledisplay_bl_data);
+					      &appledisplay_bl_data, &props);
 	if (IS_ERR(pdata->bd)) {
 		dev_err(&iface->dev, "Backlight registration failed\n");
+		retval = PTR_ERR(pdata->bd);
 		goto error;
 	}
 
-	pdata->bd->props.max_brightness = 0xff;
-
 	/* Try to get brightness */
 	brightness = appledisplay_bl_get_brightness(pdata->bd);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/berry_charge.c linux-libre-2.6.34-gnu1/drivers/usb/misc/berry_charge.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/berry_charge.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/berry_charge.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,183 +0,0 @@
-/*
- * USB BlackBerry charging module
- *
- * Copyright (C) 2007 Greg Kroah-Hartman <gregkh@suse.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, version 2.
- *
- * Information on how to switch configs was taken by the bcharge.cc file
- * created by the barry.sf.net project.
- *
- * bcharge.cc has the following copyright:
- * 	Copyright (C) 2006, Net Direct Inc. (http://www.netdirect.ca/)
- * and is released under the GPLv2.
- *
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-
-#define RIM_VENDOR		0x0fca
-#define BLACKBERRY		0x0001
-#define BLACKBERRY_PEARL_DUAL   0x0004
-#define BLACKBERRY_PEARL        0x0006
-
-static int debug;
-static int pearl_dual_mode = 1;
-
-#ifdef dbg
-#undef dbg
-#endif
-#define dbg(dev, format, arg...)				\
-	if (debug)						\
-		dev_printk(KERN_DEBUG , dev , format , ## arg)
-
-static struct usb_device_id id_table [] = {
-	{ USB_DEVICE(RIM_VENDOR, BLACKBERRY) },
-	{ USB_DEVICE(RIM_VENDOR, BLACKBERRY_PEARL) },
-	{ USB_DEVICE(RIM_VENDOR, BLACKBERRY_PEARL_DUAL) },
-	{ },					/* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, id_table);
-
-static int magic_charge(struct usb_device *udev)
-{
-	char *dummy_buffer = kzalloc(2, GFP_KERNEL);
-	int retval;
-
-	if (!dummy_buffer)
-		return -ENOMEM;
-
-	/* send two magic commands and then set the configuration.  The device
-	 * will then reset itself with the new power usage and should start
-	 * charging. */
-
-	/* Note, with testing, it only seems that the first message is really
-	 * needed (at least for the 8700c), but to be safe, we emulate what
-	 * other operating systems seem to be sending to their device.  We
-	 * really need to get some specs for this device to be sure about what
-	 * is going on here.
-	 */
-	dbg(&udev->dev, "Sending first magic command\n");
-	retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-				 0xa5, 0xc0, 0, 1, dummy_buffer, 2, 100);
-	if (retval != 2) {
-		dev_err(&udev->dev, "First magic command failed: %d.\n",
-			retval);
-		goto exit;
-	}
-
-	dbg(&udev->dev, "Sending second magic command\n");
-	retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-				 0xa2, 0x40, 0, 1, dummy_buffer, 0, 100);
-	if (retval != 0) {
-		dev_err(&udev->dev, "Second magic command failed: %d.\n",
-			retval);
-		goto exit;
-	}
-
-	dbg(&udev->dev, "Calling set_configuration\n");
-	retval = usb_driver_set_configuration(udev, 1);
-	if (retval)
-		dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval);
-
-exit:
-	kfree(dummy_buffer);
-	return retval;
-}
-
-static int magic_dual_mode(struct usb_device *udev)
-{
-	char *dummy_buffer = kzalloc(2, GFP_KERNEL);
-	int retval;
-
-	if (!dummy_buffer)
-		return -ENOMEM;
-
-	/* send magic command so that the Blackberry Pearl device exposes
-	 * two interfaces: both the USB mass-storage one and one which can
-	 * be used for database access. */
-	dbg(&udev->dev, "Sending magic pearl command\n");
-	retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-				 0xa9, 0xc0, 1, 1, dummy_buffer, 2, 100);
-	dbg(&udev->dev, "Magic pearl command returned %d\n", retval);
-
-	dbg(&udev->dev, "Calling set_configuration\n");
-	retval = usb_driver_set_configuration(udev, 1);
-	if (retval)
-		dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval);
-
-	kfree(dummy_buffer);
-	return retval;
-}
-
-static int berry_probe(struct usb_interface *intf,
-		       const struct usb_device_id *id)
-{
-	struct usb_device *udev = interface_to_usbdev(intf);
-
-	if (udev->bus_mA < 500) {
-		dbg(&udev->dev, "Not enough power to charge available\n");
-		return -ENODEV;
-	}
-
-	dbg(&udev->dev, "Power is set to %dmA\n",
-	    udev->actconfig->desc.bMaxPower * 2);
-
-	/* check the power usage so we don't try to enable something that is
-	 * already enabled */
-	if ((udev->actconfig->desc.bMaxPower * 2) == 500) {
-		dbg(&udev->dev, "device is already charging, power is "
-		    "set to %dmA\n", udev->actconfig->desc.bMaxPower * 2);
-		return -ENODEV;
-	}
-
-	/* turn the power on */
-	magic_charge(udev);
-
-	if ((le16_to_cpu(udev->descriptor.idProduct) == BLACKBERRY_PEARL) &&
-	    (pearl_dual_mode))
-		magic_dual_mode(udev);
-
-	/* we don't really want to bind to the device, userspace programs can
-	 * handle the syncing just fine, so get outta here. */
-	return -ENODEV;
-}
-
-static void berry_disconnect(struct usb_interface *intf)
-{
-}
-
-static struct usb_driver berry_driver = {
-	.name =		"berry_charge",
-	.probe =	berry_probe,
-	.disconnect =	berry_disconnect,
-	.id_table =	id_table,
-};
-
-static int __init berry_init(void)
-{
-	return usb_register(&berry_driver);
-}
-
-static void __exit berry_exit(void)
-{
-	usb_deregister(&berry_driver);
-}
-
-module_init(berry_init);
-module_exit(berry_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>");
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug enabled or not");
-module_param(pearl_dual_mode, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(pearl_dual_mode, "Change Blackberry Pearl to run in dual mode");
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/cypress_cy7c63.c linux-libre-2.6.34-gnu1/drivers/usb/misc/cypress_cy7c63.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/cypress_cy7c63.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/cypress_cy7c63.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #define DRIVER_AUTHOR		"Oliver Bock (bock@tfh-berlin.de)"
@@ -56,7 +57,7 @@
 
 
 /* table of devices that work with this driver */
-static struct usb_device_id cypress_table [] = {
+static const struct usb_device_id cypress_table[] = {
 	{ USB_DEVICE(CYPRESS_VENDOR_ID, CYPRESS_PRODUCT_ID) },
 	{ }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/cytherm.c linux-libre-2.6.34-gnu1/drivers/usb/misc/cytherm.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/cytherm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/cytherm.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/usb.h>
 
@@ -27,7 +28,7 @@
 #define USB_SKEL_VENDOR_ID	0x04b4
 #define USB_SKEL_PRODUCT_ID	0x0002
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
 	{ }
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/emi26.c linux-libre-2.6.34-gnu1/drivers/usb/misc/emi26.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/emi26.c	2013-05-03 12:12:58.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/emi26.c	2013-05-03 09:52:30.000000000 -0400
@@ -245,7 +245,7 @@ wraperr:
 	return err;
 }
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(EMI26_VENDOR_ID, EMI26_PRODUCT_ID) },
 	{ USB_DEVICE(EMI26_VENDOR_ID, EMI26B_PRODUCT_ID) },
 	{ }                                             /* Terminating entry */
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/emi62.c linux-libre-2.6.34-gnu1/drivers/usb/misc/emi62.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/emi62.c	2013-05-03 12:13:00.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/emi62.c	2013-05-03 09:52:33.000000000 -0400
@@ -259,7 +259,7 @@ wraperr:
 	return err;
 }
 
-static __devinitdata struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] __devinitconst = {
 	{ USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) },
 	{ }                                             /* Terminating entry */
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/ftdi-elan.c linux-libre-2.6.34-gnu1/drivers/usb/misc/ftdi-elan.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/ftdi-elan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/ftdi-elan.c	2010-05-16 17:17:36.000000000 -0400
@@ -86,7 +86,7 @@ static struct list_head ftdi_static_list
 #define USB_FTDI_ELAN_VENDOR_ID 0x0403
 #define USB_FTDI_ELAN_PRODUCT_ID 0xd6ea
 /* table of devices that work with this driver*/
-static struct usb_device_id ftdi_elan_table[] = {
+static const struct usb_device_id ftdi_elan_table[] = {
         {USB_DEVICE(USB_FTDI_ELAN_VENDOR_ID, USB_FTDI_ELAN_PRODUCT_ID)},
         { /* Terminating entry */ }
 };
@@ -623,9 +623,12 @@ static void ftdi_elan_status_work(struct
 */
 static int ftdi_elan_open(struct inode *inode, struct file *file)
 {
-        int subminor = iminor(inode);
-        struct usb_interface *interface = usb_find_interface(&ftdi_elan_driver,
-                subminor);
+	int subminor;
+	struct usb_interface *interface;
+
+        subminor = iminor(inode);
+        interface = usb_find_interface(&ftdi_elan_driver, subminor);
+
         if (!interface) {
                 printk(KERN_ERR "can't find device for minor %d\n", subminor);
                 return -ENODEV;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/idmouse.c linux-libre-2.6.34-gnu1/drivers/usb/misc/idmouse.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/idmouse.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/idmouse.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,7 +48,7 @@
 #define ID_CHERRY  0x0010
 
 /* device ID table */
-static struct usb_device_id idmouse_table[] = {
+static const struct usb_device_id idmouse_table[] = {
 	{USB_DEVICE(ID_SIEMENS, ID_IDMOUSE)}, /* Siemens ID Mouse (Professional) */
 	{USB_DEVICE(ID_SIEMENS, ID_CHERRY )}, /* Cherry FingerTIP ID Board       */
 	{}                                    /* terminating null entry          */
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/iowarrior.c linux-libre-2.6.34-gnu1/drivers/usb/misc/iowarrior.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/iowarrior.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/iowarrior.c	2010-05-16 17:17:36.000000000 -0400
@@ -139,7 +139,7 @@ static int usb_set_report(struct usb_int
 /* driver registration */
 /*---------------------*/
 /* table of devices that work with this driver */
-static struct usb_device_id iowarrior_ids[] = {
+static const struct usb_device_id iowarrior_ids[] = {
 	{USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40)},
 	{USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24)},
 	{USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOWPV1)},
@@ -602,10 +602,12 @@ static int iowarrior_open(struct inode *
 
 	dbg("%s", __func__);
 
+	lock_kernel();
 	subminor = iminor(inode);
 
 	interface = usb_find_interface(&iowarrior_driver, subminor);
 	if (!interface) {
+		unlock_kernel();
 		err("%s - error, can't find device for minor %d", __func__,
 		    subminor);
 		return -ENODEV;
@@ -615,6 +617,7 @@ static int iowarrior_open(struct inode *
 	dev = usb_get_intfdata(interface);
 	if (!dev) {
 		mutex_unlock(&iowarrior_open_disc_lock);
+		unlock_kernel();
 		return -ENODEV;
 	}
 
@@ -641,6 +644,7 @@ static int iowarrior_open(struct inode *
 
 out:
 	mutex_unlock(&dev->mutex);
+	unlock_kernel();
 	return retval;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/isight_firmware.c linux-libre-2.6.34-gnu1/drivers/usb/misc/isight_firmware.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/isight_firmware.c	2013-05-03 12:13:02.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/isight_firmware.c	2013-05-03 09:52:34.000000000 -0400
@@ -25,8 +25,9 @@
 #include <linux/firmware.h>
 #include <linux/errno.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
-static struct usb_device_id id_table[] = {
+static const struct usb_device_id id_table[] = {
 	{USB_DEVICE(0x05ac, 0x8300)},
 	{},
 };
@@ -112,6 +113,8 @@ out:
 	return ret;
 }
 
+/*(DEBLOBBED)*/
+
 static void isight_firmware_disconnect(struct usb_interface *intf)
 {
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/Kconfig linux-libre-2.6.34-gnu1/drivers/usb/misc/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -87,17 +87,6 @@ config USB_LCD
 	  To compile this driver as a module, choose M here: the
 	  module will be called usblcd.
 
-config USB_BERRY_CHARGE
-	tristate "USB BlackBerry recharge support"
-	depends on USB
-	help
-	  Say Y here if you want to connect a BlackBerry device to your
-	  computer's USB port and have it automatically switch to "recharge"
-	  mode.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called berry_charge.
-
 config USB_LED
 	tristate "USB LED driver support"
 	depends on USB
@@ -242,17 +231,3 @@ config USB_ISIGHTFW
 	  driver beforehand. Tools for doing so are available at
 	  http://bersace03.free.fr
 
-config USB_VST
-	tristate "USB VST driver"
-	depends on USB
-	help
-	  This driver is intended for Vernier Software Technologies
-	  bulk usb devices such as their Ocean-Optics spectrometers or
-	  Labquest.
-	  It is a bulk channel driver with configurable read and write
-	  timeouts.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called vstusb.
-
-
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/ldusb.c linux-libre-2.6.34-gnu1/drivers/usb/misc/ldusb.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/ldusb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/ldusb.c	2010-05-16 17:17:36.000000000 -0400
@@ -69,7 +69,7 @@
 #endif
 
 /* table of devices that work with this driver */
-static struct usb_device_id ld_usb_table [] = {
+static const struct usb_device_id ld_usb_table[] = {
 	{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) },
 	{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) },
 	{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) },
@@ -798,7 +798,7 @@ static int __init ld_usb_init(void)
 	/* register this driver with the USB subsystem */
 	retval = usb_register(&ld_usb_driver);
 	if (retval)
-		err("usb_register failed for the "__FILE__" driver. Error number %d\n", retval);
+		err("usb_register failed for the %s driver. Error number %d\n", __FILE__, retval);
 
 	return retval;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/legousbtower.c linux-libre-2.6.34-gnu1/drivers/usb/misc/legousbtower.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/legousbtower.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/legousbtower.c	2010-05-16 17:17:36.000000000 -0400
@@ -95,8 +95,11 @@
 
 /* Use our own dbg macro */
 #undef dbg
-#define dbg(lvl, format, arg...) do { if (debug >= lvl) printk(KERN_DEBUG  __FILE__ ": " format "\n", ## arg); } while (0)
-
+#define dbg(lvl, format, arg...)					\
+do {									\
+	if (debug >= lvl)						\
+		printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg);	\
+} while (0)
 
 /* Version Information */
 #define DRIVER_VERSION "v0.96"
@@ -192,7 +195,7 @@ struct tower_get_version_reply {
 
 
 /* table of devices that work with this driver */
-static struct usb_device_id tower_table [] = {
+static const struct usb_device_id tower_table[] = {
 	{ USB_DEVICE(LEGO_USB_TOWER_VENDOR_ID, LEGO_USB_TOWER_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
@@ -302,7 +305,7 @@ static inline void lego_usb_tower_debug_
 	if (debug < level)
 		return;
 
-	printk (KERN_DEBUG __FILE__": %s - length = %d, data = ", function, size);
+	printk (KERN_DEBUG "%s: %s - length = %d, data = ", __FILE__, function, size);
 	for (i = 0; i < size; ++i) {
 		printk ("%.2x ", data[i]);
 	}
@@ -1055,7 +1058,7 @@ static int __init lego_usb_tower_init(vo
 	/* register this driver with the USB subsystem */
 	result = usb_register(&tower_driver);
 	if (result < 0) {
-		err("usb_register failed for the "__FILE__" driver. Error number %d", result);
+		err("usb_register failed for the %s driver. Error number %d", __FILE__, result);
 		retval = -1;
 		goto exit;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/Makefile linux-libre-2.6.34-gnu1/drivers/usb/misc/Makefile
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,6 @@
 
 obj-$(CONFIG_USB_ADUTUX)	+= adutux.o
 obj-$(CONFIG_USB_APPLEDISPLAY)	+= appledisplay.o
-obj-$(CONFIG_USB_BERRY_CHARGE)	+= berry_charge.o
 obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o
 obj-$(CONFIG_USB_CYTHERM)	+= cytherm.o
 obj-$(CONFIG_USB_EMI26)		+= emi26.o
@@ -23,7 +22,6 @@ obj-$(CONFIG_USB_TEST)		+= usbtest.o
 obj-$(CONFIG_USB_TRANCEVIBRATOR)	+= trancevibrator.o
 obj-$(CONFIG_USB_USS720)	+= uss720.o
 obj-$(CONFIG_USB_SEVSEG)	+= usbsevseg.o
-obj-$(CONFIG_USB_VST)		+= vstusb.o
 
 obj-$(CONFIG_USB_SISUSBVGA)	+= sisusbvga/
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/rio500.c linux-libre-2.6.34-gnu1/drivers/usb/misc/rio500.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/rio500.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/rio500.c	2010-05-16 17:17:36.000000000 -0400
@@ -78,10 +78,13 @@ static int open_rio(struct inode *inode,
 {
 	struct rio_usb_data *rio = &rio_instance;
 
+	/* against disconnect() */
+	lock_kernel();
 	mutex_lock(&(rio->lock));
 
 	if (rio->isopen || !rio->present) {
 		mutex_unlock(&(rio->lock));
+		unlock_kernel();
 		return -EBUSY;
 	}
 	rio->isopen = 1;
@@ -91,6 +94,7 @@ static int open_rio(struct inode *inode,
 	mutex_unlock(&(rio->lock));
 
 	dev_info(&rio->rio_dev->dev, "Rio opened.\n");
+	unlock_kernel();
 
 	return 0;
 }
@@ -115,7 +119,6 @@ static long ioctl_rio(struct file *file,
 	int retries;
 	int retval=0;
 
-	lock_kernel();
 	mutex_lock(&(rio->lock));
         /* Sanity check to make sure rio is connected, powered, etc */
         if (rio->present == 0 || rio->rio_dev == NULL) {
@@ -254,7 +257,6 @@ static long ioctl_rio(struct file *file,
 
 err_out:
 	mutex_unlock(&(rio->lock));
-	unlock_kernel();
 	return retval;
 }
 
@@ -489,6 +491,7 @@ static void disconnect_rio(struct usb_in
 	struct rio_usb_data *rio = usb_get_intfdata (intf);
 
 	usb_set_intfdata (intf, NULL);
+	lock_kernel();
 	if (rio) {
 		usb_deregister_dev(intf, &usb_rio_class);
 
@@ -498,6 +501,7 @@ static void disconnect_rio(struct usb_in
 			/* better let it finish - the release will do whats needed */
 			rio->rio_dev = NULL;
 			mutex_unlock(&(rio->lock));
+			unlock_kernel();
 			return;
 		}
 		kfree(rio->ibuf);
@@ -508,9 +512,10 @@ static void disconnect_rio(struct usb_in
 		rio->present = 0;
 		mutex_unlock(&(rio->lock));
 	}
+	unlock_kernel();
 }
 
-static struct usb_device_id rio_table [] = {
+static const struct usb_device_id rio_table[] = {
 	{ USB_DEVICE(0x0841, 1) }, 		/* Rio 500 */
 	{ }					/* Terminating entry */
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/sisusbvga/sisusb.c linux-libre-2.6.34-gnu1/drivers/usb/misc/sisusbvga/sisusb.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/sisusbvga/sisusb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/sisusbvga/sisusb.c	2010-05-16 17:17:36.000000000 -0400
@@ -250,7 +250,7 @@ sisusb_bulkout_msg(struct sisusb_usb_dat
 	sisusb->urbstatus[index] |= SU_URB_BUSY;
 
 	/* Submit URB */
-	retval = usb_submit_urb(urb, GFP_ATOMIC);
+	retval = usb_submit_urb(urb, GFP_KERNEL);
 
 	/* If OK, and if timeout > 0, wait for completion */
 	if ((retval == 0) && timeout) {
@@ -306,7 +306,7 @@ sisusb_bulkin_msg(struct sisusb_usb_data
 	urb->actual_length = 0;
 
 	sisusb->completein = 0;
-	retval = usb_submit_urb(urb, GFP_ATOMIC);
+	retval = usb_submit_urb(urb, GFP_KERNEL);
 	if (retval == 0) {
 		wait_event_timeout(sisusb->wait_q, sisusb->completein, timeout);
 		if (!sisusb->completein) {
@@ -2416,21 +2416,28 @@ sisusb_open(struct inode *inode, struct
 	struct usb_interface *interface;
 	int subminor = iminor(inode);
 
-	if (!(interface = usb_find_interface(&sisusb_driver, subminor)))
+	lock_kernel();
+	if (!(interface = usb_find_interface(&sisusb_driver, subminor))) {
+		unlock_kernel();
 		return -ENODEV;
+	}
 
-	if (!(sisusb = usb_get_intfdata(interface)))
+	if (!(sisusb = usb_get_intfdata(interface))) {
+		unlock_kernel();
 		return -ENODEV;
+	}
 
 	mutex_lock(&sisusb->lock);
 
 	if (!sisusb->present || !sisusb->ready) {
 		mutex_unlock(&sisusb->lock);
+		unlock_kernel();
 		return -ENODEV;
 	}
 
 	if (sisusb->isopen) {
 		mutex_unlock(&sisusb->lock);
+		unlock_kernel();
 		return -EBUSY;
 	}
 
@@ -2439,11 +2446,13 @@ sisusb_open(struct inode *inode, struct
 			if (sisusb_init_gfxdevice(sisusb, 0)) {
 				mutex_unlock(&sisusb->lock);
 				dev_err(&sisusb->sisusb_dev->dev, "Failed to initialize device\n");
+				unlock_kernel();
 				return -EIO;
 			}
 		} else {
 			mutex_unlock(&sisusb->lock);
 			dev_err(&sisusb->sisusb_dev->dev, "Device not attached to USB 2.0 hub\n");
+			unlock_kernel();
 			return -EIO;
 		}
 	}
@@ -2456,6 +2465,7 @@ sisusb_open(struct inode *inode, struct
 	file->private_data = sisusb;
 
 	mutex_unlock(&sisusb->lock);
+	unlock_kernel();
 
 	return 0;
 }
@@ -3238,7 +3248,7 @@ static void sisusb_disconnect(struct usb
 	kref_put(&sisusb->kref, sisusb_delete);
 }
 
-static struct usb_device_id sisusb_table [] = {
+static const struct usb_device_id sisusb_table[] = {
 	{ USB_DEVICE(0x0711, 0x0550) },
 	{ USB_DEVICE(0x0711, 0x0900) },
 	{ USB_DEVICE(0x0711, 0x0901) },
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/sisusbvga/sisusb_con.c linux-libre-2.6.34-gnu1/drivers/usb/misc/sisusbvga/sisusb_con.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/sisusbvga/sisusb_con.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/sisusbvga/sisusb_con.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,7 +58,6 @@
 #include <linux/string.h>
 #include <linux/kd.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/vt_kern.h>
 #include <linux/selection.h>
 #include <linux/spinlock.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/sisusbvga/sisusb_init.c linux-libre-2.6.34-gnu1/drivers/usb/misc/sisusbvga/sisusb_init.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/sisusbvga/sisusb_init.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/sisusbvga/sisusb_init.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,6 @@
 #include <linux/errno.h>
 #include <linux/poll.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 
 #include "sisusb.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/trancevibrator.c linux-libre-2.6.34-gnu1/drivers/usb/misc/trancevibrator.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/trancevibrator.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/trancevibrator.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/usb.h>
 
@@ -33,7 +34,7 @@
 #define TRANCEVIBRATOR_VENDOR_ID	0x0b49	/* ASCII Corporation */
 #define TRANCEVIBRATOR_PRODUCT_ID	0x064f	/* Trance Vibrator */
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(TRANCEVIBRATOR_VENDOR_ID, TRANCEVIBRATOR_PRODUCT_ID) },
 	{ },
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/usblcd.c linux-libre-2.6.34-gnu1/drivers/usb/misc/usblcd.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/usblcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/usblcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,7 @@
 #define IOCTL_GET_DRV_VERSION	2
 
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ .idVendor = 0x10D2, .match_flags = USB_DEVICE_ID_MATCH_VENDOR, },
 	{ },
 };
@@ -74,10 +74,12 @@ static int lcd_open(struct inode *inode,
 	struct usb_interface *interface;
 	int subminor, r;
 
+	lock_kernel();
 	subminor = iminor(inode);
 
 	interface = usb_find_interface(&lcd_driver, subminor);
 	if (!interface) {
+		unlock_kernel();
 		err ("USBLCD: %s - error, can't find device for minor %d",
 		     __func__, subminor);
 		return -ENODEV;
@@ -87,6 +89,7 @@ static int lcd_open(struct inode *inode,
 	dev = usb_get_intfdata(interface);
 	if (!dev) {
 		mutex_unlock(&open_disc_mutex);
+		unlock_kernel();
 		return -ENODEV;
 	}
 
@@ -98,11 +101,13 @@ static int lcd_open(struct inode *inode,
 	r = usb_autopm_get_interface(interface);
 	if (r < 0) {
 		kref_put(&dev->kref, lcd_delete);
+		unlock_kernel();
 		return r;
 	}
 
 	/* save our object in the file's private structure */
 	file->private_data = dev;
+	unlock_kernel();
 
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/usbled.c linux-libre-2.6.34-gnu1/drivers/usb/misc/usbled.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/usbled.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/usbled.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,7 @@
 #define PRODUCT_ID	0x1223
 
 /* table of devices that work with this driver */
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
 	{ },
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/usbsevseg.c linux-libre-2.6.34-gnu1/drivers/usb/misc/usbsevseg.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/usbsevseg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/usbsevseg.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,7 @@
 #define MAXLEN		6
 
 /* table of devices that work with this driver */
-static struct usb_device_id id_table[] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
 	{ },
 };
@@ -49,6 +49,7 @@ struct usb_sevsegdev {
 	u16 textlength;
 
 	u8 shadow_power; /* for PM */
+	u8 has_interface_pm;
 };
 
 /* sysfs_streq can't replace this completely
@@ -68,12 +69,16 @@ static void update_display_powered(struc
 {
 	int rc;
 
-	if (!mydev->shadow_power && mydev->powered) {
+	if (mydev->powered && !mydev->has_interface_pm) {
 		rc = usb_autopm_get_interface(mydev->intf);
 		if (rc < 0)
 			return;
+		mydev->has_interface_pm = 1;
 	}
 
+	if (mydev->shadow_power != 1)
+		return;
+
 	rc = usb_control_msg(mydev->udev,
 			usb_sndctrlpipe(mydev->udev, 0),
 			0x12,
@@ -86,8 +91,10 @@ static void update_display_powered(struc
 	if (rc < 0)
 		dev_dbg(&mydev->udev->dev, "power retval = %d\n", rc);
 
-	if (mydev->shadow_power && !mydev->powered)
+	if (!mydev->powered && mydev->has_interface_pm) {
 		usb_autopm_put_interface(mydev->intf);
+		mydev->has_interface_pm = 0;
+	}
 }
 
 static void update_display_mode(struct usb_sevsegdev *mydev)
@@ -351,6 +358,10 @@ static int sevseg_probe(struct usb_inter
 	mydev->intf = interface;
 	usb_set_intfdata(interface, mydev);
 
+	/* PM */
+	mydev->shadow_power = 1; /* currently active */
+	mydev->has_interface_pm = 0; /* have not issued autopm_get */
+
 	/*set defaults */
 	mydev->textmode = 0x02; /* ascii mode */
 	mydev->mode_msb = 0x06; /* 6 characters */
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/usbtest.c linux-libre-2.6.34-gnu1/drivers/usb/misc/usbtest.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/usbtest.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/usbtest.c	2010-05-16 17:17:36.000000000 -0400
@@ -1580,10 +1580,6 @@ usbtest_ioctl (struct usb_interface *int
 		return -ERESTARTSYS;
 
 	/* FIXME: What if a system sleep starts while a test is running? */
-	if (!intf->is_active) {
-		mutex_unlock(&dev->lock);
-		return -EHOSTUNREACH;
-	}
 
 	/* some devices, like ez-usb default devices, need a non-default
 	 * altsetting to have any active endpoints.  some tests change
@@ -2101,7 +2097,7 @@ static struct usbtest_info generic_info
 #endif
 
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 
 	/*-------------------------------------------------------------*/
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/uss720.c linux-libre-2.6.34-gnu1/drivers/usb/misc/uss720.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/uss720.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/uss720.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,7 @@
 #include <linux/delay.h>
 #include <linux/completion.h>
 #include <linux/kref.h>
+#include <linux/slab.h>
 
 /*
  * Version Information
@@ -770,7 +771,7 @@ static void uss720_disconnect(struct usb
 }
 
 /* table of cables that work through this driver */
-static struct usb_device_id uss720_table [] = {
+static const struct usb_device_id uss720_table[] = {
 	{ USB_DEVICE(0x047e, 0x1001) },
 	{ USB_DEVICE(0x0557, 0x2001) },
 	{ USB_DEVICE(0x0729, 0x1284) },
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/misc/vstusb.c linux-libre-2.6.34-gnu1/drivers/usb/misc/vstusb.c
--- linux-libre-2.6.33-gnu1/drivers/usb/misc/vstusb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/misc/vstusb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,783 +0,0 @@
-/*****************************************************************************
- *  File: drivers/usb/misc/vstusb.c
- *
- *  Purpose: Support for the bulk USB Vernier Spectrophotometers
- *
- *  Author:     Johnnie Peters
- *              Axian Consulting
- *              Beaverton, OR, USA 97005
- *
- *  Modified by:     EQware Engineering, Inc.
- *                   Oregon City, OR, USA 97045
- *
- *  Copyright:  2007, 2008
- *              Vernier Software & Technology
- *              Beaverton, OR, USA 97005
- *
- *  Web:        www.vernier.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/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-#include <linux/usb.h>
-
-#include <linux/usb/vstusb.h>
-
-#define DRIVER_VERSION "VST USB Driver Version 1.5"
-#define DRIVER_DESC "Vernier Software Technology Bulk USB Driver"
-
-#ifdef CONFIG_USB_DYNAMIC_MINORS
-	#define VSTUSB_MINOR_BASE	0
-#else
-	#define VSTUSB_MINOR_BASE	199
-#endif
-
-#define USB_VENDOR_OCEANOPTICS	0x2457
-#define USB_VENDOR_VERNIER	0x08F7	/* Vernier Software & Technology */
-
-#define USB_PRODUCT_USB2000	0x1002
-#define USB_PRODUCT_ADC1000_FW	0x1003	/* firmware download (renumerates) */
-#define USB_PRODUCT_ADC1000	0x1004
-#define USB_PRODUCT_HR2000_FW	0x1009	/* firmware download (renumerates) */
-#define USB_PRODUCT_HR2000	0x100A
-#define USB_PRODUCT_HR4000_FW	0x1011	/* firmware download (renumerates) */
-#define USB_PRODUCT_HR4000	0x1012
-#define USB_PRODUCT_USB650	0x1014	/* "Red Tide" */
-#define USB_PRODUCT_QE65000	0x1018
-#define USB_PRODUCT_USB4000	0x1022
-#define USB_PRODUCT_USB325	0x1024	/* "Vernier Spectrometer" */
-
-#define USB_PRODUCT_LABPRO	0x0001
-#define USB_PRODUCT_LABQUEST	0x0005
-
-#define VST_MAXBUFFER		(64*1024)
-
-static struct usb_device_id id_table[] = {
-	{ USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB2000)},
-	{ USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_HR4000)},
-	{ USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB650)},
-	{ USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB4000)},
-	{ USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB325)},
-	{ USB_DEVICE(USB_VENDOR_VERNIER, USB_PRODUCT_LABQUEST)},
-	{ USB_DEVICE(USB_VENDOR_VERNIER, USB_PRODUCT_LABPRO)},
-	{},
-};
-
-MODULE_DEVICE_TABLE(usb, id_table);
-
-struct vstusb_device {
-	struct kref				kref;
-	struct mutex            lock;
-	struct usb_device       *usb_dev;
-	char                    present;
-	char                    isopen;
-	struct usb_anchor       submitted;
-	int                     rd_pipe;
-	int                     rd_timeout_ms;
-	int                     wr_pipe;
-	int                     wr_timeout_ms;
-};
-#define to_vst_dev(d) container_of(d, struct vstusb_device, kref)
-
-static struct usb_driver vstusb_driver;
-
-static void vstusb_delete(struct kref *kref)
-{
-	struct vstusb_device *vstdev = to_vst_dev(kref);
-
-	usb_put_dev(vstdev->usb_dev);
-	kfree(vstdev);
-}
-
-static int vstusb_open(struct inode *inode, struct file *file)
-{
-	struct vstusb_device *vstdev;
-	struct usb_interface *interface;
-
-	interface = usb_find_interface(&vstusb_driver, iminor(inode));
-
-	if (!interface) {
-		printk(KERN_ERR KBUILD_MODNAME
-		       ": %s - error, can't find device for minor %d\n",
-		       __func__, iminor(inode));
-		return -ENODEV;
-	}
-
-	vstdev = usb_get_intfdata(interface);
-
-	if (!vstdev)
-		return -ENODEV;
-
-	/* lock this device */
-	mutex_lock(&vstdev->lock);
-
-	/* can only open one time */
-	if ((!vstdev->present) || (vstdev->isopen)) {
-		mutex_unlock(&vstdev->lock);
-		return -EBUSY;
-	}
-
-	/* increment our usage count */
-	kref_get(&vstdev->kref);
-
-	vstdev->isopen = 1;
-
-	/* save device in the file's private structure */
-	file->private_data = vstdev;
-
-	dev_dbg(&vstdev->usb_dev->dev, "%s: opened\n", __func__);
-
-	mutex_unlock(&vstdev->lock);
-
-	return 0;
-}
-
-static int vstusb_release(struct inode *inode, struct file *file)
-{
-	struct vstusb_device *vstdev;
-
-	vstdev = file->private_data;
-
-	if (vstdev == NULL)
-		return -ENODEV;
-
-	mutex_lock(&vstdev->lock);
-
-	vstdev->isopen = 0;
-
-	dev_dbg(&vstdev->usb_dev->dev, "%s: released\n", __func__);
-
-	mutex_unlock(&vstdev->lock);
-
-	kref_put(&vstdev->kref, vstusb_delete);
-
-	return 0;
-}
-
-static void usb_api_blocking_completion(struct urb *urb)
-{
-	struct completion *completeit = urb->context;
-
-	complete(completeit);
-}
-
-static int vstusb_fill_and_send_urb(struct urb *urb,
-				    struct usb_device *usb_dev,
-				    unsigned int pipe, void *data,
-				    unsigned int len, struct completion *done)
-{
-	struct usb_host_endpoint *ep;
-	struct usb_host_endpoint **hostep;
-	unsigned int pipend;
-
-	int status;
-
-	hostep = usb_pipein(pipe) ? usb_dev->ep_in : usb_dev->ep_out;
-	pipend = usb_pipeendpoint(pipe);
-	ep = hostep[pipend];
-
-	if (!ep || (len == 0))
-		return -EINVAL;
-
-	if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-	    == USB_ENDPOINT_XFER_INT) {
-		pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
-		usb_fill_int_urb(urb, usb_dev, pipe, data, len,
-				 (usb_complete_t)usb_api_blocking_completion,
-				 NULL, ep->desc.bInterval);
-	} else
-		usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
-				  (usb_complete_t)usb_api_blocking_completion,
-				  NULL);
-
-	init_completion(done);
-	urb->context = done;
-	urb->actual_length = 0;
-	status = usb_submit_urb(urb, GFP_KERNEL);
-
-	return status;
-}
-
-static int vstusb_complete_urb(struct urb *urb, struct completion *done,
-			       int timeout, int *actual_length)
-{
-	unsigned long expire;
-	int status;
-
-	expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;
-	if (!wait_for_completion_interruptible_timeout(done, expire)) {
-		usb_kill_urb(urb);
-		status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status;
-
-		dev_dbg(&urb->dev->dev,
-			"%s timed out on ep%d%s len=%d/%d, urb status = %d\n",
-			current->comm,
-			usb_pipeendpoint(urb->pipe),
-			usb_pipein(urb->pipe) ? "in" : "out",
-			urb->actual_length,
-			urb->transfer_buffer_length,
-			urb->status);
-
-	} else {
-		if (signal_pending(current)) {
-			/* if really an error */
-			if (urb->status && !((urb->status == -ENOENT)     ||
-					     (urb->status == -ECONNRESET) ||
-					     (urb->status == -ESHUTDOWN))) {
-				status = -EINTR;
-				usb_kill_urb(urb);
-			} else {
-				status = 0;
-			}
-
-			dev_dbg(&urb->dev->dev,
-				"%s: signal pending on ep%d%s len=%d/%d,"
-				"urb status = %d\n",
-				current->comm,
-				usb_pipeendpoint(urb->pipe),
-				usb_pipein(urb->pipe) ? "in" : "out",
-				urb->actual_length,
-				urb->transfer_buffer_length,
-				urb->status);
-
-		} else {
-			status = urb->status;
-		}
-	}
-
-	if (actual_length)
-		*actual_length = urb->actual_length;
-
-	return status;
-}
-
-static ssize_t vstusb_read(struct file *file, char __user *buffer,
-			   size_t count, loff_t *ppos)
-{
-	struct vstusb_device *vstdev;
-	int cnt = -1;
-	void *buf;
-	int retval = 0;
-
-	struct urb              *urb;
-	struct usb_device       *dev;
-	unsigned int            pipe;
-	int                     timeout;
-
-	DECLARE_COMPLETION_ONSTACK(done);
-
-	vstdev = file->private_data;
-
-	if (vstdev == NULL)
-		return -ENODEV;
-
-	/* verify that we actually want to read some data */
-	if ((count == 0) || (count > VST_MAXBUFFER))
-		return -EINVAL;
-
-	/* lock this object */
-	if (mutex_lock_interruptible(&vstdev->lock))
-		return -ERESTARTSYS;
-
-	/* anyone home */
-	if (!vstdev->present) {
-		mutex_unlock(&vstdev->lock);
-		printk(KERN_ERR KBUILD_MODNAME
-		       ": %s: device not present\n", __func__);
-		return -ENODEV;
-	}
-
-	/* pull out the necessary data */
-	dev =     vstdev->usb_dev;
-	pipe =    usb_rcvbulkpipe(dev, vstdev->rd_pipe);
-	timeout = vstdev->rd_timeout_ms;
-
-	buf = kmalloc(count, GFP_KERNEL);
-	if (buf == NULL) {
-		mutex_unlock(&vstdev->lock);
-		return -ENOMEM;
-	}
-
-	urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!urb) {
-		kfree(buf);
-		mutex_unlock(&vstdev->lock);
-		return -ENOMEM;
-	}
-
-	usb_anchor_urb(urb, &vstdev->submitted);
-	retval = vstusb_fill_and_send_urb(urb, dev, pipe, buf, count, &done);
-	mutex_unlock(&vstdev->lock);
-	if (retval) {
-		usb_unanchor_urb(urb);
-		dev_err(&dev->dev, "%s: error %d filling and sending urb %d\n",
-			__func__, retval, pipe);
-		goto exit;
-	}
-
-	retval = vstusb_complete_urb(urb, &done, timeout, &cnt);
-	if (retval) {
-		dev_err(&dev->dev, "%s: error %d completing urb %d\n",
-			__func__, retval, pipe);
-		goto exit;
-	}
-
-	if (copy_to_user(buffer, buf, cnt)) {
-		dev_err(&dev->dev, "%s: can't copy_to_user\n", __func__);
-		retval = -EFAULT;
-	} else {
-		retval = cnt;
-		dev_dbg(&dev->dev, "%s: read %d bytes from pipe %d\n",
-			__func__, cnt, pipe);
-	}
-
-exit:
-	usb_free_urb(urb);
-	kfree(buf);
-	return retval;
-}
-
-static ssize_t vstusb_write(struct file *file, const char __user *buffer,
-			    size_t count, loff_t *ppos)
-{
-	struct vstusb_device *vstdev;
-	int cnt = -1;
-	void *buf;
-	int retval = 0;
-
-	struct urb              *urb;
-	struct usb_device       *dev;
-	unsigned int            pipe;
-	int                     timeout;
-
-	DECLARE_COMPLETION_ONSTACK(done);
-
-	vstdev = file->private_data;
-
-	if (vstdev == NULL)
-		return -ENODEV;
-
-	/* verify that we actually have some data to write */
-	if ((count == 0) || (count > VST_MAXBUFFER))
-		return retval;
-
-	/* lock this object */
-	if (mutex_lock_interruptible(&vstdev->lock))
-		return -ERESTARTSYS;
-
-	/* anyone home */
-	if (!vstdev->present) {
-		mutex_unlock(&vstdev->lock);
-		printk(KERN_ERR KBUILD_MODNAME
-		       ": %s: device not present\n", __func__);
-		return -ENODEV;
-	}
-
-	/* pull out the necessary data */
-	dev =     vstdev->usb_dev;
-	pipe =    usb_sndbulkpipe(dev, vstdev->wr_pipe);
-	timeout = vstdev->wr_timeout_ms;
-
-	buf = kmalloc(count, GFP_KERNEL);
-	if (buf == NULL) {
-		mutex_unlock(&vstdev->lock);
-		return -ENOMEM;
-	}
-
-	urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!urb) {
-		kfree(buf);
-		mutex_unlock(&vstdev->lock);
-		return -ENOMEM;
-	}
-
-	if (copy_from_user(buf, buffer, count)) {
-		mutex_unlock(&vstdev->lock);
-		dev_err(&dev->dev, "%s: can't copy_from_user\n", __func__);
-		retval = -EFAULT;
-		goto exit;
-	}
-
-	usb_anchor_urb(urb, &vstdev->submitted);
-	retval = vstusb_fill_and_send_urb(urb, dev, pipe, buf, count, &done);
-	mutex_unlock(&vstdev->lock);
-	if (retval) {
-		usb_unanchor_urb(urb);
-		dev_err(&dev->dev, "%s: error %d filling and sending urb %d\n",
-			__func__, retval, pipe);
-		goto exit;
-	}
-
-	retval = vstusb_complete_urb(urb, &done, timeout, &cnt);
-	if (retval) {
-		dev_err(&dev->dev, "%s: error %d completing urb %d\n",
-			__func__, retval, pipe);
-		goto exit;
-	} else {
-		retval = cnt;
-		dev_dbg(&dev->dev, "%s: sent %d bytes to pipe %d\n",
-			__func__, cnt, pipe);
-	}
-
-exit:
-	usb_free_urb(urb);
-	kfree(buf);
-	return retval;
-}
-
-static long vstusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	int retval = 0;
-	int cnt = -1;
-	void __user *data = (void __user *)arg;
-	struct vstusb_args usb_data;
-
-	struct vstusb_device *vstdev;
-	void *buffer = NULL; /* must be initialized. buffer is
-			      *	referenced on exit but not all
-			      * ioctls allocate it */
-
-	struct urb              *urb = NULL; /* must be initialized. urb is
-					      *	referenced on exit but not all
-					      * ioctls allocate it */
-	struct usb_device       *dev;
-	unsigned int            pipe;
-	int                     timeout;
-
-	DECLARE_COMPLETION_ONSTACK(done);
-
-	vstdev = file->private_data;
-
-	if (_IOC_TYPE(cmd) != VST_IOC_MAGIC) {
-		dev_warn(&vstdev->usb_dev->dev,
-			 "%s: ioctl command %x, bad ioctl magic %x, "
-			 "expected %x\n", __func__, cmd,
-			 _IOC_TYPE(cmd), VST_IOC_MAGIC);
-		return -EINVAL;
-	}
-
-	if (vstdev == NULL)
-		return -ENODEV;
-
-	if (copy_from_user(&usb_data, data, sizeof(struct vstusb_args))) {
-		dev_err(&vstdev->usb_dev->dev, "%s: can't copy_from_user\n",
-			__func__);
-		return -EFAULT;
-	}
-
-	/* lock this object */
-	if (mutex_lock_interruptible(&vstdev->lock)) {
-		retval = -ERESTARTSYS;
-		goto exit;
-	}
-
-	/* anyone home */
-	if (!vstdev->present) {
-		mutex_unlock(&vstdev->lock);
-		dev_err(&vstdev->usb_dev->dev, "%s: device not present\n",
-			__func__);
-		retval = -ENODEV;
-		goto exit;
-	}
-
-	/* pull out the necessary data */
-	dev = vstdev->usb_dev;
-
-	switch (cmd) {
-
-	case IOCTL_VSTUSB_CONFIG_RW:
-
-		vstdev->rd_pipe = usb_data.rd_pipe;
-		vstdev->rd_timeout_ms = usb_data.rd_timeout_ms;
-		vstdev->wr_pipe = usb_data.wr_pipe;
-		vstdev->wr_timeout_ms = usb_data.wr_timeout_ms;
-
-		mutex_unlock(&vstdev->lock);
-
-		dev_dbg(&dev->dev, "%s: setting pipes/timeouts, "
-			"rdpipe = %d, rdtimeout = %d, "
-			"wrpipe = %d, wrtimeout = %d\n", __func__,
-			vstdev->rd_pipe, vstdev->rd_timeout_ms,
-			vstdev->wr_pipe, vstdev->wr_timeout_ms);
-		break;
-
-	case IOCTL_VSTUSB_SEND_PIPE:
-
-		if ((usb_data.count == 0) || (usb_data.count > VST_MAXBUFFER)) {
-			mutex_unlock(&vstdev->lock);
-			retval = -EINVAL;
-			goto exit;
-		}
-
-		buffer = kmalloc(usb_data.count, GFP_KERNEL);
-		if (buffer == NULL) {
-			mutex_unlock(&vstdev->lock);
-			retval = -ENOMEM;
-			goto exit;
-		}
-
-		urb = usb_alloc_urb(0, GFP_KERNEL);
-		if (!urb) {
-			mutex_unlock(&vstdev->lock);
-			retval = -ENOMEM;
-			goto exit;
-		}
-
-		timeout = usb_data.timeout_ms;
-
-		pipe = usb_sndbulkpipe(dev, usb_data.pipe);
-
-		if (copy_from_user(buffer, usb_data.buffer, usb_data.count)) {
-			dev_err(&dev->dev, "%s: can't copy_from_user\n",
-				__func__);
-			mutex_unlock(&vstdev->lock);
-			retval = -EFAULT;
-			goto exit;
-		}
-
-		usb_anchor_urb(urb, &vstdev->submitted);
-		retval = vstusb_fill_and_send_urb(urb, dev, pipe, buffer,
-						  usb_data.count, &done);
-		mutex_unlock(&vstdev->lock);
-		if (retval) {
-			usb_unanchor_urb(urb);
-			dev_err(&dev->dev,
-				"%s: error %d filling and sending urb %d\n",
-				__func__, retval, pipe);
-			goto exit;
-		}
-
-		retval = vstusb_complete_urb(urb, &done, timeout, &cnt);
-		if (retval) {
-			dev_err(&dev->dev, "%s: error %d completing urb %d\n",
-				__func__, retval, pipe);
-		}
-
-		break;
-	case IOCTL_VSTUSB_RECV_PIPE:
-
-		if ((usb_data.count == 0) || (usb_data.count > VST_MAXBUFFER)) {
-			mutex_unlock(&vstdev->lock);
-			retval = -EINVAL;
-			goto exit;
-		}
-
-		buffer = kmalloc(usb_data.count, GFP_KERNEL);
-		if (buffer == NULL) {
-			mutex_unlock(&vstdev->lock);
-			retval = -ENOMEM;
-			goto exit;
-		}
-
-		urb = usb_alloc_urb(0, GFP_KERNEL);
-		if (!urb) {
-			mutex_unlock(&vstdev->lock);
-			retval = -ENOMEM;
-			goto exit;
-		}
-
-		timeout = usb_data.timeout_ms;
-
-		pipe = usb_rcvbulkpipe(dev, usb_data.pipe);
-
-		usb_anchor_urb(urb, &vstdev->submitted);
-		retval = vstusb_fill_and_send_urb(urb, dev, pipe, buffer,
-						  usb_data.count, &done);
-		mutex_unlock(&vstdev->lock);
-		if (retval) {
-			usb_unanchor_urb(urb);
-			dev_err(&dev->dev,
-				"%s: error %d filling and sending urb %d\n",
-				__func__, retval, pipe);
-			goto exit;
-		}
-
-		retval = vstusb_complete_urb(urb, &done, timeout, &cnt);
-		if (retval) {
-			dev_err(&dev->dev, "%s: error %d completing urb %d\n",
-				__func__, retval, pipe);
-			goto exit;
-		}
-
-		if (copy_to_user(usb_data.buffer, buffer, cnt)) {
-			dev_err(&dev->dev, "%s: can't copy_to_user\n",
-				__func__);
-			retval = -EFAULT;
-			goto exit;
-		}
-
-		usb_data.count = cnt;
-		if (copy_to_user(data, &usb_data, sizeof(struct vstusb_args))) {
-			dev_err(&dev->dev, "%s: can't copy_to_user\n",
-				__func__);
-			retval = -EFAULT;
-		} else {
-			dev_dbg(&dev->dev, "%s: recv %zd bytes from pipe %d\n",
-				__func__, usb_data.count, usb_data.pipe);
-		}
-
-		break;
-
-	default:
-		mutex_unlock(&vstdev->lock);
-		dev_warn(&dev->dev, "ioctl_vstusb: invalid ioctl cmd %x\n",
-			 cmd);
-		return -EINVAL;
-		break;
-	}
-exit:
-	usb_free_urb(urb);
-	kfree(buffer);
-	return retval;
-}
-
-static const struct file_operations vstusb_fops = {
-	.owner =                THIS_MODULE,
-	.read =                 vstusb_read,
-	.write =                vstusb_write,
-	.unlocked_ioctl =       vstusb_ioctl,
-	.compat_ioctl =         vstusb_ioctl,
-	.open =                 vstusb_open,
-	.release =              vstusb_release,
-};
-
-static struct usb_class_driver usb_vstusb_class = {
-	.name =         "usb/vstusb%d",
-	.fops =         &vstusb_fops,
-	.minor_base =   VSTUSB_MINOR_BASE,
-};
-
-static int vstusb_probe(struct usb_interface *intf,
-			const struct usb_device_id *id)
-{
-	struct usb_device *dev = interface_to_usbdev(intf);
-	struct vstusb_device *vstdev;
-	int i;
-	int retval = 0;
-
-	/* allocate memory for our device state and intialize it */
-
-	vstdev = kzalloc(sizeof(*vstdev), GFP_KERNEL);
-	if (vstdev == NULL)
-		return -ENOMEM;
-
-	/* must do usb_get_dev() prior to kref_init() since the kref_put()
-	 * release function will do a usb_put_dev() */
-	usb_get_dev(dev);
-	kref_init(&vstdev->kref);
-	mutex_init(&vstdev->lock);
-
-	i = dev->descriptor.bcdDevice;
-
-	dev_dbg(&intf->dev, "Version %1d%1d.%1d%1d found at address %d\n",
-		(i & 0xF000) >> 12, (i & 0xF00) >> 8,
-		(i & 0xF0) >> 4, (i & 0xF), dev->devnum);
-
-	vstdev->present = 1;
-	vstdev->isopen = 0;
-	vstdev->usb_dev = dev;
-	init_usb_anchor(&vstdev->submitted);
-
-	usb_set_intfdata(intf, vstdev);
-	retval = usb_register_dev(intf, &usb_vstusb_class);
-	if (retval) {
-		dev_err(&intf->dev,
-			"%s: Not able to get a minor for this device.\n",
-			__func__);
-		usb_set_intfdata(intf, NULL);
-		kref_put(&vstdev->kref, vstusb_delete);
-		return retval;
-	}
-
-	/* let the user know what node this device is now attached to */
-	dev_info(&intf->dev,
-		 "VST USB Device #%d now attached to major %d minor %d\n",
-		 (intf->minor - VSTUSB_MINOR_BASE), USB_MAJOR, intf->minor);
-
-	dev_info(&intf->dev, "%s, %s\n", DRIVER_DESC, DRIVER_VERSION);
-
-	return retval;
-}
-
-static void vstusb_disconnect(struct usb_interface *intf)
-{
-	struct vstusb_device *vstdev = usb_get_intfdata(intf);
-
-	usb_deregister_dev(intf, &usb_vstusb_class);
-	usb_set_intfdata(intf, NULL);
-
-	if (vstdev) {
-
-		mutex_lock(&vstdev->lock);
-		vstdev->present = 0;
-
-		usb_kill_anchored_urbs(&vstdev->submitted);
-
-		mutex_unlock(&vstdev->lock);
-
-		kref_put(&vstdev->kref, vstusb_delete);
-	}
-
-}
-
-static int vstusb_suspend(struct usb_interface *intf, pm_message_t message)
-{
-	struct vstusb_device *vstdev = usb_get_intfdata(intf);
-	int time;
-	if (!vstdev)
-		return 0;
-
-	mutex_lock(&vstdev->lock);
-	time = usb_wait_anchor_empty_timeout(&vstdev->submitted, 1000);
-	if (!time)
-		usb_kill_anchored_urbs(&vstdev->submitted);
-	mutex_unlock(&vstdev->lock);
-
-	return 0;
-}
-
-static int vstusb_resume(struct usb_interface *intf)
-{
-	return 0;
-}
-
-static struct usb_driver vstusb_driver = {
-	.name =         "vstusb",
-	.probe =        vstusb_probe,
-	.disconnect =   vstusb_disconnect,
-	.suspend =      vstusb_suspend,
-	.resume =       vstusb_resume,
-	.id_table = id_table,
-};
-
-static int __init vstusb_init(void)
-{
-	int rc;
-
-	rc = usb_register(&vstusb_driver);
-	if (rc)
-		printk(KERN_ERR "%s: failed to register (%d)", __func__, rc);
-
-	return rc;
-}
-
-static void __exit vstusb_exit(void)
-{
-	usb_deregister(&vstusb_driver);
-}
-
-module_init(vstusb_init);
-module_exit(vstusb_exit);
-
-MODULE_AUTHOR("Dennis O'Brien/Stephen Ware");
-MODULE_DESCRIPTION(DRIVER_VERSION);
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/mon/mon_bin.c linux-libre-2.6.34-gnu1/drivers/usb/mon/mon_bin.c
--- linux-libre-2.6.33-gnu1/drivers/usb/mon/mon_bin.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/mon/mon_bin.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/mm.h>
 #include <linux/smp_lock.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
@@ -460,8 +461,8 @@ static void mon_bin_event(struct mon_rea
     char ev_type, int status)
 {
 	const struct usb_endpoint_descriptor *epd = &urb->ep->desc;
-	unsigned long flags;
 	struct timeval ts;
+	unsigned long flags;
 	unsigned int urb_length;
 	unsigned int offset;
 	unsigned int length;
@@ -600,10 +601,13 @@ static void mon_bin_complete(void *data,
 static void mon_bin_error(void *data, struct urb *urb, int error)
 {
 	struct mon_reader_bin *rp = data;
+	struct timeval ts;
 	unsigned long flags;
 	unsigned int offset;
 	struct mon_bin_hdr *ep;
 
+	do_gettimeofday(&ts);
+
 	spin_lock_irqsave(&rp->b_lock, flags);
 
 	offset = mon_buff_area_alloc(rp, PKT_SIZE);
@@ -623,6 +627,8 @@ static void mon_bin_error(void *data, st
 	ep->devnum = urb->dev->devnum;
 	ep->busnum = urb->dev->bus->busnum;
 	ep->id = (unsigned long) urb;
+	ep->ts_sec = ts.tv_sec;
+	ep->ts_usec = ts.tv_usec;
 	ep->status = error;
 
 	ep->flag_setup = '-';
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/mon/mon_main.c linux-libre-2.6.34-gnu1/drivers/usb/mon/mon_main.c
--- linux-libre-2.6.33-gnu1/drivers/usb/mon/mon_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/mon/mon_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 #include <linux/notifier.h>
 #include <linux/mutex.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/mon/mon_stat.c linux-libre-2.6.34-gnu1/drivers/usb/mon/mon_stat.c
--- linux-libre-2.6.33-gnu1/drivers/usb/mon/mon_stat.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/mon/mon_stat.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/fs.h>
 #include <asm/uaccess.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/mon/mon_text.c linux-libre-2.6.34-gnu1/drivers/usb/mon/mon_text.c
--- linux-libre-2.6.33-gnu1/drivers/usb/mon/mon_text.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/mon/mon_text.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/mutex.h>
 #include <linux/debugfs.h>
@@ -180,7 +181,7 @@ static inline unsigned int mon_get_times
 	unsigned int stamp;
 
 	do_gettimeofday(&tval);
-	stamp = tval.tv_sec & 0xFFFF;	/* 2^32 = 4294967296. Limit to 4096s. */
+	stamp = tval.tv_sec & 0xFFF;	/* 2^32 = 4294967296. Limit to 4096s. */
 	stamp = stamp * 1000000 + tval.tv_usec;
 	return stamp;
 }
@@ -273,12 +274,12 @@ static void mon_text_error(void *data, s
 
 	ep->type = 'E';
 	ep->id = (unsigned long) urb;
-	ep->busnum = 0;
+	ep->busnum = urb->dev->bus->busnum;
 	ep->devnum = urb->dev->devnum;
 	ep->epnum = usb_endpoint_num(&urb->ep->desc);
 	ep->xfertype = usb_endpoint_type(&urb->ep->desc);
 	ep->is_in = usb_urb_dir_in(urb);
-	ep->tstamp = 0;
+	ep->tstamp = mon_get_timestamp();
 	ep->length = 0;
 	ep->status = error;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/blackfin.c linux-libre-2.6.34-gnu1/drivers/usb/musb/blackfin.c
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/blackfin.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/blackfin.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/gpio.h>
@@ -30,7 +29,6 @@ void musb_write_fifo(struct musb_hw_ep *
 	void __iomem *fifo = hw_ep->fifo;
 	void __iomem *epio = hw_ep->regs;
 	u8 epnum = hw_ep->epnum;
-	u16 dma_reg = 0;
 
 	prefetch((u8 *)src);
 
@@ -42,15 +40,17 @@ void musb_write_fifo(struct musb_hw_ep *
 	dump_fifo_data(src, len);
 
 	if (!ANOMALY_05000380 && epnum != 0) {
-		flush_dcache_range((unsigned int)src,
-			(unsigned int)(src + len));
+		u16 dma_reg;
+
+		flush_dcache_range((unsigned long)src,
+			(unsigned long)(src + len));
 
 		/* Setup DMA address register */
-		dma_reg = (u16) ((u32) src & 0xFFFF);
+		dma_reg = (u32)src;
 		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg);
 		SSYNC();
 
-		dma_reg = (u16) (((u32) src >> 16) & 0xFFFF);
+		dma_reg = (u32)src >> 16;
 		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg);
 		SSYNC();
 
@@ -79,12 +79,9 @@ void musb_write_fifo(struct musb_hw_ep *
 		SSYNC();
 
 		if (unlikely((unsigned long)src & 0x01))
-			outsw_8((unsigned long)fifo, src,
-				len & 0x01 ? (len >> 1) + 1 : len >> 1);
+			outsw_8((unsigned long)fifo, src, (len + 1) >> 1);
 		else
-			outsw((unsigned long)fifo, src,
-				len & 0x01 ? (len >> 1) + 1 : len >> 1);
-
+			outsw((unsigned long)fifo, src, (len + 1) >> 1);
 	}
 }
 /*
@@ -94,19 +91,19 @@ void musb_read_fifo(struct musb_hw_ep *h
 {
 	void __iomem *fifo = hw_ep->fifo;
 	u8 epnum = hw_ep->epnum;
-	u16 dma_reg = 0;
 
 	if (ANOMALY_05000467 && epnum != 0) {
+		u16 dma_reg;
 
-		invalidate_dcache_range((unsigned int)dst,
-			(unsigned int)(dst + len));
+		invalidate_dcache_range((unsigned long)dst,
+			(unsigned long)(dst + len));
 
 		/* Setup DMA address register */
-		dma_reg = (u16) ((u32) dst & 0xFFFF);
+		dma_reg = (u32)dst;
 		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg);
 		SSYNC();
 
-		dma_reg = (u16) (((u32) dst >> 16) & 0xFFFF);
+		dma_reg = (u32)dst >> 16;
 		bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg);
 		SSYNC();
 
@@ -175,13 +172,7 @@ static irqreturn_t blackfin_interrupt(in
 
 	spin_unlock_irqrestore(&musb->lock, flags);
 
-	/* REVISIT we sometimes get spurious IRQs on g_ep0
-	 * not clear why... fall in BF54x too.
-	 */
-	if (retval != IRQ_HANDLED)
-		DBG(5, "spurious?\n");
-
-	return IRQ_HANDLED;
+	return retval;
 }
 
 static void musb_conn_timer_handler(unsigned long _musb)
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/cppi_dma.c linux-libre-2.6.34-gnu1/drivers/usb/musb/cppi_dma.c
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/cppi_dma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/cppi_dma.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "musb_core.h"
@@ -1191,8 +1192,13 @@ irqreturn_t cppi_interrupt(int irq, void
 
 		bd = tx_ch->head;
 
+		/*
+		 * If Head is null then this could mean that a abort interrupt
+		 * that needs to be acknowledged.
+		 */
 		if (NULL == bd) {
 			DBG(1, "null BD\n");
+			tx_ram->tx_complete = 0;
 			continue;
 		}
 
@@ -1412,15 +1418,6 @@ static int cppi_channel_abort(struct dma
 
 	if (cppi_ch->transmit) {
 		struct cppi_tx_stateram __iomem *tx_ram;
-		int			enabled;
-
-		/* mask interrupts raised to signal teardown complete.  */
-		enabled = musb_readl(tibase, DAVINCI_TXCPPI_INTENAB_REG)
-				& (1 << cppi_ch->index);
-		if (enabled)
-			musb_writel(tibase, DAVINCI_TXCPPI_INTCLR_REG,
-					(1 << cppi_ch->index));
-
 		/* REVISIT put timeouts on these controller handshakes */
 
 		cppi_dump_tx(6, cppi_ch, " (teardown)");
@@ -1435,7 +1432,6 @@ static int cppi_channel_abort(struct dma
 		do {
 			value = musb_readl(&tx_ram->tx_complete, 0);
 		} while (0xFFFFFFFC != value);
-		musb_writel(&tx_ram->tx_complete, 0, 0xFFFFFFFC);
 
 		/* FIXME clean up the transfer state ... here?
 		 * the completion routine should get called with
@@ -1448,23 +1444,15 @@ static int cppi_channel_abort(struct dma
 		musb_writew(regs, MUSB_TXCSR, value);
 		musb_writew(regs, MUSB_TXCSR, value);
 
-		/* While we scrub the TX state RAM, ensure that we clean
-		 * up any interrupt that's currently asserted:
+		/*
 		 * 1. Write to completion Ptr value 0x1(bit 0 set)
 		 *    (write back mode)
-		 * 2. Write to completion Ptr value 0x0(bit 0 cleared)
-		 *    (compare mode)
-		 * Value written is compared(for bits 31:2) and when
-		 * equal, interrupt is deasserted.
+		 * 2. Wait for abort interrupt and then put the channel in
+		 *    compare mode by writing 1 to the tx_complete register.
 		 */
 		cppi_reset_tx(tx_ram, 1);
-		musb_writel(&tx_ram->tx_complete, 0, 0);
-
-		/* re-enable interrupt */
-		if (enabled)
-			musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG,
-					(1 << cppi_ch->index));
-
+		cppi_ch->head = 0;
+		musb_writel(&tx_ram->tx_complete, 0, 1);
 		cppi_dump_tx(5, cppi_ch, " (done teardown)");
 
 		/* REVISIT tx side _should_ clean up the same way
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/davinci.c linux-libre-2.6.34-gnu1/drivers/usb/musb/davinci.c
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/davinci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/davinci.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/delay.h>
@@ -274,7 +273,7 @@ static irqreturn_t davinci_interrupt(int
 	/* NOTE: DaVinci shadows the Mentor IRQs.  Don't manage them through
 	 * the Mentor registers (except for setup), use the TI ones and EOI.
 	 *
-	 * Docs describe irq "vector" registers asociated with the CPPI and
+	 * Docs describe irq "vector" registers associated with the CPPI and
 	 * USB EOI registers.  These hold a bitmask corresponding to the
 	 * current IRQ, not an irq handler address.  Would using those bits
 	 * resolve some of the races observed in this dispatch code??
@@ -445,6 +444,8 @@ int __init musb_platform_init(struct mus
 	return 0;
 
 fail:
+	clk_disable(musb->clock);
+
 	usb_nop_xceiv_unregister();
 	return -ENODEV;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/Kconfig linux-libre-2.6.34-gnu1/drivers/usb/musb/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -37,18 +37,18 @@ config USB_MUSB_SOC
 	depends on USB_MUSB_HDRC
 	default y if ARCH_DAVINCI
 	default y if ARCH_OMAP2430
-	default y if ARCH_OMAP34XX
+	default y if ARCH_OMAP3
 	default y if (BF54x && !BF544)
 	default y if (BF52x && !BF522 && !BF523)
 
 comment "DaVinci 35x and 644x USB support"
-	depends on USB_MUSB_HDRC && ARCH_DAVINCI
+	depends on USB_MUSB_HDRC && ARCH_DAVINCI_DMx
 
 comment "OMAP 243x high speed USB support"
 	depends on USB_MUSB_HDRC && ARCH_OMAP2430
 
 comment "OMAP 343x high speed USB support"
-	depends on USB_MUSB_HDRC && ARCH_OMAP34XX
+	depends on USB_MUSB_HDRC && ARCH_OMAP3
 
 comment "Blackfin high speed USB Support"
 	depends on USB_MUSB_HDRC && ((BF54x && !BF544) || (BF52x && !BF522 && !BF523))
@@ -153,7 +153,7 @@ config MUSB_PIO_ONLY
 config USB_INVENTRA_DMA
 	bool
 	depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
-	default ARCH_OMAP2430 || ARCH_OMAP34XX || BLACKFIN
+	default ARCH_OMAP2430 || ARCH_OMAP3 || BLACKFIN
 	help
 	  Enable DMA transfers using Mentor's engine.
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/Makefile linux-libre-2.6.34-gnu1/drivers/usb/musb/Makefile
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -6,7 +6,7 @@ musb_hdrc-objs := musb_core.o
 
 obj-$(CONFIG_USB_MUSB_HDRC)	+= musb_hdrc.o
 
-ifeq ($(CONFIG_ARCH_DAVINCI),y)
+ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y)
 	musb_hdrc-objs	+= davinci.o
 endif
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/musb_core.c linux-libre-2.6.34-gnu1/drivers/usb/musb/musb_core.c
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/musb_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/musb_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -379,7 +379,6 @@ static irqreturn_t musb_stage0_irq(struc
 				u8 devctl, u8 power)
 {
 	irqreturn_t handled = IRQ_NONE;
-	void __iomem *mbase = musb->mregs;
 
 	DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl,
 		int_usb);
@@ -394,6 +393,8 @@ static irqreturn_t musb_stage0_irq(struc
 
 		if (devctl & MUSB_DEVCTL_HM) {
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
+			void __iomem *mbase = musb->mregs;
+
 			switch (musb->xceiv->state) {
 			case OTG_STATE_A_SUSPEND:
 				/* remote wakeup?  later, GetPortStatus
@@ -471,6 +472,8 @@ static irqreturn_t musb_stage0_irq(struc
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
 	/* see manual for the order of the tests */
 	if (int_usb & MUSB_INTR_SESSREQ) {
+		void __iomem *mbase = musb->mregs;
+
 		DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb));
 
 		/* IRQ arrives from ID pin sense or (later, if VBUS power
@@ -519,6 +522,8 @@ static irqreturn_t musb_stage0_irq(struc
 		case OTG_STATE_A_WAIT_BCON:
 		case OTG_STATE_A_WAIT_VRISE:
 			if (musb->vbuserr_retry) {
+				void __iomem *mbase = musb->mregs;
+
 				musb->vbuserr_retry--;
 				ignore = 1;
 				devctl |= MUSB_DEVCTL_SESSION;
@@ -557,8 +562,72 @@ static irqreturn_t musb_stage0_irq(struc
 		handled = IRQ_HANDLED;
 	}
 
+
+	if (int_usb & MUSB_INTR_SUSPEND) {
+		DBG(1, "SUSPEND (%s) devctl %02x power %02x\n",
+				otg_state_string(musb), devctl, power);
+		handled = IRQ_HANDLED;
+
+		switch (musb->xceiv->state) {
+#ifdef	CONFIG_USB_MUSB_OTG
+		case OTG_STATE_A_PERIPHERAL:
+			/* We also come here if the cable is removed, since
+			 * this silicon doesn't report ID-no-longer-grounded.
+			 *
+			 * We depend on T(a_wait_bcon) to shut us down, and
+			 * hope users don't do anything dicey during this
+			 * undesired detour through A_WAIT_BCON.
+			 */
+			musb_hnp_stop(musb);
+			usb_hcd_resume_root_hub(musb_to_hcd(musb));
+			musb_root_disconnect(musb);
+			musb_platform_try_idle(musb, jiffies
+					+ msecs_to_jiffies(musb->a_wait_bcon
+						? : OTG_TIME_A_WAIT_BCON));
+
+			break;
+#endif
+		case OTG_STATE_B_IDLE:
+			if (!musb->is_active)
+				break;
+		case OTG_STATE_B_PERIPHERAL:
+			musb_g_suspend(musb);
+			musb->is_active = is_otg_enabled(musb)
+					&& musb->xceiv->gadget->b_hnp_enable;
+			if (musb->is_active) {
+#ifdef	CONFIG_USB_MUSB_OTG
+				musb->xceiv->state = OTG_STATE_B_WAIT_ACON;
+				DBG(1, "HNP: Setting timer for b_ase0_brst\n");
+				mod_timer(&musb->otg_timer, jiffies
+					+ msecs_to_jiffies(
+							OTG_TIME_B_ASE0_BRST));
+#endif
+			}
+			break;
+		case OTG_STATE_A_WAIT_BCON:
+			if (musb->a_wait_bcon != 0)
+				musb_platform_try_idle(musb, jiffies
+					+ msecs_to_jiffies(musb->a_wait_bcon));
+			break;
+		case OTG_STATE_A_HOST:
+			musb->xceiv->state = OTG_STATE_A_SUSPEND;
+			musb->is_active = is_otg_enabled(musb)
+					&& musb->xceiv->host->b_hnp_enable;
+			break;
+		case OTG_STATE_B_HOST:
+			/* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */
+			DBG(1, "REVISIT: SUSPEND as B_HOST\n");
+			break;
+		default:
+			/* "should not happen" */
+			musb->is_active = 0;
+			break;
+		}
+	}
+
 	if (int_usb & MUSB_INTR_CONNECT) {
 		struct usb_hcd *hcd = musb_to_hcd(musb);
+		void __iomem *mbase = musb->mregs;
 
 		handled = IRQ_HANDLED;
 		musb->is_active = 1;
@@ -625,10 +694,61 @@ b_host:
 	}
 #endif	/* CONFIG_USB_MUSB_HDRC_HCD */
 
+	if ((int_usb & MUSB_INTR_DISCONNECT) && !musb->ignore_disconnect) {
+		DBG(1, "DISCONNECT (%s) as %s, devctl %02x\n",
+				otg_state_string(musb),
+				MUSB_MODE(musb), devctl);
+		handled = IRQ_HANDLED;
+
+		switch (musb->xceiv->state) {
+#ifdef CONFIG_USB_MUSB_HDRC_HCD
+		case OTG_STATE_A_HOST:
+		case OTG_STATE_A_SUSPEND:
+			usb_hcd_resume_root_hub(musb_to_hcd(musb));
+			musb_root_disconnect(musb);
+			if (musb->a_wait_bcon != 0 && is_otg_enabled(musb))
+				musb_platform_try_idle(musb, jiffies
+					+ msecs_to_jiffies(musb->a_wait_bcon));
+			break;
+#endif	/* HOST */
+#ifdef CONFIG_USB_MUSB_OTG
+		case OTG_STATE_B_HOST:
+			/* REVISIT this behaves for "real disconnect"
+			 * cases; make sure the other transitions from
+			 * from B_HOST act right too.  The B_HOST code
+			 * in hnp_stop() is currently not used...
+			 */
+			musb_root_disconnect(musb);
+			musb_to_hcd(musb)->self.is_b_host = 0;
+			musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
+			MUSB_DEV_MODE(musb);
+			musb_g_disconnect(musb);
+			break;
+		case OTG_STATE_A_PERIPHERAL:
+			musb_hnp_stop(musb);
+			musb_root_disconnect(musb);
+			/* FALLTHROUGH */
+		case OTG_STATE_B_WAIT_ACON:
+			/* FALLTHROUGH */
+#endif	/* OTG */
+#ifdef CONFIG_USB_GADGET_MUSB_HDRC
+		case OTG_STATE_B_PERIPHERAL:
+		case OTG_STATE_B_IDLE:
+			musb_g_disconnect(musb);
+			break;
+#endif	/* GADGET */
+		default:
+			WARNING("unhandled DISCONNECT transition (%s)\n",
+				otg_state_string(musb));
+			break;
+		}
+	}
+
 	/* mentor saves a bit: bus reset and babble share the same irq.
 	 * only host sees babble; only peripheral sees bus reset.
 	 */
 	if (int_usb & MUSB_INTR_RESET) {
+		handled = IRQ_HANDLED;
 		if (is_host_capable() && (devctl & MUSB_DEVCTL_HM) != 0) {
 			/*
 			 * Looks like non-HS BABBLE can be ignored, but
@@ -641,7 +761,7 @@ b_host:
 				DBG(1, "BABBLE devctl: %02x\n", devctl);
 			else {
 				ERR("Stopping host session -- babble\n");
-				musb_writeb(mbase, MUSB_DEVCTL, 0);
+				musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
 			}
 		} else if (is_peripheral_capable()) {
 			DBG(1, "BUS RESET as %s\n", otg_state_string(musb));
@@ -686,29 +806,7 @@ b_host:
 					otg_state_string(musb));
 			}
 		}
-
-		handled = IRQ_HANDLED;
 	}
-	schedule_work(&musb->irq_work);
-
-	return handled;
-}
-
-/*
- * Interrupt Service Routine to record USB "global" interrupts.
- * Since these do not happen often and signify things of
- * paramount importance, it seems OK to check them individually;
- * the order of the tests is specified in the manual
- *
- * @param musb instance pointer
- * @param int_usb register contents
- * @param devctl
- * @param power
- */
-static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb,
-				u8 devctl, u8 power)
-{
-	irqreturn_t handled = IRQ_NONE;
 
 #if 0
 /* REVISIT ... this would be for multiplexing periodic endpoints, or
@@ -755,117 +853,7 @@ static irqreturn_t musb_stage2_irq(struc
 	}
 #endif
 
-	if ((int_usb & MUSB_INTR_DISCONNECT) && !musb->ignore_disconnect) {
-		DBG(1, "DISCONNECT (%s) as %s, devctl %02x\n",
-				otg_state_string(musb),
-				MUSB_MODE(musb), devctl);
-		handled = IRQ_HANDLED;
-
-		switch (musb->xceiv->state) {
-#ifdef CONFIG_USB_MUSB_HDRC_HCD
-		case OTG_STATE_A_HOST:
-		case OTG_STATE_A_SUSPEND:
-			usb_hcd_resume_root_hub(musb_to_hcd(musb));
-			musb_root_disconnect(musb);
-			if (musb->a_wait_bcon != 0 && is_otg_enabled(musb))
-				musb_platform_try_idle(musb, jiffies
-					+ msecs_to_jiffies(musb->a_wait_bcon));
-			break;
-#endif	/* HOST */
-#ifdef CONFIG_USB_MUSB_OTG
-		case OTG_STATE_B_HOST:
-			/* REVISIT this behaves for "real disconnect"
-			 * cases; make sure the other transitions from
-			 * from B_HOST act right too.  The B_HOST code
-			 * in hnp_stop() is currently not used...
-			 */
-			musb_root_disconnect(musb);
-			musb_to_hcd(musb)->self.is_b_host = 0;
-			musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
-			MUSB_DEV_MODE(musb);
-			musb_g_disconnect(musb);
-			break;
-		case OTG_STATE_A_PERIPHERAL:
-			musb_hnp_stop(musb);
-			musb_root_disconnect(musb);
-			/* FALLTHROUGH */
-		case OTG_STATE_B_WAIT_ACON:
-			/* FALLTHROUGH */
-#endif	/* OTG */
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
-		case OTG_STATE_B_PERIPHERAL:
-		case OTG_STATE_B_IDLE:
-			musb_g_disconnect(musb);
-			break;
-#endif	/* GADGET */
-		default:
-			WARNING("unhandled DISCONNECT transition (%s)\n",
-				otg_state_string(musb));
-			break;
-		}
-
-		schedule_work(&musb->irq_work);
-	}
-
-	if (int_usb & MUSB_INTR_SUSPEND) {
-		DBG(1, "SUSPEND (%s) devctl %02x power %02x\n",
-				otg_state_string(musb), devctl, power);
-		handled = IRQ_HANDLED;
-
-		switch (musb->xceiv->state) {
-#ifdef	CONFIG_USB_MUSB_OTG
-		case OTG_STATE_A_PERIPHERAL:
-			/* We also come here if the cable is removed, since
-			 * this silicon doesn't report ID-no-longer-grounded.
-			 *
-			 * We depend on T(a_wait_bcon) to shut us down, and
-			 * hope users don't do anything dicey during this
-			 * undesired detour through A_WAIT_BCON.
-			 */
-			musb_hnp_stop(musb);
-			usb_hcd_resume_root_hub(musb_to_hcd(musb));
-			musb_root_disconnect(musb);
-			musb_platform_try_idle(musb, jiffies
-					+ msecs_to_jiffies(musb->a_wait_bcon
-						? : OTG_TIME_A_WAIT_BCON));
-			break;
-#endif
-		case OTG_STATE_B_PERIPHERAL:
-			musb_g_suspend(musb);
-			musb->is_active = is_otg_enabled(musb)
-					&& musb->xceiv->gadget->b_hnp_enable;
-			if (musb->is_active) {
-#ifdef	CONFIG_USB_MUSB_OTG
-				musb->xceiv->state = OTG_STATE_B_WAIT_ACON;
-				DBG(1, "HNP: Setting timer for b_ase0_brst\n");
-				mod_timer(&musb->otg_timer, jiffies
-					+ msecs_to_jiffies(
-							OTG_TIME_B_ASE0_BRST));
-#endif
-			}
-			break;
-		case OTG_STATE_A_WAIT_BCON:
-			if (musb->a_wait_bcon != 0)
-				musb_platform_try_idle(musb, jiffies
-					+ msecs_to_jiffies(musb->a_wait_bcon));
-			break;
-		case OTG_STATE_A_HOST:
-			musb->xceiv->state = OTG_STATE_A_SUSPEND;
-			musb->is_active = is_otg_enabled(musb)
-					&& musb->xceiv->host->b_hnp_enable;
-			break;
-		case OTG_STATE_B_HOST:
-			/* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */
-			DBG(1, "REVISIT: SUSPEND as B_HOST\n");
-			break;
-		default:
-			/* "should not happen" */
-			musb->is_active = 0;
-			break;
-		}
-		schedule_work(&musb->irq_work);
-	}
-
+	schedule_work(&musb->irq_work);
 
 	return handled;
 }
@@ -977,10 +965,8 @@ static void musb_shutdown(struct platfor
 	spin_lock_irqsave(&musb->lock, flags);
 	musb_platform_disable(musb);
 	musb_generic_disable(musb);
-	if (musb->clock) {
+	if (musb->clock)
 		clk_put(musb->clock);
-		musb->clock = NULL;
-	}
 	spin_unlock_irqrestore(&musb->lock, flags);
 
 	/* FIXME power down */
@@ -1000,7 +986,7 @@ static void musb_shutdown(struct platfor
  * more than selecting one of a bunch of predefined configurations.
  */
 #if defined(CONFIG_USB_TUSB6010) || \
-	defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
+	defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
 static ushort __initdata fifo_mode = 4;
 #else
 static ushort __initdata fifo_mode = 2;
@@ -1095,6 +1081,36 @@ static struct fifo_cfg __initdata mode_4
 { .hw_ep_num = 15, .style = FIFO_RXTX, .maxpacket = 1024, },
 };
 
+/* mode 5 - fits in 8KB */
+static struct fifo_cfg __initdata mode_5_cfg[] = {
+{ .hw_ep_num =  1, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  1, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  2, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  2, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  3, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  3, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  4, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  4, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  5, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  5, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  6, .style = FIFO_TX,   .maxpacket = 32, },
+{ .hw_ep_num =  6, .style = FIFO_RX,   .maxpacket = 32, },
+{ .hw_ep_num =  7, .style = FIFO_TX,   .maxpacket = 32, },
+{ .hw_ep_num =  7, .style = FIFO_RX,   .maxpacket = 32, },
+{ .hw_ep_num =  8, .style = FIFO_TX,   .maxpacket = 32, },
+{ .hw_ep_num =  8, .style = FIFO_RX,   .maxpacket = 32, },
+{ .hw_ep_num =  9, .style = FIFO_TX,   .maxpacket = 32, },
+{ .hw_ep_num =  9, .style = FIFO_RX,   .maxpacket = 32, },
+{ .hw_ep_num = 10, .style = FIFO_TX,   .maxpacket = 32, },
+{ .hw_ep_num = 10, .style = FIFO_RX,   .maxpacket = 32, },
+{ .hw_ep_num = 11, .style = FIFO_TX,   .maxpacket = 32, },
+{ .hw_ep_num = 11, .style = FIFO_RX,   .maxpacket = 32, },
+{ .hw_ep_num = 12, .style = FIFO_TX,   .maxpacket = 32, },
+{ .hw_ep_num = 12, .style = FIFO_RX,   .maxpacket = 32, },
+{ .hw_ep_num = 13, .style = FIFO_RXTX, .maxpacket = 512, },
+{ .hw_ep_num = 14, .style = FIFO_RXTX, .maxpacket = 1024, },
+{ .hw_ep_num = 15, .style = FIFO_RXTX, .maxpacket = 1024, },
+};
 
 /*
  * configure a fifo; for non-shared endpoints, this may be called
@@ -1210,6 +1226,10 @@ static int __init ep_config_from_table(s
 		cfg = mode_4_cfg;
 		n = ARRAY_SIZE(mode_4_cfg);
 		break;
+	case 5:
+		cfg = mode_5_cfg;
+		n = ARRAY_SIZE(mode_5_cfg);
+		break;
 	}
 
 	printk(KERN_DEBUG "%s: setup fifo_mode %d\n",
@@ -1314,9 +1334,6 @@ enum { MUSB_CONTROLLER_MHDRC, MUSB_CONTR
  */
 static int __init musb_core_init(u16 musb_type, struct musb *musb)
 {
-#ifdef MUSB_AHB_ID
-	u32 data;
-#endif
 	u8 reg;
 	char *type;
 	char aInfo[90], aRevision[32], aDate[12];
@@ -1328,23 +1345,17 @@ static int __init musb_core_init(u16 mus
 	reg = musb_read_configdata(mbase);
 
 	strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8");
-	if (reg & MUSB_CONFIGDATA_DYNFIFO)
+	if (reg & MUSB_CONFIGDATA_DYNFIFO) {
 		strcat(aInfo, ", dyn FIFOs");
+		musb->dyn_fifo = true;
+	}
 	if (reg & MUSB_CONFIGDATA_MPRXE) {
 		strcat(aInfo, ", bulk combine");
-#ifdef C_MP_RX
 		musb->bulk_combine = true;
-#else
-		strcat(aInfo, " (X)");		/* no driver support */
-#endif
 	}
 	if (reg & MUSB_CONFIGDATA_MPTXE) {
 		strcat(aInfo, ", bulk split");
-#ifdef C_MP_TX
 		musb->bulk_split = true;
-#else
-		strcat(aInfo, " (X)");		/* no driver support */
-#endif
 	}
 	if (reg & MUSB_CONFIGDATA_HBRXE) {
 		strcat(aInfo, ", HB-ISO Rx");
@@ -1360,20 +1371,7 @@ static int __init musb_core_init(u16 mus
 	printk(KERN_DEBUG "%s: ConfigData=0x%02x (%s)\n",
 			musb_driver_name, reg, aInfo);
 
-#ifdef MUSB_AHB_ID
-	data = musb_readl(mbase, 0x404);
-	sprintf(aDate, "%04d-%02x-%02x", (data & 0xffff),
-		(data >> 16) & 0xff, (data >> 24) & 0xff);
-	/* FIXME ID2 and ID3 are unused */
-	data = musb_readl(mbase, 0x408);
-	printk(KERN_DEBUG "ID2=%lx\n", (long unsigned)data);
-	data = musb_readl(mbase, 0x40c);
-	printk(KERN_DEBUG "ID3=%lx\n", (long unsigned)data);
-	reg = musb_readb(mbase, 0x400);
-	musb_type = ('M' == reg) ? MUSB_CONTROLLER_MHDRC : MUSB_CONTROLLER_HDRC;
-#else
 	aDate[0] = 0;
-#endif
 	if (MUSB_CONTROLLER_MHDRC == musb_type) {
 		musb->is_multipoint = 1;
 		type = "M";
@@ -1404,21 +1402,10 @@ static int __init musb_core_init(u16 mus
 	musb->nr_endpoints = 1;
 	musb->epmask = 1;
 
-	if (reg & MUSB_CONFIGDATA_DYNFIFO) {
-		if (musb->config->dyn_fifo)
-			status = ep_config_from_table(musb);
-		else {
-			ERR("reconfigure software for Dynamic FIFOs\n");
-			status = -ENODEV;
-		}
-	} else {
-		if (!musb->config->dyn_fifo)
-			status = ep_config_from_hw(musb);
-		else {
-			ERR("reconfigure software for static FIFOs\n");
-			return -ENODEV;
-		}
-	}
+	if (musb->dyn_fifo)
+		status = ep_config_from_table(musb);
+	else
+		status = ep_config_from_hw(musb);
 
 	if (status < 0)
 		return status;
@@ -1587,11 +1574,6 @@ irqreturn_t musb_interrupt(struct musb *
 		ep_num++;
 	}
 
-	/* finish handling "global" interrupts after handling fifos */
-	if (musb->int_usb)
-		retval |= musb_stage2_irq(musb,
-				musb->int_usb, devctl, power);
-
 	return retval;
 }
 
@@ -1696,7 +1678,7 @@ musb_vbus_store(struct device *dev, stru
 	unsigned long	val;
 
 	if (sscanf(buf, "%lu", &val) < 1) {
-		printk(KERN_ERR "Invalid VBUS timeout ms value\n");
+		dev_err(dev, "Invalid VBUS timeout ms value\n");
 		return -EINVAL;
 	}
 
@@ -1746,7 +1728,7 @@ musb_srp_store(struct device *dev, struc
 
 	if (sscanf(buf, "%hu", &srp) != 1
 			|| (srp != 1)) {
-		printk(KERN_ERR "SRP: Value must be 1\n");
+		dev_err(dev, "SRP: Value must be 1\n");
 		return -EINVAL;
 	}
 
@@ -1759,6 +1741,19 @@ static DEVICE_ATTR(srp, 0644, NULL, musb
 
 #endif /* CONFIG_USB_GADGET_MUSB_HDRC */
 
+static struct attribute *musb_attributes[] = {
+	&dev_attr_mode.attr,
+	&dev_attr_vbus.attr,
+#ifdef CONFIG_USB_GADGET_MUSB_HDRC
+	&dev_attr_srp.attr,
+#endif
+	NULL
+};
+
+static const struct attribute_group musb_attr_group = {
+	.attrs = musb_attributes,
+};
+
 #endif	/* sysfs */
 
 /* Only used to provide driver mode change events */
@@ -1833,11 +1828,7 @@ static void musb_free(struct musb *musb)
 	 */
 
 #ifdef CONFIG_SYSFS
-	device_remove_file(musb->controller, &dev_attr_mode);
-	device_remove_file(musb->controller, &dev_attr_vbus);
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
-	device_remove_file(musb->controller, &dev_attr_srp);
-#endif
+	sysfs_remove_group(&musb->controller->kobj, &musb_attr_group);
 #endif
 
 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
@@ -1860,15 +1851,6 @@ static void musb_free(struct musb *musb)
 	put_device(musb->xceiv->dev);
 #endif
 
-	musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
-	musb_platform_exit(musb);
-	musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
-
-	if (musb->clock) {
-		clk_disable(musb->clock);
-		clk_put(musb->clock);
-	}
-
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
 	usb_put_hcd(musb_to_hcd(musb));
 #else
@@ -1896,8 +1878,10 @@ musb_init_controller(struct device *dev,
 	 */
 	if (!plat) {
 		dev_dbg(dev, "no platform_data?\n");
-		return -ENODEV;
+		status = -ENODEV;
+		goto fail0;
 	}
+
 	switch (plat->mode) {
 	case MUSB_HOST:
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
@@ -1919,13 +1903,16 @@ bad_config:
 #endif
 	default:
 		dev_err(dev, "incompatible Kconfig role setting\n");
-		return -EINVAL;
+		status = -EINVAL;
+		goto fail0;
 	}
 
 	/* allocate */
 	musb = allocate_instance(dev, plat->config, ctrl);
-	if (!musb)
-		return -ENOMEM;
+	if (!musb) {
+		status = -ENOMEM;
+		goto fail0;
+	}
 
 	spin_lock_init(&musb->lock);
 	musb->board_mode = plat->mode;
@@ -1943,7 +1930,7 @@ bad_config:
 		if (IS_ERR(musb->clock)) {
 			status = PTR_ERR(musb->clock);
 			musb->clock = NULL;
-			goto fail;
+			goto fail1;
 		}
 	}
 
@@ -1962,12 +1949,12 @@ bad_config:
 	 */
 	musb->isr = generic_interrupt;
 	status = musb_platform_init(musb);
-
 	if (status < 0)
-		goto fail;
+		goto fail2;
+
 	if (!musb->isr) {
 		status = -ENODEV;
-		goto fail2;
+		goto fail3;
 	}
 
 #ifndef CONFIG_MUSB_PIO_ONLY
@@ -1993,7 +1980,7 @@ bad_config:
 			? MUSB_CONTROLLER_MHDRC
 			: MUSB_CONTROLLER_HDRC, musb);
 	if (status < 0)
-		goto fail2;
+		goto fail3;
 
 #ifdef CONFIG_USB_MUSB_OTG
 	setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb);
@@ -2006,7 +1993,7 @@ bad_config:
 	if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) {
 		dev_err(dev, "request_irq %d failed!\n", nIrq);
 		status = -ENODEV;
-		goto fail2;
+		goto fail3;
 	}
 	musb->nIrq = nIrq;
 /* FIXME this handles wakeup irqs wrong */
@@ -2017,19 +2004,6 @@ bad_config:
 		musb->irq_wake = 0;
 	}
 
-	pr_info("%s: USB %s mode controller at %p using %s, IRQ %d\n",
-			musb_driver_name,
-			({char *s;
-			switch (musb->board_mode) {
-			case MUSB_HOST:		s = "Host"; break;
-			case MUSB_PERIPHERAL:	s = "Peripheral"; break;
-			default:		s = "OTG"; break;
-			}; s; }),
-			ctrl,
-			(is_dma_capable() && musb->dma_controller)
-				? "DMA" : "PIO",
-			musb->nIrq);
-
 	/* host side needs more setup */
 	if (is_host_enabled(musb)) {
 		struct usb_hcd	*hcd = musb_to_hcd(musb);
@@ -2040,6 +2014,13 @@ bad_config:
 			hcd->self.otg_port = 1;
 		musb->xceiv->host = &hcd->self;
 		hcd->power_budget = 2 * (plat->power ? : 250);
+
+		/* program PHY to use external vBus if required */
+		if (plat->extvbus) {
+			u8 busctl = musb_read_ulpi_buscontrol(musb->mregs);
+			busctl |= MUSB_ULPI_USE_EXTVBUS;
+			musb_write_ulpi_buscontrol(musb->mregs, busctl);
+		}
 	}
 
 	/* For the host-only role, we can activate right away.
@@ -2052,8 +2033,6 @@ bad_config:
 		musb->xceiv->state = OTG_STATE_A_IDLE;
 
 		status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
-		if (status)
-			goto fail;
 
 		DBG(1, "%s mode, status %d, devctl %02x %c\n",
 			"HOST", status,
@@ -2068,8 +2047,6 @@ bad_config:
 		musb->xceiv->state = OTG_STATE_B_IDLE;
 
 		status = musb_gadget_setup(musb);
-		if (status)
-			goto fail;
 
 		DBG(1, "%s mode, status %d, dev%02x\n",
 			is_otg_enabled(musb) ? "OTG" : "PERIPHERAL",
@@ -2077,38 +2054,52 @@ bad_config:
 			musb_readb(musb->mregs, MUSB_DEVCTL));
 
 	}
+	if (status < 0)
+		goto fail3;
 
 #ifdef CONFIG_SYSFS
-	status = device_create_file(dev, &dev_attr_mode);
-	status = device_create_file(dev, &dev_attr_vbus);
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
-	status = device_create_file(dev, &dev_attr_srp);
-#endif /* CONFIG_USB_GADGET_MUSB_HDRC */
-	status = 0;
-#endif
+	status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group);
 	if (status)
-		goto fail2;
+		goto fail4;
+#endif
+
+	dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
+			({char *s;
+			 switch (musb->board_mode) {
+			 case MUSB_HOST:		s = "Host"; break;
+			 case MUSB_PERIPHERAL:	s = "Peripheral"; break;
+			 default:		s = "OTG"; break;
+			 }; s; }),
+			ctrl,
+			(is_dma_capable() && musb->dma_controller)
+			? "DMA" : "PIO",
+			musb->nIrq);
 
 	return 0;
 
-fail2:
-#ifdef CONFIG_SYSFS
-	device_remove_file(musb->controller, &dev_attr_mode);
-	device_remove_file(musb->controller, &dev_attr_vbus);
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
-	device_remove_file(musb->controller, &dev_attr_srp);
-#endif
-#endif
+fail4:
+	if (!is_otg_enabled(musb) && is_host_enabled(musb))
+		usb_remove_hcd(musb_to_hcd(musb));
+	else
+		musb_gadget_cleanup(musb);
+
+fail3:
+	if (musb->irq_wake)
+		device_init_wakeup(dev, 0);
 	musb_platform_exit(musb);
-fail:
-	dev_err(musb->controller,
-		"musb_init_controller failed with status %d\n", status);
 
+fail2:
 	if (musb->clock)
 		clk_put(musb->clock);
-	device_init_wakeup(dev, 0);
+
+fail1:
+	dev_err(musb->controller,
+		"musb_init_controller failed with status %d\n", status);
+
 	musb_free(musb);
 
+fail0:
+
 	return status;
 
 }
@@ -2127,6 +2118,7 @@ static int __init musb_probe(struct plat
 {
 	struct device	*dev = &pdev->dev;
 	int		irq = platform_get_irq(pdev, 0);
+	int		status;
 	struct resource	*iomem;
 	void __iomem	*base;
 
@@ -2134,7 +2126,7 @@ static int __init musb_probe(struct plat
 	if (!iomem || irq == 0)
 		return -ENODEV;
 
-	base = ioremap(iomem->start, iomem->end - iomem->start + 1);
+	base = ioremap(iomem->start, resource_size(iomem));
 	if (!base) {
 		dev_err(dev, "ioremap failed\n");
 		return -ENOMEM;
@@ -2144,7 +2136,11 @@ static int __init musb_probe(struct plat
 	/* clobbered by use_dma=n */
 	orig_dma_mask = dev->dma_mask;
 #endif
-	return musb_init_controller(dev, irq, base);
+	status = musb_init_controller(dev, irq, base);
+	if (status < 0)
+		iounmap(base);
+
+	return status;
 }
 
 static int __exit musb_remove(struct platform_device *pdev)
@@ -2162,6 +2158,10 @@ static int __exit musb_remove(struct pla
 	if (musb->board_mode == MUSB_HOST)
 		usb_remove_hcd(musb_to_hcd(musb));
 #endif
+	musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+	musb_platform_exit(musb);
+	musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+
 	musb_free(musb);
 	iounmap(ctrl_base);
 	device_init_wakeup(&pdev->dev, 0);
@@ -2173,6 +2173,150 @@ static int __exit musb_remove(struct pla
 
 #ifdef	CONFIG_PM
 
+static struct musb_context_registers musb_context;
+
+void musb_save_context(struct musb *musb)
+{
+	int i;
+	void __iomem *musb_base = musb->mregs;
+
+	if (is_host_enabled(musb)) {
+		musb_context.frame = musb_readw(musb_base, MUSB_FRAME);
+		musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE);
+		musb_context.busctl = musb_read_ulpi_buscontrol(musb->mregs);
+	}
+	musb_context.power = musb_readb(musb_base, MUSB_POWER);
+	musb_context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE);
+	musb_context.intrrxe = musb_readw(musb_base, MUSB_INTRRXE);
+	musb_context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE);
+	musb_context.index = musb_readb(musb_base, MUSB_INDEX);
+	musb_context.devctl = musb_readb(musb_base, MUSB_DEVCTL);
+
+	for (i = 0; i < MUSB_C_NUM_EPS; ++i) {
+		musb_writeb(musb_base, MUSB_INDEX, i);
+		musb_context.index_regs[i].txmaxp =
+			musb_readw(musb_base, 0x10 + MUSB_TXMAXP);
+		musb_context.index_regs[i].txcsr =
+			musb_readw(musb_base, 0x10 + MUSB_TXCSR);
+		musb_context.index_regs[i].rxmaxp =
+			musb_readw(musb_base, 0x10 + MUSB_RXMAXP);
+		musb_context.index_regs[i].rxcsr =
+			musb_readw(musb_base, 0x10 + MUSB_RXCSR);
+
+		if (musb->dyn_fifo) {
+			musb_context.index_regs[i].txfifoadd =
+					musb_read_txfifoadd(musb_base);
+			musb_context.index_regs[i].rxfifoadd =
+					musb_read_rxfifoadd(musb_base);
+			musb_context.index_regs[i].txfifosz =
+					musb_read_txfifosz(musb_base);
+			musb_context.index_regs[i].rxfifosz =
+					musb_read_rxfifosz(musb_base);
+		}
+		if (is_host_enabled(musb)) {
+			musb_context.index_regs[i].txtype =
+				musb_readb(musb_base, 0x10 + MUSB_TXTYPE);
+			musb_context.index_regs[i].txinterval =
+				musb_readb(musb_base, 0x10 + MUSB_TXINTERVAL);
+			musb_context.index_regs[i].rxtype =
+				musb_readb(musb_base, 0x10 + MUSB_RXTYPE);
+			musb_context.index_regs[i].rxinterval =
+				musb_readb(musb_base, 0x10 + MUSB_RXINTERVAL);
+
+			musb_context.index_regs[i].txfunaddr =
+				musb_read_txfunaddr(musb_base, i);
+			musb_context.index_regs[i].txhubaddr =
+				musb_read_txhubaddr(musb_base, i);
+			musb_context.index_regs[i].txhubport =
+				musb_read_txhubport(musb_base, i);
+
+			musb_context.index_regs[i].rxfunaddr =
+				musb_read_rxfunaddr(musb_base, i);
+			musb_context.index_regs[i].rxhubaddr =
+				musb_read_rxhubaddr(musb_base, i);
+			musb_context.index_regs[i].rxhubport =
+				musb_read_rxhubport(musb_base, i);
+		}
+	}
+
+	musb_writeb(musb_base, MUSB_INDEX, musb_context.index);
+
+	musb_platform_save_context(musb, &musb_context);
+}
+
+void musb_restore_context(struct musb *musb)
+{
+	int i;
+	void __iomem *musb_base = musb->mregs;
+	void __iomem *ep_target_regs;
+
+	musb_platform_restore_context(musb, &musb_context);
+
+	if (is_host_enabled(musb)) {
+		musb_writew(musb_base, MUSB_FRAME, musb_context.frame);
+		musb_writeb(musb_base, MUSB_TESTMODE, musb_context.testmode);
+		musb_write_ulpi_buscontrol(musb->mregs, musb_context.busctl);
+	}
+	musb_writeb(musb_base, MUSB_POWER, musb_context.power);
+	musb_writew(musb_base, MUSB_INTRTXE, musb_context.intrtxe);
+	musb_writew(musb_base, MUSB_INTRRXE, musb_context.intrrxe);
+	musb_writeb(musb_base, MUSB_INTRUSBE, musb_context.intrusbe);
+	musb_writeb(musb_base, MUSB_DEVCTL, musb_context.devctl);
+
+	for (i = 0; i < MUSB_C_NUM_EPS; ++i) {
+		musb_writeb(musb_base, MUSB_INDEX, i);
+		musb_writew(musb_base, 0x10 + MUSB_TXMAXP,
+			musb_context.index_regs[i].txmaxp);
+		musb_writew(musb_base, 0x10 + MUSB_TXCSR,
+			musb_context.index_regs[i].txcsr);
+		musb_writew(musb_base, 0x10 + MUSB_RXMAXP,
+			musb_context.index_regs[i].rxmaxp);
+		musb_writew(musb_base, 0x10 + MUSB_RXCSR,
+			musb_context.index_regs[i].rxcsr);
+
+		if (musb->dyn_fifo) {
+			musb_write_txfifosz(musb_base,
+				musb_context.index_regs[i].txfifosz);
+			musb_write_rxfifosz(musb_base,
+				musb_context.index_regs[i].rxfifosz);
+			musb_write_txfifoadd(musb_base,
+				musb_context.index_regs[i].txfifoadd);
+			musb_write_rxfifoadd(musb_base,
+				musb_context.index_regs[i].rxfifoadd);
+		}
+
+		if (is_host_enabled(musb)) {
+			musb_writeb(musb_base, 0x10 + MUSB_TXTYPE,
+				musb_context.index_regs[i].txtype);
+			musb_writeb(musb_base, 0x10 + MUSB_TXINTERVAL,
+				musb_context.index_regs[i].txinterval);
+			musb_writeb(musb_base, 0x10 + MUSB_RXTYPE,
+				musb_context.index_regs[i].rxtype);
+			musb_writeb(musb_base, 0x10 + MUSB_RXINTERVAL,
+
+			musb_context.index_regs[i].rxinterval);
+			musb_write_txfunaddr(musb_base, i,
+				musb_context.index_regs[i].txfunaddr);
+			musb_write_txhubaddr(musb_base, i,
+				musb_context.index_regs[i].txhubaddr);
+			musb_write_txhubport(musb_base, i,
+				musb_context.index_regs[i].txhubport);
+
+			ep_target_regs =
+				musb_read_target_reg_base(i, musb_base);
+
+			musb_write_rxfunaddr(ep_target_regs,
+				musb_context.index_regs[i].rxfunaddr);
+			musb_write_rxhubaddr(ep_target_regs,
+				musb_context.index_regs[i].rxhubaddr);
+			musb_write_rxhubport(ep_target_regs,
+				musb_context.index_regs[i].rxhubport);
+		}
+	}
+
+	musb_writeb(musb_base, MUSB_INDEX, musb_context.index);
+}
+
 static int musb_suspend(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
@@ -2194,6 +2338,8 @@ static int musb_suspend(struct device *d
 		 */
 	}
 
+	musb_save_context(musb);
+
 	if (musb->set_clock)
 		musb->set_clock(musb->clock, 0);
 	else
@@ -2215,6 +2361,8 @@ static int musb_resume_noirq(struct devi
 	else
 		clk_enable(musb->clock);
 
+	musb_restore_context(musb);
+
 	/* for static cmos like DaVinci, register values were preserved
 	 * unless for some reason the whole soc powered down or the USB
 	 * module got reset through the PSC (vs just being disabled).
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/musb_core.h linux-libre-2.6.34-gnu1/drivers/usb/musb/musb_core.h
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/musb_core.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/musb_core.h	2010-05-16 17:17:36.000000000 -0400
@@ -52,6 +52,15 @@ struct musb;
 struct musb_hw_ep;
 struct musb_ep;
 
+/* Helper defines for struct musb->hwvers */
+#define MUSB_HWVERS_MAJOR(x)	((x >> 10) & 0x1f)
+#define MUSB_HWVERS_MINOR(x)	(x & 0x3ff)
+#define MUSB_HWVERS_RC		0x8000
+#define MUSB_HWVERS_1300	0x52C
+#define MUSB_HWVERS_1400	0x590
+#define MUSB_HWVERS_1800	0x720
+#define MUSB_HWVERS_1900	0x784
+#define MUSB_HWVERS_2000	0x800
 
 #include "musb_debug.h"
 #include "musb_dma.h"
@@ -322,13 +331,6 @@ struct musb {
 	struct clk		*clock;
 	irqreturn_t		(*isr)(int, void *);
 	struct work_struct	irq_work;
-#define MUSB_HWVERS_MAJOR(x)	((x >> 10) & 0x1f)
-#define MUSB_HWVERS_MINOR(x)	(x & 0x3ff)
-#define MUSB_HWVERS_RC		0x8000
-#define MUSB_HWVERS_1300	0x52C
-#define MUSB_HWVERS_1400	0x590
-#define MUSB_HWVERS_1800	0x720
-#define MUSB_HWVERS_2000	0x800
 	u16			hwvers;
 
 /* this hub status bit is reserved by USB 2.0 and not seen by usbcore */
@@ -411,22 +413,15 @@ struct musb {
 
 	unsigned		hb_iso_rx:1;	/* high bandwidth iso rx? */
 	unsigned		hb_iso_tx:1;	/* high bandwidth iso tx? */
+	unsigned		dyn_fifo:1;	/* dynamic FIFO supported? */
 
-#ifdef C_MP_TX
-	unsigned bulk_split:1;
+	unsigned		bulk_split:1;
 #define	can_bulk_split(musb,type) \
-		(((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_split)
-#else
-#define	can_bulk_split(musb, type)	0
-#endif
+	(((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_split)
 
-#ifdef C_MP_RX
-	unsigned bulk_combine:1;
+	unsigned		bulk_combine:1;
 #define	can_bulk_combine(musb,type) \
-		(((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_combine)
-#else
-#define	can_bulk_combine(musb, type)	0
-#endif
+	(((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_combine)
 
 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
 	/* is_suspended means USB B_PERIPHERAL suspend */
@@ -461,6 +456,45 @@ struct musb {
 #endif
 };
 
+#ifdef CONFIG_PM
+struct musb_csr_regs {
+	/* FIFO registers */
+	u16 txmaxp, txcsr, rxmaxp, rxcsr;
+	u16 rxfifoadd, txfifoadd;
+	u8 txtype, txinterval, rxtype, rxinterval;
+	u8 rxfifosz, txfifosz;
+	u8 txfunaddr, txhubaddr, txhubport;
+	u8 rxfunaddr, rxhubaddr, rxhubport;
+};
+
+struct musb_context_registers {
+
+#ifdef CONFIG_PM
+	u32 otg_sysconfig, otg_forcestandby;
+#endif
+	u8 power;
+	u16 intrtxe, intrrxe;
+	u8 intrusbe;
+	u16 frame;
+	u8 index, testmode;
+
+	u8 devctl, busctl, misc;
+
+	struct musb_csr_regs index_regs[MUSB_C_NUM_EPS];
+};
+
+#ifdef CONFIG_PM
+extern void musb_platform_save_context(struct musb *musb,
+		struct musb_context_registers *musb_context);
+extern void musb_platform_restore_context(struct musb *musb,
+		struct musb_context_registers *musb_context);
+#else
+#define musb_platform_save_context(m, x)	do {} while (0)
+#define musb_platform_restore_context(m, x)	do {} while (0)
+#endif
+
+#endif
+
 static inline void musb_set_vbus(struct musb *musb, int is_on)
 {
 	musb->board_set_vbus(musb, is_on);
@@ -562,7 +596,7 @@ extern void musb_hnp_stop(struct musb *m
 extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode);
 
 #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \
-	defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
+	defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
 extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout);
 #else
 #define musb_platform_try_idle(x, y)		do {} while (0)
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/musb_gadget.c linux-libre-2.6.34-gnu1/drivers/usb/musb/musb_gadget.c
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/musb_gadget.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/musb_gadget.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,7 @@
 #include <linux/moduleparam.h>
 #include <linux/stat.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include "musb_core.h"
 
@@ -895,7 +896,14 @@ static int musb_gadget_enable(struct usb
 		/* REVISIT if can_bulk_split(), use by updating "tmp";
 		 * likewise high bandwidth periodic tx
 		 */
-		musb_writew(regs, MUSB_TXMAXP, tmp);
+		/* Set TXMAXP with the FIFO size of the endpoint
+		 * to disable double buffering mode. Currently, It seems that double
+		 * buffering has problem if musb RTL revision number < 2.0.
+		 */
+		if (musb->hwvers < MUSB_HWVERS_2000)
+			musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx);
+		else
+			musb_writew(regs, MUSB_TXMAXP, tmp);
 
 		csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG;
 		if (musb_readw(regs, MUSB_TXCSR)
@@ -925,7 +933,13 @@ static int musb_gadget_enable(struct usb
 		/* REVISIT if can_bulk_combine() use by updating "tmp"
 		 * likewise high bandwidth periodic rx
 		 */
-		musb_writew(regs, MUSB_RXMAXP, tmp);
+		/* Set RXMAXP with the FIFO size of the endpoint
+		 * to disable double buffering mode.
+		 */
+		if (musb->hwvers < MUSB_HWVERS_2000)
+			musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_rx);
+		else
+			musb_writew(regs, MUSB_RXMAXP, tmp);
 
 		/* force shared fifo to OUT-only mode */
 		if (hw_ep->is_shared_fifo) {
@@ -1697,8 +1711,7 @@ int usb_gadget_register_driver(struct us
 		return -EINVAL;
 
 	/* driver must be initialized to support peripheral mode */
-	if (!musb || !(musb->board_mode == MUSB_OTG
-				|| musb->board_mode != MUSB_OTG)) {
+	if (!musb) {
 		DBG(1, "%s, no dev??\n", __func__);
 		return -ENODEV;
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/musb_host.c linux-libre-2.6.34-gnu1/drivers/usb/musb/musb_host.c
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/musb_host.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/musb_host.c	2010-05-16 17:17:36.000000000 -0400
@@ -605,8 +605,14 @@ musb_rx_reinit(struct musb *musb, struct
 	musb_writeb(ep->regs, MUSB_RXTYPE, qh->type_reg);
 	musb_writeb(ep->regs, MUSB_RXINTERVAL, qh->intv_reg);
 	/* NOTE: bulk combining rewrites high bits of maxpacket */
-	musb_writew(ep->regs, MUSB_RXMAXP,
-			qh->maxpacket | ((qh->hb_mult - 1) << 11));
+	/* Set RXMAXP with the FIFO size of the endpoint
+	 * to disable double buffer mode.
+	 */
+	if (musb->hwvers < MUSB_HWVERS_2000)
+		musb_writew(ep->regs, MUSB_RXMAXP, ep->max_packet_sz_rx);
+	else
+		musb_writew(ep->regs, MUSB_RXMAXP,
+				qh->maxpacket | ((qh->hb_mult - 1) << 11));
 
 	ep->rx_reinit = 0;
 }
@@ -1683,7 +1689,7 @@ void musb_host_rx(struct musb *musb, u8
 				dma->desired_mode = 1;
 			if (rx_count < hw_ep->max_packet_sz_rx) {
 				length = rx_count;
-				dma->bDesiredMode = 0;
+				dma->desired_mode = 0;
 			} else {
 				length = urb->transfer_buffer_length;
 			}
@@ -1771,6 +1777,9 @@ static int musb_schedule(
 	int			best_end, epnum;
 	struct musb_hw_ep	*hw_ep = NULL;
 	struct list_head	*head = NULL;
+	u8			toggle;
+	u8			txtype;
+	struct urb		*urb = next_urb(qh);
 
 	/* use fixed hardware for control and bulk */
 	if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
@@ -1809,6 +1818,27 @@ static int musb_schedule(
 		diff -= (qh->maxpacket * qh->hb_mult);
 
 		if (diff >= 0 && best_diff > diff) {
+
+			/*
+			 * Mentor controller has a bug in that if we schedule
+			 * a BULK Tx transfer on an endpoint that had earlier
+			 * handled ISOC then the BULK transfer has to start on
+			 * a zero toggle.  If the BULK transfer starts on a 1
+			 * toggle then this transfer will fail as the mentor
+			 * controller starts the Bulk transfer on a 0 toggle
+			 * irrespective of the programming of the toggle bits
+			 * in the TXCSR register.  Check for this condition
+			 * while allocating the EP for a Tx Bulk transfer.  If
+			 * so skip this EP.
+			 */
+			hw_ep = musb->endpoints + epnum;
+			toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in);
+			txtype = (musb_readb(hw_ep->regs, MUSB_TXTYPE)
+					>> 4) & 0x3;
+			if (!is_in && (qh->type == USB_ENDPOINT_XFER_BULK) &&
+				toggle && (txtype == USB_ENDPOINT_XFER_ISOC))
+				continue;
+
 			best_diff = diff;
 			best_end = epnum;
 		}
@@ -2012,6 +2042,7 @@ static int musb_urb_enqueue(
 		 * odd, rare, error prone, but legal.
 		 */
 		kfree(qh);
+		qh = NULL;
 		ret = 0;
 	} else
 		ret = musb_schedule(musb, qh,
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/musbhsdma.c linux-libre-2.6.34-gnu1/drivers/usb/musb/musbhsdma.c
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/musbhsdma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/musbhsdma.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include "musb_core.h"
 #include "musbhsdma.h"
 
@@ -250,20 +251,39 @@ static irqreturn_t dma_controller_irq(in
 	u8 bchannel;
 	u8 int_hsdma;
 
-	u32 addr;
+	u32 addr, count;
 	u16 csr;
 
 	spin_lock_irqsave(&musb->lock, flags);
 
 	int_hsdma = musb_readb(mbase, MUSB_HSDMA_INTR);
-	if (!int_hsdma)
-		goto done;
 
 #ifdef CONFIG_BLACKFIN
 	/* Clear DMA interrupt flags */
 	musb_writeb(mbase, MUSB_HSDMA_INTR, int_hsdma);
 #endif
 
+	if (!int_hsdma) {
+		DBG(2, "spurious DMA irq\n");
+
+		for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) {
+			musb_channel = (struct musb_dma_channel *)
+					&(controller->channel[bchannel]);
+			channel = &musb_channel->channel;
+			if (channel->status == MUSB_DMA_STATUS_BUSY) {
+				count = musb_read_hsdma_count(mbase, bchannel);
+
+				if (count == 0)
+					int_hsdma |= (1 << bchannel);
+			}
+		}
+
+		DBG(2, "int_hsdma = 0x%x\n", int_hsdma);
+
+		if (!int_hsdma)
+			goto done;
+	}
+
 	for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) {
 		if (int_hsdma & (1 << bchannel)) {
 			musb_channel = (struct musb_dma_channel *)
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/musbhsdma.h linux-libre-2.6.34-gnu1/drivers/usb/musb/musbhsdma.h
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/musbhsdma.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/musbhsdma.h	2010-05-16 17:17:36.000000000 -0400
@@ -55,6 +55,10 @@
 		    MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), \
 		    addr)
 
+#define musb_read_hsdma_count(mbase, bchannel)	\
+	musb_readl(mbase,	\
+		   MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT))
+
 #define musb_write_hsdma_count(mbase, bchannel, len) \
 	musb_writel(mbase, \
 		    MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), \
@@ -96,6 +100,19 @@ static inline void musb_write_hsdma_addr
 		((u16)(((u32) dma_addr >> 16) & 0xFFFF)));
 }
 
+static inline u32 musb_read_hsdma_count(void __iomem *mbase, u8 bchannel)
+{
+	u32 count = musb_readw(mbase,
+		MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH));
+
+	count = count << 16;
+
+	count |= musb_readw(mbase,
+		MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW));
+
+	return count;
+}
+
 static inline void musb_write_hsdma_count(void __iomem *mbase,
 				u8 bchannel, u32 len)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/musb_regs.h linux-libre-2.6.34-gnu1/drivers/usb/musb/musb_regs.h
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/musb_regs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/musb_regs.h	2010-05-16 17:17:36.000000000 -0400
@@ -72,6 +72,10 @@
 #define MUSB_DEVCTL_HR		0x02
 #define MUSB_DEVCTL_SESSION	0x01
 
+/* MUSB ULPI VBUSCONTROL */
+#define MUSB_ULPI_USE_EXTVBUS	0x01
+#define MUSB_ULPI_USE_EXTVBUSIND 0x02
+
 /* TESTMODE */
 #define MUSB_TEST_FORCE_HOST	0x80
 #define MUSB_TEST_FIFO_ACCESS	0x40
@@ -246,6 +250,7 @@
 
 /* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */
 #define MUSB_HWVERS		0x6C	/* 8 bit */
+#define MUSB_ULPI_BUSCONTROL	0x70	/* 8 bit */
 
 #define MUSB_EPINFO		0x78	/* 8 bit */
 #define MUSB_RAMINFO		0x79	/* 8 bit */
@@ -321,6 +326,36 @@ static inline void  musb_write_rxfifoadd
 	musb_writew(mbase, MUSB_RXFIFOADD, c_off);
 }
 
+static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val)
+{
+	musb_writeb(mbase, MUSB_ULPI_BUSCONTROL, val);
+}
+
+static inline u8 musb_read_txfifosz(void __iomem *mbase)
+{
+	return musb_readb(mbase, MUSB_TXFIFOSZ);
+}
+
+static inline u16 musb_read_txfifoadd(void __iomem *mbase)
+{
+	return musb_readw(mbase, MUSB_TXFIFOADD);
+}
+
+static inline u8 musb_read_rxfifosz(void __iomem *mbase)
+{
+	return musb_readb(mbase, MUSB_RXFIFOSZ);
+}
+
+static inline u16  musb_read_rxfifoadd(void __iomem *mbase)
+{
+	return musb_readw(mbase, MUSB_RXFIFOADD);
+}
+
+static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase)
+{
+	return musb_readb(mbase, MUSB_ULPI_BUSCONTROL);
+}
+
 static inline u8 musb_read_configdata(void __iomem *mbase)
 {
 	musb_writeb(mbase, MUSB_INDEX, 0);
@@ -376,6 +411,36 @@ static inline void  musb_write_txhubport
 			qh_h_port_reg);
 }
 
+static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum)
+{
+	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXFUNCADDR));
+}
+
+static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum)
+{
+	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBADDR));
+}
+
+static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum)
+{
+	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBPORT));
+}
+
+static inline u8  musb_read_txfunaddr(void __iomem *mbase, u8 epnum)
+{
+	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR));
+}
+
+static inline u8  musb_read_txhubaddr(void __iomem *mbase, u8 epnum)
+{
+	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR));
+}
+
+static inline u8  musb_read_txhubport(void __iomem *mbase, u8 epnum)
+{
+	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT));
+}
+
 #else /* CONFIG_BLACKFIN */
 
 #define USB_BASE		USB_FADDR
@@ -436,7 +501,7 @@ static inline void  musb_write_txhubport
 #define MUSB_FLAT_OFFSET(_epnum, _offset)	\
 	(USB_OFFSET(USB_EP_NI0_TXMAXP) + (0x40 * (_epnum)) + (_offset))
 
-/* Not implemented - HW has seperate Tx/Rx FIFO */
+/* Not implemented - HW has separate Tx/Rx FIFO */
 #define MUSB_TXCSR_MODE			0x0000
 
 static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size)
@@ -455,6 +520,35 @@ static inline void  musb_write_rxfifoadd
 {
 }
 
+static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val)
+{
+}
+
+static inline u8 musb_read_txfifosz(void __iomem *mbase)
+{
+	return 0;
+}
+
+static inline u16 musb_read_txfifoadd(void __iomem *mbase)
+{
+	return 0;
+}
+
+static inline u8 musb_read_rxfifosz(void __iomem *mbase)
+{
+	return 0;
+}
+
+static inline u16  musb_read_rxfifoadd(void __iomem *mbase)
+{
+	return 0;
+}
+
+static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase)
+{
+	return 0;
+}
+
 static inline u8 musb_read_configdata(void __iomem *mbase)
 {
 	return 0;
@@ -462,7 +556,11 @@ static inline u8 musb_read_configdata(vo
 
 static inline u16 musb_read_hwvers(void __iomem *mbase)
 {
-	return 0;
+	/*
+	 * This register is invisible on Blackfin, actually the MUSB
+	 * RTL version of Blackfin is 1.9, so just harcode its value.
+	 */
+	return MUSB_HWVERS_1900;
 }
 
 static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase)
@@ -500,6 +598,35 @@ static inline void  musb_write_txhubport
 {
 }
 
+static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum)
+{
+	return 0;
+}
+
+static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum)
+{
+	return 0;
+}
+
+static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum)
+{
+	return 0;
+}
+
+static inline u8  musb_read_txfunaddr(void __iomem *mbase, u8 epnum)
+{
+	return 0;
+}
+
+static inline u8  musb_read_txhubaddr(void __iomem *mbase, u8 epnum)
+{
+	return 0;
+}
+
+static inline void  musb_read_txhubport(void __iomem *mbase, u8 epnum)
+{
+}
+
 #endif /* CONFIG_BLACKFIN */
 
 #endif	/* __MUSB_REGS_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/musb_virthub.c linux-libre-2.6.34-gnu1/drivers/usb/musb/musb_virthub.c
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/musb_virthub.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/musb_virthub.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,7 +35,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/time.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/omap2430.c linux-libre-2.6.34-gnu1/drivers/usb/musb/omap2430.c
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/omap2430.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/omap2430.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/clk.h>
@@ -220,7 +219,7 @@ int __init musb_platform_init(struct mus
 
 	musb_platform_resume(musb);
 
-	l = omap_readl(OTG_SYSCONFIG);
+	l = musb_readl(musb->mregs, OTG_SYSCONFIG);
 	l &= ~ENABLEWAKEUP;	/* disable wakeup */
 	l &= ~NOSTDBY;		/* remove possible nostdby */
 	l |= SMARTSTDBY;	/* enable smart standby */
@@ -233,17 +232,19 @@ int __init musb_platform_init(struct mus
 	 */
 	if (!cpu_is_omap3430())
 		l |= AUTOIDLE;		/* enable auto idle */
-	omap_writel(l, OTG_SYSCONFIG);
+	musb_writel(musb->mregs, OTG_SYSCONFIG, l);
 
-	l = omap_readl(OTG_INTERFSEL);
+	l = musb_readl(musb->mregs, OTG_INTERFSEL);
 	l |= ULPI_12PIN;
-	omap_writel(l, OTG_INTERFSEL);
+	musb_writel(musb->mregs, OTG_INTERFSEL, l);
 
 	pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
 			"sysstatus 0x%x, intrfsel 0x%x, simenable  0x%x\n",
-			omap_readl(OTG_REVISION), omap_readl(OTG_SYSCONFIG),
-			omap_readl(OTG_SYSSTATUS), omap_readl(OTG_INTERFSEL),
-			omap_readl(OTG_SIMENABLE));
+			musb_readl(musb->mregs, OTG_REVISION),
+			musb_readl(musb->mregs, OTG_SYSCONFIG),
+			musb_readl(musb->mregs, OTG_SYSSTATUS),
+			musb_readl(musb->mregs, OTG_INTERFSEL),
+			musb_readl(musb->mregs, OTG_SIMENABLE));
 
 	omap_vbus_power(musb, musb->board_mode == MUSB_HOST, 1);
 
@@ -255,6 +256,22 @@ int __init musb_platform_init(struct mus
 	return 0;
 }
 
+#ifdef CONFIG_PM
+void musb_platform_save_context(struct musb *musb,
+		struct musb_context_registers *musb_context)
+{
+	musb_context->otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG);
+	musb_context->otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY);
+}
+
+void musb_platform_restore_context(struct musb *musb,
+		struct musb_context_registers *musb_context)
+{
+	musb_writel(musb->mregs, OTG_SYSCONFIG, musb_context->otg_sysconfig);
+	musb_writel(musb->mregs, OTG_FORCESTDBY, musb_context->otg_forcestandby);
+}
+#endif
+
 int musb_platform_suspend(struct musb *musb)
 {
 	u32 l;
@@ -263,13 +280,13 @@ int musb_platform_suspend(struct musb *m
 		return 0;
 
 	/* in any role */
-	l = omap_readl(OTG_FORCESTDBY);
+	l = musb_readl(musb->mregs, OTG_FORCESTDBY);
 	l |= ENABLEFORCE;	/* enable MSTANDBY */
-	omap_writel(l, OTG_FORCESTDBY);
+	musb_writel(musb->mregs, OTG_FORCESTDBY, l);
 
-	l = omap_readl(OTG_SYSCONFIG);
+	l = musb_readl(musb->mregs, OTG_SYSCONFIG);
 	l |= ENABLEWAKEUP;	/* enable wakeup */
-	omap_writel(l, OTG_SYSCONFIG);
+	musb_writel(musb->mregs, OTG_SYSCONFIG, l);
 
 	otg_set_suspend(musb->xceiv, 1);
 
@@ -295,13 +312,13 @@ static int musb_platform_resume(struct m
 	else
 		clk_enable(musb->clock);
 
-	l = omap_readl(OTG_SYSCONFIG);
+	l = musb_readl(musb->mregs, OTG_SYSCONFIG);
 	l &= ~ENABLEWAKEUP;	/* disable wakeup */
-	omap_writel(l, OTG_SYSCONFIG);
+	musb_writel(musb->mregs, OTG_SYSCONFIG, l);
 
-	l = omap_readl(OTG_FORCESTDBY);
+	l = musb_readl(musb->mregs, OTG_FORCESTDBY);
 	l &= ~ENABLEFORCE;	/* disable MSTANDBY */
-	omap_writel(l, OTG_FORCESTDBY);
+	musb_writel(musb->mregs, OTG_FORCESTDBY, l);
 
 	return 0;
 }
@@ -314,8 +331,5 @@ int musb_platform_exit(struct musb *musb
 
 	musb_platform_suspend(musb);
 
-	clk_put(musb->clock);
-	musb->clock = NULL;
-
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/omap2430.h linux-libre-2.6.34-gnu1/drivers/usb/musb/omap2430.h
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/omap2430.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/omap2430.h	2010-05-16 17:17:36.000000000 -0400
@@ -10,47 +10,43 @@
 #ifndef __MUSB_OMAP243X_H__
 #define __MUSB_OMAP243X_H__
 
-#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
-#include <mach/hardware.h>
 #include <plat/usb.h>
 
 /*
  * OMAP2430-specific definitions
  */
 
-#define MENTOR_BASE_OFFSET	0
-#if	defined(CONFIG_ARCH_OMAP2430)
-#define	OMAP_HSOTG_BASE		(OMAP243X_HS_BASE)
-#elif	defined(CONFIG_ARCH_OMAP3430)
-#define	OMAP_HSOTG_BASE		(OMAP34XX_HSUSB_OTG_BASE)
-#endif
-#define OMAP_HSOTG(offset)	(OMAP_HSOTG_BASE + 0x400 + (offset))
-#define OTG_REVISION		OMAP_HSOTG(0x0)
-#define OTG_SYSCONFIG		OMAP_HSOTG(0x4)
+#define OTG_REVISION		0x400
+
+#define OTG_SYSCONFIG		0x404
 #	define	MIDLEMODE	12	/* bit position */
 #	define	FORCESTDBY		(0 << MIDLEMODE)
 #	define	NOSTDBY			(1 << MIDLEMODE)
 #	define	SMARTSTDBY		(2 << MIDLEMODE)
+
 #	define	SIDLEMODE		3	/* bit position */
 #	define	FORCEIDLE		(0 << SIDLEMODE)
 #	define	NOIDLE			(1 << SIDLEMODE)
 #	define	SMARTIDLE		(2 << SIDLEMODE)
+
 #	define	ENABLEWAKEUP		(1 << 2)
 #	define	SOFTRST			(1 << 1)
 #	define	AUTOIDLE		(1 << 0)
-#define OTG_SYSSTATUS		OMAP_HSOTG(0x8)
+
+#define OTG_SYSSTATUS		0x408
 #	define	RESETDONE		(1 << 0)
-#define OTG_INTERFSEL		OMAP_HSOTG(0xc)
+
+#define OTG_INTERFSEL		0x40c
 #	define	EXTCP			(1 << 2)
-#	define	PHYSEL		0	/* bit position */
+#	define	PHYSEL			0	/* bit position */
 #	define	UTMI_8BIT		(0 << PHYSEL)
 #	define	ULPI_12PIN		(1 << PHYSEL)
 #	define	ULPI_8PIN		(2 << PHYSEL)
-#define OTG_SIMENABLE		OMAP_HSOTG(0x10)
+
+#define OTG_SIMENABLE		0x410
 #	define	TM1			(1 << 0)
-#define OTG_FORCESTDBY		OMAP_HSOTG(0x14)
-#	define	ENABLEFORCE		(1 << 0)
 
-#endif	/* CONFIG_ARCH_OMAP2430 */
+#define OTG_FORCESTDBY		0x414
+#	define	ENABLEFORCE		(1 << 0)
 
 #endif	/* __MUSB_OMAP243X_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/tusb6010.c linux-libre-2.6.34-gnu1/drivers/usb/musb/tusb6010.c
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/tusb6010.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/tusb6010.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,19 @@ static void tusb_source_power(struct mus
 #define TUSB_REV_MAJOR(reg_val)		((reg_val >> 4) & 0xf)
 #define TUSB_REV_MINOR(reg_val)		(reg_val & 0xf)
 
+#ifdef CONFIG_PM
+/* REVISIT: These should be only needed if somebody implements off idle */
+void musb_platform_save_context(struct musb *musb,
+			struct musb_context_registers *musb_context)
+{
+}
+
+void musb_platform_restore_context(struct musb *musb,
+			struct musb_context_registers *musb_context)
+{
+}
+#endif
+
 /*
  * Checks the revision. We need to use the DMA register as 3.0 does not
  * have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV.
@@ -1118,7 +1131,7 @@ int __init musb_platform_init(struct mus
 	}
 	musb->sync = mem->start;
 
-	sync = ioremap(mem->start, mem->end - mem->start + 1);
+	sync = ioremap(mem->start, resource_size(mem));
 	if (!sync) {
 		pr_debug("ioremap for sync failed\n");
 		ret = -ENOMEM;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/musb/tusb6010_omap.c linux-libre-2.6.34-gnu1/drivers/usb/musb/tusb6010_omap.c
--- linux-libre-2.6.33-gnu1/drivers/usb/musb/tusb6010_omap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/musb/tusb6010_omap.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/usb.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <plat/dma.h>
 #include <plat/mux.h>
 
@@ -38,7 +39,7 @@ struct tusb_omap_dma_ch {
 
 	struct tusb_omap_dma	*tusb_dma;
 
-	void __iomem		*dma_addr;
+	dma_addr_t		dma_addr;
 
 	u32			len;
 	u16			packet_sz;
@@ -125,6 +126,7 @@ static void tusb_omap_dma_cb(int lch, u1
 	struct tusb_omap_dma_ch	*chdat = to_chdat(channel);
 	struct tusb_omap_dma	*tusb_dma = chdat->tusb_dma;
 	struct musb		*musb = chdat->musb;
+	struct device		*dev = musb->controller;
 	struct musb_hw_ep	*hw_ep = chdat->hw_ep;
 	void __iomem		*ep_conf = hw_ep->conf;
 	void __iomem		*mbase = musb->mregs;
@@ -172,13 +174,15 @@ static void tusb_omap_dma_cb(int lch, u1
 		DBG(3, "Using PIO for remaining %lu bytes\n", pio);
 		buf = phys_to_virt((u32)chdat->dma_addr) + chdat->transfer_len;
 		if (chdat->tx) {
-			dma_cache_maint(phys_to_virt((u32)chdat->dma_addr),
-					chdat->transfer_len, DMA_TO_DEVICE);
+			dma_unmap_single(dev, chdat->dma_addr,
+						chdat->transfer_len,
+						DMA_TO_DEVICE);
 			musb_write_fifo(hw_ep, pio, buf);
 		} else {
+			dma_unmap_single(dev, chdat->dma_addr,
+						chdat->transfer_len,
+						DMA_FROM_DEVICE);
 			musb_read_fifo(hw_ep, pio, buf);
-			dma_cache_maint(phys_to_virt((u32)chdat->dma_addr),
-					chdat->transfer_len, DMA_FROM_DEVICE);
 		}
 		channel->actual_len += pio;
 	}
@@ -223,6 +227,7 @@ static int tusb_omap_dma_program(struct
 	struct tusb_omap_dma_ch		*chdat = to_chdat(channel);
 	struct tusb_omap_dma		*tusb_dma = chdat->tusb_dma;
 	struct musb			*musb = chdat->musb;
+	struct device			*dev = musb->controller;
 	struct musb_hw_ep		*hw_ep = chdat->hw_ep;
 	void __iomem			*mbase = musb->mregs;
 	void __iomem			*ep_conf = hw_ep->conf;
@@ -298,14 +303,16 @@ static int tusb_omap_dma_program(struct
 	chdat->packet_sz = packet_sz;
 	chdat->len = len;
 	channel->actual_len = 0;
-	chdat->dma_addr = (void __iomem *)dma_addr;
+	chdat->dma_addr = dma_addr;
 	channel->status = MUSB_DMA_STATUS_BUSY;
 
 	/* Since we're recycling dma areas, we need to clean or invalidate */
 	if (chdat->tx)
-		dma_cache_maint(phys_to_virt(dma_addr), len, DMA_TO_DEVICE);
+		dma_map_single(dev, phys_to_virt(dma_addr), len,
+				DMA_TO_DEVICE);
 	else
-		dma_cache_maint(phys_to_virt(dma_addr), len, DMA_FROM_DEVICE);
+		dma_map_single(dev, phys_to_virt(dma_addr), len,
+				DMA_FROM_DEVICE);
 
 	/* Use 16-bit transfer if dma_addr is not 32-bit aligned */
 	if ((dma_addr & 0x3) == 0) {
@@ -648,7 +655,7 @@ void dma_controller_destroy(struct dma_c
 		}
 	}
 
-	if (!tusb_dma->multichannel && tusb_dma && tusb_dma->ch >= 0)
+	if (tusb_dma && !tusb_dma->multichannel && tusb_dma->ch >= 0)
 		omap_free_dma(tusb_dma->ch);
 
 	kfree(tusb_dma);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/otg/gpio_vbus.c linux-libre-2.6.34-gnu1/drivers/usb/otg/gpio_vbus.c
--- linux-libre-2.6.33-gnu1/drivers/usb/otg/gpio_vbus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/otg/gpio_vbus.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/usb.h>
 #include <linux/workqueue.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/otg/nop-usb-xceiv.c linux-libre-2.6.34-gnu1/drivers/usb/otg/nop-usb-xceiv.c
--- linux-libre-2.6.33-gnu1/drivers/usb/otg/nop-usb-xceiv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/otg/nop-usb-xceiv.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/usb/otg.h>
+#include <linux/slab.h>
 
 struct nop_usb_xceiv {
 	struct otg_transceiver	otg;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/otg/twl4030-usb.c linux-libre-2.6.34-gnu1/drivers/usb/otg/twl4030-usb.c
--- linux-libre-2.6.33-gnu1/drivers/usb/otg/twl4030-usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/otg/twl4030-usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,7 +36,8 @@
 #include <linux/i2c/twl.h>
 #include <linux/regulator/consumer.h>
 #include <linux/err.h>
-
+#include <linux/notifier.h>
+#include <linux/slab.h>
 
 /* Register defines */
 
@@ -236,15 +237,6 @@
 #define PMBR1				0x0D
 #define GPIO_USB_4PIN_ULPI_2430C	(3 << 0)
 
-
-
-enum linkstat {
-	USB_LINK_UNKNOWN = 0,
-	USB_LINK_NONE,
-	USB_LINK_VBUS,
-	USB_LINK_ID,
-};
-
 struct twl4030_usb {
 	struct otg_transceiver	otg;
 	struct device		*dev;
@@ -347,10 +339,10 @@ twl4030_usb_clear_bits(struct twl4030_us
 
 /*-------------------------------------------------------------------------*/
 
-static enum linkstat twl4030_usb_linkstat(struct twl4030_usb *twl)
+static enum usb_xceiv_events twl4030_usb_linkstat(struct twl4030_usb *twl)
 {
 	int	status;
-	int	linkstat = USB_LINK_UNKNOWN;
+	int	linkstat = USB_EVENT_NONE;
 
 	/*
 	 * For ID/VBUS sensing, see manual section 15.4.8 ...
@@ -368,11 +360,11 @@ static enum linkstat twl4030_usb_linksta
 		dev_err(twl->dev, "USB link status err %d\n", status);
 	else if (status & (BIT(7) | BIT(2))) {
 		if (status & BIT(2))
-			linkstat = USB_LINK_ID;
+			linkstat = USB_EVENT_ID;
 		else
-			linkstat = USB_LINK_VBUS;
+			linkstat = USB_EVENT_VBUS;
 	} else
-		linkstat = USB_LINK_NONE;
+		linkstat = USB_EVENT_NONE;
 
 	dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n",
 			status, status, linkstat);
@@ -383,7 +375,7 @@ static enum linkstat twl4030_usb_linksta
 
 	spin_lock_irq(&twl->lock);
 	twl->linkstat = linkstat;
-	if (linkstat == USB_LINK_ID) {
+	if (linkstat == USB_EVENT_ID) {
 		twl->otg.default_a = true;
 		twl->otg.state = OTG_STATE_A_IDLE;
 	} else {
@@ -564,7 +556,7 @@ static ssize_t twl4030_usb_vbus_show(str
 
 	spin_lock_irqsave(&twl->lock, flags);
 	ret = sprintf(buf, "%s\n",
-			(twl->linkstat == USB_LINK_VBUS) ? "on" : "off");
+			(twl->linkstat == USB_EVENT_VBUS) ? "on" : "off");
 	spin_unlock_irqrestore(&twl->lock, flags);
 
 	return ret;
@@ -576,17 +568,8 @@ static irqreturn_t twl4030_usb_irq(int i
 	struct twl4030_usb *twl = _twl;
 	int status;
 
-#ifdef CONFIG_LOCKDEP
-	/* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
-	 * we don't want and can't tolerate.  Although it might be
-	 * friendlier not to borrow this thread context...
-	 */
-	local_irq_enable();
-#endif
-
 	status = twl4030_usb_linkstat(twl);
-	if (status != USB_LINK_UNKNOWN) {
-
+	if (status >= 0) {
 		/* FIXME add a set_power() method so that B-devices can
 		 * configure the charger appropriately.  It's not always
 		 * correct to consume VBUS power, and how much current to
@@ -598,12 +581,13 @@ static irqreturn_t twl4030_usb_irq(int i
 		 * USB_LINK_VBUS state.  musb_hdrc won't care until it
 		 * starts to handle softconnect right.
 		 */
-		if (status == USB_LINK_NONE)
+		if (status == USB_EVENT_NONE)
 			twl4030_phy_suspend(twl, 0);
 		else
 			twl4030_phy_resume(twl);
 
-		twl4030charger_usb_en(status == USB_LINK_VBUS);
+		blocking_notifier_call_chain(&twl->otg.notifier, status,
+				twl->otg.gadget);
 	}
 	sysfs_notify(&twl->dev->kobj, NULL, "vbus");
 
@@ -693,6 +677,8 @@ static int __devinit twl4030_usb_probe(s
 	if (device_create_file(&pdev->dev, &dev_attr_vbus))
 		dev_warn(&pdev->dev, "could not create sysfs file\n");
 
+	BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier);
+
 	/* Our job is to use irqs and status from the power module
 	 * to keep the transceiver disabled when nothing's connected.
 	 *
@@ -702,7 +688,7 @@ static int __devinit twl4030_usb_probe(s
 	 * need both handles, otherwise just one suffices.
 	 */
 	twl->irq_enabled = true;
-	status = request_irq(twl->irq, twl4030_usb_irq,
+	status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq,
 			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
 			"twl4030_usb", twl);
 	if (status < 0) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/otg/ulpi.c linux-libre-2.6.34-gnu1/drivers/usb/otg/ulpi.c
--- linux-libre-2.6.33-gnu1/drivers/usb/otg/ulpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/otg/ulpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/ulpi.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/aircable.c linux-libre-2.6.34-gnu1/drivers/usb/serial/aircable.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/aircable.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/aircable.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,7 @@
  */
 
 #include <linux/tty.h>
+#include <linux/slab.h>
 #include <linux/tty_flip.h>
 #include <linux/circ_buf.h>
 #include <linux/usb.h>
@@ -78,7 +79,7 @@ static int debug;
 #define DRIVER_DESC "AIRcable USB Driver"
 
 /* ID table that will be registered with USB core */
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(AIRCABLE_VID, AIRCABLE_USB_PID) },
 	{ },
 };
@@ -468,10 +469,6 @@ static void aircable_read_bulk_callback(
 
 	if (status) {
 		dbg("%s - urb status = %d", __func__, status);
-		if (!port->port.count) {
-			dbg("%s - port is closed, exiting.", __func__);
-			return;
-		}
 		if (status == -EPROTO) {
 			dbg("%s - caught -EPROTO, resubmitting the urb",
 			    __func__);
@@ -530,23 +527,19 @@ static void aircable_read_bulk_callback(
 	}
 	tty_kref_put(tty);
 
-	/* Schedule the next read _if_ we are still open */
-	if (port->port.count) {
-		usb_fill_bulk_urb(port->read_urb, port->serial->dev,
-				  usb_rcvbulkpipe(port->serial->dev,
-					  port->bulk_in_endpointAddress),
-				  port->read_urb->transfer_buffer,
-				  port->read_urb->transfer_buffer_length,
-				  aircable_read_bulk_callback, port);
-
-		result = usb_submit_urb(urb, GFP_ATOMIC);
-		if (result)
-			dev_err(&urb->dev->dev,
-				"%s - failed resubmitting read urb, error %d\n",
-				__func__, result);
-	}
+	/* Schedule the next read */
+	usb_fill_bulk_urb(port->read_urb, port->serial->dev,
+			  usb_rcvbulkpipe(port->serial->dev,
+				  port->bulk_in_endpointAddress),
+			  port->read_urb->transfer_buffer,
+			  port->read_urb->transfer_buffer_length,
+			  aircable_read_bulk_callback, port);
 
-	return;
+	result = usb_submit_urb(urb, GFP_ATOMIC);
+	if (result && result != -EPERM)
+		dev_err(&urb->dev->dev,
+			"%s - failed resubmitting read urb, error %d\n",
+			__func__, result);
 }
 
 /* Based on ftdi_sio.c throttle */
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/ark3116.c linux-libre-2.6.34-gnu1/drivers/usb/serial/ark3116.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/ark3116.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/ark3116.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/ioctl.h>
 #include <linux/tty.h>
+#include <linux/slab.h>
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/usb.h>
@@ -50,7 +51,7 @@ static int debug;
 /* usb timeout of 1 second */
 #define ARK_TIMEOUT (1*HZ)
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x6547, 0x0232) },
 	{ USB_DEVICE(0x18ec, 0x3118) },		/* USB to IrDA adapter */
 	{ },
@@ -733,7 +734,6 @@ static void ark3116_read_bulk_callback(s
 
 		tty = tty_port_tty_get(&port->port);
 		if (tty) {
-			tty_buffer_request_room(tty, urb->actual_length + 1);
 			/* overrun is special, not associated with a char */
 			if (unlikely(lsr & UART_LSR_OE))
 				tty_insert_flip_char(tty, 0, TTY_OVERRUN);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/belkin_sa.c linux-libre-2.6.34-gnu1/drivers/usb/serial/belkin_sa.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/belkin_sa.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/belkin_sa.c	2010-05-16 17:17:36.000000000 -0400
@@ -103,7 +103,7 @@ static int  belkin_sa_tiocmset(struct tt
 					unsigned int set, unsigned int clear);
 
 
-static struct usb_device_id id_table_combined [] = {
+static const struct usb_device_id id_table_combined[] = {
 	{ USB_DEVICE(BELKIN_SA_VID, BELKIN_SA_PID) },
 	{ USB_DEVICE(BELKIN_OLD_VID, BELKIN_OLD_PID) },
 	{ USB_DEVICE(PERACOM_VID, PERACOM_PID) },
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/bus.c linux-libre-2.6.34-gnu1/drivers/usb/serial/bus.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/bus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/bus.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/ch341.c linux-libre-2.6.34-gnu1/drivers/usb/serial/ch341.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/ch341.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/ch341.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,9 +19,11 @@
 #include <linux/init.h>
 #include <linux/tty.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include <linux/serial.h>
+#include <asm/unaligned.h>
 
 #define DEFAULT_BAUD_RATE 9600
 #define DEFAULT_TIMEOUT   1000
@@ -70,7 +72,7 @@
 
 static int debug;
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x4348, 0x5523) },
 	{ USB_DEVICE(0x1a86, 0x7523) },
 	{ },
@@ -392,16 +394,22 @@ static void ch341_break_ctl(struct tty_s
 	struct usb_serial_port *port = tty->driver_data;
 	int r;
 	uint16_t reg_contents;
-	uint8_t break_reg[2];
+	uint8_t *break_reg;
 
 	dbg("%s()", __func__);
 
+	break_reg = kmalloc(2, GFP_KERNEL);
+	if (!break_reg) {
+		dev_err(&port->dev, "%s - kmalloc failed\n", __func__);
+		return;
+	}
+
 	r = ch341_control_in(port->serial->dev, CH341_REQ_READ_REG,
-			ch341_break_reg, 0, break_reg, sizeof(break_reg));
+			ch341_break_reg, 0, break_reg, 2);
 	if (r < 0) {
-		printk(KERN_WARNING "%s: USB control read error whilst getting"
-				" break register contents.\n", __FILE__);
-		return;
+		dev_err(&port->dev, "%s - USB control read error (%d)\n",
+				__func__, r);
+		goto out;
 	}
 	dbg("%s - initial ch341 break register contents - reg1: %x, reg2: %x",
 			__func__, break_reg[0], break_reg[1]);
@@ -416,12 +424,14 @@ static void ch341_break_ctl(struct tty_s
 	}
 	dbg("%s - New ch341 break register contents - reg1: %x, reg2: %x",
 			__func__, break_reg[0], break_reg[1]);
-	reg_contents = (uint16_t)break_reg[0] | ((uint16_t)break_reg[1] << 8);
+	reg_contents = get_unaligned_le16(break_reg);
 	r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG,
 			ch341_break_reg, reg_contents);
 	if (r < 0)
-		printk(KERN_WARNING "%s: USB control write error whilst setting"
-				" break register contents.\n", __FILE__);
+		dev_err(&port->dev, "%s - USB control write error (%d)\n",
+				__func__, r);
+out:
+	kfree(break_reg);
 }
 
 static int ch341_tiocmset(struct tty_struct *tty, struct file *file,
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/console.c linux-libre-2.6.34-gnu1/drivers/usb/serial/console.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/console.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/console.c	2010-05-16 17:17:36.000000000 -0400
@@ -181,6 +181,7 @@ static int usb_console_setup(struct cons
 	/* The console is special in terms of closing the device so
 	 * indicate this port is now acting as a system console. */
 	port->console = 1;
+	port->port.console = 1;
 
 	mutex_unlock(&serial->disc_mutex);
 	return retval;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/cp210x.c linux-libre-2.6.34-gnu1/drivers/usb/serial/cp210x.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/cp210x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/cp210x.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,7 +55,7 @@ static int cp210x_carrier_raised(struct
 
 static int debug;
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */
 	{ USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
 	{ USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */
@@ -91,11 +91,12 @@ static struct usb_device_id id_table []
 	{ USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
 	{ USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
 	{ USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */
+	{ USB_DEVICE(0x10C4, 0x81E8) }, /* Zephyr Bioharness */
 	{ USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */
 	{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
 	{ USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */
 	{ USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */
-	{ USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */
+	{ USB_DEVICE(0x10C4, 0x8293) }, /* Telegesys ETRX2USB */
 	{ USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */
 	{ USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
 	{ USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */
@@ -312,11 +313,6 @@ static int cp210x_set_config(struct usb_
 		return -EPROTO;
 	}
 
-	/* Single data value */
-	result = usb_control_msg(serial->dev,
-			usb_sndctrlpipe(serial->dev, 0),
-			request, REQTYPE_HOST_TO_DEVICE, data[0],
-			0, NULL, 0, 300);
 	return 0;
 }
 
@@ -612,7 +608,7 @@ static void cp210x_set_termios(struct tt
 				baud);
 		if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV,
 					((BAUD_RATE_GEN_FREQ + baud/2) / baud))) {
-			dbg("Baud rate requested not supported by device\n");
+			dbg("Baud rate requested not supported by device");
 			baud = tty_termios_baud_rate(old_termios);
 		}
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/cyberjack.c linux-libre-2.6.34-gnu1/drivers/usb/serial/cyberjack.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/cyberjack.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/cyberjack.c	2010-05-16 17:17:36.000000000 -0400
@@ -70,7 +70,7 @@ static void cyberjack_read_int_callback(
 static void cyberjack_read_bulk_callback(struct urb *urb);
 static void cyberjack_write_bulk_callback(struct urb *urb);
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) },
 	{ }			/* Terminating entry */
 };
@@ -391,11 +391,10 @@ static void cyberjack_read_bulk_callback
 
 	tty = tty_port_tty_get(&port->port);
 	if (!tty) {
-		dbg("%s - ignoring since device not open\n", __func__);
+		dbg("%s - ignoring since device not open", __func__);
 		return;
 	}
 	if (urb->actual_length) {
-		tty_buffer_request_room(tty, urb->actual_length);
 		tty_insert_flip_string(tty, data, urb->actual_length);
 		tty_flip_buffer_push(tty);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/cypress_m8.c linux-libre-2.6.34-gnu1/drivers/usb/serial/cypress_m8.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/cypress_m8.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/cypress_m8.c	2010-05-16 17:17:36.000000000 -0400
@@ -66,17 +66,15 @@
 #include <linux/serial.h>
 #include <linux/delay.h>
 #include <linux/uaccess.h>
+#include <asm/unaligned.h>
 
 #include "cypress_m8.h"
 
 
-#ifdef CONFIG_USB_SERIAL_DEBUG
-	static int debug = 1;
-#else
-	static int debug;
-#endif
+static int debug;
 static int stats;
 static int interval;
+static int unstable_bauds;
 
 /*
  * Version Information
@@ -89,24 +87,24 @@ static int interval;
 #define CYPRESS_BUF_SIZE	1024
 #define CYPRESS_CLOSING_WAIT	(30*HZ)
 
-static struct usb_device_id id_table_earthmate [] = {
+static const struct usb_device_id id_table_earthmate[] = {
 	{ USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) },
 	{ USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
 	{ }						/* Terminating entry */
 };
 
-static struct usb_device_id id_table_cyphidcomrs232 [] = {
+static const struct usb_device_id id_table_cyphidcomrs232[] = {
 	{ USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
 	{ USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
 	{ }						/* Terminating entry */
 };
 
-static struct usb_device_id id_table_nokiaca42v2 [] = {
+static const struct usb_device_id id_table_nokiaca42v2[] = {
 	{ USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) },
 	{ }						/* Terminating entry */
 };
 
-static struct usb_device_id id_table_combined [] = {
+static const struct usb_device_id id_table_combined[] = {
 	{ USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) },
 	{ USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
 	{ USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
@@ -154,7 +152,7 @@ struct cypress_private {
 	int isthrottled;		   /* if throttled, discard reads */
 	wait_queue_head_t delta_msr_wait;  /* used for TIOCMIWAIT */
 	char prev_status, diff_status;	   /* used for TIOCMIWAIT */
-	/* we pass a pointer to this as the arguement sent to
+	/* we pass a pointer to this as the argument sent to
 	   cypress_set_termios old_termios */
 	struct ktermios tmp_termios; 	   /* stores the old termios settings */
 };
@@ -295,6 +293,9 @@ static int analyze_baud_rate(struct usb_
 	struct cypress_private *priv;
 	priv = usb_get_serial_port_data(port);
 
+	if (unstable_bauds)
+		return new_rate;
+
 	/*
 	 * The general purpose firmware for the Cypress M8 allows for
 	 * a maximum speed of 57600bps (I have no idea whether DeLorme
@@ -344,7 +345,8 @@ static int cypress_serial_control(struct
 {
 	int new_baudrate = 0, retval = 0, tries = 0;
 	struct cypress_private *priv;
-	__u8 feature_buffer[5];
+	u8 *feature_buffer;
+	const unsigned int feature_len = 5;
 	unsigned long flags;
 
 	dbg("%s", __func__);
@@ -354,17 +356,18 @@ static int cypress_serial_control(struct
 	if (!priv->comm_is_ok)
 		return -ENODEV;
 
+	feature_buffer = kcalloc(feature_len, sizeof(u8), GFP_KERNEL);
+	if (!feature_buffer)
+		return -ENOMEM;
+
 	switch (cypress_request_type) {
 	case CYPRESS_SET_CONFIG:
-		new_baudrate = priv->baud_rate;
 		/* 0 means 'Hang up' so doesn't change the true bit rate */
-		if (baud_rate == 0)
-			new_baudrate = priv->baud_rate;
-		/* Change of speed ? */
-		else if (baud_rate != priv->baud_rate) {
+		new_baudrate = priv->baud_rate;
+		if (baud_rate && baud_rate != priv->baud_rate) {
 			dbg("%s - baud rate is changing", __func__);
 			retval = analyze_baud_rate(port, baud_rate);
-			if (retval >=  0) {
+			if (retval >= 0) {
 				new_baudrate = retval;
 				dbg("%s - New baud rate set to %d",
 				    __func__, new_baudrate);
@@ -373,9 +376,8 @@ static int cypress_serial_control(struct
 		dbg("%s - baud rate is being sent as %d",
 					__func__, new_baudrate);
 
-		memset(feature_buffer, 0, sizeof(feature_buffer));
 		/* fill the feature_buffer with new configuration */
-		*((u_int32_t *)feature_buffer) = new_baudrate;
+		put_unaligned_le32(new_baudrate, feature_buffer);
 		feature_buffer[4] |= data_bits;   /* assign data bits in 2 bit space ( max 3 ) */
 		/* 1 bit gap */
 		feature_buffer[4] |= (stop_bits << 3);   /* assign stop bits in 1 bit space */
@@ -397,15 +399,15 @@ static int cypress_serial_control(struct
 					HID_REQ_SET_REPORT,
 					USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
 					0x0300, 0, feature_buffer,
-					sizeof(feature_buffer), 500);
+					feature_len, 500);
 
 			if (tries++ >= 3)
 				break;
 
-		} while (retval != sizeof(feature_buffer) &&
+		} while (retval != feature_len &&
 			 retval != -ENODEV);
 
-		if (retval != sizeof(feature_buffer)) {
+		if (retval != feature_len) {
 			dev_err(&port->dev, "%s - failed sending serial "
 				"line settings - %d\n", __func__, retval);
 			cypress_set_dead(port);
@@ -425,43 +427,42 @@ static int cypress_serial_control(struct
 			/* Not implemented for this device,
 			   and if we try to do it we're likely
 			   to crash the hardware. */
-			return -ENOTTY;
+			retval = -ENOTTY;
+			goto out;
 		}
 		dbg("%s - retreiving serial line settings", __func__);
-		/* set initial values in feature buffer */
-		memset(feature_buffer, 0, sizeof(feature_buffer));
-
 		do {
 			retval = usb_control_msg(port->serial->dev,
 					usb_rcvctrlpipe(port->serial->dev, 0),
 					HID_REQ_GET_REPORT,
 					USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
 					0x0300, 0, feature_buffer,
-					sizeof(feature_buffer), 500);
+					feature_len, 500);
 
 			if (tries++ >= 3)
 				break;
-		} while (retval != sizeof(feature_buffer)
+		} while (retval != feature_len
 						&& retval != -ENODEV);
 
-		if (retval != sizeof(feature_buffer)) {
+		if (retval != feature_len) {
 			dev_err(&port->dev, "%s - failed to retrieve serial "
 				"line settings - %d\n", __func__, retval);
 			cypress_set_dead(port);
-			return retval;
+			goto out;
 		} else {
 			spin_lock_irqsave(&priv->lock, flags);
 			/* store the config in one byte, and later
 			   use bit masks to check values */
 			priv->current_config = feature_buffer[4];
-			priv->baud_rate = *((u_int32_t *)feature_buffer);
+			priv->baud_rate = get_unaligned_le32(feature_buffer);
 			spin_unlock_irqrestore(&priv->lock, flags);
 		}
 	}
 	spin_lock_irqsave(&priv->lock, flags);
 	++priv->cmd_count;
 	spin_unlock_irqrestore(&priv->lock, flags);
-
+out:
+	kfree(feature_buffer);
 	return retval;
 } /* cypress_serial_control */
 
@@ -690,7 +691,6 @@ static void cypress_dtr_rts(struct usb_s
 {
 	struct cypress_private *priv = usb_get_serial_port_data(port);
 	/* drop dtr and rts */
-	priv = usb_get_serial_port_data(port);
 	spin_lock_irq(&priv->lock);
 	if (on == 0)
 		priv->line_control = 0;
@@ -1307,13 +1307,9 @@ static void cypress_read_int_callback(st
 		spin_unlock_irqrestore(&priv->lock, flags);
 
 	/* process read if there is data other than line status */
-	if (tty && (bytes > i)) {
-		bytes = tty_buffer_request_room(tty, bytes);
-		for (; i < bytes ; ++i) {
-			dbg("pushing byte number %d - %d - %c", i, data[i],
-					data[i]);
-			tty_insert_flip_char(tty, data[i], tty_flag);
-		}
+	if (tty && bytes > i) {
+		tty_insert_flip_string_fixed_flag(tty, data + i,
+				bytes - i, tty_flag);
 		tty_flip_buffer_push(tty);
 	}
 
@@ -1325,9 +1321,9 @@ static void cypress_read_int_callback(st
 continue_read:
 	tty_kref_put(tty);
 
-	/* Continue trying to always read... unless the port has closed. */
+	/* Continue trying to always read */
 
-	if (port->port.count > 0 && priv->comm_is_ok) {
+	if (priv->comm_is_ok) {
 		usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev,
 				usb_rcvintpipe(port->serial->dev,
 					port->interrupt_in_endpointAddress),
@@ -1336,7 +1332,7 @@ continue_read:
 				cypress_read_int_callback, port,
 				priv->read_urb_interval);
 		result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
-		if (result) {
+		if (result && result != -EPERM) {
 			dev_err(&urb->dev->dev, "%s - failed resubmitting "
 					"read urb, error %d\n", __func__,
 					result);
@@ -1650,3 +1646,5 @@ module_param(stats, bool, S_IRUGO | S_IW
 MODULE_PARM_DESC(stats, "Enable statistics or not");
 module_param(interval, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(interval, "Overrides interrupt interval");
+module_param(unstable_bauds, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(unstable_bauds, "Allow unstable baud rates");
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/digi_acceleport.c linux-libre-2.6.34-gnu1/drivers/usb/serial/digi_acceleport.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/digi_acceleport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/digi_acceleport.c	2010-05-16 17:17:36.000000000 -0400
@@ -470,18 +470,18 @@ static int digi_read_oob_callback(struct
 
 static int debug;
 
-static struct usb_device_id id_table_combined [] = {
+static const struct usb_device_id id_table_combined[] = {
 	{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) },
 	{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_4_ID) },
 	{ }						/* Terminating entry */
 };
 
-static struct usb_device_id id_table_2 [] = {
+static const struct usb_device_id id_table_2[] = {
 	{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) },
 	{ }						/* Terminating entry */
 };
 
-static struct usb_device_id id_table_4 [] = {
+static const struct usb_device_id id_table_4[] = {
 	{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_4_ID) },
 	{ }						/* Terminating entry */
 };
@@ -1262,10 +1262,10 @@ static void digi_write_bulk_callback(str
 		return;
 	}
 
-	/* try to send any buffered data on this port, if it is open */
+	/* try to send any buffered data on this port */
 	spin_lock(&priv->dp_port_lock);
 	priv->dp_write_urb_in_use = 0;
-	if (port->port.count && priv->dp_out_buf_len > 0) {
+	if (priv->dp_out_buf_len > 0) {
 		*((unsigned char *)(port->write_urb->transfer_buffer))
 			= (unsigned char)DIGI_CMD_SEND_DATA;
 		*((unsigned char *)(port->write_urb->transfer_buffer) + 1)
@@ -1288,7 +1288,7 @@ static void digi_write_bulk_callback(str
 	schedule_work(&priv->dp_wakeup_work);
 
 	spin_unlock(&priv->dp_port_lock);
-	if (ret)
+	if (ret && ret != -EPERM)
 		dev_err(&port->dev,
 			"%s: usb_submit_urb failed, ret=%d, port=%d\n",
 			__func__, ret, priv->dp_port_num);
@@ -1353,8 +1353,7 @@ static int digi_open(struct tty_struct *
 	struct digi_port *priv = usb_get_serial_port_data(port);
 	struct ktermios not_termios;
 
-	dbg("digi_open: TOP: port=%d, open_count=%d",
-		priv->dp_port_num, port->port.count);
+	dbg("digi_open: TOP: port=%d", priv->dp_port_num);
 
 	/* be sure the device is started up */
 	if (digi_startup_device(port->serial) != 0)
@@ -1393,8 +1392,7 @@ static void digi_close(struct usb_serial
 	unsigned char buf[32];
 	struct digi_port *priv = usb_get_serial_port_data(port);
 
-	dbg("digi_close: TOP: port=%d, open_count=%d",
-		priv->dp_port_num, port->port.count);
+	dbg("digi_close: TOP: port=%d", priv->dp_port_num);
 
 	mutex_lock(&port->serial->disc_mutex);
 	/* if disconnected, just clear flags */
@@ -1629,7 +1627,7 @@ static void digi_read_bulk_callback(stru
 	/* continue read */
 	urb->dev = port->serial->dev;
 	ret = usb_submit_urb(urb, GFP_ATOMIC);
-	if (ret != 0) {
+	if (ret != 0 && ret != -EPERM) {
 		dev_err(&port->dev,
 			"%s: failed resubmitting urb, ret=%d, port=%d\n",
 			__func__, ret, priv->dp_port_num);
@@ -1658,12 +1656,11 @@ static int digi_read_inb_callback(struct
 	int port_status = ((unsigned char *)urb->transfer_buffer)[2];
 	unsigned char *data = ((unsigned char *)urb->transfer_buffer) + 3;
 	int flag, throttled;
-	int i;
 	int status = urb->status;
 
 	/* do not process callbacks on closed ports */
 	/* but do continue the read chain */
-	if (port->port.count == 0)
+	if (urb->status == -ENOENT)
 		return 0;
 
 	/* short/multiple packet check */
@@ -1705,17 +1702,9 @@ static int digi_read_inb_callback(struct
 
 		/* data length is len-1 (one byte of len is port_status) */
 		--len;
-
-		len = tty_buffer_request_room(tty, len);
 		if (len > 0) {
-			/* Hot path */
-			if (flag == TTY_NORMAL)
-				tty_insert_flip_string(tty, data, len);
-			else {
-				for (i = 0; i < len; i++)
-					tty_insert_flip_char(tty,
-								data[i], flag);
-			}
+			tty_insert_flip_string_fixed_flag(tty, data, len,
+									flag);
 			tty_flip_buffer_push(tty);
 		}
 	}
@@ -1776,8 +1765,7 @@ static int digi_read_oob_callback(struct
 
 		tty = tty_port_tty_get(&port->port);
 		rts = 0;
-		if (port->port.count)
-			rts = tty->termios->c_cflag & CRTSCTS;
+		rts = tty->termios->c_cflag & CRTSCTS;
 		
 		if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) {
 			spin_lock(&priv->dp_port_lock);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/empeg.c linux-libre-2.6.34-gnu1/drivers/usb/serial/empeg.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/empeg.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/empeg.c	2010-05-16 17:17:36.000000000 -0400
@@ -93,7 +93,7 @@ static void empeg_init_termios(struct tt
 static void empeg_write_bulk_callback(struct urb *urb);
 static void empeg_read_bulk_callback(struct urb *urb);
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
@@ -346,7 +346,6 @@ static void empeg_read_bulk_callback(str
 	tty = tty_port_tty_get(&port->port);
 
 	if (urb->actual_length) {
-		tty_buffer_request_room(tty, urb->actual_length);
 		tty_insert_flip_string(tty, data, urb->actual_length);
 		tty_flip_buffer_push(tty);
 		bytes_in += urb->actual_length;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/ftdi_sio.c linux-libre-2.6.34-gnu1/drivers/usb/serial/ftdi_sio.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/ftdi_sio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/ftdi_sio.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,12 +33,12 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/mutex.h>
 #include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/serial.h>
@@ -88,10 +88,10 @@ struct ftdi_private {
 
 	unsigned int latency;		/* latency setting in use */
 	spinlock_t tx_lock;	/* spinlock for transmit state */
-	unsigned long tx_bytes;
 	unsigned long tx_outstanding_bytes;
 	unsigned long tx_outstanding_urbs;
 	unsigned short max_packet_size;
+	struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() and change_speed() */
 };
 
 /* struct ftdi_sio_quirk is used by devices requiring special attention. */
@@ -614,6 +614,7 @@ static struct usb_device_id id_table_com
 	{ USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) },
 	{ USB_DEVICE(TTI_VID, TTI_QL355P_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
+	{ USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) },
 	{ USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
 	{ USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
 	{ USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) },
@@ -657,6 +658,7 @@ static struct usb_device_id id_table_com
 	{ USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
 	{ USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) },
 	{ USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) },
+	{ USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) },
@@ -737,6 +739,10 @@ static struct usb_device_id id_table_com
 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 	{ USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) },
 	{ USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) },
+	{ USB_DEVICE(FTDI_VID, MJSG_GENERIC_PID) },
+	{ USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) },
+	{ USB_DEVICE(FTDI_VID, MJSG_HD_RADIO_PID) },
+	{ USB_DEVICE(FTDI_VID, MJSG_XM_RADIO_PID) },
 	{ },					/* Optional parameter entry */
 	{ }					/* Terminating entry */
 };
@@ -812,7 +818,7 @@ static struct usb_serial_driver ftdi_sio
 		.name =		"ftdi_sio",
 	},
 	.description =		"FTDI USB Serial Device",
-	.usb_driver = 		&ftdi_driver ,
+	.usb_driver = 		&ftdi_driver,
 	.id_table =		id_table_combined,
 	.num_ports =		1,
 	.probe =		ftdi_sio_probe,
@@ -828,8 +834,8 @@ static struct usb_serial_driver ftdi_sio
 	.chars_in_buffer =	ftdi_chars_in_buffer,
 	.read_bulk_callback =	ftdi_read_bulk_callback,
 	.write_bulk_callback =	ftdi_write_bulk_callback,
-	.tiocmget =             ftdi_tiocmget,
-	.tiocmset =             ftdi_tiocmset,
+	.tiocmget =		ftdi_tiocmget,
+	.tiocmset =		ftdi_tiocmset,
 	.ioctl =		ftdi_ioctl,
 	.set_termios =		ftdi_set_termios,
 	.break_ctl =		ftdi_break_ctl,
@@ -935,7 +941,6 @@ static int update_mctrl(struct usb_seria
 							unsigned int clear)
 {
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
-	char *buf;
 	unsigned urb_value;
 	int rv;
 
@@ -944,10 +949,6 @@ static int update_mctrl(struct usb_seria
 		return 0;	/* no change */
 	}
 
-	buf = kmalloc(1, GFP_NOIO);
-	if (!buf)
-		return -ENOMEM;
-
 	clear &= ~set;	/* 'set' takes precedence over 'clear' */
 	urb_value = 0;
 	if (clear & TIOCM_DTR)
@@ -963,9 +964,7 @@ static int update_mctrl(struct usb_seria
 			       FTDI_SIO_SET_MODEM_CTRL_REQUEST,
 			       FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
 			       urb_value, priv->interface,
-			       buf, 0, WDR_TIMEOUT);
-
-	kfree(buf);
+			       NULL, 0, WDR_TIMEOUT);
 	if (rv < 0) {
 		dbg("%s Error from MODEM_CTRL urb: DTR %s, RTS %s",
 				__func__,
@@ -1124,16 +1123,11 @@ static __u32 get_ftdi_divisor(struct tty
 static int change_speed(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
-	char *buf;
 	__u16 urb_value;
 	__u16 urb_index;
 	__u32 urb_index_value;
 	int rv;
 
-	buf = kmalloc(1, GFP_NOIO);
-	if (!buf)
-		return -ENOMEM;
-
 	urb_index_value = get_ftdi_divisor(tty, port);
 	urb_value = (__u16)urb_index_value;
 	urb_index = (__u16)(urb_index_value >> 16);
@@ -1146,9 +1140,7 @@ static int change_speed(struct tty_struc
 			    FTDI_SIO_SET_BAUDRATE_REQUEST,
 			    FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE,
 			    urb_value, urb_index,
-			    buf, 0, WDR_SHORT_TIMEOUT);
-
-	kfree(buf);
+			    NULL, 0, WDR_SHORT_TIMEOUT);
 	return rv;
 }
 
@@ -1156,8 +1148,7 @@ static int write_latency_timer(struct us
 {
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
 	struct usb_device *udev = port->serial->dev;
-	char buf[1];
-	int rv = 0;
+	int rv;
 	int l = priv->latency;
 
 	if (priv->flags & ASYNC_LOW_LATENCY)
@@ -1170,8 +1161,7 @@ static int write_latency_timer(struct us
 			     FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
 			     FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
 			     l, priv->interface,
-			     buf, 0, WDR_TIMEOUT);
-
+			     NULL, 0, WDR_TIMEOUT);
 	if (rv < 0)
 		dev_err(&port->dev, "Unable to write latency timer: %i\n", rv);
 	return rv;
@@ -1181,24 +1171,29 @@ static int read_latency_timer(struct usb
 {
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
 	struct usb_device *udev = port->serial->dev;
-	unsigned short latency = 0;
-	int rv = 0;
-
+	unsigned char *buf;
+	int rv;
 
 	dbg("%s", __func__);
 
+	buf = kmalloc(1, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
 	rv = usb_control_msg(udev,
 			     usb_rcvctrlpipe(udev, 0),
 			     FTDI_SIO_GET_LATENCY_TIMER_REQUEST,
 			     FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE,
 			     0, priv->interface,
-			     (char *) &latency, 1, WDR_TIMEOUT);
-
-	if (rv < 0) {
+			     buf, 1, WDR_TIMEOUT);
+	if (rv < 0)
 		dev_err(&port->dev, "Unable to read latency timer: %i\n", rv);
-		return -EIO;
-	}
-	return latency;
+	else
+		priv->latency = buf[0];
+
+	kfree(buf);
+
+	return rv;
 }
 
 static int get_serial_info(struct usb_serial_port *port,
@@ -1229,7 +1224,7 @@ static int set_serial_info(struct tty_st
 	if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
 		return -EFAULT;
 
-	lock_kernel();
+	mutex_lock(&priv->cfg_lock);
 	old_priv = *priv;
 
 	/* Do error checking and permission checking */
@@ -1237,7 +1232,7 @@ static int set_serial_info(struct tty_st
 	if (!capable(CAP_SYS_ADMIN)) {
 		if (((new_serial.flags & ~ASYNC_USR_MASK) !=
 		     (priv->flags & ~ASYNC_USR_MASK))) {
-			unlock_kernel();
+			mutex_unlock(&priv->cfg_lock);
 			return -EPERM;
 		}
 		priv->flags = ((priv->flags & ~ASYNC_USR_MASK) |
@@ -1248,7 +1243,7 @@ static int set_serial_info(struct tty_st
 
 	if ((new_serial.baud_base != priv->baud_base) &&
 	    (new_serial.baud_base < 9600)) {
-	    	unlock_kernel();
+		mutex_unlock(&priv->cfg_lock);
 		return -EINVAL;
 	}
 
@@ -1278,11 +1273,11 @@ check_and_exit:
 	     (priv->flags & ASYNC_SPD_MASK)) ||
 	    (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) &&
 	     (old_priv.custom_divisor != priv->custom_divisor))) {
-		unlock_kernel();
 		change_speed(tty, port);
+		mutex_unlock(&priv->cfg_lock);
 	}
 	else
-		unlock_kernel();
+		mutex_unlock(&priv->cfg_lock);
 	return 0;
 
 } /* set_serial_info */
@@ -1338,20 +1333,20 @@ static void ftdi_determine_type(struct u
 					__func__);
 		}
 	} else if (version < 0x200) {
-		/* Old device.  Assume its the original SIO. */
+		/* Old device.  Assume it's the original SIO. */
 		priv->chip_type = SIO;
 		priv->baud_base = 12000000 / 16;
 		priv->write_offset = 1;
 	} else if (version < 0x400) {
-		/* Assume its an FT8U232AM (or FT8U245AM) */
+		/* Assume it's an FT8U232AM (or FT8U245AM) */
 		/* (It might be a BM because of the iSerialNumber bug,
 		 * but it will still work as an AM device.) */
 		priv->chip_type = FT8U232AM;
 	} else if (version < 0x600) {
-		/* Assume its an FT232BM (or FT245BM) */
+		/* Assume it's an FT232BM (or FT245BM) */
 		priv->chip_type = FT232BM;
 	} else {
-		/* Assume its an FT232R  */
+		/* Assume it's an FT232R */
 		priv->chip_type = FT232RL;
 	}
 	dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]);
@@ -1371,7 +1366,7 @@ static void ftdi_set_max_packet_size(str
 	struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc;
 
 	unsigned num_endpoints;
-	int i = 0;
+	int i;
 
 	num_endpoints = interface->cur_altsetting->desc.bNumEndpoints;
 	dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints);
@@ -1423,7 +1418,7 @@ static ssize_t store_latency_timer(struc
 	struct usb_serial_port *port = to_usb_serial_port(dev);
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
 	int v = simple_strtoul(valbuf, NULL, 10);
-	int rv = 0;
+	int rv;
 
 	priv->latency = v;
 	rv = write_latency_timer(port);
@@ -1440,9 +1435,8 @@ static ssize_t store_event_char(struct d
 	struct usb_serial_port *port = to_usb_serial_port(dev);
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
 	struct usb_device *udev = port->serial->dev;
-	char buf[1];
 	int v = simple_strtoul(valbuf, NULL, 10);
-	int rv = 0;
+	int rv;
 
 	dbg("%s: setting event char = %i", __func__, v);
 
@@ -1451,8 +1445,7 @@ static ssize_t store_event_char(struct d
 			     FTDI_SIO_SET_EVENT_CHAR_REQUEST,
 			     FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE,
 			     v, priv->interface,
-			     buf, 0, WDR_TIMEOUT);
-
+			     NULL, 0, WDR_TIMEOUT);
 	if (rv < 0) {
 		dbg("Unable to write event character: %i", rv);
 		return -EIO;
@@ -1551,9 +1544,9 @@ static int ftdi_sio_port_probe(struct us
 
 	kref_init(&priv->kref);
 	spin_lock_init(&priv->tx_lock);
+	mutex_init(&priv->cfg_lock);
 	init_waitqueue_head(&priv->delta_msr_wait);
-	/* This will push the characters through immediately rather
-	   than queue a task to deliver them */
+
 	priv->flags = ASYNC_LOW_LATENCY;
 
 	if (quirk && quirk->port_probe)
@@ -1585,7 +1578,8 @@ static int ftdi_sio_port_probe(struct us
 
 	ftdi_determine_type(port);
 	ftdi_set_max_packet_size(port);
-	read_latency_timer(port);
+	if (read_latency_timer(port) < 0)
+		priv->latency = 16;
 	create_sysfs_attrs(port);
 	return 0;
 }
@@ -1630,8 +1624,6 @@ static int ftdi_NDI_device_setup(struct
 {
 	struct usb_device *udev = serial->dev;
 	int latency = ndi_latency_timer;
-	int rv = 0;
-	char buf[1];
 
 	if (latency == 0)
 		latency = 1;
@@ -1641,10 +1633,11 @@ static int ftdi_NDI_device_setup(struct
 	dbg("%s setting NDI device latency to %d", __func__, latency);
 	dev_info(&udev->dev, "NDI device with a latency value of %d", latency);
 
-	rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+	/* FIXME: errors are not returned */
+	usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 				FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
 				FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
-				latency, 0, buf, 0, WDR_TIMEOUT);
+				latency, 0, NULL, 0, WDR_TIMEOUT);
 	return 0;
 }
 
@@ -1720,7 +1713,7 @@ static int ftdi_submit_read_urb(struct u
 			   urb->transfer_buffer_length,
 			   ftdi_read_bulk_callback, port);
 	result = usb_submit_urb(urb, mem_flags);
-	if (result)
+	if (result && result != -EPERM)
 		dev_err(&port->dev,
 			"%s - failed submitting read urb, error %d\n",
 							__func__, result);
@@ -1732,16 +1725,10 @@ static int ftdi_open(struct tty_struct *
 	struct usb_device *dev = port->serial->dev;
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
 	unsigned long flags;
-
-	int result = 0;
-	char buf[1]; /* Needed for the usb_control_msg I think */
+	int result;
 
 	dbg("%s", __func__);
 
-	spin_lock_irqsave(&priv->tx_lock, flags);
-	priv->tx_bytes = 0;
-	spin_unlock_irqrestore(&priv->tx_lock, flags);
-
 	write_latency_timer(port);
 
 	/* No error checking for this (will get errors later anyway) */
@@ -1749,7 +1736,7 @@ static int ftdi_open(struct tty_struct *
 	usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 			FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE,
 			FTDI_SIO_RESET_SIO,
-			priv->interface, buf, 0, WDR_TIMEOUT);
+			priv->interface, NULL, 0, WDR_TIMEOUT);
 
 	/* Termios defaults are set by usb_serial_init. We don't change
 	   port->tty->termios - this would lose speed settings, etc.
@@ -1777,7 +1764,6 @@ static int ftdi_open(struct tty_struct *
 static void ftdi_dtr_rts(struct usb_serial_port *port, int on)
 {
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
-	char buf[1];
 
 	mutex_lock(&port->serial->disc_mutex);
 	if (!port->serial->disconnected) {
@@ -1786,7 +1772,7 @@ static void ftdi_dtr_rts(struct usb_seri
 			    usb_sndctrlpipe(port->serial->dev, 0),
 			    FTDI_SIO_SET_FLOW_CTRL_REQUEST,
 			    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
-			    0, priv->interface, buf, 0,
+			    0, priv->interface, NULL, 0,
 			    WDR_TIMEOUT) < 0) {
 			    dev_err(&port->dev, "error from flowcontrol urb\n");
 		}
@@ -1847,7 +1833,7 @@ static int ftdi_write(struct tty_struct
 	spin_lock_irqsave(&priv->tx_lock, flags);
 	if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) {
 		spin_unlock_irqrestore(&priv->tx_lock, flags);
-		dbg("%s - write limit hit\n", __func__);
+		dbg("%s - write limit hit", __func__);
 		return 0;
 	}
 	priv->tx_outstanding_urbs++;
@@ -1927,7 +1913,6 @@ static int ftdi_write(struct tty_struct
 	} else {
 		spin_lock_irqsave(&priv->tx_lock, flags);
 		priv->tx_outstanding_bytes += count;
-		priv->tx_bytes += count;
 		spin_unlock_irqrestore(&priv->tx_lock, flags);
 	}
 
@@ -2154,8 +2139,7 @@ static void ftdi_break_ctl(struct tty_st
 {
 	struct usb_serial_port *port = tty->driver_data;
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
-	__u16 urb_value = 0;
-	char buf[1];
+	__u16 urb_value;
 
 	/* break_state = -1 to turn on break, and 0 to turn off break */
 	/* see drivers/char/tty_io.c to see it used */
@@ -2171,7 +2155,7 @@ static void ftdi_break_ctl(struct tty_st
 			FTDI_SIO_SET_DATA_REQUEST,
 			FTDI_SIO_SET_DATA_REQUEST_TYPE,
 			urb_value , priv->interface,
-			buf, 0, WDR_TIMEOUT) < 0) {
+			NULL, 0, WDR_TIMEOUT) < 0) {
 		dev_err(&port->dev, "%s FAILED to enable/disable break state "
 			"(state was %d)\n", __func__, break_state);
 	}
@@ -2195,7 +2179,6 @@ static void ftdi_set_termios(struct tty_
 	struct ktermios *termios = tty->termios;
 	unsigned int cflag = termios->c_cflag;
 	__u16 urb_value; /* will hold the new flags */
-	char buf[1]; /* Perhaps I should dynamically alloc this? */
 
 	/* Added for xon/xoff support */
 	unsigned int iflag = termios->c_iflag;
@@ -2246,12 +2229,10 @@ static void ftdi_set_termios(struct tty_
 	}
 	if (cflag & CSIZE) {
 		switch (cflag & CSIZE) {
-		case CS5: urb_value |= 5; dbg("Setting CS5"); break;
-		case CS6: urb_value |= 6; dbg("Setting CS6"); break;
 		case CS7: urb_value |= 7; dbg("Setting CS7"); break;
 		case CS8: urb_value |= 8; dbg("Setting CS8"); break;
 		default:
-			dev_err(&port->dev, "CSIZE was set but not CS5-CS8\n");
+			dev_err(&port->dev, "CSIZE was set but not CS7-CS8\n");
 		}
 	}
 
@@ -2263,7 +2244,7 @@ static void ftdi_set_termios(struct tty_
 			    FTDI_SIO_SET_DATA_REQUEST,
 			    FTDI_SIO_SET_DATA_REQUEST_TYPE,
 			    urb_value , priv->interface,
-			    buf, 0, WDR_SHORT_TIMEOUT) < 0) {
+			    NULL, 0, WDR_SHORT_TIMEOUT) < 0) {
 		dev_err(&port->dev, "%s FAILED to set "
 			"databits/stopbits/parity\n", __func__);
 	}
@@ -2275,7 +2256,7 @@ static void ftdi_set_termios(struct tty_
 				    FTDI_SIO_SET_FLOW_CTRL_REQUEST,
 				    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
 				    0, priv->interface,
-				    buf, 0, WDR_TIMEOUT) < 0) {
+				    NULL, 0, WDR_TIMEOUT) < 0) {
 			dev_err(&port->dev,
 				"%s error from disable flowcontrol urb\n",
 				__func__);
@@ -2284,9 +2265,11 @@ static void ftdi_set_termios(struct tty_
 		clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
 	} else {
 		/* set the baudrate determined before */
+		mutex_lock(&priv->cfg_lock);
 		if (change_speed(tty, port))
 			dev_err(&port->dev, "%s urb failed to set baudrate\n",
 				__func__);
+		mutex_unlock(&priv->cfg_lock);
 		/* Ensure RTS and DTR are raised when baudrate changed from 0 */
 		if (!old_termios || (old_termios->c_cflag & CBAUD) == B0)
 			set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
@@ -2301,7 +2284,7 @@ static void ftdi_set_termios(struct tty_
 				    FTDI_SIO_SET_FLOW_CTRL_REQUEST,
 				    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
 				    0 , (FTDI_SIO_RTS_CTS_HS | priv->interface),
-				    buf, 0, WDR_TIMEOUT) < 0) {
+				    NULL, 0, WDR_TIMEOUT) < 0) {
 			dev_err(&port->dev,
 				"urb failed to set to rts/cts flow control\n");
 		}
@@ -2333,7 +2316,7 @@ static void ftdi_set_termios(struct tty_
 					    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
 					    urb_value , (FTDI_SIO_XON_XOFF_HS
 							 | priv->interface),
-					    buf, 0, WDR_TIMEOUT) < 0) {
+					    NULL, 0, WDR_TIMEOUT) < 0) {
 				dev_err(&port->dev, "urb failed to set to "
 					"xon/xoff flow control\n");
 			}
@@ -2347,7 +2330,7 @@ static void ftdi_set_termios(struct tty_
 					    FTDI_SIO_SET_FLOW_CTRL_REQUEST,
 					    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
 					    0, priv->interface,
-					    buf, 0, WDR_TIMEOUT) < 0) {
+					    NULL, 0, WDR_TIMEOUT) < 0) {
 				dev_err(&port->dev,
 					"urb failed to clear flow control\n");
 			}
@@ -2361,21 +2344,22 @@ static int ftdi_tiocmget(struct tty_stru
 {
 	struct usb_serial_port *port = tty->driver_data;
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
-	unsigned char buf[2];
+	unsigned char *buf;
+	int len;
 	int ret;
 
 	dbg("%s TIOCMGET", __func__);
+
+	buf = kmalloc(2, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	/*
+	 * The 8U232AM returns a two byte value (the SIO a 1 byte value) in
+	 * the same format as the data returned from the in point.
+	 */
 	switch (priv->chip_type) {
 	case SIO:
-		/* Request the status from the device */
-		ret = usb_control_msg(port->serial->dev,
-			   usb_rcvctrlpipe(port->serial->dev, 0),
-			   FTDI_SIO_GET_MODEM_STATUS_REQUEST,
-			   FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
-			   0, 0,
-			   buf, 1, WDR_TIMEOUT);
-		if (ret < 0)
-			return ret;
+		len = 1;
 		break;
 	case FT8U232AM:
 	case FT232BM:
@@ -2383,27 +2367,30 @@ static int ftdi_tiocmget(struct tty_stru
 	case FT232RL:
 	case FT2232H:
 	case FT4232H:
-		/* the 8U232AM returns a two byte value (the sio is a 1 byte
-		   value) - in the same format as the data returned from the in
-		   point */
-		ret = usb_control_msg(port->serial->dev,
-				   usb_rcvctrlpipe(port->serial->dev, 0),
-				   FTDI_SIO_GET_MODEM_STATUS_REQUEST,
-				   FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
-				   0, priv->interface,
-				   buf, 2, WDR_TIMEOUT);
-		if (ret < 0)
-			return ret;
+		len = 2;
 		break;
 	default:
-		return -EFAULT;
+		ret = -EFAULT;
+		goto out;
 	}
 
-	return  (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) |
+	ret = usb_control_msg(port->serial->dev,
+			usb_rcvctrlpipe(port->serial->dev, 0),
+			FTDI_SIO_GET_MODEM_STATUS_REQUEST,
+			FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
+			0, priv->interface,
+			buf, len, WDR_TIMEOUT);
+	if (ret < 0)
+		goto out;
+
+	ret = (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) |
 		(buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) |
 		(buf[0]  & FTDI_SIO_RI_MASK  ? TIOCM_RI  : 0) |
 		(buf[0]  & FTDI_SIO_RLSD_MASK ? TIOCM_CD  : 0) |
 		priv->last_dtr_rts;
+out:
+	kfree(buf);
+	return ret;
 }
 
 static int ftdi_tiocmset(struct tty_struct *tty, struct file *file,
@@ -2508,8 +2495,7 @@ void ftdi_unthrottle(struct tty_struct *
 	port->throttled = port->throttle_req = 0;
 	spin_unlock_irqrestore(&port->lock, flags);
 
-	/* Resubmit urb if throttled and open. */
-	if (was_throttled && test_bit(ASYNCB_INITIALIZED, &port->port.flags))
+	if (was_throttled)
 		ftdi_submit_read_urb(port, GFP_KERNEL);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/ftdi_sio.h linux-libre-2.6.34-gnu1/drivers/usb/serial/ftdi_sio.h
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/ftdi_sio.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/ftdi_sio.h	2010-05-16 17:17:36.000000000 -0400
@@ -28,13 +28,13 @@
 #define FTDI_SIO_SET_FLOW_CTRL	2 /* Set flow control register */
 #define FTDI_SIO_SET_BAUD_RATE	3 /* Set baud rate */
 #define FTDI_SIO_SET_DATA	4 /* Set the data characteristics of the port */
-#define FTDI_SIO_GET_MODEM_STATUS	5 /* Retrieve current value of modern status register */
+#define FTDI_SIO_GET_MODEM_STATUS	5 /* Retrieve current value of modem status register */
 #define FTDI_SIO_SET_EVENT_CHAR	6 /* Set the event character */
 #define FTDI_SIO_SET_ERROR_CHAR	7 /* Set the error character */
 #define FTDI_SIO_SET_LATENCY_TIMER	9 /* Set the latency timer */
 #define FTDI_SIO_GET_LATENCY_TIMER	10 /* Get the latency timer */
 
-/* Interface indicies for FT2232, FT2232H and FT4232H devices*/
+/* Interface indices for FT2232, FT2232H and FT4232H devices */
 #define INTERFACE_A		1
 #define INTERFACE_B		2
 #define INTERFACE_C		3
@@ -270,7 +270,7 @@ typedef enum {
  *   BmRequestType:  0100 0000b
  *   bRequest:       FTDI_SIO_SET_FLOW_CTRL
  *   wValue:         Xoff/Xon
- *   wIndex:         Protocol/Port - hIndex is protocl / lIndex is port
+ *   wIndex:         Protocol/Port - hIndex is protocol / lIndex is port
  *   wLength:        0
  *   Data:           None
  *
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/ftdi_sio_ids.h linux-libre-2.6.34-gnu1/drivers/usb/serial/ftdi_sio_ids.h
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/ftdi_sio_ids.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/ftdi_sio_ids.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,7 @@
 #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */
 #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */
 #define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */
-#define FTDI_SIO_PID	0x8372	/* Product Id SIO application of 8U100AX  */
+#define FTDI_SIO_PID	0x8372	/* Product Id SIO application of 8U100AX */
 #define FTDI_232RL_PID  0xFBFA  /* Product ID for FT232RL */
 
 
@@ -49,7 +49,7 @@
 #define LMI_LM3S_DEVEL_BOARD_PID	0xbcd8
 #define LMI_LM3S_EVAL_BOARD_PID		0xbcd9
 
-#define FTDI_TURTELIZER_PID	0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */
+#define FTDI_TURTELIZER_PID	0xBDC8 /* JTAG/RS-232 adapter by egnite GmbH */
 
 /* OpenDCC (www.opendcc.de) product id */
 #define FTDI_OPENDCC_PID	0xBFD8
@@ -185,7 +185,7 @@
 #define FTDI_ELV_TFD128_PID	0xE0EC	/* ELV Temperatur-Feuchte-Datenlogger TFD 128 */
 #define FTDI_ELV_FM3RX_PID	0xE0ED	/* ELV Messwertuebertragung FM3 RX */
 #define FTDI_ELV_WS777_PID	0xE0EE	/* Conrad WS 777 */
-#define FTDI_ELV_EM1010PC_PID	0xE0EF	/* Engery monitor EM 1010 PC */
+#define FTDI_ELV_EM1010PC_PID	0xE0EF	/* Energy monitor EM 1010 PC */
 #define FTDI_ELV_CSI8_PID	0xE0F0	/* Computer-Schalt-Interface (CSI 8) */
 #define FTDI_ELV_EM1000DL_PID	0xE0F1	/* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */
 #define FTDI_ELV_PCK100_PID	0xE0F2	/* PC-Kabeltester (PCK 100) */
@@ -212,8 +212,8 @@
  * drivers, or possibly the Comedi drivers in some cases. */
 #define FTDI_ELV_CLI7000_PID	0xFB59	/* Computer-Light-Interface (CLI 7000) */
 #define FTDI_ELV_PPS7330_PID	0xFB5C	/* Processor-Power-Supply (PPS 7330) */
-#define FTDI_ELV_TFM100_PID	0xFB5D	/* Temperartur-Feuchte Messgeraet (TFM 100) */
-#define FTDI_ELV_UDF77_PID	0xFB5E	/* USB DCF Funkurh (UDF 77) */
+#define FTDI_ELV_TFM100_PID	0xFB5D	/* Temperatur-Feuchte-Messgeraet (TFM 100) */
+#define FTDI_ELV_UDF77_PID	0xFB5E	/* USB DCF Funkuhr (UDF 77) */
 #define FTDI_ELV_UIO88_PID	0xFB5F	/* USB-I/O Interface (UIO 88) */
 
 /*
@@ -320,7 +320,7 @@
 
 /*
  * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485,
- * USB-TTY activ, USB-TTY passiv.  Some PIDs are used by several devices
+ * USB-TTY aktiv, USB-TTY passiv.  Some PIDs are used by several devices
  * and I'm not entirely sure which are used by which.
  */
 #define FTDI_4N_GALAXY_DE_1_PID	0xF3C0
@@ -330,10 +330,10 @@
  * Linx Technologies product ids
  */
 #define LINX_SDMUSBQSS_PID	0xF448	/* Linx SDM-USB-QS-S */
-#define LINX_MASTERDEVEL2_PID   0xF449   /* Linx Master Development 2.0 */
-#define LINX_FUTURE_0_PID   0xF44A   /* Linx future device */
-#define LINX_FUTURE_1_PID   0xF44B   /* Linx future device */
-#define LINX_FUTURE_2_PID   0xF44C   /* Linx future device */
+#define LINX_MASTERDEVEL2_PID   0xF449	/* Linx Master Development 2.0 */
+#define LINX_FUTURE_0_PID   0xF44A	/* Linx future device */
+#define LINX_FUTURE_1_PID   0xF44B	/* Linx future device */
+#define LINX_FUTURE_2_PID   0xF44C	/* Linx future device */
 
 /*
  * Oceanic product ids
@@ -494,6 +494,20 @@
 #define RATOC_PRODUCT_ID_USB60F	0xb020
 
 /*
+ * Contec products (http://www.contec.com)
+ * Submitted by Daniel Sangorrin
+ */
+#define CONTEC_VID		0x06CE	/* Vendor ID */
+#define CONTEC_COM1USBH_PID	0x8311	/* COM-1(USB)H */
+
+/*
+ * Contec products (http://www.contec.com)
+ * Submitted by Daniel Sangorrin
+ */
+#define CONTEC_VID		0x06CE	/* Vendor ID */
+#define CONTEC_COM1USBH_PID	0x8311	/* COM-1(USB)H */
+
+/*
  * Definitions for B&B Electronics products.
  */
 #define BANDB_VID		0x0856	/* B&B Electronics Vendor ID */
@@ -642,7 +656,7 @@
 #define FALCOM_TWIST_PID	0x0001	/* Falcom Twist USB GPRS modem */
 #define FALCOM_SAMBA_PID	0x0005	/* Falcom Samba USB GPRS modem */
 
-/* Larsen and Brusgaard AltiTrack/USBtrack  */
+/* Larsen and Brusgaard AltiTrack/USBtrack */
 #define LARSENBRUSGAARD_VID		0x0FD8
 #define LB_ALTITRACK_PID		0x0001
 
@@ -971,7 +985,7 @@
 #define ALTI2_N3_PID	0x6001	/* Neptune 3 */
 
 /*
- * Dresden Elektronic Sensor Terminal Board
+ * Dresden Elektronik Sensor Terminal Board
  */
 #define DE_VID			0x1cf1 /* Vendor ID */
 #define STB_PID			0x0001 /* Sensor Terminal Board */
@@ -1002,3 +1016,11 @@
 #define EVO_8U232AM_PID	0x02FF	/* Evolution robotics RCM2 (FT232AM)*/
 #define EVO_HYBRID_PID		0x0302	/* Evolution robotics RCM4 PID (FT232BM)*/
 #define EVO_RCM4_PID		0x0303	/* Evolution robotics RCM4 PID */
+
+/*
+ * MJS Gadgets HD Radio / XM Radio / Sirius Radio interfaces (using VID 0x0403)
+ */
+#define MJSG_GENERIC_PID	0x9378
+#define MJSG_SR_RADIO_PID	0x9379
+#define MJSG_XM_RADIO_PID	0x937A
+#define MJSG_HD_RADIO_PID	0x937C
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/funsoft.c linux-libre-2.6.34-gnu1/drivers/usb/serial/funsoft.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/funsoft.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/funsoft.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,7 @@
 
 static int debug;
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x1404, 0xcddc) },
 	{ },
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/garmin_gps.c linux-libre-2.6.34-gnu1/drivers/usb/serial/garmin_gps.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/garmin_gps.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/garmin_gps.c	2010-05-16 17:17:36.000000000 -0400
@@ -210,7 +210,7 @@ static unsigned char const PRIVATE_REQ[]
 
 
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	/* the same device id seems to be used by all
 	   usb enabled GPS devices */
 	{ USB_DEVICE(GARMIN_VENDOR_ID, 3) },
@@ -271,7 +271,6 @@ static void send_to_tty(struct usb_seria
 		usb_serial_debug_data(debug, &port->dev,
 					__func__, actual_length, data);
 
-		tty_buffer_request_room(tty, actual_length);
 		tty_insert_flip_string(tty, data, actual_length);
 		tty_flip_buffer_push(tty);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/generic.c linux-libre-2.6.34-gnu1/drivers/usb/serial/generic.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/usb/serial.h>
 #include <linux/uaccess.h>
 #include <linux/kfifo.h>
+#include <linux/serial.h>
 
 static int debug;
 
@@ -41,7 +42,7 @@ static struct usb_device_id generic_devi
 
 /* we want to look at all devices, as the vendor/product id can change
  * depending on the command line argument */
-static struct usb_device_id generic_serial_ids[] = {
+static const struct usb_device_id generic_serial_ids[] = {
 	{.driver_info = 42},
 	{}
 };
@@ -129,7 +130,7 @@ int usb_serial_generic_open(struct tty_s
 	spin_unlock_irqrestore(&port->lock, flags);
 
 	/* if we have a bulk endpoint, start reading from it */
-	if (serial->num_bulk_in) {
+	if (port->bulk_in_size) {
 		/* Start reading from the device */
 		usb_fill_bulk_urb(port->read_urb, serial->dev,
 				   usb_rcvbulkpipe(serial->dev,
@@ -158,10 +159,10 @@ static void generic_cleanup(struct usb_s
 	dbg("%s - port %d", __func__, port->number);
 
 	if (serial->dev) {
-		/* shutdown any bulk reads that might be going on */
-		if (serial->num_bulk_out)
+		/* shutdown any bulk transfers that might be going on */
+		if (port->bulk_out_size)
 			usb_kill_urb(port->write_urb);
-		if (serial->num_bulk_in)
+		if (port->bulk_in_size)
 			usb_kill_urb(port->read_urb);
 	}
 }
@@ -194,7 +195,7 @@ static int usb_serial_multi_urb_write(st
 		if (port->urbs_in_flight >
 		    port->serial->type->max_in_flight_urbs) {
 			spin_unlock_irqrestore(&port->lock, flags);
-			dbg("%s - write limit hit\n", __func__);
+			dbg("%s - write limit hit", __func__);
 			return bwrite;
 		}
 		port->tx_bytes_flight += towrite;
@@ -332,15 +333,15 @@ int usb_serial_generic_write(struct tty_
 
 	dbg("%s - port %d", __func__, port->number);
 
+	/* only do something if we have a bulk out endpoint */
+	if (!port->bulk_out_size)
+		return -ENODEV;
+
 	if (count == 0) {
 		dbg("%s - write request of 0 bytes", __func__);
 		return 0;
 	}
 
-	/* only do something if we have a bulk out endpoint */
-	if (!serial->num_bulk_out)
-		return 0;
-
 	if (serial->type->max_in_flight_urbs)
 		return usb_serial_multi_urb_write(tty, port,
 						  buf, count);
@@ -363,14 +364,19 @@ int usb_serial_generic_write_room(struct
 	int room = 0;
 
 	dbg("%s - port %d", __func__, port->number);
+
+	if (!port->bulk_out_size)
+		return 0;
+
 	spin_lock_irqsave(&port->lock, flags);
 	if (serial->type->max_in_flight_urbs) {
 		if (port->urbs_in_flight < serial->type->max_in_flight_urbs)
 			room = port->bulk_out_size *
 				(serial->type->max_in_flight_urbs -
 				 port->urbs_in_flight);
-	} else if (serial->num_bulk_out)
+	} else {
 		room = kfifo_avail(&port->write_fifo);
+	}
 	spin_unlock_irqrestore(&port->lock, flags);
 
 	dbg("%s - returns %d", __func__, room);
@@ -381,15 +387,18 @@ int usb_serial_generic_chars_in_buffer(s
 {
 	struct usb_serial_port *port = tty->driver_data;
 	struct usb_serial *serial = port->serial;
-	int chars = 0;
 	unsigned long flags;
+	int chars;
 
 	dbg("%s - port %d", __func__, port->number);
 
+	if (!port->bulk_out_size)
+		return 0;
+
 	spin_lock_irqsave(&port->lock, flags);
 	if (serial->type->max_in_flight_urbs)
 		chars = port->tx_bytes_flight;
-	else if (serial->num_bulk_out)
+	else
 		chars = kfifo_len(&port->write_fifo);
 	spin_unlock_irqrestore(&port->lock, flags);
 
@@ -414,11 +423,13 @@ void usb_serial_generic_resubmit_read_ur
 			   ((serial->type->read_bulk_callback) ?
 			     serial->type->read_bulk_callback :
 			     usb_serial_generic_read_bulk_callback), port);
+
 	result = usb_submit_urb(urb, mem_flags);
-	if (result)
+	if (result && result != -EPERM) {
 		dev_err(&port->dev,
 			"%s - failed resubmitting read urb, error %d\n",
 							__func__, result);
+	}
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb);
 
@@ -497,23 +508,18 @@ void usb_serial_generic_write_bulk_callb
 		if (port->urbs_in_flight < 0)
 			port->urbs_in_flight = 0;
 		spin_unlock_irqrestore(&port->lock, flags);
-
-		if (status) {
-			dbg("%s - nonzero multi-urb write bulk status "
-				"received: %d", __func__, status);
-			return;
-		}
 	} else {
 		port->write_urb_busy = 0;
 
-		if (status) {
-			dbg("%s - nonzero multi-urb write bulk status "
-				"received: %d", __func__, status);
+		if (status)
 			kfifo_reset_out(&port->write_fifo);
-		} else
+		else
 			usb_serial_generic_write_start(port);
 	}
 
+	if (status)
+		dbg("%s - non-zero urb status: %d", __func__, status);
+
 	usb_serial_port_softint(port);
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
@@ -585,7 +591,7 @@ int usb_serial_generic_resume(struct usb
 
 	for (i = 0; i < serial->num_ports; i++) {
 		port = serial->port[i];
-		if (!port->port.count)
+		if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags))
 			continue;
 
 		if (port->read_urb) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/hp4x.c linux-libre-2.6.34-gnu1/drivers/usb/serial/hp4x.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/hp4x.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/hp4x.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,7 +29,7 @@
 #define HP_VENDOR_ID 0x03f0
 #define HP49GP_PRODUCT_ID 0x0121
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(HP_VENDOR_ID, HP49GP_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/io_edgeport.c linux-libre-2.6.34-gnu1/drivers/usb/serial/io_edgeport.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/io_edgeport.c	2013-05-03 12:13:15.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/io_edgeport.c	2013-05-03 09:52:48.000000000 -0400
@@ -364,42 +364,6 @@ static void update_edgeport_E2PROM(struc
 	release_firmware(fw);
 }
 
-
-/************************************************************************
- *									*
- *  Get string descriptor from device					*
- *									*
- ************************************************************************/
-static int get_string(struct usb_device *dev, int Id, char *string, int buflen)
-{
-	struct usb_string_descriptor StringDesc;
-	struct usb_string_descriptor *pStringDesc;
-
-	dbg("%s - USB String ID = %d", __func__, Id);
-
-	if (!usb_get_descriptor(dev, USB_DT_STRING, Id,
-					&StringDesc, sizeof(StringDesc)))
-		return 0;
-
-	pStringDesc = kmalloc(StringDesc.bLength, GFP_KERNEL);
-	if (!pStringDesc)
-		return 0;
-
-	if (!usb_get_descriptor(dev, USB_DT_STRING, Id,
-					pStringDesc, StringDesc.bLength)) {
-		kfree(pStringDesc);
-		return 0;
-	}
-
-	unicode_to_ascii(string, buflen,
-				pStringDesc->wData, pStringDesc->bLength/2);
-
-	kfree(pStringDesc);
-	dbg("%s - USB String %s", __func__, string);
-	return strlen(string);
-}
-
-
 #if 0
 /************************************************************************
  *
@@ -2007,7 +1971,7 @@ static void process_rcvd_status(struct e
 			return;
 
 		case IOSP_EXT_STATUS_RX_CHECK_RSP:
-			dbg("%s ========== Port %u CHECK_RSP Sequence = %02x =============\n", __func__, edge_serial->rxPort, byte3);
+			dbg("%s ========== Port %u CHECK_RSP Sequence = %02x =============", __func__, edge_serial->rxPort, byte3);
 			/* Port->RxCheckRsp = true; */
 			return;
 		}
@@ -2075,7 +2039,7 @@ static void process_rcvd_status(struct e
 		break;
 
 	default:
-		dbg("%s - Unrecognized IOSP status code %u\n", __func__, code);
+		dbg("%s - Unrecognized IOSP status code %u", __func__, code);
 		break;
 	}
 	return;
@@ -2091,18 +2055,13 @@ static void edge_tty_recv(struct device
 {
 	int cnt;
 
-	do {
-		cnt = tty_buffer_request_room(tty, length);
-		if (cnt < length) {
-			dev_err(dev, "%s - dropping data, %d bytes lost\n",
-					__func__, length - cnt);
-			if (cnt == 0)
-				break;
-		}
-		tty_insert_flip_string(tty, data, cnt);
-		data += cnt;
-		length -= cnt;
-	} while (length > 0);
+	cnt = tty_insert_flip_string(tty, data, length);
+	if (cnt < length) {
+		dev_err(dev, "%s - dropping data, %d bytes lost\n",
+				__func__, length - cnt);
+	}
+	data += cnt;
+	length -= cnt;
 
 	tty_flip_buffer_push(tty);
 }
@@ -2530,7 +2489,7 @@ static int calc_baud_rate_divisor(int ba
 
 		*divisor = custom;
 
-		dbg("%s - Baud %d = %d\n", __func__, baudrate, custom);
+		dbg("%s - Baud %d = %d", __func__, baudrate, custom);
 		return 0;
 	}
 
@@ -2915,7 +2874,7 @@ static void load_application_firmware(st
 			break;
 
 		case EDGE_DOWNLOAD_FILE_NONE:
-			dbg     ("No download file specified, skipping download\n");
+			dbg("No download file specified, skipping download");
 			return;
 
 		default:
@@ -2997,10 +2956,12 @@ static int edge_startup(struct usb_seria
 	usb_set_serial_data(serial, edge_serial);
 
 	/* get the name for the device from the device */
-	i = get_string(dev, dev->descriptor.iManufacturer,
+	i = usb_string(dev, dev->descriptor.iManufacturer,
 	    &edge_serial->name[0], MAX_NAME_LEN+1);
+	if (i < 0)
+		i = 0;
 	edge_serial->name[i++] = ' ';
-	get_string(dev, dev->descriptor.iProduct,
+	usb_string(dev, dev->descriptor.iProduct,
 	    &edge_serial->name[i], MAX_NAME_LEN+2 - i);
 
 	dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/io_tables.h linux-libre-2.6.34-gnu1/drivers/usb/serial/io_tables.h
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/io_tables.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/io_tables.h	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,7 @@
 #ifndef IO_TABLES_H
 #define IO_TABLES_H
 
-static struct usb_device_id edgeport_2port_id_table [] = {
+static const struct usb_device_id edgeport_2port_id_table[] = {
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_2) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_2I) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_421) },
@@ -23,7 +23,7 @@ static struct usb_device_id edgeport_2po
 	{ }
 };
 
-static struct usb_device_id edgeport_4port_id_table [] = {
+static const struct usb_device_id edgeport_4port_id_table[] = {
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_RAPIDPORT_4) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4T) },
@@ -37,7 +37,7 @@ static struct usb_device_id edgeport_4po
 	{ }
 };
 
-static struct usb_device_id edgeport_8port_id_table [] = {
+static const struct usb_device_id edgeport_8port_id_table[] = {
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8I) },
@@ -47,7 +47,7 @@ static struct usb_device_id edgeport_8po
 	{ }
 };
 
-static struct usb_device_id Epic_port_id_table [] = {
+static const struct usb_device_id Epic_port_id_table[] = {
 	{ USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0202) },
 	{ USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0203) },
 	{ USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0310) },
@@ -60,7 +60,7 @@ static struct usb_device_id Epic_port_id
 };
 
 /* Devices that this driver supports */
-static struct usb_device_id id_table_combined [] = {
+static const struct usb_device_id id_table_combined[] = {
 	{ USB_DEVICE(USB_VENDOR_ID_ION,	ION_DEVICE_ID_EDGEPORT_4) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION,	ION_DEVICE_ID_RAPIDPORT_4) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION,	ION_DEVICE_ID_EDGEPORT_4T) },
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/io_ti.c linux-libre-2.6.34-gnu1/drivers/usb/serial/io_ti.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/io_ti.c	2013-05-03 12:13:20.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/io_ti.c	2013-05-03 09:52:53.000000000 -0400
@@ -134,7 +134,7 @@ struct edgeport_serial {
 
 
 /* Devices that this driver supports */
-static struct usb_device_id edgeport_1port_id_table [] = {
+static const struct usb_device_id edgeport_1port_id_table[] = {
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I) },
@@ -154,7 +154,7 @@ static struct usb_device_id edgeport_1po
 	{ }
 };
 
-static struct usb_device_id edgeport_2port_id_table [] = {
+static const struct usb_device_id edgeport_2port_id_table[] = {
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2C) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2I) },
@@ -177,7 +177,7 @@ static struct usb_device_id edgeport_2po
 };
 
 /* Devices that this driver supports */
-static struct usb_device_id id_table_combined [] = {
+static const struct usb_device_id id_table_combined[] = {
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1) },
 	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I) },
@@ -413,11 +413,18 @@ static int write_boot_mem(struct edgepor
 {
 	int status = 0;
 	int i;
-	__u8 temp;
+	u8 *temp;
 
 	/* Must do a read before write */
 	if (!serial->TiReadI2C) {
-		status = read_boot_mem(serial, 0, 1, &temp);
+		temp = kmalloc(1, GFP_KERNEL);
+		if (!temp) {
+			dev_err(&serial->serial->dev->dev,
+					"%s - out of memory\n", __func__);
+			return -ENOMEM;
+		}
+		status = read_boot_mem(serial, 0, 1, temp);
+		kfree(temp);
 		if (status)
 			return status;
 	}
@@ -935,37 +942,47 @@ static int build_i2c_fw_hdr(__u8 *header
 static int i2c_type_bootmode(struct edgeport_serial *serial)
 {
 	int status;
-	__u8 data;
+	u8 *data;
+
+	data = kmalloc(1, GFP_KERNEL);
+	if (!data) {
+		dev_err(&serial->serial->dev->dev,
+				"%s - out of memory\n", __func__);
+		return -ENOMEM;
+	}
 
 	/* Try to read type 2 */
 	status = ti_vread_sync(serial->serial->dev, UMPC_MEMORY_READ,
-				DTK_ADDR_SPACE_I2C_TYPE_II, 0, &data, 0x01);
+				DTK_ADDR_SPACE_I2C_TYPE_II, 0, data, 0x01);
 	if (status)
 		dbg("%s - read 2 status error = %d", __func__, status);
 	else
-		dbg("%s - read 2 data = 0x%x", __func__, data);
-	if ((!status) && (data == UMP5152 || data == UMP3410)) {
+		dbg("%s - read 2 data = 0x%x", __func__, *data);
+	if ((!status) && (*data == UMP5152 || *data == UMP3410)) {
 		dbg("%s - ROM_TYPE_II", __func__);
 		serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II;
-		return 0;
+		goto out;
 	}
 
 	/* Try to read type 3 */
 	status = ti_vread_sync(serial->serial->dev, UMPC_MEMORY_READ,
-				DTK_ADDR_SPACE_I2C_TYPE_III, 0,	&data, 0x01);
+				DTK_ADDR_SPACE_I2C_TYPE_III, 0,	data, 0x01);
 	if (status)
 		dbg("%s - read 3 status error = %d", __func__, status);
 	else
-		dbg("%s - read 2 data = 0x%x", __func__, data);
-	if ((!status) && (data == UMP5152 || data == UMP3410)) {
+		dbg("%s - read 2 data = 0x%x", __func__, *data);
+	if ((!status) && (*data == UMP5152 || *data == UMP3410)) {
 		dbg("%s - ROM_TYPE_III", __func__);
 		serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_III;
-		return 0;
+		goto out;
 	}
 
 	dbg("%s - Unknown", __func__);
 	serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II;
-	return -ENODEV;
+	status = -ENODEV;
+out:
+	kfree(data);
+	return status;
 }
 
 static int bulk_xfer(struct usb_serial *serial, void *buffer,
@@ -1113,7 +1130,7 @@ static int download_fw(struct edgeport_s
 				I2C_DESC_TYPE_FIRMWARE_BASIC, rom_desc);
 		if (start_address != 0) {
 			struct ti_i2c_firmware_rec *firmware_version;
-			__u8 record;
+			u8 *record;
 
 			dbg("%s - Found Type FIRMWARE (Type 2) record",
 								__func__);
@@ -1165,6 +1182,15 @@ static int download_fw(struct edgeport_s
 				    OperationalMajorVersion,
 				    OperationalMinorVersion);
 
+				record = kmalloc(1, GFP_KERNEL);
+				if (!record) {
+					dev_err(dev, "%s - out of memory.\n",
+							__func__);
+					kfree(firmware_version);
+					kfree(rom_desc);
+					kfree(ti_manuf_desc);
+					return -ENOMEM;
+				}
 				/* In order to update the I2C firmware we must
 				 * change the type 2 record to type 0xF2. This
 				 * will force the UMP to come up in Boot Mode.
@@ -1177,13 +1203,14 @@ static int download_fw(struct edgeport_s
 				 * firmware will update the record type from
 				 * 0xf2 to 0x02.
 				 */
-				record = I2C_DESC_TYPE_FIRMWARE_BLANK;
+				*record = I2C_DESC_TYPE_FIRMWARE_BLANK;
 
 				/* Change the I2C Firmware record type to
 				   0xf2 to trigger an update */
 				status = write_rom(serial, start_address,
-						sizeof(record),	&record);
+						sizeof(*record), record);
 				if (status) {
+					kfree(record);
 					kfree(firmware_version);
 					kfree(rom_desc);
 					kfree(ti_manuf_desc);
@@ -1196,19 +1223,21 @@ static int download_fw(struct edgeport_s
 				 */
 				status = read_rom(serial,
 							start_address,
-							sizeof(record),
-							&record);
+							sizeof(*record),
+							record);
 				if (status) {
+					kfree(record);
 					kfree(firmware_version);
 					kfree(rom_desc);
 					kfree(ti_manuf_desc);
 					return status;
 				}
 
-				if (record != I2C_DESC_TYPE_FIRMWARE_BLANK) {
+				if (*record != I2C_DESC_TYPE_FIRMWARE_BLANK) {
 					dev_err(dev,
 						"%s - error resetting device\n",
 						__func__);
+					kfree(record);
 					kfree(firmware_version);
 					kfree(rom_desc);
 					kfree(ti_manuf_desc);
@@ -1226,6 +1255,7 @@ static int download_fw(struct edgeport_s
 						__func__, status);
 
 				/* return an error on purpose. */
+				kfree(record);
 				kfree(firmware_version);
 				kfree(rom_desc);
 				kfree(ti_manuf_desc);
@@ -1686,7 +1716,7 @@ static void edge_interrupt_callback(stru
 	case TIUMP_INTERRUPT_CODE_MSR:	/* MSR */
 		/* Copy MSR from UMP */
 		msr = data[1];
-		dbg("%s - ===== Port %u MSR Status = %02x ======\n",
+		dbg("%s - ===== Port %u MSR Status = %02x ======",
 		     __func__, port_number, msr);
 		handle_new_msr(edge_port, msr);
 		break;
@@ -1790,7 +1820,6 @@ static void edge_tty_recv(struct device
 {
 	int queued;
 
-	tty_buffer_request_room(tty, length);
 	queued = tty_insert_flip_string(tty, data, length);
 	if (queued < length)
 		dev_err(dev, "%s - dropping data, %d bytes lost\n",
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/ipaq.c linux-libre-2.6.34-gnu1/drivers/usb/serial/ipaq.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/ipaq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/ipaq.c	2010-05-16 17:17:36.000000000 -0400
@@ -747,7 +747,6 @@ static void ipaq_read_bulk_callback(stru
 
 	tty = tty_port_tty_get(&port->port);
 	if (tty && urb->actual_length) {
-		tty_buffer_request_room(tty, urb->actual_length);
 		tty_insert_flip_string(tty, data, urb->actual_length);
 		tty_flip_buffer_push(tty);
 		bytes_in += urb->actual_length;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/ipw.c linux-libre-2.6.34-gnu1/drivers/usb/serial/ipw.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/ipw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/ipw.c	2010-05-16 17:17:36.000000000 -0400
@@ -134,7 +134,7 @@ enum {
 
 #define IPW_WANTS_TO_SEND	0x30
 
-static struct usb_device_id usb_ipw_ids[] = {
+static const struct usb_device_id usb_ipw_ids[] = {
 	{ USB_DEVICE(IPW_VID, IPW_PID) },
 	{ },
 };
@@ -172,7 +172,6 @@ static void ipw_read_bulk_callback(struc
 
 	tty = tty_port_tty_get(&port->port);
 	if (tty && urb->actual_length) {
-		tty_buffer_request_room(tty, urb->actual_length);
 		tty_insert_flip_string(tty, data, urb->actual_length);
 		tty_flip_buffer_push(tty);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/ir-usb.c linux-libre-2.6.34-gnu1/drivers/usb/serial/ir-usb.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/ir-usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/ir-usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -100,7 +100,7 @@ static u8 ir_baud;
 static u8 ir_xbof;
 static u8 ir_add_bof;
 
-static struct usb_device_id ir_id_table[] = {
+static const struct usb_device_id ir_id_table[] = {
 	{ USB_DEVICE(0x050f, 0x0180) },		/* KC Technology, KC-180 */
 	{ USB_DEVICE(0x08e9, 0x0100) },		/* XTNDAccess */
 	{ USB_DEVICE(0x09c4, 0x0011) },		/* ACTiSys ACT-IR2000U */
@@ -445,11 +445,6 @@ static void ir_read_bulk_callback(struct
 
 	dbg("%s - port %d", __func__, port->number);
 
-	if (!port->port.count) {
-		dbg("%s - port closed.", __func__);
-		return;
-	}
-
 	switch (status) {
 	case 0: /* Successful */
 		/*
@@ -462,10 +457,8 @@ static void ir_read_bulk_callback(struct
 		usb_serial_debug_data(debug, &port->dev, __func__,
 						urb->actual_length, data);
 		tty = tty_port_tty_get(&port->port);
-		if (tty_buffer_request_room(tty, urb->actual_length - 1)) {
-			tty_insert_flip_string(tty, data+1, urb->actual_length - 1);
-			tty_flip_buffer_push(tty);
-		}
+		tty_insert_flip_string(tty, data+1, urb->actual_length - 1);
+		tty_flip_buffer_push(tty);
 		tty_kref_put(tty);
 
 		/*
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/iuu_phoenix.c linux-libre-2.6.34-gnu1/drivers/usb/serial/iuu_phoenix.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/iuu_phoenix.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/iuu_phoenix.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,7 +43,7 @@ static int debug;
 #define DRIVER_VERSION "v0.11"
 #define DRIVER_DESC "Infinity USB Unlimited Phoenix driver"
 
-static struct usb_device_id id_table[] = {
+static const struct usb_device_id id_table[] = {
 	{USB_DEVICE(IUU_USB_VENDOR_ID, IUU_USB_PRODUCT_ID)},
 	{}			/* Terminating entry */
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/Kconfig linux-libre-2.6.34-gnu1/drivers/usb/serial/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -472,6 +472,17 @@ config USB_SERIAL_OTI6858
 	  To compile this driver as a module, choose M here: the
 	  module will be called oti6858.
 
+config USB_SERIAL_QCAUX
+	tristate "USB Qualcomm Auxiliary Serial Port Driver"
+	help
+	  Say Y here if you want to use the auxiliary serial ports provided
+	  by many modems based on Qualcomm chipsets.  These ports often use
+	  a proprietary protocol called DM and cannot be used for AT- or
+	  PPP-based communication.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called qcaux.  If unsure, choose N.
+
 config USB_SERIAL_QUALCOMM
 	tristate "USB Qualcomm Serial modem"
 	help
@@ -600,6 +611,14 @@ config USB_SERIAL_OPTICON
 	  To compile this driver as a module, choose M here: the
 	  module will be called opticon.
 
+config USB_SERIAL_VIVOPAY_SERIAL
+        tristate "USB ViVOpay serial interface driver"
+        help
+          Say Y here if you want to use a ViVOtech ViVOpay USB device.
+
+          To compile this driver as a module, choose M here: the
+          module will be called vivopay-serial.
+
 config USB_SERIAL_DEBUG
 	tristate "USB Debugging Device"
 	help
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/keyspan.c linux-libre-2.6.34-gnu1/drivers/usb/serial/keyspan.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/keyspan.c	2013-05-03 12:13:05.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/keyspan.c	2013-05-03 09:52:37.000000000 -0400
@@ -464,13 +464,9 @@ static void	usa26_indat_callback(struct
 
 	/* Resubmit urb so we continue receiving */
 	urb->dev = port->serial->dev;
-	if (port->port.count) {
-		err = usb_submit_urb(urb, GFP_ATOMIC);
-		if (err != 0)
-			dbg("%s - resubmit read urb failed. (%d)",
-					__func__, err);
-	}
-	return;
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err != 0)
+		dbg("%s - resubmit read urb failed. (%d)", __func__, err);
 }
 
 /* Outdat handling is common for all devices */
@@ -483,8 +479,7 @@ static void	usa2x_outdat_callback(struct
 	p_priv = usb_get_serial_port_data(port);
 	dbg("%s - urb %d", __func__, urb == p_priv->out_urbs[1]);
 
-	if (port->port.count)
-		usb_serial_port_softint(port);
+	usb_serial_port_softint(port);
 }
 
 static void	usa26_inack_callback(struct urb *urb)
@@ -615,12 +610,10 @@ static void usa28_indat_callback(struct
 
 		/* Resubmit urb so we continue receiving */
 		urb->dev = port->serial->dev;
-		if (port->port.count) {
-			err = usb_submit_urb(urb, GFP_ATOMIC);
-			if (err != 0)
-				dbg("%s - resubmit read urb failed. (%d)",
-								__func__, err);
-		}
+		err = usb_submit_urb(urb, GFP_ATOMIC);
+		if (err != 0)
+			dbg("%s - resubmit read urb failed. (%d)",
+							__func__, err);
 		p_priv->in_flip ^= 1;
 
 		urb = p_priv->in_urbs[p_priv->in_flip];
@@ -856,12 +849,9 @@ static void	usa49_indat_callback(struct
 
 	/* Resubmit urb so we continue receiving */
 	urb->dev = port->serial->dev;
-	if (port->port.count) {
-		err = usb_submit_urb(urb, GFP_ATOMIC);
-		if (err != 0)
-			dbg("%s - resubmit read urb failed. (%d)",
-							__func__, err);
-	}
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err != 0)
+		dbg("%s - resubmit read urb failed. (%d)", __func__, err);
 }
 
 static void usa49wg_indat_callback(struct urb *urb)
@@ -904,11 +894,7 @@ static void usa49wg_indat_callback(struc
 				/* no error on any byte */
 				i++;
 				for (x = 1; x < len ; ++x)
-					if (port->port.count)
-						tty_insert_flip_char(tty,
-								data[i++], 0);
-					else
-						i++;
+					tty_insert_flip_char(tty, data[i++], 0);
 			} else {
 				/*
 				 * some bytes had errors, every byte has status
@@ -922,14 +908,12 @@ static void usa49wg_indat_callback(struc
 					if (stat & RXERROR_PARITY)
 						flag |= TTY_PARITY;
 					/* XXX should handle break (0x10) */
-					if (port->port.count)
-						tty_insert_flip_char(tty,
+					tty_insert_flip_char(tty,
 							data[i+1], flag);
 					i += 2;
 				}
 			}
-			if (port->port.count)
-				tty_flip_buffer_push(tty);
+			tty_flip_buffer_push(tty);
 			tty_kref_put(tty);
 		}
 	}
@@ -1013,13 +997,9 @@ static void usa90_indat_callback(struct
 
 	/* Resubmit urb so we continue receiving */
 	urb->dev = port->serial->dev;
-	if (port->port.count) {
-		err = usb_submit_urb(urb, GFP_ATOMIC);
-		if (err != 0)
-			dbg("%s - resubmit read urb failed. (%d)",
-							__func__, err);
-	}
-	return;
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err != 0)
+		dbg("%s - resubmit read urb failed. (%d)", __func__, err);
 }
 
 
@@ -2418,8 +2398,7 @@ static int keyspan_usa90_send_setup(stru
 		msg.portEnabled = 0;
 	/* Sending intermediate configs */
 	else {
-		if (port->port.count)
-			msg.portEnabled = 1;
+		msg.portEnabled = 1;
 		msg.txBreak = (p_priv->break_on);
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/keyspan.h linux-libre-2.6.34-gnu1/drivers/usb/serial/keyspan.h
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/keyspan.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/keyspan.h	2010-05-16 17:17:36.000000000 -0400
@@ -456,7 +456,7 @@ static const struct keyspan_device_detai
 	NULL,
 };
 
-static struct usb_device_id keyspan_ids_combined[] = {
+static const struct usb_device_id keyspan_ids_combined[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_pre_product_id) },
@@ -497,7 +497,7 @@ static struct usb_driver keyspan_driver
 };
 
 /* usb_device_id table for the pre-firmware download keyspan devices */
-static struct usb_device_id keyspan_pre_ids[] = {
+static const struct usb_device_id keyspan_pre_ids[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_pre_product_id) },
@@ -513,7 +513,7 @@ static struct usb_device_id keyspan_pre_
 	{ } /* Terminating entry */
 };
 
-static struct usb_device_id keyspan_1port_ids[] = {
+static const struct usb_device_id keyspan_1port_ids[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_product_id) },
@@ -524,7 +524,7 @@ static struct usb_device_id keyspan_1por
 	{ } /* Terminating entry */
 };
 
-static struct usb_device_id keyspan_2port_ids[] = {
+static const struct usb_device_id keyspan_2port_ids[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) },
@@ -532,7 +532,7 @@ static struct usb_device_id keyspan_2por
 	{ } /* Terminating entry */
 };
 
-static struct usb_device_id keyspan_4port_ids[] = {
+static const struct usb_device_id keyspan_4port_ids[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)},
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wg_product_id)},
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/keyspan_pda.c linux-libre-2.6.34-gnu1/drivers/usb/serial/keyspan_pda.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/keyspan_pda.c	2013-05-03 12:13:05.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/keyspan_pda.c	2013-05-03 09:52:37.000000000 -0400
@@ -125,7 +125,7 @@ struct keyspan_pda_private {
 #define ENTREGRA_VENDOR_ID		0x1645
 #define ENTREGRA_FAKE_ID		0x8093
 
-static struct usb_device_id id_table_combined [] = {
+static const struct usb_device_id id_table_combined[] = {
 #ifdef KEYSPAN
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) },
 #endif
@@ -147,20 +147,20 @@ static struct usb_driver keyspan_pda_dri
 	.no_dynamic_id = 	1,
 };
 
-static struct usb_device_id id_table_std [] = {
+static const struct usb_device_id id_table_std[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) },
 	{ }						/* Terminating entry */
 };
 
 #ifdef KEYSPAN
-static struct usb_device_id id_table_fake [] = {
+static const struct usb_device_id id_table_fake[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) },
 	{ }						/* Terminating entry */
 };
 #endif
 
 #ifdef XIRCOM
-static struct usb_device_id id_table_fake_xircom [] = {
+static const struct usb_device_id id_table_fake_xircom[] = {
 	{ USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
 	{ USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) },
 	{ }
@@ -429,13 +429,20 @@ static int keyspan_pda_get_modem_info(st
 				      unsigned char *value)
 {
 	int rc;
-	unsigned char data;
+	u8 *data;
+
+	data = kmalloc(1, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
 	rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
 			     3, /* get pins */
 			     USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN,
-			     0, 0, &data, 1, 2000);
+			     0, 0, data, 1, 2000);
 	if (rc >= 0)
-		*value = data;
+		*value = *data;
+
+	kfree(data);
 	return rc;
 }
 
@@ -543,7 +550,14 @@ static int keyspan_pda_write(struct tty_
 	   device how much room it really has.  This is done only on
 	   scheduler time, since usb_control_msg() sleeps. */
 	if (count > priv->tx_room && !in_interrupt()) {
-		unsigned char room;
+		u8 *room;
+
+		room = kmalloc(1, GFP_KERNEL);
+		if (!room) {
+			rc = -ENOMEM;
+			goto exit;
+		}
+
 		rc = usb_control_msg(serial->dev,
 				     usb_rcvctrlpipe(serial->dev, 0),
 				     6, /* write_room */
@@ -551,9 +565,14 @@ static int keyspan_pda_write(struct tty_
 				     | USB_DIR_IN,
 				     0, /* value: 0 means "remaining room" */
 				     0, /* index */
-				     &room,
+				     room,
 				     1,
 				     2000);
+		if (rc > 0) {
+			dbg(" roomquery says %d", *room);
+			priv->tx_room = *room;
+		}
+		kfree(room);
 		if (rc < 0) {
 			dbg(" roomquery failed");
 			goto exit;
@@ -563,8 +582,6 @@ static int keyspan_pda_write(struct tty_
 			rc = -EIO; /* device didn't return any data */
 			goto exit;
 		}
-		dbg(" roomquery says %d", room);
-		priv->tx_room = room;
 	}
 	if (count > priv->tx_room) {
 		/* we're about to completely fill the Tx buffer, so
@@ -684,18 +701,22 @@ static int keyspan_pda_open(struct tty_s
 					struct usb_serial_port *port)
 {
 	struct usb_serial *serial = port->serial;
-	unsigned char room;
+	u8 *room;
 	int rc = 0;
 	struct keyspan_pda_private *priv;
 
 	/* find out how much room is in the Tx ring */
+	room = kmalloc(1, GFP_KERNEL);
+	if (!room)
+		return -ENOMEM;
+
 	rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
 			     6, /* write_room */
 			     USB_TYPE_VENDOR | USB_RECIP_INTERFACE
 			     | USB_DIR_IN,
 			     0, /* value */
 			     0, /* index */
-			     &room,
+			     room,
 			     1,
 			     2000);
 	if (rc < 0) {
@@ -708,8 +729,8 @@ static int keyspan_pda_open(struct tty_s
 		goto error;
 	}
 	priv = usb_get_serial_port_data(port);
-	priv->tx_room = room;
-	priv->tx_throttled = room ? 0 : 1;
+	priv->tx_room = *room;
+	priv->tx_throttled = *room ? 0 : 1;
 
 	/*Start reading from the device*/
 	port->interrupt_in_urb->dev = serial->dev;
@@ -718,8 +739,8 @@ static int keyspan_pda_open(struct tty_s
 		dbg("%s - usb_submit_urb(read int) failed", __func__);
 		goto error;
 	}
-
 error:
+	kfree(room);
 	return rc;
 }
 static void keyspan_pda_close(struct usb_serial_port *port)
@@ -789,6 +810,13 @@ static int keyspan_pda_fake_startup(stru
 	return 1;
 }
 
+#ifdef KEYSPAN
+MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw");
+#endif
+#ifdef XIRCOM
+MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw");
+#endif
+
 static int keyspan_pda_startup(struct usb_serial *serial)
 {
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/kl5kusb105.c linux-libre-2.6.34-gnu1/drivers/usb/serial/kl5kusb105.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/kl5kusb105.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/kl5kusb105.c	2010-05-16 17:17:36.000000000 -0400
@@ -94,7 +94,7 @@ static int  klsi_105_tiocmset(struct tty
 /*
  * All of the device info needed for the KLSI converters.
  */
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(PALMCONNECT_VID, PALMCONNECT_PID) },
 	{ USB_DEVICE(KLSI_VID, KLSI_KL5KUSB105D_PID) },
 	{ }		/* Terminating entry */
@@ -212,10 +212,19 @@ static int klsi_105_get_line_state(struc
 				   unsigned long *line_state_p)
 {
 	int rc;
-	__u8 status_buf[KLSI_STATUSBUF_LEN] = { -1, -1};
+	u8 *status_buf;
 	__u16 status;
 
 	dev_info(&port->serial->dev->dev, "sending SIO Poll request\n");
+
+	status_buf = kmalloc(KLSI_STATUSBUF_LEN, GFP_KERNEL);
+	if (!status_buf) {
+		dev_err(&port->dev, "%s - out of memory for status buffer.\n",
+				__func__);
+		return -ENOMEM;
+	}
+	status_buf[0] = 0xff;
+	status_buf[1] = 0xff;
 	rc = usb_control_msg(port->serial->dev,
 			     usb_rcvctrlpipe(port->serial->dev, 0),
 			     KL5KUSB105A_SIO_POLL,
@@ -236,6 +245,8 @@ static int klsi_105_get_line_state(struc
 
 		*line_state_p = klsi_105_status2linestate(status);
 	}
+
+	kfree(status_buf);
 	return rc;
 }
 
@@ -364,7 +375,7 @@ static int  klsi_105_open(struct tty_str
 	int rc;
 	int i;
 	unsigned long line_state;
-	struct klsi_105_port_settings cfg;
+	struct klsi_105_port_settings *cfg;
 	unsigned long flags;
 
 	dbg("%s port %d", __func__, port->number);
@@ -376,12 +387,18 @@ static int  klsi_105_open(struct tty_str
 	 * Then read the modem line control and store values in
 	 * priv->line_state.
 	 */
-	cfg.pktlen   = 5;
-	cfg.baudrate = kl5kusb105a_sio_b9600;
-	cfg.databits = kl5kusb105a_dtb_8;
-	cfg.unknown1 = 0;
-	cfg.unknown2 = 1;
-	klsi_105_chg_port_settings(port, &cfg);
+	cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
+	if (!cfg) {
+		dev_err(&port->dev, "%s - out of memory for config buffer.\n",
+				__func__);
+		return -ENOMEM;
+	}
+	cfg->pktlen   = 5;
+	cfg->baudrate = kl5kusb105a_sio_b9600;
+	cfg->databits = kl5kusb105a_dtb_8;
+	cfg->unknown1 = 0;
+	cfg->unknown2 = 1;
+	klsi_105_chg_port_settings(port, cfg);
 
 	/* set up termios structure */
 	spin_lock_irqsave(&priv->lock, flags);
@@ -391,11 +408,11 @@ static int  klsi_105_open(struct tty_str
 	priv->termios.c_lflag = tty->termios->c_lflag;
 	for (i = 0; i < NCCS; i++)
 		priv->termios.c_cc[i] = tty->termios->c_cc[i];
-	priv->cfg.pktlen   = cfg.pktlen;
-	priv->cfg.baudrate = cfg.baudrate;
-	priv->cfg.databits = cfg.databits;
-	priv->cfg.unknown1 = cfg.unknown1;
-	priv->cfg.unknown2 = cfg.unknown2;
+	priv->cfg.pktlen   = cfg->pktlen;
+	priv->cfg.baudrate = cfg->baudrate;
+	priv->cfg.databits = cfg->databits;
+	priv->cfg.unknown1 = cfg->unknown1;
+	priv->cfg.unknown2 = cfg->unknown2;
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	/* READ_ON and urb submission */
@@ -441,6 +458,7 @@ static int  klsi_105_open(struct tty_str
 		retval = rc;
 
 exit:
+	kfree(cfg);
 	return retval;
 } /* klsi_105_open */
 
@@ -681,7 +699,6 @@ static void klsi_105_read_bulk_callback(
 			bytes_sent = urb->actual_length - 2;
 		}
 
-		tty_buffer_request_room(tty, bytes_sent);
 		tty_insert_flip_string(tty, data + 2, bytes_sent);
 		tty_flip_buffer_push(tty);
 		tty_kref_put(tty);
@@ -714,10 +731,17 @@ static void klsi_105_set_termios(struct
 	unsigned int old_iflag = old_termios->c_iflag;
 	unsigned int cflag = tty->termios->c_cflag;
 	unsigned int old_cflag = old_termios->c_cflag;
-	struct klsi_105_port_settings cfg;
+	struct klsi_105_port_settings *cfg;
 	unsigned long flags;
 	speed_t baud;
 
+	cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
+	if (!cfg) {
+		dev_err(&port->dev, "%s - out of memory for config buffer.\n",
+				__func__);
+		return;
+	}
+
 	/* lock while we are modifying the settings */
 	spin_lock_irqsave(&priv->lock, flags);
 
@@ -793,11 +817,11 @@ static void klsi_105_set_termios(struct
 		case CS5:
 			dbg("%s - 5 bits/byte not supported", __func__);
 			spin_unlock_irqrestore(&priv->lock, flags);
-			return ;
+			goto err;
 		case CS6:
 			dbg("%s - 6 bits/byte not supported", __func__);
 			spin_unlock_irqrestore(&priv->lock, flags);
-			return ;
+			goto err;
 		case CS7:
 			priv->cfg.databits = kl5kusb105a_dtb_7;
 			break;
@@ -856,11 +880,13 @@ static void klsi_105_set_termios(struct
 #endif
 		;
 	}
-	memcpy(&cfg, &priv->cfg, sizeof(cfg));
+	memcpy(cfg, &priv->cfg, sizeof(*cfg));
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	/* now commit changes to device */
-	klsi_105_chg_port_settings(port, &cfg);
+	klsi_105_chg_port_settings(port, cfg);
+err:
+	kfree(cfg);
 } /* klsi_105_set_termios */
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/kobil_sct.c linux-libre-2.6.34-gnu1/drivers/usb/serial/kobil_sct.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/kobil_sct.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/kobil_sct.c	2010-05-16 17:17:36.000000000 -0400
@@ -86,7 +86,7 @@ static void kobil_set_termios(struct tty
 			struct usb_serial_port *port, struct ktermios *old);
 static void kobil_init_termios(struct tty_struct *tty);
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_B_PRODUCT_ID) },
 	{ USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_K_PRODUCT_ID) },
 	{ USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_USBTWIN_PRODUCT_ID) },
@@ -388,7 +388,6 @@ static void kobil_read_int_callback(stru
 		*/
 		/* END DEBUG */
 
-		tty_buffer_request_room(tty, urb->actual_length);
 		tty_insert_flip_string(tty, data, urb->actual_length);
 		tty_flip_buffer_push(tty);
 	}
@@ -624,7 +623,6 @@ static void kobil_set_termios(struct tty
 	unsigned short urb_val = 0;
 	int c_cflag = tty->termios->c_cflag;
 	speed_t speed;
-	void *settings;
 
 	priv = usb_get_serial_port_data(port);
 	if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
@@ -647,25 +645,13 @@ static void kobil_set_termios(struct tty
 	}
 	urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits :
 							SUSBCR_SPASB_1StopBit;
-
-	settings = kzalloc(50, GFP_KERNEL);
-	if (!settings)
-		return;
-
-	sprintf(settings, "%d ", speed);
-
 	if (c_cflag & PARENB) {
-		if  (c_cflag & PARODD) {
+		if  (c_cflag & PARODD)
 			urb_val |= SUSBCR_SPASB_OddParity;
-			strcat(settings, "Odd Parity");
-		} else {
+		else
 			urb_val |= SUSBCR_SPASB_EvenParity;
-			strcat(settings, "Even Parity");
-		}
-	} else {
+	} else
 		urb_val |= SUSBCR_SPASB_NoParity;
-		strcat(settings, "No Parity");
-	}
 	tty->termios->c_cflag &= ~CMSPAR;
 	tty_encode_baud_rate(tty, speed, speed);
 
@@ -675,11 +661,10 @@ static void kobil_set_termios(struct tty
 		  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
 		  urb_val,
 		  0,
-		  settings,
+		  NULL,
 		  0,
 		  KOBIL_TIMEOUT
 		);
-	kfree(settings);
 }
 
 static int kobil_ioctl(struct tty_struct *tty, struct file *file,
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/Makefile linux-libre-2.6.34-gnu1/drivers/usb/serial/Makefile
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -45,6 +45,7 @@ obj-$(CONFIG_USB_SERIAL_OPTICON)		+= opt
 obj-$(CONFIG_USB_SERIAL_OPTION)			+= option.o
 obj-$(CONFIG_USB_SERIAL_OTI6858)		+= oti6858.o
 obj-$(CONFIG_USB_SERIAL_PL2303)			+= pl2303.o
+obj-$(CONFIG_USB_SERIAL_QCAUX)			+= qcaux.o
 obj-$(CONFIG_USB_SERIAL_QUALCOMM)		+= qcserial.o
 obj-$(CONFIG_USB_SERIAL_SAFE)			+= safe_serial.o
 obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI)		+= siemens_mpi.o
@@ -55,4 +56,5 @@ obj-$(CONFIG_USB_SERIAL_TI)			+= ti_usb_
 obj-$(CONFIG_USB_SERIAL_VISOR)			+= visor.o
 obj-$(CONFIG_USB_SERIAL_WHITEHEAT)		+= whiteheat.o
 obj-$(CONFIG_USB_SERIAL_XIRCOM)			+= keyspan_pda.o
+obj-$(CONFIG_USB_SERIAL_VIVOPAY_SERIAL)	+= vivopay-serial.o
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/mct_u232.c linux-libre-2.6.34-gnu1/drivers/usb/serial/mct_u232.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/mct_u232.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/mct_u232.c	2010-05-16 17:17:36.000000000 -0400
@@ -75,6 +75,7 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
+#include <asm/unaligned.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include "mct_u232.h"
@@ -110,7 +111,7 @@ static void mct_u232_unthrottle(struct t
 /*
  * All of the device info needed for the MCT USB-RS232 converter.
  */
-static struct usb_device_id id_table_combined [] = {
+static const struct usb_device_id id_table_combined[] = {
 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
@@ -231,19 +232,22 @@ static int mct_u232_calculate_baud_rate(
 static int mct_u232_set_baud_rate(struct tty_struct *tty,
 	struct usb_serial *serial, struct usb_serial_port *port, speed_t value)
 {
-	__le32 divisor;
+	unsigned int divisor;
 	int rc;
-	unsigned char zero_byte = 0;
+	unsigned char *buf;
 	unsigned char cts_enable_byte = 0;
 	speed_t speed;
 
-	divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value,
-								&speed));
+	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
 
+	divisor = mct_u232_calculate_baud_rate(serial, value, &speed);
+	put_unaligned_le32(cpu_to_le32(divisor), buf);
 	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 				MCT_U232_SET_BAUD_RATE_REQUEST,
 				MCT_U232_SET_REQUEST_TYPE,
-				0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE,
+				0, 0, buf, MCT_U232_SET_BAUD_RATE_SIZE,
 				WDR_TIMEOUT);
 	if (rc < 0)	/*FIXME: What value speed results */
 		dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n",
@@ -269,10 +273,11 @@ static int mct_u232_set_baud_rate(struct
 	   a device which is not asserting 'CTS'.
 	*/
 
+	buf[0] = 0;
 	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 				MCT_U232_SET_UNKNOWN1_REQUEST,
 				MCT_U232_SET_REQUEST_TYPE,
-				0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE,
+				0, 0, buf, MCT_U232_SET_UNKNOWN1_SIZE,
 				WDR_TIMEOUT);
 	if (rc < 0)
 		dev_err(&port->dev, "Sending USB device request code %d "
@@ -284,30 +289,40 @@ static int mct_u232_set_baud_rate(struct
 
 	dbg("set_baud_rate: send second control message, data = %02X",
 							cts_enable_byte);
+	buf[0] = cts_enable_byte;
 	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 			MCT_U232_SET_CTS_REQUEST,
 			MCT_U232_SET_REQUEST_TYPE,
-			0, 0, &cts_enable_byte, MCT_U232_SET_CTS_SIZE,
+			0, 0, buf, MCT_U232_SET_CTS_SIZE,
 			WDR_TIMEOUT);
 	if (rc < 0)
 		dev_err(&port->dev, "Sending USB device request code %d "
 			"failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc);
 
+	kfree(buf);
 	return rc;
 } /* mct_u232_set_baud_rate */
 
 static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr)
 {
 	int rc;
+	unsigned char *buf;
+
+	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	buf[0] = lcr;
 	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 			MCT_U232_SET_LINE_CTRL_REQUEST,
 			MCT_U232_SET_REQUEST_TYPE,
-			0, 0, &lcr, MCT_U232_SET_LINE_CTRL_SIZE,
+			0, 0, buf, MCT_U232_SET_LINE_CTRL_SIZE,
 			WDR_TIMEOUT);
 	if (rc < 0)
 		dev_err(&serial->dev->dev,
 			"Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc);
 	dbg("set_line_ctrl: 0x%x", lcr);
+	kfree(buf);
 	return rc;
 } /* mct_u232_set_line_ctrl */
 
@@ -315,23 +330,31 @@ static int mct_u232_set_modem_ctrl(struc
 				   unsigned int control_state)
 {
 	int rc;
-	unsigned char mcr = MCT_U232_MCR_NONE;
+	unsigned char mcr;
+	unsigned char *buf;
 
+	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	mcr = MCT_U232_MCR_NONE;
 	if (control_state & TIOCM_DTR)
 		mcr |= MCT_U232_MCR_DTR;
 	if (control_state & TIOCM_RTS)
 		mcr |= MCT_U232_MCR_RTS;
 
+	buf[0] = mcr;
 	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 			MCT_U232_SET_MODEM_CTRL_REQUEST,
 			MCT_U232_SET_REQUEST_TYPE,
-			0, 0, &mcr, MCT_U232_SET_MODEM_CTRL_SIZE,
+			0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE,
 			WDR_TIMEOUT);
 	if (rc < 0)
 		dev_err(&serial->dev->dev,
 			"Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc);
 	dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr);
 
+	kfree(buf);
 	return rc;
 } /* mct_u232_set_modem_ctrl */
 
@@ -339,17 +362,27 @@ static int mct_u232_get_modem_stat(struc
 						unsigned char *msr)
 {
 	int rc;
+	unsigned char *buf;
+
+	buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
+	if (buf == NULL) {
+		*msr = 0;
+		return -ENOMEM;
+	}
 	rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
 			MCT_U232_GET_MODEM_STAT_REQUEST,
 			MCT_U232_GET_REQUEST_TYPE,
-			0, 0, msr, MCT_U232_GET_MODEM_STAT_SIZE,
+			0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE,
 			WDR_TIMEOUT);
 	if (rc < 0) {
 		dev_err(&serial->dev->dev,
 			"Get MODEM STATus failed (error = %d)\n", rc);
 		*msr = 0;
+	} else {
+		*msr = buf[0];
 	}
 	dbg("get_modem_stat: 0x%x", *msr);
+	kfree(buf);
 	return rc;
 } /* mct_u232_get_modem_stat */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/mct_u232.h linux-libre-2.6.34-gnu1/drivers/usb/serial/mct_u232.h
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/mct_u232.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/mct_u232.h	2010-05-16 17:17:36.000000000 -0400
@@ -73,6 +73,8 @@
 #define MCT_U232_SET_CTS_REQUEST   12
 #define MCT_U232_SET_CTS_SIZE       1
 
+#define MCT_U232_MAX_SIZE		4	/* of MCT_XXX_SIZE */
+
 /*
  * Baud rate (divisor)
  * Actually, there are two of them, MCT website calls them "Philips solution"
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/mos7720.c linux-libre-2.6.34-gnu1/drivers/usb/serial/mos7720.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/mos7720.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/mos7720.c	2010-05-16 17:17:36.000000000 -0400
@@ -81,12 +81,15 @@ struct moschip_serial {
 
 static int debug;
 
+static struct usb_serial_driver moschip7720_2port_driver;
+
 #define USB_VENDOR_ID_MOSCHIP		0x9710
 #define MOSCHIP_DEVICE_ID_7720		0x7720
 #define MOSCHIP_DEVICE_ID_7715		0x7715
 
-static struct usb_device_id moschip_port_id_table[] = {
+static const struct usb_device_id moschip_port_id_table[] = {
 	{ USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7720) },
+	{ USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7715) },
 	{ } /* terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, moschip_port_id_table);
@@ -106,7 +109,7 @@ static void mos7720_interrupt_callback(s
 	__u8 sp1;
 	__u8 sp2;
 
-	dbg("%s", " : Entering\n");
+	dbg(" : Entering");
 
 	switch (status) {
 	case 0:
@@ -186,6 +189,75 @@ exit:
 }
 
 /*
+ * mos7715_interrupt_callback
+ *	this is the 7715's callback function for when we have received data on
+ *	the interrupt endpoint.
+ */
+static void mos7715_interrupt_callback(struct urb *urb)
+{
+	int result;
+	int length;
+	int status = urb->status;
+	__u8 *data;
+	__u8 iir;
+
+	switch (status) {
+	case 0:
+		/* success */
+		break;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		/* this urb is terminated, clean up */
+		dbg("%s - urb shutting down with status: %d", __func__,
+		    status);
+		return;
+	default:
+		dbg("%s - nonzero urb status received: %d", __func__,
+		    status);
+		goto exit;
+	}
+
+	length = urb->actual_length;
+	data = urb->transfer_buffer;
+
+	/* Structure of data from 7715 device:
+	 * Byte 1: IIR serial Port
+	 * Byte 2: unused
+	 * Byte 2: DSR parallel port
+	 * Byte 4: FIFO status for both */
+
+	if (unlikely(length != 4)) {
+		dbg("Wrong data !!!");
+		return;
+	}
+
+	iir = data[0];
+	if (!(iir & 0x01)) {	/* serial port interrupt pending */
+		switch (iir & 0x0f) {
+		case SERIAL_IIR_RLS:
+			dbg("Serial Port: Receiver status error or address "
+			    "bit detected in 9-bit mode\n");
+			break;
+		case SERIAL_IIR_CTI:
+			dbg("Serial Port: Receiver time out");
+			break;
+		case SERIAL_IIR_MS:
+			dbg("Serial Port: Modem status change");
+			break;
+		}
+	}
+
+exit:
+	result = usb_submit_urb(urb, GFP_ATOMIC);
+	if (result)
+		dev_err(&urb->dev->dev,
+			"%s - Error %d submitting control urb\n",
+			__func__, result);
+	return;
+}
+
+/*
  * mos7720_bulk_in_callback
  *	this is the callback function for when we have received data on the
  *	bulk in endpoint.
@@ -206,7 +278,7 @@ static void mos7720_bulk_in_callback(str
 
 	mos7720_port = urb->context;
 	if (!mos7720_port) {
-		dbg("%s", "NULL mos7720_port pointer \n");
+		dbg("NULL mos7720_port pointer");
 		return ;
 	}
 
@@ -218,7 +290,6 @@ static void mos7720_bulk_in_callback(str
 
 	tty = tty_port_tty_get(&port->port);
 	if (tty && urb->actual_length) {
-		tty_buffer_request_room(tty, urb->actual_length);
 		tty_insert_flip_string(tty, data, urb->actual_length);
 		tty_flip_buffer_push(tty);
 	}
@@ -275,17 +346,15 @@ static void mos7720_bulk_out_data_callba
  *	this function will be used for sending command to device
  */
 static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value,
-			__u16 index, void *data)
+			__u16 index, u8 *data)
 {
 	int status;
-	unsigned int pipe;
+	u8 *buf;
 	u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
-	__u8 requesttype;
-	__u16 size = 0x0000;
 
 	if (value < MOS_MAX_PORT) {
 		if (product == MOSCHIP_DEVICE_ID_7715)
-			value = value*0x100+0x100;
+			value = 0x0200; /* identifies the 7715's serial port */
 		else
 			value = value*0x100+0x200;
 	} else {
@@ -298,27 +367,58 @@ static int send_mos_cmd(struct usb_seria
 	}
 
 	if (request == MOS_WRITE) {
-		request = (__u8)MOS_WRITE;
-		requesttype = (__u8)0x40;
-		value  = value + (__u16)*((unsigned char *)data);
-		data = NULL;
-		pipe = usb_sndctrlpipe(serial->dev, 0);
+		value = value + *data;
+		status = usb_control_msg(serial->dev,
+				usb_sndctrlpipe(serial->dev, 0), MOS_WRITE,
+				0x40, value, index, NULL, 0, MOS_WDR_TIMEOUT);
 	} else {
-		request = (__u8)MOS_READ;
-		requesttype = (__u8)0xC0;
-		size = 0x01;
-		pipe = usb_rcvctrlpipe(serial->dev, 0);
+		buf = kmalloc(1, GFP_KERNEL);
+		if (!buf) {
+			status = -ENOMEM;
+			goto out;
+		}
+		status = usb_control_msg(serial->dev,
+				usb_rcvctrlpipe(serial->dev, 0), MOS_READ,
+				0xc0, value, index, buf, 1, MOS_WDR_TIMEOUT);
+		*data = *buf;
+		kfree(buf);
 	}
-
-	status = usb_control_msg(serial->dev, pipe, request, requesttype,
-				 value, index, data, size, MOS_WDR_TIMEOUT);
-
+out:
 	if (status < 0)
-		dbg("Command Write failed Value %x index %x\n", value, index);
+		dbg("Command Write failed Value %x index %x", value, index);
 
 	return status;
 }
 
+
+/*
+ * mos77xx_probe
+ *	this function installs the appropriate read interrupt endpoint callback
+ *	depending on whether the device is a 7720 or 7715, thus avoiding costly
+ *	run-time checks in the high-frequency callback routine itself.
+ */
+static int mos77xx_probe(struct usb_serial *serial,
+			 const struct usb_device_id *id)
+{
+	if (id->idProduct == MOSCHIP_DEVICE_ID_7715)
+		moschip7720_2port_driver.read_int_callback =
+			mos7715_interrupt_callback;
+	else
+		moschip7720_2port_driver.read_int_callback =
+			mos7720_interrupt_callback;
+
+	return 0;
+}
+
+static int mos77xx_calc_num_ports(struct usb_serial *serial)
+{
+	u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
+	if (product == MOSCHIP_DEVICE_ID_7715)
+		return 1;
+
+	return 2;
+}
+
 static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct usb_serial *serial;
@@ -390,7 +490,7 @@ static int mos7720_open(struct tty_struc
 	  */
 	port_number = port->number - port->serial->minor;
 	send_mos_cmd(port->serial, MOS_READ, port_number, UART_LSR, &data);
-	dbg("SS::%p LSR:%x\n", mos7720_port, data);
+	dbg("SS::%p LSR:%x", mos7720_port, data);
 
 	dbg("Check:Sending Command ..........");
 
@@ -729,7 +829,7 @@ static void mos7720_throttle(struct tty_
 	struct moschip_port *mos7720_port;
 	int status;
 
-	dbg("%s- port %d\n", __func__, port->number);
+	dbg("%s- port %d", __func__, port->number);
 
 	mos7720_port = usb_get_serial_port_data(port);
 
@@ -1208,7 +1308,7 @@ static void mos7720_set_termios(struct t
 		return;
 	}
 
-	dbg("%s\n", "setting termios - ASPIRE");
+	dbg("setting termios - ASPIRE");
 
 	cflag = tty->termios->c_cflag;
 
@@ -1226,7 +1326,7 @@ static void mos7720_set_termios(struct t
 	change_port_settings(tty, mos7720_port, old_termios);
 
 	if (!port->read_urb) {
-		dbg("%s", "URB KILLED !!!!!\n");
+		dbg("URB KILLED !!!!!");
 		return;
 	}
 
@@ -1495,6 +1595,7 @@ static int mos7720_startup(struct usb_se
 	struct usb_device *dev;
 	int i;
 	char data;
+	u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
 
 	dbg("%s: Entering ..........", __func__);
 
@@ -1514,6 +1615,29 @@ static int mos7720_startup(struct usb_se
 
 	usb_set_serial_data(serial, mos7720_serial);
 
+	/*
+	 * The 7715 uses the first bulk in/out endpoint pair for the parallel
+	 * port, and the second for the serial port.  Because the usbserial core
+	 * assumes both pairs are serial ports, we must engage in a bit of
+	 * subterfuge and swap the pointers for ports 0 and 1 in order to make
+	 * port 0 point to the serial port.  However, both moschip devices use a
+	 * single interrupt-in endpoint for both ports (as mentioned a little
+	 * further down), and this endpoint was assigned to port 0.  So after
+	 * the swap, we must copy the interrupt endpoint elements from port 1
+	 * (as newly assigned) to port 0, and null out port 1 pointers.
+	 */
+	if (product == MOSCHIP_DEVICE_ID_7715) {
+		struct usb_serial_port *tmp = serial->port[0];
+		serial->port[0] = serial->port[1];
+		serial->port[1] = tmp;
+		serial->port[0]->interrupt_in_urb = tmp->interrupt_in_urb;
+		serial->port[0]->interrupt_in_buffer = tmp->interrupt_in_buffer;
+		serial->port[0]->interrupt_in_endpointAddress =
+			tmp->interrupt_in_endpointAddress;
+		serial->port[1]->interrupt_in_urb = NULL;
+		serial->port[1]->interrupt_in_buffer = NULL;
+	}
+
 	/* we set up the pointers to the endpoints in the mos7720_open *
 	 * function, as the structures aren't created yet.             */
 
@@ -1529,7 +1653,7 @@ static int mos7720_startup(struct usb_se
 
 		/* Initialize all port interrupt end point to port 0 int
 		 * endpoint.  Our device has only one interrupt endpoint
-		 * comman to all ports */
+		 * common to all ports */
 		serial->port[i]->interrupt_in_endpointAddress =
 				serial->port[0]->interrupt_in_endpointAddress;
 
@@ -1584,11 +1708,12 @@ static struct usb_serial_driver moschip7
 	.description		= "Moschip 2 port adapter",
 	.usb_driver		= &usb_driver,
 	.id_table		= moschip_port_id_table,
-	.num_ports		= 2,
+	.calc_num_ports		= mos77xx_calc_num_ports,
 	.open			= mos7720_open,
 	.close			= mos7720_close,
 	.throttle		= mos7720_throttle,
 	.unthrottle		= mos7720_unthrottle,
+	.probe			= mos77xx_probe,
 	.attach			= mos7720_startup,
 	.release		= mos7720_release,
 	.ioctl			= mos7720_ioctl,
@@ -1600,7 +1725,7 @@ static struct usb_serial_driver moschip7
 	.chars_in_buffer	= mos7720_chars_in_buffer,
 	.break_ctl		= mos7720_break,
 	.read_bulk_callback	= mos7720_bulk_in_callback,
-	.read_int_callback	= mos7720_interrupt_callback,
+	.read_int_callback	= NULL  /* dynamically assigned in probe() */
 };
 
 static int __init moschip7720_init(void)
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/mos7840.c linux-libre-2.6.34-gnu1/drivers/usb/serial/mos7840.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/mos7840.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/mos7840.c	2010-05-16 17:17:36.000000000 -0400
@@ -181,7 +181,7 @@
 #define URB_TRANSFER_BUFFER_SIZE        32	/* URB Size  */
 
 
-static struct usb_device_id moschip_port_id_table[] = {
+static const struct usb_device_id moschip_port_id_table[] = {
 	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
 	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
 	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
@@ -198,7 +198,7 @@ static struct usb_device_id moschip_port
 	{}			/* terminating entry */
 };
 
-static __devinitdata struct usb_device_id moschip_id_table_combined[] = {
+static const struct usb_device_id moschip_id_table_combined[] __devinitconst = {
 	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
 	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
 	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
@@ -283,12 +283,19 @@ static int mos7840_get_reg_sync(struct u
 {
 	struct usb_device *dev = port->serial->dev;
 	int ret = 0;
+	u8 *buf;
+
+	buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
 
 	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
-			      MCS_RD_RTYPE, 0, reg, val, VENDOR_READ_LENGTH,
+			      MCS_RD_RTYPE, 0, reg, buf, VENDOR_READ_LENGTH,
 			      MOS_WDR_TIMEOUT);
+	*val = buf[0];
 	dbg("mos7840_get_reg_sync offset is %x, return val %x", reg, *val);
-	*val = (*val) & 0x00ff;
+
+	kfree(buf);
 	return ret;
 }
 
@@ -341,6 +348,11 @@ static int mos7840_get_uart_reg(struct u
 	struct usb_device *dev = port->serial->dev;
 	int ret = 0;
 	__u16 Wval;
+	u8 *buf;
+
+	buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
 
 	/* dbg("application number is %4x",
 	    (((__u16)port->number - (__u16)(port->serial->minor))+1)<<8); */
@@ -364,9 +376,11 @@ static int mos7840_get_uart_reg(struct u
 		}
 	}
 	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
-			      MCS_RD_RTYPE, Wval, reg, val, VENDOR_READ_LENGTH,
+			      MCS_RD_RTYPE, Wval, reg, buf, VENDOR_READ_LENGTH,
 			      MOS_WDR_TIMEOUT);
-	*val = (*val) & 0x00ff;
+	*val = buf[0];
+
+	kfree(buf);
 	return ret;
 }
 
@@ -750,7 +764,6 @@ static void mos7840_bulk_in_callback(str
 	if (urb->actual_length) {
 		tty = tty_port_tty_get(&mos7840_port->port->port);
 		if (tty) {
-			tty_buffer_request_room(tty, urb->actual_length);
 			tty_insert_flip_string(tty, data, urb->actual_length);
 			dbg(" %s ", data);
 			tty_flip_buffer_push(tty);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/moto_modem.c linux-libre-2.6.34-gnu1/drivers/usb/serial/moto_modem.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/moto_modem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/moto_modem.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,7 @@
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x05c6, 0x3197) },	/* unknown Motorola phone */
 	{ USB_DEVICE(0x0c44, 0x0022) },	/* unknown Mororola phone */
 	{ USB_DEVICE(0x22b8, 0x2a64) },	/* Motorola KRZR K1m */
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/navman.c linux-libre-2.6.34-gnu1/drivers/usb/serial/navman.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/navman.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/navman.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
  *	flags as the navman is rx only so cannot echo.
  */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/tty.h>
@@ -22,7 +23,7 @@
 
 static int debug;
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x0a99, 0x0001) },	/* Talon Technology device */
 	{ },
 };
@@ -66,7 +67,6 @@ static void navman_read_int_callback(str
 
 	tty = tty_port_tty_get(&port->port);
 	if (tty && urb->actual_length) {
-		tty_buffer_request_room(tty, urb->actual_length);
 		tty_insert_flip_string(tty, data, urb->actual_length);
 		tty_flip_buffer_push(tty);
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/omninet.c linux-libre-2.6.34-gnu1/drivers/usb/serial/omninet.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/omninet.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/omninet.c	2010-05-16 17:17:36.000000000 -0400
@@ -75,7 +75,7 @@ static void omninet_disconnect(struct us
 static void omninet_release(struct usb_serial *serial);
 static int omninet_attach(struct usb_serial *serial);
 
-static struct usb_device_id id_table[] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) },
 	{ USB_DEVICE(ZYXEL_VENDOR_ID, BT_IGNITIONPRO_ID) },
 	{ }						/* Terminating entry */
@@ -218,8 +218,8 @@ static void omninet_read_bulk_callback(s
 
 	if (debug && header->oh_xxx != 0x30) {
 		if (urb->actual_length) {
-			printk(KERN_DEBUG __FILE__
-					": omninet_read %d: ", header->oh_len);
+			printk(KERN_DEBUG "%s: omninet_read %d: ",
+			       __FILE__, header->oh_len);
 			for (i = 0; i < (header->oh_len +
 						OMNINET_HEADERLEN); i++)
 				printk("%.2x ", data[i]);
@@ -332,7 +332,7 @@ static void omninet_write_bulk_callback(
 	struct usb_serial_port 	*port   =  urb->context;
 	int status = urb->status;
 
-	dbg("%s - port %0x\n", __func__, port->number);
+	dbg("%s - port %0x", __func__, port->number);
 
 	port->write_urb_busy = 0;
 	if (status) {
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/opticon.c linux-libre-2.6.34-gnu1/drivers/usb/serial/opticon.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/opticon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/opticon.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
+#include <linux/slab.h>
 #include <linux/tty_flip.h>
 #include <linux/serial.h>
 #include <linux/module.h>
@@ -22,7 +23,7 @@
 
 static int debug;
 
-static struct usb_device_id id_table[] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x065a, 0x0009) },
 	{ },
 };
@@ -55,7 +56,6 @@ static void opticon_bulk_callback(struct
 	int status = urb->status;
 	struct tty_struct *tty;
 	int result;
-	int available_room = 0;
 	int data_length;
 
 	dbg("%s - port %d", __func__, port->number);
@@ -96,13 +96,9 @@ static void opticon_bulk_callback(struct
 			/* real data, send it to the tty layer */
 			tty = tty_port_tty_get(&port->port);
 			if (tty) {
-				available_room = tty_buffer_request_room(tty,
-								data_length);
-				if (available_room) {
-					tty_insert_flip_string(tty, data,
-							       available_room);
-					tty_flip_buffer_push(tty);
-				}
+				tty_insert_flip_string(tty, data,
+							       data_length);
+				tty_flip_buffer_push(tty);
 				tty_kref_put(tty);
 			}
 		} else {
@@ -120,7 +116,7 @@ static void opticon_bulk_callback(struct
 		}
 	} else {
 		dev_dbg(&priv->udev->dev,
-			"Improper ammount of data received from the device, "
+			"Improper amount of data received from the device, "
 			"%d bytes", urb->actual_length);
 	}
 
@@ -217,7 +213,7 @@ static int opticon_write(struct tty_stru
 	spin_lock_irqsave(&priv->lock, flags);
 	if (priv->outstanding_urbs > URB_UPPER_LIMIT) {
 		spin_unlock_irqrestore(&priv->lock, flags);
-		dbg("%s - write limit hit\n", __func__);
+		dbg("%s - write limit hit", __func__);
 		return 0;
 	}
 	priv->outstanding_urbs++;
@@ -288,7 +284,7 @@ static int opticon_write_room(struct tty
 	spin_lock_irqsave(&priv->lock, flags);
 	if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) {
 		spin_unlock_irqrestore(&priv->lock, flags);
-		dbg("%s - write limit hit\n", __func__);
+		dbg("%s - write limit hit", __func__);
 		return 0;
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/option.c linux-libre-2.6.34-gnu1/drivers/usb/serial/option.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/option.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/option.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/errno.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/usb.h>
@@ -288,7 +289,9 @@ static int  option_resume(struct usb_ser
 
 #define QUALCOMM_VENDOR_ID			0x05C6
 
-#define MAXON_VENDOR_ID				0x16d8
+#define CMOTECH_VENDOR_ID			0x16d8
+#define CMOTECH_PRODUCT_6008			0x6008
+#define CMOTECH_PRODUCT_6280			0x6280
 
 #define TELIT_VENDOR_ID				0x1bc7
 #define TELIT_PRODUCT_UC864E			0x1003
@@ -302,6 +305,11 @@ static int  option_resume(struct usb_ser
 #define ZTE_PRODUCT_CDMA_TECH			0xfffe
 #define ZTE_PRODUCT_AC8710			0xfff1
 #define ZTE_PRODUCT_AC2726			0xfff5
+#define ZTE_PRODUCT_AC8710T			0xffff
+
+/* ZTE PRODUCTS -- alternate vendor ID */
+#define ZTE_VENDOR_ID2				0x1d6b
+#define ZTE_PRODUCT_MF_330			0x0002
 
 #define BENQ_VENDOR_ID				0x04a5
 #define BENQ_PRODUCT_H10			0x4068
@@ -309,6 +317,7 @@ static int  option_resume(struct usb_ser
 #define DLINK_VENDOR_ID				0x1186
 #define DLINK_PRODUCT_DWM_652			0x3e04
 #define DLINK_PRODUCT_DWM_652_U5		0xce16
+#define DLINK_PRODUCT_DWM_652_U5A		0xce1e
 
 #define QISDA_VENDOR_ID				0x1da5
 #define QISDA_PRODUCT_H21_4512			0x4512
@@ -332,19 +341,66 @@ static int  option_resume(struct usb_ser
 #define ALCATEL_VENDOR_ID			0x1bbb
 #define ALCATEL_PRODUCT_X060S			0x0000
 
+#define PIRELLI_VENDOR_ID			0x1266
+#define PIRELLI_PRODUCT_C100_1			0x1002
+#define PIRELLI_PRODUCT_C100_2			0x1003
+#define PIRELLI_PRODUCT_1004			0x1004
+#define PIRELLI_PRODUCT_1005			0x1005
+#define PIRELLI_PRODUCT_1006			0x1006
+#define PIRELLI_PRODUCT_1007			0x1007
+#define PIRELLI_PRODUCT_1008			0x1008
+#define PIRELLI_PRODUCT_1009			0x1009
+#define PIRELLI_PRODUCT_100A			0x100a
+#define PIRELLI_PRODUCT_100B			0x100b
+#define PIRELLI_PRODUCT_100C			0x100c
+#define PIRELLI_PRODUCT_100D			0x100d
+#define PIRELLI_PRODUCT_100E			0x100e
+#define PIRELLI_PRODUCT_100F			0x100f
+#define PIRELLI_PRODUCT_1011			0x1011
+#define PIRELLI_PRODUCT_1012			0x1012
+
 /* Airplus products */
 #define AIRPLUS_VENDOR_ID			0x1011
 #define AIRPLUS_PRODUCT_MCD650			0x3198
 
+/* Longcheer/Longsung vendor ID; makes whitelabel devices that
+ * many other vendors like 4G Systems, Alcatel, ChinaBird,
+ * Mobidata, etc sell under their own brand names.
+ */
+#define LONGCHEER_VENDOR_ID			0x1c9e
+
 /* 4G Systems products */
-#define FOUR_G_SYSTEMS_VENDOR_ID		0x1c9e
+/* This is the 4G XS Stick W14 a.k.a. Mobilcom Debitel Surf-Stick *
+ * It seems to contain a Qualcomm QSC6240/6290 chipset            */
 #define FOUR_G_SYSTEMS_PRODUCT_W14		0x9603
 
 /* Haier products */
 #define HAIER_VENDOR_ID				0x201e
 #define HAIER_PRODUCT_CE100			0x2009
 
-static struct usb_device_id option_ids[] = {
+#define CINTERION_VENDOR_ID			0x0681
+
+/* some devices interfaces need special handling due to a number of reasons */
+enum option_blacklist_reason {
+		OPTION_BLACKLIST_NONE = 0,
+		OPTION_BLACKLIST_SENDSETUP = 1,
+		OPTION_BLACKLIST_RESERVED_IF = 2
+};
+
+struct option_blacklist_info {
+	const u32 infolen;	/* number of interface numbers on blacklist */
+	const u8  *ifaceinfo;	/* pointer to the array holding the numbers */
+	enum option_blacklist_reason reason;
+};
+
+static const u8 four_g_w14_no_sendsetup[] = { 0, 1 };
+static const struct option_blacklist_info four_g_w14_blacklist = {
+	.infolen = ARRAY_SIZE(four_g_w14_no_sendsetup),
+	.ifaceinfo = four_g_w14_no_sendsetup,
+	.reason = OPTION_BLACKLIST_SENDSETUP
+};
+
+static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) },
@@ -520,7 +576,8 @@ static struct usb_device_id option_ids[]
 	{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
-	{ USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
+	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */
+	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) },
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
@@ -629,9 +686,12 @@ static struct usb_device_id option_ids[]
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE(ZTE_VENDOR_ID2, ZTE_PRODUCT_MF_330) },
 	{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
 	{ USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
 	{ USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */
+	{ USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5A) },
 	{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) },
 	{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) },
 	{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) },
@@ -639,13 +699,33 @@ static struct usb_device_id option_ids[]
 	{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) },
 	{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
 	{ USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
-	{ USB_DEVICE(ALINK_VENDOR_ID, 0xce16) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) },
 	{ USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
 	{ USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
-	{ USB_DEVICE(FOUR_G_SYSTEMS_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14) },
+	{ USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
+  	  .driver_info = (kernel_ulong_t)&four_g_w14_blacklist
+  	},
 	{ USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) },
+	/* Pirelli  */
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)},
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2)},
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1004)},
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1005)},
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1006)},
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1007)},
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1008)},
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1009)},
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100A)},
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100B) },
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100C) },
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100D) },
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100E) },
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) },
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)},
+	{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)},
+
+	{ USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) },
 	{ } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
@@ -709,6 +789,7 @@ struct option_intf_private {
 	spinlock_t susp_lock;
 	unsigned int suspended:1;
 	int in_flight;
+	struct option_blacklist_info *blacklist_info;
 };
 
 struct option_port_private {
@@ -768,19 +849,44 @@ static int option_probe(struct usb_seria
 			const struct usb_device_id *id)
 {
 	struct option_intf_private *data;
+
 	/* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */
 	if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID &&
 		serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 &&
 		serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8)
 		return -ENODEV;
 
+	/* Bandrich modem and AT command interface is 0xff */
+	if ((serial->dev->descriptor.idVendor == BANDRICH_VENDOR_ID ||
+		serial->dev->descriptor.idVendor == PIRELLI_VENDOR_ID) &&
+		serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff)
+		return -ENODEV;
+
 	data = serial->private = kzalloc(sizeof(struct option_intf_private), GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
 	spin_lock_init(&data->susp_lock);
+	data->blacklist_info = (struct option_blacklist_info*) id->driver_info;
 	return 0;
 }
 
+static enum option_blacklist_reason is_blacklisted(const u8 ifnum,
+				const struct option_blacklist_info *blacklist)
+{
+	const u8  *info;
+	int i;
+
+	if (blacklist) {
+		info = blacklist->ifaceinfo;
+
+		for (i = 0; i < blacklist->infolen; i++) {
+			if (info[i] == ifnum)
+				return blacklist->reason;
+		}
+	}
+	return OPTION_BLACKLIST_NONE;
+}
+
 static void option_set_termios(struct tty_struct *tty,
 		struct usb_serial_port *port, struct ktermios *old_termios)
 {
@@ -921,7 +1027,6 @@ static void option_indat_callback(struct
 	} else {
 		tty = tty_port_tty_get(&port->port);
 		if (urb->actual_length) {
-			tty_buffer_request_room(tty, urb->actual_length);
 			tty_insert_flip_string(tty, data, urb->actual_length);
 			tty_flip_buffer_push(tty);
 		} else 
@@ -929,9 +1034,9 @@ static void option_indat_callback(struct
 		tty_kref_put(tty);
 
 		/* Resubmit urb so we continue receiving */
-		if (port->port.count && status != -ESHUTDOWN) {
+		if (status != -ESHUTDOWN) {
 			err = usb_submit_urb(urb, GFP_ATOMIC);
-			if (err)
+			if (err && err != -EPERM)
 				printk(KERN_ERR "%s: resubmit read urb failed. "
 					"(%d)", __func__, err);
 			else
@@ -985,7 +1090,7 @@ static void option_instat_callback(struc
 				(struct usb_ctrlrequest *)urb->transfer_buffer;
 
 		if (!req_pkt) {
-			dbg("%s: NULL req_pkt\n", __func__);
+			dbg("%s: NULL req_pkt", __func__);
 			return;
 		}
 		if ((req_pkt->bRequestType == 0xA1) &&
@@ -1211,11 +1316,19 @@ static void option_setup_urbs(struct usb
 static int option_send_setup(struct usb_serial_port *port)
 {
 	struct usb_serial *serial = port->serial;
+	struct option_intf_private *intfdata =
+		(struct option_intf_private *) serial->private;
 	struct option_port_private *portdata;
 	int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
 	int val = 0;
 	dbg("%s", __func__);
 
+	if (is_blacklisted(ifNum, intfdata->blacklist_info) ==
+						OPTION_BLACKLIST_SENDSETUP) {
+		dbg("No send_setup on blacklisted interface #%d\n", ifNum);
+		return -EIO;
+	}
+
 	portdata = usb_get_serial_port_data(port);
 
 	if (portdata->dtr_state)
@@ -1401,7 +1514,7 @@ static int option_resume(struct usb_seri
 	for (i = 0; i < serial->num_ports; i++) {
 		port = serial->port[i];
 		if (!port->interrupt_in_urb) {
-			dbg("%s: No interrupt URB for port %d\n", __func__, i);
+			dbg("%s: No interrupt URB for port %d", __func__, i);
 			continue;
 		}
 		err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/oti6858.c linux-libre-2.6.34-gnu1/drivers/usb/serial/oti6858.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/oti6858.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/oti6858.c	2010-05-16 17:17:36.000000000 -0400
@@ -58,7 +58,7 @@
 #define OTI6858_AUTHOR "Tomasz Michal Lukaszewski <FIXME@FIXME>"
 #define OTI6858_VERSION "0.1"
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(OTI6858_VENDOR_ID, OTI6858_PRODUCT_ID) },
 	{ }
 };
@@ -302,7 +302,7 @@ void send_data(struct work_struct *work)
 	struct usb_serial_port *port = priv->port;
 	int count = 0, result;
 	unsigned long flags;
-	unsigned char allow;
+	u8 *allow;
 
 	dbg("%s(port = %d)", __func__, port->number);
 
@@ -321,13 +321,20 @@ void send_data(struct work_struct *work)
 		count = port->bulk_out_size;
 
 	if (count != 0) {
+		allow = kmalloc(1, GFP_KERNEL);
+		if (!allow) {
+			dev_err(&port->dev, "%s(): kmalloc failed\n",
+					__func__);
+			return;
+		}
 		result = usb_control_msg(port->serial->dev,
 				usb_rcvctrlpipe(port->serial->dev, 0),
 				OTI6858_REQ_T_CHECK_TXBUFF,
 				OTI6858_REQ_CHECK_TXBUFF,
-				count, 0, &allow, 1, 100);
-		if (result != 1 || allow != 0)
+				count, 0, allow, 1, 100);
+		if (result != 1 || *allow != 0)
 			count = 0;
+		kfree(allow);
 	}
 
 	if (count == 0) {
@@ -578,9 +585,6 @@ static int oti6858_open(struct tty_struc
 	usb_clear_halt(serial->dev, port->write_urb->pipe);
 	usb_clear_halt(serial->dev, port->read_urb->pipe);
 
-	if (port->port.count != 1)
-		return 0;
-
 	buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL);
 	if (buf == NULL) {
 		dev_err(&port->dev, "%s(): out of memory!\n", __func__);
@@ -927,10 +931,6 @@ static void oti6858_read_bulk_callback(s
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	if (status != 0) {
-		if (!port->port.count) {
-			dbg("%s(): port is closed, exiting", __func__);
-			return;
-		}
 		/*
 		if (status == -EPROTO) {
 			* PL2303 mysteriously fails with -EPROTO reschedule
@@ -954,14 +954,12 @@ static void oti6858_read_bulk_callback(s
 	}
 	tty_kref_put(tty);
 
-	/* schedule the interrupt urb if we are still open */
-	if (port->port.count != 0) {
-		port->interrupt_in_urb->dev = port->serial->dev;
-		result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
-		if (result != 0) {
-			dev_err(&port->dev, "%s(): usb_submit_urb() failed,"
-					" error %d\n", __func__, result);
-		}
+	/* schedule the interrupt urb */
+	port->interrupt_in_urb->dev = port->serial->dev;
+	result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
+	if (result != 0 && result != -EPERM) {
+		dev_err(&port->dev, "%s(): usb_submit_urb() failed,"
+				" error %d\n", __func__, result);
 	}
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/pl2303.c linux-libre-2.6.34-gnu1/drivers/usb/serial/pl2303.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/pl2303.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/pl2303.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,7 +50,7 @@ struct pl2303_buf {
 	char		*buf_put;
 };
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) },
 	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },
 	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_DCU11) },
@@ -59,6 +59,7 @@ static struct usb_device_id id_table []
 	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) },
 	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) },
 	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) },
+	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) },
 	{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
 	{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
 	{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
@@ -97,6 +98,7 @@ static struct usb_device_id id_table []
 	{ USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
 	{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
+	{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
 
@@ -451,7 +453,6 @@ static void pl2303_send(struct usb_seria
 			      port->write_urb->transfer_buffer);
 
 	port->write_urb->transfer_buffer_length = count;
-	port->write_urb->dev = port->serial->dev;
 	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
 	if (result) {
 		dev_err(&port->dev, "%s - failed submitting write urb,"
@@ -769,7 +770,6 @@ static int pl2303_open(struct tty_struct
 		pl2303_set_termios(tty, port, &tmp_termios);
 
 	dbg("%s - submitting read urb", __func__);
-	port->read_urb->dev = serial->dev;
 	result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 	if (result) {
 		dev_err(&port->dev, "%s - failed submitting read urb,"
@@ -779,7 +779,6 @@ static int pl2303_open(struct tty_struct
 	}
 
 	dbg("%s - submitting interrupt urb", __func__);
-	port->interrupt_in_urb->dev = serial->dev;
 	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 	if (result) {
 		dev_err(&port->dev, "%s - failed submitting interrupt urb,"
@@ -895,10 +894,23 @@ static int wait_modem_info(struct usb_se
 static int pl2303_ioctl(struct tty_struct *tty, struct file *file,
 			unsigned int cmd, unsigned long arg)
 {
+	struct serial_struct ser;
 	struct usb_serial_port *port = tty->driver_data;
 	dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd);
 
 	switch (cmd) {
+	case TIOCGSERIAL:
+		memset(&ser, 0, sizeof ser);
+		ser.type = PORT_16654;
+		ser.line = port->serial->minor;
+		ser.port = port->number;
+		ser.baud_base = 460800;
+
+		if (copy_to_user((void __user *)arg, &ser, sizeof ser))
+			return -EFAULT;
+
+		return 0;
+
 	case TIOCMIWAIT:
 		dbg("%s (%d) TIOCMIWAIT", __func__,  port->number);
 		return wait_modem_info(port, arg);
@@ -1042,7 +1054,6 @@ static void pl2303_push_data(struct tty_
 		tty_flag = TTY_FRAME;
 	dbg("%s - tty_flag = %d", __func__, tty_flag);
 
-	tty_buffer_request_room(tty, urb->actual_length + 1);
 	/* overrun is special, not associated with a char */
 	if (line_status & UART_OVERRUN_ERROR)
 		tty_insert_flip_char(tty, 0, TTY_OVERRUN);
@@ -1072,16 +1083,11 @@ static void pl2303_read_bulk_callback(st
 
 	if (status) {
 		dbg("%s - urb status = %d", __func__, status);
-		if (!port->port.count) {
-			dbg("%s - port is closed, exiting.", __func__);
-			return;
-		}
 		if (status == -EPROTO) {
 			/* PL2303 mysteriously fails with -EPROTO reschedule
 			 * the read */
 			dbg("%s - caught -EPROTO, resubmitting the urb",
 			    __func__);
-			urb->dev = port->serial->dev;
 			result = usb_submit_urb(urb, GFP_ATOMIC);
 			if (result)
 				dev_err(&urb->dev->dev, "%s - failed"
@@ -1108,15 +1114,10 @@ static void pl2303_read_bulk_callback(st
 	}
 	tty_kref_put(tty);
 	/* Schedule the next read _if_ we are still open */
-	if (port->port.count) {
-		urb->dev = port->serial->dev;
-		result = usb_submit_urb(urb, GFP_ATOMIC);
-		if (result)
-			dev_err(&urb->dev->dev, "%s - failed resubmitting"
-				" read urb, error %d\n", __func__, result);
-	}
-
-	return;
+	result = usb_submit_urb(urb, GFP_ATOMIC);
+	if (result && result != -EPERM)
+		dev_err(&urb->dev->dev, "%s - failed resubmitting"
+			" read urb, error %d\n", __func__, result);
 }
 
 static void pl2303_write_bulk_callback(struct urb *urb)
@@ -1146,7 +1147,6 @@ static void pl2303_write_bulk_callback(s
 		dbg("%s - nonzero write bulk status received: %d", __func__,
 		    status);
 		port->write_urb->transfer_buffer_length = 1;
-		port->write_urb->dev = port->serial->dev;
 		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
 		if (result)
 			dev_err(&urb->dev->dev, "%s - failed resubmitting write"
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/pl2303.h linux-libre-2.6.34-gnu1/drivers/usb/serial/pl2303.h
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/pl2303.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/pl2303.h	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #define PL2303_PRODUCT_ID_ALDIGA	0x0611
 #define PL2303_PRODUCT_ID_MMX		0x0612
 #define PL2303_PRODUCT_ID_GPRS		0x0609
+#define PL2303_PRODUCT_ID_HCR331	0x331a
 
 #define ATEN_VENDOR_ID		0x0557
 #define ATEN_VENDOR_ID2		0x0547
@@ -134,3 +135,7 @@
 /* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */
 #define SANWA_VENDOR_ID		0x11ad
 #define SANWA_PRODUCT_ID	0x0001
+
+/* ADLINK ND-6530 RS232,RS485 and RS422 adapter */
+#define ADLINK_VENDOR_ID        0x0b63
+#define ADLINK_ND6530_PRODUCT_ID       0x6530
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/qcaux.c linux-libre-2.6.34-gnu1/drivers/usb/serial/qcaux.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/qcaux.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/qcaux.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,106 @@
+/*
+ * Qualcomm USB Auxiliary Serial Port driver
+ *
+ * Copyright (C) 2008 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2010 Dan Williams <dcbw@redhat.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.
+ *
+ * Devices listed here usually provide a CDC ACM port on which normal modem
+ * AT commands and PPP can be used.  But when that port is in-use by PPP it
+ * cannot be used simultaneously for status or signal strength.  Instead, the
+ * ports here can be queried for that information using the Qualcomm DM
+ * protocol.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+/* NOTE: for now, only use this driver for devices that provide a CDC-ACM port
+ * for normal AT commands, but also provide secondary USB interfaces for the
+ * QCDM-capable ports.  Devices that do not provide a CDC-ACM port should
+ * probably be driven by option.ko.
+ */
+
+/* UTStarcom/Pantech/Curitel devices */
+#define UTSTARCOM_VENDOR_ID			0x106c
+#define UTSTARCOM_PRODUCT_PC5740		0x3701
+#define UTSTARCOM_PRODUCT_PC5750		0x3702 /* aka Pantech PX-500 */
+#define UTSTARCOM_PRODUCT_UM150			0x3711
+#define UTSTARCOM_PRODUCT_UM175_V1		0x3712
+#define UTSTARCOM_PRODUCT_UM175_V2		0x3714
+#define UTSTARCOM_PRODUCT_UM175_ALLTEL		0x3715
+
+/* CMOTECH devices */
+#define CMOTECH_VENDOR_ID			0x16d8
+#define CMOTECH_PRODUCT_CDU550			0x5553
+#define CMOTECH_PRODUCT_CDX650			0x6512
+
+/* LG devices */
+#define LG_VENDOR_ID				0x1004
+#define LG_PRODUCT_VX4400_6000			0x6000 /* VX4400/VX6000/Rumor */
+
+/* Sanyo devices */
+#define SANYO_VENDOR_ID				0x0474
+#define SANYO_PRODUCT_KATANA_LX			0x0754 /* SCP-3800 (Katana LX) */
+
+static struct usb_device_id id_table[] = {
+	{ USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5740, 0xff, 0x00, 0x00) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5750, 0xff, 0x00, 0x00) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM150, 0xff, 0x00, 0x00) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_V1, 0xff, 0x00, 0x00) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_V2, 0xff, 0x00, 0x00) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_ALLTEL, 0xff, 0x00, 0x00) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU550, 0xff, 0xff, 0x00) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDX650, 0xff, 0xff, 0x00) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) },
+	{ },
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver qcaux_driver = {
+	.name =		"qcaux",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table,
+	.no_dynamic_id = 	1,
+};
+
+static struct usb_serial_driver qcaux_device = {
+	.driver = {
+		.owner =	THIS_MODULE,
+		.name =		"qcaux",
+	},
+	.id_table =		id_table,
+	.num_ports =		1,
+};
+
+static int __init qcaux_init(void)
+{
+	int retval;
+
+	retval = usb_serial_register(&qcaux_device);
+	if (retval)
+		return retval;
+	retval = usb_register(&qcaux_driver);
+	if (retval)
+		usb_serial_deregister(&qcaux_device);
+	return retval;
+}
+
+static void __exit qcaux_exit(void)
+{
+	usb_deregister(&qcaux_driver);
+	usb_serial_deregister(&qcaux_device);
+}
+
+module_init(qcaux_init);
+module_exit(qcaux_exit);
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/qcserial.c linux-libre-2.6.34-gnu1/drivers/usb/serial/qcserial.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/qcserial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/qcserial.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,7 @@
 
 static int debug;
 
-static struct usb_device_id id_table[] = {
+static const struct usb_device_id id_table[] = {
 	{USB_DEVICE(0x05c6, 0x9211)},	/* Acer Gobi QDL device */
 	{USB_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */
 	{USB_DEVICE(0x03f0, 0x1f1d)},	/* HP un2400 Gobi Modem Device */
@@ -47,6 +47,35 @@ static struct usb_device_id id_table[] =
 	{USB_DEVICE(0x05c6, 0x9221)},	/* Generic Gobi QDL device */
 	{USB_DEVICE(0x05c6, 0x9231)},	/* Generic Gobi QDL device */
 	{USB_DEVICE(0x1f45, 0x0001)},	/* Unknown Gobi QDL device */
+	{USB_DEVICE(0x413c, 0x8185)},	/* Dell Gobi 2000 QDL device (N0218, VU936) */
+	{USB_DEVICE(0x413c, 0x8186)},	/* Dell Gobi 2000 Modem device (N0218, VU936) */
+	{USB_DEVICE(0x05c6, 0x9224)},	/* Sony Gobi 2000 QDL device (N0279, VU730) */
+	{USB_DEVICE(0x05c6, 0x9225)},	/* Sony Gobi 2000 Modem device (N0279, VU730) */
+	{USB_DEVICE(0x05c6, 0x9244)},	/* Samsung Gobi 2000 QDL device (VL176) */
+	{USB_DEVICE(0x05c6, 0x9245)},	/* Samsung Gobi 2000 Modem device (VL176) */
+	{USB_DEVICE(0x03f0, 0x241d)},	/* HP Gobi 2000 QDL device (VP412) */
+	{USB_DEVICE(0x03f0, 0x251d)},	/* HP Gobi 2000 Modem device (VP412) */
+	{USB_DEVICE(0x05c6, 0x9214)},	/* Acer Gobi 2000 QDL device (VP413) */
+	{USB_DEVICE(0x05c6, 0x9215)},	/* Acer Gobi 2000 Modem device (VP413) */
+	{USB_DEVICE(0x05c6, 0x9264)},	/* Asus Gobi 2000 QDL device (VR305) */
+	{USB_DEVICE(0x05c6, 0x9265)},	/* Asus Gobi 2000 Modem device (VR305) */
+	{USB_DEVICE(0x05c6, 0x9234)},	/* Top Global Gobi 2000 QDL device (VR306) */
+	{USB_DEVICE(0x05c6, 0x9235)},	/* Top Global Gobi 2000 Modem device (VR306) */
+	{USB_DEVICE(0x05c6, 0x9274)},	/* iRex Technologies Gobi 2000 QDL device (VR307) */
+	{USB_DEVICE(0x05c6, 0x9275)},	/* iRex Technologies Gobi 2000 Modem device (VR307) */
+	{USB_DEVICE(0x1199, 0x9000)},	/* Sierra Wireless Gobi 2000 QDL device (VT773) */
+	{USB_DEVICE(0x1199, 0x9001)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
+	{USB_DEVICE(0x1199, 0x9002)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
+	{USB_DEVICE(0x1199, 0x9003)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
+	{USB_DEVICE(0x1199, 0x9004)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
+	{USB_DEVICE(0x1199, 0x9005)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
+	{USB_DEVICE(0x1199, 0x9006)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
+	{USB_DEVICE(0x1199, 0x9007)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
+	{USB_DEVICE(0x1199, 0x9008)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
+	{USB_DEVICE(0x1199, 0x9009)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
+	{USB_DEVICE(0x1199, 0x900a)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
+	{USB_DEVICE(0x16d8, 0x8001)},	/* CMDTech Gobi 2000 QDL device (VU922) */
+	{USB_DEVICE(0x16d8, 0x8002)},	/* CMDTech Gobi 2000 Modem device (VU922) */
 	{ }				/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, id_table);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/safe_serial.c linux-libre-2.6.34-gnu1/drivers/usb/serial/safe_serial.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/safe_serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/safe_serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,8 +64,8 @@
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/siemens_mpi.c linux-libre-2.6.34-gnu1/drivers/usb/serial/siemens_mpi.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/siemens_mpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/siemens_mpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,7 +22,7 @@
 #define DRIVER_DESC "Driver for Siemens USB/MPI adapter"
 
 
-static struct usb_device_id id_table[] = {
+static const struct usb_device_id id_table[] = {
 	/* Vendor and product id for 6ES7-972-0CB20-0XA0 */
 	{ USB_DEVICE(0x908, 0x0004) },
 	{ },
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/sierra.c linux-libre-2.6.34-gnu1/drivers/usb/serial/sierra.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/sierra.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/sierra.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/jiffies.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
+#include <linux/slab.h>
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/usb.h>
@@ -226,9 +227,10 @@ static const struct sierra_iface_info di
 	.ifaceinfo = direct_ip_non_serial_ifaces,
 };
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
 	{ USB_DEVICE(0x03F0, 0x1B1D) },	/* HP ev2200 a.k.a MC5720 */
+	{ USB_DEVICE(0x03F0, 0x211D) }, /* HP ev2210 a.k.a MC5725 */
 	{ USB_DEVICE(0x03F0, 0x1E1D) },	/* HP hs2300 a.k.a MC8775 */
 
 	{ USB_DEVICE(0x1199, 0x0017) },	/* Sierra Wireless EM5625 */
@@ -304,16 +306,6 @@ static struct usb_device_id id_table []
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver sierra_driver = {
-	.name       = "sierra",
-	.probe      = usb_serial_probe,
-	.disconnect = usb_serial_disconnect,
-	.suspend    = usb_serial_suspend,
-	.resume     = usb_serial_resume,
-	.id_table   = id_table,
-	.no_dynamic_id = 	1,
-	.supports_autosuspend =	1,
-};
 
 struct sierra_port_private {
 	spinlock_t lock;	/* lock the structure */
@@ -477,7 +469,7 @@ static void sierra_outdat_callback(struc
 static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port,
 					const unsigned char *buf, int count)
 {
-	struct sierra_port_private *portdata = usb_get_serial_port_data(port);
+	struct sierra_port_private *portdata;
 	struct sierra_intf_private *intfdata;
 	struct usb_serial *serial = port->serial;
 	unsigned long flags;
@@ -604,14 +596,15 @@ static void sierra_indat_callback(struct
 	} else {
 		if (urb->actual_length) {
 			tty = tty_port_tty_get(&port->port);
+			if (tty) {
+				tty_insert_flip_string(tty, data,
+					urb->actual_length);
+				tty_flip_buffer_push(tty);
 
-			tty_buffer_request_room(tty, urb->actual_length);
-			tty_insert_flip_string(tty, data, urb->actual_length);
-			tty_flip_buffer_push(tty);
-
-			tty_kref_put(tty);
-			usb_serial_debug_data(debug, &port->dev, __func__,
-				urb->actual_length, data);
+				tty_kref_put(tty);
+				usb_serial_debug_data(debug, &port->dev,
+					__func__, urb->actual_length, data);
+			}
 		} else {
 			dev_dbg(&port->dev, "%s: empty read urb"
 				" received\n", __func__);
@@ -619,10 +612,10 @@ static void sierra_indat_callback(struct
 	}
 
 	/* Resubmit urb so we continue receiving */
-	if (port->port.count && status != -ESHUTDOWN && status != -EPERM) {
+	if (status != -ESHUTDOWN && status != -EPERM) {
 		usb_mark_last_busy(port->serial->dev);
 		err = usb_submit_urb(urb, GFP_ATOMIC);
-		if (err)
+		if (err && err != -EPERM)
 			dev_err(&port->dev, "resubmit read urb failed."
 				"(%d)\n", err);
 	}
@@ -681,11 +674,11 @@ static void sierra_instat_callback(struc
 		dev_dbg(&port->dev, "%s: error %d\n", __func__, status);
 
 	/* Resubmit urb so we continue receiving IRQ data */
-	if (port->port.count && status != -ESHUTDOWN && status != -ENOENT) {
+	if (status != -ESHUTDOWN && status != -ENOENT) {
 		usb_mark_last_busy(serial->dev);
 		urb->dev = serial->dev;
 		err = usb_submit_urb(urb, GFP_ATOMIC);
-		if (err)
+		if (err && err != -EPERM)
 			dev_err(&port->dev, "%s: resubmit intr urb "
 				"failed. (%d)\n", __func__, err);
 	}
@@ -1061,11 +1054,31 @@ static int sierra_resume(struct usb_seri
 
 	return ec ? -EIO : 0;
 }
+
+static int sierra_reset_resume(struct usb_interface *intf)
+{
+	struct usb_serial *serial = usb_get_intfdata(intf);
+	dev_err(&serial->dev->dev, "%s\n", __func__);
+	return usb_serial_resume(intf);
+}
 #else
 #define sierra_suspend NULL
 #define sierra_resume NULL
+#define sierra_reset_resume NULL
 #endif
 
+static struct usb_driver sierra_driver = {
+	.name       = "sierra",
+	.probe      = usb_serial_probe,
+	.disconnect = usb_serial_disconnect,
+	.suspend    = usb_serial_suspend,
+	.resume     = usb_serial_resume,
+	.reset_resume = sierra_reset_resume,
+	.id_table   = id_table,
+	.no_dynamic_id = 	1,
+	.supports_autosuspend =	1,
+};
+
 static struct usb_serial_driver sierra_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/spcp8x5.c linux-libre-2.6.34-gnu1/drivers/usb/serial/spcp8x5.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/spcp8x5.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/spcp8x5.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,7 +45,7 @@ static int debug;
 #define SPCP8x5_835_VID		0x04fc
 #define SPCP8x5_835_PID		0x0231
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(SPCP8x5_PHILIPS_VID , SPCP8x5_PHILIPS_PID)},
 	{ USB_DEVICE(SPCP8x5_INTERMATIC_VID, SPCP8x5_INTERMATIC_PID)},
 	{ USB_DEVICE(SPCP8x5_835_VID, SPCP8x5_835_PID)},
@@ -609,7 +609,7 @@ static void spcp8x5_set_termios(struct t
 	if (i < 0)
 		dev_err(&port->dev, "Set UART format %#x failed (error = %d)\n",
 			uartdata, i);
-	dbg("0x21:0x40:0:0  %d\n", i);
+	dbg("0x21:0x40:0:0  %d", i);
 
 	if (cflag & CRTSCTS) {
 		/* enable hardware flow control */
@@ -677,7 +677,6 @@ static void spcp8x5_read_bulk_callback(s
 	struct tty_struct *tty;
 	unsigned char *data = urb->transfer_buffer;
 	unsigned long flags;
-	int i;
 	int result = urb->status;
 	u8 status;
 	char tty_flag;
@@ -687,8 +686,6 @@ static void spcp8x5_read_bulk_callback(s
 
 	/* check the urb status */
 	if (result) {
-		if (!port->port.count)
-			return;
 		if (result == -EPROTO) {
 			/* spcp8x5 mysteriously fails with -EPROTO */
 			/* reschedule the read */
@@ -726,26 +723,20 @@ static void spcp8x5_read_bulk_callback(s
 
 	tty = tty_port_tty_get(&port->port);
 	if (tty && urb->actual_length) {
-		tty_buffer_request_room(tty, urb->actual_length + 1);
 		/* overrun is special, not associated with a char */
 		if (status & UART_OVERRUN_ERROR)
 			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-		for (i = 0; i < urb->actual_length; ++i)
-			tty_insert_flip_char(tty, data[i], tty_flag);
+		tty_insert_flip_string_fixed_flag(tty, data,
+						urb->actual_length, tty_flag);
 		tty_flip_buffer_push(tty);
 	}
 	tty_kref_put(tty);
 
-	/* Schedule the next read _if_ we are still open */
-	if (port->port.count) {
-		urb->dev = port->serial->dev;
-		result = usb_submit_urb(urb , GFP_ATOMIC);
-		if (result)
-			dev_dbg(&port->dev, "failed submitting read urb %d\n",
-				result);
-	}
-
-	return;
+	/* Schedule the next read */
+	urb->dev = port->serial->dev;
+	result = usb_submit_urb(urb , GFP_ATOMIC);
+	if (result)
+		dev_dbg(&port->dev, "failed submitting read urb %d\n", result);
 }
 
 /* get data from ring buffer and then write to usb bus */
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/symbolserial.c linux-libre-2.6.34-gnu1/drivers/usb/serial/symbolserial.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/symbolserial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/symbolserial.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/tty.h>
+#include <linux/slab.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
 #include <linux/module.h>
@@ -21,7 +22,7 @@
 
 static int debug;
 
-static struct usb_device_id id_table[] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x05e0, 0x0600) },
 	{ },
 };
@@ -51,7 +52,6 @@ static void symbol_int_callback(struct u
 	int status = urb->status;
 	struct tty_struct *tty;
 	int result;
-	int available_room = 0;
 	int data_length;
 
 	dbg("%s - port %d", __func__, port->number);
@@ -89,18 +89,13 @@ static void symbol_int_callback(struct u
 		 */
 		tty = tty_port_tty_get(&port->port);
 		if (tty) {
-			available_room = tty_buffer_request_room(tty,
-							data_length);
-			if (available_room) {
-				tty_insert_flip_string(tty, &data[1],
-						       available_room);
-				tty_flip_buffer_push(tty);
-			}
+			tty_insert_flip_string(tty, &data[1], data_length);
+			tty_flip_buffer_push(tty);
 			tty_kref_put(tty);
 		}
 	} else {
 		dev_dbg(&priv->udev->dev,
-			"Improper ammount of data received from the device, "
+			"Improper amount of data received from the device, "
 			"%d bytes", urb->actual_length);
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/ti_usb_3410_5052.c linux-libre-2.6.34-gnu1/drivers/usb/serial/ti_usb_3410_5052.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/ti_usb_3410_5052.c	2013-05-03 12:13:23.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/ti_usb_3410_5052.c	2013-05-03 09:52:55.000000000 -0400
@@ -172,7 +172,7 @@ static unsigned int product_5052_count;
 /* the array dimension is the number of default entries plus */
 /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
 /* null entry */
-static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[13+TI_EXTRA_VID_PID_COUNT+1] = {
 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
 	{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -180,6 +180,9 @@ static struct usb_device_id ti_id_table_
 	{ USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
 	{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
 	{ USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
+	{ USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) },
+	{ USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) },
+	{ USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) },
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
@@ -192,7 +195,7 @@ static struct usb_device_id ti_id_table_
 	{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
 };
 
-static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_combined[17+2*TI_EXTRA_VID_PID_COUNT+1] = {
 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
 	{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -200,6 +203,9 @@ static struct usb_device_id ti_id_table_
 	{ USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
 	{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
 	{ USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
+	{ USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) },
+	{ USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) },
+	{ USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
@@ -1267,14 +1273,13 @@ static void ti_recv(struct device *dev,
 	int cnt;
 
 	do {
-		cnt = tty_buffer_request_room(tty, length);
+		cnt = tty_insert_flip_string(tty, data, length);
 		if (cnt < length) {
 			dev_err(dev, "%s - dropping data, %d bytes lost\n",
 						__func__, length - cnt);
 			if (cnt == 0)
 				break;
 		}
-		tty_insert_flip_string(tty, data, cnt);
 		tty_flip_buffer_push(tty);
 		data += cnt;
 		length -= cnt;
@@ -1684,6 +1689,7 @@ static int ti_download_firmware(struct t
 	const struct firmware *fw_p;
 	char buf[32];
 
+	dbg("%s\n", __func__);
 	/* try ID specific firmware first, then try generic firmware */
 	sprintf(buf, "/*(DEBLOBBED)*/", dev->descriptor.idVendor,
 	    dev->descriptor.idProduct);
@@ -1700,7 +1706,15 @@ static int ti_download_firmware(struct t
 			case MTS_EDGE_PRODUCT_ID:
 				strcpy(buf, "/*(DEBLOBBED)*/");
 				break;
-			}
+			case MTS_MT9234MU_PRODUCT_ID:
+				strcpy(buf, "/*(DEBLOBBED)*/");
+				break;
+			case MTS_MT9234ZBA_PRODUCT_ID:
+				strcpy(buf, "/*(DEBLOBBED)*/");
+				break;
+			case MTS_MT9234ZBAOLD_PRODUCT_ID:
+				strcpy(buf, "/*(DEBLOBBED)*/");
+				break;			}
 		}
 		if (buf[0] == '\0') {
 			if (tdev->td_is_3410)
@@ -1715,7 +1729,7 @@ static int ti_download_firmware(struct t
 		return -ENOENT;
 	}
 	if (fw_p->size > TI_FIRMWARE_BUF_SIZE) {
-		dev_err(&dev->dev, "%s - firmware too large\n", __func__);
+		dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size);
 		return -ENOENT;
 	}
 
@@ -1727,6 +1741,7 @@ static int ti_download_firmware(struct t
 		status = ti_do_download(dev, pipe, buffer, fw_p->size);
 		kfree(buffer);
 	} else {
+		dbg("%s ENOMEM\n", __func__);
 		status = -ENOMEM;
 	}
 	release_firmware(fw_p);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/ti_usb_3410_5052.h linux-libre-2.6.34-gnu1/drivers/usb/serial/ti_usb_3410_5052.h
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/ti_usb_3410_5052.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/ti_usb_3410_5052.h	2010-05-16 17:17:36.000000000 -0400
@@ -45,6 +45,9 @@
 #define MTS_CDMA_PRODUCT_ID		0xF110
 #define MTS_GSM_PRODUCT_ID		0xF111
 #define MTS_EDGE_PRODUCT_ID		0xF112
+#define MTS_MT9234MU_PRODUCT_ID		0xF114
+#define MTS_MT9234ZBA_PRODUCT_ID	0xF115
+#define MTS_MT9234ZBAOLD_PRODUCT_ID	0x0319
 
 /* Commands */
 #define TI_GET_VERSION			0x01
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/usb_debug.c linux-libre-2.6.34-gnu1/drivers/usb/serial/usb_debug.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/usb_debug.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/usb_debug.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,6 +8,7 @@
  *	2 as published by the Free Software Foundation.
  */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/tty.h>
@@ -29,7 +30,7 @@ static char USB_DEBUG_BRK[USB_DEBUG_BRK_
 	0xff,
 };
 
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x0525, 0x127a) },
 	{ },
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/usb-serial.c linux-libre-2.6.34-gnu1/drivers/usb/serial/usb-serial.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/usb-serial.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/usb-serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -358,10 +358,6 @@ static int serial_write(struct tty_struc
 
 	dbg("%s - port %d, %d byte(s)", __func__, port->number, count);
 
-	/* count is managed under the mutex lock for the tty so cannot
-	   drop to zero until after the last close completes */
-	WARN_ON(!port->port.count);
-
 	/* pass on to the driver specific version of this function */
 	retval = port->serial->type->write(tty, port, buf, count);
 
@@ -373,7 +369,6 @@ static int serial_write_room(struct tty_
 {
 	struct usb_serial_port *port = tty->driver_data;
 	dbg("%s - port %d", __func__, port->number);
-	WARN_ON(!port->port.count);
 	/* pass on to the driver specific version of this function */
 	return port->serial->type->write_room(tty);
 }
@@ -381,7 +376,7 @@ static int serial_write_room(struct tty_
 static int serial_chars_in_buffer(struct tty_struct *tty)
 {
 	struct usb_serial_port *port = tty->driver_data;
-	dbg("%s = port %d", __func__, port->number);
+	dbg("%s - port %d", __func__, port->number);
 
 	/* if the device was unplugged then any remaining characters
 	   fell out of the connector ;) */
@@ -396,7 +391,6 @@ static void serial_throttle(struct tty_s
 	struct usb_serial_port *port = tty->driver_data;
 	dbg("%s - port %d", __func__, port->number);
 
-	WARN_ON(!port->port.count);
 	/* pass on to the driver specific version of this function */
 	if (port->serial->type->throttle)
 		port->serial->type->throttle(tty);
@@ -407,7 +401,6 @@ static void serial_unthrottle(struct tty
 	struct usb_serial_port *port = tty->driver_data;
 	dbg("%s - port %d", __func__, port->number);
 
-	WARN_ON(!port->port.count);
 	/* pass on to the driver specific version of this function */
 	if (port->serial->type->unthrottle)
 		port->serial->type->unthrottle(tty);
@@ -421,8 +414,6 @@ static int serial_ioctl(struct tty_struc
 
 	dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
 
-	WARN_ON(!port->port.count);
-
 	/* pass on to the driver specific version of this function
 	   if it is available */
 	if (port->serial->type->ioctl) {
@@ -437,7 +428,6 @@ static void serial_set_termios(struct tt
 	struct usb_serial_port *port = tty->driver_data;
 	dbg("%s - port %d", __func__, port->number);
 
-	WARN_ON(!port->port.count);
 	/* pass on to the driver specific version of this function
 	   if it is available */
 	if (port->serial->type->set_termios)
@@ -452,7 +442,6 @@ static int serial_break(struct tty_struc
 
 	dbg("%s - port %d", __func__, port->number);
 
-	WARN_ON(!port->port.count);
 	/* pass on to the driver specific version of this function
 	   if it is available */
 	if (port->serial->type->break_ctl)
@@ -513,7 +502,6 @@ static int serial_tiocmget(struct tty_st
 
 	dbg("%s - port %d", __func__, port->number);
 
-	WARN_ON(!port->port.count);
 	if (port->serial->type->tiocmget)
 		return port->serial->type->tiocmget(tty, file);
 	return -EINVAL;
@@ -526,7 +514,6 @@ static int serial_tiocmset(struct tty_st
 
 	dbg("%s - port %d", __func__, port->number);
 
-	WARN_ON(!port->port.count);
 	if (port->serial->type->tiocmset)
 		return port->serial->type->tiocmset(tty, file, set, clear);
 	return -EINVAL;
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/visor.c linux-libre-2.6.34-gnu1/drivers/usb/serial/visor.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/visor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/visor.c	2010-05-16 17:17:36.000000000 -0400
@@ -368,7 +368,7 @@ static int visor_write(struct tty_struct
 	spin_lock_irqsave(&priv->lock, flags);
 	if (priv->outstanding_urbs > URB_UPPER_LIMIT) {
 		spin_unlock_irqrestore(&priv->lock, flags);
-		dbg("%s - write limit hit\n", __func__);
+		dbg("%s - write limit hit", __func__);
 		return 0;
 	}
 	priv->outstanding_urbs++;
@@ -446,7 +446,7 @@ static int visor_write_room(struct tty_s
 	spin_lock_irqsave(&priv->lock, flags);
 	if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) {
 		spin_unlock_irqrestore(&priv->lock, flags);
-		dbg("%s - write limit hit\n", __func__);
+		dbg("%s - write limit hit", __func__);
 		return 0;
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
@@ -503,13 +503,9 @@ static void visor_read_bulk_callback(str
 	if (urb->actual_length) {
 		tty = tty_port_tty_get(&port->port);
 		if (tty) {
-			available_room = tty_buffer_request_room(tty,
-							urb->actual_length);
-			if (available_room) {
-				tty_insert_flip_string(tty, data,
-							available_room);
-				tty_flip_buffer_push(tty);
-			}
+			tty_insert_flip_string(tty, data,
+						urb->actual_length);
+			tty_flip_buffer_push(tty);
 			tty_kref_put(tty);
 		}
 		spin_lock(&priv->lock);
@@ -807,10 +803,14 @@ static int clie_3_5_startup(struct usb_s
 {
 	struct device *dev = &serial->dev->dev;
 	int result;
-	u8 data;
+	u8 *data;
 
 	dbg("%s", __func__);
 
+	data = kmalloc(1, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
 	/*
 	 * Note that PEG-300 series devices expect the following two calls.
 	 */
@@ -818,36 +818,42 @@ static int clie_3_5_startup(struct usb_s
 	/* get the config number */
 	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
 				  USB_REQ_GET_CONFIGURATION, USB_DIR_IN,
-				  0, 0, &data, 1, 3000);
+				  0, 0, data, 1, 3000);
 	if (result < 0) {
 		dev_err(dev, "%s: get config number failed: %d\n",
 							__func__, result);
-		return result;
+		goto out;
 	}
 	if (result != 1) {
 		dev_err(dev, "%s: get config number bad return length: %d\n",
 							__func__, result);
-		return -EIO;
+		result = -EIO;
+		goto out;
 	}
 
 	/* get the interface number */
 	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
 				  USB_REQ_GET_INTERFACE,
 				  USB_DIR_IN | USB_RECIP_INTERFACE,
-				  0, 0, &data, 1, 3000);
+				  0, 0, data, 1, 3000);
 	if (result < 0) {
 		dev_err(dev, "%s: get interface number failed: %d\n",
 							__func__, result);
-		return result;
+		goto out;
 	}
 	if (result != 1) {
 		dev_err(dev,
 			"%s: get interface number bad return length: %d\n",
 							__func__, result);
-		return -EIO;
+		result = -EIO;
+		goto out;
 	}
 
-	return generic_startup(serial);
+	result = generic_startup(serial);
+out:
+	kfree(data);
+
+	return result;
 }
 
 static int treo_attach(struct usb_serial *serial)
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/vivopay-serial.c linux-libre-2.6.34-gnu1/drivers/usb/serial/vivopay-serial.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/vivopay-serial.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/vivopay-serial.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2001-2005 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 2009 Outpost Embedded, LLC
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+
+#define DRIVER_VERSION "v1.0"
+#define DRIVER_DESC "ViVOpay USB Serial Driver"
+
+#define VIVOPAY_VENDOR_ID 0x1d5f
+
+
+static struct usb_device_id id_table [] = {
+	/* ViVOpay 8800 */
+	{ USB_DEVICE(VIVOPAY_VENDOR_ID, 0x1004) },
+	{ },
+};
+
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver vivopay_serial_driver = {
+	.name =			"vivopay-serial",
+	.probe =		usb_serial_probe,
+	.disconnect =		usb_serial_disconnect,
+	.id_table =		id_table,
+	.no_dynamic_id =	1,
+};
+
+static struct usb_serial_driver vivopay_serial_device = {
+	.driver = {
+		.owner =	THIS_MODULE,
+		.name =		"vivopay-serial",
+	},
+	.id_table =		id_table,
+	.usb_driver =		&vivopay_serial_driver,
+	.num_ports =		1,
+};
+
+static int __init vivopay_serial_init(void)
+{
+	int retval;
+	retval = usb_serial_register(&vivopay_serial_device);
+	if (retval)
+		goto failed_usb_serial_register;
+	retval = usb_register(&vivopay_serial_driver);
+	if (retval)
+		goto failed_usb_register;
+	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+	    DRIVER_DESC "\n");
+	return 0;
+failed_usb_register:
+	usb_serial_deregister(&vivopay_serial_device);
+failed_usb_serial_register:
+	return retval;
+}
+
+static void __exit vivopay_serial_exit(void)
+{
+	usb_deregister(&vivopay_serial_driver);
+	usb_serial_deregister(&vivopay_serial_device);
+}
+
+module_init(vivopay_serial_init);
+module_exit(vivopay_serial_exit);
+
+MODULE_AUTHOR("Forest Bond <forest.bond@outpostembedded.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/serial/whiteheat.c linux-libre-2.6.34-gnu1/drivers/usb/serial/whiteheat.c
--- linux-libre-2.6.33-gnu1/drivers/usb/serial/whiteheat.c	2013-05-03 12:13:31.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/usb/serial/whiteheat.c	2013-05-03 09:53:03.000000000 -0400
@@ -111,17 +111,17 @@ static int debug;
    separate ID tables, and then a third table that combines them
    just for the purpose of exporting the autoloading information.
 */
-static struct usb_device_id id_table_std [] = {
+static const struct usb_device_id id_table_std[] = {
 	{ USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_WHITE_HEAT_ID) },
 	{ }						/* Terminating entry */
 };
 
-static struct usb_device_id id_table_prerenumeration [] = {
+static const struct usb_device_id id_table_prerenumeration[] = {
 	{ USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_FAKE_WHITE_HEAT_ID) },
 	{ }						/* Terminating entry */
 };
 
-static struct usb_device_id id_table_combined [] = {
+static const struct usb_device_id id_table_combined[] = {
 	{ USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_WHITE_HEAT_ID) },
 	{ USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_FAKE_WHITE_HEAT_ID) },
 	{ }						/* Terminating entry */
@@ -1492,21 +1492,9 @@ static void rx_data_softint(struct work_
 		wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
 		urb = wrap->urb;
 
-		if (tty && urb->actual_length) {
-			int len = tty_buffer_request_room(tty,
-							urb->actual_length);
-			/* This stuff can go away now I suspect */
-			if (unlikely(len < urb->actual_length)) {
-				spin_lock_irqsave(&info->lock, flags);
-				list_add(tmp, &info->rx_urb_q);
-				spin_unlock_irqrestore(&info->lock, flags);
-				tty_flip_buffer_push(tty);
-				schedule_work(&info->rx_work);
-				goto out;
-			}
-			tty_insert_flip_string(tty, urb->transfer_buffer, len);
-			sent += len;
-		}
+		if (tty && urb->actual_length)
+			sent += tty_insert_flip_string(tty,
+				urb->transfer_buffer, urb->actual_length);
 
 		urb->dev = port->serial->dev;
 		result = usb_submit_urb(urb, GFP_ATOMIC);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/storage/alauda.c linux-libre-2.6.34-gnu1/drivers/usb/storage/alauda.c
--- linux-libre-2.6.33-gnu1/drivers/usb/storage/alauda.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/storage/alauda.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/storage/karma.c linux-libre-2.6.34-gnu1/drivers/usb/storage/karma.c
--- linux-libre-2.6.33-gnu1/drivers/usb/storage/karma.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/storage/karma.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/storage/onetouch.c linux-libre-2.6.34-gnu1/drivers/usb/storage/onetouch.c
--- linux-libre-2.6.33-gnu1/drivers/usb/storage/onetouch.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/storage/onetouch.c	2010-05-16 17:17:36.000000000 -0400
@@ -202,7 +202,7 @@ static int onetouch_connect_input(struct
 		goto fail1;
 
 	onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN,
-					  GFP_ATOMIC, &onetouch->data_dma);
+					  GFP_KERNEL, &onetouch->data_dma);
 	if (!onetouch->data)
 		goto fail1;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/storage/option_ms.c linux-libre-2.6.34-gnu1/drivers/usb/storage/option_ms.c
--- linux-libre-2.6.33-gnu1/drivers/usb/storage/option_ms.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/storage/option_ms.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
  */
 
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include "usb.h"
 #include "transport.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/storage/scsiglue.c linux-libre-2.6.34-gnu1/drivers/usb/storage/scsiglue.c
--- linux-libre-2.6.33-gnu1/drivers/usb/storage/scsiglue.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/storage/scsiglue.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,7 +43,6 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 
@@ -133,15 +132,15 @@ static int slave_configure(struct scsi_d
 
 		if (us->fflags & US_FL_MAX_SECTORS_MIN)
 			max_sectors = PAGE_CACHE_SIZE >> 9;
-		if (queue_max_sectors(sdev->request_queue) > max_sectors)
-			blk_queue_max_sectors(sdev->request_queue,
+		if (queue_max_hw_sectors(sdev->request_queue) > max_sectors)
+			blk_queue_max_hw_sectors(sdev->request_queue,
 					      max_sectors);
 	} else if (sdev->type == TYPE_TAPE) {
 		/* Tapes need much higher max_sector limits, so just
 		 * raise it to the maximum possible (4 GB / 512) and
 		 * let the queue segment size sort out the real limit.
 		 */
-		blk_queue_max_sectors(sdev->request_queue, 0x7FFFFF);
+		blk_queue_max_hw_sectors(sdev->request_queue, 0x7FFFFF);
 	}
 
 	/* Some USB host controllers can't do DMA; they have to use PIO.
@@ -484,7 +483,7 @@ static ssize_t show_max_sectors(struct d
 {
 	struct scsi_device *sdev = to_scsi_device(dev);
 
-	return sprintf(buf, "%u\n", queue_max_sectors(sdev->request_queue));
+	return sprintf(buf, "%u\n", queue_max_hw_sectors(sdev->request_queue));
 }
 
 /* Input routine for the sysfs max_sectors file */
@@ -494,9 +493,9 @@ static ssize_t store_max_sectors(struct
 	struct scsi_device *sdev = to_scsi_device(dev);
 	unsigned short ms;
 
-	if (sscanf(buf, "%hu", &ms) > 0 && ms <= SCSI_DEFAULT_MAX_SECTORS) {
-		blk_queue_max_sectors(sdev->request_queue, ms);
-		return strlen(buf);
+	if (sscanf(buf, "%hu", &ms) > 0) {
+		blk_queue_max_hw_sectors(sdev->request_queue, ms);
+		return count;
 	}
 	return -EINVAL;	
 }
@@ -539,7 +538,7 @@ struct scsi_host_template usb_stor_host_
 	.slave_configure =		slave_configure,
 
 	/* lots of sg segments can be handled */
-	.sg_tablesize =			SG_ALL,
+	.sg_tablesize =			SCSI_MAX_SG_CHAIN_SEGMENTS,
 
 	/* limit the total size of a transfer to 120 KB */
 	.max_sectors =                  240,
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/storage/shuttle_usbat.c linux-libre-2.6.34-gnu1/drivers/usb/storage/shuttle_usbat.c
--- linux-libre-2.6.33-gnu1/drivers/usb/storage/shuttle_usbat.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/storage/shuttle_usbat.c	2010-05-16 17:17:36.000000000 -0400
@@ -1628,10 +1628,10 @@ static int usbat_hp8200e_transport(struc
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
-	if ( (result = usbat_multiple_write(us, 
-			registers, data, 7)) != USB_STOR_TRANSPORT_GOOD) {
+	result = usbat_multiple_write(us, registers, data, 7);
+
+	if (result != USB_STOR_TRANSPORT_GOOD)
 		return result;
-	}
 
 	/*
 	 * Write the 12-byte command header.
@@ -1643,12 +1643,11 @@ static int usbat_hp8200e_transport(struc
 	 * AT SPEED 4 IS UNRELIABLE!!!
 	 */
 
-	if ((result = usbat_write_block(us,
-			USBAT_ATA, srb->cmnd, 12,
-				(srb->cmnd[0]==GPCMD_BLANK ? 75 : 10), 0) !=
-			     USB_STOR_TRANSPORT_GOOD)) {
+	result = usbat_write_block(us, USBAT_ATA, srb->cmnd, 12,
+				   srb->cmnd[0] == GPCMD_BLANK ? 75 : 10, 0);
+
+	if (result != USB_STOR_TRANSPORT_GOOD)
 		return result;
-	}
 
 	/* If there is response data to be read in then do it here. */
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/storage/sierra_ms.c linux-libre-2.6.34-gnu1/drivers/usb/storage/sierra_ms.c
--- linux-libre-2.6.33-gnu1/drivers/usb/storage/sierra_ms.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/storage/sierra_ms.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include "usb.h"
 #include "transport.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/storage/transport.c linux-libre-2.6.34-gnu1/drivers/usb/storage/transport.c
--- linux-libre-2.6.33-gnu1/drivers/usb/storage/transport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/storage/transport.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,8 +44,10 @@
  */
 
 #include <linux/sched.h>
+#include <linux/gfp.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
+
+#include <linux/usb/quirks.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_eh.h>
@@ -1297,6 +1299,10 @@ int usb_stor_port_reset(struct us_data *
 {
 	int result;
 
+	/*for these devices we must use the class specific method */
+	if (us->pusb_dev->quirks & USB_QUIRK_RESET_MORPHS)
+		return -EPERM;
+
 	result = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf);
 	if (result < 0)
 		US_DEBUGP("unable to lock device for reset: %d\n", result);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/storage/unusual_devs.h linux-libre-2.6.34-gnu1/drivers/usb/storage/unusual_devs.h
--- linux-libre-2.6.33-gnu1/drivers/usb/storage/unusual_devs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/storage/unusual_devs.h	2010-05-16 17:17:36.000000000 -0400
@@ -374,6 +374,15 @@ UNUSUAL_DEV(  0x04ce, 0x0002, 0x0074, 0x
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY),
 
+/* Reported by Ondrej Zary <linux@rainbow-software.org>
+ * The device reports one sector more and breaks when that sector is accessed
+ */
+UNUSUAL_DEV(  0x04ce, 0x0002, 0x026c, 0x026c,
+		"ScanLogic",
+		"SL11R-IDE",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_FIX_CAPACITY),
+
 /* Reported by Kriston Fincher <kriston@airmail.net>
  * Patch submitted by Sean Millichamp <sean@bruenor.org>
  * This is to support the Panasonic PalmCam PV-SD4090
@@ -1147,8 +1156,8 @@ UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0
 		0 ),
 
 /* Reported by Jan Dumon <j.dumon@option.com>
- * This device (wrongly) has a vendor-specific device descriptor.
- * The entry is needed so usb-storage can bind to it's mass-storage
+ * These devices (wrongly) have a vendor-specific device descriptor.
+ * These entries are needed so usb-storage can bind to their mass-storage
  * interface as an interface driver */
 UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000,
 		"Option",
@@ -1156,6 +1165,90 @@ UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		0 ),
 
+UNUSUAL_DEV( 0x0af0, 0x7701, 0x0000, 0x0000,
+		"Option",
+		"GI 0451 SD-Card",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		0 ),
+
+UNUSUAL_DEV( 0x0af0, 0x7706, 0x0000, 0x0000,
+		"Option",
+		"GI 0451 SD-Card",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		0 ),
+
+UNUSUAL_DEV( 0x0af0, 0x7901, 0x0000, 0x0000,
+		"Option",
+		"GI 0452 SD-Card",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		0 ),
+
+UNUSUAL_DEV( 0x0af0, 0x7A01, 0x0000, 0x0000,
+		"Option",
+		"GI 0461 SD-Card",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		0 ),
+
+UNUSUAL_DEV( 0x0af0, 0x7A05, 0x0000, 0x0000,
+		"Option",
+		"GI 0461 SD-Card",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		0 ),
+
+UNUSUAL_DEV( 0x0af0, 0x8300, 0x0000, 0x0000,
+		"Option",
+		"GI 033x SD-Card",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		0 ),
+
+UNUSUAL_DEV( 0x0af0, 0x8302, 0x0000, 0x0000,
+		"Option",
+		"GI 033x SD-Card",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		0 ),
+
+UNUSUAL_DEV( 0x0af0, 0x8304, 0x0000, 0x0000,
+		"Option",
+		"GI 033x SD-Card",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		0 ),
+
+UNUSUAL_DEV( 0x0af0, 0xc100, 0x0000, 0x0000,
+		"Option",
+		"GI 070x SD-Card",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		0 ),
+
+UNUSUAL_DEV( 0x0af0, 0xd057, 0x0000, 0x0000,
+		"Option",
+		"GI 1505 SD-Card",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		0 ),
+
+UNUSUAL_DEV( 0x0af0, 0xd058, 0x0000, 0x0000,
+		"Option",
+		"GI 1509 SD-Card",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		0 ),
+
+UNUSUAL_DEV( 0x0af0, 0xd157, 0x0000, 0x0000,
+		"Option",
+		"GI 1515 SD-Card",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		0 ),
+
+UNUSUAL_DEV( 0x0af0, 0xd257, 0x0000, 0x0000,
+		"Option",
+		"GI 1215 SD-Card",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		0 ),
+
+UNUSUAL_DEV( 0x0af0, 0xd357, 0x0000, 0x0000,
+		"Option",
+		"GI 1505 SD-Card",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		0 ),
+
 /* Reported by Ben Efros <ben@pc-doctor.com> */
 UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000,
 		"Seagate",
@@ -1296,20 +1389,6 @@ UNUSUAL_DEV(  0x0f19, 0x0105, 0x0100, 0x
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
-/* Jeremy Katz <katzj@redhat.com>:
- * The Blackberry Pearl can run in two modes; a usb-storage only mode
- * and a mode that allows access via mass storage and to its database.
- * The berry_charge module will set the device to dual mode and thus we
- * should ignore its native mode if that module is built
- */
-#ifdef CONFIG_USB_BERRY_CHARGE
-UNUSUAL_DEV(  0x0fca, 0x0006, 0x0001, 0x0001,
-		"RIM",
-		"Blackberry Pearl",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_DEVICE ),
-#endif
-
 /* Reported by Michael Stattmann <michael@stattmann.com> */
 UNUSUAL_DEV(  0x0fce, 0xd008, 0x0000, 0x0000,
 		"Sony Ericsson",
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/storage/usb.c linux-libre-2.6.34-gnu1/drivers/usb/storage/usb.c
--- linux-libre-2.6.33-gnu1/drivers/usb/storage/usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/storage/usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -78,7 +78,7 @@ MODULE_AUTHOR("Matthew Dharm <mdharm-usb
 MODULE_DESCRIPTION("USB Mass Storage driver for Linux");
 MODULE_LICENSE("GPL");
 
-static unsigned int delay_use = 5;
+static unsigned int delay_use = 1;
 module_param(delay_use, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device");
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/usb-skeleton.c linux-libre-2.6.34-gnu1/drivers/usb/usb-skeleton.c
--- linux-libre-2.6.33-gnu1/drivers/usb/usb-skeleton.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/usb-skeleton.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,7 @@
 #define USB_SKEL_PRODUCT_ID	0xfff0
 
 /* table of devices that work with this driver */
-static struct usb_device_id skel_table[] = {
+static const struct usb_device_id skel_table[] = {
 	{ USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/cbaf.c linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/cbaf.c
--- linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/cbaf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/cbaf.c	2010-05-16 17:17:36.000000000 -0400
@@ -92,6 +92,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/uwb.h>
 #include <linux/usb/wusb.h>
@@ -641,7 +642,7 @@ static void cbaf_disconnect(struct usb_i
 	kzfree(cbaf);
 }
 
-static struct usb_device_id cbaf_id_table[] = {
+static const struct usb_device_id cbaf_id_table[] = {
 	{ USB_INTERFACE_INFO(0xef, 0x03, 0x01), },
 	{ },
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/crypto.c linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/crypto.c
--- linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/crypto.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/crypto.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,7 @@
 #include <linux/module.h>
 #include <linux/err.h>
 #include <linux/uwb.h>
+#include <linux/slab.h>
 #include <linux/usb/wusb.h>
 #include <linux/scatterlist.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/devconnect.c linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/devconnect.c
--- linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/devconnect.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/devconnect.c	2010-05-16 17:17:36.000000000 -0400
@@ -88,6 +88,7 @@
 
 #include <linux/jiffies.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include "wusbhc.h"
 
@@ -437,7 +438,7 @@ static void __wusbhc_keep_alive(struct w
 	old_keep_alives = ie->hdr.bLength - sizeof(ie->hdr);
 	keep_alives = 0;
 	for (cnt = 0;
-	     keep_alives <= WUIE_ELT_MAX && cnt < wusbhc->ports_max;
+	     keep_alives < WUIE_ELT_MAX && cnt < wusbhc->ports_max;
 	     cnt++) {
 		unsigned tt = msecs_to_jiffies(wusbhc->trust_timeout);
 
@@ -868,7 +869,7 @@ static struct usb_wireless_cap_descripto
  * reference that we'll drop.
  *
  * First we need to determine if the device is a WUSB device (else we
- * ignore it). For that we use the speed setting (USB_SPEED_VARIABLE)
+ * ignore it). For that we use the speed setting (USB_SPEED_WIRELESS)
  * [FIXME: maybe we'd need something more definitive]. If so, we track
  * it's usb_busd and from there, the WUSB HC.
  *
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/mmc.c linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/mmc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/mmc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/mmc.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
  *  - add timers that autoremove intervalled IEs?
  */
 #include <linux/usb/wusb.h>
+#include <linux/slab.h>
 #include "wusbhc.h"
 
 /* Initialize the MMCIEs handling mechanism */
@@ -263,7 +264,7 @@ int wusbhc_chid_set(struct wusbhc *wusbh
 {
 	int result = 0;
 
-	if (memcmp(chid, &wusb_ckhdid_zero, sizeof(chid)) == 0)
+	if (memcmp(chid, &wusb_ckhdid_zero, sizeof(*chid)) == 0)
 		chid = NULL;
 
 	mutex_lock(&wusbhc->mutex);
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/rh.c linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/rh.c
--- linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/rh.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/rh.c	2010-05-16 17:17:36.000000000 -0400
@@ -69,6 +69,7 @@
  *
  * wusbhc_rh_start_port_reset() ??? unimplemented
  */
+#include <linux/slab.h>
 #include "wusbhc.h"
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/security.c linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/security.c
--- linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/security.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/security.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
  * FIXME: docs
  */
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/usb/ch9.h>
 #include <linux/random.h>
 #include "wusbhc.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/wa-hc.c linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/wa-hc.c
--- linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/wa-hc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/wa-hc.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  *
  * FIXME: docs
  */
+#include <linux/slab.h>
 #include "wusbhc.h"
 #include "wa-hc.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/wa-nep.c linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/wa-nep.c
--- linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/wa-nep.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/wa-nep.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,6 +51,7 @@
  */
 #include <linux/workqueue.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 
 #include "wa-hc.h"
 #include "wusbhc.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/wa-rpipe.c linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/wa-rpipe.c
--- linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/wa-rpipe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/wa-rpipe.c	2010-05-16 17:17:36.000000000 -0400
@@ -60,6 +60,7 @@
 #include <linux/init.h>
 #include <asm/atomic.h>
 #include <linux/bitmap.h>
+#include <linux/slab.h>
 
 #include "wusbhc.h"
 #include "wa-hc.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/wa-xfer.c linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/wa-xfer.c
--- linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/wa-xfer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/wa-xfer.c	2010-05-16 17:17:36.000000000 -0400
@@ -81,6 +81,7 @@
  */
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/hash.h>
 
 #include "wa-hc.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/wusbhc.h linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/wusbhc.h
--- linux-libre-2.6.33-gnu1/drivers/usb/wusbcore/wusbhc.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/usb/wusbcore/wusbhc.h	2010-05-16 17:17:36.000000000 -0400
@@ -198,7 +198,7 @@ struct wusb_port {
  *                 ports) this HC will take. Read-only.
  *
  * @port      	   Array of port status for each fake root port. Guaranteed to
- *                 always be the same lenght during device existence
+ *                 always be the same length during device existence
  *                 [this allows for some unlocked but referenced reading].
  *
  * @mmcies_max	   Max number of Information Elements this HC can send
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/address.c linux-libre-2.6.34-gnu1/drivers/uwb/address.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/address.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/address.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
  * FIXME: docs
  */
 
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/allocator.c linux-libre-2.6.34-gnu1/drivers/uwb/allocator.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/allocator.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/allocator.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/uwb.h>
 
 #include "uwb-internal.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/beacon.c linux-libre-2.6.34-gnu1/drivers/uwb/beacon.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/beacon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/beacon.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/kdev_t.h>
+#include <linux/slab.h>
 
 #include "uwb-internal.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/driver.c linux-libre-2.6.34-gnu1/drivers/uwb/driver.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/driver.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/driver.c	2010-05-16 17:17:36.000000000 -0400
@@ -74,13 +74,16 @@
 unsigned long beacon_timeout_ms = 500;
 
 static
-ssize_t beacon_timeout_ms_show(struct class *class, char *buf)
+ssize_t beacon_timeout_ms_show(struct class *class,
+				struct class_attribute *attr,
+				char *buf)
 {
 	return scnprintf(buf, PAGE_SIZE, "%lu\n", beacon_timeout_ms);
 }
 
 static
 ssize_t beacon_timeout_ms_store(struct class *class,
+				struct class_attribute *attr,
 				const char *buf, size_t size)
 {
 	unsigned long bt;
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/drp.c linux-libre-2.6.34-gnu1/drivers/uwb/drp.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/drp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/drp.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 #include <linux/kthread.h>
 #include <linux/freezer.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include "uwb-internal.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/drp-ie.c linux-libre-2.6.34-gnu1/drivers/uwb/drp-ie.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/drp-ie.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/drp-ie.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <linux/uwb.h>
 
 #include "uwb-internal.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/est.c linux-libre-2.6.34-gnu1/drivers/uwb/est.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/est.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/est.c	2010-05-16 17:17:36.000000000 -0400
@@ -40,6 +40,7 @@
  *   uwb_est_get_size()
  */
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 
 #include "uwb-internal.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/hwa-rc.c linux-libre-2.6.34-gnu1/drivers/uwb/hwa-rc.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/hwa-rc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/hwa-rc.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,6 +53,7 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/wusb.h>
 #include <linux/usb/wusb-wa.h>
@@ -891,7 +892,7 @@ static int hwarc_post_reset(struct usb_i
 }
 
 /** USB device ID's that we handle */
-static struct usb_device_id hwarc_id_table[] = {
+static const struct usb_device_id hwarc_id_table[] = {
 	/* D-Link DUB-1210 */
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3d02, 0xe0, 0x01, 0x02),
 	  .driver_info = WUSB_QUIRK_WHCI_CMD_EVT },
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/i1480/dfu/mac.c linux-libre-2.6.34-gnu1/drivers/uwb/i1480/dfu/mac.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/i1480/dfu/mac.c	2013-05-03 12:13:31.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/uwb/i1480/dfu/mac.c	2013-05-03 09:53:03.000000000 -0400
@@ -28,6 +28,7 @@
  */
 #include <linux/delay.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <linux/uwb.h>
 #include "i1480-dfu.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/i1480/dfu/usb.c linux-libre-2.6.34-gnu1/drivers/uwb/i1480/dfu/usb.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/i1480/dfu/usb.c	2013-05-03 12:13:33.000000000 -0400
+++ linux-libre-2.6.34-gnu1/drivers/uwb/i1480/dfu/usb.c	2013-05-03 09:53:05.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/uwb.h>
 #include <linux/usb/wusb.h>
@@ -120,8 +121,7 @@ int i1480_usb_write(struct i1480 *i1480,
 		result = usb_control_msg(
 			i1480_usb->usb_dev, usb_sndctrlpipe(i1480_usb->usb_dev, 0),
 			0xf0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			cpu_to_le16(memory_address & 0xffff),
-			cpu_to_le16((memory_address >> 16) & 0xffff),
+			memory_address,	(memory_address >> 16),
 			i1480->cmd_buf, buffer_size, 100 /* FIXME: arbitrary */);
 		if (result < 0)
 			break;
@@ -166,8 +166,7 @@ int i1480_usb_read(struct i1480 *i1480,
 		result = usb_control_msg(
 			i1480_usb->usb_dev, usb_rcvctrlpipe(i1480_usb->usb_dev, 0),
 			0xf0, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			cpu_to_le16(itr_addr & 0xffff),
-			cpu_to_le16((itr_addr >> 16) & 0xffff),
+			itr_addr, (itr_addr >> 16),
 			i1480->cmd_buf + itr, itr_size,
 			100 /* FIXME: arbitrary */);
 		if (result < 0) {
@@ -413,6 +412,8 @@ error:
 	return result;
 }
 
+/*(DEBLOBBED)*/
+
 #define i1480_USB_DEV(v, p)				\
 {							\
 	.match_flags = USB_DEVICE_ID_MATCH_DEVICE	\
@@ -430,7 +431,7 @@ error:
 
 
 /** USB device ID's that we handle */
-static struct usb_device_id i1480_usb_id_table[] = {
+static const struct usb_device_id i1480_usb_id_table[] = {
 	i1480_USB_DEV(0x8086, 0xdf3b),
 	i1480_USB_DEV(0x15a9, 0x0005),
 	i1480_USB_DEV(0x07d1, 0x3802),
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/i1480/i1480-est.c linux-libre-2.6.34-gnu1/drivers/uwb/i1480/i1480-est.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/i1480/i1480-est.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/i1480/i1480-est.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,7 +54,7 @@ static struct uwb_est_entry i1480_est_fd
 		.size = sizeof(struct i1480_rceb) + 2 },
 };
 
-static int i1480_est_init(void)
+static int __init i1480_est_init(void)
 {
 	int result = uwb_est_register(i1480_CET_VS1, 0x00, 0x8086, 0x0c3b,
 				      i1480_est_fd00,
@@ -73,7 +73,7 @@ static int i1480_est_init(void)
 }
 module_init(i1480_est_init);
 
-static void i1480_est_exit(void)
+static void __exit i1480_est_exit(void)
 {
 	uwb_est_unregister(i1480_CET_VS1, 0x00, 0x8086, 0x0c3b,
 			   i1480_est_fd00, ARRAY_SIZE(i1480_est_fd00));
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/i1480/i1480u-wlp/lc.c linux-libre-2.6.34-gnu1/drivers/uwb/i1480/i1480u-wlp/lc.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/i1480/i1480u-wlp/lc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/i1480/i1480u-wlp/lc.c	2010-05-16 17:17:36.000000000 -0400
@@ -55,6 +55,7 @@
  *                          is being removed.
  *         i1480u_rm()
  */
+#include <linux/gfp.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/i1480/i1480u-wlp/netdev.c linux-libre-2.6.34-gnu1/drivers/uwb/i1480/i1480u-wlp/netdev.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/i1480/i1480u-wlp/netdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/i1480/i1480u-wlp/netdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
  *     i1480u_set_config():
  */
 
+#include <linux/slab.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/i1480/i1480u-wlp/rx.c linux-libre-2.6.34-gnu1/drivers/uwb/i1480/i1480u-wlp/rx.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/i1480/i1480u-wlp/rx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/i1480/i1480u-wlp/rx.c	2010-05-16 17:17:36.000000000 -0400
@@ -64,6 +64,7 @@
  *
  */
 
+#include <linux/gfp.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include "i1480u-wlp.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/i1480/i1480u-wlp/tx.c linux-libre-2.6.34-gnu1/drivers/uwb/i1480/i1480u-wlp/tx.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/i1480/i1480u-wlp/tx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/i1480/i1480u-wlp/tx.c	2010-05-16 17:17:36.000000000 -0400
@@ -54,6 +54,7 @@
  *          the times the MTU will be smaller than one page...
  */
 
+#include <linux/slab.h>
 #include "i1480u-wlp.h"
 
 enum {
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/ie.c linux-libre-2.6.34-gnu1/drivers/uwb/ie.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/ie.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/ie.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
  * FIXME: docs
  */
 
+#include <linux/slab.h>
 #include "uwb-internal.h"
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/lc-dev.c linux-libre-2.6.34-gnu1/drivers/uwb/lc-dev.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/lc-dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/lc-dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
  * FIXME: docs
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/kdev_t.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/lc-rc.c linux-libre-2.6.34-gnu1/drivers/uwb/lc-rc.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/lc-rc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/lc-rc.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/kdev_t.h>
 #include <linux/etherdevice.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include "uwb-internal.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/neh.c linux-libre-2.6.34-gnu1/drivers/uwb/neh.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/neh.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/neh.c	2010-05-16 17:17:36.000000000 -0400
@@ -83,6 +83,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 
 #include "uwb-internal.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/reset.c linux-libre-2.6.34-gnu1/drivers/uwb/reset.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/reset.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/reset.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include "uwb-internal.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/rsv.c linux-libre-2.6.34-gnu1/drivers/uwb/rsv.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/rsv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/rsv.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/uwb.h>
+#include <linux/slab.h>
 #include <linux/random.h>
 
 #include "uwb-internal.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/scan.c linux-libre-2.6.34-gnu1/drivers/uwb/scan.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/scan.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/scan.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include "uwb-internal.h"
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/umc-bus.c linux-libre-2.6.34-gnu1/drivers/uwb/umc-bus.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/umc-bus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/umc-bus.c	2010-05-16 17:17:36.000000000 -0400
@@ -62,12 +62,12 @@ int umc_controller_reset(struct umc_dev
 	struct device *parent = umc->dev.parent;
 	int ret = 0;
 
-	if(down_trylock(&parent->sem))
+	if (device_trylock(parent))
 		return -EAGAIN;
 	ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper);
 	if (ret >= 0)
 		ret = device_for_each_child(parent, parent, umc_bus_post_reset_helper);
-	up(&parent->sem);
+	device_unlock(parent);
 
 	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/umc-dev.c linux-libre-2.6.34-gnu1/drivers/uwb/umc-dev.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/umc-dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/umc-dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -6,6 +6,7 @@
  * This file is released under the GNU GPL v2.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/uwb/umc.h>
 
 static void umc_device_release(struct device *dev)
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/uwbd.c linux-libre-2.6.34-gnu1/drivers/uwb/uwbd.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/uwbd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/uwbd.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,7 +43,7 @@
  *
  * EVENTS
  *
- * Events have a type, a subtype, a lenght, some other stuff and the
+ * Events have a type, a subtype, a length, some other stuff and the
  * data blob, which depends on the event. The header is 'struct
  * uwb_event'; for payloads, see 'struct uwbd_evt_*'.
  *
@@ -69,6 +69,7 @@
  * Handler functions are called normally uwbd_evt_handle_*().
  */
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/freezer.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/uwb-internal.h linux-libre-2.6.34-gnu1/drivers/uwb/uwb-internal.h
--- linux-libre-2.6.33-gnu1/drivers/uwb/uwb-internal.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/uwb-internal.h	2010-05-16 17:17:36.000000000 -0400
@@ -366,12 +366,12 @@ struct dentry *uwb_dbg_create_pal_dir(st
 
 static inline void uwb_dev_lock(struct uwb_dev *uwb_dev)
 {
-	down(&uwb_dev->dev.sem);
+	device_lock(&uwb_dev->dev);
 }
 
 static inline void uwb_dev_unlock(struct uwb_dev *uwb_dev)
 {
-	up(&uwb_dev->dev.sem);
+	device_unlock(&uwb_dev->dev);
 }
 
 #endif /* #ifndef __UWB_INTERNAL_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/whci.c linux-libre-2.6.34-gnu1/drivers/uwb/whci.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/whci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/whci.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <linux/uwb/whci.h>
 #include <linux/uwb/umc.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/whc-rc.c linux-libre-2.6.34-gnu1/drivers/uwb/whc-rc.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/whc-rc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/whc-rc.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,6 +45,7 @@
 #include <linux/sched.h>
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/uwb.h>
 #include <linux/uwb/whci.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/wlp/eda.c linux-libre-2.6.34-gnu1/drivers/uwb/wlp/eda.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/wlp/eda.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/wlp/eda.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,6 +53,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <linux/wlp.h>
 #include "wlp-internal.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/wlp/messages.c linux-libre-2.6.34-gnu1/drivers/uwb/wlp/messages.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/wlp/messages.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/wlp/messages.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
  */
 
 #include <linux/wlp.h>
+#include <linux/slab.h>
 
 #include "wlp-internal.h"
 
@@ -259,6 +260,63 @@ out:
 }
 
 
+static ssize_t wlp_get_attribute(struct wlp *wlp, u16 type_code,
+	struct wlp_attr_hdr *attr_hdr, void *value, ssize_t value_len,
+	ssize_t buflen)
+{
+	struct device *dev = &wlp->rc->uwb_dev.dev;
+	ssize_t attr_len = sizeof(*attr_hdr) + value_len;
+	if (buflen < 0)
+		return -EINVAL;
+	if (buflen < attr_len) {
+		dev_err(dev, "WLP: Not enough space in buffer to parse"
+			" attribute field. Need %d, received %zu\n",
+			(int)attr_len, buflen);
+		return -EIO;
+	}
+	if (wlp_check_attr_hdr(wlp, attr_hdr, type_code, value_len) < 0) {
+		dev_err(dev, "WLP: Header verification failed. \n");
+		return -EINVAL;
+	}
+	memcpy(value, (void *)attr_hdr + sizeof(*attr_hdr), value_len);
+	return attr_len;
+}
+
+static ssize_t wlp_vget_attribute(struct wlp *wlp, u16 type_code,
+	struct wlp_attr_hdr *attr_hdr, void *value, ssize_t max_value_len,
+	ssize_t buflen)
+{
+	struct device *dev = &wlp->rc->uwb_dev.dev;
+	size_t len;
+	if (buflen < 0)
+		return -EINVAL;
+	if (buflen < sizeof(*attr_hdr)) {
+		dev_err(dev, "WLP: Not enough space in buffer to parse"
+			" header.\n");
+		return -EIO;
+	}
+	if (le16_to_cpu(attr_hdr->type) != type_code) {
+		dev_err(dev, "WLP: Unexpected attribute type. Got %u, "
+			"expected %u.\n", le16_to_cpu(attr_hdr->type),
+			type_code);
+		return -EINVAL;
+	}
+	len = le16_to_cpu(attr_hdr->length);
+	if (len > max_value_len) {
+		dev_err(dev, "WLP: Attribute larger than maximum "
+			"allowed. Received %zu, max is %d.\n", len,
+			(int)max_value_len);
+		return -EFBIG;
+	}
+	if (buflen < sizeof(*attr_hdr) + len) {
+		dev_err(dev, "WLP: Not enough space in buffer to parse "
+			"variable data.\n");
+		return -EIO;
+	}
+	memcpy(value, (void *)attr_hdr + sizeof(*attr_hdr), len);
+	return sizeof(*attr_hdr) + len;
+}
+
 /**
  * Get value of attribute from fixed size attribute field.
  *
@@ -274,22 +332,8 @@ out:
 ssize_t wlp_get_##name(struct wlp *wlp, struct wlp_attr_##name *attr,	\
 		      type *value, ssize_t buflen)			\
 {									\
-	struct device *dev = &wlp->rc->uwb_dev.dev;			\
-	if (buflen < 0)							\
-		return -EINVAL;						\
-	if (buflen < sizeof(*attr)) {					\
-		dev_err(dev, "WLP: Not enough space in buffer to parse"	\
-			" attribute field. Need %d, received %zu\n",	\
-			(int)sizeof(*attr), buflen);			\
-		return -EIO;						\
-	}								\
-	if (wlp_check_attr_hdr(wlp, &attr->hdr, type_code,		\
-			       sizeof(attr->name)) < 0) {		\
-		dev_err(dev, "WLP: Header verification failed. \n");	\
-		return -EINVAL;						\
-	}								\
-	*value = attr->name;						\
-	return sizeof(*attr);						\
+	return wlp_get_attribute(wlp, (type_code), &attr->hdr,		\
+				 value, sizeof(*value), buflen);	\
 }
 
 #define wlp_get_sparse(type, type_code, name) \
@@ -313,35 +357,8 @@ static ssize_t wlp_get_##name(struct wlp
 			      struct wlp_attr_##name *attr,		\
 			      type_val *value, ssize_t buflen)		\
 {									\
-	struct device *dev = &wlp->rc->uwb_dev.dev;			\
-	size_t len;							\
-	if (buflen < 0)							\
-		return -EINVAL;						\
-	if (buflen < sizeof(*attr)) {					\
-		dev_err(dev, "WLP: Not enough space in buffer to parse"	\
-			" header.\n");					\
-		return -EIO;						\
-	}								\
-	if (le16_to_cpu(attr->hdr.type) != type_code) {			\
-		dev_err(dev, "WLP: Unexpected attribute type. Got %u, "	\
-			"expected %u.\n", le16_to_cpu(attr->hdr.type),	\
-			type_code);					\
-		return -EINVAL;						\
-	}								\
-	len = le16_to_cpu(attr->hdr.length);				\
-	if (len > max) {						\
-		dev_err(dev, "WLP: Attribute larger than maximum "	\
-			"allowed. Received %zu, max is %d.\n", len,	\
-			(int)max);					\
-		return -EFBIG;						\
-	}								\
-	if (buflen < sizeof(*attr) + len) {				\
-		dev_err(dev, "WLP: Not enough space in buffer to parse "\
-			"variable data.\n");				\
-		return -EIO;						\
-	}								\
-	memcpy(value, (void *) attr + sizeof(*attr), len);		\
-	return sizeof(*attr) + len;					\
+	return wlp_vget_attribute(wlp, (type_code), &attr->hdr, 	\
+			      value, (max), buflen);			\
 }
 
 wlp_get(u8, WLP_ATTR_WLP_VER, version)
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/wlp/sysfs.c linux-libre-2.6.34-gnu1/drivers/uwb/wlp/sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/wlp/sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/wlp/sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -615,8 +615,7 @@ ssize_t wlp_wss_attr_store(struct kobjec
 	return ret;
 }
 
-static
-struct sysfs_ops wss_sysfs_ops = {
+static const struct sysfs_ops wss_sysfs_ops = {
 	.show	= wlp_wss_attr_show,
 	.store	= wlp_wss_attr_store,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/wlp/txrx.c linux-libre-2.6.34-gnu1/drivers/uwb/wlp/txrx.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/wlp/txrx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/wlp/txrx.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
  */
 
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <linux/wlp.h>
 
 #include "wlp-internal.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/wlp/wlp-lc.c linux-libre-2.6.34-gnu1/drivers/uwb/wlp/wlp-lc.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/wlp/wlp-lc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/wlp/wlp-lc.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  * FIXME: docs
  */
 #include <linux/wlp.h>
+#include <linux/slab.h>
 
 #include "wlp-internal.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/uwb/wlp/wss-lc.c linux-libre-2.6.34-gnu1/drivers/uwb/wlp/wss-lc.c
--- linux-libre-2.6.33-gnu1/drivers/uwb/wlp/wss-lc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/uwb/wlp/wss-lc.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,6 +45,7 @@
  */
 #include <linux/etherdevice.h> /* for is_valid_ether_addr */
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/wlp.h>
 
 #include "wlp-internal.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/vhost/Kconfig linux-libre-2.6.34-gnu1/drivers/vhost/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/vhost/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/vhost/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,11 @@
+config VHOST_NET
+	tristate "Host kernel accelerator for virtio net (EXPERIMENTAL)"
+	depends on NET && EVENTFD && (TUN || !TUN) && (MACVTAP || !MACVTAP) && EXPERIMENTAL
+	---help---
+	  This kernel module can be loaded in host kernel to accelerate
+	  guest networking with virtio_net. Not to be confused with virtio_net
+	  module itself which needs to be loaded in guest kernel.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called vhost_net.
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/vhost/Makefile linux-libre-2.6.34-gnu1/drivers/vhost/Makefile
--- linux-libre-2.6.33-gnu1/drivers/vhost/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/vhost/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,2 @@
+obj-$(CONFIG_VHOST_NET) += vhost_net.o
+vhost_net-y := vhost.o net.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/vhost/net.c linux-libre-2.6.34-gnu1/drivers/vhost/net.c
--- linux-libre-2.6.33-gnu1/drivers/vhost/net.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/vhost/net.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,672 @@
+/* Copyright (C) 2009 Red Hat, Inc.
+ * Author: Michael S. Tsirkin <mst@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ *
+ * virtio-net server in host kernel.
+ */
+
+#include <linux/compat.h>
+#include <linux/eventfd.h>
+#include <linux/vhost.h>
+#include <linux/virtio_net.h>
+#include <linux/mmu_context.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/rcupdate.h>
+#include <linux/file.h>
+#include <linux/slab.h>
+
+#include <linux/net.h>
+#include <linux/if_packet.h>
+#include <linux/if_arp.h>
+#include <linux/if_tun.h>
+#include <linux/if_macvlan.h>
+
+#include <net/sock.h>
+
+#include "vhost.h"
+
+/* Max number of bytes transferred before requeueing the job.
+ * Using this limit prevents one virtqueue from starving others. */
+#define VHOST_NET_WEIGHT 0x80000
+
+enum {
+	VHOST_NET_VQ_RX = 0,
+	VHOST_NET_VQ_TX = 1,
+	VHOST_NET_VQ_MAX = 2,
+};
+
+enum vhost_net_poll_state {
+	VHOST_NET_POLL_DISABLED = 0,
+	VHOST_NET_POLL_STARTED = 1,
+	VHOST_NET_POLL_STOPPED = 2,
+};
+
+struct vhost_net {
+	struct vhost_dev dev;
+	struct vhost_virtqueue vqs[VHOST_NET_VQ_MAX];
+	struct vhost_poll poll[VHOST_NET_VQ_MAX];
+	/* Tells us whether we are polling a socket for TX.
+	 * We only do this when socket buffer fills up.
+	 * Protected by tx vq lock. */
+	enum vhost_net_poll_state tx_poll_state;
+};
+
+/* Pop first len bytes from iovec. Return number of segments used. */
+static int move_iovec_hdr(struct iovec *from, struct iovec *to,
+			  size_t len, int iov_count)
+{
+	int seg = 0;
+	size_t size;
+	while (len && seg < iov_count) {
+		size = min(from->iov_len, len);
+		to->iov_base = from->iov_base;
+		to->iov_len = size;
+		from->iov_len -= size;
+		from->iov_base += size;
+		len -= size;
+		++from;
+		++to;
+		++seg;
+	}
+	return seg;
+}
+
+/* Caller must have TX VQ lock */
+static void tx_poll_stop(struct vhost_net *net)
+{
+	if (likely(net->tx_poll_state != VHOST_NET_POLL_STARTED))
+		return;
+	vhost_poll_stop(net->poll + VHOST_NET_VQ_TX);
+	net->tx_poll_state = VHOST_NET_POLL_STOPPED;
+}
+
+/* Caller must have TX VQ lock */
+static void tx_poll_start(struct vhost_net *net, struct socket *sock)
+{
+	if (unlikely(net->tx_poll_state != VHOST_NET_POLL_STOPPED))
+		return;
+	vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file);
+	net->tx_poll_state = VHOST_NET_POLL_STARTED;
+}
+
+/* Expects to be always run from workqueue - which acts as
+ * read-size critical section for our kind of RCU. */
+static void handle_tx(struct vhost_net *net)
+{
+	struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_TX];
+	unsigned head, out, in, s;
+	struct msghdr msg = {
+		.msg_name = NULL,
+		.msg_namelen = 0,
+		.msg_control = NULL,
+		.msg_controllen = 0,
+		.msg_iov = vq->iov,
+		.msg_flags = MSG_DONTWAIT,
+	};
+	size_t len, total_len = 0;
+	int err, wmem;
+	size_t hdr_size;
+	struct socket *sock = rcu_dereference(vq->private_data);
+	if (!sock)
+		return;
+
+	wmem = atomic_read(&sock->sk->sk_wmem_alloc);
+	if (wmem >= sock->sk->sk_sndbuf) {
+		mutex_lock(&vq->mutex);
+		tx_poll_start(net, sock);
+		mutex_unlock(&vq->mutex);
+		return;
+	}
+
+	use_mm(net->dev.mm);
+	mutex_lock(&vq->mutex);
+	vhost_disable_notify(vq);
+
+	if (wmem < sock->sk->sk_sndbuf / 2)
+		tx_poll_stop(net);
+	hdr_size = vq->hdr_size;
+
+	for (;;) {
+		head = vhost_get_vq_desc(&net->dev, vq, vq->iov,
+					 ARRAY_SIZE(vq->iov),
+					 &out, &in,
+					 NULL, NULL);
+		/* Nothing new?  Wait for eventfd to tell us they refilled. */
+		if (head == vq->num) {
+			wmem = atomic_read(&sock->sk->sk_wmem_alloc);
+			if (wmem >= sock->sk->sk_sndbuf * 3 / 4) {
+				tx_poll_start(net, sock);
+				set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
+				break;
+			}
+			if (unlikely(vhost_enable_notify(vq))) {
+				vhost_disable_notify(vq);
+				continue;
+			}
+			break;
+		}
+		if (in) {
+			vq_err(vq, "Unexpected descriptor format for TX: "
+			       "out %d, int %d\n", out, in);
+			break;
+		}
+		/* Skip header. TODO: support TSO. */
+		s = move_iovec_hdr(vq->iov, vq->hdr, hdr_size, out);
+		msg.msg_iovlen = out;
+		len = iov_length(vq->iov, out);
+		/* Sanity check */
+		if (!len) {
+			vq_err(vq, "Unexpected header len for TX: "
+			       "%zd expected %zd\n",
+			       iov_length(vq->hdr, s), hdr_size);
+			break;
+		}
+		/* TODO: Check specific error and bomb out unless ENOBUFS? */
+		err = sock->ops->sendmsg(NULL, sock, &msg, len);
+		if (unlikely(err < 0)) {
+			vhost_discard_vq_desc(vq);
+			tx_poll_start(net, sock);
+			break;
+		}
+		if (err != len)
+			pr_err("Truncated TX packet: "
+			       " len %d != %zd\n", err, len);
+		vhost_add_used_and_signal(&net->dev, vq, head, 0);
+		total_len += len;
+		if (unlikely(total_len >= VHOST_NET_WEIGHT)) {
+			vhost_poll_queue(&vq->poll);
+			break;
+		}
+	}
+
+	mutex_unlock(&vq->mutex);
+	unuse_mm(net->dev.mm);
+}
+
+/* Expects to be always run from workqueue - which acts as
+ * read-size critical section for our kind of RCU. */
+static void handle_rx(struct vhost_net *net)
+{
+	struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_RX];
+	unsigned head, out, in, log, s;
+	struct vhost_log *vq_log;
+	struct msghdr msg = {
+		.msg_name = NULL,
+		.msg_namelen = 0,
+		.msg_control = NULL, /* FIXME: get and handle RX aux data. */
+		.msg_controllen = 0,
+		.msg_iov = vq->iov,
+		.msg_flags = MSG_DONTWAIT,
+	};
+
+	struct virtio_net_hdr hdr = {
+		.flags = 0,
+		.gso_type = VIRTIO_NET_HDR_GSO_NONE
+	};
+
+	size_t len, total_len = 0;
+	int err;
+	size_t hdr_size;
+	struct socket *sock = rcu_dereference(vq->private_data);
+	if (!sock || skb_queue_empty(&sock->sk->sk_receive_queue))
+		return;
+
+	use_mm(net->dev.mm);
+	mutex_lock(&vq->mutex);
+	vhost_disable_notify(vq);
+	hdr_size = vq->hdr_size;
+
+	vq_log = unlikely(vhost_has_feature(&net->dev, VHOST_F_LOG_ALL)) ?
+		vq->log : NULL;
+
+	for (;;) {
+		head = vhost_get_vq_desc(&net->dev, vq, vq->iov,
+					 ARRAY_SIZE(vq->iov),
+					 &out, &in,
+					 vq_log, &log);
+		/* OK, now we need to know about added descriptors. */
+		if (head == vq->num) {
+			if (unlikely(vhost_enable_notify(vq))) {
+				/* They have slipped one in as we were
+				 * doing that: check again. */
+				vhost_disable_notify(vq);
+				continue;
+			}
+			/* Nothing new?  Wait for eventfd to tell us
+			 * they refilled. */
+			break;
+		}
+		/* We don't need to be notified again. */
+		if (out) {
+			vq_err(vq, "Unexpected descriptor format for RX: "
+			       "out %d, int %d\n",
+			       out, in);
+			break;
+		}
+		/* Skip header. TODO: support TSO/mergeable rx buffers. */
+		s = move_iovec_hdr(vq->iov, vq->hdr, hdr_size, in);
+		msg.msg_iovlen = in;
+		len = iov_length(vq->iov, in);
+		/* Sanity check */
+		if (!len) {
+			vq_err(vq, "Unexpected header len for RX: "
+			       "%zd expected %zd\n",
+			       iov_length(vq->hdr, s), hdr_size);
+			break;
+		}
+		err = sock->ops->recvmsg(NULL, sock, &msg,
+					 len, MSG_DONTWAIT | MSG_TRUNC);
+		/* TODO: Check specific error and bomb out unless EAGAIN? */
+		if (err < 0) {
+			vhost_discard_vq_desc(vq);
+			break;
+		}
+		/* TODO: Should check and handle checksum. */
+		if (err > len) {
+			pr_err("Discarded truncated rx packet: "
+			       " len %d > %zd\n", err, len);
+			vhost_discard_vq_desc(vq);
+			continue;
+		}
+		len = err;
+		err = memcpy_toiovec(vq->hdr, (unsigned char *)&hdr, hdr_size);
+		if (err) {
+			vq_err(vq, "Unable to write vnet_hdr at addr %p: %d\n",
+			       vq->iov->iov_base, err);
+			break;
+		}
+		len += hdr_size;
+		vhost_add_used_and_signal(&net->dev, vq, head, len);
+		if (unlikely(vq_log))
+			vhost_log_write(vq, vq_log, log, len);
+		total_len += len;
+		if (unlikely(total_len >= VHOST_NET_WEIGHT)) {
+			vhost_poll_queue(&vq->poll);
+			break;
+		}
+	}
+
+	mutex_unlock(&vq->mutex);
+	unuse_mm(net->dev.mm);
+}
+
+static void handle_tx_kick(struct work_struct *work)
+{
+	struct vhost_virtqueue *vq;
+	struct vhost_net *net;
+	vq = container_of(work, struct vhost_virtqueue, poll.work);
+	net = container_of(vq->dev, struct vhost_net, dev);
+	handle_tx(net);
+}
+
+static void handle_rx_kick(struct work_struct *work)
+{
+	struct vhost_virtqueue *vq;
+	struct vhost_net *net;
+	vq = container_of(work, struct vhost_virtqueue, poll.work);
+	net = container_of(vq->dev, struct vhost_net, dev);
+	handle_rx(net);
+}
+
+static void handle_tx_net(struct work_struct *work)
+{
+	struct vhost_net *net;
+	net = container_of(work, struct vhost_net, poll[VHOST_NET_VQ_TX].work);
+	handle_tx(net);
+}
+
+static void handle_rx_net(struct work_struct *work)
+{
+	struct vhost_net *net;
+	net = container_of(work, struct vhost_net, poll[VHOST_NET_VQ_RX].work);
+	handle_rx(net);
+}
+
+static int vhost_net_open(struct inode *inode, struct file *f)
+{
+	struct vhost_net *n = kmalloc(sizeof *n, GFP_KERNEL);
+	int r;
+	if (!n)
+		return -ENOMEM;
+	n->vqs[VHOST_NET_VQ_TX].handle_kick = handle_tx_kick;
+	n->vqs[VHOST_NET_VQ_RX].handle_kick = handle_rx_kick;
+	r = vhost_dev_init(&n->dev, n->vqs, VHOST_NET_VQ_MAX);
+	if (r < 0) {
+		kfree(n);
+		return r;
+	}
+
+	vhost_poll_init(n->poll + VHOST_NET_VQ_TX, handle_tx_net, POLLOUT);
+	vhost_poll_init(n->poll + VHOST_NET_VQ_RX, handle_rx_net, POLLIN);
+	n->tx_poll_state = VHOST_NET_POLL_DISABLED;
+
+	f->private_data = n;
+
+	return 0;
+}
+
+static void vhost_net_disable_vq(struct vhost_net *n,
+				 struct vhost_virtqueue *vq)
+{
+	if (!vq->private_data)
+		return;
+	if (vq == n->vqs + VHOST_NET_VQ_TX) {
+		tx_poll_stop(n);
+		n->tx_poll_state = VHOST_NET_POLL_DISABLED;
+	} else
+		vhost_poll_stop(n->poll + VHOST_NET_VQ_RX);
+}
+
+static void vhost_net_enable_vq(struct vhost_net *n,
+				struct vhost_virtqueue *vq)
+{
+	struct socket *sock = vq->private_data;
+	if (!sock)
+		return;
+	if (vq == n->vqs + VHOST_NET_VQ_TX) {
+		n->tx_poll_state = VHOST_NET_POLL_STOPPED;
+		tx_poll_start(n, sock);
+	} else
+		vhost_poll_start(n->poll + VHOST_NET_VQ_RX, sock->file);
+}
+
+static struct socket *vhost_net_stop_vq(struct vhost_net *n,
+					struct vhost_virtqueue *vq)
+{
+	struct socket *sock;
+
+	mutex_lock(&vq->mutex);
+	sock = vq->private_data;
+	vhost_net_disable_vq(n, vq);
+	rcu_assign_pointer(vq->private_data, NULL);
+	mutex_unlock(&vq->mutex);
+	return sock;
+}
+
+static void vhost_net_stop(struct vhost_net *n, struct socket **tx_sock,
+			   struct socket **rx_sock)
+{
+	*tx_sock = vhost_net_stop_vq(n, n->vqs + VHOST_NET_VQ_TX);
+	*rx_sock = vhost_net_stop_vq(n, n->vqs + VHOST_NET_VQ_RX);
+}
+
+static void vhost_net_flush_vq(struct vhost_net *n, int index)
+{
+	vhost_poll_flush(n->poll + index);
+	vhost_poll_flush(&n->dev.vqs[index].poll);
+}
+
+static void vhost_net_flush(struct vhost_net *n)
+{
+	vhost_net_flush_vq(n, VHOST_NET_VQ_TX);
+	vhost_net_flush_vq(n, VHOST_NET_VQ_RX);
+}
+
+static int vhost_net_release(struct inode *inode, struct file *f)
+{
+	struct vhost_net *n = f->private_data;
+	struct socket *tx_sock;
+	struct socket *rx_sock;
+
+	vhost_net_stop(n, &tx_sock, &rx_sock);
+	vhost_net_flush(n);
+	vhost_dev_cleanup(&n->dev);
+	if (tx_sock)
+		fput(tx_sock->file);
+	if (rx_sock)
+		fput(rx_sock->file);
+	/* We do an extra flush before freeing memory,
+	 * since jobs can re-queue themselves. */
+	vhost_net_flush(n);
+	kfree(n);
+	return 0;
+}
+
+static struct socket *get_raw_socket(int fd)
+{
+	struct {
+		struct sockaddr_ll sa;
+		char  buf[MAX_ADDR_LEN];
+	} uaddr;
+	int uaddr_len = sizeof uaddr, r;
+	struct socket *sock = sockfd_lookup(fd, &r);
+	if (!sock)
+		return ERR_PTR(-ENOTSOCK);
+
+	/* Parameter checking */
+	if (sock->sk->sk_type != SOCK_RAW) {
+		r = -ESOCKTNOSUPPORT;
+		goto err;
+	}
+
+	r = sock->ops->getname(sock, (struct sockaddr *)&uaddr.sa,
+			       &uaddr_len, 0);
+	if (r)
+		goto err;
+
+	if (uaddr.sa.sll_family != AF_PACKET) {
+		r = -EPFNOSUPPORT;
+		goto err;
+	}
+	return sock;
+err:
+	fput(sock->file);
+	return ERR_PTR(r);
+}
+
+static struct socket *get_tap_socket(int fd)
+{
+	struct file *file = fget(fd);
+	struct socket *sock;
+	if (!file)
+		return ERR_PTR(-EBADF);
+	sock = tun_get_socket(file);
+	if (!IS_ERR(sock))
+		return sock;
+	sock = macvtap_get_socket(file);
+	if (IS_ERR(sock))
+		fput(file);
+	return sock;
+}
+
+static struct socket *get_socket(int fd)
+{
+	struct socket *sock;
+	/* special case to disable backend */
+	if (fd == -1)
+		return NULL;
+	sock = get_raw_socket(fd);
+	if (!IS_ERR(sock))
+		return sock;
+	sock = get_tap_socket(fd);
+	if (!IS_ERR(sock))
+		return sock;
+	return ERR_PTR(-ENOTSOCK);
+}
+
+static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
+{
+	struct socket *sock, *oldsock;
+	struct vhost_virtqueue *vq;
+	int r;
+
+	mutex_lock(&n->dev.mutex);
+	r = vhost_dev_check_owner(&n->dev);
+	if (r)
+		goto err;
+
+	if (index >= VHOST_NET_VQ_MAX) {
+		r = -ENOBUFS;
+		goto err;
+	}
+	vq = n->vqs + index;
+	mutex_lock(&vq->mutex);
+
+	/* Verify that ring has been setup correctly. */
+	if (!vhost_vq_access_ok(vq)) {
+		r = -EFAULT;
+		goto err_vq;
+	}
+	sock = get_socket(fd);
+	if (IS_ERR(sock)) {
+		r = PTR_ERR(sock);
+		goto err_vq;
+	}
+
+	/* start polling new socket */
+	oldsock = vq->private_data;
+	if (sock == oldsock)
+		goto done;
+
+	vhost_net_disable_vq(n, vq);
+	rcu_assign_pointer(vq->private_data, sock);
+	vhost_net_enable_vq(n, vq);
+done:
+	if (oldsock) {
+		vhost_net_flush_vq(n, index);
+		fput(oldsock->file);
+	}
+
+err_vq:
+	mutex_unlock(&vq->mutex);
+err:
+	mutex_unlock(&n->dev.mutex);
+	return r;
+}
+
+static long vhost_net_reset_owner(struct vhost_net *n)
+{
+	struct socket *tx_sock = NULL;
+	struct socket *rx_sock = NULL;
+	long err;
+	mutex_lock(&n->dev.mutex);
+	err = vhost_dev_check_owner(&n->dev);
+	if (err)
+		goto done;
+	vhost_net_stop(n, &tx_sock, &rx_sock);
+	vhost_net_flush(n);
+	err = vhost_dev_reset_owner(&n->dev);
+done:
+	mutex_unlock(&n->dev.mutex);
+	if (tx_sock)
+		fput(tx_sock->file);
+	if (rx_sock)
+		fput(rx_sock->file);
+	return err;
+}
+
+static int vhost_net_set_features(struct vhost_net *n, u64 features)
+{
+	size_t hdr_size = features & (1 << VHOST_NET_F_VIRTIO_NET_HDR) ?
+		sizeof(struct virtio_net_hdr) : 0;
+	int i;
+	mutex_lock(&n->dev.mutex);
+	if ((features & (1 << VHOST_F_LOG_ALL)) &&
+	    !vhost_log_access_ok(&n->dev)) {
+		mutex_unlock(&n->dev.mutex);
+		return -EFAULT;
+	}
+	n->dev.acked_features = features;
+	smp_wmb();
+	for (i = 0; i < VHOST_NET_VQ_MAX; ++i) {
+		mutex_lock(&n->vqs[i].mutex);
+		n->vqs[i].hdr_size = hdr_size;
+		mutex_unlock(&n->vqs[i].mutex);
+	}
+	vhost_net_flush(n);
+	mutex_unlock(&n->dev.mutex);
+	return 0;
+}
+
+static long vhost_net_ioctl(struct file *f, unsigned int ioctl,
+			    unsigned long arg)
+{
+	struct vhost_net *n = f->private_data;
+	void __user *argp = (void __user *)arg;
+	u64 __user *featurep = argp;
+	struct vhost_vring_file backend;
+	u64 features;
+	int r;
+	switch (ioctl) {
+	case VHOST_NET_SET_BACKEND:
+		r = copy_from_user(&backend, argp, sizeof backend);
+		if (r < 0)
+			return r;
+		return vhost_net_set_backend(n, backend.index, backend.fd);
+	case VHOST_GET_FEATURES:
+		features = VHOST_FEATURES;
+		return copy_to_user(featurep, &features, sizeof features);
+	case VHOST_SET_FEATURES:
+		r = copy_from_user(&features, featurep, sizeof features);
+		if (r < 0)
+			return r;
+		if (features & ~VHOST_FEATURES)
+			return -EOPNOTSUPP;
+		return vhost_net_set_features(n, features);
+	case VHOST_RESET_OWNER:
+		return vhost_net_reset_owner(n);
+	default:
+		mutex_lock(&n->dev.mutex);
+		r = vhost_dev_ioctl(&n->dev, ioctl, arg);
+		vhost_net_flush(n);
+		mutex_unlock(&n->dev.mutex);
+		return r;
+	}
+}
+
+#ifdef CONFIG_COMPAT
+static long vhost_net_compat_ioctl(struct file *f, unsigned int ioctl,
+				   unsigned long arg)
+{
+	return vhost_net_ioctl(f, ioctl, (unsigned long)compat_ptr(arg));
+}
+#endif
+
+const static struct file_operations vhost_net_fops = {
+	.owner          = THIS_MODULE,
+	.release        = vhost_net_release,
+	.unlocked_ioctl = vhost_net_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl   = vhost_net_compat_ioctl,
+#endif
+	.open           = vhost_net_open,
+};
+
+static struct miscdevice vhost_net_misc = {
+	VHOST_NET_MINOR,
+	"vhost-net",
+	&vhost_net_fops,
+};
+
+int vhost_net_init(void)
+{
+	int r = vhost_init();
+	if (r)
+		goto err_init;
+	r = misc_register(&vhost_net_misc);
+	if (r)
+		goto err_reg;
+	return 0;
+err_reg:
+	vhost_cleanup();
+err_init:
+	return r;
+
+}
+module_init(vhost_net_init);
+
+void vhost_net_exit(void)
+{
+	misc_deregister(&vhost_net_misc);
+	vhost_cleanup();
+}
+module_exit(vhost_net_exit);
+
+MODULE_VERSION("0.0.1");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Michael S. Tsirkin");
+MODULE_DESCRIPTION("Host kernel accelerator for virtio net");
diff -druNp linux-libre-2.6.33-gnu1/drivers/vhost/vhost.c linux-libre-2.6.34-gnu1/drivers/vhost/vhost.c
--- linux-libre-2.6.33-gnu1/drivers/vhost/vhost.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/vhost/vhost.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1120 @@
+/* Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2006 Rusty Russell IBM Corporation
+ *
+ * Author: Michael S. Tsirkin <mst@redhat.com>
+ *
+ * Inspiration, some code, and most witty comments come from
+ * Documentation/lguest/lguest.c, by Rusty Russell
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ *
+ * Generic code for virtio server in host kernel.
+ */
+
+#include <linux/eventfd.h>
+#include <linux/vhost.h>
+#include <linux/virtio_net.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/rcupdate.h>
+#include <linux/poll.h>
+#include <linux/file.h>
+#include <linux/highmem.h>
+#include <linux/slab.h>
+
+#include <linux/net.h>
+#include <linux/if_packet.h>
+#include <linux/if_arp.h>
+
+#include <net/sock.h>
+
+#include "vhost.h"
+
+enum {
+	VHOST_MEMORY_MAX_NREGIONS = 64,
+	VHOST_MEMORY_F_LOG = 0x1,
+};
+
+static struct workqueue_struct *vhost_workqueue;
+
+static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh,
+			    poll_table *pt)
+{
+	struct vhost_poll *poll;
+	poll = container_of(pt, struct vhost_poll, table);
+
+	poll->wqh = wqh;
+	add_wait_queue(wqh, &poll->wait);
+}
+
+static int vhost_poll_wakeup(wait_queue_t *wait, unsigned mode, int sync,
+			     void *key)
+{
+	struct vhost_poll *poll;
+	poll = container_of(wait, struct vhost_poll, wait);
+	if (!((unsigned long)key & poll->mask))
+		return 0;
+
+	queue_work(vhost_workqueue, &poll->work);
+	return 0;
+}
+
+/* Init poll structure */
+void vhost_poll_init(struct vhost_poll *poll, work_func_t func,
+		     unsigned long mask)
+{
+	INIT_WORK(&poll->work, func);
+	init_waitqueue_func_entry(&poll->wait, vhost_poll_wakeup);
+	init_poll_funcptr(&poll->table, vhost_poll_func);
+	poll->mask = mask;
+}
+
+/* Start polling a file. We add ourselves to file's wait queue. The caller must
+ * keep a reference to a file until after vhost_poll_stop is called. */
+void vhost_poll_start(struct vhost_poll *poll, struct file *file)
+{
+	unsigned long mask;
+	mask = file->f_op->poll(file, &poll->table);
+	if (mask)
+		vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask);
+}
+
+/* Stop polling a file. After this function returns, it becomes safe to drop the
+ * file reference. You must also flush afterwards. */
+void vhost_poll_stop(struct vhost_poll *poll)
+{
+	remove_wait_queue(poll->wqh, &poll->wait);
+}
+
+/* Flush any work that has been scheduled. When calling this, don't hold any
+ * locks that are also used by the callback. */
+void vhost_poll_flush(struct vhost_poll *poll)
+{
+	flush_work(&poll->work);
+}
+
+void vhost_poll_queue(struct vhost_poll *poll)
+{
+	queue_work(vhost_workqueue, &poll->work);
+}
+
+static void vhost_vq_reset(struct vhost_dev *dev,
+			   struct vhost_virtqueue *vq)
+{
+	vq->num = 1;
+	vq->desc = NULL;
+	vq->avail = NULL;
+	vq->used = NULL;
+	vq->last_avail_idx = 0;
+	vq->avail_idx = 0;
+	vq->last_used_idx = 0;
+	vq->used_flags = 0;
+	vq->used_flags = 0;
+	vq->log_used = false;
+	vq->log_addr = -1ull;
+	vq->hdr_size = 0;
+	vq->private_data = NULL;
+	vq->log_base = NULL;
+	vq->error_ctx = NULL;
+	vq->error = NULL;
+	vq->kick = NULL;
+	vq->call_ctx = NULL;
+	vq->call = NULL;
+	vq->log_ctx = NULL;
+}
+
+long vhost_dev_init(struct vhost_dev *dev,
+		    struct vhost_virtqueue *vqs, int nvqs)
+{
+	int i;
+	dev->vqs = vqs;
+	dev->nvqs = nvqs;
+	mutex_init(&dev->mutex);
+	dev->log_ctx = NULL;
+	dev->log_file = NULL;
+	dev->memory = NULL;
+	dev->mm = NULL;
+
+	for (i = 0; i < dev->nvqs; ++i) {
+		dev->vqs[i].dev = dev;
+		mutex_init(&dev->vqs[i].mutex);
+		vhost_vq_reset(dev, dev->vqs + i);
+		if (dev->vqs[i].handle_kick)
+			vhost_poll_init(&dev->vqs[i].poll,
+					dev->vqs[i].handle_kick,
+					POLLIN);
+	}
+	return 0;
+}
+
+/* Caller should have device mutex */
+long vhost_dev_check_owner(struct vhost_dev *dev)
+{
+	/* Are you the owner? If not, I don't think you mean to do that */
+	return dev->mm == current->mm ? 0 : -EPERM;
+}
+
+/* Caller should have device mutex */
+static long vhost_dev_set_owner(struct vhost_dev *dev)
+{
+	/* Is there an owner already? */
+	if (dev->mm)
+		return -EBUSY;
+	/* No owner, become one */
+	dev->mm = get_task_mm(current);
+	return 0;
+}
+
+/* Caller should have device mutex */
+long vhost_dev_reset_owner(struct vhost_dev *dev)
+{
+	struct vhost_memory *memory;
+
+	/* Restore memory to default empty mapping. */
+	memory = kmalloc(offsetof(struct vhost_memory, regions), GFP_KERNEL);
+	if (!memory)
+		return -ENOMEM;
+
+	vhost_dev_cleanup(dev);
+
+	memory->nregions = 0;
+	dev->memory = memory;
+	return 0;
+}
+
+/* Caller should have device mutex */
+void vhost_dev_cleanup(struct vhost_dev *dev)
+{
+	int i;
+	for (i = 0; i < dev->nvqs; ++i) {
+		if (dev->vqs[i].kick && dev->vqs[i].handle_kick) {
+			vhost_poll_stop(&dev->vqs[i].poll);
+			vhost_poll_flush(&dev->vqs[i].poll);
+		}
+		if (dev->vqs[i].error_ctx)
+			eventfd_ctx_put(dev->vqs[i].error_ctx);
+		if (dev->vqs[i].error)
+			fput(dev->vqs[i].error);
+		if (dev->vqs[i].kick)
+			fput(dev->vqs[i].kick);
+		if (dev->vqs[i].call_ctx)
+			eventfd_ctx_put(dev->vqs[i].call_ctx);
+		if (dev->vqs[i].call)
+			fput(dev->vqs[i].call);
+		vhost_vq_reset(dev, dev->vqs + i);
+	}
+	if (dev->log_ctx)
+		eventfd_ctx_put(dev->log_ctx);
+	dev->log_ctx = NULL;
+	if (dev->log_file)
+		fput(dev->log_file);
+	dev->log_file = NULL;
+	/* No one will access memory at this point */
+	kfree(dev->memory);
+	dev->memory = NULL;
+	if (dev->mm)
+		mmput(dev->mm);
+	dev->mm = NULL;
+}
+
+static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz)
+{
+	u64 a = addr / VHOST_PAGE_SIZE / 8;
+	/* Make sure 64 bit math will not overflow. */
+	if (a > ULONG_MAX - (unsigned long)log_base ||
+	    a + (unsigned long)log_base > ULONG_MAX)
+		return -EFAULT;
+
+	return access_ok(VERIFY_WRITE, log_base + a,
+			 (sz + VHOST_PAGE_SIZE * 8 - 1) / VHOST_PAGE_SIZE / 8);
+}
+
+/* Caller should have vq mutex and device mutex. */
+static int vq_memory_access_ok(void __user *log_base, struct vhost_memory *mem,
+			       int log_all)
+{
+	int i;
+
+        if (!mem)
+                return 0;
+
+	for (i = 0; i < mem->nregions; ++i) {
+		struct vhost_memory_region *m = mem->regions + i;
+		unsigned long a = m->userspace_addr;
+		if (m->memory_size > ULONG_MAX)
+			return 0;
+		else if (!access_ok(VERIFY_WRITE, (void __user *)a,
+				    m->memory_size))
+			return 0;
+		else if (log_all && !log_access_ok(log_base,
+						   m->guest_phys_addr,
+						   m->memory_size))
+			return 0;
+	}
+	return 1;
+}
+
+/* Can we switch to this memory table? */
+/* Caller should have device mutex but not vq mutex */
+static int memory_access_ok(struct vhost_dev *d, struct vhost_memory *mem,
+			    int log_all)
+{
+	int i;
+	for (i = 0; i < d->nvqs; ++i) {
+		int ok;
+		mutex_lock(&d->vqs[i].mutex);
+		/* If ring is inactive, will check when it's enabled. */
+		if (d->vqs[i].private_data)
+			ok = vq_memory_access_ok(d->vqs[i].log_base, mem,
+						 log_all);
+		else
+			ok = 1;
+		mutex_unlock(&d->vqs[i].mutex);
+		if (!ok)
+			return 0;
+	}
+	return 1;
+}
+
+static int vq_access_ok(unsigned int num,
+			struct vring_desc __user *desc,
+			struct vring_avail __user *avail,
+			struct vring_used __user *used)
+{
+	return access_ok(VERIFY_READ, desc, num * sizeof *desc) &&
+	       access_ok(VERIFY_READ, avail,
+			 sizeof *avail + num * sizeof *avail->ring) &&
+	       access_ok(VERIFY_WRITE, used,
+			sizeof *used + num * sizeof *used->ring);
+}
+
+/* Can we log writes? */
+/* Caller should have device mutex but not vq mutex */
+int vhost_log_access_ok(struct vhost_dev *dev)
+{
+	return memory_access_ok(dev, dev->memory, 1);
+}
+
+/* Verify access for write logging. */
+/* Caller should have vq mutex and device mutex */
+static int vq_log_access_ok(struct vhost_virtqueue *vq, void __user *log_base)
+{
+	return vq_memory_access_ok(log_base, vq->dev->memory,
+			    vhost_has_feature(vq->dev, VHOST_F_LOG_ALL)) &&
+		(!vq->log_used || log_access_ok(log_base, vq->log_addr,
+					sizeof *vq->used +
+					vq->num * sizeof *vq->used->ring));
+}
+
+/* Can we start vq? */
+/* Caller should have vq mutex and device mutex */
+int vhost_vq_access_ok(struct vhost_virtqueue *vq)
+{
+	return vq_access_ok(vq->num, vq->desc, vq->avail, vq->used) &&
+		vq_log_access_ok(vq, vq->log_base);
+}
+
+static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
+{
+	struct vhost_memory mem, *newmem, *oldmem;
+	unsigned long size = offsetof(struct vhost_memory, regions);
+	long r;
+	r = copy_from_user(&mem, m, size);
+	if (r)
+		return r;
+	if (mem.padding)
+		return -EOPNOTSUPP;
+	if (mem.nregions > VHOST_MEMORY_MAX_NREGIONS)
+		return -E2BIG;
+	newmem = kmalloc(size + mem.nregions * sizeof *m->regions, GFP_KERNEL);
+	if (!newmem)
+		return -ENOMEM;
+
+	memcpy(newmem, &mem, size);
+	r = copy_from_user(newmem->regions, m->regions,
+			   mem.nregions * sizeof *m->regions);
+	if (r) {
+		kfree(newmem);
+		return r;
+	}
+
+	if (!memory_access_ok(d, newmem, vhost_has_feature(d, VHOST_F_LOG_ALL)))
+		return -EFAULT;
+	oldmem = d->memory;
+	rcu_assign_pointer(d->memory, newmem);
+	synchronize_rcu();
+	kfree(oldmem);
+	return 0;
+}
+
+static int init_used(struct vhost_virtqueue *vq,
+		     struct vring_used __user *used)
+{
+	int r = put_user(vq->used_flags, &used->flags);
+	if (r)
+		return r;
+	return get_user(vq->last_used_idx, &used->idx);
+}
+
+static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
+{
+	struct file *eventfp, *filep = NULL,
+		    *pollstart = NULL, *pollstop = NULL;
+	struct eventfd_ctx *ctx = NULL;
+	u32 __user *idxp = argp;
+	struct vhost_virtqueue *vq;
+	struct vhost_vring_state s;
+	struct vhost_vring_file f;
+	struct vhost_vring_addr a;
+	u32 idx;
+	long r;
+
+	r = get_user(idx, idxp);
+	if (r < 0)
+		return r;
+	if (idx > d->nvqs)
+		return -ENOBUFS;
+
+	vq = d->vqs + idx;
+
+	mutex_lock(&vq->mutex);
+
+	switch (ioctl) {
+	case VHOST_SET_VRING_NUM:
+		/* Resizing ring with an active backend?
+		 * You don't want to do that. */
+		if (vq->private_data) {
+			r = -EBUSY;
+			break;
+		}
+		r = copy_from_user(&s, argp, sizeof s);
+		if (r < 0)
+			break;
+		if (!s.num || s.num > 0xffff || (s.num & (s.num - 1))) {
+			r = -EINVAL;
+			break;
+		}
+		vq->num = s.num;
+		break;
+	case VHOST_SET_VRING_BASE:
+		/* Moving base with an active backend?
+		 * You don't want to do that. */
+		if (vq->private_data) {
+			r = -EBUSY;
+			break;
+		}
+		r = copy_from_user(&s, argp, sizeof s);
+		if (r < 0)
+			break;
+		if (s.num > 0xffff) {
+			r = -EINVAL;
+			break;
+		}
+		vq->last_avail_idx = s.num;
+		/* Forget the cached index value. */
+		vq->avail_idx = vq->last_avail_idx;
+		break;
+	case VHOST_GET_VRING_BASE:
+		s.index = idx;
+		s.num = vq->last_avail_idx;
+		r = copy_to_user(argp, &s, sizeof s);
+		break;
+	case VHOST_SET_VRING_ADDR:
+		r = copy_from_user(&a, argp, sizeof a);
+		if (r < 0)
+			break;
+		if (a.flags & ~(0x1 << VHOST_VRING_F_LOG)) {
+			r = -EOPNOTSUPP;
+			break;
+		}
+		/* For 32bit, verify that the top 32bits of the user
+		   data are set to zero. */
+		if ((u64)(unsigned long)a.desc_user_addr != a.desc_user_addr ||
+		    (u64)(unsigned long)a.used_user_addr != a.used_user_addr ||
+		    (u64)(unsigned long)a.avail_user_addr != a.avail_user_addr) {
+			r = -EFAULT;
+			break;
+		}
+		if ((a.avail_user_addr & (sizeof *vq->avail->ring - 1)) ||
+		    (a.used_user_addr & (sizeof *vq->used->ring - 1)) ||
+		    (a.log_guest_addr & (sizeof *vq->used->ring - 1))) {
+			r = -EINVAL;
+			break;
+		}
+
+		/* We only verify access here if backend is configured.
+		 * If it is not, we don't as size might not have been setup.
+		 * We will verify when backend is configured. */
+		if (vq->private_data) {
+			if (!vq_access_ok(vq->num,
+				(void __user *)(unsigned long)a.desc_user_addr,
+				(void __user *)(unsigned long)a.avail_user_addr,
+				(void __user *)(unsigned long)a.used_user_addr)) {
+				r = -EINVAL;
+				break;
+			}
+
+			/* Also validate log access for used ring if enabled. */
+			if ((a.flags & (0x1 << VHOST_VRING_F_LOG)) &&
+			    !log_access_ok(vq->log_base, a.log_guest_addr,
+					   sizeof *vq->used +
+					   vq->num * sizeof *vq->used->ring)) {
+				r = -EINVAL;
+				break;
+			}
+		}
+
+		r = init_used(vq, (struct vring_used __user *)(unsigned long)
+			      a.used_user_addr);
+		if (r)
+			break;
+		vq->log_used = !!(a.flags & (0x1 << VHOST_VRING_F_LOG));
+		vq->desc = (void __user *)(unsigned long)a.desc_user_addr;
+		vq->avail = (void __user *)(unsigned long)a.avail_user_addr;
+		vq->log_addr = a.log_guest_addr;
+		vq->used = (void __user *)(unsigned long)a.used_user_addr;
+		break;
+	case VHOST_SET_VRING_KICK:
+		r = copy_from_user(&f, argp, sizeof f);
+		if (r < 0)
+			break;
+		eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd);
+		if (IS_ERR(eventfp)) {
+			r = PTR_ERR(eventfp);
+			break;
+		}
+		if (eventfp != vq->kick) {
+			pollstop = filep = vq->kick;
+			pollstart = vq->kick = eventfp;
+		} else
+			filep = eventfp;
+		break;
+	case VHOST_SET_VRING_CALL:
+		r = copy_from_user(&f, argp, sizeof f);
+		if (r < 0)
+			break;
+		eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd);
+		if (IS_ERR(eventfp)) {
+			r = PTR_ERR(eventfp);
+			break;
+		}
+		if (eventfp != vq->call) {
+			filep = vq->call;
+			ctx = vq->call_ctx;
+			vq->call = eventfp;
+			vq->call_ctx = eventfp ?
+				eventfd_ctx_fileget(eventfp) : NULL;
+		} else
+			filep = eventfp;
+		break;
+	case VHOST_SET_VRING_ERR:
+		r = copy_from_user(&f, argp, sizeof f);
+		if (r < 0)
+			break;
+		eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd);
+		if (IS_ERR(eventfp)) {
+			r = PTR_ERR(eventfp);
+			break;
+		}
+		if (eventfp != vq->error) {
+			filep = vq->error;
+			vq->error = eventfp;
+			ctx = vq->error_ctx;
+			vq->error_ctx = eventfp ?
+				eventfd_ctx_fileget(eventfp) : NULL;
+		} else
+			filep = eventfp;
+		break;
+	default:
+		r = -ENOIOCTLCMD;
+	}
+
+	if (pollstop && vq->handle_kick)
+		vhost_poll_stop(&vq->poll);
+
+	if (ctx)
+		eventfd_ctx_put(ctx);
+	if (filep)
+		fput(filep);
+
+	if (pollstart && vq->handle_kick)
+		vhost_poll_start(&vq->poll, vq->kick);
+
+	mutex_unlock(&vq->mutex);
+
+	if (pollstop && vq->handle_kick)
+		vhost_poll_flush(&vq->poll);
+	return r;
+}
+
+/* Caller must have device mutex */
+long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, unsigned long arg)
+{
+	void __user *argp = (void __user *)arg;
+	struct file *eventfp, *filep = NULL;
+	struct eventfd_ctx *ctx = NULL;
+	u64 p;
+	long r;
+	int i, fd;
+
+	/* If you are not the owner, you can become one */
+	if (ioctl == VHOST_SET_OWNER) {
+		r = vhost_dev_set_owner(d);
+		goto done;
+	}
+
+	/* You must be the owner to do anything else */
+	r = vhost_dev_check_owner(d);
+	if (r)
+		goto done;
+
+	switch (ioctl) {
+	case VHOST_SET_MEM_TABLE:
+		r = vhost_set_memory(d, argp);
+		break;
+	case VHOST_SET_LOG_BASE:
+		r = copy_from_user(&p, argp, sizeof p);
+		if (r < 0)
+			break;
+		if ((u64)(unsigned long)p != p) {
+			r = -EFAULT;
+			break;
+		}
+		for (i = 0; i < d->nvqs; ++i) {
+			struct vhost_virtqueue *vq;
+			void __user *base = (void __user *)(unsigned long)p;
+			vq = d->vqs + i;
+			mutex_lock(&vq->mutex);
+			/* If ring is inactive, will check when it's enabled. */
+			if (vq->private_data && !vq_log_access_ok(vq, base))
+				r = -EFAULT;
+			else
+				vq->log_base = base;
+			mutex_unlock(&vq->mutex);
+		}
+		break;
+	case VHOST_SET_LOG_FD:
+		r = get_user(fd, (int __user *)argp);
+		if (r < 0)
+			break;
+		eventfp = fd == -1 ? NULL : eventfd_fget(fd);
+		if (IS_ERR(eventfp)) {
+			r = PTR_ERR(eventfp);
+			break;
+		}
+		if (eventfp != d->log_file) {
+			filep = d->log_file;
+			ctx = d->log_ctx;
+			d->log_ctx = eventfp ?
+				eventfd_ctx_fileget(eventfp) : NULL;
+		} else
+			filep = eventfp;
+		for (i = 0; i < d->nvqs; ++i) {
+			mutex_lock(&d->vqs[i].mutex);
+			d->vqs[i].log_ctx = d->log_ctx;
+			mutex_unlock(&d->vqs[i].mutex);
+		}
+		if (ctx)
+			eventfd_ctx_put(ctx);
+		if (filep)
+			fput(filep);
+		break;
+	default:
+		r = vhost_set_vring(d, ioctl, argp);
+		break;
+	}
+done:
+	return r;
+}
+
+static const struct vhost_memory_region *find_region(struct vhost_memory *mem,
+						     __u64 addr, __u32 len)
+{
+	struct vhost_memory_region *reg;
+	int i;
+	/* linear search is not brilliant, but we really have on the order of 6
+	 * regions in practice */
+	for (i = 0; i < mem->nregions; ++i) {
+		reg = mem->regions + i;
+		if (reg->guest_phys_addr <= addr &&
+		    reg->guest_phys_addr + reg->memory_size - 1 >= addr)
+			return reg;
+	}
+	return NULL;
+}
+
+/* TODO: This is really inefficient.  We need something like get_user()
+ * (instruction directly accesses the data, with an exception table entry
+ * returning -EFAULT). See Documentation/x86/exception-tables.txt.
+ */
+static int set_bit_to_user(int nr, void __user *addr)
+{
+	unsigned long log = (unsigned long)addr;
+	struct page *page;
+	void *base;
+	int bit = nr + (log % PAGE_SIZE) * 8;
+	int r;
+	r = get_user_pages_fast(log, 1, 1, &page);
+	if (r < 0)
+		return r;
+	BUG_ON(r != 1);
+	base = kmap_atomic(page, KM_USER0);
+	set_bit(bit, base);
+	kunmap_atomic(base, KM_USER0);
+	set_page_dirty_lock(page);
+	put_page(page);
+	return 0;
+}
+
+static int log_write(void __user *log_base,
+		     u64 write_address, u64 write_length)
+{
+	int r;
+	if (!write_length)
+		return 0;
+	write_address /= VHOST_PAGE_SIZE;
+	for (;;) {
+		u64 base = (u64)(unsigned long)log_base;
+		u64 log = base + write_address / 8;
+		int bit = write_address % 8;
+		if ((u64)(unsigned long)log != log)
+			return -EFAULT;
+		r = set_bit_to_user(bit, (void __user *)(unsigned long)log);
+		if (r < 0)
+			return r;
+		if (write_length <= VHOST_PAGE_SIZE)
+			break;
+		write_length -= VHOST_PAGE_SIZE;
+		write_address += VHOST_PAGE_SIZE;
+	}
+	return r;
+}
+
+int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log,
+		    unsigned int log_num, u64 len)
+{
+	int i, r;
+
+	/* Make sure data written is seen before log. */
+	smp_wmb();
+	for (i = 0; i < log_num; ++i) {
+		u64 l = min(log[i].len, len);
+		r = log_write(vq->log_base, log[i].addr, l);
+		if (r < 0)
+			return r;
+		len -= l;
+		if (!len)
+			return 0;
+	}
+	if (vq->log_ctx)
+		eventfd_signal(vq->log_ctx, 1);
+	/* Length written exceeds what we have stored. This is a bug. */
+	BUG();
+	return 0;
+}
+
+int translate_desc(struct vhost_dev *dev, u64 addr, u32 len,
+		   struct iovec iov[], int iov_size)
+{
+	const struct vhost_memory_region *reg;
+	struct vhost_memory *mem;
+	struct iovec *_iov;
+	u64 s = 0;
+	int ret = 0;
+
+	rcu_read_lock();
+
+	mem = rcu_dereference(dev->memory);
+	while ((u64)len > s) {
+		u64 size;
+		if (ret >= iov_size) {
+			ret = -ENOBUFS;
+			break;
+		}
+		reg = find_region(mem, addr, len);
+		if (!reg) {
+			ret = -EFAULT;
+			break;
+		}
+		_iov = iov + ret;
+		size = reg->memory_size - addr + reg->guest_phys_addr;
+		_iov->iov_len = min((u64)len, size);
+		_iov->iov_base = (void *)(unsigned long)
+			(reg->userspace_addr + addr - reg->guest_phys_addr);
+		s += size;
+		addr += size;
+		++ret;
+	}
+
+	rcu_read_unlock();
+	return ret;
+}
+
+/* Each buffer in the virtqueues is actually a chain of descriptors.  This
+ * function returns the next descriptor in the chain,
+ * or -1U if we're at the end. */
+static unsigned next_desc(struct vring_desc *desc)
+{
+	unsigned int next;
+
+	/* If this descriptor says it doesn't chain, we're done. */
+	if (!(desc->flags & VRING_DESC_F_NEXT))
+		return -1U;
+
+	/* Check they're not leading us off end of descriptors. */
+	next = desc->next;
+	/* Make sure compiler knows to grab that: we don't want it changing! */
+	/* We will use the result as an index in an array, so most
+	 * architectures only need a compiler barrier here. */
+	read_barrier_depends();
+
+	return next;
+}
+
+static unsigned get_indirect(struct vhost_dev *dev, struct vhost_virtqueue *vq,
+			     struct iovec iov[], unsigned int iov_size,
+			     unsigned int *out_num, unsigned int *in_num,
+			     struct vhost_log *log, unsigned int *log_num,
+			     struct vring_desc *indirect)
+{
+	struct vring_desc desc;
+	unsigned int i = 0, count, found = 0;
+	int ret;
+
+	/* Sanity check */
+	if (indirect->len % sizeof desc) {
+		vq_err(vq, "Invalid length in indirect descriptor: "
+		       "len 0x%llx not multiple of 0x%zx\n",
+		       (unsigned long long)indirect->len,
+		       sizeof desc);
+		return -EINVAL;
+	}
+
+	ret = translate_desc(dev, indirect->addr, indirect->len, vq->indirect,
+			     ARRAY_SIZE(vq->indirect));
+	if (ret < 0) {
+		vq_err(vq, "Translation failure %d in indirect.\n", ret);
+		return ret;
+	}
+
+	/* We will use the result as an address to read from, so most
+	 * architectures only need a compiler barrier here. */
+	read_barrier_depends();
+
+	count = indirect->len / sizeof desc;
+	/* Buffers are chained via a 16 bit next field, so
+	 * we can have at most 2^16 of these. */
+	if (count > USHORT_MAX + 1) {
+		vq_err(vq, "Indirect buffer length too big: %d\n",
+		       indirect->len);
+		return -E2BIG;
+	}
+
+	do {
+		unsigned iov_count = *in_num + *out_num;
+		if (++found > count) {
+			vq_err(vq, "Loop detected: last one at %u "
+			       "indirect size %u\n",
+			       i, count);
+			return -EINVAL;
+		}
+		if (memcpy_fromiovec((unsigned char *)&desc, vq->indirect,
+				     sizeof desc)) {
+			vq_err(vq, "Failed indirect descriptor: idx %d, %zx\n",
+			       i, (size_t)indirect->addr + i * sizeof desc);
+			return -EINVAL;
+		}
+		if (desc.flags & VRING_DESC_F_INDIRECT) {
+			vq_err(vq, "Nested indirect descriptor: idx %d, %zx\n",
+			       i, (size_t)indirect->addr + i * sizeof desc);
+			return -EINVAL;
+		}
+
+		ret = translate_desc(dev, desc.addr, desc.len, iov + iov_count,
+				     iov_size - iov_count);
+		if (ret < 0) {
+			vq_err(vq, "Translation failure %d indirect idx %d\n",
+			       ret, i);
+			return ret;
+		}
+		/* If this is an input descriptor, increment that count. */
+		if (desc.flags & VRING_DESC_F_WRITE) {
+			*in_num += ret;
+			if (unlikely(log)) {
+				log[*log_num].addr = desc.addr;
+				log[*log_num].len = desc.len;
+				++*log_num;
+			}
+		} else {
+			/* If it's an output descriptor, they're all supposed
+			 * to come before any input descriptors. */
+			if (*in_num) {
+				vq_err(vq, "Indirect descriptor "
+				       "has out after in: idx %d\n", i);
+				return -EINVAL;
+			}
+			*out_num += ret;
+		}
+	} while ((i = next_desc(&desc)) != -1);
+	return 0;
+}
+
+/* This looks in the virtqueue and for the first available buffer, and converts
+ * it to an iovec for convenient access.  Since descriptors consist of some
+ * number of output then some number of input descriptors, it's actually two
+ * iovecs, but we pack them into one and note how many of each there were.
+ *
+ * This function returns the descriptor number found, or vq->num (which
+ * is never a valid descriptor number) if none was found. */
+unsigned vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq,
+			   struct iovec iov[], unsigned int iov_size,
+			   unsigned int *out_num, unsigned int *in_num,
+			   struct vhost_log *log, unsigned int *log_num)
+{
+	struct vring_desc desc;
+	unsigned int i, head, found = 0;
+	u16 last_avail_idx;
+	int ret;
+
+	/* Check it isn't doing very strange things with descriptor numbers. */
+	last_avail_idx = vq->last_avail_idx;
+	if (get_user(vq->avail_idx, &vq->avail->idx)) {
+		vq_err(vq, "Failed to access avail idx at %p\n",
+		       &vq->avail->idx);
+		return vq->num;
+	}
+
+	if ((u16)(vq->avail_idx - last_avail_idx) > vq->num) {
+		vq_err(vq, "Guest moved used index from %u to %u",
+		       last_avail_idx, vq->avail_idx);
+		return vq->num;
+	}
+
+	/* If there's nothing new since last we looked, return invalid. */
+	if (vq->avail_idx == last_avail_idx)
+		return vq->num;
+
+	/* Only get avail ring entries after they have been exposed by guest. */
+	smp_rmb();
+
+	/* Grab the next descriptor number they're advertising, and increment
+	 * the index we've seen. */
+	if (get_user(head, &vq->avail->ring[last_avail_idx % vq->num])) {
+		vq_err(vq, "Failed to read head: idx %d address %p\n",
+		       last_avail_idx,
+		       &vq->avail->ring[last_avail_idx % vq->num]);
+		return vq->num;
+	}
+
+	/* If their number is silly, that's an error. */
+	if (head >= vq->num) {
+		vq_err(vq, "Guest says index %u > %u is available",
+		       head, vq->num);
+		return vq->num;
+	}
+
+	/* When we start there are none of either input nor output. */
+	*out_num = *in_num = 0;
+	if (unlikely(log))
+		*log_num = 0;
+
+	i = head;
+	do {
+		unsigned iov_count = *in_num + *out_num;
+		if (i >= vq->num) {
+			vq_err(vq, "Desc index is %u > %u, head = %u",
+			       i, vq->num, head);
+			return vq->num;
+		}
+		if (++found > vq->num) {
+			vq_err(vq, "Loop detected: last one at %u "
+			       "vq size %u head %u\n",
+			       i, vq->num, head);
+			return vq->num;
+		}
+		ret = copy_from_user(&desc, vq->desc + i, sizeof desc);
+		if (ret) {
+			vq_err(vq, "Failed to get descriptor: idx %d addr %p\n",
+			       i, vq->desc + i);
+			return vq->num;
+		}
+		if (desc.flags & VRING_DESC_F_INDIRECT) {
+			ret = get_indirect(dev, vq, iov, iov_size,
+					   out_num, in_num,
+					   log, log_num, &desc);
+			if (ret < 0) {
+				vq_err(vq, "Failure detected "
+				       "in indirect descriptor at idx %d\n", i);
+				return vq->num;
+			}
+			continue;
+		}
+
+		ret = translate_desc(dev, desc.addr, desc.len, iov + iov_count,
+				     iov_size - iov_count);
+		if (ret < 0) {
+			vq_err(vq, "Translation failure %d descriptor idx %d\n",
+			       ret, i);
+			return vq->num;
+		}
+		if (desc.flags & VRING_DESC_F_WRITE) {
+			/* If this is an input descriptor,
+			 * increment that count. */
+			*in_num += ret;
+			if (unlikely(log)) {
+				log[*log_num].addr = desc.addr;
+				log[*log_num].len = desc.len;
+				++*log_num;
+			}
+		} else {
+			/* If it's an output descriptor, they're all supposed
+			 * to come before any input descriptors. */
+			if (*in_num) {
+				vq_err(vq, "Descriptor has out after in: "
+				       "idx %d\n", i);
+				return vq->num;
+			}
+			*out_num += ret;
+		}
+	} while ((i = next_desc(&desc)) != -1);
+
+	/* On success, increment avail index. */
+	vq->last_avail_idx++;
+	return head;
+}
+
+/* Reverse the effect of vhost_get_vq_desc. Useful for error handling. */
+void vhost_discard_vq_desc(struct vhost_virtqueue *vq)
+{
+	vq->last_avail_idx--;
+}
+
+/* After we've used one of their buffers, we tell them about it.  We'll then
+ * want to notify the guest, using eventfd. */
+int vhost_add_used(struct vhost_virtqueue *vq, unsigned int head, int len)
+{
+	struct vring_used_elem *used;
+
+	/* The virtqueue contains a ring of used buffers.  Get a pointer to the
+	 * next entry in that used ring. */
+	used = &vq->used->ring[vq->last_used_idx % vq->num];
+	if (put_user(head, &used->id)) {
+		vq_err(vq, "Failed to write used id");
+		return -EFAULT;
+	}
+	if (put_user(len, &used->len)) {
+		vq_err(vq, "Failed to write used len");
+		return -EFAULT;
+	}
+	/* Make sure buffer is written before we update index. */
+	smp_wmb();
+	if (put_user(vq->last_used_idx + 1, &vq->used->idx)) {
+		vq_err(vq, "Failed to increment used idx");
+		return -EFAULT;
+	}
+	if (unlikely(vq->log_used)) {
+		/* Make sure data is seen before log. */
+		smp_wmb();
+		/* Log used ring entry write. */
+		log_write(vq->log_base,
+			  vq->log_addr + ((void *)used - (void *)vq->used),
+			  sizeof *used);
+		/* Log used index update. */
+		log_write(vq->log_base,
+			  vq->log_addr + offsetof(struct vring_used, idx),
+			  sizeof vq->used->idx);
+		if (vq->log_ctx)
+			eventfd_signal(vq->log_ctx, 1);
+	}
+	vq->last_used_idx++;
+	return 0;
+}
+
+/* This actually signals the guest, using eventfd. */
+void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq)
+{
+	__u16 flags;
+	/* Flush out used index updates. This is paired
+	 * with the barrier that the Guest executes when enabling
+	 * interrupts. */
+	smp_mb();
+
+	if (get_user(flags, &vq->avail->flags)) {
+		vq_err(vq, "Failed to get flags");
+		return;
+	}
+
+	/* If they don't want an interrupt, don't signal, unless empty. */
+	if ((flags & VRING_AVAIL_F_NO_INTERRUPT) &&
+	    (vq->avail_idx != vq->last_avail_idx ||
+	     !vhost_has_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY)))
+		return;
+
+	/* Signal the Guest tell them we used something up. */
+	if (vq->call_ctx)
+		eventfd_signal(vq->call_ctx, 1);
+}
+
+/* And here's the combo meal deal.  Supersize me! */
+void vhost_add_used_and_signal(struct vhost_dev *dev,
+			       struct vhost_virtqueue *vq,
+			       unsigned int head, int len)
+{
+	vhost_add_used(vq, head, len);
+	vhost_signal(dev, vq);
+}
+
+/* OK, now we need to know about added descriptors. */
+bool vhost_enable_notify(struct vhost_virtqueue *vq)
+{
+	u16 avail_idx;
+	int r;
+	if (!(vq->used_flags & VRING_USED_F_NO_NOTIFY))
+		return false;
+	vq->used_flags &= ~VRING_USED_F_NO_NOTIFY;
+	r = put_user(vq->used_flags, &vq->used->flags);
+	if (r) {
+		vq_err(vq, "Failed to enable notification at %p: %d\n",
+		       &vq->used->flags, r);
+		return false;
+	}
+	/* They could have slipped one in as we were doing that: make
+	 * sure it's written, then check again. */
+	smp_mb();
+	r = get_user(avail_idx, &vq->avail->idx);
+	if (r) {
+		vq_err(vq, "Failed to check avail idx at %p: %d\n",
+		       &vq->avail->idx, r);
+		return false;
+	}
+
+	return avail_idx != vq->last_avail_idx;
+}
+
+/* We don't need to be notified again. */
+void vhost_disable_notify(struct vhost_virtqueue *vq)
+{
+	int r;
+	if (vq->used_flags & VRING_USED_F_NO_NOTIFY)
+		return;
+	vq->used_flags |= VRING_USED_F_NO_NOTIFY;
+	r = put_user(vq->used_flags, &vq->used->flags);
+	if (r)
+		vq_err(vq, "Failed to enable notification at %p: %d\n",
+		       &vq->used->flags, r);
+}
+
+int vhost_init(void)
+{
+	vhost_workqueue = create_singlethread_workqueue("vhost");
+	if (!vhost_workqueue)
+		return -ENOMEM;
+	return 0;
+}
+
+void vhost_cleanup(void)
+{
+	destroy_workqueue(vhost_workqueue);
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/vhost/vhost.h linux-libre-2.6.34-gnu1/drivers/vhost/vhost.h
--- linux-libre-2.6.33-gnu1/drivers/vhost/vhost.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/vhost/vhost.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,161 @@
+#ifndef _VHOST_H
+#define _VHOST_H
+
+#include <linux/eventfd.h>
+#include <linux/vhost.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/poll.h>
+#include <linux/file.h>
+#include <linux/skbuff.h>
+#include <linux/uio.h>
+#include <linux/virtio_config.h>
+#include <linux/virtio_ring.h>
+
+struct vhost_device;
+
+enum {
+	/* Enough place for all fragments, head, and virtio net header. */
+	VHOST_NET_MAX_SG = MAX_SKB_FRAGS + 2,
+};
+
+/* Poll a file (eventfd or socket) */
+/* Note: there's nothing vhost specific about this structure. */
+struct vhost_poll {
+	poll_table                table;
+	wait_queue_head_t        *wqh;
+	wait_queue_t              wait;
+	/* struct which will handle all actual work. */
+	struct work_struct        work;
+	unsigned long		  mask;
+};
+
+void vhost_poll_init(struct vhost_poll *poll, work_func_t func,
+		     unsigned long mask);
+void vhost_poll_start(struct vhost_poll *poll, struct file *file);
+void vhost_poll_stop(struct vhost_poll *poll);
+void vhost_poll_flush(struct vhost_poll *poll);
+void vhost_poll_queue(struct vhost_poll *poll);
+
+struct vhost_log {
+	u64 addr;
+	u64 len;
+};
+
+/* The virtqueue structure describes a queue attached to a device. */
+struct vhost_virtqueue {
+	struct vhost_dev *dev;
+
+	/* The actual ring of buffers. */
+	struct mutex mutex;
+	unsigned int num;
+	struct vring_desc __user *desc;
+	struct vring_avail __user *avail;
+	struct vring_used __user *used;
+	struct file *kick;
+	struct file *call;
+	struct file *error;
+	struct eventfd_ctx *call_ctx;
+	struct eventfd_ctx *error_ctx;
+	struct eventfd_ctx *log_ctx;
+
+	struct vhost_poll poll;
+
+	/* The routine to call when the Guest pings us, or timeout. */
+	work_func_t handle_kick;
+
+	/* Last available index we saw. */
+	u16 last_avail_idx;
+
+	/* Caches available index value from user. */
+	u16 avail_idx;
+
+	/* Last index we used. */
+	u16 last_used_idx;
+
+	/* Used flags */
+	u16 used_flags;
+
+	/* Log writes to used structure. */
+	bool log_used;
+	u64 log_addr;
+
+	struct iovec indirect[VHOST_NET_MAX_SG];
+	struct iovec iov[VHOST_NET_MAX_SG];
+	struct iovec hdr[VHOST_NET_MAX_SG];
+	size_t hdr_size;
+	/* We use a kind of RCU to access private pointer.
+	 * All readers access it from workqueue, which makes it possible to
+	 * flush the workqueue instead of synchronize_rcu. Therefore readers do
+	 * not need to call rcu_read_lock/rcu_read_unlock: the beginning of
+	 * work item execution acts instead of rcu_read_lock() and the end of
+	 * work item execution acts instead of rcu_read_lock().
+	 * Writers use virtqueue mutex. */
+	void *private_data;
+	/* Log write descriptors */
+	void __user *log_base;
+	struct vhost_log log[VHOST_NET_MAX_SG];
+};
+
+struct vhost_dev {
+	/* Readers use RCU to access memory table pointer
+	 * log base pointer and features.
+	 * Writers use mutex below.*/
+	struct vhost_memory *memory;
+	struct mm_struct *mm;
+	struct mutex mutex;
+	unsigned acked_features;
+	struct vhost_virtqueue *vqs;
+	int nvqs;
+	struct file *log_file;
+	struct eventfd_ctx *log_ctx;
+};
+
+long vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue *vqs, int nvqs);
+long vhost_dev_check_owner(struct vhost_dev *);
+long vhost_dev_reset_owner(struct vhost_dev *);
+void vhost_dev_cleanup(struct vhost_dev *);
+long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, unsigned long arg);
+int vhost_vq_access_ok(struct vhost_virtqueue *vq);
+int vhost_log_access_ok(struct vhost_dev *);
+
+unsigned vhost_get_vq_desc(struct vhost_dev *, struct vhost_virtqueue *,
+			   struct iovec iov[], unsigned int iov_count,
+			   unsigned int *out_num, unsigned int *in_num,
+			   struct vhost_log *log, unsigned int *log_num);
+void vhost_discard_vq_desc(struct vhost_virtqueue *);
+
+int vhost_add_used(struct vhost_virtqueue *, unsigned int head, int len);
+void vhost_signal(struct vhost_dev *, struct vhost_virtqueue *);
+void vhost_add_used_and_signal(struct vhost_dev *, struct vhost_virtqueue *,
+			       unsigned int head, int len);
+void vhost_disable_notify(struct vhost_virtqueue *);
+bool vhost_enable_notify(struct vhost_virtqueue *);
+
+int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log,
+		    unsigned int log_num, u64 len);
+
+int vhost_init(void);
+void vhost_cleanup(void);
+
+#define vq_err(vq, fmt, ...) do {                                  \
+		pr_debug(pr_fmt(fmt), ##__VA_ARGS__);       \
+		if ((vq)->error_ctx)                               \
+				eventfd_signal((vq)->error_ctx, 1);\
+	} while (0)
+
+enum {
+	VHOST_FEATURES = (1 << VIRTIO_F_NOTIFY_ON_EMPTY) |
+			 (1 << VIRTIO_RING_F_INDIRECT_DESC) |
+			 (1 << VHOST_F_LOG_ALL) |
+			 (1 << VHOST_NET_F_VIRTIO_NET_HDR),
+};
+
+static inline int vhost_has_feature(struct vhost_dev *dev, int bit)
+{
+	unsigned acked_features = rcu_dereference(dev->acked_features);
+	return acked_features & (1 << bit);
+}
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/68328fb.c linux-libre-2.6.34-gnu1/drivers/video/68328fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/68328fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/68328fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -308,7 +307,7 @@ static int mc68x328fb_setcolreg(u_int re
 	 * Pseudocolor:
 	 *    uses offset = 0 && length = RAMDAC register width.
 	 *    var->{color}.offset is 0
-	 *    var->{color}.length contains widht of DAC
+	 *    var->{color}.length contains width of DAC
 	 *    cmap is not used
 	 *    RAMDAC[X] is programmed to (red, green, blue)
 	 * Truecolor:
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/acornfb.c linux-libre-2.6.34-gnu1/drivers/video/acornfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/acornfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/acornfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,13 +22,13 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -1221,7 +1221,7 @@ free_unused_pages(unsigned int virtual_s
 	printk("acornfb: freed %dK memory\n", mb_freed);
 }
 
-static int __init acornfb_probe(struct platform_device *dev)
+static int __devinit acornfb_probe(struct platform_device *dev)
 {
 	unsigned long size;
 	u_int h_sync, v_sync;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/amba-clcd.c linux-libre-2.6.34-gnu1/drivers/video/amba-clcd.c
--- linux-libre-2.6.33-gnu1/drivers/video/amba-clcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/amba-clcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -65,16 +65,16 @@ static void clcdfb_disable(struct clcd_f
 	if (fb->board->disable)
 		fb->board->disable(fb);
 
-	val = readl(fb->regs + CLCD_CNTL);
+	val = readl(fb->regs + fb->off_cntl);
 	if (val & CNTL_LCDPWR) {
 		val &= ~CNTL_LCDPWR;
-		writel(val, fb->regs + CLCD_CNTL);
+		writel(val, fb->regs + fb->off_cntl);
 
 		clcdfb_sleep(20);
 	}
 	if (val & CNTL_LCDEN) {
 		val &= ~CNTL_LCDEN;
-		writel(val, fb->regs + CLCD_CNTL);
+		writel(val, fb->regs + fb->off_cntl);
 	}
 
 	/*
@@ -94,7 +94,7 @@ static void clcdfb_enable(struct clcd_fb
 	 * Bring up by first enabling..
 	 */
 	cntl |= CNTL_LCDEN;
-	writel(cntl, fb->regs + CLCD_CNTL);
+	writel(cntl, fb->regs + fb->off_cntl);
 
 	clcdfb_sleep(20);
 
@@ -102,7 +102,7 @@ static void clcdfb_enable(struct clcd_fb
 	 * and now apply power.
 	 */
 	cntl |= CNTL_LCDPWR;
-	writel(cntl, fb->regs + CLCD_CNTL);
+	writel(cntl, fb->regs + fb->off_cntl);
 
 	/*
 	 * finally, enable the interface.
@@ -233,7 +233,7 @@ static int clcdfb_set_par(struct fb_info
 		readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1),
 		readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3),
 		readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS),
-		readl(fb->regs + CLCD_IENB), readl(fb->regs + CLCD_CNTL));
+		readl(fb->regs + fb->off_ienb), readl(fb->regs + fb->off_cntl));
 #endif
 
 	return 0;
@@ -345,6 +345,23 @@ static int clcdfb_register(struct clcd_f
 {
 	int ret;
 
+	/*
+	 * ARM PL111 always has IENB at 0x1c; it's only PL110
+	 * which is reversed on some platforms.
+	 */
+	if (amba_manf(fb->dev) == 0x41 && amba_part(fb->dev) == 0x111) {
+		fb->off_ienb = CLCD_PL111_IENB;
+		fb->off_cntl = CLCD_PL111_CNTL;
+	} else {
+#ifdef CONFIG_ARCH_VERSATILE
+		fb->off_ienb = CLCD_PL111_IENB;
+		fb->off_cntl = CLCD_PL111_CNTL;
+#else
+		fb->off_ienb = CLCD_PL110_IENB;
+		fb->off_cntl = CLCD_PL110_CNTL;
+#endif
+	}
+
 	fb->clk = clk_get(&fb->dev->dev, NULL);
 	if (IS_ERR(fb->clk)) {
 		ret = PTR_ERR(fb->clk);
@@ -416,7 +433,7 @@ static int clcdfb_register(struct clcd_f
 	/*
 	 * Ensure interrupts are disabled.
 	 */
-	writel(0, fb->regs + CLCD_IENB);
+	writel(0, fb->regs + fb->off_ienb);
 
 	fb_set_var(&fb->fb, &fb->fb.var);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/amifb.c linux-libre-2.6.34-gnu1/drivers/video/amifb.c
--- linux-libre-2.6.33-gnu1/drivers/video/amifb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/amifb.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,7 +45,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/fb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/arcfb.c linux-libre-2.6.34-gnu1/drivers/video/arcfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/arcfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/arcfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -504,7 +503,7 @@ static struct fb_ops arcfb_ops = {
 	.fb_ioctl 	= arcfb_ioctl,
 };
 
-static int __init arcfb_probe(struct platform_device *dev)
+static int __devinit arcfb_probe(struct platform_device *dev)
 {
 	struct fb_info *info;
 	int retval = -ENOMEM;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/asiliantfb.c linux-libre-2.6.34-gnu1/drivers/video/asiliantfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/asiliantfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/asiliantfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -140,7 +139,7 @@ static void asiliant_calc_dclk2(u32 *ppi
 
 		/* 3 <= m <= 257 */
 		if (m >= 3 && m <= 257) {
-			unsigned new_error = ((Ftarget * n) - (Fref * m)) >= 0 ?
+			unsigned new_error = Ftarget * n >= Fref * m ?
 					       ((Ftarget * n) - (Fref * m)) : ((Fref * m) - (Ftarget * n));
 			if (new_error < best_error) {
 				best_n = n;
@@ -152,7 +151,7 @@ static void asiliant_calc_dclk2(u32 *ppi
 		else if (m <= 1028) {
 			/* remember there are still only 8-bits of precision in m, so
 			 * avoid over-optimistic error calculations */
-			unsigned new_error = ((Ftarget * n) - (Fref * (m & ~3))) >= 0 ?
+			unsigned new_error = Ftarget * n >= Fref * (m & ~3) ?
 					       ((Ftarget * n) - (Fref * (m & ~3))) : ((Fref * (m & ~3)) - (Ftarget * n));
 			if (new_error < best_error) {
 				best_n = n;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/atafb.c linux-libre-2.6.34-gnu1/drivers/video/atafb.c
--- linux-libre-2.6.33-gnu1/drivers/video/atafb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/atafb.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,7 +52,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/atmel_lcdfb.c linux-libre-2.6.34-gnu1/drivers/video/atmel_lcdfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/atmel_lcdfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/atmel_lcdfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/backlight.h>
+#include <linux/gfp.h>
 
 #include <mach/board.h>
 #include <mach/cpu.h>
@@ -117,6 +118,7 @@ static struct backlight_ops atmel_lcdc_b
 
 static void init_backlight(struct atmel_lcdfb_info *sinfo)
 {
+	struct backlight_properties props;
 	struct backlight_device	*bl;
 
 	sinfo->bl_power = FB_BLANK_UNBLANK;
@@ -124,8 +126,10 @@ static void init_backlight(struct atmel_
 	if (sinfo->backlight)
 		return;
 
-	bl = backlight_device_register("backlight", &sinfo->pdev->dev,
-			sinfo, &atmel_lcdc_bl_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = 0xff;
+	bl = backlight_device_register("backlight", &sinfo->pdev->dev, sinfo,
+				       &atmel_lcdc_bl_ops, &props);
 	if (IS_ERR(bl)) {
 		dev_err(&sinfo->pdev->dev, "error %ld on backlight register\n",
 				PTR_ERR(bl));
@@ -135,7 +139,6 @@ static void init_backlight(struct atmel_
 
 	bl->props.power = FB_BLANK_UNBLANK;
 	bl->props.fb_blank = FB_BLANK_UNBLANK;
-	bl->props.max_brightness = 0xff;
 	bl->props.brightness = atmel_bl_get_brightness(bl);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/aty/aty128fb.c linux-libre-2.6.34-gnu1/drivers/video/aty/aty128fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/aty/aty128fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/aty/aty128fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,7 +52,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -1802,6 +1801,7 @@ static void aty128_bl_set_power(struct f
 
 static void aty128_bl_init(struct aty128fb_par *par)
 {
+	struct backlight_properties props;
 	struct fb_info *info = pci_get_drvdata(par->pdev);
 	struct backlight_device *bd;
 	char name[12];
@@ -1817,7 +1817,10 @@ static void aty128_bl_init(struct aty128
 
 	snprintf(name, sizeof(name), "aty128bl%d", info->node);
 
-	bd = backlight_device_register(name, info->dev, par, &aty128_bl_data);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+	bd = backlight_device_register(name, info->dev, par, &aty128_bl_data,
+				       &props);
 	if (IS_ERR(bd)) {
 		info->bl_dev = NULL;
 		printk(KERN_WARNING "aty128: Backlight registration failed\n");
@@ -1829,7 +1832,6 @@ static void aty128_bl_init(struct aty128
 		 63 * FB_BACKLIGHT_MAX / MAX_LEVEL,
 		219 * FB_BACKLIGHT_MAX / MAX_LEVEL);
 
-	bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
 	bd->props.brightness = bd->props.max_brightness;
 	bd->props.power = FB_BLANK_UNBLANK;
 	backlight_update_status(bd);
@@ -1931,22 +1933,22 @@ static int __devinit aty128_init(struct
 			 * PowerMac2,2 summer 2000 iMacs
 			 * PowerMac4,1 january 2001 iMacs "flower power"
 			 */
-			if (machine_is_compatible("PowerMac2,1") ||
-			    machine_is_compatible("PowerMac2,2") ||
-			    machine_is_compatible("PowerMac4,1"))
+			if (of_machine_is_compatible("PowerMac2,1") ||
+			    of_machine_is_compatible("PowerMac2,2") ||
+			    of_machine_is_compatible("PowerMac4,1"))
 				default_vmode = VMODE_1024_768_75;
 
 			/* iBook SE */
-			if (machine_is_compatible("PowerBook2,2"))
+			if (of_machine_is_compatible("PowerBook2,2"))
 				default_vmode = VMODE_800_600_60;
 
 			/* PowerBook Firewire (Pismo), iBook Dual USB */
-			if (machine_is_compatible("PowerBook3,1") ||
-			    machine_is_compatible("PowerBook4,1"))
+			if (of_machine_is_compatible("PowerBook3,1") ||
+			    of_machine_is_compatible("PowerBook4,1"))
 				default_vmode = VMODE_1024_768_60;
 
 			/* PowerBook Titanium */
-			if (machine_is_compatible("PowerBook3,2"))
+			if (of_machine_is_compatible("PowerBook3,2"))
 				default_vmode = VMODE_1152_768_60;
 	
 			if (default_cmode > 16) 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/aty/atyfb_base.c linux-libre-2.6.34-gnu1/drivers/video/aty/atyfb_base.c
--- linux-libre-2.6.33-gnu1/drivers/video/aty/atyfb_base.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/aty/atyfb_base.c	2010-05-16 17:17:36.000000000 -0400
@@ -2232,6 +2232,7 @@ static struct backlight_ops aty_bl_data
 
 static void aty_bl_init(struct atyfb_par *par)
 {
+	struct backlight_properties props;
 	struct fb_info *info = pci_get_drvdata(par->pdev);
 	struct backlight_device *bd;
 	char name[12];
@@ -2243,7 +2244,10 @@ static void aty_bl_init(struct atyfb_par
 
 	snprintf(name, sizeof(name), "atybl%d", info->node);
 
-	bd = backlight_device_register(name, info->dev, par, &aty_bl_data);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+	bd = backlight_device_register(name, info->dev, par, &aty_bl_data,
+				       &props);
 	if (IS_ERR(bd)) {
 		info->bl_dev = NULL;
 		printk(KERN_WARNING "aty: Backlight registration failed\n");
@@ -2255,7 +2259,6 @@ static void aty_bl_init(struct atyfb_par
 			    0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL,
 			    0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
 
-	bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
 	bd->props.brightness = bd->props.max_brightness;
 	bd->props.power = FB_BLANK_UNBLANK;
 	backlight_update_status(bd);
@@ -2439,7 +2442,7 @@ static int __devinit aty_init(struct fb_
 	 * The Apple iBook1 uses non-standard memory frequencies.
 	 * We detect it and set the frequency manually.
 	 */
-	if (machine_is_compatible("PowerBook2,1")) {
+	if (of_machine_is_compatible("PowerBook2,1")) {
 		par->pll_limits.mclk = 70;
 		par->pll_limits.xclk = 53;
 	}
@@ -2659,7 +2662,7 @@ static int __devinit aty_init(struct fb_
 		      FBINFO_HWACCEL_YPAN;
 
 #ifdef CONFIG_PMAC_BACKLIGHT
-	if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) {
+	if (M64_HAS(G3_PB_1_1) && of_machine_is_compatible("PowerBook1,1")) {
 		/*
 		 * these bits let the 101 powerbook
 		 * wake up from sleep -- paulus
@@ -2690,9 +2693,9 @@ static int __devinit aty_init(struct fb_
 				if (M64_HAS(G3_PB_1024x768))
 					/* G3 PowerBook with 1024x768 LCD */
 					default_vmode = VMODE_1024_768_60;
-				else if (machine_is_compatible("iMac"))
+				else if (of_machine_is_compatible("iMac"))
 					default_vmode = VMODE_1024_768_75;
-				else if (machine_is_compatible("PowerBook2,1"))
+				else if (of_machine_is_compatible("PowerBook2,1"))
 					/* iBook with 800x600 LCD */
 					default_vmode = VMODE_800_600_60;
 				else
@@ -3104,7 +3107,7 @@ static int __devinit atyfb_setup_sparc(s
 	}
 
 	dp = pci_device_to_OF_node(pdev);
-	if (node == dp->node) {
+	if (node == dp->phandle) {
 		struct fb_var_screeninfo *var = &default_var;
 		unsigned int N, P, Q, M, T, R;
 		u32 v_total, h_total;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/aty/mach64_cursor.c linux-libre-2.6.34-gnu1/drivers/video/aty/mach64_cursor.c
--- linux-libre-2.6.33-gnu1/drivers/video/aty/mach64_cursor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/aty/mach64_cursor.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,6 @@
  *  ATI Mach64 CT/VT/GT/LT Cursor Support
  */
 
-#include <linux/slab.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/string.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/aty/radeon_backlight.c linux-libre-2.6.34-gnu1/drivers/video/aty/radeon_backlight.c
--- linux-libre-2.6.33-gnu1/drivers/video/aty/radeon_backlight.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/aty/radeon_backlight.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 
 #include "radeonfb.h"
 #include <linux/backlight.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 #include <asm/backlight.h>
@@ -134,6 +135,7 @@ static struct backlight_ops radeon_bl_da
 
 void radeonfb_bl_init(struct radeonfb_info *rinfo)
 {
+	struct backlight_properties props;
 	struct backlight_device *bd;
 	struct radeon_bl_privdata *pdata;
 	char name[12];
@@ -155,7 +157,10 @@ void radeonfb_bl_init(struct radeonfb_in
 
 	snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node);
 
-	bd = backlight_device_register(name, rinfo->info->dev, pdata, &radeon_bl_data);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+	bd = backlight_device_register(name, rinfo->info->dev, pdata,
+				       &radeon_bl_data, &props);
 	if (IS_ERR(bd)) {
 		rinfo->info->bl_dev = NULL;
 		printk("radeonfb: Backlight registration failed\n");
@@ -175,9 +180,9 @@ void radeonfb_bl_init(struct radeonfb_in
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 	pdata->negative = pdata->negative ||
-		machine_is_compatible("PowerBook4,3") ||
-		machine_is_compatible("PowerBook6,3") ||
-		machine_is_compatible("PowerBook6,5");
+		of_machine_is_compatible("PowerBook4,3") ||
+		of_machine_is_compatible("PowerBook6,3") ||
+		of_machine_is_compatible("PowerBook6,5");
 #endif
 
 	rinfo->info->bl_dev = bd;
@@ -185,7 +190,6 @@ void radeonfb_bl_init(struct radeonfb_in
 		 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL,
 		217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL);
 
-	bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
 	bd->props.brightness = bd->props.max_brightness;
 	bd->props.power = FB_BLANK_UNBLANK;
 	backlight_update_status(bd);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/aty/radeon_monitor.c linux-libre-2.6.34-gnu1/drivers/video/aty/radeon_monitor.c
--- linux-libre-2.6.33-gnu1/drivers/video/aty/radeon_monitor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/aty/radeon_monitor.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,7 @@
 #include "radeonfb.h"
+
+#include <linux/slab.h>
+
 #include "../edid.h"
 
 static struct fb_var_screeninfo radeonfb_default_var = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/au1100fb.c linux-libre-2.6.34-gnu1/drivers/video/au1100fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/au1100fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/au1100fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -52,6 +52,7 @@
 #include <linux/ctype.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/mach-au1x00/au1000.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/au1200fb.c linux-libre-2.6.34-gnu1/drivers/video/au1200fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/au1200fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/au1200fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,7 @@
 #include <linux/interrupt.h>
 #include <linux/ctype.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <asm/mach-au1x00/au1000.h>
 #include "au1200fb.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/88pm860x_bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/88pm860x_bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/88pm860x_bl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/88pm860x_bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,307 @@
+/*
+ * Backlight driver for Marvell Semiconductor 88PM8606
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ *	Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/mfd/88pm860x.h>
+#include <linux/slab.h>
+
+#define MAX_BRIGHTNESS		(0xFF)
+#define MIN_BRIGHTNESS		(0)
+
+#define CURRENT_MASK		(0x1F << 1)
+
+struct pm860x_backlight_data {
+	struct pm860x_chip *chip;
+	struct i2c_client *i2c;
+	int	current_brightness;
+	int	port;
+	int	pwm;
+	int	iset;
+};
+
+static inline int wled_a(int port)
+{
+	int ret;
+
+	ret = ((port - PM8606_BACKLIGHT1) << 1) + 2;
+	return ret;
+}
+
+static inline int wled_b(int port)
+{
+	int ret;
+
+	ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
+	return ret;
+}
+
+/* WLED2 & WLED3 share the same IDC */
+static inline int wled_idc(int port)
+{
+	int ret;
+
+	switch (port) {
+	case PM8606_BACKLIGHT1:
+	case PM8606_BACKLIGHT2:
+		ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
+		break;
+	case PM8606_BACKLIGHT3:
+	default:
+		ret = ((port - PM8606_BACKLIGHT2) << 1) + 3;
+		break;
+	}
+	return ret;
+}
+
+static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
+{
+	struct pm860x_backlight_data *data = bl_get_data(bl);
+	struct pm860x_chip *chip = data->chip;
+	unsigned char value;
+	int ret;
+
+	if (brightness > MAX_BRIGHTNESS)
+		value = MAX_BRIGHTNESS;
+	else
+		value = brightness;
+
+	ret = pm860x_reg_write(data->i2c, wled_a(data->port), value);
+	if (ret < 0)
+		goto out;
+
+	if ((data->current_brightness == 0) && brightness) {
+		if (data->iset) {
+			ret = pm860x_set_bits(data->i2c, wled_idc(data->port),
+					      CURRENT_MASK, data->iset);
+			if (ret < 0)
+				goto out;
+		}
+		if (data->pwm) {
+			ret = pm860x_set_bits(data->i2c, PM8606_PWM,
+					      PM8606_PWM_FREQ_MASK, data->pwm);
+			if (ret < 0)
+				goto out;
+		}
+		if (brightness == MAX_BRIGHTNESS) {
+			/* set WLED_ON bit as 100% */
+			ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+					      PM8606_WLED_ON, PM8606_WLED_ON);
+		}
+	} else {
+		if (brightness == MAX_BRIGHTNESS) {
+			/* set WLED_ON bit as 100% */
+			ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+					      PM8606_WLED_ON, PM8606_WLED_ON);
+		} else {
+			/* clear WLED_ON bit since it's not 100% */
+			ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+					      PM8606_WLED_ON, 0);
+		}
+	}
+	if (ret < 0)
+		goto out;
+
+	dev_dbg(chip->dev, "set brightness %d\n", value);
+	data->current_brightness = value;
+	return 0;
+out:
+	dev_dbg(chip->dev, "set brightness %d failure with return "
+		"value:%d\n", value, ret);
+	return ret;
+}
+
+static int pm860x_backlight_update_status(struct backlight_device *bl)
+{
+	int brightness = bl->props.brightness;
+
+	if (bl->props.power != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bl->props.state & BL_CORE_SUSPENDED)
+		brightness = 0;
+
+	return pm860x_backlight_set(bl, brightness);
+}
+
+static int pm860x_backlight_get_brightness(struct backlight_device *bl)
+{
+	struct pm860x_backlight_data *data = bl_get_data(bl);
+	struct pm860x_chip *chip = data->chip;
+	int ret;
+
+	ret = pm860x_reg_read(data->i2c, wled_a(data->port));
+	if (ret < 0)
+		goto out;
+	data->current_brightness = ret;
+	dev_dbg(chip->dev, "get brightness %d\n", data->current_brightness);
+	return data->current_brightness;
+out:
+	return -EINVAL;
+}
+
+static struct backlight_ops pm860x_backlight_ops = {
+	.options	= BL_CORE_SUSPENDRESUME,
+	.update_status	= pm860x_backlight_update_status,
+	.get_brightness	= pm860x_backlight_get_brightness,
+};
+
+static int __check_device(struct pm860x_backlight_pdata *pdata, char *name)
+{
+	struct pm860x_backlight_pdata *p = pdata;
+	int ret = -EINVAL;
+
+	while (p && p->id) {
+		if ((p->id != PM8606_ID_BACKLIGHT) || (p->flags < 0))
+			break;
+
+		if (!strncmp(name, pm860x_backlight_name[p->flags],
+			MFD_NAME_SIZE)) {
+			ret = (int)p->flags;
+			break;
+		}
+		p++;
+	}
+	return ret;
+}
+
+static int pm860x_backlight_probe(struct platform_device *pdev)
+{
+	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct pm860x_platform_data *pm860x_pdata;
+	struct pm860x_backlight_pdata *pdata = NULL;
+	struct pm860x_backlight_data *data;
+	struct backlight_device *bl;
+	struct resource *res;
+	struct backlight_properties props;
+	unsigned char value;
+	char name[MFD_NAME_SIZE];
+	int ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "No I/O resource!\n");
+		return -EINVAL;
+	}
+
+	if (pdev->dev.parent->platform_data) {
+		pm860x_pdata = pdev->dev.parent->platform_data;
+		pdata = pm860x_pdata->backlight;
+	}
+	if (pdata == NULL) {
+		dev_err(&pdev->dev, "platform data isn't assigned to "
+			"backlight\n");
+		return -EINVAL;
+	}
+
+	data = kzalloc(sizeof(struct pm860x_backlight_data), GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+	strncpy(name, res->name, MFD_NAME_SIZE);
+	data->chip = chip;
+	data->i2c = (chip->id == CHIP_PM8606) ? chip->client	\
+			: chip->companion;
+	data->current_brightness = MAX_BRIGHTNESS;
+	data->pwm = pdata->pwm;
+	data->iset = pdata->iset;
+	data->port = __check_device(pdata, name);
+	if (data->port < 0) {
+		dev_err(&pdev->dev, "wrong platform data is assigned");
+		return -EINVAL;
+	}
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = MAX_BRIGHTNESS;
+	bl = backlight_device_register(name, &pdev->dev, data,
+					&pm860x_backlight_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(&pdev->dev, "failed to register backlight\n");
+		kfree(data);
+		return PTR_ERR(bl);
+	}
+	bl->props.brightness = MAX_BRIGHTNESS;
+
+	platform_set_drvdata(pdev, bl);
+
+	/* Enable reference VSYS */
+	ret = pm860x_reg_read(data->i2c, PM8606_VSYS);
+	if (ret < 0)
+		goto out;
+	if ((ret & PM8606_VSYS_EN) == 0) {
+		value = ret | PM8606_VSYS_EN;
+		ret = pm860x_reg_write(data->i2c, PM8606_VSYS, value);
+		if (ret < 0)
+			goto out;
+	}
+	/* Enable reference OSC */
+	ret = pm860x_reg_read(data->i2c, PM8606_MISC);
+	if (ret < 0)
+		goto out;
+	if ((ret & PM8606_MISC_OSC_EN) == 0) {
+		value = ret | PM8606_MISC_OSC_EN;
+		ret = pm860x_reg_write(data->i2c, PM8606_MISC, value);
+		if (ret < 0)
+			goto out;
+	}
+	/* read current backlight */
+	ret = pm860x_backlight_get_brightness(bl);
+	if (ret < 0)
+		goto out;
+
+	backlight_update_status(bl);
+	return 0;
+out:
+	kfree(data);
+	return ret;
+}
+
+static int pm860x_backlight_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+	struct pm860x_backlight_data *data = bl_get_data(bl);
+
+	backlight_device_unregister(bl);
+	kfree(data);
+	return 0;
+}
+
+static struct platform_driver pm860x_backlight_driver = {
+	.driver		= {
+		.name	= "88pm860x-backlight",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= pm860x_backlight_probe,
+	.remove		= pm860x_backlight_remove,
+};
+
+static int __init pm860x_backlight_init(void)
+{
+	return platform_driver_register(&pm860x_backlight_driver);
+}
+module_init(pm860x_backlight_init);
+
+static void __exit pm860x_backlight_exit(void)
+{
+	platform_driver_unregister(&pm860x_backlight_driver);
+}
+module_exit(pm860x_backlight_exit);
+
+MODULE_DESCRIPTION("Backlight Driver for Marvell Semiconductor 88PM8606");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:88pm860x-backlight");
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/adp5520_bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/adp5520_bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/adp5520_bl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/adp5520_bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/fb.h>
 #include <linux/backlight.h>
 #include <linux/mfd/adp5520.h>
+#include <linux/slab.h>
 
 struct adp5520_bl {
 	struct device *master;
@@ -278,6 +279,7 @@ static const struct attribute_group adp5
 
 static int __devinit adp5520_bl_probe(struct platform_device *pdev)
 {
+	struct backlight_properties props;
 	struct backlight_device *bl;
 	struct adp5520_bl *data;
 	int ret = 0;
@@ -300,17 +302,17 @@ static int __devinit adp5520_bl_probe(st
 
 	mutex_init(&data->lock);
 
-	bl = backlight_device_register(pdev->name, data->master,
-			data, &adp5520_bl_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = ADP5020_MAX_BRIGHTNESS;
+	bl = backlight_device_register(pdev->name, data->master, data,
+				       &adp5520_bl_ops, &props);
 	if (IS_ERR(bl)) {
 		dev_err(&pdev->dev, "failed to register backlight\n");
 		kfree(data);
 		return PTR_ERR(bl);
 	}
 
-	bl->props.max_brightness =
-		bl->props.brightness = ADP5020_MAX_BRIGHTNESS;
-
+	bl->props.brightness = ADP5020_MAX_BRIGHTNESS;
 	if (data->pdata->en_ambl_sens)
 		ret = sysfs_create_group(&bl->dev.kobj,
 			&adp5520_bl_attr_group);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/adx_bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/adx_bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/adx_bl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/adx_bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 
 #include <linux/backlight.h>
 #include <linux/fb.h>
+#include <linux/gfp.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -56,7 +57,7 @@ static int adx_backlight_get_brightness(
 	return brightness & 0xff;
 }
 
-static int adx_backlight_check_fb(struct fb_info *fb)
+static int adx_backlight_check_fb(struct backlight_device *bldev, struct fb_info *fb)
 {
 	return 1;
 }
@@ -70,6 +71,7 @@ static const struct backlight_ops adx_ba
 
 static int __devinit adx_backlight_probe(struct platform_device *pdev)
 {
+	struct backlight_properties props;
 	struct backlight_device *bldev;
 	struct resource *res;
 	struct adxbl *bl;
@@ -101,14 +103,15 @@ static int __devinit adx_backlight_probe
 		goto out;
 	}
 
-	bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, bl,
-			&adx_backlight_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = 0xff;
+	bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev,
+					  bl, &adx_backlight_ops, &props);
 	if (!bldev) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
-	bldev->props.max_brightness = 0xff;
 	bldev->props.brightness = 0xff;
 	bldev->props.power = FB_BLANK_UNBLANK;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/atmel-pwm-bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/atmel-pwm-bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/atmel-pwm-bl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/atmel-pwm-bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/backlight.h>
 #include <linux/atmel_pwm.h>
 #include <linux/atmel-pwm-bl.h>
+#include <linux/slab.h>
 
 struct atmel_pwm_bl {
 	const struct atmel_pwm_bl_platform_data	*pdata;
@@ -120,6 +121,7 @@ static const struct backlight_ops atmel_
 
 static int atmel_pwm_bl_probe(struct platform_device *pdev)
 {
+	struct backlight_properties props;
 	const struct atmel_pwm_bl_platform_data *pdata;
 	struct backlight_device *bldev;
 	struct atmel_pwm_bl *pwmbl;
@@ -165,8 +167,10 @@ static int atmel_pwm_bl_probe(struct pla
 			goto err_free_gpio;
 	}
 
-	bldev = backlight_device_register("atmel-pwm-bl",
-			&pdev->dev, pwmbl, &atmel_pwm_bl_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
+	bldev = backlight_device_register("atmel-pwm-bl", &pdev->dev, pwmbl,
+					  &atmel_pwm_bl_ops, &props);
 	if (IS_ERR(bldev)) {
 		retval = PTR_ERR(bldev);
 		goto err_free_gpio;
@@ -178,7 +182,6 @@ static int atmel_pwm_bl_probe(struct pla
 
 	/* Power up the backlight by default at middle intesity. */
 	bldev->props.power = FB_BLANK_UNBLANK;
-	bldev->props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
 	bldev->props.brightness = bldev->props.max_brightness / 2;
 
 	retval = atmel_pwm_bl_init_pwm(pwmbl);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/backlight.c linux-libre-2.6.34-gnu1/drivers/video/backlight/backlight.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/backlight.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/backlight.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/ctype.h>
 #include <linux/err.h>
 #include <linux/fb.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 #include <asm/backlight.h>
@@ -38,7 +39,7 @@ static int fb_notifier_callback(struct n
 	mutex_lock(&bd->ops_lock);
 	if (bd->ops)
 		if (!bd->ops->check_fb ||
-		    bd->ops->check_fb(evdata->info)) {
+		    bd->ops->check_fb(bd, evdata->info)) {
 			bd->props.fb_blank = *(int *)evdata->data;
 			if (bd->props.fb_blank == FB_BLANK_UNBLANK)
 				bd->props.state &= ~BL_CORE_FBBLANK;
@@ -269,7 +270,8 @@ EXPORT_SYMBOL(backlight_force_update);
  * ERR_PTR() or a pointer to the newly allocated device.
  */
 struct backlight_device *backlight_device_register(const char *name,
-		struct device *parent, void *devdata, const struct backlight_ops *ops)
+	struct device *parent, void *devdata, const struct backlight_ops *ops,
+	const struct backlight_properties *props)
 {
 	struct backlight_device *new_bd;
 	int rc;
@@ -289,6 +291,11 @@ struct backlight_device *backlight_devic
 	dev_set_name(&new_bd->dev, name);
 	dev_set_drvdata(&new_bd->dev, devdata);
 
+	/* Set default properties */
+	if (props)
+		memcpy(&new_bd->props, props,
+		       sizeof(struct backlight_properties));
+
 	rc = device_register(&new_bd->dev);
 	if (rc) {
 		kfree(new_bd);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/corgi_lcd.c linux-libre-2.6.34-gnu1/drivers/video/backlight/corgi_lcd.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/corgi_lcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/corgi_lcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/lcd.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/corgi_lcd.h>
+#include <linux/slab.h>
 #include <asm/mach/sharpsl_param.h>
 
 #define POWER_IS_ON(pwr)	((pwr) <= FB_BLANK_NORMAL)
@@ -533,6 +534,7 @@ err_free_backlight_on:
 
 static int __devinit corgi_lcd_probe(struct spi_device *spi)
 {
+	struct backlight_properties props;
 	struct corgi_lcd_platform_data *pdata = spi->dev.platform_data;
 	struct corgi_lcd *lcd;
 	int ret = 0;
@@ -559,13 +561,14 @@ static int __devinit corgi_lcd_probe(str
 	lcd->power = FB_BLANK_POWERDOWN;
 	lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA;
 
-	lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev,
-					lcd, &corgi_bl_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = pdata->max_intensity;
+	lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, lcd,
+						&corgi_bl_ops, &props);
 	if (IS_ERR(lcd->bl_dev)) {
 		ret = PTR_ERR(lcd->bl_dev);
 		goto err_unregister_lcd;
 	}
-	lcd->bl_dev->props.max_brightness = pdata->max_intensity;
 	lcd->bl_dev->props.brightness = pdata->default_intensity;
 	lcd->bl_dev->props.power = FB_BLANK_UNBLANK;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/cr_bllcd.c linux-libre-2.6.34-gnu1/drivers/video/backlight/cr_bllcd.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/cr_bllcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/cr_bllcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/backlight.h>
 #include <linux/lcd.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 /* The LVDS- and panel power controls sits on the
  * GPIO port of the ISA bridge.
@@ -170,6 +171,7 @@ static struct lcd_ops cr_lcd_ops = {
 
 static int cr_backlight_probe(struct platform_device *pdev)
 {
+	struct backlight_properties props;
 	struct backlight_device *bdp;
 	struct lcd_device *ldp;
 	struct cr_panel *crp;
@@ -190,8 +192,9 @@ static int cr_backlight_probe(struct pla
 		return -ENODEV;
 	}
 
-	bdp = backlight_device_register("cr-backlight",
-					&pdev->dev, NULL, &cr_backlight_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	bdp = backlight_device_register("cr-backlight", &pdev->dev, NULL,
+					&cr_backlight_ops, &props);
 	if (IS_ERR(bdp)) {
 		pci_dev_put(lpc_dev);
 		return PTR_ERR(bdp);
@@ -220,9 +223,7 @@ static int cr_backlight_probe(struct pla
 	crp->cr_lcd_device = ldp;
 	crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK;
 	crp->cr_backlight_device->props.brightness = 0;
-	crp->cr_backlight_device->props.max_brightness = 0;
 	cr_backlight_set_intensity(crp->cr_backlight_device);
-
 	cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK);
 
 	platform_set_drvdata(pdev, crp);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/da903x_bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/da903x_bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/da903x_bl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/da903x_bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/fb.h>
 #include <linux/backlight.h>
 #include <linux/mfd/da903x.h>
+#include <linux/slab.h>
 
 #define DA9030_WLED_CONTROL	0x25
 #define DA9030_WLED_CP_EN	(1 << 6)
@@ -105,6 +106,7 @@ static int da903x_backlight_probe(struct
 	struct da9034_backlight_pdata *pdata = pdev->dev.platform_data;
 	struct da903x_backlight_data *data;
 	struct backlight_device *bl;
+	struct backlight_properties props;
 	int max_brightness;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -134,15 +136,15 @@ static int da903x_backlight_probe(struct
 		da903x_write(data->da903x_dev, DA9034_WLED_CONTROL2,
 				DA9034_WLED_ISET(pdata->output_current));
 
-	bl = backlight_device_register(pdev->name, data->da903x_dev,
-			data, &da903x_backlight_ops);
+	props.max_brightness = max_brightness;
+	bl = backlight_device_register(pdev->name, data->da903x_dev, data,
+				       &da903x_backlight_ops, &props);
 	if (IS_ERR(bl)) {
 		dev_err(&pdev->dev, "failed to register backlight\n");
 		kfree(data);
 		return PTR_ERR(bl);
 	}
 
-	bl->props.max_brightness = max_brightness;
 	bl->props.brightness = max_brightness;
 
 	platform_set_drvdata(pdev, bl);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/generic_bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/generic_bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/generic_bl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/generic_bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -78,6 +78,7 @@ static const struct backlight_ops generi
 
 static int genericbl_probe(struct platform_device *pdev)
 {
+	struct backlight_properties props;
 	struct generic_bl_info *machinfo = pdev->dev.platform_data;
 	const char *name = "generic-bl";
 	struct backlight_device *bd;
@@ -89,14 +90,15 @@ static int genericbl_probe(struct platfo
 	if (machinfo->name)
 		name = machinfo->name;
 
-	bd = backlight_device_register (name,
-		&pdev->dev, NULL, &genericbl_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = machinfo->max_intensity;
+	bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops,
+				       &props);
 	if (IS_ERR (bd))
 		return PTR_ERR (bd);
 
 	platform_set_drvdata(pdev, bd);
 
-	bd->props.max_brightness = machinfo->max_intensity;
 	bd->props.power = FB_BLANK_UNBLANK;
 	bd->props.brightness = machinfo->default_intensity;
 	backlight_update_status(bd);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/hp680_bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/hp680_bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/hp680_bl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/hp680_bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -105,16 +105,18 @@ static const struct backlight_ops hp680b
 
 static int __devinit hp680bl_probe(struct platform_device *pdev)
 {
+	struct backlight_properties props;
 	struct backlight_device *bd;
 
-	bd = backlight_device_register ("hp680-bl", &pdev->dev, NULL,
-		    &hp680bl_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = HP680_MAX_INTENSITY;
+	bd = backlight_device_register("hp680-bl", &pdev->dev, NULL,
+				       &hp680bl_ops, &props);
 	if (IS_ERR(bd))
 		return PTR_ERR(bd);
 
 	platform_set_drvdata(pdev, bd);
 
-	bd->props.max_brightness = HP680_MAX_INTENSITY;
 	bd->props.brightness = HP680_DEFAULT_INTENSITY;
 	hp680bl_send_intensity(bd);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/ili9320.c linux-libre-2.6.34-gnu1/drivers/video/backlight/ili9320.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/ili9320.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/ili9320.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/lcd.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/jornada720_bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/jornada720_bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/jornada720_bl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/jornada720_bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -101,10 +101,14 @@ static const struct backlight_ops jornad
 
 static int jornada_bl_probe(struct platform_device *pdev)
 {
+	struct backlight_properties props;
 	int ret;
 	struct backlight_device *bd;
 
-	bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_bl_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = BL_MAX_BRIGHT;
+	bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL,
+				       &jornada_bl_ops, &props);
 
 	if (IS_ERR(bd)) {
 		ret = PTR_ERR(bd);
@@ -117,7 +121,6 @@ static int jornada_bl_probe(struct platf
 	/* note. make sure max brightness is set otherwise
 	   you will get seemingly non-related errors when
 	   trying to change brightness */
-	bd->props.max_brightness = BL_MAX_BRIGHT;
 	jornada_bl_update_status(bd);
 
 	platform_set_drvdata(pdev, bd);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/kb3886_bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/kb3886_bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/kb3886_bl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/kb3886_bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -141,20 +141,24 @@ static const struct backlight_ops kb3886
 
 static int kb3886bl_probe(struct platform_device *pdev)
 {
+	struct backlight_properties props;
 	struct kb3886bl_machinfo *machinfo = pdev->dev.platform_data;
 
 	bl_machinfo = machinfo;
 	if (!machinfo->limit_mask)
 		machinfo->limit_mask = -1;
 
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = machinfo->max_intensity;
 	kb3886_backlight_device = backlight_device_register("kb3886-bl",
-		&pdev->dev, NULL, &kb3886bl_ops);
+							    &pdev->dev, NULL,
+							    &kb3886bl_ops,
+							    &props);
 	if (IS_ERR(kb3886_backlight_device))
 		return PTR_ERR(kb3886_backlight_device);
 
 	platform_set_drvdata(pdev, kb3886_backlight_device);
 
-	kb3886_backlight_device->props.max_brightness = machinfo->max_intensity;
 	kb3886_backlight_device->props.power = FB_BLANK_UNBLANK;
 	kb3886_backlight_device->props.brightness = machinfo->default_intensity;
 	backlight_update_status(kb3886_backlight_device);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/Kconfig linux-libre-2.6.34-gnu1/drivers/video/backlight/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,13 @@ config LCD_CORGI
 	  Say y here to support the LCD panels usually found on SHARP
 	  corgi (C7x0) and spitz (Cxx00) models.
 
+config LCD_L4F00242T03
+	tristate "Epson L4F00242T03 LCD"
+	depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO
+	help
+	  SPI driver for Epson L4F00242T03. This provides basic support
+	  for init and powering the LCD up/down through a sysfs interface.
+
 config LCD_LMS283GF05
 	tristate "Samsung LMS283GF05 LCD"
 	depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO
@@ -212,6 +219,13 @@ config BACKLIGHT_DA903X
 	  If you have a LCD backlight connected to the WLED output of DA9030
 	  or DA9034 WLED output, say Y here to enable this driver.
 
+config BACKLIGHT_MAX8925
+	tristate "Backlight driver for MAX8925"
+	depends on BACKLIGHT_CLASS_DEVICE && MFD_MAX8925
+	help
+	  If you have a LCD backlight connected to the WLED output of MAX8925
+	  WLED output, say Y here to enable this driver.
+
 config BACKLIGHT_MBP_NVIDIA
        tristate "MacBook Pro Nvidia Backlight Driver"
        depends on BACKLIGHT_CLASS_DEVICE && X86
@@ -262,3 +276,9 @@ config BACKLIGHT_ADP5520
 	  To compile this driver as a module, choose M here: the module will
 	  be called adp5520_bl.
 
+config BACKLIGHT_88PM860X
+	tristate "Backlight Driver for 88PM8606 using WLED"
+	depends on BACKLIGHT_CLASS_DEVICE && MFD_88PM860X
+	help
+	  Say Y to enable the backlight driver for Marvell 88PM8606.
+
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/l4f00242t03.c linux-libre-2.6.34-gnu1/drivers/video/backlight/l4f00242t03.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/l4f00242t03.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/l4f00242t03.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,258 @@
+/*
+ * l4f00242t03.c -- support for Epson L4F00242T03 LCD
+ *
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * 	Inspired by Marek Vasut work in l4f00242t03.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/device.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/lcd.h>
+#include <linux/slab.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/l4f00242t03.h>
+
+struct l4f00242t03_priv {
+	struct spi_device	*spi;
+	struct lcd_device	*ld;
+	int lcd_on:1;
+	struct regulator *io_reg;
+	struct regulator *core_reg;
+};
+
+
+static void l4f00242t03_reset(unsigned int gpio)
+{
+	pr_debug("l4f00242t03_reset.\n");
+	gpio_set_value(gpio, 1);
+	mdelay(100);
+	gpio_set_value(gpio, 0);
+	mdelay(10);	/* tRES >= 100us */
+	gpio_set_value(gpio, 1);
+	mdelay(20);
+}
+
+#define param(x) ((x) | 0x100)
+
+static void l4f00242t03_lcd_init(struct spi_device *spi)
+{
+	struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
+	struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+	const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) };
+
+	dev_dbg(&spi->dev, "initializing LCD\n");
+
+	if (priv->io_reg) {
+		regulator_set_voltage(priv->io_reg, 1800000, 1800000);
+		regulator_enable(priv->io_reg);
+	}
+
+	if (priv->core_reg) {
+		regulator_set_voltage(priv->core_reg, 2800000, 2800000);
+		regulator_enable(priv->core_reg);
+	}
+
+	gpio_set_value(pdata->data_enable_gpio, 1);
+	msleep(60);
+	spi_write(spi, (const u8 *)cmd, ARRAY_SIZE(cmd) * sizeof(u16));
+}
+
+static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power)
+{
+	struct l4f00242t03_priv *priv = lcd_get_data(ld);
+	struct spi_device *spi = priv->spi;
+
+	const u16 slpout = 0x11;
+	const u16 dison = 0x29;
+
+	const u16 slpin = 0x10;
+	const u16 disoff = 0x28;
+
+	if (power) {
+		if (priv->lcd_on)
+			return 0;
+
+		dev_dbg(&spi->dev, "turning on LCD\n");
+
+		spi_write(spi, (const u8 *)&slpout, sizeof(u16));
+		msleep(60);
+		spi_write(spi, (const u8 *)&dison, sizeof(u16));
+
+		priv->lcd_on = 1;
+	} else {
+		if (!priv->lcd_on)
+			return 0;
+
+		dev_dbg(&spi->dev, "turning off LCD\n");
+
+		spi_write(spi, (const u8 *)&disoff, sizeof(u16));
+		msleep(60);
+		spi_write(spi, (const u8 *)&slpin, sizeof(u16));
+
+		priv->lcd_on = 0;
+	}
+
+	return 0;
+}
+
+static struct lcd_ops l4f_ops = {
+	.set_power	= l4f00242t03_lcd_power_set,
+	.get_power	= NULL,
+};
+
+static int __devinit l4f00242t03_probe(struct spi_device *spi)
+{
+	struct l4f00242t03_priv *priv;
+	struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
+	int ret;
+
+	if (pdata == NULL) {
+		dev_err(&spi->dev, "Uninitialized platform data.\n");
+		return -EINVAL;
+	}
+
+	priv = kzalloc(sizeof(struct l4f00242t03_priv), GFP_KERNEL);
+
+	if (priv == NULL) {
+		dev_err(&spi->dev, "No memory for this device.\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	dev_set_drvdata(&spi->dev, priv);
+	spi->bits_per_word = 9;
+	spi_setup(spi);
+
+	priv->spi = spi;
+
+	ret = gpio_request(pdata->reset_gpio, "lcd l4f00242t03 reset");
+	if (ret) {
+		dev_err(&spi->dev,
+			"Unable to get the lcd l4f00242t03 reset gpio.\n");
+		return ret;
+	}
+
+	ret = gpio_direction_output(pdata->reset_gpio, 1);
+	if (ret)
+		goto err2;
+
+	ret = gpio_request(pdata->data_enable_gpio,
+				"lcd l4f00242t03 data enable");
+	if (ret) {
+		dev_err(&spi->dev,
+			"Unable to get the lcd l4f00242t03 data en gpio.\n");
+		return ret;
+	}
+
+	ret = gpio_direction_output(pdata->data_enable_gpio, 0);
+	if (ret)
+		goto err3;
+
+	if (pdata->io_supply) {
+		priv->io_reg = regulator_get(NULL, pdata->io_supply);
+
+		if (IS_ERR(priv->io_reg)) {
+			pr_err("%s: Unable to get the IO regulator\n",
+								__func__);
+			goto err3;
+		}
+	}
+
+	if (pdata->core_supply) {
+		priv->core_reg = regulator_get(NULL, pdata->core_supply);
+
+		if (IS_ERR(priv->core_reg)) {
+			pr_err("%s: Unable to get the core regulator\n",
+								__func__);
+			goto err4;
+		}
+	}
+
+	priv->ld = lcd_device_register("l4f00242t03",
+					&spi->dev, priv, &l4f_ops);
+	if (IS_ERR(priv->ld)) {
+		ret = PTR_ERR(priv->ld);
+		goto err5;
+	}
+
+	/* Init the LCD */
+	l4f00242t03_reset(pdata->reset_gpio);
+	l4f00242t03_lcd_init(spi);
+	l4f00242t03_lcd_power_set(priv->ld, 1);
+
+	dev_info(&spi->dev, "Epson l4f00242t03 lcd probed.\n");
+
+	return 0;
+
+err5:
+	if (priv->core_reg)
+		regulator_put(priv->core_reg);
+err4:
+	if (priv->io_reg)
+		regulator_put(priv->io_reg);
+err3:
+	gpio_free(pdata->data_enable_gpio);
+err2:
+	gpio_free(pdata->reset_gpio);
+err:
+	kfree(priv);
+
+	return ret;
+}
+
+static int __devexit l4f00242t03_remove(struct spi_device *spi)
+{
+	struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+	struct l4f00242t03_pdata *pdata = priv->spi->dev.platform_data;
+
+	l4f00242t03_lcd_power_set(priv->ld, 0);
+	lcd_device_unregister(priv->ld);
+
+	gpio_free(pdata->data_enable_gpio);
+	gpio_free(pdata->reset_gpio);
+
+	if (priv->io_reg)
+		regulator_put(priv->core_reg);
+	if (priv->core_reg)
+		regulator_put(priv->io_reg);
+
+	kfree(priv);
+
+	return 0;
+}
+
+static struct spi_driver l4f00242t03_driver = {
+	.driver = {
+		.name	= "l4f00242t03",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= l4f00242t03_probe,
+	.remove		= __devexit_p(l4f00242t03_remove),
+};
+
+static __init int l4f00242t03_init(void)
+{
+	return spi_register_driver(&l4f00242t03_driver);
+}
+
+static __exit void l4f00242t03_exit(void)
+{
+	spi_unregister_driver(&l4f00242t03_driver);
+}
+
+module_init(l4f00242t03_init);
+module_exit(l4f00242t03_exit);
+
+MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>");
+MODULE_DESCRIPTION("EPSON L4F00242T03 LCD");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/lcd.c linux-libre-2.6.34-gnu1/drivers/video/backlight/lcd.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/lcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/lcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/ctype.h>
 #include <linux/err.h>
 #include <linux/fb.h>
+#include <linux/slab.h>
 
 #if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
 			   defined(CONFIG_LCD_CLASS_DEVICE_MODULE))
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/lms283gf05.c linux-libre-2.6.34-gnu1/drivers/video/backlight/lms283gf05.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/lms283gf05.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/lms283gf05.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/lcd.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/locomolcd.c linux-libre-2.6.34-gnu1/drivers/video/backlight/locomolcd.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/locomolcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/locomolcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -167,6 +167,7 @@ static int locomolcd_resume(struct locom
 
 static int locomolcd_probe(struct locomo_dev *ldev)
 {
+	struct backlight_properties props;
 	unsigned long flags;
 
 	local_irq_save(flags);
@@ -182,13 +183,16 @@ static int locomolcd_probe(struct locomo
 
 	local_irq_restore(flags);
 
-	locomolcd_bl_device = backlight_device_register("locomo-bl", &ldev->dev, NULL, &locomobl_data);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = 4;
+	locomolcd_bl_device = backlight_device_register("locomo-bl",
+							&ldev->dev, NULL,
+							&locomobl_data, &props);
 
 	if (IS_ERR (locomolcd_bl_device))
 		return PTR_ERR (locomolcd_bl_device);
 
 	/* Set up frontlight so that screen is readable */
-	locomolcd_bl_device->props.max_brightness = 4,
 	locomolcd_bl_device->props.brightness = 2;
 	locomolcd_set_intensity(locomolcd_bl_device);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/ltv350qv.c linux-libre-2.6.34-gnu1/drivers/video/backlight/ltv350qv.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/ltv350qv.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/ltv350qv.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/lcd.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/spi/spi.h>
 
 #include "ltv350qv.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/Makefile linux-libre-2.6.34-gnu1/drivers/video/backlight/Makefile
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
 obj-$(CONFIG_LCD_CLASS_DEVICE)     += lcd.o
 obj-$(CONFIG_LCD_CORGI)		   += corgi_lcd.o
 obj-$(CONFIG_LCD_HP700)		   += jornada720_lcd.o
+obj-$(CONFIG_LCD_L4F00242T03)	   += l4f00242t03.o
 obj-$(CONFIG_LCD_LMS283GF05)	   += lms283gf05.o
 obj-$(CONFIG_LCD_LTV350QV)	   += ltv350qv.o
 obj-$(CONFIG_LCD_ILI9320)	   += ili9320.o
@@ -22,10 +23,12 @@ obj-$(CONFIG_BACKLIGHT_PROGEAR) += proge
 obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
 obj-$(CONFIG_BACKLIGHT_PWM)	+= pwm_bl.o
 obj-$(CONFIG_BACKLIGHT_DA903X)	+= da903x_bl.o
+obj-$(CONFIG_BACKLIGHT_MAX8925)	+= max8925_bl.o
 obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o
 obj-$(CONFIG_BACKLIGHT_TOSA)	+= tosa_bl.o
 obj-$(CONFIG_BACKLIGHT_SAHARA)	+= kb3886_bl.o
 obj-$(CONFIG_BACKLIGHT_WM831X)	+= wm831x_bl.o
 obj-$(CONFIG_BACKLIGHT_ADX)    += adx_bl.o
 obj-$(CONFIG_BACKLIGHT_ADP5520)	+= adp5520_bl.o
+obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/max8925_bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/max8925_bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/max8925_bl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/max8925_bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,203 @@
+/*
+ * Backlight driver for Maxim MAX8925
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ *      Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/mfd/max8925.h>
+#include <linux/slab.h>
+
+#define MAX_BRIGHTNESS		(0xff)
+#define MIN_BRIGHTNESS		(0)
+
+#define LWX_FREQ(x)		(((x - 601) / 100) & 0x7)
+
+struct max8925_backlight_data {
+	struct max8925_chip	*chip;
+
+	int		current_brightness;
+};
+
+static int max8925_backlight_set(struct backlight_device *bl, int brightness)
+{
+	struct max8925_backlight_data *data = bl_get_data(bl);
+	struct max8925_chip *chip = data->chip;
+	unsigned char value;
+	int ret;
+
+	if (brightness > MAX_BRIGHTNESS)
+		value = MAX_BRIGHTNESS;
+	else
+		value = brightness;
+
+	ret = max8925_reg_write(chip->i2c, MAX8925_WLED_CNTL, value);
+	if (ret < 0)
+		goto out;
+
+	if (!data->current_brightness && brightness)
+		/* enable WLED output */
+		ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 1);
+	else if (!brightness)
+		/* disable WLED output */
+		ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 0);
+	if (ret < 0)
+		goto out;
+	dev_dbg(chip->dev, "set brightness %d\n", value);
+	data->current_brightness = value;
+	return 0;
+out:
+	dev_dbg(chip->dev, "set brightness %d failure with return value:%d\n",
+		value, ret);
+	return ret;
+}
+
+static int max8925_backlight_update_status(struct backlight_device *bl)
+{
+	int brightness = bl->props.brightness;
+
+	if (bl->props.power != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bl->props.state & BL_CORE_SUSPENDED)
+		brightness = 0;
+
+	return max8925_backlight_set(bl, brightness);
+}
+
+static int max8925_backlight_get_brightness(struct backlight_device *bl)
+{
+	struct max8925_backlight_data *data = bl_get_data(bl);
+	struct max8925_chip *chip = data->chip;
+	int ret;
+
+	ret = max8925_reg_read(chip->i2c, MAX8925_WLED_CNTL);
+	if (ret < 0)
+		return -EINVAL;
+	data->current_brightness = ret;
+	dev_dbg(chip->dev, "get brightness %d\n", data->current_brightness);
+	return ret;
+}
+
+static struct backlight_ops max8925_backlight_ops = {
+	.options	= BL_CORE_SUSPENDRESUME,
+	.update_status	= max8925_backlight_update_status,
+	.get_brightness	= max8925_backlight_get_brightness,
+};
+
+static int __devinit max8925_backlight_probe(struct platform_device *pdev)
+{
+	struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct max8925_platform_data *max8925_pdata;
+	struct max8925_backlight_pdata *pdata = NULL;
+	struct max8925_backlight_data *data;
+	struct backlight_device *bl;
+	struct backlight_properties props;
+	struct resource *res;
+	char name[MAX8925_NAME_SIZE];
+	unsigned char value;
+	int ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "No I/O resource!\n");
+		return -EINVAL;
+	}
+
+	if (pdev->dev.parent->platform_data) {
+		max8925_pdata = pdev->dev.parent->platform_data;
+		pdata = max8925_pdata->backlight;
+	}
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "platform data isn't assigned to "
+			"backlight\n");
+		return -EINVAL;
+	}
+
+	data = kzalloc(sizeof(struct max8925_backlight_data), GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+	strncpy(name, res->name, MAX8925_NAME_SIZE);
+	data->chip = chip;
+	data->current_brightness = 0;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = MAX_BRIGHTNESS;
+	bl = backlight_device_register(name, &pdev->dev, data,
+					&max8925_backlight_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(&pdev->dev, "failed to register backlight\n");
+		kfree(data);
+		return PTR_ERR(bl);
+	}
+	bl->props.brightness = MAX_BRIGHTNESS;
+
+	platform_set_drvdata(pdev, bl);
+
+	value = 0;
+	if (pdata->lxw_scl)
+		value |= (1 << 7);
+	if (pdata->lxw_freq)
+		value |= (LWX_FREQ(pdata->lxw_freq) << 4);
+	if (pdata->dual_string)
+		value |= (1 << 1);
+	ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 0xfe, value);
+	if (ret < 0)
+		goto out;
+
+	backlight_update_status(bl);
+	return 0;
+out:
+	kfree(data);
+	return ret;
+}
+
+static int __devexit max8925_backlight_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+	struct max8925_backlight_data *data = bl_get_data(bl);
+
+	backlight_device_unregister(bl);
+	kfree(data);
+	return 0;
+}
+
+static struct platform_driver max8925_backlight_driver = {
+	.driver		= {
+		.name	= "max8925-backlight",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= max8925_backlight_probe,
+	.remove		= __devexit_p(max8925_backlight_remove),
+};
+
+static int __init max8925_backlight_init(void)
+{
+	return platform_driver_register(&max8925_backlight_driver);
+}
+module_init(max8925_backlight_init);
+
+static void __exit max8925_backlight_exit(void)
+{
+	platform_driver_unregister(&max8925_backlight_driver);
+};
+module_exit(max8925_backlight_exit);
+
+MODULE_DESCRIPTION("Backlight Driver for Maxim MAX8925");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:max8925-backlight");
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/mbp_nvidia_bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/mbp_nvidia_bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/mbp_nvidia_bl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/mbp_nvidia_bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -139,6 +139,51 @@ static int mbp_dmi_match(const struct dm
 static const struct dmi_system_id __initdata mbp_device_table[] = {
 	{
 		.callback	= mbp_dmi_match,
+		.ident		= "MacBook 1,1",
+		.matches	= {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"),
+		},
+		.driver_data	= (void *)&intel_chipset_data,
+	},
+	{
+		.callback	= mbp_dmi_match,
+		.ident		= "MacBook 2,1",
+		.matches	= {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"),
+		},
+		.driver_data	= (void *)&intel_chipset_data,
+	},
+	{
+		.callback	= mbp_dmi_match,
+		.ident		= "MacBook 3,1",
+		.matches	= {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBook3,1"),
+		},
+		.driver_data	= (void *)&intel_chipset_data,
+	},
+	{
+		.callback	= mbp_dmi_match,
+		.ident		= "MacBook 4,1",
+		.matches	= {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,1"),
+		},
+		.driver_data	= (void *)&intel_chipset_data,
+	},
+	{
+		.callback	= mbp_dmi_match,
+		.ident		= "MacBook 4,2",
+		.matches	= {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,2"),
+		},
+		.driver_data	= (void *)&intel_chipset_data,
+	},
+	{
+		.callback	= mbp_dmi_match,
 		.ident		= "MacBookPro 3,1",
 		.matches	= {
 			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
@@ -250,6 +295,7 @@ static const struct dmi_system_id __init
 
 static int __init mbp_init(void)
 {
+	struct backlight_properties props;
 	if (!dmi_check_system(mbp_device_table))
 		return -ENODEV;
 
@@ -257,14 +303,17 @@ static int __init mbp_init(void)
 						"Macbook Pro backlight"))
 		return -ENXIO;
 
-	mbp_backlight_device = backlight_device_register("mbp_backlight",
-					NULL, NULL, &driver_data->backlight_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = 15;
+	mbp_backlight_device = backlight_device_register("mbp_backlight", NULL,
+							 NULL,
+							 &driver_data->backlight_ops,
+							 &props);
 	if (IS_ERR(mbp_backlight_device)) {
 		release_region(driver_data->iostart, driver_data->iolen);
 		return PTR_ERR(mbp_backlight_device);
 	}
 
-	mbp_backlight_device->props.max_brightness = 15;
 	mbp_backlight_device->props.brightness =
 		driver_data->backlight_ops.get_brightness(mbp_backlight_device);
 	backlight_update_status(mbp_backlight_device);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/omap1_bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/omap1_bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/omap1_bl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/omap1_bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/fb.h>
 #include <linux/backlight.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <plat/board.h>
@@ -132,6 +133,7 @@ static const struct backlight_ops omapbl
 
 static int omapbl_probe(struct platform_device *pdev)
 {
+	struct backlight_properties props;
 	struct backlight_device *dev;
 	struct omap_backlight *bl;
 	struct omap_backlight_config *pdata = pdev->dev.platform_data;
@@ -143,7 +145,10 @@ static int omapbl_probe(struct platform_
 	if (unlikely(!bl))
 		return -ENOMEM;
 
-	dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = OMAPBL_MAX_INTENSITY;
+	dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops,
+					&props);
 	if (IS_ERR(dev)) {
 		kfree(bl);
 		return PTR_ERR(dev);
@@ -160,7 +165,6 @@ static int omapbl_probe(struct platform_
 	omap_cfg_reg(PWL);	/* Conflicts with UART3 */
 
 	dev->props.fb_blank = FB_BLANK_UNBLANK;
-	dev->props.max_brightness = OMAPBL_MAX_INTENSITY;
 	dev->props.brightness = pdata->default_intensity;
 	omapbl_update_status(dev);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/platform_lcd.c linux-libre-2.6.34-gnu1/drivers/video/backlight/platform_lcd.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/platform_lcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/platform_lcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/fb.h>
 #include <linux/backlight.h>
 #include <linux/lcd.h>
+#include <linux/slab.h>
 
 #include <video/platform_lcd.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/progear_bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/progear_bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/progear_bl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/progear_bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -61,8 +61,10 @@ static const struct backlight_ops progea
 
 static int progearbl_probe(struct platform_device *pdev)
 {
+	struct backlight_properties props;
 	u8 temp;
 	struct backlight_device *progear_backlight_device;
+	int ret;
 
 	pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL);
 	if (!pmu_dev) {
@@ -73,28 +75,37 @@ static int progearbl_probe(struct platfo
 	sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
 	if (!sb_dev) {
 		printk("ALI 1533 SB not found.\n");
-		pci_dev_put(pmu_dev);
-		return -ENODEV;
+		ret = -ENODEV;
+		goto put_pmu;
 	}
 
 	/*     Set SB_MPS1 to enable brightness control. */
 	pci_read_config_byte(sb_dev, SB_MPS1, &temp);
 	pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20);
 
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
 	progear_backlight_device = backlight_device_register("progear-bl",
 							     &pdev->dev, NULL,
-							     &progearbl_ops);
-	if (IS_ERR(progear_backlight_device))
-		return PTR_ERR(progear_backlight_device);
+							     &progearbl_ops,
+							     &props);
+	if (IS_ERR(progear_backlight_device)) {
+		ret = PTR_ERR(progear_backlight_device);
+		goto put_sb;
+	}
 
 	platform_set_drvdata(pdev, progear_backlight_device);
 
 	progear_backlight_device->props.power = FB_BLANK_UNBLANK;
 	progear_backlight_device->props.brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
-	progear_backlight_device->props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
 	progearbl_set_intensity(progear_backlight_device);
 
 	return 0;
+put_sb:
+	pci_dev_put(sb_dev);
+put_pmu:
+	pci_dev_put(pmu_dev);
+	return ret;
 }
 
 static int progearbl_remove(struct platform_device *pdev)
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/pwm_bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/pwm_bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/pwm_bl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/pwm_bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/err.h>
 #include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
+#include <linux/slab.h>
 
 struct pwm_bl_data {
 	struct pwm_device	*pwm;
@@ -65,6 +66,7 @@ static const struct backlight_ops pwm_ba
 
 static int pwm_backlight_probe(struct platform_device *pdev)
 {
+	struct backlight_properties props;
 	struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
 	struct backlight_device *bl;
 	struct pwm_bl_data *pb;
@@ -100,15 +102,16 @@ static int pwm_backlight_probe(struct pl
 	} else
 		dev_dbg(&pdev->dev, "got pwm for backlight\n");
 
-	bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev,
-			pb, &pwm_backlight_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = data->max_brightness;
+	bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
+				       &pwm_backlight_ops, &props);
 	if (IS_ERR(bl)) {
 		dev_err(&pdev->dev, "failed to register backlight\n");
 		ret = PTR_ERR(bl);
 		goto err_bl;
 	}
 
-	bl->props.max_brightness = data->max_brightness;
 	bl->props.brightness = data->dft_brightness;
 	backlight_update_status(bl);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/tdo24m.c linux-libre-2.6.34-gnu1/drivers/video/backlight/tdo24m.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/tdo24m.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/tdo24m.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/spi/tdo24m.h>
 #include <linux/fb.h>
 #include <linux/lcd.h>
+#include <linux/slab.h>
 
 #define POWER_IS_ON(pwr)	((pwr) <= FB_BLANK_NORMAL)
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/tosa_bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/tosa_bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/tosa_bl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/tosa_bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/gpio.h>
 #include <linux/fb.h>
 #include <linux/backlight.h>
+#include <linux/slab.h>
 
 #include <asm/mach/sharpsl_param.h>
 
@@ -80,6 +81,7 @@ static const struct backlight_ops bl_ops
 static int __devinit tosa_bl_probe(struct i2c_client *client,
 		const struct i2c_device_id *id)
 {
+	struct backlight_properties props;
 	struct tosa_bl_data *data = kzalloc(sizeof(struct tosa_bl_data), GFP_KERNEL);
 	int ret = 0;
 	if (!data)
@@ -99,15 +101,16 @@ static int __devinit tosa_bl_probe(struc
 	i2c_set_clientdata(client, data);
 	data->i2c = client;
 
-	data->bl = backlight_device_register("tosa-bl", &client->dev,
-			data, &bl_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = 512 - 1;
+	data->bl = backlight_device_register("tosa-bl", &client->dev, data,
+					     &bl_ops, &props);
 	if (IS_ERR(data->bl)) {
 		ret = PTR_ERR(data->bl);
 		goto err_reg;
 	}
 
 	data->bl->props.brightness = 69;
-	data->bl->props.max_brightness = 512 - 1;
 	data->bl->props.power = FB_BLANK_UNBLANK;
 
 	backlight_update_status(data->bl);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/tosa_lcd.c linux-libre-2.6.34-gnu1/drivers/video/backlight/tosa_lcd.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/tosa_lcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/tosa_lcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/device.h>
 #include <linux/spi/spi.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/lcd.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/backlight/wm831x_bl.c linux-libre-2.6.34-gnu1/drivers/video/backlight/wm831x_bl.c
--- linux-libre-2.6.33-gnu1/drivers/video/backlight/wm831x_bl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/backlight/wm831x_bl.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/fb.h>
 #include <linux/backlight.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/pdata.h>
@@ -125,6 +126,7 @@ static int wm831x_backlight_probe(struct
 	struct wm831x_backlight_pdata *pdata;
 	struct wm831x_backlight_data *data;
 	struct backlight_device *bl;
+	struct backlight_properties props;
 	int ret, i, max_isel, isink_reg, dcdc_cfg;
 
 	/* We need platform data */
@@ -191,15 +193,15 @@ static int wm831x_backlight_probe(struct
 	data->current_brightness = 0;
 	data->isink_reg = isink_reg;
 
-	bl = backlight_device_register("wm831x", &pdev->dev,
-			data, &wm831x_backlight_ops);
+	props.max_brightness = max_isel;
+	bl = backlight_device_register("wm831x", &pdev->dev, data,
+				       &wm831x_backlight_ops, &props);
 	if (IS_ERR(bl)) {
 		dev_err(&pdev->dev, "failed to register backlight\n");
 		kfree(data);
 		return PTR_ERR(bl);
 	}
 
-	bl->props.max_brightness = max_isel;
 	bl->props.brightness = max_isel;
 
 	platform_set_drvdata(pdev, bl);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/bf54x-lq043fb.c linux-libre-2.6.34-gnu1/drivers/video/bf54x-lq043fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/bf54x-lq043fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/bf54x-lq043fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -82,7 +82,6 @@ struct bfin_bf54xfb_info {
 	unsigned char *fb_buffer;	/* RGB Buffer */
 
 	dma_addr_t dma_handle;
-	int lq043_mmap;
 	int lq043_open_cnt;
 	int irq;
 	spinlock_t lock;	/* lock */
@@ -316,7 +315,6 @@ static int bfin_bf54x_fb_release(struct
 	spin_lock(&fbi->lock);
 
 	fbi->lq043_open_cnt--;
-	fbi->lq043_mmap = 0;
 
 	if (fbi->lq043_open_cnt <= 0) {
 
@@ -374,33 +372,6 @@ static int bfin_bf54x_fb_check_var(struc
 	return 0;
 }
 
-static int bfin_bf54x_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
-{
-
-	struct bfin_bf54xfb_info *fbi = info->par;
-
-	if (fbi->lq043_mmap)
-		return -1;
-
-	spin_lock(&fbi->lock);
-	fbi->lq043_mmap = 1;
-	spin_unlock(&fbi->lock);
-
-	vma->vm_start = (unsigned long)(fbi->fb_buffer);
-
-	vma->vm_end = vma->vm_start + info->fix.smem_len;
-	/* For those who don't understand how mmap works, go read
-	 *   Documentation/nommu-mmap.txt.
-	 * For those that do, you will know that the VM_MAYSHARE flag
-	 * must be set in the vma->vm_flags structure on noMMU
-	 *   Other flags can be set, and are documented in
-	 *   include/linux/mm.h
-	 */
-	vma->vm_flags |=  VM_MAYSHARE | VM_SHARED;
-
-	return 0;
-}
-
 int bfin_bf54x_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
 	if (nocursor)
@@ -452,7 +423,6 @@ static struct fb_ops bfin_bf54x_fb_ops =
 	.fb_fillrect = cfb_fillrect,
 	.fb_copyarea = cfb_copyarea,
 	.fb_imageblit = cfb_imageblit,
-	.fb_mmap = bfin_bf54x_fb_mmap,
 	.fb_cursor = bfin_bf54x_fb_cursor,
 	.fb_setcolreg = bfin_bf54x_fb_setcolreg,
 };
@@ -463,7 +433,7 @@ static int bl_get_brightness(struct back
 	return 0;
 }
 
-static struct backlight_ops bfin_lq043fb_bl_ops = {
+static const struct backlight_ops bfin_lq043fb_bl_ops = {
 	.get_brightness = bl_get_brightness,
 };
 
@@ -531,6 +501,7 @@ static irqreturn_t bfin_bf54x_irq_error(
 
 static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
 {
+	struct backlight_properties props;
 	struct bfin_bf54xfb_info *info;
 	struct fb_info *fbinfo;
 	int ret;
@@ -675,10 +646,16 @@ static int __devinit bfin_bf54x_probe(st
 		goto out8;
 	}
 #ifndef NO_BL_SUPPORT
-	bl_dev =
-	    backlight_device_register("bf54x-bl", NULL, NULL,
-				      &bfin_lq043fb_bl_ops);
-	bl_dev->props.max_brightness = 255;
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = 255;
+	bl_dev = backlight_device_register("bf54x-bl", NULL, NULL,
+					   &bfin_lq043fb_bl_ops, &props);
+	if (IS_ERR(bl_dev)) {
+		printk(KERN_ERR DRIVER_NAME
+			": unable to register backlight.\n");
+		ret = -EINVAL;
+		goto out9;
+	}
 
 	lcd_dev = lcd_device_register(DRIVER_NAME, &pdev->dev, NULL, &bfin_lcd_ops);
 	lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n");
@@ -686,6 +663,8 @@ static int __devinit bfin_bf54x_probe(st
 
 	return 0;
 
+out9:
+	unregister_framebuffer(fbinfo);
 out8:
 	free_irq(info->irq, info);
 out7:
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/bfin-lq035q1-fb.c linux-libre-2.6.34-gnu1/drivers/video/bfin-lq035q1-fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/bfin-lq035q1-fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/bfin-lq035q1-fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/fb.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
@@ -22,7 +23,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
-#include <linux/dma-mapping.h>
 
 #include <asm/blackfin.h>
 #include <asm/irq.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/bfin-t350mcqb-fb.c linux-libre-2.6.34-gnu1/drivers/video/bfin-t350mcqb-fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/bfin-t350mcqb-fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/bfin-t350mcqb-fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/gfp.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/types.h>
@@ -87,7 +88,6 @@ struct bfin_t350mcqbfb_info {
 	struct device *dev;
 	unsigned char *fb_buffer;	/* RGB Buffer */
 	dma_addr_t dma_handle;
-	int lq043_mmap;
 	int lq043_open_cnt;
 	int irq;
 	spinlock_t lock;	/* lock */
@@ -235,7 +235,6 @@ static int bfin_t350mcqb_fb_release(stru
 	spin_lock(&fbi->lock);
 
 	fbi->lq043_open_cnt--;
-	fbi->lq043_mmap = 0;
 
 	if (fbi->lq043_open_cnt <= 0) {
 		bfin_t350mcqb_disable_ppi();
@@ -293,32 +292,6 @@ static int bfin_t350mcqb_fb_check_var(st
 	return 0;
 }
 
-static int bfin_t350mcqb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
-{
-	struct bfin_t350mcqbfb_info *fbi = info->par;
-
-	if (fbi->lq043_mmap)
-		return -1;
-
-	spin_lock(&fbi->lock);
-	fbi->lq043_mmap = 1;
-	spin_unlock(&fbi->lock);
-
-	vma->vm_start = (unsigned long)(fbi->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET);
-
-	vma->vm_end = vma->vm_start + info->fix.smem_len;
-	/* For those who don't understand how mmap works, go read
-	 *   Documentation/nommu-mmap.txt.
-	 * For those that do, you will know that the VM_MAYSHARE flag
-	 * must be set in the vma->vm_flags structure on noMMU
-	 *   Other flags can be set, and are documented in
-	 *   include/linux/mm.h
-	 */
-	vma->vm_flags |= VM_MAYSHARE | VM_SHARED;
-
-	return 0;
-}
-
 int bfin_t350mcqb_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
 	if (nocursor)
@@ -370,7 +343,6 @@ static struct fb_ops bfin_t350mcqb_fb_op
 	.fb_fillrect = cfb_fillrect,
 	.fb_copyarea = cfb_copyarea,
 	.fb_imageblit = cfb_imageblit,
-	.fb_mmap = bfin_t350mcqb_fb_mmap,
 	.fb_cursor = bfin_t350mcqb_fb_cursor,
 	.fb_setcolreg = bfin_t350mcqb_fb_setcolreg,
 };
@@ -381,7 +353,7 @@ static int bl_get_brightness(struct back
 	return 0;
 }
 
-static struct backlight_ops bfin_lq043fb_bl_ops = {
+static const struct backlight_ops bfin_lq043fb_bl_ops = {
 	.get_brightness = bl_get_brightness,
 };
 
@@ -448,6 +420,7 @@ static irqreturn_t bfin_t350mcqb_irq_err
 
 static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
 {
+	struct backlight_properties props;
 	struct bfin_t350mcqbfb_info *info;
 	struct fb_info *fbinfo;
 	int ret;
@@ -515,9 +488,9 @@ static int __devinit bfin_t350mcqb_probe
 	fbinfo->fbops = &bfin_t350mcqb_fb_ops;
 	fbinfo->flags = FBINFO_FLAG_DEFAULT;
 
-	info->fb_buffer =
-	    dma_alloc_coherent(NULL, fbinfo->fix.smem_len, &info->dma_handle,
-			       GFP_KERNEL);
+	info->fb_buffer = dma_alloc_coherent(NULL, fbinfo->fix.smem_len +
+				ACTIVE_VIDEO_MEM_OFFSET,
+				&info->dma_handle, GFP_KERNEL);
 
 	if (NULL == info->fb_buffer) {
 		printk(KERN_ERR DRIVER_NAME
@@ -569,10 +542,16 @@ static int __devinit bfin_t350mcqb_probe
 		goto out8;
 	}
 #ifndef NO_BL_SUPPORT
-	bl_dev =
-	    backlight_device_register("bf52x-bl", NULL, NULL,
-				      &bfin_lq043fb_bl_ops);
-	bl_dev->props.max_brightness = 255;
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = 255;
+	bl_dev = backlight_device_register("bf52x-bl", NULL, NULL,
+					   &bfin_lq043fb_bl_ops, &props);
+	if (IS_ERR(bl_dev)) {
+		printk(KERN_ERR DRIVER_NAME
+			": unable to register backlight.\n");
+		ret = -EINVAL;
+		goto out9;
+	}
 
 	lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops);
 	lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n");
@@ -580,6 +559,8 @@ static int __devinit bfin_t350mcqb_probe
 
 	return 0;
 
+out9:
+	unregister_framebuffer(fbinfo);
 out8:
 	free_irq(info->irq, info);
 out7:
@@ -587,8 +568,8 @@ out7:
 out6:
 	fb_dealloc_cmap(&fbinfo->cmap);
 out4:
-	dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
-			  info->dma_handle);
+	dma_free_coherent(NULL, fbinfo->fix.smem_len + ACTIVE_VIDEO_MEM_OFFSET,
+			 info->fb_buffer, info->dma_handle);
 out3:
 	framebuffer_release(fbinfo);
 out2:
@@ -611,8 +592,9 @@ static int __devexit bfin_t350mcqb_remov
 	free_irq(info->irq, info);
 
 	if (info->fb_buffer != NULL)
-		dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
-				  info->dma_handle);
+		dma_free_coherent(NULL, fbinfo->fix.smem_len +
+			ACTIVE_VIDEO_MEM_OFFSET, info->fb_buffer,
+			info->dma_handle);
 
 	fb_dealloc_cmap(&fbinfo->cmap);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/broadsheetfb.c linux-libre-2.6.34-gnu1/drivers/video/broadsheetfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/broadsheetfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/broadsheetfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,11 +29,65 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/list.h>
+#include <linux/firmware.h>
 #include <linux/uaccess.h>
 
 #include <video/broadsheetfb.h>
 
-/* Display specific information */
+/* track panel specific parameters */
+struct panel_info {
+	int w;
+	int h;
+	u16 sdcfg;
+	u16 gdcfg;
+	u16 lutfmt;
+	u16 fsynclen;
+	u16 fendfbegin;
+	u16 lsynclen;
+	u16 lendlbegin;
+	u16 pixclk;
+};
+
+/* table of panel specific parameters to be indexed into by the board drivers */
+static struct panel_info panel_table[] = {
+	{	/* standard 6" on TFT backplane */
+		.w = 800,
+		.h = 600,
+		.sdcfg = (100 | (1 << 8) | (1 << 9)),
+		.gdcfg = 2,
+		.lutfmt = (4 | (1 << 7)),
+		.fsynclen = 4,
+		.fendfbegin = (10 << 8) | 4,
+		.lsynclen = 10,
+		.lendlbegin = (100 << 8) | 4,
+		.pixclk = 6,
+	},
+	{	/* custom 3.7" flexible on PET or steel */
+		.w = 320,
+		.h = 240,
+		.sdcfg = (67 | (0 << 8) | (0 << 9) | (0 << 10) | (0 << 12)),
+		.gdcfg = 3,
+		.lutfmt = (4 | (1 << 7)),
+		.fsynclen = 0,
+		.fendfbegin = (80 << 8) | 4,
+		.lsynclen = 10,
+		.lendlbegin = (80 << 8) | 20,
+		.pixclk = 14,
+	},
+	{	/* standard 9.7" on TFT backplane */
+		.w = 1200,
+		.h = 825,
+		.sdcfg = (100 | (1 << 8) | (1 << 9) | (0 << 10) | (0 << 12)),
+		.gdcfg = 2,
+		.lutfmt = (4 | (1 << 7)),
+		.fsynclen = 0,
+		.fendfbegin = (4 << 8) | 4,
+		.lsynclen = 4,
+		.lendlbegin = (60 << 8) | 10,
+		.pixclk = 3,
+	},
+};
+
 #define DPY_W 800
 #define DPY_H 600
 
@@ -62,30 +116,30 @@ static struct fb_var_screeninfo broadshe
 };
 
 /* main broadsheetfb functions */
-static void broadsheet_issue_data(struct broadsheetfb_par *par, u16 data)
+static void broadsheet_gpio_issue_data(struct broadsheetfb_par *par, u16 data)
 {
 	par->board->set_ctl(par, BS_WR, 0);
 	par->board->set_hdb(par, data);
 	par->board->set_ctl(par, BS_WR, 1);
 }
 
-static void broadsheet_issue_cmd(struct broadsheetfb_par *par, u16 data)
+static void broadsheet_gpio_issue_cmd(struct broadsheetfb_par *par, u16 data)
 {
 	par->board->set_ctl(par, BS_DC, 0);
-	broadsheet_issue_data(par, data);
+	broadsheet_gpio_issue_data(par, data);
 }
 
-static void broadsheet_send_command(struct broadsheetfb_par *par, u16 data)
+static void broadsheet_gpio_send_command(struct broadsheetfb_par *par, u16 data)
 {
 	par->board->wait_for_rdy(par);
 
 	par->board->set_ctl(par, BS_CS, 0);
-	broadsheet_issue_cmd(par, data);
+	broadsheet_gpio_issue_cmd(par, data);
 	par->board->set_ctl(par, BS_DC, 1);
 	par->board->set_ctl(par, BS_CS, 1);
 }
 
-static void broadsheet_send_cmdargs(struct broadsheetfb_par *par, u16 cmd,
+static void broadsheet_gpio_send_cmdargs(struct broadsheetfb_par *par, u16 cmd,
 					int argc, u16 *argv)
 {
 	int i;
@@ -93,15 +147,43 @@ static void broadsheet_send_cmdargs(stru
 	par->board->wait_for_rdy(par);
 
 	par->board->set_ctl(par, BS_CS, 0);
-	broadsheet_issue_cmd(par, cmd);
+	broadsheet_gpio_issue_cmd(par, cmd);
 	par->board->set_ctl(par, BS_DC, 1);
 
 	for (i = 0; i < argc; i++)
-		broadsheet_issue_data(par, argv[i]);
+		broadsheet_gpio_issue_data(par, argv[i]);
 	par->board->set_ctl(par, BS_CS, 1);
 }
 
-static void broadsheet_burst_write(struct broadsheetfb_par *par, int size,
+static void broadsheet_mmio_send_cmdargs(struct broadsheetfb_par *par, u16 cmd,
+				    int argc, u16 *argv)
+{
+	int i;
+
+	par->board->mmio_write(par, BS_MMIO_CMD, cmd);
+
+	for (i = 0; i < argc; i++)
+		par->board->mmio_write(par, BS_MMIO_DATA, argv[i]);
+}
+
+static void broadsheet_send_command(struct broadsheetfb_par *par, u16 data)
+{
+	if (par->board->mmio_write)
+		par->board->mmio_write(par, BS_MMIO_CMD, data);
+	else
+		broadsheet_gpio_send_command(par, data);
+}
+
+static void broadsheet_send_cmdargs(struct broadsheetfb_par *par, u16 cmd,
+				    int argc, u16 *argv)
+{
+	if (par->board->mmio_write)
+		broadsheet_mmio_send_cmdargs(par, cmd, argc, argv);
+	else
+		broadsheet_gpio_send_cmdargs(par, cmd, argc, argv);
+}
+
+static void broadsheet_gpio_burst_write(struct broadsheetfb_par *par, int size,
 					u16 *data)
 {
 	int i;
@@ -121,7 +203,30 @@ static void broadsheet_burst_write(struc
 	par->board->set_ctl(par, BS_CS, 1);
 }
 
-static u16 broadsheet_get_data(struct broadsheetfb_par *par)
+static void broadsheet_mmio_burst_write(struct broadsheetfb_par *par, int size,
+				   u16 *data)
+{
+	int i;
+	u16 tmp;
+
+	for (i = 0; i < size; i++) {
+		tmp = (data[i] & 0x0F) << 4;
+		tmp |= (data[i] & 0x0F00) << 4;
+		par->board->mmio_write(par, BS_MMIO_DATA, tmp);
+	}
+
+}
+
+static void broadsheet_burst_write(struct broadsheetfb_par *par, int size,
+				   u16 *data)
+{
+	if (par->board->mmio_write)
+		broadsheet_mmio_burst_write(par, size, data);
+	else
+		broadsheet_gpio_burst_write(par, size, data);
+}
+
+static u16 broadsheet_gpio_get_data(struct broadsheetfb_par *par)
 {
 	u16 res;
 	/* wait for ready to go hi. (lo is busy) */
@@ -141,7 +246,16 @@ static u16 broadsheet_get_data(struct br
 	return res;
 }
 
-static void broadsheet_write_reg(struct broadsheetfb_par *par, u16 reg,
+
+static u16 broadsheet_get_data(struct broadsheetfb_par *par)
+{
+	if (par->board->mmio_read)
+		return par->board->mmio_read(par);
+	else
+		return broadsheet_gpio_get_data(par);
+}
+
+static void broadsheet_gpio_write_reg(struct broadsheetfb_par *par, u16 reg,
 					u16 data)
 {
 	/* wait for ready to go hi. (lo is busy) */
@@ -150,44 +264,541 @@ static void broadsheet_write_reg(struct
 	/* cs lo, dc lo for cmd, we lo for each data, db as usual */
 	par->board->set_ctl(par, BS_CS, 0);
 
-	broadsheet_issue_cmd(par, BS_CMD_WR_REG);
+	broadsheet_gpio_issue_cmd(par, BS_CMD_WR_REG);
 
 	par->board->set_ctl(par, BS_DC, 1);
 
-	broadsheet_issue_data(par, reg);
-	broadsheet_issue_data(par, data);
+	broadsheet_gpio_issue_data(par, reg);
+	broadsheet_gpio_issue_data(par, data);
 
 	par->board->set_ctl(par, BS_CS, 1);
 }
 
+static void broadsheet_mmio_write_reg(struct broadsheetfb_par *par, u16 reg,
+				 u16 data)
+{
+	par->board->mmio_write(par, BS_MMIO_CMD, BS_CMD_WR_REG);
+	par->board->mmio_write(par, BS_MMIO_DATA, reg);
+	par->board->mmio_write(par, BS_MMIO_DATA, data);
+
+}
+
+static void broadsheet_write_reg(struct broadsheetfb_par *par, u16 reg,
+					u16 data)
+{
+	if (par->board->mmio_write)
+		broadsheet_mmio_write_reg(par, reg, data);
+	else
+		broadsheet_gpio_write_reg(par, reg, data);
+}
+
+static void broadsheet_write_reg32(struct broadsheetfb_par *par, u16 reg,
+					u32 data)
+{
+	broadsheet_write_reg(par, reg, cpu_to_le32(data) & 0xFFFF);
+	broadsheet_write_reg(par, reg + 2, (cpu_to_le32(data) >> 16) & 0xFFFF);
+}
+
+
 static u16 broadsheet_read_reg(struct broadsheetfb_par *par, u16 reg)
 {
-	broadsheet_send_command(par, reg);
-	msleep(100);
+	broadsheet_send_cmdargs(par, BS_CMD_RD_REG, 1, &reg);
+	par->board->wait_for_rdy(par);
 	return broadsheet_get_data(par);
 }
 
+/* functions for waveform manipulation */
+static int is_broadsheet_pll_locked(struct broadsheetfb_par *par)
+{
+	return broadsheet_read_reg(par, 0x000A) & 0x0001;
+}
+
+static int broadsheet_setup_plls(struct broadsheetfb_par *par)
+{
+	int retry_count = 0;
+	u16 tmp;
+
+	/* disable arral saemipu mode */
+	broadsheet_write_reg(par, 0x0006, 0x0000);
+
+	broadsheet_write_reg(par, 0x0010, 0x0004);
+	broadsheet_write_reg(par, 0x0012, 0x5949);
+	broadsheet_write_reg(par, 0x0014, 0x0040);
+	broadsheet_write_reg(par, 0x0016, 0x0000);
+
+	do {
+		if (retry_count++ > 100)
+			return -ETIMEDOUT;
+		mdelay(1);
+	} while (!is_broadsheet_pll_locked(par));
+
+	tmp = broadsheet_read_reg(par, 0x0006);
+	tmp &= ~0x1;
+	broadsheet_write_reg(par, 0x0006, tmp);
+
+	return 0;
+}
+
+static int broadsheet_setup_spi(struct broadsheetfb_par *par)
+{
+
+	broadsheet_write_reg(par, 0x0204, ((3 << 3) | 1));
+	broadsheet_write_reg(par, 0x0208, 0x0001);
+
+	return 0;
+}
+
+static int broadsheet_setup_spiflash(struct broadsheetfb_par *par,
+						u16 *orig_sfmcd)
+{
+
+	*orig_sfmcd = broadsheet_read_reg(par, 0x0204);
+	broadsheet_write_reg(par, 0x0208, 0);
+	broadsheet_write_reg(par, 0x0204, 0);
+	broadsheet_write_reg(par, 0x0204, ((3 << 3) | 1));
+
+	return 0;
+}
+
+static int broadsheet_spiflash_wait_for_bit(struct broadsheetfb_par *par,
+						u16 reg, int bitnum, int val,
+						int timeout)
+{
+	u16 tmp;
+
+	do {
+		tmp = broadsheet_read_reg(par, reg);
+		if (((tmp >> bitnum) & 1) == val)
+			return 0;
+		mdelay(1);
+	} while (timeout--);
+
+	return -ETIMEDOUT;
+}
+
+static int broadsheet_spiflash_write_byte(struct broadsheetfb_par *par, u8 data)
+{
+	broadsheet_write_reg(par, 0x0202, (data | 0x100));
+
+	return broadsheet_spiflash_wait_for_bit(par, 0x0206, 3, 0, 100);
+}
+
+static int broadsheet_spiflash_read_byte(struct broadsheetfb_par *par, u8 *data)
+{
+	int err;
+	u16 tmp;
+
+	broadsheet_write_reg(par, 0x0202, 0);
+
+	err = broadsheet_spiflash_wait_for_bit(par, 0x0206, 3, 0, 100);
+	if (err)
+		return err;
+
+	tmp = broadsheet_read_reg(par, 0x200);
+
+	*data = tmp & 0xFF;
+
+	return 0;
+}
+
+static int broadsheet_spiflash_wait_for_status(struct broadsheetfb_par *par,
+								int timeout)
+{
+	u8 tmp;
+	int err;
+
+	do {
+		broadsheet_write_reg(par, 0x0208, 1);
+
+		err = broadsheet_spiflash_write_byte(par, 0x05);
+		if (err)
+			goto failout;
+
+		err = broadsheet_spiflash_read_byte(par, &tmp);
+		if (err)
+			goto failout;
+
+		broadsheet_write_reg(par, 0x0208, 0);
+
+		if (!(tmp & 0x1))
+			return 0;
+
+		mdelay(5);
+	} while (timeout--);
+
+	dev_err(par->info->device, "Timed out waiting for spiflash status\n");
+	return -ETIMEDOUT;
+
+failout:
+	broadsheet_write_reg(par, 0x0208, 0);
+	return err;
+}
+
+static int broadsheet_spiflash_op_on_address(struct broadsheetfb_par *par,
+							u8 op, u32 addr)
+{
+	int i;
+	u8 tmp;
+	int err;
+
+	broadsheet_write_reg(par, 0x0208, 1);
+
+	err = broadsheet_spiflash_write_byte(par, op);
+	if (err)
+		return err;
+
+	for (i = 2; i >= 0; i--) {
+		tmp = ((addr >> (i * 8)) & 0xFF);
+		err = broadsheet_spiflash_write_byte(par, tmp);
+		if (err)
+			return err;
+	}
+
+	return err;
+}
+
+static int broadsheet_verify_spiflash(struct broadsheetfb_par *par,
+						int *flash_type)
+{
+	int err = 0;
+	u8 sig;
+
+	err = broadsheet_spiflash_op_on_address(par, 0xAB, 0x00000000);
+	if (err)
+		goto failout;
+
+	err = broadsheet_spiflash_read_byte(par, &sig);
+	if (err)
+		goto failout;
+
+	if ((sig != 0x10) && (sig != 0x11)) {
+		dev_err(par->info->device, "Unexpected flash type\n");
+		err = -EINVAL;
+		goto failout;
+	}
+
+	*flash_type = sig;
+
+failout:
+	broadsheet_write_reg(par, 0x0208, 0);
+	return err;
+}
+
+static int broadsheet_setup_for_wfm_write(struct broadsheetfb_par *par,
+					u16 *initial_sfmcd, int *flash_type)
+
+{
+	int err;
+
+	err = broadsheet_setup_plls(par);
+	if (err)
+		return err;
+
+	broadsheet_write_reg(par, 0x0106, 0x0203);
+
+	err = broadsheet_setup_spi(par);
+	if (err)
+		return err;
+
+	err = broadsheet_setup_spiflash(par, initial_sfmcd);
+	if (err)
+		return err;
+
+	return broadsheet_verify_spiflash(par, flash_type);
+}
+
+static int broadsheet_spiflash_write_control(struct broadsheetfb_par *par,
+						int mode)
+{
+	int err;
+
+	broadsheet_write_reg(par, 0x0208, 1);
+	if (mode)
+		err = broadsheet_spiflash_write_byte(par, 0x06);
+	else
+		err = broadsheet_spiflash_write_byte(par, 0x04);
+
+	broadsheet_write_reg(par, 0x0208, 0);
+	return err;
+}
+
+static int broadsheet_spiflash_erase_sector(struct broadsheetfb_par *par,
+						int addr)
+{
+	int err;
+
+	broadsheet_spiflash_write_control(par, 1);
+
+	err = broadsheet_spiflash_op_on_address(par, 0xD8, addr);
+
+	broadsheet_write_reg(par, 0x0208, 0);
+
+	if (err)
+		return err;
+
+	err = broadsheet_spiflash_wait_for_status(par, 1000);
+
+	return err;
+}
+
+static int broadsheet_spiflash_read_range(struct broadsheetfb_par *par,
+						int addr, int size, char *data)
+{
+	int err;
+	int i;
+
+	err = broadsheet_spiflash_op_on_address(par, 0x03, addr);
+	if (err)
+		goto failout;
+
+	for (i = 0; i < size; i++) {
+		err = broadsheet_spiflash_read_byte(par, &data[i]);
+		if (err)
+			goto failout;
+	}
+
+failout:
+	broadsheet_write_reg(par, 0x0208, 0);
+	return err;
+}
+
+#define BS_SPIFLASH_PAGE_SIZE 256
+static int broadsheet_spiflash_write_page(struct broadsheetfb_par *par,
+						int addr, const char *data)
+{
+	int err;
+	int i;
+
+	broadsheet_spiflash_write_control(par, 1);
+
+	err = broadsheet_spiflash_op_on_address(par, 0x02, addr);
+	if (err)
+		goto failout;
+
+	for (i = 0; i < BS_SPIFLASH_PAGE_SIZE; i++) {
+		err = broadsheet_spiflash_write_byte(par, data[i]);
+		if (err)
+			goto failout;
+	}
+
+	broadsheet_write_reg(par, 0x0208, 0);
+
+	err = broadsheet_spiflash_wait_for_status(par, 100);
+
+failout:
+	return err;
+}
+
+static int broadsheet_spiflash_write_sector(struct broadsheetfb_par *par,
+				int addr, const char *data, int sector_size)
+{
+	int i;
+	int err;
+
+	for (i = 0; i < sector_size; i += BS_SPIFLASH_PAGE_SIZE) {
+		err = broadsheet_spiflash_write_page(par, addr + i, &data[i]);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
+/*
+ * The caller must guarantee that the data to be rewritten is entirely
+ * contained within this sector. That is, data_start_addr + data_len
+ * must be less than sector_start_addr + sector_size.
+ */
+static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par,
+					int sector_size, int data_start_addr,
+					int data_len, const char *data)
+{
+	int err;
+	char *sector_buffer;
+	int tail_start_addr;
+	int start_sector_addr;
+
+	sector_buffer = kzalloc(sizeof(char)*sector_size, GFP_KERNEL);
+	if (!sector_buffer)
+		return -ENOMEM;
+
+	/* the start address of the sector is the 0th byte of that sector */
+	start_sector_addr = (data_start_addr / sector_size) * sector_size;
+
+	/*
+	 * check if there is head data that we need to readback into our sector
+	 * buffer first
+	 */
+	if (data_start_addr != start_sector_addr) {
+		/*
+		 * we need to read every byte up till the start address of our
+		 * data and we put it into our sector buffer.
+		 */
+		err = broadsheet_spiflash_read_range(par, start_sector_addr,
+						data_start_addr, sector_buffer);
+		if (err)
+			return err;
+	}
+
+	/* now we copy our data into the right place in the sector buffer */
+	memcpy(sector_buffer + data_start_addr, data, data_len);
+
+	/*
+	 * now we check if there is a tail section of the sector that we need to
+	 * readback.
+	 */
+	tail_start_addr = (data_start_addr + data_len) % sector_size;
+
+	if (tail_start_addr) {
+		int tail_len;
+
+		tail_len = sector_size - tail_start_addr;
+
+		/* now we read this tail into our sector buffer */
+		err = broadsheet_spiflash_read_range(par, tail_start_addr,
+			tail_len, sector_buffer + tail_start_addr);
+		if (err)
+			return err;
+	}
+
+	/* if we got here we have the full sector that we want to rewrite. */
+
+	/* first erase the sector */
+	err = broadsheet_spiflash_erase_sector(par, start_sector_addr);
+	if (err)
+		return err;
+
+	/* now write it */
+	err = broadsheet_spiflash_write_sector(par, start_sector_addr,
+					sector_buffer, sector_size);
+	return err;
+}
+
+static int broadsheet_write_spiflash(struct broadsheetfb_par *par, u32 wfm_addr,
+				const u8 *wfm, int bytecount, int flash_type)
+{
+	int sector_size;
+	int err;
+	int cur_addr;
+	int writecount;
+	int maxlen;
+	int offset = 0;
+
+	switch (flash_type) {
+	case 0x10:
+		sector_size = 32*1024;
+		break;
+	case 0x11:
+	default:
+		sector_size = 64*1024;
+		break;
+	}
+
+	while (bytecount) {
+		cur_addr = wfm_addr + offset;
+		maxlen = roundup(cur_addr, sector_size) - cur_addr;
+		writecount = min(bytecount, maxlen);
+
+		err = broadsheet_spiflash_rewrite_sector(par, sector_size,
+				cur_addr, writecount, wfm + offset);
+		if (err)
+			return err;
+
+		offset += writecount;
+		bytecount -= writecount;
+	}
+
+	return 0;
+}
+
+static int broadsheet_store_waveform_to_spiflash(struct broadsheetfb_par *par,
+						const u8 *wfm, size_t wfm_size)
+{
+	int err = 0;
+	u16 initial_sfmcd = 0;
+	int flash_type = 0;
+
+	err = broadsheet_setup_for_wfm_write(par, &initial_sfmcd, &flash_type);
+	if (err)
+		goto failout;
+
+	err = broadsheet_write_spiflash(par, 0x886, wfm, wfm_size, flash_type);
+
+failout:
+	broadsheet_write_reg(par, 0x0204, initial_sfmcd);
+	return err;
+}
+
+static ssize_t broadsheet_loadstore_waveform(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf, size_t len)
+{
+	int err;
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct broadsheetfb_par *par = info->par;
+	const struct firmware *fw_entry;
+
+	if (len < 1)
+		return -EINVAL;
+
+	err = request_firmware(&fw_entry, "broadsheet.wbf", dev);
+	if (err < 0) {
+		dev_err(dev, "Failed to get broadsheet waveform\n");
+		goto err_failed;
+	}
+
+	/* try to enforce reasonable min max on waveform */
+	if ((fw_entry->size < 8*1024) || (fw_entry->size > 64*1024)) {
+		dev_err(dev, "Invalid waveform\n");
+		err = -EINVAL;
+		goto err_failed;
+	}
+
+	mutex_lock(&(par->io_lock));
+	err = broadsheet_store_waveform_to_spiflash(par, fw_entry->data,
+							fw_entry->size);
+
+	mutex_unlock(&(par->io_lock));
+	if (err < 0) {
+		dev_err(dev, "Failed to store broadsheet waveform\n");
+		goto err_failed;
+	}
+
+	dev_info(dev, "Stored broadsheet waveform, size %zd\n", fw_entry->size);
+
+	return len;
+
+err_failed:
+	return err;
+}
+static DEVICE_ATTR(loadstore_waveform, S_IWUSR, NULL,
+			broadsheet_loadstore_waveform);
+
+/* upper level functions that manipulate the display and other stuff */
 static void __devinit broadsheet_init_display(struct broadsheetfb_par *par)
 {
 	u16 args[5];
+	int xres = par->info->var.xres;
+	int yres = par->info->var.yres;
 
-	args[0] = DPY_W;
-	args[1] = DPY_H;
-	args[2] = (100 | (1 << 8) | (1 << 9)); /* sdcfg */
-	args[3] = 2; /* gdrv cfg */
-	args[4] = (4 | (1 << 7)); /* lut index format */
+	args[0] = panel_table[par->panel_index].w;
+	args[1] = panel_table[par->panel_index].h;
+	args[2] = panel_table[par->panel_index].sdcfg;
+	args[3] = panel_table[par->panel_index].gdcfg;
+	args[4] = panel_table[par->panel_index].lutfmt;
 	broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args);
 
 	/* did the controller really set it? */
 	broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args);
 
-	args[0] = 4; /* fsync len */
-	args[1] = (10 << 8) | 4; /* fend/fbegin len */
-	args[2] = 10; /* line sync len */
-	args[3] = (100 << 8) | 4; /* line end/begin len */
-	args[4] = 6; /* pixel clock cfg */
+	args[0] = panel_table[par->panel_index].fsynclen;
+	args[1] = panel_table[par->panel_index].fendfbegin;
+	args[2] = panel_table[par->panel_index].lsynclen;
+	args[3] = panel_table[par->panel_index].lendlbegin;
+	args[4] = panel_table[par->panel_index].pixclk;
 	broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_TMG, 5, args);
 
+	broadsheet_write_reg32(par, 0x310, xres*yres*2);
+
 	/* setup waveform */
 	args[0] = 0x886;
 	args[1] = 0;
@@ -207,8 +818,9 @@ static void __devinit broadsheet_init_di
 	args[0] = 0x154;
 	broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args);
 
-	broadsheet_burst_write(par, DPY_W*DPY_H/2,
-				(u16 *) par->info->screen_base);
+	broadsheet_burst_write(par, (panel_table[par->panel_index].w *
+					panel_table[par->panel_index].h)/2,
+					(u16 *) par->info->screen_base);
 
 	broadsheet_send_command(par, BS_CMD_LD_IMG_END);
 
@@ -222,6 +834,21 @@ static void __devinit broadsheet_init_di
 	par->board->wait_for_rdy(par);
 }
 
+static void __devinit broadsheet_identify(struct broadsheetfb_par *par)
+{
+	u16 rev, prc;
+	struct device *dev = par->info->device;
+
+	rev = broadsheet_read_reg(par, BS_REG_REV);
+	prc = broadsheet_read_reg(par, BS_REG_PRC);
+	dev_info(dev, "Broadsheet Rev 0x%x, Product Code 0x%x\n", rev, prc);
+
+	if (prc != 0x0047)
+		dev_warn(dev, "Unrecognized Broadsheet Product Code\n");
+	if (rev != 0x0100)
+		dev_warn(dev, "Unrecognized Broadsheet Revision\n");
+}
+
 static void __devinit broadsheet_init(struct broadsheetfb_par *par)
 {
 	broadsheet_send_command(par, BS_CMD_INIT_SYS_RUN);
@@ -236,6 +863,7 @@ static void broadsheetfb_dpy_update_page
 	u16 args[5];
 	unsigned char *buf = (unsigned char *)par->info->screen_base;
 
+	mutex_lock(&(par->io_lock));
 	/* y1 must be a multiple of 4 so drop the lower bits */
 	y1 &= 0xFFFC;
 	/* y2 must be a multiple of 4 , but - 1 so up the lower bits */
@@ -265,6 +893,7 @@ static void broadsheetfb_dpy_update_page
 	broadsheet_send_command(par, BS_CMD_WAIT_DSPE_FREND);
 
 	par->board->wait_for_rdy(par);
+	mutex_unlock(&(par->io_lock));
 
 }
 
@@ -272,13 +901,15 @@ static void broadsheetfb_dpy_update(stru
 {
 	u16 args[5];
 
+	mutex_lock(&(par->io_lock));
 	args[0] = 0x3 << 4;
 	broadsheet_send_cmdargs(par, BS_CMD_LD_IMG, 1, args);
 
 	args[0] = 0x154;
 	broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args);
-	broadsheet_burst_write(par, DPY_W*DPY_H/2,
-				(u16 *) par->info->screen_base);
+	broadsheet_burst_write(par, (panel_table[par->panel_index].w *
+					panel_table[par->panel_index].h)/2,
+					(u16 *) par->info->screen_base);
 
 	broadsheet_send_command(par, BS_CMD_LD_IMG_END);
 
@@ -290,7 +921,7 @@ static void broadsheetfb_dpy_update(stru
 	broadsheet_send_command(par, BS_CMD_WAIT_DSPE_FREND);
 
 	par->board->wait_for_rdy(par);
-
+	mutex_unlock(&(par->io_lock));
 }
 
 /* this is called back from the deferred io workqueue */
@@ -436,6 +1067,8 @@ static int __devinit broadsheetfb_probe(
 	unsigned char *videomemory;
 	struct broadsheetfb_par *par;
 	int i;
+	int dpyw, dpyh;
+	int panel_index;
 
 	/* pick up board specific routines */
 	board = dev->dev.platform_data;
@@ -450,7 +1083,24 @@ static int __devinit broadsheetfb_probe(
 	if (!info)
 		goto err;
 
-	videomemorysize = (DPY_W*DPY_H);
+	switch (board->get_panel_type()) {
+	case 37:
+		panel_index = 1;
+		break;
+	case 97:
+		panel_index = 2;
+		break;
+	case 6:
+	default:
+		panel_index = 0;
+		break;
+	}
+
+	dpyw = panel_table[panel_index].w;
+	dpyh = panel_table[panel_index].h;
+
+	videomemorysize = roundup((dpyw*dpyh), PAGE_SIZE);
+
 	videomemory = vmalloc(videomemorysize);
 	if (!videomemory)
 		goto err_fb_rel;
@@ -460,16 +1110,25 @@ static int __devinit broadsheetfb_probe(
 	info->screen_base = (char *)videomemory;
 	info->fbops = &broadsheetfb_ops;
 
+	broadsheetfb_var.xres = dpyw;
+	broadsheetfb_var.yres = dpyh;
+	broadsheetfb_var.xres_virtual = dpyw;
+	broadsheetfb_var.yres_virtual = dpyh;
 	info->var = broadsheetfb_var;
+
+	broadsheetfb_fix.line_length = dpyw;
 	info->fix = broadsheetfb_fix;
 	info->fix.smem_len = videomemorysize;
 	par = info->par;
+	par->panel_index = panel_index;
 	par->info = info;
 	par->board = board;
 	par->write_reg = broadsheet_write_reg;
 	par->read_reg = broadsheet_read_reg;
 	init_waitqueue_head(&par->waitq);
 
+	mutex_init(&par->io_lock);
+
 	info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;
 
 	info->fbdefio = &broadsheetfb_defio;
@@ -496,13 +1155,20 @@ static int __devinit broadsheetfb_probe(
 	if (retval < 0)
 		goto err_free_irq;
 
+	broadsheet_identify(par);
+
 	broadsheet_init(par);
 
 	retval = register_framebuffer(info);
 	if (retval < 0)
 		goto err_free_irq;
+
 	platform_set_drvdata(dev, info);
 
+	retval = device_create_file(&dev->dev, &dev_attr_loadstore_waveform);
+	if (retval < 0)
+		goto err_unreg_fb;
+
 	printk(KERN_INFO
 	       "fb%d: Broadsheet frame buffer, using %dK of video memory\n",
 	       info->node, videomemorysize >> 10);
@@ -510,6 +1176,8 @@ static int __devinit broadsheetfb_probe(
 
 	return 0;
 
+err_unreg_fb:
+	unregister_framebuffer(info);
 err_free_irq:
 	board->cleanup(par);
 err_cmap:
@@ -530,6 +1198,8 @@ static int __devexit broadsheetfb_remove
 
 	if (info) {
 		struct broadsheetfb_par *par = info->par;
+
+		device_remove_file(info->dev, &dev_attr_loadstore_waveform);
 		unregister_framebuffer(info);
 		fb_deferred_io_cleanup(info);
 		par->board->cleanup(par);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/bw2.c linux-libre-2.6.34-gnu1/drivers/video/bw2.c
--- linux-libre-2.6.33-gnu1/drivers/video/bw2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/bw2.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/carminefb.c linux-libre-2.6.34-gnu1/drivers/video/carminefb.c
--- linux-libre-2.6.33-gnu1/drivers/video/carminefb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/carminefb.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/fb.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "carminefb.h"
 #include "carminefb_regs.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/cfbcopyarea.c linux-libre-2.6.34-gnu1/drivers/video/cfbcopyarea.c
--- linux-libre-2.6.33-gnu1/drivers/video/cfbcopyarea.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/cfbcopyarea.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,7 +26,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/fb.h>
-#include <linux/slab.h>
 #include <asm/types.h>
 #include <asm/io.h>
 #include "fb_draw.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/cg14.c linux-libre-2.6.34-gnu1/drivers/video/cg14.c
--- linux-libre-2.6.33-gnu1/drivers/video/cg14.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/cg14.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/cg3.c linux-libre-2.6.34-gnu1/drivers/video/cg3.c
--- linux-libre-2.6.33-gnu1/drivers/video/cg3.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/cg3.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/cg6.c linux-libre-2.6.34-gnu1/drivers/video/cg6.c
--- linux-libre-2.6.33-gnu1/drivers/video/cg6.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/cg6.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/chipsfb.c linux-libre-2.6.34-gnu1/drivers/video/chipsfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/chipsfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/chipsfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/cirrusfb.c linux-libre-2.6.34-gnu1/drivers/video/cirrusfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/cirrusfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/cirrusfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/cobalt_lcdfb.c linux-libre-2.6.34-gnu1/drivers/video/cobalt_lcdfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/cobalt_lcdfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/cobalt_lcdfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -287,7 +287,7 @@ static struct fb_ops cobalt_lcd_fbops =
 	.fb_cursor	= cobalt_lcdfb_cursor,
 };
 
-static int __init cobalt_lcdfb_probe(struct platform_device *dev)
+static int __devinit cobalt_lcdfb_probe(struct platform_device *dev)
 {
 	struct fb_info *info;
 	struct resource *res;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/console/bitblit.c linux-libre-2.6.34-gnu1/drivers/video/console/bitblit.c
--- linux-libre-2.6.33-gnu1/drivers/video/console/bitblit.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/console/bitblit.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/fb.h>
 #include <linux/vt_kern.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/console/fbcon.c linux-libre-2.6.34-gnu1/drivers/video/console/fbcon.c
--- linux-libre-2.6.33-gnu1/drivers/video/console/fbcon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/console/fbcon.c	2010-05-16 17:17:36.000000000 -0400
@@ -3025,6 +3025,20 @@ static int fbcon_fb_unregistered(struct
 	return 0;
 }
 
+static void fbcon_remap_all(int idx)
+{
+	int i;
+	for (i = first_fb_vc; i <= last_fb_vc; i++)
+		set_con2fb_map(i, idx, 0);
+
+	if (con_is_bound(&fb_con)) {
+		printk(KERN_INFO "fbcon: Remapping primary device, "
+		       "fb%i, to tty %i-%i\n", idx,
+		       first_fb_vc + 1, last_fb_vc + 1);
+		info_idx = idx;
+	}
+}
+
 #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
 static void fbcon_select_primary(struct fb_info *info)
 {
@@ -3225,6 +3239,10 @@ static int fbcon_event_notify(struct not
 		caps = event->data;
 		fbcon_get_requirement(info, caps);
 		break;
+	case FB_EVENT_REMAP_ALL_CONSOLE:
+		idx = info->node;
+		fbcon_remap_all(idx);
+		break;
 	}
 done:
 	return ret;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/console/fbcon_ccw.c linux-libre-2.6.34-gnu1/drivers/video/console/fbcon_ccw.c
--- linux-libre-2.6.33-gnu1/drivers/video/console/fbcon_ccw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/console/fbcon_ccw.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/fb.h>
 #include <linux/vt_kern.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/console/fbcon_cw.c linux-libre-2.6.34-gnu1/drivers/video/console/fbcon_cw.c
--- linux-libre-2.6.33-gnu1/drivers/video/console/fbcon_cw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/console/fbcon_cw.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/fb.h>
 #include <linux/vt_kern.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/console/fbcon_rotate.c linux-libre-2.6.34-gnu1/drivers/video/console/fbcon_rotate.c
--- linux-libre-2.6.33-gnu1/drivers/video/console/fbcon_rotate.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/console/fbcon_rotate.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/fb.h>
 #include <linux/vt_kern.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/console/fbcon_ud.c linux-libre-2.6.34-gnu1/drivers/video/console/fbcon_ud.c
--- linux-libre-2.6.33-gnu1/drivers/video/console/fbcon_ud.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/console/fbcon_ud.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/fb.h>
 #include <linux/vt_kern.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/console/Kconfig linux-libre-2.6.34-gnu1/drivers/video/console/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/video/console/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/console/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@ config VGACON_SOFT_SCROLLBACK
 config VGACON_SOFT_SCROLLBACK_SIZE
        int "Scrollback Buffer Size (in KB)"
        depends on VGACON_SOFT_SCROLLBACK
+       range 1 1024
        default "64"
        help
          Enter the amount of System RAM to allocate for the scrollback
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/console/mdacon.c linux-libre-2.6.34-gnu1/drivers/video/console/mdacon.c
--- linux-libre-2.6.33-gnu1/drivers/video/console/mdacon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/console/mdacon.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,7 +33,6 @@
 #include <linux/console.h>
 #include <linux/string.h>
 #include <linux/kd.h>
-#include <linux/slab.h>
 #include <linux/vt_kern.h>
 #include <linux/vt_buffer.h>
 #include <linux/selection.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/console/vgacon.c linux-libre-2.6.34-gnu1/drivers/video/console/vgacon.c
--- linux-libre-2.6.33-gnu1/drivers/video/console/vgacon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/console/vgacon.c	2010-05-16 17:17:36.000000000 -0400
@@ -112,7 +112,7 @@ static int 		vga_video_font_height;
 static int 		vga_scan_lines		__read_mostly;
 static unsigned int 	vga_rolled_over;
 
-int vgacon_text_mode_force = 0;
+static int vgacon_text_mode_force;
 
 bool vgacon_text_force(void)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/da8xx-fb.c linux-libre-2.6.34-gnu1/drivers/video/da8xx-fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/da8xx-fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/da8xx-fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/clk.h>
 #include <linux/cpufreq.h>
 #include <linux/console.h>
+#include <linux/slab.h>
 #include <video/da8xx-fb.h>
 
 #define DRIVER_NAME "da8xx_lcdc"
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/display/display-sysfs.c linux-libre-2.6.34-gnu1/drivers/video/display/display-sysfs.c
--- linux-libre-2.6.33-gnu1/drivers/video/display/display-sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/display/display-sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/idr.h>
 #include <linux/err.h>
 #include <linux/kdev_t.h>
+#include <linux/slab.h>
 
 static ssize_t display_show_name(struct device *dev,
 				struct device_attribute *attr, char *buf)
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/dnfb.c linux-libre-2.6.34-gnu1/drivers/video/dnfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/dnfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/dnfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/efifb.c linux-libre-2.6.34-gnu1/drivers/video/efifb.c
--- linux-libre-2.6.33-gnu1/drivers/video/efifb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/efifb.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,7 @@ enum {
 	M_MBP_2,	/* MacBook Pro 2nd gen */
 	M_MBP_SR,	/* MacBook Pro (Santa Rosa) */
 	M_MBP_4,	/* MacBook Pro, 4th gen */
+	M_MBP_5_1,    /* MacBook Pro, 5,1th gen */
 	M_UNKNOWN	/* placeholder */
 };
 
@@ -70,6 +71,7 @@ static struct efifb_dmi_info {
 	[M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */
 	[M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 },
 	[M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 },
+	[M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900 },
 	[M_UNKNOWN] = { NULL, 0, 0, 0, 0 }
 };
 
@@ -106,6 +108,7 @@ static struct dmi_system_id __initdata d
 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR),
 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR),
 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4),
+	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1),
 	{},
 };
 
@@ -210,7 +213,7 @@ static int __init efifb_setup(char *opti
 	return 0;
 }
 
-static int __init efifb_probe(struct platform_device *dev)
+static int __devinit efifb_probe(struct platform_device *dev)
 {
 	struct fb_info *info;
 	int err;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/ep93xx-fb.c linux-libre-2.6.34-gnu1/drivers/video/ep93xx-fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/ep93xx-fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/ep93xx-fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/fb.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/epson1355fb.c linux-libre-2.6.34-gnu1/drivers/video/epson1355fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/epson1355fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/epson1355fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,7 +48,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/init.h>
@@ -602,7 +601,7 @@ static int epson1355fb_remove(struct pla
 	return 0;
 }
 
-int __init epson1355fb_probe(struct platform_device *dev)
+int __devinit epson1355fb_probe(struct platform_device *dev)
 {
 	struct epson1355_par *default_par;
 	struct fb_info *info;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/fbcvt.c linux-libre-2.6.34-gnu1/drivers/video/fbcvt.c
--- linux-libre-2.6.33-gnu1/drivers/video/fbcvt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/fbcvt.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
  *
  */
 #include <linux/fb.h>
+#include <linux/slab.h>
 
 #define FB_CVT_CELLSIZE               8
 #define FB_CVT_GTF_C                 40
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/fb_ddc.c linux-libre-2.6.34-gnu1/drivers/video/fb_ddc.c
--- linux-libre-2.6.33-gnu1/drivers/video/fb_ddc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/fb_ddc.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/device.h>
 #include <linux/fb.h>
 #include <linux/i2c-algo-bit.h>
+#include <linux/slab.h>
 
 #include "edid.h"
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/fb_defio.c linux-libre-2.6.34-gnu1/drivers/video/fb_defio.c
--- linux-libre-2.6.33-gnu1/drivers/video/fb_defio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/fb_defio.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/fbmem.c linux-libre-2.6.34-gnu1/drivers/video/fbmem.c
--- linux-libre-2.6.33-gnu1/drivers/video/fbmem.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/fbmem.c	2010-05-16 17:17:36.000000000 -0400
@@ -1513,7 +1513,6 @@ register_framebuffer(struct fb_info *fb_
 				       fb_info->fix.id,
 				       registered_fb[i]->fix.id);
 				unregister_framebuffer(registered_fb[i]);
-				break;
 			}
 		}
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/fbmon.c linux-libre-2.6.34-gnu1/drivers/video/fbmon.c
--- linux-libre-2.6.33-gnu1/drivers/video/fbmon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/fbmon.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/fb.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <video/edid.h>
 #ifdef CONFIG_PPC_OF
 #include <asm/prom.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/fbsysfs.c linux-libre-2.6.34-gnu1/drivers/video/fbsysfs.c
--- linux-libre-2.6.33-gnu1/drivers/video/fbsysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/fbsysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/fb.h>
 #include <linux/console.h>
 #include <linux/module.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/ffb.c linux-libre-2.6.34-gnu1/drivers/video/ffb.c
--- linux-libre-2.6.33-gnu1/drivers/video/ffb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/ffb.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/fsl-diu-fb.c linux-libre-2.6.34-gnu1/drivers/video/fsl-diu-fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/fsl-diu-fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/fsl-diu-fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -1536,6 +1536,7 @@ static int __devinit fsl_diu_probe(struc
 		goto error;
 	}
 
+	sysfs_attr_init(&machine_data->dev_attr.attr);
 	machine_data->dev_attr.attr.name = "monitor";
 	machine_data->dev_attr.attr.mode = S_IRUGO|S_IWUSR;
 	machine_data->dev_attr.show = show_monitor;
@@ -1633,6 +1634,11 @@ static int __init fsl_diu_setup(char *op
 #endif
 
 static struct of_device_id fsl_diu_match[] = {
+#ifdef CONFIG_PPC_MPC512x
+	{
+		.compatible = "fsl,mpc5121-diu",
+	},
+#endif
 	{
 		.compatible = "fsl,diu",
 	},
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/g364fb.c linux-libre-2.6.34-gnu1/drivers/video/g364fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/g364fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/g364fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,7 +20,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/gbefb.c linux-libre-2.6.34-gnu1/drivers/video/gbefb.c
--- linux-libre-2.6.33-gnu1/drivers/video/gbefb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/gbefb.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -1128,7 +1129,7 @@ static int __init gbefb_setup(char *opti
 	return 0;
 }
 
-static int __init gbefb_probe(struct platform_device *p_dev)
+static int __devinit gbefb_probe(struct platform_device *p_dev)
 {
 	int i, ret = 0;
 	struct fb_info *info;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/geode/gx1fb_core.c linux-libre-2.6.34-gnu1/drivers/video/geode/gx1fb_core.c
--- linux-libre-2.6.33-gnu1/drivers/video/geode/gx1fb_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/geode/gx1fb_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/geode/gxfb_core.c linux-libre-2.6.34-gnu1/drivers/video/geode/gxfb_core.c
--- linux-libre-2.6.33-gnu1/drivers/video/geode/gxfb_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/geode/gxfb_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/console.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/geode/lxfb_core.c linux-libre-2.6.34-gnu1/drivers/video/geode/lxfb_core.c
--- linux-libre-2.6.33-gnu1/drivers/video/geode/lxfb_core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/geode/lxfb_core.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/string.h>
 #include <linux/console.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/suspend.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/geode/lxfb.h linux-libre-2.6.34-gnu1/drivers/video/geode/lxfb.h
--- linux-libre-2.6.33-gnu1/drivers/video/geode/lxfb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/geode/lxfb.h	2010-05-16 17:17:36.000000000 -0400
@@ -365,6 +365,8 @@ enum fp_registers {
 	FP_CRC, /* 0x458 */
 };
 
+#define FP_PT2_HSP			(1 << 22)
+#define FP_PT2_VSP			(1 << 23)
 #define FP_PT2_SCRC			(1 << 27)	/* shfclk free */
 
 #define FP_PM_P				(1 << 24)	/* panel power ctl */
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/geode/lxfb_ops.c linux-libre-2.6.34-gnu1/drivers/video/geode/lxfb_ops.c
--- linux-libre-2.6.33-gnu1/drivers/video/geode/lxfb_ops.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/geode/lxfb_ops.c	2010-05-16 17:17:36.000000000 -0400
@@ -274,7 +274,15 @@ static void lx_graphics_enable(struct fb
 		u32 msrlo, msrhi;
 
 		write_fp(par, FP_PT1, 0);
-		write_fp(par, FP_PT2, FP_PT2_SCRC);
+		temp = FP_PT2_SCRC;
+
+		if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
+			temp |= FP_PT2_HSP;
+
+		if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
+			temp |= FP_PT2_VSP;
+
+		write_fp(par, FP_PT2, temp);
 		write_fp(par, FP_DFC, FP_DFC_BC);
 
 		msrlo = MSR_LX_MSR_PADSEL_TFT_SEL_LOW;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/hecubafb.c linux-libre-2.6.34-gnu1/drivers/video/hecubafb.c
--- linux-libre-2.6.33-gnu1/drivers/video/hecubafb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/hecubafb.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,7 +32,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/hgafb.c linux-libre-2.6.34-gnu1/drivers/video/hgafb.c
--- linux-libre-2.6.33-gnu1/drivers/video/hgafb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/hgafb.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,7 +36,6 @@
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/init.h>
@@ -551,7 +550,7 @@ static struct fb_ops hgafb_ops = {
 	 *  Initialization
 	 */
 
-static int __init hgafb_probe(struct platform_device *pdev)
+static int __devinit hgafb_probe(struct platform_device *pdev)
 {
 	struct fb_info *info;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/hitfb.c linux-libre-2.6.34-gnu1/drivers/video/hitfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/hitfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/hitfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -325,7 +324,7 @@ static struct fb_ops hitfb_ops = {
 	.fb_imageblit	= cfb_imageblit,
 };
 
-static int __init hitfb_probe(struct platform_device *dev)
+static int __devinit hitfb_probe(struct platform_device *dev)
 {
 	unsigned short lcdclor, ldr3, ldvndr;
 	struct fb_info *info;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/hpfb.c linux-libre-2.6.34-gnu1/drivers/video/hpfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/hpfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/hpfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/i810/i810-i2c.c linux-libre-2.6.34-gnu1/drivers/video/i810/i810-i2c.c
--- linux-libre-2.6.33-gnu1/drivers/video/i810/i810-i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/i810/i810-i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/fb.h>
 #include "i810.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/imsttfb.c linux-libre-2.6.34-gnu1/drivers/video/imsttfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/imsttfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/imsttfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/intelfb/intelfbhw.c linux-libre-2.6.34-gnu1/drivers/video/intelfb/intelfbhw.c
--- linux-libre-2.6.33-gnu1/drivers/video/intelfb/intelfbhw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/intelfb/intelfbhw.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/ioport.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/Kconfig linux-libre-2.6.34-gnu1/drivers/video/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/video/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -400,9 +400,12 @@ config FB_SA1100
 	  If you plan to use the LCD display with your SA-1100 system, say
 	  Y here.
 
+config HAVE_FB_IMX
+	bool
+
 config FB_IMX
 	tristate "Motorola i.MX LCD support"
-	depends on FB && (ARCH_MX1 || ARCH_MX2)
+	depends on FB && (HAVE_FB_IMX || ARCH_MX1 || ARCH_MX2)
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
@@ -909,6 +912,18 @@ config FB_XVR2500
 	  mostly initialized the card already.  It is treated as a
 	  completely dumb framebuffer device.
 
+config FB_XVR1000
+	bool "Sun XVR-1000 support"
+	depends on (FB = y) && SPARC64
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the framebuffer device for the Sun XVR-1000 and similar
+	  graphics cards.  The driver only works on sparc64 systems where
+	  the system firmware has mostly initialized the card already.  It
+	  is treated as a completely dumb framebuffer device.
+
 config FB_PVR2
 	tristate "NEC PowerVR 2 display support"
 	depends on FB && SH_DREAMCAST
@@ -1494,7 +1509,6 @@ config FB_VIA
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        select I2C_ALGOBIT
        select I2C
        help
@@ -1867,7 +1881,7 @@ config FB_W100
 
 config FB_SH_MOBILE_LCDC
 	tristate "SuperH Mobile LCDC framebuffer support"
-	depends on FB && SUPERH && HAVE_CLK
+	depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
 	select FB_SYS_FILLRECT
 	select FB_SYS_COPYAREA
 	select FB_SYS_IMAGEBLIT
@@ -1945,6 +1959,27 @@ config FB_S3C2410_DEBUG
 	  Turn on debugging messages. Note that you can set/unset at run time
 	  through sysfs
 
+config FB_NUC900
+        bool "NUC900 LCD framebuffer support"
+        depends on FB && ARCH_W90X900
+        select FB_CFB_FILLRECT
+        select FB_CFB_COPYAREA
+        select FB_CFB_IMAGEBLIT
+        ---help---
+          Frame buffer driver for the built-in LCD controller in the Nuvoton
+          NUC900 processor
+
+config GPM1040A0_320X240
+        bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD"
+        depends on FB_NUC900
+
+config FB_NUC900_DEBUG
+        bool "NUC900 lcd debug messages"
+        depends on FB_NUC900
+        help
+          Turn on debugging messages. Note that you can set/unset at run time
+          through sysfs
+
 config FB_SM501
 	tristate "Silicon Motion SM501 framebuffer support"
 	depends on FB && MFD_SM501
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/leo.c linux-libre-2.6.34-gnu1/drivers/video/leo.c
--- linux-libre-2.6.33-gnu1/drivers/video/leo.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/leo.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/macfb.c linux-libre-2.6.34-gnu1/drivers/video/macfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/macfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/macfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,29 +1,33 @@
-/* macfb.c: Generic framebuffer for Macs whose colourmaps/modes we
-   don't know how to set */
-
-/* (c) 1999 David Huggins-Daines <dhd@debian.org>
-
-   Primarily based on vesafb.c, by Gerd Knorr
-   (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
-
-   Also uses information and code from:
-   
-   The original macfb.c from Linux/mac68k 2.0, by Alan Cox, Juergen
-   Mellinger, Mikael Forselius, Michael Schmitz, and others.
-
-   valkyriefb.c, by Martin Costabel, Kevin Schoedel, Barry Nathan, Dan
-   Jacobowitz, Paul Mackerras, Fabio Riccardi, and Geert Uytterhoeven.
-   
-   This code is free software.  You may copy, modify, and distribute
-   it subject to the terms and conditions of the GNU General Public
-   License, version 2, or any later version, at your convenience. */
+/*
+ * macfb.c: Generic framebuffer for Macs whose colourmaps/modes we
+ * don't know how to set.
+ *
+ * (c) 1999 David Huggins-Daines <dhd@debian.org>
+ *
+ * Primarily based on vesafb.c, by Gerd Knorr
+ * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
+ *
+ * Also uses information and code from:
+ *
+ * The original macfb.c from Linux/mac68k 2.0, by Alan Cox, Juergen
+ * Mellinger, Mikael Forselius, Michael Schmitz, and others.
+ *
+ * valkyriefb.c, by Martin Costabel, Kevin Schoedel, Barry Nathan, Dan
+ * Jacobowitz, Paul Mackerras, Fabio Riccardi, and Geert Uytterhoeven.
+ *
+ * The VideoToolbox "Bugs" web page at
+ * http://rajsky.psych.nyu.edu/Tips/VideoBugs.html
+ *
+ * This code is free software.  You may copy, modify, and distribute
+ * it subject to the terms and conditions of the GNU General Public
+ * License, version 2, or any later version, at your convenience.
+ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/nubus.h>
 #include <linux/init.h>
@@ -31,9 +35,6 @@
 
 #include <asm/setup.h>
 #include <asm/bootinfo.h>
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/irq.h>
 #include <asm/macintosh.h>
 #include <asm/io.h>
 
@@ -44,7 +45,7 @@
 #define DAFB_BASE 0xf9800200
 
 /* Address for the built-in Civic framebuffer in Quadra AVs */
-#define CIVIC_BASE 0x50f30800	/* Only tested on 660AV! */
+#define CIVIC_BASE 0x50f30800
 
 /* GSC (Gray Scale Controller) base address */
 #define GSC_BASE 0x50F20000
@@ -52,37 +53,9 @@
 /* CSC (Color Screen Controller) base address */
 #define CSC_BASE 0x50F20000
 
-static int (*macfb_setpalette) (unsigned int regno, unsigned int red,
-				unsigned int green, unsigned int blue,
-				struct fb_info *info) = NULL;
-static int valkyrie_setpalette (unsigned int regno, unsigned int red,
-				unsigned int green, unsigned int blue,
-				struct fb_info *info);
-static int dafb_setpalette (unsigned int regno, unsigned int red,
-			    unsigned int green, unsigned int blue,
-			    struct fb_info *fb_info);
-static int rbv_setpalette (unsigned int regno, unsigned int red,
-			   unsigned int green, unsigned int blue,
-			   struct fb_info *fb_info);
-static int mdc_setpalette (unsigned int regno, unsigned int red,
-			   unsigned int green, unsigned int blue,
-			   struct fb_info *fb_info);
-static int toby_setpalette (unsigned int regno, unsigned int red,
-			    unsigned int green, unsigned int blue,
-			    struct fb_info *fb_info);
-static int civic_setpalette (unsigned int regno, unsigned int red,
-			     unsigned int green, unsigned int blue,
-			     struct fb_info *fb_info);
-static int csc_setpalette (unsigned int regno, unsigned int red,
-			   unsigned int green, unsigned int blue,
-			   struct fb_info *fb_info);
-
-static struct {
-	unsigned char addr;
-	/* Note: word-aligned */
-	char pad[3];
-	unsigned char lut;
-} __iomem *valkyrie_cmap_regs;
+static int (*macfb_setpalette)(unsigned int regno, unsigned int red,
+			       unsigned int green, unsigned int blue,
+			       struct fb_info *info);
 
 static struct {
 	unsigned char addr;
@@ -116,15 +89,15 @@ static struct {
 } __iomem *civic_cmap_regs;
 
 static struct {
-	char    pad1[0x40];
-        unsigned char	clut_waddr;	/* 0x40 */
-        char    pad2;
-        unsigned char	clut_data;	/* 0x42 */
-        char	pad3[0x3];
-        unsigned char	clut_raddr;	/* 0x46 */
+	char pad1[0x40];
+	unsigned char clut_waddr;	/* 0x40 */
+	char pad2;
+	unsigned char clut_data;	/* 0x42 */
+	char pad3[0x3];
+	unsigned char clut_raddr;	/* 0x46 */
 } __iomem *csc_cmap_regs;
 
-/* We will leave these the way they are for the time being */
+/* The registers in these structs are in NuBus slot space */
 struct mdc_cmap_regs {
 	char pad1[0x200200];
 	unsigned char addr;
@@ -145,13 +118,10 @@ struct jet_cmap_regs {
 	unsigned char lut;
 };
 
-#define PIXEL_TO_MM(a)	(((a)*10)/28)	/* width in mm at 72 dpi */	
-
-/* mode */
-static int  video_slot = 0;
+#define PIXEL_TO_MM(a)	(((a)*10)/28)	/* width in mm at 72 dpi */
 
 static struct fb_var_screeninfo macfb_defined = {
-	.bits_per_pixel	= 8,	
+	.bits_per_pixel	= 8,
 	.activate	= FB_ACTIVATE_NOW,
 	.width		= -1,
 	.height		= -1,
@@ -167,181 +137,152 @@ static struct fb_fix_screeninfo macfb_fi
 	.accel	= FB_ACCEL_NONE,
 };
 
+static void *slot_addr;
 static struct fb_info fb_info;
 static u32 pseudo_palette[16];
-static int inverse   = 0;
-static int vidtest   = 0;
-
-static int valkyrie_setpalette (unsigned int regno, unsigned int red,
-				unsigned int green, unsigned int blue,
-				struct fb_info *info)
-{
-	unsigned long flags;
-	
-	red >>= 8;
-	green >>= 8;
-	blue >>= 8;
-
-	local_irq_save(flags);
-	
-	/* tell clut which address to fill */
-	nubus_writeb(regno, &valkyrie_cmap_regs->addr);
-	nop();
-
-	/* send one color channel at a time */
-	nubus_writeb(red, &valkyrie_cmap_regs->lut);
-	nop();
-	nubus_writeb(green, &valkyrie_cmap_regs->lut);
-	nop();
-	nubus_writeb(blue, &valkyrie_cmap_regs->lut);
-
-	local_irq_restore(flags);
-	return 0;
-}
+static int inverse;
+static int vidtest;
 
-/* Unlike the Valkyrie, the DAFB cannot set individual colormap
-   registers.  Therefore, we do what the MacOS driver does (no
-   kidding!) and simply set them one by one until we hit the one we
-   want. */
-static int dafb_setpalette (unsigned int regno, unsigned int red,
-			    unsigned int green, unsigned int blue,
-			    struct fb_info *info)
+/*
+ * Unlike the Valkyrie, the DAFB cannot set individual colormap
+ * registers.  Therefore, we do what the MacOS driver does (no
+ * kidding!) and simply set them one by one until we hit the one we
+ * want.
+ */
+static int dafb_setpalette(unsigned int regno, unsigned int red,
+			   unsigned int green, unsigned int blue,
+			   struct fb_info *info)
 {
-	/* FIXME: really, really need to use ioremap() here,
-           phys_to_virt() doesn't work anymore */
 	static int lastreg = -1;
 	unsigned long flags;
-	
-	red >>= 8;
-	green >>= 8;
-	blue >>= 8;
 
 	local_irq_save(flags);
-	
-	/* fbdev will set an entire colourmap, but X won't.  Hopefully
-	   this should accommodate both of them */
-	if (regno != lastreg+1) {
+
+	/*
+	 * fbdev will set an entire colourmap, but X won't.  Hopefully
+	 * this should accommodate both of them
+	 */
+	if (regno != lastreg + 1) {
 		int i;
-		
+
 		/* Stab in the dark trying to reset the CLUT pointer */
 		nubus_writel(0, &dafb_cmap_regs->reset);
 		nop();
-		
+
 		/* Loop until we get to the register we want */
 		for (i = 0; i < regno; i++) {
-			nubus_writeb(info->cmap.red[i] >> 8, &dafb_cmap_regs->lut);
+			nubus_writeb(info->cmap.red[i] >> 8,
+				     &dafb_cmap_regs->lut);
 			nop();
-			nubus_writeb(info->cmap.green[i] >> 8, &dafb_cmap_regs->lut);
+			nubus_writeb(info->cmap.green[i] >> 8,
+				     &dafb_cmap_regs->lut);
 			nop();
-			nubus_writeb(info->cmap.blue[i] >> 8, &dafb_cmap_regs->lut);
+			nubus_writeb(info->cmap.blue[i] >> 8,
+				     &dafb_cmap_regs->lut);
 			nop();
 		}
 	}
-		
+
 	nubus_writeb(red, &dafb_cmap_regs->lut);
 	nop();
 	nubus_writeb(green, &dafb_cmap_regs->lut);
 	nop();
 	nubus_writeb(blue, &dafb_cmap_regs->lut);
-	
+
 	local_irq_restore(flags);
 	lastreg = regno;
 	return 0;
 }
 
 /* V8 and Brazil seem to use the same DAC.  Sonora does as well. */
-static int v8_brazil_setpalette (unsigned int regno, unsigned int red,
-				 unsigned int green, unsigned int blue,
-				 struct fb_info *info)	
+static int v8_brazil_setpalette(unsigned int regno, unsigned int red,
+				unsigned int green, unsigned int blue,
+				struct fb_info *info)
 {
 	unsigned int bpp = info->var.bits_per_pixel;
-	unsigned char _red  =red>>8;
-	unsigned char _green=green>>8;
-	unsigned char _blue =blue>>8;
-	unsigned char _regno;
 	unsigned long flags;
 
-	if (bpp > 8) return 1; /* failsafe */
+	if (bpp > 8)
+		return 1; /* failsafe */
 
 	local_irq_save(flags);
 
 	/* On these chips, the CLUT register numbers are spread out
-	   across the register space.  Thus:
-
-	   In 8bpp, all regnos are valid.
-	   
-	   In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
-	   
-	   In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff */
-  	_regno = (regno << (8 - bpp)) | (0xFF >> bpp);
-	nubus_writeb(_regno, &v8_brazil_cmap_regs->addr); nop();
+	 * across the register space.  Thus:
+	 * In 8bpp, all regnos are valid.
+	 * In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
+	 * In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff
+	 */
+	regno = (regno << (8 - bpp)) | (0xFF >> bpp);
+	nubus_writeb(regno, &v8_brazil_cmap_regs->addr);
+	nop();
 
 	/* send one color channel at a time */
-	nubus_writeb(_red, &v8_brazil_cmap_regs->lut); nop();
-	nubus_writeb(_green, &v8_brazil_cmap_regs->lut); nop();
-	nubus_writeb(_blue, &v8_brazil_cmap_regs->lut);
+	nubus_writeb(red, &v8_brazil_cmap_regs->lut);
+	nop();
+	nubus_writeb(green, &v8_brazil_cmap_regs->lut);
+	nop();
+	nubus_writeb(blue, &v8_brazil_cmap_regs->lut);
 
-	local_irq_restore(flags);	
+	local_irq_restore(flags);
 	return 0;
 }
 
-static int rbv_setpalette (unsigned int regno, unsigned int red,
-			   unsigned int green, unsigned int blue,
-			   struct fb_info *info)
+/* RAM-Based Video */
+static int rbv_setpalette(unsigned int regno, unsigned int red,
+			  unsigned int green, unsigned int blue,
+			  struct fb_info *info)
 {
-	/* use MSBs */
-	unsigned char _red  =red>>8;
-	unsigned char _green=green>>8;
-	unsigned char _blue =blue>>8;
-	unsigned char _regno;
 	unsigned long flags;
 
-	if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
+	if (info->var.bits_per_pixel > 8)
+		return 1; /* failsafe */
 
 	local_irq_save(flags);
-	
+
 	/* From the VideoToolbox driver.  Seems to be saying that
 	 * regno #254 and #255 are the important ones for 1-bit color,
 	 * regno #252-255 are the important ones for 2-bit color, etc.
 	 */
-	_regno = regno + (256-(1 << info->var.bits_per_pixel));
+	regno += 256 - (1 << info->var.bits_per_pixel);
 
 	/* reset clut? (VideoToolbox sez "not necessary") */
-	nubus_writeb(0xFF, &rbv_cmap_regs->cntl); nop();
-	
+	nubus_writeb(0xFF, &rbv_cmap_regs->cntl);
+	nop();
+
 	/* tell clut which address to use. */
-	nubus_writeb(_regno, &rbv_cmap_regs->addr); nop();
-	
+	nubus_writeb(regno, &rbv_cmap_regs->addr);
+	nop();
+
 	/* send one color channel at a time. */
-	nubus_writeb(_red,   &rbv_cmap_regs->lut); nop();
-	nubus_writeb(_green, &rbv_cmap_regs->lut); nop();
-	nubus_writeb(_blue,  &rbv_cmap_regs->lut);
-	
-	local_irq_restore(flags); /* done. */
+	nubus_writeb(red, &rbv_cmap_regs->lut);
+	nop();
+	nubus_writeb(green, &rbv_cmap_regs->lut);
+	nop();
+	nubus_writeb(blue, &rbv_cmap_regs->lut);
+
+	local_irq_restore(flags);
 	return 0;
 }
 
-/* Macintosh Display Card (8x24) */
+/* Macintosh Display Card (8*24) */
 static int mdc_setpalette(unsigned int regno, unsigned int red,
 			  unsigned int green, unsigned int blue,
 			  struct fb_info *info)
 {
-	volatile struct mdc_cmap_regs *cmap_regs =
-		nubus_slot_addr(video_slot);
-	/* use MSBs */
-	unsigned char _red  =red>>8;
-	unsigned char _green=green>>8;
-	unsigned char _blue =blue>>8;
-	unsigned char _regno=regno;
+	struct mdc_cmap_regs *cmap_regs = slot_addr;
 	unsigned long flags;
 
 	local_irq_save(flags);
-	
+
 	/* the nop's are there to order writes. */
-	nubus_writeb(_regno, &cmap_regs->addr); nop();
-	nubus_writeb(_red, &cmap_regs->lut);    nop();
-	nubus_writeb(_green, &cmap_regs->lut);  nop();
-	nubus_writeb(_blue, &cmap_regs->lut);
+	nubus_writeb(regno, &cmap_regs->addr);
+	nop();
+	nubus_writeb(red, &cmap_regs->lut);
+	nop();
+	nubus_writeb(green, &cmap_regs->lut);
+	nop();
+	nubus_writeb(blue, &cmap_regs->lut);
 
 	local_irq_restore(flags);
 	return 0;
@@ -350,24 +291,26 @@ static int mdc_setpalette(unsigned int r
 /* Toby frame buffer */
 static int toby_setpalette(unsigned int regno, unsigned int red,
 			   unsigned int green, unsigned int blue,
-			   struct fb_info *info) 
+			   struct fb_info *info)
 {
-	volatile struct toby_cmap_regs *cmap_regs =
-		nubus_slot_addr(video_slot);
+	struct toby_cmap_regs *cmap_regs = slot_addr;
 	unsigned int bpp = info->var.bits_per_pixel;
-	/* use MSBs */
-	unsigned char _red  =~(red>>8);
-	unsigned char _green=~(green>>8);
-	unsigned char _blue =~(blue>>8);
-	unsigned char _regno = (regno << (8 - bpp)) | (0xFF >> bpp);
 	unsigned long flags;
 
+	red = ~red;
+	green = ~green;
+	blue = ~blue;
+	regno = (regno << (8 - bpp)) | (0xFF >> bpp);
+
 	local_irq_save(flags);
-		
-	nubus_writeb(_regno, &cmap_regs->addr); nop();
-	nubus_writeb(_red, &cmap_regs->lut);    nop();
-	nubus_writeb(_green, &cmap_regs->lut);  nop();
-	nubus_writeb(_blue, &cmap_regs->lut);
+
+	nubus_writeb(regno, &cmap_regs->addr);
+	nop();
+	nubus_writeb(red, &cmap_regs->lut);
+	nop();
+	nubus_writeb(green, &cmap_regs->lut);
+	nop();
+	nubus_writeb(blue, &cmap_regs->lut);
 
 	local_irq_restore(flags);
 	return 0;
@@ -378,20 +321,18 @@ static int jet_setpalette(unsigned int r
 			  unsigned int green, unsigned int blue,
 			  struct fb_info *info)
 {
-	volatile struct jet_cmap_regs *cmap_regs =
-		nubus_slot_addr(video_slot);
-	/* use MSBs */
-	unsigned char _red   = (red>>8);
-	unsigned char _green = (green>>8);
-	unsigned char _blue  = (blue>>8);
+	struct jet_cmap_regs *cmap_regs = slot_addr;
 	unsigned long flags;
 
 	local_irq_save(flags);
-	
-	nubus_writeb(regno, &cmap_regs->addr); nop();
-	nubus_writeb(_red, &cmap_regs->lut); nop();
-	nubus_writeb(_green, &cmap_regs->lut); nop();
-	nubus_writeb(_blue, &cmap_regs->lut);
+
+	nubus_writeb(regno, &cmap_regs->addr);
+	nop();
+	nubus_writeb(red, &cmap_regs->lut);
+	nop();
+	nubus_writeb(green, &cmap_regs->lut);
+	nop();
+	nubus_writeb(blue, &cmap_regs->lut);
 
 	local_irq_restore(flags);
 	return 0;
@@ -400,53 +341,27 @@ static int jet_setpalette(unsigned int r
 /*
  * Civic framebuffer -- Quadra AV built-in video.  A chip
  * called Sebastian holds the actual color palettes, and
- * apparently, there are two different banks of 512K RAM 
+ * apparently, there are two different banks of 512K RAM
  * which can act as separate framebuffers for doing video
  * input and viewing the screen at the same time!  The 840AV
- * Can add another 1MB RAM to give the two framebuffers 
+ * Can add another 1MB RAM to give the two framebuffers
  * 1MB RAM apiece.
- *
- * FIXME: this doesn't seem to work anymore.
  */
-static int civic_setpalette (unsigned int regno, unsigned int red,
-			     unsigned int green, unsigned int blue,
-			     struct fb_info *info)
+static int civic_setpalette(unsigned int regno, unsigned int red,
+			    unsigned int green, unsigned int blue,
+			    struct fb_info *info)
 {
-	static int lastreg = -1;
 	unsigned long flags;
 	int clut_status;
 	
-	if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
-
-	red   >>= 8;
-	green >>= 8;
-	blue  >>= 8;
+	if (info->var.bits_per_pixel > 8)
+		return 1; /* failsafe */
 
 	local_irq_save(flags);
-	
-	/*
-	 * Set the register address
-	 */
-	nubus_writeb(regno, &civic_cmap_regs->addr); nop();
 
-	/*
-	 * Wait for VBL interrupt here;
-	 * They're usually not enabled from Penguin, so we won't check
-	 */
-#if 0
-	{
-#define CIVIC_VBL_OFFSET	0x120
-		volatile unsigned long *vbl = nubus_readl(civic_cmap_regs->vbl_addr + CIVIC_VBL_OFFSET);
-		/* do interrupt setup stuff here? */
-		*vbl = 0L; nop();	/* clear */
-		*vbl = 1L; nop();	/* set */
-		while (*vbl != 0L)	/* wait for next vbl */
-		{
-			usleep(10);	/* needed? */
-		}
-		/* do interrupt shutdown stuff here? */
-	}
-#endif
+	/* Set the register address */
+	nubus_writeb(regno, &civic_cmap_regs->addr);
+	nop();
 
 	/*
 	 * Grab a status word and do some checking;
@@ -459,39 +374,52 @@ static int civic_setpalette (unsigned in
 #if 0
 		if ((clut_status & 0x000D) != 0)
 		{
-			nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
-			nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
+			nubus_writeb(0x00, &civic_cmap_regs->lut);
+			nop();
+			nubus_writeb(0x00, &civic_cmap_regs->lut);
+			nop();
 		}
 #endif
 
-		nubus_writeb(  red, &civic_cmap_regs->lut); nop();
-		nubus_writeb(green, &civic_cmap_regs->lut); nop();
-		nubus_writeb( blue, &civic_cmap_regs->lut); nop();
-		nubus_writeb( 0x00, &civic_cmap_regs->lut); nop();
+		nubus_writeb(red, &civic_cmap_regs->lut);
+		nop();
+		nubus_writeb(green, &civic_cmap_regs->lut);
+		nop();
+		nubus_writeb(blue, &civic_cmap_regs->lut);
+		nop();
+		nubus_writeb(0x00, &civic_cmap_regs->lut);
 	}
 	else
 	{
 		unsigned char junk;
 
-		junk = nubus_readb(&civic_cmap_regs->lut); nop();
-		junk = nubus_readb(&civic_cmap_regs->lut); nop();
-		junk = nubus_readb(&civic_cmap_regs->lut); nop();
-		junk = nubus_readb(&civic_cmap_regs->lut); nop();
+		junk = nubus_readb(&civic_cmap_regs->lut);
+		nop();
+		junk = nubus_readb(&civic_cmap_regs->lut);
+		nop();
+		junk = nubus_readb(&civic_cmap_regs->lut);
+		nop();
+		junk = nubus_readb(&civic_cmap_regs->lut);
+		nop();
 
 		if ((clut_status & 0x000D) != 0)
 		{
-			nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
-			nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
+			nubus_writeb(0x00, &civic_cmap_regs->lut);
+			nop();
+			nubus_writeb(0x00, &civic_cmap_regs->lut);
+			nop();
 		}
 
-		nubus_writeb(  red, &civic_cmap_regs->lut); nop();
-		nubus_writeb(green, &civic_cmap_regs->lut); nop();
-		nubus_writeb( blue, &civic_cmap_regs->lut); nop();
-		nubus_writeb( junk, &civic_cmap_regs->lut); nop();
+		nubus_writeb(red, &civic_cmap_regs->lut);
+		nop();
+		nubus_writeb(green, &civic_cmap_regs->lut);
+		nop();
+		nubus_writeb(blue, &civic_cmap_regs->lut);
+		nop();
+		nubus_writeb(junk, &civic_cmap_regs->lut);
 	}
 
 	local_irq_restore(flags);
-	lastreg = regno;
 	return 0;
 }
 
@@ -500,16 +428,21 @@ static int civic_setpalette (unsigned in
  * (and the 5300 too, but that's a PowerMac). This function
  * brought to you in part by the ECSC driver for MkLinux.
  */
-
-static int csc_setpalette (unsigned int regno, unsigned int red,
-			   unsigned int green, unsigned int blue,
-			   struct fb_info *info)
+static int csc_setpalette(unsigned int regno, unsigned int red,
+			  unsigned int green, unsigned int blue,
+			  struct fb_info *info)
 {
-	mdelay(1);
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	udelay(1); /* mklinux on PB 5300 waits for 260 ns */
 	nubus_writeb(regno, &csc_cmap_regs->clut_waddr);
-	nubus_writeb(red,   &csc_cmap_regs->clut_data);
+	nubus_writeb(red, &csc_cmap_regs->clut_data);
 	nubus_writeb(green, &csc_cmap_regs->clut_data);
-	nubus_writeb(blue,  &csc_cmap_regs->clut_data);
+	nubus_writeb(blue, &csc_cmap_regs->clut_data);
+
+	local_irq_restore(flags);
 	return 0;
 }
 
@@ -518,10 +451,10 @@ static int macfb_setcolreg(unsigned regn
 			   struct fb_info *fb_info)
 {
 	/*
-	 *  Set a single color register. The values supplied are
-	 *  already rounded down to the hardware's capabilities
-	 *  (according to the entries in the `var' structure). Return
-	 *  != 0 for invalid regno.
+	 * Set a single color register. The values supplied are
+	 * already rounded down to the hardware's capabilities
+	 * (according to the entries in the `var' structure).
+	 * Return non-zero for invalid regno.
 	 */
 	
 	if (regno >= fb_info->cmap.len)
@@ -536,8 +469,8 @@ static int macfb_setcolreg(unsigned regn
 		case 4:
 		case 8:
 			if (macfb_setpalette)
-				macfb_setpalette(regno, red, green, blue,
-						 fb_info);
+				macfb_setpalette(regno, red >> 8, green >> 8,
+						 blue >> 8, fb_info);
 			else
 				return 1;
 			break;
@@ -555,28 +488,22 @@ static int macfb_setcolreg(unsigned regn
 			} else {
 				/* 0:5:6:5 */
 				((u32*) (fb_info->pseudo_palette))[regno] =
-					((red   & 0xf800)      ) |
+					((red   & 0xf800) >>  0) |
 					((green & 0xfc00) >>  5) |
 					((blue  & 0xf800) >> 11);
 			}
 			break;
-			/* I'm pretty sure that one or the other of these
-			   doesn't exist on 68k Macs */
+		/*
+		 * 24-bit colour almost doesn't exist on 68k Macs --
+		 * http://support.apple.com/kb/TA28634 (Old Article: 10992)
+		 */
 		case 24:
-			red   >>= 8;
-			green >>= 8;
-			blue  >>= 8;
-			((u32 *)(fb_info->pseudo_palette))[regno] =
-				(red   << fb_info->var.red.offset)   |
-				(green << fb_info->var.green.offset) |
-				(blue  << fb_info->var.blue.offset);
-			break;
 		case 32:
 			red   >>= 8;
 			green >>= 8;
 			blue  >>= 8;
 			((u32 *)(fb_info->pseudo_palette))[regno] =
-				(red   << fb_info->var.red.offset)   |
+				(red   << fb_info->var.red.offset) |
 				(green << fb_info->var.green.offset) |
 				(blue  << fb_info->var.blue.offset);
 			break;
@@ -597,25 +524,24 @@ static struct fb_ops macfb_ops = {
 static void __init macfb_setup(char *options)
 {
 	char *this_opt;
-	
+
 	if (!options || !*options)
 		return;
-	
+
 	while ((this_opt = strsep(&options, ",")) != NULL) {
-		if (!*this_opt) continue;
-		
-		if (! strcmp(this_opt, "inverse"))
-			inverse=1;
-		/* This means "turn on experimental CLUT code" */
-		else if (!strcmp(this_opt, "vidtest"))
-			vidtest=1;
+		if (!*this_opt)
+			continue;
+
+		if (!strcmp(this_opt, "inverse"))
+			inverse = 1;
+		else
+			if (!strcmp(this_opt, "vidtest"))
+				vidtest = 1; /* enable experimental CLUT code */
 	}
 }
 
 static void __init iounmap_macfb(void)
 {
-	if (valkyrie_cmap_regs)
-		iounmap(valkyrie_cmap_regs);
 	if (dafb_cmap_regs)
 		iounmap(dafb_cmap_regs);
 	if (v8_brazil_cmap_regs)
@@ -642,48 +568,55 @@ static int __init macfb_init(void)
 	if (!MACH_IS_MAC) 
 		return -ENODEV;
 
-	/* There can only be one internal video controller anyway so
-	   we're not too worried about this */
+	if (mac_bi_data.id == MAC_MODEL_Q630 ||
+	    mac_bi_data.id == MAC_MODEL_P588)
+		return -ENODEV; /* See valkyriefb.c */
+
 	macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF;
 	macfb_defined.yres = mac_bi_data.dimensions >> 16;
 	macfb_defined.bits_per_pixel = mac_bi_data.videodepth;
+
 	macfb_fix.line_length = mac_bi_data.videorow;
-	macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres;
+	macfb_fix.smem_len    = macfb_fix.line_length * macfb_defined.yres;
 	/* Note: physical address (since 2.1.127) */
-	macfb_fix.smem_start = mac_bi_data.videoaddr;
-	/* This is actually redundant with the initial mappings.
-	   However, there are some non-obvious aspects to the way
-	   those mappings are set up, so this is in fact the safest
-	   way to ensure that this driver will work on every possible
-	   Mac */
-	fb_info.screen_base = ioremap(mac_bi_data.videoaddr, macfb_fix.smem_len);
-	
-	printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
-	       macfb_fix.smem_start, fb_info.screen_base, macfb_fix.smem_len/1024);
-	printk("macfb: mode is %dx%dx%d, linelength=%d\n",
-	       macfb_defined.xres, macfb_defined.yres, macfb_defined.bits_per_pixel, macfb_fix.line_length);
-	
+	macfb_fix.smem_start  = mac_bi_data.videoaddr;
+
 	/*
-	 *	Fill in the available video resolution
+	 * This is actually redundant with the initial mappings.
+	 * However, there are some non-obvious aspects to the way
+	 * those mappings are set up, so this is in fact the safest
+	 * way to ensure that this driver will work on every possible Mac
 	 */
-	 
-	macfb_defined.xres_virtual   = macfb_defined.xres;
-	macfb_defined.yres_virtual   = macfb_defined.yres;
-	macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres);
-	macfb_defined.width  = PIXEL_TO_MM(macfb_defined.xres);	 
+	fb_info.screen_base = ioremap(mac_bi_data.videoaddr,
+				      macfb_fix.smem_len);
+	if (!fb_info.screen_base)
+		return -ENODEV;
 
-	printk("macfb: scrolling: redraw\n");
+	printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
+	       macfb_fix.smem_start, fb_info.screen_base,
+	       macfb_fix.smem_len / 1024);
+	printk("macfb: mode is %dx%dx%d, linelength=%d\n",
+	       macfb_defined.xres, macfb_defined.yres,
+	       macfb_defined.bits_per_pixel, macfb_fix.line_length);
+
+	/* Fill in the available video resolution */
+	macfb_defined.xres_virtual = macfb_defined.xres;
 	macfb_defined.yres_virtual = macfb_defined.yres;
+	macfb_defined.height       = PIXEL_TO_MM(macfb_defined.yres);
+	macfb_defined.width        = PIXEL_TO_MM(macfb_defined.xres);
 
-	/* some dummy values for timing to make fbset happy */
-	macfb_defined.pixclock     = 10000000 / macfb_defined.xres * 1000 / macfb_defined.yres;
+	/* Some dummy values for timing to make fbset happy */
+	macfb_defined.pixclock     = 10000000 / macfb_defined.xres *
+				     1000 / macfb_defined.yres;
 	macfb_defined.left_margin  = (macfb_defined.xres / 8) & 0xf8;
 	macfb_defined.hsync_len    = (macfb_defined.xres / 8) & 0xf8;
 
 	switch (macfb_defined.bits_per_pixel) {
 	case 1:
-		/* XXX: I think this will catch any program that tries
-		   to do FBIO_PUTCMAP when the visual is monochrome */
+		/*
+		 * XXX: I think this will catch any program that tries
+		 * to do FBIO_PUTCMAP when the visual is monochrome.
+		 */
 		macfb_defined.red.length = macfb_defined.bits_per_pixel;
 		macfb_defined.green.length = macfb_defined.bits_per_pixel;
 		macfb_defined.blue.length = macfb_defined.bits_per_pixel;
@@ -708,53 +641,52 @@ static int __init macfb_init(void)
 		macfb_defined.green.length = 5;
 		macfb_defined.blue.offset = 0;
 		macfb_defined.blue.length = 5;
-		printk("macfb: directcolor: "
-		       "size=1:5:5:5, shift=15:10:5:0\n");
 		video_cmap_len = 16;
-		/* Should actually be FB_VISUAL_DIRECTCOLOR, but this
-		   works too */
+		/*
+		 * Should actually be FB_VISUAL_DIRECTCOLOR, but this
+		 * works too
+		 */
 		macfb_fix.visual = FB_VISUAL_TRUECOLOR;
 		break;
 	case 24:
 	case 32:
-		/* XXX: have to test these... can any 68k Macs
-		   actually do this on internal video? */
 		macfb_defined.red.offset = 16;
 		macfb_defined.red.length = 8;
 		macfb_defined.green.offset = 8;
 		macfb_defined.green.length = 8;
 		macfb_defined.blue.offset = 0;
 		macfb_defined.blue.length = 8;
-		printk("macfb: truecolor: "
-		       "size=0:8:8:8, shift=0:16:8:0\n");
 		video_cmap_len = 16;
 		macfb_fix.visual = FB_VISUAL_TRUECOLOR;
+		break;
 	default:
 		video_cmap_len = 0;
 		macfb_fix.visual = FB_VISUAL_MONO01;
-		printk("macfb: unknown or unsupported bit depth: %d\n", macfb_defined.bits_per_pixel);
+		printk("macfb: unknown or unsupported bit depth: %d\n",
+		       macfb_defined.bits_per_pixel);
 		break;
 	}
 	
-	/* Hardware dependent stuff */
-	/*  We take a wild guess that if the video physical address is
-	 *  in nubus slot space, that the nubus card is driving video.
-	 *  Penguin really ought to tell us whether we are using internal
-	 *  video or not.
+	/*
+	 * We take a wild guess that if the video physical address is
+	 * in nubus slot space, that the nubus card is driving video.
+	 * Penguin really ought to tell us whether we are using internal
+	 * video or not.
+	 * Hopefully we only find one of them.  Otherwise our NuBus
+	 * code is really broken :-)
 	 */
-	/* Hopefully we only find one of them.  Otherwise our NuBus
-           code is really broken :-) */
 
-	while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY, NUBUS_TYPE_VIDEO, ndev))
-		!= NULL)
+	while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY,
+				       NUBUS_TYPE_VIDEO, ndev)))
 	{
-		if (!(mac_bi_data.videoaddr >= ndev->board->slot_addr
-		      && (mac_bi_data.videoaddr <
-			  (unsigned long)nubus_slot_addr(ndev->board->slot+1))))
+		unsigned long base = ndev->board->slot_addr;
+
+		if (mac_bi_data.videoaddr < base ||
+		    mac_bi_data.videoaddr - base > 0xFFFFFF)
 			continue;
+
 		video_is_nubus = 1;
-		/* We should probably just use the slot address... */
-		video_slot = ndev->board->slot;
+		slot_addr = (unsigned char *)base;
 
 		switch(ndev->dr_hw) {
 		case NUBUS_DRHW_APPLE_MDC:
@@ -771,7 +703,7 @@ static int __init macfb_init(void)
 			strcpy(macfb_fix.id, "Jet");
 			macfb_setpalette = jet_setpalette;
 			macfb_defined.activate = FB_ACTIVATE_NOW;
-			break;			
+			break;
 		default:
 			strcpy(macfb_fix.id, "Generic NuBus");
 			break;
@@ -779,30 +711,19 @@ static int __init macfb_init(void)
 	}
 
 	/* If it's not a NuBus card, it must be internal video */
-	/* FIXME: this function is getting way too big.  (this driver
-           is too...) */
 	if (!video_is_nubus)
-		switch( mac_bi_data.id )
-		{
-			/* Valkyrie Quadras */
-		case MAC_MODEL_Q630:
-			/* I'm not sure about this one */
-		case MAC_MODEL_P588:
-			strcpy(macfb_fix.id, "Valkyrie");
-			macfb_setpalette = valkyrie_setpalette;
-			macfb_defined.activate = FB_ACTIVATE_NOW;
-			valkyrie_cmap_regs = ioremap(DAC_BASE, 0x1000);
-			break;
-
-			/* DAFB Quadras */
-			/* Note: these first four have the v7 DAFB, which is
-			   known to be rather unlike the ones used in the
-			   other models */
+		switch (mac_bi_data.id) {
+		/*
+		 * DAFB Quadras
+		 * Note: these first four have the v7 DAFB, which is
+		 * known to be rather unlike the ones used in the
+		 * other models
+		 */
 		case MAC_MODEL_P475:
 		case MAC_MODEL_P475F:
 		case MAC_MODEL_P575:
 		case MAC_MODEL_Q605:
-	
+
 		case MAC_MODEL_Q800:
 		case MAC_MODEL_Q650:
 		case MAC_MODEL_Q610:
@@ -817,17 +738,21 @@ static int __init macfb_init(void)
 			dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
 			break;
 
-			/* LC II uses the V8 framebuffer */
+		/*
+		 * LC II uses the V8 framebuffer
+		 */
 		case MAC_MODEL_LCII:
 			strcpy(macfb_fix.id, "V8");
 			macfb_setpalette = v8_brazil_setpalette;
 			macfb_defined.activate = FB_ACTIVATE_NOW;
 			v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
 			break;
-		
-			/* IIvi, IIvx use the "Brazil" framebuffer (which is
-			   very much like the V8, it seems, and probably uses
-			   the same DAC) */
+
+		/*
+		 * IIvi, IIvx use the "Brazil" framebuffer (which is
+		 * very much like the V8, it seems, and probably uses
+		 * the same DAC)
+		 */
 		case MAC_MODEL_IIVI:
 		case MAC_MODEL_IIVX:
 		case MAC_MODEL_P600:
@@ -836,12 +761,14 @@ static int __init macfb_init(void)
 			macfb_defined.activate = FB_ACTIVATE_NOW;
 			v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
 			break;
-		
-			/* LC III (and friends) use the Sonora framebuffer */
-			/* Incidentally this is also used in the non-AV models
-			   of the x100 PowerMacs */
-			/* These do in fact seem to use the same DAC interface
-			   as the LC II. */
+
+		/*
+		 * LC III (and friends) use the Sonora framebuffer
+		 * Incidentally this is also used in the non-AV models
+		 * of the x100 PowerMacs
+		 * These do in fact seem to use the same DAC interface
+		 * as the LC II.
+		 */
 		case MAC_MODEL_LCIII:
 		case MAC_MODEL_P520:
 		case MAC_MODEL_P550:
@@ -852,9 +779,11 @@ static int __init macfb_init(void)
 			v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
 			break;
 
-			/* IIci and IIsi use the infamous RBV chip
-                           (the IIsi is just a rebadged and crippled
-                           IIci in a different case, BTW) */
+		/*
+		 * IIci and IIsi use the infamous RBV chip
+		 * (the IIsi is just a rebadged and crippled
+		 * IIci in a different case, BTW)
+		 */
 		case MAC_MODEL_IICI:
 		case MAC_MODEL_IISI:
 			macfb_setpalette = rbv_setpalette;
@@ -863,7 +792,9 @@ static int __init macfb_init(void)
 			rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
 			break;
 
-			/* AVs use the Civic framebuffer */
+		/*
+		 * AVs use the Civic framebuffer
+		 */
 		case MAC_MODEL_Q840:
 		case MAC_MODEL_C660:
 			macfb_setpalette = civic_setpalette;
@@ -873,15 +804,10 @@ static int __init macfb_init(void)
 			break;
 
 		
-			/* Write a setpalette function for your machine, then
-			   you can add something similar here.  These are
-			   grouped by classes of video chipsets.  Some of this
-			   information is from the VideoToolbox "Bugs" web
-			   page at
-			   http://rajsky.psych.nyu.edu/Tips/VideoBugs.html */
-
-			/* Assorted weirdos */
-			/* We think this may be like the LC II */
+		/*
+		 * Assorted weirdos
+		 * We think this may be like the LC II
+		 */
 		case MAC_MODEL_LC:
 			if (vidtest) {
 				macfb_setpalette = v8_brazil_setpalette;
@@ -891,7 +817,10 @@ static int __init macfb_init(void)
 			}
 			strcpy(macfb_fix.id, "LC");
 			break;
-			/* We think this may be like the LC II */
+
+		/*
+		 * We think this may be like the LC II
+		 */
 		case MAC_MODEL_CCL:
 			if (vidtest) {
 				macfb_setpalette = v8_brazil_setpalette;
@@ -902,31 +831,42 @@ static int __init macfb_init(void)
 			strcpy(macfb_fix.id, "Color Classic");
 			break;
 
-			/* And we *do* mean "weirdos" */
+		/*
+		 * And we *do* mean "weirdos"
+		 */
 		case MAC_MODEL_TV:
 			strcpy(macfb_fix.id, "Mac TV");
 			break;
 
-			/* These don't have colour, so no need to worry */
+		/*
+		 * These don't have colour, so no need to worry
+		 */
 		case MAC_MODEL_SE30:
 		case MAC_MODEL_CLII:
 			strcpy(macfb_fix.id, "Monochrome");
 			break;
 
-			/* Powerbooks are particularly difficult.  Many of
-			   them have separate framebuffers for external and
-			   internal video, which is admittedly pretty cool,
-			   but will be a bit of a headache to support here.
-			   Also, many of them are grayscale, and we don't
-			   really support that. */
+		/*
+		 * Powerbooks are particularly difficult.  Many of
+		 * them have separate framebuffers for external and
+		 * internal video, which is admittedly pretty cool,
+		 * but will be a bit of a headache to support here.
+		 * Also, many of them are grayscale, and we don't
+		 * really support that.
+		 */
 
+		/*
+		 * Slot 0 ROM says TIM. No external video. B&W.
+		 */
 		case MAC_MODEL_PB140:
 		case MAC_MODEL_PB145:
 		case MAC_MODEL_PB170:
 			strcpy(macfb_fix.id, "DDC");
 			break;
 
-			/* Internal is GSC, External (if present) is ViSC */
+		/*
+		 * Internal is GSC, External (if present) is ViSC
+		 */
 		case MAC_MODEL_PB150:	/* no external video */
 		case MAC_MODEL_PB160:
 		case MAC_MODEL_PB165:
@@ -936,13 +876,17 @@ static int __init macfb_init(void)
 			strcpy(macfb_fix.id, "GSC");
 			break;
 
-			/* Internal is TIM, External is ViSC */
+		/*
+		 * Internal is TIM, External is ViSC
+		 */
 		case MAC_MODEL_PB165C:
 		case MAC_MODEL_PB180C:
 			strcpy(macfb_fix.id, "TIM");
 			break;
 
-			/* Internal is CSC, External is Keystone+Ariel. */
+		/*
+		 * Internal is CSC, External is Keystone+Ariel.
+		 */
 		case MAC_MODEL_PB190:	/* external video is optional */
 		case MAC_MODEL_PB520:
 		case MAC_MODEL_PB250:
@@ -954,7 +898,7 @@ static int __init macfb_init(void)
 			strcpy(macfb_fix.id, "CSC");
 			csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
 			break;
-		
+
 		default:
 			strcpy(macfb_fix.id, "Unknown");
 			break;
@@ -969,7 +913,7 @@ static int __init macfb_init(void)
 	err = fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
 	if (err)
 		goto fail_unmap;
-	
+
 	err = register_framebuffer(&fb_info);
 	if (err)
 		goto fail_dealloc;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/macmodes.c linux-libre-2.6.34-gnu1/drivers/video/macmodes.c
--- linux-libre-2.6.33-gnu1/drivers/video/macmodes.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/macmodes.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,10 @@
 
 static const struct fb_videomode mac_modedb[] = {
     {
+	/* 512x384, 60Hz, Non-Interlaced (15.67 MHz dot clock) */
+	"mac2", 60, 512, 384, 63828, 80, 16, 19, 1, 32, 3,
+	0, FB_VMODE_NONINTERLACED
+    }, {
 	/* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
 	"mac5", 60, 640, 480, 39722, 32, 32, 33, 10, 96, 2,
 	0, FB_VMODE_NONINTERLACED
@@ -41,6 +45,10 @@ static const struct fb_videomode mac_mod
 	"mac6", 67, 640, 480, 33334, 80, 80, 39, 3, 64, 3,
 	0, FB_VMODE_NONINTERLACED
     }, {
+	/* 640x870, 75Hz (portrait), Non-Interlaced (57.28 MHz dot clock) */
+	"mac7", 75, 640, 870, 17457, 80, 32, 42, 3, 80, 3,
+	0, FB_VMODE_NONINTERLACED
+    }, {
 	/* 800x600, 56 Hz, Non-Interlaced (36.00 MHz dotclock) */
 	"mac9", 56, 800, 600, 27778, 112, 40, 22, 1, 72, 2,
 	FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
@@ -105,10 +113,6 @@ static const struct fb_videomode mac_mod
 	"mac1", 60, 512, 384, pixclock, left, right, upper, lower, hslen, vslen,
 	sync, FB_VMODE_INTERLACED
     }, {
-	/* VMODE_512_384_60: 512x384, 60Hz, Non-Interlaced */
-    	"mac2", 60, 512, 384, pixclock, left, right, upper, lower, hslen, vslen,
-	sync, FB_VMODE_NONINTERLACED
-    }, {
 	/* VMODE_640_480_50I: 640x480, 50Hz, Interlaced (PAL) */
 	"mac3", 50, 640, 480, pixclock, left, right, upper, lower, hslen, vslen,
 	sync, FB_VMODE_INTERLACED
@@ -117,10 +121,6 @@ static const struct fb_videomode mac_mod
 	"mac4", 60, 640, 480, pixclock, left, right, upper, lower, hslen, vslen,
 	sync, FB_VMODE_INTERLACED
     }, {
-	/* VMODE_640_870_75P: 640x870, 75Hz (portrait), Non-Interlaced */
-	"mac7", 75, 640, 870, pixclock, left, right, upper, lower, hslen, vslen,
-	sync, FB_VMODE_NONINTERLACED
-    }, {
 	/* VMODE_768_576_50I: 768x576, 50Hz (PAL full frame), Interlaced */
 	"mac8", 50, 768, 576, pixclock, left, right, upper, lower, hslen, vslen,
 	sync, FB_VMODE_INTERLACED
@@ -134,38 +134,42 @@ static const struct fb_videomode mac_mod
      *
      *  These MUST be ordered in
      *    - increasing resolution
-     *    - decreasing refresh rate
+     *    - decreasing pixel clock period
      */
 
 static const struct mode_map {
     int vmode;
     const struct fb_videomode *mode;
 } mac_modes[] = {
+    /* 512x384 */
+    { VMODE_512_384_60, &mac_modedb[0] },
     /* 640x480 */
-    { VMODE_640_480_67, &mac_modedb[1] },
-    { VMODE_640_480_60, &mac_modedb[0] },
+    { VMODE_640_480_60, &mac_modedb[1] },
+    { VMODE_640_480_67, &mac_modedb[2] },
+    /* 640x870 */
+    { VMODE_640_870_75P, &mac_modedb[3] },
     /* 800x600 */
-    { VMODE_800_600_75, &mac_modedb[5] },
-    { VMODE_800_600_72, &mac_modedb[4] },
-    { VMODE_800_600_60, &mac_modedb[3] },
-    { VMODE_800_600_56, &mac_modedb[2] },
+    { VMODE_800_600_56, &mac_modedb[4] },
+    { VMODE_800_600_60, &mac_modedb[5] },
+    { VMODE_800_600_75, &mac_modedb[7] },
+    { VMODE_800_600_72, &mac_modedb[6] },
     /* 832x624 */
-    { VMODE_832_624_75, &mac_modedb[6] },
+    { VMODE_832_624_75, &mac_modedb[8] },
     /* 1024x768 */
-    { VMODE_1024_768_75, &mac_modedb[10] },
-    { VMODE_1024_768_75V, &mac_modedb[9] },
-    { VMODE_1024_768_70, &mac_modedb[8] },
-    { VMODE_1024_768_60, &mac_modedb[7] },
+    { VMODE_1024_768_60, &mac_modedb[9] },
+    { VMODE_1024_768_70, &mac_modedb[10] },
+    { VMODE_1024_768_75V, &mac_modedb[11] },
+    { VMODE_1024_768_75, &mac_modedb[12] },
     /* 1152x768 */
-    { VMODE_1152_768_60, &mac_modedb[14] },
+    { VMODE_1152_768_60, &mac_modedb[16] },
     /* 1152x870 */
-    { VMODE_1152_870_75, &mac_modedb[11] },
+    { VMODE_1152_870_75, &mac_modedb[13] },
     /* 1280x960 */
-    { VMODE_1280_960_75, &mac_modedb[12] },
+    { VMODE_1280_960_75, &mac_modedb[14] },
     /* 1280x1024 */
-    { VMODE_1280_1024_75, &mac_modedb[13] },
+    { VMODE_1280_1024_75, &mac_modedb[15] },
     /* 1600x1024 */
-    { VMODE_1600_1024_60, &mac_modedb[15] },
+    { VMODE_1600_1024_60, &mac_modedb[17] },
     { -1, NULL }
 };
 
@@ -299,7 +303,6 @@ EXPORT_SYMBOL(mac_vmode_to_var);
 int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
 		     int *cmode)
 {
-    const struct fb_videomode *mode = NULL;
     const struct mode_map *map;
 
     if (var->bits_per_pixel <= 8)
@@ -311,8 +314,13 @@ int mac_var_to_vmode(const struct fb_var
     else
 	return -EINVAL;
 
+    /*
+     * Find the mac_mode with a matching resolution or failing that, the
+     * closest larger resolution. Skip modes with a shorter pixel clock period.
+     */
     for (map = mac_modes; map->vmode != -1; map++) {
-	mode = map->mode;
+	const struct fb_videomode *mode = map->mode;
+
 	if (var->xres > mode->xres || var->yres > mode->yres)
 	    continue;
 	if (var->xres_virtual > mode->xres || var->yres_virtual > mode->yres)
@@ -322,6 +330,24 @@ int mac_var_to_vmode(const struct fb_var
 	if ((var->vmode & FB_VMODE_MASK) != mode->vmode)
 	    continue;
 	*vmode = map->vmode;
+
+	/*
+	 * Having found a good resolution, find the matching pixel clock
+	 * or failing that, the closest longer pixel clock period.
+	 */
+	map++;
+	while (map->vmode != -1) {
+	    const struct fb_videomode *clk_mode = map->mode;
+
+	    if (mode->xres != clk_mode->xres || mode->yres != clk_mode->yres)
+		break;
+	    if (var->pixclock > mode->pixclock)
+	        break;
+	    if (mode->vmode != clk_mode->vmode)
+		continue;
+	    *vmode = map->vmode;
+	    map++;
+	}
 	return 0;
     }
     return -EINVAL;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/Makefile linux-libre-2.6.34-gnu1/drivers/video/Makefile
--- linux-libre-2.6.33-gnu1/drivers/video/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -79,6 +79,7 @@ obj-$(CONFIG_FB_N411)             += n41
 obj-$(CONFIG_FB_HGA)              += hgafb.o
 obj-$(CONFIG_FB_XVR500)           += sunxvr500.o
 obj-$(CONFIG_FB_XVR2500)          += sunxvr2500.o
+obj-$(CONFIG_FB_XVR1000)          += sunxvr1000.o
 obj-$(CONFIG_FB_IGA)              += igafb.o
 obj-$(CONFIG_FB_APOLLO)           += dnfb.o
 obj-$(CONFIG_FB_Q40)              += q40fb.o
@@ -129,6 +130,7 @@ obj-$(CONFIG_XEN_FBDEV_FRONTEND)  += xen
 obj-$(CONFIG_FB_CARMINE)          += carminefb.o
 obj-$(CONFIG_FB_MB862XX)	  += mb862xx/
 obj-$(CONFIG_FB_MSM)              += msm/
+obj-$(CONFIG_FB_NUC900)           += nuc900fb.o
 
 # Platform or fallback drivers go here
 obj-$(CONFIG_FB_UVESA)            += uvesafb.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/matrox/i2c-matroxfb.c linux-libre-2.6.34-gnu1/drivers/video/matrox/i2c-matroxfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/matrox/i2c-matroxfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/matrox/i2c-matroxfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include "matroxfb_base.h"
 #include "matroxfb_maven.h"
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/i2c-algo-bit.h>
 
 /* MGA-TVO I2C for G200, G400 */
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/matrox/matroxfb_base.c linux-libre-2.6.34-gnu1/drivers/video/matrox/matroxfb_base.c
--- linux-libre-2.6.33-gnu1/drivers/video/matrox/matroxfb_base.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/matrox/matroxfb_base.c	2010-05-16 17:17:36.000000000 -0400
@@ -113,6 +113,7 @@
 #include "matroxfb_g450.h"
 #include <linux/matroxfb.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 
 #ifdef CONFIG_PPC_PMAC
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/matrox/matroxfb_crtc2.c linux-libre-2.6.34-gnu1/drivers/video/matrox/matroxfb_crtc2.c
--- linux-libre-2.6.33-gnu1/drivers/video/matrox/matroxfb_crtc2.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/matrox/matroxfb_crtc2.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include "matroxfb_misc.h"
 #include "matroxfb_DAC1064.h"
 #include <linux/matroxfb.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 
 /* **************************************************** */
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/matrox/matroxfb_maven.c linux-libre-2.6.34-gnu1/drivers/video/matrox/matroxfb_maven.c
--- linux-libre-2.6.33-gnu1/drivers/video/matrox/matroxfb_maven.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/matrox/matroxfb_maven.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include "matroxfb_DAC1064.h"
 #include <linux/i2c.h>
 #include <linux/matroxfb.h>
+#include <linux/slab.h>
 #include <asm/div64.h>
 
 #define MGATVO_B	1
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/maxinefb.c linux-libre-2.6.34-gnu1/drivers/video/maxinefb.c
--- linux-libre-2.6.33-gnu1/drivers/video/maxinefb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/maxinefb.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/mb862xx/mb862xxfb_accel.c linux-libre-2.6.34-gnu1/drivers/video/mb862xx/mb862xxfb_accel.c
--- linux-libre-2.6.33-gnu1/drivers/video/mb862xx/mb862xxfb_accel.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/mb862xx/mb862xxfb_accel.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,7 +4,7 @@
  * Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver acceleration support
  *
  * (C) 2007 Alexander Shishkin <virtuoso@slind.org>
- * (C) 2009 Valentin Sitdikov <valentin.sitdikov@siemens.com>
+ * (C) 2009 Valentin Sitdikov <v.sitdikov@gmail.com>
  * (C) 2009 Siemens AG
  *
  * This program is free software; you can redistribute it and/or modify
@@ -16,7 +16,9 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #if defined(CONFIG_OF)
 #include <linux/of_platform.h>
 #endif
@@ -329,3 +331,5 @@ void mb862xxfb_init_accel(struct fb_info
 	info->fix.accel = 0xff;	/*FIXME: add right define */
 }
 EXPORT_SYMBOL(mb862xxfb_init_accel);
+
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/mb862xx/mb862xxfb.c linux-libre-2.6.34-gnu1/drivers/video/mb862xx/mb862xxfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/mb862xx/mb862xxfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/mb862xx/mb862xxfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,15 +31,6 @@
 #define CARMINE_MEM_SIZE	0x8000000
 #define DRV_NAME		"mb862xxfb"
 
-#if defined(CONFIG_LWMON5)
-static struct mb862xx_gc_mode lwmon5_gc_mode = {
-	/* Mode for Sharp LQ104V1DG61 TFT LCD Panel */
-	{ "640x480", 60, 640, 480, 40000, 48, 16, 32, 11, 96, 2, 0, 0, 0 },
-	/* 16 bits/pixel, 32MB, 100MHz, SDRAM memory mode value */
-	16, 0x2000000, GC_CCF_COT_100, 0x414fb7f2
-};
-#endif
-
 #if defined(CONFIG_SOCRATES)
 static struct mb862xx_gc_mode socrates_gc_mode = {
 	/* Mode for Prime View PM070WL4 TFT LCD Panel */
@@ -600,10 +591,6 @@ static int __devinit of_platform_mb862xx
 		goto irqdisp;
 	}
 
-#if defined(CONFIG_LWMON5)
-	par->gc_mode = &lwmon5_gc_mode;
-#endif
-
 #if defined(CONFIG_SOCRATES)
 	par->gc_mode = &socrates_gc_mode;
 #endif
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/mbx/mbxdebugfs.c linux-libre-2.6.34-gnu1/drivers/video/mbx/mbxdebugfs.c
--- linux-libre-2.6.33-gnu1/drivers/video/mbx/mbxdebugfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/mbx/mbxdebugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,5 @@
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 #define BIG_BUFFER_SIZE	(1024)
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/mbx/mbxfb.c linux-libre-2.6.34-gnu1/drivers/video/mbx/mbxfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/mbx/mbxfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/mbx/mbxfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -693,7 +693,7 @@ static void __devinit setup_memc(struct
 	unsigned long tmp;
 	int i;
 
-	/* FIXME: use platfrom specific parameters */
+	/* FIXME: use platform specific parameters */
 	/* setup SDRAM controller */
 	write_reg_dly((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS |
 		LMCFG_LMA_TS),
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/metronomefb.c linux-libre-2.6.34-gnu1/drivers/video/metronomefb.c
--- linux-libre-2.6.33-gnu1/drivers/video/metronomefb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/metronomefb.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/modedb.c linux-libre-2.6.34-gnu1/drivers/video/modedb.c
--- linux-libre-2.6.33-gnu1/drivers/video/modedb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/modedb.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/fb.h>
 #include <linux/kernel.h>
 
@@ -893,7 +894,7 @@ const struct fb_videomode *fb_match_mode
 }
 
 /**
- * fb_add_videomode: adds videomode entry to modelist
+ * fb_add_videomode - adds videomode entry to modelist
  * @mode: videomode to add
  * @head: struct list_head of modelist
  *
@@ -928,7 +929,7 @@ int fb_add_videomode(const struct fb_vid
 }
 
 /**
- * fb_delete_videomode: removed videomode entry from modelist
+ * fb_delete_videomode - removed videomode entry from modelist
  * @mode: videomode to remove
  * @head: struct list_head of modelist
  *
@@ -953,7 +954,7 @@ void fb_delete_videomode(const struct fb
 }
 
 /**
- * fb_destroy_modelist: destroy modelist
+ * fb_destroy_modelist - destroy modelist
  * @head: struct list_head of modelist
  */
 void fb_destroy_modelist(struct list_head *head)
@@ -968,7 +969,7 @@ void fb_destroy_modelist(struct list_hea
 EXPORT_SYMBOL_GPL(fb_destroy_modelist);
 
 /**
- * fb_videomode_to_modelist: convert mode array to mode list
+ * fb_videomode_to_modelist - convert mode array to mode list
  * @modedb: array of struct fb_videomode
  * @num: number of entries in array
  * @head: struct list_head of modelist
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/msm/mddi.c linux-libre-2.6.34-gnu1/drivers/video/msm/mddi.c
--- linux-libre-2.6.33-gnu1/drivers/video/msm/mddi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/msm/mddi.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/spinlock.h>
 #include <linux/clk.h>
 #include <linux/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/msm/mddi_client_dummy.c linux-libre-2.6.34-gnu1/drivers/video/msm/mddi_client_dummy.c
--- linux-libre-2.6.33-gnu1/drivers/video/msm/mddi_client_dummy.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/msm/mddi_client_dummy.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/msm/mddi_client_nt35399.c linux-libre-2.6.34-gnu1/drivers/video/msm/mddi_client_nt35399.c
--- linux-libre-2.6.33-gnu1/drivers/video/msm/mddi_client_nt35399.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/msm/mddi_client_nt35399.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 #include <mach/msm_fb.h>
 
 static DECLARE_WAIT_QUEUE_HEAD(nt35399_vsync_wait);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/msm/mddi_client_toshiba.c linux-libre-2.6.34-gnu1/drivers/video/msm/mddi_client_toshiba.c
--- linux-libre-2.6.33-gnu1/drivers/video/msm/mddi_client_toshiba.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/msm/mddi_client_toshiba.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <mach/msm_fb.h>
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/msm/mdp.c linux-libre-2.6.34-gnu1/drivers/video/msm/mdp.c
--- linux-libre-2.6.33-gnu1/drivers/video/msm/mdp.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/msm/mdp.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/clk.h>
 #include <linux/file.h>
 #include <linux/major.h>
+#include <linux/slab.h>
 
 #include <mach/msm_iomap.h>
 #include <mach/msm_fb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/msm/msm_fb.c linux-libre-2.6.34-gnu1/drivers/video/msm/msm_fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/msm/msm_fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/msm/msm_fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/fb.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include <linux/freezer.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/nuc900fb.c linux-libre-2.6.34-gnu1/drivers/video/nuc900fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/nuc900fb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/nuc900fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,779 @@
+/*
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ *  Description:
+ *    Nuvoton LCD Controller Driver
+ *  Author:
+ *    Wang Qiang (rurality.linux@gmail.com) 2009/12/11
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/wait.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/io.h>
+#include <linux/pm.h>
+#include <linux/device.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-ldm.h>
+#include <mach/fb.h>
+#include <mach/clkdev.h>
+
+#include "nuc900fb.h"
+
+
+/*
+ *  Initialize the nuc900 video (dual) buffer address
+ */
+static void nuc900fb_set_lcdaddr(struct fb_info *info)
+{
+	struct nuc900fb_info *fbi = info->par;
+	void __iomem *regs = fbi->io;
+	unsigned long vbaddr1, vbaddr2;
+
+	vbaddr1  = info->fix.smem_start;
+	vbaddr2  = info->fix.smem_start;
+	vbaddr2 += info->fix.line_length * info->var.yres;
+
+	/* set frambuffer start phy addr*/
+	writel(vbaddr1, regs + REG_LCM_VA_BADDR0);
+	writel(vbaddr2, regs + REG_LCM_VA_BADDR1);
+
+	writel(fbi->regs.lcd_va_fbctrl, regs + REG_LCM_VA_FBCTRL);
+	writel(fbi->regs.lcd_va_scale, regs + REG_LCM_VA_SCALE);
+}
+
+/*
+ *	calculate divider for lcd div
+ */
+static unsigned int nuc900fb_calc_pixclk(struct nuc900fb_info *fbi,
+					 unsigned long pixclk)
+{
+	unsigned long clk = fbi->clk_rate;
+	unsigned long long div;
+
+	/* pixclk is in picseconds. our clock is in Hz*/
+	/* div = (clk * pixclk)/10^12 */
+	div = (unsigned long long)clk * pixclk;
+	div >>= 12;
+	do_div(div, 625 * 625UL * 625);
+
+	dev_dbg(fbi->dev, "pixclk %ld, divisor is %lld\n", pixclk, div);
+
+	return div;
+}
+
+/*
+ *	Check the video params of 'var'.
+ */
+static int nuc900fb_check_var(struct fb_var_screeninfo *var,
+			       struct fb_info *info)
+{
+	struct nuc900fb_info *fbi = info->par;
+	struct nuc900fb_mach_info *mach_info = fbi->dev->platform_data;
+	struct nuc900fb_display *display = NULL;
+	struct nuc900fb_display *default_display = mach_info->displays +
+						   mach_info->default_display;
+	int i;
+
+	dev_dbg(fbi->dev, "check_var(var=%p, info=%p)\n", var, info);
+
+	/* validate x/y resolution */
+	/* choose default mode if possible */
+	if (var->xres == default_display->xres &&
+	    var->yres == default_display->yres &&
+	    var->bits_per_pixel == default_display->bpp)
+		display = default_display;
+	else
+		for (i = 0; i < mach_info->num_displays; i++)
+			if (var->xres == mach_info->displays[i].xres &&
+			    var->yres == mach_info->displays[i].yres &&
+			    var->bits_per_pixel == mach_info->displays[i].bpp) {
+				display = mach_info->displays + i;
+				break;
+			}
+
+	if (display == NULL) {
+		printk(KERN_ERR "wrong resolution or depth %dx%d at %d bit per pixel\n",
+			var->xres, var->yres, var->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	/* it should be the same size as the display */
+	var->xres_virtual	= display->xres;
+	var->yres_virtual	= display->yres;
+	var->height		= display->height;
+	var->width		= display->width;
+
+	/* copy lcd settings */
+	var->pixclock		= display->pixclock;
+	var->left_margin	= display->left_margin;
+	var->right_margin	= display->right_margin;
+	var->upper_margin	= display->upper_margin;
+	var->lower_margin	= display->lower_margin;
+	var->vsync_len		= display->vsync_len;
+	var->hsync_len		= display->hsync_len;
+
+	var->transp.offset	= 0;
+	var->transp.length	= 0;
+
+	fbi->regs.lcd_dccs = display->dccs;
+	fbi->regs.lcd_device_ctrl = display->devctl;
+	fbi->regs.lcd_va_fbctrl = display->fbctrl;
+	fbi->regs.lcd_va_scale = display->scale;
+
+	/* set R/G/B possions */
+	switch (var->bits_per_pixel) {
+	case 1:
+	case 2:
+	case 4:
+	case 8:
+	default:
+		var->red.offset 	= 0;
+		var->red.length 	= var->bits_per_pixel;
+		var->green 		= var->red;
+		var->blue		= var->red;
+		break;
+	case 12:
+		var->red.length		= 4;
+		var->green.length	= 4;
+		var->blue.length	= 4;
+		var->red.offset		= 8;
+		var->green.offset	= 4;
+		var->blue.offset	= 0;
+		break;
+	case 16:
+		var->red.length		= 5;
+		var->green.length	= 6;
+		var->blue.length	= 5;
+		var->red.offset		= 11;
+		var->green.offset	= 5;
+		var->blue.offset	= 0;
+		break;
+	case 18:
+		var->red.length		= 6;
+		var->green.length	= 6;
+		var->blue.length	= 6;
+		var->red.offset		= 12;
+		var->green.offset	= 6;
+		var->blue.offset	= 0;
+		break;
+	case 32:
+		var->red.length		= 8;
+		var->green.length	= 8;
+		var->blue.length	= 8;
+		var->red.offset		= 16;
+		var->green.offset	= 8;
+		var->blue.offset	= 0;
+		break;
+	}
+
+	return 0;
+}
+
+/*
+ *	Calculate lcd register values from var setting & save into hw
+ */
+static void nuc900fb_calculate_lcd_regs(const struct fb_info *info,
+					struct nuc900fb_hw *regs)
+{
+	const struct fb_var_screeninfo *var = &info->var;
+	int vtt = var->height + var->upper_margin + var->lower_margin;
+	int htt = var->width + var->left_margin + var->right_margin;
+	int hsync = var->width + var->right_margin;
+	int vsync = var->height + var->lower_margin;
+
+	regs->lcd_crtc_size = LCM_CRTC_SIZE_VTTVAL(vtt) |
+			      LCM_CRTC_SIZE_HTTVAL(htt);
+	regs->lcd_crtc_dend = LCM_CRTC_DEND_VDENDVAL(var->height) |
+			      LCM_CRTC_DEND_HDENDVAL(var->width);
+	regs->lcd_crtc_hr = LCM_CRTC_HR_EVAL(var->width + 5) |
+			    LCM_CRTC_HR_SVAL(var->width + 1);
+	regs->lcd_crtc_hsync = LCM_CRTC_HSYNC_EVAL(hsync + var->hsync_len) |
+			       LCM_CRTC_HSYNC_SVAL(hsync);
+	regs->lcd_crtc_vr = LCM_CRTC_VR_EVAL(vsync + var->vsync_len) |
+			    LCM_CRTC_VR_SVAL(vsync);
+
+}
+
+/*
+ *	Activate (set) the controller from the given framebuffer
+ *	information
+ */
+static void nuc900fb_activate_var(struct fb_info *info)
+{
+	struct nuc900fb_info *fbi = info->par;
+	void __iomem *regs = fbi->io;
+	struct fb_var_screeninfo *var = &info->var;
+	int clkdiv;
+
+	clkdiv = nuc900fb_calc_pixclk(fbi, var->pixclock) - 1;
+	if (clkdiv < 0)
+		clkdiv = 0;
+
+	nuc900fb_calculate_lcd_regs(info, &fbi->regs);
+
+	/* set the new lcd registers*/
+
+	dev_dbg(fbi->dev, "new lcd register set:\n");
+	dev_dbg(fbi->dev, "dccs       = 0x%08x\n", fbi->regs.lcd_dccs);
+	dev_dbg(fbi->dev, "dev_ctl    = 0x%08x\n", fbi->regs.lcd_device_ctrl);
+	dev_dbg(fbi->dev, "crtc_size  = 0x%08x\n", fbi->regs.lcd_crtc_size);
+	dev_dbg(fbi->dev, "crtc_dend  = 0x%08x\n", fbi->regs.lcd_crtc_dend);
+	dev_dbg(fbi->dev, "crtc_hr    = 0x%08x\n", fbi->regs.lcd_crtc_hr);
+	dev_dbg(fbi->dev, "crtc_hsync = 0x%08x\n", fbi->regs.lcd_crtc_hsync);
+	dev_dbg(fbi->dev, "crtc_vr    = 0x%08x\n", fbi->regs.lcd_crtc_vr);
+
+	writel(fbi->regs.lcd_device_ctrl, regs + REG_LCM_DEV_CTRL);
+	writel(fbi->regs.lcd_crtc_size, regs + REG_LCM_CRTC_SIZE);
+	writel(fbi->regs.lcd_crtc_dend, regs + REG_LCM_CRTC_DEND);
+	writel(fbi->regs.lcd_crtc_hr, regs + REG_LCM_CRTC_HR);
+	writel(fbi->regs.lcd_crtc_hsync, regs + REG_LCM_CRTC_HSYNC);
+	writel(fbi->regs.lcd_crtc_vr, regs + REG_LCM_CRTC_VR);
+
+	/* set lcd address pointers */
+	nuc900fb_set_lcdaddr(info);
+
+	writel(fbi->regs.lcd_dccs, regs + REG_LCM_DCCS);
+}
+
+/*
+ *      Alters the hardware state.
+ *
+ */
+static int nuc900fb_set_par(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+
+	switch (var->bits_per_pixel) {
+	case 32:
+	case 24:
+	case 18:
+	case 16:
+	case 12:
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+		break;
+	case 1:
+		info->fix.visual = FB_VISUAL_MONO01;
+		break;
+	default:
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+		break;
+	}
+
+	info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8;
+
+	/* activate this new configuration */
+	nuc900fb_activate_var(info);
+	return 0;
+}
+
+static inline unsigned int chan_to_field(unsigned int chan,
+					 struct fb_bitfield *bf)
+{
+	chan &= 0xffff;
+	chan >>= 16 - bf->length;
+	return chan << bf->offset;
+}
+
+static int nuc900fb_setcolreg(unsigned regno,
+			       unsigned red, unsigned green, unsigned blue,
+			       unsigned transp, struct fb_info *info)
+{
+	unsigned int val;
+
+	switch (info->fix.visual) {
+	case FB_VISUAL_TRUECOLOR:
+		/* true-colour, use pseuo-palette */
+		if (regno < 16) {
+			u32 *pal = info->pseudo_palette;
+
+			val  = chan_to_field(red, &info->var.red);
+			val |= chan_to_field(green, &info->var.green);
+			val |= chan_to_field(blue, &info->var.blue);
+			pal[regno] = val;
+		}
+		break;
+
+	default:
+		return 1;   /* unknown type */
+	}
+	return 0;
+}
+
+/**
+ *      nuc900fb_blank
+ *
+ */
+static int nuc900fb_blank(int blank_mode, struct fb_info *info)
+{
+
+	return 0;
+}
+
+static struct fb_ops nuc900fb_ops = {
+	.owner			= THIS_MODULE,
+	.fb_check_var		= nuc900fb_check_var,
+	.fb_set_par		= nuc900fb_set_par,
+	.fb_blank		= nuc900fb_blank,
+	.fb_setcolreg		= nuc900fb_setcolreg,
+	.fb_fillrect		= cfb_fillrect,
+	.fb_copyarea		= cfb_copyarea,
+	.fb_imageblit		= cfb_imageblit,
+};
+
+
+static inline void modify_gpio(void __iomem *reg,
+			       unsigned long set, unsigned long mask)
+{
+	unsigned long tmp;
+	tmp = readl(reg) & ~mask;
+	writel(tmp | set, reg);
+}
+
+/*
+ * Initialise LCD-related registers
+ */
+static int nuc900fb_init_registers(struct fb_info *info)
+{
+	struct nuc900fb_info *fbi = info->par;
+	struct nuc900fb_mach_info *mach_info = fbi->dev->platform_data;
+	void __iomem *regs = fbi->io;
+
+	/*reset the display engine*/
+	writel(0, regs + REG_LCM_DCCS);
+	writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_ENG_RST,
+	       regs + REG_LCM_DCCS);
+	ndelay(100);
+	writel(readl(regs + REG_LCM_DCCS) & (~LCM_DCCS_ENG_RST),
+	       regs + REG_LCM_DCCS);
+	ndelay(100);
+
+	writel(0, regs + REG_LCM_DEV_CTRL);
+
+	/* config gpio output */
+	modify_gpio(W90X900_VA_GPIO + 0x54, mach_info->gpio_dir,
+		    mach_info->gpio_dir_mask);
+	modify_gpio(W90X900_VA_GPIO + 0x58, mach_info->gpio_data,
+		    mach_info->gpio_data_mask);
+
+	return 0;
+}
+
+
+/*
+ *    Alloc the SDRAM region of NUC900 for the frame buffer.
+ *    The buffer should be a non-cached, non-buffered, memory region
+ *    to allow palette and pixel writes without flushing the cache.
+ */
+static int __init nuc900fb_map_video_memory(struct fb_info *info)
+{
+	struct nuc900fb_info *fbi = info->par;
+	dma_addr_t map_dma;
+	unsigned long map_size = PAGE_ALIGN(info->fix.smem_len);
+
+	dev_dbg(fbi->dev, "nuc900fb_map_video_memory(fbi=%p) map_size %lu\n",
+		fbi, map_size);
+
+	info->screen_base = dma_alloc_writecombine(fbi->dev, map_size,
+							&map_dma, GFP_KERNEL);
+
+	if (!info->screen_base)
+		return -ENOMEM;
+
+	memset(info->screen_base, 0x00, map_size);
+	info->fix.smem_start = map_dma;
+
+	return 0;
+}
+
+static inline void nuc900fb_unmap_video_memory(struct fb_info *info)
+{
+	struct nuc900fb_info *fbi = info->par;
+	dma_free_writecombine(fbi->dev, PAGE_ALIGN(info->fix.smem_len),
+			      info->screen_base, info->fix.smem_start);
+}
+
+static irqreturn_t nuc900fb_irqhandler(int irq, void *dev_id)
+{
+	struct nuc900fb_info *fbi = dev_id;
+	void __iomem *regs = fbi->io;
+	void __iomem *irq_base = fbi->irq_base;
+	unsigned long lcdirq = readl(regs + REG_LCM_INT_CS);
+
+	if (lcdirq & LCM_INT_CS_DISP_F_STATUS) {
+		writel(readl(irq_base) | 1<<30, irq_base);
+
+		/* wait VA_EN low */
+		if ((readl(regs + REG_LCM_DCCS) &
+		    LCM_DCCS_SINGLE) == LCM_DCCS_SINGLE)
+			while ((readl(regs + REG_LCM_DCCS) &
+			       LCM_DCCS_VA_EN) == LCM_DCCS_VA_EN)
+				;
+		/* display_out-enable */
+		writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_DISP_OUT_EN,
+			regs + REG_LCM_DCCS);
+		/* va-enable*/
+		writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_VA_EN,
+			regs + REG_LCM_DCCS);
+	} else if (lcdirq & LCM_INT_CS_UNDERRUN_INT) {
+		writel(readl(irq_base) | LCM_INT_CS_UNDERRUN_INT, irq_base);
+	} else if (lcdirq & LCM_INT_CS_BUS_ERROR_INT) {
+		writel(readl(irq_base) | LCM_INT_CS_BUS_ERROR_INT, irq_base);
+	}
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_CPU_FREQ
+
+static int nuc900fb_cpufreq_transition(struct notifier_block *nb,
+				       unsigned long val, void *data)
+{
+	struct nuc900fb_info *info;
+	struct fb_info *fbinfo;
+	long delta_f;
+	info = container_of(nb, struct nuc900fb_info, freq_transition);
+	fbinfo = platform_get_drvdata(to_platform_device(info->dev));
+
+	delta_f = info->clk_rate - clk_get_rate(info->clk);
+
+	if ((val == CPUFREQ_POSTCHANGE && delta_f > 0) ||
+	   (val == CPUFREQ_PRECHANGE && delta_f < 0)) {
+		info->clk_rate = clk_get_rate(info->clk);
+		nuc900fb_activate_var(fbinfo);
+	}
+
+	return 0;
+}
+
+static inline int nuc900fb_cpufreq_register(struct nuc900fb_info *fbi)
+{
+	fbi->freq_transition.notifier_call = nuc900fb_cpufreq_transition;
+	return cpufreq_register_notifier(&fbi->freq_transition,
+				  CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+static inline void nuc900fb_cpufreq_deregister(struct nuc900fb_info *fbi)
+{
+	cpufreq_unregister_notifier(&fbi->freq_transition,
+				    CPUFREQ_TRANSITION_NOTIFIER);
+}
+#else
+static inline int nuc900fb_cpufreq_transition(struct notifier_block *nb,
+				       unsigned long val, void *data)
+{
+	return 0;
+}
+
+static inline int nuc900fb_cpufreq_register(struct nuc900fb_info *fbi)
+{
+	return 0;
+}
+
+static inline void nuc900fb_cpufreq_deregister(struct nuc900fb_info *info)
+{
+}
+#endif
+
+static char driver_name[] = "nuc900fb";
+
+static int __devinit nuc900fb_probe(struct platform_device *pdev)
+{
+	struct nuc900fb_info *fbi;
+	struct nuc900fb_display *display;
+	struct fb_info	   *fbinfo;
+	struct nuc900fb_mach_info *mach_info;
+	struct resource *res;
+	int ret;
+	int irq;
+	int i;
+	int size;
+
+	dev_dbg(&pdev->dev, "devinit\n");
+	mach_info = pdev->dev.platform_data;
+	if (mach_info == NULL) {
+		dev_err(&pdev->dev,
+			"no platform data for lcd, cannot attach\n");
+		return -EINVAL;
+	}
+
+	if (mach_info->default_display > mach_info->num_displays) {
+		dev_err(&pdev->dev,
+			"default display No. is %d but only %d displays \n",
+			mach_info->default_display, mach_info->num_displays);
+		return -EINVAL;
+	}
+
+
+	display = mach_info->displays + mach_info->default_display;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "no irq for device\n");
+		return -ENOENT;
+	}
+
+	fbinfo = framebuffer_alloc(sizeof(struct nuc900fb_info), &pdev->dev);
+	if (!fbinfo)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, fbinfo);
+
+	fbi = fbinfo->par;
+	fbi->dev = &pdev->dev;
+
+#ifdef CONFIG_CPU_NUC950
+	fbi->drv_type = LCDDRV_NUC950;
+#endif
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	size = (res->end - res->start) + 1;
+	fbi->mem = request_mem_region(res->start, size, pdev->name);
+	if (fbi->mem == NULL) {
+		dev_err(&pdev->dev, "failed to alloc memory region\n");
+		ret = -ENOENT;
+		goto free_fb;
+	}
+
+	fbi->io = ioremap(res->start, size);
+	if (fbi->io == NULL) {
+		dev_err(&pdev->dev, "ioremap() of lcd registers failed\n");
+		ret = -ENXIO;
+		goto release_mem_region;
+	}
+
+	fbi->irq_base = fbi->io + REG_LCM_INT_CS;
+
+
+	/* Stop the LCD */
+	writel(0, fbi->io + REG_LCM_DCCS);
+
+	/* fill the fbinfo*/
+	strcpy(fbinfo->fix.id, driver_name);
+	fbinfo->fix.type		= FB_TYPE_PACKED_PIXELS;
+	fbinfo->fix.type_aux		= 0;
+	fbinfo->fix.xpanstep		= 0;
+	fbinfo->fix.ypanstep		= 0;
+	fbinfo->fix.ywrapstep		= 0;
+	fbinfo->fix.accel		= FB_ACCEL_NONE;
+	fbinfo->var.nonstd		= 0;
+	fbinfo->var.activate		= FB_ACTIVATE_NOW;
+	fbinfo->var.accel_flags		= 0;
+	fbinfo->var.vmode		= FB_VMODE_NONINTERLACED;
+	fbinfo->fbops			= &nuc900fb_ops;
+	fbinfo->flags			= FBINFO_FLAG_DEFAULT;
+	fbinfo->pseudo_palette		= &fbi->pseudo_pal;
+
+	ret = request_irq(irq, nuc900fb_irqhandler, IRQF_DISABLED,
+			  pdev->name, fbinfo);
+	if (ret) {
+		dev_err(&pdev->dev, "cannot register irq handler %d -err %d\n",
+			irq, ret);
+		ret = -EBUSY;
+		goto release_regs;
+	}
+
+	nuc900_driver_clksrc_div(&pdev->dev, "ext", 0x2);
+
+	fbi->clk = clk_get(&pdev->dev, NULL);
+	if (!fbi->clk || IS_ERR(fbi->clk)) {
+		printk(KERN_ERR "nuc900-lcd:failed to get lcd clock source\n");
+		ret = -ENOENT;
+		goto release_irq;
+	}
+
+	clk_enable(fbi->clk);
+	dev_dbg(&pdev->dev, "got and enabled clock\n");
+
+	fbi->clk_rate = clk_get_rate(fbi->clk);
+
+	/* calutate the video buffer size */
+	for (i = 0; i < mach_info->num_displays; i++) {
+		unsigned long smem_len = mach_info->displays[i].xres;
+		smem_len *= mach_info->displays[i].yres;
+		smem_len *= mach_info->displays[i].bpp;
+		smem_len >>= 3;
+		if (fbinfo->fix.smem_len < smem_len)
+			fbinfo->fix.smem_len = smem_len;
+	}
+
+	/* Initialize Video Memory */
+	ret = nuc900fb_map_video_memory(fbinfo);
+	if (ret) {
+		printk(KERN_ERR "Failed to allocate video RAM: %x\n", ret);
+		goto release_clock;
+	}
+
+	dev_dbg(&pdev->dev, "got video memory\n");
+
+	fbinfo->var.xres = display->xres;
+	fbinfo->var.yres = display->yres;
+	fbinfo->var.bits_per_pixel = display->bpp;
+
+	nuc900fb_init_registers(fbinfo);
+
+	nuc900fb_check_var(&fbinfo->var, fbinfo);
+
+	ret = nuc900fb_cpufreq_register(fbi);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to register cpufreq\n");
+		goto free_video_memory;
+	}
+
+	ret = register_framebuffer(fbinfo);
+	if (ret) {
+		printk(KERN_ERR "failed to register framebuffer device: %d\n",
+			ret);
+		goto free_cpufreq;
+	}
+
+	printk(KERN_INFO "fb%d: %s frame buffer device\n",
+		fbinfo->node, fbinfo->fix.id);
+
+	return 0;
+
+free_cpufreq:
+	nuc900fb_cpufreq_deregister(fbi);
+free_video_memory:
+	nuc900fb_unmap_video_memory(fbinfo);
+release_clock:
+	clk_disable(fbi->clk);
+	clk_put(fbi->clk);
+release_irq:
+	free_irq(irq, fbi);
+release_regs:
+	iounmap(fbi->io);
+release_mem_region:
+	release_mem_region((unsigned long)fbi->mem, size);
+free_fb:
+	framebuffer_release(fbinfo);
+	return ret;
+}
+
+/*
+ * shutdown the lcd controller
+ */
+static void nuc900fb_stop_lcd(struct fb_info *info)
+{
+	struct nuc900fb_info *fbi = info->par;
+	void __iomem *regs = fbi->io;
+
+	writel((~LCM_DCCS_DISP_INT_EN) | (~LCM_DCCS_VA_EN) | (~LCM_DCCS_OSD_EN),
+		regs + REG_LCM_DCCS);
+}
+
+/*
+ *  Cleanup
+ */
+static int nuc900fb_remove(struct platform_device *pdev)
+{
+	struct fb_info *fbinfo = platform_get_drvdata(pdev);
+	struct nuc900fb_info *fbi = fbinfo->par;
+	int irq;
+
+	nuc900fb_stop_lcd(fbinfo);
+	msleep(1);
+
+	nuc900fb_unmap_video_memory(fbinfo);
+
+	iounmap(fbi->io);
+
+	irq = platform_get_irq(pdev, 0);
+	free_irq(irq, fbi);
+
+	release_resource(fbi->mem);
+	kfree(fbi->mem);
+
+	platform_set_drvdata(pdev, NULL);
+	framebuffer_release(fbinfo);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+/*
+ *	suspend and resume support for the lcd controller
+ */
+
+static int nuc900fb_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct fb_info	   *fbinfo = platform_get_drvdata(dev);
+	struct nuc900fb_info *info = fbinfo->par;
+
+	nuc900fb_stop_lcd();
+	msleep(1);
+	clk_disable(info->clk);
+	return 0;
+}
+
+static int nuc900fb_resume(struct platform_device *dev)
+{
+	struct fb_info	   *fbinfo = platform_get_drvdata(dev);
+	struct nuc900fb_info *fbi = fbinfo->par;
+
+	printk(KERN_INFO "nuc900fb resume\n");
+
+	clk_enable(fbi->clk);
+	msleep(1);
+
+	nuc900fb_init_registers(fbinfo);
+	nuc900fb_activate_var(bfinfo);
+
+	return 0;
+}
+
+#else
+#define nuc900fb_suspend NULL
+#define nuc900fb_resume  NULL
+#endif
+
+static struct platform_driver nuc900fb_driver = {
+	.probe		= nuc900fb_probe,
+	.remove		= nuc900fb_remove,
+	.suspend	= nuc900fb_suspend,
+	.resume		= nuc900fb_resume,
+	.driver		= {
+		.name	= "nuc900-lcd",
+		.owner	= THIS_MODULE,
+	},
+};
+
+int __devinit nuc900fb_init(void)
+{
+	return platform_driver_register(&nuc900fb_driver);
+}
+
+static void __exit nuc900fb_cleanup(void)
+{
+	platform_driver_unregister(&nuc900fb_driver);
+}
+
+module_init(nuc900fb_init);
+module_exit(nuc900fb_cleanup);
+
+MODULE_DESCRIPTION("Framebuffer driver for the NUC900");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/nuc900fb.h linux-libre-2.6.34-gnu1/drivers/video/nuc900fb.h
--- linux-libre-2.6.33-gnu1/drivers/video/nuc900fb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/nuc900fb.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ *   Auther:
+ *        Wang Qiang(rurality.linux@gmail.com)  2009/12/16
+ */
+
+#ifndef __NUC900FB_H
+#define __NUC900FB_H
+
+#include <mach/map.h>
+#include <mach/fb.h>
+
+enum nuc900_lcddrv_type {
+	LCDDRV_NUC910,
+	LCDDRV_NUC930,
+	LCDDRV_NUC932,
+	LCDDRV_NUC950,
+	LCDDRV_NUC960,
+};
+
+
+#define PALETTE_BUFFER_SIZE	256
+#define PALETTE_BUFF_CLEAR 	(0x80000000) /* entry is clear/invalid */
+
+struct nuc900fb_info {
+	struct device		*dev;
+	struct clk		*clk;
+
+	struct resource		*mem;
+	void __iomem		*io;
+	void __iomem		*irq_base;
+	int 			drv_type;
+	struct nuc900fb_hw	regs;
+	unsigned long		clk_rate;
+
+#ifdef CONFIG_CPU_FREQ
+	struct notifier_block	freq_transition;
+#endif
+
+	/* keep these registers in case we need to re-write palette */
+	u32			palette_buffer[PALETTE_BUFFER_SIZE];
+	u32			pseudo_pal[16];
+};
+
+int nuc900fb_init(void);
+
+#endif /* __NUC900FB_H */
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/nvidia/nv_backlight.c linux-libre-2.6.34-gnu1/drivers/video/nvidia/nv_backlight.c
--- linux-libre-2.6.33-gnu1/drivers/video/nvidia/nv_backlight.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/nvidia/nv_backlight.c	2010-05-16 17:17:36.000000000 -0400
@@ -94,6 +94,7 @@ static struct backlight_ops nvidia_bl_op
 
 void nvidia_bl_init(struct nvidia_par *par)
 {
+	struct backlight_properties props;
 	struct fb_info *info = pci_get_drvdata(par->pci_dev);
 	struct backlight_device *bd;
 	char name[12];
@@ -109,7 +110,10 @@ void nvidia_bl_init(struct nvidia_par *p
 
 	snprintf(name, sizeof(name), "nvidiabl%d", info->node);
 
-	bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+	bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops,
+				       &props);
 	if (IS_ERR(bd)) {
 		info->bl_dev = NULL;
 		printk(KERN_WARNING "nvidia: Backlight registration failed\n");
@@ -121,7 +125,6 @@ void nvidia_bl_init(struct nvidia_par *p
 		0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL,
 		0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
 
-	bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
 	bd->props.brightness = bd->props.max_brightness;
 	bd->props.power = FB_BLANK_UNBLANK;
 	backlight_update_status(bd);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/nvidia/nv_i2c.c linux-libre-2.6.34-gnu1/drivers/video/nvidia/nv_i2c.c
--- linux-libre-2.6.33-gnu1/drivers/video/nvidia/nv_i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/nvidia/nv_i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/fb.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/nvidia/nv_of.c linux-libre-2.6.34-gnu1/drivers/video/nvidia/nv_of.c
--- linux-libre-2.6.33-gnu1/drivers/video/nvidia/nv_of.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/nvidia/nv_of.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/fb.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/nvidia/nv_setup.c linux-libre-2.6.34-gnu1/drivers/video/nvidia/nv_setup.c
--- linux-libre-2.6.33-gnu1/drivers/video/nvidia/nv_setup.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/nvidia/nv_setup.c	2010-05-16 17:17:36.000000000 -0400
@@ -50,6 +50,7 @@
 #include <video/vga.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include "nv_type.h"
 #include "nv_local.h"
 #include "nv_proto.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/offb.c linux-libre-2.6.34-gnu1/drivers/video/offb.c
--- linux-libre-2.6.33-gnu1/drivers/video/offb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/offb.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap/dispc.c linux-libre-2.6.34-gnu1/drivers/video/omap/dispc.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap/dispc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap/dispc.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <plat/sram.h>
 #include <plat/board.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap/lcd_ams_delta.c linux-libre-2.6.34-gnu1/drivers/video/omap/lcd_ams_delta.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap/lcd_ams_delta.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap/lcd_ams_delta.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/delay.h>
+#include <linux/lcd.h>
 
 #include <plat/board-ams-delta.h>
 #include <mach/hardware.h>
@@ -32,6 +33,71 @@
 
 #define AMS_DELTA_DEFAULT_CONTRAST	112
 
+#define AMS_DELTA_MAX_CONTRAST		0x00FF
+#define AMS_DELTA_LCD_POWER		0x0100
+
+
+/* LCD class device section */
+
+static int ams_delta_lcd;
+
+static int ams_delta_lcd_set_power(struct lcd_device *dev, int power)
+{
+	if (power == FB_BLANK_UNBLANK) {
+		if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER)) {
+			omap_writeb(ams_delta_lcd & AMS_DELTA_MAX_CONTRAST,
+					OMAP_PWL_ENABLE);
+			omap_writeb(1, OMAP_PWL_CLK_ENABLE);
+			ams_delta_lcd |= AMS_DELTA_LCD_POWER;
+		}
+	} else {
+		if (ams_delta_lcd & AMS_DELTA_LCD_POWER) {
+			omap_writeb(0, OMAP_PWL_ENABLE);
+			omap_writeb(0, OMAP_PWL_CLK_ENABLE);
+			ams_delta_lcd &= ~AMS_DELTA_LCD_POWER;
+		}
+	}
+	return 0;
+}
+
+static int ams_delta_lcd_set_contrast(struct lcd_device *dev, int value)
+{
+	if ((value >= 0) && (value <= AMS_DELTA_MAX_CONTRAST)) {
+		omap_writeb(value, OMAP_PWL_ENABLE);
+		ams_delta_lcd &= ~AMS_DELTA_MAX_CONTRAST;
+		ams_delta_lcd |= value;
+	}
+	return 0;
+}
+
+#ifdef CONFIG_LCD_CLASS_DEVICE
+static int ams_delta_lcd_get_power(struct lcd_device *dev)
+{
+	if (ams_delta_lcd & AMS_DELTA_LCD_POWER)
+		return FB_BLANK_UNBLANK;
+	else
+		return FB_BLANK_POWERDOWN;
+}
+
+static int ams_delta_lcd_get_contrast(struct lcd_device *dev)
+{
+	if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER))
+		return 0;
+
+	return ams_delta_lcd & AMS_DELTA_MAX_CONTRAST;
+}
+
+static struct lcd_ops ams_delta_lcd_ops = {
+	.get_power = ams_delta_lcd_get_power,
+	.set_power = ams_delta_lcd_set_power,
+	.get_contrast = ams_delta_lcd_get_contrast,
+	.set_contrast = ams_delta_lcd_set_contrast,
+};
+#endif
+
+
+/* omapfb panel section */
+
 static int ams_delta_panel_init(struct lcd_panel *panel,
 		struct omapfb_device *fbdev)
 {
@@ -48,10 +114,6 @@ static int ams_delta_panel_enable(struct
 			AMS_DELTA_LATCH2_LCD_NDISP);
 	ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN,
 			AMS_DELTA_LATCH2_LCD_VBLEN);
-
-	omap_writeb(1, OMAP_PWL_CLK_ENABLE);
-	omap_writeb(AMS_DELTA_DEFAULT_CONTRAST, OMAP_PWL_ENABLE);
-
 	return 0;
 }
 
@@ -91,8 +153,31 @@ static struct lcd_panel ams_delta_panel
 	.get_caps	= ams_delta_panel_get_caps,
 };
 
+
+/* platform driver section */
+
 static int ams_delta_panel_probe(struct platform_device *pdev)
 {
+	struct lcd_device *lcd_device = NULL;
+#ifdef CONFIG_LCD_CLASS_DEVICE
+	int ret;
+
+	lcd_device = lcd_device_register("omapfb", &pdev->dev, NULL,
+						&ams_delta_lcd_ops);
+
+	if (IS_ERR(lcd_device)) {
+		ret = PTR_ERR(lcd_device);
+		dev_err(&pdev->dev, "failed to register device\n");
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, lcd_device);
+	lcd_device->props.max_contrast = AMS_DELTA_MAX_CONTRAST;
+#endif
+
+	ams_delta_lcd_set_contrast(lcd_device, AMS_DELTA_DEFAULT_CONTRAST);
+	ams_delta_lcd_set_power(lcd_device, FB_BLANK_UNBLANK);
+
 	omapfb_register_panel(&ams_delta_panel);
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap/lcdc.c linux-libre-2.6.34-gnu1/drivers/video/omap/lcdc.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap/lcdc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap/lcdc.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/vmalloc.h>
 #include <linux/clk.h>
+#include <linux/gfp.h>
 
 #include <mach/lcdc.h>
 #include <plat/dma.h>
@@ -389,7 +390,7 @@ static int omap_lcdc_enable_plane(int pl
 /*
  * Configure the LCD DMA for a palette load operation and do the palette
  * downloading synchronously. We don't use the frame+palette load mode of
- * the controller, since the palette can always be downloaded seperately.
+ * the controller, since the palette can always be downloaded separately.
  */
 static void load_palette(void)
 {
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap/lcd_mipid.c linux-libre-2.6.34-gnu1/drivers/video/omap/lcd_mipid.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap/lcd_mipid.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap/lcd_mipid.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 #include <linux/device.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/spi/spi.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap/omapfb_main.c linux-libre-2.6.34-gnu1/drivers/video/omap/omapfb_main.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap/omapfb_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap/omapfb_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
  */
 #include <linux/platform_device.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 
 #include <plat/dma.h>
@@ -486,10 +487,11 @@ static int set_color_mode(struct omapfb_
 		return 0;
 	case 12:
 		var->bits_per_pixel = 16;
-		plane->color_mode = OMAPFB_COLOR_RGB444;
-		return 0;
 	case 16:
-		plane->color_mode = OMAPFB_COLOR_RGB565;
+		if (plane->fbdev->panel->bpp == 12)
+			plane->color_mode = OMAPFB_COLOR_RGB444;
+		else
+			plane->color_mode = OMAPFB_COLOR_RGB565;
 		return 0;
 	default:
 		return -EINVAL;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/Kconfig linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -13,10 +13,28 @@ config PANEL_SHARP_LS037V7DW01
         help
           LCD Panel used in TI's SDP3430 and EVM boards
 
+config PANEL_SHARP_LQ043T1DG01
+        tristate "Sharp LQ043T1DG01 LCD Panel"
+        depends on OMAP2_DSS
+        help
+          LCD Panel used in TI's OMAP3517 EVM boards
+
 config PANEL_TAAL
         tristate "Taal DSI Panel"
         depends on OMAP2_DSS_DSI
         help
           Taal DSI command mode panel from TPO.
 
+config PANEL_TOPPOLY_TDO35S
+        tristate "Toppoly TDO35S LCD Panel support"
+        depends on OMAP2_DSS
+        help
+          LCD Panel used in CM-T35
+
+config PANEL_TPO_TD043MTEA1
+        tristate "TPO TD043MTEA1 LCD Panel"
+        depends on OMAP2_DSS && I2C
+        help
+          LCD Panel used in OMAP3 Pandora
+
 endmenu
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/Makefile linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/Makefile
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -1,4 +1,7 @@
 obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o
 obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
+obj-$(CONFIG_PANEL_SHARP_LQ043T1DG01) += panel-sharp-lq043t1dg01.o
 
 obj-$(CONFIG_PANEL_TAAL) += panel-taal.o
+obj-$(CONFIG_PANEL_TOPPOLY_TDO35S) += panel-toppoly-tdo35s.o
+obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/panel-generic.c linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/panel-generic.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/panel-generic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/panel-generic.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,35 @@ static struct omap_video_timings generic
 	.vbp		= 7,
 };
 
+static int generic_panel_power_on(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	r = omapdss_dpi_display_enable(dssdev);
+	if (r)
+		goto err0;
+
+	if (dssdev->platform_enable) {
+		r = dssdev->platform_enable(dssdev);
+		if (r)
+			goto err1;
+	}
+
+	return 0;
+err1:
+	omapdss_dpi_display_disable(dssdev);
+err0:
+	return r;
+}
+
+static void generic_panel_power_off(struct omap_dss_device *dssdev)
+{
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
+
+	omapdss_dpi_display_disable(dssdev);
+}
+
 static int generic_panel_probe(struct omap_dss_device *dssdev)
 {
 	dssdev->panel.config = OMAP_DSS_LCD_TFT;
@@ -51,27 +80,58 @@ static int generic_panel_enable(struct o
 {
 	int r = 0;
 
-	if (dssdev->platform_enable)
-		r = dssdev->platform_enable(dssdev);
+	r = generic_panel_power_on(dssdev);
+	if (r)
+		return r;
 
-	return r;
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	return 0;
 }
 
 static void generic_panel_disable(struct omap_dss_device *dssdev)
 {
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
+	generic_panel_power_off(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
 static int generic_panel_suspend(struct omap_dss_device *dssdev)
 {
-	generic_panel_disable(dssdev);
+	generic_panel_power_off(dssdev);
+	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
 	return 0;
 }
 
 static int generic_panel_resume(struct omap_dss_device *dssdev)
 {
-	return generic_panel_enable(dssdev);
+	int r = 0;
+
+	r = generic_panel_power_on(dssdev);
+	if (r)
+		return r;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	return 0;
+}
+
+static void generic_panel_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	dpi_set_timings(dssdev, timings);
+}
+
+static void generic_panel_get_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	*timings = dssdev->panel.timings;
+}
+
+static int generic_panel_check_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	return dpi_check_timings(dssdev, timings);
 }
 
 static struct omap_dss_driver generic_driver = {
@@ -83,6 +143,10 @@ static struct omap_dss_driver generic_dr
 	.suspend	= generic_panel_suspend,
 	.resume		= generic_panel_resume,
 
+	.set_timings	= generic_panel_set_timings,
+	.get_timings	= generic_panel_get_timings,
+	.check_timings	= generic_panel_check_timings,
+
 	.driver         = {
 		.name   = "generic_panel",
 		.owner  = THIS_MODULE,
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,159 @@
+/*
+ * LCD panel driver for Sharp LQ043T1DG01
+ *
+ * Copyright (C) 2009 Texas Instruments Inc
+ * Author: Vaibhav Hiremath <hvaibhav@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+
+#include <plat/display.h>
+
+static struct omap_video_timings sharp_lq_timings = {
+	.x_res = 480,
+	.y_res = 272,
+
+	.pixel_clock	= 9000,
+
+	.hsw		= 42,
+	.hfp		= 3,
+	.hbp		= 2,
+
+	.vsw		= 11,
+	.vfp		= 3,
+	.vbp		= 2,
+};
+
+static int sharp_lq_panel_power_on(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	r = omapdss_dpi_display_enable(dssdev);
+	if (r)
+		goto err0;
+
+	/* wait couple of vsyncs until enabling the LCD */
+	msleep(50);
+
+	if (dssdev->platform_enable) {
+		r = dssdev->platform_enable(dssdev);
+		if (r)
+			goto err1;
+	}
+
+	return 0;
+err1:
+	omapdss_dpi_display_disable(dssdev);
+err0:
+	return r;
+}
+
+static void sharp_lq_panel_power_off(struct omap_dss_device *dssdev)
+{
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
+
+	/* wait at least 5 vsyncs after disabling the LCD */
+	msleep(100);
+
+	omapdss_dpi_display_disable(dssdev);
+}
+
+static int sharp_lq_panel_probe(struct omap_dss_device *dssdev)
+{
+
+	dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+		OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO;
+	dssdev->panel.acb = 0x0;
+	dssdev->panel.timings = sharp_lq_timings;
+
+	return 0;
+}
+
+static void sharp_lq_panel_remove(struct omap_dss_device *dssdev)
+{
+}
+
+static int sharp_lq_panel_enable(struct omap_dss_device *dssdev)
+{
+	int r = 0;
+
+	r = sharp_lq_panel_power_on(dssdev);
+	if (r)
+		return r;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	return 0;
+}
+
+static void sharp_lq_panel_disable(struct omap_dss_device *dssdev)
+{
+	sharp_lq_panel_power_off(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+}
+
+static int sharp_lq_panel_suspend(struct omap_dss_device *dssdev)
+{
+	sharp_lq_panel_power_off(dssdev);
+	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+	return 0;
+}
+
+static int sharp_lq_panel_resume(struct omap_dss_device *dssdev)
+{
+	int r = 0;
+
+	r = sharp_lq_panel_power_on(dssdev);
+	if (r)
+		return r;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	return 0;
+}
+
+static struct omap_dss_driver sharp_lq_driver = {
+	.probe		= sharp_lq_panel_probe,
+	.remove		= sharp_lq_panel_remove,
+
+	.enable		= sharp_lq_panel_enable,
+	.disable	= sharp_lq_panel_disable,
+	.suspend	= sharp_lq_panel_suspend,
+	.resume		= sharp_lq_panel_resume,
+
+	.driver         = {
+		.name   = "sharp_lq_panel",
+		.owner  = THIS_MODULE,
+	},
+};
+
+static int __init sharp_lq_panel_drv_init(void)
+{
+	return omap_dss_register_driver(&sharp_lq_driver);
+}
+
+static void __exit sharp_lq_panel_drv_exit(void)
+{
+	omap_dss_unregister_driver(&sharp_lq_driver);
+}
+
+module_init(sharp_lq_panel_drv_init);
+module_exit(sharp_lq_panel_drv_exit);
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,19 +20,10 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/device.h>
-#include <linux/regulator/consumer.h>
 #include <linux/err.h>
 
 #include <plat/display.h>
 
-struct sharp_data {
-	/* XXX This regulator should actually be in SDP board file, not here,
-	 * as it doesn't actually power the LCD, but something else that
-	 * affects the output to LCD (I think. Somebody clarify). It doesn't do
-	 * harm here, as SDP is the only board using this currently */
-	struct regulator *vdvi_reg;
-};
-
 static struct omap_video_timings sharp_ls_timings = {
 	.x_res = 480,
 	.y_res = 640,
@@ -50,77 +41,81 @@ static struct omap_video_timings sharp_l
 
 static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
 {
-	struct sharp_data *sd;
-
 	dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
 		OMAP_DSS_LCD_IHS;
 	dssdev->panel.acb = 0x28;
 	dssdev->panel.timings = sharp_ls_timings;
 
-	sd = kzalloc(sizeof(*sd), GFP_KERNEL);
-	if (!sd)
-		return -ENOMEM;
-
-	dev_set_drvdata(&dssdev->dev, sd);
-
-	sd->vdvi_reg = regulator_get(&dssdev->dev, "vdvi");
-	if (IS_ERR(sd->vdvi_reg)) {
-		kfree(sd);
-		pr_err("failed to get VDVI regulator\n");
-		return PTR_ERR(sd->vdvi_reg);
-	}
-
 	return 0;
 }
 
 static void sharp_ls_panel_remove(struct omap_dss_device *dssdev)
 {
-	struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
-
-	regulator_put(sd->vdvi_reg);
-
-	kfree(sd);
 }
 
-static int sharp_ls_panel_enable(struct omap_dss_device *dssdev)
+static int sharp_ls_power_on(struct omap_dss_device *dssdev)
 {
-	struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
 	int r = 0;
 
+	r = omapdss_dpi_display_enable(dssdev);
+	if (r)
+		goto err0;
+
 	/* wait couple of vsyncs until enabling the LCD */
 	msleep(50);
 
-	regulator_enable(sd->vdvi_reg);
-
-	if (dssdev->platform_enable)
+	if (dssdev->platform_enable) {
 		r = dssdev->platform_enable(dssdev);
+		if (r)
+			goto err1;
+	}
 
+	return 0;
+err1:
+	omapdss_dpi_display_disable(dssdev);
+err0:
 	return r;
 }
 
-static void sharp_ls_panel_disable(struct omap_dss_device *dssdev)
+static void sharp_ls_power_off(struct omap_dss_device *dssdev)
 {
-	struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
-
 	if (dssdev->platform_disable)
 		dssdev->platform_disable(dssdev);
 
-	regulator_disable(sd->vdvi_reg);
-
 	/* wait at least 5 vsyncs after disabling the LCD */
 
 	msleep(100);
+
+	omapdss_dpi_display_disable(dssdev);
+}
+
+static int sharp_ls_panel_enable(struct omap_dss_device *dssdev)
+{
+	int r;
+	r = sharp_ls_power_on(dssdev);
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+	return r;
+}
+
+static void sharp_ls_panel_disable(struct omap_dss_device *dssdev)
+{
+	sharp_ls_power_off(dssdev);
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
 static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev)
 {
-	sharp_ls_panel_disable(dssdev);
+	sharp_ls_power_off(dssdev);
+	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
 	return 0;
 }
 
 static int sharp_ls_panel_resume(struct omap_dss_device *dssdev)
 {
-	return sharp_ls_panel_enable(dssdev);
+	int r;
+	r = sharp_ls_power_on(dssdev);
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+	return r;
 }
 
 static struct omap_dss_driver sharp_ls_driver = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/panel-taal.c linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/panel-taal.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/panel-taal.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/panel-taal.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/gpio.h>
 #include <linux/completion.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 #include <plat/display.h>
 
@@ -63,6 +64,8 @@
 /* #define TAAL_USE_ESD_CHECK */
 #define TAAL_ESD_CHECK_PERIOD	msecs_to_jiffies(5000)
 
+static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
+
 struct taal_data {
 	struct backlight_device *bldev;
 
@@ -484,6 +487,7 @@ static struct attribute_group taal_attr_
 
 static int taal_probe(struct omap_dss_device *dssdev)
 {
+	struct backlight_properties props;
 	struct taal_data *td;
 	struct backlight_device *bldev;
 	int r;
@@ -510,38 +514,37 @@ static int taal_probe(struct omap_dss_de
 	if (td->esd_wq == NULL) {
 		dev_err(&dssdev->dev, "can't create ESD workqueue\n");
 		r = -ENOMEM;
-		goto err2;
+		goto err1;
 	}
 	INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
 
 	dev_set_drvdata(&dssdev->dev, td);
 
-	dssdev->get_timings = taal_get_timings;
-	dssdev->get_resolution = taal_get_resolution;
-
 	/* if no platform set_backlight() defined, presume DSI backlight
 	 * control */
+	memset(&props, 0, sizeof(struct backlight_properties));
 	if (!dssdev->set_backlight)
 		td->use_dsi_bl = true;
 
+	if (td->use_dsi_bl)
+		props.max_brightness = 255;
+	else
+		props.max_brightness = 127;
 	bldev = backlight_device_register("taal", &dssdev->dev, dssdev,
-			&taal_bl_ops);
+					  &taal_bl_ops, &props);
 	if (IS_ERR(bldev)) {
 		r = PTR_ERR(bldev);
-		goto err1;
+		goto err2;
 	}
 
 	td->bldev = bldev;
 
 	bldev->props.fb_blank = FB_BLANK_UNBLANK;
 	bldev->props.power = FB_BLANK_UNBLANK;
-	if (td->use_dsi_bl) {
-		bldev->props.max_brightness = 255;
+	if (td->use_dsi_bl)
 		bldev->props.brightness = 255;
-	} else {
-		bldev->props.max_brightness = 127;
+	else
 		bldev->props.brightness = 127;
-	}
 
 	taal_bl_update_status(bldev);
 
@@ -621,14 +624,12 @@ static void taal_remove(struct omap_dss_
 	kfree(td);
 }
 
-static int taal_enable(struct omap_dss_device *dssdev)
+static int taal_power_on(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 	u8 id1, id2, id3;
 	int r;
 
-	dev_dbg(&dssdev->dev, "enable\n");
-
 	if (dssdev->platform_enable) {
 		r = dssdev->platform_enable(dssdev);
 		if (r)
@@ -638,6 +639,16 @@ static int taal_enable(struct omap_dss_d
 	/* it seems we have to wait a bit until taal is ready */
 	msleep(5);
 
+	dsi_bus_lock();
+
+	r = omapdss_dsi_display_enable(dssdev);
+	if (r) {
+		dev_err(&dssdev->dev, "failed to enable DSI\n");
+		goto err0;
+	}
+
+	omapdss_dsi_vc_enable_hs(TCH, false);
+
 	r = taal_sleep_out(td);
 	if (r)
 		goto err;
@@ -661,6 +672,10 @@ static int taal_enable(struct omap_dss_d
 
 	taal_dcs_write_0(DCS_DISPLAY_ON);
 
+	r = _taal_enable_te(dssdev, td->te_enabled);
+	if (r)
+		goto err;
+
 #ifdef TAAL_USE_ESD_CHECK
 	queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
 #endif
@@ -676,19 +691,27 @@ static int taal_enable(struct omap_dss_d
 		td->intro_printed = true;
 	}
 
+	omapdss_dsi_vc_enable_hs(TCH, true);
+
+	dsi_bus_unlock();
+
 	return 0;
 err:
+	dsi_bus_unlock();
+
+	omapdss_dsi_display_disable(dssdev);
+err0:
 	if (dssdev->platform_disable)
 		dssdev->platform_disable(dssdev);
 
 	return r;
 }
 
-static void taal_disable(struct omap_dss_device *dssdev)
+static void taal_power_off(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 
-	dev_dbg(&dssdev->dev, "disable\n");
+	dsi_bus_lock();
 
 	cancel_delayed_work(&td->esd_work);
 
@@ -698,41 +721,124 @@ static void taal_disable(struct omap_dss
 	/* wait a bit so that the message goes through */
 	msleep(10);
 
+	omapdss_dsi_display_disable(dssdev);
+
 	if (dssdev->platform_disable)
 		dssdev->platform_disable(dssdev);
 
 	td->enabled = 0;
+
+	dsi_bus_unlock();
+}
+
+static int taal_enable(struct omap_dss_device *dssdev)
+{
+	int r;
+	dev_dbg(&dssdev->dev, "enable\n");
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)
+		return -EINVAL;
+
+	r = taal_power_on(dssdev);
+	if (r)
+		return r;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	return r;
+}
+
+static void taal_disable(struct omap_dss_device *dssdev)
+{
+	dev_dbg(&dssdev->dev, "disable\n");
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+		taal_power_off(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
 static int taal_suspend(struct omap_dss_device *dssdev)
 {
-	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct backlight_device *bldev = td->bldev;
+	dev_dbg(&dssdev->dev, "suspend\n");
 
-	bldev->props.power = FB_BLANK_POWERDOWN;
-	taal_bl_update_status(bldev);
+	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+		return -EINVAL;
+
+	taal_power_off(dssdev);
+	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
 
 	return 0;
 }
 
 static int taal_resume(struct omap_dss_device *dssdev)
 {
+	int r;
+	dev_dbg(&dssdev->dev, "resume\n");
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
+		return -EINVAL;
+
+	r = taal_power_on(dssdev);
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+	return r;
+}
+
+static void taal_framedone_cb(int err, void *data)
+{
+	struct omap_dss_device *dssdev = data;
+	dev_dbg(&dssdev->dev, "framedone, err %d\n", err);
+	dsi_bus_unlock();
+}
+
+static int taal_update(struct omap_dss_device *dssdev,
+				    u16 x, u16 y, u16 w, u16 h)
+{
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct backlight_device *bldev = td->bldev;
+	int r;
 
-	bldev->props.power = FB_BLANK_UNBLANK;
-	taal_bl_update_status(bldev);
+	dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
+
+	dsi_bus_lock();
+
+	if (!td->enabled) {
+		r = 0;
+		goto err;
+	}
+
+	r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h);
+	if (r)
+		goto err;
 
+	r = taal_set_update_window(x, y, w, h);
+	if (r)
+		goto err;
+
+	r = omap_dsi_update(dssdev, TCH, x, y, w, h,
+			taal_framedone_cb, dssdev);
+	if (r)
+		goto err;
+
+	/* note: no bus_unlock here. unlock is in framedone_cb */
 	return 0;
+err:
+	dsi_bus_unlock();
+	return r;
 }
 
-static void taal_setup_update(struct omap_dss_device *dssdev,
-				    u16 x, u16 y, u16 w, u16 h)
+static int taal_sync(struct omap_dss_device *dssdev)
 {
-	taal_set_update_window(x, y, w, h);
+	dev_dbg(&dssdev->dev, "sync\n");
+
+	dsi_bus_lock();
+	dsi_bus_unlock();
+
+	dev_dbg(&dssdev->dev, "sync done\n");
+
+	return 0;
 }
 
-static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
+static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 	int r;
@@ -744,25 +850,32 @@ static int taal_enable_te(struct omap_ds
 	else
 		r = taal_dcs_write_0(DCS_TEAR_OFF);
 
+	omapdss_dsi_enable_te(dssdev, enable);
+
+	/* XXX for some reason, DSI TE breaks if we don't wait here.
+	 * Panel bug? Needs more studying */
+	msleep(100);
+
 	return r;
 }
 
-static int taal_wait_te(struct omap_dss_device *dssdev)
+static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
 {
-	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	long wait = msecs_to_jiffies(500);
+	int r;
 
-	if (!td->use_ext_te || !td->te_enabled)
-		return 0;
+	dsi_bus_lock();
 
-	INIT_COMPLETION(td->te_completion);
-	wait = wait_for_completion_timeout(&td->te_completion, wait);
-	if (wait == 0) {
-		dev_err(&dssdev->dev, "timeout waiting TE\n");
-		return -ETIME;
-	}
+	r = _taal_enable_te(dssdev, enable);
 
-	return 0;
+	dsi_bus_unlock();
+
+	return r;
+}
+
+static int taal_get_te(struct omap_dss_device *dssdev)
+{
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	return td->te_enabled;
 }
 
 static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
@@ -772,16 +885,21 @@ static int taal_rotate(struct omap_dss_d
 
 	dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
 
+	dsi_bus_lock();
+
 	if (td->enabled) {
 		r = taal_set_addr_mode(rotate, td->mirror);
-
 		if (r)
-			return r;
+			goto err;
 	}
 
 	td->rotate = rotate;
 
+	dsi_bus_unlock();
 	return 0;
+err:
+	dsi_bus_unlock();
+	return r;
 }
 
 static u8 taal_get_rotate(struct omap_dss_device *dssdev)
@@ -797,16 +915,20 @@ static int taal_mirror(struct omap_dss_d
 
 	dev_dbg(&dssdev->dev, "mirror %d\n", enable);
 
+	dsi_bus_lock();
 	if (td->enabled) {
 		r = taal_set_addr_mode(td->rotate, enable);
-
 		if (r)
-			return r;
+			goto err;
 	}
 
 	td->mirror = enable;
 
+	dsi_bus_unlock();
 	return 0;
+err:
+	dsi_bus_unlock();
+	return r;
 }
 
 static bool taal_get_mirror(struct omap_dss_device *dssdev)
@@ -820,17 +942,23 @@ static int taal_run_test(struct omap_dss
 	u8 id1, id2, id3;
 	int r;
 
+	dsi_bus_lock();
+
 	r = taal_dcs_read_1(DCS_GET_ID1, &id1);
 	if (r)
-		return r;
+		goto err;
 	r = taal_dcs_read_1(DCS_GET_ID2, &id2);
 	if (r)
-		return r;
+		goto err;
 	r = taal_dcs_read_1(DCS_GET_ID3, &id3);
 	if (r)
-		return r;
+		goto err;
 
+	dsi_bus_unlock();
 	return 0;
+err:
+	dsi_bus_unlock();
+	return r;
 }
 
 static int taal_memory_read(struct omap_dss_device *dssdev,
@@ -841,6 +969,10 @@ static int taal_memory_read(struct omap_
 	int first = 1;
 	int plen;
 	unsigned buf_used = 0;
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+
+	if (!td->enabled)
+		return -ENODEV;
 
 	if (size < w * h * 3)
 		return -ENOMEM;
@@ -849,6 +981,8 @@ static int taal_memory_read(struct omap_
 			dssdev->panel.timings.x_res *
 			dssdev->panel.timings.y_res * 3);
 
+	dsi_bus_lock();
+
 	/* plen 1 or 2 goes into short packet. until checksum error is fixed,
 	 * use short packets. plen 32 works, but bigger packets seem to cause
 	 * an error. */
@@ -857,11 +991,11 @@ static int taal_memory_read(struct omap_
 	else
 		plen = 2;
 
-	taal_setup_update(dssdev, x, y, w, h);
+	taal_set_update_window(x, y, w, h);
 
 	r = dsi_vc_set_max_rx_packet_size(TCH, plen);
 	if (r)
-		return r;
+		goto err0;
 
 	while (buf_used < size) {
 		u8 dcs_cmd = first ? 0x2e : 0x3e;
@@ -894,7 +1028,8 @@ static int taal_memory_read(struct omap_
 
 err:
 	dsi_vc_set_max_rx_packet_size(TCH, 1);
-
+err0:
+	dsi_bus_unlock();
 	return r;
 }
 
@@ -939,8 +1074,11 @@ static void taal_esd_work(struct work_st
 	}
 	/* Self-diagnostics result is also shown on TE GPIO line. We need
 	 * to re-enable TE after self diagnostics */
-	if (td->use_ext_te && td->te_enabled)
-		taal_enable_te(dssdev, true);
+	if (td->use_ext_te && td->te_enabled) {
+		r = taal_dcs_write_1(DCS_TEAR_ON, 0);
+		if (r)
+			goto err;
+	}
 
 	dsi_bus_unlock();
 
@@ -958,6 +1096,20 @@ err:
 	queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
 }
 
+static int taal_set_update_mode(struct omap_dss_device *dssdev,
+		enum omap_dss_update_mode mode)
+{
+	if (mode != OMAP_DSS_UPDATE_MANUAL)
+		return -EINVAL;
+	return 0;
+}
+
+static enum omap_dss_update_mode taal_get_update_mode(
+		struct omap_dss_device *dssdev)
+{
+	return OMAP_DSS_UPDATE_MANUAL;
+}
+
 static struct omap_dss_driver taal_driver = {
 	.probe		= taal_probe,
 	.remove		= taal_remove,
@@ -967,9 +1119,18 @@ static struct omap_dss_driver taal_drive
 	.suspend	= taal_suspend,
 	.resume		= taal_resume,
 
-	.setup_update	= taal_setup_update,
+	.set_update_mode = taal_set_update_mode,
+	.get_update_mode = taal_get_update_mode,
+
+	.update		= taal_update,
+	.sync		= taal_sync,
+
+	.get_resolution	= taal_get_resolution,
+	.get_recommended_bpp = omapdss_default_get_recommended_bpp,
+
 	.enable_te	= taal_enable_te,
-	.wait_for_te	= taal_wait_te,
+	.get_te		= taal_get_te,
+
 	.set_rotate	= taal_rotate,
 	.get_rotate	= taal_get_rotate,
 	.set_mirror	= taal_mirror,
@@ -977,6 +1138,8 @@ static struct omap_dss_driver taal_drive
 	.run_test	= taal_run_test,
 	.memory_read	= taal_memory_read,
 
+	.get_timings	= taal_get_timings,
+
 	.driver         = {
 		.name   = "taal",
 		.owner  = THIS_MODULE,
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/panel-toppoly-tdo35s.c linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/panel-toppoly-tdo35s.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/panel-toppoly-tdo35s.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/panel-toppoly-tdo35s.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,154 @@
+/*
+ * LCD panel driver for Toppoly TDO35S
+ *
+ * Copyright (C) 2009 CompuLab, Ltd.
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * Based on generic panel support
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+
+#include <plat/display.h>
+
+static struct omap_video_timings toppoly_tdo_panel_timings = {
+	/* 640 x 480 @ 60 Hz  Reduced blanking VESA CVT 0.31M3-R */
+	.x_res		= 480,
+	.y_res		= 640,
+
+	.pixel_clock	= 26000,
+
+	.hfp		= 104,
+	.hsw		= 8,
+	.hbp		= 8,
+
+	.vfp		= 4,
+	.vsw		= 2,
+	.vbp		= 2,
+};
+
+static int toppoly_tdo_panel_power_on(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	r = omapdss_dpi_display_enable(dssdev);
+	if (r)
+		goto err0;
+
+	if (dssdev->platform_enable) {
+		r = dssdev->platform_enable(dssdev);
+		if (r)
+			goto err1;
+	}
+
+	return 0;
+err1:
+	omapdss_dpi_display_disable(dssdev);
+err0:
+	return r;
+}
+
+static void toppoly_tdo_panel_power_off(struct omap_dss_device *dssdev)
+{
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
+
+	omapdss_dpi_display_disable(dssdev);
+}
+
+static int toppoly_tdo_panel_probe(struct omap_dss_device *dssdev)
+{
+	dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+		OMAP_DSS_LCD_IHS;
+	dssdev->panel.timings = toppoly_tdo_panel_timings;
+
+	return 0;
+}
+
+static void toppoly_tdo_panel_remove(struct omap_dss_device *dssdev)
+{
+}
+
+static int toppoly_tdo_panel_enable(struct omap_dss_device *dssdev)
+{
+	int r = 0;
+
+	r = toppoly_tdo_panel_power_on(dssdev);
+	if (r)
+		return r;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	return 0;
+}
+
+static void toppoly_tdo_panel_disable(struct omap_dss_device *dssdev)
+{
+	toppoly_tdo_panel_power_off(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+}
+
+static int toppoly_tdo_panel_suspend(struct omap_dss_device *dssdev)
+{
+	toppoly_tdo_panel_power_off(dssdev);
+	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+	return 0;
+}
+
+static int toppoly_tdo_panel_resume(struct omap_dss_device *dssdev)
+{
+	int r = 0;
+
+	r = toppoly_tdo_panel_power_on(dssdev);
+	if (r)
+		return r;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	return 0;
+}
+
+static struct omap_dss_driver generic_driver = {
+	.probe		= toppoly_tdo_panel_probe,
+	.remove		= toppoly_tdo_panel_remove,
+
+	.enable		= toppoly_tdo_panel_enable,
+	.disable	= toppoly_tdo_panel_disable,
+	.suspend	= toppoly_tdo_panel_suspend,
+	.resume		= toppoly_tdo_panel_resume,
+
+	.driver         = {
+		.name   = "toppoly_tdo35s_panel",
+		.owner  = THIS_MODULE,
+	},
+};
+
+static int __init toppoly_tdo_panel_drv_init(void)
+{
+	return omap_dss_register_driver(&generic_driver);
+}
+
+static void __exit toppoly_tdo_panel_drv_exit(void)
+{
+	omap_dss_unregister_driver(&generic_driver);
+}
+
+module_init(toppoly_tdo_panel_drv_init);
+module_exit(toppoly_tdo_panel_drv_exit);
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/panel-tpo-td043mtea1.c linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/displays/panel-tpo-td043mtea1.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/displays/panel-tpo-td043mtea1.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,529 @@
+/*
+ * LCD panel driver for TPO TD043MTEA1
+ *
+ * Author: GraÅ¾vydas Ignotas <notasas@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/module.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/consumer.h>
+#include <linux/gpio.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include <plat/display.h>
+
+#define TPO_R02_MODE(x)		((x) & 7)
+#define TPO_R02_MODE_800x480	7
+#define TPO_R02_NCLK_RISING	BIT(3)
+#define TPO_R02_HSYNC_HIGH	BIT(4)
+#define TPO_R02_VSYNC_HIGH	BIT(5)
+
+#define TPO_R03_NSTANDBY	BIT(0)
+#define TPO_R03_EN_CP_CLK	BIT(1)
+#define TPO_R03_EN_VGL_PUMP	BIT(2)
+#define TPO_R03_EN_PWM		BIT(3)
+#define TPO_R03_DRIVING_CAP_100	BIT(4)
+#define TPO_R03_EN_PRE_CHARGE	BIT(6)
+#define TPO_R03_SOFTWARE_CTL	BIT(7)
+
+#define TPO_R04_NFLIP_H		BIT(0)
+#define TPO_R04_NFLIP_V		BIT(1)
+#define TPO_R04_CP_CLK_FREQ_1H	BIT(2)
+#define TPO_R04_VGL_FREQ_1H	BIT(4)
+
+#define TPO_R03_VAL_NORMAL (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | \
+			TPO_R03_EN_VGL_PUMP |  TPO_R03_EN_PWM | \
+			TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \
+			TPO_R03_SOFTWARE_CTL)
+
+#define TPO_R03_VAL_STANDBY (TPO_R03_DRIVING_CAP_100 | \
+			TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL)
+
+static const u16 tpo_td043_def_gamma[12] = {
+	106, 200, 289, 375, 460, 543, 625, 705, 785, 864, 942, 1020
+};
+
+struct tpo_td043_device {
+	struct spi_device *spi;
+	struct regulator *vcc_reg;
+	u16 gamma[12];
+	u32 mode;
+	u32 hmirror:1;
+	u32 vmirror:1;
+};
+
+static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data)
+{
+	struct spi_message	m;
+	struct spi_transfer	xfer;
+	u16			w;
+	int			r;
+
+	spi_message_init(&m);
+
+	memset(&xfer, 0, sizeof(xfer));
+
+	w = ((u16)addr << 10) | (1 << 8) | data;
+	xfer.tx_buf = &w;
+	xfer.bits_per_word = 16;
+	xfer.len = 2;
+	spi_message_add_tail(&xfer, &m);
+
+	r = spi_sync(spi, &m);
+	if (r < 0)
+		dev_warn(&spi->dev, "failed to write to LCD reg (%d)\n", r);
+	return r;
+}
+
+static void tpo_td043_write_gamma(struct spi_device *spi, u16 gamma[12])
+{
+	u8 i, val;
+
+	/* gamma bits [9:8] */
+	for (val = i = 0; i < 4; i++)
+		val |= (gamma[i] & 0x300) >> ((i + 1) * 2);
+	tpo_td043_write(spi, 0x11, val);
+
+	for (val = i = 0; i < 4; i++)
+		val |= (gamma[i+4] & 0x300) >> ((i + 1) * 2);
+	tpo_td043_write(spi, 0x12, val);
+
+	for (val = i = 0; i < 4; i++)
+		val |= (gamma[i+8] & 0x300) >> ((i + 1) * 2);
+	tpo_td043_write(spi, 0x13, val);
+
+	/* gamma bits [7:0] */
+	for (val = i = 0; i < 12; i++)
+		tpo_td043_write(spi, 0x14 + i, gamma[i] & 0xff);
+}
+
+static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v)
+{
+	u8 reg4 = TPO_R04_NFLIP_H | TPO_R04_NFLIP_V | \
+		TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H;
+	if (h)
+		reg4 &= ~TPO_R04_NFLIP_H;
+	if (v)
+		reg4 &= ~TPO_R04_NFLIP_V;
+
+	return tpo_td043_write(spi, 4, reg4);
+}
+
+static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable)
+{
+	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
+
+	tpo_td043->hmirror = enable;
+	return tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror,
+			tpo_td043->vmirror);
+}
+
+static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev)
+{
+	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
+
+	return tpo_td043->hmirror;
+}
+
+static ssize_t tpo_td043_vmirror_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->vmirror);
+}
+
+static ssize_t tpo_td043_vmirror_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
+	long val;
+	int ret;
+
+	ret = strict_strtol(buf, 0, &val);
+	if (ret < 0)
+		return ret;
+
+	ret = tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, val);
+	if (ret < 0)
+		return ret;
+
+	tpo_td043->vmirror = val;
+
+	return count;
+}
+
+static ssize_t tpo_td043_mode_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->mode);
+}
+
+static ssize_t tpo_td043_mode_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
+	long val;
+	int ret;
+
+	ret = strict_strtol(buf, 0, &val);
+	if (ret != 0 || val & ~7)
+		return -EINVAL;
+
+	tpo_td043->mode = val;
+
+	val |= TPO_R02_NCLK_RISING;
+	tpo_td043_write(tpo_td043->spi, 2, val);
+
+	return count;
+}
+
+static ssize_t tpo_td043_gamma_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
+	ssize_t len = 0;
+	int ret;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(tpo_td043->gamma); i++) {
+		ret = snprintf(buf + len, PAGE_SIZE - len, "%u ",
+				tpo_td043->gamma[i]);
+		if (ret < 0)
+			return ret;
+		len += ret;
+	}
+	buf[len - 1] = '\n';
+
+	return len;
+}
+
+static ssize_t tpo_td043_gamma_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
+	unsigned int g[12];
+	int ret;
+	int i;
+
+	ret = sscanf(buf, "%u %u %u %u %u %u %u %u %u %u %u %u",
+			&g[0], &g[1], &g[2], &g[3], &g[4], &g[5],
+			&g[6], &g[7], &g[8], &g[9], &g[10], &g[11]);
+
+	if (ret != 12)
+		return -EINVAL;
+
+	for (i = 0; i < 12; i++)
+		tpo_td043->gamma[i] = g[i];
+
+	tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);
+
+	return count;
+}
+
+static DEVICE_ATTR(vmirror, S_IRUGO | S_IWUSR,
+		tpo_td043_vmirror_show, tpo_td043_vmirror_store);
+static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
+		tpo_td043_mode_show, tpo_td043_mode_store);
+static DEVICE_ATTR(gamma, S_IRUGO | S_IWUSR,
+		tpo_td043_gamma_show, tpo_td043_gamma_store);
+
+static struct attribute *tpo_td043_attrs[] = {
+	&dev_attr_vmirror.attr,
+	&dev_attr_mode.attr,
+	&dev_attr_gamma.attr,
+	NULL,
+};
+
+static struct attribute_group tpo_td043_attr_group = {
+	.attrs = tpo_td043_attrs,
+};
+
+static const struct omap_video_timings tpo_td043_timings = {
+	.x_res		= 800,
+	.y_res		= 480,
+
+	.pixel_clock	= 36000,
+
+	.hsw		= 1,
+	.hfp		= 68,
+	.hbp		= 214,
+
+	.vsw		= 1,
+	.vfp		= 39,
+	.vbp		= 34,
+};
+
+static int tpo_td043_power_on(struct omap_dss_device *dssdev)
+{
+	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
+	int nreset_gpio = dssdev->reset_gpio;
+	int r;
+
+	r = omapdss_dpi_display_enable(dssdev);
+	if (r)
+		goto err0;
+
+	if (dssdev->platform_enable) {
+		r = dssdev->platform_enable(dssdev);
+		if (r)
+			goto err1;
+	}
+
+	regulator_enable(tpo_td043->vcc_reg);
+
+	/* wait for power up */
+	msleep(160);
+
+	if (gpio_is_valid(nreset_gpio))
+		gpio_set_value(nreset_gpio, 1);
+
+	tpo_td043_write(tpo_td043->spi, 2,
+			TPO_R02_MODE(tpo_td043->mode) | TPO_R02_NCLK_RISING);
+	tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_NORMAL);
+	tpo_td043_write(tpo_td043->spi, 0x20, 0xf0);
+	tpo_td043_write(tpo_td043->spi, 0x21, 0xf0);
+	tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror,
+			tpo_td043->vmirror);
+	tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);
+
+	return 0;
+err1:
+	omapdss_dpi_display_disable(dssdev);
+err0:
+	return r;
+}
+
+static void tpo_td043_power_off(struct omap_dss_device *dssdev)
+{
+	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
+	int nreset_gpio = dssdev->reset_gpio;
+
+	tpo_td043_write(tpo_td043->spi, 3,
+			TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM);
+
+	if (gpio_is_valid(nreset_gpio))
+		gpio_set_value(nreset_gpio, 0);
+
+	/* wait for at least 2 vsyncs before cutting off power */
+	msleep(50);
+
+	tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_STANDBY);
+
+	regulator_disable(tpo_td043->vcc_reg);
+
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
+
+	omapdss_dpi_display_disable(dssdev);
+}
+
+static int tpo_td043_enable(struct omap_dss_device *dssdev)
+{
+	int ret;
+
+	dev_dbg(&dssdev->dev, "enable\n");
+
+	ret = tpo_td043_power_on(dssdev);
+	if (ret)
+		return ret;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	return 0;
+}
+
+static void tpo_td043_disable(struct omap_dss_device *dssdev)
+{
+	dev_dbg(&dssdev->dev, "disable\n");
+
+	tpo_td043_power_off(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+}
+
+static int tpo_td043_suspend(struct omap_dss_device *dssdev)
+{
+	tpo_td043_power_off(dssdev);
+	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+	return 0;
+}
+
+static int tpo_td043_resume(struct omap_dss_device *dssdev)
+{
+	int r = 0;
+
+	r = tpo_td043_power_on(dssdev);
+	if (r)
+		return r;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	return 0;
+}
+
+static int tpo_td043_probe(struct omap_dss_device *dssdev)
+{
+	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
+	int nreset_gpio = dssdev->reset_gpio;
+	int ret = 0;
+
+	dev_dbg(&dssdev->dev, "probe\n");
+
+	if (tpo_td043 == NULL) {
+		dev_err(&dssdev->dev, "missing tpo_td043_device\n");
+		return -ENODEV;
+	}
+
+	dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IHS |
+				OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IPC;
+	dssdev->panel.timings = tpo_td043_timings;
+	dssdev->ctrl.pixel_size = 24;
+
+	tpo_td043->mode = TPO_R02_MODE_800x480;
+	memcpy(tpo_td043->gamma, tpo_td043_def_gamma, sizeof(tpo_td043->gamma));
+
+	tpo_td043->vcc_reg = regulator_get(&dssdev->dev, "vcc");
+	if (IS_ERR(tpo_td043->vcc_reg)) {
+		dev_err(&dssdev->dev, "failed to get LCD VCC regulator\n");
+		ret = PTR_ERR(tpo_td043->vcc_reg);
+		goto fail_regulator;
+	}
+
+	if (gpio_is_valid(nreset_gpio)) {
+		ret = gpio_request(nreset_gpio, "lcd reset");
+		if (ret < 0) {
+			dev_err(&dssdev->dev, "couldn't request reset GPIO\n");
+			goto fail_gpio_req;
+		}
+
+		ret = gpio_direction_output(nreset_gpio, 0);
+		if (ret < 0) {
+			dev_err(&dssdev->dev, "couldn't set GPIO direction\n");
+			goto fail_gpio_direction;
+		}
+	}
+
+	ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
+	if (ret)
+		dev_warn(&dssdev->dev, "failed to create sysfs files\n");
+
+	return 0;
+
+fail_gpio_direction:
+	gpio_free(nreset_gpio);
+fail_gpio_req:
+	regulator_put(tpo_td043->vcc_reg);
+fail_regulator:
+	kfree(tpo_td043);
+	return ret;
+}
+
+static void tpo_td043_remove(struct omap_dss_device *dssdev)
+{
+	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
+	int nreset_gpio = dssdev->reset_gpio;
+
+	dev_dbg(&dssdev->dev, "remove\n");
+
+	sysfs_remove_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
+	regulator_put(tpo_td043->vcc_reg);
+	if (gpio_is_valid(nreset_gpio))
+		gpio_free(nreset_gpio);
+}
+
+static struct omap_dss_driver tpo_td043_driver = {
+	.probe		= tpo_td043_probe,
+	.remove		= tpo_td043_remove,
+
+	.enable		= tpo_td043_enable,
+	.disable	= tpo_td043_disable,
+	.suspend	= tpo_td043_suspend,
+	.resume		= tpo_td043_resume,
+	.set_mirror	= tpo_td043_set_hmirror,
+	.get_mirror	= tpo_td043_get_hmirror,
+
+	.driver         = {
+		.name	= "tpo_td043mtea1_panel",
+		.owner  = THIS_MODULE,
+	},
+};
+
+static int tpo_td043_spi_probe(struct spi_device *spi)
+{
+	struct omap_dss_device *dssdev = spi->dev.platform_data;
+	struct tpo_td043_device *tpo_td043;
+	int ret;
+
+	if (dssdev == NULL) {
+		dev_err(&spi->dev, "missing dssdev\n");
+		return -ENODEV;
+	}
+
+	spi->bits_per_word = 16;
+	spi->mode = SPI_MODE_0;
+
+	ret = spi_setup(spi);
+	if (ret < 0) {
+		dev_err(&spi->dev, "spi_setup failed: %d\n", ret);
+		return ret;
+	}
+
+	tpo_td043 = kzalloc(sizeof(*tpo_td043), GFP_KERNEL);
+	if (tpo_td043 == NULL)
+		return -ENOMEM;
+
+	tpo_td043->spi = spi;
+	dev_set_drvdata(&spi->dev, tpo_td043);
+	dev_set_drvdata(&dssdev->dev, tpo_td043);
+
+	omap_dss_register_driver(&tpo_td043_driver);
+
+	return 0;
+}
+
+static int __devexit tpo_td043_spi_remove(struct spi_device *spi)
+{
+	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&spi->dev);
+
+	omap_dss_unregister_driver(&tpo_td043_driver);
+	kfree(tpo_td043);
+
+	return 0;
+}
+
+static struct spi_driver tpo_td043_spi_driver = {
+	.driver = {
+		.name	= "tpo_td043mtea1_panel_spi",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe	= tpo_td043_spi_probe,
+	.remove	= __devexit_p(tpo_td043_spi_remove),
+};
+
+static int __init tpo_td043_init(void)
+{
+	return spi_register_driver(&tpo_td043_spi_driver);
+}
+
+static void __exit tpo_td043_exit(void)
+{
+	spi_unregister_driver(&tpo_td043_spi_driver);
+}
+
+module_init(tpo_td043_init);
+module_exit(tpo_td043_exit);
+
+MODULE_AUTHOR("GraÅ¾vydas Ignotas <notasas@gmail.com>");
+MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/core.c linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/core.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/core.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/core.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/debugfs.h>
 #include <linux/io.h>
 #include <linux/device.h>
+#include <linux/regulator/consumer.h>
 
 #include <plat/display.h>
 #include <plat/clock.h>
@@ -47,6 +48,10 @@ static struct {
 	struct clk      *dss_54m_fck;
 	struct clk	*dss_96m_fck;
 	unsigned	num_clks_enabled;
+
+	struct regulator *vdds_dsi_reg;
+	struct regulator *vdds_sdi_reg;
+	struct regulator *vdda_dac_reg;
 } core;
 
 static void dss_clk_enable_all_no_ctx(void);
@@ -284,9 +289,11 @@ static void dss_clk_enable_no_ctx(enum d
 
 void dss_clk_enable(enum dss_clock clks)
 {
+	bool check_ctx = core.num_clks_enabled == 0;
+
 	dss_clk_enable_no_ctx(clks);
 
-	if (cpu_is_omap34xx() && dss_need_ctx_restore())
+	if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
 		restore_all_ctx();
 }
 
@@ -352,6 +359,50 @@ static void dss_clk_disable_all(void)
 	dss_clk_disable(clks);
 }
 
+/* REGULATORS */
+
+struct regulator *dss_get_vdds_dsi(void)
+{
+	struct regulator *reg;
+
+	if (core.vdds_dsi_reg != NULL)
+		return core.vdds_dsi_reg;
+
+	reg = regulator_get(&core.pdev->dev, "vdds_dsi");
+	if (!IS_ERR(reg))
+		core.vdds_dsi_reg = reg;
+
+	return reg;
+}
+
+struct regulator *dss_get_vdds_sdi(void)
+{
+	struct regulator *reg;
+
+	if (core.vdds_sdi_reg != NULL)
+		return core.vdds_sdi_reg;
+
+	reg = regulator_get(&core.pdev->dev, "vdds_sdi");
+	if (!IS_ERR(reg))
+		core.vdds_sdi_reg = reg;
+
+	return reg;
+}
+
+struct regulator *dss_get_vdda_dac(void)
+{
+	struct regulator *reg;
+
+	if (core.vdda_dac_reg != NULL)
+		return core.vdda_dac_reg;
+
+	reg = regulator_get(&core.pdev->dev, "vdda_dac");
+	if (!IS_ERR(reg))
+		core.vdda_dac_reg = reg;
+
+	return reg;
+}
+
 /* DEBUGFS */
 #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
 static void dss_debug_dump_clocks(struct seq_file *s)
@@ -397,10 +448,12 @@ static int dss_initialize_debugfs(void)
 	debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
 			&dss_debug_dump_clocks, &dss_debug_fops);
 
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 	debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir,
 			&dispc_dump_irqs, &dss_debug_fops);
+#endif
 
-#ifdef CONFIG_OMAP2_DSS_DSI
+#if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS)
 	debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir,
 			&dsi_dump_irqs, &dss_debug_fops);
 #endif
@@ -473,7 +526,7 @@ static int omap_dss_probe(struct platfor
 	}
 #endif
 
-	r = dpi_init();
+	r = dpi_init(pdev);
 	if (r) {
 		DSSERR("Failed to initialize dpi\n");
 		goto fail0;
@@ -718,16 +771,14 @@ static int dss_driver_probe(struct devic
 
 	dss_init_device(core.pdev, dssdev);
 
-	/* skip this if the device is behind a ctrl */
-	if (!dssdev->panel.ctrl) {
-		force = pdata->default_device == dssdev;
-		dss_recheck_connections(dssdev, force);
-	}
+	force = pdata->default_device == dssdev;
+	dss_recheck_connections(dssdev, force);
 
 	r = dssdrv->probe(dssdev);
 
 	if (r) {
 		DSSERR("driver probe failed: %d\n", r);
+		dss_uninit_device(core.pdev, dssdev);
 		return r;
 	}
 
@@ -760,6 +811,13 @@ int omap_dss_register_driver(struct omap
 	dssdriver->driver.bus = &dss_bus_type;
 	dssdriver->driver.probe = dss_driver_probe;
 	dssdriver->driver.remove = dss_driver_remove;
+
+	if (dssdriver->get_resolution == NULL)
+		dssdriver->get_resolution = omapdss_default_get_resolution;
+	if (dssdriver->get_recommended_bpp == NULL)
+		dssdriver->get_recommended_bpp =
+			omapdss_default_get_recommended_bpp;
+
 	return driver_register(&dssdriver->driver);
 }
 EXPORT_SYMBOL(omap_dss_register_driver);
@@ -808,8 +866,6 @@ static void omap_dss_dev_release(struct
 int omap_dss_register_device(struct omap_dss_device *dssdev)
 {
 	static int dev_num;
-	static int panel_num;
-	int r;
 
 	WARN_ON(!dssdev->driver_name);
 
@@ -818,36 +874,12 @@ int omap_dss_register_device(struct omap
 	dssdev->dev.parent = &dss_bus;
 	dssdev->dev.release = omap_dss_dev_release;
 	dev_set_name(&dssdev->dev, "display%d", dev_num++);
-	r = device_register(&dssdev->dev);
-	if (r)
-		return r;
-
-	if (dssdev->ctrl.panel) {
-		struct omap_dss_device *panel = dssdev->ctrl.panel;
-
-		panel->panel.ctrl = dssdev;
-
-		reset_device(&panel->dev, 1);
-		panel->dev.bus = &dss_bus_type;
-		panel->dev.parent = &dssdev->dev;
-		panel->dev.release = omap_dss_dev_release;
-		dev_set_name(&panel->dev, "panel%d", panel_num++);
-		r = device_register(&panel->dev);
-		if (r)
-			return r;
-	}
-
-	return 0;
+	return device_register(&dssdev->dev);
 }
 
 void omap_dss_unregister_device(struct omap_dss_device *dssdev)
 {
 	device_unregister(&dssdev->dev);
-
-	if (dssdev->ctrl.panel) {
-		struct omap_dss_device *panel = dssdev->ctrl.panel;
-		device_unregister(&panel->dev);
-	}
 }
 
 /* BUS */
@@ -901,6 +933,21 @@ static int __init omap_dss_init(void)
 
 static void __exit omap_dss_exit(void)
 {
+	if (core.vdds_dsi_reg != NULL) {
+		regulator_put(core.vdds_dsi_reg);
+		core.vdds_dsi_reg = NULL;
+	}
+
+	if (core.vdds_sdi_reg != NULL) {
+		regulator_put(core.vdds_sdi_reg);
+		core.vdds_sdi_reg = NULL;
+	}
+
+	if (core.vdda_dac_reg != NULL) {
+		regulator_put(core.vdda_dac_reg);
+		core.vdda_dac_reg = NULL;
+	}
+
 	platform_driver_unregister(&omap_dss_driver);
 
 	omap_dss_bus_unregister();
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/dispc.c linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/dispc.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/dispc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/dispc.c	2010-05-16 17:17:36.000000000 -0400
@@ -1725,7 +1725,7 @@ static void _enable_lcd_out(bool enable)
 	REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
 }
 
-void dispc_enable_lcd_out(bool enable)
+static void dispc_enable_lcd_out(bool enable)
 {
 	struct completion frame_done_completion;
 	bool is_on;
@@ -1772,7 +1772,7 @@ static void _enable_digit_out(bool enabl
 	REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
 }
 
-void dispc_enable_digit_out(bool enable)
+static void dispc_enable_digit_out(bool enable)
 {
 	struct completion frame_done_completion;
 	int r;
@@ -1836,6 +1836,26 @@ void dispc_enable_digit_out(bool enable)
 	enable_clocks(0);
 }
 
+bool dispc_is_channel_enabled(enum omap_channel channel)
+{
+	if (channel == OMAP_DSS_CHANNEL_LCD)
+		return !!REG_GET(DISPC_CONTROL, 0, 0);
+	else if (channel == OMAP_DSS_CHANNEL_DIGIT)
+		return !!REG_GET(DISPC_CONTROL, 1, 1);
+	else
+		BUG();
+}
+
+void dispc_enable_channel(enum omap_channel channel, bool enable)
+{
+	if (channel == OMAP_DSS_CHANNEL_LCD)
+		dispc_enable_lcd_out(enable);
+	else if (channel == OMAP_DSS_CHANNEL_DIGIT)
+		dispc_enable_digit_out(enable);
+	else
+		BUG();
+}
+
 void dispc_lcd_enable_signal_polarity(bool act_high)
 {
 	enable_clocks(1);
@@ -2198,7 +2218,7 @@ unsigned long dispc_fclk_rate(void)
 {
 	unsigned long r = 0;
 
-	if (dss_get_dispc_clk_source() == 0)
+	if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK)
 		r = dss_clk_get_rate(DSS_CLK_FCK1);
 	else
 #ifdef CONFIG_OMAP2_DSS_DSI
@@ -2251,7 +2271,7 @@ void dispc_dump_clocks(struct seq_file *
 	seq_printf(s, "- DISPC -\n");
 
 	seq_printf(s, "dispc fclk source = %s\n",
-			dss_get_dispc_clk_source() == 0 ?
+			dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
 			"dss1_alwon_fclk" : "dsi1_pll_fclk");
 
 	seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
@@ -2301,8 +2321,6 @@ void dispc_dump_irqs(struct seq_file *s)
 	PIS(WAKEUP);
 #undef PIS
 }
-#else
-void dispc_dump_irqs(struct seq_file *s) { }
 #endif
 
 void dispc_dump_regs(struct seq_file *s)
@@ -2854,12 +2872,13 @@ static void dispc_error_worker(struct wo
 				manager = mgr;
 				enable = mgr->device->state ==
 						OMAP_DSS_DISPLAY_ACTIVE;
-				mgr->device->disable(mgr->device);
+				mgr->device->driver->disable(mgr->device);
 				break;
 			}
 		}
 
 		if (manager) {
+			struct omap_dss_device *dssdev = manager->device;
 			for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
 				struct omap_overlay *ovl;
 				ovl = omap_dss_get_overlay(i);
@@ -2874,7 +2893,7 @@ static void dispc_error_worker(struct wo
 			dispc_go(manager->id);
 			mdelay(50);
 			if (enable)
-				manager->device->enable(manager->device);
+				dssdev->driver->enable(dssdev);
 		}
 	}
 
@@ -2892,12 +2911,13 @@ static void dispc_error_worker(struct wo
 				manager = mgr;
 				enable = mgr->device->state ==
 						OMAP_DSS_DISPLAY_ACTIVE;
-				mgr->device->disable(mgr->device);
+				mgr->device->driver->disable(mgr->device);
 				break;
 			}
 		}
 
 		if (manager) {
+			struct omap_dss_device *dssdev = manager->device;
 			for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
 				struct omap_overlay *ovl;
 				ovl = omap_dss_get_overlay(i);
@@ -2912,7 +2932,7 @@ static void dispc_error_worker(struct wo
 			dispc_go(manager->id);
 			mdelay(50);
 			if (enable)
-				manager->device->enable(manager->device);
+				dssdev->driver->enable(dssdev);
 		}
 	}
 
@@ -2923,7 +2943,7 @@ static void dispc_error_worker(struct wo
 			mgr = omap_dss_get_overlay_manager(i);
 
 			if (mgr->caps & OMAP_DSS_OVL_CAP_DISPC)
-				mgr->device->disable(mgr->device);
+				mgr->device->driver->disable(mgr->device);
 		}
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/display.c linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/display.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/display.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/display.c	2010-05-16 17:17:36.000000000 -0400
@@ -53,11 +53,11 @@ static ssize_t display_enabled_store(str
 
 	if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
 		if (enabled) {
-			r = dssdev->enable(dssdev);
+			r = dssdev->driver->enable(dssdev);
 			if (r)
 				return r;
 		} else {
-			dssdev->disable(dssdev);
+			dssdev->driver->disable(dssdev);
 		}
 	}
 
@@ -69,8 +69,8 @@ static ssize_t display_upd_mode_show(str
 {
 	struct omap_dss_device *dssdev = to_dss_device(dev);
 	enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO;
-	if (dssdev->get_update_mode)
-		mode = dssdev->get_update_mode(dssdev);
+	if (dssdev->driver->get_update_mode)
+		mode = dssdev->driver->get_update_mode(dssdev);
 	return snprintf(buf, PAGE_SIZE, "%d\n", mode);
 }
 
@@ -94,7 +94,7 @@ static ssize_t display_upd_mode_store(st
 		return -EINVAL;
 	}
 
-	r = dssdev->set_update_mode(dssdev, mode);
+	r = dssdev->driver->set_update_mode(dssdev, mode);
 	if (r)
 		return r;
 
@@ -106,7 +106,8 @@ static ssize_t display_tear_show(struct
 {
 	struct omap_dss_device *dssdev = to_dss_device(dev);
 	return snprintf(buf, PAGE_SIZE, "%d\n",
-			dssdev->get_te ? dssdev->get_te(dssdev) : 0);
+			dssdev->driver->get_te ?
+			dssdev->driver->get_te(dssdev) : 0);
 }
 
 static ssize_t display_tear_store(struct device *dev,
@@ -116,12 +117,12 @@ static ssize_t display_tear_store(struct
 	unsigned long te;
 	int r;
 
-	if (!dssdev->enable_te || !dssdev->get_te)
+	if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
 		return -ENOENT;
 
 	te = simple_strtoul(buf, NULL, 0);
 
-	r = dssdev->enable_te(dssdev, te);
+	r = dssdev->driver->enable_te(dssdev, te);
 	if (r)
 		return r;
 
@@ -134,10 +135,10 @@ static ssize_t display_timings_show(stru
 	struct omap_dss_device *dssdev = to_dss_device(dev);
 	struct omap_video_timings t;
 
-	if (!dssdev->get_timings)
+	if (!dssdev->driver->get_timings)
 		return -ENOENT;
 
-	dssdev->get_timings(dssdev, &t);
+	dssdev->driver->get_timings(dssdev, &t);
 
 	return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
 			t.pixel_clock,
@@ -152,7 +153,7 @@ static ssize_t display_timings_store(str
 	struct omap_video_timings t;
 	int r, found;
 
-	if (!dssdev->set_timings || !dssdev->check_timings)
+	if (!dssdev->driver->set_timings || !dssdev->driver->check_timings)
 		return -ENOENT;
 
 	found = 0;
@@ -171,11 +172,11 @@ static ssize_t display_timings_store(str
 				&t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
 		return -EINVAL;
 
-	r = dssdev->check_timings(dssdev, &t);
+	r = dssdev->driver->check_timings(dssdev, &t);
 	if (r)
 		return r;
 
-	dssdev->set_timings(dssdev, &t);
+	dssdev->driver->set_timings(dssdev, &t);
 
 	return size;
 }
@@ -185,9 +186,9 @@ static ssize_t display_rotate_show(struc
 {
 	struct omap_dss_device *dssdev = to_dss_device(dev);
 	int rotate;
-	if (!dssdev->get_rotate)
+	if (!dssdev->driver->get_rotate)
 		return -ENOENT;
-	rotate = dssdev->get_rotate(dssdev);
+	rotate = dssdev->driver->get_rotate(dssdev);
 	return snprintf(buf, PAGE_SIZE, "%u\n", rotate);
 }
 
@@ -198,12 +199,12 @@ static ssize_t display_rotate_store(stru
 	unsigned long rot;
 	int r;
 
-	if (!dssdev->set_rotate || !dssdev->get_rotate)
+	if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
 		return -ENOENT;
 
 	rot = simple_strtoul(buf, NULL, 0);
 
-	r = dssdev->set_rotate(dssdev, rot);
+	r = dssdev->driver->set_rotate(dssdev, rot);
 	if (r)
 		return r;
 
@@ -215,9 +216,9 @@ static ssize_t display_mirror_show(struc
 {
 	struct omap_dss_device *dssdev = to_dss_device(dev);
 	int mirror;
-	if (!dssdev->get_mirror)
+	if (!dssdev->driver->get_mirror)
 		return -ENOENT;
-	mirror = dssdev->get_mirror(dssdev);
+	mirror = dssdev->driver->get_mirror(dssdev);
 	return snprintf(buf, PAGE_SIZE, "%u\n", mirror);
 }
 
@@ -228,12 +229,12 @@ static ssize_t display_mirror_store(stru
 	unsigned long mirror;
 	int r;
 
-	if (!dssdev->set_mirror || !dssdev->get_mirror)
+	if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
 		return -ENOENT;
 
 	mirror = simple_strtoul(buf, NULL, 0);
 
-	r = dssdev->set_mirror(dssdev, mirror);
+	r = dssdev->driver->set_mirror(dssdev, mirror);
 	if (r)
 		return r;
 
@@ -246,10 +247,10 @@ static ssize_t display_wss_show(struct d
 	struct omap_dss_device *dssdev = to_dss_device(dev);
 	unsigned int wss;
 
-	if (!dssdev->get_wss)
+	if (!dssdev->driver->get_wss)
 		return -ENOENT;
 
-	wss = dssdev->get_wss(dssdev);
+	wss = dssdev->driver->get_wss(dssdev);
 
 	return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss);
 }
@@ -261,7 +262,7 @@ static ssize_t display_wss_store(struct
 	unsigned long wss;
 	int r;
 
-	if (!dssdev->get_wss || !dssdev->set_wss)
+	if (!dssdev->driver->get_wss || !dssdev->driver->set_wss)
 		return -ENOENT;
 
 	if (strict_strtoul(buf, 0, &wss))
@@ -270,7 +271,7 @@ static ssize_t display_wss_store(struct
 	if (wss > 0xfffff)
 		return -EINVAL;
 
-	r = dssdev->set_wss(dssdev, wss);
+	r = dssdev->driver->set_wss(dssdev, wss);
 	if (r)
 		return r;
 
@@ -303,12 +304,13 @@ static struct device_attribute *display_
 	NULL
 };
 
-static void default_get_resolution(struct omap_dss_device *dssdev,
+void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
 			u16 *xres, u16 *yres)
 {
 	*xres = dssdev->panel.timings.x_res;
 	*yres = dssdev->panel.timings.y_res;
 }
+EXPORT_SYMBOL(omapdss_default_get_resolution);
 
 void default_get_overlay_fifo_thresholds(enum omap_plane plane,
 		u32 fifo_size, enum omap_burst_size *burst_size,
@@ -323,24 +325,8 @@ void default_get_overlay_fifo_thresholds
 	*fifo_low = fifo_size - burst_size_bytes;
 }
 
-static int default_wait_vsync(struct omap_dss_device *dssdev)
-{
-	unsigned long timeout = msecs_to_jiffies(500);
-	u32 irq;
-
-	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
-		irq = DISPC_IRQ_EVSYNC_ODD;
-	else
-		irq = DISPC_IRQ_VSYNC;
-
-	return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
-}
-
-static int default_get_recommended_bpp(struct omap_dss_device *dssdev)
+int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
 {
-	if (dssdev->panel.recommended_bpp)
-		return dssdev->panel.recommended_bpp;
-
 	switch (dssdev->type) {
 	case OMAP_DISPLAY_TYPE_DPI:
 		if (dssdev->phy.dpi.data_lines == 24)
@@ -362,6 +348,7 @@ static int default_get_recommended_bpp(s
 		BUG();
 	}
 }
+EXPORT_SYMBOL(omapdss_default_get_recommended_bpp);
 
 /* Checks if replication logic should be used. Only use for active matrix,
  * when overlay is in RGB12U or RGB16 mode, and LCD interface is
@@ -425,10 +412,6 @@ void dss_init_device(struct platform_dev
 		return;
 	}
 
-	dssdev->get_resolution = default_get_resolution;
-	dssdev->get_recommended_bpp = default_get_recommended_bpp;
-	dssdev->wait_vsync = default_wait_vsync;
-
 	switch (dssdev->type) {
 	case OMAP_DISPLAY_TYPE_DPI:
 		r = dpi_init_display(dssdev);
@@ -502,13 +485,13 @@ static int dss_suspend_device(struct dev
 		return 0;
 	}
 
-	if (!dssdev->suspend) {
+	if (!dssdev->driver->suspend) {
 		DSSERR("display '%s' doesn't implement suspend\n",
 				dssdev->name);
 		return -ENOSYS;
 	}
 
-	r = dssdev->suspend(dssdev);
+	r = dssdev->driver->suspend(dssdev);
 	if (r)
 		return r;
 
@@ -537,8 +520,8 @@ static int dss_resume_device(struct devi
 	int r;
 	struct omap_dss_device *dssdev = to_dss_device(dev);
 
-	if (dssdev->activate_after_resume && dssdev->resume) {
-		r = dssdev->resume(dssdev);
+	if (dssdev->activate_after_resume && dssdev->driver->resume) {
+		r = dssdev->driver->resume(dssdev);
 		if (r)
 			return r;
 	}
@@ -558,7 +541,7 @@ int dss_resume_all_devices(void)
 static int dss_disable_device(struct device *dev, void *data)
 {
 	struct omap_dss_device *dssdev = to_dss_device(dev);
-	dssdev->disable(dssdev);
+	dssdev->driver->disable(dssdev);
 	return 0;
 }
 
@@ -591,10 +574,6 @@ struct omap_dss_device *omap_dss_get_nex
 
 	int match(struct device *dev, void *data)
 	{
-		/* skip panels connected to controllers */
-		if (to_dss_device(dev)->panel.ctrl)
-			return 0;
-
 		return 1;
 	}
 
@@ -626,45 +605,21 @@ EXPORT_SYMBOL(omap_dss_find_device);
 
 int omap_dss_start_device(struct omap_dss_device *dssdev)
 {
-	int r;
-
 	if (!dssdev->driver) {
 		DSSDBG("no driver\n");
-		r = -ENODEV;
-		goto err0;
-	}
-
-	if (dssdev->ctrl.panel && !dssdev->ctrl.panel->driver) {
-		DSSDBG("no panel driver\n");
-		r = -ENODEV;
-		goto err0;
+		return -ENODEV;
 	}
 
 	if (!try_module_get(dssdev->dev.driver->owner)) {
-		r = -ENODEV;
-		goto err0;
-	}
-
-	if (dssdev->ctrl.panel) {
-		if (!try_module_get(dssdev->ctrl.panel->dev.driver->owner)) {
-			r = -ENODEV;
-			goto err1;
-		}
+		return -ENODEV;
 	}
 
 	return 0;
-err1:
-	module_put(dssdev->dev.driver->owner);
-err0:
-	return r;
 }
 EXPORT_SYMBOL(omap_dss_start_device);
 
 void omap_dss_stop_device(struct omap_dss_device *dssdev)
 {
-	if (dssdev->ctrl.panel)
-		module_put(dssdev->ctrl.panel->dev.driver->owner);
-
 	module_put(dssdev->dev.driver->owner);
 }
 EXPORT_SYMBOL(omap_dss_stop_device);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/dpi.c linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/dpi.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/dpi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/dpi.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,10 @@
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/err.h>
 #include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
 
 #include <plat/display.h>
 #include <plat/cpu.h>
@@ -33,7 +36,7 @@
 #include "dss.h"
 
 static struct {
-	int update_enabled;
+	struct regulator *vdds_dsi_reg;
 } dpi;
 
 #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
@@ -53,7 +56,7 @@ static int dpi_set_dsi_clk(bool is_tft,
 	if (r)
 		return r;
 
-	dss_select_clk_source(0, 1);
+	dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK);
 
 	r = dispc_set_clock_div(&dispc_cinfo);
 	if (r)
@@ -150,7 +153,7 @@ static int dpi_basic_init(struct omap_ds
 	return 0;
 }
 
-static int dpi_display_enable(struct omap_dss_device *dssdev)
+int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 {
 	int r;
 
@@ -160,10 +163,10 @@ static int dpi_display_enable(struct oma
 		goto err0;
 	}
 
-	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
-		DSSERR("display already enabled\n");
-		r = -EINVAL;
-		goto err1;
+	if (cpu_is_omap34xx()) {
+		r = regulator_enable(dpi.vdds_dsi_reg);
+		if (r)
+			goto err1;
 	}
 
 	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
@@ -184,18 +187,10 @@ static int dpi_display_enable(struct oma
 
 	mdelay(2);
 
-	dispc_enable_lcd_out(1);
-
-	r = dssdev->driver->enable(dssdev);
-	if (r)
-		goto err5;
-
-	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+	dssdev->manager->enable(dssdev->manager);
 
 	return 0;
 
-err5:
-	dispc_enable_lcd_out(0);
 err4:
 #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
 	dsi_pll_uninit();
@@ -204,78 +199,35 @@ err3:
 #endif
 err2:
 	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+	if (cpu_is_omap34xx())
+		regulator_disable(dpi.vdds_dsi_reg);
 err1:
 	omap_dss_stop_device(dssdev);
 err0:
 	return r;
 }
+EXPORT_SYMBOL(omapdss_dpi_display_enable);
 
-static int dpi_display_resume(struct omap_dss_device *dssdev);
-
-static void dpi_display_disable(struct omap_dss_device *dssdev)
+void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 {
-	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
-		return;
-
-	if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
-		dpi_display_resume(dssdev);
-
-	dssdev->driver->disable(dssdev);
-
-	dispc_enable_lcd_out(0);
+	dssdev->manager->disable(dssdev->manager);
 
 #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
-	dss_select_clk_source(0, 0);
+	dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
 	dsi_pll_uninit();
 	dss_clk_disable(DSS_CLK_FCK2);
 #endif
 
 	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
 
-	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+	if (cpu_is_omap34xx())
+		regulator_disable(dpi.vdds_dsi_reg);
 
 	omap_dss_stop_device(dssdev);
 }
+EXPORT_SYMBOL(omapdss_dpi_display_disable);
 
-static int dpi_display_suspend(struct omap_dss_device *dssdev)
-{
-	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
-		return -EINVAL;
-
-	DSSDBG("dpi_display_suspend\n");
-
-	if (dssdev->driver->suspend)
-		dssdev->driver->suspend(dssdev);
-
-	dispc_enable_lcd_out(0);
-
-	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
-
-	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-
-	return 0;
-}
-
-static int dpi_display_resume(struct omap_dss_device *dssdev)
-{
-	if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
-		return -EINVAL;
-
-	DSSDBG("dpi_display_resume\n");
-
-	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
-
-	dispc_enable_lcd_out(1);
-
-	if (dssdev->driver->resume)
-		dssdev->driver->resume(dssdev);
-
-	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-	return 0;
-}
-
-static void dpi_set_timings(struct omap_dss_device *dssdev,
+void dpi_set_timings(struct omap_dss_device *dssdev,
 			struct omap_video_timings *timings)
 {
 	DSSDBG("dpi_set_timings\n");
@@ -285,8 +237,9 @@ static void dpi_set_timings(struct omap_
 		dispc_go(OMAP_DSS_CHANNEL_LCD);
 	}
 }
+EXPORT_SYMBOL(dpi_set_timings);
 
-static int dpi_check_timings(struct omap_dss_device *dssdev,
+int dpi_check_timings(struct omap_dss_device *dssdev,
 			struct omap_video_timings *timings)
 {
 	bool is_tft;
@@ -340,56 +293,25 @@ static int dpi_check_timings(struct omap
 
 	return 0;
 }
-
-static void dpi_get_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
-{
-	*timings = dssdev->panel.timings;
-}
-
-static int dpi_display_set_update_mode(struct omap_dss_device *dssdev,
-		enum omap_dss_update_mode mode)
-{
-	if (mode == OMAP_DSS_UPDATE_MANUAL)
-		return -EINVAL;
-
-	if (mode == OMAP_DSS_UPDATE_DISABLED) {
-		dispc_enable_lcd_out(0);
-		dpi.update_enabled = 0;
-	} else {
-		dispc_enable_lcd_out(1);
-		dpi.update_enabled = 1;
-	}
-
-	return 0;
-}
-
-static enum omap_dss_update_mode dpi_display_get_update_mode(
-		struct omap_dss_device *dssdev)
-{
-	return dpi.update_enabled ? OMAP_DSS_UPDATE_AUTO :
-		OMAP_DSS_UPDATE_DISABLED;
-}
+EXPORT_SYMBOL(dpi_check_timings);
 
 int dpi_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("init_display\n");
 
-	dssdev->enable = dpi_display_enable;
-	dssdev->disable = dpi_display_disable;
-	dssdev->suspend = dpi_display_suspend;
-	dssdev->resume = dpi_display_resume;
-	dssdev->set_timings = dpi_set_timings;
-	dssdev->check_timings = dpi_check_timings;
-	dssdev->get_timings = dpi_get_timings;
-	dssdev->set_update_mode = dpi_display_set_update_mode;
-	dssdev->get_update_mode = dpi_display_get_update_mode;
-
 	return 0;
 }
 
-int dpi_init(void)
+int dpi_init(struct platform_device *pdev)
 {
+	if (cpu_is_omap34xx()) {
+		dpi.vdds_dsi_reg = dss_get_vdds_dsi();
+		if (IS_ERR(dpi.vdds_dsi_reg)) {
+			DSSERR("can't get VDDS_DSI regulator\n");
+			return PTR_ERR(dpi.vdds_dsi_reg);
+		}
+	}
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/dsi.c linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/dsi.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/dsi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/dsi.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,11 +27,12 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/semaphore.h>
 #include <linux/seq_file.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
-#include <linux/kthread.h>
 #include <linux/wait.h>
+#include <linux/workqueue.h>
 
 #include <plat/display.h>
 #include <plat/clock.h>
@@ -199,7 +200,6 @@ enum dsi_vc_mode {
 };
 
 struct dsi_update_region {
-	bool dirty;
 	u16 x, y, w, h;
 	struct omap_dss_device *device;
 };
@@ -224,29 +224,25 @@ static struct
 		enum dsi_vc_mode mode;
 		struct omap_dss_device *dssdev;
 		enum fifo_size fifo_size;
-		int dest_per;	/* destination peripheral 0-3 */
 	} vc[4];
 
 	struct mutex lock;
-	struct mutex bus_lock;
+	struct semaphore bus_lock;
 
 	unsigned pll_locked;
 
 	struct completion bta_completion;
 
-	struct task_struct *thread;
-	wait_queue_head_t waitqueue;
-
-	spinlock_t update_lock;
-	bool framedone_received;
+	int update_channel;
 	struct dsi_update_region update_region;
-	struct dsi_update_region active_update_region;
-	struct completion update_completion;
 
-	enum omap_dss_update_mode user_update_mode;
-	enum omap_dss_update_mode update_mode;
 	bool te_enabled;
-	bool use_ext_te;
+
+	struct work_struct framedone_work;
+	void (*framedone_callback)(int, void *);
+	void *framedone_data;
+
+	struct delayed_work framedone_timeout_work;
 
 #ifdef DSI_CATCH_MISSING_TE
 	struct timer_list te_timer;
@@ -261,8 +257,6 @@ static struct
 #ifdef DEBUG
 	ktime_t perf_setup_time;
 	ktime_t perf_start_time;
-	ktime_t perf_start_time_auto;
-	int perf_measure_frames;
 #endif
 	int debug_read;
 	int debug_write;
@@ -299,16 +293,21 @@ void dsi_restore_context(void)
 
 void dsi_bus_lock(void)
 {
-	mutex_lock(&dsi.bus_lock);
+	down(&dsi.bus_lock);
 }
 EXPORT_SYMBOL(dsi_bus_lock);
 
 void dsi_bus_unlock(void)
 {
-	mutex_unlock(&dsi.bus_lock);
+	up(&dsi.bus_lock);
 }
 EXPORT_SYMBOL(dsi_bus_unlock);
 
+static bool dsi_bus_is_locked(void)
+{
+	return dsi.bus_lock.count == 0;
+}
+
 static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum,
 		int value)
 {
@@ -333,12 +332,6 @@ static void dsi_perf_mark_start(void)
 	dsi.perf_start_time = ktime_get();
 }
 
-static void dsi_perf_mark_start_auto(void)
-{
-	dsi.perf_measure_frames = 0;
-	dsi.perf_start_time_auto = ktime_get();
-}
-
 static void dsi_perf_show(const char *name)
 {
 	ktime_t t, setup_time, trans_time;
@@ -348,9 +341,6 @@ static void dsi_perf_show(const char *na
 	if (!dsi_perf)
 		return;
 
-	if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED)
-		return;
-
 	t = ktime_get();
 
 	setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time);
@@ -365,76 +355,23 @@ static void dsi_perf_show(const char *na
 
 	total_us = setup_us + trans_us;
 
-	total_bytes = dsi.active_update_region.w *
-		dsi.active_update_region.h *
-		dsi.active_update_region.device->ctrl.pixel_size / 8;
-
-	if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) {
-		static u32 s_total_trans_us, s_total_setup_us;
-		static u32 s_min_trans_us = 0xffffffff, s_min_setup_us;
-		static u32 s_max_trans_us, s_max_setup_us;
-		const int numframes = 100;
-		ktime_t total_time_auto;
-		u32 total_time_auto_us;
-
-		dsi.perf_measure_frames++;
-
-		if (setup_us < s_min_setup_us)
-			s_min_setup_us = setup_us;
-
-		if (setup_us > s_max_setup_us)
-			s_max_setup_us = setup_us;
-
-		s_total_setup_us += setup_us;
-
-		if (trans_us < s_min_trans_us)
-			s_min_trans_us = trans_us;
-
-		if (trans_us > s_max_trans_us)
-			s_max_trans_us = trans_us;
-
-		s_total_trans_us += trans_us;
-
-		if (dsi.perf_measure_frames < numframes)
-			return;
-
-		total_time_auto = ktime_sub(t, dsi.perf_start_time_auto);
-		total_time_auto_us = (u32)ktime_to_us(total_time_auto);
-
-		printk(KERN_INFO "DSI(%s): %u fps, setup %u/%u/%u, "
-				"trans %u/%u/%u\n",
-				name,
-				1000 * 1000 * numframes / total_time_auto_us,
-				s_min_setup_us,
-				s_max_setup_us,
-				s_total_setup_us / numframes,
-				s_min_trans_us,
-				s_max_trans_us,
-				s_total_trans_us / numframes);
+	total_bytes = dsi.update_region.w *
+		dsi.update_region.h *
+		dsi.update_region.device->ctrl.pixel_size / 8;
 
-		s_total_setup_us = 0;
-		s_min_setup_us = 0xffffffff;
-		s_max_setup_us = 0;
-		s_total_trans_us = 0;
-		s_min_trans_us = 0xffffffff;
-		s_max_trans_us = 0;
-		dsi_perf_mark_start_auto();
-	} else {
-		printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
-				"%u bytes, %u kbytes/sec\n",
-				name,
-				setup_us,
-				trans_us,
-				total_us,
-				1000*1000 / total_us,
-				total_bytes,
-				total_bytes * 1000 / total_us);
-	}
+	printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
+			"%u bytes, %u kbytes/sec\n",
+			name,
+			setup_us,
+			trans_us,
+			total_us,
+			1000*1000 / total_us,
+			total_bytes,
+			total_bytes * 1000 / total_us);
 }
 #else
 #define dsi_perf_mark_setup()
 #define dsi_perf_mark_start()
-#define dsi_perf_mark_start_auto()
 #define dsi_perf_show(x)
 #endif
 
@@ -774,7 +711,7 @@ static unsigned long dsi_fclk_rate(void)
 {
 	unsigned long r;
 
-	if (dss_get_dsi_clk_source() == 0) {
+	if (dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) {
 		/* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */
 		r = dss_clk_get_rate(DSS_CLK_FCK1);
 	} else {
@@ -1227,17 +1164,19 @@ void dsi_dump_clocks(struct seq_file *s)
 	seq_printf(s,	"dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n",
 			cinfo->dsi1_pll_fclk,
 			cinfo->regm3,
-			dss_get_dispc_clk_source() == 0 ? "off" : "on");
+			dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
+			"off" : "on");
 
 	seq_printf(s,	"dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n",
 			cinfo->dsi2_pll_fclk,
 			cinfo->regm4,
-			dss_get_dsi_clk_source() == 0 ? "off" : "on");
+			dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
+			"off" : "on");
 
 	seq_printf(s,	"- DSI -\n");
 
 	seq_printf(s,	"dsi fclk source = %s\n",
-			dss_get_dsi_clk_source() == 0 ?
+			dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
 			"dss1_alwon_fclk" : "dsi2_pll_fclk");
 
 	seq_printf(s,	"DSI_FCLK\t%lu\n", dsi_fclk_rate());
@@ -1756,29 +1695,10 @@ static int dsi_force_tx_stop_mode_io(voi
 	return 0;
 }
 
-static void dsi_vc_print_status(int channel)
-{
-	u32 r;
-
-	r = dsi_read_reg(DSI_VC_CTRL(channel));
-	DSSDBG("vc %d: TX_FIFO_NOT_EMPTY %d, BTA_EN %d, VC_BUSY %d, "
-			"TX_FIFO_FULL %d, RX_FIFO_NOT_EMPTY %d, ",
-			channel,
-			FLD_GET(r, 5, 5),
-			FLD_GET(r, 6, 6),
-			FLD_GET(r, 15, 15),
-			FLD_GET(r, 16, 16),
-			FLD_GET(r, 20, 20));
-
-	r = dsi_read_reg(DSI_TX_FIFO_VC_EMPTINESS);
-	DSSDBG("EMPTINESS %d\n", (r >> (8 * channel)) & 0xff);
-}
-
 static int dsi_vc_enable(int channel, bool enable)
 {
-	if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO)
-		DSSDBG("dsi_vc_enable channel %d, enable %d\n",
-				channel, enable);
+	DSSDBG("dsi_vc_enable channel %d, enable %d\n",
+			channel, enable);
 
 	enable = enable ? 1 : 0;
 
@@ -1859,10 +1779,12 @@ static void dsi_vc_config_vp(int channel
 }
 
 
-static void dsi_vc_enable_hs(int channel, bool enable)
+void omapdss_dsi_vc_enable_hs(int channel, bool enable)
 {
 	DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
 
+	WARN_ON(!dsi_bus_is_locked());
+
 	dsi_vc_enable(channel, 0);
 	dsi_if_enable(0);
 
@@ -1873,6 +1795,7 @@ static void dsi_vc_enable_hs(int channel
 
 	dsi_force_tx_stop_mode_io();
 }
+EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs);
 
 static void dsi_vc_flush_long_data(int channel)
 {
@@ -1955,11 +1878,10 @@ static u16 dsi_vc_flush_receive_data(int
 
 static int dsi_vc_send_bta(int channel)
 {
-	if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO &&
-			(dsi.debug_write || dsi.debug_read))
+	if (dsi.debug_write || dsi.debug_read)
 		DSSDBG("dsi_vc_send_bta %d\n", channel);
 
-	WARN_ON(!mutex_is_locked(&dsi.bus_lock));
+	WARN_ON(!dsi_bus_is_locked());
 
 	if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {	/* RX_FIFO_NOT_EMPTY */
 		DSSERR("rx fifo not empty when sending BTA, dumping data:\n");
@@ -2010,10 +1932,9 @@ static inline void dsi_vc_write_long_hea
 	u32 val;
 	u8 data_id;
 
-	WARN_ON(!mutex_is_locked(&dsi.bus_lock));
+	WARN_ON(!dsi_bus_is_locked());
 
-	/*data_id = data_type | channel << 6; */
-	data_id = data_type | dsi.vc[channel].dest_per << 6;
+	data_id = data_type | channel << 6;
 
 	val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
 		FLD_VAL(ecc, 31, 24);
@@ -2056,13 +1977,10 @@ static int dsi_vc_send_long(int channel,
 
 	dsi_vc_write_long_header(channel, data_type, len, ecc);
 
-	/*dsi_vc_print_status(0); */
-
 	p = data;
 	for (i = 0; i < len >> 2; i++) {
 		if (dsi.debug_write)
 			DSSDBG("\tsending full packet %d\n", i);
-		/*dsi_vc_print_status(0); */
 
 		b1 = *p++;
 		b2 = *p++;
@@ -2105,7 +2023,7 @@ static int dsi_vc_send_short(int channel
 	u32 r;
 	u8 data_id;
 
-	WARN_ON(!mutex_is_locked(&dsi.bus_lock));
+	WARN_ON(!dsi_bus_is_locked());
 
 	if (dsi.debug_write)
 		DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
@@ -2119,7 +2037,7 @@ static int dsi_vc_send_short(int channel
 		return -EINVAL;
 	}
 
-	data_id = data_type | dsi.vc[channel].dest_per << 6;
+	data_id = data_type | channel << 6;
 
 	r = (data_id << 0) | (data << 8) | (ecc << 24);
 
@@ -2163,14 +2081,35 @@ int dsi_vc_dcs_write(int channel, u8 *da
 
 	r = dsi_vc_dcs_write_nosync(channel, data, len);
 	if (r)
-		return r;
+		goto err;
 
 	r = dsi_vc_send_bta_sync(channel);
+	if (r)
+		goto err;
 
+	return 0;
+err:
+	DSSERR("dsi_vc_dcs_write(ch %d, cmd 0x%02x, len %d) failed\n",
+			channel, data[0], len);
 	return r;
 }
 EXPORT_SYMBOL(dsi_vc_dcs_write);
 
+int dsi_vc_dcs_write_0(int channel, u8 dcs_cmd)
+{
+	return dsi_vc_dcs_write(channel, &dcs_cmd, 1);
+}
+EXPORT_SYMBOL(dsi_vc_dcs_write_0);
+
+int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param)
+{
+	u8 buf[2];
+	buf[0] = dcs_cmd;
+	buf[1] = param;
+	return dsi_vc_dcs_write(channel, buf, 2);
+}
+EXPORT_SYMBOL(dsi_vc_dcs_write_1);
+
 int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
 {
 	u32 val;
@@ -2182,16 +2121,17 @@ int dsi_vc_dcs_read(int channel, u8 dcs_
 
 	r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0);
 	if (r)
-		return r;
+		goto err;
 
 	r = dsi_vc_send_bta_sync(channel);
 	if (r)
-		return r;
+		goto err;
 
 	/* RX_FIFO_NOT_EMPTY */
 	if (REG_GET(DSI_VC_CTRL(channel), 20, 20) == 0) {
 		DSSERR("RX fifo empty when trying to read.\n");
-		return -EIO;
+		r = -EIO;
+		goto err;
 	}
 
 	val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
@@ -2201,15 +2141,18 @@ int dsi_vc_dcs_read(int channel, u8 dcs_
 	if (dt == DSI_DT_RX_ACK_WITH_ERR) {
 		u16 err = FLD_GET(val, 23, 8);
 		dsi_show_rx_ack_with_err(err);
-		return -EIO;
+		r = -EIO;
+		goto err;
 
 	} else if (dt == DSI_DT_RX_SHORT_READ_1) {
 		u8 data = FLD_GET(val, 15, 8);
 		if (dsi.debug_read)
 			DSSDBG("\tDCS short response, 1 byte: %02x\n", data);
 
-		if (buflen < 1)
-			return -EIO;
+		if (buflen < 1) {
+			r = -EIO;
+			goto err;
+		}
 
 		buf[0] = data;
 
@@ -2219,8 +2162,10 @@ int dsi_vc_dcs_read(int channel, u8 dcs_
 		if (dsi.debug_read)
 			DSSDBG("\tDCS short response, 2 byte: %04x\n", data);
 
-		if (buflen < 2)
-			return -EIO;
+		if (buflen < 2) {
+			r = -EIO;
+			goto err;
+		}
 
 		buf[0] = data & 0xff;
 		buf[1] = (data >> 8) & 0xff;
@@ -2232,8 +2177,10 @@ int dsi_vc_dcs_read(int channel, u8 dcs_
 		if (dsi.debug_read)
 			DSSDBG("\tDCS long response, len %d\n", len);
 
-		if (len > buflen)
-			return -EIO;
+		if (len > buflen) {
+			r = -EIO;
+			goto err;
+		}
 
 		/* two byte checksum ends the packet, not included in len */
 		for (w = 0; w < len + 2;) {
@@ -2255,14 +2202,52 @@ int dsi_vc_dcs_read(int channel, u8 dcs_
 		}
 
 		return len;
-
 	} else {
 		DSSERR("\tunknown datatype 0x%02x\n", dt);
-		return -EIO;
+		r = -EIO;
+		goto err;
 	}
+
+	BUG();
+err:
+	DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n",
+			channel, dcs_cmd);
+	return r;
+
 }
 EXPORT_SYMBOL(dsi_vc_dcs_read);
 
+int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data)
+{
+	int r;
+
+	r = dsi_vc_dcs_read(channel, dcs_cmd, data, 1);
+
+	if (r < 0)
+		return r;
+
+	if (r != 1)
+		return -EIO;
+
+	return 0;
+}
+EXPORT_SYMBOL(dsi_vc_dcs_read_1);
+
+int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u16 *data)
+{
+	int r;
+
+	r = dsi_vc_dcs_read(channel, dcs_cmd, (u8 *)data, 2);
+
+	if (r < 0)
+		return r;
+
+	if (r != 2)
+		return -EIO;
+
+	return 0;
+}
+EXPORT_SYMBOL(dsi_vc_dcs_read_2);
 
 int dsi_vc_set_max_rx_packet_size(int channel, u16 len)
 {
@@ -2491,15 +2476,15 @@ static int dsi_proto_config(struct omap_
 	u32 r;
 	int buswidth = 0;
 
-	dsi_config_tx_fifo(DSI_FIFO_SIZE_128,
-			DSI_FIFO_SIZE_0,
-			DSI_FIFO_SIZE_0,
-			DSI_FIFO_SIZE_0);
+	dsi_config_tx_fifo(DSI_FIFO_SIZE_32,
+			DSI_FIFO_SIZE_32,
+			DSI_FIFO_SIZE_32,
+			DSI_FIFO_SIZE_32);
 
-	dsi_config_rx_fifo(DSI_FIFO_SIZE_128,
-			DSI_FIFO_SIZE_0,
-			DSI_FIFO_SIZE_0,
-			DSI_FIFO_SIZE_0);
+	dsi_config_rx_fifo(DSI_FIFO_SIZE_32,
+			DSI_FIFO_SIZE_32,
+			DSI_FIFO_SIZE_32,
+			DSI_FIFO_SIZE_32);
 
 	/* XXX what values for the timeouts? */
 	dsi_set_stop_state_counter(1000);
@@ -2537,12 +2522,9 @@ static int dsi_proto_config(struct omap_
 	dsi_write_reg(DSI_CTRL, r);
 
 	dsi_vc_initial_config(0);
-
-	/* set all vc targets to peripheral 0 */
-	dsi.vc[0].dest_per = 0;
-	dsi.vc[1].dest_per = 0;
-	dsi.vc[2].dest_per = 0;
-	dsi.vc[3].dest_per = 0;
+	dsi_vc_initial_config(1);
+	dsi_vc_initial_config(2);
+	dsi_vc_initial_config(3);
 
 	return 0;
 }
@@ -2777,18 +2759,16 @@ static void dsi_update_screen_dispc(stru
 	unsigned packet_payload;
 	unsigned packet_len;
 	u32 l;
-	bool use_te_trigger;
-	const unsigned channel = 0;
+	const unsigned channel = dsi.update_channel;
 	/* line buffer is 1024 x 24bits */
 	/* XXX: for some reason using full buffer size causes considerable TX
 	 * slowdown with update sizes that fill the whole buffer */
 	const unsigned line_buf_size = 1023 * 3;
 
-	use_te_trigger = dsi.te_enabled && !dsi.use_ext_te;
+	DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
+			x, y, w, h);
 
-	if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO)
-		DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
-				x, y, w, h);
+	dsi_vc_config_vp(channel);
 
 	bytespp	= dssdev->ctrl.pixel_size / 8;
 	bytespl = w * bytespp;
@@ -2808,15 +2788,12 @@ static void dsi_update_screen_dispc(stru
 	if (bytespf % packet_payload)
 		total_len += (bytespf % packet_payload) + 1;
 
-	if (0)
-		dsi_vc_print_status(1);
-
 	l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
 	dsi_write_reg(DSI_VC_TE(channel), l);
 
 	dsi_vc_write_long_header(channel, DSI_DT_DCS_LONG_WRITE, packet_len, 0);
 
-	if (use_te_trigger)
+	if (dsi.te_enabled)
 		l = FLD_MOD(l, 1, 30, 30); /* TE_EN */
 	else
 		l = FLD_MOD(l, 1, 31, 31); /* TE_START */
@@ -2830,9 +2807,14 @@ static void dsi_update_screen_dispc(stru
 	 */
 	dispc_disable_sidle();
 
+	dsi_perf_mark_start();
+
+	schedule_delayed_work(&dsi.framedone_timeout_work,
+			msecs_to_jiffies(250));
+
 	dss_start_update(dssdev);
 
-	if (use_te_trigger) {
+	if (dsi.te_enabled) {
 		/* disable LP_RX_TO, so that we can receive TE.  Time to wait
 		 * for TE is longer than the timer allows */
 		REG_FLD_MOD(DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */
@@ -2852,110 +2834,64 @@ static void dsi_te_timeout(unsigned long
 }
 #endif
 
-static void dsi_framedone_irq_callback(void *data, u32 mask)
+static void dsi_framedone_timeout_work_callback(struct work_struct *work)
 {
-	/* Note: We get FRAMEDONE when DISPC has finished sending pixels and
-	 * turns itself off. However, DSI still has the pixels in its buffers,
-	 * and is sending the data.
-	 */
+	int r;
+	const int channel = dsi.update_channel;
+
+	DSSERR("Framedone not received for 250ms!\n");
 
 	/* SIDLEMODE back to smart-idle */
 	dispc_enable_sidle();
 
-	dsi.framedone_received = true;
-	wake_up(&dsi.waitqueue);
-}
-
-static void dsi_set_update_region(struct omap_dss_device *dssdev,
-		u16 x, u16 y, u16 w, u16 h)
-{
-	spin_lock(&dsi.update_lock);
-	if (dsi.update_region.dirty) {
-		dsi.update_region.x = min(x, dsi.update_region.x);
-		dsi.update_region.y = min(y, dsi.update_region.y);
-		dsi.update_region.w = max(w, dsi.update_region.w);
-		dsi.update_region.h = max(h, dsi.update_region.h);
-	} else {
-		dsi.update_region.x = x;
-		dsi.update_region.y = y;
-		dsi.update_region.w = w;
-		dsi.update_region.h = h;
+	if (dsi.te_enabled) {
+		/* enable LP_RX_TO again after the TE */
+		REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
 	}
 
-	dsi.update_region.device = dssdev;
-	dsi.update_region.dirty = true;
-
-	spin_unlock(&dsi.update_lock);
-
-}
-
-static int dsi_set_update_mode(struct omap_dss_device *dssdev,
-		enum omap_dss_update_mode mode)
-{
-	int r = 0;
-	int i;
-
-	WARN_ON(!mutex_is_locked(&dsi.bus_lock));
-
-	if (dsi.update_mode != mode) {
-		dsi.update_mode = mode;
-
-		/* Mark the overlays dirty, and do apply(), so that we get the
-		 * overlays configured properly after update mode change. */
-		for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
-			struct omap_overlay *ovl;
-			ovl = omap_dss_get_overlay(i);
-			if (ovl->manager == dssdev->manager)
-				ovl->info_dirty = true;
-		}
-
-		r = dssdev->manager->apply(dssdev->manager);
-
-		if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE &&
-				mode == OMAP_DSS_UPDATE_AUTO) {
-			u16 w, h;
-
-			DSSDBG("starting auto update\n");
-
-			dssdev->get_resolution(dssdev, &w, &h);
-
-			dsi_set_update_region(dssdev, 0, 0, w, h);
-
-			dsi_perf_mark_start_auto();
+	/* Send BTA after the frame. We need this for the TE to work, as TE
+	 * trigger is only sent for BTAs without preceding packet. Thus we need
+	 * to BTA after the pixel packets so that next BTA will cause TE
+	 * trigger.
+	 *
+	 * This is not needed when TE is not in use, but we do it anyway to
+	 * make sure that the transfer has been completed. It would be more
+	 * optimal, but more complex, to wait only just before starting next
+	 * transfer. */
+	r = dsi_vc_send_bta_sync(channel);
+	if (r)
+		DSSERR("BTA after framedone failed\n");
 
-			wake_up(&dsi.waitqueue);
-		}
+	/* RX_FIFO_NOT_EMPTY */
+	if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
+		DSSERR("Received error during frame transfer:\n");
+		dsi_vc_flush_receive_data(channel);
 	}
 
-	return r;
+	dsi.framedone_callback(-ETIMEDOUT, dsi.framedone_data);
 }
 
-static int dsi_set_te(struct omap_dss_device *dssdev, bool enable)
+static void dsi_framedone_irq_callback(void *data, u32 mask)
 {
-	int r = 0;
+	/* Note: We get FRAMEDONE when DISPC has finished sending pixels and
+	 * turns itself off. However, DSI still has the pixels in its buffers,
+	 * and is sending the data.
+	 */
 
-	if (dssdev->driver->enable_te) {
-		r = dssdev->driver->enable_te(dssdev, enable);
-		/* XXX for some reason, DSI TE breaks if we don't wait here.
-		 * Panel bug? Needs more studying */
-		msleep(100);
-	}
+	/* SIDLEMODE back to smart-idle */
+	dispc_enable_sidle();
 
-	return r;
+	schedule_work(&dsi.framedone_work);
 }
 
 static void dsi_handle_framedone(void)
 {
 	int r;
-	const int channel = 0;
-	bool use_te_trigger;
-
-	use_te_trigger = dsi.te_enabled && !dsi.use_ext_te;
+	const int channel = dsi.update_channel;
 
-	if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO)
-		DSSDBG("FRAMEDONE\n");
+	DSSDBG("FRAMEDONE\n");
 
-	if (use_te_trigger) {
+	if (dsi.te_enabled) {
 		/* enable LP_RX_TO again after the TE */
 		REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
 	}
@@ -2976,7 +2912,7 @@ static void dsi_handle_framedone(void)
 	/* RX_FIFO_NOT_EMPTY */
 	if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
 		DSSERR("Received error during frame transfer:\n");
-		dsi_vc_flush_receive_data(0);
+		dsi_vc_flush_receive_data(channel);
 	}
 
 #ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
@@ -2984,118 +2920,79 @@ static void dsi_handle_framedone(void)
 #endif
 }
 
-static int dsi_update_thread(void *data)
+static void dsi_framedone_work_callback(struct work_struct *work)
 {
-	unsigned long timeout;
-	struct omap_dss_device *device;
-	u16 x, y, w, h;
-
-	while (1) {
-		bool sched;
-
-		wait_event_interruptible(dsi.waitqueue,
-				dsi.update_mode == OMAP_DSS_UPDATE_AUTO ||
-				(dsi.update_mode == OMAP_DSS_UPDATE_MANUAL &&
-				 dsi.update_region.dirty == true) ||
-				kthread_should_stop());
-
-		if (kthread_should_stop())
-			break;
-
-		dsi_bus_lock();
-
-		if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED ||
-				kthread_should_stop()) {
-			dsi_bus_unlock();
-			break;
-		}
-
-		dsi_perf_mark_setup();
-
-		if (dsi.update_region.dirty) {
-			spin_lock(&dsi.update_lock);
-			dsi.active_update_region = dsi.update_region;
-			dsi.update_region.dirty = false;
-			spin_unlock(&dsi.update_lock);
-		}
+	DSSDBGF();
 
-		device = dsi.active_update_region.device;
-		x = dsi.active_update_region.x;
-		y = dsi.active_update_region.y;
-		w = dsi.active_update_region.w;
-		h = dsi.active_update_region.h;
+	cancel_delayed_work_sync(&dsi.framedone_timeout_work);
 
-		if (device->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
+	dsi_handle_framedone();
 
-			if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL)
-				dss_setup_partial_planes(device,
-						&x, &y, &w, &h);
+	dsi_perf_show("DISPC");
 
-			dispc_set_lcd_size(w, h);
-		}
+	dsi.framedone_callback(0, dsi.framedone_data);
+}
 
-		if (dsi.active_update_region.dirty) {
-			dsi.active_update_region.dirty = false;
-			/* XXX TODO we don't need to send the coords, if they
-			 * are the same that are already programmed to the
-			 * panel. That should speed up manual update a bit */
-			device->driver->setup_update(device, x, y, w, h);
-		}
+int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
+				    u16 *x, u16 *y, u16 *w, u16 *h)
+{
+	u16 dw, dh;
 
-		dsi_perf_mark_start();
+	dssdev->driver->get_resolution(dssdev, &dw, &dh);
 
-		if (device->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
-			dsi_vc_config_vp(0);
+	if  (*x > dw || *y > dh)
+		return -EINVAL;
 
-			if (dsi.te_enabled && dsi.use_ext_te)
-				device->driver->wait_for_te(device);
+	if (*x + *w > dw)
+		return -EINVAL;
 
-			dsi.framedone_received = false;
+	if (*y + *h > dh)
+		return -EINVAL;
 
-			dsi_update_screen_dispc(device, x, y, w, h);
+	if (*w == 1)
+		return -EINVAL;
 
-			/* wait for framedone */
-			timeout = msecs_to_jiffies(1000);
-			wait_event_timeout(dsi.waitqueue,
-					dsi.framedone_received == true,
-					timeout);
+	if (*w == 0 || *h == 0)
+		return -EINVAL;
 
-			if (!dsi.framedone_received) {
-				DSSERR("framedone timeout\n");
-				DSSERR("failed update %d,%d %dx%d\n",
-						x, y, w, h);
+	dsi_perf_mark_setup();
 
-				dispc_enable_sidle();
-				dispc_enable_lcd_out(0);
+	if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
+		dss_setup_partial_planes(dssdev, x, y, w, h);
+		dispc_set_lcd_size(*w, *h);
+	}
 
-				dsi_reset_tx_fifo(0);
-			} else {
-				dsi_handle_framedone();
-				dsi_perf_show("DISPC");
-			}
-		} else {
-			dsi_update_screen_l4(device, x, y, w, h);
-			dsi_perf_show("L4");
-		}
+	return 0;
+}
+EXPORT_SYMBOL(omap_dsi_prepare_update);
 
-		sched = atomic_read(&dsi.bus_lock.count) < 0;
+int omap_dsi_update(struct omap_dss_device *dssdev,
+		int channel,
+		u16 x, u16 y, u16 w, u16 h,
+		void (*callback)(int, void *), void *data)
+{
+	dsi.update_channel = channel;
 
-		complete_all(&dsi.update_completion);
+	if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
+		dsi.framedone_callback = callback;
+		dsi.framedone_data = data;
 
-		dsi_bus_unlock();
+		dsi.update_region.x = x;
+		dsi.update_region.y = y;
+		dsi.update_region.w = w;
+		dsi.update_region.h = h;
+		dsi.update_region.device = dssdev;
 
-		/* XXX We need to give others chance to get the bus lock. Is
-		 * there a better way for this? */
-		if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO && sched)
-			schedule_timeout_interruptible(1);
+		dsi_update_screen_dispc(dssdev, x, y, w, h);
+	} else {
+		dsi_update_screen_l4(dssdev, x, y, w, h);
+		dsi_perf_show("L4");
+		callback(0, data);
 	}
 
-	DSSDBG("update thread exiting\n");
-
 	return 0;
 }
-
-
+EXPORT_SYMBOL(omap_dsi_update);
 
 /* Display funcs */
 
@@ -3203,7 +3100,8 @@ static int dsi_display_init_dsi(struct o
 	if (r)
 		goto err1;
 
-	dss_select_clk_source(true, true);
+	dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK);
+	dss_select_dsi_clk_source(DSS_SRC_DSI2_PLL_FCLK);
 
 	DSSDBG("PLL OK\n");
 
@@ -3229,25 +3127,18 @@ static int dsi_display_init_dsi(struct o
 
 	/* enable interface */
 	dsi_vc_enable(0, 1);
+	dsi_vc_enable(1, 1);
+	dsi_vc_enable(2, 1);
+	dsi_vc_enable(3, 1);
 	dsi_if_enable(1);
 	dsi_force_tx_stop_mode_io();
 
-	if (dssdev->driver->enable) {
-		r = dssdev->driver->enable(dssdev);
-		if (r)
-			goto err4;
-	}
-
-	/* enable high-speed after initial config */
-	dsi_vc_enable_hs(0, 1);
-
 	return 0;
-err4:
-	dsi_if_enable(0);
 err3:
 	dsi_complexio_uninit();
 err2:
-	dss_select_clk_source(false, false);
+	dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
+	dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
 err1:
 	dsi_pll_uninit();
 err0:
@@ -3256,10 +3147,8 @@ err0:
 
 static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
 {
-	if (dssdev->driver->disable)
-		dssdev->driver->disable(dssdev);
-
-	dss_select_clk_source(false, false);
+	dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
+	dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
 	dsi_complexio_uninit();
 	dsi_pll_uninit();
 }
@@ -3280,14 +3169,15 @@ static int dsi_core_init(void)
 	return 0;
 }
 
-static int dsi_display_enable(struct omap_dss_device *dssdev)
+int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
 {
 	int r = 0;
 
 	DSSDBG("dsi_display_enable\n");
 
+	WARN_ON(!dsi_bus_is_locked());
+
 	mutex_lock(&dsi.lock);
-	dsi_bus_lock();
 
 	r = omap_dss_start_device(dssdev);
 	if (r) {
@@ -3295,100 +3185,47 @@ static int dsi_display_enable(struct oma
 		goto err0;
 	}
 
-	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
-		DSSERR("dssdev already enabled\n");
-		r = -EINVAL;
-		goto err1;
-	}
-
 	enable_clocks(1);
 	dsi_enable_pll_clock(1);
 
 	r = _dsi_reset();
 	if (r)
-		goto err2;
+		goto err1;
 
 	dsi_core_init();
 
 	r = dsi_display_init_dispc(dssdev);
 	if (r)
-		goto err2;
+		goto err1;
 
 	r = dsi_display_init_dsi(dssdev);
 	if (r)
-		goto err3;
-
-	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-	dsi.use_ext_te = dssdev->phy.dsi.ext_te;
-	r = dsi_set_te(dssdev, dsi.te_enabled);
-	if (r)
-		goto err4;
-
-	dsi_set_update_mode(dssdev, dsi.user_update_mode);
+		goto err2;
 
-	dsi_bus_unlock();
 	mutex_unlock(&dsi.lock);
 
 	return 0;
 
-err4:
-
-	dsi_display_uninit_dsi(dssdev);
-err3:
-	dsi_display_uninit_dispc(dssdev);
 err2:
+	dsi_display_uninit_dispc(dssdev);
+err1:
 	enable_clocks(0);
 	dsi_enable_pll_clock(0);
-err1:
 	omap_dss_stop_device(dssdev);
 err0:
-	dsi_bus_unlock();
 	mutex_unlock(&dsi.lock);
 	DSSDBG("dsi_display_enable FAILED\n");
 	return r;
 }
+EXPORT_SYMBOL(omapdss_dsi_display_enable);
 
-static void dsi_display_disable(struct omap_dss_device *dssdev)
+void omapdss_dsi_display_disable(struct omap_dss_device *dssdev)
 {
 	DSSDBG("dsi_display_disable\n");
 
-	mutex_lock(&dsi.lock);
-	dsi_bus_lock();
-
-	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
-			dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
-		goto end;
-
-	dsi.update_mode = OMAP_DSS_UPDATE_DISABLED;
-	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-
-	dsi_display_uninit_dispc(dssdev);
-
-	dsi_display_uninit_dsi(dssdev);
-
-	enable_clocks(0);
-	dsi_enable_pll_clock(0);
-
-	omap_dss_stop_device(dssdev);
-end:
-	dsi_bus_unlock();
-	mutex_unlock(&dsi.lock);
-}
-
-static int dsi_display_suspend(struct omap_dss_device *dssdev)
-{
-	DSSDBG("dsi_display_suspend\n");
+	WARN_ON(!dsi_bus_is_locked());
 
 	mutex_lock(&dsi.lock);
-	dsi_bus_lock();
-
-	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
-			dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
-		goto end;
-
-	dsi.update_mode = OMAP_DSS_UPDATE_DISABLED;
-	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
 
 	dsi_display_uninit_dispc(dssdev);
 
@@ -3396,312 +3233,19 @@ static int dsi_display_suspend(struct om
 
 	enable_clocks(0);
 	dsi_enable_pll_clock(0);
-end:
-	dsi_bus_unlock();
-	mutex_unlock(&dsi.lock);
 
-	return 0;
-}
-
-static int dsi_display_resume(struct omap_dss_device *dssdev)
-{
-	int r;
-
-	DSSDBG("dsi_display_resume\n");
-
-	mutex_lock(&dsi.lock);
-	dsi_bus_lock();
-
-	if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
-		DSSERR("dssdev not suspended\n");
-		r = -EINVAL;
-		goto err0;
-	}
-
-	enable_clocks(1);
-	dsi_enable_pll_clock(1);
-
-	r = _dsi_reset();
-	if (r)
-		goto err1;
-
-	dsi_core_init();
-
-	r = dsi_display_init_dispc(dssdev);
-	if (r)
-		goto err1;
-
-	r = dsi_display_init_dsi(dssdev);
-	if (r)
-		goto err2;
-
-	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-	r = dsi_set_te(dssdev, dsi.te_enabled);
-	if (r)
-		goto err2;
-
-	dsi_set_update_mode(dssdev, dsi.user_update_mode);
-
-	dsi_bus_unlock();
-	mutex_unlock(&dsi.lock);
-
-	return 0;
-
-err2:
-	dsi_display_uninit_dispc(dssdev);
-err1:
-	enable_clocks(0);
-	dsi_enable_pll_clock(0);
-err0:
-	dsi_bus_unlock();
-	mutex_unlock(&dsi.lock);
-	DSSDBG("dsi_display_resume FAILED\n");
-	return r;
-}
-
-static int dsi_display_update(struct omap_dss_device *dssdev,
-			u16 x, u16 y, u16 w, u16 h)
-{
-	int r = 0;
-	u16 dw, dh;
-
-	DSSDBG("dsi_display_update(%d,%d %dx%d)\n", x, y, w, h);
-
-	mutex_lock(&dsi.lock);
-
-	if (dsi.update_mode != OMAP_DSS_UPDATE_MANUAL)
-		goto end;
-
-	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
-		goto end;
-
-	dssdev->get_resolution(dssdev, &dw, &dh);
-
-	if  (x > dw || y > dh)
-		goto end;
-
-	if (x + w > dw)
-		w = dw - x;
-
-	if (y + h > dh)
-		h = dh - y;
-
-	if (w == 0 || h == 0)
-		goto end;
-
-	if (w == 1) {
-		r = -EINVAL;
-		goto end;
-	}
-
-	dsi_set_update_region(dssdev, x, y, w, h);
-
-	wake_up(&dsi.waitqueue);
-
-end:
-	mutex_unlock(&dsi.lock);
-
-	return r;
-}
-
-static int dsi_display_sync(struct omap_dss_device *dssdev)
-{
-	bool wait;
-
-	DSSDBG("dsi_display_sync()\n");
-
-	mutex_lock(&dsi.lock);
-	dsi_bus_lock();
-
-	if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL &&
-			dsi.update_region.dirty) {
-		INIT_COMPLETION(dsi.update_completion);
-		wait = true;
-	} else {
-		wait = false;
-	}
-
-	dsi_bus_unlock();
-	mutex_unlock(&dsi.lock);
-
-	if (wait)
-		wait_for_completion_interruptible(&dsi.update_completion);
-
-	DSSDBG("dsi_display_sync() done\n");
-	return 0;
-}
-
-static int dsi_display_set_update_mode(struct omap_dss_device *dssdev,
-		enum omap_dss_update_mode mode)
-{
-	int r = 0;
-
-	DSSDBGF("%d", mode);
-
-	mutex_lock(&dsi.lock);
-	dsi_bus_lock();
-
-	dsi.user_update_mode = mode;
-	r = dsi_set_update_mode(dssdev, mode);
+	omap_dss_stop_device(dssdev);
 
-	dsi_bus_unlock();
 	mutex_unlock(&dsi.lock);
-
-	return r;
-}
-
-static enum omap_dss_update_mode dsi_display_get_update_mode(
-		struct omap_dss_device *dssdev)
-{
-	return dsi.update_mode;
 }
+EXPORT_SYMBOL(omapdss_dsi_display_disable);
 
-
-static int dsi_display_enable_te(struct omap_dss_device *dssdev, bool enable)
+int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
 {
-	int r = 0;
-
-	DSSDBGF("%d", enable);
-
-	if (!dssdev->driver->enable_te)
-		return -ENOENT;
-
-	dsi_bus_lock();
-
 	dsi.te_enabled = enable;
-
-	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
-		goto end;
-
-	r = dsi_set_te(dssdev, enable);
-end:
-	dsi_bus_unlock();
-
-	return r;
-}
-
-static int dsi_display_get_te(struct omap_dss_device *dssdev)
-{
-	return dsi.te_enabled;
-}
-
-static int dsi_display_set_rotate(struct omap_dss_device *dssdev, u8 rotate)
-{
-
-	DSSDBGF("%d", rotate);
-
-	if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
-		return -EINVAL;
-
-	dsi_bus_lock();
-	dssdev->driver->set_rotate(dssdev, rotate);
-	if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) {
-		u16 w, h;
-		/* the display dimensions may have changed, so set a new
-		 * update region */
-		dssdev->get_resolution(dssdev, &w, &h);
-		dsi_set_update_region(dssdev, 0, 0, w, h);
-	}
-	dsi_bus_unlock();
-
-	return 0;
-}
-
-static u8 dsi_display_get_rotate(struct omap_dss_device *dssdev)
-{
-	if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
-		return 0;
-
-	return dssdev->driver->get_rotate(dssdev);
-}
-
-static int dsi_display_set_mirror(struct omap_dss_device *dssdev, bool mirror)
-{
-	DSSDBGF("%d", mirror);
-
-	if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
-		return -EINVAL;
-
-	dsi_bus_lock();
-	dssdev->driver->set_mirror(dssdev, mirror);
-	dsi_bus_unlock();
-
 	return 0;
 }
-
-static bool dsi_display_get_mirror(struct omap_dss_device *dssdev)
-{
-	if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
-		return 0;
-
-	return dssdev->driver->get_mirror(dssdev);
-}
-
-static int dsi_display_run_test(struct omap_dss_device *dssdev, int test_num)
-{
-	int r;
-
-	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
-		return -EIO;
-
-	DSSDBGF("%d", test_num);
-
-	dsi_bus_lock();
-
-	/* run test first in low speed mode */
-	dsi_vc_enable_hs(0, 0);
-
-	if (dssdev->driver->run_test) {
-		r = dssdev->driver->run_test(dssdev, test_num);
-		if (r)
-			goto end;
-	}
-
-	/* then in high speed */
-	dsi_vc_enable_hs(0, 1);
-
-	if (dssdev->driver->run_test) {
-		r = dssdev->driver->run_test(dssdev, test_num);
-		if (r)
-			goto end;
-	}
-
-end:
-	dsi_vc_enable_hs(0, 1);
-
-	dsi_bus_unlock();
-
-	return r;
-}
-
-static int dsi_display_memory_read(struct omap_dss_device *dssdev,
-		void *buf, size_t size,
-		u16 x, u16 y, u16 w, u16 h)
-{
-	int r;
-
-	DSSDBGF("");
-
-	if (!dssdev->driver->memory_read)
-		return -EINVAL;
-
-	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
-		return -EIO;
-
-	dsi_bus_lock();
-
-	r = dssdev->driver->memory_read(dssdev, buf, size,
-			x, y, w, h);
-
-	/* Memory read usually changes the update area. This will
-	 * force the next update to re-set the update area */
-	dsi.active_update_region.dirty = true;
-
-	dsi_bus_unlock();
-
-	return r;
-}
+EXPORT_SYMBOL(omapdss_dsi_enable_te);
 
 void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
 		u32 fifo_size, enum omap_burst_size *burst_size,
@@ -3720,26 +3264,6 @@ int dsi_init_display(struct omap_dss_dev
 {
 	DSSDBG("DSI init\n");
 
-	dssdev->enable = dsi_display_enable;
-	dssdev->disable = dsi_display_disable;
-	dssdev->suspend = dsi_display_suspend;
-	dssdev->resume = dsi_display_resume;
-	dssdev->update = dsi_display_update;
-	dssdev->sync = dsi_display_sync;
-	dssdev->set_update_mode = dsi_display_set_update_mode;
-	dssdev->get_update_mode = dsi_display_get_update_mode;
-	dssdev->enable_te = dsi_display_enable_te;
-	dssdev->get_te = dsi_display_get_te;
-
-	dssdev->get_rotate = dsi_display_get_rotate;
-	dssdev->set_rotate = dsi_display_set_rotate;
-
-	dssdev->get_mirror = dsi_display_get_mirror;
-	dssdev->set_mirror = dsi_display_set_mirror;
-
-	dssdev->run_test = dsi_display_run_test;
-	dssdev->memory_read = dsi_display_memory_read;
-
 	/* XXX these should be figured out dynamically */
 	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
 		OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
@@ -3754,9 +3278,6 @@ int dsi_init(struct platform_device *pde
 {
 	u32 rev;
 	int r;
-	struct sched_param param = {
-		.sched_priority = MAX_USER_RT_PRIO-1
-	};
 
 	spin_lock_init(&dsi.errors_lock);
 	dsi.errors = 0;
@@ -3767,31 +3288,19 @@ int dsi_init(struct platform_device *pde
 #endif
 
 	init_completion(&dsi.bta_completion);
-	init_completion(&dsi.update_completion);
-
-	dsi.thread = kthread_create(dsi_update_thread, NULL, "dsi");
-	if (IS_ERR(dsi.thread)) {
-		DSSERR("cannot create kthread\n");
-		r = PTR_ERR(dsi.thread);
-		goto err0;
-	}
-	sched_setscheduler(dsi.thread, SCHED_FIFO, &param);
-
-	init_waitqueue_head(&dsi.waitqueue);
-	spin_lock_init(&dsi.update_lock);
 
 	mutex_init(&dsi.lock);
-	mutex_init(&dsi.bus_lock);
+	sema_init(&dsi.bus_lock, 1);
+
+	INIT_WORK(&dsi.framedone_work, dsi_framedone_work_callback);
+	INIT_DELAYED_WORK_DEFERRABLE(&dsi.framedone_timeout_work,
+			dsi_framedone_timeout_work_callback);
 
 #ifdef DSI_CATCH_MISSING_TE
 	init_timer(&dsi.te_timer);
 	dsi.te_timer.function = dsi_te_timeout;
 	dsi.te_timer.data = 0;
 #endif
-
-	dsi.update_mode = OMAP_DSS_UPDATE_DISABLED;
-	dsi.user_update_mode = OMAP_DSS_UPDATE_DISABLED;
-
 	dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS);
 	if (!dsi.base) {
 		DSSERR("can't ioremap DSI\n");
@@ -3799,7 +3308,7 @@ int dsi_init(struct platform_device *pde
 		goto err1;
 	}
 
-	dsi.vdds_dsi_reg = regulator_get(&pdev->dev, "vdds_dsi");
+	dsi.vdds_dsi_reg = dss_get_vdds_dsi();
 	if (IS_ERR(dsi.vdds_dsi_reg)) {
 		iounmap(dsi.base);
 		DSSERR("can't get VDDS_DSI regulator\n");
@@ -3815,23 +3324,15 @@ int dsi_init(struct platform_device *pde
 
 	enable_clocks(0);
 
-	wake_up_process(dsi.thread);
-
 	return 0;
 err2:
 	iounmap(dsi.base);
 err1:
-	kthread_stop(dsi.thread);
-err0:
 	return r;
 }
 
 void dsi_exit(void)
 {
-	kthread_stop(dsi.thread);
-
-	regulator_put(dsi.vdds_dsi_reg);
-
 	iounmap(dsi.base);
 
 	DSSDBG("omap_dsi_exit\n");
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/dss.c linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/dss.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/dss.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/dss.c	2010-05-16 17:17:36.000000000 -0400
@@ -68,6 +68,9 @@ static struct {
 	struct dss_clock_info cache_dss_cinfo;
 	struct dispc_clock_info cache_dispc_cinfo;
 
+	enum dss_clk_source dsi_clk_source;
+	enum dss_clk_source dispc_clk_source;
+
 	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
 } dss;
 
@@ -247,23 +250,42 @@ void dss_dump_regs(struct seq_file *s)
 #undef DUMPREG
 }
 
-void dss_select_clk_source(bool dsi, bool dispc)
+void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
 {
-	u32 r;
-	r = dss_read_reg(DSS_CONTROL);
-	r = FLD_MOD(r, dsi, 1, 1);	/* DSI_CLK_SWITCH */
-	r = FLD_MOD(r, dispc, 0, 0);	/* DISPC_CLK_SWITCH */
-	dss_write_reg(DSS_CONTROL, r);
+	int b;
+
+	BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK &&
+			clk_src != DSS_SRC_DSS1_ALWON_FCLK);
+
+	b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
+
+	REG_FLD_MOD(DSS_CONTROL, b, 0, 0);	/* DISPC_CLK_SWITCH */
+
+	dss.dispc_clk_source = clk_src;
 }
 
-int dss_get_dsi_clk_source(void)
+void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
 {
-	return FLD_GET(dss_read_reg(DSS_CONTROL), 1, 1);
+	int b;
+
+	BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK &&
+			clk_src != DSS_SRC_DSS1_ALWON_FCLK);
+
+	b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
+
+	REG_FLD_MOD(DSS_CONTROL, b, 1, 1);	/* DSI_CLK_SWITCH */
+
+	dss.dsi_clk_source = clk_src;
 }
 
-int dss_get_dispc_clk_source(void)
+enum dss_clk_source dss_get_dispc_clk_source(void)
 {
-	return FLD_GET(dss_read_reg(DSS_CONTROL), 0, 0);
+	return dss.dispc_clk_source;
+}
+
+enum dss_clk_source dss_get_dsi_clk_source(void)
+{
+	return dss.dsi_clk_source;
 }
 
 /* calculate clock rates using dividers in cinfo */
@@ -568,6 +590,9 @@ int dss_init(bool skip_init)
 		}
 	}
 
+	dss.dsi_clk_source = DSS_SRC_DSS1_ALWON_FCLK;
+	dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK;
+
 	dss_save_context();
 
 	rev = dss_read_reg(DSS_REVISION);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/dss.h linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/dss.h
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/dss.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/dss.h	2010-05-16 17:17:36.000000000 -0400
@@ -119,6 +119,12 @@ enum dss_clock {
 	DSS_CLK_96M	= 1 << 4,
 };
 
+enum dss_clk_source {
+	DSS_SRC_DSI1_PLL_FCLK,
+	DSS_SRC_DSI2_PLL_FCLK,
+	DSS_SRC_DSS1_ALWON_FCLK,
+};
+
 struct dss_clock_info {
 	/* rates that we get with dividers below */
 	unsigned long fck;
@@ -169,6 +175,9 @@ unsigned long dss_clk_get_rate(enum dss_
 int dss_need_ctx_restore(void);
 void dss_dump_clocks(struct seq_file *s);
 struct bus_type *dss_get_bus(void);
+struct regulator *dss_get_vdds_dsi(void);
+struct regulator *dss_get_vdds_sdi(void);
+struct regulator *dss_get_vdda_dac(void);
 
 /* display */
 int dss_suspend_all_devices(void);
@@ -216,9 +225,11 @@ void dss_sdi_init(u8 datapairs);
 int dss_sdi_enable(void);
 void dss_sdi_disable(void);
 
-void dss_select_clk_source(bool dsi, bool dispc);
-int dss_get_dsi_clk_source(void);
-int dss_get_dispc_clk_source(void);
+void dss_select_dispc_clk_source(enum dss_clk_source clk_src);
+void dss_select_dsi_clk_source(enum dss_clk_source clk_src);
+enum dss_clk_source dss_get_dispc_clk_source(void);
+enum dss_clk_source dss_get_dsi_clk_source(void);
+
 void dss_set_venc_output(enum omap_dss_venc_type type);
 void dss_set_dac_pwrdn_bgz(bool enable);
 
@@ -261,7 +272,7 @@ void dsi_get_overlay_fifo_thresholds(enu
 		u32 *fifo_low, u32 *fifo_high);
 
 /* DPI */
-int dpi_init(void);
+int dpi_init(struct platform_device *pdev);
 void dpi_exit(void);
 int dpi_init_display(struct omap_dss_device *dssdev);
 
@@ -313,8 +324,8 @@ int dispc_setup_plane(enum omap_plane pl
 
 bool dispc_go_busy(enum omap_channel channel);
 void dispc_go(enum omap_channel channel);
-void dispc_enable_lcd_out(bool enable);
-void dispc_enable_digit_out(bool enable);
+void dispc_enable_channel(enum omap_channel channel, bool enable);
+bool dispc_is_channel_enabled(enum omap_channel channel);
 int dispc_enable_plane(enum omap_plane plane, bool enable);
 void dispc_enable_replication(enum omap_plane plane, bool enable);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/Kconfig linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -30,19 +30,29 @@ config OMAP2_DSS_COLLECT_IRQ_STATS
 	depends on OMAP2_DSS_DEBUG_SUPPORT
 	default n
 	help
-	  Collect DSS IRQ statistics, printable via debugfs
+	  Collect DSS IRQ statistics, printable via debugfs.
+
+	  The statistics can be found from
+	  <debugfs>/omapdss/dispc_irq for DISPC interrupts, and
+	  <debugfs>/omapdss/dsi_irq for DSI interrupts.
 
 config OMAP2_DSS_RFBI
 	bool "RFBI support"
         default n
 	help
-	  MIPI DBI, or RFBI (Remote Framebuffer Interface), support.
+	  MIPI DBI support (RFBI, Remote Framebuffer Interface, in Texas
+	  Instrument's terminology).
+
+	  DBI is a bus between the host processor and a peripheral,
+	  such as a display or a framebuffer chip.
+
+	  See http://www.mipi.org/ for DBI spesifications.
 
 config OMAP2_DSS_VENC
 	bool "VENC support"
         default y
 	help
-	  OMAP Video Encoder support.
+	  OMAP Video Encoder support for S-Video and composite TV-out.
 
 config OMAP2_DSS_SDI
 	bool "SDI support"
@@ -51,12 +61,20 @@ config OMAP2_DSS_SDI
 	help
 	  SDI (Serial Display Interface) support.
 
+	  SDI is a high speed one-way display serial bus between the host
+	  processor and a display.
+
 config OMAP2_DSS_DSI
 	bool "DSI support"
 	depends on ARCH_OMAP3
         default n
 	help
-	  MIPI DSI support.
+	  MIPI DSI (Display Serial Interface) support.
+
+	  DSI is a high speed half-duplex serial interface between the host
+	  processor and a peripheral, such as a display or a framebuffer chip.
+
+	  See http://www.mipi.org/ for DSI spesifications.
 
 config OMAP2_DSS_USE_DSI_PLL
 	bool "Use DSI PLL for PCLK (EXPERIMENTAL)"
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/manager.c linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/manager.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/manager.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/manager.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #define DSS_SUBSYS_NAME "MANAGER"
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
@@ -341,7 +342,7 @@ static ssize_t manager_attr_store(struct
 	return manager_attr->store(manager, buf, size);
 }
 
-static struct sysfs_ops manager_sysfs_ops = {
+static const struct sysfs_ops manager_sysfs_ops = {
 	.show = manager_attr_show,
 	.store = manager_attr_store,
 };
@@ -501,6 +502,19 @@ static int omap_dss_unset_device(struct
 	return 0;
 }
 
+static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
+{
+	unsigned long timeout = msecs_to_jiffies(500);
+	u32 irq;
+
+	if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC)
+		irq = DISPC_IRQ_EVSYNC_ODD;
+	else
+		irq = DISPC_IRQ_VSYNC;
+
+	return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
+}
+
 static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
 {
 	unsigned long timeout = msecs_to_jiffies(500);
@@ -509,17 +523,18 @@ static int dss_mgr_wait_for_go(struct om
 	u32 irq;
 	int r;
 	int i;
+	struct omap_dss_device *dssdev = mgr->device;
 
-	if (!mgr->device)
+	if (!dssdev)
 		return 0;
 
-	if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
+	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
 		irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
 		channel = OMAP_DSS_CHANNEL_DIGIT;
 	} else {
-		if (mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
+		if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
 			enum omap_dss_update_mode mode;
-			mode = mgr->device->get_update_mode(mgr->device);
+			mode = dssdev->driver->get_update_mode(dssdev);
 			if (mode != OMAP_DSS_UPDATE_AUTO)
 				return 0;
 
@@ -592,7 +607,7 @@ int dss_mgr_wait_for_go_ovl(struct omap_
 	} else {
 		if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
 			enum omap_dss_update_mode mode;
-			mode = dssdev->get_update_mode(dssdev);
+			mode = dssdev->driver->get_update_mode(dssdev);
 			if (mode != OMAP_DSS_UPDATE_AUTO)
 				return 0;
 
@@ -1064,7 +1079,7 @@ void dss_start_update(struct omap_dss_de
 		mc->shadow_dirty = false;
 	}
 
-	dispc_enable_lcd_out(1);
+	dssdev->manager->enable(dssdev->manager);
 }
 
 static void dss_apply_irq_handler(void *data, u32 mask)
@@ -1196,7 +1211,8 @@ static int omap_dss_mgr_apply(struct oma
 
 		oc->manual_update =
 			dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
-			dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO;
+			dssdev->driver->get_update_mode(dssdev) !=
+				OMAP_DSS_UPDATE_AUTO;
 
 		++num_planes_enabled;
 	}
@@ -1237,7 +1253,8 @@ static int omap_dss_mgr_apply(struct oma
 
 		mc->manual_update =
 			dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
-			dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO;
+			dssdev->driver->get_update_mode(dssdev) !=
+				OMAP_DSS_UPDATE_AUTO;
 	}
 
 	/* XXX TODO: Try to get fifomerge working. The problem is that it
@@ -1351,6 +1368,18 @@ static void omap_dss_mgr_get_info(struct
 	*info = mgr->info;
 }
 
+static int dss_mgr_enable(struct omap_overlay_manager *mgr)
+{
+	dispc_enable_channel(mgr->id, 1);
+	return 0;
+}
+
+static int dss_mgr_disable(struct omap_overlay_manager *mgr)
+{
+	dispc_enable_channel(mgr->id, 0);
+	return 0;
+}
+
 static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager)
 {
 	++num_managers;
@@ -1394,6 +1423,10 @@ int dss_init_overlay_managers(struct pla
 		mgr->set_manager_info = &omap_dss_mgr_set_info;
 		mgr->get_manager_info = &omap_dss_mgr_get_info;
 		mgr->wait_for_go = &dss_mgr_wait_for_go;
+		mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
+
+		mgr->enable = &dss_mgr_enable;
+		mgr->disable = &dss_mgr_disable;
 
 		mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/overlay.c linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/overlay.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/overlay.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/overlay.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/kobject.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <plat/display.h>
 #include <plat/cpu.h>
@@ -320,7 +321,7 @@ static ssize_t overlay_attr_store(struct
 	return overlay_attr->store(overlay, buf, size);
 }
 
-static struct sysfs_ops overlay_sysfs_ops = {
+static const struct sysfs_ops overlay_sysfs_ops = {
 	.show = overlay_attr_show,
 	.store = overlay_attr_store,
 };
@@ -350,7 +351,7 @@ int dss_check_overlay(struct omap_overla
 		return -EINVAL;
 	}
 
-	dssdev->get_resolution(dssdev, &dw, &dh);
+	dssdev->driver->get_resolution(dssdev, &dw, &dh);
 
 	DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n",
 			ovl->id,
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/rfbi.c linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/rfbi.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/rfbi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/rfbi.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,8 +36,6 @@
 #include <plat/display.h>
 #include "dss.h"
 
-/*#define MEASURE_PERF*/
-
 #define RFBI_BASE               0x48050800
 
 struct rfbi_reg { u16 idx; };
@@ -66,8 +64,6 @@ struct rfbi_reg { u16 idx; };
 #define RFBI_VSYNC_WIDTH	RFBI_REG(0x0090)
 #define RFBI_HSYNC_WIDTH	RFBI_REG(0x0094)
 
-#define RFBI_CMD_FIFO_LEN_BYTES (16 * sizeof(struct update_param))
-
 #define REG_FLD_MOD(idx, val, start, end) \
 	rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end))
 
@@ -102,7 +98,6 @@ enum update_cmd {
 
 static int rfbi_convert_timings(struct rfbi_timings *t);
 static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
-static void process_cmd_fifo(void);
 
 static struct {
 	void __iomem	*base;
@@ -125,11 +120,6 @@ static struct {
 	struct completion cmd_done;
 	atomic_t          cmd_fifo_full;
 	atomic_t          cmd_pending;
-#ifdef MEASURE_PERF
-	unsigned perf_bytes;
-	ktime_t perf_setup_time;
-	ktime_t perf_start_time;
-#endif
 } rfbi;
 
 struct update_region {
@@ -139,16 +129,6 @@ struct update_region {
 	u16     h;
 };
 
-struct update_param {
-	u8 rfbi_module;
-	u8 cmd;
-
-	union {
-		struct update_region r;
-		struct completion *sync;
-	} par;
-};
-
 static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
 {
 	__raw_writel(val, rfbi.base + idx.idx);
@@ -321,55 +301,6 @@ void omap_rfbi_write_pixels(const void _
 }
 EXPORT_SYMBOL(omap_rfbi_write_pixels);
 
-#ifdef MEASURE_PERF
-static void perf_mark_setup(void)
-{
-	rfbi.perf_setup_time = ktime_get();
-}
-
-static void perf_mark_start(void)
-{
-	rfbi.perf_start_time = ktime_get();
-}
-
-static void perf_show(const char *name)
-{
-	ktime_t t, setup_time, trans_time;
-	u32 total_bytes;
-	u32 setup_us, trans_us, total_us;
-
-	t = ktime_get();
-
-	setup_time = ktime_sub(rfbi.perf_start_time, rfbi.perf_setup_time);
-	setup_us = (u32)ktime_to_us(setup_time);
-	if (setup_us == 0)
-		setup_us = 1;
-
-	trans_time = ktime_sub(t, rfbi.perf_start_time);
-	trans_us = (u32)ktime_to_us(trans_time);
-	if (trans_us == 0)
-		trans_us = 1;
-
-	total_us = setup_us + trans_us;
-
-	total_bytes = rfbi.perf_bytes;
-
-	DSSINFO("%s update %u us + %u us = %u us (%uHz), %u bytes, "
-			"%u kbytes/sec\n",
-			name,
-			setup_us,
-			trans_us,
-			total_us,
-			1000*1000 / total_us,
-			total_bytes,
-			total_bytes * 1000 / total_us);
-}
-#else
-#define perf_mark_setup()
-#define perf_mark_start()
-#define perf_show(x)
-#endif
-
 void rfbi_transfer_area(u16 width, u16 height,
 			     void (callback)(void *data), void *data)
 {
@@ -382,7 +313,7 @@ void rfbi_transfer_area(u16 width, u16 h
 
 	dispc_set_lcd_size(width, height);
 
-	dispc_enable_lcd_out(1);
+	dispc_enable_channel(OMAP_DSS_CHANNEL_LCD, true);
 
 	rfbi.framedone_callback = callback;
 	rfbi.framedone_callback_data = data;
@@ -396,8 +327,6 @@ void rfbi_transfer_area(u16 width, u16 h
 	if (!rfbi.te_enabled)
 		l = FLD_MOD(l, 1, 4, 4); /* ITE */
 
-	perf_mark_start();
-
 	rfbi_write_reg(RFBI_CONTROL, l);
 }
 
@@ -407,8 +336,6 @@ static void framedone_callback(void *dat
 
 	DSSDBG("FRAMEDONE\n");
 
-	perf_show("DISPC");
-
 	REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0);
 
 	rfbi_enable_clocks(0);
@@ -416,11 +343,10 @@ static void framedone_callback(void *dat
 	callback = rfbi.framedone_callback;
 	rfbi.framedone_callback = NULL;
 
-	/*callback(rfbi.framedone_callback_data);*/
+	if (callback != NULL)
+		callback(rfbi.framedone_callback_data);
 
 	atomic_set(&rfbi.cmd_pending, 0);
-
-	process_cmd_fifo();
 }
 
 #if 1 /* VERBOSE */
@@ -937,52 +863,43 @@ int rfbi_configure(int rfbi_module, int
 }
 EXPORT_SYMBOL(rfbi_configure);
 
-static int rfbi_find_display(struct omap_dss_device *dssdev)
+int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
+		u16 *x, u16 *y, u16 *w, u16 *h)
 {
-	if (dssdev == rfbi.dssdev[0])
-		return 0;
+	u16 dw, dh;
 
-	if (dssdev == rfbi.dssdev[1])
-		return 1;
+	dssdev->driver->get_resolution(dssdev, &dw, &dh);
 
-	BUG();
-	return -1;
-}
+	if  (*x > dw || *y > dh)
+		return -EINVAL;
 
+	if (*x + *w > dw)
+		return -EINVAL;
 
-static void signal_fifo_waiters(void)
-{
-	if (atomic_read(&rfbi.cmd_fifo_full) > 0) {
-		/* DSSDBG("SIGNALING: Fifo not full for waiter!\n"); */
-		complete(&rfbi.cmd_done);
-		atomic_dec(&rfbi.cmd_fifo_full);
-	}
-}
+	if (*y + *h > dh)
+		return -EINVAL;
 
-/* returns 1 for async op, and 0 for sync op */
-static int do_update(struct omap_dss_device *dssdev, struct update_region *upd)
-{
-	u16 x = upd->x;
-	u16 y = upd->y;
-	u16 w = upd->w;
-	u16 h = upd->h;
+	if (*w == 1)
+		return -EINVAL;
 
-	perf_mark_setup();
+	if (*w == 0 || *h == 0)
+		return -EINVAL;
 
 	if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
-		/*dssdev->driver->enable_te(dssdev, 1); */
-		dss_setup_partial_planes(dssdev, &x, &y, &w, &h);
+		dss_setup_partial_planes(dssdev, x, y, w, h);
+		dispc_set_lcd_size(*w, *h);
 	}
 
-#ifdef MEASURE_PERF
-	rfbi.perf_bytes = w * h * 2; /* XXX always 16bit */
-#endif
-
-	dssdev->driver->setup_update(dssdev, x, y, w, h);
+	return 0;
+}
+EXPORT_SYMBOL(omap_rfbi_prepare_update);
 
+int omap_rfbi_update(struct omap_dss_device *dssdev,
+		u16 x, u16 y, u16 w, u16 h,
+		void (*callback)(void *), void *data)
+{
 	if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
-		rfbi_transfer_area(w, h, NULL, NULL);
-		return 1;
+		rfbi_transfer_area(w, h, callback, data);
 	} else {
 		struct omap_overlay *ovl;
 		void __iomem *addr;
@@ -994,123 +911,12 @@ static int do_update(struct omap_dss_dev
 
 		omap_rfbi_write_pixels(addr, scr_width, x, y, w, h);
 
-		perf_show("L4");
-
-		return 0;
-	}
-}
-
-static void process_cmd_fifo(void)
-{
-	int len;
-	struct update_param p;
-	struct omap_dss_device *dssdev;
-	unsigned long flags;
-
-	if (atomic_inc_return(&rfbi.cmd_pending) != 1)
-		return;
-
-	while (true) {
-		spin_lock_irqsave(&rfbi.cmd_lock, flags);
-
-		len = kfifo_out(&rfbi.cmd_fifo, (unsigned char *)&p,
-				  sizeof(struct update_param));
-		if (len == 0) {
-			DSSDBG("nothing more in fifo\n");
-			atomic_set(&rfbi.cmd_pending, 0);
-			spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
-			break;
-		}
-
-		/* DSSDBG("fifo full %d\n", rfbi.cmd_fifo_full.counter);*/
-
-		spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
-
-		BUG_ON(len != sizeof(struct update_param));
-		BUG_ON(p.rfbi_module > 1);
-
-		dssdev = rfbi.dssdev[p.rfbi_module];
-
-		if (p.cmd == RFBI_CMD_UPDATE) {
-			if (do_update(dssdev, &p.par.r))
-				break; /* async op */
-		} else if (p.cmd == RFBI_CMD_SYNC) {
-			DSSDBG("Signaling SYNC done!\n");
-			complete(p.par.sync);
-		} else
-			BUG();
-	}
-
-	signal_fifo_waiters();
-}
-
-static void rfbi_push_cmd(struct update_param *p)
-{
-	int ret;
-
-	while (1) {
-		unsigned long flags;
-		int available;
-
-		spin_lock_irqsave(&rfbi.cmd_lock, flags);
-		available = RFBI_CMD_FIFO_LEN_BYTES -
-			kfifo_len(&rfbi.cmd_fifo);
-
-/*		DSSDBG("%d bytes left in fifo\n", available); */
-		if (available < sizeof(struct update_param)) {
-			DSSDBG("Going to wait because FIFO FULL..\n");
-			spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
-			atomic_inc(&rfbi.cmd_fifo_full);
-			wait_for_completion(&rfbi.cmd_done);
-			/*DSSDBG("Woke up because fifo not full anymore\n");*/
-			continue;
-		}
-
-		ret = kfifo_in(&rfbi.cmd_fifo, (unsigned char *)p,
-				  sizeof(struct update_param));
-/*		DSSDBG("pushed %d bytes\n", ret);*/
-
-		spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
-
-		BUG_ON(ret != sizeof(struct update_param));
-
-		break;
+		callback(data);
 	}
-}
-
-static void rfbi_push_update(int rfbi_module, int x, int y, int w, int h)
-{
-	struct update_param p;
-
-	p.rfbi_module = rfbi_module;
-	p.cmd = RFBI_CMD_UPDATE;
-
-	p.par.r.x = x;
-	p.par.r.y = y;
-	p.par.r.w = w;
-	p.par.r.h = h;
-
-	DSSDBG("RFBI pushed %d,%d %dx%d\n", x, y, w, h);
-
-	rfbi_push_cmd(&p);
-
-	process_cmd_fifo();
-}
-
-static void rfbi_push_sync(int rfbi_module, struct completion *sync_comp)
-{
-	struct update_param p;
-
-	p.rfbi_module = rfbi_module;
-	p.cmd = RFBI_CMD_SYNC;
-	p.par.sync = sync_comp;
-
-	rfbi_push_cmd(&p);
-
-	DSSDBG("RFBI sync pushed to cmd fifo\n");
 
-	process_cmd_fifo();
+	return 0;
 }
+EXPORT_SYMBOL(omap_rfbi_update);
 
 void rfbi_dump_regs(struct seq_file *s)
 {
@@ -1155,12 +961,8 @@ int rfbi_init(void)
 {
 	u32 rev;
 	u32 l;
-	int r;
 
 	spin_lock_init(&rfbi.cmd_lock);
-	r = kfifo_alloc(&rfbi.cmd_fifo, RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL);
-	if (r)
-		return r;
 
 	init_completion(&rfbi.cmd_done);
 	atomic_set(&rfbi.cmd_fifo_full, 0);
@@ -1196,49 +998,10 @@ void rfbi_exit(void)
 {
 	DSSDBG("rfbi_exit\n");
 
-	kfifo_free(&rfbi.cmd_fifo);
-
 	iounmap(rfbi.base);
 }
 
-/* struct omap_display support */
-static int rfbi_display_update(struct omap_dss_device *dssdev,
-			u16 x, u16 y, u16 w, u16 h)
-{
-	int rfbi_module;
-
-	if (w == 0 || h == 0)
-		return 0;
-
-	rfbi_module = rfbi_find_display(dssdev);
-
-	rfbi_push_update(rfbi_module, x, y, w, h);
-
-	return 0;
-}
-
-static int rfbi_display_sync(struct omap_dss_device *dssdev)
-{
-	struct completion sync_comp;
-	int rfbi_module;
-
-	rfbi_module = rfbi_find_display(dssdev);
-
-	init_completion(&sync_comp);
-	rfbi_push_sync(rfbi_module, &sync_comp);
-	DSSDBG("Waiting for SYNC to happen...\n");
-	wait_for_completion(&sync_comp);
-	DSSDBG("Released from SYNC\n");
-	return 0;
-}
-
-static int rfbi_display_enable_te(struct omap_dss_device *dssdev, bool enable)
-{
-	dssdev->driver->enable_te(dssdev, enable);
-	return 0;
-}
-
-static int rfbi_display_enable(struct omap_dss_device *dssdev)
+int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
 {
 	int r;
 
@@ -1269,41 +1032,25 @@ static int rfbi_display_enable(struct om
 			 &dssdev->ctrl.rfbi_timings);
 
 
-	if (dssdev->driver->enable) {
-		r = dssdev->driver->enable(dssdev);
-		if (r)
-			goto err2;
-	}
-
 	return 0;
-err2:
-	omap_dispc_unregister_isr(framedone_callback, NULL,
-			DISPC_IRQ_FRAMEDONE);
 err1:
 	omap_dss_stop_device(dssdev);
 err0:
 	return r;
 }
+EXPORT_SYMBOL(omapdss_rfbi_display_enable);
 
-static void rfbi_display_disable(struct omap_dss_device *dssdev)
+void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
 {
-	dssdev->driver->disable(dssdev);
 	omap_dispc_unregister_isr(framedone_callback, NULL,
 			DISPC_IRQ_FRAMEDONE);
 	omap_dss_stop_device(dssdev);
 }
+EXPORT_SYMBOL(omapdss_rfbi_display_disable);
 
 int rfbi_init_display(struct omap_dss_device *dssdev)
 {
-	dssdev->enable = rfbi_display_enable;
-	dssdev->disable = rfbi_display_disable;
-	dssdev->update = rfbi_display_update;
-	dssdev->sync = rfbi_display_sync;
-	dssdev->enable_te = rfbi_display_enable_te;
-
 	rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
-
 	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
-
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/sdi.c linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/sdi.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/sdi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/sdi.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,7 +41,7 @@ static void sdi_basic_init(void)
 	dispc_lcd_enable_signal_polarity(1);
 }
 
-static int sdi_display_enable(struct omap_dss_device *dssdev)
+int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
 {
 	struct omap_video_timings *t = &dssdev->panel.timings;
 	struct dss_clock_info dss_cinfo;
@@ -57,12 +57,6 @@ static int sdi_display_enable(struct oma
 		goto err0;
 	}
 
-	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
-		DSSERR("dssdev already enabled\n");
-		r = -EINVAL;
-		goto err1;
-	}
-
 	/* In case of skip_init sdi_init has already enabled the clocks */
 	if (!sdi.skip_init)
 		dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
@@ -119,7 +113,7 @@ static int sdi_display_enable(struct oma
 		mdelay(2);
 	}
 
-	dispc_enable_lcd_out(1);
+	dssdev->manager->enable(dssdev->manager);
 
 	if (dssdev->driver->enable) {
 		r = dssdev->driver->enable(dssdev);
@@ -127,13 +121,11 @@ static int sdi_display_enable(struct oma
 			goto err3;
 	}
 
-	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
 	sdi.skip_init = 0;
 
 	return 0;
 err3:
-	dispc_enable_lcd_out(0);
+	dssdev->manager->disable(dssdev->manager);
 err2:
 	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
 err1:
@@ -141,120 +133,27 @@ err1:
 err0:
 	return r;
 }
+EXPORT_SYMBOL(omapdss_sdi_display_enable);
 
-static int sdi_display_resume(struct omap_dss_device *dssdev);
-
-static void sdi_display_disable(struct omap_dss_device *dssdev)
+void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
 {
-	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
-		return;
-
-	if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
-		if (sdi_display_resume(dssdev))
-			return;
-
 	if (dssdev->driver->disable)
 		dssdev->driver->disable(dssdev);
 
-	dispc_enable_lcd_out(0);
+	dssdev->manager->disable(dssdev->manager);
 
 	dss_sdi_disable();
 
 	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
 
-	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-
 	omap_dss_stop_device(dssdev);
 }
-
-static int sdi_display_suspend(struct omap_dss_device *dssdev)
-{
-	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
-		return -EINVAL;
-
-	if (dssdev->driver->suspend)
-		dssdev->driver->suspend(dssdev);
-
-	dispc_enable_lcd_out(0);
-
-	dss_sdi_disable();
-
-	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
-
-	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-
-	return 0;
-}
-
-static int sdi_display_resume(struct omap_dss_device *dssdev)
-{
-	int r;
-
-	if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
-		return -EINVAL;
-
-	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
-
-	r = dss_sdi_enable();
-	if (r)
-		goto err;
-	mdelay(2);
-
-	dispc_enable_lcd_out(1);
-
-	if (dssdev->driver->resume)
-		dssdev->driver->resume(dssdev);
-
-	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-	return 0;
-err:
-	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
-	return r;
-}
-
-static int sdi_display_set_update_mode(struct omap_dss_device *dssdev,
-		enum omap_dss_update_mode mode)
-{
-	if (mode == OMAP_DSS_UPDATE_MANUAL)
-		return -EINVAL;
-
-	if (mode == OMAP_DSS_UPDATE_DISABLED) {
-		dispc_enable_lcd_out(0);
-		sdi.update_enabled = 0;
-	} else {
-		dispc_enable_lcd_out(1);
-		sdi.update_enabled = 1;
-	}
-
-	return 0;
-}
-
-static enum omap_dss_update_mode sdi_display_get_update_mode(
-		struct omap_dss_device *dssdev)
-{
-	return sdi.update_enabled ? OMAP_DSS_UPDATE_AUTO :
-		OMAP_DSS_UPDATE_DISABLED;
-}
-
-static void sdi_get_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
-{
-	*timings = dssdev->panel.timings;
-}
+EXPORT_SYMBOL(omapdss_sdi_display_disable);
 
 int sdi_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("SDI init\n");
 
-	dssdev->enable = sdi_display_enable;
-	dssdev->disable = sdi_display_disable;
-	dssdev->suspend = sdi_display_suspend;
-	dssdev->resume = sdi_display_resume;
-	dssdev->set_update_mode = sdi_display_set_update_mode;
-	dssdev->get_update_mode = sdi_display_get_update_mode;
-	dssdev->get_timings = sdi_get_timings;
-
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/venc.c linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/venc.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/dss/venc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/dss/venc.c	2010-05-16 17:17:36.000000000 -0400
@@ -400,114 +400,6 @@ static const struct venc_config *venc_ti
 	BUG();
 }
 
-
-
-
-
-/* driver */
-static int venc_panel_probe(struct omap_dss_device *dssdev)
-{
-	dssdev->panel.timings = omap_dss_pal_timings;
-
-	return 0;
-}
-
-static void venc_panel_remove(struct omap_dss_device *dssdev)
-{
-}
-
-static int venc_panel_enable(struct omap_dss_device *dssdev)
-{
-	int r = 0;
-
-	/* wait couple of vsyncs until enabling the LCD */
-	msleep(50);
-
-	if (dssdev->platform_enable)
-		r = dssdev->platform_enable(dssdev);
-
-	return r;
-}
-
-static void venc_panel_disable(struct omap_dss_device *dssdev)
-{
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
-
-	/* wait at least 5 vsyncs after disabling the LCD */
-
-	msleep(100);
-}
-
-static int venc_panel_suspend(struct omap_dss_device *dssdev)
-{
-	venc_panel_disable(dssdev);
-	return 0;
-}
-
-static int venc_panel_resume(struct omap_dss_device *dssdev)
-{
-	return venc_panel_enable(dssdev);
-}
-
-static struct omap_dss_driver venc_driver = {
-	.probe		= venc_panel_probe,
-	.remove		= venc_panel_remove,
-
-	.enable		= venc_panel_enable,
-	.disable	= venc_panel_disable,
-	.suspend	= venc_panel_suspend,
-	.resume		= venc_panel_resume,
-
-	.driver         = {
-		.name   = "venc",
-		.owner  = THIS_MODULE,
-	},
-};
-/* driver end */
-
-
-
-int venc_init(struct platform_device *pdev)
-{
-	u8 rev_id;
-
-	mutex_init(&venc.venc_lock);
-
-	venc.wss_data = 0;
-
-	venc.base = ioremap(VENC_BASE, SZ_1K);
-	if (!venc.base) {
-		DSSERR("can't ioremap VENC\n");
-		return -ENOMEM;
-	}
-
-	venc.vdda_dac_reg = regulator_get(&pdev->dev, "vdda_dac");
-	if (IS_ERR(venc.vdda_dac_reg)) {
-		iounmap(venc.base);
-		DSSERR("can't get VDDA_DAC regulator\n");
-		return PTR_ERR(venc.vdda_dac_reg);
-	}
-
-	venc_enable_clocks(1);
-
-	rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
-	printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
-
-	venc_enable_clocks(0);
-
-	return omap_dss_register_driver(&venc_driver);
-}
-
-void venc_exit(void)
-{
-	omap_dss_unregister_driver(&venc_driver);
-
-	regulator_put(venc.vdda_dac_reg);
-
-	iounmap(venc.base);
-}
-
 static void venc_power_on(struct omap_dss_device *dssdev)
 {
 	u32 l;
@@ -540,7 +432,7 @@ static void venc_power_on(struct omap_ds
 	if (dssdev->platform_enable)
 		dssdev->platform_enable(dssdev);
 
-	dispc_enable_digit_out(1);
+	dssdev->manager->enable(dssdev->manager);
 }
 
 static void venc_power_off(struct omap_dss_device *dssdev)
@@ -548,7 +440,7 @@ static void venc_power_off(struct omap_d
 	venc_write_reg(VENC_OUTPUT_CONTROL, 0);
 	dss_set_dac_pwrdn_bgz(0);
 
-	dispc_enable_digit_out(0);
+	dssdev->manager->disable(dssdev->manager);
 
 	if (dssdev->platform_disable)
 		dssdev->platform_disable(dssdev);
@@ -558,7 +450,23 @@ static void venc_power_off(struct omap_d
 	venc_enable_clocks(0);
 }
 
-static int venc_enable_display(struct omap_dss_device *dssdev)
+
+
+
+
+/* driver */
+static int venc_panel_probe(struct omap_dss_device *dssdev)
+{
+	dssdev->panel.timings = omap_dss_pal_timings;
+
+	return 0;
+}
+
+static void venc_panel_remove(struct omap_dss_device *dssdev)
+{
+}
+
+static int venc_panel_enable(struct omap_dss_device *dssdev)
 {
 	int r = 0;
 
@@ -568,7 +476,13 @@ static int venc_enable_display(struct om
 
 	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
 		r = -EINVAL;
-		goto err;
+		goto err1;
+	}
+
+	if (dssdev->platform_enable) {
+		r = dssdev->platform_enable(dssdev);
+		if (r)
+			goto err2;
 	}
 
 	venc_power_on(dssdev);
@@ -576,13 +490,21 @@ static int venc_enable_display(struct om
 	venc.wss_data = 0;
 
 	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-err:
+
+	/* wait couple of vsyncs until enabling the LCD */
+	msleep(50);
+
 	mutex_unlock(&venc.venc_lock);
 
 	return r;
+err2:
+	venc_power_off(dssdev);
+err1:
+	mutex_unlock(&venc.venc_lock);
+	return r;
 }
 
-static void venc_disable_display(struct omap_dss_device *dssdev)
+static void venc_panel_disable(struct omap_dss_device *dssdev)
 {
 	DSSDBG("venc_disable_display\n");
 
@@ -599,53 +521,40 @@ static void venc_disable_display(struct
 
 	venc_power_off(dssdev);
 
+	/* wait at least 5 vsyncs after disabling the LCD */
+	msleep(100);
+
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
+
 	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 end:
 	mutex_unlock(&venc.venc_lock);
 }
 
-static int venc_display_suspend(struct omap_dss_device *dssdev)
+static int venc_panel_suspend(struct omap_dss_device *dssdev)
 {
-	int r = 0;
-
-	DSSDBG("venc_display_suspend\n");
-
-	mutex_lock(&venc.venc_lock);
-
-	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
-		r = -EINVAL;
-		goto err;
-	}
-
-	venc_power_off(dssdev);
-
-	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-err:
-	mutex_unlock(&venc.venc_lock);
-
-	return r;
+	venc_panel_disable(dssdev);
+	return 0;
 }
 
-static int venc_display_resume(struct omap_dss_device *dssdev)
+static int venc_panel_resume(struct omap_dss_device *dssdev)
 {
-	int r = 0;
-
-	DSSDBG("venc_display_resume\n");
-
-	mutex_lock(&venc.venc_lock);
-
-	if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
-		r = -EINVAL;
-		goto err;
-	}
-
-	venc_power_on(dssdev);
+	return venc_panel_enable(dssdev);
+}
 
-	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-err:
-	mutex_unlock(&venc.venc_lock);
+static enum omap_dss_update_mode venc_get_update_mode(
+		struct omap_dss_device *dssdev)
+{
+	return OMAP_DSS_UPDATE_AUTO;
+}
 
-	return r;
+static int venc_set_update_mode(struct omap_dss_device *dssdev,
+		enum omap_dss_update_mode mode)
+{
+	if (mode != OMAP_DSS_UPDATE_AUTO)
+		return -EINVAL;
+	return 0;
 }
 
 static void venc_get_timings(struct omap_dss_device *dssdev,
@@ -666,8 +575,8 @@ static void venc_set_timings(struct omap
 	dssdev->panel.timings = *timings;
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
 		/* turn the venc off and on to get new timings to use */
-		venc_disable_display(dssdev);
-		venc_enable_display(dssdev);
+		venc_panel_disable(dssdev);
+		venc_panel_enable(dssdev);
 	}
 }
 
@@ -716,30 +625,79 @@ static int venc_set_wss(struct omap_dss_
 	return 0;
 }
 
-static enum omap_dss_update_mode venc_display_get_update_mode(
-		struct omap_dss_device *dssdev)
+static struct omap_dss_driver venc_driver = {
+	.probe		= venc_panel_probe,
+	.remove		= venc_panel_remove,
+
+	.enable		= venc_panel_enable,
+	.disable	= venc_panel_disable,
+	.suspend	= venc_panel_suspend,
+	.resume		= venc_panel_resume,
+
+	.get_resolution	= omapdss_default_get_resolution,
+	.get_recommended_bpp = omapdss_default_get_recommended_bpp,
+
+	.set_update_mode = venc_set_update_mode,
+	.get_update_mode = venc_get_update_mode,
+
+	.get_timings	= venc_get_timings,
+	.set_timings	= venc_set_timings,
+	.check_timings	= venc_check_timings,
+
+	.get_wss	= venc_get_wss,
+	.set_wss	= venc_set_wss,
+
+	.driver         = {
+		.name   = "venc",
+		.owner  = THIS_MODULE,
+	},
+};
+/* driver end */
+
+
+
+int venc_init(struct platform_device *pdev)
 {
-	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
-		return OMAP_DSS_UPDATE_AUTO;
-	else
-		return OMAP_DSS_UPDATE_DISABLED;
+	u8 rev_id;
+
+	mutex_init(&venc.venc_lock);
+
+	venc.wss_data = 0;
+
+	venc.base = ioremap(VENC_BASE, SZ_1K);
+	if (!venc.base) {
+		DSSERR("can't ioremap VENC\n");
+		return -ENOMEM;
+	}
+
+	venc.vdda_dac_reg = dss_get_vdda_dac();
+	if (IS_ERR(venc.vdda_dac_reg)) {
+		iounmap(venc.base);
+		DSSERR("can't get VDDA_DAC regulator\n");
+		return PTR_ERR(venc.vdda_dac_reg);
+	}
+
+	venc_enable_clocks(1);
+
+	rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
+	printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
+
+	venc_enable_clocks(0);
+
+	return omap_dss_register_driver(&venc_driver);
+}
+
+void venc_exit(void)
+{
+	omap_dss_unregister_driver(&venc_driver);
+
+	iounmap(venc.base);
 }
 
 int venc_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("init_display\n");
 
-	dssdev->enable = venc_enable_display;
-	dssdev->disable = venc_disable_display;
-	dssdev->suspend = venc_display_suspend;
-	dssdev->resume = venc_display_resume;
-	dssdev->get_timings = venc_get_timings;
-	dssdev->set_timings = venc_set_timings;
-	dssdev->check_timings = venc_check_timings;
-	dssdev->get_wss = venc_get_wss;
-	dssdev->set_wss = venc_set_wss;
-	dssdev->get_update_mode = venc_display_get_update_mode;
-
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/omapfb/Kconfig linux-libre-2.6.34-gnu1/drivers/video/omap2/omapfb/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/omapfb/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/omapfb/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -16,16 +16,7 @@ config FB_OMAP2_DEBUG_SUPPORT
 	depends on FB_OMAP2
 	help
 	  Support for debug output. You have to enable the actual printing
-	  with debug module parameter.
-
-config FB_OMAP2_FORCE_AUTO_UPDATE
-	bool "Force main display to automatic update mode"
-	depends on FB_OMAP2
-	help
-	  Forces main display to automatic update mode (if possible),
-	  and also enables tearsync (if possible). By default
-	  displays that support manual update are started in manual
-	  update mode.
+	  with 'debug' module parameter.
 
 config FB_OMAP2_NUM_FBS
 	int "Number of framebuffers"
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/omapfb/omapfb.h linux-libre-2.6.34-gnu1/drivers/video/omap2/omapfb/omapfb.h
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/omapfb/omapfb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/omapfb/omapfb.h	2010-05-16 17:17:36.000000000 -0400
@@ -83,6 +83,12 @@ struct omapfb2_device {
 	struct omap_overlay *overlays[10];
 	unsigned num_managers;
 	struct omap_overlay_manager *managers[10];
+
+	unsigned num_bpp_overrides;
+	struct {
+		struct omap_dss_device *dssdev;
+		u8 bpp;
+	} bpp_overrides[10];
 };
 
 struct omapfb_colormode {
@@ -105,6 +111,9 @@ void omapfb_remove_sysfs(struct omapfb2_
 
 int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg);
 
+int omapfb_update_window(struct fb_info *fbi,
+		u32 x, u32 y, u32 w, u32 h);
+
 int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
 			struct fb_var_screeninfo *var);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/omapfb/omapfb-ioctl.c linux-libre-2.6.34-gnu1/drivers/video/omap2/omapfb/omapfb-ioctl.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/omapfb/omapfb-ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/omapfb/omapfb-ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -167,12 +167,12 @@ static int omapfb_update_window_nolock(s
 	if (w == 0 || h == 0)
 		return 0;
 
-	display->get_resolution(display, &dw, &dh);
+	display->driver->get_resolution(display, &dw, &dh);
 
 	if (x + w > dw || y + h > dh)
 		return -EINVAL;
 
-	return display->update(display, x, y, w, h);
+	return display->driver->update(display, x, y, w, h);
 }
 
 /* This function is exported for SGX driver use */
@@ -202,7 +202,7 @@ static int omapfb_set_update_mode(struct
 	enum omap_dss_update_mode um;
 	int r;
 
-	if (!display || !display->set_update_mode)
+	if (!display || !display->driver->set_update_mode)
 		return -EINVAL;
 
 	switch (mode) {
@@ -222,7 +222,7 @@ static int omapfb_set_update_mode(struct
 		return -EINVAL;
 	}
 
-	r = display->set_update_mode(display, um);
+	r = display->driver->set_update_mode(display, um);
 
 	return r;
 }
@@ -233,10 +233,15 @@ static int omapfb_get_update_mode(struct
 	struct omap_dss_device *display = fb2display(fbi);
 	enum omap_dss_update_mode m;
 
-	if (!display || !display->get_update_mode)
+	if (!display)
 		return -EINVAL;
 
-	m = display->get_update_mode(display);
+	if (!display->driver->get_update_mode) {
+		*mode = OMAPFB_AUTO_UPDATE;
+		return 0;
+	}
+
+	m = display->driver->get_update_mode(display);
 
 	switch (m) {
 	case OMAP_DSS_UPDATE_DISABLED:
@@ -374,7 +379,7 @@ static int omapfb_memory_read(struct fb_
 	void *buf;
 	int r;
 
-	if (!display || !display->memory_read)
+	if (!display || !display->driver->memory_read)
 		return -ENOENT;
 
 	if (!access_ok(VERIFY_WRITE, mr->buffer, mr->buffer_size))
@@ -389,7 +394,7 @@ static int omapfb_memory_read(struct fb_
 		return -ENOMEM;
 	}
 
-	r = display->memory_read(display, buf, mr->buffer_size,
+	r = display->driver->memory_read(display, buf, mr->buffer_size,
 			mr->x, mr->y, mr->w, mr->h);
 
 	if (r > 0) {
@@ -483,6 +488,7 @@ int omapfb_ioctl(struct fb_info *fbi, un
 		struct omapfb_memory_read	memory_read;
 		struct omapfb_vram_info		vram_info;
 		struct omapfb_tearsync_info	tearsync_info;
+		struct omapfb_display_info	display_info;
 	} p;
 
 	int r = 0;
@@ -490,18 +496,18 @@ int omapfb_ioctl(struct fb_info *fbi, un
 	switch (cmd) {
 	case OMAPFB_SYNC_GFX:
 		DBG("ioctl SYNC_GFX\n");
-		if (!display || !display->sync) {
+		if (!display || !display->driver->sync) {
 			/* DSS1 never returns an error here, so we neither */
 			/*r = -EINVAL;*/
 			break;
 		}
 
-		r = display->sync(display);
+		r = display->driver->sync(display);
 		break;
 
 	case OMAPFB_UPDATE_WINDOW_OLD:
 		DBG("ioctl UPDATE_WINDOW_OLD\n");
-		if (!display || !display->update) {
+		if (!display || !display->driver->update) {
 			r = -EINVAL;
 			break;
 		}
@@ -519,7 +525,7 @@ int omapfb_ioctl(struct fb_info *fbi, un
 
 	case OMAPFB_UPDATE_WINDOW:
 		DBG("ioctl UPDATE_WINDOW\n");
-		if (!display || !display->update) {
+		if (!display || !display->driver->update) {
 			r = -EINVAL;
 			break;
 		}
@@ -648,7 +654,7 @@ int omapfb_ioctl(struct fb_info *fbi, un
 			break;
 		}
 
-		r = display->wait_vsync(display);
+		r = display->manager->wait_for_vsync(display->manager);
 		break;
 
 	case OMAPFB_WAITFORGO:
@@ -669,12 +675,12 @@ int omapfb_ioctl(struct fb_info *fbi, un
 			r = -EFAULT;
 			break;
 		}
-		if (!display || !display->run_test) {
+		if (!display || !display->driver->run_test) {
 			r = -EINVAL;
 			break;
 		}
 
-		r = display->run_test(display, p.test_num);
+		r = display->driver->run_test(display, p.test_num);
 
 		break;
 
@@ -684,12 +690,12 @@ int omapfb_ioctl(struct fb_info *fbi, un
 			r = -EFAULT;
 			break;
 		}
-		if (!display || !display->run_test) {
+		if (!display || !display->driver->run_test) {
 			r = -EINVAL;
 			break;
 		}
 
-		r = display->run_test(display, p.test_num);
+		r = display->driver->run_test(display, p.test_num);
 
 		break;
 
@@ -731,13 +737,37 @@ int omapfb_ioctl(struct fb_info *fbi, un
 			break;
 		}
 
-		if (!display->enable_te) {
+		if (!display->driver->enable_te) {
 			r = -ENODEV;
 			break;
 		}
 
-		r = display->enable_te(display, !!p.tearsync_info.enabled);
+		r = display->driver->enable_te(display,
+				!!p.tearsync_info.enabled);
+
+		break;
+	}
+
+	case OMAPFB_GET_DISPLAY_INFO: {
+		u16 xres, yres;
 
+		DBG("ioctl GET_DISPLAY_INFO\n");
+
+		if (display == NULL) {
+			r = -ENODEV;
+			break;
+		}
+
+		display->driver->get_resolution(display, &xres, &yres);
+
+		p.display_info.xres = xres;
+		p.display_info.yres = yres;
+		p.display_info.width = 0;
+		p.display_info.height = 0;
+
+		if (copy_to_user((void __user *)arg, &p.display_info,
+					sizeof(p.display_info)))
+			r = -EFAULT;
 		break;
 	}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/omapfb/omapfb-main.c linux-libre-2.6.34-gnu1/drivers/video/omap2/omapfb/omapfb-main.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/omapfb/omapfb-main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/omapfb/omapfb-main.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/fb.h>
 #include <linux/dma-mapping.h>
 #include <linux/vmalloc.h>
@@ -54,6 +55,8 @@ module_param_named(test, omapfb_test_pat
 #endif
 
 static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi);
+static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev,
+		struct omap_dss_device *dssdev);
 
 #ifdef DEBUG
 static void draw_pixel(struct fb_info *fbi, int x, int y, unsigned color)
@@ -152,9 +155,9 @@ static void fill_fb(struct fb_info *fbi)
 }
 #endif
 
-static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot)
+static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot)
 {
-	struct vrfb *vrfb = &ofbi->region.vrfb;
+	const struct vrfb *vrfb = &ofbi->region.vrfb;
 	unsigned offset;
 
 	switch (rot) {
@@ -179,7 +182,7 @@ static unsigned omapfb_get_vrfb_offset(s
 	return offset;
 }
 
-static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi, int rot)
+static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot)
 {
 	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
 		return ofbi->region.vrfb.paddr[rot]
@@ -189,7 +192,7 @@ static u32 omapfb_get_region_rot_paddr(s
 	}
 }
 
-static u32 omapfb_get_region_paddr(struct omapfb_info *ofbi)
+static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi)
 {
 	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
 		return ofbi->region.vrfb.paddr[0];
@@ -197,7 +200,7 @@ static u32 omapfb_get_region_paddr(struc
 		return ofbi->region.paddr;
 }
 
-static void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi)
+static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi)
 {
 	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
 		return ofbi->region.vrfb.vaddr[0];
@@ -703,9 +706,9 @@ int check_fb_var(struct fb_info *fbi, st
 	var->width              = -1;
 	var->grayscale          = 0;
 
-	if (display && display->get_timings) {
+	if (display && display->driver->get_timings) {
 		struct omap_video_timings timings;
-		display->get_timings(display, &timings);
+		display->driver->get_timings(display, &timings);
 
 		/* pixclock in ps, the rest in pixclock */
 		var->pixclock = timings.pixel_clock != 0 ?
@@ -778,8 +781,8 @@ static int omapfb_release(struct fb_info
 	return 0;
 }
 
-static unsigned calc_rotation_offset_dma(struct fb_var_screeninfo *var,
-		struct fb_fix_screeninfo *fix, int rotation)
+static unsigned calc_rotation_offset_dma(const struct fb_var_screeninfo *var,
+		const struct fb_fix_screeninfo *fix, int rotation)
 {
 	unsigned offset;
 
@@ -789,8 +792,8 @@ static unsigned calc_rotation_offset_dma
 	return offset;
 }
 
-static unsigned calc_rotation_offset_vrfb(struct fb_var_screeninfo *var,
-		struct fb_fix_screeninfo *fix, int rotation)
+static unsigned calc_rotation_offset_vrfb(const struct fb_var_screeninfo *var,
+		const struct fb_fix_screeninfo *fix, int rotation)
 {
 	unsigned offset;
 
@@ -1221,11 +1224,11 @@ static int omapfb_blank(int blank, struc
 		if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
 			goto exit;
 
-		if (display->resume)
-			r = display->resume(display);
+		if (display->driver->resume)
+			r = display->driver->resume(display);
 
-		if (r == 0 && display->get_update_mode &&
-				display->get_update_mode(display) ==
+		if (r == 0 && display->driver->get_update_mode &&
+				display->driver->get_update_mode(display) ==
 				OMAP_DSS_UPDATE_MANUAL)
 			do_update = 1;
 
@@ -1240,8 +1243,8 @@ static int omapfb_blank(int blank, struc
 		if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
 			goto exit;
 
-		if (display->suspend)
-			r = display->suspend(display);
+		if (display->driver->suspend)
+			r = display->driver->suspend(display);
 
 		break;
 
@@ -1252,11 +1255,11 @@ static int omapfb_blank(int blank, struc
 exit:
 	omapfb_unlock(fbdev);
 
-	if (r == 0 && do_update && display->update) {
+	if (r == 0 && do_update && display->driver->update) {
 		u16 w, h;
-		display->get_resolution(display, &w, &h);
+		display->driver->get_resolution(display, &w, &h);
 
-		r = display->update(display, 0, 0, w, h);
+		r = display->driver->update(display, 0, 0, w, h);
 	}
 
 	return r;
@@ -1404,6 +1407,7 @@ static int omapfb_alloc_fbmem_display(st
 		unsigned long paddr)
 {
 	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
 	struct omap_dss_device *display;
 	int bytespp;
 
@@ -1412,7 +1416,7 @@ static int omapfb_alloc_fbmem_display(st
 	if (!display)
 		return 0;
 
-	switch (display->get_recommended_bpp(display)) {
+	switch (omapfb_get_recommended_bpp(fbdev, display)) {
 	case 16:
 		bytespp = 2;
 		break;
@@ -1427,7 +1431,7 @@ static int omapfb_alloc_fbmem_display(st
 	if (!size) {
 		u16 w, h;
 
-		display->get_resolution(display, &w, &h);
+		display->driver->get_resolution(display, &w, &h);
 
 		if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
 			size = max(omap_vrfb_min_phys_size(w, h, bytespp),
@@ -1636,8 +1640,8 @@ int omapfb_realloc_fbmem(struct fb_info
 	if (old_size == size && old_type == type)
 		return 0;
 
-	if (display && display->sync)
-			display->sync(display);
+	if (display && display->driver->sync)
+			display->driver->sync(display);
 
 	omapfb_free_fbmem(fbi);
 
@@ -1745,7 +1749,7 @@ static int omapfb_fb_init(struct omapfb2
 		u16 w, h;
 		int rotation = (var->rotate + ofbi->rotation[0]) % 4;
 
-		display->get_resolution(display, &w, &h);
+		display->driver->get_resolution(display, &w, &h);
 
 		if (rotation == FB_ROTATE_CW ||
 				rotation == FB_ROTATE_CCW) {
@@ -1760,7 +1764,7 @@ static int omapfb_fb_init(struct omapfb2
 		var->yres_virtual = var->yres;
 
 		if (!var->bits_per_pixel) {
-			switch (display->get_recommended_bpp(display)) {
+			switch (omapfb_get_recommended_bpp(fbdev, display)) {
 			case 16:
 				var->bits_per_pixel = 16;
 				break;
@@ -1828,7 +1832,7 @@ static void omapfb_free_resources(struct
 
 	for (i = 0; i < fbdev->num_displays; i++) {
 		if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED)
-			fbdev->displays[i]->disable(fbdev->displays[i]);
+			fbdev->displays[i]->driver->disable(fbdev->displays[i]);
 
 		omap_dss_put_device(fbdev->displays[i]);
 	}
@@ -2011,7 +2015,8 @@ static int omapfb_mode_to_timings(const
 	}
 }
 
-static int omapfb_set_def_mode(struct omap_dss_device *display, char *mode_str)
+static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
+		struct omap_dss_device *display, char *mode_str)
 {
 	int r;
 	u8 bpp;
@@ -2021,20 +2026,37 @@ static int omapfb_set_def_mode(struct om
 	if (r)
 		return r;
 
-	display->panel.recommended_bpp = bpp;
+	fbdev->bpp_overrides[fbdev->num_bpp_overrides].dssdev = display;
+	fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp;
+	++fbdev->num_bpp_overrides;
 
-	if (!display->check_timings || !display->set_timings)
+	if (!display->driver->check_timings || !display->driver->set_timings)
 		return -EINVAL;
 
-	r = display->check_timings(display, &timings);
+	r = display->driver->check_timings(display, &timings);
 	if (r)
 		return r;
 
-	display->set_timings(display, &timings);
+	display->driver->set_timings(display, &timings);
 
 	return 0;
 }
 
+static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev,
+		struct omap_dss_device *dssdev)
+{
+	int i;
+
+	BUG_ON(dssdev->driver->get_recommended_bpp == NULL);
+
+	for (i = 0; i < fbdev->num_bpp_overrides; ++i) {
+		if (dssdev == fbdev->bpp_overrides[i].dssdev)
+			return fbdev->bpp_overrides[i].bpp;
+	}
+
+	return dssdev->driver->get_recommended_bpp(dssdev);
+}
+
 static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
 {
 	char *str, *options, *this_opt;
@@ -2073,7 +2095,7 @@ static int omapfb_parse_def_modes(struct
 			break;
 		}
 
-		r = omapfb_set_def_mode(display, mode_str);
+		r = omapfb_set_def_mode(fbdev, display, mode_str);
 		if (r)
 			break;
 	}
@@ -2111,18 +2133,23 @@ static int omapfb_probe(struct platform_
 	fbdev->dev = &pdev->dev;
 	platform_set_drvdata(pdev, fbdev);
 
+	r = 0;
 	fbdev->num_displays = 0;
 	dssdev = NULL;
 	for_each_dss_dev(dssdev) {
 		omap_dss_get_device(dssdev);
+
 		if (!dssdev->driver) {
 			dev_err(&pdev->dev, "no driver for display\n");
-			r = -EINVAL;
-			goto cleanup;
+			r = -ENODEV;
 		}
+
 		fbdev->displays[fbdev->num_displays++] = dssdev;
 	}
 
+	if (r)
+		goto cleanup;
+
 	if (fbdev->num_displays == 0) {
 		dev_err(&pdev->dev, "no displays\n");
 		r = -EINVAL;
@@ -2167,35 +2194,28 @@ static int omapfb_probe(struct platform_
 	}
 
 	if (def_display) {
-#ifndef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE
-		u16 w, h;
-#endif
-		r = def_display->enable(def_display);
-		if (r)
+		struct omap_dss_driver *dssdrv = def_display->driver;
+
+		r = def_display->driver->enable(def_display);
+		if (r) {
 			dev_warn(fbdev->dev, "Failed to enable display '%s'\n",
 					def_display->name);
+			goto cleanup;
+		}
 
-		/* set the update mode */
 		if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
-#ifdef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE
-			if (def_display->enable_te)
-				def_display->enable_te(def_display, 1);
-			if (def_display->set_update_mode)
-				def_display->set_update_mode(def_display,
-						OMAP_DSS_UPDATE_AUTO);
-#else /* MANUAL_UPDATE */
-			if (def_display->enable_te)
-				def_display->enable_te(def_display, 0);
-			if (def_display->set_update_mode)
-				def_display->set_update_mode(def_display,
+			u16 w, h;
+			if (dssdrv->enable_te)
+				dssdrv->enable_te(def_display, 1);
+			if (dssdrv->set_update_mode)
+				dssdrv->set_update_mode(def_display,
 						OMAP_DSS_UPDATE_MANUAL);
 
-			def_display->get_resolution(def_display, &w, &h);
-			def_display->update(def_display, 0, 0, w, h);
-#endif
+			dssdrv->get_resolution(def_display, &w, &h);
+			def_display->driver->update(def_display, 0, 0, w, h);
 		} else {
-			if (def_display->set_update_mode)
-				def_display->set_update_mode(def_display,
+			if (dssdrv->set_update_mode)
+				dssdrv->set_update_mode(def_display,
 						OMAP_DSS_UPDATE_AUTO);
 		}
 	}
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/omap2/vram.c linux-libre-2.6.34-gnu1/drivers/video/omap2/vram.c
--- linux-libre-2.6.33-gnu1/drivers/video/omap2/vram.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/omap2/vram.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/bootmem.h>
 #include <linux/completion.h>
@@ -511,13 +512,14 @@ static u32 omap_vram_sdram_size __initda
 static u32 omap_vram_def_sdram_size __initdata;
 static u32 omap_vram_def_sdram_start __initdata;
 
-static void __init omap_vram_early_vram(char **p)
+static int __init omap_vram_early_vram(char *p)
 {
-	omap_vram_def_sdram_size = memparse(*p, p);
-	if (**p == ',')
-		omap_vram_def_sdram_start = simple_strtoul((*p) + 1, p, 16);
+	omap_vram_def_sdram_size = memparse(p, &p);
+	if (*p == ',')
+		omap_vram_def_sdram_start = simple_strtoul(p + 1, &p, 16);
+	return 0;
 }
-__early_param("vram=", omap_vram_early_vram);
+early_param("vram", omap_vram_early_vram);
 
 /*
  * Called from map_io. We need to call to this early enough so that we
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/output.c linux-libre-2.6.34-gnu1/drivers/video/output.c
--- linux-libre-2.6.33-gnu1/drivers/video/output.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/output.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
  */
 #include <linux/module.h>
 #include <linux/video_output.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/ctype.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/p9100.c linux-libre-2.6.34-gnu1/drivers/video/p9100.c
--- linux-libre-2.6.33-gnu1/drivers/video/p9100.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/p9100.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,7 +10,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/platinumfb.c linux-libre-2.6.34-gnu1/drivers/video/platinumfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/platinumfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/platinumfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/pm2fb.c linux-libre-2.6.34-gnu1/drivers/video/pm2fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/pm2fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/pm2fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -896,7 +896,7 @@ static int pm2fb_setcolreg(unsigned regn
 	 * Pseudocolor:
 	 *    uses offset = 0 && length = DAC register width.
 	 *    var->{color}.offset is 0
-	 *    var->{color}.length contains widht of DAC
+	 *    var->{color}.length contains width of DAC
 	 *    cmap is not used
 	 *    DAC[X] is programmed to (red, green, blue)
 	 * Truecolor:
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/pmag-aa-fb.c linux-libre-2.6.34-gnu1/drivers/video/pmag-aa-fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/pmag-aa-fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/pmag-aa-fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,7 +28,6 @@
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/pnx4008/pnxrgbfb.c linux-libre-2.6.34-gnu1/drivers/video/pnx4008/pnxrgbfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/pnx4008/pnxrgbfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/pnx4008/pnxrgbfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/pnx4008/sdum.c linux-libre-2.6.34-gnu1/drivers/video/pnx4008/sdum.c
--- linux-libre-2.6.33-gnu1/drivers/video/pnx4008/sdum.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/pnx4008/sdum.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,7 +20,6 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/tty.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -29,6 +28,7 @@
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 #include <mach/gpio.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/pvr2fb.c linux-libre-2.6.34-gnu1/drivers/video/pvr2fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/pvr2fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/pvr2fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -831,7 +831,7 @@ static int __devinit pvr2fb_common_init(
 	printk(KERN_NOTICE "fb%d: registering with SQ API\n", fb_info->node);
 
 	pvr2fb_map = sq_remap(fb_info->fix.smem_start, fb_info->fix.smem_len,
-			      fb_info->fix.id, pgprot_val(PAGE_SHARED));
+			      fb_info->fix.id, PAGE_SHARED);
 
 	printk(KERN_NOTICE "fb%d: Mapped video memory to SQ addr 0x%lx\n",
 	       fb_info->node, pvr2fb_map);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/pxa168fb.c linux-libre-2.6.34-gnu1/drivers/video/pxa168fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/pxa168fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/pxa168fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -668,7 +668,7 @@ static int __init pxa168fb_probe(struct
 	/*
 	 * Map LCD controller registers.
 	 */
-	fbi->reg_base = ioremap_nocache(res->start, res->end - res->start);
+	fbi->reg_base = ioremap_nocache(res->start, resource_size(res));
 	if (fbi->reg_base == NULL) {
 		ret = -ENOMEM;
 		goto failed;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/q40fb.c linux-libre-2.6.34-gnu1/drivers/video/q40fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/q40fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/q40fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,7 +14,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
@@ -85,7 +84,7 @@ static struct fb_ops q40fb_ops = {
 	.fb_imageblit	= cfb_imageblit,
 };
 
-static int __init q40fb_probe(struct platform_device *dev)
+static int __devinit q40fb_probe(struct platform_device *dev)
 {
 	struct fb_info *info;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/riva/fbdev.c linux-libre-2.6.34-gnu1/drivers/video/riva/fbdev.c
--- linux-libre-2.6.33-gnu1/drivers/video/riva/fbdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/riva/fbdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -338,6 +338,7 @@ static struct backlight_ops riva_bl_ops
 
 static void riva_bl_init(struct riva_par *par)
 {
+	struct backlight_properties props;
 	struct fb_info *info = pci_get_drvdata(par->pdev);
 	struct backlight_device *bd;
 	char name[12];
@@ -353,7 +354,10 @@ static void riva_bl_init(struct riva_par
 
 	snprintf(name, sizeof(name), "rivabl%d", info->node);
 
-	bd = backlight_device_register(name, info->dev, par, &riva_bl_ops);
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+	bd = backlight_device_register(name, info->dev, par, &riva_bl_ops,
+				       &props);
 	if (IS_ERR(bd)) {
 		info->bl_dev = NULL;
 		printk(KERN_WARNING "riva: Backlight registration failed\n");
@@ -365,7 +369,6 @@ static void riva_bl_init(struct riva_par
 		MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL,
 		FB_BACKLIGHT_MAX);
 
-	bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
 	bd->props.brightness = bd->props.max_brightness;
 	bd->props.power = FB_BLANK_UNBLANK;
 	backlight_update_status(bd);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/s1d13xxxfb.c linux-libre-2.6.34-gnu1/drivers/video/s1d13xxxfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/s1d13xxxfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/s1d13xxxfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/fb.h>
 #include <linux/spinlock_types.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
@@ -517,12 +518,12 @@ s1d13xxxfb_bitblt_copyarea(struct fb_inf
 		src = (sy * stride) + (bpp * sx);
 	}
 
-	/* set source adress */
+	/* set source address */
 	s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START0, (src & 0xff));
 	s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START1, (src >> 8) & 0x00ff);
 	s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START2, (src >> 16) & 0x00ff);
 
-	/* set destination adress */
+	/* set destination address */
 	s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START0, (dst & 0xff));
 	s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START1, (dst >> 8) & 0x00ff);
 	s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START2, (dst >> 16) & 0x00ff);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/s3c2410fb.c linux-libre-2.6.34-gnu1/drivers/video/s3c2410fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/s3c2410fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/s3c2410fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -1004,12 +1004,12 @@ dealloc_fb:
 	return ret;
 }
 
-static int __init s3c2410fb_probe(struct platform_device *pdev)
+static int __devinit s3c2410fb_probe(struct platform_device *pdev)
 {
 	return s3c24xxfb_probe(pdev, DRV_S3C2410);
 }
 
-static int __init s3c2412fb_probe(struct platform_device *pdev)
+static int __devinit s3c2412fb_probe(struct platform_device *pdev)
 {
 	return s3c24xxfb_probe(pdev, DRV_S3C2412);
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/s3c-fb.c linux-libre-2.6.34-gnu1/drivers/video/s3c-fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/s3c-fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/s3c-fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,8 +16,8 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <linux/init.h>
-#include <linux/gfp.h>
 #include <linux/clk.h>
 #include <linux/fb.h>
 #include <linux/io.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/s3fb.c linux-libre-2.6.34-gnu1/drivers/video/s3fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/s3fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/s3fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/tty.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/svga.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/sa1100fb.c linux-libre-2.6.34-gnu1/drivers/video/sa1100fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/sa1100fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/sa1100fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -1435,7 +1435,7 @@ static struct sa1100fb_info * __init sa1
 	return fbi;
 }
 
-static int __init sa1100fb_probe(struct platform_device *pdev)
+static int __devinit sa1100fb_probe(struct platform_device *pdev)
 {
 	struct sa1100fb_info *fbi;
 	int ret, irq;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/savage/savagefb-i2c.c linux-libre-2.6.34-gnu1/drivers/video/savage/savagefb-i2c.c
--- linux-libre-2.6.33-gnu1/drivers/video/savage/savagefb-i2c.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/savage/savagefb-i2c.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/fb.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/sgivwfb.c linux-libre-2.6.34-gnu1/drivers/video/sgivwfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/sgivwfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/sgivwfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -745,7 +745,7 @@ int __init sgivwfb_setup(char *options)
 /*
  *  Initialisation
  */
-static int __init sgivwfb_probe(struct platform_device *dev)
+static int __devinit sgivwfb_probe(struct platform_device *dev)
 {
 	struct sgivw_par *par;
 	struct fb_info *info;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/sh7760fb.c linux-libre-2.6.34-gnu1/drivers/video/sh7760fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/sh7760fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/sh7760fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/sh7760fb.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/sh_mobile_lcdcfb.c linux-libre-2.6.34-gnu1/drivers/video/sh_mobile_lcdcfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/sh_mobile_lcdcfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/sh_mobile_lcdcfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,8 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/vmalloc.h>
+#include <linux/ioctl.h>
+#include <linux/slab.h>
 #include <video/sh_mobile_lcdc.h>
 #include <asm/atomic.h>
 
@@ -106,6 +108,7 @@ static unsigned long lcdc_offs_sublcd[NR
 #define LDRCNTR_SRC	0x00010000
 #define LDRCNTR_MRS	0x00000002
 #define LDRCNTR_MRC	0x00000001
+#define LDSR_MRS	0x00000100
 
 struct sh_mobile_lcdc_priv;
 struct sh_mobile_lcdc_chan {
@@ -122,8 +125,8 @@ struct sh_mobile_lcdc_chan {
 	struct scatterlist *sglist;
 	unsigned long frame_end;
 	unsigned long pan_offset;
-	unsigned long new_pan_offset;
 	wait_queue_head_t frame_end_wait;
+	struct completion vsync_completion;
 };
 
 struct sh_mobile_lcdc_priv {
@@ -366,19 +369,8 @@ static irqreturn_t sh_mobile_lcdc_irq(in
 		}
 
 		/* VSYNC End */
-		if (ldintr & LDINTR_VES) {
-			unsigned long ldrcntr = lcdc_read(priv, _LDRCNTR);
-			/* Set the source address for the next refresh */
-			lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle +
-					       ch->new_pan_offset);
-			if (lcdc_chan_is_sublcd(ch))
-				lcdc_write(ch->lcdc, _LDRCNTR,
-					   ldrcntr ^ LDRCNTR_SRS);
-			else
-				lcdc_write(ch->lcdc, _LDRCNTR,
-					   ldrcntr ^ LDRCNTR_MRS);
-			ch->pan_offset = ch->new_pan_offset;
-		}
+		if (ldintr & LDINTR_VES)
+			complete(&ch->vsync_completion);
 	}
 
 	return IRQ_HANDLED;
@@ -703,6 +695,7 @@ static int sh_mobile_lcdc_setup_clocks(s
 	 * 1) Enable Runtime PM
 	 * 2) Force Runtime PM Resume since hardware is accessed from probe()
 	 */
+	priv->dev = &pdev->dev;
 	pm_runtime_enable(priv->dev);
 	pm_runtime_resume(priv->dev);
 	return 0;
@@ -767,25 +760,69 @@ static int sh_mobile_fb_pan_display(stru
 				     struct fb_info *info)
 {
 	struct sh_mobile_lcdc_chan *ch = info->par;
+	struct sh_mobile_lcdc_priv *priv = ch->lcdc;
+	unsigned long ldrcntr;
+	unsigned long new_pan_offset;
 
-	if (info->var.xoffset == var->xoffset &&
-	    info->var.yoffset == var->yoffset)
+	new_pan_offset = (var->yoffset * info->fix.line_length) +
+		(var->xoffset * (info->var.bits_per_pixel / 8));
+
+	if (new_pan_offset == ch->pan_offset)
 		return 0;	/* No change, do nothing */
 
-	ch->new_pan_offset = (var->yoffset * info->fix.line_length) +
-		(var->xoffset * (info->var.bits_per_pixel / 8));
+	ldrcntr = lcdc_read(priv, _LDRCNTR);
 
-	if (ch->new_pan_offset != ch->pan_offset) {
-		unsigned long ldintr;
-		ldintr = lcdc_read(ch->lcdc, _LDINTR);
-		ldintr |= LDINTR_VEE;
-		lcdc_write(ch->lcdc, _LDINTR, ldintr);
-		sh_mobile_lcdc_deferred_io_touch(info);
-	}
+	/* Set the source address for the next refresh */
+	lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle + new_pan_offset);
+	if (lcdc_chan_is_sublcd(ch))
+		lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS);
+	else
+		lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_MRS);
+
+	ch->pan_offset = new_pan_offset;
+
+	sh_mobile_lcdc_deferred_io_touch(info);
+
+	return 0;
+}
+
+static int sh_mobile_wait_for_vsync(struct fb_info *info)
+{
+	struct sh_mobile_lcdc_chan *ch = info->par;
+	unsigned long ldintr;
+	int ret;
+
+	/* Enable VSync End interrupt */
+	ldintr = lcdc_read(ch->lcdc, _LDINTR);
+	ldintr |= LDINTR_VEE;
+	lcdc_write(ch->lcdc, _LDINTR, ldintr);
+
+	ret = wait_for_completion_interruptible_timeout(&ch->vsync_completion,
+							msecs_to_jiffies(100));
+	if (!ret)
+		return -ETIMEDOUT;
 
 	return 0;
 }
 
+static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd,
+		       unsigned long arg)
+{
+	int retval;
+
+	switch (cmd) {
+	case FBIO_WAITFORVSYNC:
+		retval = sh_mobile_wait_for_vsync(info);
+		break;
+
+	default:
+		retval = -ENOIOCTLCMD;
+		break;
+	}
+	return retval;
+}
+
+
 static struct fb_ops sh_mobile_lcdc_ops = {
 	.owner          = THIS_MODULE,
 	.fb_setcolreg	= sh_mobile_lcdc_setcolreg,
@@ -795,6 +832,7 @@ static struct fb_ops sh_mobile_lcdc_ops
 	.fb_copyarea	= sh_mobile_lcdc_copyarea,
 	.fb_imageblit	= sh_mobile_lcdc_imageblit,
 	.fb_pan_display = sh_mobile_fb_pan_display,
+	.fb_ioctl       = sh_mobile_ioctl,
 };
 
 static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
@@ -907,7 +945,7 @@ static const struct dev_pm_ops sh_mobile
 
 static int sh_mobile_lcdc_remove(struct platform_device *pdev);
 
-static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
+static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
 {
 	struct fb_info *info;
 	struct sh_mobile_lcdc_priv *priv;
@@ -920,25 +958,24 @@ static int __init sh_mobile_lcdc_probe(s
 
 	if (!pdev->dev.platform_data) {
 		dev_err(&pdev->dev, "no platform data defined\n");
-		error = -EINVAL;
-		goto err0;
+		return -EINVAL;
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	i = platform_get_irq(pdev, 0);
 	if (!res || i < 0) {
 		dev_err(&pdev->dev, "cannot get platform resources\n");
-		error = -ENOENT;
-		goto err0;
+		return -ENOENT;
 	}
 
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv) {
 		dev_err(&pdev->dev, "cannot allocate device data\n");
-		error = -ENOMEM;
-		goto err0;
+		return -ENOMEM;
 	}
 
+	platform_set_drvdata(pdev, priv);
+
 	error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED,
 			    dev_name(&pdev->dev), priv);
 	if (error) {
@@ -947,8 +984,6 @@ static int __init sh_mobile_lcdc_probe(s
 	}
 
 	priv->irq = i;
-	priv->dev = &pdev->dev;
-	platform_set_drvdata(pdev, priv);
 	pdata = pdev->dev.platform_data;
 
 	j = 0;
@@ -962,8 +997,8 @@ static int __init sh_mobile_lcdc_probe(s
 			goto err1;
 		}
 		init_waitqueue_head(&priv->ch[i].frame_end_wait);
+		init_completion(&priv->ch[i].vsync_completion);
 		priv->ch[j].pan_offset = 0;
-		priv->ch[j].new_pan_offset = 0;
 
 		switch (pdata->ch[i].chan) {
 		case LCDC_CHAN_MAINLCD:
@@ -1062,9 +1097,9 @@ static int __init sh_mobile_lcdc_probe(s
 		info = ch->info;
 
 		if (info->fbdefio) {
-			priv->ch->sglist = vmalloc(sizeof(struct scatterlist) *
+			ch->sglist = vmalloc(sizeof(struct scatterlist) *
 					info->fix.smem_len >> PAGE_SHIFT);
-			if (!priv->ch->sglist) {
+			if (!ch->sglist) {
 				dev_err(&pdev->dev, "cannot allocate sglist\n");
 				goto err1;
 			}
@@ -1089,9 +1124,9 @@ static int __init sh_mobile_lcdc_probe(s
 	}
 
 	return 0;
- err1:
+err1:
 	sh_mobile_lcdc_remove(pdev);
- err0:
+
 	return error;
 }
 
@@ -1102,7 +1137,7 @@ static int sh_mobile_lcdc_remove(struct
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
-		if (priv->ch[i].info->dev)
+		if (priv->ch[i].info && priv->ch[i].info->dev)
 			unregister_framebuffer(priv->ch[i].info);
 
 	sh_mobile_lcdc_stop(priv);
@@ -1125,7 +1160,8 @@ static int sh_mobile_lcdc_remove(struct
 	if (priv->dot_clk)
 		clk_put(priv->dot_clk);
 
-	pm_runtime_disable(priv->dev);
+	if (priv->dev)
+		pm_runtime_disable(priv->dev);
 
 	if (priv->base)
 		iounmap(priv->base);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/sis/sis_main.c linux-libre-2.6.34-gnu1/drivers/video/sis/sis_main.c
--- linux-libre-2.6.33-gnu1/drivers/video/sis/sis_main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/sis/sis_main.c	2010-05-16 17:17:36.000000000 -0400
@@ -1891,9 +1891,6 @@ static struct fb_ops sisfb_ops = {
 	.fb_fillrect	= fbcon_sis_fillrect,
 	.fb_copyarea	= fbcon_sis_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-#ifdef CONFIG_FB_SOFT_CURSOR
-	.fb_cursor	= soft_cursor,
-#endif
 	.fb_sync	= fbcon_sis_sync,
 #ifdef SIS_NEW_CONFIG_COMPAT
 	.fb_compat_ioctl= sisfb_ioctl,
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/sm501fb.c linux-libre-2.6.34-gnu1/drivers/video/sm501fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/sm501fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/sm501fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -411,7 +411,7 @@ static int sm501fb_set_par_common(struct
 	struct sm501fb_par  *par = info->par;
 	struct sm501fb_info *fbi = par->info;
 	unsigned long pixclock;      /* pixelclock in Hz */
-	unsigned long sm501pixclock; /* pixelclock the 501 can achive in Hz */
+	unsigned long sm501pixclock; /* pixelclock the 501 can achieve in Hz */
 	unsigned int mem_type;
 	unsigned int clock_type;
 	unsigned int head_addr;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/sstfb.c linux-libre-2.6.34-gnu1/drivers/video/sstfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/sstfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/sstfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -86,7 +86,6 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/uaccess.h>
 #include <video/sstfb.h>
@@ -1102,7 +1101,7 @@ static void sst_set_vidmod_ics(struct fb
  * detect dac type
  * prerequisite : write to FbiInitx enabled, video and fbi and pci fifo reset,
  * dram refresh disabled, FbiInit remaped.
- * TODO: mmh.. maybe i shoud put the "prerequisite" in the func ...
+ * TODO: mmh.. maybe i should put the "prerequisite" in the func ...
  */
 
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/sunxvr1000.c linux-libre-2.6.34-gnu1/drivers/video/sunxvr1000.c
--- linux-libre-2.6.33-gnu1/drivers/video/sunxvr1000.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/sunxvr1000.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,227 @@
+/* sunxvr1000.c: Sun XVR-1000 driver for sparc64 systems
+ *
+ * Copyright (C) 2010 David S. Miller (davem@davemloft.net)
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/of_device.h>
+
+struct gfb_info {
+	struct fb_info		*info;
+
+	char __iomem		*fb_base;
+	unsigned long		fb_base_phys;
+
+	struct device_node	*of_node;
+
+	unsigned int		width;
+	unsigned int		height;
+	unsigned int		depth;
+	unsigned int		fb_size;
+
+	u32			pseudo_palette[16];
+};
+
+static int __devinit gfb_get_props(struct gfb_info *gp)
+{
+	gp->width = of_getintprop_default(gp->of_node, "width", 0);
+	gp->height = of_getintprop_default(gp->of_node, "height", 0);
+	gp->depth = of_getintprop_default(gp->of_node, "depth", 32);
+
+	if (!gp->width || !gp->height) {
+		printk(KERN_ERR "gfb: Critical properties missing for %s\n",
+		       gp->of_node->full_name);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int gfb_setcolreg(unsigned regno,
+			 unsigned red, unsigned green, unsigned blue,
+			 unsigned transp, struct fb_info *info)
+{
+	u32 value;
+
+	if (regno < 16) {
+		red >>= 8;
+		green >>= 8;
+		blue >>= 8;
+
+		value = (blue << 16) | (green << 8) | red;
+		((u32 *)info->pseudo_palette)[regno] = value;
+	}
+
+	return 0;
+}
+
+static struct fb_ops gfb_ops = {
+	.owner			= THIS_MODULE,
+	.fb_setcolreg		= gfb_setcolreg,
+	.fb_fillrect		= cfb_fillrect,
+	.fb_copyarea		= cfb_copyarea,
+	.fb_imageblit		= cfb_imageblit,
+};
+
+static int __devinit gfb_set_fbinfo(struct gfb_info *gp)
+{
+	struct fb_info *info = gp->info;
+	struct fb_var_screeninfo *var = &info->var;
+
+	info->flags = FBINFO_DEFAULT;
+	info->fbops = &gfb_ops;
+	info->screen_base = gp->fb_base;
+	info->screen_size = gp->fb_size;
+
+	info->pseudo_palette = gp->pseudo_palette;
+
+	/* Fill fix common fields */
+	strlcpy(info->fix.id, "gfb", sizeof(info->fix.id));
+        info->fix.smem_start = gp->fb_base_phys;
+        info->fix.smem_len = gp->fb_size;
+        info->fix.type = FB_TYPE_PACKED_PIXELS;
+	if (gp->depth == 32 || gp->depth == 24)
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+	else
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+
+	var->xres = gp->width;
+	var->yres = gp->height;
+	var->xres_virtual = var->xres;
+	var->yres_virtual = var->yres;
+	var->bits_per_pixel = gp->depth;
+
+	var->red.offset = 0;
+	var->red.length = 8;
+	var->green.offset = 8;
+	var->green.length = 8;
+	var->blue.offset = 16;
+	var->blue.length = 8;
+	var->transp.offset = 0;
+	var->transp.length = 0;
+
+	if (fb_alloc_cmap(&info->cmap, 256, 0)) {
+		printk(KERN_ERR "gfb: Cannot allocate color map.\n");
+		return -ENOMEM;
+	}
+
+        return 0;
+}
+
+static int __devinit gfb_probe(struct of_device *op,
+			       const struct of_device_id *match)
+{
+	struct device_node *dp = op->node;
+	struct fb_info *info;
+	struct gfb_info *gp;
+	int err;
+
+	info = framebuffer_alloc(sizeof(struct gfb_info), &op->dev);
+	if (!info) {
+		printk(KERN_ERR "gfb: Cannot allocate fb_info\n");
+		err = -ENOMEM;
+		goto err_out;
+	}
+
+	gp = info->par;
+	gp->info = info;
+	gp->of_node = dp;
+
+	gp->fb_base_phys = op->resource[6].start;
+
+	err = gfb_get_props(gp);
+	if (err)
+		goto err_release_fb;
+
+	/* Framebuffer length is the same regardless of resolution. */
+	info->fix.line_length = 16384;
+	gp->fb_size = info->fix.line_length * gp->height;
+
+	gp->fb_base = of_ioremap(&op->resource[6], 0,
+				 gp->fb_size, "gfb fb");
+	if (!gp->fb_base)
+		goto err_release_fb;
+
+	err = gfb_set_fbinfo(gp);
+	if (err)
+		goto err_unmap_fb;
+
+	printk("gfb: Found device at %s\n", dp->full_name);
+
+	err = register_framebuffer(info);
+	if (err < 0) {
+		printk(KERN_ERR "gfb: Could not register framebuffer %s\n",
+		       dp->full_name);
+		goto err_unmap_fb;
+	}
+
+	dev_set_drvdata(&op->dev, info);
+
+	return 0;
+
+err_unmap_fb:
+	of_iounmap(&op->resource[6], gp->fb_base, gp->fb_size);
+
+err_release_fb:
+        framebuffer_release(info);
+
+err_out:
+	return err;
+}
+
+static int __devexit gfb_remove(struct of_device *op)
+{
+	struct fb_info *info = dev_get_drvdata(&op->dev);
+	struct gfb_info *gp = info->par;
+
+	unregister_framebuffer(info);
+
+	iounmap(gp->fb_base);
+
+	of_iounmap(&op->resource[6], gp->fb_base, gp->fb_size);
+
+        framebuffer_release(info);
+
+	dev_set_drvdata(&op->dev, NULL);
+
+	return 0;
+}
+
+static const struct of_device_id gfb_match[] = {
+	{
+		.name = "SUNW,gfb",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, ffb_match);
+
+static struct of_platform_driver gfb_driver = {
+	.name		= "gfb",
+	.match_table	= gfb_match,
+	.probe		= gfb_probe,
+	.remove		= __devexit_p(gfb_remove),
+};
+
+static int __init gfb_init(void)
+{
+	if (fb_get_options("gfb", NULL))
+		return -ENODEV;
+
+	return of_register_driver(&gfb_driver, &of_bus_type);
+}
+
+static void __exit gfb_exit(void)
+{
+	of_unregister_driver(&gfb_driver);
+}
+
+module_init(gfb_init);
+module_exit(gfb_exit);
+
+MODULE_DESCRIPTION("framebuffer driver for Sun XVR-1000 graphics");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/sunxvr2500.c linux-libre-2.6.34-gnu1/drivers/video/sunxvr2500.c
--- linux-libre-2.6.33-gnu1/drivers/video/sunxvr2500.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/sunxvr2500.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,6 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/fb.h>
 #include <linux/pci.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/sunxvr500.c linux-libre-2.6.34-gnu1/drivers/video/sunxvr500.c
--- linux-libre-2.6.33-gnu1/drivers/video/sunxvr500.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/sunxvr500.c	2010-05-16 17:17:36.000000000 -0400
@@ -5,7 +5,6 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/fb.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -242,11 +241,27 @@ static int __devinit e3d_set_fbinfo(stru
 static int __devinit e3d_pci_register(struct pci_dev *pdev,
 				      const struct pci_device_id *ent)
 {
+	struct device_node *of_node;
+	const char *device_type;
 	struct fb_info *info;
 	struct e3d_info *ep;
 	unsigned int line_length;
 	int err;
 
+	of_node = pci_device_to_OF_node(pdev);
+	if (!of_node) {
+		printk(KERN_ERR "e3d: Cannot find OF node of %s\n",
+		       pci_name(pdev));
+		return -ENODEV;
+	}
+
+	device_type = of_get_property(of_node, "device_type", NULL);
+	if (!device_type) {
+		printk(KERN_INFO "e3d: Ignoring secondary output device "
+		       "at %s\n", pci_name(pdev));
+		return -ENODEV;
+	}
+
 	err = pci_enable_device(pdev);
 	if (err < 0) {
 		printk(KERN_ERR "e3d: Cannot enable PCI device %s\n",
@@ -265,13 +280,7 @@ static int __devinit e3d_pci_register(st
 	ep->info = info;
 	ep->pdev = pdev;
 	spin_lock_init(&ep->lock);
-	ep->of_node = pci_device_to_OF_node(pdev);
-	if (!ep->of_node) {
-		printk(KERN_ERR "e3d: Cannot find OF node of %s\n",
-		       pci_name(pdev));
-		err = -ENODEV;
-		goto err_release_fb;
-	}
+	ep->of_node = of_node;
 
 	/* Read the PCI base register of the frame buffer, which we
 	 * need in order to interpret the RAMDAC_VID_*FB* values in
@@ -400,6 +409,7 @@ static void __devexit e3d_pci_unregister
 
 static struct pci_device_id e3d_pci_table[] = {
 	{	PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a0),	},
+	{	PCI_DEVICE(0x1091, 0x7a0),			},
 	{	PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a2),	},
 	{	.vendor = PCI_VENDOR_ID_3DLABS,
 		.device = PCI_ANY_ID,
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/svgalib.c linux-libre-2.6.34-gnu1/drivers/video/svgalib.c
--- linux-libre-2.6.33-gnu1/drivers/video/svgalib.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/svgalib.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/string.h>
 #include <linux/fb.h>
 #include <linux/svga.h>
-#include <linux/slab.h>
 #include <asm/types.h>
 #include <asm/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/syscopyarea.c linux-libre-2.6.34-gnu1/drivers/video/syscopyarea.c
--- linux-libre-2.6.33-gnu1/drivers/video/syscopyarea.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/syscopyarea.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/fb.h>
-#include <linux/slab.h>
 #include <asm/types.h>
 #include <asm/io.h>
 #include "fb_draw.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/tcx.c linux-libre-2.6.34-gnu1/drivers/video/tcx.c
--- linux-libre-2.6.33-gnu1/drivers/video/tcx.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/tcx.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/tgafb.c linux-libre-2.6.34-gnu1/drivers/video/tgafb.c
--- linux-libre-2.6.33-gnu1/drivers/video/tgafb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/tgafb.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,7 +25,6 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/selection.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/tc.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/tridentfb.c linux-libre-2.6.34-gnu1/drivers/video/tridentfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/tridentfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/tridentfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include <linux/delay.h>
 #include <video/vga.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/uvesafb.c linux-libre-2.6.34-gnu1/drivers/video/uvesafb.c
--- linux-libre-2.6.33-gnu1/drivers/video/uvesafb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/uvesafb.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/fb.h>
 #include <linux/io.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <video/edid.h>
 #include <video/uvesafb.h>
 #ifdef CONFIG_X86
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/valkyriefb.c linux-libre-2.6.34-gnu1/drivers/video/valkyriefb.c
--- linux-libre-2.6.33-gnu1/drivers/video/valkyriefb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/valkyriefb.c	2010-05-16 17:17:36.000000000 -0400
@@ -69,7 +69,7 @@
 #ifdef CONFIG_MAC
 /* We don't yet have functions to read the PRAM... perhaps we can
    adapt them from the PPC code? */
-static int default_vmode = VMODE_640_480_67;
+static int default_vmode = VMODE_CHOOSE;
 static int default_cmode = CMODE_8;
 #else
 static int default_vmode = VMODE_NVRAM;
@@ -326,11 +326,11 @@ int __init valkyriefb_init(void)
 
 #ifdef CONFIG_MAC
 	if (!MACH_IS_MAC)
-		return 0;
+		return -ENODEV;
 	if (!(mac_bi_data.id == MAC_MODEL_Q630
 	      /* I'm not sure about this one */
 	    || mac_bi_data.id == MAC_MODEL_P588))
-		return 0;
+		return -ENODEV;
 
 	/* Hardcoded addresses... welcome to 68k Macintosh country :-) */
 	frame_buffer_phys = 0xf9000000;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/valkyriefb.h linux-libre-2.6.34-gnu1/drivers/video/valkyriefb.h
--- linux-libre-2.6.33-gnu1/drivers/video/valkyriefb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/valkyriefb.h	2010-05-16 17:17:36.000000000 -0400
@@ -134,15 +134,7 @@ static struct valkyrie_regvals valkyrie_
     { 1024, 0 },
 	1024, 768
 };
-
-/* Register values for 800x600, 72Hz mode (11) */
-static struct valkyrie_regvals valkyrie_reg_init_11 = {
-    13,
-    { 17, 27, 3 },  /* pixel clock = 49.63MHz for V=71.66Hz */
-    { 800, 0 },
-	800, 600
-};
-#endif /* CONFIG_MAC */
+#endif /* !defined CONFIG_MAC */
 
 /* Register values for 832x624, 75Hz mode (13) */
 static struct valkyrie_regvals valkyrie_reg_init_13 = {
@@ -152,6 +144,14 @@ static struct valkyrie_regvals valkyrie_
 	832, 624
 };
 
+/* Register values for 800x600, 72Hz mode (11) */
+static struct valkyrie_regvals valkyrie_reg_init_11 = {
+    13,
+    { 17, 27, 3 },  /* pixel clock = 49.63MHz for V=71.66Hz */
+    { 800, 0 },
+	800, 600
+};
+
 /* Register values for 800x600, 60Hz mode (10) */
 static struct valkyrie_regvals valkyrie_reg_init_10 = {
     12,
@@ -188,24 +188,13 @@ static struct valkyrie_regvals *valkyrie
 	NULL,
 	NULL,
 	&valkyrie_reg_init_10,
-#ifdef CONFIG_MAC
-	NULL,
-	NULL,
-	&valkyrie_reg_init_13,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-#else
 	&valkyrie_reg_init_11,
 	NULL,
 	&valkyrie_reg_init_13,
+#ifndef CONFIG_MAC
 	&valkyrie_reg_init_14,
 	&valkyrie_reg_init_15,
 	NULL,
 	&valkyrie_reg_init_17,
 #endif
-	NULL,
-	NULL,
-	NULL
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/vermilion/vermilion.c linux-libre-2.6.34-gnu1/drivers/video/vermilion/vermilion.c
--- linux-libre-2.6.33-gnu1/drivers/video/vermilion/vermilion.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/vermilion/vermilion.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/fb.h>
 #include <linux/pci.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/vesafb.c linux-libre-2.6.34-gnu1/drivers/video/vesafb.c
--- linux-libre-2.6.33-gnu1/drivers/video/vesafb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/vesafb.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/ioport.h>
@@ -477,7 +476,6 @@ err:
 }
 
 static struct platform_driver vesafb_driver = {
-	.probe	= vesafb_probe,
 	.driver	= {
 		.name	= "vesafb",
 	},
@@ -493,20 +491,21 @@ static int __init vesafb_init(void)
 	/* ignore error return of fb_get_options */
 	fb_get_options("vesafb", &option);
 	vesafb_setup(option);
-	ret = platform_driver_register(&vesafb_driver);
 
-	if (!ret) {
-		vesafb_device = platform_device_alloc("vesafb", 0);
+	vesafb_device = platform_device_alloc("vesafb", 0);
+	if (!vesafb_device)
+		return -ENOMEM;
 
-		if (vesafb_device)
-			ret = platform_device_add(vesafb_device);
-		else
-			ret = -ENOMEM;
+	ret = platform_device_add(vesafb_device);
+	if (!ret) {
+		ret = platform_driver_probe(&vesafb_driver, vesafb_probe);
+		if (ret)
+			platform_device_del(vesafb_device);
+	}
 
-		if (ret) {
-			platform_device_put(vesafb_device);
-			platform_driver_unregister(&vesafb_driver);
-		}
+	if (ret) {
+		platform_device_put(vesafb_device);
+		vesafb_device = NULL;
 	}
 
 	return ret;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/vfb.c linux-libre-2.6.34-gnu1/drivers/video/vfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/vfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/vfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -479,7 +478,7 @@ static int __init vfb_setup(char *option
      *  Initialisation
      */
 
-static int __init vfb_probe(struct platform_device *dev)
+static int __devinit vfb_probe(struct platform_device *dev)
 {
 	struct fb_info *info;
 	int retval = -ENOMEM;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/vga16fb.c linux-libre-2.6.34-gnu1/drivers/video/vga16fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/vga16fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/vga16fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/ioport.h>
@@ -1293,7 +1292,7 @@ static int vga16fb_setup(char *options)
 }
 #endif
 
-static int __init vga16fb_probe(struct platform_device *dev)
+static int __devinit vga16fb_probe(struct platform_device *dev)
 {
 	struct fb_info *info;
 	struct vga16fb_par *par;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/chip.h linux-libre-2.6.34-gnu1/drivers/video/via/chip.h
--- linux-libre-2.6.33-gnu1/drivers/video/via/chip.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/chip.h	2010-05-16 17:17:36.000000000 -0400
@@ -107,7 +107,6 @@
 struct tmds_chip_information {
 	int tmds_chip_name;
 	int tmds_chip_slave_addr;
-	int dvi_panel_id;
 	int data_mode;
 	int output_interface;
 	int i2c_port;
@@ -142,14 +141,9 @@ struct tmds_setting_information {
 	int iga_path;
 	int h_active;
 	int v_active;
-	int bpp;
-	int refresh_rate;
-	int get_dvi_size_method;
 	int max_pixel_clock;
-	int dvi_panel_size;
-	int dvi_panel_hres;
-	int dvi_panel_vres;
-	int native_size;
+	int max_hres;
+	int max_vres;
 };
 
 struct lvds_setting_information {
@@ -160,7 +154,6 @@ struct lvds_setting_information {
 	int refresh_rate;
 	int get_lcd_size_method;
 	int lcd_panel_id;
-	int lcd_panel_size;
 	int lcd_panel_hres;
 	int lcd_panel_vres;
 	int display_method;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/dvi.c linux-libre-2.6.34-gnu1/drivers/video/via/dvi.c
--- linux-libre-2.6.33-gnu1/drivers/video/via/dvi.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/dvi.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,11 +23,10 @@
 static void tmds_register_write(int index, u8 data);
 static int tmds_register_read(int index);
 static int tmds_register_read_bytes(int index, u8 *buff, int buff_len);
-static int check_reduce_blanking_mode(int mode_index,
-	int refresh_rate);
-static int dvi_get_panel_size_from_DDCv1(void);
-static int dvi_get_panel_size_from_DDCv2(void);
-static unsigned char dvi_get_panel_info(void);
+static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information
+	*tmds_chip, struct tmds_setting_information *tmds_setting);
+static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information
+	*tmds_chip, struct tmds_setting_information *tmds_setting);
 static int viafb_dvi_query_EDID(void);
 
 static int check_tmds_chip(int device_id_subaddr, int device_id)
@@ -38,23 +37,24 @@ static int check_tmds_chip(int device_id
 		return FAIL;
 }
 
-void viafb_init_dvi_size(void)
+void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
+	struct tmds_setting_information *tmds_setting)
 {
 	DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
-	DEBUG_MSG(KERN_INFO
-		"viaparinfo->tmds_setting_info->get_dvi_size_method %d\n",
-		  viaparinfo->tmds_setting_info->get_dvi_size_method);
 
-	switch (viaparinfo->tmds_setting_info->get_dvi_size_method) {
-	case GET_DVI_SIZE_BY_SYSTEM_BIOS:
+	viafb_dvi_sense();
+	switch (viafb_dvi_query_EDID()) {
+	case 1:
+		dvi_get_panel_size_from_DDCv1(tmds_chip, tmds_setting);
 		break;
-	case GET_DVI_SZIE_BY_HW_STRAPPING:
+	case 2:
+		dvi_get_panel_size_from_DDCv2(tmds_chip, tmds_setting);
 		break;
-	case GET_DVI_SIZE_BY_VGA_BIOS:
 	default:
-		dvi_get_panel_info();
+		printk(KERN_WARNING "viafb_init_dvi_size: DVI panel size undetected!\n");
 		break;
 	}
+
 	return;
 }
 
@@ -189,42 +189,14 @@ static int tmds_register_read_bytes(int
 	return 0;
 }
 
-static int check_reduce_blanking_mode(int mode_index,
-	int refresh_rate)
-{
-	if (refresh_rate != 60)
-		return false;
-
-	switch (mode_index) {
-		/* Following modes have reduce blanking mode. */
-	case VIA_RES_1360X768:
-	case VIA_RES_1400X1050:
-	case VIA_RES_1440X900:
-	case VIA_RES_1600X900:
-	case VIA_RES_1680X1050:
-	case VIA_RES_1920X1080:
-	case VIA_RES_1920X1200:
-		break;
-
-	default:
-		DEBUG_MSG(KERN_INFO
-			  "This dvi mode %d have no reduce blanking mode!\n",
-			  mode_index);
-		return false;
-	}
-
-	return true;
-}
-
 /* DVI Set Mode */
-void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga)
+void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp,
+	int set_iga)
 {
-	struct VideoModeTable *videoMode = NULL;
+	struct VideoModeTable *rb_mode;
 	struct crt_mode_table *pDviTiming;
 	unsigned long desirePixelClock, maxPixelClock;
-	int status = 0;
-	videoMode = viafb_get_modetbl_pointer(video_index);
-	pDviTiming = videoMode->crtc;
+	pDviTiming = mode->crtc;
 	desirePixelClock = pDviTiming->clk / 1000000;
 	maxPixelClock = (unsigned long)viaparinfo->
 		tmds_setting_info->max_pixel_clock;
@@ -232,20 +204,14 @@ void viafb_dvi_set_mode(int video_index,
 	DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
 
 	if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
-		/*Check if reduce-blanking mode is exist */
-		status =
-		    check_reduce_blanking_mode(video_index,
-					       pDviTiming->refresh_rate);
-		if (status) {
-			video_index += 100;	/*Use reduce-blanking mode */
-			videoMode = viafb_get_modetbl_pointer(video_index);
-			pDviTiming = videoMode->crtc;
-			DEBUG_MSG(KERN_INFO
-				  "DVI use reduce blanking mode %d!!\n",
-				  video_index);
+		rb_mode = viafb_get_rb_mode(mode->crtc[0].crtc.hor_addr,
+			mode->crtc[0].crtc.ver_addr);
+		if (rb_mode) {
+			mode = rb_mode;
+			pDviTiming = rb_mode->crtc;
 		}
 	}
-	viafb_fill_crtc_timing(pDviTiming, video_index, mode_bpp / 8, set_iga);
+	viafb_fill_crtc_timing(pDviTiming, mode, mode_bpp / 8, set_iga);
 	viafb_set_output_path(DEVICE_DVI, set_iga,
 			viaparinfo->chip_info->tmds_chip_info.output_interface);
 }
@@ -350,25 +316,18 @@ static int viafb_dvi_query_EDID(void)
 		return false;
 }
 
-/*
- *
- * int dvi_get_panel_size_from_DDCv1(void)
- *
- *     - Get Panel Size Using EDID1 Table
- *
- * Return Type:    int
- *
- */
-static int dvi_get_panel_size_from_DDCv1(void)
+/* Get Panel Size Using EDID1 Table */
+static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information
+	*tmds_chip, struct tmds_setting_information *tmds_setting)
 {
-	int i, max_h = 0, max_v = 0, tmp, restore;
+	int i, max_h = 0, tmp, restore;
 	unsigned char rData;
 	unsigned char EDID_DATA[18];
 
 	DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
 
-	restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
-	viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
+	restore = tmds_chip->tmds_chip_slave_addr;
+	tmds_chip->tmds_chip_slave_addr = 0xA0;
 
 	rData = tmds_register_read(0x23);
 	if (rData & 0x3C)
@@ -414,8 +373,8 @@ static int dvi_get_panel_size_from_DDCv1
 				/* The first two byte must be zero. */
 				if (EDID_DATA[3] == 0xFD) {
 					/* To get max pixel clock. */
-					viaparinfo->tmds_setting_info->
-					max_pixel_clock = EDID_DATA[9] * 10;
+					tmds_setting->max_pixel_clock =
+						EDID_DATA[9] * 10;
 				}
 			}
 			break;
@@ -425,154 +384,88 @@ static int dvi_get_panel_size_from_DDCv1
 		}
 	}
 
+	tmds_setting->max_hres = max_h;
 	switch (max_h) {
 	case 640:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_640X480;
+		tmds_setting->max_vres = 480;
 		break;
 	case 800:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_800X600;
+		tmds_setting->max_vres = 600;
 		break;
 	case 1024:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_1024X768;
+		tmds_setting->max_vres = 768;
 		break;
 	case 1280:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_1280X1024;
+		tmds_setting->max_vres = 1024;
 		break;
 	case 1400:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_1400X1050;
+		tmds_setting->max_vres = 1050;
 		break;
 	case 1440:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_1440X1050;
+		tmds_setting->max_vres = 1050;
 		break;
 	case 1600:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_1600X1200;
+		tmds_setting->max_vres = 1200;
 		break;
 	case 1920:
-		if (max_v == 1200) {
-			viaparinfo->tmds_setting_info->dvi_panel_size =
-				VIA_RES_1920X1200;
-		} else {
-			viaparinfo->tmds_setting_info->dvi_panel_size =
-				VIA_RES_1920X1080;
-		}
-
+		tmds_setting->max_vres = 1080;
 		break;
 	default:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_1024X768;
-		DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d !\
-					 set default panel size.\n", max_h);
+		DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d ! "
+					 "set default panel size.\n", max_h);
 		break;
 	}
 
 	DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",
-		  viaparinfo->tmds_setting_info->max_pixel_clock);
-	viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
-	return viaparinfo->tmds_setting_info->dvi_panel_size;
+		tmds_setting->max_pixel_clock);
+	tmds_chip->tmds_chip_slave_addr = restore;
 }
 
-/*
- *
- * int dvi_get_panel_size_from_DDCv2(void)
- *
- *     - Get Panel Size Using EDID2 Table
- *
- * Return Type:    int
- *
- */
-static int dvi_get_panel_size_from_DDCv2(void)
+/* Get Panel Size Using EDID2 Table */
+static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information
+	*tmds_chip, struct tmds_setting_information *tmds_setting)
 {
-	int HSize = 0, restore;
+	int restore;
 	unsigned char R_Buffer[2];
 
 	DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n");
 
-	restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
-	viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA2;
+	restore = tmds_chip->tmds_chip_slave_addr;
+	tmds_chip->tmds_chip_slave_addr = 0xA2;
 
 	/* Horizontal: 0x76, 0x77 */
 	tmds_register_read_bytes(0x76, R_Buffer, 2);
-	HSize = R_Buffer[0];
-	HSize += R_Buffer[1] << 8;
+	tmds_setting->max_hres = R_Buffer[0] + (R_Buffer[1] << 8);
 
-	switch (HSize) {
+	switch (tmds_setting->max_hres) {
 	case 640:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_640X480;
+		tmds_setting->max_vres = 480;
 		break;
 	case 800:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_800X600;
+		tmds_setting->max_vres = 600;
 		break;
 	case 1024:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_1024X768;
+		tmds_setting->max_vres = 768;
 		break;
 	case 1280:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_1280X1024;
+		tmds_setting->max_vres = 1024;
 		break;
 	case 1400:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_1400X1050;
+		tmds_setting->max_vres = 1050;
 		break;
 	case 1440:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_1440X1050;
+		tmds_setting->max_vres = 1050;
 		break;
 	case 1600:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_1600X1200;
-		break;
-	default:
-		viaparinfo->tmds_setting_info->dvi_panel_size =
-			VIA_RES_1024X768;
-		DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d!\
-					set default panel size.\n", HSize);
-		break;
-	}
-
-	viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
-	return viaparinfo->tmds_setting_info->dvi_panel_size;
-}
-
-/*
- *
- * unsigned char dvi_get_panel_info(void)
- *
- *     - Get Panel Size
- *
- * Return Type:    unsigned char
- */
-static unsigned char dvi_get_panel_info(void)
-{
-	unsigned char dvipanelsize;
-	DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n");
-
-	viafb_dvi_sense();
-	switch (viafb_dvi_query_EDID()) {
-	case 1:
-		dvi_get_panel_size_from_DDCv1();
-		break;
-	case 2:
-		dvi_get_panel_size_from_DDCv2();
+		tmds_setting->max_vres = 1200;
 		break;
 	default:
+		DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d! "
+			"set default panel size.\n", tmds_setting->max_hres);
 		break;
 	}
 
-	DEBUG_MSG(KERN_INFO "dvi panel size is %2d \n",
-		  viaparinfo->tmds_setting_info->dvi_panel_size);
-	dvipanelsize = (unsigned char)(viaparinfo->
-		tmds_setting_info->dvi_panel_size);
-	return dvipanelsize;
+	tmds_chip->tmds_chip_slave_addr = restore;
 }
 
 /* If Disable DVI, turn off pad */
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/dvi.h linux-libre-2.6.34-gnu1/drivers/video/via/dvi.h
--- linux-libre-2.6.33-gnu1/drivers/video/via/dvi.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/dvi.h	2010-05-16 17:17:36.000000000 -0400
@@ -53,12 +53,13 @@
 #define     DEV_CONNECT_DVI     0x01
 #define     DEV_CONNECT_HDMI    0x02
 
-struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index);
 int viafb_dvi_sense(void);
 void viafb_dvi_disable(void);
 void viafb_dvi_enable(void);
 int viafb_tmds_trasmitter_identify(void);
-void viafb_init_dvi_size(void);
-void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga);
+void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
+	struct tmds_setting_information *tmds_setting);
+void viafb_dvi_set_mode(struct VideoModeTable *videoMode, int mode_bpp,
+	int set_iga);
 
 #endif /* __DVI_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/global.c linux-libre-2.6.34-gnu1/drivers/video/via/global.c
--- linux-libre-2.6.33-gnu1/drivers/video/via/global.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/global.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,15 +23,12 @@ int viafb_platform_epia_dvi = STATE_OFF;
 int viafb_device_lcd_dualedge = STATE_OFF;
 int viafb_bus_width = 12;
 int viafb_display_hardware_layout = HW_LAYOUT_LCD_DVI;
-int viafb_memsize;
 int viafb_DeviceStatus = CRT_Device;
 int viafb_hotplug;
 int viafb_refresh = 60;
 int viafb_refresh1 = 60;
 int viafb_lcd_dsp_method = LCD_EXPANDSION;
 int viafb_lcd_mode = LCD_OPENLDI;
-int viafb_bpp = 32;
-int viafb_bpp1 = 32;
 int viafb_CRT_ON = 1;
 int viafb_DVI_ON;
 int viafb_LCD_ON ;
@@ -42,8 +39,6 @@ int viafb_hotplug_Xres = 640;
 int viafb_hotplug_Yres = 480;
 int viafb_hotplug_bpp = 32;
 int viafb_hotplug_refresh = 60;
-unsigned int viafb_second_offset;
-int viafb_second_size;
 int viafb_primary_dev = None_Device;
 unsigned int viafb_second_xres = 640;
 unsigned int viafb_second_yres = 480;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/global.h linux-libre-2.6.34-gnu1/drivers/video/via/global.h
--- linux-libre-2.6.33-gnu1/drivers/video/via/global.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/global.h	2010-05-16 17:17:36.000000000 -0400
@@ -35,7 +35,6 @@
 
 #include "debug.h"
 
-#include "iface.h"
 #include "viafbdev.h"
 #include "chip.h"
 #include "accel.h"
@@ -68,8 +67,6 @@ extern int viafb_refresh;
 extern int viafb_refresh1;
 extern int viafb_lcd_dsp_method;
 extern int viafb_lcd_mode;
-extern int viafb_bpp;
-extern int viafb_bpp1;
 
 extern int viafb_CRT_ON;
 extern int viafb_hotplug_Xres;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/hw.c linux-libre-2.6.34-gnu1/drivers/video/via/hw.c
--- linux-libre-2.6.33-gnu1/drivers/video/via/hw.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/hw.c	2010-05-16 17:17:36.000000000 -0400
@@ -524,7 +524,6 @@ static void dvi_patch_skew_dvp1(void);
 static void dvi_patch_skew_dvp_low(void);
 static void set_dvi_output_path(int set_iga, int output_interface);
 static void set_lcd_output_path(int set_iga, int output_interface);
-static int search_mode_setting(int ModeInfoIndex);
 static void load_fix_bit_crtc_reg(void);
 static void init_gfx_chip_info(struct pci_dev *pdev,
 				const struct pci_device_id *pdi);
@@ -686,6 +685,84 @@ void viafb_set_secondary_pitch(u32 pitch
 	viafb_write_reg_mask(0x71, VIACR, (pitch >> (10 - 7)) & 0x80, 0x80);
 }
 
+void viafb_set_primary_color_depth(u8 depth)
+{
+	u8 value;
+
+	DEBUG_MSG(KERN_DEBUG "viafb_set_primary_color_depth(%d)\n", depth);
+	switch (depth) {
+	case 8:
+		value = 0x00;
+		break;
+	case 15:
+		value = 0x04;
+		break;
+	case 16:
+		value = 0x14;
+		break;
+	case 24:
+		value = 0x0C;
+		break;
+	case 30:
+		value = 0x08;
+		break;
+	default:
+		printk(KERN_WARNING "viafb_set_primary_color_depth: "
+			"Unsupported depth: %d\n", depth);
+		return;
+	}
+
+	viafb_write_reg_mask(0x15, VIASR, value, 0x1C);
+}
+
+void viafb_set_secondary_color_depth(u8 depth)
+{
+	u8 value;
+
+	DEBUG_MSG(KERN_DEBUG "viafb_set_secondary_color_depth(%d)\n", depth);
+	switch (depth) {
+	case 8:
+		value = 0x00;
+		break;
+	case 16:
+		value = 0x40;
+		break;
+	case 24:
+		value = 0xC0;
+		break;
+	case 30:
+		value = 0x80;
+		break;
+	default:
+		printk(KERN_WARNING "viafb_set_secondary_color_depth: "
+			"Unsupported depth: %d\n", depth);
+		return;
+	}
+
+	viafb_write_reg_mask(0x67, VIACR, value, 0xC0);
+}
+
+static void set_color_register(u8 index, u8 red, u8 green, u8 blue)
+{
+	outb(0xFF, 0x3C6); /* bit mask of palette */
+	outb(index, 0x3C8);
+	outb(red, 0x3C9);
+	outb(green, 0x3C9);
+	outb(blue, 0x3C9);
+}
+
+void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue)
+{
+	viafb_write_reg_mask(0x1A, VIASR, 0x00, 0x01);
+	set_color_register(index, red, green, blue);
+}
+
+void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue)
+{
+	viafb_write_reg_mask(0x1A, VIASR, 0x01, 0x01);
+	set_color_register(index, red, green, blue);
+}
+
 void viafb_set_output_path(int device, int set_iga, int output_interface)
 {
 	switch (device) {
@@ -710,11 +787,8 @@ static void set_crt_output_path(int set_
 		viafb_write_reg_mask(SR16, VIASR, 0x00, BIT6);
 		break;
 	case IGA2:
-	case IGA1_IGA2:
 		viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7);
 		viafb_write_reg_mask(SR16, VIASR, 0x40, BIT6);
-		if (set_iga == IGA1_IGA2)
-			viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3);
 		break;
 	}
 }
@@ -904,13 +978,6 @@ static void set_lcd_output_path(int set_
 
 		enable_second_display_channel();
 		break;
-
-	case IGA1_IGA2:
-		viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3);
-		viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
-
-		disable_second_display_channel();
-		break;
 	}
 
 	switch (output_interface) {
@@ -987,49 +1054,6 @@ static void set_lcd_output_path(int set_
 	}
 }
 
-/* Search Mode Index */
-static int search_mode_setting(int ModeInfoIndex)
-{
-	int i = 0;
-
-	while ((i < NUM_TOTAL_MODETABLE) &&
-			(ModeInfoIndex != CLE266Modes[i].ModeIndex))
-		i++;
-	if (i >= NUM_TOTAL_MODETABLE)
-		i = 0;
-	return i;
-
-}
-
-struct VideoModeTable *viafb_get_modetbl_pointer(int Index)
-{
-	struct VideoModeTable *TmpTbl = NULL;
-	TmpTbl = &CLE266Modes[search_mode_setting(Index)];
-	return TmpTbl;
-}
-
-struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index)
-{
-	struct VideoModeTable *TmpTbl = NULL;
-	int i = 0;
-	while ((i < NUM_TOTAL_CEA_MODES) &&
-			(Index != CEA_HDMI_Modes[i].ModeIndex))
-		i++;
-	if ((i < NUM_TOTAL_CEA_MODES))
-		TmpTbl = &CEA_HDMI_Modes[i];
-	 else {
-		/*Still use general timing if don't find CEA timing */
-		i = 0;
-		while ((i < NUM_TOTAL_MODETABLE) &&
-				(Index != CLE266Modes[i].ModeIndex))
-		       i++;
-		if (i >= NUM_TOTAL_MODETABLE)
-			i = 0;
-		TmpTbl = &CLE266Modes[i];
-	}
-	return TmpTbl;
-}
-
 static void load_fix_bit_crtc_reg(void)
 {
 	/* always set to 1 */
@@ -1121,15 +1145,13 @@ void viafb_load_fetch_count_reg(int h_ad
 	struct io_register *reg = NULL;
 
 	switch (set_iga) {
-	case IGA1_IGA2:
 	case IGA1:
 		reg_value = IGA1_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
 		viafb_load_reg_num = fetch_count_reg.
 			iga1_fetch_count_reg.reg_num;
 		reg = fetch_count_reg.iga1_fetch_count_reg.reg;
 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
-		if (set_iga == IGA1)
-			break;
+		break;
 	case IGA2:
 		reg_value = IGA2_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
 		viafb_load_reg_num = fetch_count_reg.
@@ -1499,7 +1521,7 @@ void viafb_set_vclock(u32 CLK, int set_i
 	/* H.W. Reset : ON */
 	viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
 
-	if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) {
+	if (set_iga == IGA1) {
 		/* Change D,N FOR VCLK */
 		switch (viaparinfo->chip_info->gfx_chip_name) {
 		case UNICHROME_CLE266:
@@ -1528,7 +1550,7 @@ void viafb_set_vclock(u32 CLK, int set_i
 		}
 	}
 
-	if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) {
+	if (set_iga == IGA2) {
 		/* Change D,N FOR LCK */
 		switch (viaparinfo->chip_info->gfx_chip_name) {
 		case UNICHROME_CLE266:
@@ -1557,12 +1579,12 @@ void viafb_set_vclock(u32 CLK, int set_i
 	viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
 
 	/* Reset PLL */
-	if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) {
+	if (set_iga == IGA1) {
 		viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
 		viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
 	}
 
-	if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) {
+	if (set_iga == IGA2) {
 		viafb_write_reg_mask(SR40, VIASR, 0x01, BIT0);
 		viafb_write_reg_mask(SR40, VIASR, 0x00, BIT0);
 	}
@@ -1805,47 +1827,15 @@ void viafb_load_crtc_timing(struct displ
 	viafb_lock_crt();
 }
 
-void viafb_set_color_depth(int bpp_byte, int set_iga)
-{
-	if (set_iga == IGA1) {
-		switch (bpp_byte) {
-		case MODE_8BPP:
-			viafb_write_reg_mask(SR15, VIASR, 0x22, 0x7E);
-			break;
-		case MODE_16BPP:
-			viafb_write_reg_mask(SR15, VIASR, 0xB6, 0xFE);
-			break;
-		case MODE_32BPP:
-			viafb_write_reg_mask(SR15, VIASR, 0xAE, 0xFE);
-			break;
-		}
-	} else {
-		switch (bpp_byte) {
-		case MODE_8BPP:
-			viafb_write_reg_mask(CR67, VIACR, 0x00, BIT6 + BIT7);
-			break;
-		case MODE_16BPP:
-			viafb_write_reg_mask(CR67, VIACR, 0x40, BIT6 + BIT7);
-			break;
-		case MODE_32BPP:
-			viafb_write_reg_mask(CR67, VIACR, 0xC0, BIT6 + BIT7);
-			break;
-		}
-	}
-}
-
 void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
-	int mode_index, int bpp_byte, int set_iga)
+	struct VideoModeTable *video_mode, int bpp_byte, int set_iga)
 {
-	struct VideoModeTable *video_mode;
 	struct display_timing crt_reg;
 	int i;
 	int index = 0;
 	int h_addr, v_addr;
 	u32 pll_D_N;
 
-	video_mode = &CLE266Modes[search_mode_setting(mode_index)];
-
 	for (i = 0; i < video_mode->mode_array; i++) {
 		index = i;
 
@@ -1858,8 +1848,10 @@ void viafb_fill_crtc_timing(struct crt_m
 
 	/* Mode 640x480 has border, but LCD/DFP didn't have border. */
 	/* So we would delete border. */
-	if ((viafb_LCD_ON | viafb_DVI_ON) && (mode_index == VIA_RES_640X480)
-	    && (viaparinfo->crt_setting_info->refresh_rate == 60)) {
+	if ((viafb_LCD_ON | viafb_DVI_ON)
+	    && video_mode->crtc[0].crtc.hor_addr == 640
+	    && video_mode->crtc[0].crtc.ver_addr == 480
+	    && viaparinfo->crt_setting_info->refresh_rate == 60) {
 		/* The border is 8 pixels. */
 		crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8;
 
@@ -1912,9 +1904,6 @@ void viafb_fill_crtc_timing(struct crt_m
 	    && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
 		viafb_load_FIFO_reg(set_iga, h_addr, v_addr);
 
-	/* load SR Register About Memory and Color part */
-	viafb_set_color_depth(bpp_byte, set_iga);
-
 	pll_D_N = viafb_get_clk_value(crt_table[index].clk);
 	DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N);
 	viafb_set_vclock(pll_D_N, set_iga);
@@ -1956,9 +1945,6 @@ void viafb_update_device_setting(int hre
 
 		viaparinfo->tmds_setting_info->h_active = hres;
 		viaparinfo->tmds_setting_info->v_active = vres;
-		viaparinfo->tmds_setting_info->bpp = bpp;
-		viaparinfo->tmds_setting_info->refresh_rate =
-			vmode_refresh;
 
 		viaparinfo->lvds_setting_info->h_active = hres;
 		viaparinfo->lvds_setting_info->v_active = vres;
@@ -1975,9 +1961,6 @@ void viafb_update_device_setting(int hre
 		if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
 			viaparinfo->tmds_setting_info->h_active = hres;
 			viaparinfo->tmds_setting_info->v_active = vres;
-			viaparinfo->tmds_setting_info->bpp = bpp;
-			viaparinfo->tmds_setting_info->refresh_rate =
-				vmode_refresh;
 		}
 
 		if (viaparinfo->lvds_setting_info->iga_path == IGA2) {
@@ -2076,9 +2059,8 @@ static void init_tmds_chip_info(void)
 
 	DEBUG_MSG(KERN_INFO "TMDS Chip = %d\n",
 		  viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
-	viaparinfo->tmds_setting_info->get_dvi_size_method =
-		GET_DVI_SIZE_BY_VGA_BIOS;
-	viafb_init_dvi_size();
+	viafb_init_dvi_size(&viaparinfo->shared->chip_info.tmds_chip_info,
+		&viaparinfo->shared->tmds_setting_info);
 }
 
 static void init_lvds_chip_info(void)
@@ -2195,28 +2177,19 @@ static void set_display_channel(void)
 	}
 }
 
-int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
-	int vmode_index1, int hor_res1, int ver_res1, int video_bpp1)
+int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
+	struct VideoModeTable *vmode_tbl1, int video_bpp1)
 {
 	int i, j;
 	int port;
 	u8 value, index, mask;
-	struct VideoModeTable *vmode_tbl;
 	struct crt_mode_table *crt_timing;
-	struct VideoModeTable *vmode_tbl1 = NULL;
 	struct crt_mode_table *crt_timing1 = NULL;
 
-	DEBUG_MSG(KERN_INFO "Set Mode!!\n");
-	DEBUG_MSG(KERN_INFO
-		  "vmode_index=%d hor_res=%d ver_res=%d video_bpp=%d\n",
-		  vmode_index, hor_res, ver_res, video_bpp);
-
 	device_screen_off();
-	vmode_tbl = &CLE266Modes[search_mode_setting(vmode_index)];
 	crt_timing = vmode_tbl->crtc;
 
 	if (viafb_SAMM_ON == 1) {
-		vmode_tbl1 = &CLE266Modes[search_mode_setting(vmode_index1)];
 		crt_timing1 = vmode_tbl1->crtc;
 	}
 
@@ -2267,12 +2240,11 @@ int viafb_setmode(int vmode_index, int h
 		outb(VPIT.SR[i - 1], VIASR + 1);
 	}
 
-	viafb_set_primary_address(0);
-	viafb_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0);
+	viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2);
 	viafb_set_iga_path();
 
 	/* Write CRTC */
-	viafb_fill_crtc_timing(crt_timing, vmode_index, video_bpp / 8, IGA1);
+	viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1);
 
 	/* Write Graphic Controller */
 	for (i = 0; i < StdGR; i++) {
@@ -2292,65 +2264,25 @@ int viafb_setmode(int vmode_index, int h
 
 	/* Update Patch Register */
 
-	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
-	    || (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)) {
-		for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) {
-			if (res_patch_table[i].mode_index == vmode_index) {
-				for (j = 0;
-				     j < res_patch_table[i].table_length; j++) {
-					index =
-					    res_patch_table[i].
-					    io_reg_table[j].index;
-					port =
-					    res_patch_table[i].
-					    io_reg_table[j].port;
-					value =
-					    res_patch_table[i].
-					    io_reg_table[j].value;
-					mask =
-					    res_patch_table[i].
-					    io_reg_table[j].mask;
-					viafb_write_reg_mask(index, port, value,
-						       mask);
-				}
-			}
-		}
-	}
-
-	if (viafb_SAMM_ON == 1) {
-		if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
-		    || (viaparinfo->chip_info->gfx_chip_name ==
-		    UNICHROME_K400)) {
-			for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) {
-				if (res_patch_table[i].mode_index ==
-				    vmode_index1) {
-					for (j = 0;
-					     j <
-					     res_patch_table[i].
-					     table_length; j++) {
-						index =
-						    res_patch_table[i].
-						    io_reg_table[j].index;
-						port =
-						    res_patch_table[i].
-						    io_reg_table[j].port;
-						value =
-						    res_patch_table[i].
-						    io_reg_table[j].value;
-						mask =
-						    res_patch_table[i].
-						    io_reg_table[j].mask;
-						viafb_write_reg_mask(index,
-							port, value, mask);
-					}
-				}
-			}
+	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266
+	    || viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)
+	    && vmode_tbl->crtc[0].crtc.hor_addr == 1024
+	    && vmode_tbl->crtc[0].crtc.ver_addr == 768) {
+		for (j = 0; j < res_patch_table[0].table_length; j++) {
+			index = res_patch_table[0].io_reg_table[j].index;
+			port = res_patch_table[0].io_reg_table[j].port;
+			value = res_patch_table[0].io_reg_table[j].value;
+			mask = res_patch_table[0].io_reg_table[j].mask;
+			viafb_write_reg_mask(index, port, value, mask);
 		}
 	}
 
 	viafb_set_primary_pitch(viafbinfo->fix.line_length);
 	viafb_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length
 		: viafbinfo->fix.line_length);
+	viafb_set_primary_color_depth(viaparinfo->depth);
+	viafb_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth
+		: viaparinfo->depth);
 	/* Update Refresh Rate Setting */
 
 	/* Clear On Screen */
@@ -2359,11 +2291,11 @@ int viafb_setmode(int vmode_index, int h
 	if (viafb_CRT_ON) {
 		if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path ==
 			IGA2)) {
-			viafb_fill_crtc_timing(crt_timing1, vmode_index1,
+			viafb_fill_crtc_timing(crt_timing1, vmode_tbl1,
 				video_bpp1 / 8,
 				viaparinfo->crt_setting_info->iga_path);
 		} else {
-			viafb_fill_crtc_timing(crt_timing, vmode_index,
+			viafb_fill_crtc_timing(crt_timing, vmode_tbl,
 				video_bpp / 8,
 				viaparinfo->crt_setting_info->iga_path);
 		}
@@ -2373,7 +2305,7 @@ int viafb_setmode(int vmode_index, int h
 		/* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
 		to 8 alignment (1368),there is several pixels (2 pixels)
 		on right side of screen. */
-		if (hor_res % 8) {
+		if (vmode_tbl->crtc[0].crtc.hor_addr % 8) {
 			viafb_unlock_crt();
 			viafb_write_reg(CR02, VIACR,
 				viafb_read_reg(VIACR, CR02) - 1);
@@ -2384,14 +2316,14 @@ int viafb_setmode(int vmode_index, int h
 	if (viafb_DVI_ON) {
 		if (viafb_SAMM_ON &&
 			(viaparinfo->tmds_setting_info->iga_path == IGA2)) {
-			viafb_dvi_set_mode(viafb_get_mode_index
+			viafb_dvi_set_mode(viafb_get_mode
 				     (viaparinfo->tmds_setting_info->h_active,
 				      viaparinfo->tmds_setting_info->
 				      v_active),
 				     video_bpp1, viaparinfo->
 				     tmds_setting_info->iga_path);
 		} else {
-			viafb_dvi_set_mode(viafb_get_mode_index
+			viafb_dvi_set_mode(viafb_get_mode
 				     (viaparinfo->tmds_setting_info->h_active,
 				      viaparinfo->
 				      tmds_setting_info->v_active),
@@ -2445,8 +2377,8 @@ int viafb_setmode(int vmode_index, int h
 
 	/* If set mode normally, save resolution information for hot-plug . */
 	if (!viafb_hotplug) {
-		viafb_hotplug_Xres = hor_res;
-		viafb_hotplug_Yres = ver_res;
+		viafb_hotplug_Xres = vmode_tbl->crtc[0].crtc.hor_addr;
+		viafb_hotplug_Yres = vmode_tbl->crtc[0].crtc.ver_addr;
 		viafb_hotplug_bpp = video_bpp;
 		viafb_hotplug_refresh = viafb_refresh;
 
@@ -2706,13 +2638,11 @@ void viafb_set_dpa_gfx(int output_interf
 
 /*According var's xres, yres fill var's other timing information*/
 void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
-			  int mode_index)
+	struct VideoModeTable *vmode_tbl)
 {
-	struct VideoModeTable *vmode_tbl = NULL;
 	struct crt_mode_table *crt_timing = NULL;
 	struct display_timing crt_reg;
 	int i = 0, index = 0;
-	vmode_tbl = &CLE266Modes[search_mode_setting(mode_index)];
 	crt_timing = vmode_tbl->crtc;
 	for (i = 0; i < vmode_tbl->mode_array; i++) {
 		index = i;
@@ -2721,36 +2651,6 @@ void viafb_fill_var_timing_info(struct f
 	}
 
 	crt_reg = crt_timing[index].crtc;
-	switch (var->bits_per_pixel) {
-	case 8:
-		var->red.offset = 0;
-		var->green.offset = 0;
-		var->blue.offset = 0;
-		var->red.length = 6;
-		var->green.length = 6;
-		var->blue.length = 6;
-		break;
-	case 16:
-		var->red.offset = 11;
-		var->green.offset = 5;
-		var->blue.offset = 0;
-		var->red.length = 5;
-		var->green.length = 6;
-		var->blue.length = 5;
-		break;
-	case 32:
-		var->red.offset = 16;
-		var->green.offset = 8;
-		var->blue.offset = 0;
-		var->red.length = 8;
-		var->green.length = 8;
-		var->blue.length = 8;
-		break;
-	default:
-		/* never happed, put here to keep consistent */
-		break;
-	}
-
 	var->pixclock = viafb_get_pixclock(var->xres, var->yres, refresh);
 	var->left_margin =
 	    crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/hw.h linux-libre-2.6.34-gnu1/drivers/video/via/hw.h
--- linux-libre-2.6.33-gnu1/drivers/video/via/hw.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/hw.h	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #ifndef __HW_H__
 #define __HW_H__
 
+#include "viamode.h"
 #include "global.h"
 
 /***************************************************
@@ -862,8 +863,6 @@ struct pci_device_id_info {
 };
 
 extern unsigned int viafb_second_virtual_xres;
-extern unsigned int viafb_second_offset;
-extern int viafb_second_size;
 extern int viafb_SAMM_ON;
 extern int viafb_dual_fb;
 extern int viafb_LCD2_ON;
@@ -874,8 +873,9 @@ extern int viafb_hotplug;
 void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask);
 void viafb_set_output_path(int device, int set_iga,
 	int output_interface);
+
 void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
-		      int mode_index, int bpp_byte, int set_iga);
+	struct VideoModeTable *video_mode, int bpp_byte, int set_iga);
 
 void viafb_set_vclock(u32 CLK, int set_iga);
 void viafb_load_reg(int timing_value, int viafb_load_reg_num,
@@ -891,16 +891,15 @@ void viafb_lock_crt(void);
 void viafb_unlock_crt(void);
 void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga);
 void viafb_write_regx(struct io_reg RegTable[], int ItemNum);
-struct VideoModeTable *viafb_get_modetbl_pointer(int Index);
 u32 viafb_get_clk_value(int clk);
 void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active);
-void viafb_set_color_depth(int bpp_byte, int set_iga);
 void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
 					*p_gfx_dpa_setting);
 
-int viafb_setmode(int vmode_index, int hor_res, int ver_res,
-	    int video_bpp, int vmode_index1, int hor_res1,
-	    int ver_res1, int video_bpp1);
+int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
+	struct VideoModeTable *vmode_tbl1, int video_bpp1);
+void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
+	struct VideoModeTable *vmode_tbl);
 void viafb_init_chip_info(struct pci_dev *pdev,
 			  const struct pci_device_id *pdi);
 void viafb_init_dac(int set_iga);
@@ -915,6 +914,8 @@ void viafb_set_primary_address(u32 addr)
 void viafb_set_secondary_address(u32 addr);
 void viafb_set_primary_pitch(u32 pitch);
 void viafb_set_secondary_pitch(u32 pitch);
+void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue);
+void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue);
 void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len);
 
 #endif /* __HW_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/iface.c linux-libre-2.6.34-gnu1/drivers/video/via/iface.c
--- linux-libre-2.6.33-gnu1/drivers/video/via/iface.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/iface.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,78 +0,0 @@
-/*
- * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
- * Copyright 2001-2008 S3 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, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
- * the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE.See the GNU General Public License
- * for more details.
-
- * You 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 "global.h"
-
-/* Get frame buffer size from VGA BIOS */
-
-unsigned int viafb_get_memsize(void)
-{
-	unsigned int m;
-
-	/* If memory size provided by user */
-	if (viafb_memsize)
-		m = viafb_memsize * Mb;
-	else {
-		m = (unsigned int)viafb_read_reg(VIASR, SR39);
-		m = m * (4 * Mb);
-
-		if ((m < (16 * Mb)) || (m > (64 * Mb)))
-			m = 16 * Mb;
-	}
-	DEBUG_MSG(KERN_INFO "framebuffer size = %d Mb\n", m / Mb);
-	return m;
-}
-
-/* Get Video Buffer Starting Physical Address(back door)*/
-
-unsigned long viafb_get_videobuf_addr(void)
-{
-	struct pci_dev *pdev = NULL;
-	unsigned char sys_mem;
-	unsigned char video_mem;
-	unsigned long sys_mem_size;
-	unsigned long video_mem_size;
-	/*system memory = 256 MB, video memory 64 MB */
-	unsigned long vmem_starting_adr = 0x0C000000;
-
-	pdev =
-	    (struct pci_dev *)pci_get_device(VIA_K800_BRIDGE_VID,
-					     VIA_K800_BRIDGE_DID, NULL);
-	if (pdev != NULL) {
-		pci_read_config_byte(pdev, VIA_K800_SYSTEM_MEMORY_REG,
-				     &sys_mem);
-		pci_read_config_byte(pdev, VIA_K800_VIDEO_MEMORY_REG,
-				     &video_mem);
-		video_mem = (video_mem & 0x70) >> 4;
-		sys_mem_size = ((unsigned long)sys_mem) << 24;
-		if (video_mem != 0)
-			video_mem_size = (1 << (video_mem)) * 1024 * 1024;
-		else
-			video_mem_size = 0;
-
-		vmem_starting_adr = sys_mem_size - video_mem_size;
-		pci_dev_put(pdev);
-	}
-
-	DEBUG_MSG(KERN_INFO "Video Memory Starting Address = %lx \n",
-		  vmem_starting_adr);
-	return vmem_starting_adr;
-}
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/iface.h linux-libre-2.6.34-gnu1/drivers/video/via/iface.h
--- linux-libre-2.6.33-gnu1/drivers/video/via/iface.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/iface.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,38 +0,0 @@
-/*
- * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
- * Copyright 2001-2008 S3 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, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
- * the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE.See the GNU General Public License
- * for more details.
-
- * You 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 __IFACE_H__
-#define __IFACE_H__
-
-#define Kb  (1024)
-#define Mb  (Kb*Kb)
-
-#define VIA_K800_BRIDGE_VID         0x1106
-#define VIA_K800_BRIDGE_DID         0x3204
-
-#define VIA_K800_SYSTEM_MEMORY_REG  0x47
-#define VIA_K800_VIDEO_MEMORY_REG   0xA1
-
-extern int viafb_memsize;
-unsigned int viafb_get_memsize(void);
-unsigned long viafb_get_videobuf_addr(void);
-
-#endif /* __IFACE_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/lcd.c linux-libre-2.6.34-gnu1/drivers/video/via/lcd.c
--- linux-libre-2.6.33-gnu1/drivers/video/via/lcd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/lcd.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,25 +22,7 @@
 #include "global.h"
 #include "lcdtbl.h"
 
-static struct iga2_shadow_crtc_timing iga2_shadow_crtc_reg = {
-	/* IGA2 Shadow Horizontal Total */
-	{IGA2_SHADOW_HOR_TOTAL_REG_NUM, {{CR6D, 0, 7}, {CR71, 3, 3} } },
-	/* IGA2 Shadow Horizontal Blank End */
-	{IGA2_SHADOW_HOR_BLANK_END_REG_NUM, {{CR6E, 0, 7} } },
-	/* IGA2 Shadow Vertical Total */
-	{IGA2_SHADOW_VER_TOTAL_REG_NUM, {{CR6F, 0, 7}, {CR71, 0, 2} } },
-	/* IGA2 Shadow Vertical Addressable Video */
-	{IGA2_SHADOW_VER_ADDR_REG_NUM, {{CR70, 0, 7}, {CR71, 4, 6} } },
-	/* IGA2 Shadow Vertical Blank Start */
-	{IGA2_SHADOW_VER_BLANK_START_REG_NUM,
-	 {{CR72, 0, 7}, {CR74, 4, 6} } },
-	/* IGA2 Shadow Vertical Blank End */
-	{IGA2_SHADOW_VER_BLANK_END_REG_NUM, {{CR73, 0, 7}, {CR74, 0, 2} } },
-	/* IGA2 Shadow Vertical Sync Start */
-	{IGA2_SHADOW_VER_SYNC_START_REG_NUM, {{CR75, 0, 7}, {CR76, 4, 6} } },
-	/* IGA2 Shadow Vertical Sync End */
-	{IGA2_SHADOW_VER_SYNC_END_REG_NUM, {{CR76, 0, 3} } }
-};
+#define viafb_compact_res(x, y) (((x)<<16)|(y))
 
 static struct _lcd_scaling_factor lcd_scaling_factor = {
 	/* LCD Horizontal Scaling Factor Register */
@@ -59,16 +41,10 @@ static struct _lcd_scaling_factor lcd_sc
 
 static int check_lvds_chip(int device_id_subaddr, int device_id);
 static bool lvds_identify_integratedlvds(void);
-static int fp_id_to_vindex(int panel_id);
+static void fp_id_to_vindex(int panel_id);
 static int lvds_register_read(int index);
 static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
 		      int panel_vres);
-static void load_lcd_k400_patch_tbl(int set_hres, int set_vres,
-	int panel_id);
-static void load_lcd_p880_patch_tbl(int set_hres, int set_vres,
-	int panel_id);
-static void load_lcd_patch_regs(int set_hres, int set_vres,
-	int panel_id, int set_iga);
 static void via_pitch_alignment_patch_lcd(
 	struct lvds_setting_information *plvds_setting_info,
 				   struct lvds_chip_information
@@ -98,8 +74,6 @@ static void check_diport_of_integrated_l
 static struct display_timing lcd_centering_timging(struct display_timing
 					    mode_crt_reg,
 					   struct display_timing panel_crt_reg);
-static void load_crtc_shadow_timing(struct display_timing mode_timing,
-			     struct display_timing panel_timing);
 static void viafb_load_scaling_factor_for_p4m900(int set_hres,
 	int set_vres, int panel_hres, int panel_vres);
 
@@ -125,33 +99,24 @@ void viafb_init_lcd_size(void)
 		break;
 	case GET_LCD_SIZE_BY_VGA_BIOS:
 		DEBUG_MSG(KERN_INFO "Get LCD Size method by VGA BIOS !!\n");
-		viaparinfo->lvds_setting_info->lcd_panel_size =
-		    fp_id_to_vindex(viafb_lcd_panel_id);
+		fp_id_to_vindex(viafb_lcd_panel_id);
 		DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
 			  viaparinfo->lvds_setting_info->lcd_panel_id);
-		DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n",
-			  viaparinfo->lvds_setting_info->lcd_panel_size);
 		break;
 	case GET_LCD_SIZE_BY_USER_SETTING:
 		DEBUG_MSG(KERN_INFO "Get LCD Size method by user setting !!\n");
-		viaparinfo->lvds_setting_info->lcd_panel_size =
-		    fp_id_to_vindex(viafb_lcd_panel_id);
+		fp_id_to_vindex(viafb_lcd_panel_id);
 		DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
 			  viaparinfo->lvds_setting_info->lcd_panel_id);
-		DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n",
-			  viaparinfo->lvds_setting_info->lcd_panel_size);
 		break;
 	default:
 		DEBUG_MSG(KERN_INFO "viafb_init_lcd_size fail\n");
 		viaparinfo->lvds_setting_info->lcd_panel_id =
 			LCD_PANEL_ID1_800X600;
-		viaparinfo->lvds_setting_info->lcd_panel_size =
-		    fp_id_to_vindex(LCD_PANEL_ID1_800X600);
+		fp_id_to_vindex(LCD_PANEL_ID1_800X600);
 	}
 	viaparinfo->lvds_setting_info2->lcd_panel_id =
 		viaparinfo->lvds_setting_info->lcd_panel_id;
-	viaparinfo->lvds_setting_info2->lcd_panel_size =
-		viaparinfo->lvds_setting_info->lcd_panel_size;
 	viaparinfo->lvds_setting_info2->lcd_panel_hres =
 		viaparinfo->lvds_setting_info->lcd_panel_hres;
 	viaparinfo->lvds_setting_info2->lcd_panel_vres =
@@ -171,13 +136,13 @@ static bool lvds_identify_integratedlvds
 		if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
 			viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
 			    INTEGRATED_LVDS;
-			DEBUG_MSG(KERN_INFO "Support two dual channel LVDS!\
-				  (Internal LVDS + External LVDS)\n");
+			DEBUG_MSG(KERN_INFO "Support two dual channel LVDS! "
+				  "(Internal LVDS + External LVDS)\n");
 		} else {
 			viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
 			    INTEGRATED_LVDS;
-			DEBUG_MSG(KERN_INFO "Not found external LVDS,\
-				  so can't support two dual channel LVDS!\n");
+			DEBUG_MSG(KERN_INFO "Not found external LVDS, "
+				  "so can't support two dual channel LVDS!\n");
 		}
 	} else if (viafb_display_hardware_layout == HW_LAYOUT_LCD1_LCD2) {
 		/* Two single channel LCD (Internal LVDS + Internal LVDS): */
@@ -185,8 +150,8 @@ static bool lvds_identify_integratedlvds
 		INTEGRATED_LVDS;
 		viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
 			INTEGRATED_LVDS;
-		DEBUG_MSG(KERN_INFO "Support two single channel LVDS!\
-			  (Internal LVDS + Internal LVDS)\n");
+		DEBUG_MSG(KERN_INFO "Support two single channel LVDS! "
+			  "(Internal LVDS + Internal LVDS)\n");
 	} else if (viafb_display_hardware_layout != HW_LAYOUT_DVI_ONLY) {
 		/* If we have found external LVDS, just use it,
 		   otherwise, we will use internal LVDS as default. */
@@ -248,7 +213,7 @@ int viafb_lvds_trasmitter_identify(void)
 	return FAIL;
 }
 
-static int fp_id_to_vindex(int panel_id)
+static void fp_id_to_vindex(int panel_id)
 {
 	DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n");
 
@@ -264,7 +229,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID0_640X480;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 		viaparinfo->lvds_setting_info->LCDDithering = 1;
-		return VIA_RES_640X480;
 		break;
 	case 0x1:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
@@ -273,7 +237,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID1_800X600;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 		viaparinfo->lvds_setting_info->LCDDithering = 1;
-		return VIA_RES_800X600;
 		break;
 	case 0x2:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
@@ -282,7 +245,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID2_1024X768;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 		viaparinfo->lvds_setting_info->LCDDithering = 1;
-		return VIA_RES_1024X768;
 		break;
 	case 0x3:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
@@ -291,7 +253,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID3_1280X768;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 		viaparinfo->lvds_setting_info->LCDDithering = 1;
-		return VIA_RES_1280X768;
 		break;
 	case 0x4:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
@@ -300,7 +261,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID4_1280X1024;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 		viaparinfo->lvds_setting_info->LCDDithering = 1;
-		return VIA_RES_1280X1024;
 		break;
 	case 0x5:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
@@ -309,7 +269,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID5_1400X1050;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 		viaparinfo->lvds_setting_info->LCDDithering = 1;
-		return VIA_RES_1400X1050;
 		break;
 	case 0x6:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
@@ -318,7 +277,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID6_1600X1200;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 		viaparinfo->lvds_setting_info->LCDDithering = 1;
-		return VIA_RES_1600X1200;
 		break;
 	case 0x8:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
@@ -327,7 +285,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_IDA_800X480;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 		viaparinfo->lvds_setting_info->LCDDithering = 1;
-		return VIA_RES_800X480;
 		break;
 	case 0x9:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
@@ -336,7 +293,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID2_1024X768;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 		viaparinfo->lvds_setting_info->LCDDithering = 1;
-		return VIA_RES_1024X768;
 		break;
 	case 0xA:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
@@ -345,7 +301,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID2_1024X768;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 		viaparinfo->lvds_setting_info->LCDDithering = 0;
-		return VIA_RES_1024X768;
 		break;
 	case 0xB:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
@@ -354,7 +309,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID2_1024X768;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 		viaparinfo->lvds_setting_info->LCDDithering = 0;
-		return VIA_RES_1024X768;
 		break;
 	case 0xC:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
@@ -363,7 +317,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID3_1280X768;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 		viaparinfo->lvds_setting_info->LCDDithering = 0;
-		return VIA_RES_1280X768;
 		break;
 	case 0xD:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
@@ -372,7 +325,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID4_1280X1024;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 		viaparinfo->lvds_setting_info->LCDDithering = 0;
-		return VIA_RES_1280X1024;
 		break;
 	case 0xE:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
@@ -381,7 +333,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID5_1400X1050;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 		viaparinfo->lvds_setting_info->LCDDithering = 0;
-		return VIA_RES_1400X1050;
 		break;
 	case 0xF:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
@@ -390,7 +341,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID6_1600X1200;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 		viaparinfo->lvds_setting_info->LCDDithering = 0;
-		return VIA_RES_1600X1200;
 		break;
 	case 0x10:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1366;
@@ -399,7 +349,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID7_1366X768;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 		viaparinfo->lvds_setting_info->LCDDithering = 0;
-		return VIA_RES_1368X768;
 		break;
 	case 0x11:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
@@ -408,7 +357,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID8_1024X600;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 		viaparinfo->lvds_setting_info->LCDDithering = 1;
-		return VIA_RES_1024X600;
 		break;
 	case 0x12:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
@@ -417,7 +365,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID3_1280X768;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 		viaparinfo->lvds_setting_info->LCDDithering = 1;
-		return VIA_RES_1280X768;
 		break;
 	case 0x13:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
@@ -426,7 +373,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID9_1280X800;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 		viaparinfo->lvds_setting_info->LCDDithering = 1;
-		return VIA_RES_1280X800;
 		break;
 	case 0x14:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1360;
@@ -435,7 +381,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_IDB_1360X768;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 		viaparinfo->lvds_setting_info->LCDDithering = 0;
-		return VIA_RES_1360X768;
 		break;
 	case 0x15:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
@@ -444,7 +389,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID3_1280X768;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 		viaparinfo->lvds_setting_info->LCDDithering = 0;
-		return VIA_RES_1280X768;
 		break;
 	case 0x16:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 480;
@@ -453,7 +397,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_IDC_480X640;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 		viaparinfo->lvds_setting_info->LCDDithering = 1;
-		return VIA_RES_480X640;
 		break;
 	default:
 		viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
@@ -462,7 +405,6 @@ static int fp_id_to_vindex(int panel_id)
 			LCD_PANEL_ID1_800X600;
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 		viaparinfo->lvds_setting_info->LCDDithering = 1;
-		return VIA_RES_800X600;
 	}
 }
 
@@ -573,284 +515,6 @@ static void load_lcd_scaling(int set_hre
 	}
 }
 
-static void load_lcd_k400_patch_tbl(int set_hres, int set_vres,
-	int panel_id)
-{
-	int vmode_index;
-	int reg_num = 0;
-	struct io_reg *lcd_patch_reg = NULL;
-
-	vmode_index = viafb_get_mode_index(set_hres, set_vres);
-	switch (panel_id) {
-		/* LCD 800x600 */
-	case LCD_PANEL_ID1_800X600:
-		switch (vmode_index) {
-		case VIA_RES_640X400:
-		case VIA_RES_640X480:
-			reg_num = NUM_TOTAL_K400_LCD_RES_6X4_8X6;
-			lcd_patch_reg = K400_LCD_RES_6X4_8X6;
-			break;
-		case VIA_RES_720X480:
-		case VIA_RES_720X576:
-			reg_num = NUM_TOTAL_K400_LCD_RES_7X4_8X6;
-			lcd_patch_reg = K400_LCD_RES_7X4_8X6;
-			break;
-		}
-		break;
-
-		/* LCD 1024x768 */
-	case LCD_PANEL_ID2_1024X768:
-		switch (vmode_index) {
-		case VIA_RES_640X400:
-		case VIA_RES_640X480:
-			reg_num = NUM_TOTAL_K400_LCD_RES_6X4_10X7;
-			lcd_patch_reg = K400_LCD_RES_6X4_10X7;
-			break;
-		case VIA_RES_720X480:
-		case VIA_RES_720X576:
-			reg_num = NUM_TOTAL_K400_LCD_RES_7X4_10X7;
-			lcd_patch_reg = K400_LCD_RES_7X4_10X7;
-			break;
-		case VIA_RES_800X600:
-			reg_num = NUM_TOTAL_K400_LCD_RES_8X6_10X7;
-			lcd_patch_reg = K400_LCD_RES_8X6_10X7;
-			break;
-		}
-		break;
-
-		/* LCD 1280x1024 */
-	case LCD_PANEL_ID4_1280X1024:
-		switch (vmode_index) {
-		case VIA_RES_640X400:
-		case VIA_RES_640X480:
-			reg_num = NUM_TOTAL_K400_LCD_RES_6X4_12X10;
-			lcd_patch_reg = K400_LCD_RES_6X4_12X10;
-			break;
-		case VIA_RES_720X480:
-		case VIA_RES_720X576:
-			reg_num = NUM_TOTAL_K400_LCD_RES_7X4_12X10;
-			lcd_patch_reg = K400_LCD_RES_7X4_12X10;
-			break;
-		case VIA_RES_800X600:
-			reg_num = NUM_TOTAL_K400_LCD_RES_8X6_12X10;
-			lcd_patch_reg = K400_LCD_RES_8X6_12X10;
-			break;
-		case VIA_RES_1024X768:
-			reg_num = NUM_TOTAL_K400_LCD_RES_10X7_12X10;
-			lcd_patch_reg = K400_LCD_RES_10X7_12X10;
-			break;
-
-		}
-		break;
-
-		/* LCD 1400x1050 */
-	case LCD_PANEL_ID5_1400X1050:
-		switch (vmode_index) {
-		case VIA_RES_640X480:
-			reg_num = NUM_TOTAL_K400_LCD_RES_6X4_14X10;
-			lcd_patch_reg = K400_LCD_RES_6X4_14X10;
-			break;
-		case VIA_RES_800X600:
-			reg_num = NUM_TOTAL_K400_LCD_RES_8X6_14X10;
-			lcd_patch_reg = K400_LCD_RES_8X6_14X10;
-			break;
-		case VIA_RES_1024X768:
-			reg_num = NUM_TOTAL_K400_LCD_RES_10X7_14X10;
-			lcd_patch_reg = K400_LCD_RES_10X7_14X10;
-			break;
-		case VIA_RES_1280X768:
-		case VIA_RES_1280X800:
-		case VIA_RES_1280X960:
-		case VIA_RES_1280X1024:
-			reg_num = NUM_TOTAL_K400_LCD_RES_12X10_14X10;
-			lcd_patch_reg = K400_LCD_RES_12X10_14X10;
-			break;
-		}
-		break;
-
-		/* LCD 1600x1200 */
-	case LCD_PANEL_ID6_1600X1200:
-		switch (vmode_index) {
-		case VIA_RES_640X400:
-		case VIA_RES_640X480:
-			reg_num = NUM_TOTAL_K400_LCD_RES_6X4_16X12;
-			lcd_patch_reg = K400_LCD_RES_6X4_16X12;
-			break;
-		case VIA_RES_720X480:
-		case VIA_RES_720X576:
-			reg_num = NUM_TOTAL_K400_LCD_RES_7X4_16X12;
-			lcd_patch_reg = K400_LCD_RES_7X4_16X12;
-			break;
-		case VIA_RES_800X600:
-			reg_num = NUM_TOTAL_K400_LCD_RES_8X6_16X12;
-			lcd_patch_reg = K400_LCD_RES_8X6_16X12;
-			break;
-		case VIA_RES_1024X768:
-			reg_num = NUM_TOTAL_K400_LCD_RES_10X7_16X12;
-			lcd_patch_reg = K400_LCD_RES_10X7_16X12;
-			break;
-		case VIA_RES_1280X768:
-		case VIA_RES_1280X800:
-		case VIA_RES_1280X960:
-		case VIA_RES_1280X1024:
-			reg_num = NUM_TOTAL_K400_LCD_RES_12X10_16X12;
-			lcd_patch_reg = K400_LCD_RES_12X10_16X12;
-			break;
-		}
-		break;
-
-		/* LCD 1366x768 */
-	case LCD_PANEL_ID7_1366X768:
-		switch (vmode_index) {
-		case VIA_RES_640X480:
-			reg_num = NUM_TOTAL_K400_LCD_RES_6X4_1366X7;
-			lcd_patch_reg = K400_LCD_RES_6X4_1366X7;
-			break;
-		case VIA_RES_720X480:
-		case VIA_RES_720X576:
-			reg_num = NUM_TOTAL_K400_LCD_RES_7X4_1366X7;
-			lcd_patch_reg = K400_LCD_RES_7X4_1366X7;
-			break;
-		case VIA_RES_800X600:
-			reg_num = NUM_TOTAL_K400_LCD_RES_8X6_1366X7;
-			lcd_patch_reg = K400_LCD_RES_8X6_1366X7;
-			break;
-		case VIA_RES_1024X768:
-			reg_num = NUM_TOTAL_K400_LCD_RES_10X7_1366X7;
-			lcd_patch_reg = K400_LCD_RES_10X7_1366X7;
-			break;
-		case VIA_RES_1280X768:
-		case VIA_RES_1280X800:
-		case VIA_RES_1280X960:
-		case VIA_RES_1280X1024:
-			reg_num = NUM_TOTAL_K400_LCD_RES_12X10_1366X7;
-			lcd_patch_reg = K400_LCD_RES_12X10_1366X7;
-			break;
-		}
-		break;
-
-		/* LCD 1360x768 */
-	case LCD_PANEL_IDB_1360X768:
-		break;
-	}
-	if (reg_num != 0) {
-		/* H.W. Reset : ON */
-		viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
-
-		viafb_write_regx(lcd_patch_reg, reg_num);
-
-		/* H.W. Reset : OFF */
-		viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
-
-		/* Reset PLL */
-		viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
-		viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
-
-		/* Fire! */
-		outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc);
-	}
-}
-
-static void load_lcd_p880_patch_tbl(int set_hres, int set_vres,
-	int panel_id)
-{
-	int vmode_index;
-	int reg_num = 0;
-	struct io_reg *lcd_patch_reg = NULL;
-
-	vmode_index = viafb_get_mode_index(set_hres, set_vres);
-
-	switch (panel_id) {
-	case LCD_PANEL_ID5_1400X1050:
-		switch (vmode_index) {
-		case VIA_RES_640X480:
-			reg_num = NUM_TOTAL_P880_LCD_RES_6X4_14X10;
-			lcd_patch_reg = P880_LCD_RES_6X4_14X10;
-			break;
-		case VIA_RES_800X600:
-			reg_num = NUM_TOTAL_P880_LCD_RES_8X6_14X10;
-			lcd_patch_reg = P880_LCD_RES_8X6_14X10;
-			break;
-		}
-		break;
-	case LCD_PANEL_ID6_1600X1200:
-		switch (vmode_index) {
-		case VIA_RES_640X400:
-		case VIA_RES_640X480:
-			reg_num = NUM_TOTAL_P880_LCD_RES_6X4_16X12;
-			lcd_patch_reg = P880_LCD_RES_6X4_16X12;
-			break;
-		case VIA_RES_720X480:
-		case VIA_RES_720X576:
-			reg_num = NUM_TOTAL_P880_LCD_RES_7X4_16X12;
-			lcd_patch_reg = P880_LCD_RES_7X4_16X12;
-			break;
-		case VIA_RES_800X600:
-			reg_num = NUM_TOTAL_P880_LCD_RES_8X6_16X12;
-			lcd_patch_reg = P880_LCD_RES_8X6_16X12;
-			break;
-		case VIA_RES_1024X768:
-			reg_num = NUM_TOTAL_P880_LCD_RES_10X7_16X12;
-			lcd_patch_reg = P880_LCD_RES_10X7_16X12;
-			break;
-		case VIA_RES_1280X768:
-		case VIA_RES_1280X960:
-		case VIA_RES_1280X1024:
-			reg_num = NUM_TOTAL_P880_LCD_RES_12X10_16X12;
-			lcd_patch_reg = P880_LCD_RES_12X10_16X12;
-			break;
-		}
-		break;
-
-	}
-	if (reg_num != 0) {
-		/* H.W. Reset : ON */
-		viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
-
-		viafb_write_regx(lcd_patch_reg, reg_num);
-
-		/* H.W. Reset : OFF */
-		viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
-
-		/* Reset PLL */
-		viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
-		viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
-
-		/* Fire! */
-		outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc);
-	}
-}
-
-static void load_lcd_patch_regs(int set_hres, int set_vres,
-	int panel_id, int set_iga)
-{
-	int vmode_index;
-
-	vmode_index = viafb_get_mode_index(set_hres, set_vres);
-
-	viafb_unlock_crt();
-
-	/* Patch for simultaneous & Expansion */
-	if ((set_iga == IGA1_IGA2) &&
-		(viaparinfo->lvds_setting_info->display_method ==
-	    LCD_EXPANDSION)) {
-		switch (viaparinfo->chip_info->gfx_chip_name) {
-		case UNICHROME_CLE266:
-		case UNICHROME_K400:
-			load_lcd_k400_patch_tbl(set_hres, set_vres, panel_id);
-			break;
-		case UNICHROME_K800:
-			break;
-		case UNICHROME_PM800:
-		case UNICHROME_CN700:
-		case UNICHROME_CX700:
-			load_lcd_p880_patch_tbl(set_hres, set_vres, panel_id);
-		}
-	}
-
-	viafb_lock_crt();
-}
-
 static void via_pitch_alignment_patch_lcd(
 	struct lvds_setting_information *plvds_setting_info,
 				   struct lvds_chip_information
@@ -949,29 +613,25 @@ void viafb_lcd_set_mode(struct crt_mode_
 		  struct lvds_setting_information *plvds_setting_info,
 		  struct lvds_chip_information *plvds_chip_info)
 {
-	int video_index = plvds_setting_info->lcd_panel_size;
 	int set_iga = plvds_setting_info->iga_path;
 	int mode_bpp = plvds_setting_info->bpp;
-	int set_hres, set_vres;
-	int panel_hres, panel_vres;
+	int set_hres = plvds_setting_info->h_active;
+	int set_vres = plvds_setting_info->v_active;
+	int panel_hres = plvds_setting_info->lcd_panel_hres;
+	int panel_vres = plvds_setting_info->lcd_panel_vres;
 	u32 pll_D_N;
-	int offset;
 	struct display_timing mode_crt_reg, panel_crt_reg;
 	struct crt_mode_table *panel_crt_table = NULL;
-	struct VideoModeTable *vmode_tbl = NULL;
+	struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres,
+		panel_vres);
 
 	DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n");
 	/* Get mode table */
 	mode_crt_reg = mode_crt_table->crtc;
 	/* Get panel table Pointer */
-	vmode_tbl = viafb_get_modetbl_pointer(video_index);
 	panel_crt_table = vmode_tbl->crtc;
 	panel_crt_reg = panel_crt_table->crtc;
 	DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n");
-	set_hres = plvds_setting_info->h_active;
-	set_vres = plvds_setting_info->v_active;
-	panel_hres = plvds_setting_info->lcd_panel_hres;
-	panel_vres = plvds_setting_info->lcd_panel_vres;
 	if (VT1636_LVDS == plvds_chip_info->lvds_chip_name)
 		viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info);
 	plvds_setting_info->vclk = panel_crt_table->clk;
@@ -1001,54 +661,12 @@ void viafb_lcd_set_mode(struct crt_mode_
 		}
 	}
 
-	if (set_iga == IGA1_IGA2) {
-		load_crtc_shadow_timing(mode_crt_reg, panel_crt_reg);
-		/* Fill shadow registers */
-
-		switch (plvds_setting_info->lcd_panel_id) {
-		case LCD_PANEL_ID0_640X480:
-			offset = 80;
-			break;
-		case LCD_PANEL_ID1_800X600:
-		case LCD_PANEL_IDA_800X480:
-			offset = 110;
-			break;
-		case LCD_PANEL_ID2_1024X768:
-			offset = 150;
-			break;
-		case LCD_PANEL_ID3_1280X768:
-		case LCD_PANEL_ID4_1280X1024:
-		case LCD_PANEL_ID5_1400X1050:
-		case LCD_PANEL_ID9_1280X800:
-			offset = 190;
-			break;
-		case LCD_PANEL_ID6_1600X1200:
-			offset = 250;
-			break;
-		case LCD_PANEL_ID7_1366X768:
-		case LCD_PANEL_IDB_1360X768:
-			offset = 212;
-			break;
-		default:
-			offset = 140;
-			break;
-		}
-
-		/* Offset for simultaneous */
-		viafb_set_secondary_pitch(offset << 3);
-		DEBUG_MSG(KERN_INFO "viafb_load_reg!!\n");
-		viafb_load_fetch_count_reg(set_hres, 4, IGA2);
-		/* Fetch count for simultaneous */
-	} else {		/* SAMM */
-		/* Fetch count for IGA2 only */
-		viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga);
-
-		if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
-		    && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
-			viafb_load_FIFO_reg(set_iga, set_hres, set_vres);
+	/* Fetch count for IGA2 only */
+	viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga);
 
-		viafb_set_color_depth(mode_bpp / 8, set_iga);
-	}
+	if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
+		&& (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
+		viafb_load_FIFO_reg(set_iga, set_hres, set_vres);
 
 	fill_lcd_format();
 
@@ -1065,11 +683,6 @@ void viafb_lcd_set_mode(struct crt_mode_
 	    || (UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name))
 		viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0);
 
-	load_lcd_patch_regs(set_hres, set_vres,
-			    plvds_setting_info->lcd_panel_id, set_iga);
-
-	DEBUG_MSG(KERN_INFO "load_lcd_patch_regs!!\n");
-
 	/* Patch for non 32bit alignment mode */
 	via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info);
 }
@@ -1283,8 +896,7 @@ void viafb_lcd_enable(void)
 		viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48);
 	}
 
-	if ((viaparinfo->lvds_setting_info->iga_path == IGA1)
-	    || (viaparinfo->lvds_setting_info->iga_path == IGA1_IGA2)) {
+	if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
 		/* CRT path set to IGA2    */
 		viafb_write_reg_mask(SR16, VIASR, 0x40, 0x40);
 		/* IGA2 path disabled      */
@@ -1476,210 +1088,6 @@ static struct display_timing lcd_centeri
 	return crt_reg;
 }
 
-static void load_crtc_shadow_timing(struct display_timing mode_timing,
-			     struct display_timing panel_timing)
-{
-	struct io_register *reg = NULL;
-	int i;
-	int viafb_load_reg_Num = 0;
-	int reg_value = 0;
-
-	if (viaparinfo->lvds_setting_info->display_method == LCD_EXPANDSION) {
-		/* Expansion */
-		for (i = 12; i < 20; i++) {
-			switch (i) {
-			case H_TOTAL_SHADOW_INDEX:
-				reg_value =
-				    IGA2_HOR_TOTAL_SHADOW_FORMULA
-				    (panel_timing.hor_total);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.hor_total_shadow.
-				    reg_num;
-				reg = iga2_shadow_crtc_reg.hor_total_shadow.reg;
-				break;
-			case H_BLANK_END_SHADOW_INDEX:
-				reg_value =
-				    IGA2_HOR_BLANK_END_SHADOW_FORMULA
-				    (panel_timing.hor_blank_start,
-				     panel_timing.hor_blank_end);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.
-				    hor_blank_end_shadow.reg_num;
-				reg =
-				    iga2_shadow_crtc_reg.
-				    hor_blank_end_shadow.reg;
-				break;
-			case V_TOTAL_SHADOW_INDEX:
-				reg_value =
-				    IGA2_VER_TOTAL_SHADOW_FORMULA
-				    (panel_timing.ver_total);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.ver_total_shadow.
-				    reg_num;
-				reg = iga2_shadow_crtc_reg.ver_total_shadow.reg;
-				break;
-			case V_ADDR_SHADOW_INDEX:
-				reg_value =
-				    IGA2_VER_ADDR_SHADOW_FORMULA
-				    (panel_timing.ver_addr);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.ver_addr_shadow.
-				    reg_num;
-				reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg;
-				break;
-			case V_BLANK_SATRT_SHADOW_INDEX:
-				reg_value =
-				    IGA2_VER_BLANK_START_SHADOW_FORMULA
-				    (panel_timing.ver_blank_start);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.
-				    ver_blank_start_shadow.reg_num;
-				reg =
-				    iga2_shadow_crtc_reg.
-				    ver_blank_start_shadow.reg;
-				break;
-			case V_BLANK_END_SHADOW_INDEX:
-				reg_value =
-				    IGA2_VER_BLANK_END_SHADOW_FORMULA
-				    (panel_timing.ver_blank_start,
-				     panel_timing.ver_blank_end);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.
-				    ver_blank_end_shadow.reg_num;
-				reg =
-				    iga2_shadow_crtc_reg.
-				    ver_blank_end_shadow.reg;
-				break;
-			case V_SYNC_SATRT_SHADOW_INDEX:
-				reg_value =
-				    IGA2_VER_SYNC_START_SHADOW_FORMULA
-				    (panel_timing.ver_sync_start);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.
-				    ver_sync_start_shadow.reg_num;
-				reg =
-				    iga2_shadow_crtc_reg.
-				    ver_sync_start_shadow.reg;
-				break;
-			case V_SYNC_END_SHADOW_INDEX:
-				reg_value =
-				    IGA2_VER_SYNC_END_SHADOW_FORMULA
-				    (panel_timing.ver_sync_start,
-				     panel_timing.ver_sync_end);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.
-				    ver_sync_end_shadow.reg_num;
-				reg =
-				    iga2_shadow_crtc_reg.
-				    ver_sync_end_shadow.reg;
-				break;
-			}
-			viafb_load_reg(reg_value,
-				viafb_load_reg_Num, reg, VIACR);
-		}
-	} else {		/* Centering */
-		for (i = 12; i < 20; i++) {
-			switch (i) {
-			case H_TOTAL_SHADOW_INDEX:
-				reg_value =
-				    IGA2_HOR_TOTAL_SHADOW_FORMULA
-				    (panel_timing.hor_total);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.hor_total_shadow.
-				    reg_num;
-				reg = iga2_shadow_crtc_reg.hor_total_shadow.reg;
-				break;
-			case H_BLANK_END_SHADOW_INDEX:
-				reg_value =
-				    IGA2_HOR_BLANK_END_SHADOW_FORMULA
-				    (panel_timing.hor_blank_start,
-				     panel_timing.hor_blank_end);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.
-				    hor_blank_end_shadow.reg_num;
-				reg =
-				    iga2_shadow_crtc_reg.
-				    hor_blank_end_shadow.reg;
-				break;
-			case V_TOTAL_SHADOW_INDEX:
-				reg_value =
-				    IGA2_VER_TOTAL_SHADOW_FORMULA
-				    (panel_timing.ver_total);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.ver_total_shadow.
-				    reg_num;
-				reg = iga2_shadow_crtc_reg.ver_total_shadow.reg;
-				break;
-			case V_ADDR_SHADOW_INDEX:
-				reg_value =
-				    IGA2_VER_ADDR_SHADOW_FORMULA
-				    (mode_timing.ver_addr);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.ver_addr_shadow.
-				    reg_num;
-				reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg;
-				break;
-			case V_BLANK_SATRT_SHADOW_INDEX:
-				reg_value =
-				    IGA2_VER_BLANK_START_SHADOW_FORMULA
-				    (mode_timing.ver_blank_start);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.
-				    ver_blank_start_shadow.reg_num;
-				reg =
-				    iga2_shadow_crtc_reg.
-				    ver_blank_start_shadow.reg;
-				break;
-			case V_BLANK_END_SHADOW_INDEX:
-				reg_value =
-				    IGA2_VER_BLANK_END_SHADOW_FORMULA
-				    (panel_timing.ver_blank_start,
-				     panel_timing.ver_blank_end);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.
-				    ver_blank_end_shadow.reg_num;
-				reg =
-				    iga2_shadow_crtc_reg.
-				    ver_blank_end_shadow.reg;
-				break;
-			case V_SYNC_SATRT_SHADOW_INDEX:
-				reg_value =
-				    IGA2_VER_SYNC_START_SHADOW_FORMULA(
-				    (panel_timing.ver_sync_start -
-				    panel_timing.ver_blank_start) +
-				    (panel_timing.ver_addr -
-				    mode_timing.ver_addr) / 2 +
-				    mode_timing.ver_addr);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.ver_sync_start_shadow.
-				    reg_num;
-				reg =
-				    iga2_shadow_crtc_reg.ver_sync_start_shadow.
-				    reg;
-				break;
-			case V_SYNC_END_SHADOW_INDEX:
-				reg_value =
-				    IGA2_VER_SYNC_END_SHADOW_FORMULA(
-				    (panel_timing.ver_sync_start -
-				    panel_timing.ver_blank_start) +
-				    (panel_timing.ver_addr -
-				    mode_timing.ver_addr) / 2 +
-				    mode_timing.ver_addr,
-				    panel_timing.ver_sync_end);
-				viafb_load_reg_Num =
-				    iga2_shadow_crtc_reg.ver_sync_end_shadow.
-				    reg_num;
-				reg =
-				    iga2_shadow_crtc_reg.ver_sync_end_shadow.
-				    reg;
-				break;
-			}
-			viafb_load_reg(reg_value,
-				viafb_load_reg_Num, reg, VIACR);
-		}
-	}
-}
-
 bool viafb_lcd_get_mobile_state(bool *mobile)
 {
 	unsigned char *romptr, *tableptr;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/Makefile linux-libre-2.6.34-gnu1/drivers/video/via/Makefile
--- linux-libre-2.6.33-gnu1/drivers/video/via/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -4,4 +4,4 @@
 
 obj-$(CONFIG_FB_VIA) += viafb.o
 
-viafb-y	:=viafbdev.o hw.o iface.o  via_i2c.o dvi.o lcd.o ioctl.o accel.o via_utility.o vt1636.o global.o tblDPASetting.o viamode.o tbl1636.o
+viafb-y	:=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o via_utility.o vt1636.o global.o tblDPASetting.o viamode.o tbl1636.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/share.h linux-libre-2.6.34-gnu1/drivers/video/via/share.h
--- linux-libre-2.6.33-gnu1/drivers/video/via/share.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/share.h	2010-05-16 17:17:36.000000000 -0400
@@ -43,61 +43,6 @@
 /* Video Memory Size */
 #define VIDEO_MEMORY_SIZE_16M    0x1000000
 
-/* Definition Mode Index
-*/
-#define     VIA_RES_640X480                 	0
-#define     VIA_RES_800X600                 	1
-#define     VIA_RES_1024X768                	2
-#define     VIA_RES_1152X864                	3
-#define     VIA_RES_1280X1024               	4
-#define     VIA_RES_1600X1200               	5
-#define     VIA_RES_1440X1050               	6
-#define     VIA_RES_1280X768                	7
-#define     VIA_RES_1280X960                	8
-#define     VIA_RES_1920X1440               	9
-#define     VIA_RES_848X480                 	10
-#define     VIA_RES_1400X1050               	11
-#define     VIA_RES_720X480                 	12
-#define     VIA_RES_720X576                 	13
-#define     VIA_RES_1024X512                	14
-#define     VIA_RES_856X480                 	15
-#define     VIA_RES_1024X576                	16
-#define     VIA_RES_640X400                 	17
-#define     VIA_RES_1280X720                	18
-#define     VIA_RES_1920X1080               	19
-#define     VIA_RES_800X480                 	20
-#define     VIA_RES_1368X768                	21
-#define     VIA_RES_1024X600                	22
-#define     VIA_RES_1280X800                	23
-#define     VIA_RES_1680X1050               	24
-#define     VIA_RES_960X600			25
-#define     VIA_RES_1000X600               	26
-#define     VIA_RES_1088X612               	27
-#define     VIA_RES_1152X720               	28
-#define     VIA_RES_1200X720               	29
-#define     VIA_RES_1280X600               	30
-#define     VIA_RES_1360X768               	31
-#define     VIA_RES_1366X768               	32
-#define     VIA_RES_1440X900               	33
-#define     VIA_RES_1600X900               	34
-#define     VIA_RES_1600X1024              	35
-#define     VIA_RES_1792X1344              	36
-#define     VIA_RES_1856X1392              	37
-#define     VIA_RES_1920X1200              	38
-#define     VIA_RES_2048X1536              	39
-#define     VIA_RES_480X640                  	40
-
-/*Reduce Blanking*/
-#define     VIA_RES_1360X768_RB          	131
-#define     VIA_RES_1440X900_RB          	133
-#define     VIA_RES_1400X1050_RB        	111
-#define     VIA_RES_1600X900_RB          	134
-#define     VIA_RES_1680X1050_RB        	124
-#define     VIA_RES_1920X1080_RB        	119
-#define     VIA_RES_1920X1200_RB        	138
-
-#define     VIA_RES_INVALID                 	255
-
 /* standard VGA IO port
 */
 #define VIARMisc    0x3CC
@@ -118,7 +63,6 @@
 /* Display path */
 #define IGA1        1
 #define IGA2        2
-#define IGA1_IGA2   3
 
 /* Define Color Depth  */
 #define MODE_8BPP       1
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/viafbdev.c linux-libre-2.6.34-gnu1/drivers/video/via/viafbdev.c
--- linux-libre-2.6.33-gnu1/drivers/video/via/viafbdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/viafbdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,23 +21,28 @@
 
 #include <linux/module.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/stat.h>
 #define _MASTER_FILE
 
 #include "global.h"
 
-static struct fb_var_screeninfo default_var;
 static char *viafb_name = "Via";
 static u32 pseudo_pal[17];
 
 /* video mode */
-static char *viafb_mode = "640x480";
-static char *viafb_mode1 = "640x480";
+static char *viafb_mode;
+static char *viafb_mode1;
+static int viafb_bpp = 32;
+static int viafb_bpp1 = 32;
+
+static unsigned int viafb_second_offset;
+static int viafb_second_size;
 
 static int viafb_accel = 1;
 
 /* Added for specifying active devices.*/
-char *viafb_active_dev = "";
+char *viafb_active_dev;
 
 /*Added for specify lcd output port*/
 char *viafb_lcd_port = "";
@@ -50,18 +55,78 @@ static void apply_second_mode_setting(st
 	*sec_var);
 static void retrieve_device_setting(struct viafb_ioctl_setting
 	*setting_info);
+static int viafb_pan_display(struct fb_var_screeninfo *var,
+	struct fb_info *info);
 
 static struct fb_ops viafb_ops;
 
 
+static void viafb_fill_var_color_info(struct fb_var_screeninfo *var, u8 depth)
+{
+	var->grayscale = 0;
+	var->red.msb_right = 0;
+	var->green.msb_right = 0;
+	var->blue.msb_right = 0;
+	var->transp.offset = 0;
+	var->transp.length = 0;
+	var->transp.msb_right = 0;
+	var->nonstd = 0;
+	switch (depth) {
+	case 8:
+		var->bits_per_pixel = 8;
+		var->red.offset = 0;
+		var->green.offset = 0;
+		var->blue.offset = 0;
+		var->red.length = 8;
+		var->green.length = 8;
+		var->blue.length = 8;
+		break;
+	case 15:
+		var->bits_per_pixel = 16;
+		var->red.offset = 10;
+		var->green.offset = 5;
+		var->blue.offset = 0;
+		var->red.length = 5;
+		var->green.length = 5;
+		var->blue.length = 5;
+		break;
+	case 16:
+		var->bits_per_pixel = 16;
+		var->red.offset = 11;
+		var->green.offset = 5;
+		var->blue.offset = 0;
+		var->red.length = 5;
+		var->green.length = 6;
+		var->blue.length = 5;
+		break;
+	case 24:
+		var->bits_per_pixel = 32;
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->red.length = 8;
+		var->green.length = 8;
+		var->blue.length = 8;
+		break;
+	case 30:
+		var->bits_per_pixel = 32;
+		var->red.offset = 20;
+		var->green.offset = 10;
+		var->blue.offset = 0;
+		var->red.length = 10;
+		var->green.length = 10;
+		var->blue.length = 10;
+		break;
+	}
+}
+
 static void viafb_update_fix(struct fb_info *info)
 {
 	u32 bpp = info->var.bits_per_pixel;
 
 	info->fix.visual =
 		bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
-	info->fix.line_length =
-		((info->var.xres_virtual + 7) & ~7) * bpp / 8;
+	info->fix.line_length = (info->var.xres_virtual * bpp / 8 + 7) & ~7;
 }
 
 static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix,
@@ -75,6 +140,7 @@ static void viafb_setup_fixinfo(struct f
 
 	fix->type = FB_TYPE_PACKED_PIXELS;
 	fix->type_aux = 0;
+	fix->visual = FB_VISUAL_TRUECOLOR;
 
 	fix->xpanstep = fix->ywrapstep = 0;
 	fix->ypanstep = 1;
@@ -97,9 +163,10 @@ static int viafb_release(struct fb_info
 static int viafb_check_var(struct fb_var_screeninfo *var,
 	struct fb_info *info)
 {
-	int vmode_index, htotal, vtotal;
+	int htotal, vtotal, depth;
+	struct VideoModeTable *vmode_entry;
 	struct viafb_par *ppar = info->par;
-	u32 long_refresh;
+	u32 long_refresh, line;
 
 	DEBUG_MSG(KERN_INFO "viafb_check_var!\n");
 	/* Sanity check */
@@ -107,26 +174,36 @@ static int viafb_check_var(struct fb_var
 	if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE)
 		return -EINVAL;
 
-	vmode_index = viafb_get_mode_index(var->xres, var->yres);
-	if (vmode_index == VIA_RES_INVALID) {
+	vmode_entry = viafb_get_mode(var->xres, var->yres);
+	if (!vmode_entry) {
 		DEBUG_MSG(KERN_INFO
 			  "viafb: Mode %dx%dx%d not supported!!\n",
 			  var->xres, var->yres, var->bits_per_pixel);
 		return -EINVAL;
 	}
 
-	if (24 == var->bits_per_pixel)
-		var->bits_per_pixel = 32;
+	depth = fb_get_color_depth(var, &info->fix);
+	if (!depth)
+		depth = var->bits_per_pixel;
 
-	if (var->bits_per_pixel != 8 && var->bits_per_pixel != 16 &&
-		var->bits_per_pixel != 32)
+	if (depth < 0 || depth > 32)
 		return -EINVAL;
+	else if (!depth)
+		depth = 24;
+	else if (depth == 15 && viafb_dual_fb && ppar->iga_path == IGA1)
+		depth = 15;
+	else if (depth == 30)
+		depth = 30;
+	else if (depth <= 8)
+		depth = 8;
+	else if (depth <= 16)
+		depth = 16;
+	else
+		depth = 24;
 
-	if ((var->xres_virtual * (var->bits_per_pixel >> 3)) & 0x1F)
-		/*32 pixel alignment */
-		var->xres_virtual = (var->xres_virtual + 31) & ~31;
-	if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 >
-		ppar->memsize)
+	viafb_fill_var_color_info(var, depth);
+	line = (var->xres_virtual * var->bits_per_pixel / 8 + 7) & ~7;
+	if (line * var->yres_virtual > ppar->memsize)
 		return -EINVAL;
 
 	/* Based on var passed in to calculate the refresh,
@@ -142,7 +219,7 @@ static int viafb_check_var(struct fb_var
 	viafb_refresh = viafb_get_refresh(var->xres, var->yres, long_refresh);
 
 	/* Adjust var according to our driver's own table */
-	viafb_fill_var_timing_info(var, viafb_refresh, vmode_index);
+	viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry);
 	if (info->var.accel_flags & FB_ACCELF_TEXT &&
 		!ppar->shared->engine_mmio)
 		info->var.accel_flags = 0;
@@ -153,39 +230,45 @@ static int viafb_check_var(struct fb_var
 static int viafb_set_par(struct fb_info *info)
 {
 	struct viafb_par *viapar = info->par;
-	int vmode_index;
-	int vmode_index1 = 0;
+	struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL;
 	DEBUG_MSG(KERN_INFO "viafb_set_par!\n");
 
 	viapar->depth = fb_get_color_depth(&info->var, &info->fix);
-	viafb_update_device_setting(info->var.xres, info->var.yres,
-			      info->var.bits_per_pixel, viafb_refresh, 0);
-
-	vmode_index = viafb_get_mode_index(info->var.xres, info->var.yres);
+	viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres,
+		viafbinfo->var.bits_per_pixel, viafb_refresh, 0);
 
-	if (viafb_SAMM_ON == 1) {
+	vmode_entry = viafb_get_mode(viafbinfo->var.xres, viafbinfo->var.yres);
+	if (viafb_dual_fb) {
+		vmode_entry1 = viafb_get_mode(viafbinfo1->var.xres,
+			viafbinfo1->var.yres);
+		viafb_update_device_setting(viafbinfo1->var.xres,
+			viafbinfo1->var.yres, viafbinfo1->var.bits_per_pixel,
+			viafb_refresh1, 1);
+	} else if (viafb_SAMM_ON == 1) {
 		DEBUG_MSG(KERN_INFO
 		"viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n",
 			  viafb_second_xres, viafb_second_yres, viafb_bpp1);
-		vmode_index1 = viafb_get_mode_index(viafb_second_xres,
+		vmode_entry1 = viafb_get_mode(viafb_second_xres,
 			viafb_second_yres);
-		DEBUG_MSG(KERN_INFO "->viafb_SAMM_ON: index=%d\n",
-			vmode_index1);
 
 		viafb_update_device_setting(viafb_second_xres,
 			viafb_second_yres, viafb_bpp1, viafb_refresh1, 1);
 	}
 
-	if (vmode_index != VIA_RES_INVALID) {
+	if (vmode_entry) {
 		viafb_update_fix(info);
-		viafb_bpp = info->var.bits_per_pixel;
+		if (viafb_dual_fb && viapar->iga_path == IGA2)
+			viafb_bpp1 = info->var.bits_per_pixel;
+		else
+			viafb_bpp = info->var.bits_per_pixel;
+
 		if (info->var.accel_flags & FB_ACCELF_TEXT)
 			info->flags &= ~FBINFO_HWACCEL_DISABLED;
 		else
 			info->flags |= FBINFO_HWACCEL_DISABLED;
-		viafb_setmode(vmode_index, info->var.xres, info->var.yres,
-			info->var.bits_per_pixel, vmode_index1,
-			viafb_second_xres, viafb_second_yres, viafb_bpp1);
+		viafb_setmode(vmode_entry, info->var.bits_per_pixel,
+			vmode_entry1, viafb_bpp1);
+		viafb_pan_display(&info->var, info);
 	}
 
 	return 0;
@@ -195,234 +278,52 @@ static int viafb_set_par(struct fb_info
 static int viafb_setcolreg(unsigned regno, unsigned red, unsigned green,
 unsigned blue, unsigned transp, struct fb_info *info)
 {
-	u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10;
-	unsigned cmap_entries = (info->var.bits_per_pixel == 8) ? 256 : 16;
-	DEBUG_MSG(KERN_INFO "viafb_setcolreg!\n");
-	if (regno >= cmap_entries)
-		return 1;
-	if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) {
-		/*
-		 * Read PCI bus 0,dev 0,function 0,index 0xF6 to get chip rev.
-		 */
-		outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8);
-		rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff;
-	}
-	switch (info->var.bits_per_pixel) {
-	case 8:
-		outb(0x1A, 0x3C4);
-		sr1a = inb(0x3C5);
-		outb(0x1B, 0x3C4);
-		sr1b = inb(0x3C5);
-		outb(0x67, 0x3D4);
-		cr67 = inb(0x3D5);
-		outb(0x6A, 0x3D4);
-		cr6a = inb(0x3D5);
-
-		/* Map the 3C6/7/8/9 to the IGA2 */
-		outb(0x1A, 0x3C4);
-		outb(sr1a | 0x01, 0x3C5);
-		/* Second Display Engine colck always on */
-		outb(0x1B, 0x3C4);
-		outb(sr1b | 0x80, 0x3C5);
-		/* Second Display Color Depth 8 */
-		outb(0x67, 0x3D4);
-		outb(cr67 & 0x3F, 0x3D5);
-		outb(0x6A, 0x3D4);
-		/* Second Display Channel Reset CR6A[6]) */
-		outb(cr6a & 0xBF, 0x3D5);
-		/* Second Display Channel Enable CR6A[7] */
-		outb(cr6a | 0x80, 0x3D5);
-		/* Second Display Channel stop reset) */
-		outb(cr6a | 0x40, 0x3D5);
-
-		/* Bit mask of palette */
-		outb(0xFF, 0x3c6);
-		/* Write one register of IGA2 */
-		outb(regno, 0x3C8);
-		if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name &&
-			rev >= 15) {
-			shift = 8;
-			viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5);
-			viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7);
-		} else {
-			shift = 10;
-			viafb_write_reg_mask(CR6A, VIACR, 0, BIT5);
-			viafb_write_reg_mask(SR15, VIASR, 0, BIT7);
-		}
-		outb(red >> shift, 0x3C9);
-		outb(green >> shift, 0x3C9);
-		outb(blue >> shift, 0x3C9);
-
-		/* Map the 3C6/7/8/9 to the IGA1 */
-		outb(0x1A, 0x3C4);
-		outb(sr1a & 0xFE, 0x3C5);
-		/* Bit mask of palette */
-		outb(0xFF, 0x3c6);
-		/* Write one register of IGA1 */
-		outb(regno, 0x3C8);
-		outb(red >> shift, 0x3C9);
-		outb(green >> shift, 0x3C9);
-		outb(blue >> shift, 0x3C9);
+	struct viafb_par *viapar = info->par;
+	u32 r, g, b;
 
-		outb(0x1A, 0x3C4);
-		outb(sr1a, 0x3C5);
-		outb(0x1B, 0x3C4);
-		outb(sr1b, 0x3C5);
-		outb(0x67, 0x3D4);
-		outb(cr67, 0x3D5);
-		outb(0x6A, 0x3D4);
-		outb(cr6a, 0x3D5);
-		break;
-	case 16:
-		((u32 *) info->pseudo_palette)[regno] = (red & 0xF800) |
-		    ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11);
-		break;
-	case 32:
-		((u32 *) info->pseudo_palette)[regno] =
-		    ((transp & 0xFF00) << 16) |
-		    ((red & 0xFF00) << 8) |
-		    ((green & 0xFF00)) | ((blue & 0xFF00) >> 8);
-		break;
-	}
+	if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
+		if (regno > 255)
+			return -EINVAL;
 
-	return 0;
+		if (!viafb_dual_fb || viapar->iga_path == IGA1)
+			viafb_set_primary_color_register(regno, red >> 8,
+				green >> 8, blue >> 8);
 
-}
+		if (!viafb_dual_fb || viapar->iga_path == IGA2)
+			viafb_set_secondary_color_register(regno, red >> 8,
+				green >> 8, blue >> 8);
+	} else {
+		if (regno > 15)
+			return -EINVAL;
 
-/*CALLED BY: fb_set_cmap */
-/*           fb_set_var, pass 256 colors */
-/*CALLED BY: fb_set_cmap */
-/*           fbcon_set_palette, pass 16 colors */
-static int viafb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
-{
-	u32 len = cmap->len;
-	u32 i;
-	u16 *pred = cmap->red;
-	u16 *pgreen = cmap->green;
-	u16 *pblue = cmap->blue;
-	u16 *ptransp = cmap->transp;
-	u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10;
-	if (len > 256)
-		return 1;
-	if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) {
-		/*
-		 * Read PCI bus 0, dev 0, function 0, index 0xF6 to get chip
-		 * rev.
-		 */
-		outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8);
-		rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff;
+		r = (red >> (16 - info->var.red.length))
+			<< info->var.red.offset;
+		b = (blue >> (16 - info->var.blue.length))
+			<< info->var.blue.offset;
+		g = (green >> (16 - info->var.green.length))
+			<< info->var.green.offset;
+		((u32 *) info->pseudo_palette)[regno] = r | g | b;
 	}
-	switch (info->var.bits_per_pixel) {
-	case 8:
-		outb(0x1A, 0x3C4);
-		sr1a = inb(0x3C5);
-		outb(0x1B, 0x3C4);
-		sr1b = inb(0x3C5);
-		outb(0x67, 0x3D4);
-		cr67 = inb(0x3D5);
-		outb(0x6A, 0x3D4);
-		cr6a = inb(0x3D5);
-		/* Map the 3C6/7/8/9 to the IGA2 */
-		outb(0x1A, 0x3C4);
-		outb(sr1a | 0x01, 0x3C5);
-		outb(0x1B, 0x3C4);
-		/* Second Display Engine colck always on */
-		outb(sr1b | 0x80, 0x3C5);
-		outb(0x67, 0x3D4);
-		/* Second Display Color Depth 8 */
-		outb(cr67 & 0x3F, 0x3D5);
-		outb(0x6A, 0x3D4);
-		/* Second Display Channel Reset CR6A[6]) */
-		outb(cr6a & 0xBF, 0x3D5);
-		/* Second Display Channel Enable CR6A[7] */
-		outb(cr6a | 0x80, 0x3D5);
-		/* Second Display Channel stop reset) */
-		outb(cr6a | 0xC0, 0x3D5);
 
-		/* Bit mask of palette */
-		outb(0xFF, 0x3c6);
-		outb(0x00, 0x3C8);
-		if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name &&
-			rev >= 15) {
-			shift = 8;
-			viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5);
-			viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7);
-		} else {
-			shift = 10;
-			viafb_write_reg_mask(CR6A, VIACR, 0, BIT5);
-			viafb_write_reg_mask(SR15, VIASR, 0, BIT7);
-		}
-		for (i = 0; i < len; i++) {
-			outb((*(pred + i)) >> shift, 0x3C9);
-			outb((*(pgreen + i)) >> shift, 0x3C9);
-			outb((*(pblue + i)) >> shift, 0x3C9);
-		}
-
-		outb(0x1A, 0x3C4);
-		/* Map the 3C6/7/8/9 to the IGA1 */
-		outb(sr1a & 0xFE, 0x3C5);
-		/* Bit mask of palette */
-		outb(0xFF, 0x3c6);
-		outb(0x00, 0x3C8);
-		for (i = 0; i < len; i++) {
-			outb((*(pred + i)) >> shift, 0x3C9);
-			outb((*(pgreen + i)) >> shift, 0x3C9);
-			outb((*(pblue + i)) >> shift, 0x3C9);
-		}
-
-		outb(0x1A, 0x3C4);
-		outb(sr1a, 0x3C5);
-		outb(0x1B, 0x3C4);
-		outb(sr1b, 0x3C5);
-		outb(0x67, 0x3D4);
-		outb(cr67, 0x3D5);
-		outb(0x6A, 0x3D4);
-		outb(cr6a, 0x3D5);
-		break;
-	case 16:
-		if (len > 17)
-			return 0;	/* Because static u32 pseudo_pal[17]; */
-		for (i = 0; i < len; i++)
-			((u32 *) info->pseudo_palette)[i] =
-			    (*(pred + i) & 0xF800) |
-			    ((*(pgreen + i) & 0xFC00) >> 5) |
-			    ((*(pblue + i) & 0xF800) >> 11);
-		break;
-	case 32:
-		if (len > 17)
-			return 0;
-		if (ptransp) {
-			for (i = 0; i < len; i++)
-				((u32 *) info->pseudo_palette)[i] =
-				    ((*(ptransp + i) & 0xFF00) << 16) |
-				    ((*(pred + i) & 0xFF00) << 8) |
-				    ((*(pgreen + i) & 0xFF00)) |
-				    ((*(pblue + i) & 0xFF00) >> 8);
-		} else {
-			for (i = 0; i < len; i++)
-				((u32 *) info->pseudo_palette)[i] =
-				    0x00000000 |
-				    ((*(pred + i) & 0xFF00) << 8) |
-				    ((*(pgreen + i) & 0xFF00)) |
-				    ((*(pblue + i) & 0xFF00) >> 8);
-		}
-		break;
-	}
 	return 0;
 }
 
 static int viafb_pan_display(struct fb_var_screeninfo *var,
 	struct fb_info *info)
 {
-	unsigned int offset;
-
-	DEBUG_MSG(KERN_INFO "viafb_pan_display!\n");
+	struct viafb_par *viapar = info->par;
+	u32 vram_addr = (var->yoffset * var->xres_virtual + var->xoffset)
+		* (var->bits_per_pixel / 8) + viapar->vram_addr;
 
-	offset = (var->xoffset + (var->yoffset * var->xres_virtual)) *
-	    var->bits_per_pixel / 16;
+	DEBUG_MSG(KERN_DEBUG "viafb_pan_display, address = %d\n", vram_addr);
+	if (!viafb_dual_fb) {
+		viafb_set_primary_address(vram_addr);
+		viafb_set_secondary_address(vram_addr);
+	} else if (viapar->iga_path == IGA1)
+		viafb_set_primary_address(vram_addr);
+	else
+		viafb_set_secondary_address(vram_addr);
 
-	DEBUG_MSG(KERN_INFO "\nviafb_pan_display,offset =%d ", offset);
-	viafb_set_primary_address(offset);
 	return 0;
 }
 
@@ -476,6 +377,7 @@ static int viafb_ioctl(struct fb_info *i
 	u32 gpu32;
 
 	DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd);
+	printk(KERN_WARNING "viafb_ioctl: Please avoid this interface as it is unstable and might change or vanish at any time!\n");
 	memset(&u, 0, sizeof(u));
 
 	switch (cmd) {
@@ -1015,23 +917,6 @@ static int viafb_sync(struct fb_info *in
 	return 0;
 }
 
-int viafb_get_mode_index(int hres, int vres)
-{
-	u32 i;
-	DEBUG_MSG(KERN_INFO "viafb_get_mode_index!\n");
-
-	for (i = 0; i < NUM_TOTAL_MODETABLE; i++)
-		if (CLE266Modes[i].mode_array &&
-			CLE266Modes[i].crtc[0].crtc.hor_addr == hres &&
-			CLE266Modes[i].crtc[0].crtc.ver_addr == vres)
-			break;
-
-	if (i == NUM_TOTAL_MODETABLE)
-		return VIA_RES_INVALID;
-
-	return CLE266Modes[i].ModeIndex;
-}
-
 static void check_available_device_to_enable(int device_id)
 {
 	int device_num = 0;
@@ -1330,7 +1215,7 @@ static void retrieve_device_setting(stru
 	setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode;
 }
 
-static void parse_active_dev(void)
+static int parse_active_dev(void)
 {
 	viafb_CRT_ON = STATE_OFF;
 	viafb_DVI_ON = STATE_OFF;
@@ -1341,60 +1226,63 @@ static void parse_active_dev(void)
 	   IGA path to devices in SAMM case. */
 	/*    Note: The previous of active_dev is primary device,
 	   and the following is secondary device. */
-	if (!strncmp(viafb_active_dev, "CRT+DVI", 7)) {
+	if (!viafb_active_dev) {
+		viafb_CRT_ON = STATE_ON;
+		viafb_SAMM_ON = STATE_OFF;
+	} else if (!strcmp(viafb_active_dev, "CRT+DVI")) {
 		/* CRT+DVI */
 		viafb_CRT_ON = STATE_ON;
 		viafb_DVI_ON = STATE_ON;
 		viafb_primary_dev = CRT_Device;
-	} else if (!strncmp(viafb_active_dev, "DVI+CRT", 7)) {
+	} else if (!strcmp(viafb_active_dev, "DVI+CRT")) {
 		/* DVI+CRT */
 		viafb_CRT_ON = STATE_ON;
 		viafb_DVI_ON = STATE_ON;
 		viafb_primary_dev = DVI_Device;
-	} else if (!strncmp(viafb_active_dev, "CRT+LCD", 7)) {
+	} else if (!strcmp(viafb_active_dev, "CRT+LCD")) {
 		/* CRT+LCD */
 		viafb_CRT_ON = STATE_ON;
 		viafb_LCD_ON = STATE_ON;
 		viafb_primary_dev = CRT_Device;
-	} else if (!strncmp(viafb_active_dev, "LCD+CRT", 7)) {
+	} else if (!strcmp(viafb_active_dev, "LCD+CRT")) {
 		/* LCD+CRT */
 		viafb_CRT_ON = STATE_ON;
 		viafb_LCD_ON = STATE_ON;
 		viafb_primary_dev = LCD_Device;
-	} else if (!strncmp(viafb_active_dev, "DVI+LCD", 7)) {
+	} else if (!strcmp(viafb_active_dev, "DVI+LCD")) {
 		/* DVI+LCD */
 		viafb_DVI_ON = STATE_ON;
 		viafb_LCD_ON = STATE_ON;
 		viafb_primary_dev = DVI_Device;
-	} else if (!strncmp(viafb_active_dev, "LCD+DVI", 7)) {
+	} else if (!strcmp(viafb_active_dev, "LCD+DVI")) {
 		/* LCD+DVI */
 		viafb_DVI_ON = STATE_ON;
 		viafb_LCD_ON = STATE_ON;
 		viafb_primary_dev = LCD_Device;
-	} else if (!strncmp(viafb_active_dev, "LCD+LCD2", 8)) {
+	} else if (!strcmp(viafb_active_dev, "LCD+LCD2")) {
 		viafb_LCD_ON = STATE_ON;
 		viafb_LCD2_ON = STATE_ON;
 		viafb_primary_dev = LCD_Device;
-	} else if (!strncmp(viafb_active_dev, "LCD2+LCD", 8)) {
+	} else if (!strcmp(viafb_active_dev, "LCD2+LCD")) {
 		viafb_LCD_ON = STATE_ON;
 		viafb_LCD2_ON = STATE_ON;
 		viafb_primary_dev = LCD2_Device;
-	} else if (!strncmp(viafb_active_dev, "CRT", 3)) {
+	} else if (!strcmp(viafb_active_dev, "CRT")) {
 		/* CRT only */
 		viafb_CRT_ON = STATE_ON;
 		viafb_SAMM_ON = STATE_OFF;
-	} else if (!strncmp(viafb_active_dev, "DVI", 3)) {
+	} else if (!strcmp(viafb_active_dev, "DVI")) {
 		/* DVI only */
 		viafb_DVI_ON = STATE_ON;
 		viafb_SAMM_ON = STATE_OFF;
-	} else if (!strncmp(viafb_active_dev, "LCD", 3)) {
+	} else if (!strcmp(viafb_active_dev, "LCD")) {
 		/* LCD only */
 		viafb_LCD_ON = STATE_ON;
 		viafb_SAMM_ON = STATE_OFF;
-	} else {
-		viafb_CRT_ON = STATE_ON;
-		viafb_SAMM_ON = STATE_OFF;
-	}
+	} else
+		return -EINVAL;
+
+	return 0;
 }
 
 static int parse_port(char *opt_str, int *output_interface)
@@ -1823,35 +1711,37 @@ static void viafb_remove_proc(struct pro
 	remove_proc_entry("viafb", NULL);
 }
 
-static void parse_mode(const char *str, u32 *xres, u32 *yres)
+static int parse_mode(const char *str, u32 *xres, u32 *yres)
 {
 	char *ptr;
 
+	if (!str) {
+		*xres = 640;
+		*yres = 480;
+		return 0;
+	}
+
 	*xres = simple_strtoul(str, &ptr, 10);
 	if (ptr[0] != 'x')
-		goto out_default;
+		return -EINVAL;
 
 	*yres = simple_strtoul(&ptr[1], &ptr, 10);
 	if (ptr[0])
-		goto out_default;
-
-	return;
+		return -EINVAL;
 
-out_default:
-	printk(KERN_WARNING "viafb received invalid mode string: %s\n", str);
-	*xres = 640;
-	*yres = 480;
+	return 0;
 }
 
 static int __devinit via_pci_probe(struct pci_dev *pdev,
 				   const struct pci_device_id *ent)
 {
 	u32 default_xres, default_yres;
-	int vmode_index;
+	struct VideoModeTable *vmode_entry;
+	struct fb_var_screeninfo default_var;
 	u32 viafb_par_length;
 
 	DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n");
-
+	memset(&default_var, 0, sizeof(default_var));
 	viafb_par_length = ALIGN(sizeof(struct viafb_par), BITS_PER_LONG/8);
 
 	/* Allocate fb_info and ***_par here, also including some other needed
@@ -1877,7 +1767,6 @@ static int __devinit via_pci_probe(struc
 
 	if (viafb_dual_fb)
 		viafb_SAMM_ON = 1;
-	parse_active_dev();
 	parse_lcd_port();
 	parse_dvi_port();
 
@@ -1926,9 +1815,7 @@ static int __devinit via_pci_probe(struc
 	}
 
 	parse_mode(viafb_mode, &default_xres, &default_yres);
-	vmode_index = viafb_get_mode_index(default_xres, default_yres);
-	DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index);
-
+	vmode_entry = viafb_get_mode(default_xres, default_yres);
 	if (viafb_SAMM_ON == 1) {
 		parse_mode(viafb_mode1, &viafb_second_xres,
 			&viafb_second_yres);
@@ -1947,19 +1834,6 @@ static int __devinit via_pci_probe(struc
 			viafb_second_virtual_yres = viafb_second_yres;
 	}
 
-	switch (viafb_bpp) {
-	case 0 ... 8:
-		viafb_bpp = 8;
-		break;
-	case 9 ... 16:
-		viafb_bpp = 16;
-		break;
-	case 17 ... 32:
-		viafb_bpp = 32;
-		break;
-	default:
-		viafb_bpp = 8;
-	}
 	default_var.xres = default_xres;
 	default_var.yres = default_yres;
 	switch (default_xres) {
@@ -1972,8 +1846,6 @@ static int __devinit via_pci_probe(struc
 	}
 	default_var.yres_virtual = default_yres;
 	default_var.bits_per_pixel = viafb_bpp;
-	if (default_var.bits_per_pixel == 15)
-		default_var.bits_per_pixel = 16;
 	default_var.pixclock =
 	    viafb_get_pixclock(default_xres, default_yres, viafb_refresh);
 	default_var.left_margin = (default_xres >> 3) & 0xf8;
@@ -1982,6 +1854,8 @@ static int __devinit via_pci_probe(struc
 	default_var.lower_margin = 4;
 	default_var.hsync_len = default_var.left_margin;
 	default_var.vsync_len = 4;
+	viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo);
+	viafbinfo->var = default_var;
 
 	if (viafb_dual_fb) {
 		viafbinfo1 = framebuffer_alloc(viafb_par_length, &pdev->dev);
@@ -2016,8 +1890,6 @@ static int __devinit via_pci_probe(struc
 		default_var.yres = viafb_second_yres;
 		default_var.xres_virtual = viafb_second_virtual_xres;
 		default_var.yres_virtual = viafb_second_virtual_yres;
-		if (viafb_bpp1 != viafb_bpp)
-			viafb_bpp1 = viafb_bpp;
 		default_var.bits_per_pixel = viafb_bpp1;
 		default_var.pixclock =
 		    viafb_get_pixclock(viafb_second_xres, viafb_second_yres,
@@ -2037,9 +1909,7 @@ static int __devinit via_pci_probe(struc
 			&viafbinfo1->fix);
 	}
 
-	viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo);
-	viafb_check_var(&default_var, viafbinfo);
-	viafbinfo->var = default_var;
+	viafb_check_var(&viafbinfo->var, viafbinfo);
 	viafb_update_fix(viafbinfo);
 	viaparinfo->depth = fb_get_color_depth(&viafbinfo->var,
 		&viafbinfo->fix);
@@ -2197,12 +2067,20 @@ static struct pci_driver viafb_driver =
 
 static int __init viafb_init(void)
 {
+	u32 dummy;
 #ifndef MODULE
 	char *option = NULL;
 	if (fb_get_options("viafb", &option))
 		return -ENODEV;
 	viafb_setup(option);
 #endif
+	if (parse_mode(viafb_mode, &dummy, &dummy)
+		|| parse_mode(viafb_mode1, &dummy, &dummy)
+		|| viafb_bpp < 0 || viafb_bpp > 32
+		|| viafb_bpp1 < 0 || viafb_bpp1 > 32
+		|| parse_active_dev())
+		return -EINVAL;
+
 	printk(KERN_INFO
        "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n",
 	       VERSION_MAJOR, VERSION_MINOR);
@@ -2230,15 +2108,12 @@ static struct fb_ops viafb_ops = {
 	.fb_cursor = viafb_cursor,
 	.fb_ioctl = viafb_ioctl,
 	.fb_sync = viafb_sync,
-	.fb_setcmap = viafb_setcmap,
 };
 
 module_init(viafb_init);
 module_exit(viafb_exit);
 
 #ifdef MODULE
-module_param(viafb_memsize, int, S_IRUSR);
-
 module_param(viafb_mode, charp, S_IRUSR);
 MODULE_PARM_DESC(viafb_mode, "Set resolution (default=640x480)");
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/viafbdev.h linux-libre-2.6.34-gnu1/drivers/video/via/viafbdev.h
--- linux-libre-2.6.33-gnu1/drivers/video/via/viafbdev.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/viafbdev.h	2010-05-16 17:17:36.000000000 -0400
@@ -83,22 +83,16 @@ struct viafb_par {
 
 extern unsigned int viafb_second_virtual_yres;
 extern unsigned int viafb_second_virtual_xres;
-extern unsigned int viafb_second_offset;
-extern int viafb_second_size;
 extern int viafb_SAMM_ON;
 extern int viafb_dual_fb;
 extern int viafb_LCD2_ON;
 extern int viafb_LCD_ON;
 extern int viafb_DVI_ON;
 extern int viafb_hotplug;
-extern int viafb_memsize;
 
 extern int strict_strtoul(const char *cp, unsigned int base,
 	unsigned long *res);
 
-void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
-			  int mode_index);
-int viafb_get_mode_index(int hres, int vres);
 u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
 	*plvds_setting_info, struct lvds_chip_information
 	*plvds_chip_info, u8 index);
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/viamode.c linux-libre-2.6.34-gnu1/drivers/video/via/viamode.c
--- linux-libre-2.6.33-gnu1/drivers/video/via/viamode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/viamode.c	2010-05-16 17:17:36.000000000 -0400
@@ -412,7 +412,7 @@ struct io_reg PM1024x768[] = { {VIASR, 0
 };
 
 struct patch_table res_patch_table[] = {
-	{VIA_RES_1024X768, ARRAY_SIZE(PM1024x768), PM1024x768}
+	{ARRAY_SIZE(PM1024x768), PM1024x768}
 };
 
 /* struct VPITTable {
@@ -879,169 +879,151 @@ struct crt_mode_table CRTM2048x1536[] =
 	 {2800, 2048, 2048, 752, 2200, 224, 1592, 1536, 1536, 56, 1539, 4} }
 };
 
-/* Video Mode Table */
-/* struct VideoModeTable {*/
-/*  int                               ModeIndex;*/
-/*  struct crt_mode_table             *crtc;*/
-/*  int                               mode_array;*/
-/* };*/
-struct VideoModeTable CLE266Modes[] = {
+struct VideoModeTable viafb_modes[] = {
 	/* Display : 480x640 (GTF) */
-	{VIA_RES_480X640, CRTM480x640, ARRAY_SIZE(CRTM480x640)},
+	{CRTM480x640, ARRAY_SIZE(CRTM480x640)},
 
 	/* Display : 640x480 */
-	{VIA_RES_640X480, CRTM640x480, ARRAY_SIZE(CRTM640x480)},
+	{CRTM640x480, ARRAY_SIZE(CRTM640x480)},
 
 	/* Display : 720x480 (GTF) */
-	{VIA_RES_720X480, CRTM720x480, ARRAY_SIZE(CRTM720x480)},
+	{CRTM720x480, ARRAY_SIZE(CRTM720x480)},
 
 	/* Display : 720x576 (GTF) */
-	{VIA_RES_720X576, CRTM720x576, ARRAY_SIZE(CRTM720x576)},
+	{CRTM720x576, ARRAY_SIZE(CRTM720x576)},
 
 	/* Display : 800x600 */
-	{VIA_RES_800X600, CRTM800x600, ARRAY_SIZE(CRTM800x600)},
+	{CRTM800x600, ARRAY_SIZE(CRTM800x600)},
 
 	/* Display : 800x480 (CVT) */
-	{VIA_RES_800X480, CRTM800x480, ARRAY_SIZE(CRTM800x480)},
+	{CRTM800x480, ARRAY_SIZE(CRTM800x480)},
 
 	/* Display : 848x480 (CVT) */
-	{VIA_RES_848X480, CRTM848x480, ARRAY_SIZE(CRTM848x480)},
+	{CRTM848x480, ARRAY_SIZE(CRTM848x480)},
 
 	/* Display : 852x480 (GTF) */
-	{VIA_RES_856X480, CRTM852x480, ARRAY_SIZE(CRTM852x480)},
+	{CRTM852x480, ARRAY_SIZE(CRTM852x480)},
 
 	/* Display : 1024x512 (GTF) */
-	{VIA_RES_1024X512, CRTM1024x512, ARRAY_SIZE(CRTM1024x512)},
+	{CRTM1024x512, ARRAY_SIZE(CRTM1024x512)},
 
 	/* Display : 1024x600 */
-	{VIA_RES_1024X600, CRTM1024x600, ARRAY_SIZE(CRTM1024x600)},
-
-	/* Display : 1024x576 (GTF) */
-	/*{ VIA_RES_1024X576, CRTM1024x576, ARRAY_SIZE(CRTM1024x576)}, */
+	{CRTM1024x600, ARRAY_SIZE(CRTM1024x600)},
 
 	/* Display : 1024x768 */
-	{VIA_RES_1024X768, CRTM1024x768, ARRAY_SIZE(CRTM1024x768)},
+	{CRTM1024x768, ARRAY_SIZE(CRTM1024x768)},
 
 	/* Display : 1152x864 */
-	{VIA_RES_1152X864, CRTM1152x864, ARRAY_SIZE(CRTM1152x864)},
+	{CRTM1152x864, ARRAY_SIZE(CRTM1152x864)},
 
 	/* Display : 1280x768 (GTF) */
-	{VIA_RES_1280X768, CRTM1280x768, ARRAY_SIZE(CRTM1280x768)},
+	{CRTM1280x768, ARRAY_SIZE(CRTM1280x768)},
 
 	/* Display : 960x600 (CVT) */
-	{VIA_RES_960X600, CRTM960x600, ARRAY_SIZE(CRTM960x600)},
+	{CRTM960x600, ARRAY_SIZE(CRTM960x600)},
 
 	/* Display : 1000x600 (GTF) */
-	{VIA_RES_1000X600, CRTM1000x600, ARRAY_SIZE(CRTM1000x600)},
+	{CRTM1000x600, ARRAY_SIZE(CRTM1000x600)},
 
 	/* Display : 1024x576 (GTF) */
-	{VIA_RES_1024X576, CRTM1024x576, ARRAY_SIZE(CRTM1024x576)},
+	{CRTM1024x576, ARRAY_SIZE(CRTM1024x576)},
 
 	/* Display : 1088x612 (GTF) */
-	{VIA_RES_1088X612, CRTM1088x612, ARRAY_SIZE(CRTM1088x612)},
+	{CRTM1088x612, ARRAY_SIZE(CRTM1088x612)},
 
 	/* Display : 1152x720 (CVT) */
-	{VIA_RES_1152X720, CRTM1152x720, ARRAY_SIZE(CRTM1152x720)},
+	{CRTM1152x720, ARRAY_SIZE(CRTM1152x720)},
 
 	/* Display : 1200x720 (GTF) */
-	{VIA_RES_1200X720, CRTM1200x720, ARRAY_SIZE(CRTM1200x720)},
+	{CRTM1200x720, ARRAY_SIZE(CRTM1200x720)},
 
 	/* Display : 1280x600 (GTF) */
-	{VIA_RES_1280X600, CRTM1280x600, ARRAY_SIZE(CRTM1280x600)},
+	{CRTM1280x600, ARRAY_SIZE(CRTM1280x600)},
 
 	/* Display : 1280x800 (CVT) */
-	{VIA_RES_1280X800, CRTM1280x800, ARRAY_SIZE(CRTM1280x800)},
-
-	/* Display : 1280x800 (GTF) */
-	/*{ M1280x800, CRTM1280x800, ARRAY_SIZE(CRTM1280x800)}, */
+	{CRTM1280x800, ARRAY_SIZE(CRTM1280x800)},
 
 	/* Display : 1280x960 */
-	{VIA_RES_1280X960, CRTM1280x960, ARRAY_SIZE(CRTM1280x960)},
+	{CRTM1280x960, ARRAY_SIZE(CRTM1280x960)},
 
 	/* Display : 1280x1024 */
-	{VIA_RES_1280X1024, CRTM1280x1024, ARRAY_SIZE(CRTM1280x1024)},
+	{CRTM1280x1024, ARRAY_SIZE(CRTM1280x1024)},
 
 	/* Display : 1360x768 (CVT) */
-	{VIA_RES_1360X768, CRTM1360x768, ARRAY_SIZE(CRTM1360x768)},
-
-	/* Display : 1360x768 (CVT Reduce Blanking) */
-	{VIA_RES_1360X768_RB, CRTM1360x768_RB,
-	 ARRAY_SIZE(CRTM1360x768_RB)},
+	{CRTM1360x768, ARRAY_SIZE(CRTM1360x768)},
 
 	/* Display : 1366x768 */
-	{VIA_RES_1366X768, CRTM1366x768, ARRAY_SIZE(CRTM1366x768)},
+	{CRTM1366x768, ARRAY_SIZE(CRTM1366x768)},
 
 	/* Display : 1368x768 (GTF) */
-	/*{ M1368x768,CRTM1368x768,ARRAY_SIZE(CRTM1368x768)}, */
-	/* Display : 1368x768 (GTF) */
-	{VIA_RES_1368X768, CRTM1368x768, ARRAY_SIZE(CRTM1368x768)},
+	{CRTM1368x768, ARRAY_SIZE(CRTM1368x768)},
 
 	/* Display : 1440x900 (CVT) */
-	{VIA_RES_1440X900, CRTM1440x900, ARRAY_SIZE(CRTM1440x900)},
-
-	/* Display : 1440x900 (CVT Reduce Blanking) */
-	{VIA_RES_1440X900_RB, CRTM1440x900_RB,
-	 ARRAY_SIZE(CRTM1440x900_RB)},
+	{CRTM1440x900, ARRAY_SIZE(CRTM1440x900)},
 
 	/* Display : 1440x1050 (GTF) */
-	{VIA_RES_1440X1050, CRTM1440x1050, ARRAY_SIZE(CRTM1440x1050)},
-
-	/* Display : 1400x1050 (CVT Reduce Blanking) */
-	{VIA_RES_1400X1050_RB, CRTM1400x1050_RB,
-	 ARRAY_SIZE(CRTM1400x1050_RB)},
+	{CRTM1440x1050, ARRAY_SIZE(CRTM1440x1050)},
 
 	/* Display : 1600x900 (CVT) */
-	{VIA_RES_1600X900, CRTM1600x900, ARRAY_SIZE(CRTM1600x900)},
-
-	/* Display : 1600x900 (CVT Reduce Blanking) */
-	{VIA_RES_1600X900_RB, CRTM1600x900_RB,
-	 ARRAY_SIZE(CRTM1600x900_RB)},
+	{CRTM1600x900, ARRAY_SIZE(CRTM1600x900)},
 
 	/* Display : 1600x1024 (GTF) */
-	{VIA_RES_1600X1024, CRTM1600x1024, ARRAY_SIZE(CRTM1600x1024)},
+	{CRTM1600x1024, ARRAY_SIZE(CRTM1600x1024)},
 
 	/* Display : 1600x1200 */
-	{VIA_RES_1600X1200, CRTM1600x1200, ARRAY_SIZE(CRTM1600x1200)},
+	{CRTM1600x1200, ARRAY_SIZE(CRTM1600x1200)},
 
 	/* Display : 1680x1050 (CVT) */
-	{VIA_RES_1680X1050, CRTM1680x1050, ARRAY_SIZE(CRTM1680x1050)},
-
-	/* Display : 1680x1050 (CVT Reduce Blanking) */
-	{VIA_RES_1680X1050_RB, CRTM1680x1050_RB,
-	 ARRAY_SIZE(CRTM1680x1050_RB)},
+	{CRTM1680x1050, ARRAY_SIZE(CRTM1680x1050)},
 
 	/* Display : 1792x1344 (DMT) */
-	{VIA_RES_1792X1344, CRTM1792x1344, ARRAY_SIZE(CRTM1792x1344)},
+	{CRTM1792x1344, ARRAY_SIZE(CRTM1792x1344)},
 
 	/* Display : 1856x1392 (DMT) */
-	{VIA_RES_1856X1392, CRTM1856x1392, ARRAY_SIZE(CRTM1856x1392)},
+	{CRTM1856x1392, ARRAY_SIZE(CRTM1856x1392)},
 
 	/* Display : 1920x1440 */
-	{VIA_RES_1920X1440, CRTM1920x1440, ARRAY_SIZE(CRTM1920x1440)},
+	{CRTM1920x1440, ARRAY_SIZE(CRTM1920x1440)},
 
 	/* Display : 2048x1536 */
-	{VIA_RES_2048X1536, CRTM2048x1536, ARRAY_SIZE(CRTM2048x1536)},
+	{CRTM2048x1536, ARRAY_SIZE(CRTM2048x1536)},
 
 	/* Display : 1280x720 */
-	{VIA_RES_1280X720, CRTM1280x720, ARRAY_SIZE(CRTM1280x720)},
+	{CRTM1280x720, ARRAY_SIZE(CRTM1280x720)},
 
 	/* Display : 1920x1080 (CVT) */
-	{VIA_RES_1920X1080, CRTM1920x1080, ARRAY_SIZE(CRTM1920x1080)},
-
-	/* Display : 1920x1080 (CVT Reduce Blanking) */
-	{VIA_RES_1920X1080_RB, CRTM1920x1080_RB,
-	 ARRAY_SIZE(CRTM1920x1080_RB)},
+	{CRTM1920x1080, ARRAY_SIZE(CRTM1920x1080)},
 
 	/* Display : 1920x1200 (CVT) */
-	{VIA_RES_1920X1200, CRTM1920x1200, ARRAY_SIZE(CRTM1920x1200)},
-
-	/* Display : 1920x1200 (CVT Reduce Blanking) */
-	{VIA_RES_1920X1200_RB, CRTM1920x1200_RB,
-	 ARRAY_SIZE(CRTM1920x1200_RB)},
+	{CRTM1920x1200, ARRAY_SIZE(CRTM1920x1200)},
 
 	/* Display : 1400x1050 (CVT) */
-	{VIA_RES_1400X1050, CRTM1400x1050, ARRAY_SIZE(CRTM1400x1050)}
+	{CRTM1400x1050, ARRAY_SIZE(CRTM1400x1050)}
+};
+
+struct VideoModeTable viafb_rb_modes[] = {
+	/* Display : 1360x768 (CVT Reduce Blanking) */
+	{CRTM1360x768_RB, ARRAY_SIZE(CRTM1360x768_RB)},
+
+	/* Display : 1440x900 (CVT Reduce Blanking) */
+	{CRTM1440x900_RB, ARRAY_SIZE(CRTM1440x900_RB)},
+
+	/* Display : 1400x1050 (CVT Reduce Blanking) */
+	{CRTM1400x1050_RB, ARRAY_SIZE(CRTM1400x1050_RB)},
+
+	/* Display : 1600x900 (CVT Reduce Blanking) */
+	{CRTM1600x900_RB, ARRAY_SIZE(CRTM1600x900_RB)},
+
+	/* Display : 1680x1050 (CVT Reduce Blanking) */
+	{CRTM1680x1050_RB, ARRAY_SIZE(CRTM1680x1050_RB)},
+
+	/* Display : 1920x1080 (CVT Reduce Blanking) */
+	{CRTM1920x1080_RB, ARRAY_SIZE(CRTM1920x1080_RB)},
+
+	/* Display : 1920x1200 (CVT Reduce Blanking) */
+	{CRTM1920x1200_RB, ARRAY_SIZE(CRTM1920x1200_RB)}
 };
+
 struct crt_mode_table CEAM1280x720[] = {
 	{REFRESH_60, CLK_74_270M, M1280X720_CEA_R60_HSP,
 	 M1280X720_CEA_R60_VSP,
@@ -1056,8 +1038,8 @@ struct crt_mode_table CEAM1920x1080[] =
 };
 struct VideoModeTable CEA_HDMI_Modes[] = {
 	/* Display : 1280x720 */
-	{VIA_RES_1280X720, CEAM1280x720, ARRAY_SIZE(CEAM1280x720)},
-	{VIA_RES_1920X1080, CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)}
+	{CEAM1280x720, ARRAY_SIZE(CEAM1280x720)},
+	{CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)}
 };
 
 int NUM_TOTAL_RES_MAP_REFRESH = ARRAY_SIZE(res_map_refresh_tbl);
@@ -1069,4 +1051,28 @@ int NUM_TOTAL_CX700_ModeXregs = ARRAY_SI
 int NUM_TOTAL_VX855_ModeXregs = ARRAY_SIZE(VX855_ModeXregs);
 int NUM_TOTAL_CLE266_ModeXregs = ARRAY_SIZE(CLE266_ModeXregs);
 int NUM_TOTAL_PATCH_MODE = ARRAY_SIZE(res_patch_table);
-int NUM_TOTAL_MODETABLE = ARRAY_SIZE(CLE266Modes);
+
+
+struct VideoModeTable *viafb_get_mode(int hres, int vres)
+{
+	u32 i;
+	for (i = 0; i < ARRAY_SIZE(viafb_modes); i++)
+		if (viafb_modes[i].mode_array &&
+			viafb_modes[i].crtc[0].crtc.hor_addr == hres &&
+			viafb_modes[i].crtc[0].crtc.ver_addr == vres)
+			return &viafb_modes[i];
+
+	return NULL;
+}
+
+struct VideoModeTable *viafb_get_rb_mode(int hres, int vres)
+{
+	u32 i;
+	for (i = 0; i < ARRAY_SIZE(viafb_rb_modes); i++)
+		if (viafb_rb_modes[i].mode_array &&
+			viafb_rb_modes[i].crtc[0].crtc.hor_addr == hres &&
+			viafb_rb_modes[i].crtc[0].crtc.ver_addr == vres)
+			return &viafb_rb_modes[i];
+
+	return NULL;
+}
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/viamode.h linux-libre-2.6.34-gnu1/drivers/video/via/viamode.h
--- linux-libre-2.6.33-gnu1/drivers/video/via/viamode.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/viamode.h	2010-05-16 17:17:36.000000000 -0400
@@ -32,13 +32,11 @@ struct VPITTable {
 };
 
 struct VideoModeTable {
-	int ModeIndex;
 	struct crt_mode_table *crtc;
 	int mode_array;
 };
 
 struct patch_table {
-	int mode_index;
 	int table_length;
 	struct io_reg *io_reg_table;
 };
@@ -59,13 +57,11 @@ extern int NUM_TOTAL_CX700_ModeXregs;
 extern int NUM_TOTAL_VX855_ModeXregs;
 extern int NUM_TOTAL_CLE266_ModeXregs;
 extern int NUM_TOTAL_PATCH_MODE;
-extern int NUM_TOTAL_MODETABLE;
 
 /********************/
 /* Mode Table       */
 /********************/
 
-extern struct VideoModeTable CLE266Modes[];
 extern struct crt_mode_table CEAM1280x720[];
 extern struct crt_mode_table CEAM1920x1080[];
 extern struct VideoModeTable CEA_HDMI_Modes[];
@@ -81,4 +77,8 @@ extern struct io_reg CLE266_ModeXregs[];
 extern struct io_reg PM1024x768[];
 extern struct patch_table res_patch_table[];
 extern struct VPITTable VPIT;
+
+struct VideoModeTable *viafb_get_mode(int hres, int vres);
+struct VideoModeTable *viafb_get_rb_mode(int hres, int vres);
+
 #endif /* __VIAMODE_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/via_utility.c linux-libre-2.6.34-gnu1/drivers/video/via/via_utility.c
--- linux-libre-2.6.33-gnu1/drivers/video/via/via_utility.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/via_utility.c	2010-05-16 17:17:36.000000000 -0400
@@ -239,15 +239,3 @@ void viafb_get_gamma_support_state(int b
 	else
 		*support_state = CRT_Device | DVI_Device | LCD_Device;
 }
-
-int viafb_input_parameter_converter(int parameter_value)
-{
-	int result;
-
-	if (parameter_value >= 1 && parameter_value <= 9)
-		result = 1 << (parameter_value - 1);
-	else
-		result = 1;
-
-	return result;
-}
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/via/via_utility.h linux-libre-2.6.34-gnu1/drivers/video/via/via_utility.h
--- linux-libre-2.6.33-gnu1/drivers/video/via/via_utility.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/via/via_utility.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,5 @@ bool viafb_lcd_get_support_expand_state(
 void viafb_set_gamma_table(int bpp, unsigned int *gamma_table);
 void viafb_get_gamma_table(unsigned int *gamma_table);
 void viafb_get_gamma_support_state(int bpp, unsigned int *support_state);
-int viafb_input_parameter_converter(int parameter_value);
 
 #endif /* __VIAUTILITY_H__ */
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/vt8623fb.c linux-libre-2.6.34-gnu1/drivers/video/vt8623fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/vt8623fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/vt8623fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/tty.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/svga.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/w100fb.c linux-libre-2.6.34-gnu1/drivers/video/w100fb.c
--- linux-libre-2.6.33-gnu1/drivers/video/w100fb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/w100fb.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
 #include <asm/io.h>
@@ -628,7 +629,7 @@ static int w100fb_resume(struct platform
 #endif
 
 
-int __init w100fb_probe(struct platform_device *pdev)
+int __devinit w100fb_probe(struct platform_device *pdev)
 {
 	int err = -EIO;
 	struct w100fb_mach_info *inf;
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/xen-fbfront.c linux-libre-2.6.34-gnu1/drivers/video/xen-fbfront.c
--- linux-libre-2.6.33-gnu1/drivers/video/xen-fbfront.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/xen-fbfront.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/errno.h>
 #include <linux/fb.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/video/xilinxfb.c linux-libre-2.6.34-gnu1/drivers/video/xilinxfb.c
--- linux-libre-2.6.33-gnu1/drivers/video/xilinxfb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/video/xilinxfb.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/of_platform.h>
 #include <linux/io.h>
 #include <linux/xilinxfb.h>
+#include <linux/slab.h>
 #include <asm/dcr.h>
 
 #define DRIVER_NAME		"xilinxfb"
diff -druNp linux-libre-2.6.33-gnu1/drivers/virtio/virtio_balloon.c linux-libre-2.6.34-gnu1/drivers/virtio/virtio_balloon.c
--- linux-libre-2.6.33-gnu1/drivers/virtio/virtio_balloon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/virtio/virtio_balloon.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,11 +24,12 @@
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 struct virtio_balloon
 {
 	struct virtio_device *vdev;
-	struct virtqueue *inflate_vq, *deflate_vq;
+	struct virtqueue *inflate_vq, *deflate_vq, *stats_vq;
 
 	/* Where the ballooning thread waits for config to change. */
 	wait_queue_head_t config_change;
@@ -49,6 +50,10 @@ struct virtio_balloon
 	/* The array of pfns we tell the Host about. */
 	unsigned int num_pfns;
 	u32 pfns[256];
+
+	/* Memory statistics */
+	int need_stats_update;
+	struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR];
 };
 
 static struct virtio_device_id id_table[] = {
@@ -98,7 +103,8 @@ static void fill_balloon(struct virtio_b
 	num = min(num, ARRAY_SIZE(vb->pfns));
 
 	for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) {
-		struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY);
+		struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY |
+					__GFP_NOMEMALLOC | __GFP_NOWARN);
 		if (!page) {
 			if (printk_ratelimit())
 				dev_printk(KERN_INFO, &vb->vdev->dev,
@@ -154,6 +160,72 @@ static void leak_balloon(struct virtio_b
 	}
 }
 
+static inline void update_stat(struct virtio_balloon *vb, int idx,
+			       u16 tag, u64 val)
+{
+	BUG_ON(idx >= VIRTIO_BALLOON_S_NR);
+	vb->stats[idx].tag = tag;
+	vb->stats[idx].val = val;
+}
+
+#define pages_to_bytes(x) ((u64)(x) << PAGE_SHIFT)
+
+static void update_balloon_stats(struct virtio_balloon *vb)
+{
+	unsigned long events[NR_VM_EVENT_ITEMS];
+	struct sysinfo i;
+	int idx = 0;
+
+	all_vm_events(events);
+	si_meminfo(&i);
+
+	update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_IN,
+				pages_to_bytes(events[PSWPIN]));
+	update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_OUT,
+				pages_to_bytes(events[PSWPOUT]));
+	update_stat(vb, idx++, VIRTIO_BALLOON_S_MAJFLT, events[PGMAJFAULT]);
+	update_stat(vb, idx++, VIRTIO_BALLOON_S_MINFLT, events[PGFAULT]);
+	update_stat(vb, idx++, VIRTIO_BALLOON_S_MEMFREE,
+				pages_to_bytes(i.freeram));
+	update_stat(vb, idx++, VIRTIO_BALLOON_S_MEMTOT,
+				pages_to_bytes(i.totalram));
+}
+
+/*
+ * While most virtqueues communicate guest-initiated requests to the hypervisor,
+ * the stats queue operates in reverse.  The driver initializes the virtqueue
+ * with a single buffer.  From that point forward, all conversations consist of
+ * a hypervisor request (a call to this function) which directs us to refill
+ * the virtqueue with a fresh stats buffer.  Since stats collection can sleep,
+ * we notify our kthread which does the actual work via stats_handle_request().
+ */
+static void stats_request(struct virtqueue *vq)
+{
+	struct virtio_balloon *vb;
+	unsigned int len;
+
+	vb = vq->vq_ops->get_buf(vq, &len);
+	if (!vb)
+		return;
+	vb->need_stats_update = 1;
+	wake_up(&vb->config_change);
+}
+
+static void stats_handle_request(struct virtio_balloon *vb)
+{
+	struct virtqueue *vq;
+	struct scatterlist sg;
+
+	vb->need_stats_update = 0;
+	update_balloon_stats(vb);
+
+	vq = vb->stats_vq;
+	sg_init_one(&sg, vb->stats, sizeof(vb->stats));
+	if (vq->vq_ops->add_buf(vq, &sg, 1, 0, vb) < 0)
+		BUG();
+	vq->vq_ops->kick(vq);
+}
+
 static void virtballoon_changed(struct virtio_device *vdev)
 {
 	struct virtio_balloon *vb = vdev->priv;
@@ -190,8 +262,11 @@ static int balloon(void *_vballoon)
 		try_to_freeze();
 		wait_event_interruptible(vb->config_change,
 					 (diff = towards_target(vb)) != 0
+					 || vb->need_stats_update
 					 || kthread_should_stop()
 					 || freezing(current));
+		if (vb->need_stats_update)
+			stats_handle_request(vb);
 		if (diff > 0)
 			fill_balloon(vb, diff);
 		else if (diff < 0)
@@ -204,10 +279,10 @@ static int balloon(void *_vballoon)
 static int virtballoon_probe(struct virtio_device *vdev)
 {
 	struct virtio_balloon *vb;
-	struct virtqueue *vqs[2];
-	vq_callback_t *callbacks[] = { balloon_ack, balloon_ack };
-	const char *names[] = { "inflate", "deflate" };
-	int err;
+	struct virtqueue *vqs[3];
+	vq_callback_t *callbacks[] = { balloon_ack, balloon_ack, stats_request };
+	const char *names[] = { "inflate", "deflate", "stats" };
+	int err, nvqs;
 
 	vdev->priv = vb = kmalloc(sizeof(*vb), GFP_KERNEL);
 	if (!vb) {
@@ -219,14 +294,31 @@ static int virtballoon_probe(struct virt
 	vb->num_pages = 0;
 	init_waitqueue_head(&vb->config_change);
 	vb->vdev = vdev;
+	vb->need_stats_update = 0;
 
-	/* We expect two virtqueues. */
-	err = vdev->config->find_vqs(vdev, 2, vqs, callbacks, names);
+	/* We expect two virtqueues: inflate and deflate,
+	 * and optionally stat. */
+	nvqs = virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ) ? 3 : 2;
+	err = vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names);
 	if (err)
 		goto out_free_vb;
 
 	vb->inflate_vq = vqs[0];
 	vb->deflate_vq = vqs[1];
+	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ)) {
+		struct scatterlist sg;
+		vb->stats_vq = vqs[2];
+
+		/*
+		 * Prime this virtqueue with one buffer so the hypervisor can
+		 * use it to signal us later.
+		 */
+		sg_init_one(&sg, vb->stats, sizeof vb->stats);
+		if (vb->stats_vq->vq_ops->add_buf(vb->stats_vq,
+						  &sg, 1, 0, vb) < 0)
+			BUG();
+		vb->stats_vq->vq_ops->kick(vb->stats_vq);
+	}
 
 	vb->thread = kthread_run(balloon, vb, "vballoon");
 	if (IS_ERR(vb->thread)) {
@@ -264,7 +356,10 @@ static void __devexit virtballoon_remove
 	kfree(vb);
 }
 
-static unsigned int features[] = { VIRTIO_BALLOON_F_MUST_TELL_HOST };
+static unsigned int features[] = {
+	VIRTIO_BALLOON_F_MUST_TELL_HOST,
+	VIRTIO_BALLOON_F_STATS_VQ,
+};
 
 static struct virtio_driver virtio_balloon_driver = {
 	.feature_table = features,
diff -druNp linux-libre-2.6.33-gnu1/drivers/virtio/virtio_pci.c linux-libre-2.6.34-gnu1/drivers/virtio/virtio_pci.c
--- linux-libre-2.6.33-gnu1/drivers/virtio/virtio_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/virtio/virtio_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/list.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/virtio.h>
 #include <linux/virtio_config.h>
@@ -473,7 +474,8 @@ static void vp_del_vqs(struct virtio_dev
 
 	list_for_each_entry_safe(vq, n, &vdev->vqs, list) {
 		info = vq->priv;
-		if (vp_dev->per_vq_vectors)
+		if (vp_dev->per_vq_vectors &&
+			info->msix_vector != VIRTIO_MSI_NO_VECTOR)
 			free_irq(vp_dev->msix_entries[info->msix_vector].vector,
 				 vq);
 		vp_del_vq(vq);
@@ -648,6 +650,7 @@ static int __devinit virtio_pci_probe(st
 		goto out_req_regions;
 
 	pci_set_drvdata(pci_dev, vp_dev);
+	pci_set_master(pci_dev);
 
 	/* we use the subsystem vendor/device id as the virtio vendor/device
 	 * id.  this allows us to use the same PCI vendor/device id for all
@@ -702,7 +705,7 @@ static struct pci_driver virtio_pci_driv
 	.name		= "virtio-pci",
 	.id_table	= virtio_pci_id_table,
 	.probe		= virtio_pci_probe,
-	.remove		= virtio_pci_remove,
+	.remove		= __devexit_p(virtio_pci_remove),
 #ifdef CONFIG_PM
 	.suspend	= virtio_pci_suspend,
 	.resume		= virtio_pci_resume,
diff -druNp linux-libre-2.6.33-gnu1/drivers/virtio/virtio_ring.c linux-libre-2.6.34-gnu1/drivers/virtio/virtio_ring.c
--- linux-libre-2.6.33-gnu1/drivers/virtio/virtio_ring.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/virtio/virtio_ring.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,25 @@
 #include <linux/virtio_ring.h>
 #include <linux/virtio_config.h>
 #include <linux/device.h>
+#include <linux/slab.h>
+
+/* virtio guest is communicating with a virtual "device" that actually runs on
+ * a host processor.  Memory barriers are used to control SMP effects. */
+#ifdef CONFIG_SMP
+/* Where possible, use SMP barriers which are more lightweight than mandatory
+ * barriers, because mandatory barriers control MMIO effects on accesses
+ * through relaxed memory I/O windows (which virtio does not use). */
+#define virtio_mb() smp_mb()
+#define virtio_rmb() smp_rmb()
+#define virtio_wmb() smp_wmb()
+#else
+/* We must force memory ordering even if guest is UP since host could be
+ * running on another CPU, but SMP barriers are defined to barrier() in that
+ * configuration. So fall back to mandatory barriers instead. */
+#define virtio_mb() mb()
+#define virtio_rmb() rmb()
+#define virtio_wmb() wmb()
+#endif
 
 #ifdef DEBUG
 /* For development, we want to crash whenever the ring is screwed. */
@@ -36,10 +55,9 @@
 			panic("%s:in_use = %i\n",		\
 			      (_vq)->vq.name, (_vq)->in_use);	\
 		(_vq)->in_use = __LINE__;			\
-		mb();						\
 	} while (0)
 #define END_USE(_vq) \
-	do { BUG_ON(!(_vq)->in_use); (_vq)->in_use = 0; mb(); } while(0)
+	do { BUG_ON(!(_vq)->in_use); (_vq)->in_use = 0; } while(0)
 #else
 #define BAD_RING(_vq, fmt, args...)				\
 	do {							\
@@ -221,13 +239,13 @@ static void vring_kick(struct virtqueue
 	START_USE(vq);
 	/* Descriptors and available array need to be set before we expose the
 	 * new available array entries. */
-	wmb();
+	virtio_wmb();
 
 	vq->vring.avail->idx += vq->num_added;
 	vq->num_added = 0;
 
 	/* Need to update avail index before checking if we should notify */
-	mb();
+	virtio_mb();
 
 	if (!(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY))
 		/* Prod other side to tell it about changes. */
@@ -286,7 +304,7 @@ static void *vring_get_buf(struct virtqu
 	}
 
 	/* Only get used array entries after they have been exposed by host. */
-	rmb();
+	virtio_rmb();
 
 	i = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].id;
 	*len = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].len;
@@ -324,7 +342,7 @@ static bool vring_enable_cb(struct virtq
 	/* We optimistically turn back on interrupts, then check if there was
 	 * more to do. */
 	vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
-	mb();
+	virtio_mb();
 	if (unlikely(more_used(vq))) {
 		END_USE(vq);
 		return false;
@@ -334,6 +352,30 @@ static bool vring_enable_cb(struct virtq
 	return true;
 }
 
+static void *vring_detach_unused_buf(struct virtqueue *_vq)
+{
+	struct vring_virtqueue *vq = to_vvq(_vq);
+	unsigned int i;
+	void *buf;
+
+	START_USE(vq);
+
+	for (i = 0; i < vq->vring.num; i++) {
+		if (!vq->data[i])
+			continue;
+		/* detach_buf clears data, so grab it now. */
+		buf = vq->data[i];
+		detach_buf(vq, i);
+		END_USE(vq);
+		return buf;
+	}
+	/* That should have freed everything. */
+	BUG_ON(vq->num_free != vq->vring.num);
+
+	END_USE(vq);
+	return NULL;
+}
+
 irqreturn_t vring_interrupt(int irq, void *_vq)
 {
 	struct vring_virtqueue *vq = to_vvq(_vq);
@@ -360,6 +402,7 @@ static struct virtqueue_ops vring_vq_ops
 	.kick = vring_kick,
 	.disable_cb = vring_disable_cb,
 	.enable_cb = vring_enable_cb,
+	.detach_unused_buf = vring_detach_unused_buf,
 };
 
 struct virtqueue *vring_new_virtqueue(unsigned int num,
@@ -406,8 +449,11 @@ struct virtqueue *vring_new_virtqueue(un
 	/* Put everything in free lists. */
 	vq->num_free = num;
 	vq->free_head = 0;
-	for (i = 0; i < num-1; i++)
+	for (i = 0; i < num-1; i++) {
 		vq->vring.desc[i].next = i+1;
+		vq->data[i] = NULL;
+	}
+	vq->data[i] = NULL;
 
 	return &vq->vq;
 }
diff -druNp linux-libre-2.6.33-gnu1/drivers/vlynq/vlynq.c linux-libre-2.6.34-gnu1/drivers/vlynq/vlynq.c
--- linux-libre-2.6.33-gnu1/drivers/vlynq/vlynq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/vlynq/vlynq.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/vlynq.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/w1/masters/ds1wm.c linux-libre-2.6.34-gnu1/drivers/w1/masters/ds1wm.c
--- linux-libre-2.6.33-gnu1/drivers/w1/masters/ds1wm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/w1/masters/ds1wm.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/ds1wm.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/w1/masters/ds2482.c linux-libre-2.6.34-gnu1/drivers/w1/masters/ds2482.c
--- linux-libre-2.6.33-gnu1/drivers/w1/masters/ds2482.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/w1/masters/ds2482.c	2010-05-16 17:17:36.000000000 -0400
@@ -214,7 +214,7 @@ static int ds2482_wait_1wire_idle(struct
 			 (++retries < DS2482_WAIT_IDLE_TIMEOUT));
 	}
 
-	if (retries > DS2482_WAIT_IDLE_TIMEOUT)
+	if (retries >= DS2482_WAIT_IDLE_TIMEOUT)
 		printk(KERN_ERR "%s: timeout on channel %d\n",
 		       __func__, pdev->channel);
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/w1/masters/ds2490.c linux-libre-2.6.34-gnu1/drivers/w1/masters/ds2490.c
--- linux-libre-2.6.33-gnu1/drivers/w1/masters/ds2490.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/w1/masters/ds2490.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/mod_devicetable.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include "../w1_int.h"
 #include "../w1.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/w1/masters/Kconfig linux-libre-2.6.34-gnu1/drivers/w1/masters/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/w1/masters/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/w1/masters/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -60,7 +60,7 @@ config W1_MASTER_GPIO
 
 config HDQ_MASTER_OMAP
 	tristate "OMAP HDQ driver"
-	depends on ARCH_OMAP2430 || ARCH_OMAP34XX
+	depends on ARCH_OMAP2430 || ARCH_OMAP3
 	help
 	  Say Y here if you want support for the 1-wire or HDQ Interface
 	  on an OMAP processor.
diff -druNp linux-libre-2.6.33-gnu1/drivers/w1/masters/mxc_w1.c linux-libre-2.6.34-gnu1/drivers/w1/masters/mxc_w1.c
--- linux-libre-2.6.33-gnu1/drivers/w1/masters/mxc_w1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/w1/masters/mxc_w1.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 
@@ -102,7 +103,7 @@ static u8 mxc_w1_ds2_touch_bit(void *dat
 	return ((__raw_readb(ctrl_addr)) >> 3) & 0x1;
 }
 
-static int __init mxc_w1_probe(struct platform_device *pdev)
+static int __devinit mxc_w1_probe(struct platform_device *pdev)
 {
 	struct mxc_w1_device *mdev;
 	struct resource *res;
@@ -166,7 +167,7 @@ failed_clk:
 /*
  * disassociate the w1 device from the driver
  */
-static int mxc_w1_remove(struct platform_device *pdev)
+static int __devexit mxc_w1_remove(struct platform_device *pdev)
 {
 	struct mxc_w1_device *mdev = platform_get_drvdata(pdev);
 	struct resource *res;
diff -druNp linux-libre-2.6.33-gnu1/drivers/w1/masters/omap_hdq.c linux-libre-2.6.34-gnu1/drivers/w1/masters/omap_hdq.c
--- linux-libre-2.6.33-gnu1/drivers/w1/masters/omap_hdq.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/w1/masters/omap_hdq.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,9 +12,11 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/sched.h>
 
 #include <asm/irq.h>
 #include <mach/hardware.h>
@@ -72,7 +74,7 @@ struct hdq_data {
 	int			init_trans;
 };
 
-static int __init omap_hdq_probe(struct platform_device *pdev);
+static int __devinit omap_hdq_probe(struct platform_device *pdev);
 static int omap_hdq_remove(struct platform_device *pdev);
 
 static struct platform_driver omap_hdq_driver = {
@@ -558,7 +560,7 @@ static void omap_w1_write_byte(void *_hd
 	return;
 }
 
-static int __init omap_hdq_probe(struct platform_device *pdev)
+static int __devinit omap_hdq_probe(struct platform_device *pdev)
 {
 	struct hdq_data *hdq_data;
 	struct resource *res;
diff -druNp linux-libre-2.6.33-gnu1/drivers/w1/masters/w1-gpio.c linux-libre-2.6.34-gnu1/drivers/w1/masters/w1-gpio.c
--- linux-libre-2.6.33-gnu1/drivers/w1/masters/w1-gpio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/w1/masters/w1-gpio.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/w1-gpio.h>
 
 #include "../w1.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/w1/slaves/w1_ds2433.c linux-libre-2.6.34-gnu1/drivers/w1/slaves/w1_ds2433.c
--- linux-libre-2.6.33-gnu1/drivers/w1/slaves/w1_ds2433.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/w1/slaves/w1_ds2433.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/device.h>
 #include <linux/types.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #ifdef CONFIG_W1_SLAVE_DS2433_CRC
 #include <linux/crc16.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/w1/slaves/w1_ds2760.c linux-libre-2.6.34-gnu1/drivers/w1/slaves/w1_ds2760.c
--- linux-libre-2.6.33-gnu1/drivers/w1/slaves/w1_ds2760.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/w1/slaves/w1_ds2760.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
 #include <linux/idr.h>
+#include <linux/gfp.h>
 
 #include "../w1.h"
 #include "../w1_int.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/w1/slaves/w1_therm.c linux-libre-2.6.34-gnu1/drivers/w1/slaves/w1_therm.c
--- linux-libre-2.6.33-gnu1/drivers/w1/slaves/w1_therm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/w1/slaves/w1_therm.c	2010-05-16 17:17:36.000000000 -0400
@@ -115,9 +115,8 @@ static struct w1_therm_family_converter
 
 static inline int w1_DS18B20_convert_temp(u8 rom[9])
 {
-	int t = ((s16)rom[1] << 8) | rom[0];
-	t = t*1000/16;
-	return t;
+	s16 t = le16_to_cpup((__le16 *)rom);
+	return t*1000/16;
 }
 
 static inline int w1_DS18S20_convert_temp(u8 rom[9])
diff -druNp linux-libre-2.6.33-gnu1/drivers/w1/w1.c linux-libre-2.6.34-gnu1/drivers/w1/w1.c
--- linux-libre-2.6.33-gnu1/drivers/w1/w1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/w1/w1.c	2010-05-16 17:17:36.000000000 -0400
@@ -986,7 +986,7 @@ int w1_process(void *data)
 	return 0;
 }
 
-static int w1_init(void)
+static int __init w1_init(void)
 {
 	int retval;
 
@@ -1034,7 +1034,7 @@ err_out_exit_init:
 	return retval;
 }
 
-static void w1_fini(void)
+static void __exit w1_fini(void)
 {
 	struct w1_master *dev;
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/w1/w1_int.c linux-libre-2.6.34-gnu1/drivers/w1/w1_int.c
--- linux-libre-2.6.33-gnu1/drivers/w1/w1_int.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/w1/w1_int.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/list.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 #include "w1.h"
 #include "w1_log.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/w1/w1_netlink.c linux-libre-2.6.34-gnu1/drivers/w1/w1_netlink.c
--- linux-libre-2.6.33-gnu1/drivers/w1/w1_netlink.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/w1/w1_netlink.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/netlink.h>
 #include <linux/connector.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/acquirewdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/acquirewdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/acquirewdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/acquirewdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -150,7 +150,7 @@ static long acq_ioctl(struct file *file,
 	int options, retval = -EINVAL;
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
 		.firmware_version = 1,
 		.identity = WATCHDOG_NAME,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/advantechwdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/advantechwdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/advantechwdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/advantechwdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -137,7 +137,7 @@ static long advwdt_ioctl(struct file *fi
 	int new_timeout;
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options = WDIOF_KEEPALIVEPING |
 			   WDIOF_SETTIMEOUT |
 			   WDIOF_MAGICCLOSE,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/adx_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/adx_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/adx_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/adx_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <linux/io.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
@@ -37,7 +38,7 @@ struct adx_wdt {
 	spinlock_t lock;
 };
 
-static struct watchdog_info adx_wdt_info = {
+static const struct watchdog_info adx_wdt_info = {
 	.identity = "Avionic Design Xanthos Watchdog",
 	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/alim1535_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/alim1535_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/alim1535_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/alim1535_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -180,7 +180,7 @@ static long ali_ioctl(struct file *file,
 {
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options =		WDIOF_KEEPALIVEPING |
 					WDIOF_SETTIMEOUT |
 					WDIOF_MAGICCLOSE,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/alim7101_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/alim7101_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/alim7101_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/alim7101_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -238,7 +238,7 @@ static long fop_ioctl(struct file *file,
 {
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
 							| WDIOF_MAGICCLOSE,
 		.firmware_version = 1,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/ar7_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/ar7_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/ar7_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/ar7_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/ioport.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
+#include <linux/clk.h>
 
 #include <asm/addrspace.h>
 #include <asm/mach-ar7/ar7.h>
@@ -80,6 +81,8 @@ static struct resource *ar7_regs_wdt;
 /* Pointer to the remapped WDT IO space */
 static struct ar7_wdt *ar7_wdt;
 
+static struct clk *vbus_clk;
+
 static void ar7_wdt_kick(u32 value)
 {
 	WRITE_REG(ar7_wdt->kick_lock, 0x5555);
@@ -138,17 +141,19 @@ static void ar7_wdt_disable(u32 value)
 static void ar7_wdt_update_margin(int new_margin)
 {
 	u32 change;
+	u32 vbus_rate;
 
-	change = new_margin * (ar7_vbus_freq() / prescale_value);
+	vbus_rate = clk_get_rate(vbus_clk);
+	change = new_margin * (vbus_rate / prescale_value);
 	if (change < 1)
 		change = 1;
 	if (change > 0xffff)
 		change = 0xffff;
 	ar7_wdt_change(change);
-	margin = change * prescale_value / ar7_vbus_freq();
+	margin = change * prescale_value / vbus_rate;
 	printk(KERN_INFO DRVNAME
 	       ": timer margin %d seconds (prescale %d, change %d, freq %d)\n",
-	       margin, prescale_value, change, ar7_vbus_freq());
+	       margin, prescale_value, change, vbus_rate);
 }
 
 static void ar7_wdt_enable_wdt(void)
@@ -214,7 +219,7 @@ static ssize_t ar7_wdt_write(struct file
 static long ar7_wdt_ioctl(struct file *file,
 					unsigned int cmd, unsigned long arg)
 {
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.identity = LONGNAME,
 		.firmware_version = 1,
 		.options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
@@ -298,6 +303,13 @@ static int __devinit ar7_wdt_probe(struc
 		goto out_mem_region;
 	}
 
+	vbus_clk = clk_get(NULL, "vbus");
+	if (IS_ERR(vbus_clk)) {
+		printk(KERN_ERR DRVNAME ": could not get vbus clock\n");
+		rc = PTR_ERR(vbus_clk);
+		goto out_mem_region;
+	}
+
 	ar7_wdt_disable_wdt();
 	ar7_wdt_prescale(prescale_value);
 	ar7_wdt_update_margin(margin);
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/at32ap700x_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/at32ap700x_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/at32ap700x_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/at32ap700x_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 
 #define TIMEOUT_MIN		1
 #define TIMEOUT_MAX		2
@@ -202,7 +203,7 @@ static int at32_wdt_get_status(void)
 	return status;
 }
 
-static struct watchdog_info at32_wdt_info = {
+static const struct watchdog_info at32_wdt_info = {
 	.identity	= "at32ap700x watchdog",
 	.options	= WDIOF_SETTIMEOUT |
 			  WDIOF_KEEPALIVEPING |
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/at91rm9200_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/at91rm9200_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/at91rm9200_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/at91rm9200_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -121,7 +121,7 @@ static int at91_wdt_settimeout(int new_t
 	return 0;
 }
 
-static struct watchdog_info at91_wdt_info = {
+static const struct watchdog_info at91_wdt_info = {
 	.identity	= "at91 watchdog",
 	.options	= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/bcm47xx_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/bcm47xx_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/bcm47xx_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/bcm47xx_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -149,7 +149,7 @@ static ssize_t bcm47xx_wdt_write(struct
 	return len;
 }
 
-static struct watchdog_info bcm47xx_wdt_info = {
+static const struct watchdog_info bcm47xx_wdt_info = {
 	.identity 	= DRV_NAME,
 	.options 	= WDIOF_SETTIMEOUT |
 				WDIOF_KEEPALIVEPING |
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/bfin_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/bfin_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/bfin_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/bfin_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,8 +19,6 @@
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/fs.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/uaccess.h>
@@ -74,7 +72,7 @@
 
 static unsigned int timeout = WATCHDOG_TIMEOUT;
 static int nowayout = WATCHDOG_NOWAYOUT;
-static struct watchdog_info bfin_wdt_info;
+static const struct watchdog_info bfin_wdt_info;
 static unsigned long open_check;
 static char expect_close;
 static DEFINE_SPINLOCK(bfin_wdt_spinlock);
@@ -309,26 +307,6 @@ static long bfin_wdt_ioctl(struct file *
 	}
 }
 
-/**
- *	bfin_wdt_notify_sys - Notifier Handler
- *	@this: notifier block
- *	@code: notifier event
- *	@unused: unused
- *
- *	Handles specific events, such as turning off the watchdog during a
- *	shutdown event.
- */
-static int bfin_wdt_notify_sys(struct notifier_block *this,
-					unsigned long code, void *unused)
-{
-	stampit();
-
-	if (code == SYS_DOWN || code == SYS_HALT)
-		bfin_wdt_stop();
-
-	return NOTIFY_DONE;
-}
-
 #ifdef CONFIG_PM
 static int state_before_suspend;
 
@@ -388,40 +366,28 @@ static struct miscdevice bfin_wdt_miscde
 	.fops     = &bfin_wdt_fops,
 };
 
-static struct watchdog_info bfin_wdt_info = {
+static const struct watchdog_info bfin_wdt_info = {
 	.identity = "Blackfin Watchdog",
 	.options  = WDIOF_SETTIMEOUT |
 		    WDIOF_KEEPALIVEPING |
 		    WDIOF_MAGICCLOSE,
 };
 
-static struct notifier_block bfin_wdt_notifier = {
-	.notifier_call = bfin_wdt_notify_sys,
-};
-
 /**
  *	bfin_wdt_probe - Initialize module
  *
- *	Registers the misc device and notifier handler.  Actual device
+ *	Registers the misc device.  Actual device
  *	initialization is handled by bfin_wdt_open().
  */
 static int __devinit bfin_wdt_probe(struct platform_device *pdev)
 {
 	int ret;
 
-	ret = register_reboot_notifier(&bfin_wdt_notifier);
-	if (ret) {
-		pr_devinit(KERN_ERR PFX
-			"cannot register reboot notifier (err=%d)\n", ret);
-		return ret;
-	}
-
 	ret = misc_register(&bfin_wdt_miscdev);
 	if (ret) {
 		pr_devinit(KERN_ERR PFX
 			"cannot register miscdev on minor=%d (err=%d)\n",
 				WATCHDOG_MINOR, ret);
-		unregister_reboot_notifier(&bfin_wdt_notifier);
 		return ret;
 	}
 
@@ -434,21 +400,33 @@ static int __devinit bfin_wdt_probe(stru
 /**
  *	bfin_wdt_remove - Initialize module
  *
- *	Unregisters the misc device and notifier handler.  Actual device
+ *	Unregisters the misc device.  Actual device
  *	deinitialization is handled by bfin_wdt_close().
  */
 static int __devexit bfin_wdt_remove(struct platform_device *pdev)
 {
 	misc_deregister(&bfin_wdt_miscdev);
-	unregister_reboot_notifier(&bfin_wdt_notifier);
 	return 0;
 }
 
+/**
+ *	bfin_wdt_shutdown - Soft Shutdown Handler
+ *
+ *	Handles the soft shutdown event.
+ */
+static void bfin_wdt_shutdown(struct platform_device *pdev)
+{
+	stampit();
+
+	bfin_wdt_stop();
+}
+
 static struct platform_device *bfin_wdt_device;
 
 static struct platform_driver bfin_wdt_driver = {
 	.probe     = bfin_wdt_probe,
 	.remove    = __devexit_p(bfin_wdt_remove),
+	.shutdown  = bfin_wdt_shutdown,
 	.suspend   = bfin_wdt_suspend,
 	.resume    = bfin_wdt_resume,
 	.driver    = {
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/booke_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/booke_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/booke_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/booke_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -44,7 +44,7 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAUL
 
 #ifdef	CONFIG_FSL_BOOKE
 #define WDTP(x)		((((x)&0x3)<<30)|(((x)&0x3c)<<15))
-#define WDTP_MASK	(WDTP(0))
+#define WDTP_MASK	(WDTP(0x3f))
 #else
 #define WDTP(x)		(TCR_WP(x))
 #define WDTP_MASK	(TCR_WP_MASK)
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/coh901327_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/coh901327_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/coh901327_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/coh901327_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -257,7 +257,7 @@ static long coh901327_ioctl(struct file
 		struct watchdog_info __user *ident;
 		int __user *i;
 	} uarg;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options		= WDIOF_CARDRESET |
 					  WDIOF_SETTIMEOUT |
 					  WDIOF_KEEPALIVEPING,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/cpu5wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/cpu5wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/cpu5wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/cpu5wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -154,7 +154,7 @@ static long cpu5wdt_ioctl(struct file *f
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
 	unsigned int value;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options = WDIOF_CARDRESET,
 		.identity = "CPU5 WDT",
 	};
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/cpwd.c linux-libre-2.6.34-gnu1/drivers/watchdog/cpwd.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/cpwd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/cpwd.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/io.h>
 #include <linux/of.h>
@@ -403,7 +404,7 @@ static int cpwd_release(struct inode *in
 
 static long cpwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	static struct watchdog_info info = {
+	static const struct watchdog_info info = {
 		.options		= WDIOF_SETTIMEOUT,
 		.firmware_version	= 1,
 		.identity		= DRIVER_NAME,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/davinci_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/davinci_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/davinci_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/davinci_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/io.h>
 #include <linux/device.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #define MODULE_NAME "DAVINCI-WDT: "
 
@@ -142,7 +143,7 @@ davinci_wdt_write(struct file *file, con
 	return len;
 }
 
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
 	.options = WDIOF_KEEPALIVEPING,
 	.identity = "DaVinci Watchdog",
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/ep93xx_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/ep93xx_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/ep93xx_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/ep93xx_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -131,7 +131,7 @@ ep93xx_wdt_write(struct file *file, cons
 	return len;
 }
 
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
 	.options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE,
 	.identity = "EP93xx Watchdog",
 };
@@ -244,7 +244,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog can
 module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout,
 	"Watchdog timeout in seconds. (1<=timeout<=3600, default="
-				__MODULE_STRING(WATCHDOG_TIMEOUT) ")");
+				__MODULE_STRING(WDT_TIMEOUT) ")");
 
 MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>,"
 		"Alessandro Zummo <a.zummo@towertech.it>");
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/eurotechwdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/eurotechwdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/eurotechwdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/eurotechwdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -238,7 +238,7 @@ static long eurwdt_ioctl(struct file *fi
 {
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options	  = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
 							| WDIOF_MAGICCLOSE,
 		.firmware_version = 1,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/gef_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/gef_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/gef_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/gef_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,9 +1,9 @@
 /*
- * GE Fanuc watchdog userspace interface
+ * GE watchdog userspace interface
  *
- * Author:  Martyn Welch <martyn.welch@gefanuc.com>
+ * Author:  Martyn Welch <martyn.welch@ge.com>
  *
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -161,11 +161,11 @@ static long gef_wdt_ioctl(struct file *f
 	int timeout;
 	int options;
 	void __user *argp = (void __user *)arg;
-	static struct watchdog_info info = {
+	static const struct watchdog_info info = {
 		.options =	WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE |
 				WDIOF_KEEPALIVEPING,
 		.firmware_version = 0,
-		.identity = "GE Fanuc watchdog",
+		.identity = "GE watchdog",
 	};
 
 	switch (cmd) {
@@ -311,7 +311,7 @@ static struct of_platform_driver gef_wdt
 
 static int __init gef_wdt_init(void)
 {
-	printk(KERN_INFO "GE Fanuc watchdog driver\n");
+	printk(KERN_INFO "GE watchdog driver\n");
 	return of_register_platform_driver(&gef_wdt_driver);
 }
 
@@ -323,8 +323,8 @@ static void __exit gef_wdt_exit(void)
 module_init(gef_wdt_init);
 module_exit(gef_wdt_exit);
 
-MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com>");
-MODULE_DESCRIPTION("GE Fanuc watchdog driver");
+MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>");
+MODULE_DESCRIPTION("GE watchdog driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
 MODULE_ALIAS("platform: gef_wdt");
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/geodewdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/geodewdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/geodewdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/geodewdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -142,7 +142,7 @@ static long geodewdt_ioctl(struct file *
 	int __user *p = argp;
 	int interval;
 
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING
 		| WDIOF_MAGICCLOSE,
 		.firmware_version =     1,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/hpwdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/hpwdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/hpwdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/hpwdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,7 +39,6 @@
 #include <linux/efi.h>
 #include <linux/string.h>
 #include <linux/bootmem.h>
-#include <linux/slab.h>
 #include <asm/desc.h>
 #include <asm/cacheflush.h>
 
@@ -443,7 +442,7 @@ static void hpwdt_ping(void)
 static int hpwdt_change_timer(int new_margin)
 {
 	/* Arbitrary, can't find the card's limits */
-	if (new_margin < 30 || new_margin > 600) {
+	if (new_margin < 5 || new_margin > 600) {
 		printk(KERN_WARNING
 			"hpwdt: New value passed in is invalid: %d seconds.\n",
 			new_margin);
@@ -554,7 +553,7 @@ static ssize_t hpwdt_write(struct file *
 	return len;
 }
 
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
 	.options = WDIOF_SETTIMEOUT |
 		   WDIOF_KEEPALIVEPING |
 		   WDIOF_MAGICCLOSE,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/i6300esb.c linux-libre-2.6.34-gnu1/drivers/watchdog/i6300esb.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/i6300esb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/i6300esb.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,7 +34,6 @@
 #include <linux/mm.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
@@ -42,7 +41,7 @@
 #include <linux/io.h>
 
 /* Module and version information */
-#define ESB_VERSION "0.04"
+#define ESB_VERSION "0.05"
 #define ESB_MODULE_NAME "i6300ESB timer"
 #define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION
 #define PFX ESB_MODULE_NAME ": "
@@ -65,7 +64,7 @@
 /* Config register bits */
 #define ESB_WDT_REBOOT  (0x01 << 5)   /* Enable reboot on timeout          */
 #define ESB_WDT_FREQ    (0x01 << 2)   /* Decrement frequency               */
-#define ESB_WDT_INTTYPE (0x11 << 0)   /* Interrupt type on timer1 timeout  */
+#define ESB_WDT_INTTYPE (0x03 << 0)   /* Interrupt type on timer1 timeout  */
 
 /* Reload register bits */
 #define ESB_WDT_TIMEOUT (0x01 << 9)    /* Watchdog timed out                */
@@ -82,7 +81,9 @@ static unsigned long timer_alive;
 static struct pci_dev *esb_pci;
 static unsigned short triggered; /* The status of the watchdog upon boot */
 static char esb_expect_close;
-static struct platform_device *esb_platform_device;
+
+/* We can only use 1 card due to the /dev/watchdog restriction */
+static int cards_found;
 
 /* module parameters */
 /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */
@@ -111,8 +112,8 @@ MODULE_PARM_DESC(nowayout,
  */
 static inline void esb_unlock_registers(void)
 {
-	writeb(ESB_UNLOCK1, ESB_RELOAD_REG);
-	writeb(ESB_UNLOCK2, ESB_RELOAD_REG);
+	writew(ESB_UNLOCK1, ESB_RELOAD_REG);
+	writew(ESB_UNLOCK2, ESB_RELOAD_REG);
 }
 
 static int esb_timer_start(void)
@@ -256,7 +257,7 @@ static long esb_ioctl(struct file *file,
 	int new_heartbeat;
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options =		WDIOF_SETTIMEOUT |
 					WDIOF_KEEPALIVEPING |
 					WDIOF_MAGICCLOSE,
@@ -332,11 +333,6 @@ static struct miscdevice esb_miscdev = {
 
 /*
  * Data for PCI driver interface
- *
- * This data only exists for exporting the supported
- * PCI ids via MODULE_DEVICE_TABLE.  We do not actually
- * register a pci_driver, because someone else might one day
- * want to register another driver on the same PCI id.
  */
 static struct pci_device_id esb_pci_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), },
@@ -348,29 +344,19 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl);
  *      Init & exit routines
  */
 
-static unsigned char __devinit esb_getdevice(void)
+static unsigned char __devinit esb_getdevice(struct pci_dev *pdev)
 {
-	/*
-	 *      Find the PCI device
-	 */
-
-	esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL,
-					PCI_DEVICE_ID_INTEL_ESB_9, NULL);
-
-	if (!esb_pci)
-		return 0;
-
-	if (pci_enable_device(esb_pci)) {
+	if (pci_enable_device(pdev)) {
 		printk(KERN_ERR PFX "failed to enable device\n");
 		goto err_devput;
 	}
 
-	if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) {
+	if (pci_request_region(pdev, 0, ESB_MODULE_NAME)) {
 		printk(KERN_ERR PFX "failed to request region\n");
 		goto err_disable;
 	}
 
-	BASEADDR = pci_ioremap_bar(esb_pci, 0);
+	BASEADDR = pci_ioremap_bar(pdev, 0);
 	if (BASEADDR == NULL) {
 		/* Something's wrong here, BASEADDR has to be set */
 		printk(KERN_ERR PFX "failed to get BASEADDR\n");
@@ -378,14 +364,14 @@ static unsigned char __devinit esb_getde
 	}
 
 	/* Done */
+	esb_pci = pdev;
 	return 1;
 
 err_release:
-	pci_release_region(esb_pci, 0);
+	pci_release_region(pdev, 0);
 err_disable:
-	pci_disable_device(esb_pci);
+	pci_disable_device(pdev);
 err_devput:
-	pci_dev_put(esb_pci);
 	return 0;
 }
 
@@ -430,12 +416,23 @@ static void __devinit esb_initdevice(voi
 	esb_timer_set_heartbeat(heartbeat);
 }
 
-static int __devinit esb_probe(struct platform_device *dev)
+static int __devinit esb_probe(struct pci_dev *pdev,
+		const struct pci_device_id *ent)
 {
 	int ret;
 
+	cards_found++;
+	if (cards_found == 1)
+		printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n",
+			ESB_VERSION);
+
+	if (cards_found > 1) {
+		printk(KERN_ERR PFX "This driver only supports 1 device\n");
+		return -ENODEV;
+	}
+
 	/* Check whether or not the hardware watchdog is there */
-	if (!esb_getdevice() || esb_pci == NULL)
+	if (!esb_getdevice(pdev) || esb_pci == NULL)
 		return -ENODEV;
 
 	/* Check that the heartbeat value is within it's range;
@@ -467,11 +464,11 @@ err_unmap:
 	iounmap(BASEADDR);
 	pci_release_region(esb_pci, 0);
 	pci_disable_device(esb_pci);
-	pci_dev_put(esb_pci);
+	esb_pci = NULL;
 	return ret;
 }
 
-static int __devexit esb_remove(struct platform_device *dev)
+static void __devexit esb_remove(struct pci_dev *pdev)
 {
 	/* Stop the timer before we leave */
 	if (!nowayout)
@@ -482,54 +479,30 @@ static int __devexit esb_remove(struct p
 	iounmap(BASEADDR);
 	pci_release_region(esb_pci, 0);
 	pci_disable_device(esb_pci);
-	pci_dev_put(esb_pci);
-	return 0;
+	esb_pci = NULL;
 }
 
-static void esb_shutdown(struct platform_device *dev)
+static void esb_shutdown(struct pci_dev *pdev)
 {
 	esb_timer_stop();
 }
 
-static struct platform_driver esb_platform_driver = {
+static struct pci_driver esb_driver = {
+	.name		= ESB_MODULE_NAME,
+	.id_table	= esb_pci_tbl,
 	.probe          = esb_probe,
 	.remove         = __devexit_p(esb_remove),
 	.shutdown       = esb_shutdown,
-	.driver         = {
-		.owner  = THIS_MODULE,
-		.name   = ESB_MODULE_NAME,
-	},
 };
 
 static int __init watchdog_init(void)
 {
-	int err;
-
-	printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n",
-		ESB_VERSION);
-
-	err = platform_driver_register(&esb_platform_driver);
-	if (err)
-		return err;
-
-	esb_platform_device = platform_device_register_simple(ESB_MODULE_NAME,
-								-1, NULL, 0);
-	if (IS_ERR(esb_platform_device)) {
-		err = PTR_ERR(esb_platform_device);
-		goto unreg_platform_driver;
-	}
-
-	return 0;
-
-unreg_platform_driver:
-	platform_driver_unregister(&esb_platform_driver);
-	return err;
+	return pci_register_driver(&esb_driver);
 }
 
 static void __exit watchdog_cleanup(void)
 {
-	platform_device_unregister(esb_platform_device);
-	platform_driver_unregister(&esb_platform_driver);
+	pci_unregister_driver(&esb_driver);
 	printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/ib700wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/ib700wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/ib700wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/ib700wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -174,7 +174,7 @@ static long ibwdt_ioctl(struct file *fil
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
 
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
 							| WDIOF_MAGICCLOSE,
 		.firmware_version = 1,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/ibmasr.c linux-libre-2.6.34-gnu1/drivers/watchdog/ibmasr.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/ibmasr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/ibmasr.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 
 #include <linux/fs.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/timer.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/indydog.c linux-libre-2.6.34-gnu1/drivers/watchdog/indydog.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/indydog.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/indydog.c	2010-05-16 17:17:36.000000000 -0400
@@ -111,7 +111,7 @@ static long indydog_ioctl(struct file *f
 							unsigned long arg)
 {
 	int options, retval = -EINVAL;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options		= WDIOF_KEEPALIVEPING,
 		.firmware_version	= 0,
 		.identity		= "Hardware Watchdog for SGI IP22",
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/it8712f_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/it8712f_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/it8712f_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/it8712f_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -236,7 +236,7 @@ static long it8712f_wdt_ioctl(struct fil
 {
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.identity = "IT8712F Watchdog",
 		.firmware_version = 1,
 		.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/it87_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/it87_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/it87_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/it87_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -421,7 +421,7 @@ static ssize_t wdt_write(struct file *fi
 	return count;
 }
 
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
 	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
 	.firmware_version =	1,
 	.identity = WATCHDOG_NAME,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/iTCO_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/iTCO_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/iTCO_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/iTCO_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -115,8 +115,37 @@ enum iTCO_chipsets {
 	TCO_3420,	/* 3420 */
 	TCO_3450,	/* 3450 */
 	TCO_EP80579,	/* EP80579 */
-	TCO_CPTD,	/* CPT Desktop */
-	TCO_CPTM,	/* CPT Mobile */
+	TCO_CPT1,	/* Cougar Point */
+	TCO_CPT2,	/* Cougar Point Desktop */
+	TCO_CPT3,	/* Cougar Point Mobile */
+	TCO_CPT4,	/* Cougar Point */
+	TCO_CPT5,	/* Cougar Point */
+	TCO_CPT6,	/* Cougar Point */
+	TCO_CPT7,	/* Cougar Point */
+	TCO_CPT8,	/* Cougar Point */
+	TCO_CPT9,	/* Cougar Point */
+	TCO_CPT10,	/* Cougar Point */
+	TCO_CPT11,	/* Cougar Point */
+	TCO_CPT12,	/* Cougar Point */
+	TCO_CPT13,	/* Cougar Point */
+	TCO_CPT14,	/* Cougar Point */
+	TCO_CPT15,	/* Cougar Point */
+	TCO_CPT16,	/* Cougar Point */
+	TCO_CPT17,	/* Cougar Point */
+	TCO_CPT18,	/* Cougar Point */
+	TCO_CPT19,	/* Cougar Point */
+	TCO_CPT20,	/* Cougar Point */
+	TCO_CPT21,	/* Cougar Point */
+	TCO_CPT22,	/* Cougar Point */
+	TCO_CPT23,	/* Cougar Point */
+	TCO_CPT24,	/* Cougar Point */
+	TCO_CPT25,	/* Cougar Point */
+	TCO_CPT26,	/* Cougar Point */
+	TCO_CPT27,	/* Cougar Point */
+	TCO_CPT28,	/* Cougar Point */
+	TCO_CPT29,	/* Cougar Point */
+	TCO_CPT30,	/* Cougar Point */
+	TCO_CPT31,	/* Cougar Point */
 };
 
 static struct {
@@ -173,8 +202,37 @@ static struct {
 	{"3420", 2},
 	{"3450", 2},
 	{"EP80579", 2},
-	{"CPT Desktop", 2},
-	{"CPT Mobile", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
+	{"Cougar Point", 2},
 	{NULL, 0}
 };
 
@@ -259,8 +317,37 @@ static struct pci_device_id iTCO_wdt_pci
 	{ ITCO_PCI_DEVICE(0x3b14,				TCO_3420)},
 	{ ITCO_PCI_DEVICE(0x3b16,				TCO_3450)},
 	{ ITCO_PCI_DEVICE(0x5031,				TCO_EP80579)},
-	{ ITCO_PCI_DEVICE(0x1c42,				TCO_CPTD)},
-	{ ITCO_PCI_DEVICE(0x1c43,				TCO_CPTM)},
+	{ ITCO_PCI_DEVICE(0x1c41,				TCO_CPT1)},
+	{ ITCO_PCI_DEVICE(0x1c42,				TCO_CPT2)},
+	{ ITCO_PCI_DEVICE(0x1c43,				TCO_CPT3)},
+	{ ITCO_PCI_DEVICE(0x1c44,				TCO_CPT4)},
+	{ ITCO_PCI_DEVICE(0x1c45,				TCO_CPT5)},
+	{ ITCO_PCI_DEVICE(0x1c46,				TCO_CPT6)},
+	{ ITCO_PCI_DEVICE(0x1c47,				TCO_CPT7)},
+	{ ITCO_PCI_DEVICE(0x1c48,				TCO_CPT8)},
+	{ ITCO_PCI_DEVICE(0x1c49,				TCO_CPT9)},
+	{ ITCO_PCI_DEVICE(0x1c4a,				TCO_CPT10)},
+	{ ITCO_PCI_DEVICE(0x1c4b,				TCO_CPT11)},
+	{ ITCO_PCI_DEVICE(0x1c4c,				TCO_CPT12)},
+	{ ITCO_PCI_DEVICE(0x1c4d,				TCO_CPT13)},
+	{ ITCO_PCI_DEVICE(0x1c4e,				TCO_CPT14)},
+	{ ITCO_PCI_DEVICE(0x1c4f,				TCO_CPT15)},
+	{ ITCO_PCI_DEVICE(0x1c50,				TCO_CPT16)},
+	{ ITCO_PCI_DEVICE(0x1c51,				TCO_CPT17)},
+	{ ITCO_PCI_DEVICE(0x1c52,				TCO_CPT18)},
+	{ ITCO_PCI_DEVICE(0x1c53,				TCO_CPT19)},
+	{ ITCO_PCI_DEVICE(0x1c54,				TCO_CPT20)},
+	{ ITCO_PCI_DEVICE(0x1c55,				TCO_CPT21)},
+	{ ITCO_PCI_DEVICE(0x1c56,				TCO_CPT22)},
+	{ ITCO_PCI_DEVICE(0x1c57,				TCO_CPT23)},
+	{ ITCO_PCI_DEVICE(0x1c58,				TCO_CPT24)},
+	{ ITCO_PCI_DEVICE(0x1c59,				TCO_CPT25)},
+	{ ITCO_PCI_DEVICE(0x1c5a,				TCO_CPT26)},
+	{ ITCO_PCI_DEVICE(0x1c5b,				TCO_CPT27)},
+	{ ITCO_PCI_DEVICE(0x1c5c,				TCO_CPT28)},
+	{ ITCO_PCI_DEVICE(0x1c5d,				TCO_CPT29)},
+	{ ITCO_PCI_DEVICE(0x1c5e,				TCO_CPT30)},
+	{ ITCO_PCI_DEVICE(0x1c5f,				TCO_CPT31)},
 	{ 0, },			/* End of list */
 };
 MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
@@ -584,7 +671,7 @@ static long iTCO_wdt_ioctl(struct file *
 	int new_heartbeat;
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options =		WDIOF_SETTIMEOUT |
 					WDIOF_KEEPALIVEPING |
 					WDIOF_MAGICCLOSE,
@@ -698,7 +785,7 @@ static int __devinit iTCO_wdt_init(struc
 	if (iTCO_wdt_private.iTCO_version == 2) {
 		pci_read_config_dword(pdev, 0xf0, &base_address);
 		if ((base_address & 1) == 0) {
-			printk(KERN_ERR PFX "RCBA is disabled by harddware\n");
+			printk(KERN_ERR PFX "RCBA is disabled by hardware\n");
 			ret = -ENODEV;
 			goto out;
 		}
@@ -708,8 +795,8 @@ static int __devinit iTCO_wdt_init(struc
 
 	/* Check chipset's NO_REBOOT bit */
 	if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) {
-		printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, "
-					"reboot disabled by hardware\n");
+		printk(KERN_INFO PFX "unable to reset NO_REBOOT flag, "
+					"platform may have disabled it\n");
 		ret = -ENODEV;	/* Cannot reset NO_REBOOT bit */
 		goto out_unmap;
 	}
@@ -805,6 +892,7 @@ static void __devexit iTCO_wdt_cleanup(v
 
 static int __devinit iTCO_wdt_probe(struct platform_device *dev)
 {
+	int ret = -ENODEV;
 	int found = 0;
 	struct pci_dev *pdev = NULL;
 	const struct pci_device_id *ent;
@@ -814,19 +902,17 @@ static int __devinit iTCO_wdt_probe(stru
 	for_each_pci_dev(pdev) {
 		ent = pci_match_id(iTCO_wdt_pci_tbl, pdev);
 		if (ent) {
-			if (!(iTCO_wdt_init(pdev, ent, dev))) {
-				found++;
+			found++;
+			ret = iTCO_wdt_init(pdev, ent, dev);
+			if (!ret)
 				break;
-			}
 		}
 	}
 
-	if (!found) {
+	if (!found)
 		printk(KERN_INFO PFX "No card detected\n");
-		return -ENODEV;
-	}
 
-	return 0;
+	return ret;
 }
 
 static int __devexit iTCO_wdt_remove(struct platform_device *dev)
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/ixp2000_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/ixp2000_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/ixp2000_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/ixp2000_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -100,7 +100,7 @@ static ssize_t ixp2000_wdt_write(struct
 }
 
 
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
 	.options	= WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
 				WDIOF_KEEPALIVEPING,
 	.identity	= "IXP2000 Watchdog",
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/ixp4xx_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/ixp4xx_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/ixp4xx_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/ixp4xx_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -89,7 +89,7 @@ ixp4xx_wdt_write(struct file *file, cons
 	return len;
 }
 
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
 	.options	= WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
 			  WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
 	.identity	= "IXP4xx Watchdog",
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/Kconfig linux-libre-2.6.34-gnu1/drivers/watchdog/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/watchdog/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -175,7 +175,7 @@ config SA1100_WATCHDOG
 
 config MPCORE_WATCHDOG
 	tristate "MPcore watchdog"
-	depends on ARM_MPCORE_PLATFORM && LOCAL_TIMERS
+	depends on HAVE_ARM_TWD
 	help
 	  Watchdog timer embedded into the MPcore system.
 
@@ -194,10 +194,10 @@ config EP93XX_WATCHDOG
 
 config OMAP_WATCHDOG
 	tristate "OMAP Watchdog"
-	depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX
+	depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
 	help
-	  Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog.  Say 'Y'
-	  here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog timer.
+	  Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog.  Say 'Y'
+	  here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer.
 
 config PNX4008_WATCHDOG
 	tristate "PNX4008 Watchdog"
@@ -289,6 +289,23 @@ config ADX_WATCHDOG
 	  Say Y here if you want support for the watchdog timer on Avionic
 	  Design Xanthos boards.
 
+config TS72XX_WATCHDOG
+	tristate "TS-72XX SBC Watchdog"
+	depends on MACH_TS72XX
+	help
+	  Technologic Systems TS-7200, TS-7250 and TS-7260 boards have
+	  watchdog timer implemented in a external CPLD chip. Say Y here
+	  if you want to support for the watchdog timer on TS-72XX boards.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ts72xx_wdt.
+
+config MAX63XX_WATCHDOG
+	tristate "Max63xx watchdog"
+	depends on ARM && HAS_IOMEM
+	help
+	  Support for memory mapped max63{69,70,71,72,73,74} watchdog timer.
+
 # AVR32 Architecture
 
 config AT32AP700X_WDT
@@ -845,10 +862,10 @@ config TXX9_WDT
 # POWERPC Architecture
 
 config GEF_WDT
-	tristate "GE Fanuc Watchdog Timer"
+	tristate "GE Watchdog Timer"
 	depends on GEF_SBC610 || GEF_SBC310 || GEF_PPC9A
 	---help---
-	  Watchdog timer found in a number of GE Fanuc single board computers.
+	  Watchdog timer found in a number of GE single board computers.
 
 config MPC5200_WDT
 	bool "MPC52xx Watchdog Timer"
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/ks8695_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/ks8695_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/ks8695_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/ks8695_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -145,7 +145,7 @@ static int ks8695_wdt_close(struct inode
 	return 0;
 }
 
-static struct watchdog_info ks8695_wdt_info = {
+static const struct watchdog_info ks8695_wdt_info = {
 	.identity	= "ks8695 watchdog",
 	.options	= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/machzwd.c linux-libre-2.6.34-gnu1/drivers/watchdog/machzwd.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/machzwd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/machzwd.c	2010-05-16 17:17:36.000000000 -0400
@@ -101,7 +101,7 @@ MODULE_PARM_DESC(nowayout,
 
 #define PFX "machzwd"
 
-static struct watchdog_info zf_info = {
+static const struct watchdog_info zf_info = {
 	.options		= WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
 	.firmware_version	= 1,
 	.identity		= "ZF-Logic watchdog",
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/Makefile linux-libre-2.6.34-gnu1/drivers/watchdog/Makefile
--- linux-libre-2.6.33-gnu1/drivers/watchdog/Makefile	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -46,6 +46,7 @@ obj-$(CONFIG_COH901327_WATCHDOG) += coh9
 obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o
 obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
 obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o
+obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
 
 # AVR32 Architecture
 obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
@@ -142,4 +143,5 @@ obj-$(CONFIG_WATCHDOG_CP1XXX)		+= cpwd.o
 # Architecture Independant
 obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o
 obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o
+obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o
 obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/max63xx_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/max63xx_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/max63xx_wdt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/max63xx_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,403 @@
+/*
+ * drivers/char/watchdog/max63xx_wdt.c
+ *
+ * Driver for max63{69,70,71,72,73,74} watchdog timers
+ *
+ * Copyright (C) 2009 Marc Zyngier <maz@misterjones.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * This driver assumes the watchdog pins are memory mapped (as it is
+ * the case for the Arcom Zeus). Should it be connected over GPIOs or
+ * another interface, some abstraction will have to be introduced.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+
+#define DEFAULT_HEARTBEAT 60
+#define MAX_HEARTBEAT     60
+
+static int heartbeat = DEFAULT_HEARTBEAT;
+static int nowayout  = WATCHDOG_NOWAYOUT;
+
+/*
+ * Memory mapping: a single byte, 3 first lower bits to select bit 3
+ * to ping the watchdog.
+ */
+#define MAX6369_WDSET	(7 << 0)
+#define MAX6369_WDI   	(1 << 3)
+
+static DEFINE_SPINLOCK(io_lock);
+
+static unsigned long wdt_status;
+#define WDT_IN_USE	0
+#define WDT_RUNNING	1
+#define WDT_OK_TO_CLOSE 2
+
+static int nodelay;
+static struct resource	*wdt_mem;
+static void __iomem	*wdt_base;
+static struct platform_device *max63xx_pdev;
+
+/*
+ * The timeout values used are actually the absolute minimum the chip
+ * offers. Typical values on my board are slightly over twice as long
+ * (10s setting ends up with a 25s timeout), and can be up to 3 times
+ * the nominal setting (according to the datasheet). So please take
+ * these values with a grain of salt. Same goes for the initial delay
+ * "feature". Only max6373/74 have a few settings without this initial
+ * delay (selected with the "nodelay" parameter).
+ *
+ * I also decided to remove from the tables any timeout smaller than a
+ * second, as it looked completly overkill...
+ */
+
+/* Timeouts in second */
+struct max63xx_timeout {
+	u8 wdset;
+	u8 tdelay;
+	u8 twd;
+};
+
+static struct max63xx_timeout max6369_table[] = {
+	{ 5,  1,  1 },
+	{ 6, 10, 10 },
+	{ 7, 60, 60 },
+	{ },
+};
+
+static struct max63xx_timeout max6371_table[] = {
+	{ 6, 60,  3 },
+	{ 7, 60, 60 },
+	{ },
+};
+
+static struct max63xx_timeout max6373_table[] = {
+	{ 2, 60,  1 },
+	{ 5,  0,  1 },
+	{ 1,  3,  3 },
+	{ 7, 60, 10 },
+	{ 6,  0, 10 },
+	{ },
+};
+
+static struct max63xx_timeout *current_timeout;
+
+static struct max63xx_timeout *
+max63xx_select_timeout(struct max63xx_timeout *table, int value)
+{
+	while (table->twd) {
+		if (value <= table->twd) {
+			if (nodelay && table->tdelay == 0)
+				return table;
+
+			if (!nodelay)
+				return table;
+		}
+
+		table++;
+	}
+
+	return NULL;
+}
+
+static void max63xx_wdt_ping(void)
+{
+	u8 val;
+
+	spin_lock(&io_lock);
+
+	val = __raw_readb(wdt_base);
+
+	__raw_writeb(val | MAX6369_WDI, wdt_base);
+	__raw_writeb(val & ~MAX6369_WDI, wdt_base);
+
+	spin_unlock(&io_lock);
+}
+
+static void max63xx_wdt_enable(struct max63xx_timeout *entry)
+{
+	u8 val;
+
+	if (test_and_set_bit(WDT_RUNNING, &wdt_status))
+		return;
+
+	spin_lock(&io_lock);
+
+	val = __raw_readb(wdt_base);
+	val &= ~MAX6369_WDSET;
+	val |= entry->wdset;
+	__raw_writeb(val, wdt_base);
+
+	spin_unlock(&io_lock);
+
+	/* check for a edge triggered startup */
+	if (entry->tdelay == 0)
+		max63xx_wdt_ping();
+}
+
+static void max63xx_wdt_disable(void)
+{
+	u8 val;
+
+	spin_lock(&io_lock);
+
+	val = __raw_readb(wdt_base);
+	val &= ~MAX6369_WDSET;
+	val |= 3;
+	__raw_writeb(val, wdt_base);
+
+	spin_unlock(&io_lock);
+
+	clear_bit(WDT_RUNNING, &wdt_status);
+}
+
+static int max63xx_wdt_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(WDT_IN_USE, &wdt_status))
+		return -EBUSY;
+
+	max63xx_wdt_enable(current_timeout);
+	clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+	return nonseekable_open(inode, file);
+}
+
+static ssize_t max63xx_wdt_write(struct file *file, const char *data,
+				 size_t len, loff_t *ppos)
+{
+	if (len) {
+		if (!nowayout) {
+			size_t i;
+
+			clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+			for (i = 0; i != len; i++) {
+				char c;
+
+				if (get_user(c, data + i))
+					return -EFAULT;
+
+				if (c == 'V')
+					set_bit(WDT_OK_TO_CLOSE, &wdt_status);
+			}
+		}
+
+		max63xx_wdt_ping();
+	}
+
+	return len;
+}
+
+static const struct watchdog_info ident = {
+	.options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
+	.identity = "max63xx Watchdog",
+};
+
+static long max63xx_wdt_ioctl(struct file *file, unsigned int cmd,
+			      unsigned long arg)
+{
+	int ret = -ENOTTY;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		ret = copy_to_user((struct watchdog_info *)arg, &ident,
+				   sizeof(ident)) ? -EFAULT : 0;
+		break;
+
+	case WDIOC_GETSTATUS:
+	case WDIOC_GETBOOTSTATUS:
+		ret = put_user(0, (int *)arg);
+		break;
+
+	case WDIOC_KEEPALIVE:
+		max63xx_wdt_ping();
+		ret = 0;
+		break;
+
+	case WDIOC_GETTIMEOUT:
+		ret = put_user(heartbeat, (int *)arg);
+		break;
+	}
+	return ret;
+}
+
+static int max63xx_wdt_release(struct inode *inode, struct file *file)
+{
+	if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
+		max63xx_wdt_disable();
+	else
+		dev_crit(&max63xx_pdev->dev,
+			 "device closed unexpectedly - timer will not stop\n");
+
+	clear_bit(WDT_IN_USE, &wdt_status);
+	clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+	return 0;
+}
+
+static const struct file_operations max63xx_wdt_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.write		= max63xx_wdt_write,
+	.unlocked_ioctl	= max63xx_wdt_ioctl,
+	.open		= max63xx_wdt_open,
+	.release	= max63xx_wdt_release,
+};
+
+static struct miscdevice max63xx_wdt_miscdev = {
+	.minor	= WATCHDOG_MINOR,
+	.name	= "watchdog",
+	.fops	= &max63xx_wdt_fops,
+};
+
+static int __devinit max63xx_wdt_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	int size;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+	struct max63xx_timeout *table;
+
+	table = (struct max63xx_timeout *)pdev->id_entry->driver_data;
+
+	if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
+		heartbeat = DEFAULT_HEARTBEAT;
+
+	dev_info(dev, "requesting %ds heartbeat\n", heartbeat);
+	current_timeout = max63xx_select_timeout(table, heartbeat);
+
+	if (!current_timeout) {
+		dev_err(dev, "unable to satisfy heartbeat request\n");
+		return -EINVAL;
+	}
+
+	dev_info(dev, "using %ds heartbeat with %ds initial delay\n",
+		 current_timeout->twd, current_timeout->tdelay);
+
+	heartbeat = current_timeout->twd;
+
+	max63xx_pdev = pdev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(dev, "failed to get memory region resource\n");
+		return -ENOENT;
+	}
+
+	size = resource_size(res);
+	wdt_mem = request_mem_region(res->start, size, pdev->name);
+
+	if (wdt_mem == NULL) {
+		dev_err(dev, "failed to get memory region\n");
+		return -ENOENT;
+	}
+
+	wdt_base = ioremap(res->start, size);
+	if (!wdt_base) {
+		dev_err(dev, "failed to map memory region\n");
+		ret = -ENOMEM;
+		goto out_request;
+	}
+
+	ret = misc_register(&max63xx_wdt_miscdev);
+	if (ret < 0) {
+		dev_err(dev, "cannot register misc device\n");
+		goto out_unmap;
+	}
+
+	return 0;
+
+out_unmap:
+	iounmap(wdt_base);
+out_request:
+	release_resource(wdt_mem);
+	kfree(wdt_mem);
+
+	return ret;
+}
+
+static int __devexit max63xx_wdt_remove(struct platform_device *pdev)
+{
+	misc_deregister(&max63xx_wdt_miscdev);
+	if (wdt_mem) {
+		release_resource(wdt_mem);
+		kfree(wdt_mem);
+		wdt_mem = NULL;
+	}
+
+	if (wdt_base)
+		iounmap(wdt_base);
+
+	return 0;
+}
+
+static struct platform_device_id max63xx_id_table[] = {
+	{ "max6369_wdt", (kernel_ulong_t)max6369_table, },
+	{ "max6370_wdt", (kernel_ulong_t)max6369_table, },
+	{ "max6371_wdt", (kernel_ulong_t)max6371_table, },
+	{ "max6372_wdt", (kernel_ulong_t)max6371_table, },
+	{ "max6373_wdt", (kernel_ulong_t)max6373_table, },
+	{ "max6374_wdt", (kernel_ulong_t)max6373_table, },
+	{ },
+};
+MODULE_DEVICE_TABLE(platform, max63xx_id_table);
+
+static struct platform_driver max63xx_wdt_driver = {
+	.probe		= max63xx_wdt_probe,
+	.remove		= __devexit_p(max63xx_wdt_remove),
+	.id_table	= max63xx_id_table,
+	.driver		= {
+		.name	= "max63xx_wdt",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init max63xx_wdt_init(void)
+{
+	return platform_driver_register(&max63xx_wdt_driver);
+}
+
+static void __exit max63xx_wdt_exit(void)
+{
+	platform_driver_unregister(&max63xx_wdt_driver);
+}
+
+module_init(max63xx_wdt_init);
+module_exit(max63xx_wdt_exit);
+
+MODULE_AUTHOR("Marc Zyngier <maz@misterjones.org>");
+MODULE_DESCRIPTION("max63xx Watchdog Driver");
+
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat,
+		 "Watchdog heartbeat period in seconds from 1 to "
+		 __MODULE_STRING(MAX_HEARTBEAT) ", default "
+		 __MODULE_STRING(DEFAULT_HEARTBEAT));
+
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+		 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+module_param(nodelay, int, 0);
+MODULE_PARM_DESC(nodelay,
+		 "Force selection of a timeout setting without initial delay "
+		 "(max6373/74 only, default=0)");
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/mixcomwd.c linux-libre-2.6.34-gnu1/drivers/watchdog/mixcomwd.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/mixcomwd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/mixcomwd.c	2010-05-16 17:17:36.000000000 -0400
@@ -201,7 +201,7 @@ static long mixcomwd_ioctl(struct file *
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
 	int status;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
 		.firmware_version = 1,
 		.identity = "MixCOM watchdog",
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/mpc8xxx_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/mpc8xxx_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/mpc8xxx_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/mpc8xxx_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -148,7 +148,7 @@ static long mpc8xxx_wdt_ioctl(struct fil
 {
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options = WDIOF_KEEPALIVEPING,
 		.firmware_version = 1,
 		.identity = "MPC8xxx",
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/mpcore_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/mpcore_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/mpcore_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/mpcore_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,8 +30,10 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <linux/io.h>
 
-#include <asm/hardware/arm_twd.h>
+#include <asm/smp_twd.h>
 
 struct mpcore_wdt {
 	unsigned long	timer_alive;
@@ -43,7 +45,7 @@ struct mpcore_wdt {
 };
 
 static struct platform_device *mpcore_wdt_dev;
-extern unsigned int mpcore_timer_rate;
+static DEFINE_SPINLOCK(wdt_lock);
 
 #define TIMER_MARGIN	60
 static int mpcore_margin = TIMER_MARGIN;
@@ -93,13 +95,15 @@ static irqreturn_t mpcore_wdt_fire(int i
  */
 static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt)
 {
-	unsigned int count;
+	unsigned long count;
 
+	spin_lock(&wdt_lock);
 	/* Assume prescale is set to 256 */
-	count = (mpcore_timer_rate / 256) * mpcore_margin;
+	count =  __raw_readl(wdt->base + TWD_WDOG_COUNTER);
+	count = (0xFFFFFFFFU - count) * (HZ / 5);
+	count = (count / 256) * mpcore_margin;
 
 	/* Reload the counter */
-	spin_lock(&wdt_lock);
 	writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
 	wdt->perturb = wdt->perturb ? 0 : 1;
 	spin_unlock(&wdt_lock);
@@ -118,7 +122,6 @@ static void mpcore_wdt_start(struct mpco
 {
 	dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n");
 
-	spin_lock(&wdt_lock);
 	/* This loads the count register but does NOT start the count yet */
 	mpcore_wdt_keepalive(wdt);
 
@@ -129,7 +132,6 @@ static void mpcore_wdt_start(struct mpco
 		/* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */
 		writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
 	}
-	spin_unlock(&wdt_lock);
 }
 
 static int mpcore_wdt_set_heartbeat(int t)
@@ -213,7 +215,7 @@ static ssize_t mpcore_wdt_write(struct f
 	return len;
 }
 
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
 	.options		= WDIOF_SETTIMEOUT |
 				  WDIOF_KEEPALIVEPING |
 				  WDIOF_MAGICCLOSE,
@@ -359,7 +361,7 @@ static int __devinit mpcore_wdt_probe(st
 	mpcore_wdt_miscdev.parent = &dev->dev;
 	ret = misc_register(&mpcore_wdt_miscdev);
 	if (ret) {
-		dev_printk(KERN_ERR, _dev,
+		dev_printk(KERN_ERR, wdt->dev,
 			"cannot register miscdev on minor=%d (err=%d)\n",
 							WATCHDOG_MINOR, ret);
 		goto err_misc;
@@ -368,13 +370,13 @@ static int __devinit mpcore_wdt_probe(st
 	ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED,
 							"mpcore_wdt", wdt);
 	if (ret) {
-		dev_printk(KERN_ERR, _dev,
+		dev_printk(KERN_ERR, wdt->dev,
 			"cannot register IRQ%d for watchdog\n", wdt->irq);
 		goto err_irq;
 	}
 
 	mpcore_wdt_stop(wdt);
-	platform_set_drvdata(&dev->dev, wdt);
+	platform_set_drvdata(dev, wdt);
 	mpcore_wdt_dev = dev;
 
 	return 0;
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/mv64x60_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/mv64x60_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/mv64x60_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/mv64x60_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -179,7 +179,7 @@ static long mv64x60_wdt_ioctl(struct fil
 	int timeout;
 	int options;
 	void __user *argp = (void __user *)arg;
-	static struct watchdog_info info = {
+	static const struct watchdog_info info = {
 		.options =	WDIOF_SETTIMEOUT	|
 				WDIOF_MAGICCLOSE	|
 				WDIOF_KEEPALIVEPING,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/nuc900_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/nuc900_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/nuc900_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/nuc900_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/types.h>
 #include <linux/watchdog.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/omap_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/omap_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/omap_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/omap_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/bitops.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <mach/hardware.h>
 #include <plat/prcm.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/pc87413_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/pc87413_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/pc87413_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/pc87413_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -407,7 +407,7 @@ static long pc87413_ioctl(struct file *f
 		int __user *i;
 	} uarg;
 
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options          = WDIOF_KEEPALIVEPING |
 				    WDIOF_SETTIMEOUT |
 				    WDIOF_MAGICCLOSE,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/pcwd.c linux-libre-2.6.34-gnu1/drivers/watchdog/pcwd.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/pcwd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/pcwd.c	2010-05-16 17:17:36.000000000 -0400
@@ -606,7 +606,7 @@ static long pcwd_ioctl(struct file *file
 	int temperature;
 	int new_heartbeat;
 	int __user *argp = (int __user *)arg;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options =		WDIOF_OVERHEAT |
 					WDIOF_CARDRESET |
 					WDIOF_KEEPALIVEPING |
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/pcwd_pci.c linux-libre-2.6.34-gnu1/drivers/watchdog/pcwd_pci.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/pcwd_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/pcwd_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -481,7 +481,7 @@ static long pcipcwd_ioctl(struct file *f
 {
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options =		WDIOF_OVERHEAT |
 					WDIOF_CARDRESET |
 					WDIOF_KEEPALIVEPING |
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/pcwd_usb.c linux-libre-2.6.34-gnu1/drivers/watchdog/pcwd_usb.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/pcwd_usb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/pcwd_usb.c	2010-05-16 17:17:36.000000000 -0400
@@ -404,7 +404,7 @@ static long usb_pcwd_ioctl(struct file *
 {
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options =		WDIOF_KEEPALIVEPING |
 					WDIOF_SETTIMEOUT |
 					WDIOF_MAGICCLOSE,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/pnx4008_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/pnx4008_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/pnx4008_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/pnx4008_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <mach/hardware.h>
 
 #define MODULE_NAME "PNX4008-WDT: "
@@ -96,9 +97,6 @@ static void wdt_enable(void)
 {
 	spin_lock(&io_lock);
 
-	if (wdt_clk)
-		clk_set_rate(wdt_clk, 1);
-
 	/* stop counter, initiate counter reset */
 	__raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base));
 	/*wait for reset to complete. 100% guarantee event */
@@ -125,19 +123,25 @@ static void wdt_disable(void)
 	spin_lock(&io_lock);
 
 	__raw_writel(0, WDTIM_CTRL(wdt_base));	/*stop counter */
-	if (wdt_clk)
-		clk_set_rate(wdt_clk, 0);
 
 	spin_unlock(&io_lock);
 }
 
 static int pnx4008_wdt_open(struct inode *inode, struct file *file)
 {
+	int ret;
+
 	if (test_and_set_bit(WDT_IN_USE, &wdt_status))
 		return -EBUSY;
 
 	clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
 
+	ret = clk_enable(wdt_clk);
+	if (ret) {
+		clear_bit(WDT_IN_USE, &wdt_status);
+		return ret;
+	}
+
 	wdt_enable();
 
 	return nonseekable_open(inode, file);
@@ -225,6 +229,7 @@ static int pnx4008_wdt_release(struct in
 		printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n");
 
 	wdt_disable();
+	clk_disable(wdt_clk);
 	clear_bit(WDT_IN_USE, &wdt_status);
 	clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
 
@@ -273,25 +278,33 @@ static int __devinit pnx4008_wdt_probe(s
 	}
 	wdt_base = (void __iomem *)IO_ADDRESS(res->start);
 
-	wdt_clk = clk_get(&pdev->dev, "wdt_ck");
+	wdt_clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(wdt_clk)) {
 		ret = PTR_ERR(wdt_clk);
 		release_resource(wdt_mem);
 		kfree(wdt_mem);
 		goto out;
-	} else
-		clk_set_rate(wdt_clk, 1);
+	}
+
+	ret = clk_enable(wdt_clk);
+	if (ret) {
+		release_resource(wdt_mem);
+		kfree(wdt_mem);
+		goto out;
+	}
 
 	ret = misc_register(&pnx4008_wdt_miscdev);
 	if (ret < 0) {
 		printk(KERN_ERR MODULE_NAME "cannot register misc device\n");
 		release_resource(wdt_mem);
 		kfree(wdt_mem);
-		clk_set_rate(wdt_clk, 0);
+		clk_disable(wdt_clk);
+		clk_put(wdt_clk);
 	} else {
 		boot_status = (__raw_readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
 		    WDIOF_CARDRESET : 0;
 		wdt_disable();		/*disable for now */
+		clk_disable(wdt_clk);
 		set_bit(WDT_DEVICE_INITED, &wdt_status);
 	}
 
@@ -302,11 +315,10 @@ out:
 static int __devexit pnx4008_wdt_remove(struct platform_device *pdev)
 {
 	misc_deregister(&pnx4008_wdt_miscdev);
-	if (wdt_clk) {
-		clk_set_rate(wdt_clk, 0);
-		clk_put(wdt_clk);
-		wdt_clk = NULL;
-	}
+
+	clk_disable(wdt_clk);
+	clk_put(wdt_clk);
+
 	if (wdt_mem) {
 		release_resource(wdt_mem);
 		kfree(wdt_mem);
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/pnx833x_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/pnx833x_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/pnx833x_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/pnx833x_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -141,7 +141,7 @@ static long pnx833x_wdt_ioctl(struct fil
 	int options, new_timeout = 0;
 	uint32_t timeout, timeout_left = 0;
 
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
 		.firmware_version = 0,
 		.identity = "Hardware Watchdog for PNX833x",
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/rc32434_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/rc32434_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/rc32434_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/rc32434_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -198,7 +198,7 @@ static long rc32434_wdt_ioctl(struct fil
 	void __user *argp = (void __user *)arg;
 	int new_timeout;
 	unsigned int value;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options =		WDIOF_SETTIMEOUT |
 					WDIOF_KEEPALIVEPING |
 					WDIOF_MAGICCLOSE,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/rdc321x_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/rdc321x_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/rdc321x_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/rdc321x_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -149,7 +149,7 @@ static long rdc321x_wdt_ioctl(struct fil
 {
 	void __user *argp = (void __user *)arg;
 	unsigned int value;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options = WDIOF_CARDRESET,
 		.identity = "RDC321x WDT",
 	};
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/riowd.c linux-libre-2.6.34-gnu1/drivers/watchdog/riowd.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/riowd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/riowd.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/of_device.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 
 
 /* RIO uses the NatSemi Super I/O power management logical device
@@ -85,7 +86,7 @@ static int riowd_release(struct inode *i
 
 static long riowd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
-	static struct watchdog_info info = {
+	static const struct watchdog_info info = {
 		.options		= WDIOF_SETTIMEOUT,
 		.firmware_version	= 1,
 		.identity		= DRIVER_NAME,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/s3c2410_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/s3c2410_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/s3c2410_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/s3c2410_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/cpufreq.h>
+#include <linux/slab.h>
 
 #include <mach/map.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/sbc_fitpc2_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/sbc_fitpc2_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/sbc_fitpc2_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/sbc_fitpc2_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,7 +30,7 @@
 static int nowayout = WATCHDOG_NOWAYOUT;
 static unsigned int margin = 60;	/* (secs) Default is 1 minute */
 static unsigned long wdt_status;
-static DEFINE_SPINLOCK(wdt_lock);
+static DEFINE_MUTEX(wdt_lock);
 
 #define WDT_IN_USE		0
 #define WDT_OK_TO_CLOSE		1
@@ -45,26 +45,26 @@ static DEFINE_SPINLOCK(wdt_lock);
 
 static void wdt_send_data(unsigned char command, unsigned char data)
 {
-	outb(command, COMMAND_PORT);
-	msleep(100);
 	outb(data, DATA_PORT);
 	msleep(200);
+	outb(command, COMMAND_PORT);
+	msleep(100);
 }
 
 static void wdt_enable(void)
 {
-	spin_lock(&wdt_lock);
+	mutex_lock(&wdt_lock);
 	wdt_send_data(IFACE_ON_COMMAND, 1);
 	wdt_send_data(REBOOT_COMMAND, margin);
-	spin_unlock(&wdt_lock);
+	mutex_unlock(&wdt_lock);
 }
 
 static void wdt_disable(void)
 {
-	spin_lock(&wdt_lock);
+	mutex_lock(&wdt_lock);
 	wdt_send_data(IFACE_ON_COMMAND, 0);
 	wdt_send_data(REBOOT_COMMAND, 0);
-	spin_unlock(&wdt_lock);
+	mutex_unlock(&wdt_lock);
 }
 
 static int fitpc2_wdt_open(struct inode *inode, struct file *file)
@@ -111,7 +111,7 @@ out:
 }
 
 
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
 	.options	= WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
 				WDIOF_KEEPALIVEPING,
 	.identity	= WATCHDOG_NAME,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/sb_wdog.c linux-libre-2.6.34-gnu1/drivers/watchdog/sb_wdog.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/sb_wdog.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/sb_wdog.c	2010-05-16 17:17:36.000000000 -0400
@@ -67,8 +67,8 @@ static DEFINE_SPINLOCK(sbwd_lock);
 void sbwdog_set(char __iomem *wdog, unsigned long t)
 {
 	spin_lock(&sbwd_lock);
-	__raw_writeb(0, wdog - 0x10);
-	__raw_writeq(t & 0x7fffffUL, wdog);
+	__raw_writeb(0, wdog);
+	__raw_writeq(t & 0x7fffffUL, wdog - 0x10);
 	spin_unlock(&sbwd_lock);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/sch311x_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/sch311x_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/sch311x_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/sch311x_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -250,7 +250,7 @@ static long sch311x_wdt_ioctl(struct fil
 	int new_timeout;
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options		= WDIOF_KEEPALIVEPING |
 					  WDIOF_SETTIMEOUT |
 					  WDIOF_MAGICCLOSE,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/stmp3xxx_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/stmp3xxx_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/stmp3xxx_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/stmp3xxx_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -94,7 +94,7 @@ static ssize_t stmp3xxx_wdt_write(struct
 	return len;
 }
 
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
 	.options	= WDIOF_CARDRESET |
 			  WDIOF_MAGICCLOSE |
 			  WDIOF_SETTIMEOUT |
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/ts72xx_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/ts72xx_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/ts72xx_wdt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/ts72xx_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,521 @@
+/*
+ * Watchdog driver for Technologic Systems TS-72xx based SBCs
+ * (TS-7200, TS-7250 and TS-7260). These boards have external
+ * glue logic CPLD chip, which includes programmable watchdog
+ * timer.
+ *
+ * Copyright (c) 2009 Mika Westerberg <mika.westerberg@iki.fi>
+ *
+ * This driver is based on ep93xx_wdt and wm831x_wdt drivers.
+ *
+ * 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/fs.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/miscdevice.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/watchdog.h>
+#include <linux/uaccess.h>
+
+#define TS72XX_WDT_FEED_VAL		0x05
+#define TS72XX_WDT_DEFAULT_TIMEOUT	8
+
+static int timeout = TS72XX_WDT_DEFAULT_TIMEOUT;
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. "
+			  "(1 <= timeout <= 8, default="
+			  __MODULE_STRING(TS72XX_WDT_DEFAULT_TIMEOUT)
+			  ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
+
+/**
+ * struct ts72xx_wdt - watchdog control structure
+ * @lock: lock that protects this structure
+ * @regval: watchdog timeout value suitable for control register
+ * @flags: flags controlling watchdog device state
+ * @control_reg: watchdog control register
+ * @feed_reg: watchdog feed register
+ * @pdev: back pointer to platform dev
+ */
+struct ts72xx_wdt {
+	struct mutex	lock;
+	int		regval;
+
+#define TS72XX_WDT_BUSY_FLAG		1
+#define TS72XX_WDT_EXPECT_CLOSE_FLAG	2
+	int		flags;
+
+	void __iomem	*control_reg;
+	void __iomem	*feed_reg;
+
+	struct platform_device *pdev;
+};
+
+struct platform_device *ts72xx_wdt_pdev;
+
+/*
+ * TS-72xx Watchdog supports following timeouts (value written
+ * to control register):
+ *	value	description
+ *	-------------------------
+ * 	0x00	watchdog disabled
+ *	0x01	250ms
+ *	0x02	500ms
+ *	0x03	1s
+ *	0x04	reserved
+ *	0x05	2s
+ *	0x06	4s
+ *	0x07	8s
+ *
+ * Timeouts below 1s are not very usable so we don't
+ * allow them at all.
+ *
+ * We provide two functions that convert between these:
+ * timeout_to_regval() and regval_to_timeout().
+ */
+static const struct {
+	int	timeout;
+	int	regval;
+} ts72xx_wdt_map[] = {
+	{ 1, 3 },
+	{ 2, 5 },
+	{ 4, 6 },
+	{ 8, 7 },
+};
+
+/**
+ * timeout_to_regval() - converts given timeout to control register value
+ * @new_timeout: timeout in seconds to be converted
+ *
+ * Function converts given @new_timeout into valid value that can
+ * be programmed into watchdog control register. When conversion is
+ * not possible, function returns %-EINVAL.
+ */
+static int timeout_to_regval(int new_timeout)
+{
+	int i;
+
+	/* first limit it to 1 - 8 seconds */
+	new_timeout = clamp_val(new_timeout, 1, 8);
+
+	for (i = 0; i < ARRAY_SIZE(ts72xx_wdt_map); i++) {
+		if (ts72xx_wdt_map[i].timeout >= new_timeout)
+			return ts72xx_wdt_map[i].regval;
+	}
+
+	return -EINVAL;
+}
+
+/**
+ * regval_to_timeout() - converts control register value to timeout
+ * @regval: control register value to be converted
+ *
+ * Function converts given @regval to timeout in seconds (1, 2, 4 or 8).
+ * If @regval cannot be converted, function returns %-EINVAL.
+ */
+static int regval_to_timeout(int regval)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ts72xx_wdt_map); i++) {
+		if (ts72xx_wdt_map[i].regval == regval)
+			return ts72xx_wdt_map[i].timeout;
+	}
+
+	return -EINVAL;
+}
+
+/**
+ * ts72xx_wdt_kick() - kick the watchdog
+ * @wdt: watchdog to be kicked
+ *
+ * Called with @wdt->lock held.
+ */
+static inline void ts72xx_wdt_kick(struct ts72xx_wdt *wdt)
+{
+	__raw_writeb(TS72XX_WDT_FEED_VAL, wdt->feed_reg);
+}
+
+/**
+ * ts72xx_wdt_start() - starts the watchdog timer
+ * @wdt: watchdog to be started
+ *
+ * This function programs timeout to watchdog timer
+ * and starts it.
+ *
+ * Called with @wdt->lock held.
+ */
+static void ts72xx_wdt_start(struct ts72xx_wdt *wdt)
+{
+	/*
+	 * To program the wdt, it first must be "fed" and
+	 * only after that (within 30 usecs) the configuration
+	 * can be changed.
+	 */
+	ts72xx_wdt_kick(wdt);
+	__raw_writeb((u8)wdt->regval, wdt->control_reg);
+}
+
+/**
+ * ts72xx_wdt_stop() - stops the watchdog timer
+ * @wdt: watchdog to be stopped
+ *
+ * Called with @wdt->lock held.
+ */
+static void ts72xx_wdt_stop(struct ts72xx_wdt *wdt)
+{
+	ts72xx_wdt_kick(wdt);
+	__raw_writeb(0, wdt->control_reg);
+}
+
+static int ts72xx_wdt_open(struct inode *inode, struct file *file)
+{
+	struct ts72xx_wdt *wdt = platform_get_drvdata(ts72xx_wdt_pdev);
+	int regval;
+
+	/*
+	 * Try to convert default timeout to valid register
+	 * value first.
+	 */
+	regval = timeout_to_regval(timeout);
+	if (regval < 0) {
+		dev_err(&wdt->pdev->dev,
+			"failed to convert timeout (%d) to register value\n",
+			timeout);
+		return -EINVAL;
+	}
+
+	if (mutex_lock_interruptible(&wdt->lock))
+		return -ERESTARTSYS;
+
+	if ((wdt->flags & TS72XX_WDT_BUSY_FLAG) != 0) {
+		mutex_unlock(&wdt->lock);
+		return -EBUSY;
+	}
+
+	wdt->flags = TS72XX_WDT_BUSY_FLAG;
+	wdt->regval = regval;
+	file->private_data = wdt;
+
+	ts72xx_wdt_start(wdt);
+
+	mutex_unlock(&wdt->lock);
+	return nonseekable_open(inode, file);
+}
+
+static int ts72xx_wdt_release(struct inode *inode, struct file *file)
+{
+	struct ts72xx_wdt *wdt = file->private_data;
+
+	if (mutex_lock_interruptible(&wdt->lock))
+		return -ERESTARTSYS;
+
+	if ((wdt->flags & TS72XX_WDT_EXPECT_CLOSE_FLAG) != 0) {
+		ts72xx_wdt_stop(wdt);
+	} else {
+		dev_warn(&wdt->pdev->dev,
+			 "TS-72XX WDT device closed unexpectly. "
+			 "Watchdog timer will not stop!\n");
+		/*
+		 * Kick it one more time, to give userland some time
+		 * to recover (for example, respawning the kicker
+		 * daemon).
+		 */
+		ts72xx_wdt_kick(wdt);
+	}
+
+	wdt->flags = 0;
+
+	mutex_unlock(&wdt->lock);
+	return 0;
+}
+
+static ssize_t ts72xx_wdt_write(struct file *file,
+				const char __user *data,
+				size_t len,
+				loff_t *ppos)
+{
+	struct ts72xx_wdt *wdt = file->private_data;
+
+	if (!len)
+		return 0;
+
+	if (mutex_lock_interruptible(&wdt->lock))
+		return -ERESTARTSYS;
+
+	ts72xx_wdt_kick(wdt);
+
+	/*
+	 * Support for magic character closing. User process
+	 * writes 'V' into the device, just before it is closed.
+	 * This means that we know that the wdt timer can be
+	 * stopped after user closes the device.
+	 */
+	if (!nowayout) {
+		int i;
+
+		for (i = 0; i < len; i++) {
+			char c;
+
+			/* In case it was set long ago */
+			wdt->flags &= ~TS72XX_WDT_EXPECT_CLOSE_FLAG;
+
+			if (get_user(c, data + i)) {
+				mutex_unlock(&wdt->lock);
+				return -EFAULT;
+			}
+			if (c == 'V') {
+				wdt->flags |= TS72XX_WDT_EXPECT_CLOSE_FLAG;
+				break;
+			}
+		}
+	}
+
+	mutex_unlock(&wdt->lock);
+	return len;
+}
+
+static const struct watchdog_info winfo = {
+	.options		= WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
+				  WDIOF_MAGICCLOSE,
+	.firmware_version	= 1,
+	.identity		= "TS-72XX WDT",
+};
+
+static long ts72xx_wdt_ioctl(struct file *file, unsigned int cmd,
+			     unsigned long arg)
+{
+	struct ts72xx_wdt *wdt = file->private_data;
+	void __user *argp = (void __user *)arg;
+	int __user *p = (int __user *)argp;
+	int error = 0;
+
+	if (mutex_lock_interruptible(&wdt->lock))
+		return -ERESTARTSYS;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		error = copy_to_user(argp, &winfo, sizeof(winfo));
+		break;
+
+	case WDIOC_GETSTATUS:
+	case WDIOC_GETBOOTSTATUS:
+		return put_user(0, p);
+
+	case WDIOC_KEEPALIVE:
+		ts72xx_wdt_kick(wdt);
+		break;
+
+	case WDIOC_SETOPTIONS: {
+		int options;
+
+		if (get_user(options, p)) {
+			error = -EFAULT;
+			break;
+		}
+
+		error = -EINVAL;
+
+		if ((options & WDIOS_DISABLECARD) != 0) {
+			ts72xx_wdt_stop(wdt);
+			error = 0;
+		}
+		if ((options & WDIOS_ENABLECARD) != 0) {
+			ts72xx_wdt_start(wdt);
+			error = 0;
+		}
+
+		break;
+	}
+
+	case WDIOC_SETTIMEOUT: {
+		int new_timeout;
+
+		if (get_user(new_timeout, p)) {
+			error = -EFAULT;
+		} else {
+			int regval;
+
+			regval = timeout_to_regval(new_timeout);
+			if (regval < 0) {
+				error = -EINVAL;
+			} else {
+				ts72xx_wdt_stop(wdt);
+				wdt->regval = regval;
+				ts72xx_wdt_start(wdt);
+			}
+		}
+		if (error)
+			break;
+
+		/*FALLTHROUGH*/
+	}
+
+	case WDIOC_GETTIMEOUT:
+		if (put_user(regval_to_timeout(wdt->regval), p))
+			error = -EFAULT;
+		break;
+
+	default:
+		error = -ENOTTY;
+		break;
+	}
+
+	mutex_unlock(&wdt->lock);
+	return error;
+}
+
+static const struct file_operations ts72xx_wdt_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.open		= ts72xx_wdt_open,
+	.release	= ts72xx_wdt_release,
+	.write		= ts72xx_wdt_write,
+	.unlocked_ioctl	= ts72xx_wdt_ioctl,
+};
+
+static struct miscdevice ts72xx_wdt_miscdev = {
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &ts72xx_wdt_fops,
+};
+
+static __devinit int ts72xx_wdt_probe(struct platform_device *pdev)
+{
+	struct ts72xx_wdt *wdt;
+	struct resource *r1, *r2;
+	int error = 0;
+
+	wdt = kzalloc(sizeof(struct ts72xx_wdt), GFP_KERNEL);
+	if (!wdt) {
+		dev_err(&pdev->dev, "failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r1) {
+		dev_err(&pdev->dev, "failed to get memory resource\n");
+		error = -ENODEV;
+		goto fail;
+	}
+
+	r1 = request_mem_region(r1->start, resource_size(r1), pdev->name);
+	if (!r1) {
+		dev_err(&pdev->dev, "cannot request memory region\n");
+		error = -EBUSY;
+		goto fail;
+	}
+
+	wdt->control_reg = ioremap(r1->start, resource_size(r1));
+	if (!wdt->control_reg) {
+		dev_err(&pdev->dev, "failed to map memory\n");
+		error = -ENODEV;
+		goto fail_free_control;
+	}
+
+	r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!r2) {
+		dev_err(&pdev->dev, "failed to get memory resource\n");
+		error = -ENODEV;
+		goto fail_unmap_control;
+	}
+
+	r2 = request_mem_region(r2->start, resource_size(r2), pdev->name);
+	if (!r2) {
+		dev_err(&pdev->dev, "cannot request memory region\n");
+		error = -EBUSY;
+		goto fail_unmap_control;
+	}
+
+	wdt->feed_reg = ioremap(r2->start, resource_size(r2));
+	if (!wdt->feed_reg) {
+		dev_err(&pdev->dev, "failed to map memory\n");
+		error = -ENODEV;
+		goto fail_free_feed;
+	}
+
+	platform_set_drvdata(pdev, wdt);
+	ts72xx_wdt_pdev = pdev;
+	wdt->pdev = pdev;
+	mutex_init(&wdt->lock);
+
+	error = misc_register(&ts72xx_wdt_miscdev);
+	if (error) {
+		dev_err(&pdev->dev, "failed to register miscdev\n");
+		goto fail_unmap_feed;
+	}
+
+	dev_info(&pdev->dev, "TS-72xx Watchdog driver\n");
+
+	return 0;
+
+fail_unmap_feed:
+	platform_set_drvdata(pdev, NULL);
+	iounmap(wdt->feed_reg);
+fail_free_feed:
+	release_mem_region(r2->start, resource_size(r2));
+fail_unmap_control:
+	iounmap(wdt->control_reg);
+fail_free_control:
+	release_mem_region(r1->start, resource_size(r1));
+fail:
+	kfree(wdt);
+	return error;
+}
+
+static __devexit int ts72xx_wdt_remove(struct platform_device *pdev)
+{
+	struct ts72xx_wdt *wdt = platform_get_drvdata(pdev);
+	struct resource *res;
+	int error;
+
+	error = misc_deregister(&ts72xx_wdt_miscdev);
+	platform_set_drvdata(pdev, NULL);
+
+	iounmap(wdt->feed_reg);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	release_mem_region(res->start, resource_size(res));
+
+	iounmap(wdt->control_reg);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, resource_size(res));
+
+	kfree(wdt);
+	return error;
+}
+
+static struct platform_driver ts72xx_wdt_driver = {
+	.probe		= ts72xx_wdt_probe,
+	.remove		= __devexit_p(ts72xx_wdt_remove),
+	.driver		= {
+		.name	= "ts72xx-wdt",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static __init int ts72xx_wdt_init(void)
+{
+	return platform_driver_register(&ts72xx_wdt_driver);
+}
+module_init(ts72xx_wdt_init);
+
+static __exit void ts72xx_wdt_exit(void)
+{
+	platform_driver_unregister(&ts72xx_wdt_driver);
+}
+module_exit(ts72xx_wdt_exit);
+
+MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
+MODULE_DESCRIPTION("TS-72xx SBC Watchdog");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ts72xx-wdt");
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/twl4030_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/twl4030_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/twl4030_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/twl4030_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/watchdog.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/txx9wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/txx9wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/txx9wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/txx9wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/fs.h>
-#include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/uaccess.h>
 #include <linux/platform_device.h>
@@ -166,14 +165,6 @@ static long txx9wdt_ioctl(struct file *f
 	}
 }
 
-static int txx9wdt_notify_sys(struct notifier_block *this, unsigned long code,
-	void *unused)
-{
-	if (code == SYS_DOWN || code == SYS_HALT)
-		txx9wdt_stop();
-	return NOTIFY_DONE;
-}
-
 static const struct file_operations txx9wdt_fops = {
 	.owner		=	THIS_MODULE,
 	.llseek		=	no_llseek,
@@ -189,10 +180,6 @@ static struct miscdevice txx9wdt_miscdev
 	.fops	=	&txx9wdt_fops,
 };
 
-static struct notifier_block txx9wdt_notifier = {
-	.notifier_call = txx9wdt_notify_sys,
-};
-
 static int __init txx9wdt_probe(struct platform_device *dev)
 {
 	struct resource *res;
@@ -221,13 +208,8 @@ static int __init txx9wdt_probe(struct p
 	if (!txx9wdt_reg)
 		goto exit_busy;
 
-	ret = register_reboot_notifier(&txx9wdt_notifier);
-	if (ret)
-		goto exit;
-
 	ret = misc_register(&txx9wdt_miscdev);
 	if (ret) {
-		unregister_reboot_notifier(&txx9wdt_notifier);
 		goto exit;
 	}
 
@@ -249,14 +231,19 @@ exit:
 static int __exit txx9wdt_remove(struct platform_device *dev)
 {
 	misc_deregister(&txx9wdt_miscdev);
-	unregister_reboot_notifier(&txx9wdt_notifier);
 	clk_disable(txx9_imclk);
 	clk_put(txx9_imclk);
 	return 0;
 }
 
+static void txx9wdt_shutdown(struct platform_device *dev)
+{
+	txx9wdt_stop();
+}
+
 static struct platform_driver txx9wdt_driver = {
 	.remove = __exit_p(txx9wdt_remove),
+	.shutdown = txx9wdt_shutdown,
 	.driver = {
 		.name = "txx9wdt",
 		.owner = THIS_MODULE,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/w83627hf_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/w83627hf_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/w83627hf_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/w83627hf_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -201,7 +201,7 @@ static long wdt_ioctl(struct file *file,
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
 	int new_timeout;
-	static struct watchdog_info ident = {
+	static const struct watchdog_info ident = {
 		.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
 							WDIOF_MAGICCLOSE,
 		.firmware_version = 1,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/w83977f_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/w83977f_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/w83977f_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/w83977f_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -371,7 +371,7 @@ static ssize_t wdt_write(struct file *fi
  *      according to their available features.
  */
 
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
 	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
 	.firmware_version =	1,
 	.identity = WATCHDOG_NAME,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/wdrtas.c linux-libre-2.6.34-gnu1/drivers/watchdog/wdrtas.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/wdrtas.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/wdrtas.c	2010-05-16 17:17:36.000000000 -0400
@@ -312,7 +312,7 @@ static long wdrtas_ioctl(struct file *fi
 {
 	int __user *argp = (void __user *)arg;
 	int i;
-	static struct watchdog_info wdinfo = {
+	static const struct watchdog_info wdinfo = {
 		.options = WDRTAS_SUPPORTED_MASK,
 		.firmware_version = 0,
 		.identity = "wdrtas",
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -358,7 +358,7 @@ static long wdt_ioctl(struct file *file,
 	int new_heartbeat;
 	int status;
 
-	static struct watchdog_info ident = {
+	struct watchdog_info ident = {
 		.options =		WDIOF_SETTIMEOUT|
 					WDIOF_MAGICCLOSE|
 					WDIOF_KEEPALIVEPING,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/wdt_pci.c linux-libre-2.6.34-gnu1/drivers/watchdog/wdt_pci.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/wdt_pci.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/wdt_pci.c	2010-05-16 17:17:36.000000000 -0400
@@ -412,7 +412,7 @@ static long wdtpci_ioctl(struct file *fi
 	int new_heartbeat;
 	int status;
 
-	static struct watchdog_info ident = {
+	struct watchdog_info ident = {
 		.options =		WDIOF_SETTIMEOUT|
 					WDIOF_MAGICCLOSE|
 					WDIOF_KEEPALIVEPING,
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/wm831x_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/wm831x_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/wm831x_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/wm831x_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -213,7 +213,7 @@ static ssize_t wm831x_wdt_write(struct f
 	return count;
 }
 
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
 	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
 	.identity = "WM831x Watchdog",
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/watchdog/wm8350_wdt.c linux-libre-2.6.34-gnu1/drivers/watchdog/wm8350_wdt.c
--- linux-libre-2.6.33-gnu1/drivers/watchdog/wm8350_wdt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/watchdog/wm8350_wdt.c	2010-05-16 17:17:36.000000000 -0400
@@ -177,7 +177,7 @@ static ssize_t wm8350_wdt_write(struct f
 	return count;
 }
 
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
 	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
 	.identity = "WM8350 Watchdog",
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/xen/balloon.c linux-libre-2.6.34-gnu1/drivers/xen/balloon.c
--- linux-libre-2.6.33-gnu1/drivers/xen/balloon.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/xen/balloon.c	2010-05-16 17:17:36.000000000 -0400
@@ -43,6 +43,7 @@
 #include <linux/mutex.h>
 #include <linux/list.h>
 #include <linux/sysdev.h>
+#include <linux/gfp.h>
 
 #include <asm/page.h>
 #include <asm/pgalloc.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/xen/events.c linux-libre-2.6.34-gnu1/drivers/xen/events.c
--- linux-libre-2.6.33-gnu1/drivers/xen/events.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/xen/events.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/bootmem.h>
+#include <linux/slab.h>
 
 #include <asm/ptrace.h>
 #include <asm/irq.h>
@@ -649,9 +650,13 @@ void xen_evtchn_do_upcall(struct pt_regs
 				int bit_idx = __ffs(pending_bits);
 				int port = (word_idx * BITS_PER_LONG) + bit_idx;
 				int irq = evtchn_to_irq[port];
+				struct irq_desc *desc;
 
-				if (irq != -1)
-					handle_irq(irq, regs);
+				if (irq != -1) {
+					desc = irq_to_desc(irq);
+					if (desc)
+						generic_handle_irq_desc(irq, desc);
+				}
 			}
 		}
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/xen/evtchn.c linux-libre-2.6.34-gnu1/drivers/xen/evtchn.c
--- linux-libre-2.6.33-gnu1/drivers/xen/evtchn.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/xen/evtchn.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,7 +45,6 @@
 #include <linux/poll.h>
 #include <linux/irq.h>
 #include <linux/init.h>
-#include <linux/gfp.h>
 #include <linux/mutex.h>
 #include <linux/cpu.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/xen/grant-table.c linux-libre-2.6.34-gnu1/drivers/xen/grant-table.c
--- linux-libre-2.6.33-gnu1/drivers/xen/grant-table.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/xen/grant-table.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/uaccess.h>
 
diff -druNp linux-libre-2.6.33-gnu1/drivers/xen/Kconfig linux-libre-2.6.34-gnu1/drivers/xen/Kconfig
--- linux-libre-2.6.33-gnu1/drivers/xen/Kconfig	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/xen/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,8 @@
+menu "Xen driver support"
+	depends on XEN
+
 config XEN_BALLOON
 	bool "Xen memory balloon driver"
-	depends on XEN
 	default y
 	help
 	  The balloon driver allows the Xen domain to request more memory from
@@ -20,7 +22,6 @@ config XEN_SCRUB_PAGES
 
 config XEN_DEV_EVTCHN
 	tristate "Xen /dev/xen/evtchn device"
-	depends on XEN
 	default y
 	help
 	  The evtchn driver allows a userspace process to triger event
@@ -30,7 +31,6 @@ config XEN_DEV_EVTCHN
 
 config XENFS
 	tristate "Xen filesystem"
-	depends on XEN
 	default y
 	help
 	  The xen filesystem provides a way for domains to share
@@ -53,11 +53,13 @@ config XEN_COMPAT_XENFS
 
 config XEN_SYS_HYPERVISOR
        bool "Create xen entries under /sys/hypervisor"
-       depends on XEN && SYSFS
+       depends on SYSFS
        select SYS_HYPERVISOR
        default y
        help
          Create entries under /sys/hypervisor describing the Xen
 	 hypervisor environment.  When running native or in another
 	 virtual environment, /sys/hypervisor will still be present,
-	 but will have no xen contents.
\ No newline at end of file
+	 but will have no xen contents.
+
+endmenu
diff -druNp linux-libre-2.6.33-gnu1/drivers/xen/manage.c linux-libre-2.6.34-gnu1/drivers/xen/manage.c
--- linux-libre-2.6.33-gnu1/drivers/xen/manage.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/xen/manage.c	2010-05-16 17:17:36.000000000 -0400
@@ -3,6 +3,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/reboot.h>
 #include <linux/sysrq.h>
 #include <linux/stop_machine.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/xen/sys-hypervisor.c linux-libre-2.6.34-gnu1/drivers/xen/sys-hypervisor.c
--- linux-libre-2.6.33-gnu1/drivers/xen/sys-hypervisor.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/xen/sys-hypervisor.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
  *  published by the Free Software Foundation.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/kobject.h>
@@ -426,7 +427,7 @@ static ssize_t hyp_sysfs_store(struct ko
 	return 0;
 }
 
-static struct sysfs_ops hyp_sysfs_ops = {
+static const struct sysfs_ops hyp_sysfs_ops = {
 	.show = hyp_sysfs_show,
 	.store = hyp_sysfs_store,
 };
diff -druNp linux-libre-2.6.33-gnu1/drivers/xen/xenbus/xenbus_client.c linux-libre-2.6.34-gnu1/drivers/xen/xenbus/xenbus_client.c
--- linux-libre-2.6.33-gnu1/drivers/xen/xenbus/xenbus_client.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/xen/xenbus/xenbus_client.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
  * IN THE SOFTWARE.
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
 #include <asm/xen/hypervisor.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/xen/xenbus/xenbus_probe.c linux-libre-2.6.34-gnu1/drivers/xen/xenbus/xenbus_probe.c
--- linux-libre-2.6.33-gnu1/drivers/xen/xenbus/xenbus_probe.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/xen/xenbus/xenbus_probe.c	2010-05-16 17:17:36.000000000 -0400
@@ -45,6 +45,7 @@
 #include <linux/kthread.h>
 #include <linux/mutex.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/xen/xencomm.c linux-libre-2.6.34-gnu1/drivers/xen/xencomm.c
--- linux-libre-2.6.33-gnu1/drivers/xen/xencomm.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/xen/xencomm.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,8 +18,8 @@
  * Authors: Hollis Blanchard <hollisb@us.ibm.com>
  */
 
-#include <linux/gfp.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <asm/page.h>
 #include <xen/xencomm.h>
 #include <xen/interface/xen.h>
diff -druNp linux-libre-2.6.33-gnu1/drivers/xen/xenfs/xenbus.c linux-libre-2.6.34-gnu1/drivers/xen/xenfs/xenbus.c
--- linux-libre-2.6.33-gnu1/drivers/xen/xenfs/xenbus.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/xen/xenfs/xenbus.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,6 +51,7 @@
 #include <linux/init.h>
 #include <linux/namei.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 
 #include "xenfs.h"
 #include "../xenbus/xenbus_comms.h"
diff -druNp linux-libre-2.6.33-gnu1/drivers/zorro/zorro.ids linux-libre-2.6.34-gnu1/drivers/zorro/zorro.ids
--- linux-libre-2.6.33-gnu1/drivers/zorro/zorro.ids	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/drivers/zorro/zorro.ids	2010-05-16 17:17:36.000000000 -0400
@@ -108,7 +108,7 @@
 	0c00  500XP/SupraDrive WordSync [SCSI Host Adapter]
 	0d00  SupraDrive WordSync II [SCSI Host Adapter]
 	1000  2400zi+ [Modem]
-0422  Computer Systems Assosiates
+0422  Computer Systems Associates
 	1100  Magnum 40 [Accelerator and SCSI Host Adapter]
 	1500  12 Gauge [SCSI Host Adapter]
 0439  Marc Michael Groth
diff -druNp linux-libre-2.6.33-gnu1/fs/9p/cache.c linux-libre-2.6.34-gnu1/fs/9p/cache.c
--- linux-libre-2.6.33-gnu1/fs/9p/cache.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/9p/cache.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/jiffies.h>
 #include <linux/file.h>
+#include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/sched.h>
 #include <linux/fs.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/9p/fid.c linux-libre-2.6.34-gnu1/fs/9p/fid.c
--- linux-libre-2.6.33-gnu1/fs/9p/fid.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/9p/fid.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/idr.h>
 #include <net/9p/9p.h>
@@ -110,7 +111,7 @@ struct p9_fid *v9fs_fid_lookup(struct de
 {
 	int i, n, l, clone, any, access;
 	u32 uid;
-	struct p9_fid *fid;
+	struct p9_fid *fid, *old_fid = NULL;
 	struct dentry *d, *ds;
 	struct v9fs_session_info *v9ses;
 	char **wnames, *uname;
@@ -151,7 +152,7 @@ struct p9_fid *v9fs_fid_lookup(struct de
 			if (access == V9FS_ACCESS_SINGLE)
 				return ERR_PTR(-EPERM);
 
-			if (v9fs_extended(v9ses))
+			if (v9fs_proto_dotu(v9ses))
 				uname = NULL;
 			else
 				uname = v9ses->uname;
@@ -183,10 +184,18 @@ struct p9_fid *v9fs_fid_lookup(struct de
 		l = min(n - i, P9_MAXWELEM);
 		fid = p9_client_walk(fid, l, &wnames[i], clone);
 		if (IS_ERR(fid)) {
+			if (old_fid) {
+				/*
+				 * If we fail, clunk fid which are mapping
+				 * to path component and not the last component
+				 * of the path.
+				 */
+				p9_client_clunk(old_fid);
+			}
 			kfree(wnames);
 			return fid;
 		}
-
+		old_fid = fid;
 		i += l;
 		clone = 0;
 	}
diff -druNp linux-libre-2.6.33-gnu1/fs/9p/v9fs.c linux-libre-2.6.34-gnu1/fs/9p/v9fs.c
--- linux-libre-2.6.33-gnu1/fs/9p/v9fs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/9p/v9fs.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/sched.h>
 #include <linux/parser.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 #include <net/9p/transport.h>
@@ -237,11 +238,18 @@ struct p9_fid *v9fs_session_init(struct
 		return ERR_PTR(-ENOMEM);
 	}
 
+	rc = bdi_setup_and_register(&v9ses->bdi, "9p", BDI_CAP_MAP_COPY);
+	if (rc) {
+		__putname(v9ses->aname);
+		__putname(v9ses->uname);
+		return ERR_PTR(rc);
+	}
+
 	spin_lock(&v9fs_sessionlist_lock);
 	list_add(&v9ses->slist, &v9fs_sessionlist);
 	spin_unlock(&v9fs_sessionlist_lock);
 
-	v9ses->flags = V9FS_EXTENDED | V9FS_ACCESS_USER;
+	v9ses->flags = V9FS_ACCESS_USER;
 	strcpy(v9ses->uname, V9FS_DEFUSER);
 	strcpy(v9ses->aname, V9FS_DEFANAME);
 	v9ses->uid = ~0;
@@ -262,13 +270,15 @@ struct p9_fid *v9fs_session_init(struct
 		goto error;
 	}
 
-	if (!v9ses->clnt->dotu)
-		v9ses->flags &= ~V9FS_EXTENDED;
+	if (p9_is_proto_dotl(v9ses->clnt))
+		v9ses->flags |= V9FS_PROTO_2000L;
+	else if (p9_is_proto_dotu(v9ses->clnt))
+		v9ses->flags |= V9FS_PROTO_2000U;
 
 	v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ;
 
 	/* for legacy mode, fall back to V9FS_ACCESS_ANY */
-	if (!v9fs_extended(v9ses) &&
+	if (!v9fs_proto_dotu(v9ses) &&
 		((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) {
 
 		v9ses->flags &= ~V9FS_ACCESS_MASK;
@@ -298,6 +308,7 @@ struct p9_fid *v9fs_session_init(struct
 	return fid;
 
 error:
+	bdi_destroy(&v9ses->bdi);
 	return ERR_PTR(retval);
 }
 
@@ -323,6 +334,8 @@ void v9fs_session_close(struct v9fs_sess
 	__putname(v9ses->uname);
 	__putname(v9ses->aname);
 
+	bdi_destroy(&v9ses->bdi);
+
 	spin_lock(&v9fs_sessionlist_lock);
 	list_del(&v9ses->slist);
 	spin_unlock(&v9fs_sessionlist_lock);
@@ -340,6 +353,19 @@ void v9fs_session_cancel(struct v9fs_ses
 	p9_client_disconnect(v9ses->clnt);
 }
 
+/**
+ * v9fs_session_begin_cancel - Begin terminate of a session
+ * @v9ses: session to terminate
+ *
+ * After this call we don't allow any request other than clunk.
+ */
+
+void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses)
+{
+	P9_DPRINTK(P9_DEBUG_ERROR, "begin cancel session %p\n", v9ses);
+	p9_client_begin_disconnect(v9ses->clnt);
+}
+
 extern int v9fs_error_init(void);
 
 static struct kobject *v9fs_kobj;
diff -druNp linux-libre-2.6.33-gnu1/fs/9p/v9fs.h linux-libre-2.6.34-gnu1/fs/9p/v9fs.h
--- linux-libre-2.6.33-gnu1/fs/9p/v9fs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/9p/v9fs.h	2010-05-16 17:17:36.000000000 -0400
@@ -20,10 +20,12 @@
  *  Boston, MA  02111-1301  USA
  *
  */
+#include <linux/backing-dev.h>
 
 /**
  * enum p9_session_flags - option flags for each 9P session
- * @V9FS_EXTENDED: whether or not to use 9P2000.u extensions
+ * @V9FS_PROTO_2000U: whether or not to use 9P2000.u extensions
+ * @V9FS_PROTO_2000L: whether or not to use 9P2000.l extensions
  * @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy
  * @V9FS_ACCESS_USER: a new attach will be issued for every user (default)
  * @V9FS_ACCESS_ANY: use a single attach for all users
@@ -32,11 +34,12 @@
  * Session flags reflect options selected by users at mount time
  */
 enum p9_session_flags {
-	V9FS_EXTENDED		= 0x01,
-	V9FS_ACCESS_SINGLE	= 0x02,
-	V9FS_ACCESS_USER	= 0x04,
-	V9FS_ACCESS_ANY		= 0x06,
-	V9FS_ACCESS_MASK	= 0x06,
+	V9FS_PROTO_2000U	= 0x01,
+	V9FS_PROTO_2000L	= 0x02,
+	V9FS_ACCESS_SINGLE	= 0x04,
+	V9FS_ACCESS_USER	= 0x08,
+	V9FS_ACCESS_ANY		= 0x0C,
+	V9FS_ACCESS_MASK	= 0x0C,
 };
 
 /* possible values of ->cache */
@@ -100,12 +103,14 @@ struct v9fs_session_info {
 	u32 uid;		/* if ACCESS_SINGLE, the uid that has access */
 	struct p9_client *clnt;	/* 9p client */
 	struct list_head slist; /* list of sessions registered with v9fs */
+	struct backing_dev_info bdi;
 };
 
 struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
 									char *);
 void v9fs_session_close(struct v9fs_session_info *v9ses);
 void v9fs_session_cancel(struct v9fs_session_info *v9ses);
+void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses);
 
 #define V9FS_MAGIC 0x01021997
 
@@ -121,7 +126,12 @@ static inline struct v9fs_session_info *
 	return (inode->i_sb->s_fs_info);
 }
 
-static inline int v9fs_extended(struct v9fs_session_info *v9ses)
+static inline int v9fs_proto_dotu(struct v9fs_session_info *v9ses)
 {
-	return v9ses->flags & V9FS_EXTENDED;
+	return v9ses->flags & V9FS_PROTO_2000U;
+}
+
+static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
+{
+	return v9ses->flags & V9FS_PROTO_2000L;
 }
diff -druNp linux-libre-2.6.33-gnu1/fs/9p/vfs_dentry.c linux-libre-2.6.34-gnu1/fs/9p/vfs_dentry.c
--- linux-libre-2.6.33-gnu1/fs/9p/vfs_dentry.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/9p/vfs_dentry.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/namei.h>
 #include <linux/idr.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 
diff -druNp linux-libre-2.6.33-gnu1/fs/9p/vfs_dir.c linux-libre-2.6.34-gnu1/fs/9p/vfs_dir.c
--- linux-libre-2.6.33-gnu1/fs/9p/vfs_dir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/9p/vfs_dir.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/sched.h>
 #include <linux/inet.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 
@@ -76,6 +77,15 @@ static inline int dt_type(struct p9_wsta
 	return rettype;
 }
 
+static void p9stat_init(struct p9_wstat *stbuf)
+{
+	stbuf->name  = NULL;
+	stbuf->uid   = NULL;
+	stbuf->gid   = NULL;
+	stbuf->muid  = NULL;
+	stbuf->extension = NULL;
+}
+
 /**
  * v9fs_dir_readdir - read a directory
  * @filp: opened file structure
@@ -121,6 +131,8 @@ static int v9fs_dir_readdir(struct file
 	rdir = (struct p9_rdir *) fid->rdir;
 
 	err = mutex_lock_interruptible(&rdir->mutex);
+	if (err)
+		return err;
 	while (err == 0) {
 		if (rdir->tail == rdir->head) {
 			err = v9fs_file_readn(filp, rdir->buf, NULL,
@@ -131,11 +143,11 @@ static int v9fs_dir_readdir(struct file
 			rdir->head = 0;
 			rdir->tail = err;
 		}
-
 		while (rdir->head < rdir->tail) {
+			p9stat_init(&st);
 			err = p9stat_read(rdir->buf + rdir->head,
 						buflen - rdir->head, &st,
-						fid->clnt->dotu);
+						fid->clnt->proto_version);
 			if (err) {
 				P9_DPRINTK(P9_DEBUG_VFS, "returned %d\n", err);
 				err = -EIO;
diff -druNp linux-libre-2.6.33-gnu1/fs/9p/vfs_file.c linux-libre-2.6.34-gnu1/fs/9p/vfs_file.c
--- linux-libre-2.6.33-gnu1/fs/9p/vfs_file.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/9p/vfs_file.c	2010-05-16 17:17:36.000000000 -0400
@@ -61,7 +61,7 @@ int v9fs_file_open(struct inode *inode,
 
 	P9_DPRINTK(P9_DEBUG_VFS, "inode: %p file: %p \n", inode, file);
 	v9ses = v9fs_inode2v9ses(inode);
-	omode = v9fs_uflags2omode(file->f_flags, v9fs_extended(v9ses));
+	omode = v9fs_uflags2omode(file->f_flags, v9fs_proto_dotu(v9ses));
 	fid = file->private_data;
 	if (!fid) {
 		fid = v9fs_fid_clone(file->f_path.dentry);
@@ -77,7 +77,7 @@ int v9fs_file_open(struct inode *inode,
 			i_size_write(inode, 0);
 			inode->i_blocks = 0;
 		}
-		if ((file->f_flags & O_APPEND) && (!v9fs_extended(v9ses)))
+		if ((file->f_flags & O_APPEND) && (!v9fs_proto_dotu(v9ses)))
 			generic_file_llseek(file, 0, SEEK_END);
 	}
 
@@ -114,7 +114,7 @@ static int v9fs_file_lock(struct file *f
 	P9_DPRINTK(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl);
 
 	/* No mandatory locks */
-	if (__mandatory_lock(inode))
+	if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
 		return -ENOLCK;
 
 	if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
@@ -215,7 +215,7 @@ v9fs_file_write(struct file *filp, const
 	struct p9_fid *fid;
 	struct p9_client *clnt;
 	struct inode *inode = filp->f_path.dentry->d_inode;
-	int origin = *offset;
+	loff_t origin = *offset;
 	unsigned long pg_start, pg_end;
 
 	P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data,
diff -druNp linux-libre-2.6.33-gnu1/fs/9p/vfs_inode.c linux-libre-2.6.34-gnu1/fs/9p/vfs_inode.c
--- linux-libre-2.6.33-gnu1/fs/9p/vfs_inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/9p/vfs_inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/namei.h>
 #include <linux/idr.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 
@@ -60,7 +61,7 @@ static int unixmode2p9mode(struct v9fs_s
 	res = mode & 0777;
 	if (S_ISDIR(mode))
 		res |= P9_DMDIR;
-	if (v9fs_extended(v9ses)) {
+	if (v9fs_proto_dotu(v9ses)) {
 		if (S_ISLNK(mode))
 			res |= P9_DMSYMLINK;
 		if (v9ses->nodev == 0) {
@@ -102,21 +103,21 @@ static int p9mode2unixmode(struct v9fs_s
 
 	if ((mode & P9_DMDIR) == P9_DMDIR)
 		res |= S_IFDIR;
-	else if ((mode & P9_DMSYMLINK) && (v9fs_extended(v9ses)))
+	else if ((mode & P9_DMSYMLINK) && (v9fs_proto_dotu(v9ses)))
 		res |= S_IFLNK;
-	else if ((mode & P9_DMSOCKET) && (v9fs_extended(v9ses))
+	else if ((mode & P9_DMSOCKET) && (v9fs_proto_dotu(v9ses))
 		 && (v9ses->nodev == 0))
 		res |= S_IFSOCK;
-	else if ((mode & P9_DMNAMEDPIPE) && (v9fs_extended(v9ses))
+	else if ((mode & P9_DMNAMEDPIPE) && (v9fs_proto_dotu(v9ses))
 		 && (v9ses->nodev == 0))
 		res |= S_IFIFO;
-	else if ((mode & P9_DMDEVICE) && (v9fs_extended(v9ses))
+	else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses))
 		 && (v9ses->nodev == 0))
 		res |= S_IFBLK;
 	else
 		res |= S_IFREG;
 
-	if (v9fs_extended(v9ses)) {
+	if (v9fs_proto_dotu(v9ses)) {
 		if ((mode & P9_DMSETUID) == P9_DMSETUID)
 			res |= S_ISUID;
 
@@ -265,7 +266,7 @@ struct inode *v9fs_get_inode(struct supe
 	case S_IFBLK:
 	case S_IFCHR:
 	case S_IFSOCK:
-		if (!v9fs_extended(v9ses)) {
+		if (!v9fs_proto_dotu(v9ses)) {
 			P9_DPRINTK(P9_DEBUG_ERROR,
 				   "special files without extended mode\n");
 			err = -EINVAL;
@@ -278,7 +279,7 @@ struct inode *v9fs_get_inode(struct supe
 		inode->i_fop = &v9fs_file_operations;
 		break;
 	case S_IFLNK:
-		if (!v9fs_extended(v9ses)) {
+		if (!v9fs_proto_dotu(v9ses)) {
 			P9_DPRINTK(P9_DEBUG_ERROR,
 				   "extended modes used w/o 9P2000.u\n");
 			err = -EINVAL;
@@ -288,7 +289,7 @@ struct inode *v9fs_get_inode(struct supe
 		break;
 	case S_IFDIR:
 		inc_nlink(inode);
-		if (v9fs_extended(v9ses))
+		if (v9fs_proto_dotu(v9ses))
 			inode->i_op = &v9fs_dir_inode_operations_ext;
 		else
 			inode->i_op = &v9fs_dir_inode_operations;
@@ -431,6 +432,7 @@ error:
 
 static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
 {
+	int retval;
 	struct inode *file_inode;
 	struct v9fs_session_info *v9ses;
 	struct p9_fid *v9fid;
@@ -444,7 +446,10 @@ static int v9fs_remove(struct inode *dir
 	if (IS_ERR(v9fid))
 		return PTR_ERR(v9fid);
 
-	return p9_client_remove(v9fid);
+	retval = p9_client_remove(v9fid);
+	if (!retval)
+		drop_nlink(file_inode);
+	return retval;
 }
 
 static int
@@ -575,7 +580,8 @@ v9fs_vfs_create(struct inode *dir, struc
 		flags = O_RDWR;
 
 	fid = v9fs_create(v9ses, dir, dentry, NULL, perm,
-				v9fs_uflags2omode(flags, v9fs_extended(v9ses)));
+				v9fs_uflags2omode(flags,
+						v9fs_proto_dotu(v9ses)));
 	if (IS_ERR(fid)) {
 		err = PTR_ERR(fid);
 		fid = NULL;
@@ -655,6 +661,9 @@ static struct dentry *v9fs_vfs_lookup(st
 	P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n",
 		dir, dentry->d_name.name, dentry, nameidata);
 
+	if (dentry->d_name.len > NAME_MAX)
+		return ERR_PTR(-ENAMETOOLONG);
+
 	sb = dir->i_sb;
 	v9ses = v9fs_inode2v9ses(dir);
 	dfid = v9fs_fid_lookup(dentry->d_parent);
@@ -858,7 +867,7 @@ static int v9fs_vfs_setattr(struct dentr
 	if (iattr->ia_valid & ATTR_SIZE)
 		wstat.length = iattr->ia_size;
 
-	if (v9fs_extended(v9ses)) {
+	if (v9fs_proto_dotu(v9ses)) {
 		if (iattr->ia_valid & ATTR_UID)
 			wstat.n_uid = iattr->ia_uid;
 
@@ -886,6 +895,8 @@ v9fs_stat2inode(struct p9_wstat *stat, s
 	struct super_block *sb)
 {
 	char ext[32];
+	char tag_name[14];
+	unsigned int i_nlink;
 	struct v9fs_session_info *v9ses = sb->s_fs_info;
 
 	inode->i_nlink = 1;
@@ -897,11 +908,26 @@ v9fs_stat2inode(struct p9_wstat *stat, s
 	inode->i_uid = v9ses->dfltuid;
 	inode->i_gid = v9ses->dfltgid;
 
-	if (v9fs_extended(v9ses)) {
+	if (v9fs_proto_dotu(v9ses)) {
 		inode->i_uid = stat->n_uid;
 		inode->i_gid = stat->n_gid;
 	}
-
+	if ((S_ISREG(inode->i_mode)) || (S_ISDIR(inode->i_mode))) {
+		if (v9fs_proto_dotu(v9ses) && (stat->extension[0] != '\0')) {
+			/*
+			 * Hadlink support got added later to
+			 * to the .u extension. So there can be
+			 * server out there that doesn't support
+			 * this even with .u extension. So check
+			 * for non NULL stat->extension
+			 */
+			strncpy(ext, stat->extension, sizeof(ext));
+			/* HARDLINKCOUNT %u */
+			sscanf(ext, "%13s %u", tag_name, &i_nlink);
+			if (!strncmp(tag_name, "HARDLINKCOUNT", 13))
+				inode->i_nlink = i_nlink;
+		}
+	}
 	inode->i_mode = p9mode2unixmode(v9ses, stat->mode);
 	if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) {
 		char type = 0;
@@ -976,7 +1002,7 @@ static int v9fs_readlink(struct dentry *
 	if (IS_ERR(fid))
 		return PTR_ERR(fid);
 
-	if (!v9fs_extended(v9ses))
+	if (!v9fs_proto_dotu(v9ses))
 		return -EBADF;
 
 	st = p9_client_stat(fid);
@@ -1066,7 +1092,7 @@ static int v9fs_vfs_mkspecial(struct ino
 	struct p9_fid *fid;
 
 	v9ses = v9fs_inode2v9ses(dir);
-	if (!v9fs_extended(v9ses)) {
+	if (!v9fs_proto_dotu(v9ses)) {
 		P9_DPRINTK(P9_DEBUG_ERROR, "not extended\n");
 		return -EPERM;
 	}
diff -druNp linux-libre-2.6.33-gnu1/fs/9p/vfs_super.c linux-libre-2.6.34-gnu1/fs/9p/vfs_super.c
--- linux-libre-2.6.33-gnu1/fs/9p/vfs_super.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/9p/vfs_super.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/mount.h>
 #include <linux/idr.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 
@@ -76,6 +77,7 @@ v9fs_fill_super(struct super_block *sb,
 	sb->s_blocksize = 1 << sb->s_blocksize_bits;
 	sb->s_magic = V9FS_MAGIC;
 	sb->s_op = &v9fs_super_ops;
+	sb->s_bdi = &v9ses->bdi;
 
 	sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC |
 	    MS_NOATIME;
@@ -193,6 +195,7 @@ static void v9fs_kill_super(struct super
 
 	kill_anon_super(s);
 
+	v9fs_session_cancel(v9ses);
 	v9fs_session_close(v9ses);
 	kfree(v9ses);
 	s->s_fs_info = NULL;
@@ -205,7 +208,7 @@ v9fs_umount_begin(struct super_block *sb
 	struct v9fs_session_info *v9ses;
 
 	v9ses = sb->s_fs_info;
-	v9fs_session_cancel(v9ses);
+	v9fs_session_begin_cancel(v9ses);
 }
 
 static const struct super_operations v9fs_super_ops = {
diff -druNp linux-libre-2.6.33-gnu1/fs/adfs/adfs.h linux-libre-2.6.34-gnu1/fs/adfs/adfs.h
--- linux-libre-2.6.33-gnu1/fs/adfs/adfs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/adfs/adfs.h	2010-05-16 17:17:36.000000000 -0400
@@ -121,7 +121,7 @@ struct adfs_discmap {
 
 /* Inode stuff */
 struct inode *adfs_iget(struct super_block *sb, struct object_info *obj);
-int adfs_write_inode(struct inode *inode,int unused);
+int adfs_write_inode(struct inode *inode, struct writeback_control *wbc);
 int adfs_notify_change(struct dentry *dentry, struct iattr *attr);
 
 /* map.c */
diff -druNp linux-libre-2.6.33-gnu1/fs/adfs/inode.c linux-libre-2.6.34-gnu1/fs/adfs/inode.c
--- linux-libre-2.6.33-gnu1/fs/adfs/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/adfs/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  */
 #include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
+#include <linux/writeback.h>
 #include "adfs.h"
 
 /*
@@ -360,7 +361,7 @@ out:
  * The adfs-specific inode data has already been updated by
  * adfs_notify_change()
  */
-int adfs_write_inode(struct inode *inode, int wait)
+int adfs_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
 	struct super_block *sb = inode->i_sb;
 	struct object_info obj;
@@ -375,7 +376,7 @@ int adfs_write_inode(struct inode *inode
 	obj.attr	= ADFS_I(inode)->attr;
 	obj.size	= inode->i_size;
 
-	ret = adfs_dir_update(sb, &obj, wait);
+	ret = adfs_dir_update(sb, &obj, wbc->sync_mode == WB_SYNC_ALL);
 	unlock_kernel();
 	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/fs/adfs/super.c linux-libre-2.6.34-gnu1/fs/adfs/super.c
--- linux-libre-2.6.33-gnu1/fs/adfs/super.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/adfs/super.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/parser.h>
 #include <linux/mount.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/statfs.h>
 #include "adfs.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/affs/affs.h linux-libre-2.6.34-gnu1/fs/affs/affs.h
--- linux-libre-2.6.33-gnu1/fs/affs/affs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/affs/affs.h	2010-05-16 17:17:36.000000000 -0400
@@ -175,7 +175,8 @@ extern void			 affs_delete_inode(struct
 extern void			 affs_clear_inode(struct inode *inode);
 extern struct inode		*affs_iget(struct super_block *sb,
 					unsigned long ino);
-extern int			 affs_write_inode(struct inode *inode, int);
+extern int			 affs_write_inode(struct inode *inode,
+					struct writeback_control *wbc);
 extern int			 affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s32 type);
 
 /* file.c */
diff -druNp linux-libre-2.6.33-gnu1/fs/affs/bitmap.c linux-libre-2.6.34-gnu1/fs/affs/bitmap.c
--- linux-libre-2.6.33-gnu1/fs/affs/bitmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/affs/bitmap.c	2010-05-16 17:17:36.000000000 -0400
@@ -7,6 +7,7 @@
  *  block allocation, deallocation, calculation of free space.
  */
 
+#include <linux/slab.h>
 #include "affs.h"
 
 /* This is, of course, shamelessly stolen from fs/minix */
@@ -128,7 +129,7 @@ err_range:
 /*
  * Allocate a block in the given allocation zone.
  * Since we have to byte-swap the bitmap on little-endian
- * machines, this is rather expensive. Therefor we will
+ * machines, this is rather expensive. Therefore we will
  * preallocate up to 16 blocks from the same word, if
  * possible. We are not doing preallocations in the
  * header zone, though.
diff -druNp linux-libre-2.6.33-gnu1/fs/affs/inode.c linux-libre-2.6.34-gnu1/fs/affs/inode.c
--- linux-libre-2.6.33-gnu1/fs/affs/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/affs/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  *  (C) 1991  Linus Torvalds - minix filesystem
  */
 #include <linux/sched.h>
+#include <linux/gfp.h>
 #include "affs.h"
 
 extern const struct inode_operations affs_symlink_inode_operations;
@@ -166,7 +167,7 @@ bad_inode:
 }
 
 int
-affs_write_inode(struct inode *inode, int unused)
+affs_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
 	struct super_block	*sb = inode->i_sb;
 	struct buffer_head	*bh;
diff -druNp linux-libre-2.6.33-gnu1/fs/affs/super.c linux-libre-2.6.34-gnu1/fs/affs/super.c
--- linux-libre-2.6.33-gnu1/fs/affs/super.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/affs/super.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/magic.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include "affs.h"
 
 extern struct timezone sys_tz;
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/cache.c linux-libre-2.6.34-gnu1/fs/afs/cache.c
--- linux-libre-2.6.33-gnu1/fs/afs/cache.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/cache.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,7 +9,6 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#include <linux/slab.h>
 #include <linux/sched.h>
 #include "internal.h"
 
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/cmservice.c linux-libre-2.6.34-gnu1/fs/afs/cmservice.c
--- linux-libre-2.6.33-gnu1/fs/afs/cmservice.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/cmservice.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/ip.h>
 #include "internal.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/dir.c linux-libre-2.6.34-gnu1/fs/afs/dir.c
--- linux-libre-2.6.33-gnu1/fs/afs/dir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/dir.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
 #include <linux/ctype.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/file.c linux-libre-2.6.34-gnu1/fs/afs/file.c
--- linux-libre-2.6.33-gnu1/fs/afs/file.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/file.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,10 +12,10 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
 #include <linux/writeback.h>
+#include <linux/gfp.h>
 #include "internal.h"
 
 static int afs_readpage(struct file *file, struct page *page);
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/fsclient.c linux-libre-2.6.34-gnu1/fs/afs/fsclient.c
--- linux-libre-2.6.33-gnu1/fs/afs/fsclient.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/fsclient.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/circ_buf.h>
 #include "internal.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/inode.c linux-libre-2.6.34-gnu1/fs/afs/inode.c
--- linux-libre-2.6.33-gnu1/fs/afs/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
 #include <linux/sched.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/internal.h linux-libre-2.6.34-gnu1/fs/afs/internal.h
--- linux-libre-2.6.33-gnu1/fs/afs/internal.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/internal.h	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/workqueue.h>
 #include <linux/sched.h>
 #include <linux/fscache.h>
+#include <linux/backing-dev.h>
 
 #include "afs.h"
 #include "afs_vl.h"
@@ -313,6 +314,7 @@ struct afs_volume {
 	unsigned short		rjservers;	/* number of servers discarded due to -ENOMEDIUM */
 	struct afs_server	*servers[8];	/* servers on which volume resides (ordered) */
 	struct rw_semaphore	server_sem;	/* lock for accessing current server */
+	struct backing_dev_info	bdi;
 };
 
 /*
@@ -733,7 +735,6 @@ extern int afs_write_end(struct file *fi
 			struct page *page, void *fsdata);
 extern int afs_writepage(struct page *, struct writeback_control *);
 extern int afs_writepages(struct address_space *, struct writeback_control *);
-extern int afs_write_inode(struct inode *, int);
 extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *);
 extern ssize_t afs_file_write(struct kiocb *, const struct iovec *,
 			      unsigned long, loff_t);
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/mntpt.c linux-libre-2.6.34-gnu1/fs/afs/mntpt.c
--- linux-libre-2.6.33-gnu1/fs/afs/mntpt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/mntpt.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,11 +12,11 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
+#include <linux/gfp.h>
 #include "internal.h"
 
 
@@ -138,9 +138,9 @@ static struct vfsmount *afs_mntpt_do_aut
 {
 	struct afs_super_info *super;
 	struct vfsmount *mnt;
-	struct page *page = NULL;
+	struct page *page;
 	size_t size;
-	char *buf, *devname = NULL, *options = NULL;
+	char *buf, *devname, *options;
 	int ret;
 
 	_enter("{%s}", mntpt->d_name.name);
@@ -150,22 +150,22 @@ static struct vfsmount *afs_mntpt_do_aut
 	ret = -EINVAL;
 	size = mntpt->d_inode->i_size;
 	if (size > PAGE_SIZE - 1)
-		goto error;
+		goto error_no_devname;
 
 	ret = -ENOMEM;
 	devname = (char *) get_zeroed_page(GFP_KERNEL);
 	if (!devname)
-		goto error;
+		goto error_no_devname;
 
 	options = (char *) get_zeroed_page(GFP_KERNEL);
 	if (!options)
-		goto error;
+		goto error_no_options;
 
 	/* read the contents of the AFS special symlink */
 	page = read_mapping_page(mntpt->d_inode->i_mapping, 0, NULL);
 	if (IS_ERR(page)) {
 		ret = PTR_ERR(page);
-		goto error;
+		goto error_no_page;
 	}
 
 	ret = -EIO;
@@ -196,12 +196,12 @@ static struct vfsmount *afs_mntpt_do_aut
 	return mnt;
 
 error:
-	if (page)
-		page_cache_release(page);
-	if (devname)
-		free_page((unsigned long) devname);
-	if (options)
-		free_page((unsigned long) options);
+	page_cache_release(page);
+error_no_page:
+	free_page((unsigned long) options);
+error_no_options:
+	free_page((unsigned long) devname);
+error_no_devname:
 	_leave(" = %d", ret);
 	return ERR_PTR(ret);
 }
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/rxrpc.c linux-libre-2.6.34-gnu1/fs/afs/rxrpc.c
--- linux-libre-2.6.33-gnu1/fs/afs/rxrpc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/rxrpc.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include <rxrpc/packet.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/security.c linux-libre-2.6.34-gnu1/fs/afs/security.c
--- linux-libre-2.6.33-gnu1/fs/afs/security.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/security.c	2010-05-16 17:17:36.000000000 -0400
@@ -189,8 +189,9 @@ void afs_cache_permit(struct afs_vnode *
 	if (!permits)
 		goto out_unlock;
 
-	memcpy(permits->permits, xpermits->permits,
-	       count * sizeof(struct afs_permit));
+	if (xpermits)
+		memcpy(permits->permits, xpermits->permits,
+			count * sizeof(struct afs_permit));
 
 	_debug("key %x access %x",
 	       key_serial(key), vnode->status.caller_access);
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/super.c linux-libre-2.6.34-gnu1/fs/afs/super.c
--- linux-libre-2.6.33-gnu1/fs/afs/super.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/super.c	2010-05-16 17:17:36.000000000 -0400
@@ -48,7 +48,6 @@ struct file_system_type afs_fs_type = {
 static const struct super_operations afs_super_ops = {
 	.statfs		= afs_statfs,
 	.alloc_inode	= afs_alloc_inode,
-	.write_inode	= afs_write_inode,
 	.destroy_inode	= afs_destroy_inode,
 	.clear_inode	= afs_clear_inode,
 	.put_super	= afs_put_super,
@@ -312,6 +311,7 @@ static int afs_fill_super(struct super_b
 	sb->s_magic		= AFS_FS_MAGIC;
 	sb->s_op		= &afs_super_ops;
 	sb->s_fs_info		= as;
+	sb->s_bdi		= &as->volume->bdi;
 
 	/* allocate the root inode and dentry */
 	fid.vid		= as->volume->vid;
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/vlclient.c linux-libre-2.6.34-gnu1/fs/afs/vlclient.c
--- linux-libre-2.6.33-gnu1/fs/afs/vlclient.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/vlclient.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include "internal.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/vlocation.c linux-libre-2.6.34-gnu1/fs/afs/vlocation.c
--- linux-libre-2.6.33-gnu1/fs/afs/vlocation.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/vlocation.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include "internal.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/vnode.c linux-libre-2.6.34-gnu1/fs/afs/vnode.c
--- linux-libre-2.6.33-gnu1/fs/afs/vnode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/vnode.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include "internal.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/volume.c linux-libre-2.6.34-gnu1/fs/afs/volume.c
--- linux-libre-2.6.33-gnu1/fs/afs/volume.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/volume.c	2010-05-16 17:17:36.000000000 -0400
@@ -106,6 +106,10 @@ struct afs_volume *afs_volume_lookup(str
 	volume->cell		= params->cell;
 	volume->vid		= vlocation->vldb.vid[params->type];
 
+	ret = bdi_setup_and_register(&volume->bdi, "afs", BDI_CAP_MAP_COPY);
+	if (ret)
+		goto error_bdi;
+
 	init_rwsem(&volume->server_sem);
 
 	/* look up all the applicable server records */
@@ -151,6 +155,8 @@ error:
 	return ERR_PTR(ret);
 
 error_discard:
+	bdi_destroy(&volume->bdi);
+error_bdi:
 	up_write(&params->cell->vl_sem);
 
 	for (loop = volume->nservers - 1; loop >= 0; loop--)
@@ -200,6 +206,7 @@ void afs_put_volume(struct afs_volume *v
 	for (loop = volume->nservers - 1; loop >= 0; loop--)
 		afs_put_server(volume->servers[loop]);
 
+	bdi_destroy(&volume->bdi);
 	kfree(volume);
 
 	_leave(" [destroyed]");
diff -druNp linux-libre-2.6.33-gnu1/fs/afs/write.c linux-libre-2.6.34-gnu1/fs/afs/write.c
--- linux-libre-2.6.33-gnu1/fs/afs/write.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/afs/write.c	2010-05-16 17:17:36.000000000 -0400
@@ -585,27 +585,6 @@ int afs_writepages(struct address_space
 }
 
 /*
- * write an inode back
- */
-int afs_write_inode(struct inode *inode, int sync)
-{
-	struct afs_vnode *vnode = AFS_FS_I(inode);
-	int ret;
-
-	_enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode);
-
-	ret = 0;
-	if (sync) {
-		ret = filemap_fdatawait(inode->i_mapping);
-		if (ret < 0)
-			__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
-	}
-
-	_leave(" = %d", ret);
-	return ret;
-}
-
-/*
  * completion of write to server
  */
 void afs_pages_written_back(struct afs_vnode *vnode, struct afs_call *call)
diff -druNp linux-libre-2.6.33-gnu1/fs/anon_inodes.c linux-libre-2.6.34-gnu1/fs/anon_inodes.c
--- linux-libre-2.6.33-gnu1/fs/anon_inodes.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/anon_inodes.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 #include <linux/file.h>
 #include <linux/poll.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/mount.h>
@@ -209,6 +208,7 @@ static struct inode *anon_inode_mkinode(
 	inode->i_mode = S_IRUSR | S_IWUSR;
 	inode->i_uid = current_fsuid();
 	inode->i_gid = current_fsgid();
+	inode->i_flags |= S_PRIVATE;
 	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 	return inode;
 }
diff -druNp linux-libre-2.6.33-gnu1/fs/attr.c linux-libre-2.6.34-gnu1/fs/attr.c
--- linux-libre-2.6.33-gnu1/fs/attr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/attr.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,7 +12,6 @@
 #include <linux/capability.h>
 #include <linux/fsnotify.h>
 #include <linux/fcntl.h>
-#include <linux/quotaops.h>
 #include <linux/security.h>
 
 /* Taken over from the old code... */
@@ -82,7 +81,7 @@ int inode_newsize_ok(const struct inode
 	if (inode->i_size < offset) {
 		unsigned long limit;
 
-		limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
+		limit = rlimit(RLIMIT_FSIZE);
 		if (limit != RLIM_INFINITY && offset > limit)
 			goto out_sig;
 		if (offset > inode->i_sb->s_maxbytes)
@@ -212,14 +211,8 @@ int notify_change(struct dentry * dentry
 		error = inode->i_op->setattr(dentry, attr);
 	} else {
 		error = inode_change_ok(inode, attr);
-		if (!error) {
-			if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
-			    (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
-				error = vfs_dq_transfer(inode, attr) ?
-					-EDQUOT : 0;
-			if (!error)
-				error = inode_setattr(inode, attr);
-		}
+		if (!error)
+			error = inode_setattr(inode, attr);
 	}
 
 	if (ia_valid & ATTR_SIZE)
diff -druNp linux-libre-2.6.33-gnu1/fs/autofs/root.c linux-libre-2.6.34-gnu1/fs/autofs/root.c
--- linux-libre-2.6.33-gnu1/fs/autofs/root.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/autofs/root.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/capability.h>
 #include <linux/errno.h>
 #include <linux/stat.h>
+#include <linux/slab.h>
 #include <linux/param.h>
 #include <linux/time.h>
 #include <linux/smp_lock.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/autofs4/autofs_i.h linux-libre-2.6.34-gnu1/fs/autofs4/autofs_i.h
--- linux-libre-2.6.33-gnu1/fs/autofs4/autofs_i.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/autofs4/autofs_i.h	2010-05-16 17:17:36.000000000 -0400
@@ -60,11 +60,6 @@ do {							\
 		current->pid, __func__, ##args);	\
 } while (0)
 
-struct rehash_entry {
-	struct task_struct *task;
-	struct list_head list;
-};
-
 /* Unified info structure.  This is pointed to by both the dentry and
    inode structures.  Each file in the filesystem has an instance of this
    structure.  It holds a reference to the dentry, so dentries are never
@@ -81,7 +76,6 @@ struct autofs_info {
 
 	struct list_head active;
 	int active_count;
-	struct list_head rehash_list;
 
 	struct list_head expiring;
 
@@ -104,7 +98,6 @@ struct autofs_info {
 #define AUTOFS_INF_EXPIRING	(1<<0) /* dentry is in the process of expiring */
 #define AUTOFS_INF_MOUNTPOINT	(1<<1) /* mountpoint status for direct expire */
 #define AUTOFS_INF_PENDING	(1<<2) /* dentry pending mount */
-#define AUTOFS_INF_REHASH	(1<<3) /* dentry in transit to ->lookup() */
 
 struct autofs_wait_queue {
 	wait_queue_head_t queue;
diff -druNp linux-libre-2.6.33-gnu1/fs/autofs4/dev-ioctl.c linux-libre-2.6.34-gnu1/fs/autofs4/dev-ioctl.c
--- linux-libre-2.6.33-gnu1/fs/autofs4/dev-ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/autofs4/dev-ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/magic.h>
 #include <linux/dcache.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 
 #include "autofs_i.h"
 
@@ -544,10 +545,9 @@ static int autofs_dev_ioctl_ismountpoint
 			goto out;
 		devid = new_encode_dev(path.mnt->mnt_sb->s_dev);
 		err = 0;
-		if (path.dentry->d_inode &&
-		    path.mnt->mnt_root == path.dentry) {
+		if (path.mnt->mnt_root == path.dentry) {
 			err = 1;
-			magic = path.dentry->d_inode->i_sb->s_magic;
+			magic = path.mnt->mnt_sb->s_magic;
 		}
 	} else {
 		dev_t dev = sbi->sb->s_dev;
@@ -560,10 +560,8 @@ static int autofs_dev_ioctl_ismountpoint
 
 		err = have_submounts(path.dentry);
 
-		if (path.mnt->mnt_mountpoint != path.mnt->mnt_root) {
-			if (follow_down(&path))
-				magic = path.mnt->mnt_sb->s_magic;
-		}
+		if (follow_down(&path))
+			magic = path.mnt->mnt_sb->s_magic;
 	}
 
 	param->ismountpoint.out.devid = devid;
diff -druNp linux-libre-2.6.33-gnu1/fs/autofs4/expire.c linux-libre-2.6.34-gnu1/fs/autofs4/expire.c
--- linux-libre-2.6.33-gnu1/fs/autofs4/expire.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/autofs4/expire.c	2010-05-16 17:17:36.000000000 -0400
@@ -279,7 +279,6 @@ struct dentry *autofs4_expire_direct(str
 			root->d_mounted--;
 		}
 		ino->flags |= AUTOFS_INF_EXPIRING;
-		autofs4_add_expiring(root);
 		init_completion(&ino->expire_complete);
 		spin_unlock(&sbi->fs_lock);
 		return root;
@@ -407,7 +406,6 @@ found:
 		expired, (int)expired->d_name.len, expired->d_name.name);
 	ino = autofs4_dentry_ino(expired);
 	ino->flags |= AUTOFS_INF_EXPIRING;
-	autofs4_add_expiring(expired);
 	init_completion(&ino->expire_complete);
 	spin_unlock(&sbi->fs_lock);
 	spin_lock(&dcache_lock);
@@ -435,7 +433,7 @@ int autofs4_expire_wait(struct dentry *d
 
 		DPRINTK("expire done status=%d", status);
 
-		if (d_unhashed(dentry) && IS_DEADDIR(dentry->d_inode))
+		if (d_unhashed(dentry))
 			return -EAGAIN;
 
 		return status;
@@ -475,7 +473,6 @@ int autofs4_expire_run(struct super_bloc
 	spin_lock(&sbi->fs_lock);
 	ino = autofs4_dentry_ino(dentry);
 	ino->flags &= ~AUTOFS_INF_EXPIRING;
-	autofs4_del_expiring(dentry);
 	complete_all(&ino->expire_complete);
 	spin_unlock(&sbi->fs_lock);
 
@@ -506,7 +503,6 @@ int autofs4_do_expire_multi(struct super
 			ino->flags &= ~AUTOFS_INF_MOUNTPOINT;
 		}
 		ino->flags &= ~AUTOFS_INF_EXPIRING;
-		autofs4_del_expiring(dentry);
 		complete_all(&ino->expire_complete);
 		spin_unlock(&sbi->fs_lock);
 		dput(dentry);
diff -druNp linux-libre-2.6.33-gnu1/fs/autofs4/inode.c linux-libre-2.6.34-gnu1/fs/autofs4/inode.c
--- linux-libre-2.6.33-gnu1/fs/autofs4/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/autofs4/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,7 +49,6 @@ struct autofs_info *autofs4_init_ino(str
 		ino->dentry = NULL;
 		ino->size = 0;
 		INIT_LIST_HEAD(&ino->active);
-		INIT_LIST_HEAD(&ino->rehash_list);
 		ino->active_count = 0;
 		INIT_LIST_HEAD(&ino->expiring);
 		atomic_set(&ino->count, 0);
@@ -97,63 +96,6 @@ void autofs4_free_ino(struct autofs_info
 	kfree(ino);
 }
 
-/*
- * Deal with the infamous "Busy inodes after umount ..." message.
- *
- * Clean up the dentry tree. This happens with autofs if the user
- * space program goes away due to a SIGKILL, SIGSEGV etc.
- */
-static void autofs4_force_release(struct autofs_sb_info *sbi)
-{
-	struct dentry *this_parent = sbi->sb->s_root;
-	struct list_head *next;
-
-	if (!sbi->sb->s_root)
-		return;
-
-	spin_lock(&dcache_lock);
-repeat:
-	next = this_parent->d_subdirs.next;
-resume:
-	while (next != &this_parent->d_subdirs) {
-		struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
-
-		/* Negative dentry - don`t care */
-		if (!simple_positive(dentry)) {
-			next = next->next;
-			continue;
-		}
-
-		if (!list_empty(&dentry->d_subdirs)) {
-			this_parent = dentry;
-			goto repeat;
-		}
-
-		next = next->next;
-		spin_unlock(&dcache_lock);
-
-		DPRINTK("dentry %p %.*s",
-			dentry, (int)dentry->d_name.len, dentry->d_name.name);
-
-		dput(dentry);
-		spin_lock(&dcache_lock);
-	}
-
-	if (this_parent != sbi->sb->s_root) {
-		struct dentry *dentry = this_parent;
-
-		next = this_parent->d_u.d_child.next;
-		this_parent = this_parent->d_parent;
-		spin_unlock(&dcache_lock);
-		DPRINTK("parent dentry %p %.*s",
-			dentry, (int)dentry->d_name.len, dentry->d_name.name);
-		dput(dentry);
-		spin_lock(&dcache_lock);
-		goto resume;
-	}
-	spin_unlock(&dcache_lock);
-}
-
 void autofs4_kill_sb(struct super_block *sb)
 {
 	struct autofs_sb_info *sbi = autofs4_sbi(sb);
@@ -170,15 +112,12 @@ void autofs4_kill_sb(struct super_block
 	/* Free wait queues, close pipe */
 	autofs4_catatonic_mode(sbi);
 
-	/* Clean up and release dangling references */
-	autofs4_force_release(sbi);
-
 	sb->s_fs_info = NULL;
 	kfree(sbi);
 
 out_kill_sb:
 	DPRINTK("shutting down");
-	kill_anon_super(sb);
+	kill_litter_super(sb);
 }
 
 static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt)
diff -druNp linux-libre-2.6.33-gnu1/fs/autofs4/root.c linux-libre-2.6.34-gnu1/fs/autofs4/root.c
--- linux-libre-2.6.33-gnu1/fs/autofs4/root.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/autofs4/root.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/capability.h>
 #include <linux/errno.h>
 #include <linux/stat.h>
+#include <linux/slab.h>
 #include <linux/param.h>
 #include <linux/time.h>
 #include "autofs_i.h"
@@ -104,99 +105,6 @@ static void autofs4_del_active(struct de
 	return;
 }
 
-static void autofs4_add_rehash_entry(struct autofs_info *ino,
-				     struct rehash_entry *entry)
-{
-	entry->task = current;
-	INIT_LIST_HEAD(&entry->list);
-	list_add(&entry->list, &ino->rehash_list);
-	return;
-}
-
-static void autofs4_remove_rehash_entry(struct autofs_info *ino)
-{
-	struct list_head *head = &ino->rehash_list;
-	struct rehash_entry *entry;
-	list_for_each_entry(entry, head, list) {
-		if (entry->task == current) {
-			list_del(&entry->list);
-			kfree(entry);
-			break;
-		}
-	}
-	return;
-}
-
-static void autofs4_remove_rehash_entrys(struct autofs_info *ino)
-{
-	struct autofs_sb_info *sbi = ino->sbi;
-	struct rehash_entry *entry, *next;
-	struct list_head *head;
-
-	spin_lock(&sbi->fs_lock);
-	spin_lock(&sbi->lookup_lock);
-	if (!(ino->flags & AUTOFS_INF_REHASH)) {
-		spin_unlock(&sbi->lookup_lock);
-		spin_unlock(&sbi->fs_lock);
-		return;
-	}
-	ino->flags &= ~AUTOFS_INF_REHASH;
-	head = &ino->rehash_list;
-	list_for_each_entry_safe(entry, next, head, list) {
-		list_del(&entry->list);
-		kfree(entry);
-	}
-	spin_unlock(&sbi->lookup_lock);
-	spin_unlock(&sbi->fs_lock);
-	dput(ino->dentry);
-
-	return;
-}
-
-static void autofs4_revalidate_drop(struct dentry *dentry,
-				    struct rehash_entry *entry)
-{
-	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
-	struct autofs_info *ino = autofs4_dentry_ino(dentry);
-	/*
-	 * Add to the active list so we can pick this up in
-	 * ->lookup(). Also add an entry to a rehash list so
-	 * we know when there are no dentrys in flight so we
-	 * know when we can rehash the dentry.
-	 */
-	spin_lock(&sbi->lookup_lock);
-	if (list_empty(&ino->active))
-		list_add(&ino->active, &sbi->active_list);
-	autofs4_add_rehash_entry(ino, entry);
-	spin_unlock(&sbi->lookup_lock);
-	if (!(ino->flags & AUTOFS_INF_REHASH)) {
-		ino->flags |= AUTOFS_INF_REHASH;
-		dget(dentry);
-		spin_lock(&dentry->d_lock);
-		__d_drop(dentry);
-		spin_unlock(&dentry->d_lock);
-	}
-	return;
-}
-
-static void autofs4_revalidate_rehash(struct dentry *dentry)
-{
-	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
-	struct autofs_info *ino = autofs4_dentry_ino(dentry);
-	if (ino->flags & AUTOFS_INF_REHASH) {
-		spin_lock(&sbi->lookup_lock);
-		autofs4_remove_rehash_entry(ino);
-		if (list_empty(&ino->rehash_list)) {
-			spin_unlock(&sbi->lookup_lock);
-			ino->flags &= ~AUTOFS_INF_REHASH;
-			d_rehash(dentry);
-			dput(ino->dentry);
-		} else
-			spin_unlock(&sbi->lookup_lock);
-	}
-	return;
-}
-
 static unsigned int autofs4_need_mount(unsigned int flags)
 {
 	unsigned int res = 0;
@@ -236,7 +144,7 @@ out:
 	return dcache_dir_open(inode, file);
 }
 
-static int try_to_fill_dentry(struct dentry *dentry)
+static int try_to_fill_dentry(struct dentry *dentry, int flags)
 {
 	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
 	struct autofs_info *ino = autofs4_dentry_ino(dentry);
@@ -249,17 +157,54 @@ static int try_to_fill_dentry(struct den
 	 * Wait for a pending mount, triggering one if there
 	 * isn't one already
 	 */
-	DPRINTK("waiting for mount name=%.*s",
-		 dentry->d_name.len, dentry->d_name.name);
+	if (dentry->d_inode == NULL) {
+		DPRINTK("waiting for mount name=%.*s",
+			 dentry->d_name.len, dentry->d_name.name);
 
-	status = autofs4_wait(sbi, dentry, NFY_MOUNT);
+		status = autofs4_wait(sbi, dentry, NFY_MOUNT);
 
-	DPRINTK("mount done status=%d", status);
+		DPRINTK("mount done status=%d", status);
 
-	/* Update expiry counter */
-	ino->last_used = jiffies;
+		/* Turn this into a real negative dentry? */
+		if (status == -ENOENT) {
+			spin_lock(&sbi->fs_lock);
+			ino->flags &= ~AUTOFS_INF_PENDING;
+			spin_unlock(&sbi->fs_lock);
+			return status;
+		} else if (status) {
+			/* Return a negative dentry, but leave it "pending" */
+			return status;
+		}
+	/* Trigger mount for path component or follow link */
+	} else if (ino->flags & AUTOFS_INF_PENDING ||
+			autofs4_need_mount(flags)) {
+		DPRINTK("waiting for mount name=%.*s",
+			dentry->d_name.len, dentry->d_name.name);
 
-	return status;
+		spin_lock(&sbi->fs_lock);
+		ino->flags |= AUTOFS_INF_PENDING;
+		spin_unlock(&sbi->fs_lock);
+		status = autofs4_wait(sbi, dentry, NFY_MOUNT);
+
+		DPRINTK("mount done status=%d", status);
+
+		if (status) {
+			spin_lock(&sbi->fs_lock);
+			ino->flags &= ~AUTOFS_INF_PENDING;
+			spin_unlock(&sbi->fs_lock);
+			return status;
+		}
+	}
+
+	/* Initialize expiry counter after successful mount */
+	if (ino)
+		ino->last_used = jiffies;
+
+	spin_lock(&sbi->fs_lock);
+	ino->flags &= ~AUTOFS_INF_PENDING;
+	spin_unlock(&sbi->fs_lock);
+
+	return 0;
 }
 
 /* For autofs direct mounts the follow link triggers the mount */
@@ -313,16 +258,10 @@ static void *autofs4_follow_link(struct
 	 */
 	if (ino->flags & AUTOFS_INF_PENDING ||
 	    (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs))) {
-		ino->flags |= AUTOFS_INF_PENDING;
 		spin_unlock(&dcache_lock);
 		spin_unlock(&sbi->fs_lock);
 
-		status = try_to_fill_dentry(dentry);
-
-		spin_lock(&sbi->fs_lock);
-		ino->flags &= ~AUTOFS_INF_PENDING;
-		spin_unlock(&sbi->fs_lock);
-
+		status = try_to_fill_dentry(dentry, nd->flags);
 		if (status)
 			goto out_error;
 
@@ -361,47 +300,18 @@ static int autofs4_revalidate(struct den
 {
 	struct inode *dir = dentry->d_parent->d_inode;
 	struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
-	struct autofs_info *ino = autofs4_dentry_ino(dentry);
-	struct rehash_entry *entry;
+	int oz_mode = autofs4_oz_mode(sbi);
 	int flags = nd ? nd->flags : 0;
-	unsigned int mutex_aquired;
-
-	DPRINTK("name = %.*s oz_mode = %d",
-		dentry->d_name.len, dentry->d_name.name, oz_mode);
-
-	/* Daemon never causes a mount to trigger */
-	if (autofs4_oz_mode(sbi))
-		return 1;
-
-	entry = kmalloc(sizeof(struct rehash_entry), GFP_KERNEL);
-	if (!entry)
-		return -ENOMEM;
-
-	mutex_aquired = mutex_trylock(&dir->i_mutex);
+	int status = 1;
 
-	spin_lock(&sbi->fs_lock);
-	spin_lock(&dcache_lock);
 	/* Pending dentry */
+	spin_lock(&sbi->fs_lock);
 	if (autofs4_ispending(dentry)) {
-		int status;
-
-		/*
-		 * We can only unhash and send this to ->lookup() if
-		 * the directory mutex is held over d_revalidate() and
-		 * ->lookup(). This prevents the VFS from incorrectly
-		 * seeing the dentry as non-existent.
-		 */
-		ino->flags |= AUTOFS_INF_PENDING;
-		if (!mutex_aquired) {
-			autofs4_revalidate_drop(dentry, entry);
-			spin_unlock(&dcache_lock);
-			spin_unlock(&sbi->fs_lock);
-			return 0;
-		}
-		spin_unlock(&dcache_lock);
+		/* The daemon never causes a mount to trigger */
 		spin_unlock(&sbi->fs_lock);
-		mutex_unlock(&dir->i_mutex);
-		kfree(entry);
+
+		if (oz_mode)
+			return 1;
 
 		/*
 		 * If the directory has gone away due to an expire
@@ -415,82 +325,45 @@ static int autofs4_revalidate(struct den
 		 * A zero status is success otherwise we have a
 		 * negative error code.
 		 */
-		status = try_to_fill_dentry(dentry);
-
-		spin_lock(&sbi->fs_lock);
-		ino->flags &= ~AUTOFS_INF_PENDING;
-		spin_unlock(&sbi->fs_lock);
-
+		status = try_to_fill_dentry(dentry, flags);
 		if (status == 0)
 			return 1;
 
 		return status;
 	}
+	spin_unlock(&sbi->fs_lock);
+
+	/* Negative dentry.. invalidate if "old" */
+	if (dentry->d_inode == NULL)
+		return 0;
 
 	/* Check for a non-mountpoint directory with no contents */
+	spin_lock(&dcache_lock);
 	if (S_ISDIR(dentry->d_inode->i_mode) &&
 	    !d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) {
 		DPRINTK("dentry=%p %.*s, emptydir",
 			 dentry, dentry->d_name.len, dentry->d_name.name);
+		spin_unlock(&dcache_lock);
 
-		if (autofs4_need_mount(flags) || current->link_count) {
-			int status;
-
-			/*
-			 * We can only unhash and send this to ->lookup() if
-			 * the directory mutex is held over d_revalidate() and
-			 * ->lookup(). This prevents the VFS from incorrectly
-			 * seeing the dentry as non-existent.
-			 */
-			ino->flags |= AUTOFS_INF_PENDING;
-			if (!mutex_aquired) {
-				autofs4_revalidate_drop(dentry, entry);
-				spin_unlock(&dcache_lock);
-				spin_unlock(&sbi->fs_lock);
-				return 0;
-			}
-			spin_unlock(&dcache_lock);
-			spin_unlock(&sbi->fs_lock);
-			mutex_unlock(&dir->i_mutex);
-			kfree(entry);
-
-			/*
-			 * A zero status is success otherwise we have a
-			 * negative error code.
-			 */
-			status = try_to_fill_dentry(dentry);
-
-			spin_lock(&sbi->fs_lock);
-			ino->flags &= ~AUTOFS_INF_PENDING;
-			spin_unlock(&sbi->fs_lock);
+		/* The daemon never causes a mount to trigger */
+		if (oz_mode)
+			return 1;
 
-			if (status == 0)
-				return 1;
+		/*
+		 * A zero status is success otherwise we have a
+		 * negative error code.
+		 */
+		status = try_to_fill_dentry(dentry, flags);
+		if (status == 0)
+			return 1;
 
-			return status;
-		}
+		return status;
 	}
 	spin_unlock(&dcache_lock);
-	spin_unlock(&sbi->fs_lock);
-
-	if (mutex_aquired)
-		mutex_unlock(&dir->i_mutex);
-
-	kfree(entry);
 
 	return 1;
 }
 
-static void autofs4_free_rehash_entrys(struct autofs_info *inf)
-{
-	struct list_head *head = &inf->rehash_list;
-	struct rehash_entry *entry, *next;
-	list_for_each_entry_safe(entry, next, head, list) {
-		list_del(&entry->list);
-		kfree(entry);
-	}
-}
-
 void autofs4_dentry_release(struct dentry *de)
 {
 	struct autofs_info *inf;
@@ -509,8 +382,6 @@ void autofs4_dentry_release(struct dentr
 				list_del(&inf->active);
 			if (!list_empty(&inf->expiring))
 				list_del(&inf->expiring);
-			if (!list_empty(&inf->rehash_list))
-				autofs4_free_rehash_entrys(inf);
 			spin_unlock(&sbi->lookup_lock);
 		}
 
@@ -543,7 +414,6 @@ static struct dentry *autofs4_lookup_act
 	const unsigned char *str = name->name;
 	struct list_head *p, *head;
 
-restart:
 	spin_lock(&dcache_lock);
 	spin_lock(&sbi->lookup_lock);
 	head = &sbi->active_list;
@@ -561,19 +431,6 @@ restart:
 		if (atomic_read(&active->d_count) == 0)
 			goto next;
 
-		if (active->d_inode && IS_DEADDIR(active->d_inode)) {
-			if (!list_empty(&ino->rehash_list)) {
-				dget(active);
-				spin_unlock(&active->d_lock);
-				spin_unlock(&sbi->lookup_lock);
-				spin_unlock(&dcache_lock);
-				autofs4_remove_rehash_entrys(ino);
-				dput(active);
-				goto restart;
-			}
-			goto next;
-		}
-
 		qstr = &active->d_name;
 
 		if (active->d_name.hash != hash)
@@ -586,11 +443,13 @@ restart:
 		if (memcmp(qstr->name, str, len))
 			goto next;
 
-		dget(active);
-		spin_unlock(&active->d_lock);
-		spin_unlock(&sbi->lookup_lock);
-		spin_unlock(&dcache_lock);
-		return active;
+		if (d_unhashed(active)) {
+			dget(active);
+			spin_unlock(&active->d_lock);
+			spin_unlock(&sbi->lookup_lock);
+			spin_unlock(&dcache_lock);
+			return active;
+		}
 next:
 		spin_unlock(&active->d_lock);
 	}
@@ -639,11 +498,13 @@ static struct dentry *autofs4_lookup_exp
 		if (memcmp(qstr->name, str, len))
 			goto next;
 
-		dget(expiring);
-		spin_unlock(&expiring->d_lock);
-		spin_unlock(&sbi->lookup_lock);
-		spin_unlock(&dcache_lock);
-		return expiring;
+		if (d_unhashed(expiring)) {
+			dget(expiring);
+			spin_unlock(&expiring->d_lock);
+			spin_unlock(&sbi->lookup_lock);
+			spin_unlock(&dcache_lock);
+			return expiring;
+		}
 next:
 		spin_unlock(&expiring->d_lock);
 	}
@@ -653,48 +514,6 @@ next:
 	return NULL;
 }
 
-static struct autofs_info *init_new_dentry(struct autofs_sb_info *sbi,
-					   struct dentry *dentry, int oz_mode)
-{
-	struct autofs_info *ino;
-
-	/*
-	 * Mark the dentry incomplete but don't hash it. We do this
-	 * to serialize our inode creation operations (symlink and
-	 * mkdir) which prevents deadlock during the callback to
-	 * the daemon. Subsequent user space lookups for the same
-	 * dentry are placed on the wait queue while the daemon
-	 * itself is allowed passage unresticted so the create
-	 * operation itself can then hash the dentry. Finally,
-	 * we check for the hashed dentry and return the newly
-	 * hashed dentry.
-	 */
-	dentry->d_op = &autofs4_root_dentry_operations;
-
-	/*
-	 * And we need to ensure that the same dentry is used for
-	 * all following lookup calls until it is hashed so that
-	 * the dentry flags are persistent throughout the request.
-	 */
-	ino = autofs4_init_ino(NULL, sbi, 0555);
-	if (!ino)
-		return ERR_PTR(-ENOMEM);
-
-	dentry->d_fsdata = ino;
-	ino->dentry = dentry;
-
-	/*
-	 * Only set the mount pending flag for new dentrys not created
-	 * by the daemon.
-	 */
-	if (!oz_mode)
-		ino->flags |= AUTOFS_INF_PENDING;
-
-	d_instantiate(dentry, NULL);
-
-	return ino;
-}
-
 /* Lookups in the root directory */
 static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 {
@@ -702,7 +521,6 @@ static struct dentry *autofs4_lookup(str
 	struct autofs_info *ino;
 	struct dentry *expiring, *active;
 	int oz_mode;
-	int status = 0;
 
 	DPRINTK("name = %.*s",
 		dentry->d_name.len, dentry->d_name.name);
@@ -717,26 +535,44 @@ static struct dentry *autofs4_lookup(str
 	DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d",
 		 current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode);
 
-	spin_lock(&sbi->fs_lock);
 	active = autofs4_lookup_active(dentry);
 	if (active) {
 		dentry = active;
 		ino = autofs4_dentry_ino(dentry);
-		/* If this came from revalidate, rehash it */
-		autofs4_revalidate_rehash(dentry);
-		spin_unlock(&sbi->fs_lock);
 	} else {
-		spin_unlock(&sbi->fs_lock);
-		ino = init_new_dentry(sbi, dentry, oz_mode);
-		if (IS_ERR(ino))
-			return (struct dentry *) ino;
-	}
+		/*
+		 * Mark the dentry incomplete but don't hash it. We do this
+		 * to serialize our inode creation operations (symlink and
+		 * mkdir) which prevents deadlock during the callback to
+		 * the daemon. Subsequent user space lookups for the same
+		 * dentry are placed on the wait queue while the daemon
+		 * itself is allowed passage unresticted so the create
+		 * operation itself can then hash the dentry. Finally,
+		 * we check for the hashed dentry and return the newly
+		 * hashed dentry.
+		 */
+		dentry->d_op = &autofs4_root_dentry_operations;
 
-	autofs4_add_active(dentry);
+		/*
+		 * And we need to ensure that the same dentry is used for
+		 * all following lookup calls until it is hashed so that
+		 * the dentry flags are persistent throughout the request.
+		 */
+		ino = autofs4_init_ino(NULL, sbi, 0555);
+		if (!ino)
+			return ERR_PTR(-ENOMEM);
+
+		dentry->d_fsdata = ino;
+		ino->dentry = dentry;
+
+		autofs4_add_active(dentry);
+
+		d_instantiate(dentry, NULL);
+	}
 
 	if (!oz_mode) {
-		expiring = autofs4_lookup_expiring(dentry);
 		mutex_unlock(&dir->i_mutex);
+		expiring = autofs4_lookup_expiring(dentry);
 		if (expiring) {
 			/*
 			 * If we are racing with expire the request might not
@@ -744,22 +580,23 @@ static struct dentry *autofs4_lookup(str
 			 * so it must have been successful, so just wait for it.
 			 */
 			autofs4_expire_wait(expiring);
+			autofs4_del_expiring(expiring);
 			dput(expiring);
 		}
-		status = try_to_fill_dentry(dentry);
-		mutex_lock(&dir->i_mutex);
+
 		spin_lock(&sbi->fs_lock);
-		ino->flags &= ~AUTOFS_INF_PENDING;
+		ino->flags |= AUTOFS_INF_PENDING;
 		spin_unlock(&sbi->fs_lock);
+		if (dentry->d_op && dentry->d_op->d_revalidate)
+			(dentry->d_op->d_revalidate)(dentry, nd);
+		mutex_lock(&dir->i_mutex);
 	}
 
-	autofs4_del_active(dentry);
-
 	/*
-	 * If we had a mount fail, check if we had to handle
+	 * If we are still pending, check if we had to handle
 	 * a signal. If so we can force a restart..
 	 */
-	if (status) {
+	if (ino->flags & AUTOFS_INF_PENDING) {
 		/* See if we were interrupted */
 		if (signal_pending(current)) {
 			sigset_t *sigset = &current->pending.signal;
@@ -771,46 +608,43 @@ static struct dentry *autofs4_lookup(str
 			    return ERR_PTR(-ERESTARTNOINTR);
 			}
 		}
-	}
-
-	/*
-	 * User space can (and has done in the past) remove and re-create
-	 * this directory during the callback. This can leave us with an
-	 * unhashed dentry, but a successful mount!  So we need to
-	 * perform another cached lookup in case the dentry now exists.
-	 */
-	if (!oz_mode && !have_submounts(dentry)) {
-		struct dentry *new;
-		new = d_lookup(dentry->d_parent, &dentry->d_name);
-		if (new) {
-			if (active)
-				dput(active);
-			return new;
-		} else {
-			if (!status)
-				status = -ENOENT;
+		if (!oz_mode) {
+			spin_lock(&sbi->fs_lock);
+			ino->flags &= ~AUTOFS_INF_PENDING;
+			spin_unlock(&sbi->fs_lock);
 		}
 	}
 
 	/*
-	 * If we had a mount failure, return status to user space.
-	 * If the mount succeeded and we used a dentry from the active queue
-	 * return it.
+	 * If this dentry is unhashed, then we shouldn't honour this
+	 * lookup.  Returning ENOENT here doesn't do the right thing
+	 * for all system calls, but it should be OK for the operations
+	 * we permit from an autofs.
 	 */
-	if (status) {
-		dentry = ERR_PTR(status);
-		if (active)
-			dput(active);
-		return dentry;
-	} else {
+	if (!oz_mode && d_unhashed(dentry)) {
 		/*
-		 * Valid successful mount, return active dentry or NULL
-		 * for a new dentry.
+		 * A user space application can (and has done in the past)
+		 * remove and re-create this directory during the callback.
+		 * This can leave us with an unhashed dentry, but a
+		 * successful mount!  So we need to perform another
+		 * cached lookup in case the dentry now exists.
 		 */
+		struct dentry *parent = dentry->d_parent;
+		struct dentry *new = d_lookup(parent, &dentry->d_name);
+		if (new != NULL)
+			dentry = new;
+		else
+			dentry = ERR_PTR(-ENOENT);
+
 		if (active)
-			return active;
+			dput(active);
+
+		return dentry;
 	}
 
+	if (active)
+		return active;
+
 	return NULL;
 }
 
@@ -834,6 +668,8 @@ static int autofs4_dir_symlink(struct in
 	if (!ino)
 		return -ENOMEM;
 
+	autofs4_del_active(dentry);
+
 	ino->size = strlen(symname);
 	cp = kmalloc(ino->size + 1, GFP_KERNEL);
 	if (!cp) {
@@ -910,6 +746,7 @@ static int autofs4_dir_unlink(struct ino
 	dir->i_mtime = CURRENT_TIME;
 
 	spin_lock(&dcache_lock);
+	autofs4_add_expiring(dentry);
 	spin_lock(&dentry->d_lock);
 	__d_drop(dentry);
 	spin_unlock(&dentry->d_lock);
@@ -935,6 +772,7 @@ static int autofs4_dir_rmdir(struct inod
 		spin_unlock(&dcache_lock);
 		return -ENOTEMPTY;
 	}
+	autofs4_add_expiring(dentry);
 	spin_lock(&dentry->d_lock);
 	__d_drop(dentry);
 	spin_unlock(&dentry->d_lock);
@@ -972,6 +810,8 @@ static int autofs4_dir_mkdir(struct inod
 	if (!ino)
 		return -ENOMEM;
 
+	autofs4_del_active(dentry);
+
 	inode = autofs4_get_inode(dir->i_sb, ino);
 	if (!inode) {
 		if (!dentry->d_fsdata)
diff -druNp linux-libre-2.6.33-gnu1/fs/befs/datastream.c linux-libre-2.6.34-gnu1/fs/befs/datastream.c
--- linux-libre-2.6.33-gnu1/fs/befs/datastream.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/befs/datastream.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/buffer_head.h>
 #include <linux/string.h>
 
diff -druNp linux-libre-2.6.33-gnu1/fs/bfs/inode.c linux-libre-2.6.34-gnu1/fs/bfs/inode.c
--- linux-libre-2.6.33-gnu1/fs/bfs/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/bfs/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/vfs.h>
+#include <linux/writeback.h>
 #include <asm/uaccess.h>
 #include "bfs.h"
 
@@ -98,7 +99,7 @@ error:
 	return ERR_PTR(-EIO);
 }
 
-static int bfs_write_inode(struct inode *inode, int wait)
+static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
 	struct bfs_sb_info *info = BFS_SB(inode->i_sb);
 	unsigned int ino = (u16)inode->i_ino;
@@ -147,7 +148,7 @@ static int bfs_write_inode(struct inode
 	di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1);
 
 	mark_buffer_dirty(bh);
-	if (wait) {
+	if (wbc->sync_mode == WB_SYNC_ALL) {
 		sync_dirty_buffer(bh);
 		if (buffer_req(bh) && !buffer_uptodate(bh))
 			err = -EIO;
diff -druNp linux-libre-2.6.33-gnu1/fs/binfmt_aout.c linux-libre-2.6.34-gnu1/fs/binfmt_aout.c
--- linux-libre-2.6.33-gnu1/fs/binfmt_aout.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/binfmt_aout.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,10 +20,11 @@
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
-#include <linux/slab.h>
 #include <linux/binfmts.h>
 #include <linux/personality.h>
 #include <linux/init.h>
+#include <linux/coredump.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -60,26 +61,6 @@ static int set_brk(unsigned long start,
 }
 
 /*
- * These are the only things you should do on a core-file: use only these
- * macros to write out all the necessary info.
- */
-
-static int dump_write(struct file *file, const void *addr, int nr)
-{
-	return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
-}
-
-#define DUMP_WRITE(addr, nr)	\
-	if (!dump_write(file, (void *)(addr), (nr))) \
-		goto end_coredump;
-
-#define DUMP_SEEK(offset) \
-if (file->f_op->llseek) { \
-	if (file->f_op->llseek(file,(offset),0) != (offset)) \
- 		goto end_coredump; \
-} else file->f_pos = (offset)
-
-/*
  * Routine writes a core dump image in the current directory.
  * Currently only a stub-function.
  *
@@ -94,14 +75,16 @@ static int aout_core_dump(struct coredum
 	struct file *file = cprm->file;
 	mm_segment_t fs;
 	int has_dumped = 0;
-	unsigned long dump_start, dump_size;
+	void __user *dump_start;
+	int dump_size;
 	struct user dump;
 #ifdef __alpha__
-#       define START_DATA(u)	(u.start_data)
+#       define START_DATA(u)	((void __user *)u.start_data)
 #else
-#	define START_DATA(u)	((u.u_tsize << PAGE_SHIFT) + u.start_code)
+#	define START_DATA(u)	((void __user *)((u.u_tsize << PAGE_SHIFT) + \
+				 u.start_code))
 #endif
-#       define START_STACK(u)   (u.start_stack)
+#       define START_STACK(u)   ((void __user *)u.start_stack)
 
 	fs = get_fs();
 	set_fs(KERNEL_DS);
@@ -123,33 +106,38 @@ static int aout_core_dump(struct coredum
 
 /* make sure we actually have a data and stack area to dump */
 	set_fs(USER_DS);
-	if (!access_ok(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
+	if (!access_ok(VERIFY_READ, START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
 		dump.u_dsize = 0;
-	if (!access_ok(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize << PAGE_SHIFT))
+	if (!access_ok(VERIFY_READ, START_STACK(dump), dump.u_ssize << PAGE_SHIFT))
 		dump.u_ssize = 0;
 
 	set_fs(KERNEL_DS);
 /* struct user */
-	DUMP_WRITE(&dump,sizeof(dump));
+	if (!dump_write(file, &dump, sizeof(dump)))
+		goto end_coredump;
 /* Now dump all of the user data.  Include malloced stuff as well */
-	DUMP_SEEK(PAGE_SIZE);
+	if (!dump_seek(cprm->file, PAGE_SIZE - sizeof(dump)))
+		goto end_coredump;
 /* now we start writing out the user space info */
 	set_fs(USER_DS);
 /* Dump the data area */
 	if (dump.u_dsize != 0) {
 		dump_start = START_DATA(dump);
 		dump_size = dump.u_dsize << PAGE_SHIFT;
-		DUMP_WRITE(dump_start,dump_size);
+		if (!dump_write(file, dump_start, dump_size))
+			goto end_coredump;
 	}
 /* Now prepare to dump the stack area */
 	if (dump.u_ssize != 0) {
 		dump_start = START_STACK(dump);
 		dump_size = dump.u_ssize << PAGE_SHIFT;
-		DUMP_WRITE(dump_start,dump_size);
+		if (!dump_write(file, dump_start, dump_size))
+			goto end_coredump;
 	}
 /* Finally dump the task struct.  Not be used by gdb, but could be useful */
 	set_fs(KERNEL_DS);
-	DUMP_WRITE(current,sizeof(*current));
+	if (!dump_write(file, current, sizeof(*current)))
+		goto end_coredump;
 end_coredump:
 	set_fs(fs);
 	return has_dumped;
@@ -247,7 +235,7 @@ static int load_aout_binary(struct linux
 	 * size limits imposed on them by creating programs with large
 	 * arrays in the data or bss.
 	 */
-	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
+	rlim = rlimit(RLIMIT_DATA);
 	if (rlim >= RLIM_INFINITY)
 		rlim = ~0;
 	if (ex.a_data + ex.a_bss > rlim)
diff -druNp linux-libre-2.6.33-gnu1/fs/binfmt_elf.c linux-libre-2.6.34-gnu1/fs/binfmt_elf.c
--- linux-libre-2.6.33-gnu1/fs/binfmt_elf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/binfmt_elf.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/random.h>
 #include <linux/elf.h>
 #include <linux/utsname.h>
+#include <linux/coredump.h>
 #include <asm/uaccess.h>
 #include <asm/param.h>
 #include <asm/page.h>
@@ -1085,36 +1086,6 @@ out:
  * Modelled on fs/exec.c:aout_core_dump()
  * Jeremy Fitzhardinge <jeremy@sw.oz.au>
  */
-/*
- * These are the only things you should do on a core-file: use only these
- * functions to write out all the necessary info.
- */
-static int dump_write(struct file *file, const void *addr, int nr)
-{
-	return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
-}
-
-static int dump_seek(struct file *file, loff_t off)
-{
-	if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
-		if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
-			return 0;
-	} else {
-		char *buf = (char *)get_zeroed_page(GFP_KERNEL);
-		if (!buf)
-			return 0;
-		while (off > 0) {
-			unsigned long n = off;
-			if (n > PAGE_SIZE)
-				n = PAGE_SIZE;
-			if (!dump_write(file, buf, n))
-				return 0;
-			off -= n;
-		}
-		free_page((unsigned long)buf);
-	}
-	return 1;
-}
 
 /*
  * Decide what to dump of a segment, part, all or none.
@@ -1249,11 +1220,6 @@ static int writenote(struct memelfnote *
 }
 #undef DUMP_WRITE
 
-#define DUMP_WRITE(addr, nr)				\
-	if ((size += (nr)) > cprm->limit ||		\
-	    !dump_write(cprm->file, (addr), (nr)))	\
-		goto end_coredump;
-
 static void fill_elf_header(struct elfhdr *elf, int segs,
 			    u16 machine, u32 flags, u8 osabi)
 {
@@ -1872,6 +1838,34 @@ static struct vm_area_struct *next_vma(s
 	return gate_vma;
 }
 
+static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
+			     elf_addr_t e_shoff, int segs)
+{
+	elf->e_shoff = e_shoff;
+	elf->e_shentsize = sizeof(*shdr4extnum);
+	elf->e_shnum = 1;
+	elf->e_shstrndx = SHN_UNDEF;
+
+	memset(shdr4extnum, 0, sizeof(*shdr4extnum));
+
+	shdr4extnum->sh_type = SHT_NULL;
+	shdr4extnum->sh_size = elf->e_shnum;
+	shdr4extnum->sh_link = elf->e_shstrndx;
+	shdr4extnum->sh_info = segs;
+}
+
+static size_t elf_core_vma_data_size(struct vm_area_struct *gate_vma,
+				     unsigned long mm_flags)
+{
+	struct vm_area_struct *vma;
+	size_t size = 0;
+
+	for (vma = first_vma(current, gate_vma); vma != NULL;
+	     vma = next_vma(vma, gate_vma))
+		size += vma_dump_size(vma, mm_flags);
+	return size;
+}
+
 /*
  * Actual dumper
  *
@@ -1888,8 +1882,11 @@ static int elf_core_dump(struct coredump
 	struct vm_area_struct *vma, *gate_vma;
 	struct elfhdr *elf = NULL;
 	loff_t offset = 0, dataoff, foffset;
-	unsigned long mm_flags;
 	struct elf_note_info info;
+	struct elf_phdr *phdr4note = NULL;
+	struct elf_shdr *shdr4extnum = NULL;
+	Elf_Half e_phnum;
+	elf_addr_t e_shoff;
 
 	/*
 	 * We no longer stop all VM operations.
@@ -1912,20 +1909,25 @@ static int elf_core_dump(struct coredump
 	 * Please check DEFAULT_MAX_MAP_COUNT definition when you modify here.
 	 */
 	segs = current->mm->map_count;
-#ifdef ELF_CORE_EXTRA_PHDRS
-	segs += ELF_CORE_EXTRA_PHDRS;
-#endif
+	segs += elf_core_extra_phdrs();
 
 	gate_vma = get_gate_vma(current);
 	if (gate_vma != NULL)
 		segs++;
 
+	/* for notes section */
+	segs++;
+
+	/* If segs > PN_XNUM(0xffff), then e_phnum overflows. To avoid
+	 * this, kernel supports extended numbering. Have a look at
+	 * include/linux/elf.h for further information. */
+	e_phnum = segs > PN_XNUM ? PN_XNUM : segs;
+
 	/*
 	 * Collect all the non-memory information about the process for the
 	 * notes.  This also sets up the file header.
 	 */
-	if (!fill_note_info(elf, segs + 1, /* including notes section */
-			    &info, cprm->signr, cprm->regs))
+	if (!fill_note_info(elf, e_phnum, &info, cprm->signr, cprm->regs))
 		goto cleanup;
 
 	has_dumped = 1;
@@ -1934,31 +1936,47 @@ static int elf_core_dump(struct coredump
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 
-	DUMP_WRITE(elf, sizeof(*elf));
 	offset += sizeof(*elf);				/* Elf header */
-	offset += (segs + 1) * sizeof(struct elf_phdr); /* Program headers */
+	offset += segs * sizeof(struct elf_phdr);	/* Program headers */
 	foffset = offset;
 
 	/* Write notes phdr entry */
 	{
-		struct elf_phdr phdr;
 		size_t sz = get_note_info_size(&info);
 
 		sz += elf_coredump_extra_notes_size();
 
-		fill_elf_note_phdr(&phdr, sz, offset);
+		phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
+		if (!phdr4note)
+			goto end_coredump;
+
+		fill_elf_note_phdr(phdr4note, sz, offset);
 		offset += sz;
-		DUMP_WRITE(&phdr, sizeof(phdr));
 	}
 
 	dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
 
-	/*
-	 * We must use the same mm->flags while dumping core to avoid
-	 * inconsistency between the program headers and bodies, otherwise an
-	 * unusable core file can be generated.
-	 */
-	mm_flags = current->mm->flags;
+	offset += elf_core_vma_data_size(gate_vma, cprm->mm_flags);
+	offset += elf_core_extra_data_size();
+	e_shoff = offset;
+
+	if (e_phnum == PN_XNUM) {
+		shdr4extnum = kmalloc(sizeof(*shdr4extnum), GFP_KERNEL);
+		if (!shdr4extnum)
+			goto end_coredump;
+		fill_extnum_info(elf, shdr4extnum, e_shoff, segs);
+	}
+
+	offset = dataoff;
+
+	size += sizeof(*elf);
+	if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf)))
+		goto end_coredump;
+
+	size += sizeof(*phdr4note);
+	if (size > cprm->limit
+	    || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
+		goto end_coredump;
 
 	/* Write program headers for segments dump */
 	for (vma = first_vma(current, gate_vma); vma != NULL;
@@ -1969,7 +1987,7 @@ static int elf_core_dump(struct coredump
 		phdr.p_offset = offset;
 		phdr.p_vaddr = vma->vm_start;
 		phdr.p_paddr = 0;
-		phdr.p_filesz = vma_dump_size(vma, mm_flags);
+		phdr.p_filesz = vma_dump_size(vma, cprm->mm_flags);
 		phdr.p_memsz = vma->vm_end - vma->vm_start;
 		offset += phdr.p_filesz;
 		phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
@@ -1979,12 +1997,14 @@ static int elf_core_dump(struct coredump
 			phdr.p_flags |= PF_X;
 		phdr.p_align = ELF_EXEC_PAGESIZE;
 
-		DUMP_WRITE(&phdr, sizeof(phdr));
+		size += sizeof(phdr);
+		if (size > cprm->limit
+		    || !dump_write(cprm->file, &phdr, sizeof(phdr)))
+			goto end_coredump;
 	}
 
-#ifdef ELF_CORE_WRITE_EXTRA_PHDRS
-	ELF_CORE_WRITE_EXTRA_PHDRS;
-#endif
+	if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit))
+		goto end_coredump;
 
  	/* write out the notes section */
 	if (!write_note_info(&info, cprm->file, &foffset))
@@ -2002,7 +2022,7 @@ static int elf_core_dump(struct coredump
 		unsigned long addr;
 		unsigned long end;
 
-		end = vma->vm_start + vma_dump_size(vma, mm_flags);
+		end = vma->vm_start + vma_dump_size(vma, cprm->mm_flags);
 
 		for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
 			struct page *page;
@@ -2023,15 +2043,24 @@ static int elf_core_dump(struct coredump
 		}
 	}
 
-#ifdef ELF_CORE_WRITE_EXTRA_DATA
-	ELF_CORE_WRITE_EXTRA_DATA;
-#endif
+	if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit))
+		goto end_coredump;
+
+	if (e_phnum == PN_XNUM) {
+		size += sizeof(*shdr4extnum);
+		if (size > cprm->limit
+		    || !dump_write(cprm->file, shdr4extnum,
+				   sizeof(*shdr4extnum)))
+			goto end_coredump;
+	}
 
 end_coredump:
 	set_fs(fs);
 
 cleanup:
 	free_note_info(&info);
+	kfree(shdr4extnum);
+	kfree(phdr4note);
 	kfree(elf);
 out:
 	return has_dumped;
diff -druNp linux-libre-2.6.33-gnu1/fs/binfmt_elf_fdpic.c linux-libre-2.6.34-gnu1/fs/binfmt_elf_fdpic.c
--- linux-libre-2.6.33-gnu1/fs/binfmt_elf_fdpic.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/binfmt_elf_fdpic.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/elf.h>
 #include <linux/elf-fdpic.h>
 #include <linux/elfcore.h>
+#include <linux/coredump.h>
 
 #include <asm/uaccess.h>
 #include <asm/param.h>
@@ -1004,15 +1005,8 @@ static int elf_fdpic_map_file_constdisp_
 				}
 			} else if (!mm->start_data) {
 				mm->start_data = seg->addr;
-#ifndef CONFIG_MMU
 				mm->end_data = seg->addr + phdr->p_memsz;
-#endif
 			}
-
-#ifdef CONFIG_MMU
-			if (seg->addr + phdr->p_memsz > mm->end_data)
-				mm->end_data = seg->addr + phdr->p_memsz;
-#endif
 		}
 
 		seg++;
@@ -1216,26 +1210,6 @@ static int elf_fdpic_map_file_by_direct_
 #ifdef CONFIG_ELF_CORE
 
 /*
- * These are the only things you should do on a core-file: use only these
- * functions to write out all the necessary info.
- */
-static int dump_write(struct file *file, const void *addr, int nr)
-{
-	return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
-}
-
-static int dump_seek(struct file *file, loff_t off)
-{
-	if (file->f_op->llseek) {
-		if (file->f_op->llseek(file, off, SEEK_SET) != off)
-			return 0;
-	} else {
-		file->f_pos = off;
-	}
-	return 1;
-}
-
-/*
  * Decide whether a segment is worth dumping; default is yes to be
  * sure (missing info is worse than too much; etc).
  * Personally I'd include everything, and use the coredump limit...
@@ -1313,35 +1287,35 @@ static int notesize(struct memelfnote *e
 
 /* #define DEBUG */
 
-#define DUMP_WRITE(addr, nr)	\
-	do { if (!dump_write(file, (addr), (nr))) return 0; } while(0)
-#define DUMP_SEEK(off)	\
-	do { if (!dump_seek(file, (off))) return 0; } while(0)
+#define DUMP_WRITE(addr, nr, foffset)	\
+	do { if (!dump_write(file, (addr), (nr))) return 0; *foffset += (nr); } while(0)
 
-static int writenote(struct memelfnote *men, struct file *file)
+static int alignfile(struct file *file, loff_t *foffset)
 {
-	struct elf_note en;
+	static const char buf[4] = { 0, };
+	DUMP_WRITE(buf, roundup(*foffset, 4) - *foffset, foffset);
+	return 1;
+}
 
+static int writenote(struct memelfnote *men, struct file *file,
+			loff_t *foffset)
+{
+	struct elf_note en;
 	en.n_namesz = strlen(men->name) + 1;
 	en.n_descsz = men->datasz;
 	en.n_type = men->type;
 
-	DUMP_WRITE(&en, sizeof(en));
-	DUMP_WRITE(men->name, en.n_namesz);
-	/* XXX - cast from long long to long to avoid need for libgcc.a */
-	DUMP_SEEK(roundup((unsigned long)file->f_pos, 4));	/* XXX */
-	DUMP_WRITE(men->data, men->datasz);
-	DUMP_SEEK(roundup((unsigned long)file->f_pos, 4));	/* XXX */
+	DUMP_WRITE(&en, sizeof(en), foffset);
+	DUMP_WRITE(men->name, en.n_namesz, foffset);
+	if (!alignfile(file, foffset))
+		return 0;
+	DUMP_WRITE(men->data, men->datasz, foffset);
+	if (!alignfile(file, foffset))
+		return 0;
 
 	return 1;
 }
 #undef DUMP_WRITE
-#undef DUMP_SEEK
-
-#define DUMP_WRITE(addr, nr)				\
-	if ((size += (nr)) > cprm->limit ||		\
-	    !dump_write(cprm->file, (addr), (nr)))	\
-		goto end_coredump;
 
 static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs)
 {
@@ -1393,7 +1367,7 @@ static inline void fill_note(struct meme
 
 /*
  * fill up all the fields in prstatus from the given task struct, except
- * registers which need to be filled up seperately.
+ * registers which need to be filled up separately.
  */
 static void fill_prstatus(struct elf_prstatus *prstatus,
 			  struct task_struct *p, long signr)
@@ -1524,6 +1498,22 @@ static int elf_dump_thread_status(long s
 	return sz;
 }
 
+static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
+			     elf_addr_t e_shoff, int segs)
+{
+	elf->e_shoff = e_shoff;
+	elf->e_shentsize = sizeof(*shdr4extnum);
+	elf->e_shnum = 1;
+	elf->e_shstrndx = SHN_UNDEF;
+
+	memset(shdr4extnum, 0, sizeof(*shdr4extnum));
+
+	shdr4extnum->sh_type = SHT_NULL;
+	shdr4extnum->sh_size = elf->e_shnum;
+	shdr4extnum->sh_link = elf->e_shstrndx;
+	shdr4extnum->sh_info = segs;
+}
+
 /*
  * dump the segments for an MMU process
  */
@@ -1552,7 +1542,7 @@ static int elf_fdpic_dump_segments(struc
 					err = -EIO;
 				kunmap(page);
 				page_cache_release(page);
-			} else if (!dump_seek(file, file->f_pos + PAGE_SIZE))
+			} else if (!dump_seek(file, PAGE_SIZE))
 				err = -EFBIG;
 			if (err)
 				goto out;
@@ -1588,6 +1578,17 @@ static int elf_fdpic_dump_segments(struc
 }
 #endif
 
+static size_t elf_core_vma_data_size(unsigned long mm_flags)
+{
+	struct vm_area_struct *vma;
+	size_t size = 0;
+
+	for (vma = current->mm->mmap; vma; vma = vma->vm_next)
+		if (maydump(vma, mm_flags))
+			size += vma->vm_end - vma->vm_start;
+	return size;
+}
+
 /*
  * Actual dumper
  *
@@ -1605,7 +1606,7 @@ static int elf_fdpic_core_dump(struct co
 	int i;
 	struct vm_area_struct *vma;
 	struct elfhdr *elf = NULL;
-	loff_t offset = 0, dataoff;
+	loff_t offset = 0, dataoff, foffset;
 	int numnote;
 	struct memelfnote *notes = NULL;
 	struct elf_prstatus *prstatus = NULL;	/* NT_PRSTATUS */
@@ -1618,7 +1619,10 @@ static int elf_fdpic_core_dump(struct co
 #endif
 	int thread_status_size = 0;
 	elf_addr_t *auxv;
-	unsigned long mm_flags;
+	struct elf_phdr *phdr4note = NULL;
+	struct elf_shdr *shdr4extnum = NULL;
+	Elf_Half e_phnum;
+	elf_addr_t e_shoff;
 
 	/*
 	 * We no longer stop all VM operations.
@@ -1683,12 +1687,18 @@ static int elf_fdpic_core_dump(struct co
 	elf_core_copy_regs(&prstatus->pr_reg, cprm->regs);
 
 	segs = current->mm->map_count;
-#ifdef ELF_CORE_EXTRA_PHDRS
-	segs += ELF_CORE_EXTRA_PHDRS;
-#endif
+	segs += elf_core_extra_phdrs();
+
+	/* for notes section */
+	segs++;
+
+	/* If segs > PN_XNUM(0xffff), then e_phnum overflows. To avoid
+	 * this, kernel supports extended numbering. Have a look at
+	 * include/linux/elf.h for further information. */
+	e_phnum = segs > PN_XNUM ? PN_XNUM : segs;
 
 	/* Set up header */
-	fill_elf_fdpic_header(elf, segs + 1);	/* including notes section */
+	fill_elf_fdpic_header(elf, e_phnum);
 
 	has_dumped = 1;
 	current->flags |= PF_DUMPCORE;
@@ -1727,13 +1737,12 @@ static int elf_fdpic_core_dump(struct co
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 
-	DUMP_WRITE(elf, sizeof(*elf));
 	offset += sizeof(*elf);				/* Elf header */
-	offset += (segs+1) * sizeof(struct elf_phdr);	/* Program headers */
+	offset += segs * sizeof(struct elf_phdr);	/* Program headers */
+	foffset = offset;
 
 	/* Write notes phdr entry */
 	{
-		struct elf_phdr phdr;
 		int sz = 0;
 
 		for (i = 0; i < numnote; i++)
@@ -1741,20 +1750,38 @@ static int elf_fdpic_core_dump(struct co
 
 		sz += thread_status_size;
 
-		fill_elf_note_phdr(&phdr, sz, offset);
+		phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
+		if (!phdr4note)
+			goto end_coredump;
+
+		fill_elf_note_phdr(phdr4note, sz, offset);
 		offset += sz;
-		DUMP_WRITE(&phdr, sizeof(phdr));
 	}
 
 	/* Page-align dumped data */
 	dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
 
-	/*
-	 * We must use the same mm->flags while dumping core to avoid
-	 * inconsistency between the program headers and bodies, otherwise an
-	 * unusable core file can be generated.
-	 */
-	mm_flags = current->mm->flags;
+	offset += elf_core_vma_data_size(cprm->mm_flags);
+	offset += elf_core_extra_data_size();
+	e_shoff = offset;
+
+	if (e_phnum == PN_XNUM) {
+		shdr4extnum = kmalloc(sizeof(*shdr4extnum), GFP_KERNEL);
+		if (!shdr4extnum)
+			goto end_coredump;
+		fill_extnum_info(elf, shdr4extnum, e_shoff, segs);
+	}
+
+	offset = dataoff;
+
+	size += sizeof(*elf);
+	if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf)))
+		goto end_coredump;
+
+	size += sizeof(*phdr4note);
+	if (size > cprm->limit
+	    || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
+		goto end_coredump;
 
 	/* write program headers for segments dump */
 	for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
@@ -1767,7 +1794,7 @@ static int elf_fdpic_core_dump(struct co
 		phdr.p_offset = offset;
 		phdr.p_vaddr = vma->vm_start;
 		phdr.p_paddr = 0;
-		phdr.p_filesz = maydump(vma, mm_flags) ? sz : 0;
+		phdr.p_filesz = maydump(vma, cprm->mm_flags) ? sz : 0;
 		phdr.p_memsz = sz;
 		offset += phdr.p_filesz;
 		phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
@@ -1777,16 +1804,18 @@ static int elf_fdpic_core_dump(struct co
 			phdr.p_flags |= PF_X;
 		phdr.p_align = ELF_EXEC_PAGESIZE;
 
-		DUMP_WRITE(&phdr, sizeof(phdr));
+		size += sizeof(phdr);
+		if (size > cprm->limit
+		    || !dump_write(cprm->file, &phdr, sizeof(phdr)))
+			goto end_coredump;
 	}
 
-#ifdef ELF_CORE_WRITE_EXTRA_PHDRS
-	ELF_CORE_WRITE_EXTRA_PHDRS;
-#endif
+	if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit))
+		goto end_coredump;
 
  	/* write out the notes section */
 	for (i = 0; i < numnote; i++)
-		if (!writenote(notes + i, cprm->file))
+		if (!writenote(notes + i, cprm->file, &foffset))
 			goto end_coredump;
 
 	/* write out the thread status notes section */
@@ -1795,20 +1824,27 @@ static int elf_fdpic_core_dump(struct co
 				list_entry(t, struct elf_thread_status, list);
 
 		for (i = 0; i < tmp->num_notes; i++)
-			if (!writenote(&tmp->notes[i], cprm->file))
+			if (!writenote(&tmp->notes[i], cprm->file, &foffset))
 				goto end_coredump;
 	}
 
-	if (!dump_seek(cprm->file, dataoff))
+	if (!dump_seek(cprm->file, dataoff - foffset))
 		goto end_coredump;
 
 	if (elf_fdpic_dump_segments(cprm->file, &size, &cprm->limit,
-				    mm_flags) < 0)
+				    cprm->mm_flags) < 0)
 		goto end_coredump;
 
-#ifdef ELF_CORE_WRITE_EXTRA_DATA
-	ELF_CORE_WRITE_EXTRA_DATA;
-#endif
+	if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit))
+		goto end_coredump;
+
+	if (e_phnum == PN_XNUM) {
+		size += sizeof(*shdr4extnum);
+		if (size > cprm->limit
+		    || !dump_write(cprm->file, shdr4extnum,
+				   sizeof(*shdr4extnum)))
+			goto end_coredump;
+	}
 
 	if (cprm->file->f_pos != offset) {
 		/* Sanity check */
@@ -1826,7 +1862,7 @@ cleanup:
 		list_del(tmp);
 		kfree(list_entry(tmp, struct elf_thread_status, list));
 	}
-
+	kfree(phdr4note);
 	kfree(elf);
 	kfree(prstatus);
 	kfree(psinfo);
diff -druNp linux-libre-2.6.33-gnu1/fs/binfmt_em86.c linux-libre-2.6.34-gnu1/fs/binfmt_em86.c
--- linux-libre-2.6.33-gnu1/fs/binfmt_em86.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/binfmt_em86.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/stat.h>
-#include <linux/slab.h>
 #include <linux/binfmts.h>
 #include <linux/elf.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/binfmt_flat.c linux-libre-2.6.34-gnu1/fs/binfmt_flat.c
--- linux-libre-2.6.33-gnu1/fs/binfmt_flat.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/binfmt_flat.c	2010-05-16 17:17:36.000000000 -0400
@@ -355,7 +355,7 @@ calc_reloc(unsigned long r, struct lib_i
 
 	if (!flat_reloc_valid(r, start_brk - start_data + text_len)) {
 		printk("BINFMT_FLAT: reloc outside program 0x%x (0 - 0x%x/0x%x)",
-		       (int) r,(int)(start_brk-start_code),(int)text_len);
+		       (int) r,(int)(start_brk-start_data+text_len),(int)text_len);
 		goto failed;
 	}
 
@@ -501,7 +501,7 @@ static int load_flat_file(struct linux_b
 	 * size limits imposed on them by creating programs with large
 	 * arrays in the data or bss.
 	 */
-	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
+	rlim = rlimit(RLIMIT_DATA);
 	if (rlim >= RLIM_INFINITY)
 		rlim = ~0;
 	if (data_len + bss_len > rlim) {
diff -druNp linux-libre-2.6.33-gnu1/fs/binfmt_script.c linux-libre-2.6.34-gnu1/fs/binfmt_script.c
--- linux-libre-2.6.33-gnu1/fs/binfmt_script.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/binfmt_script.c	2010-05-16 17:17:36.000000000 -0400
@@ -8,7 +8,6 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/stat.h>
-#include <linux/slab.h>
 #include <linux/binfmts.h>
 #include <linux/init.h>
 #include <linux/file.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/bio.c linux-libre-2.6.34-gnu1/fs/bio.c
--- linux-libre-2.6.33-gnu1/fs/bio.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/bio.c	2010-05-16 17:17:36.000000000 -0400
@@ -264,13 +264,12 @@ EXPORT_SYMBOL(bio_init);
  * bio_alloc_bioset - allocate a bio for I/O
  * @gfp_mask:   the GFP_ mask given to the slab allocator
  * @nr_iovecs:	number of iovecs to pre-allocate
- * @bs:		the bio_set to allocate from. If %NULL, just use kmalloc
+ * @bs:		the bio_set to allocate from.
  *
  * Description:
- *   bio_alloc_bioset will first try its own mempool to satisfy the allocation.
+ *   bio_alloc_bioset will try its own mempool to satisfy the allocation.
  *   If %__GFP_WAIT is set then we will block on the internal pool waiting
- *   for a &struct bio to become free. If a %NULL @bs is passed in, we will
- *   fall back to just using @kmalloc to allocate the required memory.
+ *   for a &struct bio to become free.
  *
  *   Note that the caller must set ->bi_destructor on successful return
  *   of a bio, to do the appropriate freeing of the bio once the reference
@@ -507,10 +506,8 @@ int bio_get_nr_vecs(struct block_device
 	int nr_pages;
 
 	nr_pages = ((queue_max_sectors(q) << 9) + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	if (nr_pages > queue_max_phys_segments(q))
-		nr_pages = queue_max_phys_segments(q);
-	if (nr_pages > queue_max_hw_segments(q))
-		nr_pages = queue_max_hw_segments(q);
+	if (nr_pages > queue_max_segments(q))
+		nr_pages = queue_max_segments(q);
 
 	return nr_pages;
 }
@@ -557,7 +554,7 @@ static int __bio_add_page(struct request
 					.bi_rw = bio->bi_rw,
 				};
 
-				if (q->merge_bvec_fn(q, &bvm, prev) < len) {
+				if (q->merge_bvec_fn(q, &bvm, prev) < prev->bv_len) {
 					prev->bv_len -= len;
 					return 0;
 				}
@@ -575,8 +572,7 @@ static int __bio_add_page(struct request
 	 * make this too complex.
 	 */
 
-	while (bio->bi_phys_segments >= queue_max_phys_segments(q)
-	       || bio->bi_phys_segments >= queue_max_hw_segments(q)) {
+	while (bio->bi_phys_segments >= queue_max_segments(q)) {
 
 		if (retried_segments)
 			return 0;
@@ -611,7 +607,7 @@ static int __bio_add_page(struct request
 		 * merge_bvec_fn() returns number of bytes it can accept
 		 * at this offset
 		 */
-		if (q->merge_bvec_fn(q, &bvm, bvec) < len) {
+		if (q->merge_bvec_fn(q, &bvm, bvec) < bvec->bv_len) {
 			bvec->bv_page = NULL;
 			bvec->bv_len = 0;
 			bvec->bv_offset = 0;
diff -druNp linux-libre-2.6.33-gnu1/fs/bio-integrity.c linux-libre-2.6.34-gnu1/fs/bio-integrity.c
--- linux-libre-2.6.33-gnu1/fs/bio-integrity.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/bio-integrity.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/mempool.h>
 #include <linux/bio.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 struct integrity_slab {
 	struct kmem_cache *slab;
diff -druNp linux-libre-2.6.33-gnu1/fs/block_dev.c linux-libre-2.6.34-gnu1/fs/block_dev.c
--- linux-libre-2.6.33-gnu1/fs/block_dev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/block_dev.c	2010-05-16 17:17:36.000000000 -0400
@@ -404,20 +404,28 @@ static loff_t block_llseek(struct file *
  *	NULL first argument is nfsd_sync_dir() and that's not a directory.
  */
  
-static int block_fsync(struct file *filp, struct dentry *dentry, int datasync)
+int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync)
 {
-	struct block_device *bdev = I_BDEV(filp->f_mapping->host);
+	struct inode *bd_inode = filp->f_mapping->host;
+	struct block_device *bdev = I_BDEV(bd_inode);
 	int error;
 
-	error = sync_blockdev(bdev);
-	if (error)
-		return error;
-	
+	/*
+	 * There is no need to serialise calls to blkdev_issue_flush with
+	 * i_mutex and doing so causes performance issues with concurrent
+	 * O_SYNC writers to a block device.
+	 */
+	mutex_unlock(&bd_inode->i_mutex);
+
 	error = blkdev_issue_flush(bdev, NULL);
 	if (error == -EOPNOTSUPP)
 		error = 0;
+
+	mutex_lock(&bd_inode->i_mutex);
+
 	return error;
 }
+EXPORT_SYMBOL(blkdev_fsync);
 
 /*
  * pseudo-fs
@@ -1481,7 +1489,7 @@ const struct file_operations def_blk_fop
   	.aio_read	= generic_file_aio_read,
 	.aio_write	= blkdev_aio_write,
 	.mmap		= generic_file_mmap,
-	.fsync		= block_fsync,
+	.fsync		= blkdev_fsync,
 	.unlocked_ioctl	= block_ioctl,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= compat_blkdev_ioctl,
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/acl.c linux-libre-2.6.34-gnu1/fs/btrfs/acl.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/acl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/acl.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/posix_acl_xattr.h>
 #include <linux/posix_acl.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include "ctree.h"
 #include "btrfs_inode.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/async-thread.c linux-libre-2.6.34-gnu1/fs/btrfs/async-thread.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/async-thread.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/async-thread.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/freezer.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/btrfs_inode.h linux-libre-2.6.34-gnu1/fs/btrfs/btrfs_inode.h
--- linux-libre-2.6.33-gnu1/fs/btrfs/btrfs_inode.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/btrfs_inode.h	2010-05-16 17:17:36.000000000 -0400
@@ -153,6 +153,11 @@ struct btrfs_inode {
 	unsigned ordered_data_close:1;
 	unsigned dummy_inode:1;
 
+	/*
+	 * always compress this one file
+	 */
+	unsigned force_compress:1;
+
 	struct inode vfs_inode;
 };
 
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/compression.c linux-libre-2.6.34-gnu1/fs/btrfs/compression.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/compression.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/compression.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,7 +31,7 @@
 #include <linux/swap.h>
 #include <linux/writeback.h>
 #include <linux/bit_spinlock.h>
-#include <linux/pagevec.h>
+#include <linux/slab.h>
 #include "compat.h"
 #include "ctree.h"
 #include "disk-io.h"
@@ -445,7 +445,6 @@ static noinline int add_ra_bio_pages(str
 	unsigned long nr_pages = 0;
 	struct extent_map *em;
 	struct address_space *mapping = inode->i_mapping;
-	struct pagevec pvec;
 	struct extent_map_tree *em_tree;
 	struct extent_io_tree *tree;
 	u64 end;
@@ -461,7 +460,6 @@ static noinline int add_ra_bio_pages(str
 
 	end_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT;
 
-	pagevec_init(&pvec, 0);
 	while (last_offset < compressed_end) {
 		page_index = last_offset >> PAGE_CACHE_SHIFT;
 
@@ -478,26 +476,17 @@ static noinline int add_ra_bio_pages(str
 			goto next;
 		}
 
-		page = alloc_page(mapping_gfp_mask(mapping) | GFP_NOFS);
+		page = __page_cache_alloc(mapping_gfp_mask(mapping) &
+								~__GFP_FS);
 		if (!page)
 			break;
 
-		page->index = page_index;
-		/*
-		 * what we want to do here is call add_to_page_cache_lru,
-		 * but that isn't exported, so we reproduce it here
-		 */
-		if (add_to_page_cache(page, mapping,
-				      page->index, GFP_NOFS)) {
+		if (add_to_page_cache_lru(page, mapping, page_index,
+								GFP_NOFS)) {
 			page_cache_release(page);
 			goto next;
 		}
 
-		/* open coding of lru_cache_add, also not exported */
-		page_cache_get(page);
-		if (!pagevec_add(&pvec, page))
-			__pagevec_lru_add_file(&pvec);
-
 		end = last_offset + PAGE_CACHE_SIZE - 1;
 		/*
 		 * at this point, we have a locked page in the page cache
@@ -551,8 +540,6 @@ static noinline int add_ra_bio_pages(str
 next:
 		last_offset += PAGE_CACHE_SIZE;
 	}
-	if (pagevec_count(&pvec))
-		__pagevec_lru_add_file(&pvec);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/ctree.c linux-libre-2.6.34-gnu1/fs/btrfs/ctree.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/ctree.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/ctree.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
@@ -3040,6 +3041,10 @@ static noinline int setup_leaf_for_split
 	if (ret > 0 || item_size != btrfs_item_size_nr(leaf, path->slots[0]))
 		goto err;
 
+	/* the leaf has  changed, it now has room.  return now */
+	if (btrfs_leaf_free_space(root, path->nodes[0]) >= ins_len)
+		goto err;
+
 	if (key.type == BTRFS_EXTENT_DATA_KEY) {
 		fi = btrfs_item_ptr(leaf, path->slots[0],
 				    struct btrfs_file_extent_item);
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/ctree.h linux-libre-2.6.34-gnu1/fs/btrfs/ctree.h
--- linux-libre-2.6.33-gnu1/fs/btrfs/ctree.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/ctree.h	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/completion.h>
 #include <linux/backing-dev.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <asm/kmap_types.h>
 #include "extent_io.h"
 #include "extent_map.h"
@@ -373,11 +374,13 @@ struct btrfs_super_block {
  * ones specified below then we will fail to mount
  */
 #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF	(1ULL << 0)
+#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL	(2ULL << 0)
 
 #define BTRFS_FEATURE_COMPAT_SUPP		0ULL
 #define BTRFS_FEATURE_COMPAT_RO_SUPP		0ULL
 #define BTRFS_FEATURE_INCOMPAT_SUPP		\
-	BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF
+	(BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF |	\
+	 BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)
 
 /*
  * A leaf is full of items. offset and size tell us where to find
@@ -832,7 +835,6 @@ struct btrfs_fs_info {
 	u64 last_trans_log_full_commit;
 	u64 open_ioctl_trans;
 	unsigned long mount_opt;
-	u64 max_extent;
 	u64 max_inline;
 	u64 alloc_start;
 	struct btrfs_transaction *running_transaction;
@@ -1182,7 +1184,6 @@ struct btrfs_root {
 #define BTRFS_INODE_NOATIME		(1 << 9)
 #define BTRFS_INODE_DIRSYNC		(1 << 10)
 
-
 /* some macros to generate set/get funcs for the struct fields.  This
  * assumes there is a lefoo_to_cpu for every type, so lets make a simple
  * one for u8:
@@ -1842,7 +1843,7 @@ BTRFS_SETGET_STACK_FUNCS(super_num_devic
 BTRFS_SETGET_STACK_FUNCS(super_compat_flags, struct btrfs_super_block,
 			 compat_flags, 64);
 BTRFS_SETGET_STACK_FUNCS(super_compat_ro_flags, struct btrfs_super_block,
-			 compat_flags, 64);
+			 compat_ro_flags, 64);
 BTRFS_SETGET_STACK_FUNCS(super_incompat_flags, struct btrfs_super_block,
 			 incompat_flags, 64);
 BTRFS_SETGET_STACK_FUNCS(super_csum_type, struct btrfs_super_block,
@@ -2310,7 +2311,8 @@ int btrfs_truncate_inode_items(struct bt
 			       u32 min_type);
 
 int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput);
-int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end);
+int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
+			      struct extent_state **cached_state);
 int btrfs_writepages(struct address_space *mapping,
 		     struct writeback_control *wbc);
 int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
@@ -2326,7 +2328,7 @@ int btrfs_page_mkwrite(struct vm_area_st
 int btrfs_readpage(struct file *file, struct page *page);
 void btrfs_delete_inode(struct inode *inode);
 void btrfs_put_inode(struct inode *inode);
-int btrfs_write_inode(struct inode *inode, int wait);
+int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc);
 void btrfs_dirty_inode(struct inode *inode);
 struct inode *btrfs_alloc_inode(struct super_block *sb);
 void btrfs_destroy_inode(struct inode *inode);
@@ -2335,7 +2337,7 @@ int btrfs_init_cachep(void);
 void btrfs_destroy_cachep(void);
 long btrfs_ioctl_trans_end(struct file *file);
 struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
-			 struct btrfs_root *root);
+			 struct btrfs_root *root, int *was_new);
 int btrfs_commit_write(struct file *file, struct page *page,
 		       unsigned from, unsigned to);
 struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
@@ -2386,7 +2388,6 @@ void btrfs_sysfs_del_super(struct btrfs_
 ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
 
 /* super.c */
-u64 btrfs_parse_size(char *str);
 int btrfs_parse_options(struct btrfs_root *root, char *options);
 int btrfs_sync_fs(struct super_block *sb, int wait);
 
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/delayed-ref.c linux-libre-2.6.34-gnu1/fs/btrfs/delayed-ref.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/delayed-ref.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/delayed-ref.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/sort.h>
 #include "ctree.h"
 #include "delayed-ref.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/disk-io.c linux-libre-2.6.34-gnu1/fs/btrfs/disk-io.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/disk-io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/disk-io.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/crc32c.h>
+#include <linux/slab.h>
 #include "compat.h"
 #include "ctree.h"
 #include "disk-io.h"
@@ -43,8 +44,6 @@ static struct extent_io_ops btree_extent
 static void end_workqueue_fn(struct btrfs_work *work);
 static void free_fs_root(struct btrfs_root *root);
 
-static atomic_t btrfs_bdi_num = ATOMIC_INIT(0);
-
 /*
  * end_io_wq structs are used to do processing in task context when an IO is
  * complete.  This is used during reads to verify checksums, and it is used
@@ -263,13 +262,15 @@ static int csum_tree_block(struct btrfs_
 static int verify_parent_transid(struct extent_io_tree *io_tree,
 				 struct extent_buffer *eb, u64 parent_transid)
 {
+	struct extent_state *cached_state = NULL;
 	int ret;
 
 	if (!parent_transid || btrfs_header_generation(eb) == parent_transid)
 		return 0;
 
-	lock_extent(io_tree, eb->start, eb->start + eb->len - 1, GFP_NOFS);
-	if (extent_buffer_uptodate(io_tree, eb) &&
+	lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1,
+			 0, &cached_state, GFP_NOFS);
+	if (extent_buffer_uptodate(io_tree, eb, cached_state) &&
 	    btrfs_header_generation(eb) == parent_transid) {
 		ret = 0;
 		goto out;
@@ -282,10 +283,10 @@ static int verify_parent_transid(struct
 		       (unsigned long long)btrfs_header_generation(eb));
 	}
 	ret = 1;
-	clear_extent_buffer_uptodate(io_tree, eb);
+	clear_extent_buffer_uptodate(io_tree, eb, &cached_state);
 out:
-	unlock_extent(io_tree, eb->start, eb->start + eb->len - 1,
-		      GFP_NOFS);
+	unlock_extent_cached(io_tree, eb->start, eb->start + eb->len - 1,
+			     &cached_state, GFP_NOFS);
 	return ret;
 }
 
@@ -901,7 +902,7 @@ static int __setup_root(u32 nodesize, u3
 	root->highest_objectid = 0;
 	root->name = NULL;
 	root->in_sysfs = 0;
-	root->inode_tree.rb_node = NULL;
+	root->inode_tree = RB_ROOT;
 
 	INIT_LIST_HEAD(&root->dirty_list);
 	INIT_LIST_HEAD(&root->orphan_list);
@@ -1372,19 +1373,11 @@ static int setup_bdi(struct btrfs_fs_inf
 {
 	int err;
 
-	bdi->name = "btrfs";
 	bdi->capabilities = BDI_CAP_MAP_COPY;
-	err = bdi_init(bdi);
+	err = bdi_setup_and_register(bdi, "btrfs", BDI_CAP_MAP_COPY);
 	if (err)
 		return err;
 
-	err = bdi_register(bdi, NULL, "btrfs-%d",
-				atomic_inc_return(&btrfs_bdi_num));
-	if (err) {
-		bdi_destroy(bdi);
-		return err;
-	}
-
 	bdi->ra_pages	= default_backing_dev_info.ra_pages;
 	bdi->unplug_io_fn	= btrfs_unplug_io_fn;
 	bdi->unplug_io_data	= info;
@@ -1632,7 +1625,6 @@ struct btrfs_root *open_ctree(struct sup
 	atomic_set(&fs_info->async_submit_draining, 0);
 	atomic_set(&fs_info->nr_async_bios, 0);
 	fs_info->sb = sb;
-	fs_info->max_extent = (u64)-1;
 	fs_info->max_inline = 8192 * 1024;
 	fs_info->metadata_ratio = 0;
 
@@ -1673,7 +1665,7 @@ struct btrfs_root *open_ctree(struct sup
 	insert_inode_hash(fs_info->btree_inode);
 
 	spin_lock_init(&fs_info->block_group_cache_lock);
-	fs_info->block_group_cache_tree.rb_node = NULL;
+	fs_info->block_group_cache_tree = RB_ROOT;
 
 	extent_io_tree_init(&fs_info->freed_extents[0],
 			     fs_info->btree_inode->i_mapping, GFP_NOFS);
@@ -1920,7 +1912,11 @@ struct btrfs_root *open_ctree(struct sup
 
 	csum_root->track_dirty = 1;
 
-	btrfs_read_block_groups(extent_root);
+	ret = btrfs_read_block_groups(extent_root);
+	if (ret) {
+		printk(KERN_ERR "Failed to read block groups: %d\n", ret);
+		goto fail_block_groups;
+	}
 
 	fs_info->generation = generation;
 	fs_info->last_trans_committed = generation;
@@ -1930,7 +1926,7 @@ struct btrfs_root *open_ctree(struct sup
 	fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root,
 					       "btrfs-cleaner");
 	if (IS_ERR(fs_info->cleaner_kthread))
-		goto fail_csum_root;
+		goto fail_block_groups;
 
 	fs_info->transaction_kthread = kthread_run(transaction_kthread,
 						   tree_root,
@@ -2018,7 +2014,8 @@ fail_cleaner:
 	filemap_write_and_wait(fs_info->btree_inode->i_mapping);
 	invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
 
-fail_csum_root:
+fail_block_groups:
+	btrfs_free_block_groups(fs_info);
 	free_extent_buffer(csum_root->node);
 	free_extent_buffer(csum_root->commit_root);
 fail_dev_root:
@@ -2497,7 +2494,8 @@ int btrfs_buffer_uptodate(struct extent_
 	int ret;
 	struct inode *btree_inode = buf->first_page->mapping->host;
 
-	ret = extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree, buf);
+	ret = extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree, buf,
+				     NULL);
 	if (!ret)
 		return ret;
 
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/export.c linux-libre-2.6.34-gnu1/fs/btrfs/export.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/export.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/export.c	2010-05-16 17:17:36.000000000 -0400
@@ -95,7 +95,7 @@ static struct dentry *btrfs_get_dentry(s
 	btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
 	key.offset = 0;
 
-	inode = btrfs_iget(sb, &key, root);
+	inode = btrfs_iget(sb, &key, root, NULL);
 	if (IS_ERR(inode)) {
 		err = PTR_ERR(inode);
 		goto fail;
@@ -223,7 +223,7 @@ static struct dentry *btrfs_get_parent(s
 
 	key.type = BTRFS_INODE_ITEM_KEY;
 	key.offset = 0;
-	dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root));
+	dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root, NULL));
 	if (!IS_ERR(dentry))
 		dentry->d_op = &btrfs_dentry_operations;
 	return dentry;
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/extent_io.c linux-libre-2.6.34-gnu1/fs/btrfs/extent_io.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/extent_io.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/extent_io.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,6 @@
 #include <linux/slab.h>
 #include <linux/bio.h>
 #include <linux/mm.h>
-#include <linux/gfp.h>
 #include <linux/pagemap.h>
 #include <linux/page-flags.h>
 #include <linux/module.h>
@@ -104,8 +103,8 @@ void extent_io_exit(void)
 void extent_io_tree_init(struct extent_io_tree *tree,
 			  struct address_space *mapping, gfp_t mask)
 {
-	tree->state.rb_node = NULL;
-	tree->buffer.rb_node = NULL;
+	tree->state = RB_ROOT;
+	tree->buffer = RB_ROOT;
 	tree->ops = NULL;
 	tree->dirty_bytes = 0;
 	spin_lock_init(&tree->lock);
@@ -513,7 +512,10 @@ int clear_extent_bit(struct extent_io_tr
 	u64 last_end;
 	int err;
 	int set = 0;
+	int clear = 0;
 
+	if (bits & (EXTENT_IOBITS | EXTENT_BOUNDARY))
+		clear = 1;
 again:
 	if (!prealloc && (mask & __GFP_WAIT)) {
 		prealloc = alloc_extent_state(mask);
@@ -524,14 +526,20 @@ again:
 	spin_lock(&tree->lock);
 	if (cached_state) {
 		cached = *cached_state;
-		*cached_state = NULL;
-		cached_state = NULL;
+
+		if (clear) {
+			*cached_state = NULL;
+			cached_state = NULL;
+		}
+
 		if (cached && cached->tree && cached->start == start) {
-			atomic_dec(&cached->refs);
+			if (clear)
+				atomic_dec(&cached->refs);
 			state = cached;
 			goto hit_next;
 		}
-		free_extent_state(cached);
+		if (clear)
+			free_extent_state(cached);
 	}
 	/*
 	 * this search will find the extents that end after
@@ -946,11 +954,11 @@ int clear_extent_bits(struct extent_io_t
 }
 
 int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
-		     gfp_t mask)
+			struct extent_state **cached_state, gfp_t mask)
 {
 	return set_extent_bit(tree, start, end,
 			      EXTENT_DELALLOC | EXTENT_DIRTY | EXTENT_UPTODATE,
-			      0, NULL, NULL, mask);
+			      0, NULL, cached_state, mask);
 }
 
 int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
@@ -984,10 +992,11 @@ int set_extent_uptodate(struct extent_io
 }
 
 static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start,
-				 u64 end, gfp_t mask)
+				 u64 end, struct extent_state **cached_state,
+				 gfp_t mask)
 {
 	return clear_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, 0,
-				NULL, mask);
+				cached_state, mask);
 }
 
 int wait_on_extent_writeback(struct extent_io_tree *tree, u64 start, u64 end)
@@ -1171,7 +1180,8 @@ out:
  * 1 is returned if we find something, 0 if nothing was in the tree
  */
 static noinline u64 find_delalloc_range(struct extent_io_tree *tree,
-					u64 *start, u64 *end, u64 max_bytes)
+					u64 *start, u64 *end, u64 max_bytes,
+					struct extent_state **cached_state)
 {
 	struct rb_node *node;
 	struct extent_state *state;
@@ -1203,8 +1213,11 @@ static noinline u64 find_delalloc_range(
 				*end = state->end;
 			goto out;
 		}
-		if (!found)
+		if (!found) {
 			*start = state->start;
+			*cached_state = state;
+			atomic_inc(&state->refs);
+		}
 		found++;
 		*end = state->end;
 		cur_start = state->end + 1;
@@ -1336,10 +1349,11 @@ again:
 	delalloc_start = *start;
 	delalloc_end = 0;
 	found = find_delalloc_range(tree, &delalloc_start, &delalloc_end,
-				    max_bytes);
+				    max_bytes, &cached_state);
 	if (!found || delalloc_end <= *start) {
 		*start = delalloc_start;
 		*end = delalloc_end;
+		free_extent_state(cached_state);
 		return found;
 	}
 
@@ -1722,7 +1736,7 @@ static void end_bio_extent_writepage(str
 		}
 
 		if (!uptodate) {
-			clear_extent_uptodate(tree, start, end, GFP_NOFS);
+			clear_extent_uptodate(tree, start, end, NULL, GFP_NOFS);
 			ClearPageUptodate(page);
 			SetPageError(page);
 		}
@@ -1750,7 +1764,8 @@ static void end_bio_extent_writepage(str
 static void end_bio_extent_readpage(struct bio *bio, int err)
 {
 	int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
-	struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
+	struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1;
+	struct bio_vec *bvec = bio->bi_io_vec;
 	struct extent_io_tree *tree;
 	u64 start;
 	u64 end;
@@ -1773,7 +1788,7 @@ static void end_bio_extent_readpage(stru
 		else
 			whole_page = 0;
 
-		if (--bvec >= bio->bi_io_vec)
+		if (++bvec <= bvec_end)
 			prefetchw(&bvec->bv_page->flags);
 
 		if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) {
@@ -1818,7 +1833,7 @@ static void end_bio_extent_readpage(stru
 			}
 			check_page_locked(tree, page);
 		}
-	} while (bvec >= bio->bi_io_vec);
+	} while (bvec <= bvec_end);
 
 	bio_put(bio);
 }
@@ -2663,33 +2678,20 @@ int extent_readpages(struct extent_io_tr
 {
 	struct bio *bio = NULL;
 	unsigned page_idx;
-	struct pagevec pvec;
 	unsigned long bio_flags = 0;
 
-	pagevec_init(&pvec, 0);
 	for (page_idx = 0; page_idx < nr_pages; page_idx++) {
 		struct page *page = list_entry(pages->prev, struct page, lru);
 
 		prefetchw(&page->flags);
 		list_del(&page->lru);
-		/*
-		 * what we want to do here is call add_to_page_cache_lru,
-		 * but that isn't exported, so we reproduce it here
-		 */
-		if (!add_to_page_cache(page, mapping,
+		if (!add_to_page_cache_lru(page, mapping,
 					page->index, GFP_KERNEL)) {
-
-			/* open coding of lru_cache_add, also not exported */
-			page_cache_get(page);
-			if (!pagevec_add(&pvec, page))
-				__pagevec_lru_add_file(&pvec);
 			__extent_read_full_page(tree, page, get_extent,
 						&bio, 0, &bio_flags);
 		}
 		page_cache_release(page);
 	}
-	if (pagevec_count(&pvec))
-		__pagevec_lru_add_file(&pvec);
 	BUG_ON(!list_empty(pages));
 	if (bio)
 		submit_one_bio(READ, bio, 0, bio_flags);
@@ -2704,6 +2706,7 @@ int extent_readpages(struct extent_io_tr
 int extent_invalidatepage(struct extent_io_tree *tree,
 			  struct page *page, unsigned long offset)
 {
+	struct extent_state *cached_state = NULL;
 	u64 start = ((u64)page->index << PAGE_CACHE_SHIFT);
 	u64 end = start + PAGE_CACHE_SIZE - 1;
 	size_t blocksize = page->mapping->host->i_sb->s_blocksize;
@@ -2712,12 +2715,12 @@ int extent_invalidatepage(struct extent_
 	if (start > end)
 		return 0;
 
-	lock_extent(tree, start, end, GFP_NOFS);
+	lock_extent_bits(tree, start, end, 0, &cached_state, GFP_NOFS);
 	wait_on_page_writeback(page);
 	clear_extent_bit(tree, start, end,
 			 EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
 			 EXTENT_DO_ACCOUNTING,
-			 1, 1, NULL, GFP_NOFS);
+			 1, 1, &cached_state, GFP_NOFS);
 	return 0;
 }
 
@@ -2920,16 +2923,17 @@ sector_t extent_bmap(struct address_spac
 		get_extent_t *get_extent)
 {
 	struct inode *inode = mapping->host;
+	struct extent_state *cached_state = NULL;
 	u64 start = iblock << inode->i_blkbits;
 	sector_t sector = 0;
 	size_t blksize = (1 << inode->i_blkbits);
 	struct extent_map *em;
 
-	lock_extent(&BTRFS_I(inode)->io_tree, start, start + blksize - 1,
-		    GFP_NOFS);
+	lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + blksize - 1,
+			 0, &cached_state, GFP_NOFS);
 	em = get_extent(inode, NULL, 0, start, blksize, 0);
-	unlock_extent(&BTRFS_I(inode)->io_tree, start, start + blksize - 1,
-		      GFP_NOFS);
+	unlock_extent_cached(&BTRFS_I(inode)->io_tree, start,
+			     start + blksize - 1, &cached_state, GFP_NOFS);
 	if (!em || IS_ERR(em))
 		return 0;
 
@@ -2951,6 +2955,7 @@ int extent_fiemap(struct inode *inode, s
 	u32 flags = 0;
 	u64 disko = 0;
 	struct extent_map *em = NULL;
+	struct extent_state *cached_state = NULL;
 	int end = 0;
 	u64 em_start = 0, em_len = 0;
 	unsigned long emflags;
@@ -2959,8 +2964,8 @@ int extent_fiemap(struct inode *inode, s
 	if (len == 0)
 		return -EINVAL;
 
-	lock_extent(&BTRFS_I(inode)->io_tree, start, start + len,
-		GFP_NOFS);
+	lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0,
+			 &cached_state, GFP_NOFS);
 	em = get_extent(inode, NULL, 0, off, max - off, 0);
 	if (!em)
 		goto out;
@@ -3023,8 +3028,8 @@ int extent_fiemap(struct inode *inode, s
 out_free:
 	free_extent_map(em);
 out:
-	unlock_extent(&BTRFS_I(inode)->io_tree, start, start + len,
-			GFP_NOFS);
+	unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len,
+			     &cached_state, GFP_NOFS);
 	return ret;
 }
 
@@ -3264,7 +3269,8 @@ int set_extent_buffer_dirty(struct exten
 }
 
 int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
-				struct extent_buffer *eb)
+				struct extent_buffer *eb,
+				struct extent_state **cached_state)
 {
 	unsigned long i;
 	struct page *page;
@@ -3274,7 +3280,7 @@ int clear_extent_buffer_uptodate(struct
 	clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
 
 	clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
-			      GFP_NOFS);
+			      cached_state, GFP_NOFS);
 	for (i = 0; i < num_pages; i++) {
 		page = extent_buffer_page(eb, i);
 		if (page)
@@ -3334,7 +3340,8 @@ int extent_range_uptodate(struct extent_
 }
 
 int extent_buffer_uptodate(struct extent_io_tree *tree,
-			   struct extent_buffer *eb)
+			   struct extent_buffer *eb,
+			   struct extent_state *cached_state)
 {
 	int ret = 0;
 	unsigned long num_pages;
@@ -3346,7 +3353,7 @@ int extent_buffer_uptodate(struct extent
 		return 1;
 
 	ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1,
-			   EXTENT_UPTODATE, 1, NULL);
+			   EXTENT_UPTODATE, 1, cached_state);
 	if (ret)
 		return ret;
 
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/extent_io.h linux-libre-2.6.34-gnu1/fs/btrfs/extent_io.h
--- linux-libre-2.6.33-gnu1/fs/btrfs/extent_io.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/extent_io.h	2010-05-16 17:17:36.000000000 -0400
@@ -163,6 +163,8 @@ int lock_extent(struct extent_io_tree *t
 int lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
 		     int bits, struct extent_state **cached, gfp_t mask);
 int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask);
+int unlock_extent_cached(struct extent_io_tree *tree, u64 start, u64 end,
+			 struct extent_state **cached, gfp_t mask);
 int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end,
 		    gfp_t mask);
 int extent_read_full_page(struct extent_io_tree *tree, struct page *page,
@@ -196,7 +198,7 @@ int clear_extent_ordered(struct extent_i
 int clear_extent_ordered_metadata(struct extent_io_tree *tree, u64 start,
 				  u64 end, gfp_t mask);
 int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
-		     gfp_t mask);
+			struct extent_state **cached_state, gfp_t mask);
 int set_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end,
 		     gfp_t mask);
 int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
@@ -281,9 +283,11 @@ int test_extent_buffer_dirty(struct exte
 int set_extent_buffer_uptodate(struct extent_io_tree *tree,
 			       struct extent_buffer *eb);
 int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
-				struct extent_buffer *eb);
+				struct extent_buffer *eb,
+				struct extent_state **cached_state);
 int extent_buffer_uptodate(struct extent_io_tree *tree,
-			   struct extent_buffer *eb);
+			   struct extent_buffer *eb,
+			   struct extent_state *cached_state);
 int map_extent_buffer(struct extent_buffer *eb, unsigned long offset,
 		      unsigned long min_len, char **token, char **map,
 		      unsigned long *map_start,
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/extent_map.c linux-libre-2.6.34-gnu1/fs/btrfs/extent_map.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/extent_map.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/extent_map.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,4 @@
 #include <linux/err.h>
-#include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
@@ -35,7 +34,7 @@ void extent_map_exit(void)
  */
 void extent_map_tree_init(struct extent_map_tree *tree, gfp_t mask)
 {
-	tree->map.rb_node = NULL;
+	tree->map = RB_ROOT;
 	rwlock_init(&tree->lock);
 }
 
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/extent-tree.c linux-libre-2.6.34-gnu1/fs/btrfs/extent-tree.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/extent-tree.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/extent-tree.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/sort.h>
 #include <linux/rcupdate.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include "compat.h"
 #include "hash.h"
 #include "ctree.h"
@@ -2676,6 +2677,8 @@ static int update_space_info(struct btrf
 
 	INIT_LIST_HEAD(&found->block_groups);
 	init_rwsem(&found->groups_sem);
+	init_waitqueue_head(&found->flush_wait);
+	init_waitqueue_head(&found->allocate_wait);
 	spin_lock_init(&found->lock);
 	found->flags = flags;
 	found->total_bytes = total_bytes;
@@ -2846,7 +2849,7 @@ int btrfs_unreserve_metadata_for_delallo
 	}
 	spin_unlock(&BTRFS_I(inode)->accounting_lock);
 
-	BTRFS_I(inode)->reserved_extents--;
+	BTRFS_I(inode)->reserved_extents -= num_items;
 	BUG_ON(BTRFS_I(inode)->reserved_extents < 0);
 
 	if (meta_sinfo->bytes_delalloc < num_bytes) {
@@ -2944,12 +2947,10 @@ static void flush_delalloc(struct btrfs_
 
 	spin_lock(&info->lock);
 
-	if (!info->flushing) {
+	if (!info->flushing)
 		info->flushing = 1;
-		init_waitqueue_head(&info->flush_wait);
-	} else {
+	else
 		wait = true;
-	}
 
 	spin_unlock(&info->lock);
 
@@ -3011,7 +3012,6 @@ static int maybe_allocate_chunk(struct b
 	if (!info->allocating_chunk) {
 		info->force_alloc = 1;
 		info->allocating_chunk = 1;
-		init_waitqueue_head(&info->allocate_wait);
 	} else {
 		wait = true;
 	}
@@ -3111,7 +3111,7 @@ again:
 		return -ENOSPC;
 	}
 
-	BTRFS_I(inode)->reserved_extents++;
+	BTRFS_I(inode)->reserved_extents += num_items;
 	check_force_delalloc(meta_sinfo);
 	spin_unlock(&meta_sinfo->lock);
 
@@ -3235,7 +3235,8 @@ int btrfs_check_data_free_space(struct b
 				u64 bytes)
 {
 	struct btrfs_space_info *data_sinfo;
-	int ret = 0, committed = 0;
+	u64 used;
+	int ret = 0, committed = 0, flushed = 0;
 
 	/* make sure bytes are sectorsize aligned */
 	bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
@@ -3247,12 +3248,21 @@ int btrfs_check_data_free_space(struct b
 again:
 	/* make sure we have enough space to handle the data first */
 	spin_lock(&data_sinfo->lock);
-	if (data_sinfo->total_bytes - data_sinfo->bytes_used -
-	    data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved -
-	    data_sinfo->bytes_pinned - data_sinfo->bytes_readonly -
-	    data_sinfo->bytes_may_use - data_sinfo->bytes_super < bytes) {
+	used = data_sinfo->bytes_used + data_sinfo->bytes_delalloc +
+		data_sinfo->bytes_reserved + data_sinfo->bytes_pinned +
+		data_sinfo->bytes_readonly + data_sinfo->bytes_may_use +
+		data_sinfo->bytes_super;
+
+	if (used + bytes > data_sinfo->total_bytes) {
 		struct btrfs_trans_handle *trans;
 
+		if (!flushed) {
+			spin_unlock(&data_sinfo->lock);
+			flush_delalloc(root, data_sinfo);
+			flushed = 1;
+			goto again;
+		}
+
 		/*
 		 * if we don't have enough free bytes in this space then we need
 		 * to alloc a new chunk.
@@ -4170,6 +4180,10 @@ static noinline int find_free_extent(str
 	ins->offset = 0;
 
 	space_info = __find_space_info(root->fs_info, data);
+	if (!space_info) {
+		printk(KERN_ERR "No space info for %d\n", data);
+		return -ENOSPC;
+	}
 
 	if (orig_root->ref_cows || empty_size)
 		allowed_chunk_alloc = 1;
@@ -5205,6 +5219,8 @@ static noinline int do_walk_down(struct
 	next = btrfs_find_tree_block(root, bytenr, blocksize);
 	if (!next) {
 		next = btrfs_find_create_tree_block(root, bytenr, blocksize);
+		if (!next)
+			return -ENOMEM;
 		reada = 1;
 	}
 	btrfs_tree_lock(next);
@@ -5417,7 +5433,8 @@ static noinline int walk_down_tree(struc
 		if (ret > 0) {
 			path->slots[level]++;
 			continue;
-		}
+		} else if (ret < 0)
+			return ret;
 		level = wc->level;
 	}
 	return 0;
@@ -6561,6 +6578,7 @@ static noinline int invalidate_extent_ca
 	struct btrfs_key key;
 	struct inode *inode = NULL;
 	struct btrfs_file_extent_item *fi;
+	struct extent_state *cached_state = NULL;
 	u64 num_bytes;
 	u64 skip_objectid = 0;
 	u32 nritems;
@@ -6589,12 +6607,14 @@ static noinline int invalidate_extent_ca
 		}
 		num_bytes = btrfs_file_extent_num_bytes(leaf, fi);
 
-		lock_extent(&BTRFS_I(inode)->io_tree, key.offset,
-			    key.offset + num_bytes - 1, GFP_NOFS);
+		lock_extent_bits(&BTRFS_I(inode)->io_tree, key.offset,
+				 key.offset + num_bytes - 1, 0, &cached_state,
+				 GFP_NOFS);
 		btrfs_drop_extent_cache(inode, key.offset,
 					key.offset + num_bytes - 1, 1);
-		unlock_extent(&BTRFS_I(inode)->io_tree, key.offset,
-			      key.offset + num_bytes - 1, GFP_NOFS);
+		unlock_extent_cached(&BTRFS_I(inode)->io_tree, key.offset,
+				     key.offset + num_bytes - 1, &cached_state,
+				     GFP_NOFS);
 		cond_resched();
 	}
 	iput(inode);
@@ -7366,7 +7386,6 @@ static int find_first_block_group(struct
 		}
 		path->slots[0]++;
 	}
-	ret = -ENOENT;
 out:
 	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/file.c linux-libre-2.6.34-gnu1/fs/btrfs/file.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/file.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/file.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/writeback.h>
 #include <linux/statfs.h>
 #include <linux/compat.h>
+#include <linux/slab.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
@@ -123,7 +124,8 @@ static noinline int dirty_and_release_pa
 		    root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
 
 	end_of_last_block = start_pos + num_bytes - 1;
-	err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block);
+	err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block,
+					NULL);
 	if (err)
 		return err;
 
@@ -753,6 +755,7 @@ static noinline int prepare_pages(struct
 			 loff_t pos, unsigned long first_index,
 			 unsigned long last_index, size_t write_bytes)
 {
+	struct extent_state *cached_state = NULL;
 	int i;
 	unsigned long index = pos >> PAGE_CACHE_SHIFT;
 	struct inode *inode = fdentry(file)->d_inode;
@@ -781,16 +784,18 @@ again:
 	}
 	if (start_pos < inode->i_size) {
 		struct btrfs_ordered_extent *ordered;
-		lock_extent(&BTRFS_I(inode)->io_tree,
-			    start_pos, last_pos - 1, GFP_NOFS);
+		lock_extent_bits(&BTRFS_I(inode)->io_tree,
+				 start_pos, last_pos - 1, 0, &cached_state,
+				 GFP_NOFS);
 		ordered = btrfs_lookup_first_ordered_extent(inode,
 							    last_pos - 1);
 		if (ordered &&
 		    ordered->file_offset + ordered->len > start_pos &&
 		    ordered->file_offset < last_pos) {
 			btrfs_put_ordered_extent(ordered);
-			unlock_extent(&BTRFS_I(inode)->io_tree,
-				      start_pos, last_pos - 1, GFP_NOFS);
+			unlock_extent_cached(&BTRFS_I(inode)->io_tree,
+					     start_pos, last_pos - 1,
+					     &cached_state, GFP_NOFS);
 			for (i = 0; i < num_pages; i++) {
 				unlock_page(pages[i]);
 				page_cache_release(pages[i]);
@@ -802,12 +807,13 @@ again:
 		if (ordered)
 			btrfs_put_ordered_extent(ordered);
 
-		clear_extent_bits(&BTRFS_I(inode)->io_tree, start_pos,
+		clear_extent_bit(&BTRFS_I(inode)->io_tree, start_pos,
 				  last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
-				  EXTENT_DO_ACCOUNTING,
+				  EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
 				  GFP_NOFS);
-		unlock_extent(&BTRFS_I(inode)->io_tree,
-			      start_pos, last_pos - 1, GFP_NOFS);
+		unlock_extent_cached(&BTRFS_I(inode)->io_tree,
+				     start_pos, last_pos - 1, &cached_state,
+				     GFP_NOFS);
 	}
 	for (i = 0; i < num_pages; i++) {
 		clear_page_dirty_for_io(pages[i]);
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/file-item.c linux-libre-2.6.34-gnu1/fs/btrfs/file-item.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/file-item.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/file-item.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 
 #include <linux/bio.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/highmem.h>
 #include "ctree.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/free-space-cache.c linux-libre-2.6.34-gnu1/fs/btrfs/free-space-cache.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/free-space-cache.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/free-space-cache.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 
 #include <linux/pagemap.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/math64.h>
 #include "ctree.h"
 #include "free-space-cache.h"
@@ -870,7 +871,7 @@ __btrfs_return_cluster_to_free_space(
 		tree_insert_offset(&block_group->free_space_offset,
 				   entry->offset, &entry->offset_index, 0);
 	}
-	cluster->root.rb_node = NULL;
+	cluster->root = RB_ROOT;
 
 out:
 	spin_unlock(&cluster->lock);
@@ -1355,7 +1356,7 @@ void btrfs_init_free_cluster(struct btrf
 {
 	spin_lock_init(&cluster->lock);
 	spin_lock_init(&cluster->refill_lock);
-	cluster->root.rb_node = NULL;
+	cluster->root = RB_ROOT;
 	cluster->max_size = 0;
 	cluster->points_to_bitmap = false;
 	INIT_LIST_HEAD(&cluster->block_group_list);
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/inode.c linux-libre-2.6.34-gnu1/fs/btrfs/inode.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/xattr.h>
 #include <linux/posix_acl.h>
 #include <linux/falloc.h>
+#include <linux/slab.h>
 #include "compat.h"
 #include "ctree.h"
 #include "disk-io.h"
@@ -379,7 +380,8 @@ again:
 	 * change at any time if we discover bad compression ratios.
 	 */
 	if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS) &&
-	    btrfs_test_opt(root, COMPRESS)) {
+	    (btrfs_test_opt(root, COMPRESS) ||
+	     (BTRFS_I(inode)->force_compress))) {
 		WARN_ON(pages);
 		pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS);
 
@@ -483,8 +485,10 @@ again:
 		nr_pages_ret = 0;
 
 		/* flag the file so we don't compress in the future */
-		if (!btrfs_test_opt(root, FORCE_COMPRESS))
+		if (!btrfs_test_opt(root, FORCE_COMPRESS) &&
+		    !(BTRFS_I(inode)->force_compress)) {
 			BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS;
+		}
 	}
 	if (will_compress) {
 		*num_added += 1;
@@ -570,8 +574,8 @@ retry:
 			unsigned long nr_written = 0;
 
 			lock_extent(io_tree, async_extent->start,
-				    async_extent->start +
-				    async_extent->ram_size - 1, GFP_NOFS);
+					 async_extent->start +
+					 async_extent->ram_size - 1, GFP_NOFS);
 
 			/* allocate blocks */
 			ret = cow_file_range(inode, async_cow->locked_page,
@@ -793,7 +797,7 @@ static noinline int cow_file_range(struc
 	while (disk_num_bytes > 0) {
 		unsigned long op;
 
-		cur_alloc_size = min(disk_num_bytes, root->fs_info->max_extent);
+		cur_alloc_size = disk_num_bytes;
 		ret = btrfs_reserve_extent(trans, root, cur_alloc_size,
 					   root->sectorsize, 0, alloc_hint,
 					   (u64)-1, &ins, 1);
@@ -1211,7 +1215,8 @@ static int run_delalloc_range(struct ino
 	else if (BTRFS_I(inode)->flags & BTRFS_INODE_PREALLOC)
 		ret = run_delalloc_nocow(inode, locked_page, start, end,
 					 page_started, 0, nr_written);
-	else if (!btrfs_test_opt(root, COMPRESS))
+	else if (!btrfs_test_opt(root, COMPRESS) &&
+		 !(BTRFS_I(inode)->force_compress))
 		ret = cow_file_range(inode, locked_page, start, end,
 				      page_started, nr_written, 1);
 	else
@@ -1223,30 +1228,9 @@ static int run_delalloc_range(struct ino
 static int btrfs_split_extent_hook(struct inode *inode,
 				    struct extent_state *orig, u64 split)
 {
-	struct btrfs_root *root = BTRFS_I(inode)->root;
-	u64 size;
-
 	if (!(orig->state & EXTENT_DELALLOC))
 		return 0;
 
-	size = orig->end - orig->start + 1;
-	if (size > root->fs_info->max_extent) {
-		u64 num_extents;
-		u64 new_size;
-
-		new_size = orig->end - split + 1;
-		num_extents = div64_u64(size + root->fs_info->max_extent - 1,
-					root->fs_info->max_extent);
-
-		/*
-		 * if we break a large extent up then leave oustanding_extents
-		 * be, since we've already accounted for the large extent.
-		 */
-		if (div64_u64(new_size + root->fs_info->max_extent - 1,
-			      root->fs_info->max_extent) < num_extents)
-			return 0;
-	}
-
 	spin_lock(&BTRFS_I(inode)->accounting_lock);
 	BTRFS_I(inode)->outstanding_extents++;
 	spin_unlock(&BTRFS_I(inode)->accounting_lock);
@@ -1264,38 +1248,10 @@ static int btrfs_merge_extent_hook(struc
 				   struct extent_state *new,
 				   struct extent_state *other)
 {
-	struct btrfs_root *root = BTRFS_I(inode)->root;
-	u64 new_size, old_size;
-	u64 num_extents;
-
 	/* not delalloc, ignore it */
 	if (!(other->state & EXTENT_DELALLOC))
 		return 0;
 
-	old_size = other->end - other->start + 1;
-	if (new->start < other->start)
-		new_size = other->end - new->start + 1;
-	else
-		new_size = new->end - other->start + 1;
-
-	/* we're not bigger than the max, unreserve the space and go */
-	if (new_size <= root->fs_info->max_extent) {
-		spin_lock(&BTRFS_I(inode)->accounting_lock);
-		BTRFS_I(inode)->outstanding_extents--;
-		spin_unlock(&BTRFS_I(inode)->accounting_lock);
-		return 0;
-	}
-
-	/*
-	 * If we grew by another max_extent, just return, we want to keep that
-	 * reserved amount.
-	 */
-	num_extents = div64_u64(old_size + root->fs_info->max_extent - 1,
-				root->fs_info->max_extent);
-	if (div64_u64(new_size + root->fs_info->max_extent - 1,
-		      root->fs_info->max_extent) > num_extents)
-		return 0;
-
 	spin_lock(&BTRFS_I(inode)->accounting_lock);
 	BTRFS_I(inode)->outstanding_extents--;
 	spin_unlock(&BTRFS_I(inode)->accounting_lock);
@@ -1324,6 +1280,7 @@ static int btrfs_set_bit_hook(struct ino
 		BTRFS_I(inode)->outstanding_extents++;
 		spin_unlock(&BTRFS_I(inode)->accounting_lock);
 		btrfs_delalloc_reserve_space(root, inode, end - start + 1);
+
 		spin_lock(&root->fs_info->delalloc_lock);
 		BTRFS_I(inode)->delalloc_bytes += end - start + 1;
 		root->fs_info->delalloc_bytes += end - start + 1;
@@ -1352,6 +1309,7 @@ static int btrfs_clear_bit_hook(struct i
 
 		if (bits & EXTENT_DO_ACCOUNTING) {
 			spin_lock(&BTRFS_I(inode)->accounting_lock);
+			WARN_ON(!BTRFS_I(inode)->outstanding_extents);
 			BTRFS_I(inode)->outstanding_extents--;
 			spin_unlock(&BTRFS_I(inode)->accounting_lock);
 			btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
@@ -1508,12 +1466,13 @@ static noinline int add_pending_csums(st
 	return 0;
 }
 
-int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end)
+int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
+			      struct extent_state **cached_state)
 {
 	if ((end & (PAGE_CACHE_SIZE - 1)) == 0)
 		WARN_ON(1);
 	return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end,
-				   GFP_NOFS);
+				   cached_state, GFP_NOFS);
 }
 
 /* see btrfs_writepage_start_hook for details on why this is required */
@@ -1526,6 +1485,7 @@ static void btrfs_writepage_fixup_worker
 {
 	struct btrfs_writepage_fixup *fixup;
 	struct btrfs_ordered_extent *ordered;
+	struct extent_state *cached_state = NULL;
 	struct page *page;
 	struct inode *inode;
 	u64 page_start;
@@ -1544,7 +1504,8 @@ again:
 	page_start = page_offset(page);
 	page_end = page_offset(page) + PAGE_CACHE_SIZE - 1;
 
-	lock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS);
+	lock_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end, 0,
+			 &cached_state, GFP_NOFS);
 
 	/* already ordered? We're done */
 	if (PagePrivate2(page))
@@ -1552,17 +1513,18 @@ again:
 
 	ordered = btrfs_lookup_ordered_extent(inode, page_start);
 	if (ordered) {
-		unlock_extent(&BTRFS_I(inode)->io_tree, page_start,
-			      page_end, GFP_NOFS);
+		unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start,
+				     page_end, &cached_state, GFP_NOFS);
 		unlock_page(page);
 		btrfs_start_ordered_extent(inode, ordered, 1);
 		goto again;
 	}
 
-	btrfs_set_extent_delalloc(inode, page_start, page_end);
+	btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state);
 	ClearPageChecked(page);
 out:
-	unlock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS);
+	unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end,
+			     &cached_state, GFP_NOFS);
 out_page:
 	unlock_page(page);
 	page_cache_release(page);
@@ -1691,14 +1653,14 @@ static int btrfs_finish_ordered_io(struc
 	struct btrfs_trans_handle *trans;
 	struct btrfs_ordered_extent *ordered_extent = NULL;
 	struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
+	struct extent_state *cached_state = NULL;
 	int compressed = 0;
 	int ret;
 
-	ret = btrfs_dec_test_ordered_pending(inode, start, end - start + 1);
+	ret = btrfs_dec_test_ordered_pending(inode, &ordered_extent, start,
+					     end - start + 1);
 	if (!ret)
 		return 0;
-
-	ordered_extent = btrfs_lookup_ordered_extent(inode, start);
 	BUG_ON(!ordered_extent);
 
 	if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) {
@@ -1713,9 +1675,9 @@ static int btrfs_finish_ordered_io(struc
 		goto out;
 	}
 
-	lock_extent(io_tree, ordered_extent->file_offset,
-		    ordered_extent->file_offset + ordered_extent->len - 1,
-		    GFP_NOFS);
+	lock_extent_bits(io_tree, ordered_extent->file_offset,
+			 ordered_extent->file_offset + ordered_extent->len - 1,
+			 0, &cached_state, GFP_NOFS);
 
 	trans = btrfs_join_transaction(root, 1);
 
@@ -1742,9 +1704,10 @@ static int btrfs_finish_ordered_io(struc
 				   ordered_extent->len);
 		BUG_ON(ret);
 	}
-	unlock_extent(io_tree, ordered_extent->file_offset,
-		    ordered_extent->file_offset + ordered_extent->len - 1,
-		    GFP_NOFS);
+	unlock_extent_cached(io_tree, ordered_extent->file_offset,
+			     ordered_extent->file_offset +
+			     ordered_extent->len - 1, &cached_state, GFP_NOFS);
+
 	add_pending_csums(trans, inode, ordered_extent->file_offset,
 			  &ordered_extent->list);
 
@@ -2153,7 +2116,7 @@ void btrfs_orphan_cleanup(struct btrfs_r
 		found_key.objectid = found_key.offset;
 		found_key.type = BTRFS_INODE_ITEM_KEY;
 		found_key.offset = 0;
-		inode = btrfs_iget(root->fs_info->sb, &found_key, root);
+		inode = btrfs_iget(root->fs_info->sb, &found_key, root, NULL);
 		if (IS_ERR(inode))
 			break;
 
@@ -3081,6 +3044,7 @@ static int btrfs_truncate_page(struct ad
 	struct btrfs_root *root = BTRFS_I(inode)->root;
 	struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
 	struct btrfs_ordered_extent *ordered;
+	struct extent_state *cached_state = NULL;
 	char *kaddr;
 	u32 blocksize = root->sectorsize;
 	pgoff_t index = from >> PAGE_CACHE_SHIFT;
@@ -3127,12 +3091,14 @@ again:
 	}
 	wait_on_page_writeback(page);
 
-	lock_extent(io_tree, page_start, page_end, GFP_NOFS);
+	lock_extent_bits(io_tree, page_start, page_end, 0, &cached_state,
+			 GFP_NOFS);
 	set_page_extent_mapped(page);
 
 	ordered = btrfs_lookup_ordered_extent(inode, page_start);
 	if (ordered) {
-		unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+		unlock_extent_cached(io_tree, page_start, page_end,
+				     &cached_state, GFP_NOFS);
 		unlock_page(page);
 		page_cache_release(page);
 		btrfs_start_ordered_extent(inode, ordered, 1);
@@ -3140,13 +3106,15 @@ again:
 		goto again;
 	}
 
-	clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end,
+	clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end,
 			  EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
-			  GFP_NOFS);
+			  0, 0, &cached_state, GFP_NOFS);
 
-	ret = btrfs_set_extent_delalloc(inode, page_start, page_end);
+	ret = btrfs_set_extent_delalloc(inode, page_start, page_end,
+					&cached_state);
 	if (ret) {
-		unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+		unlock_extent_cached(io_tree, page_start, page_end,
+				     &cached_state, GFP_NOFS);
 		goto out_unlock;
 	}
 
@@ -3159,7 +3127,8 @@ again:
 	}
 	ClearPageChecked(page);
 	set_page_dirty(page);
-	unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+	unlock_extent_cached(io_tree, page_start, page_end, &cached_state,
+			     GFP_NOFS);
 
 out_unlock:
 	if (ret)
@@ -3177,6 +3146,7 @@ int btrfs_cont_expand(struct inode *inod
 	struct btrfs_root *root = BTRFS_I(inode)->root;
 	struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
 	struct extent_map *em;
+	struct extent_state *cached_state = NULL;
 	u64 mask = root->sectorsize - 1;
 	u64 hole_start = (inode->i_size + mask) & ~mask;
 	u64 block_end = (size + mask) & ~mask;
@@ -3192,11 +3162,13 @@ int btrfs_cont_expand(struct inode *inod
 		struct btrfs_ordered_extent *ordered;
 		btrfs_wait_ordered_range(inode, hole_start,
 					 block_end - hole_start);
-		lock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS);
+		lock_extent_bits(io_tree, hole_start, block_end - 1, 0,
+				 &cached_state, GFP_NOFS);
 		ordered = btrfs_lookup_ordered_extent(inode, hole_start);
 		if (!ordered)
 			break;
-		unlock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS);
+		unlock_extent_cached(io_tree, hole_start, block_end - 1,
+				     &cached_state, GFP_NOFS);
 		btrfs_put_ordered_extent(ordered);
 	}
 
@@ -3241,7 +3213,8 @@ int btrfs_cont_expand(struct inode *inod
 			break;
 	}
 
-	unlock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS);
+	unlock_extent_cached(io_tree, hole_start, block_end - 1, &cached_state,
+			     GFP_NOFS);
 	return err;
 }
 
@@ -3639,6 +3612,7 @@ static noinline void init_btrfs_i(struct
 	bi->index_cnt = (u64)-1;
 	bi->last_unlink_trans = 0;
 	bi->ordered_data_close = 0;
+	bi->force_compress = 0;
 	extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS);
 	extent_io_tree_init(&BTRFS_I(inode)->io_tree,
 			     inode->i_mapping, GFP_NOFS);
@@ -3687,7 +3661,7 @@ static struct inode *btrfs_iget_locked(s
  * Returns in *is_new if the inode was read from disk
  */
 struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
-			 struct btrfs_root *root)
+			 struct btrfs_root *root, int *new)
 {
 	struct inode *inode;
 
@@ -3702,6 +3676,8 @@ struct inode *btrfs_iget(struct super_bl
 
 		inode_tree_add(inode);
 		unlock_new_inode(inode);
+		if (new)
+			*new = 1;
 	}
 
 	return inode;
@@ -3754,7 +3730,7 @@ struct inode *btrfs_lookup_dentry(struct
 		return NULL;
 
 	if (location.type == BTRFS_INODE_ITEM_KEY) {
-		inode = btrfs_iget(dir->i_sb, &location, root);
+		inode = btrfs_iget(dir->i_sb, &location, root, NULL);
 		return inode;
 	}
 
@@ -3769,7 +3745,7 @@ struct inode *btrfs_lookup_dentry(struct
 		else
 			inode = new_simple_dir(dir->i_sb, &location, sub_root);
 	} else {
-		inode = btrfs_iget(dir->i_sb, &location, sub_root);
+		inode = btrfs_iget(dir->i_sb, &location, sub_root, NULL);
 	}
 	srcu_read_unlock(&root->fs_info->subvol_srcu, index);
 
@@ -3968,7 +3944,7 @@ err:
 	return ret;
 }
 
-int btrfs_write_inode(struct inode *inode, int wait)
+int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
 	struct btrfs_root *root = BTRFS_I(inode)->root;
 	struct btrfs_trans_handle *trans;
@@ -3977,7 +3953,7 @@ int btrfs_write_inode(struct inode *inod
 	if (root->fs_info->btree_inode == inode)
 		return 0;
 
-	if (wait) {
+	if (wbc->sync_mode == WB_SYNC_ALL) {
 		trans = btrfs_join_transaction(root, 1);
 		btrfs_set_trans_block_group(trans, inode);
 		ret = btrfs_commit_transaction(trans, root);
@@ -4501,7 +4477,7 @@ static int btrfs_mkdir(struct inode *dir
 	err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
 	if (err) {
 		err = -ENOSPC;
-		goto out_unlock;
+		goto out_fail;
 	}
 
 	inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
@@ -4979,6 +4955,7 @@ static void btrfs_invalidatepage(struct
 {
 	struct extent_io_tree *tree;
 	struct btrfs_ordered_extent *ordered;
+	struct extent_state *cached_state = NULL;
 	u64 page_start = page_offset(page);
 	u64 page_end = page_start + PAGE_CACHE_SIZE - 1;
 
@@ -4997,7 +4974,8 @@ static void btrfs_invalidatepage(struct
 		btrfs_releasepage(page, GFP_NOFS);
 		return;
 	}
-	lock_extent(tree, page_start, page_end, GFP_NOFS);
+	lock_extent_bits(tree, page_start, page_end, 0, &cached_state,
+			 GFP_NOFS);
 	ordered = btrfs_lookup_ordered_extent(page->mapping->host,
 					   page_offset(page));
 	if (ordered) {
@@ -5008,7 +4986,7 @@ static void btrfs_invalidatepage(struct
 		clear_extent_bit(tree, page_start, page_end,
 				 EXTENT_DIRTY | EXTENT_DELALLOC |
 				 EXTENT_LOCKED | EXTENT_DO_ACCOUNTING, 1, 0,
-				 NULL, GFP_NOFS);
+				 &cached_state, GFP_NOFS);
 		/*
 		 * whoever cleared the private bit is responsible
 		 * for the finish_ordered_io
@@ -5018,11 +4996,13 @@ static void btrfs_invalidatepage(struct
 						page_start, page_end);
 		}
 		btrfs_put_ordered_extent(ordered);
-		lock_extent(tree, page_start, page_end, GFP_NOFS);
+		cached_state = NULL;
+		lock_extent_bits(tree, page_start, page_end, 0, &cached_state,
+				 GFP_NOFS);
 	}
 	clear_extent_bit(tree, page_start, page_end,
 		 EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
-		 EXTENT_DO_ACCOUNTING, 1, 1, NULL, GFP_NOFS);
+		 EXTENT_DO_ACCOUNTING, 1, 1, &cached_state, GFP_NOFS);
 	__btrfs_releasepage(page, GFP_NOFS);
 
 	ClearPageChecked(page);
@@ -5055,6 +5035,7 @@ int btrfs_page_mkwrite(struct vm_area_st
 	struct btrfs_root *root = BTRFS_I(inode)->root;
 	struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
 	struct btrfs_ordered_extent *ordered;
+	struct extent_state *cached_state = NULL;
 	char *kaddr;
 	unsigned long zero_start;
 	loff_t size;
@@ -5093,7 +5074,8 @@ again:
 	}
 	wait_on_page_writeback(page);
 
-	lock_extent(io_tree, page_start, page_end, GFP_NOFS);
+	lock_extent_bits(io_tree, page_start, page_end, 0, &cached_state,
+			 GFP_NOFS);
 	set_page_extent_mapped(page);
 
 	/*
@@ -5102,7 +5084,8 @@ again:
 	 */
 	ordered = btrfs_lookup_ordered_extent(inode, page_start);
 	if (ordered) {
-		unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+		unlock_extent_cached(io_tree, page_start, page_end,
+				     &cached_state, GFP_NOFS);
 		unlock_page(page);
 		btrfs_start_ordered_extent(inode, ordered, 1);
 		btrfs_put_ordered_extent(ordered);
@@ -5116,13 +5099,15 @@ again:
 	 * is probably a better way to do this, but for now keep consistent with
 	 * prepare_pages in the normal write path.
 	 */
-	clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end,
+	clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end,
 			  EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
-			  GFP_NOFS);
+			  0, 0, &cached_state, GFP_NOFS);
 
-	ret = btrfs_set_extent_delalloc(inode, page_start, page_end);
+	ret = btrfs_set_extent_delalloc(inode, page_start, page_end,
+					&cached_state);
 	if (ret) {
-		unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+		unlock_extent_cached(io_tree, page_start, page_end,
+				     &cached_state, GFP_NOFS);
 		ret = VM_FAULT_SIGBUS;
 		btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
 		goto out_unlock;
@@ -5148,7 +5133,7 @@ again:
 	BTRFS_I(inode)->last_trans = root->fs_info->generation;
 	BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid;
 
-	unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+	unlock_extent_cached(io_tree, page_start, page_end, &cached_state, GFP_NOFS);
 
 out_unlock:
 	btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
@@ -5353,7 +5338,6 @@ free:
 void btrfs_drop_inode(struct inode *inode)
 {
 	struct btrfs_root *root = BTRFS_I(inode)->root;
-
 	if (inode->i_nlink > 0 && btrfs_root_refs(&root->root_item) == 0)
 		generic_delete_inode(inode);
 	else
@@ -5757,18 +5741,15 @@ static int prealloc_file_range(struct in
 	struct btrfs_trans_handle *trans;
 	struct btrfs_root *root = BTRFS_I(inode)->root;
 	struct btrfs_key ins;
-	u64 alloc_size;
 	u64 cur_offset = start;
 	u64 num_bytes = end - start;
 	int ret = 0;
 	u64 i_size;
 
 	while (num_bytes > 0) {
-		alloc_size = min(num_bytes, root->fs_info->max_extent);
-
 		trans = btrfs_start_transaction(root, 1);
 
-		ret = btrfs_reserve_extent(trans, root, alloc_size,
+		ret = btrfs_reserve_extent(trans, root, num_bytes,
 					   root->sectorsize, 0, alloc_hint,
 					   (u64)-1, &ins, 1);
 		if (ret) {
@@ -5827,6 +5808,7 @@ stop_trans:
 static long btrfs_fallocate(struct inode *inode, int mode,
 			    loff_t offset, loff_t len)
 {
+	struct extent_state *cached_state = NULL;
 	u64 cur_offset;
 	u64 last_byte;
 	u64 alloc_start;
@@ -5865,16 +5847,17 @@ static long btrfs_fallocate(struct inode
 		/* the extent lock is ordered inside the running
 		 * transaction
 		 */
-		lock_extent(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
-			    GFP_NOFS);
+		lock_extent_bits(&BTRFS_I(inode)->io_tree, alloc_start,
+				 locked_end, 0, &cached_state, GFP_NOFS);
 		ordered = btrfs_lookup_first_ordered_extent(inode,
 							    alloc_end - 1);
 		if (ordered &&
 		    ordered->file_offset + ordered->len > alloc_start &&
 		    ordered->file_offset < alloc_end) {
 			btrfs_put_ordered_extent(ordered);
-			unlock_extent(&BTRFS_I(inode)->io_tree,
-				      alloc_start, locked_end, GFP_NOFS);
+			unlock_extent_cached(&BTRFS_I(inode)->io_tree,
+					     alloc_start, locked_end,
+					     &cached_state, GFP_NOFS);
 			/*
 			 * we can't wait on the range with the transaction
 			 * running or with the extent lock held
@@ -5916,8 +5899,8 @@ static long btrfs_fallocate(struct inode
 			break;
 		}
 	}
-	unlock_extent(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
-		      GFP_NOFS);
+	unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
+			     &cached_state, GFP_NOFS);
 
 	btrfs_free_reserved_data_space(BTRFS_I(inode)->root, inode,
 				       alloc_end - alloc_start);
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/ioctl.c linux-libre-2.6.34-gnu1/fs/btrfs/ioctl.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/security.h>
 #include <linux/xattr.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include "compat.h"
 #include "ctree.h"
 #include "disk-io.h"
@@ -474,7 +475,79 @@ out_unlock:
 	return error;
 }
 
-static int btrfs_defrag_file(struct file *file)
+static int should_defrag_range(struct inode *inode, u64 start, u64 len,
+			       int thresh, u64 *last_len, u64 *skip,
+			       u64 *defrag_end)
+{
+	struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
+	struct extent_map *em = NULL;
+	struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
+	int ret = 1;
+
+
+	if (thresh == 0)
+		thresh = 256 * 1024;
+
+	/*
+	 * make sure that once we start defragging and extent, we keep on
+	 * defragging it
+	 */
+	if (start < *defrag_end)
+		return 1;
+
+	*skip = 0;
+
+	/*
+	 * hopefully we have this extent in the tree already, try without
+	 * the full extent lock
+	 */
+	read_lock(&em_tree->lock);
+	em = lookup_extent_mapping(em_tree, start, len);
+	read_unlock(&em_tree->lock);
+
+	if (!em) {
+		/* get the big lock and read metadata off disk */
+		lock_extent(io_tree, start, start + len - 1, GFP_NOFS);
+		em = btrfs_get_extent(inode, NULL, 0, start, len, 0);
+		unlock_extent(io_tree, start, start + len - 1, GFP_NOFS);
+
+		if (IS_ERR(em))
+			return 0;
+	}
+
+	/* this will cover holes, and inline extents */
+	if (em->block_start >= EXTENT_MAP_LAST_BYTE)
+		ret = 0;
+
+	/*
+	 * we hit a real extent, if it is big don't bother defragging it again
+	 */
+	if ((*last_len == 0 || *last_len >= thresh) && em->len >= thresh)
+		ret = 0;
+
+	/*
+	 * last_len ends up being a counter of how many bytes we've defragged.
+	 * every time we choose not to defrag an extent, we reset *last_len
+	 * so that the next tiny extent will force a defrag.
+	 *
+	 * The end result of this is that tiny extents before a single big
+	 * extent will force at least part of that big extent to be defragged.
+	 */
+	if (ret) {
+		*last_len += len;
+		*defrag_end = extent_map_end(em);
+	} else {
+		*last_len = 0;
+		*skip = extent_map_end(em);
+		*defrag_end = 0;
+	}
+
+	free_extent_map(em);
+	return ret;
+}
+
+static int btrfs_defrag_file(struct file *file,
+			     struct btrfs_ioctl_defrag_range_args *range)
 {
 	struct inode *inode = fdentry(file)->d_inode;
 	struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -486,37 +559,96 @@ static int btrfs_defrag_file(struct file
 	unsigned long total_read = 0;
 	u64 page_start;
 	u64 page_end;
+	u64 last_len = 0;
+	u64 skip = 0;
+	u64 defrag_end = 0;
 	unsigned long i;
 	int ret;
 
-	ret = btrfs_check_data_free_space(root, inode, inode->i_size);
-	if (ret)
-		return -ENOSPC;
+	if (inode->i_size == 0)
+		return 0;
+
+	if (range->start + range->len > range->start) {
+		last_index = min_t(u64, inode->i_size - 1,
+			 range->start + range->len - 1) >> PAGE_CACHE_SHIFT;
+	} else {
+		last_index = (inode->i_size - 1) >> PAGE_CACHE_SHIFT;
+	}
+
+	i = range->start >> PAGE_CACHE_SHIFT;
+	while (i <= last_index) {
+		if (!should_defrag_range(inode, (u64)i << PAGE_CACHE_SHIFT,
+					PAGE_CACHE_SIZE,
+					range->extent_thresh,
+					&last_len, &skip,
+					&defrag_end)) {
+			unsigned long next;
+			/*
+			 * the should_defrag function tells us how much to skip
+			 * bump our counter by the suggested amount
+			 */
+			next = (skip + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+			i = max(i + 1, next);
+			continue;
+		}
 
-	mutex_lock(&inode->i_mutex);
-	last_index = inode->i_size >> PAGE_CACHE_SHIFT;
-	for (i = 0; i <= last_index; i++) {
 		if (total_read % ra_pages == 0) {
 			btrfs_force_ra(inode->i_mapping, &file->f_ra, file, i,
 				       min(last_index, i + ra_pages - 1));
 		}
 		total_read++;
+		mutex_lock(&inode->i_mutex);
+		if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)
+			BTRFS_I(inode)->force_compress = 1;
+
+		ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE);
+		if (ret) {
+			ret = -ENOSPC;
+			break;
+		}
+
+		ret = btrfs_reserve_metadata_for_delalloc(root, inode, 1);
+		if (ret) {
+			btrfs_free_reserved_data_space(root, inode,
+						       PAGE_CACHE_SIZE);
+			ret = -ENOSPC;
+			break;
+		}
 again:
+		if (inode->i_size == 0 ||
+		    i > ((inode->i_size - 1) >> PAGE_CACHE_SHIFT)) {
+			ret = 0;
+			goto err_reservations;
+		}
+
 		page = grab_cache_page(inode->i_mapping, i);
 		if (!page)
-			goto out_unlock;
+			goto err_reservations;
+
 		if (!PageUptodate(page)) {
 			btrfs_readpage(NULL, page);
 			lock_page(page);
 			if (!PageUptodate(page)) {
 				unlock_page(page);
 				page_cache_release(page);
-				goto out_unlock;
+				goto err_reservations;
 			}
 		}
 
+		if (page->mapping != inode->i_mapping) {
+			unlock_page(page);
+			page_cache_release(page);
+			goto again;
+		}
+
 		wait_on_page_writeback(page);
 
+		if (PageDirty(page)) {
+			btrfs_free_reserved_data_space(root, inode,
+						       PAGE_CACHE_SIZE);
+			goto loop_unlock;
+		}
+
 		page_start = (u64)page->index << PAGE_CACHE_SHIFT;
 		page_end = page_start + PAGE_CACHE_SIZE - 1;
 		lock_extent(io_tree, page_start, page_end, GFP_NOFS);
@@ -537,18 +669,54 @@ again:
 		 * page if it is dirtied again later
 		 */
 		clear_page_dirty_for_io(page);
+		clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start,
+				  page_end, EXTENT_DIRTY | EXTENT_DELALLOC |
+				  EXTENT_DO_ACCOUNTING, GFP_NOFS);
 
-		btrfs_set_extent_delalloc(inode, page_start, page_end);
+		btrfs_set_extent_delalloc(inode, page_start, page_end, NULL);
+		ClearPageChecked(page);
 		set_page_dirty(page);
 		unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+
+loop_unlock:
 		unlock_page(page);
 		page_cache_release(page);
+		mutex_unlock(&inode->i_mutex);
+
+		btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
 		balance_dirty_pages_ratelimited_nr(inode->i_mapping, 1);
+		i++;
+	}
+
+	if ((range->flags & BTRFS_DEFRAG_RANGE_START_IO))
+		filemap_flush(inode->i_mapping);
+
+	if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) {
+		/* the filemap_flush will queue IO into the worker threads, but
+		 * we have to make sure the IO is actually started and that
+		 * ordered extents get created before we return
+		 */
+		atomic_inc(&root->fs_info->async_submit_draining);
+		while (atomic_read(&root->fs_info->nr_async_submits) ||
+		      atomic_read(&root->fs_info->async_delalloc_pages)) {
+			wait_event(root->fs_info->async_submit_wait,
+			   (atomic_read(&root->fs_info->nr_async_submits) == 0 &&
+			    atomic_read(&root->fs_info->async_delalloc_pages) == 0));
+		}
+		atomic_dec(&root->fs_info->async_submit_draining);
+
+		mutex_lock(&inode->i_mutex);
+		BTRFS_I(inode)->force_compress = 0;
+		mutex_unlock(&inode->i_mutex);
 	}
 
-out_unlock:
-	mutex_unlock(&inode->i_mutex);
 	return 0;
+
+err_reservations:
+	mutex_unlock(&inode->i_mutex);
+	btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
+	btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
+	return ret;
 }
 
 static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
@@ -608,7 +776,7 @@ static noinline int btrfs_ioctl_resize(s
 			mod = 1;
 			sizestr++;
 		}
-		new_size = btrfs_parse_size(sizestr);
+		new_size = memparse(sizestr, NULL);
 		if (new_size == 0) {
 			ret = -EINVAL;
 			goto out_unlock;
@@ -743,6 +911,330 @@ out:
 	return ret;
 }
 
+static noinline int key_in_sk(struct btrfs_key *key,
+			      struct btrfs_ioctl_search_key *sk)
+{
+	struct btrfs_key test;
+	int ret;
+
+	test.objectid = sk->min_objectid;
+	test.type = sk->min_type;
+	test.offset = sk->min_offset;
+
+	ret = btrfs_comp_cpu_keys(key, &test);
+	if (ret < 0)
+		return 0;
+
+	test.objectid = sk->max_objectid;
+	test.type = sk->max_type;
+	test.offset = sk->max_offset;
+
+	ret = btrfs_comp_cpu_keys(key, &test);
+	if (ret > 0)
+		return 0;
+	return 1;
+}
+
+static noinline int copy_to_sk(struct btrfs_root *root,
+			       struct btrfs_path *path,
+			       struct btrfs_key *key,
+			       struct btrfs_ioctl_search_key *sk,
+			       char *buf,
+			       unsigned long *sk_offset,
+			       int *num_found)
+{
+	u64 found_transid;
+	struct extent_buffer *leaf;
+	struct btrfs_ioctl_search_header sh;
+	unsigned long item_off;
+	unsigned long item_len;
+	int nritems;
+	int i;
+	int slot;
+	int found = 0;
+	int ret = 0;
+
+	leaf = path->nodes[0];
+	slot = path->slots[0];
+	nritems = btrfs_header_nritems(leaf);
+
+	if (btrfs_header_generation(leaf) > sk->max_transid) {
+		i = nritems;
+		goto advance_key;
+	}
+	found_transid = btrfs_header_generation(leaf);
+
+	for (i = slot; i < nritems; i++) {
+		item_off = btrfs_item_ptr_offset(leaf, i);
+		item_len = btrfs_item_size_nr(leaf, i);
+
+		if (item_len > BTRFS_SEARCH_ARGS_BUFSIZE)
+			item_len = 0;
+
+		if (sizeof(sh) + item_len + *sk_offset >
+		    BTRFS_SEARCH_ARGS_BUFSIZE) {
+			ret = 1;
+			goto overflow;
+		}
+
+		btrfs_item_key_to_cpu(leaf, key, i);
+		if (!key_in_sk(key, sk))
+			continue;
+
+		sh.objectid = key->objectid;
+		sh.offset = key->offset;
+		sh.type = key->type;
+		sh.len = item_len;
+		sh.transid = found_transid;
+
+		/* copy search result header */
+		memcpy(buf + *sk_offset, &sh, sizeof(sh));
+		*sk_offset += sizeof(sh);
+
+		if (item_len) {
+			char *p = buf + *sk_offset;
+			/* copy the item */
+			read_extent_buffer(leaf, p,
+					   item_off, item_len);
+			*sk_offset += item_len;
+		}
+		found++;
+
+		if (*num_found >= sk->nr_items)
+			break;
+	}
+advance_key:
+	ret = 0;
+	if (key->offset < (u64)-1 && key->offset < sk->max_offset)
+		key->offset++;
+	else if (key->type < (u8)-1 && key->type < sk->max_type) {
+		key->offset = 0;
+		key->type++;
+	} else if (key->objectid < (u64)-1 && key->objectid < sk->max_objectid) {
+		key->offset = 0;
+		key->type = 0;
+		key->objectid++;
+	} else
+		ret = 1;
+overflow:
+	*num_found += found;
+	return ret;
+}
+
+static noinline int search_ioctl(struct inode *inode,
+				 struct btrfs_ioctl_search_args *args)
+{
+	struct btrfs_root *root;
+	struct btrfs_key key;
+	struct btrfs_key max_key;
+	struct btrfs_path *path;
+	struct btrfs_ioctl_search_key *sk = &args->key;
+	struct btrfs_fs_info *info = BTRFS_I(inode)->root->fs_info;
+	int ret;
+	int num_found = 0;
+	unsigned long sk_offset = 0;
+
+	path = btrfs_alloc_path();
+	if (!path)
+		return -ENOMEM;
+
+	if (sk->tree_id == 0) {
+		/* search the root of the inode that was passed */
+		root = BTRFS_I(inode)->root;
+	} else {
+		key.objectid = sk->tree_id;
+		key.type = BTRFS_ROOT_ITEM_KEY;
+		key.offset = (u64)-1;
+		root = btrfs_read_fs_root_no_name(info, &key);
+		if (IS_ERR(root)) {
+			printk(KERN_ERR "could not find root %llu\n",
+			       sk->tree_id);
+			btrfs_free_path(path);
+			return -ENOENT;
+		}
+	}
+
+	key.objectid = sk->min_objectid;
+	key.type = sk->min_type;
+	key.offset = sk->min_offset;
+
+	max_key.objectid = sk->max_objectid;
+	max_key.type = sk->max_type;
+	max_key.offset = sk->max_offset;
+
+	path->keep_locks = 1;
+
+	while(1) {
+		ret = btrfs_search_forward(root, &key, &max_key, path, 0,
+					   sk->min_transid);
+		if (ret != 0) {
+			if (ret > 0)
+				ret = 0;
+			goto err;
+		}
+		ret = copy_to_sk(root, path, &key, sk, args->buf,
+				 &sk_offset, &num_found);
+		btrfs_release_path(root, path);
+		if (ret || num_found >= sk->nr_items)
+			break;
+
+	}
+	ret = 0;
+err:
+	sk->nr_items = num_found;
+	btrfs_free_path(path);
+	return ret;
+}
+
+static noinline int btrfs_ioctl_tree_search(struct file *file,
+					   void __user *argp)
+{
+	 struct btrfs_ioctl_search_args *args;
+	 struct inode *inode;
+	 int ret;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	args = kmalloc(sizeof(*args), GFP_KERNEL);
+	if (!args)
+		return -ENOMEM;
+
+	if (copy_from_user(args, argp, sizeof(*args))) {
+		kfree(args);
+		return -EFAULT;
+	}
+	inode = fdentry(file)->d_inode;
+	ret = search_ioctl(inode, args);
+	if (ret == 0 && copy_to_user(argp, args, sizeof(*args)))
+		ret = -EFAULT;
+	kfree(args);
+	return ret;
+}
+
+/*
+ * Search INODE_REFs to identify path name of 'dirid' directory
+ * in a 'tree_id' tree. and sets path name to 'name'.
+ */
+static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info,
+				u64 tree_id, u64 dirid, char *name)
+{
+	struct btrfs_root *root;
+	struct btrfs_key key;
+	char *ptr;
+	int ret = -1;
+	int slot;
+	int len;
+	int total_len = 0;
+	struct btrfs_inode_ref *iref;
+	struct extent_buffer *l;
+	struct btrfs_path *path;
+
+	if (dirid == BTRFS_FIRST_FREE_OBJECTID) {
+		name[0]='\0';
+		return 0;
+	}
+
+	path = btrfs_alloc_path();
+	if (!path)
+		return -ENOMEM;
+
+	ptr = &name[BTRFS_INO_LOOKUP_PATH_MAX];
+
+	key.objectid = tree_id;
+	key.type = BTRFS_ROOT_ITEM_KEY;
+	key.offset = (u64)-1;
+	root = btrfs_read_fs_root_no_name(info, &key);
+	if (IS_ERR(root)) {
+		printk(KERN_ERR "could not find root %llu\n", tree_id);
+		ret = -ENOENT;
+		goto out;
+	}
+
+	key.objectid = dirid;
+	key.type = BTRFS_INODE_REF_KEY;
+	key.offset = (u64)-1;
+
+	while(1) {
+		ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+		if (ret < 0)
+			goto out;
+
+		l = path->nodes[0];
+		slot = path->slots[0];
+		if (ret > 0 && slot > 0)
+			slot--;
+		btrfs_item_key_to_cpu(l, &key, slot);
+
+		if (ret > 0 && (key.objectid != dirid ||
+				key.type != BTRFS_INODE_REF_KEY)) {
+			ret = -ENOENT;
+			goto out;
+		}
+
+		iref = btrfs_item_ptr(l, slot, struct btrfs_inode_ref);
+		len = btrfs_inode_ref_name_len(l, iref);
+		ptr -= len + 1;
+		total_len += len + 1;
+		if (ptr < name)
+			goto out;
+
+		*(ptr + len) = '/';
+		read_extent_buffer(l, ptr,(unsigned long)(iref + 1), len);
+
+		if (key.offset == BTRFS_FIRST_FREE_OBJECTID)
+			break;
+
+		btrfs_release_path(root, path);
+		key.objectid = key.offset;
+		key.offset = (u64)-1;
+		dirid = key.objectid;
+
+	}
+	if (ptr < name)
+		goto out;
+	memcpy(name, ptr, total_len);
+	name[total_len]='\0';
+	ret = 0;
+out:
+	btrfs_free_path(path);
+	return ret;
+}
+
+static noinline int btrfs_ioctl_ino_lookup(struct file *file,
+					   void __user *argp)
+{
+	 struct btrfs_ioctl_ino_lookup_args *args;
+	 struct inode *inode;
+	 int ret;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	args = kmalloc(sizeof(*args), GFP_KERNEL);
+	if (!args)
+		return -ENOMEM;
+
+	if (copy_from_user(args, argp, sizeof(*args))) {
+		kfree(args);
+		return -EFAULT;
+	}
+	inode = fdentry(file)->d_inode;
+
+	if (args->treeid == 0)
+		args->treeid = BTRFS_I(inode)->root->root_key.objectid;
+
+	ret = btrfs_search_path_in_tree(BTRFS_I(inode)->root->fs_info,
+					args->treeid, args->objectid,
+					args->name);
+
+	if (ret == 0 && copy_to_user(argp, args, sizeof(*args)))
+		ret = -EFAULT;
+
+	kfree(args);
+	return ret;
+}
+
 static noinline int btrfs_ioctl_snap_destroy(struct file *file,
 					     void __user *arg)
 {
@@ -849,10 +1341,11 @@ out:
 	return err;
 }
 
-static int btrfs_ioctl_defrag(struct file *file)
+static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
 {
 	struct inode *inode = fdentry(file)->d_inode;
 	struct btrfs_root *root = BTRFS_I(inode)->root;
+	struct btrfs_ioctl_defrag_range_args *range;
 	int ret;
 
 	ret = mnt_want_write(file->f_path.mnt);
@@ -873,7 +1366,31 @@ static int btrfs_ioctl_defrag(struct fil
 			ret = -EINVAL;
 			goto out;
 		}
-		btrfs_defrag_file(file);
+
+		range = kzalloc(sizeof(*range), GFP_KERNEL);
+		if (!range) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		if (argp) {
+			if (copy_from_user(range, argp,
+					   sizeof(*range))) {
+				ret = -EFAULT;
+				kfree(range);
+				goto out;
+			}
+			/* compression requires us to start the IO */
+			if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) {
+				range->flags |= BTRFS_DEFRAG_RANGE_START_IO;
+				range->extent_thresh = (u32)-1;
+			}
+		} else {
+			/* the rest are all set to zero by kzalloc */
+			range->len = (u64)-1;
+		}
+		btrfs_defrag_file(file, range);
+		kfree(range);
 		break;
 	}
 out:
@@ -964,12 +1481,17 @@ static noinline long btrfs_ioctl_clone(s
 		ret = -EBADF;
 		goto out_drop_write;
 	}
+
 	src = src_file->f_dentry->d_inode;
 
 	ret = -EINVAL;
 	if (src == inode)
 		goto out_fput;
 
+	/* the src must be open for reading */
+	if (!(src_file->f_mode & FMODE_READ))
+		goto out_fput;
+
 	ret = -EISDIR;
 	if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode))
 		goto out_fput;
@@ -1274,6 +1796,157 @@ out:
 	return ret;
 }
 
+static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
+{
+	struct inode *inode = fdentry(file)->d_inode;
+	struct btrfs_root *root = BTRFS_I(inode)->root;
+	struct btrfs_root *new_root;
+	struct btrfs_dir_item *di;
+	struct btrfs_trans_handle *trans;
+	struct btrfs_path *path;
+	struct btrfs_key location;
+	struct btrfs_disk_key disk_key;
+	struct btrfs_super_block *disk_super;
+	u64 features;
+	u64 objectid = 0;
+	u64 dir_id;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&objectid, argp, sizeof(objectid)))
+		return -EFAULT;
+
+	if (!objectid)
+		objectid = root->root_key.objectid;
+
+	location.objectid = objectid;
+	location.type = BTRFS_ROOT_ITEM_KEY;
+	location.offset = (u64)-1;
+
+	new_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
+	if (IS_ERR(new_root))
+		return PTR_ERR(new_root);
+
+	if (btrfs_root_refs(&new_root->root_item) == 0)
+		return -ENOENT;
+
+	path = btrfs_alloc_path();
+	if (!path)
+		return -ENOMEM;
+	path->leave_spinning = 1;
+
+	trans = btrfs_start_transaction(root, 1);
+	if (!trans) {
+		btrfs_free_path(path);
+		return -ENOMEM;
+	}
+
+	dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
+	di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path,
+				   dir_id, "default", 7, 1);
+	if (!di) {
+		btrfs_free_path(path);
+		btrfs_end_transaction(trans, root);
+		printk(KERN_ERR "Umm, you don't have the default dir item, "
+		       "this isn't going to work\n");
+		return -ENOENT;
+	}
+
+	btrfs_cpu_key_to_disk(&disk_key, &new_root->root_key);
+	btrfs_set_dir_item_key(path->nodes[0], di, &disk_key);
+	btrfs_mark_buffer_dirty(path->nodes[0]);
+	btrfs_free_path(path);
+
+	disk_super = &root->fs_info->super_copy;
+	features = btrfs_super_incompat_flags(disk_super);
+	if (!(features & BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)) {
+		features |= BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL;
+		btrfs_set_super_incompat_flags(disk_super, features);
+	}
+	btrfs_end_transaction(trans, root);
+
+	return 0;
+}
+
+long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
+{
+	struct btrfs_ioctl_space_args space_args;
+	struct btrfs_ioctl_space_info space;
+	struct btrfs_ioctl_space_info *dest;
+	struct btrfs_ioctl_space_info *dest_orig;
+	struct btrfs_ioctl_space_info *user_dest;
+	struct btrfs_space_info *info;
+	int alloc_size;
+	int ret = 0;
+	int slot_count = 0;
+
+	if (copy_from_user(&space_args,
+			   (struct btrfs_ioctl_space_args __user *)arg,
+			   sizeof(space_args)))
+		return -EFAULT;
+
+	/* first we count slots */
+	rcu_read_lock();
+	list_for_each_entry_rcu(info, &root->fs_info->space_info, list)
+		slot_count++;
+	rcu_read_unlock();
+
+	/* space_slots == 0 means they are asking for a count */
+	if (space_args.space_slots == 0) {
+		space_args.total_spaces = slot_count;
+		goto out;
+	}
+	alloc_size = sizeof(*dest) * slot_count;
+	/* we generally have at most 6 or so space infos, one for each raid
+	 * level.  So, a whole page should be more than enough for everyone
+	 */
+	if (alloc_size > PAGE_CACHE_SIZE)
+		return -ENOMEM;
+
+	space_args.total_spaces = 0;
+	dest = kmalloc(alloc_size, GFP_NOFS);
+	if (!dest)
+		return -ENOMEM;
+	dest_orig = dest;
+
+	/* now we have a buffer to copy into */
+	rcu_read_lock();
+	list_for_each_entry_rcu(info, &root->fs_info->space_info, list) {
+		/* make sure we don't copy more than we allocated
+		 * in our buffer
+		 */
+		if (slot_count == 0)
+			break;
+		slot_count--;
+
+		/* make sure userland has enough room in their buffer */
+		if (space_args.total_spaces >= space_args.space_slots)
+			break;
+
+		space.flags = info->flags;
+		space.total_bytes = info->total_bytes;
+		space.used_bytes = info->bytes_used;
+		memcpy(dest, &space, sizeof(space));
+		dest++;
+		space_args.total_spaces++;
+	}
+	rcu_read_unlock();
+
+	user_dest = (struct btrfs_ioctl_space_info *)
+		(arg + sizeof(struct btrfs_ioctl_space_args));
+
+	if (copy_to_user(user_dest, dest_orig, alloc_size))
+		ret = -EFAULT;
+
+	kfree(dest_orig);
+out:
+	if (ret == 0 && copy_to_user(arg, &space_args, sizeof(space_args)))
+		ret = -EFAULT;
+
+	return ret;
+}
+
 /*
  * there are many ways the trans_start and trans_end ioctls can lead
  * to deadlocks.  They should only be used by applications that
@@ -1320,8 +1993,12 @@ long btrfs_ioctl(struct file *file, unsi
 		return btrfs_ioctl_snap_create(file, argp, 1);
 	case BTRFS_IOC_SNAP_DESTROY:
 		return btrfs_ioctl_snap_destroy(file, argp);
+	case BTRFS_IOC_DEFAULT_SUBVOL:
+		return btrfs_ioctl_default_subvol(file, argp);
 	case BTRFS_IOC_DEFRAG:
-		return btrfs_ioctl_defrag(file);
+		return btrfs_ioctl_defrag(file, NULL);
+	case BTRFS_IOC_DEFRAG_RANGE:
+		return btrfs_ioctl_defrag(file, argp);
 	case BTRFS_IOC_RESIZE:
 		return btrfs_ioctl_resize(root, argp);
 	case BTRFS_IOC_ADD_DEV:
@@ -1338,6 +2015,12 @@ long btrfs_ioctl(struct file *file, unsi
 		return btrfs_ioctl_trans_start(file);
 	case BTRFS_IOC_TRANS_END:
 		return btrfs_ioctl_trans_end(file);
+	case BTRFS_IOC_TREE_SEARCH:
+		return btrfs_ioctl_tree_search(file, argp);
+	case BTRFS_IOC_INO_LOOKUP:
+		return btrfs_ioctl_ino_lookup(file, argp);
+	case BTRFS_IOC_SPACE_INFO:
+		return btrfs_ioctl_space_info(root, argp);
 	case BTRFS_IOC_SYNC:
 		btrfs_sync_fs(file->f_dentry->d_sb, 1);
 		return 0;
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/ioctl.h linux-libre-2.6.34-gnu1/fs/btrfs/ioctl.h
--- linux-libre-2.6.33-gnu1/fs/btrfs/ioctl.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/ioctl.h	2010-05-16 17:17:36.000000000 -0400
@@ -30,12 +30,114 @@ struct btrfs_ioctl_vol_args {
 	char name[BTRFS_PATH_NAME_MAX + 1];
 };
 
+#define BTRFS_INO_LOOKUP_PATH_MAX 4080
+struct btrfs_ioctl_ino_lookup_args {
+	__u64 treeid;
+	__u64 objectid;
+	char name[BTRFS_INO_LOOKUP_PATH_MAX];
+};
+
+struct btrfs_ioctl_search_key {
+	/* which root are we searching.  0 is the tree of tree roots */
+	__u64 tree_id;
+
+	/* keys returned will be >= min and <= max */
+	__u64 min_objectid;
+	__u64 max_objectid;
+
+	/* keys returned will be >= min and <= max */
+	__u64 min_offset;
+	__u64 max_offset;
+
+	/* max and min transids to search for */
+	__u64 min_transid;
+	__u64 max_transid;
+
+	/* keys returned will be >= min and <= max */
+	__u32 min_type;
+	__u32 max_type;
+
+	/*
+	 * how many items did userland ask for, and how many are we
+	 * returning
+	 */
+	__u32 nr_items;
+
+	/* align to 64 bits */
+	__u32 unused;
+
+	/* some extra for later */
+	__u64 unused1;
+	__u64 unused2;
+	__u64 unused3;
+	__u64 unused4;
+};
+
+struct btrfs_ioctl_search_header {
+	__u64 transid;
+	__u64 objectid;
+	__u64 offset;
+	__u32 type;
+	__u32 len;
+};
+
+#define BTRFS_SEARCH_ARGS_BUFSIZE (4096 - sizeof(struct btrfs_ioctl_search_key))
+/*
+ * the buf is an array of search headers where
+ * each header is followed by the actual item
+ * the type field is expanded to 32 bits for alignment
+ */
+struct btrfs_ioctl_search_args {
+	struct btrfs_ioctl_search_key key;
+	char buf[BTRFS_SEARCH_ARGS_BUFSIZE];
+};
+
 struct btrfs_ioctl_clone_range_args {
   __s64 src_fd;
   __u64 src_offset, src_length;
   __u64 dest_offset;
 };
 
+/* flags for the defrag range ioctl */
+#define BTRFS_DEFRAG_RANGE_COMPRESS 1
+#define BTRFS_DEFRAG_RANGE_START_IO 2
+
+struct btrfs_ioctl_defrag_range_args {
+	/* start of the defrag operation */
+	__u64 start;
+
+	/* number of bytes to defrag, use (u64)-1 to say all */
+	__u64 len;
+
+	/*
+	 * flags for the operation, which can include turning
+	 * on compression for this one defrag
+	 */
+	__u64 flags;
+
+	/*
+	 * any extent bigger than this will be considered
+	 * already defragged.  Use 0 to take the kernel default
+	 * Use 1 to say every single extent must be rewritten
+	 */
+	__u32 extent_thresh;
+
+	/* spare for later */
+	__u32 unused[5];
+};
+
+struct btrfs_ioctl_space_info {
+	__u64 flags;
+	__u64 total_bytes;
+	__u64 used_bytes;
+};
+
+struct btrfs_ioctl_space_args {
+	__u64 space_slots;
+	__u64 total_spaces;
+	struct btrfs_ioctl_space_info spaces[0];
+};
+
 #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
 				   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
@@ -67,4 +169,13 @@ struct btrfs_ioctl_clone_range_args {
 				   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_SNAP_DESTROY _IOW(BTRFS_IOCTL_MAGIC, 15, \
 				struct btrfs_ioctl_vol_args)
+#define BTRFS_IOC_DEFRAG_RANGE _IOW(BTRFS_IOCTL_MAGIC, 16, \
+				struct btrfs_ioctl_defrag_range_args)
+#define BTRFS_IOC_TREE_SEARCH _IOWR(BTRFS_IOCTL_MAGIC, 17, \
+				   struct btrfs_ioctl_search_args)
+#define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \
+				   struct btrfs_ioctl_ino_lookup_args)
+#define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64)
+#define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \
+				    struct btrfs_ioctl_space_args)
 #endif
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/locking.c linux-libre-2.6.34-gnu1/fs/btrfs/locking.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/locking.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/locking.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
  * Boston, MA 021110-1307, USA.
  */
 #include <linux/sched.h>
-#include <linux/gfp.h>
 #include <linux/pagemap.h>
 #include <linux/spinlock.h>
 #include <linux/page-flags.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/ordered-data.c linux-libre-2.6.34-gnu1/fs/btrfs/ordered-data.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/ordered-data.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/ordered-data.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,7 +16,6 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/writeback.h>
@@ -174,7 +173,6 @@ int btrfs_add_ordered_extent(struct inod
 	if (!entry)
 		return -ENOMEM;
 
-	mutex_lock(&tree->mutex);
 	entry->file_offset = file_offset;
 	entry->start = start;
 	entry->len = len;
@@ -190,16 +188,17 @@ int btrfs_add_ordered_extent(struct inod
 	INIT_LIST_HEAD(&entry->list);
 	INIT_LIST_HEAD(&entry->root_extent_list);
 
+	spin_lock(&tree->lock);
 	node = tree_insert(&tree->tree, file_offset,
 			   &entry->rb_node);
 	BUG_ON(node);
+	spin_unlock(&tree->lock);
 
 	spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
 	list_add_tail(&entry->root_extent_list,
 		      &BTRFS_I(inode)->root->fs_info->ordered_extents);
 	spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
 
-	mutex_unlock(&tree->mutex);
 	BUG_ON(node);
 	return 0;
 }
@@ -216,9 +215,9 @@ int btrfs_add_ordered_sum(struct inode *
 	struct btrfs_ordered_inode_tree *tree;
 
 	tree = &BTRFS_I(inode)->ordered_tree;
-	mutex_lock(&tree->mutex);
+	spin_lock(&tree->lock);
 	list_add_tail(&sum->list, &entry->list);
-	mutex_unlock(&tree->mutex);
+	spin_unlock(&tree->lock);
 	return 0;
 }
 
@@ -232,15 +231,16 @@ int btrfs_add_ordered_sum(struct inode *
  * to make sure this function only returns 1 once for a given ordered extent.
  */
 int btrfs_dec_test_ordered_pending(struct inode *inode,
+				   struct btrfs_ordered_extent **cached,
 				   u64 file_offset, u64 io_size)
 {
 	struct btrfs_ordered_inode_tree *tree;
 	struct rb_node *node;
-	struct btrfs_ordered_extent *entry;
+	struct btrfs_ordered_extent *entry = NULL;
 	int ret;
 
 	tree = &BTRFS_I(inode)->ordered_tree;
-	mutex_lock(&tree->mutex);
+	spin_lock(&tree->lock);
 	node = tree_search(tree, file_offset);
 	if (!node) {
 		ret = 1;
@@ -264,7 +264,11 @@ int btrfs_dec_test_ordered_pending(struc
 	else
 		ret = 1;
 out:
-	mutex_unlock(&tree->mutex);
+	if (!ret && cached && entry) {
+		*cached = entry;
+		atomic_inc(&entry->refs);
+	}
+	spin_unlock(&tree->lock);
 	return ret == 0;
 }
 
@@ -291,13 +295,14 @@ int btrfs_put_ordered_extent(struct btrf
 
 /*
  * remove an ordered extent from the tree.  No references are dropped
- * and you must wake_up entry->wait.  You must hold the tree mutex
+ * and you must wake_up entry->wait.  You must hold the tree lock
  * while you call this function.
  */
 static int __btrfs_remove_ordered_extent(struct inode *inode,
 				struct btrfs_ordered_extent *entry)
 {
 	struct btrfs_ordered_inode_tree *tree;
+	struct btrfs_root *root = BTRFS_I(inode)->root;
 	struct rb_node *node;
 
 	tree = &BTRFS_I(inode)->ordered_tree;
@@ -307,12 +312,13 @@ static int __btrfs_remove_ordered_extent
 	set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags);
 
 	spin_lock(&BTRFS_I(inode)->accounting_lock);
+	WARN_ON(!BTRFS_I(inode)->outstanding_extents);
 	BTRFS_I(inode)->outstanding_extents--;
 	spin_unlock(&BTRFS_I(inode)->accounting_lock);
 	btrfs_unreserve_metadata_for_delalloc(BTRFS_I(inode)->root,
 					      inode, 1);
 
-	spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
+	spin_lock(&root->fs_info->ordered_extent_lock);
 	list_del_init(&entry->root_extent_list);
 
 	/*
@@ -324,7 +330,7 @@ static int __btrfs_remove_ordered_extent
 	    !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY)) {
 		list_del_init(&BTRFS_I(inode)->ordered_operations);
 	}
-	spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
+	spin_unlock(&root->fs_info->ordered_extent_lock);
 
 	return 0;
 }
@@ -340,9 +346,9 @@ int btrfs_remove_ordered_extent(struct i
 	int ret;
 
 	tree = &BTRFS_I(inode)->ordered_tree;
-	mutex_lock(&tree->mutex);
+	spin_lock(&tree->lock);
 	ret = __btrfs_remove_ordered_extent(inode, entry);
-	mutex_unlock(&tree->mutex);
+	spin_unlock(&tree->lock);
 	wake_up(&entry->wait);
 
 	return ret;
@@ -567,7 +573,7 @@ struct btrfs_ordered_extent *btrfs_looku
 	struct btrfs_ordered_extent *entry = NULL;
 
 	tree = &BTRFS_I(inode)->ordered_tree;
-	mutex_lock(&tree->mutex);
+	spin_lock(&tree->lock);
 	node = tree_search(tree, file_offset);
 	if (!node)
 		goto out;
@@ -578,7 +584,7 @@ struct btrfs_ordered_extent *btrfs_looku
 	if (entry)
 		atomic_inc(&entry->refs);
 out:
-	mutex_unlock(&tree->mutex);
+	spin_unlock(&tree->lock);
 	return entry;
 }
 
@@ -594,7 +600,7 @@ btrfs_lookup_first_ordered_extent(struct
 	struct btrfs_ordered_extent *entry = NULL;
 
 	tree = &BTRFS_I(inode)->ordered_tree;
-	mutex_lock(&tree->mutex);
+	spin_lock(&tree->lock);
 	node = tree_search(tree, file_offset);
 	if (!node)
 		goto out;
@@ -602,7 +608,7 @@ btrfs_lookup_first_ordered_extent(struct
 	entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
 	atomic_inc(&entry->refs);
 out:
-	mutex_unlock(&tree->mutex);
+	spin_unlock(&tree->lock);
 	return entry;
 }
 
@@ -629,7 +635,7 @@ int btrfs_ordered_update_i_size(struct i
 	else
 		offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize);
 
-	mutex_lock(&tree->mutex);
+	spin_lock(&tree->lock);
 	disk_i_size = BTRFS_I(inode)->disk_i_size;
 
 	/* truncate file */
@@ -735,7 +741,7 @@ out:
 	 */
 	if (ordered)
 		__btrfs_remove_ordered_extent(inode, ordered);
-	mutex_unlock(&tree->mutex);
+	spin_unlock(&tree->lock);
 	if (ordered)
 		wake_up(&ordered->wait);
 	return ret;
@@ -762,7 +768,7 @@ int btrfs_find_ordered_sum(struct inode
 	if (!ordered)
 		return 1;
 
-	mutex_lock(&tree->mutex);
+	spin_lock(&tree->lock);
 	list_for_each_entry_reverse(ordered_sum, &ordered->list, list) {
 		if (disk_bytenr >= ordered_sum->bytenr) {
 			num_sectors = ordered_sum->len / sectorsize;
@@ -777,7 +783,7 @@ int btrfs_find_ordered_sum(struct inode
 		}
 	}
 out:
-	mutex_unlock(&tree->mutex);
+	spin_unlock(&tree->lock);
 	btrfs_put_ordered_extent(ordered);
 	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/ordered-data.h linux-libre-2.6.34-gnu1/fs/btrfs/ordered-data.h
--- linux-libre-2.6.33-gnu1/fs/btrfs/ordered-data.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/ordered-data.h	2010-05-16 17:17:36.000000000 -0400
@@ -21,7 +21,7 @@
 
 /* one of these per inode */
 struct btrfs_ordered_inode_tree {
-	struct mutex mutex;
+	spinlock_t lock;
 	struct rb_root tree;
 	struct rb_node *last;
 };
@@ -128,8 +128,8 @@ static inline int btrfs_ordered_sum_size
 static inline void
 btrfs_ordered_inode_tree_init(struct btrfs_ordered_inode_tree *t)
 {
-	mutex_init(&t->mutex);
-	t->tree.rb_node = NULL;
+	spin_lock_init(&t->lock);
+	t->tree = RB_ROOT;
 	t->last = NULL;
 }
 
@@ -137,7 +137,8 @@ int btrfs_put_ordered_extent(struct btrf
 int btrfs_remove_ordered_extent(struct inode *inode,
 				struct btrfs_ordered_extent *entry);
 int btrfs_dec_test_ordered_pending(struct inode *inode,
-				       u64 file_offset, u64 io_size);
+				   struct btrfs_ordered_extent **cached,
+				   u64 file_offset, u64 io_size);
 int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
 			     u64 start, u64 len, u64 disk_len, int tyep);
 int btrfs_add_ordered_sum(struct inode *inode,
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/ref-cache.c linux-libre-2.6.34-gnu1/fs/btrfs/ref-cache.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/ref-cache.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/ref-cache.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/sort.h>
 #include "ctree.h"
 #include "ref-cache.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/ref-cache.h linux-libre-2.6.34-gnu1/fs/btrfs/ref-cache.h
--- linux-libre-2.6.33-gnu1/fs/btrfs/ref-cache.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/ref-cache.h	2010-05-16 17:17:36.000000000 -0400
@@ -52,7 +52,7 @@ static inline size_t btrfs_leaf_ref_size
 
 static inline void btrfs_leaf_ref_tree_init(struct btrfs_leaf_ref_tree *tree)
 {
-	tree->root.rb_node = NULL;
+	tree->root = RB_ROOT;
 	INIT_LIST_HEAD(&tree->list);
 	spin_lock_init(&tree->lock);
 }
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/relocation.c linux-libre-2.6.34-gnu1/fs/btrfs/relocation.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/relocation.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/relocation.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/writeback.h>
 #include <linux/blkdev.h>
 #include <linux/rbtree.h>
+#include <linux/slab.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
@@ -170,14 +171,14 @@ struct async_merge {
 
 static void mapping_tree_init(struct mapping_tree *tree)
 {
-	tree->rb_root.rb_node = NULL;
+	tree->rb_root = RB_ROOT;
 	spin_lock_init(&tree->lock);
 }
 
 static void backref_cache_init(struct backref_cache *cache)
 {
 	int i;
-	cache->rb_root.rb_node = NULL;
+	cache->rb_root = RB_ROOT;
 	for (i = 0; i < BTRFS_MAX_LEVEL; i++)
 		INIT_LIST_HEAD(&cache->pending[i]);
 	spin_lock_init(&cache->lock);
@@ -2659,7 +2660,7 @@ static int relocate_file_extent_cluster(
 					EXTENT_BOUNDARY, GFP_NOFS);
 			nr++;
 		}
-		btrfs_set_extent_delalloc(inode, page_start, page_end);
+		btrfs_set_extent_delalloc(inode, page_start, page_end, NULL);
 
 		set_page_dirty(page);
 		dirty_page++;
@@ -3487,7 +3488,7 @@ static struct inode *create_reloc_inode(
 	key.objectid = objectid;
 	key.type = BTRFS_INODE_ITEM_KEY;
 	key.offset = 0;
-	inode = btrfs_iget(root->fs_info->sb, &key, root);
+	inode = btrfs_iget(root->fs_info->sb, &key, root, NULL);
 	BUG_ON(IS_ERR(inode) || is_bad_inode(inode));
 	BTRFS_I(inode)->index_cnt = group->key.objectid;
 
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/super.c linux-libre-2.6.34-gnu1/fs/btrfs/super.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/super.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/super.c	2010-05-16 17:17:36.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/namei.h>
 #include <linux/miscdevice.h>
 #include <linux/magic.h>
+#include <linux/slab.h>
 #include "compat.h"
 #include "ctree.h"
 #include "disk-io.h"
@@ -63,22 +64,21 @@ static void btrfs_put_super(struct super
 }
 
 enum {
-	Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow,
-	Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier,
-	Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl,
-	Opt_compress, Opt_compress_force, Opt_notreelog, Opt_ratio,
-	Opt_flushoncommit,
+	Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum,
+	Opt_nodatacow, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, Opt_ssd,
+	Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress,
+	Opt_compress_force, Opt_notreelog, Opt_ratio, Opt_flushoncommit,
 	Opt_discard, Opt_err,
 };
 
 static match_table_t tokens = {
 	{Opt_degraded, "degraded"},
 	{Opt_subvol, "subvol=%s"},
+	{Opt_subvolid, "subvolid=%d"},
 	{Opt_device, "device=%s"},
 	{Opt_nodatasum, "nodatasum"},
 	{Opt_nodatacow, "nodatacow"},
 	{Opt_nobarrier, "nobarrier"},
-	{Opt_max_extent, "max_extent=%s"},
 	{Opt_max_inline, "max_inline=%s"},
 	{Opt_alloc_start, "alloc_start=%s"},
 	{Opt_thread_pool, "thread_pool=%d"},
@@ -95,31 +95,6 @@ static match_table_t tokens = {
 	{Opt_err, NULL},
 };
 
-u64 btrfs_parse_size(char *str)
-{
-	u64 res;
-	int mult = 1;
-	char *end;
-	char last;
-
-	res = simple_strtoul(str, &end, 10);
-
-	last = end[0];
-	if (isalpha(last)) {
-		last = tolower(last);
-		switch (last) {
-		case 'g':
-			mult *= 1024;
-		case 'm':
-			mult *= 1024;
-		case 'k':
-			mult *= 1024;
-		}
-		res = res * mult;
-	}
-	return res;
-}
-
 /*
  * Regular mount options parser.  Everything that is needed only when
  * reading in a new superblock is parsed here.
@@ -128,7 +103,7 @@ int btrfs_parse_options(struct btrfs_roo
 {
 	struct btrfs_fs_info *info = root->fs_info;
 	substring_t args[MAX_OPT_ARGS];
-	char *p, *num;
+	char *p, *num, *orig;
 	int intarg;
 	int ret = 0;
 
@@ -143,6 +118,7 @@ int btrfs_parse_options(struct btrfs_roo
 	if (!options)
 		return -ENOMEM;
 
+	orig = options;
 
 	while ((p = strsep(&options, ",")) != NULL) {
 		int token;
@@ -156,6 +132,7 @@ int btrfs_parse_options(struct btrfs_roo
 			btrfs_set_opt(info->mount_opt, DEGRADED);
 			break;
 		case Opt_subvol:
+		case Opt_subvolid:
 		case Opt_device:
 			/*
 			 * These are parsed by btrfs_parse_early_options
@@ -210,22 +187,10 @@ int btrfs_parse_options(struct btrfs_roo
 				       info->thread_pool_size);
 			}
 			break;
-		case Opt_max_extent:
-			num = match_strdup(&args[0]);
-			if (num) {
-				info->max_extent = btrfs_parse_size(num);
-				kfree(num);
-
-				info->max_extent = max_t(u64,
-					info->max_extent, root->sectorsize);
-				printk(KERN_INFO "btrfs: max_extent at %llu\n",
-				       (unsigned long long)info->max_extent);
-			}
-			break;
 		case Opt_max_inline:
 			num = match_strdup(&args[0]);
 			if (num) {
-				info->max_inline = btrfs_parse_size(num);
+				info->max_inline = memparse(num, NULL);
 				kfree(num);
 
 				if (info->max_inline) {
@@ -240,7 +205,7 @@ int btrfs_parse_options(struct btrfs_roo
 		case Opt_alloc_start:
 			num = match_strdup(&args[0]);
 			if (num) {
-				info->alloc_start = btrfs_parse_size(num);
+				info->alloc_start = memparse(num, NULL);
 				kfree(num);
 				printk(KERN_INFO
 					"btrfs: allocations start at %llu\n",
@@ -280,7 +245,7 @@ int btrfs_parse_options(struct btrfs_roo
 		}
 	}
 out:
-	kfree(options);
+	kfree(orig);
 	return ret;
 }
 
@@ -291,12 +256,13 @@ out:
  * only when we need to allocate a new super block.
  */
 static int btrfs_parse_early_options(const char *options, fmode_t flags,
-		void *holder, char **subvol_name,
+		void *holder, char **subvol_name, u64 *subvol_objectid,
 		struct btrfs_fs_devices **fs_devices)
 {
 	substring_t args[MAX_OPT_ARGS];
 	char *opts, *p;
 	int error = 0;
+	int intarg;
 
 	if (!options)
 		goto out;
@@ -319,6 +285,18 @@ static int btrfs_parse_early_options(con
 		case Opt_subvol:
 			*subvol_name = match_strdup(&args[0]);
 			break;
+		case Opt_subvolid:
+			intarg = 0;
+			error = match_int(&args[0], &intarg);
+			if (!error) {
+				/* we want the original fs_tree */
+				if (!intarg)
+					*subvol_objectid =
+						BTRFS_FS_TREE_OBJECTID;
+				else
+					*subvol_objectid = intarg;
+			}
+			break;
 		case Opt_device:
 			error = btrfs_scan_one_device(match_strdup(&args[0]),
 					flags, holder, fs_devices);
@@ -346,6 +324,110 @@ static int btrfs_parse_early_options(con
 	return error;
 }
 
+static struct dentry *get_default_root(struct super_block *sb,
+				       u64 subvol_objectid)
+{
+	struct btrfs_root *root = sb->s_fs_info;
+	struct btrfs_root *new_root;
+	struct btrfs_dir_item *di;
+	struct btrfs_path *path;
+	struct btrfs_key location;
+	struct inode *inode;
+	struct dentry *dentry;
+	u64 dir_id;
+	int new = 0;
+
+	/*
+	 * We have a specific subvol we want to mount, just setup location and
+	 * go look up the root.
+	 */
+	if (subvol_objectid) {
+		location.objectid = subvol_objectid;
+		location.type = BTRFS_ROOT_ITEM_KEY;
+		location.offset = (u64)-1;
+		goto find_root;
+	}
+
+	path = btrfs_alloc_path();
+	if (!path)
+		return ERR_PTR(-ENOMEM);
+	path->leave_spinning = 1;
+
+	/*
+	 * Find the "default" dir item which points to the root item that we
+	 * will mount by default if we haven't been given a specific subvolume
+	 * to mount.
+	 */
+	dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
+	di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0);
+	if (!di) {
+		/*
+		 * Ok the default dir item isn't there.  This is weird since
+		 * it's always been there, but don't freak out, just try and
+		 * mount to root most subvolume.
+		 */
+		btrfs_free_path(path);
+		dir_id = BTRFS_FIRST_FREE_OBJECTID;
+		new_root = root->fs_info->fs_root;
+		goto setup_root;
+	}
+
+	btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location);
+	btrfs_free_path(path);
+
+find_root:
+	new_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
+	if (IS_ERR(new_root))
+		return ERR_PTR(PTR_ERR(new_root));
+
+	if (btrfs_root_refs(&new_root->root_item) == 0)
+		return ERR_PTR(-ENOENT);
+
+	dir_id = btrfs_root_dirid(&new_root->root_item);
+setup_root:
+	location.objectid = dir_id;
+	location.type = BTRFS_INODE_ITEM_KEY;
+	location.offset = 0;
+
+	inode = btrfs_iget(sb, &location, new_root, &new);
+	if (!inode)
+		return ERR_PTR(-ENOMEM);
+
+	/*
+	 * If we're just mounting the root most subvol put the inode and return
+	 * a reference to the dentry.  We will have already gotten a reference
+	 * to the inode in btrfs_fill_super so we're good to go.
+	 */
+	if (!new && sb->s_root->d_inode == inode) {
+		iput(inode);
+		return dget(sb->s_root);
+	}
+
+	if (new) {
+		const struct qstr name = { .name = "/", .len = 1 };
+
+		/*
+		 * New inode, we need to make the dentry a sibling of s_root so
+		 * everything gets cleaned up properly on unmount.
+		 */
+		dentry = d_alloc(sb->s_root, &name);
+		if (!dentry) {
+			iput(inode);
+			return ERR_PTR(-ENOMEM);
+		}
+		d_splice_alias(inode, dentry);
+	} else {
+		/*
+		 * We found the inode in cache, just find a dentry for it and
+		 * put the reference to the inode we just got.
+		 */
+		dentry = d_find_alias(inode);
+		iput(inode);
+	}
+
+	return dentry;
+}
+
 static int btrfs_fill_super(struct super_block *sb,
 			    struct btrfs_fs_devices *fs_devices,
 			    void *data, int silent)
@@ -379,7 +461,7 @@ static int btrfs_fill_super(struct super
 	key.objectid = BTRFS_FIRST_FREE_OBJECTID;
 	key.type = BTRFS_INODE_ITEM_KEY;
 	key.offset = 0;
-	inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root);
+	inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root, NULL);
 	if (IS_ERR(inode)) {
 		err = PTR_ERR(inode);
 		goto fail_close;
@@ -391,12 +473,6 @@ static int btrfs_fill_super(struct super
 		err = -ENOMEM;
 		goto fail_close;
 	}
-#if 0
-	/* this does the super kobj at the same time */
-	err = btrfs_sysfs_add_super(tree_root->fs_info);
-	if (err)
-		goto fail_close;
-#endif
 
 	sb->s_root = root_dentry;
 
@@ -440,9 +516,6 @@ static int btrfs_show_options(struct seq
 		seq_puts(seq, ",nodatacow");
 	if (btrfs_test_opt(root, NOBARRIER))
 		seq_puts(seq, ",nobarrier");
-	if (info->max_extent != (u64)-1)
-		seq_printf(seq, ",max_extent=%llu",
-			   (unsigned long long)info->max_extent);
 	if (info->max_inline != 8192 * 1024)
 		seq_printf(seq, ",max_inline=%llu",
 			   (unsigned long long)info->max_inline);
@@ -488,19 +561,22 @@ static int btrfs_test_super(struct super
 static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
 		const char *dev_name, void *data, struct vfsmount *mnt)
 {
-	char *subvol_name = NULL;
 	struct block_device *bdev = NULL;
 	struct super_block *s;
 	struct dentry *root;
 	struct btrfs_fs_devices *fs_devices = NULL;
 	fmode_t mode = FMODE_READ;
+	char *subvol_name = NULL;
+	u64 subvol_objectid = 0;
 	int error = 0;
+	int found = 0;
 
 	if (!(flags & MS_RDONLY))
 		mode |= FMODE_WRITE;
 
 	error = btrfs_parse_early_options(data, mode, fs_type,
-					  &subvol_name, &fs_devices);
+					  &subvol_name, &subvol_objectid,
+					  &fs_devices);
 	if (error)
 		return error;
 
@@ -529,6 +605,7 @@ static int btrfs_get_sb(struct file_syst
 			goto error_close_devices;
 		}
 
+		found = 1;
 		btrfs_close_devices(fs_devices);
 	} else {
 		char b[BDEVNAME_SIZE];
@@ -546,25 +623,35 @@ static int btrfs_get_sb(struct file_syst
 		s->s_flags |= MS_ACTIVE;
 	}
 
-	if (!strcmp(subvol_name, "."))
-		root = dget(s->s_root);
-	else {
-		mutex_lock(&s->s_root->d_inode->i_mutex);
-		root = lookup_one_len(subvol_name, s->s_root,
+	root = get_default_root(s, subvol_objectid);
+	if (IS_ERR(root)) {
+		error = PTR_ERR(root);
+		deactivate_locked_super(s);
+		goto error;
+	}
+	/* if they gave us a subvolume name bind mount into that */
+	if (strcmp(subvol_name, ".")) {
+		struct dentry *new_root;
+		mutex_lock(&root->d_inode->i_mutex);
+		new_root = lookup_one_len(subvol_name, root,
 				      strlen(subvol_name));
-		mutex_unlock(&s->s_root->d_inode->i_mutex);
+		mutex_unlock(&root->d_inode->i_mutex);
 
-		if (IS_ERR(root)) {
+		if (IS_ERR(new_root)) {
 			deactivate_locked_super(s);
-			error = PTR_ERR(root);
-			goto error_free_subvol_name;
+			error = PTR_ERR(new_root);
+			dput(root);
+			goto error_close_devices;
 		}
-		if (!root->d_inode) {
+		if (!new_root->d_inode) {
 			dput(root);
+			dput(new_root);
 			deactivate_locked_super(s);
 			error = -ENXIO;
-			goto error_free_subvol_name;
+			goto error_close_devices;
 		}
+		dput(root);
+		root = new_root;
 	}
 
 	mnt->mnt_sb = s;
@@ -579,6 +666,7 @@ error_close_devices:
 	btrfs_close_devices(fs_devices);
 error_free_subvol_name:
 	kfree(subvol_name);
+error:
 	return error;
 }
 
@@ -623,14 +711,37 @@ static int btrfs_statfs(struct dentry *d
 {
 	struct btrfs_root *root = btrfs_sb(dentry->d_sb);
 	struct btrfs_super_block *disk_super = &root->fs_info->super_copy;
+	struct list_head *head = &root->fs_info->space_info;
+	struct btrfs_space_info *found;
+	u64 total_used = 0;
+	u64 data_used = 0;
 	int bits = dentry->d_sb->s_blocksize_bits;
 	__be32 *fsid = (__be32 *)root->fs_info->fsid;
 
+	rcu_read_lock();
+	list_for_each_entry_rcu(found, head, list) {
+		if (found->flags & (BTRFS_BLOCK_GROUP_DUP|
+				    BTRFS_BLOCK_GROUP_RAID10|
+				    BTRFS_BLOCK_GROUP_RAID1)) {
+			total_used += found->bytes_used;
+			if (found->flags & BTRFS_BLOCK_GROUP_DATA)
+				data_used += found->bytes_used;
+			else
+				data_used += found->total_bytes;
+		}
+
+		total_used += found->bytes_used;
+		if (found->flags & BTRFS_BLOCK_GROUP_DATA)
+			data_used += found->bytes_used;
+		else
+			data_used += found->total_bytes;
+	}
+	rcu_read_unlock();
+
 	buf->f_namelen = BTRFS_NAME_LEN;
 	buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits;
-	buf->f_bfree = buf->f_blocks -
-		(btrfs_super_bytes_used(disk_super) >> bits);
-	buf->f_bavail = buf->f_bfree;
+	buf->f_bfree = buf->f_blocks - (total_used >> bits);
+	buf->f_bavail = buf->f_blocks - (data_used >> bits);
 	buf->f_bsize = dentry->d_sb->s_blocksize;
 	buf->f_type = BTRFS_SUPER_MAGIC;
 
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/sysfs.c linux-libre-2.6.34-gnu1/fs/btrfs/sysfs.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/sysfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/sysfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -164,12 +164,12 @@ static void btrfs_root_release(struct ko
 	complete(&root->kobj_unregister);
 }
 
-static struct sysfs_ops btrfs_super_attr_ops = {
+static const struct sysfs_ops btrfs_super_attr_ops = {
 	.show	= btrfs_super_attr_show,
 	.store	= btrfs_super_attr_store,
 };
 
-static struct sysfs_ops btrfs_root_attr_ops = {
+static const struct sysfs_ops btrfs_root_attr_ops = {
 	.show	= btrfs_root_attr_show,
 	.store	= btrfs_root_attr_store,
 };
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/transaction.c linux-libre-2.6.34-gnu1/fs/btrfs/transaction.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/transaction.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/transaction.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/writeback.h>
 #include <linux/pagemap.h>
@@ -69,7 +70,7 @@ static noinline int join_transaction(str
 		cur_trans->commit_done = 0;
 		cur_trans->start_time = get_seconds();
 
-		cur_trans->delayed_refs.root.rb_node = NULL;
+		cur_trans->delayed_refs.root = RB_ROOT;
 		cur_trans->delayed_refs.num_entries = 0;
 		cur_trans->delayed_refs.num_heads_ready = 0;
 		cur_trans->delayed_refs.num_heads = 0;
@@ -147,18 +148,13 @@ static void wait_current_trans(struct bt
 		while (1) {
 			prepare_to_wait(&root->fs_info->transaction_wait, &wait,
 					TASK_UNINTERRUPTIBLE);
-			if (cur_trans->blocked) {
-				mutex_unlock(&root->fs_info->trans_mutex);
-				schedule();
-				mutex_lock(&root->fs_info->trans_mutex);
-				finish_wait(&root->fs_info->transaction_wait,
-					    &wait);
-			} else {
-				finish_wait(&root->fs_info->transaction_wait,
-					    &wait);
+			if (!cur_trans->blocked)
 				break;
-			}
+			mutex_unlock(&root->fs_info->trans_mutex);
+			schedule();
+			mutex_lock(&root->fs_info->trans_mutex);
 		}
+		finish_wait(&root->fs_info->transaction_wait, &wait);
 		put_transaction(cur_trans);
 	}
 }
@@ -760,10 +756,17 @@ static noinline int create_pending_snaps
 	struct btrfs_root_item *new_root_item;
 	struct btrfs_root *tree_root = fs_info->tree_root;
 	struct btrfs_root *root = pending->root;
+	struct btrfs_root *parent_root;
+	struct inode *parent_inode;
 	struct extent_buffer *tmp;
 	struct extent_buffer *old;
 	int ret;
 	u64 objectid;
+	int namelen;
+	u64 index = 0;
+
+	parent_inode = pending->dentry->d_parent->d_inode;
+	parent_root = BTRFS_I(parent_inode)->root;
 
 	new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
 	if (!new_root_item) {
@@ -774,79 +777,59 @@ static noinline int create_pending_snaps
 	if (ret)
 		goto fail;
 
-	record_root_in_trans(trans, root);
-	btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
-	memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
-
 	key.objectid = objectid;
 	/* record when the snapshot was created in key.offset */
 	key.offset = trans->transid;
 	btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
 
-	old = btrfs_lock_root_node(root);
-	btrfs_cow_block(trans, root, old, NULL, 0, &old);
-	btrfs_set_lock_blocking(old);
-
-	btrfs_copy_root(trans, root, old, &tmp, objectid);
-	btrfs_tree_unlock(old);
-	free_extent_buffer(old);
-
-	btrfs_set_root_node(new_root_item, tmp);
-	ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
-				new_root_item);
-	btrfs_tree_unlock(tmp);
-	free_extent_buffer(tmp);
-	if (ret)
-		goto fail;
-
-	key.offset = (u64)-1;
 	memcpy(&pending->root_key, &key, sizeof(key));
-fail:
-	kfree(new_root_item);
-	return ret;
-}
-
-static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info,
-				   struct btrfs_pending_snapshot *pending)
-{
-	int ret;
-	int namelen;
-	u64 index = 0;
-	struct btrfs_trans_handle *trans;
-	struct inode *parent_inode;
-	struct btrfs_root *parent_root;
-
-	parent_inode = pending->dentry->d_parent->d_inode;
-	parent_root = BTRFS_I(parent_inode)->root;
-	trans = btrfs_join_transaction(parent_root, 1);
+	pending->root_key.offset = (u64)-1;
 
+	record_root_in_trans(trans, parent_root);
 	/*
 	 * insert the directory item
 	 */
 	namelen = strlen(pending->name);
 	ret = btrfs_set_inode_index(parent_inode, &index);
+	BUG_ON(ret);
 	ret = btrfs_insert_dir_item(trans, parent_root,
 			    pending->name, namelen,
 			    parent_inode->i_ino,
 			    &pending->root_key, BTRFS_FT_DIR, index);
-
-	if (ret)
-		goto fail;
+	BUG_ON(ret);
 
 	btrfs_i_size_write(parent_inode, parent_inode->i_size + namelen * 2);
 	ret = btrfs_update_inode(trans, parent_root, parent_inode);
 	BUG_ON(ret);
 
+	record_root_in_trans(trans, root);
+	btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
+	memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
+
+	old = btrfs_lock_root_node(root);
+	btrfs_cow_block(trans, root, old, NULL, 0, &old);
+	btrfs_set_lock_blocking(old);
+
+	btrfs_copy_root(trans, root, old, &tmp, objectid);
+	btrfs_tree_unlock(old);
+	free_extent_buffer(old);
+
+	btrfs_set_root_node(new_root_item, tmp);
+	ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
+				new_root_item);
+	BUG_ON(ret);
+	btrfs_tree_unlock(tmp);
+	free_extent_buffer(tmp);
+
 	ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root,
 				 pending->root_key.objectid,
 				 parent_root->root_key.objectid,
 				 parent_inode->i_ino, index, pending->name,
 				 namelen);
-
 	BUG_ON(ret);
 
 fail:
-	btrfs_end_transaction(trans, fs_info->fs_root);
+	kfree(new_root_item);
 	return ret;
 }
 
@@ -867,25 +850,6 @@ static noinline int create_pending_snaps
 	return 0;
 }
 
-static noinline int finish_pending_snapshots(struct btrfs_trans_handle *trans,
-					     struct btrfs_fs_info *fs_info)
-{
-	struct btrfs_pending_snapshot *pending;
-	struct list_head *head = &trans->transaction->pending_snapshots;
-	int ret;
-
-	while (!list_empty(head)) {
-		pending = list_entry(head->next,
-				     struct btrfs_pending_snapshot, list);
-		ret = finish_pending_snapshot(fs_info, pending);
-		BUG_ON(ret);
-		list_del(&pending->list);
-		kfree(pending->name);
-		kfree(pending);
-	}
-	return 0;
-}
-
 static void update_super_roots(struct btrfs_root *root)
 {
 	struct btrfs_root_item *root_item;
@@ -997,13 +961,10 @@ int btrfs_commit_transaction(struct btrf
 
 		mutex_unlock(&root->fs_info->trans_mutex);
 
-		if (flush_on_commit) {
+		if (flush_on_commit || snap_pending) {
 			btrfs_start_delalloc_inodes(root, 1);
 			ret = btrfs_wait_ordered_extents(root, 0, 1);
 			BUG_ON(ret);
-		} else if (snap_pending) {
-			ret = btrfs_wait_ordered_extents(root, 0, 1);
-			BUG_ON(ret);
 		}
 
 		/*
@@ -1100,9 +1061,6 @@ int btrfs_commit_transaction(struct btrf
 
 	btrfs_finish_extent_commit(trans, root);
 
-	/* do the directory inserts of any pending snapshot creations */
-	finish_pending_snapshots(trans, root->fs_info);
-
 	mutex_lock(&root->fs_info->trans_mutex);
 
 	cur_trans->commit_done = 1;
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/tree-log.c linux-libre-2.6.34-gnu1/fs/btrfs/tree-log.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/tree-log.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/tree-log.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "ctree.h"
 #include "transaction.h"
 #include "disk-io.h"
@@ -445,7 +446,7 @@ static noinline struct inode *read_one_i
 	key.objectid = objectid;
 	key.type = BTRFS_INODE_ITEM_KEY;
 	key.offset = 0;
-	inode = btrfs_iget(root->fs_info->sb, &key, root);
+	inode = btrfs_iget(root->fs_info->sb, &key, root, NULL);
 	if (IS_ERR(inode)) {
 		inode = NULL;
 	} else if (is_bad_inode(inode)) {
diff -druNp linux-libre-2.6.33-gnu1/fs/btrfs/volumes.c linux-libre-2.6.34-gnu1/fs/btrfs/volumes.c
--- linux-libre-2.6.33-gnu1/fs/btrfs/volumes.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/btrfs/volumes.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
  */
 #include <linux/sched.h>
 #include <linux/bio.h>
+#include <linux/slab.h>
 #include <linux/buffer_head.h>
 #include <linux/blkdev.h>
 #include <linux/random.h>
@@ -256,13 +257,13 @@ loop_lock:
 			wake_up(&fs_info->async_submit_wait);
 
 		BUG_ON(atomic_read(&cur->bi_cnt) == 0);
-		submit_bio(cur->bi_rw, cur);
-		num_run++;
-		batch_run++;
 
 		if (bio_rw_flagged(cur, BIO_RW_SYNCIO))
 			num_sync_run++;
 
+		submit_bio(cur->bi_rw, cur);
+		num_run++;
+		batch_run++;
 		if (need_resched()) {
 			if (num_sync_run) {
 				blk_run_backing_dev(bdi, NULL);
@@ -325,16 +326,6 @@ loop_lock:
 		num_sync_run = 0;
 		blk_run_backing_dev(bdi, NULL);
 	}
-
-	cond_resched();
-	if (again)
-		goto loop;
-
-	spin_lock(&device->io_lock);
-	if (device->pending_bios.head || device->pending_sync_bios.head)
-		goto loop_lock;
-	spin_unlock(&device->io_lock);
-
 	/*
 	 * IO has already been through a long path to get here.  Checksumming,
 	 * async helper threads, perhaps compression.  We've done a pretty
@@ -346,6 +337,16 @@ loop_lock:
 	 * cared about found its way down here.
 	 */
 	blk_run_backing_dev(bdi, NULL);
+
+	cond_resched();
+	if (again)
+		goto loop;
+
+	spin_lock(&device->io_lock);
+	if (device->pending_bios.head || device->pending_sync_bios.head)
+		goto loop_lock;
+	spin_unlock(&device->io_lock);
+
 done:
 	return 0;
 }
@@ -365,6 +366,7 @@ static noinline int device_list_add(cons
 	struct btrfs_device *device;
 	struct btrfs_fs_devices *fs_devices;
 	u64 found_transid = btrfs_super_generation(disk_super);
+	char *name;
 
 	fs_devices = find_fsid(disk_super->fsid);
 	if (!fs_devices) {
@@ -411,6 +413,12 @@ static noinline int device_list_add(cons
 
 		device->fs_devices = fs_devices;
 		fs_devices->num_devices++;
+	} else if (strcmp(device->name, path)) {
+		name = kstrdup(path, GFP_NOFS);
+		if (!name)
+			return -ENOMEM;
+		kfree(device->name);
+		device->name = name;
 	}
 
 	if (found_transid > fs_devices->latest_trans) {
@@ -592,7 +600,7 @@ static int __btrfs_open_devices(struct b
 			goto error_close;
 
 		disk_super = (struct btrfs_super_block *)bh->b_data;
-		devid = le64_to_cpu(disk_super->dev_item.devid);
+		devid = btrfs_stack_device_id(&disk_super->dev_item);
 		if (devid != device->devid)
 			goto error_brelse;
 
@@ -694,7 +702,7 @@ int btrfs_scan_one_device(const char *pa
 		goto error_close;
 	}
 	disk_super = (struct btrfs_super_block *)bh->b_data;
-	devid = le64_to_cpu(disk_super->dev_item.devid);
+	devid = btrfs_stack_device_id(&disk_super->dev_item);
 	transid = btrfs_super_generation(disk_super);
 	if (disk_super->label[0])
 		printk(KERN_INFO "device label %s ", disk_super->label);
@@ -1187,7 +1195,7 @@ int btrfs_rm_device(struct btrfs_root *r
 			goto error_close;
 		}
 		disk_super = (struct btrfs_super_block *)bh->b_data;
-		devid = le64_to_cpu(disk_super->dev_item.devid);
+		devid = btrfs_stack_device_id(&disk_super->dev_item);
 		dev_uuid = disk_super->dev_item.uuid;
 		device = btrfs_find_device(root, devid, dev_uuid,
 					   disk_super->fsid);
@@ -2191,9 +2199,9 @@ static int __btrfs_alloc_chunk(struct bt
 		min_stripes = 2;
 	}
 	if (type & (BTRFS_BLOCK_GROUP_RAID1)) {
-		num_stripes = min_t(u64, 2, fs_devices->rw_devices);
-		if (num_stripes < 2)
+		if (fs_devices->rw_devices < 2)
 			return -ENOSPC;
+		num_stripes = 2;
 		min_stripes = 2;
 	}
 	if (type & (BTRFS_BLOCK_GROUP_RAID10)) {
@@ -2237,8 +2245,16 @@ again:
 		do_div(calc_size, stripe_len);
 		calc_size *= stripe_len;
 	}
+
 	/* we don't want tiny stripes */
-	calc_size = max_t(u64, min_stripe_size, calc_size);
+	if (!looped)
+		calc_size = max_t(u64, min_stripe_size, calc_size);
+
+	/*
+	 * we're about to do_div by the stripe_len so lets make sure
+	 * we end up with something bigger than a stripe
+	 */
+	calc_size = max_t(u64, calc_size, stripe_len * 4);
 
 	do_div(calc_size, stripe_len);
 	calc_size *= stripe_len;
@@ -3382,6 +3398,8 @@ int btrfs_read_chunk_tree(struct btrfs_r
 	key.type = 0;
 again:
 	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+	if (ret < 0)
+		goto error;
 	while (1) {
 		leaf = path->nodes[0];
 		slot = path->slots[0];
diff -druNp linux-libre-2.6.33-gnu1/fs/buffer.c linux-libre-2.6.34-gnu1/fs/buffer.c
--- linux-libre-2.6.33-gnu1/fs/buffer.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/buffer.c	2010-05-16 17:17:36.000000000 -0400
@@ -2893,7 +2893,7 @@ int block_write_full_page_endio(struct p
 
 	/*
 	 * The page straddles i_size.  It must be zeroed out on each and every
-	 * writepage invokation because it may be mmapped.  "A file is mapped
+	 * writepage invocation because it may be mmapped.  "A file is mapped
 	 * in multiples of the page size.  For a file that is not a multiple of
 	 * the  page size, the remaining memory is zeroed when mapped, and
 	 * writes to that region are not written out to the file."
@@ -3265,7 +3265,7 @@ static void recalc_bh_state(void)
 	
 struct buffer_head *alloc_buffer_head(gfp_t gfp_flags)
 {
-	struct buffer_head *ret = kmem_cache_alloc(bh_cachep, gfp_flags);
+	struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags);
 	if (ret) {
 		INIT_LIST_HEAD(&ret->b_assoc_buffers);
 		get_cpu_var(bh_accounting).nr++;
@@ -3352,15 +3352,6 @@ int bh_submit_read(struct buffer_head *b
 }
 EXPORT_SYMBOL(bh_submit_read);
 
-static void
-init_buffer_head(void *data)
-{
-	struct buffer_head *bh = data;
-
-	memset(bh, 0, sizeof(*bh));
-	INIT_LIST_HEAD(&bh->b_assoc_buffers);
-}
-
 void __init buffer_init(void)
 {
 	int nrpages;
@@ -3369,7 +3360,7 @@ void __init buffer_init(void)
 			sizeof(struct buffer_head), 0,
 				(SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|
 				SLAB_MEM_SPREAD),
-				init_buffer_head);
+				NULL);
 
 	/*
 	 * Limit the bh occupancy to 10% of ZONE_NORMAL
diff -druNp linux-libre-2.6.33-gnu1/fs/cachefiles/interface.c linux-libre-2.6.34-gnu1/fs/cachefiles/interface.c
--- linux-libre-2.6.33-gnu1/fs/cachefiles/interface.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cachefiles/interface.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
  * 2 of the Licence, or (at your option) any later version.
  */
 
+#include <linux/slab.h>
 #include <linux/mount.h>
 #include <linux/buffer_head.h>
 #include "internal.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/cachefiles/internal.h linux-libre-2.6.34-gnu1/fs/cachefiles/internal.h
--- linux-libre-2.6.33-gnu1/fs/cachefiles/internal.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cachefiles/internal.h	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@ struct cachefiles_object {
 	loff_t				i_size;		/* object size */
 	unsigned long			flags;
 #define CACHEFILES_OBJECT_ACTIVE	0		/* T if marked active */
+#define CACHEFILES_OBJECT_BURIED	1		/* T if preemptively buried */
 	atomic_t			usage;		/* object usage count */
 	uint8_t				type;		/* object type */
 	uint8_t				new;		/* T if object new */
diff -druNp linux-libre-2.6.33-gnu1/fs/cachefiles/namei.c linux-libre-2.6.34-gnu1/fs/cachefiles/namei.c
--- linux-libre-2.6.33-gnu1/fs/cachefiles/namei.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cachefiles/namei.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/security.h>
+#include <linux/slab.h>
 #include "internal.h"
 
 #define CACHEFILES_KEYBUF_SIZE 512
@@ -92,6 +93,59 @@ static noinline void cachefiles_printk_o
 }
 
 /*
+ * mark the owner of a dentry, if there is one, to indicate that that dentry
+ * has been preemptively deleted
+ * - the caller must hold the i_mutex on the dentry's parent as required to
+ *   call vfs_unlink(), vfs_rmdir() or vfs_rename()
+ */
+static void cachefiles_mark_object_buried(struct cachefiles_cache *cache,
+					  struct dentry *dentry)
+{
+	struct cachefiles_object *object;
+	struct rb_node *p;
+
+	_enter(",'%*.*s'",
+	       dentry->d_name.len, dentry->d_name.len, dentry->d_name.name);
+
+	write_lock(&cache->active_lock);
+
+	p = cache->active_nodes.rb_node;
+	while (p) {
+		object = rb_entry(p, struct cachefiles_object, active_node);
+		if (object->dentry > dentry)
+			p = p->rb_left;
+		else if (object->dentry < dentry)
+			p = p->rb_right;
+		else
+			goto found_dentry;
+	}
+
+	write_unlock(&cache->active_lock);
+	_leave(" [no owner]");
+	return;
+
+	/* found the dentry for  */
+found_dentry:
+	kdebug("preemptive burial: OBJ%x [%s] %p",
+	       object->fscache.debug_id,
+	       fscache_object_states[object->fscache.state],
+	       dentry);
+
+	if (object->fscache.state < FSCACHE_OBJECT_DYING) {
+		printk(KERN_ERR "\n");
+		printk(KERN_ERR "CacheFiles: Error:"
+		       " Can't preemptively bury live object\n");
+		cachefiles_printk_object(object, NULL);
+	} else if (test_and_set_bit(CACHEFILES_OBJECT_BURIED, &object->flags)) {
+		printk(KERN_ERR "CacheFiles: Error:"
+		       " Object already preemptively buried\n");
+	}
+
+	write_unlock(&cache->active_lock);
+	_leave(" [owner marked]");
+}
+
+/*
  * record the fact that an object is now active
  */
 static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
@@ -218,7 +272,8 @@ requeue:
  */
 static int cachefiles_bury_object(struct cachefiles_cache *cache,
 				  struct dentry *dir,
-				  struct dentry *rep)
+				  struct dentry *rep,
+				  bool preemptive)
 {
 	struct dentry *grave, *trap;
 	char nbuffer[8 + 8 + 1];
@@ -228,11 +283,16 @@ static int cachefiles_bury_object(struct
 	       dir->d_name.len, dir->d_name.len, dir->d_name.name,
 	       rep->d_name.len, rep->d_name.len, rep->d_name.name);
 
+	_debug("remove %p from %p", rep, dir);
+
 	/* non-directories can just be unlinked */
 	if (!S_ISDIR(rep->d_inode->i_mode)) {
 		_debug("unlink stale object");
 		ret = vfs_unlink(dir->d_inode, rep);
 
+		if (preemptive)
+			cachefiles_mark_object_buried(cache, rep);
+
 		mutex_unlock(&dir->d_inode->i_mutex);
 
 		if (ret == -EIO)
@@ -324,6 +384,9 @@ try_again:
 	if (ret != 0 && ret != -ENOMEM)
 		cachefiles_io_error(cache, "Rename failed with error %d", ret);
 
+	if (preemptive)
+		cachefiles_mark_object_buried(cache, rep);
+
 	unlock_rename(cache->graveyard, dir);
 	dput(grave);
 	_leave(" = 0");
@@ -339,7 +402,7 @@ int cachefiles_delete_object(struct cach
 	struct dentry *dir;
 	int ret;
 
-	_enter(",{%p}", object->dentry);
+	_enter(",OBJ%x{%p}", object->fscache.debug_id, object->dentry);
 
 	ASSERT(object->dentry);
 	ASSERT(object->dentry->d_inode);
@@ -349,15 +412,25 @@ int cachefiles_delete_object(struct cach
 
 	mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
 
-	/* we need to check that our parent is _still_ our parent - it may have
-	 * been renamed */
-	if (dir == object->dentry->d_parent) {
-		ret = cachefiles_bury_object(cache, dir, object->dentry);
-	} else {
-		/* it got moved, presumably by cachefilesd culling it, so it's
-		 * no longer in the key path and we can ignore it */
+	if (test_bit(CACHEFILES_OBJECT_BURIED, &object->flags)) {
+		/* object allocation for the same key preemptively deleted this
+		 * object's file so that it could create its own file */
+		_debug("object preemptively buried");
 		mutex_unlock(&dir->d_inode->i_mutex);
 		ret = 0;
+	} else {
+		/* we need to check that our parent is _still_ our parent - it
+		 * may have been renamed */
+		if (dir == object->dentry->d_parent) {
+			ret = cachefiles_bury_object(cache, dir,
+						     object->dentry, false);
+		} else {
+			/* it got moved, presumably by cachefilesd culling it,
+			 * so it's no longer in the key path and we can ignore
+			 * it */
+			mutex_unlock(&dir->d_inode->i_mutex);
+			ret = 0;
+		}
 	}
 
 	dput(dir);
@@ -380,7 +453,9 @@ int cachefiles_walk_to_object(struct cac
 	const char *name;
 	int ret, nlen;
 
-	_enter("{%p},,%s,", parent->dentry, key);
+	_enter("OBJ%x{%p},OBJ%x,%s,",
+	       parent->fscache.debug_id, parent->dentry,
+	       object->fscache.debug_id, key);
 
 	cache = container_of(parent->fscache.cache,
 			     struct cachefiles_cache, cache);
@@ -508,7 +583,7 @@ lookup_again:
 			 * mutex) */
 			object->dentry = NULL;
 
-			ret = cachefiles_bury_object(cache, dir, next);
+			ret = cachefiles_bury_object(cache, dir, next, true);
 			dput(next);
 			next = NULL;
 
@@ -827,7 +902,7 @@ int cachefiles_cull(struct cachefiles_ca
 	/*  actually remove the victim (drops the dir mutex) */
 	_debug("bury");
 
-	ret = cachefiles_bury_object(cache, dir, victim);
+	ret = cachefiles_bury_object(cache, dir, victim, false);
 	if (ret < 0)
 		goto error;
 
diff -druNp linux-libre-2.6.33-gnu1/fs/cachefiles/rdwr.c linux-libre-2.6.34-gnu1/fs/cachefiles/rdwr.c
--- linux-libre-2.6.33-gnu1/fs/cachefiles/rdwr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cachefiles/rdwr.c	2010-05-16 17:17:36.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/mount.h>
+#include <linux/slab.h>
 #include <linux/file.h>
 #include "internal.h"
 
diff -druNp linux-libre-2.6.33-gnu1/fs/cachefiles/security.c linux-libre-2.6.34-gnu1/fs/cachefiles/security.c
--- linux-libre-2.6.33-gnu1/fs/cachefiles/security.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cachefiles/security.c	2010-05-16 17:17:36.000000000 -0400
@@ -77,6 +77,8 @@ static int cachefiles_check_cache_dir(st
 /*
  * check the security details of the on-disk cache
  * - must be called with security override in force
+ * - must return with a security override in force - even in the case of an
+ *   error
  */
 int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
 					struct dentry *root,
@@ -99,6 +101,8 @@ int cachefiles_determine_cache_security(
 	 * which create files */
 	ret = set_create_files_as(new, root->d_inode);
 	if (ret < 0) {
+		abort_creds(new);
+		cachefiles_begin_secure(cache, _saved_cred);
 		_leave(" = %d [cfa]", ret);
 		return ret;
 	}
diff -druNp linux-libre-2.6.33-gnu1/fs/cachefiles/xattr.c linux-libre-2.6.34-gnu1/fs/cachefiles/xattr.c
--- linux-libre-2.6.33-gnu1/fs/cachefiles/xattr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cachefiles/xattr.c	2010-05-16 17:17:36.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/fsnotify.h>
 #include <linux/quotaops.h>
 #include <linux/xattr.h>
+#include <linux/slab.h>
 #include "internal.h"
 
 static const char cachefiles_xattr_cache[] =
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/addr.c linux-libre-2.6.34-gnu1/fs/ceph/addr.c
--- linux-libre-2.6.33-gnu1/fs/ceph/addr.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/addr.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1187 @@
+#include "ceph_debug.h"
+
+#include <linux/backing-dev.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/writeback.h>	/* generic_writepages */
+#include <linux/slab.h>
+#include <linux/pagevec.h>
+#include <linux/task_io_accounting_ops.h>
+
+#include "super.h"
+#include "osd_client.h"
+
+/*
+ * Ceph address space ops.
+ *
+ * There are a few funny things going on here.
+ *
+ * The page->private field is used to reference a struct
+ * ceph_snap_context for _every_ dirty page.  This indicates which
+ * snapshot the page was logically dirtied in, and thus which snap
+ * context needs to be associated with the osd write during writeback.
+ *
+ * Similarly, struct ceph_inode_info maintains a set of counters to
+ * count dirty pages on the inode.  In the absense of snapshots,
+ * i_wrbuffer_ref == i_wrbuffer_ref_head == the dirty page count.
+ *
+ * When a snapshot is taken (that is, when the client receives
+ * notification that a snapshot was taken), each inode with caps and
+ * with dirty pages (dirty pages implies there is a cap) gets a new
+ * ceph_cap_snap in the i_cap_snaps list (which is sorted in ascending
+ * order, new snaps go to the tail).  The i_wrbuffer_ref_head count is
+ * moved to capsnap->dirty. (Unless a sync write is currently in
+ * progress.  In that case, the capsnap is said to be "pending", new
+ * writes cannot start, and the capsnap isn't "finalized" until the
+ * write completes (or fails) and a final size/mtime for the inode for
+ * that snap can be settled upon.)  i_wrbuffer_ref_head is reset to 0.
+ *
+ * On writeback, we must submit writes to the osd IN SNAP ORDER.  So,
+ * we look for the first capsnap in i_cap_snaps and write out pages in
+ * that snap context _only_.  Then we move on to the next capsnap,
+ * eventually reaching the "live" or "head" context (i.e., pages that
+ * are not yet snapped) and are writing the most recently dirtied
+ * pages.
+ *
+ * Invalidate and so forth must take care to ensure the dirty page
+ * accounting is preserved.
+ */
+
+#define CONGESTION_ON_THRESH(congestion_kb) (congestion_kb >> (PAGE_SHIFT-10))
+#define CONGESTION_OFF_THRESH(congestion_kb)				\
+	(CONGESTION_ON_THRESH(congestion_kb) -				\
+	 (CONGESTION_ON_THRESH(congestion_kb) >> 2))
+
+
+
+/*
+ * Dirty a page.  Optimistically adjust accounting, on the assumption
+ * that we won't race with invalidate.  If we do, readjust.
+ */
+static int ceph_set_page_dirty(struct page *page)
+{
+	struct address_space *mapping = page->mapping;
+	struct inode *inode;
+	struct ceph_inode_info *ci;
+	int undo = 0;
+	struct ceph_snap_context *snapc;
+
+	if (unlikely(!mapping))
+		return !TestSetPageDirty(page);
+
+	if (TestSetPageDirty(page)) {
+		dout("%p set_page_dirty %p idx %lu -- already dirty\n",
+		     mapping->host, page, page->index);
+		return 0;
+	}
+
+	inode = mapping->host;
+	ci = ceph_inode(inode);
+
+	/*
+	 * Note that we're grabbing a snapc ref here without holding
+	 * any locks!
+	 */
+	snapc = ceph_get_snap_context(ci->i_snap_realm->cached_context);
+
+	/* dirty the head */
+	spin_lock(&inode->i_lock);
+	if (ci->i_wrbuffer_ref_head == 0)
+		ci->i_head_snapc = ceph_get_snap_context(snapc);
+	++ci->i_wrbuffer_ref_head;
+	if (ci->i_wrbuffer_ref == 0)
+		igrab(inode);
+	++ci->i_wrbuffer_ref;
+	dout("%p set_page_dirty %p idx %lu head %d/%d -> %d/%d "
+	     "snapc %p seq %lld (%d snaps)\n",
+	     mapping->host, page, page->index,
+	     ci->i_wrbuffer_ref-1, ci->i_wrbuffer_ref_head-1,
+	     ci->i_wrbuffer_ref, ci->i_wrbuffer_ref_head,
+	     snapc, snapc->seq, snapc->num_snaps);
+	spin_unlock(&inode->i_lock);
+
+	/* now adjust page */
+	spin_lock_irq(&mapping->tree_lock);
+	if (page->mapping) {	/* Race with truncate? */
+		WARN_ON_ONCE(!PageUptodate(page));
+
+		if (mapping_cap_account_dirty(mapping)) {
+			__inc_zone_page_state(page, NR_FILE_DIRTY);
+			__inc_bdi_stat(mapping->backing_dev_info,
+					BDI_RECLAIMABLE);
+			task_io_account_write(PAGE_CACHE_SIZE);
+		}
+		radix_tree_tag_set(&mapping->page_tree,
+				page_index(page), PAGECACHE_TAG_DIRTY);
+
+		/*
+		 * Reference snap context in page->private.  Also set
+		 * PagePrivate so that we get invalidatepage callback.
+		 */
+		page->private = (unsigned long)snapc;
+		SetPagePrivate(page);
+	} else {
+		dout("ANON set_page_dirty %p (raced truncate?)\n", page);
+		undo = 1;
+	}
+
+	spin_unlock_irq(&mapping->tree_lock);
+
+	if (undo)
+		/* whoops, we failed to dirty the page */
+		ceph_put_wrbuffer_cap_refs(ci, 1, snapc);
+
+	__mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
+
+	BUG_ON(!PageDirty(page));
+	return 1;
+}
+
+/*
+ * If we are truncating the full page (i.e. offset == 0), adjust the
+ * dirty page counters appropriately.  Only called if there is private
+ * data on the page.
+ */
+static void ceph_invalidatepage(struct page *page, unsigned long offset)
+{
+	struct inode *inode;
+	struct ceph_inode_info *ci;
+	struct ceph_snap_context *snapc = (void *)page->private;
+
+	BUG_ON(!PageLocked(page));
+	BUG_ON(!page->private);
+	BUG_ON(!PagePrivate(page));
+	BUG_ON(!page->mapping);
+
+	inode = page->mapping->host;
+
+	/*
+	 * We can get non-dirty pages here due to races between
+	 * set_page_dirty and truncate_complete_page; just spit out a
+	 * warning, in case we end up with accounting problems later.
+	 */
+	if (!PageDirty(page))
+		pr_err("%p invalidatepage %p page not dirty\n", inode, page);
+
+	if (offset == 0)
+		ClearPageChecked(page);
+
+	ci = ceph_inode(inode);
+	if (offset == 0) {
+		dout("%p invalidatepage %p idx %lu full dirty page %lu\n",
+		     inode, page, page->index, offset);
+		ceph_put_wrbuffer_cap_refs(ci, 1, snapc);
+		ceph_put_snap_context(snapc);
+		page->private = 0;
+		ClearPagePrivate(page);
+	} else {
+		dout("%p invalidatepage %p idx %lu partial dirty page\n",
+		     inode, page, page->index);
+	}
+}
+
+/* just a sanity check */
+static int ceph_releasepage(struct page *page, gfp_t g)
+{
+	struct inode *inode = page->mapping ? page->mapping->host : NULL;
+	dout("%p releasepage %p idx %lu\n", inode, page, page->index);
+	WARN_ON(PageDirty(page));
+	WARN_ON(page->private);
+	WARN_ON(PagePrivate(page));
+	return 0;
+}
+
+/*
+ * read a single page, without unlocking it.
+ */
+static int readpage_nounlock(struct file *filp, struct page *page)
+{
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_osd_client *osdc = &ceph_inode_to_client(inode)->osdc;
+	int err = 0;
+	u64 len = PAGE_CACHE_SIZE;
+
+	dout("readpage inode %p file %p page %p index %lu\n",
+	     inode, filp, page, page->index);
+	err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
+				  page->index << PAGE_CACHE_SHIFT, &len,
+				  ci->i_truncate_seq, ci->i_truncate_size,
+				  &page, 1);
+	if (err == -ENOENT)
+		err = 0;
+	if (err < 0) {
+		SetPageError(page);
+		goto out;
+	} else if (err < PAGE_CACHE_SIZE) {
+		/* zero fill remainder of page */
+		zero_user_segment(page, err, PAGE_CACHE_SIZE);
+	}
+	SetPageUptodate(page);
+
+out:
+	return err < 0 ? err : 0;
+}
+
+static int ceph_readpage(struct file *filp, struct page *page)
+{
+	int r = readpage_nounlock(filp, page);
+	unlock_page(page);
+	return r;
+}
+
+/*
+ * Build a vector of contiguous pages from the provided page list.
+ */
+static struct page **page_vector_from_list(struct list_head *page_list,
+					   unsigned *nr_pages)
+{
+	struct page **pages;
+	struct page *page;
+	int next_index, contig_pages = 0;
+
+	/* build page vector */
+	pages = kmalloc(sizeof(*pages) * *nr_pages, GFP_NOFS);
+	if (!pages)
+		return ERR_PTR(-ENOMEM);
+
+	BUG_ON(list_empty(page_list));
+	next_index = list_entry(page_list->prev, struct page, lru)->index;
+	list_for_each_entry_reverse(page, page_list, lru) {
+		if (page->index == next_index) {
+			dout("readpages page %d %p\n", contig_pages, page);
+			pages[contig_pages] = page;
+			contig_pages++;
+			next_index++;
+		} else {
+			break;
+		}
+	}
+	*nr_pages = contig_pages;
+	return pages;
+}
+
+/*
+ * Read multiple pages.  Leave pages we don't read + unlock in page_list;
+ * the caller (VM) cleans them up.
+ */
+static int ceph_readpages(struct file *file, struct address_space *mapping,
+			  struct list_head *page_list, unsigned nr_pages)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_osd_client *osdc = &ceph_inode_to_client(inode)->osdc;
+	int rc = 0;
+	struct page **pages;
+	struct pagevec pvec;
+	loff_t offset;
+	u64 len;
+
+	dout("readpages %p file %p nr_pages %d\n",
+	     inode, file, nr_pages);
+
+	pages = page_vector_from_list(page_list, &nr_pages);
+	if (IS_ERR(pages))
+		return PTR_ERR(pages);
+
+	/* guess read extent */
+	offset = pages[0]->index << PAGE_CACHE_SHIFT;
+	len = nr_pages << PAGE_CACHE_SHIFT;
+	rc = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
+				 offset, &len,
+				 ci->i_truncate_seq, ci->i_truncate_size,
+				 pages, nr_pages);
+	if (rc == -ENOENT)
+		rc = 0;
+	if (rc < 0)
+		goto out;
+
+	/* set uptodate and add to lru in pagevec-sized chunks */
+	pagevec_init(&pvec, 0);
+	for (; !list_empty(page_list) && len > 0;
+	     rc -= PAGE_CACHE_SIZE, len -= PAGE_CACHE_SIZE) {
+		struct page *page =
+			list_entry(page_list->prev, struct page, lru);
+
+		list_del(&page->lru);
+
+		if (rc < (int)PAGE_CACHE_SIZE) {
+			/* zero (remainder of) page */
+			int s = rc < 0 ? 0 : rc;
+			zero_user_segment(page, s, PAGE_CACHE_SIZE);
+		}
+
+		if (add_to_page_cache(page, mapping, page->index, GFP_NOFS)) {
+			page_cache_release(page);
+			dout("readpages %p add_to_page_cache failed %p\n",
+			     inode, page);
+			continue;
+		}
+		dout("readpages %p adding %p idx %lu\n", inode, page,
+		     page->index);
+		flush_dcache_page(page);
+		SetPageUptodate(page);
+		unlock_page(page);
+		if (pagevec_add(&pvec, page) == 0)
+			pagevec_lru_add_file(&pvec);   /* add to lru */
+	}
+	pagevec_lru_add_file(&pvec);
+	rc = 0;
+
+out:
+	kfree(pages);
+	return rc;
+}
+
+/*
+ * Get ref for the oldest snapc for an inode with dirty data... that is, the
+ * only snap context we are allowed to write back.
+ */
+static struct ceph_snap_context *get_oldest_context(struct inode *inode,
+						    u64 *snap_size)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_snap_context *snapc = NULL;
+	struct ceph_cap_snap *capsnap = NULL;
+
+	spin_lock(&inode->i_lock);
+	list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
+		dout(" cap_snap %p snapc %p has %d dirty pages\n", capsnap,
+		     capsnap->context, capsnap->dirty_pages);
+		if (capsnap->dirty_pages) {
+			snapc = ceph_get_snap_context(capsnap->context);
+			if (snap_size)
+				*snap_size = capsnap->size;
+			break;
+		}
+	}
+	if (!snapc && ci->i_head_snapc) {
+		snapc = ceph_get_snap_context(ci->i_head_snapc);
+		dout(" head snapc %p has %d dirty pages\n",
+		     snapc, ci->i_wrbuffer_ref_head);
+	}
+	spin_unlock(&inode->i_lock);
+	return snapc;
+}
+
+/*
+ * Write a single page, but leave the page locked.
+ *
+ * If we get a write error, set the page error bit, but still adjust the
+ * dirty page accounting (i.e., page is no longer dirty).
+ */
+static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
+{
+	struct inode *inode;
+	struct ceph_inode_info *ci;
+	struct ceph_client *client;
+	struct ceph_osd_client *osdc;
+	loff_t page_off = page->index << PAGE_CACHE_SHIFT;
+	int len = PAGE_CACHE_SIZE;
+	loff_t i_size;
+	int err = 0;
+	struct ceph_snap_context *snapc, *oldest;
+	u64 snap_size = 0;
+	long writeback_stat;
+
+	dout("writepage %p idx %lu\n", page, page->index);
+
+	if (!page->mapping || !page->mapping->host) {
+		dout("writepage %p - no mapping\n", page);
+		return -EFAULT;
+	}
+	inode = page->mapping->host;
+	ci = ceph_inode(inode);
+	client = ceph_inode_to_client(inode);
+	osdc = &client->osdc;
+
+	/* verify this is a writeable snap context */
+	snapc = (void *)page->private;
+	if (snapc == NULL) {
+		dout("writepage %p page %p not dirty?\n", inode, page);
+		goto out;
+	}
+	oldest = get_oldest_context(inode, &snap_size);
+	if (snapc->seq > oldest->seq) {
+		dout("writepage %p page %p snapc %p not writeable - noop\n",
+		     inode, page, (void *)page->private);
+		/* we should only noop if called by kswapd */
+		WARN_ON((current->flags & PF_MEMALLOC) == 0);
+		ceph_put_snap_context(oldest);
+		goto out;
+	}
+	ceph_put_snap_context(oldest);
+
+	/* is this a partial page at end of file? */
+	if (snap_size)
+		i_size = snap_size;
+	else
+		i_size = i_size_read(inode);
+	if (i_size < page_off + len)
+		len = i_size - page_off;
+
+	dout("writepage %p page %p index %lu on %llu~%u\n",
+	     inode, page, page->index, page_off, len);
+
+	writeback_stat = atomic_long_inc_return(&client->writeback_count);
+	if (writeback_stat >
+	    CONGESTION_ON_THRESH(client->mount_args->congestion_kb))
+		set_bdi_congested(&client->backing_dev_info, BLK_RW_ASYNC);
+
+	set_page_writeback(page);
+	err = ceph_osdc_writepages(osdc, ceph_vino(inode),
+				   &ci->i_layout, snapc,
+				   page_off, len,
+				   ci->i_truncate_seq, ci->i_truncate_size,
+				   &inode->i_mtime,
+				   &page, 1, 0, 0, true);
+	if (err < 0) {
+		dout("writepage setting page/mapping error %d %p\n", err, page);
+		SetPageError(page);
+		mapping_set_error(&inode->i_data, err);
+		if (wbc)
+			wbc->pages_skipped++;
+	} else {
+		dout("writepage cleaned page %p\n", page);
+		err = 0;  /* vfs expects us to return 0 */
+	}
+	page->private = 0;
+	ClearPagePrivate(page);
+	end_page_writeback(page);
+	ceph_put_wrbuffer_cap_refs(ci, 1, snapc);
+	ceph_put_snap_context(snapc);  /* page's reference */
+out:
+	return err;
+}
+
+static int ceph_writepage(struct page *page, struct writeback_control *wbc)
+{
+	int err;
+	struct inode *inode = page->mapping->host;
+	BUG_ON(!inode);
+	igrab(inode);
+	err = writepage_nounlock(page, wbc);
+	unlock_page(page);
+	iput(inode);
+	return err;
+}
+
+
+/*
+ * lame release_pages helper.  release_pages() isn't exported to
+ * modules.
+ */
+static void ceph_release_pages(struct page **pages, int num)
+{
+	struct pagevec pvec;
+	int i;
+
+	pagevec_init(&pvec, 0);
+	for (i = 0; i < num; i++) {
+		if (pagevec_add(&pvec, pages[i]) == 0)
+			pagevec_release(&pvec);
+	}
+	pagevec_release(&pvec);
+}
+
+
+/*
+ * async writeback completion handler.
+ *
+ * If we get an error, set the mapping error bit, but not the individual
+ * page error bits.
+ */
+static void writepages_finish(struct ceph_osd_request *req,
+			      struct ceph_msg *msg)
+{
+	struct inode *inode = req->r_inode;
+	struct ceph_osd_reply_head *replyhead;
+	struct ceph_osd_op *op;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	unsigned wrote;
+	struct page *page;
+	int i;
+	struct ceph_snap_context *snapc = req->r_snapc;
+	struct address_space *mapping = inode->i_mapping;
+	__s32 rc = -EIO;
+	u64 bytes = 0;
+	struct ceph_client *client = ceph_inode_to_client(inode);
+	long writeback_stat;
+	unsigned issued = ceph_caps_issued(ci);
+
+	/* parse reply */
+	replyhead = msg->front.iov_base;
+	WARN_ON(le32_to_cpu(replyhead->num_ops) == 0);
+	op = (void *)(replyhead + 1);
+	rc = le32_to_cpu(replyhead->result);
+	bytes = le64_to_cpu(op->extent.length);
+
+	if (rc >= 0) {
+		/*
+		 * Assume we wrote the pages we originally sent.  The
+		 * osd might reply with fewer pages if our writeback
+		 * raced with a truncation and was adjusted at the osd,
+		 * so don't believe the reply.
+		 */
+		wrote = req->r_num_pages;
+	} else {
+		wrote = 0;
+		mapping_set_error(mapping, rc);
+	}
+	dout("writepages_finish %p rc %d bytes %llu wrote %d (pages)\n",
+	     inode, rc, bytes, wrote);
+
+	/* clean all pages */
+	for (i = 0; i < req->r_num_pages; i++) {
+		page = req->r_pages[i];
+		BUG_ON(!page);
+		WARN_ON(!PageUptodate(page));
+
+		writeback_stat =
+			atomic_long_dec_return(&client->writeback_count);
+		if (writeback_stat <
+		    CONGESTION_OFF_THRESH(client->mount_args->congestion_kb))
+			clear_bdi_congested(&client->backing_dev_info,
+					    BLK_RW_ASYNC);
+
+		ceph_put_snap_context((void *)page->private);
+		page->private = 0;
+		ClearPagePrivate(page);
+		dout("unlocking %d %p\n", i, page);
+		end_page_writeback(page);
+
+		/*
+		 * We lost the cache cap, need to truncate the page before
+		 * it is unlocked, otherwise we'd truncate it later in the
+		 * page truncation thread, possibly losing some data that
+		 * raced its way in
+		 */
+		if ((issued & CEPH_CAP_FILE_CACHE) == 0)
+			generic_error_remove_page(inode->i_mapping, page);
+
+		unlock_page(page);
+	}
+	dout("%p wrote+cleaned %d pages\n", inode, wrote);
+	ceph_put_wrbuffer_cap_refs(ci, req->r_num_pages, snapc);
+
+	ceph_release_pages(req->r_pages, req->r_num_pages);
+	if (req->r_pages_from_pool)
+		mempool_free(req->r_pages,
+			     ceph_client(inode->i_sb)->wb_pagevec_pool);
+	else
+		kfree(req->r_pages);
+	ceph_osdc_put_request(req);
+}
+
+/*
+ * allocate a page vec, either directly, or if necessary, via a the
+ * mempool.  we avoid the mempool if we can because req->r_num_pages
+ * may be less than the maximum write size.
+ */
+static void alloc_page_vec(struct ceph_client *client,
+			   struct ceph_osd_request *req)
+{
+	req->r_pages = kmalloc(sizeof(struct page *) * req->r_num_pages,
+			       GFP_NOFS);
+	if (!req->r_pages) {
+		req->r_pages = mempool_alloc(client->wb_pagevec_pool, GFP_NOFS);
+		req->r_pages_from_pool = 1;
+		WARN_ON(!req->r_pages);
+	}
+}
+
+/*
+ * initiate async writeback
+ */
+static int ceph_writepages_start(struct address_space *mapping,
+				 struct writeback_control *wbc)
+{
+	struct inode *inode = mapping->host;
+	struct backing_dev_info *bdi = mapping->backing_dev_info;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_client *client;
+	pgoff_t index, start, end;
+	int range_whole = 0;
+	int should_loop = 1;
+	pgoff_t max_pages = 0, max_pages_ever = 0;
+	struct ceph_snap_context *snapc = NULL, *last_snapc = NULL, *pgsnapc;
+	struct pagevec pvec;
+	int done = 0;
+	int rc = 0;
+	unsigned wsize = 1 << inode->i_blkbits;
+	struct ceph_osd_request *req = NULL;
+	int do_sync;
+	u64 snap_size = 0;
+
+	/*
+	 * Include a 'sync' in the OSD request if this is a data
+	 * integrity write (e.g., O_SYNC write or fsync()), or if our
+	 * cap is being revoked.
+	 */
+	do_sync = wbc->sync_mode == WB_SYNC_ALL;
+	if (ceph_caps_revoking(ci, CEPH_CAP_FILE_BUFFER))
+		do_sync = 1;
+	dout("writepages_start %p dosync=%d (mode=%s)\n",
+	     inode, do_sync,
+	     wbc->sync_mode == WB_SYNC_NONE ? "NONE" :
+	     (wbc->sync_mode == WB_SYNC_ALL ? "ALL" : "HOLD"));
+
+	client = ceph_inode_to_client(inode);
+	if (client->mount_state == CEPH_MOUNT_SHUTDOWN) {
+		pr_warning("writepage_start %p on forced umount\n", inode);
+		return -EIO; /* we're in a forced umount, don't write! */
+	}
+	if (client->mount_args->wsize && client->mount_args->wsize < wsize)
+		wsize = client->mount_args->wsize;
+	if (wsize < PAGE_CACHE_SIZE)
+		wsize = PAGE_CACHE_SIZE;
+	max_pages_ever = wsize >> PAGE_CACHE_SHIFT;
+
+	pagevec_init(&pvec, 0);
+
+	/* ?? */
+	if (wbc->nonblocking && bdi_write_congested(bdi)) {
+		dout(" writepages congested\n");
+		wbc->encountered_congestion = 1;
+		goto out_final;
+	}
+
+	/* where to start/end? */
+	if (wbc->range_cyclic) {
+		start = mapping->writeback_index; /* Start from prev offset */
+		end = -1;
+		dout(" cyclic, start at %lu\n", start);
+	} else {
+		start = wbc->range_start >> PAGE_CACHE_SHIFT;
+		end = wbc->range_end >> PAGE_CACHE_SHIFT;
+		if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
+			range_whole = 1;
+		should_loop = 0;
+		dout(" not cyclic, %lu to %lu\n", start, end);
+	}
+	index = start;
+
+retry:
+	/* find oldest snap context with dirty data */
+	ceph_put_snap_context(snapc);
+	snapc = get_oldest_context(inode, &snap_size);
+	if (!snapc) {
+		/* hmm, why does writepages get called when there
+		   is no dirty data? */
+		dout(" no snap context with dirty data?\n");
+		goto out;
+	}
+	dout(" oldest snapc is %p seq %lld (%d snaps)\n",
+	     snapc, snapc->seq, snapc->num_snaps);
+	if (last_snapc && snapc != last_snapc) {
+		/* if we switched to a newer snapc, restart our scan at the
+		 * start of the original file range. */
+		dout("  snapc differs from last pass, restarting at %lu\n",
+		     index);
+		index = start;
+	}
+	last_snapc = snapc;
+
+	while (!done && index <= end) {
+		unsigned i;
+		int first;
+		pgoff_t next;
+		int pvec_pages, locked_pages;
+		struct page *page;
+		int want;
+		u64 offset, len;
+		struct ceph_osd_request_head *reqhead;
+		struct ceph_osd_op *op;
+		long writeback_stat;
+
+		next = 0;
+		locked_pages = 0;
+		max_pages = max_pages_ever;
+
+get_more_pages:
+		first = -1;
+		want = min(end - index,
+			   min((pgoff_t)PAGEVEC_SIZE,
+			       max_pages - (pgoff_t)locked_pages) - 1)
+			+ 1;
+		pvec_pages = pagevec_lookup_tag(&pvec, mapping, &index,
+						PAGECACHE_TAG_DIRTY,
+						want);
+		dout("pagevec_lookup_tag got %d\n", pvec_pages);
+		if (!pvec_pages && !locked_pages)
+			break;
+		for (i = 0; i < pvec_pages && locked_pages < max_pages; i++) {
+			page = pvec.pages[i];
+			dout("? %p idx %lu\n", page, page->index);
+			if (locked_pages == 0)
+				lock_page(page);  /* first page */
+			else if (!trylock_page(page))
+				break;
+
+			/* only dirty pages, or our accounting breaks */
+			if (unlikely(!PageDirty(page)) ||
+			    unlikely(page->mapping != mapping)) {
+				dout("!dirty or !mapping %p\n", page);
+				unlock_page(page);
+				break;
+			}
+			if (!wbc->range_cyclic && page->index > end) {
+				dout("end of range %p\n", page);
+				done = 1;
+				unlock_page(page);
+				break;
+			}
+			if (next && (page->index != next)) {
+				dout("not consecutive %p\n", page);
+				unlock_page(page);
+				break;
+			}
+			if (wbc->sync_mode != WB_SYNC_NONE) {
+				dout("waiting on writeback %p\n", page);
+				wait_on_page_writeback(page);
+			}
+			if ((snap_size && page_offset(page) > snap_size) ||
+			    (!snap_size &&
+			     page_offset(page) > i_size_read(inode))) {
+				dout("%p page eof %llu\n", page, snap_size ?
+				     snap_size : i_size_read(inode));
+				done = 1;
+				unlock_page(page);
+				break;
+			}
+			if (PageWriteback(page)) {
+				dout("%p under writeback\n", page);
+				unlock_page(page);
+				break;
+			}
+
+			/* only if matching snap context */
+			pgsnapc = (void *)page->private;
+			if (pgsnapc->seq > snapc->seq) {
+				dout("page snapc %p %lld > oldest %p %lld\n",
+				     pgsnapc, pgsnapc->seq, snapc, snapc->seq);
+				unlock_page(page);
+				if (!locked_pages)
+					continue; /* keep looking for snap */
+				break;
+			}
+
+			if (!clear_page_dirty_for_io(page)) {
+				dout("%p !clear_page_dirty_for_io\n", page);
+				unlock_page(page);
+				break;
+			}
+
+			/* ok */
+			if (locked_pages == 0) {
+				/* prepare async write request */
+				offset = page->index << PAGE_CACHE_SHIFT;
+				len = wsize;
+				req = ceph_osdc_new_request(&client->osdc,
+					    &ci->i_layout,
+					    ceph_vino(inode),
+					    offset, &len,
+					    CEPH_OSD_OP_WRITE,
+					    CEPH_OSD_FLAG_WRITE |
+						    CEPH_OSD_FLAG_ONDISK,
+					    snapc, do_sync,
+					    ci->i_truncate_seq,
+					    ci->i_truncate_size,
+					    &inode->i_mtime, true, 1);
+				max_pages = req->r_num_pages;
+
+				alloc_page_vec(client, req);
+				req->r_callback = writepages_finish;
+				req->r_inode = inode;
+			}
+
+			/* note position of first page in pvec */
+			if (first < 0)
+				first = i;
+			dout("%p will write page %p idx %lu\n",
+			     inode, page, page->index);
+
+			writeback_stat = atomic_long_inc_return(&client->writeback_count);
+			if (writeback_stat > CONGESTION_ON_THRESH(client->mount_args->congestion_kb)) {
+				set_bdi_congested(&client->backing_dev_info, BLK_RW_ASYNC);
+			}
+
+			set_page_writeback(page);
+			req->r_pages[locked_pages] = page;
+			locked_pages++;
+			next = page->index + 1;
+		}
+
+		/* did we get anything? */
+		if (!locked_pages)
+			goto release_pvec_pages;
+		if (i) {
+			int j;
+			BUG_ON(!locked_pages || first < 0);
+
+			if (pvec_pages && i == pvec_pages &&
+			    locked_pages < max_pages) {
+				dout("reached end pvec, trying for more\n");
+				pagevec_reinit(&pvec);
+				goto get_more_pages;
+			}
+
+			/* shift unused pages over in the pvec...  we
+			 * will need to release them below. */
+			for (j = i; j < pvec_pages; j++) {
+				dout(" pvec leftover page %p\n",
+				     pvec.pages[j]);
+				pvec.pages[j-i+first] = pvec.pages[j];
+			}
+			pvec.nr -= i-first;
+		}
+
+		/* submit the write */
+		offset = req->r_pages[0]->index << PAGE_CACHE_SHIFT;
+		len = min((snap_size ? snap_size : i_size_read(inode)) - offset,
+			  (u64)locked_pages << PAGE_CACHE_SHIFT);
+		dout("writepages got %d pages at %llu~%llu\n",
+		     locked_pages, offset, len);
+
+		/* revise final length, page count */
+		req->r_num_pages = locked_pages;
+		reqhead = req->r_request->front.iov_base;
+		op = (void *)(reqhead + 1);
+		op->extent.length = cpu_to_le64(len);
+		op->payload_len = cpu_to_le32(len);
+		req->r_request->hdr.data_len = cpu_to_le32(len);
+
+		ceph_osdc_start_request(&client->osdc, req, true);
+		req = NULL;
+
+		/* continue? */
+		index = next;
+		wbc->nr_to_write -= locked_pages;
+		if (wbc->nr_to_write <= 0)
+			done = 1;
+
+release_pvec_pages:
+		dout("pagevec_release on %d pages (%p)\n", (int)pvec.nr,
+		     pvec.nr ? pvec.pages[0] : NULL);
+		pagevec_release(&pvec);
+
+		if (locked_pages && !done)
+			goto retry;
+	}
+
+	if (should_loop && !done) {
+		/* more to do; loop back to beginning of file */
+		dout("writepages looping back to beginning of file\n");
+		should_loop = 0;
+		index = 0;
+		goto retry;
+	}
+
+	if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
+		mapping->writeback_index = index;
+
+out:
+	if (req)
+		ceph_osdc_put_request(req);
+	if (rc > 0)
+		rc = 0;  /* vfs expects us to return 0 */
+	ceph_put_snap_context(snapc);
+	dout("writepages done, rc = %d\n", rc);
+out_final:
+	return rc;
+}
+
+
+
+/*
+ * See if a given @snapc is either writeable, or already written.
+ */
+static int context_is_writeable_or_written(struct inode *inode,
+					   struct ceph_snap_context *snapc)
+{
+	struct ceph_snap_context *oldest = get_oldest_context(inode, NULL);
+	int ret = !oldest || snapc->seq <= oldest->seq;
+
+	ceph_put_snap_context(oldest);
+	return ret;
+}
+
+/*
+ * We are only allowed to write into/dirty the page if the page is
+ * clean, or already dirty within the same snap context.
+ *
+ * called with page locked.
+ * return success with page locked,
+ * or any failure (incl -EAGAIN) with page unlocked.
+ */
+static int ceph_update_writeable_page(struct file *file,
+			    loff_t pos, unsigned len,
+			    struct page *page)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc;
+	loff_t page_off = pos & PAGE_CACHE_MASK;
+	int pos_in_page = pos & ~PAGE_CACHE_MASK;
+	int end_in_page = pos_in_page + len;
+	loff_t i_size;
+	int r;
+	struct ceph_snap_context *snapc, *oldest;
+
+retry_locked:
+	/* writepages currently holds page lock, but if we change that later, */
+	wait_on_page_writeback(page);
+
+	/* check snap context */
+	BUG_ON(!ci->i_snap_realm);
+	down_read(&mdsc->snap_rwsem);
+	BUG_ON(!ci->i_snap_realm->cached_context);
+	snapc = (void *)page->private;
+	if (snapc && snapc != ci->i_head_snapc) {
+		/*
+		 * this page is already dirty in another (older) snap
+		 * context!  is it writeable now?
+		 */
+		oldest = get_oldest_context(inode, NULL);
+		up_read(&mdsc->snap_rwsem);
+
+		if (snapc->seq > oldest->seq) {
+			ceph_put_snap_context(oldest);
+			dout(" page %p snapc %p not current or oldest\n",
+			     page, snapc);
+			/*
+			 * queue for writeback, and wait for snapc to
+			 * be writeable or written
+			 */
+			snapc = ceph_get_snap_context(snapc);
+			unlock_page(page);
+			ceph_queue_writeback(inode);
+			r = wait_event_interruptible(ci->i_cap_wq,
+			       context_is_writeable_or_written(inode, snapc));
+			ceph_put_snap_context(snapc);
+			if (r == -ERESTARTSYS)
+				return r;
+			return -EAGAIN;
+		}
+		ceph_put_snap_context(oldest);
+
+		/* yay, writeable, do it now (without dropping page lock) */
+		dout(" page %p snapc %p not current, but oldest\n",
+		     page, snapc);
+		if (!clear_page_dirty_for_io(page))
+			goto retry_locked;
+		r = writepage_nounlock(page, NULL);
+		if (r < 0)
+			goto fail_nosnap;
+		goto retry_locked;
+	}
+
+	if (PageUptodate(page)) {
+		dout(" page %p already uptodate\n", page);
+		return 0;
+	}
+
+	/* full page? */
+	if (pos_in_page == 0 && len == PAGE_CACHE_SIZE)
+		return 0;
+
+	/* past end of file? */
+	i_size = inode->i_size;   /* caller holds i_mutex */
+
+	if (i_size + len > inode->i_sb->s_maxbytes) {
+		/* file is too big */
+		r = -EINVAL;
+		goto fail;
+	}
+
+	if (page_off >= i_size ||
+	    (pos_in_page == 0 && (pos+len) >= i_size &&
+	     end_in_page - pos_in_page != PAGE_CACHE_SIZE)) {
+		dout(" zeroing %p 0 - %d and %d - %d\n",
+		     page, pos_in_page, end_in_page, (int)PAGE_CACHE_SIZE);
+		zero_user_segments(page,
+				   0, pos_in_page,
+				   end_in_page, PAGE_CACHE_SIZE);
+		return 0;
+	}
+
+	/* we need to read it. */
+	up_read(&mdsc->snap_rwsem);
+	r = readpage_nounlock(file, page);
+	if (r < 0)
+		goto fail_nosnap;
+	goto retry_locked;
+
+fail:
+	up_read(&mdsc->snap_rwsem);
+fail_nosnap:
+	unlock_page(page);
+	return r;
+}
+
+/*
+ * We are only allowed to write into/dirty the page if the page is
+ * clean, or already dirty within the same snap context.
+ */
+static int ceph_write_begin(struct file *file, struct address_space *mapping,
+			    loff_t pos, unsigned len, unsigned flags,
+			    struct page **pagep, void **fsdata)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	struct page *page;
+	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+	int r;
+
+	do {
+		/* get a page */
+		page = grab_cache_page_write_begin(mapping, index, 0);
+		if (!page)
+			return -ENOMEM;
+		*pagep = page;
+
+		dout("write_begin file %p inode %p page %p %d~%d\n", file,
+	     	inode, page, (int)pos, (int)len);
+
+		r = ceph_update_writeable_page(file, pos, len, page);
+	} while (r == -EAGAIN);
+
+	return r;
+}
+
+/*
+ * we don't do anything in here that simple_write_end doesn't do
+ * except adjust dirty page accounting and drop read lock on
+ * mdsc->snap_rwsem.
+ */
+static int ceph_write_end(struct file *file, struct address_space *mapping,
+			  loff_t pos, unsigned len, unsigned copied,
+			  struct page *page, void *fsdata)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	struct ceph_client *client = ceph_inode_to_client(inode);
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	unsigned from = pos & (PAGE_CACHE_SIZE - 1);
+	int check_cap = 0;
+
+	dout("write_end file %p inode %p page %p %d~%d (%d)\n", file,
+	     inode, page, (int)pos, (int)copied, (int)len);
+
+	/* zero the stale part of the page if we did a short copy */
+	if (copied < len)
+		zero_user_segment(page, from+copied, len);
+
+	/* did file size increase? */
+	/* (no need for i_size_read(); we caller holds i_mutex */
+	if (pos+copied > inode->i_size)
+		check_cap = ceph_inode_set_size(inode, pos+copied);
+
+	if (!PageUptodate(page))
+		SetPageUptodate(page);
+
+	set_page_dirty(page);
+
+	unlock_page(page);
+	up_read(&mdsc->snap_rwsem);
+	page_cache_release(page);
+
+	if (check_cap)
+		ceph_check_caps(ceph_inode(inode), CHECK_CAPS_AUTHONLY, NULL);
+
+	return copied;
+}
+
+/*
+ * we set .direct_IO to indicate direct io is supported, but since we
+ * intercept O_DIRECT reads and writes early, this function should
+ * never get called.
+ */
+static ssize_t ceph_direct_io(int rw, struct kiocb *iocb,
+			      const struct iovec *iov,
+			      loff_t pos, unsigned long nr_segs)
+{
+	WARN_ON(1);
+	return -EINVAL;
+}
+
+const struct address_space_operations ceph_aops = {
+	.readpage = ceph_readpage,
+	.readpages = ceph_readpages,
+	.writepage = ceph_writepage,
+	.writepages = ceph_writepages_start,
+	.write_begin = ceph_write_begin,
+	.write_end = ceph_write_end,
+	.set_page_dirty = ceph_set_page_dirty,
+	.invalidatepage = ceph_invalidatepage,
+	.releasepage = ceph_releasepage,
+	.direct_IO = ceph_direct_io,
+};
+
+
+/*
+ * vm ops
+ */
+
+/*
+ * Reuse write_begin here for simplicity.
+ */
+static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	struct inode *inode = vma->vm_file->f_dentry->d_inode;
+	struct page *page = vmf->page;
+	struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc;
+	loff_t off = page->index << PAGE_CACHE_SHIFT;
+	loff_t size, len;
+	int ret;
+
+	size = i_size_read(inode);
+	if (off + PAGE_CACHE_SIZE <= size)
+		len = PAGE_CACHE_SIZE;
+	else
+		len = size & ~PAGE_CACHE_MASK;
+
+	dout("page_mkwrite %p %llu~%llu page %p idx %lu\n", inode,
+	     off, len, page, page->index);
+
+	lock_page(page);
+
+	ret = VM_FAULT_NOPAGE;
+	if ((off > size) ||
+	    (page->mapping != inode->i_mapping))
+		goto out;
+
+	ret = ceph_update_writeable_page(vma->vm_file, off, len, page);
+	if (ret == 0) {
+		/* success.  we'll keep the page locked. */
+		set_page_dirty(page);
+		up_read(&mdsc->snap_rwsem);
+		ret = VM_FAULT_LOCKED;
+	} else {
+		if (ret == -ENOMEM)
+			ret = VM_FAULT_OOM;
+		else
+			ret = VM_FAULT_SIGBUS;
+	}
+out:
+	dout("page_mkwrite %p %llu~%llu = %d\n", inode, off, len, ret);
+	if (ret != VM_FAULT_LOCKED)
+		unlock_page(page);
+	return ret;
+}
+
+static struct vm_operations_struct ceph_vmops = {
+	.fault		= filemap_fault,
+	.page_mkwrite	= ceph_page_mkwrite,
+};
+
+int ceph_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct address_space *mapping = file->f_mapping;
+
+	if (!mapping->a_ops->readpage)
+		return -ENOEXEC;
+	file_accessed(file);
+	vma->vm_ops = &ceph_vmops;
+	vma->vm_flags |= VM_CAN_NONLINEAR;
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/armor.c linux-libre-2.6.34-gnu1/fs/ceph/armor.c
--- linux-libre-2.6.33-gnu1/fs/ceph/armor.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/armor.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,99 @@
+
+#include <linux/errno.h>
+
+/*
+ * base64 encode/decode.
+ */
+
+const char *pem_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static int encode_bits(int c)
+{
+	return pem_key[c];
+}
+
+static int decode_bits(char c)
+{
+	if (c >= 'A' && c <= 'Z')
+		return c - 'A';
+	if (c >= 'a' && c <= 'z')
+		return c - 'a' + 26;
+	if (c >= '0' && c <= '9')
+		return c - '0' + 52;
+	if (c == '+')
+		return 62;
+	if (c == '/')
+		return 63;
+	if (c == '=')
+		return 0; /* just non-negative, please */
+	return -EINVAL;
+}
+
+int ceph_armor(char *dst, const char *src, const char *end)
+{
+	int olen = 0;
+	int line = 0;
+
+	while (src < end) {
+		unsigned char a, b, c;
+
+		a = *src++;
+		*dst++ = encode_bits(a >> 2);
+		if (src < end) {
+			b = *src++;
+			*dst++ = encode_bits(((a & 3) << 4) | (b >> 4));
+			if (src < end) {
+				c = *src++;
+				*dst++ = encode_bits(((b & 15) << 2) |
+						     (c >> 6));
+				*dst++ = encode_bits(c & 63);
+			} else {
+				*dst++ = encode_bits((b & 15) << 2);
+				*dst++ = '=';
+			}
+		} else {
+			*dst++ = encode_bits(((a & 3) << 4));
+			*dst++ = '=';
+			*dst++ = '=';
+		}
+		olen += 4;
+		line += 4;
+		if (line == 64) {
+			line = 0;
+			*(dst++) = '\n';
+			olen++;
+		}
+	}
+	return olen;
+}
+
+int ceph_unarmor(char *dst, const char *src, const char *end)
+{
+	int olen = 0;
+
+	while (src < end) {
+		int a, b, c, d;
+
+		if (src < end && src[0] == '\n')
+			src++;
+		if (src + 4 > end)
+			return -EINVAL;
+		a = decode_bits(src[0]);
+		b = decode_bits(src[1]);
+		c = decode_bits(src[2]);
+		d = decode_bits(src[3]);
+		if (a < 0 || b < 0 || c < 0 || d < 0)
+			return -EINVAL;
+
+		*dst++ = (a << 2) | (b >> 4);
+		if (src[2] == '=')
+			return olen + 1;
+		*dst++ = ((b & 15) << 4) | (c >> 2);
+		if (src[3] == '=')
+			return olen + 2;
+		*dst++ = ((c & 3) << 6) | d;
+		olen += 3;
+		src += 4;
+	}
+	return olen;
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/auth.c linux-libre-2.6.34-gnu1/fs/ceph/auth.c
--- linux-libre-2.6.33-gnu1/fs/ceph/auth.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/auth.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,259 @@
+#include "ceph_debug.h"
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include "types.h"
+#include "auth_none.h"
+#include "auth_x.h"
+#include "decode.h"
+#include "super.h"
+
+#include "messenger.h"
+
+/*
+ * get protocol handler
+ */
+static u32 supported_protocols[] = {
+	CEPH_AUTH_NONE,
+	CEPH_AUTH_CEPHX
+};
+
+int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol)
+{
+	switch (protocol) {
+	case CEPH_AUTH_NONE:
+		return ceph_auth_none_init(ac);
+	case CEPH_AUTH_CEPHX:
+		return ceph_x_init(ac);
+	default:
+		return -ENOENT;
+	}
+}
+
+/*
+ * setup, teardown.
+ */
+struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret)
+{
+	struct ceph_auth_client *ac;
+	int ret;
+
+	dout("auth_init name '%s' secret '%s'\n", name, secret);
+
+	ret = -ENOMEM;
+	ac = kzalloc(sizeof(*ac), GFP_NOFS);
+	if (!ac)
+		goto out;
+
+	ac->negotiating = true;
+	if (name)
+		ac->name = name;
+	else
+		ac->name = CEPH_AUTH_NAME_DEFAULT;
+	dout("auth_init name %s secret %s\n", ac->name, secret);
+	ac->secret = secret;
+	return ac;
+
+out:
+	return ERR_PTR(ret);
+}
+
+void ceph_auth_destroy(struct ceph_auth_client *ac)
+{
+	dout("auth_destroy %p\n", ac);
+	if (ac->ops)
+		ac->ops->destroy(ac);
+	kfree(ac);
+}
+
+/*
+ * Reset occurs when reconnecting to the monitor.
+ */
+void ceph_auth_reset(struct ceph_auth_client *ac)
+{
+	dout("auth_reset %p\n", ac);
+	if (ac->ops && !ac->negotiating)
+		ac->ops->reset(ac);
+	ac->negotiating = true;
+}
+
+int ceph_entity_name_encode(const char *name, void **p, void *end)
+{
+	int len = strlen(name);
+
+	if (*p + 2*sizeof(u32) + len > end)
+		return -ERANGE;
+	ceph_encode_32(p, CEPH_ENTITY_TYPE_CLIENT);
+	ceph_encode_32(p, len);
+	ceph_encode_copy(p, name, len);
+	return 0;
+}
+
+/*
+ * Initiate protocol negotiation with monitor.  Include entity name
+ * and list supported protocols.
+ */
+int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len)
+{
+	struct ceph_mon_request_header *monhdr = buf;
+	void *p = monhdr + 1, *end = buf + len, *lenp;
+	int i, num;
+	int ret;
+
+	dout("auth_build_hello\n");
+	monhdr->have_version = 0;
+	monhdr->session_mon = cpu_to_le16(-1);
+	monhdr->session_mon_tid = 0;
+
+	ceph_encode_32(&p, 0);  /* no protocol, yet */
+
+	lenp = p;
+	p += sizeof(u32);
+
+	ceph_decode_need(&p, end, 1 + sizeof(u32), bad);
+	ceph_encode_8(&p, 1);
+	num = ARRAY_SIZE(supported_protocols);
+	ceph_encode_32(&p, num);
+	ceph_decode_need(&p, end, num * sizeof(u32), bad);
+	for (i = 0; i < num; i++)
+		ceph_encode_32(&p, supported_protocols[i]);
+
+	ret = ceph_entity_name_encode(ac->name, &p, end);
+	if (ret < 0)
+		return ret;
+	ceph_decode_need(&p, end, sizeof(u64), bad);
+	ceph_encode_64(&p, ac->global_id);
+
+	ceph_encode_32(&lenp, p - lenp - sizeof(u32));
+	return p - buf;
+
+bad:
+	return -ERANGE;
+}
+
+int ceph_build_auth_request(struct ceph_auth_client *ac,
+			   void *msg_buf, size_t msg_len)
+{
+	struct ceph_mon_request_header *monhdr = msg_buf;
+	void *p = monhdr + 1;
+	void *end = msg_buf + msg_len;
+	int ret;
+
+	monhdr->have_version = 0;
+	monhdr->session_mon = cpu_to_le16(-1);
+	monhdr->session_mon_tid = 0;
+
+	ceph_encode_32(&p, ac->protocol);
+
+	ret = ac->ops->build_request(ac, p + sizeof(u32), end);
+	if (ret < 0) {
+		pr_err("error %d building request\n", ret);
+		return ret;
+	}
+	dout(" built request %d bytes\n", ret);
+	ceph_encode_32(&p, ret);
+	return p + ret - msg_buf;
+}
+
+/*
+ * Handle auth message from monitor.
+ */
+int ceph_handle_auth_reply(struct ceph_auth_client *ac,
+			   void *buf, size_t len,
+			   void *reply_buf, size_t reply_len)
+{
+	void *p = buf;
+	void *end = buf + len;
+	int protocol;
+	s32 result;
+	u64 global_id;
+	void *payload, *payload_end;
+	int payload_len;
+	char *result_msg;
+	int result_msg_len;
+	int ret = -EINVAL;
+
+	dout("handle_auth_reply %p %p\n", p, end);
+	ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad);
+	protocol = ceph_decode_32(&p);
+	result = ceph_decode_32(&p);
+	global_id = ceph_decode_64(&p);
+	payload_len = ceph_decode_32(&p);
+	payload = p;
+	p += payload_len;
+	ceph_decode_need(&p, end, sizeof(u32), bad);
+	result_msg_len = ceph_decode_32(&p);
+	result_msg = p;
+	p += result_msg_len;
+	if (p != end)
+		goto bad;
+
+	dout(" result %d '%.*s' gid %llu len %d\n", result, result_msg_len,
+	     result_msg, global_id, payload_len);
+
+	payload_end = payload + payload_len;
+
+	if (global_id && ac->global_id != global_id) {
+		dout(" set global_id %lld -> %lld\n", ac->global_id, global_id);
+		ac->global_id = global_id;
+	}
+
+	if (ac->negotiating) {
+		/* server does not support our protocols? */
+		if (!protocol && result < 0) {
+			ret = result;
+			goto out;
+		}
+		/* set up (new) protocol handler? */
+		if (ac->protocol && ac->protocol != protocol) {
+			ac->ops->destroy(ac);
+			ac->protocol = 0;
+			ac->ops = NULL;
+		}
+		if (ac->protocol != protocol) {
+			ret = ceph_auth_init_protocol(ac, protocol);
+			if (ret) {
+				pr_err("error %d on auth protocol %d init\n",
+				       ret, protocol);
+				goto out;
+			}
+		}
+
+		ac->negotiating = false;
+	}
+
+	ret = ac->ops->handle_reply(ac, result, payload, payload_end);
+	if (ret == -EAGAIN) {
+		return ceph_build_auth_request(ac, reply_buf, reply_len);
+	} else if (ret) {
+		pr_err("authentication error %d\n", ret);
+		return ret;
+	}
+	return 0;
+
+bad:
+	pr_err("failed to decode auth msg\n");
+out:
+	return ret;
+}
+
+int ceph_build_auth(struct ceph_auth_client *ac,
+		    void *msg_buf, size_t msg_len)
+{
+	if (!ac->protocol)
+		return ceph_auth_build_hello(ac, msg_buf, msg_len);
+	BUG_ON(!ac->ops);
+	if (!ac->ops->is_authenticated(ac))
+		return ceph_build_auth_request(ac, msg_buf, msg_len);
+	return 0;
+}
+
+int ceph_auth_is_authenticated(struct ceph_auth_client *ac)
+{
+	if (!ac->ops)
+		return 0;
+	return ac->ops->is_authenticated(ac);
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/auth.h linux-libre-2.6.34-gnu1/fs/ceph/auth.h
--- linux-libre-2.6.33-gnu1/fs/ceph/auth.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/auth.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,84 @@
+#ifndef _FS_CEPH_AUTH_H
+#define _FS_CEPH_AUTH_H
+
+#include "types.h"
+#include "buffer.h"
+
+/*
+ * Abstract interface for communicating with the authenticate module.
+ * There is some handshake that takes place between us and the monitor
+ * to acquire the necessary keys.  These are used to generate an
+ * 'authorizer' that we use when connecting to a service (mds, osd).
+ */
+
+struct ceph_auth_client;
+struct ceph_authorizer;
+
+struct ceph_auth_client_ops {
+	/*
+	 * true if we are authenticated and can connect to
+	 * services.
+	 */
+	int (*is_authenticated)(struct ceph_auth_client *ac);
+
+	/*
+	 * build requests and process replies during monitor
+	 * handshake.  if handle_reply returns -EAGAIN, we build
+	 * another request.
+	 */
+	int (*build_request)(struct ceph_auth_client *ac, void *buf, void *end);
+	int (*handle_reply)(struct ceph_auth_client *ac, int result,
+			    void *buf, void *end);
+
+	/*
+	 * Create authorizer for connecting to a service, and verify
+	 * the response to authenticate the service.
+	 */
+	int (*create_authorizer)(struct ceph_auth_client *ac, int peer_type,
+				 struct ceph_authorizer **a,
+				 void **buf, size_t *len,
+				 void **reply_buf, size_t *reply_len);
+	int (*verify_authorizer_reply)(struct ceph_auth_client *ac,
+				       struct ceph_authorizer *a, size_t len);
+	void (*destroy_authorizer)(struct ceph_auth_client *ac,
+				   struct ceph_authorizer *a);
+	void (*invalidate_authorizer)(struct ceph_auth_client *ac,
+				      int peer_type);
+
+	/* reset when we (re)connect to a monitor */
+	void (*reset)(struct ceph_auth_client *ac);
+
+	void (*destroy)(struct ceph_auth_client *ac);
+};
+
+struct ceph_auth_client {
+	u32 protocol;           /* CEPH_AUTH_* */
+	void *private;          /* for use by protocol implementation */
+	const struct ceph_auth_client_ops *ops;  /* null iff protocol==0 */
+
+	bool negotiating;       /* true if negotiating protocol */
+	const char *name;       /* entity name */
+	u64 global_id;          /* our unique id in system */
+	const char *secret;     /* our secret key */
+	unsigned want_keys;     /* which services we want */
+};
+
+extern struct ceph_auth_client *ceph_auth_init(const char *name,
+					       const char *secret);
+extern void ceph_auth_destroy(struct ceph_auth_client *ac);
+
+extern void ceph_auth_reset(struct ceph_auth_client *ac);
+
+extern int ceph_auth_build_hello(struct ceph_auth_client *ac,
+				 void *buf, size_t len);
+extern int ceph_handle_auth_reply(struct ceph_auth_client *ac,
+				  void *buf, size_t len,
+				  void *reply_buf, size_t reply_len);
+extern int ceph_entity_name_encode(const char *name, void **p, void *end);
+
+extern int ceph_build_auth(struct ceph_auth_client *ac,
+		    void *msg_buf, size_t msg_len);
+
+extern int ceph_auth_is_authenticated(struct ceph_auth_client *ac);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/auth_none.c linux-libre-2.6.34-gnu1/fs/ceph/auth_none.c
--- linux-libre-2.6.33-gnu1/fs/ceph/auth_none.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/auth_none.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,122 @@
+
+#include "ceph_debug.h"
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+
+#include "auth_none.h"
+#include "auth.h"
+#include "decode.h"
+
+static void reset(struct ceph_auth_client *ac)
+{
+	struct ceph_auth_none_info *xi = ac->private;
+
+	xi->starting = true;
+	xi->built_authorizer = false;
+}
+
+static void destroy(struct ceph_auth_client *ac)
+{
+	kfree(ac->private);
+	ac->private = NULL;
+}
+
+static int is_authenticated(struct ceph_auth_client *ac)
+{
+	struct ceph_auth_none_info *xi = ac->private;
+
+	return !xi->starting;
+}
+
+/*
+ * the generic auth code decode the global_id, and we carry no actual
+ * authenticate state, so nothing happens here.
+ */
+static int handle_reply(struct ceph_auth_client *ac, int result,
+			void *buf, void *end)
+{
+	struct ceph_auth_none_info *xi = ac->private;
+
+	xi->starting = false;
+	return result;
+}
+
+/*
+ * build an 'authorizer' with our entity_name and global_id.  we can
+ * reuse a single static copy since it is identical for all services
+ * we connect to.
+ */
+static int ceph_auth_none_create_authorizer(
+	struct ceph_auth_client *ac, int peer_type,
+	struct ceph_authorizer **a,
+	void **buf, size_t *len,
+	void **reply_buf, size_t *reply_len)
+{
+	struct ceph_auth_none_info *ai = ac->private;
+	struct ceph_none_authorizer *au = &ai->au;
+	void *p, *end;
+	int ret;
+
+	if (!ai->built_authorizer) {
+		p = au->buf;
+		end = p + sizeof(au->buf);
+		ceph_encode_8(&p, 1);
+		ret = ceph_entity_name_encode(ac->name, &p, end - 8);
+		if (ret < 0)
+			goto bad;
+		ceph_decode_need(&p, end, sizeof(u64), bad2);
+		ceph_encode_64(&p, ac->global_id);
+		au->buf_len = p - (void *)au->buf;
+		ai->built_authorizer = true;
+		dout("built authorizer len %d\n", au->buf_len);
+	}
+
+	*a = (struct ceph_authorizer *)au;
+	*buf = au->buf;
+	*len = au->buf_len;
+	*reply_buf = au->reply_buf;
+	*reply_len = sizeof(au->reply_buf);
+	return 0;
+
+bad2:
+	ret = -ERANGE;
+bad:
+	return ret;
+}
+
+static void ceph_auth_none_destroy_authorizer(struct ceph_auth_client *ac,
+				      struct ceph_authorizer *a)
+{
+	/* nothing to do */
+}
+
+static const struct ceph_auth_client_ops ceph_auth_none_ops = {
+	.reset = reset,
+	.destroy = destroy,
+	.is_authenticated = is_authenticated,
+	.handle_reply = handle_reply,
+	.create_authorizer = ceph_auth_none_create_authorizer,
+	.destroy_authorizer = ceph_auth_none_destroy_authorizer,
+};
+
+int ceph_auth_none_init(struct ceph_auth_client *ac)
+{
+	struct ceph_auth_none_info *xi;
+
+	dout("ceph_auth_none_init %p\n", ac);
+	xi = kzalloc(sizeof(*xi), GFP_NOFS);
+	if (!xi)
+		return -ENOMEM;
+
+	xi->starting = true;
+	xi->built_authorizer = false;
+
+	ac->protocol = CEPH_AUTH_NONE;
+	ac->private = xi;
+	ac->ops = &ceph_auth_none_ops;
+	return 0;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/auth_none.h linux-libre-2.6.34-gnu1/fs/ceph/auth_none.h
--- linux-libre-2.6.33-gnu1/fs/ceph/auth_none.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/auth_none.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,30 @@
+#ifndef _FS_CEPH_AUTH_NONE_H
+#define _FS_CEPH_AUTH_NONE_H
+
+#include <linux/slab.h>
+
+#include "auth.h"
+
+/*
+ * null security mode.
+ *
+ * we use a single static authorizer that simply encodes our entity name
+ * and global id.
+ */
+
+struct ceph_none_authorizer {
+	char buf[128];
+	int buf_len;
+	char reply_buf[0];
+};
+
+struct ceph_auth_none_info {
+	bool starting;
+	bool built_authorizer;
+	struct ceph_none_authorizer au;   /* we only need one; it's static */
+};
+
+extern int ceph_auth_none_init(struct ceph_auth_client *ac);
+
+#endif
+
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/auth_x.c linux-libre-2.6.34-gnu1/fs/ceph/auth_x.c
--- linux-libre-2.6.33-gnu1/fs/ceph/auth_x.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/auth_x.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,668 @@
+
+#include "ceph_debug.h"
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+
+#include "auth_x.h"
+#include "auth_x_protocol.h"
+#include "crypto.h"
+#include "auth.h"
+#include "decode.h"
+
+#define TEMP_TICKET_BUF_LEN	256
+
+static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed);
+
+static int ceph_x_is_authenticated(struct ceph_auth_client *ac)
+{
+	struct ceph_x_info *xi = ac->private;
+	int need;
+
+	ceph_x_validate_tickets(ac, &need);
+	dout("ceph_x_is_authenticated want=%d need=%d have=%d\n",
+	     ac->want_keys, need, xi->have_keys);
+	return (ac->want_keys & xi->have_keys) == ac->want_keys;
+}
+
+static int ceph_x_encrypt_buflen(int ilen)
+{
+	return sizeof(struct ceph_x_encrypt_header) + ilen + 16 +
+		sizeof(u32);
+}
+
+static int ceph_x_encrypt(struct ceph_crypto_key *secret,
+			  void *ibuf, int ilen, void *obuf, size_t olen)
+{
+	struct ceph_x_encrypt_header head = {
+		.struct_v = 1,
+		.magic = cpu_to_le64(CEPHX_ENC_MAGIC)
+	};
+	size_t len = olen - sizeof(u32);
+	int ret;
+
+	ret = ceph_encrypt2(secret, obuf + sizeof(u32), &len,
+			    &head, sizeof(head), ibuf, ilen);
+	if (ret)
+		return ret;
+	ceph_encode_32(&obuf, len);
+	return len + sizeof(u32);
+}
+
+static int ceph_x_decrypt(struct ceph_crypto_key *secret,
+			  void **p, void *end, void *obuf, size_t olen)
+{
+	struct ceph_x_encrypt_header head;
+	size_t head_len = sizeof(head);
+	int len, ret;
+
+	len = ceph_decode_32(p);
+	if (*p + len > end)
+		return -EINVAL;
+
+	dout("ceph_x_decrypt len %d\n", len);
+	ret = ceph_decrypt2(secret, &head, &head_len, obuf, &olen,
+			    *p, len);
+	if (ret)
+		return ret;
+	if (head.struct_v != 1 || le64_to_cpu(head.magic) != CEPHX_ENC_MAGIC)
+		return -EPERM;
+	*p += len;
+	return olen;
+}
+
+/*
+ * get existing (or insert new) ticket handler
+ */
+struct ceph_x_ticket_handler *get_ticket_handler(struct ceph_auth_client *ac,
+						 int service)
+{
+	struct ceph_x_ticket_handler *th;
+	struct ceph_x_info *xi = ac->private;
+	struct rb_node *parent = NULL, **p = &xi->ticket_handlers.rb_node;
+
+	while (*p) {
+		parent = *p;
+		th = rb_entry(parent, struct ceph_x_ticket_handler, node);
+		if (service < th->service)
+			p = &(*p)->rb_left;
+		else if (service > th->service)
+			p = &(*p)->rb_right;
+		else
+			return th;
+	}
+
+	/* add it */
+	th = kzalloc(sizeof(*th), GFP_NOFS);
+	if (!th)
+		return ERR_PTR(-ENOMEM);
+	th->service = service;
+	rb_link_node(&th->node, parent, p);
+	rb_insert_color(&th->node, &xi->ticket_handlers);
+	return th;
+}
+
+static void remove_ticket_handler(struct ceph_auth_client *ac,
+				  struct ceph_x_ticket_handler *th)
+{
+	struct ceph_x_info *xi = ac->private;
+
+	dout("remove_ticket_handler %p %d\n", th, th->service);
+	rb_erase(&th->node, &xi->ticket_handlers);
+	ceph_crypto_key_destroy(&th->session_key);
+	if (th->ticket_blob)
+		ceph_buffer_put(th->ticket_blob);
+	kfree(th);
+}
+
+static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
+				    struct ceph_crypto_key *secret,
+				    void *buf, void *end)
+{
+	struct ceph_x_info *xi = ac->private;
+	int num;
+	void *p = buf;
+	int ret;
+	char *dbuf;
+	char *ticket_buf;
+	u8 struct_v;
+
+	dbuf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS);
+	if (!dbuf)
+		return -ENOMEM;
+
+	ret = -ENOMEM;
+	ticket_buf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS);
+	if (!ticket_buf)
+		goto out_dbuf;
+
+	ceph_decode_need(&p, end, 1 + sizeof(u32), bad);
+	struct_v = ceph_decode_8(&p);
+	if (struct_v != 1)
+		goto bad;
+	num = ceph_decode_32(&p);
+	dout("%d tickets\n", num);
+	while (num--) {
+		int type;
+		u8 struct_v;
+		struct ceph_x_ticket_handler *th;
+		void *dp, *dend;
+		int dlen;
+		char is_enc;
+		struct timespec validity;
+		struct ceph_crypto_key old_key;
+		void *tp, *tpend;
+		struct ceph_timespec new_validity;
+		struct ceph_crypto_key new_session_key;
+		struct ceph_buffer *new_ticket_blob;
+		unsigned long new_expires, new_renew_after;
+		u64 new_secret_id;
+
+		ceph_decode_need(&p, end, sizeof(u32) + 1, bad);
+
+		type = ceph_decode_32(&p);
+		dout(" ticket type %d %s\n", type, ceph_entity_type_name(type));
+
+		struct_v = ceph_decode_8(&p);
+		if (struct_v != 1)
+			goto bad;
+
+		th = get_ticket_handler(ac, type);
+		if (IS_ERR(th)) {
+			ret = PTR_ERR(th);
+			goto out;
+		}
+
+		/* blob for me */
+		dlen = ceph_x_decrypt(secret, &p, end, dbuf,
+				      TEMP_TICKET_BUF_LEN);
+		if (dlen <= 0) {
+			ret = dlen;
+			goto out;
+		}
+		dout(" decrypted %d bytes\n", dlen);
+		dend = dbuf + dlen;
+		dp = dbuf;
+
+		struct_v = ceph_decode_8(&dp);
+		if (struct_v != 1)
+			goto bad;
+
+		memcpy(&old_key, &th->session_key, sizeof(old_key));
+		ret = ceph_crypto_key_decode(&new_session_key, &dp, dend);
+		if (ret)
+			goto out;
+
+		ceph_decode_copy(&dp, &new_validity, sizeof(new_validity));
+		ceph_decode_timespec(&validity, &new_validity);
+		new_expires = get_seconds() + validity.tv_sec;
+		new_renew_after = new_expires - (validity.tv_sec / 4);
+		dout(" expires=%lu renew_after=%lu\n", new_expires,
+		     new_renew_after);
+
+		/* ticket blob for service */
+		ceph_decode_8_safe(&p, end, is_enc, bad);
+		tp = ticket_buf;
+		if (is_enc) {
+			/* encrypted */
+			dout(" encrypted ticket\n");
+			dlen = ceph_x_decrypt(&old_key, &p, end, ticket_buf,
+					      TEMP_TICKET_BUF_LEN);
+			if (dlen < 0) {
+				ret = dlen;
+				goto out;
+			}
+			dlen = ceph_decode_32(&tp);
+		} else {
+			/* unencrypted */
+			ceph_decode_32_safe(&p, end, dlen, bad);
+			ceph_decode_need(&p, end, dlen, bad);
+			ceph_decode_copy(&p, ticket_buf, dlen);
+		}
+		tpend = tp + dlen;
+		dout(" ticket blob is %d bytes\n", dlen);
+		ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad);
+		struct_v = ceph_decode_8(&tp);
+		new_secret_id = ceph_decode_64(&tp);
+		ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend);
+		if (ret)
+			goto out;
+
+		/* all is well, update our ticket */
+		ceph_crypto_key_destroy(&th->session_key);
+		if (th->ticket_blob)
+			ceph_buffer_put(th->ticket_blob);
+		th->session_key = new_session_key;
+		th->ticket_blob = new_ticket_blob;
+		th->validity = new_validity;
+		th->secret_id = new_secret_id;
+		th->expires = new_expires;
+		th->renew_after = new_renew_after;
+		dout(" got ticket service %d (%s) secret_id %lld len %d\n",
+		     type, ceph_entity_type_name(type), th->secret_id,
+		     (int)th->ticket_blob->vec.iov_len);
+		xi->have_keys |= th->service;
+	}
+
+	ret = 0;
+out:
+	kfree(ticket_buf);
+out_dbuf:
+	kfree(dbuf);
+	return ret;
+
+bad:
+	ret = -EINVAL;
+	goto out;
+}
+
+static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
+				   struct ceph_x_ticket_handler *th,
+				   struct ceph_x_authorizer *au)
+{
+	int maxlen;
+	struct ceph_x_authorize_a *msg_a;
+	struct ceph_x_authorize_b msg_b;
+	void *p, *end;
+	int ret;
+	int ticket_blob_len =
+		(th->ticket_blob ? th->ticket_blob->vec.iov_len : 0);
+
+	dout("build_authorizer for %s %p\n",
+	     ceph_entity_type_name(th->service), au);
+
+	maxlen = sizeof(*msg_a) + sizeof(msg_b) +
+		ceph_x_encrypt_buflen(ticket_blob_len);
+	dout("  need len %d\n", maxlen);
+	if (au->buf && au->buf->alloc_len < maxlen) {
+		ceph_buffer_put(au->buf);
+		au->buf = NULL;
+	}
+	if (!au->buf) {
+		au->buf = ceph_buffer_new(maxlen, GFP_NOFS);
+		if (!au->buf)
+			return -ENOMEM;
+	}
+	au->service = th->service;
+
+	msg_a = au->buf->vec.iov_base;
+	msg_a->struct_v = 1;
+	msg_a->global_id = cpu_to_le64(ac->global_id);
+	msg_a->service_id = cpu_to_le32(th->service);
+	msg_a->ticket_blob.struct_v = 1;
+	msg_a->ticket_blob.secret_id = cpu_to_le64(th->secret_id);
+	msg_a->ticket_blob.blob_len = cpu_to_le32(ticket_blob_len);
+	if (ticket_blob_len) {
+		memcpy(msg_a->ticket_blob.blob, th->ticket_blob->vec.iov_base,
+		       th->ticket_blob->vec.iov_len);
+	}
+	dout(" th %p secret_id %lld %lld\n", th, th->secret_id,
+	     le64_to_cpu(msg_a->ticket_blob.secret_id));
+
+	p = msg_a + 1;
+	p += ticket_blob_len;
+	end = au->buf->vec.iov_base + au->buf->vec.iov_len;
+
+	get_random_bytes(&au->nonce, sizeof(au->nonce));
+	msg_b.struct_v = 1;
+	msg_b.nonce = cpu_to_le64(au->nonce);
+	ret = ceph_x_encrypt(&th->session_key, &msg_b, sizeof(msg_b),
+			     p, end - p);
+	if (ret < 0)
+		goto out_buf;
+	p += ret;
+	au->buf->vec.iov_len = p - au->buf->vec.iov_base;
+	dout(" built authorizer nonce %llx len %d\n", au->nonce,
+	     (int)au->buf->vec.iov_len);
+	BUG_ON(au->buf->vec.iov_len > maxlen);
+	return 0;
+
+out_buf:
+	ceph_buffer_put(au->buf);
+	au->buf = NULL;
+	return ret;
+}
+
+static int ceph_x_encode_ticket(struct ceph_x_ticket_handler *th,
+				void **p, void *end)
+{
+	ceph_decode_need(p, end, 1 + sizeof(u64), bad);
+	ceph_encode_8(p, 1);
+	ceph_encode_64(p, th->secret_id);
+	if (th->ticket_blob) {
+		const char *buf = th->ticket_blob->vec.iov_base;
+		u32 len = th->ticket_blob->vec.iov_len;
+
+		ceph_encode_32_safe(p, end, len, bad);
+		ceph_encode_copy_safe(p, end, buf, len, bad);
+	} else {
+		ceph_encode_32_safe(p, end, 0, bad);
+	}
+
+	return 0;
+bad:
+	return -ERANGE;
+}
+
+static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed)
+{
+	int want = ac->want_keys;
+	struct ceph_x_info *xi = ac->private;
+	int service;
+
+	*pneed = ac->want_keys & ~(xi->have_keys);
+
+	for (service = 1; service <= want; service <<= 1) {
+		struct ceph_x_ticket_handler *th;
+
+		if (!(ac->want_keys & service))
+			continue;
+
+		if (*pneed & service)
+			continue;
+
+		th = get_ticket_handler(ac, service);
+
+		if (!th) {
+			*pneed |= service;
+			continue;
+		}
+
+		if (get_seconds() >= th->renew_after)
+			*pneed |= service;
+		if (get_seconds() >= th->expires)
+			xi->have_keys &= ~service;
+	}
+}
+
+
+static int ceph_x_build_request(struct ceph_auth_client *ac,
+				void *buf, void *end)
+{
+	struct ceph_x_info *xi = ac->private;
+	int need;
+	struct ceph_x_request_header *head = buf;
+	int ret;
+	struct ceph_x_ticket_handler *th =
+		get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH);
+
+	ceph_x_validate_tickets(ac, &need);
+
+	dout("build_request want %x have %x need %x\n",
+	     ac->want_keys, xi->have_keys, need);
+
+	if (need & CEPH_ENTITY_TYPE_AUTH) {
+		struct ceph_x_authenticate *auth = (void *)(head + 1);
+		void *p = auth + 1;
+		struct ceph_x_challenge_blob tmp;
+		char tmp_enc[40];
+		u64 *u;
+
+		if (p > end)
+			return -ERANGE;
+
+		dout(" get_auth_session_key\n");
+		head->op = cpu_to_le16(CEPHX_GET_AUTH_SESSION_KEY);
+
+		/* encrypt and hash */
+		get_random_bytes(&auth->client_challenge, sizeof(u64));
+		tmp.client_challenge = auth->client_challenge;
+		tmp.server_challenge = cpu_to_le64(xi->server_challenge);
+		ret = ceph_x_encrypt(&xi->secret, &tmp, sizeof(tmp),
+				     tmp_enc, sizeof(tmp_enc));
+		if (ret < 0)
+			return ret;
+
+		auth->struct_v = 1;
+		auth->key = 0;
+		for (u = (u64 *)tmp_enc; u + 1 <= (u64 *)(tmp_enc + ret); u++)
+			auth->key ^= *u;
+		dout(" server_challenge %llx client_challenge %llx key %llx\n",
+		     xi->server_challenge, le64_to_cpu(auth->client_challenge),
+		     le64_to_cpu(auth->key));
+
+		/* now encode the old ticket if exists */
+		ret = ceph_x_encode_ticket(th, &p, end);
+		if (ret < 0)
+			return ret;
+
+		return p - buf;
+	}
+
+	if (need) {
+		void *p = head + 1;
+		struct ceph_x_service_ticket_request *req;
+
+		if (p > end)
+			return -ERANGE;
+		head->op = cpu_to_le16(CEPHX_GET_PRINCIPAL_SESSION_KEY);
+
+		BUG_ON(!th);
+		ret = ceph_x_build_authorizer(ac, th, &xi->auth_authorizer);
+		if (ret)
+			return ret;
+		ceph_encode_copy(&p, xi->auth_authorizer.buf->vec.iov_base,
+				 xi->auth_authorizer.buf->vec.iov_len);
+
+		req = p;
+		req->keys = cpu_to_le32(need);
+		p += sizeof(*req);
+		return p - buf;
+	}
+
+	return 0;
+}
+
+static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result,
+			       void *buf, void *end)
+{
+	struct ceph_x_info *xi = ac->private;
+	struct ceph_x_reply_header *head = buf;
+	struct ceph_x_ticket_handler *th;
+	int len = end - buf;
+	int op;
+	int ret;
+
+	if (result)
+		return result;  /* XXX hmm? */
+
+	if (xi->starting) {
+		/* it's a hello */
+		struct ceph_x_server_challenge *sc = buf;
+
+		if (len != sizeof(*sc))
+			return -EINVAL;
+		xi->server_challenge = le64_to_cpu(sc->server_challenge);
+		dout("handle_reply got server challenge %llx\n",
+		     xi->server_challenge);
+		xi->starting = false;
+		xi->have_keys &= ~CEPH_ENTITY_TYPE_AUTH;
+		return -EAGAIN;
+	}
+
+	op = le32_to_cpu(head->op);
+	result = le32_to_cpu(head->result);
+	dout("handle_reply op %d result %d\n", op, result);
+	switch (op) {
+	case CEPHX_GET_AUTH_SESSION_KEY:
+		/* verify auth key */
+		ret = ceph_x_proc_ticket_reply(ac, &xi->secret,
+					       buf + sizeof(*head), end);
+		break;
+
+	case CEPHX_GET_PRINCIPAL_SESSION_KEY:
+		th = get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH);
+		BUG_ON(!th);
+		ret = ceph_x_proc_ticket_reply(ac, &th->session_key,
+					       buf + sizeof(*head), end);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	if (ret)
+		return ret;
+	if (ac->want_keys == xi->have_keys)
+		return 0;
+	return -EAGAIN;
+}
+
+static int ceph_x_create_authorizer(
+	struct ceph_auth_client *ac, int peer_type,
+	struct ceph_authorizer **a,
+	void **buf, size_t *len,
+	void **reply_buf, size_t *reply_len)
+{
+	struct ceph_x_authorizer *au;
+	struct ceph_x_ticket_handler *th;
+	int ret;
+
+	th = get_ticket_handler(ac, peer_type);
+	if (IS_ERR(th))
+		return PTR_ERR(th);
+
+	au = kzalloc(sizeof(*au), GFP_NOFS);
+	if (!au)
+		return -ENOMEM;
+
+	ret = ceph_x_build_authorizer(ac, th, au);
+	if (ret) {
+		kfree(au);
+		return ret;
+	}
+
+	*a = (struct ceph_authorizer *)au;
+	*buf = au->buf->vec.iov_base;
+	*len = au->buf->vec.iov_len;
+	*reply_buf = au->reply_buf;
+	*reply_len = sizeof(au->reply_buf);
+	return 0;
+}
+
+static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac,
+					  struct ceph_authorizer *a, size_t len)
+{
+	struct ceph_x_authorizer *au = (void *)a;
+	struct ceph_x_ticket_handler *th;
+	int ret = 0;
+	struct ceph_x_authorize_reply reply;
+	void *p = au->reply_buf;
+	void *end = p + sizeof(au->reply_buf);
+
+	th = get_ticket_handler(ac, au->service);
+	if (!th)
+		return -EIO;  /* hrm! */
+	ret = ceph_x_decrypt(&th->session_key, &p, end, &reply, sizeof(reply));
+	if (ret < 0)
+		return ret;
+	if (ret != sizeof(reply))
+		return -EPERM;
+
+	if (au->nonce + 1 != le64_to_cpu(reply.nonce_plus_one))
+		ret = -EPERM;
+	else
+		ret = 0;
+	dout("verify_authorizer_reply nonce %llx got %llx ret %d\n",
+	     au->nonce, le64_to_cpu(reply.nonce_plus_one), ret);
+	return ret;
+}
+
+static void ceph_x_destroy_authorizer(struct ceph_auth_client *ac,
+				      struct ceph_authorizer *a)
+{
+	struct ceph_x_authorizer *au = (void *)a;
+
+	ceph_buffer_put(au->buf);
+	kfree(au);
+}
+
+
+static void ceph_x_reset(struct ceph_auth_client *ac)
+{
+	struct ceph_x_info *xi = ac->private;
+
+	dout("reset\n");
+	xi->starting = true;
+	xi->server_challenge = 0;
+}
+
+static void ceph_x_destroy(struct ceph_auth_client *ac)
+{
+	struct ceph_x_info *xi = ac->private;
+	struct rb_node *p;
+
+	dout("ceph_x_destroy %p\n", ac);
+	ceph_crypto_key_destroy(&xi->secret);
+
+	while ((p = rb_first(&xi->ticket_handlers)) != NULL) {
+		struct ceph_x_ticket_handler *th =
+			rb_entry(p, struct ceph_x_ticket_handler, node);
+		remove_ticket_handler(ac, th);
+	}
+
+	kfree(ac->private);
+	ac->private = NULL;
+}
+
+static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac,
+				   int peer_type)
+{
+	struct ceph_x_ticket_handler *th;
+
+	th = get_ticket_handler(ac, peer_type);
+	if (th && !IS_ERR(th))
+		remove_ticket_handler(ac, th);
+}
+
+
+static const struct ceph_auth_client_ops ceph_x_ops = {
+	.is_authenticated = ceph_x_is_authenticated,
+	.build_request = ceph_x_build_request,
+	.handle_reply = ceph_x_handle_reply,
+	.create_authorizer = ceph_x_create_authorizer,
+	.verify_authorizer_reply = ceph_x_verify_authorizer_reply,
+	.destroy_authorizer = ceph_x_destroy_authorizer,
+	.invalidate_authorizer = ceph_x_invalidate_authorizer,
+	.reset =  ceph_x_reset,
+	.destroy = ceph_x_destroy,
+};
+
+
+int ceph_x_init(struct ceph_auth_client *ac)
+{
+	struct ceph_x_info *xi;
+	int ret;
+
+	dout("ceph_x_init %p\n", ac);
+	ret = -ENOMEM;
+	xi = kzalloc(sizeof(*xi), GFP_NOFS);
+	if (!xi)
+		goto out;
+
+	ret = -EINVAL;
+	if (!ac->secret) {
+		pr_err("no secret set (for auth_x protocol)\n");
+		goto out_nomem;
+	}
+
+	ret = ceph_crypto_key_unarmor(&xi->secret, ac->secret);
+	if (ret)
+		goto out_nomem;
+
+	xi->starting = true;
+	xi->ticket_handlers = RB_ROOT;
+
+	ac->protocol = CEPH_AUTH_CEPHX;
+	ac->private = xi;
+	ac->ops = &ceph_x_ops;
+	return 0;
+
+out_nomem:
+	kfree(xi);
+out:
+	return ret;
+}
+
+
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/auth_x.h linux-libre-2.6.34-gnu1/fs/ceph/auth_x.h
--- linux-libre-2.6.33-gnu1/fs/ceph/auth_x.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/auth_x.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,49 @@
+#ifndef _FS_CEPH_AUTH_X_H
+#define _FS_CEPH_AUTH_X_H
+
+#include <linux/rbtree.h>
+
+#include "crypto.h"
+#include "auth.h"
+#include "auth_x_protocol.h"
+
+/*
+ * Handle ticket for a single service.
+ */
+struct ceph_x_ticket_handler {
+	struct rb_node node;
+	unsigned service;
+
+	struct ceph_crypto_key session_key;
+	struct ceph_timespec validity;
+
+	u64 secret_id;
+	struct ceph_buffer *ticket_blob;
+
+	unsigned long renew_after, expires;
+};
+
+
+struct ceph_x_authorizer {
+	struct ceph_buffer *buf;
+	unsigned service;
+	u64 nonce;
+	char reply_buf[128];  /* big enough for encrypted blob */
+};
+
+struct ceph_x_info {
+	struct ceph_crypto_key secret;
+
+	bool starting;
+	u64 server_challenge;
+
+	unsigned have_keys;
+	struct rb_root ticket_handlers;
+
+	struct ceph_x_authorizer auth_authorizer;
+};
+
+extern int ceph_x_init(struct ceph_auth_client *ac);
+
+#endif
+
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/auth_x_protocol.h linux-libre-2.6.34-gnu1/fs/ceph/auth_x_protocol.h
--- linux-libre-2.6.33-gnu1/fs/ceph/auth_x_protocol.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/auth_x_protocol.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,90 @@
+#ifndef __FS_CEPH_AUTH_X_PROTOCOL
+#define __FS_CEPH_AUTH_X_PROTOCOL
+
+#define CEPHX_GET_AUTH_SESSION_KEY      0x0100
+#define CEPHX_GET_PRINCIPAL_SESSION_KEY 0x0200
+#define CEPHX_GET_ROTATING_KEY          0x0400
+
+/* common bits */
+struct ceph_x_ticket_blob {
+	__u8 struct_v;
+	__le64 secret_id;
+	__le32 blob_len;
+	char blob[];
+} __attribute__ ((packed));
+
+
+/* common request/reply headers */
+struct ceph_x_request_header {
+	__le16 op;
+} __attribute__ ((packed));
+
+struct ceph_x_reply_header {
+	__le16 op;
+	__le32 result;
+} __attribute__ ((packed));
+
+
+/* authenticate handshake */
+
+/* initial hello (no reply header) */
+struct ceph_x_server_challenge {
+	__u8 struct_v;
+	__le64 server_challenge;
+} __attribute__ ((packed));
+
+struct ceph_x_authenticate {
+	__u8 struct_v;
+	__le64 client_challenge;
+	__le64 key;
+	/* ticket blob */
+} __attribute__ ((packed));
+
+struct ceph_x_service_ticket_request {
+	__u8 struct_v;
+	__le32 keys;
+} __attribute__ ((packed));
+
+struct ceph_x_challenge_blob {
+	__le64 server_challenge;
+	__le64 client_challenge;
+} __attribute__ ((packed));
+
+
+
+/* authorize handshake */
+
+/*
+ * The authorizer consists of two pieces:
+ *  a - service id, ticket blob
+ *  b - encrypted with session key
+ */
+struct ceph_x_authorize_a {
+	__u8 struct_v;
+	__le64 global_id;
+	__le32 service_id;
+	struct ceph_x_ticket_blob ticket_blob;
+} __attribute__ ((packed));
+
+struct ceph_x_authorize_b {
+	__u8 struct_v;
+	__le64 nonce;
+} __attribute__ ((packed));
+
+struct ceph_x_authorize_reply {
+	__u8 struct_v;
+	__le64 nonce_plus_one;
+} __attribute__ ((packed));
+
+
+/*
+ * encyption bundle
+ */
+#define CEPHX_ENC_MAGIC 0xff009cad8826aa55ull
+
+struct ceph_x_encrypt_header {
+	__u8 struct_v;
+	__le64 magic;
+} __attribute__ ((packed));
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/buffer.c linux-libre-2.6.34-gnu1/fs/ceph/buffer.c
--- linux-libre-2.6.33-gnu1/fs/ceph/buffer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/buffer.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,81 @@
+
+#include "ceph_debug.h"
+
+#include <linux/slab.h>
+
+#include "buffer.h"
+#include "decode.h"
+
+struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp)
+{
+	struct ceph_buffer *b;
+
+	b = kmalloc(sizeof(*b), gfp);
+	if (!b)
+		return NULL;
+
+	b->vec.iov_base = kmalloc(len, gfp | __GFP_NOWARN);
+	if (b->vec.iov_base) {
+		b->is_vmalloc = false;
+	} else {
+		b->vec.iov_base = __vmalloc(len, gfp, PAGE_KERNEL);
+		if (!b->vec.iov_base) {
+			kfree(b);
+			return NULL;
+		}
+		b->is_vmalloc = true;
+	}
+
+	kref_init(&b->kref);
+	b->alloc_len = len;
+	b->vec.iov_len = len;
+	dout("buffer_new %p\n", b);
+	return b;
+}
+
+void ceph_buffer_release(struct kref *kref)
+{
+	struct ceph_buffer *b = container_of(kref, struct ceph_buffer, kref);
+
+	dout("buffer_release %p\n", b);
+	if (b->vec.iov_base) {
+		if (b->is_vmalloc)
+			vfree(b->vec.iov_base);
+		else
+			kfree(b->vec.iov_base);
+	}
+	kfree(b);
+}
+
+int ceph_buffer_alloc(struct ceph_buffer *b, int len, gfp_t gfp)
+{
+	b->vec.iov_base = kmalloc(len, gfp | __GFP_NOWARN);
+	if (b->vec.iov_base) {
+		b->is_vmalloc = false;
+	} else {
+		b->vec.iov_base = __vmalloc(len, gfp, PAGE_KERNEL);
+		b->is_vmalloc = true;
+	}
+	if (!b->vec.iov_base)
+		return -ENOMEM;
+	b->alloc_len = len;
+	b->vec.iov_len = len;
+	return 0;
+}
+
+int ceph_decode_buffer(struct ceph_buffer **b, void **p, void *end)
+{
+	size_t len;
+
+	ceph_decode_need(p, end, sizeof(u32), bad);
+	len = ceph_decode_32(p);
+	dout("decode_buffer len %d\n", (int)len);
+	ceph_decode_need(p, end, len, bad);
+	*b = ceph_buffer_new(len, GFP_NOFS);
+	if (!*b)
+		return -ENOMEM;
+	ceph_decode_copy(p, (*b)->vec.iov_base, len);
+	return 0;
+bad:
+	return -EINVAL;
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/buffer.h linux-libre-2.6.34-gnu1/fs/ceph/buffer.h
--- linux-libre-2.6.33-gnu1/fs/ceph/buffer.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/buffer.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,39 @@
+#ifndef __FS_CEPH_BUFFER_H
+#define __FS_CEPH_BUFFER_H
+
+#include <linux/kref.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/types.h>
+#include <linux/uio.h>
+
+/*
+ * a simple reference counted buffer.
+ *
+ * use kmalloc for small sizes (<= one page), vmalloc for larger
+ * sizes.
+ */
+struct ceph_buffer {
+	struct kref kref;
+	struct kvec vec;
+	size_t alloc_len;
+	bool is_vmalloc;
+};
+
+extern struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp);
+extern void ceph_buffer_release(struct kref *kref);
+
+static inline struct ceph_buffer *ceph_buffer_get(struct ceph_buffer *b)
+{
+	kref_get(&b->kref);
+	return b;
+}
+
+static inline void ceph_buffer_put(struct ceph_buffer *b)
+{
+	kref_put(&b->kref, ceph_buffer_release);
+}
+
+extern int ceph_decode_buffer(struct ceph_buffer **b, void **p, void *end);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/caps.c linux-libre-2.6.34-gnu1/fs/ceph/caps.c
--- linux-libre-2.6.33-gnu1/fs/ceph/caps.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/caps.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,2960 @@
+#include "ceph_debug.h"
+
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/wait.h>
+#include <linux/writeback.h>
+
+#include "super.h"
+#include "decode.h"
+#include "messenger.h"
+
+/*
+ * Capability management
+ *
+ * The Ceph metadata servers control client access to inode metadata
+ * and file data by issuing capabilities, granting clients permission
+ * to read and/or write both inode field and file data to OSDs
+ * (storage nodes).  Each capability consists of a set of bits
+ * indicating which operations are allowed.
+ *
+ * If the client holds a *_SHARED cap, the client has a coherent value
+ * that can be safely read from the cached inode.
+ *
+ * In the case of a *_EXCL (exclusive) or FILE_WR capabilities, the
+ * client is allowed to change inode attributes (e.g., file size,
+ * mtime), note its dirty state in the ceph_cap, and asynchronously
+ * flush that metadata change to the MDS.
+ *
+ * In the event of a conflicting operation (perhaps by another
+ * client), the MDS will revoke the conflicting client capabilities.
+ *
+ * In order for a client to cache an inode, it must hold a capability
+ * with at least one MDS server.  When inodes are released, release
+ * notifications are batched and periodically sent en masse to the MDS
+ * cluster to release server state.
+ */
+
+
+/*
+ * Generate readable cap strings for debugging output.
+ */
+#define MAX_CAP_STR 20
+static char cap_str[MAX_CAP_STR][40];
+static DEFINE_SPINLOCK(cap_str_lock);
+static int last_cap_str;
+
+static char *gcap_string(char *s, int c)
+{
+	if (c & CEPH_CAP_GSHARED)
+		*s++ = 's';
+	if (c & CEPH_CAP_GEXCL)
+		*s++ = 'x';
+	if (c & CEPH_CAP_GCACHE)
+		*s++ = 'c';
+	if (c & CEPH_CAP_GRD)
+		*s++ = 'r';
+	if (c & CEPH_CAP_GWR)
+		*s++ = 'w';
+	if (c & CEPH_CAP_GBUFFER)
+		*s++ = 'b';
+	if (c & CEPH_CAP_GLAZYIO)
+		*s++ = 'l';
+	return s;
+}
+
+const char *ceph_cap_string(int caps)
+{
+	int i;
+	char *s;
+	int c;
+
+	spin_lock(&cap_str_lock);
+	i = last_cap_str++;
+	if (last_cap_str == MAX_CAP_STR)
+		last_cap_str = 0;
+	spin_unlock(&cap_str_lock);
+
+	s = cap_str[i];
+
+	if (caps & CEPH_CAP_PIN)
+		*s++ = 'p';
+
+	c = (caps >> CEPH_CAP_SAUTH) & 3;
+	if (c) {
+		*s++ = 'A';
+		s = gcap_string(s, c);
+	}
+
+	c = (caps >> CEPH_CAP_SLINK) & 3;
+	if (c) {
+		*s++ = 'L';
+		s = gcap_string(s, c);
+	}
+
+	c = (caps >> CEPH_CAP_SXATTR) & 3;
+	if (c) {
+		*s++ = 'X';
+		s = gcap_string(s, c);
+	}
+
+	c = caps >> CEPH_CAP_SFILE;
+	if (c) {
+		*s++ = 'F';
+		s = gcap_string(s, c);
+	}
+
+	if (s == cap_str[i])
+		*s++ = '-';
+	*s = 0;
+	return cap_str[i];
+}
+
+/*
+ * Cap reservations
+ *
+ * Maintain a global pool of preallocated struct ceph_caps, referenced
+ * by struct ceph_caps_reservations.  This ensures that we preallocate
+ * memory needed to successfully process an MDS response.  (If an MDS
+ * sends us cap information and we fail to process it, we will have
+ * problems due to the client and MDS being out of sync.)
+ *
+ * Reservations are 'owned' by a ceph_cap_reservation context.
+ */
+static spinlock_t caps_list_lock;
+static struct list_head caps_list;  /* unused (reserved or unreserved) */
+static int caps_total_count;        /* total caps allocated */
+static int caps_use_count;          /* in use */
+static int caps_reserve_count;      /* unused, reserved */
+static int caps_avail_count;        /* unused, unreserved */
+static int caps_min_count;          /* keep at least this many (unreserved) */
+
+void __init ceph_caps_init(void)
+{
+	INIT_LIST_HEAD(&caps_list);
+	spin_lock_init(&caps_list_lock);
+}
+
+void ceph_caps_finalize(void)
+{
+	struct ceph_cap *cap;
+
+	spin_lock(&caps_list_lock);
+	while (!list_empty(&caps_list)) {
+		cap = list_first_entry(&caps_list, struct ceph_cap, caps_item);
+		list_del(&cap->caps_item);
+		kmem_cache_free(ceph_cap_cachep, cap);
+	}
+	caps_total_count = 0;
+	caps_avail_count = 0;
+	caps_use_count = 0;
+	caps_reserve_count = 0;
+	caps_min_count = 0;
+	spin_unlock(&caps_list_lock);
+}
+
+void ceph_adjust_min_caps(int delta)
+{
+	spin_lock(&caps_list_lock);
+	caps_min_count += delta;
+	BUG_ON(caps_min_count < 0);
+	spin_unlock(&caps_list_lock);
+}
+
+int ceph_reserve_caps(struct ceph_cap_reservation *ctx, int need)
+{
+	int i;
+	struct ceph_cap *cap;
+	int have;
+	int alloc = 0;
+	LIST_HEAD(newcaps);
+	int ret = 0;
+
+	dout("reserve caps ctx=%p need=%d\n", ctx, need);
+
+	/* first reserve any caps that are already allocated */
+	spin_lock(&caps_list_lock);
+	if (caps_avail_count >= need)
+		have = need;
+	else
+		have = caps_avail_count;
+	caps_avail_count -= have;
+	caps_reserve_count += have;
+	BUG_ON(caps_total_count != caps_use_count + caps_reserve_count +
+	       caps_avail_count);
+	spin_unlock(&caps_list_lock);
+
+	for (i = have; i < need; i++) {
+		cap = kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS);
+		if (!cap) {
+			ret = -ENOMEM;
+			goto out_alloc_count;
+		}
+		list_add(&cap->caps_item, &newcaps);
+		alloc++;
+	}
+	BUG_ON(have + alloc != need);
+
+	spin_lock(&caps_list_lock);
+	caps_total_count += alloc;
+	caps_reserve_count += alloc;
+	list_splice(&newcaps, &caps_list);
+
+	BUG_ON(caps_total_count != caps_use_count + caps_reserve_count +
+	       caps_avail_count);
+	spin_unlock(&caps_list_lock);
+
+	ctx->count = need;
+	dout("reserve caps ctx=%p %d = %d used + %d resv + %d avail\n",
+	     ctx, caps_total_count, caps_use_count, caps_reserve_count,
+	     caps_avail_count);
+	return 0;
+
+out_alloc_count:
+	/* we didn't manage to reserve as much as we needed */
+	pr_warning("reserve caps ctx=%p ENOMEM need=%d got=%d\n",
+		   ctx, need, have);
+	return ret;
+}
+
+int ceph_unreserve_caps(struct ceph_cap_reservation *ctx)
+{
+	dout("unreserve caps ctx=%p count=%d\n", ctx, ctx->count);
+	if (ctx->count) {
+		spin_lock(&caps_list_lock);
+		BUG_ON(caps_reserve_count < ctx->count);
+		caps_reserve_count -= ctx->count;
+		caps_avail_count += ctx->count;
+		ctx->count = 0;
+		dout("unreserve caps %d = %d used + %d resv + %d avail\n",
+		     caps_total_count, caps_use_count, caps_reserve_count,
+		     caps_avail_count);
+		BUG_ON(caps_total_count != caps_use_count + caps_reserve_count +
+		       caps_avail_count);
+		spin_unlock(&caps_list_lock);
+	}
+	return 0;
+}
+
+static struct ceph_cap *get_cap(struct ceph_cap_reservation *ctx)
+{
+	struct ceph_cap *cap = NULL;
+
+	/* temporary, until we do something about cap import/export */
+	if (!ctx)
+		return kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS);
+
+	spin_lock(&caps_list_lock);
+	dout("get_cap ctx=%p (%d) %d = %d used + %d resv + %d avail\n",
+	     ctx, ctx->count, caps_total_count, caps_use_count,
+	     caps_reserve_count, caps_avail_count);
+	BUG_ON(!ctx->count);
+	BUG_ON(ctx->count > caps_reserve_count);
+	BUG_ON(list_empty(&caps_list));
+
+	ctx->count--;
+	caps_reserve_count--;
+	caps_use_count++;
+
+	cap = list_first_entry(&caps_list, struct ceph_cap, caps_item);
+	list_del(&cap->caps_item);
+
+	BUG_ON(caps_total_count != caps_use_count + caps_reserve_count +
+	       caps_avail_count);
+	spin_unlock(&caps_list_lock);
+	return cap;
+}
+
+void ceph_put_cap(struct ceph_cap *cap)
+{
+	spin_lock(&caps_list_lock);
+	dout("put_cap %p %d = %d used + %d resv + %d avail\n",
+	     cap, caps_total_count, caps_use_count,
+	     caps_reserve_count, caps_avail_count);
+	caps_use_count--;
+	/*
+	 * Keep some preallocated caps around (ceph_min_count), to
+	 * avoid lots of free/alloc churn.
+	 */
+	if (caps_avail_count >= caps_reserve_count + caps_min_count) {
+		caps_total_count--;
+		kmem_cache_free(ceph_cap_cachep, cap);
+	} else {
+		caps_avail_count++;
+		list_add(&cap->caps_item, &caps_list);
+	}
+
+	BUG_ON(caps_total_count != caps_use_count + caps_reserve_count +
+	       caps_avail_count);
+	spin_unlock(&caps_list_lock);
+}
+
+void ceph_reservation_status(struct ceph_client *client,
+			     int *total, int *avail, int *used, int *reserved,
+			     int *min)
+{
+	if (total)
+		*total = caps_total_count;
+	if (avail)
+		*avail = caps_avail_count;
+	if (used)
+		*used = caps_use_count;
+	if (reserved)
+		*reserved = caps_reserve_count;
+	if (min)
+		*min = caps_min_count;
+}
+
+/*
+ * Find ceph_cap for given mds, if any.
+ *
+ * Called with i_lock held.
+ */
+static struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds)
+{
+	struct ceph_cap *cap;
+	struct rb_node *n = ci->i_caps.rb_node;
+
+	while (n) {
+		cap = rb_entry(n, struct ceph_cap, ci_node);
+		if (mds < cap->mds)
+			n = n->rb_left;
+		else if (mds > cap->mds)
+			n = n->rb_right;
+		else
+			return cap;
+	}
+	return NULL;
+}
+
+/*
+ * Return id of any MDS with a cap, preferably FILE_WR|WRBUFFER|EXCL, else
+ * -1.
+ */
+static int __ceph_get_cap_mds(struct ceph_inode_info *ci, u32 *mseq)
+{
+	struct ceph_cap *cap;
+	int mds = -1;
+	struct rb_node *p;
+
+	/* prefer mds with WR|WRBUFFER|EXCL caps */
+	for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+		cap = rb_entry(p, struct ceph_cap, ci_node);
+		mds = cap->mds;
+		if (mseq)
+			*mseq = cap->mseq;
+		if (cap->issued & (CEPH_CAP_FILE_WR |
+				   CEPH_CAP_FILE_BUFFER |
+				   CEPH_CAP_FILE_EXCL))
+			break;
+	}
+	return mds;
+}
+
+int ceph_get_cap_mds(struct inode *inode)
+{
+	int mds;
+	spin_lock(&inode->i_lock);
+	mds = __ceph_get_cap_mds(ceph_inode(inode), NULL);
+	spin_unlock(&inode->i_lock);
+	return mds;
+}
+
+/*
+ * Called under i_lock.
+ */
+static void __insert_cap_node(struct ceph_inode_info *ci,
+			      struct ceph_cap *new)
+{
+	struct rb_node **p = &ci->i_caps.rb_node;
+	struct rb_node *parent = NULL;
+	struct ceph_cap *cap = NULL;
+
+	while (*p) {
+		parent = *p;
+		cap = rb_entry(parent, struct ceph_cap, ci_node);
+		if (new->mds < cap->mds)
+			p = &(*p)->rb_left;
+		else if (new->mds > cap->mds)
+			p = &(*p)->rb_right;
+		else
+			BUG();
+	}
+
+	rb_link_node(&new->ci_node, parent, p);
+	rb_insert_color(&new->ci_node, &ci->i_caps);
+}
+
+/*
+ * (re)set cap hold timeouts, which control the delayed release
+ * of unused caps back to the MDS.  Should be called on cap use.
+ */
+static void __cap_set_timeouts(struct ceph_mds_client *mdsc,
+			       struct ceph_inode_info *ci)
+{
+	struct ceph_mount_args *ma = mdsc->client->mount_args;
+
+	ci->i_hold_caps_min = round_jiffies(jiffies +
+					    ma->caps_wanted_delay_min * HZ);
+	ci->i_hold_caps_max = round_jiffies(jiffies +
+					    ma->caps_wanted_delay_max * HZ);
+	dout("__cap_set_timeouts %p min %lu max %lu\n", &ci->vfs_inode,
+	     ci->i_hold_caps_min - jiffies, ci->i_hold_caps_max - jiffies);
+}
+
+/*
+ * (Re)queue cap at the end of the delayed cap release list.
+ *
+ * If I_FLUSH is set, leave the inode at the front of the list.
+ *
+ * Caller holds i_lock
+ *    -> we take mdsc->cap_delay_lock
+ */
+static void __cap_delay_requeue(struct ceph_mds_client *mdsc,
+				struct ceph_inode_info *ci)
+{
+	__cap_set_timeouts(mdsc, ci);
+	dout("__cap_delay_requeue %p flags %d at %lu\n", &ci->vfs_inode,
+	     ci->i_ceph_flags, ci->i_hold_caps_max);
+	if (!mdsc->stopping) {
+		spin_lock(&mdsc->cap_delay_lock);
+		if (!list_empty(&ci->i_cap_delay_list)) {
+			if (ci->i_ceph_flags & CEPH_I_FLUSH)
+				goto no_change;
+			list_del_init(&ci->i_cap_delay_list);
+		}
+		list_add_tail(&ci->i_cap_delay_list, &mdsc->cap_delay_list);
+no_change:
+		spin_unlock(&mdsc->cap_delay_lock);
+	}
+}
+
+/*
+ * Queue an inode for immediate writeback.  Mark inode with I_FLUSH,
+ * indicating we should send a cap message to flush dirty metadata
+ * asap, and move to the front of the delayed cap list.
+ */
+static void __cap_delay_requeue_front(struct ceph_mds_client *mdsc,
+				      struct ceph_inode_info *ci)
+{
+	dout("__cap_delay_requeue_front %p\n", &ci->vfs_inode);
+	spin_lock(&mdsc->cap_delay_lock);
+	ci->i_ceph_flags |= CEPH_I_FLUSH;
+	if (!list_empty(&ci->i_cap_delay_list))
+		list_del_init(&ci->i_cap_delay_list);
+	list_add(&ci->i_cap_delay_list, &mdsc->cap_delay_list);
+	spin_unlock(&mdsc->cap_delay_lock);
+}
+
+/*
+ * Cancel delayed work on cap.
+ *
+ * Caller must hold i_lock.
+ */
+static void __cap_delay_cancel(struct ceph_mds_client *mdsc,
+			       struct ceph_inode_info *ci)
+{
+	dout("__cap_delay_cancel %p\n", &ci->vfs_inode);
+	if (list_empty(&ci->i_cap_delay_list))
+		return;
+	spin_lock(&mdsc->cap_delay_lock);
+	list_del_init(&ci->i_cap_delay_list);
+	spin_unlock(&mdsc->cap_delay_lock);
+}
+
+/*
+ * Common issue checks for add_cap, handle_cap_grant.
+ */
+static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap,
+			      unsigned issued)
+{
+	unsigned had = __ceph_caps_issued(ci, NULL);
+
+	/*
+	 * Each time we receive FILE_CACHE anew, we increment
+	 * i_rdcache_gen.
+	 */
+	if ((issued & CEPH_CAP_FILE_CACHE) &&
+	    (had & CEPH_CAP_FILE_CACHE) == 0)
+		ci->i_rdcache_gen++;
+
+	/*
+	 * if we are newly issued FILE_SHARED, clear I_COMPLETE; we
+	 * don't know what happened to this directory while we didn't
+	 * have the cap.
+	 */
+	if ((issued & CEPH_CAP_FILE_SHARED) &&
+	    (had & CEPH_CAP_FILE_SHARED) == 0) {
+		ci->i_shared_gen++;
+		if (S_ISDIR(ci->vfs_inode.i_mode)) {
+			dout(" marking %p NOT complete\n", &ci->vfs_inode);
+			ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
+		}
+	}
+}
+
+/*
+ * Add a capability under the given MDS session.
+ *
+ * Caller should hold session snap_rwsem (read) and s_mutex.
+ *
+ * @fmode is the open file mode, if we are opening a file, otherwise
+ * it is < 0.  (This is so we can atomically add the cap and add an
+ * open file reference to it.)
+ */
+int ceph_add_cap(struct inode *inode,
+		 struct ceph_mds_session *session, u64 cap_id,
+		 int fmode, unsigned issued, unsigned wanted,
+		 unsigned seq, unsigned mseq, u64 realmino, int flags,
+		 struct ceph_cap_reservation *caps_reservation)
+{
+	struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_cap *new_cap = NULL;
+	struct ceph_cap *cap;
+	int mds = session->s_mds;
+	int actual_wanted;
+
+	dout("add_cap %p mds%d cap %llx %s seq %d\n", inode,
+	     session->s_mds, cap_id, ceph_cap_string(issued), seq);
+
+	/*
+	 * If we are opening the file, include file mode wanted bits
+	 * in wanted.
+	 */
+	if (fmode >= 0)
+		wanted |= ceph_caps_for_mode(fmode);
+
+retry:
+	spin_lock(&inode->i_lock);
+	cap = __get_cap_for_mds(ci, mds);
+	if (!cap) {
+		if (new_cap) {
+			cap = new_cap;
+			new_cap = NULL;
+		} else {
+			spin_unlock(&inode->i_lock);
+			new_cap = get_cap(caps_reservation);
+			if (new_cap == NULL)
+				return -ENOMEM;
+			goto retry;
+		}
+
+		cap->issued = 0;
+		cap->implemented = 0;
+		cap->mds = mds;
+		cap->mds_wanted = 0;
+
+		cap->ci = ci;
+		__insert_cap_node(ci, cap);
+
+		/* clear out old exporting info?  (i.e. on cap import) */
+		if (ci->i_cap_exporting_mds == mds) {
+			ci->i_cap_exporting_issued = 0;
+			ci->i_cap_exporting_mseq = 0;
+			ci->i_cap_exporting_mds = -1;
+		}
+
+		/* add to session cap list */
+		cap->session = session;
+		spin_lock(&session->s_cap_lock);
+		list_add_tail(&cap->session_caps, &session->s_caps);
+		session->s_nr_caps++;
+		spin_unlock(&session->s_cap_lock);
+	}
+
+	if (!ci->i_snap_realm) {
+		/*
+		 * add this inode to the appropriate snap realm
+		 */
+		struct ceph_snap_realm *realm = ceph_lookup_snap_realm(mdsc,
+							       realmino);
+		if (realm) {
+			ceph_get_snap_realm(mdsc, realm);
+			spin_lock(&realm->inodes_with_caps_lock);
+			ci->i_snap_realm = realm;
+			list_add(&ci->i_snap_realm_item,
+				 &realm->inodes_with_caps);
+			spin_unlock(&realm->inodes_with_caps_lock);
+		} else {
+			pr_err("ceph_add_cap: couldn't find snap realm %llx\n",
+			       realmino);
+		}
+	}
+
+	__check_cap_issue(ci, cap, issued);
+
+	/*
+	 * If we are issued caps we don't want, or the mds' wanted
+	 * value appears to be off, queue a check so we'll release
+	 * later and/or update the mds wanted value.
+	 */
+	actual_wanted = __ceph_caps_wanted(ci);
+	if ((wanted & ~actual_wanted) ||
+	    (issued & ~actual_wanted & CEPH_CAP_ANY_WR)) {
+		dout(" issued %s, mds wanted %s, actual %s, queueing\n",
+		     ceph_cap_string(issued), ceph_cap_string(wanted),
+		     ceph_cap_string(actual_wanted));
+		__cap_delay_requeue(mdsc, ci);
+	}
+
+	if (flags & CEPH_CAP_FLAG_AUTH)
+		ci->i_auth_cap = cap;
+	else if (ci->i_auth_cap == cap)
+		ci->i_auth_cap = NULL;
+
+	dout("add_cap inode %p (%llx.%llx) cap %p %s now %s seq %d mds%d\n",
+	     inode, ceph_vinop(inode), cap, ceph_cap_string(issued),
+	     ceph_cap_string(issued|cap->issued), seq, mds);
+	cap->cap_id = cap_id;
+	cap->issued = issued;
+	cap->implemented |= issued;
+	cap->mds_wanted |= wanted;
+	cap->seq = seq;
+	cap->issue_seq = seq;
+	cap->mseq = mseq;
+	cap->cap_gen = session->s_cap_gen;
+
+	if (fmode >= 0)
+		__ceph_get_fmode(ci, fmode);
+	spin_unlock(&inode->i_lock);
+	wake_up(&ci->i_cap_wq);
+	return 0;
+}
+
+/*
+ * Return true if cap has not timed out and belongs to the current
+ * generation of the MDS session (i.e. has not gone 'stale' due to
+ * us losing touch with the mds).
+ */
+static int __cap_is_valid(struct ceph_cap *cap)
+{
+	unsigned long ttl;
+	u32 gen;
+
+	spin_lock(&cap->session->s_cap_lock);
+	gen = cap->session->s_cap_gen;
+	ttl = cap->session->s_cap_ttl;
+	spin_unlock(&cap->session->s_cap_lock);
+
+	if (cap->cap_gen < gen || time_after_eq(jiffies, ttl)) {
+		dout("__cap_is_valid %p cap %p issued %s "
+		     "but STALE (gen %u vs %u)\n", &cap->ci->vfs_inode,
+		     cap, ceph_cap_string(cap->issued), cap->cap_gen, gen);
+		return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * Return set of valid cap bits issued to us.  Note that caps time
+ * out, and may be invalidated in bulk if the client session times out
+ * and session->s_cap_gen is bumped.
+ */
+int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented)
+{
+	int have = ci->i_snap_caps | ci->i_cap_exporting_issued;
+	struct ceph_cap *cap;
+	struct rb_node *p;
+
+	if (implemented)
+		*implemented = 0;
+	for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+		cap = rb_entry(p, struct ceph_cap, ci_node);
+		if (!__cap_is_valid(cap))
+			continue;
+		dout("__ceph_caps_issued %p cap %p issued %s\n",
+		     &ci->vfs_inode, cap, ceph_cap_string(cap->issued));
+		have |= cap->issued;
+		if (implemented)
+			*implemented |= cap->implemented;
+	}
+	return have;
+}
+
+/*
+ * Get cap bits issued by caps other than @ocap
+ */
+int __ceph_caps_issued_other(struct ceph_inode_info *ci, struct ceph_cap *ocap)
+{
+	int have = ci->i_snap_caps;
+	struct ceph_cap *cap;
+	struct rb_node *p;
+
+	for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+		cap = rb_entry(p, struct ceph_cap, ci_node);
+		if (cap == ocap)
+			continue;
+		if (!__cap_is_valid(cap))
+			continue;
+		have |= cap->issued;
+	}
+	return have;
+}
+
+/*
+ * Move a cap to the end of the LRU (oldest caps at list head, newest
+ * at list tail).
+ */
+static void __touch_cap(struct ceph_cap *cap)
+{
+	struct ceph_mds_session *s = cap->session;
+
+	spin_lock(&s->s_cap_lock);
+	if (s->s_cap_iterator == NULL) {
+		dout("__touch_cap %p cap %p mds%d\n", &cap->ci->vfs_inode, cap,
+		     s->s_mds);
+		list_move_tail(&cap->session_caps, &s->s_caps);
+	} else {
+		dout("__touch_cap %p cap %p mds%d NOP, iterating over caps\n",
+		     &cap->ci->vfs_inode, cap, s->s_mds);
+	}
+	spin_unlock(&s->s_cap_lock);
+}
+
+/*
+ * Check if we hold the given mask.  If so, move the cap(s) to the
+ * front of their respective LRUs.  (This is the preferred way for
+ * callers to check for caps they want.)
+ */
+int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
+{
+	struct ceph_cap *cap;
+	struct rb_node *p;
+	int have = ci->i_snap_caps;
+
+	if ((have & mask) == mask) {
+		dout("__ceph_caps_issued_mask %p snap issued %s"
+		     " (mask %s)\n", &ci->vfs_inode,
+		     ceph_cap_string(have),
+		     ceph_cap_string(mask));
+		return 1;
+	}
+
+	for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+		cap = rb_entry(p, struct ceph_cap, ci_node);
+		if (!__cap_is_valid(cap))
+			continue;
+		if ((cap->issued & mask) == mask) {
+			dout("__ceph_caps_issued_mask %p cap %p issued %s"
+			     " (mask %s)\n", &ci->vfs_inode, cap,
+			     ceph_cap_string(cap->issued),
+			     ceph_cap_string(mask));
+			if (touch)
+				__touch_cap(cap);
+			return 1;
+		}
+
+		/* does a combination of caps satisfy mask? */
+		have |= cap->issued;
+		if ((have & mask) == mask) {
+			dout("__ceph_caps_issued_mask %p combo issued %s"
+			     " (mask %s)\n", &ci->vfs_inode,
+			     ceph_cap_string(cap->issued),
+			     ceph_cap_string(mask));
+			if (touch) {
+				struct rb_node *q;
+
+				/* touch this + preceeding caps */
+				__touch_cap(cap);
+				for (q = rb_first(&ci->i_caps); q != p;
+				     q = rb_next(q)) {
+					cap = rb_entry(q, struct ceph_cap,
+						       ci_node);
+					if (!__cap_is_valid(cap))
+						continue;
+					__touch_cap(cap);
+				}
+			}
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Return true if mask caps are currently being revoked by an MDS.
+ */
+int ceph_caps_revoking(struct ceph_inode_info *ci, int mask)
+{
+	struct inode *inode = &ci->vfs_inode;
+	struct ceph_cap *cap;
+	struct rb_node *p;
+	int ret = 0;
+
+	spin_lock(&inode->i_lock);
+	for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+		cap = rb_entry(p, struct ceph_cap, ci_node);
+		if (__cap_is_valid(cap) &&
+		    (cap->implemented & ~cap->issued & mask)) {
+			ret = 1;
+			break;
+		}
+	}
+	spin_unlock(&inode->i_lock);
+	dout("ceph_caps_revoking %p %s = %d\n", inode,
+	     ceph_cap_string(mask), ret);
+	return ret;
+}
+
+int __ceph_caps_used(struct ceph_inode_info *ci)
+{
+	int used = 0;
+	if (ci->i_pin_ref)
+		used |= CEPH_CAP_PIN;
+	if (ci->i_rd_ref)
+		used |= CEPH_CAP_FILE_RD;
+	if (ci->i_rdcache_ref || ci->i_rdcache_gen)
+		used |= CEPH_CAP_FILE_CACHE;
+	if (ci->i_wr_ref)
+		used |= CEPH_CAP_FILE_WR;
+	if (ci->i_wrbuffer_ref)
+		used |= CEPH_CAP_FILE_BUFFER;
+	return used;
+}
+
+/*
+ * wanted, by virtue of open file modes
+ */
+int __ceph_caps_file_wanted(struct ceph_inode_info *ci)
+{
+	int want = 0;
+	int mode;
+	for (mode = 0; mode < 4; mode++)
+		if (ci->i_nr_by_mode[mode])
+			want |= ceph_caps_for_mode(mode);
+	return want;
+}
+
+/*
+ * Return caps we have registered with the MDS(s) as 'wanted'.
+ */
+int __ceph_caps_mds_wanted(struct ceph_inode_info *ci)
+{
+	struct ceph_cap *cap;
+	struct rb_node *p;
+	int mds_wanted = 0;
+
+	for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+		cap = rb_entry(p, struct ceph_cap, ci_node);
+		if (!__cap_is_valid(cap))
+			continue;
+		mds_wanted |= cap->mds_wanted;
+	}
+	return mds_wanted;
+}
+
+/*
+ * called under i_lock
+ */
+static int __ceph_is_any_caps(struct ceph_inode_info *ci)
+{
+	return !RB_EMPTY_ROOT(&ci->i_caps) || ci->i_cap_exporting_mds >= 0;
+}
+
+/*
+ * Remove a cap.  Take steps to deal with a racing iterate_session_caps.
+ *
+ * caller should hold i_lock.
+ * caller will not hold session s_mutex if called from destroy_inode.
+ */
+void __ceph_remove_cap(struct ceph_cap *cap)
+{
+	struct ceph_mds_session *session = cap->session;
+	struct ceph_inode_info *ci = cap->ci;
+	struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc;
+	int removed = 0;
+
+	dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode);
+
+	/* remove from session list */
+	spin_lock(&session->s_cap_lock);
+	if (session->s_cap_iterator == cap) {
+		/* not yet, we are iterating over this very cap */
+		dout("__ceph_remove_cap  delaying %p removal from session %p\n",
+		     cap, cap->session);
+	} else {
+		list_del_init(&cap->session_caps);
+		session->s_nr_caps--;
+		cap->session = NULL;
+		removed = 1;
+	}
+	/* protect backpointer with s_cap_lock: see iterate_session_caps */
+	cap->ci = NULL;
+	spin_unlock(&session->s_cap_lock);
+
+	/* remove from inode list */
+	rb_erase(&cap->ci_node, &ci->i_caps);
+	if (ci->i_auth_cap == cap)
+		ci->i_auth_cap = NULL;
+
+	if (removed)
+		ceph_put_cap(cap);
+
+	if (!__ceph_is_any_caps(ci) && ci->i_snap_realm) {
+		struct ceph_snap_realm *realm = ci->i_snap_realm;
+		spin_lock(&realm->inodes_with_caps_lock);
+		list_del_init(&ci->i_snap_realm_item);
+		ci->i_snap_realm_counter++;
+		ci->i_snap_realm = NULL;
+		spin_unlock(&realm->inodes_with_caps_lock);
+		ceph_put_snap_realm(mdsc, realm);
+	}
+	if (!__ceph_is_any_real_caps(ci))
+		__cap_delay_cancel(mdsc, ci);
+}
+
+/*
+ * Build and send a cap message to the given MDS.
+ *
+ * Caller should be holding s_mutex.
+ */
+static int send_cap_msg(struct ceph_mds_session *session,
+			u64 ino, u64 cid, int op,
+			int caps, int wanted, int dirty,
+			u32 seq, u64 flush_tid, u32 issue_seq, u32 mseq,
+			u64 size, u64 max_size,
+			struct timespec *mtime, struct timespec *atime,
+			u64 time_warp_seq,
+			uid_t uid, gid_t gid, mode_t mode,
+			u64 xattr_version,
+			struct ceph_buffer *xattrs_buf,
+			u64 follows)
+{
+	struct ceph_mds_caps *fc;
+	struct ceph_msg *msg;
+
+	dout("send_cap_msg %s %llx %llx caps %s wanted %s dirty %s"
+	     " seq %u/%u mseq %u follows %lld size %llu/%llu"
+	     " xattr_ver %llu xattr_len %d\n", ceph_cap_op_name(op),
+	     cid, ino, ceph_cap_string(caps), ceph_cap_string(wanted),
+	     ceph_cap_string(dirty),
+	     seq, issue_seq, mseq, follows, size, max_size,
+	     xattr_version, xattrs_buf ? (int)xattrs_buf->vec.iov_len : 0);
+
+	msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, sizeof(*fc), 0, 0, NULL);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
+
+	msg->hdr.tid = cpu_to_le64(flush_tid);
+
+	fc = msg->front.iov_base;
+	memset(fc, 0, sizeof(*fc));
+
+	fc->cap_id = cpu_to_le64(cid);
+	fc->op = cpu_to_le32(op);
+	fc->seq = cpu_to_le32(seq);
+	fc->issue_seq = cpu_to_le32(issue_seq);
+	fc->migrate_seq = cpu_to_le32(mseq);
+	fc->caps = cpu_to_le32(caps);
+	fc->wanted = cpu_to_le32(wanted);
+	fc->dirty = cpu_to_le32(dirty);
+	fc->ino = cpu_to_le64(ino);
+	fc->snap_follows = cpu_to_le64(follows);
+
+	fc->size = cpu_to_le64(size);
+	fc->max_size = cpu_to_le64(max_size);
+	if (mtime)
+		ceph_encode_timespec(&fc->mtime, mtime);
+	if (atime)
+		ceph_encode_timespec(&fc->atime, atime);
+	fc->time_warp_seq = cpu_to_le32(time_warp_seq);
+
+	fc->uid = cpu_to_le32(uid);
+	fc->gid = cpu_to_le32(gid);
+	fc->mode = cpu_to_le32(mode);
+
+	fc->xattr_version = cpu_to_le64(xattr_version);
+	if (xattrs_buf) {
+		msg->middle = ceph_buffer_get(xattrs_buf);
+		fc->xattr_len = cpu_to_le32(xattrs_buf->vec.iov_len);
+		msg->hdr.middle_len = cpu_to_le32(xattrs_buf->vec.iov_len);
+	}
+
+	ceph_con_send(&session->s_con, msg);
+	return 0;
+}
+
+/*
+ * Queue cap releases when an inode is dropped from our cache.  Since
+ * inode is about to be destroyed, there is no need for i_lock.
+ */
+void ceph_queue_caps_release(struct inode *inode)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct rb_node *p;
+
+	p = rb_first(&ci->i_caps);
+	while (p) {
+		struct ceph_cap *cap = rb_entry(p, struct ceph_cap, ci_node);
+		struct ceph_mds_session *session = cap->session;
+		struct ceph_msg *msg;
+		struct ceph_mds_cap_release *head;
+		struct ceph_mds_cap_item *item;
+
+		spin_lock(&session->s_cap_lock);
+		BUG_ON(!session->s_num_cap_releases);
+		msg = list_first_entry(&session->s_cap_releases,
+				       struct ceph_msg, list_head);
+
+		dout(" adding %p release to mds%d msg %p (%d left)\n",
+		     inode, session->s_mds, msg, session->s_num_cap_releases);
+
+		BUG_ON(msg->front.iov_len + sizeof(*item) > PAGE_CACHE_SIZE);
+		head = msg->front.iov_base;
+		head->num = cpu_to_le32(le32_to_cpu(head->num) + 1);
+		item = msg->front.iov_base + msg->front.iov_len;
+		item->ino = cpu_to_le64(ceph_ino(inode));
+		item->cap_id = cpu_to_le64(cap->cap_id);
+		item->migrate_seq = cpu_to_le32(cap->mseq);
+		item->seq = cpu_to_le32(cap->issue_seq);
+
+		session->s_num_cap_releases--;
+
+		msg->front.iov_len += sizeof(*item);
+		if (le32_to_cpu(head->num) == CEPH_CAPS_PER_RELEASE) {
+			dout(" release msg %p full\n", msg);
+			list_move_tail(&msg->list_head,
+				       &session->s_cap_releases_done);
+		} else {
+			dout(" release msg %p at %d/%d (%d)\n", msg,
+			     (int)le32_to_cpu(head->num),
+			     (int)CEPH_CAPS_PER_RELEASE,
+			     (int)msg->front.iov_len);
+		}
+		spin_unlock(&session->s_cap_lock);
+		p = rb_next(p);
+		__ceph_remove_cap(cap);
+	}
+}
+
+/*
+ * Send a cap msg on the given inode.  Update our caps state, then
+ * drop i_lock and send the message.
+ *
+ * Make note of max_size reported/requested from mds, revoked caps
+ * that have now been implemented.
+ *
+ * Make half-hearted attempt ot to invalidate page cache if we are
+ * dropping RDCACHE.  Note that this will leave behind locked pages
+ * that we'll then need to deal with elsewhere.
+ *
+ * Return non-zero if delayed release, or we experienced an error
+ * such that the caller should requeue + retry later.
+ *
+ * called with i_lock, then drops it.
+ * caller should hold snap_rwsem (read), s_mutex.
+ */
+static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
+		      int op, int used, int want, int retain, int flushing,
+		      unsigned *pflush_tid)
+	__releases(cap->ci->vfs_inode->i_lock)
+{
+	struct ceph_inode_info *ci = cap->ci;
+	struct inode *inode = &ci->vfs_inode;
+	u64 cap_id = cap->cap_id;
+	int held, revoking, dropping, keep;
+	u64 seq, issue_seq, mseq, time_warp_seq, follows;
+	u64 size, max_size;
+	struct timespec mtime, atime;
+	int wake = 0;
+	mode_t mode;
+	uid_t uid;
+	gid_t gid;
+	struct ceph_mds_session *session;
+	u64 xattr_version = 0;
+	int delayed = 0;
+	u64 flush_tid = 0;
+	int i;
+	int ret;
+
+	held = cap->issued | cap->implemented;
+	revoking = cap->implemented & ~cap->issued;
+	retain &= ~revoking;
+	dropping = cap->issued & ~retain;
+
+	dout("__send_cap %p cap %p session %p %s -> %s (revoking %s)\n",
+	     inode, cap, cap->session,
+	     ceph_cap_string(held), ceph_cap_string(held & retain),
+	     ceph_cap_string(revoking));
+	BUG_ON((retain & CEPH_CAP_PIN) == 0);
+
+	session = cap->session;
+
+	/* don't release wanted unless we've waited a bit. */
+	if ((ci->i_ceph_flags & CEPH_I_NODELAY) == 0 &&
+	    time_before(jiffies, ci->i_hold_caps_min)) {
+		dout(" delaying issued %s -> %s, wanted %s -> %s on send\n",
+		     ceph_cap_string(cap->issued),
+		     ceph_cap_string(cap->issued & retain),
+		     ceph_cap_string(cap->mds_wanted),
+		     ceph_cap_string(want));
+		want |= cap->mds_wanted;
+		retain |= cap->issued;
+		delayed = 1;
+	}
+	ci->i_ceph_flags &= ~(CEPH_I_NODELAY | CEPH_I_FLUSH);
+
+	cap->issued &= retain;  /* drop bits we don't want */
+	if (cap->implemented & ~cap->issued) {
+		/*
+		 * Wake up any waiters on wanted -> needed transition.
+		 * This is due to the weird transition from buffered
+		 * to sync IO... we need to flush dirty pages _before_
+		 * allowing sync writes to avoid reordering.
+		 */
+		wake = 1;
+	}
+	cap->implemented &= cap->issued | used;
+	cap->mds_wanted = want;
+
+	if (flushing) {
+		/*
+		 * assign a tid for flush operations so we can avoid
+		 * flush1 -> dirty1 -> flush2 -> flushack1 -> mark
+		 * clean type races.  track latest tid for every bit
+		 * so we can handle flush AxFw, flush Fw, and have the
+		 * first ack clean Ax.
+		 */
+		flush_tid = ++ci->i_cap_flush_last_tid;
+		if (pflush_tid)
+			*pflush_tid = flush_tid;
+		dout(" cap_flush_tid %d\n", (int)flush_tid);
+		for (i = 0; i < CEPH_CAP_BITS; i++)
+			if (flushing & (1 << i))
+				ci->i_cap_flush_tid[i] = flush_tid;
+	}
+
+	keep = cap->implemented;
+	seq = cap->seq;
+	issue_seq = cap->issue_seq;
+	mseq = cap->mseq;
+	size = inode->i_size;
+	ci->i_reported_size = size;
+	max_size = ci->i_wanted_max_size;
+	ci->i_requested_max_size = max_size;
+	mtime = inode->i_mtime;
+	atime = inode->i_atime;
+	time_warp_seq = ci->i_time_warp_seq;
+	follows = ci->i_snap_realm->cached_context->seq;
+	uid = inode->i_uid;
+	gid = inode->i_gid;
+	mode = inode->i_mode;
+
+	if (dropping & CEPH_CAP_XATTR_EXCL) {
+		__ceph_build_xattrs_blob(ci);
+		xattr_version = ci->i_xattrs.version + 1;
+	}
+
+	spin_unlock(&inode->i_lock);
+
+	ret = send_cap_msg(session, ceph_vino(inode).ino, cap_id,
+		op, keep, want, flushing, seq, flush_tid, issue_seq, mseq,
+		size, max_size, &mtime, &atime, time_warp_seq,
+		uid, gid, mode,
+		xattr_version,
+		(flushing & CEPH_CAP_XATTR_EXCL) ? ci->i_xattrs.blob : NULL,
+		follows);
+	if (ret < 0) {
+		dout("error sending cap msg, must requeue %p\n", inode);
+		delayed = 1;
+	}
+
+	if (wake)
+		wake_up(&ci->i_cap_wq);
+
+	return delayed;
+}
+
+/*
+ * When a snapshot is taken, clients accumulate dirty metadata on
+ * inodes with capabilities in ceph_cap_snaps to describe the file
+ * state at the time the snapshot was taken.  This must be flushed
+ * asynchronously back to the MDS once sync writes complete and dirty
+ * data is written out.
+ *
+ * Called under i_lock.  Takes s_mutex as needed.
+ */
+void __ceph_flush_snaps(struct ceph_inode_info *ci,
+			struct ceph_mds_session **psession)
+{
+	struct inode *inode = &ci->vfs_inode;
+	int mds;
+	struct ceph_cap_snap *capsnap;
+	u32 mseq;
+	struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc;
+	struct ceph_mds_session *session = NULL; /* if session != NULL, we hold
+						    session->s_mutex */
+	u64 next_follows = 0;  /* keep track of how far we've gotten through the
+			     i_cap_snaps list, and skip these entries next time
+			     around to avoid an infinite loop */
+
+	if (psession)
+		session = *psession;
+
+	dout("__flush_snaps %p\n", inode);
+retry:
+	list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
+		/* avoid an infiniute loop after retry */
+		if (capsnap->follows < next_follows)
+			continue;
+		/*
+		 * we need to wait for sync writes to complete and for dirty
+		 * pages to be written out.
+		 */
+		if (capsnap->dirty_pages || capsnap->writing)
+			continue;
+
+		/*
+		 * if cap writeback already occurred, we should have dropped
+		 * the capsnap in ceph_put_wrbuffer_cap_refs.
+		 */
+		BUG_ON(capsnap->dirty == 0);
+
+		/* pick mds, take s_mutex */
+		mds = __ceph_get_cap_mds(ci, &mseq);
+		if (session && session->s_mds != mds) {
+			dout("oops, wrong session %p mutex\n", session);
+			mutex_unlock(&session->s_mutex);
+			ceph_put_mds_session(session);
+			session = NULL;
+		}
+		if (!session) {
+			spin_unlock(&inode->i_lock);
+			mutex_lock(&mdsc->mutex);
+			session = __ceph_lookup_mds_session(mdsc, mds);
+			mutex_unlock(&mdsc->mutex);
+			if (session) {
+				dout("inverting session/ino locks on %p\n",
+				     session);
+				mutex_lock(&session->s_mutex);
+			}
+			/*
+			 * if session == NULL, we raced against a cap
+			 * deletion.  retry, and we'll get a better
+			 * @mds value next time.
+			 */
+			spin_lock(&inode->i_lock);
+			goto retry;
+		}
+
+		capsnap->flush_tid = ++ci->i_cap_flush_last_tid;
+		atomic_inc(&capsnap->nref);
+		if (!list_empty(&capsnap->flushing_item))
+			list_del_init(&capsnap->flushing_item);
+		list_add_tail(&capsnap->flushing_item,
+			      &session->s_cap_snaps_flushing);
+		spin_unlock(&inode->i_lock);
+
+		dout("flush_snaps %p cap_snap %p follows %lld size %llu\n",
+		     inode, capsnap, next_follows, capsnap->size);
+		send_cap_msg(session, ceph_vino(inode).ino, 0,
+			     CEPH_CAP_OP_FLUSHSNAP, capsnap->issued, 0,
+			     capsnap->dirty, 0, capsnap->flush_tid, 0, mseq,
+			     capsnap->size, 0,
+			     &capsnap->mtime, &capsnap->atime,
+			     capsnap->time_warp_seq,
+			     capsnap->uid, capsnap->gid, capsnap->mode,
+			     0, NULL,
+			     capsnap->follows);
+
+		next_follows = capsnap->follows + 1;
+		ceph_put_cap_snap(capsnap);
+
+		spin_lock(&inode->i_lock);
+		goto retry;
+	}
+
+	/* we flushed them all; remove this inode from the queue */
+	spin_lock(&mdsc->snap_flush_lock);
+	list_del_init(&ci->i_snap_flush_item);
+	spin_unlock(&mdsc->snap_flush_lock);
+
+	if (psession)
+		*psession = session;
+	else if (session) {
+		mutex_unlock(&session->s_mutex);
+		ceph_put_mds_session(session);
+	}
+}
+
+static void ceph_flush_snaps(struct ceph_inode_info *ci)
+{
+	struct inode *inode = &ci->vfs_inode;
+
+	spin_lock(&inode->i_lock);
+	__ceph_flush_snaps(ci, NULL);
+	spin_unlock(&inode->i_lock);
+}
+
+/*
+ * Mark caps dirty.  If inode is newly dirty, add to the global dirty
+ * list.
+ */
+void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
+{
+	struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc;
+	struct inode *inode = &ci->vfs_inode;
+	int was = ci->i_dirty_caps;
+	int dirty = 0;
+
+	dout("__mark_dirty_caps %p %s dirty %s -> %s\n", &ci->vfs_inode,
+	     ceph_cap_string(mask), ceph_cap_string(was),
+	     ceph_cap_string(was | mask));
+	ci->i_dirty_caps |= mask;
+	if (was == 0) {
+		dout(" inode %p now dirty\n", &ci->vfs_inode);
+		BUG_ON(!list_empty(&ci->i_dirty_item));
+		spin_lock(&mdsc->cap_dirty_lock);
+		list_add(&ci->i_dirty_item, &mdsc->cap_dirty);
+		spin_unlock(&mdsc->cap_dirty_lock);
+		if (ci->i_flushing_caps == 0) {
+			igrab(inode);
+			dirty |= I_DIRTY_SYNC;
+		}
+	}
+	BUG_ON(list_empty(&ci->i_dirty_item));
+	if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) &&
+	    (mask & CEPH_CAP_FILE_BUFFER))
+		dirty |= I_DIRTY_DATASYNC;
+	if (dirty)
+		__mark_inode_dirty(inode, dirty);
+	__cap_delay_requeue(mdsc, ci);
+}
+
+/*
+ * Add dirty inode to the flushing list.  Assigned a seq number so we
+ * can wait for caps to flush without starving.
+ *
+ * Called under i_lock.
+ */
+static int __mark_caps_flushing(struct inode *inode,
+				 struct ceph_mds_session *session)
+{
+	struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int flushing;
+
+	BUG_ON(ci->i_dirty_caps == 0);
+	BUG_ON(list_empty(&ci->i_dirty_item));
+
+	flushing = ci->i_dirty_caps;
+	dout("__mark_caps_flushing flushing %s, flushing_caps %s -> %s\n",
+	     ceph_cap_string(flushing),
+	     ceph_cap_string(ci->i_flushing_caps),
+	     ceph_cap_string(ci->i_flushing_caps | flushing));
+	ci->i_flushing_caps |= flushing;
+	ci->i_dirty_caps = 0;
+	dout(" inode %p now !dirty\n", inode);
+
+	spin_lock(&mdsc->cap_dirty_lock);
+	list_del_init(&ci->i_dirty_item);
+
+	ci->i_cap_flush_seq = ++mdsc->cap_flush_seq;
+	if (list_empty(&ci->i_flushing_item)) {
+		list_add_tail(&ci->i_flushing_item, &session->s_cap_flushing);
+		mdsc->num_cap_flushing++;
+		dout(" inode %p now flushing seq %lld\n", inode,
+		     ci->i_cap_flush_seq);
+	} else {
+		list_move_tail(&ci->i_flushing_item, &session->s_cap_flushing);
+		dout(" inode %p now flushing (more) seq %lld\n", inode,
+		     ci->i_cap_flush_seq);
+	}
+	spin_unlock(&mdsc->cap_dirty_lock);
+
+	return flushing;
+}
+
+/*
+ * try to invalidate mapping pages without blocking.
+ */
+static int mapping_is_empty(struct address_space *mapping)
+{
+	struct page *page = find_get_page(mapping, 0);
+
+	if (!page)
+		return 1;
+
+	put_page(page);
+	return 0;
+}
+
+static int try_nonblocking_invalidate(struct inode *inode)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	u32 invalidating_gen = ci->i_rdcache_gen;
+
+	spin_unlock(&inode->i_lock);
+	invalidate_mapping_pages(&inode->i_data, 0, -1);
+	spin_lock(&inode->i_lock);
+
+	if (mapping_is_empty(&inode->i_data) &&
+	    invalidating_gen == ci->i_rdcache_gen) {
+		/* success. */
+		dout("try_nonblocking_invalidate %p success\n", inode);
+		ci->i_rdcache_gen = 0;
+		ci->i_rdcache_revoking = 0;
+		return 0;
+	}
+	dout("try_nonblocking_invalidate %p failed\n", inode);
+	return -1;
+}
+
+/*
+ * Swiss army knife function to examine currently used and wanted
+ * versus held caps.  Release, flush, ack revoked caps to mds as
+ * appropriate.
+ *
+ *  CHECK_CAPS_NODELAY - caller is delayed work and we should not delay
+ *    cap release further.
+ *  CHECK_CAPS_AUTHONLY - we should only check the auth cap
+ *  CHECK_CAPS_FLUSH - we should flush any dirty caps immediately, without
+ *    further delay.
+ */
+void ceph_check_caps(struct ceph_inode_info *ci, int flags,
+		     struct ceph_mds_session *session)
+	__releases(session->s_mutex)
+{
+	struct ceph_client *client = ceph_inode_to_client(&ci->vfs_inode);
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct inode *inode = &ci->vfs_inode;
+	struct ceph_cap *cap;
+	int file_wanted, used;
+	int took_snap_rwsem = 0;             /* true if mdsc->snap_rwsem held */
+	int issued, implemented, want, retain, revoking, flushing = 0;
+	int mds = -1;   /* keep track of how far we've gone through i_caps list
+			   to avoid an infinite loop on retry */
+	struct rb_node *p;
+	int tried_invalidate = 0;
+	int delayed = 0, sent = 0, force_requeue = 0, num;
+	int queue_invalidate = 0;
+	int is_delayed = flags & CHECK_CAPS_NODELAY;
+
+	/* if we are unmounting, flush any unused caps immediately. */
+	if (mdsc->stopping)
+		is_delayed = 1;
+
+	spin_lock(&inode->i_lock);
+
+	if (ci->i_ceph_flags & CEPH_I_FLUSH)
+		flags |= CHECK_CAPS_FLUSH;
+
+	/* flush snaps first time around only */
+	if (!list_empty(&ci->i_cap_snaps))
+		__ceph_flush_snaps(ci, &session);
+	goto retry_locked;
+retry:
+	spin_lock(&inode->i_lock);
+retry_locked:
+	file_wanted = __ceph_caps_file_wanted(ci);
+	used = __ceph_caps_used(ci);
+	want = file_wanted | used;
+	issued = __ceph_caps_issued(ci, &implemented);
+	revoking = implemented & ~issued;
+
+	retain = want | CEPH_CAP_PIN;
+	if (!mdsc->stopping && inode->i_nlink > 0) {
+		if (want) {
+			retain |= CEPH_CAP_ANY;       /* be greedy */
+		} else {
+			retain |= CEPH_CAP_ANY_SHARED;
+			/*
+			 * keep RD only if we didn't have the file open RW,
+			 * because then the mds would revoke it anyway to
+			 * journal max_size=0.
+			 */
+			if (ci->i_max_size == 0)
+				retain |= CEPH_CAP_ANY_RD;
+		}
+	}
+
+	dout("check_caps %p file_want %s used %s dirty %s flushing %s"
+	     " issued %s revoking %s retain %s %s%s%s\n", inode,
+	     ceph_cap_string(file_wanted),
+	     ceph_cap_string(used), ceph_cap_string(ci->i_dirty_caps),
+	     ceph_cap_string(ci->i_flushing_caps),
+	     ceph_cap_string(issued), ceph_cap_string(revoking),
+	     ceph_cap_string(retain),
+	     (flags & CHECK_CAPS_AUTHONLY) ? " AUTHONLY" : "",
+	     (flags & CHECK_CAPS_NODELAY) ? " NODELAY" : "",
+	     (flags & CHECK_CAPS_FLUSH) ? " FLUSH" : "");
+
+	/*
+	 * If we no longer need to hold onto old our caps, and we may
+	 * have cached pages, but don't want them, then try to invalidate.
+	 * If we fail, it's because pages are locked.... try again later.
+	 */
+	if ((!is_delayed || mdsc->stopping) &&
+	    ci->i_wrbuffer_ref == 0 &&               /* no dirty pages... */
+	    ci->i_rdcache_gen &&                     /* may have cached pages */
+	    (file_wanted == 0 ||                     /* no open files */
+	     (revoking & CEPH_CAP_FILE_CACHE)) &&     /*  or revoking cache */
+	    !tried_invalidate) {
+		dout("check_caps trying to invalidate on %p\n", inode);
+		if (try_nonblocking_invalidate(inode) < 0) {
+			if (revoking & CEPH_CAP_FILE_CACHE) {
+				dout("check_caps queuing invalidate\n");
+				queue_invalidate = 1;
+				ci->i_rdcache_revoking = ci->i_rdcache_gen;
+			} else {
+				dout("check_caps failed to invalidate pages\n");
+				/* we failed to invalidate pages.  check these
+				   caps again later. */
+				force_requeue = 1;
+				__cap_set_timeouts(mdsc, ci);
+			}
+		}
+		tried_invalidate = 1;
+		goto retry_locked;
+	}
+
+	num = 0;
+	for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+		cap = rb_entry(p, struct ceph_cap, ci_node);
+		num++;
+
+		/* avoid looping forever */
+		if (mds >= cap->mds ||
+		    ((flags & CHECK_CAPS_AUTHONLY) && cap != ci->i_auth_cap))
+			continue;
+
+		/* NOTE: no side-effects allowed, until we take s_mutex */
+
+		revoking = cap->implemented & ~cap->issued;
+		if (revoking)
+			dout(" mds%d revoking %s\n", cap->mds,
+			     ceph_cap_string(revoking));
+
+		if (cap == ci->i_auth_cap &&
+		    (cap->issued & CEPH_CAP_FILE_WR)) {
+			/* request larger max_size from MDS? */
+			if (ci->i_wanted_max_size > ci->i_max_size &&
+			    ci->i_wanted_max_size > ci->i_requested_max_size) {
+				dout("requesting new max_size\n");
+				goto ack;
+			}
+
+			/* approaching file_max? */
+			if ((inode->i_size << 1) >= ci->i_max_size &&
+			    (ci->i_reported_size << 1) < ci->i_max_size) {
+				dout("i_size approaching max_size\n");
+				goto ack;
+			}
+		}
+		/* flush anything dirty? */
+		if (cap == ci->i_auth_cap && (flags & CHECK_CAPS_FLUSH) &&
+		    ci->i_dirty_caps) {
+			dout("flushing dirty caps\n");
+			goto ack;
+		}
+
+		/* completed revocation? going down and there are no caps? */
+		if (revoking && (revoking & used) == 0) {
+			dout("completed revocation of %s\n",
+			     ceph_cap_string(cap->implemented & ~cap->issued));
+			goto ack;
+		}
+
+		/* want more caps from mds? */
+		if (want & ~(cap->mds_wanted | cap->issued))
+			goto ack;
+
+		/* things we might delay */
+		if ((cap->issued & ~retain) == 0 &&
+		    cap->mds_wanted == want)
+			continue;     /* nope, all good */
+
+		if (is_delayed)
+			goto ack;
+
+		/* delay? */
+		if ((ci->i_ceph_flags & CEPH_I_NODELAY) == 0 &&
+		    time_before(jiffies, ci->i_hold_caps_max)) {
+			dout(" delaying issued %s -> %s, wanted %s -> %s\n",
+			     ceph_cap_string(cap->issued),
+			     ceph_cap_string(cap->issued & retain),
+			     ceph_cap_string(cap->mds_wanted),
+			     ceph_cap_string(want));
+			delayed++;
+			continue;
+		}
+
+ack:
+		if (ci->i_ceph_flags & CEPH_I_NOFLUSH) {
+			dout(" skipping %p I_NOFLUSH set\n", inode);
+			continue;
+		}
+
+		if (session && session != cap->session) {
+			dout("oops, wrong session %p mutex\n", session);
+			mutex_unlock(&session->s_mutex);
+			session = NULL;
+		}
+		if (!session) {
+			session = cap->session;
+			if (mutex_trylock(&session->s_mutex) == 0) {
+				dout("inverting session/ino locks on %p\n",
+				     session);
+				spin_unlock(&inode->i_lock);
+				if (took_snap_rwsem) {
+					up_read(&mdsc->snap_rwsem);
+					took_snap_rwsem = 0;
+				}
+				mutex_lock(&session->s_mutex);
+				goto retry;
+			}
+		}
+		/* take snap_rwsem after session mutex */
+		if (!took_snap_rwsem) {
+			if (down_read_trylock(&mdsc->snap_rwsem) == 0) {
+				dout("inverting snap/in locks on %p\n",
+				     inode);
+				spin_unlock(&inode->i_lock);
+				down_read(&mdsc->snap_rwsem);
+				took_snap_rwsem = 1;
+				goto retry;
+			}
+			took_snap_rwsem = 1;
+		}
+
+		if (cap == ci->i_auth_cap && ci->i_dirty_caps)
+			flushing = __mark_caps_flushing(inode, session);
+
+		mds = cap->mds;  /* remember mds, so we don't repeat */
+		sent++;
+
+		/* __send_cap drops i_lock */
+		delayed += __send_cap(mdsc, cap, CEPH_CAP_OP_UPDATE, used, want,
+				      retain, flushing, NULL);
+		goto retry; /* retake i_lock and restart our cap scan. */
+	}
+
+	/*
+	 * Reschedule delayed caps release if we delayed anything,
+	 * otherwise cancel.
+	 */
+	if (delayed && is_delayed)
+		force_requeue = 1;   /* __send_cap delayed release; requeue */
+	if (!delayed && !is_delayed)
+		__cap_delay_cancel(mdsc, ci);
+	else if (!is_delayed || force_requeue)
+		__cap_delay_requeue(mdsc, ci);
+
+	spin_unlock(&inode->i_lock);
+
+	if (queue_invalidate)
+		ceph_queue_invalidate(inode);
+
+	if (session)
+		mutex_unlock(&session->s_mutex);
+	if (took_snap_rwsem)
+		up_read(&mdsc->snap_rwsem);
+}
+
+/*
+ * Try to flush dirty caps back to the auth mds.
+ */
+static int try_flush_caps(struct inode *inode, struct ceph_mds_session *session,
+			  unsigned *flush_tid)
+{
+	struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int unlock_session = session ? 0 : 1;
+	int flushing = 0;
+
+retry:
+	spin_lock(&inode->i_lock);
+	if (ci->i_ceph_flags & CEPH_I_NOFLUSH) {
+		dout("try_flush_caps skipping %p I_NOFLUSH set\n", inode);
+		goto out;
+	}
+	if (ci->i_dirty_caps && ci->i_auth_cap) {
+		struct ceph_cap *cap = ci->i_auth_cap;
+		int used = __ceph_caps_used(ci);
+		int want = __ceph_caps_wanted(ci);
+		int delayed;
+
+		if (!session) {
+			spin_unlock(&inode->i_lock);
+			session = cap->session;
+			mutex_lock(&session->s_mutex);
+			goto retry;
+		}
+		BUG_ON(session != cap->session);
+		if (cap->session->s_state < CEPH_MDS_SESSION_OPEN)
+			goto out;
+
+		flushing = __mark_caps_flushing(inode, session);
+
+		/* __send_cap drops i_lock */
+		delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, used, want,
+				     cap->issued | cap->implemented, flushing,
+				     flush_tid);
+		if (!delayed)
+			goto out_unlocked;
+
+		spin_lock(&inode->i_lock);
+		__cap_delay_requeue(mdsc, ci);
+	}
+out:
+	spin_unlock(&inode->i_lock);
+out_unlocked:
+	if (session && unlock_session)
+		mutex_unlock(&session->s_mutex);
+	return flushing;
+}
+
+/*
+ * Return true if we've flushed caps through the given flush_tid.
+ */
+static int caps_are_flushed(struct inode *inode, unsigned tid)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int dirty, i, ret = 1;
+
+	spin_lock(&inode->i_lock);
+	dirty = __ceph_caps_dirty(ci);
+	for (i = 0; i < CEPH_CAP_BITS; i++)
+		if ((ci->i_flushing_caps & (1 << i)) &&
+		    ci->i_cap_flush_tid[i] <= tid) {
+			/* still flushing this bit */
+			ret = 0;
+			break;
+		}
+	spin_unlock(&inode->i_lock);
+	return ret;
+}
+
+/*
+ * Wait on any unsafe replies for the given inode.  First wait on the
+ * newest request, and make that the upper bound.  Then, if there are
+ * more requests, keep waiting on the oldest as long as it is still older
+ * than the original request.
+ */
+static void sync_write_wait(struct inode *inode)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct list_head *head = &ci->i_unsafe_writes;
+	struct ceph_osd_request *req;
+	u64 last_tid;
+
+	spin_lock(&ci->i_unsafe_lock);
+	if (list_empty(head))
+		goto out;
+
+	/* set upper bound as _last_ entry in chain */
+	req = list_entry(head->prev, struct ceph_osd_request,
+			 r_unsafe_item);
+	last_tid = req->r_tid;
+
+	do {
+		ceph_osdc_get_request(req);
+		spin_unlock(&ci->i_unsafe_lock);
+		dout("sync_write_wait on tid %llu (until %llu)\n",
+		     req->r_tid, last_tid);
+		wait_for_completion(&req->r_safe_completion);
+		spin_lock(&ci->i_unsafe_lock);
+		ceph_osdc_put_request(req);
+
+		/*
+		 * from here on look at first entry in chain, since we
+		 * only want to wait for anything older than last_tid
+		 */
+		if (list_empty(head))
+			break;
+		req = list_entry(head->next, struct ceph_osd_request,
+				 r_unsafe_item);
+	} while (req->r_tid < last_tid);
+out:
+	spin_unlock(&ci->i_unsafe_lock);
+}
+
+int ceph_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+	struct inode *inode = dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	unsigned flush_tid;
+	int ret;
+	int dirty;
+
+	dout("fsync %p%s\n", inode, datasync ? " datasync" : "");
+	sync_write_wait(inode);
+
+	ret = filemap_write_and_wait(inode->i_mapping);
+	if (ret < 0)
+		return ret;
+
+	dirty = try_flush_caps(inode, NULL, &flush_tid);
+	dout("fsync dirty caps are %s\n", ceph_cap_string(dirty));
+
+	/*
+	 * only wait on non-file metadata writeback (the mds
+	 * can recover size and mtime, so we don't need to
+	 * wait for that)
+	 */
+	if (!datasync && (dirty & ~CEPH_CAP_ANY_FILE_WR)) {
+		dout("fsync waiting for flush_tid %u\n", flush_tid);
+		ret = wait_event_interruptible(ci->i_cap_wq,
+				       caps_are_flushed(inode, flush_tid));
+	}
+
+	dout("fsync %p%s done\n", inode, datasync ? " datasync" : "");
+	return ret;
+}
+
+/*
+ * Flush any dirty caps back to the mds.  If we aren't asked to wait,
+ * queue inode for flush but don't do so immediately, because we can
+ * get by with fewer MDS messages if we wait for data writeback to
+ * complete first.
+ */
+int ceph_write_inode(struct inode *inode, struct writeback_control *wbc)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	unsigned flush_tid;
+	int err = 0;
+	int dirty;
+	int wait = wbc->sync_mode == WB_SYNC_ALL;
+
+	dout("write_inode %p wait=%d\n", inode, wait);
+	if (wait) {
+		dirty = try_flush_caps(inode, NULL, &flush_tid);
+		if (dirty)
+			err = wait_event_interruptible(ci->i_cap_wq,
+				       caps_are_flushed(inode, flush_tid));
+	} else {
+		struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc;
+
+		spin_lock(&inode->i_lock);
+		if (__ceph_caps_dirty(ci))
+			__cap_delay_requeue_front(mdsc, ci);
+		spin_unlock(&inode->i_lock);
+	}
+	return err;
+}
+
+/*
+ * After a recovering MDS goes active, we need to resend any caps
+ * we were flushing.
+ *
+ * Caller holds session->s_mutex.
+ */
+static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc,
+				   struct ceph_mds_session *session)
+{
+	struct ceph_cap_snap *capsnap;
+
+	dout("kick_flushing_capsnaps mds%d\n", session->s_mds);
+	list_for_each_entry(capsnap, &session->s_cap_snaps_flushing,
+			    flushing_item) {
+		struct ceph_inode_info *ci = capsnap->ci;
+		struct inode *inode = &ci->vfs_inode;
+		struct ceph_cap *cap;
+
+		spin_lock(&inode->i_lock);
+		cap = ci->i_auth_cap;
+		if (cap && cap->session == session) {
+			dout("kick_flushing_caps %p cap %p capsnap %p\n", inode,
+			     cap, capsnap);
+			__ceph_flush_snaps(ci, &session);
+		} else {
+			pr_err("%p auth cap %p not mds%d ???\n", inode,
+			       cap, session->s_mds);
+		}
+		spin_unlock(&inode->i_lock);
+	}
+}
+
+void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
+			     struct ceph_mds_session *session)
+{
+	struct ceph_inode_info *ci;
+
+	kick_flushing_capsnaps(mdsc, session);
+
+	dout("kick_flushing_caps mds%d\n", session->s_mds);
+	list_for_each_entry(ci, &session->s_cap_flushing, i_flushing_item) {
+		struct inode *inode = &ci->vfs_inode;
+		struct ceph_cap *cap;
+		int delayed = 0;
+
+		spin_lock(&inode->i_lock);
+		cap = ci->i_auth_cap;
+		if (cap && cap->session == session) {
+			dout("kick_flushing_caps %p cap %p %s\n", inode,
+			     cap, ceph_cap_string(ci->i_flushing_caps));
+			delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH,
+					     __ceph_caps_used(ci),
+					     __ceph_caps_wanted(ci),
+					     cap->issued | cap->implemented,
+					     ci->i_flushing_caps, NULL);
+			if (delayed) {
+				spin_lock(&inode->i_lock);
+				__cap_delay_requeue(mdsc, ci);
+				spin_unlock(&inode->i_lock);
+			}
+		} else {
+			pr_err("%p auth cap %p not mds%d ???\n", inode,
+			       cap, session->s_mds);
+			spin_unlock(&inode->i_lock);
+		}
+	}
+}
+
+
+/*
+ * Take references to capabilities we hold, so that we don't release
+ * them to the MDS prematurely.
+ *
+ * Protected by i_lock.
+ */
+static void __take_cap_refs(struct ceph_inode_info *ci, int got)
+{
+	if (got & CEPH_CAP_PIN)
+		ci->i_pin_ref++;
+	if (got & CEPH_CAP_FILE_RD)
+		ci->i_rd_ref++;
+	if (got & CEPH_CAP_FILE_CACHE)
+		ci->i_rdcache_ref++;
+	if (got & CEPH_CAP_FILE_WR)
+		ci->i_wr_ref++;
+	if (got & CEPH_CAP_FILE_BUFFER) {
+		if (ci->i_wrbuffer_ref == 0)
+			igrab(&ci->vfs_inode);
+		ci->i_wrbuffer_ref++;
+		dout("__take_cap_refs %p wrbuffer %d -> %d (?)\n",
+		     &ci->vfs_inode, ci->i_wrbuffer_ref-1, ci->i_wrbuffer_ref);
+	}
+}
+
+/*
+ * Try to grab cap references.  Specify those refs we @want, and the
+ * minimal set we @need.  Also include the larger offset we are writing
+ * to (when applicable), and check against max_size here as well.
+ * Note that caller is responsible for ensuring max_size increases are
+ * requested from the MDS.
+ */
+static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want,
+			    int *got, loff_t endoff, int *check_max, int *err)
+{
+	struct inode *inode = &ci->vfs_inode;
+	int ret = 0;
+	int have, implemented;
+	int file_wanted;
+
+	dout("get_cap_refs %p need %s want %s\n", inode,
+	     ceph_cap_string(need), ceph_cap_string(want));
+	spin_lock(&inode->i_lock);
+
+	/* make sure file is actually open */
+	file_wanted = __ceph_caps_file_wanted(ci);
+	if ((file_wanted & need) == 0) {
+		dout("try_get_cap_refs need %s file_wanted %s, EBADF\n",
+		     ceph_cap_string(need), ceph_cap_string(file_wanted));
+		*err = -EBADF;
+		ret = 1;
+		goto out;
+	}
+
+	if (need & CEPH_CAP_FILE_WR) {
+		if (endoff >= 0 && endoff > (loff_t)ci->i_max_size) {
+			dout("get_cap_refs %p endoff %llu > maxsize %llu\n",
+			     inode, endoff, ci->i_max_size);
+			if (endoff > ci->i_wanted_max_size) {
+				*check_max = 1;
+				ret = 1;
+			}
+			goto out;
+		}
+		/*
+		 * If a sync write is in progress, we must wait, so that we
+		 * can get a final snapshot value for size+mtime.
+		 */
+		if (__ceph_have_pending_cap_snap(ci)) {
+			dout("get_cap_refs %p cap_snap_pending\n", inode);
+			goto out;
+		}
+	}
+	have = __ceph_caps_issued(ci, &implemented);
+
+	/*
+	 * disallow writes while a truncate is pending
+	 */
+	if (ci->i_truncate_pending)
+		have &= ~CEPH_CAP_FILE_WR;
+
+	if ((have & need) == need) {
+		/*
+		 * Look at (implemented & ~have & not) so that we keep waiting
+		 * on transition from wanted -> needed caps.  This is needed
+		 * for WRBUFFER|WR -> WR to avoid a new WR sync write from
+		 * going before a prior buffered writeback happens.
+		 */
+		int not = want & ~(have & need);
+		int revoking = implemented & ~have;
+		dout("get_cap_refs %p have %s but not %s (revoking %s)\n",
+		     inode, ceph_cap_string(have), ceph_cap_string(not),
+		     ceph_cap_string(revoking));
+		if ((revoking & not) == 0) {
+			*got = need | (have & want);
+			__take_cap_refs(ci, *got);
+			ret = 1;
+		}
+	} else {
+		dout("get_cap_refs %p have %s needed %s\n", inode,
+		     ceph_cap_string(have), ceph_cap_string(need));
+	}
+out:
+	spin_unlock(&inode->i_lock);
+	dout("get_cap_refs %p ret %d got %s\n", inode,
+	     ret, ceph_cap_string(*got));
+	return ret;
+}
+
+/*
+ * Check the offset we are writing up to against our current
+ * max_size.  If necessary, tell the MDS we want to write to
+ * a larger offset.
+ */
+static void check_max_size(struct inode *inode, loff_t endoff)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int check = 0;
+
+	/* do we need to explicitly request a larger max_size? */
+	spin_lock(&inode->i_lock);
+	if ((endoff >= ci->i_max_size ||
+	     endoff > (inode->i_size << 1)) &&
+	    endoff > ci->i_wanted_max_size) {
+		dout("write %p at large endoff %llu, req max_size\n",
+		     inode, endoff);
+		ci->i_wanted_max_size = endoff;
+		check = 1;
+	}
+	spin_unlock(&inode->i_lock);
+	if (check)
+		ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
+}
+
+/*
+ * Wait for caps, and take cap references.  If we can't get a WR cap
+ * due to a small max_size, make sure we check_max_size (and possibly
+ * ask the mds) so we don't get hung up indefinitely.
+ */
+int ceph_get_caps(struct ceph_inode_info *ci, int need, int want, int *got,
+		  loff_t endoff)
+{
+	int check_max, ret, err;
+
+retry:
+	if (endoff > 0)
+		check_max_size(&ci->vfs_inode, endoff);
+	check_max = 0;
+	err = 0;
+	ret = wait_event_interruptible(ci->i_cap_wq,
+				       try_get_cap_refs(ci, need, want,
+							got, endoff,
+							&check_max, &err));
+	if (err)
+		ret = err;
+	if (check_max)
+		goto retry;
+	return ret;
+}
+
+/*
+ * Take cap refs.  Caller must already know we hold at least one ref
+ * on the caps in question or we don't know this is safe.
+ */
+void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps)
+{
+	spin_lock(&ci->vfs_inode.i_lock);
+	__take_cap_refs(ci, caps);
+	spin_unlock(&ci->vfs_inode.i_lock);
+}
+
+/*
+ * Release cap refs.
+ *
+ * If we released the last ref on any given cap, call ceph_check_caps
+ * to release (or schedule a release).
+ *
+ * If we are releasing a WR cap (from a sync write), finalize any affected
+ * cap_snap, and wake up any waiters.
+ */
+void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
+{
+	struct inode *inode = &ci->vfs_inode;
+	int last = 0, put = 0, flushsnaps = 0, wake = 0;
+	struct ceph_cap_snap *capsnap;
+
+	spin_lock(&inode->i_lock);
+	if (had & CEPH_CAP_PIN)
+		--ci->i_pin_ref;
+	if (had & CEPH_CAP_FILE_RD)
+		if (--ci->i_rd_ref == 0)
+			last++;
+	if (had & CEPH_CAP_FILE_CACHE)
+		if (--ci->i_rdcache_ref == 0)
+			last++;
+	if (had & CEPH_CAP_FILE_BUFFER) {
+		if (--ci->i_wrbuffer_ref == 0) {
+			last++;
+			put++;
+		}
+		dout("put_cap_refs %p wrbuffer %d -> %d (?)\n",
+		     inode, ci->i_wrbuffer_ref+1, ci->i_wrbuffer_ref);
+	}
+	if (had & CEPH_CAP_FILE_WR)
+		if (--ci->i_wr_ref == 0) {
+			last++;
+			if (!list_empty(&ci->i_cap_snaps)) {
+				capsnap = list_first_entry(&ci->i_cap_snaps,
+						     struct ceph_cap_snap,
+						     ci_item);
+				if (capsnap->writing) {
+					capsnap->writing = 0;
+					flushsnaps =
+						__ceph_finish_cap_snap(ci,
+								       capsnap);
+					wake = 1;
+				}
+			}
+		}
+	spin_unlock(&inode->i_lock);
+
+	dout("put_cap_refs %p had %s%s%s\n", inode, ceph_cap_string(had),
+	     last ? " last" : "", put ? " put" : "");
+
+	if (last && !flushsnaps)
+		ceph_check_caps(ci, 0, NULL);
+	else if (flushsnaps)
+		ceph_flush_snaps(ci);
+	if (wake)
+		wake_up(&ci->i_cap_wq);
+	if (put)
+		iput(inode);
+}
+
+/*
+ * Release @nr WRBUFFER refs on dirty pages for the given @snapc snap
+ * context.  Adjust per-snap dirty page accounting as appropriate.
+ * Once all dirty data for a cap_snap is flushed, flush snapped file
+ * metadata back to the MDS.  If we dropped the last ref, call
+ * ceph_check_caps.
+ */
+void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
+				struct ceph_snap_context *snapc)
+{
+	struct inode *inode = &ci->vfs_inode;
+	int last = 0;
+	int complete_capsnap = 0;
+	int drop_capsnap = 0;
+	int found = 0;
+	struct ceph_cap_snap *capsnap = NULL;
+
+	spin_lock(&inode->i_lock);
+	ci->i_wrbuffer_ref -= nr;
+	last = !ci->i_wrbuffer_ref;
+
+	if (ci->i_head_snapc == snapc) {
+		ci->i_wrbuffer_ref_head -= nr;
+		if (!ci->i_wrbuffer_ref_head) {
+			ceph_put_snap_context(ci->i_head_snapc);
+			ci->i_head_snapc = NULL;
+		}
+		dout("put_wrbuffer_cap_refs on %p head %d/%d -> %d/%d %s\n",
+		     inode,
+		     ci->i_wrbuffer_ref+nr, ci->i_wrbuffer_ref_head+nr,
+		     ci->i_wrbuffer_ref, ci->i_wrbuffer_ref_head,
+		     last ? " LAST" : "");
+	} else {
+		list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
+			if (capsnap->context == snapc) {
+				found = 1;
+				break;
+			}
+		}
+		BUG_ON(!found);
+		capsnap->dirty_pages -= nr;
+		if (capsnap->dirty_pages == 0) {
+			complete_capsnap = 1;
+			if (capsnap->dirty == 0)
+				/* cap writeback completed before we created
+				 * the cap_snap; no FLUSHSNAP is needed */
+				drop_capsnap = 1;
+		}
+		dout("put_wrbuffer_cap_refs on %p cap_snap %p "
+		     " snap %lld %d/%d -> %d/%d %s%s%s\n",
+		     inode, capsnap, capsnap->context->seq,
+		     ci->i_wrbuffer_ref+nr, capsnap->dirty_pages + nr,
+		     ci->i_wrbuffer_ref, capsnap->dirty_pages,
+		     last ? " (wrbuffer last)" : "",
+		     complete_capsnap ? " (complete capsnap)" : "",
+		     drop_capsnap ? " (drop capsnap)" : "");
+		if (drop_capsnap) {
+			ceph_put_snap_context(capsnap->context);
+			list_del(&capsnap->ci_item);
+			list_del(&capsnap->flushing_item);
+			ceph_put_cap_snap(capsnap);
+		}
+	}
+
+	spin_unlock(&inode->i_lock);
+
+	if (last) {
+		ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
+		iput(inode);
+	} else if (complete_capsnap) {
+		ceph_flush_snaps(ci);
+		wake_up(&ci->i_cap_wq);
+	}
+	if (drop_capsnap)
+		iput(inode);
+}
+
+/*
+ * Handle a cap GRANT message from the MDS.  (Note that a GRANT may
+ * actually be a revocation if it specifies a smaller cap set.)
+ *
+ * caller holds s_mutex and i_lock, we drop both.
+ *
+ * return value:
+ *  0 - ok
+ *  1 - check_caps on auth cap only (writeback)
+ *  2 - check_caps (ack revoke)
+ */
+static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
+			     struct ceph_mds_session *session,
+			     struct ceph_cap *cap,
+			     struct ceph_buffer *xattr_buf)
+	__releases(inode->i_lock)
+	__releases(session->s_mutex)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int mds = session->s_mds;
+	int seq = le32_to_cpu(grant->seq);
+	int newcaps = le32_to_cpu(grant->caps);
+	int issued, implemented, used, wanted, dirty;
+	u64 size = le64_to_cpu(grant->size);
+	u64 max_size = le64_to_cpu(grant->max_size);
+	struct timespec mtime, atime, ctime;
+	int check_caps = 0;
+	int wake = 0;
+	int writeback = 0;
+	int revoked_rdcache = 0;
+	int queue_invalidate = 0;
+
+	dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n",
+	     inode, cap, mds, seq, ceph_cap_string(newcaps));
+	dout(" size %llu max_size %llu, i_size %llu\n", size, max_size,
+		inode->i_size);
+
+	/*
+	 * If CACHE is being revoked, and we have no dirty buffers,
+	 * try to invalidate (once).  (If there are dirty buffers, we
+	 * will invalidate _after_ writeback.)
+	 */
+	if (((cap->issued & ~newcaps) & CEPH_CAP_FILE_CACHE) &&
+	    !ci->i_wrbuffer_ref) {
+		if (try_nonblocking_invalidate(inode) == 0) {
+			revoked_rdcache = 1;
+		} else {
+			/* there were locked pages.. invalidate later
+			   in a separate thread. */
+			if (ci->i_rdcache_revoking != ci->i_rdcache_gen) {
+				queue_invalidate = 1;
+				ci->i_rdcache_revoking = ci->i_rdcache_gen;
+			}
+		}
+	}
+
+	/* side effects now are allowed */
+
+	issued = __ceph_caps_issued(ci, &implemented);
+	issued |= implemented | __ceph_caps_dirty(ci);
+
+	cap->cap_gen = session->s_cap_gen;
+
+	__check_cap_issue(ci, cap, newcaps);
+
+	if ((issued & CEPH_CAP_AUTH_EXCL) == 0) {
+		inode->i_mode = le32_to_cpu(grant->mode);
+		inode->i_uid = le32_to_cpu(grant->uid);
+		inode->i_gid = le32_to_cpu(grant->gid);
+		dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode,
+		     inode->i_uid, inode->i_gid);
+	}
+
+	if ((issued & CEPH_CAP_LINK_EXCL) == 0)
+		inode->i_nlink = le32_to_cpu(grant->nlink);
+
+	if ((issued & CEPH_CAP_XATTR_EXCL) == 0 && grant->xattr_len) {
+		int len = le32_to_cpu(grant->xattr_len);
+		u64 version = le64_to_cpu(grant->xattr_version);
+
+		if (version > ci->i_xattrs.version) {
+			dout(" got new xattrs v%llu on %p len %d\n",
+			     version, inode, len);
+			if (ci->i_xattrs.blob)
+				ceph_buffer_put(ci->i_xattrs.blob);
+			ci->i_xattrs.blob = ceph_buffer_get(xattr_buf);
+			ci->i_xattrs.version = version;
+		}
+	}
+
+	/* size/ctime/mtime/atime? */
+	ceph_fill_file_size(inode, issued,
+			    le32_to_cpu(grant->truncate_seq),
+			    le64_to_cpu(grant->truncate_size), size);
+	ceph_decode_timespec(&mtime, &grant->mtime);
+	ceph_decode_timespec(&atime, &grant->atime);
+	ceph_decode_timespec(&ctime, &grant->ctime);
+	ceph_fill_file_time(inode, issued,
+			    le32_to_cpu(grant->time_warp_seq), &ctime, &mtime,
+			    &atime);
+
+	/* max size increase? */
+	if (max_size != ci->i_max_size) {
+		dout("max_size %lld -> %llu\n", ci->i_max_size, max_size);
+		ci->i_max_size = max_size;
+		if (max_size >= ci->i_wanted_max_size) {
+			ci->i_wanted_max_size = 0;  /* reset */
+			ci->i_requested_max_size = 0;
+		}
+		wake = 1;
+	}
+
+	/* check cap bits */
+	wanted = __ceph_caps_wanted(ci);
+	used = __ceph_caps_used(ci);
+	dirty = __ceph_caps_dirty(ci);
+	dout(" my wanted = %s, used = %s, dirty %s\n",
+	     ceph_cap_string(wanted),
+	     ceph_cap_string(used),
+	     ceph_cap_string(dirty));
+	if (wanted != le32_to_cpu(grant->wanted)) {
+		dout("mds wanted %s -> %s\n",
+		     ceph_cap_string(le32_to_cpu(grant->wanted)),
+		     ceph_cap_string(wanted));
+		grant->wanted = cpu_to_le32(wanted);
+	}
+
+	cap->seq = seq;
+
+	/* file layout may have changed */
+	ci->i_layout = grant->layout;
+
+	/* revocation, grant, or no-op? */
+	if (cap->issued & ~newcaps) {
+		dout("revocation: %s -> %s\n", ceph_cap_string(cap->issued),
+		     ceph_cap_string(newcaps));
+		if ((used & ~newcaps) & CEPH_CAP_FILE_BUFFER)
+			writeback = 1; /* will delay ack */
+		else if (dirty & ~newcaps)
+			check_caps = 1;  /* initiate writeback in check_caps */
+		else if (((used & ~newcaps) & CEPH_CAP_FILE_CACHE) == 0 ||
+			   revoked_rdcache)
+			check_caps = 2;     /* send revoke ack in check_caps */
+		cap->issued = newcaps;
+		cap->implemented |= newcaps;
+	} else if (cap->issued == newcaps) {
+		dout("caps unchanged: %s -> %s\n",
+		     ceph_cap_string(cap->issued), ceph_cap_string(newcaps));
+	} else {
+		dout("grant: %s -> %s\n", ceph_cap_string(cap->issued),
+		     ceph_cap_string(newcaps));
+		cap->issued = newcaps;
+		cap->implemented |= newcaps; /* add bits only, to
+					      * avoid stepping on a
+					      * pending revocation */
+		wake = 1;
+	}
+	BUG_ON(cap->issued & ~cap->implemented);
+
+	spin_unlock(&inode->i_lock);
+	if (writeback)
+		/*
+		 * queue inode for writeback: we can't actually call
+		 * filemap_write_and_wait, etc. from message handler
+		 * context.
+		 */
+		ceph_queue_writeback(inode);
+	if (queue_invalidate)
+		ceph_queue_invalidate(inode);
+	if (wake)
+		wake_up(&ci->i_cap_wq);
+
+	if (check_caps == 1)
+		ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_AUTHONLY,
+				session);
+	else if (check_caps == 2)
+		ceph_check_caps(ci, CHECK_CAPS_NODELAY, session);
+	else
+		mutex_unlock(&session->s_mutex);
+}
+
+/*
+ * Handle FLUSH_ACK from MDS, indicating that metadata we sent to the
+ * MDS has been safely committed.
+ */
+static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid,
+				 struct ceph_mds_caps *m,
+				 struct ceph_mds_session *session,
+				 struct ceph_cap *cap)
+	__releases(inode->i_lock)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc;
+	unsigned seq = le32_to_cpu(m->seq);
+	int dirty = le32_to_cpu(m->dirty);
+	int cleaned = 0;
+	int drop = 0;
+	int i;
+
+	for (i = 0; i < CEPH_CAP_BITS; i++)
+		if ((dirty & (1 << i)) &&
+		    flush_tid == ci->i_cap_flush_tid[i])
+			cleaned |= 1 << i;
+
+	dout("handle_cap_flush_ack inode %p mds%d seq %d on %s cleaned %s,"
+	     " flushing %s -> %s\n",
+	     inode, session->s_mds, seq, ceph_cap_string(dirty),
+	     ceph_cap_string(cleaned), ceph_cap_string(ci->i_flushing_caps),
+	     ceph_cap_string(ci->i_flushing_caps & ~cleaned));
+
+	if (ci->i_flushing_caps == (ci->i_flushing_caps & ~cleaned))
+		goto out;
+
+	ci->i_flushing_caps &= ~cleaned;
+
+	spin_lock(&mdsc->cap_dirty_lock);
+	if (ci->i_flushing_caps == 0) {
+		list_del_init(&ci->i_flushing_item);
+		if (!list_empty(&session->s_cap_flushing))
+			dout(" mds%d still flushing cap on %p\n",
+			     session->s_mds,
+			     &list_entry(session->s_cap_flushing.next,
+					 struct ceph_inode_info,
+					 i_flushing_item)->vfs_inode);
+		mdsc->num_cap_flushing--;
+		wake_up(&mdsc->cap_flushing_wq);
+		dout(" inode %p now !flushing\n", inode);
+
+		if (ci->i_dirty_caps == 0) {
+			dout(" inode %p now clean\n", inode);
+			BUG_ON(!list_empty(&ci->i_dirty_item));
+			drop = 1;
+		} else {
+			BUG_ON(list_empty(&ci->i_dirty_item));
+		}
+	}
+	spin_unlock(&mdsc->cap_dirty_lock);
+	wake_up(&ci->i_cap_wq);
+
+out:
+	spin_unlock(&inode->i_lock);
+	if (drop)
+		iput(inode);
+}
+
+/*
+ * Handle FLUSHSNAP_ACK.  MDS has flushed snap data to disk and we can
+ * throw away our cap_snap.
+ *
+ * Caller hold s_mutex.
+ */
+static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid,
+				     struct ceph_mds_caps *m,
+				     struct ceph_mds_session *session)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	u64 follows = le64_to_cpu(m->snap_follows);
+	struct ceph_cap_snap *capsnap;
+	int drop = 0;
+
+	dout("handle_cap_flushsnap_ack inode %p ci %p mds%d follows %lld\n",
+	     inode, ci, session->s_mds, follows);
+
+	spin_lock(&inode->i_lock);
+	list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
+		if (capsnap->follows == follows) {
+			if (capsnap->flush_tid != flush_tid) {
+				dout(" cap_snap %p follows %lld tid %lld !="
+				     " %lld\n", capsnap, follows,
+				     flush_tid, capsnap->flush_tid);
+				break;
+			}
+			WARN_ON(capsnap->dirty_pages || capsnap->writing);
+			dout(" removing %p cap_snap %p follows %lld\n",
+			     inode, capsnap, follows);
+			ceph_put_snap_context(capsnap->context);
+			list_del(&capsnap->ci_item);
+			list_del(&capsnap->flushing_item);
+			ceph_put_cap_snap(capsnap);
+			drop = 1;
+			break;
+		} else {
+			dout(" skipping cap_snap %p follows %lld\n",
+			     capsnap, capsnap->follows);
+		}
+	}
+	spin_unlock(&inode->i_lock);
+	if (drop)
+		iput(inode);
+}
+
+/*
+ * Handle TRUNC from MDS, indicating file truncation.
+ *
+ * caller hold s_mutex.
+ */
+static void handle_cap_trunc(struct inode *inode,
+			     struct ceph_mds_caps *trunc,
+			     struct ceph_mds_session *session)
+	__releases(inode->i_lock)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int mds = session->s_mds;
+	int seq = le32_to_cpu(trunc->seq);
+	u32 truncate_seq = le32_to_cpu(trunc->truncate_seq);
+	u64 truncate_size = le64_to_cpu(trunc->truncate_size);
+	u64 size = le64_to_cpu(trunc->size);
+	int implemented = 0;
+	int dirty = __ceph_caps_dirty(ci);
+	int issued = __ceph_caps_issued(ceph_inode(inode), &implemented);
+	int queue_trunc = 0;
+
+	issued |= implemented | dirty;
+
+	dout("handle_cap_trunc inode %p mds%d seq %d to %lld seq %d\n",
+	     inode, mds, seq, truncate_size, truncate_seq);
+	queue_trunc = ceph_fill_file_size(inode, issued,
+					  truncate_seq, truncate_size, size);
+	spin_unlock(&inode->i_lock);
+
+	if (queue_trunc)
+		ceph_queue_vmtruncate(inode);
+}
+
+/*
+ * Handle EXPORT from MDS.  Cap is being migrated _from_ this mds to a
+ * different one.  If we are the most recent migration we've seen (as
+ * indicated by mseq), make note of the migrating cap bits for the
+ * duration (until we see the corresponding IMPORT).
+ *
+ * caller holds s_mutex
+ */
+static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex,
+			      struct ceph_mds_session *session)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int mds = session->s_mds;
+	unsigned mseq = le32_to_cpu(ex->migrate_seq);
+	struct ceph_cap *cap = NULL, *t;
+	struct rb_node *p;
+	int remember = 1;
+
+	dout("handle_cap_export inode %p ci %p mds%d mseq %d\n",
+	     inode, ci, mds, mseq);
+
+	spin_lock(&inode->i_lock);
+
+	/* make sure we haven't seen a higher mseq */
+	for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+		t = rb_entry(p, struct ceph_cap, ci_node);
+		if (ceph_seq_cmp(t->mseq, mseq) > 0) {
+			dout(" higher mseq on cap from mds%d\n",
+			     t->session->s_mds);
+			remember = 0;
+		}
+		if (t->session->s_mds == mds)
+			cap = t;
+	}
+
+	if (cap) {
+		if (remember) {
+			/* make note */
+			ci->i_cap_exporting_mds = mds;
+			ci->i_cap_exporting_mseq = mseq;
+			ci->i_cap_exporting_issued = cap->issued;
+		}
+		__ceph_remove_cap(cap);
+	}
+	/* else, we already released it */
+
+	spin_unlock(&inode->i_lock);
+}
+
+/*
+ * Handle cap IMPORT.  If there are temp bits from an older EXPORT,
+ * clean them up.
+ *
+ * caller holds s_mutex.
+ */
+static void handle_cap_import(struct ceph_mds_client *mdsc,
+			      struct inode *inode, struct ceph_mds_caps *im,
+			      struct ceph_mds_session *session,
+			      void *snaptrace, int snaptrace_len)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int mds = session->s_mds;
+	unsigned issued = le32_to_cpu(im->caps);
+	unsigned wanted = le32_to_cpu(im->wanted);
+	unsigned seq = le32_to_cpu(im->seq);
+	unsigned mseq = le32_to_cpu(im->migrate_seq);
+	u64 realmino = le64_to_cpu(im->realm);
+	u64 cap_id = le64_to_cpu(im->cap_id);
+
+	if (ci->i_cap_exporting_mds >= 0 &&
+	    ceph_seq_cmp(ci->i_cap_exporting_mseq, mseq) < 0) {
+		dout("handle_cap_import inode %p ci %p mds%d mseq %d"
+		     " - cleared exporting from mds%d\n",
+		     inode, ci, mds, mseq,
+		     ci->i_cap_exporting_mds);
+		ci->i_cap_exporting_issued = 0;
+		ci->i_cap_exporting_mseq = 0;
+		ci->i_cap_exporting_mds = -1;
+	} else {
+		dout("handle_cap_import inode %p ci %p mds%d mseq %d\n",
+		     inode, ci, mds, mseq);
+	}
+
+	down_write(&mdsc->snap_rwsem);
+	ceph_update_snap_trace(mdsc, snaptrace, snaptrace+snaptrace_len,
+			       false);
+	downgrade_write(&mdsc->snap_rwsem);
+	ceph_add_cap(inode, session, cap_id, -1,
+		     issued, wanted, seq, mseq, realmino, CEPH_CAP_FLAG_AUTH,
+		     NULL /* no caps context */);
+	try_flush_caps(inode, session, NULL);
+	up_read(&mdsc->snap_rwsem);
+}
+
+/*
+ * Handle a caps message from the MDS.
+ *
+ * Identify the appropriate session, inode, and call the right handler
+ * based on the cap op.
+ */
+void ceph_handle_caps(struct ceph_mds_session *session,
+		      struct ceph_msg *msg)
+{
+	struct ceph_mds_client *mdsc = session->s_mdsc;
+	struct super_block *sb = mdsc->client->sb;
+	struct inode *inode;
+	struct ceph_cap *cap;
+	struct ceph_mds_caps *h;
+	int mds = session->s_mds;
+	int op;
+	u32 seq;
+	struct ceph_vino vino;
+	u64 cap_id;
+	u64 size, max_size;
+	u64 tid;
+	void *snaptrace;
+
+	dout("handle_caps from mds%d\n", mds);
+
+	/* decode */
+	tid = le64_to_cpu(msg->hdr.tid);
+	if (msg->front.iov_len < sizeof(*h))
+		goto bad;
+	h = msg->front.iov_base;
+	snaptrace = h + 1;
+	op = le32_to_cpu(h->op);
+	vino.ino = le64_to_cpu(h->ino);
+	vino.snap = CEPH_NOSNAP;
+	cap_id = le64_to_cpu(h->cap_id);
+	seq = le32_to_cpu(h->seq);
+	size = le64_to_cpu(h->size);
+	max_size = le64_to_cpu(h->max_size);
+
+	mutex_lock(&session->s_mutex);
+	session->s_seq++;
+	dout(" mds%d seq %lld cap seq %u\n", session->s_mds, session->s_seq,
+	     (unsigned)seq);
+
+	/* lookup ino */
+	inode = ceph_find_inode(sb, vino);
+	dout(" op %s ino %llx.%llx inode %p\n", ceph_cap_op_name(op), vino.ino,
+	     vino.snap, inode);
+	if (!inode) {
+		dout(" i don't have ino %llx\n", vino.ino);
+		goto done;
+	}
+
+	/* these will work even if we don't have a cap yet */
+	switch (op) {
+	case CEPH_CAP_OP_FLUSHSNAP_ACK:
+		handle_cap_flushsnap_ack(inode, tid, h, session);
+		goto done;
+
+	case CEPH_CAP_OP_EXPORT:
+		handle_cap_export(inode, h, session);
+		goto done;
+
+	case CEPH_CAP_OP_IMPORT:
+		handle_cap_import(mdsc, inode, h, session,
+				  snaptrace, le32_to_cpu(h->snap_trace_len));
+		ceph_check_caps(ceph_inode(inode), CHECK_CAPS_NODELAY,
+				session);
+		goto done_unlocked;
+	}
+
+	/* the rest require a cap */
+	spin_lock(&inode->i_lock);
+	cap = __get_cap_for_mds(ceph_inode(inode), mds);
+	if (!cap) {
+		dout("no cap on %p ino %llx.%llx from mds%d, releasing\n",
+		     inode, ceph_ino(inode), ceph_snap(inode), mds);
+		spin_unlock(&inode->i_lock);
+		goto done;
+	}
+
+	/* note that each of these drops i_lock for us */
+	switch (op) {
+	case CEPH_CAP_OP_REVOKE:
+	case CEPH_CAP_OP_GRANT:
+		handle_cap_grant(inode, h, session, cap, msg->middle);
+		goto done_unlocked;
+
+	case CEPH_CAP_OP_FLUSH_ACK:
+		handle_cap_flush_ack(inode, tid, h, session, cap);
+		break;
+
+	case CEPH_CAP_OP_TRUNC:
+		handle_cap_trunc(inode, h, session);
+		break;
+
+	default:
+		spin_unlock(&inode->i_lock);
+		pr_err("ceph_handle_caps: unknown cap op %d %s\n", op,
+		       ceph_cap_op_name(op));
+	}
+
+done:
+	mutex_unlock(&session->s_mutex);
+done_unlocked:
+	if (inode)
+		iput(inode);
+	return;
+
+bad:
+	pr_err("ceph_handle_caps: corrupt message\n");
+	ceph_msg_dump(msg);
+	return;
+}
+
+/*
+ * Delayed work handler to process end of delayed cap release LRU list.
+ */
+void ceph_check_delayed_caps(struct ceph_mds_client *mdsc)
+{
+	struct ceph_inode_info *ci;
+	int flags = CHECK_CAPS_NODELAY;
+
+	dout("check_delayed_caps\n");
+	while (1) {
+		spin_lock(&mdsc->cap_delay_lock);
+		if (list_empty(&mdsc->cap_delay_list))
+			break;
+		ci = list_first_entry(&mdsc->cap_delay_list,
+				      struct ceph_inode_info,
+				      i_cap_delay_list);
+		if ((ci->i_ceph_flags & CEPH_I_FLUSH) == 0 &&
+		    time_before(jiffies, ci->i_hold_caps_max))
+			break;
+		list_del_init(&ci->i_cap_delay_list);
+		spin_unlock(&mdsc->cap_delay_lock);
+		dout("check_delayed_caps on %p\n", &ci->vfs_inode);
+		ceph_check_caps(ci, flags, NULL);
+	}
+	spin_unlock(&mdsc->cap_delay_lock);
+}
+
+/*
+ * Flush all dirty caps to the mds
+ */
+void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc)
+{
+	struct ceph_inode_info *ci, *nci = NULL;
+	struct inode *inode, *ninode = NULL;
+	struct list_head *p, *n;
+
+	dout("flush_dirty_caps\n");
+	spin_lock(&mdsc->cap_dirty_lock);
+	list_for_each_safe(p, n, &mdsc->cap_dirty) {
+		if (nci) {
+			ci = nci;
+			inode = ninode;
+			ci->i_ceph_flags &= ~CEPH_I_NOFLUSH;
+			dout("flush_dirty_caps inode %p (was next inode)\n",
+			     inode);
+		} else {
+			ci = list_entry(p, struct ceph_inode_info,
+					i_dirty_item);
+			inode = igrab(&ci->vfs_inode);
+			BUG_ON(!inode);
+			dout("flush_dirty_caps inode %p\n", inode);
+		}
+		if (n != &mdsc->cap_dirty) {
+			nci = list_entry(n, struct ceph_inode_info,
+					 i_dirty_item);
+			ninode = igrab(&nci->vfs_inode);
+			BUG_ON(!ninode);
+			nci->i_ceph_flags |= CEPH_I_NOFLUSH;
+			dout("flush_dirty_caps next inode %p, noflush\n",
+			     ninode);
+		} else {
+			nci = NULL;
+			ninode = NULL;
+		}
+		spin_unlock(&mdsc->cap_dirty_lock);
+		if (inode) {
+			ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH,
+					NULL);
+			iput(inode);
+		}
+		spin_lock(&mdsc->cap_dirty_lock);
+	}
+	spin_unlock(&mdsc->cap_dirty_lock);
+}
+
+/*
+ * Drop open file reference.  If we were the last open file,
+ * we may need to release capabilities to the MDS (or schedule
+ * their delayed release).
+ */
+void ceph_put_fmode(struct ceph_inode_info *ci, int fmode)
+{
+	struct inode *inode = &ci->vfs_inode;
+	int last = 0;
+
+	spin_lock(&inode->i_lock);
+	dout("put_fmode %p fmode %d %d -> %d\n", inode, fmode,
+	     ci->i_nr_by_mode[fmode], ci->i_nr_by_mode[fmode]-1);
+	BUG_ON(ci->i_nr_by_mode[fmode] == 0);
+	if (--ci->i_nr_by_mode[fmode] == 0)
+		last++;
+	spin_unlock(&inode->i_lock);
+
+	if (last && ci->i_vino.snap == CEPH_NOSNAP)
+		ceph_check_caps(ci, 0, NULL);
+}
+
+/*
+ * Helpers for embedding cap and dentry lease releases into mds
+ * requests.
+ *
+ * @force is used by dentry_release (below) to force inclusion of a
+ * record for the directory inode, even when there aren't any caps to
+ * drop.
+ */
+int ceph_encode_inode_release(void **p, struct inode *inode,
+			      int mds, int drop, int unless, int force)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_cap *cap;
+	struct ceph_mds_request_release *rel = *p;
+	int ret = 0;
+	int used = 0;
+
+	spin_lock(&inode->i_lock);
+	used = __ceph_caps_used(ci);
+
+	dout("encode_inode_release %p mds%d used %s drop %s unless %s\n", inode,
+	     mds, ceph_cap_string(used), ceph_cap_string(drop),
+	     ceph_cap_string(unless));
+
+	/* only drop unused caps */
+	drop &= ~used;
+
+	cap = __get_cap_for_mds(ci, mds);
+	if (cap && __cap_is_valid(cap)) {
+		if (force ||
+		    ((cap->issued & drop) &&
+		     (cap->issued & unless) == 0)) {
+			if ((cap->issued & drop) &&
+			    (cap->issued & unless) == 0) {
+				dout("encode_inode_release %p cap %p %s -> "
+				     "%s\n", inode, cap,
+				     ceph_cap_string(cap->issued),
+				     ceph_cap_string(cap->issued & ~drop));
+				cap->issued &= ~drop;
+				cap->implemented &= ~drop;
+				if (ci->i_ceph_flags & CEPH_I_NODELAY) {
+					int wanted = __ceph_caps_wanted(ci);
+					dout("  wanted %s -> %s (act %s)\n",
+					     ceph_cap_string(cap->mds_wanted),
+					     ceph_cap_string(cap->mds_wanted &
+							     ~wanted),
+					     ceph_cap_string(wanted));
+					cap->mds_wanted &= wanted;
+				}
+			} else {
+				dout("encode_inode_release %p cap %p %s"
+				     " (force)\n", inode, cap,
+				     ceph_cap_string(cap->issued));
+			}
+
+			rel->ino = cpu_to_le64(ceph_ino(inode));
+			rel->cap_id = cpu_to_le64(cap->cap_id);
+			rel->seq = cpu_to_le32(cap->seq);
+			rel->issue_seq = cpu_to_le32(cap->issue_seq),
+			rel->mseq = cpu_to_le32(cap->mseq);
+			rel->caps = cpu_to_le32(cap->issued);
+			rel->wanted = cpu_to_le32(cap->mds_wanted);
+			rel->dname_len = 0;
+			rel->dname_seq = 0;
+			*p += sizeof(*rel);
+			ret = 1;
+		} else {
+			dout("encode_inode_release %p cap %p %s\n",
+			     inode, cap, ceph_cap_string(cap->issued));
+		}
+	}
+	spin_unlock(&inode->i_lock);
+	return ret;
+}
+
+int ceph_encode_dentry_release(void **p, struct dentry *dentry,
+			       int mds, int drop, int unless)
+{
+	struct inode *dir = dentry->d_parent->d_inode;
+	struct ceph_mds_request_release *rel = *p;
+	struct ceph_dentry_info *di = ceph_dentry(dentry);
+	int force = 0;
+	int ret;
+
+	/*
+	 * force an record for the directory caps if we have a dentry lease.
+	 * this is racy (can't take i_lock and d_lock together), but it
+	 * doesn't have to be perfect; the mds will revoke anything we don't
+	 * release.
+	 */
+	spin_lock(&dentry->d_lock);
+	if (di->lease_session && di->lease_session->s_mds == mds)
+		force = 1;
+	spin_unlock(&dentry->d_lock);
+
+	ret = ceph_encode_inode_release(p, dir, mds, drop, unless, force);
+
+	spin_lock(&dentry->d_lock);
+	if (ret && di->lease_session && di->lease_session->s_mds == mds) {
+		dout("encode_dentry_release %p mds%d seq %d\n",
+		     dentry, mds, (int)di->lease_seq);
+		rel->dname_len = cpu_to_le32(dentry->d_name.len);
+		memcpy(*p, dentry->d_name.name, dentry->d_name.len);
+		*p += dentry->d_name.len;
+		rel->dname_seq = cpu_to_le32(di->lease_seq);
+	}
+	spin_unlock(&dentry->d_lock);
+	return ret;
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/ceph_debug.h linux-libre-2.6.34-gnu1/fs/ceph/ceph_debug.h
--- linux-libre-2.6.33-gnu1/fs/ceph/ceph_debug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/ceph_debug.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,37 @@
+#ifndef _FS_CEPH_DEBUG_H
+#define _FS_CEPH_DEBUG_H
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#ifdef CONFIG_CEPH_FS_PRETTYDEBUG
+
+/*
+ * wrap pr_debug to include a filename:lineno prefix on each line.
+ * this incurs some overhead (kernel size and execution time) due to
+ * the extra function call at each call site.
+ */
+
+# if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
+extern const char *ceph_file_part(const char *s, int len);
+#  define dout(fmt, ...)						\
+	pr_debug(" %12.12s:%-4d : " fmt,				\
+		 ceph_file_part(__FILE__, sizeof(__FILE__)),		\
+		 __LINE__, ##__VA_ARGS__)
+# else
+/* faux printk call just to see any compiler warnings. */
+#  define dout(fmt, ...)	do {				\
+		if (0)						\
+			printk(KERN_DEBUG fmt, ##__VA_ARGS__);	\
+	} while (0)
+# endif
+
+#else
+
+/*
+ * or, just wrap pr_debug
+ */
+# define dout(fmt, ...)	pr_debug(" " fmt, ##__VA_ARGS__)
+
+#endif
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/ceph_frag.c linux-libre-2.6.34-gnu1/fs/ceph/ceph_frag.c
--- linux-libre-2.6.33-gnu1/fs/ceph/ceph_frag.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/ceph_frag.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ * Ceph 'frag' type
+ */
+#include "types.h"
+
+int ceph_frag_compare(__u32 a, __u32 b)
+{
+	unsigned va = ceph_frag_value(a);
+	unsigned vb = ceph_frag_value(b);
+	if (va < vb)
+		return -1;
+	if (va > vb)
+		return 1;
+	va = ceph_frag_bits(a);
+	vb = ceph_frag_bits(b);
+	if (va < vb)
+		return -1;
+	if (va > vb)
+		return 1;
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/ceph_frag.h linux-libre-2.6.34-gnu1/fs/ceph/ceph_frag.h
--- linux-libre-2.6.33-gnu1/fs/ceph/ceph_frag.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/ceph_frag.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,109 @@
+#ifndef _FS_CEPH_FRAG_H
+#define _FS_CEPH_FRAG_H
+
+/*
+ * "Frags" are a way to describe a subset of a 32-bit number space,
+ * using a mask and a value to match against that mask.  Any given frag
+ * (subset of the number space) can be partitioned into 2^n sub-frags.
+ *
+ * Frags are encoded into a 32-bit word:
+ *   8 upper bits = "bits"
+ *  24 lower bits = "value"
+ * (We could go to 5+27 bits, but who cares.)
+ *
+ * We use the _most_ significant bits of the 24 bit value.  This makes
+ * values logically sort.
+ *
+ * Unfortunately, because the "bits" field is still in the high bits, we
+ * can't sort encoded frags numerically.  However, it does allow you
+ * to feed encoded frags as values into frag_contains_value.
+ */
+static inline __u32 ceph_frag_make(__u32 b, __u32 v)
+{
+	return (b << 24) |
+		(v & (0xffffffu << (24-b)) & 0xffffffu);
+}
+static inline __u32 ceph_frag_bits(__u32 f)
+{
+	return f >> 24;
+}
+static inline __u32 ceph_frag_value(__u32 f)
+{
+	return f & 0xffffffu;
+}
+static inline __u32 ceph_frag_mask(__u32 f)
+{
+	return (0xffffffu << (24-ceph_frag_bits(f))) & 0xffffffu;
+}
+static inline __u32 ceph_frag_mask_shift(__u32 f)
+{
+	return 24 - ceph_frag_bits(f);
+}
+
+static inline int ceph_frag_contains_value(__u32 f, __u32 v)
+{
+	return (v & ceph_frag_mask(f)) == ceph_frag_value(f);
+}
+static inline int ceph_frag_contains_frag(__u32 f, __u32 sub)
+{
+	/* is sub as specific as us, and contained by us? */
+	return ceph_frag_bits(sub) >= ceph_frag_bits(f) &&
+	       (ceph_frag_value(sub) & ceph_frag_mask(f)) == ceph_frag_value(f);
+}
+
+static inline __u32 ceph_frag_parent(__u32 f)
+{
+	return ceph_frag_make(ceph_frag_bits(f) - 1,
+			 ceph_frag_value(f) & (ceph_frag_mask(f) << 1));
+}
+static inline int ceph_frag_is_left_child(__u32 f)
+{
+	return ceph_frag_bits(f) > 0 &&
+		(ceph_frag_value(f) & (0x1000000 >> ceph_frag_bits(f))) == 0;
+}
+static inline int ceph_frag_is_right_child(__u32 f)
+{
+	return ceph_frag_bits(f) > 0 &&
+		(ceph_frag_value(f) & (0x1000000 >> ceph_frag_bits(f))) == 1;
+}
+static inline __u32 ceph_frag_sibling(__u32 f)
+{
+	return ceph_frag_make(ceph_frag_bits(f),
+		      ceph_frag_value(f) ^ (0x1000000 >> ceph_frag_bits(f)));
+}
+static inline __u32 ceph_frag_left_child(__u32 f)
+{
+	return ceph_frag_make(ceph_frag_bits(f)+1, ceph_frag_value(f));
+}
+static inline __u32 ceph_frag_right_child(__u32 f)
+{
+	return ceph_frag_make(ceph_frag_bits(f)+1,
+	      ceph_frag_value(f) | (0x1000000 >> (1+ceph_frag_bits(f))));
+}
+static inline __u32 ceph_frag_make_child(__u32 f, int by, int i)
+{
+	int newbits = ceph_frag_bits(f) + by;
+	return ceph_frag_make(newbits,
+			 ceph_frag_value(f) | (i << (24 - newbits)));
+}
+static inline int ceph_frag_is_leftmost(__u32 f)
+{
+	return ceph_frag_value(f) == 0;
+}
+static inline int ceph_frag_is_rightmost(__u32 f)
+{
+	return ceph_frag_value(f) == ceph_frag_mask(f);
+}
+static inline __u32 ceph_frag_next(__u32 f)
+{
+	return ceph_frag_make(ceph_frag_bits(f),
+			 ceph_frag_value(f) + (0x1000000 >> ceph_frag_bits(f)));
+}
+
+/*
+ * comparator to sort frags logically, as when traversing the
+ * number space in ascending order...
+ */
+int ceph_frag_compare(__u32 a, __u32 b);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/ceph_fs.c linux-libre-2.6.34-gnu1/fs/ceph/ceph_fs.c
--- linux-libre-2.6.33-gnu1/fs/ceph/ceph_fs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/ceph_fs.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,74 @@
+/*
+ * Some non-inline ceph helpers
+ */
+#include "types.h"
+
+/*
+ * return true if @layout appears to be valid
+ */
+int ceph_file_layout_is_valid(const struct ceph_file_layout *layout)
+{
+	__u32 su = le32_to_cpu(layout->fl_stripe_unit);
+	__u32 sc = le32_to_cpu(layout->fl_stripe_count);
+	__u32 os = le32_to_cpu(layout->fl_object_size);
+
+	/* stripe unit, object size must be non-zero, 64k increment */
+	if (!su || (su & (CEPH_MIN_STRIPE_UNIT-1)))
+		return 0;
+	if (!os || (os & (CEPH_MIN_STRIPE_UNIT-1)))
+		return 0;
+	/* object size must be a multiple of stripe unit */
+	if (os < su || os % su)
+		return 0;
+	/* stripe count must be non-zero */
+	if (!sc)
+		return 0;
+	return 1;
+}
+
+
+int ceph_flags_to_mode(int flags)
+{
+#ifdef O_DIRECTORY  /* fixme */
+	if ((flags & O_DIRECTORY) == O_DIRECTORY)
+		return CEPH_FILE_MODE_PIN;
+#endif
+#ifdef O_LAZY
+	if (flags & O_LAZY)
+		return CEPH_FILE_MODE_LAZY;
+#endif
+	if ((flags & O_APPEND) == O_APPEND)
+		flags |= O_WRONLY;
+
+	flags &= O_ACCMODE;
+	if ((flags & O_RDWR) == O_RDWR)
+		return CEPH_FILE_MODE_RDWR;
+	if ((flags & O_WRONLY) == O_WRONLY)
+		return CEPH_FILE_MODE_WR;
+	return CEPH_FILE_MODE_RD;
+}
+
+int ceph_caps_for_mode(int mode)
+{
+	switch (mode) {
+	case CEPH_FILE_MODE_PIN:
+		return CEPH_CAP_PIN;
+	case CEPH_FILE_MODE_RD:
+		return CEPH_CAP_PIN | CEPH_CAP_FILE_SHARED |
+			CEPH_CAP_FILE_RD | CEPH_CAP_FILE_CACHE;
+	case CEPH_FILE_MODE_RDWR:
+		return CEPH_CAP_PIN | CEPH_CAP_FILE_SHARED |
+			CEPH_CAP_FILE_EXCL |
+			CEPH_CAP_FILE_RD | CEPH_CAP_FILE_CACHE |
+			CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER |
+			CEPH_CAP_AUTH_SHARED | CEPH_CAP_AUTH_EXCL |
+			CEPH_CAP_XATTR_SHARED | CEPH_CAP_XATTR_EXCL;
+	case CEPH_FILE_MODE_WR:
+		return CEPH_CAP_PIN | CEPH_CAP_FILE_SHARED |
+			CEPH_CAP_FILE_EXCL |
+			CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER |
+			CEPH_CAP_AUTH_SHARED | CEPH_CAP_AUTH_EXCL |
+			CEPH_CAP_XATTR_SHARED | CEPH_CAP_XATTR_EXCL;
+	}
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/ceph_fs.h linux-libre-2.6.34-gnu1/fs/ceph/ceph_fs.h
--- linux-libre-2.6.33-gnu1/fs/ceph/ceph_fs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/ceph_fs.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,650 @@
+/*
+ * ceph_fs.h - Ceph constants and data types to share between kernel and
+ * user space.
+ *
+ * Most types in this file are defined as little-endian, and are
+ * primarily intended to describe data structures that pass over the
+ * wire or that are stored on disk.
+ *
+ * LGPL2
+ */
+
+#ifndef _FS_CEPH_CEPH_FS_H
+#define _FS_CEPH_CEPH_FS_H
+
+#include "msgr.h"
+#include "rados.h"
+
+/*
+ * Ceph release version
+ */
+#define CEPH_VERSION_MAJOR 0
+#define CEPH_VERSION_MINOR 19
+#define CEPH_VERSION_PATCH 0
+
+#define _CEPH_STRINGIFY(x) #x
+#define CEPH_STRINGIFY(x) _CEPH_STRINGIFY(x)
+#define CEPH_MAKE_VERSION(x, y, z) CEPH_STRINGIFY(x) "." CEPH_STRINGIFY(y) \
+	"." CEPH_STRINGIFY(z)
+#define CEPH_VERSION CEPH_MAKE_VERSION(CEPH_VERSION_MAJOR, \
+				       CEPH_VERSION_MINOR, CEPH_VERSION_PATCH)
+
+/*
+ * subprotocol versions.  when specific messages types or high-level
+ * protocols change, bump the affected components.  we keep rev
+ * internal cluster protocols separately from the public,
+ * client-facing protocol.
+ */
+#define CEPH_OSD_PROTOCOL     8 /* cluster internal */
+#define CEPH_MDS_PROTOCOL     9 /* cluster internal */
+#define CEPH_MON_PROTOCOL     5 /* cluster internal */
+#define CEPH_OSDC_PROTOCOL   24 /* server/client */
+#define CEPH_MDSC_PROTOCOL   32 /* server/client */
+#define CEPH_MONC_PROTOCOL   15 /* server/client */
+
+
+#define CEPH_INO_ROOT  1
+#define CEPH_INO_CEPH  2        /* hidden .ceph dir */
+
+/* arbitrary limit on max # of monitors (cluster of 3 is typical) */
+#define CEPH_MAX_MON   31
+
+
+/*
+ * feature bits
+ */
+#define CEPH_FEATURE_SUPPORTED  0
+#define CEPH_FEATURE_REQUIRED   0
+
+
+/*
+ * ceph_file_layout - describe data layout for a file/inode
+ */
+struct ceph_file_layout {
+	/* file -> object mapping */
+	__le32 fl_stripe_unit;     /* stripe unit, in bytes.  must be multiple
+				      of page size. */
+	__le32 fl_stripe_count;    /* over this many objects */
+	__le32 fl_object_size;     /* until objects are this big, then move to
+				      new objects */
+	__le32 fl_cas_hash;        /* 0 = none; 1 = sha256 */
+
+	/* pg -> disk layout */
+	__le32 fl_object_stripe_unit;  /* for per-object parity, if any */
+
+	/* object -> pg layout */
+	__le32 fl_pg_preferred; /* preferred primary for pg (-1 for none) */
+	__le32 fl_pg_pool;      /* namespace, crush ruleset, rep level */
+} __attribute__ ((packed));
+
+#define CEPH_MIN_STRIPE_UNIT 65536
+
+int ceph_file_layout_is_valid(const struct ceph_file_layout *layout);
+
+
+/* crypto algorithms */
+#define CEPH_CRYPTO_NONE 0x0
+#define CEPH_CRYPTO_AES  0x1
+
+/* security/authentication protocols */
+#define CEPH_AUTH_UNKNOWN	0x0
+#define CEPH_AUTH_NONE	 	0x1
+#define CEPH_AUTH_CEPHX	 	0x2
+
+
+/*********************************************
+ * message layer
+ */
+
+/*
+ * message types
+ */
+
+/* misc */
+#define CEPH_MSG_SHUTDOWN               1
+#define CEPH_MSG_PING                   2
+
+/* client <-> monitor */
+#define CEPH_MSG_MON_MAP                4
+#define CEPH_MSG_MON_GET_MAP            5
+#define CEPH_MSG_STATFS                 13
+#define CEPH_MSG_STATFS_REPLY           14
+#define CEPH_MSG_MON_SUBSCRIBE          15
+#define CEPH_MSG_MON_SUBSCRIBE_ACK      16
+#define CEPH_MSG_AUTH			17
+#define CEPH_MSG_AUTH_REPLY		18
+
+/* client <-> mds */
+#define CEPH_MSG_MDS_MAP                21
+
+#define CEPH_MSG_CLIENT_SESSION         22
+#define CEPH_MSG_CLIENT_RECONNECT       23
+
+#define CEPH_MSG_CLIENT_REQUEST         24
+#define CEPH_MSG_CLIENT_REQUEST_FORWARD 25
+#define CEPH_MSG_CLIENT_REPLY           26
+#define CEPH_MSG_CLIENT_CAPS            0x310
+#define CEPH_MSG_CLIENT_LEASE           0x311
+#define CEPH_MSG_CLIENT_SNAP            0x312
+#define CEPH_MSG_CLIENT_CAPRELEASE      0x313
+
+/* osd */
+#define CEPH_MSG_OSD_MAP          41
+#define CEPH_MSG_OSD_OP           42
+#define CEPH_MSG_OSD_OPREPLY      43
+
+struct ceph_mon_request_header {
+	__le64 have_version;
+	__le16 session_mon;
+	__le64 session_mon_tid;
+} __attribute__ ((packed));
+
+struct ceph_mon_statfs {
+	struct ceph_mon_request_header monhdr;
+	struct ceph_fsid fsid;
+} __attribute__ ((packed));
+
+struct ceph_statfs {
+	__le64 kb, kb_used, kb_avail;
+	__le64 num_objects;
+} __attribute__ ((packed));
+
+struct ceph_mon_statfs_reply {
+	struct ceph_fsid fsid;
+	__le64 version;
+	struct ceph_statfs st;
+} __attribute__ ((packed));
+
+struct ceph_osd_getmap {
+	struct ceph_mon_request_header monhdr;
+	struct ceph_fsid fsid;
+	__le32 start;
+} __attribute__ ((packed));
+
+struct ceph_mds_getmap {
+	struct ceph_mon_request_header monhdr;
+	struct ceph_fsid fsid;
+} __attribute__ ((packed));
+
+struct ceph_client_mount {
+	struct ceph_mon_request_header monhdr;
+} __attribute__ ((packed));
+
+struct ceph_mon_subscribe_item {
+	__le64 have_version;	__le64 have;
+	__u8 onetime;
+} __attribute__ ((packed));
+
+struct ceph_mon_subscribe_ack {
+	__le32 duration;         /* seconds */
+	struct ceph_fsid fsid;
+} __attribute__ ((packed));
+
+/*
+ * mds states
+ *   > 0 -> in
+ *  <= 0 -> out
+ */
+#define CEPH_MDS_STATE_DNE          0  /* down, does not exist. */
+#define CEPH_MDS_STATE_STOPPED     -1  /* down, once existed, but no subtrees.
+					  empty log. */
+#define CEPH_MDS_STATE_BOOT        -4  /* up, boot announcement. */
+#define CEPH_MDS_STATE_STANDBY     -5  /* up, idle.  waiting for assignment. */
+#define CEPH_MDS_STATE_CREATING    -6  /* up, creating MDS instance. */
+#define CEPH_MDS_STATE_STARTING    -7  /* up, starting previously stopped mds */
+#define CEPH_MDS_STATE_STANDBY_REPLAY -8 /* up, tailing active node's journal */
+
+#define CEPH_MDS_STATE_REPLAY       8  /* up, replaying journal. */
+#define CEPH_MDS_STATE_RESOLVE      9  /* up, disambiguating distributed
+					  operations (import, rename, etc.) */
+#define CEPH_MDS_STATE_RECONNECT    10 /* up, reconnect to clients */
+#define CEPH_MDS_STATE_REJOIN       11 /* up, rejoining distributed cache */
+#define CEPH_MDS_STATE_CLIENTREPLAY 12 /* up, replaying client operations */
+#define CEPH_MDS_STATE_ACTIVE       13 /* up, active */
+#define CEPH_MDS_STATE_STOPPING     14 /* up, but exporting metadata */
+
+extern const char *ceph_mds_state_name(int s);
+
+
+/*
+ * metadata lock types.
+ *  - these are bitmasks.. we can compose them
+ *  - they also define the lock ordering by the MDS
+ *  - a few of these are internal to the mds
+ */
+#define CEPH_LOCK_DN          1
+#define CEPH_LOCK_ISNAP       2
+#define CEPH_LOCK_IVERSION    4     /* mds internal */
+#define CEPH_LOCK_IFILE       8     /* mds internal */
+#define CEPH_LOCK_IAUTH       32
+#define CEPH_LOCK_ILINK       64
+#define CEPH_LOCK_IDFT        128   /* dir frag tree */
+#define CEPH_LOCK_INEST       256   /* mds internal */
+#define CEPH_LOCK_IXATTR      512
+#define CEPH_LOCK_INO         2048  /* immutable inode bits; not a lock */
+
+/* client_session ops */
+enum {
+	CEPH_SESSION_REQUEST_OPEN,
+	CEPH_SESSION_OPEN,
+	CEPH_SESSION_REQUEST_CLOSE,
+	CEPH_SESSION_CLOSE,
+	CEPH_SESSION_REQUEST_RENEWCAPS,
+	CEPH_SESSION_RENEWCAPS,
+	CEPH_SESSION_STALE,
+	CEPH_SESSION_RECALL_STATE,
+};
+
+extern const char *ceph_session_op_name(int op);
+
+struct ceph_mds_session_head {
+	__le32 op;
+	__le64 seq;
+	struct ceph_timespec stamp;
+	__le32 max_caps, max_leases;
+} __attribute__ ((packed));
+
+/* client_request */
+/*
+ * metadata ops.
+ *  & 0x001000 -> write op
+ *  & 0x010000 -> follow symlink (e.g. stat(), not lstat()).
+ &  & 0x100000 -> use weird ino/path trace
+ */
+#define CEPH_MDS_OP_WRITE        0x001000
+enum {
+	CEPH_MDS_OP_LOOKUP     = 0x00100,
+	CEPH_MDS_OP_GETATTR    = 0x00101,
+	CEPH_MDS_OP_LOOKUPHASH = 0x00102,
+	CEPH_MDS_OP_LOOKUPPARENT = 0x00103,
+
+	CEPH_MDS_OP_SETXATTR   = 0x01105,
+	CEPH_MDS_OP_RMXATTR    = 0x01106,
+	CEPH_MDS_OP_SETLAYOUT  = 0x01107,
+	CEPH_MDS_OP_SETATTR    = 0x01108,
+
+	CEPH_MDS_OP_MKNOD      = 0x01201,
+	CEPH_MDS_OP_LINK       = 0x01202,
+	CEPH_MDS_OP_UNLINK     = 0x01203,
+	CEPH_MDS_OP_RENAME     = 0x01204,
+	CEPH_MDS_OP_MKDIR      = 0x01220,
+	CEPH_MDS_OP_RMDIR      = 0x01221,
+	CEPH_MDS_OP_SYMLINK    = 0x01222,
+
+	CEPH_MDS_OP_CREATE     = 0x01301,
+	CEPH_MDS_OP_OPEN       = 0x00302,
+	CEPH_MDS_OP_READDIR    = 0x00305,
+
+	CEPH_MDS_OP_LOOKUPSNAP = 0x00400,
+	CEPH_MDS_OP_MKSNAP     = 0x01400,
+	CEPH_MDS_OP_RMSNAP     = 0x01401,
+	CEPH_MDS_OP_LSSNAP     = 0x00402,
+};
+
+extern const char *ceph_mds_op_name(int op);
+
+
+#define CEPH_SETATTR_MODE   1
+#define CEPH_SETATTR_UID    2
+#define CEPH_SETATTR_GID    4
+#define CEPH_SETATTR_MTIME  8
+#define CEPH_SETATTR_ATIME 16
+#define CEPH_SETATTR_SIZE  32
+#define CEPH_SETATTR_CTIME 64
+
+union ceph_mds_request_args {
+	struct {
+		__le32 mask;                 /* CEPH_CAP_* */
+	} __attribute__ ((packed)) getattr;
+	struct {
+		__le32 mode;
+		__le32 uid;
+		__le32 gid;
+		struct ceph_timespec mtime;
+		struct ceph_timespec atime;
+		__le64 size, old_size;       /* old_size needed by truncate */
+		__le32 mask;                 /* CEPH_SETATTR_* */
+	} __attribute__ ((packed)) setattr;
+	struct {
+		__le32 frag;                 /* which dir fragment */
+		__le32 max_entries;          /* how many dentries to grab */
+	} __attribute__ ((packed)) readdir;
+	struct {
+		__le32 mode;
+		__le32 rdev;
+	} __attribute__ ((packed)) mknod;
+	struct {
+		__le32 mode;
+	} __attribute__ ((packed)) mkdir;
+	struct {
+		__le32 flags;
+		__le32 mode;
+		__le32 stripe_unit;          /* layout for newly created file */
+		__le32 stripe_count;         /* ... */
+		__le32 object_size;
+		__le32 file_replication;
+		__le32 preferred;
+	} __attribute__ ((packed)) open;
+	struct {
+		__le32 flags;
+	} __attribute__ ((packed)) setxattr;
+	struct {
+		struct ceph_file_layout layout;
+	} __attribute__ ((packed)) setlayout;
+} __attribute__ ((packed));
+
+#define CEPH_MDS_FLAG_REPLAY        1  /* this is a replayed op */
+#define CEPH_MDS_FLAG_WANT_DENTRY   2  /* want dentry in reply */
+
+struct ceph_mds_request_head {
+	__le64 oldest_client_tid;
+	__le32 mdsmap_epoch;           /* on client */
+	__le32 flags;                  /* CEPH_MDS_FLAG_* */
+	__u8 num_retry, num_fwd;       /* count retry, fwd attempts */
+	__le16 num_releases;           /* # include cap/lease release records */
+	__le32 op;                     /* mds op code */
+	__le32 caller_uid, caller_gid;
+	__le64 ino;                    /* use this ino for openc, mkdir, mknod,
+					  etc. (if replaying) */
+	union ceph_mds_request_args args;
+} __attribute__ ((packed));
+
+/* cap/lease release record */
+struct ceph_mds_request_release {
+	__le64 ino, cap_id;            /* ino and unique cap id */
+	__le32 caps, wanted;           /* new issued, wanted */
+	__le32 seq, issue_seq, mseq;
+	__le32 dname_seq;              /* if releasing a dentry lease, a */
+	__le32 dname_len;              /* string follows. */
+} __attribute__ ((packed));
+
+/* client reply */
+struct ceph_mds_reply_head {
+	__le32 op;
+	__le32 result;
+	__le32 mdsmap_epoch;
+	__u8 safe;                     /* true if committed to disk */
+	__u8 is_dentry, is_target;     /* true if dentry, target inode records
+					  are included with reply */
+} __attribute__ ((packed));
+
+/* one for each node split */
+struct ceph_frag_tree_split {
+	__le32 frag;                   /* this frag splits... */
+	__le32 by;                     /* ...by this many bits */
+} __attribute__ ((packed));
+
+struct ceph_frag_tree_head {
+	__le32 nsplits;                /* num ceph_frag_tree_split records */
+	struct ceph_frag_tree_split splits[];
+} __attribute__ ((packed));
+
+/* capability issue, for bundling with mds reply */
+struct ceph_mds_reply_cap {
+	__le32 caps, wanted;           /* caps issued, wanted */
+	__le64 cap_id;
+	__le32 seq, mseq;
+	__le64 realm;                  /* snap realm */
+	__u8 flags;                    /* CEPH_CAP_FLAG_* */
+} __attribute__ ((packed));
+
+#define CEPH_CAP_FLAG_AUTH  1          /* cap is issued by auth mds */
+
+/* inode record, for bundling with mds reply */
+struct ceph_mds_reply_inode {
+	__le64 ino;
+	__le64 snapid;
+	__le32 rdev;
+	__le64 version;                /* inode version */
+	__le64 xattr_version;          /* version for xattr blob */
+	struct ceph_mds_reply_cap cap; /* caps issued for this inode */
+	struct ceph_file_layout layout;
+	struct ceph_timespec ctime, mtime, atime;
+	__le32 time_warp_seq;
+	__le64 size, max_size, truncate_size;
+	__le32 truncate_seq;
+	__le32 mode, uid, gid;
+	__le32 nlink;
+	__le64 files, subdirs, rbytes, rfiles, rsubdirs;  /* dir stats */
+	struct ceph_timespec rctime;
+	struct ceph_frag_tree_head fragtree;  /* (must be at end of struct) */
+} __attribute__ ((packed));
+/* followed by frag array, then symlink string, then xattr blob */
+
+/* reply_lease follows dname, and reply_inode */
+struct ceph_mds_reply_lease {
+	__le16 mask;            /* lease type(s) */
+	__le32 duration_ms;     /* lease duration */
+	__le32 seq;
+} __attribute__ ((packed));
+
+struct ceph_mds_reply_dirfrag {
+	__le32 frag;            /* fragment */
+	__le32 auth;            /* auth mds, if this is a delegation point */
+	__le32 ndist;           /* number of mds' this is replicated on */
+	__le32 dist[];
+} __attribute__ ((packed));
+
+/* file access modes */
+#define CEPH_FILE_MODE_PIN        0
+#define CEPH_FILE_MODE_RD         1
+#define CEPH_FILE_MODE_WR         2
+#define CEPH_FILE_MODE_RDWR       3  /* RD | WR */
+#define CEPH_FILE_MODE_LAZY       4  /* lazy io */
+#define CEPH_FILE_MODE_NUM        8  /* bc these are bit fields.. mostly */
+
+int ceph_flags_to_mode(int flags);
+
+
+/* capability bits */
+#define CEPH_CAP_PIN         1  /* no specific capabilities beyond the pin */
+
+/* generic cap bits */
+#define CEPH_CAP_GSHARED     1  /* client can reads */
+#define CEPH_CAP_GEXCL       2  /* client can read and update */
+#define CEPH_CAP_GCACHE      4  /* (file) client can cache reads */
+#define CEPH_CAP_GRD         8  /* (file) client can read */
+#define CEPH_CAP_GWR        16  /* (file) client can write */
+#define CEPH_CAP_GBUFFER    32  /* (file) client can buffer writes */
+#define CEPH_CAP_GWREXTEND  64  /* (file) client can extend EOF */
+#define CEPH_CAP_GLAZYIO   128  /* (file) client can perform lazy io */
+
+/* per-lock shift */
+#define CEPH_CAP_SAUTH      2
+#define CEPH_CAP_SLINK      4
+#define CEPH_CAP_SXATTR     6
+#define CEPH_CAP_SFILE      8   /* goes at the end (uses >2 cap bits) */
+
+#define CEPH_CAP_BITS       16
+
+/* composed values */
+#define CEPH_CAP_AUTH_SHARED  (CEPH_CAP_GSHARED  << CEPH_CAP_SAUTH)
+#define CEPH_CAP_AUTH_EXCL     (CEPH_CAP_GEXCL     << CEPH_CAP_SAUTH)
+#define CEPH_CAP_LINK_SHARED  (CEPH_CAP_GSHARED  << CEPH_CAP_SLINK)
+#define CEPH_CAP_LINK_EXCL     (CEPH_CAP_GEXCL     << CEPH_CAP_SLINK)
+#define CEPH_CAP_XATTR_SHARED (CEPH_CAP_GSHARED  << CEPH_CAP_SXATTR)
+#define CEPH_CAP_XATTR_EXCL    (CEPH_CAP_GEXCL     << CEPH_CAP_SXATTR)
+#define CEPH_CAP_FILE(x)    (x << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_SHARED   (CEPH_CAP_GSHARED   << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_EXCL     (CEPH_CAP_GEXCL     << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_CACHE    (CEPH_CAP_GCACHE    << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_RD       (CEPH_CAP_GRD       << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_WR       (CEPH_CAP_GWR       << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_BUFFER   (CEPH_CAP_GBUFFER   << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_WREXTEND (CEPH_CAP_GWREXTEND << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_LAZYIO   (CEPH_CAP_GLAZYIO   << CEPH_CAP_SFILE)
+
+/* cap masks (for getattr) */
+#define CEPH_STAT_CAP_INODE    CEPH_CAP_PIN
+#define CEPH_STAT_CAP_TYPE     CEPH_CAP_PIN  /* mode >> 12 */
+#define CEPH_STAT_CAP_SYMLINK  CEPH_CAP_PIN
+#define CEPH_STAT_CAP_UID      CEPH_CAP_AUTH_SHARED
+#define CEPH_STAT_CAP_GID      CEPH_CAP_AUTH_SHARED
+#define CEPH_STAT_CAP_MODE     CEPH_CAP_AUTH_SHARED
+#define CEPH_STAT_CAP_NLINK    CEPH_CAP_LINK_SHARED
+#define CEPH_STAT_CAP_LAYOUT   CEPH_CAP_FILE_SHARED
+#define CEPH_STAT_CAP_MTIME    CEPH_CAP_FILE_SHARED
+#define CEPH_STAT_CAP_SIZE     CEPH_CAP_FILE_SHARED
+#define CEPH_STAT_CAP_ATIME    CEPH_CAP_FILE_SHARED  /* fixme */
+#define CEPH_STAT_CAP_XATTR    CEPH_CAP_XATTR_SHARED
+#define CEPH_STAT_CAP_INODE_ALL (CEPH_CAP_PIN |			\
+				 CEPH_CAP_AUTH_SHARED |	\
+				 CEPH_CAP_LINK_SHARED |	\
+				 CEPH_CAP_FILE_SHARED |	\
+				 CEPH_CAP_XATTR_SHARED)
+
+#define CEPH_CAP_ANY_SHARED (CEPH_CAP_AUTH_SHARED |			\
+			      CEPH_CAP_LINK_SHARED |			\
+			      CEPH_CAP_XATTR_SHARED |			\
+			      CEPH_CAP_FILE_SHARED)
+#define CEPH_CAP_ANY_RD   (CEPH_CAP_ANY_SHARED | CEPH_CAP_FILE_RD |	\
+			   CEPH_CAP_FILE_CACHE)
+
+#define CEPH_CAP_ANY_EXCL (CEPH_CAP_AUTH_EXCL |		\
+			   CEPH_CAP_LINK_EXCL |		\
+			   CEPH_CAP_XATTR_EXCL |	\
+			   CEPH_CAP_FILE_EXCL)
+#define CEPH_CAP_ANY_FILE_WR (CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER |	\
+			      CEPH_CAP_FILE_EXCL)
+#define CEPH_CAP_ANY_WR   (CEPH_CAP_ANY_EXCL | CEPH_CAP_ANY_FILE_WR)
+#define CEPH_CAP_ANY      (CEPH_CAP_ANY_RD | CEPH_CAP_ANY_EXCL | \
+			   CEPH_CAP_ANY_FILE_WR | CEPH_CAP_PIN)
+
+#define CEPH_CAP_LOCKS (CEPH_LOCK_IFILE | CEPH_LOCK_IAUTH | CEPH_LOCK_ILINK | \
+			CEPH_LOCK_IXATTR)
+
+int ceph_caps_for_mode(int mode);
+
+enum {
+	CEPH_CAP_OP_GRANT,         /* mds->client grant */
+	CEPH_CAP_OP_REVOKE,        /* mds->client revoke */
+	CEPH_CAP_OP_TRUNC,         /* mds->client trunc notify */
+	CEPH_CAP_OP_EXPORT,        /* mds has exported the cap */
+	CEPH_CAP_OP_IMPORT,        /* mds has imported the cap */
+	CEPH_CAP_OP_UPDATE,        /* client->mds update */
+	CEPH_CAP_OP_DROP,          /* client->mds drop cap bits */
+	CEPH_CAP_OP_FLUSH,         /* client->mds cap writeback */
+	CEPH_CAP_OP_FLUSH_ACK,     /* mds->client flushed */
+	CEPH_CAP_OP_FLUSHSNAP,     /* client->mds flush snapped metadata */
+	CEPH_CAP_OP_FLUSHSNAP_ACK, /* mds->client flushed snapped metadata */
+	CEPH_CAP_OP_RELEASE,       /* client->mds release (clean) cap */
+	CEPH_CAP_OP_RENEW,         /* client->mds renewal request */
+};
+
+extern const char *ceph_cap_op_name(int op);
+
+/*
+ * caps message, used for capability callbacks, acks, requests, etc.
+ */
+struct ceph_mds_caps {
+	__le32 op;                  /* CEPH_CAP_OP_* */
+	__le64 ino, realm;
+	__le64 cap_id;
+	__le32 seq, issue_seq;
+	__le32 caps, wanted, dirty; /* latest issued/wanted/dirty */
+	__le32 migrate_seq;
+	__le64 snap_follows;
+	__le32 snap_trace_len;
+
+	/* authlock */
+	__le32 uid, gid, mode;
+
+	/* linklock */
+	__le32 nlink;
+
+	/* xattrlock */
+	__le32 xattr_len;
+	__le64 xattr_version;
+
+	/* filelock */
+	__le64 size, max_size, truncate_size;
+	__le32 truncate_seq;
+	struct ceph_timespec mtime, atime, ctime;
+	struct ceph_file_layout layout;
+	__le32 time_warp_seq;
+} __attribute__ ((packed));
+
+/* cap release msg head */
+struct ceph_mds_cap_release {
+	__le32 num;                /* number of cap_items that follow */
+} __attribute__ ((packed));
+
+struct ceph_mds_cap_item {
+	__le64 ino;
+	__le64 cap_id;
+	__le32 migrate_seq, seq;
+} __attribute__ ((packed));
+
+#define CEPH_MDS_LEASE_REVOKE           1  /*    mds  -> client */
+#define CEPH_MDS_LEASE_RELEASE          2  /* client  -> mds    */
+#define CEPH_MDS_LEASE_RENEW            3  /* client <-> mds    */
+#define CEPH_MDS_LEASE_REVOKE_ACK       4  /* client  -> mds    */
+
+extern const char *ceph_lease_op_name(int o);
+
+/* lease msg header */
+struct ceph_mds_lease {
+	__u8 action;            /* CEPH_MDS_LEASE_* */
+	__le16 mask;            /* which lease */
+	__le64 ino;
+	__le64 first, last;     /* snap range */
+	__le32 seq;
+	__le32 duration_ms;     /* duration of renewal */
+} __attribute__ ((packed));
+/* followed by a __le32+string for dname */
+
+/* client reconnect */
+struct ceph_mds_cap_reconnect {
+	__le64 cap_id;
+	__le32 wanted;
+	__le32 issued;
+	__le64 size;
+	struct ceph_timespec mtime, atime;
+	__le64 snaprealm;
+	__le64 pathbase;        /* base ino for our path to this ino */
+} __attribute__ ((packed));
+/* followed by encoded string */
+
+struct ceph_mds_snaprealm_reconnect {
+	__le64 ino;     /* snap realm base */
+	__le64 seq;     /* snap seq for this snap realm */
+	__le64 parent;  /* parent realm */
+} __attribute__ ((packed));
+
+/*
+ * snaps
+ */
+enum {
+	CEPH_SNAP_OP_UPDATE,  /* CREATE or DESTROY */
+	CEPH_SNAP_OP_CREATE,
+	CEPH_SNAP_OP_DESTROY,
+	CEPH_SNAP_OP_SPLIT,
+};
+
+extern const char *ceph_snap_op_name(int o);
+
+/* snap msg header */
+struct ceph_mds_snap_head {
+	__le32 op;                /* CEPH_SNAP_OP_* */
+	__le64 split;             /* ino to split off, if any */
+	__le32 num_split_inos;    /* # inos belonging to new child realm */
+	__le32 num_split_realms;  /* # child realms udner new child realm */
+	__le32 trace_len;         /* size of snap trace blob */
+} __attribute__ ((packed));
+/* followed by split ino list, then split realms, then the trace blob */
+
+/*
+ * encode info about a snaprealm, as viewed by a client
+ */
+struct ceph_mds_snap_realm {
+	__le64 ino;           /* ino */
+	__le64 created;       /* snap: when created */
+	__le64 parent;        /* ino: parent realm */
+	__le64 parent_since;  /* snap: same parent since */
+	__le64 seq;           /* snap: version */
+	__le32 num_snaps;
+	__le32 num_prior_parent_snaps;
+} __attribute__ ((packed));
+/* followed by my snap list, then prior parent snap list */
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/ceph_hash.c linux-libre-2.6.34-gnu1/fs/ceph/ceph_hash.c
--- linux-libre-2.6.33-gnu1/fs/ceph/ceph_hash.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/ceph_hash.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,118 @@
+
+#include "types.h"
+
+/*
+ * Robert Jenkin's hash function.
+ * http://burtleburtle.net/bob/hash/evahash.html
+ * This is in the public domain.
+ */
+#define mix(a, b, c)						\
+	do {							\
+		a = a - b;  a = a - c;  a = a ^ (c >> 13);	\
+		b = b - c;  b = b - a;  b = b ^ (a << 8);	\
+		c = c - a;  c = c - b;  c = c ^ (b >> 13);	\
+		a = a - b;  a = a - c;  a = a ^ (c >> 12);	\
+		b = b - c;  b = b - a;  b = b ^ (a << 16);	\
+		c = c - a;  c = c - b;  c = c ^ (b >> 5);	\
+		a = a - b;  a = a - c;  a = a ^ (c >> 3);	\
+		b = b - c;  b = b - a;  b = b ^ (a << 10);	\
+		c = c - a;  c = c - b;  c = c ^ (b >> 15);	\
+	} while (0)
+
+unsigned ceph_str_hash_rjenkins(const char *str, unsigned length)
+{
+	const unsigned char *k = (const unsigned char *)str;
+	__u32 a, b, c;  /* the internal state */
+	__u32 len;      /* how many key bytes still need mixing */
+
+	/* Set up the internal state */
+	len = length;
+	a = 0x9e3779b9;      /* the golden ratio; an arbitrary value */
+	b = a;
+	c = 0;               /* variable initialization of internal state */
+
+	/* handle most of the key */
+	while (len >= 12) {
+		a = a + (k[0] + ((__u32)k[1] << 8) + ((__u32)k[2] << 16) +
+			 ((__u32)k[3] << 24));
+		b = b + (k[4] + ((__u32)k[5] << 8) + ((__u32)k[6] << 16) +
+			 ((__u32)k[7] << 24));
+		c = c + (k[8] + ((__u32)k[9] << 8) + ((__u32)k[10] << 16) +
+			 ((__u32)k[11] << 24));
+		mix(a, b, c);
+		k = k + 12;
+		len = len - 12;
+	}
+
+	/* handle the last 11 bytes */
+	c = c + length;
+	switch (len) {            /* all the case statements fall through */
+	case 11:
+		c = c + ((__u32)k[10] << 24);
+	case 10:
+		c = c + ((__u32)k[9] << 16);
+	case 9:
+		c = c + ((__u32)k[8] << 8);
+		/* the first byte of c is reserved for the length */
+	case 8:
+		b = b + ((__u32)k[7] << 24);
+	case 7:
+		b = b + ((__u32)k[6] << 16);
+	case 6:
+		b = b + ((__u32)k[5] << 8);
+	case 5:
+		b = b + k[4];
+	case 4:
+		a = a + ((__u32)k[3] << 24);
+	case 3:
+		a = a + ((__u32)k[2] << 16);
+	case 2:
+		a = a + ((__u32)k[1] << 8);
+	case 1:
+		a = a + k[0];
+		/* case 0: nothing left to add */
+	}
+	mix(a, b, c);
+
+	return c;
+}
+
+/*
+ * linux dcache hash
+ */
+unsigned ceph_str_hash_linux(const char *str, unsigned length)
+{
+	unsigned long hash = 0;
+	unsigned char c;
+
+	while (length--) {
+		c = *str++;
+		hash = (hash + (c << 4) + (c >> 4)) * 11;
+	}
+	return hash;
+}
+
+
+unsigned ceph_str_hash(int type, const char *s, unsigned len)
+{
+	switch (type) {
+	case CEPH_STR_HASH_LINUX:
+		return ceph_str_hash_linux(s, len);
+	case CEPH_STR_HASH_RJENKINS:
+		return ceph_str_hash_rjenkins(s, len);
+	default:
+		return -1;
+	}
+}
+
+const char *ceph_str_hash_name(int type)
+{
+	switch (type) {
+	case CEPH_STR_HASH_LINUX:
+		return "linux";
+	case CEPH_STR_HASH_RJENKINS:
+		return "rjenkins";
+	default:
+		return "unknown";
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/ceph_hash.h linux-libre-2.6.34-gnu1/fs/ceph/ceph_hash.h
--- linux-libre-2.6.33-gnu1/fs/ceph/ceph_hash.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/ceph_hash.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,13 @@
+#ifndef _FS_CEPH_HASH_H
+#define _FS_CEPH_HASH_H
+
+#define CEPH_STR_HASH_LINUX      0x1  /* linux dcache hash */
+#define CEPH_STR_HASH_RJENKINS   0x2  /* robert jenkins' */
+
+extern unsigned ceph_str_hash_linux(const char *s, unsigned len);
+extern unsigned ceph_str_hash_rjenkins(const char *s, unsigned len);
+
+extern unsigned ceph_str_hash(int type, const char *s, unsigned len);
+extern const char *ceph_str_hash_name(int type);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/ceph_strings.c linux-libre-2.6.34-gnu1/fs/ceph/ceph_strings.c
--- linux-libre-2.6.33-gnu1/fs/ceph/ceph_strings.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/ceph_strings.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,176 @@
+/*
+ * Ceph string constants
+ */
+#include "types.h"
+
+const char *ceph_entity_type_name(int type)
+{
+	switch (type) {
+	case CEPH_ENTITY_TYPE_MDS: return "mds";
+	case CEPH_ENTITY_TYPE_OSD: return "osd";
+	case CEPH_ENTITY_TYPE_MON: return "mon";
+	case CEPH_ENTITY_TYPE_CLIENT: return "client";
+	case CEPH_ENTITY_TYPE_ADMIN: return "admin";
+	case CEPH_ENTITY_TYPE_AUTH: return "auth";
+	default: return "unknown";
+	}
+}
+
+const char *ceph_osd_op_name(int op)
+{
+	switch (op) {
+	case CEPH_OSD_OP_READ: return "read";
+	case CEPH_OSD_OP_STAT: return "stat";
+
+	case CEPH_OSD_OP_MASKTRUNC: return "masktrunc";
+
+	case CEPH_OSD_OP_WRITE: return "write";
+	case CEPH_OSD_OP_DELETE: return "delete";
+	case CEPH_OSD_OP_TRUNCATE: return "truncate";
+	case CEPH_OSD_OP_ZERO: return "zero";
+	case CEPH_OSD_OP_WRITEFULL: return "writefull";
+
+	case CEPH_OSD_OP_APPEND: return "append";
+	case CEPH_OSD_OP_STARTSYNC: return "startsync";
+	case CEPH_OSD_OP_SETTRUNC: return "settrunc";
+	case CEPH_OSD_OP_TRIMTRUNC: return "trimtrunc";
+
+	case CEPH_OSD_OP_TMAPUP: return "tmapup";
+	case CEPH_OSD_OP_TMAPGET: return "tmapget";
+	case CEPH_OSD_OP_TMAPPUT: return "tmapput";
+
+	case CEPH_OSD_OP_GETXATTR: return "getxattr";
+	case CEPH_OSD_OP_GETXATTRS: return "getxattrs";
+	case CEPH_OSD_OP_SETXATTR: return "setxattr";
+	case CEPH_OSD_OP_SETXATTRS: return "setxattrs";
+	case CEPH_OSD_OP_RESETXATTRS: return "resetxattrs";
+	case CEPH_OSD_OP_RMXATTR: return "rmxattr";
+
+	case CEPH_OSD_OP_PULL: return "pull";
+	case CEPH_OSD_OP_PUSH: return "push";
+	case CEPH_OSD_OP_BALANCEREADS: return "balance-reads";
+	case CEPH_OSD_OP_UNBALANCEREADS: return "unbalance-reads";
+	case CEPH_OSD_OP_SCRUB: return "scrub";
+
+	case CEPH_OSD_OP_WRLOCK: return "wrlock";
+	case CEPH_OSD_OP_WRUNLOCK: return "wrunlock";
+	case CEPH_OSD_OP_RDLOCK: return "rdlock";
+	case CEPH_OSD_OP_RDUNLOCK: return "rdunlock";
+	case CEPH_OSD_OP_UPLOCK: return "uplock";
+	case CEPH_OSD_OP_DNLOCK: return "dnlock";
+
+	case CEPH_OSD_OP_CALL: return "call";
+
+	case CEPH_OSD_OP_PGLS: return "pgls";
+	}
+	return "???";
+}
+
+const char *ceph_mds_state_name(int s)
+{
+	switch (s) {
+		/* down and out */
+	case CEPH_MDS_STATE_DNE:        return "down:dne";
+	case CEPH_MDS_STATE_STOPPED:    return "down:stopped";
+		/* up and out */
+	case CEPH_MDS_STATE_BOOT:       return "up:boot";
+	case CEPH_MDS_STATE_STANDBY:    return "up:standby";
+	case CEPH_MDS_STATE_STANDBY_REPLAY:    return "up:standby-replay";
+	case CEPH_MDS_STATE_CREATING:   return "up:creating";
+	case CEPH_MDS_STATE_STARTING:   return "up:starting";
+		/* up and in */
+	case CEPH_MDS_STATE_REPLAY:     return "up:replay";
+	case CEPH_MDS_STATE_RESOLVE:    return "up:resolve";
+	case CEPH_MDS_STATE_RECONNECT:  return "up:reconnect";
+	case CEPH_MDS_STATE_REJOIN:     return "up:rejoin";
+	case CEPH_MDS_STATE_CLIENTREPLAY: return "up:clientreplay";
+	case CEPH_MDS_STATE_ACTIVE:     return "up:active";
+	case CEPH_MDS_STATE_STOPPING:   return "up:stopping";
+	}
+	return "???";
+}
+
+const char *ceph_session_op_name(int op)
+{
+	switch (op) {
+	case CEPH_SESSION_REQUEST_OPEN: return "request_open";
+	case CEPH_SESSION_OPEN: return "open";
+	case CEPH_SESSION_REQUEST_CLOSE: return "request_close";
+	case CEPH_SESSION_CLOSE: return "close";
+	case CEPH_SESSION_REQUEST_RENEWCAPS: return "request_renewcaps";
+	case CEPH_SESSION_RENEWCAPS: return "renewcaps";
+	case CEPH_SESSION_STALE: return "stale";
+	case CEPH_SESSION_RECALL_STATE: return "recall_state";
+	}
+	return "???";
+}
+
+const char *ceph_mds_op_name(int op)
+{
+	switch (op) {
+	case CEPH_MDS_OP_LOOKUP:  return "lookup";
+	case CEPH_MDS_OP_LOOKUPHASH:  return "lookuphash";
+	case CEPH_MDS_OP_LOOKUPPARENT:  return "lookupparent";
+	case CEPH_MDS_OP_GETATTR:  return "getattr";
+	case CEPH_MDS_OP_SETXATTR: return "setxattr";
+	case CEPH_MDS_OP_SETATTR: return "setattr";
+	case CEPH_MDS_OP_RMXATTR: return "rmxattr";
+	case CEPH_MDS_OP_READDIR: return "readdir";
+	case CEPH_MDS_OP_MKNOD: return "mknod";
+	case CEPH_MDS_OP_LINK: return "link";
+	case CEPH_MDS_OP_UNLINK: return "unlink";
+	case CEPH_MDS_OP_RENAME: return "rename";
+	case CEPH_MDS_OP_MKDIR: return "mkdir";
+	case CEPH_MDS_OP_RMDIR: return "rmdir";
+	case CEPH_MDS_OP_SYMLINK: return "symlink";
+	case CEPH_MDS_OP_CREATE: return "create";
+	case CEPH_MDS_OP_OPEN: return "open";
+	case CEPH_MDS_OP_LOOKUPSNAP: return "lookupsnap";
+	case CEPH_MDS_OP_LSSNAP: return "lssnap";
+	case CEPH_MDS_OP_MKSNAP: return "mksnap";
+	case CEPH_MDS_OP_RMSNAP: return "rmsnap";
+	}
+	return "???";
+}
+
+const char *ceph_cap_op_name(int op)
+{
+	switch (op) {
+	case CEPH_CAP_OP_GRANT: return "grant";
+	case CEPH_CAP_OP_REVOKE: return "revoke";
+	case CEPH_CAP_OP_TRUNC: return "trunc";
+	case CEPH_CAP_OP_EXPORT: return "export";
+	case CEPH_CAP_OP_IMPORT: return "import";
+	case CEPH_CAP_OP_UPDATE: return "update";
+	case CEPH_CAP_OP_DROP: return "drop";
+	case CEPH_CAP_OP_FLUSH: return "flush";
+	case CEPH_CAP_OP_FLUSH_ACK: return "flush_ack";
+	case CEPH_CAP_OP_FLUSHSNAP: return "flushsnap";
+	case CEPH_CAP_OP_FLUSHSNAP_ACK: return "flushsnap_ack";
+	case CEPH_CAP_OP_RELEASE: return "release";
+	case CEPH_CAP_OP_RENEW: return "renew";
+	}
+	return "???";
+}
+
+const char *ceph_lease_op_name(int o)
+{
+	switch (o) {
+	case CEPH_MDS_LEASE_REVOKE: return "revoke";
+	case CEPH_MDS_LEASE_RELEASE: return "release";
+	case CEPH_MDS_LEASE_RENEW: return "renew";
+	case CEPH_MDS_LEASE_REVOKE_ACK: return "revoke_ack";
+	}
+	return "???";
+}
+
+const char *ceph_snap_op_name(int o)
+{
+	switch (o) {
+	case CEPH_SNAP_OP_UPDATE: return "update";
+	case CEPH_SNAP_OP_CREATE: return "create";
+	case CEPH_SNAP_OP_DESTROY: return "destroy";
+	case CEPH_SNAP_OP_SPLIT: return "split";
+	}
+	return "???";
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/crush/crush.c linux-libre-2.6.34-gnu1/fs/ceph/crush/crush.c
--- linux-libre-2.6.33-gnu1/fs/ceph/crush/crush.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/crush/crush.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,151 @@
+
+#ifdef __KERNEL__
+# include <linux/slab.h>
+#else
+# include <stdlib.h>
+# include <assert.h>
+# define kfree(x) do { if (x) free(x); } while (0)
+# define BUG_ON(x) assert(!(x))
+#endif
+
+#include "crush.h"
+
+const char *crush_bucket_alg_name(int alg)
+{
+	switch (alg) {
+	case CRUSH_BUCKET_UNIFORM: return "uniform";
+	case CRUSH_BUCKET_LIST: return "list";
+	case CRUSH_BUCKET_TREE: return "tree";
+	case CRUSH_BUCKET_STRAW: return "straw";
+	default: return "unknown";
+	}
+}
+
+/**
+ * crush_get_bucket_item_weight - Get weight of an item in given bucket
+ * @b: bucket pointer
+ * @p: item index in bucket
+ */
+int crush_get_bucket_item_weight(struct crush_bucket *b, int p)
+{
+	if (p >= b->size)
+		return 0;
+
+	switch (b->alg) {
+	case CRUSH_BUCKET_UNIFORM:
+		return ((struct crush_bucket_uniform *)b)->item_weight;
+	case CRUSH_BUCKET_LIST:
+		return ((struct crush_bucket_list *)b)->item_weights[p];
+	case CRUSH_BUCKET_TREE:
+		if (p & 1)
+			return ((struct crush_bucket_tree *)b)->node_weights[p];
+		return 0;
+	case CRUSH_BUCKET_STRAW:
+		return ((struct crush_bucket_straw *)b)->item_weights[p];
+	}
+	return 0;
+}
+
+/**
+ * crush_calc_parents - Calculate parent vectors for the given crush map.
+ * @map: crush_map pointer
+ */
+void crush_calc_parents(struct crush_map *map)
+{
+	int i, b, c;
+
+	for (b = 0; b < map->max_buckets; b++) {
+		if (map->buckets[b] == NULL)
+			continue;
+		for (i = 0; i < map->buckets[b]->size; i++) {
+			c = map->buckets[b]->items[i];
+			BUG_ON(c >= map->max_devices ||
+			       c < -map->max_buckets);
+			if (c >= 0)
+				map->device_parents[c] = map->buckets[b]->id;
+			else
+				map->bucket_parents[-1-c] = map->buckets[b]->id;
+		}
+	}
+}
+
+void crush_destroy_bucket_uniform(struct crush_bucket_uniform *b)
+{
+	kfree(b->h.perm);
+	kfree(b->h.items);
+	kfree(b);
+}
+
+void crush_destroy_bucket_list(struct crush_bucket_list *b)
+{
+	kfree(b->item_weights);
+	kfree(b->sum_weights);
+	kfree(b->h.perm);
+	kfree(b->h.items);
+	kfree(b);
+}
+
+void crush_destroy_bucket_tree(struct crush_bucket_tree *b)
+{
+	kfree(b->node_weights);
+	kfree(b);
+}
+
+void crush_destroy_bucket_straw(struct crush_bucket_straw *b)
+{
+	kfree(b->straws);
+	kfree(b->item_weights);
+	kfree(b->h.perm);
+	kfree(b->h.items);
+	kfree(b);
+}
+
+void crush_destroy_bucket(struct crush_bucket *b)
+{
+	switch (b->alg) {
+	case CRUSH_BUCKET_UNIFORM:
+		crush_destroy_bucket_uniform((struct crush_bucket_uniform *)b);
+		break;
+	case CRUSH_BUCKET_LIST:
+		crush_destroy_bucket_list((struct crush_bucket_list *)b);
+		break;
+	case CRUSH_BUCKET_TREE:
+		crush_destroy_bucket_tree((struct crush_bucket_tree *)b);
+		break;
+	case CRUSH_BUCKET_STRAW:
+		crush_destroy_bucket_straw((struct crush_bucket_straw *)b);
+		break;
+	}
+}
+
+/**
+ * crush_destroy - Destroy a crush_map
+ * @map: crush_map pointer
+ */
+void crush_destroy(struct crush_map *map)
+{
+	int b;
+
+	/* buckets */
+	if (map->buckets) {
+		for (b = 0; b < map->max_buckets; b++) {
+			if (map->buckets[b] == NULL)
+				continue;
+			crush_destroy_bucket(map->buckets[b]);
+		}
+		kfree(map->buckets);
+	}
+
+	/* rules */
+	if (map->rules) {
+		for (b = 0; b < map->max_rules; b++)
+			kfree(map->rules[b]);
+		kfree(map->rules);
+	}
+
+	kfree(map->bucket_parents);
+	kfree(map->device_parents);
+	kfree(map);
+}
+
+
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/crush/crush.h linux-libre-2.6.34-gnu1/fs/ceph/crush/crush.h
--- linux-libre-2.6.33-gnu1/fs/ceph/crush/crush.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/crush/crush.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,180 @@
+#ifndef _CRUSH_CRUSH_H
+#define _CRUSH_CRUSH_H
+
+#include <linux/types.h>
+
+/*
+ * CRUSH is a pseudo-random data distribution algorithm that
+ * efficiently distributes input values (typically, data objects)
+ * across a heterogeneous, structured storage cluster.
+ *
+ * The algorithm was originally described in detail in this paper
+ * (although the algorithm has evolved somewhat since then):
+ *
+ *     http://www.ssrc.ucsc.edu/Papers/weil-sc06.pdf
+ *
+ * LGPL2
+ */
+
+
+#define CRUSH_MAGIC 0x00010000ul   /* for detecting algorithm revisions */
+
+
+#define CRUSH_MAX_DEPTH 10  /* max crush hierarchy depth */
+#define CRUSH_MAX_SET   10  /* max size of a mapping result */
+
+
+/*
+ * CRUSH uses user-defined "rules" to describe how inputs should be
+ * mapped to devices.  A rule consists of sequence of steps to perform
+ * to generate the set of output devices.
+ */
+struct crush_rule_step {
+	__u32 op;
+	__s32 arg1;
+	__s32 arg2;
+};
+
+/* step op codes */
+enum {
+	CRUSH_RULE_NOOP = 0,
+	CRUSH_RULE_TAKE = 1,          /* arg1 = value to start with */
+	CRUSH_RULE_CHOOSE_FIRSTN = 2, /* arg1 = num items to pick */
+				      /* arg2 = type */
+	CRUSH_RULE_CHOOSE_INDEP = 3,  /* same */
+	CRUSH_RULE_EMIT = 4,          /* no args */
+	CRUSH_RULE_CHOOSE_LEAF_FIRSTN = 6,
+	CRUSH_RULE_CHOOSE_LEAF_INDEP = 7,
+};
+
+/*
+ * for specifying choose num (arg1) relative to the max parameter
+ * passed to do_rule
+ */
+#define CRUSH_CHOOSE_N            0
+#define CRUSH_CHOOSE_N_MINUS(x)   (-(x))
+
+/*
+ * The rule mask is used to describe what the rule is intended for.
+ * Given a ruleset and size of output set, we search through the
+ * rule list for a matching rule_mask.
+ */
+struct crush_rule_mask {
+	__u8 ruleset;
+	__u8 type;
+	__u8 min_size;
+	__u8 max_size;
+};
+
+struct crush_rule {
+	__u32 len;
+	struct crush_rule_mask mask;
+	struct crush_rule_step steps[0];
+};
+
+#define crush_rule_size(len) (sizeof(struct crush_rule) + \
+			      (len)*sizeof(struct crush_rule_step))
+
+
+
+/*
+ * A bucket is a named container of other items (either devices or
+ * other buckets).  Items within a bucket are chosen using one of a
+ * few different algorithms.  The table summarizes how the speed of
+ * each option measures up against mapping stability when items are
+ * added or removed.
+ *
+ *  Bucket Alg     Speed       Additions    Removals
+ *  ------------------------------------------------
+ *  uniform         O(1)       poor         poor
+ *  list            O(n)       optimal      poor
+ *  tree            O(log n)   good         good
+ *  straw           O(n)       optimal      optimal
+ */
+enum {
+	CRUSH_BUCKET_UNIFORM = 1,
+	CRUSH_BUCKET_LIST = 2,
+	CRUSH_BUCKET_TREE = 3,
+	CRUSH_BUCKET_STRAW = 4
+};
+extern const char *crush_bucket_alg_name(int alg);
+
+struct crush_bucket {
+	__s32 id;        /* this'll be negative */
+	__u16 type;      /* non-zero; type=0 is reserved for devices */
+	__u8 alg;        /* one of CRUSH_BUCKET_* */
+	__u8 hash;       /* which hash function to use, CRUSH_HASH_* */
+	__u32 weight;    /* 16-bit fixed point */
+	__u32 size;      /* num items */
+	__s32 *items;
+
+	/*
+	 * cached random permutation: used for uniform bucket and for
+	 * the linear search fallback for the other bucket types.
+	 */
+	__u32 perm_x;  /* @x for which *perm is defined */
+	__u32 perm_n;  /* num elements of *perm that are permuted/defined */
+	__u32 *perm;
+};
+
+struct crush_bucket_uniform {
+	struct crush_bucket h;
+	__u32 item_weight;  /* 16-bit fixed point; all items equally weighted */
+};
+
+struct crush_bucket_list {
+	struct crush_bucket h;
+	__u32 *item_weights;  /* 16-bit fixed point */
+	__u32 *sum_weights;   /* 16-bit fixed point.  element i is sum
+				 of weights 0..i, inclusive */
+};
+
+struct crush_bucket_tree {
+	struct crush_bucket h;  /* note: h.size is _tree_ size, not number of
+				   actual items */
+	__u8 num_nodes;
+	__u32 *node_weights;
+};
+
+struct crush_bucket_straw {
+	struct crush_bucket h;
+	__u32 *item_weights;   /* 16-bit fixed point */
+	__u32 *straws;         /* 16-bit fixed point */
+};
+
+
+
+/*
+ * CRUSH map includes all buckets, rules, etc.
+ */
+struct crush_map {
+	struct crush_bucket **buckets;
+	struct crush_rule **rules;
+
+	/*
+	 * Parent pointers to identify the parent bucket a device or
+	 * bucket in the hierarchy.  If an item appears more than
+	 * once, this is the _last_ time it appeared (where buckets
+	 * are processed in bucket id order, from -1 on down to
+	 * -max_buckets.
+	 */
+	__u32 *bucket_parents;
+	__u32 *device_parents;
+
+	__s32 max_buckets;
+	__u32 max_rules;
+	__s32 max_devices;
+};
+
+
+/* crush.c */
+extern int crush_get_bucket_item_weight(struct crush_bucket *b, int pos);
+extern void crush_calc_parents(struct crush_map *map);
+extern void crush_destroy_bucket_uniform(struct crush_bucket_uniform *b);
+extern void crush_destroy_bucket_list(struct crush_bucket_list *b);
+extern void crush_destroy_bucket_tree(struct crush_bucket_tree *b);
+extern void crush_destroy_bucket_straw(struct crush_bucket_straw *b);
+extern void crush_destroy_bucket(struct crush_bucket *b);
+extern void crush_destroy(struct crush_map *map);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/crush/hash.c linux-libre-2.6.34-gnu1/fs/ceph/crush/hash.c
--- linux-libre-2.6.33-gnu1/fs/ceph/crush/hash.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/crush/hash.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,149 @@
+
+#include <linux/types.h>
+#include "hash.h"
+
+/*
+ * Robert Jenkins' function for mixing 32-bit values
+ * http://burtleburtle.net/bob/hash/evahash.html
+ * a, b = random bits, c = input and output
+ */
+#define crush_hashmix(a, b, c) do {			\
+		a = a-b;  a = a-c;  a = a^(c>>13);	\
+		b = b-c;  b = b-a;  b = b^(a<<8);	\
+		c = c-a;  c = c-b;  c = c^(b>>13);	\
+		a = a-b;  a = a-c;  a = a^(c>>12);	\
+		b = b-c;  b = b-a;  b = b^(a<<16);	\
+		c = c-a;  c = c-b;  c = c^(b>>5);	\
+		a = a-b;  a = a-c;  a = a^(c>>3);	\
+		b = b-c;  b = b-a;  b = b^(a<<10);	\
+		c = c-a;  c = c-b;  c = c^(b>>15);	\
+	} while (0)
+
+#define crush_hash_seed 1315423911
+
+static __u32 crush_hash32_rjenkins1(__u32 a)
+{
+	__u32 hash = crush_hash_seed ^ a;
+	__u32 b = a;
+	__u32 x = 231232;
+	__u32 y = 1232;
+	crush_hashmix(b, x, hash);
+	crush_hashmix(y, a, hash);
+	return hash;
+}
+
+static __u32 crush_hash32_rjenkins1_2(__u32 a, __u32 b)
+{
+	__u32 hash = crush_hash_seed ^ a ^ b;
+	__u32 x = 231232;
+	__u32 y = 1232;
+	crush_hashmix(a, b, hash);
+	crush_hashmix(x, a, hash);
+	crush_hashmix(b, y, hash);
+	return hash;
+}
+
+static __u32 crush_hash32_rjenkins1_3(__u32 a, __u32 b, __u32 c)
+{
+	__u32 hash = crush_hash_seed ^ a ^ b ^ c;
+	__u32 x = 231232;
+	__u32 y = 1232;
+	crush_hashmix(a, b, hash);
+	crush_hashmix(c, x, hash);
+	crush_hashmix(y, a, hash);
+	crush_hashmix(b, x, hash);
+	crush_hashmix(y, c, hash);
+	return hash;
+}
+
+static __u32 crush_hash32_rjenkins1_4(__u32 a, __u32 b, __u32 c, __u32 d)
+{
+	__u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d;
+	__u32 x = 231232;
+	__u32 y = 1232;
+	crush_hashmix(a, b, hash);
+	crush_hashmix(c, d, hash);
+	crush_hashmix(a, x, hash);
+	crush_hashmix(y, b, hash);
+	crush_hashmix(c, x, hash);
+	crush_hashmix(y, d, hash);
+	return hash;
+}
+
+static __u32 crush_hash32_rjenkins1_5(__u32 a, __u32 b, __u32 c, __u32 d,
+				      __u32 e)
+{
+	__u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d ^ e;
+	__u32 x = 231232;
+	__u32 y = 1232;
+	crush_hashmix(a, b, hash);
+	crush_hashmix(c, d, hash);
+	crush_hashmix(e, x, hash);
+	crush_hashmix(y, a, hash);
+	crush_hashmix(b, x, hash);
+	crush_hashmix(y, c, hash);
+	crush_hashmix(d, x, hash);
+	crush_hashmix(y, e, hash);
+	return hash;
+}
+
+
+__u32 crush_hash32(int type, __u32 a)
+{
+	switch (type) {
+	case CRUSH_HASH_RJENKINS1:
+		return crush_hash32_rjenkins1(a);
+	default:
+		return 0;
+	}
+}
+
+__u32 crush_hash32_2(int type, __u32 a, __u32 b)
+{
+	switch (type) {
+	case CRUSH_HASH_RJENKINS1:
+		return crush_hash32_rjenkins1_2(a, b);
+	default:
+		return 0;
+	}
+}
+
+__u32 crush_hash32_3(int type, __u32 a, __u32 b, __u32 c)
+{
+	switch (type) {
+	case CRUSH_HASH_RJENKINS1:
+		return crush_hash32_rjenkins1_3(a, b, c);
+	default:
+		return 0;
+	}
+}
+
+__u32 crush_hash32_4(int type, __u32 a, __u32 b, __u32 c, __u32 d)
+{
+	switch (type) {
+	case CRUSH_HASH_RJENKINS1:
+		return crush_hash32_rjenkins1_4(a, b, c, d);
+	default:
+		return 0;
+	}
+}
+
+__u32 crush_hash32_5(int type, __u32 a, __u32 b, __u32 c, __u32 d, __u32 e)
+{
+	switch (type) {
+	case CRUSH_HASH_RJENKINS1:
+		return crush_hash32_rjenkins1_5(a, b, c, d, e);
+	default:
+		return 0;
+	}
+}
+
+const char *crush_hash_name(int type)
+{
+	switch (type) {
+	case CRUSH_HASH_RJENKINS1:
+		return "rjenkins1";
+	default:
+		return "unknown";
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/crush/hash.h linux-libre-2.6.34-gnu1/fs/ceph/crush/hash.h
--- linux-libre-2.6.33-gnu1/fs/ceph/crush/hash.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/crush/hash.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,17 @@
+#ifndef _CRUSH_HASH_H
+#define _CRUSH_HASH_H
+
+#define CRUSH_HASH_RJENKINS1   0
+
+#define CRUSH_HASH_DEFAULT CRUSH_HASH_RJENKINS1
+
+extern const char *crush_hash_name(int type);
+
+extern __u32 crush_hash32(int type, __u32 a);
+extern __u32 crush_hash32_2(int type, __u32 a, __u32 b);
+extern __u32 crush_hash32_3(int type, __u32 a, __u32 b, __u32 c);
+extern __u32 crush_hash32_4(int type, __u32 a, __u32 b, __u32 c, __u32 d);
+extern __u32 crush_hash32_5(int type, __u32 a, __u32 b, __u32 c, __u32 d,
+			    __u32 e);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/crush/mapper.c linux-libre-2.6.34-gnu1/fs/ceph/crush/mapper.c
--- linux-libre-2.6.33-gnu1/fs/ceph/crush/mapper.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/crush/mapper.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,596 @@
+
+#ifdef __KERNEL__
+# include <linux/string.h>
+# include <linux/slab.h>
+# include <linux/bug.h>
+# include <linux/kernel.h>
+# ifndef dprintk
+#  define dprintk(args...)
+# endif
+#else
+# include <string.h>
+# include <stdio.h>
+# include <stdlib.h>
+# include <assert.h>
+# define BUG_ON(x) assert(!(x))
+# define dprintk(args...) /* printf(args) */
+# define kmalloc(x, f) malloc(x)
+# define kfree(x) free(x)
+#endif
+
+#include "crush.h"
+#include "hash.h"
+
+/*
+ * Implement the core CRUSH mapping algorithm.
+ */
+
+/**
+ * crush_find_rule - find a crush_rule id for a given ruleset, type, and size.
+ * @map: the crush_map
+ * @ruleset: the storage ruleset id (user defined)
+ * @type: storage ruleset type (user defined)
+ * @size: output set size
+ */
+int crush_find_rule(struct crush_map *map, int ruleset, int type, int size)
+{
+	int i;
+
+	for (i = 0; i < map->max_rules; i++) {
+		if (map->rules[i] &&
+		    map->rules[i]->mask.ruleset == ruleset &&
+		    map->rules[i]->mask.type == type &&
+		    map->rules[i]->mask.min_size <= size &&
+		    map->rules[i]->mask.max_size >= size)
+			return i;
+	}
+	return -1;
+}
+
+
+/*
+ * bucket choose methods
+ *
+ * For each bucket algorithm, we have a "choose" method that, given a
+ * crush input @x and replica position (usually, position in output set) @r,
+ * will produce an item in the bucket.
+ */
+
+/*
+ * Choose based on a random permutation of the bucket.
+ *
+ * We used to use some prime number arithmetic to do this, but it
+ * wasn't very random, and had some other bad behaviors.  Instead, we
+ * calculate an actual random permutation of the bucket members.
+ * Since this is expensive, we optimize for the r=0 case, which
+ * captures the vast majority of calls.
+ */
+static int bucket_perm_choose(struct crush_bucket *bucket,
+			      int x, int r)
+{
+	unsigned pr = r % bucket->size;
+	unsigned i, s;
+
+	/* start a new permutation if @x has changed */
+	if (bucket->perm_x != x || bucket->perm_n == 0) {
+		dprintk("bucket %d new x=%d\n", bucket->id, x);
+		bucket->perm_x = x;
+
+		/* optimize common r=0 case */
+		if (pr == 0) {
+			s = crush_hash32_3(bucket->hash, x, bucket->id, 0) %
+				bucket->size;
+			bucket->perm[0] = s;
+			bucket->perm_n = 0xffff;   /* magic value, see below */
+			goto out;
+		}
+
+		for (i = 0; i < bucket->size; i++)
+			bucket->perm[i] = i;
+		bucket->perm_n = 0;
+	} else if (bucket->perm_n == 0xffff) {
+		/* clean up after the r=0 case above */
+		for (i = 1; i < bucket->size; i++)
+			bucket->perm[i] = i;
+		bucket->perm[bucket->perm[0]] = 0;
+		bucket->perm_n = 1;
+	}
+
+	/* calculate permutation up to pr */
+	for (i = 0; i < bucket->perm_n; i++)
+		dprintk(" perm_choose have %d: %d\n", i, bucket->perm[i]);
+	while (bucket->perm_n <= pr) {
+		unsigned p = bucket->perm_n;
+		/* no point in swapping the final entry */
+		if (p < bucket->size - 1) {
+			i = crush_hash32_3(bucket->hash, x, bucket->id, p) %
+				(bucket->size - p);
+			if (i) {
+				unsigned t = bucket->perm[p + i];
+				bucket->perm[p + i] = bucket->perm[p];
+				bucket->perm[p] = t;
+			}
+			dprintk(" perm_choose swap %d with %d\n", p, p+i);
+		}
+		bucket->perm_n++;
+	}
+	for (i = 0; i < bucket->size; i++)
+		dprintk(" perm_choose  %d: %d\n", i, bucket->perm[i]);
+
+	s = bucket->perm[pr];
+out:
+	dprintk(" perm_choose %d sz=%d x=%d r=%d (%d) s=%d\n", bucket->id,
+		bucket->size, x, r, pr, s);
+	return bucket->items[s];
+}
+
+/* uniform */
+static int bucket_uniform_choose(struct crush_bucket_uniform *bucket,
+				 int x, int r)
+{
+	return bucket_perm_choose(&bucket->h, x, r);
+}
+
+/* list */
+static int bucket_list_choose(struct crush_bucket_list *bucket,
+			      int x, int r)
+{
+	int i;
+
+	for (i = bucket->h.size-1; i >= 0; i--) {
+		__u64 w = crush_hash32_4(bucket->h.hash,x, bucket->h.items[i],
+					 r, bucket->h.id);
+		w &= 0xffff;
+		dprintk("list_choose i=%d x=%d r=%d item %d weight %x "
+			"sw %x rand %llx",
+			i, x, r, bucket->h.items[i], bucket->item_weights[i],
+			bucket->sum_weights[i], w);
+		w *= bucket->sum_weights[i];
+		w = w >> 16;
+		/*dprintk(" scaled %llx\n", w);*/
+		if (w < bucket->item_weights[i])
+			return bucket->h.items[i];
+	}
+
+	BUG_ON(1);
+	return 0;
+}
+
+
+/* (binary) tree */
+static int height(int n)
+{
+	int h = 0;
+	while ((n & 1) == 0) {
+		h++;
+		n = n >> 1;
+	}
+	return h;
+}
+
+static int left(int x)
+{
+	int h = height(x);
+	return x - (1 << (h-1));
+}
+
+static int right(int x)
+{
+	int h = height(x);
+	return x + (1 << (h-1));
+}
+
+static int terminal(int x)
+{
+	return x & 1;
+}
+
+static int bucket_tree_choose(struct crush_bucket_tree *bucket,
+			      int x, int r)
+{
+	int n, l;
+	__u32 w;
+	__u64 t;
+
+	/* start at root */
+	n = bucket->num_nodes >> 1;
+
+	while (!terminal(n)) {
+		/* pick point in [0, w) */
+		w = bucket->node_weights[n];
+		t = (__u64)crush_hash32_4(bucket->h.hash, x, n, r,
+					  bucket->h.id) * (__u64)w;
+		t = t >> 32;
+
+		/* descend to the left or right? */
+		l = left(n);
+		if (t < bucket->node_weights[l])
+			n = l;
+		else
+			n = right(n);
+	}
+
+	return bucket->h.items[n >> 1];
+}
+
+
+/* straw */
+
+static int bucket_straw_choose(struct crush_bucket_straw *bucket,
+			       int x, int r)
+{
+	int i;
+	int high = 0;
+	__u64 high_draw = 0;
+	__u64 draw;
+
+	for (i = 0; i < bucket->h.size; i++) {
+		draw = crush_hash32_3(bucket->h.hash, x, bucket->h.items[i], r);
+		draw &= 0xffff;
+		draw *= bucket->straws[i];
+		if (i == 0 || draw > high_draw) {
+			high = i;
+			high_draw = draw;
+		}
+	}
+	return bucket->h.items[high];
+}
+
+static int crush_bucket_choose(struct crush_bucket *in, int x, int r)
+{
+	dprintk("choose %d x=%d r=%d\n", in->id, x, r);
+	switch (in->alg) {
+	case CRUSH_BUCKET_UNIFORM:
+		return bucket_uniform_choose((struct crush_bucket_uniform *)in,
+					  x, r);
+	case CRUSH_BUCKET_LIST:
+		return bucket_list_choose((struct crush_bucket_list *)in,
+					  x, r);
+	case CRUSH_BUCKET_TREE:
+		return bucket_tree_choose((struct crush_bucket_tree *)in,
+					  x, r);
+	case CRUSH_BUCKET_STRAW:
+		return bucket_straw_choose((struct crush_bucket_straw *)in,
+					   x, r);
+	default:
+		BUG_ON(1);
+		return in->items[0];
+	}
+}
+
+/*
+ * true if device is marked "out" (failed, fully offloaded)
+ * of the cluster
+ */
+static int is_out(struct crush_map *map, __u32 *weight, int item, int x)
+{
+	if (weight[item] >= 0x1000)
+		return 0;
+	if (weight[item] == 0)
+		return 1;
+	if ((crush_hash32_2(CRUSH_HASH_RJENKINS1, x, item) & 0xffff)
+	    < weight[item])
+		return 0;
+	return 1;
+}
+
+/**
+ * crush_choose - choose numrep distinct items of given type
+ * @map: the crush_map
+ * @bucket: the bucket we are choose an item from
+ * @x: crush input value
+ * @numrep: the number of items to choose
+ * @type: the type of item to choose
+ * @out: pointer to output vector
+ * @outpos: our position in that vector
+ * @firstn: true if choosing "first n" items, false if choosing "indep"
+ * @recurse_to_leaf: true if we want one device under each item of given type
+ * @out2: second output vector for leaf items (if @recurse_to_leaf)
+ */
+static int crush_choose(struct crush_map *map,
+			struct crush_bucket *bucket,
+			__u32 *weight,
+			int x, int numrep, int type,
+			int *out, int outpos,
+			int firstn, int recurse_to_leaf,
+			int *out2)
+{
+	int rep;
+	int ftotal, flocal;
+	int retry_descent, retry_bucket, skip_rep;
+	struct crush_bucket *in = bucket;
+	int r;
+	int i;
+	int item = 0;
+	int itemtype;
+	int collide, reject;
+	const int orig_tries = 5; /* attempts before we fall back to search */
+	dprintk("choose bucket %d x %d outpos %d\n", bucket->id, x, outpos);
+
+	for (rep = outpos; rep < numrep; rep++) {
+		/* keep trying until we get a non-out, non-colliding item */
+		ftotal = 0;
+		skip_rep = 0;
+		do {
+			retry_descent = 0;
+			in = bucket;               /* initial bucket */
+
+			/* choose through intervening buckets */
+			flocal = 0;
+			do {
+				collide = 0;
+				retry_bucket = 0;
+				r = rep;
+				if (in->alg == CRUSH_BUCKET_UNIFORM) {
+					/* be careful */
+					if (firstn || numrep >= in->size)
+						/* r' = r + f_total */
+						r += ftotal;
+					else if (in->size % numrep == 0)
+						/* r'=r+(n+1)*f_local */
+						r += (numrep+1) *
+							(flocal+ftotal);
+					else
+						/* r' = r + n*f_local */
+						r += numrep * (flocal+ftotal);
+				} else {
+					if (firstn)
+						/* r' = r + f_total */
+						r += ftotal;
+					else
+						/* r' = r + n*f_local */
+						r += numrep * (flocal+ftotal);
+				}
+
+				/* bucket choose */
+				if (in->size == 0) {
+					reject = 1;
+					goto reject;
+				}
+				if (flocal >= (in->size>>1) &&
+				    flocal > orig_tries)
+					item = bucket_perm_choose(in, x, r);
+				else
+					item = crush_bucket_choose(in, x, r);
+				BUG_ON(item >= map->max_devices);
+
+				/* desired type? */
+				if (item < 0)
+					itemtype = map->buckets[-1-item]->type;
+				else
+					itemtype = 0;
+				dprintk("  item %d type %d\n", item, itemtype);
+
+				/* keep going? */
+				if (itemtype != type) {
+					BUG_ON(item >= 0 ||
+					       (-1-item) >= map->max_buckets);
+					in = map->buckets[-1-item];
+					continue;
+				}
+
+				/* collision? */
+				for (i = 0; i < outpos; i++) {
+					if (out[i] == item) {
+						collide = 1;
+						break;
+					}
+				}
+
+				if (recurse_to_leaf &&
+				    item < 0 &&
+				    crush_choose(map, map->buckets[-1-item],
+						 weight,
+						 x, outpos+1, 0,
+						 out2, outpos,
+						 firstn, 0, NULL) <= outpos) {
+					reject = 1;
+				} else {
+					/* out? */
+					if (itemtype == 0)
+						reject = is_out(map, weight,
+								item, x);
+					else
+						reject = 0;
+				}
+
+reject:
+				if (reject || collide) {
+					ftotal++;
+					flocal++;
+
+					if (collide && flocal < 3)
+						/* retry locally a few times */
+						retry_bucket = 1;
+					else if (flocal < in->size + orig_tries)
+						/* exhaustive bucket search */
+						retry_bucket = 1;
+					else if (ftotal < 20)
+						/* then retry descent */
+						retry_descent = 1;
+					else
+						/* else give up */
+						skip_rep = 1;
+					dprintk("  reject %d  collide %d  "
+						"ftotal %d  flocal %d\n",
+						reject, collide, ftotal,
+						flocal);
+				}
+			} while (retry_bucket);
+		} while (retry_descent);
+
+		if (skip_rep) {
+			dprintk("skip rep\n");
+			continue;
+		}
+
+		dprintk("choose got %d\n", item);
+		out[outpos] = item;
+		outpos++;
+	}
+
+	dprintk("choose returns %d\n", outpos);
+	return outpos;
+}
+
+
+/**
+ * crush_do_rule - calculate a mapping with the given input and rule
+ * @map: the crush_map
+ * @ruleno: the rule id
+ * @x: hash input
+ * @result: pointer to result vector
+ * @result_max: maximum result size
+ * @force: force initial replica choice; -1 for none
+ */
+int crush_do_rule(struct crush_map *map,
+		  int ruleno, int x, int *result, int result_max,
+		  int force, __u32 *weight)
+{
+	int result_len;
+	int force_context[CRUSH_MAX_DEPTH];
+	int force_pos = -1;
+	int a[CRUSH_MAX_SET];
+	int b[CRUSH_MAX_SET];
+	int c[CRUSH_MAX_SET];
+	int recurse_to_leaf;
+	int *w;
+	int wsize = 0;
+	int *o;
+	int osize;
+	int *tmp;
+	struct crush_rule *rule;
+	int step;
+	int i, j;
+	int numrep;
+	int firstn;
+	int rc = -1;
+
+	BUG_ON(ruleno >= map->max_rules);
+
+	rule = map->rules[ruleno];
+	result_len = 0;
+	w = a;
+	o = b;
+
+	/*
+	 * determine hierarchical context of force, if any.  note
+	 * that this may or may not correspond to the specific types
+	 * referenced by the crush rule.
+	 */
+	if (force >= 0) {
+		if (force >= map->max_devices ||
+		    map->device_parents[force] == 0) {
+			/*dprintk("CRUSH: forcefed device dne\n");*/
+			rc = -1;  /* force fed device dne */
+			goto out;
+		}
+		if (!is_out(map, weight, force, x)) {
+			while (1) {
+				force_context[++force_pos] = force;
+				if (force >= 0)
+					force = map->device_parents[force];
+				else
+					force = map->bucket_parents[-1-force];
+				if (force == 0)
+					break;
+			}
+		}
+	}
+
+	for (step = 0; step < rule->len; step++) {
+		firstn = 0;
+		switch (rule->steps[step].op) {
+		case CRUSH_RULE_TAKE:
+			w[0] = rule->steps[step].arg1;
+			if (force_pos >= 0) {
+				BUG_ON(force_context[force_pos] != w[0]);
+				force_pos--;
+			}
+			wsize = 1;
+			break;
+
+		case CRUSH_RULE_CHOOSE_LEAF_FIRSTN:
+		case CRUSH_RULE_CHOOSE_FIRSTN:
+			firstn = 1;
+		case CRUSH_RULE_CHOOSE_LEAF_INDEP:
+		case CRUSH_RULE_CHOOSE_INDEP:
+			BUG_ON(wsize == 0);
+
+			recurse_to_leaf =
+				rule->steps[step].op ==
+				 CRUSH_RULE_CHOOSE_LEAF_FIRSTN ||
+				rule->steps[step].op ==
+				CRUSH_RULE_CHOOSE_LEAF_INDEP;
+
+			/* reset output */
+			osize = 0;
+
+			for (i = 0; i < wsize; i++) {
+				/*
+				 * see CRUSH_N, CRUSH_N_MINUS macros.
+				 * basically, numrep <= 0 means relative to
+				 * the provided result_max
+				 */
+				numrep = rule->steps[step].arg1;
+				if (numrep <= 0) {
+					numrep += result_max;
+					if (numrep <= 0)
+						continue;
+				}
+				j = 0;
+				if (osize == 0 && force_pos >= 0) {
+					/* skip any intermediate types */
+					while (force_pos &&
+					       force_context[force_pos] < 0 &&
+					       rule->steps[step].arg2 !=
+					       map->buckets[-1 -
+					       force_context[force_pos]]->type)
+						force_pos--;
+					o[osize] = force_context[force_pos];
+					if (recurse_to_leaf)
+						c[osize] = force_context[0];
+					j++;
+					force_pos--;
+				}
+				osize += crush_choose(map,
+						      map->buckets[-1-w[i]],
+						      weight,
+						      x, numrep,
+						      rule->steps[step].arg2,
+						      o+osize, j,
+						      firstn,
+						      recurse_to_leaf, c+osize);
+			}
+
+			if (recurse_to_leaf)
+				/* copy final _leaf_ values to output set */
+				memcpy(o, c, osize*sizeof(*o));
+
+			/* swap t and w arrays */
+			tmp = o;
+			o = w;
+			w = tmp;
+			wsize = osize;
+			break;
+
+
+		case CRUSH_RULE_EMIT:
+			for (i = 0; i < wsize && result_len < result_max; i++) {
+				result[result_len] = w[i];
+				result_len++;
+			}
+			wsize = 0;
+			break;
+
+		default:
+			BUG_ON(1);
+		}
+	}
+	rc = result_len;
+
+out:
+	return rc;
+}
+
+
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/crush/mapper.h linux-libre-2.6.34-gnu1/fs/ceph/crush/mapper.h
--- linux-libre-2.6.33-gnu1/fs/ceph/crush/mapper.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/crush/mapper.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,20 @@
+#ifndef _CRUSH_MAPPER_H
+#define _CRUSH_MAPPER_H
+
+/*
+ * CRUSH functions for find rules and then mapping an input to an
+ * output set.
+ *
+ * LGPL2
+ */
+
+#include "crush.h"
+
+extern int crush_find_rule(struct crush_map *map, int pool, int type, int size);
+extern int crush_do_rule(struct crush_map *map,
+			 int ruleno,
+			 int x, int *result, int result_max,
+			 int forcefeed,    /* -1 for none */
+			 __u32 *weights);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/crypto.c linux-libre-2.6.34-gnu1/fs/ceph/crypto.c
--- linux-libre-2.6.33-gnu1/fs/ceph/crypto.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/crypto.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,409 @@
+
+#include "ceph_debug.h"
+
+#include <linux/err.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <crypto/hash.h>
+
+#include "crypto.h"
+#include "decode.h"
+
+int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
+{
+	if (*p + sizeof(u16) + sizeof(key->created) +
+	    sizeof(u16) + key->len > end)
+		return -ERANGE;
+	ceph_encode_16(p, key->type);
+	ceph_encode_copy(p, &key->created, sizeof(key->created));
+	ceph_encode_16(p, key->len);
+	ceph_encode_copy(p, key->key, key->len);
+	return 0;
+}
+
+int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end)
+{
+	ceph_decode_need(p, end, 2*sizeof(u16) + sizeof(key->created), bad);
+	key->type = ceph_decode_16(p);
+	ceph_decode_copy(p, &key->created, sizeof(key->created));
+	key->len = ceph_decode_16(p);
+	ceph_decode_need(p, end, key->len, bad);
+	key->key = kmalloc(key->len, GFP_NOFS);
+	if (!key->key)
+		return -ENOMEM;
+	ceph_decode_copy(p, key->key, key->len);
+	return 0;
+
+bad:
+	dout("failed to decode crypto key\n");
+	return -EINVAL;
+}
+
+int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey)
+{
+	int inlen = strlen(inkey);
+	int blen = inlen * 3 / 4;
+	void *buf, *p;
+	int ret;
+
+	dout("crypto_key_unarmor %s\n", inkey);
+	buf = kmalloc(blen, GFP_NOFS);
+	if (!buf)
+		return -ENOMEM;
+	blen = ceph_unarmor(buf, inkey, inkey+inlen);
+	if (blen < 0) {
+		kfree(buf);
+		return blen;
+	}
+
+	p = buf;
+	ret = ceph_crypto_key_decode(key, &p, p + blen);
+	kfree(buf);
+	if (ret)
+		return ret;
+	dout("crypto_key_unarmor key %p type %d len %d\n", key,
+	     key->type, key->len);
+	return 0;
+}
+
+
+
+#define AES_KEY_SIZE 16
+
+static struct crypto_blkcipher *ceph_crypto_alloc_cipher(void)
+{
+	return crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
+}
+
+const u8 *aes_iv = "cephsageyudagreg";
+
+int ceph_aes_encrypt(const void *key, int key_len, void *dst, size_t *dst_len,
+		     const void *src, size_t src_len)
+{
+	struct scatterlist sg_in[2], sg_out[1];
+	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
+	struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
+	int ret;
+	void *iv;
+	int ivsize;
+	size_t zero_padding = (0x10 - (src_len & 0x0f));
+	char pad[16];
+
+	if (IS_ERR(tfm))
+		return PTR_ERR(tfm);
+
+	memset(pad, zero_padding, zero_padding);
+
+	*dst_len = src_len + zero_padding;
+
+	crypto_blkcipher_setkey((void *)tfm, key, key_len);
+	sg_init_table(sg_in, 2);
+	sg_set_buf(&sg_in[0], src, src_len);
+	sg_set_buf(&sg_in[1], pad, zero_padding);
+	sg_init_table(sg_out, 1);
+	sg_set_buf(sg_out, dst, *dst_len);
+	iv = crypto_blkcipher_crt(tfm)->iv;
+	ivsize = crypto_blkcipher_ivsize(tfm);
+
+	memcpy(iv, aes_iv, ivsize);
+	/*
+	print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
+		       key, key_len, 1);
+	print_hex_dump(KERN_ERR, "enc src: ", DUMP_PREFIX_NONE, 16, 1,
+			src, src_len, 1);
+	print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
+			pad, zero_padding, 1);
+	*/
+	ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
+				     src_len + zero_padding);
+	crypto_free_blkcipher(tfm);
+	if (ret < 0)
+		pr_err("ceph_aes_crypt failed %d\n", ret);
+	/*
+	print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
+		       dst, *dst_len, 1);
+	*/
+	return 0;
+}
+
+int ceph_aes_encrypt2(const void *key, int key_len, void *dst, size_t *dst_len,
+		      const void *src1, size_t src1_len,
+		      const void *src2, size_t src2_len)
+{
+	struct scatterlist sg_in[3], sg_out[1];
+	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
+	struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
+	int ret;
+	void *iv;
+	int ivsize;
+	size_t zero_padding = (0x10 - ((src1_len + src2_len) & 0x0f));
+	char pad[16];
+
+	if (IS_ERR(tfm))
+		return PTR_ERR(tfm);
+
+	memset(pad, zero_padding, zero_padding);
+
+	*dst_len = src1_len + src2_len + zero_padding;
+
+	crypto_blkcipher_setkey((void *)tfm, key, key_len);
+	sg_init_table(sg_in, 3);
+	sg_set_buf(&sg_in[0], src1, src1_len);
+	sg_set_buf(&sg_in[1], src2, src2_len);
+	sg_set_buf(&sg_in[2], pad, zero_padding);
+	sg_init_table(sg_out, 1);
+	sg_set_buf(sg_out, dst, *dst_len);
+	iv = crypto_blkcipher_crt(tfm)->iv;
+	ivsize = crypto_blkcipher_ivsize(tfm);
+
+	memcpy(iv, aes_iv, ivsize);
+	/*
+	print_hex_dump(KERN_ERR, "enc  key: ", DUMP_PREFIX_NONE, 16, 1,
+		       key, key_len, 1);
+	print_hex_dump(KERN_ERR, "enc src1: ", DUMP_PREFIX_NONE, 16, 1,
+			src1, src1_len, 1);
+	print_hex_dump(KERN_ERR, "enc src2: ", DUMP_PREFIX_NONE, 16, 1,
+			src2, src2_len, 1);
+	print_hex_dump(KERN_ERR, "enc  pad: ", DUMP_PREFIX_NONE, 16, 1,
+			pad, zero_padding, 1);
+	*/
+	ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
+				     src1_len + src2_len + zero_padding);
+	crypto_free_blkcipher(tfm);
+	if (ret < 0)
+		pr_err("ceph_aes_crypt2 failed %d\n", ret);
+	/*
+	print_hex_dump(KERN_ERR, "enc  out: ", DUMP_PREFIX_NONE, 16, 1,
+		       dst, *dst_len, 1);
+	*/
+	return 0;
+}
+
+int ceph_aes_decrypt(const void *key, int key_len, void *dst, size_t *dst_len,
+		     const void *src, size_t src_len)
+{
+	struct scatterlist sg_in[1], sg_out[2];
+	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
+	struct blkcipher_desc desc = { .tfm = tfm };
+	char pad[16];
+	void *iv;
+	int ivsize;
+	int ret;
+	int last_byte;
+
+	if (IS_ERR(tfm))
+		return PTR_ERR(tfm);
+
+	crypto_blkcipher_setkey((void *)tfm, key, key_len);
+	sg_init_table(sg_in, 1);
+	sg_init_table(sg_out, 2);
+	sg_set_buf(sg_in, src, src_len);
+	sg_set_buf(&sg_out[0], dst, *dst_len);
+	sg_set_buf(&sg_out[1], pad, sizeof(pad));
+
+	iv = crypto_blkcipher_crt(tfm)->iv;
+	ivsize = crypto_blkcipher_ivsize(tfm);
+
+	memcpy(iv, aes_iv, ivsize);
+
+	/*
+	print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
+		       key, key_len, 1);
+	print_hex_dump(KERN_ERR, "dec  in: ", DUMP_PREFIX_NONE, 16, 1,
+		       src, src_len, 1);
+	*/
+
+	ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
+	crypto_free_blkcipher(tfm);
+	if (ret < 0) {
+		pr_err("ceph_aes_decrypt failed %d\n", ret);
+		return ret;
+	}
+
+	if (src_len <= *dst_len)
+		last_byte = ((char *)dst)[src_len - 1];
+	else
+		last_byte = pad[src_len - *dst_len - 1];
+	if (last_byte <= 16 && src_len >= last_byte) {
+		*dst_len = src_len - last_byte;
+	} else {
+		pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
+		       last_byte, (int)src_len);
+		return -EPERM;  /* bad padding */
+	}
+	/*
+	print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1,
+		       dst, *dst_len, 1);
+	*/
+	return 0;
+}
+
+int ceph_aes_decrypt2(const void *key, int key_len,
+		      void *dst1, size_t *dst1_len,
+		      void *dst2, size_t *dst2_len,
+		      const void *src, size_t src_len)
+{
+	struct scatterlist sg_in[1], sg_out[3];
+	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
+	struct blkcipher_desc desc = { .tfm = tfm };
+	char pad[16];
+	void *iv;
+	int ivsize;
+	int ret;
+	int last_byte;
+
+	if (IS_ERR(tfm))
+		return PTR_ERR(tfm);
+
+	sg_init_table(sg_in, 1);
+	sg_set_buf(sg_in, src, src_len);
+	sg_init_table(sg_out, 3);
+	sg_set_buf(&sg_out[0], dst1, *dst1_len);
+	sg_set_buf(&sg_out[1], dst2, *dst2_len);
+	sg_set_buf(&sg_out[2], pad, sizeof(pad));
+
+	crypto_blkcipher_setkey((void *)tfm, key, key_len);
+	iv = crypto_blkcipher_crt(tfm)->iv;
+	ivsize = crypto_blkcipher_ivsize(tfm);
+
+	memcpy(iv, aes_iv, ivsize);
+
+	/*
+	print_hex_dump(KERN_ERR, "dec  key: ", DUMP_PREFIX_NONE, 16, 1,
+		       key, key_len, 1);
+	print_hex_dump(KERN_ERR, "dec   in: ", DUMP_PREFIX_NONE, 16, 1,
+		       src, src_len, 1);
+	*/
+
+	ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
+	crypto_free_blkcipher(tfm);
+	if (ret < 0) {
+		pr_err("ceph_aes_decrypt failed %d\n", ret);
+		return ret;
+	}
+
+	if (src_len <= *dst1_len)
+		last_byte = ((char *)dst1)[src_len - 1];
+	else if (src_len <= *dst1_len + *dst2_len)
+		last_byte = ((char *)dst2)[src_len - *dst1_len - 1];
+	else
+		last_byte = pad[src_len - *dst1_len - *dst2_len - 1];
+	if (last_byte <= 16 && src_len >= last_byte) {
+		src_len -= last_byte;
+	} else {
+		pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
+		       last_byte, (int)src_len);
+		return -EPERM;  /* bad padding */
+	}
+
+	if (src_len < *dst1_len) {
+		*dst1_len = src_len;
+		*dst2_len = 0;
+	} else {
+		*dst2_len = src_len - *dst1_len;
+	}
+	/*
+	print_hex_dump(KERN_ERR, "dec  out1: ", DUMP_PREFIX_NONE, 16, 1,
+		       dst1, *dst1_len, 1);
+	print_hex_dump(KERN_ERR, "dec  out2: ", DUMP_PREFIX_NONE, 16, 1,
+		       dst2, *dst2_len, 1);
+	*/
+
+	return 0;
+}
+
+
+int ceph_decrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
+		 const void *src, size_t src_len)
+{
+	switch (secret->type) {
+	case CEPH_CRYPTO_NONE:
+		if (*dst_len < src_len)
+			return -ERANGE;
+		memcpy(dst, src, src_len);
+		*dst_len = src_len;
+		return 0;
+
+	case CEPH_CRYPTO_AES:
+		return ceph_aes_decrypt(secret->key, secret->len, dst,
+					dst_len, src, src_len);
+
+	default:
+		return -EINVAL;
+	}
+}
+
+int ceph_decrypt2(struct ceph_crypto_key *secret,
+			void *dst1, size_t *dst1_len,
+			void *dst2, size_t *dst2_len,
+			const void *src, size_t src_len)
+{
+	size_t t;
+
+	switch (secret->type) {
+	case CEPH_CRYPTO_NONE:
+		if (*dst1_len + *dst2_len < src_len)
+			return -ERANGE;
+		t = min(*dst1_len, src_len);
+		memcpy(dst1, src, t);
+		*dst1_len = t;
+		src += t;
+		src_len -= t;
+		if (src_len) {
+			t = min(*dst2_len, src_len);
+			memcpy(dst2, src, t);
+			*dst2_len = t;
+		}
+		return 0;
+
+	case CEPH_CRYPTO_AES:
+		return ceph_aes_decrypt2(secret->key, secret->len,
+					 dst1, dst1_len, dst2, dst2_len,
+					 src, src_len);
+
+	default:
+		return -EINVAL;
+	}
+}
+
+int ceph_encrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
+		 const void *src, size_t src_len)
+{
+	switch (secret->type) {
+	case CEPH_CRYPTO_NONE:
+		if (*dst_len < src_len)
+			return -ERANGE;
+		memcpy(dst, src, src_len);
+		*dst_len = src_len;
+		return 0;
+
+	case CEPH_CRYPTO_AES:
+		return ceph_aes_encrypt(secret->key, secret->len, dst,
+					dst_len, src, src_len);
+
+	default:
+		return -EINVAL;
+	}
+}
+
+int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
+		  const void *src1, size_t src1_len,
+		  const void *src2, size_t src2_len)
+{
+	switch (secret->type) {
+	case CEPH_CRYPTO_NONE:
+		if (*dst_len < src1_len + src2_len)
+			return -ERANGE;
+		memcpy(dst, src1, src1_len);
+		memcpy(dst + src1_len, src2, src2_len);
+		*dst_len = src1_len + src2_len;
+		return 0;
+
+	case CEPH_CRYPTO_AES:
+		return ceph_aes_encrypt2(secret->key, secret->len, dst, dst_len,
+					 src1, src1_len, src2, src2_len);
+
+	default:
+		return -EINVAL;
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/crypto.h linux-libre-2.6.34-gnu1/fs/ceph/crypto.h
--- linux-libre-2.6.33-gnu1/fs/ceph/crypto.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/crypto.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,48 @@
+#ifndef _FS_CEPH_CRYPTO_H
+#define _FS_CEPH_CRYPTO_H
+
+#include "types.h"
+#include "buffer.h"
+
+/*
+ * cryptographic secret
+ */
+struct ceph_crypto_key {
+	int type;
+	struct ceph_timespec created;
+	int len;
+	void *key;
+};
+
+static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
+{
+	kfree(key->key);
+}
+
+extern int ceph_crypto_key_encode(struct ceph_crypto_key *key,
+				  void **p, void *end);
+extern int ceph_crypto_key_decode(struct ceph_crypto_key *key,
+				  void **p, void *end);
+extern int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *in);
+
+/* crypto.c */
+extern int ceph_decrypt(struct ceph_crypto_key *secret,
+			void *dst, size_t *dst_len,
+			const void *src, size_t src_len);
+extern int ceph_encrypt(struct ceph_crypto_key *secret,
+			void *dst, size_t *dst_len,
+			const void *src, size_t src_len);
+extern int ceph_decrypt2(struct ceph_crypto_key *secret,
+			void *dst1, size_t *dst1_len,
+			void *dst2, size_t *dst2_len,
+			const void *src, size_t src_len);
+extern int ceph_encrypt2(struct ceph_crypto_key *secret,
+			 void *dst, size_t *dst_len,
+			 const void *src1, size_t src1_len,
+			 const void *src2, size_t src2_len);
+
+/* armor.c */
+extern int ceph_armor(char *dst, const void *src, const void *end);
+extern int ceph_unarmor(void *dst, const char *src, const char *end);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/debugfs.c linux-libre-2.6.34-gnu1/fs/ceph/debugfs.c
--- linux-libre-2.6.33-gnu1/fs/ceph/debugfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/debugfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,484 @@
+#include "ceph_debug.h"
+
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/ctype.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#include "super.h"
+#include "mds_client.h"
+#include "mon_client.h"
+#include "auth.h"
+
+#ifdef CONFIG_DEBUG_FS
+
+/*
+ * Implement /sys/kernel/debug/ceph fun
+ *
+ * /sys/kernel/debug/ceph/client*  - an instance of the ceph client
+ *      .../osdmap      - current osdmap
+ *      .../mdsmap      - current mdsmap
+ *      .../monmap      - current monmap
+ *      .../osdc        - active osd requests
+ *      .../mdsc        - active mds requests
+ *      .../monc        - mon client state
+ *      .../dentry_lru  - dump contents of dentry lru
+ *      .../caps        - expose cap (reservation) stats
+ *      .../bdi         - symlink to ../../bdi/something
+ */
+
+static struct dentry *ceph_debugfs_dir;
+
+static int monmap_show(struct seq_file *s, void *p)
+{
+	int i;
+	struct ceph_client *client = s->private;
+
+	if (client->monc.monmap == NULL)
+		return 0;
+
+	seq_printf(s, "epoch %d\n", client->monc.monmap->epoch);
+	for (i = 0; i < client->monc.monmap->num_mon; i++) {
+		struct ceph_entity_inst *inst =
+			&client->monc.monmap->mon_inst[i];
+
+		seq_printf(s, "\t%s%lld\t%s\n",
+			   ENTITY_NAME(inst->name),
+			   pr_addr(&inst->addr.in_addr));
+	}
+	return 0;
+}
+
+static int mdsmap_show(struct seq_file *s, void *p)
+{
+	int i;
+	struct ceph_client *client = s->private;
+
+	if (client->mdsc.mdsmap == NULL)
+		return 0;
+	seq_printf(s, "epoch %d\n", client->mdsc.mdsmap->m_epoch);
+	seq_printf(s, "root %d\n", client->mdsc.mdsmap->m_root);
+	seq_printf(s, "session_timeout %d\n",
+		       client->mdsc.mdsmap->m_session_timeout);
+	seq_printf(s, "session_autoclose %d\n",
+		       client->mdsc.mdsmap->m_session_autoclose);
+	for (i = 0; i < client->mdsc.mdsmap->m_max_mds; i++) {
+		struct ceph_entity_addr *addr =
+			&client->mdsc.mdsmap->m_info[i].addr;
+		int state = client->mdsc.mdsmap->m_info[i].state;
+
+		seq_printf(s, "\tmds%d\t%s\t(%s)\n", i, pr_addr(&addr->in_addr),
+			       ceph_mds_state_name(state));
+	}
+	return 0;
+}
+
+static int osdmap_show(struct seq_file *s, void *p)
+{
+	int i;
+	struct ceph_client *client = s->private;
+	struct rb_node *n;
+
+	if (client->osdc.osdmap == NULL)
+		return 0;
+	seq_printf(s, "epoch %d\n", client->osdc.osdmap->epoch);
+	seq_printf(s, "flags%s%s\n",
+		   (client->osdc.osdmap->flags & CEPH_OSDMAP_NEARFULL) ?
+		   " NEARFULL" : "",
+		   (client->osdc.osdmap->flags & CEPH_OSDMAP_FULL) ?
+		   " FULL" : "");
+	for (n = rb_first(&client->osdc.osdmap->pg_pools); n; n = rb_next(n)) {
+		struct ceph_pg_pool_info *pool =
+			rb_entry(n, struct ceph_pg_pool_info, node);
+		seq_printf(s, "pg_pool %d pg_num %d / %d, lpg_num %d / %d\n",
+			   pool->id, pool->v.pg_num, pool->pg_num_mask,
+			   pool->v.lpg_num, pool->lpg_num_mask);
+	}
+	for (i = 0; i < client->osdc.osdmap->max_osd; i++) {
+		struct ceph_entity_addr *addr =
+			&client->osdc.osdmap->osd_addr[i];
+		int state = client->osdc.osdmap->osd_state[i];
+		char sb[64];
+
+		seq_printf(s, "\tosd%d\t%s\t%3d%%\t(%s)\n",
+			   i, pr_addr(&addr->in_addr),
+			   ((client->osdc.osdmap->osd_weight[i]*100) >> 16),
+			   ceph_osdmap_state_str(sb, sizeof(sb), state));
+	}
+	return 0;
+}
+
+static int monc_show(struct seq_file *s, void *p)
+{
+	struct ceph_client *client = s->private;
+	struct ceph_mon_statfs_request *req;
+	struct ceph_mon_client *monc = &client->monc;
+	struct rb_node *rp;
+
+	mutex_lock(&monc->mutex);
+
+	if (monc->have_mdsmap)
+		seq_printf(s, "have mdsmap %u\n", (unsigned)monc->have_mdsmap);
+	if (monc->have_osdmap)
+		seq_printf(s, "have osdmap %u\n", (unsigned)monc->have_osdmap);
+	if (monc->want_next_osdmap)
+		seq_printf(s, "want next osdmap\n");
+
+	for (rp = rb_first(&monc->statfs_request_tree); rp; rp = rb_next(rp)) {
+		req = rb_entry(rp, struct ceph_mon_statfs_request, node);
+		seq_printf(s, "%lld statfs\n", req->tid);
+	}
+
+	mutex_unlock(&monc->mutex);
+	return 0;
+}
+
+static int mdsc_show(struct seq_file *s, void *p)
+{
+	struct ceph_client *client = s->private;
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct ceph_mds_request *req;
+	struct rb_node *rp;
+	int pathlen;
+	u64 pathbase;
+	char *path;
+
+	mutex_lock(&mdsc->mutex);
+	for (rp = rb_first(&mdsc->request_tree); rp; rp = rb_next(rp)) {
+		req = rb_entry(rp, struct ceph_mds_request, r_node);
+
+		if (req->r_request)
+			seq_printf(s, "%lld\tmds%d\t", req->r_tid, req->r_mds);
+		else
+			seq_printf(s, "%lld\t(no request)\t", req->r_tid);
+
+		seq_printf(s, "%s", ceph_mds_op_name(req->r_op));
+
+		if (req->r_got_unsafe)
+			seq_printf(s, "\t(unsafe)");
+		else
+			seq_printf(s, "\t");
+
+		if (req->r_inode) {
+			seq_printf(s, " #%llx", ceph_ino(req->r_inode));
+		} else if (req->r_dentry) {
+			path = ceph_mdsc_build_path(req->r_dentry, &pathlen,
+						    &pathbase, 0);
+			spin_lock(&req->r_dentry->d_lock);
+			seq_printf(s, " #%llx/%.*s (%s)",
+				   ceph_ino(req->r_dentry->d_parent->d_inode),
+				   req->r_dentry->d_name.len,
+				   req->r_dentry->d_name.name,
+				   path ? path : "");
+			spin_unlock(&req->r_dentry->d_lock);
+			kfree(path);
+		} else if (req->r_path1) {
+			seq_printf(s, " #%llx/%s", req->r_ino1.ino,
+				   req->r_path1);
+		}
+
+		if (req->r_old_dentry) {
+			path = ceph_mdsc_build_path(req->r_old_dentry, &pathlen,
+						    &pathbase, 0);
+			spin_lock(&req->r_old_dentry->d_lock);
+			seq_printf(s, " #%llx/%.*s (%s)",
+			   ceph_ino(req->r_old_dentry->d_parent->d_inode),
+				   req->r_old_dentry->d_name.len,
+				   req->r_old_dentry->d_name.name,
+				   path ? path : "");
+			spin_unlock(&req->r_old_dentry->d_lock);
+			kfree(path);
+		} else if (req->r_path2) {
+			if (req->r_ino2.ino)
+				seq_printf(s, " #%llx/%s", req->r_ino2.ino,
+					   req->r_path2);
+			else
+				seq_printf(s, " %s", req->r_path2);
+		}
+
+		seq_printf(s, "\n");
+	}
+	mutex_unlock(&mdsc->mutex);
+
+	return 0;
+}
+
+static int osdc_show(struct seq_file *s, void *pp)
+{
+	struct ceph_client *client = s->private;
+	struct ceph_osd_client *osdc = &client->osdc;
+	struct rb_node *p;
+
+	mutex_lock(&osdc->request_mutex);
+	for (p = rb_first(&osdc->requests); p; p = rb_next(p)) {
+		struct ceph_osd_request *req;
+		struct ceph_osd_request_head *head;
+		struct ceph_osd_op *op;
+		int num_ops;
+		int opcode, olen;
+		int i;
+
+		req = rb_entry(p, struct ceph_osd_request, r_node);
+
+		seq_printf(s, "%lld\tosd%d\t%d.%x\t", req->r_tid,
+			   req->r_osd ? req->r_osd->o_osd : -1,
+			   le32_to_cpu(req->r_pgid.pool),
+			   le16_to_cpu(req->r_pgid.ps));
+
+		head = req->r_request->front.iov_base;
+		op = (void *)(head + 1);
+
+		num_ops = le16_to_cpu(head->num_ops);
+		olen = le32_to_cpu(head->object_len);
+		seq_printf(s, "%.*s", olen,
+			   (const char *)(head->ops + num_ops));
+
+		if (req->r_reassert_version.epoch)
+			seq_printf(s, "\t%u'%llu",
+			   (unsigned)le32_to_cpu(req->r_reassert_version.epoch),
+			   le64_to_cpu(req->r_reassert_version.version));
+		else
+			seq_printf(s, "\t");
+
+		for (i = 0; i < num_ops; i++) {
+			opcode = le16_to_cpu(op->op);
+			seq_printf(s, "\t%s", ceph_osd_op_name(opcode));
+			op++;
+		}
+
+		seq_printf(s, "\n");
+	}
+	mutex_unlock(&osdc->request_mutex);
+	return 0;
+}
+
+static int caps_show(struct seq_file *s, void *p)
+{
+	struct ceph_client *client = p;
+	int total, avail, used, reserved, min;
+
+	ceph_reservation_status(client, &total, &avail, &used, &reserved, &min);
+	seq_printf(s, "total\t\t%d\n"
+		   "avail\t\t%d\n"
+		   "used\t\t%d\n"
+		   "reserved\t%d\n"
+		   "min\t%d\n",
+		   total, avail, used, reserved, min);
+	return 0;
+}
+
+static int dentry_lru_show(struct seq_file *s, void *ptr)
+{
+	struct ceph_client *client = s->private;
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct ceph_dentry_info *di;
+
+	spin_lock(&mdsc->dentry_lru_lock);
+	list_for_each_entry(di, &mdsc->dentry_lru, lru) {
+		struct dentry *dentry = di->dentry;
+		seq_printf(s, "%p %p\t%.*s\n",
+			   di, dentry, dentry->d_name.len, dentry->d_name.name);
+	}
+	spin_unlock(&mdsc->dentry_lru_lock);
+
+	return 0;
+}
+
+#define DEFINE_SHOW_FUNC(name) 						\
+static int name##_open(struct inode *inode, struct file *file)		\
+{									\
+	struct seq_file *sf;						\
+	int ret;							\
+									\
+	ret = single_open(file, name, NULL);				\
+	sf = file->private_data;					\
+	sf->private = inode->i_private;					\
+	return ret;							\
+}									\
+									\
+static const struct file_operations name##_fops = {			\
+	.open		= name##_open,					\
+	.read		= seq_read,					\
+	.llseek		= seq_lseek,					\
+	.release	= single_release,				\
+};
+
+DEFINE_SHOW_FUNC(monmap_show)
+DEFINE_SHOW_FUNC(mdsmap_show)
+DEFINE_SHOW_FUNC(osdmap_show)
+DEFINE_SHOW_FUNC(monc_show)
+DEFINE_SHOW_FUNC(mdsc_show)
+DEFINE_SHOW_FUNC(osdc_show)
+DEFINE_SHOW_FUNC(dentry_lru_show)
+DEFINE_SHOW_FUNC(caps_show)
+
+static int congestion_kb_set(void *data, u64 val)
+{
+	struct ceph_client *client = (struct ceph_client *)data;
+
+	if (client)
+		client->mount_args->congestion_kb = (int)val;
+
+	return 0;
+}
+
+static int congestion_kb_get(void *data, u64 *val)
+{
+	struct ceph_client *client = (struct ceph_client *)data;
+
+	if (client)
+		*val = (u64)client->mount_args->congestion_kb;
+
+	return 0;
+}
+
+
+DEFINE_SIMPLE_ATTRIBUTE(congestion_kb_fops, congestion_kb_get,
+			congestion_kb_set, "%llu\n");
+
+int __init ceph_debugfs_init(void)
+{
+	ceph_debugfs_dir = debugfs_create_dir("ceph", NULL);
+	if (!ceph_debugfs_dir)
+		return -ENOMEM;
+	return 0;
+}
+
+void ceph_debugfs_cleanup(void)
+{
+	debugfs_remove(ceph_debugfs_dir);
+}
+
+int ceph_debugfs_client_init(struct ceph_client *client)
+{
+	int ret = 0;
+	char name[80];
+
+	snprintf(name, sizeof(name), FSID_FORMAT ".client%lld",
+		 PR_FSID(&client->fsid), client->monc.auth->global_id);
+
+	client->debugfs_dir = debugfs_create_dir(name, ceph_debugfs_dir);
+	if (!client->debugfs_dir)
+		goto out;
+
+	client->monc.debugfs_file = debugfs_create_file("monc",
+						      0600,
+						      client->debugfs_dir,
+						      client,
+						      &monc_show_fops);
+	if (!client->monc.debugfs_file)
+		goto out;
+
+	client->mdsc.debugfs_file = debugfs_create_file("mdsc",
+						      0600,
+						      client->debugfs_dir,
+						      client,
+						      &mdsc_show_fops);
+	if (!client->mdsc.debugfs_file)
+		goto out;
+
+	client->osdc.debugfs_file = debugfs_create_file("osdc",
+						      0600,
+						      client->debugfs_dir,
+						      client,
+						      &osdc_show_fops);
+	if (!client->osdc.debugfs_file)
+		goto out;
+
+	client->debugfs_monmap = debugfs_create_file("monmap",
+					0600,
+					client->debugfs_dir,
+					client,
+					&monmap_show_fops);
+	if (!client->debugfs_monmap)
+		goto out;
+
+	client->debugfs_mdsmap = debugfs_create_file("mdsmap",
+					0600,
+					client->debugfs_dir,
+					client,
+					&mdsmap_show_fops);
+	if (!client->debugfs_mdsmap)
+		goto out;
+
+	client->debugfs_osdmap = debugfs_create_file("osdmap",
+					0600,
+					client->debugfs_dir,
+					client,
+					&osdmap_show_fops);
+	if (!client->debugfs_osdmap)
+		goto out;
+
+	client->debugfs_dentry_lru = debugfs_create_file("dentry_lru",
+					0600,
+					client->debugfs_dir,
+					client,
+					&dentry_lru_show_fops);
+	if (!client->debugfs_dentry_lru)
+		goto out;
+
+	client->debugfs_caps = debugfs_create_file("caps",
+						   0400,
+						   client->debugfs_dir,
+						   client,
+						   &caps_show_fops);
+	if (!client->debugfs_caps)
+		goto out;
+
+	client->debugfs_congestion_kb = debugfs_create_file("writeback_congestion_kb",
+						   0600,
+						   client->debugfs_dir,
+						   client,
+						   &congestion_kb_fops);
+	if (!client->debugfs_congestion_kb)
+		goto out;
+
+	sprintf(name, "../../bdi/%s", dev_name(client->sb->s_bdi->dev));
+	client->debugfs_bdi = debugfs_create_symlink("bdi", client->debugfs_dir,
+						     name);
+
+	return 0;
+
+out:
+	ceph_debugfs_client_cleanup(client);
+	return ret;
+}
+
+void ceph_debugfs_client_cleanup(struct ceph_client *client)
+{
+	debugfs_remove(client->debugfs_bdi);
+	debugfs_remove(client->debugfs_caps);
+	debugfs_remove(client->debugfs_dentry_lru);
+	debugfs_remove(client->debugfs_osdmap);
+	debugfs_remove(client->debugfs_mdsmap);
+	debugfs_remove(client->debugfs_monmap);
+	debugfs_remove(client->osdc.debugfs_file);
+	debugfs_remove(client->mdsc.debugfs_file);
+	debugfs_remove(client->monc.debugfs_file);
+	debugfs_remove(client->debugfs_congestion_kb);
+	debugfs_remove(client->debugfs_dir);
+}
+
+#else  // CONFIG_DEBUG_FS
+
+int __init ceph_debugfs_init(void)
+{
+	return 0;
+}
+
+void ceph_debugfs_cleanup(void)
+{
+}
+
+int ceph_debugfs_client_init(struct ceph_client *client)
+{
+	return 0;
+}
+
+void ceph_debugfs_client_cleanup(struct ceph_client *client)
+{
+}
+
+#endif  // CONFIG_DEBUG_FS
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/decode.h linux-libre-2.6.34-gnu1/fs/ceph/decode.h
--- linux-libre-2.6.33-gnu1/fs/ceph/decode.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/decode.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,194 @@
+#ifndef __CEPH_DECODE_H
+#define __CEPH_DECODE_H
+
+#include <asm/unaligned.h>
+#include <linux/time.h>
+
+#include "types.h"
+
+/*
+ * in all cases,
+ *   void **p     pointer to position pointer
+ *   void *end    pointer to end of buffer (last byte + 1)
+ */
+
+static inline u64 ceph_decode_64(void **p)
+{
+	u64 v = get_unaligned_le64(*p);
+	*p += sizeof(u64);
+	return v;
+}
+static inline u32 ceph_decode_32(void **p)
+{
+	u32 v = get_unaligned_le32(*p);
+	*p += sizeof(u32);
+	return v;
+}
+static inline u16 ceph_decode_16(void **p)
+{
+	u16 v = get_unaligned_le16(*p);
+	*p += sizeof(u16);
+	return v;
+}
+static inline u8 ceph_decode_8(void **p)
+{
+	u8 v = *(u8 *)*p;
+	(*p)++;
+	return v;
+}
+static inline void ceph_decode_copy(void **p, void *pv, size_t n)
+{
+	memcpy(pv, *p, n);
+	*p += n;
+}
+
+/*
+ * bounds check input.
+ */
+#define ceph_decode_need(p, end, n, bad)		\
+	do {						\
+		if (unlikely(*(p) + (n) > (end))) 	\
+			goto bad;			\
+	} while (0)
+
+#define ceph_decode_64_safe(p, end, v, bad)			\
+	do {							\
+		ceph_decode_need(p, end, sizeof(u64), bad);	\
+		v = ceph_decode_64(p);				\
+	} while (0)
+#define ceph_decode_32_safe(p, end, v, bad)			\
+	do {							\
+		ceph_decode_need(p, end, sizeof(u32), bad);	\
+		v = ceph_decode_32(p);				\
+	} while (0)
+#define ceph_decode_16_safe(p, end, v, bad)			\
+	do {							\
+		ceph_decode_need(p, end, sizeof(u16), bad);	\
+		v = ceph_decode_16(p);				\
+	} while (0)
+#define ceph_decode_8_safe(p, end, v, bad)			\
+	do {							\
+		ceph_decode_need(p, end, sizeof(u8), bad);	\
+		v = ceph_decode_8(p);				\
+	} while (0)
+
+#define ceph_decode_copy_safe(p, end, pv, n, bad)		\
+	do {							\
+		ceph_decode_need(p, end, n, bad);		\
+		ceph_decode_copy(p, pv, n);			\
+	} while (0)
+
+/*
+ * struct ceph_timespec <-> struct timespec
+ */
+static inline void ceph_decode_timespec(struct timespec *ts,
+					const struct ceph_timespec *tv)
+{
+	ts->tv_sec = le32_to_cpu(tv->tv_sec);
+	ts->tv_nsec = le32_to_cpu(tv->tv_nsec);
+}
+static inline void ceph_encode_timespec(struct ceph_timespec *tv,
+					const struct timespec *ts)
+{
+	tv->tv_sec = cpu_to_le32(ts->tv_sec);
+	tv->tv_nsec = cpu_to_le32(ts->tv_nsec);
+}
+
+/*
+ * sockaddr_storage <-> ceph_sockaddr
+ */
+static inline void ceph_encode_addr(struct ceph_entity_addr *a)
+{
+	a->in_addr.ss_family = htons(a->in_addr.ss_family);
+}
+static inline void ceph_decode_addr(struct ceph_entity_addr *a)
+{
+	a->in_addr.ss_family = ntohs(a->in_addr.ss_family);
+	WARN_ON(a->in_addr.ss_family == 512);
+}
+
+/*
+ * encoders
+ */
+static inline void ceph_encode_64(void **p, u64 v)
+{
+	put_unaligned_le64(v, (__le64 *)*p);
+	*p += sizeof(u64);
+}
+static inline void ceph_encode_32(void **p, u32 v)
+{
+	put_unaligned_le32(v, (__le32 *)*p);
+	*p += sizeof(u32);
+}
+static inline void ceph_encode_16(void **p, u16 v)
+{
+	put_unaligned_le16(v, (__le16 *)*p);
+	*p += sizeof(u16);
+}
+static inline void ceph_encode_8(void **p, u8 v)
+{
+	*(u8 *)*p = v;
+	(*p)++;
+}
+static inline void ceph_encode_copy(void **p, const void *s, int len)
+{
+	memcpy(*p, s, len);
+	*p += len;
+}
+
+/*
+ * filepath, string encoders
+ */
+static inline void ceph_encode_filepath(void **p, void *end,
+					u64 ino, const char *path)
+{
+	u32 len = path ? strlen(path) : 0;
+	BUG_ON(*p + sizeof(ino) + sizeof(len) + len > end);
+	ceph_encode_8(p, 1);
+	ceph_encode_64(p, ino);
+	ceph_encode_32(p, len);
+	if (len)
+		memcpy(*p, path, len);
+	*p += len;
+}
+
+static inline void ceph_encode_string(void **p, void *end,
+				      const char *s, u32 len)
+{
+	BUG_ON(*p + sizeof(len) + len > end);
+	ceph_encode_32(p, len);
+	if (len)
+		memcpy(*p, s, len);
+	*p += len;
+}
+
+#define ceph_encode_need(p, end, n, bad)		\
+	do {						\
+		if (unlikely(*(p) + (n) > (end))) 	\
+			goto bad;			\
+	} while (0)
+
+#define ceph_encode_64_safe(p, end, v, bad)			\
+	do {							\
+		ceph_encode_need(p, end, sizeof(u64), bad);	\
+		ceph_encode_64(p, v);				\
+	} while (0)
+#define ceph_encode_32_safe(p, end, v, bad)			\
+	do {							\
+		ceph_encode_need(p, end, sizeof(u32), bad);	\
+		ceph_encode_32(p, v);			\
+	} while (0)
+#define ceph_encode_16_safe(p, end, v, bad)			\
+	do {							\
+		ceph_encode_need(p, end, sizeof(u16), bad);	\
+		ceph_encode_16(p, v);			\
+	} while (0)
+
+#define ceph_encode_copy_safe(p, end, pv, n, bad)		\
+	do {							\
+		ceph_encode_need(p, end, n, bad);		\
+		ceph_encode_copy(p, pv, n);			\
+	} while (0)
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/dir.c linux-libre-2.6.34-gnu1/fs/ceph/dir.c
--- linux-libre-2.6.33-gnu1/fs/ceph/dir.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/dir.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1233 @@
+#include "ceph_debug.h"
+
+#include <linux/spinlock.h>
+#include <linux/fs_struct.h>
+#include <linux/namei.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+
+#include "super.h"
+
+/*
+ * Directory operations: readdir, lookup, create, link, unlink,
+ * rename, etc.
+ */
+
+/*
+ * Ceph MDS operations are specified in terms of a base ino and
+ * relative path.  Thus, the client can specify an operation on a
+ * specific inode (e.g., a getattr due to fstat(2)), or as a path
+ * relative to, say, the root directory.
+ *
+ * Normally, we limit ourselves to strict inode ops (no path component)
+ * or dentry operations (a single path component relative to an ino).  The
+ * exception to this is open_root_dentry(), which will open the mount
+ * point by name.
+ */
+
+const struct inode_operations ceph_dir_iops;
+const struct file_operations ceph_dir_fops;
+struct dentry_operations ceph_dentry_ops;
+
+/*
+ * Initialize ceph dentry state.
+ */
+int ceph_init_dentry(struct dentry *dentry)
+{
+	struct ceph_dentry_info *di;
+
+	if (dentry->d_fsdata)
+		return 0;
+
+	if (ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP)
+		dentry->d_op = &ceph_dentry_ops;
+	else if (ceph_snap(dentry->d_parent->d_inode) == CEPH_SNAPDIR)
+		dentry->d_op = &ceph_snapdir_dentry_ops;
+	else
+		dentry->d_op = &ceph_snap_dentry_ops;
+
+	di = kmem_cache_alloc(ceph_dentry_cachep, GFP_NOFS);
+	if (!di)
+		return -ENOMEM;          /* oh well */
+
+	spin_lock(&dentry->d_lock);
+	if (dentry->d_fsdata) /* lost a race */
+		goto out_unlock;
+	di->dentry = dentry;
+	di->lease_session = NULL;
+	dentry->d_fsdata = di;
+	dentry->d_time = jiffies;
+	ceph_dentry_lru_add(dentry);
+out_unlock:
+	spin_unlock(&dentry->d_lock);
+	return 0;
+}
+
+
+
+/*
+ * for readdir, we encode the directory frag and offset within that
+ * frag into f_pos.
+ */
+static unsigned fpos_frag(loff_t p)
+{
+	return p >> 32;
+}
+static unsigned fpos_off(loff_t p)
+{
+	return p & 0xffffffff;
+}
+
+/*
+ * When possible, we try to satisfy a readdir by peeking at the
+ * dcache.  We make this work by carefully ordering dentries on
+ * d_u.d_child when we initially get results back from the MDS, and
+ * falling back to a "normal" sync readdir if any dentries in the dir
+ * are dropped.
+ *
+ * I_COMPLETE tells indicates we have all dentries in the dir.  It is
+ * defined IFF we hold CEPH_CAP_FILE_SHARED (which will be revoked by
+ * the MDS if/when the directory is modified).
+ */
+static int __dcache_readdir(struct file *filp,
+			    void *dirent, filldir_t filldir)
+{
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct ceph_file_info *fi = filp->private_data;
+	struct dentry *parent = filp->f_dentry;
+	struct inode *dir = parent->d_inode;
+	struct list_head *p;
+	struct dentry *dentry, *last;
+	struct ceph_dentry_info *di;
+	int err = 0;
+
+	/* claim ref on last dentry we returned */
+	last = fi->dentry;
+	fi->dentry = NULL;
+
+	dout("__dcache_readdir %p at %llu (last %p)\n", dir, filp->f_pos,
+	     last);
+
+	spin_lock(&dcache_lock);
+
+	/* start at beginning? */
+	if (filp->f_pos == 2 || (last &&
+				 filp->f_pos < ceph_dentry(last)->offset)) {
+		if (list_empty(&parent->d_subdirs))
+			goto out_unlock;
+		p = parent->d_subdirs.prev;
+		dout(" initial p %p/%p\n", p->prev, p->next);
+	} else {
+		p = last->d_u.d_child.prev;
+	}
+
+more:
+	dentry = list_entry(p, struct dentry, d_u.d_child);
+	di = ceph_dentry(dentry);
+	while (1) {
+		dout(" p %p/%p d_subdirs %p/%p\n", p->prev, p->next,
+		     parent->d_subdirs.prev, parent->d_subdirs.next);
+		if (p == &parent->d_subdirs) {
+			fi->at_end = 1;
+			goto out_unlock;
+		}
+		if (!d_unhashed(dentry) && dentry->d_inode &&
+		    ceph_snap(dentry->d_inode) != CEPH_SNAPDIR &&
+		    ceph_ino(dentry->d_inode) != CEPH_INO_CEPH &&
+		    filp->f_pos <= di->offset)
+			break;
+		dout(" skipping %p %.*s at %llu (%llu)%s%s\n", dentry,
+		     dentry->d_name.len, dentry->d_name.name, di->offset,
+		     filp->f_pos, d_unhashed(dentry) ? " unhashed" : "",
+		     !dentry->d_inode ? " null" : "");
+		p = p->prev;
+		dentry = list_entry(p, struct dentry, d_u.d_child);
+		di = ceph_dentry(dentry);
+	}
+
+	atomic_inc(&dentry->d_count);
+	spin_unlock(&dcache_lock);
+	spin_unlock(&inode->i_lock);
+
+	dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, filp->f_pos,
+	     dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode);
+	filp->f_pos = di->offset;
+	err = filldir(dirent, dentry->d_name.name,
+		      dentry->d_name.len, di->offset,
+		      dentry->d_inode->i_ino,
+		      dentry->d_inode->i_mode >> 12);
+
+	if (last) {
+		if (err < 0) {
+			/* remember our position */
+			fi->dentry = last;
+			fi->next_offset = di->offset;
+		} else {
+			dput(last);
+		}
+		last = NULL;
+	}
+
+	spin_lock(&inode->i_lock);
+	spin_lock(&dcache_lock);
+
+	last = dentry;
+
+	if (err < 0)
+		goto out_unlock;
+
+	p = p->prev;
+	filp->f_pos++;
+
+	/* make sure a dentry wasn't dropped while we didn't have dcache_lock */
+	if ((ceph_inode(dir)->i_ceph_flags & CEPH_I_COMPLETE))
+		goto more;
+	dout(" lost I_COMPLETE on %p; falling back to mds\n", dir);
+	err = -EAGAIN;
+
+out_unlock:
+	spin_unlock(&dcache_lock);
+
+	if (last) {
+		spin_unlock(&inode->i_lock);
+		dput(last);
+		spin_lock(&inode->i_lock);
+	}
+
+	return err;
+}
+
+/*
+ * make note of the last dentry we read, so we can
+ * continue at the same lexicographical point,
+ * regardless of what dir changes take place on the
+ * server.
+ */
+static int note_last_dentry(struct ceph_file_info *fi, const char *name,
+			    int len)
+{
+	kfree(fi->last_name);
+	fi->last_name = kmalloc(len+1, GFP_NOFS);
+	if (!fi->last_name)
+		return -ENOMEM;
+	memcpy(fi->last_name, name, len);
+	fi->last_name[len] = 0;
+	dout("note_last_dentry '%s'\n", fi->last_name);
+	return 0;
+}
+
+static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+	struct ceph_file_info *fi = filp->private_data;
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_client *client = ceph_inode_to_client(inode);
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	unsigned frag = fpos_frag(filp->f_pos);
+	int off = fpos_off(filp->f_pos);
+	int err;
+	u32 ftype;
+	struct ceph_mds_reply_info_parsed *rinfo;
+	const int max_entries = client->mount_args->max_readdir;
+
+	dout("readdir %p filp %p frag %u off %u\n", inode, filp, frag, off);
+	if (fi->at_end)
+		return 0;
+
+	/* always start with . and .. */
+	if (filp->f_pos == 0) {
+		/* note dir version at start of readdir so we can tell
+		 * if any dentries get dropped */
+		fi->dir_release_count = ci->i_release_count;
+
+		dout("readdir off 0 -> '.'\n");
+		if (filldir(dirent, ".", 1, ceph_make_fpos(0, 0),
+			    inode->i_ino, inode->i_mode >> 12) < 0)
+			return 0;
+		filp->f_pos = 1;
+		off = 1;
+	}
+	if (filp->f_pos == 1) {
+		dout("readdir off 1 -> '..'\n");
+		if (filldir(dirent, "..", 2, ceph_make_fpos(0, 1),
+			    filp->f_dentry->d_parent->d_inode->i_ino,
+			    inode->i_mode >> 12) < 0)
+			return 0;
+		filp->f_pos = 2;
+		off = 2;
+	}
+
+	/* can we use the dcache? */
+	spin_lock(&inode->i_lock);
+	if ((filp->f_pos == 2 || fi->dentry) &&
+	    !ceph_test_opt(client, NOASYNCREADDIR) &&
+	    (ci->i_ceph_flags & CEPH_I_COMPLETE) &&
+	    __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) {
+		err = __dcache_readdir(filp, dirent, filldir);
+		if (err != -EAGAIN) {
+			spin_unlock(&inode->i_lock);
+			return err;
+		}
+	}
+	spin_unlock(&inode->i_lock);
+	if (fi->dentry) {
+		err = note_last_dentry(fi, fi->dentry->d_name.name,
+				       fi->dentry->d_name.len);
+		if (err)
+			return err;
+		dput(fi->dentry);
+		fi->dentry = NULL;
+	}
+
+	/* proceed with a normal readdir */
+
+more:
+	/* do we have the correct frag content buffered? */
+	if (fi->frag != frag || fi->last_readdir == NULL) {
+		struct ceph_mds_request *req;
+		int op = ceph_snap(inode) == CEPH_SNAPDIR ?
+			CEPH_MDS_OP_LSSNAP : CEPH_MDS_OP_READDIR;
+
+		/* discard old result, if any */
+		if (fi->last_readdir) {
+			ceph_mdsc_put_request(fi->last_readdir);
+			fi->last_readdir = NULL;
+		}
+
+		/* requery frag tree, as the frag topology may have changed */
+		frag = ceph_choose_frag(ceph_inode(inode), frag, NULL, NULL);
+
+		dout("readdir fetching %llx.%llx frag %x offset '%s'\n",
+		     ceph_vinop(inode), frag, fi->last_name);
+		req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
+		if (IS_ERR(req))
+			return PTR_ERR(req);
+		req->r_inode = igrab(inode);
+		req->r_dentry = dget(filp->f_dentry);
+		/* hints to request -> mds selection code */
+		req->r_direct_mode = USE_AUTH_MDS;
+		req->r_direct_hash = ceph_frag_value(frag);
+		req->r_direct_is_hash = true;
+		req->r_path2 = kstrdup(fi->last_name, GFP_NOFS);
+		req->r_readdir_offset = fi->next_offset;
+		req->r_args.readdir.frag = cpu_to_le32(frag);
+		req->r_args.readdir.max_entries = cpu_to_le32(max_entries);
+		req->r_num_caps = max_entries + 1;
+		err = ceph_mdsc_do_request(mdsc, NULL, req);
+		if (err < 0) {
+			ceph_mdsc_put_request(req);
+			return err;
+		}
+		dout("readdir got and parsed readdir result=%d"
+		     " on frag %x, end=%d, complete=%d\n", err, frag,
+		     (int)req->r_reply_info.dir_end,
+		     (int)req->r_reply_info.dir_complete);
+
+		if (!req->r_did_prepopulate) {
+			dout("readdir !did_prepopulate");
+			fi->dir_release_count--;    /* preclude I_COMPLETE */
+		}
+
+		/* note next offset and last dentry name */
+		fi->offset = fi->next_offset;
+		fi->last_readdir = req;
+
+		if (req->r_reply_info.dir_end) {
+			kfree(fi->last_name);
+			fi->last_name = NULL;
+			fi->next_offset = 0;
+		} else {
+			rinfo = &req->r_reply_info;
+			err = note_last_dentry(fi,
+				       rinfo->dir_dname[rinfo->dir_nr-1],
+				       rinfo->dir_dname_len[rinfo->dir_nr-1]);
+			if (err)
+				return err;
+			fi->next_offset += rinfo->dir_nr;
+		}
+	}
+
+	rinfo = &fi->last_readdir->r_reply_info;
+	dout("readdir frag %x num %d off %d chunkoff %d\n", frag,
+	     rinfo->dir_nr, off, fi->offset);
+	while (off - fi->offset >= 0 && off - fi->offset < rinfo->dir_nr) {
+		u64 pos = ceph_make_fpos(frag, off);
+		struct ceph_mds_reply_inode *in =
+			rinfo->dir_in[off - fi->offset].in;
+		dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n",
+		     off, off - fi->offset, rinfo->dir_nr, pos,
+		     rinfo->dir_dname_len[off - fi->offset],
+		     rinfo->dir_dname[off - fi->offset], in);
+		BUG_ON(!in);
+		ftype = le32_to_cpu(in->mode) >> 12;
+		if (filldir(dirent,
+			    rinfo->dir_dname[off - fi->offset],
+			    rinfo->dir_dname_len[off - fi->offset],
+			    pos,
+			    le64_to_cpu(in->ino),
+			    ftype) < 0) {
+			dout("filldir stopping us...\n");
+			return 0;
+		}
+		off++;
+		filp->f_pos = pos + 1;
+	}
+
+	if (fi->last_name) {
+		ceph_mdsc_put_request(fi->last_readdir);
+		fi->last_readdir = NULL;
+		goto more;
+	}
+
+	/* more frags? */
+	if (!ceph_frag_is_rightmost(frag)) {
+		frag = ceph_frag_next(frag);
+		off = 0;
+		filp->f_pos = ceph_make_fpos(frag, off);
+		dout("readdir next frag is %x\n", frag);
+		goto more;
+	}
+	fi->at_end = 1;
+
+	/*
+	 * if dir_release_count still matches the dir, no dentries
+	 * were released during the whole readdir, and we should have
+	 * the complete dir contents in our cache.
+	 */
+	spin_lock(&inode->i_lock);
+	if (ci->i_release_count == fi->dir_release_count) {
+		dout(" marking %p complete\n", inode);
+		ci->i_ceph_flags |= CEPH_I_COMPLETE;
+		ci->i_max_offset = filp->f_pos;
+	}
+	spin_unlock(&inode->i_lock);
+
+	dout("readdir %p filp %p done.\n", inode, filp);
+	return 0;
+}
+
+static void reset_readdir(struct ceph_file_info *fi)
+{
+	if (fi->last_readdir) {
+		ceph_mdsc_put_request(fi->last_readdir);
+		fi->last_readdir = NULL;
+	}
+	kfree(fi->last_name);
+	fi->next_offset = 2;  /* compensate for . and .. */
+	if (fi->dentry) {
+		dput(fi->dentry);
+		fi->dentry = NULL;
+	}
+	fi->at_end = 0;
+}
+
+static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int origin)
+{
+	struct ceph_file_info *fi = file->private_data;
+	struct inode *inode = file->f_mapping->host;
+	loff_t old_offset = offset;
+	loff_t retval;
+
+	mutex_lock(&inode->i_mutex);
+	switch (origin) {
+	case SEEK_END:
+		offset += inode->i_size + 2;   /* FIXME */
+		break;
+	case SEEK_CUR:
+		offset += file->f_pos;
+	}
+	retval = -EINVAL;
+	if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) {
+		if (offset != file->f_pos) {
+			file->f_pos = offset;
+			file->f_version = 0;
+			fi->at_end = 0;
+		}
+		retval = offset;
+
+		/*
+		 * discard buffered readdir content on seekdir(0), or
+		 * seek to new frag, or seek prior to current chunk.
+		 */
+		if (offset == 0 ||
+		    fpos_frag(offset) != fpos_frag(old_offset) ||
+		    fpos_off(offset) < fi->offset) {
+			dout("dir_llseek dropping %p content\n", file);
+			reset_readdir(fi);
+		}
+
+		/* bump dir_release_count if we did a forward seek */
+		if (offset > old_offset)
+			fi->dir_release_count--;
+	}
+	mutex_unlock(&inode->i_mutex);
+	return retval;
+}
+
+/*
+ * Process result of a lookup/open request.
+ *
+ * Mainly, make sure we return the final req->r_dentry (if it already
+ * existed) in place of the original VFS-provided dentry when they
+ * differ.
+ *
+ * Gracefully handle the case where the MDS replies with -ENOENT and
+ * no trace (which it may do, at its discretion, e.g., if it doesn't
+ * care to issue a lease on the negative dentry).
+ */
+struct dentry *ceph_finish_lookup(struct ceph_mds_request *req,
+				  struct dentry *dentry, int err)
+{
+	struct ceph_client *client = ceph_client(dentry->d_sb);
+	struct inode *parent = dentry->d_parent->d_inode;
+
+	/* .snap dir? */
+	if (err == -ENOENT &&
+	    ceph_vino(parent).ino != CEPH_INO_ROOT && /* no .snap in root dir */
+	    strcmp(dentry->d_name.name,
+		   client->mount_args->snapdir_name) == 0) {
+		struct inode *inode = ceph_get_snapdir(parent);
+		dout("ENOENT on snapdir %p '%.*s', linking to snapdir %p\n",
+		     dentry, dentry->d_name.len, dentry->d_name.name, inode);
+		BUG_ON(!d_unhashed(dentry));
+		d_add(dentry, inode);
+		err = 0;
+	}
+
+	if (err == -ENOENT) {
+		/* no trace? */
+		err = 0;
+		if (!req->r_reply_info.head->is_dentry) {
+			dout("ENOENT and no trace, dentry %p inode %p\n",
+			     dentry, dentry->d_inode);
+			if (dentry->d_inode) {
+				d_drop(dentry);
+				err = -ENOENT;
+			} else {
+				d_add(dentry, NULL);
+			}
+		}
+	}
+	if (err)
+		dentry = ERR_PTR(err);
+	else if (dentry != req->r_dentry)
+		dentry = dget(req->r_dentry);   /* we got spliced */
+	else
+		dentry = NULL;
+	return dentry;
+}
+
+static int is_root_ceph_dentry(struct inode *inode, struct dentry *dentry)
+{
+	return ceph_ino(inode) == CEPH_INO_ROOT &&
+		strncmp(dentry->d_name.name, ".ceph", 5) == 0;
+}
+
+/*
+ * Look up a single dir entry.  If there is a lookup intent, inform
+ * the MDS so that it gets our 'caps wanted' value in a single op.
+ */
+static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
+				  struct nameidata *nd)
+{
+	struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct ceph_mds_request *req;
+	int op;
+	int err;
+
+	dout("lookup %p dentry %p '%.*s'\n",
+	     dir, dentry, dentry->d_name.len, dentry->d_name.name);
+
+	if (dentry->d_name.len > NAME_MAX)
+		return ERR_PTR(-ENAMETOOLONG);
+
+	err = ceph_init_dentry(dentry);
+	if (err < 0)
+		return ERR_PTR(err);
+
+	/* open (but not create!) intent? */
+	if (nd &&
+	    (nd->flags & LOOKUP_OPEN) &&
+	    (nd->flags & LOOKUP_CONTINUE) == 0 && /* only open last component */
+	    !(nd->intent.open.flags & O_CREAT)) {
+		int mode = nd->intent.open.create_mode & ~current->fs->umask;
+		return ceph_lookup_open(dir, dentry, nd, mode, 1);
+	}
+
+	/* can we conclude ENOENT locally? */
+	if (dentry->d_inode == NULL) {
+		struct ceph_inode_info *ci = ceph_inode(dir);
+		struct ceph_dentry_info *di = ceph_dentry(dentry);
+
+		spin_lock(&dir->i_lock);
+		dout(" dir %p flags are %d\n", dir, ci->i_ceph_flags);
+		if (strncmp(dentry->d_name.name,
+			    client->mount_args->snapdir_name,
+			    dentry->d_name.len) &&
+		    !is_root_ceph_dentry(dir, dentry) &&
+		    (ci->i_ceph_flags & CEPH_I_COMPLETE) &&
+		    (__ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1))) {
+			di->offset = ci->i_max_offset++;
+			spin_unlock(&dir->i_lock);
+			dout(" dir %p complete, -ENOENT\n", dir);
+			d_add(dentry, NULL);
+			di->lease_shared_gen = ci->i_shared_gen;
+			return NULL;
+		}
+		spin_unlock(&dir->i_lock);
+	}
+
+	op = ceph_snap(dir) == CEPH_SNAPDIR ?
+		CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP;
+	req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS);
+	if (IS_ERR(req))
+		return ERR_PTR(PTR_ERR(req));
+	req->r_dentry = dget(dentry);
+	req->r_num_caps = 2;
+	/* we only need inode linkage */
+	req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE);
+	req->r_locked_dir = dir;
+	err = ceph_mdsc_do_request(mdsc, NULL, req);
+	dentry = ceph_finish_lookup(req, dentry, err);
+	ceph_mdsc_put_request(req);  /* will dput(dentry) */
+	dout("lookup result=%p\n", dentry);
+	return dentry;
+}
+
+/*
+ * If we do a create but get no trace back from the MDS, follow up with
+ * a lookup (the VFS expects us to link up the provided dentry).
+ */
+int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry)
+{
+	struct dentry *result = ceph_lookup(dir, dentry, NULL);
+
+	if (result && !IS_ERR(result)) {
+		/*
+		 * We created the item, then did a lookup, and found
+		 * it was already linked to another inode we already
+		 * had in our cache (and thus got spliced).  Link our
+		 * dentry to that inode, but don't hash it, just in
+		 * case the VFS wants to dereference it.
+		 */
+		BUG_ON(!result->d_inode);
+		d_instantiate(dentry, result->d_inode);
+		return 0;
+	}
+	return PTR_ERR(result);
+}
+
+static int ceph_mknod(struct inode *dir, struct dentry *dentry,
+		      int mode, dev_t rdev)
+{
+	struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct ceph_mds_request *req;
+	int err;
+
+	if (ceph_snap(dir) != CEPH_NOSNAP)
+		return -EROFS;
+
+	dout("mknod in dir %p dentry %p mode 0%o rdev %d\n",
+	     dir, dentry, mode, rdev);
+	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_MKNOD, USE_AUTH_MDS);
+	if (IS_ERR(req)) {
+		d_drop(dentry);
+		return PTR_ERR(req);
+	}
+	req->r_dentry = dget(dentry);
+	req->r_num_caps = 2;
+	req->r_locked_dir = dir;
+	req->r_args.mknod.mode = cpu_to_le32(mode);
+	req->r_args.mknod.rdev = cpu_to_le32(rdev);
+	req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+	req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+	err = ceph_mdsc_do_request(mdsc, dir, req);
+	if (!err && !req->r_reply_info.head->is_dentry)
+		err = ceph_handle_notrace_create(dir, dentry);
+	ceph_mdsc_put_request(req);
+	if (err)
+		d_drop(dentry);
+	return err;
+}
+
+static int ceph_create(struct inode *dir, struct dentry *dentry, int mode,
+		       struct nameidata *nd)
+{
+	dout("create in dir %p dentry %p name '%.*s'\n",
+	     dir, dentry, dentry->d_name.len, dentry->d_name.name);
+
+	if (ceph_snap(dir) != CEPH_NOSNAP)
+		return -EROFS;
+
+	if (nd) {
+		BUG_ON((nd->flags & LOOKUP_OPEN) == 0);
+		dentry = ceph_lookup_open(dir, dentry, nd, mode, 0);
+		/* hrm, what should i do here if we get aliased? */
+		if (IS_ERR(dentry))
+			return PTR_ERR(dentry);
+		return 0;
+	}
+
+	/* fall back to mknod */
+	return ceph_mknod(dir, dentry, (mode & ~S_IFMT) | S_IFREG, 0);
+}
+
+static int ceph_symlink(struct inode *dir, struct dentry *dentry,
+			    const char *dest)
+{
+	struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct ceph_mds_request *req;
+	int err;
+
+	if (ceph_snap(dir) != CEPH_NOSNAP)
+		return -EROFS;
+
+	dout("symlink in dir %p dentry %p to '%s'\n", dir, dentry, dest);
+	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SYMLINK, USE_AUTH_MDS);
+	if (IS_ERR(req)) {
+		d_drop(dentry);
+		return PTR_ERR(req);
+	}
+	req->r_dentry = dget(dentry);
+	req->r_num_caps = 2;
+	req->r_path2 = kstrdup(dest, GFP_NOFS);
+	req->r_locked_dir = dir;
+	req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+	req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+	err = ceph_mdsc_do_request(mdsc, dir, req);
+	if (!err && !req->r_reply_info.head->is_dentry)
+		err = ceph_handle_notrace_create(dir, dentry);
+	ceph_mdsc_put_request(req);
+	if (err)
+		d_drop(dentry);
+	return err;
+}
+
+static int ceph_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+	struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct ceph_mds_request *req;
+	int err = -EROFS;
+	int op;
+
+	if (ceph_snap(dir) == CEPH_SNAPDIR) {
+		/* mkdir .snap/foo is a MKSNAP */
+		op = CEPH_MDS_OP_MKSNAP;
+		dout("mksnap dir %p snap '%.*s' dn %p\n", dir,
+		     dentry->d_name.len, dentry->d_name.name, dentry);
+	} else if (ceph_snap(dir) == CEPH_NOSNAP) {
+		dout("mkdir dir %p dn %p mode 0%o\n", dir, dentry, mode);
+		op = CEPH_MDS_OP_MKDIR;
+	} else {
+		goto out;
+	}
+	req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
+	if (IS_ERR(req)) {
+		err = PTR_ERR(req);
+		goto out;
+	}
+
+	req->r_dentry = dget(dentry);
+	req->r_num_caps = 2;
+	req->r_locked_dir = dir;
+	req->r_args.mkdir.mode = cpu_to_le32(mode);
+	req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+	req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+	err = ceph_mdsc_do_request(mdsc, dir, req);
+	if (!err && !req->r_reply_info.head->is_dentry)
+		err = ceph_handle_notrace_create(dir, dentry);
+	ceph_mdsc_put_request(req);
+out:
+	if (err < 0)
+		d_drop(dentry);
+	return err;
+}
+
+static int ceph_link(struct dentry *old_dentry, struct inode *dir,
+		     struct dentry *dentry)
+{
+	struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct ceph_mds_request *req;
+	int err;
+
+	if (ceph_snap(dir) != CEPH_NOSNAP)
+		return -EROFS;
+
+	dout("link in dir %p old_dentry %p dentry %p\n", dir,
+	     old_dentry, dentry);
+	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LINK, USE_AUTH_MDS);
+	if (IS_ERR(req)) {
+		d_drop(dentry);
+		return PTR_ERR(req);
+	}
+	req->r_dentry = dget(dentry);
+	req->r_num_caps = 2;
+	req->r_old_dentry = dget(old_dentry); /* or inode? hrm. */
+	req->r_locked_dir = dir;
+	req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+	req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+	err = ceph_mdsc_do_request(mdsc, dir, req);
+	if (err)
+		d_drop(dentry);
+	else if (!req->r_reply_info.head->is_dentry)
+		d_instantiate(dentry, igrab(old_dentry->d_inode));
+	ceph_mdsc_put_request(req);
+	return err;
+}
+
+/*
+ * For a soon-to-be unlinked file, drop the AUTH_RDCACHE caps.  If it
+ * looks like the link count will hit 0, drop any other caps (other
+ * than PIN) we don't specifically want (due to the file still being
+ * open).
+ */
+static int drop_caps_for_unlink(struct inode *inode)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL;
+
+	spin_lock(&inode->i_lock);
+	if (inode->i_nlink == 1) {
+		drop |= ~(__ceph_caps_wanted(ci) | CEPH_CAP_PIN);
+		ci->i_ceph_flags |= CEPH_I_NODELAY;
+	}
+	spin_unlock(&inode->i_lock);
+	return drop;
+}
+
+/*
+ * rmdir and unlink are differ only by the metadata op code
+ */
+static int ceph_unlink(struct inode *dir, struct dentry *dentry)
+{
+	struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct inode *inode = dentry->d_inode;
+	struct ceph_mds_request *req;
+	int err = -EROFS;
+	int op;
+
+	if (ceph_snap(dir) == CEPH_SNAPDIR) {
+		/* rmdir .snap/foo is RMSNAP */
+		dout("rmsnap dir %p '%.*s' dn %p\n", dir, dentry->d_name.len,
+		     dentry->d_name.name, dentry);
+		op = CEPH_MDS_OP_RMSNAP;
+	} else if (ceph_snap(dir) == CEPH_NOSNAP) {
+		dout("unlink/rmdir dir %p dn %p inode %p\n",
+		     dir, dentry, inode);
+		op = ((dentry->d_inode->i_mode & S_IFMT) == S_IFDIR) ?
+			CEPH_MDS_OP_RMDIR : CEPH_MDS_OP_UNLINK;
+	} else
+		goto out;
+	req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
+	if (IS_ERR(req)) {
+		err = PTR_ERR(req);
+		goto out;
+	}
+	req->r_dentry = dget(dentry);
+	req->r_num_caps = 2;
+	req->r_locked_dir = dir;
+	req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+	req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+	req->r_inode_drop = drop_caps_for_unlink(inode);
+	err = ceph_mdsc_do_request(mdsc, dir, req);
+	if (!err && !req->r_reply_info.head->is_dentry)
+		d_delete(dentry);
+	ceph_mdsc_put_request(req);
+out:
+	return err;
+}
+
+static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
+		       struct inode *new_dir, struct dentry *new_dentry)
+{
+	struct ceph_client *client = ceph_sb_to_client(old_dir->i_sb);
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct ceph_mds_request *req;
+	int err;
+
+	if (ceph_snap(old_dir) != ceph_snap(new_dir))
+		return -EXDEV;
+	if (ceph_snap(old_dir) != CEPH_NOSNAP ||
+	    ceph_snap(new_dir) != CEPH_NOSNAP)
+		return -EROFS;
+	dout("rename dir %p dentry %p to dir %p dentry %p\n",
+	     old_dir, old_dentry, new_dir, new_dentry);
+	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RENAME, USE_AUTH_MDS);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+	req->r_dentry = dget(new_dentry);
+	req->r_num_caps = 2;
+	req->r_old_dentry = dget(old_dentry);
+	req->r_locked_dir = new_dir;
+	req->r_old_dentry_drop = CEPH_CAP_FILE_SHARED;
+	req->r_old_dentry_unless = CEPH_CAP_FILE_EXCL;
+	req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+	req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+	/* release LINK_RDCACHE on source inode (mds will lock it) */
+	req->r_old_inode_drop = CEPH_CAP_LINK_SHARED;
+	if (new_dentry->d_inode)
+		req->r_inode_drop = drop_caps_for_unlink(new_dentry->d_inode);
+	err = ceph_mdsc_do_request(mdsc, old_dir, req);
+	if (!err && !req->r_reply_info.head->is_dentry) {
+		/*
+		 * Normally d_move() is done by fill_trace (called by
+		 * do_request, above).  If there is no trace, we need
+		 * to do it here.
+		 */
+
+		/* d_move screws up d_subdirs order */
+		ceph_i_clear(new_dir, CEPH_I_COMPLETE);
+
+		d_move(old_dentry, new_dentry);
+
+		/* ensure target dentry is invalidated, despite
+		   rehashing bug in vfs_rename_dir */
+		new_dentry->d_time = jiffies;
+		ceph_dentry(new_dentry)->lease_shared_gen = 0;
+	}
+	ceph_mdsc_put_request(req);
+	return err;
+}
+
+
+/*
+ * Check if dentry lease is valid.  If not, delete the lease.  Try to
+ * renew if the least is more than half up.
+ */
+static int dentry_lease_is_valid(struct dentry *dentry)
+{
+	struct ceph_dentry_info *di;
+	struct ceph_mds_session *s;
+	int valid = 0;
+	u32 gen;
+	unsigned long ttl;
+	struct ceph_mds_session *session = NULL;
+	struct inode *dir = NULL;
+	u32 seq = 0;
+
+	spin_lock(&dentry->d_lock);
+	di = ceph_dentry(dentry);
+	if (di && di->lease_session) {
+		s = di->lease_session;
+		spin_lock(&s->s_cap_lock);
+		gen = s->s_cap_gen;
+		ttl = s->s_cap_ttl;
+		spin_unlock(&s->s_cap_lock);
+
+		if (di->lease_gen == gen &&
+		    time_before(jiffies, dentry->d_time) &&
+		    time_before(jiffies, ttl)) {
+			valid = 1;
+			if (di->lease_renew_after &&
+			    time_after(jiffies, di->lease_renew_after)) {
+				/* we should renew */
+				dir = dentry->d_parent->d_inode;
+				session = ceph_get_mds_session(s);
+				seq = di->lease_seq;
+				di->lease_renew_after = 0;
+				di->lease_renew_from = jiffies;
+			}
+		}
+	}
+	spin_unlock(&dentry->d_lock);
+
+	if (session) {
+		ceph_mdsc_lease_send_msg(session, dir, dentry,
+					 CEPH_MDS_LEASE_RENEW, seq);
+		ceph_put_mds_session(session);
+	}
+	dout("dentry_lease_is_valid - dentry %p = %d\n", dentry, valid);
+	return valid;
+}
+
+/*
+ * Check if directory-wide content lease/cap is valid.
+ */
+static int dir_lease_is_valid(struct inode *dir, struct dentry *dentry)
+{
+	struct ceph_inode_info *ci = ceph_inode(dir);
+	struct ceph_dentry_info *di = ceph_dentry(dentry);
+	int valid = 0;
+
+	spin_lock(&dir->i_lock);
+	if (ci->i_shared_gen == di->lease_shared_gen)
+		valid = __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1);
+	spin_unlock(&dir->i_lock);
+	dout("dir_lease_is_valid dir %p v%u dentry %p v%u = %d\n",
+	     dir, (unsigned)ci->i_shared_gen, dentry,
+	     (unsigned)di->lease_shared_gen, valid);
+	return valid;
+}
+
+/*
+ * Check if cached dentry can be trusted.
+ */
+static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd)
+{
+	struct inode *dir = dentry->d_parent->d_inode;
+
+	dout("d_revalidate %p '%.*s' inode %p\n", dentry,
+	     dentry->d_name.len, dentry->d_name.name, dentry->d_inode);
+
+	/* always trust cached snapped dentries, snapdir dentry */
+	if (ceph_snap(dir) != CEPH_NOSNAP) {
+		dout("d_revalidate %p '%.*s' inode %p is SNAPPED\n", dentry,
+		     dentry->d_name.len, dentry->d_name.name, dentry->d_inode);
+		goto out_touch;
+	}
+	if (dentry->d_inode && ceph_snap(dentry->d_inode) == CEPH_SNAPDIR)
+		goto out_touch;
+
+	if (dentry_lease_is_valid(dentry) ||
+	    dir_lease_is_valid(dir, dentry))
+		goto out_touch;
+
+	dout("d_revalidate %p invalid\n", dentry);
+	d_drop(dentry);
+	return 0;
+out_touch:
+	ceph_dentry_lru_touch(dentry);
+	return 1;
+}
+
+/*
+ * When a dentry is released, clear the dir I_COMPLETE if it was part
+ * of the current dir gen.
+ */
+static void ceph_dentry_release(struct dentry *dentry)
+{
+	struct ceph_dentry_info *di = ceph_dentry(dentry);
+	struct inode *parent_inode = dentry->d_parent->d_inode;
+
+	if (parent_inode) {
+		struct ceph_inode_info *ci = ceph_inode(parent_inode);
+
+		spin_lock(&parent_inode->i_lock);
+		if (ci->i_shared_gen == di->lease_shared_gen) {
+			dout(" clearing %p complete (d_release)\n",
+			     parent_inode);
+			ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
+			ci->i_release_count++;
+		}
+		spin_unlock(&parent_inode->i_lock);
+	}
+	if (di) {
+		ceph_dentry_lru_del(dentry);
+		if (di->lease_session)
+			ceph_put_mds_session(di->lease_session);
+		kmem_cache_free(ceph_dentry_cachep, di);
+		dentry->d_fsdata = NULL;
+	}
+}
+
+static int ceph_snapdir_d_revalidate(struct dentry *dentry,
+					  struct nameidata *nd)
+{
+	/*
+	 * Eventually, we'll want to revalidate snapped metadata
+	 * too... probably...
+	 */
+	return 1;
+}
+
+
+
+/*
+ * read() on a dir.  This weird interface hack only works if mounted
+ * with '-o dirstat'.
+ */
+static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size,
+			     loff_t *ppos)
+{
+	struct ceph_file_info *cf = file->private_data;
+	struct inode *inode = file->f_dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int left;
+
+	if (!ceph_test_opt(ceph_client(inode->i_sb), DIRSTAT))
+		return -EISDIR;
+
+	if (!cf->dir_info) {
+		cf->dir_info = kmalloc(1024, GFP_NOFS);
+		if (!cf->dir_info)
+			return -ENOMEM;
+		cf->dir_info_len =
+			sprintf(cf->dir_info,
+				"entries:   %20lld\n"
+				" files:    %20lld\n"
+				" subdirs:  %20lld\n"
+				"rentries:  %20lld\n"
+				" rfiles:   %20lld\n"
+				" rsubdirs: %20lld\n"
+				"rbytes:    %20lld\n"
+				"rctime:    %10ld.%09ld\n",
+				ci->i_files + ci->i_subdirs,
+				ci->i_files,
+				ci->i_subdirs,
+				ci->i_rfiles + ci->i_rsubdirs,
+				ci->i_rfiles,
+				ci->i_rsubdirs,
+				ci->i_rbytes,
+				(long)ci->i_rctime.tv_sec,
+				(long)ci->i_rctime.tv_nsec);
+	}
+
+	if (*ppos >= cf->dir_info_len)
+		return 0;
+	size = min_t(unsigned, size, cf->dir_info_len-*ppos);
+	left = copy_to_user(buf, cf->dir_info + *ppos, size);
+	if (left == size)
+		return -EFAULT;
+	*ppos += (size - left);
+	return size - left;
+}
+
+/*
+ * an fsync() on a dir will wait for any uncommitted directory
+ * operations to commit.
+ */
+static int ceph_dir_fsync(struct file *file, struct dentry *dentry,
+			  int datasync)
+{
+	struct inode *inode = dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct list_head *head = &ci->i_unsafe_dirops;
+	struct ceph_mds_request *req;
+	u64 last_tid;
+	int ret = 0;
+
+	dout("dir_fsync %p\n", inode);
+	spin_lock(&ci->i_unsafe_lock);
+	if (list_empty(head))
+		goto out;
+
+	req = list_entry(head->prev,
+			 struct ceph_mds_request, r_unsafe_dir_item);
+	last_tid = req->r_tid;
+
+	do {
+		ceph_mdsc_get_request(req);
+		spin_unlock(&ci->i_unsafe_lock);
+		dout("dir_fsync %p wait on tid %llu (until %llu)\n",
+		     inode, req->r_tid, last_tid);
+		if (req->r_timeout) {
+			ret = wait_for_completion_timeout(
+				&req->r_safe_completion, req->r_timeout);
+			if (ret > 0)
+				ret = 0;
+			else if (ret == 0)
+				ret = -EIO;  /* timed out */
+		} else {
+			wait_for_completion(&req->r_safe_completion);
+		}
+		spin_lock(&ci->i_unsafe_lock);
+		ceph_mdsc_put_request(req);
+
+		if (ret || list_empty(head))
+			break;
+		req = list_entry(head->next,
+				 struct ceph_mds_request, r_unsafe_dir_item);
+	} while (req->r_tid < last_tid);
+out:
+	spin_unlock(&ci->i_unsafe_lock);
+	return ret;
+}
+
+/*
+ * We maintain a private dentry LRU.
+ *
+ * FIXME: this needs to be changed to a per-mds lru to be useful.
+ */
+void ceph_dentry_lru_add(struct dentry *dn)
+{
+	struct ceph_dentry_info *di = ceph_dentry(dn);
+	struct ceph_mds_client *mdsc;
+
+	dout("dentry_lru_add %p %p '%.*s'\n", di, dn,
+	     dn->d_name.len, dn->d_name.name);
+	if (di) {
+		mdsc = &ceph_client(dn->d_sb)->mdsc;
+		spin_lock(&mdsc->dentry_lru_lock);
+		list_add_tail(&di->lru, &mdsc->dentry_lru);
+		mdsc->num_dentry++;
+		spin_unlock(&mdsc->dentry_lru_lock);
+	}
+}
+
+void ceph_dentry_lru_touch(struct dentry *dn)
+{
+	struct ceph_dentry_info *di = ceph_dentry(dn);
+	struct ceph_mds_client *mdsc;
+
+	dout("dentry_lru_touch %p %p '%.*s'\n", di, dn,
+	     dn->d_name.len, dn->d_name.name);
+	if (di) {
+		mdsc = &ceph_client(dn->d_sb)->mdsc;
+		spin_lock(&mdsc->dentry_lru_lock);
+		list_move_tail(&di->lru, &mdsc->dentry_lru);
+		spin_unlock(&mdsc->dentry_lru_lock);
+	}
+}
+
+void ceph_dentry_lru_del(struct dentry *dn)
+{
+	struct ceph_dentry_info *di = ceph_dentry(dn);
+	struct ceph_mds_client *mdsc;
+
+	dout("dentry_lru_del %p %p '%.*s'\n", di, dn,
+	     dn->d_name.len, dn->d_name.name);
+	if (di) {
+		mdsc = &ceph_client(dn->d_sb)->mdsc;
+		spin_lock(&mdsc->dentry_lru_lock);
+		list_del_init(&di->lru);
+		mdsc->num_dentry--;
+		spin_unlock(&mdsc->dentry_lru_lock);
+	}
+}
+
+const struct file_operations ceph_dir_fops = {
+	.read = ceph_read_dir,
+	.readdir = ceph_readdir,
+	.llseek = ceph_dir_llseek,
+	.open = ceph_open,
+	.release = ceph_release,
+	.unlocked_ioctl = ceph_ioctl,
+	.fsync = ceph_dir_fsync,
+};
+
+const struct inode_operations ceph_dir_iops = {
+	.lookup = ceph_lookup,
+	.permission = ceph_permission,
+	.getattr = ceph_getattr,
+	.setattr = ceph_setattr,
+	.setxattr = ceph_setxattr,
+	.getxattr = ceph_getxattr,
+	.listxattr = ceph_listxattr,
+	.removexattr = ceph_removexattr,
+	.mknod = ceph_mknod,
+	.symlink = ceph_symlink,
+	.mkdir = ceph_mkdir,
+	.link = ceph_link,
+	.unlink = ceph_unlink,
+	.rmdir = ceph_unlink,
+	.rename = ceph_rename,
+	.create = ceph_create,
+};
+
+struct dentry_operations ceph_dentry_ops = {
+	.d_revalidate = ceph_d_revalidate,
+	.d_release = ceph_dentry_release,
+};
+
+struct dentry_operations ceph_snapdir_dentry_ops = {
+	.d_revalidate = ceph_snapdir_d_revalidate,
+};
+
+struct dentry_operations ceph_snap_dentry_ops = {
+};
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/export.c linux-libre-2.6.34-gnu1/fs/ceph/export.c
--- linux-libre-2.6.33-gnu1/fs/ceph/export.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/export.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,224 @@
+#include "ceph_debug.h"
+
+#include <linux/exportfs.h>
+#include <linux/slab.h>
+#include <asm/unaligned.h>
+
+#include "super.h"
+
+/*
+ * NFS export support
+ *
+ * NFS re-export of a ceph mount is, at present, only semireliable.
+ * The basic issue is that the Ceph architectures doesn't lend itself
+ * well to generating filehandles that will remain valid forever.
+ *
+ * So, we do our best.  If you're lucky, your inode will be in the
+ * client's cache.  If it's not, and you have a connectable fh, then
+ * the MDS server may be able to find it for you.  Otherwise, you get
+ * ESTALE.
+ *
+ * There are ways to this more reliable, but in the non-connectable fh
+ * case, we won't every work perfectly, and in the connectable case,
+ * some changes are needed on the MDS side to work better.
+ */
+
+/*
+ * Basic fh
+ */
+struct ceph_nfs_fh {
+	u64 ino;
+} __attribute__ ((packed));
+
+/*
+ * Larger 'connectable' fh that includes parent ino and name hash.
+ * Use this whenever possible, as it works more reliably.
+ */
+struct ceph_nfs_confh {
+	u64 ino, parent_ino;
+	u32 parent_name_hash;
+} __attribute__ ((packed));
+
+static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len,
+			  int connectable)
+{
+	struct ceph_nfs_fh *fh = (void *)rawfh;
+	struct ceph_nfs_confh *cfh = (void *)rawfh;
+	struct dentry *parent = dentry->d_parent;
+	struct inode *inode = dentry->d_inode;
+	int type;
+
+	/* don't re-export snaps */
+	if (ceph_snap(inode) != CEPH_NOSNAP)
+		return -EINVAL;
+
+	if (*max_len >= sizeof(*cfh)) {
+		dout("encode_fh %p connectable\n", dentry);
+		cfh->ino = ceph_ino(dentry->d_inode);
+		cfh->parent_ino = ceph_ino(parent->d_inode);
+		cfh->parent_name_hash = parent->d_name.hash;
+		*max_len = sizeof(*cfh);
+		type = 2;
+	} else if (*max_len > sizeof(*fh)) {
+		if (connectable)
+			return -ENOSPC;
+		dout("encode_fh %p\n", dentry);
+		fh->ino = ceph_ino(dentry->d_inode);
+		*max_len = sizeof(*fh);
+		type = 1;
+	} else {
+		return -ENOSPC;
+	}
+	return type;
+}
+
+/*
+ * convert regular fh to dentry
+ *
+ * FIXME: we should try harder by querying the mds for the ino.
+ */
+static struct dentry *__fh_to_dentry(struct super_block *sb,
+				     struct ceph_nfs_fh *fh)
+{
+	struct inode *inode;
+	struct dentry *dentry;
+	struct ceph_vino vino;
+	int err;
+
+	dout("__fh_to_dentry %llx\n", fh->ino);
+	vino.ino = fh->ino;
+	vino.snap = CEPH_NOSNAP;
+	inode = ceph_find_inode(sb, vino);
+	if (!inode)
+		return ERR_PTR(-ESTALE);
+
+	dentry = d_obtain_alias(inode);
+	if (!dentry) {
+		pr_err("fh_to_dentry %llx -- inode %p but ENOMEM\n",
+		       fh->ino, inode);
+		iput(inode);
+		return ERR_PTR(-ENOMEM);
+	}
+	err = ceph_init_dentry(dentry);
+
+	if (err < 0) {
+		iput(inode);
+		return ERR_PTR(err);
+	}
+	dout("__fh_to_dentry %llx %p dentry %p\n", fh->ino, inode, dentry);
+	return dentry;
+}
+
+/*
+ * convert connectable fh to dentry
+ */
+static struct dentry *__cfh_to_dentry(struct super_block *sb,
+				      struct ceph_nfs_confh *cfh)
+{
+	struct ceph_mds_client *mdsc = &ceph_client(sb)->mdsc;
+	struct inode *inode;
+	struct dentry *dentry;
+	struct ceph_vino vino;
+	int err;
+
+	dout("__cfh_to_dentry %llx (%llx/%x)\n",
+	     cfh->ino, cfh->parent_ino, cfh->parent_name_hash);
+
+	vino.ino = cfh->ino;
+	vino.snap = CEPH_NOSNAP;
+	inode = ceph_find_inode(sb, vino);
+	if (!inode) {
+		struct ceph_mds_request *req;
+
+		req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPHASH,
+					       USE_ANY_MDS);
+		if (IS_ERR(req))
+			return ERR_PTR(PTR_ERR(req));
+
+		req->r_ino1 = vino;
+		req->r_ino2.ino = cfh->parent_ino;
+		req->r_ino2.snap = CEPH_NOSNAP;
+		req->r_path2 = kmalloc(16, GFP_NOFS);
+		snprintf(req->r_path2, 16, "%d", cfh->parent_name_hash);
+		req->r_num_caps = 1;
+		err = ceph_mdsc_do_request(mdsc, NULL, req);
+		ceph_mdsc_put_request(req);
+		inode = ceph_find_inode(sb, vino);
+		if (!inode)
+			return ERR_PTR(err ? err : -ESTALE);
+	}
+
+	dentry = d_obtain_alias(inode);
+	if (!dentry) {
+		pr_err("cfh_to_dentry %llx -- inode %p but ENOMEM\n",
+		       cfh->ino, inode);
+		iput(inode);
+		return ERR_PTR(-ENOMEM);
+	}
+	err = ceph_init_dentry(dentry);
+	if (err < 0) {
+		iput(inode);
+		return ERR_PTR(err);
+	}
+	dout("__cfh_to_dentry %llx %p dentry %p\n", cfh->ino, inode, dentry);
+	return dentry;
+}
+
+static struct dentry *ceph_fh_to_dentry(struct super_block *sb, struct fid *fid,
+					int fh_len, int fh_type)
+{
+	if (fh_type == 1)
+		return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw);
+	else
+		return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw);
+}
+
+/*
+ * get parent, if possible.
+ *
+ * FIXME: we could do better by querying the mds to discover the
+ * parent.
+ */
+static struct dentry *ceph_fh_to_parent(struct super_block *sb,
+					 struct fid *fid,
+					int fh_len, int fh_type)
+{
+	struct ceph_nfs_confh *cfh = (void *)fid->raw;
+	struct ceph_vino vino;
+	struct inode *inode;
+	struct dentry *dentry;
+	int err;
+
+	if (fh_type == 1)
+		return ERR_PTR(-ESTALE);
+
+	pr_debug("fh_to_parent %llx/%d\n", cfh->parent_ino,
+		 cfh->parent_name_hash);
+
+	vino.ino = cfh->ino;
+	vino.snap = CEPH_NOSNAP;
+	inode = ceph_find_inode(sb, vino);
+	if (!inode)
+		return ERR_PTR(-ESTALE);
+
+	dentry = d_obtain_alias(inode);
+	if (!dentry) {
+		pr_err("fh_to_parent %llx -- inode %p but ENOMEM\n",
+		       cfh->ino, inode);
+		iput(inode);
+		return ERR_PTR(-ENOMEM);
+	}
+	err = ceph_init_dentry(dentry);
+	if (err < 0) {
+		iput(inode);
+		return ERR_PTR(err);
+	}
+	dout("fh_to_parent %llx %p dentry %p\n", cfh->ino, inode, dentry);
+	return dentry;
+}
+
+const struct export_operations ceph_export_ops = {
+	.encode_fh = ceph_encode_fh,
+	.fh_to_dentry = ceph_fh_to_dentry,
+	.fh_to_parent = ceph_fh_to_parent,
+};
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/file.c linux-libre-2.6.34-gnu1/fs/ceph/file.c
--- linux-libre-2.6.33-gnu1/fs/ceph/file.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/file.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,939 @@
+#include "ceph_debug.h"
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/file.h>
+#include <linux/namei.h>
+#include <linux/writeback.h>
+
+#include "super.h"
+#include "mds_client.h"
+
+/*
+ * Ceph file operations
+ *
+ * Implement basic open/close functionality, and implement
+ * read/write.
+ *
+ * We implement three modes of file I/O:
+ *  - buffered uses the generic_file_aio_{read,write} helpers
+ *
+ *  - synchronous is used when there is multi-client read/write
+ *    sharing, avoids the page cache, and synchronously waits for an
+ *    ack from the OSD.
+ *
+ *  - direct io takes the variant of the sync path that references
+ *    user pages directly.
+ *
+ * fsync() flushes and waits on dirty pages, but just queues metadata
+ * for writeback: since the MDS can recover size and mtime there is no
+ * need to wait for MDS acknowledgement.
+ */
+
+
+/*
+ * Prepare an open request.  Preallocate ceph_cap to avoid an
+ * inopportune ENOMEM later.
+ */
+static struct ceph_mds_request *
+prepare_open_request(struct super_block *sb, int flags, int create_mode)
+{
+	struct ceph_client *client = ceph_sb_to_client(sb);
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct ceph_mds_request *req;
+	int want_auth = USE_ANY_MDS;
+	int op = (flags & O_CREAT) ? CEPH_MDS_OP_CREATE : CEPH_MDS_OP_OPEN;
+
+	if (flags & (O_WRONLY|O_RDWR|O_CREAT|O_TRUNC))
+		want_auth = USE_AUTH_MDS;
+
+	req = ceph_mdsc_create_request(mdsc, op, want_auth);
+	if (IS_ERR(req))
+		goto out;
+	req->r_fmode = ceph_flags_to_mode(flags);
+	req->r_args.open.flags = cpu_to_le32(flags);
+	req->r_args.open.mode = cpu_to_le32(create_mode);
+	req->r_args.open.preferred = cpu_to_le32(-1);
+out:
+	return req;
+}
+
+/*
+ * initialize private struct file data.
+ * if we fail, clean up by dropping fmode reference on the ceph_inode
+ */
+static int ceph_init_file(struct inode *inode, struct file *file, int fmode)
+{
+	struct ceph_file_info *cf;
+	int ret = 0;
+
+	switch (inode->i_mode & S_IFMT) {
+	case S_IFREG:
+	case S_IFDIR:
+		dout("init_file %p %p 0%o (regular)\n", inode, file,
+		     inode->i_mode);
+		cf = kmem_cache_alloc(ceph_file_cachep, GFP_NOFS | __GFP_ZERO);
+		if (cf == NULL) {
+			ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
+			return -ENOMEM;
+		}
+		cf->fmode = fmode;
+		cf->next_offset = 2;
+		file->private_data = cf;
+		BUG_ON(inode->i_fop->release != ceph_release);
+		break;
+
+	case S_IFLNK:
+		dout("init_file %p %p 0%o (symlink)\n", inode, file,
+		     inode->i_mode);
+		ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
+		break;
+
+	default:
+		dout("init_file %p %p 0%o (special)\n", inode, file,
+		     inode->i_mode);
+		/*
+		 * we need to drop the open ref now, since we don't
+		 * have .release set to ceph_release.
+		 */
+		ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
+		BUG_ON(inode->i_fop->release == ceph_release);
+
+		/* call the proper open fop */
+		ret = inode->i_fop->open(inode, file);
+	}
+	return ret;
+}
+
+/*
+ * If the filp already has private_data, that means the file was
+ * already opened by intent during lookup, and we do nothing.
+ *
+ * If we already have the requisite capabilities, we can satisfy
+ * the open request locally (no need to request new caps from the
+ * MDS).  We do, however, need to inform the MDS (asynchronously)
+ * if our wanted caps set expands.
+ */
+int ceph_open(struct inode *inode, struct file *file)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_client *client = ceph_sb_to_client(inode->i_sb);
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct ceph_mds_request *req;
+	struct ceph_file_info *cf = file->private_data;
+	struct inode *parent_inode = file->f_dentry->d_parent->d_inode;
+	int err;
+	int flags, fmode, wanted;
+
+	if (cf) {
+		dout("open file %p is already opened\n", file);
+		return 0;
+	}
+
+	/* filter out O_CREAT|O_EXCL; vfs did that already.  yuck. */
+	flags = file->f_flags & ~(O_CREAT|O_EXCL);
+	if (S_ISDIR(inode->i_mode))
+		flags = O_DIRECTORY;  /* mds likes to know */
+
+	dout("open inode %p ino %llx.%llx file %p flags %d (%d)\n", inode,
+	     ceph_vinop(inode), file, flags, file->f_flags);
+	fmode = ceph_flags_to_mode(flags);
+	wanted = ceph_caps_for_mode(fmode);
+
+	/* snapped files are read-only */
+	if (ceph_snap(inode) != CEPH_NOSNAP && (file->f_mode & FMODE_WRITE))
+		return -EROFS;
+
+	/* trivially open snapdir */
+	if (ceph_snap(inode) == CEPH_SNAPDIR) {
+		spin_lock(&inode->i_lock);
+		__ceph_get_fmode(ci, fmode);
+		spin_unlock(&inode->i_lock);
+		return ceph_init_file(inode, file, fmode);
+	}
+
+	/*
+	 * No need to block if we have any caps.  Update wanted set
+	 * asynchronously.
+	 */
+	spin_lock(&inode->i_lock);
+	if (__ceph_is_any_real_caps(ci)) {
+		int mds_wanted = __ceph_caps_mds_wanted(ci);
+		int issued = __ceph_caps_issued(ci, NULL);
+
+		dout("open %p fmode %d want %s issued %s using existing\n",
+		     inode, fmode, ceph_cap_string(wanted),
+		     ceph_cap_string(issued));
+		__ceph_get_fmode(ci, fmode);
+		spin_unlock(&inode->i_lock);
+
+		/* adjust wanted? */
+		if ((issued & wanted) != wanted &&
+		    (mds_wanted & wanted) != wanted &&
+		    ceph_snap(inode) != CEPH_SNAPDIR)
+			ceph_check_caps(ci, 0, NULL);
+
+		return ceph_init_file(inode, file, fmode);
+	} else if (ceph_snap(inode) != CEPH_NOSNAP &&
+		   (ci->i_snap_caps & wanted) == wanted) {
+		__ceph_get_fmode(ci, fmode);
+		spin_unlock(&inode->i_lock);
+		return ceph_init_file(inode, file, fmode);
+	}
+	spin_unlock(&inode->i_lock);
+
+	dout("open fmode %d wants %s\n", fmode, ceph_cap_string(wanted));
+	req = prepare_open_request(inode->i_sb, flags, 0);
+	if (IS_ERR(req)) {
+		err = PTR_ERR(req);
+		goto out;
+	}
+	req->r_inode = igrab(inode);
+	req->r_num_caps = 1;
+	err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+	if (!err)
+		err = ceph_init_file(inode, file, req->r_fmode);
+	ceph_mdsc_put_request(req);
+	dout("open result=%d on %llx.%llx\n", err, ceph_vinop(inode));
+out:
+	return err;
+}
+
+
+/*
+ * Do a lookup + open with a single request.
+ *
+ * If this succeeds, but some subsequent check in the vfs
+ * may_open() fails, the struct *file gets cleaned up (i.e.
+ * ceph_release gets called).  So fear not!
+ */
+/*
+ * flags
+ *  path_lookup_open   -> LOOKUP_OPEN
+ *  path_lookup_create -> LOOKUP_OPEN|LOOKUP_CREATE
+ */
+struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
+				struct nameidata *nd, int mode,
+				int locked_dir)
+{
+	struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct file *file = nd->intent.open.file;
+	struct inode *parent_inode = get_dentry_parent_inode(file->f_dentry);
+	struct ceph_mds_request *req;
+	int err;
+	int flags = nd->intent.open.flags - 1;  /* silly vfs! */
+
+	dout("ceph_lookup_open dentry %p '%.*s' flags %d mode 0%o\n",
+	     dentry, dentry->d_name.len, dentry->d_name.name, flags, mode);
+
+	/* do the open */
+	req = prepare_open_request(dir->i_sb, flags, mode);
+	if (IS_ERR(req))
+		return ERR_PTR(PTR_ERR(req));
+	req->r_dentry = dget(dentry);
+	req->r_num_caps = 2;
+	if (flags & O_CREAT) {
+		req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+		req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+	}
+	req->r_locked_dir = dir;           /* caller holds dir->i_mutex */
+	err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+	dentry = ceph_finish_lookup(req, dentry, err);
+	if (!err && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
+		err = ceph_handle_notrace_create(dir, dentry);
+	if (!err)
+		err = ceph_init_file(req->r_dentry->d_inode, file,
+				     req->r_fmode);
+	ceph_mdsc_put_request(req);
+	dout("ceph_lookup_open result=%p\n", dentry);
+	return dentry;
+}
+
+int ceph_release(struct inode *inode, struct file *file)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_file_info *cf = file->private_data;
+
+	dout("release inode %p file %p\n", inode, file);
+	ceph_put_fmode(ci, cf->fmode);
+	if (cf->last_readdir)
+		ceph_mdsc_put_request(cf->last_readdir);
+	kfree(cf->last_name);
+	kfree(cf->dir_info);
+	dput(cf->dentry);
+	kmem_cache_free(ceph_file_cachep, cf);
+
+	/* wake up anyone waiting for caps on this inode */
+	wake_up(&ci->i_cap_wq);
+	return 0;
+}
+
+/*
+ * build a vector of user pages
+ */
+static struct page **get_direct_page_vector(const char __user *data,
+					    int num_pages,
+					    loff_t off, size_t len)
+{
+	struct page **pages;
+	int rc;
+
+	pages = kmalloc(sizeof(*pages) * num_pages, GFP_NOFS);
+	if (!pages)
+		return ERR_PTR(-ENOMEM);
+
+	down_read(&current->mm->mmap_sem);
+	rc = get_user_pages(current, current->mm, (unsigned long)data,
+			    num_pages, 0, 0, pages, NULL);
+	up_read(&current->mm->mmap_sem);
+	if (rc < 0)
+		goto fail;
+	return pages;
+
+fail:
+	kfree(pages);
+	return ERR_PTR(rc);
+}
+
+static void put_page_vector(struct page **pages, int num_pages)
+{
+	int i;
+
+	for (i = 0; i < num_pages; i++)
+		put_page(pages[i]);
+	kfree(pages);
+}
+
+void ceph_release_page_vector(struct page **pages, int num_pages)
+{
+	int i;
+
+	for (i = 0; i < num_pages; i++)
+		__free_pages(pages[i], 0);
+	kfree(pages);
+}
+
+/*
+ * allocate a vector new pages
+ */
+static struct page **alloc_page_vector(int num_pages)
+{
+	struct page **pages;
+	int i;
+
+	pages = kmalloc(sizeof(*pages) * num_pages, GFP_NOFS);
+	if (!pages)
+		return ERR_PTR(-ENOMEM);
+	for (i = 0; i < num_pages; i++) {
+		pages[i] = alloc_page(GFP_NOFS);
+		if (pages[i] == NULL) {
+			ceph_release_page_vector(pages, i);
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+	return pages;
+}
+
+/*
+ * copy user data into a page vector
+ */
+static int copy_user_to_page_vector(struct page **pages,
+				    const char __user *data,
+				    loff_t off, size_t len)
+{
+	int i = 0;
+	int po = off & ~PAGE_CACHE_MASK;
+	int left = len;
+	int l, bad;
+
+	while (left > 0) {
+		l = min_t(int, PAGE_CACHE_SIZE-po, left);
+		bad = copy_from_user(page_address(pages[i]) + po, data, l);
+		if (bad == l)
+			return -EFAULT;
+		data += l - bad;
+		left -= l - bad;
+		po += l - bad;
+		if (po == PAGE_CACHE_SIZE) {
+			po = 0;
+			i++;
+		}
+	}
+	return len;
+}
+
+/*
+ * copy user data from a page vector into a user pointer
+ */
+static int copy_page_vector_to_user(struct page **pages, char __user *data,
+				    loff_t off, size_t len)
+{
+	int i = 0;
+	int po = off & ~PAGE_CACHE_MASK;
+	int left = len;
+	int l, bad;
+
+	while (left > 0) {
+		l = min_t(int, left, PAGE_CACHE_SIZE-po);
+		bad = copy_to_user(data, page_address(pages[i]) + po, l);
+		if (bad == l)
+			return -EFAULT;
+		data += l - bad;
+		left -= l - bad;
+		if (po) {
+			po += l - bad;
+			if (po == PAGE_CACHE_SIZE)
+				po = 0;
+		}
+		i++;
+	}
+	return len;
+}
+
+/*
+ * Zero an extent within a page vector.  Offset is relative to the
+ * start of the first page.
+ */
+static void zero_page_vector_range(int off, int len, struct page **pages)
+{
+	int i = off >> PAGE_CACHE_SHIFT;
+
+	off &= ~PAGE_CACHE_MASK;
+
+	dout("zero_page_vector_page %u~%u\n", off, len);
+
+	/* leading partial page? */
+	if (off) {
+		int end = min((int)PAGE_CACHE_SIZE, off + len);
+		dout("zeroing %d %p head from %d\n", i, pages[i],
+		     (int)off);
+		zero_user_segment(pages[i], off, end);
+		len -= (end - off);
+		i++;
+	}
+	while (len >= PAGE_CACHE_SIZE) {
+		dout("zeroing %d %p len=%d\n", i, pages[i], len);
+		zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE);
+		len -= PAGE_CACHE_SIZE;
+		i++;
+	}
+	/* trailing partial page? */
+	if (len) {
+		dout("zeroing %d %p tail to %d\n", i, pages[i], (int)len);
+		zero_user_segment(pages[i], 0, len);
+	}
+}
+
+
+/*
+ * Read a range of bytes striped over one or more objects.  Iterate over
+ * objects we stripe over.  (That's not atomic, but good enough for now.)
+ *
+ * If we get a short result from the OSD, check against i_size; we need to
+ * only return a short read to the caller if we hit EOF.
+ */
+static int striped_read(struct inode *inode,
+			u64 off, u64 len,
+			struct page **pages, int num_pages,
+			int *checkeof)
+{
+	struct ceph_client *client = ceph_inode_to_client(inode);
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	u64 pos, this_len;
+	int page_off = off & ~PAGE_CACHE_MASK; /* first byte's offset in page */
+	int left, pages_left;
+	int read;
+	struct page **page_pos;
+	int ret;
+	bool hit_stripe, was_short;
+
+	/*
+	 * we may need to do multiple reads.  not atomic, unfortunately.
+	 */
+	pos = off;
+	left = len;
+	page_pos = pages;
+	pages_left = num_pages;
+	read = 0;
+
+more:
+	this_len = left;
+	ret = ceph_osdc_readpages(&client->osdc, ceph_vino(inode),
+				  &ci->i_layout, pos, &this_len,
+				  ci->i_truncate_seq,
+				  ci->i_truncate_size,
+				  page_pos, pages_left);
+	hit_stripe = this_len < left;
+	was_short = ret >= 0 && ret < this_len;
+	if (ret == -ENOENT)
+		ret = 0;
+	dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left, read,
+	     ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");
+
+	if (ret > 0) {
+		int didpages =
+			((pos & ~PAGE_CACHE_MASK) + ret) >> PAGE_CACHE_SHIFT;
+
+		if (read < pos - off) {
+			dout(" zero gap %llu to %llu\n", off + read, pos);
+			zero_page_vector_range(page_off + read,
+					       pos - off - read, pages);
+		}
+		pos += ret;
+		read = pos - off;
+		left -= ret;
+		page_pos += didpages;
+		pages_left -= didpages;
+
+		/* hit stripe? */
+		if (left && hit_stripe)
+			goto more;
+	}
+
+	if (was_short) {
+		/* was original extent fully inside i_size? */
+		if (pos + left <= inode->i_size) {
+			dout("zero tail\n");
+			zero_page_vector_range(page_off + read, len - read,
+					       pages);
+			read = len;
+			goto out;
+		}
+
+		/* check i_size */
+		*checkeof = 1;
+	}
+
+out:
+	if (ret >= 0)
+		ret = read;
+	dout("striped_read returns %d\n", ret);
+	return ret;
+}
+
+/*
+ * Completely synchronous read and write methods.  Direct from __user
+ * buffer to osd, or directly to user pages (if O_DIRECT).
+ *
+ * If the read spans object boundary, just do multiple reads.
+ */
+static ssize_t ceph_sync_read(struct file *file, char __user *data,
+			      unsigned len, loff_t *poff, int *checkeof)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	struct page **pages;
+	u64 off = *poff;
+	int num_pages = calc_pages_for(off, len);
+	int ret;
+
+	dout("sync_read on file %p %llu~%u %s\n", file, off, len,
+	     (file->f_flags & O_DIRECT) ? "O_DIRECT" : "");
+
+	if (file->f_flags & O_DIRECT) {
+		pages = get_direct_page_vector(data, num_pages, off, len);
+
+		/*
+		 * flush any page cache pages in this range.  this
+		 * will make concurrent normal and O_DIRECT io slow,
+		 * but it will at least behave sensibly when they are
+		 * in sequence.
+		 */
+	} else {
+		pages = alloc_page_vector(num_pages);
+	}
+	if (IS_ERR(pages))
+		return PTR_ERR(pages);
+
+	ret = filemap_write_and_wait(inode->i_mapping);
+	if (ret < 0)
+		goto done;
+
+	ret = striped_read(inode, off, len, pages, num_pages, checkeof);
+
+	if (ret >= 0 && (file->f_flags & O_DIRECT) == 0)
+		ret = copy_page_vector_to_user(pages, data, off, ret);
+	if (ret >= 0)
+		*poff = off + ret;
+
+done:
+	if (file->f_flags & O_DIRECT)
+		put_page_vector(pages, num_pages);
+	else
+		ceph_release_page_vector(pages, num_pages);
+	dout("sync_read result %d\n", ret);
+	return ret;
+}
+
+/*
+ * Write commit callback, called if we requested both an ACK and
+ * ONDISK commit reply from the OSD.
+ */
+static void sync_write_commit(struct ceph_osd_request *req,
+			      struct ceph_msg *msg)
+{
+	struct ceph_inode_info *ci = ceph_inode(req->r_inode);
+
+	dout("sync_write_commit %p tid %llu\n", req, req->r_tid);
+	spin_lock(&ci->i_unsafe_lock);
+	list_del_init(&req->r_unsafe_item);
+	spin_unlock(&ci->i_unsafe_lock);
+	ceph_put_cap_refs(ci, CEPH_CAP_FILE_WR);
+}
+
+/*
+ * Synchronous write, straight from __user pointer or user pages (if
+ * O_DIRECT).
+ *
+ * If write spans object boundary, just do multiple writes.  (For a
+ * correct atomic write, we should e.g. take write locks on all
+ * objects, rollback on failure, etc.)
+ */
+static ssize_t ceph_sync_write(struct file *file, const char __user *data,
+			       size_t left, loff_t *offset)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_client *client = ceph_inode_to_client(inode);
+	struct ceph_osd_request *req;
+	struct page **pages;
+	int num_pages;
+	long long unsigned pos;
+	u64 len;
+	int written = 0;
+	int flags;
+	int do_sync = 0;
+	int check_caps = 0;
+	int ret;
+	struct timespec mtime = CURRENT_TIME;
+
+	if (ceph_snap(file->f_dentry->d_inode) != CEPH_NOSNAP)
+		return -EROFS;
+
+	dout("sync_write on file %p %lld~%u %s\n", file, *offset,
+	     (unsigned)left, (file->f_flags & O_DIRECT) ? "O_DIRECT" : "");
+
+	if (file->f_flags & O_APPEND)
+		pos = i_size_read(inode);
+	else
+		pos = *offset;
+
+	ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left);
+	if (ret < 0)
+		return ret;
+
+	ret = invalidate_inode_pages2_range(inode->i_mapping,
+					    pos >> PAGE_CACHE_SHIFT,
+					    (pos + left) >> PAGE_CACHE_SHIFT);
+	if (ret < 0)
+		dout("invalidate_inode_pages2_range returned %d\n", ret);
+
+	flags = CEPH_OSD_FLAG_ORDERSNAP |
+		CEPH_OSD_FLAG_ONDISK |
+		CEPH_OSD_FLAG_WRITE;
+	if ((file->f_flags & (O_SYNC|O_DIRECT)) == 0)
+		flags |= CEPH_OSD_FLAG_ACK;
+	else
+		do_sync = 1;
+
+	/*
+	 * we may need to do multiple writes here if we span an object
+	 * boundary.  this isn't atomic, unfortunately.  :(
+	 */
+more:
+	len = left;
+	req = ceph_osdc_new_request(&client->osdc, &ci->i_layout,
+				    ceph_vino(inode), pos, &len,
+				    CEPH_OSD_OP_WRITE, flags,
+				    ci->i_snap_realm->cached_context,
+				    do_sync,
+				    ci->i_truncate_seq, ci->i_truncate_size,
+				    &mtime, false, 2);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	num_pages = calc_pages_for(pos, len);
+
+	if (file->f_flags & O_DIRECT) {
+		pages = get_direct_page_vector(data, num_pages, pos, len);
+		if (IS_ERR(pages)) {
+			ret = PTR_ERR(pages);
+			goto out;
+		}
+
+		/*
+		 * throw out any page cache pages in this range. this
+		 * may block.
+		 */
+		truncate_inode_pages_range(inode->i_mapping, pos, 
+					   (pos+len) | (PAGE_CACHE_SIZE-1));
+	} else {
+		pages = alloc_page_vector(num_pages);
+		if (IS_ERR(pages)) {
+			ret = PTR_ERR(pages);
+			goto out;
+		}
+		ret = copy_user_to_page_vector(pages, data, pos, len);
+		if (ret < 0) {
+			ceph_release_page_vector(pages, num_pages);
+			goto out;
+		}
+
+		if ((file->f_flags & O_SYNC) == 0) {
+			/* get a second commit callback */
+			req->r_safe_callback = sync_write_commit;
+			req->r_own_pages = 1;
+		}
+	}
+	req->r_pages = pages;
+	req->r_num_pages = num_pages;
+	req->r_inode = inode;
+
+	ret = ceph_osdc_start_request(&client->osdc, req, false);
+	if (!ret) {
+		if (req->r_safe_callback) {
+			/*
+			 * Add to inode unsafe list only after we
+			 * start_request so that a tid has been assigned.
+			 */
+			spin_lock(&ci->i_unsafe_lock);
+			list_add(&ci->i_unsafe_writes, &req->r_unsafe_item);
+			spin_unlock(&ci->i_unsafe_lock);
+			ceph_get_cap_refs(ci, CEPH_CAP_FILE_WR);
+		}
+		ret = ceph_osdc_wait_request(&client->osdc, req);
+	}
+
+	if (file->f_flags & O_DIRECT)
+		put_page_vector(pages, num_pages);
+	else if (file->f_flags & O_SYNC)
+		ceph_release_page_vector(pages, num_pages);
+
+out:
+	ceph_osdc_put_request(req);
+	if (ret == 0) {
+		pos += len;
+		written += len;
+		left -= len;
+		if (left)
+			goto more;
+
+		ret = written;
+		*offset = pos;
+		if (pos > i_size_read(inode))
+			check_caps = ceph_inode_set_size(inode, pos);
+		if (check_caps)
+			ceph_check_caps(ceph_inode(inode), CHECK_CAPS_AUTHONLY,
+					NULL);
+	}
+	return ret;
+}
+
+/*
+ * Wrap generic_file_aio_read with checks for cap bits on the inode.
+ * Atomically grab references, so that those bits are not released
+ * back to the MDS mid-read.
+ *
+ * Hmm, the sync read case isn't actually async... should it be?
+ */
+static ssize_t ceph_aio_read(struct kiocb *iocb, const struct iovec *iov,
+			     unsigned long nr_segs, loff_t pos)
+{
+	struct file *filp = iocb->ki_filp;
+	loff_t *ppos = &iocb->ki_pos;
+	size_t len = iov->iov_len;
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	void *base = iov->iov_base;
+	ssize_t ret;
+	int got = 0;
+	int checkeof = 0, read = 0;
+
+	dout("aio_read %p %llx.%llx %llu~%u trying to get caps on %p\n",
+	     inode, ceph_vinop(inode), pos, (unsigned)len, inode);
+again:
+	__ceph_do_pending_vmtruncate(inode);
+	ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD, CEPH_CAP_FILE_CACHE,
+			    &got, -1);
+	if (ret < 0)
+		goto out;
+	dout("aio_read %p %llx.%llx %llu~%u got cap refs on %s\n",
+	     inode, ceph_vinop(inode), pos, (unsigned)len,
+	     ceph_cap_string(got));
+
+	if ((got & CEPH_CAP_FILE_CACHE) == 0 ||
+	    (iocb->ki_filp->f_flags & O_DIRECT) ||
+	    (inode->i_sb->s_flags & MS_SYNCHRONOUS))
+		/* hmm, this isn't really async... */
+		ret = ceph_sync_read(filp, base, len, ppos, &checkeof);
+	else
+		ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
+
+out:
+	dout("aio_read %p %llx.%llx dropping cap refs on %s = %d\n",
+	     inode, ceph_vinop(inode), ceph_cap_string(got), (int)ret);
+	ceph_put_cap_refs(ci, got);
+
+	if (checkeof && ret >= 0) {
+		int statret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE);
+
+		/* hit EOF or hole? */
+		if (statret == 0 && *ppos < inode->i_size) {
+			dout("aio_read sync_read hit hole, reading more\n");
+			read += ret;
+			base += ret;
+			len -= ret;
+			checkeof = 0;
+			goto again;
+		}
+	}
+	if (ret >= 0)
+		ret += read;
+
+	return ret;
+}
+
+/*
+ * Take cap references to avoid releasing caps to MDS mid-write.
+ *
+ * If we are synchronous, and write with an old snap context, the OSD
+ * may return EOLDSNAPC.  In that case, retry the write.. _after_
+ * dropping our cap refs and allowing the pending snap to logically
+ * complete _before_ this write occurs.
+ *
+ * If we are near ENOSPC, write synchronously.
+ */
+static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov,
+		       unsigned long nr_segs, loff_t pos)
+{
+	struct file *file = iocb->ki_filp;
+	struct inode *inode = file->f_dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_osd_client *osdc = &ceph_client(inode->i_sb)->osdc;
+	loff_t endoff = pos + iov->iov_len;
+	int got = 0;
+	int ret, err;
+
+	if (ceph_snap(inode) != CEPH_NOSNAP)
+		return -EROFS;
+
+retry_snap:
+	if (ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL))
+		return -ENOSPC;
+	__ceph_do_pending_vmtruncate(inode);
+	dout("aio_write %p %llx.%llx %llu~%u getting caps. i_size %llu\n",
+	     inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len,
+	     inode->i_size);
+	ret = ceph_get_caps(ci, CEPH_CAP_FILE_WR, CEPH_CAP_FILE_BUFFER,
+			    &got, endoff);
+	if (ret < 0)
+		goto out;
+
+	dout("aio_write %p %llx.%llx %llu~%u  got cap refs on %s\n",
+	     inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len,
+	     ceph_cap_string(got));
+
+	if ((got & CEPH_CAP_FILE_BUFFER) == 0 ||
+	    (iocb->ki_filp->f_flags & O_DIRECT) ||
+	    (inode->i_sb->s_flags & MS_SYNCHRONOUS)) {
+		ret = ceph_sync_write(file, iov->iov_base, iov->iov_len,
+			&iocb->ki_pos);
+	} else {
+		ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
+
+		if ((ret >= 0 || ret == -EIOCBQUEUED) &&
+		    ((file->f_flags & O_SYNC) || IS_SYNC(file->f_mapping->host)
+		     || ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL))) {
+			err = vfs_fsync_range(file, file->f_path.dentry,
+					      pos, pos + ret - 1, 1);
+			if (err < 0)
+				ret = err;
+		}
+	}
+	if (ret >= 0) {
+		spin_lock(&inode->i_lock);
+		__ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR);
+		spin_unlock(&inode->i_lock);
+	}
+
+out:
+	dout("aio_write %p %llx.%llx %llu~%u  dropping cap refs on %s\n",
+	     inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len,
+	     ceph_cap_string(got));
+	ceph_put_cap_refs(ci, got);
+
+	if (ret == -EOLDSNAPC) {
+		dout("aio_write %p %llx.%llx %llu~%u got EOLDSNAPC, retrying\n",
+		     inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len);
+		goto retry_snap;
+	}
+
+	return ret;
+}
+
+/*
+ * llseek.  be sure to verify file size on SEEK_END.
+ */
+static loff_t ceph_llseek(struct file *file, loff_t offset, int origin)
+{
+	struct inode *inode = file->f_mapping->host;
+	int ret;
+
+	mutex_lock(&inode->i_mutex);
+	__ceph_do_pending_vmtruncate(inode);
+	switch (origin) {
+	case SEEK_END:
+		ret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE);
+		if (ret < 0) {
+			offset = ret;
+			goto out;
+		}
+		offset += inode->i_size;
+		break;
+	case SEEK_CUR:
+		/*
+		 * Here we special-case the lseek(fd, 0, SEEK_CUR)
+		 * position-querying operation.  Avoid rewriting the "same"
+		 * f_pos value back to the file because a concurrent read(),
+		 * write() or lseek() might have altered it
+		 */
+		if (offset == 0) {
+			offset = file->f_pos;
+			goto out;
+		}
+		offset += file->f_pos;
+		break;
+	}
+
+	if (offset < 0 || offset > inode->i_sb->s_maxbytes) {
+		offset = -EINVAL;
+		goto out;
+	}
+
+	/* Special lock needed here? */
+	if (offset != file->f_pos) {
+		file->f_pos = offset;
+		file->f_version = 0;
+	}
+
+out:
+	mutex_unlock(&inode->i_mutex);
+	return offset;
+}
+
+const struct file_operations ceph_file_fops = {
+	.open = ceph_open,
+	.release = ceph_release,
+	.llseek = ceph_llseek,
+	.read = do_sync_read,
+	.write = do_sync_write,
+	.aio_read = ceph_aio_read,
+	.aio_write = ceph_aio_write,
+	.mmap = ceph_mmap,
+	.fsync = ceph_fsync,
+	.splice_read = generic_file_splice_read,
+	.splice_write = generic_file_splice_write,
+	.unlocked_ioctl = ceph_ioctl,
+	.compat_ioctl	= ceph_ioctl,
+};
+
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/inode.c linux-libre-2.6.34-gnu1/fs/ceph/inode.c
--- linux-libre-2.6.33-gnu1/fs/ceph/inode.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1782 @@
+#include "ceph_debug.h"
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/smp_lock.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+#include <linux/kernel.h>
+#include <linux/namei.h>
+#include <linux/writeback.h>
+#include <linux/vmalloc.h>
+#include <linux/pagevec.h>
+
+#include "super.h"
+#include "decode.h"
+
+/*
+ * Ceph inode operations
+ *
+ * Implement basic inode helpers (get, alloc) and inode ops (getattr,
+ * setattr, etc.), xattr helpers, and helpers for assimilating
+ * metadata returned by the MDS into our cache.
+ *
+ * Also define helpers for doing asynchronous writeback, invalidation,
+ * and truncation for the benefit of those who can't afford to block
+ * (typically because they are in the message handler path).
+ */
+
+static const struct inode_operations ceph_symlink_iops;
+
+static void ceph_invalidate_work(struct work_struct *work);
+static void ceph_writeback_work(struct work_struct *work);
+static void ceph_vmtruncate_work(struct work_struct *work);
+
+/*
+ * find or create an inode, given the ceph ino number
+ */
+struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino)
+{
+	struct inode *inode;
+	ino_t t = ceph_vino_to_ino(vino);
+
+	inode = iget5_locked(sb, t, ceph_ino_compare, ceph_set_ino_cb, &vino);
+	if (inode == NULL)
+		return ERR_PTR(-ENOMEM);
+	if (inode->i_state & I_NEW) {
+		dout("get_inode created new inode %p %llx.%llx ino %llx\n",
+		     inode, ceph_vinop(inode), (u64)inode->i_ino);
+		unlock_new_inode(inode);
+	}
+
+	dout("get_inode on %lu=%llx.%llx got %p\n", inode->i_ino, vino.ino,
+	     vino.snap, inode);
+	return inode;
+}
+
+/*
+ * get/constuct snapdir inode for a given directory
+ */
+struct inode *ceph_get_snapdir(struct inode *parent)
+{
+	struct ceph_vino vino = {
+		.ino = ceph_ino(parent),
+		.snap = CEPH_SNAPDIR,
+	};
+	struct inode *inode = ceph_get_inode(parent->i_sb, vino);
+	struct ceph_inode_info *ci = ceph_inode(inode);
+
+	BUG_ON(!S_ISDIR(parent->i_mode));
+	if (IS_ERR(inode))
+		return ERR_PTR(PTR_ERR(inode));
+	inode->i_mode = parent->i_mode;
+	inode->i_uid = parent->i_uid;
+	inode->i_gid = parent->i_gid;
+	inode->i_op = &ceph_dir_iops;
+	inode->i_fop = &ceph_dir_fops;
+	ci->i_snap_caps = CEPH_CAP_PIN; /* so we can open */
+	ci->i_rbytes = 0;
+	return inode;
+}
+
+const struct inode_operations ceph_file_iops = {
+	.permission = ceph_permission,
+	.setattr = ceph_setattr,
+	.getattr = ceph_getattr,
+	.setxattr = ceph_setxattr,
+	.getxattr = ceph_getxattr,
+	.listxattr = ceph_listxattr,
+	.removexattr = ceph_removexattr,
+};
+
+
+/*
+ * We use a 'frag tree' to keep track of the MDS's directory fragments
+ * for a given inode (usually there is just a single fragment).  We
+ * need to know when a child frag is delegated to a new MDS, or when
+ * it is flagged as replicated, so we can direct our requests
+ * accordingly.
+ */
+
+/*
+ * find/create a frag in the tree
+ */
+static struct ceph_inode_frag *__get_or_create_frag(struct ceph_inode_info *ci,
+						    u32 f)
+{
+	struct rb_node **p;
+	struct rb_node *parent = NULL;
+	struct ceph_inode_frag *frag;
+	int c;
+
+	p = &ci->i_fragtree.rb_node;
+	while (*p) {
+		parent = *p;
+		frag = rb_entry(parent, struct ceph_inode_frag, node);
+		c = ceph_frag_compare(f, frag->frag);
+		if (c < 0)
+			p = &(*p)->rb_left;
+		else if (c > 0)
+			p = &(*p)->rb_right;
+		else
+			return frag;
+	}
+
+	frag = kmalloc(sizeof(*frag), GFP_NOFS);
+	if (!frag) {
+		pr_err("__get_or_create_frag ENOMEM on %p %llx.%llx "
+		       "frag %x\n", &ci->vfs_inode,
+		       ceph_vinop(&ci->vfs_inode), f);
+		return ERR_PTR(-ENOMEM);
+	}
+	frag->frag = f;
+	frag->split_by = 0;
+	frag->mds = -1;
+	frag->ndist = 0;
+
+	rb_link_node(&frag->node, parent, p);
+	rb_insert_color(&frag->node, &ci->i_fragtree);
+
+	dout("get_or_create_frag added %llx.%llx frag %x\n",
+	     ceph_vinop(&ci->vfs_inode), f);
+	return frag;
+}
+
+/*
+ * find a specific frag @f
+ */
+struct ceph_inode_frag *__ceph_find_frag(struct ceph_inode_info *ci, u32 f)
+{
+	struct rb_node *n = ci->i_fragtree.rb_node;
+
+	while (n) {
+		struct ceph_inode_frag *frag =
+			rb_entry(n, struct ceph_inode_frag, node);
+		int c = ceph_frag_compare(f, frag->frag);
+		if (c < 0)
+			n = n->rb_left;
+		else if (c > 0)
+			n = n->rb_right;
+		else
+			return frag;
+	}
+	return NULL;
+}
+
+/*
+ * Choose frag containing the given value @v.  If @pfrag is
+ * specified, copy the frag delegation info to the caller if
+ * it is present.
+ */
+u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
+		     struct ceph_inode_frag *pfrag,
+		     int *found)
+{
+	u32 t = ceph_frag_make(0, 0);
+	struct ceph_inode_frag *frag;
+	unsigned nway, i;
+	u32 n;
+
+	if (found)
+		*found = 0;
+
+	mutex_lock(&ci->i_fragtree_mutex);
+	while (1) {
+		WARN_ON(!ceph_frag_contains_value(t, v));
+		frag = __ceph_find_frag(ci, t);
+		if (!frag)
+			break; /* t is a leaf */
+		if (frag->split_by == 0) {
+			if (pfrag)
+				memcpy(pfrag, frag, sizeof(*pfrag));
+			if (found)
+				*found = 1;
+			break;
+		}
+
+		/* choose child */
+		nway = 1 << frag->split_by;
+		dout("choose_frag(%x) %x splits by %d (%d ways)\n", v, t,
+		     frag->split_by, nway);
+		for (i = 0; i < nway; i++) {
+			n = ceph_frag_make_child(t, frag->split_by, i);
+			if (ceph_frag_contains_value(n, v)) {
+				t = n;
+				break;
+			}
+		}
+		BUG_ON(i == nway);
+	}
+	dout("choose_frag(%x) = %x\n", v, t);
+
+	mutex_unlock(&ci->i_fragtree_mutex);
+	return t;
+}
+
+/*
+ * Process dirfrag (delegation) info from the mds.  Include leaf
+ * fragment in tree ONLY if ndist > 0.  Otherwise, only
+ * branches/splits are included in i_fragtree)
+ */
+static int ceph_fill_dirfrag(struct inode *inode,
+			     struct ceph_mds_reply_dirfrag *dirinfo)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_inode_frag *frag;
+	u32 id = le32_to_cpu(dirinfo->frag);
+	int mds = le32_to_cpu(dirinfo->auth);
+	int ndist = le32_to_cpu(dirinfo->ndist);
+	int i;
+	int err = 0;
+
+	mutex_lock(&ci->i_fragtree_mutex);
+	if (ndist == 0) {
+		/* no delegation info needed. */
+		frag = __ceph_find_frag(ci, id);
+		if (!frag)
+			goto out;
+		if (frag->split_by == 0) {
+			/* tree leaf, remove */
+			dout("fill_dirfrag removed %llx.%llx frag %x"
+			     " (no ref)\n", ceph_vinop(inode), id);
+			rb_erase(&frag->node, &ci->i_fragtree);
+			kfree(frag);
+		} else {
+			/* tree branch, keep and clear */
+			dout("fill_dirfrag cleared %llx.%llx frag %x"
+			     " referral\n", ceph_vinop(inode), id);
+			frag->mds = -1;
+			frag->ndist = 0;
+		}
+		goto out;
+	}
+
+
+	/* find/add this frag to store mds delegation info */
+	frag = __get_or_create_frag(ci, id);
+	if (IS_ERR(frag)) {
+		/* this is not the end of the world; we can continue
+		   with bad/inaccurate delegation info */
+		pr_err("fill_dirfrag ENOMEM on mds ref %llx.%llx fg %x\n",
+		       ceph_vinop(inode), le32_to_cpu(dirinfo->frag));
+		err = -ENOMEM;
+		goto out;
+	}
+
+	frag->mds = mds;
+	frag->ndist = min_t(u32, ndist, CEPH_MAX_DIRFRAG_REP);
+	for (i = 0; i < frag->ndist; i++)
+		frag->dist[i] = le32_to_cpu(dirinfo->dist[i]);
+	dout("fill_dirfrag %llx.%llx frag %x ndist=%d\n",
+	     ceph_vinop(inode), frag->frag, frag->ndist);
+
+out:
+	mutex_unlock(&ci->i_fragtree_mutex);
+	return err;
+}
+
+
+/*
+ * initialize a newly allocated inode.
+ */
+struct inode *ceph_alloc_inode(struct super_block *sb)
+{
+	struct ceph_inode_info *ci;
+	int i;
+
+	ci = kmem_cache_alloc(ceph_inode_cachep, GFP_NOFS);
+	if (!ci)
+		return NULL;
+
+	dout("alloc_inode %p\n", &ci->vfs_inode);
+
+	ci->i_version = 0;
+	ci->i_time_warp_seq = 0;
+	ci->i_ceph_flags = 0;
+	ci->i_release_count = 0;
+	ci->i_symlink = NULL;
+
+	ci->i_fragtree = RB_ROOT;
+	mutex_init(&ci->i_fragtree_mutex);
+
+	ci->i_xattrs.blob = NULL;
+	ci->i_xattrs.prealloc_blob = NULL;
+	ci->i_xattrs.dirty = false;
+	ci->i_xattrs.index = RB_ROOT;
+	ci->i_xattrs.count = 0;
+	ci->i_xattrs.names_size = 0;
+	ci->i_xattrs.vals_size = 0;
+	ci->i_xattrs.version = 0;
+	ci->i_xattrs.index_version = 0;
+
+	ci->i_caps = RB_ROOT;
+	ci->i_auth_cap = NULL;
+	ci->i_dirty_caps = 0;
+	ci->i_flushing_caps = 0;
+	INIT_LIST_HEAD(&ci->i_dirty_item);
+	INIT_LIST_HEAD(&ci->i_flushing_item);
+	ci->i_cap_flush_seq = 0;
+	ci->i_cap_flush_last_tid = 0;
+	memset(&ci->i_cap_flush_tid, 0, sizeof(ci->i_cap_flush_tid));
+	init_waitqueue_head(&ci->i_cap_wq);
+	ci->i_hold_caps_min = 0;
+	ci->i_hold_caps_max = 0;
+	INIT_LIST_HEAD(&ci->i_cap_delay_list);
+	ci->i_cap_exporting_mds = 0;
+	ci->i_cap_exporting_mseq = 0;
+	ci->i_cap_exporting_issued = 0;
+	INIT_LIST_HEAD(&ci->i_cap_snaps);
+	ci->i_head_snapc = NULL;
+	ci->i_snap_caps = 0;
+
+	for (i = 0; i < CEPH_FILE_MODE_NUM; i++)
+		ci->i_nr_by_mode[i] = 0;
+
+	ci->i_truncate_seq = 0;
+	ci->i_truncate_size = 0;
+	ci->i_truncate_pending = 0;
+
+	ci->i_max_size = 0;
+	ci->i_reported_size = 0;
+	ci->i_wanted_max_size = 0;
+	ci->i_requested_max_size = 0;
+
+	ci->i_pin_ref = 0;
+	ci->i_rd_ref = 0;
+	ci->i_rdcache_ref = 0;
+	ci->i_wr_ref = 0;
+	ci->i_wrbuffer_ref = 0;
+	ci->i_wrbuffer_ref_head = 0;
+	ci->i_shared_gen = 0;
+	ci->i_rdcache_gen = 0;
+	ci->i_rdcache_revoking = 0;
+
+	INIT_LIST_HEAD(&ci->i_unsafe_writes);
+	INIT_LIST_HEAD(&ci->i_unsafe_dirops);
+	spin_lock_init(&ci->i_unsafe_lock);
+
+	ci->i_snap_realm = NULL;
+	INIT_LIST_HEAD(&ci->i_snap_realm_item);
+	INIT_LIST_HEAD(&ci->i_snap_flush_item);
+
+	INIT_WORK(&ci->i_wb_work, ceph_writeback_work);
+	INIT_WORK(&ci->i_pg_inv_work, ceph_invalidate_work);
+
+	INIT_WORK(&ci->i_vmtruncate_work, ceph_vmtruncate_work);
+
+	return &ci->vfs_inode;
+}
+
+void ceph_destroy_inode(struct inode *inode)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_inode_frag *frag;
+	struct rb_node *n;
+
+	dout("destroy_inode %p ino %llx.%llx\n", inode, ceph_vinop(inode));
+
+	ceph_queue_caps_release(inode);
+
+	/*
+	 * we may still have a snap_realm reference if there are stray
+	 * caps in i_cap_exporting_issued or i_snap_caps.
+	 */
+	if (ci->i_snap_realm) {
+		struct ceph_mds_client *mdsc =
+			&ceph_client(ci->vfs_inode.i_sb)->mdsc;
+		struct ceph_snap_realm *realm = ci->i_snap_realm;
+
+		dout(" dropping residual ref to snap realm %p\n", realm);
+		spin_lock(&realm->inodes_with_caps_lock);
+		list_del_init(&ci->i_snap_realm_item);
+		spin_unlock(&realm->inodes_with_caps_lock);
+		ceph_put_snap_realm(mdsc, realm);
+	}
+
+	kfree(ci->i_symlink);
+	while ((n = rb_first(&ci->i_fragtree)) != NULL) {
+		frag = rb_entry(n, struct ceph_inode_frag, node);
+		rb_erase(n, &ci->i_fragtree);
+		kfree(frag);
+	}
+
+	__ceph_destroy_xattrs(ci);
+	if (ci->i_xattrs.blob)
+		ceph_buffer_put(ci->i_xattrs.blob);
+	if (ci->i_xattrs.prealloc_blob)
+		ceph_buffer_put(ci->i_xattrs.prealloc_blob);
+
+	kmem_cache_free(ceph_inode_cachep, ci);
+}
+
+
+/*
+ * Helpers to fill in size, ctime, mtime, and atime.  We have to be
+ * careful because either the client or MDS may have more up to date
+ * info, depending on which capabilities are held, and whether
+ * time_warp_seq or truncate_seq have increased.  (Ordinarily, mtime
+ * and size are monotonically increasing, except when utimes() or
+ * truncate() increments the corresponding _seq values.)
+ */
+int ceph_fill_file_size(struct inode *inode, int issued,
+			u32 truncate_seq, u64 truncate_size, u64 size)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int queue_trunc = 0;
+
+	if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) > 0 ||
+	    (truncate_seq == ci->i_truncate_seq && size > inode->i_size)) {
+		dout("size %lld -> %llu\n", inode->i_size, size);
+		inode->i_size = size;
+		inode->i_blocks = (size + (1<<9) - 1) >> 9;
+		ci->i_reported_size = size;
+		if (truncate_seq != ci->i_truncate_seq) {
+			dout("truncate_seq %u -> %u\n",
+			     ci->i_truncate_seq, truncate_seq);
+			ci->i_truncate_seq = truncate_seq;
+			/*
+			 * If we hold relevant caps, or in the case where we're
+			 * not the only client referencing this file and we
+			 * don't hold those caps, then we need to check whether
+			 * the file is either opened or mmaped
+			 */
+			if ((issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_RD|
+				      CEPH_CAP_FILE_WR|CEPH_CAP_FILE_BUFFER|
+				      CEPH_CAP_FILE_EXCL)) ||
+			    mapping_mapped(inode->i_mapping) ||
+			    __ceph_caps_file_wanted(ci)) {
+				ci->i_truncate_pending++;
+				queue_trunc = 1;
+			}
+		}
+	}
+	if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) >= 0 &&
+	    ci->i_truncate_size != truncate_size) {
+		dout("truncate_size %lld -> %llu\n", ci->i_truncate_size,
+		     truncate_size);
+		ci->i_truncate_size = truncate_size;
+	}
+	return queue_trunc;
+}
+
+void ceph_fill_file_time(struct inode *inode, int issued,
+			 u64 time_warp_seq, struct timespec *ctime,
+			 struct timespec *mtime, struct timespec *atime)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int warn = 0;
+
+	if (issued & (CEPH_CAP_FILE_EXCL|
+		      CEPH_CAP_FILE_WR|
+		      CEPH_CAP_FILE_BUFFER)) {
+		if (timespec_compare(ctime, &inode->i_ctime) > 0) {
+			dout("ctime %ld.%09ld -> %ld.%09ld inc w/ cap\n",
+			     inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
+			     ctime->tv_sec, ctime->tv_nsec);
+			inode->i_ctime = *ctime;
+		}
+		if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) {
+			/* the MDS did a utimes() */
+			dout("mtime %ld.%09ld -> %ld.%09ld "
+			     "tw %d -> %d\n",
+			     inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
+			     mtime->tv_sec, mtime->tv_nsec,
+			     ci->i_time_warp_seq, (int)time_warp_seq);
+
+			inode->i_mtime = *mtime;
+			inode->i_atime = *atime;
+			ci->i_time_warp_seq = time_warp_seq;
+		} else if (time_warp_seq == ci->i_time_warp_seq) {
+			/* nobody did utimes(); take the max */
+			if (timespec_compare(mtime, &inode->i_mtime) > 0) {
+				dout("mtime %ld.%09ld -> %ld.%09ld inc\n",
+				     inode->i_mtime.tv_sec,
+				     inode->i_mtime.tv_nsec,
+				     mtime->tv_sec, mtime->tv_nsec);
+				inode->i_mtime = *mtime;
+			}
+			if (timespec_compare(atime, &inode->i_atime) > 0) {
+				dout("atime %ld.%09ld -> %ld.%09ld inc\n",
+				     inode->i_atime.tv_sec,
+				     inode->i_atime.tv_nsec,
+				     atime->tv_sec, atime->tv_nsec);
+				inode->i_atime = *atime;
+			}
+		} else if (issued & CEPH_CAP_FILE_EXCL) {
+			/* we did a utimes(); ignore mds values */
+		} else {
+			warn = 1;
+		}
+	} else {
+		/* we have no write caps; whatever the MDS says is true */
+		if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) >= 0) {
+			inode->i_ctime = *ctime;
+			inode->i_mtime = *mtime;
+			inode->i_atime = *atime;
+			ci->i_time_warp_seq = time_warp_seq;
+		} else {
+			warn = 1;
+		}
+	}
+	if (warn) /* time_warp_seq shouldn't go backwards */
+		dout("%p mds time_warp_seq %llu < %u\n",
+		     inode, time_warp_seq, ci->i_time_warp_seq);
+}
+
+/*
+ * Populate an inode based on info from mds.  May be called on new or
+ * existing inodes.
+ */
+static int fill_inode(struct inode *inode,
+		      struct ceph_mds_reply_info_in *iinfo,
+		      struct ceph_mds_reply_dirfrag *dirinfo,
+		      struct ceph_mds_session *session,
+		      unsigned long ttl_from, int cap_fmode,
+		      struct ceph_cap_reservation *caps_reservation)
+{
+	struct ceph_mds_reply_inode *info = iinfo->in;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int i;
+	int issued, implemented;
+	struct timespec mtime, atime, ctime;
+	u32 nsplits;
+	struct ceph_buffer *xattr_blob = NULL;
+	int err = 0;
+	int queue_trunc = 0;
+
+	dout("fill_inode %p ino %llx.%llx v %llu had %llu\n",
+	     inode, ceph_vinop(inode), le64_to_cpu(info->version),
+	     ci->i_version);
+
+	/*
+	 * prealloc xattr data, if it looks like we'll need it.  only
+	 * if len > 4 (meaning there are actually xattrs; the first 4
+	 * bytes are the xattr count).
+	 */
+	if (iinfo->xattr_len > 4) {
+		xattr_blob = ceph_buffer_new(iinfo->xattr_len, GFP_NOFS);
+		if (!xattr_blob)
+			pr_err("fill_inode ENOMEM xattr blob %d bytes\n",
+			       iinfo->xattr_len);
+	}
+
+	spin_lock(&inode->i_lock);
+
+	/*
+	 * provided version will be odd if inode value is projected,
+	 * even if stable.  skip the update if we have a newer info
+	 * (e.g., due to inode info racing form multiple MDSs), or if
+	 * we are getting projected (unstable) inode info.
+	 */
+	if (le64_to_cpu(info->version) > 0 &&
+	    (ci->i_version & ~1) > le64_to_cpu(info->version))
+		goto no_change;
+
+	issued = __ceph_caps_issued(ci, &implemented);
+	issued |= implemented | __ceph_caps_dirty(ci);
+
+	/* update inode */
+	ci->i_version = le64_to_cpu(info->version);
+	inode->i_version++;
+	inode->i_rdev = le32_to_cpu(info->rdev);
+
+	if ((issued & CEPH_CAP_AUTH_EXCL) == 0) {
+		inode->i_mode = le32_to_cpu(info->mode);
+		inode->i_uid = le32_to_cpu(info->uid);
+		inode->i_gid = le32_to_cpu(info->gid);
+		dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode,
+		     inode->i_uid, inode->i_gid);
+	}
+
+	if ((issued & CEPH_CAP_LINK_EXCL) == 0)
+		inode->i_nlink = le32_to_cpu(info->nlink);
+
+	/* be careful with mtime, atime, size */
+	ceph_decode_timespec(&atime, &info->atime);
+	ceph_decode_timespec(&mtime, &info->mtime);
+	ceph_decode_timespec(&ctime, &info->ctime);
+	queue_trunc = ceph_fill_file_size(inode, issued,
+					  le32_to_cpu(info->truncate_seq),
+					  le64_to_cpu(info->truncate_size),
+					  le64_to_cpu(info->size));
+	ceph_fill_file_time(inode, issued,
+			    le32_to_cpu(info->time_warp_seq),
+			    &ctime, &mtime, &atime);
+
+	ci->i_max_size = le64_to_cpu(info->max_size);
+	ci->i_layout = info->layout;
+	inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
+
+	/* xattrs */
+	/* note that if i_xattrs.len <= 4, i_xattrs.data will still be NULL. */
+	if ((issued & CEPH_CAP_XATTR_EXCL) == 0 &&
+	    le64_to_cpu(info->xattr_version) > ci->i_xattrs.version) {
+		if (ci->i_xattrs.blob)
+			ceph_buffer_put(ci->i_xattrs.blob);
+		ci->i_xattrs.blob = xattr_blob;
+		if (xattr_blob)
+			memcpy(ci->i_xattrs.blob->vec.iov_base,
+			       iinfo->xattr_data, iinfo->xattr_len);
+		ci->i_xattrs.version = le64_to_cpu(info->xattr_version);
+	}
+
+	inode->i_mapping->a_ops = &ceph_aops;
+	inode->i_mapping->backing_dev_info =
+		&ceph_client(inode->i_sb)->backing_dev_info;
+
+	switch (inode->i_mode & S_IFMT) {
+	case S_IFIFO:
+	case S_IFBLK:
+	case S_IFCHR:
+	case S_IFSOCK:
+		init_special_inode(inode, inode->i_mode, inode->i_rdev);
+		inode->i_op = &ceph_file_iops;
+		break;
+	case S_IFREG:
+		inode->i_op = &ceph_file_iops;
+		inode->i_fop = &ceph_file_fops;
+		break;
+	case S_IFLNK:
+		inode->i_op = &ceph_symlink_iops;
+		if (!ci->i_symlink) {
+			int symlen = iinfo->symlink_len;
+			char *sym;
+
+			BUG_ON(symlen != inode->i_size);
+			spin_unlock(&inode->i_lock);
+
+			err = -ENOMEM;
+			sym = kmalloc(symlen+1, GFP_NOFS);
+			if (!sym)
+				goto out;
+			memcpy(sym, iinfo->symlink, symlen);
+			sym[symlen] = 0;
+
+			spin_lock(&inode->i_lock);
+			if (!ci->i_symlink)
+				ci->i_symlink = sym;
+			else
+				kfree(sym); /* lost a race */
+		}
+		break;
+	case S_IFDIR:
+		inode->i_op = &ceph_dir_iops;
+		inode->i_fop = &ceph_dir_fops;
+
+		ci->i_files = le64_to_cpu(info->files);
+		ci->i_subdirs = le64_to_cpu(info->subdirs);
+		ci->i_rbytes = le64_to_cpu(info->rbytes);
+		ci->i_rfiles = le64_to_cpu(info->rfiles);
+		ci->i_rsubdirs = le64_to_cpu(info->rsubdirs);
+		ceph_decode_timespec(&ci->i_rctime, &info->rctime);
+
+		/* set dir completion flag? */
+		if (ci->i_files == 0 && ci->i_subdirs == 0 &&
+		    ceph_snap(inode) == CEPH_NOSNAP &&
+		    (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED)) {
+			dout(" marking %p complete (empty)\n", inode);
+			ci->i_ceph_flags |= CEPH_I_COMPLETE;
+			ci->i_max_offset = 2;
+		}
+
+		/* it may be better to set st_size in getattr instead? */
+		if (ceph_test_opt(ceph_client(inode->i_sb), RBYTES))
+			inode->i_size = ci->i_rbytes;
+		break;
+	default:
+		pr_err("fill_inode %llx.%llx BAD mode 0%o\n",
+		       ceph_vinop(inode), inode->i_mode);
+	}
+
+no_change:
+	spin_unlock(&inode->i_lock);
+
+	/* queue truncate if we saw i_size decrease */
+	if (queue_trunc)
+		ceph_queue_vmtruncate(inode);
+
+	/* populate frag tree */
+	/* FIXME: move me up, if/when version reflects fragtree changes */
+	nsplits = le32_to_cpu(info->fragtree.nsplits);
+	mutex_lock(&ci->i_fragtree_mutex);
+	for (i = 0; i < nsplits; i++) {
+		u32 id = le32_to_cpu(info->fragtree.splits[i].frag);
+		struct ceph_inode_frag *frag = __get_or_create_frag(ci, id);
+
+		if (IS_ERR(frag))
+			continue;
+		frag->split_by = le32_to_cpu(info->fragtree.splits[i].by);
+		dout(" frag %x split by %d\n", frag->frag, frag->split_by);
+	}
+	mutex_unlock(&ci->i_fragtree_mutex);
+
+	/* were we issued a capability? */
+	if (info->cap.caps) {
+		if (ceph_snap(inode) == CEPH_NOSNAP) {
+			ceph_add_cap(inode, session,
+				     le64_to_cpu(info->cap.cap_id),
+				     cap_fmode,
+				     le32_to_cpu(info->cap.caps),
+				     le32_to_cpu(info->cap.wanted),
+				     le32_to_cpu(info->cap.seq),
+				     le32_to_cpu(info->cap.mseq),
+				     le64_to_cpu(info->cap.realm),
+				     info->cap.flags,
+				     caps_reservation);
+		} else {
+			spin_lock(&inode->i_lock);
+			dout(" %p got snap_caps %s\n", inode,
+			     ceph_cap_string(le32_to_cpu(info->cap.caps)));
+			ci->i_snap_caps |= le32_to_cpu(info->cap.caps);
+			if (cap_fmode >= 0)
+				__ceph_get_fmode(ci, cap_fmode);
+			spin_unlock(&inode->i_lock);
+		}
+	} else if (cap_fmode >= 0) {
+		pr_warning("mds issued no caps on %llx.%llx\n",
+			   ceph_vinop(inode));
+		__ceph_get_fmode(ci, cap_fmode);
+	}
+
+	/* update delegation info? */
+	if (dirinfo)
+		ceph_fill_dirfrag(inode, dirinfo);
+
+	err = 0;
+
+out:
+	if (xattr_blob)
+		ceph_buffer_put(xattr_blob);
+	return err;
+}
+
+/*
+ * caller should hold session s_mutex.
+ */
+static void update_dentry_lease(struct dentry *dentry,
+				struct ceph_mds_reply_lease *lease,
+				struct ceph_mds_session *session,
+				unsigned long from_time)
+{
+	struct ceph_dentry_info *di = ceph_dentry(dentry);
+	long unsigned duration = le32_to_cpu(lease->duration_ms);
+	long unsigned ttl = from_time + (duration * HZ) / 1000;
+	long unsigned half_ttl = from_time + (duration * HZ / 2) / 1000;
+	struct inode *dir;
+
+	/* only track leases on regular dentries */
+	if (dentry->d_op != &ceph_dentry_ops)
+		return;
+
+	spin_lock(&dentry->d_lock);
+	dout("update_dentry_lease %p mask %d duration %lu ms ttl %lu\n",
+	     dentry, le16_to_cpu(lease->mask), duration, ttl);
+
+	/* make lease_rdcache_gen match directory */
+	dir = dentry->d_parent->d_inode;
+	di->lease_shared_gen = ceph_inode(dir)->i_shared_gen;
+
+	if (lease->mask == 0)
+		goto out_unlock;
+
+	if (di->lease_gen == session->s_cap_gen &&
+	    time_before(ttl, dentry->d_time))
+		goto out_unlock;  /* we already have a newer lease. */
+
+	if (di->lease_session && di->lease_session != session)
+		goto out_unlock;
+
+	ceph_dentry_lru_touch(dentry);
+
+	if (!di->lease_session)
+		di->lease_session = ceph_get_mds_session(session);
+	di->lease_gen = session->s_cap_gen;
+	di->lease_seq = le32_to_cpu(lease->seq);
+	di->lease_renew_after = half_ttl;
+	di->lease_renew_from = 0;
+	dentry->d_time = ttl;
+out_unlock:
+	spin_unlock(&dentry->d_lock);
+	return;
+}
+
+/*
+ * splice a dentry to an inode.
+ * caller must hold directory i_mutex for this to be safe.
+ *
+ * we will only rehash the resulting dentry if @prehash is
+ * true; @prehash will be set to false (for the benefit of
+ * the caller) if we fail.
+ */
+static struct dentry *splice_dentry(struct dentry *dn, struct inode *in,
+				    bool *prehash)
+{
+	struct dentry *realdn;
+
+	/* dn must be unhashed */
+	if (!d_unhashed(dn))
+		d_drop(dn);
+	realdn = d_materialise_unique(dn, in);
+	if (IS_ERR(realdn)) {
+		pr_err("splice_dentry error %p inode %p ino %llx.%llx\n",
+		       dn, in, ceph_vinop(in));
+		if (prehash)
+			*prehash = false; /* don't rehash on error */
+		dn = realdn; /* note realdn contains the error */
+		goto out;
+	} else if (realdn) {
+		dout("dn %p (%d) spliced with %p (%d) "
+		     "inode %p ino %llx.%llx\n",
+		     dn, atomic_read(&dn->d_count),
+		     realdn, atomic_read(&realdn->d_count),
+		     realdn->d_inode, ceph_vinop(realdn->d_inode));
+		dput(dn);
+		dn = realdn;
+	} else {
+		BUG_ON(!ceph_dentry(dn));
+
+		dout("dn %p attached to %p ino %llx.%llx\n",
+		     dn, dn->d_inode, ceph_vinop(dn->d_inode));
+	}
+	if ((!prehash || *prehash) && d_unhashed(dn))
+		d_rehash(dn);
+out:
+	return dn;
+}
+
+/*
+ * Set dentry's directory position based on the current dir's max, and
+ * order it in d_subdirs, so that dcache_readdir behaves.
+ */
+static void ceph_set_dentry_offset(struct dentry *dn)
+{
+	struct dentry *dir = dn->d_parent;
+	struct inode *inode = dn->d_parent->d_inode;
+	struct ceph_dentry_info *di;
+
+	BUG_ON(!inode);
+
+	di = ceph_dentry(dn);
+
+	spin_lock(&inode->i_lock);
+	di->offset = ceph_inode(inode)->i_max_offset++;
+	spin_unlock(&inode->i_lock);
+
+	spin_lock(&dcache_lock);
+	spin_lock(&dn->d_lock);
+	list_move_tail(&dir->d_subdirs, &dn->d_u.d_child);
+	dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset,
+	     dn->d_u.d_child.prev, dn->d_u.d_child.next);
+	spin_unlock(&dn->d_lock);
+	spin_unlock(&dcache_lock);
+}
+
+/*
+ * Incorporate results into the local cache.  This is either just
+ * one inode, or a directory, dentry, and possibly linked-to inode (e.g.,
+ * after a lookup).
+ *
+ * A reply may contain
+ *         a directory inode along with a dentry.
+ *  and/or a target inode
+ *
+ * Called with snap_rwsem (read).
+ */
+int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
+		    struct ceph_mds_session *session)
+{
+	struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
+	struct inode *in = NULL;
+	struct ceph_mds_reply_inode *ininfo;
+	struct ceph_vino vino;
+	struct ceph_client *client = ceph_sb_to_client(sb);
+	int i = 0;
+	int err = 0;
+
+	dout("fill_trace %p is_dentry %d is_target %d\n", req,
+	     rinfo->head->is_dentry, rinfo->head->is_target);
+
+#if 0
+	/*
+	 * Debugging hook:
+	 *
+	 * If we resend completed ops to a recovering mds, we get no
+	 * trace.  Since that is very rare, pretend this is the case
+	 * to ensure the 'no trace' handlers in the callers behave.
+	 *
+	 * Fill in inodes unconditionally to avoid breaking cap
+	 * invariants.
+	 */
+	if (rinfo->head->op & CEPH_MDS_OP_WRITE) {
+		pr_info("fill_trace faking empty trace on %lld %s\n",
+			req->r_tid, ceph_mds_op_name(rinfo->head->op));
+		if (rinfo->head->is_dentry) {
+			rinfo->head->is_dentry = 0;
+			err = fill_inode(req->r_locked_dir,
+					 &rinfo->diri, rinfo->dirfrag,
+					 session, req->r_request_started, -1);
+		}
+		if (rinfo->head->is_target) {
+			rinfo->head->is_target = 0;
+			ininfo = rinfo->targeti.in;
+			vino.ino = le64_to_cpu(ininfo->ino);
+			vino.snap = le64_to_cpu(ininfo->snapid);
+			in = ceph_get_inode(sb, vino);
+			err = fill_inode(in, &rinfo->targeti, NULL,
+					 session, req->r_request_started,
+					 req->r_fmode);
+			iput(in);
+		}
+	}
+#endif
+
+	if (!rinfo->head->is_target && !rinfo->head->is_dentry) {
+		dout("fill_trace reply is empty!\n");
+		if (rinfo->head->result == 0 && req->r_locked_dir) {
+			struct ceph_inode_info *ci =
+				ceph_inode(req->r_locked_dir);
+			dout(" clearing %p complete (empty trace)\n",
+			     req->r_locked_dir);
+			ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
+			ci->i_release_count++;
+		}
+		return 0;
+	}
+
+	if (rinfo->head->is_dentry) {
+		struct inode *dir = req->r_locked_dir;
+
+		err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag,
+				 session, req->r_request_started, -1,
+				 &req->r_caps_reservation);
+		if (err < 0)
+			return err;
+	}
+
+	/*
+	 * ignore null lease/binding on snapdir ENOENT, or else we
+	 * will have trouble splicing in the virtual snapdir later
+	 */
+	if (rinfo->head->is_dentry && !req->r_aborted &&
+	    (rinfo->head->is_target || strncmp(req->r_dentry->d_name.name,
+					       client->mount_args->snapdir_name,
+					       req->r_dentry->d_name.len))) {
+		/*
+		 * lookup link rename   : null -> possibly existing inode
+		 * mknod symlink mkdir  : null -> new inode
+		 * unlink               : linked -> null
+		 */
+		struct inode *dir = req->r_locked_dir;
+		struct dentry *dn = req->r_dentry;
+		bool have_dir_cap, have_lease;
+
+		BUG_ON(!dn);
+		BUG_ON(!dir);
+		BUG_ON(dn->d_parent->d_inode != dir);
+		BUG_ON(ceph_ino(dir) !=
+		       le64_to_cpu(rinfo->diri.in->ino));
+		BUG_ON(ceph_snap(dir) !=
+		       le64_to_cpu(rinfo->diri.in->snapid));
+
+		/* do we have a lease on the whole dir? */
+		have_dir_cap =
+			(le32_to_cpu(rinfo->diri.in->cap.caps) &
+			 CEPH_CAP_FILE_SHARED);
+
+		/* do we have a dn lease? */
+		have_lease = have_dir_cap ||
+			(le16_to_cpu(rinfo->dlease->mask) &
+			 CEPH_LOCK_DN);
+
+		if (!have_lease)
+			dout("fill_trace  no dentry lease or dir cap\n");
+
+		/* rename? */
+		if (req->r_old_dentry && req->r_op == CEPH_MDS_OP_RENAME) {
+			dout(" src %p '%.*s' dst %p '%.*s'\n",
+			     req->r_old_dentry,
+			     req->r_old_dentry->d_name.len,
+			     req->r_old_dentry->d_name.name,
+			     dn, dn->d_name.len, dn->d_name.name);
+			dout("fill_trace doing d_move %p -> %p\n",
+			     req->r_old_dentry, dn);
+
+			/* d_move screws up d_subdirs order */
+			ceph_i_clear(dir, CEPH_I_COMPLETE);
+
+			d_move(req->r_old_dentry, dn);
+			dout(" src %p '%.*s' dst %p '%.*s'\n",
+			     req->r_old_dentry,
+			     req->r_old_dentry->d_name.len,
+			     req->r_old_dentry->d_name.name,
+			     dn, dn->d_name.len, dn->d_name.name);
+			/* ensure target dentry is invalidated, despite
+			   rehashing bug in vfs_rename_dir */
+			dn->d_time = jiffies;
+			ceph_dentry(dn)->lease_shared_gen = 0;
+			/* take overwritten dentry's readdir offset */
+			ceph_dentry(req->r_old_dentry)->offset =
+				ceph_dentry(dn)->offset;
+			dn = req->r_old_dentry;  /* use old_dentry */
+			in = dn->d_inode;
+		}
+
+		/* null dentry? */
+		if (!rinfo->head->is_target) {
+			dout("fill_trace null dentry\n");
+			if (dn->d_inode) {
+				dout("d_delete %p\n", dn);
+				d_delete(dn);
+			} else {
+				dout("d_instantiate %p NULL\n", dn);
+				d_instantiate(dn, NULL);
+				if (have_lease && d_unhashed(dn))
+					d_rehash(dn);
+				update_dentry_lease(dn, rinfo->dlease,
+						    session,
+						    req->r_request_started);
+			}
+			goto done;
+		}
+
+		/* attach proper inode */
+		ininfo = rinfo->targeti.in;
+		vino.ino = le64_to_cpu(ininfo->ino);
+		vino.snap = le64_to_cpu(ininfo->snapid);
+		if (!dn->d_inode) {
+			in = ceph_get_inode(sb, vino);
+			if (IS_ERR(in)) {
+				pr_err("fill_trace bad get_inode "
+				       "%llx.%llx\n", vino.ino, vino.snap);
+				err = PTR_ERR(in);
+				d_delete(dn);
+				goto done;
+			}
+			dn = splice_dentry(dn, in, &have_lease);
+			if (IS_ERR(dn)) {
+				err = PTR_ERR(dn);
+				goto done;
+			}
+			req->r_dentry = dn;  /* may have spliced */
+			ceph_set_dentry_offset(dn);
+			igrab(in);
+		} else if (ceph_ino(in) == vino.ino &&
+			   ceph_snap(in) == vino.snap) {
+			igrab(in);
+		} else {
+			dout(" %p links to %p %llx.%llx, not %llx.%llx\n",
+			     dn, in, ceph_ino(in), ceph_snap(in),
+			     vino.ino, vino.snap);
+			have_lease = false;
+			in = NULL;
+		}
+
+		if (have_lease)
+			update_dentry_lease(dn, rinfo->dlease, session,
+					    req->r_request_started);
+		dout(" final dn %p\n", dn);
+		i++;
+	} else if (req->r_op == CEPH_MDS_OP_LOOKUPSNAP ||
+		   req->r_op == CEPH_MDS_OP_MKSNAP) {
+		struct dentry *dn = req->r_dentry;
+
+		/* fill out a snapdir LOOKUPSNAP dentry */
+		BUG_ON(!dn);
+		BUG_ON(!req->r_locked_dir);
+		BUG_ON(ceph_snap(req->r_locked_dir) != CEPH_SNAPDIR);
+		ininfo = rinfo->targeti.in;
+		vino.ino = le64_to_cpu(ininfo->ino);
+		vino.snap = le64_to_cpu(ininfo->snapid);
+		in = ceph_get_inode(sb, vino);
+		if (IS_ERR(in)) {
+			pr_err("fill_inode get_inode badness %llx.%llx\n",
+			       vino.ino, vino.snap);
+			err = PTR_ERR(in);
+			d_delete(dn);
+			goto done;
+		}
+		dout(" linking snapped dir %p to dn %p\n", in, dn);
+		dn = splice_dentry(dn, in, NULL);
+		if (IS_ERR(dn)) {
+			err = PTR_ERR(dn);
+			goto done;
+		}
+		ceph_set_dentry_offset(dn);
+		req->r_dentry = dn;  /* may have spliced */
+		igrab(in);
+		rinfo->head->is_dentry = 1;  /* fool notrace handlers */
+	}
+
+	if (rinfo->head->is_target) {
+		vino.ino = le64_to_cpu(rinfo->targeti.in->ino);
+		vino.snap = le64_to_cpu(rinfo->targeti.in->snapid);
+
+		if (in == NULL || ceph_ino(in) != vino.ino ||
+		    ceph_snap(in) != vino.snap) {
+			in = ceph_get_inode(sb, vino);
+			if (IS_ERR(in)) {
+				err = PTR_ERR(in);
+				goto done;
+			}
+		}
+		req->r_target_inode = in;
+
+		err = fill_inode(in,
+				 &rinfo->targeti, NULL,
+				 session, req->r_request_started,
+				 (le32_to_cpu(rinfo->head->result) == 0) ?
+				 req->r_fmode : -1,
+				 &req->r_caps_reservation);
+		if (err < 0) {
+			pr_err("fill_inode badness %p %llx.%llx\n",
+			       in, ceph_vinop(in));
+			goto done;
+		}
+	}
+
+done:
+	dout("fill_trace done err=%d\n", err);
+	return err;
+}
+
+/*
+ * Prepopulate our cache with readdir results, leases, etc.
+ */
+int ceph_readdir_prepopulate(struct ceph_mds_request *req,
+			     struct ceph_mds_session *session)
+{
+	struct dentry *parent = req->r_dentry;
+	struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
+	struct qstr dname;
+	struct dentry *dn;
+	struct inode *in;
+	int err = 0, i;
+	struct inode *snapdir = NULL;
+	struct ceph_mds_request_head *rhead = req->r_request->front.iov_base;
+	u64 frag = le32_to_cpu(rhead->args.readdir.frag);
+	struct ceph_dentry_info *di;
+
+	if (le32_to_cpu(rinfo->head->op) == CEPH_MDS_OP_LSSNAP) {
+		snapdir = ceph_get_snapdir(parent->d_inode);
+		parent = d_find_alias(snapdir);
+		dout("readdir_prepopulate %d items under SNAPDIR dn %p\n",
+		     rinfo->dir_nr, parent);
+	} else {
+		dout("readdir_prepopulate %d items under dn %p\n",
+		     rinfo->dir_nr, parent);
+		if (rinfo->dir_dir)
+			ceph_fill_dirfrag(parent->d_inode, rinfo->dir_dir);
+	}
+
+	for (i = 0; i < rinfo->dir_nr; i++) {
+		struct ceph_vino vino;
+
+		dname.name = rinfo->dir_dname[i];
+		dname.len = rinfo->dir_dname_len[i];
+		dname.hash = full_name_hash(dname.name, dname.len);
+
+		vino.ino = le64_to_cpu(rinfo->dir_in[i].in->ino);
+		vino.snap = le64_to_cpu(rinfo->dir_in[i].in->snapid);
+
+retry_lookup:
+		dn = d_lookup(parent, &dname);
+		dout("d_lookup on parent=%p name=%.*s got %p\n",
+		     parent, dname.len, dname.name, dn);
+
+		if (!dn) {
+			dn = d_alloc(parent, &dname);
+			dout("d_alloc %p '%.*s' = %p\n", parent,
+			     dname.len, dname.name, dn);
+			if (dn == NULL) {
+				dout("d_alloc badness\n");
+				err = -ENOMEM;
+				goto out;
+			}
+			err = ceph_init_dentry(dn);
+			if (err < 0)
+				goto out;
+		} else if (dn->d_inode &&
+			   (ceph_ino(dn->d_inode) != vino.ino ||
+			    ceph_snap(dn->d_inode) != vino.snap)) {
+			dout(" dn %p points to wrong inode %p\n",
+			     dn, dn->d_inode);
+			d_delete(dn);
+			dput(dn);
+			goto retry_lookup;
+		} else {
+			/* reorder parent's d_subdirs */
+			spin_lock(&dcache_lock);
+			spin_lock(&dn->d_lock);
+			list_move(&dn->d_u.d_child, &parent->d_subdirs);
+			spin_unlock(&dn->d_lock);
+			spin_unlock(&dcache_lock);
+		}
+
+		di = dn->d_fsdata;
+		di->offset = ceph_make_fpos(frag, i + req->r_readdir_offset);
+
+		/* inode */
+		if (dn->d_inode) {
+			in = dn->d_inode;
+		} else {
+			in = ceph_get_inode(parent->d_sb, vino);
+			if (in == NULL) {
+				dout("new_inode badness\n");
+				d_delete(dn);
+				dput(dn);
+				err = -ENOMEM;
+				goto out;
+			}
+			dn = splice_dentry(dn, in, NULL);
+		}
+
+		if (fill_inode(in, &rinfo->dir_in[i], NULL, session,
+			       req->r_request_started, -1,
+			       &req->r_caps_reservation) < 0) {
+			pr_err("fill_inode badness on %p\n", in);
+			dput(dn);
+			continue;
+		}
+		update_dentry_lease(dn, rinfo->dir_dlease[i],
+				    req->r_session, req->r_request_started);
+		dput(dn);
+	}
+	req->r_did_prepopulate = true;
+
+out:
+	if (snapdir) {
+		iput(snapdir);
+		dput(parent);
+	}
+	dout("readdir_prepopulate done\n");
+	return err;
+}
+
+int ceph_inode_set_size(struct inode *inode, loff_t size)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int ret = 0;
+
+	spin_lock(&inode->i_lock);
+	dout("set_size %p %llu -> %llu\n", inode, inode->i_size, size);
+	inode->i_size = size;
+	inode->i_blocks = (size + (1 << 9) - 1) >> 9;
+
+	/* tell the MDS if we are approaching max_size */
+	if ((size << 1) >= ci->i_max_size &&
+	    (ci->i_reported_size << 1) < ci->i_max_size)
+		ret = 1;
+
+	spin_unlock(&inode->i_lock);
+	return ret;
+}
+
+/*
+ * Write back inode data in a worker thread.  (This can't be done
+ * in the message handler context.)
+ */
+void ceph_queue_writeback(struct inode *inode)
+{
+	if (queue_work(ceph_inode_to_client(inode)->wb_wq,
+		       &ceph_inode(inode)->i_wb_work)) {
+		dout("ceph_queue_writeback %p\n", inode);
+		igrab(inode);
+	} else {
+		dout("ceph_queue_writeback %p failed\n", inode);
+	}
+}
+
+static void ceph_writeback_work(struct work_struct *work)
+{
+	struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
+						  i_wb_work);
+	struct inode *inode = &ci->vfs_inode;
+
+	dout("writeback %p\n", inode);
+	filemap_fdatawrite(&inode->i_data);
+	iput(inode);
+}
+
+/*
+ * queue an async invalidation
+ */
+void ceph_queue_invalidate(struct inode *inode)
+{
+	if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq,
+		       &ceph_inode(inode)->i_pg_inv_work)) {
+		dout("ceph_queue_invalidate %p\n", inode);
+		igrab(inode);
+	} else {
+		dout("ceph_queue_invalidate %p failed\n", inode);
+	}
+}
+
+/*
+ * invalidate any pages that are not dirty or under writeback.  this
+ * includes pages that are clean and mapped.
+ */
+static void ceph_invalidate_nondirty_pages(struct address_space *mapping)
+{
+	struct pagevec pvec;
+	pgoff_t next = 0;
+	int i;
+
+	pagevec_init(&pvec, 0);
+	while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
+		for (i = 0; i < pagevec_count(&pvec); i++) {
+			struct page *page = pvec.pages[i];
+			pgoff_t index;
+			int skip_page =
+				(PageDirty(page) || PageWriteback(page));
+
+			if (!skip_page)
+				skip_page = !trylock_page(page);
+
+			/*
+			 * We really shouldn't be looking at the ->index of an
+			 * unlocked page.  But we're not allowed to lock these
+			 * pages.  So we rely upon nobody altering the ->index
+			 * of this (pinned-by-us) page.
+			 */
+			index = page->index;
+			if (index > next)
+				next = index;
+			next++;
+
+			if (skip_page)
+				continue;
+
+			generic_error_remove_page(mapping, page);
+			unlock_page(page);
+		}
+		pagevec_release(&pvec);
+		cond_resched();
+	}
+}
+
+/*
+ * Invalidate inode pages in a worker thread.  (This can't be done
+ * in the message handler context.)
+ */
+static void ceph_invalidate_work(struct work_struct *work)
+{
+	struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
+						  i_pg_inv_work);
+	struct inode *inode = &ci->vfs_inode;
+	u32 orig_gen;
+	int check = 0;
+
+	spin_lock(&inode->i_lock);
+	dout("invalidate_pages %p gen %d revoking %d\n", inode,
+	     ci->i_rdcache_gen, ci->i_rdcache_revoking);
+	if (ci->i_rdcache_gen == 0 ||
+	    ci->i_rdcache_revoking != ci->i_rdcache_gen) {
+		BUG_ON(ci->i_rdcache_revoking > ci->i_rdcache_gen);
+		/* nevermind! */
+		ci->i_rdcache_revoking = 0;
+		spin_unlock(&inode->i_lock);
+		goto out;
+	}
+	orig_gen = ci->i_rdcache_gen;
+	spin_unlock(&inode->i_lock);
+
+	ceph_invalidate_nondirty_pages(inode->i_mapping);
+
+	spin_lock(&inode->i_lock);
+	if (orig_gen == ci->i_rdcache_gen) {
+		dout("invalidate_pages %p gen %d successful\n", inode,
+		     ci->i_rdcache_gen);
+		ci->i_rdcache_gen = 0;
+		ci->i_rdcache_revoking = 0;
+		check = 1;
+	} else {
+		dout("invalidate_pages %p gen %d raced, gen now %d\n",
+		     inode, orig_gen, ci->i_rdcache_gen);
+	}
+	spin_unlock(&inode->i_lock);
+
+	if (check)
+		ceph_check_caps(ci, 0, NULL);
+out:
+	iput(inode);
+}
+
+
+/*
+ * called by trunc_wq; take i_mutex ourselves
+ *
+ * We also truncate in a separate thread as well.
+ */
+static void ceph_vmtruncate_work(struct work_struct *work)
+{
+	struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
+						  i_vmtruncate_work);
+	struct inode *inode = &ci->vfs_inode;
+
+	dout("vmtruncate_work %p\n", inode);
+	mutex_lock(&inode->i_mutex);
+	__ceph_do_pending_vmtruncate(inode);
+	mutex_unlock(&inode->i_mutex);
+	iput(inode);
+}
+
+/*
+ * Queue an async vmtruncate.  If we fail to queue work, we will handle
+ * the truncation the next time we call __ceph_do_pending_vmtruncate.
+ */
+void ceph_queue_vmtruncate(struct inode *inode)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+
+	if (queue_work(ceph_client(inode->i_sb)->trunc_wq,
+		       &ci->i_vmtruncate_work)) {
+		dout("ceph_queue_vmtruncate %p\n", inode);
+		igrab(inode);
+	} else {
+		dout("ceph_queue_vmtruncate %p failed, pending=%d\n",
+		     inode, ci->i_truncate_pending);
+	}
+}
+
+/*
+ * called with i_mutex held.
+ *
+ * Make sure any pending truncation is applied before doing anything
+ * that may depend on it.
+ */
+void __ceph_do_pending_vmtruncate(struct inode *inode)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	u64 to;
+	int wrbuffer_refs, wake = 0;
+
+retry:
+	spin_lock(&inode->i_lock);
+	if (ci->i_truncate_pending == 0) {
+		dout("__do_pending_vmtruncate %p none pending\n", inode);
+		spin_unlock(&inode->i_lock);
+		return;
+	}
+
+	/*
+	 * make sure any dirty snapped pages are flushed before we
+	 * possibly truncate them.. so write AND block!
+	 */
+	if (ci->i_wrbuffer_ref_head < ci->i_wrbuffer_ref) {
+		dout("__do_pending_vmtruncate %p flushing snaps first\n",
+		     inode);
+		spin_unlock(&inode->i_lock);
+		filemap_write_and_wait_range(&inode->i_data, 0,
+					     inode->i_sb->s_maxbytes);
+		goto retry;
+	}
+
+	to = ci->i_truncate_size;
+	wrbuffer_refs = ci->i_wrbuffer_ref;
+	dout("__do_pending_vmtruncate %p (%d) to %lld\n", inode,
+	     ci->i_truncate_pending, to);
+	spin_unlock(&inode->i_lock);
+
+	truncate_inode_pages(inode->i_mapping, to);
+
+	spin_lock(&inode->i_lock);
+	ci->i_truncate_pending--;
+	if (ci->i_truncate_pending == 0)
+		wake = 1;
+	spin_unlock(&inode->i_lock);
+
+	if (wrbuffer_refs == 0)
+		ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
+	if (wake)
+		wake_up(&ci->i_cap_wq);
+}
+
+
+/*
+ * symlinks
+ */
+static void *ceph_sym_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+	struct ceph_inode_info *ci = ceph_inode(dentry->d_inode);
+	nd_set_link(nd, ci->i_symlink);
+	return NULL;
+}
+
+static const struct inode_operations ceph_symlink_iops = {
+	.readlink = generic_readlink,
+	.follow_link = ceph_sym_follow_link,
+};
+
+/*
+ * setattr
+ */
+int ceph_setattr(struct dentry *dentry, struct iattr *attr)
+{
+	struct inode *inode = dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct inode *parent_inode = dentry->d_parent->d_inode;
+	const unsigned int ia_valid = attr->ia_valid;
+	struct ceph_mds_request *req;
+	struct ceph_mds_client *mdsc = &ceph_client(dentry->d_sb)->mdsc;
+	int issued;
+	int release = 0, dirtied = 0;
+	int mask = 0;
+	int err = 0;
+
+	if (ceph_snap(inode) != CEPH_NOSNAP)
+		return -EROFS;
+
+	__ceph_do_pending_vmtruncate(inode);
+
+	err = inode_change_ok(inode, attr);
+	if (err != 0)
+		return err;
+
+	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETATTR,
+				       USE_AUTH_MDS);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	spin_lock(&inode->i_lock);
+	issued = __ceph_caps_issued(ci, NULL);
+	dout("setattr %p issued %s\n", inode, ceph_cap_string(issued));
+
+	if (ia_valid & ATTR_UID) {
+		dout("setattr %p uid %d -> %d\n", inode,
+		     inode->i_uid, attr->ia_uid);
+		if (issued & CEPH_CAP_AUTH_EXCL) {
+			inode->i_uid = attr->ia_uid;
+			dirtied |= CEPH_CAP_AUTH_EXCL;
+		} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
+			   attr->ia_uid != inode->i_uid) {
+			req->r_args.setattr.uid = cpu_to_le32(attr->ia_uid);
+			mask |= CEPH_SETATTR_UID;
+			release |= CEPH_CAP_AUTH_SHARED;
+		}
+	}
+	if (ia_valid & ATTR_GID) {
+		dout("setattr %p gid %d -> %d\n", inode,
+		     inode->i_gid, attr->ia_gid);
+		if (issued & CEPH_CAP_AUTH_EXCL) {
+			inode->i_gid = attr->ia_gid;
+			dirtied |= CEPH_CAP_AUTH_EXCL;
+		} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
+			   attr->ia_gid != inode->i_gid) {
+			req->r_args.setattr.gid = cpu_to_le32(attr->ia_gid);
+			mask |= CEPH_SETATTR_GID;
+			release |= CEPH_CAP_AUTH_SHARED;
+		}
+	}
+	if (ia_valid & ATTR_MODE) {
+		dout("setattr %p mode 0%o -> 0%o\n", inode, inode->i_mode,
+		     attr->ia_mode);
+		if (issued & CEPH_CAP_AUTH_EXCL) {
+			inode->i_mode = attr->ia_mode;
+			dirtied |= CEPH_CAP_AUTH_EXCL;
+		} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
+			   attr->ia_mode != inode->i_mode) {
+			req->r_args.setattr.mode = cpu_to_le32(attr->ia_mode);
+			mask |= CEPH_SETATTR_MODE;
+			release |= CEPH_CAP_AUTH_SHARED;
+		}
+	}
+
+	if (ia_valid & ATTR_ATIME) {
+		dout("setattr %p atime %ld.%ld -> %ld.%ld\n", inode,
+		     inode->i_atime.tv_sec, inode->i_atime.tv_nsec,
+		     attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec);
+		if (issued & CEPH_CAP_FILE_EXCL) {
+			ci->i_time_warp_seq++;
+			inode->i_atime = attr->ia_atime;
+			dirtied |= CEPH_CAP_FILE_EXCL;
+		} else if ((issued & CEPH_CAP_FILE_WR) &&
+			   timespec_compare(&inode->i_atime,
+					    &attr->ia_atime) < 0) {
+			inode->i_atime = attr->ia_atime;
+			dirtied |= CEPH_CAP_FILE_WR;
+		} else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
+			   !timespec_equal(&inode->i_atime, &attr->ia_atime)) {
+			ceph_encode_timespec(&req->r_args.setattr.atime,
+					     &attr->ia_atime);
+			mask |= CEPH_SETATTR_ATIME;
+			release |= CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_RD |
+				CEPH_CAP_FILE_WR;
+		}
+	}
+	if (ia_valid & ATTR_MTIME) {
+		dout("setattr %p mtime %ld.%ld -> %ld.%ld\n", inode,
+		     inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
+		     attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec);
+		if (issued & CEPH_CAP_FILE_EXCL) {
+			ci->i_time_warp_seq++;
+			inode->i_mtime = attr->ia_mtime;
+			dirtied |= CEPH_CAP_FILE_EXCL;
+		} else if ((issued & CEPH_CAP_FILE_WR) &&
+			   timespec_compare(&inode->i_mtime,
+					    &attr->ia_mtime) < 0) {
+			inode->i_mtime = attr->ia_mtime;
+			dirtied |= CEPH_CAP_FILE_WR;
+		} else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
+			   !timespec_equal(&inode->i_mtime, &attr->ia_mtime)) {
+			ceph_encode_timespec(&req->r_args.setattr.mtime,
+					     &attr->ia_mtime);
+			mask |= CEPH_SETATTR_MTIME;
+			release |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_RD |
+				CEPH_CAP_FILE_WR;
+		}
+	}
+	if (ia_valid & ATTR_SIZE) {
+		dout("setattr %p size %lld -> %lld\n", inode,
+		     inode->i_size, attr->ia_size);
+		if (attr->ia_size > inode->i_sb->s_maxbytes) {
+			err = -EINVAL;
+			goto out;
+		}
+		if ((issued & CEPH_CAP_FILE_EXCL) &&
+		    attr->ia_size > inode->i_size) {
+			inode->i_size = attr->ia_size;
+			inode->i_blocks =
+				(attr->ia_size + (1 << 9) - 1) >> 9;
+			inode->i_ctime = attr->ia_ctime;
+			ci->i_reported_size = attr->ia_size;
+			dirtied |= CEPH_CAP_FILE_EXCL;
+		} else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
+			   attr->ia_size != inode->i_size) {
+			req->r_args.setattr.size = cpu_to_le64(attr->ia_size);
+			req->r_args.setattr.old_size =
+				cpu_to_le64(inode->i_size);
+			mask |= CEPH_SETATTR_SIZE;
+			release |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_RD |
+				CEPH_CAP_FILE_WR;
+		}
+	}
+
+	/* these do nothing */
+	if (ia_valid & ATTR_CTIME) {
+		bool only = (ia_valid & (ATTR_SIZE|ATTR_MTIME|ATTR_ATIME|
+					 ATTR_MODE|ATTR_UID|ATTR_GID)) == 0;
+		dout("setattr %p ctime %ld.%ld -> %ld.%ld (%s)\n", inode,
+		     inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
+		     attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec,
+		     only ? "ctime only" : "ignored");
+		inode->i_ctime = attr->ia_ctime;
+		if (only) {
+			/*
+			 * if kernel wants to dirty ctime but nothing else,
+			 * we need to choose a cap to dirty under, or do
+			 * a almost-no-op setattr
+			 */
+			if (issued & CEPH_CAP_AUTH_EXCL)
+				dirtied |= CEPH_CAP_AUTH_EXCL;
+			else if (issued & CEPH_CAP_FILE_EXCL)
+				dirtied |= CEPH_CAP_FILE_EXCL;
+			else if (issued & CEPH_CAP_XATTR_EXCL)
+				dirtied |= CEPH_CAP_XATTR_EXCL;
+			else
+				mask |= CEPH_SETATTR_CTIME;
+		}
+	}
+	if (ia_valid & ATTR_FILE)
+		dout("setattr %p ATTR_FILE ... hrm!\n", inode);
+
+	if (dirtied) {
+		__ceph_mark_dirty_caps(ci, dirtied);
+		inode->i_ctime = CURRENT_TIME;
+	}
+
+	release &= issued;
+	spin_unlock(&inode->i_lock);
+
+	if (mask) {
+		req->r_inode = igrab(inode);
+		req->r_inode_drop = release;
+		req->r_args.setattr.mask = cpu_to_le32(mask);
+		req->r_num_caps = 1;
+		err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+	}
+	dout("setattr %p result=%d (%s locally, %d remote)\n", inode, err,
+	     ceph_cap_string(dirtied), mask);
+
+	ceph_mdsc_put_request(req);
+	__ceph_do_pending_vmtruncate(inode);
+	return err;
+out:
+	spin_unlock(&inode->i_lock);
+	ceph_mdsc_put_request(req);
+	return err;
+}
+
+/*
+ * Verify that we have a lease on the given mask.  If not,
+ * do a getattr against an mds.
+ */
+int ceph_do_getattr(struct inode *inode, int mask)
+{
+	struct ceph_client *client = ceph_sb_to_client(inode->i_sb);
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct ceph_mds_request *req;
+	int err;
+
+	if (ceph_snap(inode) == CEPH_SNAPDIR) {
+		dout("do_getattr inode %p SNAPDIR\n", inode);
+		return 0;
+	}
+
+	dout("do_getattr inode %p mask %s\n", inode, ceph_cap_string(mask));
+	if (ceph_caps_issued_mask(ceph_inode(inode), mask, 1))
+		return 0;
+
+	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+	req->r_inode = igrab(inode);
+	req->r_num_caps = 1;
+	req->r_args.getattr.mask = cpu_to_le32(mask);
+	err = ceph_mdsc_do_request(mdsc, NULL, req);
+	ceph_mdsc_put_request(req);
+	dout("do_getattr result=%d\n", err);
+	return err;
+}
+
+
+/*
+ * Check inode permissions.  We verify we have a valid value for
+ * the AUTH cap, then call the generic handler.
+ */
+int ceph_permission(struct inode *inode, int mask)
+{
+	int err = ceph_do_getattr(inode, CEPH_CAP_AUTH_SHARED);
+
+	if (!err)
+		err = generic_permission(inode, mask, NULL);
+	return err;
+}
+
+/*
+ * Get all attributes.  Hopefully somedata we'll have a statlite()
+ * and can limit the fields we require to be accurate.
+ */
+int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry,
+		 struct kstat *stat)
+{
+	struct inode *inode = dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int err;
+
+	err = ceph_do_getattr(inode, CEPH_STAT_CAP_INODE_ALL);
+	if (!err) {
+		generic_fillattr(inode, stat);
+		stat->ino = inode->i_ino;
+		if (ceph_snap(inode) != CEPH_NOSNAP)
+			stat->dev = ceph_snap(inode);
+		else
+			stat->dev = 0;
+		if (S_ISDIR(inode->i_mode)) {
+			stat->size = ci->i_rbytes;
+			stat->blocks = 0;
+			stat->blksize = 65536;
+		}
+	}
+	return err;
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/ioctl.c linux-libre-2.6.34-gnu1/fs/ceph/ioctl.c
--- linux-libre-2.6.33-gnu1/fs/ceph/ioctl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,160 @@
+#include <linux/in.h>
+
+#include "ioctl.h"
+#include "super.h"
+#include "ceph_debug.h"
+
+
+/*
+ * ioctls
+ */
+
+/*
+ * get and set the file layout
+ */
+static long ceph_ioctl_get_layout(struct file *file, void __user *arg)
+{
+	struct ceph_inode_info *ci = ceph_inode(file->f_dentry->d_inode);
+	struct ceph_ioctl_layout l;
+	int err;
+
+	err = ceph_do_getattr(file->f_dentry->d_inode, CEPH_STAT_CAP_LAYOUT);
+	if (!err) {
+		l.stripe_unit = ceph_file_layout_su(ci->i_layout);
+		l.stripe_count = ceph_file_layout_stripe_count(ci->i_layout);
+		l.object_size = ceph_file_layout_object_size(ci->i_layout);
+		l.data_pool = le32_to_cpu(ci->i_layout.fl_pg_pool);
+		l.preferred_osd =
+			(s32)le32_to_cpu(ci->i_layout.fl_pg_preferred);
+		if (copy_to_user(arg, &l, sizeof(l)))
+			return -EFAULT;
+	}
+
+	return err;
+}
+
+static long ceph_ioctl_set_layout(struct file *file, void __user *arg)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	struct inode *parent_inode = file->f_dentry->d_parent->d_inode;
+	struct ceph_mds_client *mdsc = &ceph_sb_to_client(inode->i_sb)->mdsc;
+	struct ceph_mds_request *req;
+	struct ceph_ioctl_layout l;
+	int err, i;
+
+	/* copy and validate */
+	if (copy_from_user(&l, arg, sizeof(l)))
+		return -EFAULT;
+
+	if ((l.object_size & ~PAGE_MASK) ||
+	    (l.stripe_unit & ~PAGE_MASK) ||
+	    !l.stripe_unit ||
+	    (l.object_size &&
+	     (unsigned)l.object_size % (unsigned)l.stripe_unit))
+		return -EINVAL;
+
+	/* make sure it's a valid data pool */
+	if (l.data_pool > 0) {
+		mutex_lock(&mdsc->mutex);
+		err = -EINVAL;
+		for (i = 0; i < mdsc->mdsmap->m_num_data_pg_pools; i++)
+			if (mdsc->mdsmap->m_data_pg_pools[i] == l.data_pool) {
+				err = 0;
+				break;
+			}
+		mutex_unlock(&mdsc->mutex);
+		if (err)
+			return err;
+	}
+
+	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETLAYOUT,
+				       USE_AUTH_MDS);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+	req->r_inode = igrab(inode);
+	req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL;
+
+	req->r_args.setlayout.layout.fl_stripe_unit =
+		cpu_to_le32(l.stripe_unit);
+	req->r_args.setlayout.layout.fl_stripe_count =
+		cpu_to_le32(l.stripe_count);
+	req->r_args.setlayout.layout.fl_object_size =
+		cpu_to_le32(l.object_size);
+	req->r_args.setlayout.layout.fl_pg_pool = cpu_to_le32(l.data_pool);
+	req->r_args.setlayout.layout.fl_pg_preferred =
+		cpu_to_le32(l.preferred_osd);
+
+	err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+	ceph_mdsc_put_request(req);
+	return err;
+}
+
+/*
+ * Return object name, size/offset information, and location (OSD
+ * number, network address) for a given file offset.
+ */
+static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg)
+{
+	struct ceph_ioctl_dataloc dl;
+	struct inode *inode = file->f_dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_osd_client *osdc = &ceph_client(inode->i_sb)->osdc;
+	u64 len = 1, olen;
+	u64 tmp;
+	struct ceph_object_layout ol;
+	struct ceph_pg pgid;
+
+	/* copy and validate */
+	if (copy_from_user(&dl, arg, sizeof(dl)))
+		return -EFAULT;
+
+	down_read(&osdc->map_sem);
+	ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, &len,
+				      &dl.object_no, &dl.object_offset, &olen);
+	dl.file_offset -= dl.object_offset;
+	dl.object_size = ceph_file_layout_object_size(ci->i_layout);
+	dl.block_size = ceph_file_layout_su(ci->i_layout);
+
+	/* block_offset = object_offset % block_size */
+	tmp = dl.object_offset;
+	dl.block_offset = do_div(tmp, dl.block_size);
+
+	snprintf(dl.object_name, sizeof(dl.object_name), "%llx.%08llx",
+		 ceph_ino(inode), dl.object_no);
+	ceph_calc_object_layout(&ol, dl.object_name, &ci->i_layout,
+				osdc->osdmap);
+
+	pgid = ol.ol_pgid;
+	dl.osd = ceph_calc_pg_primary(osdc->osdmap, pgid);
+	if (dl.osd >= 0) {
+		struct ceph_entity_addr *a =
+			ceph_osd_addr(osdc->osdmap, dl.osd);
+		if (a)
+			memcpy(&dl.osd_addr, &a->in_addr, sizeof(dl.osd_addr));
+	} else {
+		memset(&dl.osd_addr, 0, sizeof(dl.osd_addr));
+	}
+	up_read(&osdc->map_sem);
+
+	/* send result back to user */
+	if (copy_to_user(arg, &dl, sizeof(dl)))
+		return -EFAULT;
+
+	return 0;
+}
+
+long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	dout("ioctl file %p cmd %u arg %lu\n", file, cmd, arg);
+	switch (cmd) {
+	case CEPH_IOC_GET_LAYOUT:
+		return ceph_ioctl_get_layout(file, (void __user *)arg);
+
+	case CEPH_IOC_SET_LAYOUT:
+		return ceph_ioctl_set_layout(file, (void __user *)arg);
+
+	case CEPH_IOC_GET_DATALOC:
+		return ceph_ioctl_get_dataloc(file, (void __user *)arg);
+	}
+	return -ENOTTY;
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/ioctl.h linux-libre-2.6.34-gnu1/fs/ceph/ioctl.h
--- linux-libre-2.6.33-gnu1/fs/ceph/ioctl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/ioctl.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,40 @@
+#ifndef FS_CEPH_IOCTL_H
+#define FS_CEPH_IOCTL_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define CEPH_IOCTL_MAGIC 0x97
+
+/* just use u64 to align sanely on all archs */
+struct ceph_ioctl_layout {
+	__u64 stripe_unit, stripe_count, object_size;
+	__u64 data_pool;
+	__s64 preferred_osd;
+};
+
+#define CEPH_IOC_GET_LAYOUT _IOR(CEPH_IOCTL_MAGIC, 1,		\
+				   struct ceph_ioctl_layout)
+#define CEPH_IOC_SET_LAYOUT _IOW(CEPH_IOCTL_MAGIC, 2,		\
+				   struct ceph_ioctl_layout)
+
+/*
+ * Extract identity, address of the OSD and object storing a given
+ * file offset.
+ */
+struct ceph_ioctl_dataloc {
+	__u64 file_offset;           /* in+out: file offset */
+	__u64 object_offset;         /* out: offset in object */
+	__u64 object_no;             /* out: object # */
+	__u64 object_size;           /* out: object size */
+	char object_name[64];        /* out: object name */
+	__u64 block_offset;          /* out: offset in block */
+	__u64 block_size;            /* out: block length */
+	__s64 osd;                   /* out: osd # */
+	struct sockaddr_storage osd_addr; /* out: osd address */
+};
+
+#define CEPH_IOC_GET_DATALOC _IOWR(CEPH_IOCTL_MAGIC, 3,	\
+				   struct ceph_ioctl_dataloc)
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/Kconfig linux-libre-2.6.34-gnu1/fs/ceph/Kconfig
--- linux-libre-2.6.33-gnu1/fs/ceph/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/Kconfig	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,27 @@
+config CEPH_FS
+        tristate "Ceph distributed file system (EXPERIMENTAL)"
+	depends on INET && EXPERIMENTAL
+	select LIBCRC32C
+	select CONFIG_CRYPTO_AES
+	help
+	  Choose Y or M here to include support for mounting the
+	  experimental Ceph distributed file system.  Ceph is an extremely
+	  scalable file system designed to provide high performance,
+	  reliable access to petabytes of storage.
+
+	  More information at http://ceph.newdream.net/.
+
+	  If unsure, say N.
+
+config CEPH_FS_PRETTYDEBUG
+	bool "Include file:line in ceph debug output"
+	depends on CEPH_FS
+	default n
+	help
+	  If you say Y here, debug output will include a filename and
+	  line to aid debugging.  This icnreases kernel size and slows
+	  execution slightly when debug call sites are enabled (e.g.,
+	  via CONFIG_DYNAMIC_DEBUG).
+
+	  If unsure, say N.
+
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/Makefile linux-libre-2.6.34-gnu1/fs/ceph/Makefile
--- linux-libre-2.6.33-gnu1/fs/ceph/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/Makefile	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,39 @@
+#
+# Makefile for CEPH filesystem.
+#
+
+ifneq ($(KERNELRELEASE),)
+
+obj-$(CONFIG_CEPH_FS) += ceph.o
+
+ceph-objs := super.o inode.o dir.o file.o addr.o ioctl.o \
+	export.o caps.o snap.o xattr.o \
+	messenger.o msgpool.o buffer.o pagelist.o \
+	mds_client.o mdsmap.o \
+	mon_client.o \
+	osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \
+	debugfs.o \
+	auth.o auth_none.o \
+	crypto.o armor.o \
+	auth_x.o \
+	ceph_fs.o ceph_strings.o ceph_hash.o ceph_frag.o
+
+else
+#Otherwise we were called directly from the command
+# line; invoke the kernel build system.
+
+KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+PWD := $(shell pwd)
+
+default: all
+
+all:
+	$(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_FS=m modules
+
+modules_install:
+	$(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_FS=m modules_install
+
+clean:
+	$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
+
+endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/mds_client.c linux-libre-2.6.34-gnu1/fs/ceph/mds_client.c
--- linux-libre-2.6.33-gnu1/fs/ceph/mds_client.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/mds_client.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,3047 @@
+#include "ceph_debug.h"
+
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+
+#include "mds_client.h"
+#include "mon_client.h"
+#include "super.h"
+#include "messenger.h"
+#include "decode.h"
+#include "auth.h"
+#include "pagelist.h"
+
+/*
+ * A cluster of MDS (metadata server) daemons is responsible for
+ * managing the file system namespace (the directory hierarchy and
+ * inodes) and for coordinating shared access to storage.  Metadata is
+ * partitioning hierarchically across a number of servers, and that
+ * partition varies over time as the cluster adjusts the distribution
+ * in order to balance load.
+ *
+ * The MDS client is primarily responsible to managing synchronous
+ * metadata requests for operations like open, unlink, and so forth.
+ * If there is a MDS failure, we find out about it when we (possibly
+ * request and) receive a new MDS map, and can resubmit affected
+ * requests.
+ *
+ * For the most part, though, we take advantage of a lossless
+ * communications channel to the MDS, and do not need to worry about
+ * timing out or resubmitting requests.
+ *
+ * We maintain a stateful "session" with each MDS we interact with.
+ * Within each session, we sent periodic heartbeat messages to ensure
+ * any capabilities or leases we have been issues remain valid.  If
+ * the session times out and goes stale, our leases and capabilities
+ * are no longer valid.
+ */
+
+static void __wake_requests(struct ceph_mds_client *mdsc,
+			    struct list_head *head);
+
+const static struct ceph_connection_operations mds_con_ops;
+
+
+/*
+ * mds reply parsing
+ */
+
+/*
+ * parse individual inode info
+ */
+static int parse_reply_info_in(void **p, void *end,
+			       struct ceph_mds_reply_info_in *info)
+{
+	int err = -EIO;
+
+	info->in = *p;
+	*p += sizeof(struct ceph_mds_reply_inode) +
+		sizeof(*info->in->fragtree.splits) *
+		le32_to_cpu(info->in->fragtree.nsplits);
+
+	ceph_decode_32_safe(p, end, info->symlink_len, bad);
+	ceph_decode_need(p, end, info->symlink_len, bad);
+	info->symlink = *p;
+	*p += info->symlink_len;
+
+	ceph_decode_32_safe(p, end, info->xattr_len, bad);
+	ceph_decode_need(p, end, info->xattr_len, bad);
+	info->xattr_data = *p;
+	*p += info->xattr_len;
+	return 0;
+bad:
+	return err;
+}
+
+/*
+ * parse a normal reply, which may contain a (dir+)dentry and/or a
+ * target inode.
+ */
+static int parse_reply_info_trace(void **p, void *end,
+				  struct ceph_mds_reply_info_parsed *info)
+{
+	int err;
+
+	if (info->head->is_dentry) {
+		err = parse_reply_info_in(p, end, &info->diri);
+		if (err < 0)
+			goto out_bad;
+
+		if (unlikely(*p + sizeof(*info->dirfrag) > end))
+			goto bad;
+		info->dirfrag = *p;
+		*p += sizeof(*info->dirfrag) +
+			sizeof(u32)*le32_to_cpu(info->dirfrag->ndist);
+		if (unlikely(*p > end))
+			goto bad;
+
+		ceph_decode_32_safe(p, end, info->dname_len, bad);
+		ceph_decode_need(p, end, info->dname_len, bad);
+		info->dname = *p;
+		*p += info->dname_len;
+		info->dlease = *p;
+		*p += sizeof(*info->dlease);
+	}
+
+	if (info->head->is_target) {
+		err = parse_reply_info_in(p, end, &info->targeti);
+		if (err < 0)
+			goto out_bad;
+	}
+
+	if (unlikely(*p != end))
+		goto bad;
+	return 0;
+
+bad:
+	err = -EIO;
+out_bad:
+	pr_err("problem parsing mds trace %d\n", err);
+	return err;
+}
+
+/*
+ * parse readdir results
+ */
+static int parse_reply_info_dir(void **p, void *end,
+				struct ceph_mds_reply_info_parsed *info)
+{
+	u32 num, i = 0;
+	int err;
+
+	info->dir_dir = *p;
+	if (*p + sizeof(*info->dir_dir) > end)
+		goto bad;
+	*p += sizeof(*info->dir_dir) +
+		sizeof(u32)*le32_to_cpu(info->dir_dir->ndist);
+	if (*p > end)
+		goto bad;
+
+	ceph_decode_need(p, end, sizeof(num) + 2, bad);
+	num = ceph_decode_32(p);
+	info->dir_end = ceph_decode_8(p);
+	info->dir_complete = ceph_decode_8(p);
+	if (num == 0)
+		goto done;
+
+	/* alloc large array */
+	info->dir_nr = num;
+	info->dir_in = kcalloc(num, sizeof(*info->dir_in) +
+			       sizeof(*info->dir_dname) +
+			       sizeof(*info->dir_dname_len) +
+			       sizeof(*info->dir_dlease),
+			       GFP_NOFS);
+	if (info->dir_in == NULL) {
+		err = -ENOMEM;
+		goto out_bad;
+	}
+	info->dir_dname = (void *)(info->dir_in + num);
+	info->dir_dname_len = (void *)(info->dir_dname + num);
+	info->dir_dlease = (void *)(info->dir_dname_len + num);
+
+	while (num) {
+		/* dentry */
+		ceph_decode_need(p, end, sizeof(u32)*2, bad);
+		info->dir_dname_len[i] = ceph_decode_32(p);
+		ceph_decode_need(p, end, info->dir_dname_len[i], bad);
+		info->dir_dname[i] = *p;
+		*p += info->dir_dname_len[i];
+		dout("parsed dir dname '%.*s'\n", info->dir_dname_len[i],
+		     info->dir_dname[i]);
+		info->dir_dlease[i] = *p;
+		*p += sizeof(struct ceph_mds_reply_lease);
+
+		/* inode */
+		err = parse_reply_info_in(p, end, &info->dir_in[i]);
+		if (err < 0)
+			goto out_bad;
+		i++;
+		num--;
+	}
+
+done:
+	if (*p != end)
+		goto bad;
+	return 0;
+
+bad:
+	err = -EIO;
+out_bad:
+	pr_err("problem parsing dir contents %d\n", err);
+	return err;
+}
+
+/*
+ * parse entire mds reply
+ */
+static int parse_reply_info(struct ceph_msg *msg,
+			    struct ceph_mds_reply_info_parsed *info)
+{
+	void *p, *end;
+	u32 len;
+	int err;
+
+	info->head = msg->front.iov_base;
+	p = msg->front.iov_base + sizeof(struct ceph_mds_reply_head);
+	end = p + msg->front.iov_len - sizeof(struct ceph_mds_reply_head);
+
+	/* trace */
+	ceph_decode_32_safe(&p, end, len, bad);
+	if (len > 0) {
+		err = parse_reply_info_trace(&p, p+len, info);
+		if (err < 0)
+			goto out_bad;
+	}
+
+	/* dir content */
+	ceph_decode_32_safe(&p, end, len, bad);
+	if (len > 0) {
+		err = parse_reply_info_dir(&p, p+len, info);
+		if (err < 0)
+			goto out_bad;
+	}
+
+	/* snap blob */
+	ceph_decode_32_safe(&p, end, len, bad);
+	info->snapblob_len = len;
+	info->snapblob = p;
+	p += len;
+
+	if (p != end)
+		goto bad;
+	return 0;
+
+bad:
+	err = -EIO;
+out_bad:
+	pr_err("mds parse_reply err %d\n", err);
+	return err;
+}
+
+static void destroy_reply_info(struct ceph_mds_reply_info_parsed *info)
+{
+	kfree(info->dir_in);
+}
+
+
+/*
+ * sessions
+ */
+static const char *session_state_name(int s)
+{
+	switch (s) {
+	case CEPH_MDS_SESSION_NEW: return "new";
+	case CEPH_MDS_SESSION_OPENING: return "opening";
+	case CEPH_MDS_SESSION_OPEN: return "open";
+	case CEPH_MDS_SESSION_HUNG: return "hung";
+	case CEPH_MDS_SESSION_CLOSING: return "closing";
+	case CEPH_MDS_SESSION_RESTARTING: return "restarting";
+	case CEPH_MDS_SESSION_RECONNECTING: return "reconnecting";
+	default: return "???";
+	}
+}
+
+static struct ceph_mds_session *get_session(struct ceph_mds_session *s)
+{
+	if (atomic_inc_not_zero(&s->s_ref)) {
+		dout("mdsc get_session %p %d -> %d\n", s,
+		     atomic_read(&s->s_ref)-1, atomic_read(&s->s_ref));
+		return s;
+	} else {
+		dout("mdsc get_session %p 0 -- FAIL", s);
+		return NULL;
+	}
+}
+
+void ceph_put_mds_session(struct ceph_mds_session *s)
+{
+	dout("mdsc put_session %p %d -> %d\n", s,
+	     atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1);
+	if (atomic_dec_and_test(&s->s_ref)) {
+		if (s->s_authorizer)
+			s->s_mdsc->client->monc.auth->ops->destroy_authorizer(
+				s->s_mdsc->client->monc.auth, s->s_authorizer);
+		kfree(s);
+	}
+}
+
+/*
+ * called under mdsc->mutex
+ */
+struct ceph_mds_session *__ceph_lookup_mds_session(struct ceph_mds_client *mdsc,
+						   int mds)
+{
+	struct ceph_mds_session *session;
+
+	if (mds >= mdsc->max_sessions || mdsc->sessions[mds] == NULL)
+		return NULL;
+	session = mdsc->sessions[mds];
+	dout("lookup_mds_session %p %d\n", session,
+	     atomic_read(&session->s_ref));
+	get_session(session);
+	return session;
+}
+
+static bool __have_session(struct ceph_mds_client *mdsc, int mds)
+{
+	if (mds >= mdsc->max_sessions)
+		return false;
+	return mdsc->sessions[mds];
+}
+
+static int __verify_registered_session(struct ceph_mds_client *mdsc,
+				       struct ceph_mds_session *s)
+{
+	if (s->s_mds >= mdsc->max_sessions ||
+	    mdsc->sessions[s->s_mds] != s)
+		return -ENOENT;
+	return 0;
+}
+
+/*
+ * create+register a new session for given mds.
+ * called under mdsc->mutex.
+ */
+static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
+						 int mds)
+{
+	struct ceph_mds_session *s;
+
+	s = kzalloc(sizeof(*s), GFP_NOFS);
+	if (!s)
+		return ERR_PTR(-ENOMEM);
+	s->s_mdsc = mdsc;
+	s->s_mds = mds;
+	s->s_state = CEPH_MDS_SESSION_NEW;
+	s->s_ttl = 0;
+	s->s_seq = 0;
+	mutex_init(&s->s_mutex);
+
+	ceph_con_init(mdsc->client->msgr, &s->s_con);
+	s->s_con.private = s;
+	s->s_con.ops = &mds_con_ops;
+	s->s_con.peer_name.type = CEPH_ENTITY_TYPE_MDS;
+	s->s_con.peer_name.num = cpu_to_le64(mds);
+
+	spin_lock_init(&s->s_cap_lock);
+	s->s_cap_gen = 0;
+	s->s_cap_ttl = 0;
+	s->s_renew_requested = 0;
+	s->s_renew_seq = 0;
+	INIT_LIST_HEAD(&s->s_caps);
+	s->s_nr_caps = 0;
+	s->s_trim_caps = 0;
+	atomic_set(&s->s_ref, 1);
+	INIT_LIST_HEAD(&s->s_waiting);
+	INIT_LIST_HEAD(&s->s_unsafe);
+	s->s_num_cap_releases = 0;
+	s->s_cap_iterator = NULL;
+	INIT_LIST_HEAD(&s->s_cap_releases);
+	INIT_LIST_HEAD(&s->s_cap_releases_done);
+	INIT_LIST_HEAD(&s->s_cap_flushing);
+	INIT_LIST_HEAD(&s->s_cap_snaps_flushing);
+
+	dout("register_session mds%d\n", mds);
+	if (mds >= mdsc->max_sessions) {
+		int newmax = 1 << get_count_order(mds+1);
+		struct ceph_mds_session **sa;
+
+		dout("register_session realloc to %d\n", newmax);
+		sa = kcalloc(newmax, sizeof(void *), GFP_NOFS);
+		if (sa == NULL)
+			goto fail_realloc;
+		if (mdsc->sessions) {
+			memcpy(sa, mdsc->sessions,
+			       mdsc->max_sessions * sizeof(void *));
+			kfree(mdsc->sessions);
+		}
+		mdsc->sessions = sa;
+		mdsc->max_sessions = newmax;
+	}
+	mdsc->sessions[mds] = s;
+	atomic_inc(&s->s_ref);  /* one ref to sessions[], one to caller */
+
+	ceph_con_open(&s->s_con, ceph_mdsmap_get_addr(mdsc->mdsmap, mds));
+
+	return s;
+
+fail_realloc:
+	kfree(s);
+	return ERR_PTR(-ENOMEM);
+}
+
+/*
+ * called under mdsc->mutex
+ */
+static void __unregister_session(struct ceph_mds_client *mdsc,
+			       struct ceph_mds_session *s)
+{
+	dout("__unregister_session mds%d %p\n", s->s_mds, s);
+	BUG_ON(mdsc->sessions[s->s_mds] != s);
+	mdsc->sessions[s->s_mds] = NULL;
+	ceph_con_close(&s->s_con);
+	ceph_put_mds_session(s);
+}
+
+/*
+ * drop session refs in request.
+ *
+ * should be last request ref, or hold mdsc->mutex
+ */
+static void put_request_session(struct ceph_mds_request *req)
+{
+	if (req->r_session) {
+		ceph_put_mds_session(req->r_session);
+		req->r_session = NULL;
+	}
+}
+
+void ceph_mdsc_release_request(struct kref *kref)
+{
+	struct ceph_mds_request *req = container_of(kref,
+						    struct ceph_mds_request,
+						    r_kref);
+	if (req->r_request)
+		ceph_msg_put(req->r_request);
+	if (req->r_reply) {
+		ceph_msg_put(req->r_reply);
+		destroy_reply_info(&req->r_reply_info);
+	}
+	if (req->r_inode) {
+		ceph_put_cap_refs(ceph_inode(req->r_inode),
+				  CEPH_CAP_PIN);
+		iput(req->r_inode);
+	}
+	if (req->r_locked_dir)
+		ceph_put_cap_refs(ceph_inode(req->r_locked_dir),
+				  CEPH_CAP_PIN);
+	if (req->r_target_inode)
+		iput(req->r_target_inode);
+	if (req->r_dentry)
+		dput(req->r_dentry);
+	if (req->r_old_dentry) {
+		ceph_put_cap_refs(
+			ceph_inode(req->r_old_dentry->d_parent->d_inode),
+			CEPH_CAP_PIN);
+		dput(req->r_old_dentry);
+	}
+	kfree(req->r_path1);
+	kfree(req->r_path2);
+	put_request_session(req);
+	ceph_unreserve_caps(&req->r_caps_reservation);
+	kfree(req);
+}
+
+/*
+ * lookup session, bump ref if found.
+ *
+ * called under mdsc->mutex.
+ */
+static struct ceph_mds_request *__lookup_request(struct ceph_mds_client *mdsc,
+					     u64 tid)
+{
+	struct ceph_mds_request *req;
+	struct rb_node *n = mdsc->request_tree.rb_node;
+
+	while (n) {
+		req = rb_entry(n, struct ceph_mds_request, r_node);
+		if (tid < req->r_tid)
+			n = n->rb_left;
+		else if (tid > req->r_tid)
+			n = n->rb_right;
+		else {
+			ceph_mdsc_get_request(req);
+			return req;
+		}
+	}
+	return NULL;
+}
+
+static void __insert_request(struct ceph_mds_client *mdsc,
+			     struct ceph_mds_request *new)
+{
+	struct rb_node **p = &mdsc->request_tree.rb_node;
+	struct rb_node *parent = NULL;
+	struct ceph_mds_request *req = NULL;
+
+	while (*p) {
+		parent = *p;
+		req = rb_entry(parent, struct ceph_mds_request, r_node);
+		if (new->r_tid < req->r_tid)
+			p = &(*p)->rb_left;
+		else if (new->r_tid > req->r_tid)
+			p = &(*p)->rb_right;
+		else
+			BUG();
+	}
+
+	rb_link_node(&new->r_node, parent, p);
+	rb_insert_color(&new->r_node, &mdsc->request_tree);
+}
+
+/*
+ * Register an in-flight request, and assign a tid.  Link to directory
+ * are modifying (if any).
+ *
+ * Called under mdsc->mutex.
+ */
+static void __register_request(struct ceph_mds_client *mdsc,
+			       struct ceph_mds_request *req,
+			       struct inode *dir)
+{
+	req->r_tid = ++mdsc->last_tid;
+	if (req->r_num_caps)
+		ceph_reserve_caps(&req->r_caps_reservation, req->r_num_caps);
+	dout("__register_request %p tid %lld\n", req, req->r_tid);
+	ceph_mdsc_get_request(req);
+	__insert_request(mdsc, req);
+
+	if (dir) {
+		struct ceph_inode_info *ci = ceph_inode(dir);
+
+		spin_lock(&ci->i_unsafe_lock);
+		req->r_unsafe_dir = dir;
+		list_add_tail(&req->r_unsafe_dir_item, &ci->i_unsafe_dirops);
+		spin_unlock(&ci->i_unsafe_lock);
+	}
+}
+
+static void __unregister_request(struct ceph_mds_client *mdsc,
+				 struct ceph_mds_request *req)
+{
+	dout("__unregister_request %p tid %lld\n", req, req->r_tid);
+	rb_erase(&req->r_node, &mdsc->request_tree);
+	RB_CLEAR_NODE(&req->r_node);
+
+	if (req->r_unsafe_dir) {
+		struct ceph_inode_info *ci = ceph_inode(req->r_unsafe_dir);
+
+		spin_lock(&ci->i_unsafe_lock);
+		list_del_init(&req->r_unsafe_dir_item);
+		spin_unlock(&ci->i_unsafe_lock);
+	}
+
+	ceph_mdsc_put_request(req);
+}
+
+/*
+ * Choose mds to send request to next.  If there is a hint set in the
+ * request (e.g., due to a prior forward hint from the mds), use that.
+ * Otherwise, consult frag tree and/or caps to identify the
+ * appropriate mds.  If all else fails, choose randomly.
+ *
+ * Called under mdsc->mutex.
+ */
+static int __choose_mds(struct ceph_mds_client *mdsc,
+			struct ceph_mds_request *req)
+{
+	struct inode *inode;
+	struct ceph_inode_info *ci;
+	struct ceph_cap *cap;
+	int mode = req->r_direct_mode;
+	int mds = -1;
+	u32 hash = req->r_direct_hash;
+	bool is_hash = req->r_direct_is_hash;
+
+	/*
+	 * is there a specific mds we should try?  ignore hint if we have
+	 * no session and the mds is not up (active or recovering).
+	 */
+	if (req->r_resend_mds >= 0 &&
+	    (__have_session(mdsc, req->r_resend_mds) ||
+	     ceph_mdsmap_get_state(mdsc->mdsmap, req->r_resend_mds) > 0)) {
+		dout("choose_mds using resend_mds mds%d\n",
+		     req->r_resend_mds);
+		return req->r_resend_mds;
+	}
+
+	if (mode == USE_RANDOM_MDS)
+		goto random;
+
+	inode = NULL;
+	if (req->r_inode) {
+		inode = req->r_inode;
+	} else if (req->r_dentry) {
+		if (req->r_dentry->d_inode) {
+			inode = req->r_dentry->d_inode;
+		} else {
+			inode = req->r_dentry->d_parent->d_inode;
+			hash = req->r_dentry->d_name.hash;
+			is_hash = true;
+		}
+	}
+	dout("__choose_mds %p is_hash=%d (%d) mode %d\n", inode, (int)is_hash,
+	     (int)hash, mode);
+	if (!inode)
+		goto random;
+	ci = ceph_inode(inode);
+
+	if (is_hash && S_ISDIR(inode->i_mode)) {
+		struct ceph_inode_frag frag;
+		int found;
+
+		ceph_choose_frag(ci, hash, &frag, &found);
+		if (found) {
+			if (mode == USE_ANY_MDS && frag.ndist > 0) {
+				u8 r;
+
+				/* choose a random replica */
+				get_random_bytes(&r, 1);
+				r %= frag.ndist;
+				mds = frag.dist[r];
+				dout("choose_mds %p %llx.%llx "
+				     "frag %u mds%d (%d/%d)\n",
+				     inode, ceph_vinop(inode),
+				     frag.frag, frag.mds,
+				     (int)r, frag.ndist);
+				return mds;
+			}
+
+			/* since this file/dir wasn't known to be
+			 * replicated, then we want to look for the
+			 * authoritative mds. */
+			mode = USE_AUTH_MDS;
+			if (frag.mds >= 0) {
+				/* choose auth mds */
+				mds = frag.mds;
+				dout("choose_mds %p %llx.%llx "
+				     "frag %u mds%d (auth)\n",
+				     inode, ceph_vinop(inode), frag.frag, mds);
+				return mds;
+			}
+		}
+	}
+
+	spin_lock(&inode->i_lock);
+	cap = NULL;
+	if (mode == USE_AUTH_MDS)
+		cap = ci->i_auth_cap;
+	if (!cap && !RB_EMPTY_ROOT(&ci->i_caps))
+		cap = rb_entry(rb_first(&ci->i_caps), struct ceph_cap, ci_node);
+	if (!cap) {
+		spin_unlock(&inode->i_lock);
+		goto random;
+	}
+	mds = cap->session->s_mds;
+	dout("choose_mds %p %llx.%llx mds%d (%scap %p)\n",
+	     inode, ceph_vinop(inode), mds,
+	     cap == ci->i_auth_cap ? "auth " : "", cap);
+	spin_unlock(&inode->i_lock);
+	return mds;
+
+random:
+	mds = ceph_mdsmap_get_random_mds(mdsc->mdsmap);
+	dout("choose_mds chose random mds%d\n", mds);
+	return mds;
+}
+
+
+/*
+ * session messages
+ */
+static struct ceph_msg *create_session_msg(u32 op, u64 seq)
+{
+	struct ceph_msg *msg;
+	struct ceph_mds_session_head *h;
+
+	msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h), 0, 0, NULL);
+	if (IS_ERR(msg)) {
+		pr_err("create_session_msg ENOMEM creating msg\n");
+		return ERR_PTR(PTR_ERR(msg));
+	}
+	h = msg->front.iov_base;
+	h->op = cpu_to_le32(op);
+	h->seq = cpu_to_le64(seq);
+	return msg;
+}
+
+/*
+ * send session open request.
+ *
+ * called under mdsc->mutex
+ */
+static int __open_session(struct ceph_mds_client *mdsc,
+			  struct ceph_mds_session *session)
+{
+	struct ceph_msg *msg;
+	int mstate;
+	int mds = session->s_mds;
+	int err = 0;
+
+	/* wait for mds to go active? */
+	mstate = ceph_mdsmap_get_state(mdsc->mdsmap, mds);
+	dout("open_session to mds%d (%s)\n", mds,
+	     ceph_mds_state_name(mstate));
+	session->s_state = CEPH_MDS_SESSION_OPENING;
+	session->s_renew_requested = jiffies;
+
+	/* send connect message */
+	msg = create_session_msg(CEPH_SESSION_REQUEST_OPEN, session->s_seq);
+	if (IS_ERR(msg)) {
+		err = PTR_ERR(msg);
+		goto out;
+	}
+	ceph_con_send(&session->s_con, msg);
+
+out:
+	return 0;
+}
+
+/*
+ * session caps
+ */
+
+/*
+ * Free preallocated cap messages assigned to this session
+ */
+static void cleanup_cap_releases(struct ceph_mds_session *session)
+{
+	struct ceph_msg *msg;
+
+	spin_lock(&session->s_cap_lock);
+	while (!list_empty(&session->s_cap_releases)) {
+		msg = list_first_entry(&session->s_cap_releases,
+				       struct ceph_msg, list_head);
+		list_del_init(&msg->list_head);
+		ceph_msg_put(msg);
+	}
+	while (!list_empty(&session->s_cap_releases_done)) {
+		msg = list_first_entry(&session->s_cap_releases_done,
+				       struct ceph_msg, list_head);
+		list_del_init(&msg->list_head);
+		ceph_msg_put(msg);
+	}
+	spin_unlock(&session->s_cap_lock);
+}
+
+/*
+ * Helper to safely iterate over all caps associated with a session, with
+ * special care taken to handle a racing __ceph_remove_cap().
+ *
+ * Caller must hold session s_mutex.
+ */
+static int iterate_session_caps(struct ceph_mds_session *session,
+				 int (*cb)(struct inode *, struct ceph_cap *,
+					    void *), void *arg)
+{
+	struct list_head *p;
+	struct ceph_cap *cap;
+	struct inode *inode, *last_inode = NULL;
+	struct ceph_cap *old_cap = NULL;
+	int ret;
+
+	dout("iterate_session_caps %p mds%d\n", session, session->s_mds);
+	spin_lock(&session->s_cap_lock);
+	p = session->s_caps.next;
+	while (p != &session->s_caps) {
+		cap = list_entry(p, struct ceph_cap, session_caps);
+		inode = igrab(&cap->ci->vfs_inode);
+		if (!inode) {
+			p = p->next;
+			continue;
+		}
+		session->s_cap_iterator = cap;
+		spin_unlock(&session->s_cap_lock);
+
+		if (last_inode) {
+			iput(last_inode);
+			last_inode = NULL;
+		}
+		if (old_cap) {
+			ceph_put_cap(old_cap);
+			old_cap = NULL;
+		}
+
+		ret = cb(inode, cap, arg);
+		last_inode = inode;
+
+		spin_lock(&session->s_cap_lock);
+		p = p->next;
+		if (cap->ci == NULL) {
+			dout("iterate_session_caps  finishing cap %p removal\n",
+			     cap);
+			BUG_ON(cap->session != session);
+			list_del_init(&cap->session_caps);
+			session->s_nr_caps--;
+			cap->session = NULL;
+			old_cap = cap;  /* put_cap it w/o locks held */
+		}
+		if (ret < 0)
+			goto out;
+	}
+	ret = 0;
+out:
+	session->s_cap_iterator = NULL;
+	spin_unlock(&session->s_cap_lock);
+
+	if (last_inode)
+		iput(last_inode);
+	if (old_cap)
+		ceph_put_cap(old_cap);
+
+	return ret;
+}
+
+static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
+				   void *arg)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	dout("removing cap %p, ci is %p, inode is %p\n",
+	     cap, ci, &ci->vfs_inode);
+	ceph_remove_cap(cap);
+	return 0;
+}
+
+/*
+ * caller must hold session s_mutex
+ */
+static void remove_session_caps(struct ceph_mds_session *session)
+{
+	dout("remove_session_caps on %p\n", session);
+	iterate_session_caps(session, remove_session_caps_cb, NULL);
+	BUG_ON(session->s_nr_caps > 0);
+	cleanup_cap_releases(session);
+}
+
+/*
+ * wake up any threads waiting on this session's caps.  if the cap is
+ * old (didn't get renewed on the client reconnect), remove it now.
+ *
+ * caller must hold s_mutex.
+ */
+static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap,
+			      void *arg)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+
+	wake_up(&ci->i_cap_wq);
+	if (arg) {
+		spin_lock(&inode->i_lock);
+		ci->i_wanted_max_size = 0;
+		ci->i_requested_max_size = 0;
+		spin_unlock(&inode->i_lock);
+	}
+	return 0;
+}
+
+static void wake_up_session_caps(struct ceph_mds_session *session,
+				 int reconnect)
+{
+	dout("wake_up_session_caps %p mds%d\n", session, session->s_mds);
+	iterate_session_caps(session, wake_up_session_cb,
+			     (void *)(unsigned long)reconnect);
+}
+
+/*
+ * Send periodic message to MDS renewing all currently held caps.  The
+ * ack will reset the expiration for all caps from this session.
+ *
+ * caller holds s_mutex
+ */
+static int send_renew_caps(struct ceph_mds_client *mdsc,
+			   struct ceph_mds_session *session)
+{
+	struct ceph_msg *msg;
+	int state;
+
+	if (time_after_eq(jiffies, session->s_cap_ttl) &&
+	    time_after_eq(session->s_cap_ttl, session->s_renew_requested))
+		pr_info("mds%d caps stale\n", session->s_mds);
+	session->s_renew_requested = jiffies;
+
+	/* do not try to renew caps until a recovering mds has reconnected
+	 * with its clients. */
+	state = ceph_mdsmap_get_state(mdsc->mdsmap, session->s_mds);
+	if (state < CEPH_MDS_STATE_RECONNECT) {
+		dout("send_renew_caps ignoring mds%d (%s)\n",
+		     session->s_mds, ceph_mds_state_name(state));
+		return 0;
+	}
+
+	dout("send_renew_caps to mds%d (%s)\n", session->s_mds,
+		ceph_mds_state_name(state));
+	msg = create_session_msg(CEPH_SESSION_REQUEST_RENEWCAPS,
+				 ++session->s_renew_seq);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
+	ceph_con_send(&session->s_con, msg);
+	return 0;
+}
+
+/*
+ * Note new cap ttl, and any transition from stale -> not stale (fresh?).
+ *
+ * Called under session->s_mutex
+ */
+static void renewed_caps(struct ceph_mds_client *mdsc,
+			 struct ceph_mds_session *session, int is_renew)
+{
+	int was_stale;
+	int wake = 0;
+
+	spin_lock(&session->s_cap_lock);
+	was_stale = is_renew && (session->s_cap_ttl == 0 ||
+				 time_after_eq(jiffies, session->s_cap_ttl));
+
+	session->s_cap_ttl = session->s_renew_requested +
+		mdsc->mdsmap->m_session_timeout*HZ;
+
+	if (was_stale) {
+		if (time_before(jiffies, session->s_cap_ttl)) {
+			pr_info("mds%d caps renewed\n", session->s_mds);
+			wake = 1;
+		} else {
+			pr_info("mds%d caps still stale\n", session->s_mds);
+		}
+	}
+	dout("renewed_caps mds%d ttl now %lu, was %s, now %s\n",
+	     session->s_mds, session->s_cap_ttl, was_stale ? "stale" : "fresh",
+	     time_before(jiffies, session->s_cap_ttl) ? "stale" : "fresh");
+	spin_unlock(&session->s_cap_lock);
+
+	if (wake)
+		wake_up_session_caps(session, 0);
+}
+
+/*
+ * send a session close request
+ */
+static int request_close_session(struct ceph_mds_client *mdsc,
+				 struct ceph_mds_session *session)
+{
+	struct ceph_msg *msg;
+	int err = 0;
+
+	dout("request_close_session mds%d state %s seq %lld\n",
+	     session->s_mds, session_state_name(session->s_state),
+	     session->s_seq);
+	msg = create_session_msg(CEPH_SESSION_REQUEST_CLOSE, session->s_seq);
+	if (IS_ERR(msg))
+		err = PTR_ERR(msg);
+	else
+		ceph_con_send(&session->s_con, msg);
+	return err;
+}
+
+/*
+ * Called with s_mutex held.
+ */
+static int __close_session(struct ceph_mds_client *mdsc,
+			 struct ceph_mds_session *session)
+{
+	if (session->s_state >= CEPH_MDS_SESSION_CLOSING)
+		return 0;
+	session->s_state = CEPH_MDS_SESSION_CLOSING;
+	return request_close_session(mdsc, session);
+}
+
+/*
+ * Trim old(er) caps.
+ *
+ * Because we can't cache an inode without one or more caps, we do
+ * this indirectly: if a cap is unused, we prune its aliases, at which
+ * point the inode will hopefully get dropped to.
+ *
+ * Yes, this is a bit sloppy.  Our only real goal here is to respond to
+ * memory pressure from the MDS, though, so it needn't be perfect.
+ */
+static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
+{
+	struct ceph_mds_session *session = arg;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int used, oissued, mine;
+
+	if (session->s_trim_caps <= 0)
+		return -1;
+
+	spin_lock(&inode->i_lock);
+	mine = cap->issued | cap->implemented;
+	used = __ceph_caps_used(ci);
+	oissued = __ceph_caps_issued_other(ci, cap);
+
+	dout("trim_caps_cb %p cap %p mine %s oissued %s used %s\n",
+	     inode, cap, ceph_cap_string(mine), ceph_cap_string(oissued),
+	     ceph_cap_string(used));
+	if (ci->i_dirty_caps)
+		goto out;   /* dirty caps */
+	if ((used & ~oissued) & mine)
+		goto out;   /* we need these caps */
+
+	session->s_trim_caps--;
+	if (oissued) {
+		/* we aren't the only cap.. just remove us */
+		__ceph_remove_cap(cap);
+	} else {
+		/* try to drop referring dentries */
+		spin_unlock(&inode->i_lock);
+		d_prune_aliases(inode);
+		dout("trim_caps_cb %p cap %p  pruned, count now %d\n",
+		     inode, cap, atomic_read(&inode->i_count));
+		return 0;
+	}
+
+out:
+	spin_unlock(&inode->i_lock);
+	return 0;
+}
+
+/*
+ * Trim session cap count down to some max number.
+ */
+static int trim_caps(struct ceph_mds_client *mdsc,
+		     struct ceph_mds_session *session,
+		     int max_caps)
+{
+	int trim_caps = session->s_nr_caps - max_caps;
+
+	dout("trim_caps mds%d start: %d / %d, trim %d\n",
+	     session->s_mds, session->s_nr_caps, max_caps, trim_caps);
+	if (trim_caps > 0) {
+		session->s_trim_caps = trim_caps;
+		iterate_session_caps(session, trim_caps_cb, session);
+		dout("trim_caps mds%d done: %d / %d, trimmed %d\n",
+		     session->s_mds, session->s_nr_caps, max_caps,
+			trim_caps - session->s_trim_caps);
+		session->s_trim_caps = 0;
+	}
+	return 0;
+}
+
+/*
+ * Allocate cap_release messages.  If there is a partially full message
+ * in the queue, try to allocate enough to cover it's remainder, so that
+ * we can send it immediately.
+ *
+ * Called under s_mutex.
+ */
+static int add_cap_releases(struct ceph_mds_client *mdsc,
+			    struct ceph_mds_session *session,
+			    int extra)
+{
+	struct ceph_msg *msg;
+	struct ceph_mds_cap_release *head;
+	int err = -ENOMEM;
+
+	if (extra < 0)
+		extra = mdsc->client->mount_args->cap_release_safety;
+
+	spin_lock(&session->s_cap_lock);
+
+	if (!list_empty(&session->s_cap_releases)) {
+		msg = list_first_entry(&session->s_cap_releases,
+				       struct ceph_msg,
+				 list_head);
+		head = msg->front.iov_base;
+		extra += CEPH_CAPS_PER_RELEASE - le32_to_cpu(head->num);
+	}
+
+	while (session->s_num_cap_releases < session->s_nr_caps + extra) {
+		spin_unlock(&session->s_cap_lock);
+		msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPRELEASE, PAGE_CACHE_SIZE,
+				   0, 0, NULL);
+		if (!msg)
+			goto out_unlocked;
+		dout("add_cap_releases %p msg %p now %d\n", session, msg,
+		     (int)msg->front.iov_len);
+		head = msg->front.iov_base;
+		head->num = cpu_to_le32(0);
+		msg->front.iov_len = sizeof(*head);
+		spin_lock(&session->s_cap_lock);
+		list_add(&msg->list_head, &session->s_cap_releases);
+		session->s_num_cap_releases += CEPH_CAPS_PER_RELEASE;
+	}
+
+	if (!list_empty(&session->s_cap_releases)) {
+		msg = list_first_entry(&session->s_cap_releases,
+				       struct ceph_msg,
+				       list_head);
+		head = msg->front.iov_base;
+		if (head->num) {
+			dout(" queueing non-full %p (%d)\n", msg,
+			     le32_to_cpu(head->num));
+			list_move_tail(&msg->list_head,
+				      &session->s_cap_releases_done);
+			session->s_num_cap_releases -=
+				CEPH_CAPS_PER_RELEASE - le32_to_cpu(head->num);
+		}
+	}
+	err = 0;
+	spin_unlock(&session->s_cap_lock);
+out_unlocked:
+	return err;
+}
+
+/*
+ * flush all dirty inode data to disk.
+ *
+ * returns true if we've flushed through want_flush_seq
+ */
+static int check_cap_flush(struct ceph_mds_client *mdsc, u64 want_flush_seq)
+{
+	int mds, ret = 1;
+
+	dout("check_cap_flush want %lld\n", want_flush_seq);
+	mutex_lock(&mdsc->mutex);
+	for (mds = 0; ret && mds < mdsc->max_sessions; mds++) {
+		struct ceph_mds_session *session = mdsc->sessions[mds];
+
+		if (!session)
+			continue;
+		get_session(session);
+		mutex_unlock(&mdsc->mutex);
+
+		mutex_lock(&session->s_mutex);
+		if (!list_empty(&session->s_cap_flushing)) {
+			struct ceph_inode_info *ci =
+				list_entry(session->s_cap_flushing.next,
+					   struct ceph_inode_info,
+					   i_flushing_item);
+			struct inode *inode = &ci->vfs_inode;
+
+			spin_lock(&inode->i_lock);
+			if (ci->i_cap_flush_seq <= want_flush_seq) {
+				dout("check_cap_flush still flushing %p "
+				     "seq %lld <= %lld to mds%d\n", inode,
+				     ci->i_cap_flush_seq, want_flush_seq,
+				     session->s_mds);
+				ret = 0;
+			}
+			spin_unlock(&inode->i_lock);
+		}
+		mutex_unlock(&session->s_mutex);
+		ceph_put_mds_session(session);
+
+		if (!ret)
+			return ret;
+		mutex_lock(&mdsc->mutex);
+	}
+
+	mutex_unlock(&mdsc->mutex);
+	dout("check_cap_flush ok, flushed thru %lld\n", want_flush_seq);
+	return ret;
+}
+
+/*
+ * called under s_mutex
+ */
+static void send_cap_releases(struct ceph_mds_client *mdsc,
+		       struct ceph_mds_session *session)
+{
+	struct ceph_msg *msg;
+
+	dout("send_cap_releases mds%d\n", session->s_mds);
+	while (1) {
+		spin_lock(&session->s_cap_lock);
+		if (list_empty(&session->s_cap_releases_done))
+			break;
+		msg = list_first_entry(&session->s_cap_releases_done,
+				 struct ceph_msg, list_head);
+		list_del_init(&msg->list_head);
+		spin_unlock(&session->s_cap_lock);
+		msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
+		dout("send_cap_releases mds%d %p\n", session->s_mds, msg);
+		ceph_con_send(&session->s_con, msg);
+	}
+	spin_unlock(&session->s_cap_lock);
+}
+
+/*
+ * requests
+ */
+
+/*
+ * Create an mds request.
+ */
+struct ceph_mds_request *
+ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
+{
+	struct ceph_mds_request *req = kzalloc(sizeof(*req), GFP_NOFS);
+
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	req->r_started = jiffies;
+	req->r_resend_mds = -1;
+	INIT_LIST_HEAD(&req->r_unsafe_dir_item);
+	req->r_fmode = -1;
+	kref_init(&req->r_kref);
+	INIT_LIST_HEAD(&req->r_wait);
+	init_completion(&req->r_completion);
+	init_completion(&req->r_safe_completion);
+	INIT_LIST_HEAD(&req->r_unsafe_item);
+
+	req->r_op = op;
+	req->r_direct_mode = mode;
+	return req;
+}
+
+/*
+ * return oldest (lowest) request, tid in request tree, 0 if none.
+ *
+ * called under mdsc->mutex.
+ */
+static struct ceph_mds_request *__get_oldest_req(struct ceph_mds_client *mdsc)
+{
+	if (RB_EMPTY_ROOT(&mdsc->request_tree))
+		return NULL;
+	return rb_entry(rb_first(&mdsc->request_tree),
+			struct ceph_mds_request, r_node);
+}
+
+static u64 __get_oldest_tid(struct ceph_mds_client *mdsc)
+{
+	struct ceph_mds_request *req = __get_oldest_req(mdsc);
+
+	if (req)
+		return req->r_tid;
+	return 0;
+}
+
+/*
+ * Build a dentry's path.  Allocate on heap; caller must kfree.  Based
+ * on build_path_from_dentry in fs/cifs/dir.c.
+ *
+ * If @stop_on_nosnap, generate path relative to the first non-snapped
+ * inode.
+ *
+ * Encode hidden .snap dirs as a double /, i.e.
+ *   foo/.snap/bar -> foo//bar
+ */
+char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base,
+			   int stop_on_nosnap)
+{
+	struct dentry *temp;
+	char *path;
+	int len, pos;
+
+	if (dentry == NULL)
+		return ERR_PTR(-EINVAL);
+
+retry:
+	len = 0;
+	for (temp = dentry; !IS_ROOT(temp);) {
+		struct inode *inode = temp->d_inode;
+		if (inode && ceph_snap(inode) == CEPH_SNAPDIR)
+			len++;  /* slash only */
+		else if (stop_on_nosnap && inode &&
+			 ceph_snap(inode) == CEPH_NOSNAP)
+			break;
+		else
+			len += 1 + temp->d_name.len;
+		temp = temp->d_parent;
+		if (temp == NULL) {
+			pr_err("build_path_dentry corrupt dentry %p\n", dentry);
+			return ERR_PTR(-EINVAL);
+		}
+	}
+	if (len)
+		len--;  /* no leading '/' */
+
+	path = kmalloc(len+1, GFP_NOFS);
+	if (path == NULL)
+		return ERR_PTR(-ENOMEM);
+	pos = len;
+	path[pos] = 0;	/* trailing null */
+	for (temp = dentry; !IS_ROOT(temp) && pos != 0; ) {
+		struct inode *inode = temp->d_inode;
+
+		if (inode && ceph_snap(inode) == CEPH_SNAPDIR) {
+			dout("build_path_dentry path+%d: %p SNAPDIR\n",
+			     pos, temp);
+		} else if (stop_on_nosnap && inode &&
+			   ceph_snap(inode) == CEPH_NOSNAP) {
+			break;
+		} else {
+			pos -= temp->d_name.len;
+			if (pos < 0)
+				break;
+			strncpy(path + pos, temp->d_name.name,
+				temp->d_name.len);
+			dout("build_path_dentry path+%d: %p '%.*s'\n",
+			     pos, temp, temp->d_name.len, path + pos);
+		}
+		if (pos)
+			path[--pos] = '/';
+		temp = temp->d_parent;
+		if (temp == NULL) {
+			pr_err("build_path_dentry corrupt dentry\n");
+			kfree(path);
+			return ERR_PTR(-EINVAL);
+		}
+	}
+	if (pos != 0) {
+		pr_err("build_path_dentry did not end path lookup where "
+		       "expected, namelen is %d, pos is %d\n", len, pos);
+		/* presumably this is only possible if racing with a
+		   rename of one of the parent directories (we can not
+		   lock the dentries above us to prevent this, but
+		   retrying should be harmless) */
+		kfree(path);
+		goto retry;
+	}
+
+	*base = ceph_ino(temp->d_inode);
+	*plen = len;
+	dout("build_path_dentry on %p %d built %llx '%.*s'\n",
+	     dentry, atomic_read(&dentry->d_count), *base, len, path);
+	return path;
+}
+
+static int build_dentry_path(struct dentry *dentry,
+			     const char **ppath, int *ppathlen, u64 *pino,
+			     int *pfreepath)
+{
+	char *path;
+
+	if (ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP) {
+		*pino = ceph_ino(dentry->d_parent->d_inode);
+		*ppath = dentry->d_name.name;
+		*ppathlen = dentry->d_name.len;
+		return 0;
+	}
+	path = ceph_mdsc_build_path(dentry, ppathlen, pino, 1);
+	if (IS_ERR(path))
+		return PTR_ERR(path);
+	*ppath = path;
+	*pfreepath = 1;
+	return 0;
+}
+
+static int build_inode_path(struct inode *inode,
+			    const char **ppath, int *ppathlen, u64 *pino,
+			    int *pfreepath)
+{
+	struct dentry *dentry;
+	char *path;
+
+	if (ceph_snap(inode) == CEPH_NOSNAP) {
+		*pino = ceph_ino(inode);
+		*ppathlen = 0;
+		return 0;
+	}
+	dentry = d_find_alias(inode);
+	path = ceph_mdsc_build_path(dentry, ppathlen, pino, 1);
+	dput(dentry);
+	if (IS_ERR(path))
+		return PTR_ERR(path);
+	*ppath = path;
+	*pfreepath = 1;
+	return 0;
+}
+
+/*
+ * request arguments may be specified via an inode *, a dentry *, or
+ * an explicit ino+path.
+ */
+static int set_request_path_attr(struct inode *rinode, struct dentry *rdentry,
+				  const char *rpath, u64 rino,
+				  const char **ppath, int *pathlen,
+				  u64 *ino, int *freepath)
+{
+	int r = 0;
+
+	if (rinode) {
+		r = build_inode_path(rinode, ppath, pathlen, ino, freepath);
+		dout(" inode %p %llx.%llx\n", rinode, ceph_ino(rinode),
+		     ceph_snap(rinode));
+	} else if (rdentry) {
+		r = build_dentry_path(rdentry, ppath, pathlen, ino, freepath);
+		dout(" dentry %p %llx/%.*s\n", rdentry, *ino, *pathlen,
+		     *ppath);
+	} else if (rpath) {
+		*ino = rino;
+		*ppath = rpath;
+		*pathlen = strlen(rpath);
+		dout(" path %.*s\n", *pathlen, rpath);
+	}
+
+	return r;
+}
+
+/*
+ * called under mdsc->mutex
+ */
+static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
+					       struct ceph_mds_request *req,
+					       int mds)
+{
+	struct ceph_msg *msg;
+	struct ceph_mds_request_head *head;
+	const char *path1 = NULL;
+	const char *path2 = NULL;
+	u64 ino1 = 0, ino2 = 0;
+	int pathlen1 = 0, pathlen2 = 0;
+	int freepath1 = 0, freepath2 = 0;
+	int len;
+	u16 releases;
+	void *p, *end;
+	int ret;
+
+	ret = set_request_path_attr(req->r_inode, req->r_dentry,
+			      req->r_path1, req->r_ino1.ino,
+			      &path1, &pathlen1, &ino1, &freepath1);
+	if (ret < 0) {
+		msg = ERR_PTR(ret);
+		goto out;
+	}
+
+	ret = set_request_path_attr(NULL, req->r_old_dentry,
+			      req->r_path2, req->r_ino2.ino,
+			      &path2, &pathlen2, &ino2, &freepath2);
+	if (ret < 0) {
+		msg = ERR_PTR(ret);
+		goto out_free1;
+	}
+
+	len = sizeof(*head) +
+		pathlen1 + pathlen2 + 2*(1 + sizeof(u32) + sizeof(u64));
+
+	/* calculate (max) length for cap releases */
+	len += sizeof(struct ceph_mds_request_release) *
+		(!!req->r_inode_drop + !!req->r_dentry_drop +
+		 !!req->r_old_inode_drop + !!req->r_old_dentry_drop);
+	if (req->r_dentry_drop)
+		len += req->r_dentry->d_name.len;
+	if (req->r_old_dentry_drop)
+		len += req->r_old_dentry->d_name.len;
+
+	msg = ceph_msg_new(CEPH_MSG_CLIENT_REQUEST, len, 0, 0, NULL);
+	if (IS_ERR(msg))
+		goto out_free2;
+
+	msg->hdr.tid = cpu_to_le64(req->r_tid);
+
+	head = msg->front.iov_base;
+	p = msg->front.iov_base + sizeof(*head);
+	end = msg->front.iov_base + msg->front.iov_len;
+
+	head->mdsmap_epoch = cpu_to_le32(mdsc->mdsmap->m_epoch);
+	head->op = cpu_to_le32(req->r_op);
+	head->caller_uid = cpu_to_le32(current_fsuid());
+	head->caller_gid = cpu_to_le32(current_fsgid());
+	head->args = req->r_args;
+
+	ceph_encode_filepath(&p, end, ino1, path1);
+	ceph_encode_filepath(&p, end, ino2, path2);
+
+	/* cap releases */
+	releases = 0;
+	if (req->r_inode_drop)
+		releases += ceph_encode_inode_release(&p,
+		      req->r_inode ? req->r_inode : req->r_dentry->d_inode,
+		      mds, req->r_inode_drop, req->r_inode_unless, 0);
+	if (req->r_dentry_drop)
+		releases += ceph_encode_dentry_release(&p, req->r_dentry,
+		       mds, req->r_dentry_drop, req->r_dentry_unless);
+	if (req->r_old_dentry_drop)
+		releases += ceph_encode_dentry_release(&p, req->r_old_dentry,
+		       mds, req->r_old_dentry_drop, req->r_old_dentry_unless);
+	if (req->r_old_inode_drop)
+		releases += ceph_encode_inode_release(&p,
+		      req->r_old_dentry->d_inode,
+		      mds, req->r_old_inode_drop, req->r_old_inode_unless, 0);
+	head->num_releases = cpu_to_le16(releases);
+
+	BUG_ON(p > end);
+	msg->front.iov_len = p - msg->front.iov_base;
+	msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
+
+	msg->pages = req->r_pages;
+	msg->nr_pages = req->r_num_pages;
+	msg->hdr.data_len = cpu_to_le32(req->r_data_len);
+	msg->hdr.data_off = cpu_to_le16(0);
+
+out_free2:
+	if (freepath2)
+		kfree((char *)path2);
+out_free1:
+	if (freepath1)
+		kfree((char *)path1);
+out:
+	return msg;
+}
+
+/*
+ * called under mdsc->mutex if error, under no mutex if
+ * success.
+ */
+static void complete_request(struct ceph_mds_client *mdsc,
+			     struct ceph_mds_request *req)
+{
+	if (req->r_callback)
+		req->r_callback(mdsc, req);
+	else
+		complete(&req->r_completion);
+}
+
+/*
+ * called under mdsc->mutex
+ */
+static int __prepare_send_request(struct ceph_mds_client *mdsc,
+				  struct ceph_mds_request *req,
+				  int mds)
+{
+	struct ceph_mds_request_head *rhead;
+	struct ceph_msg *msg;
+	int flags = 0;
+
+	req->r_mds = mds;
+	req->r_attempts++;
+	dout("prepare_send_request %p tid %lld %s (attempt %d)\n", req,
+	     req->r_tid, ceph_mds_op_name(req->r_op), req->r_attempts);
+
+	if (req->r_request) {
+		ceph_msg_put(req->r_request);
+		req->r_request = NULL;
+	}
+	msg = create_request_message(mdsc, req, mds);
+	if (IS_ERR(msg)) {
+		req->r_reply = ERR_PTR(PTR_ERR(msg));
+		complete_request(mdsc, req);
+		return -PTR_ERR(msg);
+	}
+	req->r_request = msg;
+
+	rhead = msg->front.iov_base;
+	rhead->oldest_client_tid = cpu_to_le64(__get_oldest_tid(mdsc));
+	if (req->r_got_unsafe)
+		flags |= CEPH_MDS_FLAG_REPLAY;
+	if (req->r_locked_dir)
+		flags |= CEPH_MDS_FLAG_WANT_DENTRY;
+	rhead->flags = cpu_to_le32(flags);
+	rhead->num_fwd = req->r_num_fwd;
+	rhead->num_retry = req->r_attempts - 1;
+
+	dout(" r_locked_dir = %p\n", req->r_locked_dir);
+
+	if (req->r_target_inode && req->r_got_unsafe)
+		rhead->ino = cpu_to_le64(ceph_ino(req->r_target_inode));
+	else
+		rhead->ino = 0;
+	return 0;
+}
+
+/*
+ * send request, or put it on the appropriate wait list.
+ */
+static int __do_request(struct ceph_mds_client *mdsc,
+			struct ceph_mds_request *req)
+{
+	struct ceph_mds_session *session = NULL;
+	int mds = -1;
+	int err = -EAGAIN;
+
+	if (req->r_reply)
+		goto out;
+
+	if (req->r_timeout &&
+	    time_after_eq(jiffies, req->r_started + req->r_timeout)) {
+		dout("do_request timed out\n");
+		err = -EIO;
+		goto finish;
+	}
+
+	mds = __choose_mds(mdsc, req);
+	if (mds < 0 ||
+	    ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) {
+		dout("do_request no mds or not active, waiting for map\n");
+		list_add(&req->r_wait, &mdsc->waiting_for_map);
+		goto out;
+	}
+
+	/* get, open session */
+	session = __ceph_lookup_mds_session(mdsc, mds);
+	if (!session) {
+		session = register_session(mdsc, mds);
+		if (IS_ERR(session)) {
+			err = PTR_ERR(session);
+			goto finish;
+		}
+	}
+	dout("do_request mds%d session %p state %s\n", mds, session,
+	     session_state_name(session->s_state));
+	if (session->s_state != CEPH_MDS_SESSION_OPEN &&
+	    session->s_state != CEPH_MDS_SESSION_HUNG) {
+		if (session->s_state == CEPH_MDS_SESSION_NEW ||
+		    session->s_state == CEPH_MDS_SESSION_CLOSING)
+			__open_session(mdsc, session);
+		list_add(&req->r_wait, &session->s_waiting);
+		goto out_session;
+	}
+
+	/* send request */
+	req->r_session = get_session(session);
+	req->r_resend_mds = -1;   /* forget any previous mds hint */
+
+	if (req->r_request_started == 0)   /* note request start time */
+		req->r_request_started = jiffies;
+
+	err = __prepare_send_request(mdsc, req, mds);
+	if (!err) {
+		ceph_msg_get(req->r_request);
+		ceph_con_send(&session->s_con, req->r_request);
+	}
+
+out_session:
+	ceph_put_mds_session(session);
+out:
+	return err;
+
+finish:
+	req->r_reply = ERR_PTR(err);
+	complete_request(mdsc, req);
+	goto out;
+}
+
+/*
+ * called under mdsc->mutex
+ */
+static void __wake_requests(struct ceph_mds_client *mdsc,
+			    struct list_head *head)
+{
+	struct ceph_mds_request *req, *nreq;
+
+	list_for_each_entry_safe(req, nreq, head, r_wait) {
+		list_del_init(&req->r_wait);
+		__do_request(mdsc, req);
+	}
+}
+
+/*
+ * Wake up threads with requests pending for @mds, so that they can
+ * resubmit their requests to a possibly different mds.  If @all is set,
+ * wake up if their requests has been forwarded to @mds, too.
+ */
+static void kick_requests(struct ceph_mds_client *mdsc, int mds, int all)
+{
+	struct ceph_mds_request *req;
+	struct rb_node *p;
+
+	dout("kick_requests mds%d\n", mds);
+	for (p = rb_first(&mdsc->request_tree); p; p = rb_next(p)) {
+		req = rb_entry(p, struct ceph_mds_request, r_node);
+		if (req->r_got_unsafe)
+			continue;
+		if (req->r_session &&
+		    req->r_session->s_mds == mds) {
+			dout(" kicking tid %llu\n", req->r_tid);
+			put_request_session(req);
+			__do_request(mdsc, req);
+		}
+	}
+}
+
+void ceph_mdsc_submit_request(struct ceph_mds_client *mdsc,
+			      struct ceph_mds_request *req)
+{
+	dout("submit_request on %p\n", req);
+	mutex_lock(&mdsc->mutex);
+	__register_request(mdsc, req, NULL);
+	__do_request(mdsc, req);
+	mutex_unlock(&mdsc->mutex);
+}
+
+/*
+ * Synchrously perform an mds request.  Take care of all of the
+ * session setup, forwarding, retry details.
+ */
+int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
+			 struct inode *dir,
+			 struct ceph_mds_request *req)
+{
+	int err;
+
+	dout("do_request on %p\n", req);
+
+	/* take CAP_PIN refs for r_inode, r_locked_dir, r_old_dentry */
+	if (req->r_inode)
+		ceph_get_cap_refs(ceph_inode(req->r_inode), CEPH_CAP_PIN);
+	if (req->r_locked_dir)
+		ceph_get_cap_refs(ceph_inode(req->r_locked_dir), CEPH_CAP_PIN);
+	if (req->r_old_dentry)
+		ceph_get_cap_refs(
+			ceph_inode(req->r_old_dentry->d_parent->d_inode),
+			CEPH_CAP_PIN);
+
+	/* issue */
+	mutex_lock(&mdsc->mutex);
+	__register_request(mdsc, req, dir);
+	__do_request(mdsc, req);
+
+	/* wait */
+	if (!req->r_reply) {
+		mutex_unlock(&mdsc->mutex);
+		if (req->r_timeout) {
+			err = (long)wait_for_completion_interruptible_timeout(
+				&req->r_completion, req->r_timeout);
+			if (err == 0)
+				req->r_reply = ERR_PTR(-EIO);
+			else if (err < 0)
+				req->r_reply = ERR_PTR(err);
+		} else {
+                        err = wait_for_completion_interruptible(
+                                &req->r_completion);
+                        if (err)
+                                req->r_reply = ERR_PTR(err);
+		}
+		mutex_lock(&mdsc->mutex);
+	}
+
+	if (IS_ERR(req->r_reply)) {
+		err = PTR_ERR(req->r_reply);
+		req->r_reply = NULL;
+
+		if (err == -ERESTARTSYS) {
+			/* aborted */
+			req->r_aborted = true;
+
+			if (req->r_locked_dir &&
+			    (req->r_op & CEPH_MDS_OP_WRITE)) {
+				struct ceph_inode_info *ci =
+					ceph_inode(req->r_locked_dir);
+
+				dout("aborted, clearing I_COMPLETE on %p\n", 
+				     req->r_locked_dir);
+				spin_lock(&req->r_locked_dir->i_lock);
+				ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
+				ci->i_release_count++;
+				spin_unlock(&req->r_locked_dir->i_lock);
+			}
+		} else {
+			/* clean up this request */
+			__unregister_request(mdsc, req);
+			if (!list_empty(&req->r_unsafe_item))
+				list_del_init(&req->r_unsafe_item);
+			complete(&req->r_safe_completion);
+		}
+	} else if (req->r_err) {
+		err = req->r_err;
+	} else {
+		err = le32_to_cpu(req->r_reply_info.head->result);
+	}
+	mutex_unlock(&mdsc->mutex);
+
+	dout("do_request %p done, result %d\n", req, err);
+	return err;
+}
+
+/*
+ * Handle mds reply.
+ *
+ * We take the session mutex and parse and process the reply immediately.
+ * This preserves the logical ordering of replies, capabilities, etc., sent
+ * by the MDS as they are applied to our local cache.
+ */
+static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
+{
+	struct ceph_mds_client *mdsc = session->s_mdsc;
+	struct ceph_mds_request *req;
+	struct ceph_mds_reply_head *head = msg->front.iov_base;
+	struct ceph_mds_reply_info_parsed *rinfo;  /* parsed reply info */
+	u64 tid;
+	int err, result;
+	int mds = session->s_mds;
+
+	if (msg->front.iov_len < sizeof(*head)) {
+		pr_err("mdsc_handle_reply got corrupt (short) reply\n");
+		ceph_msg_dump(msg);
+		return;
+	}
+
+	/* get request, session */
+	tid = le64_to_cpu(msg->hdr.tid);
+	mutex_lock(&mdsc->mutex);
+	req = __lookup_request(mdsc, tid);
+	if (!req) {
+		dout("handle_reply on unknown tid %llu\n", tid);
+		mutex_unlock(&mdsc->mutex);
+		return;
+	}
+	dout("handle_reply %p\n", req);
+
+	/* correct session? */
+	if (req->r_session != session) {
+		pr_err("mdsc_handle_reply got %llu on session mds%d"
+		       " not mds%d\n", tid, session->s_mds,
+		       req->r_session ? req->r_session->s_mds : -1);
+		mutex_unlock(&mdsc->mutex);
+		goto out;
+	}
+
+	/* dup? */
+	if ((req->r_got_unsafe && !head->safe) ||
+	    (req->r_got_safe && head->safe)) {
+		pr_warning("got a dup %s reply on %llu from mds%d\n",
+			   head->safe ? "safe" : "unsafe", tid, mds);
+		mutex_unlock(&mdsc->mutex);
+		goto out;
+	}
+
+	result = le32_to_cpu(head->result);
+
+	/*
+	 * Tolerate 2 consecutive ESTALEs from the same mds.
+	 * FIXME: we should be looking at the cap migrate_seq.
+	 */
+	if (result == -ESTALE) {
+		req->r_direct_mode = USE_AUTH_MDS;
+		req->r_num_stale++;
+		if (req->r_num_stale <= 2) {
+			__do_request(mdsc, req);
+			mutex_unlock(&mdsc->mutex);
+			goto out;
+		}
+	} else {
+		req->r_num_stale = 0;
+	}
+
+	if (head->safe) {
+		req->r_got_safe = true;
+		__unregister_request(mdsc, req);
+		complete(&req->r_safe_completion);
+
+		if (req->r_got_unsafe) {
+			/*
+			 * We already handled the unsafe response, now do the
+			 * cleanup.  No need to examine the response; the MDS
+			 * doesn't include any result info in the safe
+			 * response.  And even if it did, there is nothing
+			 * useful we could do with a revised return value.
+			 */
+			dout("got safe reply %llu, mds%d\n", tid, mds);
+			list_del_init(&req->r_unsafe_item);
+
+			/* last unsafe request during umount? */
+			if (mdsc->stopping && !__get_oldest_req(mdsc))
+				complete(&mdsc->safe_umount_waiters);
+			mutex_unlock(&mdsc->mutex);
+			goto out;
+		}
+	}
+
+	BUG_ON(req->r_reply);
+
+	if (!head->safe) {
+		req->r_got_unsafe = true;
+		list_add_tail(&req->r_unsafe_item, &req->r_session->s_unsafe);
+	}
+
+	dout("handle_reply tid %lld result %d\n", tid, result);
+	rinfo = &req->r_reply_info;
+	err = parse_reply_info(msg, rinfo);
+	mutex_unlock(&mdsc->mutex);
+
+	mutex_lock(&session->s_mutex);
+	if (err < 0) {
+		pr_err("mdsc_handle_reply got corrupt reply mds%d\n", mds);
+		ceph_msg_dump(msg);
+		goto out_err;
+	}
+
+	/* snap trace */
+	if (rinfo->snapblob_len) {
+		down_write(&mdsc->snap_rwsem);
+		ceph_update_snap_trace(mdsc, rinfo->snapblob,
+			       rinfo->snapblob + rinfo->snapblob_len,
+			       le32_to_cpu(head->op) == CEPH_MDS_OP_RMSNAP);
+		downgrade_write(&mdsc->snap_rwsem);
+	} else {
+		down_read(&mdsc->snap_rwsem);
+	}
+
+	/* insert trace into our cache */
+	err = ceph_fill_trace(mdsc->client->sb, req, req->r_session);
+	if (err == 0) {
+		if (result == 0 && rinfo->dir_nr)
+			ceph_readdir_prepopulate(req, req->r_session);
+		ceph_unreserve_caps(&req->r_caps_reservation);
+	}
+
+	up_read(&mdsc->snap_rwsem);
+out_err:
+	if (err) {
+		req->r_err = err;
+	} else {
+		req->r_reply = msg;
+		ceph_msg_get(msg);
+	}
+
+	add_cap_releases(mdsc, req->r_session, -1);
+	mutex_unlock(&session->s_mutex);
+
+	/* kick calling process */
+	complete_request(mdsc, req);
+out:
+	ceph_mdsc_put_request(req);
+	return;
+}
+
+
+
+/*
+ * handle mds notification that our request has been forwarded.
+ */
+static void handle_forward(struct ceph_mds_client *mdsc,
+			   struct ceph_mds_session *session,
+			   struct ceph_msg *msg)
+{
+	struct ceph_mds_request *req;
+	u64 tid = le64_to_cpu(msg->hdr.tid);
+	u32 next_mds;
+	u32 fwd_seq;
+	int err = -EINVAL;
+	void *p = msg->front.iov_base;
+	void *end = p + msg->front.iov_len;
+
+	ceph_decode_need(&p, end, 2*sizeof(u32), bad);
+	next_mds = ceph_decode_32(&p);
+	fwd_seq = ceph_decode_32(&p);
+
+	mutex_lock(&mdsc->mutex);
+	req = __lookup_request(mdsc, tid);
+	if (!req) {
+		dout("forward %llu to mds%d - req dne\n", tid, next_mds);
+		goto out;  /* dup reply? */
+	}
+
+	if (fwd_seq <= req->r_num_fwd) {
+		dout("forward %llu to mds%d - old seq %d <= %d\n",
+		     tid, next_mds, req->r_num_fwd, fwd_seq);
+	} else {
+		/* resend. forward race not possible; mds would drop */
+		dout("forward %llu to mds%d (we resend)\n", tid, next_mds);
+		req->r_num_fwd = fwd_seq;
+		req->r_resend_mds = next_mds;
+		put_request_session(req);
+		__do_request(mdsc, req);
+	}
+	ceph_mdsc_put_request(req);
+out:
+	mutex_unlock(&mdsc->mutex);
+	return;
+
+bad:
+	pr_err("mdsc_handle_forward decode error err=%d\n", err);
+}
+
+/*
+ * handle a mds session control message
+ */
+static void handle_session(struct ceph_mds_session *session,
+			   struct ceph_msg *msg)
+{
+	struct ceph_mds_client *mdsc = session->s_mdsc;
+	u32 op;
+	u64 seq;
+	int mds = session->s_mds;
+	struct ceph_mds_session_head *h = msg->front.iov_base;
+	int wake = 0;
+
+	/* decode */
+	if (msg->front.iov_len != sizeof(*h))
+		goto bad;
+	op = le32_to_cpu(h->op);
+	seq = le64_to_cpu(h->seq);
+
+	mutex_lock(&mdsc->mutex);
+	if (op == CEPH_SESSION_CLOSE)
+		__unregister_session(mdsc, session);
+	/* FIXME: this ttl calculation is generous */
+	session->s_ttl = jiffies + HZ*mdsc->mdsmap->m_session_autoclose;
+	mutex_unlock(&mdsc->mutex);
+
+	mutex_lock(&session->s_mutex);
+
+	dout("handle_session mds%d %s %p state %s seq %llu\n",
+	     mds, ceph_session_op_name(op), session,
+	     session_state_name(session->s_state), seq);
+
+	if (session->s_state == CEPH_MDS_SESSION_HUNG) {
+		session->s_state = CEPH_MDS_SESSION_OPEN;
+		pr_info("mds%d came back\n", session->s_mds);
+	}
+
+	switch (op) {
+	case CEPH_SESSION_OPEN:
+		session->s_state = CEPH_MDS_SESSION_OPEN;
+		renewed_caps(mdsc, session, 0);
+		wake = 1;
+		if (mdsc->stopping)
+			__close_session(mdsc, session);
+		break;
+
+	case CEPH_SESSION_RENEWCAPS:
+		if (session->s_renew_seq == seq)
+			renewed_caps(mdsc, session, 1);
+		break;
+
+	case CEPH_SESSION_CLOSE:
+		remove_session_caps(session);
+		wake = 1; /* for good measure */
+		complete(&mdsc->session_close_waiters);
+		kick_requests(mdsc, mds, 0);      /* cur only */
+		break;
+
+	case CEPH_SESSION_STALE:
+		pr_info("mds%d caps went stale, renewing\n",
+			session->s_mds);
+		spin_lock(&session->s_cap_lock);
+		session->s_cap_gen++;
+		session->s_cap_ttl = 0;
+		spin_unlock(&session->s_cap_lock);
+		send_renew_caps(mdsc, session);
+		break;
+
+	case CEPH_SESSION_RECALL_STATE:
+		trim_caps(mdsc, session, le32_to_cpu(h->max_caps));
+		break;
+
+	default:
+		pr_err("mdsc_handle_session bad op %d mds%d\n", op, mds);
+		WARN_ON(1);
+	}
+
+	mutex_unlock(&session->s_mutex);
+	if (wake) {
+		mutex_lock(&mdsc->mutex);
+		__wake_requests(mdsc, &session->s_waiting);
+		mutex_unlock(&mdsc->mutex);
+	}
+	return;
+
+bad:
+	pr_err("mdsc_handle_session corrupt message mds%d len %d\n", mds,
+	       (int)msg->front.iov_len);
+	ceph_msg_dump(msg);
+	return;
+}
+
+
+/*
+ * called under session->mutex.
+ */
+static void replay_unsafe_requests(struct ceph_mds_client *mdsc,
+				   struct ceph_mds_session *session)
+{
+	struct ceph_mds_request *req, *nreq;
+	int err;
+
+	dout("replay_unsafe_requests mds%d\n", session->s_mds);
+
+	mutex_lock(&mdsc->mutex);
+	list_for_each_entry_safe(req, nreq, &session->s_unsafe, r_unsafe_item) {
+		err = __prepare_send_request(mdsc, req, session->s_mds);
+		if (!err) {
+			ceph_msg_get(req->r_request);
+			ceph_con_send(&session->s_con, req->r_request);
+		}
+	}
+	mutex_unlock(&mdsc->mutex);
+}
+
+/*
+ * Encode information about a cap for a reconnect with the MDS.
+ */
+static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
+			  void *arg)
+{
+	struct ceph_mds_cap_reconnect rec;
+	struct ceph_inode_info *ci;
+	struct ceph_pagelist *pagelist = arg;
+	char *path;
+	int pathlen, err;
+	u64 pathbase;
+	struct dentry *dentry;
+
+	ci = cap->ci;
+
+	dout(" adding %p ino %llx.%llx cap %p %lld %s\n",
+	     inode, ceph_vinop(inode), cap, cap->cap_id,
+	     ceph_cap_string(cap->issued));
+	err = ceph_pagelist_encode_64(pagelist, ceph_ino(inode));
+	if (err)
+		return err;
+
+	dentry = d_find_alias(inode);
+	if (dentry) {
+		path = ceph_mdsc_build_path(dentry, &pathlen, &pathbase, 0);
+		if (IS_ERR(path)) {
+			err = PTR_ERR(path);
+			BUG_ON(err);
+		}
+	} else {
+		path = NULL;
+		pathlen = 0;
+	}
+	err = ceph_pagelist_encode_string(pagelist, path, pathlen);
+	if (err)
+		goto out;
+
+	spin_lock(&inode->i_lock);
+	cap->seq = 0;        /* reset cap seq */
+	cap->issue_seq = 0;  /* and issue_seq */
+	rec.cap_id = cpu_to_le64(cap->cap_id);
+	rec.pathbase = cpu_to_le64(pathbase);
+	rec.wanted = cpu_to_le32(__ceph_caps_wanted(ci));
+	rec.issued = cpu_to_le32(cap->issued);
+	rec.size = cpu_to_le64(inode->i_size);
+	ceph_encode_timespec(&rec.mtime, &inode->i_mtime);
+	ceph_encode_timespec(&rec.atime, &inode->i_atime);
+	rec.snaprealm = cpu_to_le64(ci->i_snap_realm->ino);
+	spin_unlock(&inode->i_lock);
+
+	err = ceph_pagelist_append(pagelist, &rec, sizeof(rec));
+
+out:
+	kfree(path);
+	dput(dentry);
+	return err;
+}
+
+
+/*
+ * If an MDS fails and recovers, clients need to reconnect in order to
+ * reestablish shared state.  This includes all caps issued through
+ * this session _and_ the snap_realm hierarchy.  Because it's not
+ * clear which snap realms the mds cares about, we send everything we
+ * know about.. that ensures we'll then get any new info the
+ * recovering MDS might have.
+ *
+ * This is a relatively heavyweight operation, but it's rare.
+ *
+ * called with mdsc->mutex held.
+ */
+static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds)
+{
+	struct ceph_mds_session *session = NULL;
+	struct ceph_msg *reply;
+	struct rb_node *p;
+	int err = -ENOMEM;
+	struct ceph_pagelist *pagelist;
+
+	pr_info("reconnect to recovering mds%d\n", mds);
+
+	pagelist = kmalloc(sizeof(*pagelist), GFP_NOFS);
+	if (!pagelist)
+		goto fail_nopagelist;
+	ceph_pagelist_init(pagelist);
+
+	reply = ceph_msg_new(CEPH_MSG_CLIENT_RECONNECT, 0, 0, 0, NULL);
+	if (IS_ERR(reply)) {
+		err = PTR_ERR(reply);
+		goto fail_nomsg;
+	}
+
+	/* find session */
+	session = __ceph_lookup_mds_session(mdsc, mds);
+	mutex_unlock(&mdsc->mutex);    /* drop lock for duration */
+
+	if (session) {
+		mutex_lock(&session->s_mutex);
+
+		session->s_state = CEPH_MDS_SESSION_RECONNECTING;
+		session->s_seq = 0;
+
+		ceph_con_open(&session->s_con,
+			      ceph_mdsmap_get_addr(mdsc->mdsmap, mds));
+
+		/* replay unsafe requests */
+		replay_unsafe_requests(mdsc, session);
+	} else {
+		dout("no session for mds%d, will send short reconnect\n",
+		     mds);
+	}
+
+	down_read(&mdsc->snap_rwsem);
+
+	if (!session)
+		goto send;
+	dout("session %p state %s\n", session,
+	     session_state_name(session->s_state));
+
+	/* traverse this session's caps */
+	err = ceph_pagelist_encode_32(pagelist, session->s_nr_caps);
+	if (err)
+		goto fail;
+	err = iterate_session_caps(session, encode_caps_cb, pagelist);
+	if (err < 0)
+		goto fail;
+
+	/*
+	 * snaprealms.  we provide mds with the ino, seq (version), and
+	 * parent for all of our realms.  If the mds has any newer info,
+	 * it will tell us.
+	 */
+	for (p = rb_first(&mdsc->snap_realms); p; p = rb_next(p)) {
+		struct ceph_snap_realm *realm =
+			rb_entry(p, struct ceph_snap_realm, node);
+		struct ceph_mds_snaprealm_reconnect sr_rec;
+
+		dout(" adding snap realm %llx seq %lld parent %llx\n",
+		     realm->ino, realm->seq, realm->parent_ino);
+		sr_rec.ino = cpu_to_le64(realm->ino);
+		sr_rec.seq = cpu_to_le64(realm->seq);
+		sr_rec.parent = cpu_to_le64(realm->parent_ino);
+		err = ceph_pagelist_append(pagelist, &sr_rec, sizeof(sr_rec));
+		if (err)
+			goto fail;
+	}
+
+send:
+	reply->pagelist = pagelist;
+	reply->hdr.data_len = cpu_to_le32(pagelist->length);
+	reply->nr_pages = calc_pages_for(0, pagelist->length);
+	ceph_con_send(&session->s_con, reply);
+
+	session->s_state = CEPH_MDS_SESSION_OPEN;
+	mutex_unlock(&session->s_mutex);
+
+	mutex_lock(&mdsc->mutex);
+	__wake_requests(mdsc, &session->s_waiting);
+	mutex_unlock(&mdsc->mutex);
+
+	ceph_put_mds_session(session);
+
+	up_read(&mdsc->snap_rwsem);
+	mutex_lock(&mdsc->mutex);
+	return;
+
+fail:
+	ceph_msg_put(reply);
+	up_read(&mdsc->snap_rwsem);
+	mutex_unlock(&session->s_mutex);
+	ceph_put_mds_session(session);
+fail_nomsg:
+	ceph_pagelist_release(pagelist);
+	kfree(pagelist);
+fail_nopagelist:
+	pr_err("error %d preparing reconnect for mds%d\n", err, mds);
+	mutex_lock(&mdsc->mutex);
+	return;
+}
+
+
+/*
+ * compare old and new mdsmaps, kicking requests
+ * and closing out old connections as necessary
+ *
+ * called under mdsc->mutex.
+ */
+static void check_new_map(struct ceph_mds_client *mdsc,
+			  struct ceph_mdsmap *newmap,
+			  struct ceph_mdsmap *oldmap)
+{
+	int i;
+	int oldstate, newstate;
+	struct ceph_mds_session *s;
+
+	dout("check_new_map new %u old %u\n",
+	     newmap->m_epoch, oldmap->m_epoch);
+
+	for (i = 0; i < oldmap->m_max_mds && i < mdsc->max_sessions; i++) {
+		if (mdsc->sessions[i] == NULL)
+			continue;
+		s = mdsc->sessions[i];
+		oldstate = ceph_mdsmap_get_state(oldmap, i);
+		newstate = ceph_mdsmap_get_state(newmap, i);
+
+		dout("check_new_map mds%d state %s -> %s (session %s)\n",
+		     i, ceph_mds_state_name(oldstate),
+		     ceph_mds_state_name(newstate),
+		     session_state_name(s->s_state));
+
+		if (memcmp(ceph_mdsmap_get_addr(oldmap, i),
+			   ceph_mdsmap_get_addr(newmap, i),
+			   sizeof(struct ceph_entity_addr))) {
+			if (s->s_state == CEPH_MDS_SESSION_OPENING) {
+				/* the session never opened, just close it
+				 * out now */
+				__wake_requests(mdsc, &s->s_waiting);
+				__unregister_session(mdsc, s);
+			} else {
+				/* just close it */
+				mutex_unlock(&mdsc->mutex);
+				mutex_lock(&s->s_mutex);
+				mutex_lock(&mdsc->mutex);
+				ceph_con_close(&s->s_con);
+				mutex_unlock(&s->s_mutex);
+				s->s_state = CEPH_MDS_SESSION_RESTARTING;
+			}
+
+			/* kick any requests waiting on the recovering mds */
+			kick_requests(mdsc, i, 1);
+		} else if (oldstate == newstate) {
+			continue;  /* nothing new with this mds */
+		}
+
+		/*
+		 * send reconnect?
+		 */
+		if (s->s_state == CEPH_MDS_SESSION_RESTARTING &&
+		    newstate >= CEPH_MDS_STATE_RECONNECT)
+			send_mds_reconnect(mdsc, i);
+
+		/*
+		 * kick requests on any mds that has gone active.
+		 *
+		 * kick requests on cur or forwarder: we may have sent
+		 * the request to mds1, mds1 told us it forwarded it
+		 * to mds2, but then we learn mds1 failed and can't be
+		 * sure it successfully forwarded our request before
+		 * it died.
+		 */
+		if (oldstate < CEPH_MDS_STATE_ACTIVE &&
+		    newstate >= CEPH_MDS_STATE_ACTIVE) {
+			pr_info("mds%d reconnect completed\n", s->s_mds);
+			kick_requests(mdsc, i, 1);
+			ceph_kick_flushing_caps(mdsc, s);
+			wake_up_session_caps(s, 1);
+		}
+	}
+}
+
+
+
+/*
+ * leases
+ */
+
+/*
+ * caller must hold session s_mutex, dentry->d_lock
+ */
+void __ceph_mdsc_drop_dentry_lease(struct dentry *dentry)
+{
+	struct ceph_dentry_info *di = ceph_dentry(dentry);
+
+	ceph_put_mds_session(di->lease_session);
+	di->lease_session = NULL;
+}
+
+static void handle_lease(struct ceph_mds_client *mdsc,
+			 struct ceph_mds_session *session,
+			 struct ceph_msg *msg)
+{
+	struct super_block *sb = mdsc->client->sb;
+	struct inode *inode;
+	struct ceph_inode_info *ci;
+	struct dentry *parent, *dentry;
+	struct ceph_dentry_info *di;
+	int mds = session->s_mds;
+	struct ceph_mds_lease *h = msg->front.iov_base;
+	struct ceph_vino vino;
+	int mask;
+	struct qstr dname;
+	int release = 0;
+
+	dout("handle_lease from mds%d\n", mds);
+
+	/* decode */
+	if (msg->front.iov_len < sizeof(*h) + sizeof(u32))
+		goto bad;
+	vino.ino = le64_to_cpu(h->ino);
+	vino.snap = CEPH_NOSNAP;
+	mask = le16_to_cpu(h->mask);
+	dname.name = (void *)h + sizeof(*h) + sizeof(u32);
+	dname.len = msg->front.iov_len - sizeof(*h) - sizeof(u32);
+	if (dname.len != get_unaligned_le32(h+1))
+		goto bad;
+
+	mutex_lock(&session->s_mutex);
+	session->s_seq++;
+
+	/* lookup inode */
+	inode = ceph_find_inode(sb, vino);
+	dout("handle_lease '%s', mask %d, ino %llx %p\n",
+	     ceph_lease_op_name(h->action), mask, vino.ino, inode);
+	if (inode == NULL) {
+		dout("handle_lease no inode %llx\n", vino.ino);
+		goto release;
+	}
+	ci = ceph_inode(inode);
+
+	/* dentry */
+	parent = d_find_alias(inode);
+	if (!parent) {
+		dout("no parent dentry on inode %p\n", inode);
+		WARN_ON(1);
+		goto release;  /* hrm... */
+	}
+	dname.hash = full_name_hash(dname.name, dname.len);
+	dentry = d_lookup(parent, &dname);
+	dput(parent);
+	if (!dentry)
+		goto release;
+
+	spin_lock(&dentry->d_lock);
+	di = ceph_dentry(dentry);
+	switch (h->action) {
+	case CEPH_MDS_LEASE_REVOKE:
+		if (di && di->lease_session == session) {
+			h->seq = cpu_to_le32(di->lease_seq);
+			__ceph_mdsc_drop_dentry_lease(dentry);
+		}
+		release = 1;
+		break;
+
+	case CEPH_MDS_LEASE_RENEW:
+		if (di && di->lease_session == session &&
+		    di->lease_gen == session->s_cap_gen &&
+		    di->lease_renew_from &&
+		    di->lease_renew_after == 0) {
+			unsigned long duration =
+				le32_to_cpu(h->duration_ms) * HZ / 1000;
+
+			di->lease_seq = le32_to_cpu(h->seq);
+			dentry->d_time = di->lease_renew_from + duration;
+			di->lease_renew_after = di->lease_renew_from +
+				(duration >> 1);
+			di->lease_renew_from = 0;
+		}
+		break;
+	}
+	spin_unlock(&dentry->d_lock);
+	dput(dentry);
+
+	if (!release)
+		goto out;
+
+release:
+	/* let's just reuse the same message */
+	h->action = CEPH_MDS_LEASE_REVOKE_ACK;
+	ceph_msg_get(msg);
+	ceph_con_send(&session->s_con, msg);
+
+out:
+	iput(inode);
+	mutex_unlock(&session->s_mutex);
+	return;
+
+bad:
+	pr_err("corrupt lease message\n");
+	ceph_msg_dump(msg);
+}
+
+void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session,
+			      struct inode *inode,
+			      struct dentry *dentry, char action,
+			      u32 seq)
+{
+	struct ceph_msg *msg;
+	struct ceph_mds_lease *lease;
+	int len = sizeof(*lease) + sizeof(u32);
+	int dnamelen = 0;
+
+	dout("lease_send_msg inode %p dentry %p %s to mds%d\n",
+	     inode, dentry, ceph_lease_op_name(action), session->s_mds);
+	dnamelen = dentry->d_name.len;
+	len += dnamelen;
+
+	msg = ceph_msg_new(CEPH_MSG_CLIENT_LEASE, len, 0, 0, NULL);
+	if (IS_ERR(msg))
+		return;
+	lease = msg->front.iov_base;
+	lease->action = action;
+	lease->mask = cpu_to_le16(CEPH_LOCK_DN);
+	lease->ino = cpu_to_le64(ceph_vino(inode).ino);
+	lease->first = lease->last = cpu_to_le64(ceph_vino(inode).snap);
+	lease->seq = cpu_to_le32(seq);
+	put_unaligned_le32(dnamelen, lease + 1);
+	memcpy((void *)(lease + 1) + 4, dentry->d_name.name, dnamelen);
+
+	/*
+	 * if this is a preemptive lease RELEASE, no need to
+	 * flush request stream, since the actual request will
+	 * soon follow.
+	 */
+	msg->more_to_follow = (action == CEPH_MDS_LEASE_RELEASE);
+
+	ceph_con_send(&session->s_con, msg);
+}
+
+/*
+ * Preemptively release a lease we expect to invalidate anyway.
+ * Pass @inode always, @dentry is optional.
+ */
+void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc, struct inode *inode,
+			     struct dentry *dentry, int mask)
+{
+	struct ceph_dentry_info *di;
+	struct ceph_mds_session *session;
+	u32 seq;
+
+	BUG_ON(inode == NULL);
+	BUG_ON(dentry == NULL);
+	BUG_ON(mask != CEPH_LOCK_DN);
+
+	/* is dentry lease valid? */
+	spin_lock(&dentry->d_lock);
+	di = ceph_dentry(dentry);
+	if (!di || !di->lease_session ||
+	    di->lease_session->s_mds < 0 ||
+	    di->lease_gen != di->lease_session->s_cap_gen ||
+	    !time_before(jiffies, dentry->d_time)) {
+		dout("lease_release inode %p dentry %p -- "
+		     "no lease on %d\n",
+		     inode, dentry, mask);
+		spin_unlock(&dentry->d_lock);
+		return;
+	}
+
+	/* we do have a lease on this dentry; note mds and seq */
+	session = ceph_get_mds_session(di->lease_session);
+	seq = di->lease_seq;
+	__ceph_mdsc_drop_dentry_lease(dentry);
+	spin_unlock(&dentry->d_lock);
+
+	dout("lease_release inode %p dentry %p mask %d to mds%d\n",
+	     inode, dentry, mask, session->s_mds);
+	ceph_mdsc_lease_send_msg(session, inode, dentry,
+				 CEPH_MDS_LEASE_RELEASE, seq);
+	ceph_put_mds_session(session);
+}
+
+/*
+ * drop all leases (and dentry refs) in preparation for umount
+ */
+static void drop_leases(struct ceph_mds_client *mdsc)
+{
+	int i;
+
+	dout("drop_leases\n");
+	mutex_lock(&mdsc->mutex);
+	for (i = 0; i < mdsc->max_sessions; i++) {
+		struct ceph_mds_session *s = __ceph_lookup_mds_session(mdsc, i);
+		if (!s)
+			continue;
+		mutex_unlock(&mdsc->mutex);
+		mutex_lock(&s->s_mutex);
+		mutex_unlock(&s->s_mutex);
+		ceph_put_mds_session(s);
+		mutex_lock(&mdsc->mutex);
+	}
+	mutex_unlock(&mdsc->mutex);
+}
+
+
+
+/*
+ * delayed work -- periodically trim expired leases, renew caps with mds
+ */
+static void schedule_delayed(struct ceph_mds_client *mdsc)
+{
+	int delay = 5;
+	unsigned hz = round_jiffies_relative(HZ * delay);
+	schedule_delayed_work(&mdsc->delayed_work, hz);
+}
+
+static void delayed_work(struct work_struct *work)
+{
+	int i;
+	struct ceph_mds_client *mdsc =
+		container_of(work, struct ceph_mds_client, delayed_work.work);
+	int renew_interval;
+	int renew_caps;
+
+	dout("mdsc delayed_work\n");
+	ceph_check_delayed_caps(mdsc);
+
+	mutex_lock(&mdsc->mutex);
+	renew_interval = mdsc->mdsmap->m_session_timeout >> 2;
+	renew_caps = time_after_eq(jiffies, HZ*renew_interval +
+				   mdsc->last_renew_caps);
+	if (renew_caps)
+		mdsc->last_renew_caps = jiffies;
+
+	for (i = 0; i < mdsc->max_sessions; i++) {
+		struct ceph_mds_session *s = __ceph_lookup_mds_session(mdsc, i);
+		if (s == NULL)
+			continue;
+		if (s->s_state == CEPH_MDS_SESSION_CLOSING) {
+			dout("resending session close request for mds%d\n",
+			     s->s_mds);
+			request_close_session(mdsc, s);
+			ceph_put_mds_session(s);
+			continue;
+		}
+		if (s->s_ttl && time_after(jiffies, s->s_ttl)) {
+			if (s->s_state == CEPH_MDS_SESSION_OPEN) {
+				s->s_state = CEPH_MDS_SESSION_HUNG;
+				pr_info("mds%d hung\n", s->s_mds);
+			}
+		}
+		if (s->s_state < CEPH_MDS_SESSION_OPEN) {
+			/* this mds is failed or recovering, just wait */
+			ceph_put_mds_session(s);
+			continue;
+		}
+		mutex_unlock(&mdsc->mutex);
+
+		mutex_lock(&s->s_mutex);
+		if (renew_caps)
+			send_renew_caps(mdsc, s);
+		else
+			ceph_con_keepalive(&s->s_con);
+		add_cap_releases(mdsc, s, -1);
+		send_cap_releases(mdsc, s);
+		mutex_unlock(&s->s_mutex);
+		ceph_put_mds_session(s);
+
+		mutex_lock(&mdsc->mutex);
+	}
+	mutex_unlock(&mdsc->mutex);
+
+	schedule_delayed(mdsc);
+}
+
+
+int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client)
+{
+	mdsc->client = client;
+	mutex_init(&mdsc->mutex);
+	mdsc->mdsmap = kzalloc(sizeof(*mdsc->mdsmap), GFP_NOFS);
+	init_completion(&mdsc->safe_umount_waiters);
+	init_completion(&mdsc->session_close_waiters);
+	INIT_LIST_HEAD(&mdsc->waiting_for_map);
+	mdsc->sessions = NULL;
+	mdsc->max_sessions = 0;
+	mdsc->stopping = 0;
+	init_rwsem(&mdsc->snap_rwsem);
+	mdsc->snap_realms = RB_ROOT;
+	INIT_LIST_HEAD(&mdsc->snap_empty);
+	spin_lock_init(&mdsc->snap_empty_lock);
+	mdsc->last_tid = 0;
+	mdsc->request_tree = RB_ROOT;
+	INIT_DELAYED_WORK(&mdsc->delayed_work, delayed_work);
+	mdsc->last_renew_caps = jiffies;
+	INIT_LIST_HEAD(&mdsc->cap_delay_list);
+	spin_lock_init(&mdsc->cap_delay_lock);
+	INIT_LIST_HEAD(&mdsc->snap_flush_list);
+	spin_lock_init(&mdsc->snap_flush_lock);
+	mdsc->cap_flush_seq = 0;
+	INIT_LIST_HEAD(&mdsc->cap_dirty);
+	mdsc->num_cap_flushing = 0;
+	spin_lock_init(&mdsc->cap_dirty_lock);
+	init_waitqueue_head(&mdsc->cap_flushing_wq);
+	spin_lock_init(&mdsc->dentry_lru_lock);
+	INIT_LIST_HEAD(&mdsc->dentry_lru);
+	return 0;
+}
+
+/*
+ * Wait for safe replies on open mds requests.  If we time out, drop
+ * all requests from the tree to avoid dangling dentry refs.
+ */
+static void wait_requests(struct ceph_mds_client *mdsc)
+{
+	struct ceph_mds_request *req;
+	struct ceph_client *client = mdsc->client;
+
+	mutex_lock(&mdsc->mutex);
+	if (__get_oldest_req(mdsc)) {
+		mutex_unlock(&mdsc->mutex);
+
+		dout("wait_requests waiting for requests\n");
+		wait_for_completion_timeout(&mdsc->safe_umount_waiters,
+				    client->mount_args->mount_timeout * HZ);
+
+		/* tear down remaining requests */
+		mutex_lock(&mdsc->mutex);
+		while ((req = __get_oldest_req(mdsc))) {
+			dout("wait_requests timed out on tid %llu\n",
+			     req->r_tid);
+			__unregister_request(mdsc, req);
+		}
+	}
+	mutex_unlock(&mdsc->mutex);
+	dout("wait_requests done\n");
+}
+
+/*
+ * called before mount is ro, and before dentries are torn down.
+ * (hmm, does this still race with new lookups?)
+ */
+void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc)
+{
+	dout("pre_umount\n");
+	mdsc->stopping = 1;
+
+	drop_leases(mdsc);
+	ceph_flush_dirty_caps(mdsc);
+	wait_requests(mdsc);
+}
+
+/*
+ * wait for all write mds requests to flush.
+ */
+static void wait_unsafe_requests(struct ceph_mds_client *mdsc, u64 want_tid)
+{
+	struct ceph_mds_request *req = NULL, *nextreq;
+	struct rb_node *n;
+
+	mutex_lock(&mdsc->mutex);
+	dout("wait_unsafe_requests want %lld\n", want_tid);
+restart:
+	req = __get_oldest_req(mdsc);
+	while (req && req->r_tid <= want_tid) {
+		/* find next request */
+		n = rb_next(&req->r_node);
+		if (n)
+			nextreq = rb_entry(n, struct ceph_mds_request, r_node);
+		else
+			nextreq = NULL;
+		if ((req->r_op & CEPH_MDS_OP_WRITE)) {
+			/* write op */
+			ceph_mdsc_get_request(req);
+			if (nextreq)
+				ceph_mdsc_get_request(nextreq);
+			mutex_unlock(&mdsc->mutex);
+			dout("wait_unsafe_requests  wait on %llu (want %llu)\n",
+			     req->r_tid, want_tid);
+			wait_for_completion(&req->r_safe_completion);
+			mutex_lock(&mdsc->mutex);
+			ceph_mdsc_put_request(req);
+			if (!nextreq)
+				break;  /* next dne before, so we're done! */
+			if (RB_EMPTY_NODE(&nextreq->r_node)) {
+				/* next request was removed from tree */
+				ceph_mdsc_put_request(nextreq);
+				goto restart;
+			}
+			ceph_mdsc_put_request(nextreq);  /* won't go away */
+		}
+		req = nextreq;
+	}
+	mutex_unlock(&mdsc->mutex);
+	dout("wait_unsafe_requests done\n");
+}
+
+void ceph_mdsc_sync(struct ceph_mds_client *mdsc)
+{
+	u64 want_tid, want_flush;
+
+	dout("sync\n");
+	mutex_lock(&mdsc->mutex);
+	want_tid = mdsc->last_tid;
+	want_flush = mdsc->cap_flush_seq;
+	mutex_unlock(&mdsc->mutex);
+	dout("sync want tid %lld flush_seq %lld\n", want_tid, want_flush);
+
+	ceph_flush_dirty_caps(mdsc);
+
+	wait_unsafe_requests(mdsc, want_tid);
+	wait_event(mdsc->cap_flushing_wq, check_cap_flush(mdsc, want_flush));
+}
+
+
+/*
+ * called after sb is ro.
+ */
+void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc)
+{
+	struct ceph_mds_session *session;
+	int i;
+	int n;
+	struct ceph_client *client = mdsc->client;
+	unsigned long started, timeout = client->mount_args->mount_timeout * HZ;
+
+	dout("close_sessions\n");
+
+	mutex_lock(&mdsc->mutex);
+
+	/* close sessions */
+	started = jiffies;
+	while (time_before(jiffies, started + timeout)) {
+		dout("closing sessions\n");
+		n = 0;
+		for (i = 0; i < mdsc->max_sessions; i++) {
+			session = __ceph_lookup_mds_session(mdsc, i);
+			if (!session)
+				continue;
+			mutex_unlock(&mdsc->mutex);
+			mutex_lock(&session->s_mutex);
+			__close_session(mdsc, session);
+			mutex_unlock(&session->s_mutex);
+			ceph_put_mds_session(session);
+			mutex_lock(&mdsc->mutex);
+			n++;
+		}
+		if (n == 0)
+			break;
+
+		if (client->mount_state == CEPH_MOUNT_SHUTDOWN)
+			break;
+
+		dout("waiting for sessions to close\n");
+		mutex_unlock(&mdsc->mutex);
+		wait_for_completion_timeout(&mdsc->session_close_waiters,
+					    timeout);
+		mutex_lock(&mdsc->mutex);
+	}
+
+	/* tear down remaining sessions */
+	for (i = 0; i < mdsc->max_sessions; i++) {
+		if (mdsc->sessions[i]) {
+			session = get_session(mdsc->sessions[i]);
+			__unregister_session(mdsc, session);
+			mutex_unlock(&mdsc->mutex);
+			mutex_lock(&session->s_mutex);
+			remove_session_caps(session);
+			mutex_unlock(&session->s_mutex);
+			ceph_put_mds_session(session);
+			mutex_lock(&mdsc->mutex);
+		}
+	}
+
+	WARN_ON(!list_empty(&mdsc->cap_delay_list));
+
+	mutex_unlock(&mdsc->mutex);
+
+	ceph_cleanup_empty_realms(mdsc);
+
+	cancel_delayed_work_sync(&mdsc->delayed_work); /* cancel timer */
+
+	dout("stopped\n");
+}
+
+void ceph_mdsc_stop(struct ceph_mds_client *mdsc)
+{
+	dout("stop\n");
+	cancel_delayed_work_sync(&mdsc->delayed_work); /* cancel timer */
+	if (mdsc->mdsmap)
+		ceph_mdsmap_destroy(mdsc->mdsmap);
+	kfree(mdsc->sessions);
+}
+
+
+/*
+ * handle mds map update.
+ */
+void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
+{
+	u32 epoch;
+	u32 maplen;
+	void *p = msg->front.iov_base;
+	void *end = p + msg->front.iov_len;
+	struct ceph_mdsmap *newmap, *oldmap;
+	struct ceph_fsid fsid;
+	int err = -EINVAL;
+
+	ceph_decode_need(&p, end, sizeof(fsid)+2*sizeof(u32), bad);
+	ceph_decode_copy(&p, &fsid, sizeof(fsid));
+	if (ceph_check_fsid(mdsc->client, &fsid) < 0)
+		return;
+	epoch = ceph_decode_32(&p);
+	maplen = ceph_decode_32(&p);
+	dout("handle_map epoch %u len %d\n", epoch, (int)maplen);
+
+	/* do we need it? */
+	ceph_monc_got_mdsmap(&mdsc->client->monc, epoch);
+	mutex_lock(&mdsc->mutex);
+	if (mdsc->mdsmap && epoch <= mdsc->mdsmap->m_epoch) {
+		dout("handle_map epoch %u <= our %u\n",
+		     epoch, mdsc->mdsmap->m_epoch);
+		mutex_unlock(&mdsc->mutex);
+		return;
+	}
+
+	newmap = ceph_mdsmap_decode(&p, end);
+	if (IS_ERR(newmap)) {
+		err = PTR_ERR(newmap);
+		goto bad_unlock;
+	}
+
+	/* swap into place */
+	if (mdsc->mdsmap) {
+		oldmap = mdsc->mdsmap;
+		mdsc->mdsmap = newmap;
+		check_new_map(mdsc, newmap, oldmap);
+		ceph_mdsmap_destroy(oldmap);
+	} else {
+		mdsc->mdsmap = newmap;  /* first mds map */
+	}
+	mdsc->client->sb->s_maxbytes = mdsc->mdsmap->m_max_file_size;
+
+	__wake_requests(mdsc, &mdsc->waiting_for_map);
+
+	mutex_unlock(&mdsc->mutex);
+	schedule_delayed(mdsc);
+	return;
+
+bad_unlock:
+	mutex_unlock(&mdsc->mutex);
+bad:
+	pr_err("error decoding mdsmap %d\n", err);
+	return;
+}
+
+static struct ceph_connection *con_get(struct ceph_connection *con)
+{
+	struct ceph_mds_session *s = con->private;
+
+	if (get_session(s)) {
+		dout("mdsc con_get %p ok (%d)\n", s, atomic_read(&s->s_ref));
+		return con;
+	}
+	dout("mdsc con_get %p FAIL\n", s);
+	return NULL;
+}
+
+static void con_put(struct ceph_connection *con)
+{
+	struct ceph_mds_session *s = con->private;
+
+	ceph_put_mds_session(s);
+	dout("mdsc con_put %p (%d)\n", s, atomic_read(&s->s_ref));
+}
+
+/*
+ * if the client is unresponsive for long enough, the mds will kill
+ * the session entirely.
+ */
+static void peer_reset(struct ceph_connection *con)
+{
+	struct ceph_mds_session *s = con->private;
+
+	pr_err("mds%d gave us the boot.  IMPLEMENT RECONNECT.\n",
+	       s->s_mds);
+}
+
+static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
+{
+	struct ceph_mds_session *s = con->private;
+	struct ceph_mds_client *mdsc = s->s_mdsc;
+	int type = le16_to_cpu(msg->hdr.type);
+
+	mutex_lock(&mdsc->mutex);
+	if (__verify_registered_session(mdsc, s) < 0) {
+		mutex_unlock(&mdsc->mutex);
+		goto out;
+	}
+	mutex_unlock(&mdsc->mutex);
+
+	switch (type) {
+	case CEPH_MSG_MDS_MAP:
+		ceph_mdsc_handle_map(mdsc, msg);
+		break;
+	case CEPH_MSG_CLIENT_SESSION:
+		handle_session(s, msg);
+		break;
+	case CEPH_MSG_CLIENT_REPLY:
+		handle_reply(s, msg);
+		break;
+	case CEPH_MSG_CLIENT_REQUEST_FORWARD:
+		handle_forward(mdsc, s, msg);
+		break;
+	case CEPH_MSG_CLIENT_CAPS:
+		ceph_handle_caps(s, msg);
+		break;
+	case CEPH_MSG_CLIENT_SNAP:
+		ceph_handle_snap(mdsc, s, msg);
+		break;
+	case CEPH_MSG_CLIENT_LEASE:
+		handle_lease(mdsc, s, msg);
+		break;
+
+	default:
+		pr_err("received unknown message type %d %s\n", type,
+		       ceph_msg_type_name(type));
+	}
+out:
+	ceph_msg_put(msg);
+}
+
+/*
+ * authentication
+ */
+static int get_authorizer(struct ceph_connection *con,
+			  void **buf, int *len, int *proto,
+			  void **reply_buf, int *reply_len, int force_new)
+{
+	struct ceph_mds_session *s = con->private;
+	struct ceph_mds_client *mdsc = s->s_mdsc;
+	struct ceph_auth_client *ac = mdsc->client->monc.auth;
+	int ret = 0;
+
+	if (force_new && s->s_authorizer) {
+		ac->ops->destroy_authorizer(ac, s->s_authorizer);
+		s->s_authorizer = NULL;
+	}
+	if (s->s_authorizer == NULL) {
+		if (ac->ops->create_authorizer) {
+			ret = ac->ops->create_authorizer(
+				ac, CEPH_ENTITY_TYPE_MDS,
+				&s->s_authorizer,
+				&s->s_authorizer_buf,
+				&s->s_authorizer_buf_len,
+				&s->s_authorizer_reply_buf,
+				&s->s_authorizer_reply_buf_len);
+			if (ret)
+				return ret;
+		}
+	}
+
+	*proto = ac->protocol;
+	*buf = s->s_authorizer_buf;
+	*len = s->s_authorizer_buf_len;
+	*reply_buf = s->s_authorizer_reply_buf;
+	*reply_len = s->s_authorizer_reply_buf_len;
+	return 0;
+}
+
+
+static int verify_authorizer_reply(struct ceph_connection *con, int len)
+{
+	struct ceph_mds_session *s = con->private;
+	struct ceph_mds_client *mdsc = s->s_mdsc;
+	struct ceph_auth_client *ac = mdsc->client->monc.auth;
+
+	return ac->ops->verify_authorizer_reply(ac, s->s_authorizer, len);
+}
+
+static int invalidate_authorizer(struct ceph_connection *con)
+{
+	struct ceph_mds_session *s = con->private;
+	struct ceph_mds_client *mdsc = s->s_mdsc;
+	struct ceph_auth_client *ac = mdsc->client->monc.auth;
+
+	if (ac->ops->invalidate_authorizer)
+		ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_MDS);
+
+	return ceph_monc_validate_auth(&mdsc->client->monc);
+}
+
+const static struct ceph_connection_operations mds_con_ops = {
+	.get = con_get,
+	.put = con_put,
+	.dispatch = dispatch,
+	.get_authorizer = get_authorizer,
+	.verify_authorizer_reply = verify_authorizer_reply,
+	.invalidate_authorizer = invalidate_authorizer,
+	.peer_reset = peer_reset,
+};
+
+
+
+
+/* eof */
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/mds_client.h linux-libre-2.6.34-gnu1/fs/ceph/mds_client.h
--- linux-libre-2.6.33-gnu1/fs/ceph/mds_client.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/mds_client.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,335 @@
+#ifndef _FS_CEPH_MDS_CLIENT_H
+#define _FS_CEPH_MDS_CLIENT_H
+
+#include <linux/completion.h>
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/rbtree.h>
+#include <linux/spinlock.h>
+
+#include "types.h"
+#include "messenger.h"
+#include "mdsmap.h"
+
+/*
+ * Some lock dependencies:
+ *
+ * session->s_mutex
+ *         mdsc->mutex
+ *
+ *         mdsc->snap_rwsem
+ *
+ *         inode->i_lock
+ *                 mdsc->snap_flush_lock
+ *                 mdsc->cap_delay_lock
+ *
+ */
+
+struct ceph_client;
+struct ceph_cap;
+
+/*
+ * parsed info about a single inode.  pointers are into the encoded
+ * on-wire structures within the mds reply message payload.
+ */
+struct ceph_mds_reply_info_in {
+	struct ceph_mds_reply_inode *in;
+	u32 symlink_len;
+	char *symlink;
+	u32 xattr_len;
+	char *xattr_data;
+};
+
+/*
+ * parsed info about an mds reply, including information about the
+ * target inode and/or its parent directory and dentry, and directory
+ * contents (for readdir results).
+ */
+struct ceph_mds_reply_info_parsed {
+	struct ceph_mds_reply_head    *head;
+
+	struct ceph_mds_reply_info_in diri, targeti;
+	struct ceph_mds_reply_dirfrag *dirfrag;
+	char                          *dname;
+	u32                           dname_len;
+	struct ceph_mds_reply_lease   *dlease;
+
+	struct ceph_mds_reply_dirfrag *dir_dir;
+	int                           dir_nr;
+	char                          **dir_dname;
+	u32                           *dir_dname_len;
+	struct ceph_mds_reply_lease   **dir_dlease;
+	struct ceph_mds_reply_info_in *dir_in;
+	u8                            dir_complete, dir_end;
+
+	/* encoded blob describing snapshot contexts for certain
+	   operations (e.g., open) */
+	void *snapblob;
+	int snapblob_len;
+};
+
+
+/*
+ * cap releases are batched and sent to the MDS en masse.
+ */
+#define CEPH_CAPS_PER_RELEASE ((PAGE_CACHE_SIZE -			\
+				sizeof(struct ceph_mds_cap_release)) /	\
+			       sizeof(struct ceph_mds_cap_item))
+
+
+/*
+ * state associated with each MDS<->client session
+ */
+enum {
+	CEPH_MDS_SESSION_NEW = 1,
+	CEPH_MDS_SESSION_OPENING = 2,
+	CEPH_MDS_SESSION_OPEN = 3,
+	CEPH_MDS_SESSION_HUNG = 4,
+	CEPH_MDS_SESSION_CLOSING = 5,
+	CEPH_MDS_SESSION_RESTARTING = 6,
+	CEPH_MDS_SESSION_RECONNECTING = 7,
+};
+
+struct ceph_mds_session {
+	struct ceph_mds_client *s_mdsc;
+	int               s_mds;
+	int               s_state;
+	unsigned long     s_ttl;      /* time until mds kills us */
+	u64               s_seq;      /* incoming msg seq # */
+	struct mutex      s_mutex;    /* serialize session messages */
+
+	struct ceph_connection s_con;
+
+	struct ceph_authorizer *s_authorizer;
+	void             *s_authorizer_buf, *s_authorizer_reply_buf;
+	size_t            s_authorizer_buf_len, s_authorizer_reply_buf_len;
+
+	/* protected by s_cap_lock */
+	spinlock_t        s_cap_lock;
+	u32               s_cap_gen;  /* inc each time we get mds stale msg */
+	unsigned long     s_cap_ttl;  /* when session caps expire */
+	struct list_head  s_caps;     /* all caps issued by this session */
+	int               s_nr_caps, s_trim_caps;
+	int               s_num_cap_releases;
+	struct list_head  s_cap_releases; /* waiting cap_release messages */
+	struct list_head  s_cap_releases_done; /* ready to send */
+	struct ceph_cap  *s_cap_iterator;
+
+	/* protected by mutex */
+	struct list_head  s_cap_flushing;     /* inodes w/ flushing caps */
+	struct list_head  s_cap_snaps_flushing;
+	unsigned long     s_renew_requested; /* last time we sent a renew req */
+	u64               s_renew_seq;
+
+	atomic_t          s_ref;
+	struct list_head  s_waiting;  /* waiting requests */
+	struct list_head  s_unsafe;   /* unsafe requests */
+};
+
+/*
+ * modes of choosing which MDS to send a request to
+ */
+enum {
+	USE_ANY_MDS,
+	USE_RANDOM_MDS,
+	USE_AUTH_MDS,   /* prefer authoritative mds for this metadata item */
+};
+
+struct ceph_mds_request;
+struct ceph_mds_client;
+
+/*
+ * request completion callback
+ */
+typedef void (*ceph_mds_request_callback_t) (struct ceph_mds_client *mdsc,
+					     struct ceph_mds_request *req);
+
+/*
+ * an in-flight mds request
+ */
+struct ceph_mds_request {
+	u64 r_tid;                   /* transaction id */
+	struct rb_node r_node;
+
+	int r_op;                    /* mds op code */
+	int r_mds;
+
+	/* operation on what? */
+	struct inode *r_inode;              /* arg1 */
+	struct dentry *r_dentry;            /* arg1 */
+	struct dentry *r_old_dentry;        /* arg2: rename from or link from */
+	char *r_path1, *r_path2;
+	struct ceph_vino r_ino1, r_ino2;
+
+	struct inode *r_locked_dir; /* dir (if any) i_mutex locked by vfs */
+	struct inode *r_target_inode;       /* resulting inode */
+
+	union ceph_mds_request_args r_args;
+	int r_fmode;        /* file mode, if expecting cap */
+
+	/* for choosing which mds to send this request to */
+	int r_direct_mode;
+	u32 r_direct_hash;      /* choose dir frag based on this dentry hash */
+	bool r_direct_is_hash;  /* true if r_direct_hash is valid */
+
+	/* data payload is used for xattr ops */
+	struct page **r_pages;
+	int r_num_pages;
+	int r_data_len;
+
+	/* what caps shall we drop? */
+	int r_inode_drop, r_inode_unless;
+	int r_dentry_drop, r_dentry_unless;
+	int r_old_dentry_drop, r_old_dentry_unless;
+	struct inode *r_old_inode;
+	int r_old_inode_drop, r_old_inode_unless;
+
+	struct ceph_msg  *r_request;  /* original request */
+	struct ceph_msg  *r_reply;
+	struct ceph_mds_reply_info_parsed r_reply_info;
+	int r_err;
+	bool r_aborted;
+
+	unsigned long r_timeout;  /* optional.  jiffies */
+	unsigned long r_started;  /* start time to measure timeout against */
+	unsigned long r_request_started; /* start time for mds request only,
+					    used to measure lease durations */
+
+	/* link unsafe requests to parent directory, for fsync */
+	struct inode	*r_unsafe_dir;
+	struct list_head r_unsafe_dir_item;
+
+	struct ceph_mds_session *r_session;
+
+	int               r_attempts;   /* resend attempts */
+	int               r_num_fwd;    /* number of forward attempts */
+	int               r_num_stale;
+	int               r_resend_mds; /* mds to resend to next, if any*/
+
+	struct kref       r_kref;
+	struct list_head  r_wait;
+	struct completion r_completion;
+	struct completion r_safe_completion;
+	ceph_mds_request_callback_t r_callback;
+	struct list_head  r_unsafe_item;  /* per-session unsafe list item */
+	bool		  r_got_unsafe, r_got_safe;
+
+	bool              r_did_prepopulate;
+	u32               r_readdir_offset;
+
+	struct ceph_cap_reservation r_caps_reservation;
+	int r_num_caps;
+};
+
+/*
+ * mds client state
+ */
+struct ceph_mds_client {
+	struct ceph_client      *client;
+	struct mutex            mutex;         /* all nested structures */
+
+	struct ceph_mdsmap      *mdsmap;
+	struct completion       safe_umount_waiters, session_close_waiters;
+	struct list_head        waiting_for_map;
+
+	struct ceph_mds_session **sessions;    /* NULL for mds if no session */
+	int                     max_sessions;  /* len of s_mds_sessions */
+	int                     stopping;      /* true if shutting down */
+
+	/*
+	 * snap_rwsem will cover cap linkage into snaprealms, and
+	 * realm snap contexts.  (later, we can do per-realm snap
+	 * contexts locks..)  the empty list contains realms with no
+	 * references (implying they contain no inodes with caps) that
+	 * should be destroyed.
+	 */
+	struct rw_semaphore     snap_rwsem;
+	struct rb_root          snap_realms;
+	struct list_head        snap_empty;
+	spinlock_t              snap_empty_lock;  /* protect snap_empty */
+
+	u64                    last_tid;      /* most recent mds request */
+	struct rb_root         request_tree;  /* pending mds requests */
+	struct delayed_work    delayed_work;  /* delayed work */
+	unsigned long    last_renew_caps;  /* last time we renewed our caps */
+	struct list_head cap_delay_list;   /* caps with delayed release */
+	spinlock_t       cap_delay_lock;   /* protects cap_delay_list */
+	struct list_head snap_flush_list;  /* cap_snaps ready to flush */
+	spinlock_t       snap_flush_lock;
+
+	u64               cap_flush_seq;
+	struct list_head  cap_dirty;        /* inodes with dirty caps */
+	int               num_cap_flushing; /* # caps we are flushing */
+	spinlock_t        cap_dirty_lock;   /* protects above items */
+	wait_queue_head_t cap_flushing_wq;
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry 	  *debugfs_file;
+#endif
+
+	spinlock_t	  dentry_lru_lock;
+	struct list_head  dentry_lru;
+	int		  num_dentry;
+};
+
+extern const char *ceph_mds_op_name(int op);
+
+extern struct ceph_mds_session *
+__ceph_lookup_mds_session(struct ceph_mds_client *, int mds);
+
+static inline struct ceph_mds_session *
+ceph_get_mds_session(struct ceph_mds_session *s)
+{
+	atomic_inc(&s->s_ref);
+	return s;
+}
+
+extern void ceph_put_mds_session(struct ceph_mds_session *s);
+
+extern int ceph_send_msg_mds(struct ceph_mds_client *mdsc,
+			     struct ceph_msg *msg, int mds);
+
+extern int ceph_mdsc_init(struct ceph_mds_client *mdsc,
+			   struct ceph_client *client);
+extern void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc);
+extern void ceph_mdsc_stop(struct ceph_mds_client *mdsc);
+
+extern void ceph_mdsc_sync(struct ceph_mds_client *mdsc);
+
+extern void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc,
+				    struct inode *inode,
+				    struct dentry *dn, int mask);
+
+extern struct ceph_mds_request *
+ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode);
+extern void ceph_mdsc_submit_request(struct ceph_mds_client *mdsc,
+				     struct ceph_mds_request *req);
+extern int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
+				struct inode *dir,
+				struct ceph_mds_request *req);
+static inline void ceph_mdsc_get_request(struct ceph_mds_request *req)
+{
+	kref_get(&req->r_kref);
+}
+extern void ceph_mdsc_release_request(struct kref *kref);
+static inline void ceph_mdsc_put_request(struct ceph_mds_request *req)
+{
+	kref_put(&req->r_kref, ceph_mdsc_release_request);
+}
+
+extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc);
+
+extern char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base,
+				  int stop_on_nosnap);
+
+extern void __ceph_mdsc_drop_dentry_lease(struct dentry *dentry);
+extern void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session,
+				     struct inode *inode,
+				     struct dentry *dentry, char action,
+				     u32 seq);
+
+extern void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc,
+				 struct ceph_msg *msg);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/mdsmap.c linux-libre-2.6.34-gnu1/fs/ceph/mdsmap.c
--- linux-libre-2.6.33-gnu1/fs/ceph/mdsmap.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/mdsmap.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,174 @@
+#include "ceph_debug.h"
+
+#include <linux/bug.h>
+#include <linux/err.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "mdsmap.h"
+#include "messenger.h"
+#include "decode.h"
+
+#include "super.h"
+
+
+/*
+ * choose a random mds that is "up" (i.e. has a state > 0), or -1.
+ */
+int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m)
+{
+	int n = 0;
+	int i;
+	char r;
+
+	/* count */
+	for (i = 0; i < m->m_max_mds; i++)
+		if (m->m_info[i].state > 0)
+			n++;
+	if (n == 0)
+		return -1;
+
+	/* pick */
+	get_random_bytes(&r, 1);
+	n = r % n;
+	i = 0;
+	for (i = 0; n > 0; i++, n--)
+		while (m->m_info[i].state <= 0)
+			i++;
+
+	return i;
+}
+
+/*
+ * Decode an MDS map
+ *
+ * Ignore any fields we don't care about (there are quite a few of
+ * them).
+ */
+struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
+{
+	struct ceph_mdsmap *m;
+	const void *start = *p;
+	int i, j, n;
+	int err = -EINVAL;
+	u16 version;
+
+	m = kzalloc(sizeof(*m), GFP_NOFS);
+	if (m == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	ceph_decode_16_safe(p, end, version, bad);
+
+	ceph_decode_need(p, end, 8*sizeof(u32) + sizeof(u64), bad);
+	m->m_epoch = ceph_decode_32(p);
+	m->m_client_epoch = ceph_decode_32(p);
+	m->m_last_failure = ceph_decode_32(p);
+	m->m_root = ceph_decode_32(p);
+	m->m_session_timeout = ceph_decode_32(p);
+	m->m_session_autoclose = ceph_decode_32(p);
+	m->m_max_file_size = ceph_decode_64(p);
+	m->m_max_mds = ceph_decode_32(p);
+
+	m->m_info = kcalloc(m->m_max_mds, sizeof(*m->m_info), GFP_NOFS);
+	if (m->m_info == NULL)
+		goto badmem;
+
+	/* pick out active nodes from mds_info (state > 0) */
+	n = ceph_decode_32(p);
+	for (i = 0; i < n; i++) {
+		u64 global_id;
+		u32 namelen;
+		s32 mds, inc, state;
+		u64 state_seq;
+		u8 infoversion;
+		struct ceph_entity_addr addr;
+		u32 num_export_targets;
+		void *pexport_targets = NULL;
+
+		ceph_decode_need(p, end, sizeof(u64)*2 + 1 + sizeof(u32), bad);
+		global_id = ceph_decode_64(p);
+		infoversion = ceph_decode_8(p);
+		*p += sizeof(u64);
+		namelen = ceph_decode_32(p);  /* skip mds name */
+		*p += namelen;
+
+		ceph_decode_need(p, end,
+				 4*sizeof(u32) + sizeof(u64) +
+				 sizeof(addr) + sizeof(struct ceph_timespec),
+				 bad);
+		mds = ceph_decode_32(p);
+		inc = ceph_decode_32(p);
+		state = ceph_decode_32(p);
+		state_seq = ceph_decode_64(p);
+		ceph_decode_copy(p, &addr, sizeof(addr));
+		ceph_decode_addr(&addr);
+		*p += sizeof(struct ceph_timespec);
+		*p += sizeof(u32);
+		ceph_decode_32_safe(p, end, namelen, bad);
+		*p += namelen;
+		if (infoversion >= 2) {
+			ceph_decode_32_safe(p, end, num_export_targets, bad);
+			pexport_targets = *p;
+			*p += num_export_targets * sizeof(u32);
+		} else {
+			num_export_targets = 0;
+		}
+
+		dout("mdsmap_decode %d/%d %lld mds%d.%d %s %s\n",
+		     i+1, n, global_id, mds, inc, pr_addr(&addr.in_addr),
+		     ceph_mds_state_name(state));
+		if (mds >= 0 && mds < m->m_max_mds && state > 0) {
+			m->m_info[mds].global_id = global_id;
+			m->m_info[mds].state = state;
+			m->m_info[mds].addr = addr;
+			m->m_info[mds].num_export_targets = num_export_targets;
+			if (num_export_targets) {
+				m->m_info[mds].export_targets =
+					kcalloc(num_export_targets, sizeof(u32),
+						GFP_NOFS);
+				for (j = 0; j < num_export_targets; j++)
+					m->m_info[mds].export_targets[j] =
+					       ceph_decode_32(&pexport_targets);
+			} else {
+				m->m_info[mds].export_targets = NULL;
+			}
+		}
+	}
+
+	/* pg_pools */
+	ceph_decode_32_safe(p, end, n, bad);
+	m->m_num_data_pg_pools = n;
+	m->m_data_pg_pools = kcalloc(n, sizeof(u32), GFP_NOFS);
+	if (!m->m_data_pg_pools)
+		goto badmem;
+	ceph_decode_need(p, end, sizeof(u32)*(n+1), bad);
+	for (i = 0; i < n; i++)
+		m->m_data_pg_pools[i] = ceph_decode_32(p);
+	m->m_cas_pg_pool = ceph_decode_32(p);
+
+	/* ok, we don't care about the rest. */
+	dout("mdsmap_decode success epoch %u\n", m->m_epoch);
+	return m;
+
+badmem:
+	err = -ENOMEM;
+bad:
+	pr_err("corrupt mdsmap\n");
+	print_hex_dump(KERN_DEBUG, "mdsmap: ",
+		       DUMP_PREFIX_OFFSET, 16, 1,
+		       start, end - start, true);
+	ceph_mdsmap_destroy(m);
+	return ERR_PTR(-EINVAL);
+}
+
+void ceph_mdsmap_destroy(struct ceph_mdsmap *m)
+{
+	int i;
+
+	for (i = 0; i < m->m_max_mds; i++)
+		kfree(m->m_info[i].export_targets);
+	kfree(m->m_info);
+	kfree(m->m_data_pg_pools);
+	kfree(m);
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/mdsmap.h linux-libre-2.6.34-gnu1/fs/ceph/mdsmap.h
--- linux-libre-2.6.33-gnu1/fs/ceph/mdsmap.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/mdsmap.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,54 @@
+#ifndef _FS_CEPH_MDSMAP_H
+#define _FS_CEPH_MDSMAP_H
+
+#include "types.h"
+
+/*
+ * mds map - describe servers in the mds cluster.
+ *
+ * we limit fields to those the client actually xcares about
+ */
+struct ceph_mds_info {
+	u64 global_id;
+	struct ceph_entity_addr addr;
+	s32 state;
+	int num_export_targets;
+	u32 *export_targets;
+};
+
+struct ceph_mdsmap {
+	u32 m_epoch, m_client_epoch, m_last_failure;
+	u32 m_root;
+	u32 m_session_timeout;          /* seconds */
+	u32 m_session_autoclose;        /* seconds */
+	u64 m_max_file_size;
+	u32 m_max_mds;                  /* size of m_addr, m_state arrays */
+	struct ceph_mds_info *m_info;
+
+	/* which object pools file data can be stored in */
+	int m_num_data_pg_pools;
+	u32 *m_data_pg_pools;
+	u32 m_cas_pg_pool;
+};
+
+static inline struct ceph_entity_addr *
+ceph_mdsmap_get_addr(struct ceph_mdsmap *m, int w)
+{
+	if (w >= m->m_max_mds)
+		return NULL;
+	return &m->m_info[w].addr;
+}
+
+static inline int ceph_mdsmap_get_state(struct ceph_mdsmap *m, int w)
+{
+	BUG_ON(w < 0);
+	if (w >= m->m_max_mds)
+		return CEPH_MDS_STATE_DNE;
+	return m->m_info[w].state;
+}
+
+extern int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m);
+extern struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end);
+extern void ceph_mdsmap_destroy(struct ceph_mdsmap *m);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/messenger.c linux-libre-2.6.34-gnu1/fs/ceph/messenger.c
--- linux-libre-2.6.33-gnu1/fs/ceph/messenger.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/messenger.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,2284 @@
+#include "ceph_debug.h"
+
+#include <linux/crc32c.h>
+#include <linux/ctype.h>
+#include <linux/highmem.h>
+#include <linux/inet.h>
+#include <linux/kthread.h>
+#include <linux/net.h>
+#include <linux/slab.h>
+#include <linux/socket.h>
+#include <linux/string.h>
+#include <net/tcp.h>
+
+#include "super.h"
+#include "messenger.h"
+#include "decode.h"
+#include "pagelist.h"
+
+/*
+ * Ceph uses the messenger to exchange ceph_msg messages with other
+ * hosts in the system.  The messenger provides ordered and reliable
+ * delivery.  We tolerate TCP disconnects by reconnecting (with
+ * exponential backoff) in the case of a fault (disconnection, bad
+ * crc, protocol error).  Acks allow sent messages to be discarded by
+ * the sender.
+ */
+
+/* static tag bytes (protocol control messages) */
+static char tag_msg = CEPH_MSGR_TAG_MSG;
+static char tag_ack = CEPH_MSGR_TAG_ACK;
+static char tag_keepalive = CEPH_MSGR_TAG_KEEPALIVE;
+
+#ifdef CONFIG_LOCKDEP
+static struct lock_class_key socket_class;
+#endif
+
+
+static void queue_con(struct ceph_connection *con);
+static void con_work(struct work_struct *);
+static void ceph_fault(struct ceph_connection *con);
+
+const char *ceph_name_type_str(int t)
+{
+	switch (t) {
+	case CEPH_ENTITY_TYPE_MON: return "mon";
+	case CEPH_ENTITY_TYPE_MDS: return "mds";
+	case CEPH_ENTITY_TYPE_OSD: return "osd";
+	case CEPH_ENTITY_TYPE_CLIENT: return "client";
+	case CEPH_ENTITY_TYPE_ADMIN: return "admin";
+	default: return "???";
+	}
+}
+
+/*
+ * nicely render a sockaddr as a string.
+ */
+#define MAX_ADDR_STR 20
+static char addr_str[MAX_ADDR_STR][40];
+static DEFINE_SPINLOCK(addr_str_lock);
+static int last_addr_str;
+
+const char *pr_addr(const struct sockaddr_storage *ss)
+{
+	int i;
+	char *s;
+	struct sockaddr_in *in4 = (void *)ss;
+	unsigned char *quad = (void *)&in4->sin_addr.s_addr;
+	struct sockaddr_in6 *in6 = (void *)ss;
+
+	spin_lock(&addr_str_lock);
+	i = last_addr_str++;
+	if (last_addr_str == MAX_ADDR_STR)
+		last_addr_str = 0;
+	spin_unlock(&addr_str_lock);
+	s = addr_str[i];
+
+	switch (ss->ss_family) {
+	case AF_INET:
+		sprintf(s, "%u.%u.%u.%u:%u",
+			(unsigned int)quad[0],
+			(unsigned int)quad[1],
+			(unsigned int)quad[2],
+			(unsigned int)quad[3],
+			(unsigned int)ntohs(in4->sin_port));
+		break;
+
+	case AF_INET6:
+		sprintf(s, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%u",
+			in6->sin6_addr.s6_addr16[0],
+			in6->sin6_addr.s6_addr16[1],
+			in6->sin6_addr.s6_addr16[2],
+			in6->sin6_addr.s6_addr16[3],
+			in6->sin6_addr.s6_addr16[4],
+			in6->sin6_addr.s6_addr16[5],
+			in6->sin6_addr.s6_addr16[6],
+			in6->sin6_addr.s6_addr16[7],
+			(unsigned int)ntohs(in6->sin6_port));
+		break;
+
+	default:
+		sprintf(s, "(unknown sockaddr family %d)", (int)ss->ss_family);
+	}
+
+	return s;
+}
+
+static void encode_my_addr(struct ceph_messenger *msgr)
+{
+	memcpy(&msgr->my_enc_addr, &msgr->inst.addr, sizeof(msgr->my_enc_addr));
+	ceph_encode_addr(&msgr->my_enc_addr);
+}
+
+/*
+ * work queue for all reading and writing to/from the socket.
+ */
+struct workqueue_struct *ceph_msgr_wq;
+
+int __init ceph_msgr_init(void)
+{
+	ceph_msgr_wq = create_workqueue("ceph-msgr");
+	if (IS_ERR(ceph_msgr_wq)) {
+		int ret = PTR_ERR(ceph_msgr_wq);
+		pr_err("msgr_init failed to create workqueue: %d\n", ret);
+		ceph_msgr_wq = NULL;
+		return ret;
+	}
+	return 0;
+}
+
+void ceph_msgr_exit(void)
+{
+	destroy_workqueue(ceph_msgr_wq);
+}
+
+/*
+ * socket callback functions
+ */
+
+/* data available on socket, or listen socket received a connect */
+static void ceph_data_ready(struct sock *sk, int count_unused)
+{
+	struct ceph_connection *con =
+		(struct ceph_connection *)sk->sk_user_data;
+	if (sk->sk_state != TCP_CLOSE_WAIT) {
+		dout("ceph_data_ready on %p state = %lu, queueing work\n",
+		     con, con->state);
+		queue_con(con);
+	}
+}
+
+/* socket has buffer space for writing */
+static void ceph_write_space(struct sock *sk)
+{
+	struct ceph_connection *con =
+		(struct ceph_connection *)sk->sk_user_data;
+
+	/* only queue to workqueue if there is data we want to write. */
+	if (test_bit(WRITE_PENDING, &con->state)) {
+		dout("ceph_write_space %p queueing write work\n", con);
+		queue_con(con);
+	} else {
+		dout("ceph_write_space %p nothing to write\n", con);
+	}
+
+	/* since we have our own write_space, clear the SOCK_NOSPACE flag */
+	clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
+}
+
+/* socket's state has changed */
+static void ceph_state_change(struct sock *sk)
+{
+	struct ceph_connection *con =
+		(struct ceph_connection *)sk->sk_user_data;
+
+	dout("ceph_state_change %p state = %lu sk_state = %u\n",
+	     con, con->state, sk->sk_state);
+
+	if (test_bit(CLOSED, &con->state))
+		return;
+
+	switch (sk->sk_state) {
+	case TCP_CLOSE:
+		dout("ceph_state_change TCP_CLOSE\n");
+	case TCP_CLOSE_WAIT:
+		dout("ceph_state_change TCP_CLOSE_WAIT\n");
+		if (test_and_set_bit(SOCK_CLOSED, &con->state) == 0) {
+			if (test_bit(CONNECTING, &con->state))
+				con->error_msg = "connection failed";
+			else
+				con->error_msg = "socket closed";
+			queue_con(con);
+		}
+		break;
+	case TCP_ESTABLISHED:
+		dout("ceph_state_change TCP_ESTABLISHED\n");
+		queue_con(con);
+		break;
+	}
+}
+
+/*
+ * set up socket callbacks
+ */
+static void set_sock_callbacks(struct socket *sock,
+			       struct ceph_connection *con)
+{
+	struct sock *sk = sock->sk;
+	sk->sk_user_data = (void *)con;
+	sk->sk_data_ready = ceph_data_ready;
+	sk->sk_write_space = ceph_write_space;
+	sk->sk_state_change = ceph_state_change;
+}
+
+
+/*
+ * socket helpers
+ */
+
+/*
+ * initiate connection to a remote socket.
+ */
+static struct socket *ceph_tcp_connect(struct ceph_connection *con)
+{
+	struct sockaddr *paddr = (struct sockaddr *)&con->peer_addr.in_addr;
+	struct socket *sock;
+	int ret;
+
+	BUG_ON(con->sock);
+	ret = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
+	if (ret)
+		return ERR_PTR(ret);
+	con->sock = sock;
+	sock->sk->sk_allocation = GFP_NOFS;
+
+#ifdef CONFIG_LOCKDEP
+	lockdep_set_class(&sock->sk->sk_lock, &socket_class);
+#endif
+
+	set_sock_callbacks(sock, con);
+
+	dout("connect %s\n", pr_addr(&con->peer_addr.in_addr));
+
+	ret = sock->ops->connect(sock, paddr, sizeof(*paddr), O_NONBLOCK);
+	if (ret == -EINPROGRESS) {
+		dout("connect %s EINPROGRESS sk_state = %u\n",
+		     pr_addr(&con->peer_addr.in_addr),
+		     sock->sk->sk_state);
+		ret = 0;
+	}
+	if (ret < 0) {
+		pr_err("connect %s error %d\n",
+		       pr_addr(&con->peer_addr.in_addr), ret);
+		sock_release(sock);
+		con->sock = NULL;
+		con->error_msg = "connect error";
+	}
+
+	if (ret < 0)
+		return ERR_PTR(ret);
+	return sock;
+}
+
+static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len)
+{
+	struct kvec iov = {buf, len};
+	struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL };
+
+	return kernel_recvmsg(sock, &msg, &iov, 1, len, msg.msg_flags);
+}
+
+/*
+ * write something.  @more is true if caller will be sending more data
+ * shortly.
+ */
+static int ceph_tcp_sendmsg(struct socket *sock, struct kvec *iov,
+		     size_t kvlen, size_t len, int more)
+{
+	struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL };
+
+	if (more)
+		msg.msg_flags |= MSG_MORE;
+	else
+		msg.msg_flags |= MSG_EOR;  /* superfluous, but what the hell */
+
+	return kernel_sendmsg(sock, &msg, iov, kvlen, len);
+}
+
+
+/*
+ * Shutdown/close the socket for the given connection.
+ */
+static int con_close_socket(struct ceph_connection *con)
+{
+	int rc;
+
+	dout("con_close_socket on %p sock %p\n", con, con->sock);
+	if (!con->sock)
+		return 0;
+	set_bit(SOCK_CLOSED, &con->state);
+	rc = con->sock->ops->shutdown(con->sock, SHUT_RDWR);
+	sock_release(con->sock);
+	con->sock = NULL;
+	clear_bit(SOCK_CLOSED, &con->state);
+	return rc;
+}
+
+/*
+ * Reset a connection.  Discard all incoming and outgoing messages
+ * and clear *_seq state.
+ */
+static void ceph_msg_remove(struct ceph_msg *msg)
+{
+	list_del_init(&msg->list_head);
+	ceph_msg_put(msg);
+}
+static void ceph_msg_remove_list(struct list_head *head)
+{
+	while (!list_empty(head)) {
+		struct ceph_msg *msg = list_first_entry(head, struct ceph_msg,
+							list_head);
+		ceph_msg_remove(msg);
+	}
+}
+
+static void reset_connection(struct ceph_connection *con)
+{
+	/* reset connection, out_queue, msg_ and connect_seq */
+	/* discard existing out_queue and msg_seq */
+	ceph_msg_remove_list(&con->out_queue);
+	ceph_msg_remove_list(&con->out_sent);
+
+	if (con->in_msg) {
+		ceph_msg_put(con->in_msg);
+		con->in_msg = NULL;
+	}
+
+	con->connect_seq = 0;
+	con->out_seq = 0;
+	if (con->out_msg) {
+		ceph_msg_put(con->out_msg);
+		con->out_msg = NULL;
+	}
+	con->in_seq = 0;
+	con->in_seq_acked = 0;
+}
+
+/*
+ * mark a peer down.  drop any open connections.
+ */
+void ceph_con_close(struct ceph_connection *con)
+{
+	dout("con_close %p peer %s\n", con, pr_addr(&con->peer_addr.in_addr));
+	set_bit(CLOSED, &con->state);  /* in case there's queued work */
+	clear_bit(STANDBY, &con->state);  /* avoid connect_seq bump */
+	clear_bit(LOSSYTX, &con->state);  /* so we retry next connect */
+	clear_bit(KEEPALIVE_PENDING, &con->state);
+	clear_bit(WRITE_PENDING, &con->state);
+	mutex_lock(&con->mutex);
+	reset_connection(con);
+	cancel_delayed_work(&con->work);
+	mutex_unlock(&con->mutex);
+	queue_con(con);
+}
+
+/*
+ * Reopen a closed connection, with a new peer address.
+ */
+void ceph_con_open(struct ceph_connection *con, struct ceph_entity_addr *addr)
+{
+	dout("con_open %p %s\n", con, pr_addr(&addr->in_addr));
+	set_bit(OPENING, &con->state);
+	clear_bit(CLOSED, &con->state);
+	memcpy(&con->peer_addr, addr, sizeof(*addr));
+	con->delay = 0;      /* reset backoff memory */
+	queue_con(con);
+}
+
+/*
+ * return true if this connection ever successfully opened
+ */
+bool ceph_con_opened(struct ceph_connection *con)
+{
+	return con->connect_seq > 0;
+}
+
+/*
+ * generic get/put
+ */
+struct ceph_connection *ceph_con_get(struct ceph_connection *con)
+{
+	dout("con_get %p nref = %d -> %d\n", con,
+	     atomic_read(&con->nref), atomic_read(&con->nref) + 1);
+	if (atomic_inc_not_zero(&con->nref))
+		return con;
+	return NULL;
+}
+
+void ceph_con_put(struct ceph_connection *con)
+{
+	dout("con_put %p nref = %d -> %d\n", con,
+	     atomic_read(&con->nref), atomic_read(&con->nref) - 1);
+	BUG_ON(atomic_read(&con->nref) == 0);
+	if (atomic_dec_and_test(&con->nref)) {
+		BUG_ON(con->sock);
+		kfree(con);
+	}
+}
+
+/*
+ * initialize a new connection.
+ */
+void ceph_con_init(struct ceph_messenger *msgr, struct ceph_connection *con)
+{
+	dout("con_init %p\n", con);
+	memset(con, 0, sizeof(*con));
+	atomic_set(&con->nref, 1);
+	con->msgr = msgr;
+	mutex_init(&con->mutex);
+	INIT_LIST_HEAD(&con->out_queue);
+	INIT_LIST_HEAD(&con->out_sent);
+	INIT_DELAYED_WORK(&con->work, con_work);
+}
+
+
+/*
+ * We maintain a global counter to order connection attempts.  Get
+ * a unique seq greater than @gt.
+ */
+static u32 get_global_seq(struct ceph_messenger *msgr, u32 gt)
+{
+	u32 ret;
+
+	spin_lock(&msgr->global_seq_lock);
+	if (msgr->global_seq < gt)
+		msgr->global_seq = gt;
+	ret = ++msgr->global_seq;
+	spin_unlock(&msgr->global_seq_lock);
+	return ret;
+}
+
+
+/*
+ * Prepare footer for currently outgoing message, and finish things
+ * off.  Assumes out_kvec* are already valid.. we just add on to the end.
+ */
+static void prepare_write_message_footer(struct ceph_connection *con, int v)
+{
+	struct ceph_msg *m = con->out_msg;
+
+	dout("prepare_write_message_footer %p\n", con);
+	con->out_kvec_is_msg = true;
+	con->out_kvec[v].iov_base = &m->footer;
+	con->out_kvec[v].iov_len = sizeof(m->footer);
+	con->out_kvec_bytes += sizeof(m->footer);
+	con->out_kvec_left++;
+	con->out_more = m->more_to_follow;
+	con->out_msg_done = true;
+}
+
+/*
+ * Prepare headers for the next outgoing message.
+ */
+static void prepare_write_message(struct ceph_connection *con)
+{
+	struct ceph_msg *m;
+	int v = 0;
+
+	con->out_kvec_bytes = 0;
+	con->out_kvec_is_msg = true;
+	con->out_msg_done = false;
+
+	/* Sneak an ack in there first?  If we can get it into the same
+	 * TCP packet that's a good thing. */
+	if (con->in_seq > con->in_seq_acked) {
+		con->in_seq_acked = con->in_seq;
+		con->out_kvec[v].iov_base = &tag_ack;
+		con->out_kvec[v++].iov_len = 1;
+		con->out_temp_ack = cpu_to_le64(con->in_seq_acked);
+		con->out_kvec[v].iov_base = &con->out_temp_ack;
+		con->out_kvec[v++].iov_len = sizeof(con->out_temp_ack);
+		con->out_kvec_bytes = 1 + sizeof(con->out_temp_ack);
+	}
+
+	m = list_first_entry(&con->out_queue,
+		       struct ceph_msg, list_head);
+	con->out_msg = m;
+	if (test_bit(LOSSYTX, &con->state)) {
+		list_del_init(&m->list_head);
+	} else {
+		/* put message on sent list */
+		ceph_msg_get(m);
+		list_move_tail(&m->list_head, &con->out_sent);
+	}
+
+	/*
+	 * only assign outgoing seq # if we haven't sent this message
+	 * yet.  if it is requeued, resend with it's original seq.
+	 */
+	if (m->needs_out_seq) {
+		m->hdr.seq = cpu_to_le64(++con->out_seq);
+		m->needs_out_seq = false;
+	}
+
+	dout("prepare_write_message %p seq %lld type %d len %d+%d+%d %d pgs\n",
+	     m, con->out_seq, le16_to_cpu(m->hdr.type),
+	     le32_to_cpu(m->hdr.front_len), le32_to_cpu(m->hdr.middle_len),
+	     le32_to_cpu(m->hdr.data_len),
+	     m->nr_pages);
+	BUG_ON(le32_to_cpu(m->hdr.front_len) != m->front.iov_len);
+
+	/* tag + hdr + front + middle */
+	con->out_kvec[v].iov_base = &tag_msg;
+	con->out_kvec[v++].iov_len = 1;
+	con->out_kvec[v].iov_base = &m->hdr;
+	con->out_kvec[v++].iov_len = sizeof(m->hdr);
+	con->out_kvec[v++] = m->front;
+	if (m->middle)
+		con->out_kvec[v++] = m->middle->vec;
+	con->out_kvec_left = v;
+	con->out_kvec_bytes += 1 + sizeof(m->hdr) + m->front.iov_len +
+		(m->middle ? m->middle->vec.iov_len : 0);
+	con->out_kvec_cur = con->out_kvec;
+
+	/* fill in crc (except data pages), footer */
+	con->out_msg->hdr.crc =
+		cpu_to_le32(crc32c(0, (void *)&m->hdr,
+				      sizeof(m->hdr) - sizeof(m->hdr.crc)));
+	con->out_msg->footer.flags = CEPH_MSG_FOOTER_COMPLETE;
+	con->out_msg->footer.front_crc =
+		cpu_to_le32(crc32c(0, m->front.iov_base, m->front.iov_len));
+	if (m->middle)
+		con->out_msg->footer.middle_crc =
+			cpu_to_le32(crc32c(0, m->middle->vec.iov_base,
+					   m->middle->vec.iov_len));
+	else
+		con->out_msg->footer.middle_crc = 0;
+	con->out_msg->footer.data_crc = 0;
+	dout("prepare_write_message front_crc %u data_crc %u\n",
+	     le32_to_cpu(con->out_msg->footer.front_crc),
+	     le32_to_cpu(con->out_msg->footer.middle_crc));
+
+	/* is there a data payload? */
+	if (le32_to_cpu(m->hdr.data_len) > 0) {
+		/* initialize page iterator */
+		con->out_msg_pos.page = 0;
+		con->out_msg_pos.page_pos =
+			le16_to_cpu(m->hdr.data_off) & ~PAGE_MASK;
+		con->out_msg_pos.data_pos = 0;
+		con->out_msg_pos.did_page_crc = 0;
+		con->out_more = 1;  /* data + footer will follow */
+	} else {
+		/* no, queue up footer too and be done */
+		prepare_write_message_footer(con, v);
+	}
+
+	set_bit(WRITE_PENDING, &con->state);
+}
+
+/*
+ * Prepare an ack.
+ */
+static void prepare_write_ack(struct ceph_connection *con)
+{
+	dout("prepare_write_ack %p %llu -> %llu\n", con,
+	     con->in_seq_acked, con->in_seq);
+	con->in_seq_acked = con->in_seq;
+
+	con->out_kvec[0].iov_base = &tag_ack;
+	con->out_kvec[0].iov_len = 1;
+	con->out_temp_ack = cpu_to_le64(con->in_seq_acked);
+	con->out_kvec[1].iov_base = &con->out_temp_ack;
+	con->out_kvec[1].iov_len = sizeof(con->out_temp_ack);
+	con->out_kvec_left = 2;
+	con->out_kvec_bytes = 1 + sizeof(con->out_temp_ack);
+	con->out_kvec_cur = con->out_kvec;
+	con->out_more = 1;  /* more will follow.. eventually.. */
+	set_bit(WRITE_PENDING, &con->state);
+}
+
+/*
+ * Prepare to write keepalive byte.
+ */
+static void prepare_write_keepalive(struct ceph_connection *con)
+{
+	dout("prepare_write_keepalive %p\n", con);
+	con->out_kvec[0].iov_base = &tag_keepalive;
+	con->out_kvec[0].iov_len = 1;
+	con->out_kvec_left = 1;
+	con->out_kvec_bytes = 1;
+	con->out_kvec_cur = con->out_kvec;
+	set_bit(WRITE_PENDING, &con->state);
+}
+
+/*
+ * Connection negotiation.
+ */
+
+static void prepare_connect_authorizer(struct ceph_connection *con)
+{
+	void *auth_buf;
+	int auth_len = 0;
+	int auth_protocol = 0;
+
+	mutex_unlock(&con->mutex);
+	if (con->ops->get_authorizer)
+		con->ops->get_authorizer(con, &auth_buf, &auth_len,
+					 &auth_protocol, &con->auth_reply_buf,
+					 &con->auth_reply_buf_len,
+					 con->auth_retry);
+	mutex_lock(&con->mutex);
+
+	con->out_connect.authorizer_protocol = cpu_to_le32(auth_protocol);
+	con->out_connect.authorizer_len = cpu_to_le32(auth_len);
+
+	con->out_kvec[con->out_kvec_left].iov_base = auth_buf;
+	con->out_kvec[con->out_kvec_left].iov_len = auth_len;
+	con->out_kvec_left++;
+	con->out_kvec_bytes += auth_len;
+}
+
+/*
+ * We connected to a peer and are saying hello.
+ */
+static void prepare_write_banner(struct ceph_messenger *msgr,
+				 struct ceph_connection *con)
+{
+	int len = strlen(CEPH_BANNER);
+
+	con->out_kvec[0].iov_base = CEPH_BANNER;
+	con->out_kvec[0].iov_len = len;
+	con->out_kvec[1].iov_base = &msgr->my_enc_addr;
+	con->out_kvec[1].iov_len = sizeof(msgr->my_enc_addr);
+	con->out_kvec_left = 2;
+	con->out_kvec_bytes = len + sizeof(msgr->my_enc_addr);
+	con->out_kvec_cur = con->out_kvec;
+	con->out_more = 0;
+	set_bit(WRITE_PENDING, &con->state);
+}
+
+static void prepare_write_connect(struct ceph_messenger *msgr,
+				  struct ceph_connection *con,
+				  int after_banner)
+{
+	unsigned global_seq = get_global_seq(con->msgr, 0);
+	int proto;
+
+	switch (con->peer_name.type) {
+	case CEPH_ENTITY_TYPE_MON:
+		proto = CEPH_MONC_PROTOCOL;
+		break;
+	case CEPH_ENTITY_TYPE_OSD:
+		proto = CEPH_OSDC_PROTOCOL;
+		break;
+	case CEPH_ENTITY_TYPE_MDS:
+		proto = CEPH_MDSC_PROTOCOL;
+		break;
+	default:
+		BUG();
+	}
+
+	dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con,
+	     con->connect_seq, global_seq, proto);
+
+	con->out_connect.features = CEPH_FEATURE_SUPPORTED;
+	con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT);
+	con->out_connect.connect_seq = cpu_to_le32(con->connect_seq);
+	con->out_connect.global_seq = cpu_to_le32(global_seq);
+	con->out_connect.protocol_version = cpu_to_le32(proto);
+	con->out_connect.flags = 0;
+
+	if (!after_banner) {
+		con->out_kvec_left = 0;
+		con->out_kvec_bytes = 0;
+	}
+	con->out_kvec[con->out_kvec_left].iov_base = &con->out_connect;
+	con->out_kvec[con->out_kvec_left].iov_len = sizeof(con->out_connect);
+	con->out_kvec_left++;
+	con->out_kvec_bytes += sizeof(con->out_connect);
+	con->out_kvec_cur = con->out_kvec;
+	con->out_more = 0;
+	set_bit(WRITE_PENDING, &con->state);
+
+	prepare_connect_authorizer(con);
+}
+
+
+/*
+ * write as much of pending kvecs to the socket as we can.
+ *  1 -> done
+ *  0 -> socket full, but more to do
+ * <0 -> error
+ */
+static int write_partial_kvec(struct ceph_connection *con)
+{
+	int ret;
+
+	dout("write_partial_kvec %p %d left\n", con, con->out_kvec_bytes);
+	while (con->out_kvec_bytes > 0) {
+		ret = ceph_tcp_sendmsg(con->sock, con->out_kvec_cur,
+				       con->out_kvec_left, con->out_kvec_bytes,
+				       con->out_more);
+		if (ret <= 0)
+			goto out;
+		con->out_kvec_bytes -= ret;
+		if (con->out_kvec_bytes == 0)
+			break;            /* done */
+		while (ret > 0) {
+			if (ret >= con->out_kvec_cur->iov_len) {
+				ret -= con->out_kvec_cur->iov_len;
+				con->out_kvec_cur++;
+				con->out_kvec_left--;
+			} else {
+				con->out_kvec_cur->iov_len -= ret;
+				con->out_kvec_cur->iov_base += ret;
+				ret = 0;
+				break;
+			}
+		}
+	}
+	con->out_kvec_left = 0;
+	con->out_kvec_is_msg = false;
+	ret = 1;
+out:
+	dout("write_partial_kvec %p %d left in %d kvecs ret = %d\n", con,
+	     con->out_kvec_bytes, con->out_kvec_left, ret);
+	return ret;  /* done! */
+}
+
+/*
+ * Write as much message data payload as we can.  If we finish, queue
+ * up the footer.
+ *  1 -> done, footer is now queued in out_kvec[].
+ *  0 -> socket full, but more to do
+ * <0 -> error
+ */
+static int write_partial_msg_pages(struct ceph_connection *con)
+{
+	struct ceph_msg *msg = con->out_msg;
+	unsigned data_len = le32_to_cpu(msg->hdr.data_len);
+	size_t len;
+	int crc = con->msgr->nocrc;
+	int ret;
+
+	dout("write_partial_msg_pages %p msg %p page %d/%d offset %d\n",
+	     con, con->out_msg, con->out_msg_pos.page, con->out_msg->nr_pages,
+	     con->out_msg_pos.page_pos);
+
+	while (con->out_msg_pos.page < con->out_msg->nr_pages) {
+		struct page *page = NULL;
+		void *kaddr = NULL;
+
+		/*
+		 * if we are calculating the data crc (the default), we need
+		 * to map the page.  if our pages[] has been revoked, use the
+		 * zero page.
+		 */
+		if (msg->pages) {
+			page = msg->pages[con->out_msg_pos.page];
+			if (crc)
+				kaddr = kmap(page);
+		} else if (msg->pagelist) {
+			page = list_first_entry(&msg->pagelist->head,
+						struct page, lru);
+			if (crc)
+				kaddr = kmap(page);
+		} else {
+			page = con->msgr->zero_page;
+			if (crc)
+				kaddr = page_address(con->msgr->zero_page);
+		}
+		len = min((int)(PAGE_SIZE - con->out_msg_pos.page_pos),
+			  (int)(data_len - con->out_msg_pos.data_pos));
+		if (crc && !con->out_msg_pos.did_page_crc) {
+			void *base = kaddr + con->out_msg_pos.page_pos;
+			u32 tmpcrc = le32_to_cpu(con->out_msg->footer.data_crc);
+
+			BUG_ON(kaddr == NULL);
+			con->out_msg->footer.data_crc =
+				cpu_to_le32(crc32c(tmpcrc, base, len));
+			con->out_msg_pos.did_page_crc = 1;
+		}
+
+		ret = kernel_sendpage(con->sock, page,
+				      con->out_msg_pos.page_pos, len,
+				      MSG_DONTWAIT | MSG_NOSIGNAL |
+				      MSG_MORE);
+
+		if (crc && (msg->pages || msg->pagelist))
+			kunmap(page);
+
+		if (ret <= 0)
+			goto out;
+
+		con->out_msg_pos.data_pos += ret;
+		con->out_msg_pos.page_pos += ret;
+		if (ret == len) {
+			con->out_msg_pos.page_pos = 0;
+			con->out_msg_pos.page++;
+			con->out_msg_pos.did_page_crc = 0;
+			if (msg->pagelist)
+				list_move_tail(&page->lru,
+					       &msg->pagelist->head);
+		}
+	}
+
+	dout("write_partial_msg_pages %p msg %p done\n", con, msg);
+
+	/* prepare and queue up footer, too */
+	if (!crc)
+		con->out_msg->footer.flags |= CEPH_MSG_FOOTER_NOCRC;
+	con->out_kvec_bytes = 0;
+	con->out_kvec_left = 0;
+	con->out_kvec_cur = con->out_kvec;
+	prepare_write_message_footer(con, 0);
+	ret = 1;
+out:
+	return ret;
+}
+
+/*
+ * write some zeros
+ */
+static int write_partial_skip(struct ceph_connection *con)
+{
+	int ret;
+
+	while (con->out_skip > 0) {
+		struct kvec iov = {
+			.iov_base = page_address(con->msgr->zero_page),
+			.iov_len = min(con->out_skip, (int)PAGE_CACHE_SIZE)
+		};
+
+		ret = ceph_tcp_sendmsg(con->sock, &iov, 1, iov.iov_len, 1);
+		if (ret <= 0)
+			goto out;
+		con->out_skip -= ret;
+	}
+	ret = 1;
+out:
+	return ret;
+}
+
+/*
+ * Prepare to read connection handshake, or an ack.
+ */
+static void prepare_read_banner(struct ceph_connection *con)
+{
+	dout("prepare_read_banner %p\n", con);
+	con->in_base_pos = 0;
+}
+
+static void prepare_read_connect(struct ceph_connection *con)
+{
+	dout("prepare_read_connect %p\n", con);
+	con->in_base_pos = 0;
+}
+
+static void prepare_read_ack(struct ceph_connection *con)
+{
+	dout("prepare_read_ack %p\n", con);
+	con->in_base_pos = 0;
+}
+
+static void prepare_read_tag(struct ceph_connection *con)
+{
+	dout("prepare_read_tag %p\n", con);
+	con->in_base_pos = 0;
+	con->in_tag = CEPH_MSGR_TAG_READY;
+}
+
+/*
+ * Prepare to read a message.
+ */
+static int prepare_read_message(struct ceph_connection *con)
+{
+	dout("prepare_read_message %p\n", con);
+	BUG_ON(con->in_msg != NULL);
+	con->in_base_pos = 0;
+	con->in_front_crc = con->in_middle_crc = con->in_data_crc = 0;
+	return 0;
+}
+
+
+static int read_partial(struct ceph_connection *con,
+			int *to, int size, void *object)
+{
+	*to += size;
+	while (con->in_base_pos < *to) {
+		int left = *to - con->in_base_pos;
+		int have = size - left;
+		int ret = ceph_tcp_recvmsg(con->sock, object + have, left);
+		if (ret <= 0)
+			return ret;
+		con->in_base_pos += ret;
+	}
+	return 1;
+}
+
+
+/*
+ * Read all or part of the connect-side handshake on a new connection
+ */
+static int read_partial_banner(struct ceph_connection *con)
+{
+	int ret, to = 0;
+
+	dout("read_partial_banner %p at %d\n", con, con->in_base_pos);
+
+	/* peer's banner */
+	ret = read_partial(con, &to, strlen(CEPH_BANNER), con->in_banner);
+	if (ret <= 0)
+		goto out;
+	ret = read_partial(con, &to, sizeof(con->actual_peer_addr),
+			   &con->actual_peer_addr);
+	if (ret <= 0)
+		goto out;
+	ret = read_partial(con, &to, sizeof(con->peer_addr_for_me),
+			   &con->peer_addr_for_me);
+	if (ret <= 0)
+		goto out;
+out:
+	return ret;
+}
+
+static int read_partial_connect(struct ceph_connection *con)
+{
+	int ret, to = 0;
+
+	dout("read_partial_connect %p at %d\n", con, con->in_base_pos);
+
+	ret = read_partial(con, &to, sizeof(con->in_reply), &con->in_reply);
+	if (ret <= 0)
+		goto out;
+	ret = read_partial(con, &to, le32_to_cpu(con->in_reply.authorizer_len),
+			   con->auth_reply_buf);
+	if (ret <= 0)
+		goto out;
+
+	dout("read_partial_connect %p tag %d, con_seq = %u, g_seq = %u\n",
+	     con, (int)con->in_reply.tag,
+	     le32_to_cpu(con->in_reply.connect_seq),
+	     le32_to_cpu(con->in_reply.global_seq));
+out:
+	return ret;
+
+}
+
+/*
+ * Verify the hello banner looks okay.
+ */
+static int verify_hello(struct ceph_connection *con)
+{
+	if (memcmp(con->in_banner, CEPH_BANNER, strlen(CEPH_BANNER))) {
+		pr_err("connect to %s got bad banner\n",
+		       pr_addr(&con->peer_addr.in_addr));
+		con->error_msg = "protocol error, bad banner";
+		return -1;
+	}
+	return 0;
+}
+
+static bool addr_is_blank(struct sockaddr_storage *ss)
+{
+	switch (ss->ss_family) {
+	case AF_INET:
+		return ((struct sockaddr_in *)ss)->sin_addr.s_addr == 0;
+	case AF_INET6:
+		return
+		     ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[0] == 0 &&
+		     ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[1] == 0 &&
+		     ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[2] == 0 &&
+		     ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[3] == 0;
+	}
+	return false;
+}
+
+static int addr_port(struct sockaddr_storage *ss)
+{
+	switch (ss->ss_family) {
+	case AF_INET:
+		return ntohs(((struct sockaddr_in *)ss)->sin_port);
+	case AF_INET6:
+		return ntohs(((struct sockaddr_in6 *)ss)->sin6_port);
+	}
+	return 0;
+}
+
+static void addr_set_port(struct sockaddr_storage *ss, int p)
+{
+	switch (ss->ss_family) {
+	case AF_INET:
+		((struct sockaddr_in *)ss)->sin_port = htons(p);
+	case AF_INET6:
+		((struct sockaddr_in6 *)ss)->sin6_port = htons(p);
+	}
+}
+
+/*
+ * Parse an ip[:port] list into an addr array.  Use the default
+ * monitor port if a port isn't specified.
+ */
+int ceph_parse_ips(const char *c, const char *end,
+		   struct ceph_entity_addr *addr,
+		   int max_count, int *count)
+{
+	int i;
+	const char *p = c;
+
+	dout("parse_ips on '%.*s'\n", (int)(end-c), c);
+	for (i = 0; i < max_count; i++) {
+		const char *ipend;
+		struct sockaddr_storage *ss = &addr[i].in_addr;
+		struct sockaddr_in *in4 = (void *)ss;
+		struct sockaddr_in6 *in6 = (void *)ss;
+		int port;
+
+		memset(ss, 0, sizeof(*ss));
+		if (in4_pton(p, end - p, (u8 *)&in4->sin_addr.s_addr,
+			     ',', &ipend)) {
+			ss->ss_family = AF_INET;
+		} else if (in6_pton(p, end - p, (u8 *)&in6->sin6_addr.s6_addr,
+				    ',', &ipend)) {
+			ss->ss_family = AF_INET6;
+		} else {
+			goto bad;
+		}
+		p = ipend;
+
+		/* port? */
+		if (p < end && *p == ':') {
+			port = 0;
+			p++;
+			while (p < end && *p >= '0' && *p <= '9') {
+				port = (port * 10) + (*p - '0');
+				p++;
+			}
+			if (port > 65535 || port == 0)
+				goto bad;
+		} else {
+			port = CEPH_MON_PORT;
+		}
+
+		addr_set_port(ss, port);
+
+		dout("parse_ips got %s\n", pr_addr(ss));
+
+		if (p == end)
+			break;
+		if (*p != ',')
+			goto bad;
+		p++;
+	}
+
+	if (p != end)
+		goto bad;
+
+	if (count)
+		*count = i + 1;
+	return 0;
+
+bad:
+	pr_err("parse_ips bad ip '%s'\n", c);
+	return -EINVAL;
+}
+
+static int process_banner(struct ceph_connection *con)
+{
+	dout("process_banner on %p\n", con);
+
+	if (verify_hello(con) < 0)
+		return -1;
+
+	ceph_decode_addr(&con->actual_peer_addr);
+	ceph_decode_addr(&con->peer_addr_for_me);
+
+	/*
+	 * Make sure the other end is who we wanted.  note that the other
+	 * end may not yet know their ip address, so if it's 0.0.0.0, give
+	 * them the benefit of the doubt.
+	 */
+	if (memcmp(&con->peer_addr, &con->actual_peer_addr,
+		   sizeof(con->peer_addr)) != 0 &&
+	    !(addr_is_blank(&con->actual_peer_addr.in_addr) &&
+	      con->actual_peer_addr.nonce == con->peer_addr.nonce)) {
+		pr_warning("wrong peer, want %s/%lld, got %s/%lld\n",
+			   pr_addr(&con->peer_addr.in_addr),
+			   le64_to_cpu(con->peer_addr.nonce),
+			   pr_addr(&con->actual_peer_addr.in_addr),
+			   le64_to_cpu(con->actual_peer_addr.nonce));
+		con->error_msg = "wrong peer at address";
+		return -1;
+	}
+
+	/*
+	 * did we learn our address?
+	 */
+	if (addr_is_blank(&con->msgr->inst.addr.in_addr)) {
+		int port = addr_port(&con->msgr->inst.addr.in_addr);
+
+		memcpy(&con->msgr->inst.addr.in_addr,
+		       &con->peer_addr_for_me.in_addr,
+		       sizeof(con->peer_addr_for_me.in_addr));
+		addr_set_port(&con->msgr->inst.addr.in_addr, port);
+		encode_my_addr(con->msgr);
+		dout("process_banner learned my addr is %s\n",
+		     pr_addr(&con->msgr->inst.addr.in_addr));
+	}
+
+	set_bit(NEGOTIATING, &con->state);
+	prepare_read_connect(con);
+	return 0;
+}
+
+static void fail_protocol(struct ceph_connection *con)
+{
+	reset_connection(con);
+	set_bit(CLOSED, &con->state);  /* in case there's queued work */
+
+	mutex_unlock(&con->mutex);
+	if (con->ops->bad_proto)
+		con->ops->bad_proto(con);
+	mutex_lock(&con->mutex);
+}
+
+static int process_connect(struct ceph_connection *con)
+{
+	u64 sup_feat = CEPH_FEATURE_SUPPORTED;
+	u64 req_feat = CEPH_FEATURE_REQUIRED;
+	u64 server_feat = le64_to_cpu(con->in_reply.features);
+
+	dout("process_connect on %p tag %d\n", con, (int)con->in_tag);
+
+	switch (con->in_reply.tag) {
+	case CEPH_MSGR_TAG_FEATURES:
+		pr_err("%s%lld %s feature set mismatch,"
+		       " my %llx < server's %llx, missing %llx\n",
+		       ENTITY_NAME(con->peer_name),
+		       pr_addr(&con->peer_addr.in_addr),
+		       sup_feat, server_feat, server_feat & ~sup_feat);
+		con->error_msg = "missing required protocol features";
+		fail_protocol(con);
+		return -1;
+
+	case CEPH_MSGR_TAG_BADPROTOVER:
+		pr_err("%s%lld %s protocol version mismatch,"
+		       " my %d != server's %d\n",
+		       ENTITY_NAME(con->peer_name),
+		       pr_addr(&con->peer_addr.in_addr),
+		       le32_to_cpu(con->out_connect.protocol_version),
+		       le32_to_cpu(con->in_reply.protocol_version));
+		con->error_msg = "protocol version mismatch";
+		fail_protocol(con);
+		return -1;
+
+	case CEPH_MSGR_TAG_BADAUTHORIZER:
+		con->auth_retry++;
+		dout("process_connect %p got BADAUTHORIZER attempt %d\n", con,
+		     con->auth_retry);
+		if (con->auth_retry == 2) {
+			con->error_msg = "connect authorization failure";
+			reset_connection(con);
+			set_bit(CLOSED, &con->state);
+			return -1;
+		}
+		con->auth_retry = 1;
+		prepare_write_connect(con->msgr, con, 0);
+		prepare_read_connect(con);
+		break;
+
+	case CEPH_MSGR_TAG_RESETSESSION:
+		/*
+		 * If we connected with a large connect_seq but the peer
+		 * has no record of a session with us (no connection, or
+		 * connect_seq == 0), they will send RESETSESION to indicate
+		 * that they must have reset their session, and may have
+		 * dropped messages.
+		 */
+		dout("process_connect got RESET peer seq %u\n",
+		     le32_to_cpu(con->in_connect.connect_seq));
+		pr_err("%s%lld %s connection reset\n",
+		       ENTITY_NAME(con->peer_name),
+		       pr_addr(&con->peer_addr.in_addr));
+		reset_connection(con);
+		prepare_write_connect(con->msgr, con, 0);
+		prepare_read_connect(con);
+
+		/* Tell ceph about it. */
+		mutex_unlock(&con->mutex);
+		pr_info("reset on %s%lld\n", ENTITY_NAME(con->peer_name));
+		if (con->ops->peer_reset)
+			con->ops->peer_reset(con);
+		mutex_lock(&con->mutex);
+		break;
+
+	case CEPH_MSGR_TAG_RETRY_SESSION:
+		/*
+		 * If we sent a smaller connect_seq than the peer has, try
+		 * again with a larger value.
+		 */
+		dout("process_connect got RETRY my seq = %u, peer_seq = %u\n",
+		     le32_to_cpu(con->out_connect.connect_seq),
+		     le32_to_cpu(con->in_connect.connect_seq));
+		con->connect_seq = le32_to_cpu(con->in_connect.connect_seq);
+		prepare_write_connect(con->msgr, con, 0);
+		prepare_read_connect(con);
+		break;
+
+	case CEPH_MSGR_TAG_RETRY_GLOBAL:
+		/*
+		 * If we sent a smaller global_seq than the peer has, try
+		 * again with a larger value.
+		 */
+		dout("process_connect got RETRY_GLOBAL my %u peer_gseq %u\n",
+		     con->peer_global_seq,
+		     le32_to_cpu(con->in_connect.global_seq));
+		get_global_seq(con->msgr,
+			       le32_to_cpu(con->in_connect.global_seq));
+		prepare_write_connect(con->msgr, con, 0);
+		prepare_read_connect(con);
+		break;
+
+	case CEPH_MSGR_TAG_READY:
+		if (req_feat & ~server_feat) {
+			pr_err("%s%lld %s protocol feature mismatch,"
+			       " my required %llx > server's %llx, need %llx\n",
+			       ENTITY_NAME(con->peer_name),
+			       pr_addr(&con->peer_addr.in_addr),
+			       req_feat, server_feat, req_feat & ~server_feat);
+			con->error_msg = "missing required protocol features";
+			fail_protocol(con);
+			return -1;
+		}
+		clear_bit(CONNECTING, &con->state);
+		con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq);
+		con->connect_seq++;
+		dout("process_connect got READY gseq %d cseq %d (%d)\n",
+		     con->peer_global_seq,
+		     le32_to_cpu(con->in_reply.connect_seq),
+		     con->connect_seq);
+		WARN_ON(con->connect_seq !=
+			le32_to_cpu(con->in_reply.connect_seq));
+
+		if (con->in_reply.flags & CEPH_MSG_CONNECT_LOSSY)
+			set_bit(LOSSYTX, &con->state);
+
+		prepare_read_tag(con);
+		break;
+
+	case CEPH_MSGR_TAG_WAIT:
+		/*
+		 * If there is a connection race (we are opening
+		 * connections to each other), one of us may just have
+		 * to WAIT.  This shouldn't happen if we are the
+		 * client.
+		 */
+		pr_err("process_connect peer connecting WAIT\n");
+
+	default:
+		pr_err("connect protocol error, will retry\n");
+		con->error_msg = "protocol error, garbage tag during connect";
+		return -1;
+	}
+	return 0;
+}
+
+
+/*
+ * read (part of) an ack
+ */
+static int read_partial_ack(struct ceph_connection *con)
+{
+	int to = 0;
+
+	return read_partial(con, &to, sizeof(con->in_temp_ack),
+			    &con->in_temp_ack);
+}
+
+
+/*
+ * We can finally discard anything that's been acked.
+ */
+static void process_ack(struct ceph_connection *con)
+{
+	struct ceph_msg *m;
+	u64 ack = le64_to_cpu(con->in_temp_ack);
+	u64 seq;
+
+	while (!list_empty(&con->out_sent)) {
+		m = list_first_entry(&con->out_sent, struct ceph_msg,
+				     list_head);
+		seq = le64_to_cpu(m->hdr.seq);
+		if (seq > ack)
+			break;
+		dout("got ack for seq %llu type %d at %p\n", seq,
+		     le16_to_cpu(m->hdr.type), m);
+		ceph_msg_remove(m);
+	}
+	prepare_read_tag(con);
+}
+
+
+
+
+static int read_partial_message_section(struct ceph_connection *con,
+					struct kvec *section, unsigned int sec_len,
+					u32 *crc)
+{
+	int left;
+	int ret;
+
+	BUG_ON(!section);
+
+	while (section->iov_len < sec_len) {
+		BUG_ON(section->iov_base == NULL);
+		left = sec_len - section->iov_len;
+		ret = ceph_tcp_recvmsg(con->sock, (char *)section->iov_base +
+				       section->iov_len, left);
+		if (ret <= 0)
+			return ret;
+		section->iov_len += ret;
+		if (section->iov_len == sec_len)
+			*crc = crc32c(0, section->iov_base,
+				      section->iov_len);
+	}
+
+	return 1;
+}
+
+static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con,
+				struct ceph_msg_header *hdr,
+				int *skip);
+/*
+ * read (part of) a message.
+ */
+static int read_partial_message(struct ceph_connection *con)
+{
+	struct ceph_msg *m = con->in_msg;
+	void *p;
+	int ret;
+	int to, left;
+	unsigned front_len, middle_len, data_len, data_off;
+	int datacrc = con->msgr->nocrc;
+	int skip;
+	u64 seq;
+
+	dout("read_partial_message con %p msg %p\n", con, m);
+
+	/* header */
+	while (con->in_base_pos < sizeof(con->in_hdr)) {
+		left = sizeof(con->in_hdr) - con->in_base_pos;
+		ret = ceph_tcp_recvmsg(con->sock,
+				       (char *)&con->in_hdr + con->in_base_pos,
+				       left);
+		if (ret <= 0)
+			return ret;
+		con->in_base_pos += ret;
+		if (con->in_base_pos == sizeof(con->in_hdr)) {
+			u32 crc = crc32c(0, (void *)&con->in_hdr,
+				 sizeof(con->in_hdr) - sizeof(con->in_hdr.crc));
+			if (crc != le32_to_cpu(con->in_hdr.crc)) {
+				pr_err("read_partial_message bad hdr "
+				       " crc %u != expected %u\n",
+				       crc, con->in_hdr.crc);
+				return -EBADMSG;
+			}
+		}
+	}
+	front_len = le32_to_cpu(con->in_hdr.front_len);
+	if (front_len > CEPH_MSG_MAX_FRONT_LEN)
+		return -EIO;
+	middle_len = le32_to_cpu(con->in_hdr.middle_len);
+	if (middle_len > CEPH_MSG_MAX_DATA_LEN)
+		return -EIO;
+	data_len = le32_to_cpu(con->in_hdr.data_len);
+	if (data_len > CEPH_MSG_MAX_DATA_LEN)
+		return -EIO;
+	data_off = le16_to_cpu(con->in_hdr.data_off);
+
+	/* verify seq# */
+	seq = le64_to_cpu(con->in_hdr.seq);
+	if ((s64)seq - (s64)con->in_seq < 1) {
+		pr_info("skipping %s%lld %s seq %lld, expected %lld\n",
+			ENTITY_NAME(con->peer_name),
+			pr_addr(&con->peer_addr.in_addr),
+			seq, con->in_seq + 1);
+		con->in_base_pos = -front_len - middle_len - data_len -
+			sizeof(m->footer);
+		con->in_tag = CEPH_MSGR_TAG_READY;
+		con->in_seq++;
+		return 0;
+	} else if ((s64)seq - (s64)con->in_seq > 1) {
+		pr_err("read_partial_message bad seq %lld expected %lld\n",
+		       seq, con->in_seq + 1);
+		con->error_msg = "bad message sequence # for incoming message";
+		return -EBADMSG;
+	}
+
+	/* allocate message? */
+	if (!con->in_msg) {
+		dout("got hdr type %d front %d data %d\n", con->in_hdr.type,
+		     con->in_hdr.front_len, con->in_hdr.data_len);
+		con->in_msg = ceph_alloc_msg(con, &con->in_hdr, &skip);
+		if (skip) {
+			/* skip this message */
+			dout("alloc_msg returned NULL, skipping message\n");
+			con->in_base_pos = -front_len - middle_len - data_len -
+				sizeof(m->footer);
+			con->in_tag = CEPH_MSGR_TAG_READY;
+			con->in_seq++;
+			return 0;
+		}
+		if (IS_ERR(con->in_msg)) {
+			ret = PTR_ERR(con->in_msg);
+			con->in_msg = NULL;
+			con->error_msg =
+				"error allocating memory for incoming message";
+			return ret;
+		}
+		m = con->in_msg;
+		m->front.iov_len = 0;    /* haven't read it yet */
+		if (m->middle)
+			m->middle->vec.iov_len = 0;
+
+		con->in_msg_pos.page = 0;
+		con->in_msg_pos.page_pos = data_off & ~PAGE_MASK;
+		con->in_msg_pos.data_pos = 0;
+	}
+
+	/* front */
+	ret = read_partial_message_section(con, &m->front, front_len,
+					   &con->in_front_crc);
+	if (ret <= 0)
+		return ret;
+
+	/* middle */
+	if (m->middle) {
+		ret = read_partial_message_section(con, &m->middle->vec, middle_len,
+						   &con->in_middle_crc);
+		if (ret <= 0)
+			return ret;
+	}
+
+	/* (page) data */
+	while (con->in_msg_pos.data_pos < data_len) {
+		left = min((int)(data_len - con->in_msg_pos.data_pos),
+			   (int)(PAGE_SIZE - con->in_msg_pos.page_pos));
+		BUG_ON(m->pages == NULL);
+		p = kmap(m->pages[con->in_msg_pos.page]);
+		ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos,
+				       left);
+		if (ret > 0 && datacrc)
+			con->in_data_crc =
+				crc32c(con->in_data_crc,
+					  p + con->in_msg_pos.page_pos, ret);
+		kunmap(m->pages[con->in_msg_pos.page]);
+		if (ret <= 0)
+			return ret;
+		con->in_msg_pos.data_pos += ret;
+		con->in_msg_pos.page_pos += ret;
+		if (con->in_msg_pos.page_pos == PAGE_SIZE) {
+			con->in_msg_pos.page_pos = 0;
+			con->in_msg_pos.page++;
+		}
+	}
+
+	/* footer */
+	to = sizeof(m->hdr) + sizeof(m->footer);
+	while (con->in_base_pos < to) {
+		left = to - con->in_base_pos;
+		ret = ceph_tcp_recvmsg(con->sock, (char *)&m->footer +
+				       (con->in_base_pos - sizeof(m->hdr)),
+				       left);
+		if (ret <= 0)
+			return ret;
+		con->in_base_pos += ret;
+	}
+	dout("read_partial_message got msg %p %d (%u) + %d (%u) + %d (%u)\n",
+	     m, front_len, m->footer.front_crc, middle_len,
+	     m->footer.middle_crc, data_len, m->footer.data_crc);
+
+	/* crc ok? */
+	if (con->in_front_crc != le32_to_cpu(m->footer.front_crc)) {
+		pr_err("read_partial_message %p front crc %u != exp. %u\n",
+		       m, con->in_front_crc, m->footer.front_crc);
+		return -EBADMSG;
+	}
+	if (con->in_middle_crc != le32_to_cpu(m->footer.middle_crc)) {
+		pr_err("read_partial_message %p middle crc %u != exp %u\n",
+		       m, con->in_middle_crc, m->footer.middle_crc);
+		return -EBADMSG;
+	}
+	if (datacrc &&
+	    (m->footer.flags & CEPH_MSG_FOOTER_NOCRC) == 0 &&
+	    con->in_data_crc != le32_to_cpu(m->footer.data_crc)) {
+		pr_err("read_partial_message %p data crc %u != exp. %u\n", m,
+		       con->in_data_crc, le32_to_cpu(m->footer.data_crc));
+		return -EBADMSG;
+	}
+
+	return 1; /* done! */
+}
+
+/*
+ * Process message.  This happens in the worker thread.  The callback should
+ * be careful not to do anything that waits on other incoming messages or it
+ * may deadlock.
+ */
+static void process_message(struct ceph_connection *con)
+{
+	struct ceph_msg *msg;
+
+	msg = con->in_msg;
+	con->in_msg = NULL;
+
+	/* if first message, set peer_name */
+	if (con->peer_name.type == 0)
+		con->peer_name = msg->hdr.src.name;
+
+	con->in_seq++;
+	mutex_unlock(&con->mutex);
+
+	dout("===== %p %llu from %s%lld %d=%s len %d+%d (%u %u %u) =====\n",
+	     msg, le64_to_cpu(msg->hdr.seq),
+	     ENTITY_NAME(msg->hdr.src.name),
+	     le16_to_cpu(msg->hdr.type),
+	     ceph_msg_type_name(le16_to_cpu(msg->hdr.type)),
+	     le32_to_cpu(msg->hdr.front_len),
+	     le32_to_cpu(msg->hdr.data_len),
+	     con->in_front_crc, con->in_middle_crc, con->in_data_crc);
+	con->ops->dispatch(con, msg);
+
+	mutex_lock(&con->mutex);
+	prepare_read_tag(con);
+}
+
+
+/*
+ * Write something to the socket.  Called in a worker thread when the
+ * socket appears to be writeable and we have something ready to send.
+ */
+static int try_write(struct ceph_connection *con)
+{
+	struct ceph_messenger *msgr = con->msgr;
+	int ret = 1;
+
+	dout("try_write start %p state %lu nref %d\n", con, con->state,
+	     atomic_read(&con->nref));
+
+	mutex_lock(&con->mutex);
+more:
+	dout("try_write out_kvec_bytes %d\n", con->out_kvec_bytes);
+
+	/* open the socket first? */
+	if (con->sock == NULL) {
+		/*
+		 * if we were STANDBY and are reconnecting _this_
+		 * connection, bump connect_seq now.  Always bump
+		 * global_seq.
+		 */
+		if (test_and_clear_bit(STANDBY, &con->state))
+			con->connect_seq++;
+
+		prepare_write_banner(msgr, con);
+		prepare_write_connect(msgr, con, 1);
+		prepare_read_banner(con);
+		set_bit(CONNECTING, &con->state);
+		clear_bit(NEGOTIATING, &con->state);
+
+		BUG_ON(con->in_msg);
+		con->in_tag = CEPH_MSGR_TAG_READY;
+		dout("try_write initiating connect on %p new state %lu\n",
+		     con, con->state);
+		con->sock = ceph_tcp_connect(con);
+		if (IS_ERR(con->sock)) {
+			con->sock = NULL;
+			con->error_msg = "connect error";
+			ret = -1;
+			goto out;
+		}
+	}
+
+more_kvec:
+	/* kvec data queued? */
+	if (con->out_skip) {
+		ret = write_partial_skip(con);
+		if (ret <= 0)
+			goto done;
+		if (ret < 0) {
+			dout("try_write write_partial_skip err %d\n", ret);
+			goto done;
+		}
+	}
+	if (con->out_kvec_left) {
+		ret = write_partial_kvec(con);
+		if (ret <= 0)
+			goto done;
+	}
+
+	/* msg pages? */
+	if (con->out_msg) {
+		if (con->out_msg_done) {
+			ceph_msg_put(con->out_msg);
+			con->out_msg = NULL;   /* we're done with this one */
+			goto do_next;
+		}
+
+		ret = write_partial_msg_pages(con);
+		if (ret == 1)
+			goto more_kvec;  /* we need to send the footer, too! */
+		if (ret == 0)
+			goto done;
+		if (ret < 0) {
+			dout("try_write write_partial_msg_pages err %d\n",
+			     ret);
+			goto done;
+		}
+	}
+
+do_next:
+	if (!test_bit(CONNECTING, &con->state)) {
+		/* is anything else pending? */
+		if (!list_empty(&con->out_queue)) {
+			prepare_write_message(con);
+			goto more;
+		}
+		if (con->in_seq > con->in_seq_acked) {
+			prepare_write_ack(con);
+			goto more;
+		}
+		if (test_and_clear_bit(KEEPALIVE_PENDING, &con->state)) {
+			prepare_write_keepalive(con);
+			goto more;
+		}
+	}
+
+	/* Nothing to do! */
+	clear_bit(WRITE_PENDING, &con->state);
+	dout("try_write nothing else to write.\n");
+done:
+	ret = 0;
+out:
+	mutex_unlock(&con->mutex);
+	dout("try_write done on %p\n", con);
+	return ret;
+}
+
+
+
+/*
+ * Read what we can from the socket.
+ */
+static int try_read(struct ceph_connection *con)
+{
+	struct ceph_messenger *msgr;
+	int ret = -1;
+
+	if (!con->sock)
+		return 0;
+
+	if (test_bit(STANDBY, &con->state))
+		return 0;
+
+	dout("try_read start on %p\n", con);
+	msgr = con->msgr;
+
+	mutex_lock(&con->mutex);
+
+more:
+	dout("try_read tag %d in_base_pos %d\n", (int)con->in_tag,
+	     con->in_base_pos);
+	if (test_bit(CONNECTING, &con->state)) {
+		if (!test_bit(NEGOTIATING, &con->state)) {
+			dout("try_read connecting\n");
+			ret = read_partial_banner(con);
+			if (ret <= 0)
+				goto done;
+			if (process_banner(con) < 0) {
+				ret = -1;
+				goto out;
+			}
+		}
+		ret = read_partial_connect(con);
+		if (ret <= 0)
+			goto done;
+		if (process_connect(con) < 0) {
+			ret = -1;
+			goto out;
+		}
+		goto more;
+	}
+
+	if (con->in_base_pos < 0) {
+		/*
+		 * skipping + discarding content.
+		 *
+		 * FIXME: there must be a better way to do this!
+		 */
+		static char buf[1024];
+		int skip = min(1024, -con->in_base_pos);
+		dout("skipping %d / %d bytes\n", skip, -con->in_base_pos);
+		ret = ceph_tcp_recvmsg(con->sock, buf, skip);
+		if (ret <= 0)
+			goto done;
+		con->in_base_pos += ret;
+		if (con->in_base_pos)
+			goto more;
+	}
+	if (con->in_tag == CEPH_MSGR_TAG_READY) {
+		/*
+		 * what's next?
+		 */
+		ret = ceph_tcp_recvmsg(con->sock, &con->in_tag, 1);
+		if (ret <= 0)
+			goto done;
+		dout("try_read got tag %d\n", (int)con->in_tag);
+		switch (con->in_tag) {
+		case CEPH_MSGR_TAG_MSG:
+			prepare_read_message(con);
+			break;
+		case CEPH_MSGR_TAG_ACK:
+			prepare_read_ack(con);
+			break;
+		case CEPH_MSGR_TAG_CLOSE:
+			set_bit(CLOSED, &con->state);   /* fixme */
+			goto done;
+		default:
+			goto bad_tag;
+		}
+	}
+	if (con->in_tag == CEPH_MSGR_TAG_MSG) {
+		ret = read_partial_message(con);
+		if (ret <= 0) {
+			switch (ret) {
+			case -EBADMSG:
+				con->error_msg = "bad crc";
+				ret = -EIO;
+				goto out;
+			case -EIO:
+				con->error_msg = "io error";
+				goto out;
+			default:
+				goto done;
+			}
+		}
+		if (con->in_tag == CEPH_MSGR_TAG_READY)
+			goto more;
+		process_message(con);
+		goto more;
+	}
+	if (con->in_tag == CEPH_MSGR_TAG_ACK) {
+		ret = read_partial_ack(con);
+		if (ret <= 0)
+			goto done;
+		process_ack(con);
+		goto more;
+	}
+
+done:
+	ret = 0;
+out:
+	mutex_unlock(&con->mutex);
+	dout("try_read done on %p\n", con);
+	return ret;
+
+bad_tag:
+	pr_err("try_read bad con->in_tag = %d\n", (int)con->in_tag);
+	con->error_msg = "protocol error, garbage tag";
+	ret = -1;
+	goto out;
+}
+
+
+/*
+ * Atomically queue work on a connection.  Bump @con reference to
+ * avoid races with connection teardown.
+ *
+ * There is some trickery going on with QUEUED and BUSY because we
+ * only want a _single_ thread operating on each connection at any
+ * point in time, but we want to use all available CPUs.
+ *
+ * The worker thread only proceeds if it can atomically set BUSY.  It
+ * clears QUEUED and does it's thing.  When it thinks it's done, it
+ * clears BUSY, then rechecks QUEUED.. if it's set again, it loops
+ * (tries again to set BUSY).
+ *
+ * To queue work, we first set QUEUED, _then_ if BUSY isn't set, we
+ * try to queue work.  If that fails (work is already queued, or BUSY)
+ * we give up (work also already being done or is queued) but leave QUEUED
+ * set so that the worker thread will loop if necessary.
+ */
+static void queue_con(struct ceph_connection *con)
+{
+	if (test_bit(DEAD, &con->state)) {
+		dout("queue_con %p ignoring: DEAD\n",
+		     con);
+		return;
+	}
+
+	if (!con->ops->get(con)) {
+		dout("queue_con %p ref count 0\n", con);
+		return;
+	}
+
+	set_bit(QUEUED, &con->state);
+	if (test_bit(BUSY, &con->state)) {
+		dout("queue_con %p - already BUSY\n", con);
+		con->ops->put(con);
+	} else if (!queue_work(ceph_msgr_wq, &con->work.work)) {
+		dout("queue_con %p - already queued\n", con);
+		con->ops->put(con);
+	} else {
+		dout("queue_con %p\n", con);
+	}
+}
+
+/*
+ * Do some work on a connection.  Drop a connection ref when we're done.
+ */
+static void con_work(struct work_struct *work)
+{
+	struct ceph_connection *con = container_of(work, struct ceph_connection,
+						   work.work);
+	int backoff = 0;
+
+more:
+	if (test_and_set_bit(BUSY, &con->state) != 0) {
+		dout("con_work %p BUSY already set\n", con);
+		goto out;
+	}
+	dout("con_work %p start, clearing QUEUED\n", con);
+	clear_bit(QUEUED, &con->state);
+
+	if (test_bit(CLOSED, &con->state)) { /* e.g. if we are replaced */
+		dout("con_work CLOSED\n");
+		con_close_socket(con);
+		goto done;
+	}
+	if (test_and_clear_bit(OPENING, &con->state)) {
+		/* reopen w/ new peer */
+		dout("con_work OPENING\n");
+		con_close_socket(con);
+	}
+
+	if (test_and_clear_bit(SOCK_CLOSED, &con->state) ||
+	    try_read(con) < 0 ||
+	    try_write(con) < 0) {
+		backoff = 1;
+		ceph_fault(con);     /* error/fault path */
+	}
+
+done:
+	clear_bit(BUSY, &con->state);
+	dout("con->state=%lu\n", con->state);
+	if (test_bit(QUEUED, &con->state)) {
+		if (!backoff || test_bit(OPENING, &con->state)) {
+			dout("con_work %p QUEUED reset, looping\n", con);
+			goto more;
+		}
+		dout("con_work %p QUEUED reset, but just faulted\n", con);
+		clear_bit(QUEUED, &con->state);
+	}
+	dout("con_work %p done\n", con);
+
+out:
+	con->ops->put(con);
+}
+
+
+/*
+ * Generic error/fault handler.  A retry mechanism is used with
+ * exponential backoff
+ */
+static void ceph_fault(struct ceph_connection *con)
+{
+	pr_err("%s%lld %s %s\n", ENTITY_NAME(con->peer_name),
+	       pr_addr(&con->peer_addr.in_addr), con->error_msg);
+	dout("fault %p state %lu to peer %s\n",
+	     con, con->state, pr_addr(&con->peer_addr.in_addr));
+
+	if (test_bit(LOSSYTX, &con->state)) {
+		dout("fault on LOSSYTX channel\n");
+		goto out;
+	}
+
+	mutex_lock(&con->mutex);
+	if (test_bit(CLOSED, &con->state))
+		goto out_unlock;
+
+	con_close_socket(con);
+
+	if (con->in_msg) {
+		ceph_msg_put(con->in_msg);
+		con->in_msg = NULL;
+	}
+
+	/* Requeue anything that hasn't been acked */
+	list_splice_init(&con->out_sent, &con->out_queue);
+
+	/* If there are no messages in the queue, place the connection
+	 * in a STANDBY state (i.e., don't try to reconnect just yet). */
+	if (list_empty(&con->out_queue) && !con->out_keepalive_pending) {
+		dout("fault setting STANDBY\n");
+		set_bit(STANDBY, &con->state);
+	} else {
+		/* retry after a delay. */
+		if (con->delay == 0)
+			con->delay = BASE_DELAY_INTERVAL;
+		else if (con->delay < MAX_DELAY_INTERVAL)
+			con->delay *= 2;
+		dout("fault queueing %p delay %lu\n", con, con->delay);
+		con->ops->get(con);
+		if (queue_delayed_work(ceph_msgr_wq, &con->work,
+				       round_jiffies_relative(con->delay)) == 0)
+			con->ops->put(con);
+	}
+
+out_unlock:
+	mutex_unlock(&con->mutex);
+out:
+	/*
+	 * in case we faulted due to authentication, invalidate our
+	 * current tickets so that we can get new ones.
+         */
+	if (con->auth_retry && con->ops->invalidate_authorizer) {
+		dout("calling invalidate_authorizer()\n");
+		con->ops->invalidate_authorizer(con);
+	}
+
+	if (con->ops->fault)
+		con->ops->fault(con);
+}
+
+
+
+/*
+ * create a new messenger instance
+ */
+struct ceph_messenger *ceph_messenger_create(struct ceph_entity_addr *myaddr)
+{
+	struct ceph_messenger *msgr;
+
+	msgr = kzalloc(sizeof(*msgr), GFP_KERNEL);
+	if (msgr == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	spin_lock_init(&msgr->global_seq_lock);
+
+	/* the zero page is needed if a request is "canceled" while the message
+	 * is being written over the socket */
+	msgr->zero_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+	if (!msgr->zero_page) {
+		kfree(msgr);
+		return ERR_PTR(-ENOMEM);
+	}
+	kmap(msgr->zero_page);
+
+	if (myaddr)
+		msgr->inst.addr = *myaddr;
+
+	/* select a random nonce */
+	msgr->inst.addr.type = 0;
+	get_random_bytes(&msgr->inst.addr.nonce, sizeof(msgr->inst.addr.nonce));
+	encode_my_addr(msgr);
+
+	dout("messenger_create %p\n", msgr);
+	return msgr;
+}
+
+void ceph_messenger_destroy(struct ceph_messenger *msgr)
+{
+	dout("destroy %p\n", msgr);
+	kunmap(msgr->zero_page);
+	__free_page(msgr->zero_page);
+	kfree(msgr);
+	dout("destroyed messenger %p\n", msgr);
+}
+
+/*
+ * Queue up an outgoing message on the given connection.
+ */
+void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg)
+{
+	if (test_bit(CLOSED, &con->state)) {
+		dout("con_send %p closed, dropping %p\n", con, msg);
+		ceph_msg_put(msg);
+		return;
+	}
+
+	/* set src+dst */
+	msg->hdr.src.name = con->msgr->inst.name;
+	msg->hdr.src.addr = con->msgr->my_enc_addr;
+	msg->hdr.orig_src = msg->hdr.src;
+
+	BUG_ON(msg->front.iov_len != le32_to_cpu(msg->hdr.front_len));
+
+	msg->needs_out_seq = true;
+
+	/* queue */
+	mutex_lock(&con->mutex);
+	BUG_ON(!list_empty(&msg->list_head));
+	list_add_tail(&msg->list_head, &con->out_queue);
+	dout("----- %p to %s%lld %d=%s len %d+%d+%d -----\n", msg,
+	     ENTITY_NAME(con->peer_name), le16_to_cpu(msg->hdr.type),
+	     ceph_msg_type_name(le16_to_cpu(msg->hdr.type)),
+	     le32_to_cpu(msg->hdr.front_len),
+	     le32_to_cpu(msg->hdr.middle_len),
+	     le32_to_cpu(msg->hdr.data_len));
+	mutex_unlock(&con->mutex);
+
+	/* if there wasn't anything waiting to send before, queue
+	 * new work */
+	if (test_and_set_bit(WRITE_PENDING, &con->state) == 0)
+		queue_con(con);
+}
+
+/*
+ * Revoke a message that was previously queued for send
+ */
+void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg)
+{
+	mutex_lock(&con->mutex);
+	if (!list_empty(&msg->list_head)) {
+		dout("con_revoke %p msg %p\n", con, msg);
+		list_del_init(&msg->list_head);
+		ceph_msg_put(msg);
+		msg->hdr.seq = 0;
+		if (con->out_msg == msg) {
+			ceph_msg_put(con->out_msg);
+			con->out_msg = NULL;
+		}
+		if (con->out_kvec_is_msg) {
+			con->out_skip = con->out_kvec_bytes;
+			con->out_kvec_is_msg = false;
+		}
+	} else {
+		dout("con_revoke %p msg %p - not queued (sent?)\n", con, msg);
+	}
+	mutex_unlock(&con->mutex);
+}
+
+/*
+ * Revoke a message that we may be reading data into
+ */
+void ceph_con_revoke_message(struct ceph_connection *con, struct ceph_msg *msg)
+{
+	mutex_lock(&con->mutex);
+	if (con->in_msg && con->in_msg == msg) {
+		unsigned front_len = le32_to_cpu(con->in_hdr.front_len);
+		unsigned middle_len = le32_to_cpu(con->in_hdr.middle_len);
+		unsigned data_len = le32_to_cpu(con->in_hdr.data_len);
+
+		/* skip rest of message */
+		dout("con_revoke_pages %p msg %p revoked\n", con, msg);
+			con->in_base_pos = con->in_base_pos -
+				sizeof(struct ceph_msg_header) -
+				front_len -
+				middle_len -
+				data_len -
+				sizeof(struct ceph_msg_footer);
+		ceph_msg_put(con->in_msg);
+		con->in_msg = NULL;
+		con->in_tag = CEPH_MSGR_TAG_READY;
+		con->in_seq++;
+	} else {
+		dout("con_revoke_pages %p msg %p pages %p no-op\n",
+		     con, con->in_msg, msg);
+	}
+	mutex_unlock(&con->mutex);
+}
+
+/*
+ * Queue a keepalive byte to ensure the tcp connection is alive.
+ */
+void ceph_con_keepalive(struct ceph_connection *con)
+{
+	if (test_and_set_bit(KEEPALIVE_PENDING, &con->state) == 0 &&
+	    test_and_set_bit(WRITE_PENDING, &con->state) == 0)
+		queue_con(con);
+}
+
+
+/*
+ * construct a new message with given type, size
+ * the new msg has a ref count of 1.
+ */
+struct ceph_msg *ceph_msg_new(int type, int front_len,
+			      int page_len, int page_off, struct page **pages)
+{
+	struct ceph_msg *m;
+
+	m = kmalloc(sizeof(*m), GFP_NOFS);
+	if (m == NULL)
+		goto out;
+	kref_init(&m->kref);
+	INIT_LIST_HEAD(&m->list_head);
+
+	m->hdr.tid = 0;
+	m->hdr.type = cpu_to_le16(type);
+	m->hdr.priority = cpu_to_le16(CEPH_MSG_PRIO_DEFAULT);
+	m->hdr.version = 0;
+	m->hdr.front_len = cpu_to_le32(front_len);
+	m->hdr.middle_len = 0;
+	m->hdr.data_len = cpu_to_le32(page_len);
+	m->hdr.data_off = cpu_to_le16(page_off);
+	m->hdr.reserved = 0;
+	m->footer.front_crc = 0;
+	m->footer.middle_crc = 0;
+	m->footer.data_crc = 0;
+	m->footer.flags = 0;
+	m->front_max = front_len;
+	m->front_is_vmalloc = false;
+	m->more_to_follow = false;
+	m->pool = NULL;
+
+	/* front */
+	if (front_len) {
+		if (front_len > PAGE_CACHE_SIZE) {
+			m->front.iov_base = __vmalloc(front_len, GFP_NOFS,
+						      PAGE_KERNEL);
+			m->front_is_vmalloc = true;
+		} else {
+			m->front.iov_base = kmalloc(front_len, GFP_NOFS);
+		}
+		if (m->front.iov_base == NULL) {
+			pr_err("msg_new can't allocate %d bytes\n",
+			     front_len);
+			goto out2;
+		}
+	} else {
+		m->front.iov_base = NULL;
+	}
+	m->front.iov_len = front_len;
+
+	/* middle */
+	m->middle = NULL;
+
+	/* data */
+	m->nr_pages = calc_pages_for(page_off, page_len);
+	m->pages = pages;
+	m->pagelist = NULL;
+
+	dout("ceph_msg_new %p page %d~%d -> %d\n", m, page_off, page_len,
+	     m->nr_pages);
+	return m;
+
+out2:
+	ceph_msg_put(m);
+out:
+	pr_err("msg_new can't create type %d len %d\n", type, front_len);
+	return ERR_PTR(-ENOMEM);
+}
+
+/*
+ * Allocate "middle" portion of a message, if it is needed and wasn't
+ * allocated by alloc_msg.  This allows us to read a small fixed-size
+ * per-type header in the front and then gracefully fail (i.e.,
+ * propagate the error to the caller based on info in the front) when
+ * the middle is too large.
+ */
+static int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg)
+{
+	int type = le16_to_cpu(msg->hdr.type);
+	int middle_len = le32_to_cpu(msg->hdr.middle_len);
+
+	dout("alloc_middle %p type %d %s middle_len %d\n", msg, type,
+	     ceph_msg_type_name(type), middle_len);
+	BUG_ON(!middle_len);
+	BUG_ON(msg->middle);
+
+	msg->middle = ceph_buffer_new(middle_len, GFP_NOFS);
+	if (!msg->middle)
+		return -ENOMEM;
+	return 0;
+}
+
+/*
+ * Generic message allocator, for incoming messages.
+ */
+static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con,
+				struct ceph_msg_header *hdr,
+				int *skip)
+{
+	int type = le16_to_cpu(hdr->type);
+	int front_len = le32_to_cpu(hdr->front_len);
+	int middle_len = le32_to_cpu(hdr->middle_len);
+	struct ceph_msg *msg = NULL;
+	int ret;
+
+	if (con->ops->alloc_msg) {
+		mutex_unlock(&con->mutex);
+		msg = con->ops->alloc_msg(con, hdr, skip);
+		mutex_lock(&con->mutex);
+		if (IS_ERR(msg))
+			return msg;
+
+		if (*skip)
+			return NULL;
+	}
+	if (!msg) {
+		*skip = 0;
+		msg = ceph_msg_new(type, front_len, 0, 0, NULL);
+		if (!msg) {
+			pr_err("unable to allocate msg type %d len %d\n",
+			       type, front_len);
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+	memcpy(&msg->hdr, &con->in_hdr, sizeof(con->in_hdr));
+
+	if (middle_len) {
+		ret = ceph_alloc_middle(con, msg);
+
+		if (ret < 0) {
+			ceph_msg_put(msg);
+			return msg;
+		}
+	}
+
+	return msg;
+}
+
+
+/*
+ * Free a generically kmalloc'd message.
+ */
+void ceph_msg_kfree(struct ceph_msg *m)
+{
+	dout("msg_kfree %p\n", m);
+	if (m->front_is_vmalloc)
+		vfree(m->front.iov_base);
+	else
+		kfree(m->front.iov_base);
+	kfree(m);
+}
+
+/*
+ * Drop a msg ref.  Destroy as needed.
+ */
+void ceph_msg_last_put(struct kref *kref)
+{
+	struct ceph_msg *m = container_of(kref, struct ceph_msg, kref);
+
+	dout("ceph_msg_put last one on %p\n", m);
+	WARN_ON(!list_empty(&m->list_head));
+
+	/* drop middle, data, if any */
+	if (m->middle) {
+		ceph_buffer_put(m->middle);
+		m->middle = NULL;
+	}
+	m->nr_pages = 0;
+	m->pages = NULL;
+
+	if (m->pagelist) {
+		ceph_pagelist_release(m->pagelist);
+		kfree(m->pagelist);
+		m->pagelist = NULL;
+	}
+
+	if (m->pool)
+		ceph_msgpool_put(m->pool, m);
+	else
+		ceph_msg_kfree(m);
+}
+
+void ceph_msg_dump(struct ceph_msg *msg)
+{
+	pr_debug("msg_dump %p (front_max %d nr_pages %d)\n", msg,
+		 msg->front_max, msg->nr_pages);
+	print_hex_dump(KERN_DEBUG, "header: ",
+		       DUMP_PREFIX_OFFSET, 16, 1,
+		       &msg->hdr, sizeof(msg->hdr), true);
+	print_hex_dump(KERN_DEBUG, " front: ",
+		       DUMP_PREFIX_OFFSET, 16, 1,
+		       msg->front.iov_base, msg->front.iov_len, true);
+	if (msg->middle)
+		print_hex_dump(KERN_DEBUG, "middle: ",
+			       DUMP_PREFIX_OFFSET, 16, 1,
+			       msg->middle->vec.iov_base,
+			       msg->middle->vec.iov_len, true);
+	print_hex_dump(KERN_DEBUG, "footer: ",
+		       DUMP_PREFIX_OFFSET, 16, 1,
+		       &msg->footer, sizeof(msg->footer), true);
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/messenger.h linux-libre-2.6.34-gnu1/fs/ceph/messenger.h
--- linux-libre-2.6.33-gnu1/fs/ceph/messenger.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/messenger.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,256 @@
+#ifndef __FS_CEPH_MESSENGER_H
+#define __FS_CEPH_MESSENGER_H
+
+#include <linux/kref.h>
+#include <linux/mutex.h>
+#include <linux/net.h>
+#include <linux/radix-tree.h>
+#include <linux/uio.h>
+#include <linux/version.h>
+#include <linux/workqueue.h>
+
+#include "types.h"
+#include "buffer.h"
+
+struct ceph_msg;
+struct ceph_connection;
+
+extern struct workqueue_struct *ceph_msgr_wq;       /* receive work queue */
+
+/*
+ * Ceph defines these callbacks for handling connection events.
+ */
+struct ceph_connection_operations {
+	struct ceph_connection *(*get)(struct ceph_connection *);
+	void (*put)(struct ceph_connection *);
+
+	/* handle an incoming message. */
+	void (*dispatch) (struct ceph_connection *con, struct ceph_msg *m);
+
+	/* authorize an outgoing connection */
+	int (*get_authorizer) (struct ceph_connection *con,
+			       void **buf, int *len, int *proto,
+			       void **reply_buf, int *reply_len, int force_new);
+	int (*verify_authorizer_reply) (struct ceph_connection *con, int len);
+	int (*invalidate_authorizer)(struct ceph_connection *con);
+
+	/* protocol version mismatch */
+	void (*bad_proto) (struct ceph_connection *con);
+
+	/* there was some error on the socket (disconnect, whatever) */
+	void (*fault) (struct ceph_connection *con);
+
+	/* a remote host as terminated a message exchange session, and messages
+	 * we sent (or they tried to send us) may be lost. */
+	void (*peer_reset) (struct ceph_connection *con);
+
+	struct ceph_msg * (*alloc_msg) (struct ceph_connection *con,
+					struct ceph_msg_header *hdr,
+					int *skip);
+};
+
+extern const char *ceph_name_type_str(int t);
+
+/* use format string %s%d */
+#define ENTITY_NAME(n) ceph_name_type_str((n).type), le64_to_cpu((n).num)
+
+struct ceph_messenger {
+	struct ceph_entity_inst inst;    /* my name+address */
+	struct ceph_entity_addr my_enc_addr;
+	struct page *zero_page;          /* used in certain error cases */
+
+	bool nocrc;
+
+	/*
+	 * the global_seq counts connections i (attempt to) initiate
+	 * in order to disambiguate certain connect race conditions.
+	 */
+	u32 global_seq;
+	spinlock_t global_seq_lock;
+};
+
+/*
+ * a single message.  it contains a header (src, dest, message type, etc.),
+ * footer (crc values, mainly), a "front" message body, and possibly a
+ * data payload (stored in some number of pages).
+ */
+struct ceph_msg {
+	struct ceph_msg_header hdr;	/* header */
+	struct ceph_msg_footer footer;	/* footer */
+	struct kvec front;              /* unaligned blobs of message */
+	struct ceph_buffer *middle;
+	struct page **pages;            /* data payload.  NOT OWNER. */
+	unsigned nr_pages;              /* size of page array */
+	struct ceph_pagelist *pagelist; /* instead of pages */
+	struct list_head list_head;
+	struct kref kref;
+	bool front_is_vmalloc;
+	bool more_to_follow;
+	bool needs_out_seq;
+	int front_max;
+
+	struct ceph_msgpool *pool;
+};
+
+struct ceph_msg_pos {
+	int page, page_pos;  /* which page; offset in page */
+	int data_pos;        /* offset in data payload */
+	int did_page_crc;    /* true if we've calculated crc for current page */
+};
+
+/* ceph connection fault delay defaults, for exponential backoff */
+#define BASE_DELAY_INTERVAL	(HZ/2)
+#define MAX_DELAY_INTERVAL	(5 * 60 * HZ)
+
+/*
+ * ceph_connection state bit flags
+ *
+ * QUEUED and BUSY are used together to ensure that only a single
+ * thread is currently opening, reading or writing data to the socket.
+ */
+#define LOSSYTX         0  /* we can close channel or drop messages on errors */
+#define CONNECTING	1
+#define NEGOTIATING	2
+#define KEEPALIVE_PENDING      3
+#define WRITE_PENDING	4  /* we have data ready to send */
+#define QUEUED          5  /* there is work queued on this connection */
+#define BUSY            6  /* work is being done */
+#define STANDBY		8  /* no outgoing messages, socket closed.  we keep
+			    * the ceph_connection around to maintain shared
+			    * state with the peer. */
+#define CLOSED		10 /* we've closed the connection */
+#define SOCK_CLOSED	11 /* socket state changed to closed */
+#define OPENING         13 /* open connection w/ (possibly new) peer */
+#define DEAD            14 /* dead, about to kfree */
+
+/*
+ * A single connection with another host.
+ *
+ * We maintain a queue of outgoing messages, and some session state to
+ * ensure that we can preserve the lossless, ordered delivery of
+ * messages in the case of a TCP disconnect.
+ */
+struct ceph_connection {
+	void *private;
+	atomic_t nref;
+
+	const struct ceph_connection_operations *ops;
+
+	struct ceph_messenger *msgr;
+	struct socket *sock;
+	unsigned long state;	/* connection state (see flags above) */
+	const char *error_msg;  /* error message, if any */
+
+	struct ceph_entity_addr peer_addr; /* peer address */
+	struct ceph_entity_name peer_name; /* peer name */
+	struct ceph_entity_addr peer_addr_for_me;
+	u32 connect_seq;      /* identify the most recent connection
+				 attempt for this connection, client */
+	u32 peer_global_seq;  /* peer's global seq for this connection */
+
+	int auth_retry;       /* true if we need a newer authorizer */
+	void *auth_reply_buf;   /* where to put the authorizer reply */
+	int auth_reply_buf_len;
+
+	struct mutex mutex;
+
+	/* out queue */
+	struct list_head out_queue;
+	struct list_head out_sent;   /* sending or sent but unacked */
+	u64 out_seq;		     /* last message queued for send */
+	u64 out_seq_sent;            /* last message sent */
+	bool out_keepalive_pending;
+
+	u64 in_seq, in_seq_acked;  /* last message received, acked */
+
+	/* connection negotiation temps */
+	char in_banner[CEPH_BANNER_MAX_LEN];
+	union {
+		struct {  /* outgoing connection */
+			struct ceph_msg_connect out_connect;
+			struct ceph_msg_connect_reply in_reply;
+		};
+		struct {  /* incoming */
+			struct ceph_msg_connect in_connect;
+			struct ceph_msg_connect_reply out_reply;
+		};
+	};
+	struct ceph_entity_addr actual_peer_addr;
+
+	/* message out temps */
+	struct ceph_msg *out_msg;        /* sending message (== tail of
+					    out_sent) */
+	bool out_msg_done;
+	struct ceph_msg_pos out_msg_pos;
+
+	struct kvec out_kvec[8],         /* sending header/footer data */
+		*out_kvec_cur;
+	int out_kvec_left;   /* kvec's left in out_kvec */
+	int out_skip;        /* skip this many bytes */
+	int out_kvec_bytes;  /* total bytes left */
+	bool out_kvec_is_msg; /* kvec refers to out_msg */
+	int out_more;        /* there is more data after the kvecs */
+	__le64 out_temp_ack; /* for writing an ack */
+
+	/* message in temps */
+	struct ceph_msg_header in_hdr;
+	struct ceph_msg *in_msg;
+	struct ceph_msg_pos in_msg_pos;
+	u32 in_front_crc, in_middle_crc, in_data_crc;  /* calculated crc */
+
+	char in_tag;         /* protocol control byte */
+	int in_base_pos;     /* bytes read */
+	__le64 in_temp_ack;  /* for reading an ack */
+
+	struct delayed_work work;	    /* send|recv work */
+	unsigned long       delay;          /* current delay interval */
+};
+
+
+extern const char *pr_addr(const struct sockaddr_storage *ss);
+extern int ceph_parse_ips(const char *c, const char *end,
+			  struct ceph_entity_addr *addr,
+			  int max_count, int *count);
+
+
+extern int ceph_msgr_init(void);
+extern void ceph_msgr_exit(void);
+
+extern struct ceph_messenger *ceph_messenger_create(
+	struct ceph_entity_addr *myaddr);
+extern void ceph_messenger_destroy(struct ceph_messenger *);
+
+extern void ceph_con_init(struct ceph_messenger *msgr,
+			  struct ceph_connection *con);
+extern void ceph_con_open(struct ceph_connection *con,
+			  struct ceph_entity_addr *addr);
+extern bool ceph_con_opened(struct ceph_connection *con);
+extern void ceph_con_close(struct ceph_connection *con);
+extern void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg);
+extern void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg);
+extern void ceph_con_revoke_message(struct ceph_connection *con,
+				  struct ceph_msg *msg);
+extern void ceph_con_keepalive(struct ceph_connection *con);
+extern struct ceph_connection *ceph_con_get(struct ceph_connection *con);
+extern void ceph_con_put(struct ceph_connection *con);
+
+extern struct ceph_msg *ceph_msg_new(int type, int front_len,
+				     int page_len, int page_off,
+				     struct page **pages);
+extern void ceph_msg_kfree(struct ceph_msg *m);
+
+
+static inline struct ceph_msg *ceph_msg_get(struct ceph_msg *msg)
+{
+	kref_get(&msg->kref);
+	return msg;
+}
+extern void ceph_msg_last_put(struct kref *kref);
+static inline void ceph_msg_put(struct ceph_msg *msg)
+{
+	kref_put(&msg->kref, ceph_msg_last_put);
+}
+
+extern void ceph_msg_dump(struct ceph_msg *msg);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/mon_client.c linux-libre-2.6.34-gnu1/fs/ceph/mon_client.c
--- linux-libre-2.6.33-gnu1/fs/ceph/mon_client.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/mon_client.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,835 @@
+#include "ceph_debug.h"
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+
+#include "mon_client.h"
+#include "super.h"
+#include "auth.h"
+#include "decode.h"
+
+/*
+ * Interact with Ceph monitor cluster.  Handle requests for new map
+ * versions, and periodically resend as needed.  Also implement
+ * statfs() and umount().
+ *
+ * A small cluster of Ceph "monitors" are responsible for managing critical
+ * cluster configuration and state information.  An odd number (e.g., 3, 5)
+ * of cmon daemons use a modified version of the Paxos part-time parliament
+ * algorithm to manage the MDS map (mds cluster membership), OSD map, and
+ * list of clients who have mounted the file system.
+ *
+ * We maintain an open, active session with a monitor at all times in order to
+ * receive timely MDSMap updates.  We periodically send a keepalive byte on the
+ * TCP socket to ensure we detect a failure.  If the connection does break, we
+ * randomly hunt for a new monitor.  Once the connection is reestablished, we
+ * resend any outstanding requests.
+ */
+
+const static struct ceph_connection_operations mon_con_ops;
+
+static int __validate_auth(struct ceph_mon_client *monc);
+
+/*
+ * Decode a monmap blob (e.g., during mount).
+ */
+struct ceph_monmap *ceph_monmap_decode(void *p, void *end)
+{
+	struct ceph_monmap *m = NULL;
+	int i, err = -EINVAL;
+	struct ceph_fsid fsid;
+	u32 epoch, num_mon;
+	u16 version;
+	u32 len;
+
+	ceph_decode_32_safe(&p, end, len, bad);
+	ceph_decode_need(&p, end, len, bad);
+
+	dout("monmap_decode %p %p len %d\n", p, end, (int)(end-p));
+
+	ceph_decode_16_safe(&p, end, version, bad);
+
+	ceph_decode_need(&p, end, sizeof(fsid) + 2*sizeof(u32), bad);
+	ceph_decode_copy(&p, &fsid, sizeof(fsid));
+	epoch = ceph_decode_32(&p);
+
+	num_mon = ceph_decode_32(&p);
+	ceph_decode_need(&p, end, num_mon*sizeof(m->mon_inst[0]), bad);
+
+	if (num_mon >= CEPH_MAX_MON)
+		goto bad;
+	m = kmalloc(sizeof(*m) + sizeof(m->mon_inst[0])*num_mon, GFP_NOFS);
+	if (m == NULL)
+		return ERR_PTR(-ENOMEM);
+	m->fsid = fsid;
+	m->epoch = epoch;
+	m->num_mon = num_mon;
+	ceph_decode_copy(&p, m->mon_inst, num_mon*sizeof(m->mon_inst[0]));
+	for (i = 0; i < num_mon; i++)
+		ceph_decode_addr(&m->mon_inst[i].addr);
+
+	dout("monmap_decode epoch %d, num_mon %d\n", m->epoch,
+	     m->num_mon);
+	for (i = 0; i < m->num_mon; i++)
+		dout("monmap_decode  mon%d is %s\n", i,
+		     pr_addr(&m->mon_inst[i].addr.in_addr));
+	return m;
+
+bad:
+	dout("monmap_decode failed with %d\n", err);
+	kfree(m);
+	return ERR_PTR(err);
+}
+
+/*
+ * return true if *addr is included in the monmap.
+ */
+int ceph_monmap_contains(struct ceph_monmap *m, struct ceph_entity_addr *addr)
+{
+	int i;
+
+	for (i = 0; i < m->num_mon; i++)
+		if (memcmp(addr, &m->mon_inst[i].addr, sizeof(*addr)) == 0)
+			return 1;
+	return 0;
+}
+
+/*
+ * Send an auth request.
+ */
+static void __send_prepared_auth_request(struct ceph_mon_client *monc, int len)
+{
+	monc->pending_auth = 1;
+	monc->m_auth->front.iov_len = len;
+	monc->m_auth->hdr.front_len = cpu_to_le32(len);
+	ceph_msg_get(monc->m_auth);  /* keep our ref */
+	ceph_con_send(monc->con, monc->m_auth);
+}
+
+/*
+ * Close monitor session, if any.
+ */
+static void __close_session(struct ceph_mon_client *monc)
+{
+	if (monc->con) {
+		dout("__close_session closing mon%d\n", monc->cur_mon);
+		ceph_con_revoke(monc->con, monc->m_auth);
+		ceph_con_close(monc->con);
+		monc->cur_mon = -1;
+		monc->pending_auth = 0;
+		ceph_auth_reset(monc->auth);
+	}
+}
+
+/*
+ * Open a session with a (new) monitor.
+ */
+static int __open_session(struct ceph_mon_client *monc)
+{
+	char r;
+	int ret;
+
+	if (monc->cur_mon < 0) {
+		get_random_bytes(&r, 1);
+		monc->cur_mon = r % monc->monmap->num_mon;
+		dout("open_session num=%d r=%d -> mon%d\n",
+		     monc->monmap->num_mon, r, monc->cur_mon);
+		monc->sub_sent = 0;
+		monc->sub_renew_after = jiffies;  /* i.e., expired */
+		monc->want_next_osdmap = !!monc->want_next_osdmap;
+
+		dout("open_session mon%d opening\n", monc->cur_mon);
+		monc->con->peer_name.type = CEPH_ENTITY_TYPE_MON;
+		monc->con->peer_name.num = cpu_to_le64(monc->cur_mon);
+		ceph_con_open(monc->con,
+			      &monc->monmap->mon_inst[monc->cur_mon].addr);
+
+		/* initiatiate authentication handshake */
+		ret = ceph_auth_build_hello(monc->auth,
+					    monc->m_auth->front.iov_base,
+					    monc->m_auth->front_max);
+		__send_prepared_auth_request(monc, ret);
+	} else {
+		dout("open_session mon%d already open\n", monc->cur_mon);
+	}
+	return 0;
+}
+
+static bool __sub_expired(struct ceph_mon_client *monc)
+{
+	return time_after_eq(jiffies, monc->sub_renew_after);
+}
+
+/*
+ * Reschedule delayed work timer.
+ */
+static void __schedule_delayed(struct ceph_mon_client *monc)
+{
+	unsigned delay;
+
+	if (monc->cur_mon < 0 || __sub_expired(monc))
+		delay = 10 * HZ;
+	else
+		delay = 20 * HZ;
+	dout("__schedule_delayed after %u\n", delay);
+	schedule_delayed_work(&monc->delayed_work, delay);
+}
+
+/*
+ * Send subscribe request for mdsmap and/or osdmap.
+ */
+static void __send_subscribe(struct ceph_mon_client *monc)
+{
+	dout("__send_subscribe sub_sent=%u exp=%u want_osd=%d\n",
+	     (unsigned)monc->sub_sent, __sub_expired(monc),
+	     monc->want_next_osdmap);
+	if ((__sub_expired(monc) && !monc->sub_sent) ||
+	    monc->want_next_osdmap == 1) {
+		struct ceph_msg *msg;
+		struct ceph_mon_subscribe_item *i;
+		void *p, *end;
+
+		msg = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE, 96, 0, 0, NULL);
+		if (!msg)
+			return;
+
+		p = msg->front.iov_base;
+		end = p + msg->front.iov_len;
+
+		dout("__send_subscribe to 'mdsmap' %u+\n",
+		     (unsigned)monc->have_mdsmap);
+		if (monc->want_next_osdmap) {
+			dout("__send_subscribe to 'osdmap' %u\n",
+			     (unsigned)monc->have_osdmap);
+			ceph_encode_32(&p, 3);
+			ceph_encode_string(&p, end, "osdmap", 6);
+			i = p;
+			i->have = cpu_to_le64(monc->have_osdmap);
+			i->onetime = 1;
+			p += sizeof(*i);
+			monc->want_next_osdmap = 2;  /* requested */
+		} else {
+			ceph_encode_32(&p, 2);
+		}
+		ceph_encode_string(&p, end, "mdsmap", 6);
+		i = p;
+		i->have = cpu_to_le64(monc->have_mdsmap);
+		i->onetime = 0;
+		p += sizeof(*i);
+		ceph_encode_string(&p, end, "monmap", 6);
+		i = p;
+		i->have = 0;
+		i->onetime = 0;
+		p += sizeof(*i);
+
+		msg->front.iov_len = p - msg->front.iov_base;
+		msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
+		ceph_con_send(monc->con, msg);
+
+		monc->sub_sent = jiffies | 1;  /* never 0 */
+	}
+}
+
+static void handle_subscribe_ack(struct ceph_mon_client *monc,
+				 struct ceph_msg *msg)
+{
+	unsigned seconds;
+	struct ceph_mon_subscribe_ack *h = msg->front.iov_base;
+
+	if (msg->front.iov_len < sizeof(*h))
+		goto bad;
+	seconds = le32_to_cpu(h->duration);
+
+	mutex_lock(&monc->mutex);
+	if (monc->hunting) {
+		pr_info("mon%d %s session established\n",
+			monc->cur_mon, pr_addr(&monc->con->peer_addr.in_addr));
+		monc->hunting = false;
+	}
+	dout("handle_subscribe_ack after %d seconds\n", seconds);
+	monc->sub_renew_after = monc->sub_sent + (seconds >> 1)*HZ - 1;
+	monc->sub_sent = 0;
+	mutex_unlock(&monc->mutex);
+	return;
+bad:
+	pr_err("got corrupt subscribe-ack msg\n");
+	ceph_msg_dump(msg);
+}
+
+/*
+ * Keep track of which maps we have
+ */
+int ceph_monc_got_mdsmap(struct ceph_mon_client *monc, u32 got)
+{
+	mutex_lock(&monc->mutex);
+	monc->have_mdsmap = got;
+	mutex_unlock(&monc->mutex);
+	return 0;
+}
+
+int ceph_monc_got_osdmap(struct ceph_mon_client *monc, u32 got)
+{
+	mutex_lock(&monc->mutex);
+	monc->have_osdmap = got;
+	monc->want_next_osdmap = 0;
+	mutex_unlock(&monc->mutex);
+	return 0;
+}
+
+/*
+ * Register interest in the next osdmap
+ */
+void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc)
+{
+	dout("request_next_osdmap have %u\n", monc->have_osdmap);
+	mutex_lock(&monc->mutex);
+	if (!monc->want_next_osdmap)
+		monc->want_next_osdmap = 1;
+	if (monc->want_next_osdmap < 2)
+		__send_subscribe(monc);
+	mutex_unlock(&monc->mutex);
+}
+
+/*
+ *
+ */
+int ceph_monc_open_session(struct ceph_mon_client *monc)
+{
+	if (!monc->con) {
+		monc->con = kmalloc(sizeof(*monc->con), GFP_KERNEL);
+		if (!monc->con)
+			return -ENOMEM;
+		ceph_con_init(monc->client->msgr, monc->con);
+		monc->con->private = monc;
+		monc->con->ops = &mon_con_ops;
+	}
+
+	mutex_lock(&monc->mutex);
+	__open_session(monc);
+	__schedule_delayed(monc);
+	mutex_unlock(&monc->mutex);
+	return 0;
+}
+
+/*
+ * The monitor responds with mount ack indicate mount success.  The
+ * included client ticket allows the client to talk to MDSs and OSDs.
+ */
+static void ceph_monc_handle_map(struct ceph_mon_client *monc,
+				 struct ceph_msg *msg)
+{
+	struct ceph_client *client = monc->client;
+	struct ceph_monmap *monmap = NULL, *old = monc->monmap;
+	void *p, *end;
+
+	mutex_lock(&monc->mutex);
+
+	dout("handle_monmap\n");
+	p = msg->front.iov_base;
+	end = p + msg->front.iov_len;
+
+	monmap = ceph_monmap_decode(p, end);
+	if (IS_ERR(monmap)) {
+		pr_err("problem decoding monmap, %d\n",
+		       (int)PTR_ERR(monmap));
+		goto out;
+	}
+
+	if (ceph_check_fsid(monc->client, &monmap->fsid) < 0) {
+		kfree(monmap);
+		goto out;
+	}
+
+	client->monc.monmap = monmap;
+	kfree(old);
+
+out:
+	mutex_unlock(&monc->mutex);
+	wake_up(&client->auth_wq);
+}
+
+/*
+ * statfs
+ */
+static struct ceph_mon_statfs_request *__lookup_statfs(
+	struct ceph_mon_client *monc, u64 tid)
+{
+	struct ceph_mon_statfs_request *req;
+	struct rb_node *n = monc->statfs_request_tree.rb_node;
+
+	while (n) {
+		req = rb_entry(n, struct ceph_mon_statfs_request, node);
+		if (tid < req->tid)
+			n = n->rb_left;
+		else if (tid > req->tid)
+			n = n->rb_right;
+		else
+			return req;
+	}
+	return NULL;
+}
+
+static void __insert_statfs(struct ceph_mon_client *monc,
+			    struct ceph_mon_statfs_request *new)
+{
+	struct rb_node **p = &monc->statfs_request_tree.rb_node;
+	struct rb_node *parent = NULL;
+	struct ceph_mon_statfs_request *req = NULL;
+
+	while (*p) {
+		parent = *p;
+		req = rb_entry(parent, struct ceph_mon_statfs_request, node);
+		if (new->tid < req->tid)
+			p = &(*p)->rb_left;
+		else if (new->tid > req->tid)
+			p = &(*p)->rb_right;
+		else
+			BUG();
+	}
+
+	rb_link_node(&new->node, parent, p);
+	rb_insert_color(&new->node, &monc->statfs_request_tree);
+}
+
+static void handle_statfs_reply(struct ceph_mon_client *monc,
+				struct ceph_msg *msg)
+{
+	struct ceph_mon_statfs_request *req;
+	struct ceph_mon_statfs_reply *reply = msg->front.iov_base;
+	u64 tid;
+
+	if (msg->front.iov_len != sizeof(*reply))
+		goto bad;
+	tid = le64_to_cpu(msg->hdr.tid);
+	dout("handle_statfs_reply %p tid %llu\n", msg, tid);
+
+	mutex_lock(&monc->mutex);
+	req = __lookup_statfs(monc, tid);
+	if (req) {
+		*req->buf = reply->st;
+		req->result = 0;
+	}
+	mutex_unlock(&monc->mutex);
+	if (req)
+		complete(&req->completion);
+	return;
+
+bad:
+	pr_err("corrupt statfs reply, no tid\n");
+	ceph_msg_dump(msg);
+}
+
+/*
+ * (re)send a statfs request
+ */
+static int send_statfs(struct ceph_mon_client *monc,
+		       struct ceph_mon_statfs_request *req)
+{
+	struct ceph_msg *msg;
+	struct ceph_mon_statfs *h;
+
+	dout("send_statfs tid %llu\n", req->tid);
+	msg = ceph_msg_new(CEPH_MSG_STATFS, sizeof(*h), 0, 0, NULL);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
+	req->request = msg;
+	msg->hdr.tid = cpu_to_le64(req->tid);
+	h = msg->front.iov_base;
+	h->monhdr.have_version = 0;
+	h->monhdr.session_mon = cpu_to_le16(-1);
+	h->monhdr.session_mon_tid = 0;
+	h->fsid = monc->monmap->fsid;
+	ceph_con_send(monc->con, msg);
+	return 0;
+}
+
+/*
+ * Do a synchronous statfs().
+ */
+int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf)
+{
+	struct ceph_mon_statfs_request req;
+	int err;
+
+	req.buf = buf;
+	init_completion(&req.completion);
+
+	/* allocate memory for reply */
+	err = ceph_msgpool_resv(&monc->msgpool_statfs_reply, 1);
+	if (err)
+		return err;
+
+	/* register request */
+	mutex_lock(&monc->mutex);
+	req.tid = ++monc->last_tid;
+	req.last_attempt = jiffies;
+	req.delay = BASE_DELAY_INTERVAL;
+	__insert_statfs(monc, &req);
+	monc->num_statfs_requests++;
+	mutex_unlock(&monc->mutex);
+
+	/* send request and wait */
+	err = send_statfs(monc, &req);
+	if (!err)
+		err = wait_for_completion_interruptible(&req.completion);
+
+	mutex_lock(&monc->mutex);
+	rb_erase(&req.node, &monc->statfs_request_tree);
+	monc->num_statfs_requests--;
+	ceph_msgpool_resv(&monc->msgpool_statfs_reply, -1);
+	mutex_unlock(&monc->mutex);
+
+	if (!err)
+		err = req.result;
+	return err;
+}
+
+/*
+ * Resend pending statfs requests.
+ */
+static void __resend_statfs(struct ceph_mon_client *monc)
+{
+	struct ceph_mon_statfs_request *req;
+	struct rb_node *p;
+
+	for (p = rb_first(&monc->statfs_request_tree); p; p = rb_next(p)) {
+		req = rb_entry(p, struct ceph_mon_statfs_request, node);
+		send_statfs(monc, req);
+	}
+}
+
+/*
+ * Delayed work.  If we haven't mounted yet, retry.  Otherwise,
+ * renew/retry subscription as needed (in case it is timing out, or we
+ * got an ENOMEM).  And keep the monitor connection alive.
+ */
+static void delayed_work(struct work_struct *work)
+{
+	struct ceph_mon_client *monc =
+		container_of(work, struct ceph_mon_client, delayed_work.work);
+
+	dout("monc delayed_work\n");
+	mutex_lock(&monc->mutex);
+	if (monc->hunting) {
+		__close_session(monc);
+		__open_session(monc);  /* continue hunting */
+	} else {
+		ceph_con_keepalive(monc->con);
+
+		__validate_auth(monc);
+
+		if (monc->auth->ops->is_authenticated(monc->auth))
+			__send_subscribe(monc);
+	}
+	__schedule_delayed(monc);
+	mutex_unlock(&monc->mutex);
+}
+
+/*
+ * On startup, we build a temporary monmap populated with the IPs
+ * provided by mount(2).
+ */
+static int build_initial_monmap(struct ceph_mon_client *monc)
+{
+	struct ceph_mount_args *args = monc->client->mount_args;
+	struct ceph_entity_addr *mon_addr = args->mon_addr;
+	int num_mon = args->num_mon;
+	int i;
+
+	/* build initial monmap */
+	monc->monmap = kzalloc(sizeof(*monc->monmap) +
+			       num_mon*sizeof(monc->monmap->mon_inst[0]),
+			       GFP_KERNEL);
+	if (!monc->monmap)
+		return -ENOMEM;
+	for (i = 0; i < num_mon; i++) {
+		monc->monmap->mon_inst[i].addr = mon_addr[i];
+		monc->monmap->mon_inst[i].addr.nonce = 0;
+		monc->monmap->mon_inst[i].name.type =
+			CEPH_ENTITY_TYPE_MON;
+		monc->monmap->mon_inst[i].name.num = cpu_to_le64(i);
+	}
+	monc->monmap->num_mon = num_mon;
+	monc->have_fsid = false;
+
+	/* release addr memory */
+	kfree(args->mon_addr);
+	args->mon_addr = NULL;
+	args->num_mon = 0;
+	return 0;
+}
+
+int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
+{
+	int err = 0;
+
+	dout("init\n");
+	memset(monc, 0, sizeof(*monc));
+	monc->client = cl;
+	monc->monmap = NULL;
+	mutex_init(&monc->mutex);
+
+	err = build_initial_monmap(monc);
+	if (err)
+		goto out;
+
+	monc->con = NULL;
+
+	/* authentication */
+	monc->auth = ceph_auth_init(cl->mount_args->name,
+				    cl->mount_args->secret);
+	if (IS_ERR(monc->auth))
+		return PTR_ERR(monc->auth);
+	monc->auth->want_keys =
+		CEPH_ENTITY_TYPE_AUTH | CEPH_ENTITY_TYPE_MON |
+		CEPH_ENTITY_TYPE_OSD | CEPH_ENTITY_TYPE_MDS;
+
+	/* msg pools */
+	err = ceph_msgpool_init(&monc->msgpool_subscribe_ack,
+			       sizeof(struct ceph_mon_subscribe_ack), 1, false);
+	if (err < 0)
+		goto out_monmap;
+	err = ceph_msgpool_init(&monc->msgpool_statfs_reply,
+				sizeof(struct ceph_mon_statfs_reply), 0, false);
+	if (err < 0)
+		goto out_pool1;
+	err = ceph_msgpool_init(&monc->msgpool_auth_reply, 4096, 1, false);
+	if (err < 0)
+		goto out_pool2;
+
+	monc->m_auth = ceph_msg_new(CEPH_MSG_AUTH, 4096, 0, 0, NULL);
+	monc->pending_auth = 0;
+	if (IS_ERR(monc->m_auth)) {
+		err = PTR_ERR(monc->m_auth);
+		monc->m_auth = NULL;
+		goto out_pool3;
+	}
+
+	monc->cur_mon = -1;
+	monc->hunting = true;
+	monc->sub_renew_after = jiffies;
+	monc->sub_sent = 0;
+
+	INIT_DELAYED_WORK(&monc->delayed_work, delayed_work);
+	monc->statfs_request_tree = RB_ROOT;
+	monc->num_statfs_requests = 0;
+	monc->last_tid = 0;
+
+	monc->have_mdsmap = 0;
+	monc->have_osdmap = 0;
+	monc->want_next_osdmap = 1;
+	return 0;
+
+out_pool3:
+	ceph_msgpool_destroy(&monc->msgpool_auth_reply);
+out_pool2:
+	ceph_msgpool_destroy(&monc->msgpool_subscribe_ack);
+out_pool1:
+	ceph_msgpool_destroy(&monc->msgpool_statfs_reply);
+out_monmap:
+	kfree(monc->monmap);
+out:
+	return err;
+}
+
+void ceph_monc_stop(struct ceph_mon_client *monc)
+{
+	dout("stop\n");
+	cancel_delayed_work_sync(&monc->delayed_work);
+
+	mutex_lock(&monc->mutex);
+	__close_session(monc);
+	if (monc->con) {
+		monc->con->private = NULL;
+		monc->con->ops->put(monc->con);
+		monc->con = NULL;
+	}
+	mutex_unlock(&monc->mutex);
+
+	ceph_auth_destroy(monc->auth);
+
+	ceph_msg_put(monc->m_auth);
+	ceph_msgpool_destroy(&monc->msgpool_subscribe_ack);
+	ceph_msgpool_destroy(&monc->msgpool_statfs_reply);
+	ceph_msgpool_destroy(&monc->msgpool_auth_reply);
+
+	kfree(monc->monmap);
+}
+
+static void handle_auth_reply(struct ceph_mon_client *monc,
+			      struct ceph_msg *msg)
+{
+	int ret;
+
+	mutex_lock(&monc->mutex);
+	monc->pending_auth = 0;
+	ret = ceph_handle_auth_reply(monc->auth, msg->front.iov_base,
+				     msg->front.iov_len,
+				     monc->m_auth->front.iov_base,
+				     monc->m_auth->front_max);
+	if (ret < 0) {
+		monc->client->auth_err = ret;
+		wake_up(&monc->client->auth_wq);
+	} else if (ret > 0) {
+		__send_prepared_auth_request(monc, ret);
+	} else if (monc->auth->ops->is_authenticated(monc->auth)) {
+		dout("authenticated, starting session\n");
+
+		monc->client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT;
+		monc->client->msgr->inst.name.num = monc->auth->global_id;
+
+		__send_subscribe(monc);
+		__resend_statfs(monc);
+	}
+	mutex_unlock(&monc->mutex);
+}
+
+static int __validate_auth(struct ceph_mon_client *monc)
+{
+	int ret;
+
+	if (monc->pending_auth)
+		return 0;
+
+	ret = ceph_build_auth(monc->auth, monc->m_auth->front.iov_base,
+			      monc->m_auth->front_max);
+	if (ret <= 0)
+		return ret; /* either an error, or no need to authenticate */
+	__send_prepared_auth_request(monc, ret);
+	return 0;
+}
+
+int ceph_monc_validate_auth(struct ceph_mon_client *monc)
+{
+	int ret;
+
+	mutex_lock(&monc->mutex);
+	ret = __validate_auth(monc);
+	mutex_unlock(&monc->mutex);
+	return ret;
+}
+
+/*
+ * handle incoming message
+ */
+static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
+{
+	struct ceph_mon_client *monc = con->private;
+	int type = le16_to_cpu(msg->hdr.type);
+
+	if (!monc)
+		return;
+
+	switch (type) {
+	case CEPH_MSG_AUTH_REPLY:
+		handle_auth_reply(monc, msg);
+		break;
+
+	case CEPH_MSG_MON_SUBSCRIBE_ACK:
+		handle_subscribe_ack(monc, msg);
+		break;
+
+	case CEPH_MSG_STATFS_REPLY:
+		handle_statfs_reply(monc, msg);
+		break;
+
+	case CEPH_MSG_MON_MAP:
+		ceph_monc_handle_map(monc, msg);
+		break;
+
+	case CEPH_MSG_MDS_MAP:
+		ceph_mdsc_handle_map(&monc->client->mdsc, msg);
+		break;
+
+	case CEPH_MSG_OSD_MAP:
+		ceph_osdc_handle_map(&monc->client->osdc, msg);
+		break;
+
+	default:
+		pr_err("received unknown message type %d %s\n", type,
+		       ceph_msg_type_name(type));
+	}
+	ceph_msg_put(msg);
+}
+
+/*
+ * Allocate memory for incoming message
+ */
+static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con,
+				      struct ceph_msg_header *hdr,
+				      int *skip)
+{
+	struct ceph_mon_client *monc = con->private;
+	int type = le16_to_cpu(hdr->type);
+	int front_len = le32_to_cpu(hdr->front_len);
+	struct ceph_msg *m = NULL;
+
+	*skip = 0;
+
+	switch (type) {
+	case CEPH_MSG_MON_SUBSCRIBE_ACK:
+		m = ceph_msgpool_get(&monc->msgpool_subscribe_ack, front_len);
+		break;
+	case CEPH_MSG_STATFS_REPLY:
+		m = ceph_msgpool_get(&monc->msgpool_statfs_reply, front_len);
+		break;
+	case CEPH_MSG_AUTH_REPLY:
+		m = ceph_msgpool_get(&monc->msgpool_auth_reply, front_len);
+		break;
+	case CEPH_MSG_MON_MAP:
+	case CEPH_MSG_MDS_MAP:
+	case CEPH_MSG_OSD_MAP:
+		m = ceph_msg_new(type, front_len, 0, 0, NULL);
+		break;
+	}
+
+	if (!m) {
+		pr_info("alloc_msg unknown type %d\n", type);
+		*skip = 1;
+	}
+	return m;
+}
+
+/*
+ * If the monitor connection resets, pick a new monitor and resubmit
+ * any pending requests.
+ */
+static void mon_fault(struct ceph_connection *con)
+{
+	struct ceph_mon_client *monc = con->private;
+
+	if (!monc)
+		return;
+
+	dout("mon_fault\n");
+	mutex_lock(&monc->mutex);
+	if (!con->private)
+		goto out;
+
+	if (monc->con && !monc->hunting)
+		pr_info("mon%d %s session lost, "
+			"hunting for new mon\n", monc->cur_mon,
+			pr_addr(&monc->con->peer_addr.in_addr));
+
+	__close_session(monc);
+	if (!monc->hunting) {
+		/* start hunting */
+		monc->hunting = true;
+		__open_session(monc);
+	} else {
+		/* already hunting, let's wait a bit */
+		__schedule_delayed(monc);
+	}
+out:
+	mutex_unlock(&monc->mutex);
+}
+
+const static struct ceph_connection_operations mon_con_ops = {
+	.get = ceph_con_get,
+	.put = ceph_con_put,
+	.dispatch = dispatch,
+	.fault = mon_fault,
+	.alloc_msg = mon_alloc_msg,
+};
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/mon_client.h linux-libre-2.6.34-gnu1/fs/ceph/mon_client.h
--- linux-libre-2.6.33-gnu1/fs/ceph/mon_client.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/mon_client.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,119 @@
+#ifndef _FS_CEPH_MON_CLIENT_H
+#define _FS_CEPH_MON_CLIENT_H
+
+#include <linux/completion.h>
+#include <linux/rbtree.h>
+
+#include "messenger.h"
+#include "msgpool.h"
+
+struct ceph_client;
+struct ceph_mount_args;
+struct ceph_auth_client;
+
+/*
+ * The monitor map enumerates the set of all monitors.
+ */
+struct ceph_monmap {
+	struct ceph_fsid fsid;
+	u32 epoch;
+	u32 num_mon;
+	struct ceph_entity_inst mon_inst[0];
+};
+
+struct ceph_mon_client;
+struct ceph_mon_statfs_request;
+
+
+/*
+ * Generic mechanism for resending monitor requests.
+ */
+typedef void (*ceph_monc_request_func_t)(struct ceph_mon_client *monc,
+					 int newmon);
+
+/* a pending monitor request */
+struct ceph_mon_request {
+	struct ceph_mon_client *monc;
+	struct delayed_work delayed_work;
+	unsigned long delay;
+	ceph_monc_request_func_t do_request;
+};
+
+/*
+ * statfs() is done a bit differently because we need to get data back
+ * to the caller
+ */
+struct ceph_mon_statfs_request {
+	u64 tid;
+	struct rb_node node;
+	int result;
+	struct ceph_statfs *buf;
+	struct completion completion;
+	unsigned long last_attempt, delay; /* jiffies */
+	struct ceph_msg *request;  /* original request */
+};
+
+struct ceph_mon_client {
+	struct ceph_client *client;
+	struct ceph_monmap *monmap;
+
+	struct mutex mutex;
+	struct delayed_work delayed_work;
+
+	struct ceph_auth_client *auth;
+	struct ceph_msg *m_auth;
+	int pending_auth;
+
+	bool hunting;
+	int cur_mon;                       /* last monitor i contacted */
+	unsigned long sub_sent, sub_renew_after;
+	struct ceph_connection *con;
+	bool have_fsid;
+
+	/* msg pools */
+	struct ceph_msgpool msgpool_subscribe_ack;
+	struct ceph_msgpool msgpool_statfs_reply;
+	struct ceph_msgpool msgpool_auth_reply;
+
+	/* pending statfs requests */
+	struct rb_root statfs_request_tree;
+	int num_statfs_requests;
+	u64 last_tid;
+
+	/* mds/osd map */
+	int want_next_osdmap; /* 1 = want, 2 = want+asked */
+	u32 have_osdmap, have_mdsmap;
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs_file;
+#endif
+};
+
+extern struct ceph_monmap *ceph_monmap_decode(void *p, void *end);
+extern int ceph_monmap_contains(struct ceph_monmap *m,
+				struct ceph_entity_addr *addr);
+
+extern int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl);
+extern void ceph_monc_stop(struct ceph_mon_client *monc);
+
+/*
+ * The model here is to indicate that we need a new map of at least
+ * epoch @want, and also call in when we receive a map.  We will
+ * periodically rerequest the map from the monitor cluster until we
+ * get what we want.
+ */
+extern int ceph_monc_got_mdsmap(struct ceph_mon_client *monc, u32 have);
+extern int ceph_monc_got_osdmap(struct ceph_mon_client *monc, u32 have);
+
+extern void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc);
+
+extern int ceph_monc_do_statfs(struct ceph_mon_client *monc,
+			       struct ceph_statfs *buf);
+
+extern int ceph_monc_open_session(struct ceph_mon_client *monc);
+
+extern int ceph_monc_validate_auth(struct ceph_mon_client *monc);
+
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/msgpool.c linux-libre-2.6.34-gnu1/fs/ceph/msgpool.c
--- linux-libre-2.6.33-gnu1/fs/ceph/msgpool.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/msgpool.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,186 @@
+#include "ceph_debug.h"
+
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+
+#include "msgpool.h"
+
+/*
+ * We use msg pools to preallocate memory for messages we expect to
+ * receive over the wire, to avoid getting ourselves into OOM
+ * conditions at unexpected times.  We take use a few different
+ * strategies:
+ *
+ *  - for request/response type interactions, we preallocate the
+ * memory needed for the response when we generate the request.
+ *
+ *  - for messages we can receive at any time from the MDS, we preallocate
+ * a pool of messages we can re-use.
+ *
+ *  - for writeback, we preallocate some number of messages to use for
+ * requests and their replies, so that we always make forward
+ * progress.
+ *
+ * The msgpool behaves like a mempool_t, but keeps preallocated
+ * ceph_msgs strung together on a list_head instead of using a pointer
+ * vector.  This avoids vector reallocation when we adjust the number
+ * of preallocated items (which happens frequently).
+ */
+
+
+/*
+ * Allocate or release as necessary to meet our target pool size.
+ */
+static int __fill_msgpool(struct ceph_msgpool *pool)
+{
+	struct ceph_msg *msg;
+
+	while (pool->num < pool->min) {
+		dout("fill_msgpool %p %d/%d allocating\n", pool, pool->num,
+		     pool->min);
+		spin_unlock(&pool->lock);
+		msg = ceph_msg_new(0, pool->front_len, 0, 0, NULL);
+		spin_lock(&pool->lock);
+		if (IS_ERR(msg))
+			return PTR_ERR(msg);
+		msg->pool = pool;
+		list_add(&msg->list_head, &pool->msgs);
+		pool->num++;
+	}
+	while (pool->num > pool->min) {
+		msg = list_first_entry(&pool->msgs, struct ceph_msg, list_head);
+		dout("fill_msgpool %p %d/%d releasing %p\n", pool, pool->num,
+		     pool->min, msg);
+		list_del_init(&msg->list_head);
+		pool->num--;
+		ceph_msg_kfree(msg);
+	}
+	return 0;
+}
+
+int ceph_msgpool_init(struct ceph_msgpool *pool,
+		      int front_len, int min, bool blocking)
+{
+	int ret;
+
+	dout("msgpool_init %p front_len %d min %d\n", pool, front_len, min);
+	spin_lock_init(&pool->lock);
+	pool->front_len = front_len;
+	INIT_LIST_HEAD(&pool->msgs);
+	pool->num = 0;
+	pool->min = min;
+	pool->blocking = blocking;
+	init_waitqueue_head(&pool->wait);
+
+	spin_lock(&pool->lock);
+	ret = __fill_msgpool(pool);
+	spin_unlock(&pool->lock);
+	return ret;
+}
+
+void ceph_msgpool_destroy(struct ceph_msgpool *pool)
+{
+	dout("msgpool_destroy %p\n", pool);
+	spin_lock(&pool->lock);
+	pool->min = 0;
+	__fill_msgpool(pool);
+	spin_unlock(&pool->lock);
+}
+
+int ceph_msgpool_resv(struct ceph_msgpool *pool, int delta)
+{
+	int ret;
+
+	spin_lock(&pool->lock);
+	dout("msgpool_resv %p delta %d\n", pool, delta);
+	pool->min += delta;
+	ret = __fill_msgpool(pool);
+	spin_unlock(&pool->lock);
+	return ret;
+}
+
+struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, int front_len)
+{
+	wait_queue_t wait;
+	struct ceph_msg *msg;
+
+	if (front_len && front_len > pool->front_len) {
+		pr_err("msgpool_get pool %p need front %d, pool size is %d\n",
+		       pool, front_len, pool->front_len);
+		WARN_ON(1);
+
+		/* try to alloc a fresh message */
+		msg = ceph_msg_new(0, front_len, 0, 0, NULL);
+		if (!IS_ERR(msg))
+			return msg;
+	}
+
+	if (!front_len)
+		front_len = pool->front_len;
+
+	if (pool->blocking) {
+		/* mempool_t behavior; first try to alloc */
+		msg = ceph_msg_new(0, front_len, 0, 0, NULL);
+		if (!IS_ERR(msg))
+			return msg;
+	}
+
+	while (1) {
+		spin_lock(&pool->lock);
+		if (likely(pool->num)) {
+			msg = list_entry(pool->msgs.next, struct ceph_msg,
+					 list_head);
+			list_del_init(&msg->list_head);
+			pool->num--;
+			dout("msgpool_get %p got %p, now %d/%d\n", pool, msg,
+			     pool->num, pool->min);
+			spin_unlock(&pool->lock);
+			return msg;
+		}
+		pr_err("msgpool_get %p now %d/%d, %s\n", pool, pool->num,
+		       pool->min, pool->blocking ? "waiting" : "may fail");
+		spin_unlock(&pool->lock);
+
+		if (!pool->blocking) {
+			WARN_ON(1);
+
+			/* maybe we can allocate it now? */
+			msg = ceph_msg_new(0, front_len, 0, 0, NULL);
+			if (!IS_ERR(msg))
+				return msg;
+
+			pr_err("msgpool_get %p empty + alloc failed\n", pool);
+			return ERR_PTR(-ENOMEM);
+		}
+
+		init_wait(&wait);
+		prepare_to_wait(&pool->wait, &wait, TASK_UNINTERRUPTIBLE);
+		schedule();
+		finish_wait(&pool->wait, &wait);
+	}
+}
+
+void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg)
+{
+	spin_lock(&pool->lock);
+	if (pool->num < pool->min) {
+		/* reset msg front_len; user may have changed it */
+		msg->front.iov_len = pool->front_len;
+		msg->hdr.front_len = cpu_to_le32(pool->front_len);
+
+		kref_set(&msg->kref, 1);  /* retake a single ref */
+		list_add(&msg->list_head, &pool->msgs);
+		pool->num++;
+		dout("msgpool_put %p reclaim %p, now %d/%d\n", pool, msg,
+		     pool->num, pool->min);
+		spin_unlock(&pool->lock);
+		wake_up(&pool->wait);
+	} else {
+		dout("msgpool_put %p drop %p, at %d/%d\n", pool, msg,
+		     pool->num, pool->min);
+		spin_unlock(&pool->lock);
+		ceph_msg_kfree(msg);
+	}
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/msgpool.h linux-libre-2.6.34-gnu1/fs/ceph/msgpool.h
--- linux-libre-2.6.33-gnu1/fs/ceph/msgpool.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/msgpool.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,27 @@
+#ifndef _FS_CEPH_MSGPOOL
+#define _FS_CEPH_MSGPOOL
+
+#include "messenger.h"
+
+/*
+ * we use memory pools for preallocating messages we may receive, to
+ * avoid unexpected OOM conditions.
+ */
+struct ceph_msgpool {
+	spinlock_t lock;
+	int front_len;          /* preallocated payload size */
+	struct list_head msgs;  /* msgs in the pool; each has 1 ref */
+	int num, min;           /* cur, min # msgs in the pool */
+	bool blocking;
+	wait_queue_head_t wait;
+};
+
+extern int ceph_msgpool_init(struct ceph_msgpool *pool,
+			     int front_len, int size, bool blocking);
+extern void ceph_msgpool_destroy(struct ceph_msgpool *pool);
+extern int ceph_msgpool_resv(struct ceph_msgpool *, int delta);
+extern struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *,
+					 int front_len);
+extern void ceph_msgpool_put(struct ceph_msgpool *, struct ceph_msg *);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/msgr.h linux-libre-2.6.34-gnu1/fs/ceph/msgr.h
--- linux-libre-2.6.33-gnu1/fs/ceph/msgr.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/msgr.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,158 @@
+#ifndef __MSGR_H
+#define __MSGR_H
+
+/*
+ * Data types for message passing layer used by Ceph.
+ */
+
+#define CEPH_MON_PORT    6789  /* default monitor port */
+
+/*
+ * client-side processes will try to bind to ports in this
+ * range, simply for the benefit of tools like nmap or wireshark
+ * that would like to identify the protocol.
+ */
+#define CEPH_PORT_FIRST  6789
+#define CEPH_PORT_START  6800  /* non-monitors start here */
+#define CEPH_PORT_LAST   6900
+
+/*
+ * tcp connection banner.  include a protocol version. and adjust
+ * whenever the wire protocol changes.  try to keep this string length
+ * constant.
+ */
+#define CEPH_BANNER "ceph v027"
+#define CEPH_BANNER_MAX_LEN 30
+
+
+/*
+ * Rollover-safe type and comparator for 32-bit sequence numbers.
+ * Comparator returns -1, 0, or 1.
+ */
+typedef __u32 ceph_seq_t;
+
+static inline __s32 ceph_seq_cmp(__u32 a, __u32 b)
+{
+       return (__s32)a - (__s32)b;
+}
+
+
+/*
+ * entity_name -- logical name for a process participating in the
+ * network, e.g. 'mds0' or 'osd3'.
+ */
+struct ceph_entity_name {
+	__u8 type;      /* CEPH_ENTITY_TYPE_* */
+	__le64 num;
+} __attribute__ ((packed));
+
+#define CEPH_ENTITY_TYPE_MON    0x01
+#define CEPH_ENTITY_TYPE_MDS    0x02
+#define CEPH_ENTITY_TYPE_OSD    0x04
+#define CEPH_ENTITY_TYPE_CLIENT 0x08
+#define CEPH_ENTITY_TYPE_ADMIN  0x10
+#define CEPH_ENTITY_TYPE_AUTH   0x20
+
+#define CEPH_ENTITY_TYPE_ANY    0xFF
+
+extern const char *ceph_entity_type_name(int type);
+
+/*
+ * entity_addr -- network address
+ */
+struct ceph_entity_addr {
+	__le32 type;
+	__le32 nonce;  /* unique id for process (e.g. pid) */
+	struct sockaddr_storage in_addr;
+} __attribute__ ((packed));
+
+struct ceph_entity_inst {
+	struct ceph_entity_name name;
+	struct ceph_entity_addr addr;
+} __attribute__ ((packed));
+
+
+/* used by message exchange protocol */
+#define CEPH_MSGR_TAG_READY         1  /* server->client: ready for messages */
+#define CEPH_MSGR_TAG_RESETSESSION  2  /* server->client: reset, try again */
+#define CEPH_MSGR_TAG_WAIT          3  /* server->client: wait for racing
+					  incoming connection */
+#define CEPH_MSGR_TAG_RETRY_SESSION 4  /* server->client + cseq: try again
+					  with higher cseq */
+#define CEPH_MSGR_TAG_RETRY_GLOBAL  5  /* server->client + gseq: try again
+					  with higher gseq */
+#define CEPH_MSGR_TAG_CLOSE         6  /* closing pipe */
+#define CEPH_MSGR_TAG_MSG           7  /* message */
+#define CEPH_MSGR_TAG_ACK           8  /* message ack */
+#define CEPH_MSGR_TAG_KEEPALIVE     9  /* just a keepalive byte! */
+#define CEPH_MSGR_TAG_BADPROTOVER  10  /* bad protocol version */
+#define CEPH_MSGR_TAG_BADAUTHORIZER 11 /* bad authorizer */
+#define CEPH_MSGR_TAG_FEATURES      12 /* insufficient features */
+
+
+/*
+ * connection negotiation
+ */
+struct ceph_msg_connect {
+	__le64 features;     /* supported feature bits */
+	__le32 host_type;    /* CEPH_ENTITY_TYPE_* */
+	__le32 global_seq;   /* count connections initiated by this host */
+	__le32 connect_seq;  /* count connections initiated in this session */
+	__le32 protocol_version;
+	__le32 authorizer_protocol;
+	__le32 authorizer_len;
+	__u8  flags;         /* CEPH_MSG_CONNECT_* */
+} __attribute__ ((packed));
+
+struct ceph_msg_connect_reply {
+	__u8 tag;
+	__le64 features;     /* feature bits for this session */
+	__le32 global_seq;
+	__le32 connect_seq;
+	__le32 protocol_version;
+	__le32 authorizer_len;
+	__u8 flags;
+} __attribute__ ((packed));
+
+#define CEPH_MSG_CONNECT_LOSSY  1  /* messages i send may be safely dropped */
+
+
+/*
+ * message header
+ */
+struct ceph_msg_header {
+	__le64 seq;       /* message seq# for this session */
+	__le64 tid;       /* transaction id */
+	__le16 type;      /* message type */
+	__le16 priority;  /* priority.  higher value == higher priority */
+	__le16 version;   /* version of message encoding */
+
+	__le32 front_len; /* bytes in main payload */
+	__le32 middle_len;/* bytes in middle payload */
+	__le32 data_len;  /* bytes of data payload */
+	__le16 data_off;  /* sender: include full offset;
+			     receiver: mask against ~PAGE_MASK */
+
+	struct ceph_entity_inst src, orig_src;
+	__le32 reserved;
+	__le32 crc;       /* header crc32c */
+} __attribute__ ((packed));
+
+#define CEPH_MSG_PRIO_LOW     64
+#define CEPH_MSG_PRIO_DEFAULT 127
+#define CEPH_MSG_PRIO_HIGH    196
+#define CEPH_MSG_PRIO_HIGHEST 255
+
+/*
+ * follows data payload
+ */
+struct ceph_msg_footer {
+	__le32 front_crc, middle_crc, data_crc;
+	__u8 flags;
+} __attribute__ ((packed));
+
+#define CEPH_MSG_FOOTER_COMPLETE  (1<<0)   /* msg wasn't aborted */
+#define CEPH_MSG_FOOTER_NOCRC     (1<<1)   /* no data crc */
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/osd_client.c linux-libre-2.6.34-gnu1/fs/ceph/osd_client.c
--- linux-libre-2.6.33-gnu1/fs/ceph/osd_client.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/osd_client.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1564 @@
+#include "ceph_debug.h"
+
+#include <linux/err.h>
+#include <linux/highmem.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include "super.h"
+#include "osd_client.h"
+#include "messenger.h"
+#include "decode.h"
+#include "auth.h"
+
+#define OSD_OP_FRONT_LEN	4096
+#define OSD_OPREPLY_FRONT_LEN	512
+
+const static struct ceph_connection_operations osd_con_ops;
+static int __kick_requests(struct ceph_osd_client *osdc,
+			  struct ceph_osd *kickosd);
+
+static void kick_requests(struct ceph_osd_client *osdc, struct ceph_osd *osd);
+
+/*
+ * Implement client access to distributed object storage cluster.
+ *
+ * All data objects are stored within a cluster/cloud of OSDs, or
+ * "object storage devices."  (Note that Ceph OSDs have _nothing_ to
+ * do with the T10 OSD extensions to SCSI.)  Ceph OSDs are simply
+ * remote daemons serving up and coordinating consistent and safe
+ * access to storage.
+ *
+ * Cluster membership and the mapping of data objects onto storage devices
+ * are described by the osd map.
+ *
+ * We keep track of pending OSD requests (read, write), resubmit
+ * requests to different OSDs when the cluster topology/data layout
+ * change, or retry the affected requests when the communications
+ * channel with an OSD is reset.
+ */
+
+/*
+ * calculate the mapping of a file extent onto an object, and fill out the
+ * request accordingly.  shorten extent as necessary if it crosses an
+ * object boundary.
+ *
+ * fill osd op in request message.
+ */
+static void calc_layout(struct ceph_osd_client *osdc,
+			struct ceph_vino vino, struct ceph_file_layout *layout,
+			u64 off, u64 *plen,
+			struct ceph_osd_request *req)
+{
+	struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
+	struct ceph_osd_op *op = (void *)(reqhead + 1);
+	u64 orig_len = *plen;
+	u64 objoff, objlen;    /* extent in object */
+	u64 bno;
+
+	reqhead->snapid = cpu_to_le64(vino.snap);
+
+	/* object extent? */
+	ceph_calc_file_object_mapping(layout, off, plen, &bno,
+				      &objoff, &objlen);
+	if (*plen < orig_len)
+		dout(" skipping last %llu, final file extent %llu~%llu\n",
+		     orig_len - *plen, off, *plen);
+
+	sprintf(req->r_oid, "%llx.%08llx", vino.ino, bno);
+	req->r_oid_len = strlen(req->r_oid);
+
+	op->extent.offset = cpu_to_le64(objoff);
+	op->extent.length = cpu_to_le64(objlen);
+	req->r_num_pages = calc_pages_for(off, *plen);
+
+	dout("calc_layout %s (%d) %llu~%llu (%d pages)\n",
+	     req->r_oid, req->r_oid_len, objoff, objlen, req->r_num_pages);
+}
+
+/*
+ * requests
+ */
+void ceph_osdc_release_request(struct kref *kref)
+{
+	struct ceph_osd_request *req = container_of(kref,
+						    struct ceph_osd_request,
+						    r_kref);
+
+	if (req->r_request)
+		ceph_msg_put(req->r_request);
+	if (req->r_reply)
+		ceph_msg_put(req->r_reply);
+	if (req->r_con_filling_msg) {
+		dout("release_request revoking pages %p from con %p\n",
+		     req->r_pages, req->r_con_filling_msg);
+		ceph_con_revoke_message(req->r_con_filling_msg,
+				      req->r_reply);
+		ceph_con_put(req->r_con_filling_msg);
+	}
+	if (req->r_own_pages)
+		ceph_release_page_vector(req->r_pages,
+					 req->r_num_pages);
+	ceph_put_snap_context(req->r_snapc);
+	if (req->r_mempool)
+		mempool_free(req, req->r_osdc->req_mempool);
+	else
+		kfree(req);
+}
+
+/*
+ * build new request AND message, calculate layout, and adjust file
+ * extent as needed.
+ *
+ * if the file was recently truncated, we include information about its
+ * old and new size so that the object can be updated appropriately.  (we
+ * avoid synchronously deleting truncated objects because it's slow.)
+ *
+ * if @do_sync, include a 'startsync' command so that the osd will flush
+ * data quickly.
+ */
+struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
+					       struct ceph_file_layout *layout,
+					       struct ceph_vino vino,
+					       u64 off, u64 *plen,
+					       int opcode, int flags,
+					       struct ceph_snap_context *snapc,
+					       int do_sync,
+					       u32 truncate_seq,
+					       u64 truncate_size,
+					       struct timespec *mtime,
+					       bool use_mempool, int num_reply)
+{
+	struct ceph_osd_request *req;
+	struct ceph_msg *msg;
+	struct ceph_osd_request_head *head;
+	struct ceph_osd_op *op;
+	void *p;
+	int num_op = 1 + do_sync;
+	size_t msg_size = sizeof(*head) + num_op*sizeof(*op);
+	int i;
+
+	if (use_mempool) {
+		req = mempool_alloc(osdc->req_mempool, GFP_NOFS);
+		memset(req, 0, sizeof(*req));
+	} else {
+		req = kzalloc(sizeof(*req), GFP_NOFS);
+	}
+	if (req == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	req->r_osdc = osdc;
+	req->r_mempool = use_mempool;
+	kref_init(&req->r_kref);
+	init_completion(&req->r_completion);
+	init_completion(&req->r_safe_completion);
+	INIT_LIST_HEAD(&req->r_unsafe_item);
+	req->r_flags = flags;
+
+	WARN_ON((flags & (CEPH_OSD_FLAG_READ|CEPH_OSD_FLAG_WRITE)) == 0);
+
+	/* create reply message */
+	if (use_mempool)
+		msg = ceph_msgpool_get(&osdc->msgpool_op_reply, 0);
+	else
+		msg = ceph_msg_new(CEPH_MSG_OSD_OPREPLY,
+				   OSD_OPREPLY_FRONT_LEN, 0, 0, NULL);
+	if (IS_ERR(msg)) {
+		ceph_osdc_put_request(req);
+		return ERR_PTR(PTR_ERR(msg));
+	}
+	req->r_reply = msg;
+
+	/* create request message; allow space for oid */
+	msg_size += 40;
+	if (snapc)
+		msg_size += sizeof(u64) * snapc->num_snaps;
+	if (use_mempool)
+		msg = ceph_msgpool_get(&osdc->msgpool_op, 0);
+	else
+		msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, 0, 0, NULL);
+	if (IS_ERR(msg)) {
+		ceph_osdc_put_request(req);
+		return ERR_PTR(PTR_ERR(msg));
+	}
+	msg->hdr.type = cpu_to_le16(CEPH_MSG_OSD_OP);
+	memset(msg->front.iov_base, 0, msg->front.iov_len);
+	head = msg->front.iov_base;
+	op = (void *)(head + 1);
+	p = (void *)(op + num_op);
+
+	req->r_request = msg;
+	req->r_snapc = ceph_get_snap_context(snapc);
+
+	head->client_inc = cpu_to_le32(1); /* always, for now. */
+	head->flags = cpu_to_le32(flags);
+	if (flags & CEPH_OSD_FLAG_WRITE)
+		ceph_encode_timespec(&head->mtime, mtime);
+	head->num_ops = cpu_to_le16(num_op);
+	op->op = cpu_to_le16(opcode);
+
+	/* calculate max write size */
+	calc_layout(osdc, vino, layout, off, plen, req);
+	req->r_file_layout = *layout;  /* keep a copy */
+
+	if (flags & CEPH_OSD_FLAG_WRITE) {
+		req->r_request->hdr.data_off = cpu_to_le16(off);
+		req->r_request->hdr.data_len = cpu_to_le32(*plen);
+		op->payload_len = cpu_to_le32(*plen);
+	}
+	op->extent.truncate_size = cpu_to_le64(truncate_size);
+	op->extent.truncate_seq = cpu_to_le32(truncate_seq);
+
+	/* fill in oid */
+	head->object_len = cpu_to_le32(req->r_oid_len);
+	memcpy(p, req->r_oid, req->r_oid_len);
+	p += req->r_oid_len;
+
+	if (do_sync) {
+		op++;
+		op->op = cpu_to_le16(CEPH_OSD_OP_STARTSYNC);
+	}
+	if (snapc) {
+		head->snap_seq = cpu_to_le64(snapc->seq);
+		head->num_snaps = cpu_to_le32(snapc->num_snaps);
+		for (i = 0; i < snapc->num_snaps; i++) {
+			put_unaligned_le64(snapc->snaps[i], p);
+			p += sizeof(u64);
+		}
+	}
+
+	BUG_ON(p > msg->front.iov_base + msg->front.iov_len);
+	msg_size = p - msg->front.iov_base;
+	msg->front.iov_len = msg_size;
+	msg->hdr.front_len = cpu_to_le32(msg_size);
+	return req;
+}
+
+/*
+ * We keep osd requests in an rbtree, sorted by ->r_tid.
+ */
+static void __insert_request(struct ceph_osd_client *osdc,
+			     struct ceph_osd_request *new)
+{
+	struct rb_node **p = &osdc->requests.rb_node;
+	struct rb_node *parent = NULL;
+	struct ceph_osd_request *req = NULL;
+
+	while (*p) {
+		parent = *p;
+		req = rb_entry(parent, struct ceph_osd_request, r_node);
+		if (new->r_tid < req->r_tid)
+			p = &(*p)->rb_left;
+		else if (new->r_tid > req->r_tid)
+			p = &(*p)->rb_right;
+		else
+			BUG();
+	}
+
+	rb_link_node(&new->r_node, parent, p);
+	rb_insert_color(&new->r_node, &osdc->requests);
+}
+
+static struct ceph_osd_request *__lookup_request(struct ceph_osd_client *osdc,
+						 u64 tid)
+{
+	struct ceph_osd_request *req;
+	struct rb_node *n = osdc->requests.rb_node;
+
+	while (n) {
+		req = rb_entry(n, struct ceph_osd_request, r_node);
+		if (tid < req->r_tid)
+			n = n->rb_left;
+		else if (tid > req->r_tid)
+			n = n->rb_right;
+		else
+			return req;
+	}
+	return NULL;
+}
+
+static struct ceph_osd_request *
+__lookup_request_ge(struct ceph_osd_client *osdc,
+		    u64 tid)
+{
+	struct ceph_osd_request *req;
+	struct rb_node *n = osdc->requests.rb_node;
+
+	while (n) {
+		req = rb_entry(n, struct ceph_osd_request, r_node);
+		if (tid < req->r_tid) {
+			if (!n->rb_left)
+				return req;
+			n = n->rb_left;
+		} else if (tid > req->r_tid) {
+			n = n->rb_right;
+		} else {
+			return req;
+		}
+	}
+	return NULL;
+}
+
+
+/*
+ * If the osd connection drops, we need to resubmit all requests.
+ */
+static void osd_reset(struct ceph_connection *con)
+{
+	struct ceph_osd *osd = con->private;
+	struct ceph_osd_client *osdc;
+
+	if (!osd)
+		return;
+	dout("osd_reset osd%d\n", osd->o_osd);
+	osdc = osd->o_osdc;
+	down_read(&osdc->map_sem);
+	kick_requests(osdc, osd);
+	up_read(&osdc->map_sem);
+}
+
+/*
+ * Track open sessions with osds.
+ */
+static struct ceph_osd *create_osd(struct ceph_osd_client *osdc)
+{
+	struct ceph_osd *osd;
+
+	osd = kzalloc(sizeof(*osd), GFP_NOFS);
+	if (!osd)
+		return NULL;
+
+	atomic_set(&osd->o_ref, 1);
+	osd->o_osdc = osdc;
+	INIT_LIST_HEAD(&osd->o_requests);
+	INIT_LIST_HEAD(&osd->o_osd_lru);
+	osd->o_incarnation = 1;
+
+	ceph_con_init(osdc->client->msgr, &osd->o_con);
+	osd->o_con.private = osd;
+	osd->o_con.ops = &osd_con_ops;
+	osd->o_con.peer_name.type = CEPH_ENTITY_TYPE_OSD;
+
+	INIT_LIST_HEAD(&osd->o_keepalive_item);
+	return osd;
+}
+
+static struct ceph_osd *get_osd(struct ceph_osd *osd)
+{
+	if (atomic_inc_not_zero(&osd->o_ref)) {
+		dout("get_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref)-1,
+		     atomic_read(&osd->o_ref));
+		return osd;
+	} else {
+		dout("get_osd %p FAIL\n", osd);
+		return NULL;
+	}
+}
+
+static void put_osd(struct ceph_osd *osd)
+{
+	dout("put_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref),
+	     atomic_read(&osd->o_ref) - 1);
+	if (atomic_dec_and_test(&osd->o_ref))
+		kfree(osd);
+}
+
+/*
+ * remove an osd from our map
+ */
+static void __remove_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd)
+{
+	dout("__remove_osd %p\n", osd);
+	BUG_ON(!list_empty(&osd->o_requests));
+	rb_erase(&osd->o_node, &osdc->osds);
+	list_del_init(&osd->o_osd_lru);
+	ceph_con_close(&osd->o_con);
+	put_osd(osd);
+}
+
+static void __move_osd_to_lru(struct ceph_osd_client *osdc,
+			      struct ceph_osd *osd)
+{
+	dout("__move_osd_to_lru %p\n", osd);
+	BUG_ON(!list_empty(&osd->o_osd_lru));
+	list_add_tail(&osd->o_osd_lru, &osdc->osd_lru);
+	osd->lru_ttl = jiffies + osdc->client->mount_args->osd_idle_ttl * HZ;
+}
+
+static void __remove_osd_from_lru(struct ceph_osd *osd)
+{
+	dout("__remove_osd_from_lru %p\n", osd);
+	if (!list_empty(&osd->o_osd_lru))
+		list_del_init(&osd->o_osd_lru);
+}
+
+static void remove_old_osds(struct ceph_osd_client *osdc, int remove_all)
+{
+	struct ceph_osd *osd, *nosd;
+
+	dout("__remove_old_osds %p\n", osdc);
+	mutex_lock(&osdc->request_mutex);
+	list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) {
+		if (!remove_all && time_before(jiffies, osd->lru_ttl))
+			break;
+		__remove_osd(osdc, osd);
+	}
+	mutex_unlock(&osdc->request_mutex);
+}
+
+/*
+ * reset osd connect
+ */
+static int __reset_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd)
+{
+	struct ceph_osd_request *req;
+	int ret = 0;
+
+	dout("__reset_osd %p osd%d\n", osd, osd->o_osd);
+	if (list_empty(&osd->o_requests)) {
+		__remove_osd(osdc, osd);
+	} else if (memcmp(&osdc->osdmap->osd_addr[osd->o_osd],
+			  &osd->o_con.peer_addr,
+			  sizeof(osd->o_con.peer_addr)) == 0 &&
+		   !ceph_con_opened(&osd->o_con)) {
+		dout(" osd addr hasn't changed and connection never opened,"
+		     " letting msgr retry");
+		/* touch each r_stamp for handle_timeout()'s benfit */
+		list_for_each_entry(req, &osd->o_requests, r_osd_item)
+			req->r_stamp = jiffies;
+		ret = -EAGAIN;
+	} else {
+		ceph_con_close(&osd->o_con);
+		ceph_con_open(&osd->o_con, &osdc->osdmap->osd_addr[osd->o_osd]);
+		osd->o_incarnation++;
+	}
+	return ret;
+}
+
+static void __insert_osd(struct ceph_osd_client *osdc, struct ceph_osd *new)
+{
+	struct rb_node **p = &osdc->osds.rb_node;
+	struct rb_node *parent = NULL;
+	struct ceph_osd *osd = NULL;
+
+	while (*p) {
+		parent = *p;
+		osd = rb_entry(parent, struct ceph_osd, o_node);
+		if (new->o_osd < osd->o_osd)
+			p = &(*p)->rb_left;
+		else if (new->o_osd > osd->o_osd)
+			p = &(*p)->rb_right;
+		else
+			BUG();
+	}
+
+	rb_link_node(&new->o_node, parent, p);
+	rb_insert_color(&new->o_node, &osdc->osds);
+}
+
+static struct ceph_osd *__lookup_osd(struct ceph_osd_client *osdc, int o)
+{
+	struct ceph_osd *osd;
+	struct rb_node *n = osdc->osds.rb_node;
+
+	while (n) {
+		osd = rb_entry(n, struct ceph_osd, o_node);
+		if (o < osd->o_osd)
+			n = n->rb_left;
+		else if (o > osd->o_osd)
+			n = n->rb_right;
+		else
+			return osd;
+	}
+	return NULL;
+}
+
+static void __schedule_osd_timeout(struct ceph_osd_client *osdc)
+{
+	schedule_delayed_work(&osdc->timeout_work,
+			osdc->client->mount_args->osd_keepalive_timeout * HZ);
+}
+
+static void __cancel_osd_timeout(struct ceph_osd_client *osdc)
+{
+	cancel_delayed_work(&osdc->timeout_work);
+}
+
+/*
+ * Register request, assign tid.  If this is the first request, set up
+ * the timeout event.
+ */
+static void register_request(struct ceph_osd_client *osdc,
+			     struct ceph_osd_request *req)
+{
+	mutex_lock(&osdc->request_mutex);
+	req->r_tid = ++osdc->last_tid;
+	req->r_request->hdr.tid = cpu_to_le64(req->r_tid);
+	INIT_LIST_HEAD(&req->r_req_lru_item);
+
+	dout("register_request %p tid %lld\n", req, req->r_tid);
+	__insert_request(osdc, req);
+	ceph_osdc_get_request(req);
+	osdc->num_requests++;
+
+	if (osdc->num_requests == 1) {
+		dout(" first request, scheduling timeout\n");
+		__schedule_osd_timeout(osdc);
+	}
+	mutex_unlock(&osdc->request_mutex);
+}
+
+/*
+ * called under osdc->request_mutex
+ */
+static void __unregister_request(struct ceph_osd_client *osdc,
+				 struct ceph_osd_request *req)
+{
+	dout("__unregister_request %p tid %lld\n", req, req->r_tid);
+	rb_erase(&req->r_node, &osdc->requests);
+	osdc->num_requests--;
+
+	if (req->r_osd) {
+		/* make sure the original request isn't in flight. */
+		ceph_con_revoke(&req->r_osd->o_con, req->r_request);
+
+		list_del_init(&req->r_osd_item);
+		if (list_empty(&req->r_osd->o_requests))
+			__move_osd_to_lru(osdc, req->r_osd);
+		req->r_osd = NULL;
+	}
+
+	ceph_osdc_put_request(req);
+
+	list_del_init(&req->r_req_lru_item);
+	if (osdc->num_requests == 0) {
+		dout(" no requests, canceling timeout\n");
+		__cancel_osd_timeout(osdc);
+	}
+}
+
+/*
+ * Cancel a previously queued request message
+ */
+static void __cancel_request(struct ceph_osd_request *req)
+{
+	if (req->r_sent) {
+		ceph_con_revoke(&req->r_osd->o_con, req->r_request);
+		req->r_sent = 0;
+	}
+	list_del_init(&req->r_req_lru_item);
+}
+
+/*
+ * Pick an osd (the first 'up' osd in the pg), allocate the osd struct
+ * (as needed), and set the request r_osd appropriately.  If there is
+ * no up osd, set r_osd to NULL.
+ *
+ * Return 0 if unchanged, 1 if changed, or negative on error.
+ *
+ * Caller should hold map_sem for read and request_mutex.
+ */
+static int __map_osds(struct ceph_osd_client *osdc,
+		      struct ceph_osd_request *req)
+{
+	struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
+	struct ceph_pg pgid;
+	int acting[CEPH_PG_MAX_SIZE];
+	int o = -1, num = 0;
+	int err;
+
+	dout("map_osds %p tid %lld\n", req, req->r_tid);
+	err = ceph_calc_object_layout(&reqhead->layout, req->r_oid,
+				      &req->r_file_layout, osdc->osdmap);
+	if (err)
+		return err;
+	pgid = reqhead->layout.ol_pgid;
+	req->r_pgid = pgid;
+
+	err = ceph_calc_pg_acting(osdc->osdmap, pgid, acting);
+	if (err > 0) {
+		o = acting[0];
+		num = err;
+	}
+
+	if ((req->r_osd && req->r_osd->o_osd == o &&
+	     req->r_sent >= req->r_osd->o_incarnation &&
+	     req->r_num_pg_osds == num &&
+	     memcmp(req->r_pg_osds, acting, sizeof(acting[0])*num) == 0) ||
+	    (req->r_osd == NULL && o == -1))
+		return 0;  /* no change */
+
+	dout("map_osds tid %llu pgid %d.%x osd%d (was osd%d)\n",
+	     req->r_tid, le32_to_cpu(pgid.pool), le16_to_cpu(pgid.ps), o,
+	     req->r_osd ? req->r_osd->o_osd : -1);
+
+	/* record full pg acting set */
+	memcpy(req->r_pg_osds, acting, sizeof(acting[0]) * num);
+	req->r_num_pg_osds = num;
+
+	if (req->r_osd) {
+		__cancel_request(req);
+		list_del_init(&req->r_osd_item);
+		req->r_osd = NULL;
+	}
+
+	req->r_osd = __lookup_osd(osdc, o);
+	if (!req->r_osd && o >= 0) {
+		err = -ENOMEM;
+		req->r_osd = create_osd(osdc);
+		if (!req->r_osd)
+			goto out;
+
+		dout("map_osds osd %p is osd%d\n", req->r_osd, o);
+		req->r_osd->o_osd = o;
+		req->r_osd->o_con.peer_name.num = cpu_to_le64(o);
+		__insert_osd(osdc, req->r_osd);
+
+		ceph_con_open(&req->r_osd->o_con, &osdc->osdmap->osd_addr[o]);
+	}
+
+	if (req->r_osd) {
+		__remove_osd_from_lru(req->r_osd);
+		list_add(&req->r_osd_item, &req->r_osd->o_requests);
+	}
+	err = 1;   /* osd or pg changed */
+
+out:
+	return err;
+}
+
+/*
+ * caller should hold map_sem (for read) and request_mutex
+ */
+static int __send_request(struct ceph_osd_client *osdc,
+			  struct ceph_osd_request *req)
+{
+	struct ceph_osd_request_head *reqhead;
+	int err;
+
+	err = __map_osds(osdc, req);
+	if (err < 0)
+		return err;
+	if (req->r_osd == NULL) {
+		dout("send_request %p no up osds in pg\n", req);
+		ceph_monc_request_next_osdmap(&osdc->client->monc);
+		return 0;
+	}
+
+	dout("send_request %p tid %llu to osd%d flags %d\n",
+	     req, req->r_tid, req->r_osd->o_osd, req->r_flags);
+
+	reqhead = req->r_request->front.iov_base;
+	reqhead->osdmap_epoch = cpu_to_le32(osdc->osdmap->epoch);
+	reqhead->flags |= cpu_to_le32(req->r_flags);  /* e.g., RETRY */
+	reqhead->reassert_version = req->r_reassert_version;
+
+	req->r_stamp = jiffies;
+	list_move_tail(&osdc->req_lru, &req->r_req_lru_item);
+
+	ceph_msg_get(req->r_request); /* send consumes a ref */
+	ceph_con_send(&req->r_osd->o_con, req->r_request);
+	req->r_sent = req->r_osd->o_incarnation;
+	return 0;
+}
+
+/*
+ * Timeout callback, called every N seconds when 1 or more osd
+ * requests has been active for more than N seconds.  When this
+ * happens, we ping all OSDs with requests who have timed out to
+ * ensure any communications channel reset is detected.  Reset the
+ * request timeouts another N seconds in the future as we go.
+ * Reschedule the timeout event another N seconds in future (unless
+ * there are no open requests).
+ */
+static void handle_timeout(struct work_struct *work)
+{
+	struct ceph_osd_client *osdc =
+		container_of(work, struct ceph_osd_client, timeout_work.work);
+	struct ceph_osd_request *req, *last_req = NULL;
+	struct ceph_osd *osd;
+	unsigned long timeout = osdc->client->mount_args->osd_timeout * HZ;
+	unsigned long keepalive =
+		osdc->client->mount_args->osd_keepalive_timeout * HZ;
+	unsigned long last_stamp = 0;
+	struct rb_node *p;
+	struct list_head slow_osds;
+
+	dout("timeout\n");
+	down_read(&osdc->map_sem);
+
+	ceph_monc_request_next_osdmap(&osdc->client->monc);
+
+	mutex_lock(&osdc->request_mutex);
+	for (p = rb_first(&osdc->requests); p; p = rb_next(p)) {
+		req = rb_entry(p, struct ceph_osd_request, r_node);
+
+		if (req->r_resend) {
+			int err;
+
+			dout("osdc resending prev failed %lld\n", req->r_tid);
+			err = __send_request(osdc, req);
+			if (err)
+				dout("osdc failed again on %lld\n", req->r_tid);
+			else
+				req->r_resend = false;
+			continue;
+		}
+	}
+
+	/*
+	 * reset osds that appear to be _really_ unresponsive.  this
+	 * is a failsafe measure.. we really shouldn't be getting to
+	 * this point if the system is working properly.  the monitors
+	 * should mark the osd as failed and we should find out about
+	 * it from an updated osd map.
+	 */
+	while (!list_empty(&osdc->req_lru)) {
+		req = list_entry(osdc->req_lru.next, struct ceph_osd_request,
+				 r_req_lru_item);
+
+		if (time_before(jiffies, req->r_stamp + timeout))
+			break;
+
+		BUG_ON(req == last_req && req->r_stamp == last_stamp);
+		last_req = req;
+		last_stamp = req->r_stamp;
+
+		osd = req->r_osd;
+		BUG_ON(!osd);
+		pr_warning(" tid %llu timed out on osd%d, will reset osd\n",
+			   req->r_tid, osd->o_osd);
+		__kick_requests(osdc, osd);
+	}
+
+	/*
+	 * ping osds that are a bit slow.  this ensures that if there
+	 * is a break in the TCP connection we will notice, and reopen
+	 * a connection with that osd (from the fault callback).
+	 */
+	INIT_LIST_HEAD(&slow_osds);
+	list_for_each_entry(req, &osdc->req_lru, r_req_lru_item) {
+		if (time_before(jiffies, req->r_stamp + keepalive))
+			break;
+
+		osd = req->r_osd;
+		BUG_ON(!osd);
+		dout(" tid %llu is slow, will send keepalive on osd%d\n",
+		     req->r_tid, osd->o_osd);
+		list_move_tail(&osd->o_keepalive_item, &slow_osds);
+	}
+	while (!list_empty(&slow_osds)) {
+		osd = list_entry(slow_osds.next, struct ceph_osd,
+				 o_keepalive_item);
+		list_del_init(&osd->o_keepalive_item);
+		ceph_con_keepalive(&osd->o_con);
+	}
+
+	__schedule_osd_timeout(osdc);
+	mutex_unlock(&osdc->request_mutex);
+
+	up_read(&osdc->map_sem);
+}
+
+static void handle_osds_timeout(struct work_struct *work)
+{
+	struct ceph_osd_client *osdc =
+		container_of(work, struct ceph_osd_client,
+			     osds_timeout_work.work);
+	unsigned long delay =
+		osdc->client->mount_args->osd_idle_ttl * HZ >> 2;
+
+	dout("osds timeout\n");
+	down_read(&osdc->map_sem);
+	remove_old_osds(osdc, 0);
+	up_read(&osdc->map_sem);
+
+	schedule_delayed_work(&osdc->osds_timeout_work,
+			      round_jiffies_relative(delay));
+}
+
+/*
+ * handle osd op reply.  either call the callback if it is specified,
+ * or do the completion to wake up the waiting thread.
+ */
+static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
+			 struct ceph_connection *con)
+{
+	struct ceph_osd_reply_head *rhead = msg->front.iov_base;
+	struct ceph_osd_request *req;
+	u64 tid;
+	int numops, object_len, flags;
+	s32 result;
+
+	tid = le64_to_cpu(msg->hdr.tid);
+	if (msg->front.iov_len < sizeof(*rhead))
+		goto bad;
+	numops = le32_to_cpu(rhead->num_ops);
+	object_len = le32_to_cpu(rhead->object_len);
+	result = le32_to_cpu(rhead->result);
+	if (msg->front.iov_len != sizeof(*rhead) + object_len +
+	    numops * sizeof(struct ceph_osd_op))
+		goto bad;
+	dout("handle_reply %p tid %llu result %d\n", msg, tid, (int)result);
+
+	/* lookup */
+	mutex_lock(&osdc->request_mutex);
+	req = __lookup_request(osdc, tid);
+	if (req == NULL) {
+		dout("handle_reply tid %llu dne\n", tid);
+		mutex_unlock(&osdc->request_mutex);
+		return;
+	}
+	ceph_osdc_get_request(req);
+	flags = le32_to_cpu(rhead->flags);
+
+	/*
+	 * if this connection filled our message, drop our reference now, to
+	 * avoid a (safe but slower) revoke later.
+	 */
+	if (req->r_con_filling_msg == con && req->r_reply == msg) {
+		dout(" dropping con_filling_msg ref %p\n", con);
+		req->r_con_filling_msg = NULL;
+		ceph_con_put(con);
+	}
+
+	if (!req->r_got_reply) {
+		unsigned bytes;
+
+		req->r_result = le32_to_cpu(rhead->result);
+		bytes = le32_to_cpu(msg->hdr.data_len);
+		dout("handle_reply result %d bytes %d\n", req->r_result,
+		     bytes);
+		if (req->r_result == 0)
+			req->r_result = bytes;
+
+		/* in case this is a write and we need to replay, */
+		req->r_reassert_version = rhead->reassert_version;
+
+		req->r_got_reply = 1;
+	} else if ((flags & CEPH_OSD_FLAG_ONDISK) == 0) {
+		dout("handle_reply tid %llu dup ack\n", tid);
+		mutex_unlock(&osdc->request_mutex);
+		goto done;
+	}
+
+	dout("handle_reply tid %llu flags %d\n", tid, flags);
+
+	/* either this is a read, or we got the safe response */
+	if (result < 0 ||
+	    (flags & CEPH_OSD_FLAG_ONDISK) ||
+	    ((flags & CEPH_OSD_FLAG_WRITE) == 0))
+		__unregister_request(osdc, req);
+
+	mutex_unlock(&osdc->request_mutex);
+
+	if (req->r_callback)
+		req->r_callback(req, msg);
+	else
+		complete(&req->r_completion);
+
+	if (flags & CEPH_OSD_FLAG_ONDISK) {
+		if (req->r_safe_callback)
+			req->r_safe_callback(req, msg);
+		complete(&req->r_safe_completion);  /* fsync waiter */
+	}
+
+done:
+	ceph_osdc_put_request(req);
+	return;
+
+bad:
+	pr_err("corrupt osd_op_reply got %d %d expected %d\n",
+	       (int)msg->front.iov_len, le32_to_cpu(msg->hdr.front_len),
+	       (int)sizeof(*rhead));
+	ceph_msg_dump(msg);
+}
+
+
+static int __kick_requests(struct ceph_osd_client *osdc,
+			  struct ceph_osd *kickosd)
+{
+	struct ceph_osd_request *req;
+	struct rb_node *p, *n;
+	int needmap = 0;
+	int err;
+
+	dout("kick_requests osd%d\n", kickosd ? kickosd->o_osd : -1);
+	if (kickosd) {
+		err = __reset_osd(osdc, kickosd);
+		if (err == -EAGAIN)
+			return 1;
+	} else {
+		for (p = rb_first(&osdc->osds); p; p = n) {
+			struct ceph_osd *osd =
+				rb_entry(p, struct ceph_osd, o_node);
+
+			n = rb_next(p);
+			if (!ceph_osd_is_up(osdc->osdmap, osd->o_osd) ||
+			    memcmp(&osd->o_con.peer_addr,
+				   ceph_osd_addr(osdc->osdmap,
+						 osd->o_osd),
+				   sizeof(struct ceph_entity_addr)) != 0)
+				__reset_osd(osdc, osd);
+		}
+	}
+
+	for (p = rb_first(&osdc->requests); p; p = rb_next(p)) {
+		req = rb_entry(p, struct ceph_osd_request, r_node);
+
+		if (req->r_resend) {
+			dout(" r_resend set on tid %llu\n", req->r_tid);
+			__cancel_request(req);
+			goto kick;
+		}
+		if (req->r_osd && kickosd == req->r_osd) {
+			__cancel_request(req);
+			goto kick;
+		}
+
+		err = __map_osds(osdc, req);
+		if (err == 0)
+			continue;  /* no change */
+		if (err < 0) {
+			/*
+			 * FIXME: really, we should set the request
+			 * error and fail if this isn't a 'nofail'
+			 * request, but that's a fair bit more
+			 * complicated to do.  So retry!
+			 */
+			dout(" setting r_resend on %llu\n", req->r_tid);
+			req->r_resend = true;
+			continue;
+		}
+		if (req->r_osd == NULL) {
+			dout("tid %llu maps to no valid osd\n", req->r_tid);
+			needmap++;  /* request a newer map */
+			continue;
+		}
+
+kick:
+		dout("kicking %p tid %llu osd%d\n", req, req->r_tid,
+		     req->r_osd ? req->r_osd->o_osd : -1);
+		req->r_flags |= CEPH_OSD_FLAG_RETRY;
+		err = __send_request(osdc, req);
+		if (err) {
+			dout(" setting r_resend on %llu\n", req->r_tid);
+			req->r_resend = true;
+		}
+	}
+
+	return needmap;
+}
+
+/*
+ * Resubmit osd requests whose osd or osd address has changed.  Request
+ * a new osd map if osds are down, or we are otherwise unable to determine
+ * how to direct a request.
+ *
+ * Close connections to down osds.
+ *
+ * If @who is specified, resubmit requests for that specific osd.
+ *
+ * Caller should hold map_sem for read and request_mutex.
+ */
+static void kick_requests(struct ceph_osd_client *osdc,
+			  struct ceph_osd *kickosd)
+{
+	int needmap;
+
+	mutex_lock(&osdc->request_mutex);
+	needmap = __kick_requests(osdc, kickosd);
+	mutex_unlock(&osdc->request_mutex);
+
+	if (needmap) {
+		dout("%d requests for down osds, need new map\n", needmap);
+		ceph_monc_request_next_osdmap(&osdc->client->monc);
+	}
+
+}
+/*
+ * Process updated osd map.
+ *
+ * The message contains any number of incremental and full maps, normally
+ * indicating some sort of topology change in the cluster.  Kick requests
+ * off to different OSDs as needed.
+ */
+void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
+{
+	void *p, *end, *next;
+	u32 nr_maps, maplen;
+	u32 epoch;
+	struct ceph_osdmap *newmap = NULL, *oldmap;
+	int err;
+	struct ceph_fsid fsid;
+
+	dout("handle_map have %u\n", osdc->osdmap ? osdc->osdmap->epoch : 0);
+	p = msg->front.iov_base;
+	end = p + msg->front.iov_len;
+
+	/* verify fsid */
+	ceph_decode_need(&p, end, sizeof(fsid), bad);
+	ceph_decode_copy(&p, &fsid, sizeof(fsid));
+	if (ceph_check_fsid(osdc->client, &fsid) < 0)
+		return;
+
+	down_write(&osdc->map_sem);
+
+	/* incremental maps */
+	ceph_decode_32_safe(&p, end, nr_maps, bad);
+	dout(" %d inc maps\n", nr_maps);
+	while (nr_maps > 0) {
+		ceph_decode_need(&p, end, 2*sizeof(u32), bad);
+		epoch = ceph_decode_32(&p);
+		maplen = ceph_decode_32(&p);
+		ceph_decode_need(&p, end, maplen, bad);
+		next = p + maplen;
+		if (osdc->osdmap && osdc->osdmap->epoch+1 == epoch) {
+			dout("applying incremental map %u len %d\n",
+			     epoch, maplen);
+			newmap = osdmap_apply_incremental(&p, next,
+							  osdc->osdmap,
+							  osdc->client->msgr);
+			if (IS_ERR(newmap)) {
+				err = PTR_ERR(newmap);
+				goto bad;
+			}
+			BUG_ON(!newmap);
+			if (newmap != osdc->osdmap) {
+				ceph_osdmap_destroy(osdc->osdmap);
+				osdc->osdmap = newmap;
+			}
+		} else {
+			dout("ignoring incremental map %u len %d\n",
+			     epoch, maplen);
+		}
+		p = next;
+		nr_maps--;
+	}
+	if (newmap)
+		goto done;
+
+	/* full maps */
+	ceph_decode_32_safe(&p, end, nr_maps, bad);
+	dout(" %d full maps\n", nr_maps);
+	while (nr_maps) {
+		ceph_decode_need(&p, end, 2*sizeof(u32), bad);
+		epoch = ceph_decode_32(&p);
+		maplen = ceph_decode_32(&p);
+		ceph_decode_need(&p, end, maplen, bad);
+		if (nr_maps > 1) {
+			dout("skipping non-latest full map %u len %d\n",
+			     epoch, maplen);
+		} else if (osdc->osdmap && osdc->osdmap->epoch >= epoch) {
+			dout("skipping full map %u len %d, "
+			     "older than our %u\n", epoch, maplen,
+			     osdc->osdmap->epoch);
+		} else {
+			dout("taking full map %u len %d\n", epoch, maplen);
+			newmap = osdmap_decode(&p, p+maplen);
+			if (IS_ERR(newmap)) {
+				err = PTR_ERR(newmap);
+				goto bad;
+			}
+			BUG_ON(!newmap);
+			oldmap = osdc->osdmap;
+			osdc->osdmap = newmap;
+			if (oldmap)
+				ceph_osdmap_destroy(oldmap);
+		}
+		p += maplen;
+		nr_maps--;
+	}
+
+done:
+	downgrade_write(&osdc->map_sem);
+	ceph_monc_got_osdmap(&osdc->client->monc, osdc->osdmap->epoch);
+	if (newmap)
+		kick_requests(osdc, NULL);
+	up_read(&osdc->map_sem);
+	return;
+
+bad:
+	pr_err("osdc handle_map corrupt msg\n");
+	ceph_msg_dump(msg);
+	up_write(&osdc->map_sem);
+	return;
+}
+
+
+/*
+ * A read request prepares specific pages that data is to be read into.
+ * When a message is being read off the wire, we call prepare_pages to
+ * find those pages.
+ *  0 = success, -1 failure.
+ */
+static int __prepare_pages(struct ceph_connection *con,
+			 struct ceph_msg_header *hdr,
+			 struct ceph_osd_request *req,
+			 u64 tid,
+			 struct ceph_msg *m)
+{
+	struct ceph_osd *osd = con->private;
+	struct ceph_osd_client *osdc;
+	int ret = -1;
+	int data_len = le32_to_cpu(hdr->data_len);
+	unsigned data_off = le16_to_cpu(hdr->data_off);
+
+	int want = calc_pages_for(data_off & ~PAGE_MASK, data_len);
+
+	if (!osd)
+		return -1;
+
+	osdc = osd->o_osdc;
+
+	dout("__prepare_pages on msg %p tid %llu, has %d pages, want %d\n", m,
+	     tid, req->r_num_pages, want);
+	if (unlikely(req->r_num_pages < want))
+		goto out;
+	m->pages = req->r_pages;
+	m->nr_pages = req->r_num_pages;
+	ret = 0; /* success */
+out:
+	BUG_ON(ret < 0 || m->nr_pages < want);
+
+	return ret;
+}
+
+/*
+ * Register request, send initial attempt.
+ */
+int ceph_osdc_start_request(struct ceph_osd_client *osdc,
+			    struct ceph_osd_request *req,
+			    bool nofail)
+{
+	int rc = 0;
+
+	req->r_request->pages = req->r_pages;
+	req->r_request->nr_pages = req->r_num_pages;
+
+	register_request(osdc, req);
+
+	down_read(&osdc->map_sem);
+	mutex_lock(&osdc->request_mutex);
+	/*
+	 * a racing kick_requests() may have sent the message for us
+	 * while we dropped request_mutex above, so only send now if
+	 * the request still han't been touched yet.
+	 */
+	if (req->r_sent == 0) {
+		rc = __send_request(osdc, req);
+		if (rc) {
+			if (nofail) {
+				dout("osdc_start_request failed send, "
+				     " marking %lld\n", req->r_tid);
+				req->r_resend = true;
+				rc = 0;
+			} else {
+				__unregister_request(osdc, req);
+			}
+		}
+	}
+	mutex_unlock(&osdc->request_mutex);
+	up_read(&osdc->map_sem);
+	return rc;
+}
+
+/*
+ * wait for a request to complete
+ */
+int ceph_osdc_wait_request(struct ceph_osd_client *osdc,
+			   struct ceph_osd_request *req)
+{
+	int rc;
+
+	rc = wait_for_completion_interruptible(&req->r_completion);
+	if (rc < 0) {
+		mutex_lock(&osdc->request_mutex);
+		__cancel_request(req);
+		__unregister_request(osdc, req);
+		mutex_unlock(&osdc->request_mutex);
+		dout("wait_request tid %llu canceled/timed out\n", req->r_tid);
+		return rc;
+	}
+
+	dout("wait_request tid %llu result %d\n", req->r_tid, req->r_result);
+	return req->r_result;
+}
+
+/*
+ * sync - wait for all in-flight requests to flush.  avoid starvation.
+ */
+void ceph_osdc_sync(struct ceph_osd_client *osdc)
+{
+	struct ceph_osd_request *req;
+	u64 last_tid, next_tid = 0;
+
+	mutex_lock(&osdc->request_mutex);
+	last_tid = osdc->last_tid;
+	while (1) {
+		req = __lookup_request_ge(osdc, next_tid);
+		if (!req)
+			break;
+		if (req->r_tid > last_tid)
+			break;
+
+		next_tid = req->r_tid + 1;
+		if ((req->r_flags & CEPH_OSD_FLAG_WRITE) == 0)
+			continue;
+
+		ceph_osdc_get_request(req);
+		mutex_unlock(&osdc->request_mutex);
+		dout("sync waiting on tid %llu (last is %llu)\n",
+		     req->r_tid, last_tid);
+		wait_for_completion(&req->r_safe_completion);
+		mutex_lock(&osdc->request_mutex);
+		ceph_osdc_put_request(req);
+	}
+	mutex_unlock(&osdc->request_mutex);
+	dout("sync done (thru tid %llu)\n", last_tid);
+}
+
+/*
+ * init, shutdown
+ */
+int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client)
+{
+	int err;
+
+	dout("init\n");
+	osdc->client = client;
+	osdc->osdmap = NULL;
+	init_rwsem(&osdc->map_sem);
+	init_completion(&osdc->map_waiters);
+	osdc->last_requested_map = 0;
+	mutex_init(&osdc->request_mutex);
+	osdc->last_tid = 0;
+	osdc->osds = RB_ROOT;
+	INIT_LIST_HEAD(&osdc->osd_lru);
+	osdc->requests = RB_ROOT;
+	INIT_LIST_HEAD(&osdc->req_lru);
+	osdc->num_requests = 0;
+	INIT_DELAYED_WORK(&osdc->timeout_work, handle_timeout);
+	INIT_DELAYED_WORK(&osdc->osds_timeout_work, handle_osds_timeout);
+
+	schedule_delayed_work(&osdc->osds_timeout_work,
+	   round_jiffies_relative(osdc->client->mount_args->osd_idle_ttl * HZ));
+
+	err = -ENOMEM;
+	osdc->req_mempool = mempool_create_kmalloc_pool(10,
+					sizeof(struct ceph_osd_request));
+	if (!osdc->req_mempool)
+		goto out;
+
+	err = ceph_msgpool_init(&osdc->msgpool_op, OSD_OP_FRONT_LEN, 10, true);
+	if (err < 0)
+		goto out_mempool;
+	err = ceph_msgpool_init(&osdc->msgpool_op_reply,
+				OSD_OPREPLY_FRONT_LEN, 10, true);
+	if (err < 0)
+		goto out_msgpool;
+	return 0;
+
+out_msgpool:
+	ceph_msgpool_destroy(&osdc->msgpool_op);
+out_mempool:
+	mempool_destroy(osdc->req_mempool);
+out:
+	return err;
+}
+
+void ceph_osdc_stop(struct ceph_osd_client *osdc)
+{
+	cancel_delayed_work_sync(&osdc->timeout_work);
+	cancel_delayed_work_sync(&osdc->osds_timeout_work);
+	if (osdc->osdmap) {
+		ceph_osdmap_destroy(osdc->osdmap);
+		osdc->osdmap = NULL;
+	}
+	remove_old_osds(osdc, 1);
+	mempool_destroy(osdc->req_mempool);
+	ceph_msgpool_destroy(&osdc->msgpool_op);
+	ceph_msgpool_destroy(&osdc->msgpool_op_reply);
+}
+
+/*
+ * Read some contiguous pages.  If we cross a stripe boundary, shorten
+ * *plen.  Return number of bytes read, or error.
+ */
+int ceph_osdc_readpages(struct ceph_osd_client *osdc,
+			struct ceph_vino vino, struct ceph_file_layout *layout,
+			u64 off, u64 *plen,
+			u32 truncate_seq, u64 truncate_size,
+			struct page **pages, int num_pages)
+{
+	struct ceph_osd_request *req;
+	int rc = 0;
+
+	dout("readpages on ino %llx.%llx on %llu~%llu\n", vino.ino,
+	     vino.snap, off, *plen);
+	req = ceph_osdc_new_request(osdc, layout, vino, off, plen,
+				    CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ,
+				    NULL, 0, truncate_seq, truncate_size, NULL,
+				    false, 1);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	/* it may be a short read due to an object boundary */
+	req->r_pages = pages;
+	num_pages = calc_pages_for(off, *plen);
+	req->r_num_pages = num_pages;
+
+	dout("readpages  final extent is %llu~%llu (%d pages)\n",
+	     off, *plen, req->r_num_pages);
+
+	rc = ceph_osdc_start_request(osdc, req, false);
+	if (!rc)
+		rc = ceph_osdc_wait_request(osdc, req);
+
+	ceph_osdc_put_request(req);
+	dout("readpages result %d\n", rc);
+	return rc;
+}
+
+/*
+ * do a synchronous write on N pages
+ */
+int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
+			 struct ceph_file_layout *layout,
+			 struct ceph_snap_context *snapc,
+			 u64 off, u64 len,
+			 u32 truncate_seq, u64 truncate_size,
+			 struct timespec *mtime,
+			 struct page **pages, int num_pages,
+			 int flags, int do_sync, bool nofail)
+{
+	struct ceph_osd_request *req;
+	int rc = 0;
+
+	BUG_ON(vino.snap != CEPH_NOSNAP);
+	req = ceph_osdc_new_request(osdc, layout, vino, off, &len,
+				    CEPH_OSD_OP_WRITE,
+				    flags | CEPH_OSD_FLAG_ONDISK |
+					    CEPH_OSD_FLAG_WRITE,
+				    snapc, do_sync,
+				    truncate_seq, truncate_size, mtime,
+				    nofail, 1);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	/* it may be a short write due to an object boundary */
+	req->r_pages = pages;
+	req->r_num_pages = calc_pages_for(off, len);
+	dout("writepages %llu~%llu (%d pages)\n", off, len,
+	     req->r_num_pages);
+
+	rc = ceph_osdc_start_request(osdc, req, nofail);
+	if (!rc)
+		rc = ceph_osdc_wait_request(osdc, req);
+
+	ceph_osdc_put_request(req);
+	if (rc == 0)
+		rc = len;
+	dout("writepages result %d\n", rc);
+	return rc;
+}
+
+/*
+ * handle incoming message
+ */
+static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
+{
+	struct ceph_osd *osd = con->private;
+	struct ceph_osd_client *osdc;
+	int type = le16_to_cpu(msg->hdr.type);
+
+	if (!osd)
+		return;
+	osdc = osd->o_osdc;
+
+	switch (type) {
+	case CEPH_MSG_OSD_MAP:
+		ceph_osdc_handle_map(osdc, msg);
+		break;
+	case CEPH_MSG_OSD_OPREPLY:
+		handle_reply(osdc, msg, con);
+		break;
+
+	default:
+		pr_err("received unknown message type %d %s\n", type,
+		       ceph_msg_type_name(type));
+	}
+	ceph_msg_put(msg);
+}
+
+/*
+ * lookup and return message for incoming reply
+ */
+static struct ceph_msg *get_reply(struct ceph_connection *con,
+				  struct ceph_msg_header *hdr,
+				  int *skip)
+{
+	struct ceph_osd *osd = con->private;
+	struct ceph_osd_client *osdc = osd->o_osdc;
+	struct ceph_msg *m;
+	struct ceph_osd_request *req;
+	int front = le32_to_cpu(hdr->front_len);
+	int data_len = le32_to_cpu(hdr->data_len);
+	u64 tid;
+	int err;
+
+	tid = le64_to_cpu(hdr->tid);
+	mutex_lock(&osdc->request_mutex);
+	req = __lookup_request(osdc, tid);
+	if (!req) {
+		*skip = 1;
+		m = NULL;
+		pr_info("get_reply unknown tid %llu from osd%d\n", tid,
+			osd->o_osd);
+		goto out;
+	}
+
+	if (req->r_con_filling_msg) {
+		dout("get_reply revoking msg %p from old con %p\n",
+		     req->r_reply, req->r_con_filling_msg);
+		ceph_con_revoke_message(req->r_con_filling_msg, req->r_reply);
+		ceph_con_put(req->r_con_filling_msg);
+	}
+
+	if (front > req->r_reply->front.iov_len) {
+		pr_warning("get_reply front %d > preallocated %d\n",
+			   front, (int)req->r_reply->front.iov_len);
+		m = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, front, 0, 0, NULL);
+		if (IS_ERR(m))
+			goto out;
+		ceph_msg_put(req->r_reply);
+		req->r_reply = m;
+	}
+	m = ceph_msg_get(req->r_reply);
+
+	if (data_len > 0) {
+		err = __prepare_pages(con, hdr, req, tid, m);
+		if (err < 0) {
+			*skip = 1;
+			ceph_msg_put(m);
+			m = ERR_PTR(err);
+		}
+	}
+	*skip = 0;
+	req->r_con_filling_msg = ceph_con_get(con);
+	dout("get_reply tid %lld %p\n", tid, m);
+
+out:
+	mutex_unlock(&osdc->request_mutex);
+	return m;
+
+}
+
+static struct ceph_msg *alloc_msg(struct ceph_connection *con,
+				  struct ceph_msg_header *hdr,
+				  int *skip)
+{
+	struct ceph_osd *osd = con->private;
+	int type = le16_to_cpu(hdr->type);
+	int front = le32_to_cpu(hdr->front_len);
+
+	switch (type) {
+	case CEPH_MSG_OSD_MAP:
+		return ceph_msg_new(type, front, 0, 0, NULL);
+	case CEPH_MSG_OSD_OPREPLY:
+		return get_reply(con, hdr, skip);
+	default:
+		pr_info("alloc_msg unexpected msg type %d from osd%d\n", type,
+			osd->o_osd);
+		*skip = 1;
+		return NULL;
+	}
+}
+
+/*
+ * Wrappers to refcount containing ceph_osd struct
+ */
+static struct ceph_connection *get_osd_con(struct ceph_connection *con)
+{
+	struct ceph_osd *osd = con->private;
+	if (get_osd(osd))
+		return con;
+	return NULL;
+}
+
+static void put_osd_con(struct ceph_connection *con)
+{
+	struct ceph_osd *osd = con->private;
+	put_osd(osd);
+}
+
+/*
+ * authentication
+ */
+static int get_authorizer(struct ceph_connection *con,
+	                  void **buf, int *len, int *proto,
+	                  void **reply_buf, int *reply_len, int force_new)
+{
+	struct ceph_osd *o = con->private;
+	struct ceph_osd_client *osdc = o->o_osdc;
+	struct ceph_auth_client *ac = osdc->client->monc.auth;
+	int ret = 0;
+
+	if (force_new && o->o_authorizer) {
+		ac->ops->destroy_authorizer(ac, o->o_authorizer);
+		o->o_authorizer = NULL;
+	}
+	if (o->o_authorizer == NULL) {
+		ret = ac->ops->create_authorizer(
+			ac, CEPH_ENTITY_TYPE_OSD,
+			&o->o_authorizer,
+			&o->o_authorizer_buf,
+			&o->o_authorizer_buf_len,
+			&o->o_authorizer_reply_buf,
+			&o->o_authorizer_reply_buf_len);
+		if (ret)
+		return ret;
+	}
+
+	*proto = ac->protocol;
+	*buf = o->o_authorizer_buf;
+	*len = o->o_authorizer_buf_len;
+	*reply_buf = o->o_authorizer_reply_buf;
+	*reply_len = o->o_authorizer_reply_buf_len;
+	return 0;
+}
+
+
+static int verify_authorizer_reply(struct ceph_connection *con, int len)
+{
+	struct ceph_osd *o = con->private;
+	struct ceph_osd_client *osdc = o->o_osdc;
+	struct ceph_auth_client *ac = osdc->client->monc.auth;
+
+	return ac->ops->verify_authorizer_reply(ac, o->o_authorizer, len);
+}
+
+static int invalidate_authorizer(struct ceph_connection *con)
+{
+	struct ceph_osd *o = con->private;
+	struct ceph_osd_client *osdc = o->o_osdc;
+	struct ceph_auth_client *ac = osdc->client->monc.auth;
+
+	if (ac->ops->invalidate_authorizer)
+		ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_OSD);
+
+	return ceph_monc_validate_auth(&osdc->client->monc);
+}
+
+const static struct ceph_connection_operations osd_con_ops = {
+	.get = get_osd_con,
+	.put = put_osd_con,
+	.dispatch = dispatch,
+	.get_authorizer = get_authorizer,
+	.verify_authorizer_reply = verify_authorizer_reply,
+	.invalidate_authorizer = invalidate_authorizer,
+	.alloc_msg = alloc_msg,
+	.fault = osd_reset,
+};
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/osd_client.h linux-libre-2.6.34-gnu1/fs/ceph/osd_client.h
--- linux-libre-2.6.33-gnu1/fs/ceph/osd_client.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/osd_client.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,167 @@
+#ifndef _FS_CEPH_OSD_CLIENT_H
+#define _FS_CEPH_OSD_CLIENT_H
+
+#include <linux/completion.h>
+#include <linux/kref.h>
+#include <linux/mempool.h>
+#include <linux/rbtree.h>
+
+#include "types.h"
+#include "osdmap.h"
+#include "messenger.h"
+
+struct ceph_msg;
+struct ceph_snap_context;
+struct ceph_osd_request;
+struct ceph_osd_client;
+struct ceph_authorizer;
+
+/*
+ * completion callback for async writepages
+ */
+typedef void (*ceph_osdc_callback_t)(struct ceph_osd_request *,
+				     struct ceph_msg *);
+
+/* a given osd we're communicating with */
+struct ceph_osd {
+	atomic_t o_ref;
+	struct ceph_osd_client *o_osdc;
+	int o_osd;
+	int o_incarnation;
+	struct rb_node o_node;
+	struct ceph_connection o_con;
+	struct list_head o_requests;
+	struct list_head o_osd_lru;
+	struct ceph_authorizer *o_authorizer;
+	void *o_authorizer_buf, *o_authorizer_reply_buf;
+	size_t o_authorizer_buf_len, o_authorizer_reply_buf_len;
+	unsigned long lru_ttl;
+	int o_marked_for_keepalive;
+	struct list_head o_keepalive_item;
+};
+
+/* an in-flight request */
+struct ceph_osd_request {
+	u64             r_tid;              /* unique for this client */
+	struct rb_node  r_node;
+	struct list_head r_req_lru_item;
+	struct list_head r_osd_item;
+	struct ceph_osd *r_osd;
+	struct ceph_pg   r_pgid;
+	int              r_pg_osds[CEPH_PG_MAX_SIZE];
+	int              r_num_pg_osds;
+
+	struct ceph_connection *r_con_filling_msg;
+
+	struct ceph_msg  *r_request, *r_reply;
+	int               r_result;
+	int               r_flags;     /* any additional flags for the osd */
+	u32               r_sent;      /* >0 if r_request is sending/sent */
+	int               r_got_reply;
+
+	struct ceph_osd_client *r_osdc;
+	struct kref       r_kref;
+	bool              r_mempool;
+	struct completion r_completion, r_safe_completion;
+	ceph_osdc_callback_t r_callback, r_safe_callback;
+	struct ceph_eversion r_reassert_version;
+	struct list_head  r_unsafe_item;
+
+	struct inode *r_inode;         	      /* for use by callbacks */
+
+	char              r_oid[40];          /* object name */
+	int               r_oid_len;
+	unsigned long     r_stamp;            /* send OR check time */
+	bool              r_resend;           /* msg send failed, needs retry */
+
+	struct ceph_file_layout r_file_layout;
+	struct ceph_snap_context *r_snapc;    /* snap context for writes */
+	unsigned          r_num_pages;        /* size of page array (follows) */
+	struct page     **r_pages;            /* pages for data payload */
+	int               r_pages_from_pool;
+	int               r_own_pages;        /* if true, i own page list */
+};
+
+struct ceph_osd_client {
+	struct ceph_client     *client;
+
+	struct ceph_osdmap     *osdmap;       /* current map */
+	struct rw_semaphore    map_sem;
+	struct completion      map_waiters;
+	u64                    last_requested_map;
+
+	struct mutex           request_mutex;
+	struct rb_root         osds;          /* osds */
+	struct list_head       osd_lru;       /* idle osds */
+	u64                    timeout_tid;   /* tid of timeout triggering rq */
+	u64                    last_tid;      /* tid of last request */
+	struct rb_root         requests;      /* pending requests */
+	struct list_head       req_lru;	      /* pending requests lru */
+	int                    num_requests;
+	struct delayed_work    timeout_work;
+	struct delayed_work    osds_timeout_work;
+#ifdef CONFIG_DEBUG_FS
+	struct dentry 	       *debugfs_file;
+#endif
+
+	mempool_t              *req_mempool;
+
+	struct ceph_msgpool	msgpool_op;
+	struct ceph_msgpool	msgpool_op_reply;
+};
+
+extern int ceph_osdc_init(struct ceph_osd_client *osdc,
+			  struct ceph_client *client);
+extern void ceph_osdc_stop(struct ceph_osd_client *osdc);
+
+extern void ceph_osdc_handle_reply(struct ceph_osd_client *osdc,
+				   struct ceph_msg *msg);
+extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc,
+				 struct ceph_msg *msg);
+
+extern struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *,
+				      struct ceph_file_layout *layout,
+				      struct ceph_vino vino,
+				      u64 offset, u64 *len, int op, int flags,
+				      struct ceph_snap_context *snapc,
+				      int do_sync, u32 truncate_seq,
+				      u64 truncate_size,
+				      struct timespec *mtime,
+				      bool use_mempool, int num_reply);
+
+static inline void ceph_osdc_get_request(struct ceph_osd_request *req)
+{
+	kref_get(&req->r_kref);
+}
+extern void ceph_osdc_release_request(struct kref *kref);
+static inline void ceph_osdc_put_request(struct ceph_osd_request *req)
+{
+	kref_put(&req->r_kref, ceph_osdc_release_request);
+}
+
+extern int ceph_osdc_start_request(struct ceph_osd_client *osdc,
+				   struct ceph_osd_request *req,
+				   bool nofail);
+extern int ceph_osdc_wait_request(struct ceph_osd_client *osdc,
+				  struct ceph_osd_request *req);
+extern void ceph_osdc_sync(struct ceph_osd_client *osdc);
+
+extern int ceph_osdc_readpages(struct ceph_osd_client *osdc,
+			       struct ceph_vino vino,
+			       struct ceph_file_layout *layout,
+			       u64 off, u64 *plen,
+			       u32 truncate_seq, u64 truncate_size,
+			       struct page **pages, int nr_pages);
+
+extern int ceph_osdc_writepages(struct ceph_osd_client *osdc,
+				struct ceph_vino vino,
+				struct ceph_file_layout *layout,
+				struct ceph_snap_context *sc,
+				u64 off, u64 len,
+				u32 truncate_seq, u64 truncate_size,
+				struct timespec *mtime,
+				struct page **pages, int nr_pages,
+				int flags, int do_sync, bool nofail);
+
+#endif
+
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/osdmap.c linux-libre-2.6.34-gnu1/fs/ceph/osdmap.c
--- linux-libre-2.6.33-gnu1/fs/ceph/osdmap.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/osdmap.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1081 @@
+
+#include "ceph_debug.h"
+
+#include <linux/slab.h>
+#include <asm/div64.h>
+
+#include "super.h"
+#include "osdmap.h"
+#include "crush/hash.h"
+#include "crush/mapper.h"
+#include "decode.h"
+
+char *ceph_osdmap_state_str(char *str, int len, int state)
+{
+	int flag = 0;
+
+	if (!len)
+		goto done;
+
+	*str = '\0';
+	if (state) {
+		if (state & CEPH_OSD_EXISTS) {
+			snprintf(str, len, "exists");
+			flag = 1;
+		}
+		if (state & CEPH_OSD_UP) {
+			snprintf(str, len, "%s%s%s", str, (flag ? ", " : ""),
+				 "up");
+			flag = 1;
+		}
+	} else {
+		snprintf(str, len, "doesn't exist");
+	}
+done:
+	return str;
+}
+
+/* maps */
+
+static int calc_bits_of(unsigned t)
+{
+	int b = 0;
+	while (t) {
+		t = t >> 1;
+		b++;
+	}
+	return b;
+}
+
+/*
+ * the foo_mask is the smallest value 2^n-1 that is >= foo.
+ */
+static void calc_pg_masks(struct ceph_pg_pool_info *pi)
+{
+	pi->pg_num_mask = (1 << calc_bits_of(le32_to_cpu(pi->v.pg_num)-1)) - 1;
+	pi->pgp_num_mask =
+		(1 << calc_bits_of(le32_to_cpu(pi->v.pgp_num)-1)) - 1;
+	pi->lpg_num_mask =
+		(1 << calc_bits_of(le32_to_cpu(pi->v.lpg_num)-1)) - 1;
+	pi->lpgp_num_mask =
+		(1 << calc_bits_of(le32_to_cpu(pi->v.lpgp_num)-1)) - 1;
+}
+
+/*
+ * decode crush map
+ */
+static int crush_decode_uniform_bucket(void **p, void *end,
+				       struct crush_bucket_uniform *b)
+{
+	dout("crush_decode_uniform_bucket %p to %p\n", *p, end);
+	ceph_decode_need(p, end, (1+b->h.size) * sizeof(u32), bad);
+	b->item_weight = ceph_decode_32(p);
+	return 0;
+bad:
+	return -EINVAL;
+}
+
+static int crush_decode_list_bucket(void **p, void *end,
+				    struct crush_bucket_list *b)
+{
+	int j;
+	dout("crush_decode_list_bucket %p to %p\n", *p, end);
+	b->item_weights = kcalloc(b->h.size, sizeof(u32), GFP_NOFS);
+	if (b->item_weights == NULL)
+		return -ENOMEM;
+	b->sum_weights = kcalloc(b->h.size, sizeof(u32), GFP_NOFS);
+	if (b->sum_weights == NULL)
+		return -ENOMEM;
+	ceph_decode_need(p, end, 2 * b->h.size * sizeof(u32), bad);
+	for (j = 0; j < b->h.size; j++) {
+		b->item_weights[j] = ceph_decode_32(p);
+		b->sum_weights[j] = ceph_decode_32(p);
+	}
+	return 0;
+bad:
+	return -EINVAL;
+}
+
+static int crush_decode_tree_bucket(void **p, void *end,
+				    struct crush_bucket_tree *b)
+{
+	int j;
+	dout("crush_decode_tree_bucket %p to %p\n", *p, end);
+	ceph_decode_32_safe(p, end, b->num_nodes, bad);
+	b->node_weights = kcalloc(b->num_nodes, sizeof(u32), GFP_NOFS);
+	if (b->node_weights == NULL)
+		return -ENOMEM;
+	ceph_decode_need(p, end, b->num_nodes * sizeof(u32), bad);
+	for (j = 0; j < b->num_nodes; j++)
+		b->node_weights[j] = ceph_decode_32(p);
+	return 0;
+bad:
+	return -EINVAL;
+}
+
+static int crush_decode_straw_bucket(void **p, void *end,
+				     struct crush_bucket_straw *b)
+{
+	int j;
+	dout("crush_decode_straw_bucket %p to %p\n", *p, end);
+	b->item_weights = kcalloc(b->h.size, sizeof(u32), GFP_NOFS);
+	if (b->item_weights == NULL)
+		return -ENOMEM;
+	b->straws = kcalloc(b->h.size, sizeof(u32), GFP_NOFS);
+	if (b->straws == NULL)
+		return -ENOMEM;
+	ceph_decode_need(p, end, 2 * b->h.size * sizeof(u32), bad);
+	for (j = 0; j < b->h.size; j++) {
+		b->item_weights[j] = ceph_decode_32(p);
+		b->straws[j] = ceph_decode_32(p);
+	}
+	return 0;
+bad:
+	return -EINVAL;
+}
+
+static struct crush_map *crush_decode(void *pbyval, void *end)
+{
+	struct crush_map *c;
+	int err = -EINVAL;
+	int i, j;
+	void **p = &pbyval;
+	void *start = pbyval;
+	u32 magic;
+
+	dout("crush_decode %p to %p len %d\n", *p, end, (int)(end - *p));
+
+	c = kzalloc(sizeof(*c), GFP_NOFS);
+	if (c == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	ceph_decode_need(p, end, 4*sizeof(u32), bad);
+	magic = ceph_decode_32(p);
+	if (magic != CRUSH_MAGIC) {
+		pr_err("crush_decode magic %x != current %x\n",
+		       (unsigned)magic, (unsigned)CRUSH_MAGIC);
+		goto bad;
+	}
+	c->max_buckets = ceph_decode_32(p);
+	c->max_rules = ceph_decode_32(p);
+	c->max_devices = ceph_decode_32(p);
+
+	c->device_parents = kcalloc(c->max_devices, sizeof(u32), GFP_NOFS);
+	if (c->device_parents == NULL)
+		goto badmem;
+	c->bucket_parents = kcalloc(c->max_buckets, sizeof(u32), GFP_NOFS);
+	if (c->bucket_parents == NULL)
+		goto badmem;
+
+	c->buckets = kcalloc(c->max_buckets, sizeof(*c->buckets), GFP_NOFS);
+	if (c->buckets == NULL)
+		goto badmem;
+	c->rules = kcalloc(c->max_rules, sizeof(*c->rules), GFP_NOFS);
+	if (c->rules == NULL)
+		goto badmem;
+
+	/* buckets */
+	for (i = 0; i < c->max_buckets; i++) {
+		int size = 0;
+		u32 alg;
+		struct crush_bucket *b;
+
+		ceph_decode_32_safe(p, end, alg, bad);
+		if (alg == 0) {
+			c->buckets[i] = NULL;
+			continue;
+		}
+		dout("crush_decode bucket %d off %x %p to %p\n",
+		     i, (int)(*p-start), *p, end);
+
+		switch (alg) {
+		case CRUSH_BUCKET_UNIFORM:
+			size = sizeof(struct crush_bucket_uniform);
+			break;
+		case CRUSH_BUCKET_LIST:
+			size = sizeof(struct crush_bucket_list);
+			break;
+		case CRUSH_BUCKET_TREE:
+			size = sizeof(struct crush_bucket_tree);
+			break;
+		case CRUSH_BUCKET_STRAW:
+			size = sizeof(struct crush_bucket_straw);
+			break;
+		default:
+			err = -EINVAL;
+			goto bad;
+		}
+		BUG_ON(size == 0);
+		b = c->buckets[i] = kzalloc(size, GFP_NOFS);
+		if (b == NULL)
+			goto badmem;
+
+		ceph_decode_need(p, end, 4*sizeof(u32), bad);
+		b->id = ceph_decode_32(p);
+		b->type = ceph_decode_16(p);
+		b->alg = ceph_decode_8(p);
+		b->hash = ceph_decode_8(p);
+		b->weight = ceph_decode_32(p);
+		b->size = ceph_decode_32(p);
+
+		dout("crush_decode bucket size %d off %x %p to %p\n",
+		     b->size, (int)(*p-start), *p, end);
+
+		b->items = kcalloc(b->size, sizeof(__s32), GFP_NOFS);
+		if (b->items == NULL)
+			goto badmem;
+		b->perm = kcalloc(b->size, sizeof(u32), GFP_NOFS);
+		if (b->perm == NULL)
+			goto badmem;
+		b->perm_n = 0;
+
+		ceph_decode_need(p, end, b->size*sizeof(u32), bad);
+		for (j = 0; j < b->size; j++)
+			b->items[j] = ceph_decode_32(p);
+
+		switch (b->alg) {
+		case CRUSH_BUCKET_UNIFORM:
+			err = crush_decode_uniform_bucket(p, end,
+				  (struct crush_bucket_uniform *)b);
+			if (err < 0)
+				goto bad;
+			break;
+		case CRUSH_BUCKET_LIST:
+			err = crush_decode_list_bucket(p, end,
+			       (struct crush_bucket_list *)b);
+			if (err < 0)
+				goto bad;
+			break;
+		case CRUSH_BUCKET_TREE:
+			err = crush_decode_tree_bucket(p, end,
+				(struct crush_bucket_tree *)b);
+			if (err < 0)
+				goto bad;
+			break;
+		case CRUSH_BUCKET_STRAW:
+			err = crush_decode_straw_bucket(p, end,
+				(struct crush_bucket_straw *)b);
+			if (err < 0)
+				goto bad;
+			break;
+		}
+	}
+
+	/* rules */
+	dout("rule vec is %p\n", c->rules);
+	for (i = 0; i < c->max_rules; i++) {
+		u32 yes;
+		struct crush_rule *r;
+
+		ceph_decode_32_safe(p, end, yes, bad);
+		if (!yes) {
+			dout("crush_decode NO rule %d off %x %p to %p\n",
+			     i, (int)(*p-start), *p, end);
+			c->rules[i] = NULL;
+			continue;
+		}
+
+		dout("crush_decode rule %d off %x %p to %p\n",
+		     i, (int)(*p-start), *p, end);
+
+		/* len */
+		ceph_decode_32_safe(p, end, yes, bad);
+#if BITS_PER_LONG == 32
+		err = -EINVAL;
+		if (yes > ULONG_MAX / sizeof(struct crush_rule_step))
+			goto bad;
+#endif
+		r = c->rules[i] = kmalloc(sizeof(*r) +
+					  yes*sizeof(struct crush_rule_step),
+					  GFP_NOFS);
+		if (r == NULL)
+			goto badmem;
+		dout(" rule %d is at %p\n", i, r);
+		r->len = yes;
+		ceph_decode_copy_safe(p, end, &r->mask, 4, bad); /* 4 u8's */
+		ceph_decode_need(p, end, r->len*3*sizeof(u32), bad);
+		for (j = 0; j < r->len; j++) {
+			r->steps[j].op = ceph_decode_32(p);
+			r->steps[j].arg1 = ceph_decode_32(p);
+			r->steps[j].arg2 = ceph_decode_32(p);
+		}
+	}
+
+	/* ignore trailing name maps. */
+
+	dout("crush_decode success\n");
+	return c;
+
+badmem:
+	err = -ENOMEM;
+bad:
+	dout("crush_decode fail %d\n", err);
+	crush_destroy(c);
+	return ERR_PTR(err);
+}
+
+/*
+ * rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid
+ * to a set of osds)
+ */
+static int pgid_cmp(struct ceph_pg l, struct ceph_pg r)
+{
+	u64 a = *(u64 *)&l;
+	u64 b = *(u64 *)&r;
+
+	if (a < b)
+		return -1;
+	if (a > b)
+		return 1;
+	return 0;
+}
+
+static int __insert_pg_mapping(struct ceph_pg_mapping *new,
+			       struct rb_root *root)
+{
+	struct rb_node **p = &root->rb_node;
+	struct rb_node *parent = NULL;
+	struct ceph_pg_mapping *pg = NULL;
+	int c;
+
+	while (*p) {
+		parent = *p;
+		pg = rb_entry(parent, struct ceph_pg_mapping, node);
+		c = pgid_cmp(new->pgid, pg->pgid);
+		if (c < 0)
+			p = &(*p)->rb_left;
+		else if (c > 0)
+			p = &(*p)->rb_right;
+		else
+			return -EEXIST;
+	}
+
+	rb_link_node(&new->node, parent, p);
+	rb_insert_color(&new->node, root);
+	return 0;
+}
+
+static struct ceph_pg_mapping *__lookup_pg_mapping(struct rb_root *root,
+						   struct ceph_pg pgid)
+{
+	struct rb_node *n = root->rb_node;
+	struct ceph_pg_mapping *pg;
+	int c;
+
+	while (n) {
+		pg = rb_entry(n, struct ceph_pg_mapping, node);
+		c = pgid_cmp(pgid, pg->pgid);
+		if (c < 0)
+			n = n->rb_left;
+		else if (c > 0)
+			n = n->rb_right;
+		else
+			return pg;
+	}
+	return NULL;
+}
+
+/*
+ * rbtree of pg pool info
+ */
+static int __insert_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *new)
+{
+	struct rb_node **p = &root->rb_node;
+	struct rb_node *parent = NULL;
+	struct ceph_pg_pool_info *pi = NULL;
+
+	while (*p) {
+		parent = *p;
+		pi = rb_entry(parent, struct ceph_pg_pool_info, node);
+		if (new->id < pi->id)
+			p = &(*p)->rb_left;
+		else if (new->id > pi->id)
+			p = &(*p)->rb_right;
+		else
+			return -EEXIST;
+	}
+
+	rb_link_node(&new->node, parent, p);
+	rb_insert_color(&new->node, root);
+	return 0;
+}
+
+static struct ceph_pg_pool_info *__lookup_pg_pool(struct rb_root *root, int id)
+{
+	struct ceph_pg_pool_info *pi;
+	struct rb_node *n = root->rb_node;
+
+	while (n) {
+		pi = rb_entry(n, struct ceph_pg_pool_info, node);
+		if (id < pi->id)
+			n = n->rb_left;
+		else if (id > pi->id)
+			n = n->rb_right;
+		else
+			return pi;
+	}
+	return NULL;
+}
+
+static void __remove_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *pi)
+{
+	rb_erase(&pi->node, root);
+	kfree(pi->name);
+	kfree(pi);
+}
+
+void __decode_pool(void **p, struct ceph_pg_pool_info *pi)
+{
+	ceph_decode_copy(p, &pi->v, sizeof(pi->v));
+	calc_pg_masks(pi);
+	*p += le32_to_cpu(pi->v.num_snaps) * sizeof(u64);
+	*p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2;
+}
+
+static int __decode_pool_names(void **p, void *end, struct ceph_osdmap *map)
+{
+	struct ceph_pg_pool_info *pi;
+	u32 num, len, pool;
+
+	ceph_decode_32_safe(p, end, num, bad);
+	dout(" %d pool names\n", num);
+	while (num--) {
+		ceph_decode_32_safe(p, end, pool, bad);
+		ceph_decode_32_safe(p, end, len, bad);
+		dout("  pool %d len %d\n", pool, len);
+		pi = __lookup_pg_pool(&map->pg_pools, pool);
+		if (pi) {
+			kfree(pi->name);
+			pi->name = kmalloc(len + 1, GFP_NOFS);
+			if (pi->name) {
+				memcpy(pi->name, *p, len);
+				pi->name[len] = '\0';
+				dout("  name is %s\n", pi->name);
+			}
+		}
+		*p += len;
+	}
+	return 0;
+
+bad:
+	return -EINVAL;
+}
+
+/*
+ * osd map
+ */
+void ceph_osdmap_destroy(struct ceph_osdmap *map)
+{
+	dout("osdmap_destroy %p\n", map);
+	if (map->crush)
+		crush_destroy(map->crush);
+	while (!RB_EMPTY_ROOT(&map->pg_temp)) {
+		struct ceph_pg_mapping *pg =
+			rb_entry(rb_first(&map->pg_temp),
+				 struct ceph_pg_mapping, node);
+		rb_erase(&pg->node, &map->pg_temp);
+		kfree(pg);
+	}
+	while (!RB_EMPTY_ROOT(&map->pg_pools)) {
+		struct ceph_pg_pool_info *pi =
+			rb_entry(rb_first(&map->pg_pools),
+				 struct ceph_pg_pool_info, node);
+		__remove_pg_pool(&map->pg_pools, pi);
+	}
+	kfree(map->osd_state);
+	kfree(map->osd_weight);
+	kfree(map->osd_addr);
+	kfree(map);
+}
+
+/*
+ * adjust max osd value.  reallocate arrays.
+ */
+static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
+{
+	u8 *state;
+	struct ceph_entity_addr *addr;
+	u32 *weight;
+
+	state = kcalloc(max, sizeof(*state), GFP_NOFS);
+	addr = kcalloc(max, sizeof(*addr), GFP_NOFS);
+	weight = kcalloc(max, sizeof(*weight), GFP_NOFS);
+	if (state == NULL || addr == NULL || weight == NULL) {
+		kfree(state);
+		kfree(addr);
+		kfree(weight);
+		return -ENOMEM;
+	}
+
+	/* copy old? */
+	if (map->osd_state) {
+		memcpy(state, map->osd_state, map->max_osd*sizeof(*state));
+		memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr));
+		memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight));
+		kfree(map->osd_state);
+		kfree(map->osd_addr);
+		kfree(map->osd_weight);
+	}
+
+	map->osd_state = state;
+	map->osd_weight = weight;
+	map->osd_addr = addr;
+	map->max_osd = max;
+	return 0;
+}
+
+/*
+ * decode a full map.
+ */
+struct ceph_osdmap *osdmap_decode(void **p, void *end)
+{
+	struct ceph_osdmap *map;
+	u16 version;
+	u32 len, max, i;
+	u8 ev;
+	int err = -EINVAL;
+	void *start = *p;
+	struct ceph_pg_pool_info *pi;
+
+	dout("osdmap_decode %p to %p len %d\n", *p, end, (int)(end - *p));
+
+	map = kzalloc(sizeof(*map), GFP_NOFS);
+	if (map == NULL)
+		return ERR_PTR(-ENOMEM);
+	map->pg_temp = RB_ROOT;
+
+	ceph_decode_16_safe(p, end, version, bad);
+	if (version > CEPH_OSDMAP_VERSION) {
+		pr_warning("got unknown v %d > %d of osdmap\n", version,
+			   CEPH_OSDMAP_VERSION);
+		goto bad;
+	}
+
+	ceph_decode_need(p, end, 2*sizeof(u64)+6*sizeof(u32), bad);
+	ceph_decode_copy(p, &map->fsid, sizeof(map->fsid));
+	map->epoch = ceph_decode_32(p);
+	ceph_decode_copy(p, &map->created, sizeof(map->created));
+	ceph_decode_copy(p, &map->modified, sizeof(map->modified));
+
+	ceph_decode_32_safe(p, end, max, bad);
+	while (max--) {
+		ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad);
+		pi = kzalloc(sizeof(*pi), GFP_NOFS);
+		if (!pi)
+			goto bad;
+		pi->id = ceph_decode_32(p);
+		ev = ceph_decode_8(p); /* encoding version */
+		if (ev > CEPH_PG_POOL_VERSION) {
+			pr_warning("got unknown v %d > %d of ceph_pg_pool\n",
+				   ev, CEPH_PG_POOL_VERSION);
+			goto bad;
+		}
+		__decode_pool(p, pi);
+		__insert_pg_pool(&map->pg_pools, pi);
+	}
+
+	if (version >= 5 && __decode_pool_names(p, end, map) < 0)
+		goto bad;
+
+	ceph_decode_32_safe(p, end, map->pool_max, bad);
+
+	ceph_decode_32_safe(p, end, map->flags, bad);
+
+	max = ceph_decode_32(p);
+
+	/* (re)alloc osd arrays */
+	err = osdmap_set_max_osd(map, max);
+	if (err < 0)
+		goto bad;
+	dout("osdmap_decode max_osd = %d\n", map->max_osd);
+
+	/* osds */
+	err = -EINVAL;
+	ceph_decode_need(p, end, 3*sizeof(u32) +
+			 map->max_osd*(1 + sizeof(*map->osd_weight) +
+				       sizeof(*map->osd_addr)), bad);
+	*p += 4; /* skip length field (should match max) */
+	ceph_decode_copy(p, map->osd_state, map->max_osd);
+
+	*p += 4; /* skip length field (should match max) */
+	for (i = 0; i < map->max_osd; i++)
+		map->osd_weight[i] = ceph_decode_32(p);
+
+	*p += 4; /* skip length field (should match max) */
+	ceph_decode_copy(p, map->osd_addr, map->max_osd*sizeof(*map->osd_addr));
+	for (i = 0; i < map->max_osd; i++)
+		ceph_decode_addr(&map->osd_addr[i]);
+
+	/* pg_temp */
+	ceph_decode_32_safe(p, end, len, bad);
+	for (i = 0; i < len; i++) {
+		int n, j;
+		struct ceph_pg pgid;
+		struct ceph_pg_mapping *pg;
+
+		ceph_decode_need(p, end, sizeof(u32) + sizeof(u64), bad);
+		ceph_decode_copy(p, &pgid, sizeof(pgid));
+		n = ceph_decode_32(p);
+		ceph_decode_need(p, end, n * sizeof(u32), bad);
+		err = -ENOMEM;
+		pg = kmalloc(sizeof(*pg) + n*sizeof(u32), GFP_NOFS);
+		if (!pg)
+			goto bad;
+		pg->pgid = pgid;
+		pg->len = n;
+		for (j = 0; j < n; j++)
+			pg->osds[j] = ceph_decode_32(p);
+
+		err = __insert_pg_mapping(pg, &map->pg_temp);
+		if (err)
+			goto bad;
+		dout(" added pg_temp %llx len %d\n", *(u64 *)&pgid, len);
+	}
+
+	/* crush */
+	ceph_decode_32_safe(p, end, len, bad);
+	dout("osdmap_decode crush len %d from off 0x%x\n", len,
+	     (int)(*p - start));
+	ceph_decode_need(p, end, len, bad);
+	map->crush = crush_decode(*p, end);
+	*p += len;
+	if (IS_ERR(map->crush)) {
+		err = PTR_ERR(map->crush);
+		map->crush = NULL;
+		goto bad;
+	}
+
+	/* ignore the rest of the map */
+	*p = end;
+
+	dout("osdmap_decode done %p %p\n", *p, end);
+	return map;
+
+bad:
+	dout("osdmap_decode fail\n");
+	ceph_osdmap_destroy(map);
+	return ERR_PTR(err);
+}
+
+/*
+ * decode and apply an incremental map update.
+ */
+struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
+					     struct ceph_osdmap *map,
+					     struct ceph_messenger *msgr)
+{
+	struct crush_map *newcrush = NULL;
+	struct ceph_fsid fsid;
+	u32 epoch = 0;
+	struct ceph_timespec modified;
+	u32 len, pool;
+	__s32 new_pool_max, new_flags, max;
+	void *start = *p;
+	int err = -EINVAL;
+	u16 version;
+	struct rb_node *rbp;
+
+	ceph_decode_16_safe(p, end, version, bad);
+	if (version > CEPH_OSDMAP_INC_VERSION) {
+		pr_warning("got unknown v %d > %d of inc osdmap\n", version,
+			   CEPH_OSDMAP_INC_VERSION);
+		goto bad;
+	}
+
+	ceph_decode_need(p, end, sizeof(fsid)+sizeof(modified)+2*sizeof(u32),
+			 bad);
+	ceph_decode_copy(p, &fsid, sizeof(fsid));
+	epoch = ceph_decode_32(p);
+	BUG_ON(epoch != map->epoch+1);
+	ceph_decode_copy(p, &modified, sizeof(modified));
+	new_pool_max = ceph_decode_32(p);
+	new_flags = ceph_decode_32(p);
+
+	/* full map? */
+	ceph_decode_32_safe(p, end, len, bad);
+	if (len > 0) {
+		dout("apply_incremental full map len %d, %p to %p\n",
+		     len, *p, end);
+		return osdmap_decode(p, min(*p+len, end));
+	}
+
+	/* new crush? */
+	ceph_decode_32_safe(p, end, len, bad);
+	if (len > 0) {
+		dout("apply_incremental new crush map len %d, %p to %p\n",
+		     len, *p, end);
+		newcrush = crush_decode(*p, min(*p+len, end));
+		if (IS_ERR(newcrush))
+			return ERR_PTR(PTR_ERR(newcrush));
+	}
+
+	/* new flags? */
+	if (new_flags >= 0)
+		map->flags = new_flags;
+	if (new_pool_max >= 0)
+		map->pool_max = new_pool_max;
+
+	ceph_decode_need(p, end, 5*sizeof(u32), bad);
+
+	/* new max? */
+	max = ceph_decode_32(p);
+	if (max >= 0) {
+		err = osdmap_set_max_osd(map, max);
+		if (err < 0)
+			goto bad;
+	}
+
+	map->epoch++;
+	map->modified = map->modified;
+	if (newcrush) {
+		if (map->crush)
+			crush_destroy(map->crush);
+		map->crush = newcrush;
+		newcrush = NULL;
+	}
+
+	/* new_pool */
+	ceph_decode_32_safe(p, end, len, bad);
+	while (len--) {
+		__u8 ev;
+		struct ceph_pg_pool_info *pi;
+
+		ceph_decode_32_safe(p, end, pool, bad);
+		ceph_decode_need(p, end, 1 + sizeof(pi->v), bad);
+		ev = ceph_decode_8(p);  /* encoding version */
+		if (ev > CEPH_PG_POOL_VERSION) {
+			pr_warning("got unknown v %d > %d of ceph_pg_pool\n",
+				   ev, CEPH_PG_POOL_VERSION);
+			goto bad;
+		}
+		pi = __lookup_pg_pool(&map->pg_pools, pool);
+		if (!pi) {
+			pi = kzalloc(sizeof(*pi), GFP_NOFS);
+			if (!pi) {
+				err = -ENOMEM;
+				goto bad;
+			}
+			pi->id = pool;
+			__insert_pg_pool(&map->pg_pools, pi);
+		}
+		__decode_pool(p, pi);
+	}
+	if (version >= 5 && __decode_pool_names(p, end, map) < 0)
+		goto bad;
+
+	/* old_pool */
+	ceph_decode_32_safe(p, end, len, bad);
+	while (len--) {
+		struct ceph_pg_pool_info *pi;
+
+		ceph_decode_32_safe(p, end, pool, bad);
+		pi = __lookup_pg_pool(&map->pg_pools, pool);
+		if (pi)
+			__remove_pg_pool(&map->pg_pools, pi);
+	}
+
+	/* new_up */
+	err = -EINVAL;
+	ceph_decode_32_safe(p, end, len, bad);
+	while (len--) {
+		u32 osd;
+		struct ceph_entity_addr addr;
+		ceph_decode_32_safe(p, end, osd, bad);
+		ceph_decode_copy_safe(p, end, &addr, sizeof(addr), bad);
+		ceph_decode_addr(&addr);
+		pr_info("osd%d up\n", osd);
+		BUG_ON(osd >= map->max_osd);
+		map->osd_state[osd] |= CEPH_OSD_UP;
+		map->osd_addr[osd] = addr;
+	}
+
+	/* new_down */
+	ceph_decode_32_safe(p, end, len, bad);
+	while (len--) {
+		u32 osd;
+		ceph_decode_32_safe(p, end, osd, bad);
+		(*p)++;  /* clean flag */
+		pr_info("osd%d down\n", osd);
+		if (osd < map->max_osd)
+			map->osd_state[osd] &= ~CEPH_OSD_UP;
+	}
+
+	/* new_weight */
+	ceph_decode_32_safe(p, end, len, bad);
+	while (len--) {
+		u32 osd, off;
+		ceph_decode_need(p, end, sizeof(u32)*2, bad);
+		osd = ceph_decode_32(p);
+		off = ceph_decode_32(p);
+		pr_info("osd%d weight 0x%x %s\n", osd, off,
+		     off == CEPH_OSD_IN ? "(in)" :
+		     (off == CEPH_OSD_OUT ? "(out)" : ""));
+		if (osd < map->max_osd)
+			map->osd_weight[osd] = off;
+	}
+
+	/* new_pg_temp */
+	rbp = rb_first(&map->pg_temp);
+	ceph_decode_32_safe(p, end, len, bad);
+	while (len--) {
+		struct ceph_pg_mapping *pg;
+		int j;
+		struct ceph_pg pgid;
+		u32 pglen;
+		ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad);
+		ceph_decode_copy(p, &pgid, sizeof(pgid));
+		pglen = ceph_decode_32(p);
+
+		/* remove any? */
+		while (rbp && pgid_cmp(rb_entry(rbp, struct ceph_pg_mapping,
+						node)->pgid, pgid) <= 0) {
+			struct rb_node *cur = rbp;
+			rbp = rb_next(rbp);
+			dout(" removed pg_temp %llx\n",
+			     *(u64 *)&rb_entry(cur, struct ceph_pg_mapping,
+					       node)->pgid);
+			rb_erase(cur, &map->pg_temp);
+		}
+
+		if (pglen) {
+			/* insert */
+			ceph_decode_need(p, end, pglen*sizeof(u32), bad);
+			pg = kmalloc(sizeof(*pg) + sizeof(u32)*pglen, GFP_NOFS);
+			if (!pg) {
+				err = -ENOMEM;
+				goto bad;
+			}
+			pg->pgid = pgid;
+			pg->len = pglen;
+			for (j = 0; j < pglen; j++)
+				pg->osds[j] = ceph_decode_32(p);
+			err = __insert_pg_mapping(pg, &map->pg_temp);
+			if (err)
+				goto bad;
+			dout(" added pg_temp %llx len %d\n", *(u64 *)&pgid,
+			     pglen);
+		}
+	}
+	while (rbp) {
+		struct rb_node *cur = rbp;
+		rbp = rb_next(rbp);
+		dout(" removed pg_temp %llx\n",
+		     *(u64 *)&rb_entry(cur, struct ceph_pg_mapping,
+				       node)->pgid);
+		rb_erase(cur, &map->pg_temp);
+	}
+
+	/* ignore the rest */
+	*p = end;
+	return map;
+
+bad:
+	pr_err("corrupt inc osdmap epoch %d off %d (%p of %p-%p)\n",
+	       epoch, (int)(*p - start), *p, start, end);
+	print_hex_dump(KERN_DEBUG, "osdmap: ",
+		       DUMP_PREFIX_OFFSET, 16, 1,
+		       start, end - start, true);
+	if (newcrush)
+		crush_destroy(newcrush);
+	return ERR_PTR(err);
+}
+
+
+
+
+/*
+ * calculate file layout from given offset, length.
+ * fill in correct oid, logical length, and object extent
+ * offset, length.
+ *
+ * for now, we write only a single su, until we can
+ * pass a stride back to the caller.
+ */
+void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
+				   u64 off, u64 *plen,
+				   u64 *ono,
+				   u64 *oxoff, u64 *oxlen)
+{
+	u32 osize = le32_to_cpu(layout->fl_object_size);
+	u32 su = le32_to_cpu(layout->fl_stripe_unit);
+	u32 sc = le32_to_cpu(layout->fl_stripe_count);
+	u32 bl, stripeno, stripepos, objsetno;
+	u32 su_per_object;
+	u64 t, su_offset;
+
+	dout("mapping %llu~%llu  osize %u fl_su %u\n", off, *plen,
+	     osize, su);
+	su_per_object = osize / su;
+	dout("osize %u / su %u = su_per_object %u\n", osize, su,
+	     su_per_object);
+
+	BUG_ON((su & ~PAGE_MASK) != 0);
+	/* bl = *off / su; */
+	t = off;
+	do_div(t, su);
+	bl = t;
+	dout("off %llu / su %u = bl %u\n", off, su, bl);
+
+	stripeno = bl / sc;
+	stripepos = bl % sc;
+	objsetno = stripeno / su_per_object;
+
+	*ono = objsetno * sc + stripepos;
+	dout("objset %u * sc %u = ono %u\n", objsetno, sc, (unsigned)*ono);
+
+	/* *oxoff = *off % layout->fl_stripe_unit;  # offset in su */
+	t = off;
+	su_offset = do_div(t, su);
+	*oxoff = su_offset + (stripeno % su_per_object) * su;
+
+	/*
+	 * Calculate the length of the extent being written to the selected
+	 * object. This is the minimum of the full length requested (plen) or
+	 * the remainder of the current stripe being written to.
+	 */
+	*oxlen = min_t(u64, *plen, su - su_offset);
+	*plen = *oxlen;
+
+	dout(" obj extent %llu~%llu\n", *oxoff, *oxlen);
+}
+
+/*
+ * calculate an object layout (i.e. pgid) from an oid,
+ * file_layout, and osdmap
+ */
+int ceph_calc_object_layout(struct ceph_object_layout *ol,
+			    const char *oid,
+			    struct ceph_file_layout *fl,
+			    struct ceph_osdmap *osdmap)
+{
+	unsigned num, num_mask;
+	struct ceph_pg pgid;
+	s32 preferred = (s32)le32_to_cpu(fl->fl_pg_preferred);
+	int poolid = le32_to_cpu(fl->fl_pg_pool);
+	struct ceph_pg_pool_info *pool;
+	unsigned ps;
+
+	BUG_ON(!osdmap);
+
+	pool = __lookup_pg_pool(&osdmap->pg_pools, poolid);
+	if (!pool)
+		return -EIO;
+	ps = ceph_str_hash(pool->v.object_hash, oid, strlen(oid));
+	if (preferred >= 0) {
+		ps += preferred;
+		num = le32_to_cpu(pool->v.lpg_num);
+		num_mask = pool->lpg_num_mask;
+	} else {
+		num = le32_to_cpu(pool->v.pg_num);
+		num_mask = pool->pg_num_mask;
+	}
+
+	pgid.ps = cpu_to_le16(ps);
+	pgid.preferred = cpu_to_le16(preferred);
+	pgid.pool = fl->fl_pg_pool;
+	if (preferred >= 0)
+		dout("calc_object_layout '%s' pgid %d.%xp%d\n", oid, poolid, ps,
+		     (int)preferred);
+	else
+		dout("calc_object_layout '%s' pgid %d.%x\n", oid, poolid, ps);
+
+	ol->ol_pgid = pgid;
+	ol->ol_stripe_unit = fl->fl_object_stripe_unit;
+	return 0;
+}
+
+/*
+ * Calculate raw osd vector for the given pgid.  Return pointer to osd
+ * array, or NULL on failure.
+ */
+static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
+			int *osds, int *num)
+{
+	struct ceph_pg_mapping *pg;
+	struct ceph_pg_pool_info *pool;
+	int ruleno;
+	unsigned poolid, ps, pps;
+	int preferred;
+
+	/* pg_temp? */
+	pg = __lookup_pg_mapping(&osdmap->pg_temp, pgid);
+	if (pg) {
+		*num = pg->len;
+		return pg->osds;
+	}
+
+	/* crush */
+	poolid = le32_to_cpu(pgid.pool);
+	ps = le16_to_cpu(pgid.ps);
+	preferred = (s16)le16_to_cpu(pgid.preferred);
+
+	/* don't forcefeed bad device ids to crush */
+	if (preferred >= osdmap->max_osd ||
+	    preferred >= osdmap->crush->max_devices)
+		preferred = -1;
+
+	pool = __lookup_pg_pool(&osdmap->pg_pools, poolid);
+	if (!pool)
+		return NULL;
+	ruleno = crush_find_rule(osdmap->crush, pool->v.crush_ruleset,
+				 pool->v.type, pool->v.size);
+	if (ruleno < 0) {
+		pr_err("no crush rule pool %d type %d size %d\n",
+		       poolid, pool->v.type, pool->v.size);
+		return NULL;
+	}
+
+	if (preferred >= 0)
+		pps = ceph_stable_mod(ps,
+				      le32_to_cpu(pool->v.lpgp_num),
+				      pool->lpgp_num_mask);
+	else
+		pps = ceph_stable_mod(ps,
+				      le32_to_cpu(pool->v.pgp_num),
+				      pool->pgp_num_mask);
+	pps += poolid;
+	*num = crush_do_rule(osdmap->crush, ruleno, pps, osds,
+			     min_t(int, pool->v.size, *num),
+			     preferred, osdmap->osd_weight);
+	return osds;
+}
+
+/*
+ * Return acting set for given pgid.
+ */
+int ceph_calc_pg_acting(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
+			int *acting)
+{
+	int rawosds[CEPH_PG_MAX_SIZE], *osds;
+	int i, o, num = CEPH_PG_MAX_SIZE;
+
+	osds = calc_pg_raw(osdmap, pgid, rawosds, &num);
+	if (!osds)
+		return -1;
+
+	/* primary is first up osd */
+	o = 0;
+	for (i = 0; i < num; i++)
+		if (ceph_osd_is_up(osdmap, osds[i]))
+			acting[o++] = osds[i];
+	return o;
+}
+
+/*
+ * Return primary osd for given pgid, or -1 if none.
+ */
+int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid)
+{
+	int rawosds[CEPH_PG_MAX_SIZE], *osds;
+	int i, num = CEPH_PG_MAX_SIZE;
+
+	osds = calc_pg_raw(osdmap, pgid, rawosds, &num);
+	if (!osds)
+		return -1;
+
+	/* primary is first up osd */
+	for (i = 0; i < num; i++)
+		if (ceph_osd_is_up(osdmap, osds[i]))
+			return osds[i];
+	return -1;
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/osdmap.h linux-libre-2.6.34-gnu1/fs/ceph/osdmap.h
--- linux-libre-2.6.33-gnu1/fs/ceph/osdmap.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/osdmap.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,128 @@
+#ifndef _FS_CEPH_OSDMAP_H
+#define _FS_CEPH_OSDMAP_H
+
+#include <linux/rbtree.h>
+#include "types.h"
+#include "ceph_fs.h"
+#include "crush/crush.h"
+
+/*
+ * The osd map describes the current membership of the osd cluster and
+ * specifies the mapping of objects to placement groups and placement
+ * groups to (sets of) osds.  That is, it completely specifies the
+ * (desired) distribution of all data objects in the system at some
+ * point in time.
+ *
+ * Each map version is identified by an epoch, which increases monotonically.
+ *
+ * The map can be updated either via an incremental map (diff) describing
+ * the change between two successive epochs, or as a fully encoded map.
+ */
+struct ceph_pg_pool_info {
+	struct rb_node node;
+	int id;
+	struct ceph_pg_pool v;
+	int pg_num_mask, pgp_num_mask, lpg_num_mask, lpgp_num_mask;
+	char *name;
+};
+
+struct ceph_pg_mapping {
+	struct rb_node node;
+	struct ceph_pg pgid;
+	int len;
+	int osds[];
+};
+
+struct ceph_osdmap {
+	struct ceph_fsid fsid;
+	u32 epoch;
+	u32 mkfs_epoch;
+	struct ceph_timespec created, modified;
+
+	u32 flags;         /* CEPH_OSDMAP_* */
+
+	u32 max_osd;       /* size of osd_state, _offload, _addr arrays */
+	u8 *osd_state;     /* CEPH_OSD_* */
+	u32 *osd_weight;   /* 0 = failed, 0x10000 = 100% normal */
+	struct ceph_entity_addr *osd_addr;
+
+	struct rb_root pg_temp;
+	struct rb_root pg_pools;
+	u32 pool_max;
+
+	/* the CRUSH map specifies the mapping of placement groups to
+	 * the list of osds that store+replicate them. */
+	struct crush_map *crush;
+};
+
+/*
+ * file layout helpers
+ */
+#define ceph_file_layout_su(l) ((__s32)le32_to_cpu((l).fl_stripe_unit))
+#define ceph_file_layout_stripe_count(l) \
+	((__s32)le32_to_cpu((l).fl_stripe_count))
+#define ceph_file_layout_object_size(l) ((__s32)le32_to_cpu((l).fl_object_size))
+#define ceph_file_layout_cas_hash(l) ((__s32)le32_to_cpu((l).fl_cas_hash))
+#define ceph_file_layout_object_su(l) \
+	((__s32)le32_to_cpu((l).fl_object_stripe_unit))
+#define ceph_file_layout_pg_preferred(l) \
+	((__s32)le32_to_cpu((l).fl_pg_preferred))
+#define ceph_file_layout_pg_pool(l) \
+	((__s32)le32_to_cpu((l).fl_pg_pool))
+
+static inline unsigned ceph_file_layout_stripe_width(struct ceph_file_layout *l)
+{
+	return le32_to_cpu(l->fl_stripe_unit) *
+		le32_to_cpu(l->fl_stripe_count);
+}
+
+/* "period" == bytes before i start on a new set of objects */
+static inline unsigned ceph_file_layout_period(struct ceph_file_layout *l)
+{
+	return le32_to_cpu(l->fl_object_size) *
+		le32_to_cpu(l->fl_stripe_count);
+}
+
+
+static inline int ceph_osd_is_up(struct ceph_osdmap *map, int osd)
+{
+	return (osd < map->max_osd) && (map->osd_state[osd] & CEPH_OSD_UP);
+}
+
+static inline bool ceph_osdmap_flag(struct ceph_osdmap *map, int flag)
+{
+	return map && (map->flags & flag);
+}
+
+extern char *ceph_osdmap_state_str(char *str, int len, int state);
+
+static inline struct ceph_entity_addr *ceph_osd_addr(struct ceph_osdmap *map,
+						     int osd)
+{
+	if (osd >= map->max_osd)
+		return NULL;
+	return &map->osd_addr[osd];
+}
+
+extern struct ceph_osdmap *osdmap_decode(void **p, void *end);
+extern struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
+					    struct ceph_osdmap *map,
+					    struct ceph_messenger *msgr);
+extern void ceph_osdmap_destroy(struct ceph_osdmap *map);
+
+/* calculate mapping of a file extent to an object */
+extern void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
+					  u64 off, u64 *plen,
+					  u64 *bno, u64 *oxoff, u64 *oxlen);
+
+/* calculate mapping of object to a placement group */
+extern int ceph_calc_object_layout(struct ceph_object_layout *ol,
+				   const char *oid,
+				   struct ceph_file_layout *fl,
+				   struct ceph_osdmap *osdmap);
+extern int ceph_calc_pg_acting(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
+			       int *acting);
+extern int ceph_calc_pg_primary(struct ceph_osdmap *osdmap,
+				struct ceph_pg pgid);
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/pagelist.c linux-libre-2.6.34-gnu1/fs/ceph/pagelist.c
--- linux-libre-2.6.33-gnu1/fs/ceph/pagelist.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/pagelist.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,55 @@
+
+#include <linux/gfp.h>
+#include <linux/pagemap.h>
+#include <linux/highmem.h>
+
+#include "pagelist.h"
+
+int ceph_pagelist_release(struct ceph_pagelist *pl)
+{
+	if (pl->mapped_tail)
+		kunmap(pl->mapped_tail);
+	while (!list_empty(&pl->head)) {
+		struct page *page = list_first_entry(&pl->head, struct page,
+						     lru);
+		list_del(&page->lru);
+		__free_page(page);
+	}
+	return 0;
+}
+
+static int ceph_pagelist_addpage(struct ceph_pagelist *pl)
+{
+	struct page *page = alloc_page(GFP_NOFS);
+	if (!page)
+		return -ENOMEM;
+	pl->room += PAGE_SIZE;
+	list_add_tail(&page->lru, &pl->head);
+	if (pl->mapped_tail)
+		kunmap(pl->mapped_tail);
+	pl->mapped_tail = kmap(page);
+	return 0;
+}
+
+int ceph_pagelist_append(struct ceph_pagelist *pl, void *buf, size_t len)
+{
+	while (pl->room < len) {
+		size_t bit = pl->room;
+		int ret;
+
+		memcpy(pl->mapped_tail + (pl->length & ~PAGE_CACHE_MASK),
+		       buf, bit);
+		pl->length += bit;
+		pl->room -= bit;
+		buf += bit;
+		len -= bit;
+		ret = ceph_pagelist_addpage(pl);
+		if (ret)
+			return ret;
+	}
+
+	memcpy(pl->mapped_tail + (pl->length & ~PAGE_CACHE_MASK), buf, len);
+	pl->length += len;
+	pl->room -= len;
+	return 0;
+}
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/pagelist.h linux-libre-2.6.34-gnu1/fs/ceph/pagelist.h
--- linux-libre-2.6.33-gnu1/fs/ceph/pagelist.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/pagelist.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,54 @@
+#ifndef __FS_CEPH_PAGELIST_H
+#define __FS_CEPH_PAGELIST_H
+
+#include <linux/list.h>
+
+struct ceph_pagelist {
+	struct list_head head;
+	void *mapped_tail;
+	size_t length;
+	size_t room;
+};
+
+static inline void ceph_pagelist_init(struct ceph_pagelist *pl)
+{
+	INIT_LIST_HEAD(&pl->head);
+	pl->mapped_tail = NULL;
+	pl->length = 0;
+	pl->room = 0;
+}
+extern int ceph_pagelist_release(struct ceph_pagelist *pl);
+
+extern int ceph_pagelist_append(struct ceph_pagelist *pl, void *d, size_t l);
+
+static inline int ceph_pagelist_encode_64(struct ceph_pagelist *pl, u64 v)
+{
+	__le64 ev = cpu_to_le64(v);
+	return ceph_pagelist_append(pl, &ev, sizeof(ev));
+}
+static inline int ceph_pagelist_encode_32(struct ceph_pagelist *pl, u32 v)
+{
+	__le32 ev = cpu_to_le32(v);
+	return ceph_pagelist_append(pl, &ev, sizeof(ev));
+}
+static inline int ceph_pagelist_encode_16(struct ceph_pagelist *pl, u16 v)
+{
+	__le16 ev = cpu_to_le16(v);
+	return ceph_pagelist_append(pl, &ev, sizeof(ev));
+}
+static inline int ceph_pagelist_encode_8(struct ceph_pagelist *pl, u8 v)
+{
+	return ceph_pagelist_append(pl, &v, 1);
+}
+static inline int ceph_pagelist_encode_string(struct ceph_pagelist *pl,
+					      char *s, size_t len)
+{
+	int ret = ceph_pagelist_encode_32(pl, len);
+	if (ret)
+		return ret;
+	if (len)
+		return ceph_pagelist_append(pl, s, len);
+	return 0;
+}
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/rados.h linux-libre-2.6.34-gnu1/fs/ceph/rados.h
--- linux-libre-2.6.33-gnu1/fs/ceph/rados.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/rados.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,377 @@
+#ifndef __RADOS_H
+#define __RADOS_H
+
+/*
+ * Data types for the Ceph distributed object storage layer RADOS
+ * (Reliable Autonomic Distributed Object Store).
+ */
+
+#include "msgr.h"
+
+/*
+ * osdmap encoding versions
+ */
+#define CEPH_OSDMAP_INC_VERSION     5
+#define CEPH_OSDMAP_INC_VERSION_EXT 5
+#define CEPH_OSDMAP_VERSION         5
+#define CEPH_OSDMAP_VERSION_EXT     5
+
+/*
+ * fs id
+ */
+struct ceph_fsid {
+	unsigned char fsid[16];
+};
+
+static inline int ceph_fsid_compare(const struct ceph_fsid *a,
+				    const struct ceph_fsid *b)
+{
+	return memcmp(a, b, sizeof(*a));
+}
+
+/*
+ * ino, object, etc.
+ */
+typedef __le64 ceph_snapid_t;
+#define CEPH_SNAPDIR ((__u64)(-1))  /* reserved for hidden .snap dir */
+#define CEPH_NOSNAP  ((__u64)(-2))  /* "head", "live" revision */
+#define CEPH_MAXSNAP ((__u64)(-3))  /* largest valid snapid */
+
+struct ceph_timespec {
+	__le32 tv_sec;
+	__le32 tv_nsec;
+} __attribute__ ((packed));
+
+
+/*
+ * object layout - how objects are mapped into PGs
+ */
+#define CEPH_OBJECT_LAYOUT_HASH     1
+#define CEPH_OBJECT_LAYOUT_LINEAR   2
+#define CEPH_OBJECT_LAYOUT_HASHINO  3
+
+/*
+ * pg layout -- how PGs are mapped onto (sets of) OSDs
+ */
+#define CEPH_PG_LAYOUT_CRUSH  0
+#define CEPH_PG_LAYOUT_HASH   1
+#define CEPH_PG_LAYOUT_LINEAR 2
+#define CEPH_PG_LAYOUT_HYBRID 3
+
+#define CEPH_PG_MAX_SIZE      16  /* max # osds in a single pg */
+
+/*
+ * placement group.
+ * we encode this into one __le64.
+ */
+struct ceph_pg {
+	__le16 preferred; /* preferred primary osd */
+	__le16 ps;        /* placement seed */
+	__le32 pool;      /* object pool */
+} __attribute__ ((packed));
+
+/*
+ * pg_pool is a set of pgs storing a pool of objects
+ *
+ *  pg_num -- base number of pseudorandomly placed pgs
+ *
+ *  pgp_num -- effective number when calculating pg placement.  this
+ * is used for pg_num increases.  new pgs result in data being "split"
+ * into new pgs.  for this to proceed smoothly, new pgs are intiially
+ * colocated with their parents; that is, pgp_num doesn't increase
+ * until the new pgs have successfully split.  only _then_ are the new
+ * pgs placed independently.
+ *
+ *  lpg_num -- localized pg count (per device).  replicas are randomly
+ * selected.
+ *
+ *  lpgp_num -- as above.
+ */
+#define CEPH_PG_TYPE_REP     1
+#define CEPH_PG_TYPE_RAID4   2
+#define CEPH_PG_POOL_VERSION 2
+struct ceph_pg_pool {
+	__u8 type;                /* CEPH_PG_TYPE_* */
+	__u8 size;                /* number of osds in each pg */
+	__u8 crush_ruleset;       /* crush placement rule */
+	__u8 object_hash;         /* hash mapping object name to ps */
+	__le32 pg_num, pgp_num;   /* number of pg's */
+	__le32 lpg_num, lpgp_num; /* number of localized pg's */
+	__le32 last_change;       /* most recent epoch changed */
+	__le64 snap_seq;          /* seq for per-pool snapshot */
+	__le32 snap_epoch;        /* epoch of last snap */
+	__le32 num_snaps;
+	__le32 num_removed_snap_intervals;
+	__le64 uid;
+} __attribute__ ((packed));
+
+/*
+ * stable_mod func is used to control number of placement groups.
+ * similar to straight-up modulo, but produces a stable mapping as b
+ * increases over time.  b is the number of bins, and bmask is the
+ * containing power of 2 minus 1.
+ *
+ * b <= bmask and bmask=(2**n)-1
+ * e.g., b=12 -> bmask=15, b=123 -> bmask=127
+ */
+static inline int ceph_stable_mod(int x, int b, int bmask)
+{
+	if ((x & bmask) < b)
+		return x & bmask;
+	else
+		return x & (bmask >> 1);
+}
+
+/*
+ * object layout - how a given object should be stored.
+ */
+struct ceph_object_layout {
+	struct ceph_pg ol_pgid;   /* raw pg, with _full_ ps precision. */
+	__le32 ol_stripe_unit;    /* for per-object parity, if any */
+} __attribute__ ((packed));
+
+/*
+ * compound epoch+version, used by storage layer to serialize mutations
+ */
+struct ceph_eversion {
+	__le32 epoch;
+	__le64 version;
+} __attribute__ ((packed));
+
+/*
+ * osd map bits
+ */
+
+/* status bits */
+#define CEPH_OSD_EXISTS 1
+#define CEPH_OSD_UP     2
+
+/* osd weights.  fixed point value: 0x10000 == 1.0 ("in"), 0 == "out" */
+#define CEPH_OSD_IN  0x10000
+#define CEPH_OSD_OUT 0
+
+
+/*
+ * osd map flag bits
+ */
+#define CEPH_OSDMAP_NEARFULL (1<<0)  /* sync writes (near ENOSPC) */
+#define CEPH_OSDMAP_FULL     (1<<1)  /* no data writes (ENOSPC) */
+#define CEPH_OSDMAP_PAUSERD  (1<<2)  /* pause all reads */
+#define CEPH_OSDMAP_PAUSEWR  (1<<3)  /* pause all writes */
+#define CEPH_OSDMAP_PAUSEREC (1<<4)  /* pause recovery */
+
+/*
+ * osd ops
+ */
+#define CEPH_OSD_OP_MODE       0xf000
+#define CEPH_OSD_OP_MODE_RD    0x1000
+#define CEPH_OSD_OP_MODE_WR    0x2000
+#define CEPH_OSD_OP_MODE_RMW   0x3000
+#define CEPH_OSD_OP_MODE_SUB   0x4000
+
+#define CEPH_OSD_OP_TYPE       0x0f00
+#define CEPH_OSD_OP_TYPE_LOCK  0x0100
+#define CEPH_OSD_OP_TYPE_DATA  0x0200
+#define CEPH_OSD_OP_TYPE_ATTR  0x0300
+#define CEPH_OSD_OP_TYPE_EXEC  0x0400
+#define CEPH_OSD_OP_TYPE_PG    0x0500
+
+enum {
+	/** data **/
+	/* read */
+	CEPH_OSD_OP_READ      = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 1,
+	CEPH_OSD_OP_STAT      = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 2,
+
+	/* fancy read */
+	CEPH_OSD_OP_MASKTRUNC = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 4,
+
+	/* write */
+	CEPH_OSD_OP_WRITE     = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 1,
+	CEPH_OSD_OP_WRITEFULL = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 2,
+	CEPH_OSD_OP_TRUNCATE  = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 3,
+	CEPH_OSD_OP_ZERO      = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 4,
+	CEPH_OSD_OP_DELETE    = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 5,
+
+	/* fancy write */
+	CEPH_OSD_OP_APPEND    = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 6,
+	CEPH_OSD_OP_STARTSYNC = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 7,
+	CEPH_OSD_OP_SETTRUNC  = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 8,
+	CEPH_OSD_OP_TRIMTRUNC = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 9,
+
+	CEPH_OSD_OP_TMAPUP  = CEPH_OSD_OP_MODE_RMW | CEPH_OSD_OP_TYPE_DATA | 10,
+	CEPH_OSD_OP_TMAPPUT = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 11,
+	CEPH_OSD_OP_TMAPGET = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 12,
+
+	CEPH_OSD_OP_CREATE  = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 13,
+
+	/** attrs **/
+	/* read */
+	CEPH_OSD_OP_GETXATTR  = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_ATTR | 1,
+	CEPH_OSD_OP_GETXATTRS = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_ATTR | 2,
+
+	/* write */
+	CEPH_OSD_OP_SETXATTR  = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_ATTR | 1,
+	CEPH_OSD_OP_SETXATTRS = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_ATTR | 2,
+	CEPH_OSD_OP_RESETXATTRS = CEPH_OSD_OP_MODE_WR|CEPH_OSD_OP_TYPE_ATTR | 3,
+	CEPH_OSD_OP_RMXATTR   = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_ATTR | 4,
+
+	/** subop **/
+	CEPH_OSD_OP_PULL           = CEPH_OSD_OP_MODE_SUB | 1,
+	CEPH_OSD_OP_PUSH           = CEPH_OSD_OP_MODE_SUB | 2,
+	CEPH_OSD_OP_BALANCEREADS   = CEPH_OSD_OP_MODE_SUB | 3,
+	CEPH_OSD_OP_UNBALANCEREADS = CEPH_OSD_OP_MODE_SUB | 4,
+	CEPH_OSD_OP_SCRUB          = CEPH_OSD_OP_MODE_SUB | 5,
+
+	/** lock **/
+	CEPH_OSD_OP_WRLOCK    = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 1,
+	CEPH_OSD_OP_WRUNLOCK  = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 2,
+	CEPH_OSD_OP_RDLOCK    = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 3,
+	CEPH_OSD_OP_RDUNLOCK  = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 4,
+	CEPH_OSD_OP_UPLOCK    = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 5,
+	CEPH_OSD_OP_DNLOCK    = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 6,
+
+	/** exec **/
+	CEPH_OSD_OP_CALL    = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_EXEC | 1,
+
+	/** pg **/
+	CEPH_OSD_OP_PGLS      = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_PG | 1,
+};
+
+static inline int ceph_osd_op_type_lock(int op)
+{
+	return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_LOCK;
+}
+static inline int ceph_osd_op_type_data(int op)
+{
+	return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_DATA;
+}
+static inline int ceph_osd_op_type_attr(int op)
+{
+	return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_ATTR;
+}
+static inline int ceph_osd_op_type_exec(int op)
+{
+	return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_EXEC;
+}
+static inline int ceph_osd_op_type_pg(int op)
+{
+	return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_PG;
+}
+
+static inline int ceph_osd_op_mode_subop(int op)
+{
+	return (op & CEPH_OSD_OP_MODE) == CEPH_OSD_OP_MODE_SUB;
+}
+static inline int ceph_osd_op_mode_read(int op)
+{
+	return (op & CEPH_OSD_OP_MODE) == CEPH_OSD_OP_MODE_RD;
+}
+static inline int ceph_osd_op_mode_modify(int op)
+{
+	return (op & CEPH_OSD_OP_MODE) == CEPH_OSD_OP_MODE_WR;
+}
+
+#define CEPH_OSD_TMAP_HDR 'h'
+#define CEPH_OSD_TMAP_SET 's'
+#define CEPH_OSD_TMAP_RM  'r'
+
+extern const char *ceph_osd_op_name(int op);
+
+
+/*
+ * osd op flags
+ *
+ * An op may be READ, WRITE, or READ|WRITE.
+ */
+enum {
+	CEPH_OSD_FLAG_ACK = 1,          /* want (or is) "ack" ack */
+	CEPH_OSD_FLAG_ONNVRAM = 2,      /* want (or is) "onnvram" ack */
+	CEPH_OSD_FLAG_ONDISK = 4,       /* want (or is) "ondisk" ack */
+	CEPH_OSD_FLAG_RETRY = 8,        /* resend attempt */
+	CEPH_OSD_FLAG_READ = 16,        /* op may read */
+	CEPH_OSD_FLAG_WRITE = 32,       /* op may write */
+	CEPH_OSD_FLAG_ORDERSNAP = 64,   /* EOLDSNAP if snapc is out of order */
+	CEPH_OSD_FLAG_PEERSTAT = 128,   /* msg includes osd_peer_stat */
+	CEPH_OSD_FLAG_BALANCE_READS = 256,
+	CEPH_OSD_FLAG_PARALLELEXEC = 512, /* execute op in parallel */
+	CEPH_OSD_FLAG_PGOP = 1024,      /* pg op, no object */
+	CEPH_OSD_FLAG_EXEC = 2048,      /* op may exec */
+};
+
+enum {
+	CEPH_OSD_OP_FLAG_EXCL = 1,      /* EXCL object create */
+};
+
+#define EOLDSNAPC    ERESTART  /* ORDERSNAP flag set; writer has old snapc*/
+#define EBLACKLISTED ESHUTDOWN /* blacklisted */
+
+/*
+ * an individual object operation.  each may be accompanied by some data
+ * payload
+ */
+struct ceph_osd_op {
+	__le16 op;           /* CEPH_OSD_OP_* */
+	__le32 flags;        /* CEPH_OSD_FLAG_* */
+	union {
+		struct {
+			__le64 offset, length;
+			__le64 truncate_size;
+			__le32 truncate_seq;
+		} __attribute__ ((packed)) extent;
+		struct {
+			__le32 name_len;
+			__le32 value_len;
+		} __attribute__ ((packed)) xattr;
+		struct {
+			__u8 class_len;
+			__u8 method_len;
+			__u8 argc;
+			__le32 indata_len;
+		} __attribute__ ((packed)) cls;
+		struct {
+			__le64 cookie, count;
+		} __attribute__ ((packed)) pgls;
+	};
+	__le32 payload_len;
+} __attribute__ ((packed));
+
+/*
+ * osd request message header.  each request may include multiple
+ * ceph_osd_op object operations.
+ */
+struct ceph_osd_request_head {
+	__le32 client_inc;                 /* client incarnation */
+	struct ceph_object_layout layout;  /* pgid */
+	__le32 osdmap_epoch;               /* client's osdmap epoch */
+
+	__le32 flags;
+
+	struct ceph_timespec mtime;        /* for mutations only */
+	struct ceph_eversion reassert_version; /* if we are replaying op */
+
+	__le32 object_len;     /* length of object name */
+
+	__le64 snapid;         /* snapid to read */
+	__le64 snap_seq;       /* writer's snap context */
+	__le32 num_snaps;
+
+	__le16 num_ops;
+	struct ceph_osd_op ops[];  /* followed by ops[], obj, ticket, snaps */
+} __attribute__ ((packed));
+
+struct ceph_osd_reply_head {
+	__le32 client_inc;                /* client incarnation */
+	__le32 flags;
+	struct ceph_object_layout layout;
+	__le32 osdmap_epoch;
+	struct ceph_eversion reassert_version; /* for replaying uncommitted */
+
+	__le32 result;                    /* result code */
+
+	__le32 object_len;                /* length of object name */
+	__le32 num_ops;
+	struct ceph_osd_op ops[0];  /* ops[], object */
+} __attribute__ ((packed));
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/README linux-libre-2.6.34-gnu1/fs/ceph/README
--- linux-libre-2.6.33-gnu1/fs/ceph/README	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/README	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,20 @@
+#
+# The following files are shared by (and manually synchronized
+# between) the Ceph userland and kernel client.
+#
+# userland                  kernel
+src/include/ceph_fs.h	    fs/ceph/ceph_fs.h
+src/include/ceph_fs.cc	    fs/ceph/ceph_fs.c
+src/include/msgr.h	    fs/ceph/msgr.h
+src/include/rados.h	    fs/ceph/rados.h
+src/include/ceph_strings.cc fs/ceph/ceph_strings.c
+src/include/ceph_frag.h	    fs/ceph/ceph_frag.h
+src/include/ceph_frag.cc    fs/ceph/ceph_frag.c
+src/include/ceph_hash.h	    fs/ceph/ceph_hash.h
+src/include/ceph_hash.cc    fs/ceph/ceph_hash.c
+src/crush/crush.c	    fs/ceph/crush/crush.c
+src/crush/crush.h	    fs/ceph/crush/crush.h
+src/crush/mapper.c	    fs/ceph/crush/mapper.c
+src/crush/mapper.h	    fs/ceph/crush/mapper.h
+src/crush/hash.h	    fs/ceph/crush/hash.h
+src/crush/hash.c	    fs/ceph/crush/hash.c
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/snap.c linux-libre-2.6.34-gnu1/fs/ceph/snap.c
--- linux-libre-2.6.33-gnu1/fs/ceph/snap.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/snap.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,911 @@
+#include "ceph_debug.h"
+
+#include <linux/sort.h>
+#include <linux/slab.h>
+
+#include "super.h"
+#include "decode.h"
+
+/*
+ * Snapshots in ceph are driven in large part by cooperation from the
+ * client.  In contrast to local file systems or file servers that
+ * implement snapshots at a single point in the system, ceph's
+ * distributed access to storage requires clients to help decide
+ * whether a write logically occurs before or after a recently created
+ * snapshot.
+ *
+ * This provides a perfect instantanous client-wide snapshot.  Between
+ * clients, however, snapshots may appear to be applied at slightly
+ * different points in time, depending on delays in delivering the
+ * snapshot notification.
+ *
+ * Snapshots are _not_ file system-wide.  Instead, each snapshot
+ * applies to the subdirectory nested beneath some directory.  This
+ * effectively divides the hierarchy into multiple "realms," where all
+ * of the files contained by each realm share the same set of
+ * snapshots.  An individual realm's snap set contains snapshots
+ * explicitly created on that realm, as well as any snaps in its
+ * parent's snap set _after_ the point at which the parent became it's
+ * parent (due to, say, a rename).  Similarly, snaps from prior parents
+ * during the time intervals during which they were the parent are included.
+ *
+ * The client is spared most of this detail, fortunately... it must only
+ * maintains a hierarchy of realms reflecting the current parent/child
+ * realm relationship, and for each realm has an explicit list of snaps
+ * inherited from prior parents.
+ *
+ * A snap_realm struct is maintained for realms containing every inode
+ * with an open cap in the system.  (The needed snap realm information is
+ * provided by the MDS whenever a cap is issued, i.e., on open.)  A 'seq'
+ * version number is used to ensure that as realm parameters change (new
+ * snapshot, new parent, etc.) the client's realm hierarchy is updated.
+ *
+ * The realm hierarchy drives the generation of a 'snap context' for each
+ * realm, which simply lists the resulting set of snaps for the realm.  This
+ * is attached to any writes sent to OSDs.
+ */
+/*
+ * Unfortunately error handling is a bit mixed here.  If we get a snap
+ * update, but don't have enough memory to update our realm hierarchy,
+ * it's not clear what we can do about it (besides complaining to the
+ * console).
+ */
+
+
+/*
+ * increase ref count for the realm
+ *
+ * caller must hold snap_rwsem for write.
+ */
+void ceph_get_snap_realm(struct ceph_mds_client *mdsc,
+			 struct ceph_snap_realm *realm)
+{
+	dout("get_realm %p %d -> %d\n", realm,
+	     atomic_read(&realm->nref), atomic_read(&realm->nref)+1);
+	/*
+	 * since we _only_ increment realm refs or empty the empty
+	 * list with snap_rwsem held, adjusting the empty list here is
+	 * safe.  we do need to protect against concurrent empty list
+	 * additions, however.
+	 */
+	if (atomic_read(&realm->nref) == 0) {
+		spin_lock(&mdsc->snap_empty_lock);
+		list_del_init(&realm->empty_item);
+		spin_unlock(&mdsc->snap_empty_lock);
+	}
+
+	atomic_inc(&realm->nref);
+}
+
+static void __insert_snap_realm(struct rb_root *root,
+				struct ceph_snap_realm *new)
+{
+	struct rb_node **p = &root->rb_node;
+	struct rb_node *parent = NULL;
+	struct ceph_snap_realm *r = NULL;
+
+	while (*p) {
+		parent = *p;
+		r = rb_entry(parent, struct ceph_snap_realm, node);
+		if (new->ino < r->ino)
+			p = &(*p)->rb_left;
+		else if (new->ino > r->ino)
+			p = &(*p)->rb_right;
+		else
+			BUG();
+	}
+
+	rb_link_node(&new->node, parent, p);
+	rb_insert_color(&new->node, root);
+}
+
+/*
+ * create and get the realm rooted at @ino and bump its ref count.
+ *
+ * caller must hold snap_rwsem for write.
+ */
+static struct ceph_snap_realm *ceph_create_snap_realm(
+	struct ceph_mds_client *mdsc,
+	u64 ino)
+{
+	struct ceph_snap_realm *realm;
+
+	realm = kzalloc(sizeof(*realm), GFP_NOFS);
+	if (!realm)
+		return ERR_PTR(-ENOMEM);
+
+	atomic_set(&realm->nref, 0);    /* tree does not take a ref */
+	realm->ino = ino;
+	INIT_LIST_HEAD(&realm->children);
+	INIT_LIST_HEAD(&realm->child_item);
+	INIT_LIST_HEAD(&realm->empty_item);
+	INIT_LIST_HEAD(&realm->inodes_with_caps);
+	spin_lock_init(&realm->inodes_with_caps_lock);
+	__insert_snap_realm(&mdsc->snap_realms, realm);
+	dout("create_snap_realm %llx %p\n", realm->ino, realm);
+	return realm;
+}
+
+/*
+ * lookup the realm rooted at @ino.
+ *
+ * caller must hold snap_rwsem for write.
+ */
+struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc,
+					       u64 ino)
+{
+	struct rb_node *n = mdsc->snap_realms.rb_node;
+	struct ceph_snap_realm *r;
+
+	while (n) {
+		r = rb_entry(n, struct ceph_snap_realm, node);
+		if (ino < r->ino)
+			n = n->rb_left;
+		else if (ino > r->ino)
+			n = n->rb_right;
+		else {
+			dout("lookup_snap_realm %llx %p\n", r->ino, r);
+			return r;
+		}
+	}
+	return NULL;
+}
+
+static void __put_snap_realm(struct ceph_mds_client *mdsc,
+			     struct ceph_snap_realm *realm);
+
+/*
+ * called with snap_rwsem (write)
+ */
+static void __destroy_snap_realm(struct ceph_mds_client *mdsc,
+				 struct ceph_snap_realm *realm)
+{
+	dout("__destroy_snap_realm %p %llx\n", realm, realm->ino);
+
+	rb_erase(&realm->node, &mdsc->snap_realms);
+
+	if (realm->parent) {
+		list_del_init(&realm->child_item);
+		__put_snap_realm(mdsc, realm->parent);
+	}
+
+	kfree(realm->prior_parent_snaps);
+	kfree(realm->snaps);
+	ceph_put_snap_context(realm->cached_context);
+	kfree(realm);
+}
+
+/*
+ * caller holds snap_rwsem (write)
+ */
+static void __put_snap_realm(struct ceph_mds_client *mdsc,
+			     struct ceph_snap_realm *realm)
+{
+	dout("__put_snap_realm %llx %p %d -> %d\n", realm->ino, realm,
+	     atomic_read(&realm->nref), atomic_read(&realm->nref)-1);
+	if (atomic_dec_and_test(&realm->nref))
+		__destroy_snap_realm(mdsc, realm);
+}
+
+/*
+ * caller needn't hold any locks
+ */
+void ceph_put_snap_realm(struct ceph_mds_client *mdsc,
+			 struct ceph_snap_realm *realm)
+{
+	dout("put_snap_realm %llx %p %d -> %d\n", realm->ino, realm,
+	     atomic_read(&realm->nref), atomic_read(&realm->nref)-1);
+	if (!atomic_dec_and_test(&realm->nref))
+		return;
+
+	if (down_write_trylock(&mdsc->snap_rwsem)) {
+		__destroy_snap_realm(mdsc, realm);
+		up_write(&mdsc->snap_rwsem);
+	} else {
+		spin_lock(&mdsc->snap_empty_lock);
+		list_add(&mdsc->snap_empty, &realm->empty_item);
+		spin_unlock(&mdsc->snap_empty_lock);
+	}
+}
+
+/*
+ * Clean up any realms whose ref counts have dropped to zero.  Note
+ * that this does not include realms who were created but not yet
+ * used.
+ *
+ * Called under snap_rwsem (write)
+ */
+static void __cleanup_empty_realms(struct ceph_mds_client *mdsc)
+{
+	struct ceph_snap_realm *realm;
+
+	spin_lock(&mdsc->snap_empty_lock);
+	while (!list_empty(&mdsc->snap_empty)) {
+		realm = list_first_entry(&mdsc->snap_empty,
+				   struct ceph_snap_realm, empty_item);
+		list_del(&realm->empty_item);
+		spin_unlock(&mdsc->snap_empty_lock);
+		__destroy_snap_realm(mdsc, realm);
+		spin_lock(&mdsc->snap_empty_lock);
+	}
+	spin_unlock(&mdsc->snap_empty_lock);
+}
+
+void ceph_cleanup_empty_realms(struct ceph_mds_client *mdsc)
+{
+	down_write(&mdsc->snap_rwsem);
+	__cleanup_empty_realms(mdsc);
+	up_write(&mdsc->snap_rwsem);
+}
+
+/*
+ * adjust the parent realm of a given @realm.  adjust child list, and parent
+ * pointers, and ref counts appropriately.
+ *
+ * return true if parent was changed, 0 if unchanged, <0 on error.
+ *
+ * caller must hold snap_rwsem for write.
+ */
+static int adjust_snap_realm_parent(struct ceph_mds_client *mdsc,
+				    struct ceph_snap_realm *realm,
+				    u64 parentino)
+{
+	struct ceph_snap_realm *parent;
+
+	if (realm->parent_ino == parentino)
+		return 0;
+
+	parent = ceph_lookup_snap_realm(mdsc, parentino);
+	if (!parent) {
+		parent = ceph_create_snap_realm(mdsc, parentino);
+		if (IS_ERR(parent))
+			return PTR_ERR(parent);
+	}
+	dout("adjust_snap_realm_parent %llx %p: %llx %p -> %llx %p\n",
+	     realm->ino, realm, realm->parent_ino, realm->parent,
+	     parentino, parent);
+	if (realm->parent) {
+		list_del_init(&realm->child_item);
+		ceph_put_snap_realm(mdsc, realm->parent);
+	}
+	realm->parent_ino = parentino;
+	realm->parent = parent;
+	ceph_get_snap_realm(mdsc, parent);
+	list_add(&realm->child_item, &parent->children);
+	return 1;
+}
+
+
+static int cmpu64_rev(const void *a, const void *b)
+{
+	if (*(u64 *)a < *(u64 *)b)
+		return 1;
+	if (*(u64 *)a > *(u64 *)b)
+		return -1;
+	return 0;
+}
+
+/*
+ * build the snap context for a given realm.
+ */
+static int build_snap_context(struct ceph_snap_realm *realm)
+{
+	struct ceph_snap_realm *parent = realm->parent;
+	struct ceph_snap_context *snapc;
+	int err = 0;
+	int i;
+	int num = realm->num_prior_parent_snaps + realm->num_snaps;
+
+	/*
+	 * build parent context, if it hasn't been built.
+	 * conservatively estimate that all parent snaps might be
+	 * included by us.
+	 */
+	if (parent) {
+		if (!parent->cached_context) {
+			err = build_snap_context(parent);
+			if (err)
+				goto fail;
+		}
+		num += parent->cached_context->num_snaps;
+	}
+
+	/* do i actually need to update?  not if my context seq
+	   matches realm seq, and my parents' does to.  (this works
+	   because we rebuild_snap_realms() works _downward_ in
+	   hierarchy after each update.) */
+	if (realm->cached_context &&
+	    realm->cached_context->seq == realm->seq &&
+	    (!parent ||
+	     realm->cached_context->seq >= parent->cached_context->seq)) {
+		dout("build_snap_context %llx %p: %p seq %lld (%d snaps)"
+		     " (unchanged)\n",
+		     realm->ino, realm, realm->cached_context,
+		     realm->cached_context->seq,
+		     realm->cached_context->num_snaps);
+		return 0;
+	}
+
+	/* alloc new snap context */
+	err = -ENOMEM;
+	if (num > ULONG_MAX / sizeof(u64) - sizeof(*snapc))
+		goto fail;
+	snapc = kzalloc(sizeof(*snapc) + num*sizeof(u64), GFP_NOFS);
+	if (!snapc)
+		goto fail;
+	atomic_set(&snapc->nref, 1);
+
+	/* build (reverse sorted) snap vector */
+	num = 0;
+	snapc->seq = realm->seq;
+	if (parent) {
+		/* include any of parent's snaps occuring _after_ my
+		   parent became my parent */
+		for (i = 0; i < parent->cached_context->num_snaps; i++)
+			if (parent->cached_context->snaps[i] >=
+			    realm->parent_since)
+				snapc->snaps[num++] =
+					parent->cached_context->snaps[i];
+		if (parent->cached_context->seq > snapc->seq)
+			snapc->seq = parent->cached_context->seq;
+	}
+	memcpy(snapc->snaps + num, realm->snaps,
+	       sizeof(u64)*realm->num_snaps);
+	num += realm->num_snaps;
+	memcpy(snapc->snaps + num, realm->prior_parent_snaps,
+	       sizeof(u64)*realm->num_prior_parent_snaps);
+	num += realm->num_prior_parent_snaps;
+
+	sort(snapc->snaps, num, sizeof(u64), cmpu64_rev, NULL);
+	snapc->num_snaps = num;
+	dout("build_snap_context %llx %p: %p seq %lld (%d snaps)\n",
+	     realm->ino, realm, snapc, snapc->seq, snapc->num_snaps);
+
+	if (realm->cached_context)
+		ceph_put_snap_context(realm->cached_context);
+	realm->cached_context = snapc;
+	return 0;
+
+fail:
+	/*
+	 * if we fail, clear old (incorrect) cached_context... hopefully
+	 * we'll have better luck building it later
+	 */
+	if (realm->cached_context) {
+		ceph_put_snap_context(realm->cached_context);
+		realm->cached_context = NULL;
+	}
+	pr_err("build_snap_context %llx %p fail %d\n", realm->ino,
+	       realm, err);
+	return err;
+}
+
+/*
+ * rebuild snap context for the given realm and all of its children.
+ */
+static void rebuild_snap_realms(struct ceph_snap_realm *realm)
+{
+	struct ceph_snap_realm *child;
+
+	dout("rebuild_snap_realms %llx %p\n", realm->ino, realm);
+	build_snap_context(realm);
+
+	list_for_each_entry(child, &realm->children, child_item)
+		rebuild_snap_realms(child);
+}
+
+
+/*
+ * helper to allocate and decode an array of snapids.  free prior
+ * instance, if any.
+ */
+static int dup_array(u64 **dst, __le64 *src, int num)
+{
+	int i;
+
+	kfree(*dst);
+	if (num) {
+		*dst = kcalloc(num, sizeof(u64), GFP_NOFS);
+		if (!*dst)
+			return -ENOMEM;
+		for (i = 0; i < num; i++)
+			(*dst)[i] = get_unaligned_le64(src + i);
+	} else {
+		*dst = NULL;
+	}
+	return 0;
+}
+
+
+/*
+ * When a snapshot is applied, the size/mtime inode metadata is queued
+ * in a ceph_cap_snap (one for each snapshot) until writeback
+ * completes and the metadata can be flushed back to the MDS.
+ *
+ * However, if a (sync) write is currently in-progress when we apply
+ * the snapshot, we have to wait until the write succeeds or fails
+ * (and a final size/mtime is known).  In this case the
+ * cap_snap->writing = 1, and is said to be "pending."  When the write
+ * finishes, we __ceph_finish_cap_snap().
+ *
+ * Caller must hold snap_rwsem for read (i.e., the realm topology won't
+ * change).
+ */
+void ceph_queue_cap_snap(struct ceph_inode_info *ci)
+{
+	struct inode *inode = &ci->vfs_inode;
+	struct ceph_cap_snap *capsnap;
+	int used;
+
+	capsnap = kzalloc(sizeof(*capsnap), GFP_NOFS);
+	if (!capsnap) {
+		pr_err("ENOMEM allocating ceph_cap_snap on %p\n", inode);
+		return;
+	}
+
+	spin_lock(&inode->i_lock);
+	used = __ceph_caps_used(ci);
+	if (__ceph_have_pending_cap_snap(ci)) {
+		/* there is no point in queuing multiple "pending" cap_snaps,
+		   as no new writes are allowed to start when pending, so any
+		   writes in progress now were started before the previous
+		   cap_snap.  lucky us. */
+		dout("queue_cap_snap %p already pending\n", inode);
+		kfree(capsnap);
+	} else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR)) {
+		struct ceph_snap_context *snapc = ci->i_head_snapc;
+
+		igrab(inode);
+
+		atomic_set(&capsnap->nref, 1);
+		capsnap->ci = ci;
+		INIT_LIST_HEAD(&capsnap->ci_item);
+		INIT_LIST_HEAD(&capsnap->flushing_item);
+
+		capsnap->follows = snapc->seq - 1;
+		capsnap->issued = __ceph_caps_issued(ci, NULL);
+		capsnap->dirty = __ceph_caps_dirty(ci);
+
+		capsnap->mode = inode->i_mode;
+		capsnap->uid = inode->i_uid;
+		capsnap->gid = inode->i_gid;
+
+		/* fixme? */
+		capsnap->xattr_blob = NULL;
+		capsnap->xattr_len = 0;
+
+		/* dirty page count moved from _head to this cap_snap;
+		   all subsequent writes page dirties occur _after_ this
+		   snapshot. */
+		capsnap->dirty_pages = ci->i_wrbuffer_ref_head;
+		ci->i_wrbuffer_ref_head = 0;
+		capsnap->context = snapc;
+		ci->i_head_snapc = NULL;
+		list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps);
+
+		if (used & CEPH_CAP_FILE_WR) {
+			dout("queue_cap_snap %p cap_snap %p snapc %p"
+			     " seq %llu used WR, now pending\n", inode,
+			     capsnap, snapc, snapc->seq);
+			capsnap->writing = 1;
+		} else {
+			/* note mtime, size NOW. */
+			__ceph_finish_cap_snap(ci, capsnap);
+		}
+	} else {
+		dout("queue_cap_snap %p nothing dirty|writing\n", inode);
+		kfree(capsnap);
+	}
+
+	spin_unlock(&inode->i_lock);
+}
+
+/*
+ * Finalize the size, mtime for a cap_snap.. that is, settle on final values
+ * to be used for the snapshot, to be flushed back to the mds.
+ *
+ * If capsnap can now be flushed, add to snap_flush list, and return 1.
+ *
+ * Caller must hold i_lock.
+ */
+int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
+			    struct ceph_cap_snap *capsnap)
+{
+	struct inode *inode = &ci->vfs_inode;
+	struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc;
+
+	BUG_ON(capsnap->writing);
+	capsnap->size = inode->i_size;
+	capsnap->mtime = inode->i_mtime;
+	capsnap->atime = inode->i_atime;
+	capsnap->ctime = inode->i_ctime;
+	capsnap->time_warp_seq = ci->i_time_warp_seq;
+	if (capsnap->dirty_pages) {
+		dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu "
+		     "still has %d dirty pages\n", inode, capsnap,
+		     capsnap->context, capsnap->context->seq,
+		     ceph_cap_string(capsnap->dirty), capsnap->size,
+		     capsnap->dirty_pages);
+		return 0;
+	}
+	dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu\n",
+	     inode, capsnap, capsnap->context,
+	     capsnap->context->seq, ceph_cap_string(capsnap->dirty),
+	     capsnap->size);
+
+	spin_lock(&mdsc->snap_flush_lock);
+	list_add_tail(&ci->i_snap_flush_item, &mdsc->snap_flush_list);
+	spin_unlock(&mdsc->snap_flush_lock);
+	return 1;  /* caller may want to ceph_flush_snaps */
+}
+
+
+/*
+ * Parse and apply a snapblob "snap trace" from the MDS.  This specifies
+ * the snap realm parameters from a given realm and all of its ancestors,
+ * up to the root.
+ *
+ * Caller must hold snap_rwsem for write.
+ */
+int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
+			   void *p, void *e, bool deletion)
+{
+	struct ceph_mds_snap_realm *ri;    /* encoded */
+	__le64 *snaps;                     /* encoded */
+	__le64 *prior_parent_snaps;        /* encoded */
+	struct ceph_snap_realm *realm;
+	int invalidate = 0;
+	int err = -ENOMEM;
+
+	dout("update_snap_trace deletion=%d\n", deletion);
+more:
+	ceph_decode_need(&p, e, sizeof(*ri), bad);
+	ri = p;
+	p += sizeof(*ri);
+	ceph_decode_need(&p, e, sizeof(u64)*(le32_to_cpu(ri->num_snaps) +
+			    le32_to_cpu(ri->num_prior_parent_snaps)), bad);
+	snaps = p;
+	p += sizeof(u64) * le32_to_cpu(ri->num_snaps);
+	prior_parent_snaps = p;
+	p += sizeof(u64) * le32_to_cpu(ri->num_prior_parent_snaps);
+
+	realm = ceph_lookup_snap_realm(mdsc, le64_to_cpu(ri->ino));
+	if (!realm) {
+		realm = ceph_create_snap_realm(mdsc, le64_to_cpu(ri->ino));
+		if (IS_ERR(realm)) {
+			err = PTR_ERR(realm);
+			goto fail;
+		}
+	}
+
+	if (le64_to_cpu(ri->seq) > realm->seq) {
+		dout("update_snap_trace updating %llx %p %lld -> %lld\n",
+		     realm->ino, realm, realm->seq, le64_to_cpu(ri->seq));
+		/*
+		 * if the realm seq has changed, queue a cap_snap for every
+		 * inode with open caps.  we do this _before_ we update
+		 * the realm info so that we prepare for writeback under the
+		 * _previous_ snap context.
+		 *
+		 * ...unless it's a snap deletion!
+		 */
+		if (!deletion) {
+			struct ceph_inode_info *ci;
+			struct inode *lastinode = NULL;
+
+			spin_lock(&realm->inodes_with_caps_lock);
+			list_for_each_entry(ci, &realm->inodes_with_caps,
+					    i_snap_realm_item) {
+				struct inode *inode = igrab(&ci->vfs_inode);
+				if (!inode)
+					continue;
+				spin_unlock(&realm->inodes_with_caps_lock);
+				if (lastinode)
+					iput(lastinode);
+				lastinode = inode;
+				ceph_queue_cap_snap(ci);
+				spin_lock(&realm->inodes_with_caps_lock);
+			}
+			spin_unlock(&realm->inodes_with_caps_lock);
+			if (lastinode)
+				iput(lastinode);
+			dout("update_snap_trace cap_snaps queued\n");
+		}
+
+	} else {
+		dout("update_snap_trace %llx %p seq %lld unchanged\n",
+		     realm->ino, realm, realm->seq);
+	}
+
+	/* ensure the parent is correct */
+	err = adjust_snap_realm_parent(mdsc, realm, le64_to_cpu(ri->parent));
+	if (err < 0)
+		goto fail;
+	invalidate += err;
+
+	if (le64_to_cpu(ri->seq) > realm->seq) {
+		/* update realm parameters, snap lists */
+		realm->seq = le64_to_cpu(ri->seq);
+		realm->created = le64_to_cpu(ri->created);
+		realm->parent_since = le64_to_cpu(ri->parent_since);
+
+		realm->num_snaps = le32_to_cpu(ri->num_snaps);
+		err = dup_array(&realm->snaps, snaps, realm->num_snaps);
+		if (err < 0)
+			goto fail;
+
+		realm->num_prior_parent_snaps =
+			le32_to_cpu(ri->num_prior_parent_snaps);
+		err = dup_array(&realm->prior_parent_snaps, prior_parent_snaps,
+				realm->num_prior_parent_snaps);
+		if (err < 0)
+			goto fail;
+
+		invalidate = 1;
+	} else if (!realm->cached_context) {
+		invalidate = 1;
+	}
+
+	dout("done with %llx %p, invalidated=%d, %p %p\n", realm->ino,
+	     realm, invalidate, p, e);
+
+	if (p < e)
+		goto more;
+
+	/* invalidate when we reach the _end_ (root) of the trace */
+	if (invalidate)
+		rebuild_snap_realms(realm);
+
+	__cleanup_empty_realms(mdsc);
+	return 0;
+
+bad:
+	err = -EINVAL;
+fail:
+	pr_err("update_snap_trace error %d\n", err);
+	return err;
+}
+
+
+/*
+ * Send any cap_snaps that are queued for flush.  Try to carry
+ * s_mutex across multiple snap flushes to avoid locking overhead.
+ *
+ * Caller holds no locks.
+ */
+static void flush_snaps(struct ceph_mds_client *mdsc)
+{
+	struct ceph_inode_info *ci;
+	struct inode *inode;
+	struct ceph_mds_session *session = NULL;
+
+	dout("flush_snaps\n");
+	spin_lock(&mdsc->snap_flush_lock);
+	while (!list_empty(&mdsc->snap_flush_list)) {
+		ci = list_first_entry(&mdsc->snap_flush_list,
+				struct ceph_inode_info, i_snap_flush_item);
+		inode = &ci->vfs_inode;
+		igrab(inode);
+		spin_unlock(&mdsc->snap_flush_lock);
+		spin_lock(&inode->i_lock);
+		__ceph_flush_snaps(ci, &session);
+		spin_unlock(&inode->i_lock);
+		iput(inode);
+		spin_lock(&mdsc->snap_flush_lock);
+	}
+	spin_unlock(&mdsc->snap_flush_lock);
+
+	if (session) {
+		mutex_unlock(&session->s_mutex);
+		ceph_put_mds_session(session);
+	}
+	dout("flush_snaps done\n");
+}
+
+
+/*
+ * Handle a snap notification from the MDS.
+ *
+ * This can take two basic forms: the simplest is just a snap creation
+ * or deletion notification on an existing realm.  This should update the
+ * realm and its children.
+ *
+ * The more difficult case is realm creation, due to snap creation at a
+ * new point in the file hierarchy, or due to a rename that moves a file or
+ * directory into another realm.
+ */
+void ceph_handle_snap(struct ceph_mds_client *mdsc,
+		      struct ceph_mds_session *session,
+		      struct ceph_msg *msg)
+{
+	struct super_block *sb = mdsc->client->sb;
+	int mds = session->s_mds;
+	u64 split;
+	int op;
+	int trace_len;
+	struct ceph_snap_realm *realm = NULL;
+	void *p = msg->front.iov_base;
+	void *e = p + msg->front.iov_len;
+	struct ceph_mds_snap_head *h;
+	int num_split_inos, num_split_realms;
+	__le64 *split_inos = NULL, *split_realms = NULL;
+	int i;
+	int locked_rwsem = 0;
+
+	/* decode */
+	if (msg->front.iov_len < sizeof(*h))
+		goto bad;
+	h = p;
+	op = le32_to_cpu(h->op);
+	split = le64_to_cpu(h->split);   /* non-zero if we are splitting an
+					  * existing realm */
+	num_split_inos = le32_to_cpu(h->num_split_inos);
+	num_split_realms = le32_to_cpu(h->num_split_realms);
+	trace_len = le32_to_cpu(h->trace_len);
+	p += sizeof(*h);
+
+	dout("handle_snap from mds%d op %s split %llx tracelen %d\n", mds,
+	     ceph_snap_op_name(op), split, trace_len);
+
+	mutex_lock(&session->s_mutex);
+	session->s_seq++;
+	mutex_unlock(&session->s_mutex);
+
+	down_write(&mdsc->snap_rwsem);
+	locked_rwsem = 1;
+
+	if (op == CEPH_SNAP_OP_SPLIT) {
+		struct ceph_mds_snap_realm *ri;
+
+		/*
+		 * A "split" breaks part of an existing realm off into
+		 * a new realm.  The MDS provides a list of inodes
+		 * (with caps) and child realms that belong to the new
+		 * child.
+		 */
+		split_inos = p;
+		p += sizeof(u64) * num_split_inos;
+		split_realms = p;
+		p += sizeof(u64) * num_split_realms;
+		ceph_decode_need(&p, e, sizeof(*ri), bad);
+		/* we will peek at realm info here, but will _not_
+		 * advance p, as the realm update will occur below in
+		 * ceph_update_snap_trace. */
+		ri = p;
+
+		realm = ceph_lookup_snap_realm(mdsc, split);
+		if (!realm) {
+			realm = ceph_create_snap_realm(mdsc, split);
+			if (IS_ERR(realm))
+				goto out;
+		}
+		ceph_get_snap_realm(mdsc, realm);
+
+		dout("splitting snap_realm %llx %p\n", realm->ino, realm);
+		for (i = 0; i < num_split_inos; i++) {
+			struct ceph_vino vino = {
+				.ino = le64_to_cpu(split_inos[i]),
+				.snap = CEPH_NOSNAP,
+			};
+			struct inode *inode = ceph_find_inode(sb, vino);
+			struct ceph_inode_info *ci;
+
+			if (!inode)
+				continue;
+			ci = ceph_inode(inode);
+
+			spin_lock(&inode->i_lock);
+			if (!ci->i_snap_realm)
+				goto skip_inode;
+			/*
+			 * If this inode belongs to a realm that was
+			 * created after our new realm, we experienced
+			 * a race (due to another split notifications
+			 * arriving from a different MDS).  So skip
+			 * this inode.
+			 */
+			if (ci->i_snap_realm->created >
+			    le64_to_cpu(ri->created)) {
+				dout(" leaving %p in newer realm %llx %p\n",
+				     inode, ci->i_snap_realm->ino,
+				     ci->i_snap_realm);
+				goto skip_inode;
+			}
+			dout(" will move %p to split realm %llx %p\n",
+			     inode, realm->ino, realm);
+			/*
+			 * Remove the inode from the realm's inode
+			 * list, but don't add it to the new realm
+			 * yet.  We don't want the cap_snap to be
+			 * queued (again) by ceph_update_snap_trace()
+			 * below.  Queue it _now_, under the old context.
+			 */
+			spin_lock(&realm->inodes_with_caps_lock);
+			list_del_init(&ci->i_snap_realm_item);
+			spin_unlock(&realm->inodes_with_caps_lock);
+			spin_unlock(&inode->i_lock);
+
+			ceph_queue_cap_snap(ci);
+
+			iput(inode);
+			continue;
+
+skip_inode:
+			spin_unlock(&inode->i_lock);
+			iput(inode);
+		}
+
+		/* we may have taken some of the old realm's children. */
+		for (i = 0; i < num_split_realms; i++) {
+			struct ceph_snap_realm *child =
+				ceph_lookup_snap_realm(mdsc,
+					   le64_to_cpu(split_realms[i]));
+			if (!child)
+				continue;
+			adjust_snap_realm_parent(mdsc, child, realm->ino);
+		}
+	}
+
+	/*
+	 * update using the provided snap trace. if we are deleting a
+	 * snap, we can avoid queueing cap_snaps.
+	 */
+	ceph_update_snap_trace(mdsc, p, e,
+			       op == CEPH_SNAP_OP_DESTROY);
+
+	if (op == CEPH_SNAP_OP_SPLIT) {
+		/*
+		 * ok, _now_ add the inodes into the new realm.
+		 */
+		for (i = 0; i < num_split_inos; i++) {
+			struct ceph_vino vino = {
+				.ino = le64_to_cpu(split_inos[i]),
+				.snap = CEPH_NOSNAP,
+			};
+			struct inode *inode = ceph_find_inode(sb, vino);
+			struct ceph_inode_info *ci;
+
+			if (!inode)
+				continue;
+			ci = ceph_inode(inode);
+			spin_lock(&inode->i_lock);
+			if (list_empty(&ci->i_snap_realm_item)) {
+				struct ceph_snap_realm *oldrealm =
+					ci->i_snap_realm;
+
+				dout(" moving %p to split realm %llx %p\n",
+				     inode, realm->ino, realm);
+				spin_lock(&realm->inodes_with_caps_lock);
+				list_add(&ci->i_snap_realm_item,
+					 &realm->inodes_with_caps);
+				ci->i_snap_realm = realm;
+				spin_unlock(&realm->inodes_with_caps_lock);
+				ceph_get_snap_realm(mdsc, realm);
+				ceph_put_snap_realm(mdsc, oldrealm);
+			}
+			spin_unlock(&inode->i_lock);
+			iput(inode);
+		}
+
+		/* we took a reference when we created the realm, above */
+		ceph_put_snap_realm(mdsc, realm);
+	}
+
+	__cleanup_empty_realms(mdsc);
+
+	up_write(&mdsc->snap_rwsem);
+
+	flush_snaps(mdsc);
+	return;
+
+bad:
+	pr_err("corrupt snap message from mds%d\n", mds);
+	ceph_msg_dump(msg);
+out:
+	if (locked_rwsem)
+		up_write(&mdsc->snap_rwsem);
+	return;
+}
+
+
+
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/super.c linux-libre-2.6.34-gnu1/fs/ceph/super.c
--- linux-libre-2.6.33-gnu1/fs/ceph/super.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/super.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,1041 @@
+
+#include "ceph_debug.h"
+
+#include <linux/backing-dev.h>
+#include <linux/fs.h>
+#include <linux/inet.h>
+#include <linux/in6.h>
+#include <linux/module.h>
+#include <linux/mount.h>
+#include <linux/parser.h>
+#include <linux/rwsem.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/statfs.h>
+#include <linux/string.h>
+#include <linux/version.h>
+#include <linux/vmalloc.h>
+
+#include "decode.h"
+#include "super.h"
+#include "mon_client.h"
+#include "auth.h"
+
+/*
+ * Ceph superblock operations
+ *
+ * Handle the basics of mounting, unmounting.
+ */
+
+
+/*
+ * find filename portion of a path (/foo/bar/baz -> baz)
+ */
+const char *ceph_file_part(const char *s, int len)
+{
+	const char *e = s + len;
+
+	while (e != s && *(e-1) != '/')
+		e--;
+	return e;
+}
+
+
+/*
+ * super ops
+ */
+static void ceph_put_super(struct super_block *s)
+{
+	struct ceph_client *client = ceph_sb_to_client(s);
+
+	dout("put_super\n");
+	ceph_mdsc_close_sessions(&client->mdsc);
+
+	/*
+	 * ensure we release the bdi before put_anon_super releases
+	 * the device name.
+	 */
+	if (s->s_bdi == &client->backing_dev_info) {
+		bdi_unregister(&client->backing_dev_info);
+		s->s_bdi = NULL;
+	}
+
+	return;
+}
+
+static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+	struct ceph_client *client = ceph_inode_to_client(dentry->d_inode);
+	struct ceph_monmap *monmap = client->monc.monmap;
+	struct ceph_statfs st;
+	u64 fsid;
+	int err;
+
+	dout("statfs\n");
+	err = ceph_monc_do_statfs(&client->monc, &st);
+	if (err < 0)
+		return err;
+
+	/* fill in kstatfs */
+	buf->f_type = CEPH_SUPER_MAGIC;  /* ?? */
+
+	/*
+	 * express utilization in terms of large blocks to avoid
+	 * overflow on 32-bit machines.
+	 */
+	buf->f_bsize = 1 << CEPH_BLOCK_SHIFT;
+	buf->f_blocks = le64_to_cpu(st.kb) >> (CEPH_BLOCK_SHIFT-10);
+	buf->f_bfree = (le64_to_cpu(st.kb) - le64_to_cpu(st.kb_used)) >>
+		(CEPH_BLOCK_SHIFT-10);
+	buf->f_bavail = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);
+
+	buf->f_files = le64_to_cpu(st.num_objects);
+	buf->f_ffree = -1;
+	buf->f_namelen = PATH_MAX;
+	buf->f_frsize = PAGE_CACHE_SIZE;
+
+	/* leave fsid little-endian, regardless of host endianness */
+	fsid = *(u64 *)(&monmap->fsid) ^ *((u64 *)&monmap->fsid + 1);
+	buf->f_fsid.val[0] = fsid & 0xffffffff;
+	buf->f_fsid.val[1] = fsid >> 32;
+
+	return 0;
+}
+
+
+static int ceph_syncfs(struct super_block *sb, int wait)
+{
+	dout("sync_fs %d\n", wait);
+	ceph_osdc_sync(&ceph_client(sb)->osdc);
+	ceph_mdsc_sync(&ceph_client(sb)->mdsc);
+	dout("sync_fs %d done\n", wait);
+	return 0;
+}
+
+
+/**
+ * ceph_show_options - Show mount options in /proc/mounts
+ * @m: seq_file to write to
+ * @mnt: mount descriptor
+ */
+static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt)
+{
+	struct ceph_client *client = ceph_sb_to_client(mnt->mnt_sb);
+	struct ceph_mount_args *args = client->mount_args;
+
+	if (args->flags & CEPH_OPT_FSID)
+		seq_printf(m, ",fsidmajor=%llu,fsidminor%llu",
+			   le64_to_cpu(*(__le64 *)&args->fsid.fsid[0]),
+			   le64_to_cpu(*(__le64 *)&args->fsid.fsid[8]));
+	if (args->flags & CEPH_OPT_NOSHARE)
+		seq_puts(m, ",noshare");
+	if (args->flags & CEPH_OPT_DIRSTAT)
+		seq_puts(m, ",dirstat");
+	if ((args->flags & CEPH_OPT_RBYTES) == 0)
+		seq_puts(m, ",norbytes");
+	if (args->flags & CEPH_OPT_NOCRC)
+		seq_puts(m, ",nocrc");
+	if (args->flags & CEPH_OPT_NOASYNCREADDIR)
+		seq_puts(m, ",noasyncreaddir");
+	if (strcmp(args->snapdir_name, CEPH_SNAPDIRNAME_DEFAULT))
+		seq_printf(m, ",snapdirname=%s", args->snapdir_name);
+	if (args->name)
+		seq_printf(m, ",name=%s", args->name);
+	if (args->secret)
+		seq_puts(m, ",secret=<hidden>");
+	return 0;
+}
+
+/*
+ * caches
+ */
+struct kmem_cache *ceph_inode_cachep;
+struct kmem_cache *ceph_cap_cachep;
+struct kmem_cache *ceph_dentry_cachep;
+struct kmem_cache *ceph_file_cachep;
+
+static void ceph_inode_init_once(void *foo)
+{
+	struct ceph_inode_info *ci = foo;
+	inode_init_once(&ci->vfs_inode);
+}
+
+static int default_congestion_kb(void)
+{
+	int congestion_kb;
+
+	/*
+	 * Copied from NFS
+	 *
+	 * congestion size, scale with available memory.
+	 *
+	 *  64MB:    8192k
+	 * 128MB:   11585k
+	 * 256MB:   16384k
+	 * 512MB:   23170k
+	 *   1GB:   32768k
+	 *   2GB:   46340k
+	 *   4GB:   65536k
+	 *   8GB:   92681k
+	 *  16GB:  131072k
+	 *
+	 * This allows larger machines to have larger/more transfers.
+	 * Limit the default to 256M
+	 */
+	congestion_kb = (16*int_sqrt(totalram_pages)) << (PAGE_SHIFT-10);
+	if (congestion_kb > 256*1024)
+		congestion_kb = 256*1024;
+
+	return congestion_kb;
+}
+
+static int __init init_caches(void)
+{
+	ceph_inode_cachep = kmem_cache_create("ceph_inode_info",
+				      sizeof(struct ceph_inode_info),
+				      __alignof__(struct ceph_inode_info),
+				      (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD),
+				      ceph_inode_init_once);
+	if (ceph_inode_cachep == NULL)
+		return -ENOMEM;
+
+	ceph_cap_cachep = KMEM_CACHE(ceph_cap,
+				     SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD);
+	if (ceph_cap_cachep == NULL)
+		goto bad_cap;
+
+	ceph_dentry_cachep = KMEM_CACHE(ceph_dentry_info,
+					SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD);
+	if (ceph_dentry_cachep == NULL)
+		goto bad_dentry;
+
+	ceph_file_cachep = KMEM_CACHE(ceph_file_info,
+				      SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD);
+	if (ceph_file_cachep == NULL)
+		goto bad_file;
+
+	return 0;
+
+bad_file:
+	kmem_cache_destroy(ceph_dentry_cachep);
+bad_dentry:
+	kmem_cache_destroy(ceph_cap_cachep);
+bad_cap:
+	kmem_cache_destroy(ceph_inode_cachep);
+	return -ENOMEM;
+}
+
+static void destroy_caches(void)
+{
+	kmem_cache_destroy(ceph_inode_cachep);
+	kmem_cache_destroy(ceph_cap_cachep);
+	kmem_cache_destroy(ceph_dentry_cachep);
+	kmem_cache_destroy(ceph_file_cachep);
+}
+
+
+/*
+ * ceph_umount_begin - initiate forced umount.  Tear down down the
+ * mount, skipping steps that may hang while waiting for server(s).
+ */
+static void ceph_umount_begin(struct super_block *sb)
+{
+	struct ceph_client *client = ceph_sb_to_client(sb);
+
+	dout("ceph_umount_begin - starting forced umount\n");
+	if (!client)
+		return;
+	client->mount_state = CEPH_MOUNT_SHUTDOWN;
+	return;
+}
+
+static const struct super_operations ceph_super_ops = {
+	.alloc_inode	= ceph_alloc_inode,
+	.destroy_inode	= ceph_destroy_inode,
+	.write_inode    = ceph_write_inode,
+	.sync_fs        = ceph_syncfs,
+	.put_super	= ceph_put_super,
+	.show_options   = ceph_show_options,
+	.statfs		= ceph_statfs,
+	.umount_begin   = ceph_umount_begin,
+};
+
+
+const char *ceph_msg_type_name(int type)
+{
+	switch (type) {
+	case CEPH_MSG_SHUTDOWN: return "shutdown";
+	case CEPH_MSG_PING: return "ping";
+	case CEPH_MSG_AUTH: return "auth";
+	case CEPH_MSG_AUTH_REPLY: return "auth_reply";
+	case CEPH_MSG_MON_MAP: return "mon_map";
+	case CEPH_MSG_MON_GET_MAP: return "mon_get_map";
+	case CEPH_MSG_MON_SUBSCRIBE: return "mon_subscribe";
+	case CEPH_MSG_MON_SUBSCRIBE_ACK: return "mon_subscribe_ack";
+	case CEPH_MSG_STATFS: return "statfs";
+	case CEPH_MSG_STATFS_REPLY: return "statfs_reply";
+	case CEPH_MSG_MDS_MAP: return "mds_map";
+	case CEPH_MSG_CLIENT_SESSION: return "client_session";
+	case CEPH_MSG_CLIENT_RECONNECT: return "client_reconnect";
+	case CEPH_MSG_CLIENT_REQUEST: return "client_request";
+	case CEPH_MSG_CLIENT_REQUEST_FORWARD: return "client_request_forward";
+	case CEPH_MSG_CLIENT_REPLY: return "client_reply";
+	case CEPH_MSG_CLIENT_CAPS: return "client_caps";
+	case CEPH_MSG_CLIENT_CAPRELEASE: return "client_cap_release";
+	case CEPH_MSG_CLIENT_SNAP: return "client_snap";
+	case CEPH_MSG_CLIENT_LEASE: return "client_lease";
+	case CEPH_MSG_OSD_MAP: return "osd_map";
+	case CEPH_MSG_OSD_OP: return "osd_op";
+	case CEPH_MSG_OSD_OPREPLY: return "osd_opreply";
+	default: return "unknown";
+	}
+}
+
+
+/*
+ * mount options
+ */
+enum {
+	Opt_fsidmajor,
+	Opt_fsidminor,
+	Opt_monport,
+	Opt_wsize,
+	Opt_rsize,
+	Opt_osdtimeout,
+	Opt_osdkeepalivetimeout,
+	Opt_mount_timeout,
+	Opt_osd_idle_ttl,
+	Opt_caps_wanted_delay_min,
+	Opt_caps_wanted_delay_max,
+	Opt_readdir_max_entries,
+	Opt_congestion_kb,
+	Opt_last_int,
+	/* int args above */
+	Opt_snapdirname,
+	Opt_name,
+	Opt_secret,
+	Opt_last_string,
+	/* string args above */
+	Opt_ip,
+	Opt_noshare,
+	Opt_dirstat,
+	Opt_nodirstat,
+	Opt_rbytes,
+	Opt_norbytes,
+	Opt_nocrc,
+	Opt_noasyncreaddir,
+};
+
+static match_table_t arg_tokens = {
+	{Opt_fsidmajor, "fsidmajor=%ld"},
+	{Opt_fsidminor, "fsidminor=%ld"},
+	{Opt_monport, "monport=%d"},
+	{Opt_wsize, "wsize=%d"},
+	{Opt_rsize, "rsize=%d"},
+	{Opt_osdtimeout, "osdtimeout=%d"},
+	{Opt_osdkeepalivetimeout, "osdkeepalive=%d"},
+	{Opt_mount_timeout, "mount_timeout=%d"},
+	{Opt_osd_idle_ttl, "osd_idle_ttl=%d"},
+	{Opt_caps_wanted_delay_min, "caps_wanted_delay_min=%d"},
+	{Opt_caps_wanted_delay_max, "caps_wanted_delay_max=%d"},
+	{Opt_readdir_max_entries, "readdir_max_entries=%d"},
+	{Opt_congestion_kb, "write_congestion_kb=%d"},
+	/* int args above */
+	{Opt_snapdirname, "snapdirname=%s"},
+	{Opt_name, "name=%s"},
+	{Opt_secret, "secret=%s"},
+	/* string args above */
+	{Opt_ip, "ip=%s"},
+	{Opt_noshare, "noshare"},
+	{Opt_dirstat, "dirstat"},
+	{Opt_nodirstat, "nodirstat"},
+	{Opt_rbytes, "rbytes"},
+	{Opt_norbytes, "norbytes"},
+	{Opt_nocrc, "nocrc"},
+	{Opt_noasyncreaddir, "noasyncreaddir"},
+	{-1, NULL}
+};
+
+
+static struct ceph_mount_args *parse_mount_args(int flags, char *options,
+						const char *dev_name,
+						const char **path)
+{
+	struct ceph_mount_args *args;
+	const char *c;
+	int err = -ENOMEM;
+	substring_t argstr[MAX_OPT_ARGS];
+
+	args = kzalloc(sizeof(*args), GFP_KERNEL);
+	if (!args)
+		return ERR_PTR(-ENOMEM);
+	args->mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*args->mon_addr),
+				 GFP_KERNEL);
+	if (!args->mon_addr)
+		goto out;
+
+	dout("parse_mount_args %p, dev_name '%s'\n", args, dev_name);
+
+	/* start with defaults */
+	args->sb_flags = flags;
+	args->flags = CEPH_OPT_DEFAULT;
+	args->osd_timeout = CEPH_OSD_TIMEOUT_DEFAULT;
+	args->osd_keepalive_timeout = CEPH_OSD_KEEPALIVE_DEFAULT;
+	args->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT; /* seconds */
+	args->osd_idle_ttl = CEPH_OSD_IDLE_TTL_DEFAULT;   /* seconds */
+	args->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT;
+	args->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT;
+	args->rsize = CEPH_MOUNT_RSIZE_DEFAULT;
+	args->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL);
+	args->cap_release_safety = CEPH_CAPS_PER_RELEASE * 4;
+	args->max_readdir = 1024;
+	args->congestion_kb = default_congestion_kb();
+
+	/* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */
+	err = -EINVAL;
+	if (!dev_name)
+		goto out;
+	*path = strstr(dev_name, ":/");
+	if (*path == NULL) {
+		pr_err("device name is missing path (no :/ in %s)\n",
+		       dev_name);
+		goto out;
+	}
+
+	/* get mon ip(s) */
+	err = ceph_parse_ips(dev_name, *path, args->mon_addr,
+			     CEPH_MAX_MON, &args->num_mon);
+	if (err < 0)
+		goto out;
+
+	/* path on server */
+	*path += 2;
+	dout("server path '%s'\n", *path);
+
+	/* parse mount options */
+	while ((c = strsep(&options, ",")) != NULL) {
+		int token, intval, ret;
+		if (!*c)
+			continue;
+		err = -EINVAL;
+		token = match_token((char *)c, arg_tokens, argstr);
+		if (token < 0) {
+			pr_err("bad mount option at '%s'\n", c);
+			goto out;
+		}
+		if (token < Opt_last_int) {
+			ret = match_int(&argstr[0], &intval);
+			if (ret < 0) {
+				pr_err("bad mount option arg (not int) "
+				       "at '%s'\n", c);
+				continue;
+			}
+			dout("got int token %d val %d\n", token, intval);
+		} else if (token > Opt_last_int && token < Opt_last_string) {
+			dout("got string token %d val %s\n", token,
+			     argstr[0].from);
+		} else {
+			dout("got token %d\n", token);
+		}
+		switch (token) {
+		case Opt_fsidmajor:
+			*(__le64 *)&args->fsid.fsid[0] = cpu_to_le64(intval);
+			break;
+		case Opt_fsidminor:
+			*(__le64 *)&args->fsid.fsid[8] = cpu_to_le64(intval);
+			break;
+		case Opt_ip:
+			err = ceph_parse_ips(argstr[0].from,
+					     argstr[0].to,
+					     &args->my_addr,
+					     1, NULL);
+			if (err < 0)
+				goto out;
+			args->flags |= CEPH_OPT_MYIP;
+			break;
+
+		case Opt_snapdirname:
+			kfree(args->snapdir_name);
+			args->snapdir_name = kstrndup(argstr[0].from,
+					      argstr[0].to-argstr[0].from,
+					      GFP_KERNEL);
+			break;
+		case Opt_name:
+			args->name = kstrndup(argstr[0].from,
+					      argstr[0].to-argstr[0].from,
+					      GFP_KERNEL);
+			break;
+		case Opt_secret:
+			args->secret = kstrndup(argstr[0].from,
+						argstr[0].to-argstr[0].from,
+						GFP_KERNEL);
+			break;
+
+			/* misc */
+		case Opt_wsize:
+			args->wsize = intval;
+			break;
+		case Opt_rsize:
+			args->rsize = intval;
+			break;
+		case Opt_osdtimeout:
+			args->osd_timeout = intval;
+			break;
+		case Opt_osdkeepalivetimeout:
+			args->osd_keepalive_timeout = intval;
+			break;
+		case Opt_mount_timeout:
+			args->mount_timeout = intval;
+			break;
+		case Opt_caps_wanted_delay_min:
+			args->caps_wanted_delay_min = intval;
+			break;
+		case Opt_caps_wanted_delay_max:
+			args->caps_wanted_delay_max = intval;
+			break;
+		case Opt_readdir_max_entries:
+			args->max_readdir = intval;
+			break;
+		case Opt_congestion_kb:
+			args->congestion_kb = intval;
+			break;
+
+		case Opt_noshare:
+			args->flags |= CEPH_OPT_NOSHARE;
+			break;
+
+		case Opt_dirstat:
+			args->flags |= CEPH_OPT_DIRSTAT;
+			break;
+		case Opt_nodirstat:
+			args->flags &= ~CEPH_OPT_DIRSTAT;
+			break;
+		case Opt_rbytes:
+			args->flags |= CEPH_OPT_RBYTES;
+			break;
+		case Opt_norbytes:
+			args->flags &= ~CEPH_OPT_RBYTES;
+			break;
+		case Opt_nocrc:
+			args->flags |= CEPH_OPT_NOCRC;
+			break;
+		case Opt_noasyncreaddir:
+			args->flags |= CEPH_OPT_NOASYNCREADDIR;
+			break;
+
+		default:
+			BUG_ON(token);
+		}
+	}
+	return args;
+
+out:
+	kfree(args->mon_addr);
+	kfree(args);
+	return ERR_PTR(err);
+}
+
+static void destroy_mount_args(struct ceph_mount_args *args)
+{
+	dout("destroy_mount_args %p\n", args);
+	kfree(args->snapdir_name);
+	args->snapdir_name = NULL;
+	kfree(args->name);
+	args->name = NULL;
+	kfree(args->secret);
+	args->secret = NULL;
+	kfree(args);
+}
+
+/*
+ * create a fresh client instance
+ */
+static struct ceph_client *ceph_create_client(struct ceph_mount_args *args)
+{
+	struct ceph_client *client;
+	int err = -ENOMEM;
+
+	client = kzalloc(sizeof(*client), GFP_KERNEL);
+	if (client == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_init(&client->mount_mutex);
+
+	init_waitqueue_head(&client->auth_wq);
+
+	client->sb = NULL;
+	client->mount_state = CEPH_MOUNT_MOUNTING;
+	client->mount_args = args;
+
+	client->msgr = NULL;
+
+	client->auth_err = 0;
+	atomic_long_set(&client->writeback_count, 0);
+
+	err = bdi_init(&client->backing_dev_info);
+	if (err < 0)
+		goto fail;
+
+	err = -ENOMEM;
+	client->wb_wq = create_workqueue("ceph-writeback");
+	if (client->wb_wq == NULL)
+		goto fail_bdi;
+	client->pg_inv_wq = create_singlethread_workqueue("ceph-pg-invalid");
+	if (client->pg_inv_wq == NULL)
+		goto fail_wb_wq;
+	client->trunc_wq = create_singlethread_workqueue("ceph-trunc");
+	if (client->trunc_wq == NULL)
+		goto fail_pg_inv_wq;
+
+	/* set up mempools */
+	err = -ENOMEM;
+	client->wb_pagevec_pool = mempool_create_kmalloc_pool(10,
+			      client->mount_args->wsize >> PAGE_CACHE_SHIFT);
+	if (!client->wb_pagevec_pool)
+		goto fail_trunc_wq;
+
+	/* caps */
+	client->min_caps = args->max_readdir;
+	ceph_adjust_min_caps(client->min_caps);
+
+	/* subsystems */
+	err = ceph_monc_init(&client->monc, client);
+	if (err < 0)
+		goto fail_mempool;
+	err = ceph_osdc_init(&client->osdc, client);
+	if (err < 0)
+		goto fail_monc;
+	err = ceph_mdsc_init(&client->mdsc, client);
+	if (err < 0)
+		goto fail_osdc;
+	return client;
+
+fail_osdc:
+	ceph_osdc_stop(&client->osdc);
+fail_monc:
+	ceph_monc_stop(&client->monc);
+fail_mempool:
+	mempool_destroy(client->wb_pagevec_pool);
+fail_trunc_wq:
+	destroy_workqueue(client->trunc_wq);
+fail_pg_inv_wq:
+	destroy_workqueue(client->pg_inv_wq);
+fail_wb_wq:
+	destroy_workqueue(client->wb_wq);
+fail_bdi:
+	bdi_destroy(&client->backing_dev_info);
+fail:
+	kfree(client);
+	return ERR_PTR(err);
+}
+
+static void ceph_destroy_client(struct ceph_client *client)
+{
+	dout("destroy_client %p\n", client);
+
+	/* unmount */
+	ceph_mdsc_stop(&client->mdsc);
+	ceph_monc_stop(&client->monc);
+	ceph_osdc_stop(&client->osdc);
+
+	ceph_adjust_min_caps(-client->min_caps);
+
+	ceph_debugfs_client_cleanup(client);
+	destroy_workqueue(client->wb_wq);
+	destroy_workqueue(client->pg_inv_wq);
+	destroy_workqueue(client->trunc_wq);
+
+	bdi_destroy(&client->backing_dev_info);
+
+	if (client->msgr)
+		ceph_messenger_destroy(client->msgr);
+	mempool_destroy(client->wb_pagevec_pool);
+
+	destroy_mount_args(client->mount_args);
+
+	kfree(client);
+	dout("destroy_client %p done\n", client);
+}
+
+/*
+ * Initially learn our fsid, or verify an fsid matches.
+ */
+int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid)
+{
+	if (client->have_fsid) {
+		if (ceph_fsid_compare(&client->fsid, fsid)) {
+			pr_err("bad fsid, had " FSID_FORMAT " got " FSID_FORMAT,
+			       PR_FSID(&client->fsid), PR_FSID(fsid));
+			return -1;
+		}
+	} else {
+		pr_info("client%lld fsid " FSID_FORMAT "\n",
+			client->monc.auth->global_id, PR_FSID(fsid));
+		memcpy(&client->fsid, fsid, sizeof(*fsid));
+		ceph_debugfs_client_init(client);
+		client->have_fsid = true;
+	}
+	return 0;
+}
+
+/*
+ * true if we have the mon map (and have thus joined the cluster)
+ */
+static int have_mon_map(struct ceph_client *client)
+{
+	return client->monc.monmap && client->monc.monmap->epoch;
+}
+
+/*
+ * Bootstrap mount by opening the root directory.  Note the mount
+ * @started time from caller, and time out if this takes too long.
+ */
+static struct dentry *open_root_dentry(struct ceph_client *client,
+				       const char *path,
+				       unsigned long started)
+{
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct ceph_mds_request *req = NULL;
+	int err;
+	struct dentry *root;
+
+	/* open dir */
+	dout("open_root_inode opening '%s'\n", path);
+	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS);
+	if (IS_ERR(req))
+		return ERR_PTR(PTR_ERR(req));
+	req->r_path1 = kstrdup(path, GFP_NOFS);
+	req->r_ino1.ino = CEPH_INO_ROOT;
+	req->r_ino1.snap = CEPH_NOSNAP;
+	req->r_started = started;
+	req->r_timeout = client->mount_args->mount_timeout * HZ;
+	req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE);
+	req->r_num_caps = 2;
+	err = ceph_mdsc_do_request(mdsc, NULL, req);
+	if (err == 0) {
+		dout("open_root_inode success\n");
+		if (ceph_ino(req->r_target_inode) == CEPH_INO_ROOT &&
+		    client->sb->s_root == NULL)
+			root = d_alloc_root(req->r_target_inode);
+		else
+			root = d_obtain_alias(req->r_target_inode);
+		req->r_target_inode = NULL;
+		dout("open_root_inode success, root dentry is %p\n", root);
+	} else {
+		root = ERR_PTR(err);
+	}
+	ceph_mdsc_put_request(req);
+	return root;
+}
+
+/*
+ * mount: join the ceph cluster, and open root directory.
+ */
+static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt,
+		      const char *path)
+{
+	struct ceph_entity_addr *myaddr = NULL;
+	int err;
+	unsigned long timeout = client->mount_args->mount_timeout * HZ;
+	unsigned long started = jiffies;  /* note the start time */
+	struct dentry *root;
+
+	dout("mount start\n");
+	mutex_lock(&client->mount_mutex);
+
+	/* initialize the messenger */
+	if (client->msgr == NULL) {
+		if (ceph_test_opt(client, MYIP))
+			myaddr = &client->mount_args->my_addr;
+		client->msgr = ceph_messenger_create(myaddr);
+		if (IS_ERR(client->msgr)) {
+			err = PTR_ERR(client->msgr);
+			client->msgr = NULL;
+			goto out;
+		}
+		client->msgr->nocrc = ceph_test_opt(client, NOCRC);
+	}
+
+	/* open session, and wait for mon, mds, and osd maps */
+	err = ceph_monc_open_session(&client->monc);
+	if (err < 0)
+		goto out;
+
+	while (!have_mon_map(client)) {
+		err = -EIO;
+		if (timeout && time_after_eq(jiffies, started + timeout))
+			goto out;
+
+		/* wait */
+		dout("mount waiting for mon_map\n");
+		err = wait_event_interruptible_timeout(client->auth_wq,
+			       have_mon_map(client) || (client->auth_err < 0),
+			       timeout);
+		if (err == -EINTR || err == -ERESTARTSYS)
+			goto out;
+		if (client->auth_err < 0) {
+			err = client->auth_err;
+			goto out;
+		}
+	}
+
+	dout("mount opening root\n");
+	root = open_root_dentry(client, "", started);
+	if (IS_ERR(root)) {
+		err = PTR_ERR(root);
+		goto out;
+	}
+	if (client->sb->s_root)
+		dput(root);
+	else
+		client->sb->s_root = root;
+
+	if (path[0] == 0) {
+		dget(root);
+	} else {
+		dout("mount opening base mountpoint\n");
+		root = open_root_dentry(client, path, started);
+		if (IS_ERR(root)) {
+			err = PTR_ERR(root);
+			dput(client->sb->s_root);
+			client->sb->s_root = NULL;
+			goto out;
+		}
+	}
+
+	mnt->mnt_root = root;
+	mnt->mnt_sb = client->sb;
+
+	client->mount_state = CEPH_MOUNT_MOUNTED;
+	dout("mount success\n");
+	err = 0;
+
+out:
+	mutex_unlock(&client->mount_mutex);
+	return err;
+}
+
+static int ceph_set_super(struct super_block *s, void *data)
+{
+	struct ceph_client *client = data;
+	int ret;
+
+	dout("set_super %p data %p\n", s, data);
+
+	s->s_flags = client->mount_args->sb_flags;
+	s->s_maxbytes = 1ULL << 40;  /* temp value until we get mdsmap */
+
+	s->s_fs_info = client;
+	client->sb = s;
+
+	s->s_op = &ceph_super_ops;
+	s->s_export_op = &ceph_export_ops;
+
+	s->s_time_gran = 1000;  /* 1000 ns == 1 us */
+
+	ret = set_anon_super(s, NULL);  /* what is that second arg for? */
+	if (ret != 0)
+		goto fail;
+
+	return ret;
+
+fail:
+	s->s_fs_info = NULL;
+	client->sb = NULL;
+	return ret;
+}
+
+/*
+ * share superblock if same fs AND options
+ */
+static int ceph_compare_super(struct super_block *sb, void *data)
+{
+	struct ceph_client *new = data;
+	struct ceph_mount_args *args = new->mount_args;
+	struct ceph_client *other = ceph_sb_to_client(sb);
+	int i;
+
+	dout("ceph_compare_super %p\n", sb);
+	if (args->flags & CEPH_OPT_FSID) {
+		if (ceph_fsid_compare(&args->fsid, &other->fsid)) {
+			dout("fsid doesn't match\n");
+			return 0;
+		}
+	} else {
+		/* do we share (a) monitor? */
+		for (i = 0; i < new->monc.monmap->num_mon; i++)
+			if (ceph_monmap_contains(other->monc.monmap,
+					 &new->monc.monmap->mon_inst[i].addr))
+				break;
+		if (i == new->monc.monmap->num_mon) {
+			dout("mon ip not part of monmap\n");
+			return 0;
+		}
+		dout("mon ip matches existing sb %p\n", sb);
+	}
+	if (args->sb_flags != other->mount_args->sb_flags) {
+		dout("flags differ\n");
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * construct our own bdi so we can control readahead, etc.
+ */
+static int ceph_register_bdi(struct super_block *sb, struct ceph_client *client)
+{
+	int err;
+
+	/* set ra_pages based on rsize mount option? */
+	if (client->mount_args->rsize >= PAGE_CACHE_SIZE)
+		client->backing_dev_info.ra_pages =
+			(client->mount_args->rsize + PAGE_CACHE_SIZE - 1)
+			>> PAGE_SHIFT;
+	err = bdi_register_dev(&client->backing_dev_info, sb->s_dev);
+	if (!err)
+		sb->s_bdi = &client->backing_dev_info;
+	return err;
+}
+
+static int ceph_get_sb(struct file_system_type *fs_type,
+		       int flags, const char *dev_name, void *data,
+		       struct vfsmount *mnt)
+{
+	struct super_block *sb;
+	struct ceph_client *client;
+	int err;
+	int (*compare_super)(struct super_block *, void *) = ceph_compare_super;
+	const char *path = NULL;
+	struct ceph_mount_args *args;
+
+	dout("ceph_get_sb\n");
+	args = parse_mount_args(flags, data, dev_name, &path);
+	if (IS_ERR(args)) {
+		err = PTR_ERR(args);
+		goto out_final;
+	}
+
+	/* create client (which we may/may not use) */
+	client = ceph_create_client(args);
+	if (IS_ERR(client)) {
+		err = PTR_ERR(client);
+		goto out_final;
+	}
+
+	if (client->mount_args->flags & CEPH_OPT_NOSHARE)
+		compare_super = NULL;
+	sb = sget(fs_type, compare_super, ceph_set_super, client);
+	if (IS_ERR(sb)) {
+		err = PTR_ERR(sb);
+		goto out;
+	}
+
+	if (ceph_client(sb) != client) {
+		ceph_destroy_client(client);
+		client = ceph_client(sb);
+		dout("get_sb got existing client %p\n", client);
+	} else {
+		dout("get_sb using new client %p\n", client);
+		err = ceph_register_bdi(sb, client);
+		if (err < 0)
+			goto out_splat;
+	}
+
+	err = ceph_mount(client, mnt, path);
+	if (err < 0)
+		goto out_splat;
+	dout("root %p inode %p ino %llx.%llx\n", mnt->mnt_root,
+	     mnt->mnt_root->d_inode, ceph_vinop(mnt->mnt_root->d_inode));
+	return 0;
+
+out_splat:
+	ceph_mdsc_close_sessions(&client->mdsc);
+	up_write(&sb->s_umount);
+	deactivate_super(sb);
+	goto out_final;
+
+out:
+	ceph_destroy_client(client);
+out_final:
+	dout("ceph_get_sb fail %d\n", err);
+	return err;
+}
+
+static void ceph_kill_sb(struct super_block *s)
+{
+	struct ceph_client *client = ceph_sb_to_client(s);
+	dout("kill_sb %p\n", s);
+	ceph_mdsc_pre_umount(&client->mdsc);
+	kill_anon_super(s);    /* will call put_super after sb is r/o */
+	ceph_destroy_client(client);
+}
+
+static struct file_system_type ceph_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "ceph",
+	.get_sb		= ceph_get_sb,
+	.kill_sb	= ceph_kill_sb,
+	.fs_flags	= FS_RENAME_DOES_D_MOVE,
+};
+
+#define _STRINGIFY(x) #x
+#define STRINGIFY(x) _STRINGIFY(x)
+
+static int __init init_ceph(void)
+{
+	int ret = 0;
+
+	ret = ceph_debugfs_init();
+	if (ret < 0)
+		goto out;
+
+	ret = ceph_msgr_init();
+	if (ret < 0)
+		goto out_debugfs;
+
+	ret = init_caches();
+	if (ret)
+		goto out_msgr;
+
+	ceph_caps_init();
+
+	ret = register_filesystem(&ceph_fs_type);
+	if (ret)
+		goto out_icache;
+
+	pr_info("loaded (mon/mds/osd proto %d/%d/%d, osdmap %d/%d %d/%d)\n",
+		CEPH_MONC_PROTOCOL, CEPH_MDSC_PROTOCOL, CEPH_OSDC_PROTOCOL,
+		CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT,
+		CEPH_OSDMAP_INC_VERSION, CEPH_OSDMAP_INC_VERSION_EXT);
+	return 0;
+
+out_icache:
+	destroy_caches();
+out_msgr:
+	ceph_msgr_exit();
+out_debugfs:
+	ceph_debugfs_cleanup();
+out:
+	return ret;
+}
+
+static void __exit exit_ceph(void)
+{
+	dout("exit_ceph\n");
+	unregister_filesystem(&ceph_fs_type);
+	ceph_caps_finalize();
+	destroy_caches();
+	ceph_msgr_exit();
+	ceph_debugfs_cleanup();
+}
+
+module_init(init_ceph);
+module_exit(exit_ceph);
+
+MODULE_AUTHOR("Sage Weil <sage@newdream.net>");
+MODULE_AUTHOR("Yehuda Sadeh <yehuda@hq.newdream.net>");
+MODULE_AUTHOR("Patience Warnick <patience@newdream.net>");
+MODULE_DESCRIPTION("Ceph filesystem for Linux");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/super.h linux-libre-2.6.34-gnu1/fs/ceph/super.h
--- linux-libre-2.6.33-gnu1/fs/ceph/super.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/super.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,902 @@
+#ifndef _FS_CEPH_SUPER_H
+#define _FS_CEPH_SUPER_H
+
+#include "ceph_debug.h"
+
+#include <asm/unaligned.h>
+#include <linux/backing-dev.h>
+#include <linux/completion.h>
+#include <linux/exportfs.h>
+#include <linux/fs.h>
+#include <linux/mempool.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/writeback.h>
+#include <linux/slab.h>
+
+#include "types.h"
+#include "messenger.h"
+#include "msgpool.h"
+#include "mon_client.h"
+#include "mds_client.h"
+#include "osd_client.h"
+#include "ceph_fs.h"
+
+/* f_type in struct statfs */
+#define CEPH_SUPER_MAGIC 0x00c36400
+
+/* large granularity for statfs utilization stats to facilitate
+ * large volume sizes on 32-bit machines. */
+#define CEPH_BLOCK_SHIFT   20  /* 1 MB */
+#define CEPH_BLOCK         (1 << CEPH_BLOCK_SHIFT)
+
+/*
+ * mount options
+ */
+#define CEPH_OPT_FSID             (1<<0)
+#define CEPH_OPT_NOSHARE          (1<<1) /* don't share client with other sbs */
+#define CEPH_OPT_MYIP             (1<<2) /* specified my ip */
+#define CEPH_OPT_DIRSTAT          (1<<4) /* funky `cat dirname` for stats */
+#define CEPH_OPT_RBYTES           (1<<5) /* dir st_bytes = rbytes */
+#define CEPH_OPT_NOCRC            (1<<6) /* no data crc on writes */
+#define CEPH_OPT_NOASYNCREADDIR   (1<<7) /* no dcache readdir */
+
+#define CEPH_OPT_DEFAULT   (CEPH_OPT_RBYTES)
+
+#define ceph_set_opt(client, opt) \
+	(client)->mount_args->flags |= CEPH_OPT_##opt;
+#define ceph_test_opt(client, opt) \
+	(!!((client)->mount_args->flags & CEPH_OPT_##opt))
+
+
+struct ceph_mount_args {
+	int sb_flags;
+	int num_mon;
+	struct ceph_entity_addr *mon_addr;
+	int flags;
+	int mount_timeout;
+	int osd_idle_ttl;
+	int caps_wanted_delay_min, caps_wanted_delay_max;
+	struct ceph_fsid fsid;
+	struct ceph_entity_addr my_addr;
+	int wsize;
+	int rsize;            /* max readahead */
+	int max_readdir;      /* max readdir size */
+	int congestion_kb;      /* max readdir size */
+	int osd_timeout;
+	int osd_keepalive_timeout;
+	char *snapdir_name;   /* default ".snap" */
+	char *name;
+	char *secret;
+	int cap_release_safety;
+};
+
+/*
+ * defaults
+ */
+#define CEPH_MOUNT_TIMEOUT_DEFAULT  60
+#define CEPH_OSD_TIMEOUT_DEFAULT    60  /* seconds */
+#define CEPH_OSD_KEEPALIVE_DEFAULT  5
+#define CEPH_OSD_IDLE_TTL_DEFAULT    60
+#define CEPH_MOUNT_RSIZE_DEFAULT    (512*1024) /* readahead */
+
+#define CEPH_MSG_MAX_FRONT_LEN	(16*1024*1024)
+#define CEPH_MSG_MAX_DATA_LEN	(16*1024*1024)
+
+#define CEPH_SNAPDIRNAME_DEFAULT ".snap"
+#define CEPH_AUTH_NAME_DEFAULT   "guest"
+
+/*
+ * Delay telling the MDS we no longer want caps, in case we reopen
+ * the file.  Delay a minimum amount of time, even if we send a cap
+ * message for some other reason.  Otherwise, take the oppotunity to
+ * update the mds to avoid sending another message later.
+ */
+#define CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT      5  /* cap release delay */
+#define CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT     60  /* cap release delay */
+
+
+/* mount state */
+enum {
+	CEPH_MOUNT_MOUNTING,
+	CEPH_MOUNT_MOUNTED,
+	CEPH_MOUNT_UNMOUNTING,
+	CEPH_MOUNT_UNMOUNTED,
+	CEPH_MOUNT_SHUTDOWN,
+};
+
+/*
+ * subtract jiffies
+ */
+static inline unsigned long time_sub(unsigned long a, unsigned long b)
+{
+	BUG_ON(time_after(b, a));
+	return (long)a - (long)b;
+}
+
+/*
+ * per-filesystem client state
+ *
+ * possibly shared by multiple mount points, if they are
+ * mounting the same ceph filesystem/cluster.
+ */
+struct ceph_client {
+	struct ceph_fsid fsid;
+	bool have_fsid;
+
+	struct mutex mount_mutex;       /* serialize mount attempts */
+	struct ceph_mount_args *mount_args;
+
+	struct super_block *sb;
+
+	unsigned long mount_state;
+	wait_queue_head_t auth_wq;
+
+	int auth_err;
+
+	int min_caps;                  /* min caps i added */
+
+	struct ceph_messenger *msgr;   /* messenger instance */
+	struct ceph_mon_client monc;
+	struct ceph_mds_client mdsc;
+	struct ceph_osd_client osdc;
+
+	/* writeback */
+	mempool_t *wb_pagevec_pool;
+	struct workqueue_struct *wb_wq;
+	struct workqueue_struct *pg_inv_wq;
+	struct workqueue_struct *trunc_wq;
+	atomic_long_t writeback_count;
+
+	struct backing_dev_info backing_dev_info;
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs_monmap;
+	struct dentry *debugfs_mdsmap, *debugfs_osdmap;
+	struct dentry *debugfs_dir, *debugfs_dentry_lru, *debugfs_caps;
+	struct dentry *debugfs_congestion_kb;
+	struct dentry *debugfs_bdi;
+#endif
+};
+
+static inline struct ceph_client *ceph_client(struct super_block *sb)
+{
+	return sb->s_fs_info;
+}
+
+
+/*
+ * File i/o capability.  This tracks shared state with the metadata
+ * server that allows us to cache or writeback attributes or to read
+ * and write data.  For any given inode, we should have one or more
+ * capabilities, one issued by each metadata server, and our
+ * cumulative access is the OR of all issued capabilities.
+ *
+ * Each cap is referenced by the inode's i_caps rbtree and by per-mds
+ * session capability lists.
+ */
+struct ceph_cap {
+	struct ceph_inode_info *ci;
+	struct rb_node ci_node;          /* per-ci cap tree */
+	struct ceph_mds_session *session;
+	struct list_head session_caps;   /* per-session caplist */
+	int mds;
+	u64 cap_id;       /* unique cap id (mds provided) */
+	int issued;       /* latest, from the mds */
+	int implemented;  /* implemented superset of issued (for revocation) */
+	int mds_wanted;
+	u32 seq, issue_seq, mseq;
+	u32 cap_gen;      /* active/stale cycle */
+	unsigned long last_used;
+	struct list_head caps_item;
+};
+
+#define CHECK_CAPS_NODELAY    1  /* do not delay any further */
+#define CHECK_CAPS_AUTHONLY   2  /* only check auth cap */
+#define CHECK_CAPS_FLUSH      4  /* flush any dirty caps */
+
+/*
+ * Snapped cap state that is pending flush to mds.  When a snapshot occurs,
+ * we first complete any in-process sync writes and writeback any dirty
+ * data before flushing the snapped state (tracked here) back to the MDS.
+ */
+struct ceph_cap_snap {
+	atomic_t nref;
+	struct ceph_inode_info *ci;
+	struct list_head ci_item, flushing_item;
+
+	u64 follows, flush_tid;
+	int issued, dirty;
+	struct ceph_snap_context *context;
+
+	mode_t mode;
+	uid_t uid;
+	gid_t gid;
+
+	void *xattr_blob;
+	int xattr_len;
+	u64 xattr_version;
+
+	u64 size;
+	struct timespec mtime, atime, ctime;
+	u64 time_warp_seq;
+	int writing;   /* a sync write is still in progress */
+	int dirty_pages;     /* dirty pages awaiting writeback */
+};
+
+static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap)
+{
+	if (atomic_dec_and_test(&capsnap->nref))
+		kfree(capsnap);
+}
+
+/*
+ * The frag tree describes how a directory is fragmented, potentially across
+ * multiple metadata servers.  It is also used to indicate points where
+ * metadata authority is delegated, and whether/where metadata is replicated.
+ *
+ * A _leaf_ frag will be present in the i_fragtree IFF there is
+ * delegation info.  That is, if mds >= 0 || ndist > 0.
+ */
+#define CEPH_MAX_DIRFRAG_REP 4
+
+struct ceph_inode_frag {
+	struct rb_node node;
+
+	/* fragtree state */
+	u32 frag;
+	int split_by;         /* i.e. 2^(split_by) children */
+
+	/* delegation and replication info */
+	int mds;              /* -1 if same authority as parent */
+	int ndist;            /* >0 if replicated */
+	int dist[CEPH_MAX_DIRFRAG_REP];
+};
+
+/*
+ * We cache inode xattrs as an encoded blob until they are first used,
+ * at which point we parse them into an rbtree.
+ */
+struct ceph_inode_xattr {
+	struct rb_node node;
+
+	const char *name;
+	int name_len;
+	const char *val;
+	int val_len;
+	int dirty;
+
+	int should_free_name;
+	int should_free_val;
+};
+
+struct ceph_inode_xattrs_info {
+	/*
+	 * (still encoded) xattr blob. we avoid the overhead of parsing
+	 * this until someone actually calls getxattr, etc.
+	 *
+	 * blob->vec.iov_len == 4 implies there are no xattrs; blob ==
+	 * NULL means we don't know.
+	*/
+	struct ceph_buffer *blob, *prealloc_blob;
+
+	struct rb_root index;
+	bool dirty;
+	int count;
+	int names_size;
+	int vals_size;
+	u64 version, index_version;
+};
+
+/*
+ * Ceph inode.
+ */
+#define CEPH_I_COMPLETE  1  /* we have complete directory cached */
+#define CEPH_I_NODELAY   4  /* do not delay cap release */
+#define CEPH_I_FLUSH     8  /* do not delay flush of dirty metadata */
+#define CEPH_I_NOFLUSH  16  /* do not flush dirty caps */
+
+struct ceph_inode_info {
+	struct ceph_vino i_vino;   /* ceph ino + snap */
+
+	u64 i_version;
+	u32 i_time_warp_seq;
+
+	unsigned i_ceph_flags;
+	unsigned long i_release_count;
+
+	struct ceph_file_layout i_layout;
+	char *i_symlink;
+
+	/* for dirs */
+	struct timespec i_rctime;
+	u64 i_rbytes, i_rfiles, i_rsubdirs;
+	u64 i_files, i_subdirs;
+	u64 i_max_offset;  /* largest readdir offset, set with I_COMPLETE */
+
+	struct rb_root i_fragtree;
+	struct mutex i_fragtree_mutex;
+
+	struct ceph_inode_xattrs_info i_xattrs;
+
+	/* capabilities.  protected _both_ by i_lock and cap->session's
+	 * s_mutex. */
+	struct rb_root i_caps;           /* cap list */
+	struct ceph_cap *i_auth_cap;     /* authoritative cap, if any */
+	unsigned i_dirty_caps, i_flushing_caps;     /* mask of dirtied fields */
+	struct list_head i_dirty_item, i_flushing_item;
+	u64 i_cap_flush_seq;
+	/* we need to track cap writeback on a per-cap-bit basis, to allow
+	 * overlapping, pipelined cap flushes to the mds.  we can probably
+	 * reduce the tid to 8 bits if we're concerned about inode size. */
+	u16 i_cap_flush_last_tid, i_cap_flush_tid[CEPH_CAP_BITS];
+	wait_queue_head_t i_cap_wq;      /* threads waiting on a capability */
+	unsigned long i_hold_caps_min; /* jiffies */
+	unsigned long i_hold_caps_max; /* jiffies */
+	struct list_head i_cap_delay_list;  /* for delayed cap release to mds */
+	int i_cap_exporting_mds;         /* to handle cap migration between */
+	unsigned i_cap_exporting_mseq;   /*  mds's. */
+	unsigned i_cap_exporting_issued;
+	struct ceph_cap_reservation i_cap_migration_resv;
+	struct list_head i_cap_snaps;   /* snapped state pending flush to mds */
+	struct ceph_snap_context *i_head_snapc;  /* set if wr_buffer_head > 0 */
+	unsigned i_snap_caps;           /* cap bits for snapped files */
+
+	int i_nr_by_mode[CEPH_FILE_MODE_NUM];  /* open file counts */
+
+	u32 i_truncate_seq;        /* last truncate to smaller size */
+	u64 i_truncate_size;       /*  and the size we last truncated down to */
+	int i_truncate_pending;    /*  still need to call vmtruncate */
+
+	u64 i_max_size;            /* max file size authorized by mds */
+	u64 i_reported_size; /* (max_)size reported to or requested of mds */
+	u64 i_wanted_max_size;     /* offset we'd like to write too */
+	u64 i_requested_max_size;  /* max_size we've requested */
+
+	/* held references to caps */
+	int i_pin_ref;
+	int i_rd_ref, i_rdcache_ref, i_wr_ref;
+	int i_wrbuffer_ref, i_wrbuffer_ref_head;
+	u32 i_shared_gen;       /* increment each time we get FILE_SHARED */
+	u32 i_rdcache_gen;      /* we increment this each time we get
+				   FILE_CACHE.  If it's non-zero, we
+				   _may_ have cached pages. */
+	u32 i_rdcache_revoking; /* RDCACHE gen to async invalidate, if any */
+
+	struct list_head i_unsafe_writes; /* uncommitted sync writes */
+	struct list_head i_unsafe_dirops; /* uncommitted mds dir ops */
+	spinlock_t i_unsafe_lock;
+
+	struct ceph_snap_realm *i_snap_realm; /* snap realm (if caps) */
+	int i_snap_realm_counter; /* snap realm (if caps) */
+	struct list_head i_snap_realm_item;
+	struct list_head i_snap_flush_item;
+
+	struct work_struct i_wb_work;  /* writeback work */
+	struct work_struct i_pg_inv_work;  /* page invalidation work */
+
+	struct work_struct i_vmtruncate_work;
+
+	struct inode vfs_inode; /* at end */
+};
+
+static inline struct ceph_inode_info *ceph_inode(struct inode *inode)
+{
+	return container_of(inode, struct ceph_inode_info, vfs_inode);
+}
+
+static inline void ceph_i_clear(struct inode *inode, unsigned mask)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+
+	spin_lock(&inode->i_lock);
+	ci->i_ceph_flags &= ~mask;
+	spin_unlock(&inode->i_lock);
+}
+
+static inline void ceph_i_set(struct inode *inode, unsigned mask)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+
+	spin_lock(&inode->i_lock);
+	ci->i_ceph_flags |= mask;
+	spin_unlock(&inode->i_lock);
+}
+
+static inline bool ceph_i_test(struct inode *inode, unsigned mask)
+{
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	bool r;
+
+	smp_mb();
+	r = (ci->i_ceph_flags & mask) == mask;
+	return r;
+}
+
+
+/* find a specific frag @f */
+extern struct ceph_inode_frag *__ceph_find_frag(struct ceph_inode_info *ci,
+						u32 f);
+
+/*
+ * choose fragment for value @v.  copy frag content to pfrag, if leaf
+ * exists
+ */
+extern u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
+			    struct ceph_inode_frag *pfrag,
+			    int *found);
+
+/*
+ * Ceph dentry state
+ */
+struct ceph_dentry_info {
+	struct ceph_mds_session *lease_session;
+	u32 lease_gen, lease_shared_gen;
+	u32 lease_seq;
+	unsigned long lease_renew_after, lease_renew_from;
+	struct list_head lru;
+	struct dentry *dentry;
+	u64 time;
+	u64 offset;
+};
+
+static inline struct ceph_dentry_info *ceph_dentry(struct dentry *dentry)
+{
+	return (struct ceph_dentry_info *)dentry->d_fsdata;
+}
+
+static inline loff_t ceph_make_fpos(unsigned frag, unsigned off)
+{
+	return ((loff_t)frag << 32) | (loff_t)off;
+}
+
+/*
+ * ino_t is <64 bits on many architectures, blech.
+ *
+ * don't include snap in ino hash, at least for now.
+ */
+static inline ino_t ceph_vino_to_ino(struct ceph_vino vino)
+{
+	ino_t ino = (ino_t)vino.ino;  /* ^ (vino.snap << 20); */
+#if BITS_PER_LONG == 32
+	ino ^= vino.ino >> (sizeof(u64)-sizeof(ino_t)) * 8;
+	if (!ino)
+		ino = 1;
+#endif
+	return ino;
+}
+
+static inline int ceph_set_ino_cb(struct inode *inode, void *data)
+{
+	ceph_inode(inode)->i_vino = *(struct ceph_vino *)data;
+	inode->i_ino = ceph_vino_to_ino(*(struct ceph_vino *)data);
+	return 0;
+}
+
+static inline struct ceph_vino ceph_vino(struct inode *inode)
+{
+	return ceph_inode(inode)->i_vino;
+}
+
+/* for printf-style formatting */
+#define ceph_vinop(i) ceph_inode(i)->i_vino.ino, ceph_inode(i)->i_vino.snap
+
+static inline u64 ceph_ino(struct inode *inode)
+{
+	return ceph_inode(inode)->i_vino.ino;
+}
+static inline u64 ceph_snap(struct inode *inode)
+{
+	return ceph_inode(inode)->i_vino.snap;
+}
+
+static inline int ceph_ino_compare(struct inode *inode, void *data)
+{
+	struct ceph_vino *pvino = (struct ceph_vino *)data;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	return ci->i_vino.ino == pvino->ino &&
+		ci->i_vino.snap == pvino->snap;
+}
+
+static inline struct inode *ceph_find_inode(struct super_block *sb,
+					    struct ceph_vino vino)
+{
+	ino_t t = ceph_vino_to_ino(vino);
+	return ilookup5(sb, t, ceph_ino_compare, &vino);
+}
+
+
+/*
+ * caps helpers
+ */
+static inline bool __ceph_is_any_real_caps(struct ceph_inode_info *ci)
+{
+	return !RB_EMPTY_ROOT(&ci->i_caps);
+}
+
+extern int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented);
+extern int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int t);
+extern int __ceph_caps_issued_other(struct ceph_inode_info *ci,
+				    struct ceph_cap *cap);
+
+static inline int ceph_caps_issued(struct ceph_inode_info *ci)
+{
+	int issued;
+	spin_lock(&ci->vfs_inode.i_lock);
+	issued = __ceph_caps_issued(ci, NULL);
+	spin_unlock(&ci->vfs_inode.i_lock);
+	return issued;
+}
+
+static inline int ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask,
+					int touch)
+{
+	int r;
+	spin_lock(&ci->vfs_inode.i_lock);
+	r = __ceph_caps_issued_mask(ci, mask, touch);
+	spin_unlock(&ci->vfs_inode.i_lock);
+	return r;
+}
+
+static inline int __ceph_caps_dirty(struct ceph_inode_info *ci)
+{
+	return ci->i_dirty_caps | ci->i_flushing_caps;
+}
+extern void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask);
+
+extern int ceph_caps_revoking(struct ceph_inode_info *ci, int mask);
+extern int __ceph_caps_used(struct ceph_inode_info *ci);
+
+extern int __ceph_caps_file_wanted(struct ceph_inode_info *ci);
+
+/*
+ * wanted, by virtue of open file modes AND cap refs (buffered/cached data)
+ */
+static inline int __ceph_caps_wanted(struct ceph_inode_info *ci)
+{
+	int w = __ceph_caps_file_wanted(ci) | __ceph_caps_used(ci);
+	if (w & CEPH_CAP_FILE_BUFFER)
+		w |= CEPH_CAP_FILE_EXCL;  /* we want EXCL if dirty data */
+	return w;
+}
+
+/* what the mds thinks we want */
+extern int __ceph_caps_mds_wanted(struct ceph_inode_info *ci);
+
+extern void ceph_caps_init(void);
+extern void ceph_caps_finalize(void);
+extern void ceph_adjust_min_caps(int delta);
+extern int ceph_reserve_caps(struct ceph_cap_reservation *ctx, int need);
+extern int ceph_unreserve_caps(struct ceph_cap_reservation *ctx);
+extern void ceph_reservation_status(struct ceph_client *client,
+				    int *total, int *avail, int *used,
+				    int *reserved, int *min);
+
+static inline struct ceph_client *ceph_inode_to_client(struct inode *inode)
+{
+	return (struct ceph_client *)inode->i_sb->s_fs_info;
+}
+
+static inline struct ceph_client *ceph_sb_to_client(struct super_block *sb)
+{
+	return (struct ceph_client *)sb->s_fs_info;
+}
+
+
+/*
+ * we keep buffered readdir results attached to file->private_data
+ */
+struct ceph_file_info {
+	int fmode;     /* initialized on open */
+
+	/* readdir: position within the dir */
+	u32 frag;
+	struct ceph_mds_request *last_readdir;
+	int at_end;
+
+	/* readdir: position within a frag */
+	unsigned offset;       /* offset of last chunk, adjusted for . and .. */
+	u64 next_offset;       /* offset of next chunk (last_name's + 1) */
+	char *last_name;       /* last entry in previous chunk */
+	struct dentry *dentry; /* next dentry (for dcache readdir) */
+	unsigned long dir_release_count;
+
+	/* used for -o dirstat read() on directory thing */
+	char *dir_info;
+	int dir_info_len;
+};
+
+
+
+/*
+ * snapshots
+ */
+
+/*
+ * A "snap context" is the set of existing snapshots when we
+ * write data.  It is used by the OSD to guide its COW behavior.
+ *
+ * The ceph_snap_context is refcounted, and attached to each dirty
+ * page, indicating which context the dirty data belonged when it was
+ * dirtied.
+ */
+struct ceph_snap_context {
+	atomic_t nref;
+	u64 seq;
+	int num_snaps;
+	u64 snaps[];
+};
+
+static inline struct ceph_snap_context *
+ceph_get_snap_context(struct ceph_snap_context *sc)
+{
+	/*
+	printk("get_snap_context %p %d -> %d\n", sc, atomic_read(&sc->nref),
+	       atomic_read(&sc->nref)+1);
+	*/
+	if (sc)
+		atomic_inc(&sc->nref);
+	return sc;
+}
+
+static inline void ceph_put_snap_context(struct ceph_snap_context *sc)
+{
+	if (!sc)
+		return;
+	/*
+	printk("put_snap_context %p %d -> %d\n", sc, atomic_read(&sc->nref),
+	       atomic_read(&sc->nref)-1);
+	*/
+	if (atomic_dec_and_test(&sc->nref)) {
+		/*printk(" deleting snap_context %p\n", sc);*/
+		kfree(sc);
+	}
+}
+
+/*
+ * A "snap realm" describes a subset of the file hierarchy sharing
+ * the same set of snapshots that apply to it.  The realms themselves
+ * are organized into a hierarchy, such that children inherit (some of)
+ * the snapshots of their parents.
+ *
+ * All inodes within the realm that have capabilities are linked into a
+ * per-realm list.
+ */
+struct ceph_snap_realm {
+	u64 ino;
+	atomic_t nref;
+	struct rb_node node;
+
+	u64 created, seq;
+	u64 parent_ino;
+	u64 parent_since;   /* snapid when our current parent became so */
+
+	u64 *prior_parent_snaps;      /* snaps inherited from any parents we */
+	int num_prior_parent_snaps;   /*  had prior to parent_since */
+	u64 *snaps;                   /* snaps specific to this realm */
+	int num_snaps;
+
+	struct ceph_snap_realm *parent;
+	struct list_head children;       /* list of child realms */
+	struct list_head child_item;
+
+	struct list_head empty_item;     /* if i have ref==0 */
+
+	/* the current set of snaps for this realm */
+	struct ceph_snap_context *cached_context;
+
+	struct list_head inodes_with_caps;
+	spinlock_t inodes_with_caps_lock;
+};
+
+
+
+/*
+ * calculate the number of pages a given length and offset map onto,
+ * if we align the data.
+ */
+static inline int calc_pages_for(u64 off, u64 len)
+{
+	return ((off+len+PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT) -
+		(off >> PAGE_CACHE_SHIFT);
+}
+
+
+
+/* snap.c */
+struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc,
+					       u64 ino);
+extern void ceph_get_snap_realm(struct ceph_mds_client *mdsc,
+				struct ceph_snap_realm *realm);
+extern void ceph_put_snap_realm(struct ceph_mds_client *mdsc,
+				struct ceph_snap_realm *realm);
+extern int ceph_update_snap_trace(struct ceph_mds_client *m,
+				  void *p, void *e, bool deletion);
+extern void ceph_handle_snap(struct ceph_mds_client *mdsc,
+			     struct ceph_mds_session *session,
+			     struct ceph_msg *msg);
+extern void ceph_queue_cap_snap(struct ceph_inode_info *ci);
+extern int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
+				  struct ceph_cap_snap *capsnap);
+extern void ceph_cleanup_empty_realms(struct ceph_mds_client *mdsc);
+
+/*
+ * a cap_snap is "pending" if it is still awaiting an in-progress
+ * sync write (that may/may not still update size, mtime, etc.).
+ */
+static inline bool __ceph_have_pending_cap_snap(struct ceph_inode_info *ci)
+{
+	return !list_empty(&ci->i_cap_snaps) &&
+		list_entry(ci->i_cap_snaps.prev, struct ceph_cap_snap,
+			   ci_item)->writing;
+}
+
+
+/* super.c */
+extern struct kmem_cache *ceph_inode_cachep;
+extern struct kmem_cache *ceph_cap_cachep;
+extern struct kmem_cache *ceph_dentry_cachep;
+extern struct kmem_cache *ceph_file_cachep;
+
+extern const char *ceph_msg_type_name(int type);
+extern int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid);
+
+#define FSID_FORMAT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" \
+	"%02x%02x%02x%02x%02x%02x"
+#define PR_FSID(f) (f)->fsid[0], (f)->fsid[1], (f)->fsid[2], (f)->fsid[3], \
+		(f)->fsid[4], (f)->fsid[5], (f)->fsid[6], (f)->fsid[7],    \
+		(f)->fsid[8], (f)->fsid[9], (f)->fsid[10], (f)->fsid[11],  \
+		(f)->fsid[12], (f)->fsid[13], (f)->fsid[14], (f)->fsid[15]
+
+/* inode.c */
+extern const struct inode_operations ceph_file_iops;
+
+extern struct inode *ceph_alloc_inode(struct super_block *sb);
+extern void ceph_destroy_inode(struct inode *inode);
+
+extern struct inode *ceph_get_inode(struct super_block *sb,
+				    struct ceph_vino vino);
+extern struct inode *ceph_get_snapdir(struct inode *parent);
+extern int ceph_fill_file_size(struct inode *inode, int issued,
+			       u32 truncate_seq, u64 truncate_size, u64 size);
+extern void ceph_fill_file_time(struct inode *inode, int issued,
+				u64 time_warp_seq, struct timespec *ctime,
+				struct timespec *mtime, struct timespec *atime);
+extern int ceph_fill_trace(struct super_block *sb,
+			   struct ceph_mds_request *req,
+			   struct ceph_mds_session *session);
+extern int ceph_readdir_prepopulate(struct ceph_mds_request *req,
+				    struct ceph_mds_session *session);
+
+extern int ceph_inode_holds_cap(struct inode *inode, int mask);
+
+extern int ceph_inode_set_size(struct inode *inode, loff_t size);
+extern void __ceph_do_pending_vmtruncate(struct inode *inode);
+extern void ceph_queue_vmtruncate(struct inode *inode);
+
+extern void ceph_queue_invalidate(struct inode *inode);
+extern void ceph_queue_writeback(struct inode *inode);
+
+extern int ceph_do_getattr(struct inode *inode, int mask);
+extern int ceph_permission(struct inode *inode, int mask);
+extern int ceph_setattr(struct dentry *dentry, struct iattr *attr);
+extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry,
+			struct kstat *stat);
+
+/* xattr.c */
+extern int ceph_setxattr(struct dentry *, const char *, const void *,
+			 size_t, int);
+extern ssize_t ceph_getxattr(struct dentry *, const char *, void *, size_t);
+extern ssize_t ceph_listxattr(struct dentry *, char *, size_t);
+extern int ceph_removexattr(struct dentry *, const char *);
+extern void __ceph_build_xattrs_blob(struct ceph_inode_info *ci);
+extern void __ceph_destroy_xattrs(struct ceph_inode_info *ci);
+
+/* caps.c */
+extern const char *ceph_cap_string(int c);
+extern void ceph_handle_caps(struct ceph_mds_session *session,
+			     struct ceph_msg *msg);
+extern int ceph_add_cap(struct inode *inode,
+			struct ceph_mds_session *session, u64 cap_id,
+			int fmode, unsigned issued, unsigned wanted,
+			unsigned cap, unsigned seq, u64 realmino, int flags,
+			struct ceph_cap_reservation *caps_reservation);
+extern void __ceph_remove_cap(struct ceph_cap *cap);
+static inline void ceph_remove_cap(struct ceph_cap *cap)
+{
+	struct inode *inode = &cap->ci->vfs_inode;
+	spin_lock(&inode->i_lock);
+	__ceph_remove_cap(cap);
+	spin_unlock(&inode->i_lock);
+}
+extern void ceph_put_cap(struct ceph_cap *cap);
+
+extern void ceph_queue_caps_release(struct inode *inode);
+extern int ceph_write_inode(struct inode *inode, struct writeback_control *wbc);
+extern int ceph_fsync(struct file *file, struct dentry *dentry, int datasync);
+extern void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
+				    struct ceph_mds_session *session);
+extern int ceph_get_cap_mds(struct inode *inode);
+extern void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps);
+extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had);
+extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
+				       struct ceph_snap_context *snapc);
+extern void __ceph_flush_snaps(struct ceph_inode_info *ci,
+			       struct ceph_mds_session **psession);
+extern void ceph_check_caps(struct ceph_inode_info *ci, int flags,
+			    struct ceph_mds_session *session);
+extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc);
+extern void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc);
+
+extern int ceph_encode_inode_release(void **p, struct inode *inode,
+				     int mds, int drop, int unless, int force);
+extern int ceph_encode_dentry_release(void **p, struct dentry *dn,
+				      int mds, int drop, int unless);
+
+extern int ceph_get_caps(struct ceph_inode_info *ci, int need, int want,
+			 int *got, loff_t endoff);
+
+/* for counting open files by mode */
+static inline void __ceph_get_fmode(struct ceph_inode_info *ci, int mode)
+{
+	ci->i_nr_by_mode[mode]++;
+}
+extern void ceph_put_fmode(struct ceph_inode_info *ci, int mode);
+
+/* addr.c */
+extern const struct address_space_operations ceph_aops;
+extern int ceph_mmap(struct file *file, struct vm_area_struct *vma);
+
+/* file.c */
+extern const struct file_operations ceph_file_fops;
+extern const struct address_space_operations ceph_aops;
+extern int ceph_open(struct inode *inode, struct file *file);
+extern struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
+				       struct nameidata *nd, int mode,
+				       int locked_dir);
+extern int ceph_release(struct inode *inode, struct file *filp);
+extern void ceph_release_page_vector(struct page **pages, int num_pages);
+
+/* dir.c */
+extern const struct file_operations ceph_dir_fops;
+extern const struct inode_operations ceph_dir_iops;
+extern struct dentry_operations ceph_dentry_ops, ceph_snap_dentry_ops,
+	ceph_snapdir_dentry_ops;
+
+extern int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry);
+extern struct dentry *ceph_finish_lookup(struct ceph_mds_request *req,
+					 struct dentry *dentry, int err);
+
+extern void ceph_dentry_lru_add(struct dentry *dn);
+extern void ceph_dentry_lru_touch(struct dentry *dn);
+extern void ceph_dentry_lru_del(struct dentry *dn);
+
+/*
+ * our d_ops vary depending on whether the inode is live,
+ * snapshotted (read-only), or a virtual ".snap" directory.
+ */
+int ceph_init_dentry(struct dentry *dentry);
+
+
+/* ioctl.c */
+extern long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+
+/* export.c */
+extern const struct export_operations ceph_export_ops;
+
+/* debugfs.c */
+extern int ceph_debugfs_init(void);
+extern void ceph_debugfs_cleanup(void);
+extern int ceph_debugfs_client_init(struct ceph_client *client);
+extern void ceph_debugfs_client_cleanup(struct ceph_client *client);
+
+static inline struct inode *get_dentry_parent_inode(struct dentry *dentry)
+{
+	if (dentry && dentry->d_parent)
+		return dentry->d_parent->d_inode;
+
+	return NULL;
+}
+
+#endif /* _FS_CEPH_SUPER_H */
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/types.h linux-libre-2.6.34-gnu1/fs/ceph/types.h
--- linux-libre-2.6.33-gnu1/fs/ceph/types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/types.h	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,29 @@
+#ifndef _FS_CEPH_TYPES_H
+#define _FS_CEPH_TYPES_H
+
+/* needed before including ceph_fs.h */
+#include <linux/in.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/string.h>
+
+#include "ceph_fs.h"
+#include "ceph_frag.h"
+#include "ceph_hash.h"
+
+/*
+ * Identify inodes by both their ino AND snapshot id (a u64).
+ */
+struct ceph_vino {
+	u64 ino;
+	u64 snap;
+};
+
+
+/* context for the caps reservation mechanism */
+struct ceph_cap_reservation {
+	int count;
+};
+
+
+#endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ceph/xattr.c linux-libre-2.6.34-gnu1/fs/ceph/xattr.c
--- linux-libre-2.6.33-gnu1/fs/ceph/xattr.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ceph/xattr.c	2010-05-16 17:17:36.000000000 -0400
@@ -0,0 +1,845 @@
+#include "ceph_debug.h"
+#include "super.h"
+#include "decode.h"
+
+#include <linux/xattr.h>
+#include <linux/slab.h>
+
+static bool ceph_is_valid_xattr(const char *name)
+{
+	return !strncmp(name, XATTR_SECURITY_PREFIX,
+			XATTR_SECURITY_PREFIX_LEN) ||
+	       !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) ||
+	       !strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
+}
+
+/*
+ * These define virtual xattrs exposing the recursive directory
+ * statistics and layout metadata.
+ */
+struct ceph_vxattr_cb {
+	bool readonly;
+	char *name;
+	size_t (*getxattr_cb)(struct ceph_inode_info *ci, char *val,
+			      size_t size);
+};
+
+/* directories */
+
+static size_t ceph_vxattrcb_entries(struct ceph_inode_info *ci, char *val,
+					size_t size)
+{
+	return snprintf(val, size, "%lld", ci->i_files + ci->i_subdirs);
+}
+
+static size_t ceph_vxattrcb_files(struct ceph_inode_info *ci, char *val,
+				      size_t size)
+{
+	return snprintf(val, size, "%lld", ci->i_files);
+}
+
+static size_t ceph_vxattrcb_subdirs(struct ceph_inode_info *ci, char *val,
+					size_t size)
+{
+	return snprintf(val, size, "%lld", ci->i_subdirs);
+}
+
+static size_t ceph_vxattrcb_rentries(struct ceph_inode_info *ci, char *val,
+					 size_t size)
+{
+	return snprintf(val, size, "%lld", ci->i_rfiles + ci->i_rsubdirs);
+}
+
+static size_t ceph_vxattrcb_rfiles(struct ceph_inode_info *ci, char *val,
+				       size_t size)
+{
+	return snprintf(val, size, "%lld", ci->i_rfiles);
+}
+
+static size_t ceph_vxattrcb_rsubdirs(struct ceph_inode_info *ci, char *val,
+					 size_t size)
+{
+	return snprintf(val, size, "%lld", ci->i_rsubdirs);
+}
+
+static size_t ceph_vxattrcb_rbytes(struct ceph_inode_info *ci, char *val,
+				       size_t size)
+{
+	return snprintf(val, size, "%lld", ci->i_rbytes);
+}
+
+static size_t ceph_vxattrcb_rctime(struct ceph_inode_info *ci, char *val,
+				       size_t size)
+{
+	return snprintf(val, size, "%ld.%ld", (long)ci->i_rctime.tv_sec,
+			(long)ci->i_rctime.tv_nsec);
+}
+
+static struct ceph_vxattr_cb ceph_dir_vxattrs[] = {
+	{ true, "user.ceph.dir.entries", ceph_vxattrcb_entries},
+	{ true, "user.ceph.dir.files", ceph_vxattrcb_files},
+	{ true, "user.ceph.dir.subdirs", ceph_vxattrcb_subdirs},
+	{ true, "user.ceph.dir.rentries", ceph_vxattrcb_rentries},
+	{ true, "user.ceph.dir.rfiles", ceph_vxattrcb_rfiles},
+	{ true, "user.ceph.dir.rsubdirs", ceph_vxattrcb_rsubdirs},
+	{ true, "user.ceph.dir.rbytes", ceph_vxattrcb_rbytes},
+	{ true, "user.ceph.dir.rctime", ceph_vxattrcb_rctime},
+	{ true, NULL, NULL }
+};
+
+/* files */
+
+static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val,
+				   size_t size)
+{
+	int ret;
+
+	ret = snprintf(val, size,
+		"chunk_bytes=%lld\nstripe_count=%lld\nobject_size=%lld\n",
+		(unsigned long long)ceph_file_layout_su(ci->i_layout),
+		(unsigned long long)ceph_file_layout_stripe_count(ci->i_layout),
+		(unsigned long long)ceph_file_layout_object_size(ci->i_layout));
+	if (ceph_file_layout_pg_preferred(ci->i_layout))
+		ret += snprintf(val + ret, size, "preferred_osd=%lld\n",
+			    (unsigned long long)ceph_file_layout_pg_preferred(
+				    ci->i_layout));
+	return ret;
+}
+
+static struct ceph_vxattr_cb ceph_file_vxattrs[] = {
+	{ true, "user.ceph.layout", ceph_vxattrcb_layout},
+	{ NULL, NULL }
+};
+
+static struct ceph_vxattr_cb *ceph_inode_vxattrs(struct inode *inode)
+{
+	if (S_ISDIR(inode->i_mode))
+		return ceph_dir_vxattrs;
+	else if (S_ISREG(inode->i_mode))
+		return ceph_file_vxattrs;
+	return NULL;
+}
+
+static struct ceph_vxattr_cb *ceph_match_vxattr(struct ceph_vxattr_cb *vxattr,
+						const char *name)
+{
+	do {
+		if (strcmp(vxattr->name, name) == 0)
+			return vxattr;
+		vxattr++;
+	} while (vxattr->name);
+	return NULL;
+}
+
+static int __set_xattr(struct ceph_inode_info *ci,
+			   const char *name, int name_len,
+			   const char *val, int val_len,
+			   int dirty,
+			   int should_free_name, int should_free_val,
+			   struct ceph_inode_xattr **newxattr)
+{
+	struct rb_node **p;
+	struct rb_node *parent = NULL;
+	struct ceph_inode_xattr *xattr = NULL;
+	int c;
+	int new = 0;
+
+	p = &ci->i_xattrs.index.rb_node;
+	while (*p) {
+		parent = *p;
+		xattr = rb_entry(parent, struct ceph_inode_xattr, node);
+		c = strncmp(name, xattr->name, min(name_len, xattr->name_len));
+		if (c < 0)
+			p = &(*p)->rb_left;
+		else if (c > 0)
+			p = &(*p)->rb_right;
+		else {
+			if (name_len == xattr->name_len)
+				break;
+			else if (name_len < xattr->name_len)
+				p = &(*p)->rb_left;
+			else
+				p = &(*p)->rb_right;
+		}
+		xattr = NULL;
+	}
+
+	if (!xattr) {
+		new = 1;
+		xattr = *newxattr;
+		xattr->name = name;
+		xattr->name_len = name_len;
+		xattr->should_free_name = should_free_name;
+
+		ci->i_xattrs.count++;
+		dout("__set_xattr count=%d\n", ci->i_xattrs.count);
+	} else {
+		kfree(*newxattr);
+		*newxattr = NULL;
+		if (xattr->should_free_val)
+			kfree((void *)xattr->val);
+
+		if (should_free_name) {
+			kfree((void *)name);
+			name = xattr->name;
+		}
+		ci->i_xattrs.names_size -= xattr->name_len;
+		ci->i_xattrs.vals_size -= xattr->val_len;
+	}
+	if (!xattr) {
+		pr_err("__set_xattr ENOMEM on %p %llx.%llx xattr %s=%s\n",
+		       &ci->vfs_inode, ceph_vinop(&ci->vfs_inode), name,
+		       xattr->val);
+		return -ENOMEM;
+	}
+	ci->i_xattrs.names_size += name_len;
+	ci->i_xattrs.vals_size += val_len;
+	if (val)
+		xattr->val = val;
+	else
+		xattr->val = "";
+
+	xattr->val_len = val_len;
+	xattr->dirty = dirty;
+	xattr->should_free_val = (val && should_free_val);
+
+	if (new) {
+		rb_link_node(&xattr->node, parent, p);
+		rb_insert_color(&xattr->node, &ci->i_xattrs.index);
+		dout("__set_xattr_val p=%p\n", p);
+	}
+
+	dout("__set_xattr_val added %llx.%llx xattr %p %s=%.*s\n",
+	     ceph_vinop(&ci->vfs_inode), xattr, name, val_len, val);
+
+	return 0;
+}
+
+static struct ceph_inode_xattr *__get_xattr(struct ceph_inode_info *ci,
+			   const char *name)
+{
+	struct rb_node **p;
+	struct rb_node *parent = NULL;
+	struct ceph_inode_xattr *xattr = NULL;
+	int c;
+
+	p = &ci->i_xattrs.index.rb_node;
+	while (*p) {
+		parent = *p;
+		xattr = rb_entry(parent, struct ceph_inode_xattr, node);
+		c = strncmp(name, xattr->name, xattr->name_len);
+		if (c < 0)
+			p = &(*p)->rb_left;
+		else if (c > 0)
+			p = &(*p)->rb_right;
+		else {
+			dout("__get_xattr %s: found %.*s\n", name,
+			     xattr->val_len, xattr->val);
+			return xattr;
+		}
+	}
+
+	dout("__get_xattr %s: not found\n", name);
+
+	return NULL;
+}
+
+static void __free_xattr(struct ceph_inode_xattr *xattr)
+{
+	BUG_ON(!xattr);
+
+	if (xattr->should_free_name)
+		kfree((void *)xattr->name);
+	if (xattr->should_free_val)
+		kfree((void *)xattr->val);
+
+	kfree(xattr);
+}
+
+static int __remove_xattr(struct ceph_inode_info *ci,
+			  struct ceph_inode_xattr *xattr)
+{
+	if (!xattr)
+		return -EOPNOTSUPP;
+
+	rb_erase(&xattr->node, &ci->i_xattrs.index);
+
+	if (xattr->should_free_name)
+		kfree((void *)xattr->name);
+	if (xattr->should_free_val)
+		kfree((void *)xattr->val);
+
+	ci->i_xattrs.names_size -= xattr->name_len;
+	ci->i_xattrs.vals_size -= xattr->val_len;
+	ci->i_xattrs.count--;
+	kfree(xattr);
+
+	return 0;
+}
+
+static int __remove_xattr_by_name(struct ceph_inode_info *ci,
+			   const char *name)
+{
+	struct rb_node **p;
+	struct ceph_inode_xattr *xattr;
+	int err;
+
+	p = &ci->i_xattrs.index.rb_node;
+	xattr = __get_xattr(ci, name);
+	err = __remove_xattr(ci, xattr);
+	return err;
+}
+
+static char *__copy_xattr_names(struct ceph_inode_info *ci,
+				char *dest)
+{
+	struct rb_node *p;
+	struct ceph_inode_xattr *xattr = NULL;
+
+	p = rb_first(&ci->i_xattrs.index);
+	dout("__copy_xattr_names count=%d\n", ci->i_xattrs.count);
+
+	while (p) {
+		xattr = rb_entry(p, struct ceph_inode_xattr, node);
+		memcpy(dest, xattr->name, xattr->name_len);
+		dest[xattr->name_len] = '\0';
+
+		dout("dest=%s %p (%s) (%d/%d)\n", dest, xattr, xattr->name,
+		     xattr->name_len, ci->i_xattrs.names_size);
+
+		dest += xattr->name_len + 1;
+		p = rb_next(p);
+	}
+
+	return dest;
+}
+
+void __ceph_destroy_xattrs(struct ceph_inode_info *ci)
+{
+	struct rb_node *p, *tmp;
+	struct ceph_inode_xattr *xattr = NULL;
+
+	p = rb_first(&ci->i_xattrs.index);
+
+	dout("__ceph_destroy_xattrs p=%p\n", p);
+
+	while (p) {
+		xattr = rb_entry(p, struct ceph_inode_xattr, node);
+		tmp = p;
+		p = rb_next(tmp);
+		dout("__ceph_destroy_xattrs next p=%p (%.*s)\n", p,
+		     xattr->name_len, xattr->name);
+		rb_erase(tmp, &ci->i_xattrs.index);
+
+		__free_xattr(xattr);
+	}
+
+	ci->i_xattrs.names_size = 0;
+	ci->i_xattrs.vals_size = 0;
+	ci->i_xattrs.index_version = 0;
+	ci->i_xattrs.count = 0;
+	ci->i_xattrs.index = RB_ROOT;
+}
+
+static int __build_xattrs(struct inode *inode)
+{
+	u32 namelen;
+	u32 numattr = 0;
+	void *p, *end;
+	u32 len;
+	const char *name, *val;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	int xattr_version;
+	struct ceph_inode_xattr **xattrs = NULL;
+	int err = 0;
+	int i;
+
+	dout("__build_xattrs() len=%d\n",
+	     ci->i_xattrs.blob ? (int)ci->i_xattrs.blob->vec.iov_len : 0);
+
+	if (ci->i_xattrs.index_version >= ci->i_xattrs.version)
+		return 0; /* already built */
+
+	__ceph_destroy_xattrs(ci);
+
+start:
+	/* updated internal xattr rb tree */
+	if (ci->i_xattrs.blob && ci->i_xattrs.blob->vec.iov_len > 4) {
+		p = ci->i_xattrs.blob->vec.iov_base;
+		end = p + ci->i_xattrs.blob->vec.iov_len;
+		ceph_decode_32_safe(&p, end, numattr, bad);
+		xattr_version = ci->i_xattrs.version;
+		spin_unlock(&inode->i_lock);
+
+		xattrs = kcalloc(numattr, sizeof(struct ceph_xattr *),
+				 GFP_NOFS);
+		err = -ENOMEM;
+		if (!xattrs)
+			goto bad_lock;
+		memset(xattrs, 0, numattr*sizeof(struct ceph_xattr *));
+		for (i = 0; i < numattr; i++) {
+			xattrs[i] = kmalloc(sizeof(struct ceph_inode_xattr),
+					    GFP_NOFS);
+			if (!xattrs[i])
+				goto bad_lock;
+		}
+
+		spin_lock(&inode->i_lock);
+		if (ci->i_xattrs.version != xattr_version) {
+			/* lost a race, retry */
+			for (i = 0; i < numattr; i++)
+				kfree(xattrs[i]);
+			kfree(xattrs);
+			goto start;
+		}
+		err = -EIO;
+		while (numattr--) {
+			ceph_decode_32_safe(&p, end, len, bad);
+			namelen = len;
+			name = p;
+			p += len;
+			ceph_decode_32_safe(&p, end, len, bad);
+			val = p;
+			p += len;
+
+			err = __set_xattr(ci, name, namelen, val, len,
+					  0, 0, 0, &xattrs[numattr]);
+
+			if (err < 0)
+				goto bad;
+		}
+		kfree(xattrs);
+	}
+	ci->i_xattrs.index_version = ci->i_xattrs.version;
+	ci->i_xattrs.dirty = false;
+
+	return err;
+bad_lock:
+	spin_lock(&inode->i_lock);
+bad:
+	if (xattrs) {
+		for (i = 0; i < numattr; i++)
+			kfree(xattrs[i]);
+		kfree(xattrs);
+	}
+	ci->i_xattrs.names_size = 0;
+	return err;
+}
+
+static int __get_required_blob_size(struct ceph_inode_info *ci, int name_size,
+				    int val_size)
+{
+	/*
+	 * 4 bytes for the length, and additional 4 bytes per each xattr name,
+	 * 4 bytes per each value
+	 */
+	int size = 4 + ci->i_xattrs.count*(4 + 4) +
+			     ci->i_xattrs.names_size +
+			     ci->i_xattrs.vals_size;
+	dout("__get_required_blob_size c=%d names.size=%d vals.size=%d\n",
+	     ci->i_xattrs.count, ci->i_xattrs.names_size,
+	     ci->i_xattrs.vals_size);
+
+	if (name_size)
+		size += 4 + 4 + name_size + val_size;
+
+	return size;
+}
+
+/*
+ * If there are dirty xattrs, reencode xattrs into the prealloc_blob
+ * and swap into place.
+ */
+void __ceph_build_xattrs_blob(struct ceph_inode_info *ci)
+{
+	struct rb_node *p;
+	struct ceph_inode_xattr *xattr = NULL;
+	void *dest;
+
+	dout("__build_xattrs_blob %p\n", &ci->vfs_inode);
+	if (ci->i_xattrs.dirty) {
+		int need = __get_required_blob_size(ci, 0, 0);
+
+		BUG_ON(need > ci->i_xattrs.prealloc_blob->alloc_len);
+
+		p = rb_first(&ci->i_xattrs.index);
+		dest = ci->i_xattrs.prealloc_blob->vec.iov_base;
+
+		ceph_encode_32(&dest, ci->i_xattrs.count);
+		while (p) {
+			xattr = rb_entry(p, struct ceph_inode_xattr, node);
+
+			ceph_encode_32(&dest, xattr->name_len);
+			memcpy(dest, xattr->name, xattr->name_len);
+			dest += xattr->name_len;
+			ceph_encode_32(&dest, xattr->val_len);
+			memcpy(dest, xattr->val, xattr->val_len);
+			dest += xattr->val_len;
+
+			p = rb_next(p);
+		}
+
+		/* adjust buffer len; it may be larger than we need */
+		ci->i_xattrs.prealloc_blob->vec.iov_len =
+			dest - ci->i_xattrs.prealloc_blob->vec.iov_base;
+
+		if (ci->i_xattrs.blob)
+			ceph_buffer_put(ci->i_xattrs.blob);
+		ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob;
+		ci->i_xattrs.prealloc_blob = NULL;
+		ci->i_xattrs.dirty = false;
+	}
+}
+
+ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value,
+		      size_t size)
+{
+	struct inode *inode = dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
+	int err;
+	struct ceph_inode_xattr *xattr;
+	struct ceph_vxattr_cb *vxattr = NULL;
+
+	if (!ceph_is_valid_xattr(name))
+		return -ENODATA;
+
+	/* let's see if a virtual xattr was requested */
+	if (vxattrs)
+		vxattr = ceph_match_vxattr(vxattrs, name);
+
+	spin_lock(&inode->i_lock);
+	dout("getxattr %p ver=%lld index_ver=%lld\n", inode,
+	     ci->i_xattrs.version, ci->i_xattrs.index_version);
+
+	if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) &&
+	    (ci->i_xattrs.index_version >= ci->i_xattrs.version)) {
+		goto get_xattr;
+	} else {
+		spin_unlock(&inode->i_lock);
+		/* get xattrs from mds (if we don't already have them) */
+		err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR);
+		if (err)
+			return err;
+	}
+
+	spin_lock(&inode->i_lock);
+
+	if (vxattr && vxattr->readonly) {
+		err = vxattr->getxattr_cb(ci, value, size);
+		goto out;
+	}
+
+	err = __build_xattrs(inode);
+	if (err < 0)
+		goto out;
+
+get_xattr:
+	err = -ENODATA;  /* == ENOATTR */
+	xattr = __get_xattr(ci, name);
+	if (!xattr) {
+		if (vxattr)
+			err = vxattr->getxattr_cb(ci, value, size);
+		goto out;
+	}
+
+	err = -ERANGE;
+	if (size && size < xattr->val_len)
+		goto out;
+
+	err = xattr->val_len;
+	if (size == 0)
+		goto out;
+
+	memcpy(value, xattr->val, xattr->val_len);
+
+out:
+	spin_unlock(&inode->i_lock);
+	return err;
+}
+
+ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size)
+{
+	struct inode *inode = dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
+	u32 vir_namelen = 0;
+	u32 namelen;
+	int err;
+	u32 len;
+	int i;
+
+	spin_lock(&inode->i_lock);
+	dout("listxattr %p ver=%lld index_ver=%lld\n", inode,
+	     ci->i_xattrs.version, ci->i_xattrs.index_version);
+
+	if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) &&
+	    (ci->i_xattrs.index_version > ci->i_xattrs.version)) {
+		goto list_xattr;
+	} else {
+		spin_unlock(&inode->i_lock);
+		err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR);
+		if (err)
+			return err;
+	}
+
+	spin_lock(&inode->i_lock);
+
+	err = __build_xattrs(inode);
+	if (err < 0)
+		goto out;
+
+list_xattr:
+	vir_namelen = 0;
+	/* include virtual dir xattrs */
+	if (vxattrs)
+		for (i = 0; vxattrs[i].name; i++)
+			vir_namelen += strlen(vxattrs[i].name) + 1;
+	/* adding 1 byte per each variable due to the null termination */
+	namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count;
+	err = -ERANGE;
+	if (size && namelen > size)
+		goto out;
+
+	err = namelen;
+	if (size == 0)
+		goto out;
+
+	names = __copy_xattr_names(ci, names);
+
+	/* virtual xattr names, too */
+	if (vxattrs)
+		for (i = 0; vxattrs[i].name; i++) {
+			len = sprintf(names, "%s", vxattrs[i].name);
+			names += len + 1;
+		}
+
+out:
+	spin_unlock(&inode->i_lock);
+	return err;
+}
+
+static int ceph_sync_setxattr(struct dentry *dentry, const char *name,
+			      const char *value, size_t size, int flags)
+{
+	struct ceph_client *client = ceph_client(dentry->d_sb);
+	struct inode *inode = dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct inode *parent_inode = dentry->d_parent->d_inode;
+	struct ceph_mds_request *req;
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	int err;
+	int i, nr_pages;
+	struct page **pages = NULL;
+	void *kaddr;
+
+	/* copy value into some pages */
+	nr_pages = calc_pages_for(0, size);
+	if (nr_pages) {
+		pages = kmalloc(sizeof(pages[0])*nr_pages, GFP_NOFS);
+		if (!pages)
+			return -ENOMEM;
+		err = -ENOMEM;
+		for (i = 0; i < nr_pages; i++) {
+			pages[i] = alloc_page(GFP_NOFS);
+			if (!pages[i]) {
+				nr_pages = i;
+				goto out;
+			}
+			kaddr = kmap(pages[i]);
+			memcpy(kaddr, value + i*PAGE_CACHE_SIZE,
+			       min(PAGE_CACHE_SIZE, size-i*PAGE_CACHE_SIZE));
+		}
+	}
+
+	dout("setxattr value=%.*s\n", (int)size, value);
+
+	/* do request */
+	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR,
+				       USE_AUTH_MDS);
+	if (IS_ERR(req)) {
+		err = PTR_ERR(req);
+		goto out;
+	}
+	req->r_inode = igrab(inode);
+	req->r_inode_drop = CEPH_CAP_XATTR_SHARED;
+	req->r_num_caps = 1;
+	req->r_args.setxattr.flags = cpu_to_le32(flags);
+	req->r_path2 = kstrdup(name, GFP_NOFS);
+
+	req->r_pages = pages;
+	req->r_num_pages = nr_pages;
+	req->r_data_len = size;
+
+	dout("xattr.ver (before): %lld\n", ci->i_xattrs.version);
+	err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+	ceph_mdsc_put_request(req);
+	dout("xattr.ver (after): %lld\n", ci->i_xattrs.version);
+
+out:
+	if (pages) {
+		for (i = 0; i < nr_pages; i++)
+			__free_page(pages[i]);
+		kfree(pages);
+	}
+	return err;
+}
+
+int ceph_setxattr(struct dentry *dentry, const char *name,
+		  const void *value, size_t size, int flags)
+{
+	struct inode *inode = dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
+	int err;
+	int name_len = strlen(name);
+	int val_len = size;
+	char *newname = NULL;
+	char *newval = NULL;
+	struct ceph_inode_xattr *xattr = NULL;
+	int issued;
+	int required_blob_size;
+
+	if (ceph_snap(inode) != CEPH_NOSNAP)
+		return -EROFS;
+
+	if (!ceph_is_valid_xattr(name))
+		return -EOPNOTSUPP;
+
+	if (vxattrs) {
+		struct ceph_vxattr_cb *vxattr =
+			ceph_match_vxattr(vxattrs, name);
+		if (vxattr && vxattr->readonly)
+			return -EOPNOTSUPP;
+	}
+
+	/* preallocate memory for xattr name, value, index node */
+	err = -ENOMEM;
+	newname = kmalloc(name_len + 1, GFP_NOFS);
+	if (!newname)
+		goto out;
+	memcpy(newname, name, name_len + 1);
+
+	if (val_len) {
+		newval = kmalloc(val_len + 1, GFP_NOFS);
+		if (!newval)
+			goto out;
+		memcpy(newval, value, val_len);
+		newval[val_len] = '\0';
+	}
+
+	xattr = kmalloc(sizeof(struct ceph_inode_xattr), GFP_NOFS);
+	if (!xattr)
+		goto out;
+
+	spin_lock(&inode->i_lock);
+retry:
+	issued = __ceph_caps_issued(ci, NULL);
+	if (!(issued & CEPH_CAP_XATTR_EXCL))
+		goto do_sync;
+	__build_xattrs(inode);
+
+	required_blob_size = __get_required_blob_size(ci, name_len, val_len);
+
+	if (!ci->i_xattrs.prealloc_blob ||
+	    required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) {
+		struct ceph_buffer *blob = NULL;
+
+		spin_unlock(&inode->i_lock);
+		dout(" preaallocating new blob size=%d\n", required_blob_size);
+		blob = ceph_buffer_new(required_blob_size, GFP_NOFS);
+		if (!blob)
+			goto out;
+		spin_lock(&inode->i_lock);
+		if (ci->i_xattrs.prealloc_blob)
+			ceph_buffer_put(ci->i_xattrs.prealloc_blob);
+		ci->i_xattrs.prealloc_blob = blob;
+		goto retry;
+	}
+
+	dout("setxattr %p issued %s\n", inode, ceph_cap_string(issued));
+	err = __set_xattr(ci, newname, name_len, newval,
+			  val_len, 1, 1, 1, &xattr);
+	__ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
+	ci->i_xattrs.dirty = true;
+	inode->i_ctime = CURRENT_TIME;
+	spin_unlock(&inode->i_lock);
+
+	return err;
+
+do_sync:
+	spin_unlock(&inode->i_lock);
+	err = ceph_sync_setxattr(dentry, name, value, size, flags);
+out:
+	kfree(newname);
+	kfree(newval);
+	kfree(xattr);
+	return err;
+}
+
+static int ceph_send_removexattr(struct dentry *dentry, const char *name)
+{
+	struct ceph_client *client = ceph_client(dentry->d_sb);
+	struct ceph_mds_client *mdsc = &client->mdsc;
+	struct inode *inode = dentry->d_inode;
+	struct inode *parent_inode = dentry->d_parent->d_inode;
+	struct ceph_mds_request *req;
+	int err;
+
+	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RMXATTR,
+				       USE_AUTH_MDS);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+	req->r_inode = igrab(inode);
+	req->r_inode_drop = CEPH_CAP_XATTR_SHARED;
+	req->r_num_caps = 1;
+	req->r_path2 = kstrdup(name, GFP_NOFS);
+
+	err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+	ceph_mdsc_put_request(req);
+	return err;
+}
+
+int ceph_removexattr(struct dentry *dentry, const char *name)
+{
+	struct inode *inode = dentry->d_inode;
+	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
+	int issued;
+	int err;
+
+	if (ceph_snap(inode) != CEPH_NOSNAP)
+		return -EROFS;
+
+	if (!ceph_is_valid_xattr(name))
+		return -EOPNOTSUPP;
+
+	if (vxattrs) {
+		struct ceph_vxattr_cb *vxattr =
+			ceph_match_vxattr(vxattrs, name);
+		if (vxattr && vxattr->readonly)
+			return -EOPNOTSUPP;
+	}
+
+	spin_lock(&inode->i_lock);
+	__build_xattrs(inode);
+	issued = __ceph_caps_issued(ci, NULL);
+	dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued));
+
+	if (!(issued & CEPH_CAP_XATTR_EXCL))
+		goto do_sync;
+
+	err = __remove_xattr_by_name(ceph_inode(inode), name);
+	__ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
+	ci->i_xattrs.dirty = true;
+	inode->i_ctime = CURRENT_TIME;
+
+	spin_unlock(&inode->i_lock);
+
+	return err;
+do_sync:
+	spin_unlock(&inode->i_lock);
+	err = ceph_send_removexattr(dentry, name);
+	return err;
+}
+
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/asn1.c linux-libre-2.6.34-gnu1/fs/cifs/asn1.c
--- linux-libre-2.6.33-gnu1/fs/cifs/asn1.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/asn1.c	2010-05-16 17:17:36.000000000 -0400
@@ -136,7 +136,7 @@ asn1_enum_decode(struct asn1_ctx *ctx, _
 		return 0;
 	}
 
-	ch = *(ctx->pointer)++; /* ch has 0xa, ptr points to lenght octet */
+	ch = *(ctx->pointer)++; /* ch has 0xa, ptr points to length octet */
 	if ((ch) == ASN1_ENUM)  /* if ch value is ENUM, 0xa */
 		*val = *(++(ctx->pointer)); /* value has enum value */
 	else
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/CHANGES linux-libre-2.6.34-gnu1/fs/cifs/CHANGES
--- linux-libre-2.6.33-gnu1/fs/cifs/CHANGES	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/CHANGES	2010-05-16 17:17:36.000000000 -0400
@@ -1,6 +1,7 @@
 Version 1.62
 ------------
-Add sockopt=TCP_NODELAY mount option.
+Add sockopt=TCP_NODELAY mount option. EA (xattr) routines hardened
+to more strictly handle corrupt frames.
 
 Version 1.61
 ------------
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/cifsacl.c linux-libre-2.6.34-gnu1/fs/cifs/cifsacl.c
--- linux-libre-2.6.33-gnu1/fs/cifs/cifsacl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/cifsacl.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include "cifspdu.h"
 #include "cifsglob.h"
 #include "cifsacl.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/cifs_dfs_ref.c linux-libre-2.6.34-gnu1/fs/cifs/cifs_dfs_ref.c
--- linux-libre-2.6.33-gnu1/fs/cifs/cifs_dfs_ref.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/cifs_dfs_ref.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/dcache.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
 #include <linux/vfs.h>
 #include <linux/fs.h>
 #include "cifsglob.h"
@@ -54,7 +55,7 @@ void cifs_dfs_release_automount_timer(vo
  * Extracts sharename form full UNC.
  * i.e. strips from UNC trailing path that is not part of share
  * name and fixup missing '\' in the begining of DFS node refferal
- * if neccessary.
+ * if necessary.
  * Returns pointer to share name on success or ERR_PTR on error.
  * Caller is responsible for freeing returned string.
  */
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/cifsencrypt.c linux-libre-2.6.34-gnu1/fs/cifs/cifsencrypt.c
--- linux-libre-2.6.33-gnu1/fs/cifs/cifsencrypt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/cifsencrypt.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include "cifspdu.h"
 #include "cifsglob.h"
 #include "cifs_debug.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/cifsfs.c linux-libre-2.6.34-gnu1/fs/cifs/cifsfs.c
--- linux-libre-2.6.33-gnu1/fs/cifs/cifsfs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/cifsfs.c	2010-05-16 17:17:36.000000000 -0400
@@ -103,6 +103,12 @@ cifs_read_super(struct super_block *sb,
 	if (cifs_sb == NULL)
 		return -ENOMEM;
 
+	rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
+	if (rc) {
+		kfree(cifs_sb);
+		return rc;
+	}
+
 #ifdef CONFIG_CIFS_DFS_UPCALL
 	/* copy mount params to sb for use in submounts */
 	/* BB: should we move this after the mount so we
@@ -115,6 +121,7 @@ cifs_read_super(struct super_block *sb,
 		int len = strlen(data);
 		cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
 		if (cifs_sb->mountdata == NULL) {
+			bdi_destroy(&cifs_sb->bdi);
 			kfree(sb->s_fs_info);
 			sb->s_fs_info = NULL;
 			return -ENOMEM;
@@ -135,6 +142,7 @@ cifs_read_super(struct super_block *sb,
 
 	sb->s_magic = CIFS_MAGIC_NUMBER;
 	sb->s_op = &cifs_super_ops;
+	sb->s_bdi = &cifs_sb->bdi;
 /*	if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
 	    sb->s_blocksize =
 		cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
@@ -183,6 +191,7 @@ out_mount_failed:
 		}
 #endif
 		unload_nls(cifs_sb->local_nls);
+		bdi_destroy(&cifs_sb->bdi);
 		kfree(cifs_sb);
 	}
 	return rc;
@@ -214,6 +223,7 @@ cifs_put_super(struct super_block *sb)
 #endif
 
 	unload_nls(cifs_sb->local_nls);
+	bdi_destroy(&cifs_sb->bdi);
 	kfree(cifs_sb);
 
 	unlock_kernel();
@@ -312,6 +322,7 @@ cifs_alloc_inode(struct super_block *sb)
 	cifs_inode->clientCanCacheRead = false;
 	cifs_inode->clientCanCacheAll = false;
 	cifs_inode->delete_pending = false;
+	cifs_inode->invalid_mapping = false;
 	cifs_inode->vfs_inode.i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
 	cifs_inode->server_eof = 0;
 
@@ -638,7 +649,7 @@ static loff_t cifs_llseek(struct file *f
 		   setting the revalidate time to zero */
 		CIFS_I(file->f_path.dentry->d_inode)->time = 0;
 
-		retval = cifs_revalidate(file->f_path.dentry);
+		retval = cifs_revalidate_file(file);
 		if (retval < 0)
 			return (loff_t)retval;
 	}
@@ -807,6 +818,7 @@ const struct file_operations cifs_file_d
 	.release = cifs_close,
 	.fsync = cifs_fsync,
 	.flush = cifs_flush,
+	.mmap = cifs_file_mmap,
 	.splice_read = generic_file_splice_read,
 #ifdef CONFIG_CIFS_POSIX
 	.unlocked_ioctl  = cifs_ioctl,
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/cifsfs.h linux-libre-2.6.34-gnu1/fs/cifs/cifsfs.h
--- linux-libre-2.6.33-gnu1/fs/cifs/cifsfs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/cifsfs.h	2010-05-16 17:17:36.000000000 -0400
@@ -61,7 +61,8 @@ extern int cifs_mkdir(struct inode *, st
 extern int cifs_rmdir(struct inode *, struct dentry *);
 extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
 		       struct dentry *);
-extern int cifs_revalidate(struct dentry *);
+extern int cifs_revalidate_file(struct file *filp);
+extern int cifs_revalidate_dentry(struct dentry *);
 extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
 extern int cifs_setattr(struct dentry *, struct iattr *);
 
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/cifs_fs_sb.h linux-libre-2.6.34-gnu1/fs/cifs/cifs_fs_sb.h
--- linux-libre-2.6.33-gnu1/fs/cifs/cifs_fs_sb.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/cifs_fs_sb.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,8 @@
 #ifndef _CIFS_FS_SB_H
 #define _CIFS_FS_SB_H
 
+#include <linux/backing-dev.h>
+
 #define CIFS_MOUNT_NO_PERM      1 /* do not do client vfs_perm check */
 #define CIFS_MOUNT_SET_UID      2 /* set current's euid in create etc. */
 #define CIFS_MOUNT_SERVER_INUM  4 /* inode numbers from uniqueid from server  */
@@ -50,5 +52,6 @@ struct cifs_sb_info {
 #ifdef CONFIG_CIFS_DFS_UPCALL
 	char   *mountdata; /* mount options received at mount time */
 #endif
+	struct backing_dev_info bdi;
 };
 #endif				/* _CIFS_FS_SB_H */
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/cifsglob.h linux-libre-2.6.34-gnu1/fs/cifs/cifsglob.h
--- linux-libre-2.6.33-gnu1/fs/cifs/cifsglob.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/cifsglob.h	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
  */
 #include <linux/in.h>
 #include <linux/in6.h>
+#include <linux/slab.h>
 #include <linux/slow-work.h>
 #include "cifs_fs_sb.h"
 #include "cifsacl.h"
@@ -205,7 +206,7 @@ struct cifsUidInfo {
 struct cifsSesInfo {
 	struct list_head smb_ses_list;
 	struct list_head tcon_list;
-	struct semaphore sesSem;
+	struct mutex session_mutex;
 #if 0
 	struct cifsUidInfo *uidInfo;	/* pointer to user info */
 #endif
@@ -389,6 +390,7 @@ struct cifsInodeInfo {
 	bool clientCanCacheRead:1;	/* read oplock */
 	bool clientCanCacheAll:1;	/* read and writebehind oplock */
 	bool delete_pending:1;		/* DELETE_ON_CLOSE is set */
+	bool invalid_mapping:1;		/* pagecache is invalid */
 	u64  server_eof;		/* current file size on server */
 	u64  uniqueid;			/* server inode number */
 	struct inode vfs_inode;
@@ -500,6 +502,7 @@ struct dfs_info3_param {
 #define CIFS_FATTR_DFS_REFERRAL		0x1
 #define CIFS_FATTR_DELETE_PENDING	0x2
 #define CIFS_FATTR_NEED_REVAL		0x4
+#define CIFS_FATTR_INO_COLLISION	0x8
 
 struct cifs_fattr {
 	u32		cf_flags;
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/cifspdu.h linux-libre-2.6.34-gnu1/fs/cifs/cifspdu.h
--- linux-libre-2.6.33-gnu1/fs/cifs/cifspdu.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/cifspdu.h	2010-05-16 17:17:36.000000000 -0400
@@ -415,10 +415,10 @@ struct smb_hdr {
 	__u8 WordCount;
 } __attribute__((packed));
 /* given a pointer to an smb_hdr retrieve the value of byte count */
-#define BCC(smb_var) (*(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount)))
-#define BCC_LE(smb_var) (*(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount)))
+#define BCC(smb_var) (*(__u16 *)((char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount)))
+#define BCC_LE(smb_var) (*(__le16 *)((char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount)))
 /* given a pointer to an smb_hdr retrieve the pointer to the byte area */
-#define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount) + 2)
+#define pByteArea(smb_var) ((unsigned char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount) + 2)
 
 /*
  * Computer Name Length (since Netbios name was length 16 with last byte 0x20)
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/cifsproto.h linux-libre-2.6.34-gnu1/fs/cifs/cifsproto.h
--- linux-libre-2.6.33-gnu1/fs/cifs/cifsproto.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/cifsproto.h	2010-05-16 17:17:36.000000000 -0400
@@ -104,10 +104,12 @@ extern void cifs_fattr_to_inode(struct i
 extern struct inode *cifs_iget(struct super_block *sb,
 			       struct cifs_fattr *fattr);
 
+extern int cifs_get_file_info(struct file *filp);
 extern int cifs_get_inode_info(struct inode **pinode,
 			const unsigned char *search_path,
 			FILE_ALL_INFO *pfile_info,
 			struct super_block *sb, int xid, const __u16 *pfid);
+extern int cifs_get_file_info_unix(struct file *filp);
 extern int cifs_get_inode_info_unix(struct inode **pinode,
 			const unsigned char *search_path,
 			struct super_block *sb, int xid);
@@ -142,6 +144,8 @@ extern int CIFSFindNext(const int xid, s
 extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
 			const __u16 search_handle);
 
+extern int CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon,
+			u16 netfid, FILE_ALL_INFO *pFindData);
 extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
 			const unsigned char *searchName,
 			FILE_ALL_INFO *findData,
@@ -152,6 +156,8 @@ extern int SMBQueryInformation(const int
 			FILE_ALL_INFO *findData,
 			const struct nls_table *nls_codepage, int remap);
 
+extern int CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon,
+			u16 netfid, FILE_UNIX_BASIC_INFO *pFindData);
 extern int CIFSSMBUnixQPathInfo(const int xid,
 			struct cifsTconInfo *tcon,
 			const unsigned char *searchName,
@@ -363,13 +369,10 @@ extern int CIFSSMBNotify(const int xid,
 			__u32 filter, struct file *file, int multishot,
 			const struct nls_table *nls_codepage);
 extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
-			const unsigned char *searchName, char *EAData,
+			const unsigned char *searchName,
+			const unsigned char *ea_name, char *EAData,
 			size_t bufsize, const struct nls_table *nls_codepage,
 			int remap_special_chars);
-extern ssize_t CIFSSMBQueryEA(const int xid, struct cifsTconInfo *tcon,
-		const unsigned char *searchName, const unsigned char *ea_name,
-		unsigned char *ea_value, size_t buf_size,
-		const struct nls_table *nls_codepage, int remap_special_chars);
 extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon,
 		const char *fileName, const char *ea_name,
 		const void *ea_value, const __u16 ea_value_len,
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/cifssmb.c linux-libre-2.6.34-gnu1/fs/cifs/cifssmb.c
--- linux-libre-2.6.33-gnu1/fs/cifs/cifssmb.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/cifssmb.c	2010-05-16 17:17:36.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/vfs.h>
+#include <linux/slab.h>
 #include <linux/posix_acl_xattr.h>
 #include <asm/uaccess.h>
 #include "cifspdu.h"
@@ -170,19 +171,19 @@ cifs_reconnect_tcon(struct cifsTconInfo
 	 * need to prevent multiple threads trying to simultaneously
 	 * reconnect the same SMB session
 	 */
-	down(&ses->sesSem);
+	mutex_lock(&ses->session_mutex);
 	if (ses->need_reconnect)
 		rc = cifs_setup_session(0, ses, nls_codepage);
 
 	/* do we need to reconnect tcon? */
 	if (rc || !tcon->need_reconnect) {
-		up(&ses->sesSem);
+		mutex_unlock(&ses->session_mutex);
 		goto out;
 	}
 
 	mark_open_files_invalid(tcon);
 	rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage);
-	up(&ses->sesSem);
+	mutex_unlock(&ses->session_mutex);
 	cFYI(1, ("reconnect tcon rc = %d", rc));
 
 	if (rc)
@@ -500,7 +501,7 @@ CIFSSMBNegotiate(unsigned int xid, struc
 	} else if (pSMBr->hdr.WordCount == 13) {
 		cERROR(1, ("mount failed, cifs module not built "
 			  "with CIFS_WEAK_PW_HASH support"));
-			rc = -EOPNOTSUPP;
+		rc = -EOPNOTSUPP;
 #endif /* WEAK_PW_HASH */
 		goto neg_err_exit;
 	} else if (pSMBr->hdr.WordCount != 17) {
@@ -700,13 +701,13 @@ CIFSSMBLogoff(const int xid, struct cifs
 	if (!ses || !ses->server)
 		return -EIO;
 
-	down(&ses->sesSem);
+	mutex_lock(&ses->session_mutex);
 	if (ses->need_reconnect)
 		goto session_already_dead; /* no need to send SMBlogoff if uid
 					      already closed due to reconnect */
 	rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
 	if (rc) {
-		up(&ses->sesSem);
+		mutex_unlock(&ses->session_mutex);
 		return rc;
 	}
 
@@ -721,7 +722,7 @@ CIFSSMBLogoff(const int xid, struct cifs
 	pSMB->AndXCommand = 0xFF;
 	rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0);
 session_already_dead:
-	up(&ses->sesSem);
+	mutex_unlock(&ses->session_mutex);
 
 	/* if session dead then we do not need to do ulogoff,
 		since server closed smb session, no sense reporting
@@ -1430,6 +1431,8 @@ CIFSSMBWrite(const int xid, struct cifsT
 	__u32 bytes_sent;
 	__u16 byte_count;
 
+	*nbytes = 0;
+
 	/* cFYI(1, ("write at %lld %d bytes", offset, count));*/
 	if (tcon->ses == NULL)
 		return -ECONNABORTED;
@@ -1512,11 +1515,18 @@ CIFSSMBWrite(const int xid, struct cifsT
 	cifs_stats_inc(&tcon->num_writes);
 	if (rc) {
 		cFYI(1, ("Send error in write = %d", rc));
-		*nbytes = 0;
 	} else {
 		*nbytes = le16_to_cpu(pSMBr->CountHigh);
 		*nbytes = (*nbytes) << 16;
 		*nbytes += le16_to_cpu(pSMBr->Count);
+
+		/*
+		 * Mask off high 16 bits when bytes written as returned by the
+		 * server is greater than bytes requested by the client. Some
+		 * OS/2 servers are known to set incorrect CountHigh values.
+		 */
+		if (*nbytes > count)
+			*nbytes &= 0xFFFF;
 	}
 
 	cifs_buf_release(pSMB);
@@ -1605,6 +1615,14 @@ CIFSSMBWrite2(const int xid, struct cifs
 		*nbytes = le16_to_cpu(pSMBr->CountHigh);
 		*nbytes = (*nbytes) << 16;
 		*nbytes += le16_to_cpu(pSMBr->Count);
+
+		/*
+		 * Mask off high 16 bits when bytes written as returned by the
+		 * server is greater than bytes requested by the client. OS/2
+		 * servers are known to set incorrect CountHigh values.
+		 */
+		if (*nbytes > count)
+			*nbytes &= 0xFFFF;
 	}
 
 /*	cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
@@ -1793,8 +1811,21 @@ CIFSSMBPosixLock(const int xid, struct c
 		}
 		parm_data = (struct cifs_posix_lock *)
 			((char *)&pSMBr->hdr.Protocol + data_offset);
-		if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
+		if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
 			pLockData->fl_type = F_UNLCK;
+		else {
+			if (parm_data->lock_type ==
+					__constant_cpu_to_le16(CIFS_RDLCK))
+				pLockData->fl_type = F_RDLCK;
+			else if (parm_data->lock_type ==
+					__constant_cpu_to_le16(CIFS_WRLCK))
+				pLockData->fl_type = F_WRLCK;
+
+			pLockData->fl_start = parm_data->start;
+			pLockData->fl_end = parm_data->start +
+						parm_data->length - 1;
+			pLockData->fl_pid = parm_data->pid;
+		}
 	}
 
 plk_err_exit:
@@ -3230,8 +3261,72 @@ QInfRetry:
 	return rc;
 }
 
+int
+CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon,
+		 u16 netfid, FILE_ALL_INFO *pFindData)
+{
+	struct smb_t2_qfi_req *pSMB = NULL;
+	struct smb_t2_qfi_rsp *pSMBr = NULL;
+	int rc = 0;
+	int bytes_returned;
+	__u16 params, byte_count;
 
+QFileInfoRetry:
+	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+		      (void **) &pSMBr);
+	if (rc)
+		return rc;
 
+	params = 2 /* level */ + 2 /* fid */;
+	pSMB->t2.TotalDataCount = 0;
+	pSMB->t2.MaxParameterCount = cpu_to_le16(4);
+	/* BB find exact max data count below from sess structure BB */
+	pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
+	pSMB->t2.MaxSetupCount = 0;
+	pSMB->t2.Reserved = 0;
+	pSMB->t2.Flags = 0;
+	pSMB->t2.Timeout = 0;
+	pSMB->t2.Reserved2 = 0;
+	pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
+					       Fid) - 4);
+	pSMB->t2.DataCount = 0;
+	pSMB->t2.DataOffset = 0;
+	pSMB->t2.SetupCount = 1;
+	pSMB->t2.Reserved3 = 0;
+	pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
+	byte_count = params + 1 /* pad */ ;
+	pSMB->t2.TotalParameterCount = cpu_to_le16(params);
+	pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
+	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
+	pSMB->Pad = 0;
+	pSMB->Fid = netfid;
+	pSMB->hdr.smb_buf_length += byte_count;
+
+	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+	if (rc) {
+		cFYI(1, ("Send error in QPathInfo = %d", rc));
+	} else {		/* decode response */
+		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+
+		if (rc) /* BB add auto retry on EOPNOTSUPP? */
+			rc = -EIO;
+		else if (pSMBr->ByteCount < 40)
+			rc = -EIO;	/* bad smb */
+		else if (pFindData) {
+			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
+			memcpy((char *) pFindData,
+			       (char *) &pSMBr->hdr.Protocol +
+			       data_offset, sizeof(FILE_ALL_INFO));
+		} else
+		    rc = -ENOMEM;
+	}
+	cifs_buf_release(pSMB);
+	if (rc == -EAGAIN)
+		goto QFileInfoRetry;
+
+	return rc;
+}
 
 int
 CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
@@ -3335,6 +3430,75 @@ QPathInfoRetry:
 }
 
 int
+CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon,
+		 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
+{
+	struct smb_t2_qfi_req *pSMB = NULL;
+	struct smb_t2_qfi_rsp *pSMBr = NULL;
+	int rc = 0;
+	int bytes_returned;
+	__u16 params, byte_count;
+
+UnixQFileInfoRetry:
+	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+		      (void **) &pSMBr);
+	if (rc)
+		return rc;
+
+	params = 2 /* level */ + 2 /* fid */;
+	pSMB->t2.TotalDataCount = 0;
+	pSMB->t2.MaxParameterCount = cpu_to_le16(4);
+	/* BB find exact max data count below from sess structure BB */
+	pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
+	pSMB->t2.MaxSetupCount = 0;
+	pSMB->t2.Reserved = 0;
+	pSMB->t2.Flags = 0;
+	pSMB->t2.Timeout = 0;
+	pSMB->t2.Reserved2 = 0;
+	pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
+					       Fid) - 4);
+	pSMB->t2.DataCount = 0;
+	pSMB->t2.DataOffset = 0;
+	pSMB->t2.SetupCount = 1;
+	pSMB->t2.Reserved3 = 0;
+	pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
+	byte_count = params + 1 /* pad */ ;
+	pSMB->t2.TotalParameterCount = cpu_to_le16(params);
+	pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
+	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
+	pSMB->Pad = 0;
+	pSMB->Fid = netfid;
+	pSMB->hdr.smb_buf_length += byte_count;
+
+	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+	if (rc) {
+		cFYI(1, ("Send error in QPathInfo = %d", rc));
+	} else {		/* decode response */
+		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+
+		if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) {
+			cERROR(1, ("Malformed FILE_UNIX_BASIC_INFO response.\n"
+				   "Unix Extensions can be disabled on mount "
+				   "by specifying the nosfu mount option."));
+			rc = -EIO;	/* bad smb */
+		} else {
+			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
+			memcpy((char *) pFindData,
+			       (char *) &pSMBr->hdr.Protocol +
+			       data_offset,
+			       sizeof(FILE_UNIX_BASIC_INFO));
+		}
+	}
+
+	cifs_buf_release(pSMB);
+	if (rc == -EAGAIN)
+		goto UnixQFileInfoRetry;
+
+	return rc;
+}
+
+int
 CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
 		     const unsigned char *searchName,
 		     FILE_UNIX_BASIC_INFO *pFindData,
@@ -3886,7 +4050,7 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS
 		goto parse_DFS_referrals_exit;
 	}
 
-	/* collect neccessary data from referrals */
+	/* collect necessary data from referrals */
 	for (i = 0; i < *num_of_nodes; i++) {
 		char *temp;
 		int max_len;
@@ -5269,22 +5433,34 @@ int CIFSSMBNotify(const int xid, struct
 	cifs_buf_release(pSMB);
 	return rc;
 }
+
 #ifdef CONFIG_CIFS_XATTR
+/*
+ * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
+ * function used by listxattr and getxattr type calls. When ea_name is set,
+ * it looks for that attribute name and stuffs that value into the EAData
+ * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
+ * buffer. In both cases, the return value is either the length of the
+ * resulting data or a negative error code. If EAData is a NULL pointer then
+ * the data isn't copied to it, but the length is returned.
+ */
 ssize_t
 CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
-		 const unsigned char *searchName,
-		 char *EAData, size_t buf_size,
-		 const struct nls_table *nls_codepage, int remap)
+		const unsigned char *searchName, const unsigned char *ea_name,
+		char *EAData, size_t buf_size,
+		const struct nls_table *nls_codepage, int remap)
 {
 		/* BB assumes one setup word */
 	TRANSACTION2_QPI_REQ *pSMB = NULL;
 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
 	int rc = 0;
 	int bytes_returned;
-	int name_len;
+	int list_len;
+	struct fealist *ea_response_data;
 	struct fea *temp_fea;
 	char *temp_ptr;
-	__u16 params, byte_count;
+	char *end_of_smb;
+	__u16 params, byte_count, data_offset;
 
 	cFYI(1, ("In Query All EAs path %s", searchName));
 QAllEAsRetry:
@@ -5294,22 +5470,22 @@ QAllEAsRetry:
 		return rc;
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-		name_len =
+		list_len =
 		    cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
 				     PATH_MAX, nls_codepage, remap);
-		name_len++;	/* trailing null */
-		name_len *= 2;
+		list_len++;	/* trailing null */
+		list_len *= 2;
 	} else {	/* BB improve the check for buffer overruns BB */
-		name_len = strnlen(searchName, PATH_MAX);
-		name_len++;	/* trailing null */
-		strncpy(pSMB->FileName, searchName, name_len);
+		list_len = strnlen(searchName, PATH_MAX);
+		list_len++;	/* trailing null */
+		strncpy(pSMB->FileName, searchName, list_len);
 	}
 
-	params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
+	params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
 	pSMB->TotalDataCount = 0;
 	pSMB->MaxParameterCount = cpu_to_le16(2);
 	/* BB find exact max SMB PDU from sess structure BB */
-	pSMB->MaxDataCount = cpu_to_le16(4000);
+	pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
 	pSMB->MaxSetupCount = 0;
 	pSMB->Reserved = 0;
 	pSMB->Flags = 0;
@@ -5334,237 +5510,117 @@ QAllEAsRetry:
 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
 	if (rc) {
 		cFYI(1, ("Send error in QueryAllEAs = %d", rc));
-	} else {		/* decode response */
-		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+		goto QAllEAsOut;
+	}
 
-		/* BB also check enough total bytes returned */
-		/* BB we need to improve the validity checking
-		of these trans2 responses */
-		if (rc || (pSMBr->ByteCount < 4))
-			rc = -EIO;	/* bad smb */
-	   /* else if (pFindData){
-			memcpy((char *) pFindData,
-			       (char *) &pSMBr->hdr.Protocol +
-			       data_offset, kl);
-		}*/ else {
-			/* check that length of list is not more than bcc */
-			/* check that each entry does not go beyond length
-			   of list */
-			/* check that each element of each entry does not
-			   go beyond end of list */
-			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
-			struct fealist *ea_response_data;
-			rc = 0;
-			/* validate_trans2_offsets() */
-			/* BB check if start of smb + data_offset > &bcc+ bcc */
-			ea_response_data = (struct fealist *)
-				(((char *) &pSMBr->hdr.Protocol) +
-				data_offset);
-			name_len = le32_to_cpu(ea_response_data->list_len);
-			cFYI(1, ("ea length %d", name_len));
-			if (name_len <= 8) {
-			/* returned EA size zeroed at top of function */
-				cFYI(1, ("empty EA list returned from server"));
-			} else {
-				/* account for ea list len */
-				name_len -= 4;
-				temp_fea = ea_response_data->list;
-				temp_ptr = (char *)temp_fea;
-				while (name_len > 0) {
-					__u16 value_len;
-					name_len -= 4;
-					temp_ptr += 4;
-					rc += temp_fea->name_len;
-				/* account for prefix user. and trailing null */
-					rc = rc + 5 + 1;
-					if (rc < (int)buf_size) {
-						memcpy(EAData, "user.", 5);
-						EAData += 5;
-						memcpy(EAData, temp_ptr,
-						       temp_fea->name_len);
-						EAData += temp_fea->name_len;
-						/* null terminate name */
-						*EAData = 0;
-						EAData = EAData + 1;
-					} else if (buf_size == 0) {
-						/* skip copy - calc size only */
-					} else {
-						/* stop before overrun buffer */
-						rc = -ERANGE;
-						break;
-					}
-					name_len -= temp_fea->name_len;
-					temp_ptr += temp_fea->name_len;
-					/* account for trailing null */
-					name_len--;
-					temp_ptr++;
-					value_len =
-					      le16_to_cpu(temp_fea->value_len);
-					name_len -= value_len;
-					temp_ptr += value_len;
-					/* BB check that temp_ptr is still
-					      within the SMB BB*/
 
-					/* no trailing null to account for
-					   in value len */
-					/* go on to next EA */
-					temp_fea = (struct fea *)temp_ptr;
-				}
-			}
-		}
+	/* BB also check enough total bytes returned */
+	/* BB we need to improve the validity checking
+	of these trans2 responses */
+
+	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+	if (rc || (pSMBr->ByteCount < 4)) {
+		rc = -EIO;	/* bad smb */
+		goto QAllEAsOut;
 	}
-	cifs_buf_release(pSMB);
-	if (rc == -EAGAIN)
-		goto QAllEAsRetry;
 
-	return (ssize_t)rc;
-}
+	/* check that length of list is not more than bcc */
+	/* check that each entry does not go beyond length
+	   of list */
+	/* check that each element of each entry does not
+	   go beyond end of list */
+	/* validate_trans2_offsets() */
+	/* BB check if start of smb + data_offset > &bcc+ bcc */
 
-ssize_t CIFSSMBQueryEA(const int xid, struct cifsTconInfo *tcon,
-		const unsigned char *searchName, const unsigned char *ea_name,
-		unsigned char *ea_value, size_t buf_size,
-		const struct nls_table *nls_codepage, int remap)
-{
-	TRANSACTION2_QPI_REQ *pSMB = NULL;
-	TRANSACTION2_QPI_RSP *pSMBr = NULL;
-	int rc = 0;
-	int bytes_returned;
-	int name_len;
-	struct fea *temp_fea;
-	char *temp_ptr;
-	__u16 params, byte_count;
+	data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
+	ea_response_data = (struct fealist *)
+				(((char *) &pSMBr->hdr.Protocol) + data_offset);
 
-	cFYI(1, ("In Query EA path %s", searchName));
-QEARetry:
-	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-		      (void **) &pSMBr);
-	if (rc)
-		return rc;
+	list_len = le32_to_cpu(ea_response_data->list_len);
+	cFYI(1, ("ea length %d", list_len));
+	if (list_len <= 8) {
+		cFYI(1, ("empty EA list returned from server"));
+		goto QAllEAsOut;
+	}
 
-	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-		name_len =
-		    cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
-				     PATH_MAX, nls_codepage, remap);
-		name_len++;	/* trailing null */
-		name_len *= 2;
-	} else {	/* BB improve the check for buffer overruns BB */
-		name_len = strnlen(searchName, PATH_MAX);
-		name_len++;	/* trailing null */
-		strncpy(pSMB->FileName, searchName, name_len);
+	/* make sure list_len doesn't go past end of SMB */
+	end_of_smb = (char *)pByteArea(&pSMBr->hdr) + BCC(&pSMBr->hdr);
+	if ((char *)ea_response_data + list_len > end_of_smb) {
+		cFYI(1, ("EA list appears to go beyond SMB"));
+		rc = -EIO;
+		goto QAllEAsOut;
 	}
 
-	params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
-	pSMB->TotalDataCount = 0;
-	pSMB->MaxParameterCount = cpu_to_le16(2);
-	/* BB find exact max SMB PDU from sess structure BB */
-	pSMB->MaxDataCount = cpu_to_le16(4000);
-	pSMB->MaxSetupCount = 0;
-	pSMB->Reserved = 0;
-	pSMB->Flags = 0;
-	pSMB->Timeout = 0;
-	pSMB->Reserved2 = 0;
-	pSMB->ParameterOffset = cpu_to_le16(offsetof(
-		struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
-	pSMB->DataCount = 0;
-	pSMB->DataOffset = 0;
-	pSMB->SetupCount = 1;
-	pSMB->Reserved3 = 0;
-	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
-	byte_count = params + 1 /* pad */ ;
-	pSMB->TotalParameterCount = cpu_to_le16(params);
-	pSMB->ParameterCount = pSMB->TotalParameterCount;
-	pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
-	pSMB->Reserved4 = 0;
-	pSMB->hdr.smb_buf_length += byte_count;
-	pSMB->ByteCount = cpu_to_le16(byte_count);
+	/* account for ea list len */
+	list_len -= 4;
+	temp_fea = ea_response_data->list;
+	temp_ptr = (char *)temp_fea;
+	while (list_len > 0) {
+		unsigned int name_len;
+		__u16 value_len;
 
-	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-	if (rc) {
-		cFYI(1, ("Send error in Query EA = %d", rc));
-	} else {		/* decode response */
-		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+		list_len -= 4;
+		temp_ptr += 4;
+		/* make sure we can read name_len and value_len */
+		if (list_len < 0) {
+			cFYI(1, ("EA entry goes beyond length of list"));
+			rc = -EIO;
+			goto QAllEAsOut;
+		}
 
-		/* BB also check enough total bytes returned */
-		/* BB we need to improve the validity checking
-		of these trans2 responses */
-		if (rc || (pSMBr->ByteCount < 4))
-			rc = -EIO;	/* bad smb */
-	   /* else if (pFindData){
-			memcpy((char *) pFindData,
-			       (char *) &pSMBr->hdr.Protocol +
-			       data_offset, kl);
-		}*/ else {
-			/* check that length of list is not more than bcc */
-			/* check that each entry does not go beyond length
-			   of list */
-			/* check that each element of each entry does not
-			   go beyond end of list */
-			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
-			struct fealist *ea_response_data;
-			rc = -ENODATA;
-			/* validate_trans2_offsets() */
-			/* BB check if start of smb + data_offset > &bcc+ bcc*/
-			ea_response_data = (struct fealist *)
-				(((char *) &pSMBr->hdr.Protocol) +
-				data_offset);
-			name_len = le32_to_cpu(ea_response_data->list_len);
-			cFYI(1, ("ea length %d", name_len));
-			if (name_len <= 8) {
-			/* returned EA size zeroed at top of function */
-				cFYI(1, ("empty EA list returned from server"));
-			} else {
-				/* account for ea list len */
-				name_len -= 4;
-				temp_fea = ea_response_data->list;
-				temp_ptr = (char *)temp_fea;
-				/* loop through checking if we have a matching
-				name and then return the associated value */
-				while (name_len > 0) {
-					__u16 value_len;
-					name_len -= 4;
-					temp_ptr += 4;
-					value_len =
-					      le16_to_cpu(temp_fea->value_len);
-				/* BB validate that value_len falls within SMB,
-				even though maximum for name_len is 255 */
-					if (memcmp(temp_fea->name, ea_name,
-						  temp_fea->name_len) == 0) {
-						/* found a match */
-						rc = value_len;
-				/* account for prefix user. and trailing null */
-						if (rc <= (int)buf_size) {
-							memcpy(ea_value,
-								temp_fea->name+temp_fea->name_len+1,
-								rc);
-							/* ea values, unlike ea
-							   names, are not null
-							   terminated */
-						} else if (buf_size == 0) {
-						/* skip copy - calc size only */
-						} else {
-						/* stop before overrun buffer */
-							rc = -ERANGE;
-						}
-						break;
-					}
-					name_len -= temp_fea->name_len;
-					temp_ptr += temp_fea->name_len;
-					/* account for trailing null */
-					name_len--;
-					temp_ptr++;
-					name_len -= value_len;
-					temp_ptr += value_len;
-					/* No trailing null to account for in
-					   value_len.  Go on to next EA */
-					temp_fea = (struct fea *)temp_ptr;
+		name_len = temp_fea->name_len;
+		value_len = le16_to_cpu(temp_fea->value_len);
+		list_len -= name_len + 1 + value_len;
+		if (list_len < 0) {
+			cFYI(1, ("EA entry goes beyond length of list"));
+			rc = -EIO;
+			goto QAllEAsOut;
+		}
+
+		if (ea_name) {
+			if (strncmp(ea_name, temp_ptr, name_len) == 0) {
+				temp_ptr += name_len + 1;
+				rc = value_len;
+				if (buf_size == 0)
+					goto QAllEAsOut;
+				if ((size_t)value_len > buf_size) {
+					rc = -ERANGE;
+					goto QAllEAsOut;
 				}
+				memcpy(EAData, temp_ptr, value_len);
+				goto QAllEAsOut;
+			}
+		} else {
+			/* account for prefix user. and trailing null */
+			rc += (5 + 1 + name_len);
+			if (rc < (int) buf_size) {
+				memcpy(EAData, "user.", 5);
+				EAData += 5;
+				memcpy(EAData, temp_ptr, name_len);
+				EAData += name_len;
+				/* null terminate name */
+				*EAData = 0;
+				++EAData;
+			} else if (buf_size == 0) {
+				/* skip copy - calc size only */
+			} else {
+				/* stop before overrun buffer */
+				rc = -ERANGE;
+				break;
 			}
 		}
+		temp_ptr += name_len + 1 + value_len;
+		temp_fea = (struct fea *)temp_ptr;
 	}
+
+	/* didn't find the named attribute */
+	if (ea_name)
+		rc = -ENODATA;
+
+QAllEAsOut:
 	cifs_buf_release(pSMB);
 	if (rc == -EAGAIN)
-		goto QEARetry;
+		goto QAllEAsRetry;
 
 	return (ssize_t)rc;
 }
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/cifs_spnego.c linux-libre-2.6.34-gnu1/fs/cifs/cifs_spnego.c
--- linux-libre-2.6.33-gnu1/fs/cifs/cifs_spnego.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/cifs_spnego.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <keys/user-type.h>
 #include <linux/key-type.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/cifs_unicode.c linux-libre-2.6.34-gnu1/fs/cifs/cifs_unicode.c
--- linux-libre-2.6.33-gnu1/fs/cifs/cifs_unicode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/cifs_unicode.c	2010-05-16 17:17:36.000000000 -0400
@@ -19,6 +19,7 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include "cifs_unicode.h"
 #include "cifs_uniupr.h"
 #include "cifspdu.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/connect.c linux-libre-2.6.34-gnu1/fs/cifs/connect.c
--- linux-libre-2.6.33-gnu1/fs/cifs/connect.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/connect.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/string.h>
 #include <linux/list.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/ctype.h>
 #include <linux/utsname.h>
@@ -2388,13 +2389,13 @@ try_mount_again:
 		 */
 		cifs_put_tcp_session(srvTcp);
 
-		down(&pSesInfo->sesSem);
+		mutex_lock(&pSesInfo->session_mutex);
 		if (pSesInfo->need_reconnect) {
 			cFYI(1, ("Session needs reconnect"));
 			rc = cifs_setup_session(xid, pSesInfo,
 						cifs_sb->local_nls);
 		}
-		up(&pSesInfo->sesSem);
+		mutex_unlock(&pSesInfo->session_mutex);
 	} else if (!rc) {
 		cFYI(1, ("Existing smb sess not found"));
 		pSesInfo = sesInfoAlloc();
@@ -2437,12 +2438,12 @@ try_mount_again:
 		}
 		pSesInfo->linux_uid = volume_info->linux_uid;
 		pSesInfo->overrideSecFlg = volume_info->secFlg;
-		down(&pSesInfo->sesSem);
+		mutex_lock(&pSesInfo->session_mutex);
 
 		/* BB FIXME need to pass vol->secFlgs BB */
 		rc = cifs_setup_session(xid, pSesInfo,
 					cifs_sb->local_nls);
-		up(&pSesInfo->sesSem);
+		mutex_unlock(&pSesInfo->session_mutex);
 	}
 
 	/* search for existing tcon to this server share */
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/dir.c linux-libre-2.6.34-gnu1/fs/cifs/dir.c
--- linux-libre-2.6.33-gnu1/fs/cifs/dir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/dir.c	2010-05-16 17:17:36.000000000 -0400
@@ -739,7 +739,7 @@ cifs_d_revalidate(struct dentry *direntr
 	int isValid = 1;
 
 	if (direntry->d_inode) {
-		if (cifs_revalidate(direntry))
+		if (cifs_revalidate_dentry(direntry))
 			return 0;
 	} else {
 		cFYI(1, ("neg dentry 0x%p name = %s",
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/dns_resolve.c linux-libre-2.6.34-gnu1/fs/cifs/dns_resolve.c
--- linux-libre-2.6.33-gnu1/fs/cifs/dns_resolve.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/dns_resolve.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,6 +23,7 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
+#include <linux/slab.h>
 #include <keys/user-type.h>
 #include "dns_resolve.h"
 #include "cifsglob.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/file.c linux-libre-2.6.34-gnu1/fs/cifs/file.c
--- linux-libre-2.6.33-gnu1/fs/cifs/file.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/file.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/task_io_accounting_ops.h>
 #include <linux/delay.h>
 #include <linux/mount.h>
+#include <linux/slab.h>
 #include <asm/div64.h>
 #include "cifsfs.h"
 #include "cifspdu.h"
@@ -219,8 +220,8 @@ static inline int cifs_open_inode_helper
 		cFYI(1, ("inode unchanged on server"));
 	} else {
 		if (file->f_path.dentry->d_inode->i_mapping) {
-		/* BB no need to lock inode until after invalidate
-		   since namei code should already have it locked? */
+			/* BB no need to lock inode until after invalidate
+			since namei code should already have it locked? */
 			rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping);
 			if (rc != 0)
 				CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc;
@@ -838,8 +839,32 @@ int cifs_lock(struct file *file, int cmd
 
 		} else {
 			/* if rc == ERR_SHARING_VIOLATION ? */
-			rc = 0;	/* do not change lock type to unlock
-				   since range in use */
+			rc = 0;
+
+			if (lockType & LOCKING_ANDX_SHARED_LOCK) {
+				pfLock->fl_type = F_WRLCK;
+			} else {
+				rc = CIFSSMBLock(xid, tcon, netfid, length,
+					pfLock->fl_start, 0, 1,
+					lockType | LOCKING_ANDX_SHARED_LOCK,
+					0 /* wait flag */);
+				if (rc == 0) {
+					rc = CIFSSMBLock(xid, tcon, netfid,
+						length, pfLock->fl_start, 1, 0,
+						lockType |
+						LOCKING_ANDX_SHARED_LOCK,
+						0 /* wait flag */);
+					pfLock->fl_type = F_RDLCK;
+					if (rc != 0)
+						cERROR(1, ("Error unlocking "
+						"previously locked range %d "
+						"during test of lock", rc));
+					rc = 0;
+				} else {
+					pfLock->fl_type = F_WRLCK;
+					rc = 0;
+				}
+			}
 		}
 
 		FreeXid(xid);
@@ -1890,11 +1915,10 @@ static ssize_t cifs_read(struct file *fi
 
 int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	struct dentry *dentry = file->f_path.dentry;
 	int rc, xid;
 
 	xid = GetXid();
-	rc = cifs_revalidate(dentry);
+	rc = cifs_revalidate_file(file);
 	if (rc) {
 		cFYI(1, ("Validation prior to mmap failed, error=%d", rc));
 		FreeXid(xid);
@@ -2289,9 +2313,9 @@ cifs_oplock_break(struct slow_work *work
 	if (inode && S_ISREG(inode->i_mode)) {
 #ifdef CONFIG_CIFS_EXPERIMENTAL
 		if (cinode->clientCanCacheAll == 0)
-			break_lease(inode, FMODE_READ);
+			break_lease(inode, O_RDONLY);
 		else if (cinode->clientCanCacheRead == 0)
-			break_lease(inode, FMODE_WRITE);
+			break_lease(inode, O_WRONLY);
 #endif
 		rc = filemap_fdatawrite(inode->i_mapping);
 		if (cinode->clientCanCacheRead == 0) {
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/inode.c linux-libre-2.6.34-gnu1/fs/cifs/inode.c
--- linux-libre-2.6.33-gnu1/fs/cifs/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 #include <linux/fs.h>
 #include <linux/stat.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <asm/div64.h>
 #include "cifsfs.h"
@@ -77,6 +78,41 @@ static void cifs_set_ops(struct inode *i
 	}
 }
 
+/* check inode attributes against fattr. If they don't match, tag the
+ * inode for cache invalidation
+ */
+static void
+cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
+{
+	struct cifsInodeInfo *cifs_i = CIFS_I(inode);
+
+	cFYI(1, ("%s: revalidating inode %llu", __func__, cifs_i->uniqueid));
+
+	if (inode->i_state & I_NEW) {
+		cFYI(1, ("%s: inode %llu is new", __func__, cifs_i->uniqueid));
+		return;
+	}
+
+	/* don't bother with revalidation if we have an oplock */
+	if (cifs_i->clientCanCacheRead) {
+		cFYI(1, ("%s: inode %llu is oplocked", __func__,
+			 cifs_i->uniqueid));
+		return;
+	}
+
+	 /* revalidate if mtime or size have changed */
+	if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) &&
+	    cifs_i->server_eof == fattr->cf_eof) {
+		cFYI(1, ("%s: inode %llu is unchanged", __func__,
+			 cifs_i->uniqueid));
+		return;
+	}
+
+	cFYI(1, ("%s: invalidating inode %llu mapping", __func__,
+		 cifs_i->uniqueid));
+	cifs_i->invalid_mapping = true;
+}
+
 /* populate an inode with info from a cifs_fattr struct */
 void
 cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
@@ -85,6 +121,8 @@ cifs_fattr_to_inode(struct inode *inode,
 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 	unsigned long oldtime = cifs_i->time;
 
+	cifs_revalidate_cache(inode, fattr);
+
 	inode->i_atime = fattr->cf_atime;
 	inode->i_mtime = fattr->cf_mtime;
 	inode->i_ctime = fattr->cf_ctime;
@@ -111,6 +149,7 @@ cifs_fattr_to_inode(struct inode *inode,
 
 	cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;
 
+	cifs_i->server_eof = fattr->cf_eof;
 	/*
 	 * Can't safely change the file size here if the client is writing to
 	 * it due to potential races.
@@ -230,6 +269,31 @@ cifs_create_dfs_fattr(struct cifs_fattr
 	fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
 }
 
+int cifs_get_file_info_unix(struct file *filp)
+{
+	int rc;
+	int xid;
+	FILE_UNIX_BASIC_INFO find_data;
+	struct cifs_fattr fattr;
+	struct inode *inode = filp->f_path.dentry->d_inode;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+	struct cifsTconInfo *tcon = cifs_sb->tcon;
+	struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
+
+	xid = GetXid();
+	rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
+	if (!rc) {
+		cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
+	} else if (rc == -EREMOTE) {
+		cifs_create_dfs_fattr(&fattr, inode->i_sb);
+		rc = 0;
+	}
+
+	cifs_fattr_to_inode(inode, &fattr);
+	FreeXid(xid);
+	return rc;
+}
+
 int cifs_get_inode_info_unix(struct inode **pinode,
 			     const unsigned char *full_path,
 			     struct super_block *sb, int xid)
@@ -366,7 +430,7 @@ static int cifs_sfu_mode(struct cifs_fat
 	char ea_value[4];
 	__u32 mode;
 
-	rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS",
+	rc = CIFSSMBQAllEAs(xid, cifs_sb->tcon, path, "SETFILEBITS",
 			    ea_value, 4 /* size of buf */, cifs_sb->local_nls,
 			    cifs_sb->mnt_cifs_flags &
 				CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -431,6 +495,47 @@ cifs_all_info_to_fattr(struct cifs_fattr
 	fattr->cf_gid = cifs_sb->mnt_gid;
 }
 
+int cifs_get_file_info(struct file *filp)
+{
+	int rc;
+	int xid;
+	FILE_ALL_INFO find_data;
+	struct cifs_fattr fattr;
+	struct inode *inode = filp->f_path.dentry->d_inode;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+	struct cifsTconInfo *tcon = cifs_sb->tcon;
+	struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
+
+	xid = GetXid();
+	rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
+	if (rc == -EOPNOTSUPP || rc == -EINVAL) {
+		/*
+		 * FIXME: legacy server -- fall back to path-based call?
+		 * for now, just skip revalidating and mark inode for
+		 * immediate reval.
+		 */
+		rc = 0;
+		CIFS_I(inode)->time = 0;
+		goto cgfi_exit;
+	} else if (rc == -EREMOTE) {
+		cifs_create_dfs_fattr(&fattr, inode->i_sb);
+		rc = 0;
+	} else if (rc)
+		goto cgfi_exit;
+
+	/*
+	 * don't bother with SFU junk here -- just mark inode as needing
+	 * revalidation.
+	 */
+	cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false);
+	fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
+	fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
+	cifs_fattr_to_inode(inode, &fattr);
+cgfi_exit:
+	FreeXid(xid);
+	return rc;
+}
+
 int cifs_get_inode_info(struct inode **pinode,
 	const unsigned char *full_path, FILE_ALL_INFO *pfindData,
 	struct super_block *sb, int xid, const __u16 *pfid)
@@ -610,6 +715,16 @@ cifs_find_inode(struct inode *inode, voi
 	if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
 		return 0;
 
+	/*
+	 * uh oh -- it's a directory. We can't use it since hardlinked dirs are
+	 * verboten. Disable serverino and return it as if it were found, the
+	 * caller can discard it, generate a uniqueid and retry the find
+	 */
+	if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry)) {
+		fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
+		cifs_autodisable_serverino(CIFS_SB(inode->i_sb));
+	}
+
 	return 1;
 }
 
@@ -629,15 +744,22 @@ cifs_iget(struct super_block *sb, struct
 	unsigned long hash;
 	struct inode *inode;
 
+retry_iget5_locked:
 	cFYI(1, ("looking for uniqueid=%llu", fattr->cf_uniqueid));
 
 	/* hash down to 32-bits on 32-bit arch */
 	hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
 
 	inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
-
-	/* we have fattrs in hand, update the inode */
 	if (inode) {
+		/* was there a problematic inode number collision? */
+		if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) {
+			iput(inode);
+			fattr->cf_uniqueid = iunique(sb, ROOT_I);
+			fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION;
+			goto retry_iget5_locked;
+		}
+
 		cifs_fattr_to_inode(inode, fattr);
 		if (sb->s_flags & MS_NOATIME)
 			inode->i_flags |= S_NOATIME | S_NOCMTIME;
@@ -1388,135 +1510,103 @@ cifs_rename_exit:
 	return rc;
 }
 
-int cifs_revalidate(struct dentry *direntry)
+static bool
+cifs_inode_needs_reval(struct inode *inode)
 {
-	int xid;
-	int rc = 0, wbrc = 0;
-	char *full_path;
-	struct cifs_sb_info *cifs_sb;
-	struct cifsInodeInfo *cifsInode;
-	loff_t local_size;
-	struct timespec local_mtime;
-	bool invalidate_inode = false;
+	struct cifsInodeInfo *cifs_i = CIFS_I(inode);
 
-	if (direntry->d_inode == NULL)
-		return -ENOENT;
+	if (cifs_i->clientCanCacheRead)
+		return false;
 
-	cifsInode = CIFS_I(direntry->d_inode);
+	if (!lookupCacheEnabled)
+		return true;
 
-	if (cifsInode == NULL)
-		return -ENOENT;
+	if (cifs_i->time == 0)
+		return true;
 
-	/* no sense revalidating inode info on file that no one can write */
-	if (CIFS_I(direntry->d_inode)->clientCanCacheRead)
-		return rc;
+	/* FIXME: the actimeo should be tunable */
+	if (time_after_eq(jiffies, cifs_i->time + HZ))
+		return true;
+
+	return false;
+}
+
+/* check invalid_mapping flag and zap the cache if it's set */
+static void
+cifs_invalidate_mapping(struct inode *inode)
+{
+	int rc;
+	struct cifsInodeInfo *cifs_i = CIFS_I(inode);
+
+	cifs_i->invalid_mapping = false;
+
+	/* write back any cached data */
+	if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
+		rc = filemap_write_and_wait(inode->i_mapping);
+		if (rc)
+			cifs_i->write_behind_rc = rc;
+	}
+	invalidate_remote_inode(inode);
+}
+
+int cifs_revalidate_file(struct file *filp)
+{
+	int rc = 0;
+	struct inode *inode = filp->f_path.dentry->d_inode;
+
+	if (!cifs_inode_needs_reval(inode))
+		goto check_inval;
+
+	if (CIFS_SB(inode->i_sb)->tcon->unix_ext)
+		rc = cifs_get_file_info_unix(filp);
+	else
+		rc = cifs_get_file_info(filp);
+
+check_inval:
+	if (CIFS_I(inode)->invalid_mapping)
+		cifs_invalidate_mapping(inode);
+
+	return rc;
+}
+
+/* revalidate a dentry's inode attributes */
+int cifs_revalidate_dentry(struct dentry *dentry)
+{
+	int xid;
+	int rc = 0;
+	char *full_path = NULL;
+	struct inode *inode = dentry->d_inode;
+	struct super_block *sb = dentry->d_sb;
+
+	if (inode == NULL)
+		return -ENOENT;
 
 	xid = GetXid();
 
-	cifs_sb = CIFS_SB(direntry->d_sb);
+	if (!cifs_inode_needs_reval(inode))
+		goto check_inval;
 
 	/* can not safely grab the rename sem here if rename calls revalidate
 	   since that would deadlock */
-	full_path = build_path_from_dentry(direntry);
+	full_path = build_path_from_dentry(dentry);
 	if (full_path == NULL) {
 		rc = -ENOMEM;
-		FreeXid(xid);
-		return rc;
-	}
-	cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
-		 "jiffies %ld", full_path, direntry->d_inode,
-		 direntry->d_inode->i_count.counter, direntry,
-		 direntry->d_time, jiffies));
-
-	if (cifsInode->time == 0) {
-		/* was set to zero previously to force revalidate */
-	} else if (time_before(jiffies, cifsInode->time + HZ) &&
-		   lookupCacheEnabled) {
-		if ((S_ISREG(direntry->d_inode->i_mode) == 0) ||
-		    (direntry->d_inode->i_nlink == 1)) {
-			kfree(full_path);
-			FreeXid(xid);
-			return rc;
-		} else {
-			cFYI(1, ("Have to revalidate file due to hardlinks"));
-		}
-	}
-
-	/* save mtime and size */
-	local_mtime = direntry->d_inode->i_mtime;
-	local_size = direntry->d_inode->i_size;
-
-	if (cifs_sb->tcon->unix_ext) {
-		rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path,
-					      direntry->d_sb, xid);
-		if (rc) {
-			cFYI(1, ("error on getting revalidate info %d", rc));
-/*			if (rc != -ENOENT)
-				rc = 0; */	/* BB should we cache info on
-						   certain errors? */
-		}
-	} else {
-		rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
-					 direntry->d_sb, xid, NULL);
-		if (rc) {
-			cFYI(1, ("error on getting revalidate info %d", rc));
-/*			if (rc != -ENOENT)
-				rc = 0; */	/* BB should we cache info on
-						   certain errors? */
-		}
+		goto check_inval;
 	}
-	/* should we remap certain errors, access denied?, to zero */
 
-	/* if not oplocked, we invalidate inode pages if mtime or file size
-	   had changed on server */
+	cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
+		 "jiffies %ld", full_path, inode, inode->i_count.counter,
+		 dentry, dentry->d_time, jiffies));
 
-	if (timespec_equal(&local_mtime, &direntry->d_inode->i_mtime) &&
-	    (local_size == direntry->d_inode->i_size)) {
-		cFYI(1, ("cifs_revalidate - inode unchanged"));
-	} else {
-		/* file may have changed on server */
-		if (cifsInode->clientCanCacheRead) {
-			/* no need to invalidate inode pages since we were the
-			   only ones who could have modified the file and the
-			   server copy is staler than ours */
-		} else {
-			invalidate_inode = true;
-		}
-	}
+	if (CIFS_SB(sb)->tcon->unix_ext)
+		rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
+	else
+		rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
+					 xid, NULL);
 
-	/* can not grab this sem since kernel filesys locking documentation
-	   indicates i_mutex may be taken by the kernel on lookup and rename
-	   which could deadlock if we grab the i_mutex here as well */
-/*	mutex_lock(&direntry->d_inode->i_mutex);*/
-	/* need to write out dirty pages here  */
-	if (direntry->d_inode->i_mapping) {
-		/* do we need to lock inode until after invalidate completes
-		   below? */
-		wbrc = filemap_fdatawrite(direntry->d_inode->i_mapping);
-		if (wbrc)
-			CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
-	}
-	if (invalidate_inode) {
-	/* shrink_dcache not necessary now that cifs dentry ops
-	are exported for negative dentries */
-/*		if (S_ISDIR(direntry->d_inode->i_mode))
-			shrink_dcache_parent(direntry); */
-		if (S_ISREG(direntry->d_inode->i_mode)) {
-			if (direntry->d_inode->i_mapping) {
-				wbrc = filemap_fdatawait(direntry->d_inode->i_mapping);
-				if (wbrc)
-					CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
-			}
-			/* may eventually have to do this for open files too */
-			if (list_empty(&(cifsInode->openFileList))) {
-				/* changed on server - flush read ahead pages */
-				cFYI(1, ("Invalidating read ahead data on "
-					 "closed file"));
-				invalidate_remote_inode(direntry->d_inode);
-			}
-		}
-	}
-/*	mutex_unlock(&direntry->d_inode->i_mutex); */
+check_inval:
+	if (CIFS_I(inode)->invalid_mapping)
+		cifs_invalidate_mapping(inode);
 
 	kfree(full_path);
 	FreeXid(xid);
@@ -1526,7 +1616,7 @@ int cifs_revalidate(struct dentry *diren
 int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
 	struct kstat *stat)
 {
-	int err = cifs_revalidate(dentry);
+	int err = cifs_revalidate_dentry(dentry);
 	if (!err) {
 		generic_fillattr(dentry->d_inode, stat);
 		stat->blksize = CIFS_MAX_MSGSIZE;
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/link.c linux-libre-2.6.34-gnu1/fs/cifs/link.c
--- linux-libre-2.6.33-gnu1/fs/cifs/link.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/link.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  */
 #include <linux/fs.h>
 #include <linux/stat.h>
+#include <linux/slab.h>
 #include <linux/namei.h>
 #include "cifsfs.h"
 #include "cifspdu.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/misc.c linux-libre-2.6.34-gnu1/fs/cifs/misc.c
--- linux-libre-2.6.33-gnu1/fs/cifs/misc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/misc.c	2010-05-16 17:17:36.000000000 -0400
@@ -79,7 +79,7 @@ sesInfoAlloc(void)
 		++ret_buf->ses_count;
 		INIT_LIST_HEAD(&ret_buf->smb_ses_list);
 		INIT_LIST_HEAD(&ret_buf->tcon_list);
-		init_MUTEX(&ret_buf->sesSem);
+		mutex_init(&ret_buf->session_mutex);
 	}
 	return ret_buf;
 }
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/readdir.c linux-libre-2.6.34-gnu1/fs/cifs/readdir.c
--- linux-libre-2.6.33-gnu1/fs/cifs/readdir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/readdir.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
  */
 #include <linux/fs.h>
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 #include <linux/stat.h>
 #include "cifspdu.h"
 #include "cifsglob.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/sess.c linux-libre-2.6.34-gnu1/fs/cifs/sess.c
--- linux-libre-2.6.33-gnu1/fs/cifs/sess.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/sess.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include "ntlmssp.h"
 #include "nterr.h"
 #include <linux/utsname.h>
+#include <linux/slab.h>
 #include "cifs_spnego.h"
 
 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/smbencrypt.c linux-libre-2.6.34-gnu1/fs/cifs/smbencrypt.c
--- linux-libre-2.6.33-gnu1/fs/cifs/smbencrypt.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/smbencrypt.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/transport.c linux-libre-2.6.34-gnu1/fs/cifs/transport.c
--- linux-libre-2.6.33-gnu1/fs/cifs/transport.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/transport.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/fs.h>
 #include <linux/list.h>
+#include <linux/gfp.h>
 #include <linux/wait.h>
 #include <linux/net.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/cifs/xattr.c linux-libre-2.6.34-gnu1/fs/cifs/xattr.c
--- linux-libre-2.6.33-gnu1/fs/cifs/xattr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/cifs/xattr.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 
 #include <linux/fs.h>
 #include <linux/posix_acl_xattr.h>
+#include <linux/slab.h>
 #include "cifsfs.h"
 #include "cifspdu.h"
 #include "cifsglob.h"
@@ -244,7 +245,7 @@ ssize_t cifs_getxattr(struct dentry *dir
 			/* revalidate/getattr then populate from inode */
 		} /* BB add else when above is implemented */
 		ea_name += 5; /* skip past user. prefix */
-		rc = CIFSSMBQueryEA(xid, pTcon, full_path, ea_name, ea_value,
+		rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value,
 			buf_size, cifs_sb->local_nls,
 			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	} else if (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4) == 0) {
@@ -252,7 +253,7 @@ ssize_t cifs_getxattr(struct dentry *dir
 			goto get_ea_exit;
 
 		ea_name += 4; /* skip past os2. prefix */
-		rc = CIFSSMBQueryEA(xid, pTcon, full_path, ea_name, ea_value,
+		rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value,
 			buf_size, cifs_sb->local_nls,
 			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	} else if (strncmp(ea_name, POSIX_ACL_XATTR_ACCESS,
@@ -364,8 +365,8 @@ ssize_t cifs_listxattr(struct dentry *di
 	/* if proc/fs/cifs/streamstoxattr is set then
 		search server for EAs or streams to
 		returns as xattrs */
-	rc = CIFSSMBQAllEAs(xid, pTcon, full_path, data, buf_size,
-				cifs_sb->local_nls,
+	rc = CIFSSMBQAllEAs(xid, pTcon, full_path, NULL, data,
+				buf_size, cifs_sb->local_nls,
 				cifs_sb->mnt_cifs_flags &
 					CIFS_MOUNT_MAP_SPECIAL_CHR);
 
diff -druNp linux-libre-2.6.33-gnu1/fs/coda/dir.c linux-libre-2.6.34-gnu1/fs/coda/dir.c
--- linux-libre-2.6.33-gnu1/fs/coda/dir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/coda/dir.c	2010-05-16 17:17:36.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/time.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/file.h>
 #include <linux/stat.h>
 #include <linux/errno.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/coda/file.c linux-libre-2.6.34-gnu1/fs/coda/file.c
--- linux-libre-2.6.33-gnu1/fs/coda/file.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/coda/file.c	2010-05-16 17:17:36.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/smp_lock.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 #include <linux/coda.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/coda/inode.c linux-libre-2.6.34-gnu1/fs/coda/inode.c
--- linux-libre-2.6.33-gnu1/fs/coda/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/coda/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/smp_lock.h>
 #include <linux/file.h>
 #include <linux/vfs.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -166,6 +167,10 @@ static int coda_fill_super(struct super_
 		return -EBUSY;
 	}
 
+	error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY);
+	if (error)
+		goto bdi_err;
+
 	vc->vc_sb = sb;
 
 	sb->s_fs_info = vc;
@@ -174,6 +179,7 @@ static int coda_fill_super(struct super_
 	sb->s_blocksize_bits = 12;
 	sb->s_magic = CODA_SUPER_MAGIC;
 	sb->s_op = &coda_super_operations;
+	sb->s_bdi = &vc->bdi;
 
 	/* get root fid from Venus: this needs the root inode */
 	error = venus_rootfid(sb, &fid);
@@ -199,6 +205,8 @@ static int coda_fill_super(struct super_
         return 0;
 
  error:
+	bdi_destroy(&vc->bdi);
+ bdi_err:
 	if (root)
 		iput(root);
 	if (vc)
@@ -209,6 +217,7 @@ static int coda_fill_super(struct super_
 
 static void coda_put_super(struct super_block *sb)
 {
+	bdi_destroy(&coda_vcp(sb)->bdi);
 	coda_vcp(sb)->vc_sb = NULL;
 	sb->s_fs_info = NULL;
 
diff -druNp linux-libre-2.6.33-gnu1/fs/coda/upcall.c linux-libre-2.6.34-gnu1/fs/coda/upcall.c
--- linux-libre-2.6.33-gnu1/fs/coda/upcall.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/coda/upcall.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/stat.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/vmalloc.h>
 #include <linux/vfs.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/compat_binfmt_elf.c linux-libre-2.6.34-gnu1/fs/compat_binfmt_elf.c
--- linux-libre-2.6.33-gnu1/fs/compat_binfmt_elf.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/compat_binfmt_elf.c	2010-05-16 17:17:36.000000000 -0400
@@ -28,10 +28,12 @@
 
 #undef	elfhdr
 #undef	elf_phdr
+#undef	elf_shdr
 #undef	elf_note
 #undef	elf_addr_t
 #define elfhdr		elf32_hdr
 #define elf_phdr	elf32_phdr
+#define elf_shdr	elf32_shdr
 #define elf_note	elf32_note
 #define elf_addr_t	Elf32_Addr
 
diff -druNp linux-libre-2.6.33-gnu1/fs/compat.c linux-libre-2.6.34-gnu1/fs/compat.c
--- linux-libre-2.6.33-gnu1/fs/compat.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/compat.c	2010-05-16 17:17:36.000000000 -0400
@@ -49,6 +49,7 @@
 #include <linux/mm.h>
 #include <linux/eventpoll.h>
 #include <linux/fs_struct.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -1530,8 +1531,6 @@ int compat_do_execve(char * filename,
 	if (retval < 0)
 		goto out;
 
-	current->stack_start = current->mm->start_stack;
-
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
@@ -1795,6 +1794,24 @@ asmlinkage long compat_sys_select(int n,
 	return ret;
 }
 
+struct compat_sel_arg_struct {
+	compat_ulong_t n;
+	compat_uptr_t inp;
+	compat_uptr_t outp;
+	compat_uptr_t exp;
+	compat_uptr_t tvp;
+};
+
+asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg)
+{
+	struct compat_sel_arg_struct a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+	return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
+				 compat_ptr(a.exp), compat_ptr(a.tvp));
+}
+
 #ifdef HAVE_SET_RESTORE_SIGMASK
 static long do_compat_pselect(int n, compat_ulong_t __user *inp,
 	compat_ulong_t __user *outp, compat_ulong_t __user *exp,
diff -druNp linux-libre-2.6.33-gnu1/fs/compat_ioctl.c linux-libre-2.6.34-gnu1/fs/compat_ioctl.c
--- linux-libre-2.6.33-gnu1/fs/compat_ioctl.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/compat_ioctl.c	2010-05-16 17:17:36.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/ioctl.h>
 #include <linux/if.h>
 #include <linux/if_bridge.h>
-#include <linux/slab.h>
 #include <linux/raid/md_u.h>
 #include <linux/kd.h>
 #include <linux/route.h>
@@ -60,6 +59,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c-dev.h>
 #include <linux/atalk.h>
+#include <linux/gfp.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci.h>
@@ -102,7 +102,6 @@
 #include <linux/nbd.h>
 #include <linux/random.h>
 #include <linux/filter.h>
-#include <linux/pktcdvd.h>
 
 #include <linux/hiddev.h>
 
@@ -545,7 +544,7 @@ static int mt_ioctl_trans(unsigned int f
 		kcmd = MTIOCPOS;
 		karg = &pos;
 		break;
-	case MTIOCGET32:
+	default:	/* MTIOCGET32 */
 		kcmd = MTIOCGET;
 		karg = &get;
 		break;
@@ -663,7 +662,7 @@ static int raw_ioctl(unsigned fd, unsign
 
         switch (cmd) {
         case RAW_SETBIND:
-        case RAW_GETBIND: {
+	default: {	/* RAW_GETBIND */
                 struct raw_config_request req;
                 mm_segment_t oldfs = get_fs();
 
@@ -1126,8 +1125,6 @@ COMPATIBLE_IOCTL(PPGETMODE)
 COMPATIBLE_IOCTL(PPGETPHASE)
 COMPATIBLE_IOCTL(PPGETFLAGS)
 COMPATIBLE_IOCTL(PPSETFLAGS)
-/* pktcdvd */
-COMPATIBLE_IOCTL(PACKET_CTRL_CMD)
 /* Big A */
 /* sparc only */
 /* Big Q for sound/OSS */
diff -druNp linux-libre-2.6.33-gnu1/fs/configfs/dir.c linux-libre-2.6.34-gnu1/fs/configfs/dir.c
--- linux-libre-2.6.33-gnu1/fs/configfs/dir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/configfs/dir.c	2010-05-16 17:17:36.000000000 -0400
@@ -645,6 +645,7 @@ static void detach_groups(struct config_
 
 		configfs_detach_group(sd->s_element);
 		child->d_inode->i_flags |= S_DEAD;
+		dont_mount(child);
 
 		mutex_unlock(&child->d_inode->i_mutex);
 
@@ -840,6 +841,7 @@ static int configfs_attach_item(struct c
 			mutex_lock(&dentry->d_inode->i_mutex);
 			configfs_remove_dir(item);
 			dentry->d_inode->i_flags |= S_DEAD;
+			dont_mount(dentry);
 			mutex_unlock(&dentry->d_inode->i_mutex);
 			d_delete(dentry);
 		}
@@ -882,6 +884,7 @@ static int configfs_attach_group(struct
 		if (ret) {
 			configfs_detach_item(item);
 			dentry->d_inode->i_flags |= S_DEAD;
+			dont_mount(dentry);
 		}
 		configfs_adjust_dir_dirent_depth_after_populate(sd);
 		mutex_unlock(&dentry->d_inode->i_mutex);
@@ -1725,6 +1728,7 @@ void configfs_unregister_subsystem(struc
 	mutex_unlock(&configfs_symlink_mutex);
 	configfs_detach_group(&group->cg_item);
 	dentry->d_inode->i_flags |= S_DEAD;
+	dont_mount(dentry);
 	mutex_unlock(&dentry->d_inode->i_mutex);
 
 	d_delete(dentry);
diff -druNp linux-libre-2.6.33-gnu1/fs/configfs/inode.c linux-libre-2.6.34-gnu1/fs/configfs/inode.c
--- linux-libre-2.6.33-gnu1/fs/configfs/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/configfs/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/capability.h>
 #include <linux/sched.h>
 #include <linux/lockdep.h>
+#include <linux/slab.h>
 
 #include <linux/configfs.h>
 #include "configfs_internal.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/configfs/mount.c linux-libre-2.6.34-gnu1/fs/configfs/mount.c
--- linux-libre-2.6.33-gnu1/fs/configfs/mount.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/configfs/mount.c	2010-05-16 17:17:36.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/mount.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include <linux/configfs.h>
 #include "configfs_internal.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/configfs/symlink.c linux-libre-2.6.34-gnu1/fs/configfs/symlink.c
--- linux-libre-2.6.33-gnu1/fs/configfs/symlink.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/configfs/symlink.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/fs.h>
 #include <linux/module.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
 
 #include <linux/configfs.h>
 #include "configfs_internal.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/dcache.c linux-libre-2.6.34-gnu1/fs/dcache.c
--- linux-libre-2.6.33-gnu1/fs/dcache.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/dcache.c	2010-05-16 17:17:36.000000000 -0400
@@ -257,6 +257,7 @@ kill_it:
 	if (dentry)
 		goto repeat;
 }
+EXPORT_SYMBOL(dput);
 
 /**
  * d_invalidate - invalidate a dentry
@@ -314,6 +315,7 @@ int d_invalidate(struct dentry * dentry)
 	spin_unlock(&dcache_lock);
 	return 0;
 }
+EXPORT_SYMBOL(d_invalidate);
 
 /* This should be called _only_ with dcache_lock held */
 
@@ -328,6 +330,7 @@ struct dentry * dget_locked(struct dentr
 {
 	return __dget_locked(dentry);
 }
+EXPORT_SYMBOL(dget_locked);
 
 /**
  * d_find_alias - grab a hashed alias of inode
@@ -384,6 +387,7 @@ struct dentry * d_find_alias(struct inod
 	}
 	return de;
 }
+EXPORT_SYMBOL(d_find_alias);
 
 /*
  *	Try to kill dentries associated with this inode.
@@ -408,6 +412,7 @@ restart:
 	}
 	spin_unlock(&dcache_lock);
 }
+EXPORT_SYMBOL(d_prune_aliases);
 
 /*
  * Throw away a dentry - free the inode, dput the parent.  This requires that
@@ -610,6 +615,7 @@ void shrink_dcache_sb(struct super_block
 {
 	__shrink_dcache_sb(sb, NULL, 0);
 }
+EXPORT_SYMBOL(shrink_dcache_sb);
 
 /*
  * destroy a single subtree of dentries for unmount
@@ -792,6 +798,7 @@ positive:
 	spin_unlock(&dcache_lock);
 	return 1;
 }
+EXPORT_SYMBOL(have_submounts);
 
 /*
  * Search the dentry child list for the specified parent,
@@ -876,6 +883,7 @@ void shrink_dcache_parent(struct dentry
 	while ((found = select_parent(parent)) != 0)
 		__shrink_dcache_sb(sb, &found, 0);
 }
+EXPORT_SYMBOL(shrink_dcache_parent);
 
 /*
  * Scan `nr' dentries and return the number which remain.
@@ -968,6 +976,7 @@ struct dentry *d_alloc(struct dentry * p
 
 	return dentry;
 }
+EXPORT_SYMBOL(d_alloc);
 
 struct dentry *d_alloc_name(struct dentry *parent, const char *name)
 {
@@ -1012,6 +1021,7 @@ void d_instantiate(struct dentry *entry,
 	spin_unlock(&dcache_lock);
 	security_d_instantiate(entry, inode);
 }
+EXPORT_SYMBOL(d_instantiate);
 
 /**
  * d_instantiate_unique - instantiate a non-aliased dentry
@@ -1108,6 +1118,7 @@ struct dentry * d_alloc_root(struct inod
 	}
 	return res;
 }
+EXPORT_SYMBOL(d_alloc_root);
 
 static inline struct hlist_head *d_hash(struct dentry *parent,
 					unsigned long hash)
@@ -1211,7 +1222,6 @@ struct dentry *d_splice_alias(struct ino
 			BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
 			spin_unlock(&dcache_lock);
 			security_d_instantiate(new, inode);
-			d_rehash(dentry);
 			d_move(new, dentry);
 			iput(inode);
 		} else {
@@ -1225,6 +1235,7 @@ struct dentry *d_splice_alias(struct ino
 		d_add(dentry, inode);
 	return new;
 }
+EXPORT_SYMBOL(d_splice_alias);
 
 /**
  * d_add_ci - lookup or allocate new dentry with case-exact name
@@ -1314,6 +1325,7 @@ err_out:
 	iput(inode);
 	return ERR_PTR(error);
 }
+EXPORT_SYMBOL(d_add_ci);
 
 /**
  * d_lookup - search for a dentry
@@ -1357,6 +1369,7 @@ struct dentry * d_lookup(struct dentry *
 	} while (read_seqretry(&rename_lock, seq));
 	return dentry;
 }
+EXPORT_SYMBOL(d_lookup);
 
 struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
 {
@@ -1483,6 +1496,7 @@ int d_validate(struct dentry *dentry, st
 out:
 	return 0;
 }
+EXPORT_SYMBOL(d_validate);
 
 /*
  * When a file is deleted, we have two options:
@@ -1528,6 +1542,7 @@ void d_delete(struct dentry * dentry)
 
 	fsnotify_nameremove(dentry, isdir);
 }
+EXPORT_SYMBOL(d_delete);
 
 static void __d_rehash(struct dentry * entry, struct hlist_head *list)
 {
@@ -1556,6 +1571,7 @@ void d_rehash(struct dentry * entry)
 	spin_unlock(&entry->d_lock);
 	spin_unlock(&dcache_lock);
 }
+EXPORT_SYMBOL(d_rehash);
 
 /*
  * When switching names, the actual string doesn't strictly have to
@@ -1702,6 +1718,7 @@ void d_move(struct dentry * dentry, stru
 	d_move_locked(dentry, target);
 	spin_unlock(&dcache_lock);
 }
+EXPORT_SYMBOL(d_move);
 
 /**
  * d_ancestor - search for an ancestor
@@ -1868,6 +1885,7 @@ shouldnt_be_hashed:
 	spin_unlock(&dcache_lock);
 	BUG();
 }
+EXPORT_SYMBOL_GPL(d_materialise_unique);
 
 static int prepend(char **buffer, int *buflen, const char *str, int namelen)
 {
@@ -2005,6 +2023,7 @@ char *d_path(const struct path *path, ch
 	path_put(&root);
 	return res;
 }
+EXPORT_SYMBOL(d_path);
 
 /*
  * Helper function for dentry_operations.d_dname() members
@@ -2171,6 +2190,30 @@ int is_subdir(struct dentry *new_dentry,
 	return result;
 }
 
+int path_is_under(struct path *path1, struct path *path2)
+{
+	struct vfsmount *mnt = path1->mnt;
+	struct dentry *dentry = path1->dentry;
+	int res;
+	spin_lock(&vfsmount_lock);
+	if (mnt != path2->mnt) {
+		for (;;) {
+			if (mnt->mnt_parent == mnt) {
+				spin_unlock(&vfsmount_lock);
+				return 0;
+			}
+			if (mnt->mnt_parent == path2->mnt)
+				break;
+			mnt = mnt->mnt_parent;
+		}
+		dentry = mnt->mnt_mountpoint;
+	}
+	res = is_subdir(dentry, path2->dentry);
+	spin_unlock(&vfsmount_lock);
+	return res;
+}
+EXPORT_SYMBOL(path_is_under);
+
 void d_genocide(struct dentry *root)
 {
 	struct dentry *this_parent = root;
@@ -2228,6 +2271,7 @@ ino_t find_inode_number(struct dentry *d
 	}
 	return ino;
 }
+EXPORT_SYMBOL(find_inode_number);
 
 static __initdata unsigned long dhash_entries;
 static int __init set_dhash_entries(char *str)
@@ -2297,6 +2341,7 @@ static void __init dcache_init(void)
 
 /* SLAB cache for __getname() consumers */
 struct kmem_cache *names_cachep __read_mostly;
+EXPORT_SYMBOL(names_cachep);
 
 EXPORT_SYMBOL(d_genocide);
 
@@ -2326,26 +2371,3 @@ void __init vfs_caches_init(unsigned lon
 	bdev_cache_init();
 	chrdev_init();
 }
-
-EXPORT_SYMBOL(d_alloc);
-EXPORT_SYMBOL(d_alloc_root);
-EXPORT_SYMBOL(d_delete);
-EXPORT_SYMBOL(d_find_alias);
-EXPORT_SYMBOL(d_instantiate);
-EXPORT_SYMBOL(d_invalidate);
-EXPORT_SYMBOL(d_lookup);
-EXPORT_SYMBOL(d_move);
-EXPORT_SYMBOL_GPL(d_materialise_unique);
-EXPORT_SYMBOL(d_path);
-EXPORT_SYMBOL(d_prune_aliases);
-EXPORT_SYMBOL(d_rehash);
-EXPORT_SYMBOL(d_splice_alias);
-EXPORT_SYMBOL(d_add_ci);
-EXPORT_SYMBOL(d_validate);
-EXPORT_SYMBOL(dget_locked);
-EXPORT_SYMBOL(dput);
-EXPORT_SYMBOL(find_inode_number);
-EXPORT_SYMBOL(have_submounts);
-EXPORT_SYMBOL(names_cachep);
-EXPORT_SYMBOL(shrink_dcache_parent);
-EXPORT_SYMBOL(shrink_dcache_sb);
diff -druNp linux-libre-2.6.33-gnu1/fs/debugfs/inode.c linux-libre-2.6.34-gnu1/fs/debugfs/inode.c
--- linux-libre-2.6.33-gnu1/fs/debugfs/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/debugfs/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/fsnotify.h>
 #include <linux/string.h>
 #include <linux/magic.h>
+#include <linux/slab.h>
 
 static struct vfsmount *debugfs_mount;
 static int debugfs_mount_count;
@@ -496,7 +497,7 @@ struct dentry *debugfs_rename(struct den
 	}
 	d_move(old_dentry, dentry);
 	fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
-		old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode),
+		S_ISDIR(old_dentry->d_inode->i_mode),
 		NULL, old_dentry);
 	fsnotify_oldname_free(old_name);
 	unlock_rename(new_dir, old_dir);
diff -druNp linux-libre-2.6.33-gnu1/fs/devpts/inode.c linux-libre-2.6.34-gnu1/fs/devpts/inode.c
--- linux-libre-2.6.33-gnu1/fs/devpts/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/devpts/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
 #include <linux/mount.h>
 #include <linux/tty.h>
 #include <linux/mutex.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/dlm/ast.c linux-libre-2.6.34-gnu1/fs/dlm/ast.c
--- linux-libre-2.6.33-gnu1/fs/dlm/ast.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/dlm/ast.c	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2010 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -33,10 +33,10 @@ void dlm_del_ast(struct dlm_lkb *lkb)
 	spin_unlock(&ast_queue_lock);
 }
 
-void dlm_add_ast(struct dlm_lkb *lkb, int type, int bastmode)
+void dlm_add_ast(struct dlm_lkb *lkb, int type, int mode)
 {
 	if (lkb->lkb_flags & DLM_IFL_USER) {
-		dlm_user_add_ast(lkb, type, bastmode);
+		dlm_user_add_ast(lkb, type, mode);
 		return;
 	}
 
@@ -44,10 +44,21 @@ void dlm_add_ast(struct dlm_lkb *lkb, in
 	if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) {
 		kref_get(&lkb->lkb_ref);
 		list_add_tail(&lkb->lkb_astqueue, &ast_queue);
+		lkb->lkb_ast_first = type;
 	}
+
+	/* sanity check, this should not happen */
+
+	if ((type == AST_COMP) && (lkb->lkb_ast_type & AST_COMP))
+		log_print("repeat cast %d castmode %d lock %x %s",
+			  mode, lkb->lkb_castmode,
+			  lkb->lkb_id, lkb->lkb_resource->res_name);
+
 	lkb->lkb_ast_type |= type;
-	if (bastmode)
-		lkb->lkb_bastmode = bastmode;
+	if (type == AST_BAST)
+		lkb->lkb_bastmode = mode;
+	else
+		lkb->lkb_castmode = mode;
 	spin_unlock(&ast_queue_lock);
 
 	set_bit(WAKE_ASTS, &astd_wakeflags);
@@ -59,9 +70,9 @@ static void process_asts(void)
 	struct dlm_ls *ls = NULL;
 	struct dlm_rsb *r = NULL;
 	struct dlm_lkb *lkb;
-	void (*cast) (void *astparam);
-	void (*bast) (void *astparam, int mode);
-	int type = 0, bastmode;
+	void (*castfn) (void *astparam);
+	void (*bastfn) (void *astparam, int mode);
+	int type, first, bastmode, castmode, do_bast, do_cast, last_castmode;
 
 repeat:
 	spin_lock(&ast_queue_lock);
@@ -75,17 +86,48 @@ repeat:
 		list_del(&lkb->lkb_astqueue);
 		type = lkb->lkb_ast_type;
 		lkb->lkb_ast_type = 0;
+		first = lkb->lkb_ast_first;
+		lkb->lkb_ast_first = 0;
 		bastmode = lkb->lkb_bastmode;
-
+		castmode = lkb->lkb_castmode;
+		castfn = lkb->lkb_astfn;
+		bastfn = lkb->lkb_bastfn;
 		spin_unlock(&ast_queue_lock);
-		cast = lkb->lkb_astfn;
-		bast = lkb->lkb_bastfn;
 
-		if ((type & AST_COMP) && cast)
-			cast(lkb->lkb_astparam);
+		do_cast = (type & AST_COMP) && castfn;
+		do_bast = (type & AST_BAST) && bastfn;
 
-		if ((type & AST_BAST) && bast)
-			bast(lkb->lkb_astparam, bastmode);
+		/* Skip a bast if its blocking mode is compatible with the
+		   granted mode of the preceding cast. */
+
+		if (do_bast) {
+			if (first == AST_COMP)
+				last_castmode = castmode;
+			else
+				last_castmode = lkb->lkb_castmode_done;
+			if (dlm_modes_compat(bastmode, last_castmode))
+				do_bast = 0;
+		}
+
+		if (first == AST_COMP) {
+			if (do_cast)
+				castfn(lkb->lkb_astparam);
+			if (do_bast)
+				bastfn(lkb->lkb_astparam, bastmode);
+		} else if (first == AST_BAST) {
+			if (do_bast)
+				bastfn(lkb->lkb_astparam, bastmode);
+			if (do_cast)
+				castfn(lkb->lkb_astparam);
+		} else {
+			log_error(ls, "bad ast_first %d ast_type %d",
+				  first, type);
+		}
+
+		if (do_cast)
+			lkb->lkb_castmode_done = castmode;
+		if (do_bast)
+			lkb->lkb_bastmode_done = bastmode;
 
 		/* this removes the reference added by dlm_add_ast
 		   and may result in the lkb being freed */
diff -druNp linux-libre-2.6.33-gnu1/fs/dlm/ast.h linux-libre-2.6.34-gnu1/fs/dlm/ast.h
--- linux-libre-2.6.33-gnu1/fs/dlm/ast.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/dlm/ast.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2005-2008 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2010 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -13,7 +13,7 @@
 #ifndef __ASTD_DOT_H__
 #define __ASTD_DOT_H__
 
-void dlm_add_ast(struct dlm_lkb *lkb, int type, int bastmode);
+void dlm_add_ast(struct dlm_lkb *lkb, int type, int mode);
 void dlm_del_ast(struct dlm_lkb *lkb);
 
 void dlm_astd_wake(void);
diff -druNp linux-libre-2.6.33-gnu1/fs/dlm/config.c linux-libre-2.6.34-gnu1/fs/dlm/config.c
--- linux-libre-2.6.33-gnu1/fs/dlm/config.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/dlm/config.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/configfs.h>
+#include <linux/slab.h>
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <net/ipv6.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/dlm/debug_fs.c linux-libre-2.6.34-gnu1/fs/dlm/debug_fs.c
--- linux-libre-2.6.33-gnu1/fs/dlm/debug_fs.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/dlm/debug_fs.c	2010-05-16 17:17:36.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/ctype.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 #include "dlm_internal.h"
 #include "lock.h"
@@ -256,7 +257,7 @@ static int print_format3_lock(struct seq
 			lkb->lkb_status,
 			lkb->lkb_grmode,
 			lkb->lkb_rqmode,
-			lkb->lkb_highbast,
+			lkb->lkb_bastmode,
 			rsb_lookup,
 			lkb->lkb_wait_type,
 			lkb->lkb_lvbseq,
diff -druNp linux-libre-2.6.33-gnu1/fs/dlm/dlm_internal.h linux-libre-2.6.34-gnu1/fs/dlm/dlm_internal.h
--- linux-libre-2.6.33-gnu1/fs/dlm/dlm_internal.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/dlm/dlm_internal.h	2010-05-16 17:17:36.000000000 -0400
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2010 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -232,11 +232,17 @@ struct dlm_lkb {
 	int8_t			lkb_status;     /* granted, waiting, convert */
 	int8_t			lkb_rqmode;	/* requested lock mode */
 	int8_t			lkb_grmode;	/* granted lock mode */
-	int8_t			lkb_bastmode;	/* requested mode */
 	int8_t			lkb_highbast;	/* highest mode bast sent for */
+
 	int8_t			lkb_wait_type;	/* type of reply waiting for */
 	int8_t			lkb_wait_count;
 	int8_t			lkb_ast_type;	/* type of ast queued for */
+	int8_t			lkb_ast_first;	/* type of first ast queued */
+
+	int8_t			lkb_bastmode;	/* req mode of queued bast */
+	int8_t			lkb_castmode;	/* gr mode of queued cast */
+	int8_t			lkb_bastmode_done; /* last delivered bastmode */
+	int8_t			lkb_castmode_done; /* last delivered castmode */
 
 	struct list_head	lkb_idtbl_list;	/* lockspace lkbtbl */
 	struct list_head	lkb_statequeue;	/* rsb g/c/w list */
diff -druNp linux-libre-2.6.33-gnu1/fs/dlm/lock.c linux-libre-2.6.34-gnu1/fs/dlm/lock.c
--- linux-libre-2.6.33-gnu1/fs/dlm/lock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/dlm/lock.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2005-2008 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2010 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -56,6 +56,7 @@
    L: receive_xxxx_reply()     <-  R: send_xxxx_reply()
 */
 #include <linux/types.h>
+#include <linux/slab.h>
 #include "dlm_internal.h"
 #include <linux/dlm_device.h>
 #include "memory.h"
@@ -307,7 +308,7 @@ static void queue_cast(struct dlm_rsb *r
 	lkb->lkb_lksb->sb_status = rv;
 	lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags;
 
-	dlm_add_ast(lkb, AST_COMP, 0);
+	dlm_add_ast(lkb, AST_COMP, lkb->lkb_grmode);
 }
 
 static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb)
@@ -320,10 +321,12 @@ static void queue_bast(struct dlm_rsb *r
 {
 	lkb->lkb_time_bast = ktime_get();
 
-	if (is_master_copy(lkb))
+	if (is_master_copy(lkb)) {
+		lkb->lkb_bastmode = rqmode; /* printed by debugfs */
 		send_bast(r, lkb, rqmode);
-	else
+	} else {
 		dlm_add_ast(lkb, AST_BAST, rqmode);
+	}
 }
 
 /*
@@ -2280,20 +2283,30 @@ static int do_request(struct dlm_rsb *r,
 	if (can_be_queued(lkb)) {
 		error = -EINPROGRESS;
 		add_lkb(r, lkb, DLM_LKSTS_WAITING);
-		send_blocking_asts(r, lkb);
 		add_timeout(lkb);
 		goto out;
 	}
 
 	error = -EAGAIN;
-	if (force_blocking_asts(lkb))
-		send_blocking_asts_all(r, lkb);
 	queue_cast(r, lkb, -EAGAIN);
-
  out:
 	return error;
 }
 
+static void do_request_effects(struct dlm_rsb *r, struct dlm_lkb *lkb,
+			       int error)
+{
+	switch (error) {
+	case -EAGAIN:
+		if (force_blocking_asts(lkb))
+			send_blocking_asts_all(r, lkb);
+		break;
+	case -EINPROGRESS:
+		send_blocking_asts(r, lkb);
+		break;
+	}
+}
+
 static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
 {
 	int error = 0;
@@ -2304,7 +2317,6 @@ static int do_convert(struct dlm_rsb *r,
 	if (can_be_granted(r, lkb, 1, &deadlk)) {
 		grant_lock(r, lkb);
 		queue_cast(r, lkb, 0);
-		grant_pending_locks(r);
 		goto out;
 	}
 
@@ -2334,7 +2346,6 @@ static int do_convert(struct dlm_rsb *r,
 		if (_can_be_granted(r, lkb, 1)) {
 			grant_lock(r, lkb);
 			queue_cast(r, lkb, 0);
-			grant_pending_locks(r);
 			goto out;
 		}
 		/* else fall through and move to convert queue */
@@ -2344,28 +2355,47 @@ static int do_convert(struct dlm_rsb *r,
 		error = -EINPROGRESS;
 		del_lkb(r, lkb);
 		add_lkb(r, lkb, DLM_LKSTS_CONVERT);
-		send_blocking_asts(r, lkb);
 		add_timeout(lkb);
 		goto out;
 	}
 
 	error = -EAGAIN;
-	if (force_blocking_asts(lkb))
-		send_blocking_asts_all(r, lkb);
 	queue_cast(r, lkb, -EAGAIN);
-
  out:
 	return error;
 }
 
+static void do_convert_effects(struct dlm_rsb *r, struct dlm_lkb *lkb,
+			       int error)
+{
+	switch (error) {
+	case 0:
+		grant_pending_locks(r);
+		/* grant_pending_locks also sends basts */
+		break;
+	case -EAGAIN:
+		if (force_blocking_asts(lkb))
+			send_blocking_asts_all(r, lkb);
+		break;
+	case -EINPROGRESS:
+		send_blocking_asts(r, lkb);
+		break;
+	}
+}
+
 static int do_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb)
 {
 	remove_lock(r, lkb);
 	queue_cast(r, lkb, -DLM_EUNLOCK);
-	grant_pending_locks(r);
 	return -DLM_EUNLOCK;
 }
 
+static void do_unlock_effects(struct dlm_rsb *r, struct dlm_lkb *lkb,
+			      int error)
+{
+	grant_pending_locks(r);
+}
+
 /* returns: 0 did nothing, -DLM_ECANCEL canceled lock */
  
 static int do_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb)
@@ -2375,12 +2405,18 @@ static int do_cancel(struct dlm_rsb *r,
 	error = revert_lock(r, lkb);
 	if (error) {
 		queue_cast(r, lkb, -DLM_ECANCEL);
-		grant_pending_locks(r);
 		return -DLM_ECANCEL;
 	}
 	return 0;
 }
 
+static void do_cancel_effects(struct dlm_rsb *r, struct dlm_lkb *lkb,
+			      int error)
+{
+	if (error)
+		grant_pending_locks(r);
+}
+
 /*
  * Four stage 3 varieties:
  * _request_lock(), _convert_lock(), _unlock_lock(), _cancel_lock()
@@ -2402,11 +2438,15 @@ static int _request_lock(struct dlm_rsb
 		goto out;
 	}
 
-	if (is_remote(r))
+	if (is_remote(r)) {
 		/* receive_request() calls do_request() on remote node */
 		error = send_request(r, lkb);
-	else
+	} else {
 		error = do_request(r, lkb);
+		/* for remote locks the request_reply is sent
+		   between do_request and do_request_effects */
+		do_request_effects(r, lkb, error);
+	}
  out:
 	return error;
 }
@@ -2417,11 +2457,15 @@ static int _convert_lock(struct dlm_rsb
 {
 	int error;
 
-	if (is_remote(r))
+	if (is_remote(r)) {
 		/* receive_convert() calls do_convert() on remote node */
 		error = send_convert(r, lkb);
-	else
+	} else {
 		error = do_convert(r, lkb);
+		/* for remote locks the convert_reply is sent
+		   between do_convert and do_convert_effects */
+		do_convert_effects(r, lkb, error);
+	}
 
 	return error;
 }
@@ -2432,11 +2476,15 @@ static int _unlock_lock(struct dlm_rsb *
 {
 	int error;
 
-	if (is_remote(r))
+	if (is_remote(r)) {
 		/* receive_unlock() calls do_unlock() on remote node */
 		error = send_unlock(r, lkb);
-	else
+	} else {
 		error = do_unlock(r, lkb);
+		/* for remote locks the unlock_reply is sent
+		   between do_unlock and do_unlock_effects */
+		do_unlock_effects(r, lkb, error);
+	}
 
 	return error;
 }
@@ -2447,11 +2495,15 @@ static int _cancel_lock(struct dlm_rsb *
 {
 	int error;
 
-	if (is_remote(r))
+	if (is_remote(r)) {
 		/* receive_cancel() calls do_cancel() on remote node */
 		error = send_cancel(r, lkb);
-	else
+	} else {
 		error = do_cancel(r, lkb);
+		/* for remote locks the cancel_reply is sent
+		   between do_cancel and do_cancel_effects */
+		do_cancel_effects(r, lkb, error);
+	}
 
 	return error;
 }
@@ -3191,6 +3243,7 @@ static void receive_request(struct dlm_l
 	attach_lkb(r, lkb);
 	error = do_request(r, lkb);
 	send_request_reply(r, lkb, error);
+	do_request_effects(r, lkb, error);
 
 	unlock_rsb(r);
 	put_rsb(r);
@@ -3226,15 +3279,19 @@ static void receive_convert(struct dlm_l
 		goto out;
 
 	receive_flags(lkb, ms);
+
 	error = receive_convert_args(ls, lkb, ms);
-	if (error)
-		goto out_reply;
+	if (error) {
+		send_convert_reply(r, lkb, error);
+		goto out;
+	}
+
 	reply = !down_conversion(lkb);
 
 	error = do_convert(r, lkb);
- out_reply:
 	if (reply)
 		send_convert_reply(r, lkb, error);
+	do_convert_effects(r, lkb, error);
  out:
 	unlock_rsb(r);
 	put_rsb(r);
@@ -3266,13 +3323,16 @@ static void receive_unlock(struct dlm_ls
 		goto out;
 
 	receive_flags(lkb, ms);
+
 	error = receive_unlock_args(ls, lkb, ms);
-	if (error)
-		goto out_reply;
+	if (error) {
+		send_unlock_reply(r, lkb, error);
+		goto out;
+	}
 
 	error = do_unlock(r, lkb);
- out_reply:
 	send_unlock_reply(r, lkb, error);
+	do_unlock_effects(r, lkb, error);
  out:
 	unlock_rsb(r);
 	put_rsb(r);
@@ -3307,6 +3367,7 @@ static void receive_cancel(struct dlm_ls
 
 	error = do_cancel(r, lkb);
 	send_cancel_reply(r, lkb, error);
+	do_cancel_effects(r, lkb, error);
  out:
 	unlock_rsb(r);
 	put_rsb(r);
diff -druNp linux-libre-2.6.33-gnu1/fs/dlm/lockspace.c linux-libre-2.6.34-gnu1/fs/dlm/lockspace.c
--- linux-libre-2.6.33-gnu1/fs/dlm/lockspace.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/dlm/lockspace.c	2010-05-16 17:17:36.000000000 -0400
@@ -148,7 +148,7 @@ static void lockspace_kobj_release(struc
 	kfree(ls);
 }
 
-static struct sysfs_ops dlm_attr_ops = {
+static const struct sysfs_ops dlm_attr_ops = {
 	.show  = dlm_attr_show,
 	.store = dlm_attr_store,
 };
@@ -191,6 +191,18 @@ static int do_uevent(struct dlm_ls *ls,
 	return error;
 }
 
+static int dlm_uevent(struct kset *kset, struct kobject *kobj,
+		      struct kobj_uevent_env *env)
+{
+	struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj);
+
+	add_uevent_var(env, "LOCKSPACE=%s", ls->ls_name);
+	return 0;
+}
+
+static struct kset_uevent_ops dlm_uevent_ops = {
+	.uevent = dlm_uevent,
+};
 
 int __init dlm_lockspace_init(void)
 {
@@ -199,7 +211,7 @@ int __init dlm_lockspace_init(void)
 	INIT_LIST_HEAD(&lslist);
 	spin_lock_init(&lslist_lock);
 
-	dlm_kset = kset_create_and_add("dlm", NULL, kernel_kobj);
+	dlm_kset = kset_create_and_add("dlm", &dlm_uevent_ops, kernel_kobj);
 	if (!dlm_kset) {
 		printk(KERN_WARNING "%s: can not create kset\n", __func__);
 		return -ENOMEM;
diff -druNp linux-libre-2.6.33-gnu1/fs/dlm/lowcomms.c linux-libre-2.6.34-gnu1/fs/dlm/lowcomms.c
--- linux-libre-2.6.33-gnu1/fs/dlm/lowcomms.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/dlm/lowcomms.c	2010-05-16 17:17:36.000000000 -0400
@@ -51,6 +51,7 @@
 #include <linux/file.h>
 #include <linux/mutex.h>
 #include <linux/sctp.h>
+#include <linux/slab.h>
 #include <net/sctp/user.h>
 #include <net/ipv6.h>
 
diff -druNp linux-libre-2.6.33-gnu1/fs/dlm/member.c linux-libre-2.6.34-gnu1/fs/dlm/member.c
--- linux-libre-2.6.33-gnu1/fs/dlm/member.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/dlm/member.c	2010-05-16 17:17:36.000000000 -0400
@@ -312,7 +312,7 @@ int dlm_ls_stop(struct dlm_ls *ls)
 	/*
 	 * This in_recovery lock does two things:
 	 * 1) Keeps this function from returning until all threads are out
-	 *    of locking routines and locking is truely stopped.
+	 *    of locking routines and locking is truly stopped.
 	 * 2) Keeps any new requests from being processed until it's unlocked
 	 *    when recovery is complete.
 	 */
diff -druNp linux-libre-2.6.33-gnu1/fs/dlm/netlink.c linux-libre-2.6.34-gnu1/fs/dlm/netlink.c
--- linux-libre-2.6.33-gnu1/fs/dlm/netlink.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/dlm/netlink.c	2010-05-16 17:17:36.000000000 -0400
@@ -9,6 +9,7 @@
 #include <net/genetlink.h>
 #include <linux/dlm.h>
 #include <linux/dlm_netlink.h>
+#include <linux/gfp.h>
 
 #include "dlm_internal.h"
 
diff -druNp linux-libre-2.6.33-gnu1/fs/dlm/plock.c linux-libre-2.6.34-gnu1/fs/dlm/plock.c
--- linux-libre-2.6.33-gnu1/fs/dlm/plock.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/dlm/plock.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/poll.h>
 #include <linux/dlm.h>
 #include <linux/dlm_plock.h>
+#include <linux/slab.h>
 
 #include "dlm_internal.h"
 #include "lockspace.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/dlm/user.c linux-libre-2.6.34-gnu1/fs/dlm/user.c
--- linux-libre-2.6.33-gnu1/fs/dlm/user.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/dlm/user.c	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2009 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2006-2010 Red Hat, Inc.  All rights reserved.
  *
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
@@ -17,6 +17,7 @@
 #include <linux/spinlock.h>
 #include <linux/dlm.h>
 #include <linux/dlm_device.h>
+#include <linux/slab.h>
 
 #include "dlm_internal.h"
 #include "lockspace.h"
@@ -173,7 +174,7 @@ static int lkb_is_endoflife(struct dlm_l
 /* we could possibly check if the cancel of an orphan has resulted in the lkb
    being removed and then remove that lkb from the orphans list and free it */
 
-void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode)
+void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int mode)
 {
 	struct dlm_ls *ls;
 	struct dlm_user_args *ua;
@@ -206,8 +207,10 @@ void dlm_user_add_ast(struct dlm_lkb *lk
 
 	ast_type = lkb->lkb_ast_type;
 	lkb->lkb_ast_type |= type;
-	if (bastmode)
-		lkb->lkb_bastmode = bastmode;
+	if (type == AST_BAST)
+		lkb->lkb_bastmode = mode;
+	else
+		lkb->lkb_castmode = mode;
 
 	if (!ast_type) {
 		kref_get(&lkb->lkb_ref);
diff -druNp linux-libre-2.6.33-gnu1/fs/dlm/user.h linux-libre-2.6.34-gnu1/fs/dlm/user.h
--- linux-libre-2.6.33-gnu1/fs/dlm/user.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/dlm/user.h	2010-05-16 17:17:36.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2008 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2006-2010 Red Hat, Inc.  All rights reserved.
  *
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
@@ -9,7 +9,7 @@
 #ifndef __USER_DOT_H__
 #define __USER_DOT_H__
 
-void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode);
+void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int mode);
 int dlm_user_init(void);
 void dlm_user_exit(void);
 int dlm_device_deregister(struct dlm_ls *ls);
diff -druNp linux-libre-2.6.33-gnu1/fs/ecryptfs/crypto.c linux-libre-2.6.34-gnu1/fs/ecryptfs/crypto.c
--- linux-libre-2.6.33-gnu1/fs/ecryptfs/crypto.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ecryptfs/crypto.c	2010-05-16 17:17:36.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/crypto.h>
 #include <linux/file.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include "ecryptfs_kernel.h"
 
@@ -381,8 +382,8 @@ out:
 static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num,
 					     struct ecryptfs_crypt_stat *crypt_stat)
 {
-	(*offset) = (crypt_stat->num_header_bytes_at_front
-		     + (crypt_stat->extent_size * extent_num));
+	(*offset) = ecryptfs_lower_header_size(crypt_stat)
+		    + (crypt_stat->extent_size * extent_num);
 }
 
 /**
@@ -834,13 +835,13 @@ void ecryptfs_set_default_sizes(struct e
 	set_extent_mask_and_shift(crypt_stat);
 	crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES;
 	if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
-		crypt_stat->num_header_bytes_at_front = 0;
+		crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
 	else {
 		if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)
-			crypt_stat->num_header_bytes_at_front =
+			crypt_stat->metadata_size =
 				ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
 		else
-			crypt_stat->num_header_bytes_at_front =	PAGE_CACHE_SIZE;
+			crypt_stat->metadata_size = PAGE_CACHE_SIZE;
 	}
 }
 
@@ -1107,9 +1108,9 @@ static void write_ecryptfs_marker(char *
 	(*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
 }
 
-static void
-write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat,
-		     size_t *written)
+void ecryptfs_write_crypt_stat_flags(char *page_virt,
+				     struct ecryptfs_crypt_stat *crypt_stat,
+				     size_t *written)
 {
 	u32 flags = 0;
 	int i;
@@ -1237,8 +1238,7 @@ ecryptfs_write_header_metadata(char *vir
 
 	header_extent_size = (u32)crypt_stat->extent_size;
 	num_header_extents_at_front =
-		(u16)(crypt_stat->num_header_bytes_at_front
-		      / crypt_stat->extent_size);
+		(u16)(crypt_stat->metadata_size / crypt_stat->extent_size);
 	put_unaligned_be32(header_extent_size, virt);
 	virt += 4;
 	put_unaligned_be16(num_header_extents_at_front, virt);
@@ -1291,7 +1291,8 @@ static int ecryptfs_write_headers_virt(c
 	offset = ECRYPTFS_FILE_SIZE_BYTES;
 	write_ecryptfs_marker((page_virt + offset), &written);
 	offset += written;
-	write_ecryptfs_flags((page_virt + offset), crypt_stat, &written);
+	ecryptfs_write_crypt_stat_flags((page_virt + offset), crypt_stat,
+					&written);
 	offset += written;
 	ecryptfs_write_header_metadata((page_virt + offset), crypt_stat,
 				       &written);
@@ -1381,7 +1382,7 @@ int ecryptfs_write_metadata(struct dentr
 		rc = -EINVAL;
 		goto out;
 	}
-	virt_len = crypt_stat->num_header_bytes_at_front;
+	virt_len = crypt_stat->metadata_size;
 	order = get_order(virt_len);
 	/* Released in this function */
 	virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order);
@@ -1427,16 +1428,15 @@ static int parse_header_metadata(struct
 	header_extent_size = get_unaligned_be32(virt);
 	virt += sizeof(__be32);
 	num_header_extents_at_front = get_unaligned_be16(virt);
-	crypt_stat->num_header_bytes_at_front =
-		(((size_t)num_header_extents_at_front
-		  * (size_t)header_extent_size));
+	crypt_stat->metadata_size = (((size_t)num_header_extents_at_front
+				     * (size_t)header_extent_size));
 	(*bytes_read) = (sizeof(__be32) + sizeof(__be16));
 	if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE)
-	    && (crypt_stat->num_header_bytes_at_front
+	    && (crypt_stat->metadata_size
 		< ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) {
 		rc = -EINVAL;
 		printk(KERN_WARNING "Invalid header size: [%zd]\n",
-		       crypt_stat->num_header_bytes_at_front);
+		       crypt_stat->metadata_size);
 	}
 	return rc;
 }
@@ -1451,8 +1451,7 @@ static int parse_header_metadata(struct
  */
 static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
 {
-	crypt_stat->num_header_bytes_at_front =
-		ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
+	crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
 }
 
 /**
@@ -1606,6 +1605,7 @@ int ecryptfs_read_metadata(struct dentry
 						ecryptfs_dentry,
 						ECRYPTFS_VALIDATE_HEADER_SIZE);
 	if (rc) {
+		memset(page_virt, 0, PAGE_CACHE_SIZE);
 		rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode);
 		if (rc) {
 			printk(KERN_DEBUG "Valid eCryptfs headers not found in "
diff -druNp linux-libre-2.6.33-gnu1/fs/ecryptfs/dentry.c linux-libre-2.6.34-gnu1/fs/ecryptfs/dentry.c
--- linux-libre-2.6.33-gnu1/fs/ecryptfs/dentry.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ecryptfs/dentry.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/namei.h>
 #include <linux/mount.h>
 #include <linux/fs_stack.h>
+#include <linux/slab.h>
 #include "ecryptfs_kernel.h"
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/fs/ecryptfs/ecryptfs_kernel.h linux-libre-2.6.34-gnu1/fs/ecryptfs/ecryptfs_kernel.h
--- linux-libre-2.6.33-gnu1/fs/ecryptfs/ecryptfs_kernel.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ecryptfs/ecryptfs_kernel.h	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/scatterlist.h>
 #include <linux/hash.h>
 #include <linux/nsproxy.h>
+#include <linux/backing-dev.h>
 
 /* Version verification for shared data structures w/ userspace */
 #define ECRYPTFS_VERSION_MAJOR 0x00
@@ -273,7 +274,7 @@ struct ecryptfs_crypt_stat {
 	u32 flags;
 	unsigned int file_version;
 	size_t iv_bytes;
-	size_t num_header_bytes_at_front;
+	size_t metadata_size;
 	size_t extent_size; /* Data extent size; default is 4096 */
 	size_t key_size;
 	size_t extent_shift;
@@ -393,6 +394,7 @@ struct ecryptfs_mount_crypt_stat {
 struct ecryptfs_sb_info {
 	struct super_block *wsi_sb;
 	struct ecryptfs_mount_crypt_stat mount_crypt_stat;
+	struct backing_dev_info bdi;
 };
 
 /* file private data. */
@@ -464,6 +466,14 @@ struct ecryptfs_daemon {
 
 extern struct mutex ecryptfs_daemon_hash_mux;
 
+static inline size_t
+ecryptfs_lower_header_size(struct ecryptfs_crypt_stat *crypt_stat)
+{
+	if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
+		return 0;
+	return crypt_stat->metadata_size;
+}
+
 static inline struct ecryptfs_file_info *
 ecryptfs_file_to_private(struct file *file)
 {
@@ -651,6 +661,9 @@ int ecryptfs_decrypt_page(struct page *p
 int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry);
 int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry);
 int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry);
+void ecryptfs_write_crypt_stat_flags(char *page_virt,
+				     struct ecryptfs_crypt_stat *crypt_stat,
+				     size_t *written);
 int ecryptfs_read_and_validate_header_region(char *data,
 					     struct inode *ecryptfs_inode);
 int ecryptfs_read_and_validate_xattr_region(char *page_virt,
diff -druNp linux-libre-2.6.33-gnu1/fs/ecryptfs/file.c linux-libre-2.6.34-gnu1/fs/ecryptfs/file.c
--- linux-libre-2.6.33-gnu1/fs/ecryptfs/file.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ecryptfs/file.c	2010-05-16 17:17:36.000000000 -0400
@@ -25,6 +25,7 @@
 
 #include <linux/file.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/mount.h>
 #include <linux/pagemap.h>
 #include <linux/security.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/ecryptfs/inode.c linux-libre-2.6.34-gnu1/fs/ecryptfs/inode.c
--- linux-libre-2.6.33-gnu1/fs/ecryptfs/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ecryptfs/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/mount.h>
 #include <linux/crypto.h>
 #include <linux/fs_stack.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include "ecryptfs_kernel.h"
 
@@ -323,6 +324,7 @@ int ecryptfs_lookup_and_interpose_lower(
 	rc = ecryptfs_read_and_validate_header_region(page_virt,
 						      ecryptfs_dentry->d_inode);
 	if (rc) {
+		memset(page_virt, 0, PAGE_CACHE_SIZE);
 		rc = ecryptfs_read_and_validate_xattr_region(page_virt,
 							     ecryptfs_dentry);
 		if (rc) {
@@ -335,7 +337,7 @@ int ecryptfs_lookup_and_interpose_lower(
 		ecryptfs_dentry->d_sb)->mount_crypt_stat;
 	if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
 		if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
-			file_size = (crypt_stat->num_header_bytes_at_front
+			file_size = (crypt_stat->metadata_size
 				     + i_size_read(lower_dentry->d_inode));
 		else
 			file_size = i_size_read(lower_dentry->d_inode);
@@ -387,9 +389,9 @@ static struct dentry *ecryptfs_lookup(st
 	mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
 	if (IS_ERR(lower_dentry)) {
 		rc = PTR_ERR(lower_dentry);
-		printk(KERN_ERR "%s: lookup_one_len() returned [%d] on "
-		       "lower_dentry = [%s]\n", __func__, rc,
-		       ecryptfs_dentry->d_name.name);
+		ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
+				"[%d] on lower_dentry = [%s]\n", __func__, rc,
+				encrypted_and_encoded_name);
 		goto out_d_drop;
 	}
 	if (lower_dentry->d_inode)
@@ -416,9 +418,9 @@ static struct dentry *ecryptfs_lookup(st
 	mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
 	if (IS_ERR(lower_dentry)) {
 		rc = PTR_ERR(lower_dentry);
-		printk(KERN_ERR "%s: lookup_one_len() returned [%d] on "
-		       "lower_dentry = [%s]\n", __func__, rc,
-		       encrypted_and_encoded_name);
+		ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
+				"[%d] on lower_dentry = [%s]\n", __func__, rc,
+				encrypted_and_encoded_name);
 		goto out_d_drop;
 	}
 lookup_and_interpose:
@@ -455,8 +457,8 @@ static int ecryptfs_link(struct dentry *
 	rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
 	if (rc)
 		goto out_lock;
-	fsstack_copy_attr_times(dir, lower_new_dentry->d_inode);
-	fsstack_copy_inode_size(dir, lower_new_dentry->d_inode);
+	fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
+	fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode);
 	old_dentry->d_inode->i_nlink =
 		ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink;
 	i_size_write(new_dentry->d_inode, file_size_save);
@@ -647,38 +649,17 @@ out_lock:
 	return rc;
 }
 
-static int
-ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
+static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf,
+				   size_t *bufsiz)
 {
+	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
 	char *lower_buf;
-	size_t lower_bufsiz;
-	struct dentry *lower_dentry;
-	struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
-	char *plaintext_name;
-	size_t plaintext_name_size;
+	size_t lower_bufsiz = PATH_MAX;
 	mm_segment_t old_fs;
 	int rc;
 
-	lower_dentry = ecryptfs_dentry_to_lower(dentry);
-	if (!lower_dentry->d_inode->i_op->readlink) {
-		rc = -EINVAL;
-		goto out;
-	}
-	mount_crypt_stat = &ecryptfs_superblock_to_private(
-						dentry->d_sb)->mount_crypt_stat;
-	/*
-	 * If the lower filename is encrypted, it will result in a significantly
-	 * longer name.  If needed, truncate the name after decode and decrypt.
-	 */
-	if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)
-		lower_bufsiz = PATH_MAX;
-	else
-		lower_bufsiz = bufsiz;
-	/* Released in this function */
 	lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL);
-	if (lower_buf == NULL) {
-		printk(KERN_ERR "%s: Out of memory whilst attempting to "
-		       "kmalloc [%zd] bytes\n", __func__, lower_bufsiz);
+	if (!lower_buf) {
 		rc = -ENOMEM;
 		goto out;
 	}
@@ -688,29 +669,31 @@ ecryptfs_readlink(struct dentry *dentry,
 						   (char __user *)lower_buf,
 						   lower_bufsiz);
 	set_fs(old_fs);
-	if (rc >= 0) {
-		rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name,
-							  &plaintext_name_size,
-							  dentry, lower_buf,
-							  rc);
-		if (rc) {
-			printk(KERN_ERR "%s: Error attempting to decode and "
-			       "decrypt filename; rc = [%d]\n", __func__,
-				rc);
-			goto out_free_lower_buf;
-		}
-		/* Check for bufsiz <= 0 done in sys_readlinkat() */
-		rc = copy_to_user(buf, plaintext_name,
-				  min((size_t) bufsiz, plaintext_name_size));
-		if (rc)
-			rc = -EFAULT;
-		else
-			rc = plaintext_name_size;
-		kfree(plaintext_name);
-		fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode);
-	}
-out_free_lower_buf:
+	if (rc < 0)
+		goto out;
+	lower_bufsiz = rc;
+	rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry,
+						  lower_buf, lower_bufsiz);
+out:
 	kfree(lower_buf);
+	return rc;
+}
+
+static int
+ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
+{
+	char *kbuf;
+	size_t kbufsiz, copied;
+	int rc;
+
+	rc = ecryptfs_readlink_lower(dentry, &kbuf, &kbufsiz);
+	if (rc)
+		goto out;
+	copied = min_t(size_t, bufsiz, kbufsiz);
+	rc = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied;
+	kfree(kbuf);
+	fsstack_copy_attr_atime(dentry->d_inode,
+				ecryptfs_dentry_to_lower(dentry)->d_inode);
 out:
 	return rc;
 }
@@ -768,7 +751,7 @@ upper_size_to_lower_size(struct ecryptfs
 {
 	loff_t lower_size;
 
-	lower_size = crypt_stat->num_header_bytes_at_front;
+	lower_size = ecryptfs_lower_header_size(crypt_stat);
 	if (upper_size != 0) {
 		loff_t num_extents;
 
@@ -1015,6 +998,28 @@ out:
 	return rc;
 }
 
+int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
+			  struct kstat *stat)
+{
+	struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
+	int rc = 0;
+
+	mount_crypt_stat = &ecryptfs_superblock_to_private(
+						dentry->d_sb)->mount_crypt_stat;
+	generic_fillattr(dentry->d_inode, stat);
+	if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
+		char *target;
+		size_t targetsiz;
+
+		rc = ecryptfs_readlink_lower(dentry, &target, &targetsiz);
+		if (!rc) {
+			kfree(target);
+			stat->size = targetsiz;
+		}
+	}
+	return rc;
+}
+
 int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
 		     struct kstat *stat)
 {
@@ -1039,7 +1044,7 @@ ecryptfs_setxattr(struct dentry *dentry,
 
 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
 	if (!lower_dentry->d_inode->i_op->setxattr) {
-		rc = -ENOSYS;
+		rc = -EOPNOTSUPP;
 		goto out;
 	}
 	mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1057,7 +1062,7 @@ ecryptfs_getxattr_lower(struct dentry *l
 	int rc = 0;
 
 	if (!lower_dentry->d_inode->i_op->getxattr) {
-		rc = -ENOSYS;
+		rc = -EOPNOTSUPP;
 		goto out;
 	}
 	mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1084,7 +1089,7 @@ ecryptfs_listxattr(struct dentry *dentry
 
 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
 	if (!lower_dentry->d_inode->i_op->listxattr) {
-		rc = -ENOSYS;
+		rc = -EOPNOTSUPP;
 		goto out;
 	}
 	mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1101,7 +1106,7 @@ static int ecryptfs_removexattr(struct d
 
 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
 	if (!lower_dentry->d_inode->i_op->removexattr) {
-		rc = -ENOSYS;
+		rc = -EOPNOTSUPP;
 		goto out;
 	}
 	mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1132,6 +1137,7 @@ const struct inode_operations ecryptfs_s
 	.put_link = ecryptfs_put_link,
 	.permission = ecryptfs_permission,
 	.setattr = ecryptfs_setattr,
+	.getattr = ecryptfs_getattr_link,
 	.setxattr = ecryptfs_setxattr,
 	.getxattr = ecryptfs_getxattr,
 	.listxattr = ecryptfs_listxattr,
diff -druNp linux-libre-2.6.33-gnu1/fs/ecryptfs/keystore.c linux-libre-2.6.34-gnu1/fs/ecryptfs/keystore.c
--- linux-libre-2.6.33-gnu1/fs/ecryptfs/keystore.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ecryptfs/keystore.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/random.h>
 #include <linux/crypto.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include "ecryptfs_kernel.h"
 
 /**
diff -druNp linux-libre-2.6.33-gnu1/fs/ecryptfs/kthread.c linux-libre-2.6.34-gnu1/fs/ecryptfs/kthread.c
--- linux-libre-2.6.33-gnu1/fs/ecryptfs/kthread.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ecryptfs/kthread.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/kthread.h>
 #include <linux/freezer.h>
+#include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/mount.h>
 #include "ecryptfs_kernel.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/ecryptfs/main.c linux-libre-2.6.34-gnu1/fs/ecryptfs/main.c
--- linux-libre-2.6.33-gnu1/fs/ecryptfs/main.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ecryptfs/main.c	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/key.h>
 #include <linux/parser.h>
 #include <linux/fs_stack.h>
+#include <linux/slab.h>
 #include "ecryptfs_kernel.h"
 
 /**
@@ -496,17 +497,25 @@ struct kmem_cache *ecryptfs_sb_info_cach
 static int
 ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent)
 {
+	struct ecryptfs_sb_info *esi;
 	int rc = 0;
 
 	/* Released in ecryptfs_put_super() */
 	ecryptfs_set_superblock_private(sb,
 					kmem_cache_zalloc(ecryptfs_sb_info_cache,
 							 GFP_KERNEL));
-	if (!ecryptfs_superblock_to_private(sb)) {
+	esi = ecryptfs_superblock_to_private(sb);
+	if (!esi) {
 		ecryptfs_printk(KERN_WARNING, "Out of memory\n");
 		rc = -ENOMEM;
 		goto out;
 	}
+
+	rc = bdi_setup_and_register(&esi->bdi, "ecryptfs", BDI_CAP_MAP_COPY);
+	if (rc)
+		goto out;
+
+	sb->s_bdi = &esi->bdi;
 	sb->s_op = &ecryptfs_sops;
 	/* Released through deactivate_super(sb) from get_sb_nodev */
 	sb->s_root = d_alloc(NULL, &(const struct qstr) {
diff -druNp linux-libre-2.6.33-gnu1/fs/ecryptfs/messaging.c linux-libre-2.6.34-gnu1/fs/ecryptfs/messaging.c
--- linux-libre-2.6.33-gnu1/fs/ecryptfs/messaging.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ecryptfs/messaging.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
  * 02111-1307, USA.
  */
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/user_namespace.h>
 #include <linux/nsproxy.h>
 #include "ecryptfs_kernel.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/ecryptfs/miscdev.c linux-libre-2.6.34-gnu1/fs/ecryptfs/miscdev.c
--- linux-libre-2.6.33-gnu1/fs/ecryptfs/miscdev.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ecryptfs/miscdev.c	2010-05-16 17:17:36.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/random.h>
 #include <linux/miscdevice.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/module.h>
 #include "ecryptfs_kernel.h"
diff -druNp linux-libre-2.6.33-gnu1/fs/ecryptfs/mmap.c linux-libre-2.6.34-gnu1/fs/ecryptfs/mmap.c
--- linux-libre-2.6.33-gnu1/fs/ecryptfs/mmap.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ecryptfs/mmap.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/file.h>
 #include <linux/crypto.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include "ecryptfs_kernel.h"
 
@@ -82,6 +83,19 @@ out:
 	return rc;
 }
 
+static void strip_xattr_flag(char *page_virt,
+			     struct ecryptfs_crypt_stat *crypt_stat)
+{
+	if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
+		size_t written;
+
+		crypt_stat->flags &= ~ECRYPTFS_METADATA_IN_XATTR;
+		ecryptfs_write_crypt_stat_flags(page_virt, crypt_stat,
+						&written);
+		crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
+	}
+}
+
 /**
  *   Header Extent:
  *     Octets 0-7:        Unencrypted file size (big-endian)
@@ -97,19 +111,6 @@ out:
  *                        (big-endian)
  *     Octet  26:         Begin RFC 2440 authentication token packet set
  */
-static void set_header_info(char *page_virt,
-			    struct ecryptfs_crypt_stat *crypt_stat)
-{
-	size_t written;
-	size_t save_num_header_bytes_at_front =
-		crypt_stat->num_header_bytes_at_front;
-
-	crypt_stat->num_header_bytes_at_front =
-		ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
-	ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written);
-	crypt_stat->num_header_bytes_at_front =
-		save_num_header_bytes_at_front;
-}
 
 /**
  * ecryptfs_copy_up_encrypted_with_header
@@ -135,8 +136,7 @@ ecryptfs_copy_up_encrypted_with_header(s
 					   * num_extents_per_page)
 					  + extent_num_in_page);
 		size_t num_header_extents_at_front =
-			(crypt_stat->num_header_bytes_at_front
-			 / crypt_stat->extent_size);
+			(crypt_stat->metadata_size / crypt_stat->extent_size);
 
 		if (view_extent_num < num_header_extents_at_front) {
 			/* This is a header extent */
@@ -146,9 +146,14 @@ ecryptfs_copy_up_encrypted_with_header(s
 			memset(page_virt, 0, PAGE_CACHE_SIZE);
 			/* TODO: Support more than one header extent */
 			if (view_extent_num == 0) {
+				size_t written;
+
 				rc = ecryptfs_read_xattr_region(
 					page_virt, page->mapping->host);
-				set_header_info(page_virt, crypt_stat);
+				strip_xattr_flag(page_virt + 16, crypt_stat);
+				ecryptfs_write_header_metadata(page_virt + 20,
+							       crypt_stat,
+							       &written);
 			}
 			kunmap_atomic(page_virt, KM_USER0);
 			flush_dcache_page(page);
@@ -161,7 +166,7 @@ ecryptfs_copy_up_encrypted_with_header(s
 			/* This is an encrypted data extent */
 			loff_t lower_offset =
 				((view_extent_num * crypt_stat->extent_size)
-				 - crypt_stat->num_header_bytes_at_front);
+				 - crypt_stat->metadata_size);
 
 			rc = ecryptfs_read_lower_page_segment(
 				page, (lower_offset >> PAGE_CACHE_SHIFT),
diff -druNp linux-libre-2.6.33-gnu1/fs/ecryptfs/super.c linux-libre-2.6.34-gnu1/fs/ecryptfs/super.c
--- linux-libre-2.6.33-gnu1/fs/ecryptfs/super.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ecryptfs/super.c	2010-05-16 17:17:36.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/fs.h>
 #include <linux/mount.h>
 #include <linux/key.h>
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/smp_lock.h>
 #include <linux/file.h>
@@ -85,7 +86,6 @@ static void ecryptfs_destroy_inode(struc
 		if (lower_dentry->d_inode) {
 			fput(inode_info->lower_file);
 			inode_info->lower_file = NULL;
-			d_drop(lower_dentry);
 		}
 	}
 	ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat);
@@ -122,6 +122,7 @@ static void ecryptfs_put_super(struct su
 	lock_kernel();
 
 	ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat);
+	bdi_destroy(&sb_info->bdi);
 	kmem_cache_free(ecryptfs_sb_info_cache, sb_info);
 	ecryptfs_set_superblock_private(sb, NULL);
 
diff -druNp linux-libre-2.6.33-gnu1/fs/eventfd.c linux-libre-2.6.34-gnu1/fs/eventfd.c
--- linux-libre-2.6.33-gnu1/fs/eventfd.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/eventfd.c	2010-05-16 17:17:36.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/anon_inodes.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/exec.c linux-libre-2.6.34-gnu1/fs/exec.c
--- linux-libre-2.6.33-gnu1/fs/exec.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/exec.c	2010-05-16 17:17:36.000000000 -0400
@@ -195,7 +195,7 @@ static struct page *get_arg_page(struct
 		 *    to work from.
 		 */
 		rlim = current->signal->rlim;
-		if (size > rlim[RLIMIT_STACK].rlim_cur / 4) {
+		if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) {
 			put_page(page);
 			return NULL;
 		}
@@ -246,6 +246,7 @@ static int __bprm_mm_init(struct linux_b
 	vma->vm_start = vma->vm_end - PAGE_SIZE;
 	vma->vm_flags = VM_STACK_FLAGS;
 	vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+	INIT_LIST_HEAD(&vma->anon_vma_chain);
 	err = insert_vm_struct(mm, vma);
 	if (err)
 		goto err;
@@ -516,7 +517,8 @@ static int shift_arg_pages(struct vm_are
 	/*
 	 * cover the whole range: [new_start, old_end)
 	 */
-	vma_adjust(vma, new_start, old_end, vma->vm_pgoff, NULL);
+	if (vma_adjust(vma, new_start, old_end, vma->vm_pgoff, NULL))
+		return -ENOMEM;
 
 	/*
 	 * move the page tables downwards, on failure we rely on
@@ -547,15 +549,13 @@ static int shift_arg_pages(struct vm_are
 	tlb_finish_mmu(tlb, new_end, old_end);
 
 	/*
-	 * shrink the vma to just the new range.
+	 * Shrink the vma to just the new range.  Always succeeds.
 	 */
 	vma_adjust(vma, new_start, new_end, vma->vm_pgoff, NULL);
 
 	return 0;
 }
 
-#define EXTRA_STACK_VM_PAGES	20	/* random */
-
 /*
  * Finalizes the stack vm_area_struct. The flags and permissions are updated,
  * the stack is optionally relocated, and some extra space is added.
@@ -577,7 +577,7 @@ int setup_arg_pages(struct linux_binprm
 
 #ifdef CONFIG_STACK_GROWSUP
 	/* Limit stack size to 1GB */
-	stack_base = current->signal->rlim[RLIMIT_STACK].rlim_max;
+	stack_base = rlimit_max(RLIMIT_STACK);
 	if (stack_base > (1 << 30))
 		stack_base = 1 << 30;
 
@@ -630,7 +630,7 @@ int setup_arg_pages(struct linux_binprm
 			goto out_unlock;
 	}
 
-	stack_expand = EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+	stack_expand = 131072UL; /* randomly 32*4k (or 2*64k) pages */
 	stack_size = vma->vm_end - vma->vm_start;
 	/*
 	 * Align this down to a page boundary as expand_stack
@@ -718,6 +718,7 @@ static int exec_mmap(struct mm_struct *m
 	/* Notify parent that we're no longer interested in the old VM */
 	tsk = current;
 	old_mm = current->mm;
+	sync_mm_rss(tsk, old_mm);
 	mm_release(tsk, old_mm);
 
 	if (old_mm) {
@@ -1386,8 +1387,6 @@ int do_execve(char * filename,
 	if (retval < 0)
 		goto out;
 
-	current->stack_start = current->mm->start_stack;
-
 	/* execve succeeded */
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
@@ -1532,7 +1531,7 @@ static int format_corename(char *corenam
 			/* core limit size */
 			case 'c':
 				rc = snprintf(out_ptr, out_end - out_ptr,
-					      "%lu", current->signal->rlim[RLIMIT_CORE].rlim_cur);
+					      "%lu", rlimit(RLIMIT_CORE));
 				if (rc > out_end - out_ptr)
 					goto out;
 				out_ptr += rc;
@@ -1560,12 +1559,13 @@ out:
 	return ispipe;
 }
 
-static int zap_process(struct task_struct *start)
+static int zap_process(struct task_struct *start, int exit_code)
 {
 	struct task_struct *t;
 	int nr = 0;
 
 	start->signal->flags = SIGNAL_GROUP_EXIT;
+	start->signal->group_exit_code = exit_code;
 	start->signal->group_stop_count = 0;
 
 	t = start;
@@ -1590,8 +1590,7 @@ static inline int zap_threads(struct tas
 	spin_lock_irq(&tsk->sighand->siglock);
 	if (!signal_group_exit(tsk->signal)) {
 		mm->core_state = core_state;
-		tsk->signal->group_exit_code = exit_code;
-		nr = zap_process(tsk);
+		nr = zap_process(tsk, exit_code);
 	}
 	spin_unlock_irq(&tsk->sighand->siglock);
 	if (unlikely(nr < 0))
@@ -1640,7 +1639,7 @@ static inline int zap_threads(struct tas
 			if (p->mm) {
 				if (unlikely(p->mm == mm)) {
 					lock_task_sighand(p, &flags);
-					nr += zap_process(p);
+					nr += zap_process(p, exit_code);
 					unlock_task_sighand(p, &flags);
 				}
 				break;
@@ -1747,14 +1746,19 @@ void set_dumpable(struct mm_struct *mm,
 	}
 }
 
-int get_dumpable(struct mm_struct *mm)
+static int __get_dumpable(unsigned long mm_flags)
 {
 	int ret;
 
-	ret = mm->flags & 0x3;
+	ret = mm_flags & MMF_DUMPABLE_MASK;
 	return (ret >= 2) ? 2 : ret;
 }
 
+int get_dumpable(struct mm_struct *mm)
+{
+	return __get_dumpable(mm->flags);
+}
+
 static void wait_for_dump_helpers(struct file *file)
 {
 	struct pipe_inode_info *pipe;
@@ -1797,7 +1801,13 @@ void do_coredump(long signr, int exit_co
 	struct coredump_params cprm = {
 		.signr = signr,
 		.regs = regs,
-		.limit = current->signal->rlim[RLIMIT_CORE].rlim_cur,
+		.limit = rlimit(RLIMIT_CORE),
+		/*
+		 * We must use the same mm->flags while dumping core to avoid
+		 * inconsistency of bit flags, since this flag is not protected
+		 * by any locks.
+		 */
+		.mm_flags = mm->flags,
 	};
 
 	audit_core_dumps(signr);
@@ -1816,7 +1826,7 @@ void do_coredump(long signr, int exit_co
 	/*
 	 * If another thread got here first, or we are not dumpable, bail out.
 	 */
-	if (mm->core_state || !get_dumpable(mm)) {
+	if (mm->core_state || !__get_dumpable(cprm.mm_flags)) {
 		up_write(&mm->mmap_sem);
 		put_cred(cred);
 		goto fail;
@@ -1827,7 +1837,8 @@ void do_coredump(long signr, int exit_co
 	 *	process nor do we know its entire history. We only know it
 	 *	was tainted so we dump it as root in mode 2.
 	 */
-	if (get_dumpable(mm) == 2) {	/* Setuid core dump mode */
+	if (__get_dumpable(cprm.mm_flags) == 2) {
+		/* Setuid core dump mode */
 		flag = O_EXCL;		/* Stop rewrite attacks */
 		cred->fsuid = 0;	/* Dump root private */
 	}
@@ -1923,8 +1934,9 @@ void do_coredump(long signr, int exit_co
 	/*
 	 * Dont allow local users get cute and trick others to coredump
 	 * into their pre-created files:
+	 * Note, this is not relevant for pipes
 	 */
-	if (inode->i_uid != current_fsuid())
+	if (!ispipe && (inode->i_uid != current_fsuid()))
 		goto close_fail;
 	if (!cprm.file->f_op)
 		goto close_fail;
diff -druNp linux-libre-2.6.33-gnu1/fs/exofs/common.h linux-libre-2.6.34-gnu1/fs/exofs/common.h
--- linux-libre-2.6.33-gnu1/fs/exofs/common.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/exofs/common.h	2010-05-16 17:17:36.000000000 -0400
@@ -55,6 +55,8 @@
 /* exofs Application specific page/attribute */
 # define EXOFS_APAGE_FS_DATA	(OSD_APAGE_APP_DEFINED_FIRST + 3)
 # define EXOFS_ATTR_INODE_DATA	1
+# define EXOFS_ATTR_INODE_FILE_LAYOUT	2
+# define EXOFS_ATTR_INODE_DIR_LAYOUT	3
 
 /*
  * The maximum number of files we can have is limited by the size of the
@@ -206,4 +208,41 @@ enum {
 	(((name_len) + offsetof(struct exofs_dir_entry, name)  + \
 	  EXOFS_DIR_ROUND) & ~EXOFS_DIR_ROUND)
 
+/*
+ * The on-disk (optional) layout structure.
+ * sits in an EXOFS_ATTR_INODE_FILE_LAYOUT or EXOFS_ATTR_INODE_DIR_LAYOUT
+ * attribute, attached to any inode, usually to a directory.
+ */
+
+enum exofs_inode_layout_gen_functions {
+	LAYOUT_MOVING_WINDOW = 0,
+	LAYOUT_IMPLICT = 1,
+};
+
+struct exofs_on_disk_inode_layout {
+	__le16 gen_func; /* One of enum exofs_inode_layout_gen_functions */
+	__le16 pad;
+	union {
+		/* gen_func == LAYOUT_MOVING_WINDOW (default) */
+		struct exofs_layout_sliding_window {
+			__le32 num_devices; /* first n devices in global-table*/
+		} sliding_window __packed;
+
+		/* gen_func == LAYOUT_IMPLICT */
+		struct exofs_layout_implict_list {
+			struct exofs_dt_data_map data_map;
+			/* Variable array of size data_map.cb_num_comps. These
+			 * are device indexes of the devices in the global table
+			 */
+			__le32 dev_indexes[];
+		} implict __packed;
+	};
+} __packed;
+
+static inline size_t exofs_on_disk_inode_layout_size(unsigned max_devs)
+{
+	return sizeof(struct exofs_on_disk_inode_layout) +
+		max_devs * sizeof(__le32);
+}
+
 #endif /*ifndef __EXOFS_COM_H__*/
diff -druNp linux-libre-2.6.33-gnu1/fs/exofs/exofs.h linux-libre-2.6.34-gnu1/fs/exofs/exofs.h
--- linux-libre-2.6.33-gnu1/fs/exofs/exofs.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/exofs/exofs.h	2010-05-16 17:17:36.000000000 -0400
@@ -35,6 +35,7 @@
 
 #include <linux/fs.h>
 #include <linux/time.h>
+#include <linux/backing-dev.h>
 #include "common.h"
 
 /* FIXME: Remove once pnfs hits mainline
@@ -55,12 +56,28 @@
 /* u64 has problems with printk this will cast it to unsigned long long */
 #define _LLU(x) (unsigned long long)(x)
 
+struct exofs_layout {
+	osd_id		s_pid;			/* partition ID of file system*/
+
+	/* Our way of looking at the data_map */
+	unsigned stripe_unit;
+	unsigned mirrors_p1;
+
+	unsigned group_width;
+	u64	 group_depth;
+	unsigned group_count;
+
+	enum exofs_inode_layout_gen_functions lay_func;
+
+	unsigned	s_numdevs;		/* Num of devices in array    */
+	struct osd_dev	*s_ods[0];		/* Variable length            */
+};
+
 /*
  * our extension to the in-memory superblock
  */
 struct exofs_sb_info {
 	struct exofs_fscb s_fscb;		/* Written often, pre-allocate*/
-	osd_id		s_pid;			/* partition ID of file system*/
 	int		s_timeout;		/* timeout for OSD operations */
 	uint64_t	s_nextid;		/* highest object ID used     */
 	uint32_t	s_numfiles;		/* number of files on fs      */
@@ -68,23 +85,29 @@ struct exofs_sb_info {
 	u32		s_next_generation;	/* next gen # to use          */
 	atomic_t	s_curr_pending;		/* number of pending commands */
 	uint8_t		s_cred[OSD_CAP_LEN];	/* credential for the fscb    */
+	struct 		backing_dev_info bdi;	/* register our bdi with VFS  */
 
-	struct pnfs_osd_data_map data_map;	/* Default raid to use        */
-	unsigned	s_numdevs;		/* Num of devices in array    */
-	struct osd_dev	*s_ods[1];		/* Variable length, minimum 1 */
+	struct pnfs_osd_data_map data_map;	/* Default raid to use
+						 * FIXME: Needed ?
+						 */
+/*	struct exofs_layout	dir_layout;*/	/* Default dir layout */
+	struct exofs_layout	layout;		/* Default files layout,
+						 * contains the variable osd_dev
+						 * array. Keep last */
+	struct osd_dev	*_min_one_dev[1];	/* Place holder for one dev   */
 };
 
 /*
  * our extension to the in-memory inode
  */
 struct exofs_i_info {
+	struct inode   vfs_inode;          /* normal in-memory inode          */
+	wait_queue_head_t i_wq;            /* wait queue for inode            */
 	unsigned long  i_flags;            /* various atomic flags            */
 	uint32_t       i_data[EXOFS_IDATA];/*short symlink names and device #s*/
 	uint32_t       i_dir_start_lookup; /* which page to start lookup      */
-	wait_queue_head_t i_wq;            /* wait queue for inode            */
 	uint64_t       i_commit_size;      /* the object's written length     */
 	uint8_t        i_cred[OSD_CAP_LEN];/* all-powerful credential         */
-	struct inode   vfs_inode;          /* normal in-memory inode          */
 };
 
 static inline osd_id exofs_oi_objno(struct exofs_i_info *oi)
@@ -101,7 +124,7 @@ struct exofs_io_state {
 	void			*private;
 	exofs_io_done_fn	done;
 
-	struct exofs_sb_info	*sbi;
+	struct exofs_layout	*layout;
 	struct osd_obj_id	obj;
 	u8			*cred;
 
@@ -109,7 +132,11 @@ struct exofs_io_state {
 	loff_t			offset;
 	unsigned long		length;
 	void			*kern_buff;
-	struct bio		*bio;
+
+	struct page		**pages;
+	unsigned		nr_pages;
+	unsigned		pgbase;
+	unsigned		pages_consumed;
 
 	/* Attributes */
 	unsigned		in_attr_len;
@@ -122,6 +149,9 @@ struct exofs_io_state {
 	struct exofs_per_dev_state {
 		struct osd_request *or;
 		struct bio *bio;
+		loff_t offset;
+		unsigned length;
+		unsigned dev;
 	} per_dev[];
 };
 
@@ -175,6 +205,12 @@ static inline struct exofs_i_info *exofs
 }
 
 /*
+ * Given a layout, object_number and stripe_index return the associated global
+ * dev_index
+ */
+unsigned exofs_layout_od_id(struct exofs_layout *layout,
+			    osd_id obj_no, unsigned layout_index);
+/*
  * Maximum count of links to a file
  */
 #define EXOFS_LINK_MAX           32000
@@ -189,7 +225,8 @@ void exofs_make_credential(u8 cred_a[OSD
 int exofs_read_kern(struct osd_dev *od, u8 *cred, struct osd_obj_id *obj,
 		    u64 offset, void *p, unsigned length);
 
-int  exofs_get_io_state(struct exofs_sb_info *sbi, struct exofs_io_state** ios);
+int  exofs_get_io_state(struct exofs_layout *layout,
+			struct exofs_io_state **ios);
 void exofs_put_io_state(struct exofs_io_state *ios);
 
 int exofs_check_io(struct exofs_io_state *ios, u64 *resid);
@@ -226,7 +263,7 @@ int exofs_write_begin(struct file *file,
 		struct page **pagep, void **fsdata);
 extern struct inode *exofs_iget(struct super_block *, unsigned long);
 struct inode *exofs_new_inode(struct inode *, int);
-extern int exofs_write_inode(struct inode *, int);
+extern int exofs_write_inode(struct inode *, struct writeback_control *wbc);
 extern void exofs_delete_inode(struct inode *);
 
 /* dir.c:                */
diff -druNp linux-libre-2.6.33-gnu1/fs/exofs/inode.c linux-libre-2.6.34-gnu1/fs/exofs/inode.c
--- linux-libre-2.6.33-gnu1/fs/exofs/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/exofs/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <linux/slab.h>
 #include <linux/writeback.h>
 #include <linux/buffer_head.h>
 #include <scsi/scsi_device.h>
@@ -41,16 +42,18 @@
 
 enum { BIO_MAX_PAGES_KMALLOC =
 		(PAGE_SIZE - sizeof(struct bio)) / sizeof(struct bio_vec),
+	MAX_PAGES_KMALLOC =
+		PAGE_SIZE / sizeof(struct page *),
 };
 
 struct page_collect {
 	struct exofs_sb_info *sbi;
-	struct request_queue *req_q;
 	struct inode *inode;
 	unsigned expected_pages;
 	struct exofs_io_state *ios;
 
-	struct bio *bio;
+	struct page **pages;
+	unsigned alloc_pages;
 	unsigned nr_pages;
 	unsigned long length;
 	loff_t pg_first; /* keep 64bit also in 32-arches */
@@ -62,15 +65,12 @@ static void _pcol_init(struct page_colle
 	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
 
 	pcol->sbi = sbi;
-	/* Create master bios on first Q, later on cloning, each clone will be
-	 * allocated on it's destination Q
-	 */
-	pcol->req_q = osd_request_queue(sbi->s_ods[0]);
 	pcol->inode = inode;
 	pcol->expected_pages = expected_pages;
 
 	pcol->ios = NULL;
-	pcol->bio = NULL;
+	pcol->pages = NULL;
+	pcol->alloc_pages = 0;
 	pcol->nr_pages = 0;
 	pcol->length = 0;
 	pcol->pg_first = -1;
@@ -80,7 +80,8 @@ static void _pcol_reset(struct page_coll
 {
 	pcol->expected_pages -= min(pcol->nr_pages, pcol->expected_pages);
 
-	pcol->bio = NULL;
+	pcol->pages = NULL;
+	pcol->alloc_pages = 0;
 	pcol->nr_pages = 0;
 	pcol->length = 0;
 	pcol->pg_first = -1;
@@ -90,38 +91,43 @@ static void _pcol_reset(struct page_coll
 	 * it might not end here. don't be left with nothing
 	 */
 	if (!pcol->expected_pages)
-		pcol->expected_pages = BIO_MAX_PAGES_KMALLOC;
+		pcol->expected_pages = MAX_PAGES_KMALLOC;
 }
 
 static int pcol_try_alloc(struct page_collect *pcol)
 {
-	int pages = min_t(unsigned, pcol->expected_pages,
-			  BIO_MAX_PAGES_KMALLOC);
+	unsigned pages = min_t(unsigned, pcol->expected_pages,
+			  MAX_PAGES_KMALLOC);
 
 	if (!pcol->ios) { /* First time allocate io_state */
-		int ret = exofs_get_io_state(pcol->sbi, &pcol->ios);
+		int ret = exofs_get_io_state(&pcol->sbi->layout, &pcol->ios);
 
 		if (ret)
 			return ret;
 	}
 
+	/* TODO: easily support bio chaining */
+	pages =  min_t(unsigned, pages,
+		       pcol->sbi->layout.group_width * BIO_MAX_PAGES_KMALLOC);
+
 	for (; pages; pages >>= 1) {
-		pcol->bio = bio_kmalloc(GFP_KERNEL, pages);
-		if (likely(pcol->bio))
+		pcol->pages = kmalloc(pages * sizeof(struct page *),
+				      GFP_KERNEL);
+		if (likely(pcol->pages)) {
+			pcol->alloc_pages = pages;
 			return 0;
+		}
 	}
 
-	EXOFS_ERR("Failed to bio_kmalloc expected_pages=%u\n",
+	EXOFS_ERR("Failed to kmalloc expected_pages=%u\n",
 		  pcol->expected_pages);
 	return -ENOMEM;
 }
 
 static void pcol_free(struct page_collect *pcol)
 {
-	if (pcol->bio) {
-		bio_put(pcol->bio);
-		pcol->bio = NULL;
-	}
+	kfree(pcol->pages);
+	pcol->pages = NULL;
 
 	if (pcol->ios) {
 		exofs_put_io_state(pcol->ios);
@@ -132,11 +138,10 @@ static void pcol_free(struct page_collec
 static int pcol_add_page(struct page_collect *pcol, struct page *page,
 			 unsigned len)
 {
-	int added_len = bio_add_pc_page(pcol->req_q, pcol->bio, page, len, 0);
-	if (unlikely(len != added_len))
+	if (unlikely(pcol->nr_pages >= pcol->alloc_pages))
 		return -ENOMEM;
 
-	++pcol->nr_pages;
+	pcol->pages[pcol->nr_pages++] = page;
 	pcol->length += len;
 	return 0;
 }
@@ -181,7 +186,6 @@ static void update_write_page(struct pag
  */
 static int __readpages_done(struct page_collect *pcol, bool do_unlock)
 {
-	struct bio_vec *bvec;
 	int i;
 	u64 resid;
 	u64 good_bytes;
@@ -193,13 +197,13 @@ static int __readpages_done(struct page_
 	else
 		good_bytes = pcol->length - resid;
 
-	EXOFS_DBGMSG("readpages_done(0x%lx) good_bytes=0x%llx"
+	EXOFS_DBGMSG2("readpages_done(0x%lx) good_bytes=0x%llx"
 		     " length=0x%lx nr_pages=%u\n",
 		     pcol->inode->i_ino, _LLU(good_bytes), pcol->length,
 		     pcol->nr_pages);
 
-	__bio_for_each_segment(bvec, pcol->bio, i, 0) {
-		struct page *page = bvec->bv_page;
+	for (i = 0; i < pcol->nr_pages; i++) {
+		struct page *page = pcol->pages[i];
 		struct inode *inode = page->mapping->host;
 		int page_stat;
 
@@ -218,11 +222,11 @@ static int __readpages_done(struct page_
 		ret = update_read_page(page, page_stat);
 		if (do_unlock)
 			unlock_page(page);
-		length += bvec->bv_len;
+		length += PAGE_SIZE;
 	}
 
 	pcol_free(pcol);
-	EXOFS_DBGMSG("readpages_done END\n");
+	EXOFS_DBGMSG2("readpages_done END\n");
 	return ret;
 }
 
@@ -238,11 +242,10 @@ static void readpages_done(struct exofs_
 
 static void _unlock_pcol_pages(struct page_collect *pcol, int ret, int rw)
 {
-	struct bio_vec *bvec;
 	int i;
 
-	__bio_for_each_segment(bvec, pcol->bio, i, 0) {
-		struct page *page = bvec->bv_page;
+	for (i = 0; i < pcol->nr_pages; i++) {
+		struct page *page = pcol->pages[i];
 
 		if (rw == READ)
 			update_read_page(page, ret);
@@ -260,13 +263,14 @@ static int read_exec(struct page_collect
 	struct page_collect *pcol_copy = NULL;
 	int ret;
 
-	if (!pcol->bio)
+	if (!pcol->pages)
 		return 0;
 
 	/* see comment in _readpage() about sync reads */
 	WARN_ON(is_sync && (pcol->nr_pages != 1));
 
-	ios->bio = pcol->bio;
+	ios->pages = pcol->pages;
+	ios->nr_pages = pcol->nr_pages;
 	ios->length = pcol->length;
 	ios->offset = pcol->pg_first << PAGE_CACHE_SHIFT;
 
@@ -290,7 +294,7 @@ static int read_exec(struct page_collect
 
 	atomic_inc(&pcol->sbi->s_curr_pending);
 
-	EXOFS_DBGMSG("read_exec obj=0x%llx start=0x%llx length=0x%lx\n",
+	EXOFS_DBGMSG2("read_exec obj=0x%llx start=0x%llx length=0x%lx\n",
 		  ios->obj.id, _LLU(ios->offset), pcol->length);
 
 	/* pages ownership was passed to pcol_copy */
@@ -366,7 +370,7 @@ try_again:
 		goto try_again;
 	}
 
-	if (!pcol->bio) {
+	if (!pcol->pages) {
 		ret = pcol_try_alloc(pcol);
 		if (unlikely(ret))
 			goto fail;
@@ -448,7 +452,6 @@ static int exofs_readpage(struct file *f
 static void writepages_done(struct exofs_io_state *ios, void *p)
 {
 	struct page_collect *pcol = p;
-	struct bio_vec *bvec;
 	int i;
 	u64 resid;
 	u64  good_bytes;
@@ -462,13 +465,13 @@ static void writepages_done(struct exofs
 	else
 		good_bytes = pcol->length - resid;
 
-	EXOFS_DBGMSG("writepages_done(0x%lx) good_bytes=0x%llx"
+	EXOFS_DBGMSG2("writepages_done(0x%lx) good_bytes=0x%llx"
 		     " length=0x%lx nr_pages=%u\n",
 		     pcol->inode->i_ino, _LLU(good_bytes), pcol->length,
 		     pcol->nr_pages);
 
-	__bio_for_each_segment(bvec, pcol->bio, i, 0) {
-		struct page *page = bvec->bv_page;
+	for (i = 0; i < pcol->nr_pages; i++) {
+		struct page *page = pcol->pages[i];
 		struct inode *inode = page->mapping->host;
 		int page_stat;
 
@@ -485,12 +488,12 @@ static void writepages_done(struct exofs
 		EXOFS_DBGMSG2("    writepages_done(0x%lx, 0x%lx) status=%d\n",
 			     inode->i_ino, page->index, page_stat);
 
-		length += bvec->bv_len;
+		length += PAGE_SIZE;
 	}
 
 	pcol_free(pcol);
 	kfree(pcol);
-	EXOFS_DBGMSG("writepages_done END\n");
+	EXOFS_DBGMSG2("writepages_done END\n");
 }
 
 static int write_exec(struct page_collect *pcol)
@@ -500,7 +503,7 @@ static int write_exec(struct page_collec
 	struct page_collect *pcol_copy = NULL;
 	int ret;
 
-	if (!pcol->bio)
+	if (!pcol->pages)
 		return 0;
 
 	pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL);
@@ -512,9 +515,8 @@ static int write_exec(struct page_collec
 
 	*pcol_copy = *pcol;
 
-	pcol_copy->bio->bi_rw |= (1 << BIO_RW); /* FIXME: bio_set_dir() */
-
-	ios->bio = pcol_copy->bio;
+	ios->pages = pcol_copy->pages;
+	ios->nr_pages = pcol_copy->nr_pages;
 	ios->offset = pcol_copy->pg_first << PAGE_CACHE_SHIFT;
 	ios->length = pcol_copy->length;
 	ios->done = writepages_done;
@@ -527,7 +529,7 @@ static int write_exec(struct page_collec
 	}
 
 	atomic_inc(&pcol->sbi->s_curr_pending);
-	EXOFS_DBGMSG("write_exec(0x%lx, 0x%llx) start=0x%llx length=0x%lx\n",
+	EXOFS_DBGMSG2("write_exec(0x%lx, 0x%llx) start=0x%llx length=0x%lx\n",
 		  pcol->inode->i_ino, pcol->pg_first, _LLU(ios->offset),
 		  pcol->length);
 	/* pages ownership was passed to pcol_copy */
@@ -605,7 +607,7 @@ try_again:
 		goto try_again;
 	}
 
-	if (!pcol->bio) {
+	if (!pcol->pages) {
 		ret = pcol_try_alloc(pcol);
 		if (unlikely(ret))
 			goto fail;
@@ -616,7 +618,7 @@ try_again:
 
 	ret = pcol_add_page(pcol, page, len);
 	if (unlikely(ret)) {
-		EXOFS_DBGMSG("Failed pcol_add_page "
+		EXOFS_DBGMSG2("Failed pcol_add_page "
 			     "nr_pages=%u total_length=0x%lx\n",
 			     pcol->nr_pages, pcol->length);
 
@@ -663,7 +665,7 @@ static int exofs_writepages(struct addre
 	if (expected_pages < 32L)
 		expected_pages = 32L;
 
-	EXOFS_DBGMSG("inode(0x%lx) wbc->start=0x%llx wbc->end=0x%llx "
+	EXOFS_DBGMSG2("inode(0x%lx) wbc->start=0x%llx wbc->end=0x%llx "
 		     "nrpages=%lu start=0x%lx end=0x%lx expected_pages=%ld\n",
 		     mapping->host->i_ino, wbc->range_start, wbc->range_end,
 		     mapping->nrpages, start, end, expected_pages);
@@ -859,20 +861,33 @@ int exofs_setattr(struct dentry *dentry,
 	return error;
 }
 
+static const struct osd_attr g_attr_inode_file_layout = ATTR_DEF(
+	EXOFS_APAGE_FS_DATA,
+	EXOFS_ATTR_INODE_FILE_LAYOUT,
+	0);
+static const struct osd_attr g_attr_inode_dir_layout = ATTR_DEF(
+	EXOFS_APAGE_FS_DATA,
+	EXOFS_ATTR_INODE_DIR_LAYOUT,
+	0);
+
 /*
- * Read an inode from the OSD, and return it as is.  We also return the size
- * attribute in the 'obj_size' argument.
+ * Read the Linux inode info from the OSD, and return it as is. In exofs the
+ * inode info is in an application specific page/attribute of the osd-object.
  */
 static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
-		    struct exofs_fcb *inode, uint64_t *obj_size)
+		    struct exofs_fcb *inode)
 {
 	struct exofs_sb_info *sbi = sb->s_fs_info;
-	struct osd_attr attrs[2];
+	struct osd_attr attrs[] = {
+		[0] = g_attr_inode_data,
+		[1] = g_attr_inode_file_layout,
+		[2] = g_attr_inode_dir_layout,
+	};
 	struct exofs_io_state *ios;
+	struct exofs_on_disk_inode_layout *layout;
 	int ret;
 
-	*obj_size = ~0;
-	ret = exofs_get_io_state(sbi, &ios);
+	ret = exofs_get_io_state(&sbi->layout, &ios);
 	if (unlikely(ret)) {
 		EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__);
 		return ret;
@@ -882,14 +897,25 @@ static int exofs_get_inode(struct super_
 	exofs_make_credential(oi->i_cred, &ios->obj);
 	ios->cred = oi->i_cred;
 
-	attrs[0] = g_attr_inode_data;
-	attrs[1] = g_attr_logical_length;
+	attrs[1].len = exofs_on_disk_inode_layout_size(sbi->layout.s_numdevs);
+	attrs[2].len = exofs_on_disk_inode_layout_size(sbi->layout.s_numdevs);
+
 	ios->in_attr = attrs;
 	ios->in_attr_len = ARRAY_SIZE(attrs);
 
 	ret = exofs_sbi_read(ios);
-	if (ret)
+	if (unlikely(ret)) {
+		EXOFS_ERR("object(0x%llx) corrupted, return empty file=>%d\n",
+			  _LLU(ios->obj.id), ret);
+		memset(inode, 0, sizeof(*inode));
+		inode->i_mode = 0040000 | (0777 & ~022);
+		/* If object is lost on target we might as well enable it's
+		 * delete.
+		 */
+		if ((ret == -ENOENT) || (ret == -EINVAL))
+			ret = 0;
 		goto out;
+	}
 
 	ret = extract_attr_from_ios(ios, &attrs[0]);
 	if (ret) {
@@ -901,11 +927,33 @@ static int exofs_get_inode(struct super_
 
 	ret = extract_attr_from_ios(ios, &attrs[1]);
 	if (ret) {
-		EXOFS_ERR("%s: extract_attr of logical_length failed\n",
-			  __func__);
+		EXOFS_ERR("%s: extract_attr of inode_data failed\n", __func__);
 		goto out;
 	}
-	*obj_size = get_unaligned_be64(attrs[1].val_ptr);
+	if (attrs[1].len) {
+		layout = attrs[1].val_ptr;
+		if (layout->gen_func != cpu_to_le16(LAYOUT_MOVING_WINDOW)) {
+			EXOFS_ERR("%s: unsupported files layout %d\n",
+				__func__, layout->gen_func);
+			ret = -ENOTSUPP;
+			goto out;
+		}
+	}
+
+	ret = extract_attr_from_ios(ios, &attrs[2]);
+	if (ret) {
+		EXOFS_ERR("%s: extract_attr of inode_data failed\n", __func__);
+		goto out;
+	}
+	if (attrs[2].len) {
+		layout = attrs[2].val_ptr;
+		if (layout->gen_func != cpu_to_le16(LAYOUT_MOVING_WINDOW)) {
+			EXOFS_ERR("%s: unsupported meta-data layout %d\n",
+				__func__, layout->gen_func);
+			ret = -ENOTSUPP;
+			goto out;
+		}
+	}
 
 out:
 	exofs_put_io_state(ios);
@@ -925,7 +973,6 @@ struct inode *exofs_iget(struct super_bl
 	struct exofs_i_info *oi;
 	struct exofs_fcb fcb;
 	struct inode *inode;
-	uint64_t obj_size;
 	int ret;
 
 	inode = iget_locked(sb, ino);
@@ -937,7 +984,7 @@ struct inode *exofs_iget(struct super_bl
 	__oi_init(oi);
 
 	/* read the inode from the osd */
-	ret = exofs_get_inode(sb, oi, &fcb, &obj_size);
+	ret = exofs_get_inode(sb, oi, &fcb);
 	if (ret)
 		goto bad_inode;
 
@@ -958,13 +1005,6 @@ struct inode *exofs_iget(struct super_bl
 	inode->i_blkbits = EXOFS_BLKSHIFT;
 	inode->i_generation = le32_to_cpu(fcb.i_generation);
 
-	if ((inode->i_size != obj_size) &&
-		(!exofs_inode_is_fast_symlink(inode))) {
-		EXOFS_ERR("WARNING: Size of inode=%llu != object=%llu\n",
-			  inode->i_size, _LLU(obj_size));
-		/* FIXME: call exofs_inode_recovery() */
-	}
-
 	oi->i_dir_start_lookup = 0;
 
 	if ((inode->i_nlink == 0) && (inode->i_mode == 0)) {
@@ -1043,7 +1083,7 @@ static void create_done(struct exofs_io_
 
 	if (unlikely(ret)) {
 		EXOFS_ERR("object=0x%llx creation faild in pid=0x%llx",
-			  _LLU(exofs_oi_objno(oi)), _LLU(sbi->s_pid));
+			  _LLU(exofs_oi_objno(oi)), _LLU(sbi->layout.s_pid));
 		/*TODO: When FS is corrupted creation can fail, object already
 		 * exist. Get rid of this asynchronous creation, if exist
 		 * increment the obj counter and try the next object. Until we
@@ -1104,7 +1144,7 @@ struct inode *exofs_new_inode(struct ino
 
 	mark_inode_dirty(inode);
 
-	ret = exofs_get_io_state(sbi, &ios);
+	ret = exofs_get_io_state(&sbi->layout, &ios);
 	if (unlikely(ret)) {
 		EXOFS_ERR("exofs_new_inode: exofs_get_io_state failed\n");
 		return ERR_PTR(ret);
@@ -1170,8 +1210,10 @@ static int exofs_update_inode(struct ino
 	int ret;
 
 	args = kzalloc(sizeof(*args), GFP_KERNEL);
-	if (!args)
+	if (!args) {
+		EXOFS_DBGMSG("Faild kzalloc of args\n");
 		return -ENOMEM;
+	}
 
 	fcb = &args->fcb;
 
@@ -1200,7 +1242,7 @@ static int exofs_update_inode(struct ino
 	} else
 		memcpy(fcb->i_data, oi->i_data, sizeof(fcb->i_data));
 
-	ret = exofs_get_io_state(sbi, &ios);
+	ret = exofs_get_io_state(&sbi->layout, &ios);
 	if (unlikely(ret)) {
 		EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__);
 		goto free_args;
@@ -1234,13 +1276,14 @@ static int exofs_update_inode(struct ino
 free_args:
 	kfree(args);
 out:
-	EXOFS_DBGMSG("ret=>%d\n", ret);
+	EXOFS_DBGMSG("(0x%lx) do_sync=%d ret=>%d\n",
+		     inode->i_ino, do_sync, ret);
 	return ret;
 }
 
-int exofs_write_inode(struct inode *inode, int wait)
+int exofs_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
-	return exofs_update_inode(inode, wait);
+	return exofs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
 }
 
 /*
@@ -1283,7 +1326,7 @@ void exofs_delete_inode(struct inode *in
 
 	clear_inode(inode);
 
-	ret = exofs_get_io_state(sbi, &ios);
+	ret = exofs_get_io_state(&sbi->layout, &ios);
 	if (unlikely(ret)) {
 		EXOFS_ERR("%s: exofs_get_io_state failed\n", __func__);
 		return;
diff -druNp linux-libre-2.6.33-gnu1/fs/exofs/ios.c linux-libre-2.6.34-gnu1/fs/exofs/ios.c
--- linux-libre-2.6.33-gnu1/fs/exofs/ios.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/exofs/ios.c	2010-05-16 17:17:36.000000000 -0400
@@ -22,10 +22,15 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <linux/slab.h>
 #include <scsi/scsi_device.h>
+#include <asm/div64.h>
 
 #include "exofs.h"
 
+#define EXOFS_DBGMSG2(M...) do {} while (0)
+/* #define EXOFS_DBGMSG2 EXOFS_DBGMSG */
+
 void exofs_make_credential(u8 cred_a[OSD_CAP_LEN], const struct osd_obj_id *obj)
 {
 	osd_sec_init_nosec_doall_caps(cred_a, obj, false, true);
@@ -64,21 +69,24 @@ out:
 	return ret;
 }
 
-int exofs_get_io_state(struct exofs_sb_info *sbi, struct exofs_io_state** pios)
+int exofs_get_io_state(struct exofs_layout *layout,
+		       struct exofs_io_state **pios)
 {
 	struct exofs_io_state *ios;
 
 	/*TODO: Maybe use kmem_cach per sbi of size
-	 * exofs_io_state_size(sbi->s_numdevs)
+	 * exofs_io_state_size(layout->s_numdevs)
 	 */
-	ios = kzalloc(exofs_io_state_size(sbi->s_numdevs), GFP_KERNEL);
+	ios = kzalloc(exofs_io_state_size(layout->s_numdevs), GFP_KERNEL);
 	if (unlikely(!ios)) {
+		EXOFS_DBGMSG("Faild kzalloc bytes=%d\n",
+			     exofs_io_state_size(layout->s_numdevs));
 		*pios = NULL;
 		return -ENOMEM;
 	}
 
-	ios->sbi = sbi;
-	ios->obj.partition = sbi->s_pid;
+	ios->layout = layout;
+	ios->obj.partition = layout->s_pid;
 	*pios = ios;
 	return 0;
 }
@@ -101,6 +109,29 @@ void exofs_put_io_state(struct exofs_io_
 	}
 }
 
+unsigned exofs_layout_od_id(struct exofs_layout *layout,
+			    osd_id obj_no, unsigned layout_index)
+{
+/*	switch (layout->lay_func) {
+	case LAYOUT_MOVING_WINDOW:
+	{*/
+		unsigned dev_mod = obj_no;
+
+		return (layout_index + dev_mod * layout->mirrors_p1) %
+							      layout->s_numdevs;
+/*	}
+	case LAYOUT_FUNC_IMPLICT:
+		return layout->devs[layout_index];
+	}*/
+}
+
+static inline struct osd_dev *exofs_ios_od(struct exofs_io_state *ios,
+					   unsigned layout_index)
+{
+	return ios->layout->s_ods[
+		exofs_layout_od_id(ios->layout, ios->obj.id, layout_index)];
+}
+
 static void _sync_done(struct exofs_io_state *ios, void *p)
 {
 	struct completion *waiting = p;
@@ -168,6 +199,21 @@ static int exofs_io_execute(struct exofs
 	return ret;
 }
 
+static void _clear_bio(struct bio *bio)
+{
+	struct bio_vec *bv;
+	unsigned i;
+
+	__bio_for_each_segment(bv, bio, i, 0) {
+		unsigned this_count = bv->bv_len;
+
+		if (likely(PAGE_SIZE == this_count))
+			clear_highpage(bv->bv_page);
+		else
+			zero_user(bv->bv_page, bv->bv_offset, this_count);
+	}
+}
+
 int exofs_check_io(struct exofs_io_state *ios, u64 *resid)
 {
 	enum osd_err_priority acumulated_osd_err = 0;
@@ -176,16 +222,25 @@ int exofs_check_io(struct exofs_io_state
 
 	for (i = 0; i < ios->numdevs; i++) {
 		struct osd_sense_info osi;
-		int ret = osd_req_decode_sense(ios->per_dev[i].or, &osi);
+		struct osd_request *or = ios->per_dev[i].or;
+		int ret;
 
+		if (unlikely(!or))
+			continue;
+
+		ret = osd_req_decode_sense(or, &osi);
 		if (likely(!ret))
 			continue;
 
-		if (unlikely(ret == -EFAULT)) {
-			EXOFS_DBGMSG("%s: EFAULT Need page clear\n", __func__);
-			/*FIXME: All the pages in this device range should:
-			 *	clear_highpage(page);
-			 */
+		if (OSD_ERR_PRI_CLEAR_PAGES == osi.osd_err_pri) {
+			/* start read offset passed endof file */
+			_clear_bio(ios->per_dev[i].bio);
+			EXOFS_DBGMSG("start read offset passed end of file "
+				"offset=0x%llx, length=0x%llx\n",
+				_LLU(ios->per_dev[i].offset),
+				_LLU(ios->per_dev[i].length));
+
+			continue; /* we recovered */
 		}
 
 		if (osi.osd_err_pri >= acumulated_osd_err) {
@@ -205,14 +260,259 @@ int exofs_check_io(struct exofs_io_state
 	return acumulated_lin_err;
 }
 
+/*
+ * L - logical offset into the file
+ *
+ * U - The number of bytes in a stripe within a group
+ *
+ *	U = stripe_unit * group_width
+ *
+ * T - The number of bytes striped within a group of component objects
+ *     (before advancing to the next group)
+ *
+ *	T = stripe_unit * group_width * group_depth
+ *
+ * S - The number of bytes striped across all component objects
+ *     before the pattern repeats
+ *
+ *	S = stripe_unit * group_width * group_depth * group_count
+ *
+ * M - The "major" (i.e., across all components) stripe number
+ *
+ *	M = L / S
+ *
+ * G - Counts the groups from the beginning of the major stripe
+ *
+ *	G = (L - (M * S)) / T	[or (L % S) / T]
+ *
+ * H - The byte offset within the group
+ *
+ *	H = (L - (M * S)) % T	[or (L % S) % T]
+ *
+ * N - The "minor" (i.e., across the group) stripe number
+ *
+ *	N = H / U
+ *
+ * C - The component index coresponding to L
+ *
+ *	C = (H - (N * U)) / stripe_unit + G * group_width
+ *	[or (L % U) / stripe_unit + G * group_width]
+ *
+ * O - The component offset coresponding to L
+ *
+ *	O = L % stripe_unit + N * stripe_unit + M * group_depth * stripe_unit
+ */
+struct _striping_info {
+	u64 obj_offset;
+	u64 group_length;
+	u64 total_group_length;
+	u64 Major;
+	unsigned dev;
+	unsigned unit_off;
+};
+
+static void _calc_stripe_info(struct exofs_io_state *ios, u64 file_offset,
+			      struct _striping_info *si)
+{
+	u32	stripe_unit = ios->layout->stripe_unit;
+	u32	group_width = ios->layout->group_width;
+	u64	group_depth = ios->layout->group_depth;
+
+	u32	U = stripe_unit * group_width;
+	u64	T = U * group_depth;
+	u64	S = T * ios->layout->group_count;
+	u64	M = div64_u64(file_offset, S);
+
+	/*
+	G = (L - (M * S)) / T
+	H = (L - (M * S)) % T
+	*/
+	u64	LmodS = file_offset - M * S;
+	u32	G = div64_u64(LmodS, T);
+	u64	H = LmodS - G * T;
+
+	u32	N = div_u64(H, U);
+
+	/* "H - (N * U)" is just "H % U" so it's bound to u32 */
+	si->dev = (u32)(H - (N * U)) / stripe_unit + G * group_width;
+	si->dev *= ios->layout->mirrors_p1;
+
+	div_u64_rem(file_offset, stripe_unit, &si->unit_off);
+
+	si->obj_offset = si->unit_off + (N * stripe_unit) +
+				  (M * group_depth * stripe_unit);
+
+	si->group_length = T - H;
+	si->total_group_length = T;
+	si->Major = M;
+}
+
+static int _add_stripe_unit(struct exofs_io_state *ios,  unsigned *cur_pg,
+		unsigned pgbase, struct exofs_per_dev_state *per_dev,
+		int cur_len)
+{
+	unsigned pg = *cur_pg;
+	struct request_queue *q =
+			osd_request_queue(exofs_ios_od(ios, per_dev->dev));
+
+	per_dev->length += cur_len;
+
+	if (per_dev->bio == NULL) {
+		unsigned pages_in_stripe = ios->layout->group_width *
+					(ios->layout->stripe_unit / PAGE_SIZE);
+		unsigned bio_size = (ios->nr_pages + pages_in_stripe) /
+						ios->layout->group_width;
+
+		per_dev->bio = bio_kmalloc(GFP_KERNEL, bio_size);
+		if (unlikely(!per_dev->bio)) {
+			EXOFS_DBGMSG("Faild to allocate BIO size=%u\n",
+				     bio_size);
+			return -ENOMEM;
+		}
+	}
+
+	while (cur_len > 0) {
+		unsigned pglen = min_t(unsigned, PAGE_SIZE - pgbase, cur_len);
+		unsigned added_len;
+
+		BUG_ON(ios->nr_pages <= pg);
+		cur_len -= pglen;
+
+		added_len = bio_add_pc_page(q, per_dev->bio, ios->pages[pg],
+					    pglen, pgbase);
+		if (unlikely(pglen != added_len))
+			return -ENOMEM;
+		pgbase = 0;
+		++pg;
+	}
+	BUG_ON(cur_len);
+
+	*cur_pg = pg;
+	return 0;
+}
+
+static int _prepare_one_group(struct exofs_io_state *ios, u64 length,
+			      struct _striping_info *si, unsigned first_comp)
+{
+	unsigned stripe_unit = ios->layout->stripe_unit;
+	unsigned mirrors_p1 = ios->layout->mirrors_p1;
+	unsigned devs_in_group = ios->layout->group_width * mirrors_p1;
+	unsigned dev = si->dev;
+	unsigned first_dev = dev - (dev % devs_in_group);
+	unsigned comp = first_comp + (dev - first_dev);
+	unsigned max_comp = ios->numdevs ? ios->numdevs - mirrors_p1 : 0;
+	unsigned cur_pg = ios->pages_consumed;
+	int ret = 0;
+
+	while (length) {
+		struct exofs_per_dev_state *per_dev = &ios->per_dev[comp];
+		unsigned cur_len, page_off = 0;
+
+		if (!per_dev->length) {
+			per_dev->dev = dev;
+			if (dev < si->dev) {
+				per_dev->offset = si->obj_offset + stripe_unit -
+								   si->unit_off;
+				cur_len = stripe_unit;
+			} else if (dev == si->dev) {
+				per_dev->offset = si->obj_offset;
+				cur_len = stripe_unit - si->unit_off;
+				page_off = si->unit_off & ~PAGE_MASK;
+				BUG_ON(page_off && (page_off != ios->pgbase));
+			} else { /* dev > si->dev */
+				per_dev->offset = si->obj_offset - si->unit_off;
+				cur_len = stripe_unit;
+			}
+
+			if (max_comp < comp)
+				max_comp = comp;
+
+			dev += mirrors_p1;
+			dev = (dev % devs_in_group) + first_dev;
+		} else {
+			cur_len = stripe_unit;
+		}
+		if (cur_len >= length)
+			cur_len = length;
+
+		ret = _add_stripe_unit(ios, &cur_pg, page_off , per_dev,
+				       cur_len);
+		if (unlikely(ret))
+			goto out;
+
+		comp += mirrors_p1;
+		comp = (comp % devs_in_group) + first_comp;
+
+		length -= cur_len;
+	}
+out:
+	ios->numdevs = max_comp + mirrors_p1;
+	ios->pages_consumed = cur_pg;
+	return ret;
+}
+
+static int _prepare_for_striping(struct exofs_io_state *ios)
+{
+	u64 length = ios->length;
+	struct _striping_info si;
+	unsigned devs_in_group = ios->layout->group_width *
+				 ios->layout->mirrors_p1;
+	unsigned first_comp = 0;
+	int ret = 0;
+
+	_calc_stripe_info(ios, ios->offset, &si);
+
+	if (!ios->pages) {
+		if (ios->kern_buff) {
+			struct exofs_per_dev_state *per_dev = &ios->per_dev[0];
+
+			per_dev->offset = si.obj_offset;
+			per_dev->dev = si.dev;
+
+			/* no cross device without page array */
+			BUG_ON((ios->layout->group_width > 1) &&
+			       (si.unit_off + ios->length >
+				ios->layout->stripe_unit));
+		}
+		ios->numdevs = ios->layout->mirrors_p1;
+		return 0;
+	}
+
+	while (length) {
+		if (length < si.group_length)
+			si.group_length = length;
+
+		ret = _prepare_one_group(ios, si.group_length, &si, first_comp);
+		if (unlikely(ret))
+			goto out;
+
+		length -= si.group_length;
+
+		si.group_length = si.total_group_length;
+		si.unit_off = 0;
+		++si.Major;
+		si.obj_offset = si.Major * ios->layout->stripe_unit *
+						ios->layout->group_depth;
+
+		si.dev = (si.dev - (si.dev % devs_in_group)) + devs_in_group;
+		si.dev %= ios->layout->s_numdevs;
+
+		first_comp += devs_in_group;
+		first_comp %= ios->layout->s_numdevs;
+	}
+
+out:
+	return ret;
+}
+
 int exofs_sbi_create(struct exofs_io_state *ios)
 {
 	int i, ret;
 
-	for (i = 0; i < ios->sbi->s_numdevs; i++) {
+	for (i = 0; i < ios->layout->s_numdevs; i++) {
 		struct osd_request *or;
 
-		or = osd_start_request(ios->sbi->s_ods[i], GFP_KERNEL);
+		or = osd_start_request(exofs_ios_od(ios, i), GFP_KERNEL);
 		if (unlikely(!or)) {
 			EXOFS_ERR("%s: osd_start_request failed\n", __func__);
 			ret = -ENOMEM;
@@ -233,10 +533,10 @@ int exofs_sbi_remove(struct exofs_io_sta
 {
 	int i, ret;
 
-	for (i = 0; i < ios->sbi->s_numdevs; i++) {
+	for (i = 0; i < ios->layout->s_numdevs; i++) {
 		struct osd_request *or;
 
-		or = osd_start_request(ios->sbi->s_ods[i], GFP_KERNEL);
+		or = osd_start_request(exofs_ios_od(ios, i), GFP_KERNEL);
 		if (unlikely(!or)) {
 			EXOFS_ERR("%s: osd_start_request failed\n", __func__);
 			ret = -ENOMEM;
@@ -253,51 +553,74 @@ out:
 	return ret;
 }
 
-int exofs_sbi_write(struct exofs_io_state *ios)
+static int _sbi_write_mirror(struct exofs_io_state *ios, int cur_comp)
 {
-	int i, ret;
+	struct exofs_per_dev_state *master_dev = &ios->per_dev[cur_comp];
+	unsigned dev = ios->per_dev[cur_comp].dev;
+	unsigned last_comp = cur_comp + ios->layout->mirrors_p1;
+	int ret = 0;
 
-	for (i = 0; i < ios->sbi->s_numdevs; i++) {
+	if (ios->pages && !master_dev->length)
+		return 0; /* Just an empty slot */
+
+	for (; cur_comp < last_comp; ++cur_comp, ++dev) {
+		struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp];
 		struct osd_request *or;
 
-		or = osd_start_request(ios->sbi->s_ods[i], GFP_KERNEL);
+		or = osd_start_request(exofs_ios_od(ios, dev), GFP_KERNEL);
 		if (unlikely(!or)) {
 			EXOFS_ERR("%s: osd_start_request failed\n", __func__);
 			ret = -ENOMEM;
 			goto out;
 		}
-		ios->per_dev[i].or = or;
-		ios->numdevs++;
+		per_dev->or = or;
+		per_dev->offset = master_dev->offset;
 
-		if (ios->bio) {
+		if (ios->pages) {
 			struct bio *bio;
 
-			if (i != 0) {
+			if (per_dev != master_dev) {
 				bio = bio_kmalloc(GFP_KERNEL,
-						  ios->bio->bi_max_vecs);
+						  master_dev->bio->bi_max_vecs);
 				if (unlikely(!bio)) {
+					EXOFS_DBGMSG(
+					      "Faild to allocate BIO size=%u\n",
+					      master_dev->bio->bi_max_vecs);
 					ret = -ENOMEM;
 					goto out;
 				}
 
-				__bio_clone(bio, ios->bio);
+				__bio_clone(bio, master_dev->bio);
 				bio->bi_bdev = NULL;
 				bio->bi_next = NULL;
-				ios->per_dev[i].bio =  bio;
+				per_dev->length = master_dev->length;
+				per_dev->bio =  bio;
+				per_dev->dev = dev;
 			} else {
-				bio = ios->bio;
+				bio = master_dev->bio;
+				/* FIXME: bio_set_dir() */
+				bio->bi_rw |= (1 << BIO_RW);
 			}
 
-			osd_req_write(or, &ios->obj, ios->offset, bio,
-				      ios->length);
-/*			EXOFS_DBGMSG("write sync=%d\n", sync);*/
+			osd_req_write(or, &ios->obj, per_dev->offset, bio,
+				      per_dev->length);
+			EXOFS_DBGMSG("write(0x%llx) offset=0x%llx "
+				      "length=0x%llx dev=%d\n",
+				     _LLU(ios->obj.id), _LLU(per_dev->offset),
+				     _LLU(per_dev->length), dev);
 		} else if (ios->kern_buff) {
-			osd_req_write_kern(or, &ios->obj, ios->offset,
+			ret = osd_req_write_kern(or, &ios->obj, per_dev->offset,
 					   ios->kern_buff, ios->length);
-/*			EXOFS_DBGMSG("write_kern sync=%d\n", sync);*/
+			if (unlikely(ret))
+				goto out;
+			EXOFS_DBGMSG2("write_kern(0x%llx) offset=0x%llx "
+				      "length=0x%llx dev=%d\n",
+				     _LLU(ios->obj.id), _LLU(per_dev->offset),
+				     _LLU(ios->length), dev);
 		} else {
 			osd_req_set_attributes(or, &ios->obj);
-/*			EXOFS_DBGMSG("set_attributes sync=%d\n", sync);*/
+			EXOFS_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d\n",
+				     _LLU(ios->obj.id), ios->out_attr_len, dev);
 		}
 
 		if (ios->out_attr)
@@ -308,54 +631,93 @@ int exofs_sbi_write(struct exofs_io_stat
 			osd_req_add_get_attr_list(or, ios->in_attr,
 						  ios->in_attr_len);
 	}
-	ret = exofs_io_execute(ios);
 
 out:
 	return ret;
 }
 
-int exofs_sbi_read(struct exofs_io_state *ios)
+int exofs_sbi_write(struct exofs_io_state *ios)
 {
-	int i, ret;
+	int i;
+	int ret;
 
-	for (i = 0; i < 1; i++) {
-		struct osd_request *or;
-		unsigned first_dev = (unsigned)ios->obj.id;
+	ret = _prepare_for_striping(ios);
+	if (unlikely(ret))
+		return ret;
 
-		first_dev %= ios->sbi->s_numdevs;
-		or = osd_start_request(ios->sbi->s_ods[first_dev], GFP_KERNEL);
-		if (unlikely(!or)) {
-			EXOFS_ERR("%s: osd_start_request failed\n", __func__);
-			ret = -ENOMEM;
-			goto out;
-		}
-		ios->per_dev[i].or = or;
-		ios->numdevs++;
+	for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) {
+		ret = _sbi_write_mirror(ios, i);
+		if (unlikely(ret))
+			return ret;
+	}
 
-		if (ios->bio) {
-			osd_req_read(or, &ios->obj, ios->offset, ios->bio,
-				     ios->length);
-/*			EXOFS_DBGMSG("read sync=%d\n", sync);*/
-		} else if (ios->kern_buff) {
-			osd_req_read_kern(or, &ios->obj, ios->offset,
-					   ios->kern_buff, ios->length);
-/*			EXOFS_DBGMSG("read_kern sync=%d\n", sync);*/
-		} else {
-			osd_req_get_attributes(or, &ios->obj);
-/*			EXOFS_DBGMSG("get_attributes sync=%d\n", sync);*/
-		}
+	ret = exofs_io_execute(ios);
+	return ret;
+}
 
-		if (ios->out_attr)
-			osd_req_add_set_attr_list(or, ios->out_attr,
-						  ios->out_attr_len);
+static int _sbi_read_mirror(struct exofs_io_state *ios, unsigned cur_comp)
+{
+	struct osd_request *or;
+	struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp];
+	unsigned first_dev = (unsigned)ios->obj.id;
 
-		if (ios->in_attr)
-			osd_req_add_get_attr_list(or, ios->in_attr,
-						  ios->in_attr_len);
+	if (ios->pages && !per_dev->length)
+		return 0; /* Just an empty slot */
+
+	first_dev = per_dev->dev + first_dev % ios->layout->mirrors_p1;
+	or = osd_start_request(exofs_ios_od(ios, first_dev), GFP_KERNEL);
+	if (unlikely(!or)) {
+		EXOFS_ERR("%s: osd_start_request failed\n", __func__);
+		return -ENOMEM;
 	}
-	ret = exofs_io_execute(ios);
+	per_dev->or = or;
 
-out:
+	if (ios->pages) {
+		osd_req_read(or, &ios->obj, per_dev->offset,
+				per_dev->bio, per_dev->length);
+		EXOFS_DBGMSG("read(0x%llx) offset=0x%llx length=0x%llx"
+			     " dev=%d\n", _LLU(ios->obj.id),
+			     _LLU(per_dev->offset), _LLU(per_dev->length),
+			     first_dev);
+	} else if (ios->kern_buff) {
+		int ret = osd_req_read_kern(or, &ios->obj, per_dev->offset,
+					    ios->kern_buff, ios->length);
+		EXOFS_DBGMSG2("read_kern(0x%llx) offset=0x%llx "
+			      "length=0x%llx dev=%d ret=>%d\n",
+			      _LLU(ios->obj.id), _LLU(per_dev->offset),
+			      _LLU(ios->length), first_dev, ret);
+		if (unlikely(ret))
+			return ret;
+	} else {
+		osd_req_get_attributes(or, &ios->obj);
+		EXOFS_DBGMSG2("obj(0x%llx) get_attributes=%d dev=%d\n",
+			      _LLU(ios->obj.id), ios->in_attr_len, first_dev);
+	}
+	if (ios->out_attr)
+		osd_req_add_set_attr_list(or, ios->out_attr, ios->out_attr_len);
+
+	if (ios->in_attr)
+		osd_req_add_get_attr_list(or, ios->in_attr, ios->in_attr_len);
+
+	return 0;
+}
+
+int exofs_sbi_read(struct exofs_io_state *ios)
+{
+	int i;
+	int ret;
+
+	ret = _prepare_for_striping(ios);
+	if (unlikely(ret))
+		return ret;
+
+	for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) {
+		ret = _sbi_read_mirror(ios, i);
+		if (unlikely(ret))
+			return ret;
+	}
+
+	ret = exofs_io_execute(ios);
 	return ret;
 }
 
@@ -380,42 +742,82 @@ int extract_attr_from_ios(struct exofs_i
 	return -EIO;
 }
 
+static int _truncate_mirrors(struct exofs_io_state *ios, unsigned cur_comp,
+			     struct osd_attr *attr)
+{
+	int last_comp = cur_comp + ios->layout->mirrors_p1;
+
+	for (; cur_comp < last_comp; ++cur_comp) {
+		struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp];
+		struct osd_request *or;
+
+		or = osd_start_request(exofs_ios_od(ios, cur_comp), GFP_KERNEL);
+		if (unlikely(!or)) {
+			EXOFS_ERR("%s: osd_start_request failed\n", __func__);
+			return -ENOMEM;
+		}
+		per_dev->or = or;
+
+		osd_req_set_attributes(or, &ios->obj);
+		osd_req_add_set_attr_list(or, attr, 1);
+	}
+
+	return 0;
+}
+
 int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
 {
 	struct exofs_sb_info *sbi = oi->vfs_inode.i_sb->s_fs_info;
 	struct exofs_io_state *ios;
-	struct osd_attr attr;
-	__be64 newsize;
+	struct exofs_trunc_attr {
+		struct osd_attr attr;
+		__be64 newsize;
+	} *size_attrs;
+	struct _striping_info si;
 	int i, ret;
 
-	if (exofs_get_io_state(sbi, &ios))
-		return -ENOMEM;
+	ret = exofs_get_io_state(&sbi->layout, &ios);
+	if (unlikely(ret))
+		return ret;
+
+	size_attrs = kcalloc(ios->layout->group_width, sizeof(*size_attrs),
+			     GFP_KERNEL);
+	if (unlikely(!size_attrs)) {
+		ret = -ENOMEM;
+		goto out;
+	}
 
 	ios->obj.id = exofs_oi_objno(oi);
 	ios->cred = oi->i_cred;
 
-	newsize = cpu_to_be64(size);
-	attr = g_attr_logical_length;
-	attr.val_ptr = &newsize;
+	ios->numdevs = ios->layout->s_numdevs;
+	_calc_stripe_info(ios, size, &si);
 
-	for (i = 0; i < sbi->s_numdevs; i++) {
-		struct osd_request *or;
+	for (i = 0; i < ios->layout->group_width; ++i) {
+		struct exofs_trunc_attr *size_attr = &size_attrs[i];
+		u64 obj_size;
 
-		or = osd_start_request(sbi->s_ods[i], GFP_KERNEL);
-		if (unlikely(!or)) {
-			EXOFS_ERR("%s: osd_start_request failed\n", __func__);
-			ret = -ENOMEM;
-			goto out;
-		}
-		ios->per_dev[i].or = or;
-		ios->numdevs++;
+		if (i < si.dev)
+			obj_size = si.obj_offset +
+					ios->layout->stripe_unit - si.unit_off;
+		else if (i == si.dev)
+			obj_size = si.obj_offset;
+		else /* i > si.dev */
+			obj_size = si.obj_offset - si.unit_off;
 
-		osd_req_set_attributes(or, &ios->obj);
-		osd_req_add_set_attr_list(or, &attr, 1);
+		size_attr->newsize = cpu_to_be64(obj_size);
+		size_attr->attr = g_attr_logical_length;
+		size_attr->attr.val_ptr = &size_attr->newsize;
+
+		ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1,
+					&size_attr->attr);
+		if (unlikely(ret))
+			goto out;
 	}
 	ret = exofs_io_execute(ios);
 
 out:
+	kfree(size_attrs);
 	exofs_put_io_state(ios);
 	return ret;
 }
diff -druNp linux-libre-2.6.33-gnu1/fs/exofs/super.c linux-libre-2.6.34-gnu1/fs/exofs/super.c
--- linux-libre-2.6.33-gnu1/fs/exofs/super.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/exofs/super.c	2010-05-16 17:17:36.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/vfs.h>
 #include <linux/random.h>
 #include <linux/exportfs.h>
+#include <linux/slab.h>
 
 #include "exofs.h"
 
@@ -210,7 +211,7 @@ int exofs_sync_fs(struct super_block *sb
 	sbi = sb->s_fs_info;
 	fscb = &sbi->s_fscb;
 
-	ret = exofs_get_io_state(sbi, &ios);
+	ret = exofs_get_io_state(&sbi->layout, &ios);
 	if (ret)
 		goto out;
 
@@ -264,12 +265,12 @@ static void _exofs_print_device(const ch
 
 void exofs_free_sbi(struct exofs_sb_info *sbi)
 {
-	while (sbi->s_numdevs) {
-		int i = --sbi->s_numdevs;
-		struct osd_dev *od = sbi->s_ods[i];
+	while (sbi->layout.s_numdevs) {
+		int i = --sbi->layout.s_numdevs;
+		struct osd_dev *od = sbi->layout.s_ods[i];
 
 		if (od) {
-			sbi->s_ods[i] = NULL;
+			sbi->layout.s_ods[i] = NULL;
 			osduld_put_device(od);
 		}
 	}
@@ -298,8 +299,10 @@ static void exofs_put_super(struct super
 				  msecs_to_jiffies(100));
 	}
 
-	_exofs_print_device("Unmounting", NULL, sbi->s_ods[0], sbi->s_pid);
+	_exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0],
+			    sbi->layout.s_pid);
 
+	bdi_destroy(&sbi->bdi);
 	exofs_free_sbi(sbi);
 	sb->s_fs_info = NULL;
 }
@@ -307,6 +310,8 @@ static void exofs_put_super(struct super
 static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs,
 				    struct exofs_device_table *dt)
 {
+	u64 stripe_length;
+
 	sbi->data_map.odm_num_comps   =
 				le32_to_cpu(dt->dt_data_map.cb_num_comps);
 	sbi->data_map.odm_stripe_unit =
@@ -320,14 +325,63 @@ static int _read_and_match_data_map(stru
 	sbi->data_map.odm_raid_algorithm  =
 				le32_to_cpu(dt->dt_data_map.cb_raid_algorithm);
 
-/* FIXME: Hard coded mirror only for now. if not so do not mount */
-	if ((sbi->data_map.odm_num_comps != numdevs) ||
-	    (sbi->data_map.odm_stripe_unit != EXOFS_BLKSIZE) ||
-	    (sbi->data_map.odm_raid_algorithm != PNFS_OSD_RAID_0) ||
-	    (sbi->data_map.odm_mirror_cnt != (numdevs - 1)))
+/* FIXME: Only raid0 for now. if not so, do not mount */
+	if (sbi->data_map.odm_num_comps != numdevs) {
+		EXOFS_ERR("odm_num_comps(%u) != numdevs(%u)\n",
+			  sbi->data_map.odm_num_comps, numdevs);
 		return -EINVAL;
-	else
-		return 0;
+	}
+	if (sbi->data_map.odm_raid_algorithm != PNFS_OSD_RAID_0) {
+		EXOFS_ERR("Only RAID_0 for now\n");
+		return -EINVAL;
+	}
+	if (0 != (numdevs % (sbi->data_map.odm_mirror_cnt + 1))) {
+		EXOFS_ERR("Data Map wrong, numdevs=%d mirrors=%d\n",
+			  numdevs, sbi->data_map.odm_mirror_cnt);
+		return -EINVAL;
+	}
+
+	if (0 != (sbi->data_map.odm_stripe_unit & ~PAGE_MASK)) {
+		EXOFS_ERR("Stripe Unit(0x%llx)"
+			  " must be Multples of PAGE_SIZE(0x%lx)\n",
+			  _LLU(sbi->data_map.odm_stripe_unit), PAGE_SIZE);
+		return -EINVAL;
+	}
+
+	sbi->layout.stripe_unit = sbi->data_map.odm_stripe_unit;
+	sbi->layout.mirrors_p1 = sbi->data_map.odm_mirror_cnt + 1;
+
+	if (sbi->data_map.odm_group_width) {
+		sbi->layout.group_width = sbi->data_map.odm_group_width;
+		sbi->layout.group_depth = sbi->data_map.odm_group_depth;
+		if (!sbi->layout.group_depth) {
+			EXOFS_ERR("group_depth == 0 && group_width != 0\n");
+			return -EINVAL;
+		}
+		sbi->layout.group_count = sbi->data_map.odm_num_comps /
+						sbi->layout.mirrors_p1 /
+						sbi->data_map.odm_group_width;
+	} else {
+		if (sbi->data_map.odm_group_depth) {
+			printk(KERN_NOTICE "Warning: group_depth ignored "
+				"group_width == 0 && group_depth == %d\n",
+				sbi->data_map.odm_group_depth);
+			sbi->data_map.odm_group_depth = 0;
+		}
+		sbi->layout.group_width = sbi->data_map.odm_num_comps /
+							sbi->layout.mirrors_p1;
+		sbi->layout.group_depth = -1;
+		sbi->layout.group_count = 1;
+	}
+
+	stripe_length = (u64)sbi->layout.group_width * sbi->layout.stripe_unit;
+	if (stripe_length >= (1ULL << 32)) {
+		EXOFS_ERR("Total Stripe length(0x%llx)"
+			  " >= 32bit is not supported\n", _LLU(stripe_length));
+		return -EINVAL;
+	}
+
+	return 0;
 }
 
 /* @odi is valid only as long as @fscb_dev is valid */
@@ -361,7 +415,7 @@ static int exofs_read_lookup_dev_table(s
 {
 	struct exofs_sb_info *sbi = *psbi;
 	struct osd_dev *fscb_od;
-	struct osd_obj_id obj = {.partition = sbi->s_pid,
+	struct osd_obj_id obj = {.partition = sbi->layout.s_pid,
 				 .id = EXOFS_DEVTABLE_ID};
 	struct exofs_device_table *dt;
 	unsigned table_bytes = table_count * sizeof(dt->dt_dev_table[0]) +
@@ -376,9 +430,9 @@ static int exofs_read_lookup_dev_table(s
 		return -ENOMEM;
 	}
 
-	fscb_od = sbi->s_ods[0];
-	sbi->s_ods[0] = NULL;
-	sbi->s_numdevs = 0;
+	fscb_od = sbi->layout.s_ods[0];
+	sbi->layout.s_ods[0] = NULL;
+	sbi->layout.s_numdevs = 0;
 	ret = exofs_read_kern(fscb_od, sbi->s_cred, &obj, 0, dt, table_bytes);
 	if (unlikely(ret)) {
 		EXOFS_ERR("ERROR: reading device table\n");
@@ -397,14 +451,15 @@ static int exofs_read_lookup_dev_table(s
 		goto out;
 
 	if (likely(numdevs > 1)) {
-		unsigned size = numdevs * sizeof(sbi->s_ods[0]);
+		unsigned size = numdevs * sizeof(sbi->layout.s_ods[0]);
 
 		sbi = krealloc(sbi, sizeof(*sbi) + size, GFP_KERNEL);
 		if (unlikely(!sbi)) {
 			ret = -ENOMEM;
 			goto out;
 		}
-		memset(&sbi->s_ods[1], 0, size - sizeof(sbi->s_ods[0]));
+		memset(&sbi->layout.s_ods[1], 0,
+		       size - sizeof(sbi->layout.s_ods[0]));
 		*psbi = sbi;
 	}
 
@@ -427,8 +482,8 @@ static int exofs_read_lookup_dev_table(s
 		 * line. We always keep them in device-table order.
 		 */
 		if (fscb_od && osduld_device_same(fscb_od, &odi)) {
-			sbi->s_ods[i] = fscb_od;
-			++sbi->s_numdevs;
+			sbi->layout.s_ods[i] = fscb_od;
+			++sbi->layout.s_numdevs;
 			fscb_od = NULL;
 			continue;
 		}
@@ -441,8 +496,8 @@ static int exofs_read_lookup_dev_table(s
 			goto out;
 		}
 
-		sbi->s_ods[i] = od;
-		++sbi->s_numdevs;
+		sbi->layout.s_ods[i] = od;
+		++sbi->layout.s_numdevs;
 
 		/* Read the fscb of the other devices to make sure the FS
 		 * partition is there.
@@ -492,6 +547,10 @@ static int exofs_fill_super(struct super
 	if (!sbi)
 		return -ENOMEM;
 
+	ret = bdi_setup_and_register(&sbi->bdi, "exofs", BDI_CAP_MAP_COPY);
+	if (ret)
+		goto free_bdi;
+
 	/* use mount options to fill superblock */
 	od = osduld_path_lookup(opts->dev_name);
 	if (IS_ERR(od)) {
@@ -499,9 +558,15 @@ static int exofs_fill_super(struct super
 		goto free_sbi;
 	}
 
-	sbi->s_ods[0] = od;
-	sbi->s_numdevs = 1;
-	sbi->s_pid = opts->pid;
+	/* Default layout in case we do not have a device-table */
+	sbi->layout.stripe_unit = PAGE_SIZE;
+	sbi->layout.mirrors_p1 = 1;
+	sbi->layout.group_width = 1;
+	sbi->layout.group_depth = -1;
+	sbi->layout.group_count = 1;
+	sbi->layout.s_ods[0] = od;
+	sbi->layout.s_numdevs = 1;
+	sbi->layout.s_pid = opts->pid;
 	sbi->s_timeout = opts->timeout;
 
 	/* fill in some other data by hand */
@@ -514,7 +579,7 @@ static int exofs_fill_super(struct super
 	sb->s_bdev = NULL;
 	sb->s_dev = 0;
 
-	obj.partition = sbi->s_pid;
+	obj.partition = sbi->layout.s_pid;
 	obj.id = EXOFS_SUPER_ID;
 	exofs_make_credential(sbi->s_cred, &obj);
 
@@ -552,6 +617,7 @@ static int exofs_fill_super(struct super
 	}
 
 	/* set up operation vectors */
+	sb->s_bdi = &sbi->bdi;
 	sb->s_fs_info = sbi;
 	sb->s_op = &exofs_sops;
 	sb->s_export_op = &exofs_export_ops;
@@ -578,13 +644,15 @@ static int exofs_fill_super(struct super
 		goto free_sbi;
 	}
 
-	_exofs_print_device("Mounting", opts->dev_name, sbi->s_ods[0],
-			    sbi->s_pid);
+	_exofs_print_device("Mounting", opts->dev_name, sbi->layout.s_ods[0],
+			    sbi->layout.s_pid);
 	return 0;
 
 free_sbi:
+	bdi_destroy(&sbi->bdi);
+free_bdi:
 	EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n",
-		  opts->dev_name, sbi->s_pid, ret);
+		  opts->dev_name, sbi->layout.s_pid, ret);
 	exofs_free_sbi(sbi);
 	return ret;
 }
@@ -627,7 +695,7 @@ static int exofs_statfs(struct dentry *d
 	uint8_t cred_a[OSD_CAP_LEN];
 	int ret;
 
-	ret = exofs_get_io_state(sbi, &ios);
+	ret = exofs_get_io_state(&sbi->layout, &ios);
 	if (ret) {
 		EXOFS_DBGMSG("exofs_get_io_state failed.\n");
 		return ret;
diff -druNp linux-libre-2.6.33-gnu1/fs/ext2/balloc.c linux-libre-2.6.34-gnu1/fs/ext2/balloc.c
--- linux-libre-2.6.33-gnu1/fs/ext2/balloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext2/balloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -13,6 +13,7 @@
 
 #include "ext2.h"
 #include <linux/quotaops.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/buffer_head.h>
 #include <linux/capability.h>
@@ -570,7 +571,7 @@ do_more:
 error_return:
 	brelse(bitmap_bh);
 	release_blocks(sb, freed);
-	vfs_dq_free_block(inode, freed);
+	dquot_free_block(inode, freed);
 }
 
 /**
@@ -1236,6 +1237,7 @@ ext2_fsblk_t ext2_new_blocks(struct inod
 	unsigned short windowsz = 0;
 	unsigned long ngroups;
 	unsigned long num = *count;
+	int ret;
 
 	*errp = -ENOSPC;
 	sb = inode->i_sb;
@@ -1247,8 +1249,9 @@ ext2_fsblk_t ext2_new_blocks(struct inod
 	/*
 	 * Check quota for allocation of this block.
 	 */
-	if (vfs_dq_alloc_block(inode, num)) {
-		*errp = -EDQUOT;
+	ret = dquot_alloc_block(inode, num);
+	if (ret) {
+		*errp = ret;
 		return 0;
 	}
 
@@ -1409,7 +1412,7 @@ allocated:
 
 	*errp = 0;
 	brelse(bitmap_bh);
-	vfs_dq_free_block(inode, *count-num);
+	dquot_free_block(inode, *count-num);
 	*count = num;
 	return ret_block;
 
@@ -1420,7 +1423,7 @@ out:
 	 * Undo the block allocation
 	 */
 	if (!performed_allocation)
-		vfs_dq_free_block(inode, *count);
+		dquot_free_block(inode, *count);
 	brelse(bitmap_bh);
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/fs/ext2/ext2.h linux-libre-2.6.34-gnu1/fs/ext2/ext2.h
--- linux-libre-2.6.33-gnu1/fs/ext2/ext2.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext2/ext2.h	2010-05-16 17:17:36.000000000 -0400
@@ -118,7 +118,7 @@ extern unsigned long ext2_count_free (st
 
 /* inode.c */
 extern struct inode *ext2_iget (struct super_block *, unsigned long);
-extern int ext2_write_inode (struct inode *, int);
+extern int ext2_write_inode (struct inode *, struct writeback_control *);
 extern void ext2_delete_inode (struct inode *);
 extern int ext2_sync_inode (struct inode *);
 extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int);
diff -druNp linux-libre-2.6.33-gnu1/fs/ext2/file.c linux-libre-2.6.34-gnu1/fs/ext2/file.c
--- linux-libre-2.6.33-gnu1/fs/ext2/file.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext2/file.c	2010-05-16 17:17:36.000000000 -0400
@@ -20,6 +20,7 @@
 
 #include <linux/time.h>
 #include <linux/pagemap.h>
+#include <linux/quotaops.h>
 #include "ext2.h"
 #include "xattr.h"
 #include "acl.h"
@@ -70,7 +71,7 @@ const struct file_operations ext2_file_o
 	.compat_ioctl	= ext2_compat_ioctl,
 #endif
 	.mmap		= generic_file_mmap,
-	.open		= generic_file_open,
+	.open		= dquot_file_open,
 	.release	= ext2_release_file,
 	.fsync		= ext2_fsync,
 	.splice_read	= generic_file_splice_read,
@@ -87,7 +88,7 @@ const struct file_operations ext2_xip_fi
 	.compat_ioctl	= ext2_compat_ioctl,
 #endif
 	.mmap		= xip_file_mmap,
-	.open		= generic_file_open,
+	.open		= dquot_file_open,
 	.release	= ext2_release_file,
 	.fsync		= ext2_fsync,
 };
diff -druNp linux-libre-2.6.33-gnu1/fs/ext2/ialloc.c linux-libre-2.6.34-gnu1/fs/ext2/ialloc.c
--- linux-libre-2.6.33-gnu1/fs/ext2/ialloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext2/ialloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -121,8 +121,8 @@ void ext2_free_inode (struct inode * ino
 	if (!is_bad_inode(inode)) {
 		/* Quota is already initialized in iput() */
 		ext2_xattr_delete_inode(inode);
-		vfs_dq_free_inode(inode);
-		vfs_dq_drop(inode);
+		dquot_free_inode(inode);
+		dquot_drop(inode);
 	}
 
 	es = EXT2_SB(sb)->s_es;
@@ -586,10 +586,10 @@ got:
 		goto fail_drop;
 	}
 
-	if (vfs_dq_alloc_inode(inode)) {
-		err = -EDQUOT;
+	dquot_initialize(inode);
+	err = dquot_alloc_inode(inode);
+	if (err)
 		goto fail_drop;
-	}
 
 	err = ext2_init_acl(inode, dir);
 	if (err)
@@ -605,10 +605,10 @@ got:
 	return inode;
 
 fail_free_drop:
-	vfs_dq_free_inode(inode);
+	dquot_free_inode(inode);
 
 fail_drop:
-	vfs_dq_drop(inode);
+	dquot_drop(inode);
 	inode->i_flags |= S_NOQUOTA;
 	inode->i_nlink = 0;
 	unlock_new_inode(inode);
diff -druNp linux-libre-2.6.33-gnu1/fs/ext2/inode.c linux-libre-2.6.34-gnu1/fs/ext2/inode.c
--- linux-libre-2.6.33-gnu1/fs/ext2/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext2/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -41,6 +41,8 @@ MODULE_AUTHOR("Remy Card and others");
 MODULE_DESCRIPTION("Second Extended Filesystem");
 MODULE_LICENSE("GPL");
 
+static int __ext2_write_inode(struct inode *inode, int do_sync);
+
 /*
  * Test whether an inode is a fast symlink.
  */
@@ -58,13 +60,15 @@ static inline int ext2_inode_is_fast_sym
  */
 void ext2_delete_inode (struct inode * inode)
 {
+	if (!is_bad_inode(inode))
+		dquot_initialize(inode);
 	truncate_inode_pages(&inode->i_data, 0);
 
 	if (is_bad_inode(inode))
 		goto no_delete;
 	EXT2_I(inode)->i_dtime	= get_seconds();
 	mark_inode_dirty(inode);
-	ext2_write_inode(inode, inode_needs_sync(inode));
+	__ext2_write_inode(inode, inode_needs_sync(inode));
 
 	inode->i_size = 0;
 	if (inode->i_blocks)
@@ -1335,7 +1339,7 @@ bad_inode:
 	return ERR_PTR(ret);
 }
 
-int ext2_write_inode(struct inode *inode, int do_sync)
+static int __ext2_write_inode(struct inode *inode, int do_sync)
 {
 	struct ext2_inode_info *ei = EXT2_I(inode);
 	struct super_block *sb = inode->i_sb;
@@ -1440,6 +1444,11 @@ int ext2_write_inode(struct inode *inode
 	return err;
 }
 
+int ext2_write_inode(struct inode *inode, struct writeback_control *wbc)
+{
+	return __ext2_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
+}
+
 int ext2_sync_inode(struct inode *inode)
 {
 	struct writeback_control wbc = {
@@ -1457,9 +1466,12 @@ int ext2_setattr(struct dentry *dentry,
 	error = inode_change_ok(inode, iattr);
 	if (error)
 		return error;
+
+	if (iattr->ia_valid & ATTR_SIZE)
+		dquot_initialize(inode);
 	if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
 	    (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
-		error = vfs_dq_transfer(inode, iattr) ? -EDQUOT : 0;
+		error = dquot_transfer(inode, iattr);
 		if (error)
 			return error;
 	}
diff -druNp linux-libre-2.6.33-gnu1/fs/ext2/namei.c linux-libre-2.6.34-gnu1/fs/ext2/namei.c
--- linux-libre-2.6.33-gnu1/fs/ext2/namei.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext2/namei.c	2010-05-16 17:17:36.000000000 -0400
@@ -31,6 +31,7 @@
  */
 
 #include <linux/pagemap.h>
+#include <linux/quotaops.h>
 #include "ext2.h"
 #include "xattr.h"
 #include "acl.h"
@@ -99,24 +100,27 @@ struct dentry *ext2_get_parent(struct de
  */
 static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, struct nameidata *nd)
 {
-	struct inode * inode = ext2_new_inode (dir, mode);
-	int err = PTR_ERR(inode);
-	if (!IS_ERR(inode)) {
-		inode->i_op = &ext2_file_inode_operations;
-		if (ext2_use_xip(inode->i_sb)) {
-			inode->i_mapping->a_ops = &ext2_aops_xip;
-			inode->i_fop = &ext2_xip_file_operations;
-		} else if (test_opt(inode->i_sb, NOBH)) {
-			inode->i_mapping->a_ops = &ext2_nobh_aops;
-			inode->i_fop = &ext2_file_operations;
-		} else {
-			inode->i_mapping->a_ops = &ext2_aops;
-			inode->i_fop = &ext2_file_operations;
-		}
-		mark_inode_dirty(inode);
-		err = ext2_add_nondir(dentry, inode);
+	struct inode *inode;
+
+	dquot_initialize(dir);
+
+	inode = ext2_new_inode(dir, mode);
+	if (IS_ERR(inode))
+		return PTR_ERR(inode);
+
+	inode->i_op = &ext2_file_inode_operations;
+	if (ext2_use_xip(inode->i_sb)) {
+		inode->i_mapping->a_ops = &ext2_aops_xip;
+		inode->i_fop = &ext2_xip_file_operations;
+	} else if (test_opt(inode->i_sb, NOBH)) {
+		inode->i_mapping->a_ops = &ext2_nobh_aops;
+		inode->i_fop = &ext2_file_operations;
+	} else {
+		inode->i_mapping->a_ops = &ext2_aops;
+		inode->i_fop = &ext2_file_operations;
 	}
-	return err;
+	mark_inode_dirty(inode);
+	return ext2_add_nondir(dentry, inode);
 }
 
 static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
@@ -127,6 +131,8 @@ static int ext2_mknod (struct inode * di
 	if (!new_valid_dev(rdev))
 		return -EINVAL;
 
+	dquot_initialize(dir);
+
 	inode = ext2_new_inode (dir, mode);
 	err = PTR_ERR(inode);
 	if (!IS_ERR(inode)) {
@@ -151,6 +157,8 @@ static int ext2_symlink (struct inode *
 	if (l > sb->s_blocksize)
 		goto out;
 
+	dquot_initialize(dir);
+
 	inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO);
 	err = PTR_ERR(inode);
 	if (IS_ERR(inode))
@@ -194,6 +202,8 @@ static int ext2_link (struct dentry * ol
 	if (inode->i_nlink >= EXT2_LINK_MAX)
 		return -EMLINK;
 
+	dquot_initialize(dir);
+
 	inode->i_ctime = CURRENT_TIME_SEC;
 	inode_inc_link_count(inode);
 	atomic_inc(&inode->i_count);
@@ -216,6 +226,8 @@ static int ext2_mkdir(struct inode * dir
 	if (dir->i_nlink >= EXT2_LINK_MAX)
 		goto out;
 
+	dquot_initialize(dir);
+
 	inode_inc_link_count(dir);
 
 	inode = ext2_new_inode (dir, S_IFDIR | mode);
@@ -262,6 +274,8 @@ static int ext2_unlink(struct inode * di
 	struct page * page;
 	int err = -ENOENT;
 
+	dquot_initialize(dir);
+
 	de = ext2_find_entry (dir, &dentry->d_name, &page);
 	if (!de)
 		goto out;
@@ -304,6 +318,9 @@ static int ext2_rename (struct inode * o
 	struct ext2_dir_entry_2 * old_de;
 	int err = -ENOENT;
 
+	dquot_initialize(old_dir);
+	dquot_initialize(new_dir);
+
 	old_de = ext2_find_entry (old_dir, &old_dentry->d_name, &old_page);
 	if (!old_de)
 		goto out;
diff -druNp linux-libre-2.6.33-gnu1/fs/ext2/super.c linux-libre-2.6.34-gnu1/fs/ext2/super.c
--- linux-libre-2.6.33-gnu1/fs/ext2/super.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext2/super.c	2010-05-16 17:17:36.000000000 -0400
@@ -194,6 +194,8 @@ static void destroy_inodecache(void)
 static void ext2_clear_inode(struct inode *inode)
 {
 	struct ext2_block_alloc_info *rsv = EXT2_I(inode)->i_block_alloc_info;
+
+	dquot_drop(inode);
 	ext2_discard_reservation(inode);
 	EXT2_I(inode)->i_block_alloc_info = NULL;
 	if (unlikely(rsv))
diff -druNp linux-libre-2.6.33-gnu1/fs/ext2/symlink.c linux-libre-2.6.34-gnu1/fs/ext2/symlink.c
--- linux-libre-2.6.33-gnu1/fs/ext2/symlink.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext2/symlink.c	2010-05-16 17:17:36.000000000 -0400
@@ -32,6 +32,7 @@ const struct inode_operations ext2_symli
 	.readlink	= generic_readlink,
 	.follow_link	= page_follow_link_light,
 	.put_link	= page_put_link,
+	.setattr	= ext2_setattr,
 #ifdef CONFIG_EXT2_FS_XATTR
 	.setxattr	= generic_setxattr,
 	.getxattr	= generic_getxattr,
@@ -43,6 +44,7 @@ const struct inode_operations ext2_symli
 const struct inode_operations ext2_fast_symlink_inode_operations = {
 	.readlink	= generic_readlink,
 	.follow_link	= ext2_follow_link,
+	.setattr	= ext2_setattr,
 #ifdef CONFIG_EXT2_FS_XATTR
 	.setxattr	= generic_setxattr,
 	.getxattr	= generic_getxattr,
diff -druNp linux-libre-2.6.33-gnu1/fs/ext2/xattr.c linux-libre-2.6.34-gnu1/fs/ext2/xattr.c
--- linux-libre-2.6.33-gnu1/fs/ext2/xattr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext2/xattr.c	2010-05-16 17:17:36.000000000 -0400
@@ -644,8 +644,8 @@ ext2_xattr_set2(struct inode *inode, str
 				   the inode.  */
 				ea_bdebug(new_bh, "reusing block");
 
-				error = -EDQUOT;
-				if (vfs_dq_alloc_block(inode, 1)) {
+				error = dquot_alloc_block(inode, 1);
+				if (error) {
 					unlock_buffer(new_bh);
 					goto cleanup;
 				}
@@ -702,7 +702,7 @@ ext2_xattr_set2(struct inode *inode, str
 		 * as if nothing happened and cleanup the unused block */
 		if (error && error != -ENOSPC) {
 			if (new_bh && new_bh != old_bh)
-				vfs_dq_free_block(inode, 1);
+				dquot_free_block(inode, 1);
 			goto cleanup;
 		}
 	} else
@@ -734,7 +734,7 @@ ext2_xattr_set2(struct inode *inode, str
 			le32_add_cpu(&HDR(old_bh)->h_refcount, -1);
 			if (ce)
 				mb_cache_entry_release(ce);
-			vfs_dq_free_block(inode, 1);
+			dquot_free_block(inode, 1);
 			mark_buffer_dirty(old_bh);
 			ea_bdebug(old_bh, "refcount now=%d",
 				le32_to_cpu(HDR(old_bh)->h_refcount));
@@ -797,7 +797,7 @@ ext2_xattr_delete_inode(struct inode *in
 		mark_buffer_dirty(bh);
 		if (IS_SYNC(inode))
 			sync_dirty_buffer(bh);
-		vfs_dq_free_block(inode, 1);
+		dquot_free_block(inode, 1);
 	}
 	EXT2_I(inode)->i_file_acl = 0;
 
diff -druNp linux-libre-2.6.33-gnu1/fs/ext2/xattr_security.c linux-libre-2.6.34-gnu1/fs/ext2/xattr_security.c
--- linux-libre-2.6.33-gnu1/fs/ext2/xattr_security.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext2/xattr_security.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/fs.h>
 #include <linux/ext2_fs.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/ext3/balloc.c linux-libre-2.6.34-gnu1/fs/ext3/balloc.c
--- linux-libre-2.6.33-gnu1/fs/ext3/balloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext3/balloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/time.h>
 #include <linux/capability.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/jbd.h>
 #include <linux/ext3_fs.h>
 #include <linux/ext3_jbd.h>
@@ -676,7 +677,7 @@ void ext3_free_blocks(handle_t *handle,
 	}
 	ext3_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks);
 	if (dquot_freed_blocks)
-		vfs_dq_free_block(inode, dquot_freed_blocks);
+		dquot_free_block(inode, dquot_freed_blocks);
 	return;
 }
 
@@ -1502,8 +1503,9 @@ ext3_fsblk_t ext3_new_blocks(handle_t *h
 	/*
 	 * Check quota for allocation of this block.
 	 */
-	if (vfs_dq_alloc_block(inode, num)) {
-		*errp = -EDQUOT;
+	err = dquot_alloc_block(inode, num);
+	if (err) {
+		*errp = err;
 		return 0;
 	}
 
@@ -1713,7 +1715,7 @@ allocated:
 
 	*errp = 0;
 	brelse(bitmap_bh);
-	vfs_dq_free_block(inode, *count-num);
+	dquot_free_block(inode, *count-num);
 	*count = num;
 	return ret_block;
 
@@ -1728,7 +1730,7 @@ out:
 	 * Undo the block allocation
 	 */
 	if (!performed_allocation)
-		vfs_dq_free_block(inode, *count);
+		dquot_free_block(inode, *count);
 	brelse(bitmap_bh);
 	return 0;
 }
diff -druNp linux-libre-2.6.33-gnu1/fs/ext3/file.c linux-libre-2.6.34-gnu1/fs/ext3/file.c
--- linux-libre-2.6.33-gnu1/fs/ext3/file.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext3/file.c	2010-05-16 17:17:36.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/jbd.h>
+#include <linux/quotaops.h>
 #include <linux/ext3_fs.h>
 #include <linux/ext3_jbd.h>
 #include "xattr.h"
@@ -33,9 +34,9 @@
  */
 static int ext3_release_file (struct inode * inode, struct file * filp)
 {
-	if (EXT3_I(inode)->i_state & EXT3_STATE_FLUSH_ON_CLOSE) {
+	if (ext3_test_inode_state(inode, EXT3_STATE_FLUSH_ON_CLOSE)) {
 		filemap_flush(inode->i_mapping);
-		EXT3_I(inode)->i_state &= ~EXT3_STATE_FLUSH_ON_CLOSE;
+		ext3_clear_inode_state(inode, EXT3_STATE_FLUSH_ON_CLOSE);
 	}
 	/* if we are the last writer on the inode, drop the block reservation */
 	if ((filp->f_mode & FMODE_WRITE) &&
@@ -62,7 +63,7 @@ const struct file_operations ext3_file_o
 	.compat_ioctl	= ext3_compat_ioctl,
 #endif
 	.mmap		= generic_file_mmap,
-	.open		= generic_file_open,
+	.open		= dquot_file_open,
 	.release	= ext3_release_file,
 	.fsync		= ext3_sync_file,
 	.splice_read	= generic_file_splice_read,
diff -druNp linux-libre-2.6.33-gnu1/fs/ext3/ialloc.c linux-libre-2.6.34-gnu1/fs/ext3/ialloc.c
--- linux-libre-2.6.33-gnu1/fs/ext3/ialloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext3/ialloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -123,10 +123,10 @@ void ext3_free_inode (handle_t *handle,
 	 * Note: we must free any quota before locking the superblock,
 	 * as writing the quota to disk may need the lock as well.
 	 */
-	vfs_dq_init(inode);
+	dquot_initialize(inode);
 	ext3_xattr_delete_inode(handle, inode);
-	vfs_dq_free_inode(inode);
-	vfs_dq_drop(inode);
+	dquot_free_inode(inode);
+	dquot_drop(inode);
 
 	is_directory = S_ISDIR(inode->i_mode);
 
@@ -582,16 +582,18 @@ got:
 	inode->i_generation = sbi->s_next_generation++;
 	spin_unlock(&sbi->s_next_gen_lock);
 
-	ei->i_state = EXT3_STATE_NEW;
+	ei->i_state_flags = 0;
+	ext3_set_inode_state(inode, EXT3_STATE_NEW);
+
 	ei->i_extra_isize =
 		(EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) ?
 		sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0;
 
 	ret = inode;
-	if (vfs_dq_alloc_inode(inode)) {
-		err = -EDQUOT;
+	dquot_initialize(inode);
+	err = dquot_alloc_inode(inode);
+	if (err)
 		goto fail_drop;
-	}
 
 	err = ext3_init_acl(handle, inode, dir);
 	if (err)
@@ -619,10 +621,10 @@ really_out:
 	return ret;
 
 fail_free_drop:
-	vfs_dq_free_inode(inode);
+	dquot_free_inode(inode);
 
 fail_drop:
-	vfs_dq_drop(inode);
+	dquot_drop(inode);
 	inode->i_flags |= S_NOQUOTA;
 	inode->i_nlink = 0;
 	unlock_new_inode(inode);
diff -druNp linux-libre-2.6.33-gnu1/fs/ext3/inode.c linux-libre-2.6.34-gnu1/fs/ext3/inode.c
--- linux-libre-2.6.33-gnu1/fs/ext3/inode.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext3/inode.c	2010-05-16 17:17:36.000000000 -0400
@@ -196,6 +196,9 @@ void ext3_delete_inode (struct inode * i
 {
 	handle_t *handle;
 
+	if (!is_bad_inode(inode))
+		dquot_initialize(inode);
+
 	truncate_inode_pages(&inode->i_data, 0);
 
 	if (is_bad_inode(inode))
@@ -1378,7 +1381,7 @@ static int ext3_journalled_write_end(str
 	 */
 	if (pos + len > inode->i_size && ext3_can_truncate(inode))
 		ext3_orphan_add(handle, inode);
-	EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
+	ext3_set_inode_state(inode, EXT3_STATE_JDATA);
 	if (inode->i_size > EXT3_I(inode)->i_disksize) {
 		EXT3_I(inode)->i_disksize = inode->i_size;
 		ret2 = ext3_mark_inode_dirty(handle, inode);
@@ -1417,7 +1420,7 @@ static sector_t ext3_bmap(struct address
 	journal_t *journal;
 	int err;
 
-	if (EXT3_I(inode)->i_state & EXT3_STATE_JDATA) {
+	if (ext3_test_inode_state(inode, EXT3_STATE_JDATA)) {
 		/*
 		 * This is a REALLY heavyweight approach, but the use of
 		 * bmap on dirty files is expected to be extremely rare:
@@ -1436,7 +1439,7 @@ static sector_t ext3_bmap(struct address
 		 * everything they get.
 		 */
 
-		EXT3_I(inode)->i_state &= ~EXT3_STATE_JDATA;
+		ext3_clear_inode_state(inode, EXT3_STATE_JDATA);
 		journal = EXT3_JOURNAL(inode);
 		journal_lock_updates(journal);
 		err = journal_flush(journal);
@@ -1528,6 +1531,7 @@ static int ext3_ordered_writepage(struct
 	int err;
 
 	J_ASSERT(PageLocked(page));
+	WARN_ON_ONCE(IS_RDONLY(inode));
 
 	/*
 	 * We give up here if we're reentered, because it might be for a
@@ -1600,6 +1604,9 @@ static int ext3_writeback_writepage(stru
 	int ret = 0;
 	int err;
 
+	J_ASSERT(PageLocked(page));
+	WARN_ON_ONCE(IS_RDONLY(inode));
+
 	if (ext3_journal_current_handle())
 		goto out_fail;
 
@@ -1642,6 +1649,9 @@ static int ext3_journalled_writepage(str
 	int ret = 0;
 	int err;
 
+	J_ASSERT(PageLocked(page));
+	WARN_ON_ONCE(IS_RDONLY(inode));
+
 	if (ext3_journal_current_handle())
 		goto no_write;
 
@@ -1670,7 +1680,7 @@ static int ext3_journalled_writepage(str
 				PAGE_CACHE_SIZE, NULL, write_end_fn);
 		if (ret == 0)
 			ret = err;
-		EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
+		ext3_set_inode_state(inode, EXT3_STATE_JDATA);
 		unlock_page(page);
 	} else {
 		/*
@@ -1785,8 +1795,9 @@ retry:
 		handle = ext3_journal_start(inode, 2);
 		if (IS_ERR(handle)) {
 			/* This is really bad luck. We've written the data
-			 * but cannot extend i_size. Bail out and pretend
-			 * the write failed... */
+			 * but cannot extend i_size. Truncate allocated blocks
+			 * and pretend the write failed... */
+			ext3_truncate(inode);
 			ret = PTR_ERR(handle);
 			goto out;
 		}
@@ -2402,7 +2413,7 @@ void ext3_truncate(struct inode *inode)
 		goto out_notrans;
 
 	if (inode->i_size == 0 && ext3_should_writeback_data(inode))
-		ei->i_state |= EXT3_STATE_FLUSH_ON_CLOSE;
+		ext3_set_inode_state(inode, EXT3_STATE_FLUSH_ON_CLOSE);
 
 	/*
 	 * We have to lock the EOF page here, because lock_page() nests
@@ -2721,7 +2732,7 @@ int ext3_get_inode_loc(struct inode *ino
 {
 	/* We have all inode data except xattrs in memory here. */
 	return __ext3_get_inode_loc(inode, iloc,
-		!(EXT3_I(inode)->i_state & EXT3_STATE_XATTR));
+		!ext3_test_inode_state(inode, EXT3_STATE_XATTR));
 }
 
 void ext3_set_inode_flags(struct inode *inode)
@@ -2800,7 +2811,7 @@ struct inode *ext3_iget(struct super_blo
 	inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime);
 	inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0;
 
-	ei->i_state = 0;
+	ei->i_state_flags = 0;
 	ei->i_dir_start_lookup = 0;
 	ei->i_dtime = le32_to_cpu(raw_inode->i_dtime);
 	/* We now have enough fields to check if the inode was active or not.
@@ -2893,7 +2904,7 @@ struct inode *ext3_iget(struct super_blo
 					EXT3_GOOD_OLD_INODE_SIZE +
 					ei->i_extra_isize;
 			if (*magic == cpu_to_le32(EXT3_XATTR_MAGIC))
-				 ei->i_state |= EXT3_STATE_XATTR;
+				 ext3_set_inode_state(inode, EXT3_STATE_XATTR);
 		}
 	} else
 		ei->i_extra_isize = 0;
@@ -2955,7 +2966,7 @@ again:
 
 	/* For fields not not tracking in the in-memory inode,
 	 * initialise them to zero for new inodes. */
-	if (ei->i_state & EXT3_STATE_NEW)
+	if (ext3_test_inode_state(inode, EXT3_STATE_NEW))
 		memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size);
 
 	ext3_get_inode_flags(ei);
@@ -3052,7 +3063,7 @@ again:
 	rc = ext3_journal_dirty_metadata(handle, bh);
 	if (!err)
 		err = rc;
-	ei->i_state &= ~EXT3_STATE_NEW;
+	ext3_clear_inode_state(inode, EXT3_STATE_NEW);
 
 	atomic_set(&ei->i_sync_tid, handle->h_transaction->t_tid);
 out_brelse:
@@ -3096,7 +3107,7 @@ out_brelse:
  * `stuff()' is running, and the new i_size will be lost.  Plus the inode
  * will no longer be on the superblock's dirty inode list.
  */
-int ext3_write_inode(struct inode *inode, int wait)
+int ext3_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
 	if (current->flags & PF_MEMALLOC)
 		return 0;
@@ -3107,7 +3118,7 @@ int ext3_write_inode(struct inode *inode
 		return -EIO;
 	}
 
-	if (!wait)
+	if (wbc->sync_mode != WB_SYNC_ALL)
 		return 0;
 
 	return ext3_force_commit(inode->i_sb);
@@ -3140,6 +3151,8 @@ int ext3_setattr(struct dentry *dentry,
 	if (error)
 		return error;
 
+	if (ia_valid & ATTR_SIZE)
+		dquot_initialize(inode);
 	if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
 		(ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
 		handle_t *handle;
@@ -3152,7 +3165,7 @@ int ext3_setattr(struct dentry *dentry,
 			error = PTR_ERR(handle);
 			goto err_out;
 		}
-		error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
+		error = dquot_transfer(inode, attr);
 		if (error) {
 			ext3_journal_stop(handle);
 			return error;
@@ -3237,7 +3250,7 @@ static int ext3_writepage_trans_blocks(s
 		ret = 2 * (bpp + indirects) + 2;
 
 #ifdef CONFIG_QUOTA
-	/* We know that structure was already allocated during vfs_dq_init so
+	/* We know that structure was already allocated during dquot_initialize so
 	 * we will be updating only the data blocks + inodes */
 	ret += EXT3_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb);
 #endif
@@ -3328,7 +3341,7 @@ int ext3_mark_inode_dirty(handle_t *hand
  * i_size has been changed by generic_commit_write() and we thus need
  * to include the updated inode in the current transaction.
  *
- * Also, vfs_dq_alloc_space() will always dirty the inode when blocks
+ * Also, dquot_alloc_space() will always dirty the inode when blocks
  * are allocated to the file.
  *
  * If the inode is marked synchronous, we don't honour that here - doing
diff -druNp linux-libre-2.6.33-gnu1/fs/ext3/namei.c linux-libre-2.6.34-gnu1/fs/ext3/namei.c
--- linux-libre-2.6.33-gnu1/fs/ext3/namei.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext3/namei.c	2010-05-16 17:17:36.000000000 -0400
@@ -1696,6 +1696,8 @@ static int ext3_create (struct inode * d
 	struct inode * inode;
 	int err, retries = 0;
 
+	dquot_initialize(dir);
+
 retry:
 	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
 					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
@@ -1730,6 +1732,8 @@ static int ext3_mknod (struct inode * di
 	if (!new_valid_dev(rdev))
 		return -EINVAL;
 
+	dquot_initialize(dir);
+
 retry:
 	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
 					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
@@ -1766,6 +1770,8 @@ static int ext3_mkdir(struct inode * dir
 	if (dir->i_nlink >= EXT3_LINK_MAX)
 		return -EMLINK;
 
+	dquot_initialize(dir);
+
 retry:
 	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
 					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
@@ -2060,7 +2066,9 @@ static int ext3_rmdir (struct inode * di
 
 	/* Initialize quotas before so that eventual writes go in
 	 * separate transaction */
-	vfs_dq_init(dentry->d_inode);
+	dquot_initialize(dir);
+	dquot_initialize(dentry->d_inode);
+
 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
@@ -2119,7 +2127,9 @@ static int ext3_unlink(struct inode * di
 
 	/* Initialize quotas before so that eventual writes go
 	 * in separate transaction */
-	vfs_dq_init(dentry->d_inode);
+	dquot_initialize(dir);
+	dquot_initialize(dentry->d_inode);
+
 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
@@ -2174,6 +2184,8 @@ static int ext3_symlink (struct inode *
 	if (l > dir->i_sb->s_blocksize)
 		return -ENAMETOOLONG;
 
+	dquot_initialize(dir);
+
 retry:
 	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
 					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 +
@@ -2228,6 +2240,9 @@ static int ext3_link (struct dentry * ol
 
 	if (inode->i_nlink >= EXT3_LINK_MAX)
 		return -EMLINK;
+
+	dquot_initialize(dir);
+
 	/*
 	 * Return -ENOENT if we've raced with unlink and i_nlink is 0.  Doing
 	 * otherwise has the potential to corrupt the orphan inode list.
@@ -2278,12 +2293,15 @@ static int ext3_rename (struct inode * o
 	struct ext3_dir_entry_2 * old_de, * new_de;
 	int retval, flush_file = 0;
 
+	dquot_initialize(old_dir);
+	dquot_initialize(new_dir);
+
 	old_bh = new_bh = dir_bh = NULL;
 
 	/* Initialize quotas before so that eventual writes go
 	 * in separate transaction */
 	if (new_dentry->d_inode)
-		vfs_dq_init(new_dentry->d_inode);
+		dquot_initialize(new_dentry->d_inode);
 	handle = ext3_journal_start(old_dir, 2 *
 					EXT3_DATA_TRANS_BLOCKS(old_dir->i_sb) +
 					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
diff -druNp linux-libre-2.6.33-gnu1/fs/ext3/super.c linux-libre-2.6.34-gnu1/fs/ext3/super.c
--- linux-libre-2.6.33-gnu1/fs/ext3/super.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext3/super.c	2010-05-16 17:17:36.000000000 -0400
@@ -164,7 +164,7 @@ void ext3_msg(struct super_block *sb, co
  * write out the superblock safely.
  *
  * We'll just use the journal_abort() error code to record an error in
- * the journal instead.  On recovery, the journal will compain about
+ * the journal instead.  On recovery, the journal will complain about
  * that error until we've noted it down and cleared it.
  */
 
@@ -181,7 +181,7 @@ static void ext3_handle_error(struct sup
 	if (!test_opt (sb, ERRORS_CONT)) {
 		journal_t *journal = EXT3_SB(sb)->s_journal;
 
-		EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT;
+		set_opt(EXT3_SB(sb)->s_mount_opt, ABORT);
 		if (journal)
 			journal_abort(journal, -EIO);
 	}
@@ -296,7 +296,7 @@ void ext3_abort (struct super_block * sb
 		"error: remounting filesystem read-only");
 	EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS;
 	sb->s_flags |= MS_RDONLY;
-	EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT;
+	set_opt(EXT3_SB(sb)->s_mount_opt, ABORT);
 	if (EXT3_SB(sb)->s_journal)
 		journal_abort(EXT3_SB(sb)->s_journal, -EIO);
 }
@@ -528,6 +528,8 @@ static void destroy_inodecache(void)
 static void ext3_clear_inode(struct inode *inode)
 {
 	struct ext3_block_alloc_info *rsv = EXT3_I(inode)->i_block_alloc_info;
+
+	dquot_drop(inode);
 	ext3_discard_reservation(inode);
 	EXT3_I(inode)->i_block_alloc_info = NULL;
 	if (unlikely(rsv))
@@ -562,10 +564,10 @@ static inline void ext3_show_quota_optio
 	if (sbi->s_qf_names[GRPQUOTA])
 		seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);
 
-	if (sbi->s_mount_opt & EXT3_MOUNT_USRQUOTA)
+	if (test_opt(sb, USRQUOTA))
 		seq_puts(seq, ",usrquota");
 
-	if (sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA)
+	if (test_opt(sb, GRPQUOTA))
 		seq_puts(seq, ",grpquota");
 #endif
 }
@@ -656,8 +658,7 @@ static int ext3_show_options(struct seq_
 	if (test_opt(sb, NOBH))
 		seq_puts(seq, ",nobh");
 
-	seq_printf(seq, ",data=%s", data_mode_string(sbi->s_mount_opt &
-						     EXT3_MOUNT_DATA_FLAGS));
+	seq_printf(seq, ",data=%s", data_mode_string(test_opt(sb, DATA_FLAGS)));
 	if (test_opt(sb, DATA_ERR_ABORT))
 		seq_puts(seq, ",data_err=abort");
 
@@ -751,13 +752,6 @@ static ssize_t ext3_quota_write(struct s
 				const char *data, size_t len, loff_t off);
 
 static const struct dquot_operations ext3_quota_operations = {
-	.initialize	= dquot_initialize,
-	.drop		= dquot_drop,
-	.alloc_space	= dquot_alloc_space,
-	.alloc_inode	= dquot_alloc_inode,
-	.free_space	= dquot_free_space,
-	.free_inode	= dquot_free_inode,
-	.transfer	= dquot_transfer,
 	.write_dquot	= ext3_write_dquot,
 	.acquire_dquot	= ext3_acquire_dquot,
 	.release_dquot	= ext3_release_dquot,
@@ -896,6 +890,63 @@ static ext3_fsblk_t get_sb_block(void **
 	return sb_block;
 }
 
+#ifdef CONFIG_QUOTA
+static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
+{
+	struct ext3_sb_info *sbi = EXT3_SB(sb);
+	char *qname;
+
+	if (sb_any_quota_loaded(sb) &&
+		!sbi->s_qf_names[qtype]) {
+		ext3_msg(sb, KERN_ERR,
+			"Cannot change journaled "
+			"quota options when quota turned on");
+		return 0;
+	}
+	qname = match_strdup(args);
+	if (!qname) {
+		ext3_msg(sb, KERN_ERR,
+			"Not enough memory for storing quotafile name");
+		return 0;
+	}
+	if (sbi->s_qf_names[qtype] &&
+		strcmp(sbi->s_qf_names[qtype], qname)) {
+		ext3_msg(sb, KERN_ERR,
+			"%s quota file already specified", QTYPE2NAME(qtype));
+		kfree(qname);
+		return 0;
+	}
+	sbi->s_qf_names[qtype] = qname;
+	if (strchr(sbi->s_qf_names[qtype], '/')) {
+		ext3_msg(sb, KERN_ERR,
+			"quotafile must be on filesystem root");
+		kfree(sbi->s_qf_names[qtype]);
+		sbi->s_qf_names[qtype] = NULL;
+		return 0;
+	}
+	set_opt(sbi->s_mount_opt, QUOTA);
+	return 1;
+}
+
+static int clear_qf_name(struct super_block *sb, int qtype) {
+
+	struct ext3_sb_info *sbi = EXT3_SB(sb);
+
+	if (sb_any_quota_loaded(sb) &&
+		sbi->s_qf_names[qtype]) {
+		ext3_msg(sb, KERN_ERR, "Cannot change journaled quota options"
+			" when quota turned on");
+		return 0;
+	}
+	/*
+	 * The space will be released later when all options are confirmed
+	 * to be correct
+	 */
+	sbi->s_qf_names[qtype] = NULL;
+	return 1;
+}
+#endif
+
 static int parse_options (char *options, struct super_block *sb,
 			  unsigned int *inum, unsigned long *journal_devnum,
 			  ext3_fsblk_t *n_blocks_count, int is_remount)
@@ -906,8 +957,7 @@ static int parse_options (char *options,
 	int data_opt = 0;
 	int option;
 #ifdef CONFIG_QUOTA
-	int qtype, qfmt;
-	char *qname;
+	int qfmt;
 #endif
 
 	if (!options)
@@ -1065,20 +1115,19 @@ static int parse_options (char *options,
 			data_opt = EXT3_MOUNT_WRITEBACK_DATA;
 		datacheck:
 			if (is_remount) {
-				if ((sbi->s_mount_opt & EXT3_MOUNT_DATA_FLAGS)
-						== data_opt)
+				if (test_opt(sb, DATA_FLAGS) == data_opt)
 					break;
 				ext3_msg(sb, KERN_ERR,
 					"error: cannot change "
 					"data mode on remount. The filesystem "
 					"is mounted in data=%s mode and you "
 					"try to remount it in data=%s mode.",
-					data_mode_string(sbi->s_mount_opt &
-							EXT3_MOUNT_DATA_FLAGS),
+					data_mode_string(test_opt(sb,
+							DATA_FLAGS)),
 					data_mode_string(data_opt));
 				return 0;
 			} else {
-				sbi->s_mount_opt &= ~EXT3_MOUNT_DATA_FLAGS;
+				clear_opt(sbi->s_mount_opt, DATA_FLAGS);
 				sbi->s_mount_opt |= data_opt;
 			}
 			break;
@@ -1090,62 +1139,20 @@ static int parse_options (char *options,
 			break;
 #ifdef CONFIG_QUOTA
 		case Opt_usrjquota:
-			qtype = USRQUOTA;
-			goto set_qf_name;
-		case Opt_grpjquota:
-			qtype = GRPQUOTA;
-set_qf_name:
-			if (sb_any_quota_loaded(sb) &&
-			    !sbi->s_qf_names[qtype]) {
-				ext3_msg(sb, KERN_ERR,
-					"error: cannot change journaled "
-					"quota options when quota turned on.");
-				return 0;
-			}
-			qname = match_strdup(&args[0]);
-			if (!qname) {
-				ext3_msg(sb, KERN_ERR,
-					"error: not enough memory for "
-					"storing quotafile name.");
-				return 0;
-			}
-			if (sbi->s_qf_names[qtype] &&
-			    strcmp(sbi->s_qf_names[qtype], qname)) {
-				ext3_msg(sb, KERN_ERR,
-					"error: %s quota file already "
-					"specified.", QTYPE2NAME(qtype));
-				kfree(qname);
+			if (!set_qf_name(sb, USRQUOTA, &args[0]))
 				return 0;
-			}
-			sbi->s_qf_names[qtype] = qname;
-			if (strchr(sbi->s_qf_names[qtype], '/')) {
-				ext3_msg(sb, KERN_ERR,
-					"error: quotafile must be on "
-					"filesystem root.");
-				kfree(sbi->s_qf_names[qtype]);
-				sbi->s_qf_names[qtype] = NULL;
+			break;
+		case Opt_grpjquota:
+			if (!set_qf_name(sb, GRPQUOTA, &args[0]))
 				return 0;
-			}
-			set_opt(sbi->s_mount_opt, QUOTA);
 			break;
 		case Opt_offusrjquota:
-			qtype = USRQUOTA;
-			goto clear_qf_name;
+			if (!clear_qf_name(sb, USRQUOTA))
+				return 0;
+			break;
 		case Opt_offgrpjquota:
-			qtype = GRPQUOTA;
-clear_qf_name:
-			if (sb_any_quota_loaded(sb) &&
-			    sbi->s_qf_names[qtype]) {
-				ext3_msg(sb, KERN_ERR, "error: cannot change "
-					"journaled quota options when "
-					"quota turned on.");
+			if (!clear_qf_name(sb, GRPQUOTA))
 				return 0;
-			}
-			/*
-			 * The space will be released later when all options
-			 * are confirmed to be correct
-			 */
-			sbi->s_qf_names[qtype] = NULL;
 			break;
 		case Opt_jqfmt_vfsold:
 			qfmt = QFMT_VFS_OLD;
@@ -1244,18 +1251,12 @@ set_qf_format:
 	}
 #ifdef CONFIG_QUOTA
 	if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
-		if ((sbi->s_mount_opt & EXT3_MOUNT_USRQUOTA) &&
-		     sbi->s_qf_names[USRQUOTA])
+		if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA])
 			clear_opt(sbi->s_mount_opt, USRQUOTA);
-
-		if ((sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA) &&
-		     sbi->s_qf_names[GRPQUOTA])
+		if (test_opt(sb, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA])
 			clear_opt(sbi->s_mount_opt, GRPQUOTA);
 
-		if ((sbi->s_qf_names[USRQUOTA] &&
-				(sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA)) ||
-		    (sbi->s_qf_names[GRPQUOTA] &&
-				(sbi->s_mount_opt & EXT3_MOUNT_USRQUOTA))) {
+		if (test_opt(sb, GRPQUOTA) || test_opt(sb, USRQUOTA)) {
 			ext3_msg(sb, KERN_ERR, "error: old and new quota "
 					"format mixing.");
 			return 0;
@@ -1478,7 +1479,7 @@ static void ext3_orphan_cleanup (struct
 		}
 
 		list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan);
-		vfs_dq_init(inode);
+		dquot_initialize(inode);
 		if (inode->i_nlink) {
 			printk(KERN_DEBUG
 				"%s: truncating inode %lu to %Ld bytes\n",
@@ -1671,11 +1672,11 @@ static int ext3_fill_super (struct super
 		set_opt(sbi->s_mount_opt, POSIX_ACL);
 #endif
 	if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_DATA)
-		sbi->s_mount_opt |= EXT3_MOUNT_JOURNAL_DATA;
+		set_opt(sbi->s_mount_opt, JOURNAL_DATA);
 	else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_ORDERED)
-		sbi->s_mount_opt |= EXT3_MOUNT_ORDERED_DATA;
+		set_opt(sbi->s_mount_opt, ORDERED_DATA);
 	else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_WBACK)
-		sbi->s_mount_opt |= EXT3_MOUNT_WRITEBACK_DATA;
+		set_opt(sbi->s_mount_opt, WRITEBACK_DATA);
 
 	if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_PANIC)
 		set_opt(sbi->s_mount_opt, ERRORS_PANIC);
@@ -1694,7 +1695,7 @@ static int ext3_fill_super (struct super
 		goto failed_mount;
 
 	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
-		((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
+		(test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
 
 	if (le32_to_cpu(es->s_rev_level) == EXT3_GOOD_OLD_REV &&
 	    (EXT3_HAS_COMPAT_FEATURE(sb, ~0U) ||
@@ -2561,11 +2562,11 @@ static int ext3_remount (struct super_bl
 		goto restore_opts;
 	}
 
-	if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
+	if (test_opt(sb, ABORT))
 		ext3_abort(sb, __func__, "Abort forced by user");
 
 	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
-		((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
+		(test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
 
 	es = sbi->s_es;
 
@@ -2573,7 +2574,7 @@ static int ext3_remount (struct super_bl
 
 	if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
 		n_blocks_count > le32_to_cpu(es->s_blocks_count)) {
-		if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) {
+		if (test_opt(sb, ABORT)) {
 			err = -EROFS;
 			goto restore_opts;
 		}
@@ -2734,7 +2735,7 @@ static int ext3_statfs (struct dentry *
  * Process 1                         Process 2
  * ext3_create()                     quota_sync()
  *   journal_start()                   write_dquot()
- *   vfs_dq_init()                       down(dqio_mutex)
+ *   dquot_initialize()                       down(dqio_mutex)
  *     down(dqio_mutex)                    journal_start()
  *
  */
@@ -2942,9 +2943,7 @@ static ssize_t ext3_quota_write(struct s
 	sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb);
 	int err = 0;
 	int offset = off & (sb->s_blocksize - 1);
-	int tocopy;
 	int journal_quota = EXT3_SB(sb)->s_qf_names[type] != NULL;
-	size_t towrite = len;
 	struct buffer_head *bh;
 	handle_t *handle = journal_current_handle();
 
@@ -2955,53 +2954,54 @@ static ssize_t ext3_quota_write(struct s
 			(unsigned long long)off, (unsigned long long)len);
 		return -EIO;
 	}
+
+	/*
+	 * Since we account only one data block in transaction credits,
+	 * then it is impossible to cross a block boundary.
+	 */
+	if (sb->s_blocksize - offset < len) {
+		ext3_msg(sb, KERN_WARNING, "Quota write (off=%llu, len=%llu)"
+			" cancelled because not block aligned",
+			(unsigned long long)off, (unsigned long long)len);
+		return -EIO;
+	}
 	mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
-	while (towrite > 0) {
-		tocopy = sb->s_blocksize - offset < towrite ?
-				sb->s_blocksize - offset : towrite;
-		bh = ext3_bread(handle, inode, blk, 1, &err);
-		if (!bh)
+	bh = ext3_bread(handle, inode, blk, 1, &err);
+	if (!bh)
+		goto out;
+	if (journal_quota) {
+		err = ext3_journal_get_write_access(handle, bh);
+		if (err) {
+			brelse(bh);
 			goto out;
-		if (journal_quota) {
-			err = ext3_journal_get_write_access(handle, bh);
-			if (err) {
-				brelse(bh);
-				goto out;
-			}
-		}
-		lock_buffer(bh);
-		memcpy(bh->b_data+offset, data, tocopy);
-		flush_dcache_page(bh->b_page);
-		unlock_buffer(bh);
-		if (journal_quota)
-			err = ext3_journal_dirty_metadata(handle, bh);
-		else {
-			/* Always do at least ordered writes for quotas */
-			err = ext3_journal_dirty_data(handle, bh);
-			mark_buffer_dirty(bh);
 		}
-		brelse(bh);
-		if (err)
-			goto out;
-		offset = 0;
-		towrite -= tocopy;
-		data += tocopy;
-		blk++;
 	}
+	lock_buffer(bh);
+	memcpy(bh->b_data+offset, data, len);
+	flush_dcache_page(bh->b_page);
+	unlock_buffer(bh);
+	if (journal_quota)
+		err = ext3_journal_dirty_metadata(handle, bh);
+	else {
+		/* Always do at least ordered writes for quotas */
+		err = ext3_journal_dirty_data(handle, bh);
+		mark_buffer_dirty(bh);
+	}
+	brelse(bh);
 out:
-	if (len == towrite) {
+	if (err) {
 		mutex_unlock(&inode->i_mutex);
 		return err;
 	}
-	if (inode->i_size < off+len-towrite) {
-		i_size_write(inode, off+len-towrite);
+	if (inode->i_size < off + len) {
+		i_size_write(inode, off + len);
 		EXT3_I(inode)->i_disksize = inode->i_size;
 	}
 	inode->i_version++;
 	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 	ext3_mark_inode_dirty(handle, inode);
 	mutex_unlock(&inode->i_mutex);
-	return len - towrite;
+	return len;
 }
 
 #endif
diff -druNp linux-libre-2.6.33-gnu1/fs/ext3/symlink.c linux-libre-2.6.34-gnu1/fs/ext3/symlink.c
--- linux-libre-2.6.33-gnu1/fs/ext3/symlink.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext3/symlink.c	2010-05-16 17:17:36.000000000 -0400
@@ -34,6 +34,7 @@ const struct inode_operations ext3_symli
 	.readlink	= generic_readlink,
 	.follow_link	= page_follow_link_light,
 	.put_link	= page_put_link,
+	.setattr	= ext3_setattr,
 #ifdef CONFIG_EXT3_FS_XATTR
 	.setxattr	= generic_setxattr,
 	.getxattr	= generic_getxattr,
@@ -45,6 +46,7 @@ const struct inode_operations ext3_symli
 const struct inode_operations ext3_fast_symlink_inode_operations = {
 	.readlink	= generic_readlink,
 	.follow_link	= ext3_follow_link,
+	.setattr	= ext3_setattr,
 #ifdef CONFIG_EXT3_FS_XATTR
 	.setxattr	= generic_setxattr,
 	.getxattr	= generic_getxattr,
diff -druNp linux-libre-2.6.33-gnu1/fs/ext3/xattr.c linux-libre-2.6.34-gnu1/fs/ext3/xattr.c
--- linux-libre-2.6.33-gnu1/fs/ext3/xattr.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext3/xattr.c	2010-05-16 17:17:36.000000000 -0400
@@ -274,7 +274,7 @@ ext3_xattr_ibody_get(struct inode *inode
 	void *end;
 	int error;
 
-	if (!(EXT3_I(inode)->i_state & EXT3_STATE_XATTR))
+	if (!ext3_test_inode_state(inode, EXT3_STATE_XATTR))
 		return -ENODATA;
 	error = ext3_get_inode_loc(inode, &iloc);
 	if (error)
@@ -403,7 +403,7 @@ ext3_xattr_ibody_list(struct dentry *den
 	void *end;
 	int error;
 
-	if (!(EXT3_I(inode)->i_state & EXT3_STATE_XATTR))
+	if (!ext3_test_inode_state(inode, EXT3_STATE_XATTR))
 		return 0;
 	error = ext3_get_inode_loc(inode, &iloc);
 	if (error)
@@ -500,7 +500,7 @@ ext3_xattr_release_block(handle_t *handl
 		error = ext3_journal_dirty_metadata(handle, bh);
 		if (IS_SYNC(inode))
 			handle->h_sync = 1;
-		vfs_dq_free_block(inode, 1);
+		dquot_free_block(inode, 1);
 		ea_bdebug(bh, "refcount now=%d; releasing",
 			  le32_to_cpu(BHDR(bh)->h_refcount));
 		if (ce)
@@ -775,8 +775,8 @@ inserted:
 			else {
 				/* The old block is released after updating
 				   the inode. */
-				error = -EDQUOT;
-				if (vfs_dq_alloc_block(inode, 1))
+				error = dquot_alloc_block(inode, 1);
+				if (error)
 					goto cleanup;
 				error = ext3_journal_get_write_access(handle,
 								      new_bh);
@@ -850,7 +850,7 @@ cleanup:
 	return error;
 
 cleanup_dquot:
-	vfs_dq_free_block(inode, 1);
+	dquot_free_block(inode, 1);
 	goto cleanup;
 
 bad_block:
@@ -882,7 +882,7 @@ ext3_xattr_ibody_find(struct inode *inod
 	is->s.base = is->s.first = IFIRST(header);
 	is->s.here = is->s.first;
 	is->s.end = (void *)raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
-	if (EXT3_I(inode)->i_state & EXT3_STATE_XATTR) {
+	if (ext3_test_inode_state(inode, EXT3_STATE_XATTR)) {
 		error = ext3_xattr_check_names(IFIRST(header), is->s.end);
 		if (error)
 			return error;
@@ -914,10 +914,10 @@ ext3_xattr_ibody_set(handle_t *handle, s
 	header = IHDR(inode, ext3_raw_inode(&is->iloc));
 	if (!IS_LAST_ENTRY(s->first)) {
 		header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
-		EXT3_I(inode)->i_state |= EXT3_STATE_XATTR;
+		ext3_set_inode_state(inode, EXT3_STATE_XATTR);
 	} else {
 		header->h_magic = cpu_to_le32(0);
-		EXT3_I(inode)->i_state &= ~EXT3_STATE_XATTR;
+		ext3_clear_inode_state(inode, EXT3_STATE_XATTR);
 	}
 	return 0;
 }
@@ -967,10 +967,10 @@ ext3_xattr_set_handle(handle_t *handle,
 	if (error)
 		goto cleanup;
 
-	if (EXT3_I(inode)->i_state & EXT3_STATE_NEW) {
+	if (ext3_test_inode_state(inode, EXT3_STATE_NEW)) {
 		struct ext3_inode *raw_inode = ext3_raw_inode(&is.iloc);
 		memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size);
-		EXT3_I(inode)->i_state &= ~EXT3_STATE_NEW;
+		ext3_clear_inode_state(inode, EXT3_STATE_NEW);
 	}
 
 	error = ext3_xattr_ibody_find(inode, &i, &is);
diff -druNp linux-libre-2.6.33-gnu1/fs/ext3/xattr_security.c linux-libre-2.6.34-gnu1/fs/ext3/xattr_security.c
--- linux-libre-2.6.33-gnu1/fs/ext3/xattr_security.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext3/xattr_security.c	2010-05-16 17:17:36.000000000 -0400
@@ -4,6 +4,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/fs.h>
 #include <linux/ext3_jbd.h>
diff -druNp linux-libre-2.6.33-gnu1/fs/ext4/balloc.c linux-libre-2.6.34-gnu1/fs/ext4/balloc.c
--- linux-libre-2.6.33-gnu1/fs/ext4/balloc.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext4/balloc.c	2010-05-16 17:17:36.000000000 -0400
@@ -97,8 +97,8 @@ unsigned ext4_init_block_bitmap(struct s
 		/* If checksum is bad mark all blocks used to prevent allocation
 		 * essentially implementing a per-group read-only flag. */
 		if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
-			ext4_error(sb, __func__,
-				  "Checksum bad for group %u", block_group);
+			ext4_error(sb, "Checksum bad for group %u",
+					block_group);
 			ext4_free_blks_set(sb, gdp, 0);
 			ext4_free_inodes_set(sb, gdp, 0);
 			ext4_itable_unused_set(sb, gdp, 0);
@@ -130,8 +130,7 @@ unsigned ext4_init_block_bitmap(struct s
 		 * to make sure we calculate the right free blocks
 		 */
 		group_blocks = ext4_blocks_count(sbi->s_es) -
-			le32_to_cpu(sbi->s_es->s_first_data_block) -
-			(EXT4_BLOCKS_PER_GROUP(sb) * (ngroups - 1));
+			ext4_group_first_block_no(sb, ngroups - 1);
 	} else {
 		group_blocks = EXT4_BLOCKS_PER_GROUP(sb);
 	}
@@ -189,9 +188,6 @@ unsigned ext4_init_block_bitmap(struct s
  * when a file system is mounted (see ext4_fill_super).
  */
 
-
-#define in_range(b, first, len)	((b) >= (first) && (b) <= (first) + (len) - 1)
-
 /**
  * ext4_get_group_desc() -- load group descriptor from disk
  * @sb:			super block
@@ -210,10 +206,8 @@ struct ext4_group_desc * ext4_get_group_
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 
 	if (block_group >= ngroups) {
-		ext4_error(sb, "ext4_get_group_desc",
-			   "block_group >= groups_count - "
-			   "block_group = %u, groups_count = %u",
-			   block_group, ngroups);
+		ext4_error(sb, "block_group >= groups_count - block_group = %u,"
+			   " groups_count = %u", block_group, ngroups);
 
 		return NULL;
 	}
@@ -221,8 +215,7 @@ struct ext4_group_desc * ext4_get_group_
 	group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb);
 	offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1);
 	if (!sbi->s_group_desc[group_desc]) {
-		ext4_error(sb, "ext4_get_group_desc",
-			   "Group descriptor not loaded - "
+		ext4_error(sb, "Group descriptor not loaded - "
 			   "block_group = %u, group_desc = %u, desc = %u",
 			   block_group, group_desc, offset);
 		return NULL;
@@ -282,9 +275,7 @@ static int ext4_valid_block_bitmap(struc
 		return 1;
 
 err_out:
-	ext4_error(sb, __func__,
-			"Invalid block bitmap - "
-			"block_group = %d, block = %llu",
+	ext4_error(sb, "Invalid block bitmap - block_group = %d, block = %llu",
 			block_group, bitmap_blk);
 	return 0;
 }
@@ -311,8 +302,7 @@ ext4_read_block_bitmap(struct super_bloc
 	bitmap_blk = ext4_block_bitmap(sb, desc);
 	bh = sb_getblk(sb, bitmap_blk);
 	if (unlikely(!bh)) {
-		ext4_error(sb, __func__,
-			    "Cannot read block bitmap - "
+		ext4_error(sb, "Cannot read block bitmap - "
 			    "block_group = %u, block_bitmap = %llu",
 			    block_group, bitmap_blk);
 		return NULL;
@@ -354,8 +344,7 @@ ext4_read_block_bitmap(struct super_bloc
 	set_bitmap_uptodate(bh);
 	if (bh_submit_read(bh) < 0) {
 		put_bh(bh);
-		ext4_error(sb, __func__,
-			    "Cannot read block bitmap - "
+		ext4_error(sb, "Cannot read block bitmap - "
 			    "block_group = %u, block_bitmap = %llu",
 			    block_group, bitmap_blk);
 		return NULL;
@@ -419,8 +408,7 @@ void ext4_add_groupblocks(handle_t *hand
 	    in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) ||
 	    in_range(block + count - 1, ext4_inode_table(sb, desc),
 		     sbi->s_itb_per_group)) {
-		ext4_error(sb, __func__,
-			   "Adding blocks in system zones - "
+		ext4_error(sb, "Adding blocks in system zones - "
 			   "Block = %llu, count = %lu",
 			   block, count);
 		goto error_return;
@@ -453,8 +441,7 @@ void ext4_add_groupblocks(handle_t *hand
 		BUFFER_TRACE(bitmap_bh, "clear bit");
 		if (!ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group),
 						bit + i, bitmap_bh->b_data)) {
-			ext4_error(sb, __func__,
-				   "bit already cleared for block %llu",
+			ext4_error(sb, "bit already cleared for block %llu",
 				   (ext4_fsblk_t)(block + i));
 			BUFFER_TRACE(bitmap_bh, "bit already cleared");
 		} else {
diff -druNp linux-libre-2.6.33-gnu1/fs/ext4/block_validity.c linux-libre-2.6.34-gnu1/fs/ext4/block_validity.c
--- linux-libre-2.6.33-gnu1/fs/ext4/block_validity.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext4/block_validity.c	2010-05-16 17:17:36.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/pagemap.h>
 #include <linux/blkdev.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include "ext4.h"
 
 struct ext4_system_zone {
@@ -205,14 +206,14 @@ void ext4_release_system_zone(struct sup
 		entry = rb_entry(n, struct ext4_system_zone, node);
 		kmem_cache_free(ext4_system_zone_cachep, entry);
 		if (!parent)
-			EXT4_SB(sb)->system_blks.rb_node = NULL;
+			EXT4_SB(sb)->system_blks = RB_ROOT;
 		else if (parent->rb_left == n)
 			parent->rb_left = NULL;
 		else if (parent->rb_right == n)
 			parent->rb_right = NULL;
 		n = parent;
 	}
-	EXT4_SB(sb)->system_blks.rb_node = NULL;
+	EXT4_SB(sb)->system_blks = RB_ROOT;
 }
 
 /*
diff -druNp linux-libre-2.6.33-gnu1/fs/ext4/dir.c linux-libre-2.6.34-gnu1/fs/ext4/dir.c
--- linux-libre-2.6.33-gnu1/fs/ext4/dir.c	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext4/dir.c	2010-05-16 17:17:36.000000000 -0400
@@ -83,10 +83,12 @@ int ext4_check_dir_entry(const char *fun
 		error_msg = "inode out of bounds";
 
 	if (error_msg != NULL)
-		ext4_error(dir->i_sb, function,
-			"bad entry in directory #%lu: %s - "
-			"offset=%u, inode=%u, rec_len=%d, name_len=%d",
-			dir->i_ino, error_msg, offset,
+		__ext4_error(dir->i_sb, function,
+			"bad entry in directory #%lu: %s - block=%llu"
+			"offset=%u(%u), inode=%u, rec_len=%d, name_len=%d",
+			dir->i_ino, error_msg, 
+			(unsigned long long) bh->b_blocknr,     
+			(unsigned) (offset%bh->b_size), offset,
 			le32_to_cpu(de->inode),
 			rlen, de->name_len);
 	return error_msg == NULL ? 1 : 0;
@@ -150,7 +152,7 @@ static int ext4_readdir(struct file *fil
 		 */
 		if (!bh) {
 			if (!dir_has_error) {
-				ext4_error(sb, __func__, "directory #%lu "
+				ext4_error(sb, "directory #%lu "
 					   "contains a hole at offset %Lu",
 					   inode->i_ino,
 					   (unsigned long long) filp->f_pos);
@@ -303,7 +305,7 @@ static void free_rb_tree_fname(struct rb
 			kfree(old);
 		}
 		if (!parent)
-			root->rb_node = NULL;
+			*root = RB_ROOT;
 		else if (parent->rb_left == n)
 			parent->rb_left = NULL;
 		else if (parent->rb_right == n)
diff -druNp linux-libre-2.6.33-gnu1/fs/ext4/ext4.h linux-libre-2.6.34-gnu1/fs/ext4/ext4.h
--- linux-libre-2.6.33-gnu1/fs/ext4/ext4.h	2010-02-24 13:52:17.000000000 -0500
+++ linux-libre-2.6.34-gnu1/fs/ext4/ext4.h	2010-05-16 17:17:36.000000000 -0400
@@ -53,6 +53,12 @@
 #define ext4_debug(f, a...)	do {} while (0)
 #endif
 
+#define EXT4_ERROR_INODE(inode, fmt, a...) \
+	ext4_error_inode(__func__, (inode), (fmt), ## a);
+
+#define EXT4_ERROR_FILE(file, fmt, a...)	\
+	ext4_error_file(__func__, (file), (fmt), ## a);
+
 /* data type for block offset of block group */
 typedef int ext4_grpblk_t;
 
@@ -133,14 +139,14 @@ struct mpage_da_data {
 	int pages_written;
 	int retval;
 };
-#define	DIO_AIO_UNWRITTEN	0x1
+#define	EXT4_IO_UNWRITTEN	0x1
 typedef struct ext4_io_end {
 	struct list_head	list;		/* per-file finished AIO list */
 	struct inode		*inode;		/* file being written to */
 	unsigned int		flag;		/* unwritten or not */
-	int			error;		/* I/O error code */
-	ext4_lblk_t		offset;		/* offset in the file */
-	size_t			size;		/* size of the extent */
+	struct page		*page;		/* page struct for buffer write */
+	loff_t			offset;		/* offset in the file */
+	ssize_t			size;		/* size of the extent */
 	struct work_struct	work;		/* data work queue */
 } ext4_io_end_t;
 
@@ -284,10 +290,12 @@ struct flex_groups {
 #define EXT4_TOPDIR_FL			0x00020000 /* Top of directory hierarchies*/
 #define EXT4_HUGE_FILE_FL               0x00040000 /* Set to each huge file */
 #define EXT4_EXTENTS_FL			0x00080000 /* Inode uses extents */
+#define EXT4_EA_INODE_FL	        0x00200000 /* Inode used for large EA */
+#define EXT4_EOFBLOCKS_FL		0x00400000 /* Blocks allocated beyond EOF */
 #define EXT4_RESERVED_FL		0x80000000 /* reserved for ext4 lib */
 
-#define EXT4_FL_USER_VISIBLE		0x000BDFFF /* User visible flags */
-#define EXT4_FL_USER_MODIFIABLE		0x000B80FF /* User modifiable flags */
+#define EXT4_FL_USER_VISIBLE		0x004BDFFF /* User visible flags */
+#define EXT4_FL_USER_MODIFIABLE		0x004B80FF /* User modifiable flags */
 
 /* Flags that should be inherited by new inodes from their parent. */
 #define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\
@@ -313,17 +321,6 @@ static inline __u32 ext4_mask_flags(umod
 		return flags & EXT4_OTHER_FLMASK;
 }
 
-/*
- * Inode dynamic state flags
- */
-#define EXT4_STATE_JDATA		0x00000001 /* journaled data exists */
-#define EXT4_STATE_NEW			0x00000002 /* inode is newly created */
-#define EXT4_STATE_XATTR		0x00000004 /* has in-inode xattrs */
-#define EXT4_STATE_NO_EXPAND		0x00000008 /* No space for expansion */
-#define EXT4_STATE_DA_ALLOC_CLOSE	0x00000010 /* Alloc DA blks on close */
-#define EXT4_STATE_EXT_MIGRATE		0x00000020 /* Inode is migrating */
-#define EXT4_STATE_DIO_UNWRITTEN	0x00000040 /* need convert on dio done*/
-
 /* Used to pass group descriptor data when online resize is done */
 struct ext4_new_group_input {
 	__u32 group;		/* Group number for this data */
@@ -364,19 +361,20 @@ struct ext4_new_group_data {
 	/* caller is from the direct IO path, request to creation of an
 	unitialized extents if not allocated, split the uninitialized
 	extent if blocks has been preallocated already*/
-#define EXT4_GET_BLOCKS_DIO			0x0008
+#define EXT4_GET_BLOCKS_PRE_IO			0x0008
 #define EXT4_GET_BLOCKS_CONVERT			0x0010
-#define EXT4_GET_BLOCKS_DIO_CREATE_EXT		(EXT4_GET_BLOCKS_DIO|\
+#define EXT4_GET_BLOCKS_IO_CREATE_EXT		(EXT4_GET_BLOCKS_PRE_IO|\
+					 EXT4_GET_BLOCKS_CREATE_UNINIT_EXT)
+	/* Convert extent to initialized after IO complete */
+#define EXT4_GET_BLOCKS_IO_CONVERT_EXT		(EXT4_GET_BLOCKS_CONVERT|\
 					 EXT4_GET_BLOCKS_CREATE_UNINIT_EXT)
-	/* Convert extent to initialized after direct IO complete */
-#define EXT4_GET_BLOCKS_DIO_CONVERT_EXT		(EXT4_GET_BLOCKS_CONVERT|\
-					 EXT4_GET_BLOCKS_DIO_CREATE_EXT)
 
 /*
  * Flags used by ext4_free_blocks
  */
 #define EXT4_FREE_BLOCKS_METADATA	0x0001
 #define EXT4_FREE_BLOCKS_FORGET		0x0002
+#define EXT4_FREE_BLOCKS_VALIDATED	0x0004
 
 /*
  * ioctl commands
@@ -630,7 +628,7 @@ struct ext4_inode_info {
 	 * near to their parent directory's inode.
 	 */
 	ext4_group_t	i_block_group;
-	__u32	i_state;		/* Dynamic state flags for ext4 */
+	unsigned long	i_state_flags;		/* Dynamic state flags */
 
 	ext4_lblk_t		i_dir_start_lookup;
 #ifdef CONFIG_EXT4_FS_XATTR
@@ -708,8 +706,9 @@ struct ext4_inode_info {
 	qsize_t i_reserved_quota;
 #endif
 
-	/* completed async DIOs that might need unwritten extents handling */
-	struct list_head i_aio_dio_complete_list;
+	/* completed IOs that might need unwrit